@@ -1916,6 +1916,68 @@ static irqreturn_t test_hw_vsync_handler(int irq, void *data)
19161916 return IRQ_HANDLED ;
19171917}
19181918
1919+ static int mdss_dsi_disp_wake_thread (void * data )
1920+ {
1921+ static const struct sched_param max_rt_param = {
1922+ .sched_priority = MAX_RT_PRIO - 1
1923+ };
1924+ struct mdss_dsi_ctrl_pdata * ctrl_pdata = data ;
1925+ struct mdss_panel_data * pdata = & ctrl_pdata -> panel_data ;
1926+
1927+ sched_setscheduler_nocheck (current , SCHED_FIFO , & max_rt_param );
1928+
1929+ while (1 ) {
1930+ bool should_stop ;
1931+
1932+ wait_event (ctrl_pdata -> wake_waitq ,
1933+ (should_stop = kthread_should_stop ()) ||
1934+ atomic_cmpxchg (& ctrl_pdata -> disp_en ,
1935+ MDSS_DISPLAY_WAKING ,
1936+ MDSS_DISPLAY_ON ) == MDSS_DISPLAY_WAKING );
1937+
1938+ if (should_stop )
1939+ break ;
1940+
1941+ /* MDSS_EVENT_LINK_READY */
1942+ if (ctrl_pdata -> refresh_clk_rate )
1943+ mdss_dsi_clk_refresh (pdata ,
1944+ ctrl_pdata -> update_phy_timing );
1945+ mdss_dsi_on (pdata );
1946+
1947+ /* MDSS_EVENT_UNBLANK */
1948+ mdss_dsi_unblank (pdata );
1949+
1950+ /* MDSS_EVENT_PANEL_ON */
1951+ ctrl_pdata -> ctrl_state |= CTRL_STATE_MDP_ACTIVE ;
1952+ pdata -> panel_info .esd_rdy = true;
1953+
1954+ complete_all (& ctrl_pdata -> wake_comp );
1955+ }
1956+
1957+ return 0 ;
1958+ }
1959+
1960+ static void mdss_dsi_display_wake (struct mdss_dsi_ctrl_pdata * ctrl_pdata )
1961+ {
1962+ if (atomic_cmpxchg (& ctrl_pdata -> disp_en , MDSS_DISPLAY_OFF ,
1963+ MDSS_DISPLAY_WAKING ) == MDSS_DISPLAY_OFF )
1964+ wake_up (& ctrl_pdata -> wake_waitq );
1965+ }
1966+
1967+ static int mdss_dsi_fb_unblank_cb (struct notifier_block * nb ,
1968+ unsigned long action , void * data )
1969+ {
1970+ struct mdss_dsi_ctrl_pdata * ctrl_pdata =
1971+ container_of (nb , typeof (* ctrl_pdata ), wake_notif );
1972+ int * blank = ((struct fb_event * )data )-> data ;
1973+
1974+ /* Parse unblank events as soon as they occur */
1975+ if (action == FB_EARLY_EVENT_BLANK && * blank == FB_BLANK_UNBLANK )
1976+ mdss_dsi_display_wake (ctrl_pdata );
1977+
1978+ return NOTIFY_OK ;
1979+ }
1980+
19191981int mdss_dsi_cont_splash_on (struct mdss_panel_data * pdata )
19201982{
19211983 int ret = 0 ;
@@ -3029,25 +3091,12 @@ static int mdss_dsi_event_handler(struct mdss_panel_data *pdata,
30293091 ctrl_pdata -> refresh_clk_rate = true;
30303092 break ;
30313093 case MDSS_EVENT_LINK_READY :
3032- if (ctrl_pdata -> refresh_clk_rate )
3033- rc = mdss_dsi_clk_refresh (pdata ,
3034- ctrl_pdata -> update_phy_timing );
3035-
3036- rc = mdss_dsi_on (pdata );
3037- break ;
3038- case MDSS_EVENT_UNBLANK :
3039- if (ctrl_pdata -> on_cmds .link_state == DSI_LP_MODE )
3040- rc = mdss_dsi_unblank (pdata );
3094+ /* The unblank notifier handles waking for unblank events */
3095+ mdss_dsi_display_wake (ctrl_pdata );
30413096 break ;
30423097 case MDSS_EVENT_POST_PANEL_ON :
30433098 rc = mdss_dsi_post_panel_on (pdata );
30443099 break ;
3045- case MDSS_EVENT_PANEL_ON :
3046- ctrl_pdata -> ctrl_state |= CTRL_STATE_MDP_ACTIVE ;
3047- if (ctrl_pdata -> on_cmds .link_state == DSI_HS_MODE )
3048- rc = mdss_dsi_unblank (pdata );
3049- pdata -> panel_info .esd_rdy = true;
3050- break ;
30513100 case MDSS_EVENT_BLANK :
30523101 power_state = (int ) (unsigned long ) arg ;
30533102 if (ctrl_pdata -> off_cmds .link_state == DSI_HS_MODE )
@@ -3059,6 +3108,8 @@ static int mdss_dsi_event_handler(struct mdss_panel_data *pdata,
30593108 if (ctrl_pdata -> off_cmds .link_state == DSI_LP_MODE )
30603109 rc = mdss_dsi_blank (pdata , power_state );
30613110 rc = mdss_dsi_off (pdata , power_state );
3111+ reinit_completion (& ctrl_pdata -> wake_comp );
3112+ atomic_set (& ctrl_pdata -> disp_en , MDSS_DISPLAY_OFF );
30623113 break ;
30633114 case MDSS_EVENT_DISABLE_PANEL :
30643115 /* disable esd thread */
@@ -3807,6 +3858,23 @@ static int mdss_dsi_ctrl_probe(struct platform_device *pdev)
38073858#ifdef CONFIG_DEBUG_FS
38083859 mdss_dsi_debug_bus_init (mdss_dsi_res );
38093860#endif
3861+
3862+ init_completion (& ctrl_pdata -> wake_comp );
3863+ init_waitqueue_head (& ctrl_pdata -> wake_waitq );
3864+ ctrl_pdata -> wake_thread = kthread_run (mdss_dsi_disp_wake_thread ,
3865+ ctrl_pdata , "mdss_display_wake" );
3866+ if (IS_ERR (ctrl_pdata -> wake_thread )) {
3867+ rc = PTR_ERR (ctrl_pdata -> wake_thread );
3868+ pr_err ("%s: Failed to start display wake thread, rc=%d\n" ,
3869+ __func__ , rc );
3870+ goto error_shadow_clk_deinit ;
3871+ }
3872+
3873+ /* It's sad but not fatal for the fb client register to fail */
3874+ ctrl_pdata -> wake_notif .notifier_call = mdss_dsi_fb_unblank_cb ;
3875+ ctrl_pdata -> wake_notif .priority = INT_MAX ;
3876+ fb_register_client (& ctrl_pdata -> wake_notif );
3877+
38103878 return 0 ;
38113879
38123880error_shadow_clk_deinit :
@@ -4276,7 +4344,8 @@ static int mdss_dsi_ctrl_remove(struct platform_device *pdev)
42764344 }
42774345
42784346 mdss_dsi_pm_qos_remove_request (ctrl_pdata -> shared_data );
4279-
4347+ fb_unregister_client (& ctrl_pdata -> wake_notif );
4348+ kthread_stop (ctrl_pdata -> wake_thread );
42804349 if (msm_dss_config_vreg (& pdev -> dev ,
42814350 ctrl_pdata -> panel_power_data .vreg_config ,
42824351 ctrl_pdata -> panel_power_data .num_vreg , 1 ) < 0 )
0 commit comments