Commit f6040a43 authored by abdoulaye berthe's avatar abdoulaye berthe Committed by Alex Deucher
Browse files

drm/amd/display: configurable aux timeout support



[Description]
1-add configurable timeout support to aux engine.
2-add timeout support field to dc_caps
3-add reg_key to override extended timeout support

Signed-off-by: default avatarabdoulaye berthe <abdoulaye.berthe@amd.com>
Acked-by: default avatarBhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Reviewed-by: default avatarRoman Li <Roman.Li@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 8276dd87
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -634,6 +634,20 @@ bool dc_link_aux_transfer_with_retries(struct ddc_service *ddc,
	return dce_aux_transfer_with_retries(ddc, payload);
}


enum dc_status dc_link_aux_configure_timeout(struct ddc_service *ddc,
		uint32_t timeout)
{
	enum dc_status status = DC_OK;
	struct ddc *ddc_pin = ddc->ddc_pin;

	if (ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]->funcs->configure_timeout == NULL)
		return DC_ERROR_UNEXPECTED;
	if (!ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]->funcs->configure_timeout(ddc, timeout))
		status = DC_ERROR_UNEXPECTED;
	return status;
}

/*test only function*/
void dal_ddc_service_set_ddc_pin(
	struct ddc_service *ddc_service,
+2 −0
Original line number Diff line number Diff line
@@ -111,6 +111,7 @@ struct dc_caps {
	bool force_dp_tps4_for_cp2520;
	bool disable_dp_clk_share;
	bool psp_setup_panel_mode;
	bool extended_aux_timeout_support;
#ifdef CONFIG_DRM_AMD_DC_DCN2_0
	bool hw_3d_lut;
#endif
@@ -220,6 +221,7 @@ struct dc_config {
	bool power_down_display_on_boot;
	bool edp_not_connected;
	bool forced_clocks;
	bool disable_extended_timeout_support; // Used to disable extended timeout and lttpr feature as well
	bool multi_mon_pp_mclk_switch;
};

+69 −4
Original line number Diff line number Diff line
@@ -59,6 +59,14 @@ enum {
	AUX_TIMED_OUT_RETRY_COUNTER = 2,
	AUX_DEFER_RETRY_COUNTER = 6
};

#define TIME_OUT_INCREMENT      1016
#define TIME_OUT_MULTIPLIER_8 	8
#define TIME_OUT_MULTIPLIER_16  16
#define TIME_OUT_MULTIPLIER_32  32
#define TIME_OUT_MULTIPLIER_64  64
#define MAX_TIMEOUT_LENGTH      127

static void release_engine(
	struct dce_aux *engine)
{
@@ -202,7 +210,7 @@ static void submit_channel_request(
	REG_UPDATE(AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, 1);

	REG_WAIT(AUX_SW_STATUS, AUX_SW_DONE, 0,
				10, aux110->timeout_period/10);
				10, aux110->polling_timeout_period/10);

	/* set the delay and the number of bytes to write */

@@ -331,7 +339,7 @@ static enum aux_channel_operation_result get_channel_status(

	/* poll to make sure that SW_DONE is asserted */
	REG_WAIT(AUX_SW_STATUS, AUX_SW_DONE, 1,
				10, aux110->timeout_period/10);
				10, aux110->polling_timeout_period/10);

	value = REG_READ(AUX_SW_STATUS);
	/* in case HPD is LOW, exit AUX transaction */
@@ -419,24 +427,81 @@ void dce110_engine_destroy(struct dce_aux **engine)

}

static bool dce_aux_configure_timeout(struct ddc_service *ddc,
		uint32_t timeout_in_us)
{
	uint32_t multiplier = 0;
	uint32_t length = 0;
	uint32_t timeout = 0;
	struct ddc *ddc_pin = ddc->ddc_pin;
	struct dce_aux *aux_engine = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en];
	struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(aux_engine);

	/* 1-Update polling timeout period */
	aux110->polling_timeout_period = timeout_in_us * SW_AUX_TIMEOUT_PERIOD_MULTIPLIER;

	/* 2-Update aux timeout period length and multiplier */
	if (timeout_in_us <= TIME_OUT_INCREMENT) {
		multiplier = 0;
		length = timeout_in_us/TIME_OUT_MULTIPLIER_8;
		if (timeout_in_us % TIME_OUT_MULTIPLIER_8 != 0)
			length++;
		timeout = length * TIME_OUT_MULTIPLIER_8;
	} else if (timeout_in_us <= 2 * TIME_OUT_INCREMENT) {
		multiplier = 1;
		length = timeout_in_us/TIME_OUT_MULTIPLIER_16;
		if (timeout_in_us % TIME_OUT_MULTIPLIER_16 != 0)
			length++;
		timeout = length * TIME_OUT_MULTIPLIER_16;
	} else if (timeout_in_us <= 4 * TIME_OUT_INCREMENT) {
		multiplier = 2;
		length = timeout_in_us/TIME_OUT_MULTIPLIER_32;
		if (timeout_in_us % TIME_OUT_MULTIPLIER_32 != 0)
			length++;
		timeout = length * TIME_OUT_MULTIPLIER_32;
	} else if (timeout_in_us > 4 * TIME_OUT_INCREMENT) {
		multiplier = 3;
		length = timeout_in_us/TIME_OUT_MULTIPLIER_64;
		if (timeout_in_us % TIME_OUT_MULTIPLIER_64 != 0)
			length++;
		timeout = length * TIME_OUT_MULTIPLIER_64;
	}

	length = (length < MAX_TIMEOUT_LENGTH) ? length : MAX_TIMEOUT_LENGTH;

	REG_UPDATE_SEQ_2(AUX_DPHY_RX_CONTROL1, AUX_RX_TIMEOUT_LEN, length, AUX_RX_TIMEOUT_LEN_MUL, multiplier);

	return true;
}

static struct dce_aux_funcs aux_functions = {
	.configure_timeout = NULL,
	.destroy = NULL,
};

struct dce_aux *dce110_aux_engine_construct(struct aux_engine_dce110 *aux_engine110,
		struct dc_context *ctx,
		uint32_t inst,
		uint32_t timeout_period,
		const struct dce110_aux_registers *regs,
		const struct dce110_aux_registers_mask *mask,
		const struct dce110_aux_registers_shift *shift)
		const struct dce110_aux_registers_shift *shift,
		bool is_ext_aux_timeout_configurable)
{
	aux_engine110->base.ddc = NULL;
	aux_engine110->base.ctx = ctx;
	aux_engine110->base.delay = 0;
	aux_engine110->base.max_defer_write_retry = 0;
	aux_engine110->base.inst = inst;
	aux_engine110->timeout_period = timeout_period;
	aux_engine110->polling_timeout_period = timeout_period;
	aux_engine110->regs = regs;

	aux_engine110->mask = mask;
	aux_engine110->shift = shift;
	aux_engine110->base.funcs = &aux_functions;
	if (is_ext_aux_timeout_configurable)
		aux_engine110->base.funcs->configure_timeout = &dce_aux_configure_timeout;

	return &aux_engine110->base;
}

