ST7703 LCM显示屏调试--基于MT6765

参考

Kernel驱动加载流程

  • mtkfb驱动

mtkfb驱动通过数据结构platform_driver挂接的到platform总线上。

2890 static struct platform_driver mtkfb_driver = {
2891         .probe = mtkfb_probe,
2892         .remove = mtkfb_remove,
2893         .suspend = mtkfb_suspend,
2894         .resume = mtkfb_resume,
2895         .shutdown = mtkfb_shutdown,
2896
2897         .driver = {
2898                    .name = MTKFB_DRIVER,
2899 #ifdef CONFIG_PM
2900                    .pm = &mtkfb_pm_ops,
2901 #endif
2902                    .bus = &platform_bus_type,
2903                    .of_match_table = mtkfb_of_ids,
2904                    },
2905 };

  • mtkfb_probe(xxx) drivers/misc/mediatek/video/mt6765/videox/mtkfb.c

    • primary_display_init(xxx) drivers/misc/mediatek/video/mt6765/videox/primary_display.c
      • disp_lcm_probe(xxx) drivers/misc/mediatek/video/mt6765/videox/disp_lcm.c
        • lcm_drv = lcm_driver_list[i];加载st7703_hd720_dsi_vdo_lcm_drv模组 drivers/misc/mediatek/lcm/mt65xx_lcm_list.c
  • lcm驱动模组

struct LCM_DRIVER st7703_hd720_dsi_vdo_lcm_drv ={
	.name 			= "st7703_hd720_dsi_vdo",
	.set_util_funcs = lcm_set_util_funcs,
	.get_params     = lcm_get_params,
	.init           = lcm_init,
	.suspend        = lcm_suspend,
	.resume         = lcm_resume,
	.compare_id     = lcm_compare_id,
};

primary_display_init其实和lk是一样的,但是如果lk初始化过LCD,kernel就不会重复再初始化,根据flag is_lcm_inited判定。

primary_display_init:

3965         if (is_lcm_inited) {
3966                 /* ??? why need */
3967                 /* no need lcm power on,because lk power on lcm */
3968                 /* ret = disp_lcm_init(pgc->plcm, 0);   */
3969         } else {
3970                 /* lcm not inited:
3971                  * 1. fpga no lk(verify done);
3972                  * 2. evb no lk(need verify)
3973                  */
3974                 if (use_cmdq) {
3975                         /* make sure dsi configuration done before lcm init */
3976                         _cmdq_flush_config_handle(1, NULL, 0);
3977                         _cmdq_reset_config_handle();
3978                 }
3979
3980                 ret = disp_lcm_init(pgc->plcm, 1);
3981         }
  • kernel阶段打印
