Subversion Repositories Kolibri OS

Rev

Rev 1630 | Rev 1986 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1630 Rev 1963
Line 26... Line 26...
26
#include "drmP.h"
26
#include "drmP.h"
27
#include "radeon_drm.h"
27
#include "radeon_drm.h"
28
#include "radeon.h"
28
#include "radeon.h"
Line 29... Line 29...
29
 
29
 
30
#include "atom.h"
30
#include "atom.h"
Line 31... Line 31...
31
//#include 
31
#include 
32
 
32
 
Line 33... Line 33...
33
#include "drm_crtc_helper.h"
33
#include "drm_crtc_helper.h"
Line 40... Line 40...
40
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
40
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
41
	struct drm_device *dev = crtc->dev;
41
	struct drm_device *dev = crtc->dev;
42
	struct radeon_device *rdev = dev->dev_private;
42
	struct radeon_device *rdev = dev->dev_private;
43
	int i;
43
	int i;
Line 44... Line 44...
44
 
44
 
45
	DRM_DEBUG("%d\n", radeon_crtc->crtc_id);
45
	DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id);
Line 46... Line 46...
46
	WREG32(AVIVO_DC_LUTA_CONTROL + radeon_crtc->crtc_offset, 0);
46
	WREG32(AVIVO_DC_LUTA_CONTROL + radeon_crtc->crtc_offset, 0);
47
 
47
 
48
	WREG32(AVIVO_DC_LUTA_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0);
48
	WREG32(AVIVO_DC_LUTA_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0);
Line 66... Line 66...
66
	}
66
	}
Line 67... Line 67...
67
 
67
 
68
	WREG32(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset, radeon_crtc->crtc_id);
68
	WREG32(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset, radeon_crtc->crtc_id);
Line 69... Line 69...
69
}
69
}
70
 
70
 
71
static void evergreen_crtc_load_lut(struct drm_crtc *crtc)
71
static void dce4_crtc_load_lut(struct drm_crtc *crtc)
72
{
72
{
73
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
73
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
74
	struct drm_device *dev = crtc->dev;
74
	struct drm_device *dev = crtc->dev;
Line 75... Line 75...
75
	struct radeon_device *rdev = dev->dev_private;
75
	struct radeon_device *rdev = dev->dev_private;
76
	int i;
76
	int i;
Line 77... Line 77...
77
 
77
 
78
	DRM_DEBUG("%d\n", radeon_crtc->crtc_id);
78
	DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id);
79
	WREG32(EVERGREEN_DC_LUT_CONTROL + radeon_crtc->crtc_offset, 0);
79
	WREG32(EVERGREEN_DC_LUT_CONTROL + radeon_crtc->crtc_offset, 0);
Line 80... Line 80...
80
 
80
 
81
	WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0);
81
	WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0);
82
	WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_GREEN + radeon_crtc->crtc_offset, 0);
82
	WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_GREEN + radeon_crtc->crtc_offset, 0);
Line 83... Line 83...
83
	WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_RED + radeon_crtc->crtc_offset, 0);
83
	WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_RED + radeon_crtc->crtc_offset, 0);
84
 
84
 
Line 85... Line 85...
85
	WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_BLUE + radeon_crtc->crtc_offset, 0xffff);
85
	WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_BLUE + radeon_crtc->crtc_offset, 0xffff);
86
	WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff);
86
	WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff);
87
	WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff);
87
	WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff);
88
 
88
 
89
	WREG32(EVERGREEN_DC_LUT_RW_MODE, radeon_crtc->crtc_id);
89
	WREG32(EVERGREEN_DC_LUT_RW_MODE + radeon_crtc->crtc_offset, 0);
90
	WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK, 0x00000007);
90
	WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK + radeon_crtc->crtc_offset, 0x00000007);
91
 
91
 
92
	WREG32(EVERGREEN_DC_LUT_RW_INDEX, 0);
92
	WREG32(EVERGREEN_DC_LUT_RW_INDEX + radeon_crtc->crtc_offset, 0);
Line -... Line 93...
-
 
93
	for (i = 0; i < 256; i++) {
-
 
94
		WREG32(EVERGREEN_DC_LUT_30_COLOR + radeon_crtc->crtc_offset,
-
 
95
		       (radeon_crtc->lut_r[i] << 20) |
-
 
96
		       (radeon_crtc->lut_g[i] << 10) |
-
 
97
		       (radeon_crtc->lut_b[i] << 0));
-
 
98
	}
-
 
99
}
-
 
100
 
-
 
101
static void dce5_crtc_load_lut(struct drm_crtc *crtc)
-
 
102
{
-
 
103
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
-
 
104
	struct drm_device *dev = crtc->dev;
-
 
105
	struct radeon_device *rdev = dev->dev_private;
-
 
106
	int i;
-
 
107
 
-
 
108
	DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id);
-
 
109
 
-
 
110
	WREG32(NI_INPUT_CSC_CONTROL + radeon_crtc->crtc_offset,
-
 
111
	       (NI_INPUT_CSC_GRPH_MODE(NI_INPUT_CSC_BYPASS) |
-
 
112
		NI_INPUT_CSC_OVL_MODE(NI_INPUT_CSC_BYPASS)));
-
 
113
	WREG32(NI_PRESCALE_GRPH_CONTROL + radeon_crtc->crtc_offset,
-
 
114
	       NI_GRPH_PRESCALE_BYPASS);
-
 
115
	WREG32(NI_PRESCALE_OVL_CONTROL + radeon_crtc->crtc_offset,
-
 
116
	       NI_OVL_PRESCALE_BYPASS);
-
 
117
	WREG32(NI_INPUT_GAMMA_CONTROL + radeon_crtc->crtc_offset,
-
 
118
	       (NI_GRPH_INPUT_GAMMA_MODE(NI_INPUT_GAMMA_USE_LUT) |
-
 
119
		NI_OVL_INPUT_GAMMA_MODE(NI_INPUT_GAMMA_USE_LUT)));
-
 
120
 
-
 
121
	WREG32(EVERGREEN_DC_LUT_CONTROL + radeon_crtc->crtc_offset, 0);
-
 
122
 
-
 
123
	WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0);
-
 
124
	WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_GREEN + radeon_crtc->crtc_offset, 0);
-
 
125
	WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_RED + radeon_crtc->crtc_offset, 0);
-
 
126
 
-
 
127
	WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_BLUE + radeon_crtc->crtc_offset, 0xffff);
-
 
128
	WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff);
-
 
129
	WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff);
-
 
130
 
-
 
131
	WREG32(EVERGREEN_DC_LUT_RW_MODE + radeon_crtc->crtc_offset, 0);
-
 
132
	WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK + radeon_crtc->crtc_offset, 0x00000007);
-
 
133
 
-
 
134
	WREG32(EVERGREEN_DC_LUT_RW_INDEX + radeon_crtc->crtc_offset, 0);
-
 
135
	for (i = 0; i < 256; i++) {
-
 
136
		WREG32(EVERGREEN_DC_LUT_30_COLOR + radeon_crtc->crtc_offset,
-
 
137
		       (radeon_crtc->lut_r[i] << 20) |
-
 
138
		       (radeon_crtc->lut_g[i] << 10) |
-
 
139
		       (radeon_crtc->lut_b[i] << 0));
-
 
140
	}
-
 
141
 
-
 
142
	WREG32(NI_DEGAMMA_CONTROL + radeon_crtc->crtc_offset,
-
 
143
	       (NI_GRPH_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) |
-
 
144
		NI_OVL_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) |
-
 
145
		NI_ICON_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) |
-
 
146
		NI_CURSOR_DEGAMMA_MODE(NI_DEGAMMA_BYPASS)));
-
 
147
	WREG32(NI_GAMUT_REMAP_CONTROL + radeon_crtc->crtc_offset,
-
 
148
	       (NI_GRPH_GAMUT_REMAP_MODE(NI_GAMUT_REMAP_BYPASS) |
-
 
149
		NI_OVL_GAMUT_REMAP_MODE(NI_GAMUT_REMAP_BYPASS)));
-
 
150
	WREG32(NI_REGAMMA_CONTROL + radeon_crtc->crtc_offset,
-
 
151
	       (NI_GRPH_REGAMMA_MODE(NI_REGAMMA_BYPASS) |
-
 
152
		NI_OVL_REGAMMA_MODE(NI_REGAMMA_BYPASS)));
93
	for (i = 0; i < 256; i++) {
153
	WREG32(NI_OUTPUT_CSC_CONTROL + radeon_crtc->crtc_offset,
94
		WREG32(EVERGREEN_DC_LUT_30_COLOR,
154
	       (NI_OUTPUT_CSC_GRPH_MODE(NI_OUTPUT_CSC_BYPASS) |
95
		       (radeon_crtc->lut_r[i] << 20) |
155
		NI_OUTPUT_CSC_OVL_MODE(NI_OUTPUT_CSC_BYPASS)));
96
		       (radeon_crtc->lut_g[i] << 10) |
156
	/* XXX match this to the depth of the crtc fmt block, move to modeset? */
97
		       (radeon_crtc->lut_b[i] << 0));
157
	WREG32(0x6940 + radeon_crtc->crtc_offset, 0);
Line 128... Line 188...
128
	struct radeon_device *rdev = dev->dev_private;
188
	struct radeon_device *rdev = dev->dev_private;
Line 129... Line 189...
129
 
189
 
130
	if (!crtc->enabled)
190
	if (!crtc->enabled)
Line 131... Line 191...
131
		return;
191
		return;
132
 
192
 
-
 
193
	if (ASIC_IS_DCE5(rdev))
-
 
194
		dce5_crtc_load_lut(crtc);
133
	if (ASIC_IS_DCE4(rdev))
195
	else if (ASIC_IS_DCE4(rdev))
134
		evergreen_crtc_load_lut(crtc);
196
		dce4_crtc_load_lut(crtc);
135
	else if (ASIC_IS_AVIVO(rdev))
197
	else if (ASIC_IS_AVIVO(rdev))
136
		avivo_crtc_load_lut(crtc);
198
		avivo_crtc_load_lut(crtc);
137
	else
199
	else
Line 159... Line 221...
159
	*green = radeon_crtc->lut_g[regno] << 6;
221
	*green = radeon_crtc->lut_g[regno] << 6;
160
	*blue = radeon_crtc->lut_b[regno] << 6;
222
	*blue = radeon_crtc->lut_b[regno] << 6;
161
}
223
}
Line 162... Line 224...
162
 
