OSDN Git Service

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