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