Rev 3764 | Rev 5128 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3764 | Rev 5078 | ||
---|---|---|---|
Line 42... | Line 42... | ||
42 | static char *pre_emph_names[] = { |
42 | static char *pre_emph_names[] = { |
43 | "0dB", "3.5dB", "6dB", "9.5dB" |
43 | "0dB", "3.5dB", "6dB", "9.5dB" |
44 | }; |
44 | }; |
Line 45... | Line 45... | ||
45 | 45 | ||
- | 46 | /***** radeon AUX functions *****/ |
|
- | 47 | ||
- | 48 | /* Atom needs data in little endian format |
|
- | 49 | * so swap as appropriate when copying data to |
|
- | 50 | * or from atom. Note that atom operates on |
|
- | 51 | * dw units. |
|
- | 52 | */ |
|
- | 53 | void radeon_atom_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le) |
|
- | 54 | { |
|
- | 55 | #ifdef __BIG_ENDIAN |
|
- | 56 | u8 src_tmp[20], dst_tmp[20]; /* used for byteswapping */ |
|
- | 57 | u32 *dst32, *src32; |
|
- | 58 | int i; |
|
- | 59 | ||
- | 60 | memcpy(src_tmp, src, num_bytes); |
|
- | 61 | src32 = (u32 *)src_tmp; |
|
- | 62 | dst32 = (u32 *)dst_tmp; |
|
- | 63 | if (to_le) { |
|
- | 64 | for (i = 0; i < ((num_bytes + 3) / 4); i++) |
|
- | 65 | dst32[i] = cpu_to_le32(src32[i]); |
|
- | 66 | memcpy(dst, dst_tmp, num_bytes); |
|
- | 67 | } else { |
|
- | 68 | u8 dws = num_bytes & ~3; |
|
- | 69 | for (i = 0; i < ((num_bytes + 3) / 4); i++) |
|
- | 70 | dst32[i] = le32_to_cpu(src32[i]); |
|
- | 71 | memcpy(dst, dst_tmp, dws); |
|
- | 72 | if (num_bytes % 4) { |
|
- | 73 | for (i = 0; i < (num_bytes % 4); i++) |
|
- | 74 | dst[dws+i] = dst_tmp[dws+i]; |
|
- | 75 | } |
|
- | 76 | } |
|
- | 77 | #else |
|
- | 78 | memcpy(dst, src, num_bytes); |
|
- | 79 | #endif |
|
- | 80 | } |
|
46 | /***** radeon AUX functions *****/ |
81 | |
47 | union aux_channel_transaction { |
82 | union aux_channel_transaction { |
48 | PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION v1; |
83 | PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION v1; |
49 | PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2 v2; |
84 | PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2 v2; |
Line 58... | Line 93... | ||
58 | struct radeon_device *rdev = dev->dev_private; |
93 | struct radeon_device *rdev = dev->dev_private; |
59 | union aux_channel_transaction args; |
94 | union aux_channel_transaction args; |
60 | int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction); |
95 | int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction); |
61 | unsigned char *base; |
96 | unsigned char *base; |
62 | int recv_bytes; |
97 | int recv_bytes; |
- | 98 | int r = 0; |
|
Line 63... | Line 99... | ||
63 | 99 | ||
Line -... | Line 100... | ||
- | 100 | memset(&args, 0, sizeof(args)); |
|
- | 101 | ||
64 | memset(&args, 0, sizeof(args)); |
102 | mutex_lock(&chan->mutex); |
Line 65... | Line 103... | ||
65 | 103 | ||
Line 66... | Line 104... | ||
66 | base = (unsigned char *)(rdev->mode_info.atom_context->scratch + 1); |
104 | base = (unsigned char *)(rdev->mode_info.atom_context->scratch + 1); |
67 | 105 | ||
68 | memcpy(base, send, send_bytes); |
106 | radeon_atom_copy_swap(base, send, send_bytes, true); |
69 | 107 | ||
70 | args.v1.lpAuxRequest = 0 + 4; |
108 | args.v1.lpAuxRequest = cpu_to_le16((u16)(0 + 4)); |
71 | args.v1.lpDataOut = 16 + 4; |
109 | args.v1.lpDataOut = cpu_to_le16((u16)(16 + 4)); |
72 | args.v1.ucDataOutLen = 0; |
110 | args.v1.ucDataOutLen = 0; |
Line 80... | Line 118... | ||
80 | *ack = args.v1.ucReplyStatus; |
118 | *ack = args.v1.ucReplyStatus; |
Line 81... | Line 119... | ||
81 | 119 | ||
82 | /* timeout */ |
120 | /* timeout */ |
83 | if (args.v1.ucReplyStatus == 1) { |
121 | if (args.v1.ucReplyStatus == 1) { |
84 | DRM_DEBUG_KMS("dp_aux_ch timeout\n"); |
122 | DRM_DEBUG_KMS("dp_aux_ch timeout\n"); |
- | 123 | r = -ETIMEDOUT; |
|
85 | return -ETIMEDOUT; |
124 | goto done; |
Line 86... | Line 125... | ||
86 | } |
125 | } |
87 | 126 | ||
88 | /* flags not zero */ |
127 | /* flags not zero */ |
89 | if (args.v1.ucReplyStatus == 2) { |
128 | if (args.v1.ucReplyStatus == 2) { |
- | 129 | DRM_DEBUG_KMS("dp_aux_ch flags not zero\n"); |
|
90 | DRM_DEBUG_KMS("dp_aux_ch flags not zero\n"); |
130 | r = -EIO; |
Line 91... | Line 131... | ||
91 | return -EBUSY; |
131 | goto done; |
92 | } |
132 | } |
93 | 133 | ||
94 | /* error */ |
134 | /* error */ |
- | 135 | if (args.v1.ucReplyStatus == 3) { |
|
95 | if (args.v1.ucReplyStatus == 3) { |
136 | DRM_DEBUG_KMS("dp_aux_ch error\n"); |
Line 96... | Line 137... | ||
96 | DRM_DEBUG_KMS("dp_aux_ch error\n"); |
137 | r = -EIO; |
97 | return -EIO; |
138 | goto done; |
98 | } |
139 | } |
Line 99... | Line 140... | ||
99 | 140 | ||
100 | recv_bytes = args.v1.ucDataOutLen; |
141 | recv_bytes = args.v1.ucDataOutLen; |
Line 101... | Line 142... | ||
101 | if (recv_bytes > recv_size) |
142 | if (recv_bytes > recv_size) |
102 | recv_bytes = recv_size; |
- | |
103 | - | ||
104 | if (recv && recv_size) |
- | |
105 | memcpy(recv, base + 16, recv_bytes); |
- | |
106 | - | ||
107 | return recv_bytes; |
- | |
108 | } |
143 | recv_bytes = recv_size; |
109 | - | ||
110 | static int radeon_dp_aux_native_write(struct radeon_connector *radeon_connector, |
144 | |
111 | u16 address, u8 *send, u8 send_bytes, u8 delay) |
- | |
112 | { |
- | |
113 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; |
- | |
114 | int ret; |
- | |
115 | u8 msg[20]; |
- | |
Line 116... | Line -... | ||
116 | int msg_bytes = send_bytes + 4; |
- | |
117 | u8 ack; |
- | |
118 | unsigned retry; |
- | |
119 | - | ||
120 | if (send_bytes > 16) |
- | |
121 | return -1; |
- | |
122 | - | ||
123 | msg[0] = address; |
- | |
124 | msg[1] = address >> 8; |
- | |
125 | msg[2] = AUX_NATIVE_WRITE << 4; |
- | |
126 | msg[3] = (msg_bytes << 4) | (send_bytes - 1); |
- | |
127 | memcpy(&msg[4], send, send_bytes); |
- | |
128 | 145 | if (recv && recv_size) |
|
129 | for (retry = 0; retry < 4; retry++) { |
- | |
130 | ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, |
- | |
131 | msg, msg_bytes, NULL, 0, delay, &ack); |
- | |
132 | if (ret == -EBUSY) |
- | |
133 | continue; |
- | |
134 | else if (ret < 0) |
- | |
135 | return ret; |
146 | radeon_atom_copy_swap(recv, base + 16, recv_bytes, false); |
Line 136... | Line 147... | ||
136 | if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) |
147 | |
137 | return send_bytes; |
- | |
- | 148 | r = recv_bytes; |
|
Line 138... | Line 149... | ||
138 | else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) |
149 | done: |
139 | udelay(400); |
150 | mutex_unlock(&chan->mutex); |
140 | else |
151 | |
141 | return -EIO; |
152 | return r; |
142 | } |
- | |
143 | 153 | } |
|
144 | return -EIO; |
- | |
145 | } |
154 | |
146 | 155 | #define BARE_ADDRESS_SIZE 3 |
|
147 | static int radeon_dp_aux_native_read(struct radeon_connector *radeon_connector, |
- | |
148 | u16 address, u8 *recv, int recv_bytes, u8 delay) |
156 | #define HEADER_SIZE (BARE_ADDRESS_SIZE + 1) |
149 | { |
157 | |
150 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; |
- | |
151 | u8 msg[4]; |
- | |
152 | int msg_bytes = 4; |
158 | static ssize_t |
153 | u8 ack; |
- | |
154 | int ret; |
- | |
155 | unsigned retry; |
- | |
156 | 159 | radeon_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) |
|
157 | msg[0] = address; |
- | |
158 | msg[1] = address >> 8; |
- | |
159 | msg[2] = AUX_NATIVE_READ << 4; |
- | |
160 | msg[3] = (msg_bytes << 4) | (recv_bytes - 1); |
- | |
161 | - | ||
162 | for (retry = 0; retry < 4; retry++) { |
- | |
163 | ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, |
- | |
164 | msg, msg_bytes, recv, recv_bytes, delay, &ack); |
- | |
165 | if (ret == -EBUSY) |
- | |
166 | continue; |
- | |
167 | else if (ret < 0) |
160 | { |
168 | return ret; |
- | |
169 | if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) |
161 | struct radeon_i2c_chan *chan = |
170 | return ret; |
162 | container_of(aux, struct radeon_i2c_chan, aux); |
171 | else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) |
- | |
172 | udelay(400); |
- | |
173 | else if (ret == 0) |
163 | int ret; |
174 | return -EPROTO; |
164 | u8 tx_buf[20]; |
175 | else |
- | |
176 | return -EIO; |
165 | size_t tx_size; |
177 | } |
- | |
178 | 166 | u8 ack, delay = 0; |
|
179 | return -EIO; |
167 | |
180 | } |
168 | if (WARN_ON(msg->size > 16)) |
181 | - | ||
182 | static void radeon_write_dpcd_reg(struct radeon_connector *radeon_connector, |
- | |
183 | u16 reg, u8 val) |
- | |
184 | { |
- | |
185 | radeon_dp_aux_native_write(radeon_connector, reg, &val, 1, 0); |
- | |
186 | } |
169 | return -E2BIG; |
187 | - | ||
188 | static u8 radeon_read_dpcd_reg(struct radeon_connector *radeon_connector, |
- | |
189 | u16 reg) |
170 | |
190 | { |
171 | tx_buf[0] = msg->address & 0xff; |
191 | u8 val = 0; |
172 | tx_buf[1] = msg->address >> 8; |
192 | 173 | tx_buf[2] = msg->request << 4; |
|
193 | radeon_dp_aux_native_read(radeon_connector, reg, &val, 1, 0); |
174 | tx_buf[3] = msg->size ? (msg->size - 1) : 0; |
194 | 175 | ||
195 | return val; |
176 | switch (msg->request & ~DP_AUX_I2C_MOT) { |
196 | } |
177 | case DP_AUX_NATIVE_WRITE: |
197 | 178 | case DP_AUX_I2C_WRITE: |
|
198 | int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, |
179 | /* tx_size needs to be 4 even for bare address packets since the atom |
199 | u8 write_byte, u8 *read_byte) |
180 | * table needs the info in tx_buf[3]. |
200 | { |
181 | */ |
201 | struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; |
- | |
202 | struct radeon_i2c_chan *auxch = (struct radeon_i2c_chan *)adapter; |
- | |
203 | u16 address = algo_data->address; |
182 | tx_size = HEADER_SIZE + msg->size; |
204 | u8 msg[5]; |
- | |
205 | u8 reply[2]; |
183 | if (msg->size == 0) |
206 | unsigned retry; |
184 | tx_buf[3] |= BARE_ADDRESS_SIZE << 4; |
207 | int msg_bytes; |
185 | else |
208 | int reply_bytes = 1; |
- | |
209 | int ret; |
- | |
210 | u8 ack; |
186 | tx_buf[3] |= tx_size << 4; |
211 | - | ||
212 | /* Set up the command byte */ |
187 | memcpy(tx_buf + HEADER_SIZE, msg->buffer, msg->size); |
213 | if (mode & MODE_I2C_READ) |
188 | ret = radeon_process_aux_ch(chan, |
214 | msg[2] = AUX_I2C_READ << 4; |
189 | tx_buf, tx_size, NULL, 0, delay, &ack); |
215 | else |
- | |
216 | msg[2] = AUX_I2C_WRITE << 4; |
190 | if (ret >= 0) |
217 | 191 | /* Return payload size. */ |
|
218 | if (!(mode & MODE_I2C_STOP)) |
192 | ret = msg->size; |
219 | msg[2] |= AUX_I2C_MOT << 4; |
- | |
220 | 193 | break; |
|
221 | msg[0] = address; |
194 | case DP_AUX_NATIVE_READ: |
222 | msg[1] = address >> 8; |
195 | case DP_AUX_I2C_READ: |
223 | 196 | /* tx_size needs to be 4 even for bare address packets since the atom |
|
224 | switch (mode) { |
197 | * table needs the info in tx_buf[3]. |
225 | case MODE_I2C_WRITE: |
198 | */ |
226 | msg_bytes = 5; |
- | |
227 | msg[3] = msg_bytes << 4; |
199 | tx_size = HEADER_SIZE; |
228 | msg[4] = write_byte; |
200 | if (msg->size == 0) |
229 | break; |
201 | tx_buf[3] |= BARE_ADDRESS_SIZE << 4; |
Line 230... | Line -... | ||
230 | case MODE_I2C_READ: |
- | |
231 | msg_bytes = 4; |
- | |
232 | msg[3] = msg_bytes << 4; |
- | |
233 | break; |
202 | else |
234 | default: |
- | |
235 | msg_bytes = 4; |
203 | tx_buf[3] |= tx_size << 4; |
236 | msg[3] = 3 << 4; |
- | |
- | 204 | ret = radeon_process_aux_ch(chan, |
|
237 | break; |
205 | tx_buf, tx_size, msg->buffer, msg->size, delay, &ack); |
238 | } |
206 | break; |
Line 239... | Line -... | ||
239 | - | ||
240 | for (retry = 0; retry < 4; retry++) { |
- | |
241 | ret = radeon_process_aux_ch(auxch, |
207 | default: |
242 | msg, msg_bytes, reply, reply_bytes, 0, &ack); |
- | |
243 | if (ret == -EBUSY) |
208 | ret = -EINVAL; |
244 | continue; |
209 | break; |
245 | else if (ret < 0) { |
- | |
246 | DRM_DEBUG_KMS("aux_ch failed %d\n", ret); |
- | |
247 | return ret; |
- | |
248 | } |
- | |
249 | - | ||
250 | switch (ack & AUX_NATIVE_REPLY_MASK) { |
- | |
251 | case AUX_NATIVE_REPLY_ACK: |
- | |
252 | /* I2C-over-AUX Reply field is only valid |
- | |
253 | * when paired with AUX ACK. |
- | |
254 | */ |
- | |
255 | break; |
- | |
Line 256... | Line 210... | ||
256 | case AUX_NATIVE_REPLY_NACK: |
210 | } |
257 | DRM_DEBUG_KMS("aux_ch native nack\n"); |
- | |
258 | return -EREMOTEIO; |
- | |
259 | case AUX_NATIVE_REPLY_DEFER: |
211 | |
260 | DRM_DEBUG_KMS("aux_ch native defer\n"); |
- | |
261 | udelay(400); |
- | |
262 | continue; |
212 | if (ret >= 0) |
263 | default: |
- | |
264 | DRM_ERROR("aux_ch invalid native reply 0x%02x\n", ack); |
- | |
- | 213 | msg->reply = ack >> 4; |
|
265 | return -EREMOTEIO; |
214 | |
266 | } |
- | |
267 | 215 | return ret; |
|
268 | switch (ack & AUX_I2C_REPLY_MASK) { |
- | |
269 | case AUX_I2C_REPLY_ACK: |
216 | } |
270 | if (mode == MODE_I2C_READ) |
- | |
271 | *read_byte = reply[0]; |
- | |
272 | return ret; |
- | |
Line 273... | Line 217... | ||
273 | case AUX_I2C_REPLY_NACK: |
217 | |
274 | DRM_DEBUG_KMS("aux_i2c nack\n"); |
- | |
275 | return -EREMOTEIO; |
218 | void radeon_dp_aux_init(struct radeon_connector *radeon_connector) |
Line 276... | Line 219... | ||
276 | case AUX_I2C_REPLY_DEFER: |
219 | { |
Line 277... | Line 220... | ||
277 | DRM_DEBUG_KMS("aux_i2c defer\n"); |
220 | int ret; |
Line 347... | Line 290... | ||
347 | return (link_rate * lane_num * 8) / bpp; |
290 | return (link_rate * lane_num * 8) / bpp; |
348 | } |
291 | } |
Line 349... | Line 292... | ||
349 | 292 | ||
Line -... | Line 293... | ||
- | 293 | /***** radeon specific DP functions *****/ |
|
- | 294 | ||
- | 295 | static int radeon_dp_get_max_link_rate(struct drm_connector *connector, |
|
- | 296 | u8 dpcd[DP_DPCD_SIZE]) |
|
- | 297 | { |
|
- | 298 | int max_link_rate; |
|
- | 299 | ||
- | 300 | if (radeon_connector_is_dp12_capable(connector)) |
|
- | 301 | max_link_rate = min(drm_dp_max_link_rate(dpcd), 540000); |
|
- | 302 | else |
|
- | 303 | max_link_rate = min(drm_dp_max_link_rate(dpcd), 270000); |
|
- | 304 | ||
- | 305 | return max_link_rate; |
|
350 | /***** radeon specific DP functions *****/ |
306 | } |
351 | 307 | ||
352 | /* First get the min lane# when low rate is used according to pixel clock |
308 | /* First get the min lane# when low rate is used according to pixel clock |
353 | * (prefer low rate), second check max lane# supported by DP panel, |
309 | * (prefer low rate), second check max lane# supported by DP panel, |
354 | * if the max lane# < low rate lane# then use max lane# instead. |
310 | * if the max lane# < low rate lane# then use max lane# instead. |
355 | */ |
311 | */ |
356 | static int radeon_dp_get_dp_lane_number(struct drm_connector *connector, |
312 | static int radeon_dp_get_dp_lane_number(struct drm_connector *connector, |
357 | u8 dpcd[DP_DPCD_SIZE], |
313 | u8 dpcd[DP_DPCD_SIZE], |
358 | int pix_clock) |
314 | int pix_clock) |
359 | { |
315 | { |
360 | int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector)); |
316 | int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector)); |
361 | int max_link_rate = drm_dp_max_link_rate(dpcd); |
317 | int max_link_rate = radeon_dp_get_max_link_rate(connector, dpcd); |
362 | int max_lane_num = drm_dp_max_lane_count(dpcd); |
318 | int max_lane_num = drm_dp_max_lane_count(dpcd); |
Line 363... | Line 319... | ||
363 | int lane_num; |
319 | int lane_num; |
Line 394... | Line 350... | ||
394 | max_pix_clock = dp_get_max_dp_pix_clock(540000, lane_num, bpp); |
350 | max_pix_clock = dp_get_max_dp_pix_clock(540000, lane_num, bpp); |
395 | if (pix_clock <= max_pix_clock) |
351 | if (pix_clock <= max_pix_clock) |
396 | return 540000; |
352 | return 540000; |
397 | } |
353 | } |
Line 398... | Line 354... | ||
398 | 354 | ||
399 | return drm_dp_max_link_rate(dpcd); |
355 | return radeon_dp_get_max_link_rate(connector, dpcd); |
Line 400... | Line 356... | ||
400 | } |
356 | } |
401 | 357 | ||
402 | static u8 radeon_dp_encoder_service(struct radeon_device *rdev, |
358 | static u8 radeon_dp_encoder_service(struct radeon_device *rdev, |
Line 417... | Line 373... | ||
417 | return args.ucStatus; |
373 | return args.ucStatus; |
418 | } |
374 | } |
Line 419... | Line 375... | ||
419 | 375 | ||
420 | u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector) |
376 | u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector) |
421 | { |
- | |
422 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; |
377 | { |
423 | struct drm_device *dev = radeon_connector->base.dev; |
378 | struct drm_device *dev = radeon_connector->base.dev; |
Line 424... | Line 379... | ||
424 | struct radeon_device *rdev = dev->dev_private; |
379 | struct radeon_device *rdev = dev->dev_private; |
425 | 380 | ||
426 | return radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_GET_SINK_TYPE, 0, |
381 | return radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_GET_SINK_TYPE, 0, |
Line 427... | Line 382... | ||
427 | dig_connector->dp_i2c_bus->rec.i2c_id, 0); |
382 | radeon_connector->ddc_bus->rec.i2c_id, 0); |
428 | } |
383 | } |
429 | 384 | ||
430 | static void radeon_dp_probe_oui(struct radeon_connector *radeon_connector) |
385 | static void radeon_dp_probe_oui(struct radeon_connector *radeon_connector) |
Line 431... | Line 386... | ||
431 | { |
386 | { |
432 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; |
387 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; |
Line 433... | Line 388... | ||
433 | u8 buf[3]; |
388 | u8 buf[3]; |
434 | 389 | ||
435 | if (!(dig_connector->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT)) |
390 | if (!(dig_connector->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT)) |
Line 436... | Line 391... | ||
436 | return; |
391 | return; |
437 | 392 | ||
438 | if (radeon_dp_aux_native_read(radeon_connector, DP_SINK_OUI, buf, 3, 0)) |
393 | if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_SINK_OUI, buf, 3) == 3) |
439 | DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n", |
394 | DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n", |
Line 440... | Line 395... | ||
440 | buf[0], buf[1], buf[2]); |
395 | buf[0], buf[1], buf[2]); |
441 | 396 | ||
442 | if (radeon_dp_aux_native_read(radeon_connector, DP_BRANCH_OUI, buf, 3, 0)) |
397 | if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_BRANCH_OUI, buf, 3) == 3) |
443 | DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n", |
398 | DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n", |
444 | buf[0], buf[1], buf[2]); |
399 | buf[0], buf[1], buf[2]); |
- | 400 | } |
|
- | 401 | ||
Line 445... | Line 402... | ||
445 | } |
402 | bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector) |
446 | 403 | { |
|
447 | bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector) |
404 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; |
448 | { |
405 | u8 msg[DP_DPCD_SIZE]; |
449 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; |
- | |
- | 406 | int ret; |
|
450 | u8 msg[DP_DPCD_SIZE]; |
407 | |
451 | int ret, i; |
408 | char dpcd_hex_dump[DP_DPCD_SIZE * 3]; |
452 | 409 | ||
Line 453... | Line 410... | ||
453 | ret = radeon_dp_aux_native_read(radeon_connector, DP_DPCD_REV, msg, |
410 | ret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_DPCD_REV, msg, |
Line 454... | Line 411... | ||
454 | DP_DPCD_SIZE, 0); |
411 | DP_DPCD_SIZE); |
455 | if (ret > 0) { |
412 | if (ret > 0) { |
Line 471... | Line 428... | ||
471 | struct drm_connector *connector) |
428 | struct drm_connector *connector) |
472 | { |
429 | { |
473 | struct drm_device *dev = encoder->dev; |
430 | struct drm_device *dev = encoder->dev; |
474 | struct radeon_device *rdev = dev->dev_private; |
431 | struct radeon_device *rdev = dev->dev_private; |
475 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
432 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
- | 433 | struct radeon_connector_atom_dig *dig_connector; |
|
476 | int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; |
434 | int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; |
477 | u16 dp_bridge = radeon_connector_encoder_get_dp_bridge_encoder_id(connector); |
435 | u16 dp_bridge = radeon_connector_encoder_get_dp_bridge_encoder_id(connector); |
478 | u8 tmp; |
436 | u8 tmp; |
Line 479... | Line 437... | ||
479 | 437 | ||
480 | if (!ASIC_IS_DCE4(rdev)) |
438 | if (!ASIC_IS_DCE4(rdev)) |
Line -... | Line 439... | ||
- | 439 | return panel_mode; |
|
- | 440 | ||
- | 441 | if (!radeon_connector->con_priv) |
|
- | 442 | return panel_mode; |
|
- | 443 | ||
481 | return panel_mode; |
444 | dig_connector = radeon_connector->con_priv; |
482 | 445 | ||
483 | if (dp_bridge != ENCODER_OBJECT_ID_NONE) { |
446 | if (dp_bridge != ENCODER_OBJECT_ID_NONE) { |
- | 447 | /* DP bridge chips */ |
|
484 | /* DP bridge chips */ |
448 | if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, |
485 | tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); |
449 | DP_EDP_CONFIGURATION_CAP, &tmp) == 1) { |
486 | if (tmp & 1) |
450 | if (tmp & 1) |
487 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; |
451 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; |
488 | else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) || |
452 | else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) || |
489 | (dp_bridge == ENCODER_OBJECT_ID_TRAVIS)) |
453 | (dp_bridge == ENCODER_OBJECT_ID_TRAVIS)) |
490 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; |
454 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; |
- | 455 | else |
|
491 | else |
456 | panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; |
492 | panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; |
457 | } |
493 | } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { |
458 | } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { |
- | 459 | /* eDP */ |
|
494 | /* eDP */ |
460 | if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, |
495 | tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); |
461 | DP_EDP_CONFIGURATION_CAP, &tmp) == 1) { |
496 | if (tmp & 1) |
462 | if (tmp & 1) |
- | 463 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; |
|
Line 497... | Line 464... | ||
497 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; |
464 | } |
498 | } |
465 | } |
Line 499... | Line 466... | ||
499 | 466 | ||
Line 538... | Line 505... | ||
538 | return MODE_CLOCK_HIGH; |
505 | return MODE_CLOCK_HIGH; |
Line 539... | Line 506... | ||
539 | 506 | ||
540 | return MODE_OK; |
507 | return MODE_OK; |
Line 541... | Line -... | ||
541 | } |
- | |
542 | - | ||
543 | static bool radeon_dp_get_link_status(struct radeon_connector *radeon_connector, |
- | |
544 | u8 link_status[DP_LINK_STATUS_SIZE]) |
- | |
545 | { |
- | |
546 | int ret; |
- | |
547 | ret = radeon_dp_aux_native_read(radeon_connector, DP_LANE0_1_STATUS, |
- | |
548 | link_status, DP_LINK_STATUS_SIZE, 100); |
- | |
549 | if (ret <= 0) { |
- | |
550 | return false; |
- | |
551 | } |
- | |
552 | - | ||
553 | DRM_DEBUG_KMS("link status %*ph\n", 6, link_status); |
- | |
554 | return true; |
- | |
555 | } |
508 | } |
556 | 509 | ||
557 | bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector) |
510 | bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector) |
558 | { |
511 | { |
Line 559... | Line 512... | ||
559 | u8 link_status[DP_LINK_STATUS_SIZE]; |
512 | u8 link_status[DP_LINK_STATUS_SIZE]; |
- | 513 | struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; |
|
560 | struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; |
514 | |
561 | 515 | if (drm_dp_dpcd_read_link_status(&radeon_connector->ddc_bus->aux, link_status) |
|
562 | if (!radeon_dp_get_link_status(radeon_connector, link_status)) |
516 | <= 0) |
563 | return false; |
517 | return false; |
564 | if (drm_dp_channel_eq_ok(link_status, dig->dp_lane_count)) |
518 | if (drm_dp_channel_eq_ok(link_status, dig->dp_lane_count)) |
Line -... | Line 519... | ||
- | 519 | return false; |
|
- | 520 | return true; |
|
- | 521 | } |
|
- | 522 | ||
- | 523 | void radeon_dp_set_rx_power_state(struct drm_connector *connector, |
|
- | 524 | u8 power_state) |
|
- | 525 | { |
|
- | 526 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
|
- | 527 | struct radeon_connector_atom_dig *dig_connector; |
|
- | 528 | ||
- | 529 | if (!radeon_connector->con_priv) |
|
- | 530 | return; |
|
- | 531 | ||
- | 532 | dig_connector = radeon_connector->con_priv; |
|
- | 533 | ||
- | 534 | /* power up/down the sink */ |
|
- | 535 | if (dig_connector->dpcd[0] >= 0x11) { |
|
- | 536 | drm_dp_dpcd_writeb(&radeon_connector->ddc_bus->aux, |
|
- | 537 | DP_SET_POWER, power_state); |
|
- | 538 | usleep_range(1000, 2000); |
|
565 | return false; |
539 | } |
566 | return true; |
540 | } |
567 | } |
541 | |
568 | 542 | ||
569 | struct radeon_dp_link_train_info { |
- | |
570 | struct radeon_device *rdev; |
543 | struct radeon_dp_link_train_info { |
571 | struct drm_encoder *encoder; |
544 | struct radeon_device *rdev; |
572 | struct drm_connector *connector; |
545 | struct drm_encoder *encoder; |
573 | struct radeon_connector *radeon_connector; |
546 | struct drm_connector *connector; |
574 | int enc_id; |
547 | int enc_id; |
575 | int dp_clock; |
548 | int dp_clock; |
576 | int dp_lane_count; |
549 | int dp_lane_count; |
577 | bool tp3_supported; |
550 | bool tp3_supported; |
578 | u8 dpcd[DP_RECEIVER_CAP_SIZE]; |
551 | u8 dpcd[DP_RECEIVER_CAP_SIZE]; |
- | 552 | u8 train_set[4]; |
|
579 | u8 train_set[4]; |
553 | u8 link_status[DP_LINK_STATUS_SIZE]; |
Line 580... | Line 554... | ||
580 | u8 link_status[DP_LINK_STATUS_SIZE]; |
554 | u8 tries; |
581 | u8 tries; |
555 | bool use_dpencoder; |
582 | bool use_dpencoder; |
556 | struct drm_dp_aux *aux; |
583 | }; |
557 | }; |
584 | 558 | ||
585 | static void radeon_dp_update_vs_emph(struct radeon_dp_link_train_info *dp_info) |
559 | static void radeon_dp_update_vs_emph(struct radeon_dp_link_train_info *dp_info) |
Line 586... | Line 560... | ||
586 | { |
560 | { |
587 | /* set the initial vs/emph on the source */ |
561 | /* set the initial vs/emph on the source */ |
588 | atombios_dig_transmitter_setup(dp_info->encoder, |
562 | atombios_dig_transmitter_setup(dp_info->encoder, |
589 | ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH, |
563 | ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH, |
Line 590... | Line 564... | ||
590 | 0, dp_info->train_set[0]); /* sets all lanes at once */ |
564 | 0, dp_info->train_set[0]); /* sets all lanes at once */ |
591 | 565 | ||
592 | /* set the vs/emph on the sink */ |
566 | /* set the vs/emph on the sink */ |
Line 624... | Line 598... | ||
624 | radeon_dp_encoder_service(dp_info->rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL, |
598 | radeon_dp_encoder_service(dp_info->rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL, |
625 | dp_info->dp_clock, dp_info->enc_id, rtp); |
599 | dp_info->dp_clock, dp_info->enc_id, rtp); |
626 | } |
600 | } |
Line 627... | Line 601... | ||
627 | 601 | ||
628 | /* enable training pattern on the sink */ |
602 | /* enable training pattern on the sink */ |
629 | radeon_write_dpcd_reg(dp_info->radeon_connector, DP_TRAINING_PATTERN_SET, tp); |
603 | drm_dp_dpcd_writeb(dp_info->aux, DP_TRAINING_PATTERN_SET, tp); |
Line 630... | Line 604... | ||
630 | } |
604 | } |
631 | 605 | ||
632 | static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info) |
606 | static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info) |
633 | { |
607 | { |
634 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(dp_info->encoder); |
608 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(dp_info->encoder); |
Line 635... | Line 609... | ||
635 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
609 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
636 | u8 tmp; |
- | |
637 | 610 | u8 tmp; |
|
638 | /* power up the sink */ |
- | |
Line 639... | Line 611... | ||
639 | if (dp_info->dpcd[0] >= 0x11) |
611 | |
640 | radeon_write_dpcd_reg(dp_info->radeon_connector, |
612 | /* power up the sink */ |
641 | DP_SET_POWER, DP_SET_POWER_D0); |
613 | radeon_dp_set_rx_power_state(dp_info->connector, DP_SET_POWER_D0); |
642 | 614 | ||
643 | /* possibly enable downspread on the sink */ |
615 | /* possibly enable downspread on the sink */ |
644 | if (dp_info->dpcd[3] & 0x1) |
616 | if (dp_info->dpcd[3] & 0x1) |
645 | radeon_write_dpcd_reg(dp_info->radeon_connector, |
617 | drm_dp_dpcd_writeb(dp_info->aux, |
Line 646... | Line 618... | ||
646 | DP_DOWNSPREAD_CTRL, DP_SPREAD_AMP_0_5); |
618 | DP_DOWNSPREAD_CTRL, DP_SPREAD_AMP_0_5); |
647 | else |
619 | else |
648 | radeon_write_dpcd_reg(dp_info->radeon_connector, |
620 | drm_dp_dpcd_writeb(dp_info->aux, |
649 | DP_DOWNSPREAD_CTRL, 0); |
621 | DP_DOWNSPREAD_CTRL, 0); |
Line 650... | Line 622... | ||
650 | 622 | ||
651 | if ((dp_info->connector->connector_type == DRM_MODE_CONNECTOR_eDP) && |
623 | if ((dp_info->connector->connector_type == DRM_MODE_CONNECTOR_eDP) && |
652 | (dig->panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)) { |
624 | (dig->panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)) { |
653 | radeon_write_dpcd_reg(dp_info->radeon_connector, DP_EDP_CONFIGURATION_SET, 1); |
- | |
654 | } |
625 | drm_dp_dpcd_writeb(dp_info->aux, DP_EDP_CONFIGURATION_SET, 1); |
655 | 626 | } |
|
Line 656... | Line 627... | ||
656 | /* set the lane count on the sink */ |
627 | |
657 | tmp = dp_info->dp_lane_count; |
628 | /* set the lane count on the sink */ |
658 | if (dp_info->dpcd[DP_DPCD_REV] >= 0x11 && |
629 | tmp = dp_info->dp_lane_count; |
Line 659... | Line 630... | ||
659 | dp_info->dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP) |
630 | if (drm_dp_enhanced_frame_cap(dp_info->dpcd)) |
660 | tmp |= DP_LANE_COUNT_ENHANCED_FRAME_EN; |
631 | tmp |= DP_LANE_COUNT_ENHANCED_FRAME_EN; |
661 | radeon_write_dpcd_reg(dp_info->radeon_connector, DP_LANE_COUNT_SET, tmp); |
632 | drm_dp_dpcd_writeb(dp_info->aux, DP_LANE_COUNT_SET, tmp); |
662 | 633 | ||
663 | /* set the link rate on the sink */ |
634 | /* set the link rate on the sink */ |
664 | tmp = drm_dp_link_rate_to_bw_code(dp_info->dp_clock); |
635 | tmp = drm_dp_link_rate_to_bw_code(dp_info->dp_clock); |
665 | radeon_write_dpcd_reg(dp_info->radeon_connector, DP_LINK_BW_SET, tmp); |
636 | drm_dp_dpcd_writeb(dp_info->aux, DP_LINK_BW_SET, tmp); |
Line 666... | Line 637... | ||
666 | 637 | ||
667 | /* start training on the source */ |
638 | /* start training on the source */ |
668 | if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) |
639 | if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) |
669 | atombios_dig_encoder_setup(dp_info->encoder, |
640 | atombios_dig_encoder_setup(dp_info->encoder, |
Line 670... | Line 641... | ||
670 | ATOM_ENCODER_CMD_DP_LINK_TRAINING_START, 0); |
641 | ATOM_ENCODER_CMD_DP_LINK_TRAINING_START, 0); |
671 | else |
642 | else |
Line 683... | Line 654... | ||
683 | static int radeon_dp_link_train_finish(struct radeon_dp_link_train_info *dp_info) |
654 | static int radeon_dp_link_train_finish(struct radeon_dp_link_train_info *dp_info) |
684 | { |
655 | { |
685 | udelay(400); |
656 | udelay(400); |
Line 686... | Line 657... | ||
686 | 657 | ||
687 | /* disable the training pattern on the sink */ |
658 | /* disable the training pattern on the sink */ |
688 | radeon_write_dpcd_reg(dp_info->radeon_connector, |
659 | drm_dp_dpcd_writeb(dp_info->aux, |
689 | DP_TRAINING_PATTERN_SET, |
660 | DP_TRAINING_PATTERN_SET, |
Line 690... | Line 661... | ||
690 | DP_TRAINING_PATTERN_DISABLE); |
661 | DP_TRAINING_PATTERN_DISABLE); |
691 | 662 | ||
Line 717... | Line 688... | ||
717 | dp_info->tries = 0; |
688 | dp_info->tries = 0; |
718 | voltage = 0xff; |
689 | voltage = 0xff; |
719 | while (1) { |
690 | while (1) { |
720 | drm_dp_link_train_clock_recovery_delay(dp_info->dpcd); |
691 | drm_dp_link_train_clock_recovery_delay(dp_info->dpcd); |
Line 721... | Line 692... | ||
721 | 692 | ||
- | 693 | if (drm_dp_dpcd_read_link_status(dp_info->aux, |
|
722 | if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) { |
694 | dp_info->link_status) <= 0) { |
723 | DRM_ERROR("displayport link status failed\n"); |
695 | DRM_ERROR("displayport link status failed\n"); |
724 | break; |
696 | break; |
Line 725... | Line 697... | ||
725 | } |
697 | } |
Line 779... | Line 751... | ||
779 | dp_info->tries = 0; |
751 | dp_info->tries = 0; |
780 | channel_eq = false; |
752 | channel_eq = false; |
781 | while (1) { |
753 | while (1) { |
782 | drm_dp_link_train_channel_eq_delay(dp_info->dpcd); |
754 | drm_dp_link_train_channel_eq_delay(dp_info->dpcd); |
Line 783... | Line 755... | ||
783 | 755 | ||
- | 756 | if (drm_dp_dpcd_read_link_status(dp_info->aux, |
|
784 | if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) { |
757 | dp_info->link_status) <= 0) { |
785 | DRM_ERROR("displayport link status failed\n"); |
758 | DRM_ERROR("displayport link status failed\n"); |
786 | break; |
759 | break; |
Line 787... | Line 760... | ||
787 | } |
760 | } |
Line 862... | Line 835... | ||
862 | if (dig->linkb) |
835 | if (dig->linkb) |
863 | dp_info.enc_id |= ATOM_DP_CONFIG_LINK_B; |
836 | dp_info.enc_id |= ATOM_DP_CONFIG_LINK_B; |
864 | else |
837 | else |
865 | dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A; |
838 | dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A; |
Line 866... | Line 839... | ||
866 | 839 | ||
- | 840 | if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, DP_MAX_LANE_COUNT, &tmp) |
|
867 | tmp = radeon_read_dpcd_reg(radeon_connector, DP_MAX_LANE_COUNT); |
841 | == 1) { |
868 | if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED)) |
842 | if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED)) |
869 | dp_info.tp3_supported = true; |
843 | dp_info.tp3_supported = true; |
870 | else |
844 | else |
- | 845 | dp_info.tp3_supported = false; |
|
- | 846 | } else { |
|
- | 847 | dp_info.tp3_supported = false; |
|
Line 871... | Line 848... | ||
871 | dp_info.tp3_supported = false; |
848 | } |
872 | 849 | ||
873 | memcpy(dp_info.dpcd, dig_connector->dpcd, DP_RECEIVER_CAP_SIZE); |
850 | memcpy(dp_info.dpcd, dig_connector->dpcd, DP_RECEIVER_CAP_SIZE); |
874 | dp_info.rdev = rdev; |
851 | dp_info.rdev = rdev; |
875 | dp_info.encoder = encoder; |
- | |
876 | dp_info.connector = connector; |
852 | dp_info.encoder = encoder; |
877 | dp_info.radeon_connector = radeon_connector; |
853 | dp_info.connector = connector; |
- | 854 | dp_info.dp_lane_count = dig_connector->dp_lane_count; |
|
Line 878... | Line 855... | ||
878 | dp_info.dp_lane_count = dig_connector->dp_lane_count; |
855 | dp_info.dp_clock = dig_connector->dp_clock; |
879 | dp_info.dp_clock = dig_connector->dp_clock; |
856 | dp_info.aux = &radeon_connector->ddc_bus->aux; |
880 | 857 | ||
881 | if (radeon_dp_link_train_init(&dp_info)) |
858 | if (radeon_dp_link_train_init(&dp_info)) |