1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > win驱动移植linux LCD移植 - 基于Tiny210v2的Linux-3.9.6内核驱动移植_Linux编程_L

win驱动移植linux LCD移植 - 基于Tiny210v2的Linux-3.9.6内核驱动移植_Linux编程_L

时间:2020-03-08 07:19:07

相关推荐

win驱动移植linux LCD移植 - 基于Tiny210v2的Linux-3.9.6内核驱动移植_Linux编程_L

友善的tiny210v2我买的是7寸电容屏,具体型号得再查查,说是S70.

用原本的LINUX内的SMDKV210的LCD驱动能实现LINUX LOGO的输出,但是有一定的偏差。

主要参考:

/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_WIDTH800

#defineLCD_HEIGHT480

#defineBYTES_PER_PIXEL4

#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

#include

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

#include

#include

#include

#include

#include

#include

#include

#include

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

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

#include

#include

#include

#include

#include

#include

#include<..>

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

#include

#include

#ifdef CONFIG_HAS_WAKELOCK

#include

#include

#endif

#include

#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 {

intid;

int enabled;

int in_use;

intx;

inty;

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];

structs3cfb_alphaalpha;

structs3cfb_chromachroma;

};

struct s3cfb_global {

void__iomem *regs;

structmutex lock;

structdevice *dev;

structclk *clock;

structregulator *regulator;

structregulator *vcc_lcd;

structregulator *vlcd;

intirq;

structfb_info **fb;

structcompletion fb_complete;

int enabled;

intdsi;

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_EARLYSUSPEND

extern 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

win驱动移植linux LCD移植 - 基于Tiny210v2的Linux-3.9.6内核驱动移植_Linux编程_Linux公社-Linux系统门户网站...

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。