224
 
163
static void radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
225
static void radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
164
				  u16 *blue, uint32_t size)
226
				  u16 *blue, uint32_t start, uint32_t size)
165
{
227
{
166
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
-
 
167
	int i;
-
 
168
 
228
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
169
	if (size != 256) {
-
 
170
		return;
-
 
Line 171... Line 229...
171
	}
229
	int end = (start + size > 256) ? 256 : start + size, i;
172
 
230
 
173
	/* userspace palettes are always correct as is */
231
	/* userspace palettes are always correct as is */
174
		for (i = 0; i < 256; i++) {
232
	for (i = start; i < end; i++) {
175
			radeon_crtc->lut_r[i] = red[i] >> 6;
233
			radeon_crtc->lut_r[i] = red[i] >> 6;
176
			radeon_crtc->lut_g[i] = green[i] >> 6;
234
			radeon_crtc->lut_g[i] = green[i] >> 6;
177
			radeon_crtc->lut_b[i] = blue[i] >> 6;
235
			radeon_crtc->lut_b[i] = blue[i] >> 6;
Line 191... Line 249...
191
    .cursor_set = NULL,
249
    .cursor_set = NULL,
192
    .cursor_move = NULL,
250
    .cursor_move = NULL,
193
	.gamma_set = radeon_crtc_gamma_set,
251
	.gamma_set = radeon_crtc_gamma_set,
194
	.set_config = drm_crtc_helper_set_config,
252
	.set_config = drm_crtc_helper_set_config,
195
	.destroy = radeon_crtc_destroy,
253
	.destroy = radeon_crtc_destroy,
-
 
254
	.page_flip = NULL,
196
};
255
};
Line 197... Line 256...
197
 
256
 
198
static void radeon_crtc_init(struct drm_device *dev, int index)
257
static void radeon_crtc_init(struct drm_device *dev, int index)
199
{
258
{
Line 227... Line 286...
227
		radeon_atombios_init_crtc(dev, radeon_crtc);
286
		radeon_atombios_init_crtc(dev, radeon_crtc);
228
	else
287
	else
229
		radeon_legacy_init_crtc(dev, radeon_crtc);
288
		radeon_legacy_init_crtc(dev, radeon_crtc);
230
}
289
}
Line 231... Line 290...
231
 
290
 
232
static const char *encoder_names[34] = {
291
static const char *encoder_names[36] = {
233
	"NONE",
292
	"NONE",
234
	"INTERNAL_LVDS",
293
	"INTERNAL_LVDS",
235
	"INTERNAL_TMDS1",
294
	"INTERNAL_TMDS1",
236
	"INTERNAL_TMDS2",
295
	"INTERNAL_TMDS2",
Line 262... Line 321...
262
	"DP_DP501",
321
	"DP_DP501",
263
	"INTERNAL_UNIPHY",
322
	"INTERNAL_UNIPHY",
264
	"INTERNAL_KLDSCP_LVTMA",
323
	"INTERNAL_KLDSCP_LVTMA",
265
	"INTERNAL_UNIPHY1",
324
	"INTERNAL_UNIPHY1",
266
	"INTERNAL_UNIPHY2",
325
	"INTERNAL_UNIPHY2",
-
 
326
	"NUTMEG",
-
 
327
	"TRAVIS",
267
};
328
};
Line 268... Line 329...
268
 
329
 
269
static const char *connector_names[15] = {
330
static const char *connector_names[15] = {
270
	"Unknown",
331
	"Unknown",
Line 282... Line 343...
282
	"HDMI-B",
343
	"HDMI-B",
283
	"TV",
344
	"TV",
284
	"eDP",
345
	"eDP",
285
};
346
};
Line 286... Line 347...
286
 
347
 
287
static const char *hpd_names[7] = {
-
 
288
	"NONE",
348
static const char *hpd_names[6] = {
289
	"HPD1",
349
	"HPD1",
290
	"HPD2",
350
	"HPD2",
291
	"HPD3",
351
	"HPD3",
292
	"HPD4",
352
	"HPD4",
Line 318... Line 378...
318
				 radeon_connector->ddc_bus->rec.a_data_reg,
378
				 radeon_connector->ddc_bus->rec.a_data_reg,
319
				 radeon_connector->ddc_bus->rec.en_clk_reg,
379
				 radeon_connector->ddc_bus->rec.en_clk_reg,
320
				 radeon_connector->ddc_bus->rec.en_data_reg,
380
				 radeon_connector->ddc_bus->rec.en_data_reg,
321
				 radeon_connector->ddc_bus->rec.y_clk_reg,
381
				 radeon_connector->ddc_bus->rec.y_clk_reg,
322
				 radeon_connector->ddc_bus->rec.y_data_reg);
382
				 radeon_connector->ddc_bus->rec.y_data_reg);
-
 
383
			if (radeon_connector->router.ddc_valid)
-
 
384
				DRM_INFO("  DDC Router 0x%x/0x%x\n",
-
 
385
					 radeon_connector->router.ddc_mux_control_pin,
-
 
386
					 radeon_connector->router.ddc_mux_state);
-
 
387
			if (radeon_connector->router.cd_valid)
-
 
388
				DRM_INFO("  Clock/Data Router 0x%x/0x%x\n",
-
 
389
					 radeon_connector->router.cd_mux_control_pin,
-
 
390
					 radeon_connector->router.cd_mux_state);
323
		} else {
391
		} else {
324
			if (connector->connector_type == DRM_MODE_CONNECTOR_VGA ||
392
			if (connector->connector_type == DRM_MODE_CONNECTOR_VGA ||
325
			    connector->connector_type == DRM_MODE_CONNECTOR_DVII ||
393
			    connector->connector_type == DRM_MODE_CONNECTOR_DVII ||
326
			    connector->connector_type == DRM_MODE_CONNECTOR_DVID ||
394
			    connector->connector_type == DRM_MODE_CONNECTOR_DVID ||
327
			    connector->connector_type == DRM_MODE_CONNECTOR_DVIA ||
395
			    connector->connector_type == DRM_MODE_CONNECTOR_DVIA ||
Line 348... Line 416...
348
					DRM_INFO("    DFP3: %s\n", encoder_names[radeon_encoder->encoder_id]);
416
					DRM_INFO("    DFP3: %s\n", encoder_names[radeon_encoder->encoder_id]);
349
				if (devices & ATOM_DEVICE_DFP4_SUPPORT)
417
				if (devices & ATOM_DEVICE_DFP4_SUPPORT)
350
					DRM_INFO("    DFP4: %s\n", encoder_names[radeon_encoder->encoder_id]);
418
					DRM_INFO("    DFP4: %s\n", encoder_names[radeon_encoder->encoder_id]);
351
				if (devices & ATOM_DEVICE_DFP5_SUPPORT)
419
				if (devices & ATOM_DEVICE_DFP5_SUPPORT)
352
					DRM_INFO("    DFP5: %s\n", encoder_names[radeon_encoder->encoder_id]);
420
					DRM_INFO("    DFP5: %s\n", encoder_names[radeon_encoder->encoder_id]);
-
 
421
				if (devices & ATOM_DEVICE_DFP6_SUPPORT)
-
 
422
					DRM_INFO("    DFP6: %s\n", encoder_names[radeon_encoder->encoder_id]);
353
				if (devices & ATOM_DEVICE_TV1_SUPPORT)
423
				if (devices & ATOM_DEVICE_TV1_SUPPORT)
354
					DRM_INFO("    TV1: %s\n", encoder_names[radeon_encoder->encoder_id]);
424
					DRM_INFO("    TV1: %s\n", encoder_names[radeon_encoder->encoder_id]);
355
				if (devices & ATOM_DEVICE_CV_SUPPORT)
425
				if (devices & ATOM_DEVICE_CV_SUPPORT)
356
					DRM_INFO("    CV: %s\n", encoder_names[radeon_encoder->encoder_id]);
426
					DRM_INFO("    CV: %s\n", encoder_names[radeon_encoder->encoder_id]);
357
			}
427
			}
Line 366... Line 436...
366
	struct drm_connector *drm_connector;
436
	struct drm_connector *drm_connector;
367
	bool ret = false;
437
	bool ret = false;
Line 368... Line 438...
368
 
438
 
369
	if (rdev->bios) {
439
	if (rdev->bios) {
370
		if (rdev->is_atom_bios) {
-
 
371
			if (rdev->family >= CHIP_R600)
-
 
372
				ret = radeon_get_atom_connector_info_from_object_table(dev);
-
 
373
			else
440
		if (rdev->is_atom_bios) {
-
 
441
			ret = radeon_get_atom_connector_info_from_supported_devices_table(dev);
-
 
442
			if (ret == false)
374
				ret = radeon_get_atom_connector_info_from_supported_devices_table(dev);
443
				ret = radeon_get_atom_connector_info_from_object_table(dev);
375
		} else {
444
		} else {
376
			ret = radeon_get_legacy_connector_info_from_bios(dev);
445
			ret = radeon_get_legacy_connector_info_from_bios(dev);
377
			if (ret == false)
446
			if (ret == false)
378
				ret = radeon_get_legacy_connector_info_from_table(dev);
447
				ret = radeon_get_legacy_connector_info_from_table(dev);
Line 382... Line 451...
382
			ret = radeon_get_legacy_connector_info_from_table(dev);
451
			ret = radeon_get_legacy_connector_info_from_table(dev);
383
	}
452
	}
384
	if (ret) {
453
	if (ret) {
385
		radeon_setup_encoder_clones(dev);
454
		radeon_setup_encoder_clones(dev);
386
		radeon_print_display_setup(dev);
455
		radeon_print_display_setup(dev);
-
 
456
 
387
		list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head)
457
//       list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head)
388
			radeon_ddc_dump(drm_connector);
458
//           radeon_ddc_dump(drm_connector);
389
	}
459
	}
Line 390... Line 460...
390
 
460
 
391
	return ret;
461
	return ret;
Line 395... Line 465...
395
{
465
{
396
	struct drm_device *dev = radeon_connector->base.dev;
466
	struct drm_device *dev = radeon_connector->base.dev;
397
	struct radeon_device *rdev = dev->dev_private;
467
	struct radeon_device *rdev = dev->dev_private;
398
	int ret = 0;
468
	int ret = 0;
Line -... Line 469...
-
 
469
 
-
 
470
	/* on hw with routers, select right port */
-
 
471
	if (radeon_connector->router.ddc_valid)
-
 
472
		radeon_router_select_ddc_port(radeon_connector);
399
 
473
 
400
	if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
474
	if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
401
	    (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) {
475
	    (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) {
402
		struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
476
		struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
403
		if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT ||
477
		if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT ||
Line 407... Line 481...
407
	if (!radeon_connector->ddc_bus)
481
	if (!radeon_connector->ddc_bus)
408
		return -1;
482
		return -1;
409
	if (!radeon_connector->edid) {
483
	if (!radeon_connector->edid) {
410
		radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
484
		radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
411
	}
485
	}
-
 
486
 
-
 
487
	if (!radeon_connector->edid) {
-
 
488
		if (rdev->is_atom_bios) {
-
 
489
			/* some laptops provide a hardcoded edid in rom for LCDs */
-
 
490
			if (((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_LVDS) ||
-
 
491
			     (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)))
-
 
492
				radeon_connector->edid = radeon_bios_get_hardcoded_edid(rdev);
-
 
493
		} else
412
	/* some servers provide a hardcoded edid in rom for KVMs */
494
	/* some servers provide a hardcoded edid in rom for KVMs */
413
	if (!radeon_connector->edid)
-
 
414
		radeon_connector->edid = radeon_combios_get_hardcoded_edid(rdev);
495
			radeon_connector->edid = radeon_bios_get_hardcoded_edid(rdev);
-
 
496
	}
415
	if (radeon_connector->edid) {
497
	if (radeon_connector->edid) {
416
		drm_mode_connector_update_edid_property(&radeon_connector->base, radeon_connector->edid);
498
		drm_mode_connector_update_edid_property(&radeon_connector->base, radeon_connector->edid);
417
		ret = drm_add_edid_modes(&radeon_connector->base, radeon_connector->edid);
499
		ret = drm_add_edid_modes(&radeon_connector->base, radeon_connector->edid);
418
		return ret;
500
		return ret;
419
	}
501
	}
Line 425... Line 507...
425
{
507
{
426
	struct edid *edid;
508
	struct edid *edid;
427
	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
509
	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
428
	int ret = 0;
510
	int ret = 0;
Line -... Line 511...
-
 
511
 
-
 
512
	/* on hw with routers, select right port */
-
 
513
	if (radeon_connector->router.ddc_valid)
-
 
514
		radeon_router_select_ddc_port(radeon_connector);
429
 
515
 
430
	if (!radeon_connector->ddc_bus)
516
	if (!radeon_connector->ddc_bus)
431
		return -1;
517
		return -1;
432
	edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter);
518
	edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter);
433
	if (edid) {
519
	if (edid) {
434
		kfree(edid);
520
		kfree(edid);
435
	}
521
	}
436
	return ret;
522
	return ret;
Line -... Line 523...
-
 
523
}
-
 
524
 
-
 
525
/* avivo */
-
 
526
static void avivo_get_fb_div(struct radeon_pll *pll,
-
 
527
			     u32 target_clock,
-
 
528
			     u32 post_div,
-
 
529
			     u32 ref_div,
-
 
530
			     u32 *fb_div,
-
 
531
			     u32 *frac_fb_div)
-
 
532
{
-
 
533
	u32 tmp = post_div * ref_div;
-
 
534
 
-
 
535
	tmp *= target_clock;
-
 
536
	*fb_div = tmp / pll->reference_freq;
-
 
537
	*frac_fb_div = tmp % pll->reference_freq;
-
 
538
 
-
 
539
        if (*fb_div > pll->max_feedback_div)
-
 
540
		*fb_div = pll->max_feedback_div;
-
 
541
        else if (*fb_div < pll->min_feedback_div)
-
 
542
                *fb_div = pll->min_feedback_div;
-
 
543
}
-
 
544
 
-
 
545
static u32 avivo_get_post_div(struct radeon_pll *pll,
-
 
546
			      u32 target_clock)
-
 
547
{
-
 
548
	u32 vco, post_div, tmp;
-
 
549
 
-
 
550
	if (pll->flags & RADEON_PLL_USE_POST_DIV)
-
 
551
		return pll->post_div;
-
 
552
 
-
 
553
	if (pll->flags & RADEON_PLL_PREFER_MINM_OVER_MAXP) {
-
 
554
		if (pll->flags & RADEON_PLL_IS_LCD)
-
 
555
			vco = pll->lcd_pll_out_min;
-
 
556
		else
-
 
557
			vco = pll->pll_out_min;
-
 
558
	} else {
-
 
559
		if (pll->flags & RADEON_PLL_IS_LCD)
-
 
560
			vco = pll->lcd_pll_out_max;
-
 
561
		else
-
 
562
			vco = pll->pll_out_max;
-
 
563
	}
-
 
564
 
-
 
565
	post_div = vco / target_clock;
-
 
566
	tmp = vco % target_clock;
-
 
567
 
-
 
568
	if (pll->flags & RADEON_PLL_PREFER_MINM_OVER_MAXP) {
-
 
569
		if (tmp)
-
 
570
			post_div++;
-
 
571
	} else {
-
 
572
		if (!tmp)
-
 
573
			post_div--;
-
 
574
	}
-
 
575
 
-
 
576
	if (post_div > pll->max_post_div)
-
 
577
		post_div = pll->max_post_div;
-
 
578
	else if (post_div < pll->min_post_div)
-
 
579
		post_div = pll->min_post_div;
-
 
580
 
-
 
581
	return post_div;
-
 
582
}
-
 
583
 
-
 
584
#define MAX_TOLERANCE 10
-
 
585
 
-
 
586
void radeon_compute_pll_avivo(struct radeon_pll *pll,
-
 
587
			      u32 freq,
-
 
588
			      u32 *dot_clock_p,
-
 
589
			      u32 *fb_div_p,
-
 
590
			      u32 *frac_fb_div_p,
-
 
591
			      u32 *ref_div_p,
-
 
592
			      u32 *post_div_p)
-
 
593
{
-
 
594
	u32 target_clock = freq / 10;
-
 
595
	u32 post_div = avivo_get_post_div(pll, target_clock);
-
 
596
	u32 ref_div = pll->min_ref_div;
-
 
597
	u32 fb_div = 0, frac_fb_div = 0, tmp;
-
 
598
 
-
 
599
	if (pll->flags & RADEON_PLL_USE_REF_DIV)
-
 
600
		ref_div = pll->reference_div;
-
 
601
 
-
 
602
	if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) {
-
 
603
		avivo_get_fb_div(pll, target_clock, post_div, ref_div, &fb_div, &frac_fb_div);
-
 
604
		frac_fb_div = (100 * frac_fb_div) / pll->reference_freq;
-
 
605
		if (frac_fb_div >= 5) {
-
 
606
			frac_fb_div -= 5;
-
 
607
			frac_fb_div = frac_fb_div / 10;
-
 
608
			frac_fb_div++;
-
 
609
		}
-
 
610
		if (frac_fb_div >= 10) {
-
 
611
			fb_div++;
-
 
612
			frac_fb_div = 0;
-
 
613
		}
-
 
614
	} else {
-
 
615
		while (ref_div <= pll->max_ref_div) {
-
 
616
			avivo_get_fb_div(pll, target_clock, post_div, ref_div,
-
 
617
					 &fb_div, &frac_fb_div);
-
 
618
			if (frac_fb_div >= (pll->reference_freq / 2))
-
 
619
				fb_div++;
-
 
620
			frac_fb_div = 0;
-
 
621
			tmp = (pll->reference_freq * fb_div) / (post_div * ref_div);
-
 
622
			tmp = (tmp * 10000) / target_clock;
-
 
623
 
-
 
624
			if (tmp > (10000 + MAX_TOLERANCE))
-
 
625
				ref_div++;
-
 
626
			else if (tmp >= (10000 - MAX_TOLERANCE))
-
 
627
				break;
-
 
628
			else
-
 
629
				ref_div++;
-
 
630
		}
-
 
631
	}
-
 
632
 
-
 
633
	*dot_clock_p = ((pll->reference_freq * fb_div * 10) + (pll->reference_freq * frac_fb_div)) /
-
 
634
		(ref_div * post_div * 10);
-
 
635
	*fb_div_p = fb_div;
-
 
636
	*frac_fb_div_p = frac_fb_div;
-
 
637
	*ref_div_p = ref_div;
-
 
638
	*post_div_p = post_div;
-
 
639
	DRM_DEBUG_KMS("%d, pll dividers - fb: %d.%d ref: %d, post %d\n",
-
 
640
		      *dot_clock_p, fb_div, frac_fb_div, ref_div, post_div);
-
 
641
}
437
}
642
 
438
 
643
/* pre-avivo */
439
static inline uint32_t radeon_div(uint64_t n, uint32_t d)
644
static inline uint32_t radeon_div(uint64_t n, uint32_t d)
Line 440... Line 645...
440
{
645
{
Line 441... Line 646...
441
	uint64_t mod;
646
	uint64_t mod;
442
 
647
 
443
	n += d / 2;
648
	n += d / 2;
Line 444... Line 649...
444
 
649
 
445
	mod = do_div(n, d);
650
	mod = do_div(n, d);
446
	return n;
651
	return n;
447
}
652
}
448
 
653
 
449
static void radeon_compute_pll_legacy(struct radeon_pll *pll,
654
void radeon_compute_pll_legacy(struct radeon_pll *pll,
Line 467... Line 672...
467
	uint32_t best_frac_feedback_div = 0;
672
	uint32_t best_frac_feedback_div = 0;
468
	uint32_t best_freq = -1;
673
	uint32_t best_freq = -1;
469
	uint32_t best_error = 0xffffffff;
674
	uint32_t best_error = 0xffffffff;
470
	uint32_t best_vco_diff = 1;
675
	uint32_t best_vco_diff = 1;
471
	uint32_t post_div;
676
	uint32_t post_div;
-
 
677
	u32 pll_out_min, pll_out_max;
Line 472... Line 678...
472
 
678
 
473
	DRM_DEBUG("PLL freq %llu %u %u\n", freq, pll->min_ref_div, pll->max_ref_div);
679
	DRM_DEBUG_KMS("PLL freq %llu %u %u\n", freq, pll->min_ref_div, pll->max_ref_div);
Line -... Line 680...
-
 
680
	freq = freq * 1000;
-
 
681
 
-
 
682
	if (pll->flags & RADEON_PLL_IS_LCD) {
-
 
683
		pll_out_min = pll->lcd_pll_out_min;
-
 
684
		pll_out_max = pll->lcd_pll_out_max;
-
 
685
	} else {
-
 
686
		pll_out_min = pll->pll_out_min;
-
 
687
		pll_out_max = pll->pll_out_max;
-
 
688
	}
-
 
689
 
-
 
690
	if (pll_out_min > 64800)
474
	freq = freq * 1000;
691
		pll_out_min = 64800;
475
 
692
 
476
	if (pll->flags & RADEON_PLL_USE_REF_DIV)
693
	if (pll->flags & RADEON_PLL_USE_REF_DIV)
477
		min_ref_div = max_ref_div = pll->reference_div;
694
		min_ref_div = max_ref_div = pll->reference_div;
478
	else {
695
	else {
Line 494... Line 711...
494
	if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) {
711
	if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) {
495
		min_fractional_feed_div = pll->min_frac_feedback_div;
712
		min_fractional_feed_div = pll->min_frac_feedback_div;
496
		max_fractional_feed_div = pll->max_frac_feedback_div;
713
		max_fractional_feed_div = pll->max_frac_feedback_div;
497
	}
714
	}
Line 498... Line 715...
498
 
715
 
499
	for (post_div = min_post_div; post_div <= max_post_div; ++post_div) {
716
	for (post_div = max_post_div; post_div >= min_post_div; --post_div) {
Line 500... Line 717...
500
		uint32_t ref_div;
717
		uint32_t ref_div;
501
 
718
 
Line 534... Line 751...
534
				feedback_div = (min_feed_div + max_feed_div) / 2;
751
				feedback_div = (min_feed_div + max_feed_div) / 2;
Line 535... Line 752...
535
 
752
 
536
				tmp = (uint64_t)pll->reference_freq * feedback_div;
753
				tmp = (uint64_t)pll->reference_freq * feedback_div;
Line 537... Line 754...
537
				vco = radeon_div(tmp, ref_div);
754
				vco = radeon_div(tmp, ref_div);
538
 
755
 
539
				if (vco < pll->pll_out_min) {
756
				if (vco < pll_out_min) {
540
					min_feed_div = feedback_div + 1;
757
					min_feed_div = feedback_div + 1;
541
					continue;
758
					continue;
542
				} else if (vco > pll->pll_out_max) {
759
				} else if (vco > pll_out_max) {
543
					max_feed_div = feedback_div;
760
					max_feed_div = feedback_div;
Line 544... Line 761...
544
					continue;
761
					continue;
Line 549... Line 766...
549
					tmp = (uint64_t)pll->reference_freq * 10000 * feedback_div;
766
					tmp = (uint64_t)pll->reference_freq * 10000 * feedback_div;
550
					tmp += (uint64_t)pll->reference_freq * 1000 * frac_feedback_div;
767
					tmp += (uint64_t)pll->reference_freq * 1000 * frac_feedback_div;
551
					current_freq = radeon_div(tmp, ref_div * post_div);
768
					current_freq = radeon_div(tmp, ref_div * post_div);
Line 552... Line 769...
552
 
769
 
-
 
770
					if (pll->flags & RADEON_PLL_PREFER_CLOSEST_LOWER) {
-
 
771
						if (freq < current_freq)
-
 
772
							error = 0xffffffff;
553
					if (pll->flags & RADEON_PLL_PREFER_CLOSEST_LOWER) {
773
						else
554
						error = freq - current_freq;
-
 
555
						error = error < 0 ? 0xffffffff : error;
774
						error = freq - current_freq;
556
					} else
775
					} else
557
					error = abs(current_freq - freq);
776
					error = abs(current_freq - freq);
Line 558... Line 777...
558
					vco_diff = abs(vco - best_vco);
777
					vco_diff = abs(vco - best_vco);
559
 
778
 
560
					if ((best_vco == 0 && error < best_error) ||
779
					if ((best_vco == 0 && error < best_error) ||
561
					    (best_vco != 0 &&
780
					    (best_vco != 0 &&
562
					     (error < best_error - 100 ||
781
					     ((best_error > 100 && error < best_error - 100) ||
563
					      (abs(error - best_error) < 100 && vco_diff < best_vco_diff)))) {
782
					      (abs(error - best_error) < 100 && vco_diff < best_vco_diff)))) {
564
						best_post_div = post_div;
783
						best_post_div = post_div;
565
						best_ref_div = ref_div;
784
						best_ref_div = ref_div;
Line 608... Line 827...
608
	*dot_clock_p = best_freq / 10000;
827
	*dot_clock_p = best_freq / 10000;
609
	*fb_div_p = best_feedback_div;
828
	*fb_div_p = best_feedback_div;
610
	*frac_fb_div_p = best_frac_feedback_div;
829
	*frac_fb_div_p = best_frac_feedback_div;
611
	*ref_div_p = best_ref_div;
830
	*ref_div_p = best_ref_div;
612
	*post_div_p = best_post_div;
831
	*post_div_p = best_post_div;
613
}
-
 
614
 
-
 
615
static bool
-
 
616
calc_fb_div(struct radeon_pll *pll,
832
	DRM_DEBUG_KMS("%lld %d, pll dividers - fb: %d.%d ref: %d, post %d\n",
617
	    uint32_t freq,
833
		      (long long)freq,
618
            uint32_t post_div,
-
 
619
            uint32_t ref_div,
-
 
620
            uint32_t *fb_div,
-
 
621
            uint32_t *fb_div_frac)
-
 
622
{
-
 
623
	fixed20_12 feedback_divider, a, b;
-
 
624
	u32 vco_freq;
-
 
625
 
-
 
626
	vco_freq = freq * post_div;
-
 
627
	/* feedback_divider = vco_freq * ref_div / pll->reference_freq; */
-
 
628
	a.full = rfixed_const(pll->reference_freq);
-
 
629
	feedback_divider.full = rfixed_const(vco_freq);
-
 
630
	feedback_divider.full = rfixed_div(feedback_divider, a);
-
 
631
	a.full = rfixed_const(ref_div);
-
 
632
	feedback_divider.full = rfixed_mul(feedback_divider, a);
-
 
633
 
-
 
634
	if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) {
-
 
635
		/* feedback_divider = floor((feedback_divider * 10.0) + 0.5) * 0.1; */
-
 
636
		a.full = rfixed_const(10);
-
 
637
		feedback_divider.full = rfixed_mul(feedback_divider, a);
-
 
638
		feedback_divider.full += rfixed_const_half(0);
-
 
639
		feedback_divider.full = rfixed_floor(feedback_divider);
-
 
640
		feedback_divider.full = rfixed_div(feedback_divider, a);
-
 
641
 
-
 
642
		/* *fb_div = floor(feedback_divider); */
-
 
643
		a.full = rfixed_floor(feedback_divider);
-
 
644
		*fb_div = rfixed_trunc(a);
-
 
645
		/* *fb_div_frac = fmod(feedback_divider, 1.0) * 10.0; */
834
		      best_freq / 1000, best_feedback_div, best_frac_feedback_div,
646
		a.full = rfixed_const(10);
835
		      best_ref_div, best_post_div);
647
		b.full = rfixed_mul(feedback_divider, a);
-
 
648
 
-
 
649
		feedback_divider.full = rfixed_floor(feedback_divider);
-
 
650
		feedback_divider.full = rfixed_mul(feedback_divider, a);
-
 
651
		feedback_divider.full = b.full - feedback_divider.full;
-
 
652
		*fb_div_frac = rfixed_trunc(feedback_divider);
-
 
653
	} else {
-
 
654
		/* *fb_div = floor(feedback_divider + 0.5); */
-
 
655
		feedback_divider.full += rfixed_const_half(0);
-
 
656
		feedback_divider.full = rfixed_floor(feedback_divider);
-
 
657
 
-
 
658
		*fb_div = rfixed_trunc(feedback_divider);
-
 
659
		*fb_div_frac = 0;
-
 
660
	}
-
 
Line 661... Line -...
661
 
-
 
662
	if (((*fb_div) < pll->min_feedback_div) || ((*fb_div) > pll->max_feedback_div))
-
 
663
		return false;
-
 
664
	else
-
 
665
		return true;
-
 
666
}
-
 
667
 
-
 
668
static bool
-
 
669
calc_fb_ref_div(struct radeon_pll *pll,
-
 
670
		uint32_t freq,
-
 
671
		uint32_t post_div,
-
 
672
		uint32_t *fb_div,
-
 
673
                uint32_t *fb_div_frac,
-
 
674
                uint32_t *ref_div)
-
 
675
{
-
 
676
	fixed20_12 ffreq, max_error, error, pll_out, a;
-
 
677
	u32 vco;
-
 
678
 
-
 
679
	ffreq.full = rfixed_const(freq);
-
 
680
	/* max_error = ffreq * 0.0025; */
-
 
681
	a.full = rfixed_const(400);
-
 
682
	max_error.full = rfixed_div(ffreq, a);
-
 
683
 
-
 
684
	for ((*ref_div) = pll->min_ref_div; (*ref_div) < pll->max_ref_div; ++(*ref_div)) {
-
 
685
		if (calc_fb_div(pll, freq, post_div, (*ref_div), fb_div, fb_div_frac)) {
-
 
686
			vco = pll->reference_freq * (((*fb_div) * 10) + (*fb_div_frac));
-
 
687
			vco = vco / ((*ref_div) * 10);
-
 
688
 
-
 
689
			if ((vco < pll->pll_out_min) || (vco > pll->pll_out_max))
-
 
690
				continue;
-
 
691
 
-
 
692
			/* pll_out = vco / post_div; */
-
 
693
			a.full = rfixed_const(post_div);
-
 
694
			pll_out.full = rfixed_const(vco);
-
 
695
			pll_out.full = rfixed_div(pll_out, a);
-
 
696
 
-
 
697
			if (pll_out.full >= ffreq.full) {
-
 
698
				error.full = pll_out.full - ffreq.full;
-
 
699
				if (error.full <= max_error.full)
-
 
700
					return true;
-
 
701
			}
-
 
702
		}
-
 
703
	}
-
 
704
	return false;
-
 
705
}
-
 
706
 
-
 
707
static void radeon_compute_pll_new(struct radeon_pll *pll,
-
 
708
			      uint64_t freq,
-
 
709
			      uint32_t *dot_clock_p,
-
 
710
			      uint32_t *fb_div_p,
-
 
711
			      uint32_t *frac_fb_div_p,
-
 
712
			      uint32_t *ref_div_p,
-
 
713
			      uint32_t *post_div_p)
-
 
714
{
-
 
715
	u32 fb_div = 0, fb_div_frac = 0, post_div = 0, ref_div = 0;
-
 
716
	u32 best_freq = 0, vco_frequency;
-
 
717
 
-
 
718
	/* freq = freq / 10; */
-
 
719
	do_div(freq, 10);
-
 
720
 
-
 
721
	if (pll->flags & RADEON_PLL_USE_POST_DIV) {
-
 
722
		post_div = pll->post_div;
-
 
723
		if ((post_div < pll->min_post_div) || (post_div > pll->max_post_div))
-
 
724
			goto done;
-
 
725
 
-
 
726
		vco_frequency = freq * post_div;
-
 
727
		if ((vco_frequency < pll->pll_out_min) || (vco_frequency > pll->pll_out_max))
-
 
728
			goto done;
-
 
729
 
-
 
730
		if (pll->flags & RADEON_PLL_USE_REF_DIV) {
-
 
731
			ref_div = pll->reference_div;
-
 
732
			if ((ref_div < pll->min_ref_div) || (ref_div > pll->max_ref_div))
-
 
733
				goto done;
-
 
734
			if (!calc_fb_div(pll, freq, post_div, ref_div, &fb_div, &fb_div_frac))
-
 
735
				goto done;
-
 
736
		}
-
 
737
	} else {
-
 
738
		for (post_div = pll->max_post_div; post_div >= pll->min_post_div; --post_div) {
-
 
739
			if (pll->flags & RADEON_PLL_LEGACY) {
-
 
740
				if ((post_div == 5) ||
-
 
741
				    (post_div == 7) ||
-
 
742
				    (post_div == 9) ||
-
 
743
				    (post_div == 10) ||
-
 
744
				    (post_div == 11))
-
 
745
					continue;
-
 
746
			}
-
 
747
 
-
 
748
			if ((pll->flags & RADEON_PLL_NO_ODD_POST_DIV) && (post_div & 1))
-
 
749
			continue;
-
 
750
 
-
 
751
			vco_frequency = freq * post_div;
-
 
752
			if ((vco_frequency < pll->pll_out_min) || (vco_frequency > pll->pll_out_max))
-
 
753
			continue;
-
 
754
			if (pll->flags & RADEON_PLL_USE_REF_DIV) {
-
 
755
				ref_div = pll->reference_div;
-
 
756
				if ((ref_div < pll->min_ref_div) || (ref_div > pll->max_ref_div))
-
 
757
					goto done;
-
 
758
				if (calc_fb_div(pll, freq, post_div, ref_div, &fb_div, &fb_div_frac))
-
 
759
					break;
-
 
760
			} else {
-
 
761
				if (calc_fb_ref_div(pll, freq, post_div, &fb_div, &fb_div_frac, &ref_div))
-
 
762
			break;
-
 
763
		}
-
 
764
	}
-
 
765
	}
-
 
766
 
-
 
767
	best_freq = pll->reference_freq * 10 * fb_div;
-
 
768
	best_freq += pll->reference_freq * fb_div_frac;
-
 
769
	best_freq = best_freq / (ref_div * post_div);
-
 
770
 
-
 
771
done:
-
 
772
	if (best_freq == 0)
-
 
773
		DRM_ERROR("Couldn't find valid PLL dividers\n");
-
 
774
 
-
 
775
	*dot_clock_p = best_freq / 10;
-
 
776
	*fb_div_p = fb_div;
-
 
777
	*frac_fb_div_p = fb_div_frac;
-
 
778
	*ref_div_p = ref_div;
-
 
779
	*post_div_p = post_div;
-
 
780
 
-
 
781
	DRM_DEBUG("%u %d.%d, %d, %d\n", *dot_clock_p, *fb_div_p, *frac_fb_div_p, *ref_div_p, *post_div_p);
-
 
782
}
-
 
783
 
-
 
784
void radeon_compute_pll(struct radeon_pll *pll,
-
 
785
			uint64_t freq,
-
 
786
			uint32_t *dot_clock_p,
-
 
787
			uint32_t *fb_div_p,
-
 
788
			uint32_t *frac_fb_div_p,
-
 
789
			uint32_t *ref_div_p,
-
 
790
			uint32_t *post_div_p)
-
 
791
{
-
 
792
	switch (pll->algo) {
-
 
793
	case PLL_ALGO_NEW:
-
 
794
		radeon_compute_pll_new(pll, freq, dot_clock_p, fb_div_p,
-
 
795
				       frac_fb_div_p, ref_div_p, post_div_p);
-
 
796
		break;
-
 
797
	case PLL_ALGO_LEGACY:
-
 
798
	default:
-
 
799
		radeon_compute_pll_legacy(pll, freq, dot_clock_p, fb_div_p,
-
 
800
					  frac_fb_div_p, ref_div_p, post_div_p);
-
 
801
		break;
-
 
802
	}
836
 
Line 803... Line 837...
803
}
837
}
804
 
838
 
805
static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb)
839
static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb)
806
{
-
 
807
	struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb);
-
 
808
	struct drm_device *dev = fb->dev;
-
 
809
 
-
 
810
	if (fb->fbdev)
-
 
Line 811... Line 840...
811
		radeonfb_remove(dev, fb);
840
{
812
 
841
	struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb);
813
 
842
 
Line 828... Line 857...
828
static const struct drm_framebuffer_funcs radeon_fb_funcs = {
857
static const struct drm_framebuffer_funcs radeon_fb_funcs = {
829
	.destroy = radeon_user_framebuffer_destroy,
858
	.destroy = radeon_user_framebuffer_destroy,
830
    .create_handle = radeon_user_framebuffer_create_handle,
859
    .create_handle = radeon_user_framebuffer_create_handle,
831
};
860
};
Line 832... Line 861...
832
 
861
 
833
struct drm_framebuffer *
862
void
-
 
863
radeon_framebuffer_init(struct drm_device *dev,
834
radeon_framebuffer_create(struct drm_device *dev,
864
			struct radeon_framebuffer *rfb,
835
			  struct drm_mode_fb_cmd *mode_cmd,
865
			  struct drm_mode_fb_cmd *mode_cmd,
836
			  struct drm_gem_object *obj)
866
			  struct drm_gem_object *obj)
837
{
-
 
838
	struct radeon_framebuffer *radeon_fb;
-
 
839
 
-
 
840
    radeon_fb = kzalloc(sizeof(*radeon_fb), GFP_KERNEL);
-
 
841
	if (radeon_fb == NULL) {
867
{
842
		return NULL;
-
 
843
	}
868
	rfb->obj = obj;
844
    drm_framebuffer_init(dev, &radeon_fb->base, &radeon_fb_funcs);
869
	drm_framebuffer_init(dev, &rfb->base, &radeon_fb_funcs);
845
    drm_helper_mode_fill_fb_struct(&radeon_fb->base, mode_cmd);
-
 
846
	radeon_fb->obj = obj;
-
 
847
	return &radeon_fb->base;
870
	drm_helper_mode_fill_fb_struct(&rfb->base, mode_cmd);
Line 848... Line 871...
848
}
871
}
849
 
872
 
850
static struct drm_framebuffer *
873
static struct drm_framebuffer *
Line 859... Line 882...
859
//   obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle);
882
//   obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle);
860
//
883
//
861
//   return radeon_framebuffer_create(dev, mode_cmd, obj);
884
//   return radeon_framebuffer_create(dev, mode_cmd, obj);
862
}
885
}
Line -... Line 886...
-
 
886
 
863
 
887
 
864
static const struct drm_mode_config_funcs radeon_mode_funcs = {
888
static const struct drm_mode_config_funcs radeon_mode_funcs = {
865
 //  .fb_create = radeon_user_framebuffer_create,
889
//	.fb_create = radeon_user_framebuffer_create,
866
     .fb_changed = radeonfb_probe,
890
//   .output_poll_changed = radeon_output_poll_changed
Line 867... Line 891...
867
};
891
};
868
 
892
 
869
struct drm_prop_enum_list {
893
struct drm_prop_enum_list {
Line 885... Line 909...
885
	{ TV_STD_SCART_PAL, "scart-pal" },
909
	{ TV_STD_SCART_PAL, "scart-pal" },
886
	{ TV_STD_PAL_CN, "pal-cn" },
910
	{ TV_STD_PAL_CN, "pal-cn" },
887
	{ TV_STD_SECAM, "secam" },
911
	{ TV_STD_SECAM, "secam" },
888
};
912
};
Line -... Line 913...
-
 
913
 
-
 
914
static struct drm_prop_enum_list radeon_underscan_enum_list[] =
-
 
915
{	{ UNDERSCAN_OFF, "off" },
-
 
916
	{ UNDERSCAN_ON, "on" },
-
 
917
	{ UNDERSCAN_AUTO, "auto" },
-
 
918
};
889
 
919
 
890
static int radeon_modeset_create_props(struct radeon_device *rdev)
920
static int radeon_modeset_create_props(struct radeon_device *rdev)
891
{
921
{
Line 892... Line 922...
892
	int i, sz;
922
	int i, sz;
Line 938... Line 968...
938
				      i,
968
				      i,
939
				      radeon_tv_std_enum_list[i].type,
969
				      radeon_tv_std_enum_list[i].type,
940
				      radeon_tv_std_enum_list[i].name);
970
				      radeon_tv_std_enum_list[i].name);
941
	}
971
	}
Line -... Line 972...
-
 
972
 
-
 
973
	sz = ARRAY_SIZE(radeon_underscan_enum_list);
-
 
974
	rdev->mode_info.underscan_property =
-
 
975
		drm_property_create(rdev->ddev,
-
 
976
				    DRM_MODE_PROP_ENUM,
-
 
977
				    "underscan", sz);
-
 
978
	for (i = 0; i < sz; i++) {
-
 
979
		drm_property_add_enum(rdev->mode_info.underscan_property,
-
 
980
				      i,
-
 
981
				      radeon_underscan_enum_list[i].type,
-
 
982
				      radeon_underscan_enum_list[i].name);
-
 
983
	}
-
 
984
 
-
 
985
	rdev->mode_info.underscan_hborder_property =
-
 
986
		drm_property_create(rdev->ddev,
-
 
987
					DRM_MODE_PROP_RANGE,
-
 
988
					"underscan hborder", 2);
-
 
989
	if (!rdev->mode_info.underscan_hborder_property)
-
 
990
		return -ENOMEM;
-
 
991
	rdev->mode_info.underscan_hborder_property->values[0] = 0;
-
 
992
	rdev->mode_info.underscan_hborder_property->values[1] = 128;
-
 
993
 
-
 
994
	rdev->mode_info.underscan_vborder_property =
-
 
995
		drm_property_create(rdev->ddev,
-
 
996
					DRM_MODE_PROP_RANGE,
-
 
997
					"underscan vborder", 2);
-
 
998
	if (!rdev->mode_info.underscan_vborder_property)
-
 
999
		return -ENOMEM;
-
 
1000
	rdev->mode_info.underscan_vborder_property->values[0] = 0;
-
 
1001
	rdev->mode_info.underscan_vborder_property->values[1] = 128;
942
 
1002
 
943
	return 0;
1003
	return 0;
Line -... Line 1004...
-
 
1004
}
-
 
1005
 
-
 
1006
void radeon_update_display_priority(struct radeon_device *rdev)
-
 
1007
{
-
 
1008
	/* adjustment options for the display watermarks */
-
 
1009
	if ((radeon_disp_priority == 0) || (radeon_disp_priority > 2)) {
-
 
1010
		/* set display priority to high for r3xx, rv515 chips
-
 
1011
		 * this avoids flickering due to underflow to the
-
 
1012
		 * display controllers during heavy acceleration.
-
 
1013
		 * Don't force high on rs4xx igp chips as it seems to
-
 
1014
		 * affect the sound card.  See kernel bug 15982.
-
 
1015
		 */
-
 
1016
		if ((ASIC_IS_R300(rdev) || (rdev->family == CHIP_RV515)) &&
-
 
1017
		    !(rdev->flags & RADEON_IS_IGP))
-
 
1018
			rdev->disp_priority = 2;
-
 
1019
		else
-
 
1020
			rdev->disp_priority = 0;
-
 
1021
	} else
-
 
1022
		rdev->disp_priority = radeon_disp_priority;
-
 
1023
 
944
}
1024
}
945
 
1025
 
946
int radeon_modeset_init(struct radeon_device *rdev)
1026
int radeon_modeset_init(struct radeon_device *rdev)
947
{
1027
{
Line -... Line 1028...
-
 
1028
	int i;
-
 
1029
	int ret;
948
	int i;
1030
 
949
	int ret;
1031
    ENTER();
Line 950... Line 1032...
950
 
1032
 
Line 951... Line 1033...
951
	drm_mode_config_init(rdev->ddev);
1033
	drm_mode_config_init(rdev->ddev);
-
 
1034
	rdev->mode_info.mode_config_initialized = true;
-
 
1035
 
-
 
1036
    rdev->ddev->mode_config.funcs = (void *)&radeon_mode_funcs;
952
	rdev->mode_info.mode_config_initialized = true;
1037
 
953
 
1038
	if (ASIC_IS_DCE5(rdev)) {
954
    rdev->ddev->mode_config.funcs = (void *)&radeon_mode_funcs;
1039
		rdev->ddev->mode_config.max_width = 16384;
955
 
1040
		rdev->ddev->mode_config.max_height = 16384;
956
	if (ASIC_IS_AVIVO(rdev)) {
1041
	} else if (ASIC_IS_AVIVO(rdev)) {
Line 966... Line 1051...
966
	ret = radeon_modeset_create_props(rdev);
1051
	ret = radeon_modeset_create_props(rdev);
967
	if (ret) {
1052
	if (ret) {
968
		return ret;
1053
		return ret;
969
	}
1054
	}
Line -... Line 1055...
-
 
1055
 
-
 
1056
	/* init i2c buses */
-
 
1057
	radeon_i2c_init(rdev);
970
 
1058
 
971
	/* check combios for a valid hardcoded EDID - Sun servers */
1059
	/* check combios for a valid hardcoded EDID - Sun servers */
972
	if (!rdev->is_atom_bios) {
1060
	if (!rdev->is_atom_bios) {
973
		/* check for hardcoded EDID in BIOS */
1061
		/* check for hardcoded EDID in BIOS */
974
		radeon_combios_check_hardcoded_edid(rdev);
1062
		radeon_combios_check_hardcoded_edid(rdev);
Line 975... Line -...
975
	}
-
 
976
 
-
 
977
	if (rdev->flags & RADEON_SINGLE_CRTC)
-
 
978
		rdev->num_crtc = 1;
-
 
979
	else {
-
 
980
		if (ASIC_IS_DCE4(rdev))
-
 
981
			rdev->num_crtc = 6;
-
 
982
		else
-
 
983
			rdev->num_crtc = 2;
-
 
984
	}
1063
	}
985
 
1064
 
986
	/* allocate crtcs */
1065
	/* allocate crtcs */
987
	for (i = 0; i < rdev->num_crtc; i++) {
1066
	for (i = 0; i < rdev->num_crtc; i++) {
Line 988... Line 1067...
988
		radeon_crtc_init(rdev->ddev, i);
1067
		radeon_crtc_init(rdev->ddev, i);
989
	}
1068
	}
990
 
1069
 
991
	/* okay we should have all the bios connectors */
1070
	/* okay we should have all the bios connectors */
992
	ret = radeon_setup_enc_conn(rdev->ddev);
1071
	ret = radeon_setup_enc_conn(rdev->ddev);
-
 
1072
	if (!ret) {
-
 
1073
		return ret;
-
 
1074
	}
-
 
1075
 
-
 
1076
	/* init dig PHYs */
993
	if (!ret) {
1077
	if (rdev->is_atom_bios)
-
 
1078
		radeon_atom_encoder_init(rdev);
-
 
1079
 
-
 
1080
	/* initialize hpd */
-
 
1081
//   radeon_hpd_init(rdev);
-
 
1082
 
994
		return ret;
1083
	/* Initialize power management */
995
	}
1084
//   radeon_pm_init(rdev);
-
 
1085
 
-
 
1086
	radeon_fbdev_init(rdev);
-
 
1087
//   drm_kms_helper_poll_init(rdev->ddev);
996
	/* initialize hpd */
1088
 
997
	radeon_hpd_init(rdev);
1089
    LEAVE();
Line 998... Line 1090...
998
	drm_helper_initial_config(rdev->ddev);
1090
 
999
	return 0;
1091
	return 0;
1000
}
1092
}
Line 1001... Line 1093...
1001
 
1093
 
-
 
1094
void radeon_modeset_fini(struct radeon_device *rdev)
1002
void radeon_modeset_fini(struct radeon_device *rdev)
1095
{
1003
{
1096
	kfree(rdev->mode_info.bios_hardcoded_edid);
1004
	kfree(rdev->mode_info.bios_hardcoded_edid);
1097
 
1005
 
1098
	if (rdev->mode_info.mode_config_initialized) {
-
 
1099
//       drm_kms_helper_poll_fini(rdev->ddev);
-
 
1100
//       radeon_hpd_fini(rdev);
-
 
1101
		drm_mode_config_cleanup(rdev->ddev);
-
 
1102
		rdev->mode_info.mode_config_initialized = false;
-
 
1103
	}
-
 
1104
	/* free i2c buses */
-
 
1105
	radeon_i2c_fini(rdev);
-
 
1106
}
-
 
1107
 
-
 
1108
static bool is_hdtv_mode(struct drm_display_mode *mode)
-
 
1109
{
-
 
1110
	/* try and guess if this is a tv or a monitor */
-
 
1111
	if ((mode->vdisplay == 480 && mode->hdisplay == 720) || /* 480p */
-
 
1112
	    (mode->vdisplay == 576) || /* 576p */
1006
	if (rdev->mode_info.mode_config_initialized) {
1113
	    (mode->vdisplay == 720) || /* 720p */
Line 1007... Line 1114...
1007
		radeon_hpd_fini(rdev);
1114
	    (mode->vdisplay == 1080)) /* 1080p */
1008
		drm_mode_config_cleanup(rdev->ddev);
1115
		return true;
1009
		rdev->mode_info.mode_config_initialized = false;
1116
	else
1010
	}
1117
		return false;
1011
}
1118
}
-
 
1119
 
1012
 
1120
bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
1013
bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
1121
				struct drm_display_mode *mode,
1014
				struct drm_display_mode *mode,
1122
				struct drm_display_mode *adjusted_mode)
-
 
1123
{
-
 
1124
	struct drm_device *dev = crtc->dev;
1015
				struct drm_display_mode *adjusted_mode)
1125
	struct radeon_device *rdev = dev->dev_private;
-
 
1126
	struct drm_encoder *encoder;
-
 
1127
		struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
-
 
1128
	struct radeon_encoder *radeon_encoder;
-
 
1129
	struct drm_connector *connector;
-
 
1130
	struct radeon_connector *radeon_connector;
Line 1016... Line 1131...
1016
{
1131
	bool first = true;
1017
	struct drm_device *dev = crtc->dev;
-
 
1018
	struct drm_encoder *encoder;
1132
	u32 src_v = 1, dst_v = 1;
1019
		struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1133
	u32 src_h = 1, dst_h = 1;
-
 
1134
 
-
 
1135
	radeon_crtc->h_border = 0;
-
 
1136
	radeon_crtc->v_border = 0;
-
 
1137
 
1020
	struct radeon_encoder *radeon_encoder;
1138
	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
1021
	bool first = true;
1139
		if (encoder->crtc != crtc)
1022
 
1140
			continue;
1023
	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
1141
		radeon_encoder = to_radeon_encoder(encoder);
1024
		radeon_encoder = to_radeon_encoder(encoder);
1142
		connector = radeon_get_connector_for_encoder(encoder);
Line 1035... Line 1153...
1035
				radeon_crtc->rmx_type = RMX_OFF;
1153
				radeon_crtc->rmx_type = RMX_OFF;
1036
			/* copy native mode */
1154
			/* copy native mode */
1037
			memcpy(&radeon_crtc->native_mode,
1155
			memcpy(&radeon_crtc->native_mode,
1038
				&radeon_encoder->native_mode,
1156
				&radeon_encoder->native_mode,
1039
				sizeof(struct drm_display_mode));
1157
				sizeof(struct drm_display_mode));
-
 
1158
			src_v = crtc->mode.vdisplay;
-
 
1159
			dst_v = radeon_crtc->native_mode.vdisplay;
-
 
1160
			src_h = crtc->mode.hdisplay;
-
 
1161
			dst_h = radeon_crtc->native_mode.hdisplay;
-
 
1162
 
-
 
1163
			/* fix up for overscan on hdmi */
-
 
1164
			if (ASIC_IS_AVIVO(rdev) &&
-
 
1165
			    (!(mode->flags & DRM_MODE_FLAG_INTERLACE)) &&
-
 
1166
			    ((radeon_encoder->underscan_type == UNDERSCAN_ON) ||
-
 
1167
			     ((radeon_encoder->underscan_type == UNDERSCAN_AUTO) &&
-
 
1168
			      drm_detect_hdmi_monitor(radeon_connector->edid) &&
-
 
1169
			      is_hdtv_mode(mode)))) {
-
 
1170
				if (radeon_encoder->underscan_hborder != 0)
-
 
1171
					radeon_crtc->h_border = radeon_encoder->underscan_hborder;
-
 
1172
				else
-
 
1173
				radeon_crtc->h_border = (mode->hdisplay >> 5) + 16;
-
 
1174
				if (radeon_encoder->underscan_vborder != 0)
-
 
1175
					radeon_crtc->v_border = radeon_encoder->underscan_vborder;
-
 
1176
				else
-
 
1177
				radeon_crtc->v_border = (mode->vdisplay >> 5) + 16;
-
 
1178
				radeon_crtc->rmx_type = RMX_FULL;
-
 
1179
				src_v = crtc->mode.vdisplay;
-
 
1180
				dst_v = crtc->mode.vdisplay - (radeon_crtc->v_border * 2);
-
 
1181
				src_h = crtc->mode.hdisplay;
-
 
1182
				dst_h = crtc->mode.hdisplay - (radeon_crtc->h_border * 2);
-
 
1183
			}
1040
			first = false;
1184
			first = false;
1041
		} else {
1185
		} else {
1042
			if (radeon_crtc->rmx_type != radeon_encoder->rmx_type) {
1186
			if (radeon_crtc->rmx_type != radeon_encoder->rmx_type) {
1043
				/* WARNING: Right now this can't happen but
1187
				/* WARNING: Right now this can't happen but
1044
				 * in the future we need to check that scaling
1188
				 * in the future we need to check that scaling
1045
				 * are consistent accross different encoder
1189
				 * are consistent across different encoder
1046
				 * (ie all encoder can work with the same
1190
				 * (ie all encoder can work with the same
1047
				 *  scaling).
1191
				 *  scaling).
1048
				 */
1192
				 */
1049
				DRM_ERROR("Scaling not consistent accross encoder.\n");
1193
				DRM_ERROR("Scaling not consistent across encoder.\n");
1050
				return false;
1194
				return false;
1051
			}
1195
			}
1052
		}
1196
		}
1053
	}
