基于tiny210v2的linux-3.9.6内核驱动移植3:LCD移植

来源:互联网 发布:透明显示屏软件下载 编辑:程序博客网 时间:2024/05/21 11:01
   友善的tiny210v2我买的是7寸电容屏,具体型号得再查查,说是S70.
   用原本的LINUX内的SMDKV210的LCD驱动能实现LINUX LOGO的输出,但是有一定的偏差。
    主要参考:
       arm9home.net/read.php?tid=27609
    环境:
        UBUNTU 13.04
    内核:
        LINUX-3.9.6
一、修改arch/arm/mach-s5pv210/mach-smdkv210.c
      添加
    //=========================================================//
extern struct s3cfb_lcd *mini210_get_lcd(void);#defineLCD_WIDTH             800#defineLCD_HEIGHT             480#defineBYTES_PER_PIXEL          4#defineNUM_BUFFER_OVLY       \      (CONFIG_FB_S3C_NUM_OVLY_WIN * CONFIG_FB_S3C_NUM_BUF_OVLY_WIN)#defineNUM_BUFFER          \      (CONFIG_FB_S3C_NR_BUFFERS + NUM_BUFFER_OVLY)#definePXL2FIMD(pixels)   \       ((pixels) *BYTES_PER_PIXEL * NUM_BUFFER)#defineS5PV210_VIDEO_SAMSUNG_MEMSIZE_FIMC0       ( 6144 *SZ_1K)#defineS5PV210_VIDEO_SAMSUNG_MEMSIZE_FIMC1      (   16 * SZ_1K)#defineS5PV210_VIDEO_SAMSUNG_MEMSIZE_FIMC2       ( 6144 *SZ_1K)#defineS5PV210_VIDEO_SAMSUNG_MEMSIZE_MFC0       (36864 *SZ_1K)#defineS5PV210_VIDEO_SAMSUNG_MEMSIZE_MFC1       (36864 *SZ_1K)#defineS5PV210_VIDEO_SAMSUNG_MEMSIZE_FIMD      PXL2FIMD(LCD_WIDTH * LCD_HEIGHT)#defineS5PV210_VIDEO_SAMSUNG_MEMSIZE_JPEG       ( 8192 *SZ_1K)#defineS5PV210_VIDEO_SAMSUNG_MEMSIZE_G2D       ( 8192 *SZ_1K)#defineS5PV210_VIDEO_SAMSUNG_MEMSIZE_TEXSTREAM   ( 4096 * SZ_1K)#defineS5PV210_ANDROID_PMEM_MEMSIZE_PMEM       ( 5550 *SZ_1K)#defineS5PV210_ANDROID_PMEM_MEMSIZE_PMEM_GPU1   ( 1800 *SZ_1K)   //3300#defineS5PV210_ANDROID_PMEM_MEMSIZE_PMEM_ADSP   ( 1500 * SZ_1K)static struct s5p_media_device smdkv210_media_devs[] = {#if defined(CONFIG_VIDEO_MFC50)    {      .id          =S5P_MDEV_MFC,      .name       ="mfc",      .bank       = 0,      .memsize    =S5PV210_VIDEO_SAMSUNG_MEMSIZE_MFC0,      .paddr       = 0,    },    {      .id          =S5P_MDEV_MFC,      .name       ="mfc",      .bank       = 1,      .memsize    =S5PV210_VIDEO_SAMSUNG_MEMSIZE_MFC1,      .paddr       = 0,    },#endif#if defined(CONFIG_VIDEO_FIMC)    {      .id          =S5P_MDEV_FIMC0,      .name       ="fimc0",      .bank       = 1,      .memsize    =S5PV210_VIDEO_SAMSUNG_MEMSIZE_FIMC0,      .paddr       = 0,    },    {      .id          =S5P_MDEV_FIMC1,      .name       ="fimc1",      .bank       = 1,      .memsize    =S5PV210_VIDEO_SAMSUNG_MEMSIZE_FIMC1,      .paddr       = 0,    },    {      .id          =S5P_MDEV_FIMC2,      .name       ="fimc2",      .bank       = 1,      .memsize    =S5PV210_VIDEO_SAMSUNG_MEMSIZE_FIMC2,      .paddr       = 0,    },#endif#if defined(CONFIG_VIDEO_JPEG_V2)    {      .id          =S5P_MDEV_JPEG,      .name       ="jpeg",      .bank       = 0,      .memsize    =S5PV210_VIDEO_SAMSUNG_MEMSIZE_JPEG,      .paddr       = 0,    },#endif    {      .id          =S5P_MDEV_FIMD,      .name       ="fimd",      .bank       = 1,      .memsize    =S5PV210_VIDEO_SAMSUNG_MEMSIZE_FIMD,      .paddr       = 0,    },#if defined(CONFIG_VIDEO_G2D)    {      .id          =S5P_MDEV_G2D,      .name       ="g2d",      .bank       = 0,      .memsize    =S5PV210_VIDEO_SAMSUNG_MEMSIZE_G2D,      .paddr       = 0,    },#endif#if defined(CONFIG_ANDROID_PMEM)    {      .id          =S5P_MDEV_PMEM_GPU1,      .name       ="pmem_gpu1",      .bank       = 0,      .memsize    =S5PV210_ANDROID_PMEM_MEMSIZE_PMEM_GPU1,      .paddr       = 0,    },#endif};static void smdkv210_fixup_bootmem(int id, unsigned int size){    int i;    for (i = 0;i < ARRAY_SIZE(smdkv210_media_devs); i++) {       if(smdkv210_media_devs[i].id == id) {         smdkv210_media_devs[i].memsize = size;       }    }}#if defined(CONFIG_ANDROID_PMEM)static struct android_pmem_platform_data pmem_pdata = {   .name          ="pmem",   .no_allocator   = 1,   .cached          = 1,   .start          = 0,   .size          = 0,};static struct android_pmem_platform_data pmem_gpu1_pdata = {   .name          ="pmem_gpu1",   .no_allocator   = 1,   .cached          = 1,   .buffered       = 1,   .start          = 0,   .size          = 0,};static struct android_pmem_platform_data pmem_adsp_pdata = {   .name          ="pmem_adsp",   .no_allocator   = 1,   .cached          = 1,   .buffered       = 1,   .start          = 0,   .size          = 0,};     static struct platform_device pmem_device = {    .name ="android_pmem",    .id =0,    .dev = {.platform_data = &pmem_pdata },};static struct platform_device pmem_gpu1_device = {    .name ="android_pmem",    .id =1,    .dev = {.platform_data = &pmem_gpu1_pdata },};static struct platform_device pmem_adsp_device = {    .name ="android_pmem",    .id =2,    .dev = {.platform_data = &pmem_adsp_pdata },};static void __init android_pmem_set_platdata(void){#if    0   pmem_pdata.start = (u32)s5p_get_media_memory_bank(S5P_MDEV_PMEM,0);   pmem_pdata.size = (u32)s5p_get_media_memsize_bank(S5P_MDEV_PMEM,0);#endif   pmem_gpu1_pdata.start =(u32)s5p_get_media_memory_bank(S5P_MDEV_PMEM_GPU1, 0);   pmem_gpu1_pdata.size =(u32)s5p_get_media_memsize_bank(S5P_MDEV_PMEM_GPU1, 0);#if    0   pmem_adsp_pdata.start =(u32)s5p_get_media_memory_bank(S5P_MDEV_PMEM_ADSP, 0);   pmem_adsp_pdata.size =(u32)s5p_get_media_memsize_bank(S5P_MDEV_PMEM_ADSP, 0);#endif}#endif



