1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include <drm/drmP.h>
27#include <drm/drm_crtc_helper.h>
28#include <drm/drm_fb_helper.h>
29#include <drm/radeon_drm.h>
30#include <drm/drm_fixed.h>
31#include "radeon.h"
32#include "atom.h"
33#include "atom-bits.h"
34
35static void atombios_overscan_setup(struct drm_crtc *crtc,
36 struct drm_display_mode *mode,
37 struct drm_display_mode *adjusted_mode)
38{
39 struct drm_device *dev = crtc->dev;
40 struct radeon_device *rdev = dev->dev_private;
41 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
42 SET_CRTC_OVERSCAN_PS_ALLOCATION args;
43 int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_OverScan);
44 int a1, a2;
45
46 memset(&args, 0, sizeof(args));
47
48 args.ucCRTC = radeon_crtc->crtc_id;
49
50 switch (radeon_crtc->rmx_type) {
51 case RMX_CENTER:
52 args.usOverscanTop = cpu_to_le16((adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2);
53 args.usOverscanBottom = cpu_to_le16((adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2);
54 args.usOverscanLeft = cpu_to_le16((adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2);
55 args.usOverscanRight = cpu_to_le16((adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2);
56 break;
57 case RMX_ASPECT:
58 a1 = mode->crtc_vdisplay * adjusted_mode->crtc_hdisplay;
59 a2 = adjusted_mode->crtc_vdisplay * mode->crtc_hdisplay;
60
61 if (a1 > a2) {
62 args.usOverscanLeft = cpu_to_le16((adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2);
63 args.usOverscanRight = cpu_to_le16((adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2);
64 } else if (a2 > a1) {
65 args.usOverscanTop = cpu_to_le16((adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2);
66 args.usOverscanBottom = cpu_to_le16((adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2);
67 }
68 break;
69 case RMX_FULL:
70 default:
71 args.usOverscanRight = cpu_to_le16(radeon_crtc->h_border);
72 args.usOverscanLeft = cpu_to_le16(radeon_crtc->h_border);
73 args.usOverscanBottom = cpu_to_le16(radeon_crtc->v_border);
74 args.usOverscanTop = cpu_to_le16(radeon_crtc->v_border);
75 break;
76 }
77 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
78}
79
80static void atombios_scaler_setup(struct drm_crtc *crtc)
81{
82 struct drm_device *dev = crtc->dev;
83 struct radeon_device *rdev = dev->dev_private;
84 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
85 ENABLE_SCALER_PS_ALLOCATION args;
86 int index = GetIndexIntoMasterTable(COMMAND, EnableScaler);
87 struct radeon_encoder *radeon_encoder =
88 to_radeon_encoder(radeon_crtc->encoder);
89
90 enum radeon_tv_std tv_std = TV_STD_NTSC;
91 bool is_tv = false, is_cv = false;
92
93 if (!ASIC_IS_AVIVO(rdev) && radeon_crtc->crtc_id)
94 return;
95
96 if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) {
97 struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv;
98 tv_std = tv_dac->tv_std;
99 is_tv = true;
100 }
101
102 memset(&args, 0, sizeof(args));
103
104 args.ucScaler = radeon_crtc->crtc_id;
105
106 if (is_tv) {
107 switch (tv_std) {
108 case TV_STD_NTSC:
109 default:
110 args.ucTVStandard = ATOM_TV_NTSC;
111 break;
112 case TV_STD_PAL:
113 args.ucTVStandard = ATOM_TV_PAL;
114 break;
115 case TV_STD_PAL_M:
116 args.ucTVStandard = ATOM_TV_PALM;
117 break;
118 case TV_STD_PAL_60:
119 args.ucTVStandard = ATOM_TV_PAL60;
120 break;
121 case TV_STD_NTSC_J:
122 args.ucTVStandard = ATOM_TV_NTSCJ;
123 break;
124 case TV_STD_SCART_PAL:
125 args.ucTVStandard = ATOM_TV_PAL;
126 break;
127 case TV_STD_SECAM:
128 args.ucTVStandard = ATOM_TV_SECAM;
129 break;
130 case TV_STD_PAL_CN:
131 args.ucTVStandard = ATOM_TV_PALCN;
132 break;
133 }
134 args.ucEnable = SCALER_ENABLE_MULTITAP_MODE;
135 } else if (is_cv) {
136 args.ucTVStandard = ATOM_TV_CV;
137 args.ucEnable = SCALER_ENABLE_MULTITAP_MODE;
138 } else {
139 switch (radeon_crtc->rmx_type) {
140 case RMX_FULL:
141 args.ucEnable = ATOM_SCALER_EXPANSION;
142 break;
143 case RMX_CENTER:
144 args.ucEnable = ATOM_SCALER_CENTER;
145 break;
146 case RMX_ASPECT:
147 args.ucEnable = ATOM_SCALER_EXPANSION;
148 break;
149 default:
150 if (ASIC_IS_AVIVO(rdev))
151 args.ucEnable = ATOM_SCALER_DISABLE;
152 else
153 args.ucEnable = ATOM_SCALER_CENTER;
154 break;
155 }
156 }
157 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
158 if ((is_tv || is_cv)
159 && rdev->family >= CHIP_RV515 && rdev->family <= CHIP_R580) {
160 atom_rv515_force_tv_scaler(rdev, radeon_crtc);
161 }
162}
163
164static void atombios_lock_crtc(struct drm_crtc *crtc, int lock)
165{
166 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
167 struct drm_device *dev = crtc->dev;
168 struct radeon_device *rdev = dev->dev_private;
169 int index =
170 GetIndexIntoMasterTable(COMMAND, UpdateCRTC_DoubleBufferRegisters);
171 ENABLE_CRTC_PS_ALLOCATION args;
172
173 memset(&args, 0, sizeof(args));
174
175 args.ucCRTC = radeon_crtc->crtc_id;
176 args.ucEnable = lock;
177
178 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
179}
180
181static void atombios_enable_crtc(struct drm_crtc *crtc, int state)
182{
183 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
184 struct drm_device *dev = crtc->dev;
185 struct radeon_device *rdev = dev->dev_private;
186 int index = GetIndexIntoMasterTable(COMMAND, EnableCRTC);
187 ENABLE_CRTC_PS_ALLOCATION args;
188
189 memset(&args, 0, sizeof(args));
190
191 args.ucCRTC = radeon_crtc->crtc_id;
192 args.ucEnable = state;
193
194 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
195}
196
197static void atombios_enable_crtc_memreq(struct drm_crtc *crtc, int state)
198{
199 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
200 struct drm_device *dev = crtc->dev;
201 struct radeon_device *rdev = dev->dev_private;
202 int index = GetIndexIntoMasterTable(COMMAND, EnableCRTCMemReq);
203 ENABLE_CRTC_PS_ALLOCATION args;
204
205 memset(&args, 0, sizeof(args));
206
207 args.ucCRTC = radeon_crtc->crtc_id;
208 args.ucEnable = state;
209
210 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
211}
212
213static const u32 vga_control_regs[6] =
214{
215 AVIVO_D1VGA_CONTROL,
216 AVIVO_D2VGA_CONTROL,
217 EVERGREEN_D3VGA_CONTROL,
218 EVERGREEN_D4VGA_CONTROL,
219 EVERGREEN_D5VGA_CONTROL,
220 EVERGREEN_D6VGA_CONTROL,
221};
222
223static void atombios_blank_crtc(struct drm_crtc *crtc, int state)
224{
225 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
226 struct drm_device *dev = crtc->dev;
227 struct radeon_device *rdev = dev->dev_private;
228 int index = GetIndexIntoMasterTable(COMMAND, BlankCRTC);
229 BLANK_CRTC_PS_ALLOCATION args;
230 u32 vga_control = 0;
231
232 memset(&args, 0, sizeof(args));
233
234 if (ASIC_IS_DCE8(rdev)) {
235 vga_control = RREG32(vga_control_regs[radeon_crtc->crtc_id]);
236 WREG32(vga_control_regs[radeon_crtc->crtc_id], vga_control | 1);
237 }
238
239 args.ucCRTC = radeon_crtc->crtc_id;
240 args.ucBlanking = state;
241
242 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
243
244 if (ASIC_IS_DCE8(rdev)) {
245 WREG32(vga_control_regs[radeon_crtc->crtc_id], vga_control);
246 }
247}
248
249static void atombios_powergate_crtc(struct drm_crtc *crtc, int state)
250{
251 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
252 struct drm_device *dev = crtc->dev;
253 struct radeon_device *rdev = dev->dev_private;
254 int index = GetIndexIntoMasterTable(COMMAND, EnableDispPowerGating);
255 ENABLE_DISP_POWER_GATING_PARAMETERS_V2_1 args;
256
257 memset(&args, 0, sizeof(args));
258
259 args.ucDispPipeId = radeon_crtc->crtc_id;
260 args.ucEnable = state;
261
262 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
263}
264
265void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
266{
267 struct drm_device *dev = crtc->dev;
268 struct radeon_device *rdev = dev->dev_private;
269 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
270
271 switch (mode) {
272 case DRM_MODE_DPMS_ON:
273 radeon_crtc->enabled = true;
274 atombios_enable_crtc(crtc, ATOM_ENABLE);
275 if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev))
276 atombios_enable_crtc_memreq(crtc, ATOM_ENABLE);
277 atombios_blank_crtc(crtc, ATOM_DISABLE);
278 if (dev->num_crtcs > radeon_crtc->crtc_id)
279 drm_crtc_vblank_on(crtc);
280 radeon_crtc_load_lut(crtc);
281 break;
282 case DRM_MODE_DPMS_STANDBY:
283 case DRM_MODE_DPMS_SUSPEND:
284 case DRM_MODE_DPMS_OFF:
285 if (dev->num_crtcs > radeon_crtc->crtc_id)
286 drm_crtc_vblank_off(crtc);
287 if (radeon_crtc->enabled)
288 atombios_blank_crtc(crtc, ATOM_ENABLE);
289 if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev))
290 atombios_enable_crtc_memreq(crtc, ATOM_DISABLE);
291 atombios_enable_crtc(crtc, ATOM_DISABLE);
292 radeon_crtc->enabled = false;
293 break;
294 }
295
296 radeon_pm_compute_clocks(rdev);
297}
298
299static void
300atombios_set_crtc_dtd_timing(struct drm_crtc *crtc,
301 struct drm_display_mode *mode)
302{
303 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
304 struct drm_device *dev = crtc->dev;
305 struct radeon_device *rdev = dev->dev_private;
306 SET_CRTC_USING_DTD_TIMING_PARAMETERS args;
307 int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_UsingDTDTiming);
308 u16 misc = 0;
309
310 memset(&args, 0, sizeof(args));
311 args.usH_Size = cpu_to_le16(mode->crtc_hdisplay - (radeon_crtc->h_border * 2));
312 args.usH_Blanking_Time =
313 cpu_to_le16(mode->crtc_hblank_end - mode->crtc_hdisplay + (radeon_crtc->h_border * 2));
314 args.usV_Size = cpu_to_le16(mode->crtc_vdisplay - (radeon_crtc->v_border * 2));
315 args.usV_Blanking_Time =
316 cpu_to_le16(mode->crtc_vblank_end - mode->crtc_vdisplay + (radeon_crtc->v_border * 2));
317 args.usH_SyncOffset =
318 cpu_to_le16(mode->crtc_hsync_start - mode->crtc_hdisplay + radeon_crtc->h_border);
319 args.usH_SyncWidth =
320 cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start);
321 args.usV_SyncOffset =
322 cpu_to_le16(mode->crtc_vsync_start - mode->crtc_vdisplay + radeon_crtc->v_border);
323 args.usV_SyncWidth =
324 cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start);
325 args.ucH_Border = radeon_crtc->h_border;
326 args.ucV_Border = radeon_crtc->v_border;
327
328 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
329 misc |= ATOM_VSYNC_POLARITY;
330 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
331 misc |= ATOM_HSYNC_POLARITY;
332 if (mode->flags & DRM_MODE_FLAG_CSYNC)
333 misc |= ATOM_COMPOSITESYNC;
334 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
335 misc |= ATOM_INTERLACE;
336 if (mode->flags & DRM_MODE_FLAG_DBLCLK)
337 misc |= ATOM_DOUBLE_CLOCK_MODE;
338 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
339 misc |= ATOM_H_REPLICATIONBY2 | ATOM_V_REPLICATIONBY2;
340
341 args.susModeMiscInfo.usAccess = cpu_to_le16(misc);
342 args.ucCRTC = radeon_crtc->crtc_id;
343
344 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
345}
346
347static void atombios_crtc_set_timing(struct drm_crtc *crtc,
348 struct drm_display_mode *mode)
349{
350 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
351 struct drm_device *dev = crtc->dev;
352 struct radeon_device *rdev = dev->dev_private;
353 SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION args;
354 int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_Timing);
355 u16 misc = 0;
356
357 memset(&args, 0, sizeof(args));
358 args.usH_Total = cpu_to_le16(mode->crtc_htotal);
359 args.usH_Disp = cpu_to_le16(mode->crtc_hdisplay);
360 args.usH_SyncStart = cpu_to_le16(mode->crtc_hsync_start);
361 args.usH_SyncWidth =
362 cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start);
363 args.usV_Total = cpu_to_le16(mode->crtc_vtotal);
364 args.usV_Disp = cpu_to_le16(mode->crtc_vdisplay);
365 args.usV_SyncStart = cpu_to_le16(mode->crtc_vsync_start);
366 args.usV_SyncWidth =
367 cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start);
368
369 args.ucOverscanRight = radeon_crtc->h_border;
370 args.ucOverscanLeft = radeon_crtc->h_border;
371 args.ucOverscanBottom = radeon_crtc->v_border;
372 args.ucOverscanTop = radeon_crtc->v_border;
373
374 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
375 misc |= ATOM_VSYNC_POLARITY;
376 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
377 misc |= ATOM_HSYNC_POLARITY;
378 if (mode->flags & DRM_MODE_FLAG_CSYNC)
379 misc |= ATOM_COMPOSITESYNC;
380 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
381 misc |= ATOM_INTERLACE;
382 if (mode->flags & DRM_MODE_FLAG_DBLCLK)
383 misc |= ATOM_DOUBLE_CLOCK_MODE;
384 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
385 misc |= ATOM_H_REPLICATIONBY2 | ATOM_V_REPLICATIONBY2;
386
387 args.susModeMiscInfo.usAccess = cpu_to_le16(misc);
388 args.ucCRTC = radeon_crtc->crtc_id;
389
390 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
391}
392
393static void atombios_disable_ss(struct radeon_device *rdev, int pll_id)
394{
395 u32 ss_cntl;
396
397 if (ASIC_IS_DCE4(rdev)) {
398 switch (pll_id) {
399 case ATOM_PPLL1:
400 ss_cntl = RREG32(EVERGREEN_P1PLL_SS_CNTL);
401 ss_cntl &= ~EVERGREEN_PxPLL_SS_EN;
402 WREG32(EVERGREEN_P1PLL_SS_CNTL, ss_cntl);
403 break;
404 case ATOM_PPLL2:
405 ss_cntl = RREG32(EVERGREEN_P2PLL_SS_CNTL);
406 ss_cntl &= ~EVERGREEN_PxPLL_SS_EN;
407 WREG32(EVERGREEN_P2PLL_SS_CNTL, ss_cntl);
408 break;
409 case ATOM_DCPLL:
410 case ATOM_PPLL_INVALID:
411 return;
412 }
413 } else if (ASIC_IS_AVIVO(rdev)) {
414 switch (pll_id) {
415 case ATOM_PPLL1:
416 ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL);
417 ss_cntl &= ~1;
418 WREG32(AVIVO_P1PLL_INT_SS_CNTL, ss_cntl);
419 break;
420 case ATOM_PPLL2:
421 ss_cntl = RREG32(AVIVO_P2PLL_INT_SS_CNTL);
422 ss_cntl &= ~1;
423 WREG32(AVIVO_P2PLL_INT_SS_CNTL, ss_cntl);
424 break;
425 case ATOM_DCPLL:
426 case ATOM_PPLL_INVALID:
427 return;
428 }
429 }
430}
431
432
433union atom_enable_ss {
434 ENABLE_LVDS_SS_PARAMETERS lvds_ss;
435 ENABLE_LVDS_SS_PARAMETERS_V2 lvds_ss_2;
436 ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION v1;
437 ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 v2;
438 ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 v3;
439};
440
441static void atombios_crtc_program_ss(struct radeon_device *rdev,
442 int enable,
443 int pll_id,
444 int crtc_id,
445 struct radeon_atom_ss *ss)
446{
447 unsigned i;
448 int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL);
449 union atom_enable_ss args;
450
451 if (enable) {
452
453
454
455
456
457 if (ss->percentage == 0)
458 return;
459 if (ss->type & ATOM_EXTERNAL_SS_MASK)
460 return;
461 } else {
462 for (i = 0; i < rdev->num_crtc; i++) {
463 if (rdev->mode_info.crtcs[i] &&
464 rdev->mode_info.crtcs[i]->enabled &&
465 i != crtc_id &&
466 pll_id == rdev->mode_info.crtcs[i]->pll_id) {
467
468
469
470
471 return;
472 }
473 }
474 }
475
476 memset(&args, 0, sizeof(args));
477
478 if (ASIC_IS_DCE5(rdev)) {
479 args.v3.usSpreadSpectrumAmountFrac = cpu_to_le16(0);
480 args.v3.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK;
481 switch (pll_id) {
482 case ATOM_PPLL1:
483 args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P1PLL;
484 break;
485 case ATOM_PPLL2:
486 args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P2PLL;
487 break;
488 case ATOM_DCPLL:
489 args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_DCPLL;
490 break;
491 case ATOM_PPLL_INVALID:
492 return;
493 }
494 args.v3.usSpreadSpectrumAmount = cpu_to_le16(ss->amount);
495 args.v3.usSpreadSpectrumStep = cpu_to_le16(ss->step);
496 args.v3.ucEnable = enable;
497 } else if (ASIC_IS_DCE4(rdev)) {
498 args.v2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
499 args.v2.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK;
500 switch (pll_id) {
501 case ATOM_PPLL1:
502 args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P1PLL;
503 break;
504 case ATOM_PPLL2:
505 args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P2PLL;
506 break;
507 case ATOM_DCPLL:
508 args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_DCPLL;
509 break;
510 case ATOM_PPLL_INVALID:
511 return;
512 }
513 args.v2.usSpreadSpectrumAmount = cpu_to_le16(ss->amount);
514 args.v2.usSpreadSpectrumStep = cpu_to_le16(ss->step);
515 args.v2.ucEnable = enable;
516 } else if (ASIC_IS_DCE3(rdev)) {
517 args.v1.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
518 args.v1.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK;
519 args.v1.ucSpreadSpectrumStep = ss->step;
520 args.v1.ucSpreadSpectrumDelay = ss->delay;
521 args.v1.ucSpreadSpectrumRange = ss->range;
522 args.v1.ucPpll = pll_id;
523 args.v1.ucEnable = enable;
524 } else if (ASIC_IS_AVIVO(rdev)) {
525 if ((enable == ATOM_DISABLE) || (ss->percentage == 0) ||
526 (ss->type & ATOM_EXTERNAL_SS_MASK)) {
527 atombios_disable_ss(rdev, pll_id);
528 return;
529 }
530 args.lvds_ss_2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
531 args.lvds_ss_2.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK;
532 args.lvds_ss_2.ucSpreadSpectrumStep = ss->step;
533 args.lvds_ss_2.ucSpreadSpectrumDelay = ss->delay;
534 args.lvds_ss_2.ucSpreadSpectrumRange = ss->range;
535 args.lvds_ss_2.ucEnable = enable;
536 } else {
537 if (enable == ATOM_DISABLE) {
538 atombios_disable_ss(rdev, pll_id);
539 return;
540 }
541 args.lvds_ss.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
542 args.lvds_ss.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK;
543 args.lvds_ss.ucSpreadSpectrumStepSize_Delay = (ss->step & 3) << 2;
544 args.lvds_ss.ucSpreadSpectrumStepSize_Delay |= (ss->delay & 7) << 4;
545 args.lvds_ss.ucEnable = enable;
546 }
547 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
548}
549
550union adjust_pixel_clock {
551 ADJUST_DISPLAY_PLL_PS_ALLOCATION v1;
552 ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 v3;
553};
554
555static u32 atombios_adjust_pll(struct drm_crtc *crtc,
556 struct drm_display_mode *mode)
557{
558 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
559 struct drm_device *dev = crtc->dev;
560 struct radeon_device *rdev = dev->dev_private;
561 struct drm_encoder *encoder = radeon_crtc->encoder;
562 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
563 struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
564 u32 adjusted_clock = mode->clock;
565 int encoder_mode = atombios_get_encoder_mode(encoder);
566 u32 dp_clock = mode->clock;
567 u32 clock = mode->clock;
568 int bpc = radeon_crtc->bpc;
569 bool is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock);
570
571
572 radeon_crtc->pll_flags = 0;
573
574 if (ASIC_IS_AVIVO(rdev)) {
575 if ((rdev->family == CHIP_RS600) ||
576 (rdev->family == CHIP_RS690) ||
577 (rdev->family == CHIP_RS740))
578 radeon_crtc->pll_flags |= (
579 RADEON_PLL_PREFER_CLOSEST_LOWER);
580
581 if (ASIC_IS_DCE32(rdev) && mode->clock > 200000)
582 radeon_crtc->pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
583 else
584 radeon_crtc->pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
585
586 if (rdev->family < CHIP_RV770)
587 radeon_crtc->pll_flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP;
588
589 if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev) || ASIC_IS_DCE8(rdev))
590 radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
591
592 if (((rdev->family == CHIP_RS780) || (rdev->family == CHIP_RS880))
593 && !radeon_crtc->ss_enabled)
594 radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
595 if (ASIC_IS_DCE32(rdev) && mode->clock > 165000)
596 radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
597 } else {
598 radeon_crtc->pll_flags |= RADEON_PLL_LEGACY;
599
600 if (mode->clock > 200000)
601 radeon_crtc->pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
602 else
603 radeon_crtc->pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
604 }
605
606 if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) ||
607 (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) {
608 if (connector) {
609 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
610 struct radeon_connector_atom_dig *dig_connector =
611 radeon_connector->con_priv;
612
613 dp_clock = dig_connector->dp_clock;
614 }
615 }
616
617 if (radeon_encoder->is_mst_encoder) {
618 struct radeon_encoder_mst *mst_enc = radeon_encoder->enc_priv;
619 struct radeon_connector_atom_dig *dig_connector = mst_enc->connector->con_priv;
620
621 dp_clock = dig_connector->dp_clock;
622 }
623
624
625 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
626 if (radeon_crtc->ss_enabled) {
627 if (radeon_crtc->ss.refdiv) {
628 radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV;
629 radeon_crtc->pll_reference_div = radeon_crtc->ss.refdiv;
630 if (ASIC_IS_AVIVO(rdev) &&
631 rdev->family != CHIP_RS780 &&
632 rdev->family != CHIP_RS880)
633 radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
634 }
635 }
636 }
637
638 if (ASIC_IS_AVIVO(rdev)) {
639
640 if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)
641 adjusted_clock = mode->clock * 2;
642 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
643 radeon_crtc->pll_flags |= RADEON_PLL_PREFER_CLOSEST_LOWER;
644 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
645 radeon_crtc->pll_flags |= RADEON_PLL_IS_LCD;
646 } else {
647 if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
648 radeon_crtc->pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
649 if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS)
650 radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV;
651 }
652
653
654 if (encoder_mode == ATOM_ENCODER_MODE_HDMI) {
655 switch (bpc) {
656 case 8:
657 default:
658 break;
659 case 10:
660 clock = (clock * 5) / 4;
661 break;
662 case 12:
663 clock = (clock * 3) / 2;
664 break;
665 case 16:
666 clock = clock * 2;
667 break;
668 }
669 }
670
671
672
673
674
675 if (ASIC_IS_DCE3(rdev)) {
676 union adjust_pixel_clock args;
677 u8 frev, crev;
678 int index;
679
680 index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll);
681 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
682 &crev))
683 return adjusted_clock;
684
685 memset(&args, 0, sizeof(args));
686
687 switch (frev) {
688 case 1:
689 switch (crev) {
690 case 1:
691 case 2:
692 args.v1.usPixelClock = cpu_to_le16(clock / 10);
693 args.v1.ucTransmitterID = radeon_encoder->encoder_id;
694 args.v1.ucEncodeMode = encoder_mode;
695 if (radeon_crtc->ss_enabled && radeon_crtc->ss.percentage)
696 args.v1.ucConfig |=
697 ADJUST_DISPLAY_CONFIG_SS_ENABLE;
698
699 atom_execute_table(rdev->mode_info.atom_context,
700 index, (uint32_t *)&args);
701 adjusted_clock = le16_to_cpu(args.v1.usPixelClock) * 10;
702 break;
703 case 3:
704 args.v3.sInput.usPixelClock = cpu_to_le16(clock / 10);
705 args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id;
706 args.v3.sInput.ucEncodeMode = encoder_mode;
707 args.v3.sInput.ucDispPllConfig = 0;
708 if (radeon_crtc->ss_enabled && radeon_crtc->ss.percentage)
709 args.v3.sInput.ucDispPllConfig |=
710 DISPPLL_CONFIG_SS_ENABLE;
711 if (ENCODER_MODE_IS_DP(encoder_mode)) {
712 args.v3.sInput.ucDispPllConfig |=
713 DISPPLL_CONFIG_COHERENT_MODE;
714
715 args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10);
716 } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
717 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
718 if (dig->coherent_mode)
719 args.v3.sInput.ucDispPllConfig |=
720 DISPPLL_CONFIG_COHERENT_MODE;
721 if (is_duallink)
722 args.v3.sInput.ucDispPllConfig |=
723 DISPPLL_CONFIG_DUAL_LINK;
724 }
725 if (radeon_encoder_get_dp_bridge_encoder_id(encoder) !=
726 ENCODER_OBJECT_ID_NONE)
727 args.v3.sInput.ucExtTransmitterID =
728 radeon_encoder_get_dp_bridge_encoder_id(encoder);
729 else
730 args.v3.sInput.ucExtTransmitterID = 0;
731
732 atom_execute_table(rdev->mode_info.atom_context,
733 index, (uint32_t *)&args);
734 adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10;
735 if (args.v3.sOutput.ucRefDiv) {
736 radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
737 radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV;
738 radeon_crtc->pll_reference_div = args.v3.sOutput.ucRefDiv;
739 }
740 if (args.v3.sOutput.ucPostDiv) {
741 radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
742 radeon_crtc->pll_flags |= RADEON_PLL_USE_POST_DIV;
743 radeon_crtc->pll_post_div = args.v3.sOutput.ucPostDiv;
744 }
745 break;
746 default:
747 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
748 return adjusted_clock;
749 }
750 break;
751 default:
752 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
753 return adjusted_clock;
754 }
755 }
756 return adjusted_clock;
757}
758
759union set_pixel_clock {
760 SET_PIXEL_CLOCK_PS_ALLOCATION base;
761 PIXEL_CLOCK_PARAMETERS v1;
762 PIXEL_CLOCK_PARAMETERS_V2 v2;
763 PIXEL_CLOCK_PARAMETERS_V3 v3;
764 PIXEL_CLOCK_PARAMETERS_V5 v5;
765 PIXEL_CLOCK_PARAMETERS_V6 v6;
766};
767
768
769
770
771static void atombios_crtc_set_disp_eng_pll(struct radeon_device *rdev,
772 u32 dispclk)
773{
774 u8 frev, crev;
775 int index;
776 union set_pixel_clock args;
777
778 memset(&args, 0, sizeof(args));
779
780 index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
781 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
782 &crev))
783 return;
784
785 switch (frev) {
786 case 1:
787 switch (crev) {
788 case 5:
789
790
791
792 args.v5.ucCRTC = ATOM_CRTC_INVALID;
793 args.v5.usPixelClock = cpu_to_le16(dispclk);
794 args.v5.ucPpll = ATOM_DCPLL;
795 break;
796 case 6:
797
798
799
800 args.v6.ulDispEngClkFreq = cpu_to_le32(dispclk);
801 if (ASIC_IS_DCE61(rdev) || ASIC_IS_DCE8(rdev))
802 args.v6.ucPpll = ATOM_EXT_PLL1;
803 else if (ASIC_IS_DCE6(rdev))
804 args.v6.ucPpll = ATOM_PPLL0;
805 else
806 args.v6.ucPpll = ATOM_DCPLL;
807 break;
808 default:
809 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
810 return;
811 }
812 break;
813 default:
814 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
815 return;
816 }
817 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
818}
819
820static void atombios_crtc_program_pll(struct drm_crtc *crtc,
821 u32 crtc_id,
822 int pll_id,
823 u32 encoder_mode,
824 u32 encoder_id,
825 u32 clock,
826 u32 ref_div,
827 u32 fb_div,
828 u32 frac_fb_div,
829 u32 post_div,
830 int bpc,
831 bool ss_enabled,
832 struct radeon_atom_ss *ss)
833{
834 struct drm_device *dev = crtc->dev;
835 struct radeon_device *rdev = dev->dev_private;
836 u8 frev, crev;
837 int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
838 union set_pixel_clock args;
839
840 memset(&args, 0, sizeof(args));
841
842 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
843 &crev))
844 return;
845
846 switch (frev) {
847 case 1:
848 switch (crev) {
849 case 1:
850 if (clock == ATOM_DISABLE)
851 return;
852 args.v1.usPixelClock = cpu_to_le16(clock / 10);
853 args.v1.usRefDiv = cpu_to_le16(ref_div);
854 args.v1.usFbDiv = cpu_to_le16(fb_div);
855 args.v1.ucFracFbDiv = frac_fb_div;
856 args.v1.ucPostDiv = post_div;
857 args.v1.ucPpll = pll_id;
858 args.v1.ucCRTC = crtc_id;
859 args.v1.ucRefDivSrc = 1;
860 break;
861 case 2:
862 args.v2.usPixelClock = cpu_to_le16(clock / 10);
863 args.v2.usRefDiv = cpu_to_le16(ref_div);
864 args.v2.usFbDiv = cpu_to_le16(fb_div);
865 args.v2.ucFracFbDiv = frac_fb_div;
866 args.v2.ucPostDiv = post_div;
867 args.v2.ucPpll = pll_id;
868 args.v2.ucCRTC = crtc_id;
869 args.v2.ucRefDivSrc = 1;
870 break;
871 case 3:
872 args.v3.usPixelClock = cpu_to_le16(clock / 10);
873 args.v3.usRefDiv = cpu_to_le16(ref_div);
874 args.v3.usFbDiv = cpu_to_le16(fb_div);
875 args.v3.ucFracFbDiv = frac_fb_div;
876 args.v3.ucPostDiv = post_div;
877 args.v3.ucPpll = pll_id;
878 if (crtc_id == ATOM_CRTC2)
879 args.v3.ucMiscInfo = PIXEL_CLOCK_MISC_CRTC_SEL_CRTC2;
880 else
881 args.v3.ucMiscInfo = PIXEL_CLOCK_MISC_CRTC_SEL_CRTC1;
882 if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
883 args.v3.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC;
884 args.v3.ucTransmitterId = encoder_id;
885 args.v3.ucEncoderMode = encoder_mode;
886 break;
887 case 5:
888 args.v5.ucCRTC = crtc_id;
889 args.v5.usPixelClock = cpu_to_le16(clock / 10);
890 args.v5.ucRefDiv = ref_div;
891 args.v5.usFbDiv = cpu_to_le16(fb_div);
892 args.v5.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000);
893 args.v5.ucPostDiv = post_div;
894 args.v5.ucMiscInfo = 0;
895 if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
896 args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_REF_DIV_SRC;
897 if (encoder_mode == ATOM_ENCODER_MODE_HDMI) {
898 switch (bpc) {
899 case 8:
900 default:
901 args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_24BPP;
902 break;
903 case 10:
904
905 args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_32BPP;
906 break;
907 case 12:
908
909 args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_30BPP;
910 break;
911 }
912 }
913 args.v5.ucTransmitterID = encoder_id;
914 args.v5.ucEncoderMode = encoder_mode;
915 args.v5.ucPpll = pll_id;
916 break;
917 case 6:
918 args.v6.ulDispEngClkFreq = cpu_to_le32(crtc_id << 24 | clock / 10);
919 args.v6.ucRefDiv = ref_div;
920 args.v6.usFbDiv = cpu_to_le16(fb_div);
921 args.v6.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000);
922 args.v6.ucPostDiv = post_div;
923 args.v6.ucMiscInfo = 0;
924 if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
925 args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_REF_DIV_SRC;
926 if (encoder_mode == ATOM_ENCODER_MODE_HDMI) {
927 switch (bpc) {
928 case 8:
929 default:
930 args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_24BPP;
931 break;
932 case 10:
933 args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_30BPP_V6;
934 break;
935 case 12:
936 args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_36BPP_V6;
937 break;
938 case 16:
939 args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_48BPP;
940 break;
941 }
942 }
943 args.v6.ucTransmitterID = encoder_id;
944 args.v6.ucEncoderMode = encoder_mode;
945 args.v6.ucPpll = pll_id;
946 break;
947 default:
948 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
949 return;
950 }
951 break;
952 default:
953 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
954 return;
955 }
956
957 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
958}
959
960static bool atombios_crtc_prepare_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
961{
962 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
963 struct drm_device *dev = crtc->dev;
964 struct radeon_device *rdev = dev->dev_private;
965 struct radeon_encoder *radeon_encoder =
966 to_radeon_encoder(radeon_crtc->encoder);
967 int encoder_mode = atombios_get_encoder_mode(radeon_crtc->encoder);
968
969 radeon_crtc->bpc = 8;
970 radeon_crtc->ss_enabled = false;
971
972 if (radeon_encoder->is_mst_encoder) {
973 radeon_dp_mst_prepare_pll(crtc, mode);
974 } else if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) ||
975 (radeon_encoder_get_dp_bridge_encoder_id(radeon_crtc->encoder) != ENCODER_OBJECT_ID_NONE)) {
976 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
977 struct drm_connector *connector =
978 radeon_get_connector_for_encoder(radeon_crtc->encoder);
979 struct radeon_connector *radeon_connector =
980 to_radeon_connector(connector);
981 struct radeon_connector_atom_dig *dig_connector =
982 radeon_connector->con_priv;
983 int dp_clock;
984
985
986 radeon_connector->pixelclock_for_modeset = mode->clock;
987 radeon_crtc->bpc = radeon_get_monitor_bpc(connector);
988
989 switch (encoder_mode) {
990 case ATOM_ENCODER_MODE_DP_MST:
991 case ATOM_ENCODER_MODE_DP:
992
993 dp_clock = dig_connector->dp_clock / 10;
994 if (ASIC_IS_DCE4(rdev))
995 radeon_crtc->ss_enabled =
996 radeon_atombios_get_asic_ss_info(rdev, &radeon_crtc->ss,
997 ASIC_INTERNAL_SS_ON_DP,
998 dp_clock);
999 else {
1000 if (dp_clock == 16200) {
1001 radeon_crtc->ss_enabled =
1002 radeon_atombios_get_ppll_ss_info(rdev,
1003 &radeon_crtc->ss,
1004 ATOM_DP_SS_ID2);
1005 if (!radeon_crtc->ss_enabled)
1006 radeon_crtc->ss_enabled =
1007 radeon_atombios_get_ppll_ss_info(rdev,
1008 &radeon_crtc->ss,
1009 ATOM_DP_SS_ID1);
1010 } else {
1011 radeon_crtc->ss_enabled =
1012 radeon_atombios_get_ppll_ss_info(rdev,
1013 &radeon_crtc->ss,
1014 ATOM_DP_SS_ID1);
1015 }
1016
1017 radeon_crtc->ss_enabled = false;
1018 }
1019 break;
1020 case ATOM_ENCODER_MODE_LVDS:
1021 if (ASIC_IS_DCE4(rdev))
1022 radeon_crtc->ss_enabled =
1023 radeon_atombios_get_asic_ss_info(rdev,
1024 &radeon_crtc->ss,
1025 dig->lcd_ss_id,
1026 mode->clock / 10);
1027 else
1028 radeon_crtc->ss_enabled =
1029 radeon_atombios_get_ppll_ss_info(rdev,
1030 &radeon_crtc->ss,
1031 dig->lcd_ss_id);
1032 break;
1033 case ATOM_ENCODER_MODE_DVI:
1034 if (ASIC_IS_DCE4(rdev))
1035 radeon_crtc->ss_enabled =
1036 radeon_atombios_get_asic_ss_info(rdev,
1037 &radeon_crtc->ss,
1038 ASIC_INTERNAL_SS_ON_TMDS,
1039 mode->clock / 10);
1040 break;
1041 case ATOM_ENCODER_MODE_HDMI:
1042 if (ASIC_IS_DCE4(rdev))
1043 radeon_crtc->ss_enabled =
1044 radeon_atombios_get_asic_ss_info(rdev,
1045 &radeon_crtc->ss,
1046 ASIC_INTERNAL_SS_ON_HDMI,
1047 mode->clock / 10);
1048 break;
1049 default:
1050 break;
1051 }
1052 }
1053
1054
1055 radeon_crtc->adjusted_clock = atombios_adjust_pll(crtc, mode);
1056
1057 return true;
1058}
1059
1060static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
1061{
1062 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1063 struct drm_device *dev = crtc->dev;
1064 struct radeon_device *rdev = dev->dev_private;
1065 struct radeon_encoder *radeon_encoder =
1066 to_radeon_encoder(radeon_crtc->encoder);
1067 u32 pll_clock = mode->clock;
1068 u32 clock = mode->clock;
1069 u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
1070 struct radeon_pll *pll;
1071 int encoder_mode = atombios_get_encoder_mode(radeon_crtc->encoder);
1072
1073
1074 if (ASIC_IS_DCE5(rdev) &&
1075 (encoder_mode == ATOM_ENCODER_MODE_HDMI) &&
1076 (radeon_crtc->bpc > 8))
1077 clock = radeon_crtc->adjusted_clock;
1078
1079 switch (radeon_crtc->pll_id) {
1080 case ATOM_PPLL1:
1081 pll = &rdev->clock.p1pll;
1082 break;
1083 case ATOM_PPLL2:
1084 pll = &rdev->clock.p2pll;
1085 break;
1086 case ATOM_DCPLL:
1087 case ATOM_PPLL_INVALID:
1088 default:
1089 pll = &rdev->clock.dcpll;
1090 break;
1091 }
1092
1093
1094 pll->flags = radeon_crtc->pll_flags;
1095 pll->reference_div = radeon_crtc->pll_reference_div;
1096 pll->post_div = radeon_crtc->pll_post_div;
1097
1098 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
1099
1100 radeon_compute_pll_legacy(pll, radeon_crtc->adjusted_clock, &pll_clock,
1101 &fb_div, &frac_fb_div, &ref_div, &post_div);
1102 else if (ASIC_IS_AVIVO(rdev))
1103 radeon_compute_pll_avivo(pll, radeon_crtc->adjusted_clock, &pll_clock,
1104 &fb_div, &frac_fb_div, &ref_div, &post_div);
1105 else
1106 radeon_compute_pll_legacy(pll, radeon_crtc->adjusted_clock, &pll_clock,
1107 &fb_div, &frac_fb_div, &ref_div, &post_div);
1108
1109 atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id,
1110 radeon_crtc->crtc_id, &radeon_crtc->ss);
1111
1112 atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
1113 encoder_mode, radeon_encoder->encoder_id, clock,
1114 ref_div, fb_div, frac_fb_div, post_div,
1115 radeon_crtc->bpc, radeon_crtc->ss_enabled, &radeon_crtc->ss);
1116
1117 if (radeon_crtc->ss_enabled) {
1118
1119 if (ASIC_IS_DCE4(rdev)) {
1120 u32 step_size;
1121 u32 amount = (((fb_div * 10) + frac_fb_div) *
1122 (u32)radeon_crtc->ss.percentage) /
1123 (100 * (u32)radeon_crtc->ss.percentage_divider);
1124 radeon_crtc->ss.amount = (amount / 10) & ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK;
1125 radeon_crtc->ss.amount |= ((amount - (amount / 10)) << ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) &
1126 ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK;
1127 if (radeon_crtc->ss.type & ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD)
1128 step_size = (4 * amount * ref_div * ((u32)radeon_crtc->ss.rate * 2048)) /
1129 (125 * 25 * pll->reference_freq / 100);
1130 else
1131 step_size = (2 * amount * ref_div * ((u32)radeon_crtc->ss.rate * 2048)) /
1132 (125 * 25 * pll->reference_freq / 100);
1133 radeon_crtc->ss.step = step_size;
1134 }
1135
1136 atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id,
1137 radeon_crtc->crtc_id, &radeon_crtc->ss);
1138 }
1139}
1140
1141static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
1142 struct drm_framebuffer *fb,
1143 int x, int y, int atomic)
1144{
1145 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1146 struct drm_device *dev = crtc->dev;
1147 struct radeon_device *rdev = dev->dev_private;
1148 struct drm_framebuffer *target_fb;
1149 struct drm_gem_object *obj;
1150 struct radeon_bo *rbo;
1151 uint64_t fb_location;
1152 uint32_t fb_format, fb_pitch_pixels, tiling_flags;
1153 unsigned bankw, bankh, mtaspect, tile_split;
1154 u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE);
1155 u32 tmp, viewport_w, viewport_h;
1156 int r;
1157 bool bypass_lut = false;
1158 struct drm_format_name_buf format_name;
1159
1160
1161 if (!atomic && !crtc->primary->fb) {
1162 DRM_DEBUG_KMS("No FB bound\n");
1163 return 0;
1164 }
1165
1166 if (atomic)
1167 target_fb = fb;
1168 else
1169 target_fb = crtc->primary->fb;
1170
1171
1172
1173
1174 obj = target_fb->obj[0];
1175 rbo = gem_to_radeon_bo(obj);
1176 r = radeon_bo_reserve(rbo, false);
1177 if (unlikely(r != 0))
1178 return r;
1179
1180 if (atomic)
1181 fb_location = radeon_bo_gpu_offset(rbo);
1182 else {
1183 r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location);
1184 if (unlikely(r != 0)) {
1185 radeon_bo_unreserve(rbo);
1186 return -EINVAL;
1187 }
1188 }
1189
1190 radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
1191 radeon_bo_unreserve(rbo);
1192
1193 switch (target_fb->format->format) {
1194 case DRM_FORMAT_C8:
1195 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_8BPP) |
1196 EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_INDEXED));
1197 break;
1198 case DRM_FORMAT_XRGB4444:
1199 case DRM_FORMAT_ARGB4444:
1200 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
1201 EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB4444));
1202#ifdef __BIG_ENDIAN
1203 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16);
1204#endif
1205 break;
1206 case DRM_FORMAT_XRGB1555:
1207 case DRM_FORMAT_ARGB1555:
1208 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
1209 EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB1555));
1210#ifdef __BIG_ENDIAN
1211 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16);
1212#endif
1213 break;
1214 case DRM_FORMAT_BGRX5551:
1215 case DRM_FORMAT_BGRA5551:
1216 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
1217 EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_BGRA5551));
1218#ifdef __BIG_ENDIAN
1219 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16);
1220#endif
1221 break;
1222 case DRM_FORMAT_RGB565:
1223 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
1224 EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB565));
1225#ifdef __BIG_ENDIAN
1226 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16);
1227#endif
1228 break;
1229 case DRM_FORMAT_XRGB8888:
1230 case DRM_FORMAT_ARGB8888:
1231 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) |
1232 EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB8888));
1233#ifdef __BIG_ENDIAN
1234 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32);
1235#endif
1236 break;
1237 case DRM_FORMAT_XRGB2101010:
1238 case DRM_FORMAT_ARGB2101010:
1239 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) |
1240 EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB2101010));
1241#ifdef __BIG_ENDIAN
1242 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32);
1243#endif
1244
1245 bypass_lut = true;
1246 break;
1247 case DRM_FORMAT_BGRX1010102:
1248 case DRM_FORMAT_BGRA1010102:
1249 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) |
1250 EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_BGRA1010102));
1251#ifdef __BIG_ENDIAN
1252 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32);
1253#endif
1254
1255 bypass_lut = true;
1256 break;
1257 default:
1258 DRM_ERROR("Unsupported screen format %s\n",
1259 drm_get_format_name(target_fb->format->format, &format_name));
1260 return -EINVAL;
1261 }
1262
1263 if (tiling_flags & RADEON_TILING_MACRO) {
1264 evergreen_tiling_fields(tiling_flags, &bankw, &bankh, &mtaspect, &tile_split);
1265
1266
1267 if (rdev->family >= CHIP_TAHITI) {
1268 unsigned index, num_banks;
1269
1270 if (rdev->family >= CHIP_BONAIRE) {
1271 unsigned tileb, tile_split_bytes;
1272
1273
1274 tile_split_bytes = 64 << tile_split;
1275 tileb = 8 * 8 * target_fb->format->cpp[0];
1276 tileb = min(tile_split_bytes, tileb);
1277
1278 for (index = 0; tileb > 64; index++)
1279 tileb >>= 1;
1280
1281 if (index >= 16) {
1282 DRM_ERROR("Wrong screen bpp (%u) or tile split (%u)\n",
1283 target_fb->format->cpp[0] * 8,
1284 tile_split);
1285 return -EINVAL;
1286 }
1287
1288 num_banks = (rdev->config.cik.macrotile_mode_array[index] >> 6) & 0x3;
1289 } else {
1290 switch (target_fb->format->cpp[0] * 8) {
1291 case 8:
1292 index = 10;
1293 break;
1294 case 16:
1295 index = SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP;
1296 break;
1297 default:
1298 case 32:
1299 index = SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP;
1300 break;
1301 }
1302
1303 num_banks = (rdev->config.si.tile_mode_array[index] >> 20) & 0x3;
1304 }
1305
1306 fb_format |= EVERGREEN_GRPH_NUM_BANKS(num_banks);
1307 } else {
1308
1309 if (rdev->family >= CHIP_CAYMAN)
1310 tmp = rdev->config.cayman.tile_config;
1311 else
1312 tmp = rdev->config.evergreen.tile_config;
1313
1314 switch ((tmp & 0xf0) >> 4) {
1315 case 0:
1316 fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_4_BANK);
1317 break;
1318 case 1:
1319 default:
1320 fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_8_BANK);
1321 break;
1322 case 2:
1323 fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_16_BANK);
1324 break;
1325 }
1326 }
1327
1328 fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1);
1329 fb_format |= EVERGREEN_GRPH_TILE_SPLIT(tile_split);
1330 fb_format |= EVERGREEN_GRPH_BANK_WIDTH(bankw);
1331 fb_format |= EVERGREEN_GRPH_BANK_HEIGHT(bankh);
1332 fb_format |= EVERGREEN_GRPH_MACRO_TILE_ASPECT(mtaspect);
1333 if (rdev->family >= CHIP_BONAIRE) {
1334
1335 fb_format |= CIK_GRPH_MICRO_TILE_MODE(CIK_DISPLAY_MICRO_TILING);
1336 }
1337 } else if (tiling_flags & RADEON_TILING_MICRO)
1338 fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1);
1339
1340 if (rdev->family >= CHIP_BONAIRE) {
1341
1342
1343
1344 u32 pipe_config = (rdev->config.cik.tile_mode_array[10] >> 6) & 0x1f;
1345
1346 fb_format |= CIK_GRPH_PIPE_CONFIG(pipe_config);
1347 } else if ((rdev->family == CHIP_TAHITI) ||
1348 (rdev->family == CHIP_PITCAIRN))
1349 fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P8_32x32_8x16);
1350 else if ((rdev->family == CHIP_VERDE) ||
1351 (rdev->family == CHIP_OLAND) ||
1352 (rdev->family == CHIP_HAINAN))
1353 fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P4_8x16);
1354
1355 switch (radeon_crtc->crtc_id) {
1356 case 0:
1357 WREG32(AVIVO_D1VGA_CONTROL, 0);
1358 break;
1359 case 1:
1360 WREG32(AVIVO_D2VGA_CONTROL, 0);
1361 break;
1362 case 2:
1363 WREG32(EVERGREEN_D3VGA_CONTROL, 0);
1364 break;
1365 case 3:
1366 WREG32(EVERGREEN_D4VGA_CONTROL, 0);
1367 break;
1368 case 4:
1369 WREG32(EVERGREEN_D5VGA_CONTROL, 0);
1370 break;
1371 case 5:
1372 WREG32(EVERGREEN_D6VGA_CONTROL, 0);
1373 break;
1374 default:
1375 break;
1376 }
1377
1378
1379
1380
1381 WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, 0);
1382
1383 WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
1384 upper_32_bits(fb_location));
1385 WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
1386 upper_32_bits(fb_location));
1387 WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
1388 (u32)fb_location & EVERGREEN_GRPH_SURFACE_ADDRESS_MASK);
1389 WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
1390 (u32) fb_location & EVERGREEN_GRPH_SURFACE_ADDRESS_MASK);
1391 WREG32(EVERGREEN_GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format);
1392 WREG32(EVERGREEN_GRPH_SWAP_CONTROL + radeon_crtc->crtc_offset, fb_swap);
1393
1394
1395
1396
1397
1398
1399 WREG32_P(EVERGREEN_GRPH_LUT_10BIT_BYPASS_CONTROL + radeon_crtc->crtc_offset,
1400 (bypass_lut ? EVERGREEN_LUT_10BIT_BYPASS_EN : 0),
1401 ~EVERGREEN_LUT_10BIT_BYPASS_EN);
1402
1403 if (bypass_lut)
1404 DRM_DEBUG_KMS("Bypassing hardware LUT due to 10 bit fb scanout.\n");
1405
1406 WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0);
1407 WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0);
1408 WREG32(EVERGREEN_GRPH_X_START + radeon_crtc->crtc_offset, 0);
1409 WREG32(EVERGREEN_GRPH_Y_START + radeon_crtc->crtc_offset, 0);
1410 WREG32(EVERGREEN_GRPH_X_END + radeon_crtc->crtc_offset, target_fb->width);
1411 WREG32(EVERGREEN_GRPH_Y_END + radeon_crtc->crtc_offset, target_fb->height);
1412
1413 fb_pitch_pixels = target_fb->pitches[0] / target_fb->format->cpp[0];
1414 WREG32(EVERGREEN_GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels);
1415 WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
1416
1417 if (rdev->family >= CHIP_BONAIRE)
1418 WREG32(CIK_LB_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
1419 target_fb->height);
1420 else
1421 WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
1422 target_fb->height);
1423 x &= ~3;
1424 y &= ~1;
1425 WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset,
1426 (x << 16) | y);
1427 viewport_w = crtc->mode.hdisplay;
1428 viewport_h = (crtc->mode.vdisplay + 1) & ~1;
1429 if ((rdev->family >= CHIP_BONAIRE) &&
1430 (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE))
1431 viewport_h *= 2;
1432 WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
1433 (viewport_w << 16) | viewport_h);
1434
1435
1436 WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0);
1437
1438 if (!atomic && fb && fb != crtc->primary->fb) {
1439 rbo = gem_to_radeon_bo(fb->obj[0]);
1440 r = radeon_bo_reserve(rbo, false);
1441 if (unlikely(r != 0))
1442 return r;
1443 radeon_bo_unpin(rbo);
1444 radeon_bo_unreserve(rbo);
1445 }
1446
1447
1448 radeon_bandwidth_update(rdev);
1449
1450 return 0;
1451}
1452
1453static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
1454 struct drm_framebuffer *fb,
1455 int x, int y, int atomic)
1456{
1457 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1458 struct drm_device *dev = crtc->dev;
1459 struct radeon_device *rdev = dev->dev_private;
1460 struct drm_gem_object *obj;
1461 struct radeon_bo *rbo;
1462 struct drm_framebuffer *target_fb;
1463 uint64_t fb_location;
1464 uint32_t fb_format, fb_pitch_pixels, tiling_flags;
1465 u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE;
1466 u32 viewport_w, viewport_h;
1467 int r;
1468 bool bypass_lut = false;
1469 struct drm_format_name_buf format_name;
1470
1471
1472 if (!atomic && !crtc->primary->fb) {
1473 DRM_DEBUG_KMS("No FB bound\n");
1474 return 0;
1475 }
1476
1477 if (atomic)
1478 target_fb = fb;
1479 else
1480 target_fb = crtc->primary->fb;
1481
1482 obj = target_fb->obj[0];
1483 rbo = gem_to_radeon_bo(obj);
1484 r = radeon_bo_reserve(rbo, false);
1485 if (unlikely(r != 0))
1486 return r;
1487
1488
1489
1490
1491 if (atomic)
1492 fb_location = radeon_bo_gpu_offset(rbo);
1493 else {
1494 r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location);
1495 if (unlikely(r != 0)) {
1496 radeon_bo_unreserve(rbo);
1497 return -EINVAL;
1498 }
1499 }
1500 radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
1501 radeon_bo_unreserve(rbo);
1502
1503 switch (target_fb->format->format) {
1504 case DRM_FORMAT_C8:
1505 fb_format =
1506 AVIVO_D1GRPH_CONTROL_DEPTH_8BPP |
1507 AVIVO_D1GRPH_CONTROL_8BPP_INDEXED;
1508 break;
1509 case DRM_FORMAT_XRGB4444:
1510 case DRM_FORMAT_ARGB4444:
1511 fb_format =
1512 AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
1513 AVIVO_D1GRPH_CONTROL_16BPP_ARGB4444;
1514#ifdef __BIG_ENDIAN
1515 fb_swap = R600_D1GRPH_SWAP_ENDIAN_16BIT;
1516#endif
1517 break;
1518 case DRM_FORMAT_XRGB1555:
1519 fb_format =
1520 AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
1521 AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555;
1522#ifdef __BIG_ENDIAN
1523 fb_swap = R600_D1GRPH_SWAP_ENDIAN_16BIT;
1524#endif
1525 break;
1526 case DRM_FORMAT_RGB565:
1527 fb_format =
1528 AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
1529 AVIVO_D1GRPH_CONTROL_16BPP_RGB565;
1530#ifdef __BIG_ENDIAN
1531 fb_swap = R600_D1GRPH_SWAP_ENDIAN_16BIT;
1532#endif
1533 break;
1534 case DRM_FORMAT_XRGB8888:
1535 case DRM_FORMAT_ARGB8888:
1536 fb_format =
1537 AVIVO_D1GRPH_CONTROL_DEPTH_32BPP |
1538 AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888;
1539#ifdef __BIG_ENDIAN
1540 fb_swap = R600_D1GRPH_SWAP_ENDIAN_32BIT;
1541#endif
1542 break;
1543 case DRM_FORMAT_XRGB2101010:
1544 case DRM_FORMAT_ARGB2101010:
1545 fb_format =
1546 AVIVO_D1GRPH_CONTROL_DEPTH_32BPP |
1547 AVIVO_D1GRPH_CONTROL_32BPP_ARGB2101010;
1548#ifdef __BIG_ENDIAN
1549 fb_swap = R600_D1GRPH_SWAP_ENDIAN_32BIT;
1550#endif
1551
1552 bypass_lut = true;
1553 break;
1554 default:
1555 DRM_ERROR("Unsupported screen format %s\n",
1556 drm_get_format_name(target_fb->format->format, &format_name));
1557 return -EINVAL;
1558 }
1559
1560 if (rdev->family >= CHIP_R600) {
1561 if (tiling_flags & RADEON_TILING_MACRO)
1562 fb_format |= R600_D1GRPH_ARRAY_MODE_2D_TILED_THIN1;
1563 else if (tiling_flags & RADEON_TILING_MICRO)
1564 fb_format |= R600_D1GRPH_ARRAY_MODE_1D_TILED_THIN1;
1565 } else {
1566 if (tiling_flags & RADEON_TILING_MACRO)
1567 fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE;
1568
1569 if (tiling_flags & RADEON_TILING_MICRO)
1570 fb_format |= AVIVO_D1GRPH_TILED;
1571 }
1572
1573 if (radeon_crtc->crtc_id == 0)
1574 WREG32(AVIVO_D1VGA_CONTROL, 0);
1575 else
1576 WREG32(AVIVO_D2VGA_CONTROL, 0);
1577
1578
1579
1580
1581 WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, 0);
1582
1583 if (rdev->family >= CHIP_RV770) {
1584 if (radeon_crtc->crtc_id) {
1585 WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
1586 WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
1587 } else {
1588 WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
1589 WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
1590 }
1591 }
1592 WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
1593 (u32) fb_location);
1594 WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS +
1595 radeon_crtc->crtc_offset, (u32) fb_location);
1596 WREG32(AVIVO_D1GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format);
1597 if (rdev->family >= CHIP_R600)
1598 WREG32(R600_D1GRPH_SWAP_CONTROL + radeon_crtc->crtc_offset, fb_swap);
1599
1600
1601 WREG32_P(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset,
1602 (bypass_lut ? AVIVO_LUT_10BIT_BYPASS_EN : 0), ~AVIVO_LUT_10BIT_BYPASS_EN);
1603
1604 if (bypass_lut)
1605 DRM_DEBUG_KMS("Bypassing hardware LUT due to 10 bit fb scanout.\n");
1606
1607 WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0);
1608 WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0);
1609 WREG32(AVIVO_D1GRPH_X_START + radeon_crtc->crtc_offset, 0);
1610 WREG32(AVIVO_D1GRPH_Y_START + radeon_crtc->crtc_offset, 0);
1611 WREG32(AVIVO_D1GRPH_X_END + radeon_crtc->crtc_offset, target_fb->width);
1612 WREG32(AVIVO_D1GRPH_Y_END + radeon_crtc->crtc_offset, target_fb->height);
1613
1614 fb_pitch_pixels = target_fb->pitches[0] / target_fb->format->cpp[0];
1615 WREG32(AVIVO_D1GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels);
1616 WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
1617
1618 WREG32(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
1619 target_fb->height);
1620 x &= ~3;
1621 y &= ~1;
1622 WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset,
1623 (x << 16) | y);
1624 viewport_w = crtc->mode.hdisplay;
1625 viewport_h = (crtc->mode.vdisplay + 1) & ~1;
1626 WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
1627 (viewport_w << 16) | viewport_h);
1628
1629
1630 WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 3);
1631
1632 if (!atomic && fb && fb != crtc->primary->fb) {
1633 rbo = gem_to_radeon_bo(fb->obj[0]);
1634 r = radeon_bo_reserve(rbo, false);
1635 if (unlikely(r != 0))
1636 return r;
1637 radeon_bo_unpin(rbo);
1638 radeon_bo_unreserve(rbo);
1639 }
1640
1641
1642 radeon_bandwidth_update(rdev);
1643
1644 return 0;
1645}
1646
1647int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
1648 struct drm_framebuffer *old_fb)
1649{
1650 struct drm_device *dev = crtc->dev;
1651 struct radeon_device *rdev = dev->dev_private;
1652
1653 if (ASIC_IS_DCE4(rdev))
1654 return dce4_crtc_do_set_base(crtc, old_fb, x, y, 0);
1655 else if (ASIC_IS_AVIVO(rdev))
1656 return avivo_crtc_do_set_base(crtc, old_fb, x, y, 0);
1657 else
1658 return radeon_crtc_do_set_base(crtc, old_fb, x, y, 0);
1659}
1660
1661int atombios_crtc_set_base_atomic(struct drm_crtc *crtc,
1662 struct drm_framebuffer *fb,
1663 int x, int y, enum mode_set_atomic state)
1664{
1665 struct drm_device *dev = crtc->dev;
1666 struct radeon_device *rdev = dev->dev_private;
1667
1668 if (ASIC_IS_DCE4(rdev))
1669 return dce4_crtc_do_set_base(crtc, fb, x, y, 1);
1670 else if (ASIC_IS_AVIVO(rdev))
1671 return avivo_crtc_do_set_base(crtc, fb, x, y, 1);
1672 else
1673 return radeon_crtc_do_set_base(crtc, fb, x, y, 1);
1674}
1675
1676
1677static void radeon_legacy_atom_fixup(struct drm_crtc *crtc)
1678{
1679 struct drm_device *dev = crtc->dev;
1680 struct radeon_device *rdev = dev->dev_private;
1681 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1682 u32 disp_merge_cntl;
1683
1684 switch (radeon_crtc->crtc_id) {
1685 case 0:
1686 disp_merge_cntl = RREG32(RADEON_DISP_MERGE_CNTL);
1687 disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN;
1688 WREG32(RADEON_DISP_MERGE_CNTL, disp_merge_cntl);
1689 break;
1690 case 1:
1691 disp_merge_cntl = RREG32(RADEON_DISP2_MERGE_CNTL);
1692 disp_merge_cntl &= ~RADEON_DISP2_RGB_OFFSET_EN;
1693 WREG32(RADEON_DISP2_MERGE_CNTL, disp_merge_cntl);
1694 WREG32(RADEON_FP_H2_SYNC_STRT_WID, RREG32(RADEON_CRTC2_H_SYNC_STRT_WID));
1695 WREG32(RADEON_FP_V2_SYNC_STRT_WID, RREG32(RADEON_CRTC2_V_SYNC_STRT_WID));
1696 break;
1697 }
1698}
1699
1700
1701
1702
1703
1704
1705
1706
1707static u32 radeon_get_pll_use_mask(struct drm_crtc *crtc)
1708{
1709 struct drm_device *dev = crtc->dev;
1710 struct drm_crtc *test_crtc;
1711 struct radeon_crtc *test_radeon_crtc;
1712 u32 pll_in_use = 0;
1713
1714 list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
1715 if (crtc == test_crtc)
1716 continue;
1717
1718 test_radeon_crtc = to_radeon_crtc(test_crtc);
1719 if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID)
1720 pll_in_use |= (1 << test_radeon_crtc->pll_id);
1721 }
1722 return pll_in_use;
1723}
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734static int radeon_get_shared_dp_ppll(struct drm_crtc *crtc)
1735{
1736 struct drm_device *dev = crtc->dev;
1737 struct radeon_device *rdev = dev->dev_private;
1738 struct drm_crtc *test_crtc;
1739 struct radeon_crtc *test_radeon_crtc;
1740
1741 list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
1742 if (crtc == test_crtc)
1743 continue;
1744 test_radeon_crtc = to_radeon_crtc(test_crtc);
1745 if (test_radeon_crtc->encoder &&
1746 ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_radeon_crtc->encoder))) {
1747
1748 if (ASIC_IS_DCE61(rdev) && !ASIC_IS_DCE8(rdev) &&
1749 test_radeon_crtc->pll_id == ATOM_PPLL2)
1750 continue;
1751
1752 if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID)
1753 return test_radeon_crtc->pll_id;
1754 }
1755 }
1756 return ATOM_PPLL_INVALID;
1757}
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768static int radeon_get_shared_nondp_ppll(struct drm_crtc *crtc)
1769{
1770 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1771 struct drm_device *dev = crtc->dev;
1772 struct radeon_device *rdev = dev->dev_private;
1773 struct drm_crtc *test_crtc;
1774 struct radeon_crtc *test_radeon_crtc;
1775 u32 adjusted_clock, test_adjusted_clock;
1776
1777 adjusted_clock = radeon_crtc->adjusted_clock;
1778
1779 if (adjusted_clock == 0)
1780 return ATOM_PPLL_INVALID;
1781
1782 list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
1783 if (crtc == test_crtc)
1784 continue;
1785 test_radeon_crtc = to_radeon_crtc(test_crtc);
1786 if (test_radeon_crtc->encoder &&
1787 !ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_radeon_crtc->encoder))) {
1788
1789 if (ASIC_IS_DCE61(rdev) && !ASIC_IS_DCE8(rdev) &&
1790 test_radeon_crtc->pll_id == ATOM_PPLL2)
1791 continue;
1792
1793 if (test_radeon_crtc->connector == radeon_crtc->connector) {
1794
1795 if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID)
1796 return test_radeon_crtc->pll_id;
1797 }
1798
1799 test_adjusted_clock = test_radeon_crtc->adjusted_clock;
1800 if ((crtc->mode.clock == test_crtc->mode.clock) &&
1801 (adjusted_clock == test_adjusted_clock) &&
1802 (radeon_crtc->ss_enabled == test_radeon_crtc->ss_enabled) &&
1803 (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID))
1804 return test_radeon_crtc->pll_id;
1805 }
1806 }
1807 return ATOM_PPLL_INVALID;
1808}
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847static int radeon_atom_pick_pll(struct drm_crtc *crtc)
1848{
1849 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1850 struct drm_device *dev = crtc->dev;
1851 struct radeon_device *rdev = dev->dev_private;
1852 struct radeon_encoder *radeon_encoder =
1853 to_radeon_encoder(radeon_crtc->encoder);
1854 u32 pll_in_use;
1855 int pll;
1856
1857 if (ASIC_IS_DCE8(rdev)) {
1858 if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
1859 if (rdev->clock.dp_extclk)
1860
1861 return ATOM_PPLL_INVALID;
1862 else {
1863
1864 pll = radeon_get_shared_dp_ppll(crtc);
1865 if (pll != ATOM_PPLL_INVALID)
1866 return pll;
1867 }
1868 } else {
1869
1870 pll = radeon_get_shared_nondp_ppll(crtc);
1871 if (pll != ATOM_PPLL_INVALID)
1872 return pll;
1873 }
1874
1875 if ((rdev->family == CHIP_KABINI) ||
1876 (rdev->family == CHIP_MULLINS)) {
1877
1878 pll_in_use = radeon_get_pll_use_mask(crtc);
1879 if (!(pll_in_use & (1 << ATOM_PPLL2)))
1880 return ATOM_PPLL2;
1881 if (!(pll_in_use & (1 << ATOM_PPLL1)))
1882 return ATOM_PPLL1;
1883 DRM_ERROR("unable to allocate a PPLL\n");
1884 return ATOM_PPLL_INVALID;
1885 } else {
1886
1887 pll_in_use = radeon_get_pll_use_mask(crtc);
1888 if (!(pll_in_use & (1 << ATOM_PPLL2)))
1889 return ATOM_PPLL2;
1890 if (!(pll_in_use & (1 << ATOM_PPLL1)))
1891 return ATOM_PPLL1;
1892 if (!(pll_in_use & (1 << ATOM_PPLL0)))
1893 return ATOM_PPLL0;
1894 DRM_ERROR("unable to allocate a PPLL\n");
1895 return ATOM_PPLL_INVALID;
1896 }
1897 } else if (ASIC_IS_DCE61(rdev)) {
1898 struct radeon_encoder_atom_dig *dig =
1899 radeon_encoder->enc_priv;
1900
1901 if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY) &&
1902 (dig->linkb == false))
1903
1904 return ATOM_PPLL2;
1905 else if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
1906
1907 if (rdev->clock.dp_extclk)
1908
1909 return ATOM_PPLL_INVALID;
1910 else {
1911
1912 pll = radeon_get_shared_dp_ppll(crtc);
1913 if (pll != ATOM_PPLL_INVALID)
1914 return pll;
1915 }
1916 } else {
1917
1918 pll = radeon_get_shared_nondp_ppll(crtc);
1919 if (pll != ATOM_PPLL_INVALID)
1920 return pll;
1921 }
1922
1923 pll_in_use = radeon_get_pll_use_mask(crtc);
1924 if (!(pll_in_use & (1 << ATOM_PPLL0)))
1925 return ATOM_PPLL0;
1926 if (!(pll_in_use & (1 << ATOM_PPLL1)))
1927 return ATOM_PPLL1;
1928 DRM_ERROR("unable to allocate a PPLL\n");
1929 return ATOM_PPLL_INVALID;
1930 } else if (ASIC_IS_DCE41(rdev)) {
1931
1932 if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
1933 if (rdev->clock.dp_extclk)
1934
1935 return ATOM_PPLL_INVALID;
1936 }
1937 pll_in_use = radeon_get_pll_use_mask(crtc);
1938 if (!(pll_in_use & (1 << ATOM_PPLL1)))
1939 return ATOM_PPLL1;
1940 if (!(pll_in_use & (1 << ATOM_PPLL2)))
1941 return ATOM_PPLL2;
1942 DRM_ERROR("unable to allocate a PPLL\n");
1943 return ATOM_PPLL_INVALID;
1944 } else if (ASIC_IS_DCE4(rdev)) {
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955 if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
1956 if (rdev->clock.dp_extclk)
1957
1958 return ATOM_PPLL_INVALID;
1959 else if (ASIC_IS_DCE6(rdev))
1960
1961 return ATOM_PPLL0;
1962 else if (ASIC_IS_DCE5(rdev))
1963
1964 return ATOM_DCPLL;
1965 else {
1966
1967 pll = radeon_get_shared_dp_ppll(crtc);
1968 if (pll != ATOM_PPLL_INVALID)
1969 return pll;
1970 }
1971 } else {
1972
1973 pll = radeon_get_shared_nondp_ppll(crtc);
1974 if (pll != ATOM_PPLL_INVALID)
1975 return pll;
1976 }
1977
1978 pll_in_use = radeon_get_pll_use_mask(crtc);
1979 if (!(pll_in_use & (1 << ATOM_PPLL1)))
1980 return ATOM_PPLL1;
1981 if (!(pll_in_use & (1 << ATOM_PPLL2)))
1982 return ATOM_PPLL2;
1983 DRM_ERROR("unable to allocate a PPLL\n");
1984 return ATOM_PPLL_INVALID;
1985 } else {
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001 return radeon_crtc->crtc_id;
2002 }
2003}
2004
2005void radeon_atom_disp_eng_pll_init(struct radeon_device *rdev)
2006{
2007
2008 if (ASIC_IS_DCE6(rdev))
2009 atombios_crtc_set_disp_eng_pll(rdev, rdev->clock.default_dispclk);
2010 else if (ASIC_IS_DCE4(rdev)) {
2011 struct radeon_atom_ss ss;
2012 bool ss_enabled = radeon_atombios_get_asic_ss_info(rdev, &ss,
2013 ASIC_INTERNAL_SS_ON_DCPLL,
2014 rdev->clock.default_dispclk);
2015 if (ss_enabled)
2016 atombios_crtc_program_ss(rdev, ATOM_DISABLE, ATOM_DCPLL, -1, &ss);
2017
2018 atombios_crtc_set_disp_eng_pll(rdev, rdev->clock.default_dispclk);
2019 if (ss_enabled)
2020 atombios_crtc_program_ss(rdev, ATOM_ENABLE, ATOM_DCPLL, -1, &ss);
2021 }
2022
2023}
2024
2025int atombios_crtc_mode_set(struct drm_crtc *crtc,
2026 struct drm_display_mode *mode,
2027 struct drm_display_mode *adjusted_mode,
2028 int x, int y, struct drm_framebuffer *old_fb)
2029{
2030 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
2031 struct drm_device *dev = crtc->dev;
2032 struct radeon_device *rdev = dev->dev_private;
2033 struct radeon_encoder *radeon_encoder =
2034 to_radeon_encoder(radeon_crtc->encoder);
2035 bool is_tvcv = false;
2036
2037 if (radeon_encoder->active_device &
2038 (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
2039 is_tvcv = true;
2040
2041 if (!radeon_crtc->adjusted_clock)
2042 return -EINVAL;
2043
2044 atombios_crtc_set_pll(crtc, adjusted_mode);
2045
2046 if (ASIC_IS_DCE4(rdev))
2047 atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
2048 else if (ASIC_IS_AVIVO(rdev)) {
2049 if (is_tvcv)
2050 atombios_crtc_set_timing(crtc, adjusted_mode);
2051 else
2052 atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
2053 } else {
2054 atombios_crtc_set_timing(crtc, adjusted_mode);
2055 if (radeon_crtc->crtc_id == 0)
2056 atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
2057 radeon_legacy_atom_fixup(crtc);
2058 }
2059 atombios_crtc_set_base(crtc, x, y, old_fb);
2060 atombios_overscan_setup(crtc, mode, adjusted_mode);
2061 atombios_scaler_setup(crtc);
2062 radeon_cursor_reset(crtc);
2063
2064 radeon_crtc->hw_mode = *adjusted_mode;
2065
2066 return 0;
2067}
2068
2069static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc,
2070 const struct drm_display_mode *mode,
2071 struct drm_display_mode *adjusted_mode)
2072{
2073 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
2074 struct drm_device *dev = crtc->dev;
2075 struct drm_encoder *encoder;
2076
2077
2078 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
2079 if (encoder->crtc == crtc) {
2080 radeon_crtc->encoder = encoder;
2081 radeon_crtc->connector = radeon_get_connector_for_encoder(encoder);
2082 break;
2083 }
2084 }
2085 if ((radeon_crtc->encoder == NULL) || (radeon_crtc->connector == NULL)) {
2086 radeon_crtc->encoder = NULL;
2087 radeon_crtc->connector = NULL;
2088 return false;
2089 }
2090 if (radeon_crtc->encoder) {
2091 struct radeon_encoder *radeon_encoder =
2092 to_radeon_encoder(radeon_crtc->encoder);
2093
2094 radeon_crtc->output_csc = radeon_encoder->output_csc;
2095 }
2096 if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode))
2097 return false;
2098 if (!atombios_crtc_prepare_pll(crtc, adjusted_mode))
2099 return false;
2100
2101 radeon_crtc->pll_id = radeon_atom_pick_pll(crtc);
2102
2103 if ((radeon_crtc->pll_id == ATOM_PPLL_INVALID) &&
2104 !ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder)))
2105 return false;
2106
2107 return true;
2108}
2109
2110static void atombios_crtc_prepare(struct drm_crtc *crtc)
2111{
2112 struct drm_device *dev = crtc->dev;
2113 struct radeon_device *rdev = dev->dev_private;
2114
2115
2116 if (ASIC_IS_DCE6(rdev))
2117 atombios_powergate_crtc(crtc, ATOM_DISABLE);
2118
2119 atombios_lock_crtc(crtc, ATOM_ENABLE);
2120 atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
2121}
2122
2123static void atombios_crtc_commit(struct drm_crtc *crtc)
2124{
2125 atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
2126 atombios_lock_crtc(crtc, ATOM_DISABLE);
2127}
2128
2129static void atombios_crtc_disable(struct drm_crtc *crtc)
2130{
2131 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
2132 struct drm_device *dev = crtc->dev;
2133 struct radeon_device *rdev = dev->dev_private;
2134 struct radeon_atom_ss ss;
2135 int i;
2136
2137 atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
2138 if (crtc->primary->fb) {
2139 int r;
2140 struct radeon_bo *rbo;
2141
2142 rbo = gem_to_radeon_bo(crtc->primary->fb->obj[0]);
2143 r = radeon_bo_reserve(rbo, false);
2144 if (unlikely(r))
2145 DRM_ERROR("failed to reserve rbo before unpin\n");
2146 else {
2147 radeon_bo_unpin(rbo);
2148 radeon_bo_unreserve(rbo);
2149 }
2150 }
2151
2152 if (ASIC_IS_DCE4(rdev))
2153 WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 0);
2154 else if (ASIC_IS_AVIVO(rdev))
2155 WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 0);
2156
2157 if (ASIC_IS_DCE6(rdev))
2158 atombios_powergate_crtc(crtc, ATOM_ENABLE);
2159
2160 for (i = 0; i < rdev->num_crtc; i++) {
2161 if (rdev->mode_info.crtcs[i] &&
2162 rdev->mode_info.crtcs[i]->enabled &&
2163 i != radeon_crtc->crtc_id &&
2164 radeon_crtc->pll_id == rdev->mode_info.crtcs[i]->pll_id) {
2165
2166
2167
2168 goto done;
2169 }
2170 }
2171
2172 switch (radeon_crtc->pll_id) {
2173 case ATOM_PPLL1:
2174 case ATOM_PPLL2:
2175
2176 atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
2177 0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss);
2178 break;
2179 case ATOM_PPLL0:
2180
2181 if ((rdev->family == CHIP_ARUBA) ||
2182 (rdev->family == CHIP_KAVERI) ||
2183 (rdev->family == CHIP_BONAIRE) ||
2184 (rdev->family == CHIP_HAWAII))
2185 atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
2186 0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss);
2187 break;
2188 default:
2189 break;
2190 }
2191done:
2192 radeon_crtc->pll_id = ATOM_PPLL_INVALID;
2193 radeon_crtc->adjusted_clock = 0;
2194 radeon_crtc->encoder = NULL;
2195 radeon_crtc->connector = NULL;
2196}
2197
2198static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
2199 .dpms = atombios_crtc_dpms,
2200 .mode_fixup = atombios_crtc_mode_fixup,
2201 .mode_set = atombios_crtc_mode_set,
2202 .mode_set_base = atombios_crtc_set_base,
2203 .mode_set_base_atomic = atombios_crtc_set_base_atomic,
2204 .prepare = atombios_crtc_prepare,
2205 .commit = atombios_crtc_commit,
2206 .disable = atombios_crtc_disable,
2207};
2208
2209void radeon_atombios_init_crtc(struct drm_device *dev,
2210 struct radeon_crtc *radeon_crtc)
2211{
2212 struct radeon_device *rdev = dev->dev_private;
2213
2214 if (ASIC_IS_DCE4(rdev)) {
2215 switch (radeon_crtc->crtc_id) {
2216 case 0:
2217 default:
2218 radeon_crtc->crtc_offset = EVERGREEN_CRTC0_REGISTER_OFFSET;
2219 break;
2220 case 1:
2221 radeon_crtc->crtc_offset = EVERGREEN_CRTC1_REGISTER_OFFSET;
2222 break;
2223 case 2:
2224 radeon_crtc->crtc_offset = EVERGREEN_CRTC2_REGISTER_OFFSET;
2225 break;
2226 case 3:
2227 radeon_crtc->crtc_offset = EVERGREEN_CRTC3_REGISTER_OFFSET;
2228 break;
2229 case 4:
2230 radeon_crtc->crtc_offset = EVERGREEN_CRTC4_REGISTER_OFFSET;
2231 break;
2232 case 5:
2233 radeon_crtc->crtc_offset = EVERGREEN_CRTC5_REGISTER_OFFSET;
2234 break;
2235 }
2236 } else {
2237 if (radeon_crtc->crtc_id == 1)
2238 radeon_crtc->crtc_offset =
2239 AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL;
2240 else
2241 radeon_crtc->crtc_offset = 0;
2242 }
2243 radeon_crtc->pll_id = ATOM_PPLL_INVALID;
2244 radeon_crtc->adjusted_clock = 0;
2245 radeon_crtc->encoder = NULL;
2246 radeon_crtc->connector = NULL;
2247 drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs);
2248}
2249