1197
	}
1054
	if (radeon_crtc->rmx_type != RMX_OFF) {
1198
	if (radeon_crtc->rmx_type != RMX_OFF) {
1055
        fixed20_12 a, b;
1199
        fixed20_12 a, b;
1056
		a.full = rfixed_const(crtc->mode.vdisplay);
1200
		a.full = dfixed_const(src_v);
1057
		b.full = rfixed_const(radeon_crtc->native_mode.hdisplay);
1201
		b.full = dfixed_const(dst_v);
1058
		radeon_crtc->vsc.full = rfixed_div(a, b);
1202
		radeon_crtc->vsc.full = dfixed_div(a, b);
1059
		a.full = rfixed_const(crtc->mode.hdisplay);
1203
		a.full = dfixed_const(src_h);
1060
		b.full = rfixed_const(radeon_crtc->native_mode.vdisplay);
1204
		b.full = dfixed_const(dst_h);
1061
		radeon_crtc->hsc.full = rfixed_div(a, b);
1205
		radeon_crtc->hsc.full = dfixed_div(a, b);
1062
	} else {
1206
	} else {
1063
		radeon_crtc->vsc.full = rfixed_const(1);
1207
		radeon_crtc->vsc.full = dfixed_const(1);
1064
		radeon_crtc->hsc.full = rfixed_const(1);
1208
		radeon_crtc->hsc.full = dfixed_const(1);
1065
	}
1209
	}
