aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/0345-drm-amd-display-Parse-scanline-registers.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/0345-drm-amd-display-Parse-scanline-registers.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.14.71/0345-drm-amd-display-Parse-scanline-registers.patch329
1 files changed, 329 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/0345-drm-amd-display-Parse-scanline-registers.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/0345-drm-amd-display-Parse-scanline-registers.patch
new file mode 100644
index 00000000..7f2186fc
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/0345-drm-amd-display-Parse-scanline-registers.patch
@@ -0,0 +1,329 @@
+From c5b6a475f11abc7e3fe73811038e63a647de8fe6 Mon Sep 17 00:00:00 2001
+From: Sylvia Tsai <sylvia.tsai@amd.com>
+Date: Tue, 11 Apr 2017 15:15:28 -0400
+Subject: [PATCH 0345/4131] drm/amd/display: Parse scanline registers
+
+They could differ between ASIC generations
+
+Signed-off-by: Sylvia Tsai <sylvia.tsai@amd.com>
+Signed-off-by: Harry Wentland <harry.wentland@amd.com>
+Acked-by: Harry Wentland <Harry.Wentland@amd.com>
+Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 15 +++++-
+ drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 21 ++++++---
+ drivers/gpu/drm/amd/display/dc/dc.h | 7 ++-
+ .../display/dc/dce110/dce110_timing_generator.c | 54 ++++++++++------------
+ .../display/dc/dce110/dce110_timing_generator.h | 8 ++--
+ .../display/dc/dce120/dce120_timing_generator.c | 42 ++++++++---------
+ .../drm/amd/display/dc/inc/hw/timing_generator.h | 8 ++--
+ 7 files changed, 89 insertions(+), 66 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 7ede233..2ae541c 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -103,6 +103,8 @@ static u32 dm_vblank_get_counter(struct amdgpu_device *adev, int crtc)
+ static int dm_crtc_get_scanoutpos(struct amdgpu_device *adev, int crtc,
+ u32 *vbl, u32 *position)
+ {
++ uint32_t v_blank_start, v_blank_end, h_position, v_position;
++
+ if ((crtc < 0) || (crtc >= adev->mode_info.num_crtc))
+ return -EINVAL;
+ else {
+@@ -113,7 +115,18 @@ static int dm_crtc_get_scanoutpos(struct amdgpu_device *adev, int crtc,
+ return 0;
+ }
+
+- return dc_stream_get_scanoutpos(acrtc->stream, vbl, position);
++ /*
++ * TODO rework base driver to use values directly.
++ * for now parse it back into reg-format
++ */
++ dc_stream_get_scanoutpos(acrtc->stream,
++ &v_blank_start,
++ &v_blank_end,
++ &h_position,
++ &v_position);
++
++ *position = (v_position) || (h_position << 16);
++ *vbl = (v_blank_start) || (v_blank_end << 16);
+ }
+
+ return 0;
+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 bf209f7..3dbd6c0 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+@@ -282,12 +282,14 @@ uint32_t dc_stream_get_vblank_counter(const struct dc_stream *dc_stream)
+ return 0;
+ }
+
+-uint32_t dc_stream_get_scanoutpos(
+- const struct dc_stream *dc_stream,
+- uint32_t *vbl,
+- uint32_t *position)
++bool dc_stream_get_scanoutpos(const struct dc_stream *dc_stream,
++ uint32_t *v_blank_start,
++ uint32_t *v_blank_end,
++ uint32_t *h_position,
++ uint32_t *v_position)
+ {
+ uint8_t i;
++ bool ret = false;
+ struct core_stream *stream = DC_STREAM_TO_CORE(dc_stream);
+ struct core_dc *core_dc = DC_TO_CORE(stream->ctx->dc);
+ struct resource_context *res_ctx =
+@@ -299,10 +301,17 @@ uint32_t dc_stream_get_scanoutpos(
+ if (res_ctx->pipe_ctx[i].stream != stream)
+ continue;
+
+- return tg->funcs->get_scanoutpos(tg, vbl, position);
++ tg->funcs->get_scanoutpos(tg,
++ v_blank_start,
++ v_blank_end,
++ h_position,
++ v_position);
++
++ ret = true;
++ break;
+ }
+
+- return 0;
++ return ret;
+ }
+
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
+index 97af8f6..7d548b4 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc.h
++++ b/drivers/gpu/drm/amd/display/dc/dc.h
+@@ -484,8 +484,11 @@ uint32_t dc_stream_get_vblank_counter(const struct dc_stream *stream);
+ * This has a dependency on the caller (amdgpu_get_crtc_scanoutpos)
+ * being refactored properly to be dce-specific
+ */
+-uint32_t dc_stream_get_scanoutpos(
+- const struct dc_stream *stream, uint32_t *vbl, uint32_t *position);
++bool dc_stream_get_scanoutpos(const struct dc_stream *stream,
++ uint32_t *v_blank_start,
++ uint32_t *v_blank_end,
++ uint32_t *h_position,
++ uint32_t *v_position);
+
+ /*
+ * Structure to store surface/stream associations for validation
+diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c
+index 006412b..7070aaf 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c
++++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c
+@@ -574,29 +574,26 @@ void dce110_timing_generator_get_crtc_positions(
+ * @param [out] vpos, hpos
+ *****************************************************************************
+ */
+-uint32_t dce110_timing_generator_get_crtc_scanoutpos(
++void dce110_timing_generator_get_crtc_scanoutpos(
+ struct timing_generator *tg,
+- uint32_t *vbl,
+- uint32_t *position)
++ uint32_t *v_blank_start,
++ uint32_t *v_blank_end,
++ uint32_t *h_position,
++ uint32_t *v_position)
+ {
+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
+- /* TODO 1: Update the implementation once caller is updated
+- * WARNING!! This function is returning the whole register value
+- * because the caller is expecting it instead of proper vertical and
+- * horizontal position. This should be a temporary implementation
+- * until the caller is updated. */
+
+- /* TODO 2: re-use dce110_timing_generator_get_crtc_positions() */
+-
+- *vbl = dm_read_reg(tg->ctx,
++ uint32_t v_blank_start_end = dm_read_reg(tg->ctx,
+ CRTC_REG(mmCRTC_V_BLANK_START_END));
+
+- *position = dm_read_reg(tg->ctx,
+- CRTC_REG(mmCRTC_STATUS_POSITION));
++ *v_blank_start = get_reg_field_value(v_blank_start_end,
++ CRTC_V_BLANK_START_END,
++ CRTC_V_BLANK_START);
++ *v_blank_end = get_reg_field_value(v_blank_start_end,
++ CRTC_V_BLANK_START_END,
++ CRTC_V_BLANK_END);
+
+- /* @TODO: return value should indicate if current
+- * crtc is inside vblank*/
+- return 0;
++ dce110_timing_generator_get_crtc_positions(tg, h_position, v_position);
+ }
+
+ /* TODO: is it safe to assume that mask/shift of Primary and Underlay
+@@ -1875,34 +1872,31 @@ void dce110_tg_set_colors(struct timing_generator *tg,
+ bool dce110_arm_vert_intr(struct timing_generator *tg, uint8_t width)
+ {
+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
+- uint32_t vbl = 0;
++ uint32_t v_blank_start = 0;
++ uint32_t v_blank_end = 0;
+ uint32_t val = 0;
+- uint32_t position, vbl_start;
++ uint32_t h_position, v_position;
+
+ tg->funcs->get_scanoutpos(
+ tg,
+- &vbl,
+- &position);
++ &v_blank_start,
++ &v_blank_end,
++ &h_position,
++ &v_position);
+
+- if (vbl == 0)
++ if (v_blank_start == 0 || v_blank_end == 0)
+ return false;
+
+- vbl_start =
+- get_reg_field_value(
+- vbl,
+- CRTC_V_BLANK_START_END,
+- CRTC_V_BLANK_START);
+-
+ set_reg_field_value(
+ val,
+- vbl_start,
++ v_blank_start,
+ CRTC_VERTICAL_INTERRUPT0_POSITION,
+ CRTC_VERTICAL_INTERRUPT0_LINE_START);
+
+- /* Set interaval width for interrupt to fire to 1 scanline */
++ /* Set interval width for interrupt to fire to 1 scanline */
+ set_reg_field_value(
+ val,
+- vbl_start + width,
++ v_blank_start + width,
+ CRTC_VERTICAL_INTERRUPT0_POSITION,
+ CRTC_VERTICAL_INTERRUPT0_LINE_END);
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.h b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.h
+index ca387b4..f14a4d9 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.h
++++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.h
+@@ -230,10 +230,12 @@ void dce110_timing_generator_set_static_screen_control(
+ struct timing_generator *tg,
+ uint32_t value);
+
+-uint32_t dce110_timing_generator_get_crtc_scanoutpos(
++void dce110_timing_generator_get_crtc_scanoutpos(
+ struct timing_generator *tg,
+- uint32_t *vbl,
+- uint32_t *position);
++ uint32_t *v_blank_start,
++ uint32_t *v_blank_end,
++ uint32_t *h_position,
++ uint32_t *v_position);
+
+ void dce110_timing_generator_enable_advanced_request(
+ struct timing_generator *tg,
+diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c
+index 95cb176..1318df7 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c
++++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c
+@@ -576,24 +576,28 @@ void dce120_timing_generator_set_drr(
+ }
+ }
+
+-uint32_t dce120_timing_generator_get_crtc_scanoutpos(
++void dce120_timing_generator_get_crtc_scanoutpos(
+ struct timing_generator *tg,
+- uint32_t *vbl,
+- uint32_t *position)
++ uint32_t *v_blank_start,
++ uint32_t *v_blank_end,
++ uint32_t *h_position,
++ uint32_t *v_position)
+ {
+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
+
+- *vbl = dm_read_reg_soc15(
++ uint32_t v_blank_start_end = dm_read_reg_soc15(
+ tg->ctx,
+ mmCRTC0_CRTC_V_BLANK_START_END,
+ tg110->offsets.crtc);
+
+- *position = dm_read_reg_soc15(
+- tg->ctx,
+- mmCRTC0_CRTC_STATUS_POSITION,
+- tg110->offsets.crtc);
++ *v_blank_start = get_reg_field_value(v_blank_start_end,
++ CRTC0_CRTC_V_BLANK_START_END,
++ CRTC_V_BLANK_START);
++ *v_blank_end = get_reg_field_value(v_blank_start_end,
++ CRTC0_CRTC_V_BLANK_START_END,
++ CRTC_V_BLANK_END);
+
+- return 0;
++ dce120_timing_generator_get_crtc_positions(tg, h_position, v_position);
+ }
+
+ void dce120_timing_generator_enable_advanced_request(
+@@ -1044,26 +1048,22 @@ static bool dce120_arm_vert_intr(
+ uint8_t width)
+ {
+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
+- uint32_t vbl, position, vbl_start;
++ uint32_t v_blank_start, v_blank_end, h_position, v_position;
+
+ tg->funcs->get_scanoutpos(
+ tg,
+- &vbl,
+- &position);
++ &v_blank_start,
++ &v_blank_end,
++ &h_position,
++ &v_position);
+
+- if (vbl == 0)
++ if (v_blank_start == 0 || v_blank_end == 0)
+ return false;
+
+- vbl_start =
+- get_reg_field_value(
+- vbl,
+- CRTC0_CRTC_V_BLANK_START_END,
+- CRTC_V_BLANK_START);
+-
+ CRTC_REG_SET_2(
+ CRTC0_CRTC_VERTICAL_INTERRUPT0_POSITION,
+- CRTC_VERTICAL_INTERRUPT0_LINE_START, vbl_start,
+- CRTC_VERTICAL_INTERRUPT0_LINE_END, vbl_start + width);
++ CRTC_VERTICAL_INTERRUPT0_LINE_START, v_blank_start,
++ CRTC_VERTICAL_INTERRUPT0_LINE_END, v_blank_start + width);
+
+ return true;
+ }
+diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
+index 51902a4..b3deaf2 100644
+--- a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
+@@ -120,10 +120,12 @@ struct timing_generator_funcs {
+ int32_t *h_position,
+ int32_t *v_position);
+ uint32_t (*get_frame_count)(struct timing_generator *tg);
+- uint32_t (*get_scanoutpos)(
++ void (*get_scanoutpos)(
+ struct timing_generator *tg,
+- uint32_t *vbl,
+- uint32_t *position);
++ uint32_t *v_blank_start,
++ uint32_t *v_blank_end,
++ uint32_t *h_position,
++ uint32_t *v_position);
+ void (*set_early_control)(struct timing_generator *tg,
+ uint32_t early_cntl);
+ void (*wait_for_state)(struct timing_generator *tg,
+--
+2.7.4
+