root/drivers/bcma/driver_chipcommon.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. bcma_cc_write32_masked
  2. bcma_chipco_get_alp_clock
  3. bcma_core_cc_has_pmu_watchdog
  4. bcma_chipco_watchdog_get_max_timer
  5. bcma_chipco_watchdog_timer_set_wdt
  6. bcma_chipco_watchdog_timer_set_ms_wdt
  7. bcma_chipco_watchdog_ticks_per_ms
  8. bcma_chipco_watchdog_register
  9. bcma_core_chipcommon_flash_detect
  10. bcma_core_chipcommon_early_init
  11. bcma_core_chipcommon_init
  12. bcma_chipco_watchdog_timer_set
  13. bcma_chipco_irq_mask
  14. bcma_chipco_irq_status
  15. bcma_chipco_gpio_in
  16. bcma_chipco_gpio_out
  17. bcma_chipco_gpio_outen
  18. bcma_chipco_gpio_control
  19. bcma_chipco_gpio_intmask
  20. bcma_chipco_gpio_polarity
  21. bcma_chipco_gpio_pullup
  22. bcma_chipco_gpio_pulldown
  23. bcma_chipco_serial_init

   1 /*
   2  * Broadcom specific AMBA
   3  * ChipCommon core driver
   4  *
   5  * Copyright 2005, Broadcom Corporation
   6  * 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 "bcma_private.h"
  13 #include <linux/bcm47xx_wdt.h>
  14 #include <linux/export.h>
  15 #include <linux/platform_device.h>
  16 #include <linux/bcma/bcma.h>
  17 
  18 static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset,
  19                                          u32 mask, u32 value)
  20 {
  21         value &= mask;
  22         value |= bcma_cc_read32(cc, offset) & ~mask;
  23         bcma_cc_write32(cc, offset, value);
  24 
  25         return value;
  26 }
  27 
  28 u32 bcma_chipco_get_alp_clock(struct bcma_drv_cc *cc)
  29 {
  30         if (cc->capabilities & BCMA_CC_CAP_PMU)
  31                 return bcma_pmu_get_alp_clock(cc);
  32 
  33         return 20000000;
  34 }
  35 EXPORT_SYMBOL_GPL(bcma_chipco_get_alp_clock);
  36 
  37 static bool bcma_core_cc_has_pmu_watchdog(struct bcma_drv_cc *cc)
  38 {
  39         struct bcma_bus *bus = cc->core->bus;
  40 
  41         if (cc->capabilities & BCMA_CC_CAP_PMU) {
  42                 if (bus->chipinfo.id == BCMA_CHIP_ID_BCM53573) {
  43                         WARN(bus->chipinfo.rev <= 1, "No watchdog available\n");
  44                         /* 53573B0 and 53573B1 have bugged PMU watchdog. It can
  45                          * be enabled but timer can't be bumped. Use CC one
  46                          * instead.
  47                          */
  48                         return false;
  49                 }
  50                 return true;
  51         } else {
  52                 return false;
  53         }
  54 }
  55 
  56 static u32 bcma_chipco_watchdog_get_max_timer(struct bcma_drv_cc *cc)
  57 {
  58         struct bcma_bus *bus = cc->core->bus;
  59         u32 nb;
  60 
  61         if (bcma_core_cc_has_pmu_watchdog(cc)) {
  62                 if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706)
  63                         nb = 32;
  64                 else if (cc->core->id.rev < 26)
  65                         nb = 16;
  66                 else
  67                         nb = (cc->core->id.rev >= 37) ? 32 : 24;
  68         } else {
  69                 nb = 28;
  70         }
  71         if (nb == 32)
  72                 return 0xffffffff;
  73         else
  74                 return (1 << nb) - 1;
  75 }
  76 
  77 static u32 bcma_chipco_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt,
  78                                               u32 ticks)
  79 {
  80         struct bcma_drv_cc *cc = bcm47xx_wdt_get_drvdata(wdt);
  81 
  82         return bcma_chipco_watchdog_timer_set(cc, ticks);
  83 }
  84 
  85 static u32 bcma_chipco_watchdog_timer_set_ms_wdt(struct bcm47xx_wdt *wdt,
  86                                                  u32 ms)
  87 {
  88         struct bcma_drv_cc *cc = bcm47xx_wdt_get_drvdata(wdt);
  89         u32 ticks;
  90 
  91         ticks = bcma_chipco_watchdog_timer_set(cc, cc->ticks_per_ms * ms);
  92         return ticks / cc->ticks_per_ms;
  93 }
  94 
  95 static int bcma_chipco_watchdog_ticks_per_ms(struct bcma_drv_cc *cc)
  96 {
  97         struct bcma_bus *bus = cc->core->bus;
  98 
  99         if (cc->capabilities & BCMA_CC_CAP_PMU) {
 100                 if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706)
 101                         /* 4706 CC and PMU watchdogs are clocked at 1/4 of ALP
 102                          * clock
 103                          */
 104                         return bcma_chipco_get_alp_clock(cc) / 4000;
 105                 else
 106                         /* based on 32KHz ILP clock */
 107                         return 32;
 108         } else {
 109                 return bcma_chipco_get_alp_clock(cc) / 1000;
 110         }
 111 }
 112 
 113 int bcma_chipco_watchdog_register(struct bcma_drv_cc *cc)
 114 {
 115         struct bcma_bus *bus = cc->core->bus;
 116         struct bcm47xx_wdt wdt = {};
 117         struct platform_device *pdev;
 118 
 119         if (bus->chipinfo.id == BCMA_CHIP_ID_BCM53573 &&
 120             bus->chipinfo.rev <= 1) {
 121                 pr_debug("No watchdog on 53573A0 / 53573A1\n");
 122                 return 0;
 123         }
 124 
 125         wdt.driver_data = cc;
 126         wdt.timer_set = bcma_chipco_watchdog_timer_set_wdt;
 127         wdt.timer_set_ms = bcma_chipco_watchdog_timer_set_ms_wdt;
 128         wdt.max_timer_ms =
 129                 bcma_chipco_watchdog_get_max_timer(cc) / cc->ticks_per_ms;
 130 
 131         pdev = platform_device_register_data(NULL, "bcm47xx-wdt",
 132                                              bus->num, &wdt,
 133                                              sizeof(wdt));
 134         if (IS_ERR(pdev))
 135                 return PTR_ERR(pdev);
 136 
 137         cc->watchdog = pdev;
 138 
 139         return 0;
 140 }
 141 
 142 static void bcma_core_chipcommon_flash_detect(struct bcma_drv_cc *cc)
 143 {
 144         struct bcma_bus *bus = cc->core->bus;
 145 
 146         switch (cc->capabilities & BCMA_CC_CAP_FLASHT) {
 147         case BCMA_CC_FLASHT_STSER:
 148         case BCMA_CC_FLASHT_ATSER:
 149                 bcma_debug(bus, "Found serial flash\n");
 150                 bcma_sflash_init(cc);
 151                 break;
 152         case BCMA_CC_FLASHT_PARA:
 153                 bcma_debug(bus, "Found parallel flash\n");
 154                 bcma_pflash_init(cc);
 155                 break;
 156         default:
 157                 bcma_err(bus, "Flash type not supported\n");
 158         }
 159 
 160         if (cc->core->id.rev == 38 ||
 161             bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) {
 162                 if (cc->capabilities & BCMA_CC_CAP_NFLASH) {
 163                         bcma_debug(bus, "Found NAND flash\n");
 164                         bcma_nflash_init(cc);
 165                 }
 166         }
 167 }
 168 
 169 void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc)
 170 {
 171         struct bcma_bus *bus = cc->core->bus;
 172 
 173         if (cc->early_setup_done)
 174                 return;
 175 
 176         spin_lock_init(&cc->gpio_lock);
 177 
 178         if (cc->core->id.rev >= 11)
 179                 cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
 180         cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
 181         if (cc->core->id.rev >= 35)
 182                 cc->capabilities_ext = bcma_cc_read32(cc, BCMA_CC_CAP_EXT);
 183 
 184         if (cc->capabilities & BCMA_CC_CAP_PMU)
 185                 bcma_pmu_early_init(cc);
 186 
 187         if (bus->hosttype == BCMA_HOSTTYPE_SOC)
 188                 bcma_core_chipcommon_flash_detect(cc);
 189 
 190         cc->early_setup_done = true;
 191 }
 192 
 193 void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
 194 {
 195         u32 leddc_on = 10;
 196         u32 leddc_off = 90;
 197 
 198         if (cc->setup_done)
 199                 return;
 200 
 201         bcma_core_chipcommon_early_init(cc);
 202 
 203         if (cc->core->id.rev >= 20) {
 204                 u32 pullup = 0, pulldown = 0;
 205 
 206                 if (cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM43142) {
 207                         pullup = 0x402e0;
 208                         pulldown = 0x20500;
 209                 }
 210 
 211                 bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, pullup);
 212                 bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, pulldown);
 213         }
 214 
 215         if (cc->capabilities & BCMA_CC_CAP_PMU)
 216                 bcma_pmu_init(cc);
 217         if (cc->capabilities & BCMA_CC_CAP_PCTL)
 218                 bcma_err(cc->core->bus, "Power control not implemented!\n");
 219 
 220         if (cc->core->id.rev >= 16) {
 221                 if (cc->core->bus->sprom.leddc_on_time &&
 222                     cc->core->bus->sprom.leddc_off_time) {
 223                         leddc_on = cc->core->bus->sprom.leddc_on_time;
 224                         leddc_off = cc->core->bus->sprom.leddc_off_time;
 225                 }
 226                 bcma_cc_write32(cc, BCMA_CC_GPIOTIMER,
 227                         ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
 228                          (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
 229         }
 230         cc->ticks_per_ms = bcma_chipco_watchdog_ticks_per_ms(cc);
 231 
 232         cc->setup_done = true;
 233 }
 234 
 235 /* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
 236 u32 bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks)
 237 {
 238         u32 maxt;
 239 
 240         maxt = bcma_chipco_watchdog_get_max_timer(cc);
 241         if (bcma_core_cc_has_pmu_watchdog(cc)) {
 242                 if (ticks == 1)
 243                         ticks = 2;
 244                 else if (ticks > maxt)
 245                         ticks = maxt;
 246                 bcma_pmu_write32(cc, BCMA_CC_PMU_WATCHDOG, ticks);
 247         } else {
 248                 struct bcma_bus *bus = cc->core->bus;
 249 
 250                 if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4707 &&
 251                     bus->chipinfo.id != BCMA_CHIP_ID_BCM47094 &&
 252                     bus->chipinfo.id != BCMA_CHIP_ID_BCM53018)
 253                         bcma_core_set_clockmode(cc->core,
 254                                                 ticks ? BCMA_CLKMODE_FAST : BCMA_CLKMODE_DYNAMIC);
 255 
 256                 if (ticks > maxt)
 257                         ticks = maxt;
 258                 /* instant NMI */
 259                 bcma_cc_write32(cc, BCMA_CC_WATCHDOG, ticks);
 260         }
 261         return ticks;
 262 }
 263 
 264 void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value)
 265 {
 266         bcma_cc_write32_masked(cc, BCMA_CC_IRQMASK, mask, value);
 267 }
 268 
 269 u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask)
 270 {
 271         return bcma_cc_read32(cc, BCMA_CC_IRQSTAT) & mask;
 272 }
 273 
 274 u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask)
 275 {
 276         return bcma_cc_read32(cc, BCMA_CC_GPIOIN) & mask;
 277 }
 278 
 279 u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value)
 280 {
 281         unsigned long flags;
 282         u32 res;
 283 
 284         spin_lock_irqsave(&cc->gpio_lock, flags);
 285         res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value);
 286         spin_unlock_irqrestore(&cc->gpio_lock, flags);
 287 
 288         return res;
 289 }
 290 EXPORT_SYMBOL_GPL(bcma_chipco_gpio_out);
 291 
 292 u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value)
 293 {
 294         unsigned long flags;
 295         u32 res;
 296 
 297         spin_lock_irqsave(&cc->gpio_lock, flags);
 298         res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value);
 299         spin_unlock_irqrestore(&cc->gpio_lock, flags);
 300 
 301         return res;
 302 }
 303 EXPORT_SYMBOL_GPL(bcma_chipco_gpio_outen);
 304 
 305 /*
 306  * If the bit is set to 0, chipcommon controlls this GPIO,
 307  * if the bit is set to 1, it is used by some part of the chip and not our code.
 308  */
 309 u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value)
 310 {
 311         unsigned long flags;
 312         u32 res;
 313 
 314         spin_lock_irqsave(&cc->gpio_lock, flags);
 315         res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value);
 316         spin_unlock_irqrestore(&cc->gpio_lock, flags);
 317 
 318         return res;
 319 }
 320 EXPORT_SYMBOL_GPL(bcma_chipco_gpio_control);
 321 
 322 u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value)
 323 {
 324         unsigned long flags;
 325         u32 res;
 326 
 327         spin_lock_irqsave(&cc->gpio_lock, flags);
 328         res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value);
 329         spin_unlock_irqrestore(&cc->gpio_lock, flags);
 330 
 331         return res;
 332 }
 333 
 334 u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value)
 335 {
 336         unsigned long flags;
 337         u32 res;
 338 
 339         spin_lock_irqsave(&cc->gpio_lock, flags);
 340         res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
 341         spin_unlock_irqrestore(&cc->gpio_lock, flags);
 342 
 343         return res;
 344 }
 345 
 346 u32 bcma_chipco_gpio_pullup(struct bcma_drv_cc *cc, u32 mask, u32 value)
 347 {
 348         unsigned long flags;
 349         u32 res;
 350 
 351         if (cc->core->id.rev < 20)
 352                 return 0;
 353 
 354         spin_lock_irqsave(&cc->gpio_lock, flags);
 355         res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOPULLUP, mask, value);
 356         spin_unlock_irqrestore(&cc->gpio_lock, flags);
 357 
 358         return res;
 359 }
 360 
 361 u32 bcma_chipco_gpio_pulldown(struct bcma_drv_cc *cc, u32 mask, u32 value)
 362 {
 363         unsigned long flags;
 364         u32 res;
 365 
 366         if (cc->core->id.rev < 20)
 367                 return 0;
 368 
 369         spin_lock_irqsave(&cc->gpio_lock, flags);
 370         res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOPULLDOWN, mask, value);
 371         spin_unlock_irqrestore(&cc->gpio_lock, flags);
 372 
 373         return res;
 374 }
 375 
 376 #ifdef CONFIG_BCMA_DRIVER_MIPS
 377 void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
 378 {
 379         unsigned int irq;
 380         u32 baud_base;
 381         u32 i;
 382         unsigned int ccrev = cc->core->id.rev;
 383         struct bcma_serial_port *ports = cc->serial_ports;
 384 
 385         if (ccrev >= 11 && ccrev != 15) {
 386                 baud_base = bcma_chipco_get_alp_clock(cc);
 387                 if (ccrev >= 21) {
 388                         /* Turn off UART clock before switching clocksource. */
 389                         bcma_cc_write32(cc, BCMA_CC_CORECTL,
 390                                        bcma_cc_read32(cc, BCMA_CC_CORECTL)
 391                                        & ~BCMA_CC_CORECTL_UARTCLKEN);
 392                 }
 393                 /* Set the override bit so we don't divide it */
 394                 bcma_cc_write32(cc, BCMA_CC_CORECTL,
 395                                bcma_cc_read32(cc, BCMA_CC_CORECTL)
 396                                | BCMA_CC_CORECTL_UARTCLK0);
 397                 if (ccrev >= 21) {
 398                         /* Re-enable the UART clock. */
 399                         bcma_cc_write32(cc, BCMA_CC_CORECTL,
 400                                        bcma_cc_read32(cc, BCMA_CC_CORECTL)
 401                                        | BCMA_CC_CORECTL_UARTCLKEN);
 402                 }
 403         } else {
 404                 bcma_err(cc->core->bus, "serial not supported on this device ccrev: 0x%x\n",
 405                          ccrev);
 406                 return;
 407         }
 408 
 409         irq = bcma_core_irq(cc->core, 0);
 410 
 411         /* Determine the registers of the UARTs */
 412         cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART);
 413         for (i = 0; i < cc->nr_serial_ports; i++) {
 414                 ports[i].regs = cc->core->io_addr + BCMA_CC_UART0_DATA +
 415                                 (i * 256);
 416                 ports[i].irq = irq;
 417                 ports[i].baud_base = baud_base;
 418                 ports[i].reg_shift = 0;
 419         }
 420 }
 421 #endif /* CONFIG_BCMA_DRIVER_MIPS */

/* [<][>][^][v][top][bottom][index][help] */