s3c6410_LCD & frame buffer 驱动分析(二)

深夜了,我依旧是这么的难眠,总有那么多伤心的往事在脑海中断断续续的浮现,我不知道为什么会这样,或许吧,有些东西我真的该放弃了.可是一直纠结着。我是不是没药可救了?我想不是,我想我还留了一点什么悬念吧。

//该函数在prob中被调用,用来初始化5个窗口的,看了好几次,模模糊糊的来了一点头绪,先不管那么多,做个笔记再说。

int s3cfb_init_registers(s3cfb_info_t *fbi)

{
struct clk *lcd_clock;//LCD时钟来源
struct fb_var_screeninfo *var = &fbi->fb.var;//可变参数
unsigned long flags = 0, page_width = 0, offset = 0;
unsigned long video_phy_temp_f1 = fbi->screen_dma_f1;/**缓存物理地址*/
unsigned long video_phy_temp_f2 = fbi->screen_dma_f2;
int win_num = fbi->win_id;

/* Initialise LCD with values from hare */
local_irq_save(flags);

page_width = var->xres * s3cfb_fimd.bytes_per_pixel;
offset = (var->xres_virtual - var->xres) * s3cfb_fimd.bytes_per_pixel;/**偏移量,应该就是左边界距离吧
if (win_num == 0) {
s3cfb_fimd.vidcon0 = s3cfb_fimd.vidcon0 & ~(S3C_VIDCON0_ENVID_ENABLE | S3C_VIDCON0_ENVID_F_ENABLE);
writel(s3cfb_fimd.vidcon0, S3C_VIDCON0);//视频输出及显示控制信号使能

lcd_clock = clk_get(NULL, "lcd");//获取视频始终源
s3cfb_fimd.vidcon0 |= S3C_VIDCON0_CLKVAL_F((int) ((clk_get_rate(lcd_clock) / s3cfb_fimd.pixclock) - 1));
#if defined(CONFIG_FB_S3C_EXT_VIRTUAL_SCREEN)
offset = 0;
s3cfb_fimd.vidw00add0b0 = video_phy_temp_f1;
s3cfb_fimd.vidw00add0b1 = video_phy_temp_f2;
s3cfb_fimd.vidw00add1b0 = S3C_VIDWxxADD1_VBASEL_F((unsigned long) video_phy_temp_f1 + (page_width + offset) * (var->yres));
s3cfb_fimd.vidw00add1b1 = S3C_VIDWxxADD1_VBASEL_F((unsigned long) video_phy_temp_f2 + (page_width + offset) * (var->yres));
#endif
}

writel(video_phy_temp_f1, S3C_VIDW00ADD0B0 + (0x08 * win_num));
writel(S3C_VIDWxxADD1_VBASEL_F((unsigned long) video_phy_temp_f1 + (page_width + offset) * (var->yres)), S3C_VIDW00ADD1B0 + (0x08 * win_num));
writel(S3C_VIDWxxADD2_OFFSIZE_F(offset) | (S3C_VIDWxxADD2_PAGEWIDTH_F(page_width)), S3C_VIDW00ADD2 + (0x04 * win_num));

if (win_num < 2) {
writel(video_phy_temp_f2, S3C_VIDW00ADD0B1 + (0x08 * win_num));
writel(S3C_VIDWxxADD1_VBASEL_F((unsigned long) video_phy_temp_f2 + (page_width + offset) * (var->yres)), S3C_VIDW00ADD1B1 + (0x08 * win_num));
}
/*********下面就是往各种寄存器里面写东西,初始化各个窗口所对应的寄存器等**/
switch (win_num) {
case 0:
writel(s3cfb_fimd.wincon0, S3C_WINCON0);
writel(s3cfb_fimd.vidcon0, S3C_VIDCON0);
writel(s3cfb_fimd.vidcon1, S3C_VIDCON1);
writel(s3cfb_fimd.vidtcon0, S3C_VIDTCON0);
writel(s3cfb_fimd.vidtcon1, S3C_VIDTCON1);
writel(s3cfb_fimd.vidtcon2, S3C_VIDTCON2);
writel(s3cfb_fimd.dithmode, S3C_DITHMODE);
writel(s3cfb_fimd.vidintcon0, S3C_VIDINTCON0);
writel(s3cfb_fimd.vidintcon1, S3C_VIDINTCON1);
writel(s3cfb_fimd.vidosd0a, S3C_VIDOSD0A);
writel(s3cfb_fimd.vidosd0b, S3C_VIDOSD0B);
writel(s3cfb_fimd.vidosd0c, S3C_VIDOSD0C);
writel(s3cfb_fimd.wpalcon, S3C_WPALCON);
/**使能视频输出和VEDIO控制信号**/
s3cfb_onoff_win(fbi, ON);
break;

case 1:
writel(s3cfb_fimd.wincon1, S3C_WINCON1);
writel(s3cfb_fimd.vidosd1a, S3C_VIDOSD1A);
writel(s3cfb_fimd.vidosd1b, S3C_VIDOSD1B);
writel(s3cfb_fimd.vidosd1c, S3C_VIDOSD1C);
writel(s3cfb_fimd.vidosd1d, S3C_VIDOSD1D);
writel(s3cfb_fimd.wpalcon, S3C_WPALCON);

s3cfb_onoff_win(fbi, OFF);
break;

case 2:
writel(s3cfb_fimd.wincon2, S3C_WINCON2);
writel(s3cfb_fimd.vidosd2a, S3C_VIDOSD2A);
writel(s3cfb_fimd.vidosd2b, S3C_VIDOSD2B);
writel(s3cfb_fimd.vidosd2c, S3C_VIDOSD2C);
writel(s3cfb_fimd.vidosd2d, S3C_VIDOSD2D);
writel(s3cfb_fimd.wpalcon, S3C_WPALCON);

s3cfb_onoff_win(fbi, OFF);
break;

case 3:
writel(s3cfb_fimd.wincon3, S3C_WINCON3);
writel(s3cfb_fimd.vidosd3a, S3C_VIDOSD3A);
writel(s3cfb_fimd.vidosd3b, S3C_VIDOSD3B);
writel(s3cfb_fimd.vidosd3c, S3C_VIDOSD3C);
writel(s3cfb_fimd.wpalcon, S3C_WPALCON);

s3cfb_onoff_win(fbi, OFF);
break;

case 4:
writel(s3cfb_fimd.wincon4, S3C_WINCON4);
writel(s3cfb_fimd.vidosd4a, S3C_VIDOSD4A);
writel(s3cfb_fimd.vidosd4b, S3C_VIDOSD4B);
writel(s3cfb_fimd.vidosd4c, S3C_VIDOSD4C);
writel(s3cfb_fimd.wpalcon, S3C_WPALCON);

s3cfb_onoff_win(fbi, OFF);
break;
}

local_irq_restore(flags);

return 0;
}



你可能感兴趣的:(buffer)