(200730_19:48:00.187)[320] [DISP]func|primary_display_init
(200730_19:48:00.187)[320] [DISPCHECK]disp_lcm_probe SUCCESS
(200730_19:48:00.187)[321] [DISP]func|disp_lcm_get_params
...
(200730_19:48:00.994)[1146] [DISP]read from lcm 0x0A: 0
(200730_19:48:00.994)[1146] [DISP]lcm is not connected
(200730_19:48:00.994)[1146] [DISP]func|disp_lcm_is_video_mode
(200730_19:48:00.994)[1152] [DISP]func|primary_display_config_input
(200730_19:48:00.994)[1153] [DISP]func|ddp_dsi_is_busy
...
(200730_19:48:02.456)[2634] boot_voltage buf [0], [0x560bb24c:0x560bb24d:1]
(200730_19:48:02.456)[2635] boot_voltage buf [0], [0x560bb24c:0x560bb24d:1]
(200730_19:48:02.457)[2636] Not Support VCORE DVFS
(200730_19:48:02.457)[2637] [DISP]func|disp_lcm_get_name
(200730_19:48:02.457)[2637] [DISP]ERROR:wait event fail
(200730_19:48:02.457)[2637] mt_disp_get_lcd_time, fps=0 //如果fps=0, 强制fps=60
(200730_19:48:02.457)[2638] videolfb - fb_base = 0x7be20000
(200730_19:48:02.457)[2638] videolfb - islcmfound = 0
(200730_19:48:02.458)[2639] videolfb - fps = 6000
(200730_19:48:02.458)[2639] videolfb - vram = 29229056
(200730_19:48:02.458)[2639] videolfb - lcmname = jd9366_wxga_dsi_vdo_fiti_kd
/vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6765/ddp_dsi.c #mipi相关
LK启动流程:
kmain //main.c
->thread_init_early(); //thread.c get us into some sort of thread context
->arch_early_init(); //arch.c early arch stuff
->platform_early_init(); //platform.c do any super early platform initialization
->platform_init_interrupts(); //interrupts.c
->platform_early_init_timer(); //timer.c
->mt_gpio_set_default(); //mt_gpio_init.c
->uart_init_early(); //uart.c
->mtk_wdt_init() //mtk_wdt.c
->i2c_hw_init(); //mt_i2c.c
->leds_init(); //mt_leds.c
->pmic_init(); //mt_pmic.c、mt_pmic_mt6392.c
->target_early_init(); //init.c do any super early target initialization
->call_constructors(); //main.c deal with any static constructors
->heap_init(); //heap.c bring up the kernel heap
->thread_init(); //thread.c initialize the threading system
->dpc_init(); //dpc.c initialize the dpc system
->timer_init(); //timer.c initialize kernel timers
->thread_t *thread_bs2 = thread_create("bootstrap2", &bootstrap2, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE); //main.c create a thread to complete system initialization
->arch_init(); //arch.c
->mboot_allocate_lk_scratch_from_mblock(); //mt_boot.c Allocate LK memory from mb, free before jump to kernel
->platform_init() //platform.c initialize the rest of the platform //8167 9.0会打开PARALLEL_PART_FLOW,并行开启两个线程初始化disp_thread_routine、storage_thread_routine,10.0就是串行初始化
->mmc_legacy_init(1); //mmc_common_inter.c
->mt_part_register_device(&boot_dev); //combo_emmc_ufs_generic_inter.c
->mt_part_dev = dev;
->dump_boot_arg(); //platform.c
->load_device_tree(); //fdt_op.c The device tree should be loaded as early as possible
->if ((g_boot_arg->boot_reason == BR_USB) && (upmu_is_chr_det() == KAL_FALSE))
->mt6575_power_off(); //power_off.c
->rtc_bbpu_power_down() //rtc.c
->env_init(); //env.c
->print_env(); //env.c //mt_disp_get_vram_size->DISP_GetVRamSize->DISP_GetFBRamSize->DISP_GetScreenWidth->primary_display_get_width->if (pgc->plcm == NULL)->disp_lcm_probe->get_params
->g_fb_size = mt_disp_get_vram_size(); //initialize the frame buffet information
->g_fb_base = mblock_reserve_ext(&g_boot_arg->mblock_info, g_fb_size, 0x10000, 0x100000000, 0, "framebuffer");
->mt_disp_init((void *)g_fb_base) //mt_disp_drv.c
->primary_display_init(NULL) //primary_display.c
->dpmgr_init(); //ddp_manager.c
->if (pgc->plcm == NULL)
->pgc->plcm = disp_lcm_probe( lcm_name, LCM_INTERFACE_NOTDEFINED); //disp_lcm.c
->lcm_param = disp_lcm_get_params(pgc->plcm); //disp_lcm.c
->dpmgr_path_set_video_mode(pgc->dpmgr_handle, primary_display_is_video_mode()); //ddp_manager.c
->dpmgr_path_init(pgc->dpmgr_handle, CMDQ_DISABLE); //ddp_manager.c
->dpmgr_path_config(pgc->dpmgr_handle, &data_config, CMDQ_DISABLE); //ddp_manager.c
->disp_lcm_init(pgc->plcm) //disp_lcm.c
->lcm_drv->init_power();
->lcm_drv->init();
->plcm->is_connected = isLCMConnected;
->dpmgr_enable_event(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC); //ddp_manager.c
->dpmgr_enable_event(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC); //ddp_manager.c
->pgc->state = 1;
->display_init = 1;
->disp_input_config input; //struct is defined in primary_display.h
->memset(&input, 0, sizeof(disp_input_config));
->input.layer = BOOT_MENU_LAYER; ... ...
->primary_display_config_input(&input); //primary_display.c
->memset(&input, 0, sizeof(disp_input_config));
->input.layer = FB_LAYER; ... ...
->primary_display_config_input(&input); //primary_display.c
->drv_video_init(); //mtk_cfb.c set cursor to the right-bottom corner,scroll screen immediately for the first time video_printf()
->mboot_common_load_logo((unsigned long)mt_get_logo_db_addr_pa(), "logo"); //load_image.c
->set_kpd_pmic_mode(); //keypad.c for kpd pmic mode setting
->boot_mode_select(); //boot_mode.c
->BOOTMODE g_boot_mode = NORMAL_BOOT; // global variable for specifying boot mode (default = NORMAL)
->mtk_detect_key(MT65XX_FACTORY_KEY) g_boot_mode = FACTORY_BOOT;
->mtk_detect_key(MT65XX_BOOT_MENU_KEY) boot_menu_select();
->mtk_detect_key(MT65XX_RECOVERY_KEY) g_boot_mode = RECOVERY_BOOT;
->kernel_power_off_charging_detection()
->off_mode_status = get_off_mode_charge_status();
->if (off_mode_status) {
->g_boot_mode = KERNEL_POWER_OFF_CHARGING_BOOT;
->mtk_wdt_boot_check(); //mtk_wdt.c rollback boot reason
->sec_func_init(pl_start_addr); //initialize security library 找不到实现方法,应该是不开源的
->if (g_boot_arg->boot_mode == DOWNLOAD_BOOT) {
->mt65xx_backlight_on();
->enum led_brightness backlight_level = get_cust_led_default_level();
->mt65xx_leds_brightness_set(MT65XX_LED_TYPE_LCD, backlight_level);
->mtk_wdt_disable(); //Disable wdt before jump to DA
->platform_uninit();
->arch_disable_cache(UCACHE);
->arch_disable_mmu();
->config_shared_SRAM_size();
->jump_da(g_boot_arg->da_info.addr, g_boot_arg->da_info.arg1, g_boot_arg->da_info.arg2);
->#ifdef MTK_CHARGER_NEW_ARCH //mt8168 公版默认
->mtk_charger_init(); //mtk_charger_intf.c
->pmic_dlpt_init();
->check_sw_ocv();
->mtk_charger_start();
->get_dlpt_imix_r();
->#else
->mt65xx_bat_init(); //mt_battery.c mt8168需要手动添加该文件
->if (is_low_battery(bat_vol))
->check_bat_protect_status();
->#endif
->rtc_boot_check(false); //* NOTE: if define CFG_POWER_CHARGING, will rtc_boot_check() in mt65xx_bat_init() */
->if (kernel_charging_boot() == 1) //关机充电且充电器存在1,关机充电且充电器不存在-1,其它0
->mt_disp_power(TRUE);
->mt_disp_show_low_battery(); //mt_logo.c 爱高的要改成:mt_disp_show_battery_capacity(get_battery_capacity());
->mt65xx_leds_brightness_set(6, 110);
->如果是NORMAL_BOOT、META_BOOT、RECOVERY_BOOT、FACTORY_BOOT...
->mt_disp_show_boot_logo();
->mt65xx_backlight_on(); //mt_leds.c 爱高的还要判断,如果关机充电且充电器不存在-1,则不亮背光
->enum led_brightness backlight_level = get_cust_led_default_level();
->mt65xx_leds_brightness_set(MT65XX_LED_TYPE_LCD, backlight_level);
->struct cust_mt65xx_led *cust_led_list = get_cust_led_list() //返回在cust_leds.c定义的结构体指针
->mt65xx_led_set_cust(&cust_led_list[type], level); //int mt65xx_led_set_cust(struct cust_mt65xx_led *cust, int level) //传入相应TYPE的数组元素地址
->switch (cust->mode) {
->case MT65XX_LED_MODE_CUST_BLS_PWM:
->((cust_brightness_set)(cust->data))(level); //disp_bls_set_backlight
->level_1024 = (level_256 << 2) + 2; //将255等级转换为1023等级
->disp_pwm_set_backlight(disp_pwm_get_main(), level_1024); //static disp_pwm_id_t g_pwm_main_id = DISP_PWM0;
->disp_pwm_init(id);
->reg_base = pwm_get_reg_base(id); //#define pwm_get_reg_base(id) ((id) == DISP_PWM0 ? DISPSYS_PWM0_BASE : DISPSYS_PWM0_BASE)
->level_1024 = disp_pwm_level_remap(id, level_1024); //return level_1024;
->PWM_REG_SET(reg_base + DISP_PWM_COMMIT_OFF, 0);
->PWM_REG_SET(reg_base + DISP_PWM_CON_1_OFF, (level_1024 << 16) | 0x3ff); //设置PWM level
->disp_pwm_set_enabled(id, 1);
->reg_base = pwm_get_reg_base(id);
->if (!disp_pwm_is_enabled(id))
->PWM_REG_SET(reg_base + DISP_PWM_EN_OFF, 0x1); //使能PWM
->primary_display_trigger(TRUE); //primary_display.c pwm need display sof
->sw_env(); //platform.c end of platform_init()
->target_init(); //init.c initialize the target empty function
->apps_init //app.c
->const struct app_descriptor *app
->app->init(app)
->mt_boot_init
->boot_linux_from_storage
->boot_linux
->boot_linux_fdt
->target_atag_videolfb
->mt_disp_get_lcd_time
->primary_display_get_vsync_interval
->thread_t *thread_io = thread_create("iothread", &iothread, NULL, IO_THREAD_PRIORITY, DEFAULT_STACK_SIZE); //iothread.c
->exit_critical_section(); //thread.h enable interrupts
->thread_become_idle(); //thread.c become the idle thread
#define PWM_REG_SET(reg, value) do { \ //vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt8168/ddp_pwm.c
mt65xx_reg_sync_writel(value, (volatile unsigned int*)(reg)); \
PWM_DBG("set reg[0x%08x] = 0x%08x", (unsigned int)reg, (unsigned int)value); \
} while (0)
Mediatek Replied at 2020-08-03 10:18:27
应该是贵司使用的屏,不支持0x0A信息读取,将disp_lcm_init中的#ifndef MACH_FPGA 改成#if 0,强制令isLCMConnected = 1;即可
/vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt8168/disp_lcm.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
int disp_lcm_init(disp_lcm_handle *plcm) { DISPFUNC(); LCM_DRIVER *lcm_drv = NULL; bool isLCMConnected = false; if (_is_lcm_inited(plcm)) { lcm_drv = plcm->drv; if (lcm_drv->init_power) { DISPCHECK("lcm init_power \n"); lcm_drv->init_power(); } if (lcm_drv->init) { if (!disp_lcm_is_inited(plcm)) { DISPCHECK("lcm init \n"); lcm_drv->init(); } } else { DISPERR("FATAL ERROR, lcm_drv->init is null\n"); return -1; } #if 0 //#ifndef MACH_FPGA //MTK REMOVED for fixing "read 0x0A failed" if (LCM_TYPE_DSI == plcm->params->type) { int ret = 0; char buffer = 0; 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"); } } if (plcm->params->dsi.edp_panel == 1) { isLCMConnected = 1; } #else isLCMConnected = 1; #endif plcm->is_connected = isLCMConnected; //ddp_dsi_start(DISP_MODULE_DSI0, NULL); //DSI_BIST_Pattern_Test(DISP_MODULE_DSI0,NULL,true, 0x00ffff00); //ddp_dsi_dump(DISP_MODULE_DSI0, 2); return 0; } else { DISPERR("plcm is null\n"); return -1; } } |
/vendor/mediatek/proprietary/bootable/bootloader/lk/app/mt_boot/mt_boot.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
extern unsigned *target_atag_videolfb(unsigned *ptr, size_t buf_size); int boot_linux_fdt(void *kernel, unsigned *tags, unsigned machtype, void *ramdisk, unsigned ramdisk_sz) { ... #ifndef MACH_FPGA_NO_DISPLAY ptr = (char *)target_atag_videolfb((unsigned *)buf, FDT_BUFF_SIZE); ret = fdt_setprop(fdt, offset, "atag,videolfb", buf, ptr - buf); if (ret) { assert(0); return FALSE; } #if (MTK_DUAL_DISPLAY_SUPPORT == 2) ptr = (char *)target_atag_ext_videolfb((unsigned *)buf); ret = fdt_setprop(fdt, offset, "atag,ext_videolfb", buf, ptr - buf); if (ret) { assert(0); return FALSE; } #endif #else ... ... } |
/vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt8168/atags.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
unsigned *target_atag_videolfb(unsigned *ptr, size_t buf_size) { extern unsigned long long fb_addr_pa_k; const char *lcmname = mt_disp_get_lcm_id(); unsigned int *p = NULL; unsigned long long *phy_p = (unsigned long long *)ptr; int lcd_time; #ifdef MACH_FPGA *phy_p = fb_addr_pa_k = g_fb_base; #else *phy_p = fb_addr_pa_k; #endif p = (unsigned int*)(phy_p + 1); *p++ = DISP_IsLcmFound(); #ifdef MACH_FPGA //no *p++ = lcd_time = 6000; #else *p++ = lcd_time = mt_disp_get_lcd_time(); #endif *p++ = DISP_GetVRamSize(); strcpy((char *)p,lcmname); p += (strlen(lcmname) + 1 + 4) >> 2; dprintf(CRITICAL, "videolfb - fb_base = 0x%llx\n",fb_addr_pa_k); dprintf(CRITICAL, "videolfb - islcmfound = %d\n",DISP_IsLcmFound()); dprintf(CRITICAL, "videolfb - fps = %d\n",lcd_time); dprintf(CRITICAL, "videolfb - vram = %d\n",DISP_GetVRamSize()); dprintf(CRITICAL, "videolfb - lcmname = %s\n",lcmname); return (unsigned *)p; } |
/vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt8168/mt_disp_drv.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
UINT32 mt_disp_get_lcd_time(void) { static unsigned int fps = 0; if (!fps) { fps = primary_display_get_vsync_interval(); dprintf(CRITICAL, "%s, fps=%d\n", __func__, fps); if (!fps) fps = 6000; } return fps; } |
/vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt8168/primary_display.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
int primary_display_get_vsync_interval(void) { int ret = 0; unsigned int time0 = 0; unsigned int time1 = 0; unsigned int lcd_time = 0; if (pgc->plcm->is_connected == false) goto fail; pgc->plcm->is_connected = false; ret = dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC,1000); if (ret <= 0) goto fail; ret = dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC,1000); if (ret <= 0) goto fail; // because we are polling irq status, so the first event should be ignored time0 = gpt4_tick2time_us(gpt4_get_current_tick()); //DISPMSG("vsync signaled:%d\n", gpt4_tick2time_us(gpt4_get_current_tick())); ret = dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC,1000); if (ret <= 0) goto fail; //DISPMSG("vsync signaled:%d\n", gpt4_tick2time_us(gpt4_get_current_tick())); ret = dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC,1000); if (ret > 0) { time1 = gpt4_tick2time_us(gpt4_get_current_tick()); } else goto fail; lcd_time = (time1 - time0)/2; pgc->plcm->is_connected = true; if (0 != lcd_time) return (100000000/lcd_time); else return (6000); fail: DISPERR("wait event fail\n"); return 0; } |