[PATCH 24/39] drm/amd/dal: consolidate mem_input
Harry Wentland
harry.wentland at amd.com
Thu Nov 24 02:02:53 UTC 2016
From: Tony Cheng <tony.cheng at amd.com>
- dce_mem_input_allocate_dmif
- dce_mem_input_free_dmif
- mem_input_program_display_marks (DCE11.2)
- also fix MC_HUB_RDREQ_DMIF_LIMIT wa is different in different DCE
- also add more robust error checking in new programming model
-- more asserts
Change-Id: Iea64d3c771375ff3d09ea4e7d15be4c63fe0ca32
Signed-off-by: Tony Cheng <tony.cheng at amd.com>
Acked-by: Harry Wentland <harry.wentland at amd.com>
---
drivers/gpu/drm/amd/dal/dc/dc_helper.c | 6 +-
drivers/gpu/drm/amd/dal/dc/dce/dce_mem_input.c | 191 ++++++++++
drivers/gpu/drm/amd/dal/dc/dce/dce_mem_input.h | 91 ++++-
.../gpu/drm/amd/dal/dc/dce100/dce100_resource.c | 16 +-
.../gpu/drm/amd/dal/dc/dce110/dce110_mem_input.c | 205 +----------
.../gpu/drm/amd/dal/dc/dce110/dce110_resource.c | 17 +-
.../gpu/drm/amd/dal/dc/dce112/dce112_mem_input.c | 384 +--------------------
drivers/gpu/drm/amd/dal/dc/dce80/dce80_mem_input.c | 126 +------
drivers/gpu/drm/amd/dal/dc/dce80/dce80_resource.c | 17 +-
drivers/gpu/drm/amd/dal/dc/dm_services.h | 8 +-
drivers/gpu/drm/amd/dal/dc/inc/hw/mem_input.h | 1 +
drivers/gpu/drm/amd/dal/dc/inc/reg_helper.h | 2 +-
12 files changed, 334 insertions(+), 730 deletions(-)
diff --git a/drivers/gpu/drm/amd/dal/dc/dc_helper.c b/drivers/gpu/drm/amd/dal/dc/dc_helper.c
index 96724ba17e4b..22b72f0bcbbc 100644
--- a/drivers/gpu/drm/amd/dal/dc/dc_helper.c
+++ b/drivers/gpu/drm/amd/dal/dc/dc_helper.c
@@ -114,7 +114,8 @@ uint32_t generic_reg_get(const struct dc_context *ctx,
uint32_t generic_reg_wait(const struct dc_context *ctx,
uint32_t addr, uint32_t shift, uint32_t mask, uint32_t condition_value,
- unsigned int delay_between_poll_us, unsigned int time_out_num_tries)
+ unsigned int delay_between_poll_us, unsigned int time_out_num_tries,
+ const char *func_name)
{
uint32_t field_value;
uint32_t reg_val;
@@ -137,6 +138,7 @@ uint32_t generic_reg_wait(const struct dc_context *ctx,
return reg_val;
}
- BREAK_TO_DEBUGGER();
+ DC_ERR("REG_WAIT timeout %dus * %d tries - ",
+ delay_between_poll_us, time_out_num_tries, func_name);
return reg_val;
}
diff --git a/drivers/gpu/drm/amd/dal/dc/dce/dce_mem_input.c b/drivers/gpu/drm/amd/dal/dc/dce/dce_mem_input.c
index 1b4a5b9bb8b6..654731cccdcd 100644
--- a/drivers/gpu/drm/amd/dal/dc/dce/dce_mem_input.c
+++ b/drivers/gpu/drm/amd/dal/dc/dce/dce_mem_input.c
@@ -36,6 +36,78 @@
mi->shifts->field_name, mi->masks->field_name
+static void program_urgency_watermark(struct mem_input *mi,
+ uint32_t wm_select,
+ uint32_t urgency_low_wm,
+ uint32_t urgency_high_wm)
+{
+ REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
+ URGENCY_WATERMARK_MASK, wm_select);
+
+ REG_SET_2(DPG_PIPE_URGENCY_CONTROL, 0,
+ URGENCY_LOW_WATERMARK, urgency_low_wm,
+ URGENCY_HIGH_WATERMARK, urgency_high_wm);
+}
+
+static void program_nbp_watermark(struct mem_input *mi,
+ uint32_t wm_select,
+ uint32_t nbp_wm)
+{
+ if (REG(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL)) {
+ REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
+ NB_PSTATE_CHANGE_WATERMARK_MASK, wm_select);
+
+ REG_UPDATE_3(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
+ NB_PSTATE_CHANGE_ENABLE, 1,
+ NB_PSTATE_CHANGE_URGENT_DURING_REQUEST, 1,
+ NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST, 1);
+
+ REG_UPDATE(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
+ NB_PSTATE_CHANGE_WATERMARK, nbp_wm);
+ }
+}
+
+static void program_stutter_watermark(struct mem_input *mi,
+ uint32_t wm_select,
+ uint32_t stutter_mark)
+{
+ REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
+ STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK, wm_select);
+
+ REG_UPDATE(DPG_PIPE_STUTTER_CONTROL,
+ STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark);
+}
+
+void dce_mem_input_program_display_marks(struct mem_input *mi,
+ struct bw_watermarks nbp,
+ struct bw_watermarks stutter,
+ struct bw_watermarks urgent,
+ uint32_t total_dest_line_time_ns)
+{
+ uint32_t stutter_en = mi->ctx->dc->debug.disable_stutter ? 0 : 1;
+
+ program_urgency_watermark(mi, 0, /* set a */
+ urgent.a_mark, total_dest_line_time_ns);
+ program_urgency_watermark(mi, 1, /* set b */
+ urgent.b_mark, total_dest_line_time_ns);
+ program_urgency_watermark(mi, 2, /* set c */
+ urgent.c_mark, total_dest_line_time_ns);
+ program_urgency_watermark(mi, 3, /* set d */
+ urgent.d_mark, total_dest_line_time_ns);
+
+ REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL,
+ STUTTER_ENABLE, stutter_en,
+ STUTTER_IGNORE_FBC, 1);
+ program_nbp_watermark(mi, 0, nbp.a_mark); /* set a */
+ program_nbp_watermark(mi, 1, nbp.b_mark); /* set b */
+ program_nbp_watermark(mi, 2, nbp.c_mark); /* set c */
+ program_nbp_watermark(mi, 3, nbp.d_mark); /* set d */
+
+ program_stutter_watermark(mi, 0, stutter.a_mark); /* set a */
+ program_stutter_watermark(mi, 1, stutter.b_mark); /* set b */
+ program_stutter_watermark(mi, 2, stutter.c_mark); /* set c */
+ program_stutter_watermark(mi, 3, stutter.d_mark); /* set d */
+}
static void program_tiling(struct mem_input *mi,
const union dc_tiling_info *info)
@@ -191,3 +263,122 @@ bool dce_mem_input_program_surface_config(struct mem_input *mi,
return true;
}
+
+static uint32_t get_dmif_switch_time_us(
+ uint32_t h_total,
+ uint32_t v_total,
+ uint32_t pix_clk_khz)
+{
+ uint32_t frame_time;
+ uint32_t pixels_per_second;
+ uint32_t pixels_per_frame;
+ uint32_t refresh_rate;
+ const uint32_t us_in_sec = 1000000;
+ const uint32_t min_single_frame_time_us = 30000;
+ /*return double of frame time*/
+ const uint32_t single_frame_time_multiplier = 2;
+
+ if (!h_total || v_total || !pix_clk_khz)
+ return single_frame_time_multiplier * min_single_frame_time_us;
+
+ /*TODO: should we use pixel format normalized pixel clock here?*/
+ pixels_per_second = pix_clk_khz * 1000;
+ pixels_per_frame = h_total * v_total;
+
+ if (!pixels_per_second || !pixels_per_frame) {
+ /* avoid division by zero */
+ ASSERT(pixels_per_frame);
+ ASSERT(pixels_per_second);
+ return single_frame_time_multiplier * min_single_frame_time_us;
+ }
+
+ refresh_rate = pixels_per_second / pixels_per_frame;
+
+ if (!refresh_rate) {
+ /* avoid division by zero*/
+ ASSERT(refresh_rate);
+ return single_frame_time_multiplier * min_single_frame_time_us;
+ }
+
+ frame_time = us_in_sec / refresh_rate;
+
+ if (frame_time < min_single_frame_time_us)
+ frame_time = min_single_frame_time_us;
+
+ frame_time *= single_frame_time_multiplier;
+
+ return frame_time;
+}
+
+void dce_mem_input_allocate_dmif(struct mem_input *mi,
+ uint32_t h_total,
+ uint32_t v_total,
+ uint32_t pix_clk_khz,
+ uint32_t total_stream_num)
+{
+ const uint32_t retry_delay = 10;
+ uint32_t retry_count = get_dmif_switch_time_us(
+ h_total,
+ v_total,
+ pix_clk_khz) / retry_delay;
+
+ uint32_t pix_dur;
+ uint32_t buffers_allocated;
+ uint32_t dmif_buffer_control;
+
+ dmif_buffer_control = REG_GET(DMIF_BUFFER_CONTROL,
+ DMIF_BUFFERS_ALLOCATED, &buffers_allocated);
+
+ if (buffers_allocated == 2)
+ return;
+
+ REG_SET(DMIF_BUFFER_CONTROL, dmif_buffer_control,
+ DMIF_BUFFERS_ALLOCATED, 2);
+
+ REG_WAIT(DMIF_BUFFER_CONTROL,
+ DMIF_BUFFERS_ALLOCATION_COMPLETED, 1,
+ retry_delay, retry_count);
+
+ if (pix_clk_khz != 0) {
+ pix_dur = 1000000000ULL / pix_clk_khz;
+
+ REG_UPDATE(DPG_PIPE_ARBITRATION_CONTROL1,
+ PIXEL_DURATION, pix_dur);
+ }
+
+ if (mi->wa.single_head_rdreq_dmif_limit) {
+ uint32_t eanble = (total_stream_num > 1) ? 0 :
+ mi->wa.single_head_rdreq_dmif_limit;
+
+ REG_UPDATE(MC_HUB_RDREQ_DMIF_LIMIT,
+ ENABLE, eanble);
+ }
+}
+
+void dce_mem_input_free_dmif(struct mem_input *mi,
+ uint32_t total_stream_num)
+{
+ uint32_t buffers_allocated;
+ uint32_t dmif_buffer_control;
+
+ dmif_buffer_control = REG_GET(DMIF_BUFFER_CONTROL,
+ DMIF_BUFFERS_ALLOCATED, &buffers_allocated);
+
+ if (buffers_allocated == 0)
+ return;
+
+ REG_SET(DMIF_BUFFER_CONTROL, dmif_buffer_control,
+ DMIF_BUFFERS_ALLOCATED, 0);
+
+ REG_WAIT(DMIF_BUFFER_CONTROL,
+ DMIF_BUFFERS_ALLOCATION_COMPLETED, 1,
+ 10, 0xBB8);
+
+ if (mi->wa.single_head_rdreq_dmif_limit) {
+ uint32_t eanble = (total_stream_num > 1) ? 0 :
+ mi->wa.single_head_rdreq_dmif_limit;
+
+ REG_UPDATE(MC_HUB_RDREQ_DMIF_LIMIT,
+ ENABLE, eanble);
+ }
+}
diff --git a/drivers/gpu/drm/amd/dal/dc/dce/dce_mem_input.h b/drivers/gpu/drm/amd/dal/dc/dce/dce_mem_input.h
index 96c7736e223b..d5930a925fcb 100644
--- a/drivers/gpu/drm/amd/dal/dc/dce/dce_mem_input.h
+++ b/drivers/gpu/drm/amd/dal/dc/dce/dce_mem_input.h
@@ -25,7 +25,7 @@
#ifndef __DCE_MEM_INPUT_H__
#define __DCE_MEM_INPUT_H__
-#define MI_REG_LIST(id)\
+#define MI_DCE_BASE_REG_LIST(id)\
SRI(GRPH_ENABLE, DCP, id),\
SRI(GRPH_CONTROL, DCP, id),\
SRI(GRPH_X_START, DCP, id),\
@@ -35,9 +35,19 @@
SRI(GRPH_PITCH, DCP, id),\
SRI(HW_ROTATION, DCP, id),\
SRI(GRPH_SWAP_CNTL, DCP, id),\
- SRI(PRESCALE_GRPH_CONTROL, DCP, id)
+ SRI(PRESCALE_GRPH_CONTROL, DCP, id),\
+ SRI(DPG_PIPE_ARBITRATION_CONTROL1, DMIF_PG, id),\
+ SRI(DPG_WATERMARK_MASK_CONTROL, DMIF_PG, id),\
+ SRI(DPG_PIPE_URGENCY_CONTROL, DMIF_PG, id),\
+ SRI(DPG_PIPE_STUTTER_CONTROL, DMIF_PG, id),\
+ SRI(DMIF_BUFFER_CONTROL, PIPE, id)
+
+#define MI_REG_LIST(id)\
+ MI_DCE_BASE_REG_LIST(id),\
+ SRI(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL, DMIF_PG, id)
struct dce_mem_input_registers {
+ /* DCP */
uint32_t GRPH_ENABLE;
uint32_t GRPH_CONTROL;
uint32_t GRPH_X_START;
@@ -48,6 +58,18 @@ struct dce_mem_input_registers {
uint32_t HW_ROTATION;
uint32_t GRPH_SWAP_CNTL;
uint32_t PRESCALE_GRPH_CONTROL;
+ /* DMIF_PG */
+ uint32_t DPG_PIPE_ARBITRATION_CONTROL1;
+ uint32_t DPG_WATERMARK_MASK_CONTROL;
+ uint32_t DPG_PIPE_URGENCY_CONTROL;
+ uint32_t DPG_PIPE_NB_PSTATE_CHANGE_CONTROL;
+ uint32_t DPG_PIPE_LOW_POWER_CONTROL;
+ uint32_t DPG_PIPE_STUTTER_CONTROL;
+ uint32_t DPG_PIPE_STUTTER_CONTROL2;
+ /* DCI */
+ uint32_t DMIF_BUFFER_CONTROL;
+ /* MC_HUB */
+ uint32_t MC_HUB_RDREQ_DMIF_LIMIT;
};
/* Set_Filed_for_Block */
@@ -81,9 +103,30 @@ struct dce_mem_input_registers {
SFB(blk, PRESCALE_GRPH_CONTROL, GRPH_PRESCALE_G_SIGN, mask_sh),\
SFB(blk, PRESCALE_GRPH_CONTROL, GRPH_PRESCALE_B_SIGN, mask_sh)
+#define MI_DMIF_PG_MASK_SH_LIST(mask_sh, blk)\
+ SFB(blk, DPG_PIPE_ARBITRATION_CONTROL1, PIXEL_DURATION, mask_sh),\
+ SFB(blk, DPG_WATERMARK_MASK_CONTROL, URGENCY_WATERMARK_MASK, mask_sh),\
+ SFB(blk, DPG_WATERMARK_MASK_CONTROL, STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK, mask_sh),\
+ SFB(blk, DPG_PIPE_URGENCY_CONTROL, URGENCY_LOW_WATERMARK, mask_sh),\
+ SFB(blk, DPG_PIPE_URGENCY_CONTROL, URGENCY_HIGH_WATERMARK, mask_sh),\
+ SFB(blk, DPG_PIPE_STUTTER_CONTROL, STUTTER_ENABLE, mask_sh),\
+ SFB(blk, DPG_PIPE_STUTTER_CONTROL, STUTTER_IGNORE_FBC, mask_sh),\
+ SF(PIPE0_DMIF_BUFFER_CONTROL, DMIF_BUFFERS_ALLOCATED, mask_sh),\
+ SF(PIPE0_DMIF_BUFFER_CONTROL, DMIF_BUFFERS_ALLOCATION_COMPLETED, mask_sh)
+
+#define MI_DMIF_PG_MASK_SH_DCE(mask_sh, blk)\
+ SFB(blk, DPG_PIPE_STUTTER_CONTROL, STUTTER_EXIT_SELF_REFRESH_WATERMARK, mask_sh),\
+ SFB(blk, DPG_WATERMARK_MASK_CONTROL, NB_PSTATE_CHANGE_WATERMARK_MASK, mask_sh),\
+ SFB(blk, DPG_PIPE_NB_PSTATE_CHANGE_CONTROL, NB_PSTATE_CHANGE_ENABLE, mask_sh),\
+ SFB(blk, DPG_PIPE_NB_PSTATE_CHANGE_CONTROL, NB_PSTATE_CHANGE_URGENT_DURING_REQUEST, mask_sh),\
+ SFB(blk, DPG_PIPE_NB_PSTATE_CHANGE_CONTROL, NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST, mask_sh),\
+ SFB(blk, DPG_PIPE_NB_PSTATE_CHANGE_CONTROL, NB_PSTATE_CHANGE_WATERMARK, mask_sh)
+
#define MI_DCE_MASK_SH_LIST(mask_sh)\
- MI_DCP_MASK_SH_LIST(mask_sh, ),\
- MI_GFX8_TILE_MASK_SH_LIST(mask_sh, )
+ MI_DCP_MASK_SH_LIST(mask_sh,),\
+ MI_DMIF_PG_MASK_SH_LIST(mask_sh,),\
+ MI_DMIF_PG_MASK_SH_DCE(mask_sh,),\
+ MI_GFX8_TILE_MASK_SH_LIST(mask_sh,)
#define MI_REG_FIELD_LIST(type) \
type GRPH_ENABLE; \
@@ -113,6 +156,27 @@ struct dce_mem_input_registers {
type GRPH_SW_MODE; \
type GRPH_NUM_SHADER_ENGINES; \
type GRPH_NUM_PIPES; \
+ type PIXEL_DURATION; \
+ type URGENCY_WATERMARK_MASK; \
+ type PSTATE_CHANGE_WATERMARK_MASK; \
+ type NB_PSTATE_CHANGE_WATERMARK_MASK; \
+ type STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK; \
+ type URGENCY_LOW_WATERMARK; \
+ type URGENCY_HIGH_WATERMARK; \
+ type NB_PSTATE_CHANGE_ENABLE; \
+ type NB_PSTATE_CHANGE_URGENT_DURING_REQUEST; \
+ type NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST; \
+ type NB_PSTATE_CHANGE_WATERMARK; \
+ type PSTATE_CHANGE_ENABLE; \
+ type PSTATE_CHANGE_URGENT_DURING_REQUEST; \
+ type PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST; \
+ type PSTATE_CHANGE_WATERMARK; \
+ type STUTTER_ENABLE; \
+ type STUTTER_IGNORE_FBC; \
+ type STUTTER_EXIT_SELF_REFRESH_WATERMARK; \
+ type DMIF_BUFFERS_ALLOCATED; \
+ type DMIF_BUFFERS_ALLOCATION_COMPLETED; \
+ type ENABLE; /* MC_HUB_RDREQ_DMIF_LIMIT */\
struct dce_mem_input_shift {
MI_REG_FIELD_LIST(uint8_t)
@@ -122,6 +186,10 @@ struct dce_mem_input_mask {
MI_REG_FIELD_LIST(uint32_t)
};
+struct dce_mem_input_wa {
+ uint8_t single_head_rdreq_dmif_limit;
+};
+
struct mem_input;
bool dce_mem_input_program_surface_config(struct mem_input *mi,
enum surface_pixel_format format,
@@ -131,4 +199,19 @@ bool dce_mem_input_program_surface_config(struct mem_input *mi,
struct dc_plane_dcc_param *dcc,
bool horizontal_mirror);
+void dce_mem_input_allocate_dmif(struct mem_input *mi,
+ uint32_t h_total,
+ uint32_t v_total,
+ uint32_t pix_clk_khz,
+ uint32_t total_stream_num);
+
+void dce_mem_input_free_dmif(struct mem_input *mi,
+ uint32_t total_stream_num);
+
+void dce_mem_input_program_display_marks(struct mem_input *mi,
+ struct bw_watermarks nbp,
+ struct bw_watermarks stutter,
+ struct bw_watermarks urgent,
+ uint32_t total_dest_line_time_ns);
+
#endif /*__DCE_MEM_INPUT_H__*/
diff --git a/drivers/gpu/drm/amd/dal/dc/dce100/dce100_resource.c b/drivers/gpu/drm/amd/dal/dc/dce100/dce100_resource.c
index 6c17a52df574..851247c647a1 100644
--- a/drivers/gpu/drm/amd/dal/dc/dce100/dce100_resource.c
+++ b/drivers/gpu/drm/amd/dal/dc/dce100/dce100_resource.c
@@ -51,6 +51,10 @@
#include "dce/dce_10_0_d.h"
#include "dce/dce_10_0_sh_mask.h"
+#ifndef mmMC_HUB_RDREQ_DMIF_LIMIT
+#include "gmc/gmc_8_2_d.h"
+#include "gmc/gmc_8_2_sh_mask.h"
+#endif
#ifndef mmDP_DPHY_INTERNAL_CTRL
#define mmDP_DPHY_INTERNAL_CTRL 0x4aa7
@@ -471,7 +475,10 @@ static const struct resource_create_funcs res_create_funcs = {
.create_hwseq = dce100_hwseq_create,
};
-#define mi_inst_regs(id) { MI_REG_LIST(id) }
+#define mi_inst_regs(id) { \
+ MI_REG_LIST(id), \
+ .MC_HUB_RDREQ_DMIF_LIMIT = mmMC_HUB_RDREQ_DMIF_LIMIT \
+}
static const struct dce_mem_input_registers mi_regs[] = {
mi_inst_regs(0),
mi_inst_regs(1),
@@ -482,11 +489,13 @@ static const struct dce_mem_input_registers mi_regs[] = {
};
static const struct dce_mem_input_shift mi_shifts = {
- MI_DCE_MASK_SH_LIST(__SHIFT)
+ MI_DCE_MASK_SH_LIST(__SHIFT),
+ .ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE__SHIFT
};
static const struct dce_mem_input_mask mi_masks = {
- MI_DCE_MASK_SH_LIST(_MASK)
+ MI_DCE_MASK_SH_LIST(_MASK),
+ .ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE_MASK
};
static struct mem_input *dce100_mem_input_create(
@@ -506,6 +515,7 @@ static struct mem_input *dce100_mem_input_create(
mi->regs = &mi_regs[inst];
mi->shifts = &mi_shifts;
mi->masks = &mi_masks;
+ mi->wa.single_head_rdreq_dmif_limit = 2;
return mi;
}
diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_mem_input.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_mem_input.c
index 4092abe3812d..c0a68c6f585e 100644
--- a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_mem_input.c
+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_mem_input.c
@@ -494,212 +494,11 @@ void dce110_mem_input_program_display_marks(
stutter);
}
-static uint32_t get_dmif_switch_time_us(
- uint32_t h_total,
- uint32_t v_total,
- uint32_t pix_clk_khz)
-{
- uint32_t frame_time;
- uint32_t pixels_per_second;
- uint32_t pixels_per_frame;
- uint32_t refresh_rate;
- const uint32_t us_in_sec = 1000000;
- const uint32_t min_single_frame_time_us = 30000;
- /*return double of frame time*/
- const uint32_t single_frame_time_multiplier = 2;
-
- if (!h_total || v_total || !pix_clk_khz)
- return single_frame_time_multiplier * min_single_frame_time_us;
-
- /*TODO: should we use pixel format normalized pixel clock here?*/
- pixels_per_second = pix_clk_khz * 1000;
- pixels_per_frame = h_total * v_total;
-
- if (!pixels_per_second || !pixels_per_frame) {
- /* avoid division by zero */
- ASSERT(pixels_per_frame);
- ASSERT(pixels_per_second);
- return single_frame_time_multiplier * min_single_frame_time_us;
- }
-
- refresh_rate = pixels_per_second / pixels_per_frame;
-
- if (!refresh_rate) {
- /* avoid division by zero*/
- ASSERT(refresh_rate);
- return single_frame_time_multiplier * min_single_frame_time_us;
- }
-
- frame_time = us_in_sec / refresh_rate;
-
- if (frame_time < min_single_frame_time_us)
- frame_time = min_single_frame_time_us;
-
- frame_time *= single_frame_time_multiplier;
-
- return frame_time;
-}
-
-void dce110_allocate_mem_input(
- struct mem_input *mi,
- uint32_t h_total,/* for current stream */
- uint32_t v_total,/* for current stream */
- uint32_t pix_clk_khz,/* for current stream */
- uint32_t total_stream_num)
-{
- const uint32_t retry_delay = 10;
- uint32_t retry_count = get_dmif_switch_time_us(
- h_total,
- v_total,
- pix_clk_khz) / retry_delay;
-
- struct dce110_mem_input *bm110 = TO_DCE110_MEM_INPUT(mi);
- uint32_t addr = bm110->offsets.pipe + mmPIPE0_DMIF_BUFFER_CONTROL;
- uint32_t value;
- uint32_t field;
- uint32_t pix_dur;
-
- /*Allocate DMIF buffer*/
- value = dm_read_reg(mi->ctx, addr);
- field = get_reg_field_value(
- value, PIPE0_DMIF_BUFFER_CONTROL, DMIF_BUFFERS_ALLOCATED);
- if (field == 2)
- goto register_underflow_int;
-
- set_reg_field_value(
- value,
- 2,
- PIPE0_DMIF_BUFFER_CONTROL,
- DMIF_BUFFERS_ALLOCATED);
-
- dm_write_reg(mi->ctx, addr, value);
-
- do {
- value = dm_read_reg(mi->ctx, addr);
- field = get_reg_field_value(
- value,
- PIPE0_DMIF_BUFFER_CONTROL,
- DMIF_BUFFERS_ALLOCATION_COMPLETED);
-
- if (field)
- break;
-
- udelay(retry_delay);
- retry_count--;
-
- } while (retry_count > 0);
-
- if (field == 0)
- dm_logger_write(mi->ctx->logger, LOG_ERROR,
- "%s: DMIF allocation failed",
- __func__);
-
- if (pix_clk_khz != 0) {
- addr = mmDPG_PIPE_ARBITRATION_CONTROL1 + bm110->offsets.dmif;
- value = dm_read_reg(mi->ctx, addr);
- pix_dur = 1000000000ULL / pix_clk_khz;
-
- set_reg_field_value(
- value,
- pix_dur,
- DPG_PIPE_ARBITRATION_CONTROL1,
- PIXEL_DURATION);
-
- dm_write_reg(mi->ctx, addr, value);
- }
-
- /*
- * Stella Wong proposed the following change
- *
- * Value of mcHubRdReqDmifLimit.ENABLE:
- * 00 - disable DMIF rdreq limit
- * 01 - enable DMIF rdreq limit, disabled by DMIF stall = 1 || urg != 0
- * 02 - enable DMIF rdreq limit, disable by DMIF stall = 1
- * 03 - force enable DMIF rdreq limit, ignore DMIF stall / urgent
- */
- if (!IS_FPGA_MAXIMUS_DC(mi->ctx->dce_environment)) {
- addr = mmMC_HUB_RDREQ_DMIF_LIMIT;
- value = dm_read_reg(mi->ctx, addr);
-
- if (total_stream_num > 1)
- set_reg_field_value(value, 0, MC_HUB_RDREQ_DMIF_LIMIT, ENABLE);
- else
- set_reg_field_value(value, 3, MC_HUB_RDREQ_DMIF_LIMIT, ENABLE);
- dm_write_reg(mi->ctx, addr, value);
- }
-
-register_underflow_int:
- /*todo*/;
- /*register_interrupt(bm110, irq_source, ctrl_id);*/
-}
-
-static void deallocate_dmif_buffer_helper(
- struct dc_context *ctx, uint32_t offset)
-{
- uint32_t value;
- uint32_t count = 0xBB8; /* max retry count */
-
- value = dm_read_reg(ctx, mmPIPE0_DMIF_BUFFER_CONTROL + offset);
-
- if (!get_reg_field_value(
- value, PIPE0_DMIF_BUFFER_CONTROL, DMIF_BUFFERS_ALLOCATED))
- return;
-
- set_reg_field_value(
- value, 0, PIPE0_DMIF_BUFFER_CONTROL, DMIF_BUFFERS_ALLOCATED);
-
- dm_write_reg(
- ctx, mmPIPE0_DMIF_BUFFER_CONTROL + offset, value);
-
- do {
- value = dm_read_reg(ctx, mmPIPE0_DMIF_BUFFER_CONTROL + offset);
- udelay(10);
- count--;
- } while (count > 0 &&
- !get_reg_field_value(
- value,
- PIPE0_DMIF_BUFFER_CONTROL,
- DMIF_BUFFERS_ALLOCATION_COMPLETED));
-}
-
-void dce110_free_mem_input(
- struct mem_input *mi,
- uint32_t total_stream_num)
-{
- struct dce110_mem_input *bm_dce110 = TO_DCE110_MEM_INPUT(mi);
- uint32_t value;
-
- /* De-allocate DMIF buffer first */
- if (mmPIPE0_DMIF_BUFFER_CONTROL + bm_dce110->offsets.pipe != 0)
- deallocate_dmif_buffer_helper(
- mi->ctx, bm_dce110->offsets.pipe);
-
- /* TODO: unregister underflow interrupt
- unregisterInterrupt();
- */
-
- /* Value of mcHubRdReqDmifLimit.ENABLE.
- * 00 - disable dmif rdreq limit
- * 01 - enable dmif rdreq limit, disable by dmif stall=1||urg!=0
- * 02 - enable dmif rdreq limit, disable by dmif stall=1
- * 03 - force enable dmif rdreq limit, ignore dmif stall/urgent
- * Stella Wong proposed this change. */
- if (!IS_FPGA_MAXIMUS_DC(mi->ctx->dce_environment)) {
- value = dm_read_reg(mi->ctx, mmMC_HUB_RDREQ_DMIF_LIMIT);
- if (total_stream_num > 1)
- set_reg_field_value(value, 0, MC_HUB_RDREQ_DMIF_LIMIT, ENABLE);
- else
- set_reg_field_value(value, 3, MC_HUB_RDREQ_DMIF_LIMIT, ENABLE);
-
- dm_write_reg(mi->ctx, mmMC_HUB_RDREQ_DMIF_LIMIT, value);
- }
-}
-
static struct mem_input_funcs dce110_mem_input_funcs = {
.mem_input_program_display_marks =
dce110_mem_input_program_display_marks,
- .allocate_mem_input = dce110_allocate_mem_input,
- .free_mem_input = dce110_free_mem_input,
+ .allocate_mem_input = dce_mem_input_allocate_dmif,
+ .free_mem_input = dce_mem_input_free_dmif,
.mem_input_program_surface_flip_and_addr =
dce110_mem_input_program_surface_flip_and_addr,
.mem_input_program_pte_vm =
diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c
index 7731f80db2fb..dac53df2cb86 100644
--- a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c
+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c
@@ -54,6 +54,11 @@
#include "dce/dce_11_0_d.h"
#include "dce/dce_11_0_sh_mask.h"
+#ifndef mmMC_HUB_RDREQ_DMIF_LIMIT
+#include "gmc/gmc_8_2_d.h"
+#include "gmc/gmc_8_2_sh_mask.h"
+#endif
+
#ifndef mmDP_DPHY_INTERNAL_CTRL
#define mmDP_DPHY_INTERNAL_CTRL 0x4aa7
#define mmDP0_DP_DPHY_INTERNAL_CTRL 0x4aa7
@@ -464,7 +469,10 @@ static const struct resource_create_funcs res_create_funcs = {
.create_hwseq = dce110_hwseq_create,
};
-#define mi_inst_regs(id) { MI_REG_LIST(id) }
+#define mi_inst_regs(id) { \
+ MI_REG_LIST(id), \
+ .MC_HUB_RDREQ_DMIF_LIMIT = mmMC_HUB_RDREQ_DMIF_LIMIT \
+}
static const struct dce_mem_input_registers mi_regs[] = {
mi_inst_regs(0),
mi_inst_regs(1),
@@ -472,11 +480,13 @@ static const struct dce_mem_input_registers mi_regs[] = {
};
static const struct dce_mem_input_shift mi_shifts = {
- MI_DCE_MASK_SH_LIST(__SHIFT)
+ MI_DCE_MASK_SH_LIST(__SHIFT),
+ .ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE__SHIFT
};
static const struct dce_mem_input_mask mi_masks = {
- MI_DCE_MASK_SH_LIST(_MASK)
+ MI_DCE_MASK_SH_LIST(_MASK),
+ .ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE_MASK
};
static struct mem_input *dce110_mem_input_create(
@@ -496,6 +506,7 @@ static struct mem_input *dce110_mem_input_create(
mi->regs = &mi_regs[inst];
mi->shifts = &mi_shifts;
mi->masks = &mi_masks;
+ mi->wa.single_head_rdreq_dmif_limit = 3;
return mi;
}
diff --git a/drivers/gpu/drm/amd/dal/dc/dce112/dce112_mem_input.c b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_mem_input.c
index 24b1b91abd71..c29007dafe21 100644
--- a/drivers/gpu/drm/amd/dal/dc/dce112/dce112_mem_input.c
+++ b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_mem_input.c
@@ -34,388 +34,6 @@
#define DMIF_REG(reg) (reg + mem_input110->offsets.dmif)
#define PIPE_REG(reg) (reg + mem_input110->offsets.pipe)
-static void program_urgency_watermark(
- const struct dc_context *ctx,
- const uint32_t offset,
- struct bw_watermarks marks_low,
- uint32_t total_dest_line_time_ns)
-{
- /* register value */
- uint32_t urgency_cntl = 0;
- uint32_t wm_mask_cntl = 0;
-
- uint32_t urgency_addr = offset + mmDPG_PIPE_URGENCY_CONTROL;
- uint32_t wm_addr = offset + mmDPG_WATERMARK_MASK_CONTROL;
-
- /*Write mask to enable reading/writing of watermark set A*/
- wm_mask_cntl = dm_read_reg(ctx, wm_addr);
- set_reg_field_value(wm_mask_cntl,
- 0,
- DPG_WATERMARK_MASK_CONTROL,
- URGENCY_WATERMARK_MASK);
- dm_write_reg(ctx, wm_addr, wm_mask_cntl);
-
- urgency_cntl = dm_read_reg(ctx, urgency_addr);
-
- set_reg_field_value(
- urgency_cntl,
- marks_low.a_mark,
- DPG_PIPE_URGENCY_CONTROL,
- URGENCY_LOW_WATERMARK);
-
- set_reg_field_value(
- urgency_cntl,
- total_dest_line_time_ns,
- DPG_PIPE_URGENCY_CONTROL,
- URGENCY_HIGH_WATERMARK);
- dm_write_reg(ctx, urgency_addr, urgency_cntl);
-
- /*Write mask to enable reading/writing of watermark set B*/
- wm_mask_cntl = dm_read_reg(ctx, wm_addr);
- set_reg_field_value(wm_mask_cntl,
- 1,
- DPG_WATERMARK_MASK_CONTROL,
- URGENCY_WATERMARK_MASK);
- dm_write_reg(ctx, wm_addr, wm_mask_cntl);
-
- urgency_cntl = dm_read_reg(ctx, urgency_addr);
-
- set_reg_field_value(urgency_cntl,
- marks_low.b_mark,
- DPG_PIPE_URGENCY_CONTROL,
- URGENCY_LOW_WATERMARK);
-
- set_reg_field_value(urgency_cntl,
- total_dest_line_time_ns,
- DPG_PIPE_URGENCY_CONTROL,
- URGENCY_HIGH_WATERMARK);
- dm_write_reg(ctx, urgency_addr, urgency_cntl);
-
- /*Write mask to enable reading/writing of watermark set C*/
- wm_mask_cntl = dm_read_reg(ctx, wm_addr);
- set_reg_field_value(wm_mask_cntl,
- 2,
- DPG_WATERMARK_MASK_CONTROL,
- URGENCY_WATERMARK_MASK);
- dm_write_reg(ctx, wm_addr, wm_mask_cntl);
-
- urgency_cntl = dm_read_reg(ctx, urgency_addr);
-
- set_reg_field_value(urgency_cntl,
- marks_low.c_mark,
- DPG_PIPE_URGENCY_CONTROL,
- URGENCY_LOW_WATERMARK);
-
- set_reg_field_value(urgency_cntl,
- total_dest_line_time_ns,
- DPG_PIPE_URGENCY_CONTROL,
- URGENCY_HIGH_WATERMARK);
- dm_write_reg(ctx, urgency_addr, urgency_cntl);
-
- /*Write mask to enable reading/writing of watermark set D*/
- wm_mask_cntl = dm_read_reg(ctx, wm_addr);
- set_reg_field_value(wm_mask_cntl,
- 3,
- DPG_WATERMARK_MASK_CONTROL,
- URGENCY_WATERMARK_MASK);
- dm_write_reg(ctx, wm_addr, wm_mask_cntl);
-
- urgency_cntl = dm_read_reg(ctx, urgency_addr);
-
- set_reg_field_value(urgency_cntl,
- marks_low.d_mark,
- DPG_PIPE_URGENCY_CONTROL,
- URGENCY_LOW_WATERMARK);
-
- set_reg_field_value(urgency_cntl,
- total_dest_line_time_ns,
- DPG_PIPE_URGENCY_CONTROL,
- URGENCY_HIGH_WATERMARK);
- dm_write_reg(ctx, urgency_addr, urgency_cntl);
-}
-
-static void program_stutter_watermark(
- const struct dc_context *ctx,
- const uint32_t offset,
- struct bw_watermarks marks)
-{
- /* register value */
- uint32_t stutter_cntl = 0;
- uint32_t wm_mask_cntl = 0;
-
- uint32_t stutter_addr = offset + mmDPG_PIPE_STUTTER_CONTROL;
- uint32_t wm_addr = offset + mmDPG_WATERMARK_MASK_CONTROL;
-
- /*Write mask to enable reading/writing of watermark set A*/
-
- wm_mask_cntl = dm_read_reg(ctx, wm_addr);
- set_reg_field_value(wm_mask_cntl,
- 0,
- DPG_WATERMARK_MASK_CONTROL,
- STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK);
- dm_write_reg(ctx, wm_addr, wm_mask_cntl);
-
- stutter_cntl = dm_read_reg(ctx, stutter_addr);
-
- if (ctx->dc->debug.disable_stutter) {
- set_reg_field_value(stutter_cntl,
- 0,
- DPG_PIPE_STUTTER_CONTROL,
- STUTTER_ENABLE);
- } else {
- set_reg_field_value(stutter_cntl,
- 1,
- DPG_PIPE_STUTTER_CONTROL,
- STUTTER_ENABLE);
- }
-
- set_reg_field_value(stutter_cntl,
- 1,
- DPG_PIPE_STUTTER_CONTROL,
- STUTTER_IGNORE_FBC);
-
- /*Write watermark set A*/
- set_reg_field_value(stutter_cntl,
- marks.a_mark,
- DPG_PIPE_STUTTER_CONTROL,
- STUTTER_EXIT_SELF_REFRESH_WATERMARK);
- dm_write_reg(ctx, stutter_addr, stutter_cntl);
-
- /*Write mask to enable reading/writing of watermark set B*/
- wm_mask_cntl = dm_read_reg(ctx, wm_addr);
- set_reg_field_value(wm_mask_cntl,
- 1,
- DPG_WATERMARK_MASK_CONTROL,
- STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK);
- dm_write_reg(ctx, wm_addr, wm_mask_cntl);
-
- stutter_cntl = dm_read_reg(ctx, stutter_addr);
- /*Write watermark set B*/
- set_reg_field_value(stutter_cntl,
- marks.b_mark,
- DPG_PIPE_STUTTER_CONTROL,
- STUTTER_EXIT_SELF_REFRESH_WATERMARK);
- dm_write_reg(ctx, stutter_addr, stutter_cntl);
-
- /*Write mask to enable reading/writing of watermark set C*/
- wm_mask_cntl = dm_read_reg(ctx, wm_addr);
- set_reg_field_value(wm_mask_cntl,
- 2,
- DPG_WATERMARK_MASK_CONTROL,
- STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK);
- dm_write_reg(ctx, wm_addr, wm_mask_cntl);
-
- stutter_cntl = dm_read_reg(ctx, stutter_addr);
- /*Write watermark set C*/
- set_reg_field_value(stutter_cntl,
- marks.c_mark,
- DPG_PIPE_STUTTER_CONTROL,
- STUTTER_EXIT_SELF_REFRESH_WATERMARK);
- dm_write_reg(ctx, stutter_addr, stutter_cntl);
-
- /*Write mask to enable reading/writing of watermark set D*/
- wm_mask_cntl = dm_read_reg(ctx, wm_addr);
- set_reg_field_value(wm_mask_cntl,
- 3,
- DPG_WATERMARK_MASK_CONTROL,
- STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK);
- dm_write_reg(ctx, wm_addr, wm_mask_cntl);
-
- stutter_cntl = dm_read_reg(ctx, stutter_addr);
- /*Write watermark set D*/
- set_reg_field_value(stutter_cntl,
- marks.d_mark,
- DPG_PIPE_STUTTER_CONTROL,
- STUTTER_EXIT_SELF_REFRESH_WATERMARK);
- dm_write_reg(ctx, stutter_addr, stutter_cntl);
-}
-
-static void program_nbp_watermark(
- const struct dc_context *ctx,
- const uint32_t offset,
- struct bw_watermarks marks)
-{
- uint32_t value;
- uint32_t addr;
- /* Write mask to enable reading/writing of watermark set A */
- addr = offset + mmDPG_WATERMARK_MASK_CONTROL;
- value = dm_read_reg(ctx, addr);
- set_reg_field_value(
- value,
- 0,
- DPG_WATERMARK_MASK_CONTROL,
- NB_PSTATE_CHANGE_WATERMARK_MASK);
- dm_write_reg(ctx, addr, value);
-
- addr = offset + mmDPG_PIPE_NB_PSTATE_CHANGE_CONTROL;
- value = dm_read_reg(ctx, addr);
- set_reg_field_value(
- value,
- 1,
- DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
- NB_PSTATE_CHANGE_ENABLE);
- set_reg_field_value(
- value,
- 1,
- DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
- NB_PSTATE_CHANGE_URGENT_DURING_REQUEST);
- set_reg_field_value(
- value,
- 1,
- DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
- NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST);
- dm_write_reg(ctx, addr, value);
-
- /* Write watermark set A */
- value = dm_read_reg(ctx, addr);
- set_reg_field_value(
- value,
- marks.a_mark,
- DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
- NB_PSTATE_CHANGE_WATERMARK);
- dm_write_reg(ctx, addr, value);
-
- /* Write mask to enable reading/writing of watermark set B */
- addr = offset + mmDPG_WATERMARK_MASK_CONTROL;
- value = dm_read_reg(ctx, addr);
- set_reg_field_value(
- value,
- 1,
- DPG_WATERMARK_MASK_CONTROL,
- NB_PSTATE_CHANGE_WATERMARK_MASK);
- dm_write_reg(ctx, addr, value);
-
- addr = offset + mmDPG_PIPE_NB_PSTATE_CHANGE_CONTROL;
- value = dm_read_reg(ctx, addr);
- set_reg_field_value(
- value,
- 1,
- DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
- NB_PSTATE_CHANGE_ENABLE);
- set_reg_field_value(
- value,
- 1,
- DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
- NB_PSTATE_CHANGE_URGENT_DURING_REQUEST);
- set_reg_field_value(
- value,
- 1,
- DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
- NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST);
- dm_write_reg(ctx, addr, value);
-
- /* Write watermark set B */
- value = dm_read_reg(ctx, addr);
- set_reg_field_value(
- value,
- marks.b_mark,
- DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
- NB_PSTATE_CHANGE_WATERMARK);
- dm_write_reg(ctx, addr, value);
-
- /* Write mask to enable reading/writing of watermark set C */
- addr = offset + mmDPG_WATERMARK_MASK_CONTROL;
- value = dm_read_reg(ctx, addr);
- set_reg_field_value(
- value,
- 2,
- DPG_WATERMARK_MASK_CONTROL,
- NB_PSTATE_CHANGE_WATERMARK_MASK);
- dm_write_reg(ctx, addr, value);
-
- addr = offset + mmDPG_PIPE_NB_PSTATE_CHANGE_CONTROL;
- value = dm_read_reg(ctx, addr);
- set_reg_field_value(
- value,
- 1,
- DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
- NB_PSTATE_CHANGE_ENABLE);
- set_reg_field_value(
- value,
- 1,
- DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
- NB_PSTATE_CHANGE_URGENT_DURING_REQUEST);
- set_reg_field_value(
- value,
- 1,
- DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
- NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST);
- dm_write_reg(ctx, addr, value);
-
- /* Write watermark set C */
- value = dm_read_reg(ctx, addr);
- set_reg_field_value(
- value,
- marks.c_mark,
- DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
- NB_PSTATE_CHANGE_WATERMARK);
- dm_write_reg(ctx, addr, value);
-
- /* Write mask to enable reading/writing of watermark set D */
- addr = offset + mmDPG_WATERMARK_MASK_CONTROL;
- value = dm_read_reg(ctx, addr);
- set_reg_field_value(
- value,
- 3,
- DPG_WATERMARK_MASK_CONTROL,
- NB_PSTATE_CHANGE_WATERMARK_MASK);
- dm_write_reg(ctx, addr, value);
-
- addr = offset + mmDPG_PIPE_NB_PSTATE_CHANGE_CONTROL;
- value = dm_read_reg(ctx, addr);
- set_reg_field_value(
- value,
- 1,
- DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
- NB_PSTATE_CHANGE_ENABLE);
- set_reg_field_value(
- value,
- 1,
- DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
- NB_PSTATE_CHANGE_URGENT_DURING_REQUEST);
- set_reg_field_value(
- value,
- 1,
- DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
- NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST);
- dm_write_reg(ctx, addr, value);
-
- /* Write watermark set D */
- value = dm_read_reg(ctx, addr);
- set_reg_field_value(
- value,
- marks.d_mark,
- DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
- NB_PSTATE_CHANGE_WATERMARK);
- dm_write_reg(ctx, addr, value);
-}
-
-static void dce112_mem_input_program_display_marks(
- struct mem_input *mem_input,
- struct bw_watermarks nbp,
- struct bw_watermarks stutter,
- struct bw_watermarks urgent,
- uint32_t total_dest_line_time_ns)
-{
- struct dce110_mem_input *bm_dce110 = TO_DCE110_MEM_INPUT(mem_input);
-
- program_urgency_watermark(
- mem_input->ctx,
- bm_dce110->offsets.dmif,
- urgent,
- total_dest_line_time_ns);
-
- program_nbp_watermark(
- mem_input->ctx,
- bm_dce110->offsets.dmif,
- nbp);
-
- program_stutter_watermark(
- mem_input->ctx,
- bm_dce110->offsets.dmif,
- stutter);
-}
-
/*****************************************/
/* Constructor, Destructor */
/*****************************************/
@@ -430,7 +48,7 @@ bool dce112_mem_input_construct(
return false;
mem_input110->base.funcs->mem_input_program_display_marks =
- dce112_mem_input_program_display_marks;
+ dce_mem_input_program_display_marks;
return true;
}
diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_mem_input.c b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_mem_input.c
index 8da0e31f1b6a..ebb8df3cdf4a 100644
--- a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_mem_input.c
+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_mem_input.c
@@ -43,133 +43,11 @@
#define DMIF_REG(reg) (reg + mem_input80->offsets.dmif)
#define PIPE_REG(reg) (reg + mem_input80->offsets.pipe)
-static uint32_t get_dmif_switch_time_us(
- uint32_t h_total,
- uint32_t v_total,
- uint32_t pix_clk_khz)
-{
- uint32_t frame_time;
- uint32_t pixels_per_second;
- uint32_t pixels_per_frame;
- uint32_t refresh_rate;
- const uint32_t us_in_sec = 1000000;
- const uint32_t min_single_frame_time_us = 30000;
- /*return double of frame time*/
- const uint32_t single_frame_time_multiplier = 2;
-
- if (!h_total || v_total || !pix_clk_khz)
- return single_frame_time_multiplier * min_single_frame_time_us;
-
- /*TODO: should we use pixel format normalized pixel clock here?*/
- pixels_per_second = pix_clk_khz * 1000;
- pixels_per_frame = h_total * v_total;
-
- if (!pixels_per_second || !pixels_per_frame) {
- /* avoid division by zero */
- ASSERT(pixels_per_frame);
- ASSERT(pixels_per_second);
- return single_frame_time_multiplier * min_single_frame_time_us;
- }
-
- refresh_rate = pixels_per_second / pixels_per_frame;
-
- if (!refresh_rate) {
- /* avoid division by zero*/
- ASSERT(refresh_rate);
- return single_frame_time_multiplier * min_single_frame_time_us;
- }
-
- frame_time = us_in_sec / refresh_rate;
-
- if (frame_time < min_single_frame_time_us)
- frame_time = min_single_frame_time_us;
-
- frame_time *= single_frame_time_multiplier;
-
- return frame_time;
-}
-
-static void allocate_mem_input(
- struct mem_input *mi,
- uint32_t h_total,
- uint32_t v_total,
- uint32_t pix_clk_khz,
- uint32_t total_targets_num)
-{
- const uint32_t retry_delay = 10;
- uint32_t retry_count = get_dmif_switch_time_us(
- h_total,
- v_total,
- pix_clk_khz) / retry_delay;
-
- struct dce110_mem_input *bm80 = TO_DCE110_MEM_INPUT(mi);
- uint32_t addr = bm80->offsets.pipe + mmPIPE0_DMIF_BUFFER_CONTROL;
- uint32_t value;
- uint32_t field;
-
- /*Allocate DMIF buffer*/
- value = dm_read_reg(mi->ctx, addr);
- field = get_reg_field_value(
- value, PIPE0_DMIF_BUFFER_CONTROL, DMIF_BUFFERS_ALLOCATED);
- if (field == 2)
- goto register_underflow_int;
-
- set_reg_field_value(
- value,
- 2,
- PIPE0_DMIF_BUFFER_CONTROL,
- DMIF_BUFFERS_ALLOCATED);
-
- dm_write_reg(mi->ctx, addr, value);
-
- do {
- value = dm_read_reg(mi->ctx, addr);
- field = get_reg_field_value(
- value,
- PIPE0_DMIF_BUFFER_CONTROL,
- DMIF_BUFFERS_ALLOCATION_COMPLETED);
-
- if (field)
- break;
-
- udelay(retry_delay);
- retry_count--;
-
- } while (retry_count > 0);
-
- if (field == 0)
- dm_logger_write(mi->ctx->logger, LOG_ERROR,
- "%s: DMIF allocation failed",
- __func__);
-
- /*
- * Stella Wong proposed the following change
- *
- * Value of mcHubRdReqDmifLimit.ENABLE:
- * 00 - disable DMIF rdreq limit
- * 01 - enable DMIF rdreq limit, disabled by DMIF stall = 1 || urg != 0
- * 02 - enable DMIF rdreq limit, disable by DMIF stall = 1
- * 03 - force enable DMIF rdreq limit, ignore DMIF stall / urgent
- */
- addr = mmMC_HUB_RDREQ_DMIF_LIMIT;
- value = dm_read_reg(mi->ctx, addr);
- if (total_targets_num > 1)
- set_reg_field_value(value, 0, MC_HUB_RDREQ_DMIF_LIMIT, ENABLE);
- else
- set_reg_field_value(value, 3, MC_HUB_RDREQ_DMIF_LIMIT, ENABLE);
- dm_write_reg(mi->ctx, addr, value);
-
-register_underflow_int:
- /*todo*/;
- /*register_interrupt(bm80, irq_source, ctrl_id);*/
-}
-
static struct mem_input_funcs dce80_mem_input_funcs = {
.mem_input_program_display_marks =
dce110_mem_input_program_display_marks,
- .allocate_mem_input = allocate_mem_input,
- .free_mem_input =
- dce110_free_mem_input,
+ .allocate_mem_input = dce_mem_input_allocate_dmif,
+ .free_mem_input = dce_mem_input_free_dmif,
.mem_input_program_surface_flip_and_addr =
dce110_mem_input_program_surface_flip_and_addr,
.mem_input_program_surface_config =
diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_resource.c b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_resource.c
index d2fd25b97996..73110341cb4d 100644
--- a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_resource.c
+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_resource.c
@@ -56,6 +56,11 @@
/* TODO remove this include */
+#ifndef mmMC_HUB_RDREQ_DMIF_LIMIT
+#include "gmc/gmc_7_1_d.h"
+#include "gmc/gmc_7_1_sh_mask.h"
+#endif
+
#ifndef mmDP_DPHY_INTERNAL_CTRL
#define mmDP_DPHY_INTERNAL_CTRL 0x1CDE
#define mmDP0_DP_DPHY_INTERNAL_CTRL 0x1CDE
@@ -453,7 +458,10 @@ static const struct resource_create_funcs res_create_funcs = {
.create_hwseq = dce80_hwseq_create,
};
-#define mi_inst_regs(id) { MI_REG_LIST(id) }
+#define mi_inst_regs(id) { \
+ MI_REG_LIST(id), \
+ .MC_HUB_RDREQ_DMIF_LIMIT = mmMC_HUB_RDREQ_DMIF_LIMIT \
+}
static const struct dce_mem_input_registers mi_regs[] = {
mi_inst_regs(0),
mi_inst_regs(1),
@@ -464,11 +472,13 @@ static const struct dce_mem_input_registers mi_regs[] = {
};
static const struct dce_mem_input_shift mi_shifts = {
- MI_DCE_MASK_SH_LIST(__SHIFT)
+ MI_DCE_MASK_SH_LIST(__SHIFT),
+ .ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE__SHIFT
};
static const struct dce_mem_input_mask mi_masks = {
- MI_DCE_MASK_SH_LIST(_MASK)
+ MI_DCE_MASK_SH_LIST(_MASK),
+ .ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE_MASK
};
static struct mem_input *dce80_mem_input_create(
@@ -488,6 +498,7 @@ static struct mem_input *dce80_mem_input_create(
mi->regs = &mi_regs[inst];
mi->shifts = &mi_shifts;
mi->masks = &mi_masks;
+ mi->wa.single_head_rdreq_dmif_limit = 2;
return mi;
}
diff --git a/drivers/gpu/drm/amd/dal/dc/dm_services.h b/drivers/gpu/drm/amd/dal/dc/dm_services.h
index 289264403983..9cb874a03d54 100644
--- a/drivers/gpu/drm/amd/dal/dc/dm_services.h
+++ b/drivers/gpu/drm/amd/dal/dc/dm_services.h
@@ -70,10 +70,9 @@
#endif /* CONFIG_DEBUG_KERNEL || CONFIG_DEBUG_DRIVER */
-
-#define DC_ERR(err_msg) do { \
+#define DC_ERR(...) do { \
+ dm_error(__VA_ARGS__); \
BREAK_TO_DEBUGGER(); \
- dm_error(err_msg); \
} while (0)
#define dm_alloc(size) kzalloc(size, GFP_KERNEL)
@@ -202,7 +201,8 @@ uint32_t generic_reg_update_ex(const struct dc_context *ctx,
*/
unsigned int generic_reg_wait(const struct dc_context *ctx,
uint32_t addr, uint32_t mask, uint32_t shift, uint32_t condition_value,
- unsigned int delay_between_poll_us, unsigned int time_out_num_tries);
+ unsigned int delay_between_poll_us, unsigned int time_out_num_tries,
+ const char *func_name);
/**************************************
* Power Play (PP) interfaces
diff --git a/drivers/gpu/drm/amd/dal/dc/inc/hw/mem_input.h b/drivers/gpu/drm/amd/dal/dc/inc/hw/mem_input.h
index e7026ec87bce..78dab74edc2d 100644
--- a/drivers/gpu/drm/amd/dal/dc/inc/hw/mem_input.h
+++ b/drivers/gpu/drm/amd/dal/dc/inc/hw/mem_input.h
@@ -48,6 +48,7 @@ struct mem_input {
const struct dce_mem_input_registers *regs;
const struct dce_mem_input_shift *shifts;
const struct dce_mem_input_mask *masks;
+ struct dce_mem_input_wa wa;
};
struct mem_input_funcs {
diff --git a/drivers/gpu/drm/amd/dal/dc/inc/reg_helper.h b/drivers/gpu/drm/amd/dal/dc/inc/reg_helper.h
index 7a05141484c9..92a699337322 100644
--- a/drivers/gpu/drm/amd/dal/dc/inc/reg_helper.h
+++ b/drivers/gpu/drm/amd/dal/dc/inc/reg_helper.h
@@ -156,7 +156,7 @@
#define REG_WAIT(reg_name, field, val, delay, max_try) \
generic_reg_wait(CTX, \
REG(reg_name), FN(reg_name, field), val,\
- delay, max_try)
+ delay, max_try, __func__)
/* macro to update (read, modify, write) register fields
*/
--
2.10.1
More information about the amd-gfx
mailing list