Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/m68k/platform/5249/config.c
10819 views
1
/***************************************************************************/
2
3
/*
4
* linux/arch/m68knommu/platform/5249/config.c
5
*
6
* Copyright (C) 2002, Greg Ungerer ([email protected])
7
*/
8
9
/***************************************************************************/
10
11
#include <linux/kernel.h>
12
#include <linux/param.h>
13
#include <linux/init.h>
14
#include <linux/io.h>
15
#include <linux/spi/spi.h>
16
#include <linux/gpio.h>
17
#include <asm/machdep.h>
18
#include <asm/coldfire.h>
19
#include <asm/mcfsim.h>
20
#include <asm/mcfuart.h>
21
#include <asm/mcfqspi.h>
22
23
/***************************************************************************/
24
25
static struct mcf_platform_uart m5249_uart_platform[] = {
26
{
27
.mapbase = MCF_MBAR + MCFUART_BASE1,
28
.irq = 73,
29
},
30
{
31
.mapbase = MCF_MBAR + MCFUART_BASE2,
32
.irq = 74,
33
},
34
{ },
35
};
36
37
static struct platform_device m5249_uart = {
38
.name = "mcfuart",
39
.id = 0,
40
.dev.platform_data = m5249_uart_platform,
41
};
42
43
#ifdef CONFIG_M5249C3
44
45
static struct resource m5249_smc91x_resources[] = {
46
{
47
.start = 0xe0000300,
48
.end = 0xe0000300 + 0x100,
49
.flags = IORESOURCE_MEM,
50
},
51
{
52
.start = MCFINTC2_GPIOIRQ6,
53
.end = MCFINTC2_GPIOIRQ6,
54
.flags = IORESOURCE_IRQ,
55
},
56
};
57
58
static struct platform_device m5249_smc91x = {
59
.name = "smc91x",
60
.id = 0,
61
.num_resources = ARRAY_SIZE(m5249_smc91x_resources),
62
.resource = m5249_smc91x_resources,
63
};
64
65
#endif /* CONFIG_M5249C3 */
66
67
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
68
static struct resource m5249_qspi_resources[] = {
69
{
70
.start = MCFQSPI_IOBASE,
71
.end = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
72
.flags = IORESOURCE_MEM,
73
},
74
{
75
.start = MCF_IRQ_QSPI,
76
.end = MCF_IRQ_QSPI,
77
.flags = IORESOURCE_IRQ,
78
},
79
};
80
81
#define MCFQSPI_CS0 29
82
#define MCFQSPI_CS1 24
83
#define MCFQSPI_CS2 21
84
#define MCFQSPI_CS3 22
85
86
static int m5249_cs_setup(struct mcfqspi_cs_control *cs_control)
87
{
88
int status;
89
90
status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
91
if (status) {
92
pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
93
goto fail0;
94
}
95
status = gpio_direction_output(MCFQSPI_CS0, 1);
96
if (status) {
97
pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
98
goto fail1;
99
}
100
101
status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
102
if (status) {
103
pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
104
goto fail1;
105
}
106
status = gpio_direction_output(MCFQSPI_CS1, 1);
107
if (status) {
108
pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
109
goto fail2;
110
}
111
112
status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
113
if (status) {
114
pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
115
goto fail2;
116
}
117
status = gpio_direction_output(MCFQSPI_CS2, 1);
118
if (status) {
119
pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
120
goto fail3;
121
}
122
123
status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
124
if (status) {
125
pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
126
goto fail3;
127
}
128
status = gpio_direction_output(MCFQSPI_CS3, 1);
129
if (status) {
130
pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
131
goto fail4;
132
}
133
134
return 0;
135
136
fail4:
137
gpio_free(MCFQSPI_CS3);
138
fail3:
139
gpio_free(MCFQSPI_CS2);
140
fail2:
141
gpio_free(MCFQSPI_CS1);
142
fail1:
143
gpio_free(MCFQSPI_CS0);
144
fail0:
145
return status;
146
}
147
148
static void m5249_cs_teardown(struct mcfqspi_cs_control *cs_control)
149
{
150
gpio_free(MCFQSPI_CS3);
151
gpio_free(MCFQSPI_CS2);
152
gpio_free(MCFQSPI_CS1);
153
gpio_free(MCFQSPI_CS0);
154
}
155
156
static void m5249_cs_select(struct mcfqspi_cs_control *cs_control,
157
u8 chip_select, bool cs_high)
158
{
159
switch (chip_select) {
160
case 0:
161
gpio_set_value(MCFQSPI_CS0, cs_high);
162
break;
163
case 1:
164
gpio_set_value(MCFQSPI_CS1, cs_high);
165
break;
166
case 2:
167
gpio_set_value(MCFQSPI_CS2, cs_high);
168
break;
169
case 3:
170
gpio_set_value(MCFQSPI_CS3, cs_high);
171
break;
172
}
173
}
174
175
static void m5249_cs_deselect(struct mcfqspi_cs_control *cs_control,
176
u8 chip_select, bool cs_high)
177
{
178
switch (chip_select) {
179
case 0:
180
gpio_set_value(MCFQSPI_CS0, !cs_high);
181
break;
182
case 1:
183
gpio_set_value(MCFQSPI_CS1, !cs_high);
184
break;
185
case 2:
186
gpio_set_value(MCFQSPI_CS2, !cs_high);
187
break;
188
case 3:
189
gpio_set_value(MCFQSPI_CS3, !cs_high);
190
break;
191
}
192
}
193
194
static struct mcfqspi_cs_control m5249_cs_control = {
195
.setup = m5249_cs_setup,
196
.teardown = m5249_cs_teardown,
197
.select = m5249_cs_select,
198
.deselect = m5249_cs_deselect,
199
};
200
201
static struct mcfqspi_platform_data m5249_qspi_data = {
202
.bus_num = 0,
203
.num_chipselect = 4,
204
.cs_control = &m5249_cs_control,
205
};
206
207
static struct platform_device m5249_qspi = {
208
.name = "mcfqspi",
209
.id = 0,
210
.num_resources = ARRAY_SIZE(m5249_qspi_resources),
211
.resource = m5249_qspi_resources,
212
.dev.platform_data = &m5249_qspi_data,
213
};
214
215
static void __init m5249_qspi_init(void)
216
{
217
/* QSPI irq setup */
218
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI0,
219
MCF_MBAR + MCFSIM_QSPIICR);
220
mcf_mapirq2imr(MCF_IRQ_QSPI, MCFINTC_QSPI);
221
}
222
#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
223
224
225
static struct platform_device *m5249_devices[] __initdata = {
226
&m5249_uart,
227
#ifdef CONFIG_M5249C3
228
&m5249_smc91x,
229
#endif
230
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
231
&m5249_qspi,
232
#endif
233
};
234
235
/***************************************************************************/
236
237
static void __init m5249_uart_init_line(int line, int irq)
238
{
239
if (line == 0) {
240
writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
241
writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR);
242
mcf_mapirq2imr(irq, MCFINTC_UART0);
243
} else if (line == 1) {
244
writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
245
writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR);
246
mcf_mapirq2imr(irq, MCFINTC_UART1);
247
}
248
}
249
250
static void __init m5249_uarts_init(void)
251
{
252
const int nrlines = ARRAY_SIZE(m5249_uart_platform);
253
int line;
254
255
for (line = 0; (line < nrlines); line++)
256
m5249_uart_init_line(line, m5249_uart_platform[line].irq);
257
}
258
259
/***************************************************************************/
260
261
#ifdef CONFIG_M5249C3
262
263
static void __init m5249_smc91x_init(void)
264
{
265
u32 gpio;
266
267
/* Set the GPIO line as interrupt source for smc91x device */
268
gpio = readl(MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
269
writel(gpio | 0x40, MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
270
271
gpio = readl(MCF_MBAR2 + MCFSIM2_INTLEVEL5);
272
writel(gpio | 0x04000000, MCF_MBAR2 + MCFSIM2_INTLEVEL5);
273
}
274
275
#endif /* CONFIG_M5249C3 */
276
277
/***************************************************************************/
278
279
static void __init m5249_timers_init(void)
280
{
281
/* Timer1 is always used as system timer */
282
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
283
MCF_MBAR + MCFSIM_TIMER1ICR);
284
mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);
285
286
#ifdef CONFIG_HIGHPROFILE
287
/* Timer2 is to be used as a high speed profile timer */
288
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
289
MCF_MBAR + MCFSIM_TIMER2ICR);
290
mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
291
#endif
292
}
293
294
/***************************************************************************/
295
296
void m5249_cpu_reset(void)
297
{
298
local_irq_disable();
299
/* Set watchdog to soft reset, and enabled */
300
__raw_writeb(0xc0, MCF_MBAR + MCFSIM_SYPCR);
301
for (;;)
302
/* wait for watchdog to timeout */;
303
}
304
305
/***************************************************************************/
306
307
void __init config_BSP(char *commandp, int size)
308
{
309
mach_reset = m5249_cpu_reset;
310
m5249_timers_init();
311
m5249_uarts_init();
312
#ifdef CONFIG_M5249C3
313
m5249_smc91x_init();
314
#endif
315
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
316
m5249_qspi_init();
317
#endif
318
}
319
320
/***************************************************************************/
321
322
static int __init init_BSP(void)
323
{
324
platform_add_devices(m5249_devices, ARRAY_SIZE(m5249_devices));
325
return 0;
326
}
327
328
arch_initcall(init_BSP);
329
330
/***************************************************************************/
331
332