美文网首页mtk_显示相关
MTK平台LCM代码流程介绍

MTK平台LCM代码流程介绍

作者: Be_a_young_man | 来源:发表于2019-01-23 15:29 被阅读0次

    LK阶段:

    • project\vendor\mediatek\proprietary\bootable\bootloader\lk\kernel\main.c
    kmain();
    --thread_t *thread_bs2 = thread_create("bootstrap2", &bootstrap2, NULL,DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
       -- bootstrap2(void *arg);
         -- platform_init();
    
    重点从platform_init来讲起;

    主要讲这3个部分:
    1、初始化lk中的fb,获取大小、长宽等,同时给驱动结构体pgc分配空间,为进行驱动初始化做准备。

    /* initialize the frame buffet information */
    g_fb_size = mt_disp_get_vram_size();
    g_fb_base = mblock_reserve_ext(&g_boot_arg->mblock_info, g_fb_size, 0x10000, 0x78000000, 0, "framebuffer");
    

    2、mt_disp_init((void *)g_fb_base);

    3、mt65xx_backlight_on();

    • project\vendor\mediatek\proprietary\bootable\bootloader\lk\platform\mt6739\platform.c
    void platform_init(void)
    {
        /* initialize the frame buffet information */
        g_fb_size = mt_disp_get_vram_size();
        g_fb_base = mblock_reserve_ext(&g_boot_arg->mblock_info, g_fb_size, 0x10000, 0x78000000, 0, "framebuffer");
        ...
        mt_disp_init((void *)g_fb_base);
        ...
        mt65xx_backlight_on();
        ...
    }
    
    下面分别讲解这几个函数:
    1、mt_disp_get_vram_size();
    --DISP_GetVRamSize();
      --vramSize = DISP_GetFBRamSize();
          -- DISP_GetScreenWidth(void)
              --primary_display_get_width();
                --if (pgc->plcm == NULL) {
                  pgc->plcm = disp_lcm_probe(NULL, LCM_INTERFACE_NOTDEFINED);//跑probe函数,lcm参数初始化。
                  ...}
        vramSize += DAL_GetLayerSize();
        return vramSize;
    //pgc结构体的定义start//    
    #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;
    }
    //pgc结构体的定义end//  
    
    2、mt_disp_init((void *)g_fb_base);
    ---/// fb base pa and va
       fb_addr_pa_k = arm_mmu_va2pa((unsigned int)lcdbase);
       fb_addr_pa   = (void *)(unsigned int)(fb_addr_pa_k & 0xffffffffull);
       fb_addr      = lcdbase;
       primary_display_init(NULL)
       --pgc->plcm = disp_lcm_probe( lcm_name, LCM_INTERFACE_NOTDEFINED)
           --//当_lcm_count() > 0时会调用lcm_drv->compare_id() != 0时break,找到相应lcm
             compare_id()
       --ret = disp_lcm_init(pgc->plcm);
         --ret = DSI_dcs_read_lcm_reg_v2(_get_dst_module_by_lcm(plcm), NULL, 0x0A, (UINT8 *)&buffer,1);
               >DISPMSG("read from lcm 0x0A: %d\n", buffer);
               if (ret == 0) {
                   isLCMConnected = 0;
                   DISPMSG("lcm is not connected\n");
               } else {
                   isLCMConnected = 1;
                   DISPMSG("lcm is connected\n");
               }
    
    3、void mt65xx_backlight_on(void){
       --enum led_brightness backlight_level = get_cust_led_default_level();
         mt65xx_leds_brightness_set(MT65XX_LED_TYPE_LCD, backlight_level);//默认backlight_level = LED_FULL
         --mt65xx_led_set_cust(&cust_led_list[type], level)
            --  switch (cust->mode) {
                ...
                case MT65XX_LED_MODE_GPIO:
                    return ((cust_brightness_set)(cust->data))(level);
                case MT65XX_LED_MODE_PMIC:
                    return brightness_set_pmic(cust->data, level);
                case MT65XX_LED_MODE_CUST_LCM:
                    return ((cust_brightness_set)(cust->data))(level);
                case MT65XX_LED_MODE_CUST_BLS_PWM:
                    return ((cust_brightness_set)(cust->data))(level); ////dts中对应的背光模式 MT65XX_LED_MODE_CUST_BLS_PWM
                case MT65XX_LED_MODE_NONE:
                default:
                    break;
                }
    }
    //与背光相关的结构体
    enum led_brightness {
        LED_OFF     = 0,
        LED_HALF    = 127,
        LED_FULL    = 255,
    };
    enum mt65xx_led_type
    {
        MT65XX_LED_TYPE_RED = 0,
        MT65XX_LED_TYPE_GREEN,
        MT65XX_LED_TYPE_BLUE,
        MT65XX_LED_TYPE_JOGBALL,
        MT65XX_LED_TYPE_KEYBOARD,
        MT65XX_LED_TYPE_BUTTON,
        MT65XX_LED_TYPE_LCD,
        MT65XX_LED_TYPE_TOTAL,
    };    
    enum mt65xx_led_mode
    {
        MT65XX_LED_MODE_NONE,
        MT65XX_LED_MODE_PWM,
        MT65XX_LED_MODE_GPIO,
        MT65XX_LED_MODE_PMIC,
        MT65XX_LED_MODE_CUST_LCM,
        MT65XX_LED_MODE_CUST_BLS_PWM //5
    };
    //dts中对应的背光模式,在K39tv1_64_bsp.dts中
        led6:led@6 {
            compatible = "mediatek,lcd-backlight";
            led_mode = <5>; //对应的背光模式MT65XX_LED_MODE_CUST_BLS_PWM
            data = <1>;
            pwm_config = <0 2 0 0 0>;
        };
    

    KERNEL阶段:

    • L:\work3\project\kernel-4.4\drivers\misc\mediatek\video\mt6739\videox\
    mtkfb.c:
    module_init(mtkfb_init);
    int __init mtkfb_init(void)
    {
    platform_driver_register(&mtkfb_driver)
        --.of_match_table = mtkfb_of_ids,
            --{.compatible = "mediatek,MTKFB",}//和设备树中的相匹配后跑prob函数
    ...
    }
    
    static int mtkfb_probe(struct platform_device *pdev)
    {
    ...
        |_parse_tag_videolfb();//用于获取LK传递过来的lcm型号参数
        |  --chosen_node = of_find_node_by_path("/chosen");
        |    ret = __parse_tag_videolfb(chosen_node);
        |      --videolfb_tag = (struct tag_videolfb *)of_get_property(node, "atag,videolfb", (int *)&size);
        |        memset((void *)mtkfb_lcm_name, 0, sizeof(mtkfb_lcm_name));
        |        strncpy((char *)mtkfb_lcm_name, videolfb_tag->lcmname, sizeof(mtkfb_lcm_name));
        |        mtkfb_lcm_name[strlen(videolfb_tag->lcmname)] = '\0';//解析出lcd的名字,lk在初始化时进行lcm匹配修改放入相应的到chosen节点,来传递给kernel。
        |
        |primary_display_init(mtkfb_find_lcm_driver(), lcd_fps, is_lcm_inited);  //进行LCM主要的初始化
        |   --pgc->plcm = disp_lcm_probe(lcm_name, LCM_INTERFACE_NOTDEFINED, is_lcm_inited);
        |   --primary_display_check_recovery_init();//ESD检测
        |       --primary_display_check_task =kthread_create(primary_display_check_recovery_worker_kthread, NULL,"disp_check");//创建线程
        |           --wake_up_process(primary_display_check_task);//唤醒线程函数
        |              --static int primary_display_check_recovery_worker_kthread(void *data)
        |                   --do {
        |                            ret = primary_display_esd_check();
        |            
        |                            if (ret == 1) {
        |                                DISPERR("[ESD]esd check fail, will do esd recovery. try=%d\n", i);
        |                                primary_display_esd_recovery();//ESD check failed 挂起LCM,重新进行初始化。
        |                                   -- {  ...DISPDBG("[POWER]lcm suspend[begin]\n");
        |                                        disp_lcm_suspend(primary_get_lcm());
        |                                        DISPCHECK("[POWER]lcm suspend[end]\n");
        |                                       
        |                                        mmprofile_log_ex(ddp_mmp_get_events()->esd_recovery_t, MMPROFILE_FLAG_PULSE, 0, 7);
        |                                       
        |                                        DISPDBG("[ESD]lcm force init[begin]\n");
        |                                        disp_lcm_init(primary_get_lcm(), 1);
        |                                        DISPCHECK("[ESD]lcm force init[end]\n");...}
        |                   
        |                                recovery_done = 1;
        |                            } else
        |                                break;
        |            
        |                          } while (++i < esd_try_cnt);//esd_try_cnt = 5
        |
        |
    ...
    }
    

    相关文章

      网友评论

        本文标题:MTK平台LCM代码流程介绍

        本文链接:https://www.haomeiwen.com/subject/oqajjqtx.html