^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * License. See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2009 Florian Fainelli <florian@openwrt.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) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/cpu-info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/mipsregs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <bcm63xx_cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <bcm63xx_regs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <bcm63xx_io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <bcm63xx_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) const unsigned long *bcm63xx_regs_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) EXPORT_SYMBOL(bcm63xx_regs_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) const int *bcm63xx_irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) EXPORT_SYMBOL(bcm63xx_irqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) u16 bcm63xx_cpu_id __read_mostly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) EXPORT_SYMBOL(bcm63xx_cpu_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static u8 bcm63xx_cpu_rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static unsigned int bcm63xx_cpu_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static unsigned int bcm63xx_memory_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static const unsigned long bcm3368_regs_base[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) __GEN_CPU_REGS_TABLE(3368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static const int bcm3368_irqs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) __GEN_CPU_IRQ_TABLE(3368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static const unsigned long bcm6328_regs_base[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) __GEN_CPU_REGS_TABLE(6328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static const int bcm6328_irqs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) __GEN_CPU_IRQ_TABLE(6328)
^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) static const unsigned long bcm6338_regs_base[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) __GEN_CPU_REGS_TABLE(6338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static const int bcm6338_irqs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) __GEN_CPU_IRQ_TABLE(6338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static const unsigned long bcm6345_regs_base[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) __GEN_CPU_REGS_TABLE(6345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static const int bcm6345_irqs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) __GEN_CPU_IRQ_TABLE(6345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static const unsigned long bcm6348_regs_base[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) __GEN_CPU_REGS_TABLE(6348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static const int bcm6348_irqs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) __GEN_CPU_IRQ_TABLE(6348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^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 const unsigned long bcm6358_regs_base[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) __GEN_CPU_REGS_TABLE(6358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static const int bcm6358_irqs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) __GEN_CPU_IRQ_TABLE(6358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static const unsigned long bcm6362_regs_base[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) __GEN_CPU_REGS_TABLE(6362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static const int bcm6362_irqs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) __GEN_CPU_IRQ_TABLE(6362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static const unsigned long bcm6368_regs_base[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) __GEN_CPU_REGS_TABLE(6368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static const int bcm6368_irqs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) __GEN_CPU_IRQ_TABLE(6368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) u8 bcm63xx_get_cpu_rev(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return bcm63xx_cpu_rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) EXPORT_SYMBOL(bcm63xx_get_cpu_rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) unsigned int bcm63xx_get_cpu_freq(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return bcm63xx_cpu_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) unsigned int bcm63xx_get_memory_size(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return bcm63xx_memory_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static unsigned int detect_cpu_clock(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) u16 cpu_id = bcm63xx_get_cpu_id();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) switch (cpu_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) case BCM3368_CPU_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return 300000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) case BCM6328_CPU_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) unsigned int tmp, mips_pll_fcvo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) tmp = bcm_misc_readl(MISC_STRAPBUS_6328_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) mips_pll_fcvo = (tmp & STRAPBUS_6328_FCVO_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) >> STRAPBUS_6328_FCVO_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) switch (mips_pll_fcvo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) case 0x12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) case 0x14:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) case 0x19:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return 160000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) case 0x1c:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return 192000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) case 0x13:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) case 0x15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return 200000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) case 0x1a:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return 384000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) case 0x16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return 400000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return 320000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) case BCM6338_CPU_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /* BCM6338 has a fixed 240 Mhz frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return 240000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) case BCM6345_CPU_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /* BCM6345 has a fixed 140Mhz frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return 140000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) case BCM6348_CPU_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) unsigned int tmp, n1, n2, m1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* 16MHz * (N1 + 1) * (N2 + 2) / (M1_CPU + 1) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) tmp = bcm_perf_readl(PERF_MIPSPLLCTL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) n1 = (tmp & MIPSPLLCTL_N1_MASK) >> MIPSPLLCTL_N1_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) n2 = (tmp & MIPSPLLCTL_N2_MASK) >> MIPSPLLCTL_N2_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) m1 = (tmp & MIPSPLLCTL_M1CPU_MASK) >> MIPSPLLCTL_M1CPU_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) n1 += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) n2 += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) m1 += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return (16 * 1000000 * n1 * n2) / m1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) case BCM6358_CPU_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) unsigned int tmp, n1, n2, m1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /* 16MHz * N1 * N2 / M1_CPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) tmp = bcm_ddr_readl(DDR_DMIPSPLLCFG_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) n1 = (tmp & DMIPSPLLCFG_N1_MASK) >> DMIPSPLLCFG_N1_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) n2 = (tmp & DMIPSPLLCFG_N2_MASK) >> DMIPSPLLCFG_N2_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) m1 = (tmp & DMIPSPLLCFG_M1_MASK) >> DMIPSPLLCFG_M1_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return (16 * 1000000 * n1 * n2) / m1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) case BCM6362_CPU_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) unsigned int tmp, mips_pll_fcvo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) tmp = bcm_misc_readl(MISC_STRAPBUS_6362_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) mips_pll_fcvo = (tmp & STRAPBUS_6362_FCVO_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) >> STRAPBUS_6362_FCVO_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) switch (mips_pll_fcvo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) case 0x03:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) case 0x0b:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) case 0x13:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) case 0x1b:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) return 240000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) case 0x04:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) case 0x0c:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) case 0x14:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) case 0x1c:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return 160000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) case 0x05:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) case 0x0e:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) case 0x16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) case 0x1e:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) case 0x1f:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return 400000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) case 0x06:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return 440000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) case 0x07:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) case 0x17:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) return 384000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) case 0x15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) case 0x1d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return 200000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return 320000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) case BCM6368_CPU_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) unsigned int tmp, p1, p2, ndiv, m1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) /* (64MHz / P1) * P2 * NDIV / M1_CPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) tmp = bcm_ddr_readl(DDR_DMIPSPLLCFG_6368_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) p1 = (tmp & DMIPSPLLCFG_6368_P1_MASK) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) DMIPSPLLCFG_6368_P1_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) p2 = (tmp & DMIPSPLLCFG_6368_P2_MASK) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) DMIPSPLLCFG_6368_P2_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) ndiv = (tmp & DMIPSPLLCFG_6368_NDIV_MASK) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) DMIPSPLLCFG_6368_NDIV_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) tmp = bcm_ddr_readl(DDR_DMIPSPLLDIV_6368_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) m1 = (tmp & DMIPSPLLDIV_6368_MDIV_MASK) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) DMIPSPLLDIV_6368_MDIV_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return (((64 * 1000000) / p1) * p2 * ndiv) / m1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) panic("Failed to detect clock for CPU with id=%04X\n", cpu_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * attempt to detect the amount of memory installed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) static unsigned int detect_memory_size(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) unsigned int cols = 0, rows = 0, is_32bits = 0, banks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (BCMCPU_IS_6328() || BCMCPU_IS_6362())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return bcm_ddr_readl(DDR_CSEND_REG) << 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (BCMCPU_IS_6345()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) val = bcm_sdram_readl(SDRAM_MBASE_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return val * 8 * 1024 * 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) val = bcm_sdram_readl(SDRAM_CFG_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) rows = (val & SDRAM_CFG_ROW_MASK) >> SDRAM_CFG_ROW_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) cols = (val & SDRAM_CFG_COL_MASK) >> SDRAM_CFG_COL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) is_32bits = (val & SDRAM_CFG_32B_MASK) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) banks = (val & SDRAM_CFG_BANK_MASK) ? 2 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (BCMCPU_IS_3368() || BCMCPU_IS_6358() || BCMCPU_IS_6368()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) val = bcm_memc_readl(MEMC_CFG_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) rows = (val & MEMC_CFG_ROW_MASK) >> MEMC_CFG_ROW_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) cols = (val & MEMC_CFG_COL_MASK) >> MEMC_CFG_COL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) is_32bits = (val & MEMC_CFG_32B_MASK) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) banks = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) /* 0 => 11 address bits ... 2 => 13 address bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) rows += 11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) /* 0 => 8 address bits ... 2 => 10 address bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) cols += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return 1 << (cols + rows + (is_32bits + 1) + banks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) void __init bcm63xx_cpu_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) unsigned int cpu = smp_processor_id();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) u32 chipid_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /* soc registers location depends on cpu type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) chipid_reg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) switch (current_cpu_type()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) case CPU_BMIPS3300:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if ((read_c0_prid() & PRID_IMP_MASK) != PRID_IMP_BMIPS3300_ALT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) __cpu_name[cpu] = "Broadcom BCM6338";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) case CPU_BMIPS32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) chipid_reg = BCM_6345_PERF_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) case CPU_BMIPS4350:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) switch ((read_c0_prid() & PRID_REV_MASK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) case 0x04:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) chipid_reg = BCM_3368_PERF_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) case 0x10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) chipid_reg = BCM_6345_PERF_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) chipid_reg = BCM_6368_PERF_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) * really early to panic, but delaying panic would not help since we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * will never get any working console
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (!chipid_reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) panic("unsupported Broadcom CPU");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) /* read out CPU type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) tmp = bcm_readl(chipid_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) bcm63xx_cpu_id = (tmp & REV_CHIPID_MASK) >> REV_CHIPID_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) bcm63xx_cpu_rev = (tmp & REV_REVID_MASK) >> REV_REVID_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) switch (bcm63xx_cpu_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) case BCM3368_CPU_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) bcm63xx_regs_base = bcm3368_regs_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) bcm63xx_irqs = bcm3368_irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) case BCM6328_CPU_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) bcm63xx_regs_base = bcm6328_regs_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) bcm63xx_irqs = bcm6328_irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) case BCM6338_CPU_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) bcm63xx_regs_base = bcm6338_regs_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) bcm63xx_irqs = bcm6338_irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) case BCM6345_CPU_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) bcm63xx_regs_base = bcm6345_regs_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) bcm63xx_irqs = bcm6345_irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) case BCM6348_CPU_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) bcm63xx_regs_base = bcm6348_regs_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) bcm63xx_irqs = bcm6348_irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) case BCM6358_CPU_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) bcm63xx_regs_base = bcm6358_regs_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) bcm63xx_irqs = bcm6358_irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) case BCM6362_CPU_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) bcm63xx_regs_base = bcm6362_regs_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) bcm63xx_irqs = bcm6362_irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) case BCM6368_CPU_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) bcm63xx_regs_base = bcm6368_regs_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) bcm63xx_irqs = bcm6368_irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) panic("unsupported broadcom CPU %x", bcm63xx_cpu_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) bcm63xx_cpu_freq = detect_cpu_clock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) bcm63xx_memory_size = detect_memory_size();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) pr_info("Detected Broadcom 0x%04x CPU revision %02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) bcm63xx_cpu_id, bcm63xx_cpu_rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) pr_info("CPU frequency is %u MHz\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) bcm63xx_cpu_freq / 1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) pr_info("%uMB of RAM installed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) bcm63xx_memory_size >> 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }