Subversion Repositories Kolibri OS

Rev

Rev 1404 | Rev 1963 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1123 serge 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
 */
1179 serge 26
#include 
27
#include 
28
#include 
1123 serge 29
#include "radeon_fixed.h"
30
#include "radeon.h"
31
#include "atom.h"
32
#include "atom-bits.h"
33
 
1179 serge 34
static void atombios_overscan_setup(struct drm_crtc *crtc,
35
				    struct drm_display_mode *mode,
36
				    struct drm_display_mode *adjusted_mode)
37
{
38
	struct drm_device *dev = crtc->dev;
39
	struct radeon_device *rdev = dev->dev_private;
40
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
41
	SET_CRTC_OVERSCAN_PS_ALLOCATION args;
42
	int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_OverScan);
43
	int a1, a2;
44
 
45
	memset(&args, 0, sizeof(args));
46
 
47
	args.usOverscanRight = 0;
48
	args.usOverscanLeft = 0;
49
	args.usOverscanBottom = 0;
50
	args.usOverscanTop = 0;
51
	args.ucCRTC = radeon_crtc->crtc_id;
52
 
53
	switch (radeon_crtc->rmx_type) {
54
	case RMX_CENTER:
55
		args.usOverscanTop = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2;
56
		args.usOverscanBottom = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2;
57
		args.usOverscanLeft = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2;
58
		args.usOverscanRight = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2;
59
		atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
60
		break;
61
	case RMX_ASPECT:
62
		a1 = mode->crtc_vdisplay * adjusted_mode->crtc_hdisplay;
63
		a2 = adjusted_mode->crtc_vdisplay * mode->crtc_hdisplay;
64
 
65
		if (a1 > a2) {
66
			args.usOverscanLeft = (adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2;
67
			args.usOverscanRight = (adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2;
68
		} else if (a2 > a1) {
69
			args.usOverscanLeft = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2;
70
			args.usOverscanRight = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2;
71
		}
72
		atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
73
		break;
74
	case RMX_FULL:
75
	default:
76
		args.usOverscanRight = 0;
77
		args.usOverscanLeft = 0;
78
		args.usOverscanBottom = 0;
79
		args.usOverscanTop = 0;
80
		atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
81
		break;
82
	}
83
}
84
 
85
static void atombios_scaler_setup(struct drm_crtc *crtc)
86
{
87
	struct drm_device *dev = crtc->dev;
88
	struct radeon_device *rdev = dev->dev_private;
89
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
90
	ENABLE_SCALER_PS_ALLOCATION args;
91
	int index = GetIndexIntoMasterTable(COMMAND, EnableScaler);
92
 
93
	/* fixme - fill in enc_priv for atom dac */
94
	enum radeon_tv_std tv_std = TV_STD_NTSC;
95
	bool is_tv = false, is_cv = false;
96
	struct drm_encoder *encoder;
97
 
98
	if (!ASIC_IS_AVIVO(rdev) && radeon_crtc->crtc_id)
99
		return;
100
 
101
	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
102
		/* find tv std */
103
		if (encoder->crtc == crtc) {
104
			struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
105
			if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) {
106
				struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv;
107
				tv_std = tv_dac->tv_std;
108
				is_tv = true;
109
			}
110
		}
111
	}
112
 
113
	memset(&args, 0, sizeof(args));
114
 
115
	args.ucScaler = radeon_crtc->crtc_id;
116
 
117
	if (is_tv) {
118
		switch (tv_std) {
119
		case TV_STD_NTSC:
120
		default:
121
			args.ucTVStandard = ATOM_TV_NTSC;
122
			break;
123
		case TV_STD_PAL:
124
			args.ucTVStandard = ATOM_TV_PAL;
125
			break;
126
		case TV_STD_PAL_M:
127
			args.ucTVStandard = ATOM_TV_PALM;
128
			break;
129
		case TV_STD_PAL_60:
130
			args.ucTVStandard = ATOM_TV_PAL60;
131
			break;
132
		case TV_STD_NTSC_J:
133
			args.ucTVStandard = ATOM_TV_NTSCJ;
134
			break;
135
		case TV_STD_SCART_PAL:
136
			args.ucTVStandard = ATOM_TV_PAL; /* ??? */
137
			break;
138
		case TV_STD_SECAM:
139
			args.ucTVStandard = ATOM_TV_SECAM;
140
			break;
141
		case TV_STD_PAL_CN:
142
			args.ucTVStandard = ATOM_TV_PALCN;
143
			break;
144
		}
145
		args.ucEnable = SCALER_ENABLE_MULTITAP_MODE;
146
	} else if (is_cv) {
147
		args.ucTVStandard = ATOM_TV_CV;
148
		args.ucEnable = SCALER_ENABLE_MULTITAP_MODE;
149
	} else {
150
		switch (radeon_crtc->rmx_type) {
151
		case RMX_FULL:
152
			args.ucEnable = ATOM_SCALER_EXPANSION;
153
			break;
154
		case RMX_CENTER:
155
			args.ucEnable = ATOM_SCALER_CENTER;
156
			break;
157
		case RMX_ASPECT:
158
			args.ucEnable = ATOM_SCALER_EXPANSION;
159
			break;
160
		default:
161
			if (ASIC_IS_AVIVO(rdev))
162
				args.ucEnable = ATOM_SCALER_DISABLE;
163
			else
164
				args.ucEnable = ATOM_SCALER_CENTER;
165
			break;
166
		}
167
	}
168
	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
169
	if ((is_tv || is_cv)
170
	    && rdev->family >= CHIP_RV515 && rdev->family <= CHIP_R580) {
171
		atom_rv515_force_tv_scaler(rdev, radeon_crtc);
172
	}
173
}
174
 
1123 serge 175
static void atombios_lock_crtc(struct drm_crtc *crtc, int lock)
176
{
177
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
178
	struct drm_device *dev = crtc->dev;
179
	struct radeon_device *rdev = dev->dev_private;
180
	int index =
181
	    GetIndexIntoMasterTable(COMMAND, UpdateCRTC_DoubleBufferRegisters);
182
	ENABLE_CRTC_PS_ALLOCATION args;
183
 
184
	memset(&args, 0, sizeof(args));
185
 
186
	args.ucCRTC = radeon_crtc->crtc_id;
187
	args.ucEnable = lock;
188
 
189
	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
190
}
191
 