[   27.615827] <1>.(0)[271:kworker/0:2][name:ddp_drv&]disp driver(1) disp_probe end
[   27.615836] <1>.(0)[271:kworker/0:2][name:ddp_drv&]disp driver(1) disp_probe_1 begin
[   27.627919] <1>.(0)[271:kworker/0:2][name:ddp_drv&]disp driver(1) disp_probe_1 end
[   27.627949] <1>.(0)[271:kworker/0:2][name:bootprof&][name:bootprof&]BOOTPROF:     27627.944603:probe: probe=platform_drv_probe drv=DISPSYS(dispsys_of_driver)    21.845615ms
[   27.629197] <1>.(0)[271:kworker/0:2][DISP][DT][videolfb]isvideofb_parse_done = 0
[   27.629229] <1>.(0)[271:kworker/0:2][DISP][DT][videolfb] islcmfound = 1
[   27.629243] <1>.(0)[271:kworker/0:2][DISP][DT][videolfb] is_lcm_inited = 1
[   27.629258] <1>.(0)[271:kworker/0:2][DISP][DT][videolfb] fps        = 5750
[   27.629273] <1>.(0)[271:kworker/0:2][DISP][DT][videolfb] fb_base    = 0x7f0e0000
[   27.629288] <1>.(0)[271:kworker/0:2][DISP][DT][videolfb] vram       = 0xe20000 (14811136)
[   27.629303] <1>.(0)[271:kworker/0:2][DISP][DT][videolfb] lcmname    = st7703_hd720_dsi_vdo_drv
[   27.629753] <1>.(0)[271:kworker/0:2][name:ddp_m4u&]disphal_allocate_fb, pa_start=0x0x000000007f0e0000, pa_end=0x0x000000007fefffff, va=0xffffff800e000000
[   27.632537] <1>.(0)[271:kworker/0:2][DISP][DT][videolfb]isvideofb_parse_done = 1
[   27.632571] <1>.(0)[271:kworker/0:2][DISP]primary_display_init begin lcm=st7703_hd720_dsi_vdo_drv, inited=1
[   27.632589] <1>.(0)[271:kworker/0:2][name:mmprofile&][name:mmprofile&]MMP: mmprofile_enable(): enable: 1
[   27.636614] <1>.(0)[271:kworker/0:2][name:mmprofile&][name:mmprofile&]MMP: mmprofile_force_start(): start: 1
[   27.639191] <1>.(0)[271:kworker/0:2][DISP]plcm_name=st7703_hd720_dsi_vdo_drv is_lcm_inited 1
[   27.639200] <1>.(0)[271:kworker/0:2][wugn]enter disp_lcm_probe plcm_name = 1907365624
[   27.639258] <1>.(0)[271:kworker/0:2][name:st7703_hd720_dsi_vdo&][KERNEL/LCM][wugn]enter lcm_get_params
[   27.639286] <1>.(0)[271:kworker/0:2][DISP][LCM] name: st7703_hd720_dsi_vdo_drv
[   27.639302] <1>.(0)[271:kworker/0:2][DISP][LCM] resolution: 720 x 1440
[   27.639318] <1>.(0)[271:kworker/0:2][DISP][LCM] physical size: 74 x 132
[   27.639333] <1>.(0)[271:kworker/0:2][DISP][LCM] physical size: 74 x 132
[   27.639348] <1>.(0)[271:kworker/0:2][DISP][LCM] interface: unknown
[   27.639363] <1>.(0)[271:kworker/0:2][DISP][LCM] Type: DSI
[   27.639379] <1>.(0)[271:kworker/0:2][DISP][LCM] DSI Mode: SYNC_PULSE_VDO_MODE
[   27.639394] <1>.(0)[271:kworker/0:2][DISP][LCM] LANE_NUM: 4
[   27.639414] <1>.(0)[271:kworker/0:2][DISP][LCM] vact: 4, vbp: 19, vfp: 18, vact_line: 1440, hact: 20, hbp: 20, hfp: 20, hblank: 0
[   27.639432] <1>.(0)[271:kworker/0:2][DISP][LCM] pll_select: 0, pll_div1: 0, pll_div2: 0, fbk_div: 0,fbk_sel: 0, rg_bir: 0
[   27.639467] <1>.(0)[271:kworker/0:2][DISP][LCM] rg_bic: 0, rg_bp: 0,PLL_CLOCK: 208, dsi_clock: 0, ssc_range: 0,ssc_disable: 1
[   27.639466] <1>.(0)[271:kworker/0:2][DISP][LCM]compatibility_for_nvk: 0, cont_clock: 0
[   27.639484] <1>.(0)[271:kworker/0:2][DISP][LCM] lcm_ext_te_enable: 0, noncont_clock: 0, noncont_clock_period: 0
[   27.639499] <1>.(0)[271:kworker/0:2][DISP]disp_lcm_probe SUCCESS
[   27.639507] <1>.(0)[271:kworker/0:2]111111
[   27.639515] <1>.(0)[271:kworker/0:2][wugn]enter disp_lcm_get_params
[   27.639526] <1>.(0)[271:kworker/0:2]222222
[   27.640887] <1>.(0)[271:kworker/0:2][DISP][DT][videolfb]isvideofb_parse_done = 1
[   27.645103] <1>.(0)[271:kworker/0:2][DISP]dsi0 initializing _dsi_context
[   27.647424] <1>.(0)[271:kworker/0:2]33333333
[   27.647446] <1>.(0)[271:kworker/0:2]44444444444444
[   27.648729] <1>.(0)[271:kworker/0:2]555555555555555555
[   27.648746] <1>.(0)[271:kworker/0:2][DISP]primary_display_init->dpmgr_path_start
[   27.649070] <1>.(0)[271:kworker/0:2][name:ddp_gamma&][GAMMA] disp_gamma_write_lut_reg: table [0] not initialized
[   27.649070] <1>
[   27.652293] <1>.(0)[271:kworker/0:2]6666666666666
[   27.652682] <1>.(4)[292:init_decouple_b][name:primary_display&]init_decouple_buffers done
[   27.662993] <1>.(0)[271:kworker/0:2][name:mtk_sodi&]Power/swap - mtk_idle_disp_is_ready not support anymore!
[   27.664990] <1>.(0)[271:kworker/0:2][name:cmdq_mdp_common&][CMDQ][Res]resource clock engine:0x400 enable:true
[   27.665784] <1>.(0)[271:kworker/0:2][DISP]primary_display_init done
[   27.666049] <1>.(0)[271:kworker/0:2][DISP]MTK_FB_XRES=720, MTKFB_YRES=1440, MTKFB_BPP=32, MTK_FB_PAGES=3, MTKFB_LINE=2944, MTKFB_SIZEV=12718080
[   27.666067] <1>.(0)[271:kworker/0:2][DISP][FB Driver] fbdev->fb_pa_base = 0x000000000597696f, fbdev->fb_va_base = 0x000000005866925e
[   27.666154] <1>.(0)[271:kworker/0:2][DISP]mtkfb_check_var,xres=720,yres=1440,x_virt=736,y_virt=4320,xoffset=0,yoffset=0,bits_per_pixel=32)
[   27.666213] <1>.(0)[271:kworker/0:2][DISP]AEE is not enabled, will disable layer 3
[   27.998818] <1>.(7)[0:swapper/7][name:rtnetlink&][name:rtnetlink&][mtk_net][rtnl_lock]There is no process hold rtnl lock
[   28.536888] <0>.(0)[271:kworker/0:2][DISP][DT][videolfb]isvideofb_parse_done = 1
[   28.544324] <0>.(0)[271:kworker/0:2][DISP][DT][videolfb]isvideofb_parse_done = 1
[   28.553798] <0>.(0)[271:kworker/0:2][name:ion_drv&][ION]ion_drv_create_heap: create heap: ion_fb_heap
[   28.563053] <0>.(0)[271:kworker/0:2][DISP][DT][videolfb]isvideofb_parse_done = 1
[   28.570466] <0>.(0)[271:kworker/0:2][name:mtkfb&]disp driver(2) mtkfb_probe end