+13 −3
Original line number Diff line number Diff line
@@ -250,7 +250,7 @@ struct dce_aux {
	uint32_t max_defer_write_retry;

	bool acquire_reset;
	const struct dce_aux_funcs *funcs;
	struct dce_aux_funcs *funcs;
};

struct dce110_aux_registers_mask {
@@ -277,7 +277,7 @@ struct aux_engine_dce110 {
		uint32_t aux_dphy_rx_control0;
		uint32_t aux_sw_status;
	} addr;
	uint32_t timeout_period;
	uint32_t polling_timeout_period;
};

struct aux_engine_dce110_init_data {
@@ -294,7 +294,8 @@ struct dce_aux *dce110_aux_engine_construct(struct aux_engine_dce110 *aux_engine
		const struct dce110_aux_registers *regs,

		const struct dce110_aux_registers_mask *mask,
		const struct dce110_aux_registers_shift *shift);
		const struct dce110_aux_registers_shift *shift,
		bool is_ext_aux_timeout_configurable);

void dce110_engine_destroy(struct dce_aux **engine);

@@ -308,4 +309,13 @@ int dce_aux_transfer_raw(struct ddc_service *ddc,

bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
		struct aux_payload *cmd);

struct dce_aux_funcs {
	bool (*configure_timeout)
		(struct ddc_service *ddc,
		 uint32_t timeout);
	void (*destroy)
		(struct aux_engine **ptr);
};

#endif
+4 −1
Original line number Diff line number Diff line
@@ -621,7 +621,8 @@ struct dce_aux *dce100_aux_engine_create(
				    SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
				    &aux_engine_regs[inst],
					&aux_mask,
					&aux_shift);
					&aux_shift,
					ctx->dc->caps.extended_aux_timeout_support);

	return &aux_engine->base;
}
@@ -1007,6 +1008,8 @@ static bool construct(
	dc->caps.max_cursor_size = 128;
	dc->caps.dual_link_dvi = true;
	dc->caps.disable_dp_clk_share = true;
	dc->caps.extended_aux_timeout_support = false;

	for (i = 0; i < pool->base.pipe_count; i++) {
		pool->base.timing_generators[i] =
			dce100_timing_generator_create(
Loading