192
static void atombios_enable_crtc(struct drm_crtc *crtc, int state)
193
{
194
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
195
	struct drm_device *dev = crtc->dev;
196
	struct radeon_device *rdev = dev->dev_private;
197
	int index = GetIndexIntoMasterTable(COMMAND, EnableCRTC);
198
	ENABLE_CRTC_PS_ALLOCATION args;
199
 
200
	memset(&args, 0, sizeof(args));
201
 
202
	args.ucCRTC = radeon_crtc->crtc_id;
203
	args.ucEnable = state;
204
 
205
	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
206
}
207
 
208
static void atombios_enable_crtc_memreq(struct drm_crtc *crtc, int state)
209
{
210
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
211
	struct drm_device *dev = crtc->dev;
212
	struct radeon_device *rdev = dev->dev_private;
213
	int index = GetIndexIntoMasterTable(COMMAND, EnableCRTCMemReq);
214
	ENABLE_CRTC_PS_ALLOCATION args;
215
 
216
	memset(&args, 0, sizeof(args));
217
 
218
	args.ucCRTC = radeon_crtc->crtc_id;
219
	args.ucEnable = state;
220
 
221
	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
222
}
223
 
224
static void atombios_blank_crtc(struct drm_crtc *crtc, int state)
225
{
226
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
227
	struct drm_device *dev = crtc->dev;
228
	struct radeon_device *rdev = dev->dev_private;
229
	int index = GetIndexIntoMasterTable(COMMAND, BlankCRTC);
230
	BLANK_CRTC_PS_ALLOCATION args;
231
 
232
	memset(&args, 0, sizeof(args));
233
 
234
	args.ucCRTC = radeon_crtc->crtc_id;
235
	args.ucBlanking = state;
236
 
237
	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
238
}
239
 
240
void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
241
{
242
	struct drm_device *dev = crtc->dev;
243
	struct radeon_device *rdev = dev->dev_private;
1321 serge 244
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1123 serge 245
 
246
	switch (mode) {
247
	case DRM_MODE_DPMS_ON:
1430 serge 248
		atombios_enable_crtc(crtc, ATOM_ENABLE);
1123 serge 249
		if (ASIC_IS_DCE3(rdev))
1430 serge 250
			atombios_enable_crtc_memreq(crtc, ATOM_ENABLE);
251
		atombios_blank_crtc(crtc, ATOM_DISABLE);
252
		/* XXX re-enable when interrupt support is added */
253
		if (!ASIC_IS_DCE4(rdev))
254
			drm_vblank_post_modeset(dev, radeon_crtc->crtc_id);
1321 serge 255
		radeon_crtc_load_lut(crtc);
1123 serge 256
		break;
257
	case DRM_MODE_DPMS_STANDBY:
258
	case DRM_MODE_DPMS_SUSPEND:
259
	case DRM_MODE_DPMS_OFF:
1430 serge 260
		/* XXX re-enable when interrupt support is added */
261
		if (!ASIC_IS_DCE4(rdev))
262
			drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id);
263
		atombios_blank_crtc(crtc, ATOM_ENABLE);
1123 serge 264
		if (ASIC_IS_DCE3(rdev))
1430 serge 265
			atombios_enable_crtc_memreq(crtc, ATOM_DISABLE);
266
		atombios_enable_crtc(crtc, ATOM_DISABLE);
1123 serge 267
		break;
268
	}
269
}
270
 
271
static void
272
atombios_set_crtc_dtd_timing(struct drm_crtc *crtc,
1268 serge 273
			     struct drm_display_mode *mode)
1123 serge 274
{
1268 serge 275
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1123 serge 276
	struct drm_device *dev = crtc->dev;
277
	struct radeon_device *rdev = dev->dev_private;
1268 serge 278
	SET_CRTC_USING_DTD_TIMING_PARAMETERS args;
1123 serge 279
	int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_UsingDTDTiming);
1268 serge 280
	u16 misc = 0;
1123 serge 281
 
1268 serge 282
	memset(&args, 0, sizeof(args));
283
	args.usH_Size = cpu_to_le16(mode->crtc_hdisplay);
284
	args.usH_Blanking_Time =
285
		cpu_to_le16(mode->crtc_hblank_end - mode->crtc_hdisplay);
286
	args.usV_Size = cpu_to_le16(mode->crtc_vdisplay);
287
	args.usV_Blanking_Time =
288
	    cpu_to_le16(mode->crtc_vblank_end - mode->crtc_vdisplay);
289
	args.usH_SyncOffset =
290
		cpu_to_le16(mode->crtc_hsync_start - mode->crtc_hdisplay);
291
	args.usH_SyncWidth =
292
		cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start);
293
	args.usV_SyncOffset =
294
		cpu_to_le16(mode->crtc_vsync_start - mode->crtc_vdisplay);
295
	args.usV_SyncWidth =
296
		cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start);
297
	/*args.ucH_Border = mode->hborder;*/
298
	/*args.ucV_Border = mode->vborder;*/
1123 serge 299
 
1268 serge 300
	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
301
		misc |= ATOM_VSYNC_POLARITY;
302
	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
303
		misc |= ATOM_HSYNC_POLARITY;
304
	if (mode->flags & DRM_MODE_FLAG_CSYNC)
305
		misc |= ATOM_COMPOSITESYNC;
306
	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
307
		misc |= ATOM_INTERLACE;
308
	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
309
		misc |= ATOM_DOUBLE_CLOCK_MODE;
310
 
311
	args.susModeMiscInfo.usAccess = cpu_to_le16(misc);
312
	args.ucCRTC = radeon_crtc->crtc_id;
313
 
314
	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
1123 serge 315
}
316
 