LK驱动加载流程

  • platform.c流程分析
platform/mt6765/platform.c

void platform_init(void) {
//framebuffer的大小
g_fb_size = mt_disp_get_vram_size();
//framebuffer的起始地址
g_fb_base = mblock_reserve(&g_boot_arg->mblock_info, g_fb_size, 0x10000, 0xa0000000, RANKMAX);
//mtk display系统初始化
mt_disp_init((void *)g_fb_base);
//fb预先填充black
mt_disp_fill_rect(0, 0, CFG_DISPLAY_WIDTH, CFG_DISPLAY_HEIGHT, 0x0);
//将fb内容更新到lcm上
mt_disp_update(0, 0, CFG_DISPLAY_WIDTH, CFG_DISPLAY_HEIGHT);
//初始化charge
mtk_charger_init();
//初始化电池
mt65xx_bat_init();
//如果没接电池且是低电量模式,将显示低电量logo,否则正常显示logo
if (kernel_charging_boot() == 1) {
    if ((g_boot_mode != LOW_POWER_OFF_CHARGING_BOOT) {
        mt_disp_show_low_battery();
    }
} else if (g_boot_mode != KERNEL_POWER_OFF_CHARGING_BOOT && g_boot_mode != LOW_POWER_OFF_CHARGING_BOOT) {
    //加载logo
    mboot_common_load_logo((unsigned long)mt_get_logo_db_addr_pa(), "logo");
    //根据启动方式选择加载的logo,填充到fb中
    mt_disp_show_boot_logo();
}
//打开背光
mt65xx_backlight_on();
mt_disp_update(0, 0, CFG_DISPLAY_WIDTH, CFG_DISPLAY_HEIGHT);
}

流程如下:

  • thread_create(“bootstrap2”…) kernel/main.c

    • bootstrap2(void *arg)
      • platform_init();
        • mt_disp_init(void *lcdbase) “platform/mt6765/mt_disp_drv.c”
          • primary_display_init(char *lcm_name)
            • pgc->plcm = disp_lcm_probe(…);“platform/mt6765/primary_display.c初始化pgc->plcm,很重要”
              • struct LCM_DRIVER *lcm_drv = NULL;
              • lcm_drv = lcm_driver_list[i];
                • &st7703_hd720_dsi_vdo_lcm_drv在mk文件中定义了CUSTOM_LK_LCM=“st7703_hd720_dsi_vdo”,选择此驱动
              • lcm_drv->get_params(&hlcm_param);
              • plcm->lcm_if_id = plcm->params->lcm_if;lcm的接口id,分为DSI0、DSI1
              • lcm_drv->init_power()
              • lcm_drv->compare_id()
              • _dump_lcm_info(plcm);打印LCM信息
            • lcm_param = disp_lcm_get_params(pgc->plcm);
              • plcm->params; 调用st7703中的lcm_get_params
            • disp_lcm_init(pgc->plcm);
              • lcm_drv->init调用st7703中的lcm_init
          • primary_display_config_input(&input);
  • disp_lcm_probe部分代码详解:

	lcm_drv= lcm_driver_list[i];  //驱动选择st7703
	lcm_drv->get_params(&hlcm_param);  //调用lcm_get_params获取参数
	plcm->drv = lcm_drv; 
	plcm->params = &hlcm_param; //赋值
	plcm->lcm_if_id = plcm->params->lcm_if; //lcm的接口id,分为DSI0、DSI1、dual port DSI、DBI0、DPI0、DPI1
	
if (lcm_drv->init_power) { //实现上电复位初始化的动作,并通过回读0x0A寄存器判断跟lcm之前是否连接OK
		lcm_drv->init_power();
	}
	if (lcm_drv->compare_id != NULL) { //读取display ID
		if (lcm_drv->compare_id() != 0) {
			isLCMFound = true;
			_display_interface_path_deinit(handle);
			dprintf(0,"we will use lcm: %s\n", lcm_drv->name);
			break;
		}
	}
  • pgc->plcm详解

结构体如下:

 24 struct disp_lcm_handle {
 25         struct LCM_PARAMS *params;
 26         struct LCM_DRIVER *drv;
 27         enum LCM_INTERFACE_ID lcm_if_id;
 28         int module;
 29         int is_inited;
 30         unsigned int lcm_original_width;
 31         unsigned int lcm_original_height;
 32         int index;
 33 };

params和drv两个参数很重要,一个是从st7703中获取的显示参数,用lcm_get_params结构获取,同lcm_param,一个是驱动程序。

//LCM_DRIVER,lcm相关的一系列的操作函数
typedef struct {
    const char *name;  --用于匹配lcm
    void (*set_util_funcs) (const LCM_UTIL_FUNCS *util);  --设置lcm操作函数,gpio、reset、delay、write/read cmd
    void (*get_params) (LCM_PARAMS *params);  --获取lcm的参数,接口、分辨率、porch、PLL clock、data format等

    void (*init) (void);  --lcm初始化,一般为上电复位初始化
    void (*suspend) (void);  --pm相关
    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);  --设置ram的显示区域(x,y)->(x+width,y+height),只在command mode下使用
    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);  --调节刷新率,一般刷新率为60Hz

    /* ///ESD_RECOVERY// */
    unsigned int (*esd_check) (void);  --ESD检测相关,开启该功能,系统会周期性检测lcm寄存器状态,状态NG则会reset lcm
    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);  --用于切换mode,command mode 和video 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;
