diff options
author | Philippe CORNU <philippe.cornu@st.com> | 2018-01-22 11:46:28 -0500 |
---|---|---|
committer | Benjamin Gaignard <benjamin.gaignard@linaro.org> | 2018-01-30 05:45:01 -0500 |
commit | 023f34890199dc16c6b4451fa30b7b1ced54113c (patch) | |
tree | e5375bb104c8d8744dda8113eb8fba59e9bd1117 | |
parent | f35b55565a4932739350065bce57ec0f67fcd54b (diff) |
drm/stm: dsi: Add 1.31 version support
Add support for the stm dsi phy/wrapper version 1.31.
Only lane capabilities need to be modified.
Signed-off-by: Philippe Cornu <philippe.cornu@st.com>
Signed-off-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20180122164628.24728-1-philippe.cornu@st.com
-rw-r--r-- | drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c index 0ba8635d738a..a514b593f37c 100644 --- a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c +++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | |||
@@ -14,7 +14,14 @@ | |||
14 | #include <drm/bridge/dw_mipi_dsi.h> | 14 | #include <drm/bridge/dw_mipi_dsi.h> |
15 | #include <video/mipi_display.h> | 15 | #include <video/mipi_display.h> |
16 | 16 | ||
17 | /* DSI wrapper register & bit definitions */ | 17 | #define HWVER_130 0x31333000 /* IP version 1.30 */ |
18 | #define HWVER_131 0x31333100 /* IP version 1.31 */ | ||
19 | |||
20 | /* DSI digital registers & bit definitions */ | ||
21 | #define DSI_VERSION 0x00 | ||
22 | #define VERSION GENMASK(31, 8) | ||
23 | |||
24 | /* DSI wrapper registers & bit definitions */ | ||
18 | /* Note: registers are named as in the Reference Manual */ | 25 | /* Note: registers are named as in the Reference Manual */ |
19 | #define DSI_WCFGR 0x0400 /* Wrapper ConFiGuration Reg */ | 26 | #define DSI_WCFGR 0x0400 /* Wrapper ConFiGuration Reg */ |
20 | #define WCFGR_DSIM BIT(0) /* DSI Mode */ | 27 | #define WCFGR_DSIM BIT(0) /* DSI Mode */ |
@@ -66,6 +73,9 @@ struct dw_mipi_dsi_stm { | |||
66 | void __iomem *base; | 73 | void __iomem *base; |
67 | struct clk *pllref_clk; | 74 | struct clk *pllref_clk; |
68 | struct dw_mipi_dsi *dsi; | 75 | struct dw_mipi_dsi *dsi; |
76 | u32 hw_version; | ||
77 | int lane_min_kbps; | ||
78 | int lane_max_kbps; | ||
69 | }; | 79 | }; |
70 | 80 | ||
71 | static inline void dsi_write(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 val) | 81 | static inline void dsi_write(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 val) |
@@ -122,7 +132,8 @@ static int dsi_pll_get_clkout_khz(int clkin_khz, int idf, int ndiv, int odf) | |||
122 | return DIV_ROUND_CLOSEST(clkin_khz * ndiv, divisor); | 132 | return DIV_ROUND_CLOSEST(clkin_khz * ndiv, divisor); |
123 | } | 133 | } |
124 | 134 | ||
125 | static int dsi_pll_get_params(int clkin_khz, int clkout_khz, | 135 | static int dsi_pll_get_params(struct dw_mipi_dsi_stm *dsi, |
136 | int clkin_khz, int clkout_khz, | ||
126 | int *idf, int *ndiv, int *odf) | 137 | int *idf, int *ndiv, int *odf) |
127 | { | 138 | { |
128 | int i, o, n, n_min, n_max; | 139 | int i, o, n, n_min, n_max; |
@@ -132,8 +143,8 @@ static int dsi_pll_get_params(int clkin_khz, int clkout_khz, | |||
132 | if (clkin_khz <= 0 || clkout_khz <= 0) | 143 | if (clkin_khz <= 0 || clkout_khz <= 0) |
133 | return -EINVAL; | 144 | return -EINVAL; |
134 | 145 | ||
135 | fvco_min = LANE_MIN_KBPS * 2 * ODF_MAX; | 146 | fvco_min = dsi->lane_min_kbps * 2 * ODF_MAX; |
136 | fvco_max = LANE_MAX_KBPS * 2 * ODF_MIN; | 147 | fvco_max = dsi->lane_max_kbps * 2 * ODF_MIN; |
137 | 148 | ||
138 | best_delta = 1000000; /* big started value (1000000khz) */ | 149 | best_delta = 1000000; /* big started value (1000000khz) */ |
139 | 150 | ||
@@ -213,6 +224,15 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, struct drm_display_mode *mode, | |||
213 | int ret, bpp; | 224 | int ret, bpp; |
214 | u32 val; | 225 | u32 val; |
215 | 226 | ||
227 | /* Update lane capabilities according to hw version */ | ||
228 | dsi->hw_version = dsi_read(dsi, DSI_VERSION) & VERSION; | ||
229 | dsi->lane_min_kbps = LANE_MIN_KBPS; | ||
230 | dsi->lane_max_kbps = LANE_MAX_KBPS; | ||
231 | if (dsi->hw_version == HWVER_131) { | ||
232 | dsi->lane_min_kbps *= 2; | ||
233 | dsi->lane_max_kbps *= 2; | ||
234 | } | ||
235 | |||
216 | pll_in_khz = (unsigned int)(clk_get_rate(dsi->pllref_clk) / 1000); | 236 | pll_in_khz = (unsigned int)(clk_get_rate(dsi->pllref_clk) / 1000); |
217 | 237 | ||
218 | /* Compute requested pll out */ | 238 | /* Compute requested pll out */ |
@@ -220,12 +240,12 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, struct drm_display_mode *mode, | |||
220 | pll_out_khz = mode->clock * bpp / lanes; | 240 | pll_out_khz = mode->clock * bpp / lanes; |
221 | /* Add 20% to pll out to be higher than pixel bw (burst mode only) */ | 241 | /* Add 20% to pll out to be higher than pixel bw (burst mode only) */ |
222 | pll_out_khz = (pll_out_khz * 12) / 10; | 242 | pll_out_khz = (pll_out_khz * 12) / 10; |
223 | if (pll_out_khz > LANE_MAX_KBPS) { | 243 | if (pll_out_khz > dsi->lane_max_kbps) { |
224 | pll_out_khz = LANE_MAX_KBPS; | 244 | pll_out_khz = dsi->lane_max_kbps; |
225 | DRM_WARN("Warning max phy mbps is used\n"); | 245 | DRM_WARN("Warning max phy mbps is used\n"); |
226 | } | 246 | } |
227 | if (pll_out_khz < LANE_MIN_KBPS) { | 247 | if (pll_out_khz < dsi->lane_min_kbps) { |
228 | pll_out_khz = LANE_MIN_KBPS; | 248 | pll_out_khz = dsi->lane_min_kbps; |
229 | DRM_WARN("Warning min phy mbps is used\n"); | 249 | DRM_WARN("Warning min phy mbps is used\n"); |
230 | } | 250 | } |
231 | 251 | ||
@@ -233,7 +253,8 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, struct drm_display_mode *mode, | |||
233 | idf = 0; | 253 | idf = 0; |
234 | ndiv = 0; | 254 | ndiv = 0; |
235 | odf = 0; | 255 | odf = 0; |
236 | ret = dsi_pll_get_params(pll_in_khz, pll_out_khz, &idf, &ndiv, &odf); | 256 | ret = dsi_pll_get_params(dsi, pll_in_khz, pll_out_khz, |
257 | &idf, &ndiv, &odf); | ||
237 | if (ret) | 258 | if (ret) |
238 | DRM_WARN("Warning dsi_pll_get_params(): bad params\n"); | 259 | DRM_WARN("Warning dsi_pll_get_params(): bad params\n"); |
239 | 260 | ||