1066
	return true;
1210
	return true;
1067
}
1211
}
-
 
1212
 
-
 
1213
/*
-
 
1214
 * Retrieve current video scanout position of crtc on a given gpu.
-
 
1215
 *
-
 
1216
 * \param dev Device to query.
-
 
1217
 * \param crtc Crtc to query.
-
 
1218
 * \param *vpos Location where vertical scanout position should be stored.
-
 
1219
 * \param *hpos Location where horizontal scanout position should go.
-
 
1220
 *
-
 
1221
 * Returns vpos as a positive number while in active scanout area.
-
 
1222
 * Returns vpos as a negative number inside vblank, counting the number
-
 
1223
 * of scanlines to go until end of vblank, e.g., -1 means "one scanline
-
 
1224
 * until start of active scanout / end of vblank."
-
 
1225
 *
-
 
1226
 * \return Flags, or'ed together as follows:
-
 
1227
 *
-
 
1228
 * DRM_SCANOUTPOS_VALID = Query successful.
-
 
1229
 * DRM_SCANOUTPOS_INVBL = Inside vblank.
-
 
1230
 * DRM_SCANOUTPOS_ACCURATE = Returned position is accurate. A lack of
-
 
1231
 * this flag means that returned position may be offset by a constant but
-
 
1232
 * unknown small number of scanlines wrt. real scanout position.
-
 
1233
 *
-
 
1234
 */
