diff options
author | Stephane Viau <sviau@codeaurora.org> | 2015-03-13 15:49:34 -0400 |
---|---|---|
committer | Rob Clark <robdclark@gmail.com> | 2015-04-01 19:29:34 -0400 |
commit | 67ac0a2d6994fef77a611106fa7f6fcc58f4bb8d (patch) | |
tree | 187a12bc1a31e23b50863acaa356c230de45015d | |
parent | 389b09a1822db2bf5050060acc63611ea6c4670d (diff) |
drm/msm/mdp5: Make the intf connection in config module
Up until now, we assume that eDP is tight to intf_0 and HDMI to
intf_3. This information shall actually come from the mdp5_cfg
module since it can change from one chip to another.
v2: rename macro to mdp5_cfg_intf_is_virtual() [pointed by Archit]
v3: add sanity check before writing in INTF_TIMING_ENGINE_EN registers
Signed-off-by: Stephane Viau <sviau@codeaurora.org>
Signed-off-by: Rob Clark <robdclark@gmail.com>
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 112 |
3 files changed, 75 insertions, 49 deletions
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c index 1eacea72c5eb..baf4c95e7d92 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c | |||
@@ -62,6 +62,10 @@ const struct mdp5_cfg_hw msm8x74_config = { | |||
62 | .count = 4, | 62 | .count = 4, |
63 | .base = { 0x12500, 0x12700, 0x12900, 0x12b00 }, | 63 | .base = { 0x12500, 0x12700, 0x12900, 0x12b00 }, |
64 | }, | 64 | }, |
65 | .intfs = { | ||
66 | [0] = INTF_eDP, | ||
67 | [3] = INTF_HDMI, | ||
68 | }, | ||
65 | .max_clk = 200000000, | 69 | .max_clk = 200000000, |
66 | }; | 70 | }; |
67 | 71 | ||
@@ -111,6 +115,10 @@ const struct mdp5_cfg_hw apq8084_config = { | |||
111 | .count = 5, | 115 | .count = 5, |
112 | .base = { 0x12500, 0x12700, 0x12900, 0x12b00, 0x12d00 }, | 116 | .base = { 0x12500, 0x12700, 0x12900, 0x12b00, 0x12d00 }, |
113 | }, | 117 | }, |
118 | .intfs = { | ||
119 | [0] = INTF_eDP, | ||
120 | [3] = INTF_HDMI, | ||
121 | }, | ||
114 | .max_clk = 320000000, | 122 | .max_clk = 320000000, |
115 | }; | 123 | }; |
116 | 124 | ||
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h index 69e35aca80a7..12224d777e7b 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h | |||
@@ -56,6 +56,8 @@ struct mdp5_smp_block { | |||
56 | int reserved[MAX_CLIENTS]; /* # of MMBs allocated per client */ | 56 | int reserved[MAX_CLIENTS]; /* # of MMBs allocated per client */ |
57 | }; | 57 | }; |
58 | 58 | ||
59 | #define MDP5_INTF_NUM_MAX 5 | ||
60 | |||
59 | struct mdp5_cfg_hw { | 61 | struct mdp5_cfg_hw { |
60 | char *name; | 62 | char *name; |
61 | 63 | ||
@@ -69,6 +71,8 @@ struct mdp5_cfg_hw { | |||
69 | struct mdp5_sub_block ad; | 71 | struct mdp5_sub_block ad; |
70 | struct mdp5_sub_block intf; | 72 | struct mdp5_sub_block intf; |
71 | 73 | ||
74 | u32 intfs[MDP5_INTF_NUM_MAX]; /* array of enum mdp5_intf_type */ | ||
75 | |||
72 | uint32_t max_clk; | 76 | uint32_t max_clk; |
73 | }; | 77 | }; |
74 | 78 | ||
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 390d9d2b6882..7e03af56206a 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | |||
@@ -161,6 +161,44 @@ int mdp5_enable(struct mdp5_kms *mdp5_kms) | |||
161 | return 0; | 161 | return 0; |
162 | } | 162 | } |
163 | 163 | ||
164 | static int construct_encoder(struct mdp5_kms *mdp5_kms, | ||
165 | enum mdp5_intf_type intf_type, int intf_num) | ||
166 | { | ||
167 | struct drm_device *dev = mdp5_kms->dev; | ||
168 | struct msm_drm_private *priv = dev->dev_private; | ||
169 | struct drm_encoder *encoder; | ||
170 | struct mdp5_interface intf = { | ||
171 | .num = intf_num, | ||
172 | .type = intf_type, | ||
173 | .mode = MDP5_INTF_MODE_NONE, | ||
174 | }; | ||
175 | int ret = 0; | ||
176 | |||
177 | encoder = mdp5_encoder_init(dev, &intf); | ||
178 | if (IS_ERR(encoder)) { | ||
179 | ret = PTR_ERR(encoder); | ||
180 | dev_err(dev->dev, "failed to construct encoder: %d\n", ret); | ||
181 | return ret; | ||
182 | } | ||
183 | |||
184 | encoder->possible_crtcs = (1 << priv->num_crtcs) - 1; | ||
185 | priv->encoders[priv->num_encoders++] = encoder; | ||
186 | |||
187 | if (intf_type == INTF_HDMI) { | ||
188 | ret = hdmi_modeset_init(priv->hdmi, dev, encoder); | ||
189 | if (ret) | ||
190 | dev_err(dev->dev, "failed to init HDMI: %d\n", ret); | ||
191 | |||
192 | } else if (intf_type == INTF_eDP) { | ||
193 | /* Construct bridge/connector for eDP: */ | ||
194 | ret = msm_edp_modeset_init(priv->edp, dev, encoder); | ||
195 | if (ret) | ||
196 | dev_err(dev->dev, "failed to init eDP: %d\n", ret); | ||
197 | } | ||
198 | |||
199 | return ret; | ||
200 | } | ||
201 | |||
164 | static int modeset_init(struct mdp5_kms *mdp5_kms) | 202 | static int modeset_init(struct mdp5_kms *mdp5_kms) |
165 | { | 203 | { |
166 | static const enum mdp5_pipe crtcs[] = { | 204 | static const enum mdp5_pipe crtcs[] = { |
@@ -171,7 +209,6 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) | |||
171 | }; | 209 | }; |
172 | struct drm_device *dev = mdp5_kms->dev; | 210 | struct drm_device *dev = mdp5_kms->dev; |
173 | struct msm_drm_private *priv = dev->dev_private; | 211 | struct msm_drm_private *priv = dev->dev_private; |
174 | struct drm_encoder *encoder; | ||
175 | const struct mdp5_cfg_hw *hw_cfg; | 212 | const struct mdp5_cfg_hw *hw_cfg; |
176 | int i, ret; | 213 | int i, ret; |
177 | 214 | ||
@@ -222,56 +259,29 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) | |||
222 | } | 259 | } |
223 | } | 260 | } |
224 | 261 | ||
225 | if (priv->hdmi) { | 262 | /* Construct external display interfaces' encoders: */ |
226 | struct mdp5_interface intf = { | 263 | for (i = 0; i < ARRAY_SIZE(hw_cfg->intfs); i++) { |
227 | .num = 3, | 264 | enum mdp5_intf_type intf_type = hw_cfg->intfs[i]; |
228 | .type = INTF_HDMI, | 265 | |
229 | .mode = MDP5_INTF_MODE_NONE, | 266 | switch (intf_type) { |
230 | }; | 267 | case INTF_DISABLED: |
231 | 268 | break; | |
232 | /* Construct encoder for HDMI: */ | 269 | case INTF_eDP: |
233 | encoder = mdp5_encoder_init(dev, &intf); | 270 | if (priv->edp) |
234 | if (IS_ERR(encoder)) { | 271 | ret = construct_encoder(mdp5_kms, INTF_eDP, i); |
235 | dev_err(dev->dev, "failed to construct encoder\n"); | 272 | break; |
236 | ret = PTR_ERR(encoder); | 273 | case INTF_HDMI: |
237 | goto fail; | 274 | if (priv->hdmi) |
238 | } | 275 | ret = construct_encoder(mdp5_kms, INTF_HDMI, i); |
239 | 276 | break; | |
240 | encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;; | 277 | default: |
241 | priv->encoders[priv->num_encoders++] = encoder; | 278 | dev_err(dev->dev, "unknown intf: %d\n", intf_type); |
242 | 279 | ret = -EINVAL; | |
243 | ret = hdmi_modeset_init(priv->hdmi, dev, encoder); | 280 | break; |
244 | if (ret) { | ||
245 | dev_err(dev->dev, "failed to initialize HDMI: %d\n", ret); | ||
246 | goto fail; | ||
247 | } | ||
248 | } | ||
249 | |||
250 | if (priv->edp) { | ||
251 | struct mdp5_interface intf = { | ||
252 | .num = 0, | ||
253 | .type = INTF_eDP, | ||
254 | .mode = MDP5_INTF_MODE_NONE, | ||
255 | }; | ||
256 | |||
257 | /* Construct encoder for eDP: */ | ||
258 | encoder = mdp5_encoder_init(dev, &intf); | ||
259 | if (IS_ERR(encoder)) { | ||
260 | dev_err(dev->dev, "failed to construct eDP encoder\n"); | ||
261 | ret = PTR_ERR(encoder); | ||
262 | goto fail; | ||
263 | } | 281 | } |
264 | 282 | ||
265 | encoder->possible_crtcs = (1 << priv->num_crtcs) - 1; | 283 | if (ret) |
266 | priv->encoders[priv->num_encoders++] = encoder; | ||
267 | |||
268 | /* Construct bridge/connector for eDP: */ | ||
269 | ret = msm_edp_modeset_init(priv->edp, dev, encoder); | ||
270 | if (ret) { | ||
271 | dev_err(dev->dev, "failed to initialize eDP: %d\n", | ||
272 | ret); | ||
273 | goto fail; | 284 | goto fail; |
274 | } | ||
275 | } | 285 | } |
276 | 286 | ||
277 | return 0; | 287 | return 0; |
@@ -415,8 +425,12 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) | |||
415 | * we don't disable): | 425 | * we don't disable): |
416 | */ | 426 | */ |
417 | mdp5_enable(mdp5_kms); | 427 | mdp5_enable(mdp5_kms); |
418 | for (i = 0; i < config->hw->intf.count; i++) | 428 | for (i = 0; i < MDP5_INTF_NUM_MAX; i++) { |
429 | if (!config->hw->intf.base[i] || | ||
430 | mdp5_cfg_intf_is_virtual(config->hw->intfs[i])) | ||
431 | continue; | ||
419 | mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(i), 0); | 432 | mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(i), 0); |
433 | } | ||
420 | mdp5_disable(mdp5_kms); | 434 | mdp5_disable(mdp5_kms); |
421 | mdelay(16); | 435 | mdelay(16); |
422 | 436 | ||