Rev 5078 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5078 | Rev 6104 | ||
---|---|---|---|
Line 89... | Line 89... | ||
89 | { |
89 | { |
90 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
90 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
91 | struct radeon_device *rdev = crtc->dev->dev_private; |
91 | struct radeon_device *rdev = crtc->dev->dev_private; |
Line 92... | Line 92... | ||
92 | 92 | ||
- | 93 | if (ASIC_IS_DCE4(rdev)) { |
|
- | 94 | WREG32(EVERGREEN_CUR_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, |
|
- | 95 | upper_32_bits(radeon_crtc->cursor_addr)); |
|
- | 96 | WREG32(EVERGREEN_CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, |
|
93 | if (ASIC_IS_DCE4(rdev)) { |
97 | lower_32_bits(radeon_crtc->cursor_addr)); |
94 | WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); |
98 | WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); |
95 | WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_EN | |
99 | WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_EN | |
96 | EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT) | |
100 | EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT) | |
97 | EVERGREEN_CURSOR_URGENT_CONTROL(EVERGREEN_CURSOR_URGENT_1_2)); |
101 | EVERGREEN_CURSOR_URGENT_CONTROL(EVERGREEN_CURSOR_URGENT_1_2)); |
- | 102 | } else if (ASIC_IS_AVIVO(rdev)) { |
|
- | 103 | if (rdev->family >= CHIP_RV770) { |
|
- | 104 | if (radeon_crtc->crtc_id) |
|
- | 105 | WREG32(R700_D2CUR_SURFACE_ADDRESS_HIGH, |
|
- | 106 | upper_32_bits(radeon_crtc->cursor_addr)); |
|
- | 107 | else |
|
- | 108 | WREG32(R700_D1CUR_SURFACE_ADDRESS_HIGH, |
|
- | 109 | upper_32_bits(radeon_crtc->cursor_addr)); |
|
- | 110 | } |
|
- | 111 | ||
- | 112 | WREG32(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, |
|
98 | } else if (ASIC_IS_AVIVO(rdev)) { |
113 | lower_32_bits(radeon_crtc->cursor_addr)); |
99 | WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); |
114 | WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); |
100 | WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN | |
115 | WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN | |
101 | (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT)); |
116 | (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT)); |
- | 117 | } else { |
|
- | 118 | /* offset is from DISP(2)_BASE_ADDRESS */ |
|
- | 119 | WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, |
|
- | 120 | radeon_crtc->cursor_addr - radeon_crtc->legacy_display_base_addr); |
|
102 | } else { |
121 | |
103 | switch (radeon_crtc->crtc_id) { |
122 | switch (radeon_crtc->crtc_id) { |
104 | case 0: |
123 | case 0: |
105 | WREG32(RADEON_MM_INDEX, RADEON_CRTC_GEN_CNTL); |
124 | WREG32(RADEON_MM_INDEX, RADEON_CRTC_GEN_CNTL); |
106 | break; |
125 | break; |
Line 115... | Line 134... | ||
115 | (RADEON_CRTC_CUR_MODE_24BPP << RADEON_CRTC_CUR_MODE_SHIFT)), |
134 | (RADEON_CRTC_CUR_MODE_24BPP << RADEON_CRTC_CUR_MODE_SHIFT)), |
116 | ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_CUR_MODE_MASK)); |
135 | ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_CUR_MODE_MASK)); |
117 | } |
136 | } |
118 | } |
137 | } |
Line 119... | Line -... | ||
119 | - | ||
120 | static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, |
- | |
121 | uint64_t gpu_addr) |
- | |
122 | { |
- | |
123 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
- | |
124 | struct radeon_device *rdev = crtc->dev->dev_private; |
- | |
125 | - | ||
126 | if (ASIC_IS_DCE4(rdev)) { |
- | |
127 | WREG32(EVERGREEN_CUR_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, |
- | |
128 | upper_32_bits(gpu_addr)); |
- | |
129 | WREG32(EVERGREEN_CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, |
- | |
130 | gpu_addr & 0xffffffff); |
- | |
131 | } else if (ASIC_IS_AVIVO(rdev)) { |
- | |
132 | if (rdev->family >= CHIP_RV770) { |
- | |
133 | if (radeon_crtc->crtc_id) |
- | |
134 | WREG32(R700_D2CUR_SURFACE_ADDRESS_HIGH, upper_32_bits(gpu_addr)); |
- | |
135 | else |
- | |
136 | WREG32(R700_D1CUR_SURFACE_ADDRESS_HIGH, upper_32_bits(gpu_addr)); |
- | |
137 | } |
- | |
138 | WREG32(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, |
- | |
139 | gpu_addr & 0xffffffff); |
- | |
140 | } else { |
- | |
141 | radeon_crtc->legacy_cursor_offset = gpu_addr - radeon_crtc->legacy_display_base_addr; |
- | |
142 | /* offset is from DISP(2)_BASE_ADDRESS */ |
- | |
143 | WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, radeon_crtc->legacy_cursor_offset); |
- | |
144 | } |
- | |
145 | } |
- | |
146 | - | ||
147 | int radeon_crtc_cursor_set(struct drm_crtc *crtc, |
- | |
148 | struct drm_file *file_priv, |
- | |
149 | uint32_t handle, |
- | |
150 | uint32_t width, |
- | |
151 | uint32_t height) |
- | |
152 | { |
- | |
153 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
- | |
154 | struct radeon_device *rdev = crtc->dev->dev_private; |
- | |
155 | struct drm_gem_object *obj; |
- | |
156 | struct radeon_bo *robj; |
- | |
157 | uint64_t gpu_addr; |
- | |
158 | int ret; |
- | |
159 | - | ||
160 | if (!handle) { |
- | |
161 | /* turn off cursor */ |
- | |
162 | radeon_hide_cursor(crtc); |
- | |
163 | obj = NULL; |
- | |
164 | goto unpin; |
- | |
165 | } |
- | |
166 | - | ||
167 | if ((width > radeon_crtc->max_cursor_width) || |
- | |
168 | (height > radeon_crtc->max_cursor_height)) { |
- | |
169 | DRM_ERROR("bad cursor width or height %d x %d\n", width, height); |
- | |
170 | return -EINVAL; |
- | |
171 | } |
- | |
172 | - | ||
173 | obj = drm_gem_object_lookup(crtc->dev, file_priv, handle); |
- | |
174 | if (!obj) { |
- | |
175 | DRM_ERROR("Cannot find cursor object %x for crtc %d\n", handle, radeon_crtc->crtc_id); |
- | |
176 | return -ENOENT; |
- | |
177 | } |
- | |
178 | - | ||
179 | robj = gem_to_radeon_bo(obj); |
- | |
180 | ret = radeon_bo_reserve(robj, false); |
- | |
181 | if (unlikely(ret != 0)) |
- | |
182 | goto fail; |
- | |
183 | /* Only 27 bit offset for legacy cursor */ |
- | |
184 | ret = radeon_bo_pin_restricted(robj, RADEON_GEM_DOMAIN_VRAM, |
- | |
185 | ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27, |
- | |
186 | &gpu_addr); |
- | |
187 | radeon_bo_unreserve(robj); |
- | |
188 | if (ret) |
- | |
189 | goto fail; |
- | |
190 | - | ||
191 | radeon_crtc->cursor_width = width; |
- | |
192 | radeon_crtc->cursor_height = height; |
- | |
193 | - | ||
194 | radeon_lock_cursor(crtc, true); |
- | |
195 | radeon_set_cursor(crtc, obj, gpu_addr); |
- | |
196 | radeon_show_cursor(crtc); |
- | |
197 | radeon_lock_cursor(crtc, false); |
- | |
198 | - | ||
199 | unpin: |
- | |
200 | if (radeon_crtc->cursor_bo) { |
- | |
201 | robj = gem_to_radeon_bo(radeon_crtc->cursor_bo); |
- | |
202 | ret = radeon_bo_reserve(robj, false); |
- | |
203 | if (likely(ret == 0)) { |
- | |
204 | radeon_bo_unpin(robj); |
- | |
205 | radeon_bo_unreserve(robj); |
- | |
206 | } |
- | |
207 | drm_gem_object_unreference_unlocked(radeon_crtc->cursor_bo); |
- | |
208 | } |
- | |
209 | - | ||
210 | radeon_crtc->cursor_bo = obj; |
- | |
211 | return 0; |
- | |
212 | fail: |
- | |
213 | drm_gem_object_unreference_unlocked(obj); |
- | |
214 | - | ||
215 | return ret; |
- | |
216 | } |
- | |
217 | 138 | ||
218 | int radeon_crtc_cursor_move(struct drm_crtc *crtc, |
- | |
219 | int x, int y) |
139 | static int radeon_cursor_move_locked(struct drm_crtc *crtc, int x, int y) |
220 | { |
140 | { |
221 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
141 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
222 | struct radeon_device *rdev = crtc->dev->dev_private; |
142 | struct radeon_device *rdev = crtc->dev->dev_private; |
223 | int xorigin = 0, yorigin = 0; |
143 | int xorigin = 0, yorigin = 0; |
Line 279... | Line 199... | ||
279 | } |
199 | } |
280 | } |
200 | } |
281 | } |
201 | } |
282 | } |
202 | } |
Line 283... | Line -... | ||
283 | - | ||
284 | radeon_lock_cursor(crtc, true); |
203 | |
285 | if (ASIC_IS_DCE4(rdev)) { |
204 | if (ASIC_IS_DCE4(rdev)) { |
286 | WREG32(EVERGREEN_CUR_POSITION + radeon_crtc->crtc_offset, (x << 16) | y); |
205 | WREG32(EVERGREEN_CUR_POSITION + radeon_crtc->crtc_offset, (x << 16) | y); |
287 | WREG32(EVERGREEN_CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin); |
206 | WREG32(EVERGREEN_CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin); |
288 | WREG32(EVERGREEN_CUR_SIZE + radeon_crtc->crtc_offset, |
207 | WREG32(EVERGREEN_CUR_SIZE + radeon_crtc->crtc_offset, |
Line 303... | Line 222... | ||
303 | WREG32(RADEON_CUR_HORZ_VERT_POSN + radeon_crtc->crtc_offset, |
222 | WREG32(RADEON_CUR_HORZ_VERT_POSN + radeon_crtc->crtc_offset, |
304 | (RADEON_CUR_LOCK |
223 | (RADEON_CUR_LOCK |
305 | | (x << 16) |
224 | | (x << 16) |
306 | | y)); |
225 | | y)); |
307 | /* offset is from DISP(2)_BASE_ADDRESS */ |
226 | /* offset is from DISP(2)_BASE_ADDRESS */ |
308 | WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, (radeon_crtc->legacy_cursor_offset + |
227 | WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, |
- | 228 | radeon_crtc->cursor_addr - radeon_crtc->legacy_display_base_addr + |
|
309 | (yorigin * 256))); |
229 | yorigin * 256); |
- | 230 | } |
|
- | 231 | ||
- | 232 | radeon_crtc->cursor_x = x; |
|
- | 233 | radeon_crtc->cursor_y = y; |
|
- | 234 | ||
- | 235 | return 0; |
|
- | 236 | } |
|
- | 237 | ||
- | 238 | int radeon_crtc_cursor_move(struct drm_crtc *crtc, |
|
- | 239 | int x, int y) |
|
- | 240 | { |
|
- | 241 | int ret; |
|
- | 242 | ||
- | 243 | radeon_lock_cursor(crtc, true); |
|
- | 244 | ret = radeon_cursor_move_locked(crtc, x, y); |
|
- | 245 | radeon_lock_cursor(crtc, false); |
|
- | 246 | ||
- | 247 | return ret; |
|
- | 248 | } |
|
- | 249 | ||
- | 250 | int radeon_crtc_cursor_set2(struct drm_crtc *crtc, |
|
- | 251 | struct drm_file *file_priv, |
|
- | 252 | uint32_t handle, |
|
- | 253 | uint32_t width, |
|
- | 254 | uint32_t height, |
|
- | 255 | int32_t hot_x, |
|
- | 256 | int32_t hot_y) |
|
- | 257 | { |
|
- | 258 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
|
- | 259 | struct radeon_device *rdev = crtc->dev->dev_private; |
|
- | 260 | struct drm_gem_object *obj; |
|
- | 261 | struct radeon_bo *robj; |
|
- | 262 | int ret; |
|
- | 263 | ||
- | 264 | if (!handle) { |
|
- | 265 | /* turn off cursor */ |
|
- | 266 | radeon_hide_cursor(crtc); |
|
- | 267 | obj = NULL; |
|
- | 268 | goto unpin; |
|
- | 269 | } |
|
- | 270 | ||
- | 271 | if ((width > radeon_crtc->max_cursor_width) || |
|
- | 272 | (height > radeon_crtc->max_cursor_height)) { |
|
- | 273 | DRM_ERROR("bad cursor width or height %d x %d\n", width, height); |
|
- | 274 | return -EINVAL; |
|
- | 275 | } |
|
- | 276 | ||
- | 277 | obj = drm_gem_object_lookup(crtc->dev, file_priv, handle); |
|
- | 278 | if (!obj) { |
|
- | 279 | DRM_ERROR("Cannot find cursor object %x for crtc %d\n", handle, radeon_crtc->crtc_id); |
|
- | 280 | return -ENOENT; |
|
- | 281 | } |
|
- | 282 | ||
- | 283 | robj = gem_to_radeon_bo(obj); |
|
- | 284 | ret = radeon_bo_reserve(robj, false); |
|
- | 285 | if (ret != 0) { |
|
- | 286 | drm_gem_object_unreference_unlocked(obj); |
|
- | 287 | return ret; |
|
310 | } |
288 | } |
- | 289 | /* Only 27 bit offset for legacy cursor */ |
|
- | 290 | ret = radeon_bo_pin_restricted(robj, RADEON_GEM_DOMAIN_VRAM, |
|
- | 291 | ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27, |
|
- | 292 | &radeon_crtc->cursor_addr); |
|
- | 293 | radeon_bo_unreserve(robj); |
|
- | 294 | if (ret) { |
|
- | 295 | DRM_ERROR("Failed to pin new cursor BO (%d)\n", ret); |
|
- | 296 | drm_gem_object_unreference_unlocked(obj); |
|
- | 297 | return ret; |
|
- | 298 | } |
|
- | 299 | ||
- | 300 | radeon_crtc->cursor_width = width; |
|
- | 301 | radeon_crtc->cursor_height = height; |
|
- | 302 | ||
- | 303 | radeon_lock_cursor(crtc, true); |
|
- | 304 | ||
- | 305 | if (hot_x != radeon_crtc->cursor_hot_x || |
|
- | 306 | hot_y != radeon_crtc->cursor_hot_y) { |
|
- | 307 | int x, y; |
|
- | 308 | ||
- | 309 | x = radeon_crtc->cursor_x + radeon_crtc->cursor_hot_x - hot_x; |
|
- | 310 | y = radeon_crtc->cursor_y + radeon_crtc->cursor_hot_y - hot_y; |
|
- | 311 | ||
- | 312 | radeon_cursor_move_locked(crtc, x, y); |
|
- | 313 | ||
- | 314 | radeon_crtc->cursor_hot_x = hot_x; |
|
- | 315 | radeon_crtc->cursor_hot_y = hot_y; |
|
- | 316 | } |
|
- | 317 | ||
- | 318 | radeon_show_cursor(crtc); |
|
- | 319 | ||
311 | radeon_lock_cursor(crtc, false); |
320 | radeon_lock_cursor(crtc, false); |
Line -... | Line 321... | ||
- | 321 | ||
- | 322 | unpin: |
|
- | 323 | if (radeon_crtc->cursor_bo) { |
|
- | 324 | struct radeon_bo *robj = gem_to_radeon_bo(radeon_crtc->cursor_bo); |
|
- | 325 | ret = radeon_bo_reserve(robj, false); |
|
- | 326 | if (likely(ret == 0)) { |
|
- | 327 | radeon_bo_unpin(robj); |
|
- | 328 | radeon_bo_unreserve(robj); |
|
- | 329 | } |
|
- | 330 | drm_gem_object_unreference_unlocked(radeon_crtc->cursor_bo); |
|
- | 331 | } |
|
- | 332 | ||
312 | 333 | radeon_crtc->cursor_bo = obj; |
|
313 | return 0; |
334 | return 0; |
- | 335 | } |
|
- | 336 | ||
- | 337 | /** |
|
- | 338 | * radeon_cursor_reset - Re-set the current cursor, if any. |
|
- | 339 | * |
|
- | 340 | * @crtc: drm crtc |
|
- | 341 | * |
|
- | 342 | * If the CRTC passed in currently has a cursor assigned, this function |
|
- | 343 | * makes sure it's visible. |
|
- | 344 | */ |
|
- | 345 | void radeon_cursor_reset(struct drm_crtc *crtc) |
|
- | 346 | { |
|
- | 347 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
|
- | 348 | ||
- | 349 | if (radeon_crtc->cursor_bo) { |
|
- | 350 | radeon_lock_cursor(crtc, true); |
|
- | 351 | ||
- | 352 | radeon_cursor_move_locked(crtc, radeon_crtc->cursor_x, |
|
- | 353 | radeon_crtc->cursor_y); |
|
- | 354 | ||
- | 355 | radeon_show_cursor(crtc); |
|
- | 356 | ||
- | 357 | radeon_lock_cursor(crtc, false); |
|
- | 358 | } |