summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/display/dc
diff options
context:
space:
mode:
authorMeenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com>2021-01-22 01:25:56 -0500
committerAlex Deucher <alexander.deucher@amd.com>2021-03-02 14:05:41 -0500
commit4f8e37dbaf584de6d38f58b3000b0bfd7eaf2ff6 (patch)
tree1cd598f900ac8effb15f285dcae76430de079a42 /drivers/gpu/drm/amd/display/dc
parentc524c1c9a78f12137da0447e085411cbbd89ab0b (diff)
downloadlinux-4f8e37dbaf584de6d38f58b3000b0bfd7eaf2ff6.tar.bz2
drm/amd/display: Support for DMUB AUX
[WHY] To process AUX transactions with DMUB using inbox1 and outbox1 mail boxes. [HOW] 1) Added inbox1 command DMUB_CMD__DP_AUX_ACCESS to issue AUX commands to DMUB in dc_process_dmub_aux_transfer_async(). DMUB processes AUX cmd with DCN and sends reply back in an outbox1 message triggering an outbox1 interrupt to driver. 2) In existing driver implementation, AUX commands are processed synchronously by configuring DCN reg. But in DMUB AUX, driver sends an inbox1 message and waits for a conditional variable (CV) which will be signaled by outbox1 ISR. 3) As the driver holds dal and dc locks while waiting for CV, the outbox1 ISR is registered with noMutexWait set to true, which allows ISR to run and signal CV. This sets a constraint on ISR to not modify variables such as dc, dmub, etc. 4) Created dmub_outbox.c with dmub_enable_outbox_notification() to enable outbox1 mailbox. 5) New mailbox address ranges allocated for outbox1 of size DMUB_RB_SIZE. Created dmub functions for Outbox1: dmub_dcn20_setup_out_mailbox(), dmub_dcn20_get_outbox1_wptr() and dmub_dcn20_set_outbox1_rptr(). 6) Added functions dc_stat_get_dmub_notification() and dmub_srv_stat_get_notification() to retrieve Outbox1 message. 7) Currently, DMUB doesn't opens DDC in AUX mode before issuing AUX transaction. A workaround is added in dce_aux_transfer_dmub_raw() to open in DDC in AUX mode for every AUX transaction. 8) Added dc debug option enable_dmub_aux_for_legacy_ddc enable/disable DMUB AUX. This debug option is checked dce_aux_transfer_with_retries() to select the method to process AUX transactions. Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com> Reviewed-by: Jun Lei <Jun.Lei@amd.com> Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc')
-rw-r--r--drivers/gpu/drm/amd/display/dc/Makefile2
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc.c94
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_stat.c64
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc.h12
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_ddc_types.h10
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_stat.h42
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/Makefile2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_aux.c40
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_aux.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dmub_outbox.c60
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dmub_outbox.h33
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c5
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/aux_engine.h4
-rw-r--r--drivers/gpu/drm/amd/display/dc/irq_types.h2
16 files changed, 344 insertions, 35 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/Makefile b/drivers/gpu/drm/amd/display/dc/Makefile
index 5bf2f2375b40..bbde6e6a4e43 100644
--- a/drivers/gpu/drm/amd/display/dc/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/Makefile
@@ -54,7 +54,7 @@ AMD_DC = $(addsuffix /Makefile, $(addprefix $(FULL_AMD_DISPLAY_PATH)/dc/,$(DC_LI
include $(AMD_DC)
-DISPLAY_CORE = dc.o dc_link.o dc_resource.o dc_hw_sequencer.o dc_sink.o \
+DISPLAY_CORE = dc.o dc_stat.o dc_link.o dc_resource.o dc_hw_sequencer.o dc_sink.o \
dc_surface.o dc_link_hwss.o dc_link_dp.o dc_link_ddc.o dc_debug.o dc_stream.o
ifdef CONFIG_DRM_AMD_DC_DCN
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 8a873af5ff42..1cdef90c03aa 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -68,6 +68,7 @@
#include "dmub/dmub_srv.h"
+#include "i2caux_interface.h"
#include "dce/dmub_hw_lock_mgr.h"
#include "dc_trace.h"
@@ -3190,3 +3191,96 @@ void dc_hardware_release(struct dc *dc)
dc->hwss.hardware_release(dc);
}
#endif
+
+/**
+ *****************************************************************************
+ * Function: dc_enable_dmub_notifications
+ *
+ * @brief
+ * Returns whether dmub notification can be enabled
+ *
+ * @param
+ * [in] dc: dc structure
+ *
+ * @return
+ * True to enable dmub notifications, False otherwise
+ *****************************************************************************
+ */
+bool dc_enable_dmub_notifications(struct dc *dc)
+{
+ /* dmub aux needs dmub notifications to be enabled */
+ return dc->debug.enable_dmub_aux_for_legacy_ddc;
+}
+
+/**
+ *****************************************************************************
+ * Function: dc_process_dmub_aux_transfer_async
+ *
+ * @brief
+ * Submits aux command to dmub via inbox message
+ * Sets port index appropriately for legacy DDC
+ *
+ * @param
+ * [in] dc: dc structure
+ * [in] link_index: link index
+ * [in] payload: aux payload
+ *
+ * @return
+ * True if successful, False if failure
+ *****************************************************************************
+ */
+bool dc_process_dmub_aux_transfer_async(struct dc *dc,
+ uint32_t link_index,
+ struct aux_payload *payload)
+{
+ uint8_t action;
+ union dmub_rb_cmd cmd = {0};
+ struct dc_dmub_srv *dmub_srv = dc->ctx->dmub_srv;
+
+ ASSERT(payload->length <= 16);
+
+ cmd.dp_aux_access.header.type = DMUB_CMD__DP_AUX_ACCESS;
+ cmd.dp_aux_access.header.payload_bytes = 0;
+ cmd.dp_aux_access.aux_control.type = AUX_CHANNEL_LEGACY_DDC;
+ cmd.dp_aux_access.aux_control.instance = dc->links[link_index]->ddc_hw_inst;
+ cmd.dp_aux_access.aux_control.sw_crc_enabled = 0;
+ cmd.dp_aux_access.aux_control.timeout = 0;
+ cmd.dp_aux_access.aux_control.dpaux.address = payload->address;
+ cmd.dp_aux_access.aux_control.dpaux.is_i2c_over_aux = payload->i2c_over_aux;
+ cmd.dp_aux_access.aux_control.dpaux.length = payload->length;
+
+ /* set aux action */
+ if (payload->i2c_over_aux) {
+ if (payload->write) {
+ if (payload->mot)
+ action = DP_AUX_REQ_ACTION_I2C_WRITE_MOT;
+ else
+ action = DP_AUX_REQ_ACTION_I2C_WRITE;
+ } else {
+ if (payload->mot)
+ action = DP_AUX_REQ_ACTION_I2C_READ_MOT;
+ else
+ action = DP_AUX_REQ_ACTION_I2C_READ;
+ }
+ } else {
+ if (payload->write)
+ action = DP_AUX_REQ_ACTION_DPCD_WRITE;
+ else
+ action = DP_AUX_REQ_ACTION_DPCD_READ;
+ }
+
+ cmd.dp_aux_access.aux_control.dpaux.action = action;
+
+ if (payload->length && payload->write) {
+ memcpy(cmd.dp_aux_access.aux_control.dpaux.data,
+ payload->data,
+ payload->length
+ );
+ }
+
+ dc_dmub_srv_cmd_queue(dmub_srv, &cmd);
+ dc_dmub_srv_cmd_execute(dmub_srv);
+ dc_dmub_srv_wait_idle(dmub_srv);
+
+ return true;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
index 42a4177e829a..64414c51312d 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
@@ -36,6 +36,7 @@
#include "core_types.h"
#include "dc_link_ddc.h"
#include "dce/dce_aux.h"
+#include "dmub/inc/dmub_cmd.h"
#define DC_LOGGER_INIT(logger)
@@ -655,7 +656,7 @@ bool dal_ddc_submit_aux_command(struct ddc_service *ddc,
*/
int dc_link_aux_transfer_raw(struct ddc_service *ddc,
struct aux_payload *payload,
- enum aux_channel_operation_result *operation_result)
+ enum aux_return_code_type *operation_result)
{
return dce_aux_transfer_raw(ddc, payload, operation_result);
}
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stat.c b/drivers/gpu/drm/amd/display/dc/core/dc_stat.c
new file mode 100644
index 000000000000..31761f3595a6
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stat.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2020 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ */
+
+#include "dc/dc_stat.h"
+#include "dmub/dmub_srv_stat.h"
+#include "dc_dmub_srv.h"
+
+/**
+ * DOC: DC STAT Interface
+ *
+ * These interfaces are called without acquiring DAL and DC locks.
+ * Hence, there is limitations on whese interfaces can access. Only
+ * variables exclusively defined for these interfaces can be modified.
+ */
+
+/**
+ *****************************************************************************
+ * Function: dc_stat_get_dmub_notification
+ *
+ * @brief
+ * Calls dmub layer to retrieve dmub notification
+ *
+ * @param
+ * [in] dc: dc structure
+ * [in] notify: dmub notification structure
+ *
+ * @return
+ * None
+ *****************************************************************************
+ */
+void dc_stat_get_dmub_notification(const struct dc *dc, struct dmub_notification *notify)
+{
+ /**
+ * This function is called without dal and dc locks, so
+ * we shall not modify any dc, dc_dmub_srv or dmub variables
+ * except variables exclusively accessed by this function
+ */
+ struct dmub_srv *dmub = dc->ctx->dmub_srv->dmub;
+ enum dmub_status status;
+
+ status = dmub_srv_stat_get_notification(dmub, notify);
+ ASSERT(status == DMUB_STATUS_OK);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index bd1cb665a585..49e055a8309c 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -42,6 +42,9 @@
#include "inc/hw/dmcu.h"
#include "dml/display_mode_lib.h"
+/* forward declaration */
+struct aux_payload;
+
#define DC_VER "3.2.124"
#define MAX_SURFACES 3
@@ -531,6 +534,9 @@ struct dc_debug_options {
bool enable_dram_clock_change_one_display_vactive;
union mem_low_power_enable_options enable_mem_low_power;
bool force_vblank_alignment;
+
+ /* Enable dmub aux for legacy ddc */
+ bool enable_dmub_aux_for_legacy_ddc;
};
struct dc_debug_data {
@@ -1293,6 +1299,12 @@ void dc_hardware_release(struct dc *dc);
bool dc_set_psr_allow_active(struct dc *dc, bool enable);
+bool dc_enable_dmub_notifications(struct dc *dc);
+
+bool dc_process_dmub_aux_transfer_async(struct dc *dc,
+ uint32_t link_index,
+ struct aux_payload *payload);
+
/*******************************************************************************
* DSC Interfaces
******************************************************************************/
diff --git a/drivers/gpu/drm/amd/display/dc/dc_ddc_types.h b/drivers/gpu/drm/amd/display/dc/dc_ddc_types.h
index 4f8f576d5fcf..7769bd099a5a 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_ddc_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_ddc_types.h
@@ -44,16 +44,6 @@ enum i2caux_transaction_action {
I2CAUX_TRANSACTION_ACTION_DP_READ = 0x90
};
-enum aux_channel_operation_result {
- AUX_CHANNEL_OPERATION_SUCCEEDED,
- AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN,
- AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY,
- AUX_CHANNEL_OPERATION_FAILED_TIMEOUT,
- AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON,
- AUX_CHANNEL_OPERATION_FAILED_ENGINE_ACQUIRE
-};
-
-
struct aux_request_transaction_data {
enum aux_transaction_type type;
enum i2caux_transaction_action action;
diff --git a/drivers/gpu/drm/amd/display/dc/dc_stat.h b/drivers/gpu/drm/amd/display/dc/dc_stat.h
new file mode 100644
index 000000000000..2a000ba54ddb
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dc_stat.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2020 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef _DC_STAT_H_
+#define _DC_STAT_H_
+
+/**
+ * DOC: DC STAT Interface
+ *
+ * These interfaces are called without acquiring DAL and DC locks.
+ * Hence, there is limitations on whese interfaces can access. Only
+ * variables exclusively defined for these interfaces can be modified.
+ */
+
+#include "dc.h"
+#include "dmub/dmub_srv.h"
+
+void dc_stat_get_dmub_notification(const struct dc *dc, struct dmub_notification *notify);
+
+#endif /* _DC_STAT_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/dce/Makefile b/drivers/gpu/drm/amd/display/dc/dce/Makefile
index 973be8f9fd10..0d7db132a20f 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dce/Makefile
@@ -30,7 +30,7 @@ DCE = dce_audio.o dce_stream_encoder.o dce_link_encoder.o dce_hwseq.o \
dce_mem_input.o dce_clock_source.o dce_scl_filters.o dce_transform.o \
dce_opp.o dce_dmcu.o dce_abm.o dce_ipp.o dce_aux.o \
dce_i2c.o dce_i2c_hw.o dce_i2c_sw.o dmub_psr.o dmub_abm.o dce_panel_cntl.o \
-dmub_hw_lock_mgr.o
+dmub_hw_lock_mgr.o dmub_outbox.o
AMD_DAL_DCE = $(addprefix $(AMDDALPATH)/dc/dce/,$(DCE))
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
index d51b5fe91287..87d57e81de12 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
@@ -31,6 +31,8 @@
#include "dce_aux.h"
#include "dce/dce_11_0_sh_mask.h"
#include "dm_event_log.h"
+#include "dm_helpers.h"
+#include "dmub/inc/dmub_cmd.h"
#define CTX \
aux110->base.ctx
@@ -324,7 +326,7 @@ static int read_channel_reply(struct dce_aux *engine, uint32_t size,
return 0;
}
-static enum aux_channel_operation_result get_channel_status(
+static enum aux_return_code_type get_channel_status(
struct dce_aux *engine,
uint8_t *returned_bytes)
{
@@ -335,7 +337,7 @@ static enum aux_channel_operation_result get_channel_status(
if (returned_bytes == NULL) {
/*caller pass NULL pointer*/
ASSERT_CRITICAL(false);
- return AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN;
+ return AUX_RET_ERROR_UNKNOWN;
}
*returned_bytes = 0;
@@ -346,7 +348,7 @@ static enum aux_channel_operation_result get_channel_status(
value = REG_READ(AUX_SW_STATUS);
/* in case HPD is LOW, exit AUX transaction */
if ((value & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK))
- return AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON;
+ return AUX_RET_ERROR_HPD_DISCON;
/* Note that the following bits are set in 'status.bits'
* during CTS 4.2.1.2 (FW 3.3.1):
@@ -359,14 +361,14 @@ static enum aux_channel_operation_result get_channel_status(
if (value & AUX_SW_STATUS__AUX_SW_DONE_MASK) {
if ((value & AUX_SW_STATUS__AUX_SW_RX_TIMEOUT_STATE_MASK) ||
(value & AUX_SW_STATUS__AUX_SW_RX_TIMEOUT_MASK))
- return AUX_CHANNEL_OPERATION_FAILED_TIMEOUT;
+ return AUX_RET_ERROR_TIMEOUT;
else if ((value & AUX_SW_STATUS__AUX_SW_RX_INVALID_STOP_MASK) ||
(value & AUX_SW_STATUS__AUX_SW_RX_RECV_NO_DET_MASK) ||
(value &
AUX_SW_STATUS__AUX_SW_RX_RECV_INVALID_H_MASK) ||
(value & AUX_SW_STATUS__AUX_SW_RX_RECV_INVALID_L_MASK))
- return AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY;
+ return AUX_RET_ERROR_INVALID_REPLY;
*returned_bytes = get_reg_field_value(value,
AUX_SW_STATUS,
@@ -374,17 +376,17 @@ static enum aux_channel_operation_result get_channel_status(
if (*returned_bytes == 0)
return
- AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY;
+ AUX_RET_ERROR_INVALID_REPLY;
else {
*returned_bytes -= 1;
- return AUX_CHANNEL_OPERATION_SUCCEEDED;
+ return AUX_RET_SUCCESS;
}
} else {
/*time_elapsed >= aux_engine->timeout_period
* AUX_SW_STATUS__AUX_SW_HPD_DISCON = at this point
*/
ASSERT_CRITICAL(false);
- return AUX_CHANNEL_OPERATION_FAILED_TIMEOUT;
+ return AUX_RET_ERROR_TIMEOUT;
}
}
@@ -541,7 +543,7 @@ static enum i2caux_transaction_action i2caux_action_from_payload(struct aux_payl
int dce_aux_transfer_raw(struct ddc_service *ddc,
struct aux_payload *payload,
- enum aux_channel_operation_result *operation_result)
+ enum aux_return_code_type *operation_result)
{
struct ddc *ddc_pin = ddc->ddc_pin;
struct dce_aux *aux_engine;
@@ -556,7 +558,7 @@ int dce_aux_transfer_raw(struct ddc_service *ddc,
aux_engine = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en];
if (!acquire(aux_engine, ddc_pin)) {
- *operation_result = AUX_CHANNEL_OPERATION_FAILED_ENGINE_ACQUIRE;
+ *operation_result = AUX_RET_ERROR_ENGINE_ACQUIRE;
return -1;
}
@@ -575,8 +577,9 @@ int dce_aux_transfer_raw(struct ddc_service *ddc,
submit_channel_request(aux_engine, &aux_req);
*operation_result = get_channel_status(aux_engine, &returned_bytes);
- if (*operation_result == AUX_CHANNEL_OPERATION_SUCCEEDED) {
+ if (*operation_result == AUX_RET_SUCCESS) {
int __maybe_unused bytes_replied = 0;
+
bytes_replied = read_channel_reply(aux_engine, payload->length,
payload->data, payload->reply,
&status);
@@ -604,7 +607,7 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
int i, ret = 0;
uint8_t reply;
bool payload_reply = true;
- enum aux_channel_operation_result operation_result;
+ enum aux_return_code_type operation_result;
bool retry_on_defer = false;
int aux_ack_retries = 0,
@@ -620,8 +623,9 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
for (i = 0; i < AUX_MAX_RETRIES; i++) {
ret = dce_aux_transfer_raw(ddc, payload, &operation_result);
+
switch (operation_result) {
- case AUX_CHANNEL_OPERATION_SUCCEEDED:
+ case AUX_RET_SUCCESS:
aux_timeout_retries = 0;
aux_invalid_reply_retries = 0;
@@ -667,14 +671,14 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
}
break;
- case AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY:
+ case AUX_RET_ERROR_INVALID_REPLY:
if (++aux_invalid_reply_retries >= AUX_MAX_INVALID_REPLY_RETRIES)
goto fail;
else
udelay(400);
break;
- case AUX_CHANNEL_OPERATION_FAILED_TIMEOUT:
+ case AUX_RET_ERROR_TIMEOUT:
// Check whether a DEFER had occurred before the timeout.
// If so, treat timeout as a DEFER.
if (retry_on_defer) {
@@ -696,9 +700,9 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
}
break;
- case AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON:
- case AUX_CHANNEL_OPERATION_FAILED_ENGINE_ACQUIRE:
- case AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN:
+ case AUX_RET_ERROR_HPD_DISCON:
+ case AUX_RET_ERROR_ENGINE_ACQUIRE:
+ case AUX_RET_ERROR_UNKNOWN:
default:
goto fail;
}
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h
index 277484cf853e..775e24926380 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h
@@ -29,6 +29,7 @@
#include "i2caux_interface.h"
#include "inc/hw/aux_engine.h"
+enum aux_return_code_type;
#define AUX_COMMON_REG_LIST0(id)\
SRI(AUX_CONTROL, DP_AUX, id), \
@@ -302,7 +303,7 @@ bool dce110_aux_engine_acquire(
int dce_aux_transfer_raw(struct ddc_service *ddc,
struct aux_payload *cmd,
- enum aux_channel_operation_result *operation_result);
+ enum aux_return_code_type *operation_result);
bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
struct aux_payload *cmd);
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_outbox.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_outbox.c
new file mode 100644
index 000000000000..295596d1f47f
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_outbox.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2020 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ */
+
+#include "dmub_outbox.h"
+#include "dc_dmub_srv.h"
+#include "dmub/inc/dmub_cmd.h"
+
+/**
+ *****************************************************************************
+ * Function: dmub_enable_outbox_notification
+ *
+ * @brief
+ * Sends inbox cmd to dmub to enable outbox1 messages with interrupt.
+ * Dmub sends outbox1 message and triggers outbox1 interrupt.
+ *
+ * @param
+ * [in] dc: dc structure
+ *
+ * @return
+ * None
+ *****************************************************************************
+ */
+void dmub_enable_outbox_notification(struct dc *dc)
+{
+ union dmub_rb_cmd cmd;
+ struct dc_context *dc_ctx = dc->ctx;
+
+ memset(&cmd, 0x0, sizeof(cmd));
+ cmd.outbox1_enable.header.type = DMUB_CMD__OUTBOX1_ENABLE;
+ cmd.outbox1_enable.header.sub_type = 0;
+ cmd.outbox1_enable.header.payload_bytes =
+ sizeof(cmd.outbox1_enable) -
+ sizeof(cmd.outbox1_enable.header);
+ cmd.outbox1_enable.enable = true;
+
+ dc_dmub_srv_cmd_queue(dc_ctx->dmub_srv, &cmd);
+ dc_dmub_srv_cmd_execute(dc_ctx->dmub_srv);
+ dc_dmub_srv_wait_idle(dc_ctx->dmub_srv);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_outbox.h b/drivers/gpu/drm/amd/display/dc/dce/dmub_outbox.h
new file mode 100644
index 000000000000..4e0aa0d1a2d5
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_outbox.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2020 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef _DMUB_OUTBOX_H_
+#define _DMUB_OUTBOX_H_
+
+#include "dc.h"
+
+void dmub_enable_outbox_notification(struct dc *dc);
+
+#endif /* _DMUB_OUTBOX_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
index 72b845911dcf..74c2edae08f2 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
@@ -53,6 +53,7 @@
#include "dsc.h"
#include "dce/dmub_hw_lock_mgr.h"
#include "dc_trace.h"
+#include "dce/dmub_outbox.h"
#define DC_LOGGER_INIT(logger)
@@ -1355,6 +1356,10 @@ void dcn10_init_hw(struct dc *dc)
hws->funcs.dsc_pg_control(hws, res_pool->dscs[i]->inst, false);
}
+ /* Enable outbox notification feature of dmub */
+ if (dc->debug.enable_dmub_aux_for_legacy_ddc)
+ dmub_enable_outbox_notification(dc);
+
/* we want to turn off all dp displays before doing detection */
if (dc->config.power_down_display_on_boot) {
uint8_t dpcd_power_state = '\0';
diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h
index b324e13f3f78..4d7b271b6409 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h
@@ -56,6 +56,7 @@ struct dp_receiver_id_info;
struct i2c_payloads;
struct aux_payloads;
+enum aux_return_code_type;
void dal_ddc_i2c_payloads_add(
struct i2c_payloads *payloads,
@@ -100,7 +101,7 @@ bool dal_ddc_submit_aux_command(struct ddc_service *ddc,
int dc_link_aux_transfer_raw(struct ddc_service *ddc,
struct aux_payload *payload,
- enum aux_channel_operation_result *operation_result);
+ enum aux_return_code_type *operation_result);
bool dc_link_aux_transfer_with_retries(struct ddc_service *ddc,
struct aux_payload *payload);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/aux_engine.h b/drivers/gpu/drm/amd/display/dc/inc/hw/aux_engine.h
index e77b3a76766d..2ae630bf2aee 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/aux_engine.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/aux_engine.h
@@ -29,6 +29,8 @@
#include "dc_ddc_types.h"
#include "include/i2caux_interface.h"
+enum aux_return_code_type;
+
enum i2caux_transaction_operation {
I2CAUX_TRANSACTION_READ,
I2CAUX_TRANSACTION_WRITE
@@ -162,7 +164,7 @@ struct aux_engine_funcs {
uint8_t *buffer,
uint8_t *reply_result,
uint32_t *sw_status);
- enum aux_channel_operation_result (*get_channel_status)(
+ enum aux_return_code_type (*get_channel_status)(
struct aux_engine *engine,
uint8_t *returned_bytes);
bool (*is_engine_available)(struct aux_engine *engine);
diff --git a/drivers/gpu/drm/amd/display/dc/irq_types.h b/drivers/gpu/drm/amd/display/dc/irq_types.h
index 87812d81fed3..125b9beb505a 100644
--- a/drivers/gpu/drm/amd/display/dc/irq_types.h
+++ b/drivers/gpu/drm/amd/display/dc/irq_types.h
@@ -150,7 +150,7 @@ enum dc_irq_source {
DC_IRQ_SOURCE_DC4_VLINE1,
DC_IRQ_SOURCE_DC5_VLINE1,
DC_IRQ_SOURCE_DC6_VLINE1,
-
+ DC_IRQ_DMCUB_OUTBOX1,
DAL_IRQ_SOURCES_NUMBER
};