1268 serge 317
static void atombios_crtc_set_timing(struct drm_crtc *crtc,
318
				     struct drm_display_mode *mode)
1123 serge 319
{
1268 serge 320
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1123 serge 321
	struct drm_device *dev = crtc->dev;
322
	struct radeon_device *rdev = dev->dev_private;
1268 serge 323
	SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION args;
1123 serge 324
	int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_Timing);
1268 serge 325
	u16 misc = 0;
1123 serge 326
 
1268 serge 327
	memset(&args, 0, sizeof(args));
328
	args.usH_Total = cpu_to_le16(mode->crtc_htotal);
329
	args.usH_Disp = cpu_to_le16(mode->crtc_hdisplay);
330
	args.usH_SyncStart = cpu_to_le16(mode->crtc_hsync_start);
331
	args.usH_SyncWidth =
332
		cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start);
333
	args.usV_Total = cpu_to_le16(mode->crtc_vtotal);
334
	args.usV_Disp = cpu_to_le16(mode->crtc_vdisplay);
335
	args.usV_SyncStart = cpu_to_le16(mode->crtc_vsync_start);
336
	args.usV_SyncWidth =
337
		cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start);
1123 serge 338
 
1268 serge 339
	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
340
		misc |= ATOM_VSYNC_POLARITY;
341
	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
342
		misc |= ATOM_HSYNC_POLARITY;
343
	if (mode->flags & DRM_MODE_FLAG_CSYNC)
344
		misc |= ATOM_COMPOSITESYNC;
345
	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
346
		misc |= ATOM_INTERLACE;
347
	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
348
		misc |= ATOM_DOUBLE_CLOCK_MODE;
349
 
350
	args.susModeMiscInfo.usAccess = cpu_to_le16(misc);
351
	args.ucCRTC = radeon_crtc->crtc_id;
352
 
353
	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
1123 serge 354
}
355
 
1430 serge 356
union atom_enable_ss {
357
	ENABLE_LVDS_SS_PARAMETERS legacy;
358
	ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION v1;
359
};
360
 
1268 serge 361
static void atombios_set_ss(struct drm_crtc *crtc, int enable)
362
{
363
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
364
	struct drm_device *dev = crtc->dev;
365
	struct radeon_device *rdev = dev->dev_private;
366
	struct drm_encoder *encoder = NULL;
367
	struct radeon_encoder *radeon_encoder = NULL;
368
	struct radeon_encoder_atom_dig *dig = NULL;
369
	int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL);
1430 serge 370
	union atom_enable_ss args;
1268 serge 371
	uint16_t percentage = 0;
372
	uint8_t type = 0, step = 0, delay = 0, range = 0;
373
 
1430 serge 374
	/* XXX add ss support for DCE4 */
375
	if (ASIC_IS_DCE4(rdev))
376
		return;
377
 
1268 serge 378
	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
379
		if (encoder->crtc == crtc) {
380
			radeon_encoder = to_radeon_encoder(encoder);
381
			/* only enable spread spectrum on LVDS */
382
			if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
383
				dig = radeon_encoder->enc_priv;
384
				if (dig && dig->ss) {
385
					percentage = dig->ss->percentage;
386
					type = dig->ss->type;
387
					step = dig->ss->step;
388
					delay = dig->ss->delay;
389
					range = dig->ss->range;
390
				} else if (enable)
391
					return;
392
			} else if (enable)
393
				return;
394
			break;
395
		}
396
	}
397
 
398
	if (!radeon_encoder)
399
		return;
400
 
1430 serge 401
	memset(&args, 0, sizeof(args));
1268 serge 402
	if (ASIC_IS_AVIVO(rdev)) {
1430 serge 403
		args.v1.usSpreadSpectrumPercentage = cpu_to_le16(percentage);
404
		args.v1.ucSpreadSpectrumType = type;
405
		args.v1.ucSpreadSpectrumStep = step;
406
		args.v1.ucSpreadSpectrumDelay = delay;
407
		args.v1.ucSpreadSpectrumRange = range;
408
		args.v1.ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
409
		args.v1.ucEnable = enable;
1268 serge 410
	} else {
1430 serge 411
		args.legacy.usSpreadSpectrumPercentage = cpu_to_le16(percentage);
412
		args.legacy.ucSpreadSpectrumType = type;
413
		args.legacy.ucSpreadSpectrumStepSize_Delay = (step & 3) << 2;
414
		args.legacy.ucSpreadSpectrumStepSize_Delay |= (delay & 7) << 4;
415
		args.legacy.ucEnable = enable;
1268 serge 416
	}
1430 serge 417
	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
1268 serge 418
}
419
 
1404 serge 420
union adjust_pixel_clock {
421
	ADJUST_DISPLAY_PLL_PS_ALLOCATION v1;
1430 serge 422
	ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 v3;
1404 serge 423
};
424
 
425
static u32 atombios_adjust_pll(struct drm_crtc *crtc,
426
			       struct drm_display_mode *mode,
427
			       struct radeon_pll *pll)
