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

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
...@@ -35,6 +35,8 @@ ...@@ -35,6 +35,8 @@
#include "dc_link_ddc.h" #include "dc_link_ddc.h"
#include "i2caux_interface.h"
/* #define TRACE_DPCD */ /* #define TRACE_DPCD */
#ifdef TRACE_DPCD #ifdef TRACE_DPCD
...@@ -81,80 +83,24 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, ...@@ -81,80 +83,24 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
struct drm_dp_aux_msg *msg) struct drm_dp_aux_msg *msg)
{ {
ssize_t result = 0; ssize_t result = 0;
enum i2caux_transaction_action action; struct aux_payload payload;
enum aux_transaction_type type;
if (WARN_ON(msg->size > 16)) if (WARN_ON(msg->size > 16))
return -E2BIG; return -E2BIG;
switch (msg->request & ~DP_AUX_I2C_MOT) { payload.address = msg->address;
case DP_AUX_NATIVE_READ: payload.data = msg->buffer;
type = AUX_TRANSACTION_TYPE_DP; payload.length = msg->size;
action = I2CAUX_TRANSACTION_ACTION_DP_READ; payload.reply = &msg->reply;
payload.i2c_over_aux = (msg->request & DP_AUX_NATIVE_WRITE) == 0;
result = dc_link_aux_transfer(TO_DM_AUX(aux)->ddc_service, payload.write = (msg->request & DP_AUX_I2C_READ) == 0;
msg->address, payload.mot = (msg->request & DP_AUX_I2C_MOT) != 0;
&msg->reply, payload.defer_delay = 0;
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;
}
#ifdef TRACE_DPCD result = dc_link_aux_transfer(TO_DM_AUX(aux)->ddc_service, &payload);
log_dpcd(msg->request,
msg->address, if (payload.write)
msg->buffer, result = msg->size;
msg->size,
r == DDC_RESULT_SUCESSFULL);
#endif
if (result < 0) /* DC doesn't know about kernel error codes */ if (result < 0) /* DC doesn't know about kernel error codes */
result = -EIO; result = -EIO;
......
...@@ -229,7 +229,9 @@ void dal_ddc_aux_payloads_add( ...@@ -229,7 +229,9 @@ void dal_ddc_aux_payloads_add(
uint32_t address, uint32_t address,
uint32_t len, uint32_t len,
uint8_t *data, uint8_t *data,
bool write) bool write,
bool mot,
uint32_t defer_delay)
{ {
uint32_t payload_size = DEFAULT_AUX_MAX_DATA_SIZE; uint32_t payload_size = DEFAULT_AUX_MAX_DATA_SIZE;
uint32_t pos; uint32_t pos;
...@@ -240,7 +242,10 @@ void dal_ddc_aux_payloads_add( ...@@ -240,7 +242,10 @@ void dal_ddc_aux_payloads_add(
.write = write, .write = write,
.address = address, .address = address,
.length = DDC_MIN(payload_size, len - pos), .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); dal_vector_append(&payloads->payloads, &payload);
} }
} }
...@@ -584,10 +589,10 @@ bool dal_ddc_service_query_ddc_data( ...@@ -584,10 +589,10 @@ bool dal_ddc_service_query_ddc_data(
.max_defer_write_retry = 0 }; .max_defer_write_retry = 0 };
dal_ddc_aux_payloads_add( 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( 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 = command.number_of_payloads =
dal_ddc_aux_payloads_get_count(payloads); dal_ddc_aux_payloads_get_count(payloads);
...@@ -629,13 +634,25 @@ bool dal_ddc_service_query_ddc_data( ...@@ -629,13 +634,25 @@ bool dal_ddc_service_query_ddc_data(
return ret; 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, int dc_link_aux_transfer(struct ddc_service *ddc,
unsigned int address, struct aux_payload *payload)
uint8_t *reply,
void *buffer,
unsigned int size,
enum aux_transaction_type type,
enum i2caux_transaction_action action)
{ {
struct ddc *ddc_pin = ddc->ddc_pin; struct ddc *ddc_pin = ddc->ddc_pin;
struct aux_engine *aux_engine; struct aux_engine *aux_engine;
...@@ -652,21 +669,25 @@ int dc_link_aux_transfer(struct ddc_service *ddc, ...@@ -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 = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en];
aux_engine->funcs->acquire(aux_engine, ddc_pin); aux_engine->funcs->acquire(aux_engine, ddc_pin);
aux_req.type = type; if (payload->i2c_over_aux)
aux_req.action = action; 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.address = payload->address;
aux_req.delay = 0; aux_req.delay = payload->defer_delay * 10;
aux_req.length = size; aux_req.length = payload->length;
aux_req.data = buffer; aux_req.data = payload->data;
aux_engine->funcs->submit_channel_request(aux_engine, &aux_req); aux_engine->funcs->submit_channel_request(aux_engine, &aux_req);
operation_result = aux_engine->funcs->get_channel_status(aux_engine, &returned_bytes); operation_result = aux_engine->funcs->get_channel_status(aux_engine, &returned_bytes);
switch (operation_result) { switch (operation_result) {
case AUX_CHANNEL_OPERATION_SUCCEEDED: case AUX_CHANNEL_OPERATION_SUCCEEDED:
res = aux_engine->funcs->read_channel_reply(aux_engine, size, res = aux_engine->funcs->read_channel_reply(aux_engine, payload->length,
buffer, reply, payload->data, payload->reply,
&status); &status);
break; break;
case AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON: case AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON:
......
...@@ -273,7 +273,8 @@ static int read_channel_reply(struct aux_engine *engine, uint32_t size, ...@@ -273,7 +273,8 @@ static int read_channel_reply(struct aux_engine *engine, uint32_t size,
REG_GET(AUX_SW_DATA, AUX_SW_DATA, &reply_result_32); REG_GET(AUX_SW_DATA, AUX_SW_DATA, &reply_result_32);
reply_result_32 = reply_result_32 >> 4; reply_result_32 = reply_result_32 >> 4;
*reply_result = (uint8_t)reply_result_32; if (reply_result != NULL)
*reply_result = (uint8_t)reply_result_32;
if (reply_result_32 == 0) { /* ACK */ if (reply_result_32 == 0) { /* ACK */
uint32_t i = 0; uint32_t i = 0;
......
...@@ -69,7 +69,9 @@ void dal_ddc_aux_payloads_add( ...@@ -69,7 +69,9 @@ void dal_ddc_aux_payloads_add(
uint32_t address, uint32_t address,
uint32_t len, uint32_t len,
uint8_t *data, uint8_t *data,
bool write); bool write,
bool mot,
uint32_t defer_delay);
struct ddc_service_init_data { struct ddc_service_init_data {
struct graphics_object_id id; struct graphics_object_id id;
...@@ -103,12 +105,7 @@ bool dal_ddc_service_query_ddc_data( ...@@ -103,12 +105,7 @@ bool dal_ddc_service_query_ddc_data(
uint32_t read_size); uint32_t read_size);
int dc_link_aux_transfer(struct ddc_service *ddc, int dc_link_aux_transfer(struct ddc_service *ddc,
unsigned int address, struct aux_payload *payload);
uint8_t *reply,
void *buffer,
unsigned int size,
enum aux_transaction_type type,
enum i2caux_transaction_action action);
void dal_ddc_service_write_scdc_data( void dal_ddc_service_write_scdc_data(
struct ddc_service *ddc_service, struct ddc_service *ddc_service,
......
...@@ -40,9 +40,19 @@ struct aux_payload { ...@@ -40,9 +40,19 @@ struct aux_payload {
/* set following flag to write data, /* set following flag to write data,
* reset it to read data */ * reset it to read data */
bool write; bool write;
bool mot;
uint32_t address; uint32_t address;
uint8_t length; uint8_t length;
uint8_t *data; 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 { struct aux_command {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment