sp6820平台:(linux2.6)
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;
panelnfo.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平台:(linux3.10)
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平台:(linux3.10)
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;
}