//LCM_PARAMS,lcm参数设置
typedef struct {
    LCM_TYPE type;  --lcm的接口类型,分为DSI、DBI、DPI        
    LCM_CTRL ctrl;   --lcm寄存器的访问方式,普遍通过MIPI LP下指令,也有的支持spi/i2c等接口访问   
    LCM_INTERFACE_ID lcm_if;  --lcm的接口id,分为DSI0、DSI1、dual port DSI、DBI0、DPI0、DPI1
    LCM_INTERFACE_ID lcm_cmd_if;  --cmd模式接口,和lcm_if一致
    /* common parameters */
    unsigned int lcm_x;  --(lcm_x,lcm_y)定义显示的起始pixel,(virtual_width,virtual_height)or(width,height)定义显示区域的宽和高
    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;  --DBI参数
    LCM_DPI_PARAMS dpi;  --DPI参数
    LCM_DSI_PARAMS dsi;  --DSI参数
    unsigned int physical_width;
    unsigned int physical_height;
    unsigned int od_table_size;
    void *od_table;  --光学相关表格,gamma节点
} LCM_PARAMS;

调试准备

  • 用dct工具配置dws

工具位置:vendor\mediatek\proprietary\scripts\dct

ST7703 LCM显示屏调试--基于MT6765

dws位置:vendor\mediatek\proprietary\bootable\bootloader\preloader\custom\k62v1_64_pax\dct\dct\codegen.dws

配置完相应GPIO后进行驱动代码的移植。

  • 添加lcm到lcm_driver_list[]数组*遍历(kernel和lk阶段)。

(略···)

  • MK文件的配置(kernel和lk阶段)。

(略···)

调试lcm

  • LCM_setting_table调试

调试指令:

struct LCM_setting_table {
unsigned char cmd; // 命令地址
unsigned char count; // 寄存器值的个数
unsigned char para_list[128]; //寄存器的值
};
  • lcm_initialization_setting 设置

供应商提供资料:

SSD_SEND(0x11,0xB9,0xF1,0x12,0x83);
SSD_SEND(0x11,0xBA,0x33,0x81,0x05,0xF9,0x0e,0x0e,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x25,0x00,0x91,0x0a,0x00,0x00,0x02,0x4F,0x11,0x00,0x00,0x37);
SSD_SEND(0x11,0xB8,0x75,0x22,0x20,0x03);
SSD_SEND(0x11,0xB3,0x10,0x10,0x05,0x05,0x03,0xFF,0x00,0x00,0x00,0x00);
SSD_SEND(0x11,0xC0,0x70,0x73,0x50,0x50,0x00,0x00,0x08,0x70,0x00);
SSD_SEND(0x10,0xBC,0x4E);
SSD_SEND(0x10,0xCC,0x0B);
SSD_SEND(0x10,0xB4,0x80);
SSD_SEND(0x11,0xB2,0xF0,0x12,0x30);
SSD_SEND(0x11,0xE3,0x07,0x07,0x0B,0x0B,0x03,0x0B,0x00,0x00,0x00,0x00,0xFF,0x00,0xC0,0x10);
SSD_SEND(0x11,0xC1,0x54,0x00,0x1E,0x1E,0x77,0xF1,0xFF,0xFF,0xCC,0xCC,0x77,0x77);   
SSD_SEND(0x11,0xB5,0x07,0x07);
SSD_SEND(0x11,0xB6,0x30,0x30);
SSD_SEND(0x11,0xBF,0x02,0x11,0x00);
SSD_SEND(0x11,0xE9,0X02,0x00,0x10,0x05,0xB6,0x0A,0xA0,0x12,0x31,0x23,0x37,0x13,0x40,0xA0,0x27,0x38,0x0C,0x00,0x03,0x00,0x00,0x00,0x0C,0x00,0x03,0x00,0x00,0x00,0x75,0x75,0x31,0x88,0x88,0x88,0x88,0x88,0x88,0x13,0x88,0x64,0x64,0x20,0x88,0x88,0x88,0x88,0x88,0x88,0x02,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00);
SSD_SEND(0x11,0xEA,0x02,0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x46,0x02,0x88,0x88,0x88,0x88,0x88,0x88,0x64,0x88,0x13,0x57,0x13,0x88,0x88,0x88,0x88,0x88,0x88,0x75,0x88,0x23,0x10,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0A,0xA0,0x00,0x00,0x00,0x00);
SSD_SEND(0x11,0xE0,0x00,0x07,0x0F,0x30,0x35,0x3C,0x43,0x37,0x06,0x0D,0x0D,0x10,0x11,0x0F,0x12,0x0F,0x14,0x00,0x07,0x0F,0x30,0x35,0x3C,0x43,0x37,0x06,0x0D,0x0D,0x10,0x11,0x0F,0x12,0x0F,0x14);

    DCS_Short_Write_NP(0x11);
	Delay(600);
	DCS_Short_Write_NP(0x29);
	Delay(250);

