setup_tx4939.c 16 KB

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