//==========================================================//

接着在static void __init smdkv210_map_io(void)函数中加入
  
  structs3cfb_lcd *lcd = smdkv210_get_lcd();    intframe_size, fimd_size;    frame_size =lcd->width * lcd->height *BYTES_PER_PIXEL;    fimd_size =ALIGN(frame_size, PAGE_SIZE) * NUM_BUFFER;    if(frame_size > 0x200000) {       fimd_size +=ALIGN(frame_size, PAGE_SIZE) * 2;    }       fimd_size +=ALIGN(1280*720, PAGE_SIZE) * 3;    fimd_size +=ALIGN(1280*360, PAGE_SIZE) * 3 + PAGE_SIZE;    if(fimd_size != S5PV210_VIDEO_SAMSUNG_MEMSIZE_FIMD) {      smdkv210_fixup_bootmem(S5P_MDEV_FIMD, fimd_size);    }    if(lcd->width > 1280) {      smdkv210_fixup_bootmem(S5P_MDEV_FIMC2, 12288 * SZ_1K);    }   s5p_reserve_bootmem(smdkv210_media_devs,         ARRAY_SIZE(smdkv210_media_devs), S5P_RANGE_MFC);


//===============================================//
二、在arch/arm/mach-s5pv210/include/mach 下建立media.h
 