-
 
1235
int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, int *vpos, int *hpos)
-
 
1236
{
-
 
1237
	u32 stat_crtc = 0, vbl = 0, position = 0;
-
 
1238
	int vbl_start, vbl_end, vtotal, ret = 0;
-
 
1239
	bool in_vbl = true;
-
 
1240
 
-
 
1241
	struct radeon_device *rdev = dev->dev_private;
-
 
1242
 
-
 
1243
	if (ASIC_IS_DCE4(rdev)) {
-
 
1244
		if (crtc == 0) {
-
 
1245
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
-
 
1246
				     EVERGREEN_CRTC0_REGISTER_OFFSET);
-
 
1247
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
-
 
1248
					  EVERGREEN_CRTC0_REGISTER_OFFSET);
-
 
1249
			ret |= DRM_SCANOUTPOS_VALID;
-
 
1250
		}
-
 
1251
		if (crtc == 1) {
-
 
1252
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
-
 
1253
				     EVERGREEN_CRTC1_REGISTER_OFFSET);
-
 
1254
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
-
 
1255
					  EVERGREEN_CRTC1_REGISTER_OFFSET);
-
 
1256
			ret |= DRM_SCANOUTPOS_VALID;
-
 
1257
		}
-
 
1258
		if (crtc == 2) {
-
 
1259
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
-
 
1260
				     EVERGREEN_CRTC2_REGISTER_OFFSET);
