1771fe6b9SJerome Glisse /* 2771fe6b9SJerome Glisse * Copyright 2007-8 Advanced Micro Devices, Inc. 3771fe6b9SJerome Glisse * Copyright 2008 Red Hat Inc. 4771fe6b9SJerome Glisse * 5771fe6b9SJerome Glisse * Permission is hereby granted, free of charge, to any person obtaining a 6771fe6b9SJerome Glisse * copy of this software and associated documentation files (the "Software"), 7771fe6b9SJerome Glisse * to deal in the Software without restriction, including without limitation 8771fe6b9SJerome Glisse * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9771fe6b9SJerome Glisse * and/or sell copies of the Software, and to permit persons to whom the 10771fe6b9SJerome Glisse * Software is furnished to do so, subject to the following conditions: 11771fe6b9SJerome Glisse * 12771fe6b9SJerome Glisse * The above copyright notice and this permission notice shall be included in 13771fe6b9SJerome Glisse * all copies or substantial portions of the Software. 14771fe6b9SJerome Glisse * 15771fe6b9SJerome Glisse * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16771fe6b9SJerome Glisse * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17771fe6b9SJerome Glisse * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18771fe6b9SJerome Glisse * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 19771fe6b9SJerome Glisse * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 20771fe6b9SJerome Glisse * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 21771fe6b9SJerome Glisse * OTHER DEALINGS IN THE SOFTWARE. 22771fe6b9SJerome Glisse * 23771fe6b9SJerome Glisse * Authors: Dave Airlie 24771fe6b9SJerome Glisse * Alex Deucher 25771fe6b9SJerome Glisse */ 26760285e7SDavid Howells #include <drm/drmP.h> 27760285e7SDavid Howells #include <drm/radeon_drm.h> 28771fe6b9SJerome Glisse #include "radeon.h" 29771fe6b9SJerome Glisse 30771fe6b9SJerome Glisse static void radeon_lock_cursor(struct drm_crtc *crtc, bool lock) 31771fe6b9SJerome Glisse { 32771fe6b9SJerome Glisse struct radeon_device *rdev = crtc->dev->dev_private; 33771fe6b9SJerome Glisse struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 34771fe6b9SJerome Glisse uint32_t cur_lock; 35771fe6b9SJerome Glisse 36bcc1c2a1SAlex Deucher if (ASIC_IS_DCE4(rdev)) { 37bcc1c2a1SAlex Deucher cur_lock = RREG32(EVERGREEN_CUR_UPDATE + radeon_crtc->crtc_offset); 38bcc1c2a1SAlex Deucher if (lock) 39bcc1c2a1SAlex Deucher cur_lock |= EVERGREEN_CURSOR_UPDATE_LOCK; 40bcc1c2a1SAlex Deucher else 41bcc1c2a1SAlex Deucher cur_lock &= ~EVERGREEN_CURSOR_UPDATE_LOCK; 42bcc1c2a1SAlex Deucher WREG32(EVERGREEN_CUR_UPDATE + radeon_crtc->crtc_offset, cur_lock); 43bcc1c2a1SAlex Deucher } else if (ASIC_IS_AVIVO(rdev)) { 44771fe6b9SJerome Glisse cur_lock = RREG32(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset); 45771fe6b9SJerome Glisse if (lock) 46771fe6b9SJerome Glisse cur_lock |= AVIVO_D1CURSOR_UPDATE_LOCK; 47771fe6b9SJerome Glisse else 48771fe6b9SJerome Glisse cur_lock &= ~AVIVO_D1CURSOR_UPDATE_LOCK; 49771fe6b9SJerome Glisse WREG32(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset, cur_lock); 50771fe6b9SJerome Glisse } else { 51771fe6b9SJerome Glisse cur_lock = RREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset); 52771fe6b9SJerome Glisse if (lock) 53771fe6b9SJerome Glisse cur_lock |= RADEON_CUR_LOCK; 54771fe6b9SJerome Glisse else 55771fe6b9SJerome Glisse cur_lock &= ~RADEON_CUR_LOCK; 56771fe6b9SJerome Glisse WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, cur_lock); 57771fe6b9SJerome Glisse } 58771fe6b9SJerome Glisse } 59771fe6b9SJerome Glisse 60771fe6b9SJerome Glisse static void radeon_hide_cursor(struct drm_crtc *crtc) 61771fe6b9SJerome Glisse { 62771fe6b9SJerome Glisse struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 63771fe6b9SJerome Glisse struct radeon_device *rdev = crtc->dev->dev_private; 64771fe6b9SJerome Glisse 65bcc1c2a1SAlex Deucher if (ASIC_IS_DCE4(rdev)) { 662ef9bdfeSDaniel Vetter WREG32_IDX(EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset, 672ef9bdfeSDaniel Vetter EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT) | 68f4254a2bSAlex Deucher EVERGREEN_CURSOR_URGENT_CONTROL(EVERGREEN_CURSOR_URGENT_1_2)); 69bcc1c2a1SAlex Deucher } else if (ASIC_IS_AVIVO(rdev)) { 702ef9bdfeSDaniel Vetter WREG32_IDX(AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset, 712ef9bdfeSDaniel Vetter (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT)); 72771fe6b9SJerome Glisse } else { 732ef9bdfeSDaniel Vetter u32 reg; 74771fe6b9SJerome Glisse switch (radeon_crtc->crtc_id) { 75771fe6b9SJerome Glisse case 0: 762ef9bdfeSDaniel Vetter reg = RADEON_CRTC_GEN_CNTL; 77771fe6b9SJerome Glisse break; 78771fe6b9SJerome Glisse case 1: 792ef9bdfeSDaniel Vetter reg = RADEON_CRTC2_GEN_CNTL; 80771fe6b9SJerome Glisse break; 81771fe6b9SJerome Glisse default: 82771fe6b9SJerome Glisse return; 83771fe6b9SJerome Glisse } 842ef9bdfeSDaniel Vetter WREG32_IDX(reg, RREG32_IDX(reg) & ~RADEON_CRTC_CUR_EN); 85771fe6b9SJerome Glisse } 86771fe6b9SJerome Glisse } 87771fe6b9SJerome Glisse 88771fe6b9SJerome Glisse static void radeon_show_cursor(struct drm_crtc *crtc) 89771fe6b9SJerome Glisse { 90771fe6b9SJerome Glisse struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 91771fe6b9SJerome Glisse struct radeon_device *rdev = crtc->dev->dev_private; 92771fe6b9SJerome Glisse 93bcc1c2a1SAlex Deucher if (ASIC_IS_DCE4(rdev)) { 948991668aSMichel Dänzer WREG32(EVERGREEN_CUR_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, 958991668aSMichel Dänzer upper_32_bits(radeon_crtc->cursor_addr)); 968991668aSMichel Dänzer WREG32(EVERGREEN_CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, 978991668aSMichel Dänzer lower_32_bits(radeon_crtc->cursor_addr)); 98bcc1c2a1SAlex Deucher WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); 99bcc1c2a1SAlex Deucher WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_EN | 100f4254a2bSAlex Deucher EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT) | 101f4254a2bSAlex Deucher EVERGREEN_CURSOR_URGENT_CONTROL(EVERGREEN_CURSOR_URGENT_1_2)); 102bcc1c2a1SAlex Deucher } else if (ASIC_IS_AVIVO(rdev)) { 1038991668aSMichel Dänzer if (rdev->family >= CHIP_RV770) { 1048991668aSMichel Dänzer if (radeon_crtc->crtc_id) 1058991668aSMichel Dänzer WREG32(R700_D2CUR_SURFACE_ADDRESS_HIGH, 1068991668aSMichel Dänzer upper_32_bits(radeon_crtc->cursor_addr)); 1078991668aSMichel Dänzer else 1088991668aSMichel Dänzer WREG32(R700_D1CUR_SURFACE_ADDRESS_HIGH, 1098991668aSMichel Dänzer upper_32_bits(radeon_crtc->cursor_addr)); 1108991668aSMichel Dänzer } 1118991668aSMichel Dänzer 1128991668aSMichel Dänzer WREG32(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, 1138991668aSMichel Dänzer lower_32_bits(radeon_crtc->cursor_addr)); 114771fe6b9SJerome Glisse WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); 115771fe6b9SJerome Glisse WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN | 116771fe6b9SJerome Glisse (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT)); 117771fe6b9SJerome Glisse } else { 1188991668aSMichel Dänzer /* offset is from DISP(2)_BASE_ADDRESS */ 1198991668aSMichel Dänzer WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, 1208991668aSMichel Dänzer radeon_crtc->cursor_addr - radeon_crtc->legacy_display_base_addr); 1218991668aSMichel Dänzer 122771fe6b9SJerome Glisse switch (radeon_crtc->crtc_id) { 123771fe6b9SJerome Glisse case 0: 124771fe6b9SJerome Glisse WREG32(RADEON_MM_INDEX, RADEON_CRTC_GEN_CNTL); 125771fe6b9SJerome Glisse break; 126771fe6b9SJerome Glisse case 1: 127771fe6b9SJerome Glisse WREG32(RADEON_MM_INDEX, RADEON_CRTC2_GEN_CNTL); 128771fe6b9SJerome Glisse break; 129771fe6b9SJerome Glisse default: 130771fe6b9SJerome Glisse return; 131771fe6b9SJerome Glisse } 132771fe6b9SJerome Glisse 133771fe6b9SJerome Glisse WREG32_P(RADEON_MM_DATA, (RADEON_CRTC_CUR_EN | 134771fe6b9SJerome Glisse (RADEON_CRTC_CUR_MODE_24BPP << RADEON_CRTC_CUR_MODE_SHIFT)), 135771fe6b9SJerome Glisse ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_CUR_MODE_MASK)); 136771fe6b9SJerome Glisse } 137771fe6b9SJerome Glisse } 138771fe6b9SJerome Glisse 1393feba08dSMichel Dänzer static int radeon_cursor_move_locked(struct drm_crtc *crtc, int x, int y) 1403feba08dSMichel Dänzer { 1413feba08dSMichel Dänzer struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 1423feba08dSMichel Dänzer struct radeon_device *rdev = crtc->dev->dev_private; 1433feba08dSMichel Dänzer int xorigin = 0, yorigin = 0; 1443feba08dSMichel Dänzer int w = radeon_crtc->cursor_width; 1453feba08dSMichel Dänzer 1463feba08dSMichel Dänzer if (ASIC_IS_AVIVO(rdev)) { 1473feba08dSMichel Dänzer /* avivo cursor are offset into the total surface */ 1483feba08dSMichel Dänzer x += crtc->x; 1493feba08dSMichel Dänzer y += crtc->y; 1503feba08dSMichel Dänzer } 1513feba08dSMichel Dänzer DRM_DEBUG("x %d y %d c->x %d c->y %d\n", x, y, crtc->x, crtc->y); 1523feba08dSMichel Dänzer 1533feba08dSMichel Dänzer if (x < 0) { 1543feba08dSMichel Dänzer xorigin = min(-x, radeon_crtc->max_cursor_width - 1); 1553feba08dSMichel Dänzer x = 0; 1563feba08dSMichel Dänzer } 1573feba08dSMichel Dänzer if (y < 0) { 1583feba08dSMichel Dänzer yorigin = min(-y, radeon_crtc->max_cursor_height - 1); 1593feba08dSMichel Dänzer y = 0; 1603feba08dSMichel Dänzer } 1613feba08dSMichel Dänzer 1623feba08dSMichel Dänzer /* fixed on DCE6 and newer */ 1633feba08dSMichel Dänzer if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE6(rdev)) { 1643feba08dSMichel Dänzer int i = 0; 1653feba08dSMichel Dänzer struct drm_crtc *crtc_p; 1663feba08dSMichel Dänzer 1673feba08dSMichel Dänzer /* 1683feba08dSMichel Dänzer * avivo cursor image can't end on 128 pixel boundary or 1693feba08dSMichel Dänzer * go past the end of the frame if both crtcs are enabled 1703feba08dSMichel Dänzer * 1713feba08dSMichel Dänzer * NOTE: It is safe to access crtc->enabled of other crtcs 1723feba08dSMichel Dänzer * without holding either the mode_config lock or the other 1733feba08dSMichel Dänzer * crtc's lock as long as write access to this flag _always_ 1743feba08dSMichel Dänzer * grabs all locks. 1753feba08dSMichel Dänzer */ 1763feba08dSMichel Dänzer list_for_each_entry(crtc_p, &crtc->dev->mode_config.crtc_list, head) { 1773feba08dSMichel Dänzer if (crtc_p->enabled) 1783feba08dSMichel Dänzer i++; 1793feba08dSMichel Dänzer } 1803feba08dSMichel Dänzer if (i > 1) { 1813feba08dSMichel Dänzer int cursor_end, frame_end; 1823feba08dSMichel Dänzer 1833feba08dSMichel Dänzer cursor_end = x - xorigin + w; 1843feba08dSMichel Dänzer frame_end = crtc->x + crtc->mode.crtc_hdisplay; 1853feba08dSMichel Dänzer if (cursor_end >= frame_end) { 1863feba08dSMichel Dänzer w = w - (cursor_end - frame_end); 1873feba08dSMichel Dänzer if (!(frame_end & 0x7f)) 1883feba08dSMichel Dänzer w--; 1893feba08dSMichel Dänzer } else { 1903feba08dSMichel Dänzer if (!(cursor_end & 0x7f)) 1913feba08dSMichel Dänzer w--; 1923feba08dSMichel Dänzer } 1933feba08dSMichel Dänzer if (w <= 0) { 1943feba08dSMichel Dänzer w = 1; 1953feba08dSMichel Dänzer cursor_end = x - xorigin + w; 1963feba08dSMichel Dänzer if (!(cursor_end & 0x7f)) { 1973feba08dSMichel Dänzer x--; 1983feba08dSMichel Dänzer WARN_ON_ONCE(x < 0); 1993feba08dSMichel Dänzer } 2003feba08dSMichel Dänzer } 2013feba08dSMichel Dänzer } 2023feba08dSMichel Dänzer } 2033feba08dSMichel Dänzer 2043feba08dSMichel Dänzer if (ASIC_IS_DCE4(rdev)) { 2053feba08dSMichel Dänzer WREG32(EVERGREEN_CUR_POSITION + radeon_crtc->crtc_offset, (x << 16) | y); 2063feba08dSMichel Dänzer WREG32(EVERGREEN_CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin); 2073feba08dSMichel Dänzer WREG32(EVERGREEN_CUR_SIZE + radeon_crtc->crtc_offset, 2083feba08dSMichel Dänzer ((w - 1) << 16) | (radeon_crtc->cursor_height - 1)); 2093feba08dSMichel Dänzer } else if (ASIC_IS_AVIVO(rdev)) { 2103feba08dSMichel Dänzer WREG32(AVIVO_D1CUR_POSITION + radeon_crtc->crtc_offset, (x << 16) | y); 2113feba08dSMichel Dänzer WREG32(AVIVO_D1CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin); 2123feba08dSMichel Dänzer WREG32(AVIVO_D1CUR_SIZE + radeon_crtc->crtc_offset, 2133feba08dSMichel Dänzer ((w - 1) << 16) | (radeon_crtc->cursor_height - 1)); 2143feba08dSMichel Dänzer } else { 2153feba08dSMichel Dänzer if (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN) 2163feba08dSMichel Dänzer y *= 2; 2173feba08dSMichel Dänzer 2183feba08dSMichel Dänzer WREG32(RADEON_CUR_HORZ_VERT_OFF + radeon_crtc->crtc_offset, 2193feba08dSMichel Dänzer (RADEON_CUR_LOCK 2203feba08dSMichel Dänzer | (xorigin << 16) 2213feba08dSMichel Dänzer | yorigin)); 2223feba08dSMichel Dänzer WREG32(RADEON_CUR_HORZ_VERT_POSN + radeon_crtc->crtc_offset, 2233feba08dSMichel Dänzer (RADEON_CUR_LOCK 2243feba08dSMichel Dänzer | (x << 16) 2253feba08dSMichel Dänzer | y)); 2263feba08dSMichel Dänzer /* offset is from DISP(2)_BASE_ADDRESS */ 227cd404af0SMichel Dänzer WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, 228cd404af0SMichel Dänzer radeon_crtc->cursor_addr - radeon_crtc->legacy_display_base_addr + 229cd404af0SMichel Dänzer yorigin * 256); 2303feba08dSMichel Dänzer } 2313feba08dSMichel Dänzer 2323feba08dSMichel Dänzer radeon_crtc->cursor_x = x; 2333feba08dSMichel Dänzer radeon_crtc->cursor_y = y; 2343feba08dSMichel Dänzer 2353feba08dSMichel Dänzer return 0; 2363feba08dSMichel Dänzer } 2373feba08dSMichel Dänzer 2383feba08dSMichel Dänzer int radeon_crtc_cursor_move(struct drm_crtc *crtc, 2393feba08dSMichel Dänzer int x, int y) 2403feba08dSMichel Dänzer { 2413feba08dSMichel Dänzer int ret; 2423feba08dSMichel Dänzer 2433feba08dSMichel Dänzer radeon_lock_cursor(crtc, true); 2443feba08dSMichel Dänzer ret = radeon_cursor_move_locked(crtc, x, y); 2453feba08dSMichel Dänzer radeon_lock_cursor(crtc, false); 2463feba08dSMichel Dänzer 2473feba08dSMichel Dänzer return ret; 2483feba08dSMichel Dänzer } 24978b1a601SMichel Dänzer 25078b1a601SMichel Dänzer int radeon_crtc_cursor_set2(struct drm_crtc *crtc, 251771fe6b9SJerome Glisse struct drm_file *file_priv, 252771fe6b9SJerome Glisse uint32_t handle, 253771fe6b9SJerome Glisse uint32_t width, 25478b1a601SMichel Dänzer uint32_t height, 25578b1a601SMichel Dänzer int32_t hot_x, 25678b1a601SMichel Dänzer int32_t hot_y) 257771fe6b9SJerome Glisse { 258771fe6b9SJerome Glisse struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 259cd404af0SMichel Dänzer struct radeon_device *rdev = crtc->dev->dev_private; 260771fe6b9SJerome Glisse struct drm_gem_object *obj; 261cd404af0SMichel Dänzer struct radeon_bo *robj; 262771fe6b9SJerome Glisse int ret; 263771fe6b9SJerome Glisse 264771fe6b9SJerome Glisse if (!handle) { 265771fe6b9SJerome Glisse /* turn off cursor */ 266771fe6b9SJerome Glisse radeon_hide_cursor(crtc); 267771fe6b9SJerome Glisse obj = NULL; 268771fe6b9SJerome Glisse goto unpin; 269771fe6b9SJerome Glisse } 270771fe6b9SJerome Glisse 2719e05fa1dSAlex Deucher if ((width > radeon_crtc->max_cursor_width) || 2729e05fa1dSAlex Deucher (height > radeon_crtc->max_cursor_height)) { 273771fe6b9SJerome Glisse DRM_ERROR("bad cursor width or height %d x %d\n", width, height); 274771fe6b9SJerome Glisse return -EINVAL; 275771fe6b9SJerome Glisse } 276771fe6b9SJerome Glisse 277*a8ad0bd8SChris Wilson obj = drm_gem_object_lookup(file_priv, handle); 278771fe6b9SJerome Glisse if (!obj) { 279771fe6b9SJerome Glisse DRM_ERROR("Cannot find cursor object %x for crtc %d\n", handle, radeon_crtc->crtc_id); 280bf79cb91SChris Wilson return -ENOENT; 281771fe6b9SJerome Glisse } 282771fe6b9SJerome Glisse 283cd404af0SMichel Dänzer robj = gem_to_radeon_bo(obj); 284cd404af0SMichel Dänzer ret = radeon_bo_reserve(robj, false); 285cd404af0SMichel Dänzer if (ret != 0) { 286cd404af0SMichel Dänzer drm_gem_object_unreference_unlocked(obj); 287cd404af0SMichel Dänzer return ret; 288cd404af0SMichel Dänzer } 289cd404af0SMichel Dänzer /* Only 27 bit offset for legacy cursor */ 290cd404af0SMichel Dänzer ret = radeon_bo_pin_restricted(robj, RADEON_GEM_DOMAIN_VRAM, 291cd404af0SMichel Dänzer ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27, 292cd404af0SMichel Dänzer &radeon_crtc->cursor_addr); 293cd404af0SMichel Dänzer radeon_bo_unreserve(robj); 294cd404af0SMichel Dänzer if (ret) { 295cd404af0SMichel Dänzer DRM_ERROR("Failed to pin new cursor BO (%d)\n", ret); 296cd404af0SMichel Dänzer drm_gem_object_unreference_unlocked(obj); 297cd404af0SMichel Dänzer return ret; 298cd404af0SMichel Dänzer } 299cd404af0SMichel Dänzer 30045e5f6a2SIlija Hadzic radeon_crtc->cursor_width = width; 30145e5f6a2SIlija Hadzic radeon_crtc->cursor_height = height; 30245e5f6a2SIlija Hadzic 303771fe6b9SJerome Glisse radeon_lock_cursor(crtc, true); 3042e007e61SMichel Dänzer 3052e007e61SMichel Dänzer if (hot_x != radeon_crtc->cursor_hot_x || 3062e007e61SMichel Dänzer hot_y != radeon_crtc->cursor_hot_y) { 3072e007e61SMichel Dänzer int x, y; 3082e007e61SMichel Dänzer 3092e007e61SMichel Dänzer x = radeon_crtc->cursor_x + radeon_crtc->cursor_hot_x - hot_x; 3102e007e61SMichel Dänzer y = radeon_crtc->cursor_y + radeon_crtc->cursor_hot_y - hot_y; 3112e007e61SMichel Dänzer 3122e007e61SMichel Dänzer radeon_cursor_move_locked(crtc, x, y); 3132e007e61SMichel Dänzer 3142e007e61SMichel Dänzer radeon_crtc->cursor_hot_x = hot_x; 3152e007e61SMichel Dänzer radeon_crtc->cursor_hot_y = hot_y; 3162e007e61SMichel Dänzer } 3172e007e61SMichel Dänzer 318771fe6b9SJerome Glisse radeon_show_cursor(crtc); 3196d3759faSMichel Dänzer 320771fe6b9SJerome Glisse radeon_lock_cursor(crtc, false); 321771fe6b9SJerome Glisse 322771fe6b9SJerome Glisse unpin: 323771fe6b9SJerome Glisse if (radeon_crtc->cursor_bo) { 3246d3759faSMichel Dänzer struct radeon_bo *robj = gem_to_radeon_bo(radeon_crtc->cursor_bo); 325654c59cfSMichel Dänzer ret = radeon_bo_reserve(robj, false); 326654c59cfSMichel Dänzer if (likely(ret == 0)) { 327654c59cfSMichel Dänzer radeon_bo_unpin(robj); 328654c59cfSMichel Dänzer radeon_bo_unreserve(robj); 329654c59cfSMichel Dänzer } 330bc9025bdSLuca Barbieri drm_gem_object_unreference_unlocked(radeon_crtc->cursor_bo); 331771fe6b9SJerome Glisse } 332771fe6b9SJerome Glisse 333771fe6b9SJerome Glisse radeon_crtc->cursor_bo = obj; 334771fe6b9SJerome Glisse return 0; 3356d3759faSMichel Dänzer } 336771fe6b9SJerome Glisse 3376d3759faSMichel Dänzer /** 3386d3759faSMichel Dänzer * radeon_cursor_reset - Re-set the current cursor, if any. 3396d3759faSMichel Dänzer * 3406d3759faSMichel Dänzer * @crtc: drm crtc 3416d3759faSMichel Dänzer * 3426d3759faSMichel Dänzer * If the CRTC passed in currently has a cursor assigned, this function 3436d3759faSMichel Dänzer * makes sure it's visible. 3446d3759faSMichel Dänzer */ 3456d3759faSMichel Dänzer void radeon_cursor_reset(struct drm_crtc *crtc) 3466d3759faSMichel Dänzer { 3476d3759faSMichel Dänzer struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 3486d3759faSMichel Dänzer 3496d3759faSMichel Dänzer if (radeon_crtc->cursor_bo) { 3506d3759faSMichel Dänzer radeon_lock_cursor(crtc, true); 3516d3759faSMichel Dänzer 3526d3759faSMichel Dänzer radeon_cursor_move_locked(crtc, radeon_crtc->cursor_x, 3536d3759faSMichel Dänzer radeon_crtc->cursor_y); 3546d3759faSMichel Dänzer 3556d3759faSMichel Dänzer radeon_show_cursor(crtc); 3566d3759faSMichel Dänzer 3576d3759faSMichel Dänzer radeon_lock_cursor(crtc, false); 3586d3759faSMichel Dänzer } 359771fe6b9SJerome Glisse } 360