v2m.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. /*
  2. * Versatile Express V2M Motherboard Support
  3. */
  4. #include <linux/device.h>
  5. #include <linux/amba/bus.h>
  6. #include <linux/amba/mmci.h>
  7. #include <linux/io.h>
  8. #include <linux/init.h>
  9. #include <linux/platform_device.h>
  10. #include <linux/ata_platform.h>
  11. #include <linux/smsc911x.h>
  12. #include <linux/spinlock.h>
  13. #include <linux/sysdev.h>
  14. #include <linux/usb/isp1760.h>
  15. #include <linux/clkdev.h>
  16. #include <asm/mach-types.h>
  17. #include <asm/sizes.h>
  18. #include <asm/mach/arch.h>
  19. #include <asm/mach/flash.h>
  20. #include <asm/mach/map.h>
  21. #include <asm/mach/time.h>
  22. #include <asm/hardware/arm_timer.h>
  23. #include <asm/hardware/timer-sp.h>
  24. #include <asm/hardware/sp810.h>
  25. #include <mach/ct-ca9x4.h>
  26. #include <mach/motherboard.h>
  27. #include <plat/sched_clock.h>
  28. #include "core.h"
  29. #define V2M_PA_CS0 0x40000000
  30. #define V2M_PA_CS1 0x44000000
  31. #define V2M_PA_CS2 0x48000000
  32. #define V2M_PA_CS3 0x4c000000
  33. #define V2M_PA_CS7 0x10000000
  34. static struct map_desc v2m_io_desc[] __initdata = {
  35. {
  36. .virtual = __MMIO_P2V(V2M_PA_CS7),
  37. .pfn = __phys_to_pfn(V2M_PA_CS7),
  38. .length = SZ_128K,
  39. .type = MT_DEVICE,
  40. },
  41. };
  42. static void __init v2m_init_early(void)
  43. {
  44. ct_desc->init_early();
  45. versatile_sched_clock_init(MMIO_P2V(V2M_SYS_24MHZ), 24000000);
  46. }
  47. static void __init v2m_timer_init(void)
  48. {
  49. u32 scctrl;
  50. /* Select 1MHz TIMCLK as the reference clock for SP804 timers */
  51. scctrl = readl(MMIO_P2V(V2M_SYSCTL + SCCTRL));
  52. scctrl |= SCCTRL_TIMEREN0SEL_TIMCLK;
  53. scctrl |= SCCTRL_TIMEREN1SEL_TIMCLK;
  54. writel(scctrl, MMIO_P2V(V2M_SYSCTL + SCCTRL));
  55. writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL);
  56. writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL);
  57. sp804_clocksource_init(MMIO_P2V(V2M_TIMER1), "v2m-timer1");
  58. sp804_clockevents_init(MMIO_P2V(V2M_TIMER0), IRQ_V2M_TIMER0,
  59. "v2m-timer0");
  60. }
  61. static struct sys_timer v2m_timer = {
  62. .init = v2m_timer_init,
  63. };
  64. static DEFINE_SPINLOCK(v2m_cfg_lock);
  65. int v2m_cfg_write(u32 devfn, u32 data)
  66. {
  67. /* Configuration interface broken? */
  68. u32 val;
  69. printk("%s: writing %08x to %08x\n", __func__, data, devfn);
  70. devfn |= SYS_CFG_START | SYS_CFG_WRITE;
  71. spin_lock(&v2m_cfg_lock);
  72. val = readl(MMIO_P2V(V2M_SYS_CFGSTAT));
  73. writel(val & ~SYS_CFG_COMPLETE, MMIO_P2V(V2M_SYS_CFGSTAT));
  74. writel(data, MMIO_P2V(V2M_SYS_CFGDATA));
  75. writel(devfn, MMIO_P2V(V2M_SYS_CFGCTRL));
  76. do {
  77. val = readl(MMIO_P2V(V2M_SYS_CFGSTAT));
  78. } while (val == 0);
  79. spin_unlock(&v2m_cfg_lock);
  80. return !!(val & SYS_CFG_ERR);
  81. }
  82. int v2m_cfg_read(u32 devfn, u32 *data)
  83. {
  84. u32 val;
  85. devfn |= SYS_CFG_START;
  86. spin_lock(&v2m_cfg_lock);
  87. writel(0, MMIO_P2V(V2M_SYS_CFGSTAT));
  88. writel(devfn, MMIO_P2V(V2M_SYS_CFGCTRL));
  89. mb();
  90. do {
  91. cpu_relax();
  92. val = readl(MMIO_P2V(V2M_SYS_CFGSTAT));
  93. } while (val == 0);
  94. *data = readl(MMIO_P2V(V2M_SYS_CFGDATA));
  95. spin_unlock(&v2m_cfg_lock);
  96. return !!(val & SYS_CFG_ERR);
  97. }
  98. static struct resource v2m_pcie_i2c_resource = {
  99. .start = V2M_SERIAL_BUS_PCI,
  100. .end = V2M_SERIAL_BUS_PCI + SZ_4K - 1,
  101. .flags = IORESOURCE_MEM,
  102. };
  103. static struct platform_device v2m_pcie_i2c_device = {
  104. .name = "versatile-i2c",
  105. .id = 0,
  106. .num_resources = 1,
  107. .resource = &v2m_pcie_i2c_resource,
  108. };
  109. static struct resource v2m_ddc_i2c_resource = {
  110. .start = V2M_SERIAL_BUS_DVI,
  111. .end = V2M_SERIAL_BUS_DVI + SZ_4K - 1,
  112. .flags = IORESOURCE_MEM,
  113. };
  114. static struct platform_device v2m_ddc_i2c_device = {
  115. .name = "versatile-i2c",
  116. .id = 1,
  117. .num_resources = 1,
  118. .resource = &v2m_ddc_i2c_resource,
  119. };
  120. static struct resource v2m_eth_resources[] = {
  121. {
  122. .start = V2M_LAN9118,
  123. .end = V2M_LAN9118 + SZ_64K - 1,
  124. .flags = IORESOURCE_MEM,
  125. }, {
  126. .start = IRQ_V2M_LAN9118,
  127. .end = IRQ_V2M_LAN9118,
  128. .flags = IORESOURCE_IRQ,
  129. },
  130. };
  131. static struct smsc911x_platform_config v2m_eth_config = {
  132. .flags = SMSC911X_USE_32BIT,
  133. .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
  134. .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
  135. .phy_interface = PHY_INTERFACE_MODE_MII,
  136. };
  137. static struct platform_device v2m_eth_device = {
  138. .name = "smsc911x",
  139. .id = -1,
  140. .resource = v2m_eth_resources,
  141. .num_resources = ARRAY_SIZE(v2m_eth_resources),
  142. .dev.platform_data = &v2m_eth_config,
  143. };
  144. static struct resource v2m_usb_resources[] = {
  145. {
  146. .start = V2M_ISP1761,
  147. .end = V2M_ISP1761 + SZ_128K - 1,
  148. .flags = IORESOURCE_MEM,
  149. }, {
  150. .start = IRQ_V2M_ISP1761,
  151. .end = IRQ_V2M_ISP1761,
  152. .flags = IORESOURCE_IRQ,
  153. },
  154. };
  155. static struct isp1760_platform_data v2m_usb_config = {
  156. .is_isp1761 = true,
  157. .bus_width_16 = false,
  158. .port1_otg = true,
  159. .analog_oc = false,
  160. .dack_polarity_high = false,
  161. .dreq_polarity_high = false,
  162. };
  163. static struct platform_device v2m_usb_device = {
  164. .name = "isp1760",
  165. .id = -1,
  166. .resource = v2m_usb_resources,
  167. .num_resources = ARRAY_SIZE(v2m_usb_resources),
  168. .dev.platform_data = &v2m_usb_config,
  169. };
  170. static int v2m_flash_init(void)
  171. {
  172. writel(0, MMIO_P2V(V2M_SYS_FLASH));
  173. return 0;
  174. }
  175. static void v2m_flash_exit(void)
  176. {
  177. writel(0, MMIO_P2V(V2M_SYS_FLASH));
  178. }
  179. static void v2m_flash_set_vpp(int on)
  180. {
  181. writel(on != 0, MMIO_P2V(V2M_SYS_FLASH));
  182. }
  183. static struct flash_platform_data v2m_flash_data = {
  184. .map_name = "cfi_probe",
  185. .width = 4,
  186. .init = v2m_flash_init,
  187. .exit = v2m_flash_exit,
  188. .set_vpp = v2m_flash_set_vpp,
  189. };
  190. static struct resource v2m_flash_resources[] = {
  191. {
  192. .start = V2M_NOR0,
  193. .end = V2M_NOR0 + SZ_64M - 1,
  194. .flags = IORESOURCE_MEM,
  195. }, {
  196. .start = V2M_NOR1,
  197. .end = V2M_NOR1 + SZ_64M - 1,
  198. .flags = IORESOURCE_MEM,
  199. },
  200. };
  201. static struct platform_device v2m_flash_device = {
  202. .name = "armflash",
  203. .id = -1,
  204. .resource = v2m_flash_resources,
  205. .num_resources = ARRAY_SIZE(v2m_flash_resources),
  206. .dev.platform_data = &v2m_flash_data,
  207. };
  208. static struct pata_platform_info v2m_pata_data = {
  209. .ioport_shift = 2,
  210. };
  211. static struct resource v2m_pata_resources[] = {
  212. {
  213. .start = V2M_CF,
  214. .end = V2M_CF + 0xff,
  215. .flags = IORESOURCE_MEM,
  216. }, {
  217. .start = V2M_CF + 0x100,
  218. .end = V2M_CF + SZ_4K - 1,
  219. .flags = IORESOURCE_MEM,
  220. },
  221. };
  222. static struct platform_device v2m_cf_device = {
  223. .name = "pata_platform",
  224. .id = -1,
  225. .resource = v2m_pata_resources,
  226. .num_resources = ARRAY_SIZE(v2m_pata_resources),
  227. .dev.platform_data = &v2m_pata_data,
  228. };
  229. static unsigned int v2m_mmci_status(struct device *dev)
  230. {
  231. return readl(MMIO_P2V(V2M_SYS_MCI)) & (1 << 0);
  232. }
  233. static struct mmci_platform_data v2m_mmci_data = {
  234. .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
  235. .status = v2m_mmci_status,
  236. };
  237. static AMBA_DEVICE(aaci, "mb:aaci", V2M_AACI, NULL);
  238. static AMBA_DEVICE(mmci, "mb:mmci", V2M_MMCI, &v2m_mmci_data);
  239. static AMBA_DEVICE(kmi0, "mb:kmi0", V2M_KMI0, NULL);
  240. static AMBA_DEVICE(kmi1, "mb:kmi1", V2M_KMI1, NULL);
  241. static AMBA_DEVICE(uart0, "mb:uart0", V2M_UART0, NULL);
  242. static AMBA_DEVICE(uart1, "mb:uart1", V2M_UART1, NULL);
  243. static AMBA_DEVICE(uart2, "mb:uart2", V2M_UART2, NULL);
  244. static AMBA_DEVICE(uart3, "mb:uart3", V2M_UART3, NULL);
  245. static AMBA_DEVICE(wdt, "mb:wdt", V2M_WDT, NULL);
  246. static AMBA_DEVICE(rtc, "mb:rtc", V2M_RTC, NULL);
  247. static struct amba_device *v2m_amba_devs[] __initdata = {
  248. &aaci_device,
  249. &mmci_device,
  250. &kmi0_device,
  251. &kmi1_device,
  252. &uart0_device,
  253. &uart1_device,
  254. &uart2_device,
  255. &uart3_device,
  256. &wdt_device,
  257. &rtc_device,
  258. };
  259. static long v2m_osc_round(struct clk *clk, unsigned long rate)
  260. {
  261. return rate;
  262. }
  263. static int v2m_osc1_set(struct clk *clk, unsigned long rate)
  264. {
  265. return v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE_MB | 1, rate);
  266. }
  267. static const struct clk_ops osc1_clk_ops = {
  268. .round = v2m_osc_round,
  269. .set = v2m_osc1_set,
  270. };
  271. static struct clk osc1_clk = {
  272. .ops = &osc1_clk_ops,
  273. .rate = 24000000,
  274. };
  275. static struct clk osc2_clk = {
  276. .rate = 24000000,
  277. };
  278. static struct clk v2m_sp804_clk = {
  279. .rate = 1000000,
  280. };
  281. static struct clk dummy_apb_pclk;
  282. static struct clk_lookup v2m_lookups[] = {
  283. { /* AMBA bus clock */
  284. .con_id = "apb_pclk",
  285. .clk = &dummy_apb_pclk,
  286. }, { /* UART0 */
  287. .dev_id = "mb:uart0",
  288. .clk = &osc2_clk,
  289. }, { /* UART1 */
  290. .dev_id = "mb:uart1",
  291. .clk = &osc2_clk,
  292. }, { /* UART2 */
  293. .dev_id = "mb:uart2",
  294. .clk = &osc2_clk,
  295. }, { /* UART3 */
  296. .dev_id = "mb:uart3",
  297. .clk = &osc2_clk,
  298. }, { /* KMI0 */
  299. .dev_id = "mb:kmi0",
  300. .clk = &osc2_clk,
  301. }, { /* KMI1 */
  302. .dev_id = "mb:kmi1",
  303. .clk = &osc2_clk,
  304. }, { /* MMC0 */
  305. .dev_id = "mb:mmci",
  306. .clk = &osc2_clk,
  307. }, { /* CLCD */
  308. .dev_id = "mb:clcd",
  309. .clk = &osc1_clk,
  310. }, { /* SP804 timers */
  311. .dev_id = "sp804",
  312. .con_id = "v2m-timer0",
  313. .clk = &v2m_sp804_clk,
  314. }, { /* SP804 timers */
  315. .dev_id = "sp804",
  316. .con_id = "v2m-timer1",
  317. .clk = &v2m_sp804_clk,
  318. },
  319. };
  320. static void v2m_power_off(void)
  321. {
  322. if (v2m_cfg_write(SYS_CFG_SHUTDOWN | SYS_CFG_SITE_MB, 0))
  323. printk(KERN_EMERG "Unable to shutdown\n");
  324. }
  325. static void v2m_restart(char str, const char *cmd)
  326. {
  327. if (v2m_cfg_write(SYS_CFG_REBOOT | SYS_CFG_SITE_MB, 0))
  328. printk(KERN_EMERG "Unable to reboot\n");
  329. }
  330. struct ct_desc *ct_desc;
  331. static struct ct_desc *ct_descs[] __initdata = {
  332. #ifdef CONFIG_ARCH_VEXPRESS_CA9X4
  333. &ct_ca9x4_desc,
  334. #endif
  335. };
  336. static void __init v2m_populate_ct_desc(void)
  337. {
  338. int i;
  339. u32 current_tile_id;
  340. ct_desc = NULL;
  341. current_tile_id = readl(MMIO_P2V(V2M_SYS_PROCID0)) & V2M_CT_ID_MASK;
  342. for (i = 0; i < ARRAY_SIZE(ct_descs) && !ct_desc; ++i)
  343. if (ct_descs[i]->id == current_tile_id)
  344. ct_desc = ct_descs[i];
  345. if (!ct_desc)
  346. panic("vexpress: failed to populate core tile description "
  347. "for tile ID 0x%8x\n", current_tile_id);
  348. }
  349. static void __init v2m_map_io(void)
  350. {
  351. iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc));
  352. v2m_populate_ct_desc();
  353. ct_desc->map_io();
  354. }
  355. static void __init v2m_init_irq(void)
  356. {
  357. ct_desc->init_irq();
  358. }
  359. static void __init v2m_init(void)
  360. {
  361. int i;
  362. clkdev_add_table(v2m_lookups, ARRAY_SIZE(v2m_lookups));
  363. platform_device_register(&v2m_pcie_i2c_device);
  364. platform_device_register(&v2m_ddc_i2c_device);
  365. platform_device_register(&v2m_flash_device);
  366. platform_device_register(&v2m_cf_device);
  367. platform_device_register(&v2m_eth_device);
  368. platform_device_register(&v2m_usb_device);
  369. for (i = 0; i < ARRAY_SIZE(v2m_amba_devs); i++)
  370. amba_device_register(v2m_amba_devs[i], &iomem_resource);
  371. pm_power_off = v2m_power_off;
  372. arm_pm_restart = v2m_restart;
  373. ct_desc->init_tile();
  374. }
  375. MACHINE_START(VEXPRESS, "ARM-Versatile Express")
  376. .boot_params = PLAT_PHYS_OFFSET + 0x00000100,
  377. .map_io = v2m_map_io,
  378. .init_early = v2m_init_early,
  379. .init_irq = v2m_init_irq,
  380. .timer = &v2m_timer,
  381. .init_machine = v2m_init,
  382. MACHINE_END