Line data Source code
1 : /*
2 : * Copyright 2007-8 Advanced Micro Devices, Inc.
3 : * Copyright 2008 Red Hat Inc.
4 : *
5 : * Permission is hereby granted, free of charge, to any person obtaining a
6 : * copy of this software and associated documentation files (the "Software"),
7 : * to deal in the Software without restriction, including without limitation
8 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 : * and/or sell copies of the Software, and to permit persons to whom the
10 : * Software is furnished to do so, subject to the following conditions:
11 : *
12 : * The above copyright notice and this permission notice shall be included in
13 : * all copies or substantial portions of the Software.
14 : *
15 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 : * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 : * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 : * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 : * OTHER DEALINGS IN THE SOFTWARE.
22 : *
23 : * Authors: Dave Airlie
24 : * Alex Deucher
25 : */
26 : #include <dev/pci/drm/drmP.h>
27 : #include <dev/pci/drm/radeon_drm.h>
28 : #include "radeon.h"
29 :
30 : #include "atom.h"
31 :
32 : #include <dev/pci/drm/drm_crtc_helper.h>
33 : #include <dev/pci/drm/drm_plane_helper.h>
34 : #include <dev/pci/drm/drm_edid.h>
35 :
36 :
37 0 : static void avivo_crtc_load_lut(struct drm_crtc *crtc)
38 : {
39 0 : struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
40 0 : struct drm_device *dev = crtc->dev;
41 0 : struct radeon_device *rdev = dev->dev_private;
42 : int i;
43 :
44 : DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id);
45 0 : WREG32(AVIVO_DC_LUTA_CONTROL + radeon_crtc->crtc_offset, 0);
46 :
47 0 : WREG32(AVIVO_DC_LUTA_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0);
48 0 : WREG32(AVIVO_DC_LUTA_BLACK_OFFSET_GREEN + radeon_crtc->crtc_offset, 0);
49 0 : WREG32(AVIVO_DC_LUTA_BLACK_OFFSET_RED + radeon_crtc->crtc_offset, 0);
50 :
51 0 : WREG32(AVIVO_DC_LUTA_WHITE_OFFSET_BLUE + radeon_crtc->crtc_offset, 0xffff);
52 0 : WREG32(AVIVO_DC_LUTA_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff);
53 0 : WREG32(AVIVO_DC_LUTA_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff);
54 :
55 0 : WREG32(AVIVO_DC_LUT_RW_SELECT, radeon_crtc->crtc_id);
56 0 : WREG32(AVIVO_DC_LUT_RW_MODE, 0);
57 0 : WREG32(AVIVO_DC_LUT_WRITE_EN_MASK, 0x0000003f);
58 :
59 0 : WREG8(AVIVO_DC_LUT_RW_INDEX, 0);
60 0 : for (i = 0; i < 256; i++) {
61 0 : WREG32(AVIVO_DC_LUT_30_COLOR,
62 : (radeon_crtc->lut_r[i] << 20) |
63 : (radeon_crtc->lut_g[i] << 10) |
64 : (radeon_crtc->lut_b[i] << 0));
65 : }
66 :
67 : /* Only change bit 0 of LUT_SEL, other bits are set elsewhere */
68 0 : WREG32_P(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset, radeon_crtc->crtc_id, ~1);
69 0 : }
70 :
71 0 : static void dce4_crtc_load_lut(struct drm_crtc *crtc)
72 : {
73 0 : struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
74 0 : struct drm_device *dev = crtc->dev;
75 0 : struct radeon_device *rdev = dev->dev_private;
76 : int i;
77 :
78 : DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id);
79 0 : WREG32(EVERGREEN_DC_LUT_CONTROL + radeon_crtc->crtc_offset, 0);
80 :
81 0 : WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0);
82 0 : WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_GREEN + radeon_crtc->crtc_offset, 0);
83 0 : WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_RED + radeon_crtc->crtc_offset, 0);
84 :
85 0 : WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_BLUE + radeon_crtc->crtc_offset, 0xffff);
86 0 : WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff);
87 0 : WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff);
88 :
89 0 : WREG32(EVERGREEN_DC_LUT_RW_MODE + radeon_crtc->crtc_offset, 0);
90 0 : WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK + radeon_crtc->crtc_offset, 0x00000007);
91 :
92 0 : WREG32(EVERGREEN_DC_LUT_RW_INDEX + radeon_crtc->crtc_offset, 0);
93 0 : for (i = 0; i < 256; i++) {
94 0 : WREG32(EVERGREEN_DC_LUT_30_COLOR + radeon_crtc->crtc_offset,
95 : (radeon_crtc->lut_r[i] << 20) |
96 : (radeon_crtc->lut_g[i] << 10) |
97 : (radeon_crtc->lut_b[i] << 0));
98 : }
99 0 : }
100 :
101 0 : static void dce5_crtc_load_lut(struct drm_crtc *crtc)
102 : {
103 0 : struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
104 0 : struct drm_device *dev = crtc->dev;
105 0 : struct radeon_device *rdev = dev->dev_private;
106 : int i;
107 :
108 : DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id);
109 :
110 0 : WREG32(NI_INPUT_CSC_CONTROL + radeon_crtc->crtc_offset,
111 : (NI_INPUT_CSC_GRPH_MODE(NI_INPUT_CSC_BYPASS) |
112 : NI_INPUT_CSC_OVL_MODE(NI_INPUT_CSC_BYPASS)));
113 0 : WREG32(NI_PRESCALE_GRPH_CONTROL + radeon_crtc->crtc_offset,
114 : NI_GRPH_PRESCALE_BYPASS);
115 0 : WREG32(NI_PRESCALE_OVL_CONTROL + radeon_crtc->crtc_offset,
116 : NI_OVL_PRESCALE_BYPASS);
117 0 : WREG32(NI_INPUT_GAMMA_CONTROL + radeon_crtc->crtc_offset,
118 : (NI_GRPH_INPUT_GAMMA_MODE(NI_INPUT_GAMMA_USE_LUT) |
119 : NI_OVL_INPUT_GAMMA_MODE(NI_INPUT_GAMMA_USE_LUT)));
120 :
121 0 : WREG32(EVERGREEN_DC_LUT_CONTROL + radeon_crtc->crtc_offset, 0);
122 :
123 0 : WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0);
124 0 : WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_GREEN + radeon_crtc->crtc_offset, 0);
125 0 : WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_RED + radeon_crtc->crtc_offset, 0);
126 :
127 0 : WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_BLUE + radeon_crtc->crtc_offset, 0xffff);
128 0 : WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff);
129 0 : WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff);
130 :
131 0 : WREG32(EVERGREEN_DC_LUT_RW_MODE + radeon_crtc->crtc_offset, 0);
132 0 : WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK + radeon_crtc->crtc_offset, 0x00000007);
133 :
134 0 : WREG32(EVERGREEN_DC_LUT_RW_INDEX + radeon_crtc->crtc_offset, 0);
135 0 : for (i = 0; i < 256; i++) {
136 0 : WREG32(EVERGREEN_DC_LUT_30_COLOR + radeon_crtc->crtc_offset,
137 : (radeon_crtc->lut_r[i] << 20) |
138 : (radeon_crtc->lut_g[i] << 10) |
139 : (radeon_crtc->lut_b[i] << 0));
140 : }
141 :
142 0 : WREG32(NI_DEGAMMA_CONTROL + radeon_crtc->crtc_offset,
143 : (NI_GRPH_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) |
144 : NI_OVL_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) |
145 : NI_ICON_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) |
146 : NI_CURSOR_DEGAMMA_MODE(NI_DEGAMMA_BYPASS)));
147 0 : WREG32(NI_GAMUT_REMAP_CONTROL + radeon_crtc->crtc_offset,
148 : (NI_GRPH_GAMUT_REMAP_MODE(NI_GAMUT_REMAP_BYPASS) |
149 : NI_OVL_GAMUT_REMAP_MODE(NI_GAMUT_REMAP_BYPASS)));
150 0 : WREG32(NI_REGAMMA_CONTROL + radeon_crtc->crtc_offset,
151 : (NI_GRPH_REGAMMA_MODE(NI_REGAMMA_BYPASS) |
152 : NI_OVL_REGAMMA_MODE(NI_REGAMMA_BYPASS)));
153 0 : WREG32(NI_OUTPUT_CSC_CONTROL + radeon_crtc->crtc_offset,
154 : (NI_OUTPUT_CSC_GRPH_MODE(radeon_crtc->output_csc) |
155 : NI_OUTPUT_CSC_OVL_MODE(NI_OUTPUT_CSC_BYPASS)));
156 : /* XXX match this to the depth of the crtc fmt block, move to modeset? */
157 0 : WREG32(0x6940 + radeon_crtc->crtc_offset, 0);
158 0 : if (ASIC_IS_DCE8(rdev)) {
159 : /* XXX this only needs to be programmed once per crtc at startup,
160 : * not sure where the best place for it is
161 : */
162 0 : WREG32(CIK_ALPHA_CONTROL + radeon_crtc->crtc_offset,
163 : CIK_CURSOR_ALPHA_BLND_ENA);
164 0 : }
165 0 : }
166 :
167 0 : static void legacy_crtc_load_lut(struct drm_crtc *crtc)
168 : {
169 0 : struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
170 0 : struct drm_device *dev = crtc->dev;
171 0 : struct radeon_device *rdev = dev->dev_private;
172 : int i;
173 : uint32_t dac2_cntl;
174 :
175 0 : dac2_cntl = RREG32(RADEON_DAC_CNTL2);
176 0 : if (radeon_crtc->crtc_id == 0)
177 0 : dac2_cntl &= (uint32_t)~RADEON_DAC2_PALETTE_ACC_CTL;
178 : else
179 0 : dac2_cntl |= RADEON_DAC2_PALETTE_ACC_CTL;
180 0 : WREG32(RADEON_DAC_CNTL2, dac2_cntl);
181 :
182 0 : WREG8(RADEON_PALETTE_INDEX, 0);
183 0 : for (i = 0; i < 256; i++) {
184 0 : WREG32(RADEON_PALETTE_30_DATA,
185 : (radeon_crtc->lut_r[i] << 20) |
186 : (radeon_crtc->lut_g[i] << 10) |
187 : (radeon_crtc->lut_b[i] << 0));
188 : }
189 0 : }
190 :
191 0 : void radeon_crtc_load_lut(struct drm_crtc *crtc)
192 : {
193 0 : struct drm_device *dev = crtc->dev;
194 0 : struct radeon_device *rdev = dev->dev_private;
195 :
196 0 : if (!crtc->enabled)
197 0 : return;
198 :
199 0 : if (ASIC_IS_DCE5(rdev))
200 0 : dce5_crtc_load_lut(crtc);
201 0 : else if (ASIC_IS_DCE4(rdev))
202 0 : dce4_crtc_load_lut(crtc);
203 0 : else if (ASIC_IS_AVIVO(rdev))
204 0 : avivo_crtc_load_lut(crtc);
205 : else
206 0 : legacy_crtc_load_lut(crtc);
207 0 : }
208 :
209 : /** Sets the color ramps on behalf of fbcon */
210 0 : void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
211 : u16 blue, int regno)
212 : {
213 0 : struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
214 :
215 0 : radeon_crtc->lut_r[regno] = red >> 6;
216 0 : radeon_crtc->lut_g[regno] = green >> 6;
217 0 : radeon_crtc->lut_b[regno] = blue >> 6;
218 0 : }
219 :
220 : /** Gets the color ramps on behalf of fbcon */
221 0 : void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
222 : u16 *blue, int regno)
223 : {
224 0 : struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
225 :
226 0 : *red = radeon_crtc->lut_r[regno] << 6;
227 0 : *green = radeon_crtc->lut_g[regno] << 6;
228 0 : *blue = radeon_crtc->lut_b[regno] << 6;
229 0 : }
230 :
231 0 : static void radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
232 : u16 *blue, uint32_t start, uint32_t size)
233 : {
234 0 : struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
235 0 : int end = (start + size > 256) ? 256 : start + size, i;
236 :
237 : /* userspace palettes are always correct as is */
238 0 : for (i = start; i < end; i++) {
239 0 : radeon_crtc->lut_r[i] = red[i] >> 6;
240 0 : radeon_crtc->lut_g[i] = green[i] >> 6;
241 0 : radeon_crtc->lut_b[i] = blue[i] >> 6;
242 : }
243 0 : radeon_crtc_load_lut(crtc);
244 0 : }
245 :
246 0 : static void radeon_crtc_destroy(struct drm_crtc *crtc)
247 : {
248 0 : struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
249 :
250 0 : drm_crtc_cleanup(crtc);
251 0 : destroy_workqueue(radeon_crtc->flip_queue);
252 0 : kfree(radeon_crtc);
253 0 : }
254 :
255 : /**
256 : * radeon_unpin_work_func - unpin old buffer object
257 : *
258 : * @__work - kernel work item
259 : *
260 : * Unpin the old frame buffer object outside of the interrupt handler
261 : */
262 0 : static void radeon_unpin_work_func(struct work_struct *__work)
263 : {
264 : struct radeon_flip_work *work =
265 0 : container_of(__work, struct radeon_flip_work, unpin_work);
266 : int r;
267 :
268 : /* unpin of the old buffer */
269 0 : r = radeon_bo_reserve(work->old_rbo, false);
270 0 : if (likely(r == 0)) {
271 0 : r = radeon_bo_unpin(work->old_rbo);
272 0 : if (unlikely(r != 0)) {
273 0 : DRM_ERROR("failed to unpin buffer after flip\n");
274 0 : }
275 0 : radeon_bo_unreserve(work->old_rbo);
276 0 : } else
277 0 : DRM_ERROR("failed to reserve buffer after flip\n");
278 :
279 0 : drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
280 0 : kfree(work);
281 0 : }
282 :
283 0 : void radeon_crtc_handle_vblank(struct radeon_device *rdev, int crtc_id)
284 : {
285 0 : struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
286 : unsigned long flags;
287 : u32 update_pending;
288 0 : int vpos, hpos;
289 :
290 : /* can happen during initialization */
291 0 : if (radeon_crtc == NULL)
292 0 : return;
293 :
294 : /* Skip the pageflip completion check below (based on polling) on
295 : * asics which reliably support hw pageflip completion irqs. pflip
296 : * irqs are a reliable and race-free method of handling pageflip
297 : * completion detection. A use_pflipirq module parameter < 2 allows
298 : * to override this in case of asics with faulty pflip irqs.
299 : * A module parameter of 0 would only use this polling based path,
300 : * a parameter of 1 would use pflip irq only as a backup to this
301 : * path, as in Linux 3.16.
302 : */
303 0 : if ((radeon_use_pflipirq == 2) && ASIC_IS_DCE4(rdev))
304 0 : return;
305 :
306 0 : spin_lock_irqsave(&rdev->ddev->event_lock, flags);
307 0 : if (radeon_crtc->flip_status != RADEON_FLIP_SUBMITTED) {
308 : DRM_DEBUG_DRIVER("radeon_crtc->flip_status = %d != "
309 : "RADEON_FLIP_SUBMITTED(%d)\n",
310 : radeon_crtc->flip_status,
311 : RADEON_FLIP_SUBMITTED);
312 0 : spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
313 0 : return;
314 : }
315 :
316 0 : update_pending = radeon_page_flip_pending(rdev, crtc_id);
317 :
318 : /* Has the pageflip already completed in crtc, or is it certain
319 : * to complete in this vblank?
320 : */
321 0 : if (update_pending &&
322 0 : (DRM_SCANOUTPOS_VALID & radeon_get_crtc_scanoutpos(rdev->ddev,
323 : crtc_id,
324 : USE_REAL_VBLANKSTART,
325 : &vpos, &hpos, NULL, NULL,
326 0 : &rdev->mode_info.crtcs[crtc_id]->base.hwmode)) &&
327 0 : ((vpos >= (99 * rdev->mode_info.crtcs[crtc_id]->base.hwmode.crtc_vdisplay)/100) ||
328 0 : (vpos < 0 && !ASIC_IS_AVIVO(rdev)))) {
329 : /* crtc didn't flip in this target vblank interval,
330 : * but flip is pending in crtc. Based on the current
331 : * scanout position we know that the current frame is
332 : * (nearly) complete and the flip will (likely)
333 : * complete before the start of the next frame.
334 : */
335 : update_pending = 0;
336 0 : }
337 0 : spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
338 0 : if (!update_pending)
339 0 : radeon_crtc_handle_flip(rdev, crtc_id);
340 0 : }
341 :
342 : /**
343 : * radeon_crtc_handle_flip - page flip completed
344 : *
345 : * @rdev: radeon device pointer
346 : * @crtc_id: crtc number this event is for
347 : *
348 : * Called when we are sure that a page flip for this crtc is completed.
349 : */
350 0 : void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
351 : {
352 0 : struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
353 : struct radeon_flip_work *work;
354 : unsigned long flags;
355 :
356 : /* this can happen at init */
357 0 : if (radeon_crtc == NULL)
358 0 : return;
359 :
360 0 : spin_lock_irqsave(&rdev->ddev->event_lock, flags);
361 0 : work = radeon_crtc->flip_work;
362 0 : if (radeon_crtc->flip_status != RADEON_FLIP_SUBMITTED) {
363 : DRM_DEBUG_DRIVER("radeon_crtc->flip_status = %d != "
364 : "RADEON_FLIP_SUBMITTED(%d)\n",
365 : radeon_crtc->flip_status,
366 : RADEON_FLIP_SUBMITTED);
367 0 : spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
368 0 : return;
369 : }
370 :
371 : /* Pageflip completed. Clean up. */
372 0 : radeon_crtc->flip_status = RADEON_FLIP_NONE;
373 0 : radeon_crtc->flip_work = NULL;
374 :
375 : /* wakeup userspace */
376 0 : if (work->event)
377 0 : drm_send_vblank_event(rdev->ddev, crtc_id, work->event);
378 :
379 0 : spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
380 :
381 0 : drm_vblank_put(rdev->ddev, radeon_crtc->crtc_id);
382 0 : radeon_irq_kms_pflip_irq_put(rdev, work->crtc_id);
383 0 : queue_work(radeon_crtc->flip_queue, &work->unpin_work);
384 0 : }
385 :
386 : /**
387 : * radeon_flip_work_func - page flip framebuffer
388 : *
389 : * @work - kernel work item
390 : *
391 : * Wait for the buffer object to become idle and do the actual page flip
392 : */
393 0 : static void radeon_flip_work_func(struct work_struct *__work)
394 : {
395 : struct radeon_flip_work *work =
396 0 : container_of(__work, struct radeon_flip_work, flip_work);
397 0 : struct radeon_device *rdev = work->rdev;
398 0 : struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[work->crtc_id];
399 :
400 0 : struct drm_crtc *crtc = &radeon_crtc->base;
401 : unsigned long flags;
402 : int r;
403 0 : int vpos, hpos, stat, min_udelay = 0;
404 : unsigned repcnt = 4;
405 0 : struct drm_vblank_crtc *vblank = &crtc->dev->vblank[work->crtc_id];
406 :
407 0 : down_read(&rdev->exclusive_lock);
408 0 : if (work->fence) {
409 : struct radeon_fence *fence;
410 :
411 0 : fence = to_radeon_fence(work->fence);
412 0 : if (fence && fence->rdev == rdev) {
413 0 : r = radeon_fence_wait(fence, false);
414 0 : if (r == -EDEADLK) {
415 0 : up_read(&rdev->exclusive_lock);
416 0 : do {
417 0 : r = radeon_gpu_reset(rdev);
418 0 : } while (r == -EAGAIN);
419 0 : down_read(&rdev->exclusive_lock);
420 0 : }
421 : } else
422 0 : r = fence_wait(work->fence, false);
423 :
424 0 : if (r)
425 0 : DRM_ERROR("failed to wait on page flip fence (%d)!\n", r);
426 :
427 : /* We continue with the page flip even if we failed to wait on
428 : * the fence, otherwise the DRM core and userspace will be
429 : * confused about which BO the CRTC is scanning out
430 : */
431 :
432 0 : fence_put(work->fence);
433 0 : work->fence = NULL;
434 0 : }
435 :
436 : /* We borrow the event spin lock for protecting flip_status */
437 0 : spin_lock_irqsave(&crtc->dev->event_lock, flags);
438 :
439 : /* set the proper interrupt */
440 0 : radeon_irq_kms_pflip_irq_get(rdev, radeon_crtc->crtc_id);
441 :
442 : /* If this happens to execute within the "virtually extended" vblank
443 : * interval before the start of the real vblank interval then it needs
444 : * to delay programming the mmio flip until the real vblank is entered.
445 : * This prevents completing a flip too early due to the way we fudge
446 : * our vblank counter and vblank timestamps in order to work around the
447 : * problem that the hw fires vblank interrupts before actual start of
448 : * vblank (when line buffer refilling is done for a frame). It
449 : * complements the fudging logic in radeon_get_crtc_scanoutpos() for
450 : * timestamping and radeon_get_vblank_counter_kms() for vblank counts.
451 : *
452 : * In practice this won't execute very often unless on very fast
453 : * machines because the time window for this to happen is very small.
454 : */
455 0 : while (radeon_crtc->enabled && --repcnt) {
456 : /* GET_DISTANCE_TO_VBLANKSTART returns distance to real vblank
457 : * start in hpos, and to the "fudged earlier" vblank start in
458 : * vpos.
459 : */
460 0 : stat = radeon_get_crtc_scanoutpos(rdev->ddev, work->crtc_id,
461 : GET_DISTANCE_TO_VBLANKSTART,
462 : &vpos, &hpos, NULL, NULL,
463 0 : &crtc->hwmode);
464 :
465 0 : if ((stat & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE)) !=
466 0 : (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE) ||
467 0 : !(vpos >= 0 && hpos <= 0))
468 : break;
469 :
470 : /* Sleep at least until estimated real start of hw vblank */
471 0 : min_udelay = (-hpos + 1) * max(vblank->linedur_ns / 1000, 5);
472 0 : if (min_udelay > vblank->framedur_ns / 2000) {
473 : /* Don't wait ridiculously long - something is wrong */
474 : repcnt = 0;
475 0 : break;
476 : }
477 0 : spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
478 0 : usleep_range(min_udelay, 2 * min_udelay);
479 0 : spin_lock_irqsave(&crtc->dev->event_lock, flags);
480 : };
481 :
482 : if (!repcnt)
483 : DRM_DEBUG_DRIVER("Delay problem on crtc %d: min_udelay %d, "
484 : "framedur %d, linedur %d, stat %d, vpos %d, "
485 : "hpos %d\n", work->crtc_id, min_udelay,
486 : vblank->framedur_ns / 1000,
487 : vblank->linedur_ns / 1000, stat, vpos, hpos);
488 :
489 : /* do the flip (mmio) */
490 0 : radeon_page_flip(rdev, radeon_crtc->crtc_id, work->base);
491 :
492 0 : radeon_crtc->flip_status = RADEON_FLIP_SUBMITTED;
493 0 : spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
494 0 : up_read(&rdev->exclusive_lock);
495 0 : }
496 :
497 0 : static int radeon_crtc_page_flip(struct drm_crtc *crtc,
498 : struct drm_framebuffer *fb,
499 : struct drm_pending_vblank_event *event,
500 : uint32_t page_flip_flags)
501 : {
502 0 : struct drm_device *dev = crtc->dev;
503 0 : struct radeon_device *rdev = dev->dev_private;
504 0 : struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
505 : struct radeon_framebuffer *old_radeon_fb;
506 : struct radeon_framebuffer *new_radeon_fb;
507 : struct drm_gem_object *obj;
508 : struct radeon_flip_work *work;
509 : struct radeon_bo *new_rbo;
510 0 : uint32_t tiling_flags, pitch_pixels;
511 0 : uint64_t base;
512 : unsigned long flags;
513 : int r;
514 :
515 0 : work = kzalloc(sizeof *work, GFP_KERNEL);
516 0 : if (work == NULL)
517 0 : return -ENOMEM;
518 :
519 0 : INIT_WORK(&work->flip_work, radeon_flip_work_func);
520 0 : INIT_WORK(&work->unpin_work, radeon_unpin_work_func);
521 :
522 0 : work->rdev = rdev;
523 0 : work->crtc_id = radeon_crtc->crtc_id;
524 0 : work->event = event;
525 :
526 : /* schedule unpin of the old buffer */
527 0 : old_radeon_fb = to_radeon_framebuffer(crtc->primary->fb);
528 0 : obj = old_radeon_fb->obj;
529 :
530 : /* take a reference to the old object */
531 0 : drm_gem_object_reference(obj);
532 0 : work->old_rbo = gem_to_radeon_bo(obj);
533 :
534 0 : new_radeon_fb = to_radeon_framebuffer(fb);
535 0 : obj = new_radeon_fb->obj;
536 0 : new_rbo = gem_to_radeon_bo(obj);
537 :
538 : /* pin the new buffer */
539 : DRM_DEBUG_DRIVER("flip-ioctl() cur_rbo = %p, new_rbo = %p\n",
540 : work->old_rbo, new_rbo);
541 :
542 0 : r = radeon_bo_reserve(new_rbo, false);
543 0 : if (unlikely(r != 0)) {
544 0 : DRM_ERROR("failed to reserve new rbo buffer before flip\n");
545 0 : goto cleanup;
546 : }
547 : /* Only 27 bit offset for legacy CRTC */
548 0 : r = radeon_bo_pin_restricted(new_rbo, RADEON_GEM_DOMAIN_VRAM,
549 0 : ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27, &base);
550 0 : if (unlikely(r != 0)) {
551 0 : radeon_bo_unreserve(new_rbo);
552 : r = -EINVAL;
553 0 : DRM_ERROR("failed to pin new rbo buffer before flip\n");
554 0 : goto cleanup;
555 : }
556 0 : work->fence = fence_get(reservation_object_get_excl(new_rbo->tbo.resv));
557 0 : radeon_bo_get_tiling_flags(new_rbo, &tiling_flags, NULL);
558 0 : radeon_bo_unreserve(new_rbo);
559 :
560 0 : if (!ASIC_IS_AVIVO(rdev)) {
561 : /* crtc offset is from display base addr not FB location */
562 0 : base -= radeon_crtc->legacy_display_base_addr;
563 0 : pitch_pixels = fb->pitches[0] / (fb->bits_per_pixel / 8);
564 :
565 0 : if (tiling_flags & RADEON_TILING_MACRO) {
566 0 : if (ASIC_IS_R300(rdev)) {
567 0 : base &= ~0x7ff;
568 0 : } else {
569 0 : int byteshift = fb->bits_per_pixel >> 4;
570 0 : int tile_addr = (((crtc->y >> 3) * pitch_pixels + crtc->x) >> (8 - byteshift)) << 11;
571 0 : base += tile_addr + ((crtc->x << byteshift) % 256) + ((crtc->y % 8) << 8);
572 : }
573 : } else {
574 0 : int offset = crtc->y * pitch_pixels + crtc->x;
575 0 : switch (fb->bits_per_pixel) {
576 : case 8:
577 : default:
578 : offset *= 1;
579 0 : break;
580 : case 15:
581 : case 16:
582 0 : offset *= 2;
583 0 : break;
584 : case 24:
585 0 : offset *= 3;
586 0 : break;
587 : case 32:
588 0 : offset *= 4;
589 0 : break;
590 : }
591 0 : base += offset;
592 : }
593 0 : base &= ~7;
594 0 : }
595 0 : work->base = base;
596 :
597 0 : r = drm_vblank_get(crtc->dev, radeon_crtc->crtc_id);
598 0 : if (r) {
599 0 : DRM_ERROR("failed to get vblank before flip\n");
600 0 : goto pflip_cleanup;
601 : }
602 :
603 : /* We borrow the event spin lock for protecting flip_work */
604 0 : spin_lock_irqsave(&crtc->dev->event_lock, flags);
605 :
606 0 : if (radeon_crtc->flip_status != RADEON_FLIP_NONE) {
607 : DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
608 0 : spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
609 : r = -EBUSY;
610 : goto vblank_cleanup;
611 : }
612 0 : radeon_crtc->flip_status = RADEON_FLIP_PENDING;
613 0 : radeon_crtc->flip_work = work;
614 :
615 : /* update crtc fb */
616 0 : crtc->primary->fb = fb;
617 :
618 0 : spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
619 :
620 0 : queue_work(radeon_crtc->flip_queue, &work->flip_work);
621 0 : return 0;
622 :
623 : vblank_cleanup:
624 0 : drm_vblank_put(crtc->dev, radeon_crtc->crtc_id);
625 :
626 : pflip_cleanup:
627 0 : if (unlikely(radeon_bo_reserve(new_rbo, false) != 0)) {
628 0 : DRM_ERROR("failed to reserve new rbo in error path\n");
629 0 : goto cleanup;
630 : }
631 0 : if (unlikely(radeon_bo_unpin(new_rbo) != 0)) {
632 0 : DRM_ERROR("failed to unpin new rbo in error path\n");
633 0 : }
634 0 : radeon_bo_unreserve(new_rbo);
635 :
636 : cleanup:
637 0 : drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
638 0 : fence_put(work->fence);
639 0 : kfree(work);
640 0 : return r;
641 0 : }
642 :
643 : static int
644 0 : radeon_crtc_set_config(struct drm_mode_set *set)
645 : {
646 : struct drm_device *dev;
647 : struct radeon_device *rdev;
648 : struct drm_crtc *crtc;
649 : bool active = false;
650 : int ret;
651 :
652 0 : if (!set || !set->crtc)
653 0 : return -EINVAL;
654 :
655 0 : dev = set->crtc->dev;
656 :
657 0 : ret = pm_runtime_get_sync(dev->dev);
658 0 : if (ret < 0)
659 0 : return ret;
660 :
661 0 : ret = drm_crtc_helper_set_config(set);
662 :
663 0 : list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
664 0 : if (crtc->enabled)
665 0 : active = true;
666 :
667 : pm_runtime_mark_last_busy(dev->dev);
668 :
669 0 : rdev = dev->dev_private;
670 : /* if we have active crtcs and we don't have a power ref,
671 : take the current one */
672 0 : if (active && !rdev->have_disp_power_ref) {
673 0 : rdev->have_disp_power_ref = true;
674 0 : return ret;
675 : }
676 : /* if we have no active crtcs, then drop the power ref
677 : we got before */
678 0 : if (!active && rdev->have_disp_power_ref) {
679 : pm_runtime_put_autosuspend(dev->dev);
680 0 : rdev->have_disp_power_ref = false;
681 0 : }
682 :
683 : /* drop the power reference we got coming in here */
684 : pm_runtime_put_autosuspend(dev->dev);
685 0 : return ret;
686 0 : }
687 : static const struct drm_crtc_funcs radeon_crtc_funcs = {
688 : .cursor_set2 = radeon_crtc_cursor_set2,
689 : .cursor_move = radeon_crtc_cursor_move,
690 : .gamma_set = radeon_crtc_gamma_set,
691 : .set_config = radeon_crtc_set_config,
692 : .destroy = radeon_crtc_destroy,
693 : .page_flip = radeon_crtc_page_flip,
694 : };
695 :
696 0 : static void radeon_crtc_init(struct drm_device *dev, int index)
697 : {
698 0 : struct radeon_device *rdev = dev->dev_private;
699 : struct radeon_crtc *radeon_crtc;
700 : int i;
701 :
702 0 : radeon_crtc = kzalloc(sizeof(struct radeon_crtc) + (RADEONFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
703 0 : if (radeon_crtc == NULL)
704 0 : return;
705 :
706 0 : drm_crtc_init(dev, &radeon_crtc->base, &radeon_crtc_funcs);
707 :
708 0 : drm_mode_crtc_set_gamma_size(&radeon_crtc->base, 256);
709 0 : radeon_crtc->crtc_id = index;
710 0 : radeon_crtc->flip_queue = create_singlethread_workqueue("radeon-crtc");
711 0 : rdev->mode_info.crtcs[index] = radeon_crtc;
712 :
713 0 : if (rdev->family >= CHIP_BONAIRE) {
714 0 : radeon_crtc->max_cursor_width = CIK_CURSOR_WIDTH;
715 0 : radeon_crtc->max_cursor_height = CIK_CURSOR_HEIGHT;
716 0 : } else {
717 0 : radeon_crtc->max_cursor_width = CURSOR_WIDTH;
718 0 : radeon_crtc->max_cursor_height = CURSOR_HEIGHT;
719 : }
720 0 : dev->mode_config.cursor_width = radeon_crtc->max_cursor_width;
721 0 : dev->mode_config.cursor_height = radeon_crtc->max_cursor_height;
722 :
723 : #if 0
724 : radeon_crtc->mode_set.crtc = &radeon_crtc->base;
725 : radeon_crtc->mode_set.connectors = (struct drm_connector **)(radeon_crtc + 1);
726 : radeon_crtc->mode_set.num_connectors = 0;
727 : #endif
728 :
729 0 : for (i = 0; i < 256; i++) {
730 0 : radeon_crtc->lut_r[i] = rasops_cmap[3 * i] << 2;
731 0 : radeon_crtc->lut_g[i] = rasops_cmap[(3 * i) + 1] << 2;
732 0 : radeon_crtc->lut_b[i] = rasops_cmap[(3 * i) + 2] << 2;
733 : }
734 :
735 0 : if (rdev->is_atom_bios && (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom))
736 0 : radeon_atombios_init_crtc(dev, radeon_crtc);
737 : else
738 0 : radeon_legacy_init_crtc(dev, radeon_crtc);
739 0 : }
740 :
741 : #ifdef DRMDEBUG
742 : static const char *encoder_names[38] = {
743 : "NONE",
744 : "INTERNAL_LVDS",
745 : "INTERNAL_TMDS1",
746 : "INTERNAL_TMDS2",
747 : "INTERNAL_DAC1",
748 : "INTERNAL_DAC2",
749 : "INTERNAL_SDVOA",
750 : "INTERNAL_SDVOB",
751 : "SI170B",
752 : "CH7303",
753 : "CH7301",
754 : "INTERNAL_DVO1",
755 : "EXTERNAL_SDVOA",
756 : "EXTERNAL_SDVOB",
757 : "TITFP513",
758 : "INTERNAL_LVTM1",
759 : "VT1623",
760 : "HDMI_SI1930",
761 : "HDMI_INTERNAL",
762 : "INTERNAL_KLDSCP_TMDS1",
763 : "INTERNAL_KLDSCP_DVO1",
764 : "INTERNAL_KLDSCP_DAC1",
765 : "INTERNAL_KLDSCP_DAC2",
766 : "SI178",
767 : "MVPU_FPGA",
768 : "INTERNAL_DDI",
769 : "VT1625",
770 : "HDMI_SI1932",
771 : "DP_AN9801",
772 : "DP_DP501",
773 : "INTERNAL_UNIPHY",
774 : "INTERNAL_KLDSCP_LVTMA",
775 : "INTERNAL_UNIPHY1",
776 : "INTERNAL_UNIPHY2",
777 : "NUTMEG",
778 : "TRAVIS",
779 : "INTERNAL_VCE",
780 : "INTERNAL_UNIPHY3",
781 : };
782 :
783 : static const char *hpd_names[6] = {
784 : "HPD1",
785 : "HPD2",
786 : "HPD3",
787 : "HPD4",
788 : "HPD5",
789 : "HPD6",
790 : };
791 : #endif
792 :
793 0 : static void radeon_print_display_setup(struct drm_device *dev)
794 : {
795 : struct drm_connector *connector;
796 : struct radeon_connector *radeon_connector;
797 : struct drm_encoder *encoder;
798 : struct radeon_encoder *radeon_encoder;
799 : uint32_t devices;
800 : int i = 0;
801 :
802 : DRM_INFO("Radeon Display Connectors\n");
803 0 : list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
804 0 : radeon_connector = to_radeon_connector(connector);
805 : DRM_INFO("Connector %d:\n", i);
806 : DRM_INFO(" %s\n", connector->name);
807 0 : if (radeon_connector->hpd.hpd != RADEON_HPD_NONE)
808 : DRM_INFO(" %s\n", hpd_names[radeon_connector->hpd.hpd]);
809 0 : if (radeon_connector->ddc_bus) {
810 : DRM_INFO(" DDC: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
811 : radeon_connector->ddc_bus->rec.mask_clk_reg,
812 : radeon_connector->ddc_bus->rec.mask_data_reg,
813 : radeon_connector->ddc_bus->rec.a_clk_reg,
814 : radeon_connector->ddc_bus->rec.a_data_reg,
815 : radeon_connector->ddc_bus->rec.en_clk_reg,
816 : radeon_connector->ddc_bus->rec.en_data_reg,
817 : radeon_connector->ddc_bus->rec.y_clk_reg,
818 : radeon_connector->ddc_bus->rec.y_data_reg);
819 0 : if (radeon_connector->router.ddc_valid)
820 : DRM_INFO(" DDC Router 0x%x/0x%x\n",
821 : radeon_connector->router.ddc_mux_control_pin,
822 : radeon_connector->router.ddc_mux_state);
823 0 : if (radeon_connector->router.cd_valid)
824 : DRM_INFO(" Clock/Data Router 0x%x/0x%x\n",
825 : radeon_connector->router.cd_mux_control_pin,
826 : radeon_connector->router.cd_mux_state);
827 0 : } else {
828 : if (connector->connector_type == DRM_MODE_CONNECTOR_VGA ||
829 : connector->connector_type == DRM_MODE_CONNECTOR_DVII ||
830 : connector->connector_type == DRM_MODE_CONNECTOR_DVID ||
831 : connector->connector_type == DRM_MODE_CONNECTOR_DVIA ||
832 : connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
833 : connector->connector_type == DRM_MODE_CONNECTOR_HDMIB)
834 : DRM_INFO(" DDC: no ddc bus - possible BIOS bug - please report to xorg-driver-ati@lists.x.org\n");
835 : }
836 : DRM_INFO(" Encoders:\n");
837 0 : list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
838 0 : radeon_encoder = to_radeon_encoder(encoder);
839 0 : devices = radeon_encoder->devices & radeon_connector->devices;
840 0 : if (devices) {
841 0 : if (devices & ATOM_DEVICE_CRT1_SUPPORT)
842 : DRM_INFO(" CRT1: %s\n", encoder_names[radeon_encoder->encoder_id]);
843 0 : if (devices & ATOM_DEVICE_CRT2_SUPPORT)
844 : DRM_INFO(" CRT2: %s\n", encoder_names[radeon_encoder->encoder_id]);
845 0 : if (devices & ATOM_DEVICE_LCD1_SUPPORT)
846 : DRM_INFO(" LCD1: %s\n", encoder_names[radeon_encoder->encoder_id]);
847 0 : if (devices & ATOM_DEVICE_DFP1_SUPPORT)
848 : DRM_INFO(" DFP1: %s\n", encoder_names[radeon_encoder->encoder_id]);
849 0 : if (devices & ATOM_DEVICE_DFP2_SUPPORT)
850 : DRM_INFO(" DFP2: %s\n", encoder_names[radeon_encoder->encoder_id]);
851 0 : if (devices & ATOM_DEVICE_DFP3_SUPPORT)
852 : DRM_INFO(" DFP3: %s\n", encoder_names[radeon_encoder->encoder_id]);
853 0 : if (devices & ATOM_DEVICE_DFP4_SUPPORT)
854 : DRM_INFO(" DFP4: %s\n", encoder_names[radeon_encoder->encoder_id]);
855 0 : if (devices & ATOM_DEVICE_DFP5_SUPPORT)
856 : DRM_INFO(" DFP5: %s\n", encoder_names[radeon_encoder->encoder_id]);
857 0 : if (devices & ATOM_DEVICE_DFP6_SUPPORT)
858 : DRM_INFO(" DFP6: %s\n", encoder_names[radeon_encoder->encoder_id]);
859 0 : if (devices & ATOM_DEVICE_TV1_SUPPORT)
860 : DRM_INFO(" TV1: %s\n", encoder_names[radeon_encoder->encoder_id]);
861 0 : if (devices & ATOM_DEVICE_CV_SUPPORT)
862 : DRM_INFO(" CV: %s\n", encoder_names[radeon_encoder->encoder_id]);
863 0 : }
864 : }
865 0 : i++;
866 : }
867 0 : }
868 :
869 0 : static bool radeon_setup_enc_conn(struct drm_device *dev)
870 : {
871 0 : struct radeon_device *rdev = dev->dev_private;
872 : bool ret = false;
873 :
874 0 : if (rdev->bios) {
875 0 : if (rdev->is_atom_bios) {
876 0 : ret = radeon_get_atom_connector_info_from_supported_devices_table(dev);
877 0 : if (ret == false)
878 0 : ret = radeon_get_atom_connector_info_from_object_table(dev);
879 : } else {
880 0 : ret = radeon_get_legacy_connector_info_from_bios(dev);
881 0 : if (ret == false)
882 0 : ret = radeon_get_legacy_connector_info_from_table(dev);
883 : }
884 : } else {
885 0 : if (!ASIC_IS_AVIVO(rdev))
886 0 : ret = radeon_get_legacy_connector_info_from_table(dev);
887 : }
888 0 : if (ret) {
889 0 : radeon_setup_encoder_clones(dev);
890 0 : radeon_print_display_setup(dev);
891 0 : }
892 :
893 0 : return ret;
894 : }
895 :
896 : /* avivo */
897 :
898 : /**
899 : * avivo_reduce_ratio - fractional number reduction
900 : *
901 : * @nom: nominator
902 : * @den: denominator
903 : * @nom_min: minimum value for nominator
904 : * @den_min: minimum value for denominator
905 : *
906 : * Find the greatest common divisor and apply it on both nominator and
907 : * denominator, but make nominator and denominator are at least as large
908 : * as their minimum values.
909 : */
910 0 : static void avivo_reduce_ratio(unsigned *nom, unsigned *den,
911 : unsigned nom_min, unsigned den_min)
912 : {
913 : unsigned tmp;
914 :
915 : /* reduce the numbers to a simpler ratio */
916 0 : tmp = gcd(*nom, *den);
917 0 : *nom /= tmp;
918 0 : *den /= tmp;
919 :
920 : /* make sure nominator is large enough */
921 0 : if (*nom < nom_min) {
922 0 : tmp = DIV_ROUND_UP(nom_min, *nom);
923 0 : *nom *= tmp;
924 0 : *den *= tmp;
925 0 : }
926 :
927 : /* make sure the denominator is large enough */
928 0 : if (*den < den_min) {
929 0 : tmp = DIV_ROUND_UP(den_min, *den);
930 0 : *nom *= tmp;
931 0 : *den *= tmp;
932 0 : }
933 0 : }
934 :
935 : /**
936 : * avivo_get_fb_ref_div - feedback and ref divider calculation
937 : *
938 : * @nom: nominator
939 : * @den: denominator
940 : * @post_div: post divider
941 : * @fb_div_max: feedback divider maximum
942 : * @ref_div_max: reference divider maximum
943 : * @fb_div: resulting feedback divider
944 : * @ref_div: resulting reference divider
945 : *
946 : * Calculate feedback and reference divider for a given post divider. Makes
947 : * sure we stay within the limits.
948 : */
949 0 : static void avivo_get_fb_ref_div(unsigned nom, unsigned den, unsigned post_div,
950 : unsigned fb_div_max, unsigned ref_div_max,
951 : unsigned *fb_div, unsigned *ref_div)
952 : {
953 : /* limit reference * post divider to a maximum */
954 0 : ref_div_max = max(min(100 / post_div, ref_div_max), 1u);
955 :
956 : /* get matching reference and feedback divider */
957 0 : *ref_div = min(max(DIV_ROUND_CLOSEST(den, post_div), 1u), ref_div_max);
958 0 : *fb_div = DIV_ROUND_CLOSEST(nom * *ref_div * post_div, den);
959 :
960 : /* limit fb divider to its maximum */
961 0 : if (*fb_div > fb_div_max) {
962 0 : *ref_div = DIV_ROUND_CLOSEST(*ref_div * fb_div_max, *fb_div);
963 0 : *fb_div = fb_div_max;
964 0 : }
965 0 : }
966 :
967 : /**
968 : * radeon_compute_pll_avivo - compute PLL paramaters
969 : *
970 : * @pll: information about the PLL
971 : * @dot_clock_p: resulting pixel clock
972 : * fb_div_p: resulting feedback divider
973 : * frac_fb_div_p: fractional part of the feedback divider
974 : * ref_div_p: resulting reference divider
975 : * post_div_p: resulting reference divider
976 : *
977 : * Try to calculate the PLL parameters to generate the given frequency:
978 : * dot_clock = (ref_freq * feedback_div) / (ref_div * post_div)
979 : */
980 0 : void radeon_compute_pll_avivo(struct radeon_pll *pll,
981 : u32 freq,
982 : u32 *dot_clock_p,
983 : u32 *fb_div_p,
984 : u32 *frac_fb_div_p,
985 : u32 *ref_div_p,
986 : u32 *post_div_p)
987 : {
988 0 : unsigned target_clock = pll->flags & RADEON_PLL_USE_FRAC_FB_DIV ?
989 0 : freq : freq / 10;
990 :
991 0 : unsigned fb_div_min, fb_div_max, fb_div;
992 : unsigned post_div_min, post_div_max, post_div;
993 0 : unsigned ref_div_min, ref_div_max, ref_div;
994 : unsigned post_div_best, diff_best;
995 0 : unsigned nom, den;
996 :
997 : /* determine allowed feedback divider range */
998 0 : fb_div_min = pll->min_feedback_div;
999 0 : fb_div_max = pll->max_feedback_div;
1000 :
1001 0 : if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) {
1002 0 : fb_div_min *= 10;
1003 0 : fb_div_max *= 10;
1004 0 : }
1005 :
1006 : /* determine allowed ref divider range */
1007 0 : if (pll->flags & RADEON_PLL_USE_REF_DIV)
1008 0 : ref_div_min = pll->reference_div;
1009 : else
1010 0 : ref_div_min = pll->min_ref_div;
1011 :
1012 0 : if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV &&
1013 0 : pll->flags & RADEON_PLL_USE_REF_DIV)
1014 0 : ref_div_max = pll->reference_div;
1015 0 : else if (pll->flags & RADEON_PLL_PREFER_MINM_OVER_MAXP)
1016 : /* fix for problems on RS880 */
1017 0 : ref_div_max = min(pll->max_ref_div, 7u);
1018 : else
1019 : ref_div_max = pll->max_ref_div;
1020 :
1021 : /* determine allowed post divider range */
1022 0 : if (pll->flags & RADEON_PLL_USE_POST_DIV) {
1023 0 : post_div_min = pll->post_div;
1024 : post_div_max = pll->post_div;
1025 0 : } else {
1026 : unsigned vco_min, vco_max;
1027 :
1028 0 : if (pll->flags & RADEON_PLL_IS_LCD) {
1029 0 : vco_min = pll->lcd_pll_out_min;
1030 0 : vco_max = pll->lcd_pll_out_max;
1031 0 : } else {
1032 0 : vco_min = pll->pll_out_min;
1033 0 : vco_max = pll->pll_out_max;
1034 : }
1035 :
1036 0 : if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) {
1037 0 : vco_min *= 10;
1038 0 : vco_max *= 10;
1039 0 : }
1040 :
1041 0 : post_div_min = vco_min / target_clock;
1042 0 : if ((target_clock * post_div_min) < vco_min)
1043 0 : ++post_div_min;
1044 0 : if (post_div_min < pll->min_post_div)
1045 0 : post_div_min = pll->min_post_div;
1046 :
1047 0 : post_div_max = vco_max / target_clock;
1048 0 : if ((target_clock * post_div_max) > vco_max)
1049 0 : --post_div_max;
1050 0 : if (post_div_max > pll->max_post_div)
1051 0 : post_div_max = pll->max_post_div;
1052 : }
1053 :
1054 : /* represent the searched ratio as fractional number */
1055 0 : nom = target_clock;
1056 0 : den = pll->reference_freq;
1057 :
1058 : /* reduce the numbers to a simpler ratio */
1059 0 : avivo_reduce_ratio(&nom, &den, fb_div_min, post_div_min);
1060 :
1061 : /* now search for a post divider */
1062 0 : if (pll->flags & RADEON_PLL_PREFER_MINM_OVER_MAXP)
1063 0 : post_div_best = post_div_min;
1064 : else
1065 : post_div_best = post_div_max;
1066 : diff_best = ~0;
1067 :
1068 0 : for (post_div = post_div_min; post_div <= post_div_max; ++post_div) {
1069 : unsigned diff;
1070 0 : avivo_get_fb_ref_div(nom, den, post_div, fb_div_max,
1071 : ref_div_max, &fb_div, &ref_div);
1072 0 : diff = abs(target_clock - (pll->reference_freq * fb_div) /
1073 0 : (ref_div * post_div));
1074 :
1075 0 : if (diff < diff_best || (diff == diff_best &&
1076 0 : !(pll->flags & RADEON_PLL_PREFER_MINM_OVER_MAXP))) {
1077 :
1078 : post_div_best = post_div;
1079 : diff_best = diff;
1080 0 : }
1081 : }
1082 : post_div = post_div_best;
1083 :
1084 : /* get the feedback and reference divider for the optimal value */
1085 0 : avivo_get_fb_ref_div(nom, den, post_div, fb_div_max, ref_div_max,
1086 : &fb_div, &ref_div);
1087 :
1088 : /* reduce the numbers to a simpler ratio once more */
1089 : /* this also makes sure that the reference divider is large enough */
1090 0 : avivo_reduce_ratio(&fb_div, &ref_div, fb_div_min, ref_div_min);
1091 :
1092 : /* avoid high jitter with small fractional dividers */
1093 0 : if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV && (fb_div % 10)) {
1094 0 : fb_div_min = max(fb_div_min, (9 - (fb_div % 10)) * 20 + 50);
1095 0 : if (fb_div < fb_div_min) {
1096 0 : unsigned tmp = DIV_ROUND_UP(fb_div_min, fb_div);
1097 0 : fb_div *= tmp;
1098 0 : ref_div *= tmp;
1099 0 : }
1100 : }
1101 :
1102 : /* and finally save the result */
1103 0 : if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) {
1104 0 : *fb_div_p = fb_div / 10;
1105 0 : *frac_fb_div_p = fb_div % 10;
1106 0 : } else {
1107 0 : *fb_div_p = fb_div;
1108 0 : *frac_fb_div_p = 0;
1109 : }
1110 :
1111 0 : *dot_clock_p = ((pll->reference_freq * *fb_div_p * 10) +
1112 0 : (pll->reference_freq * *frac_fb_div_p)) /
1113 0 : (ref_div * post_div * 10);
1114 0 : *ref_div_p = ref_div;
1115 0 : *post_div_p = post_div;
1116 :
1117 : DRM_DEBUG_KMS("%d - %d, pll dividers - fb: %d.%d ref: %d, post %d\n",
1118 : freq, *dot_clock_p * 10, *fb_div_p, *frac_fb_div_p,
1119 : ref_div, post_div);
1120 0 : }
1121 :
1122 : /* pre-avivo */
1123 0 : static inline uint32_t radeon_div(uint64_t n, uint32_t d)
1124 : {
1125 : uint64_t mod;
1126 :
1127 0 : n += d / 2;
1128 :
1129 0 : mod = do_div(n, d);
1130 0 : return n;
1131 : }
1132 :
1133 0 : void radeon_compute_pll_legacy(struct radeon_pll *pll,
1134 : uint64_t freq,
1135 : uint32_t *dot_clock_p,
1136 : uint32_t *fb_div_p,
1137 : uint32_t *frac_fb_div_p,
1138 : uint32_t *ref_div_p,
1139 : uint32_t *post_div_p)
1140 : {
1141 0 : uint32_t min_ref_div = pll->min_ref_div;
1142 0 : uint32_t max_ref_div = pll->max_ref_div;
1143 0 : uint32_t min_post_div = pll->min_post_div;
1144 0 : uint32_t max_post_div = pll->max_post_div;
1145 : uint32_t min_fractional_feed_div = 0;
1146 : uint32_t max_fractional_feed_div = 0;
1147 0 : uint32_t best_vco = pll->best_vco;
1148 : uint32_t best_post_div = 1;
1149 : uint32_t best_ref_div = 1;
1150 : uint32_t best_feedback_div = 1;
1151 : uint32_t best_frac_feedback_div = 0;
1152 : uint32_t best_freq = -1;
1153 : uint32_t best_error = 0xffffffff;
1154 : uint32_t best_vco_diff = 1;
1155 : uint32_t post_div;
1156 : u32 pll_out_min, pll_out_max;
1157 :
1158 : DRM_DEBUG_KMS("PLL freq %llu %u %u\n", freq, pll->min_ref_div, pll->max_ref_div);
1159 0 : freq = freq * 1000;
1160 :
1161 0 : if (pll->flags & RADEON_PLL_IS_LCD) {
1162 0 : pll_out_min = pll->lcd_pll_out_min;
1163 0 : pll_out_max = pll->lcd_pll_out_max;
1164 0 : } else {
1165 0 : pll_out_min = pll->pll_out_min;
1166 0 : pll_out_max = pll->pll_out_max;
1167 : }
1168 :
1169 0 : if (pll_out_min > 64800)
1170 0 : pll_out_min = 64800;
1171 :
1172 0 : if (pll->flags & RADEON_PLL_USE_REF_DIV)
1173 0 : min_ref_div = max_ref_div = pll->reference_div;
1174 : else {
1175 0 : while (min_ref_div < max_ref_div-1) {
1176 0 : uint32_t mid = (min_ref_div + max_ref_div) / 2;
1177 0 : uint32_t pll_in = pll->reference_freq / mid;
1178 0 : if (pll_in < pll->pll_in_min)
1179 0 : max_ref_div = mid;
1180 0 : else if (pll_in > pll->pll_in_max)
1181 : min_ref_div = mid;
1182 : else
1183 0 : break;
1184 0 : }
1185 : }
1186 :
1187 0 : if (pll->flags & RADEON_PLL_USE_POST_DIV)
1188 0 : min_post_div = max_post_div = pll->post_div;
1189 :
1190 0 : if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) {
1191 0 : min_fractional_feed_div = pll->min_frac_feedback_div;
1192 0 : max_fractional_feed_div = pll->max_frac_feedback_div;
1193 0 : }
1194 :
1195 0 : for (post_div = max_post_div; post_div >= min_post_div; --post_div) {
1196 : uint32_t ref_div;
1197 :
1198 0 : if ((pll->flags & RADEON_PLL_NO_ODD_POST_DIV) && (post_div & 1))
1199 0 : continue;
1200 :
1201 : /* legacy radeons only have a few post_divs */
1202 0 : if (pll->flags & RADEON_PLL_LEGACY) {
1203 0 : if ((post_div == 5) ||
1204 0 : (post_div == 7) ||
1205 0 : (post_div == 9) ||
1206 0 : (post_div == 10) ||
1207 0 : (post_div == 11) ||
1208 0 : (post_div == 13) ||
1209 0 : (post_div == 14) ||
1210 0 : (post_div == 15))
1211 0 : continue;
1212 : }
1213 :
1214 0 : for (ref_div = min_ref_div; ref_div <= max_ref_div; ++ref_div) {
1215 : uint32_t feedback_div, current_freq = 0, error, vco_diff;
1216 0 : uint32_t pll_in = pll->reference_freq / ref_div;
1217 0 : uint32_t min_feed_div = pll->min_feedback_div;
1218 0 : uint32_t max_feed_div = pll->max_feedback_div + 1;
1219 :
1220 0 : if (pll_in < pll->pll_in_min || pll_in > pll->pll_in_max)
1221 0 : continue;
1222 :
1223 0 : while (min_feed_div < max_feed_div) {
1224 : uint32_t vco;
1225 : uint32_t min_frac_feed_div = min_fractional_feed_div;
1226 0 : uint32_t max_frac_feed_div = max_fractional_feed_div + 1;
1227 : uint32_t frac_feedback_div;
1228 : uint64_t tmp;
1229 :
1230 0 : feedback_div = (min_feed_div + max_feed_div) / 2;
1231 :
1232 0 : tmp = (uint64_t)pll->reference_freq * feedback_div;
1233 0 : vco = radeon_div(tmp, ref_div);
1234 :
1235 0 : if (vco < pll_out_min) {
1236 0 : min_feed_div = feedback_div + 1;
1237 0 : continue;
1238 0 : } else if (vco > pll_out_max) {
1239 : max_feed_div = feedback_div;
1240 0 : continue;
1241 : }
1242 :
1243 0 : while (min_frac_feed_div < max_frac_feed_div) {
1244 0 : frac_feedback_div = (min_frac_feed_div + max_frac_feed_div) / 2;
1245 0 : tmp = (uint64_t)pll->reference_freq * 10000 * feedback_div;
1246 0 : tmp += (uint64_t)pll->reference_freq * 1000 * frac_feedback_div;
1247 0 : current_freq = radeon_div(tmp, ref_div * post_div);
1248 :
1249 0 : if (pll->flags & RADEON_PLL_PREFER_CLOSEST_LOWER) {
1250 0 : if (freq < current_freq)
1251 0 : error = 0xffffffff;
1252 : else
1253 0 : error = freq - current_freq;
1254 : } else
1255 0 : error = abs(current_freq - freq);
1256 0 : vco_diff = abs(vco - best_vco);
1257 :
1258 0 : if ((best_vco == 0 && error < best_error) ||
1259 0 : (best_vco != 0 &&
1260 0 : ((best_error > 100 && error < best_error - 100) ||
1261 0 : (abs(error - best_error) < 100 && vco_diff < best_vco_diff)))) {
1262 : best_post_div = post_div;
1263 : best_ref_div = ref_div;
1264 : best_feedback_div = feedback_div;
1265 : best_frac_feedback_div = frac_feedback_div;
1266 : best_freq = current_freq;
1267 : best_error = error;
1268 : best_vco_diff = vco_diff;
1269 0 : } else if (current_freq == freq) {
1270 0 : if (best_freq == -1) {
1271 : best_post_div = post_div;
1272 : best_ref_div = ref_div;
1273 : best_feedback_div = feedback_div;
1274 : best_frac_feedback_div = frac_feedback_div;
1275 : best_freq = current_freq;
1276 : best_error = error;
1277 : best_vco_diff = vco_diff;
1278 0 : } else if (((pll->flags & RADEON_PLL_PREFER_LOW_REF_DIV) && (ref_div < best_ref_div)) ||
1279 0 : ((pll->flags & RADEON_PLL_PREFER_HIGH_REF_DIV) && (ref_div > best_ref_div)) ||
1280 0 : ((pll->flags & RADEON_PLL_PREFER_LOW_FB_DIV) && (feedback_div < best_feedback_div)) ||
1281 0 : ((pll->flags & RADEON_PLL_PREFER_HIGH_FB_DIV) && (feedback_div > best_feedback_div)) ||
1282 0 : ((pll->flags & RADEON_PLL_PREFER_LOW_POST_DIV) && (post_div < best_post_div)) ||
1283 0 : ((pll->flags & RADEON_PLL_PREFER_HIGH_POST_DIV) && (post_div > best_post_div))) {
1284 : best_post_div = post_div;
1285 : best_ref_div = ref_div;
1286 : best_feedback_div = feedback_div;
1287 : best_frac_feedback_div = frac_feedback_div;
1288 : best_freq = current_freq;
1289 : best_error = error;
1290 : best_vco_diff = vco_diff;
1291 0 : }
1292 : }
1293 0 : if (current_freq < freq)
1294 0 : min_frac_feed_div = frac_feedback_div + 1;
1295 : else
1296 : max_frac_feed_div = frac_feedback_div;
1297 : }
1298 0 : if (current_freq < freq)
1299 0 : min_feed_div = feedback_div + 1;
1300 : else
1301 : max_feed_div = feedback_div;
1302 0 : }
1303 0 : }
1304 0 : }
1305 :
1306 0 : *dot_clock_p = best_freq / 10000;
1307 0 : *fb_div_p = best_feedback_div;
1308 0 : *frac_fb_div_p = best_frac_feedback_div;
1309 0 : *ref_div_p = best_ref_div;
1310 0 : *post_div_p = best_post_div;
1311 : DRM_DEBUG_KMS("%lld %d, pll dividers - fb: %d.%d ref: %d, post %d\n",
1312 : (long long)freq,
1313 : best_freq / 1000, best_feedback_div, best_frac_feedback_div,
1314 : best_ref_div, best_post_div);
1315 :
1316 0 : }
1317 :
1318 0 : static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb)
1319 : {
1320 0 : struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb);
1321 :
1322 0 : if (radeon_fb->obj) {
1323 0 : drm_gem_object_unreference_unlocked(radeon_fb->obj);
1324 0 : }
1325 0 : drm_framebuffer_cleanup(fb);
1326 0 : kfree(radeon_fb);
1327 0 : }
1328 :
1329 0 : static int radeon_user_framebuffer_create_handle(struct drm_framebuffer *fb,
1330 : struct drm_file *file_priv,
1331 : unsigned int *handle)
1332 : {
1333 0 : struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb);
1334 :
1335 0 : return drm_gem_handle_create(file_priv, radeon_fb->obj, handle);
1336 : }
1337 :
1338 : static const struct drm_framebuffer_funcs radeon_fb_funcs = {
1339 : .destroy = radeon_user_framebuffer_destroy,
1340 : .create_handle = radeon_user_framebuffer_create_handle,
1341 : };
1342 :
1343 : int
1344 0 : radeon_framebuffer_init(struct drm_device *dev,
1345 : struct radeon_framebuffer *rfb,
1346 : struct drm_mode_fb_cmd2 *mode_cmd,
1347 : struct drm_gem_object *obj)
1348 : {
1349 : int ret;
1350 0 : rfb->obj = obj;
1351 0 : drm_helper_mode_fill_fb_struct(&rfb->base, mode_cmd);
1352 0 : ret = drm_framebuffer_init(dev, &rfb->base, &radeon_fb_funcs);
1353 0 : if (ret) {
1354 0 : rfb->obj = NULL;
1355 0 : return ret;
1356 : }
1357 0 : return 0;
1358 0 : }
1359 :
1360 : static struct drm_framebuffer *
1361 0 : radeon_user_framebuffer_create(struct drm_device *dev,
1362 : struct drm_file *file_priv,
1363 : struct drm_mode_fb_cmd2 *mode_cmd)
1364 : {
1365 : struct drm_gem_object *obj;
1366 : struct radeon_framebuffer *radeon_fb;
1367 : int ret;
1368 :
1369 0 : obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]);
1370 0 : if (obj == NULL) {
1371 0 : dev_err(&dev->pdev->dev, "No GEM object associated to handle 0x%08X, "
1372 : "can't create framebuffer\n", mode_cmd->handles[0]);
1373 0 : return ERR_PTR(-ENOENT);
1374 : }
1375 :
1376 : #ifdef notyet
1377 : /* Handle is imported dma-buf, so cannot be migrated to VRAM for scanout */
1378 : if (obj->import_attach) {
1379 : DRM_DEBUG_KMS("Cannot create framebuffer from imported dma_buf\n");
1380 : return ERR_PTR(-EINVAL);
1381 : }
1382 : #endif
1383 :
1384 0 : radeon_fb = kzalloc(sizeof(*radeon_fb), GFP_KERNEL);
1385 0 : if (radeon_fb == NULL) {
1386 0 : drm_gem_object_unreference_unlocked(obj);
1387 0 : return ERR_PTR(-ENOMEM);
1388 : }
1389 :
1390 0 : ret = radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj);
1391 0 : if (ret) {
1392 0 : kfree(radeon_fb);
1393 0 : drm_gem_object_unreference_unlocked(obj);
1394 0 : return ERR_PTR(ret);
1395 : }
1396 :
1397 0 : return &radeon_fb->base;
1398 0 : }
1399 :
1400 0 : static void radeon_output_poll_changed(struct drm_device *dev)
1401 : {
1402 0 : struct radeon_device *rdev = dev->dev_private;
1403 0 : radeon_fb_output_poll_changed(rdev);
1404 0 : }
1405 :
1406 : static const struct drm_mode_config_funcs radeon_mode_funcs = {
1407 : .fb_create = radeon_user_framebuffer_create,
1408 : .output_poll_changed = radeon_output_poll_changed
1409 : };
1410 :
1411 : static struct drm_prop_enum_list radeon_tmds_pll_enum_list[] =
1412 : { { 0, "driver" },
1413 : { 1, "bios" },
1414 : };
1415 :
1416 : static struct drm_prop_enum_list radeon_tv_std_enum_list[] =
1417 : { { TV_STD_NTSC, "ntsc" },
1418 : { TV_STD_PAL, "pal" },
1419 : { TV_STD_PAL_M, "pal-m" },
1420 : { TV_STD_PAL_60, "pal-60" },
1421 : { TV_STD_NTSC_J, "ntsc-j" },
1422 : { TV_STD_SCART_PAL, "scart-pal" },
1423 : { TV_STD_PAL_CN, "pal-cn" },
1424 : { TV_STD_SECAM, "secam" },
1425 : };
1426 :
1427 : static struct drm_prop_enum_list radeon_underscan_enum_list[] =
1428 : { { UNDERSCAN_OFF, "off" },
1429 : { UNDERSCAN_ON, "on" },
1430 : { UNDERSCAN_AUTO, "auto" },
1431 : };
1432 :
1433 : static struct drm_prop_enum_list radeon_audio_enum_list[] =
1434 : { { RADEON_AUDIO_DISABLE, "off" },
1435 : { RADEON_AUDIO_ENABLE, "on" },
1436 : { RADEON_AUDIO_AUTO, "auto" },
1437 : };
1438 :
1439 : /* XXX support different dither options? spatial, temporal, both, etc. */
1440 : static struct drm_prop_enum_list radeon_dither_enum_list[] =
1441 : { { RADEON_FMT_DITHER_DISABLE, "off" },
1442 : { RADEON_FMT_DITHER_ENABLE, "on" },
1443 : };
1444 :
1445 : static struct drm_prop_enum_list radeon_output_csc_enum_list[] =
1446 : { { RADEON_OUTPUT_CSC_BYPASS, "bypass" },
1447 : { RADEON_OUTPUT_CSC_TVRGB, "tvrgb" },
1448 : { RADEON_OUTPUT_CSC_YCBCR601, "ycbcr601" },
1449 : { RADEON_OUTPUT_CSC_YCBCR709, "ycbcr709" },
1450 : };
1451 :
1452 0 : static int radeon_modeset_create_props(struct radeon_device *rdev)
1453 : {
1454 : int sz;
1455 :
1456 0 : if (rdev->is_atom_bios) {
1457 0 : rdev->mode_info.coherent_mode_property =
1458 0 : drm_property_create_range(rdev->ddev, 0 , "coherent", 0, 1);
1459 0 : if (!rdev->mode_info.coherent_mode_property)
1460 0 : return -ENOMEM;
1461 : }
1462 :
1463 0 : if (!ASIC_IS_AVIVO(rdev)) {
1464 : sz = ARRAY_SIZE(radeon_tmds_pll_enum_list);
1465 0 : rdev->mode_info.tmds_pll_property =
1466 0 : drm_property_create_enum(rdev->ddev, 0,
1467 : "tmds_pll",
1468 : radeon_tmds_pll_enum_list, sz);
1469 0 : }
1470 :
1471 0 : rdev->mode_info.load_detect_property =
1472 0 : drm_property_create_range(rdev->ddev, 0, "load detection", 0, 1);
1473 0 : if (!rdev->mode_info.load_detect_property)
1474 0 : return -ENOMEM;
1475 :
1476 0 : drm_mode_create_scaling_mode_property(rdev->ddev);
1477 :
1478 : sz = ARRAY_SIZE(radeon_tv_std_enum_list);
1479 0 : rdev->mode_info.tv_std_property =
1480 0 : drm_property_create_enum(rdev->ddev, 0,
1481 : "tv standard",
1482 : radeon_tv_std_enum_list, sz);
1483 :
1484 : sz = ARRAY_SIZE(radeon_underscan_enum_list);
1485 0 : rdev->mode_info.underscan_property =
1486 0 : drm_property_create_enum(rdev->ddev, 0,
1487 : "underscan",
1488 : radeon_underscan_enum_list, sz);
1489 :
1490 0 : rdev->mode_info.underscan_hborder_property =
1491 0 : drm_property_create_range(rdev->ddev, 0,
1492 : "underscan hborder", 0, 128);
1493 0 : if (!rdev->mode_info.underscan_hborder_property)
1494 0 : return -ENOMEM;
1495 :
1496 0 : rdev->mode_info.underscan_vborder_property =
1497 0 : drm_property_create_range(rdev->ddev, 0,
1498 : "underscan vborder", 0, 128);
1499 0 : if (!rdev->mode_info.underscan_vborder_property)
1500 0 : return -ENOMEM;
1501 :
1502 : sz = ARRAY_SIZE(radeon_audio_enum_list);
1503 0 : rdev->mode_info.audio_property =
1504 0 : drm_property_create_enum(rdev->ddev, 0,
1505 : "audio",
1506 : radeon_audio_enum_list, sz);
1507 :
1508 : sz = ARRAY_SIZE(radeon_dither_enum_list);
1509 0 : rdev->mode_info.dither_property =
1510 0 : drm_property_create_enum(rdev->ddev, 0,
1511 : "dither",
1512 : radeon_dither_enum_list, sz);
1513 :
1514 : sz = ARRAY_SIZE(radeon_output_csc_enum_list);
1515 0 : rdev->mode_info.output_csc_property =
1516 0 : drm_property_create_enum(rdev->ddev, 0,
1517 : "output_csc",
1518 : radeon_output_csc_enum_list, sz);
1519 :
1520 0 : return 0;
1521 0 : }
1522 :
1523 0 : void radeon_update_display_priority(struct radeon_device *rdev)
1524 : {
1525 : /* adjustment options for the display watermarks */
1526 0 : if ((radeon_disp_priority == 0) || (radeon_disp_priority > 2)) {
1527 : /* set display priority to high for r3xx, rv515 chips
1528 : * this avoids flickering due to underflow to the
1529 : * display controllers during heavy acceleration.
1530 : * Don't force high on rs4xx igp chips as it seems to
1531 : * affect the sound card. See kernel bug 15982.
1532 : */
1533 0 : if ((ASIC_IS_R300(rdev) || (rdev->family == CHIP_RV515)) &&
1534 0 : !(rdev->flags & RADEON_IS_IGP))
1535 0 : rdev->disp_priority = 2;
1536 : else
1537 0 : rdev->disp_priority = 0;
1538 : } else
1539 0 : rdev->disp_priority = radeon_disp_priority;
1540 :
1541 0 : }
1542 :
1543 : /*
1544 : * Allocate hdmi structs and determine register offsets
1545 : */
1546 0 : static void radeon_afmt_init(struct radeon_device *rdev)
1547 : {
1548 : int i;
1549 :
1550 0 : for (i = 0; i < RADEON_MAX_AFMT_BLOCKS; i++)
1551 0 : rdev->mode_info.afmt[i] = NULL;
1552 :
1553 0 : if (ASIC_IS_NODCE(rdev)) {
1554 : /* nothing to do */
1555 0 : } else if (ASIC_IS_DCE4(rdev)) {
1556 : static uint32_t eg_offsets[] = {
1557 : EVERGREEN_CRTC0_REGISTER_OFFSET,
1558 : EVERGREEN_CRTC1_REGISTER_OFFSET,
1559 : EVERGREEN_CRTC2_REGISTER_OFFSET,
1560 : EVERGREEN_CRTC3_REGISTER_OFFSET,
1561 : EVERGREEN_CRTC4_REGISTER_OFFSET,
1562 : EVERGREEN_CRTC5_REGISTER_OFFSET,
1563 : 0x13830 - 0x7030,
1564 : };
1565 : int num_afmt;
1566 :
1567 : /* DCE8 has 7 audio blocks tied to DIG encoders */
1568 : /* DCE6 has 6 audio blocks tied to DIG encoders */
1569 : /* DCE4/5 has 6 audio blocks tied to DIG encoders */
1570 : /* DCE4.1 has 2 audio blocks tied to DIG encoders */
1571 0 : if (ASIC_IS_DCE8(rdev))
1572 0 : num_afmt = 7;
1573 0 : else if (ASIC_IS_DCE6(rdev))
1574 0 : num_afmt = 6;
1575 0 : else if (ASIC_IS_DCE5(rdev))
1576 0 : num_afmt = 6;
1577 0 : else if (ASIC_IS_DCE41(rdev))
1578 0 : num_afmt = 2;
1579 : else /* DCE4 */
1580 : num_afmt = 6;
1581 :
1582 0 : BUG_ON(num_afmt > ARRAY_SIZE(eg_offsets));
1583 0 : for (i = 0; i < num_afmt; i++) {
1584 0 : rdev->mode_info.afmt[i] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL);
1585 0 : if (rdev->mode_info.afmt[i]) {
1586 0 : rdev->mode_info.afmt[i]->offset = eg_offsets[i];
1587 0 : rdev->mode_info.afmt[i]->id = i;
1588 0 : }
1589 : }
1590 0 : } else if (ASIC_IS_DCE3(rdev)) {
1591 : /* DCE3.x has 2 audio blocks tied to DIG encoders */
1592 0 : rdev->mode_info.afmt[0] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL);
1593 0 : if (rdev->mode_info.afmt[0]) {
1594 0 : rdev->mode_info.afmt[0]->offset = DCE3_HDMI_OFFSET0;
1595 0 : rdev->mode_info.afmt[0]->id = 0;
1596 0 : }
1597 0 : rdev->mode_info.afmt[1] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL);
1598 0 : if (rdev->mode_info.afmt[1]) {
1599 0 : rdev->mode_info.afmt[1]->offset = DCE3_HDMI_OFFSET1;
1600 0 : rdev->mode_info.afmt[1]->id = 1;
1601 0 : }
1602 0 : } else if (ASIC_IS_DCE2(rdev)) {
1603 : /* DCE2 has at least 1 routable audio block */
1604 0 : rdev->mode_info.afmt[0] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL);
1605 0 : if (rdev->mode_info.afmt[0]) {
1606 0 : rdev->mode_info.afmt[0]->offset = DCE2_HDMI_OFFSET0;
1607 0 : rdev->mode_info.afmt[0]->id = 0;
1608 0 : }
1609 : /* r6xx has 2 routable audio blocks */
1610 0 : if (rdev->family >= CHIP_R600) {
1611 0 : rdev->mode_info.afmt[1] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL);
1612 0 : if (rdev->mode_info.afmt[1]) {
1613 0 : rdev->mode_info.afmt[1]->offset = DCE2_HDMI_OFFSET1;
1614 0 : rdev->mode_info.afmt[1]->id = 1;
1615 0 : }
1616 : }
1617 : }
1618 0 : }
1619 :
1620 0 : static void radeon_afmt_fini(struct radeon_device *rdev)
1621 : {
1622 : int i;
1623 :
1624 0 : for (i = 0; i < RADEON_MAX_AFMT_BLOCKS; i++) {
1625 0 : kfree(rdev->mode_info.afmt[i]);
1626 0 : rdev->mode_info.afmt[i] = NULL;
1627 : }
1628 0 : }
1629 :
1630 0 : int radeon_modeset_init(struct radeon_device *rdev)
1631 : {
1632 : int i;
1633 : int ret;
1634 :
1635 0 : drm_mode_config_init(rdev->ddev);
1636 0 : rdev->mode_info.mode_config_initialized = true;
1637 :
1638 0 : rdev->ddev->mode_config.funcs = &radeon_mode_funcs;
1639 :
1640 0 : if (ASIC_IS_DCE5(rdev)) {
1641 0 : rdev->ddev->mode_config.max_width = 16384;
1642 0 : rdev->ddev->mode_config.max_height = 16384;
1643 0 : } else if (ASIC_IS_AVIVO(rdev)) {
1644 0 : rdev->ddev->mode_config.max_width = 8192;
1645 0 : rdev->ddev->mode_config.max_height = 8192;
1646 0 : } else {
1647 0 : rdev->ddev->mode_config.max_width = 4096;
1648 0 : rdev->ddev->mode_config.max_height = 4096;
1649 : }
1650 :
1651 0 : rdev->ddev->mode_config.preferred_depth = 24;
1652 0 : rdev->ddev->mode_config.prefer_shadow = 1;
1653 :
1654 0 : rdev->ddev->mode_config.fb_base = rdev->mc.aper_base;
1655 :
1656 0 : ret = radeon_modeset_create_props(rdev);
1657 0 : if (ret) {
1658 0 : return ret;
1659 : }
1660 :
1661 : /* init i2c buses */
1662 0 : radeon_i2c_init(rdev);
1663 :
1664 : /* check combios for a valid hardcoded EDID - Sun servers */
1665 0 : if (!rdev->is_atom_bios) {
1666 : /* check for hardcoded EDID in BIOS */
1667 0 : radeon_combios_check_hardcoded_edid(rdev);
1668 0 : }
1669 :
1670 : /* allocate crtcs */
1671 0 : for (i = 0; i < rdev->num_crtc; i++) {
1672 0 : radeon_crtc_init(rdev->ddev, i);
1673 : }
1674 :
1675 : /* okay we should have all the bios connectors */
1676 0 : ret = radeon_setup_enc_conn(rdev->ddev);
1677 0 : if (!ret) {
1678 0 : return ret;
1679 : }
1680 :
1681 : /* init dig PHYs, disp eng pll */
1682 0 : if (rdev->is_atom_bios) {
1683 0 : radeon_atom_encoder_init(rdev);
1684 0 : radeon_atom_disp_eng_pll_init(rdev);
1685 0 : }
1686 :
1687 : /* initialize hpd */
1688 0 : radeon_hpd_init(rdev);
1689 :
1690 : /* setup afmt */
1691 0 : radeon_afmt_init(rdev);
1692 :
1693 0 : radeon_fbdev_init(rdev);
1694 0 : drm_kms_helper_poll_init(rdev->ddev);
1695 :
1696 : /* do pm late init */
1697 0 : ret = radeon_pm_late_init(rdev);
1698 :
1699 0 : return 0;
1700 0 : }
1701 :
1702 0 : void radeon_modeset_fini(struct radeon_device *rdev)
1703 : {
1704 0 : radeon_fbdev_fini(rdev);
1705 0 : kfree(rdev->mode_info.bios_hardcoded_edid);
1706 :
1707 0 : if (rdev->mode_info.mode_config_initialized) {
1708 0 : radeon_afmt_fini(rdev);
1709 0 : drm_kms_helper_poll_fini(rdev->ddev);
1710 0 : radeon_hpd_fini(rdev);
1711 0 : drm_mode_config_cleanup(rdev->ddev);
1712 0 : rdev->mode_info.mode_config_initialized = false;
1713 0 : }
1714 : /* free i2c buses */
1715 0 : radeon_i2c_fini(rdev);
1716 0 : }
1717 :
1718 0 : static bool is_hdtv_mode(const struct drm_display_mode *mode)
1719 : {
1720 : /* try and guess if this is a tv or a monitor */
1721 0 : if ((mode->vdisplay == 480 && mode->hdisplay == 720) || /* 480p */
1722 0 : (mode->vdisplay == 576) || /* 576p */
1723 0 : (mode->vdisplay == 720) || /* 720p */
1724 0 : (mode->vdisplay == 1080)) /* 1080p */
1725 0 : return true;
1726 : else
1727 0 : return false;
1728 0 : }
1729 :
1730 0 : bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
1731 : const struct drm_display_mode *mode,
1732 : struct drm_display_mode *adjusted_mode)
1733 : {
1734 0 : struct drm_device *dev = crtc->dev;
1735 0 : struct radeon_device *rdev = dev->dev_private;
1736 : struct drm_encoder *encoder;
1737 0 : struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1738 : struct radeon_encoder *radeon_encoder;
1739 : struct drm_connector *connector;
1740 : struct radeon_connector *radeon_connector;
1741 : bool first = true;
1742 : u32 src_v = 1, dst_v = 1;
1743 : u32 src_h = 1, dst_h = 1;
1744 :
1745 0 : radeon_crtc->h_border = 0;
1746 0 : radeon_crtc->v_border = 0;
1747 :
1748 0 : list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
1749 0 : if (encoder->crtc != crtc)
1750 : continue;
1751 0 : radeon_encoder = to_radeon_encoder(encoder);
1752 0 : connector = radeon_get_connector_for_encoder(encoder);
1753 0 : radeon_connector = to_radeon_connector(connector);
1754 :
1755 0 : if (first) {
1756 : /* set scaling */
1757 0 : if (radeon_encoder->rmx_type == RMX_OFF)
1758 0 : radeon_crtc->rmx_type = RMX_OFF;
1759 0 : else if (mode->hdisplay < radeon_encoder->native_mode.hdisplay ||
1760 0 : mode->vdisplay < radeon_encoder->native_mode.vdisplay)
1761 0 : radeon_crtc->rmx_type = radeon_encoder->rmx_type;
1762 : else
1763 0 : radeon_crtc->rmx_type = RMX_OFF;
1764 : /* copy native mode */
1765 0 : memcpy(&radeon_crtc->native_mode,
1766 : &radeon_encoder->native_mode,
1767 : sizeof(struct drm_display_mode));
1768 0 : src_v = crtc->mode.vdisplay;
1769 0 : dst_v = radeon_crtc->native_mode.vdisplay;
1770 0 : src_h = crtc->mode.hdisplay;
1771 0 : dst_h = radeon_crtc->native_mode.hdisplay;
1772 :
1773 : /* fix up for overscan on hdmi */
1774 0 : if (ASIC_IS_AVIVO(rdev) &&
1775 0 : (!(mode->flags & DRM_MODE_FLAG_INTERLACE)) &&
1776 0 : ((radeon_encoder->underscan_type == UNDERSCAN_ON) ||
1777 0 : ((radeon_encoder->underscan_type == UNDERSCAN_AUTO) &&
1778 0 : drm_detect_hdmi_monitor(radeon_connector_edid(connector)) &&
1779 0 : is_hdtv_mode(mode)))) {
1780 0 : if (radeon_encoder->underscan_hborder != 0)
1781 0 : radeon_crtc->h_border = radeon_encoder->underscan_hborder;
1782 : else
1783 0 : radeon_crtc->h_border = (mode->hdisplay >> 5) + 16;
1784 0 : if (radeon_encoder->underscan_vborder != 0)
1785 0 : radeon_crtc->v_border = radeon_encoder->underscan_vborder;
1786 : else
1787 0 : radeon_crtc->v_border = (mode->vdisplay >> 5) + 16;
1788 0 : radeon_crtc->rmx_type = RMX_FULL;
1789 0 : src_v = crtc->mode.vdisplay;
1790 0 : dst_v = crtc->mode.vdisplay - (radeon_crtc->v_border * 2);
1791 0 : src_h = crtc->mode.hdisplay;
1792 0 : dst_h = crtc->mode.hdisplay - (radeon_crtc->h_border * 2);
1793 0 : }
1794 : first = false;
1795 0 : } else {
1796 0 : if (radeon_crtc->rmx_type != radeon_encoder->rmx_type) {
1797 : /* WARNING: Right now this can't happen but
1798 : * in the future we need to check that scaling
1799 : * are consistent across different encoder
1800 : * (ie all encoder can work with the same
1801 : * scaling).
1802 : */
1803 0 : DRM_ERROR("Scaling not consistent across encoder.\n");
1804 0 : return false;
1805 : }
1806 : }
1807 : }
1808 0 : if (radeon_crtc->rmx_type != RMX_OFF) {
1809 : fixed20_12 a, b;
1810 0 : a.full = dfixed_const(src_v);
1811 0 : b.full = dfixed_const(dst_v);
1812 0 : radeon_crtc->vsc.full = dfixed_div(a, b);
1813 0 : a.full = dfixed_const(src_h);
1814 0 : b.full = dfixed_const(dst_h);
1815 0 : radeon_crtc->hsc.full = dfixed_div(a, b);
1816 0 : } else {
1817 0 : radeon_crtc->vsc.full = dfixed_const(1);
1818 0 : radeon_crtc->hsc.full = dfixed_const(1);
1819 : }
1820 0 : return true;
1821 0 : }
1822 :
1823 : /*
1824 : * Retrieve current video scanout position of crtc on a given gpu, and
1825 : * an optional accurate timestamp of when query happened.
1826 : *
1827 : * \param dev Device to query.
1828 : * \param crtc Crtc to query.
1829 : * \param flags Flags from caller (DRM_CALLED_FROM_VBLIRQ or 0).
1830 : * For driver internal use only also supports these flags:
1831 : *
1832 : * USE_REAL_VBLANKSTART to use the real start of vblank instead
1833 : * of a fudged earlier start of vblank.
1834 : *
1835 : * GET_DISTANCE_TO_VBLANKSTART to return distance to the
1836 : * fudged earlier start of vblank in *vpos and the distance
1837 : * to true start of vblank in *hpos.
1838 : *
1839 : * \param *vpos Location where vertical scanout position should be stored.
1840 : * \param *hpos Location where horizontal scanout position should go.
1841 : * \param *stime Target location for timestamp taken immediately before
1842 : * scanout position query. Can be NULL to skip timestamp.
1843 : * \param *etime Target location for timestamp taken immediately after
1844 : * scanout position query. Can be NULL to skip timestamp.
1845 : *
1846 : * Returns vpos as a positive number while in active scanout area.
1847 : * Returns vpos as a negative number inside vblank, counting the number
1848 : * of scanlines to go until end of vblank, e.g., -1 means "one scanline
1849 : * until start of active scanout / end of vblank."
1850 : *
1851 : * \return Flags, or'ed together as follows:
1852 : *
1853 : * DRM_SCANOUTPOS_VALID = Query successful.
1854 : * DRM_SCANOUTPOS_INVBL = Inside vblank.
1855 : * DRM_SCANOUTPOS_ACCURATE = Returned position is accurate. A lack of
1856 : * this flag means that returned position may be offset by a constant but
1857 : * unknown small number of scanlines wrt. real scanout position.
1858 : *
1859 : */
1860 0 : int radeon_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe,
1861 : unsigned int flags, int *vpos, int *hpos,
1862 : ktime_t *stime, ktime_t *etime,
1863 : const struct drm_display_mode *mode)
1864 : {
1865 : u32 stat_crtc = 0, vbl = 0, position = 0;
1866 : int vbl_start, vbl_end, vtotal, ret = 0;
1867 : bool in_vbl = true;
1868 :
1869 0 : struct radeon_device *rdev = dev->dev_private;
1870 :
1871 : /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */
1872 :
1873 : /* Get optional system timestamp before query. */
1874 0 : if (stime)
1875 0 : *stime = ktime_get();
1876 :
1877 0 : if (ASIC_IS_DCE4(rdev)) {
1878 0 : if (pipe == 0) {
1879 0 : vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
1880 : EVERGREEN_CRTC0_REGISTER_OFFSET);
1881 0 : position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
1882 : EVERGREEN_CRTC0_REGISTER_OFFSET);
1883 : ret |= DRM_SCANOUTPOS_VALID;
1884 0 : }
1885 0 : if (pipe == 1) {
1886 0 : vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
1887 : EVERGREEN_CRTC1_REGISTER_OFFSET);
1888 0 : position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
1889 : EVERGREEN_CRTC1_REGISTER_OFFSET);
1890 : ret |= DRM_SCANOUTPOS_VALID;
1891 0 : }
1892 0 : if (pipe == 2) {
1893 0 : vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
1894 : EVERGREEN_CRTC2_REGISTER_OFFSET);
1895 0 : position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
1896 : EVERGREEN_CRTC2_REGISTER_OFFSET);
1897 : ret |= DRM_SCANOUTPOS_VALID;
1898 0 : }
1899 0 : if (pipe == 3) {
1900 0 : vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
1901 : EVERGREEN_CRTC3_REGISTER_OFFSET);
1902 0 : position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
1903 : EVERGREEN_CRTC3_REGISTER_OFFSET);
1904 : ret |= DRM_SCANOUTPOS_VALID;
1905 0 : }
1906 0 : if (pipe == 4) {
1907 0 : vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
1908 : EVERGREEN_CRTC4_REGISTER_OFFSET);
1909 0 : position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
1910 : EVERGREEN_CRTC4_REGISTER_OFFSET);
1911 0 : ret |= DRM_SCANOUTPOS_VALID;
1912 0 : }
1913 0 : if (pipe == 5) {
1914 0 : vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
1915 : EVERGREEN_CRTC5_REGISTER_OFFSET);
1916 0 : position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
1917 : EVERGREEN_CRTC5_REGISTER_OFFSET);
1918 0 : ret |= DRM_SCANOUTPOS_VALID;
1919 0 : }
1920 0 : } else if (ASIC_IS_AVIVO(rdev)) {
1921 0 : if (pipe == 0) {
1922 0 : vbl = RREG32(AVIVO_D1CRTC_V_BLANK_START_END);
1923 0 : position = RREG32(AVIVO_D1CRTC_STATUS_POSITION);
1924 : ret |= DRM_SCANOUTPOS_VALID;
1925 0 : }
1926 0 : if (pipe == 1) {
1927 0 : vbl = RREG32(AVIVO_D2CRTC_V_BLANK_START_END);
1928 0 : position = RREG32(AVIVO_D2CRTC_STATUS_POSITION);
1929 : ret |= DRM_SCANOUTPOS_VALID;
1930 0 : }
1931 : } else {
1932 : /* Pre-AVIVO: Different encoding of scanout pos and vblank interval. */
1933 0 : if (pipe == 0) {
1934 : /* Assume vbl_end == 0, get vbl_start from
1935 : * upper 16 bits.
1936 : */
1937 0 : vbl = (RREG32(RADEON_CRTC_V_TOTAL_DISP) &
1938 0 : RADEON_CRTC_V_DISP) >> RADEON_CRTC_V_DISP_SHIFT;
1939 : /* Only retrieve vpos from upper 16 bits, set hpos == 0. */
1940 0 : position = (RREG32(RADEON_CRTC_VLINE_CRNT_VLINE) >> 16) & RADEON_CRTC_V_TOTAL;
1941 0 : stat_crtc = RREG32(RADEON_CRTC_STATUS);
1942 0 : if (!(stat_crtc & 1))
1943 0 : in_vbl = false;
1944 :
1945 : ret |= DRM_SCANOUTPOS_VALID;
1946 0 : }
1947 0 : if (pipe == 1) {
1948 0 : vbl = (RREG32(RADEON_CRTC2_V_TOTAL_DISP) &
1949 0 : RADEON_CRTC_V_DISP) >> RADEON_CRTC_V_DISP_SHIFT;
1950 0 : position = (RREG32(RADEON_CRTC2_VLINE_CRNT_VLINE) >> 16) & RADEON_CRTC_V_TOTAL;
1951 0 : stat_crtc = RREG32(RADEON_CRTC2_STATUS);
1952 0 : if (!(stat_crtc & 1))
1953 0 : in_vbl = false;
1954 :
1955 : ret |= DRM_SCANOUTPOS_VALID;
1956 0 : }
1957 : }
1958 :
1959 : /* Get optional system timestamp after query. */
1960 0 : if (etime)
1961 0 : *etime = ktime_get();
1962 :
1963 : /* preempt_enable_rt() should go right here in PREEMPT_RT patchset. */
1964 :
1965 : /* Decode into vertical and horizontal scanout position. */
1966 0 : *vpos = position & 0x1fff;
1967 0 : *hpos = (position >> 16) & 0x1fff;
1968 :
1969 : /* Valid vblank area boundaries from gpu retrieved? */
1970 0 : if (vbl > 0) {
1971 : /* Yes: Decode. */
1972 0 : ret |= DRM_SCANOUTPOS_ACCURATE;
1973 0 : vbl_start = vbl & 0x1fff;
1974 0 : vbl_end = (vbl >> 16) & 0x1fff;
1975 0 : }
1976 : else {
1977 : /* No: Fake something reasonable which gives at least ok results. */
1978 0 : vbl_start = mode->crtc_vdisplay;
1979 : vbl_end = 0;
1980 : }
1981 :
1982 : /* Called from driver internal vblank counter query code? */
1983 0 : if (flags & GET_DISTANCE_TO_VBLANKSTART) {
1984 : /* Caller wants distance from real vbl_start in *hpos */
1985 0 : *hpos = *vpos - vbl_start;
1986 0 : }
1987 :
1988 : /* Fudge vblank to start a few scanlines earlier to handle the
1989 : * problem that vblank irqs fire a few scanlines before start
1990 : * of vblank. Some driver internal callers need the true vblank
1991 : * start to be used and signal this via the USE_REAL_VBLANKSTART flag.
1992 : *
1993 : * The cause of the "early" vblank irq is that the irq is triggered
1994 : * by the line buffer logic when the line buffer read position enters
1995 : * the vblank, whereas our crtc scanout position naturally lags the
1996 : * line buffer read position.
1997 : */
1998 0 : if (!(flags & USE_REAL_VBLANKSTART))
1999 0 : vbl_start -= rdev->mode_info.crtcs[pipe]->lb_vblank_lead_lines;
2000 :
2001 : /* Test scanout position against vblank region. */
2002 0 : if ((*vpos < vbl_start) && (*vpos >= vbl_end))
2003 0 : in_vbl = false;
2004 :
2005 : /* In vblank? */
2006 0 : if (in_vbl)
2007 0 : ret |= DRM_SCANOUTPOS_IN_VBLANK;
2008 :
2009 : /* Called from driver internal vblank counter query code? */
2010 0 : if (flags & GET_DISTANCE_TO_VBLANKSTART) {
2011 : /* Caller wants distance from fudged earlier vbl_start */
2012 0 : *vpos -= vbl_start;
2013 0 : return ret;
2014 : }
2015 :
2016 : /* Check if inside vblank area and apply corrective offsets:
2017 : * vpos will then be >=0 in video scanout area, but negative
2018 : * within vblank area, counting down the number of lines until
2019 : * start of scanout.
2020 : */
2021 :
2022 : /* Inside "upper part" of vblank area? Apply corrective offset if so: */
2023 0 : if (in_vbl && (*vpos >= vbl_start)) {
2024 0 : vtotal = mode->crtc_vtotal;
2025 0 : *vpos = *vpos - vtotal;
2026 0 : }
2027 :
2028 : /* Correct for shifted end of vbl at vbl_end. */
2029 0 : *vpos = *vpos - vbl_end;
2030 :
2031 0 : return ret;
2032 0 : }
|