| #include <linux/device.h> | |
| #include <linux/dma-mapping.h> | |
| #include <linux/amba/bus.h> | |
| #include <linux/amba/clcd.h> | |
| #include <linux/platform_data/video-clcd-versatile.h> | |
| 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_BGR | CNTL_LCDVCOMP(1), | |
| .caps = CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888, | |
| .bpp = 16, | |
| }; | |
| static struct clcd_panel xvga = { | |
| .mode = { | |
| .name = "XVGA", | |
| .refresh = 60, | |
| .xres = 1024, | |
| .yres = 768, | |
| .pixclock = 15748, | |
| .left_margin = 152, | |
| .right_margin = 48, | |
| .upper_margin = 23, | |
| .lower_margin = 3, | |
| .hsync_len = 104, | |
| .vsync_len = 4, | |
| .sync = 0, | |
| .vmode = FB_VMODE_NONINTERLACED, | |
| }, | |
| .width = -1, | |
| .height = -1, | |
| .tim2 = TIM2_BCD | TIM2_IPC, | |
| .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1), | |
| .caps = CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888, | |
| .bpp = 16, | |
| }; | |
| /* Sanyo TM38QV67A02A - 3.8 inch QVGA (320x240) Color TFT */ | |
| static struct clcd_panel sanyo_tm38qv67a02a = { | |
| .mode = { | |
| .name = "Sanyo TM38QV67A02A", | |
| .refresh = 116, | |
| .xres = 320, | |
| .yres = 240, | |
| .pixclock = 100000, | |
| .left_margin = 6, | |
| .right_margin = 6, | |
| .upper_margin = 5, | |
| .lower_margin = 5, | |
| .hsync_len = 6, | |
| .vsync_len = 6, | |
| .sync = 0, | |
| .vmode = FB_VMODE_NONINTERLACED, | |
| }, | |
| .width = -1, | |
| .height = -1, | |
| .tim2 = TIM2_BCD, | |
| .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1), | |
| .caps = CLCD_CAP_5551, | |
| .bpp = 16, | |
| }; | |
| static struct clcd_panel sanyo_2_5_in = { | |
| .mode = { | |
| .name = "Sanyo QVGA Portrait", | |
| .refresh = 116, | |
| .xres = 240, | |
| .yres = 320, | |
| .pixclock = 100000, | |
| .left_margin = 20, | |
| .right_margin = 10, | |
| .upper_margin = 2, | |
| .lower_margin = 2, | |
| .hsync_len = 10, | |
| .vsync_len = 2, | |
| .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | |
| .vmode = FB_VMODE_NONINTERLACED, | |
| }, | |
| .width = -1, | |
| .height = -1, | |
| .tim2 = TIM2_IVS | TIM2_IHS | TIM2_IPC, | |
| .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1), | |
| .caps = CLCD_CAP_5551, | |
| .bpp = 16, | |
| }; | |
| /* Epson L2F50113T00 - 2.2 inch 176x220 Color TFT */ | |
| static struct clcd_panel epson_l2f50113t00 = { | |
| .mode = { | |
| .name = "Epson L2F50113T00", | |
| .refresh = 390, | |
| .xres = 176, | |
| .yres = 220, | |
| .pixclock = 62500, | |
| .left_margin = 3, | |
| .right_margin = 2, | |
| .upper_margin = 1, | |
| .lower_margin = 0, | |
| .hsync_len = 3, | |
| .vsync_len = 2, | |
| .sync = 0, | |
| .vmode = FB_VMODE_NONINTERLACED, | |
| }, | |
| .width = -1, | |
| .height = -1, | |
| .tim2 = TIM2_BCD | TIM2_IPC, | |
| .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1), | |
| .caps = CLCD_CAP_5551, | |
| .bpp = 16, | |
| }; | |
| static struct clcd_panel *panels[] = { | |
| &vga, | |
| &xvga, | |
| &sanyo_tm38qv67a02a, | |
| &sanyo_2_5_in, | |
| &epson_l2f50113t00, | |
| }; | |
| struct clcd_panel *versatile_clcd_get_panel(const char *name) | |
| { | |
| int i; | |
| for (i = 0; i < ARRAY_SIZE(panels); i++) | |
| if (strcmp(panels[i]->mode.name, name) == 0) | |
| break; | |
| if (i < ARRAY_SIZE(panels)) | |
| return panels[i]; | |
| pr_err("CLCD: couldn't get parameters for panel %s\n", name); | |
| return NULL; | |
| } | |
| int versatile_clcd_setup_dma(struct clcd_fb *fb, unsigned long framesize) | |
| { | |
| dma_addr_t dma; | |
| fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize, | |
| &dma, GFP_KERNEL); | |
| if (!fb->fb.screen_base) { | |
| pr_err("CLCD: unable to map framebuffer\n"); | |
| return -ENOMEM; | |
| } | |
| fb->fb.fix.smem_start = dma; | |
| fb->fb.fix.smem_len = framesize; | |
| return 0; | |
| } | |
| int versatile_clcd_mmap_dma(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); | |
| } | |
| void versatile_clcd_remove_dma(struct clcd_fb *fb) | |
| { | |
| dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len, | |
| fb->fb.screen_base, fb->fb.fix.smem_start); | |
| } |