一、修改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_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