diff options
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c | 70 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h | 7 |
2 files changed, 42 insertions, 35 deletions
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c index fef22e8cabb6..6781aa994613 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c | |||
@@ -167,34 +167,54 @@ static bool mdp4_crtc_mode_fixup(struct drm_crtc *crtc, | |||
167 | return true; | 167 | return true; |
168 | } | 168 | } |
169 | 169 | ||
170 | static void blend_setup(struct drm_crtc *crtc) | 170 | /* statically (for now) map planes to mixer stage (z-order): */ |
171 | static const int idxs[] = { | ||
172 | [VG1] = 1, | ||
173 | [VG2] = 2, | ||
174 | [RGB1] = 0, | ||
175 | [RGB2] = 0, | ||
176 | [RGB3] = 0, | ||
177 | [VG3] = 3, | ||
178 | [VG4] = 4, | ||
179 | |||
180 | }; | ||
181 | |||
182 | /* setup mixer config, for which we need to consider all crtc's and | ||
183 | * the planes attached to them | ||
184 | * | ||
185 | * TODO may possibly need some extra locking here | ||
186 | */ | ||
187 | static void setup_mixer(struct mdp4_kms *mdp4_kms) | ||
171 | { | 188 | { |
172 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); | 189 | struct drm_mode_config *config = &mdp4_kms->dev->mode_config; |
173 | struct mdp4_kms *mdp4_kms = get_kms(crtc); | 190 | struct drm_crtc *crtc; |
174 | struct drm_plane *plane; | ||
175 | int i, ovlp = mdp4_crtc->ovlp; | ||
176 | uint32_t mixer_cfg = 0; | 191 | uint32_t mixer_cfg = 0; |
177 | static const enum mdp_mixer_stage_id stages[] = { | 192 | static const enum mdp_mixer_stage_id stages[] = { |
178 | STAGE_BASE, STAGE0, STAGE1, STAGE2, STAGE3, | 193 | STAGE_BASE, STAGE0, STAGE1, STAGE2, STAGE3, |
179 | }; | 194 | }; |
180 | /* statically (for now) map planes to mixer stage (z-order): */ | ||
181 | static const int idxs[] = { | ||
182 | [VG1] = 1, | ||
183 | [VG2] = 2, | ||
184 | [RGB1] = 0, | ||
185 | [RGB2] = 0, | ||
186 | [RGB3] = 0, | ||
187 | [VG3] = 3, | ||
188 | [VG4] = 4, | ||
189 | 195 | ||
190 | }; | 196 | list_for_each_entry(crtc, &config->crtc_list, head) { |
191 | bool alpha[4]= { false, false, false, false }; | 197 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); |
198 | struct drm_plane *plane; | ||
192 | 199 | ||
193 | /* Don't rely on value read back from hw, but instead use our | 200 | for_each_plane_on_crtc(crtc, plane) { |
194 | * own shadowed value. Possibly disable/reenable looses the | 201 | enum mdp4_pipe pipe_id = mdp4_plane_pipe(plane); |
195 | * previous value and goes back to power-on default? | 202 | int idx = idxs[pipe_id]; |
196 | */ | 203 | mixer_cfg = mixercfg(mixer_cfg, mdp4_crtc->mixer, |
197 | mixer_cfg = mdp4_kms->mixer_cfg; | 204 | pipe_id, stages[idx]); |
205 | } | ||
206 | } | ||
207 | |||
208 | mdp4_write(mdp4_kms, REG_MDP4_LAYERMIXER_IN_CFG, mixer_cfg); | ||
209 | } | ||
210 | |||
211 | static void blend_setup(struct drm_crtc *crtc) | ||
212 | { | ||
213 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); | ||
214 | struct mdp4_kms *mdp4_kms = get_kms(crtc); | ||
215 | struct drm_plane *plane; | ||
216 | int i, ovlp = mdp4_crtc->ovlp; | ||
217 | bool alpha[4]= { false, false, false, false }; | ||
198 | 218 | ||
199 | mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW0(ovlp), 0); | 219 | mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW0(ovlp), 0); |
200 | mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW1(ovlp), 0); | 220 | mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW1(ovlp), 0); |
@@ -209,13 +229,8 @@ static void blend_setup(struct drm_crtc *crtc) | |||
209 | to_mdp_format(msm_framebuffer_format(plane->fb)); | 229 | to_mdp_format(msm_framebuffer_format(plane->fb)); |
210 | alpha[idx-1] = format->alpha_enable; | 230 | alpha[idx-1] = format->alpha_enable; |
211 | } | 231 | } |
212 | mixer_cfg = mixercfg(mixer_cfg, mdp4_crtc->mixer, | ||
213 | pipe_id, stages[idx]); | ||
214 | } | 232 | } |
215 | 233 | ||
216 | /* this shouldn't happen.. and seems to cause underflow: */ | ||
217 | WARN_ON(!mixer_cfg); | ||
218 | |||
219 | for (i = 0; i < 4; i++) { | 234 | for (i = 0; i < 4; i++) { |
220 | uint32_t op; | 235 | uint32_t op; |
221 | 236 | ||
@@ -238,8 +253,7 @@ static void blend_setup(struct drm_crtc *crtc) | |||
238 | mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_HIGH1(ovlp, i), 0); | 253 | mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_HIGH1(ovlp, i), 0); |
239 | } | 254 | } |
240 | 255 | ||
241 | mdp4_kms->mixer_cfg = mixer_cfg; | 256 | setup_mixer(mdp4_kms); |
242 | mdp4_write(mdp4_kms, REG_MDP4_LAYERMIXER_IN_CFG, mixer_cfg); | ||
243 | } | 257 | } |
244 | 258 | ||
245 | static void mdp4_crtc_mode_set_nofb(struct drm_crtc *crtc) | 259 | static void mdp4_crtc_mode_set_nofb(struct drm_crtc *crtc) |
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h index 770645296f11..cbd77bc626d5 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h | |||
@@ -32,13 +32,6 @@ struct mdp4_kms { | |||
32 | 32 | ||
33 | int rev; | 33 | int rev; |
34 | 34 | ||
35 | /* Shadow value for MDP4_LAYERMIXER_IN_CFG.. since setup for all | ||
36 | * crtcs/encoders is in one shared register, we need to update it | ||
37 | * via read/modify/write. But to avoid getting confused by power- | ||
38 | * on-default values after resume, use this shadow value instead: | ||
39 | */ | ||
40 | uint32_t mixer_cfg; | ||
41 | |||
42 | /* mapper-id used to request GEM buffer mapped for scanout: */ | 35 | /* mapper-id used to request GEM buffer mapped for scanout: */ |
43 | int id; | 36 | int id; |
44 | 37 | ||