MLK-18995 drm/imx: hdp: Set pixel link vld and sync ctrl in enc->enable/disable
authorLiu Ying <victor.liu@nxp.com>
Tue, 24 Jul 2018 16:26:24 +0000 (00:26 +0800)
committerLeonard Crestez <leonard.crestez@nxp.com>
Wed, 17 Apr 2019 23:51:34 +0000 (02:51 +0300)
The pixel link validation and sync ctrl enablement should be the last
step to enable the display pipeline which involves the HDP encoder.
So, let's move the pixel link operations from initialization stage to
enc->enable/disable.  Also, the pixel_link_init/deinit hooks are replaced
with pixel_link_validate/invalidate and pixel_link_sync_ctrl_enable/disable,
since the display controller driver has already initialized the pixel link
at the driver probe stage.

Signed-off-by: Liu Ying <victor.liu@nxp.com>
(cherry picked from commit cb234bc95e870a540e2f3a608f743a7e72a3e754)

drivers/gpu/drm/imx/hdp/imx-hdp.c
drivers/gpu/drm/imx/hdp/imx-hdp.h

index 7b1eafe..ed61ee4 100644 (file)
@@ -108,7 +108,7 @@ static void imx8qm_pixel_link_mux(state_struct *state, struct drm_display_mode *
        writel(val, hdp->mem.ss_base + CSR_PIXEL_LINK_MUX_CTL);
 }
 
-int imx8qm_pixel_link_init(state_struct *state)
+static int imx8qm_pixel_link_validate(state_struct *state)
 {
        struct imx_hdp *hdp = state_to_imx_hdp(state);
        sc_err_t sciErr;
@@ -125,20 +125,100 @@ int imx8qm_pixel_link_init(state_struct *state)
                return -EINVAL;
        }
 
-       sc_misc_set_control(hdp->ipcHndl, SC_R_DC_0, SC_C_PXL_LINK_MST1_VLD, 1);
-       sc_misc_set_control(hdp->ipcHndl, SC_R_DC_0, SC_C_SYNC_CTRL0, 1);
+       sciErr = sc_misc_set_control(hdp->ipcHndl, SC_R_DC_0,
+                                       SC_C_PXL_LINK_MST1_VLD, 1);
+       if (sciErr != SC_ERR_NONE) {
+               DRM_ERROR("SC_R_DC_0:SC_C_PXL_LINK_MST1_VLD sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+               return -EINVAL;
+       }
 
-       return true;
+       sc_ipc_close(hdp->mu_id);
+
+       return 0;
 }
 
