Subversion Repositories Kolibri OS

Rev

Rev 1963 | Rev 2160 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1963 Rev 1986
1
/*
1
/*
2
 * Copyright 2007-8 Advanced Micro Devices, Inc.
2
 * Copyright 2007-8 Advanced Micro Devices, Inc.
3
 * Copyright 2008 Red Hat Inc.
3
 * Copyright 2008 Red Hat Inc.
4
 *
4
 *
5
 * Permission is hereby granted, free of charge, to any person obtaining a
5
 * Permission is hereby granted, free of charge, to any person obtaining a
6
 * copy of this software and associated documentation files (the "Software"),
6
 * copy of this software and associated documentation files (the "Software"),
7
 * to deal in the Software without restriction, including without limitation
7
 * to deal in the Software without restriction, including without limitation
8
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
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
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:
10
 * Software is furnished to do so, subject to the following conditions:
11
 *
11
 *
12
 * The above copyright notice and this permission notice shall be included in
12
 * The above copyright notice and this permission notice shall be included in
13
 * all copies or substantial portions of the Software.
13
 * all copies or substantial portions of the Software.
14
 *
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
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,
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
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
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,
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
20
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21
 * OTHER DEALINGS IN THE SOFTWARE.
21
 * OTHER DEALINGS IN THE SOFTWARE.
22
 *
22
 *
23
 * Authors: Dave Airlie
23
 * Authors: Dave Airlie
24
 *          Alex Deucher
24
 *          Alex Deucher
25
 */
25
 */
26
#include "drmP.h"
26
#include "drmP.h"
27
#include "drm_crtc_helper.h"
27
#include "drm_crtc_helper.h"
28
#include "radeon_drm.h"
28
#include "radeon_drm.h"
29
#include "radeon.h"
29
#include "radeon.h"
30
#include "atom.h"
30
#include "atom.h"
31
 
31
 
32
extern int atom_debug;
32
extern int atom_debug;
33
 
33
 
34
/* evil but including atombios.h is much worse */
34
/* evil but including atombios.h is much worse */
35
bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
35
bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
36
				struct drm_display_mode *mode);
36
				struct drm_display_mode *mode);
37
 
37
 
38
static uint32_t radeon_encoder_clones(struct drm_encoder *encoder)
38
static uint32_t radeon_encoder_clones(struct drm_encoder *encoder)
39
{
39
{
40
	struct drm_device *dev = encoder->dev;
40
	struct drm_device *dev = encoder->dev;
41
	struct radeon_device *rdev = dev->dev_private;
41
	struct radeon_device *rdev = dev->dev_private;
42
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
42
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
43
	struct drm_encoder *clone_encoder;
43
	struct drm_encoder *clone_encoder;
44
	uint32_t index_mask = 0;
44
	uint32_t index_mask = 0;
45
	int count;
45
	int count;
46
 
46
 
47
	/* DIG routing gets problematic */
47
	/* DIG routing gets problematic */
48
	if (rdev->family >= CHIP_R600)
48
	if (rdev->family >= CHIP_R600)
49
		return index_mask;
49
		return index_mask;
50
	/* LVDS/TV are too wacky */
50
	/* LVDS/TV are too wacky */
51
	if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT)
51
	if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT)
52
		return index_mask;
52
		return index_mask;
53
	/* DVO requires 2x ppll clocks depending on tmds chip */
53
	/* DVO requires 2x ppll clocks depending on tmds chip */
54
	if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT)
54
	if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT)
55
		return index_mask;
55
		return index_mask;
56
 
56
 
57
	count = -1;
57
	count = -1;
58
	list_for_each_entry(clone_encoder, &dev->mode_config.encoder_list, head) {
58
	list_for_each_entry(clone_encoder, &dev->mode_config.encoder_list, head) {
59
		struct radeon_encoder *radeon_clone = to_radeon_encoder(clone_encoder);
59
		struct radeon_encoder *radeon_clone = to_radeon_encoder(clone_encoder);
60
		count++;
60
		count++;
61
 
61
 
62
		if (clone_encoder == encoder)
62
		if (clone_encoder == encoder)
63
			continue;
63
			continue;
64
		if (radeon_clone->devices & (ATOM_DEVICE_LCD_SUPPORT))
64
		if (radeon_clone->devices & (ATOM_DEVICE_LCD_SUPPORT))
65
			continue;
65
			continue;
66
		if (radeon_clone->devices & ATOM_DEVICE_DFP2_SUPPORT)
66
		if (radeon_clone->devices & ATOM_DEVICE_DFP2_SUPPORT)
67
			continue;
67
			continue;
68
		else
68
		else
69
			index_mask |= (1 << count);
69
			index_mask |= (1 << count);
70
	}
70
	}
