drm/msm/dsi: Return more timings from PHY to host
authorHai Li <hali@codeaurora.org>
Thu, 15 Sep 2016 09:04:49 +0000 (14:34 +0530)
committerRob Clark <robdclark@gmail.com>
Mon, 6 Feb 2017 16:28:45 +0000 (11:28 -0500)
The DSI host is required to configure more timings calculated
in PHY. By introducing a shared structure, this change allows
more timing information passed from PHY to host.

Signed-off-by: Hai Li <hali@codeaurora.org>
Signed-off-by: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Rob Clark <robdclark@gmail.com>
drivers/gpu/drm/msm/dsi/dsi.h
drivers/gpu/drm/msm/dsi/dsi_host.c
drivers/gpu/drm/msm/dsi/dsi_manager.c
drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
drivers/gpu/drm/msm/dsi/phy/dsi_phy.h

index 81971b3caf3b61721e6ab1ca9b7f1d99a35e48c6..f5e4ccfc902d79bce021463d1c486cba9e1d0497 100644 (file)
@@ -27,6 +27,8 @@
 #define DSI_1  1
 #define DSI_MAX        2
 
+struct msm_dsi_phy_shared_timings;
+
 enum msm_dsi_phy_type {
        MSM_DSI_PHY_28NM_HPM,
        MSM_DSI_PHY_28NM_LP,
@@ -86,7 +88,7 @@ struct drm_connector *msm_dsi_manager_connector_init(u8 id);
 struct drm_connector *msm_dsi_manager_ext_bridge_init(u8 id);
 int msm_dsi_manager_phy_enable(int id,
                const unsigned long bit_rate, const unsigned long esc_rate,
-               u32 *clk_pre, u32 *clk_post);
+               struct msm_dsi_phy_shared_timings *shared_timing);
 void msm_dsi_manager_phy_disable(int id);
 int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg);
 bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, u32 len);
@@ -165,13 +167,18 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi);
 
 /* dsi phy */
 struct msm_dsi_phy;
+struct msm_dsi_phy_shared_timings {
+       u32 clk_post;
+       u32 clk_pre;
+       bool clk_pre_inc_by_2;
+};
 void msm_dsi_phy_driver_register(void);
 void msm_dsi_phy_driver_unregister(void);
 int msm_dsi_phy_enable(struct msm_dsi_phy *phy, int src_pll_id,
        const unsigned long bit_rate, const unsigned long esc_rate);
 void msm_dsi_phy_disable(struct msm_dsi_phy *phy);
-void msm_dsi_phy_get_clk_pre_post(struct msm_dsi_phy *phy,
-                                       u32 *clk_pre, u32 *clk_post);
+void msm_dsi_phy_get_shared_timings(struct msm_dsi_phy *phy,
+                       struct msm_dsi_phy_shared_timings *shared_timing);
 struct msm_dsi_pll *msm_dsi_phy_get_pll(struct msm_dsi_phy *phy);
 
 #endif /* __DSI_CONNECTOR_H__ */
index c4dad9084a3a4f76ac6c2fd49240b3a7368da273..8e75e001ad02b21e99d27ae7f00bfb07321221a3 100644 (file)
@@ -756,7 +756,7 @@ static inline enum dsi_cmd_dst_format dsi_get_cmd_fmt(
 }
 
 static void dsi_ctrl_config(struct msm_dsi_host *msm_host, bool enable,
-                               u32 clk_pre, u32 clk_post)
+                       struct msm_dsi_phy_shared_timings *phy_shared_timings)
 {
        u32 flags = msm_host->mode_flags;
        enum mipi_dsi_pixel_format mipi_fmt = msm_host->format;
@@ -819,10 +819,16 @@ static void dsi_ctrl_config(struct msm_dsi_host *msm_host, bool enable,
                data |= DSI_TRIG_CTRL_BLOCK_DMA_WITHIN_FRAME;
        dsi_write(msm_host, REG_DSI_TRIG_CTRL, data);
 
-       data = DSI_CLKOUT_TIMING_CTRL_T_CLK_POST(clk_post) |
-               DSI_CLKOUT_TIMING_CTRL_T_CLK_PRE(clk_pre);
+       data = DSI_CLKOUT_TIMING_CTRL_T_CLK_POST(phy_shared_timings->clk_post) |
+               DSI_CLKOUT_TIMING_CTRL_T_CLK_PRE(phy_shared_timings->clk_pre);
        dsi_write(msm_host, REG_DSI_CLKOUT_TIMING_CTRL, data);
 
+       if ((cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) &&
+           (cfg_hnd->minor > MSM_DSI_6G_VER_MINOR_V1_0) &&
+           phy_shared_timings->clk_pre_inc_by_2)
+               dsi_write(msm_host, REG_DSI_T_CLK_PRE_EXTEND,
+                         DSI_T_CLK_PRE_EXTEND_INC_BY_2_BYTECLK);
+
        data = 0;
        if (!(flags & MIPI_DSI_MODE_EOT_PACKET))
                data |= DSI_EOT_PACKET_CTRL_TX_EOT_APPEND;
@@ -2170,7 +2176,7 @@ static void msm_dsi_sfpb_config(struct msm_dsi_host *msm_host, bool enable)
 int msm_dsi_host_power_on(struct mipi_dsi_host *host)
 {
        struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
-       u32 clk_pre = 0, clk_post = 0;
+       struct msm_dsi_phy_shared_timings phy_shared_timings;
        int ret = 0;
 
        mutex_lock(&msm_host->dev_mutex);
@@ -2204,7 +2210,7 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host)
        ret = msm_dsi_manager_phy_enable(msm_host->id,
                                        msm_host->byte_clk_rate * 8,
                                        msm_host->esc_clk_rate,
-                                       &clk_pre, &clk_post);
+                                       &phy_shared_timings);
        dsi_bus_clk_disable(msm_host);
        if (ret) {
                pr_err("%s: failed to enable phy, %d\n", __func__, ret);
@@ -2226,7 +2232,7 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host)
 
        dsi_timing_setup(msm_host);
        dsi_sw_reset(msm_host);
-       dsi_ctrl_config(msm_host, true, clk_pre, clk_post);
+       dsi_ctrl_config(msm_host, true, &phy_shared_timings);
 
        if (msm_host->disp_en_gpio)
                gpiod_set_value(msm_host->disp_en_gpio, 1);
@@ -2255,7 +2261,7 @@ int msm_dsi_host_power_off(struct mipi_dsi_host *host)
                goto unlock_ret;
        }
 