1123 serge 428
{
429
	struct drm_device *dev = crtc->dev;
430
	struct radeon_device *rdev = dev->dev_private;
431
	struct drm_encoder *encoder = NULL;
432
	struct radeon_encoder *radeon_encoder = NULL;
1404 serge 433
	u32 adjusted_clock = mode->clock;
1430 serge 434
	int encoder_mode = 0;
1123 serge 435
 
1404 serge 436
	/* reset the pll flags */
437
	pll->flags = 0;
1123 serge 438
 
1430 serge 439
	/* select the PLL algo */
1123 serge 440
	if (ASIC_IS_AVIVO(rdev)) {
1430 serge 441
		if (radeon_new_pll == 0)
442
			pll->algo = PLL_ALGO_LEGACY;
443
		else
444
			pll->algo = PLL_ALGO_NEW;
445
	} else {
446
		if (radeon_new_pll == 1)
447
			pll->algo = PLL_ALGO_NEW;
448
		else
449
			pll->algo = PLL_ALGO_LEGACY;
450
	}
451
 
452
	if (ASIC_IS_AVIVO(rdev)) {
1179 serge 453
		if ((rdev->family == CHIP_RS600) ||
454
		    (rdev->family == CHIP_RS690) ||
455
		    (rdev->family == CHIP_RS740))
1404 serge 456
			pll->flags |= (RADEON_PLL_USE_FRAC_FB_DIV |
1179 serge 457
				      RADEON_PLL_PREFER_CLOSEST_LOWER);
458
 
1123 serge 459
		if (ASIC_IS_DCE32(rdev) && mode->clock > 200000)	/* range limits??? */
1404 serge 460
			pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
1123 serge 461
		else
1404 serge 462
			pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
1123 serge 463
	} else {
1404 serge 464
		pll->flags |= RADEON_PLL_LEGACY;
1123 serge 465
 
466
		if (mode->clock > 200000)	/* range limits??? */
1404 serge 467
			pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
1123 serge 468
		else
1404 serge 469
			pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
1123 serge 470
 
471
	}
472
 
473
	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
474
		if (encoder->crtc == crtc) {
1404 serge 475
			radeon_encoder = to_radeon_encoder(encoder);
1430 serge 476
			encoder_mode = atombios_get_encoder_mode(encoder);
1404 serge 477
			if (ASIC_IS_AVIVO(rdev)) {
478
				/* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
479
				if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)
480
					adjusted_clock = mode->clock * 2;
1430 serge 481
				/* LVDS PLL quirks */
482
				if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) {
483
					struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
484
					pll->algo = dig->pll_algo;
485
				}
1404 serge 486
			} else {
487
				if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
488
					pll->flags |= RADEON_PLL_NO_ODD_POST_DIV;
489
				if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS)
490
					pll->flags |= RADEON_PLL_USE_REF_DIV;
1123 serge 491
			}
1179 serge 492
			break;
1123 serge 493
		}
494
	}
495
 
1268 serge 496
	/* DCE3+ has an AdjustDisplayPll that will adjust the pixel clock
497
	 * accordingly based on the encoder/transmitter to work around
498
	 * special hw requirements.
499
	 */
500
	if (ASIC_IS_DCE3(rdev)) {
1404 serge 501
		union adjust_pixel_clock args;
502
		u8 frev, crev;
503
		int index;
1268 serge 504
 
1404 serge 505
		index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll);
506
		atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
507
				      &crev);
1268 serge 508
 
1404 serge 509
		memset(&args, 0, sizeof(args));
510
 
511
		switch (frev) {
512
		case 1:
513
			switch (crev) {
514
			case 1:
515
			case 2:
516
				args.v1.usPixelClock = cpu_to_le16(mode->clock / 10);
517
				args.v1.ucTransmitterID = radeon_encoder->encoder_id;
1430 serge 518
				args.v1.ucEncodeMode = encoder_mode;
1404 serge 519
 
1268 serge 520
		atom_execute_table(rdev->mode_info.atom_context,
1404 serge 521
						   index, (uint32_t *)&args);
522
				adjusted_clock = le16_to_cpu(args.v1.usPixelClock) * 10;
523
				break;
1430 serge 524
			case 3:
525
				args.v3.sInput.usPixelClock = cpu_to_le16(mode->clock / 10);
526
				args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id;
527
				args.v3.sInput.ucEncodeMode = encoder_mode;
528
				args.v3.sInput.ucDispPllConfig = 0;
529
				if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
530
					struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
531
 
532
					if (encoder_mode == ATOM_ENCODER_MODE_DP)
533
						args.v3.sInput.ucDispPllConfig |=
534
							DISPPLL_CONFIG_COHERENT_MODE;
535
					else {
536
						if (dig->coherent_mode)
537
							args.v3.sInput.ucDispPllConfig |=
538
								DISPPLL_CONFIG_COHERENT_MODE;
539
						if (mode->clock > 165000)
540
							args.v3.sInput.ucDispPllConfig |=
541
								DISPPLL_CONFIG_DUAL_LINK;
542
					}
543
				} else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
544
					/* may want to enable SS on DP/eDP eventually */
545
					args.v3.sInput.ucDispPllConfig |=
546
						DISPPLL_CONFIG_SS_ENABLE;
547
					if (mode->clock > 165000)
548
						args.v3.sInput.ucDispPllConfig |=
549
							DISPPLL_CONFIG_DUAL_LINK;
550
				}
551
				atom_execute_table(rdev->mode_info.atom_context,
552
						   index, (uint32_t *)&args);
553
				adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10;
554
				if (args.v3.sOutput.ucRefDiv) {
555
					pll->flags |= RADEON_PLL_USE_REF_DIV;
556
					pll->reference_div = args.v3.sOutput.ucRefDiv;
557
				}
558
				if (args.v3.sOutput.ucPostDiv) {
559
					pll->flags |= RADEON_PLL_USE_POST_DIV;
560
					pll->post_div = args.v3.sOutput.ucPostDiv;
561
				}
562
				break;
1404 serge 563
			default:
564
				DRM_ERROR("Unknown table version %d %d\n", frev, crev);
565
				return adjusted_clock;
566
			}
567
			break;
568
		default:
569
			DRM_ERROR("Unknown table version %d %d\n", frev, crev);
570
			return adjusted_clock;
571
		}
1268 serge 572
	}
1404 serge 573
	return adjusted_clock;
574
}
1268 serge 575
 
1404 serge 576
union set_pixel_clock {
577
	SET_PIXEL_CLOCK_PS_ALLOCATION base;
578
	PIXEL_CLOCK_PARAMETERS v1;
579
	PIXEL_CLOCK_PARAMETERS_V2 v2;
580
	PIXEL_CLOCK_PARAMETERS_V3 v3;
1430 serge 581
	PIXEL_CLOCK_PARAMETERS_V5 v5;
1404 serge 582
};
583
 
1430 serge 584
static void atombios_crtc_set_dcpll(struct drm_crtc *crtc)
1404 serge 585
{
1430 serge 586
	struct drm_device *dev = crtc->dev;
587
	struct radeon_device *rdev = dev->dev_private;
588
	u8 frev, crev;
589
	int index;
590
	union set_pixel_clock args;
591
 
592
	memset(&args, 0, sizeof(args));
593
 
594
	index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
595
	atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
596
			      &crev);
