Subversion Repositories Kolibri OS

Rev

Rev 3764 | Rev 5271 | 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
 */
2997 Serge 26
#include 
27
#include 
1123 serge 28
#include "radeon.h"
29
 
30
#include "atom.h"
1963 serge 31
#include 
1123 serge 32
 
2997 Serge 33
#include 
34
#include 
1123 serge 35
 
5078 serge 36
/* Greatest common divisor */
37
unsigned long gcd(unsigned long a, unsigned long b)
38
{
39
        unsigned long r;
40
 
41
        if (a < b)
42
                swap(a, b);
43
 
44
        if (!b)
45
                return a;
46
        while ((r = a % b) != 0) {
47
                a = b;
48
                b = r;
49
        }
50
        return b;
51
}
52
 
1123 serge 53
static void avivo_crtc_load_lut(struct drm_crtc *crtc)
54
{
55
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
56
	struct drm_device *dev = crtc->dev;
57
	struct radeon_device *rdev = dev->dev_private;
58
	int i;
59
 
1963 serge 60
	DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id);
1123 serge 61
	WREG32(AVIVO_DC_LUTA_CONTROL + radeon_crtc->crtc_offset, 0);
62
 
63
	WREG32(AVIVO_DC_LUTA_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0);
64
	WREG32(AVIVO_DC_LUTA_BLACK_OFFSET_GREEN + radeon_crtc->crtc_offset, 0);
65
	WREG32(AVIVO_DC_LUTA_BLACK_OFFSET_RED + radeon_crtc->crtc_offset, 0);
66
 
67
	WREG32(AVIVO_DC_LUTA_WHITE_OFFSET_BLUE + radeon_crtc->crtc_offset, 0xffff);
68
	WREG32(AVIVO_DC_LUTA_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff);
69
	WREG32(AVIVO_DC_LUTA_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff);
70
 
71
	WREG32(AVIVO_DC_LUT_RW_SELECT, radeon_crtc->crtc_id);
72
	WREG32(AVIVO_DC_LUT_RW_MODE, 0);
73
	WREG32(AVIVO_DC_LUT_WRITE_EN_MASK, 0x0000003f);
74
 
75
	WREG8(AVIVO_DC_LUT_RW_INDEX, 0);
76
	for (i = 0; i < 256; i++) {
77
		WREG32(AVIVO_DC_LUT_30_COLOR,
78
			     (radeon_crtc->lut_r[i] << 20) |
79
			     (radeon_crtc->lut_g[i] << 10) |
80
			     (radeon_crtc->lut_b[i] << 0));
81
	}
82
 
5078 serge 83
	/* Only change bit 0 of LUT_SEL, other bits are set elsewhere */
84
	WREG32_P(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset, radeon_crtc->crtc_id, ~1);
1123 serge 85
}
86
 
1963 serge 87
static void dce4_crtc_load_lut(struct drm_crtc *crtc)
1430 serge 88
{
89
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
90
	struct drm_device *dev = crtc->dev;
91
	struct radeon_device *rdev = dev->dev_private;
92
	int i;
93
 
1963 serge 94
	DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id);
1430 serge 95
	WREG32(EVERGREEN_DC_LUT_CONTROL + radeon_crtc->crtc_offset, 0);
96
 
97
	WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0);
98
	WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_GREEN + radeon_crtc->crtc_offset, 0);
99
	WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_RED + radeon_crtc->crtc_offset, 0);
100
 
101
	WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_BLUE + radeon_crtc->crtc_offset, 0xffff);
102
	WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff);
103
	WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff);
104
 
1963 serge 105
	WREG32(EVERGREEN_DC_LUT_RW_MODE + radeon_crtc->crtc_offset, 0);
106
	WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK + radeon_crtc->crtc_offset, 0x00000007);
1430 serge 107
 
1963 serge 108
	WREG32(EVERGREEN_DC_LUT_RW_INDEX + radeon_crtc->crtc_offset, 0);
1430 serge 109
	for (i = 0; i < 256; i++) {
1963 serge 110
		WREG32(EVERGREEN_DC_LUT_30_COLOR + radeon_crtc->crtc_offset,
1430 serge 111
		       (radeon_crtc->lut_r[i] << 20) |
112
		       (radeon_crtc->lut_g[i] << 10) |
113
		       (radeon_crtc->lut_b[i] << 0));
114
	}
115
}
116
 
1963 serge 117
static void dce5_crtc_load_lut(struct drm_crtc *crtc)
118
{
119
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
120
	struct drm_device *dev = crtc->dev;
121
	struct radeon_device *rdev = dev->dev_private;
122
	int i;
123
 
124
	DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id);
125
 
126
	WREG32(NI_INPUT_CSC_CONTROL + radeon_crtc->crtc_offset,
127
	       (NI_INPUT_CSC_GRPH_MODE(NI_INPUT_CSC_BYPASS) |
128
		NI_INPUT_CSC_OVL_MODE(NI_INPUT_CSC_BYPASS)));
129
	WREG32(NI_PRESCALE_GRPH_CONTROL + radeon_crtc->crtc_offset,
130
	       NI_GRPH_PRESCALE_BYPASS);
131
	WREG32(NI_PRESCALE_OVL_CONTROL + radeon_crtc->crtc_offset,
132
	       NI_OVL_PRESCALE_BYPASS);
133
	WREG32(NI_INPUT_GAMMA_CONTROL + radeon_crtc->crtc_offset,
134
	       (NI_GRPH_INPUT_GAMMA_MODE(NI_INPUT_GAMMA_USE_LUT) |
135
		NI_OVL_INPUT_GAMMA_MODE(NI_INPUT_GAMMA_USE_LUT)));
136
 
137
	WREG32(EVERGREEN_DC_LUT_CONTROL + radeon_crtc->crtc_offset, 0);
138
 
139
	WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0);
140
	WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_GREEN + radeon_crtc->crtc_offset, 0);
141
	WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_RED + radeon_crtc->crtc_offset, 0);
142
 
143
	WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_BLUE + radeon_crtc->crtc_offset, 0xffff);
144
	WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff);
145
	WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff);
146
 
147
	WREG32(EVERGREEN_DC_LUT_RW_MODE + radeon_crtc->crtc_offset, 0);
148
	WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK + radeon_crtc->crtc_offset, 0x00000007);
149
 
150
	WREG32(EVERGREEN_DC_LUT_RW_INDEX + radeon_crtc->crtc_offset, 0);
151
	for (i = 0; i < 256; i++) {
152
		WREG32(EVERGREEN_DC_LUT_30_COLOR + radeon_crtc->crtc_offset,
153
		       (radeon_crtc->lut_r[i] << 20) |
154
		       (radeon_crtc->lut_g[i] << 10) |
155
		       (radeon_crtc->lut_b[i] << 0));
156
	}
157
 
158
	WREG32(NI_DEGAMMA_CONTROL + radeon_crtc->crtc_offset,
159
	       (NI_GRPH_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) |
160
		NI_OVL_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) |
161
		NI_ICON_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) |
162
		NI_CURSOR_DEGAMMA_MODE(NI_DEGAMMA_BYPASS)));
163
	WREG32(NI_GAMUT_REMAP_CONTROL + radeon_crtc->crtc_offset,
164
	       (NI_GRPH_GAMUT_REMAP_MODE(NI_GAMUT_REMAP_BYPASS) |
165
		NI_OVL_GAMUT_REMAP_MODE(NI_GAMUT_REMAP_BYPASS)));
166
	WREG32(NI_REGAMMA_CONTROL + radeon_crtc->crtc_offset,
167
	       (NI_GRPH_REGAMMA_MODE(NI_REGAMMA_BYPASS) |
168
		NI_OVL_REGAMMA_MODE(NI_REGAMMA_BYPASS)));
169
	WREG32(NI_OUTPUT_CSC_CONTROL + radeon_crtc->crtc_offset,
170
	       (NI_OUTPUT_CSC_GRPH_MODE(NI_OUTPUT_CSC_BYPASS) |
171
		NI_OUTPUT_CSC_OVL_MODE(NI_OUTPUT_CSC_BYPASS)));
172
	/* XXX match this to the depth of the crtc fmt block, move to modeset? */
173
	WREG32(0x6940 + radeon_crtc->crtc_offset, 0);
5078 serge 174
	if (ASIC_IS_DCE8(rdev)) {
175
		/* XXX this only needs to be programmed once per crtc at startup,
176
		 * not sure where the best place for it is
177
		 */
178
		WREG32(CIK_ALPHA_CONTROL + radeon_crtc->crtc_offset,
179
		       CIK_CURSOR_ALPHA_BLND_ENA);
180
	}
1963 serge 181
}
182
 
1123 serge 183
static void legacy_crtc_load_lut(struct drm_crtc *crtc)
184
{
185
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
186
	struct drm_device *dev = crtc->dev;
187
	struct radeon_device *rdev = dev->dev_private;
188
	int i;
189
	uint32_t dac2_cntl;
190
 
191
	dac2_cntl = RREG32(RADEON_DAC_CNTL2);
192
	if (radeon_crtc->crtc_id == 0)
193
		dac2_cntl &= (uint32_t)~RADEON_DAC2_PALETTE_ACC_CTL;
194
	else
195
		dac2_cntl |= RADEON_DAC2_PALETTE_ACC_CTL;
196
	WREG32(RADEON_DAC_CNTL2, dac2_cntl);
197
 
198
	WREG8(RADEON_PALETTE_INDEX, 0);
199
	for (i = 0; i < 256; i++) {
200
		WREG32(RADEON_PALETTE_30_DATA,
201
			     (radeon_crtc->lut_r[i] << 20) |
202
			     (radeon_crtc->lut_g[i] << 10) |
203
			     (radeon_crtc->lut_b[i] << 0));
204
	}
205
}
206
 
