698 lines · c
1/*2 * Sonics Silicon Backplane3 * Broadcom ChipCommon core driver4 *5 * Copyright 2005, Broadcom Corporation6 * Copyright 2006, 2007, Michael Buesch <m@bues.ch>7 * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de>8 *9 * Licensed under the GNU/GPL. See COPYING for details.10 */11 12#include "ssb_private.h"13 14#include <linux/ssb/ssb.h>15#include <linux/ssb/ssb_regs.h>16#include <linux/export.h>17#include <linux/pci.h>18#include <linux/bcm47xx_wdt.h>19 20 21/* Clock sources */22enum ssb_clksrc {23 /* PCI clock */24 SSB_CHIPCO_CLKSRC_PCI,25 /* Crystal slow clock oscillator */26 SSB_CHIPCO_CLKSRC_XTALOS,27 /* Low power oscillator */28 SSB_CHIPCO_CLKSRC_LOPWROS,29};30 31 32static inline u32 chipco_write32_masked(struct ssb_chipcommon *cc, u16 offset,33 u32 mask, u32 value)34{35 value &= mask;36 value |= chipco_read32(cc, offset) & ~mask;37 chipco_write32(cc, offset, value);38 39 return value;40}41 42void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc,43 enum ssb_clkmode mode)44{45 struct ssb_device *ccdev = cc->dev;46 struct ssb_bus *bus;47 u32 tmp;48 49 if (!ccdev)50 return;51 bus = ccdev->bus;52 53 /* We support SLOW only on 6..9 */54 if (ccdev->id.revision >= 10 && mode == SSB_CLKMODE_SLOW)55 mode = SSB_CLKMODE_DYNAMIC;56 57 if (cc->capabilities & SSB_CHIPCO_CAP_PMU)58 return; /* PMU controls clockmode, separated function needed */59 WARN_ON(ccdev->id.revision >= 20);60 61 /* chipcommon cores prior to rev6 don't support dynamic clock control */62 if (ccdev->id.revision < 6)63 return;64 65 /* ChipCommon cores rev10+ need testing */66 if (ccdev->id.revision >= 10)67 return;68 69 if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL))70 return;71 72 switch (mode) {73 case SSB_CLKMODE_SLOW: /* For revs 6..9 only */74 tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);75 tmp |= SSB_CHIPCO_SLOWCLKCTL_FSLOW;76 chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);77 break;78 case SSB_CLKMODE_FAST:79 if (ccdev->id.revision < 10) {80 ssb_pci_xtal(bus, SSB_GPIO_XTAL, 1); /* Force crystal on */81 tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);82 tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;83 tmp |= SSB_CHIPCO_SLOWCLKCTL_IPLL;84 chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);85 } else {86 chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL,87 (chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) |88 SSB_CHIPCO_SYSCLKCTL_FORCEHT));89 /* udelay(150); TODO: not available in early init */90 }91 break;92 case SSB_CLKMODE_DYNAMIC:93 if (ccdev->id.revision < 10) {94 tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);95 tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;96 tmp &= ~SSB_CHIPCO_SLOWCLKCTL_IPLL;97 tmp &= ~SSB_CHIPCO_SLOWCLKCTL_ENXTAL;98 if ((tmp & SSB_CHIPCO_SLOWCLKCTL_SRC) !=99 SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL)100 tmp |= SSB_CHIPCO_SLOWCLKCTL_ENXTAL;101 chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);102 103 /* For dynamic control, we have to release our xtal_pu104 * "force on" */105 if (tmp & SSB_CHIPCO_SLOWCLKCTL_ENXTAL)106 ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0);107 } else {108 chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL,109 (chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) &110 ~SSB_CHIPCO_SYSCLKCTL_FORCEHT));111 }112 break;113 default:114 WARN_ON(1);115 }116}117 118/* Get the Slow Clock Source */119static enum ssb_clksrc chipco_pctl_get_slowclksrc(struct ssb_chipcommon *cc)120{121 struct ssb_bus *bus = cc->dev->bus;122 u32 tmp;123 124 if (cc->dev->id.revision < 6) {125 if (bus->bustype == SSB_BUSTYPE_SSB ||126 bus->bustype == SSB_BUSTYPE_PCMCIA)127 return SSB_CHIPCO_CLKSRC_XTALOS;128 if (bus->bustype == SSB_BUSTYPE_PCI) {129 pci_read_config_dword(bus->host_pci, SSB_GPIO_OUT, &tmp);130 if (tmp & 0x10)131 return SSB_CHIPCO_CLKSRC_PCI;132 return SSB_CHIPCO_CLKSRC_XTALOS;133 }134 }135 if (cc->dev->id.revision < 10) {136 tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);137 tmp &= 0x7;138 if (tmp == 0)139 return SSB_CHIPCO_CLKSRC_LOPWROS;140 if (tmp == 1)141 return SSB_CHIPCO_CLKSRC_XTALOS;142 if (tmp == 2)143 return SSB_CHIPCO_CLKSRC_PCI;144 }145 146 return SSB_CHIPCO_CLKSRC_XTALOS;147}148 149/* Get maximum or minimum (depending on get_max flag) slowclock frequency. */150static int chipco_pctl_clockfreqlimit(struct ssb_chipcommon *cc, int get_max)151{152 int limit;153 enum ssb_clksrc clocksrc;154 int divisor = 1;155 u32 tmp;156 157 clocksrc = chipco_pctl_get_slowclksrc(cc);158 if (cc->dev->id.revision < 6) {159 switch (clocksrc) {160 case SSB_CHIPCO_CLKSRC_PCI:161 divisor = 64;162 break;163 case SSB_CHIPCO_CLKSRC_XTALOS:164 divisor = 32;165 break;166 default:167 WARN_ON(1);168 }169 } else if (cc->dev->id.revision < 10) {170 switch (clocksrc) {171 case SSB_CHIPCO_CLKSRC_LOPWROS:172 break;173 case SSB_CHIPCO_CLKSRC_XTALOS:174 case SSB_CHIPCO_CLKSRC_PCI:175 tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);176 divisor = (tmp >> 16) + 1;177 divisor *= 4;178 break;179 }180 } else {181 tmp = chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL);182 divisor = (tmp >> 16) + 1;183 divisor *= 4;184 }185 186 switch (clocksrc) {187 case SSB_CHIPCO_CLKSRC_LOPWROS:188 if (get_max)189 limit = 43000;190 else191 limit = 25000;192 break;193 case SSB_CHIPCO_CLKSRC_XTALOS:194 if (get_max)195 limit = 20200000;196 else197 limit = 19800000;198 break;199 case SSB_CHIPCO_CLKSRC_PCI:200 if (get_max)201 limit = 34000000;202 else203 limit = 25000000;204 break;205 }206 limit /= divisor;207 208 return limit;209}210 211static void chipco_powercontrol_init(struct ssb_chipcommon *cc)212{213 struct ssb_bus *bus = cc->dev->bus;214 215 if (bus->chip_id == 0x4321) {216 if (bus->chip_rev == 0)217 chipco_write32(cc, SSB_CHIPCO_CHIPCTL, 0x3A4);218 else if (bus->chip_rev == 1)219 chipco_write32(cc, SSB_CHIPCO_CHIPCTL, 0xA4);220 }221 222 if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL))223 return;224 225 if (cc->dev->id.revision >= 10) {226 /* Set Idle Power clock rate to 1Mhz */227 chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL,228 (chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) &229 0x0000FFFF) | 0x00040000);230 } else {231 int maxfreq;232 233 maxfreq = chipco_pctl_clockfreqlimit(cc, 1);234 chipco_write32(cc, SSB_CHIPCO_PLLONDELAY,235 (maxfreq * 150 + 999999) / 1000000);236 chipco_write32(cc, SSB_CHIPCO_FREFSELDELAY,237 (maxfreq * 15 + 999999) / 1000000);238 }239}240 241/* https://bcm-v4.sipsolutions.net/802.11/PmuFastPwrupDelay */242static u16 pmu_fast_powerup_delay(struct ssb_chipcommon *cc)243{244 struct ssb_bus *bus = cc->dev->bus;245 246 switch (bus->chip_id) {247 case 0x4312:248 case 0x4322:249 case 0x4328:250 return 7000;251 case 0x4325:252 /* TODO: */253 default:254 return 15000;255 }256}257 258/* https://bcm-v4.sipsolutions.net/802.11/ClkctlFastPwrupDelay */259static void calc_fast_powerup_delay(struct ssb_chipcommon *cc)260{261 struct ssb_bus *bus = cc->dev->bus;262 int minfreq;263 unsigned int tmp;264 u32 pll_on_delay;265 266 if (bus->bustype != SSB_BUSTYPE_PCI)267 return;268 269 if (cc->capabilities & SSB_CHIPCO_CAP_PMU) {270 cc->fast_pwrup_delay = pmu_fast_powerup_delay(cc);271 return;272 }273 274 if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL))275 return;276 277 minfreq = chipco_pctl_clockfreqlimit(cc, 0);278 pll_on_delay = chipco_read32(cc, SSB_CHIPCO_PLLONDELAY);279 tmp = (((pll_on_delay + 2) * 1000000) + (minfreq - 1)) / minfreq;280 WARN_ON(tmp & ~0xFFFF);281 282 cc->fast_pwrup_delay = tmp;283}284 285static u32 ssb_chipco_alp_clock(struct ssb_chipcommon *cc)286{287 if (cc->capabilities & SSB_CHIPCO_CAP_PMU)288 return ssb_pmu_get_alp_clock(cc);289 290 return 20000000;291}292 293static u32 ssb_chipco_watchdog_get_max_timer(struct ssb_chipcommon *cc)294{295 u32 nb;296 297 if (cc->capabilities & SSB_CHIPCO_CAP_PMU) {298 if (cc->dev->id.revision < 26)299 nb = 16;300 else301 nb = (cc->dev->id.revision >= 37) ? 32 : 24;302 } else {303 nb = 28;304 }305 if (nb == 32)306 return 0xffffffff;307 else308 return (1 << nb) - 1;309}310 311u32 ssb_chipco_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, u32 ticks)312{313 struct ssb_chipcommon *cc = bcm47xx_wdt_get_drvdata(wdt);314 315 if (cc->dev->bus->bustype != SSB_BUSTYPE_SSB)316 return 0;317 318 return ssb_chipco_watchdog_timer_set(cc, ticks);319}320 321u32 ssb_chipco_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms)322{323 struct ssb_chipcommon *cc = bcm47xx_wdt_get_drvdata(wdt);324 u32 ticks;325 326 if (cc->dev->bus->bustype != SSB_BUSTYPE_SSB)327 return 0;328 329 ticks = ssb_chipco_watchdog_timer_set(cc, cc->ticks_per_ms * ms);330 return ticks / cc->ticks_per_ms;331}332 333static int ssb_chipco_watchdog_ticks_per_ms(struct ssb_chipcommon *cc)334{335 struct ssb_bus *bus = cc->dev->bus;336 337 if (cc->capabilities & SSB_CHIPCO_CAP_PMU) {338 /* based on 32KHz ILP clock */339 return 32;340 } else {341 if (cc->dev->id.revision < 18)342 return ssb_clockspeed(bus) / 1000;343 else344 return ssb_chipco_alp_clock(cc) / 1000;345 }346}347 348void ssb_chipcommon_init(struct ssb_chipcommon *cc)349{350 if (!cc->dev)351 return; /* We don't have a ChipCommon */352 353 spin_lock_init(&cc->gpio_lock);354 355 if (cc->dev->id.revision >= 11)356 cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT);357 dev_dbg(cc->dev->dev, "chipcommon status is 0x%x\n", cc->status);358 359 if (cc->dev->id.revision >= 20) {360 chipco_write32(cc, SSB_CHIPCO_GPIOPULLUP, 0);361 chipco_write32(cc, SSB_CHIPCO_GPIOPULLDOWN, 0);362 }363 364 ssb_pmu_init(cc);365 chipco_powercontrol_init(cc);366 ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);367 calc_fast_powerup_delay(cc);368 369 if (cc->dev->bus->bustype == SSB_BUSTYPE_SSB) {370 cc->ticks_per_ms = ssb_chipco_watchdog_ticks_per_ms(cc);371 cc->max_timer_ms = ssb_chipco_watchdog_get_max_timer(cc) / cc->ticks_per_ms;372 }373}374 375void ssb_chipco_suspend(struct ssb_chipcommon *cc)376{377 if (!cc->dev)378 return;379 ssb_chipco_set_clockmode(cc, SSB_CLKMODE_SLOW);380}381 382void ssb_chipco_resume(struct ssb_chipcommon *cc)383{384 if (!cc->dev)385 return;386 chipco_powercontrol_init(cc);387 ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);388}389 390/* Get the processor clock */391void ssb_chipco_get_clockcpu(struct ssb_chipcommon *cc,392 u32 *plltype, u32 *n, u32 *m)393{394 *n = chipco_read32(cc, SSB_CHIPCO_CLOCK_N);395 *plltype = (cc->capabilities & SSB_CHIPCO_CAP_PLLT);396 switch (*plltype) {397 case SSB_PLLTYPE_2:398 case SSB_PLLTYPE_4:399 case SSB_PLLTYPE_6:400 case SSB_PLLTYPE_7:401 *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_MIPS);402 break;403 case SSB_PLLTYPE_3:404 /* 5350 uses m2 to control mips */405 *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_M2);406 break;407 default:408 *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_SB);409 break;410 }411}412 413/* Get the bus clock */414void ssb_chipco_get_clockcontrol(struct ssb_chipcommon *cc,415 u32 *plltype, u32 *n, u32 *m)416{417 *n = chipco_read32(cc, SSB_CHIPCO_CLOCK_N);418 *plltype = (cc->capabilities & SSB_CHIPCO_CAP_PLLT);419 switch (*plltype) {420 case SSB_PLLTYPE_6: /* 100/200 or 120/240 only */421 *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_MIPS);422 break;423 case SSB_PLLTYPE_3: /* 25Mhz, 2 dividers */424 if (cc->dev->bus->chip_id != 0x5365) {425 *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_M2);426 break;427 }428 fallthrough;429 default:430 *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_SB);431 }432}433 434void ssb_chipco_timing_init(struct ssb_chipcommon *cc,435 unsigned long ns)436{437 struct ssb_device *dev = cc->dev;438 struct ssb_bus *bus = dev->bus;439 u32 tmp;440 441 /* set register for external IO to control LED. */442 chipco_write32(cc, SSB_CHIPCO_PROG_CFG, 0x11);443 tmp = DIV_ROUND_UP(10, ns) << SSB_PROG_WCNT_3_SHIFT; /* Waitcount-3 = 10ns */444 tmp |= DIV_ROUND_UP(40, ns) << SSB_PROG_WCNT_1_SHIFT; /* Waitcount-1 = 40ns */445 tmp |= DIV_ROUND_UP(240, ns); /* Waitcount-0 = 240ns */446 chipco_write32(cc, SSB_CHIPCO_PROG_WAITCNT, tmp); /* 0x01020a0c for a 100Mhz clock */447 448 /* Set timing for the flash */449 tmp = DIV_ROUND_UP(10, ns) << SSB_FLASH_WCNT_3_SHIFT; /* Waitcount-3 = 10nS */450 tmp |= DIV_ROUND_UP(10, ns) << SSB_FLASH_WCNT_1_SHIFT; /* Waitcount-1 = 10nS */451 tmp |= DIV_ROUND_UP(120, ns); /* Waitcount-0 = 120nS */452 if ((bus->chip_id == 0x5365) ||453 (dev->id.revision < 9))454 chipco_write32(cc, SSB_CHIPCO_FLASH_WAITCNT, tmp);455 if ((bus->chip_id == 0x5365) ||456 (dev->id.revision < 9) ||457 ((bus->chip_id == 0x5350) && (bus->chip_rev == 0)))458 chipco_write32(cc, SSB_CHIPCO_PCMCIA_MEMWAIT, tmp);459 460 if (bus->chip_id == 0x5350) {461 /* Enable EXTIF */462 tmp = DIV_ROUND_UP(10, ns) << SSB_PROG_WCNT_3_SHIFT; /* Waitcount-3 = 10ns */463 tmp |= DIV_ROUND_UP(20, ns) << SSB_PROG_WCNT_2_SHIFT; /* Waitcount-2 = 20ns */464 tmp |= DIV_ROUND_UP(100, ns) << SSB_PROG_WCNT_1_SHIFT; /* Waitcount-1 = 100ns */465 tmp |= DIV_ROUND_UP(120, ns); /* Waitcount-0 = 120ns */466 chipco_write32(cc, SSB_CHIPCO_PROG_WAITCNT, tmp); /* 0x01020a0c for a 100Mhz clock */467 }468}469 470/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */471u32 ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks)472{473 u32 maxt;474 enum ssb_clkmode clkmode;475 476 maxt = ssb_chipco_watchdog_get_max_timer(cc);477 if (cc->capabilities & SSB_CHIPCO_CAP_PMU) {478 if (ticks == 1)479 ticks = 2;480 else if (ticks > maxt)481 ticks = maxt;482 chipco_write32(cc, SSB_CHIPCO_PMU_WATCHDOG, ticks);483 } else {484 clkmode = ticks ? SSB_CLKMODE_FAST : SSB_CLKMODE_DYNAMIC;485 ssb_chipco_set_clockmode(cc, clkmode);486 if (ticks > maxt)487 ticks = maxt;488 /* instant NMI */489 chipco_write32(cc, SSB_CHIPCO_WATCHDOG, ticks);490 }491 return ticks;492}493 494void ssb_chipco_irq_mask(struct ssb_chipcommon *cc, u32 mask, u32 value)495{496 chipco_write32_masked(cc, SSB_CHIPCO_IRQMASK, mask, value);497}498 499u32 ssb_chipco_irq_status(struct ssb_chipcommon *cc, u32 mask)500{501 return chipco_read32(cc, SSB_CHIPCO_IRQSTAT) & mask;502}503 504u32 ssb_chipco_gpio_in(struct ssb_chipcommon *cc, u32 mask)505{506 return chipco_read32(cc, SSB_CHIPCO_GPIOIN) & mask;507}508 509u32 ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value)510{511 unsigned long flags;512 u32 res = 0;513 514 spin_lock_irqsave(&cc->gpio_lock, flags);515 res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUT, mask, value);516 spin_unlock_irqrestore(&cc->gpio_lock, flags);517 518 return res;519}520 521u32 ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value)522{523 unsigned long flags;524 u32 res = 0;525 526 spin_lock_irqsave(&cc->gpio_lock, flags);527 res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUTEN, mask, value);528 spin_unlock_irqrestore(&cc->gpio_lock, flags);529 530 return res;531}532 533u32 ssb_chipco_gpio_control(struct ssb_chipcommon *cc, u32 mask, u32 value)534{535 unsigned long flags;536 u32 res = 0;537 538 spin_lock_irqsave(&cc->gpio_lock, flags);539 res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOCTL, mask, value);540 spin_unlock_irqrestore(&cc->gpio_lock, flags);541 542 return res;543}544EXPORT_SYMBOL(ssb_chipco_gpio_control);545 546u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value)547{548 unsigned long flags;549 u32 res = 0;550 551 spin_lock_irqsave(&cc->gpio_lock, flags);552 res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOIRQ, mask, value);553 spin_unlock_irqrestore(&cc->gpio_lock, flags);554 555 return res;556}557 558u32 ssb_chipco_gpio_polarity(struct ssb_chipcommon *cc, u32 mask, u32 value)559{560 unsigned long flags;561 u32 res = 0;562 563 spin_lock_irqsave(&cc->gpio_lock, flags);564 res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOPOL, mask, value);565 spin_unlock_irqrestore(&cc->gpio_lock, flags);566 567 return res;568}569 570u32 ssb_chipco_gpio_pullup(struct ssb_chipcommon *cc, u32 mask, u32 value)571{572 unsigned long flags;573 u32 res = 0;574 575 if (cc->dev->id.revision < 20)576 return 0xffffffff;577 578 spin_lock_irqsave(&cc->gpio_lock, flags);579 res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOPULLUP, mask, value);580 spin_unlock_irqrestore(&cc->gpio_lock, flags);581 582 return res;583}584 585u32 ssb_chipco_gpio_pulldown(struct ssb_chipcommon *cc, u32 mask, u32 value)586{587 unsigned long flags;588 u32 res = 0;589 590 if (cc->dev->id.revision < 20)591 return 0xffffffff;592 593 spin_lock_irqsave(&cc->gpio_lock, flags);594 res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOPULLDOWN, mask, value);595 spin_unlock_irqrestore(&cc->gpio_lock, flags);596 597 return res;598}599 600#ifdef CONFIG_SSB_SERIAL601int ssb_chipco_serial_init(struct ssb_chipcommon *cc,602 struct ssb_serial_port *ports)603{604 struct ssb_bus *bus = cc->dev->bus;605 int nr_ports = 0;606 u32 plltype;607 unsigned int irq;608 u32 baud_base, div;609 u32 i, n;610 unsigned int ccrev = cc->dev->id.revision;611 612 plltype = (cc->capabilities & SSB_CHIPCO_CAP_PLLT);613 irq = ssb_mips_irq(cc->dev);614 615 if (plltype == SSB_PLLTYPE_1) {616 /* PLL clock */617 baud_base = ssb_calc_clock_rate(plltype,618 chipco_read32(cc, SSB_CHIPCO_CLOCK_N),619 chipco_read32(cc, SSB_CHIPCO_CLOCK_M2));620 div = 1;621 } else {622 if (ccrev == 20) {623 /* BCM5354 uses constant 25MHz clock */624 baud_base = 25000000;625 div = 48;626 /* Set the override bit so we don't divide it */627 chipco_write32(cc, SSB_CHIPCO_CORECTL,628 chipco_read32(cc, SSB_CHIPCO_CORECTL)629 | SSB_CHIPCO_CORECTL_UARTCLK0);630 } else if ((ccrev >= 11) && (ccrev != 15)) {631 baud_base = ssb_chipco_alp_clock(cc);632 div = 1;633 if (ccrev >= 21) {634 /* Turn off UART clock before switching clocksource. */635 chipco_write32(cc, SSB_CHIPCO_CORECTL,636 chipco_read32(cc, SSB_CHIPCO_CORECTL)637 & ~SSB_CHIPCO_CORECTL_UARTCLKEN);638 }639 /* Set the override bit so we don't divide it */640 chipco_write32(cc, SSB_CHIPCO_CORECTL,641 chipco_read32(cc, SSB_CHIPCO_CORECTL)642 | SSB_CHIPCO_CORECTL_UARTCLK0);643 if (ccrev >= 21) {644 /* Re-enable the UART clock. */645 chipco_write32(cc, SSB_CHIPCO_CORECTL,646 chipco_read32(cc, SSB_CHIPCO_CORECTL)647 | SSB_CHIPCO_CORECTL_UARTCLKEN);648 }649 } else if (ccrev >= 3) {650 /* Internal backplane clock */651 baud_base = ssb_clockspeed(bus);652 div = chipco_read32(cc, SSB_CHIPCO_CLKDIV)653 & SSB_CHIPCO_CLKDIV_UART;654 } else {655 /* Fixed internal backplane clock */656 baud_base = 88000000;657 div = 48;658 }659 660 /* Clock source depends on strapping if UartClkOverride is unset */661 if ((ccrev > 0) &&662 !(chipco_read32(cc, SSB_CHIPCO_CORECTL) & SSB_CHIPCO_CORECTL_UARTCLK0)) {663 if ((cc->capabilities & SSB_CHIPCO_CAP_UARTCLK) ==664 SSB_CHIPCO_CAP_UARTCLK_INT) {665 /* Internal divided backplane clock */666 baud_base /= div;667 } else {668 /* Assume external clock of 1.8432 MHz */669 baud_base = 1843200;670 }671 }672 }673 674 /* Determine the registers of the UARTs */675 n = (cc->capabilities & SSB_CHIPCO_CAP_NRUART);676 for (i = 0; i < n; i++) {677 void __iomem *cc_mmio;678 void __iomem *uart_regs;679 680 cc_mmio = cc->dev->bus->mmio + (cc->dev->core_index * SSB_CORE_SIZE);681 uart_regs = cc_mmio + SSB_CHIPCO_UART0_DATA;682 /* Offset changed at after rev 0 */683 if (ccrev == 0)684 uart_regs += (i * 8);685 else686 uart_regs += (i * 256);687 688 nr_ports++;689 ports[i].regs = uart_regs;690 ports[i].irq = irq;691 ports[i].baud_base = baud_base;692 ports[i].reg_shift = 0;693 }694 695 return nr_ports;696}697#endif /* CONFIG_SSB_SERIAL */698