597
 
598
	switch (frev) {
599
	case 1:
600
		switch (crev) {
601
		case 5:
602
			/* if the default dcpll clock is specified,
603
			 * SetPixelClock provides the dividers
604
			 */
605
			args.v5.ucCRTC = ATOM_CRTC_INVALID;
606
			args.v5.usPixelClock = rdev->clock.default_dispclk;
607
			args.v5.ucPpll = ATOM_DCPLL;
608
			break;
609
		default:
610
			DRM_ERROR("Unknown table version %d %d\n", frev, crev);
611
			return;
612
		}
613
		break;
614
	default:
615
		DRM_ERROR("Unknown table version %d %d\n", frev, crev);
616
		return;
617
	}
618
	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
619
}
620
 
621
static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
622
{
1404 serge 623
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
624
	struct drm_device *dev = crtc->dev;
625
	struct radeon_device *rdev = dev->dev_private;
626
	struct drm_encoder *encoder = NULL;
627
	struct radeon_encoder *radeon_encoder = NULL;
628
	u8 frev, crev;
629
	int index;
630
	union set_pixel_clock args;
631
	u32 pll_clock = mode->clock;
632
	u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
633
	struct radeon_pll *pll;
634
	u32 adjusted_clock;
1430 serge 635
	int encoder_mode = 0;
1404 serge 636
 
637
	memset(&args, 0, sizeof(args));
638
 
639
	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
640
		if (encoder->crtc == crtc) {
641
			radeon_encoder = to_radeon_encoder(encoder);
1430 serge 642
			encoder_mode = atombios_get_encoder_mode(encoder);
1404 serge 643
			break;
644
		}
645
	}
646
 
647
	if (!radeon_encoder)
648
		return;
649
 
1430 serge 650
	switch (radeon_crtc->pll_id) {
651
	case ATOM_PPLL1:
1123 serge 652
		pll = &rdev->clock.p1pll;
1430 serge 653
		break;
654
	case ATOM_PPLL2:
1123 serge 655
		pll = &rdev->clock.p2pll;
1430 serge 656
		break;
657
	case ATOM_DCPLL:
658
	case ATOM_PPLL_INVALID:
659
		pll = &rdev->clock.dcpll;
660
		break;
661
	}
1123 serge 662
 
1404 serge 663
	/* adjust pixel clock as needed */
664
	adjusted_clock = atombios_adjust_pll(crtc, mode, pll);
665
 
1268 serge 666
	radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
1404 serge 667
				   &ref_div, &post_div);
1123 serge 668
 
1268 serge 669
	index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
1123 serge 670
	atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
671
			      &crev);
672
 
673
	switch (frev) {
674
	case 1:
675
		switch (crev) {
676
		case 1:
1404 serge 677
			args.v1.usPixelClock = cpu_to_le16(mode->clock / 10);
678
			args.v1.usRefDiv = cpu_to_le16(ref_div);
679
			args.v1.usFbDiv = cpu_to_le16(fb_div);
680
			args.v1.ucFracFbDiv = frac_fb_div;
681
			args.v1.ucPostDiv = post_div;
1430 serge 682
			args.v1.ucPpll = radeon_crtc->pll_id;
1404 serge 683
			args.v1.ucCRTC = radeon_crtc->crtc_id;
684
			args.v1.ucRefDivSrc = 1;
1123 serge 685
			break;
686
		case 2:
1404 serge 687
			args.v2.usPixelClock = cpu_to_le16(mode->clock / 10);
688
			args.v2.usRefDiv = cpu_to_le16(ref_div);
689
			args.v2.usFbDiv = cpu_to_le16(fb_div);
690
			args.v2.ucFracFbDiv = frac_fb_div;
691
			args.v2.ucPostDiv = post_div;
1430 serge 692
			args.v2.ucPpll = radeon_crtc->pll_id;
1404 serge 693
			args.v2.ucCRTC = radeon_crtc->crtc_id;
694
			args.v2.ucRefDivSrc = 1;
1123 serge 695
			break;
696
		case 3:
1404 serge 697
			args.v3.usPixelClock = cpu_to_le16(mode->clock / 10);
698
			args.v3.usRefDiv = cpu_to_le16(ref_div);
699
			args.v3.usFbDiv = cpu_to_le16(fb_div);
700
			args.v3.ucFracFbDiv = frac_fb_div;
701
			args.v3.ucPostDiv = post_div;
1430 serge 702
			args.v3.ucPpll = radeon_crtc->pll_id;
703
			args.v3.ucMiscInfo = (radeon_crtc->pll_id << 2);
1404 serge 704
			args.v3.ucTransmitterId = radeon_encoder->encoder_id;
1430 serge 705
			args.v3.ucEncoderMode = encoder_mode;
1123 serge 706
			break;
1430 serge 707
		case 5:
708
			args.v5.ucCRTC = radeon_crtc->crtc_id;
709
			args.v5.usPixelClock = cpu_to_le16(mode->clock / 10);
710
			args.v5.ucRefDiv = ref_div;
711
			args.v5.usFbDiv = cpu_to_le16(fb_div);
712
			args.v5.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000);
713
			args.v5.ucPostDiv = post_div;
714
			args.v5.ucMiscInfo = 0; /* HDMI depth, etc. */
715
			args.v5.ucTransmitterID = radeon_encoder->encoder_id;
716
			args.v5.ucEncoderMode = encoder_mode;
717
			args.v5.ucPpll = radeon_crtc->pll_id;
718
			break;
1123 serge 719
		default:
720
			DRM_ERROR("Unknown table version %d %d\n", frev, crev);
721
			return;
722
		}
723
		break;
724
	default:
725
		DRM_ERROR("Unknown table version %d %d\n", frev, crev);
726
		return;
727
	}
728
 
729
	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
730
}
731
 
1430 serge 732
static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y,
733
				   struct drm_framebuffer *old_fb)