代码修改如下:

static struct LCM_setting_table init_setting[] = {
	{REGFLAG_DELAY, 50, {0}},
	{0xb9,3,{0xF1,0x12,0x83}},
	{0xba,27,{0x33,0x81,0x05,0xF9,0x0E,0x0E,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x25,0x00,0x91,0x0A,0x00,0x00,0x02,0x4F,0x11,0x00,0x00,0x37}},
	{0xb8,4,{0x26,0x22,0x20,0x03}},  
	{0xb3,10,{0x10,0x10,0x05,0x05,0x03,0xFF,0x00,0x00,0x00,0x00}},
	{0xc0,9,{0x70,0x73,0x50,0x50,0x00,0x00,0x08,0x70,0x00}},
	{0xbc,1,{0x4E}},
	{0xcc,2,{0x0B}},
	{0xb4,1,{0x80}},
	{0xb2,3,{0xF0,0x12,0x30}},
	{0xe3,14,{0x07,0x07,0x0B,0x0B,0x03,0x0B,0x00,0x00,0x00,0x00,0xFF,0x80,0xC0,0x10}},
	{0xc1,12,{0x54,0x00,0x1E,0x1E,0x77,0xF1,0xFF,0xFF,0xCC,0xCC,0x77,0x77}},
	{0xb5,2,{0x07,0x07}},
	{0xb6,2,{0x30,0x30}},
	{0xbf,3,{0x02,0x11,0x00}},
	{0xe9,63,{0x02,0x00,0x10,0x05,0xB6,0x0A,0xA0,0x12,0x31,0x23,0x37,0x13,0x40,0xA0,0x27,0x38,0x0C,0x00,0x03,0x00,0x00,0x00,0x0C,0x00,0x03,0x00,0x00,0x00,0x75,0x75,0x31,0x88,0x88,0x88,0x88,0x88,0x88,0x13,0x88,0x64,0x64,0x20,0x88,0x88,0x88,0x88,0x88,0x88,0x02,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
	{0xea,61,{0x02,0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x46,0x02,0x88,0x88,0x88,0x88,0x88,0x88,0x64,0x88,0x13,0x57,0x13,0x88,0x88,0x88,0x88,0x88,0x88,0x75,0x88,0x23,0x10,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0A,0xA0,0x00,0x00,0x00,0x00}},
	{0xe0,34,{0x00,0x07,0x0F,0x30,0x35,0x3C,0x43,0x37,0x06,0x0D,0x0D,0x10,0x11,0x0F,0x12,0x0F,0x14,0x00,0x07,0x0F,0x30,0x35,0x3C,0x43,0x37,0x06,0x0D,0x0D,0x10,0x11,0x0F,0x12,0x0F,0x14}},
  {0x11,1,{0x00}}, 
  {REGFLAG_DELAY, 600, {0}},
	{0x29,1,{0x00}},  // Display On
	{REGFLAG_DELAY, 250, {0}},
	{REGFLAG_END_OF_TABLE, 0x00, {}}
};

mipi屏的话,MTK平台的是不同的屏只要换这个lcm_initialization_setting初始化设置的代码就可以跑起来的,当然有些屏ic已经有程序,不需要再从初始化里下载这段代码。只要上电时序和配置对了就可以跑起来。

  • lcm_sleep_out_setting和lcm_deep_sleep_mode_in_setting设置

开屏和关屏设置。

#if 0
static struct LCM_setting_table lcm_sleep_out_setting和[] = {  // Display On
	{0x11, 0, {0x00}},
	{REGFLAG_DELAY, 120, {}},

	{0x29, 0, {0x00}},
	{REGFLAG_END_OF_TABLE, 0x00, {}}
};
#endif

static struct LCM_setting_table lcm_deep_sleep_mode_in_setting[] = {  // Display Off
	{0x28, 0, {0x00}},
	{REGFLAG_DELAY, 50, {}},

	/* Sleep Mode On */
	{0x10, 0, {0x00}},
	{ REGFLAG_DELAY, 120, {} },
	{ REGFLAG_END_OF_TABLE, 0x00, {} }
};
  • 分辨率设置
#define FRAME_WIDTH						(720)
#define FRAME_HEIGHT 						(1440)
  • display ID
LCM_ID_ST7703       					(0x3821)

查阅datasheet找到ID信息如下:
ST7703 LCM显示屏调试--基于MT6765
只需要读0x04寄存器的两个字节就能确定是st7703这个屏了,读取ID的驱动程序如下:

static unsigned int lcm_compare_id(void)
{
	unsigned int id=0;
	unsigned char buffer[3];
	unsigned int array[16];
	...
	read_reg_v2(0x04, buffer, 3);
	id = buffer[1]|(buffer[0]<<8); //we only need ID
	...
	if(id == LCM_ID_ST7703)
		return 1;
}

LCM_DRIVER st7703_hd720_dsi_vdo_lcm_drv ={
    .compare_id     = lcm_compare_id,
};
  • DSI PLL_CLOCK设置

MIPI DSI接口PLL计算:

总数据量=(VS+VBP+VACT+VFP)(HS+HBP+HACT+HFP) fps * format_bit(format_bit根据一个pixel的数据位来定,大多为24位,RGB888)

每lane的数据量=总数据量/lane数

DSI为差分信号,一个clock内双沿采样,传输2bit数据

则最终PLL速率为每lane数据量/2

params->dsi.PLL_CLOCK = 208;
公式如下:
(VS+VBP+VACT+VFP)*(HS+HBP+HACT+HFP)* fps * format_bit
pll=(4+19+1440+18)*(20+20+720+20)*60*24/(4*2)=1481*780*60*24/8=207,932,400
  • 屏幕圆缺角设置

此功能主要是设定4个边角是圆弧形的。

static void lcm_get_params(LCM_PARAMS *params) {
    ...
    #ifdef MTK_ROUND_CORNER_SUPPORT
    	params->round_corner_params.round_corner_en = 1;
    	params->round_corner_params.full_content = 0;
    	params->round_corner_params.w = ROUND_CORNER_W;
    	params->round_corner_params.h = ROUND_CORNER_H;
    	params->round_corner_params.lt_addr = left_top;
    	params->round_corner_params.lb_addr = left_bottom;
    	params->round_corner_params.rt_addr = right_top;
    	params->round_corner_params.rb_addr = right_bottom;
    #endif
    ...
}
  • display-timming && DSI设置

DSI为4 lane,display-timming供应商提供如下:

ST7703 LCM显示屏调试--基于MT6765

	/* DSI */
	/* Command mode setting */
	params->dsi.LANE_NUM = LCM_FOUR_LANE;
	/* The following defined the fomat for data coming from LCD engine. */
	params->dsi.data_format.color_order = LCM_COLOR_ORDER_RGB;
	params->dsi.data_format.trans_seq = LCM_DSI_TRANS_SEQ_MSB_FIRST;
	params->dsi.data_format.padding = LCM_DSI_PADDING_ON_LSB;
	params->dsi.data_format.format = LCM_DSI_FORMAT_RGB888;

	/* Highly depends on LCD driver capability. */
	/* Not support in MT6573 */
	params->dsi.packet_size = 256;
	params->dsi.PS = LCM_PACKED_PS_24BIT_RGB888;

	params->dsi.vertical_sync_active	= 4;
	params->dsi.vertical_backporch		= 19;
	params->dsi.vertical_frontporch		= 18;
	params->dsi.vertical_active_line = FRAME_HEIGHT;

	params->dsi.horizontal_sync_active	= 20;
	params->dsi.horizontal_backporch	= 20;
	params->dsi.horizontal_frontporch	= 20;
	params->dsi.horizontal_active_pixel = FRAME_WIDTH;

	params->dsi.PLL_CLOCK = 230;	/* this value must be in MTK suggested table */

Lk调试打印

_dump_lcm_info(plcm)打印如下:

[1865] [DISP]func|disp_lcm_probe
[1869] [DISPCHECK]******** dump lcm driver information ********
[1874] [DISPCHECK][LCM], name: st7703_hd720_dsi_vdo
[1879] [DISPCHECK][LCM] resolution: 720 x 1440
[1883] [DISPCHECK][LCM] physical size: 0 x 0
[1887] [DISPCHECK][LCM] physical size: 0 x 0
[1891] [DISPCHECK][LCM] lcm_if:0, cmd_if:0
[1895] [DISPCHECK][LCM] interface: unknown
[1899] [DISPCHECK][LCM] Type: DSI
[1902] [DISPCHECK][LCM] DSI Mode: SYNC_PULSE_VDO_MODE
[1907] [DISPCHECK][LCM] LANE_NUM: 4,data_format:(0,2,0,0)
[1913] [DISPCHECK][LCM] vact: 4, vbp: 19, vfp: 18, vact_line: 1440, hact: 20, hbp: 20, hfp: 20, hblank: 0, hactive: 720
[1923] [DISPCHECK][LCM] pll_select: 0, pll_div1: 0, pll_div2: 0, fbk_div: 0,fbk_sel: 0, rg_bir: 0
[1932] [DISPCHECK][LCM] rg_bic: 0, rg_bp: 0, PLL_CLOCK: 230, dsi_clock: 0, ssc_range: 0,	ssc_disable: 0, compatibility_for_nvk: 0, cont_clock: 0
[1945] [DISPCHECK][LCM] lcm_ext_te_enable: 0, noncont_clock: 0, noncont_clock_period: 0

primary_display_init打印如下:

[2470] [DISP]func|primary_display_init
[2474] [LK_DDP/ddp_manager]ddp manager init
[2478] [DISPCHECK]disp_lcm_probe SUCCESS
[2481] [DISP]func|disp_lcm_get_params
[2485] [DISP]func|_build_path_direct_link
[2489] [LK_DDP/ddp_manager]scenario primary_disp acquire mutex 0 , left mutex 0xe!
[2496] [LK_DDP/ddp_manager]create handle 0x480b8710 on scenario primary_disp
[2503] [DISPCHECK]dpmgr create path SUCCESS(0x480b8710)
[2508] [LK_DDP/ddp_manager]set dst module on scenario primary_disp, module dsi0
[2515] [LK_DDP/ddp_path]ddp_set_dst_module, scenario=primary_disp, dst_module=dsi0
[2523] [LK_DDP/ddp_path]dsi0 is already on path
[2527] [DISPCHECK]dpmgr set dst module FINISHED(dsi0)
[2532] [LK_DDP/ddp_manager]path set lcm drv handle 0x480b8710
[2538] [LK_DDP/ddp_manager]dsi0 set lcm utils
[2542] [DISPCHECK]primary display is DIRECT LINK MODE
[2547] [DISPCHECK]primary display BUILD cmdq trigger loop finished
[2553] [DISPCHECK]primary display START cmdq trigger loop finished
[2559] [DISP]func|disp_lcm_is_video_mode
[2562] [LK_DDP/ddp_manager]set scenario primary_disp mode Video Mode
[2569] [LK_DDP/ddp_manager]path init on scenario primary_disp
[2574] [LK_DDP/ddp_path]ddp path top clock on
[2578] [LK_DDP/ddp_path]ddp CG0:df87ffff CG1:3ffff
[2583] [LK_DDP/ddp_path]ddp path m4u off
[2587] [LK_DDP/ddp_path]module ovl0 added to mutex 0
[2592] [LK_DDP/ddp_path]module ovl0_2l added to mutex 0
[2597] [LK_DDP/ddp_path]module rdma0 added to mutex 0
[2602] [LK_DDP/ddp_path]module disp_rsz0_virtual0 not added to mutex 0
[2608] [LK_DDP/ddp_path]module disp_rsz0_virtual1 not added to mutex 0
[2614] [LK_DDP/ddp_path]module pwm0 added to mutex 0
[2619] [LK_DDP/ddp_path]module dsi0 added to mutex 0
[2624] [LK_DDP/ddp_path]mutex 0 value=0x90380, sof=dsi0, eof=dsi0
[2630] [LK_DDP/ddp_path]path connect on scenario primary_disp
[2635] [LK_DDP/ddp_path]connect_path: ovl0 to dsi0
[2640] [LK_DDP/ddp_path]connect mout ovl0 to ovl0_2l  bits 0x2
[2646] [LK_DDP/ddp_path]connect mout ovl0_2l to rdma0  bits 0x1
[2651] [LK_DDP/ddp_path]connect out_s rdma0 to disp_rsz0_virtual0, value=0
[2658] [LK_DDP/ddp_path]connect out_s disp_rsz0_virtual1 to dsi0, value=0
[2665] [LK_DDP/ddp_path]connect in_s ovl0_2l to rdma0, value=1
[2670] [LK_DDP/ddp_path]connect in_s disp_rsz0_virtual0 to disp_rsz0_virtual1, value=0
[2678] [LK_DDP/ddp_path]connect in_s disp_rsz0_virtual1 to dsi0, value=0
[2685] [DISP]func|ddp_dsi_init
[2688] [DISPCHECK]dsi0 init finished
[2691] [LK_DDP/ddp_manager]path config ovl 0, rdma 0, wdma 0, dst 1 on handle 0x480b8710 scenario primary_disp 
[2701] [DISP]func|ddp_dsi_config
[2704] [DISPCHECK][DDPDSI] DSI Mode: SYNC_PULSE_VDO_MODE
[2709] [DISPCHECK][DDPDSI] LANE_NUM: 4,data_format:(0,2,0,0)
[2715] [DISPCHECK][DDPDSI] vact: 4, vbp: 19, vfp: 18, vact_line: 1440, hact: 20, hbp: 20, hfp: 20, hblank: 0
[2724] [DISPCHECK][DDPDSI] pll_select: 0, pll_div1: 0, pll_div2: 0, fbk_div: 0,fbk_sel: 0, rg_bir: 0
[2733] [DISPCHECK][DDPDSI] rg_bic: 0, rg_bp: 0, PLL_CLOCK: 208, dsi_clock: 0, ssc_range: 0,	ssc_disable: 1, compatibility_for_nvk: 0, cont_clock: 0
[2746] [DISPCHECK][DDPDSI] lcm_ext_te_enable: 0, noncont_clock: 0, noncont_clock_period: 0
[2755] [DISP]func|DSI_PHY_clk_setting
[2762] [DISP]func|DSI_PS_Control
[2765] [DISPCHECK][DISP] - LK - DSI_PHY_TIMCONFIG, pll=208, Cycle Time = 20(ns), Unit Interval = 3(ns). , lane# = 4
[2776] DISP/[DISP] - LK - DSI_PHY_TIMCONFIG, HS_TRAIL = 4, HS_ZERO = 8, HS_PRPR = 3, LPX = 4, TA_GET = 20, TA_SURE = 6, TA_GO = 16, CLK_TRAIL = 5, CLK_ZERO = 20, CLK_HS_PRPR = 3 
[2791] DISP/CLK_HS_POST=36,CLK_HS_EXIT=8,CLK_TRAIL=5
[2796] DSI_PHY_TIMCONFIG, 0x04080304,0x08140610,0x05140100,0x00082403
[2802] [DISP]func|DSI_Config_VDO_Timing
[2806] [DISP]func|disp_lcm_init
[2809] [DISPCHECK]lcm init_power 
[2812] [DISPCHECK]lcm init 
[2819] [LK/LCM]st7703----tps6132----cmd=b3--i2c write success----
[2827] [LK/LCM]st7703----tps6132----cmd=b4--i2c write success----
[2834] [LK/LCM]st7703----tps6132----cmd=b1--i2c write success----
[3265] [DISP]func|DSI_dcs_read_lcm_reg_v2
[3269] [DISPCHECK]Last DSI Read Why not clear irq???
[3274] [DISPCHECK]DSI_CMDQ_SIZE  : 1
[3277] [DISPCHECK]DSI_CMDQ_DATA0 : 0x00291500
[3281] [DISPCHECK]DSI_RX_DATA0   : 0x00000000
[3285] [DISPCHECK]DSI_RX_DATA1   : 0x00000000
[3290] [DISPCHECK]DSI_RX_DATA2   : 0x00000000
[3294] [DISPCHECK]DSI_RX_DATA3   : 0x00000000
[3298] DISP/ Start polling DSI read ready!!!
[3302] DISP/ End polling DSI read ready!!!
[3306] [DISPCHECK]DSI read begin i = 1 --------------------
[3311] [DISPCHECK]DSI_RX_STA     : 0x00000740
[3316] [DISPCHECK]DSI_CMDQ_SIZE  : 2
[3319] [DISPCHECK]DSI_CMDQ_DATA0 : 0x00013700
[3323] [DISPCHECK]DSI_CMDQ_DATA1 : 0x000a0604
[3327] [DISPCHECK]DSI_RX_DATA0   : 0x0c00011a
[3332] [DISPCHECK]DSI_RX_DATA1   : 0x0051629c
[3336] [DISPCHECK]DSI_RX_DATA2   : 0x00000000
[3340] [DISPCHECK]DSI_RX_DATA3   : 0x00000000
[3344] [DISPCHECK]DSI read end ----------------------------
[3350] [DISPCHECK]DSI read packet_type is 0x1a
[3354] [DISPCHECK]DSI read long packet size: 1
[3358] [DISP]read from lcm 0x0A: 156
[3362] [DISP]lcm is connected
[3364] [DISP]func|disp_lcm_is_video_mode
[3368] [LK_DDP/ddp_manager]map event 7 to irq 0x60004 on scenario primary_disp
[3375] [LK_DDP/ddp_manager]enable event on scenario primary_disp, event 7, irtbit 0x60004
[3383] [LK_DDP/ddp_manager]enable event on scenario primary_disp, event 1, irtbit 0x60004
[3394] [DISP]func|primary_display_config_input
[3398] [LK_DDP/ddp_manager]path check busy on scenario primary_disp
[3404] [DISP]func|ddp_dsi_is_busy
[3407] [LK_DDP/ddp_manager]path config ovl 1, rdma 0, wdma 0, dst 0 on handle 0x480b8710 scenario primary_disp 
[3417] [LK_DDP/OVL]module 0, layer=1, en=1, src=0, fmt=16785410, addr=0x7f4eb000, x=0, y=0, pitch=2880, dst(0, 0, 720, 1440),keyEn=0, key=0, aen=1, alpha=255
[3431] [LK_DDP/OVL]ovl0, layer=1, source=memory, off(x=0, y=0), dst(0, 0, 720, 1440),pitch=2880,fmt=eBGRA8888, addr=7f4eb000, keyEn=0, key=0, aen=1, alpha=255 
[3445] [DISP]func|ddp_dsi_config
[3448] [DISP]func|primary_display_config_input
[3453] [LK_DDP/ddp_manager]path check busy on scenario primary_disp
[3459] [DISP]func|ddp_dsi_is_busy
[3462] [LK_DDP/ddp_manager]path config ovl 1, rdma 0, wdma 0, dst 0 on handle 0x480b8710 scenario primary_disp 
[3472] [LK_DDP/OVL]module 0, layer=0, en=1, src=0, fmt=16785410, addr=0x7f0e0000, x=0, y=0, pitch=2944, dst(0, 0, 720, 1440),keyEn=0, key=0, aen=1, alpha=255
[3486] [LK_DDP/OVL]ovl0, layer=0, source=memory, off(x=0, y=0), dst(0, 0, 720, 1440),pitch=2944,fmt=eBGRA8888, addr=7f0e0000, keyEn=0, key=0, aen=1, alpha=255 
[3500] [LK_DDP/OVL]module 0, layer=1, en=1, src=0, fmt=16785410, addr=0x7f4eb000, x=0, y=0, pitch=2880, dst(0, 0, 720, 1440),keyEn=0, key=0, aen=1, alpha=255
[3514] [LK_DDP/OVL]ovl0, layer=1, source=memory, off(x=0, y=0), dst(0, 0, 720, 1440),pitch=2880,fmt=eBGRA8888, addr=7f4eb000, keyEn=0, key=0, aen=1, alpha=255 
[3528] [DISP]func|ddp_dsi_config
[3531] [DISP]mt_disp_init() done
上一篇:520了,用32做个简单的小程序


下一篇:逆向工程核心原理——第二十八章