-       dsi_ctrl_config(msm_host, false, 0, 0);
+       dsi_ctrl_config(msm_host, false, NULL);
 
        if (msm_host->disp_en_gpio)
                gpiod_set_value(msm_host->disp_en_gpio, 0);
index bd4ba00d2524975ec015bcdfeb86eafce2e01b4b..423afa66bd0f592b7bafd3b169c6a7f8643b9ea1 100644 (file)
@@ -660,7 +660,7 @@ void msm_dsi_manager_bridge_destroy(struct drm_bridge *bridge)
 
 int msm_dsi_manager_phy_enable(int id,
                const unsigned long bit_rate, const unsigned long esc_rate,
-               u32 *clk_pre, u32 *clk_post)
+               struct msm_dsi_phy_shared_timings *shared_timings)
 {
        struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
        struct msm_dsi_phy *phy = msm_dsi->phy;
@@ -688,7 +688,7 @@ int msm_dsi_manager_phy_enable(int id,
        }
 
        msm_dsi->phy_enabled = true;
-       msm_dsi_phy_get_clk_pre_post(phy, clk_pre, clk_post);
+       msm_dsi_phy_get_shared_timings(phy, shared_timings);
 
        return 0;
 }
index 03a3549336069a9d7ef0e22410c0cb846323705d..51f7c66078d738688c2bd55642802ac5c2c198f8 100644 (file)
@@ -115,8 +115,8 @@ int msm_dsi_dphy_timing_calc(struct msm_dsi_dphy_timing *timing,
        temp = ((timing->hs_exit >> 1) + 1) * 2 * ui;
        temp = 60 * coeff + 52 * ui - 24 * ui - temp;
        tmin = S_DIV_ROUND_UP(temp, 8 * ui) - 1;
-       timing->clk_post = linear_inter(tmax, tmin, pcnt2, 0, false);
-
+       timing->shared_timings.clk_post = linear_inter(tmax, tmin, pcnt2, 0,
+                                                      false);
        tmax = 63;
        temp = ((timing->clk_prepare >> 1) + 1) * 2 * ui;
        temp += ((timing->clk_zero >> 1) + 1) * 2 * ui;
@@ -124,17 +124,21 @@ int msm_dsi_dphy_timing_calc(struct msm_dsi_dphy_timing *timing,
        tmin = S_DIV_ROUND_UP(temp, 8 * ui) - 1;
        if (tmin > tmax) {
                temp = linear_inter(2 * tmax, tmin, pcnt2, 0, false);
-               timing->clk_pre = temp >> 1;
+               timing->shared_timings.clk_pre = temp >> 1;
+               timing->shared_timings.clk_pre_inc_by_2 = true;
        } else {
-               timing->clk_pre = linear_inter(tmax, tmin, pcnt2, 0, false);
+               timing->shared_timings.clk_pre =
+                               linear_inter(tmax, tmin, pcnt2, 0, false);
+               timing->shared_timings.clk_pre_inc_by_2 = false;
        }
 
        timing->ta_go = 3;
        timing->ta_sure = 0;
        timing->ta_get = 4;
 
-       DBG("PHY timings: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
-               timing->clk_pre, timing->clk_post, timing->clk_zero,
+       DBG("PHY timings: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
+               timing->shared_timings.clk_pre, timing->shared_timings.clk_post,
+               timing->shared_timings.clk_pre_inc_by_2, timing->clk_zero,
                timing->clk_trail, timing->clk_prepare, timing->hs_exit,
                timing->hs_zero, timing->hs_prepare, timing->hs_trail,
                timing->hs_rqst);
@@ -460,16 +464,11 @@ void msm_dsi_phy_disable(struct msm_dsi_phy *phy)
        dsi_phy_regulator_disable(phy);
 }
 
-void msm_dsi_phy_get_clk_pre_post(struct msm_dsi_phy *phy,
-                                       u32 *clk_pre, u32 *clk_post)
+void msm_dsi_phy_get_shared_timings(struct msm_dsi_phy *phy,
+                       struct msm_dsi_phy_shared_timings *shared_timings)
 {
-       if (!phy)
-               return;
-
-       if (clk_pre)
-               *clk_pre = phy->timing.clk_pre;
-       if (clk_post)
-               *clk_post = phy->timing.clk_post;
+       memcpy(shared_timings, &phy->timing.shared_timings,
+              sizeof(*shared_timings));
 }
 
 struct msm_dsi_pll *msm_dsi_phy_get_pll(struct msm_dsi_phy *phy)
index b9d7d02260da9bf1d9d67aa6ebdd0ae2221fd371..7399934cec546c8d25b5ed2dc063a97025a4d5c6 100644 (file)
@@ -62,6 +62,8 @@ struct msm_dsi_dphy_timing {
        u32 ta_go;
        u32 ta_sure;
        u32 ta_get;
+
+       struct msm_dsi_phy_shared_timings shared_timings;
 };
 
 struct msm_dsi_phy {