X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Farm%2Fmach-integrator%2Fintegrator_cp.c;h=913f64b224051bc968bab4e15464682e3085ba86;hb=refs%2Fheads%2Fvserver;hp=e56fcb1ea8ad5f72db3c74568a67ae6c01b86895;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index e56fcb1ea..913f64b22 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -11,20 +11,23 @@ #include #include #include -#include +#include +#include #include #include #include +#include +#include +#include #include #include #include #include #include -#include -#include #include +#include #include #include @@ -32,7 +35,9 @@ #include #include #include +#include +#include "common.h" #include "clock.h" #define INTCP_PA_MMC_BASE 0x1c000000 @@ -69,18 +74,62 @@ */ static struct map_desc intcp_io_desc[] __initdata = { - { IO_ADDRESS(INTEGRATOR_HDR_BASE), INTEGRATOR_HDR_BASE, SZ_4K, MT_DEVICE }, - { IO_ADDRESS(INTEGRATOR_SC_BASE), INTEGRATOR_SC_BASE, SZ_4K, MT_DEVICE }, - { IO_ADDRESS(INTEGRATOR_EBI_BASE), INTEGRATOR_EBI_BASE, SZ_4K, MT_DEVICE }, - { IO_ADDRESS(INTEGRATOR_CT_BASE), INTEGRATOR_CT_BASE, SZ_4K, MT_DEVICE }, - { IO_ADDRESS(INTEGRATOR_IC_BASE), INTEGRATOR_IC_BASE, SZ_4K, MT_DEVICE }, - { IO_ADDRESS(INTEGRATOR_UART0_BASE), INTEGRATOR_UART0_BASE, SZ_4K, MT_DEVICE }, - { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K, MT_DEVICE }, - { IO_ADDRESS(INTEGRATOR_DBG_BASE), INTEGRATOR_DBG_BASE, SZ_4K, MT_DEVICE }, - { IO_ADDRESS(INTEGRATOR_GPIO_BASE), INTEGRATOR_GPIO_BASE, SZ_4K, MT_DEVICE }, - { 0xfc900000, 0xc9000000, SZ_4K, MT_DEVICE }, - { 0xfca00000, 0xca000000, SZ_4K, MT_DEVICE }, - { 0xfcb00000, 0xcb000000, SZ_4K, MT_DEVICE }, + { + .virtual = IO_ADDRESS(INTEGRATOR_HDR_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_HDR_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(INTEGRATOR_SC_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_SC_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(INTEGRATOR_EBI_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_EBI_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(INTEGRATOR_CT_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_CT_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(INTEGRATOR_IC_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_IC_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(INTEGRATOR_UART0_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_UART0_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(INTEGRATOR_UART1_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_UART1_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(INTEGRATOR_DBG_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_DBG_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = IO_ADDRESS(INTEGRATOR_GPIO_BASE), + .pfn = __phys_to_pfn(INTEGRATOR_GPIO_BASE), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = 0xfca00000, + .pfn = __phys_to_pfn(0xca000000), + .length = SZ_4K, + .type = MT_DEVICE + }, { + .virtual = 0xfcb00000, + .pfn = __phys_to_pfn(0xcb000000), + .length = SZ_4K, + .type = MT_DEVICE + } }; static void __init intcp_map_io(void) @@ -107,7 +156,8 @@ static void cic_unmask_irq(unsigned int irq) cic_writel(1 << irq, INTCP_VA_CIC_BASE + IRQ_ENABLE_SET); } -static struct irqchip cic_chip = { +static struct irq_chip cic_chip = { + .name = "CIC", .ack = cic_mask_irq, .mask = cic_mask_irq, .unmask = cic_unmask_irq, @@ -125,7 +175,8 @@ static void pic_unmask_irq(unsigned int irq) pic_writel(1 << irq, INTCP_VA_PIC_BASE + IRQ_ENABLE_SET); } -static struct irqchip pic_chip = { +static struct irq_chip pic_chip = { + .name = "PIC", .ack = pic_mask_irq, .mask = pic_mask_irq, .unmask = pic_unmask_irq, @@ -143,19 +194,20 @@ static void sic_unmask_irq(unsigned int irq) sic_writel(1 << irq, INTCP_VA_SIC_BASE + IRQ_ENABLE_SET); } -static struct irqchip sic_chip = { +static struct irq_chip sic_chip = { + .name = "SIC", .ack = sic_mask_irq, .mask = sic_mask_irq, .unmask = sic_unmask_irq, }; static void -sic_handle_irq(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) +sic_handle_irq(unsigned int irq, struct irq_desc *desc) { unsigned long status = sic_readl(INTCP_VA_SIC_BASE + IRQ_STATUS); if (status == 0) { - do_bad_IRQ(irq, desc, regs); + do_bad_IRQ(irq, desc); return; } @@ -166,7 +218,7 @@ sic_handle_irq(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) irq += IRQ_SIC_START; desc = irq_desc + irq; - desc->handle(irq, desc, regs); + desc_handle_irq(irq, desc); } while (status); } @@ -183,12 +235,10 @@ static void __init intcp_init_irq(void) for (i = IRQ_PIC_START; i <= IRQ_PIC_END; i++) { if (i == 11) i = 22; - if (i == IRQ_CP_CPPLDINT) - i++; if (i == 29) break; set_irq_chip(i, &pic_chip); - set_irq_handler(i, do_level_IRQ); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } @@ -197,7 +247,7 @@ static void __init intcp_init_irq(void) for (i = IRQ_CIC_START; i <= IRQ_CIC_END; i++) { set_irq_chip(i, &cic_chip); - set_irq_handler(i, do_level_IRQ); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID); } @@ -206,12 +256,11 @@ static void __init intcp_init_irq(void) for (i = IRQ_SIC_START; i <= IRQ_SIC_END; i++) { set_irq_chip(i, &sic_chip); - set_irq_handler(i, do_level_IRQ); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } - set_irq_handler(IRQ_CP_CPPLDINT, sic_handle_irq); - pic_unmask_irq(IRQ_CP_CPPLDINT); + set_irq_chained_handler(IRQ_CP_CPPLDINT, sic_handle_irq); } /* @@ -382,10 +431,109 @@ static struct amba_device aaci_device = { .periphid = 0, }; + +/* + * CLCD support + */ +static struct clcd_panel vga = { + .mode = { + .name = "VGA", + .refresh = 60, + .xres = 640, + .yres = 480, + .pixclock = 39721, + .left_margin = 40, + .right_margin = 24, + .upper_margin = 32, + .lower_margin = 11, + .hsync_len = 96, + .vsync_len = 2, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + }, + .width = -1, + .height = -1, + .tim2 = TIM2_BCD | TIM2_IPC, + .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1), + .bpp = 16, + .grayscale = 0, +}; + +/* + * Ensure VGA is selected. + */ +static void cp_clcd_enable(struct clcd_fb *fb) +{ + u32 val; + + if (fb->fb.var.bits_per_pixel <= 8) + val = CM_CTRL_LCDMUXSEL_VGA_8421BPP; + else if (fb->fb.var.bits_per_pixel <= 16) + val = CM_CTRL_LCDMUXSEL_VGA_16BPP + | CM_CTRL_LCDEN0 | CM_CTRL_LCDEN1 + | CM_CTRL_STATIC1 | CM_CTRL_STATIC2; + else + val = 0; /* no idea for this, don't trust the docs */ + + cm_control(CM_CTRL_LCDMUXSEL_MASK| + CM_CTRL_LCDEN0| + CM_CTRL_LCDEN1| + CM_CTRL_STATIC1| + CM_CTRL_STATIC2| + CM_CTRL_STATIC| + CM_CTRL_n24BITEN, val); +} + +static unsigned long framesize = SZ_1M; + +static int cp_clcd_setup(struct clcd_fb *fb) +{ + dma_addr_t dma; + + fb->panel = &vga; + + fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize, + &dma, GFP_KERNEL); + if (!fb->fb.screen_base) { + printk(KERN_ERR "CLCD: unable to map framebuffer\n"); + return -ENOMEM; + } + + fb->fb.fix.smem_start = dma; + fb->fb.fix.smem_len = framesize; + + return 0; +} + +static int cp_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma) +{ + return dma_mmap_writecombine(&fb->dev->dev, vma, + fb->fb.screen_base, + fb->fb.fix.smem_start, + fb->fb.fix.smem_len); +} + +static void cp_clcd_remove(struct clcd_fb *fb) +{ + dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len, + fb->fb.screen_base, fb->fb.fix.smem_start); +} + +static struct clcd_board clcd_data = { + .name = "Integrator/CP", + .check = clcdfb_check, + .decode = clcdfb_decode, + .enable = cp_clcd_enable, + .setup = cp_clcd_setup, + .mmap = cp_clcd_mmap, + .remove = cp_clcd_remove, +}; + static struct amba_device clcd_device = { .dev = { .bus_id = "mb:c0", .coherent_dma_mask = ~0, + .platform_data = &clcd_data, }, .res = { .start = INTCP_PA_CLCD_BASE, @@ -420,17 +568,23 @@ static void __init intcp_init(void) #define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable */ -static void __init intcp_init_time(void) +static void __init intcp_timer_init(void) { integrator_time_init(1000000 / HZ, TIMER_CTRL_IE); } +static struct sys_timer cp_timer = { + .init = intcp_timer_init, + .offset = integrator_gettimeoffset, +}; + MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP") - MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") - BOOT_MEM(0x00000000, 0x16000000, 0xf1600000) - BOOT_PARAMS(0x00000100) - MAPIO(intcp_map_io) - INITIRQ(intcp_init_irq) - INITTIME(intcp_init_time) - INIT_MACHINE(intcp_init) + /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ + .phys_io = 0x16000000, + .io_pg_offst = ((0xf1600000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = intcp_map_io, + .init_irq = intcp_init_irq, + .timer = &cp_timer, + .init_machine = intcp_init, MACHINE_END