Commit c1e34175 authored by Noah Abradjian's avatar Noah Abradjian Committed by Alex Deucher
Browse files

drm/amd/display: Indirect reg read macro with shift and mask



[Why]
Recent double buffering changes for dcn2 use IX_REG_READ.
However, this macro returns the full register value, with the need to
manually shift and mask it to retrieve field data.

[How]
Create new IX_REG_GET macro that handles shift and mask.
Use this for double buffering reads instead of IX_REG_READ.

Signed-off-by: default avatarNoah Abradjian <noah.abradjian@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Acked-by: default avatarHarry Wentland <harry.wentland@amd.com>
Acked-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent ec256f44
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -552,6 +552,36 @@ uint32_t generic_read_indirect_reg(const struct dc_context *ctx,
	return value;
}

uint32_t generic_indirect_reg_get(const struct dc_context *ctx,
		uint32_t addr_index, uint32_t addr_data,
		uint32_t index, int n,
		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
		...)
{
	uint32_t shift, mask, *field_value;
	uint32_t value = 0;
	int i = 1;

	va_list ap;

	va_start(ap, field_value1);

	value = generic_read_indirect_reg(ctx, addr_index, addr_data, index);
	*field_value1 = get_reg_field_value_ex(value, mask1, shift1);

	while (i < n) {
		shift = va_arg(ap, uint32_t);
		mask = va_arg(ap, uint32_t);
		field_value = va_arg(ap, uint32_t *);

		*field_value = get_reg_field_value_ex(value, mask, shift);
		i++;
	}

	va_end(ap);

	return value;
}

