diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc')
21 files changed, 228 insertions, 126 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 35e84ed031de..12868c769606 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c | |||
@@ -1358,13 +1358,13 @@ enum dc_irq_source dc_interrupt_to_irq_source( | |||
1358 | return dal_irq_service_to_irq_source(dc->res_pool->irqs, src_id, ext_id); | 1358 | return dal_irq_service_to_irq_source(dc->res_pool->irqs, src_id, ext_id); |
1359 | } | 1359 | } |
1360 | 1360 | ||
1361 | void dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable) | 1361 | bool dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable) |
1362 | { | 1362 | { |
1363 | 1363 | ||
1364 | if (dc == NULL) | 1364 | if (dc == NULL) |
1365 | return; | 1365 | return false; |
1366 | 1366 | ||
1367 | dal_irq_service_set(dc->res_pool->irqs, src, enable); | 1367 | return dal_irq_service_set(dc->res_pool->irqs, src, enable); |
1368 | } | 1368 | } |
1369 | 1369 | ||
1370 | void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src) | 1370 | void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src) |
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index a37428271573..be5546181fa8 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c | |||
@@ -1749,8 +1749,7 @@ static void enable_link_hdmi(struct pipe_ctx *pipe_ctx) | |||
1749 | link->link_enc, | 1749 | link->link_enc, |
1750 | pipe_ctx->clock_source->id, | 1750 | pipe_ctx->clock_source->id, |
1751 | display_color_depth, | 1751 | display_color_depth, |
1752 | pipe_ctx->stream->signal == SIGNAL_TYPE_HDMI_TYPE_A, | 1752 | pipe_ctx->stream->signal, |
1753 | pipe_ctx->stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK, | ||
1754 | stream->phy_pix_clk); | 1753 | stream->phy_pix_clk); |
1755 | 1754 | ||
1756 | if (pipe_ctx->stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) | 1755 | if (pipe_ctx->stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) |
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index 95b8dd0e53c6..4d07ffebfd31 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c | |||
@@ -1360,9 +1360,6 @@ bool dc_is_stream_scaling_unchanged( | |||
1360 | return true; | 1360 | return true; |
1361 | } | 1361 | } |
1362 | 1362 | ||
1363 | /* Maximum TMDS single link pixel clock 165MHz */ | ||
1364 | #define TMDS_MAX_PIXEL_CLOCK_IN_KHZ 165000 | ||
1365 | |||
1366 | static void update_stream_engine_usage( | 1363 | static void update_stream_engine_usage( |
1367 | struct resource_context *res_ctx, | 1364 | struct resource_context *res_ctx, |
1368 | const struct resource_pool *pool, | 1365 | const struct resource_pool *pool, |
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 539c3e0a6292..cd5819789d76 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c | |||
@@ -33,8 +33,7 @@ | |||
33 | /******************************************************************************* | 33 | /******************************************************************************* |
34 | * Private functions | 34 | * Private functions |
35 | ******************************************************************************/ | 35 | ******************************************************************************/ |
36 | #define TMDS_MAX_PIXEL_CLOCK_IN_KHZ_UPMOST 297000 | 36 | void update_stream_signal(struct dc_stream_state *stream) |
37 | static void update_stream_signal(struct dc_stream_state *stream) | ||
38 | { | 37 | { |
39 | 38 | ||
40 | struct dc_sink *dc_sink = stream->sink; | 39 | struct dc_sink *dc_sink = stream->sink; |
@@ -45,8 +44,9 @@ static void update_stream_signal(struct dc_stream_state *stream) | |||
45 | stream->signal = dc_sink->sink_signal; | 44 | stream->signal = dc_sink->sink_signal; |
46 | 45 | ||
47 | if (dc_is_dvi_signal(stream->signal)) { | 46 | if (dc_is_dvi_signal(stream->signal)) { |
48 | if (stream->timing.pix_clk_khz > TMDS_MAX_PIXEL_CLOCK_IN_KHZ_UPMOST && | 47 | if (stream->ctx->dc->caps.dual_link_dvi && |
49 | stream->sink->sink_signal != SIGNAL_TYPE_DVI_SINGLE_LINK) | 48 | stream->timing.pix_clk_khz > TMDS_MAX_PIXEL_CLOCK && |
49 | stream->sink->sink_signal != SIGNAL_TYPE_DVI_SINGLE_LINK) | ||
50 | stream->signal = SIGNAL_TYPE_DVI_DUAL_LINK; | 50 | stream->signal = SIGNAL_TYPE_DVI_DUAL_LINK; |
51 | else | 51 | else |
52 | stream->signal = SIGNAL_TYPE_DVI_SINGLE_LINK; | 52 | stream->signal = SIGNAL_TYPE_DVI_SINGLE_LINK; |
@@ -193,6 +193,7 @@ bool dc_stream_set_cursor_attributes( | |||
193 | 193 | ||
194 | core_dc = stream->ctx->dc; | 194 | core_dc = stream->ctx->dc; |
195 | res_ctx = &core_dc->current_state->res_ctx; | 195 | res_ctx = &core_dc->current_state->res_ctx; |
196 | stream->cursor_attributes = *attributes; | ||
196 | 197 | ||
197 | for (i = 0; i < MAX_PIPES; i++) { | 198 | for (i = 0; i < MAX_PIPES; i++) { |
198 | struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; | 199 | struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; |
@@ -204,34 +205,8 @@ bool dc_stream_set_cursor_attributes( | |||
204 | continue; | 205 | continue; |
205 | 206 | ||
206 | 207 | ||
207 | if (pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes != NULL) | 208 | core_dc->hwss.set_cursor_attribute(pipe_ctx); |
208 | pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes( | ||
209 | pipe_ctx->plane_res.ipp, attributes); | ||
210 | |||
211 | if (pipe_ctx->plane_res.hubp != NULL && | ||
212 | pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes != NULL) | ||
213 | pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes( | ||
214 | pipe_ctx->plane_res.hubp, attributes); | ||
215 | |||
216 | if (pipe_ctx->plane_res.mi != NULL && | ||
217 | pipe_ctx->plane_res.mi->funcs->set_cursor_attributes != NULL) | ||
218 | pipe_ctx->plane_res.mi->funcs->set_cursor_attributes( | ||
219 | pipe_ctx->plane_res.mi, attributes); | ||
220 | |||
221 | |||
222 | if (pipe_ctx->plane_res.xfm != NULL && | ||
223 | pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes != NULL) | ||
224 | pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes( | ||
225 | pipe_ctx->plane_res.xfm, attributes); | ||
226 | |||
227 | if (pipe_ctx->plane_res.dpp != NULL && | ||
228 | pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes != NULL) | ||
229 | pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes( | ||
230 | pipe_ctx->plane_res.dpp, attributes->color_format); | ||
231 | } | 209 | } |
232 | |||
233 | stream->cursor_attributes = *attributes; | ||
234 | |||
235 | return true; | 210 | return true; |
236 | } | 211 | } |
237 | 212 | ||
@@ -255,21 +230,10 @@ bool dc_stream_set_cursor_position( | |||
255 | 230 | ||
256 | core_dc = stream->ctx->dc; | 231 | core_dc = stream->ctx->dc; |
257 | res_ctx = &core_dc->current_state->res_ctx; | 232 | res_ctx = &core_dc->current_state->res_ctx; |
233 | stream->cursor_position = *position; | ||
258 | 234 | ||
259 | for (i = 0; i < MAX_PIPES; i++) { | 235 | for (i = 0; i < MAX_PIPES; i++) { |
260 | struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; | 236 | struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; |
261 | struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp; | ||
262 | struct mem_input *mi = pipe_ctx->plane_res.mi; | ||
263 | struct hubp *hubp = pipe_ctx->plane_res.hubp; | ||
264 | struct dpp *dpp = pipe_ctx->plane_res.dpp; | ||
265 | struct dc_cursor_position pos_cpy = *position; | ||
266 | struct dc_cursor_mi_param param = { | ||
267 | .pixel_clk_khz = stream->timing.pix_clk_khz, | ||
268 | .ref_clk_khz = core_dc->res_pool->ref_clock_inKhz, | ||
269 | .viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x, | ||
270 | .viewport_width = pipe_ctx->plane_res.scl_data.viewport.width, | ||
271 | .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz | ||
272 | }; | ||
273 | 237 | ||
274 | if (pipe_ctx->stream != stream || | 238 | if (pipe_ctx->stream != stream || |
275 | (!pipe_ctx->plane_res.mi && !pipe_ctx->plane_res.hubp) || | 239 | (!pipe_ctx->plane_res.mi && !pipe_ctx->plane_res.hubp) || |
@@ -278,33 +242,9 @@ bool dc_stream_set_cursor_position( | |||
278 | !pipe_ctx->plane_res.ipp) | 242 | !pipe_ctx->plane_res.ipp) |
279 | continue; | 243 | continue; |
280 | 244 | ||
281 | if (pipe_ctx->plane_state->address.type | 245 | core_dc->hwss.set_cursor_position(pipe_ctx); |
282 | == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) | ||
283 | pos_cpy.enable = false; | ||
284 | |||
285 | if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state) | ||
286 | pos_cpy.enable = false; | ||
287 | |||
288 | |||
289 | if (ipp != NULL && ipp->funcs->ipp_cursor_set_position != NULL) | ||
290 | ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, ¶m); | ||
291 | |||
292 | if (mi != NULL && mi->funcs->set_cursor_position != NULL) | ||
293 | mi->funcs->set_cursor_position(mi, &pos_cpy, ¶m); | ||
294 | |||
295 | if (!hubp) | ||
296 | continue; | ||
297 | |||
298 | if (hubp->funcs->set_cursor_position != NULL) | ||
299 | hubp->funcs->set_cursor_position(hubp, &pos_cpy, ¶m); | ||
300 | |||
301 | if (dpp != NULL && dpp->funcs->set_cursor_position != NULL) | ||
302 | dpp->funcs->set_cursor_position(dpp, &pos_cpy, ¶m, hubp->curs_attr.width); | ||
303 | |||
304 | } | 246 | } |
305 | 247 | ||
306 | stream->cursor_position = *position; | ||
307 | |||
308 | return true; | 248 | return true; |
309 | } | 249 | } |
310 | 250 | ||
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index e2e3c9df79ea..d6d56611604e 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h | |||
@@ -62,6 +62,7 @@ struct dc_caps { | |||
62 | bool dcc_const_color; | 62 | bool dcc_const_color; |
63 | bool dynamic_audio; | 63 | bool dynamic_audio; |
64 | bool is_apu; | 64 | bool is_apu; |
65 | bool dual_link_dvi; | ||
65 | }; | 66 | }; |
66 | 67 | ||
67 | struct dc_dcc_surface_param { | 68 | struct dc_dcc_surface_param { |
@@ -672,7 +673,7 @@ enum dc_irq_source dc_interrupt_to_irq_source( | |||
672 | struct dc *dc, | 673 | struct dc *dc, |
673 | uint32_t src_id, | 674 | uint32_t src_id, |
674 | uint32_t ext_id); | 675 | uint32_t ext_id); |
675 | void dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable); | 676 | bool dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable); |
676 | void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src); | 677 | void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src); |
677 | enum dc_irq_source dc_get_hpd_irq_source_at_index( | 678 | enum dc_irq_source dc_get_hpd_irq_source_at_index( |
678 | struct dc *dc, uint32_t link_index); | 679 | struct dc *dc, uint32_t link_index); |
diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h index 01c60f11b2bd..456e4d29eadd 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h | |||
@@ -237,6 +237,8 @@ enum surface_update_type dc_check_update_surfaces_for_stream( | |||
237 | */ | 237 | */ |
238 | struct dc_stream_state *dc_create_stream_for_sink(struct dc_sink *dc_sink); | 238 | struct dc_stream_state *dc_create_stream_for_sink(struct dc_sink *dc_sink); |
239 | 239 | ||
240 | void update_stream_signal(struct dc_stream_state *stream); | ||
241 | |||
240 | void dc_stream_retain(struct dc_stream_state *dc_stream); | 242 | void dc_stream_retain(struct dc_stream_state *dc_stream); |
241 | void dc_stream_release(struct dc_stream_state *dc_stream); | 243 | void dc_stream_release(struct dc_stream_state *dc_stream); |
242 | 244 | ||
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 b73db9e78437..f11f17fe08f9 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h | |||
@@ -236,6 +236,7 @@ | |||
236 | SR(D2VGA_CONTROL), \ | 236 | SR(D2VGA_CONTROL), \ |
237 | SR(D3VGA_CONTROL), \ | 237 | SR(D3VGA_CONTROL), \ |
238 | SR(D4VGA_CONTROL), \ | 238 | SR(D4VGA_CONTROL), \ |
239 | SR(VGA_TEST_CONTROL), \ | ||
239 | SR(DC_IP_REQUEST_CNTL), \ | 240 | SR(DC_IP_REQUEST_CNTL), \ |
240 | BL_REG_LIST() | 241 | BL_REG_LIST() |
241 | 242 | ||
@@ -337,6 +338,7 @@ struct dce_hwseq_registers { | |||
337 | uint32_t D2VGA_CONTROL; | 338 | uint32_t D2VGA_CONTROL; |
338 | uint32_t D3VGA_CONTROL; | 339 | uint32_t D3VGA_CONTROL; |
339 | uint32_t D4VGA_CONTROL; | 340 | uint32_t D4VGA_CONTROL; |
341 | uint32_t VGA_TEST_CONTROL; | ||
340 | /* MMHUB registers. read only. temporary hack */ | 342 | /* MMHUB registers. read only. temporary hack */ |
341 | uint32_t VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32; | 343 | uint32_t VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32; |
342 | uint32_t VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32; | 344 | uint32_t VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32; |
@@ -493,6 +495,12 @@ struct dce_hwseq_registers { | |||
493 | HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \ | 495 | HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \ |
494 | HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \ | 496 | HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \ |
495 | HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \ | 497 | HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \ |
498 | HWS_SF(, D1VGA_CONTROL, D1VGA_MODE_ENABLE, mask_sh),\ | ||
499 | HWS_SF(, D2VGA_CONTROL, D2VGA_MODE_ENABLE, mask_sh),\ | ||
500 | HWS_SF(, D3VGA_CONTROL, D3VGA_MODE_ENABLE, mask_sh),\ | ||
501 | HWS_SF(, D4VGA_CONTROL, D4VGA_MODE_ENABLE, mask_sh),\ | ||
502 | HWS_SF(, VGA_TEST_CONTROL, VGA_TEST_ENABLE, mask_sh),\ | ||
503 | HWS_SF(, VGA_TEST_CONTROL, VGA_TEST_RENDER_START, mask_sh),\ | ||
496 | HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \ | 504 | HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \ |
497 | HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh) | 505 | HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh) |
498 | 506 | ||
@@ -583,7 +591,13 @@ struct dce_hwseq_registers { | |||
583 | type DCFCLK_GATE_DIS; \ | 591 | type DCFCLK_GATE_DIS; \ |
584 | type DCHUBBUB_GLOBAL_TIMER_REFDIV; \ | 592 | type DCHUBBUB_GLOBAL_TIMER_REFDIV; \ |
585 | type DENTIST_DPPCLK_WDIVIDER; \ | 593 | type DENTIST_DPPCLK_WDIVIDER; \ |
586 | type DENTIST_DISPCLK_WDIVIDER; | 594 | type DENTIST_DISPCLK_WDIVIDER; \ |
595 | type VGA_TEST_ENABLE; \ | ||
596 | type VGA_TEST_RENDER_START; \ | ||
597 | type D1VGA_MODE_ENABLE; \ | ||
598 | type D2VGA_MODE_ENABLE; \ | ||
599 | type D3VGA_MODE_ENABLE; \ | ||
600 | type D4VGA_MODE_ENABLE; | ||
587 | 601 | ||
588 | struct dce_hwseq_shift { | 602 | struct dce_hwseq_shift { |
589 | HWSEQ_REG_FIELD_LIST(uint8_t) | 603 | HWSEQ_REG_FIELD_LIST(uint8_t) |
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c index a266e3f5e75f..e4741f1a2b01 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c | |||
@@ -82,13 +82,6 @@ | |||
82 | #define DCE110_DIG_FE_SOURCE_SELECT_DIGF 0x20 | 82 | #define DCE110_DIG_FE_SOURCE_SELECT_DIGF 0x20 |
83 | #define DCE110_DIG_FE_SOURCE_SELECT_DIGG 0x40 | 83 | #define DCE110_DIG_FE_SOURCE_SELECT_DIGG 0x40 |
84 | 84 | ||
85 | /* Minimum pixel clock, in KHz. For TMDS signal is 25.00 MHz */ | ||
86 | #define TMDS_MIN_PIXEL_CLOCK 25000 | ||
87 | /* Maximum pixel clock, in KHz. For TMDS signal is 165.00 MHz */ | ||
88 | #define TMDS_MAX_PIXEL_CLOCK 165000 | ||
89 | /* For current ASICs pixel clock - 600MHz */ | ||
90 | #define MAX_ENCODER_CLOCK 600000 | ||
91 | |||
92 | enum { | 85 | enum { |
93 | DP_MST_UPDATE_MAX_RETRY = 50 | 86 | DP_MST_UPDATE_MAX_RETRY = 50 |
94 | }; | 87 | }; |
@@ -683,6 +676,7 @@ void dce110_link_encoder_construct( | |||
683 | { | 676 | { |
684 | struct bp_encoder_cap_info bp_cap_info = {0}; | 677 | struct bp_encoder_cap_info bp_cap_info = {0}; |
685 | const struct dc_vbios_funcs *bp_funcs = init_data->ctx->dc_bios->funcs; | 678 | const struct dc_vbios_funcs *bp_funcs = init_data->ctx->dc_bios->funcs; |
679 | enum bp_result result = BP_RESULT_OK; | ||
686 | 680 | ||
687 | enc110->base.funcs = &dce110_lnk_enc_funcs; | 681 | enc110->base.funcs = &dce110_lnk_enc_funcs; |
688 | enc110->base.ctx = init_data->ctx; | 682 | enc110->base.ctx = init_data->ctx; |
@@ -757,15 +751,24 @@ void dce110_link_encoder_construct( | |||
757 | enc110->base.preferred_engine = ENGINE_ID_UNKNOWN; | 751 | enc110->base.preferred_engine = ENGINE_ID_UNKNOWN; |
758 | } | 752 | } |
759 | 753 | ||
754 | /* default to one to mirror Windows behavior */ | ||
755 | enc110->base.features.flags.bits.HDMI_6GB_EN = 1; | ||
756 | |||
757 | result = bp_funcs->get_encoder_cap_info(enc110->base.ctx->dc_bios, | ||
758 | enc110->base.id, &bp_cap_info); | ||
759 | |||
760 | /* Override features with DCE-specific values */ | 760 | /* Override features with DCE-specific values */ |
761 | if (BP_RESULT_OK == bp_funcs->get_encoder_cap_info( | 761 | if (BP_RESULT_OK == result) { |
762 | enc110->base.ctx->dc_bios, enc110->base.id, | ||
763 | &bp_cap_info)) { | ||
764 | enc110->base.features.flags.bits.IS_HBR2_CAPABLE = | 762 | enc110->base.features.flags.bits.IS_HBR2_CAPABLE = |
765 | bp_cap_info.DP_HBR2_EN; | 763 | bp_cap_info.DP_HBR2_EN; |
766 | enc110->base.features.flags.bits.IS_HBR3_CAPABLE = | 764 | enc110->base.features.flags.bits.IS_HBR3_CAPABLE = |
767 | bp_cap_info.DP_HBR3_EN; | 765 | bp_cap_info.DP_HBR3_EN; |
768 | enc110->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN; | 766 | enc110->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN; |
767 | } else { | ||
768 | dm_logger_write(enc110->base.ctx->logger, LOG_WARNING, | ||
769 | "%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n", | ||
770 | __func__, | ||
771 | result); | ||
769 | } | 772 | } |
770 | } | 773 | } |
771 | 774 | ||
@@ -904,8 +907,7 @@ void dce110_link_encoder_enable_tmds_output( | |||
904 | struct link_encoder *enc, | 907 | struct link_encoder *enc, |
905 | enum clock_source_id clock_source, | 908 | enum clock_source_id clock_source, |
906 | enum dc_color_depth color_depth, | 909 | enum dc_color_depth color_depth, |
907 | bool hdmi, | 910 | enum signal_type signal, |
908 | bool dual_link, | ||
909 | uint32_t pixel_clock) | 911 | uint32_t pixel_clock) |
910 | { | 912 | { |
911 | struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); | 913 | struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); |
@@ -919,16 +921,12 @@ void dce110_link_encoder_enable_tmds_output( | |||
919 | cntl.engine_id = enc->preferred_engine; | 921 | cntl.engine_id = enc->preferred_engine; |
920 | cntl.transmitter = enc110->base.transmitter; | 922 | cntl.transmitter = enc110->base.transmitter; |
921 | cntl.pll_id = clock_source; | 923 | cntl.pll_id = clock_source; |
922 | if (hdmi) { | 924 | cntl.signal = signal; |
923 | cntl.signal = SIGNAL_TYPE_HDMI_TYPE_A; | 925 | if (cntl.signal == SIGNAL_TYPE_DVI_DUAL_LINK) |
924 | cntl.lanes_number = 4; | ||
925 | } else if (dual_link) { | ||
926 | cntl.signal = SIGNAL_TYPE_DVI_DUAL_LINK; | ||
927 | cntl.lanes_number = 8; | 926 | cntl.lanes_number = 8; |
928 | } else { | 927 | else |
929 | cntl.signal = SIGNAL_TYPE_DVI_SINGLE_LINK; | ||
930 | cntl.lanes_number = 4; | 928 | cntl.lanes_number = 4; |
931 | } | 929 | |
932 | cntl.hpd_sel = enc110->base.hpd_source; | 930 | cntl.hpd_sel = enc110->base.hpd_source; |
933 | 931 | ||
934 | cntl.pixel_clock = pixel_clock; | 932 | cntl.pixel_clock = pixel_clock; |
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h index 8ca9afe47a2b..0ec3433d34b6 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h | |||
@@ -210,8 +210,7 @@ void dce110_link_encoder_enable_tmds_output( | |||
210 | struct link_encoder *enc, | 210 | struct link_encoder *enc, |
211 | enum clock_source_id clock_source, | 211 | enum clock_source_id clock_source, |
212 | enum dc_color_depth color_depth, | 212 | enum dc_color_depth color_depth, |
213 | bool hdmi, | 213 | enum signal_type signal, |
214 | bool dual_link, | ||
215 | uint32_t pixel_clock); | 214 | uint32_t pixel_clock); |
216 | 215 | ||
217 | /* enables DP PHY output */ | 216 | /* enables DP PHY output */ |
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_opp.c b/drivers/gpu/drm/amd/display/dc/dce/dce_opp.c index 3931412ab6d3..87093894ea9e 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_opp.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_opp.c | |||
@@ -128,23 +128,22 @@ static void set_truncation( | |||
128 | return; | 128 | return; |
129 | } | 129 | } |
130 | /* on other format-to do */ | 130 | /* on other format-to do */ |
131 | if (params->flags.TRUNCATE_ENABLED == 0 || | 131 | if (params->flags.TRUNCATE_ENABLED == 0) |
132 | params->flags.TRUNCATE_DEPTH == 2) | ||
133 | return; | 132 | return; |
134 | /*Set truncation depth and Enable truncation*/ | 133 | /*Set truncation depth and Enable truncation*/ |
135 | REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL, | 134 | REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL, |
136 | FMT_TRUNCATE_EN, 1, | 135 | FMT_TRUNCATE_EN, 1, |
137 | FMT_TRUNCATE_DEPTH, | 136 | FMT_TRUNCATE_DEPTH, |
138 | params->flags.TRUNCATE_MODE, | 137 | params->flags.TRUNCATE_DEPTH, |
139 | FMT_TRUNCATE_MODE, | 138 | FMT_TRUNCATE_MODE, |
140 | params->flags.TRUNCATE_DEPTH); | 139 | params->flags.TRUNCATE_MODE); |
141 | } | 140 | } |
142 | 141 | ||
143 | 142 | ||
144 | /** | 143 | /** |
145 | * set_spatial_dither | 144 | * set_spatial_dither |
146 | * 1) set spatial dithering mode: pattern of seed | 145 | * 1) set spatial dithering mode: pattern of seed |
147 | * 2) set spatical dithering depth: 0 for 18bpp or 1 for 24bpp | 146 | * 2) set spatial dithering depth: 0 for 18bpp or 1 for 24bpp |
148 | * 3) set random seed | 147 | * 3) set random seed |
149 | * 4) set random mode | 148 | * 4) set random mode |
150 | * lfsr is reset every frame or not reset | 149 | * lfsr is reset every frame or not reset |
diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c index 3ea43e2a9450..442dd2d93618 100644 --- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c | |||
@@ -852,6 +852,7 @@ static bool construct( | |||
852 | dc->caps.max_downscale_ratio = 200; | 852 | dc->caps.max_downscale_ratio = 200; |
853 | dc->caps.i2c_speed_in_khz = 40; | 853 | dc->caps.i2c_speed_in_khz = 40; |
854 | dc->caps.max_cursor_size = 128; | 854 | dc->caps.max_cursor_size = 128; |
855 | dc->caps.dual_link_dvi = true; | ||
855 | 856 | ||
856 | for (i = 0; i < pool->base.pipe_count; i++) { | 857 | for (i = 0; i < pool->base.pipe_count; i++) { |
857 | pool->base.timing_generators[i] = | 858 | pool->base.timing_generators[i] = |
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 86cdd7b4811f..6f382a3ac90f 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | |||
@@ -688,15 +688,22 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx) | |||
688 | struct dc_crtc_timing *timing = &pipe_ctx->stream->timing; | 688 | struct dc_crtc_timing *timing = &pipe_ctx->stream->timing; |
689 | struct dc_link *link = pipe_ctx->stream->sink->link; | 689 | struct dc_link *link = pipe_ctx->stream->sink->link; |
690 | 690 | ||
691 | /* 1. update AVI info frame (HDMI, DP) | 691 | |
692 | * we always need to update info frame | ||
693 | */ | ||
694 | uint32_t active_total_with_borders; | 692 | uint32_t active_total_with_borders; |
695 | uint32_t early_control = 0; | 693 | uint32_t early_control = 0; |
696 | struct timing_generator *tg = pipe_ctx->stream_res.tg; | 694 | struct timing_generator *tg = pipe_ctx->stream_res.tg; |
697 | 695 | ||
698 | /* TODOFPGA may change to hwss.update_info_frame */ | 696 | /* For MST, there are multiply stream go to only one link. |
697 | * connect DIG back_end to front_end while enable_stream and | ||
698 | * disconnect them during disable_stream | ||
699 | * BY this, it is logic clean to separate stream and link */ | ||
700 | link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc, | ||
701 | pipe_ctx->stream_res.stream_enc->id, true); | ||
702 | |||
703 | /* update AVI info frame (HDMI, DP)*/ | ||
704 | /* TODO: FPGA may change to hwss.update_info_frame */ | ||
699 | dce110_update_info_frame(pipe_ctx); | 705 | dce110_update_info_frame(pipe_ctx); |
706 | |||
700 | /* enable early control to avoid corruption on DP monitor*/ | 707 | /* enable early control to avoid corruption on DP monitor*/ |
701 | active_total_with_borders = | 708 | active_total_with_borders = |
702 | timing->h_addressable | 709 | timing->h_addressable |
@@ -717,12 +724,8 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx) | |||
717 | pipe_ctx->stream_res.stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_res.stream_enc); | 724 | pipe_ctx->stream_res.stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_res.stream_enc); |
718 | } | 725 | } |
719 | 726 | ||
720 | /* For MST, there are multiply stream go to only one link. | 727 | |
721 | * connect DIG back_end to front_end while enable_stream and | 728 | |
722 | * disconnect them during disable_stream | ||
723 | * BY this, it is logic clean to separate stream and link */ | ||
724 | link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc, | ||
725 | pipe_ctx->stream_res.stream_enc->id, true); | ||
726 | 729 | ||
727 | } | 730 | } |
728 | 731 | ||
@@ -1690,9 +1693,13 @@ static void apply_min_clocks( | |||
1690 | * Check if FBC can be enabled | 1693 | * Check if FBC can be enabled |
1691 | */ | 1694 | */ |
1692 | static bool should_enable_fbc(struct dc *dc, | 1695 | static bool should_enable_fbc(struct dc *dc, |
1693 | struct dc_state *context) | 1696 | struct dc_state *context, |
1697 | uint32_t *pipe_idx) | ||
1694 | { | 1698 | { |
1695 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[0]; | 1699 | uint32_t i; |
1700 | struct pipe_ctx *pipe_ctx = NULL; | ||
1701 | struct resource_context *res_ctx = &context->res_ctx; | ||
1702 | |||
1696 | 1703 | ||
1697 | ASSERT(dc->fbc_compressor); | 1704 | ASSERT(dc->fbc_compressor); |
1698 | 1705 | ||
@@ -1704,6 +1711,14 @@ static bool should_enable_fbc(struct dc *dc, | |||
1704 | if (context->stream_count != 1) | 1711 | if (context->stream_count != 1) |
1705 | return false; | 1712 | return false; |
1706 | 1713 | ||
1714 | for (i = 0; i < dc->res_pool->pipe_count; i++) { | ||
1715 | if (res_ctx->pipe_ctx[i].stream) { | ||
1716 | pipe_ctx = &res_ctx->pipe_ctx[i]; | ||
1717 | *pipe_idx = i; | ||
1718 | break; | ||
1719 | } | ||
1720 | } | ||
1721 | |||
1707 | /* Only supports eDP */ | 1722 | /* Only supports eDP */ |
1708 | if (pipe_ctx->stream->sink->link->connector_signal != SIGNAL_TYPE_EDP) | 1723 | if (pipe_ctx->stream->sink->link->connector_signal != SIGNAL_TYPE_EDP) |
1709 | return false; | 1724 | return false; |
@@ -1729,11 +1744,14 @@ static bool should_enable_fbc(struct dc *dc, | |||
1729 | static void enable_fbc(struct dc *dc, | 1744 | static void enable_fbc(struct dc *dc, |
1730 | struct dc_state *context) | 1745 | struct dc_state *context) |
1731 | { | 1746 | { |
1732 | if (should_enable_fbc(dc, context)) { | 1747 | uint32_t pipe_idx = 0; |
1748 | |||
1749 | if (should_enable_fbc(dc, context, &pipe_idx)) { | ||
1733 | /* Program GRPH COMPRESSED ADDRESS and PITCH */ | 1750 | /* Program GRPH COMPRESSED ADDRESS and PITCH */ |
1734 | struct compr_addr_and_pitch_params params = {0, 0, 0}; | 1751 | struct compr_addr_and_pitch_params params = {0, 0, 0}; |
1735 | struct compressor *compr = dc->fbc_compressor; | 1752 | struct compressor *compr = dc->fbc_compressor; |
1736 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[0]; | 1753 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx]; |
1754 | |||
1737 | 1755 | ||
1738 | params.source_view_width = pipe_ctx->stream->timing.h_addressable; | 1756 | params.source_view_width = pipe_ctx->stream->timing.h_addressable; |
1739 | params.source_view_height = pipe_ctx->stream->timing.v_addressable; | 1757 | params.source_view_height = pipe_ctx->stream->timing.v_addressable; |
@@ -2915,6 +2933,49 @@ static void program_csc_matrix(struct pipe_ctx *pipe_ctx, | |||
2915 | } | 2933 | } |
2916 | } | 2934 | } |
2917 | 2935 | ||
2936 | void dce110_set_cursor_position(struct pipe_ctx *pipe_ctx) | ||
2937 | { | ||
2938 | struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position; | ||
2939 | struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp; | ||
2940 | struct mem_input *mi = pipe_ctx->plane_res.mi; | ||
2941 | struct dc_cursor_mi_param param = { | ||
2942 | .pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_khz, | ||
2943 | .ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clock_inKhz, | ||
2944 | .viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x, | ||
2945 | .viewport_width = pipe_ctx->plane_res.scl_data.viewport.width, | ||
2946 | .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz | ||
2947 | }; | ||
2948 | |||
2949 | if (pipe_ctx->plane_state->address.type | ||
2950 | == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) | ||
2951 | pos_cpy.enable = false; | ||
2952 | |||
2953 | if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state) | ||
2954 | pos_cpy.enable = false; | ||
2955 | |||
2956 | if (ipp->funcs->ipp_cursor_set_position) | ||
2957 | ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, ¶m); | ||
2958 | if (mi->funcs->set_cursor_position) | ||
2959 | mi->funcs->set_cursor_position(mi, &pos_cpy, ¶m); | ||
2960 | } | ||
2961 | |||
2962 | void dce110_set_cursor_attribute(struct pipe_ctx *pipe_ctx) | ||
2963 | { | ||
2964 | struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes; | ||
2965 | |||
2966 | if (pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes) | ||
2967 | pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes( | ||
2968 | pipe_ctx->plane_res.ipp, attributes); | ||
2969 | |||
2970 | if (pipe_ctx->plane_res.mi->funcs->set_cursor_attributes) | ||
2971 | pipe_ctx->plane_res.mi->funcs->set_cursor_attributes( | ||
2972 | pipe_ctx->plane_res.mi, attributes); | ||
2973 | |||
2974 | if (pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes) | ||
2975 | pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes( | ||
2976 | pipe_ctx->plane_res.xfm, attributes); | ||
2977 | } | ||
2978 | |||
2918 | static void ready_shared_resources(struct dc *dc, struct dc_state *context) {} | 2979 | static void ready_shared_resources(struct dc *dc, struct dc_state *context) {} |
2919 | 2980 | ||
2920 | static void optimize_shared_resources(struct dc *dc) {} | 2981 | static void optimize_shared_resources(struct dc *dc) {} |
@@ -2957,6 +3018,8 @@ static const struct hw_sequencer_funcs dce110_funcs = { | |||
2957 | .edp_backlight_control = hwss_edp_backlight_control, | 3018 | .edp_backlight_control = hwss_edp_backlight_control, |
2958 | .edp_power_control = hwss_edp_power_control, | 3019 | .edp_power_control = hwss_edp_power_control, |
2959 | .edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready, | 3020 | .edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready, |
3021 | .set_cursor_position = dce110_set_cursor_position, | ||
3022 | .set_cursor_attribute = dce110_set_cursor_attribute | ||
2960 | }; | 3023 | }; |
2961 | 3024 | ||
2962 | void dce110_hw_sequencer_construct(struct dc *dc) | 3025 | void dce110_hw_sequencer_construct(struct dc *dc) |
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c index 7c4779578fb7..00f18c485e1e 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c | |||
@@ -846,6 +846,16 @@ static bool dce110_validate_bandwidth( | |||
846 | return result; | 846 | return result; |
847 | } | 847 | } |
848 | 848 | ||
849 | enum dc_status dce110_validate_plane(const struct dc_plane_state *plane_state, | ||
850 | struct dc_caps *caps) | ||
851 | { | ||
852 | if (((plane_state->dst_rect.width * 2) < plane_state->src_rect.width) || | ||
853 | ((plane_state->dst_rect.height * 2) < plane_state->src_rect.height)) | ||
854 | return DC_FAIL_SURFACE_VALIDATE; | ||
855 | |||
856 | return DC_OK; | ||
857 | } | ||
858 | |||
849 | static bool dce110_validate_surface_sets( | 859 | static bool dce110_validate_surface_sets( |
850 | struct dc_state *context) | 860 | struct dc_state *context) |
851 | { | 861 | { |
@@ -869,6 +879,13 @@ static bool dce110_validate_surface_sets( | |||
869 | plane->src_rect.height > 1080)) | 879 | plane->src_rect.height > 1080)) |
870 | return false; | 880 | return false; |
871 | 881 | ||
882 | /* we don't have the logic to support underlay | ||
883 | * only yet so block the use case where we get | ||
884 | * NV12 plane as top layer | ||
885 | */ | ||
886 | if (j == 0) | ||
887 | return false; | ||
888 | |||
872 | /* irrespective of plane format, | 889 | /* irrespective of plane format, |
873 | * stream should be RGB encoded | 890 | * stream should be RGB encoded |
874 | */ | 891 | */ |
@@ -1021,6 +1038,7 @@ static const struct resource_funcs dce110_res_pool_funcs = { | |||
1021 | .link_enc_create = dce110_link_encoder_create, | 1038 | .link_enc_create = dce110_link_encoder_create, |
1022 | .validate_guaranteed = dce110_validate_guaranteed, | 1039 | .validate_guaranteed = dce110_validate_guaranteed, |
1023 | .validate_bandwidth = dce110_validate_bandwidth, | 1040 | .validate_bandwidth = dce110_validate_bandwidth, |
1041 | .validate_plane = dce110_validate_plane, | ||
1024 | .acquire_idle_pipe_for_layer = dce110_acquire_underlay, | 1042 | .acquire_idle_pipe_for_layer = dce110_acquire_underlay, |
1025 | .add_stream_to_ctx = dce110_add_stream_to_ctx, | 1043 | .add_stream_to_ctx = dce110_add_stream_to_ctx, |
1026 | .validate_global = dce110_validate_global | 1044 | .validate_global = dce110_validate_global |
diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c index 663e0a047a4b..98d9cd0109e1 100644 --- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c | |||
@@ -1103,6 +1103,8 @@ static bool construct( | |||
1103 | dc->caps.max_downscale_ratio = 200; | 1103 | dc->caps.max_downscale_ratio = 200; |
1104 | dc->caps.i2c_speed_in_khz = 100; | 1104 | dc->caps.i2c_speed_in_khz = 100; |
1105 | dc->caps.max_cursor_size = 128; | 1105 | dc->caps.max_cursor_size = 128; |
1106 | dc->caps.dual_link_dvi = true; | ||
1107 | |||
1106 | 1108 | ||
1107 | /************************************************* | 1109 | /************************************************* |
1108 | * Create resources * | 1110 | * Create resources * |
diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c index 57cd67359567..5aab01db28ee 100644 --- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c | |||
@@ -835,6 +835,8 @@ static bool construct( | |||
835 | dc->caps.max_downscale_ratio = 200; | 835 | dc->caps.max_downscale_ratio = 200; |
836 | dc->caps.i2c_speed_in_khz = 100; | 836 | dc->caps.i2c_speed_in_khz = 100; |
837 | dc->caps.max_cursor_size = 128; | 837 | dc->caps.max_cursor_size = 128; |
838 | dc->caps.dual_link_dvi = true; | ||
839 | |||
838 | dc->debug = debug_defaults; | 840 | dc->debug = debug_defaults; |
839 | 841 | ||
840 | /************************************************* | 842 | /************************************************* |
diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c index 8f2bd56f3461..25d7eb1567ae 100644 --- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c | |||
@@ -793,6 +793,7 @@ static bool dce80_construct( | |||
793 | dc->caps.max_downscale_ratio = 200; | 793 | dc->caps.max_downscale_ratio = 200; |
794 | dc->caps.i2c_speed_in_khz = 40; | 794 | dc->caps.i2c_speed_in_khz = 40; |
795 | dc->caps.max_cursor_size = 128; | 795 | dc->caps.max_cursor_size = 128; |
796 | dc->caps.dual_link_dvi = true; | ||
796 | 797 | ||
797 | /************************************************* | 798 | /************************************************* |
798 | * Create resources * | 799 | * Create resources * |
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 82572863acab..dc1e010725c1 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 | |||
@@ -238,10 +238,34 @@ static void enable_power_gating_plane( | |||
238 | static void disable_vga( | 238 | static void disable_vga( |
239 | struct dce_hwseq *hws) | 239 | struct dce_hwseq *hws) |
240 | { | 240 | { |
241 | unsigned int in_vga1_mode = 0; | ||
242 | unsigned int in_vga2_mode = 0; | ||
243 | unsigned int in_vga3_mode = 0; | ||
244 | unsigned int in_vga4_mode = 0; | ||
245 | |||
246 | REG_GET(D1VGA_CONTROL, D1VGA_MODE_ENABLE, &in_vga1_mode); | ||
247 | REG_GET(D2VGA_CONTROL, D2VGA_MODE_ENABLE, &in_vga2_mode); | ||
248 | REG_GET(D3VGA_CONTROL, D3VGA_MODE_ENABLE, &in_vga3_mode); | ||
249 | REG_GET(D4VGA_CONTROL, D4VGA_MODE_ENABLE, &in_vga4_mode); | ||
250 | |||
251 | if (in_vga1_mode == 0 && in_vga2_mode == 0 && | ||
252 | in_vga3_mode == 0 && in_vga4_mode == 0) | ||
253 | return; | ||
254 | |||
241 | REG_WRITE(D1VGA_CONTROL, 0); | 255 | REG_WRITE(D1VGA_CONTROL, 0); |
242 | REG_WRITE(D2VGA_CONTROL, 0); | 256 | REG_WRITE(D2VGA_CONTROL, 0); |
243 | REG_WRITE(D3VGA_CONTROL, 0); | 257 | REG_WRITE(D3VGA_CONTROL, 0); |
244 | REG_WRITE(D4VGA_CONTROL, 0); | 258 | REG_WRITE(D4VGA_CONTROL, 0); |
259 | |||
260 | /* HW Engineer's Notes: | ||
261 | * During switch from vga->extended, if we set the VGA_TEST_ENABLE and | ||
262 | * then hit the VGA_TEST_RENDER_START, then the DCHUBP timing gets updated correctly. | ||
263 | * | ||
264 | * Then vBIOS will have it poll for the VGA_TEST_RENDER_DONE and unset | ||
265 | * VGA_TEST_ENABLE, to leave it in the same state as before. | ||
266 | */ | ||
267 | REG_UPDATE(VGA_TEST_CONTROL, VGA_TEST_ENABLE, 1); | ||
268 | REG_UPDATE(VGA_TEST_CONTROL, VGA_TEST_RENDER_START, 1); | ||
245 | } | 269 | } |
246 | 270 | ||
247 | static void dpp_pg_control( | 271 | static void dpp_pg_control( |
@@ -1761,6 +1785,11 @@ static void update_dchubp_dpp( | |||
1761 | &pipe_ctx->plane_res.scl_data.viewport_c); | 1785 | &pipe_ctx->plane_res.scl_data.viewport_c); |
1762 | } | 1786 | } |
1763 | 1787 | ||
1788 | if (pipe_ctx->stream->cursor_attributes.address.quad_part != 0) { | ||
1789 | dc->hwss.set_cursor_position(pipe_ctx); | ||
1790 | dc->hwss.set_cursor_attribute(pipe_ctx); | ||
1791 | } | ||
1792 | |||
1764 | if (plane_state->update_flags.bits.full_update) { | 1793 | if (plane_state->update_flags.bits.full_update) { |
1765 | /*gamut remap*/ | 1794 | /*gamut remap*/ |
1766 | program_gamut_remap(pipe_ctx); | 1795 | program_gamut_remap(pipe_ctx); |
@@ -2296,7 +2325,7 @@ static bool dcn10_dummy_display_power_gating( | |||
2296 | return true; | 2325 | return true; |
2297 | } | 2326 | } |
2298 | 2327 | ||
2299 | void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx) | 2328 | static void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx) |
2300 | { | 2329 | { |
2301 | struct dc_plane_state *plane_state = pipe_ctx->plane_state; | 2330 | struct dc_plane_state *plane_state = pipe_ctx->plane_state; |
2302 | struct timing_generator *tg = pipe_ctx->stream_res.tg; | 2331 | struct timing_generator *tg = pipe_ctx->stream_res.tg; |
@@ -2316,12 +2345,46 @@ void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx) | |||
2316 | } | 2345 | } |
2317 | } | 2346 | } |
2318 | 2347 | ||
2319 | void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data) | 2348 | static void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data) |
2320 | { | 2349 | { |
2321 | if (hws->ctx->dc->res_pool->hubbub != NULL) | 2350 | if (hws->ctx->dc->res_pool->hubbub != NULL) |
2322 | hubbub1_update_dchub(hws->ctx->dc->res_pool->hubbub, dh_data); | 2351 | hubbub1_update_dchub(hws->ctx->dc->res_pool->hubbub, dh_data); |
2323 | } | 2352 | } |
2324 | 2353 | ||
2354 | static void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx) | ||
2355 | { | ||
2356 | struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position; | ||
2357 | struct hubp *hubp = pipe_ctx->plane_res.hubp; | ||
2358 | struct dpp *dpp = pipe_ctx->plane_res.dpp; | ||
2359 | struct dc_cursor_mi_param param = { | ||
2360 | .pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_khz, | ||
2361 | .ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clock_inKhz, | ||
2362 | .viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x, | ||
2363 | .viewport_width = pipe_ctx->plane_res.scl_data.viewport.width, | ||
2364 | .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz | ||
2365 | }; | ||
2366 | |||
2367 | if (pipe_ctx->plane_state->address.type | ||
2368 | == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) | ||
2369 | pos_cpy.enable = false; | ||
2370 | |||
2371 | if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state) | ||
2372 | pos_cpy.enable = false; | ||
2373 | |||
2374 | hubp->funcs->set_cursor_position(hubp, &pos_cpy, ¶m); | ||
2375 | dpp->funcs->set_cursor_position(dpp, &pos_cpy, ¶m, hubp->curs_attr.width); | ||
2376 | } | ||
2377 | |||
2378 | static void dcn10_set_cursor_attribute(struct pipe_ctx *pipe_ctx) | ||
2379 | { | ||
2380 | struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes; | ||
2381 | |||
2382 | pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes( | ||
2383 | pipe_ctx->plane_res.hubp, attributes); | ||
2384 | pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes( | ||
2385 | pipe_ctx->plane_res.dpp, attributes->color_format); | ||
2386 | } | ||
2387 | |||
2325 | static const struct hw_sequencer_funcs dcn10_funcs = { | 2388 | static const struct hw_sequencer_funcs dcn10_funcs = { |
2326 | .program_gamut_remap = program_gamut_remap, | 2389 | .program_gamut_remap = program_gamut_remap, |
2327 | .program_csc_matrix = program_csc_matrix, | 2390 | .program_csc_matrix = program_csc_matrix, |
@@ -2362,6 +2425,8 @@ static const struct hw_sequencer_funcs dcn10_funcs = { | |||
2362 | .edp_backlight_control = hwss_edp_backlight_control, | 2425 | .edp_backlight_control = hwss_edp_backlight_control, |
2363 | .edp_power_control = hwss_edp_power_control, | 2426 | .edp_power_control = hwss_edp_power_control, |
2364 | .edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready, | 2427 | .edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready, |
2428 | .set_cursor_position = dcn10_set_cursor_position, | ||
2429 | .set_cursor_attribute = dcn10_set_cursor_attribute | ||
2365 | }; | 2430 | }; |
2366 | 2431 | ||
2367 | 2432 | ||
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h index 0fd329deacd8..54d8a1386142 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h | |||
@@ -123,8 +123,7 @@ struct link_encoder_funcs { | |||
123 | void (*enable_tmds_output)(struct link_encoder *enc, | 123 | void (*enable_tmds_output)(struct link_encoder *enc, |
124 | enum clock_source_id clock_source, | 124 | enum clock_source_id clock_source, |
125 | enum dc_color_depth color_depth, | 125 | enum dc_color_depth color_depth, |
126 | bool hdmi, | 126 | enum signal_type signal, |
127 | bool dual_link, | ||
128 | uint32_t pixel_clock); | 127 | uint32_t pixel_clock); |
129 | void (*enable_dp_output)(struct link_encoder *enc, | 128 | void (*enable_dp_output)(struct link_encoder *enc, |
130 | const struct dc_link_settings *link_settings, | 129 | const struct dc_link_settings *link_settings, |
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h index 4c0aa56f7bae..379c6ecd271a 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h | |||
@@ -198,6 +198,9 @@ struct hw_sequencer_funcs { | |||
198 | bool enable); | 198 | bool enable); |
199 | void (*edp_wait_for_hpd_ready)(struct dc_link *link, bool power_up); | 199 | void (*edp_wait_for_hpd_ready)(struct dc_link *link, bool power_up); |
200 | 200 | ||
201 | void (*set_cursor_position)(struct pipe_ctx *pipe); | ||
202 | void (*set_cursor_attribute)(struct pipe_ctx *pipe); | ||
203 | |||
201 | }; | 204 | }; |
202 | 205 | ||
203 | void color_space_to_black_color( | 206 | void color_space_to_black_color( |
diff --git a/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c b/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c index f7e40b292dfb..d3e1923b01a8 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c | |||
@@ -217,7 +217,7 @@ bool dce110_vblank_set( | |||
217 | core_dc->current_state->res_ctx.pipe_ctx[pipe_offset].stream_res.tg; | 217 | core_dc->current_state->res_ctx.pipe_ctx[pipe_offset].stream_res.tg; |
218 | 218 | ||
219 | if (enable) { | 219 | if (enable) { |
220 | if (!tg->funcs->arm_vert_intr(tg, 2)) { | 220 | if (!tg || !tg->funcs->arm_vert_intr(tg, 2)) { |
221 | DC_ERROR("Failed to get VBLANK!\n"); | 221 | DC_ERROR("Failed to get VBLANK!\n"); |
222 | return false; | 222 | return false; |
223 | } | 223 | } |
diff --git a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c b/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c index 57a54a7b89e5..1c079ba37c30 100644 --- a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c | |||
@@ -42,8 +42,7 @@ static void virtual_link_encoder_enable_tmds_output( | |||
42 | struct link_encoder *enc, | 42 | struct link_encoder *enc, |
43 | enum clock_source_id clock_source, | 43 | enum clock_source_id clock_source, |
44 | enum dc_color_depth color_depth, | 44 | enum dc_color_depth color_depth, |
45 | bool hdmi, | 45 | enum signal_type signal, |
46 | bool dual_link, | ||
47 | uint32_t pixel_clock) {} | 46 | uint32_t pixel_clock) {} |
48 | 47 | ||
49 | static void virtual_link_encoder_enable_dp_output( | 48 | static void virtual_link_encoder_enable_dp_output( |