~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/mips/loongson32/common/platform.c

Version: ~ [ linux-5.9 ] ~ [ linux-5.8.14 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.70 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.150 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.200 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.238 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.238 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 /* DMA */
 85 static struct resource ls1x_dma_resources[] = {
 86         [0] = {
 87                 .start = LS1X_DMAC_BASE,
 88                 .end = LS1X_DMAC_BASE + SZ_4 - 1,
 89                 .flags = IORESOURCE_MEM,
 90         },
 91         [1] = {
 92                 .start = LS1X_DMA0_IRQ,
 93                 .end = LS1X_DMA0_IRQ,
 94                 .flags = IORESOURCE_IRQ,
 95         },
 96         [2] = {
 97                 .start = LS1X_DMA1_IRQ,
 98                 .end = LS1X_DMA1_IRQ,
 99                 .flags = IORESOURCE_IRQ,
100         },
101         [3] = {
102                 .start = LS1X_DMA2_IRQ,
103                 .end = LS1X_DMA2_IRQ,
104                 .flags = IORESOURCE_IRQ,
105         },
106 };
107 
108 struct platform_device ls1x_dma_pdev = {
109         .name           = "ls1x-dma",
110         .id             = -1,
111         .num_resources  = ARRAY_SIZE(ls1x_dma_resources),
112         .resource       = ls1x_dma_resources,
113 };
114 
115 void __init ls1x_dma_set_platdata(struct plat_ls1x_dma *pdata)
116 {
117         ls1x_dma_pdev.dev.platform_data = pdata;
118 }
119 
120 /* Synopsys Ethernet GMAC */
121 static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = {
122         .phy_mask       = 0,
123 };
124 
125 static struct stmmac_dma_cfg ls1x_eth_dma_cfg = {
126         .pbl            = 1,
127 };
128 
129 int ls1x_eth_mux_init(struct platform_device *pdev, void *priv)
130 {
131         struct plat_stmmacenet_data *plat_dat = NULL;
132         u32 val;
133 
134         val = __raw_readl(LS1X_MUX_CTRL1);
135 
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);
144                         break;
145                 case PHY_INTERFACE_MODE_MII:
146                         val |= (GMAC1_USE_TXCLK | GMAC1_USE_PWM23);
147                         break;
148                 default:
149                         pr_err("unsupported mii mode %d\n",
150                                plat_dat->interface);
151                         return -ENOTSUPP;
152                 }
153                 val &= ~GMAC1_SHUT;
154         } else {
155                 switch (plat_dat->interface) {
156                 case PHY_INTERFACE_MODE_RGMII:
157                         val &= ~(GMAC0_USE_TXCLK | GMAC0_USE_PWM01);
158                         break;
159                 case PHY_INTERFACE_MODE_MII:
160                         val |= (GMAC0_USE_TXCLK | GMAC0_USE_PWM01);
161                         break;
162                 default:
163                         pr_err("unsupported mii mode %d\n",
164                                plat_dat->interface);
165                         return -ENOTSUPP;
166                 }
167                 val &= ~GMAC0_SHUT;
168         }
169         __raw_writel(val, LS1X_MUX_CTRL1);
170 #elif defined(CONFIG_LOONGSON1_LS1C)
171         plat_dat = dev_get_platdata(&pdev->dev);
172 
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);
177 
178         val = __raw_readl(LS1X_MUX_CTRL0);
179         __raw_writel(val & (~GMAC_SHUT), LS1X_MUX_CTRL0);
180 #endif
181 
182         return 0;
183 }
184 
185 static struct plat_stmmacenet_data ls1x_eth0_pdata = {
186         .bus_id                 = 0,
187         .phy_addr               = -1,
188 #if defined(CONFIG_LOONGSON1_LS1B)
189         .interface              = PHY_INTERFACE_MODE_MII,
190 #elif defined(CONFIG_LOONGSON1_LS1C)
191         .interface              = PHY_INTERFACE_MODE_RMII,
192 #endif
193         .mdio_bus_data          = &ls1x_mdio_bus_data,
194         .dma_cfg                = &ls1x_eth_dma_cfg,
195         .has_gmac               = 1,
196         .tx_coe                 = 1,
197         .rx_queues_to_use       = 1,
198         .tx_queues_to_use       = 1,
199         .init                   = ls1x_eth_mux_init,
200 };
201 
202 static struct resource ls1x_eth0_resources[] = {
203         [0] = {
204                 .start  = LS1X_GMAC0_BASE,
205                 .end    = LS1X_GMAC0_BASE + SZ_64K - 1,
206                 .flags  = IORESOURCE_MEM,
207         },
208         [1] = {
209                 .name   = "macirq",
210                 .start  = LS1X_GMAC0_IRQ,
211                 .flags  = IORESOURCE_IRQ,
212         },
213 };
214 
215 struct platform_device ls1x_eth0_pdev = {
216         .name           = "stmmaceth",
217         .id             = 0,
218         .num_resources  = ARRAY_SIZE(ls1x_eth0_resources),
219         .resource       = ls1x_eth0_resources,
220         .dev            = {
221                 .platform_data = &ls1x_eth0_pdata,
222         },
223 };
224 
225 #ifdef CONFIG_LOONGSON1_LS1B
226 static struct plat_stmmacenet_data ls1x_eth1_pdata = {
227         .bus_id                 = 1,
228         .phy_addr               = -1,
229         .interface              = PHY_INTERFACE_MODE_MII,
230         .mdio_bus_data          = &ls1x_mdio_bus_data,
231         .dma_cfg                = &ls1x_eth_dma_cfg,
232         .has_gmac               = 1,
233         .tx_coe                 = 1,
234         .rx_queues_to_use       = 1,
235         .tx_queues_to_use       = 1,
236         .init                   = ls1x_eth_mux_init,
237 };
238 
239 static struct resource ls1x_eth1_resources[] = {
240         [0] = {
241                 .start  = LS1X_GMAC1_BASE,
242                 .end    = LS1X_GMAC1_BASE + SZ_64K - 1,
243                 .flags  = IORESOURCE_MEM,
244         },
245         [1] = {
246                 .name   = "macirq",
247                 .start  = LS1X_GMAC1_IRQ,
248                 .flags  = IORESOURCE_IRQ,
249         },
250 };
251 
252 struct platform_device ls1x_eth1_pdev = {
253         .name           = "stmmaceth",
254         .id             = 1,
255         .num_resources  = ARRAY_SIZE(ls1x_eth1_resources),
256         .resource       = ls1x_eth1_resources,
257         .dev            = {
258                 .platform_data = &ls1x_eth1_pdata,
259         },
260 };
261 #endif  /* CONFIG_LOONGSON1_LS1B */
262 
263 /* GPIO */
264 static struct resource ls1x_gpio0_resources[] = {
265         [0] = {
266                 .start  = LS1X_GPIO0_BASE,
267                 .end    = LS1X_GPIO0_BASE + SZ_4 - 1,
268                 .flags  = IORESOURCE_MEM,
269         },
270 };
271 
272 struct platform_device ls1x_gpio0_pdev = {
273         .name           = "ls1x-gpio",
274         .id             = 0,
275         .num_resources  = ARRAY_SIZE(ls1x_gpio0_resources),
276         .resource       = ls1x_gpio0_resources,
277 };
278 
279 static struct resource ls1x_gpio1_resources[] = {
280         [0] = {
281                 .start  = LS1X_GPIO1_BASE,
282                 .end    = LS1X_GPIO1_BASE + SZ_4 - 1,
283                 .flags  = IORESOURCE_MEM,
284         },
285 };
286 
287 struct platform_device ls1x_gpio1_pdev = {
288         .name           = "ls1x-gpio",
289         .id             = 1,
290         .num_resources  = ARRAY_SIZE(ls1x_gpio1_resources),
291         .resource       = ls1x_gpio1_resources,
292 };
293 
294 /* NAND Flash */
295 static struct resource ls1x_nand_resources[] = {
296         [0] = {
297                 .start  = LS1X_NAND_BASE,
298                 .end    = LS1X_NAND_BASE + SZ_32 - 1,
299                 .flags  = IORESOURCE_MEM,
300         },
301         [1] = {
302                 /* DMA channel 0 is dedicated to NAND */
303                 .start  = LS1X_DMA_CHANNEL0,
304                 .end    = LS1X_DMA_CHANNEL0,
305                 .flags  = IORESOURCE_DMA,
306         },
307 };
308 
309 struct platform_device ls1x_nand_pdev = {
310         .name           = "ls1x-nand",
311         .id             = -1,
312         .num_resources  = ARRAY_SIZE(ls1x_nand_resources),
313         .resource       = ls1x_nand_resources,
314 };
315 
316 void __init ls1x_nand_set_platdata(struct plat_ls1x_nand *pdata)
317 {
318         ls1x_nand_pdev.dev.platform_data = pdata;
319 }
320 
321 /* USB EHCI */
322 static u64 ls1x_ehci_dmamask = DMA_BIT_MASK(32);
323 
324 static struct resource ls1x_ehci_resources[] = {
325         [0] = {
326                 .start  = LS1X_EHCI_BASE,
327                 .end    = LS1X_EHCI_BASE + SZ_32K - 1,
328                 .flags  = IORESOURCE_MEM,
329         },
330         [1] = {
331                 .start  = LS1X_EHCI_IRQ,
332                 .flags  = IORESOURCE_IRQ,
333         },
334 };
335 
336 static struct usb_ehci_pdata ls1x_ehci_pdata = {
337 };
338 
339 struct platform_device ls1x_ehci_pdev = {
340         .name           = "ehci-platform",
341         .id             = -1,
342         .num_resources  = ARRAY_SIZE(ls1x_ehci_resources),
343         .resource       = ls1x_ehci_resources,
344         .dev            = {
345                 .dma_mask = &ls1x_ehci_dmamask,
346                 .platform_data = &ls1x_ehci_pdata,
347         },
348 };
349 
350 /* Real Time Clock */
351 void __init ls1x_rtc_set_extclk(struct platform_device *pdev)
352 {
353         u32 val = __raw_readl(LS1X_RTC_CTRL);
354 
355         if (!(val & RTC_EXTCLK_OK))
356                 __raw_writel(val | RTC_EXTCLK_EN, LS1X_RTC_CTRL);
357 }
358 
359 struct platform_device ls1x_rtc_pdev = {
360         .name           = "ls1x-rtc",
361         .id             = -1,
362 };
363 
364 /* Watchdog */
365 static struct resource ls1x_wdt_resources[] = {
366         {
367                 .start  = LS1X_WDT_BASE,
368                 .end    = LS1X_WDT_BASE + SZ_16 - 1,
369                 .flags  = IORESOURCE_MEM,
370         },
371 };
372 
373 struct platform_device ls1x_wdt_pdev = {
374         .name           = "ls1x-wdt",
375         .id             = -1,
376         .num_resources  = ARRAY_SIZE(ls1x_wdt_resources),
377         .resource       = ls1x_wdt_resources,
378 };
379 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp