From: Zeyu Fan <Zeyu.Fan@xxxxxxx> Change-Id: Ibe3a78a8a5b633e0e785611a5a16c2627937e91a Signed-off-by: Zeyu Fan <Zeyu.Fan at amd.com> Reviewed-by: Tony Cheng <Tony.Cheng at amd.com> Acked-by: Harry Wentland <Harry.Wentland at amd.com> --- .../drm/amd/dal/dc/i2caux/dce100/i2caux_dce100.c | 12 +- .../dal/dc/i2caux/dce110/i2c_hw_engine_dce110.c | 55 ++++----- .../dal/dc/i2caux/dce110/i2c_hw_engine_dce110.h | 124 ++++++++++++++++++++- .../drm/amd/dal/dc/i2caux/dce110/i2caux_dce110.c | 18 ++- .../drm/amd/dal/dc/i2caux/dce110/i2caux_dce110.h | 6 +- .../drm/amd/dal/dc/i2caux/dce112/i2caux_dce112.c | 12 +- 6 files changed, 195 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/dce100/i2caux_dce100.c b/drivers/gpu/drm/amd/dal/dc/i2caux/dce100/i2caux_dce100.c index ab138464aaa2..0712cafb4c42 100644 --- a/drivers/gpu/drm/amd/dal/dc/i2caux/dce100/i2caux_dce100.c +++ b/drivers/gpu/drm/amd/dal/dc/i2caux/dce100/i2caux_dce100.c @@ -76,6 +76,14 @@ static const struct dce110_i2c_hw_engine_registers dce100_hw_engine_regs[] = { hw_engine_regs(6) }; +static const struct dce110_i2c_hw_engine_shift i2c_shift = { + I2C_COMMON_MASK_SH_LIST_DCE100(__SHIFT) +}; + +static const struct dce110_i2c_hw_engine_mask i2c_mask = { + I2C_COMMON_MASK_SH_LIST_DCE100(_MASK) +}; + struct i2caux *dal_i2caux_dce100_create( struct dc_context *ctx) { @@ -91,7 +99,9 @@ struct i2caux *dal_i2caux_dce100_create( i2caux_dce110, ctx, dce100_aux_regs, - dce100_hw_engine_regs)) + dce100_hw_engine_regs, + &i2c_shift, + &i2c_mask)) return &i2caux_dce110->base; ASSERT_CRITICAL(false); diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2c_hw_engine_dce110.c b/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2c_hw_engine_dce110.c index cfcd5db825f6..80d06ad78e07 100644 --- a/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2c_hw_engine_dce110.c +++ b/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2c_hw_engine_dce110.c @@ -43,14 +43,6 @@ /* * Post-requisites: headers required by this unit */ - -/* - * Temporarily adding ellesmere specific headers - * to get the right defined values - */ -#include "dce/dce_11_2_d.h" -#include "dce/dce_11_2_sh_mask.h" - #include "reg_helper.h" /* @@ -100,8 +92,14 @@ enum { #define CTX \ hw_engine->base.base.base.ctx + #define REG(reg_name)\ (hw_engine->regs->reg_name) + +#undef FN +#define FN(reg_name, field_name) \ + hw_engine->i2c_shift->field_name, hw_engine->i2c_mask->field_name + #include "reg_helper.h" static void disable_i2c_hw_engine( @@ -187,9 +185,7 @@ static uint32_t get_speed( const struct i2c_hw_engine_dce110 *hw_engine = FROM_I2C_ENGINE(i2c_engine); uint32_t pre_scale = 0; - generic_reg_get( - CTX, REG(SPEED), - FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_PRESCALE), &pre_scale); + REG_GET(SPEED, DC_I2C_DDC1_PRESCALE, &pre_scale); /* [anaumov] it seems following is unnecessary */ /*ASSERT(value.bits.DC_I2C_DDC1_PRESCALE);*/ @@ -204,12 +200,19 @@ static void set_speed( { struct i2c_hw_engine_dce110 *hw_engine = FROM_I2C_ENGINE(i2c_engine); - if (speed) - REG_UPDATE_N( - SPEED, 3, - FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_PRESCALE), hw_engine->reference_frequency / speed, - FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_THRESHOLD), 2, - FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_START_STOP_TIMING_CNTL), speed > 50 ? 2:1); + if (speed) { + if (hw_engine->i2c_mask->DC_I2C_DDC1_START_STOP_TIMING_CNTL) + REG_UPDATE_N( + SPEED, 3, + FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_PRESCALE), hw_engine->reference_frequency / speed, + FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_THRESHOLD), 2, + FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_START_STOP_TIMING_CNTL), speed > 50 ? 2:1); + else + REG_UPDATE_N( + SPEED, 2, + FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_PRESCALE), hw_engine->reference_frequency / speed, + FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_THRESHOLD), 2); + } } static inline void reset_hw_engine(struct engine *engine) @@ -393,12 +396,10 @@ static void process_channel_reply( * (i.e. DC_I2C_STATUS_DONE = 1) then the I2C controller * should read data bytes from I2C circular data buffer */ - uint32_t value = REG_READ(DC_I2C_DATA); + uint32_t i2c_data; - *buffer++ = get_reg_field_value( - value, - DC_I2C_DATA, - DC_I2C_DATA); + REG_GET(DC_I2C_DATA, DC_I2C_DATA, &i2c_data); + *buffer++ = i2c_data; --length; } @@ -415,13 +416,13 @@ static enum i2c_channel_operation_result get_channel_status( if (i2c_sw_status == DC_I2C_STATUS__DC_I2C_STATUS_USED_BY_SW) return I2C_CHANNEL_OPERATION_ENGINE_BUSY; - else if (value & DC_I2C_SW_STATUS__DC_I2C_SW_STOPPED_ON_NACK_MASK) + else if (value & hw_engine->i2c_mask->DC_I2C_SW_STOPPED_ON_NACK) return I2C_CHANNEL_OPERATION_NO_RESPONSE; - else if (value & DC_I2C_SW_STATUS__DC_I2C_SW_TIMEOUT_MASK) + else if (value & hw_engine->i2c_mask->DC_I2C_SW_TIMEOUT) return I2C_CHANNEL_OPERATION_TIMEOUT; - else if (value & DC_I2C_SW_STATUS__DC_I2C_SW_ABORTED_MASK) + else if (value & hw_engine->i2c_mask->DC_I2C_SW_ABORTED) return I2C_CHANNEL_OPERATION_FAILED; - else if (value & DC_I2C_SW_STATUS__DC_I2C_SW_DONE_MASK) + else if (value & hw_engine->i2c_mask->DC_I2C_SW_DONE) return I2C_CHANNEL_OPERATION_SUCCEEDED; /* @@ -515,6 +516,8 @@ bool i2c_hw_engine_dce110_construct( hw_engine->base.default_speed = arg->default_speed; hw_engine->regs = arg->regs; + hw_engine->i2c_shift = arg->i2c_shift; + hw_engine->i2c_mask = arg->i2c_mask; hw_engine->engine_id = arg->engine_id; diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2c_hw_engine_dce110.h b/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2c_hw_engine_dce110.h index ee40e7c9dbeb..c573c6459ec6 100644 --- a/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2c_hw_engine_dce110.h +++ b/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2c_hw_engine_dce110.h @@ -39,6 +39,125 @@ SR(DC_I2C_DATA),\ SR(MICROSECOND_TIME_BASE_DIV) +#define I2C_SF(reg_name, field_name, post_fix)\ + .field_name = reg_name ## __ ## field_name ## post_fix + +#define I2C_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh)\ + I2C_SF(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_ENABLE, mask_sh),\ + I2C_SF(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_TIME_LIMIT, mask_sh),\ + I2C_SF(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_DATA_DRIVE_EN, mask_sh),\ + I2C_SF(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_CLK_DRIVE_EN, mask_sh),\ + I2C_SF(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_DATA_DRIVE_SEL, mask_sh),\ + I2C_SF(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_INTRA_TRANSACTION_DELAY, mask_sh),\ + I2C_SF(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_INTRA_BYTE_DELAY, mask_sh),\ + I2C_SF(DC_I2C_ARBITRATION, DC_I2C_SW_DONE_USING_I2C_REG, mask_sh),\ + I2C_SF(DC_I2C_ARBITRATION, DC_I2C_NO_QUEUED_SW_GO, mask_sh),\ + I2C_SF(DC_I2C_ARBITRATION, DC_I2C_SW_PRIORITY, mask_sh),\ + I2C_SF(DC_I2C_CONTROL, DC_I2C_SOFT_RESET, mask_sh),\ + I2C_SF(DC_I2C_CONTROL, DC_I2C_SW_STATUS_RESET, mask_sh),\ + I2C_SF(DC_I2C_CONTROL, DC_I2C_GO, mask_sh),\ + I2C_SF(DC_I2C_CONTROL, DC_I2C_SEND_RESET, mask_sh),\ + I2C_SF(DC_I2C_CONTROL, DC_I2C_TRANSACTION_COUNT, mask_sh),\ + I2C_SF(DC_I2C_CONTROL, DC_I2C_DDC_SELECT, mask_sh),\ + I2C_SF(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_PRESCALE, mask_sh),\ + I2C_SF(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_THRESHOLD, mask_sh),\ + I2C_SF(DC_I2C_SW_STATUS, DC_I2C_SW_STOPPED_ON_NACK, mask_sh),\ + I2C_SF(DC_I2C_SW_STATUS, DC_I2C_SW_TIMEOUT, mask_sh),\ + I2C_SF(DC_I2C_SW_STATUS, DC_I2C_SW_ABORTED, mask_sh),\ + I2C_SF(DC_I2C_SW_STATUS, DC_I2C_SW_DONE, mask_sh),\ + I2C_SF(DC_I2C_SW_STATUS, DC_I2C_SW_STATUS, mask_sh),\ + I2C_SF(DC_I2C_TRANSACTION0, DC_I2C_STOP_ON_NACK0, mask_sh),\ + I2C_SF(DC_I2C_TRANSACTION0, DC_I2C_START0, mask_sh),\ + I2C_SF(DC_I2C_TRANSACTION0, DC_I2C_RW0, mask_sh),\ + I2C_SF(DC_I2C_TRANSACTION0, DC_I2C_STOP0, mask_sh),\ + I2C_SF(DC_I2C_TRANSACTION0, DC_I2C_COUNT0, mask_sh),\ + I2C_SF(DC_I2C_DATA, DC_I2C_DATA_RW, mask_sh),\ + I2C_SF(DC_I2C_DATA, DC_I2C_DATA, mask_sh),\ + I2C_SF(DC_I2C_DATA, DC_I2C_INDEX, mask_sh),\ + I2C_SF(DC_I2C_DATA, DC_I2C_INDEX_WRITE, mask_sh),\ + I2C_SF(MICROSECOND_TIME_BASE_DIV, XTAL_REF_DIV, mask_sh) + +#define I2C_COMMON_MASK_SH_LIST_DCE100(mask_sh)\ + I2C_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh) + +#define I2C_COMMON_MASK_SH_LIST_DCE110(mask_sh)\ + I2C_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh),\ + I2C_SF(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_START_STOP_TIMING_CNTL, mask_sh) + +struct dce110_i2c_hw_engine_shift { + uint8_t DC_I2C_DDC1_ENABLE; + uint8_t DC_I2C_DDC1_TIME_LIMIT; + uint8_t DC_I2C_DDC1_DATA_DRIVE_EN; + uint8_t DC_I2C_DDC1_CLK_DRIVE_EN; + uint8_t DC_I2C_DDC1_DATA_DRIVE_SEL; + uint8_t DC_I2C_DDC1_INTRA_TRANSACTION_DELAY; + uint8_t DC_I2C_DDC1_INTRA_BYTE_DELAY; + uint8_t DC_I2C_SW_DONE_USING_I2C_REG; + uint8_t DC_I2C_NO_QUEUED_SW_GO; + uint8_t DC_I2C_SW_PRIORITY; + uint8_t DC_I2C_SOFT_RESET; + uint8_t DC_I2C_SW_STATUS_RESET; + uint8_t DC_I2C_GO; + uint8_t DC_I2C_SEND_RESET; + uint8_t DC_I2C_TRANSACTION_COUNT; + uint8_t DC_I2C_DDC_SELECT; + uint8_t DC_I2C_DDC1_PRESCALE; + uint8_t DC_I2C_DDC1_THRESHOLD; + uint8_t DC_I2C_DDC1_START_STOP_TIMING_CNTL; + uint8_t DC_I2C_SW_STOPPED_ON_NACK; + uint8_t DC_I2C_SW_TIMEOUT; + uint8_t DC_I2C_SW_ABORTED; + uint8_t DC_I2C_SW_DONE; + uint8_t DC_I2C_SW_STATUS; + uint8_t DC_I2C_STOP_ON_NACK0; + uint8_t DC_I2C_START0; + uint8_t DC_I2C_RW0; + uint8_t DC_I2C_STOP0; + uint8_t DC_I2C_COUNT0; + uint8_t DC_I2C_DATA_RW; + uint8_t DC_I2C_DATA; + uint8_t DC_I2C_INDEX; + uint8_t DC_I2C_INDEX_WRITE; + uint8_t XTAL_REF_DIV; +}; + +struct dce110_i2c_hw_engine_mask { + uint32_t DC_I2C_DDC1_ENABLE; + uint32_t DC_I2C_DDC1_TIME_LIMIT; + uint32_t DC_I2C_DDC1_DATA_DRIVE_EN; + uint32_t DC_I2C_DDC1_CLK_DRIVE_EN; + uint32_t DC_I2C_DDC1_DATA_DRIVE_SEL; + uint32_t DC_I2C_DDC1_INTRA_TRANSACTION_DELAY; + uint32_t DC_I2C_DDC1_INTRA_BYTE_DELAY; + uint32_t DC_I2C_SW_DONE_USING_I2C_REG; + uint32_t DC_I2C_NO_QUEUED_SW_GO; + uint32_t DC_I2C_SW_PRIORITY; + uint32_t DC_I2C_SOFT_RESET; + uint32_t DC_I2C_SW_STATUS_RESET; + uint32_t DC_I2C_GO; + uint32_t DC_I2C_SEND_RESET; + uint32_t DC_I2C_TRANSACTION_COUNT; + uint32_t DC_I2C_DDC_SELECT; + uint32_t DC_I2C_DDC1_PRESCALE; + uint32_t DC_I2C_DDC1_THRESHOLD; + uint32_t DC_I2C_DDC1_START_STOP_TIMING_CNTL; + uint32_t DC_I2C_SW_STOPPED_ON_NACK; + uint32_t DC_I2C_SW_TIMEOUT; + uint32_t DC_I2C_SW_ABORTED; + uint32_t DC_I2C_SW_DONE; + uint32_t DC_I2C_SW_STATUS; + uint32_t DC_I2C_STOP_ON_NACK0; + uint32_t DC_I2C_START0; + uint32_t DC_I2C_RW0; + uint32_t DC_I2C_STOP0; + uint32_t DC_I2C_COUNT0; + uint32_t DC_I2C_DATA_RW; + uint32_t DC_I2C_DATA; + uint32_t DC_I2C_INDEX; + uint32_t DC_I2C_INDEX_WRITE; + uint32_t XTAL_REF_DIV; +}; + struct dce110_i2c_hw_engine_registers { uint32_t SETUP; uint32_t SPEED; @@ -53,10 +172,11 @@ struct dce110_i2c_hw_engine_registers { uint32_t MICROSECOND_TIME_BASE_DIV; }; - struct i2c_hw_engine_dce110 { struct i2c_hw_engine base; const struct dce110_i2c_hw_engine_registers *regs; + const struct dce110_i2c_hw_engine_shift *i2c_shift; + const struct dce110_i2c_hw_engine_mask *i2c_mask; struct { uint32_t DC_I2C_DDCX_SETUP; uint32_t DC_I2C_DDCX_SPEED; @@ -80,6 +200,8 @@ struct i2c_hw_engine_dce110_create_arg { uint32_t default_speed; struct dc_context *ctx; const struct dce110_i2c_hw_engine_registers *regs; + const struct dce110_i2c_hw_engine_shift *i2c_shift; + const struct dce110_i2c_hw_engine_mask *i2c_mask; }; struct i2c_engine *dal_i2c_hw_engine_dce110_create( diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2caux_dce110.c b/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2caux_dce110.c index a66c365edfac..1c00ed0010d9 100644 --- a/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2caux_dce110.c +++ b/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2caux_dce110.c @@ -188,11 +188,21 @@ static const struct dce110_i2c_hw_engine_registers i2c_hw_engine_regs[] = { hw_engine_regs(6) }; +static const struct dce110_i2c_hw_engine_shift i2c_shift = { + I2C_COMMON_MASK_SH_LIST_DCE110(__SHIFT) +}; + +static const struct dce110_i2c_hw_engine_mask i2c_mask = { + I2C_COMMON_MASK_SH_LIST_DCE110(_MASK) +}; + bool dal_i2caux_dce110_construct( struct i2caux_dce110 *i2caux_dce110, struct dc_context *ctx, const struct dce110_aux_registers aux_regs[], - const struct dce110_i2c_hw_engine_registers i2c_hw_engine_regs[]) + const struct dce110_i2c_hw_engine_registers i2c_hw_engine_regs[], + const struct dce110_i2c_hw_engine_shift *i2c_shift, + const struct dce110_i2c_hw_engine_mask *i2c_mask) { uint32_t i = 0; uint32_t reference_frequency = 0; @@ -237,6 +247,8 @@ bool dal_i2caux_dce110_construct( hw_arg_dce110.default_speed = base->default_i2c_hw_speed; hw_arg_dce110.ctx = ctx; hw_arg_dce110.regs = &i2c_hw_engine_regs[i]; + hw_arg_dce110.i2c_shift = i2c_shift; + hw_arg_dce110.i2c_mask = i2c_mask; base->i2c_hw_engines[line_id] = dal_i2c_hw_engine_dce110_create(&hw_arg_dce110); @@ -298,7 +310,9 @@ struct i2caux *dal_i2caux_dce110_create( i2caux_dce110, ctx, dce110_aux_regs, - i2c_hw_engine_regs)) + i2c_hw_engine_regs, + &i2c_shift, + &i2c_mask)) return &i2caux_dce110->base; ASSERT_CRITICAL(false); diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2caux_dce110.h b/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2caux_dce110.h index 4d544f4e6289..fd1cc23c3d70 100644 --- a/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2caux_dce110.h +++ b/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2caux_dce110.h @@ -36,6 +36,8 @@ struct i2caux_dce110 { struct dce110_aux_registers; struct dce110_i2c_hw_engine_registers; +struct dce110_i2c_hw_engine_shift; +struct dce110_i2c_hw_engine_mask; struct i2caux *dal_i2caux_dce110_create( struct dc_context *ctx); @@ -44,6 +46,8 @@ bool dal_i2caux_dce110_construct( struct i2caux_dce110 *i2caux_dce110, struct dc_context *ctx, const struct dce110_aux_registers *aux_regs, - const struct dce110_i2c_hw_engine_registers *i2c_hw_engine_regs); + const struct dce110_i2c_hw_engine_registers *i2c_hw_engine_regs, + const struct dce110_i2c_hw_engine_shift *i2c_shift, + const struct dce110_i2c_hw_engine_mask *i2c_mask); #endif /* __DAL_I2C_AUX_DCE110_H__ */ diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/dce112/i2caux_dce112.c b/drivers/gpu/drm/amd/dal/dc/i2caux/dce112/i2caux_dce112.c index 2b1456e3d367..d74f3f15d600 100644 --- a/drivers/gpu/drm/amd/dal/dc/i2caux/dce112/i2caux_dce112.c +++ b/drivers/gpu/drm/amd/dal/dc/i2caux/dce112/i2caux_dce112.c @@ -79,6 +79,14 @@ static const struct dce110_i2c_hw_engine_registers dce112_hw_engine_regs[] = { hw_engine_regs(6) }; +static const struct dce110_i2c_hw_engine_shift i2c_shift = { + I2C_COMMON_MASK_SH_LIST_DCE110(__SHIFT) +}; + +static const struct dce110_i2c_hw_engine_mask i2c_mask = { + I2C_COMMON_MASK_SH_LIST_DCE110(_MASK) +}; + static bool construct( struct i2caux_dce110 *i2caux_dce110, struct dc_context *ctx) @@ -87,7 +95,9 @@ static bool construct( i2caux_dce110, ctx, dce112_aux_regs, - dce112_hw_engine_regs)) { + dce112_hw_engine_regs, + &i2c_shift, + &i2c_mask)) { ASSERT_CRITICAL(false); return false; } -- 2.9.3