-
 
1261
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
-
 
1262
					  EVERGREEN_CRTC2_REGISTER_OFFSET);
-
 
1263
			ret |= DRM_SCANOUTPOS_VALID;
-
 
1264
		}
-
 
1265
		if (crtc == 3) {
-
 
1266
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
-
 
1267
				     EVERGREEN_CRTC3_REGISTER_OFFSET);
-
 
1268
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
-
 
1269
					  EVERGREEN_CRTC3_REGISTER_OFFSET);
-
 
1270
			ret |= DRM_SCANOUTPOS_VALID;
-
 
1271
		}
-
 
1272
		if (crtc == 4) {
-
 
1273
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
-
 
1274
				     EVERGREEN_CRTC4_REGISTER_OFFSET);
-
 
1275
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
-
 
1276
					  EVERGREEN_CRTC4_REGISTER_OFFSET);
-
 
1277
			ret |= DRM_SCANOUTPOS_VALID;
-
 
1278
		}
-
 
1279
		if (crtc == 5) {
-
 
1280
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
-
 
1281
				     EVERGREEN_CRTC5_REGISTER_OFFSET);
-
 
1282
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
-
 
1283
					  EVERGREEN_CRTC5_REGISTER_OFFSET);
-
 
1284
			ret |= DRM_SCANOUTPOS_VALID;
