友善的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_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