diff --git a/patch/kernel/sun8i-default/0006-h3-videomode-cmdline.patch b/patch/kernel/sun8i-default/0006-h3-videomode-cmdline.patch new file mode 100644 index 000000000..3511d65a6 --- /dev/null +++ b/patch/kernel/sun8i-default/0006-h3-videomode-cmdline.patch @@ -0,0 +1,386 @@ +diff --git a/drivers/video/sunxi/disp2/disp/dev_disp.c b/drivers/video/sunxi/disp2/disp/dev_disp.c +index 7ad900b..27f56c6 100755 +--- a/drivers/video/sunxi/disp2/disp/dev_disp.c ++++ b/drivers/video/sunxi/disp2/disp/dev_disp.c +@@ -12,6 +12,38 @@ + + #include "dev_disp.h" + ++#define VIDEOMODE_CMDLINE 1 ++ ++#ifdef VIDEOMODE_CMDLINE ++static int screen0_output_type = -1; ++module_param(screen0_output_type, int, 0444); ++MODULE_PARM_DESC(screen0_output_type, "0:none; 1:lcd; 2:tv; 3:hdmi; 4:vga"); ++ ++static char *screen0_output_mode; ++module_param(screen0_output_mode, charp, 0444); ++MODULE_PARM_DESC(screen0_output_mode, ++ "used for hdmi output" ++ "0:480i 1:576i 2:480p 3:576p 4:720p50" ++ "5:720p60 6:1080i50 7:1080i60 8:1080p24 9:1080p50 10:1080p60" ++ "check sys_config.fex for more info."); ++ ++static int screen1_output_type = -1; ++module_param(screen1_output_type, int, 0444); ++MODULE_PARM_DESC(screen1_output_type, "0:none; 1:lcd; 2:tv; 3:hdmi; 4:vga"); ++ ++static char *screen1_output_mode; ++module_param(screen1_output_mode, charp, 0444); ++MODULE_PARM_DESC(screen1_output_mode, "See screen0_output_mode"); ++ ++static int screen2_output_type = -1; ++module_param(screen2_output_type, int, 0444); ++MODULE_PARM_DESC(screen2_output_type, "0:none; 1:lcd; 2:tv; 3:hdmi; 4:vga"); ++ ++static char *screen2_output_mode; ++module_param(screen2_output_mode, charp, 0444); ++MODULE_PARM_DESC(screen2_output_mode, "See screen0_output_mode"); ++#endif ++ + disp_drv_info g_disp_drv; + + #define MY_BYTE_ALIGN(x) ( ( (x + (4*1024-1)) >> 12) << 12) /* alloc based on 4K byte */ +@@ -371,6 +403,13 @@ static s32 parser_disp_init_para(disp_init_para * init_para) + init_para->disp_mode= value; + + //screen0 ++#ifdef VIDEOMODE_CMDLINE ++ if (screen0_output_type != -1) { ++ value = screen0_output_type; ++ pr_info("[DISP]%s: screen0_output_type(%d)\n", __func__, screen0_output_type); ++ } ++ else ++#endif + if(disp_sys_script_get_item("disp_init", "screen0_output_type", &value, 1) < 0) { + __wrn("fetch script data disp_init.screen0_output_type fail\n"); + return -1; +@@ -390,6 +429,15 @@ static s32 parser_disp_init_para(disp_init_para * init_para) + return -1; + } + ++#ifdef VIDEOMODE_CMDLINE ++ if (screen0_output_mode != NULL) { ++ // TODO: support sunxi mode ++ sscanf(screen0_output_mode, "%d", &value); ++ pr_info("[DISP]%s: screen0_output_mode(%s) value(%d)\n", __func__, screen0_output_mode, value); ++ } ++ else ++#endif ++ + if(disp_sys_script_get_item("disp_init", "screen0_output_mode", &value, 1) < 0) { + __wrn("fetch script data disp_init.screen0_output_mode fail\n"); + return -1; +@@ -400,6 +448,13 @@ static s32 parser_disp_init_para(disp_init_para * init_para) + } + + //screen1 ++#ifdef VIDEOMODE_CMDLINE ++ if (screen1_output_type != -1) { ++ value = screen1_output_type; ++ pr_info("[DISP]%s: screen1_output_type(%d)\n", __func__, screen1_output_type); ++ } ++ else ++#endif + if(disp_sys_script_get_item("disp_init", "screen1_output_type", &value, 1) < 0) { + __wrn("fetch script data disp_init.screen1_output_type fail\n"); + return -1; +@@ -419,6 +474,14 @@ static s32 parser_disp_init_para(disp_init_para * init_para) + return -1; + } + ++#ifdef VIDEOMODE_CMDLINE ++ if (screen1_output_mode != NULL) { ++ // TODO: support sunxi mode ++ sscanf(screen1_output_mode, "%d", &value); ++ pr_info("[DISP]%s: screen1_output_mode(%s) value(%d)\n", __func__, screen0_output_mode, value); ++ } ++ else ++#endif + if(disp_sys_script_get_item("disp_init", "screen1_output_mode", &value, 1) < 0) { + __wrn("fetch script data disp_init.screen1_output_mode fail\n"); + return -1; +@@ -429,6 +492,13 @@ static s32 parser_disp_init_para(disp_init_para * init_para) + } + + //screen2 ++#ifdef VIDEOMODE_CMDLINE ++ if (screen2_output_type != -1) { ++ value = screen2_output_type; ++ pr_info("[DISP]%s: screen2_output_type(%d)\n", __func__, screen2_output_type); ++ } ++ else ++#endif + if(disp_sys_script_get_item("disp_init", "screen2_output_type", &value, 1) < 0) { + __inf("fetch script data disp_init.screen2_output_type fail\n"); + } +@@ -446,6 +516,14 @@ static s32 parser_disp_init_para(disp_init_para * init_para) + __inf("invalid screen0_output_type %d\n", init_para->output_type[2]); + } + ++#ifdef VIDEOMODE_CMDLINE ++ if (screen2_output_mode != NULL) { ++ // TODO: support sunxi mode ++ sscanf(screen2_output_mode, "%d", &value); ++ pr_info("[DISP]%s: screen2_output_mode(%s) value(%d)\n", __func__, screen2_output_mode, value); ++ } ++ else ++#endif + if(disp_sys_script_get_item("disp_init", "screen2_output_mode", &value, 1) < 0) { + __inf("fetch script data disp_init.screen2_output_mode fail\n"); + } +@@ -902,7 +980,10 @@ static s32 disp_init(struct platform_device *pdev) + para->start_process = start_process; + //para.capture_event = capture_event; + +- value = disp_boot_para_parse(); ++ //Justin Porting 20150707 Start ++ //value = disp_boot_para_parse(); ++ //Justin Porting 20150707 End ++ + output_type = (value >> 8) & 0xff; + output_mode = (value) & 0xff; + if(output_type != (int)DISP_OUTPUT_TYPE_NONE) { +@@ -1126,7 +1207,8 @@ static int disp_remove(struct platform_device *pdev) + return 0; + } + +-void suspend() ++#if defined(CONFIG_HAS_EARLYSUSPEND) ++void backlight_early_suspend(struct early_suspend *h) + { + u32 screen_id = 0; + int num_screens; +@@ -1137,23 +1219,18 @@ void suspend() + + num_screens = bsp_disp_feat_get_num_screens(); + ++ disp_suspend_cb(); + for(screen_id=0; screen_iddevice) { + struct disp_device *dispdev = mgr->device; + + suspend_output_type[screen_id] = bsp_disp_get_output_type(screen_id); +- if(suspend_output_type[screen_id] == DISP_OUTPUT_TYPE_LCD) { +- if(2 == suspend_prestep) { +- /* resume -> suspend */ +- flush_work(&g_disp_drv.resume_work[screen_id]); +- } +- } + if(dispdev->is_enabled(dispdev)) + dispdev->disable(dispdev); + } + } +- ++ //FIXME: hdmi suspend + disp_list = disp_device_get_list_head(); + list_for_each_entry(dispdev_suspend, disp_list, list) { + if (dispdev_suspend->suspend) { +@@ -1161,9 +1238,13 @@ void suspend() + } + } + ++ suspend_status |= DISPLAY_LIGHT_SLEEP; ++ suspend_prestep = 0; ++ ++ pr_info("%s finish\n", __func__); + } + +-void resume() ++void backlight_late_resume(struct early_suspend *h) + { + u32 screen_id = 0; + int num_screens; +@@ -1171,8 +1252,6 @@ void resume() + struct disp_device* dispdev = NULL; + struct list_head* disp_list= NULL; + pr_info("%s\n", __func__); +- +- + num_screens = bsp_disp_feat_get_num_screens(); + + disp_list = disp_device_get_list_head(); +@@ -1186,13 +1265,15 @@ void resume() + mgr = g_disp_drv.mgr[screen_id]; + if(!mgr || !mgr->device) + continue; ++ + if(suspend_output_type[screen_id] == DISP_OUTPUT_TYPE_LCD) { +- if(0 == suspend_prestep || 2 == suspend_prestep) { +- /* early_suspend --> late_resume or resume -- > late_resume */ ++ if(0 == suspend_prestep) { ++ /* early_suspend --> late_resume */ + mgr->device->enable(mgr->device); + } else { + /* resume -> late_resume */ +- schedule_work(&g_disp_drv.resume_work[screen_id]); ++ flush_work(&g_disp_drv.resume_work[screen_id]); ++ mgr->device->pwm_enable(mgr->device); + mgr->device->backlight_enable(mgr->device); + } + } else if(suspend_output_type[screen_id] != DISP_OUTPUT_TYPE_NONE) { +@@ -1205,25 +1286,11 @@ void resume() + } + } + +-} +- +-#if defined(CONFIG_HAS_EARLYSUSPEND) +-void backlight_early_suspend(struct early_suspend *h) +-{ +- pr_info("%s\n", __func__); +- msleep(300); +- suspend(); +- suspend_status |= DISPLAY_LIGHT_SLEEP; +- suspend_prestep = 0; +- pr_info("%s finish\n", __func__); +-} +- +-void backlight_late_resume(struct early_suspend *h) +-{ +- pr_info("%s\n", __func__); +- resume(); + suspend_status &= (~DISPLAY_LIGHT_SLEEP); + suspend_prestep = 3; ++ ++ disp_resume_cb(); ++ + pr_info("%s finish\n", __func__); + } + +@@ -1237,30 +1304,120 @@ static struct early_suspend backlight_early_suspend_handler = + + static int disp_suspend(struct platform_device *pdev, pm_message_t state) + { +- pr_info("%s\n", __func__); ++ u32 screen_id = 0; ++ int num_screens; ++ struct disp_manager *mgr = NULL; ++ + #if !defined(CONFIG_HAS_EARLYSUSPEND) +- msleep(300); +- suspend(); +-#endif ++ ++ struct disp_device* dispdev_suspend = NULL; ++ struct list_head* disp_list= NULL; ++ ++ pr_info("%s\n", __func__); ++ num_screens = bsp_disp_feat_get_num_screens(); ++ + disp_suspend_cb(); ++ for(screen_id=0; screen_iddevice) ++ continue; ++ if(suspend_output_type[screen_id] != DISP_OUTPUT_TYPE_NONE) ++ mgr->device->disable(mgr->device); ++ } ++ ++ /*suspend for all display device*/ + ++ disp_list = disp_device_get_list_head(); ++ list_for_each_entry(dispdev_suspend, disp_list, list) { ++ if (dispdev_suspend->suspend) { ++ dispdev_suspend->suspend(dispdev_suspend); ++ } ++ } ++ ++#else ++ pr_info("%s\n", __func__); ++ num_screens = bsp_disp_feat_get_num_screens(); ++ ++ for(screen_id=0; screen_iddevice) ++ continue; ++ if(suspend_output_type[screen_id] == DISP_OUTPUT_TYPE_LCD) { ++ if(2 == suspend_prestep) { ++ /* resume -> suspend */ ++ flush_work(&g_disp_drv.resume_work[screen_id]); ++ mgr->device->disable(mgr->device); ++ } ++ } ++ } ++#endif ++ //FIXME: hdmi suspend + suspend_status |= DISPLAY_DEEP_SLEEP; + suspend_prestep = 1; ++ + pr_info("%s finish\n", __func__); ++ + return 0; + } + + + static int disp_resume(struct platform_device *pdev) + { +- pr_info("%s\n", __func__); +- disp_resume_cb(); ++ u32 screen_id = 0; ++ int num_screens; ++ struct disp_manager *mgr = NULL; ++ + #if !defined(CONFIG_HAS_EARLYSUSPEND) +- resume(); ++ ++ struct disp_device* dispdev_resume = NULL; ++ struct list_head* disp_list= NULL; ++ ++ pr_info("%s\n", __func__); ++ num_screens = bsp_disp_feat_get_num_screens(); ++ ++ disp_list = disp_device_get_list_head(); ++ list_for_each_entry(dispdev_resume, disp_list, list) { ++ if (dispdev_resume->resume) { ++ dispdev_resume->resume(dispdev_resume); ++ } ++ } ++ ++ for(screen_id=0; screen_iddevice) ++ continue; ++ if(suspend_output_type[screen_id] != DISP_OUTPUT_TYPE_NONE) { ++ if(mgr->device->set_mode && mgr->device->get_mode) { ++ u32 mode = mgr->device->get_mode(mgr->device); ++ ++ mgr->device->set_mode(mgr->device, mode); ++ } ++ ++ mgr->device->enable(mgr->device); ++ } ++ } ++ disp_resume_cb(); ++#else ++ pr_info("%s\n", __func__); ++ num_screens = bsp_disp_feat_get_num_screens(); ++ ++ for(screen_id=0; screen_iddevice) ++ continue; ++ ++ if(suspend_output_type[screen_id] == DISP_OUTPUT_TYPE_LCD) { ++ schedule_work(&g_disp_drv.resume_work[screen_id]); ++ } ++ } + #endif ++ + suspend_status &= (~DISPLAY_DEEP_SLEEP); + suspend_prestep = 2; +- pr_info("%s\n finish", __func__); ++ ++ pr_info("%s\n", __func__); ++ + return 0; + } + +@@ -1783,4 +1940,3 @@ MODULE_DESCRIPTION("display driver"); + MODULE_LICENSE("GPL"); + MODULE_ALIAS("platform:disp"); + +- +