#ifndef _S5PV210_MEDIA_H#define _S5PV210_MEDIA_H#defineS5P_MDEV_FIMC0     0#defineS5P_MDEV_FIMC1     1#defineS5P_MDEV_FIMC2     2#defineS5P_MDEV_TV        3#defineS5P_MDEV_MFC       4#defineS5P_MDEV_JPEG      5#defineS5P_MDEV_PMEM      6#define S5P_MDEV_PMEM_GPU1  7#define S5P_MDEV_PMEM_ADSP  8#define S5P_MDEV_TEXSTREAM  9#defineS5P_MDEV_FIMD      10#defineS5P_MDEV_G2D       11#defineS5P_MDEV_MAX       12#defineS5P_RANGE_MFC      SZ_256M#endif


//=================================================//
三、在arch/arm/plat-samsung/include/plat新建文件media.h


#ifndef _S5P_MEDIA_H#define _S5P_MEDIA_H#include <linux/types.h>#include <asm/setup.h>struct s5p_media_device {   u32       id;    constchar   *name;   u32       bank;   size_t      memsize;   dma_addr_t   paddr;};extern struct meminfo meminfo;extern dma_addr_t s5p_get_media_memory_bank(int dev_id, intbank);extern size_t s5p_get_media_memsize_bank(int dev_id, intbank);extern dma_addr_t s5p_get_media_membase_bank(int bank);extern void s5p_reserve_bootmem(struct s5p_media_device *mdevs, intnr_mdevs, size_t boundary);#endif


//===============================================//
四、在/arch/arm/plat-samsung/新建bootmem.c


#include <linux/err.h>#include <linux/memblock.h>#include <linux/mm.h>#include <linux/swap.h>#include <asm/setup.h>#include <linux/io.h>#include <mach/memory.h>#include <plat/media.h>#include <mach/media.h>static struct s5p_media_device *media_devs;static int nr_media_devs;static dma_addr_t media_base[NR_BANKS];static struct s5p_media_device *s5p_get_media_device(int dev_id,int bank){    structs5p_media_device *mdev = NULL;    int i = 0,found = 0;    if (dev_id< 0)       returnNULL;    while(!found && (i <nr_media_devs)) {       mdev =&media_devs[i];       if(mdev->id == dev_id&& mdev->bank ==bank)          found =1;       else          i++;    }    if(!found)       mdev =NULL;    returnmdev;}dma_addr_t s5p_get_media_memory_bank(int dev_id, int bank){    structs5p_media_device *mdev;    mdev =s5p_get_media_device(dev_id, bank);    if (!mdev){      printk(KERN_ERR "invalid media device %d\n", dev_id);       return0;    }    if(!mdev->paddr) {      printk(KERN_ERR "no memory for %s\n",mdev->name);       return0;    }    returnmdev->paddr;}EXPORT_SYMBOL(s5p_get_media_memory_bank);size_t s5p_get_media_memsize_bank(int dev_id, int bank){    structs5p_media_device *mdev;    mdev =s5p_get_media_device(dev_id, bank);    if (!mdev){      printk(KERN_ERR "invalid media device %d\n", dev_id);       return0;    }    returnmdev->memsize;}EXPORT_SYMBOL(s5p_get_media_memsize_bank);dma_addr_t s5p_get_media_membase_bank(int bank){    if (bank> meminfo.nr_banks) {      printk(KERN_ERR "invalid bank.\n");       return-EINVAL;    }    returnmedia_base[bank];}EXPORT_SYMBOL(s5p_get_media_membase_bank);void s5p_reserve_bootmem(struct s5p_media_device *mdevs,          int nr_mdevs, size_t boundary){    structs5p_media_device *mdev;    u64 start,end;    int i,ret;    media_devs =mdevs;   nr_media_devs = nr_mdevs;    for (i = 0;i < meminfo.nr_banks; i++)      media_base[i] = meminfo.bank[i].start + meminfo.bank[i].size;    for (i = 0;i < nr_media_devs; i++) {       mdev =&media_devs[i];       if(mdev->memsize <= 0)         continue;       if(!mdev->paddr) {          start =meminfo.bank[mdev->bank].start;          end = start+ meminfo.bank[mdev->bank].size;          if (boundary&& (boundary < end -start))             start = end- boundary;         mdev->paddr = memblock_find_in_range(start,end,                  mdev->memsize, PAGE_SIZE);       }       ret =memblock_remove(mdev->paddr,mdev->memsize);       if (ret< 0)         pr_err("memblock_reserve(%x, %x) failed\n",            mdev->paddr, mdev->memsize);       if(media_base[mdev->bank] >mdev->paddr)         media_base[mdev->bank] =mdev->paddr;      printk(KERN_INFO "s5p: %lu kbytes system memory reserved "          "for %s at0xx, %d-bank base(0xx)\n",          (unsignedlong) (mdev->memsize>> 10), mdev->name,mdev->paddr,         mdev->bank,media_base[mdev->bank]);    }}int dma_needs_bounce(struct device *dev, dma_addr_t addr, size_tsize){    return0;}


