2 * Copyright 2012-15 Advanced Micro Devices, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
26 #include <linux/delay.h>
27 #include <linux/slab.h>
29 #include "dm_services.h"
30 #include "core_types.h"
32 #include "dce/dce_11_0_sh_mask.h"
33 #include "dm_event_log.h"
37 #define REG(reg_name)\
38 (aux110->regs->reg_name)
43 #include "reg_helper.h"
46 #define FN(reg_name, field_name) \
47 aux110->shift->field_name, aux110->mask->field_name
49 #define FROM_AUX_ENGINE(ptr) \
50 container_of((ptr), struct aux_engine_dce110, base)
52 #define FROM_ENGINE(ptr) \
53 FROM_AUX_ENGINE(container_of((ptr), struct dce_aux, base))
55 #define FROM_AUX_ENGINE_ENGINE(ptr) \
56 container_of((ptr), struct dce_aux, base)
58 AUX_INVALID_REPLY_RETRY_COUNTER = 1,
59 AUX_TIMED_OUT_RETRY_COUNTER = 2,
60 AUX_DEFER_RETRY_COUNTER = 6
63 #define TIME_OUT_INCREMENT 1016
64 #define TIME_OUT_MULTIPLIER_8 8
65 #define TIME_OUT_MULTIPLIER_16 16
66 #define TIME_OUT_MULTIPLIER_32 32
67 #define TIME_OUT_MULTIPLIER_64 64
68 #define MAX_TIMEOUT_LENGTH 127
70 static void release_engine(
71 struct dce_aux *engine)
73 struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine);
75 dal_ddc_close(engine->ddc);
79 REG_UPDATE(AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, 1);
82 #define SW_CAN_ACCESS_AUX 1
83 #define DMCU_CAN_ACCESS_AUX 2
85 static bool is_engine_available(
86 struct dce_aux *engine)
88 struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine);
90 uint32_t value = REG_READ(AUX_ARB_CONTROL);
91 uint32_t field = get_reg_field_value(
94 AUX_REG_RW_CNTL_STATUS);
96 return (field != DMCU_CAN_ACCESS_AUX);
98 static bool acquire_engine(
99 struct dce_aux *engine)
101 struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine);
103 uint32_t value = REG_READ(AUX_ARB_CONTROL);
104 uint32_t field = get_reg_field_value(
107 AUX_REG_RW_CNTL_STATUS);
108 if (field == DMCU_CAN_ACCESS_AUX)
110 /* enable AUX before request SW to access AUX */
111 value = REG_READ(AUX_CONTROL);
112 field = get_reg_field_value(value,
123 if (REG(AUX_RESET_MASK)) {
124 /*DP_AUX block as part of the enable sequence*/
132 REG_WRITE(AUX_CONTROL, value);
134 if (REG(AUX_RESET_MASK)) {
135 /*poll HW to make sure reset it done*/
137 REG_WAIT(AUX_CONTROL, AUX_RESET_DONE, 1,
146 REG_WRITE(AUX_CONTROL, value);
148 REG_WAIT(AUX_CONTROL, AUX_RESET_DONE, 0,
153 /* request SW to access AUX */
154 REG_UPDATE(AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, 1);
156 value = REG_READ(AUX_ARB_CONTROL);
157 field = get_reg_field_value(
160 AUX_REG_RW_CNTL_STATUS);
162 return (field == SW_CAN_ACCESS_AUX);
165 #define COMPOSE_AUX_SW_DATA_16_20(command, address) \
166 ((command) | ((0xF0000 & (address)) >> 16))
168 #define COMPOSE_AUX_SW_DATA_8_15(address) \
169 ((0xFF00 & (address)) >> 8)
171 #define COMPOSE_AUX_SW_DATA_0_7(address) \
174 static void submit_channel_request(
175 struct dce_aux *engine,
176 struct aux_request_transaction_data *request)
178 struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine);
183 ((request->type == AUX_TRANSACTION_TYPE_DP) &&
184 (request->action == I2CAUX_TRANSACTION_ACTION_DP_WRITE)) ||
185 ((request->type == AUX_TRANSACTION_TYPE_I2C) &&
186 ((request->action == I2CAUX_TRANSACTION_ACTION_I2C_WRITE) ||
187 (request->action == I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT)));
188 if (REG(AUXN_IMPCAL)) {
189 /* clear_aux_error */
190 REG_UPDATE_SEQ_2(AUXN_IMPCAL,
191 AUXN_CALOUT_ERROR_AK, 1,
192 AUXN_CALOUT_ERROR_AK, 0);
194 REG_UPDATE_SEQ_2(AUXP_IMPCAL,
195 AUXP_CALOUT_ERROR_AK, 1,
196 AUXP_CALOUT_ERROR_AK, 0);
198 /* force_default_calibrate */
199 REG_UPDATE_SEQ_2(AUXN_IMPCAL,
200 AUXN_IMPCAL_ENABLE, 1,
201 AUXN_IMPCAL_OVERRIDE_ENABLE, 0);
203 /* bug? why AUXN update EN and OVERRIDE_EN 1 by 1 while AUX P toggles OVERRIDE? */
205 REG_UPDATE_SEQ_2(AUXP_IMPCAL,
206 AUXP_IMPCAL_OVERRIDE_ENABLE, 1,
207 AUXP_IMPCAL_OVERRIDE_ENABLE, 0);
210 REG_UPDATE(AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, 1);
212 REG_WAIT(AUX_SW_STATUS, AUX_SW_DONE, 0,
213 10, aux110->polling_timeout_period/10);
215 /* set the delay and the number of bytes to write */
217 /* The length include
218 * the 4 bit header and the 20 bit address
220 * If the requested length is non zero this means
221 * an addition byte specifying the length is required.
224 length = request->length ? 4 : 3;
226 length += request->length;
228 REG_UPDATE_2(AUX_SW_CONTROL,
229 AUX_SW_START_DELAY, request->delay,
230 AUX_SW_WR_BYTES, length);
232 /* program action and address and payload data (if 'is_write') */
233 value = REG_UPDATE_4(AUX_SW_DATA,
236 AUX_SW_AUTOINCREMENT_DISABLE, 1,
237 AUX_SW_DATA, COMPOSE_AUX_SW_DATA_16_20(request->action, request->address));
239 value = REG_SET_2(AUX_SW_DATA, value,
240 AUX_SW_AUTOINCREMENT_DISABLE, 0,
241 AUX_SW_DATA, COMPOSE_AUX_SW_DATA_8_15(request->address));
243 value = REG_SET(AUX_SW_DATA, value,
244 AUX_SW_DATA, COMPOSE_AUX_SW_DATA_0_7(request->address));
246 if (request->length) {
247 value = REG_SET(AUX_SW_DATA, value,
248 AUX_SW_DATA, request->length - 1);
252 /* Load the HW buffer with the Data to be sent.
253 * This is relevant for write operation.
254 * For read, the data recived data will be
255 * processed in process_channel_reply().
259 while (i < request->length) {
260 value = REG_SET(AUX_SW_DATA, value,
261 AUX_SW_DATA, request->data[i]);
267 REG_UPDATE(AUX_SW_CONTROL, AUX_SW_GO, 1);
268 EVENT_LOG_AUX_REQ(engine->ddc->pin_data->en, EVENT_LOG_AUX_ORIGIN_NATIVE,
269 request->action, request->address, request->length, request->data);
272 static int read_channel_reply(struct dce_aux *engine, uint32_t size,
273 uint8_t *buffer, uint8_t *reply_result,
276 struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine);
277 uint32_t bytes_replied;
278 uint32_t reply_result_32;
280 *sw_status = REG_GET(AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT,
283 /* In case HPD is LOW, exit AUX transaction */
284 if ((*sw_status & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK))
287 /* Need at least the status byte */
291 REG_UPDATE_SEQ_3(AUX_SW_DATA,
293 AUX_SW_AUTOINCREMENT_DISABLE, 1,
296 REG_GET(AUX_SW_DATA, AUX_SW_DATA, &reply_result_32);
297 reply_result_32 = reply_result_32 >> 4;
298 if (reply_result != NULL)
299 *reply_result = (uint8_t)reply_result_32;
301 if (reply_result_32 == 0) { /* ACK */
304 /* First byte was already used to get the command status */
307 /* Do not overflow buffer */
308 if (bytes_replied > size)
311 while (i < bytes_replied) {
312 uint32_t aux_sw_data_val;
314 REG_GET(AUX_SW_DATA, AUX_SW_DATA, &aux_sw_data_val);
315 buffer[i] = aux_sw_data_val;
325 static enum aux_channel_operation_result get_channel_status(
326 struct dce_aux *engine,
327 uint8_t *returned_bytes)
329 struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine);
333 if (returned_bytes == NULL) {
334 /*caller pass NULL pointer*/
335 ASSERT_CRITICAL(false);
336 return AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN;
340 /* poll to make sure that SW_DONE is asserted */
341 REG_WAIT(AUX_SW_STATUS, AUX_SW_DONE, 1,
342 10, aux110->polling_timeout_period/10);
344 value = REG_READ(AUX_SW_STATUS);
345 /* in case HPD is LOW, exit AUX transaction */
346 if ((value & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK))
347 return AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON;
349 /* Note that the following bits are set in 'status.bits'
350 * during CTS 4.2.1.2 (FW 3.3.1):
351 * AUX_SW_RX_MIN_COUNT_VIOL, AUX_SW_RX_INVALID_STOP,
352 * AUX_SW_RX_RECV_NO_DET, AUX_SW_RX_RECV_INVALID_H.
354 * AUX_SW_RX_MIN_COUNT_VIOL is an internal,
355 * HW debugging bit and should be ignored.
357 if (value & AUX_SW_STATUS__AUX_SW_DONE_MASK) {
358 if ((value & AUX_SW_STATUS__AUX_SW_RX_TIMEOUT_STATE_MASK) ||
359 (value & AUX_SW_STATUS__AUX_SW_RX_TIMEOUT_MASK))
360 return AUX_CHANNEL_OPERATION_FAILED_TIMEOUT;
362 else if ((value & AUX_SW_STATUS__AUX_SW_RX_INVALID_STOP_MASK) ||
363 (value & AUX_SW_STATUS__AUX_SW_RX_RECV_NO_DET_MASK) ||
365 AUX_SW_STATUS__AUX_SW_RX_RECV_INVALID_H_MASK) ||
366 (value & AUX_SW_STATUS__AUX_SW_RX_RECV_INVALID_L_MASK))
367 return AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY;
369 *returned_bytes = get_reg_field_value(value,
371 AUX_SW_REPLY_BYTE_COUNT);
373 if (*returned_bytes == 0)
375 AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY;
377 *returned_bytes -= 1;
378 return AUX_CHANNEL_OPERATION_SUCCEEDED;
381 /*time_elapsed >= aux_engine->timeout_period
382 * AUX_SW_STATUS__AUX_SW_HPD_DISCON = at this point
384 ASSERT_CRITICAL(false);
385 return AUX_CHANNEL_OPERATION_FAILED_TIMEOUT;
389 enum i2caux_engine_type get_engine_type(
390 const struct dce_aux *engine)
392 return I2CAUX_ENGINE_TYPE_AUX;
396 struct dce_aux *engine,
399 enum gpio_result result;
401 if (!is_engine_available(engine))
404 result = dal_ddc_open(ddc, GPIO_MODE_HARDWARE,
405 GPIO_DDC_CONFIG_TYPE_MODE_AUX);
407 if (result != GPIO_RESULT_OK)
410 if (!acquire_engine(engine)) {
420 void dce110_engine_destroy(struct dce_aux **engine)
423 struct aux_engine_dce110 *engine110 = FROM_AUX_ENGINE(*engine);
430 static bool dce_aux_configure_timeout(struct ddc_service *ddc,
431 uint32_t timeout_in_us)
433 uint32_t multiplier = 0;
435 struct ddc *ddc_pin = ddc->ddc_pin;
436 struct dce_aux *aux_engine = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en];
437 struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(aux_engine);
439 /* 1-Update polling timeout period */
440 aux110->polling_timeout_period = timeout_in_us * SW_AUX_TIMEOUT_PERIOD_MULTIPLIER;
442 /* 2-Update aux timeout period length and multiplier */
443 if (timeout_in_us <= TIME_OUT_INCREMENT) {
445 length = timeout_in_us/TIME_OUT_MULTIPLIER_8;
446 if (timeout_in_us % TIME_OUT_MULTIPLIER_8 != 0)
448 } else if (timeout_in_us <= 2 * TIME_OUT_INCREMENT) {
450 length = timeout_in_us/TIME_OUT_MULTIPLIER_16;
451 if (timeout_in_us % TIME_OUT_MULTIPLIER_16 != 0)
453 } else if (timeout_in_us <= 4 * TIME_OUT_INCREMENT) {
455 length = timeout_in_us/TIME_OUT_MULTIPLIER_32;
456 if (timeout_in_us % TIME_OUT_MULTIPLIER_32 != 0)
458 } else if (timeout_in_us > 4 * TIME_OUT_INCREMENT) {
460 length = timeout_in_us/TIME_OUT_MULTIPLIER_64;
461 if (timeout_in_us % TIME_OUT_MULTIPLIER_64 != 0)
465 length = (length < MAX_TIMEOUT_LENGTH) ? length : MAX_TIMEOUT_LENGTH;
467 REG_UPDATE_SEQ_2(AUX_DPHY_RX_CONTROL1, AUX_RX_TIMEOUT_LEN, length, AUX_RX_TIMEOUT_LEN_MUL, multiplier);
472 static struct dce_aux_funcs aux_functions = {
473 .configure_timeout = NULL,
477 struct dce_aux *dce110_aux_engine_construct(struct aux_engine_dce110 *aux_engine110,
478 struct dc_context *ctx,
480 uint32_t timeout_period,
481 const struct dce110_aux_registers *regs,
482 const struct dce110_aux_registers_mask *mask,
483 const struct dce110_aux_registers_shift *shift,
484 bool is_ext_aux_timeout_configurable)
486 aux_engine110->base.ddc = NULL;
487 aux_engine110->base.ctx = ctx;
488 aux_engine110->base.delay = 0;
489 aux_engine110->base.max_defer_write_retry = 0;
490 aux_engine110->base.inst = inst;
491 aux_engine110->polling_timeout_period = timeout_period;
492 aux_engine110->regs = regs;
494 aux_engine110->mask = mask;
495 aux_engine110->shift = shift;
496 aux_engine110->base.funcs = &aux_functions;
497 if (is_ext_aux_timeout_configurable)
498 aux_engine110->base.funcs->configure_timeout = &dce_aux_configure_timeout;
500 return &aux_engine110->base;
503 static enum i2caux_transaction_action i2caux_action_from_payload(struct aux_payload *payload)
505 if (payload->i2c_over_aux) {
506 if (payload->write) {
508 return I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT;
509 return I2CAUX_TRANSACTION_ACTION_I2C_WRITE;
512 return I2CAUX_TRANSACTION_ACTION_I2C_READ_MOT;
513 return I2CAUX_TRANSACTION_ACTION_I2C_READ;
516 return I2CAUX_TRANSACTION_ACTION_DP_WRITE;
517 return I2CAUX_TRANSACTION_ACTION_DP_READ;
520 int dce_aux_transfer_raw(struct ddc_service *ddc,
521 struct aux_payload *payload,
522 enum aux_channel_operation_result *operation_result)
524 struct ddc *ddc_pin = ddc->ddc_pin;
525 struct dce_aux *aux_engine;
526 struct aux_request_transaction_data aux_req;
527 struct aux_reply_transaction_data aux_rep;
528 uint8_t returned_bytes = 0;
532 memset(&aux_req, 0, sizeof(aux_req));
533 memset(&aux_rep, 0, sizeof(aux_rep));
535 aux_engine = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en];
536 if (!acquire(aux_engine, ddc_pin)) {
537 *operation_result = AUX_CHANNEL_OPERATION_FAILED_ENGINE_ACQUIRE;
541 if (payload->i2c_over_aux)
542 aux_req.type = AUX_TRANSACTION_TYPE_I2C;
544 aux_req.type = AUX_TRANSACTION_TYPE_DP;
546 aux_req.action = i2caux_action_from_payload(payload);
548 aux_req.address = payload->address;
550 aux_req.length = payload->length;
551 aux_req.data = payload->data;
553 submit_channel_request(aux_engine, &aux_req);
554 *operation_result = get_channel_status(aux_engine, &returned_bytes);
556 if (*operation_result == AUX_CHANNEL_OPERATION_SUCCEEDED) {
557 int bytes_replied = 0;
558 bytes_replied = read_channel_reply(aux_engine, payload->length,
559 payload->data, payload->reply,
561 EVENT_LOG_AUX_REP(aux_engine->ddc->pin_data->en,
562 EVENT_LOG_AUX_ORIGIN_NATIVE, *payload->reply,
563 bytes_replied, payload->data);
564 res = returned_bytes;
569 release_engine(aux_engine);
573 #define AUX_MAX_RETRIES 7
574 #define AUX_MAX_DEFER_RETRIES 7
575 #define AUX_MAX_I2C_DEFER_RETRIES 7
576 #define AUX_MAX_INVALID_REPLY_RETRIES 2
577 #define AUX_MAX_TIMEOUT_RETRIES 3
579 bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
580 struct aux_payload *payload)
584 bool payload_reply = true;
585 enum aux_channel_operation_result operation_result;
586 bool retry_on_defer = false;
588 int aux_ack_retries = 0,
589 aux_defer_retries = 0,
590 aux_i2c_defer_retries = 0,
591 aux_timeout_retries = 0,
592 aux_invalid_reply_retries = 0;
594 if (!payload->reply) {
595 payload_reply = false;
596 payload->reply = &reply;
599 for (i = 0; i < AUX_MAX_RETRIES; i++) {
600 ret = dce_aux_transfer_raw(ddc, payload, &operation_result);
601 switch (operation_result) {
602 case AUX_CHANNEL_OPERATION_SUCCEEDED:
603 aux_timeout_retries = 0;
604 aux_invalid_reply_retries = 0;
606 switch (*payload->reply) {
607 case AUX_TRANSACTION_REPLY_AUX_ACK:
608 if (!payload->write && payload->length != ret) {
609 if (++aux_ack_retries >= AUX_MAX_RETRIES)
617 case AUX_TRANSACTION_REPLY_AUX_DEFER:
618 case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER:
619 retry_on_defer = true;
621 case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_NACK:
622 if (++aux_defer_retries >= AUX_MAX_DEFER_RETRIES) {
625 if ((*payload->reply == AUX_TRANSACTION_REPLY_AUX_DEFER) ||
626 (*payload->reply == AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER)) {
627 if (payload->defer_delay > 0)
628 msleep(payload->defer_delay);
633 case AUX_TRANSACTION_REPLY_I2C_DEFER:
634 aux_defer_retries = 0;
635 if (++aux_i2c_defer_retries >= AUX_MAX_I2C_DEFER_RETRIES)
639 case AUX_TRANSACTION_REPLY_AUX_NACK:
640 case AUX_TRANSACTION_REPLY_HPD_DISCON:
646 case AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY:
647 if (++aux_invalid_reply_retries >= AUX_MAX_INVALID_REPLY_RETRIES)
653 case AUX_CHANNEL_OPERATION_FAILED_TIMEOUT:
654 // Check whether a DEFER had occurred before the timeout.
655 // If so, treat timeout as a DEFER.
656 if (retry_on_defer) {
657 if (++aux_defer_retries >= AUX_MAX_DEFER_RETRIES)
659 else if (payload->defer_delay > 0)
660 msleep(payload->defer_delay);
662 if (++aux_timeout_retries >= AUX_MAX_TIMEOUT_RETRIES)
666 * DP 1.4, 2.8.2: AUX Transaction Response/Reply Timeouts
667 * According to the DP spec there should be 3 retries total
668 * with a 400us wait inbetween each. Hardware already waits
669 * for 550us therefore no wait is required here.
675 case AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON:
676 case AUX_CHANNEL_OPERATION_FAILED_ENGINE_ACQUIRE:
677 case AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN:
685 payload->reply = NULL;