您的位置:首页 > 编程语言

lk 中的显示驱动代码分析

2017-10-19 17:20 567 查看
一.相关的结构体为:
1. display_primary_path_context 结构体
typedef struct {
int                             state;
int                         need_trigger_overlay;
DISP_PRIMARY_PATH_MODE  mode;
unsigned int                    last_vsync_tick;
#ifndef DDP_LK_BOOT
struct mutex                    lock;
#endif
disp_lcm_handle *               plcm;
cmdqRecHandle               cmdq_handle_config;
cmdqRecHandle               cmdq_handle_trigger;
disp_path_handle                    dpmgr_handle;
disp_path_handle                ovl2mem_path_handle;
} display_primary_path_context;

2.disp_lcm_handle 结构体
typedef struct
{
LCM_PARAMS 			*params;
LCM_DRIVER 			*drv;
LCM_INTERFACE_ID	lcm_if_id;
int					module;
int					is_inited;
int					is_connected;
}disp_lcm_handle, *pdisp_lcm_handle;

3.LCM_PARAMS 结构体
typedef struct {
LCM_TYPE type;
LCM_CTRL ctrl;      /* ! how to control LCM registers */
LCM_INTERFACE_ID lcm_if;
LCM_INTERFACE_ID lcm_cmd_if;
/* common parameters */
unsigned int lcm_x;
unsigned int lcm_y;
unsigned int width;
unsigned int height;
unsigned int virtual_width;
unsigned int virtual_height;
unsigned int io_select_mode;    /* DBI or DPI should select IO mode according to chip spec */

/* particular parameters */
LCM_DBI_PARAMS dbi;
LCM_DPI_PARAMS dpi;
LCM_DSI_PARAMS dsi;
unsigned int physical_width;
unsigned int physical_height;
unsigned int od_table_size;
void *od_table;
} LCM_PARAMS;

4. LCM_DRIVER 结构体
typedef struct {
const char *name;
void (*set_util_funcs) (const LCM_UTIL_FUNCS *util);
void (*get_params) (LCM_PARAMS *params);

void (*init) (void);
void (*suspend) (void);
void (*resume) (void);

/* for power-on sequence refinement */
void (*init_power) (void);
void (*suspend_power) (void);
void (*resume_power) (void);

void (*update) (unsigned int x, unsigned int y, unsigned int width, unsigned int height);
unsigned int (*compare_id) (void);
void (*parse_dts)(const LCM_DTS *DTS, unsigned char force_update);

/* CABC backlight related function */
void (*set_backlight) (unsigned int level);
void (*set_backlight_cmdq) (void *handle, unsigned int level);
void (*set_pwm) (unsigned int divider);
unsigned int (*get_pwm) (unsigned int divider);
void (*set_backlight_mode) (unsigned int mode);

int (*adjust_fps) (void *cmdq, int fps);

/* ESD_RECOVERY*/
unsigned int (*esd_check) (void);
unsigned int (*esd_recover) (void);
unsigned int (*check_status) (void);
unsigned int (*ata_check) (unsigned char *buffer);
void (*read_fb) (unsigned char *buffer);
int (*ioctl) (LCM_DRV_IOCTL_CMD cmd, unsigned int data);

void (*enter_idle)(void);
void (*exit_idle)(void);
void (*change_fps)(unsigned int mode);

/* switch mode */
void *(*switch_mode) (int mode);
void (*set_cmd) (void *handle, int *mode, unsigned int cmd_num);
void (*set_lcm_cmd) (void *handle, unsigned int *lcm_cmd, unsigned int *lcm_count,unsigned int *lcm_value);
/* PWM*/
void (*set_pwm_for_mix) (int enable);
} LCM_DRIVER;

5. pgc 的定义
#define pgc _get_context()

