展讯平台lcd读取id适配流程


sp6820平台:(linux2.6)

kernel:

sprdfb_init(void)
    ---> 1fb_get_options("sprdfb", &option)   // get kernel boot parameters
           2sprdfb_setup(option); // 
                ---> get_opt_int(this_opt, "fb0_id", &panel_id[0]); // 取出uboot中传来的IDget_opt_int(this_opt, "fb1_id", &panel_id[1]);
         3lcdc_hardware_init();
         4platform_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_iduboot中传来的是否一致
          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_devicedev->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中传来的ID1、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;
    } 

猜你喜欢

转载自blog.csdn.net/u013656962/article/details/77411366