OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [arm/] [mach-pxa/] [lubbock.c] - Blame information for rev 17

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 *  linux/arch/arm/mach-pxa/lubbock.c
3
 *
4
 *  Support for the Intel DBPXA250 Development Platform.
5
 *
6
 *  Author:     Nicolas Pitre
7
 *  Created:    Jun 15, 2001
8
 *  Copyright:  MontaVista Software Inc.
9
 *
10
 *  This program is free software; you can redistribute it and/or modify
11
 *  it under the terms of the GNU General Public License version 2 as
12
 *  published by the Free Software Foundation.
13
 */
14
#include <linux/module.h>
15
#include <linux/kernel.h>
16
#include <linux/init.h>
17
#include <linux/platform_device.h>
18
#include <linux/sysdev.h>
19
#include <linux/major.h>
20
#include <linux/fb.h>
21
#include <linux/interrupt.h>
22
#include <linux/mtd/mtd.h>
23
#include <linux/mtd/partitions.h>
24
 
25
#include <linux/spi/spi.h>
26
#include <linux/spi/ads7846.h>
27
#include <asm/arch/pxa2xx_spi.h>
28
 
29
#include <asm/setup.h>
30
#include <asm/memory.h>
31
#include <asm/mach-types.h>
32
#include <asm/hardware.h>
33
#include <asm/irq.h>
34
#include <asm/sizes.h>
35
 
36
#include <asm/mach/arch.h>
37
#include <asm/mach/map.h>
38
#include <asm/mach/irq.h>
39
#include <asm/mach/flash.h>
40
 
41
#include <asm/hardware/sa1111.h>
42
 
43
#include <asm/arch/pxa-regs.h>
44
#include <asm/arch/lubbock.h>
45
#include <asm/arch/udc.h>
46
#include <asm/arch/irda.h>
47
#include <asm/arch/pxafb.h>
48
#include <asm/arch/mmc.h>
49
 
50
#include "generic.h"
51
#include "devices.h"
52
 
53
 
54
#define LUB_MISC_WR             __LUB_REG(LUBBOCK_FPGA_PHYS + 0x080)
55
 
56
void lubbock_set_misc_wr(unsigned int mask, unsigned int set)
57
{
58
        unsigned long flags;
59
 
60
        local_irq_save(flags);
61
        LUB_MISC_WR = (LUB_MISC_WR & ~mask) | (set & mask);
62
        local_irq_restore(flags);
63
}
64
EXPORT_SYMBOL(lubbock_set_misc_wr);
65
 
66
static unsigned long lubbock_irq_enabled;
67
 
68
static void lubbock_mask_irq(unsigned int irq)
69
{
70
        int lubbock_irq = (irq - LUBBOCK_IRQ(0));
71
        LUB_IRQ_MASK_EN = (lubbock_irq_enabled &= ~(1 << lubbock_irq));
72
}
73
 
74
static void lubbock_unmask_irq(unsigned int irq)
75
{
76
        int lubbock_irq = (irq - LUBBOCK_IRQ(0));
77
        /* the irq can be acknowledged only if deasserted, so it's done here */
78
        LUB_IRQ_SET_CLR &= ~(1 << lubbock_irq);
79
        LUB_IRQ_MASK_EN = (lubbock_irq_enabled |= (1 << lubbock_irq));
80
}
81
 
82
static struct irq_chip lubbock_irq_chip = {
83
        .name           = "FPGA",
84
        .ack            = lubbock_mask_irq,
85
        .mask           = lubbock_mask_irq,
86
        .unmask         = lubbock_unmask_irq,
87
};
88
 
89
static void lubbock_irq_handler(unsigned int irq, struct irq_desc *desc)
90
{
91
        unsigned long pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled;
92
        do {
93
                GEDR(0) = GPIO_bit(0);    /* clear our parent irq */
94
                if (likely(pending)) {
95
                        irq = LUBBOCK_IRQ(0) + __ffs(pending);
96
                        desc = irq_desc + irq;
97
                        desc_handle_irq(irq, desc);
98
                }
99
                pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled;
100
        } while (pending);
101
}
102
 
