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