734
{
735
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
736
	struct drm_device *dev = crtc->dev;
737
	struct radeon_device *rdev = dev->dev_private;
738
	struct radeon_framebuffer *radeon_fb;
739
	struct drm_gem_object *obj;
740
	struct radeon_bo *rbo;
741
	uint64_t fb_location;
742
	uint32_t fb_format, fb_pitch_pixels, tiling_flags;
743
	int r;
744
 
745
	/* no fb bound */
746
	if (!crtc->fb) {
747
		DRM_DEBUG("No FB bound\n");
748
		return 0;
749
	}
750
 
751
	radeon_fb = to_radeon_framebuffer(crtc->fb);
752
 
753
	/* Pin framebuffer & get tilling informations */
754
	obj = radeon_fb->obj;
755
	rbo = obj->driver_private;
756
	r = radeon_bo_reserve(rbo, false);
757
	if (unlikely(r != 0))
758
		return r;
759
	r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location);
760
	if (unlikely(r != 0)) {
761
		radeon_bo_unreserve(rbo);
762
		return -EINVAL;
763
	}
764
	radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
765
	radeon_bo_unreserve(rbo);
766
 
767
	switch (crtc->fb->bits_per_pixel) {
768
	case 8:
769
		fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_8BPP) |
770
			     EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_INDEXED));
771
		break;
772
	case 15:
773
		fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
774
			     EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB1555));
775
		break;
776
	case 16:
777
		fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
778
			     EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB565));
779
		break;
780
	case 24:
781
	case 32:
782
		fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) |
783
			     EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB8888));
784
		break;
785
	default:
786
		DRM_ERROR("Unsupported screen depth %d\n",
787
			  crtc->fb->bits_per_pixel);
788
		return -EINVAL;
789
	}
790
 
791
	switch (radeon_crtc->crtc_id) {
792
	case 0:
793
		WREG32(AVIVO_D1VGA_CONTROL, 0);
794
		break;
795
	case 1:
796
		WREG32(AVIVO_D2VGA_CONTROL, 0);
797
		break;
798
	case 2:
799
		WREG32(EVERGREEN_D3VGA_CONTROL, 0);
800
		break;
801
	case 3:
802
		WREG32(EVERGREEN_D4VGA_CONTROL, 0);
803
		break;
804
	case 4:
805
		WREG32(EVERGREEN_D5VGA_CONTROL, 0);
806
		break;
807
	case 5:
808
		WREG32(EVERGREEN_D6VGA_CONTROL, 0);
809
		break;
810
	default:
811
		break;
812
	}
813
 
814
	WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
815
	       upper_32_bits(fb_location));
816
	WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
817
	       upper_32_bits(fb_location));
818
	WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
819
	       (u32)fb_location & EVERGREEN_GRPH_SURFACE_ADDRESS_MASK);
820
	WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
821
	       (u32) fb_location & EVERGREEN_GRPH_SURFACE_ADDRESS_MASK);
822
	WREG32(EVERGREEN_GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format);
823
 
824
	WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0);
825
	WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0);
826
	WREG32(EVERGREEN_GRPH_X_START + radeon_crtc->crtc_offset, 0);
827
	WREG32(EVERGREEN_GRPH_Y_START + radeon_crtc->crtc_offset, 0);
828
	WREG32(EVERGREEN_GRPH_X_END + radeon_crtc->crtc_offset, crtc->fb->width);
829
	WREG32(EVERGREEN_GRPH_Y_END + radeon_crtc->crtc_offset, crtc->fb->height);
830
 
831
	fb_pitch_pixels = crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8);
832
	WREG32(EVERGREEN_GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels);
833
	WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
834
 
835
	WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
836
	       crtc->mode.vdisplay);
837
	x &= ~3;
838
	y &= ~1;
839
	WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset,
840
	       (x << 16) | y);
841
	WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
842
	       (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay);
843
 
844
	if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE)
845
		WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset,
846
		       EVERGREEN_INTERLEAVE_EN);
847
	else
848
		WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0);
849
 
850
	if (old_fb && old_fb != crtc->fb) {
851
		radeon_fb = to_radeon_framebuffer(old_fb);
852
		rbo = radeon_fb->obj->driver_private;
853
		r = radeon_bo_reserve(rbo, false);
854
		if (unlikely(r != 0))
855
			return r;
856
		radeon_bo_unpin(rbo);
857
		radeon_bo_unreserve(rbo);
858
	}
859
 
860
	/* Bytes per pixel may have changed */
861
	radeon_bandwidth_update(rdev);
862
 
863
	return 0;
864
}
865
 
1404 serge 866
static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y,
1123 serge 867
			   struct drm_framebuffer *old_fb)
868
{
869
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
870
	struct drm_device *dev = crtc->dev;
871
	struct radeon_device *rdev = dev->dev_private;
872
	struct radeon_framebuffer *radeon_fb;
873
	struct drm_gem_object *obj;
1321 serge 874
	struct radeon_bo *rbo;
1123 serge 875
	uint64_t fb_location;
1179 serge 876
	uint32_t fb_format, fb_pitch_pixels, tiling_flags;
1321 serge 877
	int r;
1123 serge 878
 
1321 serge 879
	/* no fb bound */
880
	if (!crtc->fb) {
881
		DRM_DEBUG("No FB bound\n");
882
		return 0;
883
	}
1123 serge 884
 
885
	radeon_fb = to_radeon_framebuffer(crtc->fb);
886
 
1321 serge 887
	/* Pin framebuffer & get tilling informations */
1123 serge 888
	obj = radeon_fb->obj;
1404 serge 889
	rbo = obj->driver_private;
890
	r = radeon_bo_reserve(rbo, false);
891
	if (unlikely(r != 0))
892
		return r;
893
	r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location);
894
	if (unlikely(r != 0)) {
895
		radeon_bo_unreserve(rbo);
896
		return -EINVAL;
897
	}
898
	radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
899
	radeon_bo_unreserve(rbo);
1123 serge 900
 
