1/*
2 *  Ralink RT3662/RT3883 SoC platform device registration
3 *
4 *  Copyright (C) 2011-2012 Gabor Juhos <juhosg@openwrt.org>
5 *
6 *  This program is free software; you can redistribute it and/or modify it
7 *  under the terms of the GNU General Public License version 2 as published
8 *  by the Free Software Foundation.
9 */
10
11#include <linux/kernel.h>
12#include <linux/platform_device.h>
13#include <linux/mtd/mtd.h>
14#include <linux/mtd/physmap.h>
15#include <linux/mtd/partitions.h>
16#include <linux/dma-mapping.h>
17#include <linux/spi/spi.h>
18#include <linux/delay.h>
19#include <linux/err.h>
20#include <linux/clk.h>
21#include <linux/rt2x00_platform.h>
22
23#include <asm/addrspace.h>
24
25#include <asm/mach-ralink/rt3883.h>
26#include <asm/mach-ralink/rt3883_regs.h>
27#include <asm/mach-ralink/rt3883_ehci_platform.h>
28#include <asm/mach-ralink/rt3883_ohci_platform.h>
29#include <asm/mach-ralink/ramips_nand_platform.h>
30#include "devices.h"
31
32#include <ramips_eth_platform.h>
33
34static struct resource rt3883_flash0_resources[] = {
35	{
36		.flags	= IORESOURCE_MEM,
37		.start	= RT3883_BOOT_BASE,
38		.end	= RT3883_BOOT_BASE + RT3883_BOOT_SIZE - 1,
39	},
40};
41
42struct physmap_flash_data rt3883_flash0_data;
43static struct platform_device rt3883_flash0_device = {
44	.name		= "physmap-flash",
45	.resource	= rt3883_flash0_resources,
46	.num_resources	= ARRAY_SIZE(rt3883_flash0_resources),
47	.dev = {
48		.platform_data = &rt3883_flash0_data,
49	},
50};
51
52static struct resource rt3883_flash1_resources[] = {
53	{
54		.flags	= IORESOURCE_MEM,
55		.start	= RT3883_SRAM_BASE,
56		.end	= RT3883_SRAM_BASE + RT3883_SRAM_SIZE - 1,
57	},
58};
59
60struct physmap_flash_data rt3883_flash1_data;
61static struct platform_device rt3883_flash1_device = {
62	.name		= "physmap-flash",
63	.resource	= rt3883_flash1_resources,
64	.num_resources	= ARRAY_SIZE(rt3883_flash1_resources),
65	.dev = {
66		.platform_data = &rt3883_flash1_data,
67	},
68};
69
70static int rt3883_flash_instance __initdata;
71void __init rt3883_register_pflash(unsigned int id)
72{
73	struct platform_device *pdev;
74	struct physmap_flash_data *pdata;
75	void __iomem *fscc_base;
76	u32 t;
77	int reg;
78
79	switch (id) {
80	case 0:
81		pdev = &rt3883_flash0_device;
82		reg = RT3883_FSCC_REG_FLASH_CFG0;
83		break;
84	case 1:
85		pdev = &rt3883_flash1_device;
86		reg = RT3883_FSCC_REG_FLASH_CFG1;
87		break;
88	default:
89		return;
90	}
91
92	pdata = pdev->dev.platform_data;
93
94	fscc_base = ioremap(RT3883_FSCC_BASE, RT3883_FSCC_SIZE);
95	if (!fscc_base)
96		panic("RT3883: ioremap failed for FSCC");
97
98	t = __raw_readl(fscc_base + reg);
99	iounmap(fscc_base);
100
101	t = (t >> RT3883_FLASH_CFG_WIDTH_SHIFT) & RT3883_FLASH_CFG_WIDTH_MASK;
102	switch (t) {
103	case RT3883_FLASH_CFG_WIDTH_8BIT:
104		pdata->width = 1;
105		break;
106	case RT3883_FLASH_CFG_WIDTH_16BIT:
107		pdata->width = 2;
108		break;
109	case RT3883_FLASH_CFG_WIDTH_32BIT:
110		if (id == 1) {
111			pdata->width = 4;
112			break;
113		}
114		/* fallthrough */
115	default:
116		pr_warn("RT3883: flash bank%d: invalid width detected\n", id);
117		return;
118	}
119
120	pdev->id = rt3883_flash_instance;
121
122	platform_device_register(pdev);
123	rt3883_flash_instance++;
124}
125
126static atomic_t rt3883_usb_use_count = ATOMIC_INIT(0);
127
128static void rt3883_usb_host_start(void)
129{
130	u32 t;
131
132	if (atomic_inc_return(&rt3883_usb_use_count) != 1)
133		return;
134
135	t = rt3883_sysc_rr(RT3883_SYSC_REG_USB_PS);
136
137#if 0
138	/* put the HOST controller into reset */
139	t = rt3883_sysc_rr(RT3883_SYSC_REG_RSTCTRL);
140	t |= RT3883_RSTCTRL_UHST;
141	rt3883_sysc_wr(t, RT3883_SYSC_REG_RSTCTRL);
142#endif
143
144	/* enable clock for port0's and port1's phys */
145	t = rt3883_sysc_rr(RT3883_SYSC_REG_CLKCFG1);
146	t = t | RT3883_CLKCFG1_UPHY0_CLK_EN | RT3883_CLKCFG1_UPHY1_CLK_EN;
147	rt3883_sysc_wr(t, RT3883_SYSC_REG_CLKCFG1);
148	mdelay(500);
149
150	/* pull USBHOST and USBDEV out from reset */
151	t = rt3883_sysc_rr(RT3883_SYSC_REG_RSTCTRL);
152	t &= ~(RT3883_RSTCTRL_UHST | RT3883_RSTCTRL_UDEV);
153	rt3883_sysc_wr(t, RT3883_SYSC_REG_RSTCTRL);
154	mdelay(500);
155
156	/* enable host mode */
157	t = rt3883_sysc_rr(RT3883_SYSC_REG_SYSCFG1);
158	t |= RT3883_SYSCFG1_USB0_HOST_MODE;
159	rt3883_sysc_wr(t, RT3883_SYSC_REG_SYSCFG1);
160
161	t = rt3883_sysc_rr(RT3883_SYSC_REG_USB_PS);
162}
163
164static void rt3883_usb_host_stop(void)
165{
166	u32 t;
167
168	if (atomic_dec_return(&rt3883_usb_use_count) != 0)
169		return;
170
171	/* put USBHOST and USBDEV into reset */
172	t = rt3883_sysc_rr(RT3883_SYSC_REG_RSTCTRL);
173	t |= RT3883_RSTCTRL_UHST | RT3883_RSTCTRL_UDEV;
174	rt3883_sysc_wr(t, RT3883_SYSC_REG_RSTCTRL);
175	udelay(10000);
176
177	/* disable clock for port0's and port1's phys*/
178	t = rt3883_sysc_rr(RT3883_SYSC_REG_CLKCFG1);
179	t &= ~(RT3883_CLKCFG1_UPHY0_CLK_EN | RT3883_CLKCFG1_UPHY1_CLK_EN);
180	rt3883_sysc_wr(t, RT3883_SYSC_REG_CLKCFG1);
181	udelay(10000);
182}
183
184static struct rt3883_ehci_platform_data rt3883_ehci_data = {
185	.start_hw	= rt3883_usb_host_start,
186	.stop_hw	= rt3883_usb_host_stop,
187};
188
189static struct resource rt3883_ehci_resources[] = {
190	{
191		.start	= RT3883_EHCI_BASE,
192		.end	= RT3883_EHCI_BASE + PAGE_SIZE - 1,
193		.flags	= IORESOURCE_MEM,
194	}, {
195		.start	= RT3883_INTC_IRQ_UHST,
196		.end	= RT3883_INTC_IRQ_UHST,
197		.flags	= IORESOURCE_IRQ,
198	},
199};
200
201static u64 rt3883_ehci_dmamask = DMA_BIT_MASK(32);
202static struct platform_device rt3883_ehci_device = {
203	.name		= "rt3883-ehci",
204	.id		= -1,
205	.resource	= rt3883_ehci_resources,
206	.num_resources	= ARRAY_SIZE(rt3883_ehci_resources),
207	.dev            = {
208		.dma_mask		= &rt3883_ehci_dmamask,
209		.coherent_dma_mask	= DMA_BIT_MASK(32),
210		.platform_data		= &rt3883_ehci_data,
211	},
212};
213
214static struct resource rt3883_ohci_resources[] = {
215	{
216		.start	= RT3883_OHCI_BASE,
217		.end	= RT3883_OHCI_BASE + PAGE_SIZE - 1,
218		.flags	= IORESOURCE_MEM,
219	}, {
220		.start	= RT3883_INTC_IRQ_UHST,
221		.end	= RT3883_INTC_IRQ_UHST,
222		.flags	= IORESOURCE_IRQ,
223	},
224};
225
226static struct rt3883_ohci_platform_data rt3883_ohci_data = {
227	.start_hw	= rt3883_usb_host_start,
228	.stop_hw	= rt3883_usb_host_stop,
229};
230
231static u64 rt3883_ohci_dmamask = DMA_BIT_MASK(32);
232static struct platform_device rt3883_ohci_device = {
233	.name		= "rt3883-ohci",
234	.id		= -1,
235	.resource	= rt3883_ohci_resources,
236	.num_resources	= ARRAY_SIZE(rt3883_ohci_resources),
237	.dev            = {
238		.dma_mask		= &rt3883_ohci_dmamask,
239		.coherent_dma_mask	= DMA_BIT_MASK(32),
240		.platform_data		= &rt3883_ohci_data,
241	},
242};
243
244void __init rt3883_register_usbhost(void)
245{
246	platform_device_register(&rt3883_ehci_device);
247	platform_device_register(&rt3883_ohci_device);
248}
249
250static void rt3883_fe_reset(void)
251{
252	u32 t;
253
254	t = rt3883_sysc_rr(RT3883_SYSC_REG_RSTCTRL);
255	t |= RT3883_RSTCTRL_FE;
256	rt3883_sysc_wr(t , RT3883_SYSC_REG_RSTCTRL);
257
258	t &= ~RT3883_RSTCTRL_FE;
259	rt3883_sysc_wr(t, RT3883_SYSC_REG_RSTCTRL);
260}
261
262static struct resource rt3883_eth_resources[] = {
263	{
264		.start	= RT3883_FE_BASE,
265		.end	= RT3883_FE_BASE + PAGE_SIZE - 1,
266		.flags	= IORESOURCE_MEM,
267	}, {
268		.start	= RT3883_CPU_IRQ_FE,
269		.end	= RT3883_CPU_IRQ_FE,
270		.flags	= IORESOURCE_IRQ,
271	},
272};
273
274struct ramips_eth_platform_data rt3883_eth_data = {
275	.mac		= { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 },
276	.reset_fe	= rt3883_fe_reset,
277	.min_pkt_len	= 64,
278};
279
280static struct platform_device rt3883_eth_device = {
281	.name		= "ramips_eth",
282	.resource	= rt3883_eth_resources,
283	.num_resources	= ARRAY_SIZE(rt3883_eth_resources),
284	.dev = {
285		.platform_data = &rt3883_eth_data,
286	}
287};
288
289void __init rt3883_register_ethernet(void)
290{
291	struct clk *clk;
292
293	clk = clk_get(NULL, "sys");
294	if (IS_ERR(clk))
295		panic("unable to get SYS clock, err=%ld", PTR_ERR(clk));
296
297	rt3883_eth_data.sys_freq = clk_get_rate(clk);
298
299	platform_device_register(&rt3883_eth_device);
300}
301
302static struct resource rt3883_wlan_resources[] = {
303	{
304		.start	= RT3883_WLAN_BASE,
305		.end	= RT3883_WLAN_BASE + 0x3FFFF,
306		.flags	= IORESOURCE_MEM,
307	}, {
308		.start	= RT3883_CPU_IRQ_WLAN,
309		.end	= RT3883_CPU_IRQ_WLAN,
310		.flags	= IORESOURCE_IRQ,
311	},
312};
313
314struct rt2x00_platform_data rt3883_wlan_data;
315static struct platform_device rt3883_wlan_device = {
316	.name		= "rt2800_wmac",
317	.resource	= rt3883_wlan_resources,
318	.num_resources	= ARRAY_SIZE(rt3883_wlan_resources),
319	.dev = {
320		.platform_data = &rt3883_wlan_data,
321	}
322};
323
324void __init rt3883_register_wlan(void)
325{
326	rt3883_wlan_data.eeprom_file_name = "RT3883.eeprom",
327	platform_device_register(&rt3883_wlan_device);
328}
329
330static struct resource rt3883_wdt_resources[] = {
331	{
332		.start	= RT3883_TIMER_BASE,
333		.end	= RT3883_TIMER_BASE + RT3883_TIMER_SIZE - 1,
334		.flags	= IORESOURCE_MEM,
335	},
336};
337
338static struct platform_device rt3883_wdt_device = {
339	.name		= "ramips-wdt",
340	.id		= -1,
341	.resource	= rt3883_wdt_resources,
342	.num_resources	= ARRAY_SIZE(rt3883_wdt_resources),
343};
344
345void __init rt3883_register_wdt(bool enable_reset)
346{
347	if (enable_reset) {
348		u32 t;
349
350		/* enable WDT reset output on GPIO 2 */
351		t = rt3883_sysc_rr(RT3883_SYSC_REG_SYSCFG1);
352		t |= RT3883_SYSCFG1_GPIO2_AS_WDT_OUT;
353		rt3883_sysc_wr(t, RT3883_SYSC_REG_SYSCFG1);
354	}
355
356	platform_device_register(&rt3883_wdt_device);
357}
358
359static struct resource rt3883_nand_resources[] = {
360	{
361		.flags	= IORESOURCE_MEM,
362		.start	= RT3883_NANDC_BASE,
363		.end	= RT3883_NANDC_BASE + RT3883_NANDC_SIZE - 1,
364	},
365};
366
367struct ramips_nand_platform_data rt3883_nand_data;
368static struct platform_device rt3883_nand_device = {
369	.name		= RAMIPS_NAND_DRIVER_NAME,
370	.id		= -1,
371	.resource	= rt3883_nand_resources,
372	.num_resources	= ARRAY_SIZE(rt3883_nand_resources),
373	.dev	= {
374		.platform_data = &rt3883_nand_data,
375	},
376};
377
378void __init rt3883_register_nand(void)
379{
380	platform_device_register(&rt3883_nand_device);
381}
382
383static struct resource rt3883_spi_resources[] = {
384	{
385		.flags	= IORESOURCE_MEM,
386		.start	= RT3883_SPI_BASE,
387		.end	= RT3883_SPI_BASE + RT3883_SPI_SIZE - 1,
388	},
389};
390
391static struct platform_device rt3883_spi_device = {
392	.name		= "ramips-spi",
393	.id		= 0,
394	.resource	= rt3883_spi_resources,
395	.num_resources	= ARRAY_SIZE(rt3883_spi_resources),
396};
397
398void __init rt3883_register_spi(struct spi_board_info *info, int n)
399{
400	spi_register_board_info(info, n);
401	platform_device_register(&rt3883_spi_device);
402}
403
404