71
	return index_mask;
71
	return index_mask;
72
}
72
}
73
 
73
 
74
void radeon_setup_encoder_clones(struct drm_device *dev)
74
void radeon_setup_encoder_clones(struct drm_device *dev)
75
{
75
{
76
	struct drm_encoder *encoder;
76
	struct drm_encoder *encoder;
77
 
77
 
78
	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
78
	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
79
		encoder->possible_clones = radeon_encoder_clones(encoder);
79
		encoder->possible_clones = radeon_encoder_clones(encoder);
80
	}
80
	}
81
}
81
}
82
 
82
 
83
uint32_t
83
uint32_t
84
radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, uint8_t dac)
84
radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, uint8_t dac)
85
{
85
{
86
	struct radeon_device *rdev = dev->dev_private;
86
	struct radeon_device *rdev = dev->dev_private;
87
	uint32_t ret = 0;
87
	uint32_t ret = 0;
88
 
88
 
89
	switch (supported_device) {
89
	switch (supported_device) {
90
	case ATOM_DEVICE_CRT1_SUPPORT:
90
	case ATOM_DEVICE_CRT1_SUPPORT:
91
	case ATOM_DEVICE_TV1_SUPPORT:
91
	case ATOM_DEVICE_TV1_SUPPORT:
92
	case ATOM_DEVICE_TV2_SUPPORT:
92
	case ATOM_DEVICE_TV2_SUPPORT:
93
	case ATOM_DEVICE_CRT2_SUPPORT:
93
	case ATOM_DEVICE_CRT2_SUPPORT:
94
	case ATOM_DEVICE_CV_SUPPORT:
94
	case ATOM_DEVICE_CV_SUPPORT:
95
		switch (dac) {
95
		switch (dac) {
96
		case 1: /* dac a */
96
		case 1: /* dac a */
97
			if ((rdev->family == CHIP_RS300) ||
97
			if ((rdev->family == CHIP_RS300) ||
98
			    (rdev->family == CHIP_RS400) ||
98
			    (rdev->family == CHIP_RS400) ||
99
			    (rdev->family == CHIP_RS480))
99
			    (rdev->family == CHIP_RS480))
100
				ret = ENCODER_INTERNAL_DAC2_ENUM_ID1;
100
				ret = ENCODER_INTERNAL_DAC2_ENUM_ID1;
101
			else if (ASIC_IS_AVIVO(rdev))
101
			else if (ASIC_IS_AVIVO(rdev))
102
				ret = ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1;
102
				ret = ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1;
103
			else
103
			else
104
				ret = ENCODER_INTERNAL_DAC1_ENUM_ID1;
104
				ret = ENCODER_INTERNAL_DAC1_ENUM_ID1;
105
			break;
105
			break;
106
		case 2: /* dac b */
106
		case 2: /* dac b */
107
			if (ASIC_IS_AVIVO(rdev))
107
			if (ASIC_IS_AVIVO(rdev))
108
				ret = ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1;
108
				ret = ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1;
109
			else {
109
			else {
110
				/*if (rdev->family == CHIP_R200)
110
				/*if (rdev->family == CHIP_R200)
111
				  ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
111
				  ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
112
				  else*/
112
				  else*/
113
				ret = ENCODER_INTERNAL_DAC2_ENUM_ID1;
113
				ret = ENCODER_INTERNAL_DAC2_ENUM_ID1;
114
			}
114
			}
115
			break;
115
			break;
116
		case 3: /* external dac */
116
		case 3: /* external dac */
117
			if (ASIC_IS_AVIVO(rdev))
117
			if (ASIC_IS_AVIVO(rdev))
118
				ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1;
118
				ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1;
119
			else
119
			else
120
				ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
120
				ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
121
			break;
121
			break;
122
		}
122
		}
123
		break;
123
		break;
124
	case ATOM_DEVICE_LCD1_SUPPORT:
124
	case ATOM_DEVICE_LCD1_SUPPORT:
125
		if (ASIC_IS_AVIVO(rdev))
125
		if (ASIC_IS_AVIVO(rdev))
126
			ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1;
126
			ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1;
127
		else
127
		else
128
			ret = ENCODER_INTERNAL_LVDS_ENUM_ID1;
128
			ret = ENCODER_INTERNAL_LVDS_ENUM_ID1;
129
		break;
129
		break;
130
	case ATOM_DEVICE_DFP1_SUPPORT:
130
	case ATOM_DEVICE_DFP1_SUPPORT:
131
		if ((rdev->family == CHIP_RS300) ||
131
		if ((rdev->family == CHIP_RS300) ||
132
		    (rdev->family == CHIP_RS400) ||
132
		    (rdev->family == CHIP_RS400) ||
133
		    (rdev->family == CHIP_RS480))
133
		    (rdev->family == CHIP_RS480))
134
			ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
134
			ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
135
		else if (ASIC_IS_AVIVO(rdev))
135
		else if (ASIC_IS_AVIVO(rdev))
136
			ret = ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1;
136
			ret = ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1;
137
		else
137
		else
138
			ret = ENCODER_INTERNAL_TMDS1_ENUM_ID1;
138
			ret = ENCODER_INTERNAL_TMDS1_ENUM_ID1;
139
		break;
139
		break;
140
	case ATOM_DEVICE_LCD2_SUPPORT:
140
	case ATOM_DEVICE_LCD2_SUPPORT:
141
	case ATOM_DEVICE_DFP2_SUPPORT:
141
	case ATOM_DEVICE_DFP2_SUPPORT:
142
		if ((rdev->family == CHIP_RS600) ||
142
		if ((rdev->family == CHIP_RS600) ||
143
		    (rdev->family == CHIP_RS690) ||
143
		    (rdev->family == CHIP_RS690) ||
144
		    (rdev->family == CHIP_RS740))
144
		    (rdev->family == CHIP_RS740))
145
			ret = ENCODER_INTERNAL_DDI_ENUM_ID1;
145
			ret = ENCODER_INTERNAL_DDI_ENUM_ID1;
146
		else if (ASIC_IS_AVIVO(rdev))
146
		else if (ASIC_IS_AVIVO(rdev))
147
			ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1;
147
			ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1;
148
		else
148
		else
149
			ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
149
			ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
150
		break;
150
		break;
151
	case ATOM_DEVICE_DFP3_SUPPORT:
151
	case ATOM_DEVICE_DFP3_SUPPORT:
152
		ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1;
152
		ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1;
153
		break;
153
		break;
154
	}
154
	}
155
 
155
 
156
	return ret;
156
	return ret;
157
}
157
}
158
 
