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