diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/atombios_dp.c')
-rw-r--r-- | drivers/gpu/drm/radeon/atombios_dp.c | 175 |
1 files changed, 56 insertions, 119 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 8b0ab170cef9..54e4f52549af 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
@@ -142,7 +142,8 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan, | |||
142 | return recv_bytes; | 142 | return recv_bytes; |
143 | } | 143 | } |
144 | 144 | ||
145 | #define HEADER_SIZE 4 | 145 | #define BARE_ADDRESS_SIZE 3 |
146 | #define HEADER_SIZE (BARE_ADDRESS_SIZE + 1) | ||
146 | 147 | ||
147 | static ssize_t | 148 | static ssize_t |
148 | radeon_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) | 149 | radeon_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) |
@@ -160,13 +161,19 @@ radeon_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) | |||
160 | tx_buf[0] = msg->address & 0xff; | 161 | tx_buf[0] = msg->address & 0xff; |
161 | tx_buf[1] = msg->address >> 8; | 162 | tx_buf[1] = msg->address >> 8; |
162 | tx_buf[2] = msg->request << 4; | 163 | tx_buf[2] = msg->request << 4; |
163 | tx_buf[3] = msg->size - 1; | 164 | tx_buf[3] = msg->size ? (msg->size - 1) : 0; |
164 | 165 | ||
165 | switch (msg->request & ~DP_AUX_I2C_MOT) { | 166 | switch (msg->request & ~DP_AUX_I2C_MOT) { |
166 | case DP_AUX_NATIVE_WRITE: | 167 | case DP_AUX_NATIVE_WRITE: |
167 | case DP_AUX_I2C_WRITE: | 168 | case DP_AUX_I2C_WRITE: |
169 | /* tx_size needs to be 4 even for bare address packets since the atom | ||
170 | * table needs the info in tx_buf[3]. | ||
171 | */ | ||
168 | tx_size = HEADER_SIZE + msg->size; | 172 | tx_size = HEADER_SIZE + msg->size; |
169 | tx_buf[3] |= tx_size << 4; | 173 | if (msg->size == 0) |
174 | tx_buf[3] |= BARE_ADDRESS_SIZE << 4; | ||
175 | else | ||
176 | tx_buf[3] |= tx_size << 4; | ||
170 | memcpy(tx_buf + HEADER_SIZE, msg->buffer, msg->size); | 177 | memcpy(tx_buf + HEADER_SIZE, msg->buffer, msg->size); |
171 | ret = radeon_process_aux_ch(chan, | 178 | ret = radeon_process_aux_ch(chan, |
172 | tx_buf, tx_size, NULL, 0, delay, &ack); | 179 | tx_buf, tx_size, NULL, 0, delay, &ack); |
@@ -176,8 +183,14 @@ radeon_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) | |||
176 | break; | 183 | break; |
177 | case DP_AUX_NATIVE_READ: | 184 | case DP_AUX_NATIVE_READ: |
178 | case DP_AUX_I2C_READ: | 185 | case DP_AUX_I2C_READ: |
186 | /* tx_size needs to be 4 even for bare address packets since the atom | ||
187 | * table needs the info in tx_buf[3]. | ||
188 | */ | ||
179 | tx_size = HEADER_SIZE; | 189 | tx_size = HEADER_SIZE; |
180 | tx_buf[3] |= tx_size << 4; | 190 | if (msg->size == 0) |
191 | tx_buf[3] |= BARE_ADDRESS_SIZE << 4; | ||
192 | else | ||
193 | tx_buf[3] |= tx_size << 4; | ||
181 | ret = radeon_process_aux_ch(chan, | 194 | ret = radeon_process_aux_ch(chan, |
182 | tx_buf, tx_size, msg->buffer, msg->size, delay, &ack); | 195 | tx_buf, tx_size, msg->buffer, msg->size, delay, &ack); |
183 | break; | 196 | break; |
@@ -186,7 +199,7 @@ radeon_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) | |||
186 | break; | 199 | break; |
187 | } | 200 | } |
188 | 201 | ||
189 | if (ret > 0) | 202 | if (ret >= 0) |
190 | msg->reply = ack >> 4; | 203 | msg->reply = ack >> 4; |
191 | 204 | ||
192 | return ret; | 205 | return ret; |
@@ -194,98 +207,16 @@ radeon_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) | |||
194 | 207 | ||
195 | void radeon_dp_aux_init(struct radeon_connector *radeon_connector) | 208 | void radeon_dp_aux_init(struct radeon_connector *radeon_connector) |
196 | { | 209 | { |
197 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; | ||
198 | |||
199 | dig_connector->dp_i2c_bus->aux.dev = radeon_connector->base.kdev; | ||
200 | dig_connector->dp_i2c_bus->aux.transfer = radeon_dp_aux_transfer; | ||
201 | } | ||
202 | |||
203 | int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | ||
204 | u8 write_byte, u8 *read_byte) | ||
205 | { | ||
206 | struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; | ||
207 | struct radeon_i2c_chan *auxch = i2c_get_adapdata(adapter); | ||
208 | u16 address = algo_data->address; | ||
209 | u8 msg[5]; | ||
210 | u8 reply[2]; | ||
211 | unsigned retry; | ||
212 | int msg_bytes; | ||
213 | int reply_bytes = 1; | ||
214 | int ret; | 210 | int ret; |
215 | u8 ack; | ||
216 | 211 | ||
217 | /* Set up the address */ | 212 | radeon_connector->ddc_bus->rec.hpd = radeon_connector->hpd.hpd; |
218 | msg[0] = address; | 213 | radeon_connector->ddc_bus->aux.dev = radeon_connector->base.kdev; |
219 | msg[1] = address >> 8; | 214 | radeon_connector->ddc_bus->aux.transfer = radeon_dp_aux_transfer; |
215 | ret = drm_dp_aux_register_i2c_bus(&radeon_connector->ddc_bus->aux); | ||
216 | if (!ret) | ||
217 | radeon_connector->ddc_bus->has_aux = true; | ||
220 | 218 | ||
221 | /* Set up the command byte */ | 219 | WARN(ret, "drm_dp_aux_register_i2c_bus() failed with error %d\n", ret); |
222 | if (mode & MODE_I2C_READ) { | ||
223 | msg[2] = DP_AUX_I2C_READ << 4; | ||
224 | msg_bytes = 4; | ||
225 | msg[3] = msg_bytes << 4; | ||
226 | } else { | ||
227 | msg[2] = DP_AUX_I2C_WRITE << 4; | ||
228 | msg_bytes = 5; | ||
229 | msg[3] = msg_bytes << 4; | ||
230 | msg[4] = write_byte; | ||
231 | } | ||
232 | |||
233 | /* special handling for start/stop */ | ||
234 | if (mode & (MODE_I2C_START | MODE_I2C_STOP)) | ||
235 | msg[3] = 3 << 4; | ||
236 | |||
237 | /* Set MOT bit for all but stop */ | ||
238 | if ((mode & MODE_I2C_STOP) == 0) | ||
239 | msg[2] |= DP_AUX_I2C_MOT << 4; | ||
240 | |||
241 | for (retry = 0; retry < 7; retry++) { | ||
242 | ret = radeon_process_aux_ch(auxch, | ||
243 | msg, msg_bytes, reply, reply_bytes, 0, &ack); | ||
244 | if (ret == -EBUSY) | ||
245 | continue; | ||
246 | else if (ret < 0) { | ||
247 | DRM_DEBUG_KMS("aux_ch failed %d\n", ret); | ||
248 | return ret; | ||
249 | } | ||
250 | |||
251 | switch ((ack >> 4) & DP_AUX_NATIVE_REPLY_MASK) { | ||
252 | case DP_AUX_NATIVE_REPLY_ACK: | ||
253 | /* I2C-over-AUX Reply field is only valid | ||
254 | * when paired with AUX ACK. | ||
255 | */ | ||
256 | break; | ||
257 | case DP_AUX_NATIVE_REPLY_NACK: | ||
258 | DRM_DEBUG_KMS("aux_ch native nack\n"); | ||
259 | return -EREMOTEIO; | ||
260 | case DP_AUX_NATIVE_REPLY_DEFER: | ||
261 | DRM_DEBUG_KMS("aux_ch native defer\n"); | ||
262 | usleep_range(500, 600); | ||
263 | continue; | ||
264 | default: | ||
265 | DRM_ERROR("aux_ch invalid native reply 0x%02x\n", ack); | ||
266 | return -EREMOTEIO; | ||
267 | } | ||
268 | |||
269 | switch ((ack >> 4) & DP_AUX_I2C_REPLY_MASK) { | ||
270 | case DP_AUX_I2C_REPLY_ACK: | ||
271 | if (mode == MODE_I2C_READ) | ||
272 | *read_byte = reply[0]; | ||
273 | return ret; | ||
274 | case DP_AUX_I2C_REPLY_NACK: | ||
275 | DRM_DEBUG_KMS("aux_i2c nack\n"); | ||
276 | return -EREMOTEIO; | ||
277 | case DP_AUX_I2C_REPLY_DEFER: | ||
278 | DRM_DEBUG_KMS("aux_i2c defer\n"); | ||
279 | usleep_range(400, 500); | ||
280 | break; | ||
281 | default: | ||
282 | DRM_ERROR("aux_i2c invalid reply 0x%02x\n", ack); | ||
283 | return -EREMOTEIO; | ||
284 | } | ||
285 | } | ||
286 | |||
287 | DRM_DEBUG_KMS("aux i2c too many retries, giving up\n"); | ||
288 | return -EREMOTEIO; | ||
289 | } | 220 | } |
290 | 221 | ||
291 | /***** general DP utility functions *****/ | 222 | /***** general DP utility functions *****/ |
@@ -420,12 +351,11 @@ static u8 radeon_dp_encoder_service(struct radeon_device *rdev, | |||
420 | 351 | ||
421 | u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector) | 352 | u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector) |
422 | { | 353 | { |
423 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; | ||
424 | struct drm_device *dev = radeon_connector->base.dev; | 354 | struct drm_device *dev = radeon_connector->base.dev; |
425 | struct radeon_device *rdev = dev->dev_private; | 355 | struct radeon_device *rdev = dev->dev_private; |
426 | 356 | ||
427 | return radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_GET_SINK_TYPE, 0, | 357 | return radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_GET_SINK_TYPE, 0, |
428 | dig_connector->dp_i2c_bus->rec.i2c_id, 0); | 358 | radeon_connector->ddc_bus->rec.i2c_id, 0); |
429 | } | 359 | } |
430 | 360 | ||
431 | static void radeon_dp_probe_oui(struct radeon_connector *radeon_connector) | 361 | static void radeon_dp_probe_oui(struct radeon_connector *radeon_connector) |
@@ -436,11 +366,11 @@ static void radeon_dp_probe_oui(struct radeon_connector *radeon_connector) | |||
436 | if (!(dig_connector->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT)) | 366 | if (!(dig_connector->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT)) |
437 | return; | 367 | return; |
438 | 368 | ||
439 | if (drm_dp_dpcd_read(&dig_connector->dp_i2c_bus->aux, DP_SINK_OUI, buf, 3)) | 369 | if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_SINK_OUI, buf, 3) == 3) |
440 | DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n", | 370 | DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n", |
441 | buf[0], buf[1], buf[2]); | 371 | buf[0], buf[1], buf[2]); |
442 | 372 | ||
443 | if (drm_dp_dpcd_read(&dig_connector->dp_i2c_bus->aux, DP_BRANCH_OUI, buf, 3)) | 373 | if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_BRANCH_OUI, buf, 3) == 3) |
444 | DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n", | 374 | DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n", |
445 | buf[0], buf[1], buf[2]); | 375 | buf[0], buf[1], buf[2]); |
446 | } | 376 | } |
@@ -451,7 +381,7 @@ bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector) | |||
451 | u8 msg[DP_DPCD_SIZE]; | 381 | u8 msg[DP_DPCD_SIZE]; |
452 | int ret, i; | 382 | int ret, i; |
453 | 383 | ||
454 | ret = drm_dp_dpcd_read(&dig_connector->dp_i2c_bus->aux, DP_DPCD_REV, msg, | 384 | ret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_DPCD_REV, msg, |
455 | DP_DPCD_SIZE); | 385 | DP_DPCD_SIZE); |
456 | if (ret > 0) { | 386 | if (ret > 0) { |
457 | memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE); | 387 | memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE); |
@@ -489,21 +419,23 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder, | |||
489 | 419 | ||
490 | if (dp_bridge != ENCODER_OBJECT_ID_NONE) { | 420 | if (dp_bridge != ENCODER_OBJECT_ID_NONE) { |
491 | /* DP bridge chips */ | 421 | /* DP bridge chips */ |
492 | drm_dp_dpcd_readb(&dig_connector->dp_i2c_bus->aux, | 422 | if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, |
493 | DP_EDP_CONFIGURATION_CAP, &tmp); | 423 | DP_EDP_CONFIGURATION_CAP, &tmp) == 1) { |
494 | if (tmp & 1) | 424 | if (tmp & 1) |
495 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; | 425 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; |
496 | else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) || | 426 | else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) || |
497 | (dp_bridge == ENCODER_OBJECT_ID_TRAVIS)) | 427 | (dp_bridge == ENCODER_OBJECT_ID_TRAVIS)) |
498 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; | 428 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; |
499 | else | 429 | else |
500 | panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; | 430 | panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; |
431 | } | ||
501 | } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { | 432 | } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { |
502 | /* eDP */ | 433 | /* eDP */ |
503 | drm_dp_dpcd_readb(&dig_connector->dp_i2c_bus->aux, | 434 | if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, |
504 | DP_EDP_CONFIGURATION_CAP, &tmp); | 435 | DP_EDP_CONFIGURATION_CAP, &tmp) == 1) { |
505 | if (tmp & 1) | 436 | if (tmp & 1) |
506 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; | 437 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; |
438 | } | ||
507 | } | 439 | } |
508 | 440 | ||
509 | return panel_mode; | 441 | return panel_mode; |
@@ -554,7 +486,8 @@ bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector) | |||
554 | u8 link_status[DP_LINK_STATUS_SIZE]; | 486 | u8 link_status[DP_LINK_STATUS_SIZE]; |
555 | struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; | 487 | struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; |
556 | 488 | ||
557 | if (drm_dp_dpcd_read_link_status(&dig->dp_i2c_bus->aux, link_status) <= 0) | 489 | if (drm_dp_dpcd_read_link_status(&radeon_connector->ddc_bus->aux, link_status) |
490 | <= 0) | ||
558 | return false; | 491 | return false; |
559 | if (drm_dp_channel_eq_ok(link_status, dig->dp_lane_count)) | 492 | if (drm_dp_channel_eq_ok(link_status, dig->dp_lane_count)) |
560 | return false; | 493 | return false; |
@@ -574,7 +507,7 @@ void radeon_dp_set_rx_power_state(struct drm_connector *connector, | |||
574 | 507 | ||
575 | /* power up/down the sink */ | 508 | /* power up/down the sink */ |
576 | if (dig_connector->dpcd[0] >= 0x11) { | 509 | if (dig_connector->dpcd[0] >= 0x11) { |
577 | drm_dp_dpcd_writeb(&dig_connector->dp_i2c_bus->aux, | 510 | drm_dp_dpcd_writeb(&radeon_connector->ddc_bus->aux, |
578 | DP_SET_POWER, power_state); | 511 | DP_SET_POWER, power_state); |
579 | usleep_range(1000, 2000); | 512 | usleep_range(1000, 2000); |
580 | } | 513 | } |
@@ -878,11 +811,15 @@ void radeon_dp_link_train(struct drm_encoder *encoder, | |||
878 | else | 811 | else |
879 | dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A; | 812 | dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A; |
880 | 813 | ||
881 | drm_dp_dpcd_readb(&dig_connector->dp_i2c_bus->aux, DP_MAX_LANE_COUNT, &tmp); | 814 | if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, DP_MAX_LANE_COUNT, &tmp) |
882 | if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED)) | 815 | == 1) { |
883 | dp_info.tp3_supported = true; | 816 | if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED)) |
884 | else | 817 | dp_info.tp3_supported = true; |
818 | else | ||
819 | dp_info.tp3_supported = false; | ||
820 | } else { | ||
885 | dp_info.tp3_supported = false; | 821 | dp_info.tp3_supported = false; |
822 | } | ||
886 | 823 | ||
887 | memcpy(dp_info.dpcd, dig_connector->dpcd, DP_RECEIVER_CAP_SIZE); | 824 | memcpy(dp_info.dpcd, dig_connector->dpcd, DP_RECEIVER_CAP_SIZE); |
888 | dp_info.rdev = rdev; | 825 | dp_info.rdev = rdev; |
@@ -890,7 +827,7 @@ void radeon_dp_link_train(struct drm_encoder *encoder, | |||
890 | dp_info.connector = connector; | 827 | dp_info.connector = connector; |
891 | dp_info.dp_lane_count = dig_connector->dp_lane_count; | 828 | dp_info.dp_lane_count = dig_connector->dp_lane_count; |
892 | dp_info.dp_clock = dig_connector->dp_clock; | 829 | dp_info.dp_clock = dig_connector->dp_clock; |
893 | dp_info.aux = &dig_connector->dp_i2c_bus->aux; | 830 | dp_info.aux = &radeon_connector->ddc_bus->aux; |
894 | 831 | ||
895 | if (radeon_dp_link_train_init(&dp_info)) | 832 | if (radeon_dp_link_train_init(&dp_info)) |
896 | goto done; | 833 | goto done; |