1/*
2 * iop13xx tpmi device resources
3 * Copyright (c) 2005-2006, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16 * Place - Suite 330, Boston, MA 02111-1307 USA.
17 *
18 */
19
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/platform_device.h>
23#include <linux/dma-mapping.h>
24#include <asm/io.h>
25#include <asm/irq.h>
26#include <asm/sizes.h>
27
28/* assumes CONTROLLER_ONLY# is never asserted in the ESSR register */
29#define IOP13XX_TPMI_MMR(dev) 	IOP13XX_REG_ADDR32_PHYS(0x48000 + (dev << 12))
30#define IOP13XX_TPMI_MEM(dev) 	IOP13XX_REG_ADDR32_PHYS(0x60000 + (dev << 13))
31#define IOP13XX_TPMI_CTRL(dev)	IOP13XX_REG_ADDR32_PHYS(0x50000 + (dev << 10))
32#define IOP13XX_TPMI_MMR_SIZE	    (SZ_4K - 1)
33#define IOP13XX_TPMI_MEM_SIZE	    (255)
34#define IOP13XX_TPMI_MEM_CTRL	    (SZ_1K - 1)
35#define IOP13XX_TPMI_RESOURCE_MMR  0
36#define IOP13XX_TPMI_RESOURCE_MEM  1
37#define IOP13XX_TPMI_RESOURCE_CTRL 2
38#define IOP13XX_TPMI_RESOURCE_IRQ  3
39
40static struct resource iop13xx_tpmi_0_resources[] = {
41	[IOP13XX_TPMI_RESOURCE_MMR] = {
42		.start = IOP13XX_TPMI_MMR(4), /* tpmi0 starts at dev == 4 */
43		.end = IOP13XX_TPMI_MMR(4) + IOP13XX_TPMI_MMR_SIZE,
44		.flags = IORESOURCE_MEM,
45	},
46	[IOP13XX_TPMI_RESOURCE_MEM] = {
47		.start = IOP13XX_TPMI_MEM(0),
48		.end = IOP13XX_TPMI_MEM(0) + IOP13XX_TPMI_MEM_SIZE,
49		.flags = IORESOURCE_MEM,
50	},
51	[IOP13XX_TPMI_RESOURCE_CTRL] = {
52		.start = IOP13XX_TPMI_CTRL(0),
53		.end = IOP13XX_TPMI_CTRL(0) + IOP13XX_TPMI_MEM_CTRL,
54		.flags = IORESOURCE_MEM,
55	},
56	[IOP13XX_TPMI_RESOURCE_IRQ] = {
57		.start = IRQ_IOP13XX_TPMI0_OUT,
58		.end = IRQ_IOP13XX_TPMI0_OUT,
59		.flags = IORESOURCE_IRQ
60	}
61};
62
63static struct resource iop13xx_tpmi_1_resources[] = {
64	[IOP13XX_TPMI_RESOURCE_MMR] = {
65		.start = IOP13XX_TPMI_MMR(1),
66		.end = IOP13XX_TPMI_MMR(1) + IOP13XX_TPMI_MMR_SIZE,
67		.flags = IORESOURCE_MEM,
68	},
69	[IOP13XX_TPMI_RESOURCE_MEM] = {
70		.start = IOP13XX_TPMI_MEM(1),
71		.end = IOP13XX_TPMI_MEM(1) + IOP13XX_TPMI_MEM_SIZE,
72		.flags = IORESOURCE_MEM,
73	},
74	[IOP13XX_TPMI_RESOURCE_CTRL] = {
75		.start = IOP13XX_TPMI_CTRL(1),
76		.end = IOP13XX_TPMI_CTRL(1) + IOP13XX_TPMI_MEM_CTRL,
77		.flags = IORESOURCE_MEM,
78	},
79	[IOP13XX_TPMI_RESOURCE_IRQ] = {
80		.start = IRQ_IOP13XX_TPMI1_OUT,
81		.end = IRQ_IOP13XX_TPMI1_OUT,
82		.flags = IORESOURCE_IRQ
83	}
84};
85
86static struct resource iop13xx_tpmi_2_resources[] = {
87	[IOP13XX_TPMI_RESOURCE_MMR] = {
88		.start = IOP13XX_TPMI_MMR(2),
89		.end = IOP13XX_TPMI_MMR(2) + IOP13XX_TPMI_MMR_SIZE,
90		.flags = IORESOURCE_MEM,
91	},
92	[IOP13XX_TPMI_RESOURCE_MEM] = {
93		.start = IOP13XX_TPMI_MEM(2),
94		.end = IOP13XX_TPMI_MEM(2) + IOP13XX_TPMI_MEM_SIZE,
95		.flags = IORESOURCE_MEM,
96	},
97	[IOP13XX_TPMI_RESOURCE_CTRL] = {
98		.start = IOP13XX_TPMI_CTRL(2),
99		.end = IOP13XX_TPMI_CTRL(2) + IOP13XX_TPMI_MEM_CTRL,
100		.flags = IORESOURCE_MEM,
101	},
102	[IOP13XX_TPMI_RESOURCE_IRQ] = {
103		.start = IRQ_IOP13XX_TPMI2_OUT,
104		.end = IRQ_IOP13XX_TPMI2_OUT,
105		.flags = IORESOURCE_IRQ
106	}
107};
108
109static struct resource iop13xx_tpmi_3_resources[] = {
110	[IOP13XX_TPMI_RESOURCE_MMR] = {
111		.start = IOP13XX_TPMI_MMR(3),
112		.end = IOP13XX_TPMI_MMR(3) + IOP13XX_TPMI_MMR_SIZE,
113		.flags = IORESOURCE_MEM,
114	},
115	[IOP13XX_TPMI_RESOURCE_MEM] = {
116		.start = IOP13XX_TPMI_MEM(3),
117		.end = IOP13XX_TPMI_MEM(3) + IOP13XX_TPMI_MEM_SIZE,
118		.flags = IORESOURCE_MEM,
119	},
120	[IOP13XX_TPMI_RESOURCE_CTRL] = {
121		.start = IOP13XX_TPMI_CTRL(3),
122		.end = IOP13XX_TPMI_CTRL(3) + IOP13XX_TPMI_MEM_CTRL,
123		.flags = IORESOURCE_MEM,
124	},
125	[IOP13XX_TPMI_RESOURCE_IRQ] = {
126		.start = IRQ_IOP13XX_TPMI3_OUT,
127		.end = IRQ_IOP13XX_TPMI3_OUT,
128		.flags = IORESOURCE_IRQ
129	}
130};
131
132u64 iop13xx_tpmi_mask = DMA_64BIT_MASK;
133static struct platform_device iop13xx_tpmi_0_device = {
134	.name = "iop-tpmi",
135	.id = 0,
136	.num_resources = 4,
137	.resource = iop13xx_tpmi_0_resources,
138	.dev = {
139		.dma_mask          = &iop13xx_tpmi_mask,
140		.coherent_dma_mask = DMA_64BIT_MASK,
141	},
142};
143
144static struct platform_device iop13xx_tpmi_1_device = {
145	.name = "iop-tpmi",
146	.id = 1,
147	.num_resources = 4,
148	.resource = iop13xx_tpmi_1_resources,
149	.dev = {
150		.dma_mask          = &iop13xx_tpmi_mask,
151		.coherent_dma_mask = DMA_64BIT_MASK,
152	},
153};
154
155static struct platform_device iop13xx_tpmi_2_device = {
156	.name = "iop-tpmi",
157	.id = 2,
158	.num_resources = 4,
159	.resource = iop13xx_tpmi_2_resources,
160	.dev = {
161		.dma_mask          = &iop13xx_tpmi_mask,
162		.coherent_dma_mask = DMA_64BIT_MASK,
163	},
164};
165
166static struct platform_device iop13xx_tpmi_3_device = {
167	.name = "iop-tpmi",
168	.id = 3,
169	.num_resources = 4,
170	.resource = iop13xx_tpmi_3_resources,
171	.dev = {
172		.dma_mask          = &iop13xx_tpmi_mask,
173		.coherent_dma_mask = DMA_64BIT_MASK,
174	},
175};
176
177__init void iop13xx_add_tpmi_devices(void)
178{
179	unsigned short device_id;
180
181	/* tpmi's not present on iop341 or iop342 */
182	if (__raw_readl(IOP13XX_ESSR0) & IOP13XX_INTERFACE_SEL_PCIX)
183		/* ATUE must be present */
184		device_id = __raw_readw(IOP13XX_ATUE_DID);
185	else
186		/* ATUX must be present */
187		device_id = __raw_readw(IOP13XX_ATUX_DID);
188
189	switch (device_id) {
190	/* iop34[1|2] 0-tpmi */
191	case 0x3380:
192	case 0x3384:
193	case 0x3388:
194	case 0x338c:
195	case 0x3382:
196	case 0x3386:
197	case 0x338a:
198	case 0x338e:
199		return;
200	/* iop348 1-tpmi */
201	case 0x3310:
202	case 0x3312:
203	case 0x3314:
204	case 0x3318:
205	case 0x331a:
206	case 0x331c:
207	case 0x33c0:
208	case 0x33c2:
209	case 0x33c4:
210	case 0x33c8:
211	case 0x33ca:
212	case 0x33cc:
213	case 0x33b0:
214	case 0x33b2:
215	case 0x33b4:
216	case 0x33b8:
217	case 0x33ba:
218	case 0x33bc:
219	case 0x3320:
220	case 0x3322:
221	case 0x3324:
222	case 0x3328:
223	case 0x332a:
224	case 0x332c:
225		platform_device_register(&iop13xx_tpmi_0_device);
226		return;
227	default:
228		platform_device_register(&iop13xx_tpmi_0_device);
229		platform_device_register(&iop13xx_tpmi_1_device);
230		platform_device_register(&iop13xx_tpmi_2_device);
231		platform_device_register(&iop13xx_tpmi_3_device);
232		return;
233	}
234}
235