103
static void __init lubbock_init_irq(void)
104
{
105
        int irq;
106
 
107
        pxa25x_init_irq();
108
 
109
        /* setup extra lubbock irqs */
110
        for (irq = LUBBOCK_IRQ(0); irq <= LUBBOCK_LAST_IRQ; irq++) {
111
                set_irq_chip(irq, &lubbock_irq_chip);
112
                set_irq_handler(irq, handle_level_irq);
113
                set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
114
        }
115
 
116
        set_irq_chained_handler(IRQ_GPIO(0), lubbock_irq_handler);
117
        set_irq_type(IRQ_GPIO(0), IRQT_FALLING);
118
}
119
 
120
#ifdef CONFIG_PM
121
 
122
static int lubbock_irq_resume(struct sys_device *dev)
123
{
124
        LUB_IRQ_MASK_EN = lubbock_irq_enabled;
125
        return 0;
126
}
127
 
128
static struct sysdev_class lubbock_irq_sysclass = {
129
        set_kset_name("cpld_irq"),
130
        .resume = lubbock_irq_resume,
131
};
132
 
133
static struct sys_device lubbock_irq_device = {
134
        .cls = &lubbock_irq_sysclass,
135
};
136
 
137
static int __init lubbock_irq_device_init(void)
138
{
139
        int ret = sysdev_class_register(&lubbock_irq_sysclass);
140
        if (ret == 0)
141
                ret = sysdev_register(&lubbock_irq_device);
142
        return ret;
143
}
144
 
145
device_initcall(lubbock_irq_device_init);
146
 
147
#endif
148
 
149
static int lubbock_udc_is_connected(void)
150
{
151
        return (LUB_MISC_RD & (1 << 9)) == 0;
152
}
153
 
154
static struct pxa2xx_udc_mach_info udc_info __initdata = {
155
        .udc_is_connected       = lubbock_udc_is_connected,
156
        // no D+ pullup; lubbock can't connect/disconnect in software
157
};
158
 
159
static struct platform_device lub_audio_device = {
160
        .name           = "pxa2xx-ac97",
161
        .id             = -1,
162
};
163
 
164
static struct resource sa1111_resources[] = {
165
        [0] = {
166
                .start  = 0x10000000,
167
                .end    = 0x10001fff,
168
                .flags  = IORESOURCE_MEM,
169
        },
170
        [1] = {
171
                .start  = LUBBOCK_SA1111_IRQ,
172
                .end    = LUBBOCK_SA1111_IRQ,
173
                .flags  = IORESOURCE_IRQ,
174
        },
175
};
176
 
177
static struct platform_device sa1111_device = {
178
        .name           = "sa1111",
179
        .id             = -1,
180
        .num_resources  = ARRAY_SIZE(sa1111_resources),
181
        .resource       = sa1111_resources,
182
};
183
 
184
static struct resource smc91x_resources[] = {
185
        [0] = {
186
                .name   = "smc91x-regs",
187
                .start  = 0x0c000c00,
188
                .end    = 0x0c0fffff,
189
                .flags  = IORESOURCE_MEM,
190
        },
191
        [1] = {
192
                .start  = LUBBOCK_ETH_IRQ,
193
                .end    = LUBBOCK_ETH_IRQ,
194
                .flags  = IORESOURCE_IRQ,
195
        },
196
        [2] = {
197
                .name   = "smc91x-attrib",
198
                .start  = 0x0e000000,
199
                .end    = 0x0e0fffff,
200
                .flags  = IORESOURCE_MEM,
201
        },
202
};
203
 
204
/* ADS7846 is connected through SSP ... and if your board has J5 populated,
205
 * you can select it to replace the ucb1400 by switching the touchscreen cable
206
 * (to J5) and poking board registers (as done below).  Else it's only useful
207
 * for the temperature sensors.
208
 */
209
static struct resource pxa_ssp_resources[] = {
210
        [0] = {
211
                .start  = __PREG(SSCR0_P(1)),
212
                .end    = __PREG(SSCR0_P(1)) + 0x14,
213
                .flags  = IORESOURCE_MEM,
214
        },
215
        [1] = {
216
                .start  = IRQ_SSP,
217
                .end    = IRQ_SSP,
218
                .flags  = IORESOURCE_IRQ,
219
        },
220
};
221
 
222
static struct pxa2xx_spi_master pxa_ssp_master_info = {
223
        .ssp_type       = PXA25x_SSP,
224
        .clock_enable   = CKEN_SSP,
225
        .num_chipselect = 0,
226
};
227
 