-
 
1285
		}
-
 
1286
	} else if (ASIC_IS_AVIVO(rdev)) {
-
 
1287
		if (crtc == 0) {
-
 
1288
			vbl = RREG32(AVIVO_D1CRTC_V_BLANK_START_END);
-
 
1289
			position = RREG32(AVIVO_D1CRTC_STATUS_POSITION);
-
 
1290
			ret |= DRM_SCANOUTPOS_VALID;
-
 
1291
		}
-
 
1292
		if (crtc == 1) {
-
 
1293
			vbl = RREG32(AVIVO_D2CRTC_V_BLANK_START_END);
-
 
1294
			position = RREG32(AVIVO_D2CRTC_STATUS_POSITION);
-
 
1295
			ret |= DRM_SCANOUTPOS_VALID;
-
 
1296
		}
-
 
1297
	} else {
-
 
1298
		/* Pre-AVIVO: Different encoding of scanout pos and vblank interval. */
-
 
1299
		if (crtc == 0) {
-
 
1300
			/* Assume vbl_end == 0, get vbl_start from
-
 
1301
			 * upper 16 bits.
-
 
1302
			 */
-
 
1303
			vbl = (RREG32(RADEON_CRTC_V_TOTAL_DISP) &
-
 
1304
				RADEON_CRTC_V_DISP) >> RADEON_CRTC_V_DISP_SHIFT;
-
 
1305
			/* Only retrieve vpos from upper 16 bits, set hpos == 0. */
-
 
1306
			position = (RREG32(RADEON_CRTC_VLINE_CRNT_VLINE) >> 16) & RADEON_CRTC_V_TOTAL;
-
 
1307
			stat_crtc = RREG32(RADEON_CRTC_STATUS);
-
 
1308
			if (!(stat_crtc & 1))
-
 
1309
				in_vbl = false;
-
 
1310
 
-
 
1311
			ret |= DRM_SCANOUTPOS_VALID;
-
 
1312
		}
-
 
1313
		if (crtc == 1) {
-
 
1314
			vbl = (RREG32(RADEON_CRTC2_V_TOTAL_DISP) &
-
 
1315
				RADEON_CRTC_V_DISP) >> RADEON_CRTC_V_DISP_SHIFT;
-
 
1316
			position = (RREG32(RADEON_CRTC2_VLINE_CRNT_VLINE) >> 16) & RADEON_CRTC_V_TOTAL;
-
 
1317
			stat_crtc = RREG32(RADEON_CRTC2_STATUS);
-
 
1318
			if (!(stat_crtc & 1))
-
 
1319
				in_vbl = false;
-
 
1320
 
-
 
1321
			ret |= DRM_SCANOUTPOS_VALID;
-
 
1322
		}
-
 
1323
	}
