aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/msm
diff options
context:
space:
mode:
authorRob Clark <robdclark@gmail.com>2015-02-24 14:47:57 -0500
committerRob Clark <robdclark@gmail.com>2015-03-04 18:23:40 -0500
commit58560890b3e33d789c4f13a10324af9c85c52308 (patch)
tree069ddbbd3ddef93fecb500b5f3ff842cd634679a /drivers/gpu/drm/msm
parent5b2e2b6c5e542f7334dcaeb5b577d8328a5f2fc0 (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.c68
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
414static 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
414static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, 440static 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),