158
 
159
static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder)
159
static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder)
160
{
160
{
161
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
161
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
162
	switch (radeon_encoder->encoder_id) {
162
	switch (radeon_encoder->encoder_id) {
163
	case ENCODER_OBJECT_ID_INTERNAL_LVDS:
163
	case ENCODER_OBJECT_ID_INTERNAL_LVDS:
164
	case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
164
	case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
165
	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
165
	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
166
	case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
166
	case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
167
	case ENCODER_OBJECT_ID_INTERNAL_DVO1:
167
	case ENCODER_OBJECT_ID_INTERNAL_DVO1:
168
	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
168
	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
169
	case ENCODER_OBJECT_ID_INTERNAL_DDI:
169
	case ENCODER_OBJECT_ID_INTERNAL_DDI:
170
	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
170
	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
171
	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
171
	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
172
	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
172
	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
173
	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
173
	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
174
		return true;
174
		return true;
175
	default:
175
	default:
176
		return false;
176
		return false;
177
	}
177
	}
178
}
178
}
179
 
179
 
180
void
180
void
181
radeon_link_encoder_connector(struct drm_device *dev)
181
radeon_link_encoder_connector(struct drm_device *dev)
182
{
182
{
183
	struct drm_connector *connector;
183
	struct drm_connector *connector;
184
	struct radeon_connector *radeon_connector;
184
	struct radeon_connector *radeon_connector;
185
	struct drm_encoder *encoder;
185
	struct drm_encoder *encoder;
186
	struct radeon_encoder *radeon_encoder;
186
	struct radeon_encoder *radeon_encoder;
187
 
187
 
188
	/* walk the list and link encoders to connectors */
188
	/* walk the list and link encoders to connectors */
189
	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
189
	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
190
		radeon_connector = to_radeon_connector(connector);
190
		radeon_connector = to_radeon_connector(connector);
191
		list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
191
		list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
192
			radeon_encoder = to_radeon_encoder(encoder);
192
			radeon_encoder = to_radeon_encoder(encoder);
193
			if (radeon_encoder->devices & radeon_connector->devices)
193
			if (radeon_encoder->devices & radeon_connector->devices)
194
				drm_mode_connector_attach_encoder(connector, encoder);
194
				drm_mode_connector_attach_encoder(connector, encoder);
195
		}
195
		}
196
	}
196
	}
197
}
197
}
198
 
198
 
199
void radeon_encoder_set_active_device(struct drm_encoder *encoder)
199
void radeon_encoder_set_active_device(struct drm_encoder *encoder)
200
{
200
{
201
	struct drm_device *dev = encoder->dev;
201
	struct drm_device *dev = encoder->dev;
202
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
202
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
203
	struct drm_connector *connector;
203
	struct drm_connector *connector;
204