Commit ad6756b4 authored by David Francis's avatar David Francis Committed by Alex Deucher
Browse files

drm/amd/display: Shift dc link aux to aux_payload



[Why]
aux_payload should be the struct used inside dc to start
aux transactions.  This will allow the old aux interface
to be seamlessly replaced.

[How]
Add three fields to aux_payload: reply, mot, defer_delay
This will mean that aux_payload has all data required
to submit a request.  Shift dc_link to use this struct

Signed-off-by: default avatarDavid Francis <David.Francis@amd.com>
Reviewed-by: default avatarHarry Wentland <Harry.Wentland@amd.com>
Acked-by: default avatarLeo Li <sunpeng.li@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent bbba9831
Loading
Loading
Loading
Loading
+15 −69
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@

#include "dc_link_ddc.h"

#include "i2caux_interface.h"

/* #define TRACE_DPCD */

#ifdef TRACE_DPCD
@@ -81,80 +83,24 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
				  struct drm_dp_aux_msg *msg)
{
	ssize_t result = 0;
	enum i2caux_transaction_action action;
	enum aux_transaction_type type;
	struct aux_payload payload;

	if (WARN_ON(msg->size > 16))
		return -E2BIG;

	switch (msg->request & ~DP_AUX_I2C_MOT) {
	case DP_AUX_NATIVE_READ:
		type = AUX_TRANSACTION_TYPE_DP;
		action = I2CAUX_TRANSACTION_ACTION_DP_READ;

		result = dc_link_aux_transfer(TO_DM_AUX(aux)->ddc_service,
					      msg->address,
					      &msg->reply,
					      msg->buffer,
					      msg->size,
					      type,
					      action);
		break;
	case DP_AUX_NATIVE_WRITE:
		type = AUX_TRANSACTION_TYPE_DP;
		action = I2CAUX_TRANSACTION_ACTION_DP_WRITE;

		dc_link_aux_transfer(TO_DM_AUX(aux)->ddc_service,
				     msg->address,
				     &msg->reply,
				     msg->buffer,
				     msg->size,
				     type,
				     action);
		result = msg->size;
		break;
	case DP_AUX_I2C_READ:
		type = AUX_TRANSACTION_TYPE_I2C;
		if (msg->request & DP_AUX_I2C_MOT)
			action = I2CAUX_TRANSACTION_ACTION_I2C_READ_MOT;
		else
			action = I2CAUX_TRANSACTION_ACTION_I2C_READ;

		result = dc_link_aux_transfer(TO_DM_AUX(aux)->ddc_service,
					      msg->address,
					      &msg->reply,
					      msg->buffer,
					      msg->size,
					      type,
					      action);
		break;
	case DP_AUX_I2C_WRITE:
		type = AUX_TRANSACTION_TYPE_I2C;
		if (msg->request & DP_AUX_I2C_MOT)
			action = I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT;
		else
			action = I2CAUX_TRANSACTION_ACTION_I2C_WRITE;

		dc_link_aux_transfer(TO_DM_AUX(aux)->ddc_service,
				     msg->address,
				     &msg->reply,
				     msg->buffer,
				     msg->size,
				     type,
				     action);
		result = msg->size;
		break;
	default:
		return -EINVAL;
	}
	payload.address = msg->address;
	payload.data = msg->buffer;
	payload.length = msg->size;
	payload.reply = &msg->reply;
	payload.i2c_over_aux = (msg->request & DP_AUX_NATIVE_WRITE) == 0;
	payload.write = (msg->request & DP_AUX_I2C_READ) == 0;
	payload.mot = (msg->request & DP_AUX_I2C_MOT) != 0;
	payload.defer_delay = 0;

#ifdef TRACE_DPCD
	log_dpcd(msg->request,
		 msg->address,
		 msg->buffer,
		 msg->size,
		 r == DDC_RESULT_SUCESSFULL);
#endif
	result = dc_link_aux_transfer(TO_DM_AUX(aux)->ddc_service, &payload);

	if (payload.write)
		result = msg->size;

	if (result < 0) /* DC doesn't know about kernel error codes */
		result = -EIO;
+39 −18
Original line number Diff line number Diff line
@@ -229,7 +229,9 @@ void dal_ddc_aux_payloads_add(
	uint32_t address,
	uint32_t len,
	uint8_t *data,
	bool write)
	bool write,
	bool mot,
	uint32_t defer_delay)
{
	uint32_t payload_size = DEFAULT_AUX_MAX_DATA_SIZE;
	uint32_t pos;
@@ -240,7 +242,10 @@ void dal_ddc_aux_payloads_add(
			.write = write,
			.address = address,
			.length = DDC_MIN(payload_size, len - pos),
			.data = data + pos };
			.data = data + pos,
			.reply = NULL,
			.mot = mot,
			.defer_delay = defer_delay};
		dal_vector_append(&payloads->payloads, &payload);
	}
}
@@ -584,10 +589,10 @@ bool dal_ddc_service_query_ddc_data(
			.max_defer_write_retry = 0 };

		dal_ddc_aux_payloads_add(
			payloads, address, write_size, write_buf, true);
			payloads, address, write_size, write_buf, true, true, get_defer_delay(ddc));

		dal_ddc_aux_payloads_add(
			payloads, address, read_size, read_buf, false);
			payloads, address, read_size, read_buf, false, false, get_defer_delay(ddc));

		command.number_of_payloads =
			dal_ddc_aux_payloads_get_count(payloads);
