diff --git a/drivers/video/sunxi/disp2/disp/dev_disp.c b/drivers/video/sunxi/disp2/disp/dev_disp.c index 7ad900b..1761309 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 screen1_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 screen2_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__, screen1_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,8 @@ static s32 disp_init(struct platform_device *pdev) para->start_process = start_process; //para.capture_event = capture_event; - value = disp_boot_para_parse(); + //value = disp_boot_para_parse(); + output_type = (value >> 8) & 0xff; output_mode = (value) & 0xff; if(output_type != (int)DISP_OUTPUT_TYPE_NONE) { @@ -1126,7 +1205,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 +1217,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 +1236,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 +1250,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 +1263,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 +1284,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 +1302,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; }