Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/display: Fix DP2.0 timing sync

[Why]
Triggering OTG sync before all OTG/HPO clock programming is complete
causes timing sync to fail and a subsequent P-state hang.

[How]
Move DTB clock programming earlier in the sequence to
enable_stream_timing.

Reviewed-by: Ariel Bernstein <eric.bernstein@amd.com>
Acked-by: Wayne Lin <wayne.lin@amd.com>
Signed-off-by: Ilya Bakoulin <ilya.bakoulin@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Ilya Bakoulin and committed by
Alex Deucher
ce74bece 1288d702

+55 -31
+48 -31
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
··· 670 670 return flow_ctrl_cnt; 671 671 } 672 672 673 + static enum phyd32clk_clock_source get_phyd32clk_src(struct dc_link *link) 674 + { 675 + switch (link->link_enc->transmitter) { 676 + case TRANSMITTER_UNIPHY_A: 677 + return PHYD32CLKA; 678 + case TRANSMITTER_UNIPHY_B: 679 + return PHYD32CLKB; 680 + case TRANSMITTER_UNIPHY_C: 681 + return PHYD32CLKC; 682 + case TRANSMITTER_UNIPHY_D: 683 + return PHYD32CLKD; 684 + case TRANSMITTER_UNIPHY_E: 685 + return PHYD32CLKE; 686 + default: 687 + return PHYD32CLKA; 688 + } 689 + } 690 + 691 + static int get_odm_segment_count(struct pipe_ctx *pipe_ctx) 692 + { 693 + struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe; 694 + int count = 1; 695 + 696 + while (odm_pipe != NULL) { 697 + count++; 698 + odm_pipe = odm_pipe->next_odm_pipe; 699 + } 700 + 701 + return count; 702 + } 703 + 673 704 enum dc_status dcn20_enable_stream_timing( 674 705 struct pipe_ctx *pipe_ctx, 675 706 struct dc_state *context, ··· 848 817 if (pipe_ctx->stream_res.tg && pipe_ctx->stream_res.tg->funcs->phantom_crtc_post_enable) 849 818 pipe_ctx->stream_res.tg->funcs->phantom_crtc_post_enable(pipe_ctx->stream_res.tg); 850 819 } 820 + 821 + if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { 822 + struct dccg *dccg = dc->res_pool->dccg; 823 + struct timing_generator *tg = pipe_ctx->stream_res.tg; 824 + struct dtbclk_dto_params dto_params = {0}; 825 + 826 + if (dccg->funcs->set_dtbclk_p_src) 827 + dccg->funcs->set_dtbclk_p_src(dccg, DTBCLK0, tg->inst); 828 + 829 + dto_params.otg_inst = tg->inst; 830 + dto_params.pixclk_khz = pipe_ctx->stream->timing.pix_clk_100hz / 10; 831 + dto_params.num_odm_segments = get_odm_segment_count(pipe_ctx); 832 + dto_params.timing = &pipe_ctx->stream->timing; 833 + dto_params.ref_dtbclk_khz = dc->clk_mgr->funcs->get_dtb_ref_clk_frequency(dc->clk_mgr); 834 + dccg->funcs->set_dtbclk_dto(dccg, &dto_params); 835 + } 836 + 851 837 return DC_OK; 852 838 } 853 839 ··· 2705 2657 ASSERT(new_mpcc != NULL); 2706 2658 hubp->opp_id = pipe_ctx->stream_res.opp->inst; 2707 2659 hubp->mpcc_id = mpcc_id; 2708 - } 2709 - 2710 - static enum phyd32clk_clock_source get_phyd32clk_src(struct dc_link *link) 2711 - { 2712 - switch (link->link_enc->transmitter) { 2713 - case TRANSMITTER_UNIPHY_A: 2714 - return PHYD32CLKA; 2715 - case TRANSMITTER_UNIPHY_B: 2716 - return PHYD32CLKB; 2717 - case TRANSMITTER_UNIPHY_C: 2718 - return PHYD32CLKC; 2719 - case TRANSMITTER_UNIPHY_D: 2720 - return PHYD32CLKD; 2721 - case TRANSMITTER_UNIPHY_E: 2722 - return PHYD32CLKE; 2723 - default: 2724 - return PHYD32CLKA; 2725 - } 2726 - } 2727 - 2728 - static int get_odm_segment_count(struct pipe_ctx *pipe_ctx) 2729 - { 2730 - struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe; 2731 - int count = 1; 2732 - 2733 - while (odm_pipe != NULL) { 2734 - count++; 2735 - odm_pipe = odm_pipe->next_odm_pipe; 2736 - } 2737 - 2738 - return count; 2739 2660 } 2740 2661 2741 2662 void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
+1
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c
··· 375 375 .set_pixel_rate_div = dccg314_set_pixel_rate_div, 376 376 .trigger_dio_fifo_resync = dccg314_trigger_dio_fifo_resync, 377 377 .set_valid_pixel_rate = dccg314_set_valid_pixel_rate, 378 + .set_dtbclk_p_src = dccg314_set_dtbclk_p_src 378 379 }; 379 380 380 381 struct dccg *dccg314_create(
+1
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c
··· 345 345 .otg_drop_pixel = dccg32_otg_drop_pixel, 346 346 .set_pixel_rate_div = dccg32_set_pixel_rate_div, 347 347 .trigger_dio_fifo_resync = dccg32_trigger_dio_fifo_resync, 348 + .set_dtbclk_p_src = dccg32_set_dtbclk_p_src, 348 349 }; 349 350 350 351 struct dccg *dccg32_create(
+1
drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c
··· 767 767 .set_valid_pixel_rate = dccg35_set_valid_pixel_rate, 768 768 .enable_symclk_se = dccg35_enable_symclk_se, 769 769 .disable_symclk_se = dccg35_disable_symclk_se, 770 + .set_dtbclk_p_src = dccg35_set_dtbclk_p_src, 770 771 }; 771 772 772 773 struct dccg *dccg35_create(
+4
drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h
··· 192 192 void (*set_dp_dto)( 193 193 struct dccg *dccg, 194 194 const struct dp_dto_params *params); 195 + void (*set_dtbclk_p_src)( 196 + struct dccg *dccg, 197 + enum streamclk_source src, 198 + uint32_t otg_inst); 195 199 }; 196 200 197 201 #endif //__DAL_DCCG_H__