platform.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright (c) 2011-2016 Zhang, Keguang <[email protected]>
  4. */
  5. #include <linux/clk.h>
  6. #include <linux/dma-mapping.h>
  7. #include <linux/err.h>
  8. #include <linux/mtd/partitions.h>
  9. #include <linux/sizes.h>
  10. #include <linux/phy.h>
  11. #include <linux/serial_8250.h>
  12. #include <linux/stmmac.h>
  13. #include <linux/usb/ehci_pdriver.h>
  14. #include <platform.h>
  15. #include <loongson1.h>
  16. #include <cpufreq.h>
  17. #include <dma.h>
  18. #include <nand.h>
  19. /* 8250/16550 compatible UART */
  20. #define LS1X_UART(_id) \
  21. { \
  22. .mapbase = LS1X_UART ## _id ## _BASE, \
  23. .irq = LS1X_UART ## _id ## _IRQ, \
  24. .iotype = UPIO_MEM, \
  25. .flags = UPF_IOREMAP | UPF_FIXED_TYPE, \
  26. .type = PORT_16550A, \
  27. }
  28. static struct plat_serial8250_port ls1x_serial8250_pdata[] = {
  29. LS1X_UART(0),
  30. LS1X_UART(1),
  31. LS1X_UART(2),
  32. LS1X_UART(3),
  33. {},
  34. };
  35. struct platform_device ls1x_uart_pdev = {
  36. .name = "serial8250",
  37. .id = PLAT8250_DEV_PLATFORM,
  38. .dev = {
  39. .platform_data = ls1x_serial8250_pdata,
  40. },
  41. };
  42. void __init ls1x_serial_set_uartclk(struct platform_device *pdev)
  43. {
  44. struct clk *clk;
  45. struct plat_serial8250_port *p;
  46. clk = clk_get(&pdev->dev, pdev->name);
  47. if (IS_ERR(clk)) {
  48. pr_err("unable to get %s clock, err=%ld",
  49. pdev->name, PTR_ERR(clk));
  50. return;
  51. }
  52. clk_prepare_enable(clk);
  53. for (p = pdev->dev.platform_data; p->flags != 0; ++p)
  54. p->uartclk = clk_get_rate(clk);
  55. }
  56. /* CPUFreq */
  57. static struct plat_ls1x_cpufreq ls1x_cpufreq_pdata = {
  58. .clk_name = "cpu_clk",
  59. .osc_clk_name = "osc_clk",
  60. .max_freq = 266 * 1000,
  61. .min_freq = 33 * 1000,
  62. };
  63. struct platform_device ls1x_cpufreq_pdev = {
  64. .name = "ls1x-cpufreq",
  65. .dev = {
  66. .platform_data = &ls1x_cpufreq_pdata,
  67. },
  68. };
  69. /* Synopsys Ethernet GMAC */
  70. static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = {
  71. .phy_mask = 0,
  72. };
  73. static struct stmmac_dma_cfg ls1x_eth_dma_cfg = {
  74. .pbl = 1,
  75. };
  76. int ls1x_eth_mux_init(struct platform_device *pdev, void *priv)
  77. {
  78. struct plat_stmmacenet_data *plat_dat = NULL;
  79. u32 val;
  80. val = __raw_readl(LS1X_MUX_CTRL1);
  81. #if defined(CONFIG_LOONGSON1_LS1B)
  82. plat_dat = dev_get_platdata(&pdev->dev);
  83. if (plat_dat->bus_id) {
  84. __raw_writel(__raw_readl(LS1X_MUX_CTRL0) | GMAC1_USE_UART1 |
  85. GMAC1_USE_UART0, LS1X_MUX_CTRL0);
  86. switch (plat_dat->phy_interface) {
  87. case PHY_INTERFACE_MODE_RGMII:
  88. val &= ~(GMAC1_USE_TXCLK | GMAC1_USE_PWM23);
  89. break;
  90. case PHY_INTERFACE_MODE_MII:
  91. val |= (GMAC1_USE_TXCLK | GMAC1_USE_PWM23);
  92. break;
  93. default:
  94. pr_err("unsupported mii mode %d\n",
  95. plat_dat->phy_interface);
  96. return -ENOTSUPP;
  97. }
  98. val &= ~GMAC1_SHUT;
  99. } else {
  100. switch (plat_dat->phy_interface) {
  101. case PHY_INTERFACE_MODE_RGMII:
  102. val &= ~(GMAC0_USE_TXCLK | GMAC0_USE_PWM01);
  103. break;
  104. case PHY_INTERFACE_MODE_MII:
  105. val |= (GMAC0_USE_TXCLK | GMAC0_USE_PWM01);
  106. break;
  107. default:
  108. pr_err("unsupported mii mode %d\n",
  109. plat_dat->phy_interface);
  110. return -ENOTSUPP;
  111. }
  112. val &= ~GMAC0_SHUT;
  113. }
  114. __raw_writel(val, LS1X_MUX_CTRL1);
  115. #elif defined(CONFIG_LOONGSON1_LS1C)
  116. plat_dat = dev_get_platdata(&pdev->dev);
  117. val &= ~PHY_INTF_SELI;
  118. if (plat_dat->phy_interface == PHY_INTERFACE_MODE_RMII)
  119. val |= 0x4 << PHY_INTF_SELI_SHIFT;
  120. __raw_writel(val, LS1X_MUX_CTRL1);
  121. val = __raw_readl(LS1X_MUX_CTRL0);
  122. __raw_writel(val & (~GMAC_SHUT), LS1X_MUX_CTRL0);
  123. #endif
  124. return 0;
  125. }
  126. static struct plat_stmmacenet_data ls1x_eth0_pdata = {
  127. .bus_id = 0,
  128. .phy_addr = -1,
  129. #if defined(CONFIG_LOONGSON1_LS1B)
  130. .phy_interface = PHY_INTERFACE_MODE_MII,
  131. #elif defined(CONFIG_LOONGSON1_LS1C)
  132. .phy_interface = PHY_INTERFACE_MODE_RMII,
  133. #endif
  134. .mdio_bus_data = &ls1x_mdio_bus_data,
  135. .dma_cfg = &ls1x_eth_dma_cfg,
  136. .has_gmac = 1,
  137. .tx_coe = 1,
  138. .rx_queues_to_use = 1,
  139. .tx_queues_to_use = 1,
  140. .init = ls1x_eth_mux_init,
  141. };
  142. static struct resource ls1x_eth0_resources[] = {
  143. [0] = {
  144. .start = LS1X_GMAC0_BASE,
  145. .end = LS1X_GMAC0_BASE + SZ_64K - 1,
  146. .flags = IORESOURCE_MEM,
  147. },
  148. [1] = {
  149. .name = "macirq",
  150. .start = LS1X_GMAC0_IRQ,
  151. .flags = IORESOURCE_IRQ,
  152. },
  153. };
  154. struct platform_device ls1x_eth0_pdev = {
  155. .name = "stmmaceth",
  156. .id = 0,
  157. .num_resources = ARRAY_SIZE(ls1x_eth0_resources),
  158. .resource = ls1x_eth0_resources,
  159. .dev = {
  160. .platform_data = &ls1x_eth0_pdata,
  161. },
  162. };
  163. #ifdef CONFIG_LOONGSON1_LS1B
  164. static struct plat_stmmacenet_data ls1x_eth1_pdata = {
  165. .bus_id = 1,
  166. .phy_addr = -1,
  167. .phy_interface = PHY_INTERFACE_MODE_MII,
  168. .mdio_bus_data = &ls1x_mdio_bus_data,
  169. .dma_cfg = &ls1x_eth_dma_cfg,
  170. .has_gmac = 1,
  171. .tx_coe = 1,
  172. .rx_queues_to_use = 1,
  173. .tx_queues_to_use = 1,
  174. .init = ls1x_eth_mux_init,
  175. };
  176. static struct resource ls1x_eth1_resources[] = {
  177. [0] = {
  178. .start = LS1X_GMAC1_BASE,
  179. .end = LS1X_GMAC1_BASE + SZ_64K - 1,
  180. .flags = IORESOURCE_MEM,
  181. },
  182. [1] = {
  183. .name = "macirq",
  184. .start = LS1X_GMAC1_IRQ,
  185. .flags = IORESOURCE_IRQ,
  186. },
  187. };
  188. struct platform_device ls1x_eth1_pdev = {
  189. .name = "stmmaceth",
  190. .id = 1,
  191. .num_resources = ARRAY_SIZE(ls1x_eth1_resources),
  192. .resource = ls1x_eth1_resources,
  193. .dev = {
  194. .platform_data = &ls1x_eth1_pdata,
  195. },
  196. };
  197. #endif /* CONFIG_LOONGSON1_LS1B */
  198. /* GPIO */
  199. static struct resource ls1x_gpio0_resources[] = {
  200. [0] = {
  201. .start = LS1X_GPIO0_BASE,
  202. .end = LS1X_GPIO0_BASE + SZ_4 - 1,
  203. .flags = IORESOURCE_MEM,
  204. },
  205. };
  206. struct platform_device ls1x_gpio0_pdev = {
  207. .name = "ls1x-gpio",
  208. .id = 0,
  209. .num_resources = ARRAY_SIZE(ls1x_gpio0_resources),
  210. .resource = ls1x_gpio0_resources,
  211. };
  212. static struct resource ls1x_gpio1_resources[] = {
  213. [0] = {
  214. .start = LS1X_GPIO1_BASE,
  215. .end = LS1X_GPIO1_BASE + SZ_4 - 1,
  216. .flags = IORESOURCE_MEM,
  217. },
  218. };
  219. struct platform_device ls1x_gpio1_pdev = {
  220. .name = "ls1x-gpio",
  221. .id = 1,
  222. .num_resources = ARRAY_SIZE(ls1x_gpio1_resources),
  223. .resource = ls1x_gpio1_resources,
  224. };
  225. /* USB EHCI */
  226. static u64 ls1x_ehci_dmamask = DMA_BIT_MASK(32);
  227. static struct resource ls1x_ehci_resources[] = {
  228. [0] = {
  229. .start = LS1X_EHCI_BASE,
  230. .end = LS1X_EHCI_BASE + SZ_32K - 1,
  231. .flags = IORESOURCE_MEM,
  232. },
  233. [1] = {
  234. .start = LS1X_EHCI_IRQ,
  235. .flags = IORESOURCE_IRQ,
  236. },
  237. };
  238. static struct usb_ehci_pdata ls1x_ehci_pdata = {
  239. };
  240. struct platform_device ls1x_ehci_pdev = {
  241. .name = "ehci-platform",
  242. .id = -1,
  243. .num_resources = ARRAY_SIZE(ls1x_ehci_resources),
  244. .resource = ls1x_ehci_resources,
  245. .dev = {
  246. .dma_mask = &ls1x_ehci_dmamask,
  247. .platform_data = &ls1x_ehci_pdata,
  248. },
  249. };
  250. /* Real Time Clock */
  251. void __init ls1x_rtc_set_extclk(struct platform_device *pdev)
  252. {
  253. u32 val = __raw_readl(LS1X_RTC_CTRL);
  254. if (!(val & RTC_EXTCLK_OK))
  255. __raw_writel(val | RTC_EXTCLK_EN, LS1X_RTC_CTRL);
  256. }
  257. struct platform_device ls1x_rtc_pdev = {
  258. .name = "ls1x-rtc",
  259. .id = -1,
  260. };
  261. /* Watchdog */
  262. static struct resource ls1x_wdt_resources[] = {
  263. {
  264. .start = LS1X_WDT_BASE,
  265. .end = LS1X_WDT_BASE + SZ_16 - 1,
  266. .flags = IORESOURCE_MEM,
  267. },
  268. };
  269. struct platform_device ls1x_wdt_pdev = {
  270. .name = "ls1x-wdt",
  271. .id = -1,
  272. .num_resources = ARRAY_SIZE(ls1x_wdt_resources),
  273. .resource = ls1x_wdt_resources,
  274. };