uint32_t generic_indirect_reg_update_ex(const struct dc_context *ctx,
		uint32_t addr_index, uint32_t addr_data,
+12 −4
Original line number Diff line number Diff line
@@ -589,14 +589,22 @@
 *			Gamut Remap Mode: [10..9]
 */
#define CM_TEST_DEBUG_DATA_STATUS_IDX 9
#define CM_TEST_DEBUG_DATA_ICSC_MODE_SH 3
#define CM_TEST_DEBUG_DATA_ICSC_MODE_MASK 0x3
#define CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE_SH 9
#define CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE_MASK 0x3

#define TF_DEBUG_REG_LIST_SH_DCN20 \
	TF_DEBUG_REG_LIST_SH_DCN10, \
	.CM_TEST_DEBUG_DATA_ICSC_MODE = 3, \
	.CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE = 9

#define TF_DEBUG_REG_LIST_MASK_DCN20 \
	TF_DEBUG_REG_LIST_MASK_DCN10, \
	.CM_TEST_DEBUG_DATA_ICSC_MODE = 0x18, \
	.CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE = 0x600

#define TF_REG_FIELD_LIST_DCN2_0(type) \
	TF_REG_FIELD_LIST(type) \
	type CM_BLNDGAM_LUT_DATA; \
	type CM_TEST_DEBUG_DATA_ICSC_MODE; \
	type CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE; \
	type FORMAT_CNV16; \
	type CNVC_BYPASS_MSB_ALIGN; \
	type CLAMP_POSITIVE; \
+6 −12
Original line number Diff line number Diff line
@@ -176,12 +176,9 @@ static void program_gamut_remap(
	 * currently. select the alternate set to double buffer
	 * the update so gamut_remap is updated on frame boundary
	 */
	cur_select = IX_REG_READ(CM_TEST_DEBUG_INDEX, CM_TEST_DEBUG_DATA,
					CM_TEST_DEBUG_DATA_STATUS_IDX);

	/* IX_REG_READ reads whole reg, so isolate part we want [10..9] */
	cur_select = (cur_select >> CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE_SH)
					& CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE_MASK;
	IX_REG_GET(CM_TEST_DEBUG_INDEX, CM_TEST_DEBUG_DATA,
					CM_TEST_DEBUG_DATA_STATUS_IDX,
					CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE, &cur_select);

	/* value stored in dbg reg will be 1 greater than mode we want */
	if (cur_select != DCN2_GAMUT_REMAP_COEF_A)
@@ -275,12 +272,9 @@ void dpp2_program_input_csc(
	 * currently.  select the alternate set to double buffer
	 * the CSC update so CSC is updated on frame boundary
	 */
	cur_select = IX_REG_READ(CM_TEST_DEBUG_INDEX, CM_TEST_DEBUG_DATA,
					CM_TEST_DEBUG_DATA_STATUS_IDX);

	/* IX_REG_READ reads whole reg, so isolate part we want [4..3] */
	cur_select = (cur_select >> CM_TEST_DEBUG_DATA_ICSC_MODE_SH)
					& CM_TEST_DEBUG_DATA_ICSC_MODE_MASK;
	IX_REG_GET(CM_TEST_DEBUG_INDEX, CM_TEST_DEBUG_DATA,
					CM_TEST_DEBUG_DATA_STATUS_IDX,
					CM_TEST_DEBUG_DATA_ICSC_MODE, &cur_select);

	if (cur_select != DCN2_ICSC_SELECT_ICSC_A)
		select = DCN2_ICSC_SELECT_ICSC_A;
+6 −10
Original line number Diff line number Diff line
@@ -153,11 +153,9 @@ void mpc2_set_output_csc(
	 * currently.  select the alternate set to double buffer
	 * the CSC update so CSC is updated on frame boundary
	 */
	cur_mode = IX_REG_READ(MPC_OCSC_TEST_DEBUG_INDEX, MPC_OCSC_TEST_DEBUG_DATA,
						MPC_OCSC_TEST_DEBUG_DATA_STATUS_IDX);

	/* Isolate part of reg data we want [1..0] */
	cur_mode = cur_mode & MPC_OCSC_TEST_DEBUG_DATA_OCSC_MODE_MASK;
	IX_REG_GET(MPC_OCSC_TEST_DEBUG_INDEX, MPC_OCSC_TEST_DEBUG_DATA,
						MPC_OCSC_TEST_DEBUG_DATA_STATUS_IDX,
						MPC_OCSC_TEST_DEBUG_DATA_OCSC_MODE, &cur_mode);

	if (cur_mode != MPC_OUTPUT_CSC_COEF_A)
		ocsc_mode = MPC_OUTPUT_CSC_COEF_A;
@@ -213,11 +211,9 @@ void mpc2_set_ocsc_default(
	 * currently.  select the alternate set to double buffer
	 * the CSC update so CSC is updated on frame boundary
	 */
	cur_mode = IX_REG_READ(MPC_OCSC_TEST_DEBUG_INDEX, MPC_OCSC_TEST_DEBUG_DATA,
						MPC_OCSC_TEST_DEBUG_DATA_STATUS_IDX);

	/* Isolate part of reg data we want [1..0] */
	cur_mode = cur_mode & MPC_OCSC_TEST_DEBUG_DATA_OCSC_MODE_MASK;
	IX_REG_GET(MPC_OCSC_TEST_DEBUG_INDEX, MPC_OCSC_TEST_DEBUG_DATA,
						MPC_OCSC_TEST_DEBUG_DATA_STATUS_IDX,
						MPC_OCSC_TEST_DEBUG_DATA_OCSC_MODE, &cur_mode);

	if (cur_mode != MPC_OUTPUT_CSC_COEF_A)
		ocsc_mode = MPC_OUTPUT_CSC_COEF_A;
+7 −3
Original line number Diff line number Diff line
@@ -140,7 +140,6 @@
	SF(MPCC0_MPCC_TOP_GAIN, MPCC_TOP_GAIN, mask_sh),\
	SF(MPCC0_MPCC_BOT_GAIN_INSIDE, MPCC_BOT_GAIN_INSIDE, mask_sh),\
	SF(MPCC0_MPCC_BOT_GAIN_OUTSIDE, MPCC_BOT_GAIN_OUTSIDE, mask_sh),\
	SF(MPC_OCSC_TEST_DEBUG_DATA, MPC_OCSC_TEST_DEBUG_DATA, mask_sh),\
	SF(MPC_OCSC_TEST_DEBUG_INDEX, MPC_OCSC_TEST_DEBUG_INDEX, mask_sh),\
	SF(MPC_OUT0_CSC_MODE, MPC_OCSC_MODE, mask_sh),\
	SF(MPC_OUT0_CSC_C11_C12_A, MPC_OCSC_C11_A, mask_sh),\
@@ -189,7 +188,12 @@
 *			OCSC Mode: [1..0]
 */
#define MPC_OCSC_TEST_DEBUG_DATA_STATUS_IDX 1
#define MPC_OCSC_TEST_DEBUG_DATA_OCSC_MODE_MASK 0x3

#define MPC_DEBUG_REG_LIST_SH_DCN20 \
	.MPC_OCSC_TEST_DEBUG_DATA_OCSC_MODE = 0

#define MPC_DEBUG_REG_LIST_MASK_DCN20 \
	.MPC_OCSC_TEST_DEBUG_DATA_OCSC_MODE = 0x3

#define MPC_REG_FIELD_LIST_DCN2_0(type) \
	MPC_REG_FIELD_LIST(type)\
@@ -198,7 +202,7 @@
	type MPCC_TOP_GAIN;\
	type MPCC_BOT_GAIN_INSIDE;\
	type MPCC_BOT_GAIN_OUTSIDE;\
	type MPC_OCSC_TEST_DEBUG_DATA;\
	type MPC_OCSC_TEST_DEBUG_DATA_OCSC_MODE;\
	type MPC_OCSC_TEST_DEBUG_INDEX;\
	type MPC_OCSC_MODE;\
	type MPC_OCSC_C11_A;\
Loading