diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/i2caux')
4 files changed, 55 insertions, 76 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c b/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c index bb526ad326e5..1d7309611978 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c +++ b/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c @@ -157,6 +157,10 @@ static void process_read_reply( ctx->operation_succeeded = false; } break; + case AUX_TRANSACTION_REPLY_HPD_DISCON: + ctx->status = I2CAUX_TRANSACTION_STATUS_FAILED_HPD_DISCON; + ctx->operation_succeeded = false; + break; default: ctx->status = I2CAUX_TRANSACTION_STATUS_UNKNOWN; ctx->operation_succeeded = false; @@ -215,6 +219,10 @@ static void process_read_request( * so we should not wait here */ } break; + case AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON: + ctx->status = I2CAUX_TRANSACTION_STATUS_FAILED_HPD_DISCON; + ctx->operation_succeeded = false; + break; default: ctx->status = I2CAUX_TRANSACTION_STATUS_UNKNOWN; ctx->operation_succeeded = false; @@ -370,6 +378,10 @@ static void process_write_reply( ctx->operation_succeeded = false; } break; + case AUX_TRANSACTION_REPLY_HPD_DISCON: + ctx->status = I2CAUX_TRANSACTION_STATUS_FAILED_HPD_DISCON; + ctx->operation_succeeded = false; + break; default: ctx->status = I2CAUX_TRANSACTION_STATUS_UNKNOWN; ctx->operation_succeeded = false; @@ -422,6 +434,10 @@ static void process_write_request( * so we should not wait here */ } break; + case AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON: + ctx->status = I2CAUX_TRANSACTION_STATUS_FAILED_HPD_DISCON; + ctx->operation_succeeded = false; + break; default: ctx->status = I2CAUX_TRANSACTION_STATUS_UNKNOWN; ctx->operation_succeeded = false; diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.h b/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.h index 8e71324ccb10..b01488f710d5 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.h +++ b/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.h @@ -26,46 +26,7 @@ #ifndef __DAL_AUX_ENGINE_H__ #define __DAL_AUX_ENGINE_H__ -enum aux_transaction_type { - AUX_TRANSACTION_TYPE_DP, - AUX_TRANSACTION_TYPE_I2C -}; - -struct aux_request_transaction_data { - enum aux_transaction_type type; - enum i2caux_transaction_action action; - /* 20-bit AUX channel transaction address */ - uint32_t address; - /* delay, in 100-microsecond units */ - uint8_t delay; - uint32_t length; - uint8_t *data; -}; - -enum aux_transaction_reply { - AUX_TRANSACTION_REPLY_AUX_ACK = 0x00, - AUX_TRANSACTION_REPLY_AUX_NACK = 0x01, - AUX_TRANSACTION_REPLY_AUX_DEFER = 0x02, - - AUX_TRANSACTION_REPLY_I2C_ACK = 0x00, - AUX_TRANSACTION_REPLY_I2C_NACK = 0x10, - AUX_TRANSACTION_REPLY_I2C_DEFER = 0x20, - - AUX_TRANSACTION_REPLY_INVALID = 0xFF -}; - -struct aux_reply_transaction_data { - enum aux_transaction_reply status; - uint32_t length; - uint8_t *data; -}; - -enum aux_channel_operation_result { - AUX_CHANNEL_OPERATION_SUCCEEDED, - AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN, - AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY, - AUX_CHANNEL_OPERATION_FAILED_TIMEOUT -}; +#include "dc_ddc_types.h" struct aux_engine; diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/aux_engine_dce110.c b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/aux_engine_dce110.c index 5f47f6c007ac..2b927f25937b 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/aux_engine_dce110.c +++ b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/aux_engine_dce110.c @@ -198,27 +198,27 @@ static void submit_channel_request( ((request->type == AUX_TRANSACTION_TYPE_I2C) && ((request->action == I2CAUX_TRANSACTION_ACTION_I2C_WRITE) || (request->action == I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT))); + if (REG(AUXN_IMPCAL)) { + /* clear_aux_error */ + REG_UPDATE_SEQ(AUXN_IMPCAL, AUXN_CALOUT_ERROR_AK, + 1, + 0); - /* clear_aux_error */ - REG_UPDATE_SEQ(AUXN_IMPCAL, AUXN_CALOUT_ERROR_AK, - 1, - 0); - - REG_UPDATE_SEQ(AUXP_IMPCAL, AUXP_CALOUT_ERROR_AK, - 1, - 0); - - /* force_default_calibrate */ - REG_UPDATE_1BY1_2(AUXN_IMPCAL, - AUXN_IMPCAL_ENABLE, 1, - AUXN_IMPCAL_OVERRIDE_ENABLE, 0); + REG_UPDATE_SEQ(AUXP_IMPCAL, AUXP_CALOUT_ERROR_AK, + 1, + 0); - /* bug? why AUXN update EN and OVERRIDE_EN 1 by 1 while AUX P toggles OVERRIDE? */ + /* force_default_calibrate */ + REG_UPDATE_1BY1_2(AUXN_IMPCAL, + AUXN_IMPCAL_ENABLE, 1, + AUXN_IMPCAL_OVERRIDE_ENABLE, 0); - REG_UPDATE_SEQ(AUXP_IMPCAL, AUXP_IMPCAL_OVERRIDE_ENABLE, - 1, - 0); + /* bug? why AUXN update EN and OVERRIDE_EN 1 by 1 while AUX P toggles OVERRIDE? */ + REG_UPDATE_SEQ(AUXP_IMPCAL, AUXP_IMPCAL_OVERRIDE_ENABLE, + 1, + 0); + } /* set the delay and the number of bytes to write */ /* The length include @@ -291,6 +291,12 @@ static void process_channel_reply( value = REG_GET(AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, &bytes_replied); + /* in case HPD is LOW, exit AUX transaction */ + if ((value & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK)) { + reply->status = AUX_TRANSACTION_REPLY_HPD_DISCON; + return; + } + if (bytes_replied) { uint32_t reply_result; @@ -347,8 +353,10 @@ static void process_channel_reply( * because there was surely an error that was asserted * that should have been handled * for hot plug case, this could happens*/ - if (!(value & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK)) + if (!(value & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK)) { + reply->status = AUX_TRANSACTION_REPLY_INVALID; ASSERT_CRITICAL(false); + } } } @@ -371,6 +379,10 @@ static enum aux_channel_operation_result get_channel_status( value = REG_WAIT(AUX_SW_STATUS, AUX_SW_DONE, 1, 10, aux110->timeout_period/10); + /* in case HPD is LOW, exit AUX transaction */ + if ((value & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK)) + return AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON; + /* Note that the following bits are set in 'status.bits' * during CTS 4.2.1.2 (FW 3.3.1): * AUX_SW_RX_MIN_COUNT_VIOL, AUX_SW_RX_INVALID_STOP, @@ -402,10 +414,10 @@ static enum aux_channel_operation_result get_channel_status( return AUX_CHANNEL_OPERATION_SUCCEEDED; } } else { - /*time_elapsed >= aux_engine->timeout_period */ - if (!(value & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK)) - ASSERT_CRITICAL(false); - + /*time_elapsed >= aux_engine->timeout_period + * AUX_SW_STATUS__AUX_SW_HPD_DISCON = at this point + */ + ASSERT_CRITICAL(false); return AUX_CHANNEL_OPERATION_FAILED_TIMEOUT; } } diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/engine.h b/drivers/gpu/drm/amd/display/dc/i2caux/engine.h index 33de8a8834dc..1e8a1585e401 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/engine.h +++ b/drivers/gpu/drm/amd/display/dc/i2caux/engine.h @@ -26,6 +26,8 @@ #ifndef __DAL_ENGINE_H__ #define __DAL_ENGINE_H__ +#include "dc_ddc_types.h" + enum i2caux_transaction_operation { I2CAUX_TRANSACTION_READ, I2CAUX_TRANSACTION_WRITE @@ -53,7 +55,8 @@ enum i2caux_transaction_status { I2CAUX_TRANSACTION_STATUS_FAILED_INCOMPLETE, I2CAUX_TRANSACTION_STATUS_FAILED_OPERATION, I2CAUX_TRANSACTION_STATUS_FAILED_INVALID_OPERATION, - I2CAUX_TRANSACTION_STATUS_FAILED_BUFFER_OVERFLOW + I2CAUX_TRANSACTION_STATUS_FAILED_BUFFER_OVERFLOW, + I2CAUX_TRANSACTION_STATUS_FAILED_HPD_DISCON }; struct i2caux_transaction_request { @@ -75,19 +78,6 @@ enum i2c_default_speed { I2CAUX_DEFAULT_I2C_SW_SPEED = 50 }; -enum i2caux_transaction_action { - I2CAUX_TRANSACTION_ACTION_I2C_WRITE = 0x00, - I2CAUX_TRANSACTION_ACTION_I2C_READ = 0x10, - I2CAUX_TRANSACTION_ACTION_I2C_STATUS_REQUEST = 0x20, - - I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT = 0x40, - I2CAUX_TRANSACTION_ACTION_I2C_READ_MOT = 0x50, - I2CAUX_TRANSACTION_ACTION_I2C_STATUS_REQUEST_MOT = 0x60, - - I2CAUX_TRANSACTION_ACTION_DP_WRITE = 0x80, - I2CAUX_TRANSACTION_ACTION_DP_READ = 0x90 -}; - struct engine; struct engine_funcs { |