207
void radeon_crtc_load_lut(struct drm_crtc *crtc)
208
{
209
	struct drm_device *dev = crtc->dev;
210
	struct radeon_device *rdev = dev->dev_private;
211
 
212
	if (!crtc->enabled)
213
		return;
214
 
1963 serge 215
	if (ASIC_IS_DCE5(rdev))
216
		dce5_crtc_load_lut(crtc);
217
	else if (ASIC_IS_DCE4(rdev))
218
		dce4_crtc_load_lut(crtc);
1430 serge 219
	else if (ASIC_IS_AVIVO(rdev))
1123 serge 220
		avivo_crtc_load_lut(crtc);
221
	else
222
		legacy_crtc_load_lut(crtc);
223
}
224
 
1221 serge 225
/** Sets the color ramps on behalf of fbcon */
1123 serge 226
void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
227
			      u16 blue, int regno)
228
{
229
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
230
 
231
	radeon_crtc->lut_r[regno] = red >> 6;
232
	radeon_crtc->lut_g[regno] = green >> 6;
233
	radeon_crtc->lut_b[regno] = blue >> 6;
234
}
235
 
1221 serge 236
/** Gets the color ramps on behalf of fbcon */
237
void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
238
			      u16 *blue, int regno)
239
{
240
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
241
 
242
	*red = radeon_crtc->lut_r[regno] << 6;
243
	*green = radeon_crtc->lut_g[regno] << 6;
244
	*blue = radeon_crtc->lut_b[regno] << 6;
245
}
246
 
1123 serge 247
static void radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
1963 serge 248
				  u16 *blue, uint32_t start, uint32_t size)
1123 serge 249
{
250
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1963 serge 251
	int end = (start + size > 256) ? 256 : start + size, i;
1123 serge 252
 
1221 serge 253
	/* userspace palettes are always correct as is */
1963 serge 254
	for (i = start; i < end; i++) {
1123 serge 255
			radeon_crtc->lut_r[i] = red[i] >> 6;
256
			radeon_crtc->lut_g[i] = green[i] >> 6;
257
			radeon_crtc->lut_b[i] = blue[i] >> 6;
258
		}
259
	radeon_crtc_load_lut(crtc);
260
}
261
 
262
static void radeon_crtc_destroy(struct drm_crtc *crtc)
263
{
264
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
265
 
266
	drm_crtc_cleanup(crtc);
267
	kfree(radeon_crtc);
268
}
269
 
5078 serge 270
static int
271
radeon_crtc_set_config(struct drm_mode_set *set)
272
{
273
	struct drm_device *dev;
274
	struct radeon_device *rdev;
275
	struct drm_crtc *crtc;
276
	bool active = false;
277
	int ret;
278
 
279
	if (!set || !set->crtc)
280
		return -EINVAL;
281
 
282
	dev = set->crtc->dev;
283
 
284
	ret = drm_crtc_helper_set_config(set);
285
 
286
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
287
		if (crtc->enabled)
288
			active = true;
289
 
290
//   pm_runtime_mark_last_busy(dev->dev);
291
 
292
	rdev = dev->dev_private;
293
	/* if we have active crtcs and we don't have a power ref,
294
	   take the current one */
295
	if (active && !rdev->have_disp_power_ref) {
296
		rdev->have_disp_power_ref = true;
297
		return ret;
298
	}
299
	/* if we have no active crtcs, then drop the power ref
300
	   we got before */
301
	if (!active && rdev->have_disp_power_ref) {
302
//       pm_runtime_put_autosuspend(dev->dev);
303
		rdev->have_disp_power_ref = false;
304
	}
305
 
306
	/* drop the power reference we got coming in here */
307
//   pm_runtime_put_autosuspend(dev->dev);
308
	return ret;
309
}
1123 serge 310
static const struct drm_crtc_funcs radeon_crtc_funcs = {
1221 serge 311
    .cursor_set = NULL,
312
    .cursor_move = NULL,
1123 serge 313
	.gamma_set = radeon_crtc_gamma_set,
5078 serge 314
	.set_config = radeon_crtc_set_config,
1123 serge 315
	.destroy = radeon_crtc_destroy,
1963 serge 316
	.page_flip = NULL,
1123 serge 317
};
318
 
319
static void radeon_crtc_init(struct drm_device *dev, int index)
320
{
321
	struct radeon_device *rdev = dev->dev_private;
322
	struct radeon_crtc *radeon_crtc;
323
	int i;
324
 
325
	radeon_crtc = kzalloc(sizeof(struct radeon_crtc) + (RADEONFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
326
	if (radeon_crtc == NULL)
327
		return;
328
 
329
	drm_crtc_init(dev, &radeon_crtc->base, &radeon_crtc_funcs);
330
 
331
	drm_mode_crtc_set_gamma_size(&radeon_crtc->base, 256);
332
	radeon_crtc->crtc_id = index;
1179 serge 333
	rdev->mode_info.crtcs[index] = radeon_crtc;
1123 serge 334
 
5078 serge 335
	if (rdev->family >= CHIP_BONAIRE) {
336
		radeon_crtc->max_cursor_width = CIK_CURSOR_WIDTH;
337
		radeon_crtc->max_cursor_height = CIK_CURSOR_HEIGHT;
338
	} else {
339
		radeon_crtc->max_cursor_width = CURSOR_WIDTH;
340
		radeon_crtc->max_cursor_height = CURSOR_HEIGHT;
341
	}
342
	dev->mode_config.cursor_width = radeon_crtc->max_cursor_width;
343
	dev->mode_config.cursor_height = radeon_crtc->max_cursor_height;
344
 
1179 serge 345
#if 0
1123 serge 346
	radeon_crtc->mode_set.crtc = &radeon_crtc->base;
347
	radeon_crtc->mode_set.connectors = (struct drm_connector **)(radeon_crtc + 1);
348
	radeon_crtc->mode_set.num_connectors = 0;
1179 serge 349
#endif
1123 serge 350
 
351
	for (i = 0; i < 256; i++) {
352
		radeon_crtc->lut_r[i] = i << 2;
353
		radeon_crtc->lut_g[i] = i << 2;
354
		radeon_crtc->lut_b[i] = i << 2;
355
	}
356
 
357
	if (rdev->is_atom_bios && (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom))
358
		radeon_atombios_init_crtc(dev, radeon_crtc);
359
	else
360
		radeon_legacy_init_crtc(dev, radeon_crtc);
361
}
362
 
5078 serge 363
static const char *encoder_names[38] = {
1123 serge 364
	"NONE",
365
	"INTERNAL_LVDS",
366
	"INTERNAL_TMDS1",
367
	"INTERNAL_TMDS2",
368
	"INTERNAL_DAC1",
369
	"INTERNAL_DAC2",
370
	"INTERNAL_SDVOA",
371
	"INTERNAL_SDVOB",
372
	"SI170B",
373
	"CH7303",
374
	"CH7301",
375
	"INTERNAL_DVO1",
376
	"EXTERNAL_SDVOA",
377
	"EXTERNAL_SDVOB",
378
	"TITFP513",
379
	"INTERNAL_LVTM1",
380
	"VT1623",
381
	"HDMI_SI1930",
382
	"HDMI_INTERNAL",
383
	"INTERNAL_KLDSCP_TMDS1",
384
	"INTERNAL_KLDSCP_DVO1",
385
	"INTERNAL_KLDSCP_DAC1",
386
	"INTERNAL_KLDSCP_DAC2",
387
	"SI178",
388
	"MVPU_FPGA",
389
	"INTERNAL_DDI",
390
	"VT1625",
391
	"HDMI_SI1932",
392
	"DP_AN9801",
393
	"DP_DP501",
394
	"INTERNAL_UNIPHY",
395
	"INTERNAL_KLDSCP_LVTMA",
396
	"INTERNAL_UNIPHY1",
397
	"INTERNAL_UNIPHY2",
1963 serge 398
	"NUTMEG",
399
	"TRAVIS",
5078 serge 400
	"INTERNAL_VCE",
401
	"INTERNAL_UNIPHY3",
1123 serge 402
};
403
 
1963 serge 404
static const char *hpd_names[6] = {
1404 serge 405
	"HPD1",
406
	"HPD2",
407
	"HPD3",
408
	"HPD4",
409
	"HPD5",
410
	"HPD6",
411
};
412
 
1123 serge 413
static void radeon_print_display_setup(struct drm_device *dev)
414
{
415
	struct drm_connector *connector;
416
	struct radeon_connector *radeon_connector;
417
	struct drm_encoder *encoder;
418
	struct radeon_encoder *radeon_encoder;
419
	uint32_t devices;
420
	int i = 0;
421
 
422
	DRM_INFO("Radeon Display Connectors\n");
423
	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
424
		radeon_connector = to_radeon_connector(connector);
425
		DRM_INFO("Connector %d:\n", i);
5078 serge 426
		DRM_INFO("  %s\n", connector->name);
1404 serge 427
		if (radeon_connector->hpd.hpd != RADEON_HPD_NONE)
428
			DRM_INFO("  %s\n", hpd_names[radeon_connector->hpd.hpd]);
429
		if (radeon_connector->ddc_bus) {
1123 serge 430
			DRM_INFO("  DDC: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
431
				 radeon_connector->ddc_bus->rec.mask_clk_reg,
432
				 radeon_connector->ddc_bus->rec.mask_data_reg,
433
				 radeon_connector->ddc_bus->rec.a_clk_reg,
434
				 radeon_connector->ddc_bus->rec.a_data_reg,
1404 serge 435
				 radeon_connector->ddc_bus->rec.en_clk_reg,
436
				 radeon_connector->ddc_bus->rec.en_data_reg,
437
				 radeon_connector->ddc_bus->rec.y_clk_reg,
438
				 radeon_connector->ddc_bus->rec.y_data_reg);
1963 serge 439
			if (radeon_connector->router.ddc_valid)
440
				DRM_INFO("  DDC Router 0x%x/0x%x\n",
441
					 radeon_connector->router.ddc_mux_control_pin,
442
					 radeon_connector->router.ddc_mux_state);
443
			if (radeon_connector->router.cd_valid)
444
				DRM_INFO("  Clock/Data Router 0x%x/0x%x\n",
445
					 radeon_connector->router.cd_mux_control_pin,
446
					 radeon_connector->router.cd_mux_state);
1404 serge 447
		} else {
448
			if (connector->connector_type == DRM_MODE_CONNECTOR_VGA ||
449
			    connector->connector_type == DRM_MODE_CONNECTOR_DVII ||
450
			    connector->connector_type == DRM_MODE_CONNECTOR_DVID ||
451
			    connector->connector_type == DRM_MODE_CONNECTOR_DVIA ||
452
			    connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
453
			    connector->connector_type == DRM_MODE_CONNECTOR_HDMIB)
454
				DRM_INFO("  DDC: no ddc bus - possible BIOS bug - please report to xorg-driver-ati@lists.x.org\n");
455
		}
1123 serge 456
		DRM_INFO("  Encoders:\n");
457
		list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
458
			radeon_encoder = to_radeon_encoder(encoder);
459
			devices = radeon_encoder->devices & radeon_connector->devices;
460
			if (devices) {
461
				if (devices & ATOM_DEVICE_CRT1_SUPPORT)
462
					DRM_INFO("    CRT1: %s\n", encoder_names[radeon_encoder->encoder_id]);
463
				if (devices & ATOM_DEVICE_CRT2_SUPPORT)
464
					DRM_INFO("    CRT2: %s\n", encoder_names[radeon_encoder->encoder_id]);
465
				if (devices & ATOM_DEVICE_LCD1_SUPPORT)
466
					DRM_INFO("    LCD1: %s\n", encoder_names[radeon_encoder->encoder_id]);
467
				if (devices & ATOM_DEVICE_DFP1_SUPPORT)
468
					DRM_INFO("    DFP1: %s\n", encoder_names[radeon_encoder->encoder_id]);
469
				if (devices & ATOM_DEVICE_DFP2_SUPPORT)
470
					DRM_INFO("    DFP2: %s\n", encoder_names[radeon_encoder->encoder_id]);
471
				if (devices & ATOM_DEVICE_DFP3_SUPPORT)
472
					DRM_INFO("    DFP3: %s\n", encoder_names[radeon_encoder->encoder_id]);
473
				if (devices & ATOM_DEVICE_DFP4_SUPPORT)
474
					DRM_INFO("    DFP4: %s\n", encoder_names[radeon_encoder->encoder_id]);
475
				if (devices & ATOM_DEVICE_DFP5_SUPPORT)
476
					DRM_INFO("    DFP5: %s\n", encoder_names[radeon_encoder->encoder_id]);
1963 serge 477
				if (devices & ATOM_DEVICE_DFP6_SUPPORT)
478
					DRM_INFO("    DFP6: %s\n", encoder_names[radeon_encoder->encoder_id]);
1123 serge 479
				if (devices & ATOM_DEVICE_TV1_SUPPORT)
480
					DRM_INFO("    TV1: %s\n", encoder_names[radeon_encoder->encoder_id]);
481
				if (devices & ATOM_DEVICE_CV_SUPPORT)
482
					DRM_INFO("    CV: %s\n", encoder_names[radeon_encoder->encoder_id]);
483
			}
484
		}
485
		i++;
486
	}
487
}
488
 
