Commit 2750160b authored by Charlene Liu's avatar Charlene Liu Committed by Alex Deucher

drm/amd/display: dcn add check surface in_use

Driver need to  poll the SURFACE_INUSE register to determine when to
start the new task and write data to the checked surface.

Implement the wait functions, and add the necessary hubbub registers.
Signed-off-by: default avatarCharlene Liu <charlene.liu@amd.com>
Reviewed-by: default avatarDmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Acked-by: default avatarLeo Li <sunpeng.li@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 46f81fc4
...@@ -1726,6 +1726,9 @@ static void commit_planes_for_stream(struct dc *dc, ...@@ -1726,6 +1726,9 @@ static void commit_planes_for_stream(struct dc *dc,
if (!pipe_ctx->plane_state) if (!pipe_ctx->plane_state)
continue; continue;
/*make sure hw finished surface update*/
if (dc->hwss.wait_surface_safe_to_update)
dc->hwss.wait_surface_safe_to_update(dc, pipe_ctx);
/* Full fe update*/ /* Full fe update*/
if (update_type == UPDATE_TYPE_FAST) if (update_type == UPDATE_TYPE_FAST)
......
...@@ -642,6 +642,50 @@ void hubbub1_soft_reset(struct hubbub *hubbub, bool reset) ...@@ -642,6 +642,50 @@ void hubbub1_soft_reset(struct hubbub *hubbub, bool reset)
DCHUBBUB_GLOBAL_SOFT_RESET, reset_en); DCHUBBUB_GLOBAL_SOFT_RESET, reset_en);
} }
static bool hubbub1_is_surf_still_in_update(struct hubbub *hubbub, uint32_t hbup_inst)
{
struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
uint32_t still_used_by_dcn = 0;
switch (hbup_inst) {
case 0:
REG_GET(SURFACE_CHECK0_ADDRESS_MSB,
CHECKER0_SURFACE_INUSE,
&still_used_by_dcn);
break;
case 1:
REG_GET(SURFACE_CHECK1_ADDRESS_MSB,
CHECKER1_SURFACE_INUSE,
&still_used_by_dcn);
break;
case 2:
REG_GET(SURFACE_CHECK2_ADDRESS_MSB,
CHECKER2_SURFACE_INUSE,
&still_used_by_dcn);
break;
case 3:
REG_GET(SURFACE_CHECK3_ADDRESS_MSB,
CHECKER3_SURFACE_INUSE,
&still_used_by_dcn);
break;
default:
break;
}
return (still_used_by_dcn == 1);
}
void hubbub1_wait_for_safe_surf_update(struct hubbub *hubbub, uint32_t hbup_inst)
{
uint32_t still_used_by_dcn = 0, count = 0;
do {
still_used_by_dcn = hubbub1_is_surf_still_in_update(hubbub, hbup_inst);
udelay(1);
count++;
} while (still_used_by_dcn == 1 && count < 100);
ASSERT(count < 100);
}
static bool hubbub1_dcc_support_swizzle( static bool hubbub1_dcc_support_swizzle(
enum swizzle_mode_values swizzle, enum swizzle_mode_values swizzle,
unsigned int bytes_per_element, unsigned int bytes_per_element,
...@@ -860,12 +904,14 @@ static bool hubbub1_get_dcc_compression_cap(struct hubbub *hubbub, ...@@ -860,12 +904,14 @@ static bool hubbub1_get_dcc_compression_cap(struct hubbub *hubbub,
return true; return true;
} }
static const struct hubbub_funcs hubbub1_funcs = { static const struct hubbub_funcs hubbub1_funcs = {
.update_dchub = hubbub1_update_dchub, .update_dchub = hubbub1_update_dchub,
.dcc_support_swizzle = hubbub1_dcc_support_swizzle, .dcc_support_swizzle = hubbub1_dcc_support_swizzle,
.dcc_support_pixel_format = hubbub1_dcc_support_pixel_format, .dcc_support_pixel_format = hubbub1_dcc_support_pixel_format,
.get_dcc_compression_cap = hubbub1_get_dcc_compression_cap, .get_dcc_compression_cap = hubbub1_get_dcc_compression_cap,
.wm_read_state = hubbub1_wm_read_state, .wm_read_state = hubbub1_wm_read_state,
.wait_for_surf_safe_update = hubbub1_wait_for_safe_surf_update,
}; };
void hubbub1_construct(struct hubbub *hubbub, void hubbub1_construct(struct hubbub *hubbub,
......
...@@ -52,7 +52,11 @@ ...@@ -52,7 +52,11 @@
SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \ SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \
SR(DCHUBBUB_TEST_DEBUG_INDEX), \ SR(DCHUBBUB_TEST_DEBUG_INDEX), \
SR(DCHUBBUB_TEST_DEBUG_DATA),\ SR(DCHUBBUB_TEST_DEBUG_DATA),\
SR(DCHUBBUB_SOFT_RESET) SR(DCHUBBUB_SOFT_RESET),\
SR(SURFACE_CHECK0_ADDRESS_MSB),\
SR(SURFACE_CHECK1_ADDRESS_MSB),\
SR(SURFACE_CHECK2_ADDRESS_MSB),\
SR(SURFACE_CHECK3_ADDRESS_MSB)
#define HUBBUB_SR_WATERMARK_REG_LIST()\ #define HUBBUB_SR_WATERMARK_REG_LIST()\
SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A),\ SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A),\
...@@ -116,6 +120,10 @@ struct dcn_hubbub_registers { ...@@ -116,6 +120,10 @@ struct dcn_hubbub_registers {
uint32_t DCN_VM_AGP_BOT; uint32_t DCN_VM_AGP_BOT;
uint32_t DCN_VM_AGP_TOP; uint32_t DCN_VM_AGP_TOP;
uint32_t DCN_VM_AGP_BASE; uint32_t DCN_VM_AGP_BASE;
uint32_t SURFACE_CHECK0_ADDRESS_MSB;
uint32_t SURFACE_CHECK1_ADDRESS_MSB;
uint32_t SURFACE_CHECK2_ADDRESS_MSB;
uint32_t SURFACE_CHECK3_ADDRESS_MSB;
}; };
/* set field name */ /* set field name */
...@@ -133,7 +141,11 @@ struct dcn_hubbub_registers { ...@@ -133,7 +141,11 @@ struct dcn_hubbub_registers {
HUBBUB_SF(DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, mask_sh), \ HUBBUB_SF(DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, mask_sh), \
HUBBUB_SF(DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, mask_sh), \ HUBBUB_SF(DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, mask_sh), \
HUBBUB_SF(DCHUBBUB_ARB_SAT_LEVEL, DCHUBBUB_ARB_SAT_LEVEL, mask_sh), \ HUBBUB_SF(DCHUBBUB_ARB_SAT_LEVEL, DCHUBBUB_ARB_SAT_LEVEL, mask_sh), \
HUBBUB_SF(DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND, mask_sh) HUBBUB_SF(DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND, mask_sh),\
HUBBUB_SF(SURFACE_CHECK0_ADDRESS_MSB, CHECKER0_SURFACE_INUSE, mask_sh),\
HUBBUB_SF(SURFACE_CHECK1_ADDRESS_MSB, CHECKER1_SURFACE_INUSE, mask_sh),\
HUBBUB_SF(SURFACE_CHECK2_ADDRESS_MSB, CHECKER2_SURFACE_INUSE, mask_sh),\
HUBBUB_SF(SURFACE_CHECK3_ADDRESS_MSB, CHECKER3_SURFACE_INUSE, mask_sh)
#define HUBBUB_MASK_SH_LIST_DCN10(mask_sh)\ #define HUBBUB_MASK_SH_LIST_DCN10(mask_sh)\
HUBBUB_MASK_SH_LIST_DCN(mask_sh), \ HUBBUB_MASK_SH_LIST_DCN(mask_sh), \
...@@ -167,7 +179,12 @@ struct dcn_hubbub_registers { ...@@ -167,7 +179,12 @@ struct dcn_hubbub_registers {
type FB_OFFSET;\ type FB_OFFSET;\
type AGP_BOT;\ type AGP_BOT;\
type AGP_TOP;\ type AGP_TOP;\
type AGP_BASE type AGP_BASE;\
type CHECKER0_SURFACE_INUSE;\
type CHECKER1_SURFACE_INUSE;\
type CHECKER2_SURFACE_INUSE;\
type CHECKER3_SURFACE_INUSE
struct dcn_hubbub_shift { struct dcn_hubbub_shift {
...@@ -215,6 +232,8 @@ void hubbub1_wm_read_state(struct hubbub *hubbub, ...@@ -215,6 +232,8 @@ void hubbub1_wm_read_state(struct hubbub *hubbub,
struct dcn_hubbub_wm *wm); struct dcn_hubbub_wm *wm);
void hubbub1_soft_reset(struct hubbub *hubbub, bool reset); void hubbub1_soft_reset(struct hubbub *hubbub, bool reset);
void hubbub1_wait_for_safe_surf_update(struct hubbub *hubbub, uint32_t hbup_inst);
void hubbub1_construct(struct hubbub *hubbub, void hubbub1_construct(struct hubbub *hubbub,
struct dc_context *ctx, struct dc_context *ctx,
const struct dcn_hubbub_registers *hubbub_regs, const struct dcn_hubbub_registers *hubbub_regs,
......
...@@ -88,6 +88,24 @@ static void log_mpc_crc(struct dc *dc, ...@@ -88,6 +88,24 @@ static void log_mpc_crc(struct dc *dc,
REG_READ(DPP_TOP0_DPP_CRC_VAL_B_A), REG_READ(DPP_TOP0_DPP_CRC_VAL_R_G)); REG_READ(DPP_TOP0_DPP_CRC_VAL_B_A), REG_READ(DPP_TOP0_DPP_CRC_VAL_R_G));
} }
void dcn10_wait_for_surface_safe_to_use(struct dc *dc,
struct pipe_ctx *pipe_ctx)
{
struct hubbub *hubbub = dc->res_pool->hubbub;
if (!pipe_ctx->plane_state)
return;
if (!pipe_ctx->stream)
return;
if (!pipe_ctx->plane_state->visible)
return;
if (hubbub->funcs->wait_for_surf_safe_update) {
hubbub->funcs->wait_for_surf_safe_update(dc->res_pool->hubbub,
pipe_ctx->plane_res.hubp->inst);
}
}
void dcn10_log_hubbub_state(struct dc *dc, struct dc_log_buffer_ctx *log_ctx) void dcn10_log_hubbub_state(struct dc *dc, struct dc_log_buffer_ctx *log_ctx)
{ {
struct dc_context *dc_ctx = dc->ctx; struct dc_context *dc_ctx = dc->ctx;
...@@ -2946,7 +2964,9 @@ static const struct hw_sequencer_funcs dcn10_funcs = { ...@@ -2946,7 +2964,9 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
.disable_stream_gating = NULL, .disable_stream_gating = NULL,
.enable_stream_gating = NULL, .enable_stream_gating = NULL,
.setup_periodic_interrupt = dcn10_setup_periodic_interrupt, .setup_periodic_interrupt = dcn10_setup_periodic_interrupt,
.setup_vupdate_interrupt = dcn10_setup_vupdate_interrupt .setup_vupdate_interrupt = dcn10_setup_vupdate_interrupt,
.wait_surface_safe_to_update = dcn10_wait_for_surface_safe_to_use,
}; };
......
...@@ -73,6 +73,9 @@ struct hubbub_funcs { ...@@ -73,6 +73,9 @@ struct hubbub_funcs {
void (*wm_read_state)(struct hubbub *hubbub, void (*wm_read_state)(struct hubbub *hubbub,
struct dcn_hubbub_wm *wm); struct dcn_hubbub_wm *wm);
void (*wait_for_surf_safe_update)(struct hubbub *hubbub,
uint32_t hbup_inst);
}; };
struct hubbub { struct hubbub {
......
...@@ -232,6 +232,8 @@ struct hw_sequencer_funcs { ...@@ -232,6 +232,8 @@ struct hw_sequencer_funcs {
void (*setup_periodic_interrupt)(struct pipe_ctx *pipe_ctx, enum vline_select vline); void (*setup_periodic_interrupt)(struct pipe_ctx *pipe_ctx, enum vline_select vline);
void (*setup_vupdate_interrupt)(struct pipe_ctx *pipe_ctx); void (*setup_vupdate_interrupt)(struct pipe_ctx *pipe_ctx);
void (*wait_surface_safe_to_update)(struct dc *dc,
struct pipe_ctx *pipe_ctx);
}; };
void color_space_to_black_color( void color_space_to_black_color(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment