setup_tx4939.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. /*
  2. * TX4939 setup routines
  3. * Based on linux/arch/mips/txx9/generic/setup_tx4938.c,
  4. * and RBTX49xx patch from CELF patch archive.
  5. *
  6. * 2003-2005 (c) MontaVista Software, Inc.
  7. * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007
  8. *
  9. * This file is subject to the terms and conditions of the GNU General Public
  10. * License. See the file "COPYING" in the main directory of this archive
  11. * for more details.
  12. */
  13. #include <linux/init.h>
  14. #include <linux/ioport.h>
  15. #include <linux/delay.h>
  16. #include <linux/netdevice.h>
  17. #include <linux/notifier.h>
  18. #include <linux/device.h>
  19. #include <linux/ethtool.h>
  20. #include <linux/param.h>
  21. #include <linux/ptrace.h>
  22. #include <linux/mtd/physmap.h>
  23. #include <linux/platform_device.h>
  24. #include <asm/bootinfo.h>
  25. #include <asm/reboot.h>
  26. #include <asm/traps.h>
  27. #include <asm/txx9irq.h>
  28. #include <asm/txx9tmr.h>
  29. #include <asm/txx9/generic.h>
  30. #include <asm/txx9/ndfmc.h>
  31. #include <asm/txx9/dmac.h>
  32. #include <asm/txx9/tx4939.h>
  33. static void __init tx4939_wdr_init(void)
  34. {
  35. /* report watchdog reset status */
  36. if (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDRST)
  37. pr_warn("Watchdog reset detected at 0x%lx\n",
  38. read_c0_errorepc());
  39. /* clear WatchDogReset (W1C) */
  40. tx4939_ccfg_set(TX4939_CCFG_WDRST);
  41. /* do reset on watchdog */
  42. tx4939_ccfg_set(TX4939_CCFG_WR);
  43. }
  44. void __init tx4939_wdt_init(void)
  45. {
  46. txx9_wdt_init(TX4939_TMR_REG(2) & 0xfffffffffULL);
  47. }
  48. static void tx4939_machine_restart(char *command)
  49. {
  50. local_irq_disable();
  51. pr_emerg("Rebooting (with %s watchdog reset)...\n",
  52. (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDREXEN) ?
  53. "external" : "internal");
  54. /* clear watchdog status */
  55. tx4939_ccfg_set(TX4939_CCFG_WDRST); /* W1C */
  56. txx9_wdt_now(TX4939_TMR_REG(2) & 0xfffffffffULL);
  57. while (!(____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDRST))
  58. ;
  59. mdelay(10);
  60. if (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDREXEN) {
  61. pr_emerg("Rebooting (with internal watchdog reset)...\n");
  62. /* External WDRST failed. Do internal watchdog reset */
  63. tx4939_ccfg_clear(TX4939_CCFG_WDREXEN);
  64. }
  65. /* fallback */
  66. (*_machine_halt)();
  67. }
  68. void show_registers(struct pt_regs *regs);
  69. static int tx4939_be_handler(struct pt_regs *regs, int is_fixup)
  70. {
  71. int data = regs->cp0_cause & 4;
  72. console_verbose();
  73. pr_err("%cBE exception at %#lx\n",
  74. data ? 'D' : 'I', regs->cp0_epc);
  75. pr_err("ccfg:%llx, toea:%llx\n",
  76. (unsigned long long)____raw_readq(&tx4939_ccfgptr->ccfg),
  77. (unsigned long long)____raw_readq(&tx4939_ccfgptr->toea));
  78. #ifdef CONFIG_PCI
  79. tx4927_report_pcic_status();
  80. #endif
  81. show_registers(regs);
  82. panic("BusError!");
  83. }
  84. static void __init tx4939_be_init(void)
  85. {
  86. board_be_handler = tx4939_be_handler;
  87. }
  88. static struct resource tx4939_sdram_resource[4];
  89. static struct resource tx4939_sram_resource;
  90. #define TX4939_SRAM_SIZE 0x800
  91. void __init tx4939_add_memory_regions(void)
  92. {
  93. int i;
  94. unsigned long start, size;
  95. u64 win;
  96. for (i = 0; i < 4; i++) {
  97. if (!((__u32)____raw_readq(&tx4939_ddrcptr->winen) & (1 << i)))
  98. continue;
  99. win = ____raw_readq(&tx4939_ddrcptr->win[i]);
  100. start = (unsigned long)(win >> 48);
  101. size = (((unsigned long)(win >> 32) & 0xffff) + 1) - start;
  102. add_memory_region(start << 20, size << 20, BOOT_MEM_RAM);
  103. }
  104. }
  105. void __init tx4939_setup(void)
  106. {
  107. int i;
  108. __u32 divmode;
  109. __u64 pcfg;
  110. unsigned int cpuclk = 0;
  111. txx9_reg_res_init(TX4939_REV_PCODE(), TX4939_REG_BASE,
  112. TX4939_REG_SIZE);
  113. set_c0_config(TX49_CONF_CWFON);
  114. /* SDRAMC,EBUSC are configured by PROM */
  115. for (i = 0; i < 4; i++) {
  116. if (!(TX4939_EBUSC_CR(i) & 0x8))
  117. continue; /* disabled */
  118. txx9_ce_res[i].start = (unsigned long)TX4939_EBUSC_BA(i);
  119. txx9_ce_res[i].end =
  120. txx9_ce_res[i].start + TX4939_EBUSC_SIZE(i) - 1;
  121. request_resource(&iomem_resource, &txx9_ce_res[i]);
  122. }
  123. /* clocks */
  124. if (txx9_master_clock) {
  125. /* calculate cpu_clock from master_clock */
  126. divmode = (__u32)____raw_readq(&tx4939_ccfgptr->ccfg) &
  127. TX4939_CCFG_MULCLK_MASK;
  128. cpuclk = txx9_master_clock * 20 / 2;
  129. switch (divmode) {
  130. case TX4939_CCFG_MULCLK_8:
  131. cpuclk = cpuclk / 3 * 4 /* / 6 * 8 */; break;
  132. case TX4939_CCFG_MULCLK_9:
  133. cpuclk = cpuclk / 2 * 3 /* / 6 * 9 */; break;
  134. case TX4939_CCFG_MULCLK_10:
  135. cpuclk = cpuclk / 3 * 5 /* / 6 * 10 */; break;
  136. case TX4939_CCFG_MULCLK_11:
  137. cpuclk = cpuclk / 6 * 11; break;
  138. case TX4939_CCFG_MULCLK_12:
  139. cpuclk = cpuclk * 2 /* / 6 * 12 */; break;
  140. case TX4939_CCFG_MULCLK_13:
  141. cpuclk = cpuclk / 6 * 13; break;
  142. case TX4939_CCFG_MULCLK_14:
  143. cpuclk = cpuclk / 3 * 7 /* / 6 * 14 */; break;
  144. case TX4939_CCFG_MULCLK_15:
  145. cpuclk = cpuclk / 2 * 5 /* / 6 * 15 */; break;
  146. }
  147. txx9_cpu_clock = cpuclk;
  148. } else {
  149. if (txx9_cpu_clock == 0)
  150. txx9_cpu_clock = 400000000; /* 400MHz */
  151. /* calculate master_clock from cpu_clock */
  152. cpuclk = txx9_cpu_clock;
  153. divmode = (__u32)____raw_readq(&tx4939_ccfgptr->ccfg) &
  154. TX4939_CCFG_MULCLK_MASK;
  155. switch (divmode) {
  156. case TX4939_CCFG_MULCLK_8:
  157. txx9_master_clock = cpuclk * 6 / 8; break;
  158. case TX4939_CCFG_MULCLK_9:
  159. txx9_master_clock = cpuclk * 6 / 9; break;
  160. case TX4939_CCFG_MULCLK_10:
  161. txx9_master_clock = cpuclk * 6 / 10; break;
  162. case TX4939_CCFG_MULCLK_11:
  163. txx9_master_clock = cpuclk * 6 / 11; break;
  164. case TX4939_CCFG_MULCLK_12:
  165. txx9_master_clock = cpuclk * 6 / 12; break;
  166. case TX4939_CCFG_MULCLK_13:
  167. txx9_master_clock = cpuclk * 6 / 13; break;
  168. case TX4939_CCFG_MULCLK_14:
  169. txx9_master_clock = cpuclk * 6 / 14; break;
  170. case TX4939_CCFG_MULCLK_15:
  171. txx9_master_clock = cpuclk * 6 / 15; break;
  172. }
  173. txx9_master_clock /= 10; /* * 2 / 20 */
  174. }
  175. /* calculate gbus_clock from cpu_clock */
  176. divmode = (__u32)____raw_readq(&tx4939_ccfgptr->ccfg) &
  177. TX4939_CCFG_YDIVMODE_MASK;
  178. txx9_gbus_clock = txx9_cpu_clock;
  179. switch (divmode) {
  180. case TX4939_CCFG_YDIVMODE_2:
  181. txx9_gbus_clock /= 2; break;
  182. case TX4939_CCFG_YDIVMODE_3:
  183. txx9_gbus_clock /= 3; break;
  184. case TX4939_CCFG_YDIVMODE_5:
  185. txx9_gbus_clock /= 5; break;
  186. case TX4939_CCFG_YDIVMODE_6:
  187. txx9_gbus_clock /= 6; break;
  188. }
  189. /* change default value to udelay/mdelay take reasonable time */
  190. loops_per_jiffy = txx9_cpu_clock / HZ / 2;
  191. /* CCFG */
  192. tx4939_wdr_init();
  193. /* clear BusErrorOnWrite flag (W1C) */
  194. tx4939_ccfg_set(TX4939_CCFG_WDRST | TX4939_CCFG_BEOW);
  195. /* enable Timeout BusError */
  196. if (txx9_ccfg_toeon)
  197. tx4939_ccfg_set(TX4939_CCFG_TOE);
  198. /* DMA selection */
  199. txx9_clear64(&tx4939_ccfgptr->pcfg, TX4939_PCFG_DMASEL_ALL);
  200. /* Use external clock for external arbiter */
  201. if (!(____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_PCIARB))
  202. txx9_clear64(&tx4939_ccfgptr->pcfg, TX4939_PCFG_PCICLKEN_ALL);
  203. pr_info("%s -- %dMHz(M%dMHz,G%dMHz) CRIR:%08x CCFG:%llx PCFG:%llx\n",
  204. txx9_pcode_str,
  205. (cpuclk + 500000) / 1000000,
  206. (txx9_master_clock + 500000) / 1000000,
  207. (txx9_gbus_clock + 500000) / 1000000,
  208. (__u32)____raw_readq(&tx4939_ccfgptr->crir),
  209. (unsigned long long)____raw_readq(&tx4939_ccfgptr->ccfg),
  210. (unsigned long long)____raw_readq(&tx4939_ccfgptr->pcfg));
  211. pr_info("%s DDRC -- EN:%08x", txx9_pcode_str,
  212. (__u32)____raw_readq(&tx4939_ddrcptr->winen));
  213. for (i = 0; i < 4; i++) {
  214. __u64 win = ____raw_readq(&tx4939_ddrcptr->win[i]);
  215. if (!((__u32)____raw_readq(&tx4939_ddrcptr->winen) & (1 << i)))
  216. continue; /* disabled */
  217. printk(KERN_CONT " #%d:%016llx", i, (unsigned long long)win);
  218. tx4939_sdram_resource[i].name = "DDR SDRAM";
  219. tx4939_sdram_resource[i].start =
  220. (unsigned long)(win >> 48) << 20;
  221. tx4939_sdram_resource[i].end =
  222. ((((unsigned long)(win >> 32) & 0xffff) + 1) <<
  223. 20) - 1;
  224. tx4939_sdram_resource[i].flags = IORESOURCE_MEM;
  225. request_resource(&iomem_resource, &tx4939_sdram_resource[i]);
  226. }
  227. printk(KERN_CONT "\n");
  228. /* SRAM */
  229. if (____raw_readq(&tx4939_sramcptr->cr) & 1) {
  230. unsigned int size = TX4939_SRAM_SIZE;
  231. tx4939_sram_resource.name = "SRAM";
  232. tx4939_sram_resource.start =
  233. (____raw_readq(&tx4939_sramcptr->cr) >> (39-11))
  234. & ~(size - 1);
  235. tx4939_sram_resource.end =
  236. tx4939_sram_resource.start + TX4939_SRAM_SIZE - 1;
  237. tx4939_sram_resource.flags = IORESOURCE_MEM;
  238. request_resource(&iomem_resource, &tx4939_sram_resource);
  239. }
  240. /* TMR */
  241. /* disable all timers */
  242. for (i = 0; i < TX4939_NR_TMR; i++)
  243. txx9_tmr_init(TX4939_TMR_REG(i) & 0xfffffffffULL);
  244. /* set PCIC1 reset (required to prevent hangup on BIST) */
  245. txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_PCI1RST);
  246. pcfg = ____raw_readq(&tx4939_ccfgptr->pcfg);
  247. if (pcfg & (TX4939_PCFG_ET0MODE | TX4939_PCFG_ET1MODE)) {
  248. mdelay(1); /* at least 128 cpu clock */
  249. /* clear PCIC1 reset */
  250. txx9_clear64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_PCI1RST);
  251. } else {
  252. pr_info("%s: stop PCIC1\n", txx9_pcode_str);
  253. /* stop PCIC1 */
  254. txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_PCI1CKD);
  255. }
  256. if (!(pcfg & TX4939_PCFG_ET0MODE)) {
  257. pr_info("%s: stop ETH0\n", txx9_pcode_str);
  258. txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_ETH0RST);
  259. txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_ETH0CKD);
  260. }
  261. if (!(pcfg & TX4939_PCFG_ET1MODE)) {
  262. pr_info("%s: stop ETH1\n", txx9_pcode_str);
  263. txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_ETH1RST);
  264. txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_ETH1CKD);
  265. }
  266. _machine_restart = tx4939_machine_restart;
  267. board_be_init = tx4939_be_init;
  268. }
  269. void __init tx4939_time_init(unsigned int tmrnr)
  270. {
  271. if (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_TINTDIS)
  272. txx9_clockevent_init(TX4939_TMR_REG(tmrnr) & 0xfffffffffULL,
  273. TXX9_IRQ_BASE + TX4939_IR_TMR(tmrnr),
  274. TXX9_IMCLK);
  275. }
  276. void __init tx4939_sio_init(unsigned int sclk, unsigned int cts_mask)
  277. {
  278. int i;
  279. unsigned int ch_mask = 0;
  280. __u64 pcfg = __raw_readq(&tx4939_ccfgptr->pcfg);
  281. cts_mask |= ~1; /* only SIO0 have RTS/CTS */
  282. if ((pcfg & TX4939_PCFG_SIO2MODE_MASK) != TX4939_PCFG_SIO2MODE_SIO0)
  283. cts_mask |= 1 << 0; /* disable SIO0 RTS/CTS by PCFG setting */
  284. if ((pcfg & TX4939_PCFG_SIO2MODE_MASK) != TX4939_PCFG_SIO2MODE_SIO2)
  285. ch_mask |= 1 << 2; /* disable SIO2 by PCFG setting */
  286. if (pcfg & TX4939_PCFG_SIO3MODE)
  287. ch_mask |= 1 << 3; /* disable SIO3 by PCFG setting */
  288. for (i = 0; i < 4; i++) {
  289. if ((1 << i) & ch_mask)
  290. continue;
  291. txx9_sio_init(TX4939_SIO_REG(i) & 0xfffffffffULL,
  292. TXX9_IRQ_BASE + TX4939_IR_SIO(i),
  293. i, sclk, (1 << i) & cts_mask);
  294. }
  295. }
  296. #if IS_ENABLED(CONFIG_TC35815)
  297. static u32 tx4939_get_eth_speed(struct net_device *dev)
  298. {
  299. struct ethtool_link_ksettings cmd;
  300. if (__ethtool_get_link_ksettings(dev, &cmd))
  301. return 100; /* default 100Mbps */
  302. return cmd.base.speed;
  303. }
  304. static int tx4939_netdev_event(struct notifier_block *this,
  305. unsigned long event,
  306. void *ptr)
  307. {
  308. struct net_device *dev = netdev_notifier_info_to_dev(ptr);
  309. if (event == NETDEV_CHANGE && netif_carrier_ok(dev)) {
  310. __u64 bit = 0;
  311. if (dev->irq == TXX9_IRQ_BASE + TX4939_IR_ETH(0))
  312. bit = TX4939_PCFG_SPEED0;
  313. else if (dev->irq == TXX9_IRQ_BASE + TX4939_IR_ETH(1))
  314. bit = TX4939_PCFG_SPEED1;
  315. if (bit) {
  316. if (tx4939_get_eth_speed(dev) == 100)
  317. txx9_set64(&tx4939_ccfgptr->pcfg, bit);
  318. else
  319. txx9_clear64(&tx4939_ccfgptr->pcfg, bit);
  320. }
  321. }
  322. return NOTIFY_DONE;
  323. }
  324. static struct notifier_block tx4939_netdev_notifier = {
  325. .notifier_call = tx4939_netdev_event,
  326. .priority = 1,
  327. };
  328. void __init tx4939_ethaddr_init(unsigned char *addr0, unsigned char *addr1)
  329. {
  330. u64 pcfg = __raw_readq(&tx4939_ccfgptr->pcfg);
  331. if (addr0 && (pcfg & TX4939_PCFG_ET0MODE))
  332. txx9_ethaddr_init(TXX9_IRQ_BASE + TX4939_IR_ETH(0), addr0);
  333. if (addr1 && (pcfg & TX4939_PCFG_ET1MODE))
  334. txx9_ethaddr_init(TXX9_IRQ_BASE + TX4939_IR_ETH(1), addr1);
  335. register_netdevice_notifier(&tx4939_netdev_notifier);
  336. }
  337. #else
  338. void __init tx4939_ethaddr_init(unsigned char *addr0, unsigned char *addr1)
  339. {
  340. }
  341. #endif
  342. void __init tx4939_mtd_init(int ch)
  343. {
  344. struct physmap_flash_data pdata = {
  345. .width = TX4939_EBUSC_WIDTH(ch) / 8,
  346. };
  347. unsigned long start = txx9_ce_res[ch].start;
  348. unsigned long size = txx9_ce_res[ch].end - start + 1;
  349. if (!(TX4939_EBUSC_CR(ch) & 0x8))
  350. return; /* disabled */
  351. txx9_physmap_flash_init(ch, start, size, &pdata);
  352. }
  353. #define TX4939_ATA_REG_PHYS(ch) (TX4939_ATA_REG(ch) & 0xfffffffffULL)
  354. void __init tx4939_ata_init(void)
  355. {
  356. static struct resource ata0_res[] = {
  357. {
  358. .start = TX4939_ATA_REG_PHYS(0),
  359. .end = TX4939_ATA_REG_PHYS(0) + 0x1000 - 1,
  360. .flags = IORESOURCE_MEM,
  361. }, {
  362. .start = TXX9_IRQ_BASE + TX4939_IR_ATA(0),
  363. .flags = IORESOURCE_IRQ,
  364. },
  365. };
  366. static struct resource ata1_res[] = {
  367. {
  368. .start = TX4939_ATA_REG_PHYS(1),
  369. .end = TX4939_ATA_REG_PHYS(1) + 0x1000 - 1,
  370. .flags = IORESOURCE_MEM,
  371. }, {
  372. .start = TXX9_IRQ_BASE + TX4939_IR_ATA(1),
  373. .flags = IORESOURCE_IRQ,
  374. },
  375. };
  376. static struct platform_device ata0_dev = {
  377. .name = "tx4939ide",
  378. .id = 0,
  379. .num_resources = ARRAY_SIZE(ata0_res),
  380. .resource = ata0_res,
  381. };
  382. static struct platform_device ata1_dev = {
  383. .name = "tx4939ide",
  384. .id = 1,
  385. .num_resources = ARRAY_SIZE(ata1_res),
  386. .resource = ata1_res,
  387. };
  388. __u64 pcfg = __raw_readq(&tx4939_ccfgptr->pcfg);
  389. if (pcfg & TX4939_PCFG_ATA0MODE)
  390. platform_device_register(&ata0_dev);
  391. if ((pcfg & (TX4939_PCFG_ATA1MODE |
  392. TX4939_PCFG_ET1MODE |
  393. TX4939_PCFG_ET0MODE)) == TX4939_PCFG_ATA1MODE)
  394. platform_device_register(&ata1_dev);
  395. }
  396. void __init tx4939_rtc_init(void)
  397. {
  398. static struct resource res[] = {
  399. {
  400. .start = TX4939_RTC_REG & 0xfffffffffULL,
  401. .end = (TX4939_RTC_REG & 0xfffffffffULL) + 0x100 - 1,
  402. .flags = IORESOURCE_MEM,
  403. }, {
  404. .start = TXX9_IRQ_BASE + TX4939_IR_RTC,
  405. .flags = IORESOURCE_IRQ,
  406. },
  407. };
  408. static struct platform_device rtc_dev = {
  409. .name = "tx4939rtc",
  410. .id = -1,
  411. .num_resources = ARRAY_SIZE(res),
  412. .resource = res,
  413. };
  414. platform_device_register(&rtc_dev);
  415. }
  416. void __init tx4939_ndfmc_init(unsigned int hold, unsigned int spw,
  417. unsigned char ch_mask, unsigned char wide_mask)
  418. {
  419. struct txx9ndfmc_platform_data plat_data = {
  420. .shift = 1,
  421. .gbus_clock = txx9_gbus_clock,
  422. .hold = hold,
  423. .spw = spw,
  424. .flags = NDFMC_PLAT_FLAG_NO_RSTR | NDFMC_PLAT_FLAG_HOLDADD |
  425. NDFMC_PLAT_FLAG_DUMMYWRITE,
  426. .ch_mask = ch_mask,
  427. .wide_mask = wide_mask,
  428. };
  429. txx9_ndfmc_init(TX4939_NDFMC_REG & 0xfffffffffULL, &plat_data);
  430. }
  431. void __init tx4939_dmac_init(int memcpy_chan0, int memcpy_chan1)
  432. {
  433. struct txx9dmac_platform_data plat_data = {
  434. .have_64bit_regs = true,
  435. };
  436. int i;
  437. for (i = 0; i < 2; i++) {
  438. plat_data.memcpy_chan = i ? memcpy_chan1 : memcpy_chan0;
  439. txx9_dmac_init(i, TX4939_DMA_REG(i) & 0xfffffffffULL,
  440. TXX9_IRQ_BASE + TX4939_IR_DMA(i, 0),
  441. &plat_data);
  442. }
  443. }
  444. void __init tx4939_aclc_init(void)
  445. {
  446. u64 pcfg = __raw_readq(&tx4939_ccfgptr->pcfg);
  447. if ((pcfg & TX4939_PCFG_I2SMODE_MASK) == TX4939_PCFG_I2SMODE_ACLC)
  448. txx9_aclc_init(TX4939_ACLC_REG & 0xfffffffffULL,
  449. TXX9_IRQ_BASE + TX4939_IR_ACLC, 1, 0, 1);
  450. }
  451. void __init tx4939_sramc_init(void)
  452. {
  453. if (tx4939_sram_resource.start)
  454. txx9_sramc_init(&tx4939_sram_resource);
  455. }
  456. void __init tx4939_rng_init(void)
  457. {
  458. static struct resource res = {
  459. .start = TX4939_RNG_REG & 0xfffffffffULL,
  460. .end = (TX4939_RNG_REG & 0xfffffffffULL) + 0x30 - 1,
  461. .flags = IORESOURCE_MEM,
  462. };
  463. static struct platform_device pdev = {
  464. .name = "tx4939-rng",
  465. .id = -1,
  466. .num_resources = 1,
  467. .resource = &res,
  468. };
  469. platform_device_register(&pdev);
  470. }
  471. static void __init tx4939_stop_unused_modules(void)
  472. {
  473. __u64 pcfg, rst = 0, ckd = 0;
  474. char buf[128];
  475. buf[0] = '\0';
  476. local_irq_disable();
  477. pcfg = ____raw_readq(&tx4939_ccfgptr->pcfg);
  478. if ((pcfg & TX4939_PCFG_I2SMODE_MASK) !=
  479. TX4939_PCFG_I2SMODE_ACLC) {
  480. rst |= TX4939_CLKCTR_ACLRST;
  481. ckd |= TX4939_CLKCTR_ACLCKD;
  482. strcat(buf, " ACLC");
  483. }
  484. if ((pcfg & TX4939_PCFG_I2SMODE_MASK) !=
  485. TX4939_PCFG_I2SMODE_I2S &&
  486. (pcfg & TX4939_PCFG_I2SMODE_MASK) !=
  487. TX4939_PCFG_I2SMODE_I2S_ALT) {
  488. rst |= TX4939_CLKCTR_I2SRST;
  489. ckd |= TX4939_CLKCTR_I2SCKD;
  490. strcat(buf, " I2S");
  491. }
  492. if (!(pcfg & TX4939_PCFG_ATA0MODE)) {
  493. rst |= TX4939_CLKCTR_ATA0RST;
  494. ckd |= TX4939_CLKCTR_ATA0CKD;
  495. strcat(buf, " ATA0");
  496. }
  497. if (!(pcfg & TX4939_PCFG_ATA1MODE)) {
  498. rst |= TX4939_CLKCTR_ATA1RST;
  499. ckd |= TX4939_CLKCTR_ATA1CKD;
  500. strcat(buf, " ATA1");
  501. }
  502. if (pcfg & TX4939_PCFG_SPIMODE) {
  503. rst |= TX4939_CLKCTR_SPIRST;
  504. ckd |= TX4939_CLKCTR_SPICKD;
  505. strcat(buf, " SPI");
  506. }
  507. if (!(pcfg & (TX4939_PCFG_VSSMODE | TX4939_PCFG_VPSMODE))) {
  508. rst |= TX4939_CLKCTR_VPCRST;
  509. ckd |= TX4939_CLKCTR_VPCCKD;
  510. strcat(buf, " VPC");
  511. }
  512. if ((pcfg & TX4939_PCFG_SIO2MODE_MASK) != TX4939_PCFG_SIO2MODE_SIO2) {
  513. rst |= TX4939_CLKCTR_SIO2RST;
  514. ckd |= TX4939_CLKCTR_SIO2CKD;
  515. strcat(buf, " SIO2");
  516. }
  517. if (pcfg & TX4939_PCFG_SIO3MODE) {
  518. rst |= TX4939_CLKCTR_SIO3RST;
  519. ckd |= TX4939_CLKCTR_SIO3CKD;
  520. strcat(buf, " SIO3");
  521. }
  522. if (rst | ckd) {
  523. txx9_set64(&tx4939_ccfgptr->clkctr, rst);
  524. txx9_set64(&tx4939_ccfgptr->clkctr, ckd);
  525. }
  526. local_irq_enable();
  527. if (buf[0])
  528. pr_info("%s: stop%s\n", txx9_pcode_str, buf);
  529. }
  530. static int __init tx4939_late_init(void)
  531. {
  532. if (txx9_pcode != 0x4939)
  533. return -ENODEV;
  534. tx4939_stop_unused_modules();
  535. return 0;
  536. }
  537. late_initcall(tx4939_late_init);