diff options
24 files changed, 2657 insertions, 323 deletions
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index b5713eedd6e1..feb52eee4314 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile | |||
@@ -49,7 +49,7 @@ radeon-y += radeon_device.o radeon_kms.o \ | |||
49 | radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \ | 49 | radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \ |
50 | rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \ | 50 | rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \ |
51 | r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \ | 51 | r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \ |
52 | r600_blit_kms.o radeon_pm.o | 52 | r600_blit_kms.o radeon_pm.o atombios_dp.o |
53 | 53 | ||
54 | radeon-$(CONFIG_COMPAT) += radeon_ioc32.o | 54 | radeon-$(CONFIG_COMPAT) += radeon_ioc32.o |
55 | 55 | ||
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index d67c42555ab9..6578d19dff93 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c | |||
@@ -263,10 +263,10 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr, | |||
263 | case ATOM_ARG_FB: | 263 | case ATOM_ARG_FB: |
264 | idx = U8(*ptr); | 264 | idx = U8(*ptr); |
265 | (*ptr)++; | 265 | (*ptr)++; |
266 | val = gctx->scratch[((gctx->fb_base + idx) / 4)]; | ||
266 | if (print) | 267 | if (print) |
267 | DEBUG("FB[0x%02X]", idx); | 268 | DEBUG("FB[0x%02X]", idx); |
268 | printk(KERN_INFO "FB access is not implemented.\n"); | 269 | break; |
269 | return 0; | ||
270 | case ATOM_ARG_IMM: | 270 | case ATOM_ARG_IMM: |
271 | switch (align) { | 271 | switch (align) { |
272 | case ATOM_SRC_DWORD: | 272 | case ATOM_SRC_DWORD: |
@@ -488,9 +488,9 @@ static void atom_put_dst(atom_exec_context *ctx, int arg, uint8_t attr, | |||
488 | case ATOM_ARG_FB: | 488 | case ATOM_ARG_FB: |
489 | idx = U8(*ptr); | 489 | idx = U8(*ptr); |
490 | (*ptr)++; | 490 | (*ptr)++; |
491 | gctx->scratch[((gctx->fb_base + idx) / 4)] = val; | ||
491 | DEBUG("FB[0x%02X]", idx); | 492 | DEBUG("FB[0x%02X]", idx); |
492 | printk(KERN_INFO "FB access is not implemented.\n"); | 493 | break; |
493 | return; | ||
494 | case ATOM_ARG_PLL: | 494 | case ATOM_ARG_PLL: |
495 | idx = U8(*ptr); | 495 | idx = U8(*ptr); |
496 | (*ptr)++; | 496 | (*ptr)++; |
@@ -1214,3 +1214,28 @@ void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev, | |||
1214 | *crev = CU8(idx + 3); | 1214 | *crev = CU8(idx + 3); |
1215 | return; | 1215 | return; |
1216 | } | 1216 | } |
1217 | |||
1218 | int atom_allocate_fb_scratch(struct atom_context *ctx) | ||
1219 | { | ||
1220 | int index = GetIndexIntoMasterTable(DATA, VRAM_UsageByFirmware); | ||
1221 | uint16_t data_offset; | ||
1222 | int usage_bytes; | ||
1223 | struct _ATOM_VRAM_USAGE_BY_FIRMWARE *firmware_usage; | ||
1224 | |||
1225 | atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset); | ||
1226 | |||
1227 | firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset); | ||
1228 | |||
1229 | DRM_DEBUG("atom firmware requested %08x %dkb\n", | ||
1230 | firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware, | ||
1231 | firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb); | ||
1232 | |||
1233 | usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024; | ||
1234 | if (usage_bytes == 0) | ||
1235 | usage_bytes = 20 * 1024; | ||
1236 | /* allocate some scratch memory */ | ||
1237 | ctx->scratch = kzalloc(usage_bytes, GFP_KERNEL); | ||
1238 | if (!ctx->scratch) | ||
1239 | return -ENOMEM; | ||
1240 | return 0; | ||
1241 | } | ||
diff --git a/drivers/gpu/drm/radeon/atom.h b/drivers/gpu/drm/radeon/atom.h index e6eb38f2bcae..6671848e5ea1 100644 --- a/drivers/gpu/drm/radeon/atom.h +++ b/drivers/gpu/drm/radeon/atom.h | |||
@@ -132,6 +132,7 @@ struct atom_context { | |||
132 | uint8_t shift; | 132 | uint8_t shift; |
133 | int cs_equal, cs_above; | 133 | int cs_equal, cs_above; |
134 | int io_mode; | 134 | int io_mode; |
135 | uint32_t *scratch; | ||
135 | }; | 136 | }; |
136 | 137 | ||
137 | extern int atom_debug; | 138 | extern int atom_debug; |
@@ -142,6 +143,7 @@ int atom_asic_init(struct atom_context *); | |||
142 | void atom_destroy(struct atom_context *); | 143 | void atom_destroy(struct atom_context *); |
143 | void atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, uint8_t *frev, uint8_t *crev, uint16_t *data_start); | 144 | void atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, uint8_t *frev, uint8_t *crev, uint16_t *data_start); |
144 | void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t *frev, uint8_t *crev); | 145 | void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t *frev, uint8_t *crev); |
146 | int atom_allocate_fb_scratch(struct atom_context *ctx); | ||
145 | #include "atom-types.h" | 147 | #include "atom-types.h" |
146 | #include "atombios.h" | 148 | #include "atombios.h" |
147 | #include "ObjectID.h" | 149 | #include "ObjectID.h" |
diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h index c11ddddfb3b6..e83927644de4 100644 --- a/drivers/gpu/drm/radeon/atombios.h +++ b/drivers/gpu/drm/radeon/atombios.h | |||
@@ -2680,7 +2680,7 @@ typedef struct _ATOM_I2C_RECORD { | |||
2680 | typedef struct _ATOM_HPD_INT_RECORD { | 2680 | typedef struct _ATOM_HPD_INT_RECORD { |
2681 | ATOM_COMMON_RECORD_HEADER sheader; | 2681 | ATOM_COMMON_RECORD_HEADER sheader; |
2682 | UCHAR ucHPDIntGPIOID; /* Corresponding block in GPIO_PIN_INFO table gives the pin info */ | 2682 | UCHAR ucHPDIntGPIOID; /* Corresponding block in GPIO_PIN_INFO table gives the pin info */ |
2683 | UCHAR ucPluggged_PinState; | 2683 | UCHAR ucPlugged_PinState; |
2684 | } ATOM_HPD_INT_RECORD; | 2684 | } ATOM_HPD_INT_RECORD; |
2685 | 2685 | ||
2686 | typedef struct _ATOM_OUTPUT_PROTECTION_RECORD { | 2686 | typedef struct _ATOM_OUTPUT_PROTECTION_RECORD { |
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c new file mode 100644 index 000000000000..0d63c4436e7c --- /dev/null +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
@@ -0,0 +1,790 @@ | |||
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 | */ | ||
26 | #include "drmP.h" | ||
27 | #include "radeon_drm.h" | ||
28 | #include "radeon.h" | ||
29 | |||
30 | #include "atom.h" | ||
31 | #include "atom-bits.h" | ||
32 | #include "drm_dp_helper.h" | ||
33 | |||
34 | /* move these to drm_dp_helper.c/h */ | ||
35 | #define DP_LINK_CONFIGURATION_SIZE 9 | ||
36 | #define DP_LINK_STATUS_SIZE 6 | ||
37 | #define DP_DPCD_SIZE 8 | ||
38 | |||
39 | static char *voltage_names[] = { | ||
40 | "0.4V", "0.6V", "0.8V", "1.2V" | ||
41 | }; | ||
42 | static char *pre_emph_names[] = { | ||
43 | "0dB", "3.5dB", "6dB", "9.5dB" | ||
44 | }; | ||
45 | |||
46 | static const int dp_clocks[] = { | ||
47 | 54000, /* 1 lane, 1.62 Ghz */ | ||
48 | 90000, /* 1 lane, 2.70 Ghz */ | ||
49 | 108000, /* 2 lane, 1.62 Ghz */ | ||
50 | 180000, /* 2 lane, 2.70 Ghz */ | ||
51 | 216000, /* 4 lane, 1.62 Ghz */ | ||
52 | 360000, /* 4 lane, 2.70 Ghz */ | ||
53 | }; | ||
54 | |||
55 | static const int num_dp_clocks = sizeof(dp_clocks) / sizeof(int); | ||
56 | |||
57 | /* common helper functions */ | ||
58 | static int dp_lanes_for_mode_clock(u8 dpcd[DP_DPCD_SIZE], int mode_clock) | ||
59 | { | ||
60 | int i; | ||
61 | u8 max_link_bw; | ||
62 | u8 max_lane_count; | ||
63 | |||
64 | if (!dpcd) | ||
65 | return 0; | ||
66 | |||
67 | max_link_bw = dpcd[DP_MAX_LINK_RATE]; | ||
68 | max_lane_count = dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK; | ||
69 | |||
70 | switch (max_link_bw) { | ||
71 | case DP_LINK_BW_1_62: | ||
72 | default: | ||
73 | for (i = 0; i < num_dp_clocks; i++) { | ||
74 | if (i % 2) | ||
75 | continue; | ||
76 | switch (max_lane_count) { | ||
77 | case 1: | ||
78 | if (i > 1) | ||
79 | return 0; | ||
80 | break; | ||
81 | case 2: | ||
82 | if (i > 3) | ||
83 | return 0; | ||
84 | break; | ||
85 | case 4: | ||
86 | default: | ||
87 | break; | ||
88 | } | ||
89 | if (dp_clocks[i] > mode_clock) { | ||
90 | if (i < 2) | ||
91 | return 1; | ||
92 | else if (i < 4) | ||
93 | return 2; | ||
94 | else | ||
95 | return 4; | ||
96 | } | ||
97 | } | ||
98 | break; | ||
99 | case DP_LINK_BW_2_7: | ||
100 | for (i = 0; i < num_dp_clocks; i++) { | ||
101 | switch (max_lane_count) { | ||
102 | case 1: | ||
103 | if (i > 1) | ||
104 | return 0; | ||
105 | break; | ||
106 | case 2: | ||
107 | if (i > 3) | ||
108 | return 0; | ||
109 | break; | ||
110 | case 4: | ||
111 | default: | ||
112 | break; | ||
113 | } | ||
114 | if (dp_clocks[i] > mode_clock) { | ||
115 | if (i < 2) | ||
116 | return 1; | ||
117 | else if (i < 4) | ||
118 | return 2; | ||
119 | else | ||
120 | return 4; | ||
121 | } | ||
122 | } | ||
123 | break; | ||
124 | } | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int dp_link_clock_for_mode_clock(u8 dpcd[DP_DPCD_SIZE], int mode_clock) | ||
130 | { | ||
131 | int i; | ||
132 | u8 max_link_bw; | ||
133 | u8 max_lane_count; | ||
134 | |||
135 | if (!dpcd) | ||
136 | return 0; | ||
137 | |||
138 | max_link_bw = dpcd[DP_MAX_LINK_RATE]; | ||
139 | max_lane_count = dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK; | ||
140 | |||
141 | switch (max_link_bw) { | ||
142 | case DP_LINK_BW_1_62: | ||
143 | default: | ||
144 | for (i = 0; i < num_dp_clocks; i++) { | ||
145 | if (i % 2) | ||
146 | continue; | ||
147 | switch (max_lane_count) { | ||
148 | case 1: | ||
149 | if (i > 1) | ||
150 | return 0; | ||
151 | break; | ||
152 | case 2: | ||
153 | if (i > 3) | ||
154 | return 0; | ||
155 | break; | ||
156 | case 4: | ||
157 | default: | ||
158 | break; | ||
159 | } | ||
160 | if (dp_clocks[i] > mode_clock) | ||
161 | return 162000; | ||
162 | } | ||
163 | break; | ||
164 | case DP_LINK_BW_2_7: | ||
165 | for (i = 0; i < num_dp_clocks; i++) { | ||
166 | switch (max_lane_count) { | ||
167 | case 1: | ||
168 | if (i > 1) | ||
169 | return 0; | ||
170 | break; | ||
171 | case 2: | ||
172 | if (i > 3) | ||
173 | return 0; | ||
174 | break; | ||
175 | case 4: | ||
176 | default: | ||
177 | break; | ||
178 | } | ||
179 | if (dp_clocks[i] > mode_clock) | ||
180 | return (i % 2) ? 270000 : 162000; | ||
181 | } | ||
182 | } | ||
183 | |||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | int dp_mode_valid(u8 dpcd[DP_DPCD_SIZE], int mode_clock) | ||
188 | { | ||
189 | int lanes = dp_lanes_for_mode_clock(dpcd, mode_clock); | ||
190 | int bw = dp_lanes_for_mode_clock(dpcd, mode_clock); | ||
191 | |||
192 | if ((lanes == 0) || (bw == 0)) | ||
193 | return MODE_CLOCK_HIGH; | ||
194 | |||
195 | return MODE_OK; | ||
196 | } | ||
197 | |||
198 | static u8 dp_link_status(u8 link_status[DP_LINK_STATUS_SIZE], int r) | ||
199 | { | ||
200 | return link_status[r - DP_LANE0_1_STATUS]; | ||
201 | } | ||
202 | |||
203 | static u8 dp_get_lane_status(u8 link_status[DP_LINK_STATUS_SIZE], | ||
204 | int lane) | ||
205 | { | ||
206 | int i = DP_LANE0_1_STATUS + (lane >> 1); | ||
207 | int s = (lane & 1) * 4; | ||
208 | u8 l = dp_link_status(link_status, i); | ||
209 | return (l >> s) & 0xf; | ||
210 | } | ||
211 | |||
212 | static bool dp_clock_recovery_ok(u8 link_status[DP_LINK_STATUS_SIZE], | ||
213 | int lane_count) | ||
214 | { | ||
215 | int lane; | ||
216 | u8 lane_status; | ||
217 | |||
218 | for (lane = 0; lane < lane_count; lane++) { | ||
219 | lane_status = dp_get_lane_status(link_status, lane); | ||
220 | if ((lane_status & DP_LANE_CR_DONE) == 0) | ||
221 | return false; | ||
222 | } | ||
223 | return true; | ||
224 | } | ||
225 | |||
226 | static bool dp_channel_eq_ok(u8 link_status[DP_LINK_STATUS_SIZE], | ||
227 | int lane_count) | ||
228 | { | ||
229 | u8 lane_align; | ||
230 | u8 lane_status; | ||
231 | int lane; | ||
232 | |||
233 | lane_align = dp_link_status(link_status, | ||
234 | DP_LANE_ALIGN_STATUS_UPDATED); | ||
235 | if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0) | ||
236 | return false; | ||
237 | for (lane = 0; lane < lane_count; lane++) { | ||
238 | lane_status = dp_get_lane_status(link_status, lane); | ||
239 | if ((lane_status & DP_CHANNEL_EQ_BITS) != DP_CHANNEL_EQ_BITS) | ||
240 | return false; | ||
241 | } | ||
242 | return true; | ||
243 | } | ||
244 | |||
245 | static u8 dp_get_adjust_request_voltage(uint8_t link_status[DP_LINK_STATUS_SIZE], | ||
246 | int lane) | ||
247 | |||
248 | { | ||
249 | int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); | ||
250 | int s = ((lane & 1) ? | ||
251 | DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT : | ||
252 | DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT); | ||
253 | u8 l = dp_link_status(link_status, i); | ||
254 | |||
255 | return ((l >> s) & 0x3) << DP_TRAIN_VOLTAGE_SWING_SHIFT; | ||
256 | } | ||
257 | |||
258 | static u8 dp_get_adjust_request_pre_emphasis(uint8_t link_status[DP_LINK_STATUS_SIZE], | ||
259 | int lane) | ||
260 | { | ||
261 | int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); | ||
262 | int s = ((lane & 1) ? | ||
263 | DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT : | ||
264 | DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT); | ||
265 | u8 l = dp_link_status(link_status, i); | ||
266 | |||
267 | return ((l >> s) & 0x3) << DP_TRAIN_PRE_EMPHASIS_SHIFT; | ||
268 | } | ||
269 | |||
270 | /* XXX fix me -- chip specific */ | ||
271 | #define DP_VOLTAGE_MAX DP_TRAIN_VOLTAGE_SWING_1200 | ||
272 | static u8 dp_pre_emphasis_max(u8 voltage_swing) | ||
273 | { | ||
274 | switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) { | ||
275 | case DP_TRAIN_VOLTAGE_SWING_400: | ||
276 | return DP_TRAIN_PRE_EMPHASIS_6; | ||
277 | case DP_TRAIN_VOLTAGE_SWING_600: | ||
278 | return DP_TRAIN_PRE_EMPHASIS_6; | ||
279 | case DP_TRAIN_VOLTAGE_SWING_800: | ||
280 | return DP_TRAIN_PRE_EMPHASIS_3_5; | ||
281 | case DP_TRAIN_VOLTAGE_SWING_1200: | ||
282 | default: | ||
283 | return DP_TRAIN_PRE_EMPHASIS_0; | ||
284 | } | ||
285 | } | ||
286 | |||
287 | static void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE], | ||
288 | int lane_count, | ||
289 | u8 train_set[4]) | ||
290 | { | ||
291 | u8 v = 0; | ||
292 | u8 p = 0; | ||
293 | int lane; | ||
294 | |||
295 | for (lane = 0; lane < lane_count; lane++) { | ||
296 | u8 this_v = dp_get_adjust_request_voltage(link_status, lane); | ||
297 | u8 this_p = dp_get_adjust_request_pre_emphasis(link_status, lane); | ||
298 | |||
299 | DRM_DEBUG("requested signal parameters: lane %d voltage %s pre_emph %s\n", | ||
300 | lane, | ||
301 | voltage_names[this_v >> DP_TRAIN_VOLTAGE_SWING_SHIFT], | ||
302 | pre_emph_names[this_p >> DP_TRAIN_PRE_EMPHASIS_SHIFT]); | ||
303 | |||
304 | if (this_v > v) | ||
305 | v = this_v; | ||
306 | if (this_p > p) | ||
307 | p = this_p; | ||
308 | } | ||
309 | |||
310 | if (v >= DP_VOLTAGE_MAX) | ||
311 | v = DP_VOLTAGE_MAX | DP_TRAIN_MAX_SWING_REACHED; | ||
312 | |||
313 | if (p >= dp_pre_emphasis_max(v)) | ||
314 | p = dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; | ||
315 | |||
316 | DRM_DEBUG("using signal parameters: voltage %s pre_emph %s\n", | ||
317 | voltage_names[(v & DP_TRAIN_VOLTAGE_SWING_MASK) >> DP_TRAIN_VOLTAGE_SWING_SHIFT], | ||
318 | pre_emph_names[(p & DP_TRAIN_PRE_EMPHASIS_MASK) >> DP_TRAIN_PRE_EMPHASIS_SHIFT]); | ||
319 | |||
320 | for (lane = 0; lane < 4; lane++) | ||
321 | train_set[lane] = v | p; | ||
322 | } | ||
323 | |||
324 | |||
325 | /* radeon aux chan functions */ | ||
326 | bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes, | ||
327 | int num_bytes, u8 *read_byte, | ||
328 | u8 read_buf_len, u8 delay) | ||
329 | { | ||
330 | struct drm_device *dev = chan->dev; | ||
331 | struct radeon_device *rdev = dev->dev_private; | ||
332 | PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION args; | ||
333 | int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction); | ||
334 | unsigned char *base; | ||
335 | |||
336 | memset(&args, 0, sizeof(args)); | ||
337 | |||
338 | base = (unsigned char *)rdev->mode_info.atom_context->scratch; | ||
339 | |||
340 | memcpy(base, req_bytes, num_bytes); | ||
341 | |||
342 | args.lpAuxRequest = 0; | ||
343 | args.lpDataOut = 16; | ||
344 | args.ucDataOutLen = 0; | ||
345 | args.ucChannelID = chan->rec.i2c_id; | ||
346 | args.ucDelay = delay / 10; | ||
347 | |||
348 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
349 | |||
350 | if (args.ucReplyStatus) { | ||
351 | DRM_DEBUG("failed to get auxch %02x%02x %02x %02x 0x%02x %02x\n", | ||
352 | req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3], | ||
353 | chan->rec.i2c_id, args.ucReplyStatus); | ||
354 | return false; | ||
355 | } | ||
356 | |||
357 | if (args.ucDataOutLen && read_byte && read_buf_len) { | ||
358 | if (read_buf_len < args.ucDataOutLen) { | ||
359 | DRM_ERROR("Buffer to small for return answer %d %d\n", | ||
360 | read_buf_len, args.ucDataOutLen); | ||
361 | return false; | ||
362 | } | ||
363 | { | ||
364 | int len = min(read_buf_len, args.ucDataOutLen); | ||
365 | memcpy(read_byte, base + 16, len); | ||
366 | } | ||
367 | } | ||
368 | return true; | ||
369 | } | ||
370 | |||
371 | bool radeon_dp_aux_native_write(struct radeon_connector *radeon_connector, uint16_t address, | ||
372 | uint8_t send_bytes, uint8_t *send) | ||
373 | { | ||
374 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; | ||
375 | u8 msg[20]; | ||
376 | u8 msg_len, dp_msg_len; | ||
377 | bool ret; | ||
378 | |||
379 | dp_msg_len = 4; | ||
380 | msg[0] = address; | ||
381 | msg[1] = address >> 8; | ||
382 | msg[2] = AUX_NATIVE_WRITE << 4; | ||
383 | dp_msg_len += send_bytes; | ||
384 | msg[3] = (dp_msg_len << 4) | (send_bytes - 1); | ||
385 | |||
386 | if (send_bytes > 16) | ||
387 | return false; | ||
388 | |||
389 | memcpy(&msg[4], send, send_bytes); | ||
390 | msg_len = 4 + send_bytes; | ||
391 | ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, msg, msg_len, NULL, 0, 0); | ||
392 | return ret; | ||
393 | } | ||
394 | |||
395 | bool radeon_dp_aux_native_read(struct radeon_connector *radeon_connector, uint16_t address, | ||
396 | uint8_t delay, uint8_t expected_bytes, | ||
397 | uint8_t *read_p) | ||
398 | { | ||
399 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; | ||
400 | u8 msg[20]; | ||
401 | u8 msg_len, dp_msg_len; | ||
402 | bool ret = false; | ||
403 | msg_len = 4; | ||
404 | dp_msg_len = 4; | ||
405 | msg[0] = address; | ||
406 | msg[1] = address >> 8; | ||
407 | msg[2] = AUX_NATIVE_READ << 4; | ||
408 | msg[3] = (dp_msg_len) << 4; | ||
409 | msg[3] |= expected_bytes - 1; | ||
410 | |||
411 | ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, msg, msg_len, read_p, expected_bytes, delay); | ||
412 | return ret; | ||
413 | } | ||
414 | |||
415 | /* radeon dp functions */ | ||
416 | static u8 radeon_dp_encoder_service(struct radeon_device *rdev, int action, int dp_clock, | ||
417 | uint8_t ucconfig, uint8_t lane_num) | ||
418 | { | ||
419 | DP_ENCODER_SERVICE_PARAMETERS args; | ||
420 | int index = GetIndexIntoMasterTable(COMMAND, DPEncoderService); | ||
421 | |||
422 | memset(&args, 0, sizeof(args)); | ||
423 | args.ucLinkClock = dp_clock / 10; | ||
424 | args.ucConfig = ucconfig; | ||
425 | args.ucAction = action; | ||
426 | args.ucLaneNum = lane_num; | ||
427 | args.ucStatus = 0; | ||
428 | |||
429 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
430 | return args.ucStatus; | ||
431 | } | ||
432 | |||
433 | u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector) | ||
434 | { | ||
435 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; | ||
436 | struct drm_device *dev = radeon_connector->base.dev; | ||
437 | struct radeon_device *rdev = dev->dev_private; | ||
438 | |||
439 | return radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_GET_SINK_TYPE, 0, | ||
440 | dig_connector->dp_i2c_bus->rec.i2c_id, 0); | ||
441 | } | ||
442 | |||
443 | bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector) | ||
444 | { | ||
445 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; | ||
446 | u8 msg[25]; | ||
447 | int ret; | ||
448 | |||
449 | ret = radeon_dp_aux_native_read(radeon_connector, DP_DPCD_REV, 0, 8, msg); | ||
450 | if (ret) { | ||
451 | memcpy(dig_connector->dpcd, msg, 8); | ||
452 | { | ||
453 | int i; | ||
454 | DRM_DEBUG("DPCD: "); | ||
455 | for (i = 0; i < 8; i++) | ||
456 | DRM_DEBUG("%02x ", msg[i]); | ||
457 | DRM_DEBUG("\n"); | ||
458 | } | ||
459 | return true; | ||
460 | } | ||
461 | dig_connector->dpcd[0] = 0; | ||
462 | return false; | ||
463 | } | ||
464 | |||
465 | void radeon_dp_set_link_config(struct drm_connector *connector, | ||
466 | struct drm_display_mode *mode) | ||
467 | { | ||
468 | struct radeon_connector *radeon_connector; | ||
469 | struct radeon_connector_atom_dig *dig_connector; | ||
470 | |||
471 | if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) | ||
472 | return; | ||
473 | |||
474 | radeon_connector = to_radeon_connector(connector); | ||
475 | if (!radeon_connector->con_priv) | ||
476 | return; | ||
477 | dig_connector = radeon_connector->con_priv; | ||
478 | |||
479 | dig_connector->dp_clock = | ||
480 | dp_link_clock_for_mode_clock(dig_connector->dpcd, mode->clock); | ||
481 | dig_connector->dp_lane_count = | ||
482 | dp_lanes_for_mode_clock(dig_connector->dpcd, mode->clock); | ||
483 | } | ||
484 | |||
485 | int radeon_dp_mode_valid_helper(struct radeon_connector *radeon_connector, | ||
486 | struct drm_display_mode *mode) | ||
487 | { | ||
488 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; | ||
489 | |||
490 | return dp_mode_valid(dig_connector->dpcd, mode->clock); | ||
491 | } | ||
492 | |||
493 | static bool atom_dp_get_link_status(struct radeon_connector *radeon_connector, | ||
494 | u8 link_status[DP_LINK_STATUS_SIZE]) | ||
495 | { | ||
496 | int ret; | ||
497 | ret = radeon_dp_aux_native_read(radeon_connector, DP_LANE0_1_STATUS, 100, | ||
498 | DP_LINK_STATUS_SIZE, link_status); | ||
499 | if (!ret) { | ||
500 | DRM_ERROR("displayport link status failed\n"); | ||
501 | return false; | ||
502 | } | ||
503 | |||
504 | DRM_DEBUG("link status %02x %02x %02x %02x %02x %02x\n", | ||
505 | link_status[0], link_status[1], link_status[2], | ||
506 | link_status[3], link_status[4], link_status[5]); | ||
507 | return true; | ||
508 | } | ||
509 | |||
510 | bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector) | ||
511 | { | ||
512 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; | ||
513 | u8 link_status[DP_LINK_STATUS_SIZE]; | ||
514 | |||
515 | if (!atom_dp_get_link_status(radeon_connector, link_status)) | ||
516 | return false; | ||
517 | if (dp_channel_eq_ok(link_status, dig_connector->dp_lane_count)) | ||
518 | return false; | ||
519 | return true; | ||
520 | } | ||
521 | |||
522 | static void dp_set_power(struct radeon_connector *radeon_connector, u8 power_state) | ||
523 | { | ||
524 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; | ||
525 | |||
526 | if (dig_connector->dpcd[0] >= 0x11) { | ||
527 | radeon_dp_aux_native_write(radeon_connector, DP_SET_POWER, 1, | ||
528 | &power_state); | ||
529 | } | ||
530 | } | ||
531 | |||
532 | static void dp_set_downspread(struct radeon_connector *radeon_connector, u8 downspread) | ||
533 | { | ||
534 | radeon_dp_aux_native_write(radeon_connector, DP_DOWNSPREAD_CTRL, 1, | ||
535 | &downspread); | ||
536 | } | ||
537 | |||
538 | static void dp_set_link_bw_lanes(struct radeon_connector *radeon_connector, | ||
539 | u8 link_configuration[DP_LINK_CONFIGURATION_SIZE]) | ||
540 | { | ||
541 | radeon_dp_aux_native_write(radeon_connector, DP_LINK_BW_SET, 2, | ||
542 | link_configuration); | ||
543 | } | ||
544 | |||
545 | static void dp_update_dpvs_emph(struct radeon_connector *radeon_connector, | ||
546 | struct drm_encoder *encoder, | ||
547 | u8 train_set[4]) | ||
548 | { | ||
549 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; | ||
550 | int i; | ||
551 | |||
552 | for (i = 0; i < dig_connector->dp_lane_count; i++) | ||
553 | atombios_dig_transmitter_setup(encoder, | ||
554 | ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH, | ||
555 | i, train_set[i]); | ||
556 | |||
557 | radeon_dp_aux_native_write(radeon_connector, DP_TRAINING_LANE0_SET, | ||
558 | dig_connector->dp_lane_count, train_set); | ||
559 | } | ||
560 | |||
561 | static void dp_set_training(struct radeon_connector *radeon_connector, | ||
562 | u8 training) | ||
563 | { | ||
564 | radeon_dp_aux_native_write(radeon_connector, DP_TRAINING_PATTERN_SET, | ||
565 | 1, &training); | ||
566 | } | ||
567 | |||
568 | void dp_link_train(struct drm_encoder *encoder, | ||
569 | struct drm_connector *connector) | ||
570 | { | ||
571 | struct drm_device *dev = encoder->dev; | ||
572 | struct radeon_device *rdev = dev->dev_private; | ||
573 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
574 | struct radeon_encoder_atom_dig *dig; | ||
575 | struct radeon_connector *radeon_connector; | ||
576 | struct radeon_connector_atom_dig *dig_connector; | ||
577 | int enc_id = 0; | ||
578 | bool clock_recovery, channel_eq; | ||
579 | u8 link_status[DP_LINK_STATUS_SIZE]; | ||
580 | u8 link_configuration[DP_LINK_CONFIGURATION_SIZE]; | ||
581 | u8 tries, voltage; | ||
582 | u8 train_set[4]; | ||
583 | int i; | ||
584 | |||
585 | if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) | ||
586 | return; | ||
587 | |||
588 | if (!radeon_encoder->enc_priv) | ||
589 | return; | ||
590 | dig = radeon_encoder->enc_priv; | ||
591 | |||
592 | radeon_connector = to_radeon_connector(connector); | ||
593 | if (!radeon_connector->con_priv) | ||
594 | return; | ||
595 | dig_connector = radeon_connector->con_priv; | ||
596 | |||
597 | if (ASIC_IS_DCE32(rdev)) { | ||
598 | if (dig->dig_block) | ||
599 | enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER; | ||
600 | else | ||
601 | enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER; | ||
602 | if (dig_connector->linkb) | ||
603 | enc_id |= ATOM_DP_CONFIG_LINK_B; | ||
604 | else | ||
605 | enc_id |= ATOM_DP_CONFIG_LINK_A; | ||
606 | } else { | ||
607 | if (dig_connector->linkb) | ||
608 | enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER | ATOM_DP_CONFIG_LINK_B; | ||
609 | else | ||
610 | enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER | ATOM_DP_CONFIG_LINK_A; | ||
611 | } | ||
612 | |||
613 | memset(link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); | ||
614 | if (dig_connector->dp_clock == 270000) | ||
615 | link_configuration[0] = DP_LINK_BW_2_7; | ||
616 | else | ||
617 | link_configuration[0] = DP_LINK_BW_1_62; | ||
618 | link_configuration[1] = dig_connector->dp_lane_count; | ||
619 | if (dig_connector->dpcd[0] >= 0x11) | ||
620 | link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; | ||
621 | |||
622 | /* power up the sink */ | ||
623 | dp_set_power(radeon_connector, DP_SET_POWER_D0); | ||
624 | /* disable the training pattern on the sink */ | ||
625 | dp_set_training(radeon_connector, DP_TRAINING_PATTERN_DISABLE); | ||
626 | /* set link bw and lanes on the sink */ | ||
627 | dp_set_link_bw_lanes(radeon_connector, link_configuration); | ||
628 | /* disable downspread on the sink */ | ||
629 | dp_set_downspread(radeon_connector, 0); | ||
630 | /* start training on the source */ | ||
631 | radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_START, | ||
632 | dig_connector->dp_clock, enc_id, 0); | ||
633 | /* set training pattern 1 on the source */ | ||
634 | radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL, | ||
635 | dig_connector->dp_clock, enc_id, 0); | ||
636 | |||
637 | /* set initial vs/emph */ | ||
638 | memset(train_set, 0, 4); | ||
639 | udelay(400); | ||
640 | /* set training pattern 1 on the sink */ | ||
641 | dp_set_training(radeon_connector, DP_TRAINING_PATTERN_1); | ||
642 | |||
643 | dp_update_dpvs_emph(radeon_connector, encoder, train_set); | ||
644 | |||
645 | /* clock recovery loop */ | ||
646 | clock_recovery = false; | ||
647 | tries = 0; | ||
648 | voltage = 0xff; | ||
649 | for (;;) { | ||
650 | udelay(100); | ||
651 | if (!atom_dp_get_link_status(radeon_connector, link_status)) | ||
652 | break; | ||
653 | |||
654 | if (dp_clock_recovery_ok(link_status, dig_connector->dp_lane_count)) { | ||
655 | clock_recovery = true; | ||
656 | break; | ||
657 | } | ||
658 | |||
659 | for (i = 0; i < dig_connector->dp_lane_count; i++) { | ||
660 | if ((train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) | ||
661 | break; | ||
662 | } | ||
663 | if (i == dig_connector->dp_lane_count) { | ||
664 | DRM_ERROR("clock recovery reached max voltage\n"); | ||
665 | break; | ||
666 | } | ||
667 | |||
668 | if ((train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) { | ||
669 | ++tries; | ||
670 | if (tries == 5) { | ||
671 | DRM_ERROR("clock recovery tried 5 times\n"); | ||
672 | break; | ||
673 | } | ||
674 | } else | ||
675 | tries = 0; | ||
676 | |||
677 | voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; | ||
678 | |||
679 | /* Compute new train_set as requested by sink */ | ||
680 | dp_get_adjust_train(link_status, dig_connector->dp_lane_count, train_set); | ||
681 | dp_update_dpvs_emph(radeon_connector, encoder, train_set); | ||
682 | } | ||
683 | if (!clock_recovery) | ||
684 | DRM_ERROR("clock recovery failed\n"); | ||
685 | else | ||
686 | DRM_DEBUG("clock recovery at voltage %d pre-emphasis %d\n", | ||
687 | train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK, | ||
688 | (train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK) >> | ||
689 | DP_TRAIN_PRE_EMPHASIS_SHIFT); | ||
690 | |||
691 | |||
692 | /* set training pattern 2 on the sink */ | ||
693 | dp_set_training(radeon_connector, DP_TRAINING_PATTERN_2); | ||
694 | /* set training pattern 2 on the source */ | ||
695 | radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL, | ||
696 | dig_connector->dp_clock, enc_id, 1); | ||
697 | |||
698 | /* channel equalization loop */ | ||
699 | tries = 0; | ||
700 | channel_eq = false; | ||
701 | for (;;) { | ||
702 | udelay(400); | ||
703 | if (!atom_dp_get_link_status(radeon_connector, link_status)) | ||
704 | break; | ||
705 | |||
706 | if (dp_channel_eq_ok(link_status, dig_connector->dp_lane_count)) { | ||
707 | channel_eq = true; | ||
708 | break; | ||
709 | } | ||
710 | |||
711 | /* Try 5 times */ | ||
712 | if (tries > 5) { | ||
713 | DRM_ERROR("channel eq failed: 5 tries\n"); | ||
714 | break; | ||
715 | } | ||
716 | |||
717 | /* Compute new train_set as requested by sink */ | ||
718 | dp_get_adjust_train(link_status, dig_connector->dp_lane_count, train_set); | ||
719 | dp_update_dpvs_emph(radeon_connector, encoder, train_set); | ||
720 | |||
721 | tries++; | ||
722 | } | ||
723 | |||
724 | if (!channel_eq) | ||
725 | DRM_ERROR("channel eq failed\n"); | ||
726 | else | ||
727 | DRM_DEBUG("channel eq at voltage %d pre-emphasis %d\n", | ||
728 | train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK, | ||
729 | (train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK) | ||
730 | >> DP_TRAIN_PRE_EMPHASIS_SHIFT); | ||
731 | |||
732 | /* disable the training pattern on the sink */ | ||
733 | dp_set_training(radeon_connector, DP_TRAINING_PATTERN_DISABLE); | ||
734 | |||
735 | radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE, | ||
736 | dig_connector->dp_clock, enc_id, 0); | ||
737 | } | ||
738 | |||
739 | int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | ||
740 | uint8_t write_byte, uint8_t *read_byte) | ||
741 | { | ||
742 | struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; | ||
743 | struct radeon_i2c_chan *auxch = (struct radeon_i2c_chan *)adapter; | ||
744 | int ret = 0; | ||
745 | uint16_t address = algo_data->address; | ||
746 | uint8_t msg[5]; | ||
747 | uint8_t reply[2]; | ||
748 | int msg_len, dp_msg_len; | ||
749 | int reply_bytes; | ||
750 | |||
751 | /* Set up the command byte */ | ||
752 | if (mode & MODE_I2C_READ) | ||
753 | msg[2] = AUX_I2C_READ << 4; | ||
754 | else | ||
755 | msg[2] = AUX_I2C_WRITE << 4; | ||
756 | |||
757 | if (!(mode & MODE_I2C_STOP)) | ||
758 | msg[2] |= AUX_I2C_MOT << 4; | ||
759 | |||
760 | msg[0] = address; | ||
761 | msg[1] = address >> 8; | ||
762 | |||
763 | reply_bytes = 1; | ||
764 | |||
765 | msg_len = 4; | ||
766 | dp_msg_len = 3; | ||
767 | switch (mode) { | ||
768 | case MODE_I2C_WRITE: | ||
769 | msg[4] = write_byte; | ||
770 | msg_len++; | ||
771 | dp_msg_len += 2; | ||
772 | break; | ||
773 | case MODE_I2C_READ: | ||
774 | dp_msg_len += 1; | ||
775 | break; | ||
776 | default: | ||
777 | break; | ||
778 | } | ||
779 | |||
780 | msg[3] = (dp_msg_len) << 4; | ||
781 | ret = radeon_process_aux_ch(auxch, msg, msg_len, reply, reply_bytes, 0); | ||
782 | |||
783 | if (ret) { | ||
784 | if (read_byte) | ||
785 | *read_byte = reply[0]; | ||
786 | return reply_bytes; | ||
787 | } | ||
788 | return -EREMOTEIO; | ||
789 | } | ||
790 | |||
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 109096802e66..b7baf16c11d7 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -65,6 +65,95 @@ MODULE_FIRMWARE(FIRMWARE_R520); | |||
65 | * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 | 65 | * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 |
66 | */ | 66 | */ |
67 | 67 | ||
68 | /* hpd for digital panel detect/disconnect */ | ||
69 | bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) | ||
70 | { | ||
71 | bool connected = false; | ||
72 | |||
73 | switch (hpd) { | ||
74 | case RADEON_HPD_1: | ||
75 | if (RREG32(RADEON_FP_GEN_CNTL) & RADEON_FP_DETECT_SENSE) | ||
76 | connected = true; | ||
77 | break; | ||
78 | case RADEON_HPD_2: | ||
79 | if (RREG32(RADEON_FP2_GEN_CNTL) & RADEON_FP2_DETECT_SENSE) | ||
80 | connected = true; | ||
81 | break; | ||
82 | default: | ||
83 | break; | ||
84 | } | ||
85 | return connected; | ||
86 | } | ||
87 | |||
88 | void r100_hpd_set_polarity(struct radeon_device *rdev, | ||
89 | enum radeon_hpd_id hpd) | ||
90 | { | ||
91 | u32 tmp; | ||
92 | bool connected = r100_hpd_sense(rdev, hpd); | ||
93 | |||
94 | switch (hpd) { | ||
95 | case RADEON_HPD_1: | ||
96 | tmp = RREG32(RADEON_FP_GEN_CNTL); | ||
97 | if (connected) | ||
98 | tmp &= ~RADEON_FP_DETECT_INT_POL; | ||
99 | else | ||
100 | tmp |= RADEON_FP_DETECT_INT_POL; | ||
101 | WREG32(RADEON_FP_GEN_CNTL, tmp); | ||
102 | break; | ||
103 | case RADEON_HPD_2: | ||
104 | tmp = RREG32(RADEON_FP2_GEN_CNTL); | ||
105 | if (connected) | ||
106 | tmp &= ~RADEON_FP2_DETECT_INT_POL; | ||
107 | else | ||
108 | tmp |= RADEON_FP2_DETECT_INT_POL; | ||
109 | WREG32(RADEON_FP2_GEN_CNTL, tmp); | ||
110 | break; | ||
111 | default: | ||
112 | break; | ||
113 | } | ||
114 | } | ||
115 | |||
116 | void r100_hpd_init(struct radeon_device *rdev) | ||
117 | { | ||
118 | struct drm_device *dev = rdev->ddev; | ||
119 | struct drm_connector *connector; | ||
120 | |||
121 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
122 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
123 | switch (radeon_connector->hpd.hpd) { | ||
124 | case RADEON_HPD_1: | ||
125 | rdev->irq.hpd[0] = true; | ||
126 | break; | ||
127 | case RADEON_HPD_2: | ||
128 | rdev->irq.hpd[1] = true; | ||
129 | break; | ||
130 | default: | ||
131 | break; | ||
132 | } | ||
133 | } | ||
134 | r100_irq_set(rdev); | ||
135 | } | ||
136 | |||
137 | void r100_hpd_fini(struct radeon_device *rdev) | ||
138 | { | ||
139 | struct drm_device *dev = rdev->ddev; | ||
140 | struct drm_connector *connector; | ||
141 | |||
142 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
143 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
144 | switch (radeon_connector->hpd.hpd) { | ||
145 | case RADEON_HPD_1: | ||
146 | rdev->irq.hpd[0] = false; | ||
147 | break; | ||
148 | case RADEON_HPD_2: | ||
149 | rdev->irq.hpd[1] = false; | ||
150 | break; | ||
151 | default: | ||
152 | break; | ||
153 | } | ||
154 | } | ||
155 | } | ||
156 | |||
68 | /* | 157 | /* |
69 | * PCI GART | 158 | * PCI GART |
70 | */ | 159 | */ |
@@ -163,6 +252,12 @@ int r100_irq_set(struct radeon_device *rdev) | |||
163 | if (rdev->irq.crtc_vblank_int[1]) { | 252 | if (rdev->irq.crtc_vblank_int[1]) { |
164 | tmp |= RADEON_CRTC2_VBLANK_MASK; | 253 | tmp |= RADEON_CRTC2_VBLANK_MASK; |
165 | } | 254 | } |
255 | if (rdev->irq.hpd[0]) { | ||
256 | tmp |= RADEON_FP_DETECT_MASK; | ||
257 | } | ||
258 | if (rdev->irq.hpd[1]) { | ||
259 | tmp |= RADEON_FP2_DETECT_MASK; | ||
260 | } | ||
166 | WREG32(RADEON_GEN_INT_CNTL, tmp); | 261 | WREG32(RADEON_GEN_INT_CNTL, tmp); |
167 | return 0; | 262 | return 0; |
168 | } | 263 | } |
@@ -181,8 +276,9 @@ void r100_irq_disable(struct radeon_device *rdev) | |||
181 | static inline uint32_t r100_irq_ack(struct radeon_device *rdev) | 276 | static inline uint32_t r100_irq_ack(struct radeon_device *rdev) |
182 | { | 277 | { |
183 | uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS); | 278 | uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS); |
184 | uint32_t irq_mask = RADEON_SW_INT_TEST | RADEON_CRTC_VBLANK_STAT | | 279 | uint32_t irq_mask = RADEON_SW_INT_TEST | |
185 | RADEON_CRTC2_VBLANK_STAT; | 280 | RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT | |
281 | RADEON_FP_DETECT_STAT | RADEON_FP2_DETECT_STAT; | ||
186 | 282 | ||
187 | if (irqs) { | 283 | if (irqs) { |
188 | WREG32(RADEON_GEN_INT_STATUS, irqs); | 284 | WREG32(RADEON_GEN_INT_STATUS, irqs); |
@@ -193,6 +289,7 @@ static inline uint32_t r100_irq_ack(struct radeon_device *rdev) | |||
193 | int r100_irq_process(struct radeon_device *rdev) | 289 | int r100_irq_process(struct radeon_device *rdev) |
194 | { | 290 | { |
195 | uint32_t status, msi_rearm; | 291 | uint32_t status, msi_rearm; |
292 | bool queue_hotplug = false; | ||
196 | 293 | ||
197 | status = r100_irq_ack(rdev); | 294 | status = r100_irq_ack(rdev); |
198 | if (!status) { | 295 | if (!status) { |
@@ -213,8 +310,18 @@ int r100_irq_process(struct radeon_device *rdev) | |||
213 | if (status & RADEON_CRTC2_VBLANK_STAT) { | 310 | if (status & RADEON_CRTC2_VBLANK_STAT) { |
214 | drm_handle_vblank(rdev->ddev, 1); | 311 | drm_handle_vblank(rdev->ddev, 1); |
215 | } | 312 | } |
313 | if (status & RADEON_FP_DETECT_STAT) { | ||
314 | queue_hotplug = true; | ||
315 | DRM_DEBUG("HPD1\n"); | ||
316 | } | ||
317 | if (status & RADEON_FP2_DETECT_STAT) { | ||
318 | queue_hotplug = true; | ||
319 | DRM_DEBUG("HPD2\n"); | ||
320 | } | ||
216 | status = r100_irq_ack(rdev); | 321 | status = r100_irq_ack(rdev); |
217 | } | 322 | } |
323 | if (queue_hotplug) | ||
324 | queue_work(rdev->wq, &rdev->hotplug_work); | ||
218 | if (rdev->msi_enabled) { | 325 | if (rdev->msi_enabled) { |
219 | switch (rdev->family) { | 326 | switch (rdev->family) { |
220 | case CHIP_RS400: | 327 | case CHIP_RS400: |
diff --git a/drivers/gpu/drm/radeon/r500_reg.h b/drivers/gpu/drm/radeon/r500_reg.h index 7baa73955563..74ad89bdf2b5 100644 --- a/drivers/gpu/drm/radeon/r500_reg.h +++ b/drivers/gpu/drm/radeon/r500_reg.h | |||
@@ -716,6 +716,8 @@ | |||
716 | 716 | ||
717 | #define AVIVO_DVOA_BIT_DEPTH_CONTROL 0x7988 | 717 | #define AVIVO_DVOA_BIT_DEPTH_CONTROL 0x7988 |
718 | 718 | ||
719 | #define AVIVO_DC_GPIO_HPD_A 0x7e94 | ||
720 | |||
719 | #define AVIVO_GPIO_0 0x7e30 | 721 | #define AVIVO_GPIO_0 0x7e30 |
720 | #define AVIVO_GPIO_1 0x7e40 | 722 | #define AVIVO_GPIO_1 0x7e40 |
721 | #define AVIVO_GPIO_2 0x7e50 | 723 | #define AVIVO_GPIO_2 0x7e50 |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 94e7fd2f59e9..250ec3fe1a16 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -74,6 +74,281 @@ int r600_mc_wait_for_idle(struct radeon_device *rdev); | |||
74 | void r600_gpu_init(struct radeon_device *rdev); | 74 | void r600_gpu_init(struct radeon_device *rdev); |
75 | void r600_fini(struct radeon_device *rdev); | 75 | void r600_fini(struct radeon_device *rdev); |
76 | 76 | ||
77 | /* hpd for digital panel detect/disconnect */ | ||
78 | bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) | ||
79 | { | ||
80 | bool connected = false; | ||
81 | |||
82 | if (ASIC_IS_DCE3(rdev)) { | ||
83 | switch (hpd) { | ||
84 | case RADEON_HPD_1: | ||
85 | if (RREG32(DC_HPD1_INT_STATUS) & DC_HPDx_SENSE) | ||
86 | connected = true; | ||
87 | break; | ||
88 | case RADEON_HPD_2: | ||
89 | if (RREG32(DC_HPD2_INT_STATUS) & DC_HPDx_SENSE) | ||
90 | connected = true; | ||
91 | break; | ||
92 | case RADEON_HPD_3: | ||
93 | if (RREG32(DC_HPD3_INT_STATUS) & DC_HPDx_SENSE) | ||
94 | connected = true; | ||
95 | break; | ||
96 | case RADEON_HPD_4: | ||
97 | if (RREG32(DC_HPD4_INT_STATUS) & DC_HPDx_SENSE) | ||
98 | connected = true; | ||
99 | break; | ||
100 | /* DCE 3.2 */ | ||
101 | case RADEON_HPD_5: | ||
102 | if (RREG32(DC_HPD5_INT_STATUS) & DC_HPDx_SENSE) | ||
103 | connected = true; | ||
104 | break; | ||
105 | case RADEON_HPD_6: | ||
106 | if (RREG32(DC_HPD6_INT_STATUS) & DC_HPDx_SENSE) | ||
107 | connected = true; | ||
108 | break; | ||
109 | default: | ||
110 | break; | ||
111 | } | ||
112 | } else { | ||
113 | switch (hpd) { | ||
114 | case RADEON_HPD_1: | ||
115 | if (RREG32(DC_HOT_PLUG_DETECT1_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE) | ||
116 | connected = true; | ||
117 | break; | ||
118 | case RADEON_HPD_2: | ||
119 | if (RREG32(DC_HOT_PLUG_DETECT2_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE) | ||
120 | connected = true; | ||
121 | break; | ||
122 | case RADEON_HPD_3: | ||
123 | if (RREG32(DC_HOT_PLUG_DETECT3_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE) | ||
124 | connected = true; | ||
125 | break; | ||
126 | default: | ||
127 | break; | ||
128 | } | ||
129 | } | ||
130 | return connected; | ||
131 | } | ||
132 | |||
133 | void r600_hpd_set_polarity(struct radeon_device *rdev, | ||
134 | enum radeon_hpd_id hpd) | ||
135 | { | ||
136 | u32 tmp; | ||
137 | bool connected = r600_hpd_sense(rdev, hpd); | ||
138 | |||
139 | if (ASIC_IS_DCE3(rdev)) { | ||
140 | switch (hpd) { | ||
141 | case RADEON_HPD_1: | ||
142 | tmp = RREG32(DC_HPD1_INT_CONTROL); | ||
143 | if (connected) | ||
144 | tmp &= ~DC_HPDx_INT_POLARITY; | ||
145 | else | ||
146 | tmp |= DC_HPDx_INT_POLARITY; | ||
147 | WREG32(DC_HPD1_INT_CONTROL, tmp); | ||
148 | break; | ||
149 | case RADEON_HPD_2: | ||
150 | tmp = RREG32(DC_HPD2_INT_CONTROL); | ||
151 | if (connected) | ||
152 | tmp &= ~DC_HPDx_INT_POLARITY; | ||
153 | else | ||
154 | tmp |= DC_HPDx_INT_POLARITY; | ||
155 | WREG32(DC_HPD2_INT_CONTROL, tmp); | ||
156 | break; | ||
157 | case RADEON_HPD_3: | ||
158 | tmp = RREG32(DC_HPD3_INT_CONTROL); | ||
159 | if (connected) | ||
160 | tmp &= ~DC_HPDx_INT_POLARITY; | ||
161 | else | ||
162 | tmp |= DC_HPDx_INT_POLARITY; | ||
163 | WREG32(DC_HPD3_INT_CONTROL, tmp); | ||
164 | break; | ||
165 | case RADEON_HPD_4: | ||
166 | tmp = RREG32(DC_HPD4_INT_CONTROL); | ||
167 | if (connected) | ||
168 | tmp &= ~DC_HPDx_INT_POLARITY; | ||
169 | else | ||
170 | tmp |= DC_HPDx_INT_POLARITY; | ||
171 | WREG32(DC_HPD4_INT_CONTROL, tmp); | ||
172 | break; | ||
173 | case RADEON_HPD_5: | ||
174 | tmp = RREG32(DC_HPD5_INT_CONTROL); | ||
175 | if (connected) | ||
176 | tmp &= ~DC_HPDx_INT_POLARITY; | ||
177 | else | ||
178 | tmp |= DC_HPDx_INT_POLARITY; | ||
179 | WREG32(DC_HPD5_INT_CONTROL, tmp); | ||
180 | break; | ||
181 | /* DCE 3.2 */ | ||
182 | case RADEON_HPD_6: | ||
183 | tmp = RREG32(DC_HPD6_INT_CONTROL); | ||
184 | if (connected) | ||
185 | tmp &= ~DC_HPDx_INT_POLARITY; | ||
186 | else | ||
187 | tmp |= DC_HPDx_INT_POLARITY; | ||
188 | WREG32(DC_HPD6_INT_CONTROL, tmp); | ||
189 | break; | ||
190 | default: | ||
191 | break; | ||
192 | } | ||
193 | } else { | ||
194 | switch (hpd) { | ||
195 | case RADEON_HPD_1: | ||
196 | tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL); | ||
197 | if (connected) | ||
198 | tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
199 | else | ||
200 | tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
201 | WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); | ||
202 | break; | ||
203 | case RADEON_HPD_2: | ||
204 | tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL); | ||
205 | if (connected) | ||
206 | tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
207 | else | ||
208 | tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
209 | WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); | ||
210 | break; | ||
211 | case RADEON_HPD_3: | ||
212 | tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL); | ||
213 | if (connected) | ||
214 | tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
215 | else | ||
216 | tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
217 | WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp); | ||
218 | break; | ||
219 | default: | ||
220 | break; | ||
221 | } | ||
222 | } | ||
223 | } | ||
224 | |||
225 | void r600_hpd_init(struct radeon_device *rdev) | ||
226 | { | ||
227 | struct drm_device *dev = rdev->ddev; | ||
228 | struct drm_connector *connector; | ||
229 | |||
230 | if (ASIC_IS_DCE3(rdev)) { | ||
231 | u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) | DC_HPDx_RX_INT_TIMER(0xfa); | ||
232 | if (ASIC_IS_DCE32(rdev)) | ||
233 | tmp |= DC_HPDx_EN; | ||
234 | |||
235 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
236 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
237 | switch (radeon_connector->hpd.hpd) { | ||
238 | case RADEON_HPD_1: | ||
239 | WREG32(DC_HPD1_CONTROL, tmp); | ||
240 | rdev->irq.hpd[0] = true; | ||
241 | break; | ||
242 | case RADEON_HPD_2: | ||
243 | WREG32(DC_HPD2_CONTROL, tmp); | ||
244 | rdev->irq.hpd[1] = true; | ||
245 | break; | ||
246 | case RADEON_HPD_3: | ||
247 | WREG32(DC_HPD3_CONTROL, tmp); | ||
248 | rdev->irq.hpd[2] = true; | ||
249 | break; | ||
250 | case RADEON_HPD_4: | ||
251 | WREG32(DC_HPD4_CONTROL, tmp); | ||
252 | rdev->irq.hpd[3] = true; | ||
253 | break; | ||
254 | /* DCE 3.2 */ | ||
255 | case RADEON_HPD_5: | ||
256 | WREG32(DC_HPD5_CONTROL, tmp); | ||
257 | rdev->irq.hpd[4] = true; | ||
258 | break; | ||
259 | case RADEON_HPD_6: | ||
260 | WREG32(DC_HPD6_CONTROL, tmp); | ||
261 | rdev->irq.hpd[5] = true; | ||
262 | break; | ||
263 | default: | ||
264 | break; | ||
265 | } | ||
266 | } | ||
267 | } else { | ||
268 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
269 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
270 | switch (radeon_connector->hpd.hpd) { | ||
271 | case RADEON_HPD_1: | ||
272 | WREG32(DC_HOT_PLUG_DETECT1_CONTROL, DC_HOT_PLUG_DETECTx_EN); | ||
273 | rdev->irq.hpd[0] = true; | ||
274 | break; | ||
275 | case RADEON_HPD_2: | ||
276 | WREG32(DC_HOT_PLUG_DETECT2_CONTROL, DC_HOT_PLUG_DETECTx_EN); | ||
277 | rdev->irq.hpd[1] = true; | ||
278 | break; | ||
279 | case RADEON_HPD_3: | ||
280 | WREG32(DC_HOT_PLUG_DETECT3_CONTROL, DC_HOT_PLUG_DETECTx_EN); | ||
281 | rdev->irq.hpd[2] = true; | ||
282 | break; | ||
283 | default: | ||
284 | break; | ||
285 | } | ||
286 | } | ||
287 | } | ||
288 | r600_irq_set(rdev); | ||
289 | } | ||
290 | |||
291 | void r600_hpd_fini(struct radeon_device *rdev) | ||
292 | { | ||
293 | struct drm_device *dev = rdev->ddev; | ||
294 | struct drm_connector *connector; | ||
295 | |||
296 | if (ASIC_IS_DCE3(rdev)) { | ||
297 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
298 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
299 | switch (radeon_connector->hpd.hpd) { | ||
300 | case RADEON_HPD_1: | ||
301 | WREG32(DC_HPD1_CONTROL, 0); | ||
302 | rdev->irq.hpd[0] = false; | ||
303 | break; | ||
304 | case RADEON_HPD_2: | ||
305 | WREG32(DC_HPD2_CONTROL, 0); | ||
306 | rdev->irq.hpd[1] = false; | ||
307 | break; | ||
308 | case RADEON_HPD_3: | ||
309 | WREG32(DC_HPD3_CONTROL, 0); | ||
310 | rdev->irq.hpd[2] = false; | ||
311 | break; | ||
312 | case RADEON_HPD_4: | ||
313 | WREG32(DC_HPD4_CONTROL, 0); | ||
314 | rdev->irq.hpd[3] = false; | ||
315 | break; | ||
316 | /* DCE 3.2 */ | ||
317 | case RADEON_HPD_5: | ||
318 | WREG32(DC_HPD5_CONTROL, 0); | ||
319 | rdev->irq.hpd[4] = false; | ||
320 | break; | ||
321 | case RADEON_HPD_6: | ||
322 | WREG32(DC_HPD6_CONTROL, 0); | ||
323 | rdev->irq.hpd[5] = false; | ||
324 | break; | ||
325 | default: | ||
326 | break; | ||
327 | } | ||
328 | } | ||
329 | } else { | ||
330 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
331 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
332 | switch (radeon_connector->hpd.hpd) { | ||
333 | case RADEON_HPD_1: | ||
334 | WREG32(DC_HOT_PLUG_DETECT1_CONTROL, 0); | ||
335 | rdev->irq.hpd[0] = false; | ||
336 | break; | ||
337 | case RADEON_HPD_2: | ||
338 | WREG32(DC_HOT_PLUG_DETECT2_CONTROL, 0); | ||
339 | rdev->irq.hpd[1] = false; | ||
340 | break; | ||
341 | case RADEON_HPD_3: | ||
342 | WREG32(DC_HOT_PLUG_DETECT3_CONTROL, 0); | ||
343 | rdev->irq.hpd[2] = false; | ||
344 | break; | ||
345 | default: | ||
346 | break; | ||
347 | } | ||
348 | } | ||
349 | } | ||
350 | } | ||
351 | |||
77 | /* | 352 | /* |
78 | * R600 PCIE GART | 353 | * R600 PCIE GART |
79 | */ | 354 | */ |
@@ -2060,6 +2335,42 @@ static void r600_disable_interrupts(struct radeon_device *rdev) | |||
2060 | rdev->ih.rptr = 0; | 2335 | rdev->ih.rptr = 0; |
2061 | } | 2336 | } |
2062 | 2337 | ||
2338 | static void r600_disable_interrupt_state(struct radeon_device *rdev) | ||
2339 | { | ||
2340 | u32 tmp; | ||
2341 | |||
2342 | WREG32(CP_INT_CNTL, 0); | ||
2343 | WREG32(GRBM_INT_CNTL, 0); | ||
2344 | WREG32(DxMODE_INT_MASK, 0); | ||
2345 | if (ASIC_IS_DCE3(rdev)) { | ||
2346 | WREG32(DCE3_DACA_AUTODETECT_INT_CONTROL, 0); | ||
2347 | WREG32(DCE3_DACB_AUTODETECT_INT_CONTROL, 0); | ||
2348 | tmp = RREG32(DC_HPD1_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
2349 | WREG32(DC_HPD1_INT_CONTROL, tmp); | ||
2350 | tmp = RREG32(DC_HPD2_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
2351 | WREG32(DC_HPD2_INT_CONTROL, tmp); | ||
2352 | tmp = RREG32(DC_HPD3_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
2353 | WREG32(DC_HPD3_INT_CONTROL, tmp); | ||
2354 | tmp = RREG32(DC_HPD4_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
2355 | WREG32(DC_HPD4_INT_CONTROL, tmp); | ||
2356 | if (ASIC_IS_DCE32(rdev)) { | ||
2357 | tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
2358 | WREG32(DC_HPD5_INT_CONTROL, 0); | ||
2359 | tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
2360 | WREG32(DC_HPD6_INT_CONTROL, 0); | ||
2361 | } | ||
2362 | } else { | ||
2363 | WREG32(DACA_AUTODETECT_INT_CONTROL, 0); | ||
2364 | WREG32(DACB_AUTODETECT_INT_CONTROL, 0); | ||
2365 | tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
2366 | WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, 0); | ||
2367 | tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
2368 | WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, 0); | ||
2369 | tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
2370 | WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, 0); | ||
2371 | } | ||
2372 | } | ||
2373 | |||
2063 | int r600_irq_init(struct radeon_device *rdev) | 2374 | int r600_irq_init(struct radeon_device *rdev) |
2064 | { | 2375 | { |
2065 | int ret = 0; | 2376 | int ret = 0; |
@@ -2122,9 +2433,7 @@ int r600_irq_init(struct radeon_device *rdev) | |||
2122 | WREG32(IH_CNTL, ih_cntl); | 2433 | WREG32(IH_CNTL, ih_cntl); |
2123 | 2434 | ||
2124 | /* force the active interrupt state to all disabled */ | 2435 | /* force the active interrupt state to all disabled */ |
2125 | WREG32(CP_INT_CNTL, 0); | 2436 | r600_disable_interrupt_state(rdev); |
2126 | WREG32(GRBM_INT_CNTL, 0); | ||
2127 | WREG32(DxMODE_INT_MASK, 0); | ||
2128 | 2437 | ||
2129 | /* enable irqs */ | 2438 | /* enable irqs */ |
2130 | r600_enable_interrupts(rdev); | 2439 | r600_enable_interrupts(rdev); |
@@ -2141,13 +2450,29 @@ void r600_irq_fini(struct radeon_device *rdev) | |||
2141 | 2450 | ||
2142 | int r600_irq_set(struct radeon_device *rdev) | 2451 | int r600_irq_set(struct radeon_device *rdev) |
2143 | { | 2452 | { |
2144 | uint32_t cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE; | 2453 | u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE; |
2145 | uint32_t mode_int = 0; | 2454 | u32 mode_int = 0; |
2455 | u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0; | ||
2146 | 2456 | ||
2147 | /* don't enable anything if the ih is disabled */ | 2457 | /* don't enable anything if the ih is disabled */ |
2148 | if (!rdev->ih.enabled) | 2458 | if (!rdev->ih.enabled) |
2149 | return 0; | 2459 | return 0; |
2150 | 2460 | ||
2461 | if (ASIC_IS_DCE3(rdev)) { | ||
2462 | hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
2463 | hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
2464 | hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
2465 | hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
2466 | if (ASIC_IS_DCE32(rdev)) { | ||
2467 | hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
2468 | hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
2469 | } | ||
2470 | } else { | ||
2471 | hpd1 = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
2472 | hpd2 = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
2473 | hpd3 = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
2474 | } | ||
2475 | |||
2151 | if (rdev->irq.sw_int) { | 2476 | if (rdev->irq.sw_int) { |
2152 | DRM_DEBUG("r600_irq_set: sw int\n"); | 2477 | DRM_DEBUG("r600_irq_set: sw int\n"); |
2153 | cp_int_cntl |= RB_INT_ENABLE; | 2478 | cp_int_cntl |= RB_INT_ENABLE; |
@@ -2160,39 +2485,137 @@ int r600_irq_set(struct radeon_device *rdev) | |||
2160 | DRM_DEBUG("r600_irq_set: vblank 1\n"); | 2485 | DRM_DEBUG("r600_irq_set: vblank 1\n"); |
2161 | mode_int |= D2MODE_VBLANK_INT_MASK; | 2486 | mode_int |= D2MODE_VBLANK_INT_MASK; |
2162 | } | 2487 | } |
2488 | if (rdev->irq.hpd[0]) { | ||
2489 | DRM_DEBUG("r600_irq_set: hpd 1\n"); | ||
2490 | hpd1 |= DC_HPDx_INT_EN; | ||
2491 | } | ||
2492 | if (rdev->irq.hpd[1]) { | ||
2493 | DRM_DEBUG("r600_irq_set: hpd 2\n"); | ||
2494 | hpd2 |= DC_HPDx_INT_EN; | ||
2495 | } | ||
2496 | if (rdev->irq.hpd[2]) { | ||
2497 | DRM_DEBUG("r600_irq_set: hpd 3\n"); | ||
2498 | hpd3 |= DC_HPDx_INT_EN; | ||
2499 | } | ||
2500 | if (rdev->irq.hpd[3]) { | ||
2501 | DRM_DEBUG("r600_irq_set: hpd 4\n"); | ||
2502 | hpd4 |= DC_HPDx_INT_EN; | ||
2503 | } | ||
2504 | if (rdev->irq.hpd[4]) { | ||
2505 | DRM_DEBUG("r600_irq_set: hpd 5\n"); | ||
2506 | hpd5 |= DC_HPDx_INT_EN; | ||
2507 | } | ||
2508 | if (rdev->irq.hpd[5]) { | ||
2509 | DRM_DEBUG("r600_irq_set: hpd 6\n"); | ||
2510 | hpd6 |= DC_HPDx_INT_EN; | ||
2511 | } | ||
2163 | 2512 | ||
2164 | WREG32(CP_INT_CNTL, cp_int_cntl); | 2513 | WREG32(CP_INT_CNTL, cp_int_cntl); |
2165 | WREG32(DxMODE_INT_MASK, mode_int); | 2514 | WREG32(DxMODE_INT_MASK, mode_int); |
2515 | if (ASIC_IS_DCE3(rdev)) { | ||
2516 | WREG32(DC_HPD1_INT_CONTROL, hpd1); | ||
2517 | WREG32(DC_HPD2_INT_CONTROL, hpd2); | ||
2518 | WREG32(DC_HPD3_INT_CONTROL, hpd3); | ||
2519 | WREG32(DC_HPD4_INT_CONTROL, hpd4); | ||
2520 | if (ASIC_IS_DCE32(rdev)) { | ||
2521 | WREG32(DC_HPD5_INT_CONTROL, hpd5); | ||
2522 | WREG32(DC_HPD6_INT_CONTROL, hpd6); | ||
2523 | } | ||
2524 | } else { | ||
2525 | WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, hpd1); | ||
2526 | WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2); | ||
2527 | WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, hpd3); | ||
2528 | } | ||
2166 | 2529 | ||
2167 | return 0; | 2530 | return 0; |
2168 | } | 2531 | } |
2169 | 2532 | ||
2170 | static inline void r600_irq_ack(struct radeon_device *rdev, u32 disp_int) | 2533 | static inline void r600_irq_ack(struct radeon_device *rdev, |
2534 | u32 *disp_int, | ||
2535 | u32 *disp_int_cont, | ||
2536 | u32 *disp_int_cont2) | ||
2171 | { | 2537 | { |
2538 | u32 tmp; | ||
2539 | |||
2540 | if (ASIC_IS_DCE3(rdev)) { | ||
2541 | *disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS); | ||
2542 | *disp_int_cont = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE); | ||
2543 | *disp_int_cont2 = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE2); | ||
2544 | } else { | ||
2545 | *disp_int = RREG32(DISP_INTERRUPT_STATUS); | ||
2546 | *disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); | ||
2547 | *disp_int_cont2 = 0; | ||
2548 | } | ||
2172 | 2549 | ||
2173 | if (disp_int & LB_D1_VBLANK_INTERRUPT) | 2550 | if (*disp_int & LB_D1_VBLANK_INTERRUPT) |
2174 | WREG32(D1MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); | 2551 | WREG32(D1MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); |
2175 | if (disp_int & LB_D1_VLINE_INTERRUPT) | 2552 | if (*disp_int & LB_D1_VLINE_INTERRUPT) |
2176 | WREG32(D1MODE_VLINE_STATUS, DxMODE_VLINE_ACK); | 2553 | WREG32(D1MODE_VLINE_STATUS, DxMODE_VLINE_ACK); |
2177 | if (disp_int & LB_D2_VBLANK_INTERRUPT) | 2554 | if (*disp_int & LB_D2_VBLANK_INTERRUPT) |
2178 | WREG32(D2MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); | 2555 | WREG32(D2MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); |
2179 | if (disp_int & LB_D2_VLINE_INTERRUPT) | 2556 | if (*disp_int & LB_D2_VLINE_INTERRUPT) |
2180 | WREG32(D2MODE_VLINE_STATUS, DxMODE_VLINE_ACK); | 2557 | WREG32(D2MODE_VLINE_STATUS, DxMODE_VLINE_ACK); |
2181 | 2558 | if (*disp_int & DC_HPD1_INTERRUPT) { | |
2559 | if (ASIC_IS_DCE3(rdev)) { | ||
2560 | tmp = RREG32(DC_HPD1_INT_CONTROL); | ||
2561 | tmp |= DC_HPDx_INT_ACK; | ||
2562 | WREG32(DC_HPD1_INT_CONTROL, tmp); | ||
2563 | } else { | ||
2564 | tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL); | ||
2565 | tmp |= DC_HPDx_INT_ACK; | ||
2566 | WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); | ||
2567 | } | ||
2568 | } | ||
2569 | if (*disp_int & DC_HPD2_INTERRUPT) { | ||
2570 | if (ASIC_IS_DCE3(rdev)) { | ||
2571 | tmp = RREG32(DC_HPD2_INT_CONTROL); | ||
2572 | tmp |= DC_HPDx_INT_ACK; | ||
2573 | WREG32(DC_HPD2_INT_CONTROL, tmp); | ||
2574 | } else { | ||
2575 | tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL); | ||
2576 | tmp |= DC_HPDx_INT_ACK; | ||
2577 | WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); | ||
2578 | } | ||
2579 | } | ||
2580 | if (*disp_int_cont & DC_HPD3_INTERRUPT) { | ||
2581 | if (ASIC_IS_DCE3(rdev)) { | ||
2582 | tmp = RREG32(DC_HPD3_INT_CONTROL); | ||
2583 | tmp |= DC_HPDx_INT_ACK; | ||
2584 | WREG32(DC_HPD3_INT_CONTROL, tmp); | ||
2585 | } else { | ||
2586 | tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL); | ||
2587 | tmp |= DC_HPDx_INT_ACK; | ||
2588 | WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp); | ||
2589 | } | ||
2590 | } | ||
2591 | if (*disp_int_cont & DC_HPD4_INTERRUPT) { | ||
2592 | tmp = RREG32(DC_HPD4_INT_CONTROL); | ||
2593 | tmp |= DC_HPDx_INT_ACK; | ||
2594 | WREG32(DC_HPD4_INT_CONTROL, tmp); | ||
2595 | } | ||
2596 | if (ASIC_IS_DCE32(rdev)) { | ||
2597 | if (*disp_int_cont2 & DC_HPD5_INTERRUPT) { | ||
2598 | tmp = RREG32(DC_HPD5_INT_CONTROL); | ||
2599 | tmp |= DC_HPDx_INT_ACK; | ||
2600 | WREG32(DC_HPD5_INT_CONTROL, tmp); | ||
2601 | } | ||
2602 | if (*disp_int_cont2 & DC_HPD6_INTERRUPT) { | ||
2603 | tmp = RREG32(DC_HPD5_INT_CONTROL); | ||
2604 | tmp |= DC_HPDx_INT_ACK; | ||
2605 | WREG32(DC_HPD6_INT_CONTROL, tmp); | ||
2606 | } | ||
2607 | } | ||
2182 | } | 2608 | } |
2183 | 2609 | ||
2184 | void r600_irq_disable(struct radeon_device *rdev) | 2610 | void r600_irq_disable(struct radeon_device *rdev) |
2185 | { | 2611 | { |
2186 | u32 disp_int; | 2612 | u32 disp_int, disp_int_cont, disp_int_cont2; |
2187 | 2613 | ||
2188 | r600_disable_interrupts(rdev); | 2614 | r600_disable_interrupts(rdev); |
2189 | /* Wait and acknowledge irq */ | 2615 | /* Wait and acknowledge irq */ |
2190 | mdelay(1); | 2616 | mdelay(1); |
2191 | if (ASIC_IS_DCE3(rdev)) | 2617 | r600_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2); |
2192 | disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS); | 2618 | r600_disable_interrupt_state(rdev); |
2193 | else | ||
2194 | disp_int = RREG32(DISP_INTERRUPT_STATUS); | ||
2195 | r600_irq_ack(rdev, disp_int); | ||
2196 | } | 2619 | } |
2197 | 2620 | ||
2198 | static inline u32 r600_get_ih_wptr(struct radeon_device *rdev) | 2621 | static inline u32 r600_get_ih_wptr(struct radeon_device *rdev) |
@@ -2249,8 +2672,9 @@ int r600_irq_process(struct radeon_device *rdev) | |||
2249 | u32 rptr = rdev->ih.rptr; | 2672 | u32 rptr = rdev->ih.rptr; |
2250 | u32 src_id, src_data; | 2673 | u32 src_id, src_data; |
2251 | u32 last_entry = rdev->ih.ring_size - 16; | 2674 | u32 last_entry = rdev->ih.ring_size - 16; |
2252 | u32 ring_index, disp_int; | 2675 | u32 ring_index, disp_int, disp_int_cont, disp_int_cont2; |
2253 | unsigned long flags; | 2676 | unsigned long flags; |
2677 | bool queue_hotplug = false; | ||
2254 | 2678 | ||
2255 | DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); | 2679 | DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); |
2256 | 2680 | ||
@@ -2267,11 +2691,7 @@ int r600_irq_process(struct radeon_device *rdev) | |||
2267 | 2691 | ||
2268 | restart_ih: | 2692 | restart_ih: |
2269 | /* display interrupts */ | 2693 | /* display interrupts */ |
2270 | if (ASIC_IS_DCE3(rdev)) | 2694 | r600_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2); |
2271 | disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS); | ||
2272 | else | ||
2273 | disp_int = RREG32(DISP_INTERRUPT_STATUS); | ||
2274 | r600_irq_ack(rdev, disp_int); | ||
2275 | 2695 | ||
2276 | rdev->ih.wptr = wptr; | 2696 | rdev->ih.wptr = wptr; |
2277 | while (rptr != wptr) { | 2697 | while (rptr != wptr) { |
@@ -2321,6 +2741,55 @@ restart_ih: | |||
2321 | break; | 2741 | break; |
2322 | } | 2742 | } |
2323 | break; | 2743 | break; |
2744 | case 19: /* HPD/DAC hotplug */ | ||
2745 | switch (src_data) { | ||
2746 | case 0: | ||
2747 | if (disp_int & DC_HPD1_INTERRUPT) { | ||
2748 | disp_int &= ~DC_HPD1_INTERRUPT; | ||
2749 | queue_hotplug = true; | ||
2750 | DRM_DEBUG("IH: HPD1\n"); | ||
2751 | } | ||
2752 | break; | ||
2753 | case 1: | ||
2754 | if (disp_int & DC_HPD2_INTERRUPT) { | ||
2755 | disp_int &= ~DC_HPD2_INTERRUPT; | ||
2756 | queue_hotplug = true; | ||
2757 | DRM_DEBUG("IH: HPD2\n"); | ||
2758 | } | ||
2759 | break; | ||
2760 | case 4: | ||
2761 | if (disp_int_cont & DC_HPD3_INTERRUPT) { | ||
2762 | disp_int_cont &= ~DC_HPD3_INTERRUPT; | ||
2763 | queue_hotplug = true; | ||
2764 | DRM_DEBUG("IH: HPD3\n"); | ||
2765 | } | ||
2766 | break; | ||
2767 | case 5: | ||
2768 | if (disp_int_cont & DC_HPD4_INTERRUPT) { | ||
2769 | disp_int_cont &= ~DC_HPD4_INTERRUPT; | ||
2770 | queue_hotplug = true; | ||
2771 | DRM_DEBUG("IH: HPD4\n"); | ||
2772 | } | ||
2773 | break; | ||
2774 | case 10: | ||
2775 | if (disp_int_cont2 & DC_HPD5_INTERRUPT) { | ||
2776 | disp_int_cont &= ~DC_HPD5_INTERRUPT; | ||
2777 | queue_hotplug = true; | ||
2778 | DRM_DEBUG("IH: HPD5\n"); | ||
2779 | } | ||
2780 | break; | ||
2781 | case 12: | ||
2782 | if (disp_int_cont2 & DC_HPD6_INTERRUPT) { | ||
2783 | disp_int_cont &= ~DC_HPD6_INTERRUPT; | ||
2784 | queue_hotplug = true; | ||
2785 | DRM_DEBUG("IH: HPD6\n"); | ||
2786 | } | ||
2787 | break; | ||
2788 | default: | ||
2789 | DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data); | ||
2790 | break; | ||
2791 | } | ||
2792 | break; | ||
2324 | case 176: /* CP_INT in ring buffer */ | 2793 | case 176: /* CP_INT in ring buffer */ |
2325 | case 177: /* CP_INT in IB1 */ | 2794 | case 177: /* CP_INT in IB1 */ |
2326 | case 178: /* CP_INT in IB2 */ | 2795 | case 178: /* CP_INT in IB2 */ |
@@ -2345,6 +2814,8 @@ restart_ih: | |||
2345 | wptr = r600_get_ih_wptr(rdev); | 2814 | wptr = r600_get_ih_wptr(rdev); |
2346 | if (wptr != rdev->ih.wptr) | 2815 | if (wptr != rdev->ih.wptr) |
2347 | goto restart_ih; | 2816 | goto restart_ih; |
2817 | if (queue_hotplug) | ||
2818 | queue_work(rdev->wq, &rdev->hotplug_work); | ||
2348 | rdev->ih.rptr = rptr; | 2819 | rdev->ih.rptr = rptr; |
2349 | WREG32(IH_RB_RPTR, rdev->ih.rptr); | 2820 | WREG32(IH_RB_RPTR, rdev->ih.rptr); |
2350 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | 2821 | spin_unlock_irqrestore(&rdev->ih.lock, flags); |
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 61ccde5637d7..05894edadab4 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
@@ -558,6 +558,7 @@ | |||
558 | # define DC_HOT_PLUG_DETECT2_INTERRUPT (1 << 19) | 558 | # define DC_HOT_PLUG_DETECT2_INTERRUPT (1 << 19) |
559 | # define DC_I2C_SW_DONE_INTERRUPT (1 << 20) | 559 | # define DC_I2C_SW_DONE_INTERRUPT (1 << 20) |
560 | # define DC_I2C_HW_DONE_INTERRUPT (1 << 21) | 560 | # define DC_I2C_HW_DONE_INTERRUPT (1 << 21) |
561 | #define DISP_INTERRUPT_STATUS_CONTINUE 0x7ee8 | ||
561 | #define DCE3_DISP_INTERRUPT_STATUS_CONTINUE 0x7de8 | 562 | #define DCE3_DISP_INTERRUPT_STATUS_CONTINUE 0x7de8 |
562 | # define DC_HPD4_INTERRUPT (1 << 14) | 563 | # define DC_HPD4_INTERRUPT (1 << 14) |
563 | # define DC_HPD4_RX_INTERRUPT (1 << 15) | 564 | # define DC_HPD4_RX_INTERRUPT (1 << 15) |
@@ -590,6 +591,18 @@ | |||
590 | # define DC_HPD6_INTERRUPT (1 << 21) | 591 | # define DC_HPD6_INTERRUPT (1 << 21) |
591 | # define DC_HPD6_RX_INTERRUPT (1 << 22) | 592 | # define DC_HPD6_RX_INTERRUPT (1 << 22) |
592 | 593 | ||
594 | #define DACA_AUTO_DETECT_CONTROL 0x7828 | ||
595 | #define DACB_AUTO_DETECT_CONTROL 0x7a28 | ||
596 | #define DCE3_DACA_AUTO_DETECT_CONTROL 0x7028 | ||
597 | #define DCE3_DACB_AUTO_DETECT_CONTROL 0x7128 | ||
598 | # define DACx_AUTODETECT_MODE(x) ((x) << 0) | ||
599 | # define DACx_AUTODETECT_MODE_NONE 0 | ||
600 | # define DACx_AUTODETECT_MODE_CONNECT 1 | ||
601 | # define DACx_AUTODETECT_MODE_DISCONNECT 2 | ||
602 | # define DACx_AUTODETECT_FRAME_TIME_COUNTER(x) ((x) << 8) | ||
603 | /* bit 18 = R/C, 17 = G/Y, 16 = B/Comp */ | ||
604 | # define DACx_AUTODETECT_CHECK_MASK(x) ((x) << 16) | ||
605 | |||
593 | #define DCE3_DACA_AUTODETECT_INT_CONTROL 0x7038 | 606 | #define DCE3_DACA_AUTODETECT_INT_CONTROL 0x7038 |
594 | #define DCE3_DACB_AUTODETECT_INT_CONTROL 0x7138 | 607 | #define DCE3_DACB_AUTODETECT_INT_CONTROL 0x7138 |
595 | #define DACA_AUTODETECT_INT_CONTROL 0x7838 | 608 | #define DACA_AUTODETECT_INT_CONTROL 0x7838 |
@@ -597,23 +610,62 @@ | |||
597 | # define DACx_AUTODETECT_ACK (1 << 0) | 610 | # define DACx_AUTODETECT_ACK (1 << 0) |
598 | # define DACx_AUTODETECT_INT_ENABLE (1 << 16) | 611 | # define DACx_AUTODETECT_INT_ENABLE (1 << 16) |
599 | 612 | ||
613 | #define DC_HOT_PLUG_DETECT1_CONTROL 0x7d00 | ||
614 | #define DC_HOT_PLUG_DETECT2_CONTROL 0x7d10 | ||
615 | #define DC_HOT_PLUG_DETECT3_CONTROL 0x7d24 | ||
616 | # define DC_HOT_PLUG_DETECTx_EN (1 << 0) | ||
617 | |||
618 | #define DC_HOT_PLUG_DETECT1_INT_STATUS 0x7d04 | ||
619 | #define DC_HOT_PLUG_DETECT2_INT_STATUS 0x7d14 | ||
620 | #define DC_HOT_PLUG_DETECT3_INT_STATUS 0x7d28 | ||
621 | # define DC_HOT_PLUG_DETECTx_INT_STATUS (1 << 0) | ||
622 | # define DC_HOT_PLUG_DETECTx_SENSE (1 << 1) | ||
623 | |||
624 | /* DCE 3.0 */ | ||
625 | #define DC_HPD1_INT_STATUS 0x7d00 | ||
626 | #define DC_HPD2_INT_STATUS 0x7d0c | ||
627 | #define DC_HPD3_INT_STATUS 0x7d18 | ||
628 | #define DC_HPD4_INT_STATUS 0x7d24 | ||
629 | /* DCE 3.2 */ | ||
630 | #define DC_HPD5_INT_STATUS 0x7dc0 | ||
631 | #define DC_HPD6_INT_STATUS 0x7df4 | ||
632 | # define DC_HPDx_INT_STATUS (1 << 0) | ||
633 | # define DC_HPDx_SENSE (1 << 1) | ||
634 | # define DC_HPDx_RX_INT_STATUS (1 << 8) | ||
635 | |||
600 | #define DC_HOT_PLUG_DETECT1_INT_CONTROL 0x7d08 | 636 | #define DC_HOT_PLUG_DETECT1_INT_CONTROL 0x7d08 |
601 | #define DC_HOT_PLUG_DETECT2_INT_CONTROL 0x7d18 | 637 | #define DC_HOT_PLUG_DETECT2_INT_CONTROL 0x7d18 |
602 | #define DC_HOT_PLUG_DETECT3_INT_CONTROL 0x7d2c | 638 | #define DC_HOT_PLUG_DETECT3_INT_CONTROL 0x7d2c |
603 | # define DC_HOT_PLUG_DETECTx_INT_ACK (1 << 0) | 639 | # define DC_HOT_PLUG_DETECTx_INT_ACK (1 << 0) |
604 | # define DC_HOT_PLUG_DETECTx_INT_POLARITY (1 << 8) | 640 | # define DC_HOT_PLUG_DETECTx_INT_POLARITY (1 << 8) |
605 | # define DC_HOT_PLUG_DETECTx_INT_EN (1 << 16) | 641 | # define DC_HOT_PLUG_DETECTx_INT_EN (1 << 16) |
606 | /* DCE 3.2 */ | 642 | /* DCE 3.0 */ |
607 | #define DC_HPD1_INT_CONTROL 0x7d04 | 643 | #define DC_HPD1_INT_CONTROL 0x7d04 |
608 | #define DC_HPD2_INT_CONTROL 0x7d10 | 644 | #define DC_HPD2_INT_CONTROL 0x7d10 |
609 | #define DC_HPD3_INT_CONTROL 0x7d1c | 645 | #define DC_HPD3_INT_CONTROL 0x7d1c |
610 | #define DC_HPD4_INT_CONTROL 0x7d28 | 646 | #define DC_HPD4_INT_CONTROL 0x7d28 |
647 | /* DCE 3.2 */ | ||
648 | #define DC_HPD5_INT_CONTROL 0x7dc4 | ||
649 | #define DC_HPD6_INT_CONTROL 0x7df8 | ||
611 | # define DC_HPDx_INT_ACK (1 << 0) | 650 | # define DC_HPDx_INT_ACK (1 << 0) |
612 | # define DC_HPDx_INT_POLARITY (1 << 8) | 651 | # define DC_HPDx_INT_POLARITY (1 << 8) |
613 | # define DC_HPDx_INT_EN (1 << 16) | 652 | # define DC_HPDx_INT_EN (1 << 16) |
614 | # define DC_HPDx_RX_INT_ACK (1 << 20) | 653 | # define DC_HPDx_RX_INT_ACK (1 << 20) |
615 | # define DC_HPDx_RX_INT_EN (1 << 24) | 654 | # define DC_HPDx_RX_INT_EN (1 << 24) |
616 | 655 | ||
656 | /* DCE 3.0 */ | ||
657 | #define DC_HPD1_CONTROL 0x7d08 | ||
658 | #define DC_HPD2_CONTROL 0x7d14 | ||
659 | #define DC_HPD3_CONTROL 0x7d20 | ||
660 | #define DC_HPD4_CONTROL 0x7d2c | ||
661 | /* DCE 3.2 */ | ||
662 | #define DC_HPD5_CONTROL 0x7dc8 | ||
663 | #define DC_HPD6_CONTROL 0x7dfc | ||
664 | # define DC_HPDx_CONNECTION_TIMER(x) ((x) << 0) | ||
665 | # define DC_HPDx_RX_INT_TIMER(x) ((x) << 16) | ||
666 | /* DCE 3.2 */ | ||
667 | # define DC_HPDx_EN (1 << 28) | ||
668 | |||
617 | /* | 669 | /* |
618 | * PM4 | 670 | * PM4 |
619 | */ | 671 | */ |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index f3deb4982b2d..a15cf9ceb9a7 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -339,6 +339,8 @@ struct radeon_irq { | |||
339 | bool sw_int; | 339 | bool sw_int; |
340 | /* FIXME: use a define max crtc rather than hardcode it */ | 340 | /* FIXME: use a define max crtc rather than hardcode it */ |
341 | bool crtc_vblank_int[2]; | 341 | bool crtc_vblank_int[2]; |
342 | /* FIXME: use defines for max hpd/dacs */ | ||
343 | bool hpd[6]; | ||
342 | spinlock_t sw_lock; | 344 | spinlock_t sw_lock; |
343 | int sw_refcount; | 345 | int sw_refcount; |
344 | }; | 346 | }; |
@@ -647,6 +649,10 @@ struct radeon_asic { | |||
647 | int (*clear_surface_reg)(struct radeon_device *rdev, int reg); | 649 | int (*clear_surface_reg)(struct radeon_device *rdev, int reg); |
648 | void (*bandwidth_update)(struct radeon_device *rdev); | 650 | void (*bandwidth_update)(struct radeon_device *rdev); |
649 | void (*hdp_flush)(struct radeon_device *rdev); | 651 | void (*hdp_flush)(struct radeon_device *rdev); |
652 | void (*hpd_init)(struct radeon_device *rdev); | ||
653 | void (*hpd_fini)(struct radeon_device *rdev); | ||
654 | bool (*hpd_sense)(struct radeon_device *rdev, enum radeon_hpd_id hpd); | ||
655 | void (*hpd_set_polarity)(struct radeon_device *rdev, enum radeon_hpd_id hpd); | ||
650 | }; | 656 | }; |
651 | 657 | ||
652 | /* | 658 | /* |
@@ -803,6 +809,8 @@ struct radeon_device { | |||
803 | struct r600_blit r600_blit; | 809 | struct r600_blit r600_blit; |
804 | int msi_enabled; /* msi enabled */ | 810 | int msi_enabled; /* msi enabled */ |
805 | struct r600_ih ih; /* r6/700 interrupt ring */ | 811 | struct r600_ih ih; /* r6/700 interrupt ring */ |
812 | struct workqueue_struct *wq; | ||
813 | struct work_struct hotplug_work; | ||
806 | }; | 814 | }; |
807 | 815 | ||
808 | int radeon_device_init(struct radeon_device *rdev, | 816 | int radeon_device_init(struct radeon_device *rdev, |
@@ -986,6 +994,10 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) | |||
986 | #define radeon_clear_surface_reg(rdev, r) ((rdev)->asic->clear_surface_reg((rdev), (r))) | 994 | #define radeon_clear_surface_reg(rdev, r) ((rdev)->asic->clear_surface_reg((rdev), (r))) |
987 | #define radeon_bandwidth_update(rdev) (rdev)->asic->bandwidth_update((rdev)) | 995 | #define radeon_bandwidth_update(rdev) (rdev)->asic->bandwidth_update((rdev)) |
988 | #define radeon_hdp_flush(rdev) (rdev)->asic->hdp_flush((rdev)) | 996 | #define radeon_hdp_flush(rdev) (rdev)->asic->hdp_flush((rdev)) |
997 | #define radeon_hpd_init(rdev) (rdev)->asic->hpd_init((rdev)) | ||
998 | #define radeon_hpd_fini(rdev) (rdev)->asic->hpd_fini((rdev)) | ||
999 | #define radeon_hpd_sense(rdev, hpd) (rdev)->asic->hpd_sense((rdev), (hpd)) | ||
1000 | #define radeon_hpd_set_polarity(rdev, hpd) (rdev)->asic->hpd_set_polarity((rdev), (hpd)) | ||
989 | 1001 | ||
990 | /* Common functions */ | 1002 | /* Common functions */ |
991 | extern int radeon_gart_table_vram_pin(struct radeon_device *rdev); | 1003 | extern int radeon_gart_table_vram_pin(struct radeon_device *rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 755f50555c3d..636116bedcb4 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -77,6 +77,11 @@ void r100_bandwidth_update(struct radeon_device *rdev); | |||
77 | void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); | 77 | void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); |
78 | int r100_ring_test(struct radeon_device *rdev); | 78 | int r100_ring_test(struct radeon_device *rdev); |
79 | void r100_hdp_flush(struct radeon_device *rdev); | 79 | void r100_hdp_flush(struct radeon_device *rdev); |
80 | void r100_hpd_init(struct radeon_device *rdev); | ||
81 | void r100_hpd_fini(struct radeon_device *rdev); | ||
82 | bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); | ||
83 | void r100_hpd_set_polarity(struct radeon_device *rdev, | ||
84 | enum radeon_hpd_id hpd); | ||
80 | 85 | ||
81 | static struct radeon_asic r100_asic = { | 86 | static struct radeon_asic r100_asic = { |
82 | .init = &r100_init, | 87 | .init = &r100_init, |
@@ -109,6 +114,10 @@ static struct radeon_asic r100_asic = { | |||
109 | .clear_surface_reg = r100_clear_surface_reg, | 114 | .clear_surface_reg = r100_clear_surface_reg, |
110 | .bandwidth_update = &r100_bandwidth_update, | 115 | .bandwidth_update = &r100_bandwidth_update, |
111 | .hdp_flush = &r100_hdp_flush, | 116 | .hdp_flush = &r100_hdp_flush, |
117 | .hpd_init = &r100_hpd_init, | ||
118 | .hpd_fini = &r100_hpd_fini, | ||
119 | .hpd_sense = &r100_hpd_sense, | ||
120 | .hpd_set_polarity = &r100_hpd_set_polarity, | ||
112 | }; | 121 | }; |
113 | 122 | ||
114 | 123 | ||
@@ -165,6 +174,10 @@ static struct radeon_asic r300_asic = { | |||
165 | .clear_surface_reg = r100_clear_surface_reg, | 174 | .clear_surface_reg = r100_clear_surface_reg, |
166 | .bandwidth_update = &r100_bandwidth_update, | 175 | .bandwidth_update = &r100_bandwidth_update, |
167 | .hdp_flush = &r100_hdp_flush, | 176 | .hdp_flush = &r100_hdp_flush, |
177 | .hpd_init = &r100_hpd_init, | ||
178 | .hpd_fini = &r100_hpd_fini, | ||
179 | .hpd_sense = &r100_hpd_sense, | ||
180 | .hpd_set_polarity = &r100_hpd_set_polarity, | ||
168 | }; | 181 | }; |
169 | 182 | ||
170 | /* | 183 | /* |
@@ -205,6 +218,10 @@ static struct radeon_asic r420_asic = { | |||
205 | .clear_surface_reg = r100_clear_surface_reg, | 218 | .clear_surface_reg = r100_clear_surface_reg, |
206 | .bandwidth_update = &r100_bandwidth_update, | 219 | .bandwidth_update = &r100_bandwidth_update, |
207 | .hdp_flush = &r100_hdp_flush, | 220 | .hdp_flush = &r100_hdp_flush, |
221 | .hpd_init = &r100_hpd_init, | ||
222 | .hpd_fini = &r100_hpd_fini, | ||
223 | .hpd_sense = &r100_hpd_sense, | ||
224 | .hpd_set_polarity = &r100_hpd_set_polarity, | ||
208 | }; | 225 | }; |
209 | 226 | ||
210 | 227 | ||
@@ -250,6 +267,10 @@ static struct radeon_asic rs400_asic = { | |||
250 | .clear_surface_reg = r100_clear_surface_reg, | 267 | .clear_surface_reg = r100_clear_surface_reg, |
251 | .bandwidth_update = &r100_bandwidth_update, | 268 | .bandwidth_update = &r100_bandwidth_update, |
252 | .hdp_flush = &r100_hdp_flush, | 269 | .hdp_flush = &r100_hdp_flush, |
270 | .hpd_init = &r100_hpd_init, | ||
271 | .hpd_fini = &r100_hpd_fini, | ||
272 | .hpd_sense = &r100_hpd_sense, | ||
273 | .hpd_set_polarity = &r100_hpd_set_polarity, | ||
253 | }; | 274 | }; |
254 | 275 | ||
255 | 276 | ||
@@ -268,6 +289,12 @@ int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); | |||
268 | uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg); | 289 | uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg); |
269 | void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); | 290 | void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); |
270 | void rs600_bandwidth_update(struct radeon_device *rdev); | 291 | void rs600_bandwidth_update(struct radeon_device *rdev); |
292 | void rs600_hpd_init(struct radeon_device *rdev); | ||
293 | void rs600_hpd_fini(struct radeon_device *rdev); | ||
294 | bool rs600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); | ||
295 | void rs600_hpd_set_polarity(struct radeon_device *rdev, | ||
296 | enum radeon_hpd_id hpd); | ||
297 | |||
271 | static struct radeon_asic rs600_asic = { | 298 | static struct radeon_asic rs600_asic = { |
272 | .init = &rs600_init, | 299 | .init = &rs600_init, |
273 | .fini = &rs600_fini, | 300 | .fini = &rs600_fini, |
@@ -297,6 +324,10 @@ static struct radeon_asic rs600_asic = { | |||
297 | .set_clock_gating = &radeon_atom_set_clock_gating, | 324 | .set_clock_gating = &radeon_atom_set_clock_gating, |
298 | .bandwidth_update = &rs600_bandwidth_update, | 325 | .bandwidth_update = &rs600_bandwidth_update, |
299 | .hdp_flush = &r100_hdp_flush, | 326 | .hdp_flush = &r100_hdp_flush, |
327 | .hpd_init = &rs600_hpd_init, | ||
328 | .hpd_fini = &rs600_hpd_fini, | ||
329 | .hpd_sense = &rs600_hpd_sense, | ||
330 | .hpd_set_polarity = &rs600_hpd_set_polarity, | ||
300 | }; | 331 | }; |
301 | 332 | ||
302 | 333 | ||
@@ -341,6 +372,10 @@ static struct radeon_asic rs690_asic = { | |||
341 | .clear_surface_reg = r100_clear_surface_reg, | 372 | .clear_surface_reg = r100_clear_surface_reg, |
342 | .bandwidth_update = &rs690_bandwidth_update, | 373 | .bandwidth_update = &rs690_bandwidth_update, |
343 | .hdp_flush = &r100_hdp_flush, | 374 | .hdp_flush = &r100_hdp_flush, |
375 | .hpd_init = &rs600_hpd_init, | ||
376 | .hpd_fini = &rs600_hpd_fini, | ||
377 | .hpd_sense = &rs600_hpd_sense, | ||
378 | .hpd_set_polarity = &rs600_hpd_set_polarity, | ||
344 | }; | 379 | }; |
345 | 380 | ||
346 | 381 | ||
@@ -389,6 +424,10 @@ static struct radeon_asic rv515_asic = { | |||
389 | .clear_surface_reg = r100_clear_surface_reg, | 424 | .clear_surface_reg = r100_clear_surface_reg, |
390 | .bandwidth_update = &rv515_bandwidth_update, | 425 | .bandwidth_update = &rv515_bandwidth_update, |
391 | .hdp_flush = &r100_hdp_flush, | 426 | .hdp_flush = &r100_hdp_flush, |
427 | .hpd_init = &rs600_hpd_init, | ||
428 | .hpd_fini = &rs600_hpd_fini, | ||
429 | .hpd_sense = &rs600_hpd_sense, | ||
430 | .hpd_set_polarity = &rs600_hpd_set_polarity, | ||
392 | }; | 431 | }; |
393 | 432 | ||
394 | 433 | ||
@@ -428,6 +467,10 @@ static struct radeon_asic r520_asic = { | |||
428 | .clear_surface_reg = r100_clear_surface_reg, | 467 | .clear_surface_reg = r100_clear_surface_reg, |
429 | .bandwidth_update = &rv515_bandwidth_update, | 468 | .bandwidth_update = &rv515_bandwidth_update, |
430 | .hdp_flush = &r100_hdp_flush, | 469 | .hdp_flush = &r100_hdp_flush, |
470 | .hpd_init = &rs600_hpd_init, | ||
471 | .hpd_fini = &rs600_hpd_fini, | ||
472 | .hpd_sense = &rs600_hpd_sense, | ||
473 | .hpd_set_polarity = &rs600_hpd_set_polarity, | ||
431 | }; | 474 | }; |
432 | 475 | ||
433 | /* | 476 | /* |
@@ -465,6 +508,11 @@ int r600_copy_blit(struct radeon_device *rdev, | |||
465 | uint64_t src_offset, uint64_t dst_offset, | 508 | uint64_t src_offset, uint64_t dst_offset, |
466 | unsigned num_pages, struct radeon_fence *fence); | 509 | unsigned num_pages, struct radeon_fence *fence); |
467 | void r600_hdp_flush(struct radeon_device *rdev); | 510 | void r600_hdp_flush(struct radeon_device *rdev); |
511 | void r600_hpd_init(struct radeon_device *rdev); | ||
512 | void r600_hpd_fini(struct radeon_device *rdev); | ||
513 | bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); | ||
514 | void r600_hpd_set_polarity(struct radeon_device *rdev, | ||
515 | enum radeon_hpd_id hpd); | ||
468 | 516 | ||
469 | static struct radeon_asic r600_asic = { | 517 | static struct radeon_asic r600_asic = { |
470 | .init = &r600_init, | 518 | .init = &r600_init, |
@@ -496,6 +544,10 @@ static struct radeon_asic r600_asic = { | |||
496 | .clear_surface_reg = r600_clear_surface_reg, | 544 | .clear_surface_reg = r600_clear_surface_reg, |
497 | .bandwidth_update = &rv515_bandwidth_update, | 545 | .bandwidth_update = &rv515_bandwidth_update, |
498 | .hdp_flush = &r600_hdp_flush, | 546 | .hdp_flush = &r600_hdp_flush, |
547 | .hpd_init = &r600_hpd_init, | ||
548 | .hpd_fini = &r600_hpd_fini, | ||
549 | .hpd_sense = &r600_hpd_sense, | ||
550 | .hpd_set_polarity = &r600_hpd_set_polarity, | ||
499 | }; | 551 | }; |
500 | 552 | ||
501 | /* | 553 | /* |
@@ -537,6 +589,10 @@ static struct radeon_asic rv770_asic = { | |||
537 | .clear_surface_reg = r600_clear_surface_reg, | 589 | .clear_surface_reg = r600_clear_surface_reg, |
538 | .bandwidth_update = &rv515_bandwidth_update, | 590 | .bandwidth_update = &rv515_bandwidth_update, |
539 | .hdp_flush = &r600_hdp_flush, | 591 | .hdp_flush = &r600_hdp_flush, |
592 | .hpd_init = &r600_hpd_init, | ||
593 | .hpd_fini = &r600_hpd_fini, | ||
594 | .hpd_sense = &r600_hpd_sense, | ||
595 | .hpd_set_polarity = &r600_hpd_set_polarity, | ||
540 | }; | 596 | }; |
541 | 597 | ||
542 | #endif | 598 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 5e414102c875..d7b0feb7d47f 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -47,7 +47,8 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
47 | int connector_type, | 47 | int connector_type, |
48 | struct radeon_i2c_bus_rec *i2c_bus, | 48 | struct radeon_i2c_bus_rec *i2c_bus, |
49 | bool linkb, uint32_t igp_lane_info, | 49 | bool linkb, uint32_t igp_lane_info, |
50 | uint16_t connector_object_id); | 50 | uint16_t connector_object_id, |
51 | struct radeon_hpd *hpd); | ||
51 | 52 | ||
52 | /* from radeon_legacy_encoder.c */ | 53 | /* from radeon_legacy_encoder.c */ |
53 | extern void | 54 | extern void |
@@ -60,12 +61,11 @@ union atom_supported_devices { | |||
60 | struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1; | 61 | struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1; |
61 | }; | 62 | }; |
62 | 63 | ||
63 | static inline struct radeon_i2c_bus_rec radeon_lookup_gpio(struct drm_device | 64 | static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rdev, |
64 | *dev, uint8_t id) | 65 | uint8_t id) |
65 | { | 66 | { |
66 | struct radeon_device *rdev = dev->dev_private; | ||
67 | struct atom_context *ctx = rdev->mode_info.atom_context; | 67 | struct atom_context *ctx = rdev->mode_info.atom_context; |
68 | ATOM_GPIO_I2C_ASSIGMENT gpio; | 68 | ATOM_GPIO_I2C_ASSIGMENT *gpio; |
69 | struct radeon_i2c_bus_rec i2c; | 69 | struct radeon_i2c_bus_rec i2c; |
70 | int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info); | 70 | int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info); |
71 | struct _ATOM_GPIO_I2C_INFO *i2c_info; | 71 | struct _ATOM_GPIO_I2C_INFO *i2c_info; |
@@ -78,34 +78,116 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_gpio(struct drm_device | |||
78 | 78 | ||
79 | i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); | 79 | i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); |
80 | 80 | ||
81 | gpio = i2c_info->asGPIO_Info[id]; | 81 | gpio = &i2c_info->asGPIO_Info[id]; |
82 | 82 | ||
83 | i2c.mask_clk_reg = le16_to_cpu(gpio.usClkMaskRegisterIndex) * 4; | 83 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; |
84 | i2c.mask_data_reg = le16_to_cpu(gpio.usDataMaskRegisterIndex) * 4; | 84 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; |
85 | i2c.en_clk_reg = le16_to_cpu(gpio.usClkEnRegisterIndex) * 4; | 85 | i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; |
86 | i2c.en_data_reg = le16_to_cpu(gpio.usDataEnRegisterIndex) * 4; | 86 | i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4; |
87 | i2c.y_clk_reg = le16_to_cpu(gpio.usClkY_RegisterIndex) * 4; | 87 | i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4; |
88 | i2c.y_data_reg = le16_to_cpu(gpio.usDataY_RegisterIndex) * 4; | 88 | i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4; |
89 | i2c.a_clk_reg = le16_to_cpu(gpio.usClkA_RegisterIndex) * 4; | 89 | i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4; |
90 | i2c.a_data_reg = le16_to_cpu(gpio.usDataA_RegisterIndex) * 4; | 90 | i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4; |
91 | i2c.mask_clk_mask = (1 << gpio.ucClkMaskShift); | 91 | i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift); |
92 | i2c.mask_data_mask = (1 << gpio.ucDataMaskShift); | 92 | i2c.mask_data_mask = (1 << gpio->ucDataMaskShift); |
93 | i2c.en_clk_mask = (1 << gpio.ucClkEnShift); | 93 | i2c.en_clk_mask = (1 << gpio->ucClkEnShift); |
94 | i2c.en_data_mask = (1 << gpio.ucDataEnShift); | 94 | i2c.en_data_mask = (1 << gpio->ucDataEnShift); |
95 | i2c.y_clk_mask = (1 << gpio.ucClkY_Shift); | 95 | i2c.y_clk_mask = (1 << gpio->ucClkY_Shift); |
96 | i2c.y_data_mask = (1 << gpio.ucDataY_Shift); | 96 | i2c.y_data_mask = (1 << gpio->ucDataY_Shift); |
97 | i2c.a_clk_mask = (1 << gpio.ucClkA_Shift); | 97 | i2c.a_clk_mask = (1 << gpio->ucClkA_Shift); |
98 | i2c.a_data_mask = (1 << gpio.ucDataA_Shift); | 98 | i2c.a_data_mask = (1 << gpio->ucDataA_Shift); |
99 | |||
100 | if (gpio->sucI2cId.sbfAccess.bfHW_Capable) | ||
101 | i2c.hw_capable = true; | ||
102 | else | ||
103 | i2c.hw_capable = false; | ||
104 | |||
105 | if (gpio->sucI2cId.ucAccess == 0xa0) | ||
106 | i2c.mm_i2c = true; | ||
107 | else | ||
108 | i2c.mm_i2c = false; | ||
109 | |||
110 | i2c.i2c_id = gpio->sucI2cId.ucAccess; | ||
111 | |||
99 | i2c.valid = true; | 112 | i2c.valid = true; |
100 | 113 | ||
101 | return i2c; | 114 | return i2c; |
102 | } | 115 | } |
103 | 116 | ||
117 | static inline struct radeon_gpio_rec radeon_lookup_gpio(struct radeon_device *rdev, | ||
118 | u8 id) | ||
119 | { | ||
120 | struct atom_context *ctx = rdev->mode_info.atom_context; | ||
121 | struct radeon_gpio_rec gpio; | ||
122 | int index = GetIndexIntoMasterTable(DATA, GPIO_Pin_LUT); | ||
123 | struct _ATOM_GPIO_PIN_LUT *gpio_info; | ||
124 | ATOM_GPIO_PIN_ASSIGNMENT *pin; | ||
125 | u16 data_offset, size; | ||
126 | int i, num_indices; | ||
127 | |||
128 | memset(&gpio, 0, sizeof(struct radeon_gpio_rec)); | ||
129 | gpio.valid = false; | ||
130 | |||
131 | atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset); | ||
132 | |||
133 | gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset); | ||
134 | |||
135 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / sizeof(ATOM_GPIO_PIN_ASSIGNMENT); | ||
136 | |||
137 | for (i = 0; i < num_indices; i++) { | ||
138 | pin = &gpio_info->asGPIO_Pin[i]; | ||
139 | if (id == pin->ucGPIO_ID) { | ||
140 | gpio.id = pin->ucGPIO_ID; | ||
141 | gpio.reg = pin->usGpioPin_AIndex * 4; | ||
142 | gpio.mask = (1 << pin->ucGpioPinBitShift); | ||
143 | gpio.valid = true; | ||
144 | break; | ||
145 | } | ||
146 | } | ||
147 | |||
148 | return gpio; | ||
149 | } | ||
150 | |||
151 | static struct radeon_hpd radeon_atom_get_hpd_info_from_gpio(struct radeon_device *rdev, | ||
152 | struct radeon_gpio_rec *gpio) | ||
153 | { | ||
154 | struct radeon_hpd hpd; | ||
155 | hpd.gpio = *gpio; | ||
156 | if (gpio->reg == AVIVO_DC_GPIO_HPD_A) { | ||
157 | switch(gpio->mask) { | ||
158 | case (1 << 0): | ||
159 | hpd.hpd = RADEON_HPD_1; | ||
160 | break; | ||
161 | case (1 << 8): | ||
162 | hpd.hpd = RADEON_HPD_2; | ||
163 | break; | ||
164 | case (1 << 16): | ||
165 | hpd.hpd = RADEON_HPD_3; | ||
166 | break; | ||
167 | case (1 << 24): | ||
168 | hpd.hpd = RADEON_HPD_4; | ||
169 | break; | ||
170 | case (1 << 26): | ||
171 | hpd.hpd = RADEON_HPD_5; | ||
172 | break; | ||
173 | case (1 << 28): | ||
174 | hpd.hpd = RADEON_HPD_6; | ||
175 | break; | ||
176 | default: | ||
177 | hpd.hpd = RADEON_HPD_NONE; | ||
178 | break; | ||
179 | } | ||
180 | } else | ||
181 | hpd.hpd = RADEON_HPD_NONE; | ||
182 | return hpd; | ||
183 | } | ||
184 | |||
104 | static bool radeon_atom_apply_quirks(struct drm_device *dev, | 185 | static bool radeon_atom_apply_quirks(struct drm_device *dev, |
105 | uint32_t supported_device, | 186 | uint32_t supported_device, |
106 | int *connector_type, | 187 | int *connector_type, |
107 | struct radeon_i2c_bus_rec *i2c_bus, | 188 | struct radeon_i2c_bus_rec *i2c_bus, |
108 | uint16_t *line_mux) | 189 | uint16_t *line_mux, |
190 | struct radeon_hpd *hpd) | ||
109 | { | 191 | { |
110 | 192 | ||
111 | /* Asus M2A-VM HDMI board lists the DVI port as HDMI */ | 193 | /* Asus M2A-VM HDMI board lists the DVI port as HDMI */ |
@@ -266,16 +348,18 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
266 | struct radeon_mode_info *mode_info = &rdev->mode_info; | 348 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
267 | struct atom_context *ctx = mode_info->atom_context; | 349 | struct atom_context *ctx = mode_info->atom_context; |
268 | int index = GetIndexIntoMasterTable(DATA, Object_Header); | 350 | int index = GetIndexIntoMasterTable(DATA, Object_Header); |
269 | uint16_t size, data_offset; | 351 | u16 size, data_offset; |
270 | uint8_t frev, crev, line_mux = 0; | 352 | u8 frev, crev; |
271 | ATOM_CONNECTOR_OBJECT_TABLE *con_obj; | 353 | ATOM_CONNECTOR_OBJECT_TABLE *con_obj; |
272 | ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj; | 354 | ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj; |
273 | ATOM_OBJECT_HEADER *obj_header; | 355 | ATOM_OBJECT_HEADER *obj_header; |
274 | int i, j, path_size, device_support; | 356 | int i, j, path_size, device_support; |
275 | int connector_type; | 357 | int connector_type; |
276 | uint16_t igp_lane_info, conn_id, connector_object_id; | 358 | u16 igp_lane_info, conn_id, connector_object_id; |
277 | bool linkb; | 359 | bool linkb; |
278 | struct radeon_i2c_bus_rec ddc_bus; | 360 | struct radeon_i2c_bus_rec ddc_bus; |
361 | struct radeon_gpio_rec gpio; | ||
362 | struct radeon_hpd hpd; | ||
279 | 363 | ||
280 | atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); | 364 | atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); |
281 | 365 | ||
@@ -302,7 +386,6 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
302 | path = (ATOM_DISPLAY_OBJECT_PATH *) addr; | 386 | path = (ATOM_DISPLAY_OBJECT_PATH *) addr; |
303 | path_size += le16_to_cpu(path->usSize); | 387 | path_size += le16_to_cpu(path->usSize); |
304 | linkb = false; | 388 | linkb = false; |
305 | |||
306 | if (device_support & le16_to_cpu(path->usDeviceTag)) { | 389 | if (device_support & le16_to_cpu(path->usDeviceTag)) { |
307 | uint8_t con_obj_id, con_obj_num, con_obj_type; | 390 | uint8_t con_obj_id, con_obj_num, con_obj_type; |
308 | 391 | ||
@@ -403,10 +486,9 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
403 | } | 486 | } |
404 | } | 487 | } |
405 | 488 | ||
406 | /* look up gpio for ddc */ | 489 | /* look up gpio for ddc, hpd */ |
407 | if ((le16_to_cpu(path->usDeviceTag) & | 490 | if ((le16_to_cpu(path->usDeviceTag) & |
408 | (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) | 491 | (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) == 0) { |
409 | == 0) { | ||
410 | for (j = 0; j < con_obj->ucNumberOfObjects; j++) { | 492 | for (j = 0; j < con_obj->ucNumberOfObjects; j++) { |
411 | if (le16_to_cpu(path->usConnObjectId) == | 493 | if (le16_to_cpu(path->usConnObjectId) == |
412 | le16_to_cpu(con_obj->asObjects[j]. | 494 | le16_to_cpu(con_obj->asObjects[j]. |
@@ -420,21 +502,31 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
420 | asObjects[j]. | 502 | asObjects[j]. |
421 | usRecordOffset)); | 503 | usRecordOffset)); |
422 | ATOM_I2C_RECORD *i2c_record; | 504 | ATOM_I2C_RECORD *i2c_record; |
505 | ATOM_HPD_INT_RECORD *hpd_record; | ||
506 | hpd.hpd = RADEON_HPD_NONE; | ||
423 | 507 | ||
424 | while (record->ucRecordType > 0 | 508 | while (record->ucRecordType > 0 |
425 | && record-> | 509 | && record-> |
426 | ucRecordType <= | 510 | ucRecordType <= |
427 | ATOM_MAX_OBJECT_RECORD_NUMBER) { | 511 | ATOM_MAX_OBJECT_RECORD_NUMBER) { |
428 | switch (record-> | 512 | switch (record->ucRecordType) { |
429 | ucRecordType) { | ||
430 | case ATOM_I2C_RECORD_TYPE: | 513 | case ATOM_I2C_RECORD_TYPE: |
431 | i2c_record = | 514 | i2c_record = |
432 | (ATOM_I2C_RECORD | 515 | (ATOM_I2C_RECORD *) |
433 | *) record; | 516 | record; |
434 | line_mux = | 517 | ddc_bus = radeon_lookup_i2c_gpio(rdev, |
435 | i2c_record-> | 518 | i2c_record-> |
436 | sucI2cId. | 519 | sucI2cId. |
437 | bfI2C_LineMux; | 520 | bfI2C_LineMux); |
521 | break; | ||
522 | case ATOM_HPD_INT_RECORD_TYPE: | ||
523 | hpd_record = | ||
524 | (ATOM_HPD_INT_RECORD *) | ||
525 | record; | ||
526 | gpio = radeon_lookup_gpio(rdev, | ||
527 | hpd_record->ucHPDIntGPIOID); | ||
528 | hpd = radeon_atom_get_hpd_info_from_gpio(rdev, &gpio); | ||
529 | hpd.plugged_state = hpd_record->ucPlugged_PinState; | ||
438 | break; | 530 | break; |
439 | } | 531 | } |
440 | record = | 532 | record = |
@@ -447,24 +539,16 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
447 | break; | 539 | break; |
448 | } | 540 | } |
449 | } | 541 | } |
450 | } else | 542 | } else { |
451 | line_mux = 0; | 543 | hpd.hpd = RADEON_HPD_NONE; |
452 | |||
453 | if ((le16_to_cpu(path->usDeviceTag) == | ||
454 | ATOM_DEVICE_TV1_SUPPORT) | ||
455 | || (le16_to_cpu(path->usDeviceTag) == | ||
456 | ATOM_DEVICE_TV2_SUPPORT) | ||
457 | || (le16_to_cpu(path->usDeviceTag) == | ||
458 | ATOM_DEVICE_CV_SUPPORT)) | ||
459 | ddc_bus.valid = false; | 544 | ddc_bus.valid = false; |
460 | else | 545 | } |
461 | ddc_bus = radeon_lookup_gpio(dev, line_mux); | ||
462 | 546 | ||
463 | conn_id = le16_to_cpu(path->usConnObjectId); | 547 | conn_id = le16_to_cpu(path->usConnObjectId); |
464 | 548 | ||
465 | if (!radeon_atom_apply_quirks | 549 | if (!radeon_atom_apply_quirks |
466 | (dev, le16_to_cpu(path->usDeviceTag), &connector_type, | 550 | (dev, le16_to_cpu(path->usDeviceTag), &connector_type, |
467 | &ddc_bus, &conn_id)) | 551 | &ddc_bus, &conn_id, &hpd)) |
468 | continue; | 552 | continue; |
469 | 553 | ||
470 | radeon_add_atom_connector(dev, | 554 | radeon_add_atom_connector(dev, |
@@ -473,7 +557,8 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
473 | usDeviceTag), | 557 | usDeviceTag), |
474 | connector_type, &ddc_bus, | 558 | connector_type, &ddc_bus, |
475 | linkb, igp_lane_info, | 559 | linkb, igp_lane_info, |
476 | connector_object_id); | 560 | connector_object_id, |
561 | &hpd); | ||
477 | 562 | ||
478 | } | 563 | } |
479 | } | 564 | } |
@@ -528,6 +613,7 @@ struct bios_connector { | |||
528 | uint16_t devices; | 613 | uint16_t devices; |
529 | int connector_type; | 614 | int connector_type; |
530 | struct radeon_i2c_bus_rec ddc_bus; | 615 | struct radeon_i2c_bus_rec ddc_bus; |
616 | struct radeon_hpd hpd; | ||
531 | }; | 617 | }; |
532 | 618 | ||
533 | bool radeon_get_atom_connector_info_from_supported_devices_table(struct | 619 | bool radeon_get_atom_connector_info_from_supported_devices_table(struct |
@@ -543,7 +629,7 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
543 | uint16_t device_support; | 629 | uint16_t device_support; |
544 | uint8_t dac; | 630 | uint8_t dac; |
545 | union atom_supported_devices *supported_devices; | 631 | union atom_supported_devices *supported_devices; |
546 | int i, j; | 632 | int i, j, max_device; |
547 | struct bios_connector bios_connectors[ATOM_MAX_SUPPORTED_DEVICE]; | 633 | struct bios_connector bios_connectors[ATOM_MAX_SUPPORTED_DEVICE]; |
548 | 634 | ||
549 | atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); | 635 | atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); |
@@ -553,7 +639,12 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
553 | 639 | ||
554 | device_support = le16_to_cpu(supported_devices->info.usDeviceSupport); | 640 | device_support = le16_to_cpu(supported_devices->info.usDeviceSupport); |
555 | 641 | ||
556 | for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { | 642 | if (frev > 1) |
643 | max_device = ATOM_MAX_SUPPORTED_DEVICE; | ||
644 | else | ||
645 | max_device = ATOM_MAX_SUPPORTED_DEVICE_INFO; | ||
646 | |||
647 | for (i = 0; i < max_device; i++) { | ||
557 | ATOM_CONNECTOR_INFO_I2C ci = | 648 | ATOM_CONNECTOR_INFO_I2C ci = |
558 | supported_devices->info.asConnInfo[i]; | 649 | supported_devices->info.asConnInfo[i]; |
559 | 650 | ||
@@ -608,8 +699,30 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
608 | bios_connectors[i].line_mux = 52; | 699 | bios_connectors[i].line_mux = 52; |
609 | } else | 700 | } else |
610 | bios_connectors[i].ddc_bus = | 701 | bios_connectors[i].ddc_bus = |
611 | radeon_lookup_gpio(dev, | 702 | radeon_lookup_i2c_gpio(rdev, |
612 | bios_connectors[i].line_mux); | 703 | bios_connectors[i].line_mux); |
704 | |||
705 | if ((crev > 1) && (frev > 1)) { | ||
706 | u8 isb = supported_devices->info_2d1.asIntSrcInfo[i].ucIntSrcBitmap; | ||
707 | switch (isb) { | ||
708 | case 0x4: | ||
709 | bios_connectors[i].hpd.hpd = RADEON_HPD_1; | ||
710 | break; | ||
711 | case 0xa: | ||
712 | bios_connectors[i].hpd.hpd = RADEON_HPD_2; | ||
713 | break; | ||
714 | default: | ||
715 | bios_connectors[i].hpd.hpd = RADEON_HPD_NONE; | ||
716 | break; | ||
717 | } | ||
718 | } else { | ||
719 | if (i == ATOM_DEVICE_DFP1_INDEX) | ||
720 | bios_connectors[i].hpd.hpd = RADEON_HPD_1; | ||
721 | else if (i == ATOM_DEVICE_DFP2_INDEX) | ||
722 | bios_connectors[i].hpd.hpd = RADEON_HPD_2; | ||
723 | else | ||
724 | bios_connectors[i].hpd.hpd = RADEON_HPD_NONE; | ||
725 | } | ||
613 | 726 | ||
614 | /* Always set the connector type to VGA for CRT1/CRT2. if they are | 727 | /* Always set the connector type to VGA for CRT1/CRT2. if they are |
615 | * shared with a DVI port, we'll pick up the DVI connector when we | 728 | * shared with a DVI port, we'll pick up the DVI connector when we |
@@ -621,7 +734,8 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
621 | 734 | ||
622 | if (!radeon_atom_apply_quirks | 735 | if (!radeon_atom_apply_quirks |
623 | (dev, (1 << i), &bios_connectors[i].connector_type, | 736 | (dev, (1 << i), &bios_connectors[i].connector_type, |
624 | &bios_connectors[i].ddc_bus, &bios_connectors[i].line_mux)) | 737 | &bios_connectors[i].ddc_bus, &bios_connectors[i].line_mux, |
738 | &bios_connectors[i].hpd)) | ||
625 | continue; | 739 | continue; |
626 | 740 | ||
627 | bios_connectors[i].valid = true; | 741 | bios_connectors[i].valid = true; |
@@ -643,9 +757,9 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
643 | } | 757 | } |
644 | 758 | ||
645 | /* combine shared connectors */ | 759 | /* combine shared connectors */ |
646 | for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { | 760 | for (i = 0; i < max_device; i++) { |
647 | if (bios_connectors[i].valid) { | 761 | if (bios_connectors[i].valid) { |
648 | for (j = 0; j < ATOM_MAX_SUPPORTED_DEVICE; j++) { | 762 | for (j = 0; j < max_device; j++) { |
649 | if (bios_connectors[j].valid && (i != j)) { | 763 | if (bios_connectors[j].valid && (i != j)) { |
650 | if (bios_connectors[i].line_mux == | 764 | if (bios_connectors[i].line_mux == |
651 | bios_connectors[j].line_mux) { | 765 | bios_connectors[j].line_mux) { |
@@ -669,6 +783,10 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
669 | bios_connectors[i]. | 783 | bios_connectors[i]. |
670 | connector_type = | 784 | connector_type = |
671 | DRM_MODE_CONNECTOR_DVII; | 785 | DRM_MODE_CONNECTOR_DVII; |
786 | if (bios_connectors[j].devices & | ||
787 | (ATOM_DEVICE_DFP_SUPPORT)) | ||
788 | bios_connectors[i].hpd = | ||
789 | bios_connectors[j].hpd; | ||
672 | bios_connectors[j]. | 790 | bios_connectors[j]. |
673 | valid = false; | 791 | valid = false; |
674 | } | 792 | } |
@@ -679,7 +797,7 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
679 | } | 797 | } |
680 | 798 | ||
681 | /* add the connectors */ | 799 | /* add the connectors */ |
682 | for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { | 800 | for (i = 0; i < max_device; i++) { |
683 | if (bios_connectors[i].valid) { | 801 | if (bios_connectors[i].valid) { |
684 | uint16_t connector_object_id = | 802 | uint16_t connector_object_id = |
685 | atombios_get_connector_object_id(dev, | 803 | atombios_get_connector_object_id(dev, |
@@ -692,7 +810,8 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
692 | connector_type, | 810 | connector_type, |
693 | &bios_connectors[i].ddc_bus, | 811 | &bios_connectors[i].ddc_bus, |
694 | false, 0, | 812 | false, 0, |
695 | connector_object_id); | 813 | connector_object_id, |
814 | &bios_connectors[i].hpd); | ||
696 | } | 815 | } |
697 | } | 816 | } |
698 | 817 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 14d3555e4afe..c5021a3445de 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
@@ -50,7 +50,8 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
50 | uint32_t supported_device, | 50 | uint32_t supported_device, |
51 | int connector_type, | 51 | int connector_type, |
52 | struct radeon_i2c_bus_rec *i2c_bus, | 52 | struct radeon_i2c_bus_rec *i2c_bus, |
53 | uint16_t connector_object_id); | 53 | uint16_t connector_object_id, |
54 | struct radeon_hpd *hpd); | ||
54 | 55 | ||
55 | /* from radeon_legacy_encoder.c */ | 56 | /* from radeon_legacy_encoder.c */ |
56 | extern void | 57 | extern void |
@@ -442,29 +443,39 @@ static uint16_t combios_get_table_offset(struct drm_device *dev, | |||
442 | 443 | ||
443 | } | 444 | } |
444 | 445 | ||
445 | struct radeon_i2c_bus_rec combios_setup_i2c_bus(int ddc_line) | 446 | static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rdev, |
447 | int ddc_line) | ||
446 | { | 448 | { |
447 | struct radeon_i2c_bus_rec i2c; | 449 | struct radeon_i2c_bus_rec i2c; |
448 | 450 | ||
449 | i2c.mask_clk_mask = RADEON_GPIO_EN_1; | 451 | if (ddc_line == RADEON_GPIOPAD_MASK) { |
450 | i2c.mask_data_mask = RADEON_GPIO_EN_0; | 452 | i2c.mask_clk_reg = RADEON_GPIOPAD_MASK; |
451 | i2c.a_clk_mask = RADEON_GPIO_A_1; | 453 | i2c.mask_data_reg = RADEON_GPIOPAD_MASK; |
452 | i2c.a_data_mask = RADEON_GPIO_A_0; | 454 | i2c.a_clk_reg = RADEON_GPIOPAD_A; |
453 | i2c.en_clk_mask = RADEON_GPIO_EN_1; | 455 | i2c.a_data_reg = RADEON_GPIOPAD_A; |
454 | i2c.en_data_mask = RADEON_GPIO_EN_0; | 456 | i2c.en_clk_reg = RADEON_GPIOPAD_EN; |
455 | i2c.y_clk_mask = RADEON_GPIO_Y_1; | 457 | i2c.en_data_reg = RADEON_GPIOPAD_EN; |
456 | i2c.y_data_mask = RADEON_GPIO_Y_0; | 458 | i2c.y_clk_reg = RADEON_GPIOPAD_Y; |
457 | if ((ddc_line == RADEON_LCD_GPIO_MASK) || | 459 | i2c.y_data_reg = RADEON_GPIOPAD_Y; |
458 | (ddc_line == RADEON_MDGPIO_EN_REG)) { | 460 | } else if (ddc_line == RADEON_MDGPIO_MASK) { |
459 | i2c.mask_clk_reg = ddc_line; | 461 | i2c.mask_clk_reg = RADEON_MDGPIO_MASK; |
460 | i2c.mask_data_reg = ddc_line; | 462 | i2c.mask_data_reg = RADEON_MDGPIO_MASK; |
461 | i2c.a_clk_reg = ddc_line; | 463 | i2c.a_clk_reg = RADEON_MDGPIO_A; |
462 | i2c.a_data_reg = ddc_line; | 464 | i2c.a_data_reg = RADEON_MDGPIO_A; |
463 | i2c.en_clk_reg = ddc_line; | 465 | i2c.en_clk_reg = RADEON_MDGPIO_EN; |
464 | i2c.en_data_reg = ddc_line; | 466 | i2c.en_data_reg = RADEON_MDGPIO_EN; |
465 | i2c.y_clk_reg = ddc_line + 4; | 467 | i2c.y_clk_reg = RADEON_MDGPIO_Y; |
466 | i2c.y_data_reg = ddc_line + 4; | 468 | i2c.y_data_reg = RADEON_MDGPIO_Y; |
467 | } else { | 469 | } else { |
470 | i2c.mask_clk_mask = RADEON_GPIO_EN_1; | ||
471 | i2c.mask_data_mask = RADEON_GPIO_EN_0; | ||
472 | i2c.a_clk_mask = RADEON_GPIO_A_1; | ||
473 | i2c.a_data_mask = RADEON_GPIO_A_0; | ||
474 | i2c.en_clk_mask = RADEON_GPIO_EN_1; | ||
475 | i2c.en_data_mask = RADEON_GPIO_EN_0; | ||
476 | i2c.y_clk_mask = RADEON_GPIO_Y_1; | ||
477 | i2c.y_data_mask = RADEON_GPIO_Y_0; | ||
478 | |||
468 | i2c.mask_clk_reg = ddc_line; | 479 | i2c.mask_clk_reg = ddc_line; |
469 | i2c.mask_data_reg = ddc_line; | 480 | i2c.mask_data_reg = ddc_line; |
470 | i2c.a_clk_reg = ddc_line; | 481 | i2c.a_clk_reg = ddc_line; |
@@ -475,6 +486,28 @@ struct radeon_i2c_bus_rec combios_setup_i2c_bus(int ddc_line) | |||
475 | i2c.y_data_reg = ddc_line; | 486 | i2c.y_data_reg = ddc_line; |
476 | } | 487 | } |
477 | 488 | ||
489 | if (rdev->family < CHIP_R200) | ||
490 | i2c.hw_capable = false; | ||
491 | else { | ||
492 | switch (ddc_line) { | ||
493 | case RADEON_GPIO_VGA_DDC: | ||
494 | case RADEON_GPIO_DVI_DDC: | ||
495 | i2c.hw_capable = true; | ||
496 | break; | ||
497 | case RADEON_GPIO_MONID: | ||
498 | /* hw i2c on RADEON_GPIO_MONID doesn't seem to work | ||
499 | * reliably on some pre-r4xx hardware; not sure why. | ||
500 | */ | ||
501 | i2c.hw_capable = false; | ||
502 | break; | ||
503 | default: | ||
504 | i2c.hw_capable = false; | ||
505 | break; | ||
506 | } | ||
507 | } | ||
508 | i2c.mm_i2c = false; | ||
509 | i2c.i2c_id = 0; | ||
510 | |||
478 | if (ddc_line) | 511 | if (ddc_line) |
479 | i2c.valid = true; | 512 | i2c.valid = true; |
480 | else | 513 | else |
@@ -1077,7 +1110,7 @@ bool radeon_legacy_get_ext_tmds_info_from_table(struct radeon_encoder *encoder, | |||
1077 | struct radeon_i2c_bus_rec i2c_bus; | 1110 | struct radeon_i2c_bus_rec i2c_bus; |
1078 | 1111 | ||
1079 | /* default for macs */ | 1112 | /* default for macs */ |
1080 | i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_MONID); | 1113 | i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID); |
1081 | tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO"); | 1114 | tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO"); |
1082 | 1115 | ||
1083 | /* XXX some macs have duallink chips */ | 1116 | /* XXX some macs have duallink chips */ |
@@ -1153,23 +1186,23 @@ bool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder | |||
1153 | gpio = RBIOS8(offset + 4 + 3); | 1186 | gpio = RBIOS8(offset + 4 + 3); |
1154 | switch (gpio) { | 1187 | switch (gpio) { |
1155 | case DDC_MONID: | 1188 | case DDC_MONID: |
1156 | i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_MONID); | 1189 | i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID); |
1157 | tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO"); | 1190 | tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO"); |
1158 | break; | 1191 | break; |
1159 | case DDC_DVI: | 1192 | case DDC_DVI: |
1160 | i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); | 1193 | i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); |
1161 | tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO"); | 1194 | tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO"); |
1162 | break; | 1195 | break; |
1163 | case DDC_VGA: | 1196 | case DDC_VGA: |
1164 | i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1197 | i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
1165 | tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO"); | 1198 | tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO"); |
1166 | break; | 1199 | break; |
1167 | case DDC_CRT2: | 1200 | case DDC_CRT2: |
1168 | /* R3xx+ chips don't have GPIO_CRT2_DDC gpio pad */ | 1201 | /* R3xx+ chips don't have GPIO_CRT2_DDC gpio pad */ |
1169 | if (rdev->family >= CHIP_R300) | 1202 | if (rdev->family >= CHIP_R300) |
1170 | i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_MONID); | 1203 | i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID); |
1171 | else | 1204 | else |
1172 | i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); | 1205 | i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC); |
1173 | tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO"); | 1206 | tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO"); |
1174 | break; | 1207 | break; |
1175 | case DDC_LCD: /* MM i2c */ | 1208 | case DDC_LCD: /* MM i2c */ |
@@ -1194,6 +1227,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1194 | { | 1227 | { |
1195 | struct radeon_device *rdev = dev->dev_private; | 1228 | struct radeon_device *rdev = dev->dev_private; |
1196 | struct radeon_i2c_bus_rec ddc_i2c; | 1229 | struct radeon_i2c_bus_rec ddc_i2c; |
1230 | struct radeon_hpd hpd; | ||
1197 | 1231 | ||
1198 | rdev->mode_info.connector_table = radeon_connector_table; | 1232 | rdev->mode_info.connector_table = radeon_connector_table; |
1199 | if (rdev->mode_info.connector_table == CT_NONE) { | 1233 | if (rdev->mode_info.connector_table == CT_NONE) { |
@@ -1254,7 +1288,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1254 | /* these are the most common settings */ | 1288 | /* these are the most common settings */ |
1255 | if (rdev->flags & RADEON_SINGLE_CRTC) { | 1289 | if (rdev->flags & RADEON_SINGLE_CRTC) { |
1256 | /* VGA - primary dac */ | 1290 | /* VGA - primary dac */ |
1257 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1291 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
1292 | hpd.hpd = RADEON_HPD_NONE; | ||
1258 | radeon_add_legacy_encoder(dev, | 1293 | radeon_add_legacy_encoder(dev, |
1259 | radeon_get_encoder_id(dev, | 1294 | radeon_get_encoder_id(dev, |
1260 | ATOM_DEVICE_CRT1_SUPPORT, | 1295 | ATOM_DEVICE_CRT1_SUPPORT, |
@@ -1264,10 +1299,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1264 | ATOM_DEVICE_CRT1_SUPPORT, | 1299 | ATOM_DEVICE_CRT1_SUPPORT, |
1265 | DRM_MODE_CONNECTOR_VGA, | 1300 | DRM_MODE_CONNECTOR_VGA, |
1266 | &ddc_i2c, | 1301 | &ddc_i2c, |
1267 | CONNECTOR_OBJECT_ID_VGA); | 1302 | CONNECTOR_OBJECT_ID_VGA, |
1303 | &hpd); | ||
1268 | } else if (rdev->flags & RADEON_IS_MOBILITY) { | 1304 | } else if (rdev->flags & RADEON_IS_MOBILITY) { |
1269 | /* LVDS */ | 1305 | /* LVDS */ |
1270 | ddc_i2c = combios_setup_i2c_bus(RADEON_LCD_GPIO_MASK); | 1306 | ddc_i2c = combios_setup_i2c_bus(rdev, 0); |
1307 | hpd.hpd = RADEON_HPD_NONE; | ||
1271 | radeon_add_legacy_encoder(dev, | 1308 | radeon_add_legacy_encoder(dev, |
1272 | radeon_get_encoder_id(dev, | 1309 | radeon_get_encoder_id(dev, |
1273 | ATOM_DEVICE_LCD1_SUPPORT, | 1310 | ATOM_DEVICE_LCD1_SUPPORT, |
@@ -1277,10 +1314,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1277 | ATOM_DEVICE_LCD1_SUPPORT, | 1314 | ATOM_DEVICE_LCD1_SUPPORT, |
1278 | DRM_MODE_CONNECTOR_LVDS, | 1315 | DRM_MODE_CONNECTOR_LVDS, |
1279 | &ddc_i2c, | 1316 | &ddc_i2c, |
1280 | CONNECTOR_OBJECT_ID_LVDS); | 1317 | CONNECTOR_OBJECT_ID_LVDS, |
1318 | &hpd); | ||
1281 | 1319 | ||
1282 | /* VGA - primary dac */ | 1320 | /* VGA - primary dac */ |
1283 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1321 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
1322 | hpd.hpd = RADEON_HPD_NONE; | ||
1284 | radeon_add_legacy_encoder(dev, | 1323 | radeon_add_legacy_encoder(dev, |
1285 | radeon_get_encoder_id(dev, | 1324 | radeon_get_encoder_id(dev, |
1286 | ATOM_DEVICE_CRT1_SUPPORT, | 1325 | ATOM_DEVICE_CRT1_SUPPORT, |
@@ -1290,10 +1329,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1290 | ATOM_DEVICE_CRT1_SUPPORT, | 1329 | ATOM_DEVICE_CRT1_SUPPORT, |
1291 | DRM_MODE_CONNECTOR_VGA, | 1330 | DRM_MODE_CONNECTOR_VGA, |
1292 | &ddc_i2c, | 1331 | &ddc_i2c, |
1293 | CONNECTOR_OBJECT_ID_VGA); | 1332 | CONNECTOR_OBJECT_ID_VGA, |
1333 | &hpd); | ||
1294 | } else { | 1334 | } else { |
1295 | /* DVI-I - tv dac, int tmds */ | 1335 | /* DVI-I - tv dac, int tmds */ |
1296 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); | 1336 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); |
1337 | hpd.hpd = RADEON_HPD_1; | ||
1297 | radeon_add_legacy_encoder(dev, | 1338 | radeon_add_legacy_encoder(dev, |
1298 | radeon_get_encoder_id(dev, | 1339 | radeon_get_encoder_id(dev, |
1299 | ATOM_DEVICE_DFP1_SUPPORT, | 1340 | ATOM_DEVICE_DFP1_SUPPORT, |
@@ -1309,10 +1350,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1309 | ATOM_DEVICE_CRT2_SUPPORT, | 1350 | ATOM_DEVICE_CRT2_SUPPORT, |
1310 | DRM_MODE_CONNECTOR_DVII, | 1351 | DRM_MODE_CONNECTOR_DVII, |
1311 | &ddc_i2c, | 1352 | &ddc_i2c, |
1312 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I); | 1353 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, |
1354 | &hpd); | ||
1313 | 1355 | ||
1314 | /* VGA - primary dac */ | 1356 | /* VGA - primary dac */ |
1315 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1357 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
1358 | hpd.hpd = RADEON_HPD_NONE; | ||
1316 | radeon_add_legacy_encoder(dev, | 1359 | radeon_add_legacy_encoder(dev, |
1317 | radeon_get_encoder_id(dev, | 1360 | radeon_get_encoder_id(dev, |
1318 | ATOM_DEVICE_CRT1_SUPPORT, | 1361 | ATOM_DEVICE_CRT1_SUPPORT, |
@@ -1322,11 +1365,14 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1322 | ATOM_DEVICE_CRT1_SUPPORT, | 1365 | ATOM_DEVICE_CRT1_SUPPORT, |
1323 | DRM_MODE_CONNECTOR_VGA, | 1366 | DRM_MODE_CONNECTOR_VGA, |
1324 | &ddc_i2c, | 1367 | &ddc_i2c, |
1325 | CONNECTOR_OBJECT_ID_VGA); | 1368 | CONNECTOR_OBJECT_ID_VGA, |
1369 | &hpd); | ||
1326 | } | 1370 | } |
1327 | 1371 | ||
1328 | if (rdev->family != CHIP_R100 && rdev->family != CHIP_R200) { | 1372 | if (rdev->family != CHIP_R100 && rdev->family != CHIP_R200) { |
1329 | /* TV - tv dac */ | 1373 | /* TV - tv dac */ |
1374 | ddc_i2c.valid = false; | ||
1375 | hpd.hpd = RADEON_HPD_NONE; | ||
1330 | radeon_add_legacy_encoder(dev, | 1376 | radeon_add_legacy_encoder(dev, |
1331 | radeon_get_encoder_id(dev, | 1377 | radeon_get_encoder_id(dev, |
1332 | ATOM_DEVICE_TV1_SUPPORT, | 1378 | ATOM_DEVICE_TV1_SUPPORT, |
@@ -1336,14 +1382,16 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1336 | ATOM_DEVICE_TV1_SUPPORT, | 1382 | ATOM_DEVICE_TV1_SUPPORT, |
1337 | DRM_MODE_CONNECTOR_SVIDEO, | 1383 | DRM_MODE_CONNECTOR_SVIDEO, |
1338 | &ddc_i2c, | 1384 | &ddc_i2c, |
1339 | CONNECTOR_OBJECT_ID_SVIDEO); | 1385 | CONNECTOR_OBJECT_ID_SVIDEO, |
1386 | &hpd); | ||
1340 | } | 1387 | } |
1341 | break; | 1388 | break; |
1342 | case CT_IBOOK: | 1389 | case CT_IBOOK: |
1343 | DRM_INFO("Connector Table: %d (ibook)\n", | 1390 | DRM_INFO("Connector Table: %d (ibook)\n", |
1344 | rdev->mode_info.connector_table); | 1391 | rdev->mode_info.connector_table); |
1345 | /* LVDS */ | 1392 | /* LVDS */ |
1346 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); | 1393 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); |
1394 | hpd.hpd = RADEON_HPD_NONE; | ||
1347 | radeon_add_legacy_encoder(dev, | 1395 | radeon_add_legacy_encoder(dev, |
1348 | radeon_get_encoder_id(dev, | 1396 | radeon_get_encoder_id(dev, |
1349 | ATOM_DEVICE_LCD1_SUPPORT, | 1397 | ATOM_DEVICE_LCD1_SUPPORT, |
@@ -1351,9 +1399,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1351 | ATOM_DEVICE_LCD1_SUPPORT); | 1399 | ATOM_DEVICE_LCD1_SUPPORT); |
1352 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, | 1400 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, |
1353 | DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, | 1401 | DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, |
1354 | CONNECTOR_OBJECT_ID_LVDS); | 1402 | CONNECTOR_OBJECT_ID_LVDS, |
1403 | &hpd); | ||
1355 | /* VGA - TV DAC */ | 1404 | /* VGA - TV DAC */ |
1356 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1405 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
1406 | hpd.hpd = RADEON_HPD_NONE; | ||
1357 | radeon_add_legacy_encoder(dev, | 1407 | radeon_add_legacy_encoder(dev, |
1358 | radeon_get_encoder_id(dev, | 1408 | radeon_get_encoder_id(dev, |
1359 | ATOM_DEVICE_CRT2_SUPPORT, | 1409 | ATOM_DEVICE_CRT2_SUPPORT, |
@@ -1361,8 +1411,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1361 | ATOM_DEVICE_CRT2_SUPPORT); | 1411 | ATOM_DEVICE_CRT2_SUPPORT); |
1362 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, | 1412 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, |
1363 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c, | 1413 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c, |
1364 | CONNECTOR_OBJECT_ID_VGA); | 1414 | CONNECTOR_OBJECT_ID_VGA, |
1415 | &hpd); | ||
1365 | /* TV - TV DAC */ | 1416 | /* TV - TV DAC */ |
1417 | ddc_i2c.valid = false; | ||
1418 | hpd.hpd = RADEON_HPD_NONE; | ||
1366 | radeon_add_legacy_encoder(dev, | 1419 | radeon_add_legacy_encoder(dev, |
1367 | radeon_get_encoder_id(dev, | 1420 | radeon_get_encoder_id(dev, |
1368 | ATOM_DEVICE_TV1_SUPPORT, | 1421 | ATOM_DEVICE_TV1_SUPPORT, |
@@ -1371,13 +1424,15 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1371 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, | 1424 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, |
1372 | DRM_MODE_CONNECTOR_SVIDEO, | 1425 | DRM_MODE_CONNECTOR_SVIDEO, |
1373 | &ddc_i2c, | 1426 | &ddc_i2c, |
1374 | CONNECTOR_OBJECT_ID_SVIDEO); | 1427 | CONNECTOR_OBJECT_ID_SVIDEO, |
1428 | &hpd); | ||
1375 | break; | 1429 | break; |
1376 | case CT_POWERBOOK_EXTERNAL: | 1430 | case CT_POWERBOOK_EXTERNAL: |
1377 | DRM_INFO("Connector Table: %d (powerbook external tmds)\n", | 1431 | DRM_INFO("Connector Table: %d (powerbook external tmds)\n", |
1378 | rdev->mode_info.connector_table); | 1432 | rdev->mode_info.connector_table); |
1379 | /* LVDS */ | 1433 | /* LVDS */ |
1380 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); | 1434 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); |
1435 | hpd.hpd = RADEON_HPD_NONE; | ||
1381 | radeon_add_legacy_encoder(dev, | 1436 | radeon_add_legacy_encoder(dev, |
1382 | radeon_get_encoder_id(dev, | 1437 | radeon_get_encoder_id(dev, |
1383 | ATOM_DEVICE_LCD1_SUPPORT, | 1438 | ATOM_DEVICE_LCD1_SUPPORT, |
@@ -1385,9 +1440,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1385 | ATOM_DEVICE_LCD1_SUPPORT); | 1440 | ATOM_DEVICE_LCD1_SUPPORT); |
1386 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, | 1441 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, |
1387 | DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, | 1442 | DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, |
1388 | CONNECTOR_OBJECT_ID_LVDS); | 1443 | CONNECTOR_OBJECT_ID_LVDS, |
1444 | &hpd); | ||
1389 | /* DVI-I - primary dac, ext tmds */ | 1445 | /* DVI-I - primary dac, ext tmds */ |
1390 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1446 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
1447 | hpd.hpd = RADEON_HPD_2; /* ??? */ | ||
1391 | radeon_add_legacy_encoder(dev, | 1448 | radeon_add_legacy_encoder(dev, |
1392 | radeon_get_encoder_id(dev, | 1449 | radeon_get_encoder_id(dev, |
1393 | ATOM_DEVICE_DFP2_SUPPORT, | 1450 | ATOM_DEVICE_DFP2_SUPPORT, |
@@ -1403,8 +1460,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1403 | ATOM_DEVICE_DFP2_SUPPORT | | 1460 | ATOM_DEVICE_DFP2_SUPPORT | |
1404 | ATOM_DEVICE_CRT1_SUPPORT, | 1461 | ATOM_DEVICE_CRT1_SUPPORT, |
1405 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c, | 1462 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c, |
1406 | CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I); | 1463 | CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I, |
1464 | &hpd); | ||
1407 | /* TV - TV DAC */ | 1465 | /* TV - TV DAC */ |
1466 | ddc_i2c.valid = false; | ||
1467 | hpd.hpd = RADEON_HPD_NONE; | ||
1408 | radeon_add_legacy_encoder(dev, | 1468 | radeon_add_legacy_encoder(dev, |
1409 | radeon_get_encoder_id(dev, | 1469 | radeon_get_encoder_id(dev, |
1410 | ATOM_DEVICE_TV1_SUPPORT, | 1470 | ATOM_DEVICE_TV1_SUPPORT, |
@@ -1413,13 +1473,15 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1413 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, | 1473 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, |
1414 | DRM_MODE_CONNECTOR_SVIDEO, | 1474 | DRM_MODE_CONNECTOR_SVIDEO, |
1415 | &ddc_i2c, | 1475 | &ddc_i2c, |
1416 | CONNECTOR_OBJECT_ID_SVIDEO); | 1476 | CONNECTOR_OBJECT_ID_SVIDEO, |
1477 | &hpd); | ||
1417 | break; | 1478 | break; |
1418 | case CT_POWERBOOK_INTERNAL: | 1479 | case CT_POWERBOOK_INTERNAL: |
1419 | DRM_INFO("Connector Table: %d (powerbook internal tmds)\n", | 1480 | DRM_INFO("Connector Table: %d (powerbook internal tmds)\n", |
1420 | rdev->mode_info.connector_table); | 1481 | rdev->mode_info.connector_table); |
1421 | /* LVDS */ | 1482 | /* LVDS */ |
1422 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); | 1483 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); |
1484 | hpd.hpd = RADEON_HPD_NONE; | ||
1423 | radeon_add_legacy_encoder(dev, | 1485 | radeon_add_legacy_encoder(dev, |
1424 | radeon_get_encoder_id(dev, | 1486 | radeon_get_encoder_id(dev, |
1425 | ATOM_DEVICE_LCD1_SUPPORT, | 1487 | ATOM_DEVICE_LCD1_SUPPORT, |
@@ -1427,9 +1489,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1427 | ATOM_DEVICE_LCD1_SUPPORT); | 1489 | ATOM_DEVICE_LCD1_SUPPORT); |
1428 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, | 1490 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, |
1429 | DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, | 1491 | DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, |
1430 | CONNECTOR_OBJECT_ID_LVDS); | 1492 | CONNECTOR_OBJECT_ID_LVDS, |
1493 | &hpd); | ||
1431 | /* DVI-I - primary dac, int tmds */ | 1494 | /* DVI-I - primary dac, int tmds */ |
1432 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1495 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
1496 | hpd.hpd = RADEON_HPD_1; /* ??? */ | ||
1433 | radeon_add_legacy_encoder(dev, | 1497 | radeon_add_legacy_encoder(dev, |
1434 | radeon_get_encoder_id(dev, | 1498 | radeon_get_encoder_id(dev, |
1435 | ATOM_DEVICE_DFP1_SUPPORT, | 1499 | ATOM_DEVICE_DFP1_SUPPORT, |
@@ -1444,8 +1508,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1444 | ATOM_DEVICE_DFP1_SUPPORT | | 1508 | ATOM_DEVICE_DFP1_SUPPORT | |
1445 | ATOM_DEVICE_CRT1_SUPPORT, | 1509 | ATOM_DEVICE_CRT1_SUPPORT, |
1446 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c, | 1510 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c, |
1447 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I); | 1511 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, |
1512 | &hpd); | ||
1448 | /* TV - TV DAC */ | 1513 | /* TV - TV DAC */ |
1514 | ddc_i2c.valid = false; | ||
1515 | hpd.hpd = RADEON_HPD_NONE; | ||
1449 | radeon_add_legacy_encoder(dev, | 1516 | radeon_add_legacy_encoder(dev, |
1450 | radeon_get_encoder_id(dev, | 1517 | radeon_get_encoder_id(dev, |
1451 | ATOM_DEVICE_TV1_SUPPORT, | 1518 | ATOM_DEVICE_TV1_SUPPORT, |
@@ -1454,13 +1521,15 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1454 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, | 1521 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, |
1455 | DRM_MODE_CONNECTOR_SVIDEO, | 1522 | DRM_MODE_CONNECTOR_SVIDEO, |
1456 | &ddc_i2c, | 1523 | &ddc_i2c, |
1457 | CONNECTOR_OBJECT_ID_SVIDEO); | 1524 | CONNECTOR_OBJECT_ID_SVIDEO, |
1525 | &hpd); | ||
1458 | break; | 1526 | break; |
1459 | case CT_POWERBOOK_VGA: | 1527 | case CT_POWERBOOK_VGA: |
1460 | DRM_INFO("Connector Table: %d (powerbook vga)\n", | 1528 | DRM_INFO("Connector Table: %d (powerbook vga)\n", |
1461 | rdev->mode_info.connector_table); | 1529 | rdev->mode_info.connector_table); |
1462 | /* LVDS */ | 1530 | /* LVDS */ |
1463 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); | 1531 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); |
1532 | hpd.hpd = RADEON_HPD_NONE; | ||
1464 | radeon_add_legacy_encoder(dev, | 1533 | radeon_add_legacy_encoder(dev, |
1465 | radeon_get_encoder_id(dev, | 1534 | radeon_get_encoder_id(dev, |
1466 | ATOM_DEVICE_LCD1_SUPPORT, | 1535 | ATOM_DEVICE_LCD1_SUPPORT, |
@@ -1468,9 +1537,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1468 | ATOM_DEVICE_LCD1_SUPPORT); | 1537 | ATOM_DEVICE_LCD1_SUPPORT); |
1469 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, | 1538 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, |
1470 | DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, | 1539 | DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, |
1471 | CONNECTOR_OBJECT_ID_LVDS); | 1540 | CONNECTOR_OBJECT_ID_LVDS, |
1541 | &hpd); | ||
1472 | /* VGA - primary dac */ | 1542 | /* VGA - primary dac */ |
1473 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1543 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
1544 | hpd.hpd = RADEON_HPD_NONE; | ||
1474 | radeon_add_legacy_encoder(dev, | 1545 | radeon_add_legacy_encoder(dev, |
1475 | radeon_get_encoder_id(dev, | 1546 | radeon_get_encoder_id(dev, |
1476 | ATOM_DEVICE_CRT1_SUPPORT, | 1547 | ATOM_DEVICE_CRT1_SUPPORT, |
@@ -1478,8 +1549,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1478 | ATOM_DEVICE_CRT1_SUPPORT); | 1549 | ATOM_DEVICE_CRT1_SUPPORT); |
1479 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT, | 1550 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT, |
1480 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c, | 1551 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c, |
1481 | CONNECTOR_OBJECT_ID_VGA); | 1552 | CONNECTOR_OBJECT_ID_VGA, |
1553 | &hpd); | ||
1482 | /* TV - TV DAC */ | 1554 | /* TV - TV DAC */ |
1555 | ddc_i2c.valid = false; | ||
1556 | hpd.hpd = RADEON_HPD_NONE; | ||
1483 | radeon_add_legacy_encoder(dev, | 1557 | radeon_add_legacy_encoder(dev, |
1484 | radeon_get_encoder_id(dev, | 1558 | radeon_get_encoder_id(dev, |
1485 | ATOM_DEVICE_TV1_SUPPORT, | 1559 | ATOM_DEVICE_TV1_SUPPORT, |
@@ -1488,13 +1562,15 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1488 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, | 1562 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, |
1489 | DRM_MODE_CONNECTOR_SVIDEO, | 1563 | DRM_MODE_CONNECTOR_SVIDEO, |
1490 | &ddc_i2c, | 1564 | &ddc_i2c, |
1491 | CONNECTOR_OBJECT_ID_SVIDEO); | 1565 | CONNECTOR_OBJECT_ID_SVIDEO, |
1566 | &hpd); | ||
1492 | break; | 1567 | break; |
1493 | case CT_MINI_EXTERNAL: | 1568 | case CT_MINI_EXTERNAL: |
1494 | DRM_INFO("Connector Table: %d (mini external tmds)\n", | 1569 | DRM_INFO("Connector Table: %d (mini external tmds)\n", |
1495 | rdev->mode_info.connector_table); | 1570 | rdev->mode_info.connector_table); |
1496 | /* DVI-I - tv dac, ext tmds */ | 1571 | /* DVI-I - tv dac, ext tmds */ |
1497 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); | 1572 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC); |
1573 | hpd.hpd = RADEON_HPD_2; /* ??? */ | ||
1498 | radeon_add_legacy_encoder(dev, | 1574 | radeon_add_legacy_encoder(dev, |
1499 | radeon_get_encoder_id(dev, | 1575 | radeon_get_encoder_id(dev, |
1500 | ATOM_DEVICE_DFP2_SUPPORT, | 1576 | ATOM_DEVICE_DFP2_SUPPORT, |
@@ -1510,8 +1586,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1510 | ATOM_DEVICE_DFP2_SUPPORT | | 1586 | ATOM_DEVICE_DFP2_SUPPORT | |
1511 | ATOM_DEVICE_CRT2_SUPPORT, | 1587 | ATOM_DEVICE_CRT2_SUPPORT, |
1512 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c, | 1588 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c, |
1513 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I); | 1589 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, |
1590 | &hpd); | ||
1514 | /* TV - TV DAC */ | 1591 | /* TV - TV DAC */ |
1592 | ddc_i2c.valid = false; | ||
1593 | hpd.hpd = RADEON_HPD_NONE; | ||
1515 | radeon_add_legacy_encoder(dev, | 1594 | radeon_add_legacy_encoder(dev, |
1516 | radeon_get_encoder_id(dev, | 1595 | radeon_get_encoder_id(dev, |
1517 | ATOM_DEVICE_TV1_SUPPORT, | 1596 | ATOM_DEVICE_TV1_SUPPORT, |
@@ -1520,13 +1599,15 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1520 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT, | 1599 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT, |
1521 | DRM_MODE_CONNECTOR_SVIDEO, | 1600 | DRM_MODE_CONNECTOR_SVIDEO, |
1522 | &ddc_i2c, | 1601 | &ddc_i2c, |
1523 | CONNECTOR_OBJECT_ID_SVIDEO); | 1602 | CONNECTOR_OBJECT_ID_SVIDEO, |
1603 | &hpd); | ||
1524 | break; | 1604 | break; |
1525 | case CT_MINI_INTERNAL: | 1605 | case CT_MINI_INTERNAL: |
1526 | DRM_INFO("Connector Table: %d (mini internal tmds)\n", | 1606 | DRM_INFO("Connector Table: %d (mini internal tmds)\n", |
1527 | rdev->mode_info.connector_table); | 1607 | rdev->mode_info.connector_table); |
1528 | /* DVI-I - tv dac, int tmds */ | 1608 | /* DVI-I - tv dac, int tmds */ |
1529 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); | 1609 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC); |
1610 | hpd.hpd = RADEON_HPD_1; /* ??? */ | ||
1530 | radeon_add_legacy_encoder(dev, | 1611 | radeon_add_legacy_encoder(dev, |
1531 | radeon_get_encoder_id(dev, | 1612 | radeon_get_encoder_id(dev, |
1532 | ATOM_DEVICE_DFP1_SUPPORT, | 1613 | ATOM_DEVICE_DFP1_SUPPORT, |
@@ -1541,8 +1622,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1541 | ATOM_DEVICE_DFP1_SUPPORT | | 1622 | ATOM_DEVICE_DFP1_SUPPORT | |
1542 | ATOM_DEVICE_CRT2_SUPPORT, | 1623 | ATOM_DEVICE_CRT2_SUPPORT, |
1543 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c, | 1624 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c, |
1544 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I); | 1625 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, |
1626 | &hpd); | ||
1545 | /* TV - TV DAC */ | 1627 | /* TV - TV DAC */ |
1628 | ddc_i2c.valid = false; | ||
1629 | hpd.hpd = RADEON_HPD_NONE; | ||
1546 | radeon_add_legacy_encoder(dev, | 1630 | radeon_add_legacy_encoder(dev, |
1547 | radeon_get_encoder_id(dev, | 1631 | radeon_get_encoder_id(dev, |
1548 | ATOM_DEVICE_TV1_SUPPORT, | 1632 | ATOM_DEVICE_TV1_SUPPORT, |
@@ -1551,13 +1635,15 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1551 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT, | 1635 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT, |
1552 | DRM_MODE_CONNECTOR_SVIDEO, | 1636 | DRM_MODE_CONNECTOR_SVIDEO, |
1553 | &ddc_i2c, | 1637 | &ddc_i2c, |
1554 | CONNECTOR_OBJECT_ID_SVIDEO); | 1638 | CONNECTOR_OBJECT_ID_SVIDEO, |
1639 | &hpd); | ||
1555 | break; | 1640 | break; |
1556 | case CT_IMAC_G5_ISIGHT: | 1641 | case CT_IMAC_G5_ISIGHT: |
1557 | DRM_INFO("Connector Table: %d (imac g5 isight)\n", | 1642 | DRM_INFO("Connector Table: %d (imac g5 isight)\n", |
1558 | rdev->mode_info.connector_table); | 1643 | rdev->mode_info.connector_table); |
1559 | /* DVI-D - int tmds */ | 1644 | /* DVI-D - int tmds */ |
1560 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_MONID); | 1645 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID); |
1646 | hpd.hpd = RADEON_HPD_1; /* ??? */ | ||
1561 | radeon_add_legacy_encoder(dev, | 1647 | radeon_add_legacy_encoder(dev, |
1562 | radeon_get_encoder_id(dev, | 1648 | radeon_get_encoder_id(dev, |
1563 | ATOM_DEVICE_DFP1_SUPPORT, | 1649 | ATOM_DEVICE_DFP1_SUPPORT, |
@@ -1565,9 +1651,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1565 | ATOM_DEVICE_DFP1_SUPPORT); | 1651 | ATOM_DEVICE_DFP1_SUPPORT); |
1566 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_DFP1_SUPPORT, | 1652 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_DFP1_SUPPORT, |
1567 | DRM_MODE_CONNECTOR_DVID, &ddc_i2c, | 1653 | DRM_MODE_CONNECTOR_DVID, &ddc_i2c, |
1568 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D); | 1654 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D, |
1655 | &hpd); | ||
1569 | /* VGA - tv dac */ | 1656 | /* VGA - tv dac */ |
1570 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); | 1657 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); |
1658 | hpd.hpd = RADEON_HPD_NONE; | ||
1571 | radeon_add_legacy_encoder(dev, | 1659 | radeon_add_legacy_encoder(dev, |
1572 | radeon_get_encoder_id(dev, | 1660 | radeon_get_encoder_id(dev, |
1573 | ATOM_DEVICE_CRT2_SUPPORT, | 1661 | ATOM_DEVICE_CRT2_SUPPORT, |
@@ -1575,8 +1663,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1575 | ATOM_DEVICE_CRT2_SUPPORT); | 1663 | ATOM_DEVICE_CRT2_SUPPORT); |
1576 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, | 1664 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, |
1577 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c, | 1665 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c, |
1578 | CONNECTOR_OBJECT_ID_VGA); | 1666 | CONNECTOR_OBJECT_ID_VGA, |
1667 | &hpd); | ||
1579 | /* TV - TV DAC */ | 1668 | /* TV - TV DAC */ |
1669 | ddc_i2c.valid = false; | ||
1670 | hpd.hpd = RADEON_HPD_NONE; | ||
1580 | radeon_add_legacy_encoder(dev, | 1671 | radeon_add_legacy_encoder(dev, |
1581 | radeon_get_encoder_id(dev, | 1672 | radeon_get_encoder_id(dev, |
1582 | ATOM_DEVICE_TV1_SUPPORT, | 1673 | ATOM_DEVICE_TV1_SUPPORT, |
@@ -1585,13 +1676,15 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1585 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, | 1676 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, |
1586 | DRM_MODE_CONNECTOR_SVIDEO, | 1677 | DRM_MODE_CONNECTOR_SVIDEO, |
1587 | &ddc_i2c, | 1678 | &ddc_i2c, |
1588 | CONNECTOR_OBJECT_ID_SVIDEO); | 1679 | CONNECTOR_OBJECT_ID_SVIDEO, |
1680 | &hpd); | ||
1589 | break; | 1681 | break; |
1590 | case CT_EMAC: | 1682 | case CT_EMAC: |
1591 | DRM_INFO("Connector Table: %d (emac)\n", | 1683 | DRM_INFO("Connector Table: %d (emac)\n", |
1592 | rdev->mode_info.connector_table); | 1684 | rdev->mode_info.connector_table); |
1593 | /* VGA - primary dac */ | 1685 | /* VGA - primary dac */ |
1594 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1686 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
1687 | hpd.hpd = RADEON_HPD_NONE; | ||
1595 | radeon_add_legacy_encoder(dev, | 1688 | radeon_add_legacy_encoder(dev, |
1596 | radeon_get_encoder_id(dev, | 1689 | radeon_get_encoder_id(dev, |
1597 | ATOM_DEVICE_CRT1_SUPPORT, | 1690 | ATOM_DEVICE_CRT1_SUPPORT, |
@@ -1599,9 +1692,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1599 | ATOM_DEVICE_CRT1_SUPPORT); | 1692 | ATOM_DEVICE_CRT1_SUPPORT); |
1600 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_CRT1_SUPPORT, | 1693 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_CRT1_SUPPORT, |
1601 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c, | 1694 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c, |
1602 | CONNECTOR_OBJECT_ID_VGA); | 1695 | CONNECTOR_OBJECT_ID_VGA, |
1696 | &hpd); | ||
1603 | /* VGA - tv dac */ | 1697 | /* VGA - tv dac */ |
1604 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); | 1698 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC); |
1699 | hpd.hpd = RADEON_HPD_NONE; | ||
1605 | radeon_add_legacy_encoder(dev, | 1700 | radeon_add_legacy_encoder(dev, |
1606 | radeon_get_encoder_id(dev, | 1701 | radeon_get_encoder_id(dev, |
1607 | ATOM_DEVICE_CRT2_SUPPORT, | 1702 | ATOM_DEVICE_CRT2_SUPPORT, |
@@ -1609,8 +1704,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1609 | ATOM_DEVICE_CRT2_SUPPORT); | 1704 | ATOM_DEVICE_CRT2_SUPPORT); |
1610 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, | 1705 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, |
1611 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c, | 1706 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c, |
1612 | CONNECTOR_OBJECT_ID_VGA); | 1707 | CONNECTOR_OBJECT_ID_VGA, |
1708 | &hpd); | ||
1613 | /* TV - TV DAC */ | 1709 | /* TV - TV DAC */ |
1710 | ddc_i2c.valid = false; | ||
1711 | hpd.hpd = RADEON_HPD_NONE; | ||
1614 | radeon_add_legacy_encoder(dev, | 1712 | radeon_add_legacy_encoder(dev, |
1615 | radeon_get_encoder_id(dev, | 1713 | radeon_get_encoder_id(dev, |
1616 | ATOM_DEVICE_TV1_SUPPORT, | 1714 | ATOM_DEVICE_TV1_SUPPORT, |
@@ -1619,7 +1717,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1619 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, | 1717 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, |
1620 | DRM_MODE_CONNECTOR_SVIDEO, | 1718 | DRM_MODE_CONNECTOR_SVIDEO, |
1621 | &ddc_i2c, | 1719 | &ddc_i2c, |
1622 | CONNECTOR_OBJECT_ID_SVIDEO); | 1720 | CONNECTOR_OBJECT_ID_SVIDEO, |
1721 | &hpd); | ||
1623 | break; | 1722 | break; |
1624 | default: | 1723 | default: |
1625 | DRM_INFO("Connector table: %d (invalid)\n", | 1724 | DRM_INFO("Connector table: %d (invalid)\n", |
@@ -1636,7 +1735,8 @@ static bool radeon_apply_legacy_quirks(struct drm_device *dev, | |||
1636 | int bios_index, | 1735 | int bios_index, |
1637 | enum radeon_combios_connector | 1736 | enum radeon_combios_connector |
1638 | *legacy_connector, | 1737 | *legacy_connector, |
1639 | struct radeon_i2c_bus_rec *ddc_i2c) | 1738 | struct radeon_i2c_bus_rec *ddc_i2c, |
1739 | struct radeon_hpd *hpd) | ||
1640 | { | 1740 | { |
1641 | struct radeon_device *rdev = dev->dev_private; | 1741 | struct radeon_device *rdev = dev->dev_private; |
1642 | 1742 | ||
@@ -1644,11 +1744,11 @@ static bool radeon_apply_legacy_quirks(struct drm_device *dev, | |||
1644 | if ((rdev->family == CHIP_RS400 || | 1744 | if ((rdev->family == CHIP_RS400 || |
1645 | rdev->family == CHIP_RS480) && | 1745 | rdev->family == CHIP_RS480) && |
1646 | ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC) | 1746 | ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC) |
1647 | *ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_MONID); | 1747 | *ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID); |
1648 | else if ((rdev->family == CHIP_RS400 || | 1748 | else if ((rdev->family == CHIP_RS400 || |
1649 | rdev->family == CHIP_RS480) && | 1749 | rdev->family == CHIP_RS480) && |
1650 | ddc_i2c->mask_clk_reg == RADEON_GPIO_MONID) { | 1750 | ddc_i2c->mask_clk_reg == RADEON_GPIO_MONID) { |
1651 | ddc_i2c->valid = true; | 1751 | *ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIOPAD_MASK); |
1652 | ddc_i2c->mask_clk_mask = (0x20 << 8); | 1752 | ddc_i2c->mask_clk_mask = (0x20 << 8); |
1653 | ddc_i2c->mask_data_mask = 0x80; | 1753 | ddc_i2c->mask_data_mask = 0x80; |
1654 | ddc_i2c->a_clk_mask = (0x20 << 8); | 1754 | ddc_i2c->a_clk_mask = (0x20 << 8); |
@@ -1657,20 +1757,12 @@ static bool radeon_apply_legacy_quirks(struct drm_device *dev, | |||
1657 | ddc_i2c->en_data_mask = 0x80; | 1757 | ddc_i2c->en_data_mask = 0x80; |
1658 | ddc_i2c->y_clk_mask = (0x20 << 8); | 1758 | ddc_i2c->y_clk_mask = (0x20 << 8); |
1659 | ddc_i2c->y_data_mask = 0x80; | 1759 | ddc_i2c->y_data_mask = 0x80; |
1660 | ddc_i2c->mask_clk_reg = RADEON_GPIOPAD_MASK; | ||
1661 | ddc_i2c->mask_data_reg = RADEON_GPIOPAD_MASK; | ||
1662 | ddc_i2c->a_clk_reg = RADEON_GPIOPAD_A; | ||
1663 | ddc_i2c->a_data_reg = RADEON_GPIOPAD_A; | ||
1664 | ddc_i2c->en_clk_reg = RADEON_GPIOPAD_EN; | ||
1665 | ddc_i2c->en_data_reg = RADEON_GPIOPAD_EN; | ||
1666 | ddc_i2c->y_clk_reg = RADEON_GPIOPAD_Y; | ||
1667 | ddc_i2c->y_data_reg = RADEON_GPIOPAD_Y; | ||
1668 | } | 1760 | } |
1669 | 1761 | ||
1670 | /* R3xx+ chips don't have GPIO_CRT2_DDC gpio pad */ | 1762 | /* R3xx+ chips don't have GPIO_CRT2_DDC gpio pad */ |
1671 | if ((rdev->family >= CHIP_R300) && | 1763 | if ((rdev->family >= CHIP_R300) && |
1672 | ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC) | 1764 | ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC) |
1673 | *ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); | 1765 | *ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); |
1674 | 1766 | ||
1675 | /* Certain IBM chipset RN50s have a BIOS reporting two VGAs, | 1767 | /* Certain IBM chipset RN50s have a BIOS reporting two VGAs, |
1676 | one with VGA DDC and one with CRT2 DDC. - kill the CRT2 DDC one */ | 1768 | one with VGA DDC and one with CRT2 DDC. - kill the CRT2 DDC one */ |
@@ -1768,6 +1860,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
1768 | enum radeon_combios_connector connector; | 1860 | enum radeon_combios_connector connector; |
1769 | int i = 0; | 1861 | int i = 0; |
1770 | struct radeon_i2c_bus_rec ddc_i2c; | 1862 | struct radeon_i2c_bus_rec ddc_i2c; |
1863 | struct radeon_hpd hpd; | ||
1771 | 1864 | ||
1772 | if (rdev->bios == NULL) | 1865 | if (rdev->bios == NULL) |
1773 | return false; | 1866 | return false; |
@@ -1788,26 +1881,40 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
1788 | switch (ddc_type) { | 1881 | switch (ddc_type) { |
1789 | case DDC_MONID: | 1882 | case DDC_MONID: |
1790 | ddc_i2c = | 1883 | ddc_i2c = |
1791 | combios_setup_i2c_bus(RADEON_GPIO_MONID); | 1884 | combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID); |
1792 | break; | 1885 | break; |
1793 | case DDC_DVI: | 1886 | case DDC_DVI: |
1794 | ddc_i2c = | 1887 | ddc_i2c = |
1795 | combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); | 1888 | combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); |
1796 | break; | 1889 | break; |
1797 | case DDC_VGA: | 1890 | case DDC_VGA: |
1798 | ddc_i2c = | 1891 | ddc_i2c = |
1799 | combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1892 | combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
1800 | break; | 1893 | break; |
1801 | case DDC_CRT2: | 1894 | case DDC_CRT2: |
1802 | ddc_i2c = | 1895 | ddc_i2c = |
1803 | combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); | 1896 | combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC); |
1897 | break; | ||
1898 | default: | ||
1899 | break; | ||
1900 | } | ||
1901 | |||
1902 | switch (connector) { | ||
1903 | case CONNECTOR_PROPRIETARY_LEGACY: | ||
1904 | case CONNECTOR_DVI_I_LEGACY: | ||
1905 | case CONNECTOR_DVI_D_LEGACY: | ||
1906 | if ((tmp >> 4) & 0x1) | ||
1907 | hpd.hpd = RADEON_HPD_2; | ||
1908 | else | ||
1909 | hpd.hpd = RADEON_HPD_1; | ||
1804 | break; | 1910 | break; |
1805 | default: | 1911 | default: |
1912 | hpd.hpd = RADEON_HPD_NONE; | ||
1806 | break; | 1913 | break; |
1807 | } | 1914 | } |
1808 | 1915 | ||
1809 | if (!radeon_apply_legacy_quirks(dev, i, &connector, | 1916 | if (!radeon_apply_legacy_quirks(dev, i, &connector, |
1810 | &ddc_i2c)) | 1917 | &ddc_i2c, &hpd)) |
1811 | continue; | 1918 | continue; |
1812 | 1919 | ||
1813 | switch (connector) { | 1920 | switch (connector) { |
@@ -1824,7 +1931,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
1824 | legacy_connector_convert | 1931 | legacy_connector_convert |
1825 | [connector], | 1932 | [connector], |
1826 | &ddc_i2c, | 1933 | &ddc_i2c, |
1827 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D); | 1934 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D, |
1935 | &hpd); | ||
1828 | break; | 1936 | break; |
1829 | case CONNECTOR_CRT_LEGACY: | 1937 | case CONNECTOR_CRT_LEGACY: |
1830 | if (tmp & 0x1) { | 1938 | if (tmp & 0x1) { |
@@ -1850,7 +1958,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
1850 | legacy_connector_convert | 1958 | legacy_connector_convert |
1851 | [connector], | 1959 | [connector], |
1852 | &ddc_i2c, | 1960 | &ddc_i2c, |
1853 | CONNECTOR_OBJECT_ID_VGA); | 1961 | CONNECTOR_OBJECT_ID_VGA, |
1962 | &hpd); | ||
1854 | break; | 1963 | break; |
1855 | case CONNECTOR_DVI_I_LEGACY: | 1964 | case CONNECTOR_DVI_I_LEGACY: |
1856 | devices = 0; | 1965 | devices = 0; |
@@ -1896,7 +2005,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
1896 | legacy_connector_convert | 2005 | legacy_connector_convert |
1897 | [connector], | 2006 | [connector], |
1898 | &ddc_i2c, | 2007 | &ddc_i2c, |
1899 | connector_object_id); | 2008 | connector_object_id, |
2009 | &hpd); | ||
1900 | break; | 2010 | break; |
1901 | case CONNECTOR_DVI_D_LEGACY: | 2011 | case CONNECTOR_DVI_D_LEGACY: |
1902 | if ((tmp >> 4) & 0x1) { | 2012 | if ((tmp >> 4) & 0x1) { |
@@ -1914,7 +2024,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
1914 | legacy_connector_convert | 2024 | legacy_connector_convert |
1915 | [connector], | 2025 | [connector], |
1916 | &ddc_i2c, | 2026 | &ddc_i2c, |
1917 | connector_object_id); | 2027 | connector_object_id, |
2028 | &hpd); | ||
1918 | break; | 2029 | break; |
1919 | case CONNECTOR_CTV_LEGACY: | 2030 | case CONNECTOR_CTV_LEGACY: |
1920 | case CONNECTOR_STV_LEGACY: | 2031 | case CONNECTOR_STV_LEGACY: |
@@ -1929,7 +2040,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
1929 | legacy_connector_convert | 2040 | legacy_connector_convert |
1930 | [connector], | 2041 | [connector], |
1931 | &ddc_i2c, | 2042 | &ddc_i2c, |
1932 | CONNECTOR_OBJECT_ID_SVIDEO); | 2043 | CONNECTOR_OBJECT_ID_SVIDEO, |
2044 | &hpd); | ||
1933 | break; | 2045 | break; |
1934 | default: | 2046 | default: |
1935 | DRM_ERROR("Unknown connector type: %d\n", | 2047 | DRM_ERROR("Unknown connector type: %d\n", |
@@ -1955,14 +2067,16 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
1955 | 0), | 2067 | 0), |
1956 | ATOM_DEVICE_DFP1_SUPPORT); | 2068 | ATOM_DEVICE_DFP1_SUPPORT); |
1957 | 2069 | ||
1958 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); | 2070 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); |
2071 | hpd.hpd = RADEON_HPD_NONE; | ||
1959 | radeon_add_legacy_connector(dev, | 2072 | radeon_add_legacy_connector(dev, |
1960 | 0, | 2073 | 0, |
1961 | ATOM_DEVICE_CRT1_SUPPORT | | 2074 | ATOM_DEVICE_CRT1_SUPPORT | |
1962 | ATOM_DEVICE_DFP1_SUPPORT, | 2075 | ATOM_DEVICE_DFP1_SUPPORT, |
1963 | DRM_MODE_CONNECTOR_DVII, | 2076 | DRM_MODE_CONNECTOR_DVII, |
1964 | &ddc_i2c, | 2077 | &ddc_i2c, |
1965 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I); | 2078 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, |
2079 | &hpd); | ||
1966 | } else { | 2080 | } else { |
1967 | uint16_t crt_info = | 2081 | uint16_t crt_info = |
1968 | combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE); | 2082 | combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE); |
@@ -1973,13 +2087,15 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
1973 | ATOM_DEVICE_CRT1_SUPPORT, | 2087 | ATOM_DEVICE_CRT1_SUPPORT, |
1974 | 1), | 2088 | 1), |
1975 | ATOM_DEVICE_CRT1_SUPPORT); | 2089 | ATOM_DEVICE_CRT1_SUPPORT); |
1976 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 2090 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
2091 | hpd.hpd = RADEON_HPD_NONE; | ||
1977 | radeon_add_legacy_connector(dev, | 2092 | radeon_add_legacy_connector(dev, |
1978 | 0, | 2093 | 0, |
1979 | ATOM_DEVICE_CRT1_SUPPORT, | 2094 | ATOM_DEVICE_CRT1_SUPPORT, |
1980 | DRM_MODE_CONNECTOR_VGA, | 2095 | DRM_MODE_CONNECTOR_VGA, |
1981 | &ddc_i2c, | 2096 | &ddc_i2c, |
1982 | CONNECTOR_OBJECT_ID_VGA); | 2097 | CONNECTOR_OBJECT_ID_VGA, |
2098 | &hpd); | ||
1983 | } else { | 2099 | } else { |
1984 | DRM_DEBUG("No connector info found\n"); | 2100 | DRM_DEBUG("No connector info found\n"); |
1985 | return false; | 2101 | return false; |
@@ -2007,27 +2123,27 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2007 | case DDC_MONID: | 2123 | case DDC_MONID: |
2008 | ddc_i2c = | 2124 | ddc_i2c = |
2009 | combios_setup_i2c_bus | 2125 | combios_setup_i2c_bus |
2010 | (RADEON_GPIO_MONID); | 2126 | (rdev, RADEON_GPIO_MONID); |
2011 | break; | 2127 | break; |
2012 | case DDC_DVI: | 2128 | case DDC_DVI: |
2013 | ddc_i2c = | 2129 | ddc_i2c = |
2014 | combios_setup_i2c_bus | 2130 | combios_setup_i2c_bus |
2015 | (RADEON_GPIO_DVI_DDC); | 2131 | (rdev, RADEON_GPIO_DVI_DDC); |
2016 | break; | 2132 | break; |
2017 | case DDC_VGA: | 2133 | case DDC_VGA: |
2018 | ddc_i2c = | 2134 | ddc_i2c = |
2019 | combios_setup_i2c_bus | 2135 | combios_setup_i2c_bus |
2020 | (RADEON_GPIO_VGA_DDC); | 2136 | (rdev, RADEON_GPIO_VGA_DDC); |
2021 | break; | 2137 | break; |
2022 | case DDC_CRT2: | 2138 | case DDC_CRT2: |
2023 | ddc_i2c = | 2139 | ddc_i2c = |
2024 | combios_setup_i2c_bus | 2140 | combios_setup_i2c_bus |
2025 | (RADEON_GPIO_CRT2_DDC); | 2141 | (rdev, RADEON_GPIO_CRT2_DDC); |
2026 | break; | 2142 | break; |
2027 | case DDC_LCD: | 2143 | case DDC_LCD: |
2028 | ddc_i2c = | 2144 | ddc_i2c = |
2029 | combios_setup_i2c_bus | 2145 | combios_setup_i2c_bus |
2030 | (RADEON_LCD_GPIO_MASK); | 2146 | (rdev, RADEON_GPIOPAD_MASK); |
2031 | ddc_i2c.mask_clk_mask = | 2147 | ddc_i2c.mask_clk_mask = |
2032 | RBIOS32(lcd_ddc_info + 3); | 2148 | RBIOS32(lcd_ddc_info + 3); |
2033 | ddc_i2c.mask_data_mask = | 2149 | ddc_i2c.mask_data_mask = |
@@ -2048,7 +2164,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2048 | case DDC_GPIO: | 2164 | case DDC_GPIO: |
2049 | ddc_i2c = | 2165 | ddc_i2c = |
2050 | combios_setup_i2c_bus | 2166 | combios_setup_i2c_bus |
2051 | (RADEON_MDGPIO_EN_REG); | 2167 | (rdev, RADEON_MDGPIO_MASK); |
2052 | ddc_i2c.mask_clk_mask = | 2168 | ddc_i2c.mask_clk_mask = |
2053 | RBIOS32(lcd_ddc_info + 3); | 2169 | RBIOS32(lcd_ddc_info + 3); |
2054 | ddc_i2c.mask_data_mask = | 2170 | ddc_i2c.mask_data_mask = |
@@ -2074,12 +2190,14 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2074 | } else | 2190 | } else |
2075 | ddc_i2c.valid = false; | 2191 | ddc_i2c.valid = false; |
2076 | 2192 | ||
2193 | hpd.hpd = RADEON_HPD_NONE; | ||
2077 | radeon_add_legacy_connector(dev, | 2194 | radeon_add_legacy_connector(dev, |
2078 | 5, | 2195 | 5, |
2079 | ATOM_DEVICE_LCD1_SUPPORT, | 2196 | ATOM_DEVICE_LCD1_SUPPORT, |
2080 | DRM_MODE_CONNECTOR_LVDS, | 2197 | DRM_MODE_CONNECTOR_LVDS, |
2081 | &ddc_i2c, | 2198 | &ddc_i2c, |
2082 | CONNECTOR_OBJECT_ID_LVDS); | 2199 | CONNECTOR_OBJECT_ID_LVDS, |
2200 | &hpd); | ||
2083 | } | 2201 | } |
2084 | } | 2202 | } |
2085 | 2203 | ||
@@ -2090,6 +2208,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2090 | if (tv_info) { | 2208 | if (tv_info) { |
2091 | if (RBIOS8(tv_info + 6) == 'T') { | 2209 | if (RBIOS8(tv_info + 6) == 'T') { |
2092 | if (radeon_apply_legacy_tv_quirks(dev)) { | 2210 | if (radeon_apply_legacy_tv_quirks(dev)) { |
2211 | hpd.hpd = RADEON_HPD_NONE; | ||
2093 | radeon_add_legacy_encoder(dev, | 2212 | radeon_add_legacy_encoder(dev, |
2094 | radeon_get_encoder_id | 2213 | radeon_get_encoder_id |
2095 | (dev, | 2214 | (dev, |
@@ -2100,7 +2219,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2100 | ATOM_DEVICE_TV1_SUPPORT, | 2219 | ATOM_DEVICE_TV1_SUPPORT, |
2101 | DRM_MODE_CONNECTOR_SVIDEO, | 2220 | DRM_MODE_CONNECTOR_SVIDEO, |
2102 | &ddc_i2c, | 2221 | &ddc_i2c, |
2103 | CONNECTOR_OBJECT_ID_SVIDEO); | 2222 | CONNECTOR_OBJECT_ID_SVIDEO, |
2223 | &hpd); | ||
2104 | } | 2224 | } |
2105 | } | 2225 | } |
2106 | } | 2226 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 7ab3c501b4dd..cfa2ebb259fe 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -40,6 +40,26 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector, | |||
40 | struct drm_encoder *encoder, | 40 | struct drm_encoder *encoder, |
41 | bool connected); | 41 | bool connected); |
42 | 42 | ||
43 | void radeon_connector_hotplug(struct drm_connector *connector) | ||
44 | { | ||
45 | struct drm_device *dev = connector->dev; | ||
46 | struct radeon_device *rdev = dev->dev_private; | ||
47 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
48 | |||
49 | if (radeon_connector->hpd.hpd != RADEON_HPD_NONE) | ||
50 | radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); | ||
51 | |||
52 | if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) { | ||
53 | if (radeon_dp_getsinktype(radeon_connector) == CONNECTOR_OBJECT_ID_DISPLAYPORT) { | ||
54 | if (radeon_dp_needs_link_train(radeon_connector)) { | ||
55 | if (connector->encoder) | ||
56 | dp_link_train(connector->encoder, connector); | ||
57 | } | ||
58 | } | ||
59 | } | ||
60 | |||
61 | } | ||
62 | |||
43 | static void radeon_property_change_mode(struct drm_encoder *encoder) | 63 | static void radeon_property_change_mode(struct drm_encoder *encoder) |
44 | { | 64 | { |
45 | struct drm_crtc *crtc = encoder->crtc; | 65 | struct drm_crtc *crtc = encoder->crtc; |
@@ -896,6 +916,91 @@ struct drm_connector_funcs radeon_dvi_connector_funcs = { | |||
896 | .force = radeon_dvi_force, | 916 | .force = radeon_dvi_force, |
897 | }; | 917 | }; |
898 | 918 | ||
919 | static void radeon_dp_connector_destroy(struct drm_connector *connector) | ||
920 | { | ||
921 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
922 | struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; | ||
923 | |||
924 | if (radeon_connector->ddc_bus) | ||
925 | radeon_i2c_destroy(radeon_connector->ddc_bus); | ||
926 | if (radeon_connector->edid) | ||
927 | kfree(radeon_connector->edid); | ||
928 | if (radeon_dig_connector->dp_i2c_bus) | ||
929 | radeon_i2c_destroy(radeon_dig_connector->dp_i2c_bus); | ||
930 | kfree(radeon_connector->con_priv); | ||
931 | drm_sysfs_connector_remove(connector); | ||
932 | drm_connector_cleanup(connector); | ||
933 | kfree(connector); | ||
934 | } | ||
935 | |||
936 | static int radeon_dp_get_modes(struct drm_connector *connector) | ||
937 | { | ||
938 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
939 | int ret; | ||
940 | |||
941 | ret = radeon_ddc_get_modes(radeon_connector); | ||
942 | return ret; | ||
943 | } | ||
944 | |||
945 | static enum drm_connector_status radeon_dp_detect(struct drm_connector *connector) | ||
946 | { | ||
947 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
948 | enum drm_connector_status ret = connector_status_disconnected; | ||
949 | struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; | ||
950 | u8 sink_type; | ||
951 | |||
952 | if (radeon_connector->edid) { | ||
953 | kfree(radeon_connector->edid); | ||
954 | radeon_connector->edid = NULL; | ||
955 | } | ||
956 | |||
957 | sink_type = radeon_dp_getsinktype(radeon_connector); | ||
958 | if (sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) { | ||
959 | if (radeon_dp_getdpcd(radeon_connector)) { | ||
960 | radeon_dig_connector->dp_sink_type = sink_type; | ||
961 | ret = connector_status_connected; | ||
962 | } | ||
963 | } else { | ||
964 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 1); | ||
965 | if (radeon_ddc_probe(radeon_connector)) { | ||
966 | radeon_dig_connector->dp_sink_type = sink_type; | ||
967 | ret = connector_status_connected; | ||
968 | } | ||
969 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 0); | ||
970 | } | ||
971 | |||
972 | return ret; | ||
973 | } | ||
974 | |||
975 | static int radeon_dp_mode_valid(struct drm_connector *connector, | ||
976 | struct drm_display_mode *mode) | ||
977 | { | ||
978 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
979 | struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; | ||
980 | |||
981 | /* XXX check mode bandwidth */ | ||
982 | |||
983 | if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) | ||
984 | return radeon_dp_mode_valid_helper(radeon_connector, mode); | ||
985 | else | ||
986 | return MODE_OK; | ||
987 | } | ||
988 | |||
989 | struct drm_connector_helper_funcs radeon_dp_connector_helper_funcs = { | ||
990 | .get_modes = radeon_dp_get_modes, | ||
991 | .mode_valid = radeon_dp_mode_valid, | ||
992 | .best_encoder = radeon_dvi_encoder, | ||
993 | }; | ||
994 | |||
995 | struct drm_connector_funcs radeon_dp_connector_funcs = { | ||
996 | .dpms = drm_helper_connector_dpms, | ||
997 | .detect = radeon_dp_detect, | ||
998 | .fill_modes = drm_helper_probe_single_connector_modes, | ||
999 | .set_property = radeon_connector_set_property, | ||
1000 | .destroy = radeon_dp_connector_destroy, | ||
1001 | .force = radeon_dvi_force, | ||
1002 | }; | ||
1003 | |||
899 | void | 1004 | void |
900 | radeon_add_atom_connector(struct drm_device *dev, | 1005 | radeon_add_atom_connector(struct drm_device *dev, |
901 | uint32_t connector_id, | 1006 | uint32_t connector_id, |
@@ -904,7 +1009,8 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
904 | struct radeon_i2c_bus_rec *i2c_bus, | 1009 | struct radeon_i2c_bus_rec *i2c_bus, |
905 | bool linkb, | 1010 | bool linkb, |
906 | uint32_t igp_lane_info, | 1011 | uint32_t igp_lane_info, |
907 | uint16_t connector_object_id) | 1012 | uint16_t connector_object_id, |
1013 | struct radeon_hpd *hpd) | ||
908 | { | 1014 | { |
909 | struct radeon_device *rdev = dev->dev_private; | 1015 | struct radeon_device *rdev = dev->dev_private; |
910 | struct drm_connector *connector; | 1016 | struct drm_connector *connector; |
@@ -944,6 +1050,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
944 | radeon_connector->devices = supported_device; | 1050 | radeon_connector->devices = supported_device; |
945 | radeon_connector->shared_ddc = shared_ddc; | 1051 | radeon_connector->shared_ddc = shared_ddc; |
946 | radeon_connector->connector_object_id = connector_object_id; | 1052 | radeon_connector->connector_object_id = connector_object_id; |
1053 | radeon_connector->hpd = *hpd; | ||
947 | switch (connector_type) { | 1054 | switch (connector_type) { |
948 | case DRM_MODE_CONNECTOR_VGA: | 1055 | case DRM_MODE_CONNECTOR_VGA: |
949 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); | 1056 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); |
@@ -1030,10 +1137,12 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1030 | radeon_dig_connector->linkb = linkb; | 1137 | radeon_dig_connector->linkb = linkb; |
1031 | radeon_dig_connector->igp_lane_info = igp_lane_info; | 1138 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
1032 | radeon_connector->con_priv = radeon_dig_connector; | 1139 | radeon_connector->con_priv = radeon_dig_connector; |
1033 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); | 1140 | drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type); |
1034 | ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); | 1141 | ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs); |
1035 | if (ret) | 1142 | if (ret) |
1036 | goto failed; | 1143 | goto failed; |
1144 | /* add DP i2c bus */ | ||
1145 | radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch"); | ||
1037 | if (i2c_bus->valid) { | 1146 | if (i2c_bus->valid) { |
1038 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DP"); | 1147 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DP"); |
1039 | if (!radeon_connector->ddc_bus) | 1148 | if (!radeon_connector->ddc_bus) |
@@ -1099,7 +1208,8 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1099 | uint32_t supported_device, | 1208 | uint32_t supported_device, |
1100 | int connector_type, | 1209 | int connector_type, |
1101 | struct radeon_i2c_bus_rec *i2c_bus, | 1210 | struct radeon_i2c_bus_rec *i2c_bus, |
1102 | uint16_t connector_object_id) | 1211 | uint16_t connector_object_id, |
1212 | struct radeon_hpd *hpd) | ||
1103 | { | 1213 | { |
1104 | struct radeon_device *rdev = dev->dev_private; | 1214 | struct radeon_device *rdev = dev->dev_private; |
1105 | struct drm_connector *connector; | 1215 | struct drm_connector *connector; |
@@ -1129,6 +1239,7 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1129 | radeon_connector->connector_id = connector_id; | 1239 | radeon_connector->connector_id = connector_id; |
1130 | radeon_connector->devices = supported_device; | 1240 | radeon_connector->devices = supported_device; |
1131 | radeon_connector->connector_object_id = connector_object_id; | 1241 | radeon_connector->connector_object_id = connector_object_id; |
1242 | radeon_connector->hpd = *hpd; | ||
1132 | switch (connector_type) { | 1243 | switch (connector_type) { |
1133 | case DRM_MODE_CONNECTOR_VGA: | 1244 | case DRM_MODE_CONNECTOR_VGA: |
1134 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); | 1245 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index a014ba4cc97c..7e55647f118e 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -481,11 +481,13 @@ int radeon_atombios_init(struct radeon_device *rdev) | |||
481 | 481 | ||
482 | rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios); | 482 | rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios); |
483 | radeon_atom_initialize_bios_scratch_regs(rdev->ddev); | 483 | radeon_atom_initialize_bios_scratch_regs(rdev->ddev); |
484 | atom_allocate_fb_scratch(rdev->mode_info.atom_context); | ||
484 | return 0; | 485 | return 0; |
485 | } | 486 | } |
486 | 487 | ||
487 | void radeon_atombios_fini(struct radeon_device *rdev) | 488 | void radeon_atombios_fini(struct radeon_device *rdev) |
488 | { | 489 | { |
490 | kfree(rdev->mode_info.atom_context->scratch); | ||
489 | kfree(rdev->mode_info.atom_context); | 491 | kfree(rdev->mode_info.atom_context); |
490 | kfree(rdev->mode_info.atom_card_info); | 492 | kfree(rdev->mode_info.atom_card_info); |
491 | } | 493 | } |
@@ -568,6 +570,11 @@ int radeon_device_init(struct radeon_device *rdev, | |||
568 | rwlock_init(&rdev->fence_drv.lock); | 570 | rwlock_init(&rdev->fence_drv.lock); |
569 | INIT_LIST_HEAD(&rdev->gem.objects); | 571 | INIT_LIST_HEAD(&rdev->gem.objects); |
570 | 572 | ||
573 | /* setup workqueue */ | ||
574 | rdev->wq = create_workqueue("radeon"); | ||
575 | if (rdev->wq == NULL) | ||
576 | return -ENOMEM; | ||
577 | |||
571 | /* Set asic functions */ | 578 | /* Set asic functions */ |
572 | r = radeon_asic_init(rdev); | 579 | r = radeon_asic_init(rdev); |
573 | if (r) { | 580 | if (r) { |
@@ -641,6 +648,7 @@ void radeon_device_fini(struct radeon_device *rdev) | |||
641 | DRM_INFO("radeon: finishing device.\n"); | 648 | DRM_INFO("radeon: finishing device.\n"); |
642 | rdev->shutdown = true; | 649 | rdev->shutdown = true; |
643 | radeon_fini(rdev); | 650 | radeon_fini(rdev); |
651 | destroy_workqueue(rdev->wq); | ||
644 | vga_client_register(rdev->pdev, NULL, NULL, NULL); | 652 | vga_client_register(rdev->pdev, NULL, NULL, NULL); |
645 | iounmap(rdev->rmmio); | 653 | iounmap(rdev->rmmio); |
646 | rdev->rmmio = NULL; | 654 | rdev->rmmio = NULL; |
@@ -687,6 +695,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) | |||
687 | radeon_save_bios_scratch_regs(rdev); | 695 | radeon_save_bios_scratch_regs(rdev); |
688 | 696 | ||
689 | radeon_suspend(rdev); | 697 | radeon_suspend(rdev); |
698 | radeon_hpd_fini(rdev); | ||
690 | /* evict remaining vram memory */ | 699 | /* evict remaining vram memory */ |
691 | radeon_bo_evict_vram(rdev); | 700 | radeon_bo_evict_vram(rdev); |
692 | 701 | ||
@@ -721,6 +730,8 @@ int radeon_resume_kms(struct drm_device *dev) | |||
721 | fb_set_suspend(rdev->fbdev_info, 0); | 730 | fb_set_suspend(rdev->fbdev_info, 0); |
722 | release_console_sem(); | 731 | release_console_sem(); |
723 | 732 | ||
733 | /* reset hpd state */ | ||
734 | radeon_hpd_init(rdev); | ||
724 | /* blat the mode back in */ | 735 | /* blat the mode back in */ |
725 | drm_helper_resume_force_mode(dev); | 736 | drm_helper_resume_force_mode(dev); |
726 | return 0; | 737 | return 0; |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 62b02372cb09..c115f2e442eb 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -250,6 +250,16 @@ static const char *connector_names[13] = { | |||
250 | "HDMI-B", | 250 | "HDMI-B", |
251 | }; | 251 | }; |
252 | 252 | ||
253 | static const char *hpd_names[7] = { | ||
254 | "NONE", | ||
255 | "HPD1", | ||
256 | "HPD2", | ||
257 | "HPD3", | ||
258 | "HPD4", | ||
259 | "HPD5", | ||
260 | "HPD6", | ||
261 | }; | ||
262 | |||
253 | static void radeon_print_display_setup(struct drm_device *dev) | 263 | static void radeon_print_display_setup(struct drm_device *dev) |
254 | { | 264 | { |
255 | struct drm_connector *connector; | 265 | struct drm_connector *connector; |
@@ -264,6 +274,8 @@ static void radeon_print_display_setup(struct drm_device *dev) | |||
264 | radeon_connector = to_radeon_connector(connector); | 274 | radeon_connector = to_radeon_connector(connector); |
265 | DRM_INFO("Connector %d:\n", i); | 275 | DRM_INFO("Connector %d:\n", i); |
266 | DRM_INFO(" %s\n", connector_names[connector->connector_type]); | 276 | DRM_INFO(" %s\n", connector_names[connector->connector_type]); |
277 | if (radeon_connector->hpd.hpd != RADEON_HPD_NONE) | ||
278 | DRM_INFO(" %s\n", hpd_names[radeon_connector->hpd.hpd]); | ||
267 | if (radeon_connector->ddc_bus) | 279 | if (radeon_connector->ddc_bus) |
268 | DRM_INFO(" DDC: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", | 280 | DRM_INFO(" DDC: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", |
269 | radeon_connector->ddc_bus->rec.mask_clk_reg, | 281 | radeon_connector->ddc_bus->rec.mask_clk_reg, |
@@ -337,6 +349,11 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) | |||
337 | { | 349 | { |
338 | int ret = 0; | 350 | int ret = 0; |
339 | 351 | ||
352 | if (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) { | ||
353 | struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; | ||
354 | if (dig->dp_i2c_bus) | ||
355 | radeon_connector->edid = drm_get_edid(&radeon_connector->base, &dig->dp_i2c_bus->adapter); | ||
356 | } | ||
340 | if (!radeon_connector->ddc_bus) | 357 | if (!radeon_connector->ddc_bus) |
341 | return -1; | 358 | return -1; |
342 | if (!radeon_connector->edid) { | 359 | if (!radeon_connector->edid) { |
@@ -724,6 +741,8 @@ int radeon_modeset_init(struct radeon_device *rdev) | |||
724 | if (!ret) { | 741 | if (!ret) { |
725 | return ret; | 742 | return ret; |
726 | } | 743 | } |
744 | /* initialize hpd */ | ||
745 | radeon_hpd_init(rdev); | ||
727 | drm_helper_initial_config(rdev->ddev); | 746 | drm_helper_initial_config(rdev->ddev); |
728 | return 0; | 747 | return 0; |
729 | } | 748 | } |
@@ -731,6 +750,7 @@ int radeon_modeset_init(struct radeon_device *rdev) | |||
731 | void radeon_modeset_fini(struct radeon_device *rdev) | 750 | void radeon_modeset_fini(struct radeon_device *rdev) |
732 | { | 751 | { |
733 | if (rdev->mode_info.mode_config_initialized) { | 752 | if (rdev->mode_info.mode_config_initialized) { |
753 | radeon_hpd_fini(rdev); | ||
734 | drm_mode_config_cleanup(rdev->ddev); | 754 | drm_mode_config_cleanup(rdev->ddev); |
735 | rdev->mode_info.mode_config_initialized = false; | 755 | rdev->mode_info.mode_config_initialized = false; |
736 | } | 756 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 291f6dd3683c..b4f23ec93201 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -250,6 +250,12 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, | |||
250 | } | 250 | } |
251 | } | 251 | } |
252 | 252 | ||
253 | if (ASIC_IS_DCE3(rdev) && | ||
254 | (radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT))) { | ||
255 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
256 | radeon_dp_set_link_config(connector, mode); | ||
257 | } | ||
258 | |||
253 | return true; | 259 | return true; |
254 | } | 260 | } |
255 | 261 | ||
@@ -554,6 +560,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
554 | { | 560 | { |
555 | struct drm_connector *connector; | 561 | struct drm_connector *connector; |
556 | struct radeon_connector *radeon_connector; | 562 | struct radeon_connector *radeon_connector; |
563 | struct radeon_connector_atom_dig *radeon_dig_connector; | ||
557 | 564 | ||
558 | connector = radeon_get_connector_for_encoder(encoder); | 565 | connector = radeon_get_connector_for_encoder(encoder); |
559 | if (!connector) | 566 | if (!connector) |
@@ -583,10 +590,10 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
583 | return ATOM_ENCODER_MODE_LVDS; | 590 | return ATOM_ENCODER_MODE_LVDS; |
584 | break; | 591 | break; |
585 | case DRM_MODE_CONNECTOR_DisplayPort: | 592 | case DRM_MODE_CONNECTOR_DisplayPort: |
586 | /*if (radeon_output->MonType == MT_DP) | 593 | radeon_dig_connector = radeon_connector->con_priv; |
587 | return ATOM_ENCODER_MODE_DP; | 594 | if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) |
588 | else*/ | 595 | return ATOM_ENCODER_MODE_DP; |
589 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) | 596 | else if (drm_detect_hdmi_monitor(radeon_connector->edid)) |
590 | return ATOM_ENCODER_MODE_HDMI; | 597 | return ATOM_ENCODER_MODE_HDMI; |
591 | else | 598 | else |
592 | return ATOM_ENCODER_MODE_DVI; | 599 | return ATOM_ENCODER_MODE_DVI; |
@@ -605,6 +612,30 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
605 | } | 612 | } |
606 | } | 613 | } |
607 | 614 | ||
615 | /* | ||
616 | * DIG Encoder/Transmitter Setup | ||
617 | * | ||
618 | * DCE 3.0/3.1 | ||
619 | * - 2 DIG transmitter blocks. UNIPHY (links A and B) and LVTMA. | ||
620 | * Supports up to 3 digital outputs | ||
621 | * - 2 DIG encoder blocks. | ||
622 | * DIG1 can drive UNIPHY link A or link B | ||
623 | * DIG2 can drive UNIPHY link B or LVTMA | ||
624 | * | ||
625 | * DCE 3.2 | ||
626 | * - 3 DIG transmitter blocks. UNIPHY0/1/2 (links A and B). | ||
627 | * Supports up to 5 digital outputs | ||
628 | * - 2 DIG encoder blocks. | ||
629 | * DIG1/2 can drive UNIPHY0/1/2 link A or link B | ||
630 | * | ||
631 | * Routing | ||
632 | * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links) | ||
633 | * Examples: | ||
634 | * crtc0 -> dig2 -> LVTMA links A+B -> TMDS/HDMI | ||
635 | * crtc1 -> dig1 -> UNIPHY0 link B -> DP | ||
636 | * crtc0 -> dig1 -> UNIPHY2 link A -> LVDS | ||
637 | * crtc1 -> dig2 -> UNIPHY1 link B+A -> TMDS/HDMI | ||
638 | */ | ||
608 | static void | 639 | static void |
609 | atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | 640 | atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) |
610 | { | 641 | { |
@@ -646,10 +677,17 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
646 | } else { | 677 | } else { |
647 | switch (radeon_encoder->encoder_id) { | 678 | switch (radeon_encoder->encoder_id) { |
648 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | 679 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
649 | index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); | 680 | /* XXX doesn't really matter which dig encoder we pick as long as it's |
681 | * not already in use | ||
682 | */ | ||
683 | if (dig_connector->linkb) | ||
684 | index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); | ||
685 | else | ||
686 | index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); | ||
650 | num = 1; | 687 | num = 1; |
651 | break; | 688 | break; |
652 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | 689 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
690 | /* Only dig2 encoder can drive LVTMA */ | ||
653 | index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); | 691 | index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); |
654 | num = 2; | 692 | num = 2; |
655 | break; | 693 | break; |
@@ -684,18 +722,21 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
684 | } | 722 | } |
685 | } | 723 | } |
686 | 724 | ||
687 | if (radeon_encoder->pixel_clock > 165000) { | 725 | args.ucEncoderMode = atombios_get_encoder_mode(encoder); |
688 | args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA_B; | 726 | |
727 | if (args.ucEncoderMode == ATOM_ENCODER_MODE_DP) { | ||
728 | if (dig_connector->dp_clock == 270000) | ||
729 | args.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; | ||
730 | args.ucLaneNum = dig_connector->dp_lane_count; | ||
731 | } else if (radeon_encoder->pixel_clock > 165000) | ||
689 | args.ucLaneNum = 8; | 732 | args.ucLaneNum = 8; |
690 | } else { | 733 | else |
691 | if (dig_connector->linkb) | ||
692 | args.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; | ||
693 | else | ||
694 | args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; | ||
695 | args.ucLaneNum = 4; | 734 | args.ucLaneNum = 4; |
696 | } | ||
697 | 735 | ||
698 | args.ucEncoderMode = atombios_get_encoder_mode(encoder); | 736 | if (dig_connector->linkb) |
737 | args.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; | ||
738 | else | ||
739 | args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; | ||
699 | 740 | ||
700 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 741 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
701 | 742 | ||
@@ -706,8 +747,8 @@ union dig_transmitter_control { | |||
706 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2; | 747 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2; |
707 | }; | 748 | }; |
708 | 749 | ||
709 | static void | 750 | void |
710 | atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action) | 751 | atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t lane_num, uint8_t lane_set) |
711 | { | 752 | { |
712 | struct drm_device *dev = encoder->dev; | 753 | struct drm_device *dev = encoder->dev; |
713 | struct radeon_device *rdev = dev->dev_private; | 754 | struct radeon_device *rdev = dev->dev_private; |
@@ -719,6 +760,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action) | |||
719 | struct drm_connector *connector; | 760 | struct drm_connector *connector; |
720 | struct radeon_connector *radeon_connector; | 761 | struct radeon_connector *radeon_connector; |
721 | struct radeon_connector_atom_dig *dig_connector; | 762 | struct radeon_connector_atom_dig *dig_connector; |
763 | bool is_dp = false; | ||
722 | 764 | ||
723 | connector = radeon_get_connector_for_encoder(encoder); | 765 | connector = radeon_get_connector_for_encoder(encoder); |
724 | if (!connector) | 766 | if (!connector) |
@@ -736,6 +778,9 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action) | |||
736 | 778 | ||
737 | dig_connector = radeon_connector->con_priv; | 779 | dig_connector = radeon_connector->con_priv; |
738 | 780 | ||
781 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) | ||
782 | is_dp = true; | ||
783 | |||
739 | memset(&args, 0, sizeof(args)); | 784 | memset(&args, 0, sizeof(args)); |
740 | 785 | ||
741 | if (ASIC_IS_DCE32(rdev)) | 786 | if (ASIC_IS_DCE32(rdev)) |
@@ -756,17 +801,23 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action) | |||
756 | args.v1.ucAction = action; | 801 | args.v1.ucAction = action; |
757 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { | 802 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { |
758 | args.v1.usInitInfo = radeon_connector->connector_object_id; | 803 | args.v1.usInitInfo = radeon_connector->connector_object_id; |
804 | } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { | ||
805 | args.v1.asMode.ucLaneSel = lane_num; | ||
806 | args.v1.asMode.ucLaneSet = lane_set; | ||
759 | } else { | 807 | } else { |
760 | if (radeon_encoder->pixel_clock > 165000) | 808 | if (is_dp) |
809 | args.v1.usPixelClock = | ||
810 | cpu_to_le16(dig_connector->dp_clock / 10); | ||
811 | else if (radeon_encoder->pixel_clock > 165000) | ||
761 | args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | 812 | args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); |
762 | else | 813 | else |
763 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 814 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
764 | } | 815 | } |
765 | if (ASIC_IS_DCE32(rdev)) { | 816 | if (ASIC_IS_DCE32(rdev)) { |
766 | if (radeon_encoder->pixel_clock > 165000) | ||
767 | args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | ||
768 | if (dig->dig_block) | 817 | if (dig->dig_block) |
769 | args.v2.acConfig.ucEncoderSel = 1; | 818 | args.v2.acConfig.ucEncoderSel = 1; |
819 | if (dig_connector->linkb) | ||
820 | args.v2.acConfig.ucLinkSel = 1; | ||
770 | 821 | ||
771 | switch (radeon_encoder->encoder_id) { | 822 | switch (radeon_encoder->encoder_id) { |
772 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | 823 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
@@ -783,7 +834,9 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action) | |||
783 | break; | 834 | break; |
784 | } | 835 | } |
785 | 836 | ||
786 | if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | 837 | if (is_dp) |
838 | args.v2.acConfig.fCoherentMode = 1; | ||
839 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
787 | if (dig->coherent_mode) | 840 | if (dig->coherent_mode) |
788 | args.v2.acConfig.fCoherentMode = 1; | 841 | args.v2.acConfig.fCoherentMode = 1; |
789 | } | 842 | } |
@@ -792,17 +845,20 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action) | |||
792 | 845 | ||
793 | switch (radeon_encoder->encoder_id) { | 846 | switch (radeon_encoder->encoder_id) { |
794 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | 847 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
795 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER; | 848 | /* XXX doesn't really matter which dig encoder we pick as long as it's |
849 | * not already in use | ||
850 | */ | ||
851 | if (dig_connector->linkb) | ||
852 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER; | ||
853 | else | ||
854 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER; | ||
796 | if (rdev->flags & RADEON_IS_IGP) { | 855 | if (rdev->flags & RADEON_IS_IGP) { |
797 | if (radeon_encoder->pixel_clock > 165000) { | 856 | if (radeon_encoder->pixel_clock > 165000) { |
798 | args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK | | ||
799 | ATOM_TRANSMITTER_CONFIG_LINKA_B); | ||
800 | if (dig_connector->igp_lane_info & 0x3) | 857 | if (dig_connector->igp_lane_info & 0x3) |
801 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7; | 858 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7; |
802 | else if (dig_connector->igp_lane_info & 0xc) | 859 | else if (dig_connector->igp_lane_info & 0xc) |
803 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15; | 860 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15; |
804 | } else { | 861 | } else { |
805 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA; | ||
806 | if (dig_connector->igp_lane_info & 0x1) | 862 | if (dig_connector->igp_lane_info & 0x1) |
807 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; | 863 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; |
808 | else if (dig_connector->igp_lane_info & 0x2) | 864 | else if (dig_connector->igp_lane_info & 0x2) |
@@ -812,35 +868,25 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action) | |||
812 | else if (dig_connector->igp_lane_info & 0x8) | 868 | else if (dig_connector->igp_lane_info & 0x8) |
813 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15; | 869 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15; |
814 | } | 870 | } |
815 | } else { | ||
816 | if (radeon_encoder->pixel_clock > 165000) | ||
817 | args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK | | ||
818 | ATOM_TRANSMITTER_CONFIG_LINKA_B | | ||
819 | ATOM_TRANSMITTER_CONFIG_LANE_0_7); | ||
820 | else { | ||
821 | if (dig_connector->linkb) | ||
822 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3; | ||
823 | else | ||
824 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3; | ||
825 | } | ||
826 | } | 871 | } |
827 | break; | 872 | break; |
828 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | 873 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
874 | /* Only dig2 encoder can drive LVTMA */ | ||
829 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER; | 875 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER; |
830 | if (radeon_encoder->pixel_clock > 165000) | ||
831 | args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK | | ||
832 | ATOM_TRANSMITTER_CONFIG_LINKA_B | | ||
833 | ATOM_TRANSMITTER_CONFIG_LANE_0_7); | ||
834 | else { | ||
835 | if (dig_connector->linkb) | ||
836 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3; | ||
837 | else | ||
838 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3; | ||
839 | } | ||
840 | break; | 876 | break; |
841 | } | 877 | } |
842 | 878 | ||
843 | if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | 879 | if (radeon_encoder->pixel_clock > 165000) |
880 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK; | ||
881 | |||
882 | if (dig_connector->linkb) | ||
883 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB; | ||
884 | else | ||
885 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA; | ||
886 | |||
887 | if (is_dp) | ||
888 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; | ||
889 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
844 | if (dig->coherent_mode) | 890 | if (dig->coherent_mode) |
845 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; | 891 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; |
846 | } | 892 | } |
@@ -950,12 +996,16 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
950 | if (is_dig) { | 996 | if (is_dig) { |
951 | switch (mode) { | 997 | switch (mode) { |
952 | case DRM_MODE_DPMS_ON: | 998 | case DRM_MODE_DPMS_ON: |
953 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT); | 999 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); |
1000 | { | ||
1001 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
1002 | dp_link_train(encoder, connector); | ||
1003 | } | ||
954 | break; | 1004 | break; |
955 | case DRM_MODE_DPMS_STANDBY: | 1005 | case DRM_MODE_DPMS_STANDBY: |
956 | case DRM_MODE_DPMS_SUSPEND: | 1006 | case DRM_MODE_DPMS_SUSPEND: |
957 | case DRM_MODE_DPMS_OFF: | 1007 | case DRM_MODE_DPMS_OFF: |
958 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT); | 1008 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); |
959 | break; | 1009 | break; |
960 | } | 1010 | } |
961 | } else { | 1011 | } else { |
@@ -1057,13 +1107,33 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder) | |||
1057 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; | 1107 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; |
1058 | else | 1108 | else |
1059 | args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; | 1109 | args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; |
1060 | } else | 1110 | } else { |
1061 | args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; | 1111 | struct drm_connector *connector; |
1112 | struct radeon_connector *radeon_connector; | ||
1113 | struct radeon_connector_atom_dig *dig_connector; | ||
1114 | |||
1115 | connector = radeon_get_connector_for_encoder(encoder); | ||
1116 | if (!connector) | ||
1117 | return; | ||
1118 | radeon_connector = to_radeon_connector(connector); | ||
1119 | if (!radeon_connector->con_priv) | ||
1120 | return; | ||
1121 | dig_connector = radeon_connector->con_priv; | ||
1122 | |||
1123 | /* XXX doesn't really matter which dig encoder we pick as long as it's | ||
1124 | * not already in use | ||
1125 | */ | ||
1126 | if (dig_connector->linkb) | ||
1127 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; | ||
1128 | else | ||
1129 | args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; | ||
1130 | } | ||
1062 | break; | 1131 | break; |
1063 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | 1132 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: |
1064 | args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID; | 1133 | args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID; |
1065 | break; | 1134 | break; |
1066 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | 1135 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
1136 | /* Only dig2 encoder can drive LVTMA */ | ||
1067 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; | 1137 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; |
1068 | break; | 1138 | break; |
1069 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | 1139 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: |
@@ -1136,11 +1206,14 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
1136 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1206 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
1137 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | 1207 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); |
1138 | 1208 | ||
1139 | if (radeon_encoder->enc_priv) { | 1209 | if (radeon_encoder->active_device & |
1140 | struct radeon_encoder_atom_dig *dig; | 1210 | (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) { |
1211 | if (radeon_encoder->enc_priv) { | ||
1212 | struct radeon_encoder_atom_dig *dig; | ||
1141 | 1213 | ||
1142 | dig = radeon_encoder->enc_priv; | 1214 | dig = radeon_encoder->enc_priv; |
1143 | dig->dig_block = radeon_crtc->crtc_id; | 1215 | dig->dig_block = radeon_crtc->crtc_id; |
1216 | } | ||
1144 | } | 1217 | } |
1145 | radeon_encoder->pixel_clock = adjusted_mode->clock; | 1218 | radeon_encoder->pixel_clock = adjusted_mode->clock; |
1146 | 1219 | ||
@@ -1166,14 +1239,14 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
1166 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 1239 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
1167 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | 1240 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
1168 | /* disable the encoder and transmitter */ | 1241 | /* disable the encoder and transmitter */ |
1169 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE); | 1242 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); |
1170 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE); | 1243 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE); |
1171 | 1244 | ||
1172 | /* setup and enable the encoder and transmitter */ | 1245 | /* setup and enable the encoder and transmitter */ |
1173 | atombios_dig_encoder_setup(encoder, ATOM_ENABLE); | 1246 | atombios_dig_encoder_setup(encoder, ATOM_ENABLE); |
1174 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT); | 1247 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0); |
1175 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP); | 1248 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); |
1176 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE); | 1249 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); |
1177 | break; | 1250 | break; |
1178 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | 1251 | case ENCODER_OBJECT_ID_INTERNAL_DDI: |
1179 | atombios_ddia_setup(encoder, ATOM_ENABLE); | 1252 | atombios_ddia_setup(encoder, ATOM_ENABLE); |
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index 6c645fb4dad8..da3da1e89d00 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c | |||
@@ -69,13 +69,15 @@ void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state) | |||
69 | * holds the i2c port in a bad state - switch hw i2c away before | 69 | * holds the i2c port in a bad state - switch hw i2c away before |
70 | * doing DDC - do this for all r200s/r300s/r400s for safety sake | 70 | * doing DDC - do this for all r200s/r300s/r400s for safety sake |
71 | */ | 71 | */ |
72 | if ((rdev->family >= CHIP_R200) && !ASIC_IS_AVIVO(rdev)) { | 72 | if (rec->hw_capable) { |
73 | if (rec->a_clk_reg == RADEON_GPIO_MONID) { | 73 | if ((rdev->family >= CHIP_R200) && !ASIC_IS_AVIVO(rdev)) { |
74 | WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | | 74 | if (rec->a_clk_reg == RADEON_GPIO_MONID) { |
75 | R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1))); | 75 | WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | |
76 | } else { | 76 | R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1))); |
77 | WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | | 77 | } else { |
78 | R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3))); | 78 | WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | |
79 | R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3))); | ||
80 | } | ||
79 | } | 81 | } |
80 | } | 82 | } |
81 | 83 | ||
@@ -86,6 +88,12 @@ void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state) | |||
86 | temp = RREG32(rec->a_data_reg) & ~rec->a_data_mask; | 88 | temp = RREG32(rec->a_data_reg) & ~rec->a_data_mask; |
87 | WREG32(rec->a_data_reg, temp); | 89 | WREG32(rec->a_data_reg, temp); |
88 | 90 | ||
91 | /* set the pins to input */ | ||
92 | temp = RREG32(rec->en_clk_reg) & ~rec->en_clk_mask; | ||
93 | WREG32(rec->en_clk_reg, temp); | ||
94 | |||
95 | temp = RREG32(rec->en_data_reg) & ~rec->en_data_mask; | ||
96 | WREG32(rec->en_data_reg, temp); | ||
89 | 97 | ||
90 | /* mask the gpio pins for software use */ | 98 | /* mask the gpio pins for software use */ |
91 | temp = RREG32(rec->mask_clk_reg); | 99 | temp = RREG32(rec->mask_clk_reg); |
@@ -172,20 +180,19 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, | |||
172 | return NULL; | 180 | return NULL; |
173 | 181 | ||
174 | i2c->adapter.owner = THIS_MODULE; | 182 | i2c->adapter.owner = THIS_MODULE; |
175 | i2c->adapter.algo_data = &i2c->algo; | ||
176 | i2c->dev = dev; | 183 | i2c->dev = dev; |
177 | i2c->algo.setsda = set_data; | 184 | i2c_set_adapdata(&i2c->adapter, i2c); |
178 | i2c->algo.setscl = set_clock; | 185 | i2c->adapter.algo_data = &i2c->algo.bit; |
179 | i2c->algo.getsda = get_data; | 186 | i2c->algo.bit.setsda = set_data; |
180 | i2c->algo.getscl = get_clock; | 187 | i2c->algo.bit.setscl = set_clock; |
181 | i2c->algo.udelay = 20; | 188 | i2c->algo.bit.getsda = get_data; |
189 | i2c->algo.bit.getscl = get_clock; | ||
190 | i2c->algo.bit.udelay = 20; | ||
182 | /* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always | 191 | /* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always |
183 | * make this, 2 jiffies is a lot more reliable */ | 192 | * make this, 2 jiffies is a lot more reliable */ |
184 | i2c->algo.timeout = 2; | 193 | i2c->algo.bit.timeout = 2; |
185 | i2c->algo.data = i2c; | 194 | i2c->algo.bit.data = i2c; |
186 | i2c->rec = *rec; | 195 | i2c->rec = *rec; |
187 | i2c_set_adapdata(&i2c->adapter, i2c); | ||
188 | |||
189 | ret = i2c_bit_add_bus(&i2c->adapter); | 196 | ret = i2c_bit_add_bus(&i2c->adapter); |
190 | if (ret) { | 197 | if (ret) { |
191 | DRM_INFO("Failed to register i2c %s\n", name); | 198 | DRM_INFO("Failed to register i2c %s\n", name); |
@@ -199,6 +206,38 @@ out_free: | |||
199 | 206 | ||
200 | } | 207 | } |
201 | 208 | ||
209 | struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev, | ||
210 | struct radeon_i2c_bus_rec *rec, | ||
211 | const char *name) | ||
212 | { | ||
213 | struct radeon_i2c_chan *i2c; | ||
214 | int ret; | ||
215 | |||
216 | i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL); | ||
217 | if (i2c == NULL) | ||
218 | return NULL; | ||
219 | |||
220 | i2c->rec = *rec; | ||
221 | i2c->adapter.owner = THIS_MODULE; | ||
222 | i2c->dev = dev; | ||
223 | i2c_set_adapdata(&i2c->adapter, i2c); | ||
224 | i2c->adapter.algo_data = &i2c->algo.dp; | ||
225 | i2c->algo.dp.aux_ch = radeon_dp_i2c_aux_ch; | ||
226 | i2c->algo.dp.address = 0; | ||
227 | ret = i2c_dp_aux_add_bus(&i2c->adapter); | ||
228 | if (ret) { | ||
229 | DRM_INFO("Failed to register i2c %s\n", name); | ||
230 | goto out_free; | ||
231 | } | ||
232 | |||
233 | return i2c; | ||
234 | out_free: | ||
235 | kfree(i2c); | ||
236 | return NULL; | ||
237 | |||
238 | } | ||
239 | |||
240 | |||
202 | void radeon_i2c_destroy(struct radeon_i2c_chan *i2c) | 241 | void radeon_i2c_destroy(struct radeon_i2c_chan *i2c) |
203 | { | 242 | { |
204 | if (!i2c) | 243 | if (!i2c) |
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 26789970c5cf..9223296fe37b 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c | |||
@@ -39,11 +39,32 @@ irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS) | |||
39 | return radeon_irq_process(rdev); | 39 | return radeon_irq_process(rdev); |
40 | } | 40 | } |
41 | 41 | ||
42 | /* | ||
43 | * Handle hotplug events outside the interrupt handler proper. | ||
44 | */ | ||
45 | static void radeon_hotplug_work_func(struct work_struct *work) | ||
46 | { | ||
47 | struct radeon_device *rdev = container_of(work, struct radeon_device, | ||
48 | hotplug_work); | ||
49 | struct drm_device *dev = rdev->ddev; | ||
50 | struct drm_mode_config *mode_config = &dev->mode_config; | ||
51 | struct drm_connector *connector; | ||
52 | |||
53 | if (mode_config->num_connector) { | ||
54 | list_for_each_entry(connector, &mode_config->connector_list, head) | ||
55 | radeon_connector_hotplug(connector); | ||
56 | } | ||
57 | /* Just fire off a uevent and let userspace tell us what to do */ | ||
58 | drm_sysfs_hotplug_event(dev); | ||
59 | } | ||
60 | |||
42 | void radeon_driver_irq_preinstall_kms(struct drm_device *dev) | 61 | void radeon_driver_irq_preinstall_kms(struct drm_device *dev) |
43 | { | 62 | { |
44 | struct radeon_device *rdev = dev->dev_private; | 63 | struct radeon_device *rdev = dev->dev_private; |
45 | unsigned i; | 64 | unsigned i; |
46 | 65 | ||
66 | INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func); | ||
67 | |||
47 | /* Disable *all* interrupts */ | 68 | /* Disable *all* interrupts */ |
48 | rdev->irq.sw_int = false; | 69 | rdev->irq.sw_int = false; |
49 | for (i = 0; i < 2; i++) { | 70 | for (i = 0; i < 2; i++) { |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 135693d5437e..15ec7ca18a95 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <drm_crtc.h> | 33 | #include <drm_crtc.h> |
34 | #include <drm_mode.h> | 34 | #include <drm_mode.h> |
35 | #include <drm_edid.h> | 35 | #include <drm_edid.h> |
36 | #include <drm_dp_helper.h> | ||
36 | #include <linux/i2c.h> | 37 | #include <linux/i2c.h> |
37 | #include <linux/i2c-id.h> | 38 | #include <linux/i2c-id.h> |
38 | #include <linux/i2c-algo-bit.h> | 39 | #include <linux/i2c-algo-bit.h> |
@@ -105,6 +106,13 @@ enum radeon_tv_std { | |||
105 | */ | 106 | */ |
106 | struct radeon_i2c_bus_rec { | 107 | struct radeon_i2c_bus_rec { |
107 | bool valid; | 108 | bool valid; |
109 | /* id used by atom */ | ||
110 | uint8_t i2c_id; | ||
111 | /* can be used with hw i2c engine */ | ||
112 | bool hw_capable; | ||
113 | /* uses multi-media i2c engine */ | ||
114 | bool mm_i2c; | ||
115 | /* regs and bits */ | ||
108 | uint32_t mask_clk_reg; | 116 | uint32_t mask_clk_reg; |
109 | uint32_t mask_data_reg; | 117 | uint32_t mask_data_reg; |
110 | uint32_t a_clk_reg; | 118 | uint32_t a_clk_reg; |
@@ -164,9 +172,12 @@ struct radeon_pll { | |||
164 | }; | 172 | }; |
165 | 173 | ||
166 | struct radeon_i2c_chan { | 174 | struct radeon_i2c_chan { |
167 | struct drm_device *dev; | ||
168 | struct i2c_adapter adapter; | 175 | struct i2c_adapter adapter; |
169 | struct i2c_algo_bit_data algo; | 176 | struct drm_device *dev; |
177 | union { | ||
178 | struct i2c_algo_dp_aux_data dp; | ||
179 | struct i2c_algo_bit_data bit; | ||
180 | } algo; | ||
170 | struct radeon_i2c_bus_rec rec; | 181 | struct radeon_i2c_bus_rec rec; |
171 | }; | 182 | }; |
172 | 183 | ||
@@ -328,6 +339,35 @@ struct radeon_encoder { | |||
328 | struct radeon_connector_atom_dig { | 339 | struct radeon_connector_atom_dig { |
329 | uint32_t igp_lane_info; | 340 | uint32_t igp_lane_info; |
330 | bool linkb; | 341 | bool linkb; |
342 | /* displayport */ | ||
343 | struct radeon_i2c_chan *dp_i2c_bus; | ||
344 | u8 dpcd[8]; | ||
345 | u8 dp_sink_type; | ||
346 | int dp_clock; | ||
347 | int dp_lane_count; | ||
348 | }; | ||
349 | |||
350 | struct radeon_gpio_rec { | ||
351 | bool valid; | ||
352 | u8 id; | ||
353 | u32 reg; | ||
354 | u32 mask; | ||
355 | }; | ||
356 | |||
357 | enum radeon_hpd_id { | ||
358 | RADEON_HPD_NONE = 0, | ||
359 | RADEON_HPD_1, | ||
360 | RADEON_HPD_2, | ||
361 | RADEON_HPD_3, | ||
362 | RADEON_HPD_4, | ||
363 | RADEON_HPD_5, | ||
364 | RADEON_HPD_6, | ||
365 | }; | ||
366 | |||
367 | struct radeon_hpd { | ||
368 | enum radeon_hpd_id hpd; | ||
369 | u8 plugged_state; | ||
370 | struct radeon_gpio_rec gpio; | ||
331 | }; | 371 | }; |
332 | 372 | ||
333 | struct radeon_connector { | 373 | struct radeon_connector { |
@@ -344,6 +384,7 @@ struct radeon_connector { | |||
344 | void *con_priv; | 384 | void *con_priv; |
345 | bool dac_load_detect; | 385 | bool dac_load_detect; |
346 | uint16_t connector_object_id; | 386 | uint16_t connector_object_id; |
387 | struct radeon_hpd hpd; | ||
347 | }; | 388 | }; |
348 | 389 | ||
349 | struct radeon_framebuffer { | 390 | struct radeon_framebuffer { |
@@ -351,6 +392,25 @@ struct radeon_framebuffer { | |||
351 | struct drm_gem_object *obj; | 392 | struct drm_gem_object *obj; |
352 | }; | 393 | }; |
353 | 394 | ||
395 | extern void radeon_connector_hotplug(struct drm_connector *connector); | ||
396 | extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector); | ||
397 | extern int radeon_dp_mode_valid_helper(struct radeon_connector *radeon_connector, | ||
398 | struct drm_display_mode *mode); | ||
399 | extern void radeon_dp_set_link_config(struct drm_connector *connector, | ||
400 | struct drm_display_mode *mode); | ||
401 | extern void dp_link_train(struct drm_encoder *encoder, | ||
402 | struct drm_connector *connector); | ||
403 | extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector); | ||
404 | extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector); | ||
405 | extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder, | ||
406 | int action, uint8_t lane_num, | ||
407 | uint8_t lane_set); | ||
408 | extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | ||
409 | uint8_t write_byte, uint8_t *read_byte); | ||
410 | |||
411 | extern struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev, | ||
412 | struct radeon_i2c_bus_rec *rec, | ||
413 | const char *name); | ||
354 | extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, | 414 | extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, |
355 | struct radeon_i2c_bus_rec *rec, | 415 | struct radeon_i2c_bus_rec *rec, |
356 | const char *name); | 416 | const char *name); |
diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h index c4c41c8d908c..6d0a009dd4a1 100644 --- a/drivers/gpu/drm/radeon/radeon_reg.h +++ b/drivers/gpu/drm/radeon/radeon_reg.h | |||
@@ -887,6 +887,7 @@ | |||
887 | # define RADEON_FP_PANEL_FORMAT (1 << 3) | 887 | # define RADEON_FP_PANEL_FORMAT (1 << 3) |
888 | # define RADEON_FP_EN_TMDS (1 << 7) | 888 | # define RADEON_FP_EN_TMDS (1 << 7) |
889 | # define RADEON_FP_DETECT_SENSE (1 << 8) | 889 | # define RADEON_FP_DETECT_SENSE (1 << 8) |
890 | # define RADEON_FP_DETECT_INT_POL (1 << 9) | ||
890 | # define R200_FP_SOURCE_SEL_MASK (3 << 10) | 891 | # define R200_FP_SOURCE_SEL_MASK (3 << 10) |
891 | # define R200_FP_SOURCE_SEL_CRTC1 (0 << 10) | 892 | # define R200_FP_SOURCE_SEL_CRTC1 (0 << 10) |
892 | # define R200_FP_SOURCE_SEL_CRTC2 (1 << 10) | 893 | # define R200_FP_SOURCE_SEL_CRTC2 (1 << 10) |
@@ -894,6 +895,7 @@ | |||
894 | # define R200_FP_SOURCE_SEL_TRANS (3 << 10) | 895 | # define R200_FP_SOURCE_SEL_TRANS (3 << 10) |
895 | # define RADEON_FP_SEL_CRTC1 (0 << 13) | 896 | # define RADEON_FP_SEL_CRTC1 (0 << 13) |
896 | # define RADEON_FP_SEL_CRTC2 (1 << 13) | 897 | # define RADEON_FP_SEL_CRTC2 (1 << 13) |
898 | # define R300_HPD_SEL(x) ((x) << 13) | ||
897 | # define RADEON_FP_CRTC_DONT_SHADOW_HPAR (1 << 15) | 899 | # define RADEON_FP_CRTC_DONT_SHADOW_HPAR (1 << 15) |
898 | # define RADEON_FP_CRTC_DONT_SHADOW_VPAR (1 << 16) | 900 | # define RADEON_FP_CRTC_DONT_SHADOW_VPAR (1 << 16) |
899 | # define RADEON_FP_CRTC_DONT_SHADOW_HEND (1 << 17) | 901 | # define RADEON_FP_CRTC_DONT_SHADOW_HEND (1 << 17) |
@@ -909,6 +911,7 @@ | |||
909 | # define RADEON_FP2_ON (1 << 2) | 911 | # define RADEON_FP2_ON (1 << 2) |
910 | # define RADEON_FP2_PANEL_FORMAT (1 << 3) | 912 | # define RADEON_FP2_PANEL_FORMAT (1 << 3) |
911 | # define RADEON_FP2_DETECT_SENSE (1 << 8) | 913 | # define RADEON_FP2_DETECT_SENSE (1 << 8) |
914 | # define RADEON_FP2_DETECT_INT_POL (1 << 9) | ||
912 | # define R200_FP2_SOURCE_SEL_MASK (3 << 10) | 915 | # define R200_FP2_SOURCE_SEL_MASK (3 << 10) |
913 | # define R200_FP2_SOURCE_SEL_CRTC1 (0 << 10) | 916 | # define R200_FP2_SOURCE_SEL_CRTC1 (0 << 10) |
914 | # define R200_FP2_SOURCE_SEL_CRTC2 (1 << 10) | 917 | # define R200_FP2_SOURCE_SEL_CRTC2 (1 << 10) |
@@ -988,14 +991,20 @@ | |||
988 | 991 | ||
989 | #define RADEON_GEN_INT_CNTL 0x0040 | 992 | #define RADEON_GEN_INT_CNTL 0x0040 |
990 | # define RADEON_CRTC_VBLANK_MASK (1 << 0) | 993 | # define RADEON_CRTC_VBLANK_MASK (1 << 0) |
994 | # define RADEON_FP_DETECT_MASK (1 << 4) | ||
991 | # define RADEON_CRTC2_VBLANK_MASK (1 << 9) | 995 | # define RADEON_CRTC2_VBLANK_MASK (1 << 9) |
996 | # define RADEON_FP2_DETECT_MASK (1 << 10) | ||
992 | # define RADEON_SW_INT_ENABLE (1 << 25) | 997 | # define RADEON_SW_INT_ENABLE (1 << 25) |
993 | #define RADEON_GEN_INT_STATUS 0x0044 | 998 | #define RADEON_GEN_INT_STATUS 0x0044 |
994 | # define AVIVO_DISPLAY_INT_STATUS (1 << 0) | 999 | # define AVIVO_DISPLAY_INT_STATUS (1 << 0) |
995 | # define RADEON_CRTC_VBLANK_STAT (1 << 0) | 1000 | # define RADEON_CRTC_VBLANK_STAT (1 << 0) |
996 | # define RADEON_CRTC_VBLANK_STAT_ACK (1 << 0) | 1001 | # define RADEON_CRTC_VBLANK_STAT_ACK (1 << 0) |
1002 | # define RADEON_FP_DETECT_STAT (1 << 4) | ||
1003 | # define RADEON_FP_DETECT_STAT_ACK (1 << 4) | ||
997 | # define RADEON_CRTC2_VBLANK_STAT (1 << 9) | 1004 | # define RADEON_CRTC2_VBLANK_STAT (1 << 9) |
998 | # define RADEON_CRTC2_VBLANK_STAT_ACK (1 << 9) | 1005 | # define RADEON_CRTC2_VBLANK_STAT_ACK (1 << 9) |
1006 | # define RADEON_FP2_DETECT_STAT (1 << 10) | ||
1007 | # define RADEON_FP2_DETECT_STAT_ACK (1 << 10) | ||
999 | # define RADEON_SW_INT_FIRE (1 << 26) | 1008 | # define RADEON_SW_INT_FIRE (1 << 26) |
1000 | # define RADEON_SW_INT_TEST (1 << 25) | 1009 | # define RADEON_SW_INT_TEST (1 << 25) |
1001 | # define RADEON_SW_INT_TEST_ACK (1 << 25) | 1010 | # define RADEON_SW_INT_TEST_ACK (1 << 25) |
@@ -1148,16 +1157,16 @@ | |||
1148 | # define RADEON_IO_MCLK_MAX_DYN_STOP_LAT (1 << 13) | 1157 | # define RADEON_IO_MCLK_MAX_DYN_STOP_LAT (1 << 13) |
1149 | # define RADEON_MC_MCLK_DYN_ENABLE (1 << 14) | 1158 | # define RADEON_MC_MCLK_DYN_ENABLE (1 << 14) |
1150 | # define RADEON_IO_MCLK_DYN_ENABLE (1 << 15) | 1159 | # define RADEON_IO_MCLK_DYN_ENABLE (1 << 15) |
1160 | |||
1151 | #define RADEON_GPIOPAD_MASK 0x0198 | 1161 | #define RADEON_GPIOPAD_MASK 0x0198 |
1152 | #define RADEON_GPIOPAD_A 0x019c | 1162 | #define RADEON_GPIOPAD_A 0x019c |
1153 | #define RADEON_GPIOPAD_EN 0x01a0 | 1163 | #define RADEON_GPIOPAD_EN 0x01a0 |
1154 | #define RADEON_GPIOPAD_Y 0x01a4 | 1164 | #define RADEON_GPIOPAD_Y 0x01a4 |
1155 | #define RADEON_LCD_GPIO_MASK 0x01a0 | 1165 | #define RADEON_MDGPIO_MASK 0x01a8 |
1156 | #define RADEON_LCD_GPIO_Y_REG 0x01a4 | 1166 | #define RADEON_MDGPIO_A 0x01ac |
1157 | #define RADEON_MDGPIO_A_REG 0x01ac | 1167 | #define RADEON_MDGPIO_EN 0x01b0 |
1158 | #define RADEON_MDGPIO_EN_REG 0x01b0 | 1168 | #define RADEON_MDGPIO_Y 0x01b4 |
1159 | #define RADEON_MDGPIO_MASK 0x0198 | 1169 | |
1160 | #define RADEON_MDGPIO_Y_REG 0x01b4 | ||
1161 | #define RADEON_MEM_ADDR_CONFIG 0x0148 | 1170 | #define RADEON_MEM_ADDR_CONFIG 0x0148 |
1162 | #define RADEON_MEM_BASE 0x0f10 /* PCI */ | 1171 | #define RADEON_MEM_BASE 0x0f10 /* PCI */ |
1163 | #define RADEON_MEM_CNTL 0x0140 | 1172 | #define RADEON_MEM_CNTL 0x0140 |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 84b26376027d..fd5ab01f6ad1 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -60,6 +60,107 @@ int rs600_mc_init(struct radeon_device *rdev) | |||
60 | return r; | 60 | return r; |
61 | return 0; | 61 | return 0; |
62 | } | 62 | } |
63 | |||
64 | /* hpd for digital panel detect/disconnect */ | ||
65 | bool rs600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) | ||
66 | { | ||
67 | u32 tmp; | ||
68 | bool connected = false; | ||
69 | |||
70 | switch (hpd) { | ||
71 | case RADEON_HPD_1: | ||
72 | tmp = RREG32(R_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS); | ||
73 | if (G_007D04_DC_HOT_PLUG_DETECT1_SENSE(tmp)) | ||
74 | connected = true; | ||
75 | break; | ||
76 | case RADEON_HPD_2: | ||
77 | tmp = RREG32(R_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS); | ||
78 | if (G_007D14_DC_HOT_PLUG_DETECT2_SENSE(tmp)) | ||
79 | connected = true; | ||
80 | break; | ||
81 | default: | ||
82 | break; | ||
83 | } | ||
84 | return connected; | ||
85 | } | ||
86 | |||
87 | void rs600_hpd_set_polarity(struct radeon_device *rdev, | ||
88 | enum radeon_hpd_id hpd) | ||
89 | { | ||
90 | u32 tmp; | ||
91 | bool connected = rs600_hpd_sense(rdev, hpd); | ||
92 | |||
93 | switch (hpd) { | ||
94 | case RADEON_HPD_1: | ||
95 | tmp = RREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL); | ||
96 | if (connected) | ||
97 | tmp &= ~S_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(1); | ||
98 | else | ||
99 | tmp |= S_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(1); | ||
100 | WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); | ||
101 | break; | ||
102 | case RADEON_HPD_2: | ||
103 | tmp = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL); | ||
104 | if (connected) | ||
105 | tmp &= ~S_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(1); | ||
106 | else | ||
107 | tmp |= S_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(1); | ||
108 | WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); | ||
109 | break; | ||
110 | default: | ||
111 | break; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | void rs600_hpd_init(struct radeon_device *rdev) | ||
116 | { | ||
117 | struct drm_device *dev = rdev->ddev; | ||
118 | struct drm_connector *connector; | ||
119 | |||
120 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
121 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
122 | switch (radeon_connector->hpd.hpd) { | ||
123 | case RADEON_HPD_1: | ||
124 | WREG32(R_007D00_DC_HOT_PLUG_DETECT1_CONTROL, | ||
125 | S_007D00_DC_HOT_PLUG_DETECT1_EN(1)); | ||
126 | rdev->irq.hpd[0] = true; | ||
127 | break; | ||
128 | case RADEON_HPD_2: | ||
129 | WREG32(R_007D10_DC_HOT_PLUG_DETECT2_CONTROL, | ||
130 | S_007D10_DC_HOT_PLUG_DETECT2_EN(1)); | ||
131 | rdev->irq.hpd[1] = true; | ||
132 | break; | ||
133 | default: | ||
134 | break; | ||
135 | } | ||
136 | } | ||
137 | rs600_irq_set(rdev); | ||
138 | } | ||
139 | |||
140 | void rs600_hpd_fini(struct radeon_device *rdev) | ||
141 | { | ||
142 | struct drm_device *dev = rdev->ddev; | ||
143 | struct drm_connector *connector; | ||
144 | |||
145 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
146 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
147 | switch (radeon_connector->hpd.hpd) { | ||
148 | case RADEON_HPD_1: | ||
149 | WREG32(R_007D00_DC_HOT_PLUG_DETECT1_CONTROL, | ||
150 | S_007D00_DC_HOT_PLUG_DETECT1_EN(0)); | ||
151 | rdev->irq.hpd[0] = false; | ||
152 | break; | ||
153 | case RADEON_HPD_2: | ||
154 | WREG32(R_007D10_DC_HOT_PLUG_DETECT2_CONTROL, | ||
155 | S_007D10_DC_HOT_PLUG_DETECT2_EN(0)); | ||
156 | rdev->irq.hpd[1] = false; | ||
157 | break; | ||
158 | default: | ||
159 | break; | ||
160 | } | ||
161 | } | ||
162 | } | ||
163 | |||
63 | /* | 164 | /* |
64 | * GART. | 165 | * GART. |
65 | */ | 166 | */ |
@@ -209,6 +310,10 @@ int rs600_irq_set(struct radeon_device *rdev) | |||
209 | { | 310 | { |
210 | uint32_t tmp = 0; | 311 | uint32_t tmp = 0; |
211 | uint32_t mode_int = 0; | 312 | uint32_t mode_int = 0; |
313 | u32 hpd1 = RREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL) & | ||
314 | ~S_007D08_DC_HOT_PLUG_DETECT1_INT_EN(1); | ||
315 | u32 hpd2 = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL) & | ||
316 | ~S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1); | ||
212 | 317 | ||
213 | if (rdev->irq.sw_int) { | 318 | if (rdev->irq.sw_int) { |
214 | tmp |= S_000040_SW_INT_EN(1); | 319 | tmp |= S_000040_SW_INT_EN(1); |
@@ -219,8 +324,16 @@ int rs600_irq_set(struct radeon_device *rdev) | |||
219 | if (rdev->irq.crtc_vblank_int[1]) { | 324 | if (rdev->irq.crtc_vblank_int[1]) { |
220 | mode_int |= S_006540_D2MODE_VBLANK_INT_MASK(1); | 325 | mode_int |= S_006540_D2MODE_VBLANK_INT_MASK(1); |
221 | } | 326 | } |
327 | if (rdev->irq.hpd[0]) { | ||
328 | hpd1 |= S_007D08_DC_HOT_PLUG_DETECT1_INT_EN(1); | ||
329 | } | ||
330 | if (rdev->irq.hpd[1]) { | ||
331 | hpd2 |= S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1); | ||
332 | } | ||
222 | WREG32(R_000040_GEN_INT_CNTL, tmp); | 333 | WREG32(R_000040_GEN_INT_CNTL, tmp); |
223 | WREG32(R_006540_DxMODE_INT_MASK, mode_int); | 334 | WREG32(R_006540_DxMODE_INT_MASK, mode_int); |
335 | WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, hpd1); | ||
336 | WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2); | ||
224 | return 0; | 337 | return 0; |
225 | } | 338 | } |
226 | 339 | ||
@@ -228,6 +341,7 @@ static inline uint32_t rs600_irq_ack(struct radeon_device *rdev, u32 *r500_disp_ | |||
228 | { | 341 | { |
229 | uint32_t irqs = RREG32(R_000044_GEN_INT_STATUS); | 342 | uint32_t irqs = RREG32(R_000044_GEN_INT_STATUS); |
230 | uint32_t irq_mask = ~C_000044_SW_INT; | 343 | uint32_t irq_mask = ~C_000044_SW_INT; |
344 | u32 tmp; | ||
231 | 345 | ||
232 | if (G_000044_DISPLAY_INT_STAT(irqs)) { | 346 | if (G_000044_DISPLAY_INT_STAT(irqs)) { |
233 | *r500_disp_int = RREG32(R_007EDC_DISP_INTERRUPT_STATUS); | 347 | *r500_disp_int = RREG32(R_007EDC_DISP_INTERRUPT_STATUS); |
@@ -239,6 +353,16 @@ static inline uint32_t rs600_irq_ack(struct radeon_device *rdev, u32 *r500_disp_ | |||
239 | WREG32(R_006D34_D2MODE_VBLANK_STATUS, | 353 | WREG32(R_006D34_D2MODE_VBLANK_STATUS, |
240 | S_006D34_D2MODE_VBLANK_ACK(1)); | 354 | S_006D34_D2MODE_VBLANK_ACK(1)); |
241 | } | 355 | } |
356 | if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(*r500_disp_int)) { | ||
357 | tmp = RREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL); | ||
358 | tmp |= S_007D08_DC_HOT_PLUG_DETECT1_INT_ACK(1); | ||
359 | WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); | ||
360 | } | ||
361 | if (G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(*r500_disp_int)) { | ||
362 | tmp = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL); | ||
363 | tmp |= S_007D18_DC_HOT_PLUG_DETECT2_INT_ACK(1); | ||
364 | WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); | ||
365 | } | ||
242 | } else { | 366 | } else { |
243 | *r500_disp_int = 0; | 367 | *r500_disp_int = 0; |
244 | } | 368 | } |
@@ -264,6 +388,7 @@ int rs600_irq_process(struct radeon_device *rdev) | |||
264 | { | 388 | { |
265 | uint32_t status, msi_rearm; | 389 | uint32_t status, msi_rearm; |
266 | uint32_t r500_disp_int; | 390 | uint32_t r500_disp_int; |
391 | bool queue_hotplug = false; | ||
267 | 392 | ||
268 | status = rs600_irq_ack(rdev, &r500_disp_int); | 393 | status = rs600_irq_ack(rdev, &r500_disp_int); |
269 | if (!status && !r500_disp_int) { | 394 | if (!status && !r500_disp_int) { |
@@ -278,8 +403,18 @@ int rs600_irq_process(struct radeon_device *rdev) | |||
278 | drm_handle_vblank(rdev->ddev, 0); | 403 | drm_handle_vblank(rdev->ddev, 0); |
279 | if (G_007EDC_LB_D2_VBLANK_INTERRUPT(r500_disp_int)) | 404 | if (G_007EDC_LB_D2_VBLANK_INTERRUPT(r500_disp_int)) |
280 | drm_handle_vblank(rdev->ddev, 1); | 405 | drm_handle_vblank(rdev->ddev, 1); |
406 | if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(r500_disp_int)) { | ||
407 | queue_hotplug = true; | ||
408 | DRM_DEBUG("HPD1\n"); | ||
409 | } | ||
410 | if (G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(r500_disp_int)) { | ||
411 | queue_hotplug = true; | ||
412 | DRM_DEBUG("HPD2\n"); | ||
413 | } | ||
281 | status = rs600_irq_ack(rdev, &r500_disp_int); | 414 | status = rs600_irq_ack(rdev, &r500_disp_int); |
282 | } | 415 | } |
416 | if (queue_hotplug) | ||
417 | queue_work(rdev->wq, &rdev->hotplug_work); | ||
283 | if (rdev->msi_enabled) { | 418 | if (rdev->msi_enabled) { |
284 | switch (rdev->family) { | 419 | switch (rdev->family) { |
285 | case CHIP_RS600: | 420 | case CHIP_RS600: |
diff --git a/drivers/gpu/drm/radeon/rs600d.h b/drivers/gpu/drm/radeon/rs600d.h index 81308924859a..c1c8f5885cbb 100644 --- a/drivers/gpu/drm/radeon/rs600d.h +++ b/drivers/gpu/drm/radeon/rs600d.h | |||
@@ -30,27 +30,12 @@ | |||
30 | 30 | ||
31 | /* Registers */ | 31 | /* Registers */ |
32 | #define R_000040_GEN_INT_CNTL 0x000040 | 32 | #define R_000040_GEN_INT_CNTL 0x000040 |
33 | #define S_000040_DISPLAY_INT_STATUS(x) (((x) & 0x1) << 0) | 33 | #define S_000040_SCRATCH_INT_MASK(x) (((x) & 0x1) << 18) |
34 | #define G_000040_DISPLAY_INT_STATUS(x) (((x) >> 0) & 0x1) | 34 | #define G_000040_SCRATCH_INT_MASK(x) (((x) >> 18) & 0x1) |
35 | #define C_000040_DISPLAY_INT_STATUS 0xFFFFFFFE | 35 | #define C_000040_SCRATCH_INT_MASK 0xFFFBFFFF |
36 | #define S_000040_DMA_VIPH0_INT_EN(x) (((x) & 0x1) << 12) | 36 | #define S_000040_GUI_IDLE_MASK(x) (((x) & 0x1) << 19) |
37 | #define G_000040_DMA_VIPH0_INT_EN(x) (((x) >> 12) & 0x1) | 37 | #define G_000040_GUI_IDLE_MASK(x) (((x) >> 19) & 0x1) |
38 | #define C_000040_DMA_VIPH0_INT_EN 0xFFFFEFFF | 38 | #define C_000040_GUI_IDLE_MASK 0xFFF7FFFF |
39 | #define S_000040_CRTC2_VSYNC(x) (((x) & 0x1) << 6) | ||
40 | #define G_000040_CRTC2_VSYNC(x) (((x) >> 6) & 0x1) | ||
41 | #define C_000040_CRTC2_VSYNC 0xFFFFFFBF | ||
42 | #define S_000040_SNAPSHOT2(x) (((x) & 0x1) << 7) | ||
43 | #define G_000040_SNAPSHOT2(x) (((x) >> 7) & 0x1) | ||
44 | #define C_000040_SNAPSHOT2 0xFFFFFF7F | ||
45 | #define S_000040_CRTC2_VBLANK(x) (((x) & 0x1) << 9) | ||
46 | #define G_000040_CRTC2_VBLANK(x) (((x) >> 9) & 0x1) | ||
47 | #define C_000040_CRTC2_VBLANK 0xFFFFFDFF | ||
48 | #define S_000040_FP2_DETECT(x) (((x) & 0x1) << 10) | ||
49 | #define G_000040_FP2_DETECT(x) (((x) >> 10) & 0x1) | ||
50 | #define C_000040_FP2_DETECT 0xFFFFFBFF | ||
51 | #define S_000040_VSYNC_DIFF_OVER_LIMIT(x) (((x) & 0x1) << 11) | ||
52 | #define G_000040_VSYNC_DIFF_OVER_LIMIT(x) (((x) >> 11) & 0x1) | ||
53 | #define C_000040_VSYNC_DIFF_OVER_LIMIT 0xFFFFF7FF | ||
54 | #define S_000040_DMA_VIPH1_INT_EN(x) (((x) & 0x1) << 13) | 39 | #define S_000040_DMA_VIPH1_INT_EN(x) (((x) & 0x1) << 13) |
55 | #define G_000040_DMA_VIPH1_INT_EN(x) (((x) >> 13) & 0x1) | 40 | #define G_000040_DMA_VIPH1_INT_EN(x) (((x) >> 13) & 0x1) |
56 | #define C_000040_DMA_VIPH1_INT_EN 0xFFFFDFFF | 41 | #define C_000040_DMA_VIPH1_INT_EN 0xFFFFDFFF |
@@ -370,7 +355,90 @@ | |||
370 | #define S_007EDC_LB_D2_VBLANK_INTERRUPT(x) (((x) & 0x1) << 5) | 355 | #define S_007EDC_LB_D2_VBLANK_INTERRUPT(x) (((x) & 0x1) << 5) |
371 | #define G_007EDC_LB_D2_VBLANK_INTERRUPT(x) (((x) >> 5) & 0x1) | 356 | #define G_007EDC_LB_D2_VBLANK_INTERRUPT(x) (((x) >> 5) & 0x1) |
372 | #define C_007EDC_LB_D2_VBLANK_INTERRUPT 0xFFFFFFDF | 357 | #define C_007EDC_LB_D2_VBLANK_INTERRUPT 0xFFFFFFDF |
373 | 358 | #define S_007EDC_DACA_AUTODETECT_INTERRUPT(x) (((x) & 0x1) << 16) | |
359 | #define G_007EDC_DACA_AUTODETECT_INTERRUPT(x) (((x) >> 16) & 0x1) | ||
360 | #define C_007EDC_DACA_AUTODETECT_INTERRUPT 0xFFFEFFFF | ||
361 | #define S_007EDC_DACB_AUTODETECT_INTERRUPT(x) (((x) & 0x1) << 17) | ||
362 | #define G_007EDC_DACB_AUTODETECT_INTERRUPT(x) (((x) >> 17) & 0x1) | ||
363 | #define C_007EDC_DACB_AUTODETECT_INTERRUPT 0xFFFDFFFF | ||
364 | #define S_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(x) (((x) & 0x1) << 18) | ||
365 | #define G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(x) (((x) >> 18) & 0x1) | ||
366 | #define C_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT 0xFFFBFFFF | ||
367 | #define S_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(x) (((x) & 0x1) << 19) | ||
368 | #define G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(x) (((x) >> 19) & 0x1) | ||
369 | #define C_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT 0xFFF7FFFF | ||
370 | #define R_007828_DACA_AUTODETECT_CONTROL 0x007828 | ||
371 | #define S_007828_DACA_AUTODETECT_MODE(x) (((x) & 0x3) << 0) | ||
372 | #define G_007828_DACA_AUTODETECT_MODE(x) (((x) >> 0) & 0x3) | ||
373 | #define C_007828_DACA_AUTODETECT_MODE 0xFFFFFFFC | ||
374 | #define S_007828_DACA_AUTODETECT_FRAME_TIME_COUNTER(x) (((x) & 0xff) << 8) | ||
375 | #define G_007828_DACA_AUTODETECT_FRAME_TIME_COUNTER(x) (((x) >> 8) & 0xff) | ||
376 | #define C_007828_DACA_AUTODETECT_FRAME_TIME_COUNTER 0xFFFF00FF | ||
377 | #define S_007828_DACA_AUTODETECT_CHECK_MASK(x) (((x) & 0x3) << 16) | ||
378 | #define G_007828_DACA_AUTODETECT_CHECK_MASK(x) (((x) >> 16) & 0x3) | ||
379 | #define C_007828_DACA_AUTODETECT_CHECK_MASK 0xFFFCFFFF | ||
380 | #define R_007838_DACA_AUTODETECT_INT_CONTROL 0x007838 | ||
381 | #define S_007838_DACA_AUTODETECT_ACK(x) (((x) & 0x1) << 0) | ||
382 | #define C_007838_DACA_DACA_AUTODETECT_ACK 0xFFFFFFFE | ||
383 | #define S_007838_DACA_AUTODETECT_INT_ENABLE(x) (((x) & 0x1) << 16) | ||
384 | #define G_007838_DACA_AUTODETECT_INT_ENABLE(x) (((x) >> 16) & 0x1) | ||
385 | #define C_007838_DACA_AUTODETECT_INT_ENABLE 0xFFFCFFFF | ||
386 | #define R_007A28_DACB_AUTODETECT_CONTROL 0x007A28 | ||
387 | #define S_007A28_DACB_AUTODETECT_MODE(x) (((x) & 0x3) << 0) | ||
388 | #define G_007A28_DACB_AUTODETECT_MODE(x) (((x) >> 0) & 0x3) | ||
389 | #define C_007A28_DACB_AUTODETECT_MODE 0xFFFFFFFC | ||
390 | #define S_007A28_DACB_AUTODETECT_FRAME_TIME_COUNTER(x) (((x) & 0xff) << 8) | ||
391 | #define G_007A28_DACB_AUTODETECT_FRAME_TIME_COUNTER(x) (((x) >> 8) & 0xff) | ||
392 | #define C_007A28_DACB_AUTODETECT_FRAME_TIME_COUNTER 0xFFFF00FF | ||
393 | #define S_007A28_DACB_AUTODETECT_CHECK_MASK(x) (((x) & 0x3) << 16) | ||
394 | #define G_007A28_DACB_AUTODETECT_CHECK_MASK(x) (((x) >> 16) & 0x3) | ||
395 | #define C_007A28_DACB_AUTODETECT_CHECK_MASK 0xFFFCFFFF | ||
396 | #define R_007A38_DACB_AUTODETECT_INT_CONTROL 0x007A38 | ||
397 | #define S_007A38_DACB_AUTODETECT_ACK(x) (((x) & 0x1) << 0) | ||
398 | #define C_007A38_DACB_DACA_AUTODETECT_ACK 0xFFFFFFFE | ||
399 | #define S_007A38_DACB_AUTODETECT_INT_ENABLE(x) (((x) & 0x1) << 16) | ||
400 | #define G_007A38_DACB_AUTODETECT_INT_ENABLE(x) (((x) >> 16) & 0x1) | ||
401 | #define C_007A38_DACB_AUTODETECT_INT_ENABLE 0xFFFCFFFF | ||
402 | #define R_007D00_DC_HOT_PLUG_DETECT1_CONTROL 0x007D00 | ||
403 | #define S_007D00_DC_HOT_PLUG_DETECT1_EN(x) (((x) & 0x1) << 0) | ||
404 | #define G_007D00_DC_HOT_PLUG_DETECT1_EN(x) (((x) >> 0) & 0x1) | ||
405 | #define C_007D00_DC_HOT_PLUG_DETECT1_EN 0xFFFFFFFE | ||
406 | #define R_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS 0x007D04 | ||
407 | #define S_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS(x) (((x) & 0x1) << 0) | ||
408 | #define G_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS(x) (((x) >> 0) & 0x1) | ||
409 | #define C_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS 0xFFFFFFFE | ||
410 | #define S_007D04_DC_HOT_PLUG_DETECT1_SENSE(x) (((x) & 0x1) << 1) | ||
411 | #define G_007D04_DC_HOT_PLUG_DETECT1_SENSE(x) (((x) >> 1) & 0x1) | ||
412 | #define C_007D04_DC_HOT_PLUG_DETECT1_SENSE 0xFFFFFFFD | ||
413 | #define R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL 0x007D08 | ||
414 | #define S_007D08_DC_HOT_PLUG_DETECT1_INT_ACK(x) (((x) & 0x1) << 0) | ||
415 | #define C_007D08_DC_HOT_PLUG_DETECT1_INT_ACK 0xFFFFFFFE | ||
416 | #define S_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(x) (((x) & 0x1) << 8) | ||
417 | #define G_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(x) (((x) >> 8) & 0x1) | ||
418 | #define C_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY 0xFFFFFEFF | ||
419 | #define S_007D08_DC_HOT_PLUG_DETECT1_INT_EN(x) (((x) & 0x1) << 16) | ||
420 | #define G_007D08_DC_HOT_PLUG_DETECT1_INT_EN(x) (((x) >> 16) & 0x1) | ||
421 | #define C_007D08_DC_HOT_PLUG_DETECT1_INT_EN 0xFFFEFFFF | ||
422 | #define R_007D10_DC_HOT_PLUG_DETECT2_CONTROL 0x007D10 | ||
423 | #define S_007D10_DC_HOT_PLUG_DETECT2_EN(x) (((x) & 0x1) << 0) | ||
424 | #define G_007D10_DC_HOT_PLUG_DETECT2_EN(x) (((x) >> 0) & 0x1) | ||
425 | #define C_007D10_DC_HOT_PLUG_DETECT2_EN 0xFFFFFFFE | ||
426 | #define R_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS 0x007D14 | ||
427 | #define S_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS(x) (((x) & 0x1) << 0) | ||
428 | #define G_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS(x) (((x) >> 0) & 0x1) | ||
429 | #define C_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS 0xFFFFFFFE | ||
430 | #define S_007D14_DC_HOT_PLUG_DETECT2_SENSE(x) (((x) & 0x1) << 1) | ||
431 | #define G_007D14_DC_HOT_PLUG_DETECT2_SENSE(x) (((x) >> 1) & 0x1) | ||
432 | #define C_007D14_DC_HOT_PLUG_DETECT2_SENSE 0xFFFFFFFD | ||
433 | #define R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL 0x007D18 | ||
434 | #define S_007D18_DC_HOT_PLUG_DETECT2_INT_ACK(x) (((x) & 0x1) << 0) | ||
435 | #define C_007D18_DC_HOT_PLUG_DETECT2_INT_ACK 0xFFFFFFFE | ||
436 | #define S_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(x) (((x) & 0x1) << 8) | ||
437 | #define G_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(x) (((x) >> 8) & 0x1) | ||
438 | #define C_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY 0xFFFFFEFF | ||
439 | #define S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(x) (((x) & 0x1) << 16) | ||
440 | #define G_007D18_DC_HOT_PLUG_DETECT2_INT_EN(x) (((x) >> 16) & 0x1) | ||
441 | #define C_007D18_DC_HOT_PLUG_DETECT2_INT_EN 0xFFFEFFFF | ||
374 | 442 | ||
375 | /* MC registers */ | 443 | /* MC registers */ |
376 | #define R_000000_MC_STATUS 0x000000 | 444 | #define R_000000_MC_STATUS 0x000000 |
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index e49879ce95f9..a49e791db0b0 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h | |||
@@ -43,16 +43,41 @@ | |||
43 | #define AUX_I2C_REPLY_MASK (0x3 << 6) | 43 | #define AUX_I2C_REPLY_MASK (0x3 << 6) |
44 | 44 | ||
45 | /* AUX CH addresses */ | 45 | /* AUX CH addresses */ |
46 | #define DP_LINK_BW_SET 0x100 | 46 | /* DPCD */ |
47 | #define DP_DPCD_REV 0x000 | ||
48 | |||
49 | #define DP_MAX_LINK_RATE 0x001 | ||
50 | |||
51 | #define DP_MAX_LANE_COUNT 0x002 | ||
52 | # define DP_MAX_LANE_COUNT_MASK 0x1f | ||
53 | # define DP_ENHANCED_FRAME_CAP (1 << 7) | ||
54 | |||
55 | #define DP_MAX_DOWNSPREAD 0x003 | ||
56 | # define DP_NO_AUX_HANDSHAKE_LINK_TRAINING (1 << 6) | ||
57 | |||
58 | #define DP_NORP 0x004 | ||
59 | |||
60 | #define DP_DOWNSTREAMPORT_PRESENT 0x005 | ||
61 | # define DP_DWN_STRM_PORT_PRESENT (1 << 0) | ||
62 | # define DP_DWN_STRM_PORT_TYPE_MASK 0x06 | ||
63 | /* 00b = DisplayPort */ | ||
64 | /* 01b = Analog */ | ||
65 | /* 10b = TMDS or HDMI */ | ||
66 | /* 11b = Other */ | ||
67 | # define DP_FORMAT_CONVERSION (1 << 3) | ||
68 | |||
69 | #define DP_MAIN_LINK_CHANNEL_CODING 0x006 | ||
70 | |||
71 | /* link configuration */ | ||
72 | #define DP_LINK_BW_SET 0x100 | ||
47 | # define DP_LINK_BW_1_62 0x06 | 73 | # define DP_LINK_BW_1_62 0x06 |
48 | # define DP_LINK_BW_2_7 0x0a | 74 | # define DP_LINK_BW_2_7 0x0a |
49 | 75 | ||
50 | #define DP_LANE_COUNT_SET 0x101 | 76 | #define DP_LANE_COUNT_SET 0x101 |
51 | # define DP_LANE_COUNT_MASK 0x0f | 77 | # define DP_LANE_COUNT_MASK 0x0f |
52 | # define DP_LANE_COUNT_ENHANCED_FRAME_EN (1 << 7) | 78 | # define DP_LANE_COUNT_ENHANCED_FRAME_EN (1 << 7) |
53 | 79 | ||
54 | #define DP_TRAINING_PATTERN_SET 0x102 | 80 | #define DP_TRAINING_PATTERN_SET 0x102 |
55 | |||
56 | # define DP_TRAINING_PATTERN_DISABLE 0 | 81 | # define DP_TRAINING_PATTERN_DISABLE 0 |
57 | # define DP_TRAINING_PATTERN_1 1 | 82 | # define DP_TRAINING_PATTERN_1 1 |
58 | # define DP_TRAINING_PATTERN_2 2 | 83 | # define DP_TRAINING_PATTERN_2 2 |
@@ -102,11 +127,14 @@ | |||
102 | 127 | ||
103 | #define DP_LANE0_1_STATUS 0x202 | 128 | #define DP_LANE0_1_STATUS 0x202 |
104 | #define DP_LANE2_3_STATUS 0x203 | 129 | #define DP_LANE2_3_STATUS 0x203 |
105 | |||
106 | # define DP_LANE_CR_DONE (1 << 0) | 130 | # define DP_LANE_CR_DONE (1 << 0) |
107 | # define DP_LANE_CHANNEL_EQ_DONE (1 << 1) | 131 | # define DP_LANE_CHANNEL_EQ_DONE (1 << 1) |
108 | # define DP_LANE_SYMBOL_LOCKED (1 << 2) | 132 | # define DP_LANE_SYMBOL_LOCKED (1 << 2) |
109 | 133 | ||
134 | #define DP_CHANNEL_EQ_BITS (DP_LANE_CR_DONE | \ | ||
135 | DP_LANE_CHANNEL_EQ_DONE | \ | ||
136 | DP_LANE_SYMBOL_LOCKED) | ||
137 | |||
110 | #define DP_LANE_ALIGN_STATUS_UPDATED 0x204 | 138 | #define DP_LANE_ALIGN_STATUS_UPDATED 0x204 |
111 | 139 | ||
112 | #define DP_INTERLANE_ALIGN_DONE (1 << 0) | 140 | #define DP_INTERLANE_ALIGN_DONE (1 << 0) |
@@ -120,15 +148,18 @@ | |||
120 | 148 | ||
121 | #define DP_ADJUST_REQUEST_LANE0_1 0x206 | 149 | #define DP_ADJUST_REQUEST_LANE0_1 0x206 |
122 | #define DP_ADJUST_REQUEST_LANE2_3 0x207 | 150 | #define DP_ADJUST_REQUEST_LANE2_3 0x207 |
123 | 151 | # define DP_ADJUST_VOLTAGE_SWING_LANE0_MASK 0x03 | |
124 | #define DP_ADJUST_VOLTAGE_SWING_LANE0_MASK 0x03 | 152 | # define DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT 0 |
125 | #define DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT 0 | 153 | # define DP_ADJUST_PRE_EMPHASIS_LANE0_MASK 0x0c |
126 | #define DP_ADJUST_PRE_EMPHASIS_LANE0_MASK 0x0c | 154 | # define DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT 2 |
127 | #define DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT 2 | 155 | # define DP_ADJUST_VOLTAGE_SWING_LANE1_MASK 0x30 |
128 | #define DP_ADJUST_VOLTAGE_SWING_LANE1_MASK 0x30 | 156 | # define DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT 4 |
129 | #define DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT 4 | 157 | # define DP_ADJUST_PRE_EMPHASIS_LANE1_MASK 0xc0 |
130 | #define DP_ADJUST_PRE_EMPHASIS_LANE1_MASK 0xc0 | 158 | # define DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT 6 |
131 | #define DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT 6 | 159 | |
160 | #define DP_SET_POWER 0x600 | ||
161 | # define DP_SET_POWER_D0 0x1 | ||
162 | # define DP_SET_POWER_D3 0x2 | ||
132 | 163 | ||
133 | #define MODE_I2C_START 1 | 164 | #define MODE_I2C_START 1 |
134 | #define MODE_I2C_WRITE 2 | 165 | #define MODE_I2C_WRITE 2 |