diff options
author | Rob Clark <robdclark@gmail.com> | 2015-02-24 14:47:57 -0500 |
---|---|---|
committer | Rob Clark <robdclark@gmail.com> | 2015-03-04 18:23:40 -0500 |
commit | 58560890b3e33d789c4f13a10324af9c85c52308 (patch) | |
tree | 069ddbbd3ddef93fecb500b5f3ff842cd634679a /drivers/gpu/drm/msm | |
parent | 5b2e2b6c5e542f7334dcaeb5b577d8328a5f2fc0 (diff) |
drm/msm/mdp5: fix cursor ROI
If cursor is set near the edge of the screen, it is not valid to use the
new cursor width/height as the ROI dimensions. Split out the ROI calc
and use it both cursor_set and cursor_move.
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_crtc.c | 68 |
1 files changed, 40 insertions, 28 deletions
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index 2aeae7351621..4c4be4344653 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | |||
@@ -62,8 +62,8 @@ struct mdp5_crtc { | |||
62 | 62 | ||
63 | /* current cursor being scanned out: */ | 63 | /* current cursor being scanned out: */ |
64 | struct drm_gem_object *scanout_bo; | 64 | struct drm_gem_object *scanout_bo; |
65 | uint32_t width; | 65 | uint32_t width, height; |
66 | uint32_t height; | 66 | uint32_t x, y; |
67 | } cursor; | 67 | } cursor; |
68 | }; | 68 | }; |
69 | #define to_mdp5_crtc(x) container_of(x, struct mdp5_crtc, base) | 69 | #define to_mdp5_crtc(x) container_of(x, struct mdp5_crtc, base) |
@@ -411,6 +411,32 @@ static int mdp5_crtc_set_property(struct drm_crtc *crtc, | |||
411 | return -EINVAL; | 411 | return -EINVAL; |
412 | } | 412 | } |
413 | 413 | ||
414 | static void get_roi(struct drm_crtc *crtc, uint32_t *roi_w, uint32_t *roi_h) | ||
415 | { | ||
416 | struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); | ||
417 | uint32_t xres = crtc->mode.hdisplay; | ||
418 | uint32_t yres = crtc->mode.vdisplay; | ||
419 | |||
420 | /* | ||
421 | * Cursor Region Of Interest (ROI) is a plane read from cursor | ||
422 | * buffer to render. The ROI region is determined by the visibility of | ||
423 | * the cursor point. In the default Cursor image the cursor point will | ||
424 | * be at the top left of the cursor image, unless it is specified | ||
425 | * otherwise using hotspot feature. | ||
426 | * | ||
427 | * If the cursor point reaches the right (xres - x < cursor.width) or | ||
428 | * bottom (yres - y < cursor.height) boundary of the screen, then ROI | ||
429 | * width and ROI height need to be evaluated to crop the cursor image | ||
430 | * accordingly. | ||
431 | * (xres-x) will be new cursor width when x > (xres - cursor.width) | ||
432 | * (yres-y) will be new cursor height when y > (yres - cursor.height) | ||
433 | */ | ||
434 | *roi_w = min(mdp5_crtc->cursor.width, xres - | ||
435 | mdp5_crtc->cursor.x); | ||
436 | *roi_h = min(mdp5_crtc->cursor.height, yres - | ||
437 | mdp5_crtc->cursor.y); | ||
438 | } | ||
439 | |||
414 | static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, | 440 | static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, |
415 | struct drm_file *file, uint32_t handle, | 441 | struct drm_file *file, uint32_t handle, |
416 | uint32_t width, uint32_t height) | 442 | uint32_t width, uint32_t height) |
@@ -424,6 +450,7 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, | |||
424 | unsigned int depth; | 450 | unsigned int depth; |
425 | enum mdp5_cursor_alpha cur_alpha = CURSOR_ALPHA_PER_PIXEL; | 451 | enum mdp5_cursor_alpha cur_alpha = CURSOR_ALPHA_PER_PIXEL; |
426 | uint32_t flush_mask = mdp_ctl_flush_mask_cursor(0); | 452 | uint32_t flush_mask = mdp_ctl_flush_mask_cursor(0); |
453 | uint32_t roi_w, roi_h; | ||
427 | unsigned long flags; | 454 | unsigned long flags; |
428 | 455 | ||
429 | if ((width > CURSOR_WIDTH) || (height > CURSOR_HEIGHT)) { | 456 | if ((width > CURSOR_WIDTH) || (height > CURSOR_HEIGHT)) { |
@@ -454,6 +481,12 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, | |||
454 | spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags); | 481 | spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags); |
455 | old_bo = mdp5_crtc->cursor.scanout_bo; | 482 | old_bo = mdp5_crtc->cursor.scanout_bo; |
456 | 483 | ||
484 | mdp5_crtc->cursor.scanout_bo = cursor_bo; | ||
485 | mdp5_crtc->cursor.width = width; | ||
486 | mdp5_crtc->cursor.height = height; | ||
487 | |||
488 | get_roi(crtc, &roi_w, &roi_h); | ||
489 | |||
457 | mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_STRIDE(lm), stride); | 490 | mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_STRIDE(lm), stride); |
458 | mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_FORMAT(lm), | 491 | mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_FORMAT(lm), |
459 | MDP5_LM_CURSOR_FORMAT_FORMAT(CURSOR_FMT_ARGB8888)); | 492 | MDP5_LM_CURSOR_FORMAT_FORMAT(CURSOR_FMT_ARGB8888)); |
@@ -461,19 +494,15 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, | |||
461 | MDP5_LM_CURSOR_IMG_SIZE_SRC_H(height) | | 494 | MDP5_LM_CURSOR_IMG_SIZE_SRC_H(height) | |
462 | MDP5_LM_CURSOR_IMG_SIZE_SRC_W(width)); | 495 | MDP5_LM_CURSOR_IMG_SIZE_SRC_W(width)); |
463 | mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_SIZE(lm), | 496 | mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_SIZE(lm), |
464 | MDP5_LM_CURSOR_SIZE_ROI_H(height) | | 497 | MDP5_LM_CURSOR_SIZE_ROI_H(roi_h) | |
465 | MDP5_LM_CURSOR_SIZE_ROI_W(width)); | 498 | MDP5_LM_CURSOR_SIZE_ROI_W(roi_w)); |
466 | mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_BASE_ADDR(lm), cursor_addr); | 499 | mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_BASE_ADDR(lm), cursor_addr); |
467 | 500 | ||
468 | |||
469 | blendcfg = MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_EN; | 501 | blendcfg = MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_EN; |
470 | blendcfg |= MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_TRANSP_EN; | 502 | blendcfg |= MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_TRANSP_EN; |
471 | blendcfg |= MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_ALPHA_SEL(cur_alpha); | 503 | blendcfg |= MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_ALPHA_SEL(cur_alpha); |
472 | mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_BLEND_CONFIG(lm), blendcfg); | 504 | mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_BLEND_CONFIG(lm), blendcfg); |
473 | 505 | ||
474 | mdp5_crtc->cursor.scanout_bo = cursor_bo; | ||
475 | mdp5_crtc->cursor.width = width; | ||
476 | mdp5_crtc->cursor.height = height; | ||
477 | spin_unlock_irqrestore(&mdp5_crtc->cursor.lock, flags); | 506 | spin_unlock_irqrestore(&mdp5_crtc->cursor.lock, flags); |
478 | 507 | ||
479 | ret = mdp5_ctl_set_cursor(mdp5_crtc->ctl, true); | 508 | ret = mdp5_ctl_set_cursor(mdp5_crtc->ctl, true); |
@@ -497,8 +526,6 @@ static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) | |||
497 | struct mdp5_kms *mdp5_kms = get_kms(crtc); | 526 | struct mdp5_kms *mdp5_kms = get_kms(crtc); |
498 | struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); | 527 | struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); |
499 | uint32_t flush_mask = mdp_ctl_flush_mask_cursor(0); | 528 | uint32_t flush_mask = mdp_ctl_flush_mask_cursor(0); |
500 | uint32_t xres = crtc->mode.hdisplay; | ||
501 | uint32_t yres = crtc->mode.vdisplay; | ||
502 | uint32_t roi_w; | 529 | uint32_t roi_w; |
503 | uint32_t roi_h; | 530 | uint32_t roi_h; |
504 | unsigned long flags; | 531 | unsigned long flags; |
@@ -507,25 +534,10 @@ static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) | |||
507 | if (unlikely(!crtc->state->enable)) | 534 | if (unlikely(!crtc->state->enable)) |
508 | return 0; | 535 | return 0; |
509 | 536 | ||
510 | x = (x > 0) ? x : 0; | 537 | mdp5_crtc->cursor.x = x = max(x, 0); |
511 | y = (y > 0) ? y : 0; | 538 | mdp5_crtc->cursor.y = y = max(y, 0); |
512 | 539 | ||
513 | /* | 540 | get_roi(crtc, &roi_w, &roi_h); |
514 | * Cursor Region Of Interest (ROI) is a plane read from cursor | ||
515 | * buffer to render. The ROI region is determined by the visiblity of | ||
516 | * the cursor point. In the default Cursor image the cursor point will | ||
517 | * be at the top left of the cursor image, unless it is specified | ||
518 | * otherwise using hotspot feature. | ||
519 | * | ||
520 | * If the cursor point reaches the right (xres - x < cursor.width) or | ||
521 | * bottom (yres - y < cursor.height) boundary of the screen, then ROI | ||
522 | * width and ROI height need to be evaluated to crop the cursor image | ||
523 | * accordingly. | ||
524 | * (xres-x) will be new cursor width when x > (xres - cursor.width) | ||
525 | * (yres-y) will be new cursor height when y > (yres - cursor.height) | ||
526 | */ | ||
527 | roi_w = min(mdp5_crtc->cursor.width, xres - x); | ||
528 | roi_h = min(mdp5_crtc->cursor.height, yres - y); | ||
529 | 541 | ||
530 | spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags); | 542 | spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags); |
531 | mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_SIZE(mdp5_crtc->lm), | 543 | mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_SIZE(mdp5_crtc->lm), |