^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * bcu.c, Bus Control Unit routines for the NEC VR4100 series.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2002 MontaVista Software Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Author: Yoichi Yuasa <source@mvista.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2003-2005 Yoichi Yuasa <yuasa@linux-mips.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Changes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * MontaVista Software Inc. <source@mvista.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * - New creation, NEC VR4122 and VR4131 are supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * - Added support for NEC VR4111 and VR4121.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Yoichi Yuasa <yuasa@linux-mips.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * - Added support for NEC VR4133.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <asm/cpu-type.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <asm/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define CLKSPEEDREG_TYPE1 (void __iomem *)KSEG1ADDR(0x0b000014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define CLKSPEEDREG_TYPE2 (void __iomem *)KSEG1ADDR(0x0f000014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define CLKSP(x) ((x) & 0x001f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define CLKSP_VR4133(x) ((x) & 0x0007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define DIV2B 0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define DIV3B 0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define DIV4B 0x2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define DIVT(x) (((x) & 0xf000) >> 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define DIVVT(x) (((x) & 0x0f00) >> 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define TDIVMODE(x) (2 << (((x) & 0x1000) >> 12))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define VTDIVMODE(x) (((x) & 0x0700) >> 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static unsigned long vr41xx_vtclock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static unsigned long vr41xx_tclock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) unsigned long vr41xx_get_vtclock_frequency(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) return vr41xx_vtclock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) EXPORT_SYMBOL_GPL(vr41xx_get_vtclock_frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) unsigned long vr41xx_get_tclock_frequency(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) return vr41xx_tclock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) EXPORT_SYMBOL_GPL(vr41xx_get_tclock_frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static inline uint16_t read_clkspeed(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) switch (current_cpu_type()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) case CPU_VR4111:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) case CPU_VR4121: return readw(CLKSPEEDREG_TYPE1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) case CPU_VR4122:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) case CPU_VR4131:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) case CPU_VR4133: return readw(CLKSPEEDREG_TYPE2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static inline unsigned long calculate_pclock(uint16_t clkspeed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) unsigned long pclock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) switch (current_cpu_type()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) case CPU_VR4111:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) case CPU_VR4121:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) pclock = 18432000 * 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) pclock /= CLKSP(clkspeed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) case CPU_VR4122:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) pclock = 18432000 * 98;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) pclock /= CLKSP(clkspeed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) case CPU_VR4131:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) pclock = 18432000 * 108;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) pclock /= CLKSP(clkspeed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) case CPU_VR4133:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) switch (CLKSP_VR4133(clkspeed)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) pclock = 133000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) pclock = 149000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) pclock = 165900000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) pclock = 199100000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) pclock = 265900000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) printk(KERN_INFO "Unknown PClock speed for NEC VR4133\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) printk(KERN_INFO "PClock: %ldHz\n", pclock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return pclock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static inline unsigned long calculate_vtclock(uint16_t clkspeed, unsigned long pclock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) unsigned long vtclock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) switch (current_cpu_type()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) case CPU_VR4111:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /* The NEC VR4111 doesn't have the VTClock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) case CPU_VR4121:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) vtclock = pclock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /* DIVVT == 9 Divide by 1.5 . VTClock = (PClock * 6) / 9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (DIVVT(clkspeed) == 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) vtclock = pclock * 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /* DIVVT == 10 Divide by 2.5 . VTClock = (PClock * 4) / 10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) else if (DIVVT(clkspeed) == 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) vtclock = pclock * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) vtclock /= DIVVT(clkspeed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) printk(KERN_INFO "VTClock: %ldHz\n", vtclock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) case CPU_VR4122:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if(VTDIVMODE(clkspeed) == 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) vtclock = pclock / 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) else if(VTDIVMODE(clkspeed) == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) vtclock = pclock / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) vtclock = pclock / VTDIVMODE(clkspeed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) printk(KERN_INFO "VTClock: %ldHz\n", vtclock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) case CPU_VR4131:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) case CPU_VR4133:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) vtclock = pclock / VTDIVMODE(clkspeed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) printk(KERN_INFO "VTClock: %ldHz\n", vtclock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return vtclock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static inline unsigned long calculate_tclock(uint16_t clkspeed, unsigned long pclock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) unsigned long vtclock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) unsigned long tclock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) switch (current_cpu_type()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) case CPU_VR4111:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (!(clkspeed & DIV2B))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) tclock = pclock / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) else if (!(clkspeed & DIV3B))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) tclock = pclock / 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) else if (!(clkspeed & DIV4B))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) tclock = pclock / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) case CPU_VR4121:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) tclock = pclock / DIVT(clkspeed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) case CPU_VR4122:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) case CPU_VR4131:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) case CPU_VR4133:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) tclock = vtclock / TDIVMODE(clkspeed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) printk(KERN_INFO "TClock: %ldHz\n", tclock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return tclock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) void vr41xx_calculate_clock_frequency(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) unsigned long pclock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) uint16_t clkspeed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) clkspeed = read_clkspeed();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) pclock = calculate_pclock(clkspeed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) vr41xx_vtclock = calculate_vtclock(clkspeed, pclock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) vr41xx_tclock = calculate_tclock(clkspeed, pclock, vr41xx_vtclock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) EXPORT_SYMBOL_GPL(vr41xx_calculate_clock_frequency);