展讯平台lcd匹配流程

来源:互联网 发布:java 23种设计模式 编辑:程序博客网 时间:2024/05/16 02:05

sp6820
kernel:
sprdfb_init(void)
—> 1、fb_get_options(“sprdfb”, &option) // get kernel boot parameters
2、sprdfb_setup(option); //
—> get_opt_int(this_opt, “fb0_id”, &panel_id[0]); // 取出uboot中传来的ID号
get_opt_int(this_opt, “fb1_id”, &panel_id[1]);
3、lcdc_hardware_init();
4、platform_driver_register(&sprdfb_driver);
—> .probe = sprdfb_probe,
—> sprdfb_probe(struct platform_device *pdev)
—> 1))、dev->device_id = panel_id[pdev->id];
2))、lcdc_early_init(platform_data, dev)
—> lcd_adapt = find_adapt_from_uboot(dev->device_id, platform_data)
device_id == lcd_panel[i].lcd_id // 判断cfg->lcd_id与uboot中传来的是否一致
return i;
—> | lcd_adapt = FAIL–> find_adapt_from_readid(dev,platform_data) /* can not reach here; get device id from u-boot */
|
lcd_adapt = OK
|
–>mount_panel(dev, lcd_panel[lcd_adapt].panel) 挂接LCD panel的参数到sprdfb_device中
dev->panel = panel;
panel->info.mcu->ops = dev->ops;
panel->ops->lcd_reset = panel_reset;
dev->width = panel->width;
dev->height = panel->height;
dev->bpp = panel->bpp = 32;
dev->timing[0] = lcdc_calculate_lcm_timing(timing);
dev->timing[1] = lcdc_calculate_lcm_timing(timing);
dev->fb->fix.reserved[0] = 0x6f76;
dev->fb->fix.reserved[1] = 0x6572;

u-boot:

sc8810fb_probe
—> find_adapt_from_readid(fb)
—>
|
|

    |--> 1、mount_panel(fb,lcd_panel[i].panel); //first ,try mount        fb->panel = panel;    panel->info.mcu->ops = fb->ops;    panel->ops->lcd_reset = panel_reset;    fb->register_timing = lcdc_calc_lcm_timing(timing);    fb->gram_timing = lcdc_calc_lcm_timing(timing);       2、hw_init(fb);                        //hw init to every panel     3、id = fb->panel->ops->lcd_readid(fb->panel); //read id     4、save_lcd_id_to_kernel(id)            ---> lcd_id_to_kernel = id

sp7715
kernel:
sprdfb_probe
— > sprdfb_panel_get(dev)
—->
__setup(“lcd_id=”, lcd_id_get);
sscanf(&str[2], “%x”, &lcd_id_from_uboot); // get LCD Panel ID from uboot取出uboot中传来的ID号
1、panel = adapt_panel_from_uboot(dev->dev_id)
—-> | panel == 0 read id FAIL
|
panel != 0
|–> list_for_each_entry(cfg, panel_list, list) // 使用链表遍历cfg
lcd_id_from_uboot == cfg->lcd_id // 判断cfg->lcd_id与uboot中传来的是否一致
return cfg->panel;

2、panel_mount(dev, panel);           ---> dev->panel = panel;            dev->panel->ops->panel_reset = panel_reset_dispc;               panel->if_ctrl->panel_if_mount(dev);3、panel_init(dev);

sp7731

u-boot:
sprdfb_panel_probe(struct sprdfb_device *dev)
— > adapt_panel_from_readid(dev);
— > for(i = 0;i<(sizeof(panel_cfg))/(sizeof(panel_cfg[0]));i++) { // 遍历cfg数组
ret = panel_mount(dev, panel_cfg[i].panel);
— > dev->if_ctrl->panel_if_mount(dev);
id = dev->panel->ops->panel_readid(dev->panel); // 跑lcd driver readid函数
if(id == panel_cfg[i].lcd_id) { // 比较读出的id与cfg数组注册的id

            if(NULL != dev->panel->ops->panel_init){                dev->panel->ops->panel_init(dev->panel);    // 若是id一致,就跑lcd driver init code            }            save_lcd_id_to_kernel(id);              // 保存lcd id值到开机启动参数 bootargs                --- > lcd_id_to_kernel = id;                --- > fdt_fixup_lcdid(void *fdt)                    sprintf(&buf[str_len], "%x", lcd_id);                    fdt_chosen_bootargs_append(fdt, buf, 1);                    ( fdt_chosen_bootargs_append(void *fdt, char *append_args, int force) )                        --- > path = fdt_getprop(fdt, nodeoffset, "bootargs", NULL);                            --- > sprintf(strargs, "%s", append_args);                                  fdt_setprop(fdt, nodeoffset, "bootargs", strargs, strlen(strargs) + 1);                           panel_ready(dev);            return panel_cfg[i].panel;              // 返回匹配成功的panel结构体地址        }

kernel:
sprdfb_probe
— > sprdfb_panel_get(dev);
—-> panel = adapt_panel_from_uboot(dev->dev_id); // 取出uboot中传来的ID号

        --- > list_for_each_entry(cfg, panel_list, list) // 比较注册进panel_list 的 lcd的panel_cfg            if(lcd_id_from_uboot == cfg->lcd_id) {  // 比较bootargs获取的lcd id值与panel_cfg里注册的lcd id值                    ---->                                   static int __init lcd_id_get(char *str) // 从启动参数 bootargs里获取适配的lcd id值                        {                            if ((str != NULL) && (str[0] == 'I') && (str[1] == 'D')) {                                sscanf(&str[2], "%x", &lcd_id_from_uboot);                            }                            return 1;                        }                        __setup("lcd_id=", lcd_id_get);                sprd_lcd_name=  cfg->lcd_name;                return cfg->panel;  // 返回匹配成功的panel结构体地址            }    if (panel) {    // 匹配了panel        panel_mount(dev, panel);        panel_init(dev);            // 跑lcd driver init code        return true;    } 
原创粉丝点击