228
static struct platform_device pxa_ssp = {
229
        .name           = "pxa2xx-spi",
230
        .id             = 1,
231
        .resource       = pxa_ssp_resources,
232
        .num_resources  = ARRAY_SIZE(pxa_ssp_resources),
233
        .dev = {
234
                .platform_data  = &pxa_ssp_master_info,
235
        },
236
};
237
 
238
static int lubbock_ads7846_pendown_state(void)
239
{
240
        /* TS_BUSY is bit 8 in LUB_MISC_RD, but pendown is irq-only */
241
        return 0;
242
}
243
 
244
static struct ads7846_platform_data ads_info = {
245
        .model                  = 7846,
246
        .vref_delay_usecs       = 100,          /* internal, no cap */
247
        .get_pendown_state      = lubbock_ads7846_pendown_state,
248
        // .x_plate_ohms                = 500,  /* GUESS! */
249
        // .y_plate_ohms                = 500,  /* GUESS! */
250
};
251
 
252
static void ads7846_cs(u32 command)
253
{
254
        static const unsigned   TS_nCS = 1 << 11;
255
        lubbock_set_misc_wr(TS_nCS, (command == PXA2XX_CS_ASSERT) ? 0 : TS_nCS);
256
}
257
 
258
static struct pxa2xx_spi_chip ads_hw = {
259
        .tx_threshold           = 1,
260
        .rx_threshold           = 2,
261
        .cs_control             = ads7846_cs,
262
};
263
 
264
static struct spi_board_info spi_board_info[] __initdata = { {
265
        .modalias       = "ads7846",
266
        .platform_data  = &ads_info,
267
        .controller_data = &ads_hw,
268
        .irq            = LUBBOCK_BB_IRQ,
269
        .max_speed_hz   = 120000 /* max sample rate at 3V */
270
                                * 26 /* command + data + overhead */,
271
        .bus_num        = 1,
272
        .chip_select    = 0,
273
},
274
};
275
 
276
static struct platform_device smc91x_device = {
277
        .name           = "smc91x",
278
        .id             = -1,
279
        .num_resources  = ARRAY_SIZE(smc91x_resources),
280
        .resource       = smc91x_resources,
281
};
282
 
283
static struct resource flash_resources[] = {
284
        [0] = {
285
                .start  = 0x00000000,
286
                .end    = SZ_64M - 1,
287
                .flags  = IORESOURCE_MEM,
288
        },
289
        [1] = {
290
                .start  = 0x04000000,
291
                .end    = 0x04000000 + SZ_64M - 1,
292
                .flags  = IORESOURCE_MEM,
293
        },
294
};
295
 
296
static struct mtd_partition lubbock_partitions[] = {
297
        {
298
                .name =         "Bootloader",
299
                .size =         0x00040000,
300
                .offset =       0,
301
                .mask_flags =   MTD_WRITEABLE  /* force read-only */
302
        },{
303
                .name =         "Kernel",
304
                .size =         0x00100000,
305
                .offset =       0x00040000,
306
        },{
307
                .name =         "Filesystem",
308
                .size =         MTDPART_SIZ_FULL,
309
                .offset =       0x00140000
310
        }
311
};
312
 
313
static struct flash_platform_data lubbock_flash_data[2] = {
314
        {
315
                .map_name       = "cfi_probe",
316
                .parts          = lubbock_partitions,
317
                .nr_parts       = ARRAY_SIZE(lubbock_partitions),
318
        }, {
319
                .map_name       = "cfi_probe",
320
                .parts          = NULL,
321
                .nr_parts       = 0,
322
        }
323
};
324
 
325
static struct platform_device lubbock_flash_device[2] = {
326
        {
327
                .name           = "pxa2xx-flash",
328
                .id             = 0,
329
                .dev = {
330
                        .platform_data = &lubbock_flash_data[0],
331
                },
332
                .resource = &flash_resources[0],
333
                .num_resources = 1,
334
        },
335
        {
336
                .name           = "pxa2xx-flash",
337
                .id             = 1,
338
                .dev = {
339
                        .platform_data = &lubbock_flash_data[1],
340
                },
341
                .resource = &flash_resources[1],
342
                .num_resources = 1,
343
        },
344
};
345
 
346
static struct platform_device *devices[] __initdata = {
347
        &sa1111_device,
348
        &lub_audio_device,
349
        &smc91x_device,
350
        &lubbock_flash_device[0],
351
        &lubbock_flash_device[1],
352
        &pxa_ssp,
353
};
354
 
