diff options
author | Tony Cheng <tony.cheng@amd.com> | 2017-07-14 13:42:23 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2017-09-26 18:15:16 -0400 |
commit | d65359d571aa33dee9ddae659e92d1cb09ffbb2a (patch) | |
tree | 4db612a5c7132d36639cf7f523d4a6c40e9e04a7 /drivers/gpu/drm/amd/display | |
parent | 15e173352eeae76286e0d018f9eec6b55726caa4 (diff) |
drm/amd/display: revert order change of HUBP and MPC disable
- root cause was we disable opp clk in MPC disconnect
- hubp_blank is not double buffered, so we can't blank until MPC disconnect or we have risk of underflow
Signed-off-by: Tony Cheng <tony.cheng@amd.com>
Reviewed-by: Eric Yang <eric.yang2@amd.com>
Acked-by: Harry Wentland <Harry.Wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display')
4 files changed, 32 insertions, 18 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h index 7e1d46fdcc76..94d12b5fb7c6 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h | |||
@@ -288,7 +288,6 @@ struct dce_hwseq_registers { | |||
288 | HWS_SF1(OTG0_, PHYPLL_PIXEL_RATE_CNTL, PHYPLL_PIXEL_RATE_SOURCE, mask_sh), \ | 288 | HWS_SF1(OTG0_, PHYPLL_PIXEL_RATE_CNTL, PHYPLL_PIXEL_RATE_SOURCE, mask_sh), \ |
289 | HWS_SF(OTG0_, OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_EVENT_CLEAR, mask_sh), \ | 289 | HWS_SF(OTG0_, OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_EVENT_CLEAR, mask_sh), \ |
290 | HWS_SF(OTG0_, OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_EVENT_OCCURRED, mask_sh), \ | 290 | HWS_SF(OTG0_, OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_EVENT_OCCURRED, mask_sh), \ |
291 | HWS_SF(HUBP0_, DCHUBP_CNTL, HUBP_NO_OUTSTANDING_REQ, mask_sh), \ | ||
292 | HWS_SF(HUBP0_, DCHUBP_CNTL, HUBP_VTG_SEL, mask_sh), \ | 291 | HWS_SF(HUBP0_, DCHUBP_CNTL, HUBP_VTG_SEL, mask_sh), \ |
293 | HWS_SF(HUBP0_, HUBP_CLK_CNTL, HUBP_CLOCK_ENABLE, mask_sh), \ | 292 | HWS_SF(HUBP0_, HUBP_CLK_CNTL, HUBP_CLOCK_ENABLE, mask_sh), \ |
294 | HWS_SF(DPP_TOP0_, DPP_CONTROL, DPP_CLOCK_ENABLE, mask_sh), \ | 293 | HWS_SF(DPP_TOP0_, DPP_CONTROL, DPP_CLOCK_ENABLE, mask_sh), \ |
@@ -351,7 +350,6 @@ struct dce_hwseq_registers { | |||
351 | #define HWSEQ_DCN_REG_FIELD_LIST(type) \ | 350 | #define HWSEQ_DCN_REG_FIELD_LIST(type) \ |
352 | type VUPDATE_NO_LOCK_EVENT_CLEAR; \ | 351 | type VUPDATE_NO_LOCK_EVENT_CLEAR; \ |
353 | type VUPDATE_NO_LOCK_EVENT_OCCURRED; \ | 352 | type VUPDATE_NO_LOCK_EVENT_OCCURRED; \ |
354 | type HUBP_NO_OUTSTANDING_REQ; \ | ||
355 | type HUBP_VTG_SEL; \ | 353 | type HUBP_VTG_SEL; \ |
356 | type HUBP_CLOCK_ENABLE; \ | 354 | type HUBP_CLOCK_ENABLE; \ |
357 | type DPP_CLOCK_ENABLE; \ | 355 | type DPP_CLOCK_ENABLE; \ |
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 8284837898d2..adf3d2990687 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 | |||
@@ -436,29 +436,17 @@ static void reset_back_end_for_pipe( | |||
436 | pipe_ctx->pipe_idx, pipe_ctx->tg->inst); | 436 | pipe_ctx->pipe_idx, pipe_ctx->tg->inst); |
437 | } | 437 | } |
438 | 438 | ||
439 | static void reset_front_end( | 439 | static void plane_atomic_stop( |
440 | struct core_dc *dc, | 440 | struct core_dc *dc, |
441 | int fe_idx) | 441 | int fe_idx) |
442 | { | 442 | { |
443 | struct dce_hwseq *hws = dc->hwseq; | ||
444 | struct mpcc_cfg mpcc_cfg; | 443 | struct mpcc_cfg mpcc_cfg; |
445 | struct mem_input *mi = dc->res_pool->mis[fe_idx]; | 444 | struct mem_input *mi = dc->res_pool->mis[fe_idx]; |
446 | struct transform *xfm = dc->res_pool->transforms[fe_idx]; | 445 | struct transform *xfm = dc->res_pool->transforms[fe_idx]; |
447 | struct mpcc *mpcc = dc->res_pool->mpcc[fe_idx]; | 446 | struct mpcc *mpcc = dc->res_pool->mpcc[fe_idx]; |
448 | struct timing_generator *tg = dc->res_pool->timing_generators[mpcc->opp_id]; | 447 | struct timing_generator *tg = dc->res_pool->timing_generators[mpcc->opp_id]; |
449 | unsigned int opp_id = mpcc->opp_id; | ||
450 | |||
451 | /*Already reset*/ | ||
452 | if (opp_id == 0xf) | ||
453 | return; | ||
454 | |||
455 | tg->funcs->lock(tg); | ||
456 | 448 | ||
457 | mi->funcs->dcc_control(mi, false, false); | 449 | mi->funcs->dcc_control(mi, false, false); |
458 | mi->funcs->set_blank(mi, true); | ||
459 | REG_WAIT(DCHUBP_CNTL[fe_idx], | ||
460 | HUBP_NO_OUTSTANDING_REQ, 1, | ||
461 | 1, 200); | ||
462 | 450 | ||
463 | mpcc_cfg.opp_id = 0xf; | 451 | mpcc_cfg.opp_id = 0xf; |
464 | mpcc_cfg.top_dpp_id = 0xf; | 452 | mpcc_cfg.top_dpp_id = 0xf; |
@@ -466,23 +454,44 @@ static void reset_front_end( | |||
466 | mpcc_cfg.top_of_tree = tg->inst == mpcc->inst; | 454 | mpcc_cfg.top_of_tree = tg->inst == mpcc->inst; |
467 | mpcc->funcs->set(mpcc, &mpcc_cfg); | 455 | mpcc->funcs->set(mpcc, &mpcc_cfg); |
468 | 456 | ||
457 | xfm->funcs->transform_reset(xfm); | ||
458 | } | ||
459 | |||
460 | static void reset_front_end( | ||
461 | struct core_dc *dc, | ||
462 | int fe_idx) | ||
463 | { | ||
464 | struct dce_hwseq *hws = dc->hwseq; | ||
465 | struct mem_input *mi = dc->res_pool->mis[fe_idx]; | ||
466 | struct mpcc *mpcc = dc->res_pool->mpcc[fe_idx]; | ||
467 | struct timing_generator *tg = dc->res_pool->timing_generators[mpcc->opp_id]; | ||
468 | unsigned int opp_id = mpcc->opp_id; | ||
469 | |||
470 | /*Already reset*/ | ||
471 | if (opp_id == 0xf) | ||
472 | return; | ||
473 | |||
474 | tg->funcs->lock(tg); | ||
475 | |||
476 | plane_atomic_stop(dc, fe_idx); | ||
477 | |||
469 | REG_UPDATE(OTG_GLOBAL_SYNC_STATUS[tg->inst], VUPDATE_NO_LOCK_EVENT_CLEAR, 1); | 478 | REG_UPDATE(OTG_GLOBAL_SYNC_STATUS[tg->inst], VUPDATE_NO_LOCK_EVENT_CLEAR, 1); |
470 | tg->funcs->unlock(tg); | 479 | tg->funcs->unlock(tg); |
471 | REG_WAIT(OTG_GLOBAL_SYNC_STATUS[tg->inst], VUPDATE_NO_LOCK_EVENT_OCCURRED, 1, 20000, 200000); | 480 | REG_WAIT(OTG_GLOBAL_SYNC_STATUS[tg->inst], VUPDATE_NO_LOCK_EVENT_OCCURRED, 1, 20000, 200000); |
472 | 481 | ||
473 | mpcc->funcs->wait_for_idle(mpcc); | 482 | mpcc->funcs->wait_for_idle(mpcc); |
474 | 483 | ||
484 | mi->funcs->set_blank(mi, true); | ||
485 | |||
475 | REG_UPDATE(HUBP_CLK_CNTL[fe_idx], | 486 | REG_UPDATE(HUBP_CLK_CNTL[fe_idx], |
476 | HUBP_CLOCK_ENABLE, 0); | 487 | HUBP_CLOCK_ENABLE, 0); |
477 | REG_UPDATE(DPP_CONTROL[fe_idx], | 488 | REG_UPDATE(DPP_CONTROL[fe_idx], |
478 | DPP_CLOCK_ENABLE, 0); | 489 | DPP_CLOCK_ENABLE, 0); |
479 | 490 | ||
480 | if (mpcc_cfg.top_of_tree) | 491 | if (tg->inst == mpcc->inst) |
481 | REG_UPDATE(OPP_PIPE_CONTROL[opp_id], | 492 | REG_UPDATE(OPP_PIPE_CONTROL[opp_id], |
482 | OPP_PIPE_CLOCK_EN, 0); | 493 | OPP_PIPE_CLOCK_EN, 0); |
483 | 494 | ||
484 | xfm->funcs->transform_reset(xfm); | ||
485 | |||
486 | dm_logger_write(dc->ctx->logger, LOG_DC, | 495 | dm_logger_write(dc->ctx->logger, LOG_DC, |
487 | "Reset front end %d\n", | 496 | "Reset front end %d\n", |
488 | fe_idx); | 497 | fe_idx); |
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c index efa02d160d1a..8054794dd96d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c | |||
@@ -46,6 +46,11 @@ static void min10_set_blank(struct mem_input *mem_input, bool blank) | |||
46 | REG_UPDATE_2(DCHUBP_CNTL, | 46 | REG_UPDATE_2(DCHUBP_CNTL, |
47 | HUBP_BLANK_EN, blank_en, | 47 | HUBP_BLANK_EN, blank_en, |
48 | HUBP_TTU_DISABLE, blank_en); | 48 | HUBP_TTU_DISABLE, blank_en); |
49 | |||
50 | if (blank) | ||
51 | REG_WAIT(DCHUBP_CNTL, | ||
52 | HUBP_NO_OUTSTANDING_REQ, 1, | ||
53 | 1, 200); | ||
49 | } | 54 | } |
50 | 55 | ||
51 | static void min10_vready_workaround(struct mem_input *mem_input, | 56 | static void min10_vready_workaround(struct mem_input *mem_input, |
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h index 7efa857b8710..a0a1cef38d18 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h | |||
@@ -304,6 +304,7 @@ struct dcn_mi_registers { | |||
304 | #define MI_MASK_SH_LIST_DCN(mask_sh)\ | 304 | #define MI_MASK_SH_LIST_DCN(mask_sh)\ |
305 | MI_SF(HUBP0_DCHUBP_CNTL, HUBP_BLANK_EN, mask_sh),\ | 305 | MI_SF(HUBP0_DCHUBP_CNTL, HUBP_BLANK_EN, mask_sh),\ |
306 | MI_SF(HUBP0_DCHUBP_CNTL, HUBP_TTU_DISABLE, mask_sh),\ | 306 | MI_SF(HUBP0_DCHUBP_CNTL, HUBP_TTU_DISABLE, mask_sh),\ |
307 | MI_SF(HUBP0_DCHUBP_CNTL, HUBP_NO_OUTSTANDING_REQ, mask_sh),\ | ||
307 | MI_SF(HUBP0_DCSURF_ADDR_CONFIG, NUM_PIPES, mask_sh),\ | 308 | MI_SF(HUBP0_DCSURF_ADDR_CONFIG, NUM_PIPES, mask_sh),\ |
308 | MI_SF(HUBP0_DCSURF_ADDR_CONFIG, NUM_BANKS, mask_sh),\ | 309 | MI_SF(HUBP0_DCSURF_ADDR_CONFIG, NUM_BANKS, mask_sh),\ |
309 | MI_SF(HUBP0_DCSURF_ADDR_CONFIG, PIPE_INTERLEAVE, mask_sh),\ | 310 | MI_SF(HUBP0_DCSURF_ADDR_CONFIG, PIPE_INTERLEAVE, mask_sh),\ |
@@ -463,6 +464,7 @@ struct dcn_mi_registers { | |||
463 | #define DCN_MI_REG_FIELD_LIST(type) \ | 464 | #define DCN_MI_REG_FIELD_LIST(type) \ |
464 | type HUBP_BLANK_EN;\ | 465 | type HUBP_BLANK_EN;\ |
465 | type HUBP_TTU_DISABLE;\ | 466 | type HUBP_TTU_DISABLE;\ |
467 | type HUBP_NO_OUTSTANDING_REQ;\ | ||
466 | type NUM_PIPES;\ | 468 | type NUM_PIPES;\ |
467 | type NUM_BANKS;\ | 469 | type NUM_BANKS;\ |
468 | type PIPE_INTERLEAVE;\ | 470 | type PIPE_INTERLEAVE;\ |