v2m.c 9.8 KB

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