common.c 21 KB

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