-
 
1324
 
-
 
1325
	/* Decode into vertical and horizontal scanout position. */
-
 
1326
	*vpos = position & 0x1fff;
-
 
1327
	*hpos = (position >> 16) & 0x1fff;
-
 
1328
 
-
 
1329
	/* Valid vblank area boundaries from gpu retrieved? */
-
 
1330
	if (vbl > 0) {
-
 
1331
		/* Yes: Decode. */
-
 
1332
		ret |= DRM_SCANOUTPOS_ACCURATE;
-
 
1333
		vbl_start = vbl & 0x1fff;
-
 
1334
		vbl_end = (vbl >> 16) & 0x1fff;
-
 
1335
	}
-
 
1336
	else {
-
 
1337
		/* No: Fake something reasonable which gives at least ok results. */
-
 
1338
		vbl_start = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vdisplay;
-
 
1339
		vbl_end = 0;
-
 
1340
	}
-
 
1341
 
-
 
1342
	/* Test scanout position against vblank region. */
-
 
1343
	if ((*vpos < vbl_start) && (*vpos >= vbl_end))
-
 
1344
		in_vbl = false;
-
 
1345
 
-
 
1346
	/* Check if inside vblank area and apply corrective offsets:
-
 
1347
	 * vpos will then be >=0 in video scanout area, but negative
-
 
1348
	 * within vblank area, counting down the number of lines until
-
 
1349
	 * start of scanout.
-
 
1350
	 */
-
 
1351
 
-
 
1352
	/* Inside "upper part" of vblank area? Apply corrective offset if so: */
-
 
1353
	if (in_vbl && (*vpos >= vbl_start)) {
-
 
1354
		vtotal = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vtotal;
-
 
1355
		*vpos = *vpos - vtotal;
-
 
1356
	}
-
 
1357
 
-
 
1358
	/* Correct for shifted end of vbl at vbl_end. */
-
 
1359
	*vpos = *vpos - vbl_end;
-
 
1360
 
-
 
1361
	/* In vblank? */
-
 
1362
	if (in_vbl)
-
 
1363
		ret |= DRM_SCANOUTPOS_INVBL;
-
 
1364
 
-
 
1365
	return ret;
-
 
1366
}