901
	switch (crtc->fb->bits_per_pixel) {
1179 serge 902
	case 8:
903
		fb_format =
904
		    AVIVO_D1GRPH_CONTROL_DEPTH_8BPP |
905
		    AVIVO_D1GRPH_CONTROL_8BPP_INDEXED;
906
		break;
1123 serge 907
	case 15:
908
		fb_format =
909
		    AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
910
		    AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555;
911
		break;
912
	case 16:
913
		fb_format =
914
		    AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
915
		    AVIVO_D1GRPH_CONTROL_16BPP_RGB565;
916
		break;
917
	case 24:
918
	case 32:
919
		fb_format =
920
		    AVIVO_D1GRPH_CONTROL_DEPTH_32BPP |
921
		    AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888;
922
		break;
923
	default:
924
		DRM_ERROR("Unsupported screen depth %d\n",
925
			  crtc->fb->bits_per_pixel);
926
		return -EINVAL;
927
	}
928
 
1321 serge 929
	if (tiling_flags & RADEON_TILING_MACRO)
930
		fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE;
1179 serge 931
 
1321 serge 932
	if (tiling_flags & RADEON_TILING_MICRO)
933
		fb_format |= AVIVO_D1GRPH_TILED;
1179 serge 934
 
1123 serge 935
	if (radeon_crtc->crtc_id == 0)
936
		WREG32(AVIVO_D1VGA_CONTROL, 0);
937
	else
938
		WREG32(AVIVO_D2VGA_CONTROL, 0);
1268 serge 939
 
940
	if (rdev->family >= CHIP_RV770) {
941
		if (radeon_crtc->crtc_id) {
942
			WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0);
943
			WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0);
944
		} else {
945
			WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0);
946
			WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0);
947
		}
948
	}
1123 serge 949
	WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
950
	       (u32) fb_location);
951
	WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS +
952
	       radeon_crtc->crtc_offset, (u32) fb_location);
953
	WREG32(AVIVO_D1GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format);
954
 
955
	WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0);
956
	WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0);
957
	WREG32(AVIVO_D1GRPH_X_START + radeon_crtc->crtc_offset, 0);
958
	WREG32(AVIVO_D1GRPH_Y_START + radeon_crtc->crtc_offset, 0);
959
	WREG32(AVIVO_D1GRPH_X_END + radeon_crtc->crtc_offset, crtc->fb->width);
960
	WREG32(AVIVO_D1GRPH_Y_END + radeon_crtc->crtc_offset, crtc->fb->height);
961
 
962
	fb_pitch_pixels = crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8);
963
	WREG32(AVIVO_D1GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels);
964
	WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
965
 
966
	WREG32(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
967
	       crtc->mode.vdisplay);
968
	x &= ~3;
969
	y &= ~1;
970
	WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset,
971
	       (x << 16) | y);
972
	WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
973
	       (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay);
974
 
975
	if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE)
976
		WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset,
977
		       AVIVO_D1MODE_INTERLEAVE_EN);
978
	else
979
		WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0);
980
 
1404 serge 981
	if (old_fb && old_fb != crtc->fb) {
982
		radeon_fb = to_radeon_framebuffer(old_fb);
983
		rbo = radeon_fb->obj->driver_private;
984
		r = radeon_bo_reserve(rbo, false);
985
		if (unlikely(r != 0))
986
			return r;
987
		radeon_bo_unpin(rbo);
988
		radeon_bo_unreserve(rbo);
989
	}
1246 serge 990
 
1268 serge 991
	/* Bytes per pixel may have changed */
992
	radeon_bandwidth_update(rdev);
993
 
1123 serge 994
	return 0;
995
}
996
 
1404 serge 997
int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
998
			   struct drm_framebuffer *old_fb)
999
{
1000
	struct drm_device *dev = crtc->dev;
1001
	struct radeon_device *rdev = dev->dev_private;
1002
 
1430 serge 1003
	if (ASIC_IS_DCE4(rdev))
1004
		return evergreen_crtc_set_base(crtc, x, y, old_fb);
1005
	else if (ASIC_IS_AVIVO(rdev))
1404 serge 1006
		return avivo_crtc_set_base(crtc, x, y, old_fb);
1007
	else
1008
		return radeon_crtc_set_base(crtc, x, y, old_fb);
1009
}
1010
 
1011
/* properly set additional regs when using atombios */
1012
static void radeon_legacy_atom_fixup(struct drm_crtc *crtc)
1013
{
1014
	struct drm_device *dev = crtc->dev;
1015
	struct radeon_device *rdev = dev->dev_private;
1016
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1017
	u32 disp_merge_cntl;
1018
 
1019
	switch (radeon_crtc->crtc_id) {
1020
	case 0:
1021
		disp_merge_cntl = RREG32(RADEON_DISP_MERGE_CNTL);
1022
		disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN;
1023
		WREG32(RADEON_DISP_MERGE_CNTL, disp_merge_cntl);
1024
		break;
1025
	case 1:
1026
		disp_merge_cntl = RREG32(RADEON_DISP2_MERGE_CNTL);
1027
		disp_merge_cntl &= ~RADEON_DISP2_RGB_OFFSET_EN;
1028
		WREG32(RADEON_DISP2_MERGE_CNTL, disp_merge_cntl);
1029
		WREG32(RADEON_FP_H2_SYNC_STRT_WID,   RREG32(RADEON_CRTC2_H_SYNC_STRT_WID));
1030
		WREG32(RADEON_FP_V2_SYNC_STRT_WID,   RREG32(RADEON_CRTC2_V_SYNC_STRT_WID));
1031
		break;
1032
	}
1033
}
1034
 
