0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include "bcma_private.h"
0014
0015 #include <linux/bcma/bcma.h>
0016
0017 #include <linux/serial.h>
0018 #include <linux/serial_core.h>
0019 #include <linux/serial_reg.h>
0020 #include <linux/time.h>
0021 #ifdef CONFIG_BCM47XX
0022 #include <linux/bcm47xx_nvram.h>
0023 #endif
0024
0025 enum bcma_boot_dev {
0026 BCMA_BOOT_DEV_UNK = 0,
0027 BCMA_BOOT_DEV_ROM,
0028 BCMA_BOOT_DEV_PARALLEL,
0029 BCMA_BOOT_DEV_SERIAL,
0030 BCMA_BOOT_DEV_NAND,
0031 };
0032
0033
0034 static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev)
0035 {
0036 return dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM47162 &&
0037 dev->bus->chipinfo.rev == 0 && dev->id.id == BCMA_CORE_MIPS_74K;
0038 }
0039
0040
0041 static inline bool bcma_core_mips_bcm5357b0_quirk(struct bcma_device *dev)
0042 {
0043 return (dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM5357 ||
0044 dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM4749) &&
0045 dev->bus->chipinfo.pkg == 11 &&
0046 dev->id.id == BCMA_CORE_USB20_HOST;
0047 }
0048
0049 static inline u32 mips_read32(struct bcma_drv_mips *mcore,
0050 u16 offset)
0051 {
0052 return bcma_read32(mcore->core, offset);
0053 }
0054
0055 static u32 bcma_core_mips_irqflag(struct bcma_device *dev)
0056 {
0057 u32 flag;
0058
0059 if (bcma_core_mips_bcm47162a0_quirk(dev))
0060 return dev->core_index;
0061 if (bcma_core_mips_bcm5357b0_quirk(dev))
0062 return dev->core_index;
0063 flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30);
0064
0065 if (flag)
0066 return flag & 0x1F;
0067 else
0068 return 0x3f;
0069 }
0070
0071
0072
0073
0074
0075
0076 unsigned int bcma_core_mips_irq(struct bcma_device *dev)
0077 {
0078 struct bcma_device *mdev = dev->bus->drv_mips.core;
0079 u32 irqflag;
0080 unsigned int irq;
0081
0082 irqflag = bcma_core_mips_irqflag(dev);
0083 if (irqflag == 0x3f)
0084 return 6;
0085
0086 for (irq = 0; irq <= 4; irq++)
0087 if (bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq)) &
0088 (1 << irqflag))
0089 return irq;
0090
0091 return 5;
0092 }
0093
0094 static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
0095 {
0096 unsigned int oldirq = bcma_core_mips_irq(dev);
0097 struct bcma_bus *bus = dev->bus;
0098 struct bcma_device *mdev = bus->drv_mips.core;
0099 u32 irqflag;
0100
0101 irqflag = bcma_core_mips_irqflag(dev);
0102 BUG_ON(oldirq == 6);
0103
0104 dev->irq = irq + 2;
0105
0106
0107 if (oldirq == 0)
0108 bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
0109 bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) &
0110 ~(1 << irqflag));
0111 else if (oldirq != 5)
0112 bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(oldirq), 0);
0113
0114
0115 if (irq == 0) {
0116 bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
0117 bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) |
0118 (1 << irqflag));
0119 } else {
0120 u32 irqinitmask = bcma_read32(mdev,
0121 BCMA_MIPS_MIPS74K_INTMASK(irq));
0122 if (irqinitmask) {
0123 struct bcma_device *core;
0124
0125
0126
0127
0128 list_for_each_entry(core, &bus->cores, list) {
0129 if ((1 << bcma_core_mips_irqflag(core)) ==
0130 irqinitmask) {
0131 bcma_core_mips_set_irq(core, 0);
0132 break;
0133 }
0134 }
0135 }
0136 bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq),
0137 1 << irqflag);
0138 }
0139
0140 bcma_debug(bus, "set_irq: core 0x%04x, irq %d => %d\n",
0141 dev->id.id, oldirq <= 4 ? oldirq + 2 : 0, irq + 2);
0142 }
0143
0144 static void bcma_core_mips_set_irq_name(struct bcma_bus *bus, unsigned int irq,
0145 u16 coreid, u8 unit)
0146 {
0147 struct bcma_device *core;
0148
0149 core = bcma_find_core_unit(bus, coreid, unit);
0150 if (!core) {
0151 bcma_warn(bus,
0152 "Can not find core (id: 0x%x, unit %i) for IRQ configuration.\n",
0153 coreid, unit);
0154 return;
0155 }
0156
0157 bcma_core_mips_set_irq(core, irq);
0158 }
0159
0160 static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq)
0161 {
0162 int i;
0163 static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
0164 char interrupts[25];
0165 char *ints = interrupts;
0166
0167 for (i = 0; i < ARRAY_SIZE(irq_name); i++)
0168 ints += sprintf(ints, " %s%c",
0169 irq_name[i], i == irq ? '*' : ' ');
0170
0171 bcma_debug(dev->bus, "core 0x%04x, irq:%s\n", dev->id.id, interrupts);
0172 }
0173
0174 static void bcma_core_mips_dump_irq(struct bcma_bus *bus)
0175 {
0176 struct bcma_device *core;
0177
0178 list_for_each_entry(core, &bus->cores, list) {
0179 bcma_core_mips_print_irq(core, bcma_core_mips_irq(core));
0180 }
0181 }
0182
0183 u32 bcma_cpu_clock(struct bcma_drv_mips *mcore)
0184 {
0185 struct bcma_bus *bus = mcore->core->bus;
0186
0187 if (bus->drv_cc.capabilities & BCMA_CC_CAP_PMU)
0188 return bcma_pmu_get_cpu_clock(&bus->drv_cc);
0189
0190 bcma_err(bus, "No PMU available, need this to get the cpu clock\n");
0191 return 0;
0192 }
0193 EXPORT_SYMBOL(bcma_cpu_clock);
0194
0195 static enum bcma_boot_dev bcma_boot_dev(struct bcma_bus *bus)
0196 {
0197 struct bcma_drv_cc *cc = &bus->drv_cc;
0198 u8 cc_rev = cc->core->id.rev;
0199
0200 if (cc_rev == 42) {
0201 struct bcma_device *core;
0202
0203 core = bcma_find_core(bus, BCMA_CORE_NS_ROM);
0204 if (core) {
0205 switch (bcma_aread32(core, BCMA_IOST) &
0206 BCMA_NS_ROM_IOST_BOOT_DEV_MASK) {
0207 case BCMA_NS_ROM_IOST_BOOT_DEV_NOR:
0208 return BCMA_BOOT_DEV_SERIAL;
0209 case BCMA_NS_ROM_IOST_BOOT_DEV_NAND:
0210 return BCMA_BOOT_DEV_NAND;
0211 case BCMA_NS_ROM_IOST_BOOT_DEV_ROM:
0212 default:
0213 return BCMA_BOOT_DEV_ROM;
0214 }
0215 }
0216 } else {
0217 if (cc_rev == 38) {
0218 if (cc->status & BCMA_CC_CHIPST_5357_NAND_BOOT)
0219 return BCMA_BOOT_DEV_NAND;
0220 else if (cc->status & BIT(5))
0221 return BCMA_BOOT_DEV_ROM;
0222 }
0223
0224 if ((cc->capabilities & BCMA_CC_CAP_FLASHT) ==
0225 BCMA_CC_FLASHT_PARA)
0226 return BCMA_BOOT_DEV_PARALLEL;
0227 else
0228 return BCMA_BOOT_DEV_SERIAL;
0229 }
0230
0231 return BCMA_BOOT_DEV_SERIAL;
0232 }
0233
0234 static void bcma_core_mips_nvram_init(struct bcma_drv_mips *mcore)
0235 {
0236 struct bcma_bus *bus = mcore->core->bus;
0237 enum bcma_boot_dev boot_dev;
0238
0239
0240 boot_dev = bcma_boot_dev(bus);
0241 switch (boot_dev) {
0242 case BCMA_BOOT_DEV_PARALLEL:
0243 case BCMA_BOOT_DEV_SERIAL:
0244 #ifdef CONFIG_BCM47XX
0245 bcm47xx_nvram_init_from_mem(BCMA_SOC_FLASH2,
0246 BCMA_SOC_FLASH2_SZ);
0247 #endif
0248 break;
0249 case BCMA_BOOT_DEV_NAND:
0250 #ifdef CONFIG_BCM47XX
0251 bcm47xx_nvram_init_from_mem(BCMA_SOC_FLASH1,
0252 BCMA_SOC_FLASH1_SZ);
0253 #endif
0254 break;
0255 default:
0256 break;
0257 }
0258 }
0259
0260 void bcma_core_mips_early_init(struct bcma_drv_mips *mcore)
0261 {
0262 struct bcma_bus *bus = mcore->core->bus;
0263
0264 if (mcore->early_setup_done)
0265 return;
0266
0267 bcma_chipco_serial_init(&bus->drv_cc);
0268 bcma_core_mips_nvram_init(mcore);
0269
0270 mcore->early_setup_done = true;
0271 }
0272
0273 static void bcma_fix_i2s_irqflag(struct bcma_bus *bus)
0274 {
0275 struct bcma_device *cpu, *pcie, *i2s;
0276
0277
0278
0279
0280 if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4716 &&
0281 bus->chipinfo.id != BCMA_CHIP_ID_BCM4748)
0282 return;
0283
0284 cpu = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
0285 pcie = bcma_find_core(bus, BCMA_CORE_PCIE);
0286 i2s = bcma_find_core(bus, BCMA_CORE_I2S);
0287 if (cpu && pcie && i2s &&
0288 bcma_aread32(cpu, BCMA_MIPS_OOBSELINA74) == 0x08060504 &&
0289 bcma_aread32(pcie, BCMA_MIPS_OOBSELINA74) == 0x08060504 &&
0290 bcma_aread32(i2s, BCMA_MIPS_OOBSELOUTA30) == 0x88) {
0291 bcma_awrite32(cpu, BCMA_MIPS_OOBSELINA74, 0x07060504);
0292 bcma_awrite32(pcie, BCMA_MIPS_OOBSELINA74, 0x07060504);
0293 bcma_awrite32(i2s, BCMA_MIPS_OOBSELOUTA30, 0x87);
0294 bcma_debug(bus,
0295 "Moved i2s interrupt to oob line 7 instead of 8\n");
0296 }
0297 }
0298
0299 void bcma_core_mips_init(struct bcma_drv_mips *mcore)
0300 {
0301 struct bcma_bus *bus;
0302 struct bcma_device *core;
0303 bus = mcore->core->bus;
0304
0305 if (mcore->setup_done)
0306 return;
0307
0308 bcma_debug(bus, "Initializing MIPS core...\n");
0309
0310 bcma_core_mips_early_init(mcore);
0311
0312 bcma_fix_i2s_irqflag(bus);
0313
0314 switch (bus->chipinfo.id) {
0315 case BCMA_CHIP_ID_BCM4716:
0316 case BCMA_CHIP_ID_BCM4748:
0317 bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0);
0318 bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0);
0319 bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_USB20_HOST, 0);
0320 bcma_core_mips_set_irq_name(bus, 4, BCMA_CORE_PCIE, 0);
0321 bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0);
0322 bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_I2S, 0);
0323 break;
0324 case BCMA_CHIP_ID_BCM5356:
0325 case BCMA_CHIP_ID_BCM47162:
0326 case BCMA_CHIP_ID_BCM53572:
0327 bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0);
0328 bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0);
0329 bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0);
0330 break;
0331 case BCMA_CHIP_ID_BCM5357:
0332 case BCMA_CHIP_ID_BCM4749:
0333 bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0);
0334 bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0);
0335 bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_USB20_HOST, 0);
0336 bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0);
0337 bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_I2S, 0);
0338 break;
0339 case BCMA_CHIP_ID_BCM4706:
0340 bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_PCIE, 0);
0341 bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_4706_MAC_GBIT,
0342 0);
0343 bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_PCIE, 1);
0344 bcma_core_mips_set_irq_name(bus, 4, BCMA_CORE_USB20_HOST, 0);
0345 bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_4706_CHIPCOMMON,
0346 0);
0347 break;
0348 default:
0349 list_for_each_entry(core, &bus->cores, list) {
0350 core->irq = bcma_core_irq(core, 0);
0351 }
0352 bcma_err(bus,
0353 "Unknown device (0x%x) found, can not configure IRQs\n",
0354 bus->chipinfo.id);
0355 }
0356 bcma_debug(bus, "IRQ reconfiguration done\n");
0357 bcma_core_mips_dump_irq(bus);
0358
0359 mcore->setup_done = true;
0360 }