board-omapl138-hawk.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Hawkboard.org based on TI's OMAP-L138 Platform
  4. *
  5. * Initial code: Syed Mohammed Khasim
  6. *
  7. * Copyright (C) 2009 Texas Instruments Incorporated - https://www.ti.com
  8. */
  9. #include <linux/kernel.h>
  10. #include <linux/init.h>
  11. #include <linux/console.h>
  12. #include <linux/interrupt.h>
  13. #include <linux/gpio.h>
  14. #include <linux/gpio/machine.h>
  15. #include <linux/mtd/partitions.h>
  16. #include <linux/mtd/rawnand.h>
  17. #include <linux/platform_data/gpio-davinci.h>
  18. #include <linux/platform_data/mtd-davinci.h>
  19. #include <linux/platform_data/mtd-davinci-aemif.h>
  20. #include <linux/platform_data/ti-aemif.h>
  21. #include <linux/regulator/fixed.h>
  22. #include <linux/regulator/machine.h>
  23. #include <asm/mach-types.h>
  24. #include <asm/mach/arch.h>
  25. #include "common.h"
  26. #include "da8xx.h"
  27. #include "mux.h"
  28. #define HAWKBOARD_PHY_ID "davinci_mdio-0:07"
  29. #define DA850_USB1_VBUS_PIN GPIO_TO_PIN(2, 4)
  30. #define DA850_USB1_OC_PIN GPIO_TO_PIN(6, 13)
  31. static short omapl138_hawk_mii_pins[] __initdata = {
  32. DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3,
  33. DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER,
  34. DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3,
  35. DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK,
  36. DA850_MDIO_D,
  37. -1
  38. };
  39. static __init void omapl138_hawk_config_emac(void)
  40. {
  41. void __iomem *cfgchip3 = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG);
  42. int ret;
  43. u32 val;
  44. struct davinci_soc_info *soc_info = &davinci_soc_info;
  45. val = __raw_readl(cfgchip3);
  46. val &= ~BIT(8);
  47. ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins);
  48. if (ret) {
  49. pr_warn("%s: CPGMAC/MII mux setup failed: %d\n", __func__, ret);
  50. return;
  51. }
  52. /* configure the CFGCHIP3 register for MII */
  53. __raw_writel(val, cfgchip3);
  54. pr_info("EMAC: MII PHY configured\n");
  55. soc_info->emac_pdata->phy_id = HAWKBOARD_PHY_ID;
  56. ret = da8xx_register_emac();
  57. if (ret)
  58. pr_warn("%s: EMAC registration failed: %d\n", __func__, ret);
  59. }
  60. /*
  61. * The following EDMA channels/slots are not being used by drivers (for
  62. * example: Timer, GPIO, UART events etc) on da850/omap-l138 EVM/Hawkboard,
  63. * hence they are being reserved for codecs on the DSP side.
  64. */
  65. static const s16 da850_dma0_rsv_chans[][2] = {
  66. /* (offset, number) */
  67. { 8, 6},
  68. {24, 4},
  69. {30, 2},
  70. {-1, -1}
  71. };
  72. static const s16 da850_dma0_rsv_slots[][2] = {
  73. /* (offset, number) */
  74. { 8, 6},
  75. {24, 4},
  76. {30, 50},
  77. {-1, -1}
  78. };
  79. static const s16 da850_dma1_rsv_chans[][2] = {
  80. /* (offset, number) */
  81. { 0, 28},
  82. {30, 2},
  83. {-1, -1}
  84. };
  85. static const s16 da850_dma1_rsv_slots[][2] = {
  86. /* (offset, number) */
  87. { 0, 28},
  88. {30, 90},
  89. {-1, -1}
  90. };
  91. static struct edma_rsv_info da850_edma_cc0_rsv = {
  92. .rsv_chans = da850_dma0_rsv_chans,
  93. .rsv_slots = da850_dma0_rsv_slots,
  94. };
  95. static struct edma_rsv_info da850_edma_cc1_rsv = {
  96. .rsv_chans = da850_dma1_rsv_chans,
  97. .rsv_slots = da850_dma1_rsv_slots,
  98. };
  99. static struct edma_rsv_info *da850_edma_rsv[2] = {
  100. &da850_edma_cc0_rsv,
  101. &da850_edma_cc1_rsv,
  102. };
  103. static const short hawk_mmcsd0_pins[] = {
  104. DA850_MMCSD0_DAT_0, DA850_MMCSD0_DAT_1, DA850_MMCSD0_DAT_2,
  105. DA850_MMCSD0_DAT_3, DA850_MMCSD0_CLK, DA850_MMCSD0_CMD,
  106. DA850_GPIO3_12, DA850_GPIO3_13,
  107. -1
  108. };
  109. #define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12)
  110. #define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13)
  111. static struct gpiod_lookup_table mmc_gpios_table = {
  112. .dev_id = "da830-mmc.0",
  113. .table = {
  114. GPIO_LOOKUP("davinci_gpio", DA850_HAWK_MMCSD_CD_PIN, "cd",
  115. GPIO_ACTIVE_LOW),
  116. GPIO_LOOKUP("davinci_gpio", DA850_HAWK_MMCSD_WP_PIN, "wp",
  117. GPIO_ACTIVE_LOW),
  118. },
  119. };
  120. static struct davinci_mmc_config da850_mmc_config = {
  121. .wires = 4,
  122. .max_freq = 50000000,
  123. .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
  124. };
  125. static __init void omapl138_hawk_mmc_init(void)
  126. {
  127. int ret;
  128. ret = davinci_cfg_reg_list(hawk_mmcsd0_pins);
  129. if (ret) {
  130. pr_warn("%s: MMC/SD0 mux setup failed: %d\n", __func__, ret);
  131. return;
  132. }
  133. gpiod_add_lookup_table(&mmc_gpios_table);
  134. ret = da8xx_register_mmcsd0(&da850_mmc_config);
  135. if (ret) {
  136. pr_warn("%s: MMC/SD0 registration failed: %d\n", __func__, ret);
  137. goto mmc_setup_mmcsd_fail;
  138. }
  139. return;
  140. mmc_setup_mmcsd_fail:
  141. gpiod_remove_lookup_table(&mmc_gpios_table);
  142. }
  143. static struct mtd_partition omapl138_hawk_nandflash_partition[] = {
  144. {
  145. .name = "u-boot env",
  146. .offset = 0,
  147. .size = SZ_128K,
  148. .mask_flags = MTD_WRITEABLE,
  149. },
  150. {
  151. .name = "u-boot",
  152. .offset = MTDPART_OFS_APPEND,
  153. .size = SZ_512K,
  154. .mask_flags = MTD_WRITEABLE,
  155. },
  156. {
  157. .name = "free space",
  158. .offset = MTDPART_OFS_APPEND,
  159. .size = MTDPART_SIZ_FULL,
  160. .mask_flags = 0,
  161. },
  162. };
  163. static struct davinci_aemif_timing omapl138_hawk_nandflash_timing = {
  164. .wsetup = 24,
  165. .wstrobe = 21,
  166. .whold = 14,
  167. .rsetup = 19,
  168. .rstrobe = 50,
  169. .rhold = 0,
  170. .ta = 20,
  171. };
  172. static struct davinci_nand_pdata omapl138_hawk_nandflash_data = {
  173. .core_chipsel = 1,
  174. .parts = omapl138_hawk_nandflash_partition,
  175. .nr_parts = ARRAY_SIZE(omapl138_hawk_nandflash_partition),
  176. .engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST,
  177. .ecc_bits = 4,
  178. .bbt_options = NAND_BBT_USE_FLASH,
  179. .options = NAND_BUSWIDTH_16,
  180. .timing = &omapl138_hawk_nandflash_timing,
  181. .mask_chipsel = 0,
  182. .mask_ale = 0,
  183. .mask_cle = 0,
  184. };
  185. static struct resource omapl138_hawk_nandflash_resource[] = {
  186. {
  187. .start = DA8XX_AEMIF_CS3_BASE,
  188. .end = DA8XX_AEMIF_CS3_BASE + SZ_32M,
  189. .flags = IORESOURCE_MEM,
  190. },
  191. {
  192. .start = DA8XX_AEMIF_CTL_BASE,
  193. .end = DA8XX_AEMIF_CTL_BASE + SZ_32K,
  194. .flags = IORESOURCE_MEM,
  195. },
  196. };
  197. static struct resource omapl138_hawk_aemif_resource[] = {
  198. {
  199. .start = DA8XX_AEMIF_CTL_BASE,
  200. .end = DA8XX_AEMIF_CTL_BASE + SZ_32K,
  201. .flags = IORESOURCE_MEM,
  202. }
  203. };
  204. static struct aemif_abus_data omapl138_hawk_aemif_abus_data[] = {
  205. {
  206. .cs = 3,
  207. }
  208. };
  209. static struct platform_device omapl138_hawk_aemif_devices[] = {
  210. {
  211. .name = "davinci_nand",
  212. .id = -1,
  213. .dev = {
  214. .platform_data = &omapl138_hawk_nandflash_data,
  215. },
  216. .resource = omapl138_hawk_nandflash_resource,
  217. .num_resources = ARRAY_SIZE(omapl138_hawk_nandflash_resource),
  218. }
  219. };
  220. static struct aemif_platform_data omapl138_hawk_aemif_pdata = {
  221. .cs_offset = 2,
  222. .abus_data = omapl138_hawk_aemif_abus_data,
  223. .num_abus_data = ARRAY_SIZE(omapl138_hawk_aemif_abus_data),
  224. .sub_devices = omapl138_hawk_aemif_devices,
  225. .num_sub_devices = ARRAY_SIZE(omapl138_hawk_aemif_devices),
  226. };
  227. static struct platform_device omapl138_hawk_aemif_device = {
  228. .name = "ti-aemif",
  229. .id = -1,
  230. .dev = {
  231. .platform_data = &omapl138_hawk_aemif_pdata,
  232. },
  233. .resource = omapl138_hawk_aemif_resource,
  234. .num_resources = ARRAY_SIZE(omapl138_hawk_aemif_resource),
  235. };
  236. static const short omapl138_hawk_nand_pins[] = {
  237. DA850_EMA_WAIT_1, DA850_NEMA_OE, DA850_NEMA_WE, DA850_NEMA_CS_3,
  238. DA850_EMA_D_0, DA850_EMA_D_1, DA850_EMA_D_2, DA850_EMA_D_3,
  239. DA850_EMA_D_4, DA850_EMA_D_5, DA850_EMA_D_6, DA850_EMA_D_7,
  240. DA850_EMA_D_8, DA850_EMA_D_9, DA850_EMA_D_10, DA850_EMA_D_11,
  241. DA850_EMA_D_12, DA850_EMA_D_13, DA850_EMA_D_14, DA850_EMA_D_15,
  242. DA850_EMA_A_1, DA850_EMA_A_2,
  243. -1
  244. };
  245. static int omapl138_hawk_register_aemif(void)
  246. {
  247. int ret;
  248. ret = davinci_cfg_reg_list(omapl138_hawk_nand_pins);
  249. if (ret)
  250. pr_warn("%s: NAND mux setup failed: %d\n", __func__, ret);
  251. return platform_device_register(&omapl138_hawk_aemif_device);
  252. }
  253. static const short da850_hawk_usb11_pins[] = {
  254. DA850_GPIO2_4, DA850_GPIO6_13,
  255. -1
  256. };
  257. static struct regulator_consumer_supply hawk_usb_supplies[] = {
  258. REGULATOR_SUPPLY("vbus", NULL),
  259. };
  260. static struct regulator_init_data hawk_usb_vbus_data = {
  261. .consumer_supplies = hawk_usb_supplies,
  262. .num_consumer_supplies = ARRAY_SIZE(hawk_usb_supplies),
  263. .constraints = {
  264. .valid_ops_mask = REGULATOR_CHANGE_STATUS,
  265. },
  266. };
  267. static struct fixed_voltage_config hawk_usb_vbus = {
  268. .supply_name = "vbus",
  269. .microvolts = 3300000,
  270. .init_data = &hawk_usb_vbus_data,
  271. };
  272. static struct platform_device hawk_usb_vbus_device = {
  273. .name = "reg-fixed-voltage",
  274. .id = 0,
  275. .dev = {
  276. .platform_data = &hawk_usb_vbus,
  277. },
  278. };
  279. static struct gpiod_lookup_table hawk_usb_oc_gpio_lookup = {
  280. .dev_id = "ohci-da8xx",
  281. .table = {
  282. GPIO_LOOKUP("davinci_gpio", DA850_USB1_OC_PIN, "oc", 0),
  283. { }
  284. },
  285. };
  286. static struct gpiod_lookup_table hawk_usb_vbus_gpio_lookup = {
  287. .dev_id = "reg-fixed-voltage.0",
  288. .table = {
  289. GPIO_LOOKUP("davinci_gpio", DA850_USB1_VBUS_PIN, NULL, 0),
  290. { }
  291. },
  292. };
  293. static struct gpiod_lookup_table *hawk_usb_gpio_lookups[] = {
  294. &hawk_usb_oc_gpio_lookup,
  295. &hawk_usb_vbus_gpio_lookup,
  296. };
  297. static struct da8xx_ohci_root_hub omapl138_hawk_usb11_pdata = {
  298. /* TPS2087 switch @ 5V */
  299. .potpgt = (3 + 1) / 2, /* 3 ms max */
  300. };
  301. static __init void omapl138_hawk_usb_init(void)
  302. {
  303. int ret;
  304. ret = davinci_cfg_reg_list(da850_hawk_usb11_pins);
  305. if (ret) {
  306. pr_warn("%s: USB 1.1 PinMux setup failed: %d\n", __func__, ret);
  307. return;
  308. }
  309. ret = da8xx_register_usb_phy_clocks();
  310. if (ret)
  311. pr_warn("%s: USB PHY CLK registration failed: %d\n",
  312. __func__, ret);
  313. gpiod_add_lookup_tables(hawk_usb_gpio_lookups,
  314. ARRAY_SIZE(hawk_usb_gpio_lookups));
  315. ret = da8xx_register_usb_phy();
  316. if (ret)
  317. pr_warn("%s: USB PHY registration failed: %d\n",
  318. __func__, ret);
  319. ret = platform_device_register(&hawk_usb_vbus_device);
  320. if (ret) {
  321. pr_warn("%s: Unable to register the vbus supply\n", __func__);
  322. return;
  323. }
  324. ret = da8xx_register_usb11(&omapl138_hawk_usb11_pdata);
  325. if (ret)
  326. pr_warn("%s: USB 1.1 registration failed: %d\n", __func__, ret);
  327. return;
  328. }
  329. static __init void omapl138_hawk_init(void)
  330. {
  331. int ret;
  332. da850_register_clocks();
  333. ret = da850_register_gpio();
  334. if (ret)
  335. pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
  336. davinci_serial_init(da8xx_serial_device);
  337. omapl138_hawk_config_emac();
  338. ret = da850_register_edma(da850_edma_rsv);
  339. if (ret)
  340. pr_warn("%s: EDMA registration failed: %d\n", __func__, ret);
  341. omapl138_hawk_mmc_init();
  342. omapl138_hawk_usb_init();
  343. ret = omapl138_hawk_register_aemif();
  344. if (ret)
  345. pr_warn("%s: aemif registration failed: %d\n", __func__, ret);
  346. ret = da8xx_register_watchdog();
  347. if (ret)
  348. pr_warn("%s: watchdog registration failed: %d\n",
  349. __func__, ret);
  350. ret = da8xx_register_rproc();
  351. if (ret)
  352. pr_warn("%s: dsp/rproc registration failed: %d\n",
  353. __func__, ret);
  354. regulator_has_full_constraints();
  355. }
  356. #ifdef CONFIG_SERIAL_8250_CONSOLE
  357. static int __init omapl138_hawk_console_init(void)
  358. {
  359. if (!machine_is_omapl138_hawkboard())
  360. return 0;
  361. return add_preferred_console("ttyS", 2, "115200");
  362. }
  363. console_initcall(omapl138_hawk_console_init);
  364. #endif
  365. static void __init omapl138_hawk_map_io(void)
  366. {
  367. da850_init();
  368. }
  369. MACHINE_START(OMAPL138_HAWKBOARD, "AM18x/OMAP-L138 Hawkboard")
  370. .atag_offset = 0x100,
  371. .map_io = omapl138_hawk_map_io,
  372. .init_irq = da850_init_irq,
  373. .init_time = da850_init_time,
  374. .init_machine = omapl138_hawk_init,
  375. .init_late = davinci_init_late,
  376. .dma_zone_size = SZ_128M,
  377. .reserve = da8xx_rproc_reserve_cma,
  378. MACHINE_END