355
static struct pxafb_mode_info sharp_lm8v31_mode = {
356
        .pixclock       = 270000,
357
        .xres           = 640,
358
        .yres           = 480,
359
        .bpp            = 16,
360
        .hsync_len      = 1,
361
        .left_margin    = 3,
362
        .right_margin   = 3,
363
        .vsync_len      = 1,
364
        .upper_margin   = 0,
365
        .lower_margin   = 0,
366
        .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
367
        .cmap_greyscale = 0,
368
};
369
 
370
static struct pxafb_mach_info sharp_lm8v31 = {
371
        .modes          = &sharp_lm8v31_mode,
372
        .num_modes      = 1,
373
        .cmap_inverse   = 0,
374
        .cmap_static    = 0,
375
        .lccr0          = LCCR0_SDS,
376
        .lccr3          = LCCR3_PCP | LCCR3_Acb(255),
377
};
378
 
379
#define MMC_POLL_RATE           msecs_to_jiffies(1000)
380
 
381
static void lubbock_mmc_poll(unsigned long);
382
static irq_handler_t mmc_detect_int;
383
 
384
static struct timer_list mmc_timer = {
385
        .function       = lubbock_mmc_poll,
386
};
387
 
388
static void lubbock_mmc_poll(unsigned long data)
389
{
390
        unsigned long flags;
391
 
392
        /* clear any previous irq state, then ... */
393
        local_irq_save(flags);
394
        LUB_IRQ_SET_CLR &= ~(1 << 0);
395
        local_irq_restore(flags);
396
 
397
        /* poll until mmc/sd card is removed */
398
        if (LUB_IRQ_SET_CLR & (1 << 0))
399
                mod_timer(&mmc_timer, jiffies + MMC_POLL_RATE);
400
        else {
401
                (void) mmc_detect_int(LUBBOCK_SD_IRQ, (void *)data);
402
                enable_irq(LUBBOCK_SD_IRQ);
403
        }
404
}
405
 
406
static irqreturn_t lubbock_detect_int(int irq, void *data)
407
{
408
        /* IRQ is level triggered; disable, and poll for removal */
409
        disable_irq(irq);
410
        mod_timer(&mmc_timer, jiffies + MMC_POLL_RATE);
411
 
412
        return mmc_detect_int(irq, data);
413
}
414
 
415
static int lubbock_mci_init(struct device *dev,
416
                irq_handler_t detect_int,
417
                void *data)
418
{
419
        /* setup GPIO for PXA25x MMC controller */
420
        pxa_gpio_mode(GPIO6_MMCCLK_MD);
421
        pxa_gpio_mode(GPIO8_MMCCS0_MD);
422
 
423
        /* detect card insert/eject */
424
        mmc_detect_int = detect_int;
425
        init_timer(&mmc_timer);
426
        mmc_timer.data = (unsigned long) data;
427
        return request_irq(LUBBOCK_SD_IRQ, lubbock_detect_int,
428
                        IRQF_SAMPLE_RANDOM, "lubbock-sd-detect", data);
429
}
430
 
431
static int lubbock_mci_get_ro(struct device *dev)
432
{
433
        return (LUB_MISC_RD & (1 << 2)) != 0;
434
}
435
 
436
static void lubbock_mci_exit(struct device *dev, void *data)
437
{
438
        free_irq(LUBBOCK_SD_IRQ, data);
439
        del_timer_sync(&mmc_timer);
440
}
441
 
442
static struct pxamci_platform_data lubbock_mci_platform_data = {
443
        .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
444
        .detect_delay   = 1,
445
        .init           = lubbock_mci_init,
446
        .get_ro         = lubbock_mci_get_ro,
447
        .exit           = lubbock_mci_exit,
448
};
449
 
450
static void lubbock_irda_transceiver_mode(struct device *dev, int mode)
451
{
452
        unsigned long flags;
453
 
454
        local_irq_save(flags);
455
        if (mode & IR_SIRMODE) {
456
                LUB_MISC_WR &= ~(1 << 4);
457
        } else if (mode & IR_FIRMODE) {
458
                LUB_MISC_WR |= 1 << 4;
459
        }
460
        local_irq_restore(flags);
461
}
462
 
463
static struct pxaficp_platform_data lubbock_ficp_platform_data = {
464
        .transceiver_cap  = IR_SIRMODE | IR_FIRMODE,
465
        .transceiver_mode = lubbock_irda_transceiver_mode,
466
};
467
 
