diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display')
15 files changed, 161 insertions, 70 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 1ce10bc2d37b..d7d1245c1050 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/moduleparam.h> | 46 | #include <linux/moduleparam.h> |
47 | #include <linux/version.h> | 47 | #include <linux/version.h> |
48 | #include <linux/types.h> | 48 | #include <linux/types.h> |
49 | #include <linux/pm_runtime.h> | ||
49 | 50 | ||
50 | #include <drm/drmP.h> | 51 | #include <drm/drmP.h> |
51 | #include <drm/drm_atomic.h> | 52 | #include <drm/drm_atomic.h> |
@@ -2095,12 +2096,6 @@ convert_color_depth_from_display_info(const struct drm_connector *connector) | |||
2095 | { | 2096 | { |
2096 | uint32_t bpc = connector->display_info.bpc; | 2097 | uint32_t bpc = connector->display_info.bpc; |
2097 | 2098 | ||
2098 | /* Limited color depth to 8bit | ||
2099 | * TODO: Still need to handle deep color | ||
2100 | */ | ||
2101 | if (bpc > 8) | ||
2102 | bpc = 8; | ||
2103 | |||
2104 | switch (bpc) { | 2099 | switch (bpc) { |
2105 | case 0: | 2100 | case 0: |
2106 | /* Temporary Work around, DRM don't parse color depth for | 2101 | /* Temporary Work around, DRM don't parse color depth for |
@@ -2316,27 +2311,22 @@ decide_crtc_timing_for_drm_display_mode(struct drm_display_mode *drm_mode, | |||
2316 | } | 2311 | } |
2317 | } | 2312 | } |
2318 | 2313 | ||
2319 | static int create_fake_sink(struct amdgpu_dm_connector *aconnector) | 2314 | static struct dc_sink * |
2315 | create_fake_sink(struct amdgpu_dm_connector *aconnector) | ||
2320 | { | 2316 | { |
2321 | struct dc_sink *sink = NULL; | ||
2322 | struct dc_sink_init_data sink_init_data = { 0 }; | 2317 | struct dc_sink_init_data sink_init_data = { 0 }; |
2323 | 2318 | struct dc_sink *sink = NULL; | |
2324 | sink_init_data.link = aconnector->dc_link; | 2319 | sink_init_data.link = aconnector->dc_link; |
2325 | sink_init_data.sink_signal = aconnector->dc_link->connector_signal; | 2320 | sink_init_data.sink_signal = aconnector->dc_link->connector_signal; |
2326 | 2321 | ||
2327 | sink = dc_sink_create(&sink_init_data); | 2322 | sink = dc_sink_create(&sink_init_data); |
2328 | if (!sink) { | 2323 | if (!sink) { |
2329 | DRM_ERROR("Failed to create sink!\n"); | 2324 | DRM_ERROR("Failed to create sink!\n"); |
2330 | return -ENOMEM; | 2325 | return NULL; |
2331 | } | 2326 | } |
2332 | |||
2333 | sink->sink_signal = SIGNAL_TYPE_VIRTUAL; | 2327 | sink->sink_signal = SIGNAL_TYPE_VIRTUAL; |
2334 | aconnector->fake_enable = true; | ||
2335 | |||
2336 | aconnector->dc_sink = sink; | ||
2337 | aconnector->dc_link->local_sink = sink; | ||
2338 | 2328 | ||
2339 | return 0; | 2329 | return sink; |
2340 | } | 2330 | } |
2341 | 2331 | ||
2342 | static void set_multisync_trigger_params( | 2332 | static void set_multisync_trigger_params( |
@@ -2399,7 +2389,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, | |||
2399 | struct dc_stream_state *stream = NULL; | 2389 | struct dc_stream_state *stream = NULL; |
2400 | struct drm_display_mode mode = *drm_mode; | 2390 | struct drm_display_mode mode = *drm_mode; |
2401 | bool native_mode_found = false; | 2391 | bool native_mode_found = false; |
2402 | 2392 | struct dc_sink *sink = NULL; | |
2403 | if (aconnector == NULL) { | 2393 | if (aconnector == NULL) { |
2404 | DRM_ERROR("aconnector is NULL!\n"); | 2394 | DRM_ERROR("aconnector is NULL!\n"); |
2405 | return stream; | 2395 | return stream; |
@@ -2417,15 +2407,18 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, | |||
2417 | return stream; | 2407 | return stream; |
2418 | } | 2408 | } |
2419 | 2409 | ||
2420 | if (create_fake_sink(aconnector)) | 2410 | sink = create_fake_sink(aconnector); |
2411 | if (!sink) | ||
2421 | return stream; | 2412 | return stream; |
2413 | } else { | ||
2414 | sink = aconnector->dc_sink; | ||
2422 | } | 2415 | } |
2423 | 2416 | ||
2424 | stream = dc_create_stream_for_sink(aconnector->dc_sink); | 2417 | stream = dc_create_stream_for_sink(sink); |
2425 | 2418 | ||
2426 | if (stream == NULL) { | 2419 | if (stream == NULL) { |
2427 | DRM_ERROR("Failed to create stream for sink!\n"); | 2420 | DRM_ERROR("Failed to create stream for sink!\n"); |
2428 | return stream; | 2421 | goto finish; |
2429 | } | 2422 | } |
2430 | 2423 | ||
2431 | list_for_each_entry(preferred_mode, &aconnector->base.modes, head) { | 2424 | list_for_each_entry(preferred_mode, &aconnector->base.modes, head) { |
@@ -2464,12 +2457,15 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, | |||
2464 | fill_audio_info( | 2457 | fill_audio_info( |
2465 | &stream->audio_info, | 2458 | &stream->audio_info, |
2466 | drm_connector, | 2459 | drm_connector, |
2467 | aconnector->dc_sink); | 2460 | sink); |
2468 | 2461 | ||
2469 | update_stream_signal(stream); | 2462 | update_stream_signal(stream); |
2470 | 2463 | ||
2471 | if (dm_state && dm_state->freesync_capable) | 2464 | if (dm_state && dm_state->freesync_capable) |
2472 | stream->ignore_msa_timing_param = true; | 2465 | stream->ignore_msa_timing_param = true; |
2466 | finish: | ||
2467 | if (sink && sink->sink_signal == SIGNAL_TYPE_VIRTUAL) | ||
2468 | dc_sink_release(sink); | ||
2473 | 2469 | ||
2474 | return stream; | 2470 | return stream; |
2475 | } | 2471 | } |
@@ -2714,6 +2710,9 @@ void amdgpu_dm_connector_funcs_reset(struct drm_connector *connector) | |||
2714 | struct dm_connector_state *state = | 2710 | struct dm_connector_state *state = |
2715 | to_dm_connector_state(connector->state); | 2711 | to_dm_connector_state(connector->state); |
2716 | 2712 | ||
2713 | if (connector->state) | ||
2714 | __drm_atomic_helper_connector_destroy_state(connector->state); | ||
2715 | |||
2717 | kfree(state); | 2716 | kfree(state); |
2718 | 2717 | ||
2719 | state = kzalloc(sizeof(*state), GFP_KERNEL); | 2718 | state = kzalloc(sizeof(*state), GFP_KERNEL); |
@@ -2724,8 +2723,7 @@ void amdgpu_dm_connector_funcs_reset(struct drm_connector *connector) | |||
2724 | state->underscan_hborder = 0; | 2723 | state->underscan_hborder = 0; |
2725 | state->underscan_vborder = 0; | 2724 | state->underscan_vborder = 0; |
2726 | 2725 | ||
2727 | connector->state = &state->base; | 2726 | __drm_atomic_helper_connector_reset(connector, &state->base); |
2728 | connector->state->connector = connector; | ||
2729 | } | 2727 | } |
2730 | } | 2728 | } |
2731 | 2729 | ||
@@ -3083,17 +3081,6 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane, | |||
3083 | } | 3081 | } |
3084 | } | 3082 | } |
3085 | 3083 | ||
3086 | /* It's a hack for s3 since in 4.9 kernel filter out cursor buffer | ||
3087 | * prepare and cleanup in drm_atomic_helper_prepare_planes | ||
3088 | * and drm_atomic_helper_cleanup_planes because fb doens't in s3. | ||
3089 | * IN 4.10 kernel this code should be removed and amdgpu_device_suspend | ||
3090 | * code touching fram buffers should be avoided for DC. | ||
3091 | */ | ||
3092 | if (plane->type == DRM_PLANE_TYPE_CURSOR) { | ||
3093 | struct amdgpu_crtc *acrtc = to_amdgpu_crtc(new_state->crtc); | ||
3094 | |||
3095 | acrtc->cursor_bo = obj; | ||
3096 | } | ||
3097 | return 0; | 3084 | return 0; |
3098 | } | 3085 | } |
3099 | 3086 | ||
@@ -4281,6 +4268,8 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) | |||
4281 | if (dm_old_crtc_state->stream) | 4268 | if (dm_old_crtc_state->stream) |
4282 | remove_stream(adev, acrtc, dm_old_crtc_state->stream); | 4269 | remove_stream(adev, acrtc, dm_old_crtc_state->stream); |
4283 | 4270 | ||
4271 | pm_runtime_get_noresume(dev->dev); | ||
4272 | |||
4284 | acrtc->enabled = true; | 4273 | acrtc->enabled = true; |
4285 | acrtc->hw_mode = new_crtc_state->mode; | 4274 | acrtc->hw_mode = new_crtc_state->mode; |
4286 | crtc->hwmode = new_crtc_state->mode; | 4275 | crtc->hwmode = new_crtc_state->mode; |
@@ -4469,6 +4458,16 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) | |||
4469 | drm_atomic_helper_wait_for_flip_done(dev, state); | 4458 | drm_atomic_helper_wait_for_flip_done(dev, state); |
4470 | 4459 | ||
4471 | drm_atomic_helper_cleanup_planes(dev, state); | 4460 | drm_atomic_helper_cleanup_planes(dev, state); |
4461 | |||
4462 | /* Finally, drop a runtime PM reference for each newly disabled CRTC, | ||
4463 | * so we can put the GPU into runtime suspend if we're not driving any | ||
4464 | * displays anymore | ||
4465 | */ | ||
4466 | pm_runtime_mark_last_busy(dev->dev); | ||
4467 | for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { | ||
4468 | if (old_crtc_state->active && !new_crtc_state->active) | ||
4469 | pm_runtime_put_autosuspend(dev->dev); | ||
4470 | } | ||
4472 | } | 4471 | } |
4473 | 4472 | ||
4474 | 4473 | ||
@@ -4768,15 +4767,16 @@ next_crtc: | |||
4768 | * We want to do dc stream updates that do not require a | 4767 | * We want to do dc stream updates that do not require a |
4769 | * full modeset below. | 4768 | * full modeset below. |
4770 | */ | 4769 | */ |
4771 | if (!enable || !aconnector || modereset_required(new_crtc_state)) | 4770 | if (!(enable && aconnector && new_crtc_state->enable && |
4771 | new_crtc_state->active)) | ||
4772 | continue; | 4772 | continue; |
4773 | /* | 4773 | /* |
4774 | * Given above conditions, the dc state cannot be NULL because: | 4774 | * Given above conditions, the dc state cannot be NULL because: |
4775 | * 1. We're attempting to enable a CRTC. Which has a... | 4775 | * 1. We're in the process of enabling CRTCs (just been added |
4776 | * 2. Valid connector attached, and | 4776 | * to the dc context, or already is on the context) |
4777 | * 3. User does not want to reset it (disable or mark inactive, | 4777 | * 2. Has a valid connector attached, and |
4778 | * which can happen on a CRTC that's already disabled). | 4778 | * 3. Is currently active and enabled. |
4779 | * => It currently exists. | 4779 | * => The dc stream state currently exists. |
4780 | */ | 4780 | */ |
4781 | BUG_ON(dm_new_crtc_state->stream == NULL); | 4781 | BUG_ON(dm_new_crtc_state->stream == NULL); |
4782 | 4782 | ||
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c index 4be21bf54749..a910f01838ab 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c | |||
@@ -555,6 +555,9 @@ static inline int dm_irq_state(struct amdgpu_device *adev, | |||
555 | return 0; | 555 | return 0; |
556 | } | 556 | } |
557 | 557 | ||
558 | if (acrtc->otg_inst == -1) | ||
559 | return 0; | ||
560 | |||
558 | irq_source = dal_irq_type + acrtc->otg_inst; | 561 | irq_source = dal_irq_type + acrtc->otg_inst; |
559 | 562 | ||
560 | st = (state == AMDGPU_IRQ_STATE_ENABLE); | 563 | st = (state == AMDGPU_IRQ_STATE_ENABLE); |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c index 0229c7edb8ad..5a3346124a01 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c | |||
@@ -234,6 +234,33 @@ static void pp_to_dc_clock_levels( | |||
234 | } | 234 | } |
235 | } | 235 | } |
236 | 236 | ||
237 | static void pp_to_dc_clock_levels_with_latency( | ||
238 | const struct pp_clock_levels_with_latency *pp_clks, | ||
239 | struct dm_pp_clock_levels_with_latency *clk_level_info, | ||
240 | enum dm_pp_clock_type dc_clk_type) | ||
241 | { | ||
242 | uint32_t i; | ||
243 | |||
244 | if (pp_clks->num_levels > DM_PP_MAX_CLOCK_LEVELS) { | ||
245 | DRM_INFO("DM_PPLIB: Warning: %s clock: number of levels %d exceeds maximum of %d!\n", | ||
246 | DC_DECODE_PP_CLOCK_TYPE(dc_clk_type), | ||
247 | pp_clks->num_levels, | ||
248 | DM_PP_MAX_CLOCK_LEVELS); | ||
249 | |||
250 | clk_level_info->num_levels = DM_PP_MAX_CLOCK_LEVELS; | ||
251 | } else | ||
252 | clk_level_info->num_levels = pp_clks->num_levels; | ||
253 | |||
254 | DRM_DEBUG("DM_PPLIB: values for %s clock\n", | ||
255 | DC_DECODE_PP_CLOCK_TYPE(dc_clk_type)); | ||
256 | |||
257 | for (i = 0; i < clk_level_info->num_levels; i++) { | ||
258 | DRM_DEBUG("DM_PPLIB:\t %d\n", pp_clks->data[i].clocks_in_khz); | ||
259 | clk_level_info->data[i].clocks_in_khz = pp_clks->data[i].clocks_in_khz; | ||
260 | clk_level_info->data[i].latency_in_us = pp_clks->data[i].latency_in_us; | ||
261 | } | ||
262 | } | ||
263 | |||
237 | bool dm_pp_get_clock_levels_by_type( | 264 | bool dm_pp_get_clock_levels_by_type( |
238 | const struct dc_context *ctx, | 265 | const struct dc_context *ctx, |
239 | enum dm_pp_clock_type clk_type, | 266 | enum dm_pp_clock_type clk_type, |
@@ -311,8 +338,22 @@ bool dm_pp_get_clock_levels_by_type_with_latency( | |||
311 | enum dm_pp_clock_type clk_type, | 338 | enum dm_pp_clock_type clk_type, |
312 | struct dm_pp_clock_levels_with_latency *clk_level_info) | 339 | struct dm_pp_clock_levels_with_latency *clk_level_info) |
313 | { | 340 | { |
314 | /* TODO: to be implemented */ | 341 | struct amdgpu_device *adev = ctx->driver_context; |
315 | return false; | 342 | void *pp_handle = adev->powerplay.pp_handle; |
343 | struct pp_clock_levels_with_latency pp_clks = { 0 }; | ||
344 | const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; | ||
345 | |||
346 | if (!pp_funcs || !pp_funcs->get_clock_by_type_with_latency) | ||
347 | return false; | ||
348 | |||
349 | if (pp_funcs->get_clock_by_type_with_latency(pp_handle, | ||
350 | dc_to_pp_clock_type(clk_type), | ||
351 | &pp_clks)) | ||
352 | return false; | ||
353 | |||
354 | pp_to_dc_clock_levels_with_latency(&pp_clks, clk_level_info, clk_type); | ||
355 | |||
356 | return true; | ||
316 | } | 357 | } |
317 | 358 | ||
318 | bool dm_pp_get_clock_levels_by_type_with_voltage( | 359 | bool dm_pp_get_clock_levels_by_type_with_voltage( |
diff --git a/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c b/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c index e61dd97d0928..f28989860fd8 100644 --- a/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c +++ b/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c | |||
@@ -449,6 +449,11 @@ static inline unsigned int clamp_ux_dy( | |||
449 | return min_clamp; | 449 | return min_clamp; |
450 | } | 450 | } |
451 | 451 | ||
452 | unsigned int dc_fixpt_u3d19(struct fixed31_32 arg) | ||
453 | { | ||
454 | return ux_dy(arg.value, 3, 19); | ||
455 | } | ||
456 | |||
452 | unsigned int dc_fixpt_u2d19(struct fixed31_32 arg) | 457 | unsigned int dc_fixpt_u2d19(struct fixed31_32 arg) |
453 | { | 458 | { |
454 | return ux_dy(arg.value, 2, 19); | 459 | return ux_dy(arg.value, 2, 19); |
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index 7d609c71394b..7857cb42b3e6 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | |||
@@ -1630,17 +1630,42 @@ static enum dc_status read_hpd_rx_irq_data( | |||
1630 | struct dc_link *link, | 1630 | struct dc_link *link, |
1631 | union hpd_irq_data *irq_data) | 1631 | union hpd_irq_data *irq_data) |
1632 | { | 1632 | { |
1633 | static enum dc_status retval; | ||
1634 | |||
1633 | /* The HW reads 16 bytes from 200h on HPD, | 1635 | /* The HW reads 16 bytes from 200h on HPD, |
1634 | * but if we get an AUX_DEFER, the HW cannot retry | 1636 | * but if we get an AUX_DEFER, the HW cannot retry |
1635 | * and this causes the CTS tests 4.3.2.1 - 3.2.4 to | 1637 | * and this causes the CTS tests 4.3.2.1 - 3.2.4 to |
1636 | * fail, so we now explicitly read 6 bytes which is | 1638 | * fail, so we now explicitly read 6 bytes which is |
1637 | * the req from the above mentioned test cases. | 1639 | * the req from the above mentioned test cases. |
1640 | * | ||
1641 | * For DP 1.4 we need to read those from 2002h range. | ||
1638 | */ | 1642 | */ |
1639 | return core_link_read_dpcd( | 1643 | if (link->dpcd_caps.dpcd_rev.raw < DPCD_REV_14) |
1640 | link, | 1644 | retval = core_link_read_dpcd( |
1641 | DP_SINK_COUNT, | 1645 | link, |
1642 | irq_data->raw, | 1646 | DP_SINK_COUNT, |
1643 | sizeof(union hpd_irq_data)); | 1647 | irq_data->raw, |
1648 | sizeof(union hpd_irq_data)); | ||
1649 | else { | ||
1650 | /* Read 2 bytes at this location,... */ | ||
1651 | retval = core_link_read_dpcd( | ||
1652 | link, | ||
1653 | DP_SINK_COUNT_ESI, | ||
1654 | irq_data->raw, | ||
1655 | 2); | ||
1656 | |||
1657 | if (retval != DC_OK) | ||
1658 | return retval; | ||
1659 | |||
1660 | /* ... then read remaining 4 at the other location */ | ||
1661 | retval = core_link_read_dpcd( | ||
1662 | link, | ||
1663 | DP_LANE0_1_STATUS_ESI, | ||
1664 | &irq_data->raw[2], | ||
1665 | 4); | ||
1666 | } | ||
1667 | |||
1668 | return retval; | ||
1644 | } | 1669 | } |
1645 | 1670 | ||
1646 | static bool allow_hpd_rx_irq(const struct dc_link *link) | 1671 | static bool allow_hpd_rx_irq(const struct dc_link *link) |
@@ -2278,7 +2303,7 @@ static void dp_wa_power_up_0010FA(struct dc_link *link, uint8_t *dpcd_data, | |||
2278 | 2303 | ||
2279 | static bool retrieve_link_cap(struct dc_link *link) | 2304 | static bool retrieve_link_cap(struct dc_link *link) |
2280 | { | 2305 | { |
2281 | uint8_t dpcd_data[DP_TRAINING_AUX_RD_INTERVAL - DP_DPCD_REV + 1]; | 2306 | uint8_t dpcd_data[DP_ADAPTER_CAP - DP_DPCD_REV + 1]; |
2282 | 2307 | ||
2283 | union down_stream_port_count down_strm_port_count; | 2308 | union down_stream_port_count down_strm_port_count; |
2284 | union edp_configuration_cap edp_config_cap; | 2309 | union edp_configuration_cap edp_config_cap; |
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c index 0a6d483dc046..c0e813c7ddd4 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c | |||
@@ -72,7 +72,8 @@ static void dce110_update_generic_info_packet( | |||
72 | uint32_t max_retries = 50; | 72 | uint32_t max_retries = 50; |
73 | 73 | ||
74 | /*we need turn on clock before programming AFMT block*/ | 74 | /*we need turn on clock before programming AFMT block*/ |
75 | REG_UPDATE(AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, 1); | 75 | if (REG(AFMT_CNTL)) |
76 | REG_UPDATE(AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, 1); | ||
76 | 77 | ||
77 | if (REG(AFMT_VBI_PACKET_CONTROL1)) { | 78 | if (REG(AFMT_VBI_PACKET_CONTROL1)) { |
78 | if (packet_index >= 8) | 79 | if (packet_index >= 8) |
@@ -719,7 +720,8 @@ static void dce110_stream_encoder_update_hdmi_info_packets( | |||
719 | const uint32_t *content = | 720 | const uint32_t *content = |
720 | (const uint32_t *) &info_frame->avi.sb[0]; | 721 | (const uint32_t *) &info_frame->avi.sb[0]; |
721 | /*we need turn on clock before programming AFMT block*/ | 722 | /*we need turn on clock before programming AFMT block*/ |
722 | REG_UPDATE(AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, 1); | 723 | if (REG(AFMT_CNTL)) |
724 | REG_UPDATE(AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, 1); | ||
723 | 725 | ||
724 | REG_WRITE(AFMT_AVI_INFO0, content[0]); | 726 | REG_WRITE(AFMT_AVI_INFO0, content[0]); |
725 | 727 | ||
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c index 9150d2694450..e2994d337044 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c | |||
@@ -121,10 +121,10 @@ static void reset_lb_on_vblank(struct dc_context *ctx) | |||
121 | frame_count = dm_read_reg(ctx, mmCRTC_STATUS_FRAME_COUNT); | 121 | frame_count = dm_read_reg(ctx, mmCRTC_STATUS_FRAME_COUNT); |
122 | 122 | ||
123 | 123 | ||
124 | for (retry = 100; retry > 0; retry--) { | 124 | for (retry = 10000; retry > 0; retry--) { |
125 | if (frame_count != dm_read_reg(ctx, mmCRTC_STATUS_FRAME_COUNT)) | 125 | if (frame_count != dm_read_reg(ctx, mmCRTC_STATUS_FRAME_COUNT)) |
126 | break; | 126 | break; |
127 | msleep(1); | 127 | udelay(10); |
128 | } | 128 | } |
129 | if (!retry) | 129 | if (!retry) |
130 | dm_error("Frame count did not increase for 100ms.\n"); | 130 | dm_error("Frame count did not increase for 100ms.\n"); |
@@ -147,14 +147,14 @@ static void wait_for_fbc_state_changed( | |||
147 | uint32_t addr = mmFBC_STATUS; | 147 | uint32_t addr = mmFBC_STATUS; |
148 | uint32_t value; | 148 | uint32_t value; |
149 | 149 | ||
150 | while (counter < 10) { | 150 | while (counter < 1000) { |
151 | value = dm_read_reg(cp110->base.ctx, addr); | 151 | value = dm_read_reg(cp110->base.ctx, addr); |
152 | if (get_reg_field_value( | 152 | if (get_reg_field_value( |
153 | value, | 153 | value, |
154 | FBC_STATUS, | 154 | FBC_STATUS, |
155 | FBC_ENABLE_STATUS) == enabled) | 155 | FBC_ENABLE_STATUS) == enabled) |
156 | break; | 156 | break; |
157 | msleep(10); | 157 | udelay(100); |
158 | counter++; | 158 | counter++; |
159 | } | 159 | } |
160 | 160 | ||
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 a92fb0aa2ff3..c29052b6da5a 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 | |||
@@ -1004,9 +1004,9 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option) | |||
1004 | /*don't free audio if it is from retrain or internal disable stream*/ | 1004 | /*don't free audio if it is from retrain or internal disable stream*/ |
1005 | if (option == FREE_ACQUIRED_RESOURCE && dc->caps.dynamic_audio == true) { | 1005 | if (option == FREE_ACQUIRED_RESOURCE && dc->caps.dynamic_audio == true) { |
1006 | /*we have to dynamic arbitrate the audio endpoints*/ | 1006 | /*we have to dynamic arbitrate the audio endpoints*/ |
1007 | pipe_ctx->stream_res.audio = NULL; | ||
1008 | /*we free the resource, need reset is_audio_acquired*/ | 1007 | /*we free the resource, need reset is_audio_acquired*/ |
1009 | update_audio_usage(&dc->current_state->res_ctx, dc->res_pool, pipe_ctx->stream_res.audio, false); | 1008 | update_audio_usage(&dc->current_state->res_ctx, dc->res_pool, pipe_ctx->stream_res.audio, false); |
1009 | pipe_ctx->stream_res.audio = NULL; | ||
1010 | } | 1010 | } |
1011 | 1011 | ||
1012 | /* TODO: notify audio driver for if audio modes list changed | 1012 | /* TODO: notify audio driver for if audio modes list changed |
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c index 46a35c7f01df..c69fa4bfab0a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c | |||
@@ -132,8 +132,7 @@ void dpp_set_gamut_remap_bypass(struct dcn10_dpp *dpp) | |||
132 | 132 | ||
133 | #define IDENTITY_RATIO(ratio) (dc_fixpt_u2d19(ratio) == (1 << 19)) | 133 | #define IDENTITY_RATIO(ratio) (dc_fixpt_u2d19(ratio) == (1 << 19)) |
134 | 134 | ||
135 | 135 | static bool dpp_get_optimal_number_of_taps( | |
136 | bool dpp_get_optimal_number_of_taps( | ||
137 | struct dpp *dpp, | 136 | struct dpp *dpp, |
138 | struct scaler_data *scl_data, | 137 | struct scaler_data *scl_data, |
139 | const struct scaling_taps *in_taps) | 138 | const struct scaling_taps *in_taps) |
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h index 5944a3ba0409..e862cafa6501 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h | |||
@@ -1424,12 +1424,8 @@ void dpp1_set_degamma( | |||
1424 | enum ipp_degamma_mode mode); | 1424 | enum ipp_degamma_mode mode); |
1425 | 1425 | ||
1426 | void dpp1_set_degamma_pwl(struct dpp *dpp_base, | 1426 | void dpp1_set_degamma_pwl(struct dpp *dpp_base, |
1427 | const struct pwl_params *params); | 1427 | const struct pwl_params *params); |
1428 | 1428 | ||
1429 | bool dpp_get_optimal_number_of_taps( | ||
1430 | struct dpp *dpp, | ||
1431 | struct scaler_data *scl_data, | ||
1432 | const struct scaling_taps *in_taps); | ||
1433 | 1429 | ||
1434 | void dpp_read_state(struct dpp *dpp_base, | 1430 | void dpp_read_state(struct dpp *dpp_base, |
1435 | struct dcn_dpp_state *s); | 1431 | struct dcn_dpp_state *s); |
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c index 4ddd6273d5a5..f862fd148cca 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c | |||
@@ -565,16 +565,16 @@ static void dpp1_dscl_set_manual_ratio_init( | |||
565 | uint32_t init_int = 0; | 565 | uint32_t init_int = 0; |
566 | 566 | ||
567 | REG_SET(SCL_HORZ_FILTER_SCALE_RATIO, 0, | 567 | REG_SET(SCL_HORZ_FILTER_SCALE_RATIO, 0, |
568 | SCL_H_SCALE_RATIO, dc_fixpt_u2d19(data->ratios.horz) << 5); | 568 | SCL_H_SCALE_RATIO, dc_fixpt_u3d19(data->ratios.horz) << 5); |
569 | 569 | ||
570 | REG_SET(SCL_VERT_FILTER_SCALE_RATIO, 0, | 570 | REG_SET(SCL_VERT_FILTER_SCALE_RATIO, 0, |
571 | SCL_V_SCALE_RATIO, dc_fixpt_u2d19(data->ratios.vert) << 5); | 571 | SCL_V_SCALE_RATIO, dc_fixpt_u3d19(data->ratios.vert) << 5); |
572 | 572 | ||
573 | REG_SET(SCL_HORZ_FILTER_SCALE_RATIO_C, 0, | 573 | REG_SET(SCL_HORZ_FILTER_SCALE_RATIO_C, 0, |
574 | SCL_H_SCALE_RATIO_C, dc_fixpt_u2d19(data->ratios.horz_c) << 5); | 574 | SCL_H_SCALE_RATIO_C, dc_fixpt_u3d19(data->ratios.horz_c) << 5); |
575 | 575 | ||
576 | REG_SET(SCL_VERT_FILTER_SCALE_RATIO_C, 0, | 576 | REG_SET(SCL_VERT_FILTER_SCALE_RATIO_C, 0, |
577 | SCL_V_SCALE_RATIO_C, dc_fixpt_u2d19(data->ratios.vert_c) << 5); | 577 | SCL_V_SCALE_RATIO_C, dc_fixpt_u3d19(data->ratios.vert_c) << 5); |
578 | 578 | ||
579 | /* | 579 | /* |
580 | * 0.24 format for fraction, first five bits zeroed | 580 | * 0.24 format for fraction, first five bits zeroed |
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c index d2ab78b35a7a..c28085be39ff 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c | |||
@@ -396,11 +396,15 @@ bool hubp1_program_surface_flip_and_addr( | |||
396 | if (address->grph_stereo.right_addr.quad_part == 0) | 396 | if (address->grph_stereo.right_addr.quad_part == 0) |
397 | break; | 397 | break; |
398 | 398 | ||
399 | REG_UPDATE_4(DCSURF_SURFACE_CONTROL, | 399 | REG_UPDATE_8(DCSURF_SURFACE_CONTROL, |
400 | PRIMARY_SURFACE_TMZ, address->tmz_surface, | 400 | PRIMARY_SURFACE_TMZ, address->tmz_surface, |
401 | PRIMARY_SURFACE_TMZ_C, address->tmz_surface, | 401 | PRIMARY_SURFACE_TMZ_C, address->tmz_surface, |
402 | PRIMARY_META_SURFACE_TMZ, address->tmz_surface, | 402 | PRIMARY_META_SURFACE_TMZ, address->tmz_surface, |
403 | PRIMARY_META_SURFACE_TMZ_C, address->tmz_surface); | 403 | PRIMARY_META_SURFACE_TMZ_C, address->tmz_surface, |
404 | SECONDARY_SURFACE_TMZ, address->tmz_surface, | ||
405 | SECONDARY_SURFACE_TMZ_C, address->tmz_surface, | ||
406 | SECONDARY_META_SURFACE_TMZ, address->tmz_surface, | ||
407 | SECONDARY_META_SURFACE_TMZ_C, address->tmz_surface); | ||
404 | 408 | ||
405 | if (address->grph_stereo.right_meta_addr.quad_part != 0) { | 409 | if (address->grph_stereo.right_meta_addr.quad_part != 0) { |
406 | 410 | ||
@@ -459,9 +463,11 @@ void hubp1_dcc_control(struct hubp *hubp, bool enable, | |||
459 | uint32_t dcc_ind_64b_blk = independent_64b_blks ? 1 : 0; | 463 | uint32_t dcc_ind_64b_blk = independent_64b_blks ? 1 : 0; |
460 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); | 464 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); |
461 | 465 | ||
462 | REG_UPDATE_2(DCSURF_SURFACE_CONTROL, | 466 | REG_UPDATE_4(DCSURF_SURFACE_CONTROL, |
463 | PRIMARY_SURFACE_DCC_EN, dcc_en, | 467 | PRIMARY_SURFACE_DCC_EN, dcc_en, |
464 | PRIMARY_SURFACE_DCC_IND_64B_BLK, dcc_ind_64b_blk); | 468 | PRIMARY_SURFACE_DCC_IND_64B_BLK, dcc_ind_64b_blk, |
469 | SECONDARY_SURFACE_DCC_EN, dcc_en, | ||
470 | SECONDARY_SURFACE_DCC_IND_64B_BLK, dcc_ind_64b_blk); | ||
465 | } | 471 | } |
466 | 472 | ||
467 | void hubp1_program_surface_config( | 473 | void hubp1_program_surface_config( |
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h index af384034398f..d901d5092969 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h | |||
@@ -312,6 +312,12 @@ | |||
312 | HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, PRIMARY_META_SURFACE_TMZ_C, mask_sh),\ | 312 | HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, PRIMARY_META_SURFACE_TMZ_C, mask_sh),\ |
313 | HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, PRIMARY_SURFACE_DCC_EN, mask_sh),\ | 313 | HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, PRIMARY_SURFACE_DCC_EN, mask_sh),\ |
314 | HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, PRIMARY_SURFACE_DCC_IND_64B_BLK, mask_sh),\ | 314 | HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, PRIMARY_SURFACE_DCC_IND_64B_BLK, mask_sh),\ |
315 | HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, SECONDARY_SURFACE_TMZ, mask_sh),\ | ||
316 | HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, SECONDARY_SURFACE_TMZ_C, mask_sh),\ | ||
317 | HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, SECONDARY_META_SURFACE_TMZ, mask_sh),\ | ||
318 | HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, SECONDARY_META_SURFACE_TMZ_C, mask_sh),\ | ||
319 | HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, SECONDARY_SURFACE_DCC_EN, mask_sh),\ | ||
320 | HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, SECONDARY_SURFACE_DCC_IND_64B_BLK, mask_sh),\ | ||
315 | HUBP_SF(HUBPRET0_HUBPRET_CONTROL, DET_BUF_PLANE1_BASE_ADDRESS, mask_sh),\ | 321 | HUBP_SF(HUBPRET0_HUBPRET_CONTROL, DET_BUF_PLANE1_BASE_ADDRESS, mask_sh),\ |
316 | HUBP_SF(HUBPRET0_HUBPRET_CONTROL, CROSSBAR_SRC_CB_B, mask_sh),\ | 322 | HUBP_SF(HUBPRET0_HUBPRET_CONTROL, CROSSBAR_SRC_CB_B, mask_sh),\ |
317 | HUBP_SF(HUBPRET0_HUBPRET_CONTROL, CROSSBAR_SRC_CR_R, mask_sh),\ | 323 | HUBP_SF(HUBPRET0_HUBPRET_CONTROL, CROSSBAR_SRC_CR_R, mask_sh),\ |
@@ -489,6 +495,8 @@ | |||
489 | type SECONDARY_META_SURFACE_TMZ_C;\ | 495 | type SECONDARY_META_SURFACE_TMZ_C;\ |
490 | type PRIMARY_SURFACE_DCC_EN;\ | 496 | type PRIMARY_SURFACE_DCC_EN;\ |
491 | type PRIMARY_SURFACE_DCC_IND_64B_BLK;\ | 497 | type PRIMARY_SURFACE_DCC_IND_64B_BLK;\ |
498 | type SECONDARY_SURFACE_DCC_EN;\ | ||
499 | type SECONDARY_SURFACE_DCC_IND_64B_BLK;\ | ||
492 | type DET_BUF_PLANE1_BASE_ADDRESS;\ | 500 | type DET_BUF_PLANE1_BASE_ADDRESS;\ |
493 | type CROSSBAR_SRC_CB_B;\ | 501 | type CROSSBAR_SRC_CB_B;\ |
494 | type CROSSBAR_SRC_CR_R;\ | 502 | type CROSSBAR_SRC_CR_R;\ |
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c index 653b7b2efe2e..c928ee4cd382 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c | |||
@@ -319,6 +319,10 @@ void enc1_stream_encoder_dp_set_stream_attribute( | |||
319 | REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH, | 319 | REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH, |
320 | DP_COMPONENT_PIXEL_DEPTH_12BPC); | 320 | DP_COMPONENT_PIXEL_DEPTH_12BPC); |
321 | break; | 321 | break; |
322 | case COLOR_DEPTH_161616: | ||
323 | REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH, | ||
324 | DP_COMPONENT_PIXEL_DEPTH_16BPC); | ||
325 | break; | ||
322 | default: | 326 | default: |
323 | REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH, | 327 | REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH, |
324 | DP_COMPONENT_PIXEL_DEPTH_6BPC); | 328 | DP_COMPONENT_PIXEL_DEPTH_6BPC); |
diff --git a/drivers/gpu/drm/amd/display/include/fixed31_32.h b/drivers/gpu/drm/amd/display/include/fixed31_32.h index bb0d4ebba9f0..a981b3e99ab3 100644 --- a/drivers/gpu/drm/amd/display/include/fixed31_32.h +++ b/drivers/gpu/drm/amd/display/include/fixed31_32.h | |||
@@ -496,6 +496,8 @@ static inline int dc_fixpt_ceil(struct fixed31_32 arg) | |||
496 | * fractional | 496 | * fractional |
497 | */ | 497 | */ |
498 | 498 | ||
499 | unsigned int dc_fixpt_u3d19(struct fixed31_32 arg); | ||
500 | |||
499 | unsigned int dc_fixpt_u2d19(struct fixed31_32 arg); | 501 | unsigned int dc_fixpt_u2d19(struct fixed31_32 arg); |
500 | 502 | ||
501 | unsigned int dc_fixpt_u0d19(struct fixed31_32 arg); | 503 | unsigned int dc_fixpt_u0d19(struct fixed31_32 arg); |