summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/display/dc
diff options
context:
space:
mode:
authorDave Airlie2017-11-16 03:39:40 +0100
committerDave Airlie2017-11-16 03:39:40 +0100
commit49e37ba07a3ae697086c0a1a32c113a1f177d138 (patch)
tree492fc0db4fc5d7b417cb9e6a39580bce0ccbc33a /drivers/gpu/drm/amd/display/dc
parentMerge branch 'drm-next-4.15-dc' of git://people.freedesktop.org/~agd5f/linux ... (diff)
parentdrm/amd/display: fix MST link training fail division by 0 (diff)
downloadkernel-qcow2-linux-49e37ba07a3ae697086c0a1a32c113a1f177d138.tar.gz
kernel-qcow2-linux-49e37ba07a3ae697086c0a1a32c113a1f177d138.tar.xz
kernel-qcow2-linux-49e37ba07a3ae697086c0a1a32c113a1f177d138.zip
Merge branch 'drm-next-4.15-dc' of git://people.freedesktop.org/~agd5f/linux into drm-next
Various fixes for DC for 4.15. * 'drm-next-4.15-dc' of git://people.freedesktop.org/~agd5f/linux: drm/amd/display: fix MST link training fail division by 0 drm/amd/display: Fix formatting for null pointer dereference fix drm/amd/display: Remove dangling planes on dc commit state drm/amd/display: add flip_immediate to commit update for stream drm/amd/display: Miss register MST encoder cbs drm/amd/display: Fix warnings on S3 resume drm/amd/display: use num_timing_generator instead of pipe_count drm/amd/display: use configurable FBC option in dm drm/amd/display: fix AZ clock not enabled before program AZ endpoint amdgpu/dm: Don't use DRM_ERROR in amdgpu_dm_atomic_check
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc')
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc.c42
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_link.c6
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_stream.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_audio.c31
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c2
5 files changed, 74 insertions, 9 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index ce3c57b38bc0..fe63f5894d43 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -619,6 +619,39 @@ fail:
return false;
}
+static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
+{
+ int i, j;
+ struct dc_state *dangling_context = dc_create_state();
+ struct dc_state *current_ctx;
+
+ if (dangling_context == NULL)
+ return;
+
+ dc_resource_state_copy_construct(dc->current_state, dangling_context);
+
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ struct dc_stream_state *old_stream =
+ dc->current_state->res_ctx.pipe_ctx[i].stream;
+ bool should_disable = true;
+
+ for (j = 0; j < context->stream_count; j++) {
+ if (old_stream == context->streams[j]) {
+ should_disable = false;
+ break;
+ }
+ }
+ if (should_disable && old_stream) {
+ dc_rem_all_planes_for_stream(dc, old_stream, dangling_context);
+ dc->hwss.apply_ctx_for_surface(dc, old_stream, 0, dangling_context);
+ }
+ }
+
+ current_ctx = dc->current_state;
+ dc->current_state = dangling_context;
+ dc_release_state(current_ctx);
+}
+
/*******************************************************************************
* Public functions
******************************************************************************/
@@ -801,6 +834,8 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
int i, j, k, l;
struct dc_stream_state *dc_streams[MAX_STREAMS] = {0};
+ disable_dangling_plane(dc, context);
+
for (i = 0; i < context->stream_count; i++)
dc_streams[i] = context->streams[i];
@@ -830,8 +865,6 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
}
}
-
-
CONN_MSG_MODE(sink->link, "{%dx%d, %dx%d@%dKhz}",
context->streams[i]->timing.h_addressable,
context->streams[i]->timing.v_addressable,
@@ -1414,8 +1447,11 @@ void dc_commit_updates_for_stream(struct dc *dc,
/* TODO: On flip we don't build the state, so it still has the
* old address. Which is why we are updating the address here
*/
- if (srf_updates[i].flip_addr)
+ if (srf_updates[i].flip_addr) {
surface->address = srf_updates[i].flip_addr->address;
+ surface->flip_immediate = srf_updates[i].flip_addr->flip_immediate;
+
+ }
if (update_type >= UPDATE_TYPE_MED) {
for (j = 0; j < dc->res_pool->pipe_count; j++) {
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index e70612eaf257..0602610489d7 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -2318,9 +2318,11 @@ void core_link_enable_stream(
/* Abort stream enable *unless* the failure was due to
* DP link training - some DP monitors will recover and
- * show the stream anyway.
+ * show the stream anyway. But MST displays can't proceed
+ * without link training.
*/
- if (status != DC_FAIL_DP_LINK_TRAINING) {
+ if (status != DC_FAIL_DP_LINK_TRAINING ||
+ pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
BREAK_TO_DEBUGGER();
return;
}
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
index de04b95e103a..b00a6040a697 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -288,7 +288,7 @@ bool dc_stream_set_cursor_position(
pos_cpy.enable = false;
- if (ipp !=NULL && ipp->funcs->ipp_cursor_set_position != NULL)
+ if (ipp != NULL && ipp->funcs->ipp_cursor_set_position != NULL)
ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, &param);
if (mi != NULL && mi->funcs->set_cursor_position != NULL)
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
index d882adf746a5..81c40f8864db 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
@@ -348,29 +348,44 @@ static void set_audio_latency(
void dce_aud_az_enable(struct audio *audio)
{
+ struct dce_audio *aud = DCE_AUD(audio);
uint32_t value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
- if (get_reg_field_value(value,
+ set_reg_field_value(value, 1,
AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
- AUDIO_ENABLED) != 1)
+ CLOCK_GATING_DISABLE);
set_reg_field_value(value, 1,
AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
AUDIO_ENABLED);
AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
+ value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
+
+ dm_logger_write(CTX->logger, LOG_HW_AUDIO,
+ "\n\t========= AUDIO:dce_aud_az_enable: index: %u data: 0x%x\n",
+ audio->inst, value);
}
void dce_aud_az_disable(struct audio *audio)
{
uint32_t value;
+ struct dce_audio *aud = DCE_AUD(audio);
value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
set_reg_field_value(value, 0,
AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
AUDIO_ENABLED);
+ AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
+ set_reg_field_value(value, 0,
+ AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
+ CLOCK_GATING_DISABLE);
AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
+ value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
+ dm_logger_write(CTX->logger, LOG_HW_AUDIO,
+ "\n\t========= AUDIO:dce_aud_az_disable: index: %u data: 0x%x\n",
+ audio->inst, value);
}
void dce_aud_az_configure(
@@ -390,6 +405,11 @@ void dce_aud_az_configure(
bool is_ac3_supported = false;
union audio_sample_rates sample_rate;
uint32_t strlen = 0;
+ value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
+ set_reg_field_value(value, 1,
+ AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
+ CLOCK_GATING_DISABLE);
+ AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
/* Speaker Allocation */
/*
@@ -852,6 +872,7 @@ static bool dce_aud_endpoint_valid(struct audio *audio)
void dce_aud_hw_init(
struct audio *audio)
{
+ uint32_t value;
struct dce_audio *aud = DCE_AUD(audio);
/* we only need to program the following registers once, so we only do
@@ -863,6 +884,12 @@ void dce_aud_hw_init(
* Suport R6 - 44.1khz
* Suport R7 - 48khz
*/
+ /*disable clock gating before write to endpoint register*/
+ value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
+ set_reg_field_value(value, 1,
+ AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
+ CLOCK_GATING_DISABLE);
+ AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
REG_UPDATE(AZALIA_F0_CODEC_FUNCTION_PARAMETER_SUPPORTED_SIZE_RATES,
AUDIO_RATE_CAPABILITIES, 0x70);
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 63c2f5266142..961ad5c3b454 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
@@ -202,7 +202,7 @@ static void dcn10_log_hw_state(struct dc *dc)
DTN_INFO("OTG:\t v_bs \t v_be \t v_ss \t v_se \t vpol \t vmax \t vmin \t "
"h_bs \t h_be \t h_ss \t h_se \t hpol \t htot \t vtot \t underflow\n");
- for (i = 0; i < pool->pipe_count; i++) {
+ for (i = 0; i < pool->res_cap->num_timing_generator; i++) {
struct timing_generator *tg = pool->timing_generators[i];
struct dcn_otg_state s = {0};