static display_primary_path_context* _get_context(void)
{
static int is_context_inited = 0;
static display_primary_path_context g_context;
if (!is_context_inited) {
memset((void*)&g_context, 0, sizeof(display_primary_path_context));
is_context_inited = 1;
}
return &g_context;
}
二.显示驱动在lk的 platform_init 函数中调用:
void platform_init(void)
{
……

g_fb_size = mt_disp_get_vram_size();
/*第一次调用显示驱动,这里会调用 disp_lcm_probe 初始化显示驱动。
序号三分析该函数。*/

g_fb_base = mblock_reserve(&g_boot_arg->mblock_info, g_fb_size, 0x10000, 0x100000000, RANKMAX);
/*从存储设备中分配一块用于fb的地址。*/

mt_disp_init((void *)g_fb_base);
/*显示相关的初始化:*/

mt_disp_fill_rect(0, 0, CFG_DISPLAY_WIDTH, CFG_DISPLAY_HEIGHT, 0x0);
mt_disp_update(0, 0, CFG_DISPLAY_WIDTH, CFG_DISPLAY_HEIGHT);

……
}
三.disp_lcm_probe 函数
/*传入的形参为:		pgc->plcm = disp_lcm_probe(NULL, LCM_INTERFACE_NOTDEFINED);*/
disp_lcm_handle *disp_lcm_probe(char *plcm_name, LCM_INTERFACE_ID lcm_id)
{
LCM_DRIVER *lcm_drv = NULL;
LCM_PARAMS *lcm_param = NULL;
disp_lcm_handle *plcm = NULL;
unsigned int lcm_hwinfo_num = 0;

{
char main_name[32] = {0};
int i = 0;
unsigned short temp = 0;

for (i = 0; i < 32/*MAX_LCM_NUM*/; i++) {
sprintf(main_name, "lcd%d_para", i);

if (hwinfo_parser_fetch(main_name, "lcd_used", &temp, 1) <= 0) {
printf("-----hwinfo get [%s] lcd_used,fail-----\n", main_name);
break;
} else{
lcm_hwinfo_num++;
}
}
/*这段代码查找配置文件lcd%d_para中是否有lcd_used这个变量。如果有2个lcd配置文件,则 lcm_hwinfo_num=2。*/
}

disp_path_handle handle = NULL;
disp_lcm_handle hlcm;
disp_lcm_handle *plcm = &hlcm;
LCM_PARAMS hlcm_param;

for(i = 0; i< lcm_hwinfo_num; i++)
{
memset((void*)&hlcm, 0, sizeof(disp_lcm_handle));
memset((void*)&hlcm_param, 0, sizeof(LCM_PARAMS));

lcm_hwinfo_cfg = i;		/* compare the lcm_hwinfo_cfg lcm*/
lcm_drv= lcm_driver_list[0];
/*lcm_driver_list[0] = {	&lcm_common_drv};*/
lcm_drv->get_params(&hlcm_param);
/*获取LCM参数,保存到hlcm_param中。*/

plcm->drv = lcm_drv;
plcm->params = &hlcm_param;
plcm->lcm_if_id = plcm->params->lcm_if;
if(lcm_id == LCM_INTERFACE_NOTDEFINED ||(lcm_id != LCM_INTERFACE_NOTDEFINED && plcm->lcm_if_id == lcm_id))
{
handle = _display_interface_path_init(plcm);
/*初始化显示接口通道*/
if(lcm_drv->init_power)
{
lcm_drv->init_power();
/*初始化lcm power */
}

if(lcm_drv->compare_id != NULL)
{
if(lcm_drv->compare_id() != 0)
{
dprintf(0, "disp_lcm_probe. hwinfo compare_id: %d \n", lcm_hwinfo_cfg);
isLCMFound = true;
_display_interface_path_deinit(handle);
/*显示接口通道的某些功能禁止。*/
break;
/*当有多个兼容屏的配置文件时,通过屏id来区分使用哪个配置文件,compare_id返回1即为匹配成功,退出循环。*/
}
}
_display_interface_path_deinit(handle);
}
}
plcm = &_disp_lcm_driver[0];
lcm_param = &_disp_lcm_params;
plcm->params = lcm_param;
plcm->drv = lcm_drv;
/*给显示驱动和参数赋值。*/

handle = _display_interface_path_init(plcm);
/*初始化显示接口通道*/

_display_interface_path_deinit(handle);
/*显示接口通道的某些功能禁止。*/

return plcm;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  lk mtk 显示驱动
相关文章推荐