1179 serge 489
static bool radeon_setup_enc_conn(struct drm_device *dev)
1123 serge 490
{
491
	struct radeon_device *rdev = dev->dev_private;
492
	bool ret = false;
493
 
494
	if (rdev->bios) {
495
		if (rdev->is_atom_bios) {
1963 serge 496
			ret = radeon_get_atom_connector_info_from_supported_devices_table(dev);
497
			if (ret == false)
1123 serge 498
				ret = radeon_get_atom_connector_info_from_object_table(dev);
1404 serge 499
		} else {
1123 serge 500
			ret = radeon_get_legacy_connector_info_from_bios(dev);
1404 serge 501
			if (ret == false)
502
				ret = radeon_get_legacy_connector_info_from_table(dev);
503
		}
1123 serge 504
	} else {
505
		if (!ASIC_IS_AVIVO(rdev))
506
			ret = radeon_get_legacy_connector_info_from_table(dev);
507
	}
508
	if (ret) {
1404 serge 509
		radeon_setup_encoder_clones(dev);
1123 serge 510
		radeon_print_display_setup(dev);
511
	}
512
 
513
	return ret;
514
}
515
 
5078 serge 516
/* avivo */
517
 
518
/**
519
 * avivo_reduce_ratio - fractional number reduction
520
 *
521
 * @nom: nominator
522
 * @den: denominator
523
 * @nom_min: minimum value for nominator
524
 * @den_min: minimum value for denominator
525
 *
526
 * Find the greatest common divisor and apply it on both nominator and
527
 * denominator, but make nominator and denominator are at least as large
528
 * as their minimum values.
529
 */
530
static void avivo_reduce_ratio(unsigned *nom, unsigned *den,
531
			       unsigned nom_min, unsigned den_min)
1123 serge 532
{
5078 serge 533
	unsigned tmp;
1123 serge 534
 
5078 serge 535
	/* reduce the numbers to a simpler ratio */
536
	tmp = gcd(*nom, *den);
537
	*nom /= tmp;
538
	*den /= tmp;
1963 serge 539
 
5078 serge 540
	/* make sure nominator is large enough */
541
        if (*nom < nom_min) {
542
		tmp = DIV_ROUND_UP(nom_min, *nom);
543
		*nom *= tmp;
544
		*den *= tmp;
1404 serge 545
	}
1963 serge 546
 
5078 serge 547
	/* make sure the denominator is large enough */
548
	if (*den < den_min) {
549
		tmp = DIV_ROUND_UP(den_min, *den);
550
		*nom *= tmp;
551
		*den *= tmp;
1963 serge 552
	}
1123 serge 553
}
554
 
5078 serge 555
/**
556
 * avivo_get_fb_ref_div - feedback and ref divider calculation
557
 *
558
 * @nom: nominator
559
 * @den: denominator
560
 * @post_div: post divider
561
 * @fb_div_max: feedback divider maximum
562
 * @ref_div_max: reference divider maximum
563
 * @fb_div: resulting feedback divider
564
 * @ref_div: resulting reference divider
565
 *
566
 * Calculate feedback and reference divider for a given post divider. Makes
567
 * sure we stay within the limits.
568
 */
569
static void avivo_get_fb_ref_div(unsigned nom, unsigned den, unsigned post_div,
570
				 unsigned fb_div_max, unsigned ref_div_max,
571
				 unsigned *fb_div, unsigned *ref_div)
1963 serge 572
{
5078 serge 573
	/* limit reference * post divider to a maximum */
574
	ref_div_max = max(min(100 / post_div, ref_div_max), 1u);
1963 serge 575
 
5078 serge 576
	/* get matching reference and feedback divider */
577
	*ref_div = min(max(DIV_ROUND_CLOSEST(den, post_div), 1u), ref_div_max);
578
	*fb_div = DIV_ROUND_CLOSEST(nom * *ref_div * post_div, den);
1963 serge 579
 
5078 serge 580
	/* limit fb divider to its maximum */
581
        if (*fb_div > fb_div_max) {
582
		*ref_div = DIV_ROUND_CLOSEST(*ref_div * fb_div_max, *fb_div);
583
		*fb_div = fb_div_max;
584
	}
1963 serge 585
}
586
 
5078 serge 587
/**
588
 * radeon_compute_pll_avivo - compute PLL paramaters
589
 *
590
 * @pll: information about the PLL
591
 * @dot_clock_p: resulting pixel clock
592
 * fb_div_p: resulting feedback divider
593
 * frac_fb_div_p: fractional part of the feedback divider
594
 * ref_div_p: resulting reference divider
595
 * post_div_p: resulting reference divider
596
 *
597
 * Try to calculate the PLL parameters to generate the given frequency:
598
 * dot_clock = (ref_freq * feedback_div) / (ref_div * post_div)
599
 */