//==================================================//
五、在arch/arm/mach-s5pv210 下建立smdkv210-lcds.c


#include <linux/kernel.h>#include <linux/types.h>#include <linux/init.h>#include <linux/gpio.h>#include <plat/fb.h>#include <mach/gpio.h>#include <mach/regs-gpio.h>#include<../../../drivers/video/s3cfb.h>static struct s3cfb_lcd wvga_w50 = {    .width=800,    .height =480,    .p_width =108,    .p_height =64,    .bpp =32,    .freq =75,    .timing ={       .h_fp =40,       .h_bp =40,       .h_sw =48,       .v_fp =20,       .v_fpe =1,       .v_bp =20,       .v_bpe =1,       .v_sw =12,    },    .polarity ={       .rise_vclk =0,       .inv_hsync =1,       .inv_vsync =1,       .inv_vden =0,    },};static struct s3cfb_lcd wvga_a70 = {    .width =800,    .height =480,    .p_width =152,    .p_height =90,    .bpp =32,    .freq =85,    .timing ={       .h_fp =40,       .h_bp =40,       .h_sw =48,       .v_fp =17,       .v_fpe =1,       .v_bp =29,       .v_bpe =1,       .v_sw =24,    },    .polarity ={       .rise_vclk =0,       .inv_hsync =1,       .inv_vsync =1,       .inv_vden =0,    },};static struct s3cfb_lcd wvga_s70 = {    .width =800,    .height =480,    .p_width =154,    .p_height =96,    .bpp =32,    .freq =65,    .timing ={       .h_fp =80,       .h_bp =36,       .h_sw =10,       .v_fp =22,       .v_fpe =1,       .v_bp =15,       .v_bpe =1,       .v_sw =8,    },    .polarity ={       .rise_vclk =0,       .inv_hsync =1,       .inv_vsync =1,       .inv_vden =0,    },};static struct s3cfb_lcd wvga_h43 = {    .width =480,    .height =272,    .p_width =96,    .p_height =54,    .bpp =32,    .freq =65,    .timing ={       .h_fp=  5,       .h_bp =40,       .h_sw=  2,       .v_fp=  8,       .v_fpe =1,       .v_bp=  8,       .v_bpe =1,       .v_sw=  2,    },    .polarity ={       .rise_vclk =0,       .inv_hsync =1,       .inv_vsync =1,       .inv_vden =0,    },};static struct s3cfb_lcd wvga_a97 = {    .width =1024,    .height =768,    .p_width =200,    .p_height =150,    .bpp =32,    .freq =62,    .timing ={       .h_fp =12,       .h_bp =12,       .h_sw =4,       .v_fp =8,       .v_fpe =1,       .v_bp =8,       .v_bpe =1,       .v_sw=  4,    },    .polarity ={       .rise_vclk =0,       .inv_hsync =1,       .inv_vsync =1,       .inv_vden =0,    },};static struct s3cfb_lcd wvga_l80 = {    .width=640,    .height =480,    .p_width =160,    .p_height =120,    .bpp =32,    .freq =65,    .timing ={       .h_fp =35,       .h_bp =53,       .h_sw =73,       .v_fp =3,       .v_fpe =1,       .v_bp =29,       .v_bpe =1,       .v_sw =6,    },    .polarity ={       .rise_vclk =0,       .inv_hsync =1,       .inv_vsync =1,       .inv_vden =0,    },};static struct s3cfb_lcd wvga_g10 = {    .width=640,    .height =480,    .p_width =213,    .p_height =160,    .bpp =32,    .freq =65,    .timing ={       .h_fp =0x3c,       .h_bp =0x63,       .h_sw =1,       .v_fp =0x0a,       .v_fpe =1,       .v_bp =0x22,       .v_bpe =1,       .v_sw =1,    },    .polarity ={       .rise_vclk =0,       .inv_hsync =0,       .inv_vsync =0,       .inv_vden =0,    },};static struct s3cfb_lcd wvga_a56 = {    .width=640,    .height =480,    .p_width =112,    .p_height =84,    .bpp =32,    .freq =65,    .timing ={       .h_fp =16,       .h_bp =134,       .h_sw =10,       .v_fp =32,       .v_fpe =1,       .v_bp =11,       .v_bpe =1,       .v_sw =2,    },    .polarity ={       .rise_vclk =1,       .inv_hsync =1,       .inv_vsync =1,       .inv_vden =0,    },};static struct s3cfb_lcd wvga_w101 = {    .width=1024,    .height =600,    .p_width =204,    .p_height =120,    .bpp =32,    .freq =60,    .timing ={       .h_fp =40,       .h_bp =40,       .h_sw =120,       .v_fp =10,       .v_fpe =1,       .v_bp =10,       .v_bpe =1,       .v_sw =12,    },    .polarity ={       .rise_vclk =0,       .inv_hsync =1,       .inv_vsync =1,       .inv_vden =0,    },};static struct s3cfb_lcd wvga_w35 = {    .width=320,    .height =240,    .p_width =70,    .p_height =52,    .bpp =32,    .freq =65,    .timing ={       .h_fp=  4,       .h_bp =70,       .h_sw=  4,       .v_fp=  4,       .v_fpe =1,       .v_bp =12,       .v_bpe =1,       .v_sw=  4,    },    .polarity ={       .rise_vclk =1,       .inv_hsync =0,       .inv_vsync =0,       .inv_vden =0,    },};static struct s3cfb_lcd hdmi_def = {    .width =1920,    .height =1080,    .p_width =480,    .p_height =320,    .bpp =32,    .freq =62,    .timing ={       .h_fp =12,       .h_bp =12,       .h_sw =4,       .v_fp =8,       .v_fpe =1,       .v_bp =8,       .v_bpe =1,       .v_sw=  4,    },    .polarity ={       .rise_vclk =0,       .inv_hsync =1,       .inv_vsync =1,       .inv_vden =0,    },};static struct hdmi_config {    char*name;    intwidth;    intheight;} smdkv210_hdmi_config[] = {    {"HDMI1080P60",   1920, 1080 },    {"HDMI1080I60",   1920, 1080 },    {"HDMI1080P30",   1920, 1080 },    {"HDMI1080P60D",    960,  536 },    {"HDMI1080I60D",    960,  536 },    {"HDMI1080P30D",    960,  536 },    {"HDMI720P60",      1280,  720 },    {"HDMI720P60D",    640,  360 },    {"HDMI576P16X9",    720,  576 },    {"HDMI576P16X9D",    720,  576 },    {"HDMI576P4X3",    720,  576 },    {"HDMI576P4X3D",    720,  576 },    {"HDMI480P16X9",    720,  480 },    {"HDMI480P16X9D",    720,  480 },    {"HDMI480P4X3",    720,  480 },    {"HDMI480P4X3D",    720,  480 },};static struct {    char*name;    structs3cfb_lcd *lcd;    intctp;} smdkv210_lcd_config[] = {    {"W50", &wvga_w50,  0 },    {"A70", &wvga_a70,  0 },    {"S70", &wvga_s70,  1 },    {"H43", &wvga_h43,  1 },    {"A97", &wvga_a97,  0 },    {"L80", &wvga_l80,  0 },    {"G10", &wvga_g10,  0 },    {"A56", &wvga_a56,  0 },    { "W101",&wvga_w101, 0 },    {"W35", &wvga_w35,  0 },    {"HDM", &hdmi_def,  0},   };static int lcd_idx = 2;static int __init smdkv210_setup_lcd(char *str){    int i;    if(!strncasecmp("HDMI", str, 4)) {       structhdmi_config *cfg = &smdkv210_hdmi_config[0];       structs3cfb_lcd *lcd;       lcd_idx =ARRAY_SIZE(smdkv210_lcd_config) - 1;       lcd =smdkv210_lcd_config[lcd_idx].lcd;      lcd->args = lcd_idx;       for (i = 0;i < ARRAY_SIZE(smdkv210_hdmi_config); i++, cfg++){          if(!strcasecmp(cfg->name, str)) {            lcd->width = cfg->width;            lcd->height = cfg->height;             goto__ret;          }       }    }    for (i = 0;i < ARRAY_SIZE(smdkv210_lcd_config); i++) {       if(!strcasecmp(smdkv210_lcd_config[i].name, str)) {          lcd_idx =i;         smdkv210_lcd_config[lcd_idx].lcd->args =lcd_idx;          break;       }    }__ret:   printk("smdkv210: %s selected\n",smdkv210_lcd_config[lcd_idx].name);    return0;}early_param("lcd", smdkv210_setup_lcd);struct s3cfb_lcd *smdkv210_get_lcd(void){    returnsmdkv210_lcd_config[lcd_idx].lcd;}void smdkv210_get_lcd_res(int *w, int *h){    structs3cfb_lcd *lcd = smdkv210_lcd_config[lcd_idx].lcd;    if (w)       *w =lcd->width;    if (h)       *h =lcd->height;   return;}EXPORT_SYMBOL(smdkv210_get_lcd_res);


