<div dir="ltr">I found the solution:<div><br></div><div>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:</div><div><br></div><div><div>Index: kernel-source/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c</div><div>===================================================================</div><div>--- kernel-source.orig/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c</div><div>+++ kernel-source/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c</div><div>@@ -65,7 +65,7 @@ struct mdp5_crtc {</div><div> <span style="white-space:pre">          </span>struct drm_gem_object *scanout_bo;</div><div> <span style="white-space:pre">          </span>uint64_t iova;</div><div> <span style="white-space:pre">              </span>uint32_t width, height;</div><div>-<span style="white-space:pre">              </span>uint32_t x, y;</div><div>+<span style="white-space:pre">               </span>int x, y;</div><div> <span style="white-space:pre">   </span>} cursor;</div><div> };</div><div> #define to_mdp5_crtc(x) container_of(x, struct mdp5_crtc, base)</div><div>@@ -756,10 +756,16 @@ static void get_roi(struct drm_crtc *crt</div><div> <span style="white-space:pre">   </span> * (xres-x) will be new cursor width when x > (xres - cursor.width)</div><div> <span style="white-space:pre">      </span> * (yres-y) will be new cursor height when y > (yres - cursor.height)</div><div> <span style="white-space:pre">    </span> */</div><div>-<span style="white-space:pre">  </span>*roi_w = min(mdp5_crtc->cursor.width, xres -</div><div>-<span style="white-space:pre">                      </span>mdp5_crtc->cursor.x);</div><div>-<span style="white-space:pre">     </span>*roi_h = min(mdp5_crtc->cursor.height, yres -</div><div>-<span style="white-space:pre">                     </span>mdp5_crtc->cursor.y);</div><div>+<span style="white-space:pre">     </span>if (mdp5_crtc->cursor.x >= 0)</div><div>+<span style="white-space:pre">  </span>        *roi_w = min(mdp5_crtc->cursor.width, xres -</div><div>+<span style="white-space:pre">                  </span>        mdp5_crtc->cursor.x);</div><div>+<span style="white-space:pre"> </span>else</div><div>+<span style="white-space:pre"> </span>        *roi_w = mdp5_crtc->cursor.width - abs(mdp5_crtc->cursor.x);</div><div>+<span style="white-space:pre">       </span>if (mdp5_crtc->cursor.y >= 0)</div><div>+<span style="white-space:pre">  </span>        *roi_h = min(mdp5_crtc->cursor.height, yres -</div><div>+<span style="white-space:pre">                 </span>        mdp5_crtc->cursor.y);</div><div>+<span style="white-space:pre"> </span>else</div><div>+<span style="white-space:pre"> </span>        *roi_h = mdp5_crtc->cursor.height - abs(mdp5_crtc->cursor.y);</div><div> }</div><div> </div><div> static void mdp5_crtc_restore_cursor(struct drm_crtc *crtc)</div><div>@@ -769,7 +775,7 @@ static void mdp5_crtc_restore_cursor(str</div><div> <span style="white-space:pre">   </span>struct mdp5_kms *mdp5_kms = get_kms(crtc);</div><div> <span style="white-space:pre">  </span>const enum mdp5_cursor_alpha cur_alpha = CURSOR_ALPHA_PER_PIXEL;</div><div> <span style="white-space:pre">    </span>uint32_t blendcfg, stride;</div><div>-<span style="white-space:pre">   </span>uint32_t x, y, width, height;</div><div>+<span style="white-space:pre">        </span>uint32_t x, y, src_x, src_y, width, height;</div><div> <span style="white-space:pre"> </span>uint32_t roi_w, roi_h;</div><div> <span style="white-space:pre">      </span>int lm;</div><div> </div><div>@@ -786,6 +792,20 @@ static void mdp5_crtc_restore_cursor(str</div><div> </div><div> <span style="white-space:pre">       </span>get_roi(crtc, &roi_w, &roi_h);</div><div> </div><div>+        if (mdp5_crtc->cursor.x < 0) {</div><div>+                src_x = abs(mdp5_crtc->cursor.x);</div><div>+                x = 0;</div><div>+         } else</div><div>+                src_x = 0;</div><div>+</div><div>+        if (mdp5_crtc->cursor.y < 0) {</div><div>+                src_y = abs(mdp5_crtc->cursor.y);</div><div>+                y = 0;</div><div>+        } else</div><div>+                src_y = 0;</div><div>+</div><div>+<span style="white-space:pre">        </span>//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);</div><div>+</div><div> <span style="white-space:pre">   </span>mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_STRIDE(lm), stride);</div><div> <span style="white-space:pre">        </span>mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_FORMAT(lm),</div><div> <span style="white-space:pre">                 </span>MDP5_LM_CURSOR_FORMAT_FORMAT(CURSOR_FMT_ARGB8888));</div><div>@@ -798,6 +818,9 @@ static void mdp5_crtc_restore_cursor(str</div><div> <span style="white-space:pre">      </span>mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_START_XY(lm),</div><div> <span style="white-space:pre">                       </span>MDP5_LM_CURSOR_START_XY_Y_START(y) |</div><div> <span style="white-space:pre">                        </span>MDP5_LM_CURSOR_START_XY_X_START(x));</div><div>+<span style="white-space:pre"> </span>mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_XY(lm),</div><div>+<span style="white-space:pre">                      </span>MDP5_LM_CURSOR_XY_SRC_Y(src_y) |</div><div>+<span style="white-space:pre">                     </span>MDP5_LM_CURSOR_XY_SRC_X(src_x));</div><div> <span style="white-space:pre">    </span>mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_BASE_ADDR(lm),</div><div> <span style="white-space:pre">                      </span>mdp5_crtc->cursor.iova);</div><div> </div><div>@@ -903,6 +926,8 @@ static int mdp5_crtc_cursor_move(struct</div><div> <span style="white-space:pre">      </span>uint32_t roi_w;</div><div> <span style="white-space:pre">     </span>uint32_t roi_h;</div><div> <span style="white-space:pre">     </span>unsigned long flags;</div><div>+<span style="white-space:pre"> </span>int border_x = mdp5_crtc->cursor.width * (-1);</div><div>+<span style="white-space:pre">    </span>int border_y = mdp5_crtc->cursor.height * (-1);</div><div> </div><div> <span style="white-space:pre"> </span>if (!mdp5_crtc->lm_cursor_enabled) {</div><div> <span style="white-space:pre">             </span>dev_warn(dev->dev,</div><div>@@ -918,8 +943,8 @@ static int mdp5_crtc_cursor_move(struct</div><div> <span style="white-space:pre">     </span>if (unlikely(!crtc->state->enable))</div><div> <span style="white-space:pre">           </span>return 0;</div><div> </div><div>-<span style="white-space:pre">   </span>mdp5_crtc->cursor.x = x = max(x, 0);</div><div>-<span style="white-space:pre">      </span>mdp5_crtc->cursor.y = y = max(y, 0);</div><div>+<span style="white-space:pre">      </span>mdp5_crtc->cursor.x = x = max(x, border_x);</div><div>+<span style="white-space:pre">       </span>mdp5_crtc->cursor.y = y = max(y, border_y);</div><div> </div><div> <span style="white-space:pre">     </span>get_roi(crtc, &roi_w, &roi_h);</div><div> </div></div><div>Best regards</div><div>-Carsten</div></div><div class="gmail_extra"><br><div class="gmail_quote">2018-07-10 12:11 GMT+02:00 Carsten Behling <span dir="ltr"><<a href="mailto:carsten.behling@googlemail.com" target="_blank">carsten.behling@googlemail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi,<div><br></div><div>modesetting X11 driver may provide negative x/y cordinates in mdp5_crtc_cursor_move(...) call when rotation is enabled.</div><div><br></div><div>Because of</div><div><br></div><div>static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)<br></div><div>{</div><div>...</div><div><div><span style="white-space:pre-wrap">        </span>mdp5_crtc->cursor.x = x = max(x, 0);</div><div><span style="white-space:pre-wrap">  </span>mdp5_crtc->cursor.y = y = max(y, 0);</div></div><div>...</div><div>}</div><div><br></div><div>x/y is calmped to 0/0 in those cases resulting that the cursor does not move anymore beyond mdp5_crtc->cursor.width, mdp5_<wbr>crtc->cursor.height.</div><div><br></div><div>For e.g rotation of 180 degree that means that the upper left cursor point stays never reaches the region (0/0) to  (<span style="font-size:small;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">mdp5_crtc->cursor.width/<wbr>mdp5_crtc->cursor.height).</span></div><div><span style="font-size:small;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><br></span></div><div><span style="font-size:small;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">I already asked the X men if this should be fixed in modesetting driver or in the kernel CRT</span></div><div><span style="font-size:small;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">functions:</span></div><div><span style="font-size:small;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><br></span></div><div><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><a href="https://www.spinics.net/lists/xorg/msg58969.html" target="_blank">https://www.spinics.net/lists/<wbr>xorg/msg58969.html</a><br></span></div><div><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><br></span></div><div><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">They told me to fix this in the kernel.</span></div><div><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><br></span></div><div><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">So, I suppose:</span></div><div><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><br></span></div><div><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">1.) cursor x should be rather clamped instead to</span></div><div><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><br></span></div>static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
{ <div><span style="white-space:pre-wrap">...</span></div><div><span style="white-space:pre-wrap">     </span>mdp5_crtc->cursor.x = x = max(x, -mdp5_crtc->cursor.width);</div><div><span style="white-space:pre-wrap">        </span>mdp5_crtc->cursor.y = y = max(y, -mdp5_crtc->cursor.height);</div><div>...</div><div>}</div><div><br></div><div><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"> 2.) The ROI calculation must be extendet to:</span></div><div><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><br></span></div><div><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><div>static void get_roi(struct drm_crtc *crtc, uint32_t *roi_w, uint32_t *roi_h)</div><div>{</div><div>...</div><div><div><span style="white-space:pre-wrap">       </span>if (x>=0)</div><div><span style="white-space:pre-wrap">     </span>        *roi_w = min(mdp5_crtc->cursor.width, xres -</div><div><span style="white-space:pre-wrap">                      </span>        mdp5_crtc->cursor.x);</div><div><span style="white-space:pre-wrap">     </span>else</div><div><span style="white-space:pre-wrap">     </span>        *roi_w = mdp5_crtc->cursor.width - abs(mdp5_crtc->cursor.x);</div><div><span style="white-space:pre-wrap">   </span>if (y>=0)</div><div><span style="white-space:pre-wrap">     </span>        *roi_h = min(mdp5_crtc->cursor.height, yres -</div><div><span style="white-space:pre-wrap">                     </span>        mdp5_crtc->cursor.y);</div><div><span style="white-space:pre-wrap">     </span>else</div><div><span style="white-space:pre-wrap">     </span>        *roi_h = mdp5_crtc->cursor.height - abs(mdp5_crtc->cursor.y);</div></div><div>...</div><div>}</div><div><br></div><div>3.) There has to be some kind of hotspot setup in mdp5_crtc_restore_cursor(..<wbr>.)</div><div><br></div><div>Since I have no MDP5 documentation, I don't know how to setup the hotspot and I can't</div><div>implement 3.)</div><div><br></div><div>Please help!</div><div><br></div><div>Best regards</div><span class="HOEnZb"><font color="#888888"><div>-Carsten</div></font></span></span></div></div>
</blockquote></div><br></div>