-void imx8qm_pixel_link_deinit(state_struct *state)
+static int imx8qm_pixel_link_invalidate(state_struct *state)
 {
        struct imx_hdp *hdp = state_to_imx_hdp(state);
+       sc_err_t sciErr;
 
-       sc_misc_set_control(hdp->ipcHndl, SC_R_DC_0, SC_C_PXL_LINK_MST1_VLD, 0);
-       sc_misc_set_control(hdp->ipcHndl, SC_R_DC_0, SC_C_SYNC_CTRL0, 0);
+       sciErr = sc_ipc_getMuID(&hdp->mu_id);
+       if (sciErr != SC_ERR_NONE) {
+               DRM_ERROR("Cannot obtain MU ID\n");
+               return -EINVAL;
+       }
+
+       sciErr = sc_ipc_open(&hdp->ipcHndl, hdp->mu_id);
+       if (sciErr != SC_ERR_NONE) {
+               DRM_ERROR("sc_ipc_open failed! (sciError = %d)\n", sciErr);
+               return -EINVAL;
+       }
+
+       sciErr = sc_misc_set_control(hdp->ipcHndl, SC_R_DC_0, SC_C_PXL_LINK_MST1_VLD, 0);
+       if (sciErr != SC_ERR_NONE) {
+               DRM_ERROR("SC_R_DC_0:SC_C_PXL_LINK_MST1_VLD sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+               return -EINVAL;
+       }
 
        sc_ipc_close(hdp->mu_id);
+
+       return 0;
+}
+
+static int imx8qm_pixel_link_sync_ctrl_enable(state_struct *state)
+{
+       struct imx_hdp *hdp = state_to_imx_hdp(state);
+       sc_err_t sciErr;
+
+       sciErr = sc_ipc_getMuID(&hdp->mu_id);
+       if (sciErr != SC_ERR_NONE) {
+               DRM_ERROR("Cannot obtain MU ID\n");
+               return -EINVAL;
+       }
+
+       sciErr = sc_ipc_open(&hdp->ipcHndl, hdp->mu_id);
+       if (sciErr != SC_ERR_NONE) {
+               DRM_ERROR("sc_ipc_open failed! (sciError = %d)\n", sciErr);
+               return -EINVAL;
+       }
+
+       sciErr = sc_misc_set_control(hdp->ipcHndl, SC_R_DC_0, SC_C_SYNC_CTRL0, 1);
+       if (sciErr != SC_ERR_NONE) {
+               DRM_ERROR("SC_R_DC_0:SC_C_SYNC_CTRL0 sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+               return -EINVAL;
+       }
+
+       sc_ipc_close(hdp->mu_id);
+
+       return 0;
+}
+
+static int imx8qm_pixel_link_sync_ctrl_disable(state_struct *state)
+{
+       struct imx_hdp *hdp = state_to_imx_hdp(state);
+       sc_err_t sciErr;
+
+       sciErr = sc_ipc_getMuID(&hdp->mu_id);
+       if (sciErr != SC_ERR_NONE) {
+               DRM_ERROR("Cannot obtain MU ID\n");
+               return -EINVAL;
+       }
+
+       sciErr = sc_ipc_open(&hdp->ipcHndl, hdp->mu_id);
+       if (sciErr != SC_ERR_NONE) {
+               DRM_ERROR("sc_ipc_open failed! (sciError = %d)\n", sciErr);
+               return -EINVAL;
+       }
+
+       sciErr = sc_misc_set_control(hdp->ipcHndl, SC_R_DC_0, SC_C_SYNC_CTRL0, 0);
+       if (sciErr != SC_ERR_NONE) {
+               DRM_ERROR("SC_R_DC_0:SC_C_SYNC_CTRL0 sc_misc_set_control failed! (sciError = %d)\n", sciErr);
+               return -EINVAL;
+       }
+
+       sc_ipc_close(hdp->mu_id);
+
+       return 0;
 }
 
 void imx8qm_phy_reset(sc_ipc_t ipcHndl, struct hdp_mem *mem, u8 reset)
@@ -786,6 +866,10 @@ static const struct drm_bridge_funcs imx_hdp_bridge_funcs = {
 
 static void imx_hdp_imx_encoder_disable(struct drm_encoder *encoder)
 {
+       struct imx_hdp *hdp = container_of(encoder, struct imx_hdp, encoder);
+
+       imx_hdp_call(hdp, pixel_link_sync_ctrl_disable, &hdp->state);
+       imx_hdp_call(hdp, pixel_link_invalidate, &hdp->state);
 }
 
 static void imx_hdp_imx_encoder_enable(struct drm_encoder *encoder)
@@ -797,7 +881,7 @@ static void imx_hdp_imx_encoder_enable(struct drm_encoder *encoder)
        int ret = 0;
 
        if (!hdp->ops->write_hdr_metadata)
-               return;
+               goto out;
 
        if (hdp->hdr_metadata_present) {
                hdr_metadata = (struct hdr_static_metadata *)
@@ -823,6 +907,10 @@ static void imx_hdp_imx_encoder_enable(struct drm_encoder *encoder)
        }
 
        hdp->ops->write_hdr_metadata(&hdp->state, &frame);
+
+out:
+       imx_hdp_call(hdp, pixel_link_validate, &hdp->state);
+       imx_hdp_call(hdp, pixel_link_sync_ctrl_enable , &hdp->state);
 }
 
 static int imx_hdp_imx_encoder_atomic_check(struct drm_encoder *encoder,
@@ -952,8 +1040,10 @@ static struct hdp_ops imx8qm_dp_ops = {
        .get_hpd_state = dp_get_hpd_state,
 
        .phy_reset = imx8qm_phy_reset,
-       .pixel_link_init = imx8qm_pixel_link_init,
-       .pixel_link_deinit = imx8qm_pixel_link_deinit,
+       .pixel_link_validate = imx8qm_pixel_link_validate,
+       .pixel_link_invalidate = imx8qm_pixel_link_invalidate,
+       .pixel_link_sync_ctrl_enable = imx8qm_pixel_link_sync_ctrl_enable,
+       .pixel_link_sync_ctrl_disable = imx8qm_pixel_link_sync_ctrl_disable,
        .pixel_link_mux = imx8qm_pixel_link_mux,
 
        .clock_init = imx8qm_clock_init,
@@ -976,8 +1066,10 @@ static struct hdp_ops imx8qm_hdmi_ops = {
        .get_hpd_state = hdmi_get_hpd_state,
 
        .phy_reset = imx8qm_phy_reset,
-       .pixel_link_init = imx8qm_pixel_link_init,
-       .pixel_link_deinit = imx8qm_pixel_link_deinit,
+       .pixel_link_validate = imx8qm_pixel_link_validate,
+       .pixel_link_invalidate = imx8qm_pixel_link_invalidate,
+       .pixel_link_sync_ctrl_enable = imx8qm_pixel_link_sync_ctrl_enable,
+       .pixel_link_sync_ctrl_disable = imx8qm_pixel_link_sync_ctrl_disable,
        .pixel_link_mux = imx8qm_pixel_link_mux,
 
        .clock_init = imx8qm_clock_init,
@@ -1197,12 +1289,6 @@ static int imx_hdp_imx_bind(struct device *dev, struct device *master,
 
        hdp->dual_mode = false;
 
-       ret = imx_hdp_call(hdp, pixel_link_init, &hdp->state);
-       if (ret < 0) {
-               DRM_ERROR("Failed to initialize clock %d\n", ret);
-               return ret;
-       }
-
        ret = imx_hdp_call(hdp, clock_init, &hdp->clks);
        if (ret < 0) {
                DRM_ERROR("Failed to initialize clock\n");
@@ -1342,7 +1428,6 @@ static void imx_hdp_imx_unbind(struct device *dev, struct device *master,
                imx_cec_unregister(&hdp->cec);
 #endif
        imx_hdp_call(hdp, pixel_clock_disable, &hdp->clks);
-       imx_hdp_call(hdp, pixel_link_deinit, &hdp->state);
 }
 
 static const struct component_ops imx_hdp_imx_ops = {
index 5cfdec4..822b9f5 100644 (file)
@@ -96,8 +96,10 @@ struct hdp_ops {
                                  union hdmi_infoframe *hdr_infoframe);
 
        void (*phy_reset)(sc_ipc_t ipcHndl, struct hdp_mem *mem, u8 reset);
-       int (*pixel_link_init)(state_struct *state);
-       void (*pixel_link_deinit)(state_struct *state);
+       int (*pixel_link_validate)(state_struct *state);
+       int (*pixel_link_invalidate)(state_struct *state);
+       int (*pixel_link_sync_ctrl_enable)(state_struct *state);
+       int (*pixel_link_sync_ctrl_disable)(state_struct *state);
        void (*pixel_link_mux)(state_struct *state, struct drm_display_mode *mode);
        void (*pixel_engine_reset)(state_struct *state);