return result;
}
+
+enum dc_edid_status dm_helpers_read_local_edid(
+ struct dc_context *ctx,
+ struct dc_link *link,
+ struct dc_sink *sink)
+{
+ struct amdgpu_connector *aconnector = link->priv;
+ struct i2c_adapter *ddc;
+ int retry = 3;
+ enum dc_edid_status edid_status;
+ struct edid *edid;
+
+ if (link->aux_mode)
+ ddc = &aconnector->dm_dp_aux.aux.ddc;
+ else
+ ddc = &aconnector->i2c->base;
+
+ /* some dongles read edid incorrectly the first time,
+ * do check sum and retry to make sure read correct edid.
+ */
+ do {
+
+ edid = drm_get_edid(&aconnector->base, ddc);
+
+ if (!edid)
+ return EDID_NO_RESPONSE;
+
+ sink->dc_edid.length = EDID_LENGTH * (edid->extensions + 1);
+ memmove(sink->dc_edid.raw_edid, (uint8_t *)edid, sink->dc_edid.length);
+
+ /* We don't need the original edid anymore */
+ kfree(edid);
+
+ edid_status = dm_helpers_parse_edid_caps(
+ ctx,
+ &sink->dc_edid,
+ &sink->edid_caps);
+
+ } while (edid_status == EDID_BAD_CHECKSUM && --retry > 0);
+
+ if (edid_status != EDID_OK)
+ DRM_ERROR("EDID err: %d, on connector: %s",
+ edid_status,
+ aconnector->base.name);
+
+ return edid_status;
+}
struct drm_device *drm_dev = pci_get_drvdata(pdev);
struct amdgpu_device *adev = drm_dev->dev_private;
struct dc *dc = adev->dm.dc;
+ enum i2c_mot_mode mot = (msg->request & DP_AUX_I2C_MOT) ? I2C_MOT_TRUE : I2C_MOT_FALSE;
bool res;
- switch (msg->request) {
+ switch (msg->request & ~DP_AUX_I2C_MOT) {
case DP_AUX_NATIVE_READ:
- res = dc_read_dpcd(
- dc,
- TO_DM_AUX(aux)->link_index,
- msg->address,
- msg->buffer,
- msg->size);
+ res = dc_read_aux_dpcd(
+ dc,
+ TO_DM_AUX(aux)->link_index,
+ msg->address,
+ msg->buffer,
+ msg->size);
break;
case DP_AUX_NATIVE_WRITE:
- res = dc_write_dpcd(
- dc,
- TO_DM_AUX(aux)->link_index,
- msg->address,
- msg->buffer,
- msg->size);
+ res = dc_write_aux_dpcd(
+ dc,
+ TO_DM_AUX(aux)->link_index,
+ msg->address,
+ msg->buffer,
+ msg->size);
+ break;
+ case DP_AUX_I2C_READ:
+ res = dc_read_aux_i2c(
+ dc,
+ TO_DM_AUX(aux)->link_index,
+ mot,
+ msg->address,
+ msg->buffer,
+ msg->size);
+ break;
+ case DP_AUX_I2C_WRITE:
+ res = dc_write_aux_i2c(
+ dc,
+ TO_DM_AUX(aux)->link_index,
+ mot,
+ msg->address,
+ msg->buffer,
+ msg->size);
break;
default:
return 0;
.register_connector = dm_dp_mst_register_connector
};
-void amdgpu_dm_initialize_mst_connector(
+void amdgpu_dm_initialize_dp_connector(
struct amdgpu_display_manager *dm,
struct amdgpu_connector *aconnector)
{
struct amdgpu_display_manager;
struct amdgpu_connector;
-void amdgpu_dm_initialize_mst_connector(
+void amdgpu_dm_initialize_dp_connector(
struct amdgpu_display_manager *dm,
struct amdgpu_connector *aconnector);
if (connector_type == DRM_MODE_CONNECTOR_DisplayPort
|| connector_type == DRM_MODE_CONNECTOR_eDP)
- amdgpu_dm_initialize_mst_connector(dm, aconnector);
+ amdgpu_dm_initialize_dp_connector(dm, aconnector);
#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) ||\
defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
uint8_t dpcd_data;
bool capable = false;
if (amdgpu_connector->dc_link &&
- dc_read_dpcd(dc, amdgpu_connector->dc_link->link_index,
- DP_DOWN_STREAM_PORT_COUNT,
- &dpcd_data, sizeof(dpcd_data)) )
+ dc_read_aux_dpcd(
+ dc,
+ amdgpu_connector->dc_link->link_index,
+ DP_DOWN_STREAM_PORT_COUNT,
+ &dpcd_data, sizeof(dpcd_data)))
capable = (dpcd_data & DP_MSA_TIMING_PAR_IGNORED) ? true:false;
return capable;
core_link_resume(core_dc->links[i]);
}
-bool dc_read_dpcd(
+bool dc_read_aux_dpcd(
struct dc *dc,
uint32_t link_index,
uint32_t address,
struct core_link *link = core_dc->links[link_index];
enum ddc_result r = dal_ddc_service_read_dpcd_data(
link->ddc,
+ false,
+ I2C_MOT_UNDEF,
address,
data,
size);
return r == DDC_RESULT_SUCESSFULL;
}
-bool dc_query_ddc_data(
+bool dc_write_aux_dpcd(
struct dc *dc,
uint32_t link_index,
uint32_t address,
- uint8_t *write_buf,
- uint32_t write_size,
- uint8_t *read_buf,
- uint32_t read_size) {
-
+ const uint8_t *data,
+ uint32_t size)
+{
struct core_dc *core_dc = DC_TO_CORE(dc);
-
struct core_link *link = core_dc->links[link_index];
- bool result = dal_ddc_service_query_ddc_data(
+ enum ddc_result r = dal_ddc_service_write_dpcd_data(
link->ddc,
+ false,
+ I2C_MOT_UNDEF,
address,
- write_buf,
- write_size,
- read_buf,
- read_size);
-
- return result;
+ data,
+ size);
+ return r == DDC_RESULT_SUCESSFULL;
}
+bool dc_read_aux_i2c(
+ struct dc *dc,
+ uint32_t link_index,
+ enum i2c_mot_mode mot,
+ uint32_t address,
+ uint8_t *data,
+ uint32_t size)
+{
+ struct core_dc *core_dc = DC_TO_CORE(dc);
-bool dc_write_dpcd(
+ struct core_link *link = core_dc->links[link_index];
+ enum ddc_result r = dal_ddc_service_read_dpcd_data(
+ link->ddc,
+ true,
+ mot,
+ address,
+ data,
+ size);
+ return r == DDC_RESULT_SUCESSFULL;
+}
+
+bool dc_write_aux_i2c(
struct dc *dc,
uint32_t link_index,
+ enum i2c_mot_mode mot,
uint32_t address,
const uint8_t *data,
uint32_t size)
{
struct core_dc *core_dc = DC_TO_CORE(dc);
-
struct core_link *link = core_dc->links[link_index];
enum ddc_result r = dal_ddc_service_write_dpcd_data(
link->ddc,
+ true,
+ mot,
address,
data,
size);
return r == DDC_RESULT_SUCESSFULL;
}
+bool dc_query_ddc_data(
+ struct dc *dc,
+ uint32_t link_index,
+ uint32_t address,
+ uint8_t *write_buf,
+ uint32_t write_size,
+ uint8_t *read_buf,
+ uint32_t read_size) {
+
+ struct core_dc *core_dc = DC_TO_CORE(dc);
+
+ struct core_link *link = core_dc->links[link_index];
+
+ bool result = dal_ddc_service_query_ddc_data(
+ link->ddc,
+ address,
+ write_buf,
+ write_size,
+ read_buf,
+ read_size);
+
+ return result;
+}
+
bool dc_submit_i2c(
struct dc *dc,
uint32_t link_index,
link->dpcd_sink_count = 0;
}
-static enum dc_edid_status read_edid(
- struct core_link *link,
- struct core_sink *sink)
-{
- uint32_t edid_retry = 3;
- enum dc_edid_status edid_status;
-
- /* some dongles read edid incorrectly the first time,
- * do check sum and retry to make sure read correct edid.
- */
- do {
- sink->public.dc_edid.length =
- dal_ddc_service_edid_query(link->ddc);
-
- if (0 == sink->public.dc_edid.length)
- return EDID_NO_RESPONSE;
-
- dal_ddc_service_get_edid_buf(link->ddc,
- sink->public.dc_edid.raw_edid);
- edid_status = dm_helpers_parse_edid_caps(
- sink->ctx,
- &sink->public.dc_edid,
- &sink->public.edid_caps);
- --edid_retry;
- if (edid_status == EDID_BAD_CHECKSUM)
- dm_logger_write(link->ctx->logger, LOG_WARNING,
- "Bad EDID checksum, retry remain: %d\n",
- edid_retry);
- } while (edid_status == EDID_BAD_CHECKSUM && edid_retry > 0);
-
- return edid_status;
-}
-
static void detect_dp(
struct core_link *link,
struct display_sink_capability *sink_caps,
link->ddc,
sink_caps.transaction_type);
+ link->public.aux_mode = dal_ddc_service_is_in_aux_transaction_mode(
+ link->ddc);
+
sink_init_data.link = &link->public;
sink_init_data.sink_signal = sink_caps.signal;
sink = DC_SINK_TO_CORE(dc_sink);
link->public.local_sink = &sink->public;
- edid_status = read_edid(link, sink);
+ edid_status = dm_helpers_read_local_edid(
+ link->ctx,
+ &link->public,
+ &sink->public);
switch (edid_status) {
case EDID_BAD_CHECKSUM:
*/
psr_configuration.bits.IRQ_HPD_WITH_CRC_ERROR = 1;
}
- dal_ddc_service_write_dpcd_data(
- link->ddc,
- 368,
- &psr_configuration.raw,
- sizeof(psr_configuration.raw));
+
+ dm_helpers_dp_write_dpcd(
+ link->ctx,
+ dc_link,
+ 368,
+ &psr_configuration.raw,
+ sizeof(psr_configuration.raw));
psr_context.channel = link->ddc->ddc_pin->hw_info.ddc_channel;
if (psr_context.channel == 0)
uint8_t eot;/* end of transmition '\x4' */
};
-/* Address range from 0x00 to 0x1F.*/
-#define DP_ADAPTOR_TYPE2_SIZE 0x20
-#define DP_ADAPTOR_TYPE2_REG_ID 0x10
-#define DP_ADAPTOR_TYPE2_REG_MAX_TMDS_CLK 0x1D
-/* Identifies adaptor as Dual-mode adaptor */
-#define DP_ADAPTOR_TYPE2_ID 0xA0
-/* MHz*/
-#define DP_ADAPTOR_TYPE2_MAX_TMDS_CLK 600
-/* MHz*/
-#define DP_ADAPTOR_TYPE2_MIN_TMDS_CLK 25
-/* kHZ*/
-#define DP_ADAPTOR_DVI_MAX_TMDS_CLK 165000
-/* kHZ*/
-#define DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK 165000
-
-#define DDC_I2C_COMMAND_ENGINE I2C_COMMAND_ENGINE_SW
-
-enum edid_read_result {
- EDID_READ_RESULT_EDID_MATCH = 0,
- EDID_READ_RESULT_EDID_MISMATCH,
- EDID_READ_RESULT_CHECKSUM_READ_ERR,
- EDID_READ_RESULT_VENDOR_READ_ERR
-};
-
/* SCDC Address defines (HDMI 2.0)*/
#define HDMI_SCDC_WRITE_UPDATE_0_ARRAY 3
#define HDMI_SCDC_ADDRESS 0x54
#define DP_TRANSLATOR_DELAY 5
-static uint32_t get_defer_delay(struct ddc_service *ddc)
+uint32_t get_defer_delay(struct ddc_service *ddc)
{
uint32_t defer_delay = 0;
&command);
}
-static uint8_t aux_read_edid_block(
- struct ddc_service *ddc,
- uint8_t address,
- uint8_t index,
- uint8_t *buf)
-{
- struct aux_command cmd = {
- .payloads = NULL,
- .number_of_payloads = 0,
- .defer_delay = get_defer_delay(ddc),
- .max_defer_write_retry = 0 };
-
- uint8_t retrieved = 0;
- uint8_t base_offset =
- (index % DDC_EDID_BLOCKS_PER_SEGMENT) * DDC_EDID_BLOCK_SIZE;
- uint8_t segment = index / DDC_EDID_BLOCKS_PER_SEGMENT;
-
- for (retrieved = 0; retrieved < DDC_EDID_BLOCK_SIZE;
- retrieved += DEFAULT_AUX_MAX_DATA_SIZE) {
-
- uint8_t offset = base_offset + retrieved;
-
- struct aux_payload payloads[3] = {
- {
- .i2c_over_aux = true,
- .write = true,
- .address = DDC_EDID_SEGMENT_ADDRESS,
- .length = 1,
- .data = &segment },
- {
- .i2c_over_aux = true,
- .write = true,
- .address = address,
- .length = 1,
- .data = &offset },
- {
- .i2c_over_aux = true,
- .write = false,
- .address = address,
- .length = DEFAULT_AUX_MAX_DATA_SIZE,
- .data = &buf[retrieved] } };
-
- if (segment == 0) {
- cmd.payloads = &payloads[1];
- cmd.number_of_payloads = 2;
- } else {
- cmd.payloads = payloads;
- cmd.number_of_payloads = 3;
- }
-
- if (!dal_i2caux_submit_aux_command(
- ddc->ctx->i2caux,
- ddc->ddc_pin,
- &cmd))
- /* cannot read, break*/
- break;
- }
-
- /* Reset segment to 0. Needed by some panels */
- if (0 != segment) {
- struct aux_payload payloads[1] = { {
- .i2c_over_aux = true,
- .write = true,
- .address = DDC_EDID_SEGMENT_ADDRESS,
- .length = 1,
- .data = &segment } };
- bool result = false;
-
- segment = 0;
-
- cmd.number_of_payloads = ARRAY_SIZE(payloads);
- cmd.payloads = payloads;
-
- result = dal_i2caux_submit_aux_command(
- ddc->ctx->i2caux,
- ddc->ddc_pin,
- &cmd);
-
- if (false == result)
- dm_logger_write(
- ddc->ctx->logger, LOG_ERROR,
- "%s: Writing of EDID Segment (0x30) failed!\n",
- __func__);
- }
-
- return retrieved;
-}
-
-static uint8_t i2c_read_edid_block(
- struct ddc_service *ddc,
- uint8_t address,
- uint8_t index,
- uint8_t *buf)
-{
- bool ret = false;
- uint8_t offset = (index % DDC_EDID_BLOCKS_PER_SEGMENT) *
- DDC_EDID_BLOCK_SIZE;
- uint8_t segment = index / DDC_EDID_BLOCKS_PER_SEGMENT;
-
- struct i2c_command cmd = {
- .payloads = NULL,
- .number_of_payloads = 0,
- .engine = DDC_I2C_COMMAND_ENGINE,
- .speed = ddc->ctx->dc->caps.i2c_speed_in_khz };
-
- struct i2c_payload payloads[3] = {
- {
- .write = true,
- .address = DDC_EDID_SEGMENT_ADDRESS,
- .length = 1,
- .data = &segment },
- {
- .write = true,
- .address = address,
- .length = 1,
- .data = &offset },
- {
- .write = false,
- .address = address,
- .length = DDC_EDID_BLOCK_SIZE,
- .data = buf } };
-/*
- * Some I2C engines don't handle stop/start between write-offset and read-data
- * commands properly. For those displays, we have to force the newer E-DDC
- * behavior of repeated-start which can be enabled by runtime parameter. */
-/* Originally implemented for OnLive using NXP receiver chip */
-
- if (index == 0 && !ddc->flags.FORCE_READ_REPEATED_START) {
- /* base block, use use DDC2B, submit as 2 commands */
- cmd.payloads = &payloads[1];
- cmd.number_of_payloads = 1;
-
- if (dm_helpers_submit_i2c(
- ddc->ctx,
- &ddc->link->public,
- &cmd)) {
-
- cmd.payloads = &payloads[2];
- cmd.number_of_payloads = 1;
-
- ret = dm_helpers_submit_i2c(
- ddc->ctx,
- &ddc->link->public,
- &cmd);
- }
-
- } else {
- /*
- * extension block use E-DDC, submit as 1 command
- * or if repeated-start is forced by runtime parameter
- */
- if (segment != 0) {
- /* include segment offset in command*/
- cmd.payloads = payloads;
- cmd.number_of_payloads = 3;
- } else {
- /* we are reading first segment,
- * segment offset is not required */
- cmd.payloads = &payloads[1];
- cmd.number_of_payloads = 2;
- }
-
- ret = dm_helpers_submit_i2c(
- ddc->ctx,
- &ddc->link->public,
- &cmd);
- }
-
- return ret ? DDC_EDID_BLOCK_SIZE : 0;
-}
-
-static uint32_t query_edid_block(
- struct ddc_service *ddc,
- uint8_t address,
- uint8_t index,
- uint8_t *buf,
- uint32_t size)
-{
- uint32_t size_retrieved = 0;
-
- if (size < DDC_EDID_BLOCK_SIZE)
- return 0;
-
- if (dal_ddc_service_is_in_aux_transaction_mode(ddc)) {
- size_retrieved =
- aux_read_edid_block(ddc, address, index, buf);
- } else {
- size_retrieved =
- i2c_read_edid_block(ddc, address, index, buf);
- }
-
- return size_retrieved;
-}
-
-#define DDC_DPCD_EDID_CHECKSUM_WRITE_ADDRESS 0x261
-#define DDC_TEST_ACK_ADDRESS 0x260
-#define DDC_DPCD_EDID_TEST_ACK 0x04
-#define DDC_DPCD_EDID_TEST_MASK 0x04
-#define DDC_DPCD_TEST_REQUEST_ADDRESS 0x218
-
-/* AG TODO GO throug DM callback here like for DPCD */
-
-static void write_dp_edid_checksum(
- struct ddc_service *ddc,
- uint8_t checksum)
-{
- uint8_t dpcd_data;
-
- dal_ddc_service_read_dpcd_data(
- ddc,
- DDC_DPCD_TEST_REQUEST_ADDRESS,
- &dpcd_data,
- 1);
-
- if (dpcd_data & DDC_DPCD_EDID_TEST_MASK) {
-
- dal_ddc_service_write_dpcd_data(
- ddc,
- DDC_DPCD_EDID_CHECKSUM_WRITE_ADDRESS,
- &checksum,
- 1);
-
- dpcd_data = DDC_DPCD_EDID_TEST_ACK;
-
- dal_ddc_service_write_dpcd_data(
- ddc,
- DDC_TEST_ACK_ADDRESS,
- &dpcd_data,
- 1);
- }
-}
-
-uint32_t dal_ddc_service_edid_query(struct ddc_service *ddc)
-{
- uint32_t bytes_read = 0;
- uint32_t ext_cnt = 0;
-
- uint8_t address;
- uint32_t i;
-
- for (address = DDC_EDID_ADDRESS_START;
- address <= DDC_EDID_ADDRESS_END; ++address) {
-
- bytes_read = query_edid_block(
- ddc,
- address,
- 0,
- ddc->edid_buf,
- sizeof(ddc->edid_buf) - bytes_read);
-
- if (bytes_read != DDC_EDID_BLOCK_SIZE)
- continue;
-
- /* get the number of ext blocks*/
- ext_cnt = ddc->edid_buf[DDC_EDID_EXT_COUNT_OFFSET];
-
- /* EDID 2.0, need to read 1 more block because EDID2.0 is
- * 256 byte in size*/
- if (ddc->edid_buf[DDC_EDID_20_SIGNATURE_OFFSET] ==
- DDC_EDID_20_SIGNATURE)
- ext_cnt = 1;
-
- for (i = 0; i < ext_cnt; i++) {
- /* read additional ext blocks accordingly */
- bytes_read += query_edid_block(
- ddc,
- address,
- i+1,
- &ddc->edid_buf[bytes_read],
- sizeof(ddc->edid_buf) - bytes_read);
- }
-
- /*this is special code path for DP compliance*/
- if (DDC_TRANSACTION_TYPE_I2C_OVER_AUX == ddc->transaction_type)
- write_dp_edid_checksum(
- ddc,
- ddc->edid_buf[(ext_cnt * DDC_EDID_BLOCK_SIZE) +
- DDC_EDID1X_CHECKSUM_OFFSET]);
-
- /*remembers the address where we fetch the EDID from
- * for later signature check use */
- ddc->address = address;
-
- break;/* already read edid, done*/
- }
-
- ddc->edid_buf_len = bytes_read;
- return bytes_read;
-}
-
-uint32_t dal_ddc_service_get_edid_buf_len(struct ddc_service *ddc)
-{
- return ddc->edid_buf_len;
-}
-
-void dal_ddc_service_get_edid_buf(struct ddc_service *ddc, uint8_t *edid_buf)
-{
- memmove(edid_buf,
- ddc->edid_buf, ddc->edid_buf_len);
-}
-
void dal_ddc_service_i2c_query_dp_dual_mode_adaptor(
struct ddc_service *ddc,
struct display_sink_capability *sink_cap)
enum ddc_result dal_ddc_service_read_dpcd_data(
struct ddc_service *ddc,
+ bool i2c,
+ enum i2c_mot_mode mot,
uint32_t address,
uint8_t *data,
uint32_t len)
{
struct aux_payload read_payload = {
- .i2c_over_aux = false,
+ .i2c_over_aux = i2c,
.write = false,
.address = address,
.length = len,
.number_of_payloads = 1,
.defer_delay = 0,
.max_defer_write_retry = 0,
+ .mot = mot
};
if (len > DEFAULT_AUX_MAX_DATA_SIZE) {
enum ddc_result dal_ddc_service_write_dpcd_data(
struct ddc_service *ddc,
+ bool i2c,
+ enum i2c_mot_mode mot,
uint32_t address,
const uint8_t *data,
uint32_t len)
{
struct aux_payload write_payload = {
- .i2c_over_aux = false,
+ .i2c_over_aux = i2c,
.write = true,
.address = address,
.length = len,
.number_of_payloads = 1,
.defer_delay = 0,
.max_defer_write_retry = 0,
+ .mot = mot
};
if (len > DEFAULT_AUX_MAX_DATA_SIZE) {
if (link->public.psr_caps.psr_version == 0)
return false;
- dal_ddc_service_read_dpcd_data(
- link->ddc,
- 368 /*DpcdAddress_PSR_Enable_Cfg*/,
- &psr_configuration.raw,
- sizeof(psr_configuration.raw));
+ dm_helpers_dp_read_dpcd(
+ link->ctx,
+ &link->public,
+ 368,/*DpcdAddress_PSR_Enable_Cfg*/
+ &psr_configuration.raw,
+ sizeof(psr_configuration.raw));
+
if (psr_configuration.bits.ENABLE) {
unsigned char dpcdbuf[3] = {0};
union psr_error_status psr_error_status;
union psr_sink_psr_status psr_sink_psr_status;
- dal_ddc_service_read_dpcd_data(
- link->ddc,
- 0x2006 /*DpcdAddress_PSR_Error_Status*/,
- (unsigned char *) dpcdbuf,
- sizeof(dpcdbuf));
+ dm_helpers_dp_read_dpcd(
+ link->ctx,
+ &link->public,
+ 0x2006, /*DpcdAddress_PSR_Error_Status*/
+ (unsigned char *) dpcdbuf,
+ sizeof(dpcdbuf));
/*DPCD 2006h ERROR STATUS*/
psr_error_status.raw = dpcdbuf[0];
if (psr_error_status.bits.LINK_CRC_ERROR ||
psr_error_status.bits.RFB_STORAGE_ERROR) {
/* Acknowledge and clear error bits */
- dal_ddc_service_write_dpcd_data(
- link->ddc,
- 8198 /*DpcdAddress_PSR_Error_Status*/,
+ dm_helpers_dp_write_dpcd(
+ link->ctx,
+ &link->public,
+ 8198,/*DpcdAddress_PSR_Error_Status*/
&psr_error_status.raw,
sizeof(psr_error_status.raw));
union compliance_test_state compliance_test_state;
void *priv;
+ bool aux_mode;
};
struct dpcd_caps {
* DPCD access interfaces
*/
-bool dc_read_dpcd(
+bool dc_read_aux_dpcd(
struct dc *dc,
uint32_t link_index,
uint32_t address,
uint8_t *data,
uint32_t size);
-bool dc_write_dpcd(
+bool dc_write_aux_dpcd(
struct dc *dc,
uint32_t link_index,
uint32_t address,
const uint8_t *data,
uint32_t size);
+bool dc_read_aux_i2c(
+ struct dc *dc,
+ uint32_t link_index,
+ enum i2c_mot_mode mot,
+ uint32_t address,
+ uint8_t *data,
+ uint32_t size);
+
+bool dc_write_aux_i2c(
+ struct dc *dc,
+ uint32_t link_index,
+ enum i2c_mot_mode mot,
+ uint32_t address,
+ const uint8_t *data,
+ uint32_t size);
+
bool dc_query_ddc_data(
struct dc *dc,
uint32_t link_index,
unsigned int psr_sdp_transmit_line_num_deadline;
};
+enum i2c_mot_mode {
+ I2C_MOT_UNDEF,
+ I2C_MOT_TRUE,
+ I2C_MOT_FALSE
+};
+
#endif /* DC_TYPES_H_ */
struct i2c_command *cmd);
+
+
+
+
+enum dc_edid_status dm_helpers_read_local_edid(
+ struct dc_context *ctx,
+ struct dc_link *link,
+ struct dc_sink *sink);
+
+
#endif /* __DM_HELPERS__ */
struct aux_engine *engine;
uint8_t index_of_payload = 0;
bool result;
+ bool mot;
if (!ddc) {
BREAK_TO_DEBUGGER();
result = true;
while (index_of_payload < cmd->number_of_payloads) {
- bool mot = (index_of_payload != cmd->number_of_payloads - 1);
-
struct aux_payload *payload = cmd->payloads + index_of_payload;
-
struct i2caux_transaction_request request = { 0 };
+ if (cmd->mot == I2C_MOT_UNDEF)
+ mot = (index_of_payload != cmd->number_of_payloads - 1);
+ else
+ mot = (cmd->mot == I2C_MOT_TRUE);
+
request.operation = payload->write ?
I2CAUX_TRANSACTION_WRITE :
I2CAUX_TRANSACTION_READ;
#define EDID_SEGMENT_SIZE 256
+/* Address range from 0x00 to 0x1F.*/
+#define DP_ADAPTOR_TYPE2_SIZE 0x20
+#define DP_ADAPTOR_TYPE2_REG_ID 0x10
+#define DP_ADAPTOR_TYPE2_REG_MAX_TMDS_CLK 0x1D
+/* Identifies adaptor as Dual-mode adaptor */
+#define DP_ADAPTOR_TYPE2_ID 0xA0
+/* MHz*/
+#define DP_ADAPTOR_TYPE2_MAX_TMDS_CLK 600
+/* MHz*/
+#define DP_ADAPTOR_TYPE2_MIN_TMDS_CLK 25
+/* kHZ*/
+#define DP_ADAPTOR_DVI_MAX_TMDS_CLK 165000
+/* kHZ*/
+#define DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK 165000
+
+#define DDC_I2C_COMMAND_ENGINE I2C_COMMAND_ENGINE_SW
+
struct ddc_service;
struct graphics_object_id;
enum ddc_result;
bool dal_ddc_service_is_in_aux_transaction_mode(struct ddc_service *ddc);
-uint32_t dal_ddc_service_edid_query(struct ddc_service *ddc);
-
-uint32_t dal_ddc_service_get_edid_buf_len(struct ddc_service *ddc);
-
-void dal_ddc_service_get_edid_buf(struct ddc_service *ddc, uint8_t *edid_buf);
-
void dal_ddc_service_i2c_query_dp_dual_mode_adaptor(
struct ddc_service *ddc,
struct display_sink_capability *sink_cap);
enum ddc_result dal_ddc_service_read_dpcd_data(
struct ddc_service *ddc,
+ bool i2c,
+ enum i2c_mot_mode mot,
uint32_t address,
uint8_t *data,
uint32_t len);
enum ddc_result dal_ddc_service_write_dpcd_data(
struct ddc_service *ddc,
+ bool i2c,
+ enum i2c_mot_mode mot,
uint32_t address,
const uint8_t *data,
uint32_t len);
struct ddc *dal_ddc_service_get_ddc_pin(struct ddc_service *ddc_service);
-enum ddc_result dal_ddc_service_read_dpcd_data(
- struct ddc_service *ddc,
- uint32_t address,
- uint8_t *data,
- uint32_t len);
-enum ddc_result dal_ddc_service_write_dpcd_data(
- struct ddc_service *ddc,
- uint32_t address,
- const uint8_t *data,
- uint32_t len);
+uint32_t get_defer_delay(struct ddc_service *ddc);
#endif /* __DAL_DDC_SERVICE_H__ */
uint8_t aud_del_ins3;/* DPCD 0002Dh */
};
-/** EDID retrieval related constants, also used by MstMgr **/
-
-#define DDC_EDID_SEGMENT_SIZE 256
-#define DDC_EDID_BLOCK_SIZE 128
-#define DDC_EDID_BLOCKS_PER_SEGMENT \
- (DDC_EDID_SEGMENT_SIZE / DDC_EDID_BLOCK_SIZE)
-
-#define DDC_EDID_EXT_COUNT_OFFSET 0x7E
-
-#define DDC_EDID_ADDRESS_START 0x50
-#define DDC_EDID_ADDRESS_END 0x52
-#define DDC_EDID_SEGMENT_ADDRESS 0x30
-
-/* signatures for Edid 1x */
-#define DDC_EDID1X_VENDORID_SIGNATURE_OFFSET 8
-#define DDC_EDID1X_VENDORID_SIGNATURE_LEN 4
-#define DDC_EDID1X_EXT_CNT_AND_CHECKSUM_OFFSET 126
-#define DDC_EDID1X_EXT_CNT_AND_CHECKSUM_LEN 2
-#define DDC_EDID1X_CHECKSUM_OFFSET 127
-/* signatures for Edid 20*/
-#define DDC_EDID_20_SIGNATURE_OFFSET 0
-#define DDC_EDID_20_SIGNATURE 0x20
-
-#define DDC_EDID20_VENDORID_SIGNATURE_OFFSET 1
-#define DDC_EDID20_VENDORID_SIGNATURE_LEN 4
-#define DDC_EDID20_CHECKSUM_OFFSET 255
-#define DDC_EDID20_CHECKSUM_LEN 1
-
/*DP to VGA converter*/
static const uint8_t DP_VGA_CONVERTER_ID_1[] = "mVGAa";
/*DP to Dual link DVI converter*/
#ifndef __DAL_I2CAUX_INTERFACE_H__
#define __DAL_I2CAUX_INTERFACE_H__
+#include "dc_types.h"
#include "gpio_service_interface.h"
/* zero means "use default value" */
uint32_t max_defer_write_retry;
+
+ enum i2c_mot_mode mot;
};
union aux_config {