0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include "bcma_private.h"
0013 #include <linux/bcm47xx_wdt.h>
0014 #include <linux/export.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/bcma/bcma.h>
0017
0018 static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset,
0019 u32 mask, u32 value)
0020 {
0021 value &= mask;
0022 value |= bcma_cc_read32(cc, offset) & ~mask;
0023 bcma_cc_write32(cc, offset, value);
0024
0025 return value;
0026 }
0027
0028 u32 bcma_chipco_get_alp_clock(struct bcma_drv_cc *cc)
0029 {
0030 if (cc->capabilities & BCMA_CC_CAP_PMU)
0031 return bcma_pmu_get_alp_clock(cc);
0032
0033 return 20000000;
0034 }
0035 EXPORT_SYMBOL_GPL(bcma_chipco_get_alp_clock);
0036
0037 static bool bcma_core_cc_has_pmu_watchdog(struct bcma_drv_cc *cc)
0038 {
0039 struct bcma_bus *bus = cc->core->bus;
0040
0041 if (cc->capabilities & BCMA_CC_CAP_PMU) {
0042 if (bus->chipinfo.id == BCMA_CHIP_ID_BCM53573) {
0043 WARN(bus->chipinfo.rev <= 1, "No watchdog available\n");
0044
0045
0046
0047
0048 return false;
0049 }
0050 return true;
0051 } else {
0052 return false;
0053 }
0054 }
0055
0056 static u32 bcma_chipco_watchdog_get_max_timer(struct bcma_drv_cc *cc)
0057 {
0058 struct bcma_bus *bus = cc->core->bus;
0059 u32 nb;
0060
0061 if (bcma_core_cc_has_pmu_watchdog(cc)) {
0062 if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706)
0063 nb = 32;
0064 else if (cc->core->id.rev < 26)
0065 nb = 16;
0066 else
0067 nb = (cc->core->id.rev >= 37) ? 32 : 24;
0068 } else {
0069 nb = 28;
0070 }
0071 if (nb == 32)
0072 return 0xffffffff;
0073 else
0074 return (1 << nb) - 1;
0075 }
0076
0077 static u32 bcma_chipco_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt,
0078 u32 ticks)
0079 {
0080 struct bcma_drv_cc *cc = bcm47xx_wdt_get_drvdata(wdt);
0081
0082 return bcma_chipco_watchdog_timer_set(cc, ticks);
0083 }
0084
0085 static u32 bcma_chipco_watchdog_timer_set_ms_wdt(struct bcm47xx_wdt *wdt,
0086 u32 ms)
0087 {
0088 struct bcma_drv_cc *cc = bcm47xx_wdt_get_drvdata(wdt);
0089 u32 ticks;
0090
0091 ticks = bcma_chipco_watchdog_timer_set(cc, cc->ticks_per_ms * ms);
0092 return ticks / cc->ticks_per_ms;
0093 }
0094
0095 static int bcma_chipco_watchdog_ticks_per_ms(struct bcma_drv_cc *cc)
0096 {
0097 struct bcma_bus *bus = cc->core->bus;
0098
0099 if (cc->capabilities & BCMA_CC_CAP_PMU) {
0100 if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706)
0101
0102
0103
0104 return bcma_chipco_get_alp_clock(cc) / 4000;
0105 else
0106
0107 return 32;
0108 } else {
0109 return bcma_chipco_get_alp_clock(cc) / 1000;
0110 }
0111 }
0112
0113 int bcma_chipco_watchdog_register(struct bcma_drv_cc *cc)
0114 {
0115 struct bcma_bus *bus = cc->core->bus;
0116 struct bcm47xx_wdt wdt = {};
0117 struct platform_device *pdev;
0118
0119 if (bus->chipinfo.id == BCMA_CHIP_ID_BCM53573 &&
0120 bus->chipinfo.rev <= 1) {
0121 pr_debug("No watchdog on 53573A0 / 53573A1\n");
0122 return 0;
0123 }
0124
0125 wdt.driver_data = cc;
0126 wdt.timer_set = bcma_chipco_watchdog_timer_set_wdt;
0127 wdt.timer_set_ms = bcma_chipco_watchdog_timer_set_ms_wdt;
0128 wdt.max_timer_ms =
0129 bcma_chipco_watchdog_get_max_timer(cc) / cc->ticks_per_ms;
0130
0131 pdev = platform_device_register_data(NULL, "bcm47xx-wdt",
0132 bus->num, &wdt,
0133 sizeof(wdt));
0134 if (IS_ERR(pdev))
0135 return PTR_ERR(pdev);
0136
0137 cc->watchdog = pdev;
0138
0139 return 0;
0140 }
0141
0142 static void bcma_core_chipcommon_flash_detect(struct bcma_drv_cc *cc)
0143 {
0144 struct bcma_bus *bus = cc->core->bus;
0145
0146 switch (cc->capabilities & BCMA_CC_CAP_FLASHT) {
0147 case BCMA_CC_FLASHT_STSER:
0148 case BCMA_CC_FLASHT_ATSER:
0149 bcma_debug(bus, "Found serial flash\n");
0150 bcma_sflash_init(cc);
0151 break;
0152 case BCMA_CC_FLASHT_PARA:
0153 bcma_debug(bus, "Found parallel flash\n");
0154 bcma_pflash_init(cc);
0155 break;
0156 default:
0157 bcma_err(bus, "Flash type not supported\n");
0158 }
0159
0160 if (cc->core->id.rev == 38 ||
0161 bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) {
0162 if (cc->capabilities & BCMA_CC_CAP_NFLASH) {
0163 bcma_debug(bus, "Found NAND flash\n");
0164 bcma_nflash_init(cc);
0165 }
0166 }
0167 }
0168
0169 void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc)
0170 {
0171 struct bcma_bus *bus = cc->core->bus;
0172
0173 if (cc->early_setup_done)
0174 return;
0175
0176 spin_lock_init(&cc->gpio_lock);
0177
0178 if (cc->core->id.rev >= 11)
0179 cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
0180 cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
0181 if (cc->core->id.rev >= 35)
0182 cc->capabilities_ext = bcma_cc_read32(cc, BCMA_CC_CAP_EXT);
0183
0184 if (cc->capabilities & BCMA_CC_CAP_PMU)
0185 bcma_pmu_early_init(cc);
0186
0187 if (bus->hosttype == BCMA_HOSTTYPE_SOC)
0188 bcma_core_chipcommon_flash_detect(cc);
0189
0190 cc->early_setup_done = true;
0191 }
0192
0193 void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
0194 {
0195 u32 leddc_on = 10;
0196 u32 leddc_off = 90;
0197
0198 if (cc->setup_done)
0199 return;
0200
0201 bcma_core_chipcommon_early_init(cc);
0202
0203 if (cc->core->id.rev >= 20) {
0204 u32 pullup = 0, pulldown = 0;
0205
0206 if (cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM43142) {
0207 pullup = 0x402e0;
0208 pulldown = 0x20500;
0209 }
0210
0211 bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, pullup);
0212 bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, pulldown);
0213 }
0214
0215 if (cc->capabilities & BCMA_CC_CAP_PMU)
0216 bcma_pmu_init(cc);
0217 if (cc->capabilities & BCMA_CC_CAP_PCTL)
0218 bcma_err(cc->core->bus, "Power control not implemented!\n");
0219
0220 if (cc->core->id.rev >= 16) {
0221 if (cc->core->bus->sprom.leddc_on_time &&
0222 cc->core->bus->sprom.leddc_off_time) {
0223 leddc_on = cc->core->bus->sprom.leddc_on_time;
0224 leddc_off = cc->core->bus->sprom.leddc_off_time;
0225 }
0226 bcma_cc_write32(cc, BCMA_CC_GPIOTIMER,
0227 ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
0228 (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
0229 }
0230 cc->ticks_per_ms = bcma_chipco_watchdog_ticks_per_ms(cc);
0231
0232 cc->setup_done = true;
0233 }
0234
0235
0236 u32 bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks)
0237 {
0238 u32 maxt;
0239
0240 maxt = bcma_chipco_watchdog_get_max_timer(cc);
0241 if (bcma_core_cc_has_pmu_watchdog(cc)) {
0242 if (ticks == 1)
0243 ticks = 2;
0244 else if (ticks > maxt)
0245 ticks = maxt;
0246 bcma_pmu_write32(cc, BCMA_CC_PMU_WATCHDOG, ticks);
0247 } else {
0248 struct bcma_bus *bus = cc->core->bus;
0249
0250 if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4707 &&
0251 bus->chipinfo.id != BCMA_CHIP_ID_BCM47094 &&
0252 bus->chipinfo.id != BCMA_CHIP_ID_BCM53018)
0253 bcma_core_set_clockmode(cc->core,
0254 ticks ? BCMA_CLKMODE_FAST : BCMA_CLKMODE_DYNAMIC);
0255
0256 if (ticks > maxt)
0257 ticks = maxt;
0258
0259 bcma_cc_write32(cc, BCMA_CC_WATCHDOG, ticks);
0260 }
0261 return ticks;
0262 }
0263
0264 void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value)
0265 {
0266 bcma_cc_write32_masked(cc, BCMA_CC_IRQMASK, mask, value);
0267 }
0268
0269 u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask)
0270 {
0271 return bcma_cc_read32(cc, BCMA_CC_IRQSTAT) & mask;
0272 }
0273
0274 u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask)
0275 {
0276 return bcma_cc_read32(cc, BCMA_CC_GPIOIN) & mask;
0277 }
0278
0279 u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value)
0280 {
0281 unsigned long flags;
0282 u32 res;
0283
0284 spin_lock_irqsave(&cc->gpio_lock, flags);
0285 res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value);
0286 spin_unlock_irqrestore(&cc->gpio_lock, flags);
0287
0288 return res;
0289 }
0290 EXPORT_SYMBOL_GPL(bcma_chipco_gpio_out);
0291
0292 u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value)
0293 {
0294 unsigned long flags;
0295 u32 res;
0296
0297 spin_lock_irqsave(&cc->gpio_lock, flags);
0298 res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value);
0299 spin_unlock_irqrestore(&cc->gpio_lock, flags);
0300
0301 return res;
0302 }
0303 EXPORT_SYMBOL_GPL(bcma_chipco_gpio_outen);
0304
0305
0306
0307
0308
0309 u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value)
0310 {
0311 unsigned long flags;
0312 u32 res;
0313
0314 spin_lock_irqsave(&cc->gpio_lock, flags);
0315 res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value);
0316 spin_unlock_irqrestore(&cc->gpio_lock, flags);
0317
0318 return res;
0319 }
0320 EXPORT_SYMBOL_GPL(bcma_chipco_gpio_control);
0321
0322 u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value)
0323 {
0324 unsigned long flags;
0325 u32 res;
0326
0327 spin_lock_irqsave(&cc->gpio_lock, flags);
0328 res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value);
0329 spin_unlock_irqrestore(&cc->gpio_lock, flags);
0330
0331 return res;
0332 }
0333
0334 u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value)
0335 {
0336 unsigned long flags;
0337 u32 res;
0338
0339 spin_lock_irqsave(&cc->gpio_lock, flags);
0340 res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
0341 spin_unlock_irqrestore(&cc->gpio_lock, flags);
0342
0343 return res;
0344 }
0345
0346 u32 bcma_chipco_gpio_pullup(struct bcma_drv_cc *cc, u32 mask, u32 value)
0347 {
0348 unsigned long flags;
0349 u32 res;
0350
0351 if (cc->core->id.rev < 20)
0352 return 0;
0353
0354 spin_lock_irqsave(&cc->gpio_lock, flags);
0355 res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOPULLUP, mask, value);
0356 spin_unlock_irqrestore(&cc->gpio_lock, flags);
0357
0358 return res;
0359 }
0360
0361 u32 bcma_chipco_gpio_pulldown(struct bcma_drv_cc *cc, u32 mask, u32 value)
0362 {
0363 unsigned long flags;
0364 u32 res;
0365
0366 if (cc->core->id.rev < 20)
0367 return 0;
0368
0369 spin_lock_irqsave(&cc->gpio_lock, flags);
0370 res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOPULLDOWN, mask, value);
0371 spin_unlock_irqrestore(&cc->gpio_lock, flags);
0372
0373 return res;
0374 }
0375
0376 #ifdef CONFIG_BCMA_DRIVER_MIPS
0377 void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
0378 {
0379 unsigned int irq;
0380 u32 baud_base;
0381 u32 i;
0382 unsigned int ccrev = cc->core->id.rev;
0383 struct bcma_serial_port *ports = cc->serial_ports;
0384
0385 if (ccrev >= 11 && ccrev != 15) {
0386 baud_base = bcma_chipco_get_alp_clock(cc);
0387 if (ccrev >= 21) {
0388
0389 bcma_cc_write32(cc, BCMA_CC_CORECTL,
0390 bcma_cc_read32(cc, BCMA_CC_CORECTL)
0391 & ~BCMA_CC_CORECTL_UARTCLKEN);
0392 }
0393
0394 bcma_cc_write32(cc, BCMA_CC_CORECTL,
0395 bcma_cc_read32(cc, BCMA_CC_CORECTL)
0396 | BCMA_CC_CORECTL_UARTCLK0);
0397 if (ccrev >= 21) {
0398
0399 bcma_cc_write32(cc, BCMA_CC_CORECTL,
0400 bcma_cc_read32(cc, BCMA_CC_CORECTL)
0401 | BCMA_CC_CORECTL_UARTCLKEN);
0402 }
0403 } else {
0404 bcma_err(cc->core->bus, "serial not supported on this device ccrev: 0x%x\n",
0405 ccrev);
0406 return;
0407 }
0408
0409 irq = bcma_core_irq(cc->core, 0);
0410
0411
0412 cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART);
0413 for (i = 0; i < cc->nr_serial_ports; i++) {
0414 ports[i].regs = cc->core->io_addr + BCMA_CC_UART0_DATA +
0415 (i * 256);
0416 ports[i].irq = irq;
0417 ports[i].baud_base = baud_base;
0418 ports[i].reg_shift = 0;
0419 }
0420 }
0421 #endif