2 * Copyright (c) 2011-2016 Zhang, Keguang <keguang.zhang@gmail.com>
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.
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>
21 #include <loongson1.h>
26 /* 8250/16550 compatible UART */
27 #define LS1X_UART(_id) \
29 .mapbase = LS1X_UART ## _id ## _BASE, \
30 .irq = LS1X_UART ## _id ## _IRQ, \
32 .flags = UPF_IOREMAP | UPF_FIXED_TYPE, \
33 .type = PORT_16550A, \
36 static struct plat_serial8250_port ls1x_serial8250_pdata
[] = {
44 struct platform_device ls1x_uart_pdev
= {
46 .id
= PLAT8250_DEV_PLATFORM
,
48 .platform_data
= ls1x_serial8250_pdata
,
52 void __init
ls1x_serial_set_uartclk(struct platform_device
*pdev
)
55 struct plat_serial8250_port
*p
;
57 clk
= clk_get(&pdev
->dev
, pdev
->name
);
59 pr_err("unable to get %s clock, err=%ld",
60 pdev
->name
, PTR_ERR(clk
));
63 clk_prepare_enable(clk
);
65 for (p
= pdev
->dev
.platform_data
; p
->flags
!= 0; ++p
)
66 p
->uartclk
= clk_get_rate(clk
);
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,
77 struct platform_device ls1x_cpufreq_pdev
= {
78 .name
= "ls1x-cpufreq",
80 .platform_data
= &ls1x_cpufreq_pdata
,
85 static struct resource ls1x_dma_resources
[] = {
87 .start
= LS1X_DMAC_BASE
,
88 .end
= LS1X_DMAC_BASE
+ SZ_4
- 1,
89 .flags
= IORESOURCE_MEM
,
92 .start
= LS1X_DMA0_IRQ
,
94 .flags
= IORESOURCE_IRQ
,
97 .start
= LS1X_DMA1_IRQ
,
99 .flags
= IORESOURCE_IRQ
,
102 .start
= LS1X_DMA2_IRQ
,
103 .end
= LS1X_DMA2_IRQ
,
104 .flags
= IORESOURCE_IRQ
,
108 struct platform_device ls1x_dma_pdev
= {
111 .num_resources
= ARRAY_SIZE(ls1x_dma_resources
),
112 .resource
= ls1x_dma_resources
,
115 void __init
ls1x_dma_set_platdata(struct plat_ls1x_dma
*pdata
)
117 ls1x_dma_pdev
.dev
.platform_data
= pdata
;
120 /* Synopsys Ethernet GMAC */
121 static struct stmmac_mdio_bus_data ls1x_mdio_bus_data
= {
125 static struct stmmac_dma_cfg ls1x_eth_dma_cfg
= {
129 int ls1x_eth_mux_init(struct platform_device
*pdev
, void *priv
)
131 struct plat_stmmacenet_data
*plat_dat
= NULL
;
134 val
= __raw_readl(LS1X_MUX_CTRL1
);
136 #if defined(CONFIG_LOONGSON1_LS1B)
137 plat_dat
= dev_get_platdata(&pdev
->dev
);
138 if (plat_dat
->bus_id
) {
139 __raw_writel(__raw_readl(LS1X_MUX_CTRL0
) | GMAC1_USE_UART1
|
140 GMAC1_USE_UART0
, LS1X_MUX_CTRL0
);
141 switch (plat_dat
->interface
) {
142 case PHY_INTERFACE_MODE_RGMII
:
143 val
&= ~(GMAC1_USE_TXCLK
| GMAC1_USE_PWM23
);
145 case PHY_INTERFACE_MODE_MII
:
146 val
|= (GMAC1_USE_TXCLK
| GMAC1_USE_PWM23
);
149 pr_err("unsupported mii mode %d\n",
150 plat_dat
->interface
);
155 switch (plat_dat
->interface
) {
156 case PHY_INTERFACE_MODE_RGMII
:
157 val
&= ~(GMAC0_USE_TXCLK
| GMAC0_USE_PWM01
);
159 case PHY_INTERFACE_MODE_MII
:
160 val
|= (GMAC0_USE_TXCLK
| GMAC0_USE_PWM01
);
163 pr_err("unsupported mii mode %d\n",
164 plat_dat
->interface
);
169 __raw_writel(val
, LS1X_MUX_CTRL1
);
170 #elif defined(CONFIG_LOONGSON1_LS1C)
171 plat_dat
= dev_get_platdata(&pdev
->dev
);
173 val
&= ~PHY_INTF_SELI
;
174 if (plat_dat
->interface
== PHY_INTERFACE_MODE_RMII
)
175 val
|= 0x4 << PHY_INTF_SELI_SHIFT
;
176 __raw_writel(val
, LS1X_MUX_CTRL1
);
178 val
= __raw_readl(LS1X_MUX_CTRL0
);
179 __raw_writel(val
& (~GMAC_SHUT
), LS1X_MUX_CTRL0
);
185 static struct plat_stmmacenet_data ls1x_eth0_pdata
= {
188 #if defined(CONFIG_LOONGSON1_LS1B)
189 .interface
= PHY_INTERFACE_MODE_MII
,
190 #elif defined(CONFIG_LOONGSON1_LS1C)
191 .interface
= PHY_INTERFACE_MODE_RMII
,
193 .mdio_bus_data
= &ls1x_mdio_bus_data
,
194 .dma_cfg
= &ls1x_eth_dma_cfg
,
197 .rx_queues_to_use
= 1,
198 .tx_queues_to_use
= 1,
199 .init
= ls1x_eth_mux_init
,
202 static struct resource ls1x_eth0_resources
[] = {
204 .start
= LS1X_GMAC0_BASE
,
205 .end
= LS1X_GMAC0_BASE
+ SZ_64K
- 1,
206 .flags
= IORESOURCE_MEM
,
210 .start
= LS1X_GMAC0_IRQ
,
211 .flags
= IORESOURCE_IRQ
,
215 struct platform_device ls1x_eth0_pdev
= {
218 .num_resources
= ARRAY_SIZE(ls1x_eth0_resources
),
219 .resource
= ls1x_eth0_resources
,
221 .platform_data
= &ls1x_eth0_pdata
,
225 #ifdef CONFIG_LOONGSON1_LS1B
226 static struct plat_stmmacenet_data ls1x_eth1_pdata
= {
229 .interface
= PHY_INTERFACE_MODE_MII
,
230 .mdio_bus_data
= &ls1x_mdio_bus_data
,
231 .dma_cfg
= &ls1x_eth_dma_cfg
,
234 .rx_queues_to_use
= 1,
235 .tx_queues_to_use
= 1,
236 .init
= ls1x_eth_mux_init
,
239 static struct resource ls1x_eth1_resources
[] = {
241 .start
= LS1X_GMAC1_BASE
,
242 .end
= LS1X_GMAC1_BASE
+ SZ_64K
- 1,
243 .flags
= IORESOURCE_MEM
,
247 .start
= LS1X_GMAC1_IRQ
,
248 .flags
= IORESOURCE_IRQ
,
252 struct platform_device ls1x_eth1_pdev
= {
255 .num_resources
= ARRAY_SIZE(ls1x_eth1_resources
),
256 .resource
= ls1x_eth1_resources
,
258 .platform_data
= &ls1x_eth1_pdata
,
261 #endif /* CONFIG_LOONGSON1_LS1B */
264 static struct resource ls1x_gpio0_resources
[] = {
266 .start
= LS1X_GPIO0_BASE
,
267 .end
= LS1X_GPIO0_BASE
+ SZ_4
- 1,
268 .flags
= IORESOURCE_MEM
,
272 struct platform_device ls1x_gpio0_pdev
= {
275 .num_resources
= ARRAY_SIZE(ls1x_gpio0_resources
),
276 .resource
= ls1x_gpio0_resources
,
279 static struct resource ls1x_gpio1_resources
[] = {
281 .start
= LS1X_GPIO1_BASE
,
282 .end
= LS1X_GPIO1_BASE
+ SZ_4
- 1,
283 .flags
= IORESOURCE_MEM
,
287 struct platform_device ls1x_gpio1_pdev
= {
290 .num_resources
= ARRAY_SIZE(ls1x_gpio1_resources
),
291 .resource
= ls1x_gpio1_resources
,
295 static struct resource ls1x_nand_resources
[] = {
297 .start
= LS1X_NAND_BASE
,
298 .end
= LS1X_NAND_BASE
+ SZ_32
- 1,
299 .flags
= IORESOURCE_MEM
,
302 /* DMA channel 0 is dedicated to NAND */
303 .start
= LS1X_DMA_CHANNEL0
,
304 .end
= LS1X_DMA_CHANNEL0
,
305 .flags
= IORESOURCE_DMA
,
309 struct platform_device ls1x_nand_pdev
= {
312 .num_resources
= ARRAY_SIZE(ls1x_nand_resources
),
313 .resource
= ls1x_nand_resources
,
316 void __init
ls1x_nand_set_platdata(struct plat_ls1x_nand
*pdata
)
318 ls1x_nand_pdev
.dev
.platform_data
= pdata
;
322 static u64 ls1x_ehci_dmamask
= DMA_BIT_MASK(32);
324 static struct resource ls1x_ehci_resources
[] = {
326 .start
= LS1X_EHCI_BASE
,
327 .end
= LS1X_EHCI_BASE
+ SZ_32K
- 1,
328 .flags
= IORESOURCE_MEM
,
331 .start
= LS1X_EHCI_IRQ
,
332 .flags
= IORESOURCE_IRQ
,
336 static struct usb_ehci_pdata ls1x_ehci_pdata
= {
339 struct platform_device ls1x_ehci_pdev
= {
340 .name
= "ehci-platform",
342 .num_resources
= ARRAY_SIZE(ls1x_ehci_resources
),
343 .resource
= ls1x_ehci_resources
,
345 .dma_mask
= &ls1x_ehci_dmamask
,
346 .platform_data
= &ls1x_ehci_pdata
,
350 /* Real Time Clock */
351 void __init
ls1x_rtc_set_extclk(struct platform_device
*pdev
)
353 u32 val
= __raw_readl(LS1X_RTC_CTRL
);
355 if (!(val
& RTC_EXTCLK_OK
))
356 __raw_writel(val
| RTC_EXTCLK_EN
, LS1X_RTC_CTRL
);
359 struct platform_device ls1x_rtc_pdev
= {
365 static struct resource ls1x_wdt_resources
[] = {
367 .start
= LS1X_WDT_BASE
,
368 .end
= LS1X_WDT_BASE
+ SZ_16
- 1,
369 .flags
= IORESOURCE_MEM
,
373 struct platform_device ls1x_wdt_pdev
= {
376 .num_resources
= ARRAY_SIZE(ls1x_wdt_resources
),
377 .resource
= ls1x_wdt_resources
,