600
void radeon_compute_pll_avivo(struct radeon_pll *pll,
601
			      u32 freq,
602
			      u32 *dot_clock_p,
603
			      u32 *fb_div_p,
604
			      u32 *frac_fb_div_p,
605
			      u32 *ref_div_p,
606
			      u32 *post_div_p)
1963 serge 607
{
5078 serge 608
	unsigned target_clock = pll->flags & RADEON_PLL_USE_FRAC_FB_DIV ?
609
		freq : freq / 10;
1963 serge 610
 
5078 serge 611
	unsigned fb_div_min, fb_div_max, fb_div;
612
	unsigned post_div_min, post_div_max, post_div;
613
	unsigned ref_div_min, ref_div_max, ref_div;
614
	unsigned post_div_best, diff_best;
615
	unsigned nom, den;
1963 serge 616
 
5078 serge 617
	/* determine allowed feedback divider range */
618
	fb_div_min = pll->min_feedback_div;
619
	fb_div_max = pll->max_feedback_div;
620
 
621
	if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) {
622
		fb_div_min *= 10;
623
		fb_div_max *= 10;
624
	}
625
 
626
	/* determine allowed ref divider range */
627
	if (pll->flags & RADEON_PLL_USE_REF_DIV)
628
		ref_div_min = pll->reference_div;
629
	else
630
		ref_div_min = pll->min_ref_div;
631
 
632
	if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV &&
633
	    pll->flags & RADEON_PLL_USE_REF_DIV)
634
		ref_div_max = pll->reference_div;
1963 serge 635
		else
5078 serge 636
		ref_div_max = pll->max_ref_div;
637
 
638
	/* determine allowed post divider range */
639
	if (pll->flags & RADEON_PLL_USE_POST_DIV) {
640
		post_div_min = pll->post_div;
641
		post_div_max = pll->post_div;
1963 serge 642
	} else {
5078 serge 643
		unsigned vco_min, vco_max;
644
 
645
		if (pll->flags & RADEON_PLL_IS_LCD) {
646
			vco_min = pll->lcd_pll_out_min;
647
			vco_max = pll->lcd_pll_out_max;
648
		} else {
649
			vco_min = pll->pll_out_min;
650
			vco_max = pll->pll_out_max;
651
		}
652
 
653
		if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) {
654
			vco_min *= 10;
655
			vco_max *= 10;
1963 serge 656
	}
657
 
5078 serge 658
		post_div_min = vco_min / target_clock;
659
		if ((target_clock * post_div_min) < vco_min)
660
			++post_div_min;
661
		if (post_div_min < pll->min_post_div)
662
			post_div_min = pll->min_post_div;
1963 serge 663
 
5078 serge 664
		post_div_max = vco_max / target_clock;
665
		if ((target_clock * post_div_max) > vco_max)
666
			--post_div_max;
667
		if (post_div_max > pll->max_post_div)
668
			post_div_max = pll->max_post_div;
1963 serge 669
	}
670
 
5078 serge 671
	/* represent the searched ratio as fractional number */
672
	nom = target_clock;
673
	den = pll->reference_freq;
1963 serge 674
 
5078 serge 675
	/* reduce the numbers to a simpler ratio */
676
	avivo_reduce_ratio(&nom, &den, fb_div_min, post_div_min);
1963 serge 677
 
5078 serge 678
	/* now search for a post divider */
679
	if (pll->flags & RADEON_PLL_PREFER_MINM_OVER_MAXP)
680
		post_div_best = post_div_min;
681
	else
682
		post_div_best = post_div_max;
683
	diff_best = ~0;
1963 serge 684
 
5078 serge 685
	for (post_div = post_div_min; post_div <= post_div_max; ++post_div) {
686
		unsigned diff;
687
		avivo_get_fb_ref_div(nom, den, post_div, fb_div_max,
688
				     ref_div_max, &fb_div, &ref_div);
689
		diff = abs(target_clock - (pll->reference_freq * fb_div) /
690
			(ref_div * post_div));
1963 serge 691
 
5078 serge 692
		if (diff < diff_best || (diff == diff_best &&
693
		    !(pll->flags & RADEON_PLL_PREFER_MINM_OVER_MAXP))) {
1963 serge 694
 
5078 serge 695
			post_div_best = post_div;
696
			diff_best = diff;
1963 serge 697
		}
5078 serge 698
	}
699
	post_div = post_div_best;
1963 serge 700
 
5078 serge 701
	/* get the feedback and reference divider for the optimal value */
702
	avivo_get_fb_ref_div(nom, den, post_div, fb_div_max, ref_div_max,
703
			     &fb_div, &ref_div);
704
 
705
	/* reduce the numbers to a simpler ratio once more */
706
	/* this also makes sure that the reference divider is large enough */
707
	avivo_reduce_ratio(&fb_div, &ref_div, fb_div_min, ref_div_min);
708
 
709
	/* avoid high jitter with small fractional dividers */
710
	if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV && (fb_div % 10)) {
711
		fb_div_min = max(fb_div_min, (9 - (fb_div % 10)) * 20 + 50);
712
		if (fb_div < fb_div_min) {
713
			unsigned tmp = DIV_ROUND_UP(fb_div_min, fb_div);
714
			fb_div *= tmp;
715
			ref_div *= tmp;
1963 serge 716
		}
717
	}
718
 
5078 serge 719
	/* and finally save the result */
720
	if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) {
721
		*fb_div_p = fb_div / 10;
722
		*frac_fb_div_p = fb_div % 10;
723
	} else {
724
		*fb_div_p = fb_div;
725
		*frac_fb_div_p = 0;
726
	}
727
 
728
	*dot_clock_p = ((pll->reference_freq * *fb_div_p * 10) +
729
			(pll->reference_freq * *frac_fb_div_p)) /
1963 serge 730
		(ref_div * post_div * 10);
731
	*ref_div_p = ref_div;
732
	*post_div_p = post_div;
5078 serge 733
 
734
	DRM_DEBUG_KMS("%d - %d, pll dividers - fb: %d.%d ref: %d, post %d\n",
735
		      freq, *dot_clock_p * 10, *fb_div_p, *frac_fb_div_p,
736
		      ref_div, post_div);
1963 serge 737
}
738
 
739
/* pre-avivo */
1123 serge 740
static inline uint32_t radeon_div(uint64_t n, uint32_t d)
741
{
742
	uint64_t mod;
743
 
744
	n += d / 2;
745
 
746
	mod = do_div(n, d);
747
	return n;
748
}
749
 
1963 serge 750
void radeon_compute_pll_legacy(struct radeon_pll *pll,
1123 serge 751
			uint64_t freq,
752
			uint32_t *dot_clock_p,
753
			uint32_t *fb_div_p,
754
			uint32_t *frac_fb_div_p,
755
			uint32_t *ref_div_p,
1404 serge 756
			uint32_t *post_div_p)
1123 serge 757
{
758
	uint32_t min_ref_div = pll->min_ref_div;
759
	uint32_t max_ref_div = pll->max_ref_div;
1404 serge 760
	uint32_t min_post_div = pll->min_post_div;
761
	uint32_t max_post_div = pll->max_post_div;
1123 serge 762
	uint32_t min_fractional_feed_div = 0;
763
	uint32_t max_fractional_feed_div = 0;
764
	uint32_t best_vco = pll->best_vco;
765
	uint32_t best_post_div = 1;
766
	uint32_t best_ref_div = 1;
767
	uint32_t best_feedback_div = 1;
768
	uint32_t best_frac_feedback_div = 0;
769
	uint32_t best_freq = -1;
770
	uint32_t best_error = 0xffffffff;
771
	uint32_t best_vco_diff = 1;
772
	uint32_t post_div;
1963 serge 773
	u32 pll_out_min, pll_out_max;
1123 serge 774
 
1963 serge 775
	DRM_DEBUG_KMS("PLL freq %llu %u %u\n", freq, pll->min_ref_div, pll->max_ref_div);
1123 serge 776
	freq = freq * 1000;
777
 
1963 serge 778
	if (pll->flags & RADEON_PLL_IS_LCD) {
779
		pll_out_min = pll->lcd_pll_out_min;
780
		pll_out_max = pll->lcd_pll_out_max;
781
	} else {
782
		pll_out_min = pll->pll_out_min;
783
		pll_out_max = pll->pll_out_max;
784
	}
785
 
786
	if (pll_out_min > 64800)
787
		pll_out_min = 64800;
788
 
1404 serge 789
	if (pll->flags & RADEON_PLL_USE_REF_DIV)
1123 serge 790
		min_ref_div = max_ref_div = pll->reference_div;
791
	else {
792
		while (min_ref_div < max_ref_div-1) {
793
			uint32_t mid = (min_ref_div + max_ref_div) / 2;
794
			uint32_t pll_in = pll->reference_freq / mid;
795
			if (pll_in < pll->pll_in_min)
796
				max_ref_div = mid;
797
			else if (pll_in > pll->pll_in_max)
798
				min_ref_div = mid;
799
			else
800
				break;
801
		}
802
	}
803
 
1404 serge 804
	if (pll->flags & RADEON_PLL_USE_POST_DIV)
805
		min_post_div = max_post_div = pll->post_div;
806
 
807
	if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) {
1123 serge 808
		min_fractional_feed_div = pll->min_frac_feedback_div;
809
		max_fractional_feed_div = pll->max_frac_feedback_div;
810
	}