1430 serge 1035
static int radeon_atom_pick_pll(struct drm_crtc *crtc)
1036
{
1037
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1038
	struct drm_device *dev = crtc->dev;
1039
	struct radeon_device *rdev = dev->dev_private;
1040
	struct drm_encoder *test_encoder;
1041
	struct drm_crtc *test_crtc;
1042
	uint32_t pll_in_use = 0;
1043
 
1044
	if (ASIC_IS_DCE4(rdev)) {
1045
		/* if crtc is driving DP and we have an ext clock, use that */
1046
		list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
1047
			if (test_encoder->crtc && (test_encoder->crtc == crtc)) {
1048
				if (atombios_get_encoder_mode(test_encoder) == ATOM_ENCODER_MODE_DP) {
1049
					if (rdev->clock.dp_extclk)
1050
						return ATOM_PPLL_INVALID;
1051
				}
1052
			}
1053
		}
1054
 
1055
		/* otherwise, pick one of the plls */
1056
		list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
1057
			struct radeon_crtc *radeon_test_crtc;
1058
 
1059
			if (crtc == test_crtc)
1060
				continue;
1061
 
1062
			radeon_test_crtc = to_radeon_crtc(test_crtc);
1063
			if ((radeon_test_crtc->pll_id >= ATOM_PPLL1) &&
1064
			    (radeon_test_crtc->pll_id <= ATOM_PPLL2))
1065
				pll_in_use |= (1 << radeon_test_crtc->pll_id);
1066
		}
1067
		if (!(pll_in_use & 1))
1068
			return ATOM_PPLL1;
1069
		return ATOM_PPLL2;
1070
	} else
1071
		return radeon_crtc->crtc_id;
1072
 
1073
}
1074
 
1123 serge 1075
int atombios_crtc_mode_set(struct drm_crtc *crtc,
1076
			   struct drm_display_mode *mode,
1077
			   struct drm_display_mode *adjusted_mode,
1078
			   int x, int y, struct drm_framebuffer *old_fb)
1079
{
1080
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1081
	struct drm_device *dev = crtc->dev;
1082
	struct radeon_device *rdev = dev->dev_private;
1083
 
1084
	/* TODO color tiling */
1085
 
1430 serge 1086
	/* pick pll */
1087
	radeon_crtc->pll_id = radeon_atom_pick_pll(crtc);
1088
 
1268 serge 1089
	atombios_set_ss(crtc, 0);
1430 serge 1090
	/* always set DCPLL */
1091
	if (ASIC_IS_DCE4(rdev))
1092
		atombios_crtc_set_dcpll(crtc);
1123 serge 1093
	atombios_crtc_set_pll(crtc, adjusted_mode);
1268 serge 1094
	atombios_set_ss(crtc, 1);
1430 serge 1095
 
1096
	if (ASIC_IS_DCE4(rdev))
1097
		atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
1098
	else if (ASIC_IS_AVIVO(rdev))
1268 serge 1099
	atombios_crtc_set_timing(crtc, adjusted_mode);
1123 serge 1100
	else {
1430 serge 1101
		atombios_crtc_set_timing(crtc, adjusted_mode);
1268 serge 1102
		if (radeon_crtc->crtc_id == 0)
1103
			atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
1404 serge 1104
		radeon_legacy_atom_fixup(crtc);
1123 serge 1105
	}
1430 serge 1106
	atombios_crtc_set_base(crtc, x, y, old_fb);
1179 serge 1107
	atombios_overscan_setup(crtc, mode, adjusted_mode);
1108
	atombios_scaler_setup(crtc);
1123 serge 1109
	return 0;
1110
}
1111
 
1112
static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc,
1113
				     struct drm_display_mode *mode,
1114
				     struct drm_display_mode *adjusted_mode)
1115
{
1179 serge 1116
	if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode))
1117
		return false;
1123 serge 1118
	return true;
1119
}
1120
 
1121
static void atombios_crtc_prepare(struct drm_crtc *crtc)
1122
{
1430 serge 1123
	atombios_lock_crtc(crtc, ATOM_ENABLE);
1123 serge 1124
	atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
1125
}
1126
 
1127
static void atombios_crtc_commit(struct drm_crtc *crtc)
1128
{
1129
	atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
1430 serge 1130
	atombios_lock_crtc(crtc, ATOM_DISABLE);
1123 serge 1131
}
1132
 
1133
static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
1134
	.dpms = atombios_crtc_dpms,
1135
	.mode_fixup = atombios_crtc_mode_fixup,
1136
	.mode_set = atombios_crtc_mode_set,
1137
	.mode_set_base = atombios_crtc_set_base,
1138
	.prepare = atombios_crtc_prepare,
1139
	.commit = atombios_crtc_commit,
1221 serge 1140
	.load_lut = radeon_crtc_load_lut,
1123 serge 1141
};
1142
 
1143
void radeon_atombios_init_crtc(struct drm_device *dev,
1144
			       struct radeon_crtc *radeon_crtc)
1145
{
1430 serge 1146
	struct radeon_device *rdev = dev->dev_private;
1147
 
1148
	if (ASIC_IS_DCE4(rdev)) {
1149
		switch (radeon_crtc->crtc_id) {
1150
		case 0:
1151
		default:
1152
			radeon_crtc->crtc_offset = EVERGREEN_CRTC0_REGISTER_OFFSET;
1153
			break;
1154
		case 1:
1155
			radeon_crtc->crtc_offset = EVERGREEN_CRTC1_REGISTER_OFFSET;
1156
			break;
1157
		case 2:
1158
			radeon_crtc->crtc_offset = EVERGREEN_CRTC2_REGISTER_OFFSET;
1159
			break;
1160
		case 3:
1161
			radeon_crtc->crtc_offset = EVERGREEN_CRTC3_REGISTER_OFFSET;
1162
			break;
1163
		case 4:
1164
			radeon_crtc->crtc_offset = EVERGREEN_CRTC4_REGISTER_OFFSET;
1165
			break;
1166
		case 5:
1167
			radeon_crtc->crtc_offset = EVERGREEN_CRTC5_REGISTER_OFFSET;
1168
			break;
1169
		}
1170
	} else {
1123 serge 1171
	if (radeon_crtc->crtc_id == 1)
1172
		radeon_crtc->crtc_offset =
1173
		    AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL;
1430 serge 1174
		else
1175
			radeon_crtc->crtc_offset = 0;
1176
	}
1177
	radeon_crtc->pll_id = -1;
1123 serge 1178
	drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs);
1179
}