driver_chipcommon.c 9.9 KB

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