六、修改该目录下的Makefile将obj-$(CONFIG_MACH_SMDKV210)   += mach-smdkv210.o修改为obj-$(CONFIG_MACH_SMDKV210)   += mach-smdkv210.o smdkv210-lcds.o七、在drivers/video下新建s3cfb.h
#ifndef _S3CFB_H#define _S3CFB_H#ifdef __KERNEL__#include <linux/wait.h>#include <linux/mutex.h>#include <linux/fb.h>#ifdef CONFIG_HAS_WAKELOCK#include <linux/wakelock.h>#include <linux/earlysuspend.h>#endif#include <plat/fb.h>#endif#defineS3CFB_NAME      "s3cfb"#define S3CFB_AVALUE(r, g,b)    (((r& 0xf) << 8) |\             ((g& 0xf) << 4) |\             ((b& 0xf) << 0))#define S3CFB_CHROMA(r, g,b)    (((r& 0xff) << 16) |\             ((g& 0xff) << 8) |\             ((b& 0xff) << 0))enum s3cfb_data_path_t {   DATA_PATH_FIFO = 0,   DATA_PATH_DMA = 1,   DATA_PATH_IPC = 2,};enum s3cfb_alpha_t {   PLANE_BLENDING,   PIXEL_BLENDING,};enum s3cfb_chroma_dir_t {   CHROMA_FG,   CHROMA_BG,};enum s3cfb_output_t {   OUTPUT_RGB,   OUTPUT_ITU,   OUTPUT_I80LDI0,   OUTPUT_I80LDI1,   OUTPUT_WB_RGB,   OUTPUT_WB_I80LDI0,   OUTPUT_WB_I80LDI1,};enum s3cfb_rgb_mode_t {    MODE_RGB_P =0,    MODE_BGR_P =1,    MODE_RGB_S =2,    MODE_BGR_S =3,};enum s3cfb_mem_owner_t {   DMA_MEM_NONE   = 0,   DMA_MEM_FIMD   = 1,   DMA_MEM_OTHER   = 2,};struct s3cfb_alpha {   enum      s3cfb_alpha_t mode;   int      channel;    unsignedint   value;};struct s3cfb_chroma {   int      enabled;   int      blended;    unsignedint   key;    unsignedint   comp_key;    unsignedint   alpha;   enum      s3cfb_chroma_dir_t dir;};struct s3cfb_lcd_polarity {   int   rise_vclk;   int   inv_hsync;   int   inv_vsync;   int   inv_vden;};struct s3cfb_lcd_timing {   int   h_fp;   int   h_bp;   int   h_sw;   int   v_fp;   int   v_fpe;   int   v_bp;   int   v_bpe;   int   v_sw;};struct s3cfb_lcd {   int   width;   int   height;   int   p_width;   int   p_height;   int   bpp;   int   freq;   struct   s3cfb_lcd_timing timing;   struct   s3cfb_lcd_polarity polarity;   void   (*init_ldi)(void);   void   (*deinit_ldi)(void);    unsignedlong args;};struct s3cfb_window {   int          id;   int         enabled;   int         in_use;   int          x;   int          y;   enum         s3cfb_data_path_t path;   enum         s3cfb_mem_owner_t owner;    unsignedint   other_mem_addr;    unsignedint   other_mem_size;   int         local_channel;   int         dma_burst;    unsignedint      pseudo_pal[16];   struct          s3cfb_alphaalpha;   struct          s3cfb_chromachroma;};struct s3cfb_global {       void__iomem       *regs;    structmutex       lock;    structdevice       *dev;    structclk      *clock;    structregulator   *regulator;    structregulator   *vcc_lcd;    structregulator   *vlcd;   int          irq;    structfb_info       **fb;    structcompletion   fb_complete;      int         enabled;   int          dsi;   int         interlace;    enums3cfb_output_t   output;    enums3cfb_rgb_mode_t   rgb_mode;    structs3cfb_lcd   *lcd;   u32         pixclock_hz;#ifdef CONFIG_HAS_WAKELOCK    structearly_suspend   early_suspend;    structwake_lock   idle_lock;#endif#ifdef CONFIG_CPU_FREQ    structnotifier_block   freq_transition;    structnotifier_block   freq_policy;#endif};struct s3cfb_user_window {    int x;    int y;};struct s3cfb_user_plane_alpha {   int      channel;    unsignedchar   red;    unsignedchar   green;    unsignedchar   blue;};struct s3cfb_user_chroma {   int      enabled;    unsignedchar   red;    unsignedchar   green;    unsignedchar   blue;};struct s3cfb_next_info {    unsigned intphy_start_addr;    unsigned intxres;          unsigned intyres;    unsigned intxres_virtual;       unsigned intyres_virtual;    unsigned intxoffset;          unsigned intyoffset;          unsigned intlcd_offset_x;    unsigned intlcd_offset_y;};#defineS3CFB_WIN_POSITION       _IOW('F',203, \                   structs3cfb_user_window)#defineS3CFB_WIN_SET_PLANE_ALPHA   _IOW('F', 204, \                   structs3cfb_user_plane_alpha)#defineS3CFB_WIN_SET_CHROMA       _IOW('F',205, \                   structs3cfb_user_chroma)#defineS3CFB_SET_VSYNC_INT       _IOW('F',206, u32)#defineS3CFB_GET_VSYNC_INT_STATUS   _IOR('F', 207, u32)#defineS3CFB_GET_LCD_WIDTH       _IOR('F',302, int)#defineS3CFB_GET_LCD_HEIGHT       _IOR('F',303, int)#defineS3CFB_SET_WRITEBACK       _IOW('F',304, u32)#defineS3CFB_GET_CURR_FB_INFO       _IOR('F',305, struct s3cfb_next_info)#defineS3CFB_SET_WIN_ON       _IOW('F',306, u32)#defineS3CFB_SET_WIN_OFF       _IOW('F',307, u32)#defineS3CFB_SET_WIN_PATH       _IOW('F',308, \                   enums3cfb_data_path_t)#defineS3CFB_SET_WIN_ADDR       _IOW('F',309, unsigned long)#defineS3CFB_SET_WIN_MEM       _IOW('F',310, \                   enums3cfb_mem_owner_t)#defineS3CFB_GET_LCD_ADDR       _IOR('F',311, int)extern int soft_cursor(struct fb_info *info, struct fb_cursor*cursor);extern void s3cfb_set_lcd_info(struct s3cfb_global *ctrl);extern struct s3c_platform_fb *to_fb_plat(struct device*dev);extern void s3cfb_check_line_count(struct s3cfb_global*ctrl);extern int s3cfb_set_output(struct s3cfb_global *ctrl);extern int s3cfb_set_display_mode(struct s3cfb_global *ctrl);extern int s3cfb_display_on(struct s3cfb_global *ctrl);extern int s3cfb_display_off(struct s3cfb_global *ctrl);extern int s3cfb_frame_off(struct s3cfb_global *ctrl);extern int s3cfb_set_clock(struct s3cfb_global *ctrl);extern int s3cfb_set_polarity(struct s3cfb_global *ctrl);extern int s3cfb_set_timing(struct s3cfb_global *ctrl);extern int s3cfb_set_lcd_size(struct s3cfb_global *ctrl);extern int s3cfb_set_global_interrupt(struct s3cfb_global *ctrl,int enable);extern int s3cfb_set_vsync_interrupt(struct s3cfb_global *ctrl, intenable);extern int s3cfb_get_vsync_interrupt(struct s3cfb_global*ctrl);extern int s3cfb_set_fifo_interrupt(struct s3cfb_global *ctrl, intenable);extern int s3cfb_clear_interrupt(struct s3cfb_global *ctrl);extern int s3cfb_channel_localpath_on(struct s3cfb_global *ctrl,int id);extern int s3cfb_channel_localpath_off(struct s3cfb_global *ctrl,int id);extern int s3cfb_window_on(struct s3cfb_global *ctrl, intid);extern int s3cfb_window_off(struct s3cfb_global *ctrl, intid);extern int s3cfb_win_map_on(struct s3cfb_global *ctrl, int id, intcolor);extern int s3cfb_win_map_off(struct s3cfb_global *ctrl, intid);extern int s3cfb_set_window_control(struct s3cfb_global *ctrl, intid);extern int s3cfb_set_alpha_blending(struct s3cfb_global *ctrl, intid);extern int s3cfb_set_window_position(struct s3cfb_global *ctrl, intid);extern int s3cfb_set_window_size(struct s3cfb_global *ctrl, intid);extern int s3cfb_set_buffer_address(struct s3cfb_global *ctrl, intid);extern int s3cfb_set_buffer_size(struct s3cfb_global *ctrl, intid);extern int s3cfb_set_chroma_key(struct s3cfb_global *ctrl, intid);#ifdef CONFIG_HAS_WAKELOCK#ifdef CONFIG_HAS_EARLYSUSPENDextern void s3cfb_early_suspend(struct early_suspend *h);extern void s3cfb_late_resume(struct early_suspend *h);#endif#endif#if defined(CONFIG_FB_S3C_TL2796)extern void tl2796_ldi_init(void);extern void tl2796_ldi_enable(void);extern void tl2796_ldi_disable(void);extern void lcd_cfg_gpio_early_suspend(void);extern void lcd_cfg_gpio_late_resume(void);#endif#endif


//=================================================//
八、修改driver/video/Kconfig
添加

config FB_S3C_DEFAULT_WINDOW
    int "DefaultWindow (0-4)"
    range 04
    depends onFB_S3C
    default"2"
   ---help---
     This indicates the default window number, andwhich is used as console framebuffer

config FB_S3C_NR_BUFFERS
    int "Numberof frame buffers (1-3)"
    depends onFB_S3C
    default"2"
   ---help---
     This indicates the number of buffers for pandisplay,
     1 means no pan display and
     2 means the double size of video buffer will beallocated for default window

config FB_S3C_NUM_OVLY_WIN
    int "Numberof overlay window (0-3)"
    range 03
    depends onFB_S3C
    default"1"
   ---help---
     This indicates the number of overlay windows forvideo rendering

config FB_S3C_NUM_BUF_OVLY_WIN
    int "Numberof buffers for overlay window (2-3)"
    range 23
    depends onFB_S3C
    default"3"
   ---help---
     This indicates the number of buffers for overlaywindows


最后make,测试ing





原创粉丝点击