811
 
1963 serge 812
	for (post_div = max_post_div; post_div >= min_post_div; --post_div) {
1123 serge 813
		uint32_t ref_div;
814
 
1404 serge 815
		if ((pll->flags & RADEON_PLL_NO_ODD_POST_DIV) && (post_div & 1))
1123 serge 816
			continue;
817
 
818
		/* legacy radeons only have a few post_divs */
1404 serge 819
		if (pll->flags & RADEON_PLL_LEGACY) {
1123 serge 820
			if ((post_div == 5) ||
821
			    (post_div == 7) ||
822
			    (post_div == 9) ||
823
			    (post_div == 10) ||
824
			    (post_div == 11) ||
825
			    (post_div == 13) ||
826
			    (post_div == 14) ||
827
			    (post_div == 15))
828
				continue;
829
		}
830
 
831
		for (ref_div = min_ref_div; ref_div <= max_ref_div; ++ref_div) {
832
			uint32_t feedback_div, current_freq = 0, error, vco_diff;
833
			uint32_t pll_in = pll->reference_freq / ref_div;
834
			uint32_t min_feed_div = pll->min_feedback_div;
835
			uint32_t max_feed_div = pll->max_feedback_div + 1;
836
 
837
			if (pll_in < pll->pll_in_min || pll_in > pll->pll_in_max)
838
				continue;
839
 
840
			while (min_feed_div < max_feed_div) {
841
				uint32_t vco;
842
				uint32_t min_frac_feed_div = min_fractional_feed_div;
843
				uint32_t max_frac_feed_div = max_fractional_feed_div + 1;
844
				uint32_t frac_feedback_div;
845
				uint64_t tmp;
846
 
847
				feedback_div = (min_feed_div + max_feed_div) / 2;
848
 
849
				tmp = (uint64_t)pll->reference_freq * feedback_div;
850
				vco = radeon_div(tmp, ref_div);
851
 
1963 serge 852
				if (vco < pll_out_min) {
1123 serge 853
					min_feed_div = feedback_div + 1;
854
					continue;
1963 serge 855
				} else if (vco > pll_out_max) {
1123 serge 856
					max_feed_div = feedback_div;
857
					continue;
858
				}
859
 
860
				while (min_frac_feed_div < max_frac_feed_div) {
861
					frac_feedback_div = (min_frac_feed_div + max_frac_feed_div) / 2;
862
					tmp = (uint64_t)pll->reference_freq * 10000 * feedback_div;
863
					tmp += (uint64_t)pll->reference_freq * 1000 * frac_feedback_div;
864
					current_freq = radeon_div(tmp, ref_div * post_div);
865
 
1404 serge 866
					if (pll->flags & RADEON_PLL_PREFER_CLOSEST_LOWER) {
1963 serge 867
						if (freq < current_freq)
868
							error = 0xffffffff;
869
						else
1179 serge 870
						error = freq - current_freq;
871
					} else
1123 serge 872
					error = abs(current_freq - freq);
873
					vco_diff = abs(vco - best_vco);
874
 
875
					if ((best_vco == 0 && error < best_error) ||
876
					    (best_vco != 0 &&
1963 serge 877
					     ((best_error > 100 && error < best_error - 100) ||
1123 serge 878
					      (abs(error - best_error) < 100 && vco_diff < best_vco_diff)))) {
879
						best_post_div = post_div;
880
						best_ref_div = ref_div;
881
						best_feedback_div = feedback_div;
882
						best_frac_feedback_div = frac_feedback_div;
883
						best_freq = current_freq;
884
						best_error = error;
885
						best_vco_diff = vco_diff;
886
					} else if (current_freq == freq) {
887
						if (best_freq == -1) {
888
							best_post_div = post_div;
889
							best_ref_div = ref_div;
890
							best_feedback_div = feedback_div;
891
							best_frac_feedback_div = frac_feedback_div;
892
							best_freq = current_freq;
893
							best_error = error;
894
							best_vco_diff = vco_diff;
1404 serge 895
						} else if (((pll->flags & RADEON_PLL_PREFER_LOW_REF_DIV) && (ref_div < best_ref_div)) ||
896
							   ((pll->flags & RADEON_PLL_PREFER_HIGH_REF_DIV) && (ref_div > best_ref_div)) ||
897
							   ((pll->flags & RADEON_PLL_PREFER_LOW_FB_DIV) && (feedback_div < best_feedback_div)) ||
898
							   ((pll->flags & RADEON_PLL_PREFER_HIGH_FB_DIV) && (feedback_div > best_feedback_div)) ||
899
							   ((pll->flags & RADEON_PLL_PREFER_LOW_POST_DIV) && (post_div < best_post_div)) ||
900
							   ((pll->flags & RADEON_PLL_PREFER_HIGH_POST_DIV) && (post_div > best_post_div))) {
1123 serge 901
							best_post_div = post_div;
902
							best_ref_div = ref_div;
903
							best_feedback_div = feedback_div;
904
							best_frac_feedback_div = frac_feedback_div;
905
							best_freq = current_freq;
906
							best_error = error;
907
							best_vco_diff = vco_diff;
908
						}
909
					}
910
					if (current_freq < freq)
911
						min_frac_feed_div = frac_feedback_div + 1;
912
					else
913
						max_frac_feed_div = frac_feedback_div;
914
				}
915
				if (current_freq < freq)
916
					min_feed_div = feedback_div + 1;
917
				else
918
					max_feed_div = feedback_div;
919
			}
920
		}
921
	}
922
 
923
	*dot_clock_p = best_freq / 10000;
924
	*fb_div_p = best_feedback_div;
925
	*frac_fb_div_p = best_frac_feedback_div;
926
	*ref_div_p = best_ref_div;
927
	*post_div_p = best_post_div;
1963 serge 928
	DRM_DEBUG_KMS("%lld %d, pll dividers - fb: %d.%d ref: %d, post %d\n",
929
		      (long long)freq,
930
		      best_freq / 1000, best_feedback_div, best_frac_feedback_div,
931
		      best_ref_div, best_post_div);
1123 serge 932
 
1430 serge 933
}
934
 
1123 serge 935
static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb)
936
{
937
	struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb);
938
 
5078 serge 939
	if (radeon_fb->obj) {
940
		drm_gem_object_unreference_unlocked(radeon_fb->obj);
941
	}
1123 serge 942
	drm_framebuffer_cleanup(fb);
943
	kfree(radeon_fb);
944
}
945
 
946
static int radeon_user_framebuffer_create_handle(struct drm_framebuffer *fb,
947
                         struct drm_file *file_priv,
948
                         unsigned int *handle)
949
{
950
   struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb);
951
 
952
   return NULL;
953
//   return drm_gem_handle_create(file_priv, radeon_fb->obj, handle);
954
}
955
 
956
static const struct drm_framebuffer_funcs radeon_fb_funcs = {
957
	.destroy = radeon_user_framebuffer_destroy,
958
    .create_handle = radeon_user_framebuffer_create_handle,
959
};
960
 
2997 Serge 961
int
1963 serge 962
radeon_framebuffer_init(struct drm_device *dev,
963
			struct radeon_framebuffer *rfb,
2997 Serge 964
			struct drm_mode_fb_cmd2 *mode_cmd,
1123 serge 965
			  struct drm_gem_object *obj)
966
{
2997 Serge 967
	int ret;
1963 serge 968
	rfb->obj = obj;
3764 Serge 969
	drm_helper_mode_fill_fb_struct(&rfb->base, mode_cmd);
2997 Serge 970
	ret = drm_framebuffer_init(dev, &rfb->base, &radeon_fb_funcs);
971
	if (ret) {
972
		rfb->obj = NULL;
973
		return ret;
974
	}
975
	return 0;
1123 serge 976
}
977
 
978
 
979
 
980
static const struct drm_mode_config_funcs radeon_mode_funcs = {
1963 serge 981
//	.fb_create = radeon_user_framebuffer_create,
982
//   .output_poll_changed = radeon_output_poll_changed
1123 serge 983
};
984
 
1179 serge 985
static struct drm_prop_enum_list radeon_tmds_pll_enum_list[] =
986
{	{ 0, "driver" },
987
	{ 1, "bios" },
988
};
989
 
990
static struct drm_prop_enum_list radeon_tv_std_enum_list[] =
991
{	{ TV_STD_NTSC, "ntsc" },
992
	{ TV_STD_PAL, "pal" },
993
	{ TV_STD_PAL_M, "pal-m" },
994
	{ TV_STD_PAL_60, "pal-60" },
995
	{ TV_STD_NTSC_J, "ntsc-j" },
996
	{ TV_STD_SCART_PAL, "scart-pal" },
997
	{ TV_STD_PAL_CN, "pal-cn" },
998
	{ TV_STD_SECAM, "secam" },
999
};
1000
 
1963 serge 1001
static struct drm_prop_enum_list radeon_underscan_enum_list[] =
1002
{	{ UNDERSCAN_OFF, "off" },
1003
	{ UNDERSCAN_ON, "on" },
1004
	{ UNDERSCAN_AUTO, "auto" },
1005
};
1006
 
