Loading drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c +70 −13 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <linux/iopoll.h> #include <linux/delay.h> #include <linux/clk/msm-clock-generic.h> #include <linux/usb/usbpd.h> #include "mdss-pll.h" #include "mdss-dp-pll.h" Loading Loading @@ -172,9 +173,27 @@ int dp_config_vco_rate(struct dp_pll_vco_clk *vco, unsigned long rate) { u32 res = 0; struct mdss_pll_resources *dp_res = vco->priv; u8 orientation, ln_cnt; u32 spare_value; spare_value = MDSS_PLL_REG_R(dp_res->phy_base, DP_PHY_SPARE0); ln_cnt = spare_value & 0x0F; orientation = (spare_value & 0xF0) >> 4; pr_debug("%s: spare_value=0x%x, ln_cnt=0x%x, orientation=0x%x\n", __func__, spare_value, ln_cnt, orientation); if (ln_cnt != 4) { if (orientation == ORIENTATION_CC2) MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_PD_CTL, 0x2d); else MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_PD_CTL, 0x35); } else { MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_PD_CTL, 0x3d); } /* Make sure the PHY register writes are done */ wmb(); MDSS_PLL_REG_W(dp_res->pll_base, Loading Loading @@ -314,8 +333,13 @@ int dp_config_vco_rate(struct dp_pll_vco_clk *vco, unsigned long rate) /* Make sure the PLL register writes are done */ wmb(); if (orientation == ORIENTATION_CC2) MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_MODE, 0x48); else MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_MODE, 0x58); MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_TX0_TX1_LANE_CTL, 0x05); MDSS_PLL_REG_W(dp_res->phy_base, Loading Loading @@ -427,6 +451,12 @@ static int dp_pll_enable(struct clk *c) u32 status; struct dp_pll_vco_clk *vco = mdss_dp_to_vco_clk(c); struct mdss_pll_resources *dp_res = vco->priv; u8 orientation, ln_cnt; u32 spare_value, bias_en, drvr_en; spare_value = MDSS_PLL_REG_R(dp_res->phy_base, DP_PHY_SPARE0); ln_cnt = spare_value & 0x0F; orientation = (spare_value & 0xF0) >> 4; MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_CFG, 0x01); Loading Loading @@ -474,18 +504,45 @@ static int dp_pll_enable(struct clk *c) pr_debug("%s: PLL is locked\n", __func__); if (ln_cnt == 1) { bias_en = 0x3e; drvr_en = 0x13; } else { bias_en = 0x3f; drvr_en = 0x10; } if (ln_cnt != 4) { if (orientation == ORIENTATION_CC1) { MDSS_PLL_REG_W(dp_res->phy_base, QSERDES_TX1_OFFSET + TXn_TRANSCEIVER_BIAS_EN, 0x3f); bias_en); MDSS_PLL_REG_W(dp_res->phy_base, QSERDES_TX1_OFFSET + TXn_HIGHZ_DRVR_EN, 0x10); drvr_en); } else { MDSS_PLL_REG_W(dp_res->phy_base, QSERDES_TX0_OFFSET + TXn_TRANSCEIVER_BIAS_EN, bias_en); MDSS_PLL_REG_W(dp_res->phy_base, QSERDES_TX0_OFFSET + TXn_HIGHZ_DRVR_EN, drvr_en); } } else { MDSS_PLL_REG_W(dp_res->phy_base, QSERDES_TX0_OFFSET + TXn_TRANSCEIVER_BIAS_EN, 0x3f); bias_en); MDSS_PLL_REG_W(dp_res->phy_base, QSERDES_TX0_OFFSET + TXn_HIGHZ_DRVR_EN, 0x10); drvr_en); MDSS_PLL_REG_W(dp_res->phy_base, QSERDES_TX1_OFFSET + TXn_TRANSCEIVER_BIAS_EN, bias_en); MDSS_PLL_REG_W(dp_res->phy_base, QSERDES_TX1_OFFSET + TXn_HIGHZ_DRVR_EN, drvr_en); } MDSS_PLL_REG_W(dp_res->phy_base, QSERDES_TX0_OFFSET + TXn_TX_POL_INV, 0x0a); Loading Loading @@ -615,7 +672,7 @@ int dp_vco_prepare(struct clk *c) rc = dp_pll_enable(c); if (rc) { mdss_pll_resource_enable(dp_pll_res, false); pr_err("ndx=%d failed to enable dsi pll\n", pr_err("ndx=%d failed to enable dp pll\n", dp_pll_res->index); goto error; } Loading drivers/clk/msm/mdss/mdss-dp-pll-cobalt.h +1 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ #define DP_PHY_TX0_TX1_LANE_CTL 0x0068 #define DP_PHY_TX2_TX3_LANE_CTL 0x0084 #define DP_PHY_SPARE0 0x00A8 #define DP_PHY_STATUS 0x00BC /* Tx registers */ Loading drivers/video/fbdev/msm/mdss_dp.c +95 −24 Original line number Diff line number Diff line Loading @@ -789,17 +789,34 @@ void mdss_dp_config_ctrl(struct mdss_dp_drv_pdata *dp) cap = &dp->dpcd; data = dp->lane_cnt - 1; data <<= 4; data |= (2 << 13); /* Default-> LSCLK DIV: 1/4 LCLK */ /* Color Format */ switch (dp->panel_data.panel_info.out_format) { case MDP_Y_CBCR_H2V2: data |= (1 << 11); /* YUV420 */ break; case MDP_Y_CBCR_H2V1: data |= (2 << 11); /* YUV422 */ break; default: data |= (0 << 11); /* RGB */ break; } /* Scrambler reset enable */ if (cap->scrambler_reset) data |= (1 << 10); if (dp->edid.color_depth != 6) data |= 0x100; /* Default: 8 bits */ /* Num of Lanes */ data |= ((dp->lane_cnt - 1) << 4); if (cap->enhanced_frame) data |= 0x40; if (dp->edid.color_depth == 8) { /* 0 == 6 bits, 1 == 8 bits */ data |= 0x100; /* bit 8 */ } if (!timing->interlaced) /* progressive */ data |= 0x04; Loading Loading @@ -863,6 +880,8 @@ static int dp_audio_info_setup(struct platform_device *pdev, mdss_dp_set_safe_to_exit_level(&dp_ctrl->ctrl_io, dp_ctrl->lane_cnt); mdss_dp_audio_enable(&dp_ctrl->ctrl_io, true); dp_ctrl->wait_for_audio_comp = true; return rc; } /* dp_audio_info_setup */ Loading @@ -885,6 +904,17 @@ static int dp_get_audio_edid_blk(struct platform_device *pdev, return rc; } /* dp_get_audio_edid_blk */ static void dp_audio_codec_teardown_done(struct platform_device *pdev) { struct mdss_dp_drv_pdata *dp = platform_get_drvdata(pdev); if (!dp) pr_err("invalid input\n"); pr_debug("audio codec teardown done\n"); complete_all(&dp->audio_comp); } static int mdss_dp_init_ext_disp(struct mdss_dp_drv_pdata *dp) { int ret = 0; Loading @@ -906,6 +936,8 @@ static int mdss_dp_init_ext_disp(struct mdss_dp_drv_pdata *dp) dp_get_audio_edid_blk; dp->ext_audio_data.codec_ops.cable_status = dp_get_cable_status; dp->ext_audio_data.codec_ops.teardown_done = dp_audio_codec_teardown_done; if (!dp->pdev->dev.of_node) { pr_err("%s cannot find dp dev.of_node\n", __func__); Loading Loading @@ -987,6 +1019,13 @@ static int dp_init_panel_info(struct mdss_dp_drv_pdata *dp_drv, u32 vic) return 0; } /* dp_init_panel_info */ static inline void mdss_dp_set_audio_switch_node( struct mdss_dp_drv_pdata *dp, int val) { if (dp && dp->ext_audio_data.intf_ops.notify) dp->ext_audio_data.intf_ops.notify(dp->ext_pdev, val); } int mdss_dp_on(struct mdss_panel_data *pdata) { Loading Loading @@ -1054,6 +1093,9 @@ int mdss_dp_on(struct mdss_panel_data *pdata) goto exit; } mdss_dp_phy_share_lane_config(&dp_drv->phy_io, orientation, dp_drv->dpcd.max_lane_count); pr_debug("link_rate = 0x%x\n", dp_drv->link_rate); dp_drv->power_data[DP_CTRL_PM].clk_config[0].rate = Loading Loading @@ -1096,6 +1138,7 @@ int mdss_dp_on(struct mdss_panel_data *pdata) pr_debug("mainlink ready\n"); dp_drv->power_on = true; mdss_dp_set_audio_switch_node(dp_drv, true); pr_debug("End-\n"); exit: Loading @@ -1119,14 +1162,15 @@ int mdss_dp_off(struct mdss_panel_data *pdata) mutex_lock(&dp_drv->train_mutex); reinit_completion(&dp_drv->idle_comp); mdss_dp_state_ctrl(&dp_drv->ctrl_io, 0); mdss_dp_state_ctrl(&dp_drv->ctrl_io, ST_PUSH_IDLE); if (dp_drv->link_clks_on) mdss_dp_mainlink_ctrl(&dp_drv->ctrl_io, false); mdss_dp_aux_ctrl(&dp_drv->ctrl_io, false); mdss_dp_audio_enable(&dp_drv->ctrl_io, false); mdss_dp_irq_disable(dp_drv); mdss_dp_config_gpios(dp_drv, false); Loading @@ -1147,14 +1191,6 @@ int mdss_dp_off(struct mdss_panel_data *pdata) return 0; } static inline void mdss_dp_set_audio_switch_node( struct mdss_dp_drv_pdata *dp, int val) { if (dp && dp->ext_audio_data.intf_ops.notify) dp->ext_audio_data.intf_ops.notify(dp->ext_pdev, val); } static void mdss_dp_send_cable_notification( struct mdss_dp_drv_pdata *dp, int val) { Loading @@ -1169,6 +1205,38 @@ static void mdss_dp_send_cable_notification( dp->ext_audio_data.type, val); } static void mdss_dp_audio_codec_wait(struct mdss_dp_drv_pdata *dp) { const int audio_completion_timeout_ms = HZ * 3; int ret = 0; if (!dp->wait_for_audio_comp) return; reinit_completion(&dp->audio_comp); ret = wait_for_completion_timeout(&dp->audio_comp, audio_completion_timeout_ms); if (ret <= 0) pr_warn("audio codec teardown timed out\n"); dp->wait_for_audio_comp = false; } static void mdss_dp_notify_clients(struct mdss_dp_drv_pdata *dp, bool enable) { if (enable) { mdss_dp_send_cable_notification(dp, enable); } else { mdss_dp_set_audio_switch_node(dp, enable); mdss_dp_audio_codec_wait(dp); mdss_dp_send_cable_notification(dp, enable); } pr_debug("notify state %s done\n", enable ? "ENABLE" : "DISABLE"); } static int mdss_dp_edid_init(struct mdss_panel_data *pdata) { struct mdss_dp_drv_pdata *dp_drv = NULL; Loading Loading @@ -1236,15 +1304,19 @@ static int mdss_dp_host_init(struct mdss_panel_data *pdata) mdss_dp_aux_init(dp_drv); mdss_dp_phy_initialize(dp_drv); mdss_dp_ctrl_reset(&dp_drv->ctrl_io); mdss_dp_phy_reset(&dp_drv->ctrl_io); mdss_dp_aux_reset(&dp_drv->ctrl_io); mdss_dp_phy_initialize(dp_drv); mdss_dp_aux_ctrl(&dp_drv->ctrl_io, true); pr_debug("Ctrl_hw_rev =0x%x, phy hw_rev =0x%x\n", mdss_dp_get_ctrl_hw_version(&dp_drv->ctrl_io), mdss_dp_get_phy_hw_version(&dp_drv->phy_io)); pr_debug("plug Orientation = %d\n", usbpd_get_plug_orientation(dp_drv->pd)); mdss_dp_phy_aux_setup(&dp_drv->phy_io); mdss_dp_irq_enable(dp_drv); Loading @@ -1264,8 +1336,7 @@ static int mdss_dp_host_init(struct mdss_panel_data *pdata) goto edid_error; } mdss_dp_send_cable_notification(dp_drv, true); mdss_dp_set_audio_switch_node(dp_drv, true); mdss_dp_notify_clients(dp_drv, true); dp_drv->dp_initialized = true; return ret; Loading Loading @@ -1771,8 +1842,7 @@ static void dp_send_events(struct mdss_dp_drv_pdata *dp, u32 events) { spin_lock(&dp->event_lock); dp->current_event = events; queue_delayed_work(dp->workq, &dp->dwork, HZ); queue_delayed_work(dp->workq, &dp->dwork, HZ / 100); spin_unlock(&dp->event_lock); } Loading Loading @@ -1883,8 +1953,7 @@ static void usbpd_disconnect_callback(struct usbpd_svid_handler *hdlr) mutex_lock(&dp_drv->pd_msg_mutex); dp_drv->cable_connected = false; mutex_unlock(&dp_drv->pd_msg_mutex); mdss_dp_send_cable_notification(dp_drv, false); mdss_dp_set_audio_switch_node(dp_drv, false); mdss_dp_notify_clients(dp_drv, false); } static void usbpd_response_callback(struct usbpd_svid_handler *hdlr, u8 cmd, Loading Loading @@ -2135,6 +2204,8 @@ static int mdss_dp_probe(struct platform_device *pdev) mdss_dp_device_register(dp_drv); dp_drv->inited = true; dp_drv->wait_for_audio_comp = false; init_completion(&dp_drv->audio_comp); pr_debug("done\n"); Loading drivers/video/fbdev/msm/mdss_dp.h +2 −0 Original line number Diff line number Diff line Loading @@ -399,6 +399,7 @@ struct mdss_dp_drv_pdata { struct completion train_comp; struct completion idle_comp; struct completion video_comp; struct completion audio_comp; struct mutex aux_mutex; struct mutex train_mutex; struct mutex pd_msg_mutex; Loading @@ -423,6 +424,7 @@ struct mdss_dp_drv_pdata { char delay_start; u32 bpp; struct dp_statistic dp_stat; bool wait_for_audio_comp; /* event */ struct workqueue_struct *workq; Loading drivers/video/fbdev/msm/mdss_dp_aux.c +7 −7 Original line number Diff line number Diff line Loading @@ -1113,17 +1113,17 @@ static void dp_host_train_set(struct mdss_dp_drv_pdata *ep, int train) } char vm_pre_emphasis[4][4] = { {0x00, 0x06, 0x09, 0x0C}, /* pe0, 0 db */ {0x00, 0x06, 0x09, 0xFF}, /* pe1, 3.5 db */ {0x03, 0x06, 0xFF, 0xFF}, /* pe2, 6.0 db */ {0x03, 0xFF, 0xFF, 0xFF} /* pe3, 9.5 db */ {0x00, 0x09, 0x11, 0x0C}, /* pe0, 0 db */ {0x00, 0x0A, 0x10, 0xFF}, /* pe1, 3.5 db */ {0x00, 0x0C, 0xFF, 0xFF}, /* pe2, 6.0 db */ {0x00, 0xFF, 0xFF, 0xFF} /* pe3, 9.5 db */ }; /* voltage swing, 0.2v and 1.0v are not support */ char vm_voltage_swing[4][4] = { {0x0a, 0x18, 0x1A, 0x1E}, /* sw0, 0.4v */ {0x07, 0x1A, 0x1E, 0xFF}, /* sw1, 0.6 v */ {0x1A, 0x1E, 0xFF, 0xFF}, /* sw1, 0.8 v */ {0x07, 0x0f, 0x12, 0x1E}, /* sw0, 0.4v */ {0x11, 0x1D, 0x1F, 0xFF}, /* sw1, 0.6 v */ {0x18, 0x1F, 0xFF, 0xFF}, /* sw1, 0.8 v */ {0x1E, 0xFF, 0xFF, 0xFF} /* sw1, 1.2 v, optional */ }; Loading Loading
drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c +70 −13 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <linux/iopoll.h> #include <linux/delay.h> #include <linux/clk/msm-clock-generic.h> #include <linux/usb/usbpd.h> #include "mdss-pll.h" #include "mdss-dp-pll.h" Loading Loading @@ -172,9 +173,27 @@ int dp_config_vco_rate(struct dp_pll_vco_clk *vco, unsigned long rate) { u32 res = 0; struct mdss_pll_resources *dp_res = vco->priv; u8 orientation, ln_cnt; u32 spare_value; spare_value = MDSS_PLL_REG_R(dp_res->phy_base, DP_PHY_SPARE0); ln_cnt = spare_value & 0x0F; orientation = (spare_value & 0xF0) >> 4; pr_debug("%s: spare_value=0x%x, ln_cnt=0x%x, orientation=0x%x\n", __func__, spare_value, ln_cnt, orientation); if (ln_cnt != 4) { if (orientation == ORIENTATION_CC2) MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_PD_CTL, 0x2d); else MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_PD_CTL, 0x35); } else { MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_PD_CTL, 0x3d); } /* Make sure the PHY register writes are done */ wmb(); MDSS_PLL_REG_W(dp_res->pll_base, Loading Loading @@ -314,8 +333,13 @@ int dp_config_vco_rate(struct dp_pll_vco_clk *vco, unsigned long rate) /* Make sure the PLL register writes are done */ wmb(); if (orientation == ORIENTATION_CC2) MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_MODE, 0x48); else MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_MODE, 0x58); MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_TX0_TX1_LANE_CTL, 0x05); MDSS_PLL_REG_W(dp_res->phy_base, Loading Loading @@ -427,6 +451,12 @@ static int dp_pll_enable(struct clk *c) u32 status; struct dp_pll_vco_clk *vco = mdss_dp_to_vco_clk(c); struct mdss_pll_resources *dp_res = vco->priv; u8 orientation, ln_cnt; u32 spare_value, bias_en, drvr_en; spare_value = MDSS_PLL_REG_R(dp_res->phy_base, DP_PHY_SPARE0); ln_cnt = spare_value & 0x0F; orientation = (spare_value & 0xF0) >> 4; MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_CFG, 0x01); Loading Loading @@ -474,18 +504,45 @@ static int dp_pll_enable(struct clk *c) pr_debug("%s: PLL is locked\n", __func__); if (ln_cnt == 1) { bias_en = 0x3e; drvr_en = 0x13; } else { bias_en = 0x3f; drvr_en = 0x10; } if (ln_cnt != 4) { if (orientation == ORIENTATION_CC1) { MDSS_PLL_REG_W(dp_res->phy_base, QSERDES_TX1_OFFSET + TXn_TRANSCEIVER_BIAS_EN, 0x3f); bias_en); MDSS_PLL_REG_W(dp_res->phy_base, QSERDES_TX1_OFFSET + TXn_HIGHZ_DRVR_EN, 0x10); drvr_en); } else { MDSS_PLL_REG_W(dp_res->phy_base, QSERDES_TX0_OFFSET + TXn_TRANSCEIVER_BIAS_EN, bias_en); MDSS_PLL_REG_W(dp_res->phy_base, QSERDES_TX0_OFFSET + TXn_HIGHZ_DRVR_EN, drvr_en); } } else { MDSS_PLL_REG_W(dp_res->phy_base, QSERDES_TX0_OFFSET + TXn_TRANSCEIVER_BIAS_EN, 0x3f); bias_en); MDSS_PLL_REG_W(dp_res->phy_base, QSERDES_TX0_OFFSET + TXn_HIGHZ_DRVR_EN, 0x10); drvr_en); MDSS_PLL_REG_W(dp_res->phy_base, QSERDES_TX1_OFFSET + TXn_TRANSCEIVER_BIAS_EN, bias_en); MDSS_PLL_REG_W(dp_res->phy_base, QSERDES_TX1_OFFSET + TXn_HIGHZ_DRVR_EN, drvr_en); } MDSS_PLL_REG_W(dp_res->phy_base, QSERDES_TX0_OFFSET + TXn_TX_POL_INV, 0x0a); Loading Loading @@ -615,7 +672,7 @@ int dp_vco_prepare(struct clk *c) rc = dp_pll_enable(c); if (rc) { mdss_pll_resource_enable(dp_pll_res, false); pr_err("ndx=%d failed to enable dsi pll\n", pr_err("ndx=%d failed to enable dp pll\n", dp_pll_res->index); goto error; } Loading
drivers/clk/msm/mdss/mdss-dp-pll-cobalt.h +1 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ #define DP_PHY_TX0_TX1_LANE_CTL 0x0068 #define DP_PHY_TX2_TX3_LANE_CTL 0x0084 #define DP_PHY_SPARE0 0x00A8 #define DP_PHY_STATUS 0x00BC /* Tx registers */ Loading
drivers/video/fbdev/msm/mdss_dp.c +95 −24 Original line number Diff line number Diff line Loading @@ -789,17 +789,34 @@ void mdss_dp_config_ctrl(struct mdss_dp_drv_pdata *dp) cap = &dp->dpcd; data = dp->lane_cnt - 1; data <<= 4; data |= (2 << 13); /* Default-> LSCLK DIV: 1/4 LCLK */ /* Color Format */ switch (dp->panel_data.panel_info.out_format) { case MDP_Y_CBCR_H2V2: data |= (1 << 11); /* YUV420 */ break; case MDP_Y_CBCR_H2V1: data |= (2 << 11); /* YUV422 */ break; default: data |= (0 << 11); /* RGB */ break; } /* Scrambler reset enable */ if (cap->scrambler_reset) data |= (1 << 10); if (dp->edid.color_depth != 6) data |= 0x100; /* Default: 8 bits */ /* Num of Lanes */ data |= ((dp->lane_cnt - 1) << 4); if (cap->enhanced_frame) data |= 0x40; if (dp->edid.color_depth == 8) { /* 0 == 6 bits, 1 == 8 bits */ data |= 0x100; /* bit 8 */ } if (!timing->interlaced) /* progressive */ data |= 0x04; Loading Loading @@ -863,6 +880,8 @@ static int dp_audio_info_setup(struct platform_device *pdev, mdss_dp_set_safe_to_exit_level(&dp_ctrl->ctrl_io, dp_ctrl->lane_cnt); mdss_dp_audio_enable(&dp_ctrl->ctrl_io, true); dp_ctrl->wait_for_audio_comp = true; return rc; } /* dp_audio_info_setup */ Loading @@ -885,6 +904,17 @@ static int dp_get_audio_edid_blk(struct platform_device *pdev, return rc; } /* dp_get_audio_edid_blk */ static void dp_audio_codec_teardown_done(struct platform_device *pdev) { struct mdss_dp_drv_pdata *dp = platform_get_drvdata(pdev); if (!dp) pr_err("invalid input\n"); pr_debug("audio codec teardown done\n"); complete_all(&dp->audio_comp); } static int mdss_dp_init_ext_disp(struct mdss_dp_drv_pdata *dp) { int ret = 0; Loading @@ -906,6 +936,8 @@ static int mdss_dp_init_ext_disp(struct mdss_dp_drv_pdata *dp) dp_get_audio_edid_blk; dp->ext_audio_data.codec_ops.cable_status = dp_get_cable_status; dp->ext_audio_data.codec_ops.teardown_done = dp_audio_codec_teardown_done; if (!dp->pdev->dev.of_node) { pr_err("%s cannot find dp dev.of_node\n", __func__); Loading Loading @@ -987,6 +1019,13 @@ static int dp_init_panel_info(struct mdss_dp_drv_pdata *dp_drv, u32 vic) return 0; } /* dp_init_panel_info */ static inline void mdss_dp_set_audio_switch_node( struct mdss_dp_drv_pdata *dp, int val) { if (dp && dp->ext_audio_data.intf_ops.notify) dp->ext_audio_data.intf_ops.notify(dp->ext_pdev, val); } int mdss_dp_on(struct mdss_panel_data *pdata) { Loading Loading @@ -1054,6 +1093,9 @@ int mdss_dp_on(struct mdss_panel_data *pdata) goto exit; } mdss_dp_phy_share_lane_config(&dp_drv->phy_io, orientation, dp_drv->dpcd.max_lane_count); pr_debug("link_rate = 0x%x\n", dp_drv->link_rate); dp_drv->power_data[DP_CTRL_PM].clk_config[0].rate = Loading Loading @@ -1096,6 +1138,7 @@ int mdss_dp_on(struct mdss_panel_data *pdata) pr_debug("mainlink ready\n"); dp_drv->power_on = true; mdss_dp_set_audio_switch_node(dp_drv, true); pr_debug("End-\n"); exit: Loading @@ -1119,14 +1162,15 @@ int mdss_dp_off(struct mdss_panel_data *pdata) mutex_lock(&dp_drv->train_mutex); reinit_completion(&dp_drv->idle_comp); mdss_dp_state_ctrl(&dp_drv->ctrl_io, 0); mdss_dp_state_ctrl(&dp_drv->ctrl_io, ST_PUSH_IDLE); if (dp_drv->link_clks_on) mdss_dp_mainlink_ctrl(&dp_drv->ctrl_io, false); mdss_dp_aux_ctrl(&dp_drv->ctrl_io, false); mdss_dp_audio_enable(&dp_drv->ctrl_io, false); mdss_dp_irq_disable(dp_drv); mdss_dp_config_gpios(dp_drv, false); Loading @@ -1147,14 +1191,6 @@ int mdss_dp_off(struct mdss_panel_data *pdata) return 0; } static inline void mdss_dp_set_audio_switch_node( struct mdss_dp_drv_pdata *dp, int val) { if (dp && dp->ext_audio_data.intf_ops.notify) dp->ext_audio_data.intf_ops.notify(dp->ext_pdev, val); } static void mdss_dp_send_cable_notification( struct mdss_dp_drv_pdata *dp, int val) { Loading @@ -1169,6 +1205,38 @@ static void mdss_dp_send_cable_notification( dp->ext_audio_data.type, val); } static void mdss_dp_audio_codec_wait(struct mdss_dp_drv_pdata *dp) { const int audio_completion_timeout_ms = HZ * 3; int ret = 0; if (!dp->wait_for_audio_comp) return; reinit_completion(&dp->audio_comp); ret = wait_for_completion_timeout(&dp->audio_comp, audio_completion_timeout_ms); if (ret <= 0) pr_warn("audio codec teardown timed out\n"); dp->wait_for_audio_comp = false; } static void mdss_dp_notify_clients(struct mdss_dp_drv_pdata *dp, bool enable) { if (enable) { mdss_dp_send_cable_notification(dp, enable); } else { mdss_dp_set_audio_switch_node(dp, enable); mdss_dp_audio_codec_wait(dp); mdss_dp_send_cable_notification(dp, enable); } pr_debug("notify state %s done\n", enable ? "ENABLE" : "DISABLE"); } static int mdss_dp_edid_init(struct mdss_panel_data *pdata) { struct mdss_dp_drv_pdata *dp_drv = NULL; Loading Loading @@ -1236,15 +1304,19 @@ static int mdss_dp_host_init(struct mdss_panel_data *pdata) mdss_dp_aux_init(dp_drv); mdss_dp_phy_initialize(dp_drv); mdss_dp_ctrl_reset(&dp_drv->ctrl_io); mdss_dp_phy_reset(&dp_drv->ctrl_io); mdss_dp_aux_reset(&dp_drv->ctrl_io); mdss_dp_phy_initialize(dp_drv); mdss_dp_aux_ctrl(&dp_drv->ctrl_io, true); pr_debug("Ctrl_hw_rev =0x%x, phy hw_rev =0x%x\n", mdss_dp_get_ctrl_hw_version(&dp_drv->ctrl_io), mdss_dp_get_phy_hw_version(&dp_drv->phy_io)); pr_debug("plug Orientation = %d\n", usbpd_get_plug_orientation(dp_drv->pd)); mdss_dp_phy_aux_setup(&dp_drv->phy_io); mdss_dp_irq_enable(dp_drv); Loading @@ -1264,8 +1336,7 @@ static int mdss_dp_host_init(struct mdss_panel_data *pdata) goto edid_error; } mdss_dp_send_cable_notification(dp_drv, true); mdss_dp_set_audio_switch_node(dp_drv, true); mdss_dp_notify_clients(dp_drv, true); dp_drv->dp_initialized = true; return ret; Loading Loading @@ -1771,8 +1842,7 @@ static void dp_send_events(struct mdss_dp_drv_pdata *dp, u32 events) { spin_lock(&dp->event_lock); dp->current_event = events; queue_delayed_work(dp->workq, &dp->dwork, HZ); queue_delayed_work(dp->workq, &dp->dwork, HZ / 100); spin_unlock(&dp->event_lock); } Loading Loading @@ -1883,8 +1953,7 @@ static void usbpd_disconnect_callback(struct usbpd_svid_handler *hdlr) mutex_lock(&dp_drv->pd_msg_mutex); dp_drv->cable_connected = false; mutex_unlock(&dp_drv->pd_msg_mutex); mdss_dp_send_cable_notification(dp_drv, false); mdss_dp_set_audio_switch_node(dp_drv, false); mdss_dp_notify_clients(dp_drv, false); } static void usbpd_response_callback(struct usbpd_svid_handler *hdlr, u8 cmd, Loading Loading @@ -2135,6 +2204,8 @@ static int mdss_dp_probe(struct platform_device *pdev) mdss_dp_device_register(dp_drv); dp_drv->inited = true; dp_drv->wait_for_audio_comp = false; init_completion(&dp_drv->audio_comp); pr_debug("done\n"); Loading
drivers/video/fbdev/msm/mdss_dp.h +2 −0 Original line number Diff line number Diff line Loading @@ -399,6 +399,7 @@ struct mdss_dp_drv_pdata { struct completion train_comp; struct completion idle_comp; struct completion video_comp; struct completion audio_comp; struct mutex aux_mutex; struct mutex train_mutex; struct mutex pd_msg_mutex; Loading @@ -423,6 +424,7 @@ struct mdss_dp_drv_pdata { char delay_start; u32 bpp; struct dp_statistic dp_stat; bool wait_for_audio_comp; /* event */ struct workqueue_struct *workq; Loading
drivers/video/fbdev/msm/mdss_dp_aux.c +7 −7 Original line number Diff line number Diff line Loading @@ -1113,17 +1113,17 @@ static void dp_host_train_set(struct mdss_dp_drv_pdata *ep, int train) } char vm_pre_emphasis[4][4] = { {0x00, 0x06, 0x09, 0x0C}, /* pe0, 0 db */ {0x00, 0x06, 0x09, 0xFF}, /* pe1, 3.5 db */ {0x03, 0x06, 0xFF, 0xFF}, /* pe2, 6.0 db */ {0x03, 0xFF, 0xFF, 0xFF} /* pe3, 9.5 db */ {0x00, 0x09, 0x11, 0x0C}, /* pe0, 0 db */ {0x00, 0x0A, 0x10, 0xFF}, /* pe1, 3.5 db */ {0x00, 0x0C, 0xFF, 0xFF}, /* pe2, 6.0 db */ {0x00, 0xFF, 0xFF, 0xFF} /* pe3, 9.5 db */ }; /* voltage swing, 0.2v and 1.0v are not support */ char vm_voltage_swing[4][4] = { {0x0a, 0x18, 0x1A, 0x1E}, /* sw0, 0.4v */ {0x07, 0x1A, 0x1E, 0xFF}, /* sw1, 0.6 v */ {0x1A, 0x1E, 0xFF, 0xFF}, /* sw1, 0.8 v */ {0x07, 0x0f, 0x12, 0x1E}, /* sw0, 0.4v */ {0x11, 0x1D, 0x1F, 0xFF}, /* sw1, 0.6 v */ {0x18, 0x1F, 0xFF, 0xFF}, /* sw1, 0.8 v */ {0x1E, 0xFF, 0xFF, 0xFF} /* sw1, 1.2 v, optional */ }; Loading