468
static void __init lubbock_init(void)
469
{
470
        int flashboot = (LUB_CONF_SWITCHES & 1);
471
 
472
        pxa_set_udc_info(&udc_info);
473
        set_pxa_fb_info(&sharp_lm8v31);
474
        pxa_set_mci_info(&lubbock_mci_platform_data);
475
        pxa_set_ficp_info(&lubbock_ficp_platform_data);
476
 
477
        lubbock_flash_data[0].width = lubbock_flash_data[1].width =
478
                (BOOT_DEF & 1) ? 2 : 4;
479
        /* Compensate for the nROMBT switch which swaps the flash banks */
480
        printk(KERN_NOTICE "Lubbock configured to boot from %s (bank %d)\n",
481
               flashboot?"Flash":"ROM", flashboot);
482
 
483
        lubbock_flash_data[flashboot^1].name = "application-flash";
484
        lubbock_flash_data[flashboot].name = "boot-rom";
485
        (void) platform_add_devices(devices, ARRAY_SIZE(devices));
486
 
487
        spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
488
}
489
 
490
static struct map_desc lubbock_io_desc[] __initdata = {
491
        {       /* CPLD */
492
                .virtual        =  LUBBOCK_FPGA_VIRT,
493
                .pfn            = __phys_to_pfn(LUBBOCK_FPGA_PHYS),
494
                .length         = 0x00100000,
495
                .type           = MT_DEVICE
496
        }
497
};
498
 
499
static void __init lubbock_map_io(void)
500
{
501
        pxa_map_io();
502
        iotable_init(lubbock_io_desc, ARRAY_SIZE(lubbock_io_desc));
503
 
504
        /* SSP data pins */
505
        pxa_gpio_mode(GPIO23_SCLK_MD);
506
        pxa_gpio_mode(GPIO25_STXD_MD);
507
        pxa_gpio_mode(GPIO26_SRXD_MD);
508
 
509
        /* This enables the BTUART */
510
        pxa_gpio_mode(GPIO42_BTRXD_MD);
511
        pxa_gpio_mode(GPIO43_BTTXD_MD);
512
        pxa_gpio_mode(GPIO44_BTCTS_MD);
513
        pxa_gpio_mode(GPIO45_BTRTS_MD);
514
 
515
        GPSR(GPIO48_nPOE) =
516
                GPIO_bit(GPIO48_nPOE) |
517
                GPIO_bit(GPIO49_nPWE) |
518
                GPIO_bit(GPIO50_nPIOR) |
519
                GPIO_bit(GPIO51_nPIOW) |
520
                GPIO_bit(GPIO52_nPCE_1) |
521
                GPIO_bit(GPIO53_nPCE_2);
522
 
523
        pxa_gpio_mode(GPIO48_nPOE_MD);
524
        pxa_gpio_mode(GPIO49_nPWE_MD);
525
        pxa_gpio_mode(GPIO50_nPIOR_MD);
526
        pxa_gpio_mode(GPIO51_nPIOW_MD);
527
        pxa_gpio_mode(GPIO52_nPCE_1_MD);
528
        pxa_gpio_mode(GPIO53_nPCE_2_MD);
529
        pxa_gpio_mode(GPIO54_pSKTSEL_MD);
530
        pxa_gpio_mode(GPIO55_nPREG_MD);
531
        pxa_gpio_mode(GPIO56_nPWAIT_MD);
532
        pxa_gpio_mode(GPIO57_nIOIS16_MD);
533
 
534
        /* This is for the SMC chip select */
535
        pxa_gpio_mode(GPIO79_nCS_3_MD);
536
 
537
        /* setup sleep mode values */
538
        PWER  = 0x00000002;
539
        PFER  = 0x00000000;
540
        PRER  = 0x00000002;
541
        PGSR0 = 0x00008000;
542
        PGSR1 = 0x003F0202;
543
        PGSR2 = 0x0001C000;
544
        PCFR |= PCFR_OPDE;
545
}
546
 
547
MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)")
548
        /* Maintainer: MontaVista Software Inc. */
549
        .phys_io        = 0x40000000,
550
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
551
        .map_io         = lubbock_map_io,
552
        .init_irq       = lubbock_init_irq,
553
        .timer          = &pxa_timer,
554
        .init_machine   = lubbock_init,
555
MACHINE_END

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.