5078 serge 1007
static struct drm_prop_enum_list radeon_audio_enum_list[] =
1008
{	{ RADEON_AUDIO_DISABLE, "off" },
1009
	{ RADEON_AUDIO_ENABLE, "on" },
1010
	{ RADEON_AUDIO_AUTO, "auto" },
1011
};
1012
 
1013
/* XXX support different dither options? spatial, temporal, both, etc. */
1014
static struct drm_prop_enum_list radeon_dither_enum_list[] =
1015
{	{ RADEON_FMT_DITHER_DISABLE, "off" },
1016
	{ RADEON_FMT_DITHER_ENABLE, "on" },
1017
};
1018
 
1404 serge 1019
static int radeon_modeset_create_props(struct radeon_device *rdev)
1123 serge 1020
{
2997 Serge 1021
	int sz;
1125 serge 1022
 
1179 serge 1023
	if (rdev->is_atom_bios) {
1024
		rdev->mode_info.coherent_mode_property =
2997 Serge 1025
			drm_property_create_range(rdev->ddev, 0 , "coherent", 0, 1);
1179 serge 1026
		if (!rdev->mode_info.coherent_mode_property)
1027
			return -ENOMEM;
1028
	}
1029
 
1030
	if (!ASIC_IS_AVIVO(rdev)) {
1031
		sz = ARRAY_SIZE(radeon_tmds_pll_enum_list);
1032
		rdev->mode_info.tmds_pll_property =
2997 Serge 1033
			drm_property_create_enum(rdev->ddev, 0,
1034
					    "tmds_pll",
1035
					    radeon_tmds_pll_enum_list, sz);
1179 serge 1036
	}
1037
 
1038
	rdev->mode_info.load_detect_property =
2997 Serge 1039
		drm_property_create_range(rdev->ddev, 0, "load detection", 0, 1);
1179 serge 1040
	if (!rdev->mode_info.load_detect_property)
1041
		return -ENOMEM;
1042
 
1043
	drm_mode_create_scaling_mode_property(rdev->ddev);
1044
 
1045
	sz = ARRAY_SIZE(radeon_tv_std_enum_list);
1046
	rdev->mode_info.tv_std_property =
2997 Serge 1047
		drm_property_create_enum(rdev->ddev, 0,
1048
				    "tv standard",
1049
				    radeon_tv_std_enum_list, sz);
1179 serge 1050
 
1963 serge 1051
	sz = ARRAY_SIZE(radeon_underscan_enum_list);
1052
	rdev->mode_info.underscan_property =
2997 Serge 1053
		drm_property_create_enum(rdev->ddev, 0,
1054
				    "underscan",
1055
				    radeon_underscan_enum_list, sz);
1963 serge 1056
 
1057
	rdev->mode_info.underscan_hborder_property =
2997 Serge 1058
		drm_property_create_range(rdev->ddev, 0,
1059
					"underscan hborder", 0, 128);
1963 serge 1060
	if (!rdev->mode_info.underscan_hborder_property)
1061
		return -ENOMEM;
1062
 
1063
	rdev->mode_info.underscan_vborder_property =
2997 Serge 1064
		drm_property_create_range(rdev->ddev, 0,
1065
					"underscan vborder", 0, 128);
1963 serge 1066
	if (!rdev->mode_info.underscan_vborder_property)
1067
		return -ENOMEM;
1068
 
5078 serge 1069
	sz = ARRAY_SIZE(radeon_audio_enum_list);
1070
	rdev->mode_info.audio_property =
1071
		drm_property_create_enum(rdev->ddev, 0,
1072
					 "audio",
1073
					 radeon_audio_enum_list, sz);
1074
 
1075
	sz = ARRAY_SIZE(radeon_dither_enum_list);
1076
	rdev->mode_info.dither_property =
1077
		drm_property_create_enum(rdev->ddev, 0,
1078
					 "dither",
1079
					 radeon_dither_enum_list, sz);
1080
 
1179 serge 1081
	return 0;
1082
}
1083
 
1963 serge 1084
void radeon_update_display_priority(struct radeon_device *rdev)
1085
{
1086
	/* adjustment options for the display watermarks */
1087
	if ((radeon_disp_priority == 0) || (radeon_disp_priority > 2)) {
1088
		/* set display priority to high for r3xx, rv515 chips
1089
		 * this avoids flickering due to underflow to the
1090
		 * display controllers during heavy acceleration.
1091
		 * Don't force high on rs4xx igp chips as it seems to
1092
		 * affect the sound card.  See kernel bug 15982.
1093
		 */
1094
		if ((ASIC_IS_R300(rdev) || (rdev->family == CHIP_RV515)) &&
1095
		    !(rdev->flags & RADEON_IS_IGP))
1096
			rdev->disp_priority = 2;
1097
		else
1098
			rdev->disp_priority = 0;
1099
	} else
1100
		rdev->disp_priority = radeon_disp_priority;
1101
 
1102
}
1103
 
2997 Serge 1104
/*
1105
 * Allocate hdmi structs and determine register offsets
1106
 */
1107
static void radeon_afmt_init(struct radeon_device *rdev)
1108
{
1109
	int i;
1110
 
1111
	for (i = 0; i < RADEON_MAX_AFMT_BLOCKS; i++)
1112
		rdev->mode_info.afmt[i] = NULL;
1113
 
5078 serge 1114
	if (ASIC_IS_NODCE(rdev)) {
1115
		/* nothing to do */
2997 Serge 1116
	} else if (ASIC_IS_DCE4(rdev)) {
5078 serge 1117
		static uint32_t eg_offsets[] = {
1118
			EVERGREEN_CRTC0_REGISTER_OFFSET,
1119
			EVERGREEN_CRTC1_REGISTER_OFFSET,
1120
			EVERGREEN_CRTC2_REGISTER_OFFSET,
1121
			EVERGREEN_CRTC3_REGISTER_OFFSET,
1122
			EVERGREEN_CRTC4_REGISTER_OFFSET,
1123
			EVERGREEN_CRTC5_REGISTER_OFFSET,
1124
			0x13830 - 0x7030,
1125
		};
1126
		int num_afmt;
1127
 
1128
		/* DCE8 has 7 audio blocks tied to DIG encoders */
1129
		/* DCE6 has 6 audio blocks tied to DIG encoders */
2997 Serge 1130
		/* DCE4/5 has 6 audio blocks tied to DIG encoders */
1131
		/* DCE4.1 has 2 audio blocks tied to DIG encoders */
5078 serge 1132
		if (ASIC_IS_DCE8(rdev))
1133
			num_afmt = 7;
1134
		else if (ASIC_IS_DCE6(rdev))
1135
			num_afmt = 6;
1136
		else if (ASIC_IS_DCE5(rdev))
1137
			num_afmt = 6;
1138
		else if (ASIC_IS_DCE41(rdev))
1139
			num_afmt = 2;
1140
		else /* DCE4 */
1141
			num_afmt = 6;
1142
 
1143
		BUG_ON(num_afmt > ARRAY_SIZE(eg_offsets));
1144
		for (i = 0; i < num_afmt; i++) {
1145
			rdev->mode_info.afmt[i] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL);
1146
			if (rdev->mode_info.afmt[i]) {
1147
				rdev->mode_info.afmt[i]->offset = eg_offsets[i];
1148
				rdev->mode_info.afmt[i]->id = i;
2997 Serge 1149
			}
1150
		}
1151
	} else if (ASIC_IS_DCE3(rdev)) {
1152
		/* DCE3.x has 2 audio blocks tied to DIG encoders */
1153
		rdev->mode_info.afmt[0] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL);
1154
		if (rdev->mode_info.afmt[0]) {
1155
			rdev->mode_info.afmt[0]->offset = DCE3_HDMI_OFFSET0;
1156
			rdev->mode_info.afmt[0]->id = 0;
1157
		}
1158
		rdev->mode_info.afmt[1] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL);
1159
		if (rdev->mode_info.afmt[1]) {
1160
			rdev->mode_info.afmt[1]->offset = DCE3_HDMI_OFFSET1;
1161
			rdev->mode_info.afmt[1]->id = 1;
1162
		}
1163
	} else if (ASIC_IS_DCE2(rdev)) {
1164
		/* DCE2 has at least 1 routable audio block */
1165
		rdev->mode_info.afmt[0] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL);
1166
		if (rdev->mode_info.afmt[0]) {
1167
			rdev->mode_info.afmt[0]->offset = DCE2_HDMI_OFFSET0;
1168
			rdev->mode_info.afmt[0]->id = 0;
1169
		}
1170
		/* r6xx has 2 routable audio blocks */
1171
		if (rdev->family >= CHIP_R600) {
1172
			rdev->mode_info.afmt[1] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL);
1173
			if (rdev->mode_info.afmt[1]) {
1174
				rdev->mode_info.afmt[1]->offset = DCE2_HDMI_OFFSET1;
1175
				rdev->mode_info.afmt[1]->id = 1;
1176
			}
1177
		}
1178
	}
1179
}
1180
 
1181
static void radeon_afmt_fini(struct radeon_device *rdev)
1182
{
1183
	int i;
1184
 
1185
	for (i = 0; i < RADEON_MAX_AFMT_BLOCKS; i++) {
1186
		kfree(rdev->mode_info.afmt[i]);
1187
		rdev->mode_info.afmt[i] = NULL;
1188
	}
1189
}
1190
 
