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 <linux/io.h>
25#include <asm/irq.h>
26#include <asm/sizes.h>
27#include <mach/irqs.h>
28
29/* assumes CONTROLLER_ONLY# is never asserted in the ESSR register */
30#define IOP13XX_TPMI_MMR(dev) 	IOP13XX_REG_ADDR32_PHYS(0x48000 + (dev << 12))
31#define IOP13XX_TPMI_MEM(dev) 	IOP13XX_REG_ADDR32_PHYS(0x60000 + (dev << 13))
32#define IOP13XX_TPMI_CTRL(dev)	IOP13XX_REG_ADDR32_PHYS(0x50000 + (dev << 10))
33#define IOP13XX_TPMI_IOP_CTRL(dev) (IOP13XX_TPMI_CTRL(dev) + 0x2000)
34#define IOP13XX_TPMI_MMR_SIZE	    (SZ_4K - 1)
35#define IOP13XX_TPMI_MEM_SIZE	    (255)
36#define IOP13XX_TPMI_MEM_CTRL	    (SZ_1K - 1)
37#define IOP13XX_TPMI_RESOURCE_MMR  0
38#define IOP13XX_TPMI_RESOURCE_MEM  1
39#define IOP13XX_TPMI_RESOURCE_CTRL 2
40#define IOP13XX_TPMI_RESOURCE_IOP_CTRL 3
41#define IOP13XX_TPMI_RESOURCE_IRQ  4
42
43static struct resource iop13xx_tpmi_0_resources[] = {
44	[IOP13XX_TPMI_RESOURCE_MMR] = {
45		.start = IOP13XX_TPMI_MMR(4), /* tpmi0 starts at dev == 4 */
46		.end = IOP13XX_TPMI_MMR(4) + IOP13XX_TPMI_MMR_SIZE,
47		.flags = IORESOURCE_MEM,
48	},
49	[IOP13XX_TPMI_RESOURCE_MEM] = {
50		.start = IOP13XX_TPMI_MEM(0),
51		.end = IOP13XX_TPMI_MEM(0) + IOP13XX_TPMI_MEM_SIZE,
52		.flags = IORESOURCE_MEM,
53	},
54	[IOP13XX_TPMI_RESOURCE_CTRL] = {
55		.start = IOP13XX_TPMI_CTRL(0),
56		.end = IOP13XX_TPMI_CTRL(0) + IOP13XX_TPMI_MEM_CTRL,
57		.flags = IORESOURCE_MEM,
58	},
59	[IOP13XX_TPMI_RESOURCE_IOP_CTRL] = {
60		.start = IOP13XX_TPMI_IOP_CTRL(0),
61		.end = IOP13XX_TPMI_IOP_CTRL(0) + IOP13XX_TPMI_MEM_CTRL,
62		.flags = IORESOURCE_MEM,
63	},
64	[IOP13XX_TPMI_RESOURCE_IRQ] = {
65		.start = IRQ_IOP13XX_TPMI0_OUT,
66		.end = IRQ_IOP13XX_TPMI0_OUT,
67		.flags = IORESOURCE_IRQ
68	}
69};
70
71static struct resource iop13xx_tpmi_1_resources[] = {
72	[IOP13XX_TPMI_RESOURCE_MMR] = {
73		.start = IOP13XX_TPMI_MMR(1),
74		.end = IOP13XX_TPMI_MMR(1) + IOP13XX_TPMI_MMR_SIZE,
75		.flags = IORESOURCE_MEM,
76	},
77	[IOP13XX_TPMI_RESOURCE_MEM] = {
78		.start = IOP13XX_TPMI_MEM(1),
79		.end = IOP13XX_TPMI_MEM(1) + IOP13XX_TPMI_MEM_SIZE,
80		.flags = IORESOURCE_MEM,
81	},
82	[IOP13XX_TPMI_RESOURCE_CTRL] = {
83		.start = IOP13XX_TPMI_CTRL(1),
84		.end = IOP13XX_TPMI_CTRL(1) + IOP13XX_TPMI_MEM_CTRL,
85		.flags = IORESOURCE_MEM,
86	},
87	[IOP13XX_TPMI_RESOURCE_IOP_CTRL] = {
88		.start = IOP13XX_TPMI_IOP_CTRL(1),
89		.end = IOP13XX_TPMI_IOP_CTRL(1) + IOP13XX_TPMI_MEM_CTRL,
90		.flags = IORESOURCE_MEM,
91	},
92	[IOP13XX_TPMI_RESOURCE_IRQ] = {
93		.start = IRQ_IOP13XX_TPMI1_OUT,
94		.end = IRQ_IOP13XX_TPMI1_OUT,
95		.flags = IORESOURCE_IRQ
96	}
97};
98
99static struct resource iop13xx_tpmi_2_resources[] = {
100	[IOP13XX_TPMI_RESOURCE_MMR] = {
101		.start = IOP13XX_TPMI_MMR(2),
102		.end = IOP13XX_TPMI_MMR(2) + IOP13XX_TPMI_MMR_SIZE,
103		.flags = IORESOURCE_MEM,
104	},
105	[IOP13XX_TPMI_RESOURCE_MEM] = {
106		.start = IOP13XX_TPMI_MEM(2),
107		.end = IOP13XX_TPMI_MEM(2) + IOP13XX_TPMI_MEM_SIZE,
108		.flags = IORESOURCE_MEM,
109	},
110	[IOP13XX_TPMI_RESOURCE_CTRL] = {
111		.start = IOP13XX_TPMI_CTRL(2),
112		.end = IOP13XX_TPMI_CTRL(2) + IOP13XX_TPMI_MEM_CTRL,
113		.flags = IORESOURCE_MEM,
114	},
115	[IOP13XX_TPMI_RESOURCE_IOP_CTRL] = {
116		.start = IOP13XX_TPMI_IOP_CTRL(2),
117		.end = IOP13XX_TPMI_IOP_CTRL(2) + IOP13XX_TPMI_MEM_CTRL,
118		.flags = IORESOURCE_MEM,
119	},
120	[IOP13XX_TPMI_RESOURCE_IRQ] = {
121		.start = IRQ_IOP13XX_TPMI2_OUT,
122		.end = IRQ_IOP13XX_TPMI2_OUT,
123		.flags = IORESOURCE_IRQ
124	}
125};
126
127static struct resource iop13xx_tpmi_3_resources[] = {
128	[IOP13XX_TPMI_RESOURCE_MMR] = {
129		.start = IOP13XX_TPMI_MMR(3),
130		.end = IOP13XX_TPMI_MMR(3) + IOP13XX_TPMI_MMR_SIZE,
131		.flags = IORESOURCE_MEM,
132	},
133	[IOP13XX_TPMI_RESOURCE_MEM] = {
134		.start = IOP13XX_TPMI_MEM(3),
135		.end = IOP13XX_TPMI_MEM(3) + IOP13XX_TPMI_MEM_SIZE,
136		.flags = IORESOURCE_MEM,
137	},
138	[IOP13XX_TPMI_RESOURCE_CTRL] = {
139		.start = IOP13XX_TPMI_CTRL(3),
140		.end = IOP13XX_TPMI_CTRL(3) + IOP13XX_TPMI_MEM_CTRL,
141		.flags = IORESOURCE_MEM,
142	},
143	[IOP13XX_TPMI_RESOURCE_IOP_CTRL] = {
144		.start = IOP13XX_TPMI_IOP_CTRL(3),
145		.end = IOP13XX_TPMI_IOP_CTRL(3) + IOP13XX_TPMI_MEM_CTRL,
146		.flags = IORESOURCE_MEM,
147	},
148	[IOP13XX_TPMI_RESOURCE_IRQ] = {
149		.start = IRQ_IOP13XX_TPMI3_OUT,
150		.end = IRQ_IOP13XX_TPMI3_OUT,
151		.flags = IORESOURCE_IRQ
152	}
153};
154
155u64 iop13xx_tpmi_mask = DMA_BIT_MASK(64);
156static struct platform_device iop13xx_tpmi_0_device = {
157	.name = "iop-tpmi",
158	.id = 0,
159	.num_resources = ARRAY_SIZE(iop13xx_tpmi_0_resources),
160	.resource = iop13xx_tpmi_0_resources,
161	.dev = {
162		.dma_mask          = &iop13xx_tpmi_mask,
163		.coherent_dma_mask = DMA_BIT_MASK(64),
164	},
165};
166
167static struct platform_device iop13xx_tpmi_1_device = {
168	.name = "iop-tpmi",
169	.id = 1,
170	.num_resources = ARRAY_SIZE(iop13xx_tpmi_1_resources),
171	.resource = iop13xx_tpmi_1_resources,
172	.dev = {
173		.dma_mask          = &iop13xx_tpmi_mask,
174		.coherent_dma_mask = DMA_BIT_MASK(64),
175	},
176};
177
178static struct platform_device iop13xx_tpmi_2_device = {
179	.name = "iop-tpmi",
180	.id = 2,
181	.num_resources = ARRAY_SIZE(iop13xx_tpmi_2_resources),
182	.resource = iop13xx_tpmi_2_resources,
183	.dev = {
184		.dma_mask          = &iop13xx_tpmi_mask,
185		.coherent_dma_mask = DMA_BIT_MASK(64),
186	},
187};
188
189static struct platform_device iop13xx_tpmi_3_device = {
190	.name = "iop-tpmi",
191	.id = 3,
192	.num_resources = ARRAY_SIZE(iop13xx_tpmi_3_resources),
193	.resource = iop13xx_tpmi_3_resources,
194	.dev = {
195		.dma_mask          = &iop13xx_tpmi_mask,
196		.coherent_dma_mask = DMA_BIT_MASK(64),
197	},
198};
199
200__init void iop13xx_add_tpmi_devices(void)
201{
202	unsigned short device_id;
203
204	/* tpmi's not present on iop341 or iop342 */
205	if (__raw_readl(IOP13XX_ESSR0) & IOP13XX_INTERFACE_SEL_PCIX)
206		/* ATUE must be present */
207		device_id = __raw_readw(IOP13XX_ATUE_DID);
208	else
209		/* ATUX must be present */
210		device_id = __raw_readw(IOP13XX_ATUX_DID);
211
212	switch (device_id) {
213	/* iop34[1|2] 0-tpmi */
214	case 0x3380:
215	case 0x3384:
216	case 0x3388:
217	case 0x338c:
218	case 0x3382:
219	case 0x3386:
220	case 0x338a:
221	case 0x338e:
222		return;
223	/* iop348 1-tpmi */
224	case 0x3310:
225	case 0x3312:
226	case 0x3314:
227	case 0x3318:
228	case 0x331a:
229	case 0x331c:
230	case 0x33c0:
231	case 0x33c2:
232	case 0x33c4:
233	case 0x33c8:
234	case 0x33ca:
235	case 0x33cc:
236	case 0x33b0:
237	case 0x33b2:
238	case 0x33b4:
239	case 0x33b8:
240	case 0x33ba:
241	case 0x33bc:
242	case 0x3320:
243	case 0x3322:
244	case 0x3324:
245	case 0x3328:
246	case 0x332a:
247	case 0x332c:
248		platform_device_register(&iop13xx_tpmi_0_device);
249		return;
250	default:
251		platform_device_register(&iop13xx_tpmi_0_device);
252		platform_device_register(&iop13xx_tpmi_1_device);
253		platform_device_register(&iop13xx_tpmi_2_device);
254		platform_device_register(&iop13xx_tpmi_3_device);
255		return;
256	}
257}
258