drm/amd/display: generic indirect register access

add generic indirect register access following our register access pattern

this will make it easier to review code and programming sequence,
with all the complexity hidden in macro

Signed-off-by: Tony Cheng <tony.cheng@amd.com>
Reviewed-by: Yongqiang Sun <yongqiang.sun@amd.com>
Acked-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Tony Cheng 2018-06-16 19:43:41 -04:00 committed by Alex Deucher
parent 4981a66144
commit 16aecfd4bf
2 changed files with 97 additions and 0 deletions
drivers/gpu/drm/amd/display/dc

@ -255,3 +255,54 @@ uint32_t generic_reg_wait(const struct dc_context *ctx,
return reg_val;
}
void generic_write_indirect_reg(const struct dc_context *ctx,
uint32_t addr_index, uint32_t addr_data,
uint32_t index, uint32_t data)
{
dm_write_reg(ctx, addr_index, index);
dm_write_reg(ctx, addr_data, data);
}
uint32_t generic_read_indirect_reg(const struct dc_context *ctx,
uint32_t addr_index, uint32_t addr_data,
uint32_t index)
{
uint32_t value = 0;
dm_write_reg(ctx, addr_index, index);
value = dm_read_reg(ctx, addr_data);
return value;
}
uint32_t generic_indirect_reg_update_ex(const struct dc_context *ctx,
uint32_t addr_index, uint32_t addr_data,
uint32_t index, uint32_t reg_val, int n,
uint8_t shift1, uint32_t mask1, uint32_t field_value1,
...)
{
uint32_t shift, mask, field_value;
int i = 1;
va_list ap;
va_start(ap, field_value1);
reg_val = set_reg_field_value_ex(reg_val, field_value1, mask1, shift1);
while (i < n) {
shift = va_arg(ap, uint32_t);
mask = va_arg(ap, uint32_t);
field_value = va_arg(ap, uint32_t);
reg_val = set_reg_field_value_ex(reg_val, field_value, mask, shift);
i++;
}
generic_write_indirect_reg(ctx, addr_index, addr_data, index, reg_val);
va_end(ap);
return reg_val;
}

@ -445,4 +445,50 @@ uint32_t generic_reg_get8(const struct dc_context *ctx, uint32_t addr,
uint8_t shift6, uint32_t mask6, uint32_t *field_value6,
uint8_t shift7, uint32_t mask7, uint32_t *field_value7,
uint8_t shift8, uint32_t mask8, uint32_t *field_value8);
/* indirect register access */
#define IX_REG_SET_N(index_reg_name, data_reg_name, index, n, initial_val, ...) \
generic_indirect_reg_update_ex(CTX, \
REG(index_reg_name), REG(data_reg_name), IND_REG(index), \
initial_val, \
n, __VA_ARGS__)
#define IX_REG_SET_2(index_reg_name, data_reg_name, index, init_value, f1, v1, f2, v2) \
IX_REG_SET_N(index_reg_name, data_reg_name, index, 2, init_value, \
FN(reg, f1), v1,\
FN(reg, f2), v2)
#define IX_REG_READ(index_reg_name, data_reg_name, index) \
generic_read_indirect_reg(CTX, REG(index_reg_name), REG(data_reg_name), IND_REG(index))
#define IX_REG_UPDATE_N(index_reg_name, data_reg_name, index, n, ...) \
generic_indirect_reg_update_ex(CTX, \
REG(index_reg_name), REG(data_reg_name), IND_REG(index), \
IX_REG_READ(index_reg_name, data_reg_name, index), \
n, __VA_ARGS__)
#define IX_REG_UPDATE_2(index_reg_name, data_reg_name, index, f1, v1, f2, v2) \
IX_REG_UPDATE_N(index_reg_name, data_reg_name, index, 2,\
FN(reg, f1), v1,\
FN(reg, f2), v2)
void generic_write_indirect_reg(const struct dc_context *ctx,
uint32_t addr_index, uint32_t addr_data,
uint32_t index, uint32_t data);
uint32_t generic_read_indirect_reg(const struct dc_context *ctx,
uint32_t addr_index, uint32_t addr_data,
uint32_t index);
uint32_t generic_indirect_reg_update_ex(const struct dc_context *ctx,
uint32_t addr_index, uint32_t addr_data,
uint32_t index, uint32_t reg_val, int n,
uint8_t shift1, uint32_t mask1, uint32_t field_value1,
...);
#endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_REG_HELPER_H_ */