181 lines
3.8 KiB
C
181 lines
3.8 KiB
C
#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_wc(&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_wc(&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_wc(&fb->dev->dev, fb->fb.fix.smem_len, fb->fb.screen_base,
|
|
fb->fb.fix.smem_start);
|
|
}
|