diff options
author | Hai Li <hali@codeaurora.org> | 2015-06-26 16:03:25 -0400 |
---|---|---|
committer | Rob Clark <robdclark@gmail.com> | 2015-08-15 18:27:16 -0400 |
commit | c71716b17bc772e9c38f85a4b496bbfac0dd32f0 (patch) | |
tree | 06b551c9d06a7edad0d12841b094e99a20855198 /drivers/gpu/drm/msm | |
parent | 129877819c0a5f8d419fe67ae08a8a7c811afa5e (diff) |
drm/msm/mdp5: Allocate CTL for each display interface
In MDP5, CTL contains information of the whole pipeline whose
output goes down to a display interface. In various cases, one
interface may require 2 CRTCs, but only one CTL. Some interfaces
also require to use certain CTLs.
Instead of allocating CTL for each active CRTC, this change is to
associate a CTL with each interface.
Signed-off-by: Hai Li <hali@codeaurora.org>
Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/msm')
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 25 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c | 53 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 36 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | 12 |
7 files changed, 80 insertions, 79 deletions
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c index ee31b16fe7ea..8e6c9b598a57 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c | |||
@@ -21,6 +21,8 @@ struct mdp5_cmd_encoder { | |||
21 | struct mdp5_interface intf; | 21 | struct mdp5_interface intf; |
22 | bool enabled; | 22 | bool enabled; |
23 | uint32_t bsc; | 23 | uint32_t bsc; |
24 | |||
25 | struct mdp5_ctl *ctl; | ||
24 | }; | 26 | }; |
25 | #define to_mdp5_cmd_encoder(x) container_of(x, struct mdp5_cmd_encoder, base) | 27 | #define to_mdp5_cmd_encoder(x) container_of(x, struct mdp5_cmd_encoder, base) |
26 | 28 | ||
@@ -210,13 +212,14 @@ static void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder, | |||
210 | mode->vsync_end, mode->vtotal, | 212 | mode->vsync_end, mode->vtotal, |
211 | mode->type, mode->flags); | 213 | mode->type, mode->flags); |
212 | pingpong_tearcheck_setup(encoder, mode); | 214 | pingpong_tearcheck_setup(encoder, mode); |
213 | mdp5_crtc_set_intf(encoder->crtc, &mdp5_cmd_enc->intf); | 215 | mdp5_crtc_set_pipeline(encoder->crtc, &mdp5_cmd_enc->intf, |
216 | mdp5_cmd_enc->ctl); | ||
214 | } | 217 | } |
215 | 218 | ||
216 | static void mdp5_cmd_encoder_disable(struct drm_encoder *encoder) | 219 | static void mdp5_cmd_encoder_disable(struct drm_encoder *encoder) |
217 | { | 220 | { |
218 | struct mdp5_cmd_encoder *mdp5_cmd_enc = to_mdp5_cmd_encoder(encoder); | 221 | struct mdp5_cmd_encoder *mdp5_cmd_enc = to_mdp5_cmd_encoder(encoder); |
219 | struct mdp5_ctl *ctl = mdp5_crtc_get_ctl(encoder->crtc); | 222 | struct mdp5_ctl *ctl = mdp5_cmd_enc->ctl; |
220 | struct mdp5_interface *intf = &mdp5_cmd_enc->intf; | 223 | struct mdp5_interface *intf = &mdp5_cmd_enc->intf; |
221 | 224 | ||
222 | if (WARN_ON(!mdp5_cmd_enc->enabled)) | 225 | if (WARN_ON(!mdp5_cmd_enc->enabled)) |
@@ -235,7 +238,7 @@ static void mdp5_cmd_encoder_disable(struct drm_encoder *encoder) | |||
235 | static void mdp5_cmd_encoder_enable(struct drm_encoder *encoder) | 238 | static void mdp5_cmd_encoder_enable(struct drm_encoder *encoder) |
236 | { | 239 | { |
237 | struct mdp5_cmd_encoder *mdp5_cmd_enc = to_mdp5_cmd_encoder(encoder); | 240 | struct mdp5_cmd_encoder *mdp5_cmd_enc = to_mdp5_cmd_encoder(encoder); |
238 | struct mdp5_ctl *ctl = mdp5_crtc_get_ctl(encoder->crtc); | 241 | struct mdp5_ctl *ctl = mdp5_cmd_enc->ctl; |
239 | struct mdp5_interface *intf = &mdp5_cmd_enc->intf; | 242 | struct mdp5_interface *intf = &mdp5_cmd_enc->intf; |
240 | 243 | ||
241 | if (WARN_ON(mdp5_cmd_enc->enabled)) | 244 | if (WARN_ON(mdp5_cmd_enc->enabled)) |
@@ -300,7 +303,7 @@ int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder, | |||
300 | 303 | ||
301 | /* initialize command mode encoder */ | 304 | /* initialize command mode encoder */ |
302 | struct drm_encoder *mdp5_cmd_encoder_init(struct drm_device *dev, | 305 | struct drm_encoder *mdp5_cmd_encoder_init(struct drm_device *dev, |
303 | struct mdp5_interface *intf) | 306 | struct mdp5_interface *intf, struct mdp5_ctl *ctl) |
304 | { | 307 | { |
305 | struct drm_encoder *encoder = NULL; | 308 | struct drm_encoder *encoder = NULL; |
306 | struct mdp5_cmd_encoder *mdp5_cmd_enc; | 309 | struct mdp5_cmd_encoder *mdp5_cmd_enc; |
@@ -320,6 +323,7 @@ struct drm_encoder *mdp5_cmd_encoder_init(struct drm_device *dev, | |||
320 | 323 | ||
321 | memcpy(&mdp5_cmd_enc->intf, intf, sizeof(mdp5_cmd_enc->intf)); | 324 | memcpy(&mdp5_cmd_enc->intf, intf, sizeof(mdp5_cmd_enc->intf)); |
322 | encoder = &mdp5_cmd_enc->base; | 325 | encoder = &mdp5_cmd_enc->base; |
326 | mdp5_cmd_enc->ctl = ctl; | ||
323 | 327 | ||
324 | drm_encoder_init(dev, encoder, &mdp5_cmd_encoder_funcs, | 328 | drm_encoder_init(dev, encoder, &mdp5_cmd_encoder_funcs, |
325 | DRM_MODE_ENCODER_DSI); | 329 | DRM_MODE_ENCODER_DSI); |
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index 572f57927595..7f9f4ac88029 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | |||
@@ -160,8 +160,7 @@ static void complete_flip(struct drm_crtc *crtc, struct drm_file *file) | |||
160 | 160 | ||
161 | if (mdp5_crtc->ctl && !crtc->state->enable) { | 161 | if (mdp5_crtc->ctl && !crtc->state->enable) { |
162 | /* set STAGE_UNUSED for all layers */ | 162 | /* set STAGE_UNUSED for all layers */ |
163 | mdp5_ctl_blend(mdp5_crtc->ctl, mdp5_crtc->lm, NULL, 0, 0); | 163 | mdp5_ctl_blend(mdp5_crtc->ctl, NULL, 0, 0); |
164 | mdp5_ctl_release(mdp5_crtc->ctl); | ||
165 | mdp5_crtc->ctl = NULL; | 164 | mdp5_crtc->ctl = NULL; |
166 | } | 165 | } |
167 | } | 166 | } |
@@ -289,7 +288,7 @@ static void blend_setup(struct drm_crtc *crtc) | |||
289 | blender(i)), bg_alpha); | 288 | blender(i)), bg_alpha); |
290 | } | 289 | } |
291 | 290 | ||
292 | mdp5_ctl_blend(mdp5_crtc->ctl, lm, stage, plane_cnt, ctl_blend_flags); | 291 | mdp5_ctl_blend(mdp5_crtc->ctl, stage, plane_cnt, ctl_blend_flags); |
293 | 292 | ||
294 | out: | 293 | out: |
295 | spin_unlock_irqrestore(&mdp5_crtc->lm_lock, flags); | 294 | spin_unlock_irqrestore(&mdp5_crtc->lm_lock, flags); |
@@ -386,13 +385,6 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc, | |||
386 | 385 | ||
387 | DBG("%s: check", mdp5_crtc->name); | 386 | DBG("%s: check", mdp5_crtc->name); |
388 | 387 | ||
389 | /* request a free CTL, if none is already allocated for this CRTC */ | ||
390 | if (state->enable && !mdp5_crtc->ctl) { | ||
391 | mdp5_crtc->ctl = mdp5_ctlm_request(mdp5_kms->ctlm, crtc); | ||
392 | if (WARN_ON(!mdp5_crtc->ctl)) | ||
393 | return -EINVAL; | ||
394 | } | ||
395 | |||
396 | /* verify that there are not too many planes attached to crtc | 388 | /* verify that there are not too many planes attached to crtc |
397 | * and that we don't have conflicting mixer stages: | 389 | * and that we don't have conflicting mixer stages: |
398 | */ | 390 | */ |
@@ -735,8 +727,8 @@ void mdp5_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file) | |||
735 | complete_flip(crtc, file); | 727 | complete_flip(crtc, file); |
736 | } | 728 | } |
737 | 729 | ||
738 | /* set interface for routing crtc->encoder: */ | 730 | void mdp5_crtc_set_pipeline(struct drm_crtc *crtc, |
739 | void mdp5_crtc_set_intf(struct drm_crtc *crtc, struct mdp5_interface *intf) | 731 | struct mdp5_interface *intf, struct mdp5_ctl *ctl) |
740 | { | 732 | { |
741 | struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); | 733 | struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); |
742 | struct mdp5_kms *mdp5_kms = get_kms(crtc); | 734 | struct mdp5_kms *mdp5_kms = get_kms(crtc); |
@@ -759,7 +751,8 @@ void mdp5_crtc_set_intf(struct drm_crtc *crtc, struct mdp5_interface *intf) | |||
759 | 751 | ||
760 | mdp_irq_update(&mdp5_kms->base); | 752 | mdp_irq_update(&mdp5_kms->base); |
761 | 753 | ||
762 | mdp5_ctl_set_intf(mdp5_crtc->ctl, intf); | 754 | mdp5_crtc->ctl = ctl; |
755 | mdp5_ctl_set_pipeline(ctl, intf, lm); | ||
763 | } | 756 | } |
764 | 757 | ||
765 | int mdp5_crtc_get_lm(struct drm_crtc *crtc) | 758 | int mdp5_crtc_get_lm(struct drm_crtc *crtc) |
@@ -768,12 +761,6 @@ int mdp5_crtc_get_lm(struct drm_crtc *crtc) | |||
768 | return WARN_ON(!crtc) ? -EINVAL : mdp5_crtc->lm; | 761 | return WARN_ON(!crtc) ? -EINVAL : mdp5_crtc->lm; |
769 | } | 762 | } |
770 | 763 | ||
771 | struct mdp5_ctl *mdp5_crtc_get_ctl(struct drm_crtc *crtc) | ||
772 | { | ||
773 | struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); | ||
774 | return WARN_ON(!crtc) ? NULL : mdp5_crtc->ctl; | ||
775 | } | ||
776 | |||
777 | void mdp5_crtc_wait_for_commit_done(struct drm_crtc *crtc) | 764 | void mdp5_crtc_wait_for_commit_done(struct drm_crtc *crtc) |
778 | { | 765 | { |
779 | struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); | 766 | struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); |
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c index 622849bbc346..9cf987bb0b09 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c | |||
@@ -60,8 +60,6 @@ struct mdp5_ctl { | |||
60 | u32 pending_ctl_trigger; | 60 | u32 pending_ctl_trigger; |
61 | 61 | ||
62 | bool cursor_on; | 62 | bool cursor_on; |
63 | |||
64 | struct drm_crtc *crtc; | ||
65 | }; | 63 | }; |
66 | 64 | ||
67 | struct mdp5_ctl_manager { | 65 | struct mdp5_ctl_manager { |
@@ -168,11 +166,21 @@ static void set_ctl_op(struct mdp5_ctl *ctl, struct mdp5_interface *intf) | |||
168 | spin_unlock_irqrestore(&ctl->hw_lock, flags); | 166 | spin_unlock_irqrestore(&ctl->hw_lock, flags); |
169 | } | 167 | } |
170 | 168 | ||
171 | int mdp5_ctl_set_intf(struct mdp5_ctl *ctl, struct mdp5_interface *intf) | 169 | int mdp5_ctl_set_pipeline(struct mdp5_ctl *ctl, |
170 | struct mdp5_interface *intf, int lm) | ||
172 | { | 171 | { |
173 | struct mdp5_ctl_manager *ctl_mgr = ctl->ctlm; | 172 | struct mdp5_ctl_manager *ctl_mgr = ctl->ctlm; |
174 | struct mdp5_kms *mdp5_kms = get_kms(ctl_mgr); | 173 | struct mdp5_kms *mdp5_kms = get_kms(ctl_mgr); |
175 | 174 | ||
175 | if (unlikely(WARN_ON(intf->num != ctl->pipeline.intf.num))) { | ||
176 | dev_err(mdp5_kms->dev->dev, | ||
177 | "CTL %d is allocated by INTF %d, but used by INTF %d\n", | ||
178 | ctl->id, ctl->pipeline.intf.num, intf->num); | ||
179 | return -EINVAL; | ||
180 | } | ||
181 | |||
182 | ctl->lm = lm; | ||
183 | |||
176 | memcpy(&ctl->pipeline.intf, intf, sizeof(*intf)); | 184 | memcpy(&ctl->pipeline.intf, intf, sizeof(*intf)); |
177 | 185 | ||
178 | ctl->pipeline.start_mask = mdp_ctl_flush_mask_lm(ctl->lm) | | 186 | ctl->pipeline.start_mask = mdp_ctl_flush_mask_lm(ctl->lm) | |
@@ -335,7 +343,7 @@ static u32 mdp_ctl_blend_ext_mask(enum mdp5_pipe pipe, | |||
335 | } | 343 | } |
336 | } | 344 | } |
337 | 345 | ||
338 | int mdp5_ctl_blend(struct mdp5_ctl *ctl, u32 lm, u8 *stage, u32 stage_cnt, | 346 | int mdp5_ctl_blend(struct mdp5_ctl *ctl, u8 *stage, u32 stage_cnt, |
339 | u32 ctl_blend_op_flags) | 347 | u32 ctl_blend_op_flags) |
340 | { | 348 | { |
341 | unsigned long flags; | 349 | unsigned long flags; |
@@ -358,13 +366,13 @@ int mdp5_ctl_blend(struct mdp5_ctl *ctl, u32 lm, u8 *stage, u32 stage_cnt, | |||
358 | if (ctl->cursor_on) | 366 | if (ctl->cursor_on) |
359 | blend_cfg |= MDP5_CTL_LAYER_REG_CURSOR_OUT; | 367 | blend_cfg |= MDP5_CTL_LAYER_REG_CURSOR_OUT; |
360 | 368 | ||
361 | ctl_write(ctl, REG_MDP5_CTL_LAYER_REG(ctl->id, lm), blend_cfg); | 369 | ctl_write(ctl, REG_MDP5_CTL_LAYER_REG(ctl->id, ctl->lm), blend_cfg); |
362 | ctl_write(ctl, REG_MDP5_CTL_LAYER_EXT_REG(ctl->id, lm), blend_ext_cfg); | 370 | ctl_write(ctl, REG_MDP5_CTL_LAYER_EXT_REG(ctl->id, ctl->lm), blend_ext_cfg); |
363 | spin_unlock_irqrestore(&ctl->hw_lock, flags); | 371 | spin_unlock_irqrestore(&ctl->hw_lock, flags); |
364 | 372 | ||
365 | ctl->pending_ctl_trigger = mdp_ctl_flush_mask_lm(lm); | 373 | ctl->pending_ctl_trigger = mdp_ctl_flush_mask_lm(ctl->lm); |
366 | 374 | ||
367 | DBG("lm%d: blend config = 0x%08x. ext_cfg = 0x%08x", lm, | 375 | DBG("lm%d: blend config = 0x%08x. ext_cfg = 0x%08x", ctl->lm, |
368 | blend_cfg, blend_ext_cfg); | 376 | blend_cfg, blend_ext_cfg); |
369 | 377 | ||
370 | return 0; | 378 | return 0; |
@@ -490,38 +498,18 @@ u32 mdp5_ctl_get_commit_status(struct mdp5_ctl *ctl) | |||
490 | return ctl_read(ctl, REG_MDP5_CTL_FLUSH(ctl->id)); | 498 | return ctl_read(ctl, REG_MDP5_CTL_FLUSH(ctl->id)); |
491 | } | 499 | } |
492 | 500 | ||
493 | void mdp5_ctl_release(struct mdp5_ctl *ctl) | ||
494 | { | ||
495 | struct mdp5_ctl_manager *ctl_mgr = ctl->ctlm; | ||
496 | unsigned long flags; | ||
497 | |||
498 | if (unlikely(WARN_ON(ctl->id >= MAX_CTL) || !ctl->busy)) { | ||
499 | dev_err(ctl_mgr->dev->dev, "CTL %d in bad state (%d)", | ||
500 | ctl->id, ctl->busy); | ||
501 | return; | ||
502 | } | ||
503 | |||
504 | spin_lock_irqsave(&ctl_mgr->pool_lock, flags); | ||
505 | ctl->busy = false; | ||
506 | spin_unlock_irqrestore(&ctl_mgr->pool_lock, flags); | ||
507 | |||
508 | DBG("CTL %d released", ctl->id); | ||
509 | } | ||
510 | |||
511 | int mdp5_ctl_get_ctl_id(struct mdp5_ctl *ctl) | 501 | int mdp5_ctl_get_ctl_id(struct mdp5_ctl *ctl) |
512 | { | 502 | { |
513 | return WARN_ON(!ctl) ? -EINVAL : ctl->id; | 503 | return WARN_ON(!ctl) ? -EINVAL : ctl->id; |
514 | } | 504 | } |
515 | 505 | ||
516 | /* | 506 | /* |
517 | * mdp5_ctl_request() - CTL dynamic allocation | 507 | * mdp5_ctl_request() - CTL allocation |
518 | * | ||
519 | * Note: Current implementation considers that we can only have one CRTC per CTL | ||
520 | * | 508 | * |
521 | * @return first free CTL | 509 | * @return first free CTL |
522 | */ | 510 | */ |
523 | struct mdp5_ctl *mdp5_ctlm_request(struct mdp5_ctl_manager *ctl_mgr, | 511 | struct mdp5_ctl *mdp5_ctlm_request(struct mdp5_ctl_manager *ctl_mgr, |
524 | struct drm_crtc *crtc) | 512 | int intf_num) |
525 | { | 513 | { |
526 | struct mdp5_ctl *ctl = NULL; | 514 | struct mdp5_ctl *ctl = NULL; |
527 | unsigned long flags; | 515 | unsigned long flags; |
@@ -539,9 +527,8 @@ struct mdp5_ctl *mdp5_ctlm_request(struct mdp5_ctl_manager *ctl_mgr, | |||
539 | } | 527 | } |
540 | 528 | ||
541 | ctl = &ctl_mgr->ctls[c]; | 529 | ctl = &ctl_mgr->ctls[c]; |
542 | 530 | ctl->pipeline.intf.num = intf_num; | |
543 | ctl->lm = mdp5_crtc_get_lm(crtc); | 531 | ctl->lm = -1; |
544 | ctl->crtc = crtc; | ||
545 | ctl->busy = true; | 532 | ctl->busy = true; |
546 | ctl->pending_ctl_trigger = 0; | 533 | ctl->pending_ctl_trigger = 0; |
547 | DBG("CTL %d allocated", ctl->id); | 534 | DBG("CTL %d allocated", ctl->id); |
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h index ab52675d2bd0..5f473fa3aa50 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h | |||
@@ -32,11 +32,12 @@ void mdp5_ctlm_destroy(struct mdp5_ctl_manager *ctlm); | |||
32 | * mdp5_ctl_request(ctlm, ...) returns a ctl (CTL resource) handler, | 32 | * mdp5_ctl_request(ctlm, ...) returns a ctl (CTL resource) handler, |
33 | * which is then used to call the other mdp5_ctl_*(ctl, ...) functions. | 33 | * which is then used to call the other mdp5_ctl_*(ctl, ...) functions. |
34 | */ | 34 | */ |
35 | struct mdp5_ctl *mdp5_ctlm_request(struct mdp5_ctl_manager *ctlm, struct drm_crtc *crtc); | 35 | struct mdp5_ctl *mdp5_ctlm_request(struct mdp5_ctl_manager *ctlm, int intf_num); |
36 | int mdp5_ctl_get_ctl_id(struct mdp5_ctl *ctl); | 36 | int mdp5_ctl_get_ctl_id(struct mdp5_ctl *ctl); |
37 | 37 | ||
38 | struct mdp5_interface; | 38 | struct mdp5_interface; |
39 | int mdp5_ctl_set_intf(struct mdp5_ctl *ctl, struct mdp5_interface *intf); | 39 | int mdp5_ctl_set_pipeline(struct mdp5_ctl *ctl, struct mdp5_interface *intf, |
40 | int lm); | ||
40 | int mdp5_ctl_set_encoder_state(struct mdp5_ctl *ctl, bool enabled); | 41 | int mdp5_ctl_set_encoder_state(struct mdp5_ctl *ctl, bool enabled); |
41 | 42 | ||
42 | int mdp5_ctl_set_cursor(struct mdp5_ctl *ctl, int cursor_id, bool enable); | 43 | int mdp5_ctl_set_cursor(struct mdp5_ctl *ctl, int cursor_id, bool enable); |
@@ -53,7 +54,7 @@ int mdp5_ctl_set_cursor(struct mdp5_ctl *ctl, int cursor_id, bool enable); | |||
53 | * (call mdp5_ctl_commit() with mdp_ctl_flush_mask_ctl() mask) | 54 | * (call mdp5_ctl_commit() with mdp_ctl_flush_mask_ctl() mask) |
54 | */ | 55 | */ |
55 | #define MDP5_CTL_BLEND_OP_FLAG_BORDER_OUT BIT(0) | 56 | #define MDP5_CTL_BLEND_OP_FLAG_BORDER_OUT BIT(0) |
56 | int mdp5_ctl_blend(struct mdp5_ctl *ctl, u32 lm, u8 *stage, u32 stage_cnt, | 57 | int mdp5_ctl_blend(struct mdp5_ctl *ctl, u8 *stage, u32 stage_cnt, |
57 | u32 ctl_blend_op_flags); | 58 | u32 ctl_blend_op_flags); |
58 | 59 | ||
59 | /** | 60 | /** |
@@ -71,8 +72,6 @@ u32 mdp_ctl_flush_mask_encoder(struct mdp5_interface *intf); | |||
71 | u32 mdp5_ctl_commit(struct mdp5_ctl *ctl, u32 flush_mask); | 72 | u32 mdp5_ctl_commit(struct mdp5_ctl *ctl, u32 flush_mask); |
72 | u32 mdp5_ctl_get_commit_status(struct mdp5_ctl *ctl); | 73 | u32 mdp5_ctl_get_commit_status(struct mdp5_ctl *ctl); |
73 | 74 | ||
74 | void mdp5_ctl_release(struct mdp5_ctl *ctl); | ||
75 | |||
76 | 75 | ||
77 | 76 | ||
78 | #endif /* __MDP5_CTL_H__ */ | 77 | #endif /* __MDP5_CTL_H__ */ |
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c index de97c08f3f1f..3fa19138b388 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c | |||
@@ -27,6 +27,8 @@ struct mdp5_encoder { | |||
27 | spinlock_t intf_lock; /* protect REG_MDP5_INTF_* registers */ | 27 | spinlock_t intf_lock; /* protect REG_MDP5_INTF_* registers */ |
28 | bool enabled; | 28 | bool enabled; |
29 | uint32_t bsc; | 29 | uint32_t bsc; |
30 | |||
31 | struct mdp5_ctl *ctl; | ||
30 | }; | 32 | }; |
31 | #define to_mdp5_encoder(x) container_of(x, struct mdp5_encoder, base) | 33 | #define to_mdp5_encoder(x) container_of(x, struct mdp5_encoder, base) |
32 | 34 | ||
@@ -222,14 +224,15 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder, | |||
222 | 224 | ||
223 | spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags); | 225 | spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags); |
224 | 226 | ||
225 | mdp5_crtc_set_intf(encoder->crtc, &mdp5_encoder->intf); | 227 | mdp5_crtc_set_pipeline(encoder->crtc, &mdp5_encoder->intf, |
228 | mdp5_encoder->ctl); | ||
226 | } | 229 | } |
227 | 230 | ||
228 | static void mdp5_encoder_disable(struct drm_encoder *encoder) | 231 | static void mdp5_encoder_disable(struct drm_encoder *encoder) |
229 | { | 232 | { |
230 | struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); | 233 | struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); |
231 | struct mdp5_kms *mdp5_kms = get_kms(encoder); | 234 | struct mdp5_kms *mdp5_kms = get_kms(encoder); |
232 | struct mdp5_ctl *ctl = mdp5_crtc_get_ctl(encoder->crtc); | 235 | struct mdp5_ctl *ctl = mdp5_encoder->ctl; |
233 | int lm = mdp5_crtc_get_lm(encoder->crtc); | 236 | int lm = mdp5_crtc_get_lm(encoder->crtc); |
234 | struct mdp5_interface *intf = &mdp5_encoder->intf; | 237 | struct mdp5_interface *intf = &mdp5_encoder->intf; |
235 | int intfn = mdp5_encoder->intf.num; | 238 | int intfn = mdp5_encoder->intf.num; |
@@ -264,7 +267,7 @@ static void mdp5_encoder_enable(struct drm_encoder *encoder) | |||
264 | { | 267 | { |
265 | struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); | 268 | struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); |
266 | struct mdp5_kms *mdp5_kms = get_kms(encoder); | 269 | struct mdp5_kms *mdp5_kms = get_kms(encoder); |
267 | struct mdp5_ctl *ctl = mdp5_crtc_get_ctl(encoder->crtc); | 270 | struct mdp5_ctl *ctl = mdp5_encoder->ctl; |
268 | struct mdp5_interface *intf = &mdp5_encoder->intf; | 271 | struct mdp5_interface *intf = &mdp5_encoder->intf; |
269 | int intfn = mdp5_encoder->intf.num; | 272 | int intfn = mdp5_encoder->intf.num; |
270 | unsigned long flags; | 273 | unsigned long flags; |
@@ -329,7 +332,7 @@ int mdp5_encoder_set_split_display(struct drm_encoder *encoder, | |||
329 | 332 | ||
330 | /* initialize encoder */ | 333 | /* initialize encoder */ |
331 | struct drm_encoder *mdp5_encoder_init(struct drm_device *dev, | 334 | struct drm_encoder *mdp5_encoder_init(struct drm_device *dev, |
332 | struct mdp5_interface *intf) | 335 | struct mdp5_interface *intf, struct mdp5_ctl *ctl) |
333 | { | 336 | { |
334 | struct drm_encoder *encoder = NULL; | 337 | struct drm_encoder *encoder = NULL; |
335 | struct mdp5_encoder *mdp5_encoder; | 338 | struct mdp5_encoder *mdp5_encoder; |
@@ -345,6 +348,7 @@ struct drm_encoder *mdp5_encoder_init(struct drm_device *dev, | |||
345 | 348 | ||
346 | memcpy(&mdp5_encoder->intf, intf, sizeof(mdp5_encoder->intf)); | 349 | memcpy(&mdp5_encoder->intf, intf, sizeof(mdp5_encoder->intf)); |
347 | encoder = &mdp5_encoder->base; | 350 | encoder = &mdp5_encoder->base; |
351 | mdp5_encoder->ctl = ctl; | ||
348 | 352 | ||
349 | spin_lock_init(&mdp5_encoder->intf_lock); | 353 | spin_lock_init(&mdp5_encoder->intf_lock); |
350 | 354 | ||
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 97d9da2175b4..cd587a6dfbd0 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | |||
@@ -198,7 +198,7 @@ int mdp5_enable(struct mdp5_kms *mdp5_kms) | |||
198 | 198 | ||
199 | static struct drm_encoder *construct_encoder(struct mdp5_kms *mdp5_kms, | 199 | static struct drm_encoder *construct_encoder(struct mdp5_kms *mdp5_kms, |
200 | enum mdp5_intf_type intf_type, int intf_num, | 200 | enum mdp5_intf_type intf_type, int intf_num, |
201 | enum mdp5_intf_mode intf_mode) | 201 | enum mdp5_intf_mode intf_mode, struct mdp5_ctl *ctl) |
202 | { | 202 | { |
203 | struct drm_device *dev = mdp5_kms->dev; | 203 | struct drm_device *dev = mdp5_kms->dev; |
204 | struct msm_drm_private *priv = dev->dev_private; | 204 | struct msm_drm_private *priv = dev->dev_private; |
@@ -211,9 +211,9 @@ static struct drm_encoder *construct_encoder(struct mdp5_kms *mdp5_kms, | |||
211 | 211 | ||
212 | if ((intf_type == INTF_DSI) && | 212 | if ((intf_type == INTF_DSI) && |
213 | (intf_mode == MDP5_INTF_DSI_MODE_COMMAND)) | 213 | (intf_mode == MDP5_INTF_DSI_MODE_COMMAND)) |
214 | encoder = mdp5_cmd_encoder_init(dev, &intf); | 214 | encoder = mdp5_cmd_encoder_init(dev, &intf, ctl); |
215 | else | 215 | else |
216 | encoder = mdp5_encoder_init(dev, &intf); | 216 | encoder = mdp5_encoder_init(dev, &intf, ctl); |
217 | 217 | ||
218 | if (IS_ERR(encoder)) { | 218 | if (IS_ERR(encoder)) { |
219 | dev_err(dev->dev, "failed to construct encoder\n"); | 219 | dev_err(dev->dev, "failed to construct encoder\n"); |
@@ -251,6 +251,8 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num) | |||
251 | const struct mdp5_cfg_hw *hw_cfg = | 251 | const struct mdp5_cfg_hw *hw_cfg = |
252 | mdp5_cfg_get_hw_config(mdp5_kms->cfg); | 252 | mdp5_cfg_get_hw_config(mdp5_kms->cfg); |
253 | enum mdp5_intf_type intf_type = hw_cfg->intf.connect[intf_num]; | 253 | enum mdp5_intf_type intf_type = hw_cfg->intf.connect[intf_num]; |
254 | struct mdp5_ctl_manager *ctlm = mdp5_kms->ctlm; | ||
255 | struct mdp5_ctl *ctl; | ||
254 | struct drm_encoder *encoder; | 256 | struct drm_encoder *encoder; |
255 | int ret = 0; | 257 | int ret = 0; |
256 | 258 | ||
@@ -261,8 +263,14 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num) | |||
261 | if (!priv->edp) | 263 | if (!priv->edp) |
262 | break; | 264 | break; |
263 | 265 | ||
266 | ctl = mdp5_ctlm_request(ctlm, intf_num); | ||
267 | if (!ctl) { | ||
268 | ret = -EINVAL; | ||
269 | break; | ||
270 | } | ||
271 | |||
264 | encoder = construct_encoder(mdp5_kms, INTF_eDP, intf_num, | 272 | encoder = construct_encoder(mdp5_kms, INTF_eDP, intf_num, |
265 | MDP5_INTF_MODE_NONE); | 273 | MDP5_INTF_MODE_NONE, ctl); |
266 | if (IS_ERR(encoder)) { | 274 | if (IS_ERR(encoder)) { |
267 | ret = PTR_ERR(encoder); | 275 | ret = PTR_ERR(encoder); |
268 | break; | 276 | break; |
@@ -274,8 +282,14 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num) | |||
274 | if (!priv->hdmi) | 282 | if (!priv->hdmi) |
275 | break; | 283 | break; |
276 | 284 | ||
285 | ctl = mdp5_ctlm_request(ctlm, intf_num); | ||
286 | if (!ctl) { | ||
287 | ret = -EINVAL; | ||
288 | break; | ||
289 | } | ||
290 | |||
277 | encoder = construct_encoder(mdp5_kms, INTF_HDMI, intf_num, | 291 | encoder = construct_encoder(mdp5_kms, INTF_HDMI, intf_num, |
278 | MDP5_INTF_MODE_NONE); | 292 | MDP5_INTF_MODE_NONE, ctl); |
279 | if (IS_ERR(encoder)) { | 293 | if (IS_ERR(encoder)) { |
280 | ret = PTR_ERR(encoder); | 294 | ret = PTR_ERR(encoder); |
281 | break; | 295 | break; |
@@ -300,14 +314,20 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num) | |||
300 | if (!priv->dsi[dsi_id]) | 314 | if (!priv->dsi[dsi_id]) |
301 | break; | 315 | break; |
302 | 316 | ||
317 | ctl = mdp5_ctlm_request(ctlm, intf_num); | ||
318 | if (!ctl) { | ||
319 | ret = -EINVAL; | ||
320 | break; | ||
321 | } | ||
322 | |||
303 | for (i = 0; i < MSM_DSI_ENCODER_NUM; i++) { | 323 | for (i = 0; i < MSM_DSI_ENCODER_NUM; i++) { |
304 | mode = (i == MSM_DSI_CMD_ENCODER_ID) ? | 324 | mode = (i == MSM_DSI_CMD_ENCODER_ID) ? |
305 | MDP5_INTF_DSI_MODE_COMMAND : | 325 | MDP5_INTF_DSI_MODE_COMMAND : |
306 | MDP5_INTF_DSI_MODE_VIDEO; | 326 | MDP5_INTF_DSI_MODE_VIDEO; |
307 | dsi_encs[i] = construct_encoder(mdp5_kms, INTF_DSI, | 327 | dsi_encs[i] = construct_encoder(mdp5_kms, INTF_DSI, |
308 | intf_num, mode); | 328 | intf_num, mode, ctl); |
309 | if (IS_ERR(dsi_encs)) { | 329 | if (IS_ERR(dsi_encs[i])) { |
310 | ret = PTR_ERR(dsi_encs); | 330 | ret = PTR_ERR(dsi_encs[i]); |
311 | break; | 331 | break; |
312 | } | 332 | } |
313 | } | 333 | } |
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h index 776b84b828e3..dc94c8f29404 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | |||
@@ -228,26 +228,26 @@ struct drm_plane *mdp5_plane_init(struct drm_device *dev, | |||
228 | uint32_t mdp5_crtc_vblank(struct drm_crtc *crtc); | 228 | uint32_t mdp5_crtc_vblank(struct drm_crtc *crtc); |
229 | 229 | ||
230 | int mdp5_crtc_get_lm(struct drm_crtc *crtc); | 230 | int mdp5_crtc_get_lm(struct drm_crtc *crtc); |
231 | struct mdp5_ctl *mdp5_crtc_get_ctl(struct drm_crtc *crtc); | ||
232 | void mdp5_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file); | 231 | void mdp5_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file); |
233 | void mdp5_crtc_set_intf(struct drm_crtc *crtc, struct mdp5_interface *intf); | 232 | void mdp5_crtc_set_pipeline(struct drm_crtc *crtc, |
233 | struct mdp5_interface *intf, struct mdp5_ctl *ctl); | ||
234 | void mdp5_crtc_wait_for_commit_done(struct drm_crtc *crtc); | 234 | void mdp5_crtc_wait_for_commit_done(struct drm_crtc *crtc); |
235 | struct drm_crtc *mdp5_crtc_init(struct drm_device *dev, | 235 | struct drm_crtc *mdp5_crtc_init(struct drm_device *dev, |
236 | struct drm_plane *plane, int id); | 236 | struct drm_plane *plane, int id); |
237 | 237 | ||
238 | struct drm_encoder *mdp5_encoder_init(struct drm_device *dev, | 238 | struct drm_encoder *mdp5_encoder_init(struct drm_device *dev, |
239 | struct mdp5_interface *intf); | 239 | struct mdp5_interface *intf, struct mdp5_ctl *ctl); |
240 | int mdp5_encoder_set_split_display(struct drm_encoder *encoder, | 240 | int mdp5_encoder_set_split_display(struct drm_encoder *encoder, |
241 | struct drm_encoder *slave_encoder); | 241 | struct drm_encoder *slave_encoder); |
242 | 242 | ||
243 | #ifdef CONFIG_DRM_MSM_DSI | 243 | #ifdef CONFIG_DRM_MSM_DSI |
244 | struct drm_encoder *mdp5_cmd_encoder_init(struct drm_device *dev, | 244 | struct drm_encoder *mdp5_cmd_encoder_init(struct drm_device *dev, |
245 | struct mdp5_interface *intf); | 245 | struct mdp5_interface *intf, struct mdp5_ctl *ctl); |
246 | int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder, | 246 | int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder, |
247 | struct drm_encoder *slave_encoder); | 247 | struct drm_encoder *slave_encoder); |
248 | #else | 248 | #else |
249 | static inline struct drm_encoder *mdp5_cmd_encoder_init( | 249 | static inline struct drm_encoder *mdp5_cmd_encoder_init(struct drm_device *dev, |
250 | struct drm_device *dev, struct mdp5_interface *intf) | 250 | struct mdp5_interface *intf, struct mdp5_ctl *ctl) |
251 | { | 251 | { |
252 | return ERR_PTR(-EINVAL); | 252 | return ERR_PTR(-EINVAL); |
253 | } | 253 | } |