1 /* 2 * Copyright (c) 2011-2016 Zhang, Keguang <keguang.zhang@gmail.com> 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License as published by the 6 * Free Software Foundation; either version 2 of the License, or (at your 7 * option) any later version. 8 */ 9 10 #include <linux/clk.h> 11 #include <linux/dma-mapping.h> 12 #include <linux/err.h> 13 #include <linux/mtd/partitions.h> 14 #include <linux/sizes.h> 15 #include <linux/phy.h> 16 #include <linux/serial_8250.h> 17 #include <linux/stmmac.h> 18 #include <linux/usb/ehci_pdriver.h> 19 20 #include <platform.h> 21 #include <loongson1.h> 22 #include <cpufreq.h> 23 #include <dma.h> 24 #include <nand.h> 25 26 #define LS1X_RTC_CTRL ((void __iomem *)KSEG1ADDR(LS1X_RTC_BASE + 0x40)) 27 #define RTC_EXTCLK_OK (BIT(5) | BIT(8)) 28 #define RTC_EXTCLK_EN BIT(8) 29 30 /* 8250/16550 compatible UART */ 31 #define LS1X_UART(_id) \ 32 { \ 33 .mapbase = LS1X_UART ## _id ## _BASE, \ 34 .irq = LS1X_UART ## _id ## _IRQ, \ 35 .iotype = UPIO_MEM, \ 36 .flags = UPF_IOREMAP | UPF_FIXED_TYPE, \ 37 .type = PORT_16550A, \ 38 } 39 40 static struct plat_serial8250_port ls1x_serial8250_pdata[] = { 41 LS1X_UART(0), 42 LS1X_UART(1), 43 LS1X_UART(2), 44 LS1X_UART(3), 45 {}, 46 }; 47 48 struct platform_device ls1x_uart_pdev = { 49 .name = "serial8250", 50 .id = PLAT8250_DEV_PLATFORM, 51 .dev = { 52 .platform_data = ls1x_serial8250_pdata, 53 }, 54 }; 55 56 void __init ls1x_serial_set_uartclk(struct platform_device *pdev) 57 { 58 struct clk *clk; 59 struct plat_serial8250_port *p; 60 61 clk = clk_get(&pdev->dev, pdev->name); 62 if (IS_ERR(clk)) { 63 pr_err("unable to get %s clock, err=%ld", 64 pdev->name, PTR_ERR(clk)); 65 return; 66 } 67 clk_prepare_enable(clk); 68 69 for (p = pdev->dev.platform_data; p->flags != 0; ++p) 70 p->uartclk = clk_get_rate(clk); 71 } 72 73 void __init ls1x_rtc_set_extclk(struct platform_device *pdev) 74 { 75 u32 val; 76 77 val = __raw_readl(LS1X_RTC_CTRL); 78 if (!(val & RTC_EXTCLK_OK)) 79 __raw_writel(val | RTC_EXTCLK_EN, LS1X_RTC_CTRL); 80 } 81 82 /* CPUFreq */ 83 static struct plat_ls1x_cpufreq ls1x_cpufreq_pdata = { 84 .clk_name = "cpu_clk", 85 .osc_clk_name = "osc_33m_clk", 86 .max_freq = 266 * 1000, 87 .min_freq = 33 * 1000, 88 }; 89 90 struct platform_device ls1x_cpufreq_pdev = { 91 .name = "ls1x-cpufreq", 92 .dev = { 93 .platform_data = &ls1x_cpufreq_pdata, 94 }, 95 }; 96 97 /* DMA */ 98 static struct resource ls1x_dma_resources[] = { 99 [0] = { 100 .start = LS1X_DMAC_BASE, 101 .end = LS1X_DMAC_BASE + SZ_4 - 1, 102 .flags = IORESOURCE_MEM, 103 }, 104 [1] = { 105 .start = LS1X_DMA0_IRQ, 106 .end = LS1X_DMA0_IRQ, 107 .flags = IORESOURCE_IRQ, 108 }, 109 [2] = { 110 .start = LS1X_DMA1_IRQ, 111 .end = LS1X_DMA1_IRQ, 112 .flags = IORESOURCE_IRQ, 113 }, 114 [3] = { 115 .start = LS1X_DMA2_IRQ, 116 .end = LS1X_DMA2_IRQ, 117 .flags = IORESOURCE_IRQ, 118 }, 119 }; 120 121 struct platform_device ls1x_dma_pdev = { 122 .name = "ls1x-dma", 123 .id = -1, 124 .num_resources = ARRAY_SIZE(ls1x_dma_resources), 125 .resource = ls1x_dma_resources, 126 }; 127 128 void __init ls1x_dma_set_platdata(struct plat_ls1x_dma *pdata) 129 { 130 ls1x_dma_pdev.dev.platform_data = pdata; 131 } 132 133 /* Synopsys Ethernet GMAC */ 134 static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = { 135 .phy_mask = 0, 136 }; 137 138 static struct stmmac_dma_cfg ls1x_eth_dma_cfg = { 139 .pbl = 1, 140 }; 141 142 int ls1x_eth_mux_init(struct platform_device *pdev, void *priv) 143 { 144 struct plat_stmmacenet_data *plat_dat = NULL; 145 u32 val; 146 147 val = __raw_readl(LS1X_MUX_CTRL1); 148 149 #if defined(CONFIG_LOONGSON1_LS1B) 150 plat_dat = dev_get_platdata(&pdev->dev); 151 if (plat_dat->bus_id) { 152 __raw_writel(__raw_readl(LS1X_MUX_CTRL0) | GMAC1_USE_UART1 | 153 GMAC1_USE_UART0, LS1X_MUX_CTRL0); 154 switch (plat_dat->interface) { 155 case PHY_INTERFACE_MODE_RGMII: 156 val &= ~(GMAC1_USE_TXCLK | GMAC1_USE_PWM23); 157 break; 158 case PHY_INTERFACE_MODE_MII: 159 val |= (GMAC1_USE_TXCLK | GMAC1_USE_PWM23); 160 break; 161 default: 162 pr_err("unsupported mii mode %d\n", 163 plat_dat->interface); 164 return -ENOTSUPP; 165 } 166 val &= ~GMAC1_SHUT; 167 } else { 168 switch (plat_dat->interface) { 169 case PHY_INTERFACE_MODE_RGMII: 170 val &= ~(GMAC0_USE_TXCLK | GMAC0_USE_PWM01); 171 break; 172 case PHY_INTERFACE_MODE_MII: 173 val |= (GMAC0_USE_TXCLK | GMAC0_USE_PWM01); 174 break; 175 default: 176 pr_err("unsupported mii mode %d\n", 177 plat_dat->interface); 178 return -ENOTSUPP; 179 } 180 val &= ~GMAC0_SHUT; 181 } 182 __raw_writel(val, LS1X_MUX_CTRL1); 183 #elif defined(CONFIG_LOONGSON1_LS1C) 184 plat_dat = dev_get_platdata(&pdev->dev); 185 186 val &= ~PHY_INTF_SELI; 187 if (plat_dat->interface == PHY_INTERFACE_MODE_RMII) 188 val |= 0x4 << PHY_INTF_SELI_SHIFT; 189 __raw_writel(val, LS1X_MUX_CTRL1); 190 191 val = __raw_readl(LS1X_MUX_CTRL0); 192 __raw_writel(val & (~GMAC_SHUT), LS1X_MUX_CTRL0); 193 #endif 194 195 return 0; 196 } 197 198 static struct plat_stmmacenet_data ls1x_eth0_pdata = { 199 .bus_id = 0, 200 .phy_addr = -1, 201 #if defined(CONFIG_LOONGSON1_LS1B) 202 .interface = PHY_INTERFACE_MODE_MII, 203 #elif defined(CONFIG_LOONGSON1_LS1C) 204 .interface = PHY_INTERFACE_MODE_RMII, 205 #endif 206 .mdio_bus_data = &ls1x_mdio_bus_data, 207 .dma_cfg = &ls1x_eth_dma_cfg, 208 .has_gmac = 1, 209 .tx_coe = 1, 210 .init = ls1x_eth_mux_init, 211 }; 212 213 static struct resource ls1x_eth0_resources[] = { 214 [0] = { 215 .start = LS1X_GMAC0_BASE, 216 .end = LS1X_GMAC0_BASE + SZ_64K - 1, 217 .flags = IORESOURCE_MEM, 218 }, 219 [1] = { 220 .name = "macirq", 221 .start = LS1X_GMAC0_IRQ, 222 .flags = IORESOURCE_IRQ, 223 }, 224 }; 225 226 struct platform_device ls1x_eth0_pdev = { 227 .name = "stmmaceth", 228 .id = 0, 229 .num_resources = ARRAY_SIZE(ls1x_eth0_resources), 230 .resource = ls1x_eth0_resources, 231 .dev = { 232 .platform_data = &ls1x_eth0_pdata, 233 }, 234 }; 235 236 #ifdef CONFIG_LOONGSON1_LS1B 237 static struct plat_stmmacenet_data ls1x_eth1_pdata = { 238 .bus_id = 1, 239 .phy_addr = -1, 240 .interface = PHY_INTERFACE_MODE_MII, 241 .mdio_bus_data = &ls1x_mdio_bus_data, 242 .dma_cfg = &ls1x_eth_dma_cfg, 243 .has_gmac = 1, 244 .tx_coe = 1, 245 .init = ls1x_eth_mux_init, 246 }; 247 248 static struct resource ls1x_eth1_resources[] = { 249 [0] = { 250 .start = LS1X_GMAC1_BASE, 251 .end = LS1X_GMAC1_BASE + SZ_64K - 1, 252 .flags = IORESOURCE_MEM, 253 }, 254 [1] = { 255 .name = "macirq", 256 .start = LS1X_GMAC1_IRQ, 257 .flags = IORESOURCE_IRQ, 258 }, 259 }; 260 261 struct platform_device ls1x_eth1_pdev = { 262 .name = "stmmaceth", 263 .id = 1, 264 .num_resources = ARRAY_SIZE(ls1x_eth1_resources), 265 .resource = ls1x_eth1_resources, 266 .dev = { 267 .platform_data = &ls1x_eth1_pdata, 268 }, 269 }; 270 #endif /* CONFIG_LOONGSON1_LS1B */ 271 272 /* GPIO */ 273 static struct resource ls1x_gpio0_resources[] = { 274 [0] = { 275 .start = LS1X_GPIO0_BASE, 276 .end = LS1X_GPIO0_BASE + SZ_4 - 1, 277 .flags = IORESOURCE_MEM, 278 }, 279 }; 280 281 struct platform_device ls1x_gpio0_pdev = { 282 .name = "ls1x-gpio", 283 .id = 0, 284 .num_resources = ARRAY_SIZE(ls1x_gpio0_resources), 285 .resource = ls1x_gpio0_resources, 286 }; 287 288 static struct resource ls1x_gpio1_resources[] = { 289 [0] = { 290 .start = LS1X_GPIO1_BASE, 291 .end = LS1X_GPIO1_BASE + SZ_4 - 1, 292 .flags = IORESOURCE_MEM, 293 }, 294 }; 295 296 struct platform_device ls1x_gpio1_pdev = { 297 .name = "ls1x-gpio", 298 .id = 1, 299 .num_resources = ARRAY_SIZE(ls1x_gpio1_resources), 300 .resource = ls1x_gpio1_resources, 301 }; 302 303 /* NAND Flash */ 304 static struct resource ls1x_nand_resources[] = { 305 [0] = { 306 .start = LS1X_NAND_BASE, 307 .end = LS1X_NAND_BASE + SZ_32 - 1, 308 .flags = IORESOURCE_MEM, 309 }, 310 [1] = { 311 /* DMA channel 0 is dedicated to NAND */ 312 .start = LS1X_DMA_CHANNEL0, 313 .end = LS1X_DMA_CHANNEL0, 314 .flags = IORESOURCE_DMA, 315 }, 316 }; 317 318 struct platform_device ls1x_nand_pdev = { 319 .name = "ls1x-nand", 320 .id = -1, 321 .num_resources = ARRAY_SIZE(ls1x_nand_resources), 322 .resource = ls1x_nand_resources, 323 }; 324 325 void __init ls1x_nand_set_platdata(struct plat_ls1x_nand *pdata) 326 { 327 ls1x_nand_pdev.dev.platform_data = pdata; 328 } 329 330 /* USB EHCI */ 331 static u64 ls1x_ehci_dmamask = DMA_BIT_MASK(32); 332 333 static struct resource ls1x_ehci_resources[] = { 334 [0] = { 335 .start = LS1X_EHCI_BASE, 336 .end = LS1X_EHCI_BASE + SZ_32K - 1, 337 .flags = IORESOURCE_MEM, 338 }, 339 [1] = { 340 .start = LS1X_EHCI_IRQ, 341 .flags = IORESOURCE_IRQ, 342 }, 343 }; 344 345 static struct usb_ehci_pdata ls1x_ehci_pdata = { 346 }; 347 348 struct platform_device ls1x_ehci_pdev = { 349 .name = "ehci-platform", 350 .id = -1, 351 .num_resources = ARRAY_SIZE(ls1x_ehci_resources), 352 .resource = ls1x_ehci_resources, 353 .dev = { 354 .dma_mask = &ls1x_ehci_dmamask, 355 .platform_data = &ls1x_ehci_pdata, 356 }, 357 }; 358 359 /* Real Time Clock */ 360 struct platform_device ls1x_rtc_pdev = { 361 .name = "ls1x-rtc", 362 .id = -1, 363 }; 364