common.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814
  1. /*
  2. * arch/arm/mach-mv78xx0/common.c
  3. *
  4. * Core functions for Marvell MV78xx0 SoCs
  5. *
  6. * This file is licensed under the terms of the GNU General Public
  7. * License version 2. This program is licensed "as is" without any
  8. * warranty of any kind, whether express or implied.
  9. */
  10. #include <linux/kernel.h>
  11. #include <linux/init.h>
  12. #include <linux/platform_device.h>
  13. #include <linux/serial_8250.h>
  14. #include <linux/mbus.h>
  15. #include <linux/mv643xx_eth.h>
  16. #include <linux/ata_platform.h>
  17. #include <linux/ethtool.h>
  18. #include <asm/mach/map.h>
  19. #include <asm/mach/time.h>
  20. #include <mach/mv78xx0.h>
  21. #include <plat/cache-feroceon-l2.h>
  22. #include <plat/ehci-orion.h>
  23. #include <plat/orion_nand.h>
  24. #include <plat/time.h>
  25. #include "common.h"
  26. /*****************************************************************************
  27. * Common bits
  28. ****************************************************************************/
  29. int mv78xx0_core_index(void)
  30. {
  31. u32 extra;
  32. /*
  33. * Read Extra Features register.
  34. */
  35. __asm__("mrc p15, 1, %0, c15, c1, 0" : "=r" (extra));
  36. return !!(extra & 0x00004000);
  37. }
  38. static int get_hclk(void)
  39. {
  40. int hclk;
  41. /*
  42. * HCLK tick rate is configured by DEV_D[7:5] pins.
  43. */
  44. switch ((readl(SAMPLE_AT_RESET_LOW) >> 5) & 7) {
  45. case 0:
  46. hclk = 166666667;
  47. break;
  48. case 1:
  49. hclk = 200000000;
  50. break;
  51. case 2:
  52. hclk = 266666667;
  53. break;
  54. case 3:
  55. hclk = 333333333;
  56. break;
  57. case 4:
  58. hclk = 400000000;
  59. break;
  60. default:
  61. panic("unknown HCLK PLL setting: %.8x\n",
  62. readl(SAMPLE_AT_RESET_LOW));
  63. }
  64. return hclk;
  65. }
  66. static void get_pclk_l2clk(int hclk, int core_index, int *pclk, int *l2clk)
  67. {
  68. u32 cfg;
  69. /*
  70. * Core #0 PCLK/L2CLK is configured by bits [13:8], core #1
  71. * PCLK/L2CLK by bits [19:14].
  72. */
  73. if (core_index == 0) {
  74. cfg = (readl(SAMPLE_AT_RESET_LOW) >> 8) & 0x3f;
  75. } else {
  76. cfg = (readl(SAMPLE_AT_RESET_LOW) >> 14) & 0x3f;
  77. }
  78. /*
  79. * Bits [11:8] ([17:14] for core #1) configure the PCLK:HCLK
  80. * ratio (1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6).
  81. */
  82. *pclk = ((u64)hclk * (2 + (cfg & 0xf))) >> 1;
  83. /*
  84. * Bits [13:12] ([19:18] for core #1) configure the PCLK:L2CLK
  85. * ratio (1, 2, 3).
  86. */
  87. *l2clk = *pclk / (((cfg >> 4) & 3) + 1);
  88. }
  89. static int get_tclk(void)
  90. {
  91. int tclk;
  92. /*
  93. * TCLK tick rate is configured by DEV_A[2:0] strap pins.
  94. */
  95. switch ((readl(SAMPLE_AT_RESET_HIGH) >> 6) & 7) {
  96. case 1:
  97. tclk = 166666667;
  98. break;
  99. case 3:
  100. tclk = 200000000;
  101. break;
  102. default:
  103. panic("unknown TCLK PLL setting: %.8x\n",
  104. readl(SAMPLE_AT_RESET_HIGH));
  105. }
  106. return tclk;
  107. }
  108. /*****************************************************************************
  109. * I/O Address Mapping
  110. ****************************************************************************/
  111. static struct map_desc mv78xx0_io_desc[] __initdata = {
  112. {
  113. .virtual = MV78XX0_CORE_REGS_VIRT_BASE,
  114. .pfn = 0,
  115. .length = MV78XX0_CORE_REGS_SIZE,
  116. .type = MT_DEVICE,
  117. }, {
  118. .virtual = MV78XX0_PCIE_IO_VIRT_BASE(0),
  119. .pfn = __phys_to_pfn(MV78XX0_PCIE_IO_PHYS_BASE(0)),
  120. .length = MV78XX0_PCIE_IO_SIZE * 8,
  121. .type = MT_DEVICE,
  122. }, {
  123. .virtual = MV78XX0_REGS_VIRT_BASE,
  124. .pfn = __phys_to_pfn(MV78XX0_REGS_PHYS_BASE),
  125. .length = MV78XX0_REGS_SIZE,
  126. .type = MT_DEVICE,
  127. },
  128. };
  129. void __init mv78xx0_map_io(void)
  130. {
  131. unsigned long phys;
  132. /*
  133. * Map the right set of per-core registers depending on
  134. * which core we are running on.
  135. */
  136. if (mv78xx0_core_index() == 0) {
  137. phys = MV78XX0_CORE0_REGS_PHYS_BASE;
  138. } else {
  139. phys = MV78XX0_CORE1_REGS_PHYS_BASE;
  140. }
  141. mv78xx0_io_desc[0].pfn = __phys_to_pfn(phys);
  142. iotable_init(mv78xx0_io_desc, ARRAY_SIZE(mv78xx0_io_desc));
  143. }
  144. /*****************************************************************************
  145. * EHCI
  146. ****************************************************************************/
  147. static struct orion_ehci_data mv78xx0_ehci_data = {
  148. .dram = &mv78xx0_mbus_dram_info,
  149. .phy_version = EHCI_PHY_NA,
  150. };
  151. static u64 ehci_dmamask = 0xffffffffUL;
  152. /*****************************************************************************
  153. * EHCI0
  154. ****************************************************************************/
  155. static struct resource mv78xx0_ehci0_resources[] = {
  156. {
  157. .start = USB0_PHYS_BASE,
  158. .end = USB0_PHYS_BASE + 0x0fff,
  159. .flags = IORESOURCE_MEM,
  160. }, {
  161. .start = IRQ_MV78XX0_USB_0,
  162. .end = IRQ_MV78XX0_USB_0,
  163. .flags = IORESOURCE_IRQ,
  164. },
  165. };
  166. static struct platform_device mv78xx0_ehci0 = {
  167. .name = "orion-ehci",
  168. .id = 0,
  169. .dev = {
  170. .dma_mask = &ehci_dmamask,
  171. .coherent_dma_mask = 0xffffffff,
  172. .platform_data = &mv78xx0_ehci_data,
  173. },
  174. .resource = mv78xx0_ehci0_resources,
  175. .num_resources = ARRAY_SIZE(mv78xx0_ehci0_resources),
  176. };
  177. void __init mv78xx0_ehci0_init(void)
  178. {
  179. platform_device_register(&mv78xx0_ehci0);
  180. }
  181. /*****************************************************************************
  182. * EHCI1
  183. ****************************************************************************/
  184. static struct resource mv78xx0_ehci1_resources[] = {
  185. {
  186. .start = USB1_PHYS_BASE,
  187. .end = USB1_PHYS_BASE + 0x0fff,
  188. .flags = IORESOURCE_MEM,
  189. }, {
  190. .start = IRQ_MV78XX0_USB_1,
  191. .end = IRQ_MV78XX0_USB_1,
  192. .flags = IORESOURCE_IRQ,
  193. },
  194. };
  195. static struct platform_device mv78xx0_ehci1 = {
  196. .name = "orion-ehci",
  197. .id = 1,
  198. .dev = {
  199. .dma_mask = &ehci_dmamask,
  200. .coherent_dma_mask = 0xffffffff,
  201. .platform_data = &mv78xx0_ehci_data,
  202. },
  203. .resource = mv78xx0_ehci1_resources,
  204. .num_resources = ARRAY_SIZE(mv78xx0_ehci1_resources),
  205. };
  206. void __init mv78xx0_ehci1_init(void)
  207. {
  208. platform_device_register(&mv78xx0_ehci1);
  209. }
  210. /*****************************************************************************
  211. * EHCI2
  212. ****************************************************************************/
  213. static struct resource mv78xx0_ehci2_resources[] = {
  214. {
  215. .start = USB2_PHYS_BASE,
  216. .end = USB2_PHYS_BASE + 0x0fff,
  217. .flags = IORESOURCE_MEM,
  218. }, {
  219. .start = IRQ_MV78XX0_USB_2,
  220. .end = IRQ_MV78XX0_USB_2,
  221. .flags = IORESOURCE_IRQ,
  222. },
  223. };
  224. static struct platform_device mv78xx0_ehci2 = {
  225. .name = "orion-ehci",
  226. .id = 2,
  227. .dev = {
  228. .dma_mask = &ehci_dmamask,
  229. .coherent_dma_mask = 0xffffffff,
  230. .platform_data = &mv78xx0_ehci_data,
  231. },
  232. .resource = mv78xx0_ehci2_resources,
  233. .num_resources = ARRAY_SIZE(mv78xx0_ehci2_resources),
  234. };
  235. void __init mv78xx0_ehci2_init(void)
  236. {
  237. platform_device_register(&mv78xx0_ehci2);
  238. }
  239. /*****************************************************************************
  240. * GE00
  241. ****************************************************************************/
  242. struct mv643xx_eth_shared_platform_data mv78xx0_ge00_shared_data = {
  243. .t_clk = 0,
  244. .dram = &mv78xx0_mbus_dram_info,
  245. };
  246. static struct resource mv78xx0_ge00_shared_resources[] = {
  247. {
  248. .name = "ge00 base",
  249. .start = GE00_PHYS_BASE + 0x2000,
  250. .end = GE00_PHYS_BASE + 0x3fff,
  251. .flags = IORESOURCE_MEM,
  252. }, {
  253. .name = "ge err irq",
  254. .start = IRQ_MV78XX0_GE_ERR,
  255. .end = IRQ_MV78XX0_GE_ERR,
  256. .flags = IORESOURCE_IRQ,
  257. },
  258. };
  259. static struct platform_device mv78xx0_ge00_shared = {
  260. .name = MV643XX_ETH_SHARED_NAME,
  261. .id = 0,
  262. .dev = {
  263. .platform_data = &mv78xx0_ge00_shared_data,
  264. },
  265. .num_resources = ARRAY_SIZE(mv78xx0_ge00_shared_resources),
  266. .resource = mv78xx0_ge00_shared_resources,
  267. };
  268. static struct resource mv78xx0_ge00_resources[] = {
  269. {
  270. .name = "ge00 irq",
  271. .start = IRQ_MV78XX0_GE00_SUM,
  272. .end = IRQ_MV78XX0_GE00_SUM,
  273. .flags = IORESOURCE_IRQ,
  274. },
  275. };
  276. static struct platform_device mv78xx0_ge00 = {
  277. .name = MV643XX_ETH_NAME,
  278. .id = 0,
  279. .num_resources = 1,
  280. .resource = mv78xx0_ge00_resources,
  281. };
  282. void __init mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data)
  283. {
  284. eth_data->shared = &mv78xx0_ge00_shared;
  285. mv78xx0_ge00.dev.platform_data = eth_data;
  286. platform_device_register(&mv78xx0_ge00_shared);
  287. platform_device_register(&mv78xx0_ge00);
  288. }
  289. /*****************************************************************************
  290. * GE01
  291. ****************************************************************************/
  292. struct mv643xx_eth_shared_platform_data mv78xx0_ge01_shared_data = {
  293. .t_clk = 0,
  294. .dram = &mv78xx0_mbus_dram_info,
  295. .shared_smi = &mv78xx0_ge00_shared,
  296. };
  297. static struct resource mv78xx0_ge01_shared_resources[] = {
  298. {
  299. .name = "ge01 base",
  300. .start = GE01_PHYS_BASE + 0x2000,
  301. .end = GE01_PHYS_BASE + 0x3fff,
  302. .flags = IORESOURCE_MEM,
  303. },
  304. };
  305. static struct platform_device mv78xx0_ge01_shared = {
  306. .name = MV643XX_ETH_SHARED_NAME,
  307. .id = 1,
  308. .dev = {
  309. .platform_data = &mv78xx0_ge01_shared_data,
  310. },
  311. .num_resources = 1,
  312. .resource = mv78xx0_ge01_shared_resources,
  313. };
  314. static struct resource mv78xx0_ge01_resources[] = {
  315. {
  316. .name = "ge01 irq",
  317. .start = IRQ_MV78XX0_GE01_SUM,
  318. .end = IRQ_MV78XX0_GE01_SUM,
  319. .flags = IORESOURCE_IRQ,
  320. },
  321. };
  322. static struct platform_device mv78xx0_ge01 = {
  323. .name = MV643XX_ETH_NAME,
  324. .id = 1,
  325. .num_resources = 1,
  326. .resource = mv78xx0_ge01_resources,
  327. };
  328. void __init mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data)
  329. {
  330. eth_data->shared = &mv78xx0_ge01_shared;
  331. mv78xx0_ge01.dev.platform_data = eth_data;
  332. platform_device_register(&mv78xx0_ge01_shared);
  333. platform_device_register(&mv78xx0_ge01);
  334. }
  335. /*****************************************************************************
  336. * GE10
  337. ****************************************************************************/
  338. struct mv643xx_eth_shared_platform_data mv78xx0_ge10_shared_data = {
  339. .t_clk = 0,
  340. .dram = &mv78xx0_mbus_dram_info,
  341. .shared_smi = &mv78xx0_ge00_shared,
  342. };
  343. static struct resource mv78xx0_ge10_shared_resources[] = {
  344. {
  345. .name = "ge10 base",
  346. .start = GE10_PHYS_BASE + 0x2000,
  347. .end = GE10_PHYS_BASE + 0x3fff,
  348. .flags = IORESOURCE_MEM,
  349. },
  350. };
  351. static struct platform_device mv78xx0_ge10_shared = {
  352. .name = MV643XX_ETH_SHARED_NAME,
  353. .id = 2,
  354. .dev = {
  355. .platform_data = &mv78xx0_ge10_shared_data,
  356. },
  357. .num_resources = 1,
  358. .resource = mv78xx0_ge10_shared_resources,
  359. };
  360. static struct resource mv78xx0_ge10_resources[] = {
  361. {
  362. .name = "ge10 irq",
  363. .start = IRQ_MV78XX0_GE10_SUM,
  364. .end = IRQ_MV78XX0_GE10_SUM,
  365. .flags = IORESOURCE_IRQ,
  366. },
  367. };
  368. static struct platform_device mv78xx0_ge10 = {
  369. .name = MV643XX_ETH_NAME,
  370. .id = 2,
  371. .num_resources = 1,
  372. .resource = mv78xx0_ge10_resources,
  373. };
  374. void __init mv78xx0_ge10_init(struct mv643xx_eth_platform_data *eth_data)
  375. {
  376. u32 dev, rev;
  377. eth_data->shared = &mv78xx0_ge10_shared;
  378. mv78xx0_ge10.dev.platform_data = eth_data;
  379. /*
  380. * On the Z0, ge10 and ge11 are internally connected back
  381. * to back, and not brought out.
  382. */
  383. mv78xx0_pcie_id(&dev, &rev);
  384. if (dev == MV78X00_Z0_DEV_ID) {
  385. eth_data->phy_addr = MV643XX_ETH_PHY_NONE;
  386. eth_data->speed = SPEED_1000;
  387. eth_data->duplex = DUPLEX_FULL;
  388. }
  389. platform_device_register(&mv78xx0_ge10_shared);
  390. platform_device_register(&mv78xx0_ge10);
  391. }
  392. /*****************************************************************************
  393. * GE11
  394. ****************************************************************************/
  395. struct mv643xx_eth_shared_platform_data mv78xx0_ge11_shared_data = {
  396. .t_clk = 0,
  397. .dram = &mv78xx0_mbus_dram_info,
  398. .shared_smi = &mv78xx0_ge00_shared,
  399. };
  400. static struct resource mv78xx0_ge11_shared_resources[] = {
  401. {
  402. .name = "ge11 base",
  403. .start = GE11_PHYS_BASE + 0x2000,
  404. .end = GE11_PHYS_BASE + 0x3fff,
  405. .flags = IORESOURCE_MEM,
  406. },
  407. };
  408. static struct platform_device mv78xx0_ge11_shared = {
  409. .name = MV643XX_ETH_SHARED_NAME,
  410. .id = 3,
  411. .dev = {
  412. .platform_data = &mv78xx0_ge11_shared_data,
  413. },
  414. .num_resources = 1,
  415. .resource = mv78xx0_ge11_shared_resources,
  416. };
  417. static struct resource mv78xx0_ge11_resources[] = {
  418. {
  419. .name = "ge11 irq",
  420. .start = IRQ_MV78XX0_GE11_SUM,
  421. .end = IRQ_MV78XX0_GE11_SUM,
  422. .flags = IORESOURCE_IRQ,
  423. },
  424. };
  425. static struct platform_device mv78xx0_ge11 = {
  426. .name = MV643XX_ETH_NAME,
  427. .id = 3,
  428. .num_resources = 1,
  429. .resource = mv78xx0_ge11_resources,
  430. };
  431. void __init mv78xx0_ge11_init(struct mv643xx_eth_platform_data *eth_data)
  432. {
  433. u32 dev, rev;
  434. eth_data->shared = &mv78xx0_ge11_shared;
  435. mv78xx0_ge11.dev.platform_data = eth_data;
  436. /*
  437. * On the Z0, ge10 and ge11 are internally connected back
  438. * to back, and not brought out.
  439. */
  440. mv78xx0_pcie_id(&dev, &rev);
  441. if (dev == MV78X00_Z0_DEV_ID) {
  442. eth_data->phy_addr = MV643XX_ETH_PHY_NONE;
  443. eth_data->speed = SPEED_1000;
  444. eth_data->duplex = DUPLEX_FULL;
  445. }
  446. platform_device_register(&mv78xx0_ge11_shared);
  447. platform_device_register(&mv78xx0_ge11);
  448. }
  449. /*****************************************************************************
  450. * SATA
  451. ****************************************************************************/
  452. static struct resource mv78xx0_sata_resources[] = {
  453. {
  454. .name = "sata base",
  455. .start = SATA_PHYS_BASE,
  456. .end = SATA_PHYS_BASE + 0x5000 - 1,
  457. .flags = IORESOURCE_MEM,
  458. }, {
  459. .name = "sata irq",
  460. .start = IRQ_MV78XX0_SATA,
  461. .end = IRQ_MV78XX0_SATA,
  462. .flags = IORESOURCE_IRQ,
  463. },
  464. };
  465. static struct platform_device mv78xx0_sata = {
  466. .name = "sata_mv",
  467. .id = 0,
  468. .dev = {
  469. .coherent_dma_mask = 0xffffffff,
  470. },
  471. .num_resources = ARRAY_SIZE(mv78xx0_sata_resources),
  472. .resource = mv78xx0_sata_resources,
  473. };
  474. void __init mv78xx0_sata_init(struct mv_sata_platform_data *sata_data)
  475. {
  476. sata_data->dram = &mv78xx0_mbus_dram_info;
  477. mv78xx0_sata.dev.platform_data = sata_data;
  478. platform_device_register(&mv78xx0_sata);
  479. }
  480. /*****************************************************************************
  481. * UART0
  482. ****************************************************************************/
  483. static struct plat_serial8250_port mv78xx0_uart0_data[] = {
  484. {
  485. .mapbase = UART0_PHYS_BASE,
  486. .membase = (char *)UART0_VIRT_BASE,
  487. .irq = IRQ_MV78XX0_UART_0,
  488. .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
  489. .iotype = UPIO_MEM,
  490. .regshift = 2,
  491. .uartclk = 0,
  492. }, {
  493. },
  494. };
  495. static struct resource mv78xx0_uart0_resources[] = {
  496. {
  497. .start = UART0_PHYS_BASE,
  498. .end = UART0_PHYS_BASE + 0xff,
  499. .flags = IORESOURCE_MEM,
  500. }, {
  501. .start = IRQ_MV78XX0_UART_0,
  502. .end = IRQ_MV78XX0_UART_0,
  503. .flags = IORESOURCE_IRQ,
  504. },
  505. };
  506. static struct platform_device mv78xx0_uart0 = {
  507. .name = "serial8250",
  508. .id = 0,
  509. .dev = {
  510. .platform_data = mv78xx0_uart0_data,
  511. },
  512. .resource = mv78xx0_uart0_resources,
  513. .num_resources = ARRAY_SIZE(mv78xx0_uart0_resources),
  514. };
  515. void __init mv78xx0_uart0_init(void)
  516. {
  517. platform_device_register(&mv78xx0_uart0);
  518. }
  519. /*****************************************************************************
  520. * UART1
  521. ****************************************************************************/
  522. static struct plat_serial8250_port mv78xx0_uart1_data[] = {
  523. {
  524. .mapbase = UART1_PHYS_BASE,
  525. .membase = (char *)UART1_VIRT_BASE,
  526. .irq = IRQ_MV78XX0_UART_1,
  527. .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
  528. .iotype = UPIO_MEM,
  529. .regshift = 2,
  530. .uartclk = 0,
  531. }, {
  532. },
  533. };
  534. static struct resource mv78xx0_uart1_resources[] = {
  535. {
  536. .start = UART1_PHYS_BASE,
  537. .end = UART1_PHYS_BASE + 0xff,
  538. .flags = IORESOURCE_MEM,
  539. }, {
  540. .start = IRQ_MV78XX0_UART_1,
  541. .end = IRQ_MV78XX0_UART_1,
  542. .flags = IORESOURCE_IRQ,
  543. },
  544. };
  545. static struct platform_device mv78xx0_uart1 = {
  546. .name = "serial8250",
  547. .id = 1,
  548. .dev = {
  549. .platform_data = mv78xx0_uart1_data,
  550. },
  551. .resource = mv78xx0_uart1_resources,
  552. .num_resources = ARRAY_SIZE(mv78xx0_uart1_resources),
  553. };
  554. void __init mv78xx0_uart1_init(void)
  555. {
  556. platform_device_register(&mv78xx0_uart1);
  557. }
  558. /*****************************************************************************
  559. * UART2
  560. ****************************************************************************/
  561. static struct plat_serial8250_port mv78xx0_uart2_data[] = {
  562. {
  563. .mapbase = UART2_PHYS_BASE,
  564. .membase = (char *)UART2_VIRT_BASE,
  565. .irq = IRQ_MV78XX0_UART_2,
  566. .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
  567. .iotype = UPIO_MEM,
  568. .regshift = 2,
  569. .uartclk = 0,
  570. }, {
  571. },
  572. };
  573. static struct resource mv78xx0_uart2_resources[] = {
  574. {
  575. .start = UART2_PHYS_BASE,
  576. .end = UART2_PHYS_BASE + 0xff,
  577. .flags = IORESOURCE_MEM,
  578. }, {
  579. .start = IRQ_MV78XX0_UART_2,
  580. .end = IRQ_MV78XX0_UART_2,
  581. .flags = IORESOURCE_IRQ,
  582. },
  583. };
  584. static struct platform_device mv78xx0_uart2 = {
  585. .name = "serial8250",
  586. .id = 2,
  587. .dev = {
  588. .platform_data = mv78xx0_uart2_data,
  589. },
  590. .resource = mv78xx0_uart2_resources,
  591. .num_resources = ARRAY_SIZE(mv78xx0_uart2_resources),
  592. };
  593. void __init mv78xx0_uart2_init(void)
  594. {
  595. platform_device_register(&mv78xx0_uart2);
  596. }
  597. /*****************************************************************************
  598. * UART3
  599. ****************************************************************************/
  600. static struct plat_serial8250_port mv78xx0_uart3_data[] = {
  601. {
  602. .mapbase = UART3_PHYS_BASE,
  603. .membase = (char *)UART3_VIRT_BASE,
  604. .irq = IRQ_MV78XX0_UART_3,
  605. .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
  606. .iotype = UPIO_MEM,
  607. .regshift = 2,
  608. .uartclk = 0,
  609. }, {
  610. },
  611. };
  612. static struct resource mv78xx0_uart3_resources[] = {
  613. {
  614. .start = UART3_PHYS_BASE,
  615. .end = UART3_PHYS_BASE + 0xff,
  616. .flags = IORESOURCE_MEM,
  617. }, {
  618. .start = IRQ_MV78XX0_UART_3,
  619. .end = IRQ_MV78XX0_UART_3,
  620. .flags = IORESOURCE_IRQ,
  621. },
  622. };
  623. static struct platform_device mv78xx0_uart3 = {
  624. .name = "serial8250",
  625. .id = 3,
  626. .dev = {
  627. .platform_data = mv78xx0_uart3_data,
  628. },
  629. .resource = mv78xx0_uart3_resources,
  630. .num_resources = ARRAY_SIZE(mv78xx0_uart3_resources),
  631. };
  632. void __init mv78xx0_uart3_init(void)
  633. {
  634. platform_device_register(&mv78xx0_uart3);
  635. }
  636. /*****************************************************************************
  637. * Time handling
  638. ****************************************************************************/
  639. static void mv78xx0_timer_init(void)
  640. {
  641. orion_time_init(IRQ_MV78XX0_TIMER_1, get_tclk());
  642. }
  643. struct sys_timer mv78xx0_timer = {
  644. .init = mv78xx0_timer_init,
  645. };
  646. /*****************************************************************************
  647. * General
  648. ****************************************************************************/
  649. static char * __init mv78xx0_id(void)
  650. {
  651. u32 dev, rev;
  652. mv78xx0_pcie_id(&dev, &rev);
  653. if (dev == MV78X00_Z0_DEV_ID) {
  654. if (rev == MV78X00_REV_Z0)
  655. return "MV78X00-Z0";
  656. else
  657. return "MV78X00-Rev-Unsupported";
  658. } else if (dev == MV78100_DEV_ID) {
  659. if (rev == MV78100_REV_A0)
  660. return "MV78100-A0";
  661. else
  662. return "MV78100-Rev-Unsupported";
  663. } else if (dev == MV78200_DEV_ID) {
  664. if (rev == MV78100_REV_A0)
  665. return "MV78200-A0";
  666. else
  667. return "MV78200-Rev-Unsupported";
  668. } else {
  669. return "Device-Unknown";
  670. }
  671. }
  672. static int __init is_l2_writethrough(void)
  673. {
  674. return !!(readl(CPU_CONTROL) & L2_WRITETHROUGH);
  675. }
  676. void __init mv78xx0_init(void)
  677. {
  678. int core_index;
  679. int hclk;
  680. int pclk;
  681. int l2clk;
  682. int tclk;
  683. core_index = mv78xx0_core_index();
  684. hclk = get_hclk();
  685. get_pclk_l2clk(hclk, core_index, &pclk, &l2clk);
  686. tclk = get_tclk();
  687. printk(KERN_INFO "%s ", mv78xx0_id());
  688. printk("core #%d, ", core_index);
  689. printk("PCLK = %dMHz, ", (pclk + 499999) / 1000000);
  690. printk("L2 = %dMHz, ", (l2clk + 499999) / 1000000);
  691. printk("HCLK = %dMHz, ", (hclk + 499999) / 1000000);
  692. printk("TCLK = %dMHz\n", (tclk + 499999) / 1000000);
  693. mv78xx0_setup_cpu_mbus();
  694. #ifdef CONFIG_CACHE_FEROCEON_L2
  695. feroceon_l2_init(is_l2_writethrough());
  696. #endif
  697. mv78xx0_ge00_shared_data.t_clk = tclk;
  698. mv78xx0_ge01_shared_data.t_clk = tclk;
  699. mv78xx0_ge10_shared_data.t_clk = tclk;
  700. mv78xx0_ge11_shared_data.t_clk = tclk;
  701. mv78xx0_uart0_data[0].uartclk = tclk;
  702. mv78xx0_uart1_data[0].uartclk = tclk;
  703. mv78xx0_uart2_data[0].uartclk = tclk;
  704. mv78xx0_uart3_data[0].uartclk = tclk;
  705. }