1/*
2 * mach-davinci/devices.c
3 *
4 * DaVinci platform device setup/initialization
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#include <linux/init.h>
13#include <linux/platform_device.h>
14#include <linux/dma-mapping.h>
15#include <linux/io.h>
16#include <linux/reboot.h>
17
18#include <mach/hardware.h>
19#include <linux/platform_data/i2c-davinci.h>
20#include <mach/irqs.h>
21#include <mach/cputype.h>
22#include <mach/mux.h>
23#include <linux/platform_data/mmc-davinci.h>
24#include <mach/time.h>
25#include <linux/platform_data/edma.h>
26
27
28#include "davinci.h"
29#include "clock.h"
30
31#define DAVINCI_I2C_BASE	     0x01C21000
32#define DAVINCI_ATA_BASE	     0x01C66000
33#define DAVINCI_MMCSD0_BASE	     0x01E10000
34#define DM355_MMCSD0_BASE	     0x01E11000
35#define DM355_MMCSD1_BASE	     0x01E00000
36#define DM365_MMCSD0_BASE	     0x01D11000
37#define DM365_MMCSD1_BASE	     0x01D00000
38
39#define DAVINCI_DMA_MMCRXEVT	26
40#define DAVINCI_DMA_MMCTXEVT	27
41
42void __iomem  *davinci_sysmod_base;
43
44void davinci_map_sysmod(void)
45{
46	davinci_sysmod_base = ioremap_nocache(DAVINCI_SYSTEM_MODULE_BASE,
47					      0x800);
48	/*
49	 * Throw a bug since a lot of board initialization code depends
50	 * on system module availability. ioremap() failing this early
51	 * need careful looking into anyway.
52	 */
53	BUG_ON(!davinci_sysmod_base);
54}
55
56static struct resource i2c_resources[] = {
57	{
58		.start		= DAVINCI_I2C_BASE,
59		.end		= DAVINCI_I2C_BASE + 0x40,
60		.flags		= IORESOURCE_MEM,
61	},
62	{
63		.start		= IRQ_I2C,
64		.flags		= IORESOURCE_IRQ,
65	},
66};
67
68static struct platform_device davinci_i2c_device = {
69	.name           = "i2c_davinci",
70	.id             = 1,
71	.num_resources	= ARRAY_SIZE(i2c_resources),
72	.resource	= i2c_resources,
73};
74
75void __init davinci_init_i2c(struct davinci_i2c_platform_data *pdata)
76{
77	if (cpu_is_davinci_dm644x())
78		davinci_cfg_reg(DM644X_I2C);
79
80	davinci_i2c_device.dev.platform_data = pdata;
81	(void) platform_device_register(&davinci_i2c_device);
82}
83
84static struct resource ide_resources[] = {
85	{
86		.start		= DAVINCI_ATA_BASE,
87		.end		= DAVINCI_ATA_BASE + 0x7ff,
88		.flags		= IORESOURCE_MEM,
89	},
90	{
91		.start		= IRQ_IDE,
92		.end		= IRQ_IDE,
93		.flags		= IORESOURCE_IRQ,
94	},
95};
96
97static u64 ide_dma_mask = DMA_BIT_MASK(32);
98
99static struct platform_device ide_device = {
100	.name           = "palm_bk3710",
101	.id             = -1,
102	.resource       = ide_resources,
103	.num_resources  = ARRAY_SIZE(ide_resources),
104	.dev = {
105		.dma_mask		= &ide_dma_mask,
106		.coherent_dma_mask      = DMA_BIT_MASK(32),
107	},
108};
109
110void __init davinci_init_ide(void)
111{
112	if (cpu_is_davinci_dm644x()) {
113		davinci_cfg_reg(DM644X_HPIEN_DISABLE);
114		davinci_cfg_reg(DM644X_ATAEN);
115		davinci_cfg_reg(DM644X_HDIREN);
116	} else if (cpu_is_davinci_dm646x()) {
117		/* IRQ_DM646X_IDE is the same as IRQ_IDE */
118		davinci_cfg_reg(DM646X_ATAEN);
119	} else {
120		WARN_ON(1);
121		return;
122	}
123
124	platform_device_register(&ide_device);
125}
126
127#if IS_ENABLED(CONFIG_MMC_DAVINCI)
128
129static u64 mmcsd0_dma_mask = DMA_BIT_MASK(32);
130
131static struct resource mmcsd0_resources[] = {
132	{
133		/* different on dm355 */
134		.start = DAVINCI_MMCSD0_BASE,
135		.end   = DAVINCI_MMCSD0_BASE + SZ_4K - 1,
136		.flags = IORESOURCE_MEM,
137	},
138	/* IRQs:  MMC/SD, then SDIO */
139	{
140		.start = IRQ_MMCINT,
141		.flags = IORESOURCE_IRQ,
142	}, {
143		/* different on dm355 */
144		.start = IRQ_SDIOINT,
145		.flags = IORESOURCE_IRQ,
146	},
147	/* DMA channels: RX, then TX */
148	{
149		.start = EDMA_CTLR_CHAN(0, DAVINCI_DMA_MMCRXEVT),
150		.flags = IORESOURCE_DMA,
151	}, {
152		.start = EDMA_CTLR_CHAN(0, DAVINCI_DMA_MMCTXEVT),
153		.flags = IORESOURCE_DMA,
154	},
155};
156
157static struct platform_device davinci_mmcsd0_device = {
158	.name = "dm6441-mmc",
159	.id = 0,
160	.dev = {
161		.dma_mask = &mmcsd0_dma_mask,
162		.coherent_dma_mask = DMA_BIT_MASK(32),
163	},
164	.num_resources = ARRAY_SIZE(mmcsd0_resources),
165	.resource = mmcsd0_resources,
166};
167
168static u64 mmcsd1_dma_mask = DMA_BIT_MASK(32);
169
170static struct resource mmcsd1_resources[] = {
171	{
172		.start = DM355_MMCSD1_BASE,
173		.end   = DM355_MMCSD1_BASE + SZ_4K - 1,
174		.flags = IORESOURCE_MEM,
175	},
176	/* IRQs:  MMC/SD, then SDIO */
177	{
178		.start = IRQ_DM355_MMCINT1,
179		.flags = IORESOURCE_IRQ,
180	}, {
181		.start = IRQ_DM355_SDIOINT1,
182		.flags = IORESOURCE_IRQ,
183	},
184	/* DMA channels: RX, then TX */
185	{
186		.start = EDMA_CTLR_CHAN(0, 30),	/* rx */
187		.flags = IORESOURCE_DMA,
188	}, {
189		.start = EDMA_CTLR_CHAN(0, 31),	/* tx */
190		.flags = IORESOURCE_DMA,
191	},
192};
193
194static struct platform_device davinci_mmcsd1_device = {
195	.name = "dm6441-mmc",
196	.id = 1,
197	.dev = {
198		.dma_mask = &mmcsd1_dma_mask,
199		.coherent_dma_mask = DMA_BIT_MASK(32),
200	},
201	.num_resources = ARRAY_SIZE(mmcsd1_resources),
202	.resource = mmcsd1_resources,
203};
204
205
206void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config)
207{
208	struct platform_device	*pdev = NULL;
209
210	if (WARN_ON(cpu_is_davinci_dm646x()))
211		return;
212
213	/* REVISIT: update PINMUX, ARM_IRQMUX, and EDMA_EVTMUX here too;
214	 * for example if MMCSD1 is used for SDIO, maybe DAT2 is unused.
215	 *
216	 * FIXME dm6441 (no MMC/SD), dm357 (one), and dm335 (two) are
217	 * not handled right here ...
218	 */
219	switch (module) {
220	case 1:
221		if (cpu_is_davinci_dm355()) {
222			/* REVISIT we may not need all these pins if e.g. this
223			 * is a hard-wired SDIO device...
224			 */
225			davinci_cfg_reg(DM355_SD1_CMD);
226			davinci_cfg_reg(DM355_SD1_CLK);
227			davinci_cfg_reg(DM355_SD1_DATA0);
228			davinci_cfg_reg(DM355_SD1_DATA1);
229			davinci_cfg_reg(DM355_SD1_DATA2);
230			davinci_cfg_reg(DM355_SD1_DATA3);
231		} else if (cpu_is_davinci_dm365()) {
232			/* Configure pull down control */
233			unsigned v;
234
235			v = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_PUPDCTL1));
236			__raw_writel(v & ~0xfc0,
237					DAVINCI_SYSMOD_VIRT(SYSMOD_PUPDCTL1));
238
239			mmcsd1_resources[0].start = DM365_MMCSD1_BASE;
240			mmcsd1_resources[0].end = DM365_MMCSD1_BASE +
241							SZ_4K - 1;
242			mmcsd1_resources[2].start = IRQ_DM365_SDIOINT1;
243			davinci_mmcsd1_device.name = "da830-mmc";
244		} else
245			break;
246
247		pdev = &davinci_mmcsd1_device;
248		break;
249	case 0:
250		if (cpu_is_davinci_dm355()) {
251			mmcsd0_resources[0].start = DM355_MMCSD0_BASE;
252			mmcsd0_resources[0].end = DM355_MMCSD0_BASE + SZ_4K - 1;
253			mmcsd0_resources[2].start = IRQ_DM355_SDIOINT0;
254
255			/* expose all 6 MMC0 signals:  CLK, CMD, DATA[0..3] */
256			davinci_cfg_reg(DM355_MMCSD0);
257
258			/* enable RX EDMA */
259			davinci_cfg_reg(DM355_EVT26_MMC0_RX);
260		} else if (cpu_is_davinci_dm365()) {
261			mmcsd0_resources[0].start = DM365_MMCSD0_BASE;
262			mmcsd0_resources[0].end = DM365_MMCSD0_BASE +
263							SZ_4K - 1;
264			mmcsd0_resources[2].start = IRQ_DM365_SDIOINT0;
265			davinci_mmcsd0_device.name = "da830-mmc";
266		} else if (cpu_is_davinci_dm644x()) {
267			/* REVISIT: should this be in board-init code? */
268			/* Power-on 3.3V IO cells */
269			__raw_writel(0,
270				DAVINCI_SYSMOD_VIRT(SYSMOD_VDD3P3VPWDN));
271			/*Set up the pull regiter for MMC */
272			davinci_cfg_reg(DM644X_MSTK);
273		}
274
275		pdev = &davinci_mmcsd0_device;
276		break;
277	}
278
279	if (WARN_ON(!pdev))
280		return;
281
282	pdev->dev.platform_data = config;
283	platform_device_register(pdev);
284}
285
286#else
287
288void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config)
289{
290}
291
292#endif
293
294/*-------------------------------------------------------------------------*/
295
296static struct resource wdt_resources[] = {
297	{
298		.start	= DAVINCI_WDOG_BASE,
299		.end	= DAVINCI_WDOG_BASE + SZ_1K - 1,
300		.flags	= IORESOURCE_MEM,
301	},
302};
303
304struct platform_device davinci_wdt_device = {
305	.name		= "davinci-wdt",
306	.id		= -1,
307	.num_resources	= ARRAY_SIZE(wdt_resources),
308	.resource	= wdt_resources,
309};
310
311void davinci_restart(enum reboot_mode mode, const char *cmd)
312{
313	davinci_watchdog_reset(&davinci_wdt_device);
314}
315
316int davinci_init_wdt(void)
317{
318	return platform_device_register(&davinci_wdt_device);
319}
320
321static struct platform_device davinci_gpio_device = {
322	.name	= "davinci_gpio",
323	.id	= -1,
324};
325
326int davinci_gpio_register(struct resource *res, int size, void *pdata)
327{
328	davinci_gpio_device.resource = res;
329	davinci_gpio_device.num_resources = size;
330	davinci_gpio_device.dev.platform_data = pdata;
331	return platform_device_register(&davinci_gpio_device);
332}
333
334/*-------------------------------------------------------------------------*/
335
336/*-------------------------------------------------------------------------*/
337
338struct davinci_timer_instance davinci_timer_instance[2] = {
339	{
340		.base		= DAVINCI_TIMER0_BASE,
341		.bottom_irq	= IRQ_TINT0_TINT12,
342		.top_irq	= IRQ_TINT0_TINT34,
343	},
344	{
345		.base		= DAVINCI_TIMER1_BASE,
346		.bottom_irq	= IRQ_TINT1_TINT12,
347		.top_irq	= IRQ_TINT1_TINT34,
348	},
349};
350
351