18369ae33SRafał Miłecki /* 28369ae33SRafał Miłecki * Broadcom specific AMBA 38369ae33SRafał Miłecki * ChipCommon core driver 48369ae33SRafał Miłecki * 58369ae33SRafał Miłecki * Copyright 2005, Broadcom Corporation 6eb032b98SMichael Büsch * Copyright 2006, 2007, Michael Buesch <m@bues.ch> 756fd5f07SHauke Mehrtens * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de> 88369ae33SRafał Miłecki * 98369ae33SRafał Miłecki * Licensed under the GNU/GPL. See COPYING for details. 108369ae33SRafał Miłecki */ 118369ae33SRafał Miłecki 128369ae33SRafał Miłecki #include "bcma_private.h" 13a22a3114SHauke Mehrtens #include <linux/bcm47xx_wdt.h> 1444a8e377SPaul Gortmaker #include <linux/export.h> 15a4855f39SHauke Mehrtens #include <linux/platform_device.h> 168369ae33SRafał Miłecki #include <linux/bcma/bcma.h> 178369ae33SRafał Miłecki 188369ae33SRafał Miłecki static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset, 198369ae33SRafał Miłecki u32 mask, u32 value) 208369ae33SRafał Miłecki { 218369ae33SRafał Miłecki value &= mask; 228369ae33SRafał Miłecki value |= bcma_cc_read32(cc, offset) & ~mask; 238369ae33SRafał Miłecki bcma_cc_write32(cc, offset, value); 248369ae33SRafał Miłecki 258369ae33SRafał Miłecki return value; 268369ae33SRafał Miłecki } 278369ae33SRafał Miłecki 286951618bSHauke Mehrtens u32 bcma_chipco_get_alp_clock(struct bcma_drv_cc *cc) 2956fd5f07SHauke Mehrtens { 3056fd5f07SHauke Mehrtens if (cc->capabilities & BCMA_CC_CAP_PMU) 315b5ac414SRafał Miłecki return bcma_pmu_get_alp_clock(cc); 3256fd5f07SHauke Mehrtens 3356fd5f07SHauke Mehrtens return 20000000; 3456fd5f07SHauke Mehrtens } 356951618bSHauke Mehrtens EXPORT_SYMBOL_GPL(bcma_chipco_get_alp_clock); 3656fd5f07SHauke Mehrtens 37f6354c8cSHauke Mehrtens static u32 bcma_chipco_watchdog_get_max_timer(struct bcma_drv_cc *cc) 38f6354c8cSHauke Mehrtens { 39f6354c8cSHauke Mehrtens struct bcma_bus *bus = cc->core->bus; 40f6354c8cSHauke Mehrtens u32 nb; 41f6354c8cSHauke Mehrtens 42f6354c8cSHauke Mehrtens if (cc->capabilities & BCMA_CC_CAP_PMU) { 43f6354c8cSHauke Mehrtens if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) 44f6354c8cSHauke Mehrtens nb = 32; 45f6354c8cSHauke Mehrtens else if (cc->core->id.rev < 26) 46f6354c8cSHauke Mehrtens nb = 16; 47f6354c8cSHauke Mehrtens else 48f6354c8cSHauke Mehrtens nb = (cc->core->id.rev >= 37) ? 32 : 24; 49f6354c8cSHauke Mehrtens } else { 50f6354c8cSHauke Mehrtens nb = 28; 51f6354c8cSHauke Mehrtens } 52f6354c8cSHauke Mehrtens if (nb == 32) 53f6354c8cSHauke Mehrtens return 0xffffffff; 54f6354c8cSHauke Mehrtens else 55f6354c8cSHauke Mehrtens return (1 << nb) - 1; 56f6354c8cSHauke Mehrtens } 57f6354c8cSHauke Mehrtens 58a22a3114SHauke Mehrtens static u32 bcma_chipco_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, 59a22a3114SHauke Mehrtens u32 ticks) 60a22a3114SHauke Mehrtens { 61a22a3114SHauke Mehrtens struct bcma_drv_cc *cc = bcm47xx_wdt_get_drvdata(wdt); 62a22a3114SHauke Mehrtens 63a22a3114SHauke Mehrtens return bcma_chipco_watchdog_timer_set(cc, ticks); 64a22a3114SHauke Mehrtens } 65a22a3114SHauke Mehrtens 66a22a3114SHauke Mehrtens static u32 bcma_chipco_watchdog_timer_set_ms_wdt(struct bcm47xx_wdt *wdt, 67a22a3114SHauke Mehrtens u32 ms) 68a22a3114SHauke Mehrtens { 69a22a3114SHauke Mehrtens struct bcma_drv_cc *cc = bcm47xx_wdt_get_drvdata(wdt); 70a22a3114SHauke Mehrtens u32 ticks; 71a22a3114SHauke Mehrtens 72a22a3114SHauke Mehrtens ticks = bcma_chipco_watchdog_timer_set(cc, cc->ticks_per_ms * ms); 73a22a3114SHauke Mehrtens return ticks / cc->ticks_per_ms; 74a22a3114SHauke Mehrtens } 75a22a3114SHauke Mehrtens 76a22a3114SHauke Mehrtens static int bcma_chipco_watchdog_ticks_per_ms(struct bcma_drv_cc *cc) 77a22a3114SHauke Mehrtens { 78a22a3114SHauke Mehrtens struct bcma_bus *bus = cc->core->bus; 79a22a3114SHauke Mehrtens 80a22a3114SHauke Mehrtens if (cc->capabilities & BCMA_CC_CAP_PMU) { 81a22a3114SHauke Mehrtens if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) 82d0f66df5SOscar Forner Martinez /* 4706 CC and PMU watchdogs are clocked at 1/4 of ALP 83d0f66df5SOscar Forner Martinez * clock 84d0f66df5SOscar Forner Martinez */ 855b5ac414SRafał Miłecki return bcma_chipco_get_alp_clock(cc) / 4000; 86a22a3114SHauke Mehrtens else 87a22a3114SHauke Mehrtens /* based on 32KHz ILP clock */ 88a22a3114SHauke Mehrtens return 32; 89a22a3114SHauke Mehrtens } else { 905b5ac414SRafał Miłecki return bcma_chipco_get_alp_clock(cc) / 1000; 91a22a3114SHauke Mehrtens } 92a22a3114SHauke Mehrtens } 93f6354c8cSHauke Mehrtens 94a4855f39SHauke Mehrtens int bcma_chipco_watchdog_register(struct bcma_drv_cc *cc) 95a4855f39SHauke Mehrtens { 96a4855f39SHauke Mehrtens struct bcm47xx_wdt wdt = {}; 97a4855f39SHauke Mehrtens struct platform_device *pdev; 98a4855f39SHauke Mehrtens 99a4855f39SHauke Mehrtens wdt.driver_data = cc; 100a4855f39SHauke Mehrtens wdt.timer_set = bcma_chipco_watchdog_timer_set_wdt; 101a4855f39SHauke Mehrtens wdt.timer_set_ms = bcma_chipco_watchdog_timer_set_ms_wdt; 102d0f66df5SOscar Forner Martinez wdt.max_timer_ms = 103d0f66df5SOscar Forner Martinez bcma_chipco_watchdog_get_max_timer(cc) / cc->ticks_per_ms; 104a4855f39SHauke Mehrtens 105a4855f39SHauke Mehrtens pdev = platform_device_register_data(NULL, "bcm47xx-wdt", 106a4855f39SHauke Mehrtens cc->core->bus->num, &wdt, 107a4855f39SHauke Mehrtens sizeof(wdt)); 108a4855f39SHauke Mehrtens if (IS_ERR(pdev)) 109a4855f39SHauke Mehrtens return PTR_ERR(pdev); 110a4855f39SHauke Mehrtens 111a4855f39SHauke Mehrtens cc->watchdog = pdev; 112a4855f39SHauke Mehrtens 113a4855f39SHauke Mehrtens return 0; 114a4855f39SHauke Mehrtens } 115a4855f39SHauke Mehrtens 11649655bb8SHauke Mehrtens void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc) 11749655bb8SHauke Mehrtens { 11849655bb8SHauke Mehrtens if (cc->early_setup_done) 11949655bb8SHauke Mehrtens return; 12049655bb8SHauke Mehrtens 121ef85fb28SHauke Mehrtens spin_lock_init(&cc->gpio_lock); 122ef85fb28SHauke Mehrtens 12349655bb8SHauke Mehrtens if (cc->core->id.rev >= 11) 12449655bb8SHauke Mehrtens cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT); 12549655bb8SHauke Mehrtens cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP); 12649655bb8SHauke Mehrtens if (cc->core->id.rev >= 35) 12749655bb8SHauke Mehrtens cc->capabilities_ext = bcma_cc_read32(cc, BCMA_CC_CAP_EXT); 12849655bb8SHauke Mehrtens 12949655bb8SHauke Mehrtens if (cc->capabilities & BCMA_CC_CAP_PMU) 13049655bb8SHauke Mehrtens bcma_pmu_early_init(cc); 13149655bb8SHauke Mehrtens 13249655bb8SHauke Mehrtens cc->early_setup_done = true; 13349655bb8SHauke Mehrtens } 13449655bb8SHauke Mehrtens 1358369ae33SRafał Miłecki void bcma_core_chipcommon_init(struct bcma_drv_cc *cc) 1368369ae33SRafał Miłecki { 13718dfa495SRafał Miłecki u32 leddc_on = 10; 13818dfa495SRafał Miłecki u32 leddc_off = 90; 13918dfa495SRafał Miłecki 140517f43e5SHauke Mehrtens if (cc->setup_done) 141517f43e5SHauke Mehrtens return; 142517f43e5SHauke Mehrtens 14349655bb8SHauke Mehrtens bcma_core_chipcommon_early_init(cc); 1448369ae33SRafał Miłecki 1451073e4eeSRafał Miłecki if (cc->core->id.rev >= 20) { 14688f9b65dSRafał Miłecki u32 pullup = 0, pulldown = 0; 14788f9b65dSRafał Miłecki 14888f9b65dSRafał Miłecki if (cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM43142) { 14988f9b65dSRafał Miłecki pullup = 0x402e0; 15088f9b65dSRafał Miłecki pulldown = 0x20500; 15188f9b65dSRafał Miłecki } 15288f9b65dSRafał Miłecki 15388f9b65dSRafał Miłecki bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, pullup); 15488f9b65dSRafał Miłecki bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, pulldown); 1551073e4eeSRafał Miłecki } 1568369ae33SRafał Miłecki 1578369ae33SRafał Miłecki if (cc->capabilities & BCMA_CC_CAP_PMU) 1588369ae33SRafał Miłecki bcma_pmu_init(cc); 1598369ae33SRafał Miłecki if (cc->capabilities & BCMA_CC_CAP_PCTL) 1603d9d8af3SRafał Miłecki bcma_err(cc->core->bus, "Power control not implemented!\n"); 16118dfa495SRafał Miłecki 16218dfa495SRafał Miłecki if (cc->core->id.rev >= 16) { 16318dfa495SRafał Miłecki if (cc->core->bus->sprom.leddc_on_time && 16418dfa495SRafał Miłecki cc->core->bus->sprom.leddc_off_time) { 16518dfa495SRafał Miłecki leddc_on = cc->core->bus->sprom.leddc_on_time; 16618dfa495SRafał Miłecki leddc_off = cc->core->bus->sprom.leddc_off_time; 16718dfa495SRafał Miłecki } 16818dfa495SRafał Miłecki bcma_cc_write32(cc, BCMA_CC_GPIOTIMER, 16918dfa495SRafał Miłecki ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) | 17018dfa495SRafał Miłecki (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT))); 17118dfa495SRafał Miłecki } 172a22a3114SHauke Mehrtens cc->ticks_per_ms = bcma_chipco_watchdog_ticks_per_ms(cc); 173517f43e5SHauke Mehrtens 174517f43e5SHauke Mehrtens cc->setup_done = true; 1758369ae33SRafał Miłecki } 1768369ae33SRafał Miłecki 1778369ae33SRafał Miłecki /* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */ 178a22a3114SHauke Mehrtens u32 bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks) 1798369ae33SRafał Miłecki { 180f6354c8cSHauke Mehrtens u32 maxt; 181f6354c8cSHauke Mehrtens 182f6354c8cSHauke Mehrtens maxt = bcma_chipco_watchdog_get_max_timer(cc); 183f6354c8cSHauke Mehrtens if (cc->capabilities & BCMA_CC_CAP_PMU) { 184f6354c8cSHauke Mehrtens if (ticks == 1) 185f6354c8cSHauke Mehrtens ticks = 2; 186f6354c8cSHauke Mehrtens else if (ticks > maxt) 187f6354c8cSHauke Mehrtens ticks = maxt; 188f6354c8cSHauke Mehrtens bcma_cc_write32(cc, BCMA_CC_PMU_WATCHDOG, ticks); 189f6354c8cSHauke Mehrtens } else { 19068fcd245SRafał Miłecki struct bcma_bus *bus = cc->core->bus; 19168fcd245SRafał Miłecki 19268fcd245SRafał Miłecki if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4707 && 19368fcd245SRafał Miłecki bus->chipinfo.id != BCMA_CHIP_ID_BCM53018) 19468fcd245SRafał Miłecki bcma_core_set_clockmode(cc->core, 19568fcd245SRafał Miłecki ticks ? BCMA_CLKMODE_FAST : BCMA_CLKMODE_DYNAMIC); 19668fcd245SRafał Miłecki 197f6354c8cSHauke Mehrtens if (ticks > maxt) 198f6354c8cSHauke Mehrtens ticks = maxt; 1998369ae33SRafał Miłecki /* instant NMI */ 2008369ae33SRafał Miłecki bcma_cc_write32(cc, BCMA_CC_WATCHDOG, ticks); 2018369ae33SRafał Miłecki } 202a22a3114SHauke Mehrtens return ticks; 203f6354c8cSHauke Mehrtens } 2048369ae33SRafał Miłecki 2058369ae33SRafał Miłecki void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value) 2068369ae33SRafał Miłecki { 2078369ae33SRafał Miłecki bcma_cc_write32_masked(cc, BCMA_CC_IRQMASK, mask, value); 2088369ae33SRafał Miłecki } 2098369ae33SRafał Miłecki 2108369ae33SRafał Miłecki u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask) 2118369ae33SRafał Miłecki { 2128369ae33SRafał Miłecki return bcma_cc_read32(cc, BCMA_CC_IRQSTAT) & mask; 2138369ae33SRafał Miłecki } 2148369ae33SRafał Miłecki 2158369ae33SRafał Miłecki u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask) 2168369ae33SRafał Miłecki { 2178369ae33SRafał Miłecki return bcma_cc_read32(cc, BCMA_CC_GPIOIN) & mask; 2188369ae33SRafał Miłecki } 2198369ae33SRafał Miłecki 2208369ae33SRafał Miłecki u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value) 2218369ae33SRafał Miłecki { 222ef85fb28SHauke Mehrtens unsigned long flags; 223ef85fb28SHauke Mehrtens u32 res; 224ef85fb28SHauke Mehrtens 225ef85fb28SHauke Mehrtens spin_lock_irqsave(&cc->gpio_lock, flags); 226ef85fb28SHauke Mehrtens res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value); 227ef85fb28SHauke Mehrtens spin_unlock_irqrestore(&cc->gpio_lock, flags); 228ef85fb28SHauke Mehrtens 229ef85fb28SHauke Mehrtens return res; 2308369ae33SRafał Miłecki } 231ca84a6c5SHauke Mehrtens EXPORT_SYMBOL_GPL(bcma_chipco_gpio_out); 2328369ae33SRafał Miłecki 2338369ae33SRafał Miłecki u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value) 2348369ae33SRafał Miłecki { 235ef85fb28SHauke Mehrtens unsigned long flags; 236ef85fb28SHauke Mehrtens u32 res; 237ef85fb28SHauke Mehrtens 238ef85fb28SHauke Mehrtens spin_lock_irqsave(&cc->gpio_lock, flags); 239ef85fb28SHauke Mehrtens res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value); 240ef85fb28SHauke Mehrtens spin_unlock_irqrestore(&cc->gpio_lock, flags); 241ef85fb28SHauke Mehrtens 242ef85fb28SHauke Mehrtens return res; 2438369ae33SRafał Miłecki } 244ca84a6c5SHauke Mehrtens EXPORT_SYMBOL_GPL(bcma_chipco_gpio_outen); 2458369ae33SRafał Miłecki 2463e8bb507SHauke Mehrtens /* 2473e8bb507SHauke Mehrtens * If the bit is set to 0, chipcommon controlls this GPIO, 2483e8bb507SHauke Mehrtens * if the bit is set to 1, it is used by some part of the chip and not our code. 2493e8bb507SHauke Mehrtens */ 2508369ae33SRafał Miłecki u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value) 2518369ae33SRafał Miłecki { 252ef85fb28SHauke Mehrtens unsigned long flags; 253ef85fb28SHauke Mehrtens u32 res; 254ef85fb28SHauke Mehrtens 255ef85fb28SHauke Mehrtens spin_lock_irqsave(&cc->gpio_lock, flags); 256ef85fb28SHauke Mehrtens res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value); 257ef85fb28SHauke Mehrtens spin_unlock_irqrestore(&cc->gpio_lock, flags); 258ef85fb28SHauke Mehrtens 259ef85fb28SHauke Mehrtens return res; 2608369ae33SRafał Miłecki } 2618369ae33SRafał Miłecki EXPORT_SYMBOL_GPL(bcma_chipco_gpio_control); 2628369ae33SRafał Miłecki 2638369ae33SRafał Miłecki u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value) 2648369ae33SRafał Miłecki { 265ef85fb28SHauke Mehrtens unsigned long flags; 266ef85fb28SHauke Mehrtens u32 res; 267ef85fb28SHauke Mehrtens 268ef85fb28SHauke Mehrtens spin_lock_irqsave(&cc->gpio_lock, flags); 269ef85fb28SHauke Mehrtens res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value); 270ef85fb28SHauke Mehrtens spin_unlock_irqrestore(&cc->gpio_lock, flags); 271ef85fb28SHauke Mehrtens 272ef85fb28SHauke Mehrtens return res; 2738369ae33SRafał Miłecki } 2748369ae33SRafał Miłecki 2758369ae33SRafał Miłecki u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value) 2768369ae33SRafał Miłecki { 277ef85fb28SHauke Mehrtens unsigned long flags; 278ef85fb28SHauke Mehrtens u32 res; 279ef85fb28SHauke Mehrtens 280ef85fb28SHauke Mehrtens spin_lock_irqsave(&cc->gpio_lock, flags); 281ef85fb28SHauke Mehrtens res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value); 282ef85fb28SHauke Mehrtens spin_unlock_irqrestore(&cc->gpio_lock, flags); 283ef85fb28SHauke Mehrtens 284ef85fb28SHauke Mehrtens return res; 2858369ae33SRafał Miłecki } 286e3afe0e5SHauke Mehrtens 287ea3488f4SHauke Mehrtens u32 bcma_chipco_gpio_pullup(struct bcma_drv_cc *cc, u32 mask, u32 value) 288ea3488f4SHauke Mehrtens { 289ea3488f4SHauke Mehrtens unsigned long flags; 290ea3488f4SHauke Mehrtens u32 res; 291ea3488f4SHauke Mehrtens 292ea3488f4SHauke Mehrtens if (cc->core->id.rev < 20) 293ea3488f4SHauke Mehrtens return 0; 294ea3488f4SHauke Mehrtens 295ea3488f4SHauke Mehrtens spin_lock_irqsave(&cc->gpio_lock, flags); 296ea3488f4SHauke Mehrtens res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOPULLUP, mask, value); 297ea3488f4SHauke Mehrtens spin_unlock_irqrestore(&cc->gpio_lock, flags); 298ea3488f4SHauke Mehrtens 299ea3488f4SHauke Mehrtens return res; 300ea3488f4SHauke Mehrtens } 301ea3488f4SHauke Mehrtens 302ea3488f4SHauke Mehrtens u32 bcma_chipco_gpio_pulldown(struct bcma_drv_cc *cc, u32 mask, u32 value) 303ea3488f4SHauke Mehrtens { 304ea3488f4SHauke Mehrtens unsigned long flags; 305ea3488f4SHauke Mehrtens u32 res; 306ea3488f4SHauke Mehrtens 307ea3488f4SHauke Mehrtens if (cc->core->id.rev < 20) 308ea3488f4SHauke Mehrtens return 0; 309ea3488f4SHauke Mehrtens 310ea3488f4SHauke Mehrtens spin_lock_irqsave(&cc->gpio_lock, flags); 311ea3488f4SHauke Mehrtens res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOPULLDOWN, mask, value); 312ea3488f4SHauke Mehrtens spin_unlock_irqrestore(&cc->gpio_lock, flags); 313ea3488f4SHauke Mehrtens 314ea3488f4SHauke Mehrtens return res; 3158369ae33SRafał Miłecki } 316e3afe0e5SHauke Mehrtens 317e3afe0e5SHauke Mehrtens #ifdef CONFIG_BCMA_DRIVER_MIPS 318e3afe0e5SHauke Mehrtens void bcma_chipco_serial_init(struct bcma_drv_cc *cc) 319e3afe0e5SHauke Mehrtens { 320e3afe0e5SHauke Mehrtens unsigned int irq; 321e3afe0e5SHauke Mehrtens u32 baud_base; 322e3afe0e5SHauke Mehrtens u32 i; 323e3afe0e5SHauke Mehrtens unsigned int ccrev = cc->core->id.rev; 324e3afe0e5SHauke Mehrtens struct bcma_serial_port *ports = cc->serial_ports; 325e3afe0e5SHauke Mehrtens 326e3afe0e5SHauke Mehrtens if (ccrev >= 11 && ccrev != 15) { 3275b5ac414SRafał Miłecki baud_base = bcma_chipco_get_alp_clock(cc); 328e3afe0e5SHauke Mehrtens if (ccrev >= 21) { 329e3afe0e5SHauke Mehrtens /* Turn off UART clock before switching clocksource. */ 330e3afe0e5SHauke Mehrtens bcma_cc_write32(cc, BCMA_CC_CORECTL, 331e3afe0e5SHauke Mehrtens bcma_cc_read32(cc, BCMA_CC_CORECTL) 332e3afe0e5SHauke Mehrtens & ~BCMA_CC_CORECTL_UARTCLKEN); 333e3afe0e5SHauke Mehrtens } 334e3afe0e5SHauke Mehrtens /* Set the override bit so we don't divide it */ 335e3afe0e5SHauke Mehrtens bcma_cc_write32(cc, BCMA_CC_CORECTL, 336e3afe0e5SHauke Mehrtens bcma_cc_read32(cc, BCMA_CC_CORECTL) 337e3afe0e5SHauke Mehrtens | BCMA_CC_CORECTL_UARTCLK0); 338e3afe0e5SHauke Mehrtens if (ccrev >= 21) { 339e3afe0e5SHauke Mehrtens /* Re-enable the UART clock. */ 340e3afe0e5SHauke Mehrtens bcma_cc_write32(cc, BCMA_CC_CORECTL, 341e3afe0e5SHauke Mehrtens bcma_cc_read32(cc, BCMA_CC_CORECTL) 342e3afe0e5SHauke Mehrtens | BCMA_CC_CORECTL_UARTCLKEN); 343e3afe0e5SHauke Mehrtens } 344e3afe0e5SHauke Mehrtens } else { 345d0f66df5SOscar Forner Martinez bcma_err(cc->core->bus, "serial not supported on this device ccrev: 0x%x\n", 346d0f66df5SOscar Forner Martinez ccrev); 347e3afe0e5SHauke Mehrtens return; 348e3afe0e5SHauke Mehrtens } 349e3afe0e5SHauke Mehrtens 35085eb92e8SHauke Mehrtens irq = bcma_core_irq(cc->core, 0); 351e3afe0e5SHauke Mehrtens 352e3afe0e5SHauke Mehrtens /* Determine the registers of the UARTs */ 353e3afe0e5SHauke Mehrtens cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART); 354e3afe0e5SHauke Mehrtens for (i = 0; i < cc->nr_serial_ports; i++) { 355e3afe0e5SHauke Mehrtens ports[i].regs = cc->core->io_addr + BCMA_CC_UART0_DATA + 356e3afe0e5SHauke Mehrtens (i * 256); 357e3afe0e5SHauke Mehrtens ports[i].irq = irq; 358e3afe0e5SHauke Mehrtens ports[i].baud_base = baud_base; 359e3afe0e5SHauke Mehrtens ports[i].reg_shift = 0; 360e3afe0e5SHauke Mehrtens } 361e3afe0e5SHauke Mehrtens } 362e3afe0e5SHauke Mehrtens #endif /* CONFIG_BCMA_DRIVER_MIPS */ 363