@@ -629,13 +634,25 @@ bool dal_ddc_service_query_ddc_data(
	return ret;
}

static enum i2caux_transaction_action i2caux_action_from_payload(struct aux_payload *payload)
{
	if (payload->i2c_over_aux) {
		if (payload->write) {
			if (payload->mot)
				return I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT;
			return I2CAUX_TRANSACTION_ACTION_I2C_WRITE;
		}
		if (payload->mot)
			return I2CAUX_TRANSACTION_ACTION_I2C_READ_MOT;
		return I2CAUX_TRANSACTION_ACTION_I2C_READ;
	}
	if (payload->write)
		return I2CAUX_TRANSACTION_ACTION_DP_WRITE;
	return I2CAUX_TRANSACTION_ACTION_DP_READ;
}

int dc_link_aux_transfer(struct ddc_service *ddc,
			     unsigned int address,
			     uint8_t *reply,
			     void *buffer,
			     unsigned int size,
			     enum aux_transaction_type type,
			     enum i2caux_transaction_action action)
		struct aux_payload *payload)
{
	struct ddc *ddc_pin = ddc->ddc_pin;
	struct aux_engine *aux_engine;
@@ -652,21 +669,25 @@ int dc_link_aux_transfer(struct ddc_service *ddc,
	aux_engine = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en];
	aux_engine->funcs->acquire(aux_engine, ddc_pin);

	aux_req.type = type;
	aux_req.action = action;
	if (payload->i2c_over_aux)
		aux_req.type = AUX_TRANSACTION_TYPE_I2C;
	else
		aux_req.type = AUX_TRANSACTION_TYPE_DP;

	aux_req.action = i2caux_action_from_payload(payload);

	aux_req.address = address;
	aux_req.delay = 0;
	aux_req.length = size;
	aux_req.data = buffer;
	aux_req.address = payload->address;
	aux_req.delay = payload->defer_delay * 10;
	aux_req.length = payload->length;
	aux_req.data = payload->data;

	aux_engine->funcs->submit_channel_request(aux_engine, &aux_req);
	operation_result = aux_engine->funcs->get_channel_status(aux_engine, &returned_bytes);

	switch (operation_result) {
	case AUX_CHANNEL_OPERATION_SUCCEEDED:
		res = aux_engine->funcs->read_channel_reply(aux_engine, size,
							buffer, reply,
		res = aux_engine->funcs->read_channel_reply(aux_engine, payload->length,
							payload->data, payload->reply,
							&status);
		break;
	case AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON:
+2 −1
Original line number Diff line number Diff line
@@ -273,6 +273,7 @@ static int read_channel_reply(struct aux_engine *engine, uint32_t size,

	REG_GET(AUX_SW_DATA, AUX_SW_DATA, &reply_result_32);
	reply_result_32 = reply_result_32 >> 4;
	if (reply_result != NULL)
		*reply_result = (uint8_t)reply_result_32;

	if (reply_result_32 == 0) { /* ACK */
+4 −7
Original line number Diff line number Diff line
@@ -69,7 +69,9 @@ void dal_ddc_aux_payloads_add(
		uint32_t address,
		uint32_t len,
		uint8_t *data,
		bool write);
		bool write,
		bool mot,
		uint32_t defer_delay);

struct ddc_service_init_data {
	struct graphics_object_id id;
@@ -103,12 +105,7 @@ bool dal_ddc_service_query_ddc_data(
		uint32_t read_size);

int dc_link_aux_transfer(struct ddc_service *ddc,
			     unsigned int address,
			     uint8_t *reply,
			     void *buffer,
			     unsigned int size,
			     enum aux_transaction_type type,
			     enum i2caux_transaction_action action);
		struct aux_payload *payload);

void dal_ddc_service_write_scdc_data(
		struct ddc_service *ddc_service,
+10 −0
Original line number Diff line number Diff line
@@ -40,9 +40,19 @@ struct aux_payload {
	/* set following flag to write data,
	 * reset it to read data */
	bool write;
	bool mot;
	uint32_t address;
	uint8_t length;
	uint8_t *data;
	/*
	 * used to return the reply type of the transaction
	 * ignored if NULL
	 */
	uint8_t *reply;
	/* expressed in milliseconds
	 * zero means "use default value"
	 */
	uint32_t defer_delay;
};

struct aux_command {