xref: /linux/drivers/gpu/drm/radeon/radeon_cursor.c (revision 654c59cf76a220866d1f74ab169bf469940c2d70)
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  */
26771fe6b9SJerome Glisse #include "drmP.h"
27771fe6b9SJerome Glisse #include "radeon_drm.h"
28771fe6b9SJerome Glisse #include "radeon.h"
29771fe6b9SJerome Glisse 
30771fe6b9SJerome Glisse #define CURSOR_WIDTH 64
31771fe6b9SJerome Glisse #define CURSOR_HEIGHT 64
32771fe6b9SJerome Glisse 
33771fe6b9SJerome Glisse static void radeon_lock_cursor(struct drm_crtc *crtc, bool lock)
34771fe6b9SJerome Glisse {
35771fe6b9SJerome Glisse 	struct radeon_device *rdev = crtc->dev->dev_private;
36771fe6b9SJerome Glisse 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
37771fe6b9SJerome Glisse 	uint32_t cur_lock;
38771fe6b9SJerome Glisse 
39bcc1c2a1SAlex Deucher 	if (ASIC_IS_DCE4(rdev)) {
40bcc1c2a1SAlex Deucher 		cur_lock = RREG32(EVERGREEN_CUR_UPDATE + radeon_crtc->crtc_offset);
41bcc1c2a1SAlex Deucher 		if (lock)
42bcc1c2a1SAlex Deucher 			cur_lock |= EVERGREEN_CURSOR_UPDATE_LOCK;
43bcc1c2a1SAlex Deucher 		else
44bcc1c2a1SAlex Deucher 			cur_lock &= ~EVERGREEN_CURSOR_UPDATE_LOCK;
45bcc1c2a1SAlex Deucher 		WREG32(EVERGREEN_CUR_UPDATE + radeon_crtc->crtc_offset, cur_lock);
46bcc1c2a1SAlex Deucher 	} else if (ASIC_IS_AVIVO(rdev)) {
47771fe6b9SJerome Glisse 		cur_lock = RREG32(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset);
48771fe6b9SJerome Glisse 		if (lock)
49771fe6b9SJerome Glisse 			cur_lock |= AVIVO_D1CURSOR_UPDATE_LOCK;
50771fe6b9SJerome Glisse 		else
51771fe6b9SJerome Glisse 			cur_lock &= ~AVIVO_D1CURSOR_UPDATE_LOCK;
52771fe6b9SJerome Glisse 		WREG32(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset, cur_lock);
53771fe6b9SJerome Glisse 	} else {
54771fe6b9SJerome Glisse 		cur_lock = RREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset);
55771fe6b9SJerome Glisse 		if (lock)
56771fe6b9SJerome Glisse 			cur_lock |= RADEON_CUR_LOCK;
57771fe6b9SJerome Glisse 		else
58771fe6b9SJerome Glisse 			cur_lock &= ~RADEON_CUR_LOCK;
59771fe6b9SJerome Glisse 		WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, cur_lock);
60771fe6b9SJerome Glisse 	}
61771fe6b9SJerome Glisse }
62771fe6b9SJerome Glisse 
63771fe6b9SJerome Glisse static void radeon_hide_cursor(struct drm_crtc *crtc)
64771fe6b9SJerome Glisse {
65771fe6b9SJerome Glisse 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
66771fe6b9SJerome Glisse 	struct radeon_device *rdev = crtc->dev->dev_private;
67771fe6b9SJerome Glisse 
68bcc1c2a1SAlex Deucher 	if (ASIC_IS_DCE4(rdev)) {
69bcc1c2a1SAlex Deucher 		WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset);
70bcc1c2a1SAlex Deucher 		WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT));
71bcc1c2a1SAlex Deucher 	} else if (ASIC_IS_AVIVO(rdev)) {
72771fe6b9SJerome Glisse 		WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset);
73771fe6b9SJerome Glisse 		WREG32(RADEON_MM_DATA, (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT));
74771fe6b9SJerome Glisse 	} else {
75771fe6b9SJerome Glisse 		switch (radeon_crtc->crtc_id) {
76771fe6b9SJerome Glisse 		case 0:
77771fe6b9SJerome Glisse 			WREG32(RADEON_MM_INDEX, RADEON_CRTC_GEN_CNTL);
78771fe6b9SJerome Glisse 			break;
79771fe6b9SJerome Glisse 		case 1:
80771fe6b9SJerome Glisse 			WREG32(RADEON_MM_INDEX, RADEON_CRTC2_GEN_CNTL);
81771fe6b9SJerome Glisse 			break;
82771fe6b9SJerome Glisse 		default:
83771fe6b9SJerome Glisse 			return;
84771fe6b9SJerome Glisse 		}
85771fe6b9SJerome Glisse 		WREG32_P(RADEON_MM_DATA, 0, ~RADEON_CRTC_CUR_EN);
86771fe6b9SJerome Glisse 	}
87771fe6b9SJerome Glisse }
88771fe6b9SJerome Glisse 
89771fe6b9SJerome Glisse static void radeon_show_cursor(struct drm_crtc *crtc)
90771fe6b9SJerome Glisse {
91771fe6b9SJerome Glisse 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
92771fe6b9SJerome Glisse 	struct radeon_device *rdev = crtc->dev->dev_private;
93771fe6b9SJerome Glisse 
94bcc1c2a1SAlex Deucher 	if (ASIC_IS_DCE4(rdev)) {
95bcc1c2a1SAlex Deucher 		WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset);
96bcc1c2a1SAlex Deucher 		WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_EN |
97bcc1c2a1SAlex Deucher 		       EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT));
98bcc1c2a1SAlex Deucher 	} else if (ASIC_IS_AVIVO(rdev)) {
99771fe6b9SJerome Glisse 		WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset);
100771fe6b9SJerome Glisse 		WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN |
101771fe6b9SJerome Glisse 		       (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT));
102771fe6b9SJerome Glisse 	} else {
103771fe6b9SJerome Glisse 		switch (radeon_crtc->crtc_id) {
104771fe6b9SJerome Glisse 		case 0:
105771fe6b9SJerome Glisse 			WREG32(RADEON_MM_INDEX, RADEON_CRTC_GEN_CNTL);
106771fe6b9SJerome Glisse 			break;
107771fe6b9SJerome Glisse 		case 1:
108771fe6b9SJerome Glisse 			WREG32(RADEON_MM_INDEX, RADEON_CRTC2_GEN_CNTL);
109771fe6b9SJerome Glisse 			break;
110771fe6b9SJerome Glisse 		default:
111771fe6b9SJerome Glisse 			return;
112771fe6b9SJerome Glisse 		}
113771fe6b9SJerome Glisse 
114771fe6b9SJerome Glisse 		WREG32_P(RADEON_MM_DATA, (RADEON_CRTC_CUR_EN |
115771fe6b9SJerome Glisse 					  (RADEON_CRTC_CUR_MODE_24BPP << RADEON_CRTC_CUR_MODE_SHIFT)),
116771fe6b9SJerome Glisse 			 ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_CUR_MODE_MASK));
117771fe6b9SJerome Glisse 	}
118771fe6b9SJerome Glisse }
119771fe6b9SJerome Glisse 
120771fe6b9SJerome Glisse static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj,
121f981d463SAlex Deucher 			      uint64_t gpu_addr)
122771fe6b9SJerome Glisse {
123771fe6b9SJerome Glisse 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
124771fe6b9SJerome Glisse 	struct radeon_device *rdev = crtc->dev->dev_private;
125771fe6b9SJerome Glisse 
126bcc1c2a1SAlex Deucher 	if (ASIC_IS_DCE4(rdev)) {
127f981d463SAlex Deucher 		WREG32(EVERGREEN_CUR_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
128f981d463SAlex Deucher 		       upper_32_bits(gpu_addr));
129f981d463SAlex Deucher 		WREG32(EVERGREEN_CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
130f981d463SAlex Deucher 		       gpu_addr & 0xffffffff);
131bcc1c2a1SAlex Deucher 	} else if (ASIC_IS_AVIVO(rdev)) {
132c290dadfSAlex Deucher 		if (rdev->family >= CHIP_RV770) {
133c290dadfSAlex Deucher 			if (radeon_crtc->crtc_id)
134f981d463SAlex Deucher 				WREG32(R700_D2CUR_SURFACE_ADDRESS_HIGH, upper_32_bits(gpu_addr));
135c290dadfSAlex Deucher 			else
136f981d463SAlex Deucher 				WREG32(R700_D1CUR_SURFACE_ADDRESS_HIGH, upper_32_bits(gpu_addr));
137c290dadfSAlex Deucher 		}
138f981d463SAlex Deucher 		WREG32(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
139f981d463SAlex Deucher 		       gpu_addr & 0xffffffff);
140c290dadfSAlex Deucher 	} else {
141c836e862SAlex Deucher 		radeon_crtc->legacy_cursor_offset = gpu_addr - radeon_crtc->legacy_display_base_addr;
142771fe6b9SJerome Glisse 		/* offset is from DISP(2)_BASE_ADDRESS */
143c836e862SAlex Deucher 		WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, radeon_crtc->legacy_cursor_offset);
144c836e862SAlex Deucher 	}
145771fe6b9SJerome Glisse }
146771fe6b9SJerome Glisse 
147771fe6b9SJerome Glisse int radeon_crtc_cursor_set(struct drm_crtc *crtc,
148771fe6b9SJerome Glisse 			   struct drm_file *file_priv,
149771fe6b9SJerome Glisse 			   uint32_t handle,
150771fe6b9SJerome Glisse 			   uint32_t width,
151771fe6b9SJerome Glisse 			   uint32_t height)
152771fe6b9SJerome Glisse {
153771fe6b9SJerome Glisse 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
154c4353016SMichel Dänzer 	struct radeon_device *rdev = crtc->dev->dev_private;
155771fe6b9SJerome Glisse 	struct drm_gem_object *obj;
156c4353016SMichel Dänzer 	struct radeon_bo *robj;
157771fe6b9SJerome Glisse 	uint64_t gpu_addr;
158771fe6b9SJerome Glisse 	int ret;
159771fe6b9SJerome Glisse 
160771fe6b9SJerome Glisse 	if (!handle) {
161771fe6b9SJerome Glisse 		/* turn off cursor */
162771fe6b9SJerome Glisse 		radeon_hide_cursor(crtc);
163771fe6b9SJerome Glisse 		obj = NULL;
164771fe6b9SJerome Glisse 		goto unpin;
165771fe6b9SJerome Glisse 	}
166771fe6b9SJerome Glisse 
167771fe6b9SJerome Glisse 	if ((width > CURSOR_WIDTH) || (height > CURSOR_HEIGHT)) {
168771fe6b9SJerome Glisse 		DRM_ERROR("bad cursor width or height %d x %d\n", width, height);
169771fe6b9SJerome Glisse 		return -EINVAL;
170771fe6b9SJerome Glisse 	}
171771fe6b9SJerome Glisse 
172771fe6b9SJerome Glisse 	obj = drm_gem_object_lookup(crtc->dev, file_priv, handle);
173771fe6b9SJerome Glisse 	if (!obj) {
174771fe6b9SJerome Glisse 		DRM_ERROR("Cannot find cursor object %x for crtc %d\n", handle, radeon_crtc->crtc_id);
175bf79cb91SChris Wilson 		return -ENOENT;
176771fe6b9SJerome Glisse 	}
177771fe6b9SJerome Glisse 
178c4353016SMichel Dänzer 	robj = gem_to_radeon_bo(obj);
179c4353016SMichel Dänzer 	ret = radeon_bo_reserve(robj, false);
180c4353016SMichel Dänzer 	if (unlikely(ret != 0))
181c4353016SMichel Dänzer 		goto fail;
182c4353016SMichel Dänzer 	/* Only 27 bit offset for legacy cursor */
183c4353016SMichel Dänzer 	ret = radeon_bo_pin_restricted(robj, RADEON_GEM_DOMAIN_VRAM,
184c4353016SMichel Dänzer 				       ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27,
185c4353016SMichel Dänzer 				       &gpu_addr);
186c4353016SMichel Dänzer 	radeon_bo_unreserve(robj);
187771fe6b9SJerome Glisse 	if (ret)
188771fe6b9SJerome Glisse 		goto fail;
189771fe6b9SJerome Glisse 
19045e5f6a2SIlija Hadzic 	radeon_crtc->cursor_width = width;
19145e5f6a2SIlija Hadzic 	radeon_crtc->cursor_height = height;
19245e5f6a2SIlija Hadzic 
193771fe6b9SJerome Glisse 	radeon_lock_cursor(crtc, true);
194771fe6b9SJerome Glisse 	radeon_set_cursor(crtc, obj, gpu_addr);
195771fe6b9SJerome Glisse 	radeon_show_cursor(crtc);
196771fe6b9SJerome Glisse 	radeon_lock_cursor(crtc, false);
197771fe6b9SJerome Glisse 
198771fe6b9SJerome Glisse unpin:
199771fe6b9SJerome Glisse 	if (radeon_crtc->cursor_bo) {
200*654c59cfSMichel Dänzer 		robj = gem_to_radeon_bo(radeon_crtc->cursor_bo);
201*654c59cfSMichel Dänzer 		ret = radeon_bo_reserve(robj, false);
202*654c59cfSMichel Dänzer 		if (likely(ret == 0)) {
203*654c59cfSMichel Dänzer 			radeon_bo_unpin(robj);
204*654c59cfSMichel Dänzer 			radeon_bo_unreserve(robj);
205*654c59cfSMichel Dänzer 		}
206bc9025bdSLuca Barbieri 		drm_gem_object_unreference_unlocked(radeon_crtc->cursor_bo);
207771fe6b9SJerome Glisse 	}
208771fe6b9SJerome Glisse 
209771fe6b9SJerome Glisse 	radeon_crtc->cursor_bo = obj;
210771fe6b9SJerome Glisse 	return 0;
211771fe6b9SJerome Glisse fail:
212bc9025bdSLuca Barbieri 	drm_gem_object_unreference_unlocked(obj);
213771fe6b9SJerome Glisse 
2144cdb82b9SMatt Turner 	return ret;
215771fe6b9SJerome Glisse }
216771fe6b9SJerome Glisse 
217771fe6b9SJerome Glisse int radeon_crtc_cursor_move(struct drm_crtc *crtc,
218771fe6b9SJerome Glisse 			    int x, int y)
219771fe6b9SJerome Glisse {
220771fe6b9SJerome Glisse 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
221771fe6b9SJerome Glisse 	struct radeon_device *rdev = crtc->dev->dev_private;
222771fe6b9SJerome Glisse 	int xorigin = 0, yorigin = 0;
2236a2a11dbSAlex Deucher 	int w = radeon_crtc->cursor_width;
224771fe6b9SJerome Glisse 
225b8aee294SMichel Dänzer 	if (ASIC_IS_AVIVO(rdev)) {
226b8aee294SMichel Dänzer 		/* avivo cursor are offset into the total surface */
227b8aee294SMichel Dänzer 		x += crtc->x;
228b8aee294SMichel Dänzer 		y += crtc->y;
229b8aee294SMichel Dänzer 	}
230b8aee294SMichel Dänzer 	DRM_DEBUG("x %d y %d c->x %d c->y %d\n", x, y, crtc->x, crtc->y);
231b8aee294SMichel Dänzer 
23202e6859eSMichel Dänzer 	if (x < 0) {
2337d309529SMichel Dänzer 		xorigin = min(-x, CURSOR_WIDTH - 1);
23402e6859eSMichel Dänzer 		x = 0;
23502e6859eSMichel Dänzer 	}
23602e6859eSMichel Dänzer 	if (y < 0) {
2377d309529SMichel Dänzer 		yorigin = min(-y, CURSOR_HEIGHT - 1);
23802e6859eSMichel Dänzer 		y = 0;
23902e6859eSMichel Dänzer 	}
240771fe6b9SJerome Glisse 
2416a2a11dbSAlex Deucher 	if (ASIC_IS_AVIVO(rdev)) {
242771fe6b9SJerome Glisse 		int i = 0;
243771fe6b9SJerome Glisse 		struct drm_crtc *crtc_p;
244771fe6b9SJerome Glisse 
24525985edcSLucas De Marchi 		/* avivo cursor image can't end on 128 pixel boundary or
246771fe6b9SJerome Glisse 		 * go past the end of the frame if both crtcs are enabled
247771fe6b9SJerome Glisse 		 */
248771fe6b9SJerome Glisse 		list_for_each_entry(crtc_p, &crtc->dev->mode_config.crtc_list, head) {
249771fe6b9SJerome Glisse 			if (crtc_p->enabled)
250771fe6b9SJerome Glisse 				i++;
251771fe6b9SJerome Glisse 		}
252771fe6b9SJerome Glisse 		if (i > 1) {
253771fe6b9SJerome Glisse 			int cursor_end, frame_end;
254771fe6b9SJerome Glisse 
255771fe6b9SJerome Glisse 			cursor_end = x - xorigin + w;
256771fe6b9SJerome Glisse 			frame_end = crtc->x + crtc->mode.crtc_hdisplay;
257771fe6b9SJerome Glisse 			if (cursor_end >= frame_end) {
258771fe6b9SJerome Glisse 				w = w - (cursor_end - frame_end);
259771fe6b9SJerome Glisse 				if (!(frame_end & 0x7f))
260771fe6b9SJerome Glisse 					w--;
261771fe6b9SJerome Glisse 			} else {
262771fe6b9SJerome Glisse 				if (!(cursor_end & 0x7f))
263771fe6b9SJerome Glisse 					w--;
264771fe6b9SJerome Glisse 			}
265771fe6b9SJerome Glisse 			if (w <= 0)
266771fe6b9SJerome Glisse 				w = 1;
267771fe6b9SJerome Glisse 		}
2686a2a11dbSAlex Deucher 	}
269771fe6b9SJerome Glisse 
2706a2a11dbSAlex Deucher 	radeon_lock_cursor(crtc, true);
2716a2a11dbSAlex Deucher 	if (ASIC_IS_DCE4(rdev)) {
27202e6859eSMichel Dänzer 		WREG32(EVERGREEN_CUR_POSITION + radeon_crtc->crtc_offset, (x << 16) | y);
2736a2a11dbSAlex Deucher 		WREG32(EVERGREEN_CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin);
2746a2a11dbSAlex Deucher 		WREG32(EVERGREEN_CUR_SIZE + radeon_crtc->crtc_offset,
2756a2a11dbSAlex Deucher 		       ((w - 1) << 16) | (radeon_crtc->cursor_height - 1));
2766a2a11dbSAlex Deucher 	} else if (ASIC_IS_AVIVO(rdev)) {
27702e6859eSMichel Dänzer 		WREG32(AVIVO_D1CUR_POSITION + radeon_crtc->crtc_offset, (x << 16) | y);
278771fe6b9SJerome Glisse 		WREG32(AVIVO_D1CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin);
279771fe6b9SJerome Glisse 		WREG32(AVIVO_D1CUR_SIZE + radeon_crtc->crtc_offset,
280771fe6b9SJerome Glisse 		       ((w - 1) << 16) | (radeon_crtc->cursor_height - 1));
281771fe6b9SJerome Glisse 	} else {
282771fe6b9SJerome Glisse 		if (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN)
283771fe6b9SJerome Glisse 			y *= 2;
284771fe6b9SJerome Glisse 
285771fe6b9SJerome Glisse 		WREG32(RADEON_CUR_HORZ_VERT_OFF + radeon_crtc->crtc_offset,
286771fe6b9SJerome Glisse 		       (RADEON_CUR_LOCK
287771fe6b9SJerome Glisse 			| (xorigin << 16)
288771fe6b9SJerome Glisse 			| yorigin));
289771fe6b9SJerome Glisse 		WREG32(RADEON_CUR_HORZ_VERT_POSN + radeon_crtc->crtc_offset,
290771fe6b9SJerome Glisse 		       (RADEON_CUR_LOCK
29102e6859eSMichel Dänzer 			| (x << 16)
29202e6859eSMichel Dänzer 			| y));
293c836e862SAlex Deucher 		/* offset is from DISP(2)_BASE_ADDRESS */
294c836e862SAlex Deucher 		WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, (radeon_crtc->legacy_cursor_offset +
295c836e862SAlex Deucher 								      (yorigin * 256)));
296771fe6b9SJerome Glisse 	}
297771fe6b9SJerome Glisse 	radeon_lock_cursor(crtc, false);
298771fe6b9SJerome Glisse 
299771fe6b9SJerome Glisse 	return 0;
300771fe6b9SJerome Glisse }
301