1179 serge 1191
int radeon_modeset_init(struct radeon_device *rdev)
1192
{
1430 serge 1193
	int i;
1123 serge 1194
	int ret;
1195
 
5078 serge 1196
ENTER();
1197
 
1123 serge 1198
	drm_mode_config_init(rdev->ddev);
1199
	rdev->mode_info.mode_config_initialized = true;
1200
 
2997 Serge 1201
	rdev->ddev->mode_config.funcs = &radeon_mode_funcs;
1123 serge 1202
 
1963 serge 1203
	if (ASIC_IS_DCE5(rdev)) {
1204
		rdev->ddev->mode_config.max_width = 16384;
1205
		rdev->ddev->mode_config.max_height = 16384;
1206
	} else if (ASIC_IS_AVIVO(rdev)) {
1123 serge 1207
		rdev->ddev->mode_config.max_width = 8192;
1208
		rdev->ddev->mode_config.max_height = 8192;
1209
	} else {
1210
		rdev->ddev->mode_config.max_width = 4096;
1211
		rdev->ddev->mode_config.max_height = 4096;
1212
	}
1213
 
2997 Serge 1214
	rdev->ddev->mode_config.preferred_depth = 24;
1215
	rdev->ddev->mode_config.prefer_shadow = 1;
1216
 
1123 serge 1217
	rdev->ddev->mode_config.fb_base = rdev->mc.aper_base;
1218
 
1179 serge 1219
	ret = radeon_modeset_create_props(rdev);
1220
	if (ret) {
1221
		return ret;
1222
	}
1221 serge 1223
 
1963 serge 1224
	/* init i2c buses */
1225
	radeon_i2c_init(rdev);
1226
 
1430 serge 1227
	/* check combios for a valid hardcoded EDID - Sun servers */
1228
	if (!rdev->is_atom_bios) {
1229
		/* check for hardcoded EDID in BIOS */
1230
		radeon_combios_check_hardcoded_edid(rdev);
1231
	}
1232
 
1221 serge 1233
	/* allocate crtcs */
1430 serge 1234
	for (i = 0; i < rdev->num_crtc; i++) {
1123 serge 1235
		radeon_crtc_init(rdev->ddev, i);
1236
	}
1237
 
1238
	/* okay we should have all the bios connectors */
1239
	ret = radeon_setup_enc_conn(rdev->ddev);
1240
	if (!ret) {
1241
		return ret;
1242
	}
1963 serge 1243
 
2997 Serge 1244
	/* init dig PHYs, disp eng pll */
1245
	if (rdev->is_atom_bios) {
1963 serge 1246
		radeon_atom_encoder_init(rdev);
2997 Serge 1247
		radeon_atom_disp_eng_pll_init(rdev);
1248
	}
1963 serge 1249
 
1404 serge 1250
	/* initialize hpd */
1963 serge 1251
//   radeon_hpd_init(rdev);
1252
 
2997 Serge 1253
	/* setup afmt */
5078 serge 1254
	radeon_afmt_init(rdev);
2997 Serge 1255
 
1963 serge 1256
	radeon_fbdev_init(rdev);
1257
 
5078 serge 1258
LEAVE();
1259
 
1123 serge 1260
	return 0;
1261
}
1262
 
1263
void radeon_modeset_fini(struct radeon_device *rdev)
1264
{
1430 serge 1265
	kfree(rdev->mode_info.bios_hardcoded_edid);
1266
 
1123 serge 1267
	if (rdev->mode_info.mode_config_initialized) {
2997 Serge 1268
//		radeon_afmt_fini(rdev);
1963 serge 1269
//       drm_kms_helper_poll_fini(rdev->ddev);
1270
//       radeon_hpd_fini(rdev);
3764 Serge 1271
//       drm_mode_config_cleanup(rdev->ddev);
1123 serge 1272
		rdev->mode_info.mode_config_initialized = false;
1273
	}
1963 serge 1274
	/* free i2c buses */
1275
	radeon_i2c_fini(rdev);
1123 serge 1276
}
1277
 
2997 Serge 1278
static bool is_hdtv_mode(const struct drm_display_mode *mode)
1963 serge 1279
{
1280
	/* try and guess if this is a tv or a monitor */
1281
	if ((mode->vdisplay == 480 && mode->hdisplay == 720) || /* 480p */
1282
	    (mode->vdisplay == 576) || /* 576p */
1283
	    (mode->vdisplay == 720) || /* 720p */
1284
	    (mode->vdisplay == 1080)) /* 1080p */
1285
		return true;
1286
	else
1287
		return false;
1288
}
1289
 
1179 serge 1290
bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
2997 Serge 1291
				const struct drm_display_mode *mode,
1179 serge 1292
				struct drm_display_mode *adjusted_mode)
1123 serge 1293
{
1179 serge 1294
	struct drm_device *dev = crtc->dev;
1963 serge 1295
	struct radeon_device *rdev = dev->dev_private;
1179 serge 1296
	struct drm_encoder *encoder;
1123 serge 1297
		struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1179 serge 1298
	struct radeon_encoder *radeon_encoder;
1963 serge 1299
	struct drm_connector *connector;
1300
	struct radeon_connector *radeon_connector;
1179 serge 1301
	bool first = true;
1963 serge 1302
	u32 src_v = 1, dst_v = 1;
1303
	u32 src_h = 1, dst_h = 1;
1123 serge 1304
 
1963 serge 1305
	radeon_crtc->h_border = 0;
1306
	radeon_crtc->v_border = 0;
1307
 
1179 serge 1308
	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
1309
		if (encoder->crtc != crtc)
1310
			continue;
1963 serge 1311
		radeon_encoder = to_radeon_encoder(encoder);
1312
		connector = radeon_get_connector_for_encoder(encoder);
1313
		radeon_connector = to_radeon_connector(connector);
1314
 
1179 serge 1315
		if (first) {
1404 serge 1316
			/* set scaling */
1317
			if (radeon_encoder->rmx_type == RMX_OFF)
1318
				radeon_crtc->rmx_type = RMX_OFF;
1319
			else if (mode->hdisplay < radeon_encoder->native_mode.hdisplay ||
1320
				 mode->vdisplay < radeon_encoder->native_mode.vdisplay)
1179 serge 1321
			radeon_crtc->rmx_type = radeon_encoder->rmx_type;
1404 serge 1322
			else
1323
				radeon_crtc->rmx_type = RMX_OFF;
1324
			/* copy native mode */
1179 serge 1325
			memcpy(&radeon_crtc->native_mode,
1326
				&radeon_encoder->native_mode,
1268 serge 1327
				sizeof(struct drm_display_mode));
1963 serge 1328
			src_v = crtc->mode.vdisplay;
1329
			dst_v = radeon_crtc->native_mode.vdisplay;
1330
			src_h = crtc->mode.hdisplay;
1331
			dst_h = radeon_crtc->native_mode.hdisplay;
1332
 
1333
			/* fix up for overscan on hdmi */
1334
			if (ASIC_IS_AVIVO(rdev) &&
1335
			    (!(mode->flags & DRM_MODE_FLAG_INTERLACE)) &&
1336
			    ((radeon_encoder->underscan_type == UNDERSCAN_ON) ||
1337
			     ((radeon_encoder->underscan_type == UNDERSCAN_AUTO) &&
5078 serge 1338
			      drm_detect_hdmi_monitor(radeon_connector_edid(connector)) &&
1963 serge 1339
			      is_hdtv_mode(mode)))) {
1340
				if (radeon_encoder->underscan_hborder != 0)
1341
					radeon_crtc->h_border = radeon_encoder->underscan_hborder;
1342
				else
1343
				radeon_crtc->h_border = (mode->hdisplay >> 5) + 16;
1344
				if (radeon_encoder->underscan_vborder != 0)
1345
					radeon_crtc->v_border = radeon_encoder->underscan_vborder;
1346
				else
1347
				radeon_crtc->v_border = (mode->vdisplay >> 5) + 16;
1348
				radeon_crtc->rmx_type = RMX_FULL;
1349
				src_v = crtc->mode.vdisplay;
1350
				dst_v = crtc->mode.vdisplay - (radeon_crtc->v_border * 2);
1351
				src_h = crtc->mode.hdisplay;
1352
				dst_h = crtc->mode.hdisplay - (radeon_crtc->h_border * 2);
1353
			}
1179 serge 1354
			first = false;
1355
		} else {
1356
			if (radeon_crtc->rmx_type != radeon_encoder->rmx_type) {
1357
				/* WARNING: Right now this can't happen but
1358
				 * in the future we need to check that scaling
1963 serge 1359
				 * are consistent across different encoder
1179 serge 1360
				 * (ie all encoder can work with the same
1361
				 *  scaling).
1362
				 */
1963 serge 1363
				DRM_ERROR("Scaling not consistent across encoder.\n");
1179 serge 1364
				return false;
1365
			}
1123 serge 1366
		}
1367
	}
1179 serge 1368
	if (radeon_crtc->rmx_type != RMX_OFF) {
1221 serge 1369
        fixed20_12 a, b;
1963 serge 1370
		a.full = dfixed_const(src_v);
1371
		b.full = dfixed_const(dst_v);
1372
		radeon_crtc->vsc.full = dfixed_div(a, b);
1373
		a.full = dfixed_const(src_h);
1374
		b.full = dfixed_const(dst_h);
1375
		radeon_crtc->hsc.full = dfixed_div(a, b);
1123 serge 1376
	} else {
1963 serge 1377
		radeon_crtc->vsc.full = dfixed_const(1);
1378
		radeon_crtc->hsc.full = dfixed_const(1);
1123 serge 1379
	}
