drm/msm/mdp5: negative x/y in cursor move
Rob Clark
robdclark at gmail.com
Mon Jul 16 11:49:57 UTC 2018
On Tue, Jul 10, 2018 at 1:18 PM, Carsten Behling
<carsten.behling at googlemail.com> wrote:
> I found the solution:
>
> ROI has to be recalculated for negative x/y indicating using the lower/right
> corner of the cursor buffer. Further, MDP5_LM_CURSOR_XY_SRC_Y and
> MDP5_LM_CURSOR_XY_SRC_X mus be calculated for the hotspot:
oh, sorry, I had not seen your earlier msg.. but if you haven't found
it already, mdp5 (and rest of SoC) register docs are in the HRD:
http://linaro.co/96b-qc-hrd
(often somewhat, umm, terse, but can be helpful)
If you could send this as a proper git patch, that would be appreciated. Thx
BR,
-R
>
> Index: kernel-source/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
> ===================================================================
> --- kernel-source.orig/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
> +++ kernel-source/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
> @@ -65,7 +65,7 @@ struct mdp5_crtc {
> struct drm_gem_object *scanout_bo;
> uint64_t iova;
> uint32_t width, height;
> - uint32_t x, y;
> + int x, y;
> } cursor;
> };
> #define to_mdp5_crtc(x) container_of(x, struct mdp5_crtc, base)
> @@ -756,10 +756,16 @@ static void get_roi(struct drm_crtc *crt
> * (xres-x) will be new cursor width when x > (xres - cursor.width)
> * (yres-y) will be new cursor height when y > (yres - cursor.height)
> */
> - *roi_w = min(mdp5_crtc->cursor.width, xres -
> - mdp5_crtc->cursor.x);
> - *roi_h = min(mdp5_crtc->cursor.height, yres -
> - mdp5_crtc->cursor.y);
> + if (mdp5_crtc->cursor.x >= 0)
> + *roi_w = min(mdp5_crtc->cursor.width, xres -
> + mdp5_crtc->cursor.x);
> + else
> + *roi_w = mdp5_crtc->cursor.width - abs(mdp5_crtc->cursor.x);
> + if (mdp5_crtc->cursor.y >= 0)
> + *roi_h = min(mdp5_crtc->cursor.height, yres -
> + mdp5_crtc->cursor.y);
> + else
> + *roi_h = mdp5_crtc->cursor.height - abs(mdp5_crtc->cursor.y);
> }
>
> static void mdp5_crtc_restore_cursor(struct drm_crtc *crtc)
> @@ -769,7 +775,7 @@ static void mdp5_crtc_restore_cursor(str
> struct mdp5_kms *mdp5_kms = get_kms(crtc);
> const enum mdp5_cursor_alpha cur_alpha = CURSOR_ALPHA_PER_PIXEL;
> uint32_t blendcfg, stride;
> - uint32_t x, y, width, height;
> + uint32_t x, y, src_x, src_y, width, height;
> uint32_t roi_w, roi_h;
> int lm;
>
> @@ -786,6 +792,20 @@ static void mdp5_crtc_restore_cursor(str
>
> get_roi(crtc, &roi_w, &roi_h);
>
> + if (mdp5_crtc->cursor.x < 0) {
> + src_x = abs(mdp5_crtc->cursor.x);
> + x = 0;
> + } else
> + src_x = 0;
> +
> + if (mdp5_crtc->cursor.y < 0) {
> + src_y = abs(mdp5_crtc->cursor.y);
> + y = 0;
> + } else
> + src_y = 0;
> +
> + //printk("x=%d, y=%d roi_w=%d roi_h=%d src_x=%d src_y=%d\n", x, y, roi_w,
> roi_h, src_x, src_y);
> +
> mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_STRIDE(lm), stride);
> mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_FORMAT(lm),
> MDP5_LM_CURSOR_FORMAT_FORMAT(CURSOR_FMT_ARGB8888));
> @@ -798,6 +818,9 @@ static void mdp5_crtc_restore_cursor(str
> mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_START_XY(lm),
> MDP5_LM_CURSOR_START_XY_Y_START(y) |
> MDP5_LM_CURSOR_START_XY_X_START(x));
> + mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_XY(lm),
> + MDP5_LM_CURSOR_XY_SRC_Y(src_y) |
> + MDP5_LM_CURSOR_XY_SRC_X(src_x));
> mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_BASE_ADDR(lm),
> mdp5_crtc->cursor.iova);
>
> @@ -903,6 +926,8 @@ static int mdp5_crtc_cursor_move(struct
> uint32_t roi_w;
> uint32_t roi_h;
> unsigned long flags;
> + int border_x = mdp5_crtc->cursor.width * (-1);
> + int border_y = mdp5_crtc->cursor.height * (-1);
>
> if (!mdp5_crtc->lm_cursor_enabled) {
> dev_warn(dev->dev,
> @@ -918,8 +943,8 @@ static int mdp5_crtc_cursor_move(struct
> if (unlikely(!crtc->state->enable))
> return 0;
>
> - mdp5_crtc->cursor.x = x = max(x, 0);
> - mdp5_crtc->cursor.y = y = max(y, 0);
> + mdp5_crtc->cursor.x = x = max(x, border_x);
> + mdp5_crtc->cursor.y = y = max(y, border_y);
>
> get_roi(crtc, &roi_w, &roi_h);
>
> Best regards
> -Carsten
>
> 2018-07-10 12:11 GMT+02:00 Carsten Behling <carsten.behling at googlemail.com>:
>>
>> Hi,
>>
>> modesetting X11 driver may provide negative x/y cordinates in
>> mdp5_crtc_cursor_move(...) call when rotation is enabled.
>>
>> Because of
>>
>> static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
>> {
>> ...
>> mdp5_crtc->cursor.x = x = max(x, 0);
>> mdp5_crtc->cursor.y = y = max(y, 0);
>> ...
>> }
>>
>> x/y is calmped to 0/0 in those cases resulting that the cursor does not
>> move anymore beyond mdp5_crtc->cursor.width, mdp5_crtc->cursor.height.
>>
>> For e.g rotation of 180 degree that means that the upper left cursor point
>> stays never reaches the region (0/0) to
>> (mdp5_crtc->cursor.width/mdp5_crtc->cursor.height).
>>
>> I already asked the X men if this should be fixed in modesetting driver or
>> in the kernel CRT
>> functions:
>>
>> https://www.spinics.net/lists/xorg/msg58969.html
>>
>> They told me to fix this in the kernel.
>>
>> So, I suppose:
>>
>> 1.) cursor x should be rather clamped instead to
>>
>> static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) {
>> ...
>> mdp5_crtc->cursor.x = x = max(x, -mdp5_crtc->cursor.width);
>> mdp5_crtc->cursor.y = y = max(y, -mdp5_crtc->cursor.height);
>> ...
>> }
>>
>> 2.) The ROI calculation must be extendet to:
>>
>> static void get_roi(struct drm_crtc *crtc, uint32_t *roi_w, uint32_t
>> *roi_h)
>> {
>> ...
>> if (x>=0)
>> *roi_w = min(mdp5_crtc->cursor.width, xres -
>> mdp5_crtc->cursor.x);
>> else
>> *roi_w = mdp5_crtc->cursor.width - abs(mdp5_crtc->cursor.x);
>> if (y>=0)
>> *roi_h = min(mdp5_crtc->cursor.height, yres -
>> mdp5_crtc->cursor.y);
>> else
>> *roi_h = mdp5_crtc->cursor.height - abs(mdp5_crtc->cursor.y);
>> ...
>> }
>>
>> 3.) There has to be some kind of hotspot setup in
>> mdp5_crtc_restore_cursor(...)
>>
>> Since I have no MDP5 documentation, I don't know how to setup the hotspot
>> and I can't
>> implement 3.)
>>
>> Please help!
>>
>> Best regards
>> -Carsten
>
>
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>
More information about the dri-devel
mailing list