1179 serge 1380
	return true;
1123 serge 1381
}
1963 serge 1382
 
1383
/*
5078 serge 1384
 * Retrieve current video scanout position of crtc on a given gpu, and
1385
 * an optional accurate timestamp of when query happened.
1963 serge 1386
 *
1387
 * \param dev Device to query.
1388
 * \param crtc Crtc to query.
5078 serge 1389
 * \param flags Flags from caller (DRM_CALLED_FROM_VBLIRQ or 0).
1963 serge 1390
 * \param *vpos Location where vertical scanout position should be stored.
1391
 * \param *hpos Location where horizontal scanout position should go.
5078 serge 1392
 * \param *stime Target location for timestamp taken immediately before
1393
 *               scanout position query. Can be NULL to skip timestamp.
1394
 * \param *etime Target location for timestamp taken immediately after
1395
 *               scanout position query. Can be NULL to skip timestamp.
1963 serge 1396
 *
1397
 * Returns vpos as a positive number while in active scanout area.
1398
 * Returns vpos as a negative number inside vblank, counting the number
1399
 * of scanlines to go until end of vblank, e.g., -1 means "one scanline
1400
 * until start of active scanout / end of vblank."
1401
 *
1402
 * \return Flags, or'ed together as follows:
1403
 *
1404
 * DRM_SCANOUTPOS_VALID = Query successful.
1405
 * DRM_SCANOUTPOS_INVBL = Inside vblank.
1406
 * DRM_SCANOUTPOS_ACCURATE = Returned position is accurate. A lack of
1407
 * this flag means that returned position may be offset by a constant but
1408
 * unknown small number of scanlines wrt. real scanout position.
1409
 *
1410
 */
5078 serge 1411
int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int flags,
1412
			       int *vpos, int *hpos, void *stime, void *etime)
1963 serge 1413
{
1414
	u32 stat_crtc = 0, vbl = 0, position = 0;
1415
	int vbl_start, vbl_end, vtotal, ret = 0;
1416
	bool in_vbl = true;
1417
 
1418
	struct radeon_device *rdev = dev->dev_private;
1419
 
1420
	if (ASIC_IS_DCE4(rdev)) {
1421
		if (crtc == 0) {
1422
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
1423
				     EVERGREEN_CRTC0_REGISTER_OFFSET);
1424
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
1425
					  EVERGREEN_CRTC0_REGISTER_OFFSET);
1426
			ret |= DRM_SCANOUTPOS_VALID;
1427
		}
1428
		if (crtc == 1) {
1429
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
1430
				     EVERGREEN_CRTC1_REGISTER_OFFSET);
1431
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
1432
					  EVERGREEN_CRTC1_REGISTER_OFFSET);
1433
			ret |= DRM_SCANOUTPOS_VALID;
1434
		}
1435
		if (crtc == 2) {
1436
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
1437
				     EVERGREEN_CRTC2_REGISTER_OFFSET);
1438
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
1439
					  EVERGREEN_CRTC2_REGISTER_OFFSET);
1440
			ret |= DRM_SCANOUTPOS_VALID;
1441
		}
1442
		if (crtc == 3) {
1443
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
1444
				     EVERGREEN_CRTC3_REGISTER_OFFSET);
1445
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
1446
					  EVERGREEN_CRTC3_REGISTER_OFFSET);
1447
			ret |= DRM_SCANOUTPOS_VALID;
1448
		}
1449
		if (crtc == 4) {
1450
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
1451
				     EVERGREEN_CRTC4_REGISTER_OFFSET);
1452
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
1453
					  EVERGREEN_CRTC4_REGISTER_OFFSET);
1454
			ret |= DRM_SCANOUTPOS_VALID;
1455
		}
1456
		if (crtc == 5) {
1457
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
1458
				     EVERGREEN_CRTC5_REGISTER_OFFSET);
1459
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
1460
					  EVERGREEN_CRTC5_REGISTER_OFFSET);
1461
			ret |= DRM_SCANOUTPOS_VALID;
1462
		}
1463
	} else if (ASIC_IS_AVIVO(rdev)) {
1464
		if (crtc == 0) {
1465
			vbl = RREG32(AVIVO_D1CRTC_V_BLANK_START_END);
1466
			position = RREG32(AVIVO_D1CRTC_STATUS_POSITION);
1467
			ret |= DRM_SCANOUTPOS_VALID;
1468
		}
1469
		if (crtc == 1) {
1470
			vbl = RREG32(AVIVO_D2CRTC_V_BLANK_START_END);
1471
			position = RREG32(AVIVO_D2CRTC_STATUS_POSITION);
1472
			ret |= DRM_SCANOUTPOS_VALID;
1473
		}
1474
	} else {
1475
		/* Pre-AVIVO: Different encoding of scanout pos and vblank interval. */
1476
		if (crtc == 0) {
1477
			/* Assume vbl_end == 0, get vbl_start from
1478
			 * upper 16 bits.
1479
			 */
1480
			vbl = (RREG32(RADEON_CRTC_V_TOTAL_DISP) &
1481
				RADEON_CRTC_V_DISP) >> RADEON_CRTC_V_DISP_SHIFT;
1482
			/* Only retrieve vpos from upper 16 bits, set hpos == 0. */
1483
			position = (RREG32(RADEON_CRTC_VLINE_CRNT_VLINE) >> 16) & RADEON_CRTC_V_TOTAL;
1484
			stat_crtc = RREG32(RADEON_CRTC_STATUS);
1485
			if (!(stat_crtc & 1))
1486
				in_vbl = false;
1487
 
1488
			ret |= DRM_SCANOUTPOS_VALID;
1489
		}
1490
		if (crtc == 1) {
1491
			vbl = (RREG32(RADEON_CRTC2_V_TOTAL_DISP) &
1492
				RADEON_CRTC_V_DISP) >> RADEON_CRTC_V_DISP_SHIFT;
1493
			position = (RREG32(RADEON_CRTC2_VLINE_CRNT_VLINE) >> 16) & RADEON_CRTC_V_TOTAL;
1494
			stat_crtc = RREG32(RADEON_CRTC2_STATUS);
1495
			if (!(stat_crtc & 1))
1496
				in_vbl = false;
1497
 
1498
			ret |= DRM_SCANOUTPOS_VALID;
1499
		}
1500
	}
1501
 
1502
	/* Decode into vertical and horizontal scanout position. */
1503
	*vpos = position & 0x1fff;
1504
	*hpos = (position >> 16) & 0x1fff;
1505
 
1506
	/* Valid vblank area boundaries from gpu retrieved? */
1507
	if (vbl > 0) {
1508
		/* Yes: Decode. */
1509
		ret |= DRM_SCANOUTPOS_ACCURATE;
1510
		vbl_start = vbl & 0x1fff;
1511
		vbl_end = (vbl >> 16) & 0x1fff;
1512
	}
1513
	else {
1514
		/* No: Fake something reasonable which gives at least ok results. */
1515
		vbl_start = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vdisplay;
1516
		vbl_end = 0;
1517
	}
1518
 
1519
	/* Test scanout position against vblank region. */
1520
	if ((*vpos < vbl_start) && (*vpos >= vbl_end))
1521
		in_vbl = false;
1522
 
1523
	/* Check if inside vblank area and apply corrective offsets:
1524
	 * vpos will then be >=0 in video scanout area, but negative
1525
	 * within vblank area, counting down the number of lines until
1526
	 * start of scanout.
1527
	 */
1528
 
1529
	/* Inside "upper part" of vblank area? Apply corrective offset if so: */
1530
	if (in_vbl && (*vpos >= vbl_start)) {
1531
		vtotal = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vtotal;
1532
		*vpos = *vpos - vtotal;
1533
	}
1534
 
1535
	/* Correct for shifted end of vbl at vbl_end. */
1536
	*vpos = *vpos - vbl_end;
1537
 
1538
	/* In vblank? */
1539
	if (in_vbl)
1540
		ret |= DRM_SCANOUTPOS_INVBL;
1541
 
5078 serge 1542
	/* Is vpos outside nominal vblank area, but less than
1543
	 * 1/100 of a frame height away from start of vblank?
1544
	 * If so, assume this isn't a massively delayed vblank
1545
	 * interrupt, but a vblank interrupt that fired a few
1546
	 * microseconds before true start of vblank. Compensate
1547
	 * by adding a full frame duration to the final timestamp.
1548
	 * Happens, e.g., on ATI R500, R600.
1549
	 *
1550
	 * We only do this if DRM_CALLED_FROM_VBLIRQ.
1551
	 */
1552
	if ((flags & DRM_CALLED_FROM_VBLIRQ) && !in_vbl) {
1553
		vbl_start = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vdisplay;
1554
		vtotal = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vtotal;
1555
 
1556
		if (vbl_start - *vpos < vtotal / 100) {
1557
			*vpos -= vtotal;
1558
 
1559
			/* Signal this correction as "applied". */
1560
			ret |= 0x8;
1561
		}
1562
	}
1563
 
1963 serge 1564
	return ret;
1565
}