diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display')
86 files changed, 2809 insertions, 1187 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 00edf78975b1..a0c8c41e4e57 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -121,7 +121,7 @@ MODULE_FIRMWARE(FIRMWARE_NAVI12_DMCU); * DOC: overview * * The AMDgpu display manager, **amdgpu_dm** (or even simpler, - * **dm**) sits between DRM and DC. It acts as a liason, converting DRM + * **dm**) sits between DRM and DC. It acts as a liaison, converting DRM * requests into DC requests, and DC responses into DRM responses. * * The root control structure is &struct amdgpu_display_manager. @@ -130,6 +130,7 @@ MODULE_FIRMWARE(FIRMWARE_NAVI12_DMCU); /* basic init/fini API */ static int amdgpu_dm_init(struct amdgpu_device *adev); static void amdgpu_dm_fini(struct amdgpu_device *adev); +static bool is_freesync_video_mode(const struct drm_display_mode *mode, struct amdgpu_dm_connector *aconnector); static enum drm_mode_subconnector get_subconnector_type(struct dc_link *link) { @@ -371,14 +372,14 @@ static void dm_pflip_high_irq(void *interrupt_params) /* IRQ could occur when in initial stage */ /* TODO work and BO cleanup */ if (amdgpu_crtc == NULL) { - DRM_DEBUG_DRIVER("CRTC is null, returning.\n"); + DC_LOG_PFLIP("CRTC is null, returning.\n"); return; } spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags); if (amdgpu_crtc->pflip_status != AMDGPU_FLIP_SUBMITTED){ - DRM_DEBUG_DRIVER("amdgpu_crtc->pflip_status = %d !=AMDGPU_FLIP_SUBMITTED(%d) on crtc:%d[%p] \n", + DC_LOG_PFLIP("amdgpu_crtc->pflip_status = %d !=AMDGPU_FLIP_SUBMITTED(%d) on crtc:%d[%p] \n", amdgpu_crtc->pflip_status, AMDGPU_FLIP_SUBMITTED, amdgpu_crtc->crtc_id, @@ -449,9 +450,9 @@ static void dm_pflip_high_irq(void *interrupt_params) amdgpu_crtc->pflip_status = AMDGPU_FLIP_NONE; spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags); - DRM_DEBUG_DRIVER("crtc:%d[%p], pflip_stat:AMDGPU_FLIP_NONE, vrr[%d]-fp %d\n", - amdgpu_crtc->crtc_id, amdgpu_crtc, - vrr_active, (int) !e); + DC_LOG_PFLIP("crtc:%d[%p], pflip_stat:AMDGPU_FLIP_NONE, vrr[%d]-fp %d\n", + amdgpu_crtc->crtc_id, amdgpu_crtc, + vrr_active, (int) !e); } static void dm_vupdate_high_irq(void *interrupt_params) @@ -459,6 +460,9 @@ static void dm_vupdate_high_irq(void *interrupt_params) struct common_irq_params *irq_params = interrupt_params; struct amdgpu_device *adev = irq_params->adev; struct amdgpu_crtc *acrtc; + struct drm_device *drm_dev; + struct drm_vblank_crtc *vblank; + ktime_t frame_duration_ns, previous_timestamp; unsigned long flags; int vrr_active; @@ -466,8 +470,19 @@ static void dm_vupdate_high_irq(void *interrupt_params) if (acrtc) { vrr_active = amdgpu_dm_vrr_active_irq(acrtc); + drm_dev = acrtc->base.dev; + vblank = &drm_dev->vblank[acrtc->base.index]; + previous_timestamp = atomic64_read(&irq_params->previous_timestamp); + frame_duration_ns = vblank->time - previous_timestamp; - DRM_DEBUG_VBL("crtc:%d, vupdate-vrr:%d\n", + if (frame_duration_ns > 0) { + trace_amdgpu_refresh_rate_track(acrtc->base.index, + frame_duration_ns, + ktime_divns(NSEC_PER_SEC, frame_duration_ns)); + atomic64_set(&irq_params->previous_timestamp, vblank->time); + } + + DC_LOG_VBLANK("crtc:%d, vupdate-vrr:%d\n", acrtc->crtc_id, vrr_active); @@ -520,7 +535,7 @@ static void dm_crtc_high_irq(void *interrupt_params) vrr_active = amdgpu_dm_vrr_active_irq(acrtc); - DRM_DEBUG_VBL("crtc:%d, vupdate-vrr:%d, planes:%d\n", acrtc->crtc_id, + DC_LOG_VBLANK("crtc:%d, vupdate-vrr:%d, planes:%d\n", acrtc->crtc_id, vrr_active, acrtc->dm_irq_params.active_planes); /** @@ -923,6 +938,32 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev) } #if defined(CONFIG_DRM_AMD_DC_DCN) +#define DMUB_TRACE_MAX_READ 64 +static void dm_dmub_trace_high_irq(void *interrupt_params) +{ + struct common_irq_params *irq_params = interrupt_params; + struct amdgpu_device *adev = irq_params->adev; + struct amdgpu_display_manager *dm = &adev->dm; + struct dmcub_trace_buf_entry entry = { 0 }; + uint32_t count = 0; + + do { + if (dc_dmub_srv_get_dmub_outbox0_msg(dm->dc, &entry)) { + trace_amdgpu_dmub_trace_high_irq(entry.trace_code, entry.tick_count, + entry.param0, entry.param1); + + DRM_DEBUG_DRIVER("trace_code:%u, tick_count:%u, param0:%u, param1:%u\n", + entry.trace_code, entry.tick_count, entry.param0, entry.param1); + } else + break; + + count++; + + } while (count <= DMUB_TRACE_MAX_READ); + + ASSERT(count <= DMUB_TRACE_MAX_READ); +} + static void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_addr_space_config *pa_config) { uint64_t pt_base; @@ -987,13 +1028,12 @@ static void event_mall_stutter(struct work_struct *work) if (vblank_work->enable) dm->active_vblank_irq_count++; - else + else if(dm->active_vblank_irq_count) dm->active_vblank_irq_count--; dc_allow_idle_optimizations(dm->dc, dm->active_vblank_irq_count == 0); - DRM_DEBUG_DRIVER("Allow idle optimizations (MALL): %d\n", dm->active_vblank_irq_count == 0); - + DRM_DEBUG_KMS("Allow idle optimizations (MALL): %d\n", dm->active_vblank_irq_count == 0); mutex_unlock(&dm->dc_lock); } @@ -1809,8 +1849,8 @@ static void dm_gpureset_toggle_interrupts(struct amdgpu_device *adev, if (acrtc && state->stream_status[i].plane_count != 0) { irq_source = IRQ_TYPE_PFLIP + acrtc->otg_inst; rc = dc_interrupt_set(adev->dm.dc, irq_source, enable) ? 0 : -EBUSY; - DRM_DEBUG("crtc %d - vupdate irq %sabling: r=%d\n", - acrtc->crtc_id, enable ? "en" : "dis", rc); + DRM_DEBUG_VBL("crtc %d - vupdate irq %sabling: r=%d\n", + acrtc->crtc_id, enable ? "en" : "dis", rc); if (rc) DRM_WARN("Failed to %s pflip interrupts\n", enable ? "enable" : "disable"); @@ -3104,6 +3144,28 @@ static int dcn10_register_irq_handlers(struct amdgpu_device *adev) } + if (dc->ctx->dmub_srv) { + i = DCN_1_0__SRCID__DMCUB_OUTBOX_HIGH_PRIORITY_READY_INT; + r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_DCE, i, &adev->dmub_trace_irq); + + if (r) { + DRM_ERROR("Failed to add dmub trace irq id!\n"); + return r; + } + + int_params.int_context = INTERRUPT_HIGH_IRQ_CONTEXT; + int_params.irq_source = + dc_interrupt_to_irq_source(dc, i, 0); + + c_irq_params = &adev->dm.dmub_trace_params[0]; + + c_irq_params->adev = adev; + c_irq_params->irq_src = int_params.irq_source; + + amdgpu_dm_irq_register_interrupt(adev, &int_params, + dm_dmub_trace_high_irq, c_irq_params); + } + /* HPD */ r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_DCE, DCN_1_0__SRCID__DC_HPD1_INT, &adev->hpd_irq); @@ -4892,8 +4954,8 @@ static void update_stream_scaling_settings(const struct drm_display_mode *mode, stream->src = src; stream->dst = dst; - DRM_DEBUG_DRIVER("Destination Rectangle x:%d y:%d width:%d height:%d\n", - dst.x, dst.y, dst.width, dst.height); + DRM_DEBUG_KMS("Destination Rectangle x:%d y:%d width:%d height:%d\n", + dst.x, dst.y, dst.width, dst.height); } @@ -5106,15 +5168,27 @@ static void fill_stream_properties_from_drm_display_mode( timing_out->hdmi_vic = hv_frame.vic; } - timing_out->h_addressable = mode_in->hdisplay; - timing_out->h_total = mode_in->htotal; - timing_out->h_sync_width = mode_in->hsync_end - mode_in->hsync_start; - timing_out->h_front_porch = mode_in->hsync_start - mode_in->hdisplay; - timing_out->v_total = mode_in->vtotal; - timing_out->v_addressable = mode_in->vdisplay; - timing_out->v_front_porch = mode_in->vsync_start - mode_in->vdisplay; - timing_out->v_sync_width = mode_in->vsync_end - mode_in->vsync_start; - timing_out->pix_clk_100hz = mode_in->clock * 10; + if (is_freesync_video_mode(mode_in, aconnector)) { + timing_out->h_addressable = mode_in->hdisplay; + timing_out->h_total = mode_in->htotal; + timing_out->h_sync_width = mode_in->hsync_end - mode_in->hsync_start; + timing_out->h_front_porch = mode_in->hsync_start - mode_in->hdisplay; + timing_out->v_total = mode_in->vtotal; + timing_out->v_addressable = mode_in->vdisplay; + timing_out->v_front_porch = mode_in->vsync_start - mode_in->vdisplay; + timing_out->v_sync_width = mode_in->vsync_end - mode_in->vsync_start; + timing_out->pix_clk_100hz = mode_in->clock * 10; + } else { + timing_out->h_addressable = mode_in->crtc_hdisplay; + timing_out->h_total = mode_in->crtc_htotal; + timing_out->h_sync_width = mode_in->crtc_hsync_end - mode_in->crtc_hsync_start; + timing_out->h_front_porch = mode_in->crtc_hsync_start - mode_in->crtc_hdisplay; + timing_out->v_total = mode_in->crtc_vtotal; + timing_out->v_addressable = mode_in->crtc_vdisplay; + timing_out->v_front_porch = mode_in->crtc_vsync_start - mode_in->crtc_vdisplay; + timing_out->v_sync_width = mode_in->crtc_vsync_end - mode_in->crtc_vsync_start; + timing_out->pix_clk_100hz = mode_in->crtc_clock * 10; + } timing_out->aspect_ratio = get_aspect_ratio(mode_in); @@ -5234,9 +5308,14 @@ create_fake_sink(struct amdgpu_dm_connector *aconnector) static void set_multisync_trigger_params( struct dc_stream_state *stream) { + struct dc_stream_state *master = NULL; + if (stream->triggered_crtc_reset.enabled) { - stream->triggered_crtc_reset.event = CRTC_EVENT_VSYNC_RISING; - stream->triggered_crtc_reset.delay = TRIGGER_DELAY_NEXT_LINE; + master = stream->triggered_crtc_reset.event_source; + stream->triggered_crtc_reset.event = + master->timing.flags.VSYNC_POSITIVE_POLARITY ? + CRTC_EVENT_VSYNC_RISING : CRTC_EVENT_VSYNC_FALLING; + stream->triggered_crtc_reset.delay = TRIGGER_DELAY_NEXT_PIXEL; } } @@ -5266,6 +5345,7 @@ static void set_master_stream(struct dc_stream_state *stream_set[], static void dm_enable_per_frame_crtc_master_sync(struct dc_state *context) { int i = 0; + struct dc_stream_state *stream; if (context->stream_count < 2) return; @@ -5277,9 +5357,18 @@ static void dm_enable_per_frame_crtc_master_sync(struct dc_state *context) * crtc_sync_master.multi_sync_enabled flag * For now it's set to false */ - set_multisync_trigger_params(context->streams[i]); } + set_master_stream(context->streams, context->stream_count); + + for (i = 0; i < context->stream_count ; i++) { + stream = context->streams[i]; + + if (!stream) + continue; + + set_multisync_trigger_params(stream); + } } static struct drm_display_mode * @@ -5335,7 +5424,7 @@ get_highest_refresh_rate_mode(struct amdgpu_dm_connector *aconnector, return m_pref; } -static bool is_freesync_video_mode(struct drm_display_mode *mode, +static bool is_freesync_video_mode(const struct drm_display_mode *mode, struct amdgpu_dm_connector *aconnector) { struct drm_display_mode *high_mode; @@ -5458,7 +5547,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, if (recalculate_timing) drm_mode_set_crtcinfo(&saved_mode, 0); - else + else if (!dm_state) drm_mode_set_crtcinfo(&mode, 0); /* @@ -5636,8 +5725,8 @@ static inline int dm_set_vupdate_irq(struct drm_crtc *crtc, bool enable) rc = dc_interrupt_set(adev->dm.dc, irq_source, enable) ? 0 : -EBUSY; - DRM_DEBUG_DRIVER("crtc %d - vupdate irq %sabling: r=%d\n", - acrtc->crtc_id, enable ? "en" : "dis", rc); + DRM_DEBUG_VBL("crtc %d - vupdate irq %sabling: r=%d\n", + acrtc->crtc_id, enable ? "en" : "dis", rc); return rc; } @@ -6075,6 +6164,15 @@ create_validate_stream_for_sink(struct amdgpu_dm_connector *aconnector, } while (stream == NULL && requested_bpc >= 6); + if (dc_result == DC_FAIL_ENC_VALIDATE && !aconnector->force_yuv420_output) { + DRM_DEBUG_KMS("Retry forcing YCbCr420 encoding\n"); + + aconnector->force_yuv420_output = true; + stream = create_validate_stream_for_sink(aconnector, drm_mode, + dm_state, old_stream); + aconnector->force_yuv420_output = false; + } + return stream; } @@ -6577,7 +6675,7 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane, int r; if (!new_state->fb) { - DRM_DEBUG_DRIVER("No FB bound\n"); + DRM_DEBUG_KMS("No FB bound\n"); return 0; } @@ -7295,7 +7393,7 @@ static void amdgpu_dm_connector_add_freesync_modes(struct drm_connector *connect if (!(amdgpu_freesync_vid_mode && edid)) return; - + if (amdgpu_dm_connector->max_vfreq - amdgpu_dm_connector->min_vfreq > 10) amdgpu_dm_connector->num_modes += add_fs_modes(amdgpu_dm_connector); @@ -7810,11 +7908,11 @@ static void handle_cursor_update(struct drm_plane *plane, if (!plane->state->fb && !old_plane_state->fb) return; - DRM_DEBUG_DRIVER("%s: crtc_id=%d with size %d to %d\n", - __func__, - amdgpu_crtc->crtc_id, - plane->state->crtc_w, - plane->state->crtc_h); + DC_LOG_CURSOR("%s: crtc_id=%d with size %d to %d\n", + __func__, + amdgpu_crtc->crtc_id, + plane->state->crtc_w, + plane->state->crtc_h); ret = get_cursor_position(plane, crtc, &position); if (ret) @@ -7872,8 +7970,8 @@ static void prepare_flip_isr(struct amdgpu_crtc *acrtc) /* Mark this event as consumed */ acrtc->base.state->event = NULL; - DRM_DEBUG_DRIVER("crtc:%d, pflip_stat:AMDGPU_FLIP_SUBMITTED\n", - acrtc->crtc_id); + DC_LOG_PFLIP("crtc:%d, pflip_stat:AMDGPU_FLIP_SUBMITTED\n", + acrtc->crtc_id); } static void update_freesync_state_on_stream( @@ -8179,7 +8277,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, &bundle->flip_addrs[planes_count].address, afb->tmz_surface, false); - DRM_DEBUG_DRIVER("plane: id=%d dcc_en=%d\n", + DRM_DEBUG_ATOMIC("plane: id=%d dcc_en=%d\n", new_plane_state->plane->index, bundle->plane_infos[planes_count].dcc.enable); @@ -8213,7 +8311,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, dc_plane, bundle->flip_addrs[planes_count].flip_timestamp_in_us); - DRM_DEBUG_DRIVER("%s Flipping to hi: 0x%x, low: 0x%x\n", + DRM_DEBUG_ATOMIC("%s Flipping to hi: 0x%x, low: 0x%x\n", __func__, bundle->flip_addrs[planes_count].address.grph.addr.high_part, bundle->flip_addrs[planes_count].address.grph.addr.low_part); @@ -8535,7 +8633,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); - DRM_DEBUG_DRIVER( + DRM_DEBUG_ATOMIC( "amdgpu_crtc id:%d crtc_state_flags: enable:%d, active:%d, " "planes_changed:%d, mode_changed:%d,active_changed:%d," "connectors_changed:%d\n", @@ -8569,7 +8667,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) if (modeset_required(new_crtc_state, dm_new_crtc_state->stream, dm_old_crtc_state->stream)) { - DRM_DEBUG_DRIVER("Atomic commit: SET crtc id %d: [%p]\n", acrtc->crtc_id, acrtc); + DRM_DEBUG_ATOMIC("Atomic commit: SET crtc id %d: [%p]\n", acrtc->crtc_id, acrtc); if (!dm_new_crtc_state->stream) { /* @@ -8602,7 +8700,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) crtc->hwmode = new_crtc_state->mode; mode_set_reset_required = true; } else if (modereset_required(new_crtc_state)) { - DRM_DEBUG_DRIVER("Atomic commit: RESET. crtc id %d:[%p]\n", acrtc->crtc_id, acrtc); + DRM_DEBUG_ATOMIC("Atomic commit: RESET. crtc id %d:[%p]\n", acrtc->crtc_id, acrtc); /* i.e. reset mode */ if (dm_old_crtc_state->stream) remove_stream(adev, acrtc, dm_old_crtc_state->stream); @@ -8619,6 +8717,11 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) dm_enable_per_frame_crtc_master_sync(dc_state); mutex_lock(&dm->dc_lock); WARN_ON(!dc_commit_state(dm->dc, dc_state)); +#if defined(CONFIG_DRM_AMD_DC_DCN) + /* Allow idle optimization when vblank count is 0 for display off */ + if (dm->active_vblank_irq_count == 0) + dc_allow_idle_optimizations(dm->dc,true); +#endif mutex_unlock(&dm->dc_lock); } @@ -9207,7 +9310,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, if (!drm_atomic_crtc_needs_modeset(new_crtc_state)) goto skip_modeset; - DRM_DEBUG_DRIVER( + DRM_DEBUG_ATOMIC( "amdgpu_crtc id:%d crtc_state_flags: enable:%d, active:%d, " "planes_changed:%d, mode_changed:%d,active_changed:%d," "connectors_changed:%d\n", @@ -9291,8 +9394,8 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, dc_stream_retain(new_stream); - DRM_DEBUG_DRIVER("Enabling DRM crtc: %d\n", - crtc->base.id); + DRM_DEBUG_ATOMIC("Enabling DRM crtc: %d\n", + crtc->base.id); if (dc_add_stream_to_ctx( dm->dc, @@ -9637,8 +9740,8 @@ static int dm_update_plane_state(struct dc *dc, if (!dc_new_plane_state) return -ENOMEM; - DRM_DEBUG_DRIVER("Enabling DRM plane: %d on DRM crtc %d\n", - plane->base.id, new_plane_crtc->base.id); + DRM_DEBUG_ATOMIC("Enabling DRM plane: %d on DRM crtc %d\n", + plane->base.id, new_plane_crtc->base.id); ret = fill_dc_plane_attributes( drm_to_adev(new_plane_crtc->dev), @@ -9701,7 +9804,8 @@ static int dm_check_crtc_cursor(struct drm_atomic_state *state, new_cursor_state = drm_atomic_get_new_plane_state(state, crtc->cursor); new_primary_state = drm_atomic_get_new_plane_state(state, crtc->primary); - if (!new_cursor_state || !new_primary_state || !new_cursor_state->fb) { + if (!new_cursor_state || !new_primary_state || + !new_cursor_state->fb || !new_primary_state->fb) { return 0; } diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index 8f98d44490aa..018943113025 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -66,6 +66,7 @@ struct dc_plane_state; struct common_irq_params { struct amdgpu_device *adev; enum dc_irq_source irq_src; + atomic64_t previous_timestamp; }; /** @@ -339,6 +340,15 @@ struct amdgpu_display_manager { struct common_irq_params vupdate_params[DC_IRQ_SOURCE_VUPDATE6 - DC_IRQ_SOURCE_VUPDATE1 + 1]; + /** + * @dmub_trace_params: + * + * DMUB trace event IRQ parameters, passed to registered handlers when + * triggered. + */ + struct common_irq_params + dmub_trace_params[1]; + spinlock_t irq_handler_list_table_lock; struct backlight_device *backlight_dev; @@ -385,6 +395,11 @@ struct amdgpu_display_manager { #endif #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) + /** + * @crc_rd_wrk: + * + * Work to be executed in a separate thread to communicate with PSP. + */ struct crc_rd_work *crc_rd_wrk; #endif diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c index c6d6baab106e..5cd788b20c21 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c @@ -307,7 +307,7 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name) goto cleanup; } - aux = &aconn->dm_dp_aux.aux; + aux = (aconn->port) ? &aconn->port->aux : &aconn->dm_dp_aux.aux; if (!aux) { DRM_DEBUG_DRIVER("No dp aux for amd connector\n"); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c index 927de7678a4f..9a13f47022df 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c @@ -34,6 +34,7 @@ #include "resource.h" #include "dsc.h" #include "dc_link_dp.h" +#include "link_hwss.h" #include "dc/dc_dmub_srv.h" struct dmub_debugfs_trace_header { @@ -149,7 +150,7 @@ static int parse_write_buffer_into_params(char *wr_buf, uint32_t wr_buf_size, * * --- to get dp configuration * - * cat link_settings + * cat /sys/kernel/debug/dri/0/DP-x/link_settings * * It will list current, verified, reported, preferred dp configuration. * current -- for current video mode @@ -162,7 +163,7 @@ static int parse_write_buffer_into_params(char *wr_buf, uint32_t wr_buf_size, * echo <lane_count> <link_rate> > link_settings * * for example, to force to 2 lane, 2.7GHz, - * echo 4 0xa > link_settings + * echo 4 0xa > /sys/kernel/debug/dri/0/DP-x/link_settings * * spread_spectrum could not be changed dynamically. * @@ -170,7 +171,7 @@ static int parse_write_buffer_into_params(char *wr_buf, uint32_t wr_buf_size, * done. please check link settings after force operation to see if HW get * programming. * - * cat link_settings + * cat /sys/kernel/debug/dri/0/DP-x/link_settings * * check current and preferred settings. * @@ -246,7 +247,6 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf, { struct amdgpu_dm_connector *connector = file_inode(f)->i_private; struct dc_link *link = connector->dc_link; - struct dc *dc = (struct dc *)link->dc; struct dc_link_settings prefer_link_settings; char *wr_buf = NULL; const uint32_t wr_buf_size = 40; @@ -254,7 +254,7 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf, int max_param_num = 2; uint8_t param_nums = 0; long param[2]; - bool valid_input = false; + bool valid_input = true; if (size == 0) return -EINVAL; @@ -281,9 +281,9 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf, case LANE_COUNT_ONE: case LANE_COUNT_TWO: case LANE_COUNT_FOUR: - valid_input = true; break; default: + valid_input = false; break; } @@ -293,9 +293,9 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf, case LINK_RATE_RBR2: case LINK_RATE_HIGH2: case LINK_RATE_HIGH3: - valid_input = true; break; default: + valid_input = false; break; } @@ -309,10 +309,11 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf, * spread spectrum will not be changed */ prefer_link_settings.link_spread = link->cur_link_settings.link_spread; + prefer_link_settings.use_link_rate_set = false; prefer_link_settings.lane_count = param[0]; prefer_link_settings.link_rate = param[1]; - dc_link_set_preferred_link_settings(dc, &prefer_link_settings, link); + dp_retrain_link_dp_test(link, &prefer_link_settings, false); kfree(wr_buf); return size; @@ -399,6 +400,70 @@ static ssize_t dp_phy_settings_read(struct file *f, char __user *buf, return result; } +static int dp_lttpr_status_show(struct seq_file *m, void *d) +{ + char *data; + struct amdgpu_dm_connector *connector = file_inode(m->file)->i_private; + struct dc_link *link = connector->dc_link; + uint32_t read_size = 1; + uint8_t repeater_count = 0; + + data = kzalloc(read_size, GFP_KERNEL); + if (!data) + return 0; + + dm_helpers_dp_read_dpcd(link->ctx, link, 0xF0002, data, read_size); + + switch ((uint8_t)*data) { + case 0x80: + repeater_count = 1; + break; + case 0x40: + repeater_count = 2; + break; + case 0x20: + repeater_count = 3; + break; + case 0x10: + repeater_count = 4; + break; + case 0x8: + repeater_count = 5; + break; + case 0x4: + repeater_count = 6; + break; + case 0x2: + repeater_count = 7; + break; + case 0x1: + repeater_count = 8; + break; + case 0x0: + repeater_count = 0; + break; + default: + repeater_count = (uint8_t)*data; + break; + } + + seq_printf(m, "phy repeater count: %d\n", repeater_count); + + dm_helpers_dp_read_dpcd(link->ctx, link, 0xF0003, data, read_size); + + if ((uint8_t)*data == 0x55) + seq_printf(m, "phy repeater mode: transparent\n"); + else if ((uint8_t)*data == 0xAA) + seq_printf(m, "phy repeater mode: non-transparent\n"); + else if ((uint8_t)*data == 0x00) + seq_printf(m, "phy repeater mode: non lttpr\n"); + else + seq_printf(m, "phy repeater mode: read error\n"); + + kfree(data); + return 0; +} + static ssize_t dp_phy_settings_write(struct file *f, const char __user *buf, size_t size, loff_t *pos) { @@ -2300,6 +2365,7 @@ DEFINE_SHOW_ATTRIBUTE(dp_dsc_fec_support); DEFINE_SHOW_ATTRIBUTE(dmub_fw_state); DEFINE_SHOW_ATTRIBUTE(dmub_tracebuffer); DEFINE_SHOW_ATTRIBUTE(output_bpc); +DEFINE_SHOW_ATTRIBUTE(dp_lttpr_status); #ifdef CONFIG_DRM_AMD_DC_HDCP DEFINE_SHOW_ATTRIBUTE(hdcp_sink_capability); #endif @@ -2420,6 +2486,7 @@ static const struct { } dp_debugfs_entries[] = { {"link_settings", &dp_link_settings_debugfs_fops}, {"phy_settings", &dp_phy_settings_debugfs_fop}, + {"lttpr_status", &dp_lttpr_status_fops}, {"test_pattern", &dp_phy_test_pattern_fops}, #ifdef CONFIG_DRM_AMD_DC_HDCP {"hdcp_sink_capability", &hdcp_sink_capability_fops}, @@ -2900,6 +2967,10 @@ static int mst_topo_show(struct seq_file *m, void *unused) aconnector = to_amdgpu_dm_connector(connector); + /* Ensure we're only dumping the topology of a root mst node */ + if (!aconnector->mst_mgr.mst_state) + continue; + seq_printf(m, "\nMST topology for connector %d\n", aconnector->connector_id); drm_dp_mst_dump_topology(m, &aconnector->mst_mgr); } @@ -2909,7 +2980,73 @@ static int mst_topo_show(struct seq_file *m, void *unused) } /* - * Sets the force_timing_sync debug optino from the given string. + * Sets trigger hpd for MST topologies. + * All connected connectors will be rediscovered and re started as needed if val of 1 is sent. + * All topologies will be disconnected if val of 0 is set . + * Usage to enable topologies: echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_trigger_hpd_mst + * Usage to disable topologies: echo 0 > /sys/kernel/debug/dri/0/amdgpu_dm_trigger_hpd_mst + */ +static int trigger_hpd_mst_set(void *data, u64 val) +{ + struct amdgpu_device *adev = data; + struct drm_device *dev = adev_to_drm(adev); + struct drm_connector_list_iter iter; + struct amdgpu_dm_connector *aconnector; + struct drm_connector *connector; + struct dc_link *link = NULL; + + if (val == 1) { + drm_connector_list_iter_begin(dev, &iter); + drm_for_each_connector_iter(connector, &iter) { + aconnector = to_amdgpu_dm_connector(connector); + if (aconnector->dc_link->type == dc_connection_mst_branch && + aconnector->mst_mgr.aux) { + dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD); + drm_dp_mst_topology_mgr_set_mst(&aconnector->mst_mgr, true); + } + } + } else if (val == 0) { + drm_connector_list_iter_begin(dev, &iter); + drm_for_each_connector_iter(connector, &iter) { + aconnector = to_amdgpu_dm_connector(connector); + if (!aconnector->dc_link) + continue; + + if (!(aconnector->port && &aconnector->mst_port->mst_mgr)) + continue; + + link = aconnector->dc_link; + dp_receiver_power_ctrl(link, false); + drm_dp_mst_topology_mgr_set_mst(&aconnector->mst_port->mst_mgr, false); + link->mst_stream_alloc_table.stream_count = 0; + memset(link->mst_stream_alloc_table.stream_allocations, 0, + sizeof(link->mst_stream_alloc_table.stream_allocations)); + } + } else { + return 0; + } + drm_kms_helper_hotplug_event(dev); + + return 0; +} + +/* + * The interface doesn't need get function, so it will return the + * value of zero + * Usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_trigger_hpd_mst + */ +static int trigger_hpd_mst_get(void *data, u64 *val) +{ + *val = 0; + return 0; +} + +DEFINE_DEBUGFS_ATTRIBUTE(trigger_hpd_mst_ops, trigger_hpd_mst_get, + trigger_hpd_mst_set, "%llu\n"); + + +/* + * Sets the force_timing_sync debug option from the given string. * All connected displays will be force synchronized immediately. * Usage: echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_force_timing_sync */ @@ -2972,6 +3109,64 @@ DEFINE_SHOW_ATTRIBUTE(mst_topo); DEFINE_DEBUGFS_ATTRIBUTE(visual_confirm_fops, visual_confirm_get, visual_confirm_set, "%llu\n"); +/* + * Dumps the DCC_EN bit for each pipe. + * Example usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_dcc_en + */ +static ssize_t dcc_en_bits_read( + struct file *f, + char __user *buf, + size_t size, + loff_t *pos) +{ + struct amdgpu_device *adev = file_inode(f)->i_private; + struct dc *dc = adev->dm.dc; + char *rd_buf = NULL; + const uint32_t rd_buf_size = 32; + uint32_t result = 0; + int offset = 0; + int num_pipes = dc->res_pool->pipe_count; + int *dcc_en_bits; + int i, r; + + dcc_en_bits = kcalloc(num_pipes, sizeof(int), GFP_KERNEL); + if (!dcc_en_bits) + return -ENOMEM; + + if (!dc->hwss.get_dcc_en_bits) { + kfree(dcc_en_bits); + return 0; + } + + dc->hwss.get_dcc_en_bits(dc, dcc_en_bits); + + rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL); + if (!rd_buf) + return -ENOMEM; + + for (i = 0; i < num_pipes; i++) + offset += snprintf(rd_buf + offset, rd_buf_size - offset, + "%d ", dcc_en_bits[i]); + rd_buf[strlen(rd_buf)] = '\n'; + + kfree(dcc_en_bits); + + while (size) { + if (*pos >= rd_buf_size) + break; + r = put_user(*(rd_buf + result), buf); + if (r) + return r; /* r = -EFAULT */ + buf += 1; + size -= 1; + *pos += 1; + result += 1; + } + + kfree(rd_buf); + return result; +} + void dtn_debugfs_init(struct amdgpu_device *adev) { static const struct file_operations dtn_log_fops = { @@ -2980,6 +3175,11 @@ void dtn_debugfs_init(struct amdgpu_device *adev) .write = dtn_log_write, .llseek = default_llseek }; + static const struct file_operations dcc_en_bits_fops = { + .owner = THIS_MODULE, + .read = dcc_en_bits_read, + .llseek = default_llseek + }; struct drm_minor *minor = adev_to_drm(adev)->primary; struct dentry *root = minor->debugfs_root; @@ -3007,4 +3207,10 @@ void dtn_debugfs_init(struct amdgpu_device *adev) debugfs_create_file_unsafe("amdgpu_dm_dmcub_trace_event_en", 0644, root, adev, &dmcub_trace_event_state_fops); + + debugfs_create_file_unsafe("amdgpu_dm_trigger_hpd_mst", 0644, root, + adev, &trigger_hpd_mst_ops); + + debugfs_create_file_unsafe("amdgpu_dm_dcc_en", 0644, root, adev, + &dcc_en_bits_fops); } diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c index 0cdbfcd475ec..60f91853bd82 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c @@ -191,7 +191,7 @@ void hdcp_update_display(struct hdcp_workqueue *hdcp_work, psp_set_srm(hdcp_work->hdcp.config.psp.handle, hdcp_work->srm, hdcp_work->srm_size, &hdcp_work->srm_version); - display->adjust.disable = 0; + display->adjust.disable = MOD_HDCP_DISPLAY_NOT_DISABLE; if (content_type == DRM_MODE_HDCP_CONTENT_TYPE0) { hdcp_w->link.adjust.hdcp1.disable = 0; hdcp_w->link.adjust.hdcp2.force_type = MOD_HDCP_FORCE_TYPE_0; @@ -203,7 +203,7 @@ void hdcp_update_display(struct hdcp_workqueue *hdcp_work, schedule_delayed_work(&hdcp_w->property_validate_dwork, msecs_to_jiffies(DRM_HDCP_CHECK_PERIOD_MS)); } else { - display->adjust.disable = 1; + display->adjust.disable = MOD_HDCP_DISPLAY_DISABLE_AUTHENTICATION; hdcp_w->encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF; cancel_delayed_work(&hdcp_w->property_validate_dwork); } @@ -456,7 +456,7 @@ static void update_config(void *handle, struct cp_psp_stream_config *config) link->dp.rev = aconnector->dc_link->dpcd_caps.dpcd_rev.raw; link->dp.assr_enabled = config->assr_enabled; link->dp.mst_enabled = config->mst_enabled; - display->adjust.disable = 1; + display->adjust.disable = MOD_HDCP_DISPLAY_DISABLE_AUTHENTICATION; link->adjust.auth_delay = 3; link->adjust.hdcp1.disable = 0; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c index 09bdffb3a09e..103e29905b57 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -700,6 +700,14 @@ void dm_helpers_free_gpu_mem( bool dm_helpers_dmub_outbox0_interrupt_control(struct dc_context *ctx, bool enable) { - // TODO - return true; + enum dc_irq_source irq_source; + bool ret; + + irq_source = DC_IRQ_SOURCE_DMCUB_OUTBOX0; + + ret = dc_interrupt_set(ctx->dc, irq_source, enable); + + DRM_DEBUG_DRIVER("Dmub trace irq %sabling: r=%d\n", + enable ? "en" : "dis", ret); + return ret; } 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 d3c687d07ee6..b3ed7e777720 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 @@ -73,6 +73,7 @@ * @handler_arg: Argument passed to the handler when triggered * @dm: DM which this handler belongs to * @irq_source: DC interrupt source that this handler is registered for + * @work: work struct */ struct amdgpu_dm_irq_handler_data { struct list_head list; @@ -184,6 +185,55 @@ static struct list_head *remove_irq_handler(struct amdgpu_device *adev, return hnd_list; } +/** + * unregister_all_irq_handlers() - Cleans up handlers from the DM IRQ table + * @adev: The base driver device containing the DM device + * + * Go through low and high context IRQ tables and deallocate handlers. + */ +static void unregister_all_irq_handlers(struct amdgpu_device *adev) +{ + struct list_head *hnd_list_low; + struct list_head *hnd_list_high; + struct list_head *entry, *tmp; + struct amdgpu_dm_irq_handler_data *handler; + unsigned long irq_table_flags; + int i; + + DM_IRQ_TABLE_LOCK(adev, irq_table_flags); + + for (i = 0; i < DAL_IRQ_SOURCES_NUMBER; i++) { + hnd_list_low = &adev->dm.irq_handler_list_low_tab[i]; + hnd_list_high = &adev->dm.irq_handler_list_high_tab[i]; + + list_for_each_safe(entry, tmp, hnd_list_low) { + + handler = list_entry(entry, struct amdgpu_dm_irq_handler_data, + list); + + if (handler == NULL || handler->handler == NULL) + continue; + + list_del(&handler->list); + kfree(handler); + } + + list_for_each_safe(entry, tmp, hnd_list_high) { + + handler = list_entry(entry, struct amdgpu_dm_irq_handler_data, + list); + + if (handler == NULL || handler->handler == NULL) + continue; + + list_del(&handler->list); + kfree(handler); + } + } + + DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags); +} + static bool validate_irq_registration_params(struct dc_interrupt_params *int_params, void (*ih)(void *)) @@ -414,6 +464,8 @@ void amdgpu_dm_irq_fini(struct amdgpu_device *adev) } } } + /* Deallocate handlers from the table. */ + unregister_all_irq_handlers(adev); } int amdgpu_dm_irq_suspend(struct amdgpu_device *adev) @@ -731,6 +783,18 @@ static int amdgpu_dm_set_vupdate_irq_state(struct amdgpu_device *adev, __func__); } +static int amdgpu_dm_set_dmub_trace_irq_state(struct amdgpu_device *adev, + struct amdgpu_irq_src *source, + unsigned int type, + enum amdgpu_interrupt_state state) +{ + enum dc_irq_source irq_source = DC_IRQ_SOURCE_DMCUB_OUTBOX0; + bool st = (state == AMDGPU_IRQ_STATE_ENABLE); + + dc_interrupt_set(adev->dm.dc, irq_source, st); + return 0; +} + static const struct amdgpu_irq_src_funcs dm_crtc_irq_funcs = { .set = amdgpu_dm_set_crtc_irq_state, .process = amdgpu_dm_irq_handler, @@ -746,6 +810,11 @@ static const struct amdgpu_irq_src_funcs dm_vupdate_irq_funcs = { .process = amdgpu_dm_irq_handler, }; +static const struct amdgpu_irq_src_funcs dm_dmub_trace_irq_funcs = { + .set = amdgpu_dm_set_dmub_trace_irq_state, + .process = amdgpu_dm_irq_handler, +}; + static const struct amdgpu_irq_src_funcs dm_pageflip_irq_funcs = { .set = amdgpu_dm_set_pflip_irq_state, .process = amdgpu_dm_irq_handler, @@ -768,6 +837,9 @@ void amdgpu_dm_set_irq_funcs(struct amdgpu_device *adev) adev->vupdate_irq.num_types = adev->mode_info.num_crtc; adev->vupdate_irq.funcs = &dm_vupdate_irq_funcs; + adev->dmub_trace_irq.num_types = 1; + adev->dmub_trace_irq.funcs = &dm_dmub_trace_irq_funcs; + adev->pageflip_irq.num_types = adev->mode_info.num_crtc; adev->pageflip_irq.funcs = &dm_pageflip_irq_funcs; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c index 607ec0999445..eba270121698 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c @@ -32,15 +32,12 @@ #include "amdgpu_dm_irq.h" #include "amdgpu_pm.h" #include "dm_pp_smu.h" -#include "amdgpu_smu.h" - bool dm_pp_apply_display_requirements( const struct dc_context *ctx, const struct dm_pp_display_configuration *pp_display_cfg) { struct amdgpu_device *adev = ctx->driver_context; - struct smu_context *smu = &adev->smu; int i; if (adev->pm.dpm_enabled) { @@ -106,9 +103,6 @@ bool dm_pp_apply_display_requirements( adev->powerplay.pp_funcs->display_configuration_change( adev->powerplay.pp_handle, &adev->pm.pm_display_cfg); - else if (adev->smu.ppt_funcs) - smu_display_configuration_change(smu, - &adev->pm.pm_display_cfg); amdgpu_pm_compute_clocks(adev); } @@ -148,36 +142,6 @@ static void get_default_clock_levels( } } -static enum smu_clk_type dc_to_smu_clock_type( - enum dm_pp_clock_type dm_pp_clk_type) -{ - enum smu_clk_type smu_clk_type = SMU_CLK_COUNT; - - switch (dm_pp_clk_type) { - case DM_PP_CLOCK_TYPE_DISPLAY_CLK: - smu_clk_type = SMU_DISPCLK; - break; - case DM_PP_CLOCK_TYPE_ENGINE_CLK: - smu_clk_type = SMU_GFXCLK; - break; - case DM_PP_CLOCK_TYPE_MEMORY_CLK: - smu_clk_type = SMU_MCLK; - break; - case DM_PP_CLOCK_TYPE_DCEFCLK: - smu_clk_type = SMU_DCEFCLK; - break; - case DM_PP_CLOCK_TYPE_SOCCLK: - smu_clk_type = SMU_SOCCLK; - break; - default: - DRM_ERROR("DM_PPLIB: invalid clock type: %d!\n", - dm_pp_clk_type); - break; - } - - return smu_clk_type; -} - static enum amd_pp_clock_type dc_to_pp_clock_type( enum dm_pp_clock_type dm_pp_clk_type) { @@ -417,14 +381,8 @@ bool dm_pp_get_clock_levels_by_type_with_latency( &pp_clks); if (ret) return false; - } else if (adev->smu.ppt_funcs && adev->smu.ppt_funcs->get_clock_by_type_with_latency) { - if (smu_get_clock_by_type_with_latency(&adev->smu, - dc_to_smu_clock_type(clk_type), - &pp_clks)) - return false; } - pp_to_dc_clock_levels_with_latency(&pp_clks, clk_level_info, clk_type); return true; @@ -502,10 +460,6 @@ bool dm_pp_apply_clock_for_voltage_request( ret = adev->powerplay.pp_funcs->display_clock_voltage_request( adev->powerplay.pp_handle, &pp_clock_request); - else if (adev->smu.ppt_funcs && - adev->smu.ppt_funcs->display_clock_voltage_request) - ret = smu_display_clock_voltage_request(&adev->smu, - &pp_clock_request); if (ret) return false; return true; @@ -655,8 +609,11 @@ static enum pp_smu_status pp_nv_set_wm_ranges(struct pp_smu *pp, { const struct dc_context *ctx = pp->dm; struct amdgpu_device *adev = ctx->driver_context; + void *pp_handle = adev->powerplay.pp_handle; + const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; - smu_set_watermarks_for_clock_ranges(&adev->smu, ranges); + if (pp_funcs && pp_funcs->set_watermarks_for_clocks_ranges) + pp_funcs->set_watermarks_for_clocks_ranges(pp_handle, ranges); return PP_SMU_RESULT_OK; } @@ -665,13 +622,14 @@ static enum pp_smu_status pp_nv_set_display_count(struct pp_smu *pp, int count) { const struct dc_context *ctx = pp->dm; struct amdgpu_device *adev = ctx->driver_context; - struct smu_context *smu = &adev->smu; + void *pp_handle = adev->powerplay.pp_handle; + const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; - if (!smu->ppt_funcs) + if (!pp_funcs || !pp_funcs->set_active_display_count) return PP_SMU_RESULT_UNSUPPORTED; /* 0: successful or smu.ppt_funcs->set_display_count = NULL; 1: fail */ - if (smu_set_display_count(smu, count)) + if (pp_funcs->set_active_display_count(pp_handle, count)) return PP_SMU_RESULT_FAIL; return PP_SMU_RESULT_OK; @@ -682,13 +640,14 @@ pp_nv_set_min_deep_sleep_dcfclk(struct pp_smu *pp, int mhz) { const struct dc_context *ctx = pp->dm; struct amdgpu_device *adev = ctx->driver_context; - struct smu_context *smu = &adev->smu; + void *pp_handle = adev->powerplay.pp_handle; + const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; - if (!smu->ppt_funcs) + if (!pp_funcs || !pp_funcs->set_min_deep_sleep_dcefclk) return PP_SMU_RESULT_UNSUPPORTED; /* 0: successful or smu.ppt_funcs->set_deep_sleep_dcefclk = NULL;1: fail */ - if (smu_set_deep_sleep_dcefclk(smu, mhz)) + if (pp_funcs->set_min_deep_sleep_dcefclk(pp_handle, mhz)) return PP_SMU_RESULT_FAIL; return PP_SMU_RESULT_OK; @@ -699,10 +658,11 @@ static enum pp_smu_status pp_nv_set_hard_min_dcefclk_by_freq( { const struct dc_context *ctx = pp->dm; struct amdgpu_device *adev = ctx->driver_context; - struct smu_context *smu = &adev->smu; + void *pp_handle = adev->powerplay.pp_handle; + const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; struct pp_display_clock_request clock_req; - if (!smu->ppt_funcs) + if (!pp_funcs || !pp_funcs->display_clock_voltage_request) return PP_SMU_RESULT_UNSUPPORTED; clock_req.clock_type = amd_pp_dcef_clock; @@ -711,7 +671,7 @@ static enum pp_smu_status pp_nv_set_hard_min_dcefclk_by_freq( /* 0: successful or smu.ppt_funcs->display_clock_voltage_request = NULL * 1: fail */ - if (smu_display_clock_voltage_request(smu, &clock_req)) + if (pp_funcs->display_clock_voltage_request(pp_handle, &clock_req)) return PP_SMU_RESULT_FAIL; return PP_SMU_RESULT_OK; @@ -722,10 +682,11 @@ pp_nv_set_hard_min_uclk_by_freq(struct pp_smu *pp, int mhz) { const struct dc_context *ctx = pp->dm; struct amdgpu_device *adev = ctx->driver_context; - struct smu_context *smu = &adev->smu; + void *pp_handle = adev->powerplay.pp_handle; + const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; struct pp_display_clock_request clock_req; - if (!smu->ppt_funcs) + if (!pp_funcs || !pp_funcs->display_clock_voltage_request) return PP_SMU_RESULT_UNSUPPORTED; clock_req.clock_type = amd_pp_mem_clock; @@ -734,7 +695,7 @@ pp_nv_set_hard_min_uclk_by_freq(struct pp_smu *pp, int mhz) /* 0: successful or smu.ppt_funcs->display_clock_voltage_request = NULL * 1: fail */ - if (smu_display_clock_voltage_request(smu, &clock_req)) + if (pp_funcs->display_clock_voltage_request(pp_handle, &clock_req)) return PP_SMU_RESULT_FAIL; return PP_SMU_RESULT_OK; @@ -745,10 +706,14 @@ static enum pp_smu_status pp_nv_set_pstate_handshake_support( { const struct dc_context *ctx = pp->dm; struct amdgpu_device *adev = ctx->driver_context; - struct smu_context *smu = &adev->smu; + void *pp_handle = adev->powerplay.pp_handle; + const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; - if (smu_display_disable_memory_clock_switch(smu, !pstate_handshake_supported)) - return PP_SMU_RESULT_FAIL; + if (pp_funcs && pp_funcs->display_disable_memory_clock_switch) { + if (pp_funcs->display_disable_memory_clock_switch(pp_handle, + !pstate_handshake_supported)) + return PP_SMU_RESULT_FAIL; + } return PP_SMU_RESULT_OK; } @@ -758,10 +723,11 @@ static enum pp_smu_status pp_nv_set_voltage_by_freq(struct pp_smu *pp, { const struct dc_context *ctx = pp->dm; struct amdgpu_device *adev = ctx->driver_context; - struct smu_context *smu = &adev->smu; + void *pp_handle = adev->powerplay.pp_handle; + const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; struct pp_display_clock_request clock_req; - if (!smu->ppt_funcs) + if (!pp_funcs || !pp_funcs->display_clock_voltage_request) return PP_SMU_RESULT_UNSUPPORTED; switch (clock_id) { @@ -782,7 +748,7 @@ static enum pp_smu_status pp_nv_set_voltage_by_freq(struct pp_smu *pp, /* 0: successful or smu.ppt_funcs->display_clock_voltage_request = NULL * 1: fail */ - if (smu_display_clock_voltage_request(smu, &clock_req)) + if (pp_funcs->display_clock_voltage_request(pp_handle, &clock_req)) return PP_SMU_RESULT_FAIL; return PP_SMU_RESULT_OK; @@ -793,15 +759,13 @@ static enum pp_smu_status pp_nv_get_maximum_sustainable_clocks( { const struct dc_context *ctx = pp->dm; struct amdgpu_device *adev = ctx->driver_context; - struct smu_context *smu = &adev->smu; - - if (!smu->ppt_funcs) - return PP_SMU_RESULT_UNSUPPORTED; + void *pp_handle = adev->powerplay.pp_handle; + const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; - if (!smu->ppt_funcs->get_max_sustainable_clocks_by_dc) + if (!pp_funcs || !pp_funcs->get_max_sustainable_clocks_by_dc) return PP_SMU_RESULT_UNSUPPORTED; - if (!smu_get_max_sustainable_clocks_by_dc(smu, max_clocks)) + if (!pp_funcs->get_max_sustainable_clocks_by_dc(pp_handle, max_clocks)) return PP_SMU_RESULT_OK; return PP_SMU_RESULT_FAIL; @@ -812,16 +776,15 @@ static enum pp_smu_status pp_nv_get_uclk_dpm_states(struct pp_smu *pp, { const struct dc_context *ctx = pp->dm; struct amdgpu_device *adev = ctx->driver_context; - struct smu_context *smu = &adev->smu; - - if (!smu->ppt_funcs) - return PP_SMU_RESULT_UNSUPPORTED; + void *pp_handle = adev->powerplay.pp_handle; + const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; - if (!smu->ppt_funcs->get_uclk_dpm_states) + if (!pp_funcs || !pp_funcs->get_uclk_dpm_states) return PP_SMU_RESULT_UNSUPPORTED; - if (!smu_get_uclk_dpm_states(smu, - clock_values_in_khz, num_states)) + if (!pp_funcs->get_uclk_dpm_states(pp_handle, + clock_values_in_khz, + num_states)) return PP_SMU_RESULT_OK; return PP_SMU_RESULT_FAIL; @@ -832,15 +795,13 @@ static enum pp_smu_status pp_rn_get_dpm_clock_table( { const struct dc_context *ctx = pp->dm; struct amdgpu_device *adev = ctx->driver_context; - struct smu_context *smu = &adev->smu; - - if (!smu->ppt_funcs) - return PP_SMU_RESULT_UNSUPPORTED; + void *pp_handle = adev->powerplay.pp_handle; + const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; - if (!smu->ppt_funcs->get_dpm_clock_table) + if (!pp_funcs || !pp_funcs->get_dpm_clock_table) return PP_SMU_RESULT_UNSUPPORTED; - if (!smu_get_dpm_clock_table(smu, clock_table)) + if (!pp_funcs->get_dpm_clock_table(pp_handle, clock_table)) return PP_SMU_RESULT_OK; return PP_SMU_RESULT_FAIL; @@ -851,8 +812,11 @@ static enum pp_smu_status pp_rn_set_wm_ranges(struct pp_smu *pp, { const struct dc_context *ctx = pp->dm; struct amdgpu_device *adev = ctx->driver_context; + void *pp_handle = adev->powerplay.pp_handle; + const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; - smu_set_watermarks_for_clock_ranges(&adev->smu, ranges); + if (pp_funcs && pp_funcs->set_watermarks_for_clocks_ranges) + pp_funcs->set_watermarks_for_clocks_ranges(pp_handle, ranges); return PP_SMU_RESULT_OK; } diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h index 86960476823c..46a33f64cf8e 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h @@ -597,6 +597,46 @@ TRACE_EVENT(amdgpu_dm_dce_clocks_state, ) ); +TRACE_EVENT(amdgpu_dmub_trace_high_irq, + TP_PROTO(uint32_t trace_code, uint32_t tick_count, uint32_t param0, + uint32_t param1), + TP_ARGS(trace_code, tick_count, param0, param1), + TP_STRUCT__entry( + __field(uint32_t, trace_code) + __field(uint32_t, tick_count) + __field(uint32_t, param0) + __field(uint32_t, param1) + ), + TP_fast_assign( + __entry->trace_code = trace_code; + __entry->tick_count = tick_count; + __entry->param0 = param0; + __entry->param1 = param1; + ), + TP_printk("trace_code=%u tick_count=%u param0=%u param1=%u", + __entry->trace_code, __entry->tick_count, + __entry->param0, __entry->param1) +); + +TRACE_EVENT(amdgpu_refresh_rate_track, + TP_PROTO(int crtc_index, ktime_t refresh_rate_ns, uint32_t refresh_rate_hz), + TP_ARGS(crtc_index, refresh_rate_ns, refresh_rate_hz), + TP_STRUCT__entry( + __field(int, crtc_index) + __field(ktime_t, refresh_rate_ns) + __field(uint32_t, refresh_rate_hz) + ), + TP_fast_assign( + __entry->crtc_index = crtc_index; + __entry->refresh_rate_ns = refresh_rate_ns; + __entry->refresh_rate_hz = refresh_rate_hz; + ), + TP_printk("crtc_index=%d refresh_rate=%dHz (%lld)", + __entry->crtc_index, + __entry->refresh_rate_hz, + __entry->refresh_rate_ns) +); + #endif /* _AMDGPU_DM_TRACE_H_ */ #undef TRACE_INCLUDE_PATH diff --git a/drivers/gpu/drm/amd/display/dc/Makefile b/drivers/gpu/drm/amd/display/dc/Makefile index bbde6e6a4e43..f33847299bca 100644 --- a/drivers/gpu/drm/amd/display/dc/Makefile +++ b/drivers/gpu/drm/amd/display/dc/Makefile @@ -54,8 +54,9 @@ AMD_DC = $(addsuffix /Makefile, $(addprefix $(FULL_AMD_DISPLAY_PATH)/dc/,$(DC_LI include $(AMD_DC) -DISPLAY_CORE = dc.o dc_stat.o dc_link.o dc_resource.o dc_hw_sequencer.o dc_sink.o \ -dc_surface.o dc_link_hwss.o dc_link_dp.o dc_link_ddc.o dc_debug.o dc_stream.o +DISPLAY_CORE = dc.o dc_link.o dc_resource.o dc_hw_sequencer.o dc_sink.o \ +dc_surface.o dc_link_hwss.o dc_link_dp.o dc_link_ddc.o dc_debug.o dc_stream.o \ +dc_link_enc_cfg.o ifdef CONFIG_DRM_AMD_DC_DCN DISPLAY_CORE += dc_vm_helper.o diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c index b208f06ed514..d79f4fe06c47 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c @@ -916,6 +916,192 @@ static enum bp_result bios_parser_get_soc_bb_info( return result; } +static enum bp_result get_disp_caps_v4_1( + struct bios_parser *bp, + uint8_t *dce_caps) +{ + enum bp_result result = BP_RESULT_OK; + struct atom_display_controller_info_v4_1 *disp_cntl_tbl = NULL; + + if (!dce_caps) + return BP_RESULT_BADINPUT; + + if (!DATA_TABLES(dce_info)) + return BP_RESULT_BADBIOSTABLE; + + disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_1, + DATA_TABLES(dce_info)); + + if (!disp_cntl_tbl) + return BP_RESULT_BADBIOSTABLE; + + *dce_caps = disp_cntl_tbl->display_caps; + + return result; +} + +static enum bp_result get_disp_caps_v4_2( + struct bios_parser *bp, + uint8_t *dce_caps) +{ + enum bp_result result = BP_RESULT_OK; + struct atom_display_controller_info_v4_2 *disp_cntl_tbl = NULL; + + if (!dce_caps) + return BP_RESULT_BADINPUT; + + if (!DATA_TABLES(dce_info)) + return BP_RESULT_BADBIOSTABLE; + + disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_2, + DATA_TABLES(dce_info)); + + if (!disp_cntl_tbl) + return BP_RESULT_BADBIOSTABLE; + + *dce_caps = disp_cntl_tbl->display_caps; + + return result; +} + +static enum bp_result get_disp_caps_v4_3( + struct bios_parser *bp, + uint8_t *dce_caps) +{ + enum bp_result result = BP_RESULT_OK; + struct atom_display_controller_info_v4_3 *disp_cntl_tbl = NULL; + + if (!dce_caps) + return BP_RESULT_BADINPUT; + + if (!DATA_TABLES(dce_info)) + return BP_RESULT_BADBIOSTABLE; + + disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_3, + DATA_TABLES(dce_info)); + + if (!disp_cntl_tbl) + return BP_RESULT_BADBIOSTABLE; + + *dce_caps = disp_cntl_tbl->display_caps; + + return result; +} + +static enum bp_result get_disp_caps_v4_4( + struct bios_parser *bp, + uint8_t *dce_caps) +{ + enum bp_result result = BP_RESULT_OK; + struct atom_display_controller_info_v4_4 *disp_cntl_tbl = NULL; + + if (!dce_caps) + return BP_RESULT_BADINPUT; + + if (!DATA_TABLES(dce_info)) + return BP_RESULT_BADBIOSTABLE; + + disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_4, + DATA_TABLES(dce_info)); + + if (!disp_cntl_tbl) + return BP_RESULT_BADBIOSTABLE; + + *dce_caps = disp_cntl_tbl->display_caps; + + return result; +} + +static enum bp_result bios_parser_get_lttpr_interop( + struct dc_bios *dcb, + uint8_t *dce_caps) +{ + struct bios_parser *bp = BP_FROM_DCB(dcb); + enum bp_result result = BP_RESULT_UNSUPPORTED; + struct atom_common_table_header *header; + struct atom_data_revision tbl_revision; + + if (!DATA_TABLES(dce_info)) + return BP_RESULT_UNSUPPORTED; + + header = GET_IMAGE(struct atom_common_table_header, + DATA_TABLES(dce_info)); + get_atom_data_table_revision(header, &tbl_revision); + switch (tbl_revision.major) { + case 4: + switch (tbl_revision.minor) { + case 1: + result = get_disp_caps_v4_1(bp, dce_caps); + *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE); + break; + case 2: + result = get_disp_caps_v4_2(bp, dce_caps); + *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE); + break; + case 3: + result = get_disp_caps_v4_3(bp, dce_caps); + *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE); + break; + case 4: + result = get_disp_caps_v4_4(bp, dce_caps); + *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE); + break; + default: + break; + } + break; + default: + break; + } + + return result; +} + +static enum bp_result bios_parser_get_lttpr_caps( + struct dc_bios *dcb, + uint8_t *dce_caps) +{ + struct bios_parser *bp = BP_FROM_DCB(dcb); + enum bp_result result = BP_RESULT_UNSUPPORTED; + struct atom_common_table_header *header; + struct atom_data_revision tbl_revision; + + if (!DATA_TABLES(dce_info)) + return BP_RESULT_UNSUPPORTED; + + header = GET_IMAGE(struct atom_common_table_header, + DATA_TABLES(dce_info)); + get_atom_data_table_revision(header, &tbl_revision); + switch (tbl_revision.major) { + case 4: + switch (tbl_revision.minor) { + case 1: + result = get_disp_caps_v4_1(bp, dce_caps); + *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE); + break; + case 2: + result = get_disp_caps_v4_2(bp, dce_caps); + *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE); + break; + case 3: + result = get_disp_caps_v4_3(bp, dce_caps); + *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE); + break; + case 4: + result = get_disp_caps_v4_4(bp, dce_caps); + *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE); + break; + default: + break; + } + break; + default: + break; + } + + return result; +} + static enum bp_result get_embedded_panel_info_v2_1( struct bios_parser *bp, struct embedded_panel_info *info) @@ -2531,6 +2717,10 @@ static const struct dc_vbios_funcs vbios_funcs = { .get_soc_bb_info = bios_parser_get_soc_bb_info, .get_disp_connector_caps_info = bios_parser_get_disp_connector_caps_info, + + .get_lttpr_caps = bios_parser_get_lttpr_caps, + + .get_lttpr_interop = bios_parser_get_lttpr_interop, }; static bool bios_parser2_construct( diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c index e633f8a51edb..1244fcb0f446 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c @@ -98,16 +98,16 @@ static void calculate_bandwidth( int32_t num_cursor_lines; int32_t i, j, k; - struct bw_fixed yclk[3]; - struct bw_fixed sclk[8]; + struct bw_fixed *yclk; + struct bw_fixed *sclk; bool d0_underlay_enable; bool d1_underlay_enable; bool fbc_enabled; bool lpt_enabled; enum bw_defines sclk_message; enum bw_defines yclk_message; - enum bw_defines tiling_mode[maximum_number_of_surfaces]; - enum bw_defines surface_type[maximum_number_of_surfaces]; + enum bw_defines *tiling_mode; + enum bw_defines *surface_type; enum bw_defines voltage; enum bw_defines pipe_check; enum bw_defines hsr_check; @@ -122,6 +122,22 @@ static void calculate_bandwidth( int32_t number_of_displays_enabled_with_margin = 0; int32_t number_of_aligned_displays_with_no_margin = 0; + yclk = kcalloc(3, sizeof(*yclk), GFP_KERNEL); + if (!yclk) + return; + + sclk = kcalloc(8, sizeof(*sclk), GFP_KERNEL); + if (!sclk) + goto free_yclk; + + tiling_mode = kcalloc(maximum_number_of_surfaces, sizeof(*tiling_mode), GFP_KERNEL); + if (!tiling_mode) + goto free_sclk; + + surface_type = kcalloc(maximum_number_of_surfaces, sizeof(*surface_type), GFP_KERNEL); + if (!surface_type) + goto free_tiling_mode; + yclk[low] = vbios->low_yclk; yclk[mid] = vbios->mid_yclk; yclk[high] = vbios->high_yclk; @@ -2013,6 +2029,14 @@ static void calculate_bandwidth( } } } + + kfree(surface_type); +free_tiling_mode: + kfree(tiling_mode); +free_yclk: + kfree(yclk); +free_sclk: + kfree(sclk); } /******************************************************************************* @@ -2022,707 +2046,719 @@ void bw_calcs_init(struct bw_calcs_dceip *bw_dceip, struct bw_calcs_vbios *bw_vbios, struct hw_asic_id asic_id) { - struct bw_calcs_dceip dceip = { 0 }; - struct bw_calcs_vbios vbios = { 0 }; + struct bw_calcs_dceip *dceip; + struct bw_calcs_vbios *vbios; enum bw_calcs_version version = bw_calcs_version_from_asic_id(asic_id); - dceip.version = version; + dceip = kzalloc(sizeof(*dceip), GFP_KERNEL); + if (!dceip) + return; + + vbios = kzalloc(sizeof(*vbios), GFP_KERNEL); + if (!vbios) { + kfree(dceip); + return; + } + + dceip->version = version; switch (version) { case BW_CALCS_VERSION_CARRIZO: - vbios.memory_type = bw_def_gddr5; - vbios.dram_channel_width_in_bits = 64; - vbios.number_of_dram_channels = asic_id.vram_width / vbios.dram_channel_width_in_bits; - vbios.number_of_dram_banks = 8; - vbios.high_yclk = bw_int_to_fixed(1600); - vbios.mid_yclk = bw_int_to_fixed(1600); - vbios.low_yclk = bw_frc_to_fixed(66666, 100); - vbios.low_sclk = bw_int_to_fixed(200); - vbios.mid1_sclk = bw_int_to_fixed(300); - vbios.mid2_sclk = bw_int_to_fixed(300); - vbios.mid3_sclk = bw_int_to_fixed(300); - vbios.mid4_sclk = bw_int_to_fixed(300); - vbios.mid5_sclk = bw_int_to_fixed(300); - vbios.mid6_sclk = bw_int_to_fixed(300); - vbios.high_sclk = bw_frc_to_fixed(62609, 100); - vbios.low_voltage_max_dispclk = bw_int_to_fixed(352); - vbios.mid_voltage_max_dispclk = bw_int_to_fixed(467); - vbios.high_voltage_max_dispclk = bw_int_to_fixed(643); - vbios.low_voltage_max_phyclk = bw_int_to_fixed(540); - vbios.mid_voltage_max_phyclk = bw_int_to_fixed(810); - vbios.high_voltage_max_phyclk = bw_int_to_fixed(810); - vbios.data_return_bus_width = bw_int_to_fixed(32); - vbios.trc = bw_int_to_fixed(50); - vbios.dmifmc_urgent_latency = bw_int_to_fixed(4); - vbios.stutter_self_refresh_exit_latency = bw_frc_to_fixed(153, 10); - vbios.stutter_self_refresh_entry_latency = bw_int_to_fixed(0); - vbios.nbp_state_change_latency = bw_frc_to_fixed(19649, 1000); - vbios.mcifwrmc_urgent_latency = bw_int_to_fixed(10); - vbios.scatter_gather_enable = true; - vbios.down_spread_percentage = bw_frc_to_fixed(5, 10); - vbios.cursor_width = 32; - vbios.average_compression_rate = 4; - vbios.number_of_request_slots_gmc_reserves_for_dmif_per_channel = 256; - vbios.blackout_duration = bw_int_to_fixed(0); /* us */ - vbios.maximum_blackout_recovery_time = bw_int_to_fixed(0); - - dceip.max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation = 100; - dceip.max_average_percent_of_ideal_drambw_display_can_use_in_normal_system_operation = 100; - dceip.percent_of_ideal_port_bw_received_after_urgent_latency = 100; - dceip.large_cursor = false; - dceip.dmif_request_buffer_size = bw_int_to_fixed(768); - dceip.dmif_pipe_en_fbc_chunk_tracker = false; - dceip.cursor_max_outstanding_group_num = 1; - dceip.lines_interleaved_into_lb = 2; - dceip.chunk_width = 256; - dceip.number_of_graphics_pipes = 3; - dceip.number_of_underlay_pipes = 1; - dceip.low_power_tiling_mode = 0; - dceip.display_write_back_supported = false; - dceip.argb_compression_support = false; - dceip.underlay_vscaler_efficiency6_bit_per_component = + vbios->memory_type = bw_def_gddr5; + vbios->dram_channel_width_in_bits = 64; + vbios->number_of_dram_channels = asic_id.vram_width / vbios->dram_channel_width_in_bits; + vbios->number_of_dram_banks = 8; + vbios->high_yclk = bw_int_to_fixed(1600); + vbios->mid_yclk = bw_int_to_fixed(1600); + vbios->low_yclk = bw_frc_to_fixed(66666, 100); + vbios->low_sclk = bw_int_to_fixed(200); + vbios->mid1_sclk = bw_int_to_fixed(300); + vbios->mid2_sclk = bw_int_to_fixed(300); + vbios->mid3_sclk = bw_int_to_fixed(300); + vbios->mid4_sclk = bw_int_to_fixed(300); + vbios->mid5_sclk = bw_int_to_fixed(300); + vbios->mid6_sclk = bw_int_to_fixed(300); + vbios->high_sclk = bw_frc_to_fixed(62609, 100); + vbios->low_voltage_max_dispclk = bw_int_to_fixed(352); + vbios->mid_voltage_max_dispclk = bw_int_to_fixed(467); + vbios->high_voltage_max_dispclk = bw_int_to_fixed(643); + vbios->low_voltage_max_phyclk = bw_int_to_fixed(540); + vbios->mid_voltage_max_phyclk = bw_int_to_fixed(810); + vbios->high_voltage_max_phyclk = bw_int_to_fixed(810); + vbios->data_return_bus_width = bw_int_to_fixed(32); + vbios->trc = bw_int_to_fixed(50); + vbios->dmifmc_urgent_latency = bw_int_to_fixed(4); + vbios->stutter_self_refresh_exit_latency = bw_frc_to_fixed(153, 10); + vbios->stutter_self_refresh_entry_latency = bw_int_to_fixed(0); + vbios->nbp_state_change_latency = bw_frc_to_fixed(19649, 1000); + vbios->mcifwrmc_urgent_latency = bw_int_to_fixed(10); + vbios->scatter_gather_enable = true; + vbios->down_spread_percentage = bw_frc_to_fixed(5, 10); + vbios->cursor_width = 32; + vbios->average_compression_rate = 4; + vbios->number_of_request_slots_gmc_reserves_for_dmif_per_channel = 256; + vbios->blackout_duration = bw_int_to_fixed(0); /* us */ + vbios->maximum_blackout_recovery_time = bw_int_to_fixed(0); + + dceip->max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation = 100; + dceip->max_average_percent_of_ideal_drambw_display_can_use_in_normal_system_operation = 100; + dceip->percent_of_ideal_port_bw_received_after_urgent_latency = 100; + dceip->large_cursor = false; + dceip->dmif_request_buffer_size = bw_int_to_fixed(768); + dceip->dmif_pipe_en_fbc_chunk_tracker = false; + dceip->cursor_max_outstanding_group_num = 1; + dceip->lines_interleaved_into_lb = 2; + dceip->chunk_width = 256; + dceip->number_of_graphics_pipes = 3; + dceip->number_of_underlay_pipes = 1; + dceip->low_power_tiling_mode = 0; + dceip->display_write_back_supported = false; + dceip->argb_compression_support = false; + dceip->underlay_vscaler_efficiency6_bit_per_component = bw_frc_to_fixed(35556, 10000); - dceip.underlay_vscaler_efficiency8_bit_per_component = + dceip->underlay_vscaler_efficiency8_bit_per_component = bw_frc_to_fixed(34286, 10000); - dceip.underlay_vscaler_efficiency10_bit_per_component = + dceip->underlay_vscaler_efficiency10_bit_per_component = bw_frc_to_fixed(32, 10); - dceip.underlay_vscaler_efficiency12_bit_per_component = + dceip->underlay_vscaler_efficiency12_bit_per_component = bw_int_to_fixed(3); - dceip.graphics_vscaler_efficiency6_bit_per_component = + dceip->graphics_vscaler_efficiency6_bit_per_component = bw_frc_to_fixed(35, 10); - dceip.graphics_vscaler_efficiency8_bit_per_component = + dceip->graphics_vscaler_efficiency8_bit_per_component = bw_frc_to_fixed(34286, 10000); - dceip.graphics_vscaler_efficiency10_bit_per_component = + dceip->graphics_vscaler_efficiency10_bit_per_component = bw_frc_to_fixed(32, 10); - dceip.graphics_vscaler_efficiency12_bit_per_component = + dceip->graphics_vscaler_efficiency12_bit_per_component = bw_int_to_fixed(3); - dceip.alpha_vscaler_efficiency = bw_int_to_fixed(3); - dceip.max_dmif_buffer_allocated = 2; - dceip.graphics_dmif_size = 12288; - dceip.underlay_luma_dmif_size = 19456; - dceip.underlay_chroma_dmif_size = 23552; - dceip.pre_downscaler_enabled = true; - dceip.underlay_downscale_prefetch_enabled = true; - dceip.lb_write_pixels_per_dispclk = bw_int_to_fixed(1); - dceip.lb_size_per_component444 = bw_int_to_fixed(82176); - dceip.graphics_lb_nodownscaling_multi_line_prefetching = false; - dceip.stutter_and_dram_clock_state_change_gated_before_cursor = + dceip->alpha_vscaler_efficiency = bw_int_to_fixed(3); + dceip->max_dmif_buffer_allocated = 2; + dceip->graphics_dmif_size = 12288; + dceip->underlay_luma_dmif_size = 19456; + dceip->underlay_chroma_dmif_size = 23552; + dceip->pre_downscaler_enabled = true; + dceip->underlay_downscale_prefetch_enabled = true; + dceip->lb_write_pixels_per_dispclk = bw_int_to_fixed(1); + dceip->lb_size_per_component444 = bw_int_to_fixed(82176); + dceip->graphics_lb_nodownscaling_multi_line_prefetching = false; + dceip->stutter_and_dram_clock_state_change_gated_before_cursor = bw_int_to_fixed(0); - dceip.underlay420_luma_lb_size_per_component = bw_int_to_fixed( + dceip->underlay420_luma_lb_size_per_component = bw_int_to_fixed( 82176); - dceip.underlay420_chroma_lb_size_per_component = + dceip->underlay420_chroma_lb_size_per_component = bw_int_to_fixed(164352); - dceip.underlay422_lb_size_per_component = bw_int_to_fixed( + dceip->underlay422_lb_size_per_component = bw_int_to_fixed( 82176); - dceip.cursor_chunk_width = bw_int_to_fixed(64); - dceip.cursor_dcp_buffer_lines = bw_int_to_fixed(4); - dceip.underlay_maximum_width_efficient_for_tiling = + dceip->cursor_chunk_width = bw_int_to_fixed(64); + dceip->cursor_dcp_buffer_lines = bw_int_to_fixed(4); + dceip->underlay_maximum_width_efficient_for_tiling = bw_int_to_fixed(1920); - dceip.underlay_maximum_height_efficient_for_tiling = + dceip->underlay_maximum_height_efficient_for_tiling = bw_int_to_fixed(1080); - dceip.peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display = + dceip->peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display = bw_frc_to_fixed(3, 10); - dceip.peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation = + dceip->peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation = bw_int_to_fixed(25); - dceip.minimum_outstanding_pte_request_limit = bw_int_to_fixed( + dceip->minimum_outstanding_pte_request_limit = bw_int_to_fixed( 2); - dceip.maximum_total_outstanding_pte_requests_allowed_by_saw = + dceip->maximum_total_outstanding_pte_requests_allowed_by_saw = bw_int_to_fixed(128); - dceip.limit_excessive_outstanding_dmif_requests = true; - dceip.linear_mode_line_request_alternation_slice = + dceip->limit_excessive_outstanding_dmif_requests = true; + dceip->linear_mode_line_request_alternation_slice = bw_int_to_fixed(64); - dceip.scatter_gather_lines_of_pte_prefetching_in_linear_mode = + dceip->scatter_gather_lines_of_pte_prefetching_in_linear_mode = 32; - dceip.display_write_back420_luma_mcifwr_buffer_size = 12288; - dceip.display_write_back420_chroma_mcifwr_buffer_size = 8192; - dceip.request_efficiency = bw_frc_to_fixed(8, 10); - dceip.dispclk_per_request = bw_int_to_fixed(2); - dceip.dispclk_ramping_factor = bw_frc_to_fixed(105, 100); - dceip.display_pipe_throughput_factor = bw_frc_to_fixed(105, 100); - dceip.scatter_gather_pte_request_rows_in_tiling_mode = 2; - dceip.mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0); /* todo: this is a bug*/ + dceip->display_write_back420_luma_mcifwr_buffer_size = 12288; + dceip->display_write_back420_chroma_mcifwr_buffer_size = 8192; + dceip->request_efficiency = bw_frc_to_fixed(8, 10); + dceip->dispclk_per_request = bw_int_to_fixed(2); + dceip->dispclk_ramping_factor = bw_frc_to_fixed(105, 100); + dceip->display_pipe_throughput_factor = bw_frc_to_fixed(105, 100); + dceip->scatter_gather_pte_request_rows_in_tiling_mode = 2; + dceip->mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0); /* todo: this is a bug*/ break; case BW_CALCS_VERSION_POLARIS10: /* TODO: Treat VEGAM the same as P10 for now * Need to tune the para for VEGAM if needed */ case BW_CALCS_VERSION_VEGAM: - vbios.memory_type = bw_def_gddr5; - vbios.dram_channel_width_in_bits = 32; - vbios.number_of_dram_channels = asic_id.vram_width / vbios.dram_channel_width_in_bits; - vbios.number_of_dram_banks = 8; - vbios.high_yclk = bw_int_to_fixed(6000); - vbios.mid_yclk = bw_int_to_fixed(3200); - vbios.low_yclk = bw_int_to_fixed(1000); - vbios.low_sclk = bw_int_to_fixed(300); - vbios.mid1_sclk = bw_int_to_fixed(400); - vbios.mid2_sclk = bw_int_to_fixed(500); - vbios.mid3_sclk = bw_int_to_fixed(600); - vbios.mid4_sclk = bw_int_to_fixed(700); - vbios.mid5_sclk = bw_int_to_fixed(800); - vbios.mid6_sclk = bw_int_to_fixed(974); - vbios.high_sclk = bw_int_to_fixed(1154); - vbios.low_voltage_max_dispclk = bw_int_to_fixed(459); - vbios.mid_voltage_max_dispclk = bw_int_to_fixed(654); - vbios.high_voltage_max_dispclk = bw_int_to_fixed(1108); - vbios.low_voltage_max_phyclk = bw_int_to_fixed(540); - vbios.mid_voltage_max_phyclk = bw_int_to_fixed(810); - vbios.high_voltage_max_phyclk = bw_int_to_fixed(810); - vbios.data_return_bus_width = bw_int_to_fixed(32); - vbios.trc = bw_int_to_fixed(48); - vbios.dmifmc_urgent_latency = bw_int_to_fixed(3); - vbios.stutter_self_refresh_exit_latency = bw_int_to_fixed(5); - vbios.stutter_self_refresh_entry_latency = bw_int_to_fixed(0); - vbios.nbp_state_change_latency = bw_int_to_fixed(45); - vbios.mcifwrmc_urgent_latency = bw_int_to_fixed(10); - vbios.scatter_gather_enable = true; - vbios.down_spread_percentage = bw_frc_to_fixed(5, 10); - vbios.cursor_width = 32; - vbios.average_compression_rate = 4; - vbios.number_of_request_slots_gmc_reserves_for_dmif_per_channel = 256; - vbios.blackout_duration = bw_int_to_fixed(0); /* us */ - vbios.maximum_blackout_recovery_time = bw_int_to_fixed(0); - - dceip.max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation = 100; - dceip.max_average_percent_of_ideal_drambw_display_can_use_in_normal_system_operation = 100; - dceip.percent_of_ideal_port_bw_received_after_urgent_latency = 100; - dceip.large_cursor = false; - dceip.dmif_request_buffer_size = bw_int_to_fixed(768); - dceip.dmif_pipe_en_fbc_chunk_tracker = false; - dceip.cursor_max_outstanding_group_num = 1; - dceip.lines_interleaved_into_lb = 2; - dceip.chunk_width = 256; - dceip.number_of_graphics_pipes = 6; - dceip.number_of_underlay_pipes = 0; - dceip.low_power_tiling_mode = 0; - dceip.display_write_back_supported = false; - dceip.argb_compression_support = true; - dceip.underlay_vscaler_efficiency6_bit_per_component = + vbios->memory_type = bw_def_gddr5; + vbios->dram_channel_width_in_bits = 32; + vbios->number_of_dram_channels = asic_id.vram_width / vbios->dram_channel_width_in_bits; + vbios->number_of_dram_banks = 8; + vbios->high_yclk = bw_int_to_fixed(6000); + vbios->mid_yclk = bw_int_to_fixed(3200); + vbios->low_yclk = bw_int_to_fixed(1000); + vbios->low_sclk = bw_int_to_fixed(300); + vbios->mid1_sclk = bw_int_to_fixed(400); + vbios->mid2_sclk = bw_int_to_fixed(500); + vbios->mid3_sclk = bw_int_to_fixed(600); + vbios->mid4_sclk = bw_int_to_fixed(700); + vbios->mid5_sclk = bw_int_to_fixed(800); + vbios->mid6_sclk = bw_int_to_fixed(974); + vbios->high_sclk = bw_int_to_fixed(1154); + vbios->low_voltage_max_dispclk = bw_int_to_fixed(459); + vbios->mid_voltage_max_dispclk = bw_int_to_fixed(654); + vbios->high_voltage_max_dispclk = bw_int_to_fixed(1108); + vbios->low_voltage_max_phyclk = bw_int_to_fixed(540); + vbios->mid_voltage_max_phyclk = bw_int_to_fixed(810); + vbios->high_voltage_max_phyclk = bw_int_to_fixed(810); + vbios->data_return_bus_width = bw_int_to_fixed(32); + vbios->trc = bw_int_to_fixed(48); + vbios->dmifmc_urgent_latency = bw_int_to_fixed(3); + vbios->stutter_self_refresh_exit_latency = bw_int_to_fixed(5); + vbios->stutter_self_refresh_entry_latency = bw_int_to_fixed(0); + vbios->nbp_state_change_latency = bw_int_to_fixed(45); + vbios->mcifwrmc_urgent_latency = bw_int_to_fixed(10); + vbios->scatter_gather_enable = true; + vbios->down_spread_percentage = bw_frc_to_fixed(5, 10); + vbios->cursor_width = 32; + vbios->average_compression_rate = 4; + vbios->number_of_request_slots_gmc_reserves_for_dmif_per_channel = 256; + vbios->blackout_duration = bw_int_to_fixed(0); /* us */ + vbios->maximum_blackout_recovery_time = bw_int_to_fixed(0); + + dceip->max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation = 100; + dceip->max_average_percent_of_ideal_drambw_display_can_use_in_normal_system_operation = 100; + dceip->percent_of_ideal_port_bw_received_after_urgent_latency = 100; + dceip->large_cursor = false; + dceip->dmif_request_buffer_size = bw_int_to_fixed(768); + dceip->dmif_pipe_en_fbc_chunk_tracker = false; + dceip->cursor_max_outstanding_group_num = 1; + dceip->lines_interleaved_into_lb = 2; + dceip->chunk_width = 256; + dceip->number_of_graphics_pipes = 6; + dceip->number_of_underlay_pipes = 0; + dceip->low_power_tiling_mode = 0; + dceip->display_write_back_supported = false; + dceip->argb_compression_support = true; + dceip->underlay_vscaler_efficiency6_bit_per_component = bw_frc_to_fixed(35556, 10000); - dceip.underlay_vscaler_efficiency8_bit_per_component = + dceip->underlay_vscaler_efficiency8_bit_per_component = bw_frc_to_fixed(34286, 10000); - dceip.underlay_vscaler_efficiency10_bit_per_component = + dceip->underlay_vscaler_efficiency10_bit_per_component = bw_frc_to_fixed(32, 10); - dceip.underlay_vscaler_efficiency12_bit_per_component = + dceip->underlay_vscaler_efficiency12_bit_per_component = bw_int_to_fixed(3); - dceip.graphics_vscaler_efficiency6_bit_per_component = + dceip->graphics_vscaler_efficiency6_bit_per_component = bw_frc_to_fixed(35, 10); - dceip.graphics_vscaler_efficiency8_bit_per_component = + dceip->graphics_vscaler_efficiency8_bit_per_component = bw_frc_to_fixed(34286, 10000); - dceip.graphics_vscaler_efficiency10_bit_per_component = + dceip->graphics_vscaler_efficiency10_bit_per_component = bw_frc_to_fixed(32, 10); - dceip.graphics_vscaler_efficiency12_bit_per_component = + dceip->graphics_vscaler_efficiency12_bit_per_component = bw_int_to_fixed(3); - dceip.alpha_vscaler_efficiency = bw_int_to_fixed(3); - dceip.max_dmif_buffer_allocated = 4; - dceip.graphics_dmif_size = 12288; - dceip.underlay_luma_dmif_size = 19456; - dceip.underlay_chroma_dmif_size = 23552; - dceip.pre_downscaler_enabled = true; - dceip.underlay_downscale_prefetch_enabled = true; - dceip.lb_write_pixels_per_dispclk = bw_int_to_fixed(1); - dceip.lb_size_per_component444 = bw_int_to_fixed(245952); - dceip.graphics_lb_nodownscaling_multi_line_prefetching = true; - dceip.stutter_and_dram_clock_state_change_gated_before_cursor = + dceip->alpha_vscaler_efficiency = bw_int_to_fixed(3); + dceip->max_dmif_buffer_allocated = 4; + dceip->graphics_dmif_size = 12288; + dceip->underlay_luma_dmif_size = 19456; + dceip->underlay_chroma_dmif_size = 23552; + dceip->pre_downscaler_enabled = true; + dceip->underlay_downscale_prefetch_enabled = true; + dceip->lb_write_pixels_per_dispclk = bw_int_to_fixed(1); + dceip->lb_size_per_component444 = bw_int_to_fixed(245952); + dceip->graphics_lb_nodownscaling_multi_line_prefetching = true; + dceip->stutter_and_dram_clock_state_change_gated_before_cursor = bw_int_to_fixed(1); - dceip.underlay420_luma_lb_size_per_component = bw_int_to_fixed( + dceip->underlay420_luma_lb_size_per_component = bw_int_to_fixed( 82176); - dceip.underlay420_chroma_lb_size_per_component = + dceip->underlay420_chroma_lb_size_per_component = bw_int_to_fixed(164352); - dceip.underlay422_lb_size_per_component = bw_int_to_fixed( + dceip->underlay422_lb_size_per_component = bw_int_to_fixed( 82176); - dceip.cursor_chunk_width = bw_int_to_fixed(64); - dceip.cursor_dcp_buffer_lines = bw_int_to_fixed(4); - dceip.underlay_maximum_width_efficient_for_tiling = + dceip->cursor_chunk_width = bw_int_to_fixed(64); + dceip->cursor_dcp_buffer_lines = bw_int_to_fixed(4); + dceip->underlay_maximum_width_efficient_for_tiling = bw_int_to_fixed(1920); - dceip.underlay_maximum_height_efficient_for_tiling = + dceip->underlay_maximum_height_efficient_for_tiling = bw_int_to_fixed(1080); - dceip.peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display = + dceip->peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display = bw_frc_to_fixed(3, 10); - dceip.peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation = + dceip->peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation = bw_int_to_fixed(25); - dceip.minimum_outstanding_pte_request_limit = bw_int_to_fixed( + dceip->minimum_outstanding_pte_request_limit = bw_int_to_fixed( 2); - dceip.maximum_total_outstanding_pte_requests_allowed_by_saw = + dceip->maximum_total_outstanding_pte_requests_allowed_by_saw = bw_int_to_fixed(128); - dceip.limit_excessive_outstanding_dmif_requests = true; - dceip.linear_mode_line_request_alternation_slice = + dceip->limit_excessive_outstanding_dmif_requests = true; + dceip->linear_mode_line_request_alternation_slice = bw_int_to_fixed(64); - dceip.scatter_gather_lines_of_pte_prefetching_in_linear_mode = + dceip->scatter_gather_lines_of_pte_prefetching_in_linear_mode = 32; - dceip.display_write_back420_luma_mcifwr_buffer_size = 12288; - dceip.display_write_back420_chroma_mcifwr_buffer_size = 8192; - dceip.request_efficiency = bw_frc_to_fixed(8, 10); - dceip.dispclk_per_request = bw_int_to_fixed(2); - dceip.dispclk_ramping_factor = bw_frc_to_fixed(105, 100); - dceip.display_pipe_throughput_factor = bw_frc_to_fixed(105, 100); - dceip.scatter_gather_pte_request_rows_in_tiling_mode = 2; - dceip.mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0); + dceip->display_write_back420_luma_mcifwr_buffer_size = 12288; + dceip->display_write_back420_chroma_mcifwr_buffer_size = 8192; + dceip->request_efficiency = bw_frc_to_fixed(8, 10); + dceip->dispclk_per_request = bw_int_to_fixed(2); + dceip->dispclk_ramping_factor = bw_frc_to_fixed(105, 100); + dceip->display_pipe_throughput_factor = bw_frc_to_fixed(105, 100); + dceip->scatter_gather_pte_request_rows_in_tiling_mode = 2; + dceip->mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0); break; case BW_CALCS_VERSION_POLARIS11: - vbios.memory_type = bw_def_gddr5; - vbios.dram_channel_width_in_bits = 32; - vbios.number_of_dram_channels = asic_id.vram_width / vbios.dram_channel_width_in_bits; - vbios.number_of_dram_banks = 8; - vbios.high_yclk = bw_int_to_fixed(6000); - vbios.mid_yclk = bw_int_to_fixed(3200); - vbios.low_yclk = bw_int_to_fixed(1000); - vbios.low_sclk = bw_int_to_fixed(300); - vbios.mid1_sclk = bw_int_to_fixed(400); - vbios.mid2_sclk = bw_int_to_fixed(500); - vbios.mid3_sclk = bw_int_to_fixed(600); - vbios.mid4_sclk = bw_int_to_fixed(700); - vbios.mid5_sclk = bw_int_to_fixed(800); - vbios.mid6_sclk = bw_int_to_fixed(974); - vbios.high_sclk = bw_int_to_fixed(1154); - vbios.low_voltage_max_dispclk = bw_int_to_fixed(459); - vbios.mid_voltage_max_dispclk = bw_int_to_fixed(654); - vbios.high_voltage_max_dispclk = bw_int_to_fixed(1108); - vbios.low_voltage_max_phyclk = bw_int_to_fixed(540); - vbios.mid_voltage_max_phyclk = bw_int_to_fixed(810); - vbios.high_voltage_max_phyclk = bw_int_to_fixed(810); - vbios.data_return_bus_width = bw_int_to_fixed(32); - vbios.trc = bw_int_to_fixed(48); - if (vbios.number_of_dram_channels == 2) // 64-bit - vbios.dmifmc_urgent_latency = bw_int_to_fixed(4); + vbios->memory_type = bw_def_gddr5; + vbios->dram_channel_width_in_bits = 32; + vbios->number_of_dram_channels = asic_id.vram_width / vbios->dram_channel_width_in_bits; + vbios->number_of_dram_banks = 8; + vbios->high_yclk = bw_int_to_fixed(6000); + vbios->mid_yclk = bw_int_to_fixed(3200); + vbios->low_yclk = bw_int_to_fixed(1000); + vbios->low_sclk = bw_int_to_fixed(300); + vbios->mid1_sclk = bw_int_to_fixed(400); + vbios->mid2_sclk = bw_int_to_fixed(500); + vbios->mid3_sclk = bw_int_to_fixed(600); + vbios->mid4_sclk = bw_int_to_fixed(700); + vbios->mid5_sclk = bw_int_to_fixed(800); + vbios->mid6_sclk = bw_int_to_fixed(974); + vbios->high_sclk = bw_int_to_fixed(1154); + vbios->low_voltage_max_dispclk = bw_int_to_fixed(459); + vbios->mid_voltage_max_dispclk = bw_int_to_fixed(654); + vbios->high_voltage_max_dispclk = bw_int_to_fixed(1108); + vbios->low_voltage_max_phyclk = bw_int_to_fixed(540); + vbios->mid_voltage_max_phyclk = bw_int_to_fixed(810); + vbios->high_voltage_max_phyclk = bw_int_to_fixed(810); + vbios->data_return_bus_width = bw_int_to_fixed(32); + vbios->trc = bw_int_to_fixed(48); + if (vbios->number_of_dram_channels == 2) // 64-bit + vbios->dmifmc_urgent_latency = bw_int_to_fixed(4); else - vbios.dmifmc_urgent_latency = bw_int_to_fixed(3); - vbios.stutter_self_refresh_exit_latency = bw_int_to_fixed(5); - vbios.stutter_self_refresh_entry_latency = bw_int_to_fixed(0); - vbios.nbp_state_change_latency = bw_int_to_fixed(45); - vbios.mcifwrmc_urgent_latency = bw_int_to_fixed(10); - vbios.scatter_gather_enable = true; - vbios.down_spread_percentage = bw_frc_to_fixed(5, 10); - vbios.cursor_width = 32; - vbios.average_compression_rate = 4; - vbios.number_of_request_slots_gmc_reserves_for_dmif_per_channel = 256; - vbios.blackout_duration = bw_int_to_fixed(0); /* us */ - vbios.maximum_blackout_recovery_time = bw_int_to_fixed(0); - - dceip.max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation = 100; - dceip.max_average_percent_of_ideal_drambw_display_can_use_in_normal_system_operation = 100; - dceip.percent_of_ideal_port_bw_received_after_urgent_latency = 100; - dceip.large_cursor = false; - dceip.dmif_request_buffer_size = bw_int_to_fixed(768); - dceip.dmif_pipe_en_fbc_chunk_tracker = false; - dceip.cursor_max_outstanding_group_num = 1; - dceip.lines_interleaved_into_lb = 2; - dceip.chunk_width = 256; - dceip.number_of_graphics_pipes = 5; - dceip.number_of_underlay_pipes = 0; - dceip.low_power_tiling_mode = 0; - dceip.display_write_back_supported = false; - dceip.argb_compression_support = true; - dceip.underlay_vscaler_efficiency6_bit_per_component = + vbios->dmifmc_urgent_latency = bw_int_to_fixed(3); + vbios->stutter_self_refresh_exit_latency = bw_int_to_fixed(5); + vbios->stutter_self_refresh_entry_latency = bw_int_to_fixed(0); + vbios->nbp_state_change_latency = bw_int_to_fixed(45); + vbios->mcifwrmc_urgent_latency = bw_int_to_fixed(10); + vbios->scatter_gather_enable = true; + vbios->down_spread_percentage = bw_frc_to_fixed(5, 10); + vbios->cursor_width = 32; + vbios->average_compression_rate = 4; + vbios->number_of_request_slots_gmc_reserves_for_dmif_per_channel = 256; + vbios->blackout_duration = bw_int_to_fixed(0); /* us */ + vbios->maximum_blackout_recovery_time = bw_int_to_fixed(0); + + dceip->max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation = 100; + dceip->max_average_percent_of_ideal_drambw_display_can_use_in_normal_system_operation = 100; + dceip->percent_of_ideal_port_bw_received_after_urgent_latency = 100; + dceip->large_cursor = false; + dceip->dmif_request_buffer_size = bw_int_to_fixed(768); + dceip->dmif_pipe_en_fbc_chunk_tracker = false; + dceip->cursor_max_outstanding_group_num = 1; + dceip->lines_interleaved_into_lb = 2; + dceip->chunk_width = 256; + dceip->number_of_graphics_pipes = 5; + dceip->number_of_underlay_pipes = 0; + dceip->low_power_tiling_mode = 0; + dceip->display_write_back_supported = false; + dceip->argb_compression_support = true; + dceip->underlay_vscaler_efficiency6_bit_per_component = bw_frc_to_fixed(35556, 10000); - dceip.underlay_vscaler_efficiency8_bit_per_component = + dceip->underlay_vscaler_efficiency8_bit_per_component = bw_frc_to_fixed(34286, 10000); - dceip.underlay_vscaler_efficiency10_bit_per_component = + dceip->underlay_vscaler_efficiency10_bit_per_component = bw_frc_to_fixed(32, 10); - dceip.underlay_vscaler_efficiency12_bit_per_component = + dceip->underlay_vscaler_efficiency12_bit_per_component = bw_int_to_fixed(3); - dceip.graphics_vscaler_efficiency6_bit_per_component = + dceip->graphics_vscaler_efficiency6_bit_per_component = bw_frc_to_fixed(35, 10); - dceip.graphics_vscaler_efficiency8_bit_per_component = + dceip->graphics_vscaler_efficiency8_bit_per_component = bw_frc_to_fixed(34286, 10000); - dceip.graphics_vscaler_efficiency10_bit_per_component = + dceip->graphics_vscaler_efficiency10_bit_per_component = bw_frc_to_fixed(32, 10); - dceip.graphics_vscaler_efficiency12_bit_per_component = + dceip->graphics_vscaler_efficiency12_bit_per_component = bw_int_to_fixed(3); - dceip.alpha_vscaler_efficiency = bw_int_to_fixed(3); - dceip.max_dmif_buffer_allocated = 4; - dceip.graphics_dmif_size = 12288; - dceip.underlay_luma_dmif_size = 19456; - dceip.underlay_chroma_dmif_size = 23552; - dceip.pre_downscaler_enabled = true; - dceip.underlay_downscale_prefetch_enabled = true; - dceip.lb_write_pixels_per_dispclk = bw_int_to_fixed(1); - dceip.lb_size_per_component444 = bw_int_to_fixed(245952); - dceip.graphics_lb_nodownscaling_multi_line_prefetching = true; - dceip.stutter_and_dram_clock_state_change_gated_before_cursor = + dceip->alpha_vscaler_efficiency = bw_int_to_fixed(3); + dceip->max_dmif_buffer_allocated = 4; + dceip->graphics_dmif_size = 12288; + dceip->underlay_luma_dmif_size = 19456; + dceip->underlay_chroma_dmif_size = 23552; + dceip->pre_downscaler_enabled = true; + dceip->underlay_downscale_prefetch_enabled = true; + dceip->lb_write_pixels_per_dispclk = bw_int_to_fixed(1); + dceip->lb_size_per_component444 = bw_int_to_fixed(245952); + dceip->graphics_lb_nodownscaling_multi_line_prefetching = true; + dceip->stutter_and_dram_clock_state_change_gated_before_cursor = bw_int_to_fixed(1); - dceip.underlay420_luma_lb_size_per_component = bw_int_to_fixed( + dceip->underlay420_luma_lb_size_per_component = bw_int_to_fixed( 82176); - dceip.underlay420_chroma_lb_size_per_component = + dceip->underlay420_chroma_lb_size_per_component = bw_int_to_fixed(164352); - dceip.underlay422_lb_size_per_component = bw_int_to_fixed( + dceip->underlay422_lb_size_per_component = bw_int_to_fixed( 82176); - dceip.cursor_chunk_width = bw_int_to_fixed(64); - dceip.cursor_dcp_buffer_lines = bw_int_to_fixed(4); - dceip.underlay_maximum_width_efficient_for_tiling = + dceip->cursor_chunk_width = bw_int_to_fixed(64); + dceip->cursor_dcp_buffer_lines = bw_int_to_fixed(4); + dceip->underlay_maximum_width_efficient_for_tiling = bw_int_to_fixed(1920); - dceip.underlay_maximum_height_efficient_for_tiling = + dceip->underlay_maximum_height_efficient_for_tiling = bw_int_to_fixed(1080); - dceip.peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display = + dceip->peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display = bw_frc_to_fixed(3, 10); - dceip.peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation = + dceip->peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation = bw_int_to_fixed(25); - dceip.minimum_outstanding_pte_request_limit = bw_int_to_fixed( + dceip->minimum_outstanding_pte_request_limit = bw_int_to_fixed( 2); - dceip.maximum_total_outstanding_pte_requests_allowed_by_saw = + dceip->maximum_total_outstanding_pte_requests_allowed_by_saw = bw_int_to_fixed(128); - dceip.limit_excessive_outstanding_dmif_requests = true; - dceip.linear_mode_line_request_alternation_slice = + dceip->limit_excessive_outstanding_dmif_requests = true; + dceip->linear_mode_line_request_alternation_slice = bw_int_to_fixed(64); - dceip.scatter_gather_lines_of_pte_prefetching_in_linear_mode = + dceip->scatter_gather_lines_of_pte_prefetching_in_linear_mode = 32; - dceip.display_write_back420_luma_mcifwr_buffer_size = 12288; - dceip.display_write_back420_chroma_mcifwr_buffer_size = 8192; - dceip.request_efficiency = bw_frc_to_fixed(8, 10); - dceip.dispclk_per_request = bw_int_to_fixed(2); - dceip.dispclk_ramping_factor = bw_frc_to_fixed(105, 100); - dceip.display_pipe_throughput_factor = bw_frc_to_fixed(105, 100); - dceip.scatter_gather_pte_request_rows_in_tiling_mode = 2; - dceip.mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0); + dceip->display_write_back420_luma_mcifwr_buffer_size = 12288; + dceip->display_write_back420_chroma_mcifwr_buffer_size = 8192; + dceip->request_efficiency = bw_frc_to_fixed(8, 10); + dceip->dispclk_per_request = bw_int_to_fixed(2); + dceip->dispclk_ramping_factor = bw_frc_to_fixed(105, 100); + dceip->display_pipe_throughput_factor = bw_frc_to_fixed(105, 100); + dceip->scatter_gather_pte_request_rows_in_tiling_mode = 2; + dceip->mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0); break; case BW_CALCS_VERSION_POLARIS12: - vbios.memory_type = bw_def_gddr5; - vbios.dram_channel_width_in_bits = 32; - vbios.number_of_dram_channels = asic_id.vram_width / vbios.dram_channel_width_in_bits; - vbios.number_of_dram_banks = 8; - vbios.high_yclk = bw_int_to_fixed(6000); - vbios.mid_yclk = bw_int_to_fixed(3200); - vbios.low_yclk = bw_int_to_fixed(1000); - vbios.low_sclk = bw_int_to_fixed(678); - vbios.mid1_sclk = bw_int_to_fixed(864); - vbios.mid2_sclk = bw_int_to_fixed(900); - vbios.mid3_sclk = bw_int_to_fixed(920); - vbios.mid4_sclk = bw_int_to_fixed(940); - vbios.mid5_sclk = bw_int_to_fixed(960); - vbios.mid6_sclk = bw_int_to_fixed(980); - vbios.high_sclk = bw_int_to_fixed(1049); - vbios.low_voltage_max_dispclk = bw_int_to_fixed(459); - vbios.mid_voltage_max_dispclk = bw_int_to_fixed(654); - vbios.high_voltage_max_dispclk = bw_int_to_fixed(1108); - vbios.low_voltage_max_phyclk = bw_int_to_fixed(540); - vbios.mid_voltage_max_phyclk = bw_int_to_fixed(810); - vbios.high_voltage_max_phyclk = bw_int_to_fixed(810); - vbios.data_return_bus_width = bw_int_to_fixed(32); - vbios.trc = bw_int_to_fixed(48); - if (vbios.number_of_dram_channels == 2) // 64-bit - vbios.dmifmc_urgent_latency = bw_int_to_fixed(4); + vbios->memory_type = bw_def_gddr5; + vbios->dram_channel_width_in_bits = 32; + vbios->number_of_dram_channels = asic_id.vram_width / vbios->dram_channel_width_in_bits; + vbios->number_of_dram_banks = 8; + vbios->high_yclk = bw_int_to_fixed(6000); + vbios->mid_yclk = bw_int_to_fixed(3200); + vbios->low_yclk = bw_int_to_fixed(1000); + vbios->low_sclk = bw_int_to_fixed(678); + vbios->mid1_sclk = bw_int_to_fixed(864); + vbios->mid2_sclk = bw_int_to_fixed(900); + vbios->mid3_sclk = bw_int_to_fixed(920); + vbios->mid4_sclk = bw_int_to_fixed(940); + vbios->mid5_sclk = bw_int_to_fixed(960); + vbios->mid6_sclk = bw_int_to_fixed(980); + vbios->high_sclk = bw_int_to_fixed(1049); + vbios->low_voltage_max_dispclk = bw_int_to_fixed(459); + vbios->mid_voltage_max_dispclk = bw_int_to_fixed(654); + vbios->high_voltage_max_dispclk = bw_int_to_fixed(1108); + vbios->low_voltage_max_phyclk = bw_int_to_fixed(540); + vbios->mid_voltage_max_phyclk = bw_int_to_fixed(810); + vbios->high_voltage_max_phyclk = bw_int_to_fixed(810); + vbios->data_return_bus_width = bw_int_to_fixed(32); + vbios->trc = bw_int_to_fixed(48); + if (vbios->number_of_dram_channels == 2) // 64-bit + vbios->dmifmc_urgent_latency = bw_int_to_fixed(4); else - vbios.dmifmc_urgent_latency = bw_int_to_fixed(3); - vbios.stutter_self_refresh_exit_latency = bw_int_to_fixed(5); - vbios.stutter_self_refresh_entry_latency = bw_int_to_fixed(0); - vbios.nbp_state_change_latency = bw_int_to_fixed(250); - vbios.mcifwrmc_urgent_latency = bw_int_to_fixed(10); - vbios.scatter_gather_enable = false; - vbios.down_spread_percentage = bw_frc_to_fixed(5, 10); - vbios.cursor_width = 32; - vbios.average_compression_rate = 4; - vbios.number_of_request_slots_gmc_reserves_for_dmif_per_channel = 256; - vbios.blackout_duration = bw_int_to_fixed(0); /* us */ - vbios.maximum_blackout_recovery_time = bw_int_to_fixed(0); - - dceip.max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation = 100; - dceip.max_average_percent_of_ideal_drambw_display_can_use_in_normal_system_operation = 100; - dceip.percent_of_ideal_port_bw_received_after_urgent_latency = 100; - dceip.large_cursor = false; - dceip.dmif_request_buffer_size = bw_int_to_fixed(768); - dceip.dmif_pipe_en_fbc_chunk_tracker = false; - dceip.cursor_max_outstanding_group_num = 1; - dceip.lines_interleaved_into_lb = 2; - dceip.chunk_width = 256; - dceip.number_of_graphics_pipes = 5; - dceip.number_of_underlay_pipes = 0; - dceip.low_power_tiling_mode = 0; - dceip.display_write_back_supported = true; - dceip.argb_compression_support = true; - dceip.underlay_vscaler_efficiency6_bit_per_component = + vbios->dmifmc_urgent_latency = bw_int_to_fixed(3); + vbios->stutter_self_refresh_exit_latency = bw_int_to_fixed(5); + vbios->stutter_self_refresh_entry_latency = bw_int_to_fixed(0); + vbios->nbp_state_change_latency = bw_int_to_fixed(250); + vbios->mcifwrmc_urgent_latency = bw_int_to_fixed(10); + vbios->scatter_gather_enable = false; + vbios->down_spread_percentage = bw_frc_to_fixed(5, 10); + vbios->cursor_width = 32; + vbios->average_compression_rate = 4; + vbios->number_of_request_slots_gmc_reserves_for_dmif_per_channel = 256; + vbios->blackout_duration = bw_int_to_fixed(0); /* us */ + vbios->maximum_blackout_recovery_time = bw_int_to_fixed(0); + + dceip->max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation = 100; + dceip->max_average_percent_of_ideal_drambw_display_can_use_in_normal_system_operation = 100; + dceip->percent_of_ideal_port_bw_received_after_urgent_latency = 100; + dceip->large_cursor = false; + dceip->dmif_request_buffer_size = bw_int_to_fixed(768); + dceip->dmif_pipe_en_fbc_chunk_tracker = false; + dceip->cursor_max_outstanding_group_num = 1; + dceip->lines_interleaved_into_lb = 2; + dceip->chunk_width = 256; + dceip->number_of_graphics_pipes = 5; + dceip->number_of_underlay_pipes = 0; + dceip->low_power_tiling_mode = 0; + dceip->display_write_back_supported = true; + dceip->argb_compression_support = true; + dceip->underlay_vscaler_efficiency6_bit_per_component = bw_frc_to_fixed(35556, 10000); - dceip.underlay_vscaler_efficiency8_bit_per_component = + dceip->underlay_vscaler_efficiency8_bit_per_component = bw_frc_to_fixed(34286, 10000); - dceip.underlay_vscaler_efficiency10_bit_per_component = + dceip->underlay_vscaler_efficiency10_bit_per_component = bw_frc_to_fixed(32, 10); - dceip.underlay_vscaler_efficiency12_bit_per_component = + dceip->underlay_vscaler_efficiency12_bit_per_component = bw_int_to_fixed(3); - dceip.graphics_vscaler_efficiency6_bit_per_component = + dceip->graphics_vscaler_efficiency6_bit_per_component = bw_frc_to_fixed(35, 10); - dceip.graphics_vscaler_efficiency8_bit_per_component = + dceip->graphics_vscaler_efficiency8_bit_per_component = bw_frc_to_fixed(34286, 10000); - dceip.graphics_vscaler_efficiency10_bit_per_component = + dceip->graphics_vscaler_efficiency10_bit_per_component = bw_frc_to_fixed(32, 10); - dceip.graphics_vscaler_efficiency12_bit_per_component = + dceip->graphics_vscaler_efficiency12_bit_per_component = bw_int_to_fixed(3); - dceip.alpha_vscaler_efficiency = bw_int_to_fixed(3); - dceip.max_dmif_buffer_allocated = 4; - dceip.graphics_dmif_size = 12288; - dceip.underlay_luma_dmif_size = 19456; - dceip.underlay_chroma_dmif_size = 23552; - dceip.pre_downscaler_enabled = true; - dceip.underlay_downscale_prefetch_enabled = true; - dceip.lb_write_pixels_per_dispclk = bw_int_to_fixed(1); - dceip.lb_size_per_component444 = bw_int_to_fixed(245952); - dceip.graphics_lb_nodownscaling_multi_line_prefetching = true; - dceip.stutter_and_dram_clock_state_change_gated_before_cursor = + dceip->alpha_vscaler_efficiency = bw_int_to_fixed(3); + dceip->max_dmif_buffer_allocated = 4; + dceip->graphics_dmif_size = 12288; + dceip->underlay_luma_dmif_size = 19456; + dceip->underlay_chroma_dmif_size = 23552; + dceip->pre_downscaler_enabled = true; + dceip->underlay_downscale_prefetch_enabled = true; + dceip->lb_write_pixels_per_dispclk = bw_int_to_fixed(1); + dceip->lb_size_per_component444 = bw_int_to_fixed(245952); + dceip->graphics_lb_nodownscaling_multi_line_prefetching = true; + dceip->stutter_and_dram_clock_state_change_gated_before_cursor = bw_int_to_fixed(1); - dceip.underlay420_luma_lb_size_per_component = bw_int_to_fixed( + dceip->underlay420_luma_lb_size_per_component = bw_int_to_fixed( 82176); - dceip.underlay420_chroma_lb_size_per_component = + dceip->underlay420_chroma_lb_size_per_component = bw_int_to_fixed(164352); - dceip.underlay422_lb_size_per_component = bw_int_to_fixed( + dceip->underlay422_lb_size_per_component = bw_int_to_fixed( 82176); - dceip.cursor_chunk_width = bw_int_to_fixed(64); - dceip.cursor_dcp_buffer_lines = bw_int_to_fixed(4); - dceip.underlay_maximum_width_efficient_for_tiling = + dceip->cursor_chunk_width = bw_int_to_fixed(64); + dceip->cursor_dcp_buffer_lines = bw_int_to_fixed(4); + dceip->underlay_maximum_width_efficient_for_tiling = bw_int_to_fixed(1920); - dceip.underlay_maximum_height_efficient_for_tiling = + dceip->underlay_maximum_height_efficient_for_tiling = bw_int_to_fixed(1080); - dceip.peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display = + dceip->peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display = bw_frc_to_fixed(3, 10); - dceip.peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation = + dceip->peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation = bw_int_to_fixed(25); - dceip.minimum_outstanding_pte_request_limit = bw_int_to_fixed( + dceip->minimum_outstanding_pte_request_limit = bw_int_to_fixed( 2); - dceip.maximum_total_outstanding_pte_requests_allowed_by_saw = + dceip->maximum_total_outstanding_pte_requests_allowed_by_saw = bw_int_to_fixed(128); - dceip.limit_excessive_outstanding_dmif_requests = true; - dceip.linear_mode_line_request_alternation_slice = + dceip->limit_excessive_outstanding_dmif_requests = true; + dceip->linear_mode_line_request_alternation_slice = bw_int_to_fixed(64); - dceip.scatter_gather_lines_of_pte_prefetching_in_linear_mode = + dceip->scatter_gather_lines_of_pte_prefetching_in_linear_mode = 32; - dceip.display_write_back420_luma_mcifwr_buffer_size = 12288; - dceip.display_write_back420_chroma_mcifwr_buffer_size = 8192; - dceip.request_efficiency = bw_frc_to_fixed(8, 10); - dceip.dispclk_per_request = bw_int_to_fixed(2); - dceip.dispclk_ramping_factor = bw_frc_to_fixed(105, 100); - dceip.display_pipe_throughput_factor = bw_frc_to_fixed(105, 100); - dceip.scatter_gather_pte_request_rows_in_tiling_mode = 2; - dceip.mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0); + dceip->display_write_back420_luma_mcifwr_buffer_size = 12288; + dceip->display_write_back420_chroma_mcifwr_buffer_size = 8192; + dceip->request_efficiency = bw_frc_to_fixed(8, 10); + dceip->dispclk_per_request = bw_int_to_fixed(2); + dceip->dispclk_ramping_factor = bw_frc_to_fixed(105, 100); + dceip->display_pipe_throughput_factor = bw_frc_to_fixed(105, 100); + dceip->scatter_gather_pte_request_rows_in_tiling_mode = 2; + dceip->mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0); break; case BW_CALCS_VERSION_STONEY: - vbios.memory_type = bw_def_gddr5; - vbios.dram_channel_width_in_bits = 64; - vbios.number_of_dram_channels = asic_id.vram_width / vbios.dram_channel_width_in_bits; - vbios.number_of_dram_banks = 8; - vbios.high_yclk = bw_int_to_fixed(1866); - vbios.mid_yclk = bw_int_to_fixed(1866); - vbios.low_yclk = bw_int_to_fixed(1333); - vbios.low_sclk = bw_int_to_fixed(200); - vbios.mid1_sclk = bw_int_to_fixed(600); - vbios.mid2_sclk = bw_int_to_fixed(600); - vbios.mid3_sclk = bw_int_to_fixed(600); - vbios.mid4_sclk = bw_int_to_fixed(600); - vbios.mid5_sclk = bw_int_to_fixed(600); - vbios.mid6_sclk = bw_int_to_fixed(600); - vbios.high_sclk = bw_int_to_fixed(800); - vbios.low_voltage_max_dispclk = bw_int_to_fixed(352); - vbios.mid_voltage_max_dispclk = bw_int_to_fixed(467); - vbios.high_voltage_max_dispclk = bw_int_to_fixed(643); - vbios.low_voltage_max_phyclk = bw_int_to_fixed(540); - vbios.mid_voltage_max_phyclk = bw_int_to_fixed(810); - vbios.high_voltage_max_phyclk = bw_int_to_fixed(810); - vbios.data_return_bus_width = bw_int_to_fixed(32); - vbios.trc = bw_int_to_fixed(50); - vbios.dmifmc_urgent_latency = bw_int_to_fixed(4); - vbios.stutter_self_refresh_exit_latency = bw_frc_to_fixed(158, 10); - vbios.stutter_self_refresh_entry_latency = bw_int_to_fixed(0); - vbios.nbp_state_change_latency = bw_frc_to_fixed(2008, 100); - vbios.mcifwrmc_urgent_latency = bw_int_to_fixed(10); - vbios.scatter_gather_enable = true; - vbios.down_spread_percentage = bw_frc_to_fixed(5, 10); - vbios.cursor_width = 32; - vbios.average_compression_rate = 4; - vbios.number_of_request_slots_gmc_reserves_for_dmif_per_channel = 256; - vbios.blackout_duration = bw_int_to_fixed(0); /* us */ - vbios.maximum_blackout_recovery_time = bw_int_to_fixed(0); - - dceip.max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation = 100; - dceip.max_average_percent_of_ideal_drambw_display_can_use_in_normal_system_operation = 100; - dceip.percent_of_ideal_port_bw_received_after_urgent_latency = 100; - dceip.large_cursor = false; - dceip.dmif_request_buffer_size = bw_int_to_fixed(768); - dceip.dmif_pipe_en_fbc_chunk_tracker = false; - dceip.cursor_max_outstanding_group_num = 1; - dceip.lines_interleaved_into_lb = 2; - dceip.chunk_width = 256; - dceip.number_of_graphics_pipes = 2; - dceip.number_of_underlay_pipes = 1; - dceip.low_power_tiling_mode = 0; - dceip.display_write_back_supported = false; - dceip.argb_compression_support = true; - dceip.underlay_vscaler_efficiency6_bit_per_component = + vbios->memory_type = bw_def_gddr5; + vbios->dram_channel_width_in_bits = 64; + vbios->number_of_dram_channels = asic_id.vram_width / vbios->dram_channel_width_in_bits; + vbios->number_of_dram_banks = 8; + vbios->high_yclk = bw_int_to_fixed(1866); + vbios->mid_yclk = bw_int_to_fixed(1866); + vbios->low_yclk = bw_int_to_fixed(1333); + vbios->low_sclk = bw_int_to_fixed(200); + vbios->mid1_sclk = bw_int_to_fixed(600); + vbios->mid2_sclk = bw_int_to_fixed(600); + vbios->mid3_sclk = bw_int_to_fixed(600); + vbios->mid4_sclk = bw_int_to_fixed(600); + vbios->mid5_sclk = bw_int_to_fixed(600); + vbios->mid6_sclk = bw_int_to_fixed(600); + vbios->high_sclk = bw_int_to_fixed(800); + vbios->low_voltage_max_dispclk = bw_int_to_fixed(352); + vbios->mid_voltage_max_dispclk = bw_int_to_fixed(467); + vbios->high_voltage_max_dispclk = bw_int_to_fixed(643); + vbios->low_voltage_max_phyclk = bw_int_to_fixed(540); + vbios->mid_voltage_max_phyclk = bw_int_to_fixed(810); + vbios->high_voltage_max_phyclk = bw_int_to_fixed(810); + vbios->data_return_bus_width = bw_int_to_fixed(32); + vbios->trc = bw_int_to_fixed(50); + vbios->dmifmc_urgent_latency = bw_int_to_fixed(4); + vbios->stutter_self_refresh_exit_latency = bw_frc_to_fixed(158, 10); + vbios->stutter_self_refresh_entry_latency = bw_int_to_fixed(0); + vbios->nbp_state_change_latency = bw_frc_to_fixed(2008, 100); + vbios->mcifwrmc_urgent_latency = bw_int_to_fixed(10); + vbios->scatter_gather_enable = true; + vbios->down_spread_percentage = bw_frc_to_fixed(5, 10); + vbios->cursor_width = 32; + vbios->average_compression_rate = 4; + vbios->number_of_request_slots_gmc_reserves_for_dmif_per_channel = 256; + vbios->blackout_duration = bw_int_to_fixed(0); /* us */ + vbios->maximum_blackout_recovery_time = bw_int_to_fixed(0); + + dceip->max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation = 100; + dceip->max_average_percent_of_ideal_drambw_display_can_use_in_normal_system_operation = 100; + dceip->percent_of_ideal_port_bw_received_after_urgent_latency = 100; + dceip->large_cursor = false; + dceip->dmif_request_buffer_size = bw_int_to_fixed(768); + dceip->dmif_pipe_en_fbc_chunk_tracker = false; + dceip->cursor_max_outstanding_group_num = 1; + dceip->lines_interleaved_into_lb = 2; + dceip->chunk_width = 256; + dceip->number_of_graphics_pipes = 2; + dceip->number_of_underlay_pipes = 1; + dceip->low_power_tiling_mode = 0; + dceip->display_write_back_supported = false; + dceip->argb_compression_support = true; + dceip->underlay_vscaler_efficiency6_bit_per_component = bw_frc_to_fixed(35556, 10000); - dceip.underlay_vscaler_efficiency8_bit_per_component = + dceip->underlay_vscaler_efficiency8_bit_per_component = bw_frc_to_fixed(34286, 10000); - dceip.underlay_vscaler_efficiency10_bit_per_component = + dceip->underlay_vscaler_efficiency10_bit_per_component = bw_frc_to_fixed(32, 10); - dceip.underlay_vscaler_efficiency12_bit_per_component = + dceip->underlay_vscaler_efficiency12_bit_per_component = bw_int_to_fixed(3); - dceip.graphics_vscaler_efficiency6_bit_per_component = + dceip->graphics_vscaler_efficiency6_bit_per_component = bw_frc_to_fixed(35, 10); - dceip.graphics_vscaler_efficiency8_bit_per_component = + dceip->graphics_vscaler_efficiency8_bit_per_component = bw_frc_to_fixed(34286, 10000); - dceip.graphics_vscaler_efficiency10_bit_per_component = + dceip->graphics_vscaler_efficiency10_bit_per_component = bw_frc_to_fixed(32, 10); - dceip.graphics_vscaler_efficiency12_bit_per_component = + dceip->graphics_vscaler_efficiency12_bit_per_component = bw_int_to_fixed(3); - dceip.alpha_vscaler_efficiency = bw_int_to_fixed(3); - dceip.max_dmif_buffer_allocated = 2; - dceip.graphics_dmif_size = 12288; - dceip.underlay_luma_dmif_size = 19456; - dceip.underlay_chroma_dmif_size = 23552; - dceip.pre_downscaler_enabled = true; - dceip.underlay_downscale_prefetch_enabled = true; - dceip.lb_write_pixels_per_dispclk = bw_int_to_fixed(1); - dceip.lb_size_per_component444 = bw_int_to_fixed(82176); - dceip.graphics_lb_nodownscaling_multi_line_prefetching = false; - dceip.stutter_and_dram_clock_state_change_gated_before_cursor = + dceip->alpha_vscaler_efficiency = bw_int_to_fixed(3); + dceip->max_dmif_buffer_allocated = 2; + dceip->graphics_dmif_size = 12288; + dceip->underlay_luma_dmif_size = 19456; + dceip->underlay_chroma_dmif_size = 23552; + dceip->pre_downscaler_enabled = true; + dceip->underlay_downscale_prefetch_enabled = true; + dceip->lb_write_pixels_per_dispclk = bw_int_to_fixed(1); + dceip->lb_size_per_component444 = bw_int_to_fixed(82176); + dceip->graphics_lb_nodownscaling_multi_line_prefetching = false; + dceip->stutter_and_dram_clock_state_change_gated_before_cursor = bw_int_to_fixed(0); - dceip.underlay420_luma_lb_size_per_component = bw_int_to_fixed( + dceip->underlay420_luma_lb_size_per_component = bw_int_to_fixed( 82176); - dceip.underlay420_chroma_lb_size_per_component = + dceip->underlay420_chroma_lb_size_per_component = bw_int_to_fixed(164352); - dceip.underlay422_lb_size_per_component = bw_int_to_fixed( + dceip->underlay422_lb_size_per_component = bw_int_to_fixed( 82176); - dceip.cursor_chunk_width = bw_int_to_fixed(64); - dceip.cursor_dcp_buffer_lines = bw_int_to_fixed(4); - dceip.underlay_maximum_width_efficient_for_tiling = + dceip->cursor_chunk_width = bw_int_to_fixed(64); + dceip->cursor_dcp_buffer_lines = bw_int_to_fixed(4); + dceip->underlay_maximum_width_efficient_for_tiling = bw_int_to_fixed(1920); - dceip.underlay_maximum_height_efficient_for_tiling = + dceip->underlay_maximum_height_efficient_for_tiling = bw_int_to_fixed(1080); - dceip.peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display = + dceip->peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display = bw_frc_to_fixed(3, 10); - dceip.peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation = + dceip->peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation = bw_int_to_fixed(25); - dceip.minimum_outstanding_pte_request_limit = bw_int_to_fixed( + dceip->minimum_outstanding_pte_request_limit = bw_int_to_fixed( 2); - dceip.maximum_total_outstanding_pte_requests_allowed_by_saw = + dceip->maximum_total_outstanding_pte_requests_allowed_by_saw = bw_int_to_fixed(128); - dceip.limit_excessive_outstanding_dmif_requests = true; - dceip.linear_mode_line_request_alternation_slice = + dceip->limit_excessive_outstanding_dmif_requests = true; + dceip->linear_mode_line_request_alternation_slice = bw_int_to_fixed(64); - dceip.scatter_gather_lines_of_pte_prefetching_in_linear_mode = + dceip->scatter_gather_lines_of_pte_prefetching_in_linear_mode = 32; - dceip.display_write_back420_luma_mcifwr_buffer_size = 12288; - dceip.display_write_back420_chroma_mcifwr_buffer_size = 8192; - dceip.request_efficiency = bw_frc_to_fixed(8, 10); - dceip.dispclk_per_request = bw_int_to_fixed(2); - dceip.dispclk_ramping_factor = bw_frc_to_fixed(105, 100); - dceip.display_pipe_throughput_factor = bw_frc_to_fixed(105, 100); - dceip.scatter_gather_pte_request_rows_in_tiling_mode = 2; - dceip.mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0); + dceip->display_write_back420_luma_mcifwr_buffer_size = 12288; + dceip->display_write_back420_chroma_mcifwr_buffer_size = 8192; + dceip->request_efficiency = bw_frc_to_fixed(8, 10); + dceip->dispclk_per_request = bw_int_to_fixed(2); + dceip->dispclk_ramping_factor = bw_frc_to_fixed(105, 100); + dceip->display_pipe_throughput_factor = bw_frc_to_fixed(105, 100); + dceip->scatter_gather_pte_request_rows_in_tiling_mode = 2; + dceip->mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0); break; case BW_CALCS_VERSION_VEGA10: - vbios.memory_type = bw_def_hbm; - vbios.dram_channel_width_in_bits = 128; - vbios.number_of_dram_channels = asic_id.vram_width / vbios.dram_channel_width_in_bits; - vbios.number_of_dram_banks = 16; - vbios.high_yclk = bw_int_to_fixed(2400); - vbios.mid_yclk = bw_int_to_fixed(1700); - vbios.low_yclk = bw_int_to_fixed(1000); - vbios.low_sclk = bw_int_to_fixed(300); - vbios.mid1_sclk = bw_int_to_fixed(350); - vbios.mid2_sclk = bw_int_to_fixed(400); - vbios.mid3_sclk = bw_int_to_fixed(500); - vbios.mid4_sclk = bw_int_to_fixed(600); - vbios.mid5_sclk = bw_int_to_fixed(700); - vbios.mid6_sclk = bw_int_to_fixed(760); - vbios.high_sclk = bw_int_to_fixed(776); - vbios.low_voltage_max_dispclk = bw_int_to_fixed(460); - vbios.mid_voltage_max_dispclk = bw_int_to_fixed(670); - vbios.high_voltage_max_dispclk = bw_int_to_fixed(1133); - vbios.low_voltage_max_phyclk = bw_int_to_fixed(540); - vbios.mid_voltage_max_phyclk = bw_int_to_fixed(810); - vbios.high_voltage_max_phyclk = bw_int_to_fixed(810); - vbios.data_return_bus_width = bw_int_to_fixed(32); - vbios.trc = bw_int_to_fixed(48); - vbios.dmifmc_urgent_latency = bw_int_to_fixed(3); - vbios.stutter_self_refresh_exit_latency = bw_frc_to_fixed(75, 10); - vbios.stutter_self_refresh_entry_latency = bw_frc_to_fixed(19, 10); - vbios.nbp_state_change_latency = bw_int_to_fixed(39); - vbios.mcifwrmc_urgent_latency = bw_int_to_fixed(10); - vbios.scatter_gather_enable = false; - vbios.down_spread_percentage = bw_frc_to_fixed(5, 10); - vbios.cursor_width = 32; - vbios.average_compression_rate = 4; - vbios.number_of_request_slots_gmc_reserves_for_dmif_per_channel = 8; - vbios.blackout_duration = bw_int_to_fixed(0); /* us */ - vbios.maximum_blackout_recovery_time = bw_int_to_fixed(0); - - dceip.max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation = 100; - dceip.max_average_percent_of_ideal_drambw_display_can_use_in_normal_system_operation = 100; - dceip.percent_of_ideal_port_bw_received_after_urgent_latency = 100; - dceip.large_cursor = false; - dceip.dmif_request_buffer_size = bw_int_to_fixed(2304); - dceip.dmif_pipe_en_fbc_chunk_tracker = true; - dceip.cursor_max_outstanding_group_num = 1; - dceip.lines_interleaved_into_lb = 2; - dceip.chunk_width = 256; - dceip.number_of_graphics_pipes = 6; - dceip.number_of_underlay_pipes = 0; - dceip.low_power_tiling_mode = 0; - dceip.display_write_back_supported = true; - dceip.argb_compression_support = true; - dceip.underlay_vscaler_efficiency6_bit_per_component = + vbios->memory_type = bw_def_hbm; + vbios->dram_channel_width_in_bits = 128; + vbios->number_of_dram_channels = asic_id.vram_width / vbios->dram_channel_width_in_bits; + vbios->number_of_dram_banks = 16; + vbios->high_yclk = bw_int_to_fixed(2400); + vbios->mid_yclk = bw_int_to_fixed(1700); + vbios->low_yclk = bw_int_to_fixed(1000); + vbios->low_sclk = bw_int_to_fixed(300); + vbios->mid1_sclk = bw_int_to_fixed(350); + vbios->mid2_sclk = bw_int_to_fixed(400); + vbios->mid3_sclk = bw_int_to_fixed(500); + vbios->mid4_sclk = bw_int_to_fixed(600); + vbios->mid5_sclk = bw_int_to_fixed(700); + vbios->mid6_sclk = bw_int_to_fixed(760); + vbios->high_sclk = bw_int_to_fixed(776); + vbios->low_voltage_max_dispclk = bw_int_to_fixed(460); + vbios->mid_voltage_max_dispclk = bw_int_to_fixed(670); + vbios->high_voltage_max_dispclk = bw_int_to_fixed(1133); + vbios->low_voltage_max_phyclk = bw_int_to_fixed(540); + vbios->mid_voltage_max_phyclk = bw_int_to_fixed(810); + vbios->high_voltage_max_phyclk = bw_int_to_fixed(810); + vbios->data_return_bus_width = bw_int_to_fixed(32); + vbios->trc = bw_int_to_fixed(48); + vbios->dmifmc_urgent_latency = bw_int_to_fixed(3); + vbios->stutter_self_refresh_exit_latency = bw_frc_to_fixed(75, 10); + vbios->stutter_self_refresh_entry_latency = bw_frc_to_fixed(19, 10); + vbios->nbp_state_change_latency = bw_int_to_fixed(39); + vbios->mcifwrmc_urgent_latency = bw_int_to_fixed(10); + vbios->scatter_gather_enable = false; + vbios->down_spread_percentage = bw_frc_to_fixed(5, 10); + vbios->cursor_width = 32; + vbios->average_compression_rate = 4; + vbios->number_of_request_slots_gmc_reserves_for_dmif_per_channel = 8; + vbios->blackout_duration = bw_int_to_fixed(0); /* us */ + vbios->maximum_blackout_recovery_time = bw_int_to_fixed(0); + + dceip->max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation = 100; + dceip->max_average_percent_of_ideal_drambw_display_can_use_in_normal_system_operation = 100; + dceip->percent_of_ideal_port_bw_received_after_urgent_latency = 100; + dceip->large_cursor = false; + dceip->dmif_request_buffer_size = bw_int_to_fixed(2304); + dceip->dmif_pipe_en_fbc_chunk_tracker = true; + dceip->cursor_max_outstanding_group_num = 1; + dceip->lines_interleaved_into_lb = 2; + dceip->chunk_width = 256; + dceip->number_of_graphics_pipes = 6; + dceip->number_of_underlay_pipes = 0; + dceip->low_power_tiling_mode = 0; + dceip->display_write_back_supported = true; + dceip->argb_compression_support = true; + dceip->underlay_vscaler_efficiency6_bit_per_component = bw_frc_to_fixed(35556, 10000); - dceip.underlay_vscaler_efficiency8_bit_per_component = + dceip->underlay_vscaler_efficiency8_bit_per_component = bw_frc_to_fixed(34286, 10000); - dceip.underlay_vscaler_efficiency10_bit_per_component = + dceip->underlay_vscaler_efficiency10_bit_per_component = bw_frc_to_fixed(32, 10); - dceip.underlay_vscaler_efficiency12_bit_per_component = + dceip->underlay_vscaler_efficiency12_bit_per_component = bw_int_to_fixed(3); - dceip.graphics_vscaler_efficiency6_bit_per_component = + dceip->graphics_vscaler_efficiency6_bit_per_component = bw_frc_to_fixed(35, 10); - dceip.graphics_vscaler_efficiency8_bit_per_component = + dceip->graphics_vscaler_efficiency8_bit_per_component = bw_frc_to_fixed(34286, 10000); - dceip.graphics_vscaler_efficiency10_bit_per_component = + dceip->graphics_vscaler_efficiency10_bit_per_component = bw_frc_to_fixed(32, 10); - dceip.graphics_vscaler_efficiency12_bit_per_component = + dceip->graphics_vscaler_efficiency12_bit_per_component = bw_int_to_fixed(3); - dceip.alpha_vscaler_efficiency = bw_int_to_fixed(3); - dceip.max_dmif_buffer_allocated = 4; - dceip.graphics_dmif_size = 24576; - dceip.underlay_luma_dmif_size = 19456; - dceip.underlay_chroma_dmif_size = 23552; - dceip.pre_downscaler_enabled = true; - dceip.underlay_downscale_prefetch_enabled = false; - dceip.lb_write_pixels_per_dispclk = bw_int_to_fixed(1); - dceip.lb_size_per_component444 = bw_int_to_fixed(245952); - dceip.graphics_lb_nodownscaling_multi_line_prefetching = true; - dceip.stutter_and_dram_clock_state_change_gated_before_cursor = + dceip->alpha_vscaler_efficiency = bw_int_to_fixed(3); + dceip->max_dmif_buffer_allocated = 4; + dceip->graphics_dmif_size = 24576; + dceip->underlay_luma_dmif_size = 19456; + dceip->underlay_chroma_dmif_size = 23552; + dceip->pre_downscaler_enabled = true; + dceip->underlay_downscale_prefetch_enabled = false; + dceip->lb_write_pixels_per_dispclk = bw_int_to_fixed(1); + dceip->lb_size_per_component444 = bw_int_to_fixed(245952); + dceip->graphics_lb_nodownscaling_multi_line_prefetching = true; + dceip->stutter_and_dram_clock_state_change_gated_before_cursor = bw_int_to_fixed(1); - dceip.underlay420_luma_lb_size_per_component = bw_int_to_fixed( + dceip->underlay420_luma_lb_size_per_component = bw_int_to_fixed( 82176); - dceip.underlay420_chroma_lb_size_per_component = + dceip->underlay420_chroma_lb_size_per_component = bw_int_to_fixed(164352); - dceip.underlay422_lb_size_per_component = bw_int_to_fixed( + dceip->underlay422_lb_size_per_component = bw_int_to_fixed( 82176); - dceip.cursor_chunk_width = bw_int_to_fixed(64); - dceip.cursor_dcp_buffer_lines = bw_int_to_fixed(4); - dceip.underlay_maximum_width_efficient_for_tiling = + dceip->cursor_chunk_width = bw_int_to_fixed(64); + dceip->cursor_dcp_buffer_lines = bw_int_to_fixed(4); + dceip->underlay_maximum_width_efficient_for_tiling = bw_int_to_fixed(1920); - dceip.underlay_maximum_height_efficient_for_tiling = + dceip->underlay_maximum_height_efficient_for_tiling = bw_int_to_fixed(1080); - dceip.peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display = + dceip->peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display = bw_frc_to_fixed(3, 10); - dceip.peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation = + dceip->peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation = bw_int_to_fixed(25); - dceip.minimum_outstanding_pte_request_limit = bw_int_to_fixed( + dceip->minimum_outstanding_pte_request_limit = bw_int_to_fixed( 2); - dceip.maximum_total_outstanding_pte_requests_allowed_by_saw = + dceip->maximum_total_outstanding_pte_requests_allowed_by_saw = bw_int_to_fixed(128); - dceip.limit_excessive_outstanding_dmif_requests = true; - dceip.linear_mode_line_request_alternation_slice = + dceip->limit_excessive_outstanding_dmif_requests = true; + dceip->linear_mode_line_request_alternation_slice = bw_int_to_fixed(64); - dceip.scatter_gather_lines_of_pte_prefetching_in_linear_mode = + dceip->scatter_gather_lines_of_pte_prefetching_in_linear_mode = 32; - dceip.display_write_back420_luma_mcifwr_buffer_size = 12288; - dceip.display_write_back420_chroma_mcifwr_buffer_size = 8192; - dceip.request_efficiency = bw_frc_to_fixed(8, 10); - dceip.dispclk_per_request = bw_int_to_fixed(2); - dceip.dispclk_ramping_factor = bw_frc_to_fixed(105, 100); - dceip.display_pipe_throughput_factor = bw_frc_to_fixed(105, 100); - dceip.scatter_gather_pte_request_rows_in_tiling_mode = 2; - dceip.mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0); + dceip->display_write_back420_luma_mcifwr_buffer_size = 12288; + dceip->display_write_back420_chroma_mcifwr_buffer_size = 8192; + dceip->request_efficiency = bw_frc_to_fixed(8, 10); + dceip->dispclk_per_request = bw_int_to_fixed(2); + dceip->dispclk_ramping_factor = bw_frc_to_fixed(105, 100); + dceip->display_pipe_throughput_factor = bw_frc_to_fixed(105, 100); + dceip->scatter_gather_pte_request_rows_in_tiling_mode = 2; + dceip->mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0); break; default: break; } - *bw_dceip = dceip; - *bw_vbios = vbios; + *bw_dceip = *dceip; + *bw_vbios = *vbios; + kfree(dceip); + kfree(vbios); } /* diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c index f7c728d4f50a..7d6c68c5dea9 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c @@ -125,87 +125,136 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p { struct hw_asic_id asic_id = ctx->asic_id; - struct clk_mgr_internal *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL); - - if (clk_mgr == NULL) { - BREAK_TO_DEBUGGER(); - return NULL; - } - switch (asic_id.chip_family) { #if defined(CONFIG_DRM_AMD_DC_SI) - case FAMILY_SI: + case FAMILY_SI: { + struct clk_mgr_internal *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL); + + if (clk_mgr == NULL) { + BREAK_TO_DEBUGGER(); + return NULL; + } dce60_clk_mgr_construct(ctx, clk_mgr); - break; + dce_clk_mgr_construct(ctx, clk_mgr); + return &clk_mgr->base; + } #endif case FAMILY_CI: - case FAMILY_KV: + case FAMILY_KV: { + struct clk_mgr_internal *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL); + + if (clk_mgr == NULL) { + BREAK_TO_DEBUGGER(); + return NULL; + } dce_clk_mgr_construct(ctx, clk_mgr); - break; - case FAMILY_CZ: + return &clk_mgr->base; + } + case FAMILY_CZ: { + struct clk_mgr_internal *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL); + + if (clk_mgr == NULL) { + BREAK_TO_DEBUGGER(); + return NULL; + } dce110_clk_mgr_construct(ctx, clk_mgr); - break; - case FAMILY_VI: + return &clk_mgr->base; + } + case FAMILY_VI: { + struct clk_mgr_internal *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL); + + if (clk_mgr == NULL) { + BREAK_TO_DEBUGGER(); + return NULL; + } if (ASIC_REV_IS_TONGA_P(asic_id.hw_internal_rev) || ASIC_REV_IS_FIJI_P(asic_id.hw_internal_rev)) { dce_clk_mgr_construct(ctx, clk_mgr); - break; + return &clk_mgr->base; } if (ASIC_REV_IS_POLARIS10_P(asic_id.hw_internal_rev) || ASIC_REV_IS_POLARIS11_M(asic_id.hw_internal_rev) || ASIC_REV_IS_POLARIS12_V(asic_id.hw_internal_rev)) { dce112_clk_mgr_construct(ctx, clk_mgr); - break; + return &clk_mgr->base; } if (ASIC_REV_IS_VEGAM(asic_id.hw_internal_rev)) { dce112_clk_mgr_construct(ctx, clk_mgr); - break; + return &clk_mgr->base; + } + return &clk_mgr->base; + } + case FAMILY_AI: { + struct clk_mgr_internal *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL); + + if (clk_mgr == NULL) { + BREAK_TO_DEBUGGER(); + return NULL; } - break; - case FAMILY_AI: if (ASICREV_IS_VEGA20_P(asic_id.hw_internal_rev)) dce121_clk_mgr_construct(ctx, clk_mgr); else dce120_clk_mgr_construct(ctx, clk_mgr); - break; - + return &clk_mgr->base; + } #if defined(CONFIG_DRM_AMD_DC_DCN) - case FAMILY_RV: + case FAMILY_RV: { + struct clk_mgr_internal *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL); + + if (clk_mgr == NULL) { + BREAK_TO_DEBUGGER(); + return NULL; + } + if (ASICREV_IS_RENOIR(asic_id.hw_internal_rev)) { rn_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); - break; + return &clk_mgr->base; } if (ASICREV_IS_GREEN_SARDINE(asic_id.hw_internal_rev)) { rn_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); - break; + return &clk_mgr->base; } if (ASICREV_IS_RAVEN2(asic_id.hw_internal_rev)) { rv2_clk_mgr_construct(ctx, clk_mgr, pp_smu); - break; + return &clk_mgr->base; } if (ASICREV_IS_RAVEN(asic_id.hw_internal_rev) || ASICREV_IS_PICASSO(asic_id.hw_internal_rev)) { rv1_clk_mgr_construct(ctx, clk_mgr, pp_smu); - break; + return &clk_mgr->base; } - break; + return &clk_mgr->base; + } + case FAMILY_NV: { + struct clk_mgr_internal *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL); - case FAMILY_NV: + if (clk_mgr == NULL) { + BREAK_TO_DEBUGGER(); + return NULL; + } if (ASICREV_IS_SIENNA_CICHLID_P(asic_id.hw_internal_rev)) { dcn3_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); - break; + return &clk_mgr->base; } if (ASICREV_IS_DIMGREY_CAVEFISH_P(asic_id.hw_internal_rev)) { dcn3_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); - break; + return &clk_mgr->base; } dcn20_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); - break; - + return &clk_mgr->base; + } case FAMILY_VGH: - if (ASICREV_IS_VANGOGH(asic_id.hw_internal_rev)) + if (ASICREV_IS_VANGOGH(asic_id.hw_internal_rev)) { + struct clk_mgr_vgh *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL); + + if (clk_mgr == NULL) { + BREAK_TO_DEBUGGER(); + return NULL; + } vg_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); + return &clk_mgr->base.base; + } break; #endif default: @@ -213,7 +262,7 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p break; } - return &clk_mgr->base; + return NULL; } void dc_destroy_clk_mgr(struct clk_mgr *clk_mgr_base) @@ -226,6 +275,9 @@ void dc_destroy_clk_mgr(struct clk_mgr *clk_mgr_base) if (ASICREV_IS_SIENNA_CICHLID_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) { dcn3_clk_mgr_destroy(clk_mgr); } + if (ASICREV_IS_DIMGREY_CAVEFISH_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) { + dcn3_clk_mgr_destroy(clk_mgr); + } break; case FAMILY_VGH: diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c index 01b1853b7750..887a54246bde 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c @@ -797,7 +797,18 @@ static struct wm_table lpddr4_wm_table_rn = { }, } }; +static unsigned int find_socclk_for_voltage(struct dpm_clocks *clock_table, unsigned int voltage) +{ + int i; + + for (i = 0; i < PP_SMU_NUM_SOCCLK_DPM_LEVELS; i++) { + if (clock_table->SocClocks[i].Vol == voltage) + return clock_table->SocClocks[i].Freq; + } + ASSERT(0); + return 0; +} static unsigned int find_dcfclk_for_voltage(struct dpm_clocks *clock_table, unsigned int voltage) { int i; @@ -841,6 +852,8 @@ static void rn_clk_mgr_helper_populate_bw_params(struct clk_bw_params *bw_params bw_params->clk_table.entries[i].memclk_mhz = clock_table->MemClocks[j].Freq; bw_params->clk_table.entries[i].voltage = clock_table->FClocks[j].Vol; bw_params->clk_table.entries[i].dcfclk_mhz = find_dcfclk_for_voltage(clock_table, clock_table->FClocks[j].Vol); + bw_params->clk_table.entries[i].socclk_mhz = find_socclk_for_voltage(clock_table, + bw_params->clk_table.entries[i].voltage); } bw_params->vram_type = bios_info->memory_type; diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c index 81ea5d3a1947..577e7f97045e 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c @@ -432,6 +432,12 @@ static void dcn3_get_memclk_states_from_smu(struct clk_mgr *clk_mgr_base) clk_mgr->base.ctx->dc, clk_mgr_base->bw_params); } +static bool dcn3_is_smu_prsent(struct clk_mgr *clk_mgr_base) +{ + struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); + return clk_mgr->smu_present; +} + static bool dcn3_are_clock_states_equal(struct dc_clocks *a, struct dc_clocks *b) { @@ -494,6 +500,7 @@ static struct clk_mgr_funcs dcn3_funcs = { .are_clock_states_equal = dcn3_are_clock_states_equal, .enable_pme_wa = dcn3_enable_pme_wa, .notify_link_rate_change = dcn30_notify_link_rate_change, + .is_smu_present = dcn3_is_smu_prsent }; static void dcn3_init_clocks_fpga(struct clk_mgr *clk_mgr) diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/dcn301_smu.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/dcn301_smu.c index 68942bbc7472..07774fa2c2cf 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/dcn301_smu.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/dcn301_smu.c @@ -113,10 +113,13 @@ int dcn301_smu_send_msg_with_param( int dcn301_smu_get_smu_version(struct clk_mgr_internal *clk_mgr) { - return dcn301_smu_send_msg_with_param( - clk_mgr, - VBIOSSMC_MSG_GetSmuVersion, - 0); + int smu_version = dcn301_smu_send_msg_with_param(clk_mgr, + VBIOSSMC_MSG_GetSmuVersion, + 0); + + DC_LOG_DEBUG("%s %x\n", __func__, smu_version); + + return smu_version; } @@ -124,6 +127,8 @@ int dcn301_smu_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_dispc { int actual_dispclk_set_mhz = -1; + DC_LOG_DEBUG("%s(%d)\n", __func__, requested_dispclk_khz); + /* Unit of SMU msg parameter is Mhz */ actual_dispclk_set_mhz = dcn301_smu_send_msg_with_param( clk_mgr, @@ -137,6 +142,8 @@ int dcn301_smu_set_dprefclk(struct clk_mgr_internal *clk_mgr) { int actual_dprefclk_set_mhz = -1; + DC_LOG_DEBUG("%s %d\n", __func__, clk_mgr->base.dprefclk_khz / 1000); + actual_dprefclk_set_mhz = dcn301_smu_send_msg_with_param( clk_mgr, VBIOSSMC_MSG_SetDprefclkFreq, @@ -151,6 +158,8 @@ int dcn301_smu_set_hard_min_dcfclk(struct clk_mgr_internal *clk_mgr, int request { int actual_dcfclk_set_mhz = -1; + DC_LOG_DEBUG("%s(%d)\n", __func__, requested_dcfclk_khz); + actual_dcfclk_set_mhz = dcn301_smu_send_msg_with_param( clk_mgr, VBIOSSMC_MSG_SetHardMinDcfclkByFreq, @@ -163,6 +172,8 @@ int dcn301_smu_set_min_deep_sleep_dcfclk(struct clk_mgr_internal *clk_mgr, int r { int actual_min_ds_dcfclk_mhz = -1; + DC_LOG_DEBUG("%s(%d)\n", __func__, requested_min_ds_dcfclk_khz); + actual_min_ds_dcfclk_mhz = dcn301_smu_send_msg_with_param( clk_mgr, VBIOSSMC_MSG_SetMinDeepSleepDcfclk, @@ -175,6 +186,8 @@ int dcn301_smu_set_dppclk(struct clk_mgr_internal *clk_mgr, int requested_dpp_kh { int actual_dppclk_set_mhz = -1; + DC_LOG_DEBUG("%s(%d)\n", __func__, requested_dpp_khz); + actual_dppclk_set_mhz = dcn301_smu_send_msg_with_param( clk_mgr, VBIOSSMC_MSG_SetDppclkFreq, @@ -187,6 +200,8 @@ void dcn301_smu_set_display_idle_optimization(struct clk_mgr_internal *clk_mgr, { //TODO: Work with smu team to define optimization options. + DC_LOG_DEBUG("%s(%x)\n", __func__, idle_info); + dcn301_smu_send_msg_with_param( clk_mgr, VBIOSSMC_MSG_SetDisplayIdleOptimizations, @@ -202,6 +217,8 @@ void dcn301_smu_enable_phy_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr, bool idle_info.idle_info.phy_ref_clk_off = 1; } + DC_LOG_DEBUG("%s(%d)\n", __func__, enable); + dcn301_smu_send_msg_with_param( clk_mgr, VBIOSSMC_MSG_SetDisplayIdleOptimizations, @@ -218,12 +235,16 @@ void dcn301_smu_enable_pme_wa(struct clk_mgr_internal *clk_mgr) void dcn301_smu_set_dram_addr_high(struct clk_mgr_internal *clk_mgr, uint32_t addr_high) { + DC_LOG_DEBUG("%s(%x)\n", __func__, addr_high); + dcn301_smu_send_msg_with_param(clk_mgr, VBIOSSMC_MSG_SetVbiosDramAddrHigh, addr_high); } void dcn301_smu_set_dram_addr_low(struct clk_mgr_internal *clk_mgr, uint32_t addr_low) { + DC_LOG_DEBUG("%s(%x)\n", __func__, addr_low); + dcn301_smu_send_msg_with_param(clk_mgr, VBIOSSMC_MSG_SetVbiosDramAddrLow, addr_low); } diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c index aadb801447a7..c636b589d69d 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c @@ -32,9 +32,8 @@ // For dcn20_update_clocks_update_dpp_dto #include "dcn20/dcn20_clk_mgr.h" - - #include "vg_clk_mgr.h" +#include "dcn301_smu.h" #include "reg_helper.h" #include "core_types.h" #include "dm_helpers.h" @@ -50,11 +49,14 @@ /* Macros */ +#define TO_CLK_MGR_VGH(clk_mgr)\ + container_of(clk_mgr, struct clk_mgr_vgh, base) + #define REG(reg_name) \ (CLK_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name) /* TODO: evaluate how to lower or disable all dcn clocks in screen off case */ -int vg_get_active_display_cnt_wa( +static int vg_get_active_display_cnt_wa( struct dc *dc, struct dc_state *context) { @@ -134,13 +136,13 @@ void vg_update_clocks(struct clk_mgr *clk_mgr_base, } } - if (should_set_clock(safe_to_lower, new_clocks->dcfclk_khz, clk_mgr_base->clks.dcfclk_khz)) { + if (should_set_clock(safe_to_lower, new_clocks->dcfclk_khz, clk_mgr_base->clks.dcfclk_khz) && !dc->debug.disable_min_fclk) { clk_mgr_base->clks.dcfclk_khz = new_clocks->dcfclk_khz; dcn301_smu_set_hard_min_dcfclk(clk_mgr, clk_mgr_base->clks.dcfclk_khz); } if (should_set_clock(safe_to_lower, - new_clocks->dcfclk_deep_sleep_khz, clk_mgr_base->clks.dcfclk_deep_sleep_khz)) { + new_clocks->dcfclk_deep_sleep_khz, clk_mgr_base->clks.dcfclk_deep_sleep_khz) && !dc->debug.disable_min_fclk) { clk_mgr_base->clks.dcfclk_deep_sleep_khz = new_clocks->dcfclk_deep_sleep_khz; dcn301_smu_set_min_deep_sleep_dcfclk(clk_mgr, clk_mgr_base->clks.dcfclk_deep_sleep_khz); } @@ -377,7 +379,7 @@ void vg_get_clk_states(struct clk_mgr *clk_mgr_base, struct clk_states *s) s->dprefclk_khz = sb.dprefclk * 1000; } -void vg_enable_pme_wa(struct clk_mgr *clk_mgr_base) +static void vg_enable_pme_wa(struct clk_mgr *clk_mgr_base) { struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); @@ -449,15 +451,16 @@ static void vg_build_watermark_ranges(struct clk_bw_params *bw_params, struct wa } -void vg_notify_wm_ranges(struct clk_mgr *clk_mgr_base) +static void vg_notify_wm_ranges(struct clk_mgr *clk_mgr_base) { struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); - struct watermarks *table = clk_mgr_base->smu_wm_set.wm_set; + struct clk_mgr_vgh *clk_mgr_vgh = TO_CLK_MGR_VGH(clk_mgr); + struct watermarks *table = clk_mgr_vgh->smu_wm_set.wm_set; if (!clk_mgr->smu_ver) return; - if (!table || clk_mgr_base->smu_wm_set.mc_address.quad_part == 0) + if (!table || clk_mgr_vgh->smu_wm_set.mc_address.quad_part == 0) return; memset(table, 0, sizeof(*table)); @@ -465,9 +468,9 @@ void vg_notify_wm_ranges(struct clk_mgr *clk_mgr_base) vg_build_watermark_ranges(clk_mgr_base->bw_params, table); dcn301_smu_set_dram_addr_high(clk_mgr, - clk_mgr_base->smu_wm_set.mc_address.high_part); + clk_mgr_vgh->smu_wm_set.mc_address.high_part); dcn301_smu_set_dram_addr_low(clk_mgr, - clk_mgr_base->smu_wm_set.mc_address.low_part); + clk_mgr_vgh->smu_wm_set.mc_address.low_part); dcn301_smu_transfer_wm_table_dram_2_smu(clk_mgr); } @@ -625,7 +628,7 @@ static unsigned int find_dcfclk_for_voltage(const struct vg_dpm_clocks *clock_ta return 0; } -void vg_clk_mgr_helper_populate_bw_params( +static void vg_clk_mgr_helper_populate_bw_params( struct clk_mgr_internal *clk_mgr, struct integrated_info *bios_info, const struct vg_dpm_clocks *clock_table) @@ -703,7 +706,7 @@ static struct vg_dpm_clocks dummy_clocks = { static struct watermarks dummy_wms = { 0 }; -void vg_get_dpm_table_from_smu(struct clk_mgr_internal *clk_mgr, +static void vg_get_dpm_table_from_smu(struct clk_mgr_internal *clk_mgr, struct smu_dpm_clks *smu_dpm_clks) { struct vg_dpm_clocks *table = smu_dpm_clks->dpm_clks; @@ -725,39 +728,39 @@ void vg_get_dpm_table_from_smu(struct clk_mgr_internal *clk_mgr, void vg_clk_mgr_construct( struct dc_context *ctx, - struct clk_mgr_internal *clk_mgr, + struct clk_mgr_vgh *clk_mgr, struct pp_smu_funcs *pp_smu, struct dccg *dccg) { struct smu_dpm_clks smu_dpm_clks = { 0 }; - clk_mgr->base.ctx = ctx; - clk_mgr->base.funcs = &vg_funcs; + clk_mgr->base.base.ctx = ctx; + clk_mgr->base.base.funcs = &vg_funcs; - clk_mgr->pp_smu = pp_smu; + clk_mgr->base.pp_smu = pp_smu; - clk_mgr->dccg = dccg; - clk_mgr->dfs_bypass_disp_clk = 0; + clk_mgr->base.dccg = dccg; + clk_mgr->base.dfs_bypass_disp_clk = 0; - clk_mgr->dprefclk_ss_percentage = 0; - clk_mgr->dprefclk_ss_divider = 1000; - clk_mgr->ss_on_dprefclk = false; - clk_mgr->dfs_ref_freq_khz = 48000; + clk_mgr->base.dprefclk_ss_percentage = 0; + clk_mgr->base.dprefclk_ss_divider = 1000; + clk_mgr->base.ss_on_dprefclk = false; + clk_mgr->base.dfs_ref_freq_khz = 48000; - clk_mgr->base.smu_wm_set.wm_set = (struct watermarks *)dm_helpers_allocate_gpu_mem( - clk_mgr->base.ctx, + clk_mgr->smu_wm_set.wm_set = (struct watermarks *)dm_helpers_allocate_gpu_mem( + clk_mgr->base.base.ctx, DC_MEM_ALLOC_TYPE_FRAME_BUFFER, sizeof(struct watermarks), - &clk_mgr->base.smu_wm_set.mc_address.quad_part); + &clk_mgr->smu_wm_set.mc_address.quad_part); - if (clk_mgr->base.smu_wm_set.wm_set == 0) { - clk_mgr->base.smu_wm_set.wm_set = &dummy_wms; - clk_mgr->base.smu_wm_set.mc_address.quad_part = 0; + if (clk_mgr->smu_wm_set.wm_set == 0) { + clk_mgr->smu_wm_set.wm_set = &dummy_wms; + clk_mgr->smu_wm_set.mc_address.quad_part = 0; } - ASSERT(clk_mgr->base.smu_wm_set.wm_set); + ASSERT(clk_mgr->smu_wm_set.wm_set); smu_dpm_clks.dpm_clks = (struct vg_dpm_clocks *)dm_helpers_allocate_gpu_mem( - clk_mgr->base.ctx, + clk_mgr->base.base.ctx, DC_MEM_ALLOC_TYPE_FRAME_BUFFER, sizeof(struct vg_dpm_clocks), &smu_dpm_clks.mc_address.quad_part); @@ -771,21 +774,21 @@ void vg_clk_mgr_construct( if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) { vg_funcs.update_clocks = dcn2_update_clocks_fpga; - clk_mgr->base.dentist_vco_freq_khz = 3600000; + clk_mgr->base.base.dentist_vco_freq_khz = 3600000; } else { struct clk_log_info log_info = {0}; - clk_mgr->smu_ver = dcn301_smu_get_smu_version(clk_mgr); + clk_mgr->base.smu_ver = dcn301_smu_get_smu_version(&clk_mgr->base); - if (clk_mgr->smu_ver) - clk_mgr->smu_present = true; + if (clk_mgr->base.smu_ver) + clk_mgr->base.smu_present = true; /* TODO: Check we get what we expect during bringup */ - clk_mgr->base.dentist_vco_freq_khz = get_vco_frequency_from_reg(clk_mgr); + clk_mgr->base.base.dentist_vco_freq_khz = get_vco_frequency_from_reg(&clk_mgr->base); /* in case we don't get a value from the register, use default */ - if (clk_mgr->base.dentist_vco_freq_khz == 0) - clk_mgr->base.dentist_vco_freq_khz = 3600000; + if (clk_mgr->base.base.dentist_vco_freq_khz == 0) + clk_mgr->base.base.dentist_vco_freq_khz = 3600000; if (ctx->dc_bios->integrated_info->memory_type == LpDdr5MemType) { vg_bw_params.wm_table = lpddr5_wm_table; @@ -793,36 +796,38 @@ void vg_clk_mgr_construct( vg_bw_params.wm_table = ddr4_wm_table; } /* Saved clocks configured at boot for debug purposes */ - vg_dump_clk_registers(&clk_mgr->base.boot_snapshot, &clk_mgr->base, &log_info); + vg_dump_clk_registers(&clk_mgr->base.base.boot_snapshot, &clk_mgr->base.base, &log_info); } - clk_mgr->base.dprefclk_khz = 600000; - dce_clock_read_ss_info(clk_mgr); + clk_mgr->base.base.dprefclk_khz = 600000; + dce_clock_read_ss_info(&clk_mgr->base); - clk_mgr->base.bw_params = &vg_bw_params; + clk_mgr->base.base.bw_params = &vg_bw_params; - vg_get_dpm_table_from_smu(clk_mgr, &smu_dpm_clks); + vg_get_dpm_table_from_smu(&clk_mgr->base, &smu_dpm_clks); if (ctx->dc_bios && ctx->dc_bios->integrated_info) { vg_clk_mgr_helper_populate_bw_params( - clk_mgr, + &clk_mgr->base, ctx->dc_bios->integrated_info, smu_dpm_clks.dpm_clks); } if (smu_dpm_clks.dpm_clks && smu_dpm_clks.mc_address.quad_part != 0) - dm_helpers_free_gpu_mem(clk_mgr->base.ctx, DC_MEM_ALLOC_TYPE_FRAME_BUFFER, + dm_helpers_free_gpu_mem(clk_mgr->base.base.ctx, DC_MEM_ALLOC_TYPE_FRAME_BUFFER, smu_dpm_clks.dpm_clks); /* - if (!IS_FPGA_MAXIMUS_DC(ctx->dce_environment) && clk_mgr->smu_ver) { + if (!IS_FPGA_MAXIMUS_DC(ctx->dce_environment) && clk_mgr->base.smu_ver) { enable powerfeatures when displaycount goes to 0 dcn301_smu_enable_phy_refclk_pwrdwn(clk_mgr, !debug->disable_48mhz_pwrdwn); } */ } -void vg_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr) +void vg_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr_int) { - if (clk_mgr->base.smu_wm_set.wm_set && clk_mgr->base.smu_wm_set.mc_address.quad_part != 0) - dm_helpers_free_gpu_mem(clk_mgr->base.ctx, DC_MEM_ALLOC_TYPE_FRAME_BUFFER, - clk_mgr->base.smu_wm_set.wm_set); + struct clk_mgr_vgh *clk_mgr = TO_CLK_MGR_VGH(clk_mgr_int); + + if (clk_mgr->smu_wm_set.wm_set && clk_mgr->smu_wm_set.mc_address.quad_part != 0) + dm_helpers_free_gpu_mem(clk_mgr_int->base.ctx, DC_MEM_ALLOC_TYPE_FRAME_BUFFER, + clk_mgr->smu_wm_set.wm_set); } diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.h index b5115b3123a1..7255477307f1 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.h +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.h @@ -25,29 +25,25 @@ #ifndef __VG_CLK_MGR_H__ #define __VG_CLK_MGR_H__ +#include "clk_mgr_internal.h" -int vg_get_active_display_cnt_wa( - struct dc *dc, - struct dc_state *context); +struct watermarks; -void vg_enable_pme_wa(struct clk_mgr *clk_mgr_base); +struct smu_watermark_set { + struct watermarks *wm_set; + union large_integer mc_address; +}; + +struct clk_mgr_vgh { + struct clk_mgr_internal base; + struct smu_watermark_set smu_wm_set; +}; void vg_clk_mgr_construct(struct dc_context *ctx, - struct clk_mgr_internal *clk_mgr, + struct clk_mgr_vgh *clk_mgr, struct pp_smu_funcs *pp_smu, struct dccg *dccg); void vg_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr); -#include "dcn301_smu.h" -void vg_notify_wm_ranges(struct clk_mgr *clk_mgr_base); - -void vg_get_dpm_table_from_smu(struct clk_mgr_internal *clk_mgr, - struct smu_dpm_clks *smu_dpm_clks); - -void vg_clk_mgr_helper_populate_bw_params( - struct clk_mgr_internal *clk_mgr, - struct integrated_info *bios_info, - const struct vg_dpm_clocks *clock_table); - #endif //__VG_CLK_MGR_H__ diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 8e6c815b55d2..8f0a13807d05 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -49,9 +49,11 @@ #include "timing_generator.h" #include "abm.h" #include "virtual/virtual_link_encoder.h" +#include "hubp.h" #include "link_hwss.h" #include "link_encoder.h" +#include "link_enc_cfg.h" #include "dc_link_ddc.h" #include "dm_helpers.h" @@ -304,7 +306,10 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc, int i = 0; bool ret = false; - stream->adjust = *adjust; + stream->adjust.v_total_max = adjust->v_total_max; + stream->adjust.v_total_mid = adjust->v_total_mid; + stream->adjust.v_total_mid_frame_num = adjust->v_total_mid_frame_num; + stream->adjust.v_total_min = adjust->v_total_min; for (i = 0; i < MAX_PIPES; i++) { struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i]; @@ -312,10 +317,7 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc, if (pipe->stream == stream && pipe->stream_res.tg) { dc->hwss.set_drr(&pipe, 1, - adjust->v_total_min, - adjust->v_total_max, - adjust->v_total_mid, - adjust->v_total_mid_frame_num); + *adjust); ret = true; } @@ -870,6 +872,9 @@ static bool dc_construct(struct dc *dc, if (!create_links(dc, init_params->num_virtual_links)) goto fail; + /* Initialise DIG link encoder resource tracking variables. */ + link_enc_cfg_init(dc, dc->current_state); + return true; fail: @@ -2091,6 +2096,10 @@ static enum surface_update_type check_update_surfaces_for_stream( if (stream_status == NULL || stream_status->plane_count != surface_count) overall_type = UPDATE_TYPE_FULL; + if (stream_update && stream_update->pending_test_pattern) { + overall_type = UPDATE_TYPE_FULL; + } + /* some stream updates require passive update */ if (stream_update) { union stream_update_flags *su_flags = &stream_update->stream->update_flags; @@ -2390,6 +2399,8 @@ static void copy_stream_update_to_stream(struct dc *dc, if (update->dither_option) stream->dither_option = *update->dither_option; + if (update->pending_test_pattern) + stream->test_pattern = *update->pending_test_pattern; /* update current stream with writeback info */ if (update->wb_update) { int i; @@ -2485,6 +2496,7 @@ static void commit_planes_do_stream_update(struct dc *dc, } } + /* Full fe update*/ if (update_type == UPDATE_TYPE_FAST) continue; @@ -2492,6 +2504,15 @@ static void commit_planes_do_stream_update(struct dc *dc, if (stream_update->dsc_config) dp_update_dsc_config(pipe_ctx); + if (stream_update->pending_test_pattern) { + dc_link_dp_set_test_pattern(stream->link, + stream->test_pattern.type, + stream->test_pattern.color_space, + stream->test_pattern.p_link_settings, + stream->test_pattern.p_custom_pattern, + stream->test_pattern.cust_pattern_size); + } + if (stream_update->dpms_off) { if (*stream_update->dpms_off) { core_link_disable_stream(pipe_ctx); @@ -2578,6 +2599,17 @@ static void commit_planes_for_stream(struct dc *dc, } } +#ifdef CONFIG_DRM_AMD_DC_DCN + if (stream->test_pattern.type != DP_TEST_PATTERN_VIDEO_MODE) { + struct pipe_ctx *mpcc_pipe; + struct pipe_ctx *odm_pipe; + + for (mpcc_pipe = top_pipe_to_program; mpcc_pipe; mpcc_pipe = mpcc_pipe->bottom_pipe) + for (odm_pipe = mpcc_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) + odm_pipe->ttu_regs.min_ttu_vblank = MAX_TTU; + } +#endif + if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed) if (top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) { if (should_use_dmub_lock(stream->link)) { @@ -2784,6 +2816,9 @@ static void commit_planes_for_stream(struct dc *dc, for (j = 0; j < dc->res_pool->pipe_count; j++) { struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; + if (!pipe_ctx->plane_state) + continue; + if (pipe_ctx->bottom_pipe || pipe_ctx->next_odm_pipe || !pipe_ctx->stream || pipe_ctx->stream != stream || !pipe_ctx->plane_state->update_flags.bits.addr_update) @@ -3225,6 +3260,10 @@ void dc_allow_idle_optimizations(struct dc *dc, bool allow) if (dc->debug.disable_idle_power_optimizations) return; + if (dc->clk_mgr->funcs->is_smu_present) + if (!dc->clk_mgr->funcs->is_smu_present(dc->clk_mgr)) + return; + if (allow == dc->idle_optimizations_allowed) return; 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 f9a33dc52c45..29bc2874f6a7 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -92,11 +92,14 @@ static void dc_link_destruct(struct dc_link *link) link->panel_cntl->funcs->destroy(&link->panel_cntl); if (link->link_enc) { - /* Update link encoder tracking variables. These are used for the dynamic - * assignment of link encoders to streams. + /* Update link encoder resource tracking variables. These are used for + * the dynamic assignment of link encoders to streams. Virtual links + * are not assigned encoder resources on creation. */ - link->dc->res_pool->link_encoders[link->link_enc->preferred_engine] = NULL; - link->dc->res_pool->dig_link_enc_count--; + if (link->link_id.id != CONNECTOR_ID_VIRTUAL) { + link->dc->res_pool->link_encoders[link->eng_id - ENGINE_ID_DIGA] = NULL; + link->dc->res_pool->dig_link_enc_count--; + } link->link_enc->funcs->destroy(&link->link_enc); } @@ -1407,6 +1410,8 @@ static bool dc_link_construct(struct dc_link *link, link->link_id = bios->funcs->get_connector_id(bios, init_params->connector_index); + link->ep_type = DISPLAY_ENDPOINT_PHY; + DC_LOG_DC("BIOS object table - link_id: %d", link->link_id.id); if (bios->funcs->get_disp_connector_caps_info) { @@ -1506,10 +1511,12 @@ static bool dc_link_construct(struct dc_link *link, (link->link_id.id == CONNECTOR_ID_EDP || link->link_id.id == CONNECTOR_ID_LVDS)) { panel_cntl_init_data.ctx = dc_ctx; - panel_cntl_init_data.inst = link->link_index; + panel_cntl_init_data.inst = + panel_cntl_init_data.ctx->dc_edp_id_count; link->panel_cntl = link->dc->res_pool->funcs->panel_cntl_create( &panel_cntl_init_data); + panel_cntl_init_data.ctx->dc_edp_id_count++; if (link->panel_cntl == NULL) { DC_ERROR("Failed to create link panel_cntl!\n"); @@ -1541,7 +1548,8 @@ static bool dc_link_construct(struct dc_link *link, /* Update link encoder tracking variables. These are used for the dynamic * assignment of link encoders to streams. */ - link->dc->res_pool->link_encoders[link->link_enc->preferred_engine] = link->link_enc; + link->eng_id = link->link_enc->preferred_engine; + link->dc->res_pool->link_encoders[link->eng_id - ENGINE_ID_DIGA] = link->link_enc; link->dc->res_pool->dig_link_enc_count++; link->link_enc_hw_inst = link->link_enc->transmitter; @@ -2883,8 +2891,8 @@ static struct fixed31_32 get_pbn_per_slot(struct dc_stream_state *stream) static struct fixed31_32 get_pbn_from_bw_in_kbps(uint64_t kbps) { struct fixed31_32 peak_kbps; - uint32_t numerator; - uint32_t denominator; + uint32_t numerator = 0; + uint32_t denominator = 1; /* * margin 5300ppm + 300ppm ~ 0.6% as per spec, factor is 1.006 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 47e6c33f73cb..7d2e433c2275 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 @@ -284,7 +284,7 @@ static uint8_t dc_dp_initialize_scrambling_data_symbols( static inline bool is_repeater(struct dc_link *link, uint32_t offset) { - return (link->lttpr_non_transparent_mode && offset != 0); + return (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) && (offset != 0); } static void dpcd_set_lt_pattern_and_lane_settings( @@ -1072,7 +1072,7 @@ static enum link_training_result perform_clock_recovery_sequence( /* 3. wait receiver to lock-on*/ wait_time_microsec = lt_settings->cr_pattern_time; - if (link->lttpr_non_transparent_mode) + if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) wait_time_microsec = TRAINING_AUX_RD_INTERVAL; wait_for_training_aux_rd_interval( @@ -1098,11 +1098,13 @@ static enum link_training_result perform_clock_recovery_sequence( if (is_max_vs_reached(lt_settings)) break; - /* 7. same voltage*/ - /* Note: VS same for all lanes, - * so comparing first lane is sufficient*/ - if (lt_settings->lane_settings[0].VOLTAGE_SWING == + /* 7. same lane settings*/ + /* Note: settings are the same for all lanes, + * so comparing first lane is sufficient*/ + if ((lt_settings->lane_settings[0].VOLTAGE_SWING == req_settings.lane_settings[0].VOLTAGE_SWING) + && (lt_settings->lane_settings[0].PRE_EMPHASIS == + req_settings.lane_settings[0].PRE_EMPHASIS)) retries_cr++; else retries_cr = 0; @@ -1324,7 +1326,17 @@ static uint8_t convert_to_count(uint8_t lttpr_repeater_count) return 0; // invalid value } -static void configure_lttpr_mode(struct dc_link *link) +static void configure_lttpr_mode_transparent(struct dc_link *link) +{ + uint8_t repeater_mode = DP_PHY_REPEATER_MODE_TRANSPARENT; + + core_link_write_dpcd(link, + DP_PHY_REPEATER_MODE, + (uint8_t *)&repeater_mode, + sizeof(repeater_mode)); +} + +static void configure_lttpr_mode_non_transparent(struct dc_link *link) { /* aux timeout is already set to extended */ /* RESET/SET lttpr mode to enable non transparent mode */ @@ -1344,7 +1356,7 @@ static void configure_lttpr_mode(struct dc_link *link) link->dpcd_caps.lttpr_caps.mode = repeater_mode; } - if (link->lttpr_non_transparent_mode) { + if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) { DC_LOG_HW_LINK_TRAINING("%s\n Set LTTPR to Non Transparent Mode\n", __func__); @@ -1560,8 +1572,10 @@ enum link_training_result dc_link_dp_perform_link_training( <_settings); /* Configure lttpr mode */ - if (link->lttpr_non_transparent_mode) - configure_lttpr_mode(link); + if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) + configure_lttpr_mode_non_transparent(link); + else if (link->lttpr_mode == LTTPR_MODE_TRANSPARENT) + configure_lttpr_mode_transparent(link); if (link->ctx->dc->work_arounds.lt_early_cr_pattern) start_clock_recovery_pattern_early(link, <_settings, DPRX); @@ -1576,7 +1590,7 @@ enum link_training_result dc_link_dp_perform_link_training( dp_set_fec_ready(link, fec_enable); - if (link->lttpr_non_transparent_mode) { + if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) { /* 2. perform link training (set link training done * to false is done as well) @@ -1633,6 +1647,42 @@ enum link_training_result dc_link_dp_perform_link_training( return status; } +static enum dp_panel_mode try_enable_assr(struct dc_stream_state *stream) +{ + struct dc_link *link = stream->link; + enum dp_panel_mode panel_mode = dp_get_panel_mode(link); +#ifdef CONFIG_DRM_AMD_DC_HDCP + struct cp_psp *cp_psp = &stream->ctx->cp_psp; +#endif + + /* ASSR must be supported on the panel */ + if (panel_mode == DP_PANEL_MODE_DEFAULT) + return panel_mode; + + /* eDP or internal DP only */ + if (link->connector_signal != SIGNAL_TYPE_EDP && + !(link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT && + link->is_internal_display)) + return DP_PANEL_MODE_DEFAULT; + +#ifdef CONFIG_DRM_AMD_DC_HDCP + if (cp_psp && cp_psp->funcs.enable_assr) { + if (!cp_psp->funcs.enable_assr(cp_psp->handle, link)) { + /* since eDP implies ASSR on, change panel + * mode to disable ASSR + */ + panel_mode = DP_PANEL_MODE_DEFAULT; + } + } else + panel_mode = DP_PANEL_MODE_DEFAULT; + +#else + /* turn off ASSR if the implementation is not compiled in */ + panel_mode = DP_PANEL_MODE_DEFAULT; +#endif + return panel_mode; +} + bool perform_link_training_with_retries( const struct dc_link_settings *link_setting, bool skip_video_pattern, @@ -1644,7 +1694,7 @@ bool perform_link_training_with_retries( uint8_t delay_between_attempts = LINK_TRAINING_RETRY_DELAY; struct dc_stream_state *stream = pipe_ctx->stream; struct dc_link *link = stream->link; - enum dp_panel_mode panel_mode = dp_get_panel_mode(link); + enum dp_panel_mode panel_mode; /* We need to do this before the link training to ensure the idle pattern in SST * mode will be sent right after the link training @@ -1669,32 +1719,25 @@ bool perform_link_training_with_retries( msleep(delay_dp_power_up_in_ms); } -#ifdef CONFIG_DRM_AMD_DC_HDCP - if (panel_mode == DP_PANEL_MODE_EDP) { - struct cp_psp *cp_psp = &stream->ctx->cp_psp; - - if (cp_psp && cp_psp->funcs.enable_assr) { - if (!cp_psp->funcs.enable_assr(cp_psp->handle, link)) { - /* since eDP implies ASSR on, change panel - * mode to disable ASSR - */ - panel_mode = DP_PANEL_MODE_DEFAULT; - } - } else - panel_mode = DP_PANEL_MODE_DEFAULT; - } -#endif - + panel_mode = try_enable_assr(stream); dp_set_panel_mode(link, panel_mode); + DC_LOG_DETECTION_DP_CAPS("Link: %d ASSR enabled: %d\n", + link->link_index, + panel_mode != DP_PANEL_MODE_DEFAULT); if (link->aux_access_disabled) { dc_link_dp_perform_link_training_skip_aux(link, link_setting); return true; - } else if (dc_link_dp_perform_link_training( - link, - link_setting, - skip_video_pattern) == LINK_TRAINING_SUCCESS) - return true; + } else { + enum link_training_result status = LINK_TRAINING_CR_FAIL_LANE0; + + status = dc_link_dp_perform_link_training( + link, + link_setting, + skip_video_pattern); + if (status == LINK_TRAINING_SUCCESS) + return true; + } /* latest link training still fail, skip delay and keep PHY on */ @@ -1873,7 +1916,7 @@ static struct dc_link_settings get_max_link_cap(struct dc_link *link) * account for lttpr repeaters cap * notes: repeaters do not snoop in the DPRX Capabilities addresses (3.6.3). */ - if (link->lttpr_non_transparent_mode) { + if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) { if (link->dpcd_caps.lttpr_caps.max_lane_count < max_link_cap.lane_count) max_link_cap.lane_count = link->dpcd_caps.lttpr_caps.max_lane_count; @@ -2031,7 +2074,7 @@ bool dp_verify_link_cap( max_link_cap = get_max_link_cap(link); /* Grant extended timeout request */ - if (link->lttpr_non_transparent_mode && link->dpcd_caps.lttpr_caps.max_ext_timeout > 0) { + if ((link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) && (link->dpcd_caps.lttpr_caps.max_ext_timeout > 0)) { uint8_t grant = link->dpcd_caps.lttpr_caps.max_ext_timeout & 0x80; core_link_write_dpcd(link, DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT, &grant, sizeof(grant)); @@ -2782,10 +2825,27 @@ static void dp_test_send_link_test_pattern(struct dc_link *link) enum dp_test_pattern test_pattern; enum dp_test_pattern_color_space test_pattern_color_space = DP_TEST_PATTERN_COLOR_SPACE_UNDEFINED; + enum dc_color_depth requestColorDepth = COLOR_DEPTH_UNDEFINED; + struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx; + struct pipe_ctx *pipe_ctx = NULL; + int i; memset(&dpcd_test_pattern, 0, sizeof(dpcd_test_pattern)); memset(&dpcd_test_params, 0, sizeof(dpcd_test_params)); + for (i = 0; i < MAX_PIPES; i++) { + if (pipes[i].stream == NULL) + continue; + + if (pipes[i].stream->link == link && !pipes[i].top_pipe && !pipes[i].prev_odm_pipe) { + pipe_ctx = &pipes[i]; + break; + } + } + + if (pipe_ctx == NULL) + return; + /* get link test pattern and pattern parameters */ core_link_read_dpcd( link, @@ -2823,6 +2883,33 @@ static void dp_test_send_link_test_pattern(struct dc_link *link) DP_TEST_PATTERN_COLOR_SPACE_YCBCR709 : DP_TEST_PATTERN_COLOR_SPACE_YCBCR601; + switch (dpcd_test_params.bits.BPC) { + case 0: // 6 bits + requestColorDepth = COLOR_DEPTH_666; + break; + case 1: // 8 bits + requestColorDepth = COLOR_DEPTH_888; + break; + case 2: // 10 bits + requestColorDepth = COLOR_DEPTH_101010; + break; + case 3: // 12 bits + requestColorDepth = COLOR_DEPTH_121212; + break; + default: + break; + } + + if (requestColorDepth != COLOR_DEPTH_UNDEFINED + && pipe_ctx->stream->timing.display_color_depth != requestColorDepth) { + DC_LOG_DEBUG("%s: original bpc %d, changing to %d\n", + __func__, + pipe_ctx->stream->timing.display_color_depth, + requestColorDepth); + pipe_ctx->stream->timing.display_color_depth = requestColorDepth; + dp_update_dsc_config(pipe_ctx); + } + dc_link_dp_set_test_pattern( link, test_pattern, @@ -3369,6 +3456,9 @@ static bool retrieve_link_cap(struct dc_link *link) struct dp_sink_hw_fw_revision dp_hw_fw_revision; bool is_lttpr_present = false; const uint32_t post_oui_delay = 30; // 30ms + bool vbios_lttpr_enable = false; + bool vbios_lttpr_interop = false; + struct dc_bios *bios = link->dc->ctx->dc_bios; memset(dpcd_data, '\0', sizeof(dpcd_data)); memset(lttpr_dpcd_data, '\0', sizeof(lttpr_dpcd_data)); @@ -3416,13 +3506,45 @@ static bool retrieve_link_cap(struct dc_link *link) return false; } - if (link->dc->caps.extended_aux_timeout_support && - link->dc->config.allow_lttpr_non_transparent_mode) { + /* Query BIOS to determine if LTTPR functionality is forced on by system */ + if (bios->funcs->get_lttpr_caps) { + enum bp_result bp_query_result; + uint8_t is_vbios_lttpr_enable = 0; + + bp_query_result = bios->funcs->get_lttpr_caps(bios, &is_vbios_lttpr_enable); + vbios_lttpr_enable = (bp_query_result == BP_RESULT_OK) && !!is_vbios_lttpr_enable; + } + + if (bios->funcs->get_lttpr_interop) { + enum bp_result bp_query_result; + uint8_t is_vbios_interop_enabled = 0; + + bp_query_result = bios->funcs->get_lttpr_interop(bios, &is_vbios_interop_enabled); + vbios_lttpr_interop = (bp_query_result == BP_RESULT_OK) && !!is_vbios_interop_enabled; + } + + /* + * Logic to determine LTTPR mode + */ + link->lttpr_mode = LTTPR_MODE_NON_LTTPR; + if (vbios_lttpr_enable && vbios_lttpr_interop) + link->lttpr_mode = LTTPR_MODE_NON_TRANSPARENT; + else if (!vbios_lttpr_enable && vbios_lttpr_interop) { + if (link->dc->config.allow_lttpr_non_transparent_mode) + link->lttpr_mode = LTTPR_MODE_NON_TRANSPARENT; + else + link->lttpr_mode = LTTPR_MODE_TRANSPARENT; + } else if (!vbios_lttpr_enable && !vbios_lttpr_interop) { + if (!link->dc->config.allow_lttpr_non_transparent_mode + || !link->dc->caps.extended_aux_timeout_support) + link->lttpr_mode = LTTPR_MODE_NON_LTTPR; + else + link->lttpr_mode = LTTPR_MODE_NON_TRANSPARENT; + } + + if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT || link->lttpr_mode == LTTPR_MODE_TRANSPARENT) { /* By reading LTTPR capability, RX assumes that we will enable - * LTTPR non transparent if LTTPR is present. - * Therefore, only query LTTPR capability when both LTTPR - * extended aux timeout and - * non transparent mode is supported by hardware + * LTTPR extended aux timeout if LTTPR is present. */ status = core_link_read_dpcd( link, @@ -3462,9 +3584,6 @@ static bool retrieve_link_cap(struct dc_link *link) CONN_DATA_DETECT(link, lttpr_dpcd_data, sizeof(lttpr_dpcd_data), "LTTPR Caps: "); } - /* decide lttpr non transparent mode */ - link->lttpr_non_transparent_mode = is_lttpr_present; - if (!is_lttpr_present) dc_link_aux_try_to_configure_timeout(link->ddc, LINK_AUX_DEFAULT_TIMEOUT_PERIOD); diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c new file mode 100644 index 000000000000..1361b87d86d7 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c @@ -0,0 +1,303 @@ +/* + * Copyright 2021 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#include "link_enc_cfg.h" +#include "resource.h" +#include "dc_link_dp.h" + +/* Check whether stream is supported by DIG link encoders. */ +static bool is_dig_link_enc_stream(struct dc_stream_state *stream) +{ + bool is_dig_stream = false; + struct link_encoder *link_enc = NULL; + int i; + + /* Loop over created link encoder objects. */ + for (i = 0; i < stream->ctx->dc->res_pool->res_cap->num_dig_link_enc; i++) { + link_enc = stream->ctx->dc->res_pool->link_encoders[i]; + + if (link_enc && + ((uint32_t)stream->signal & link_enc->output_signals)) { + if (dc_is_dp_signal(stream->signal)) { + /* DIGs do not support DP2.0 streams with 128b/132b encoding. */ + struct dc_link_settings link_settings = {0}; + + decide_link_settings(stream, &link_settings); + if ((link_settings.link_rate >= LINK_RATE_LOW) && + link_settings.link_rate <= LINK_RATE_HIGH3) { + is_dig_stream = true; + break; + } + } else { + is_dig_stream = true; + break; + } + } + } + + return is_dig_stream; +} + +/* Update DIG link encoder resource tracking variables in dc_state. */ +static void update_link_enc_assignment( + struct dc_state *state, + struct dc_stream_state *stream, + enum engine_id eng_id, + bool add_enc) +{ + int eng_idx; + int stream_idx; + int i; + + if (eng_id != ENGINE_ID_UNKNOWN) { + eng_idx = eng_id - ENGINE_ID_DIGA; + stream_idx = -1; + + /* Index of stream in dc_state used to update correct entry in + * link_enc_assignments table. + */ + for (i = 0; i < state->stream_count; i++) { + if (stream == state->streams[i]) { + stream_idx = i; + break; + } + } + + /* Update link encoder assignments table, link encoder availability + * pool and link encoder assigned to stream in state. + * Add/remove encoder resource to/from stream. + */ + if (stream_idx != -1) { + if (add_enc) { + state->res_ctx.link_enc_assignments[stream_idx] = (struct link_enc_assignment){ + .valid = true, + .ep_id = (struct display_endpoint_id) { + .link_id = stream->link->link_id, + .ep_type = stream->link->ep_type}, + .eng_id = eng_id}; + state->res_ctx.link_enc_avail[eng_idx] = ENGINE_ID_UNKNOWN; + stream->link_enc = stream->ctx->dc->res_pool->link_encoders[eng_idx]; + } else { + state->res_ctx.link_enc_assignments[stream_idx].valid = false; + state->res_ctx.link_enc_avail[eng_idx] = eng_id; + stream->link_enc = NULL; + } + } else { + dm_output_to_console("%s: Stream not found in dc_state.\n", __func__); + } + } +} + +/* Return first available DIG link encoder. */ +static enum engine_id find_first_avail_link_enc( + struct dc_context *ctx, + struct dc_state *state) +{ + enum engine_id eng_id = ENGINE_ID_UNKNOWN; + int i; + + for (i = 0; i < ctx->dc->res_pool->res_cap->num_dig_link_enc; i++) { + eng_id = state->res_ctx.link_enc_avail[i]; + if (eng_id != ENGINE_ID_UNKNOWN) + break; + } + + return eng_id; +} + +/* Return stream using DIG link encoder resource. NULL if unused. */ +static struct dc_stream_state *get_stream_using_link_enc( + struct dc_state *state, + enum engine_id eng_id) +{ + struct dc_stream_state *stream = NULL; + int stream_idx = -1; + int i; + + for (i = 0; i < state->stream_count; i++) { + struct link_enc_assignment assignment = state->res_ctx.link_enc_assignments[i]; + + if (assignment.valid && (assignment.eng_id == eng_id)) { + stream_idx = i; + break; + } + } + + if (stream_idx != -1) + stream = state->streams[stream_idx]; + else + dm_output_to_console("%s: No stream using DIG(%d).\n", __func__, eng_id); + + return stream; +} + +void link_enc_cfg_init( + struct dc *dc, + struct dc_state *state) +{ + int i; + + for (i = 0; i < dc->res_pool->res_cap->num_dig_link_enc; i++) { + if (dc->res_pool->link_encoders[i]) + state->res_ctx.link_enc_avail[i] = (enum engine_id) i; + else + state->res_ctx.link_enc_avail[i] = ENGINE_ID_UNKNOWN; + } +} + +void link_enc_cfg_link_encs_assign( + struct dc *dc, + struct dc_state *state, + struct dc_stream_state *streams[], + uint8_t stream_count) +{ + enum engine_id eng_id = ENGINE_ID_UNKNOWN; + int i; + + /* Release DIG link encoder resources before running assignment algorithm. */ + for (i = 0; i < stream_count; i++) + dc->res_pool->funcs->link_enc_unassign(state, streams[i]); + + /* (a) Assign DIG link encoders to physical (unmappable) endpoints first. */ + for (i = 0; i < stream_count; i++) { + struct dc_stream_state *stream = streams[i]; + + /* Skip stream if not supported by DIG link encoder. */ + if (!is_dig_link_enc_stream(stream)) + continue; + + /* Physical endpoints have a fixed mapping to DIG link encoders. */ + if (!stream->link->is_dig_mapping_flexible) { + eng_id = stream->link->eng_id; + update_link_enc_assignment(state, stream, eng_id, true); + } + } + + /* (b) Then assign encoders to mappable endpoints. */ + eng_id = ENGINE_ID_UNKNOWN; + + for (i = 0; i < stream_count; i++) { + struct dc_stream_state *stream = streams[i]; + + /* Skip stream if not supported by DIG link encoder. */ + if (!is_dig_link_enc_stream(stream)) + continue; + + /* Mappable endpoints have a flexible mapping to DIG link encoders. */ + if (stream->link->is_dig_mapping_flexible) { + eng_id = find_first_avail_link_enc(stream->ctx, state); + update_link_enc_assignment(state, stream, eng_id, true); + } + } +} + +void link_enc_cfg_link_enc_unassign( + struct dc_state *state, + struct dc_stream_state *stream) +{ + enum engine_id eng_id = ENGINE_ID_UNKNOWN; + + /* Only DIG link encoders. */ + if (!is_dig_link_enc_stream(stream)) + return; + + if (stream->link_enc) + eng_id = stream->link_enc->preferred_engine; + + update_link_enc_assignment(state, stream, eng_id, false); +} + +bool link_enc_cfg_is_transmitter_mappable( + struct dc_state *state, + struct link_encoder *link_enc) +{ + bool is_mappable = false; + enum engine_id eng_id = link_enc->preferred_engine; + struct dc_stream_state *stream = get_stream_using_link_enc(state, eng_id); + + if (stream) + is_mappable = stream->link->is_dig_mapping_flexible; + + return is_mappable; +} + +struct dc_link *link_enc_cfg_get_link_using_link_enc( + struct dc_state *state, + enum engine_id eng_id) +{ + struct dc_link *link = NULL; + int stream_idx = -1; + int i; + + for (i = 0; i < state->stream_count; i++) { + struct link_enc_assignment assignment = state->res_ctx.link_enc_assignments[i]; + + if (assignment.valid && (assignment.eng_id == eng_id)) { + stream_idx = i; + break; + } + } + + if (stream_idx != -1) + link = state->streams[stream_idx]->link; + else + dm_output_to_console("%s: No link using DIG(%d).\n", __func__, eng_id); + + return link; +} + +struct link_encoder *link_enc_cfg_get_link_enc_used_by_link( + struct dc_state *state, + struct dc_link *link) +{ + struct link_encoder *link_enc = NULL; + struct display_endpoint_id ep_id; + int stream_idx = -1; + int i; + + ep_id = (struct display_endpoint_id) { + .link_id = link->link_id, + .ep_type = link->ep_type}; + + for (i = 0; i < state->stream_count; i++) { + struct link_enc_assignment assignment = state->res_ctx.link_enc_assignments[i]; + + if (assignment.valid && + assignment.ep_id.link_id.id == ep_id.link_id.id && + assignment.ep_id.link_id.enum_id == ep_id.link_id.enum_id && + assignment.ep_id.link_id.type == ep_id.link_id.type && + assignment.ep_id.ep_type == ep_id.ep_type) { + stream_idx = i; + break; + } + } + + if (stream_idx != -1) + link_enc = state->streams[stream_idx]->link_enc; + else + dm_output_to_console("%s: No link encoder used by link(%d).\n", __func__, link->link_index); + + return link_enc; +} diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c index 124ce215fca5..48ad1a8d4a74 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c @@ -14,6 +14,7 @@ #include "dpcd_defs.h" #include "dsc.h" #include "resource.h" +#include "link_enc_cfg.h" #include "clk_mgr.h" static uint8_t convert_to_count(uint8_t lttpr_repeater_count) @@ -95,7 +96,7 @@ void dp_enable_link_phy( enum clock_source_id clock_source, const struct dc_link_settings *link_settings) { - struct link_encoder *link_enc = link->link_enc; + struct link_encoder *link_enc; struct dc *dc = link->ctx->dc; struct dmcu *dmcu = dc->res_pool->dmcu; @@ -105,6 +106,13 @@ void dp_enable_link_phy( link->dc->res_pool->dp_clock_source; unsigned int i; + /* Link should always be assigned encoder when en-/disabling. */ + if (link->is_dig_mapping_flexible && dc->res_pool->funcs->link_encs_assign) + link_enc = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link); + else + link_enc = link->link_enc; + ASSERT(link_enc); + if (link->connector_signal == SIGNAL_TYPE_EDP) { link->dc->hwss.edp_power_control(link, true); link->dc->hwss.edp_wait_for_hpd_ready(link, true); @@ -227,6 +235,14 @@ void dp_disable_link_phy(struct dc_link *link, enum signal_type signal) { struct dc *dc = link->ctx->dc; struct dmcu *dmcu = dc->res_pool->dmcu; + struct link_encoder *link_enc; + + /* Link should always be assigned encoder when en-/disabling. */ + if (link->is_dig_mapping_flexible && dc->res_pool->funcs->link_encs_assign) + link_enc = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link); + else + link_enc = link->link_enc; + ASSERT(link_enc); if (!link->wa_flags.dp_keep_receiver_powered) dp_receiver_power_ctrl(link, false); @@ -234,13 +250,13 @@ void dp_disable_link_phy(struct dc_link *link, enum signal_type signal) if (signal == SIGNAL_TYPE_EDP) { if (link->dc->hwss.edp_backlight_control) link->dc->hwss.edp_backlight_control(link, false); - link->link_enc->funcs->disable_output(link->link_enc, signal); + link_enc->funcs->disable_output(link_enc, signal); link->dc->hwss.edp_power_control(link, false); } else { if (dmcu != NULL && dmcu->funcs->lock_phy) dmcu->funcs->lock_phy(dmcu); - link->link_enc->funcs->disable_output(link->link_enc, signal); + link_enc->funcs->disable_output(link_enc, signal); if (dmcu != NULL && dmcu->funcs->unlock_phy) dmcu->funcs->unlock_phy(dmcu); @@ -302,7 +318,7 @@ void dp_set_hw_lane_settings( { struct link_encoder *encoder = link->link_enc; - if (link->lttpr_non_transparent_mode && !is_immediate_downstream(link, offset)) + if ((link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) && !is_immediate_downstream(link, offset)) return; /* call Encoder to set lane settings */ 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 3c91d16c2710..ac7a75887f95 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1930,6 +1930,9 @@ enum dc_status dc_remove_stream_from_ctx( dc->res_pool, del_pipe->stream_res.stream_enc, false); + /* Release link encoder from stream in new dc_state. */ + if (dc->res_pool->funcs->link_enc_unassign) + dc->res_pool->funcs->link_enc_unassign(new_ctx, del_pipe->stream); if (del_pipe->stream_res.audio) update_audio_usage( @@ -2842,6 +2845,10 @@ bool pipe_need_reprogram( if (pipe_ctx_old->stream_res.dsc != pipe_ctx->stream_res.dsc) return true; + /* DIG link encoder resource assignment for stream changed. */ + if (pipe_ctx_old->stream->link_enc != pipe_ctx->stream->link_enc) + return true; + return false; } diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index d163007e057c..8108b82bac60 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -45,7 +45,7 @@ /* forward declaration */ struct aux_payload; -#define DC_VER "3.2.127" +#define DC_VER "3.2.130" #define MAX_SURFACES 3 #define MAX_PLANES 6 @@ -460,6 +460,7 @@ struct dc_debug_options { enum pipe_split_policy pipe_split_policy; bool force_single_disp_pipe_split; bool voltage_align_fclk; + bool disable_min_fclk; bool disable_dfs_bypass; bool disable_dpp_power_gate; diff --git a/drivers/gpu/drm/amd/display/dc/dc_bios_types.h b/drivers/gpu/drm/amd/display/dc/dc_bios_types.h index 86ab8f16f621..67abda44eb1f 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_bios_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_bios_types.h @@ -150,6 +150,12 @@ struct dc_vbios_funcs { struct dc_bios *dcb, struct graphics_object_id object_id, struct bp_disp_connector_caps_info *info); + enum bp_result (*get_lttpr_caps)( + struct dc_bios *dcb, + uint8_t *dce_caps); + enum bp_result (*get_lttpr_interop)( + struct dc_bios *dcb, + uint8_t *dce_caps); }; struct bios_registers { diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h index c50ef5a909a6..b0013e674864 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_link.h +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h @@ -35,6 +35,13 @@ enum dc_link_fec_state { dc_link_fec_ready, dc_link_fec_enabled }; + +enum lttpr_mode { + LTTPR_MODE_NON_LTTPR, + LTTPR_MODE_TRANSPARENT, + LTTPR_MODE_NON_TRANSPARENT, +}; + struct dc_link_status { bool link_active; struct dpcd_caps *dpcd_caps; @@ -100,7 +107,7 @@ struct dc_link { bool link_state_valid; bool aux_access_disabled; bool sync_lt_in_progress; - bool lttpr_non_transparent_mode; + enum lttpr_mode lttpr_mode; bool is_internal_display; /* TODO: Rename. Flag an endpoint as having a programmable mapping to a @@ -125,6 +132,11 @@ struct dc_link { uint8_t hpd_src; uint8_t link_enc_hw_inst; + /* DIG link encoder ID. Used as index in link encoder resource pool. + * For links with fixed mapping to DIG, this is not changed after dc_link + * object creation. + */ + enum engine_id eng_id; bool test_pattern_enabled; union compliance_test_state compliance_test_state; @@ -144,6 +156,11 @@ struct dc_link { struct panel_cntl *panel_cntl; struct link_encoder *link_enc; struct graphics_object_id link_id; + /* Endpoint type distinguishes display endpoints which do not have entries + * in the BIOS connector table from those that do. Helps when tracking link + * encoder to display endpoint assignments. + */ + enum display_endpoint_type ep_type; union ddi_channel_mapping ddi_channel_mapping; struct connector_device_tag_info device_tag; struct dpcd_caps dpcd_caps; diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h index e747370fc43b..b0297f07f9de 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h @@ -130,12 +130,24 @@ union stream_update_flags { uint32_t raw; }; +struct test_pattern { + enum dp_test_pattern type; + enum dp_test_pattern_color_space color_space; + struct link_training_settings const *p_link_settings; + unsigned char const *p_custom_pattern; + unsigned int cust_pattern_size; +}; + struct dc_stream_state { // sink is deprecated, new code should not reference // this pointer struct dc_sink *sink; struct dc_link *link; + /* For dynamic link encoder assignment, update the link encoder assigned to + * a stream via the volatile dc_state rather than the static dc_link. + */ + struct link_encoder *link_enc; struct dc_panel_patch sink_patches; union display_content_support content_support; struct dc_crtc_timing timing; @@ -227,6 +239,8 @@ struct dc_stream_state { uint32_t stream_id; bool is_dsc_enabled; + + struct test_pattern test_pattern; union stream_update_flags update_flags; bool has_non_synchronizable_pclk; @@ -264,6 +278,8 @@ struct dc_stream_update { struct dc_dsc_config *dsc_config; struct dc_transfer_func *func_shaper; struct dc_3dlut *lut3d_func; + + struct test_pattern *pending_test_pattern; }; bool dc_is_stream_unchanged( diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h index 80757a0ea7c6..432754eaf10b 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h @@ -113,6 +113,7 @@ struct dc_context { struct gpio_service *gpio_service; uint32_t dc_sink_id_count; uint32_t dc_stream_id_count; + uint32_t dc_edp_id_count; uint64_t fbc_gpu_addr; struct dc_dmub_srv *dmub_srv; @@ -687,7 +688,8 @@ enum dc_psr_state { PSR_STATE5, PSR_STATE5a, PSR_STATE5b, - PSR_STATE5c + PSR_STATE5c, + PSR_STATE_INVALID = 0xFF }; struct psr_config { @@ -934,4 +936,19 @@ enum dc_psr_version { DC_PSR_VERSION_UNSUPPORTED = 0xFFFFFFFF, }; +/* Possible values of display_endpoint_id.endpoint */ +enum display_endpoint_type { + DISPLAY_ENDPOINT_PHY = 0, /* Physical connector. */ + DISPLAY_ENDPOINT_UNKNOWN = -1 +}; + +/* Extends graphics_object_id with an additional member 'ep_type' for + * distinguishing between physical endpoints (with entries in BIOS connector table) and + * logical endpoints. + */ +struct display_endpoint_id { + struct graphics_object_id link_id; + enum display_endpoint_type ep_type; +}; + #endif /* DC_TYPES_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c index 4e87e70237e3..874b132fe1d7 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c @@ -283,7 +283,7 @@ struct abm *dce_abm_create( const struct dce_abm_shift *abm_shift, const struct dce_abm_mask *abm_mask) { - struct dce_abm *abm_dce = kzalloc(sizeof(*abm_dce), GFP_KERNEL); + struct dce_abm *abm_dce = kzalloc(sizeof(*abm_dce), GFP_ATOMIC); if (abm_dce == NULL) { BREAK_TO_DEBUGGER(); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c index 4f864501e046..8cd841320ded 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c @@ -1133,7 +1133,7 @@ struct dmcu *dcn10_dmcu_create( const struct dce_dmcu_shift *dmcu_shift, const struct dce_dmcu_mask *dmcu_mask) { - struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_KERNEL); + struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_ATOMIC); if (dmcu_dce == NULL) { BREAK_TO_DEBUGGER(); @@ -1154,7 +1154,7 @@ struct dmcu *dcn20_dmcu_create( const struct dce_dmcu_shift *dmcu_shift, const struct dce_dmcu_mask *dmcu_mask) { - struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_KERNEL); + struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_ATOMIC); if (dmcu_dce == NULL) { BREAK_TO_DEBUGGER(); @@ -1175,7 +1175,7 @@ struct dmcu *dcn21_dmcu_create( const struct dce_dmcu_shift *dmcu_shift, const struct dce_dmcu_mask *dmcu_mask) { - struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_KERNEL); + struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_ATOMIC); if (dmcu_dce == NULL) { BREAK_TO_DEBUGGER(); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c index 15ed09b7a452..28ff059aa7f3 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c @@ -80,19 +80,26 @@ static enum dc_psr_state convert_psr_state(uint32_t raw_state) static void dmub_psr_get_state(struct dmub_psr *dmub, enum dc_psr_state *state) { struct dmub_srv *srv = dmub->ctx->dmub_srv->dmub; - uint32_t raw_state; + uint32_t raw_state = 0; + uint32_t retry_count = 0; enum dmub_status status; - // Send gpint command and wait for ack - status = dmub_srv_send_gpint_command(srv, DMUB_GPINT__GET_PSR_STATE, 0, 30); - - if (status == DMUB_STATUS_OK) { - // GPINT was executed, get response - dmub_srv_get_gpint_response(srv, &raw_state); - *state = convert_psr_state(raw_state); - } else - // Return invalid state when GPINT times out - *state = 0xFF; + do { + // Send gpint command and wait for ack + status = dmub_srv_send_gpint_command(srv, DMUB_GPINT__GET_PSR_STATE, 0, 30); + + if (status == DMUB_STATUS_OK) { + // GPINT was executed, get response + dmub_srv_get_gpint_response(srv, &raw_state); + *state = convert_psr_state(raw_state); + } else + // Return invalid state when GPINT times out + *state = PSR_STATE_INVALID; + + // Assert if max retry hit + if (retry_count >= 1000) + ASSERT(0); + } while (++retry_count <= 1000 && *state == PSR_STATE_INVALID); } /* 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 804092f81f85..873c6f2d2cd9 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 @@ -1846,8 +1846,7 @@ void dce110_set_safe_displaymarks( ******************************************************************************/ static void set_drr(struct pipe_ctx **pipe_ctx, - int num_pipes, unsigned int vmin, unsigned int vmax, - unsigned int vmid, unsigned int vmid_frame_number) + int num_pipes, struct dc_crtc_timing_adjust adjust) { int i = 0; struct drr_params params = {0}; @@ -1856,8 +1855,8 @@ static void set_drr(struct pipe_ctx **pipe_ctx, // Note DRR trigger events are generated regardless of whether num frames met. unsigned int num_frames = 2; - params.vertical_total_max = vmax; - params.vertical_total_min = vmin; + params.vertical_total_max = adjust.v_total_max; + params.vertical_total_min = adjust.v_total_min; /* TODO: If multiple pipes are to be supported, you need * some GSL stuff. Static screen triggers may be programmed differently @@ -1867,7 +1866,7 @@ static void set_drr(struct pipe_ctx **pipe_ctx, pipe_ctx[i]->stream_res.tg->funcs->set_drr( pipe_ctx[i]->stream_res.tg, ¶ms); - if (vmax != 0 && vmin != 0) + if (adjust.v_total_max != 0 && adjust.v_total_min != 0) pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control( pipe_ctx[i]->stream_res.tg, event_triggers, num_frames); 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 612450f99278..725d92e40cd3 100644 --- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c @@ -526,7 +526,7 @@ static struct output_pixel_processor *dce80_opp_create( return &opp->base; } -struct dce_aux *dce80_aux_engine_create( +static struct dce_aux *dce80_aux_engine_create( struct dc_context *ctx, uint32_t inst) { @@ -564,7 +564,7 @@ static const struct dce_i2c_mask i2c_masks = { I2C_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) }; -struct dce_i2c_hw *dce80_i2c_hw_create( +static struct dce_i2c_hw *dce80_i2c_hw_create( struct dc_context *ctx, uint32_t inst) { @@ -580,7 +580,7 @@ struct dce_i2c_hw *dce80_i2c_hw_create( return dce_i2c_hw; } -struct dce_i2c_sw *dce80_i2c_sw_create( +static struct dce_i2c_sw *dce80_i2c_sw_create( struct dc_context *ctx) { struct dce_i2c_sw *dce_i2c_sw = @@ -714,7 +714,7 @@ static const struct encoder_feature_support link_enc_feature = { .flags.bits.IS_TPS3_CAPABLE = true }; -struct link_encoder *dce80_link_encoder_create( +static struct link_encoder *dce80_link_encoder_create( const struct encoder_init_data *enc_init_data) { struct dce110_link_encoder *enc110 = @@ -753,7 +753,7 @@ static struct panel_cntl *dce80_panel_cntl_create(const struct panel_cntl_init_d return &panel_cntl->base; } -struct clock_source *dce80_clock_source_create( +static struct clock_source *dce80_clock_source_create( struct dc_context *ctx, struct dc_bios *bios, enum clock_source_id id, @@ -777,7 +777,7 @@ struct clock_source *dce80_clock_source_create( return NULL; } -void dce80_clock_source_destroy(struct clock_source **clk_src) +static void dce80_clock_source_destroy(struct clock_source **clk_src) { kfree(TO_DCE110_CLK_SRC(*clk_src)); *clk_src = NULL; @@ -867,7 +867,7 @@ static void dce80_resource_destruct(struct dce110_resource_pool *pool) } } -bool dce80_validate_bandwidth( +static bool dce80_validate_bandwidth( struct dc *dc, struct dc_state *context, bool fast_validate) @@ -912,7 +912,7 @@ static bool dce80_validate_surface_sets( return true; } -enum dc_status dce80_validate_global( +static enum dc_status dce80_validate_global( struct dc *dc, struct dc_state *context) { 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 9eb33eae0e81..7c939c0a977b 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 @@ -1893,7 +1893,7 @@ uint64_t reduceSizeAndFraction( num = *numerator; denom = *denominator; for (i = 0; i < count; i++) { - uint32_t num_reminder, denom_reminder; + uint32_t num_remainder, denom_remainder; uint64_t num_result, denom_result; if (checkUint32Bounary && num <= max_int32 && denom <= max_int32) { @@ -1901,13 +1901,13 @@ uint64_t reduceSizeAndFraction( break; } do { - num_result = div_u64_rem(num, prime_numbers[i], &num_reminder); - denom_result = div_u64_rem(denom, prime_numbers[i], &denom_reminder); - if (num_reminder == 0 && denom_reminder == 0) { + num_result = div_u64_rem(num, prime_numbers[i], &num_remainder); + denom_result = div_u64_rem(denom, prime_numbers[i], &denom_remainder); + if (num_remainder == 0 && denom_remainder == 0) { num = num_result; denom = denom_result; } - } while (num_reminder == 0 && denom_reminder == 0); + } while (num_remainder == 0 && denom_remainder == 0); } *numerator = num; *denominator = denom; @@ -3271,8 +3271,7 @@ void dcn10_optimize_bandwidth( } void dcn10_set_drr(struct pipe_ctx **pipe_ctx, - int num_pipes, unsigned int vmin, unsigned int vmax, - unsigned int vmid, unsigned int vmid_frame_number) + int num_pipes, struct dc_crtc_timing_adjust adjust) { int i = 0; struct drr_params params = {0}; @@ -3281,11 +3280,10 @@ void dcn10_set_drr(struct pipe_ctx **pipe_ctx, // Note DRR trigger events are generated regardless of whether num frames met. unsigned int num_frames = 2; - params.vertical_total_max = vmax; - params.vertical_total_min = vmin; - params.vertical_total_mid = vmid; - params.vertical_total_mid_frame_num = vmid_frame_number; - + params.vertical_total_max = adjust.v_total_max; + params.vertical_total_min = adjust.v_total_min; + params.vertical_total_mid = adjust.v_total_mid; + params.vertical_total_mid_frame_num = adjust.v_total_mid_frame_num; /* TODO: If multiple pipes are to be supported, you need * some GSL stuff. Static screen triggers may be programmed differently * as well. @@ -3293,7 +3291,7 @@ void dcn10_set_drr(struct pipe_ctx **pipe_ctx, for (i = 0; i < num_pipes; i++) { pipe_ctx[i]->stream_res.tg->funcs->set_drr( pipe_ctx[i]->stream_res.tg, ¶ms); - if (vmax != 0 && vmin != 0) + if (adjust.v_total_max != 0 && adjust.v_total_min != 0) pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control( pipe_ctx[i]->stream_res.tg, event_triggers, num_frames); @@ -3981,3 +3979,19 @@ void dcn10_get_clock(struct dc *dc, dc->clk_mgr->funcs->get_clock(dc->clk_mgr, context, clock_type, clock_cfg); } + +void dcn10_get_dcc_en_bits(struct dc *dc, int *dcc_en_bits) +{ + struct resource_pool *pool = dc->res_pool; + int i; + + for (i = 0; i < pool->pipe_count; i++) { + struct hubp *hubp = pool->hubps[i]; + struct dcn_hubp_state *s = &(TO_DCN10_HUBP(hubp)->state); + + hubp->funcs->hubp_read_state(hubp); + + if (!s->blank_en) + dcc_en_bits[i] = s->dcc_en ? 1 : 0; + } +} diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h index e0800cd1cc02..37bec421fde8 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h @@ -1,5 +1,5 @@ /* -* Copyright 2016 Advanced Micro Devices, Inc. +* Copyright 2016-2020 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -145,8 +145,7 @@ bool dcn10_dummy_display_power_gating( struct dc_bios *dcb, enum pipe_gating_control power_gating); void dcn10_set_drr(struct pipe_ctx **pipe_ctx, - int num_pipes, unsigned int vmin, unsigned int vmax, - unsigned int vmid, unsigned int vmid_frame_number); + int num_pipes, struct dc_crtc_timing_adjust adjust); void dcn10_get_position(struct pipe_ctx **pipe_ctx, int num_pipes, struct crtc_position *position); @@ -210,4 +209,6 @@ void dcn10_wait_for_pending_cleared(struct dc *dc, void dcn10_set_hdr_multiplier(struct pipe_ctx *pipe_ctx); void dcn10_verify_allow_pstate_change_high(struct dc *dc); +void dcn10_get_dcc_en_bits(struct dc *dc, int *dcc_en_bits); + #endif /* __DC_HWSS_DCN10_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c index 254300b06b43..d532c78ee764 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c @@ -1,5 +1,5 @@ /* - * Copyright 2016 Advanced Micro Devices, Inc. + * Copyright 2016-2020 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -79,6 +79,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = { .set_backlight_level = dce110_set_backlight_level, .set_abm_immediate_disable = dce110_set_abm_immediate_disable, .set_pipe = dce110_set_pipe, + .get_dcc_en_bits = dcn10_get_dcc_en_bits, }; static const struct hwseq_private_funcs dcn10_private_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c index 6138f4887de7..677663cc7bff 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c @@ -132,6 +132,22 @@ void optc1_setup_vertical_interrupt2( } /** + * Vupdate keepout can be set to a window to block the update lock for that pipe from changing. + * Start offset begins with vstartup and goes for x number of clocks, + * end offset starts from end of vupdate to x number of clocks. + */ +void optc1_set_vupdate_keepout(struct timing_generator *optc, + struct vupdate_keepout_params *params) +{ + struct optc *optc1 = DCN10TG_FROM_TG(optc); + + REG_SET_3(OTG_VUPDATE_KEEPOUT, 0, + MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_START_OFFSET, params->start_offset, + MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_END_OFFSET, params->end_offset, + OTG_MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_EN, params->enable); +} + +/** * program_timing_generator used by mode timing set * Program CRTC Timing Registers - OTG_H_*, OTG_V_*, Pixel repetition. * Including SYNC. Call BIOS command table to program Timings. diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h index 2529723beeb1..cabfe83fd634 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h @@ -194,6 +194,9 @@ struct dcn_optc_registers { SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_UPDATE_PENDING, mask_sh),\ SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_BLANK_DATA_DOUBLE_BUFFER_EN, mask_sh),\ SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_RANGE_TIMING_DBUF_UPDATE_MODE, mask_sh),\ + SF(OTG0_OTG_VUPDATE_KEEPOUT, OTG_MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_EN, mask_sh), \ + SF(OTG0_OTG_VUPDATE_KEEPOUT, MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_START_OFFSET, mask_sh), \ + SF(OTG0_OTG_VUPDATE_KEEPOUT, MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_END_OFFSET, mask_sh), \ SF(OTG0_OTG_H_TOTAL, OTG_H_TOTAL, mask_sh),\ SF(OTG0_OTG_H_BLANK_START_END, OTG_H_BLANK_START, mask_sh),\ SF(OTG0_OTG_H_BLANK_START_END, OTG_H_BLANK_END, mask_sh),\ diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index d079f4e491e5..f962b905e79e 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -82,7 +82,7 @@ const struct _vcs_dpi_ip_params_st dcn1_0_ip = { .meta_chunk_size_kbytes = 2, .writeback_chunk_size_kbytes = 2, .line_buffer_size_bits = 589824, - .max_line_buffer_lines = 32, + .max_line_buffer_lines = 12, .IsLineBufferBppFixed = 0, .LineBufferFixedBpp = -1, .writeback_luma_buffer_size_kbytes = 12, @@ -619,7 +619,6 @@ static const struct dc_debug_options debug_defaults_drv = { .recovery_enabled = false, /*enable this by default after testing.*/ .max_downscale_src_width = 3840, .underflow_assert_delay_us = 0xFFFFFFFF, - .use_max_lb = true }; static const struct dc_debug_options debug_defaults_diags = { @@ -631,7 +630,6 @@ static const struct dc_debug_options debug_defaults_diags = { .disable_pplib_clock_request = true, .disable_pplib_wm_range = true, .underflow_assert_delay_us = 0xFFFFFFFF, - .use_max_lb = true }; static void dcn10_dpp_destroy(struct dpp **dpp) diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.c index 62cc2651e00c..8774406120fc 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.c @@ -112,7 +112,7 @@ struct dccg *dccg2_create( const struct dccg_shift *dccg_shift, const struct dccg_mask *dccg_mask) { - struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL); + struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_ATOMIC); struct dccg *base; if (dccg_dcn == NULL) { diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c index 7218ed9e43dc..b5bb613eed4d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c @@ -95,6 +95,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = { .optimize_timing_for_fsft = dcn20_optimize_timing_for_fsft, #endif .set_disp_pattern_generator = dcn20_set_disp_pattern_generator, + .get_dcc_en_bits = dcn10_get_dcc_en_bits, }; static const struct hwseq_private_funcs dcn20_private_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.c index fa013496e26b..2f9bfaeaba8d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.c @@ -341,8 +341,7 @@ void enc2_hw_init(struct link_encoder *enc) } else { AUX_REG_WRITE(AUX_DPHY_RX_CONTROL0, 0x103d1110); - AUX_REG_WRITE(AUX_DPHY_TX_CONTROL, 0x21c4d); - + AUX_REG_WRITE(AUX_DPHY_TX_CONTROL, 0x21c7a); } //AUX_DPHY_TX_REF_CONTROL'AUX_TX_REF_DIV HW default is 0x32; diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c index ea7eaf7d755f..3139d90017ee 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c @@ -134,22 +134,6 @@ void optc2_set_gsl_window(struct timing_generator *optc, OTG_GSL_WINDOW_END_Y, params->gsl_window_end_y); } -/** - * Vupdate keepout can be set to a window to block the update lock for that pipe from changing. - * Start offset begins with vstartup and goes for x number of clocks, - * end offset starts from end of vupdate to x number of clocks. - */ -void optc2_set_vupdate_keepout(struct timing_generator *optc, - const struct vupdate_keepout_params *params) -{ - struct optc *optc1 = DCN10TG_FROM_TG(optc); - - REG_SET_3(OTG_VUPDATE_KEEPOUT, 0, - MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_START_OFFSET, params->start_offset, - MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_END_OFFSET, params->end_offset, - OTG_MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_EN, params->enable); -} - void optc2_set_gsl_source_select( struct timing_generator *optc, int group_idx, diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.h index e0a0a8a8e2c6..3dee2ec2a1bb 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.h +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.h @@ -56,9 +56,6 @@ SF(OTG0_OTG_GSL_WINDOW_X, OTG_GSL_WINDOW_END_X, mask_sh), \ SF(OTG0_OTG_GSL_WINDOW_Y, OTG_GSL_WINDOW_START_Y, mask_sh),\ SF(OTG0_OTG_GSL_WINDOW_Y, OTG_GSL_WINDOW_END_Y, mask_sh),\ - SF(OTG0_OTG_VUPDATE_KEEPOUT, OTG_MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_EN, mask_sh), \ - SF(OTG0_OTG_VUPDATE_KEEPOUT, MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_START_OFFSET, mask_sh), \ - SF(OTG0_OTG_VUPDATE_KEEPOUT, MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_END_OFFSET, mask_sh), \ SF(OTG0_OTG_GSL_CONTROL, OTG_GSL_MASTER_MODE, mask_sh), \ SF(OTG0_OTG_GSL_CONTROL, OTG_MASTER_UPDATE_LOCK_GSL_EN, mask_sh), \ SF(OTG0_OTG_DSC_START_POSITION, OTG_DSC_START_POSITION_X, mask_sh), \ diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c index 2307b3517821..f65a6904d09c 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -112,7 +112,7 @@ struct _vcs_dpi_ip_params_st dcn2_0_ip = { .is_line_buffer_bpp_fixed = 0, .line_buffer_fixed_bpp = 0, .dcc_supported = true, - .max_line_buffer_lines = 32, + .max_line_buffer_lines = 12, .writeback_luma_buffer_size_kbytes = 12, .writeback_chroma_buffer_size_kbytes = 8, .writeback_chroma_line_buffer_width_pixels = 4, @@ -180,7 +180,7 @@ static struct _vcs_dpi_ip_params_st dcn2_0_nv14_ip = { .is_line_buffer_bpp_fixed = 0, .line_buffer_fixed_bpp = 0, .dcc_supported = true, - .max_line_buffer_lines = 32, + .max_line_buffer_lines = 12, .writeback_luma_buffer_size_kbytes = 12, .writeback_chroma_buffer_size_kbytes = 8, .writeback_chroma_line_buffer_width_pixels = 4, @@ -1075,7 +1075,6 @@ static const struct dc_debug_options debug_defaults_drv = { .scl_reset_length10 = true, .sanity_checks = false, .underflow_assert_delay_us = 0xFFFFFFFF, - .use_max_lb = true }; static const struct dc_debug_options debug_defaults_diags = { @@ -1092,7 +1091,6 @@ static const struct dc_debug_options debug_defaults_diags = { .scl_reset_length10 = true, .underflow_assert_delay_us = 0xFFFFFFFF, .enable_tri_buf = true, - .use_max_lb = true }; void dcn20_dpp_destroy(struct dpp **dpp) @@ -1106,7 +1104,7 @@ struct dpp *dcn20_dpp_create( uint32_t inst) { struct dcn20_dpp *dpp = - kzalloc(sizeof(struct dcn20_dpp), GFP_KERNEL); + kzalloc(sizeof(struct dcn20_dpp), GFP_ATOMIC); if (!dpp) return NULL; @@ -1124,7 +1122,7 @@ struct input_pixel_processor *dcn20_ipp_create( struct dc_context *ctx, uint32_t inst) { struct dcn10_ipp *ipp = - kzalloc(sizeof(struct dcn10_ipp), GFP_KERNEL); + kzalloc(sizeof(struct dcn10_ipp), GFP_ATOMIC); if (!ipp) { BREAK_TO_DEBUGGER(); @@ -1141,7 +1139,7 @@ struct output_pixel_processor *dcn20_opp_create( struct dc_context *ctx, uint32_t inst) { struct dcn20_opp *opp = - kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL); + kzalloc(sizeof(struct dcn20_opp), GFP_ATOMIC); if (!opp) { BREAK_TO_DEBUGGER(); @@ -1158,7 +1156,7 @@ struct dce_aux *dcn20_aux_engine_create( uint32_t inst) { struct aux_engine_dce110 *aux_engine = - kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); + kzalloc(sizeof(struct aux_engine_dce110), GFP_ATOMIC); if (!aux_engine) return NULL; @@ -1196,7 +1194,7 @@ struct dce_i2c_hw *dcn20_i2c_hw_create( uint32_t inst) { struct dce_i2c_hw *dce_i2c_hw = - kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); + kzalloc(sizeof(struct dce_i2c_hw), GFP_ATOMIC); if (!dce_i2c_hw) return NULL; @@ -1209,7 +1207,7 @@ struct dce_i2c_hw *dcn20_i2c_hw_create( struct mpc *dcn20_mpc_create(struct dc_context *ctx) { struct dcn20_mpc *mpc20 = kzalloc(sizeof(struct dcn20_mpc), - GFP_KERNEL); + GFP_ATOMIC); if (!mpc20) return NULL; @@ -1227,7 +1225,7 @@ struct hubbub *dcn20_hubbub_create(struct dc_context *ctx) { int i; struct dcn20_hubbub *hubbub = kzalloc(sizeof(struct dcn20_hubbub), - GFP_KERNEL); + GFP_ATOMIC); if (!hubbub) return NULL; @@ -1255,7 +1253,7 @@ struct timing_generator *dcn20_timing_generator_create( uint32_t instance) { struct optc *tgn10 = - kzalloc(sizeof(struct optc), GFP_KERNEL); + kzalloc(sizeof(struct optc), GFP_ATOMIC); if (!tgn10) return NULL; @@ -1334,7 +1332,7 @@ static struct clock_source *dcn20_clock_source_create( bool dp_clk_src) { struct dce110_clk_src *clk_src = - kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); + kzalloc(sizeof(struct dce110_clk_src), GFP_ATOMIC); if (!clk_src) return NULL; @@ -1440,7 +1438,7 @@ struct display_stream_compressor *dcn20_dsc_create( struct dc_context *ctx, uint32_t inst) { struct dcn20_dsc *dsc = - kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL); + kzalloc(sizeof(struct dcn20_dsc), GFP_ATOMIC); if (!dsc) { BREAK_TO_DEBUGGER(); @@ -1574,7 +1572,7 @@ struct hubp *dcn20_hubp_create( uint32_t inst) { struct dcn20_hubp *hubp2 = - kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL); + kzalloc(sizeof(struct dcn20_hubp), GFP_ATOMIC); if (!hubp2) return NULL; @@ -2218,7 +2216,7 @@ int dcn20_populate_dml_pipes_from_context( pipes[pipe_cnt].dout.output_bpp = res_ctx->pipe_ctx[i].stream->timing.dsc_cfg.bits_per_pixel / 16.0; /* todo: default max for now, until there is logic reflecting this in dc*/ - pipes[pipe_cnt].dout.output_bpc = 12; + pipes[pipe_cnt].dout.dsc_input_bpc = 12; /*fill up the audio sample rate (unit in kHz)*/ get_audio_check(&res_ctx->pipe_ctx[i].stream->audio_info, &aud_check); pipes[pipe_cnt].dout.max_audio_sample_rate = aud_check.max_audiosample_rate / 1000; @@ -3396,7 +3394,7 @@ bool dcn20_mmhubbub_create(struct dc_context *ctx, struct resource_pool *pool) static struct pp_smu_funcs *dcn20_pp_smu_create(struct dc_context *ctx) { - struct pp_smu_funcs *pp_smu = kzalloc(sizeof(*pp_smu), GFP_KERNEL); + struct pp_smu_funcs *pp_smu = kzalloc(sizeof(*pp_smu), GFP_ATOMIC); if (!pp_smu) return pp_smu; @@ -4042,7 +4040,7 @@ struct resource_pool *dcn20_create_resource_pool( struct dc *dc) { struct dcn20_resource_pool *pool = - kzalloc(sizeof(struct dcn20_resource_pool), GFP_KERNEL); + kzalloc(sizeof(struct dcn20_resource_pool), GFP_ATOMIC); if (!pool) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c index 074e2713257f..4f20a85ff396 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c @@ -1,5 +1,5 @@ /* - * Copyright 2016 Advanced Micro Devices, Inc. + * Copyright 2016-2020 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -99,6 +99,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = { #endif .is_abm_supported = dcn21_is_abm_supported, .set_disp_pattern_generator = dcn20_set_disp_pattern_generator, + .get_dcc_en_bits = dcn10_get_dcc_en_bits, }; static const struct hwseq_private_funcs dcn21_private_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c index e62f931fc269..8e3f1d0b4cc3 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c @@ -55,7 +55,6 @@ #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" #include "virtual/virtual_stream_encoder.h" -#include "dce110/dce110_resource.h" #include "dml/display_mode_vba.h" #include "dcn20/dcn20_dccg.h" #include "dcn21/dcn21_dccg.h" @@ -115,7 +114,7 @@ struct _vcs_dpi_ip_params_st dcn2_1_ip = { .is_line_buffer_bpp_fixed = 0, .line_buffer_fixed_bpp = 0, .dcc_supported = true, - .max_line_buffer_lines = 32, + .max_line_buffer_lines = 12, .writeback_luma_buffer_size_kbytes = 12, .writeback_chroma_buffer_size_kbytes = 8, .writeback_chroma_line_buffer_width_pixels = 4, diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.h index 705fbfc37502..8a32772d4e91 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.h +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.h @@ -134,6 +134,7 @@ HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, SECONDARY_SURFACE_DCC_EN, mask_sh),\ HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, SECONDARY_SURFACE_DCC_IND_BLK, mask_sh),\ HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, SECONDARY_SURFACE_DCC_IND_BLK_C, mask_sh),\ + HUBP_SF(HUBPREQ0_DCSURF_SURFACE_FLIP_INTERRUPT, SURFACE_FLIP_INT_MASK, mask_sh),\ HUBP_SF(HUBPRET0_HUBPRET_CONTROL, DET_BUF_PLANE1_BASE_ADDRESS, mask_sh),\ HUBP_SF(HUBPRET0_HUBPRET_CONTROL, CROSSBAR_SRC_CB_B, mask_sh),\ HUBP_SF(HUBPRET0_HUBPRET_CONTROL, CROSSBAR_SRC_CR_R, mask_sh),\ diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c index c4c14e9c1309..bf7fa98b39eb 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c @@ -1,5 +1,5 @@ /* - * Copyright 2020 Advanced Micro Devices, Inc. + * Copyright 2016-2020 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -98,6 +98,7 @@ static const struct hw_sequencer_funcs dcn30_funcs = { .hardware_release = dcn30_hardware_release, .set_pipe = dcn21_set_pipe, .set_disp_pattern_generator = dcn30_set_disp_pattern_generator, + .get_dcc_en_bits = dcn10_get_dcc_en_bits, }; static const struct hwseq_private_funcs dcn30_private_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c index 263c2986682d..4a5fa23d8e7b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c @@ -120,7 +120,7 @@ struct _vcs_dpi_ip_params_st dcn3_0_ip = { .dcc_supported = true, .writeback_interface_buffer_size_kbytes = 90, .writeback_line_buffer_buffer_size = 0, - .max_line_buffer_lines = 32, + .max_line_buffer_lines = 12, .writeback_luma_buffer_size_kbytes = 12, // writeback_line_buffer_buffer_size = 656640 .writeback_chroma_buffer_size_kbytes = 8, .writeback_chroma_line_buffer_width_pixels = 4, diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c index bdad72140cbc..0d90523c7cdc 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c @@ -1,5 +1,5 @@ /* - * Copyright 2020 Advanced Micro Devices, Inc. + * Copyright 2016-2020 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -98,6 +98,7 @@ static const struct hw_sequencer_funcs dcn301_funcs = { .set_abm_immediate_disable = dcn21_set_abm_immediate_disable, .set_pipe = dcn21_set_pipe, .set_disp_pattern_generator = dcn30_set_disp_pattern_generator, + .get_dcc_en_bits = dcn10_get_dcc_en_bits, }; static const struct hwseq_private_funcs dcn301_private_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c index 622a5bf9737f..5b54b7fc5105 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c @@ -1,5 +1,5 @@ /* - * Copyright 2020 Advanced Micro Devices, Inc. + * Copyright 2019-2021 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -116,7 +116,7 @@ struct _vcs_dpi_ip_params_st dcn3_01_ip = { .dcc_supported = true, .writeback_interface_buffer_size_kbytes = 90, .writeback_line_buffer_buffer_size = 656640, - .max_line_buffer_lines = 32, + .max_line_buffer_lines = 12, .writeback_luma_buffer_size_kbytes = 12, // writeback_line_buffer_buffer_size = 656640 .writeback_chroma_buffer_size_kbytes = 8, .writeback_chroma_line_buffer_width_pixels = 4, diff --git a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c index 0723e29fd42e..fc2dea243d1b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c @@ -101,7 +101,7 @@ struct _vcs_dpi_ip_params_st dcn3_02_ip = { .dcc_supported = true, .writeback_interface_buffer_size_kbytes = 90, .writeback_line_buffer_buffer_size = 0, - .max_line_buffer_lines = 32, + .max_line_buffer_lines = 12, .writeback_luma_buffer_size_kbytes = 12, // writeback_line_buffer_buffer_size = 656640 .writeback_chroma_buffer_size_kbytes = 8, .writeback_chroma_line_buffer_width_pixels = 4, @@ -164,7 +164,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_02_soc = { .min_dcfclk = 500.0, /* TODO: set this to actual min DCFCLK */ .num_states = 1, - .sr_exit_time_us = 12, + .sr_exit_time_us = 15.5, .sr_enter_plus_exit_time_us = 20, .urgent_latency_us = 4.0, .urgent_latency_pixel_data_only_us = 4.0, diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c index 72423dc425dc..799bae229e67 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c @@ -293,13 +293,31 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib, if (surf_linear) { log2_swath_height_l = 0; log2_swath_height_c = 0; - } else if (!surf_vert) { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c; } else { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c; + unsigned int swath_height_l; + unsigned int swath_height_c; + + if (!surf_vert) { + swath_height_l = rq_param->misc.rq_l.blk256_height; + swath_height_c = rq_param->misc.rq_c.blk256_height; + } else { + swath_height_l = rq_param->misc.rq_l.blk256_width; + swath_height_c = rq_param->misc.rq_c.blk256_width; + } + + if (swath_height_l > 0) + log2_swath_height_l = dml_log2(swath_height_l); + + if (req128_l && log2_swath_height_l > 0) + log2_swath_height_l -= 1; + + if (swath_height_c > 0) + log2_swath_height_c = dml_log2(swath_height_c); + + if (req128_c && log2_swath_height_c > 0) + log2_swath_height_c -= 1; } + rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l; rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c index 9c78446c3a9d..6a6d5970d1d5 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c @@ -293,13 +293,31 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib, if (surf_linear) { log2_swath_height_l = 0; log2_swath_height_c = 0; - } else if (!surf_vert) { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c; } else { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c; + unsigned int swath_height_l; + unsigned int swath_height_c; + + if (!surf_vert) { + swath_height_l = rq_param->misc.rq_l.blk256_height; + swath_height_c = rq_param->misc.rq_c.blk256_height; + } else { + swath_height_l = rq_param->misc.rq_l.blk256_width; + swath_height_c = rq_param->misc.rq_c.blk256_width; + } + + if (swath_height_l > 0) + log2_swath_height_l = dml_log2(swath_height_l); + + if (req128_l && log2_swath_height_l > 0) + log2_swath_height_l -= 1; + + if (swath_height_c > 0) + log2_swath_height_c = dml_log2(swath_height_c); + + if (req128_c && log2_swath_height_c > 0) + log2_swath_height_c -= 1; } + rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l; rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c index edd41d358291..dc1c81a6e377 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c @@ -277,13 +277,31 @@ static void handle_det_buf_split( if (surf_linear) { log2_swath_height_l = 0; log2_swath_height_c = 0; - } else if (!surf_vert) { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c; } else { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c; + unsigned int swath_height_l; + unsigned int swath_height_c; + + if (!surf_vert) { + swath_height_l = rq_param->misc.rq_l.blk256_height; + swath_height_c = rq_param->misc.rq_c.blk256_height; + } else { + swath_height_l = rq_param->misc.rq_l.blk256_width; + swath_height_c = rq_param->misc.rq_c.blk256_width; + } + + if (swath_height_l > 0) + log2_swath_height_l = dml_log2(swath_height_l); + + if (req128_l && log2_swath_height_l > 0) + log2_swath_height_l -= 1; + + if (swath_height_c > 0) + log2_swath_height_c = dml_log2(swath_height_c); + + if (req128_c && log2_swath_height_c > 0) + log2_swath_height_c -= 1; } + rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l; rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c index 0f14f205ebe5..04601a767a8f 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c @@ -237,13 +237,31 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib, if (surf_linear) { log2_swath_height_l = 0; log2_swath_height_c = 0; - } else if (!surf_vert) { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c; } else { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c; + unsigned int swath_height_l; + unsigned int swath_height_c; + + if (!surf_vert) { + swath_height_l = rq_param->misc.rq_l.blk256_height; + swath_height_c = rq_param->misc.rq_c.blk256_height; + } else { + swath_height_l = rq_param->misc.rq_l.blk256_width; + swath_height_c = rq_param->misc.rq_c.blk256_width; + } + + if (swath_height_l > 0) + log2_swath_height_l = dml_log2(swath_height_l); + + if (req128_l && log2_swath_height_l > 0) + log2_swath_height_l -= 1; + + if (swath_height_c > 0) + log2_swath_height_c = dml_log2(swath_height_c); + + if (req128_c && log2_swath_height_c > 0) + log2_swath_height_c -= 1; } + rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l; rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c; diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c index 098d6433f7f3..1f7b6ddf3020 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c @@ -226,7 +226,7 @@ void dml_log_pipe_params( dml_print("DML PARAMS: PIPE [%d] DISPLAY OUTPUT PARAMS:\n", i); dml_print("DML PARAMS: output_type = %d\n", dout->output_type); dml_print("DML PARAMS: output_format = %d\n", dout->output_format); - dml_print("DML PARAMS: output_bpc = %d\n", dout->output_bpc); + dml_print("DML PARAMS: dsc_input_bpc = %d\n", dout->dsc_input_bpc); dml_print("DML PARAMS: output_bpp = %3.4f\n", dout->output_bpp); dml_print("DML PARAMS: dp_lanes = %d\n", dout->dp_lanes); dml_print("DML PARAMS: dsc_enable = %d\n", dout->dsc_enable); diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h index 0c5128187e08..2ece3690bfa3 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h @@ -164,7 +164,7 @@ struct _vcs_dpi_ip_params_st { double writeback_max_vscl_ratio; double writeback_min_hscl_ratio; double writeback_min_vscl_ratio; - double maximum_dsc_bits_per_component; + unsigned int maximum_dsc_bits_per_component; unsigned int writeback_max_hscl_taps; unsigned int writeback_max_vscl_taps; unsigned int writeback_line_buffer_luma_buffer_size; @@ -292,10 +292,10 @@ struct writeback_st { struct _vcs_dpi_display_output_params_st { int dp_lanes; double output_bpp; + unsigned int dsc_input_bpc; int dsc_enable; int wb_enable; int num_active_wb; - int output_bpc; int output_type; int is_virtual; int output_format; diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c index 94036a9612cf..2a967458065b 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c @@ -471,7 +471,13 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib) mode_lib->vba.DSCEnable[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_enable; mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_slices; - mode_lib->vba.DSCInputBitPerComponent[mode_lib->vba.NumberOfActivePlanes] = dout->output_bpc; + if (!dout->dsc_input_bpc) { + mode_lib->vba.DSCInputBitPerComponent[mode_lib->vba.NumberOfActivePlanes] = + ip->maximum_dsc_bits_per_component; + } else { + mode_lib->vba.DSCInputBitPerComponent[mode_lib->vba.NumberOfActivePlanes] = + dout->dsc_input_bpc; + } mode_lib->vba.WritebackEnable[mode_lib->vba.NumberOfActivePlanes] = dout->wb_enable; mode_lib->vba.ActiveWritebacksPerPlane[mode_lib->vba.NumberOfActivePlanes] = dout->num_active_wb; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c index 4c3e9cc30167..414da64f5734 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c @@ -344,13 +344,31 @@ static void handle_det_buf_split( if (surf_linear) { log2_swath_height_l = 0; log2_swath_height_c = 0; - } else if (!surf_vert) { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c; } else { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c; + unsigned int swath_height_l; + unsigned int swath_height_c; + + if (!surf_vert) { + swath_height_l = rq_param->misc.rq_l.blk256_height; + swath_height_c = rq_param->misc.rq_c.blk256_height; + } else { + swath_height_l = rq_param->misc.rq_l.blk256_width; + swath_height_c = rq_param->misc.rq_c.blk256_width; + } + + if (swath_height_l > 0) + log2_swath_height_l = dml_log2(swath_height_l); + + if (req128_l && log2_swath_height_l > 0) + log2_swath_height_l -= 1; + + if (swath_height_c > 0) + log2_swath_height_c = dml_log2(swath_height_c); + + if (req128_c && log2_swath_height_c > 0) + log2_swath_height_c -= 1; } + rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l; rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c; diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h index eb1a19bf0d81..81b92f20d5b6 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -118,6 +118,27 @@ struct resource_funcs { display_e2e_pipe_params_st *pipes, bool fast_validate); + /* + * Algorithm for assigning available link encoders to links. + * + * Update link_enc_assignments table and link_enc_avail list accordingly in + * struct resource_context. + */ + void (*link_encs_assign)( + struct dc *dc, + struct dc_state *state, + struct dc_stream_state *streams[], + uint8_t stream_count); + /* + * Unassign a link encoder from a stream. + * + * Update link_enc_assignments table and link_enc_avail list accordingly in + * struct resource_context. + */ + void (*link_enc_unassign)( + struct dc_state *state, + struct dc_stream_state *stream); + enum dc_status (*validate_global)( struct dc *dc, struct dc_state *context); @@ -358,6 +379,12 @@ struct resource_context { uint8_t clock_source_ref_count[MAX_CLOCK_SOURCES]; uint8_t dp_clock_source_ref_count; bool is_dsc_acquired[MAX_PIPES]; + /* A table/array of encoder-to-link assignments. One entry per stream. + * Indexed by stream index in dc_state. + */ + struct link_enc_assignment link_enc_assignments[MAX_PIPES]; + /* List of available link encoders. Uses engine ID as encoder identifier. */ + enum engine_id link_enc_avail[MAX_DIG_LINK_ENCODERS]; #if defined(CONFIG_DRM_AMD_DC_DCN) bool is_mpc_3dlut_acquired[MAX_PIPES]; #endif diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h index 3a29f379d0c8..5dc8d02b40c3 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h @@ -262,14 +262,9 @@ struct clk_mgr_funcs { /* Get current memclk states from PMFW, update relevant structures */ void (*get_memclk_states_from_smu)(struct clk_mgr *clk_mgr); -}; - -struct dpm_clocks; -struct wartermarks; -struct smu_watermark_set { - struct watermarks *wm_set; - union large_integer mc_address; + /* Get SMU present */ + bool (*is_smu_present)(struct clk_mgr *clk_mgr); }; struct clk_mgr { @@ -283,7 +278,6 @@ struct clk_mgr { struct clk_state_registers_and_bypass boot_snapshot; struct clk_bw_params *bw_params; struct pp_smu_wm_range_sets ranges; - struct smu_watermark_set smu_wm_set; }; /* forward declarations */ diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h index 346dcd87dc10..80e1a32bc63d 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h @@ -29,6 +29,7 @@ #include "mem_input.h" #define OPP_ID_INVALID 0xf +#define MAX_TTU 0xffffff enum cursor_pitch { 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 7f5acd8fb918..80bc99500645 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 @@ -187,4 +187,17 @@ struct link_encoder_funcs { struct link_encoder *enc); }; +/* + * Used to track assignments of links (display endpoints) to link encoders. + * + * Entry in link_enc_assignments table in struct resource_context. + * Entries only marked valid once encoder assigned to a link and invalidated once unassigned. + * Uses engine ID as identifier since PHY ID not relevant for USB4 DPIA endpoint. + */ +struct link_enc_assignment { + bool valid; + struct display_endpoint_id ep_id; + enum engine_id eng_id; +}; + #endif /* LINK_ENCODER_H_ */ 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 2fedfcac6705..1d5853c95448 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h @@ -118,8 +118,7 @@ struct hw_sequencer_funcs { struct pipe_ctx *pipe_ctx, enum vline_select vline); void (*set_drr)(struct pipe_ctx **pipe_ctx, int num_pipes, - unsigned int vmin, unsigned int vmax, - unsigned int vmid, unsigned int vmid_frame_number); + struct dc_crtc_timing_adjust adjust); void (*set_static_screen_control)(struct pipe_ctx **pipe_ctx, int num_pipes, const struct dc_static_screen_params *events); @@ -218,6 +217,8 @@ struct hw_sequencer_funcs { void (*set_pipe)(struct pipe_ctx *pipe_ctx); + void (*get_dcc_en_bits)(struct dc *dc, int *dcc_en_bits); + /* Idle Optimization Related */ bool (*apply_idle_power_optimizations)(struct dc *dc, bool enable); diff --git a/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h b/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h new file mode 100644 index 000000000000..7d36e55f3097 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h @@ -0,0 +1,86 @@ +/* + * Copyright 2021 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#ifndef DC_INC_LINK_ENC_CFG_H_ +#define DC_INC_LINK_ENC_CFG_H_ + +/* This module implements functionality for dynamically assigning DIG link + * encoder resources to display endpoints (links). + */ + +#include "core_types.h" + +/* + * Initialise link encoder resource tracking. + */ +void link_enc_cfg_init( + struct dc *dc, + struct dc_state *state); + +/* + * Algorithm for assigning available DIG link encoders to streams. + * + * Update link_enc_assignments table and link_enc_avail list accordingly in + * struct resource_context. + * + * Loop over all streams twice: + * a) First assign encoders to unmappable endpoints. + * b) Then assign encoders to mappable endpoints. + */ +void link_enc_cfg_link_encs_assign( + struct dc *dc, + struct dc_state *state, + struct dc_stream_state *streams[], + uint8_t stream_count); + +/* + * Unassign a link encoder from a stream. + * + * Update link_enc_assignments table and link_enc_avail list accordingly in + * struct resource_context. + */ +void link_enc_cfg_link_enc_unassign( + struct dc_state *state, + struct dc_stream_state *stream); + +/* + * Check whether the transmitter driven by a link encoder is a mappable + * endpoint. + */ +bool link_enc_cfg_is_transmitter_mappable( + struct dc_state *state, + struct link_encoder *link_enc); + +/* Return link using DIG link encoder resource. NULL if unused. */ +struct dc_link *link_enc_cfg_get_link_using_link_enc( + struct dc_state *state, + enum engine_id eng_id); + +/* Return DIG link encoder used by link. NULL if unused. */ +struct link_encoder *link_enc_cfg_get_link_enc_used_by_link( + struct dc_state *state, + struct dc_link *link); + +#endif /* DC_INC_LINK_ENC_CFG_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c b/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c index 6ee9dd833b85..1a5be2792055 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c @@ -187,6 +187,10 @@ static const struct irq_source_info_funcs vupdate_no_lock_irq_info_funcs = { .ack = NULL }; +static const struct irq_source_info_funcs dmub_trace_irq_info_funcs = { + .set = NULL, + .ack = NULL +}; static const struct irq_source_info_funcs vline0_irq_info_funcs = { .set = NULL, @@ -205,6 +209,9 @@ static const struct irq_source_info_funcs vline0_irq_info_funcs = { BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ mm ## block ## id ## _ ## reg_name +#define SRI_DMUB(reg_name)\ + BASE(mm ## reg_name ## _BASE_IDX) + \ + mm ## reg_name #define IRQ_REG_ENTRY(block, reg_num, reg1, mask1, reg2, mask2)\ .enable_reg = SRI(reg1, block, reg_num),\ @@ -220,7 +227,19 @@ static const struct irq_source_info_funcs vline0_irq_info_funcs = { .ack_value = \ block ## reg_num ## _ ## reg2 ## __ ## mask2 ## _MASK \ - +#define IRQ_REG_ENTRY_DMUB(reg1, mask1, reg2, mask2)\ + .enable_reg = SRI_DMUB(reg1),\ + .enable_mask = \ + reg1 ## __ ## mask1 ## _MASK,\ + .enable_value = {\ + reg1 ## __ ## mask1 ## _MASK,\ + ~reg1 ## __ ## mask1 ## _MASK \ + },\ + .ack_reg = SRI_DMUB(reg2),\ + .ack_mask = \ + reg2 ## __ ## mask2 ## _MASK,\ + .ack_value = \ + reg2 ## __ ## mask2 ## _MASK \ #define hpd_int_entry(reg_num)\ [DC_IRQ_SOURCE_HPD1 + reg_num] = {\ @@ -282,6 +301,13 @@ static const struct irq_source_info_funcs vline0_irq_info_funcs = { .funcs = &vline0_irq_info_funcs\ } +#define dmub_trace_int_entry()\ + [DC_IRQ_SOURCE_DMCUB_OUTBOX0] = {\ + IRQ_REG_ENTRY_DMUB(DMCUB_INTERRUPT_ENABLE, DMCUB_OUTBOX0_READY_INT_EN,\ + DMCUB_INTERRUPT_ACK, DMCUB_OUTBOX0_READY_INT_ACK),\ + .funcs = &dmub_trace_irq_info_funcs\ + } + #define dummy_irq_entry() \ {\ .funcs = &dummy_irq_info_funcs\ @@ -400,6 +426,7 @@ irq_source_info_dcn21[DAL_IRQ_SOURCES_NUMBER] = { vline0_int_entry(3), vline0_int_entry(4), vline0_int_entry(5), + dmub_trace_int_entry(), }; static const struct irq_service_funcs irq_service_funcs_dcn21 = { diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.c b/drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.c index 4ec6f6ad8c48..914ce2ce1c2f 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.c @@ -215,6 +215,9 @@ static const struct irq_source_info_funcs vline0_irq_info_funcs = { BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ mm ## block ## id ## _ ## reg_name +#define SRI_DMUB(reg_name)\ + BASE(mm ## reg_name ## _BASE_IDX) + \ + mm ## reg_name #define IRQ_REG_ENTRY(block, reg_num, reg1, mask1, reg2, mask2)\ .enable_reg = SRI(reg1, block, reg_num),\ @@ -230,7 +233,19 @@ static const struct irq_source_info_funcs vline0_irq_info_funcs = { .ack_value = \ block ## reg_num ## _ ## reg2 ## __ ## mask2 ## _MASK \ - +#define IRQ_REG_ENTRY_DMUB(reg1, mask1, reg2, mask2)\ + .enable_reg = SRI_DMUB(reg1),\ + .enable_mask = \ + reg1 ## __ ## mask1 ## _MASK,\ + .enable_value = {\ + reg1 ## __ ## mask1 ## _MASK,\ + ~reg1 ## __ ## mask1 ## _MASK \ + },\ + .ack_reg = SRI_DMUB(reg2),\ + .ack_mask = \ + reg2 ## __ ## mask2 ## _MASK,\ + .ack_value = \ + reg2 ## __ ## mask2 ## _MASK \ #define hpd_int_entry(reg_num)\ [DC_IRQ_SOURCE_HPD1 + reg_num] = {\ @@ -284,6 +299,13 @@ static const struct irq_source_info_funcs vline0_irq_info_funcs = { .funcs = &vline0_irq_info_funcs\ } +#define dmub_trace_int_entry()\ + [DC_IRQ_SOURCE_DMCUB_OUTBOX0] = {\ + IRQ_REG_ENTRY_DMUB(DMCUB_INTERRUPT_ENABLE, DMCUB_OUTBOX0_READY_INT_EN,\ + DMCUB_INTERRUPT_ACK, DMCUB_OUTBOX0_READY_INT_ACK),\ + .funcs = &dmub_trace_irq_info_funcs\ + } + #define dummy_irq_entry() \ {\ .funcs = &dummy_irq_info_funcs\ @@ -398,6 +420,7 @@ irq_source_info_dcn30[DAL_IRQ_SOURCES_NUMBER] = { vline0_int_entry(3), vline0_int_entry(4), vline0_int_entry(5), + dmub_trace_int_entry(), }; static const struct irq_service_funcs irq_service_funcs_dcn30 = { diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn302/irq_service_dcn302.c b/drivers/gpu/drm/amd/display/dc/irq/dcn302/irq_service_dcn302.c index 2313a5664f44..40fd34fb1d5e 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn302/irq_service_dcn302.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn302/irq_service_dcn302.c @@ -50,6 +50,8 @@ static enum dc_irq_source to_dal_irq_source_dcn302(struct irq_service *irq_servi return DC_IRQ_SOURCE_VBLANK5; case DCN_1_0__SRCID__DC_D6_OTG_VSTARTUP: return DC_IRQ_SOURCE_VBLANK6; + case DCN_1_0__SRCID__DMCUB_OUTBOX_HIGH_PRIORITY_READY_INT: + return DC_IRQ_SOURCE_DMCUB_OUTBOX0; case DCN_1_0__SRCID__OTG1_VERTICAL_INTERRUPT0_CONTROL: return DC_IRQ_SOURCE_DC1_VLINE0; case DCN_1_0__SRCID__OTG2_VERTICAL_INTERRUPT0_CONTROL: @@ -166,6 +168,11 @@ static const struct irq_source_info_funcs vblank_irq_info_funcs = { .ack = NULL }; +static const struct irq_source_info_funcs dmub_trace_irq_info_funcs = { + .set = NULL, + .ack = NULL +}; + static const struct irq_source_info_funcs vline0_irq_info_funcs = { .set = NULL, .ack = NULL @@ -181,6 +188,9 @@ static const struct irq_source_info_funcs vline0_irq_info_funcs = { BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ mm ## block ## id ## _ ## reg_name +#define SRI_DMUB(reg_name)\ + BASE(mm ## reg_name ## _BASE_IDX) + \ + mm ## reg_name #define IRQ_REG_ENTRY(block, reg_num, reg1, mask1, reg2, mask2)\ .enable_reg = SRI(reg1, block, reg_num),\ @@ -193,7 +203,26 @@ static const struct irq_source_info_funcs vline0_irq_info_funcs = { .ack_mask = block ## reg_num ## _ ## reg2 ## __ ## mask2 ## _MASK,\ .ack_value = block ## reg_num ## _ ## reg2 ## __ ## mask2 ## _MASK \ +#define dmub_trace_int_entry()\ + [DC_IRQ_SOURCE_DMCUB_OUTBOX0] = {\ + IRQ_REG_ENTRY_DMUB(DMCUB_INTERRUPT_ENABLE, DMCUB_OUTBOX0_READY_INT_EN,\ + DMCUB_INTERRUPT_ACK, DMCUB_OUTBOX0_READY_INT_ACK),\ + .funcs = &dmub_trace_irq_info_funcs\ + } +#define IRQ_REG_ENTRY_DMUB(reg1, mask1, reg2, mask2)\ + .enable_reg = SRI_DMUB(reg1),\ + .enable_mask = \ + reg1 ## __ ## mask1 ## _MASK,\ + .enable_value = {\ + reg1 ## __ ## mask1 ## _MASK,\ + ~reg1 ## __ ## mask1 ## _MASK \ + },\ + .ack_reg = SRI_DMUB(reg2),\ + .ack_mask = \ + reg2 ## __ ## mask2 ## _MASK,\ + .ack_value = \ + reg2 ## __ ## mask2 ## _MASK \ #define hpd_int_entry(reg_num)\ [DC_IRQ_SOURCE_HPD1 + reg_num] = {\ @@ -348,6 +377,7 @@ static const struct irq_source_info irq_source_info_dcn302[DAL_IRQ_SOURCES_NUMBE vline0_int_entry(2), vline0_int_entry(3), vline0_int_entry(4), + dmub_trace_int_entry(), }; static const struct irq_service_funcs irq_service_funcs_dcn302 = { diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h index f07b348f7c29..44003836fafd 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h @@ -47,10 +47,10 @@ /* Firmware versioning. */ #ifdef DMUB_EXPOSE_VERSION -#define DMUB_FW_VERSION_GIT_HASH 0xc29b1734b +#define DMUB_FW_VERSION_GIT_HASH 0x7f2db1846 #define DMUB_FW_VERSION_MAJOR 0 #define DMUB_FW_VERSION_MINOR 0 -#define DMUB_FW_VERSION_REVISION 56 +#define DMUB_FW_VERSION_REVISION 59 #define DMUB_FW_VERSION_TEST 0 #define DMUB_FW_VERSION_VBIOS 0 #define DMUB_FW_VERSION_HOTFIX 0 @@ -202,12 +202,7 @@ struct dmub_feature_caps { * Max PSR version supported by FW. */ uint8_t psr; -#ifndef TRIM_FAMS - uint8_t fw_assisted_mclk_switch; - uint8_t reserved[6]; -#else uint8_t reserved[7]; -#endif }; #if defined(__cplusplus) @@ -532,10 +527,6 @@ enum dmub_cmd_type { * Command type used for OUTBOX1 notification enable */ DMUB_CMD__OUTBOX1_ENABLE = 71, -#ifndef TRIM_FAMS - DMUB_CMD__FW_ASSISTED_MCLK_SWITCH = 76, -#endif - /** * Command type used for all VBIOS interface commands. */ @@ -1115,13 +1106,6 @@ enum dmub_cmd_psr_type { DMUB_CMD__PSR_FORCE_STATIC = 5, }; -#ifndef TRIM_FAMS -enum dmub_cmd_fams_type { - DMUB_CMD__FAMS_SETUP_FW_CTRL = 0, - DMUB_CMD__FAMS_DRR_UPDATE = 1, -}; -#endif - /** * PSR versions. */ @@ -1245,6 +1229,19 @@ struct dmub_cmd_psr_copy_settings_data { * Length of each horizontal line in us. */ uint32_t line_time_in_us; + /** + * FEC enable status in driver + */ + uint8_t fec_enable_status; + /** + * FEC re-enable delay when PSR exit. + * unit is 100us, range form 0~255(0xFF). + */ + uint8_t fec_enable_delay_in100us; + /** + * Explicit padding to 4 byte boundary. + */ + uint8_t pad3[2]; }; /** @@ -1791,24 +1788,6 @@ struct dmub_rb_cmd_drr_update { struct dmub_optc_state dmub_optc_state_req; }; -#ifndef TRIM_FAMS -struct dmub_cmd_fw_assisted_mclk_switch_pipe_data { - uint32_t pix_clk_100hz; - uint32_t min_refresh_in_uhz; - uint32_t max_ramp_step; -}; - -struct dmub_cmd_fw_assisted_mclk_switch_config { - uint32_t fams_enabled; - struct dmub_cmd_fw_assisted_mclk_switch_pipe_data pipe_data[DMUB_MAX_STREAMS]; -}; - -struct dmub_rb_cmd_fw_assisted_mclk_switch { - struct dmub_cmd_header header; - struct dmub_cmd_fw_assisted_mclk_switch_config config_data; -}; -#endif - /** * Data passed from driver to FW in a DMUB_CMD__VBIOS_LVTMA_CONTROL command. */ @@ -1951,9 +1930,6 @@ union dmub_rb_cmd { */ struct dmub_rb_cmd_query_feature_caps query_feature_caps; struct dmub_rb_cmd_drr_update drr_update; -#ifndef TRIM_FAMS - struct dmub_rb_cmd_fw_assisted_mclk_switch fw_assisted_mclk_switch; -#endif /** * Definition of a DMUB_CMD__VBIOS_LVTMA_CONTROL command. */ diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c index 8ba0a9e2da54..1cbb125b4063 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c @@ -415,6 +415,12 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub, if (!dmub->sw_init) return DMUB_STATUS_INVALID; + if (!inst_fb || !stack_fb || !data_fb || !bios_fb || !mail_fb || + !tracebuff_fb || !fw_state_fb || !scratch_mem_fb) { + ASSERT(0); + return DMUB_STATUS_INVALID; + } + dmub->fb_base = params->fb_base; dmub->fb_offset = params->fb_offset; dmub->psp_version = params->psp_version; @@ -422,101 +428,89 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub, if (dmub->hw_funcs.reset) dmub->hw_funcs.reset(dmub); - if (inst_fb && data_fb) { - cw0.offset.quad_part = inst_fb->gpu_addr; - cw0.region.base = DMUB_CW0_BASE; - cw0.region.top = cw0.region.base + inst_fb->size - 1; - - cw1.offset.quad_part = stack_fb->gpu_addr; - cw1.region.base = DMUB_CW1_BASE; - cw1.region.top = cw1.region.base + stack_fb->size - 1; - - if (params->load_inst_const && dmub->hw_funcs.backdoor_load) { - /** - * Read back all the instruction memory so we don't hang the - * DMCUB when backdoor loading if the write from x86 hasn't been - * flushed yet. This only occurs in backdoor loading. - */ - dmub_flush_buffer_mem(inst_fb); - dmub->hw_funcs.backdoor_load(dmub, &cw0, &cw1); - } - - } - - if (inst_fb && data_fb && bios_fb && mail_fb && tracebuff_fb && - fw_state_fb && scratch_mem_fb) { - cw2.offset.quad_part = data_fb->gpu_addr; - cw2.region.base = DMUB_CW0_BASE + inst_fb->size; - cw2.region.top = cw2.region.base + data_fb->size; - - cw3.offset.quad_part = bios_fb->gpu_addr; - cw3.region.base = DMUB_CW3_BASE; - cw3.region.top = cw3.region.base + bios_fb->size; + cw0.offset.quad_part = inst_fb->gpu_addr; + cw0.region.base = DMUB_CW0_BASE; + cw0.region.top = cw0.region.base + inst_fb->size - 1; - cw4.offset.quad_part = mail_fb->gpu_addr; - cw4.region.base = DMUB_CW4_BASE; - cw4.region.top = cw4.region.base + mail_fb->size; + cw1.offset.quad_part = stack_fb->gpu_addr; + cw1.region.base = DMUB_CW1_BASE; + cw1.region.top = cw1.region.base + stack_fb->size - 1; + if (params->load_inst_const && dmub->hw_funcs.backdoor_load) { /** - * Doubled the mailbox region to accomodate inbox and outbox. - * Note: Currently, currently total mailbox size is 16KB. It is split - * equally into 8KB between inbox and outbox. If this config is - * changed, then uncached base address configuration of outbox1 - * has to be updated in funcs->setup_out_mailbox. + * Read back all the instruction memory so we don't hang the + * DMCUB when backdoor loading if the write from x86 hasn't been + * flushed yet. This only occurs in backdoor loading. */ - inbox1.base = cw4.region.base; - inbox1.top = cw4.region.base + DMUB_RB_SIZE; - outbox1.base = inbox1.top; - outbox1.top = cw4.region.top; + dmub_flush_buffer_mem(inst_fb); + dmub->hw_funcs.backdoor_load(dmub, &cw0, &cw1); + } - cw5.offset.quad_part = tracebuff_fb->gpu_addr; - cw5.region.base = DMUB_CW5_BASE; - cw5.region.top = cw5.region.base + tracebuff_fb->size; + cw2.offset.quad_part = data_fb->gpu_addr; + cw2.region.base = DMUB_CW0_BASE + inst_fb->size; + cw2.region.top = cw2.region.base + data_fb->size; - outbox0.base = DMUB_REGION5_BASE + TRACE_BUFFER_ENTRY_OFFSET; - outbox0.top = outbox0.base + tracebuff_fb->size - TRACE_BUFFER_ENTRY_OFFSET; + cw3.offset.quad_part = bios_fb->gpu_addr; + cw3.region.base = DMUB_CW3_BASE; + cw3.region.top = cw3.region.base + bios_fb->size; + cw4.offset.quad_part = mail_fb->gpu_addr; + cw4.region.base = DMUB_CW4_BASE; + cw4.region.top = cw4.region.base + mail_fb->size; - cw6.offset.quad_part = fw_state_fb->gpu_addr; - cw6.region.base = DMUB_CW6_BASE; - cw6.region.top = cw6.region.base + fw_state_fb->size; + /** + * Doubled the mailbox region to accomodate inbox and outbox. + * Note: Currently, currently total mailbox size is 16KB. It is split + * equally into 8KB between inbox and outbox. If this config is + * changed, then uncached base address configuration of outbox1 + * has to be updated in funcs->setup_out_mailbox. + */ + inbox1.base = cw4.region.base; + inbox1.top = cw4.region.base + DMUB_RB_SIZE; + outbox1.base = inbox1.top; + outbox1.top = cw4.region.top; - dmub->fw_state = fw_state_fb->cpu_addr; + cw5.offset.quad_part = tracebuff_fb->gpu_addr; + cw5.region.base = DMUB_CW5_BASE; + cw5.region.top = cw5.region.base + tracebuff_fb->size; - dmub->scratch_mem_fb = *scratch_mem_fb; + outbox0.base = DMUB_REGION5_BASE + TRACE_BUFFER_ENTRY_OFFSET; + outbox0.top = outbox0.base + tracebuff_fb->size - TRACE_BUFFER_ENTRY_OFFSET; - if (dmub->hw_funcs.setup_windows) - dmub->hw_funcs.setup_windows(dmub, &cw2, &cw3, &cw4, - &cw5, &cw6); + cw6.offset.quad_part = fw_state_fb->gpu_addr; + cw6.region.base = DMUB_CW6_BASE; + cw6.region.top = cw6.region.base + fw_state_fb->size; - if (dmub->hw_funcs.setup_outbox0) - dmub->hw_funcs.setup_outbox0(dmub, &outbox0); + dmub->fw_state = fw_state_fb->cpu_addr; - if (dmub->hw_funcs.setup_mailbox) - dmub->hw_funcs.setup_mailbox(dmub, &inbox1); - if (dmub->hw_funcs.setup_out_mailbox) - dmub->hw_funcs.setup_out_mailbox(dmub, &outbox1); - } + dmub->scratch_mem_fb = *scratch_mem_fb; - if (mail_fb) { - dmub_memset(&rb_params, 0, sizeof(rb_params)); - rb_params.ctx = dmub; - rb_params.base_address = mail_fb->cpu_addr; - rb_params.capacity = DMUB_RB_SIZE; + if (dmub->hw_funcs.setup_windows) + dmub->hw_funcs.setup_windows(dmub, &cw2, &cw3, &cw4, &cw5, &cw6); - dmub_rb_init(&dmub->inbox1_rb, &rb_params); + if (dmub->hw_funcs.setup_outbox0) + dmub->hw_funcs.setup_outbox0(dmub, &outbox0); - // Initialize outbox1 ring buffer - rb_params.ctx = dmub; - rb_params.base_address = (void *) ((uint8_t *) (mail_fb->cpu_addr) + DMUB_RB_SIZE); - rb_params.capacity = DMUB_RB_SIZE; - dmub_rb_init(&dmub->outbox1_rb, &rb_params); + if (dmub->hw_funcs.setup_mailbox) + dmub->hw_funcs.setup_mailbox(dmub, &inbox1); + if (dmub->hw_funcs.setup_out_mailbox) + dmub->hw_funcs.setup_out_mailbox(dmub, &outbox1); - } + dmub_memset(&rb_params, 0, sizeof(rb_params)); + rb_params.ctx = dmub; + rb_params.base_address = mail_fb->cpu_addr; + rb_params.capacity = DMUB_RB_SIZE; + dmub_rb_init(&dmub->inbox1_rb, &rb_params); + + // Initialize outbox1 ring buffer + rb_params.ctx = dmub; + rb_params.base_address = (void *) ((uint8_t *) (mail_fb->cpu_addr) + DMUB_RB_SIZE); + rb_params.capacity = DMUB_RB_SIZE; + dmub_rb_init(&dmub->outbox1_rb, &rb_params); dmub_memset(&outbox0_rb_params, 0, sizeof(outbox0_rb_params)); outbox0_rb_params.ctx = dmub; - outbox0_rb_params.base_address = (void *)((uint64_t)(tracebuff_fb->cpu_addr) + TRACE_BUFFER_ENTRY_OFFSET); + outbox0_rb_params.base_address = (void *)((uintptr_t)(tracebuff_fb->cpu_addr) + TRACE_BUFFER_ENTRY_OFFSET); outbox0_rb_params.capacity = tracebuff_fb->size - dmub_align(TRACE_BUFFER_ENTRY_OFFSET, 64); dmub_rb_init(&dmub->outbox0_rb, &outbox0_rb_params); @@ -653,6 +647,8 @@ dmub_srv_send_gpint_command(struct dmub_srv *dmub, dmub->hw_funcs.set_gpint(dmub, reg); for (i = 0; i < timeout_us; ++i) { + udelay(1); + if (dmub->hw_funcs.is_gpint_acked(dmub, reg)) return DMUB_STATUS_OK; } diff --git a/drivers/gpu/drm/amd/display/include/logger_types.h b/drivers/gpu/drm/amd/display/include/logger_types.h index 21bbee17c527..571fcf23cea9 100644 --- a/drivers/gpu/drm/amd/display/include/logger_types.h +++ b/drivers/gpu/drm/amd/display/include/logger_types.h @@ -36,6 +36,9 @@ #define DC_LOG_DC(...) DRM_DEBUG_KMS(__VA_ARGS__) #define DC_LOG_DTN(...) DRM_DEBUG_KMS(__VA_ARGS__) #define DC_LOG_SURFACE(...) pr_debug("[SURFACE]:"__VA_ARGS__) +#define DC_LOG_CURSOR(...) pr_debug("[CURSOR]:"__VA_ARGS__) +#define DC_LOG_PFLIP(...) pr_debug("[PFLIP]:"__VA_ARGS__) +#define DC_LOG_VBLANK(...) pr_debug("[VBLANK]:"__VA_ARGS__) #define DC_LOG_HW_HOTPLUG(...) DRM_DEBUG_KMS(__VA_ARGS__) #define DC_LOG_HW_LINK_TRAINING(...) pr_debug("[HW_LINK_TRAINING]:"__VA_ARGS__) #define DC_LOG_HW_SET_MODE(...) DRM_DEBUG_KMS(__VA_ARGS__) diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c index 5c67e12b2e55..ef742d95ef05 100644 --- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c +++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c @@ -942,7 +942,7 @@ static void hermite_spline_eetf(struct fixed31_32 input_x, static bool build_freesync_hdr(struct pwl_float_data_ex *rgb_regamma, uint32_t hw_points_num, const struct hw_x_point *coordinate_x, - const struct freesync_hdr_tf_params *fs_params, + const struct hdr_tm_params *fs_params, struct calculate_buffer *cal_buffer) { uint32_t i; @@ -2027,7 +2027,7 @@ rgb_user_alloc_fail: static bool calculate_curve(enum dc_transfer_func_predefined trans, struct dc_transfer_func_distributed_points *points, struct pwl_float_data_ex *rgb_regamma, - const struct freesync_hdr_tf_params *fs_params, + const struct hdr_tm_params *fs_params, uint32_t sdr_ref_white_level, struct calculate_buffer *cal_buffer) { @@ -2106,7 +2106,7 @@ static bool calculate_curve(enum dc_transfer_func_predefined trans, bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf, const struct dc_gamma *ramp, bool mapUserRamp, bool canRomBeUsed, - const struct freesync_hdr_tf_params *fs_params, + const struct hdr_tm_params *fs_params, struct calculate_buffer *cal_buffer) { struct dc_transfer_func_distributed_points *tf_pts = &output_tf->tf_pts; diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.h b/drivers/gpu/drm/amd/display/modules/color/color_gamma.h index 7563457e2ff4..2893abf48208 100644 --- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.h +++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.h @@ -76,7 +76,7 @@ struct regamma_lut { }; }; -struct freesync_hdr_tf_params { +struct hdr_tm_params { unsigned int sdr_white_level; unsigned int min_content; // luminance in 1/10000 nits unsigned int max_content; // luminance in nits @@ -108,7 +108,7 @@ void precompute_de_pq(void); bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf, const struct dc_gamma *ramp, bool mapUserRamp, bool canRomBeUsed, - const struct freesync_hdr_tf_params *fs_params, + const struct hdr_tm_params *fs_params, struct calculate_buffer *cal_buffer); bool mod_color_calculate_degamma_params(struct dc_color_caps *dc_caps, diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c index e5f9d7704a63..3f4f44b44e6a 100644 --- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c +++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c @@ -118,7 +118,7 @@ static unsigned int calc_duration_in_us_from_v_total( return duration_in_us; } -static unsigned int calc_v_total_from_refresh( +unsigned int mod_freesync_calc_v_total_from_refresh( const struct dc_stream_state *stream, unsigned int refresh_in_uhz) { @@ -280,10 +280,10 @@ static void apply_below_the_range(struct core_freesync *core_freesync, /* Restore FreeSync */ in_out_vrr->adjust.v_total_min = - calc_v_total_from_refresh(stream, + mod_freesync_calc_v_total_from_refresh(stream, in_out_vrr->max_refresh_in_uhz); in_out_vrr->adjust.v_total_max = - calc_v_total_from_refresh(stream, + mod_freesync_calc_v_total_from_refresh(stream, in_out_vrr->min_refresh_in_uhz); /* BTR set to "active" so engage */ } else { @@ -442,16 +442,16 @@ static void apply_fixed_refresh(struct core_freesync *core_freesync, if (update) { if (in_out_vrr->fixed.fixed_active) { in_out_vrr->adjust.v_total_min = - calc_v_total_from_refresh( + mod_freesync_calc_v_total_from_refresh( stream, in_out_vrr->max_refresh_in_uhz); in_out_vrr->adjust.v_total_max = in_out_vrr->adjust.v_total_min; } else { in_out_vrr->adjust.v_total_min = - calc_v_total_from_refresh(stream, + mod_freesync_calc_v_total_from_refresh(stream, in_out_vrr->max_refresh_in_uhz); in_out_vrr->adjust.v_total_max = - calc_v_total_from_refresh(stream, + mod_freesync_calc_v_total_from_refresh(stream, in_out_vrr->min_refresh_in_uhz); } } @@ -543,8 +543,8 @@ static void build_vrr_infopacket_data_v1(const struct mod_vrr_params *vrr, infopacket->sb[6] |= 0x02; /* PB6 = [Bit 2 = FreeSync Active] */ - if (vrr->state == VRR_STATE_ACTIVE_VARIABLE || - vrr->state == VRR_STATE_ACTIVE_FIXED) + if (vrr->state != VRR_STATE_DISABLED && + vrr->state != VRR_STATE_UNSUPPORTED) infopacket->sb[6] |= 0x04; // For v1 & 2 infoframes program nominal if non-fs mode, otherwise full range @@ -1082,10 +1082,10 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync, refresh_range >= MIN_REFRESH_RANGE) { in_out_vrr->adjust.v_total_min = - calc_v_total_from_refresh(stream, + mod_freesync_calc_v_total_from_refresh(stream, in_out_vrr->max_refresh_in_uhz); in_out_vrr->adjust.v_total_max = - calc_v_total_from_refresh(stream, + mod_freesync_calc_v_total_from_refresh(stream, in_out_vrr->min_refresh_in_uhz); } else if (in_out_vrr->state == VRR_STATE_ACTIVE_FIXED) { in_out_vrr->fixed.target_refresh_in_uhz = @@ -1099,7 +1099,7 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync, } else { in_out_vrr->fixed.fixed_active = true; in_out_vrr->adjust.v_total_min = - calc_v_total_from_refresh(stream, + mod_freesync_calc_v_total_from_refresh(stream, in_out_vrr->fixed.target_refresh_in_uhz); in_out_vrr->adjust.v_total_max = in_out_vrr->adjust.v_total_min; @@ -1206,10 +1206,10 @@ void mod_freesync_handle_v_update(struct mod_freesync *mod_freesync, /* Restore FreeSync */ if (in_out_vrr->btr.frame_counter == 0) { in_out_vrr->adjust.v_total_min = - calc_v_total_from_refresh(stream, + mod_freesync_calc_v_total_from_refresh(stream, in_out_vrr->max_refresh_in_uhz); in_out_vrr->adjust.v_total_max = - calc_v_total_from_refresh(stream, + mod_freesync_calc_v_total_from_refresh(stream, in_out_vrr->min_refresh_in_uhz); } } @@ -1267,6 +1267,21 @@ unsigned long long mod_freesync_calc_nominal_field_rate( return nominal_field_rate_in_uhz; } +unsigned long long mod_freesync_calc_field_rate_from_timing( + unsigned int vtotal, unsigned int htotal, unsigned int pix_clk) +{ + unsigned long long field_rate_in_uhz = 0; + unsigned int total = htotal * vtotal; + + /* Calculate nominal field rate for stream, rounded up to nearest integer */ + field_rate_in_uhz = pix_clk; + field_rate_in_uhz *= 1000000ULL; + + field_rate_in_uhz = div_u64(field_rate_in_uhz, total); + + return field_rate_in_uhz; +} + bool mod_freesync_is_valid_range(uint32_t min_refresh_cap_in_uhz, uint32_t max_refresh_cap_in_uhz, uint32_t nominal_field_rate_in_uhz) diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c index 20e554e771d1..68a6481d7f8f 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c @@ -53,7 +53,7 @@ static uint8_t is_cp_desired_hdcp1(struct mod_hdcp *hdcp) */ for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) { if (hdcp->displays[i].state != MOD_HDCP_DISPLAY_INACTIVE && - !hdcp->displays[i].adjust.disable) { + hdcp->displays[i].adjust.disable != MOD_HDCP_DISPLAY_DISABLE_AUTHENTICATION) { is_auth_needed = 1; break; } @@ -74,7 +74,7 @@ static uint8_t is_cp_desired_hdcp2(struct mod_hdcp *hdcp) */ for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) { if (hdcp->displays[i].state != MOD_HDCP_DISPLAY_INACTIVE && - !hdcp->displays[i].adjust.disable) { + hdcp->displays[i].adjust.disable != MOD_HDCP_DISPLAY_DISABLE_AUTHENTICATION) { is_auth_needed = 1; break; } @@ -314,6 +314,9 @@ enum mod_hdcp_status mod_hdcp_add_display(struct mod_hdcp *hdcp, goto out; } + /* save current encryption states to restore after next authentication */ + mod_hdcp_save_current_encryption_states(hdcp); + /* reset existing authentication status */ status = reset_authentication(hdcp, output); if (status != MOD_HDCP_STATUS_SUCCESS) @@ -360,6 +363,9 @@ enum mod_hdcp_status mod_hdcp_remove_display(struct mod_hdcp *hdcp, goto out; } + /* save current encryption states to restore after next authentication */ + mod_hdcp_save_current_encryption_states(hdcp); + /* stop current authentication */ status = reset_authentication(hdcp, output); if (status != MOD_HDCP_STATUS_SUCCESS) diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h index 5c22cf7e6118..3ce91db560d1 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h @@ -331,6 +331,8 @@ enum mod_hdcp_status mod_hdcp_add_display_to_topology( struct mod_hdcp *hdcp, struct mod_hdcp_display *display); enum mod_hdcp_status mod_hdcp_remove_display_from_topology( struct mod_hdcp *hdcp, uint8_t index); +bool mod_hdcp_is_link_encryption_enabled(struct mod_hdcp *hdcp); +void mod_hdcp_save_current_encryption_states(struct mod_hdcp *hdcp); enum mod_hdcp_status mod_hdcp_hdcp1_create_session(struct mod_hdcp *hdcp); enum mod_hdcp_status mod_hdcp_hdcp1_destroy_session(struct mod_hdcp *hdcp); enum mod_hdcp_status mod_hdcp_hdcp1_validate_rx(struct mod_hdcp *hdcp); @@ -339,8 +341,6 @@ enum mod_hdcp_status mod_hdcp_hdcp1_validate_ksvlist_vp(struct mod_hdcp *hdcp); enum mod_hdcp_status mod_hdcp_hdcp1_enable_dp_stream_encryption( struct mod_hdcp *hdcp); enum mod_hdcp_status mod_hdcp_hdcp1_link_maintenance(struct mod_hdcp *hdcp); -enum mod_hdcp_status mod_hdcp_hdcp1_get_link_encryption_status(struct mod_hdcp *hdcp, - enum mod_hdcp_encryption_status *encryption_status); enum mod_hdcp_status mod_hdcp_hdcp2_create_session(struct mod_hdcp *hdcp); enum mod_hdcp_status mod_hdcp_hdcp2_destroy_session(struct mod_hdcp *hdcp); enum mod_hdcp_status mod_hdcp_hdcp2_prepare_ake_init(struct mod_hdcp *hdcp); diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c index 73ca49f05bd3..eeac14300a2a 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c @@ -256,10 +256,12 @@ static enum mod_hdcp_status authenticated(struct mod_hdcp *hdcp, goto out; } - if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp1_link_maintenance, + mod_hdcp_execute_and_set(mod_hdcp_hdcp1_link_maintenance, &input->link_maintenance, &status, - hdcp, "link_maintenance")) - goto out; + hdcp, "link_maintenance"); + + if (status != MOD_HDCP_STATUS_SUCCESS) + mod_hdcp_save_current_encryption_states(hdcp); out: return status; } @@ -425,19 +427,24 @@ static enum mod_hdcp_status authenticated_dp(struct mod_hdcp *hdcp, event_ctx->unexpected_event = 1; goto out; } - - if (!mod_hdcp_execute_and_set(mod_hdcp_read_bstatus, - &input->bstatus_read, &status, - hdcp, "bstatus_read")) - goto out; - if (!mod_hdcp_execute_and_set(check_link_integrity_dp, - &input->link_integrity_check, &status, - hdcp, "link_integrity_check")) - goto out; - if (!mod_hdcp_execute_and_set(check_no_reauthentication_request_dp, - &input->reauth_request_check, &status, - hdcp, "reauth_request_check")) + if (!mod_hdcp_is_link_encryption_enabled(hdcp)) goto out; + + if (status == MOD_HDCP_STATUS_SUCCESS) + mod_hdcp_execute_and_set(mod_hdcp_read_bstatus, + &input->bstatus_read, &status, + hdcp, "bstatus_read"); + if (status == MOD_HDCP_STATUS_SUCCESS) + mod_hdcp_execute_and_set(check_link_integrity_dp, + &input->link_integrity_check, &status, + hdcp, "link_integrity_check"); + if (status == MOD_HDCP_STATUS_SUCCESS) + mod_hdcp_execute_and_set(check_no_reauthentication_request_dp, + &input->reauth_request_check, &status, + hdcp, "reauth_request_check"); + + if (status != MOD_HDCP_STATUS_SUCCESS) + mod_hdcp_save_current_encryption_states(hdcp); out: return status; } diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_transition.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_transition.c index 24ab95b093f7..3dda8c1d83fc 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_transition.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_transition.c @@ -93,7 +93,7 @@ enum mod_hdcp_status mod_hdcp_hdcp1_transition(struct mod_hdcp *hdcp, } break; case H1_A45_AUTHENTICATED: - if (input->link_maintenance != PASS) { + if (input->link_maintenance == FAIL) { /* 1A-07: consider invalid ri' a failure */ /* 1A-07a: consider read ri' not returned a failure */ fail_and_restart_in_ms(0, &status, output); @@ -243,8 +243,8 @@ enum mod_hdcp_status mod_hdcp_hdcp1_dp_transition(struct mod_hdcp *hdcp, } break; case D1_A4_AUTHENTICATED: - if (input->link_integrity_check != PASS || - input->reauth_request_check != PASS) { + if (input->link_integrity_check == FAIL || + input->reauth_request_check == FAIL) { /* 1A-07: restart hdcp on a link integrity failure */ fail_and_restart_in_ms(0, &status, output); break; diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_execution.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_execution.c index a0895a7efda2..f164f6a5d4dc 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_execution.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_execution.c @@ -564,11 +564,13 @@ static enum mod_hdcp_status authenticated(struct mod_hdcp *hdcp, event_ctx->unexpected_event = 1; goto out; } - - if (!process_rxstatus(hdcp, event_ctx, input, &status)) - goto out; - if (event_ctx->rx_id_list_ready) + if (!mod_hdcp_is_link_encryption_enabled(hdcp)) goto out; + + process_rxstatus(hdcp, event_ctx, input, &status); + + if (status != MOD_HDCP_STATUS_SUCCESS) + mod_hdcp_save_current_encryption_states(hdcp); out: return status; } diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_transition.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_transition.c index e738c7ae66ec..b0306ed6d6b4 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_transition.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_transition.c @@ -245,8 +245,8 @@ enum mod_hdcp_status mod_hdcp_hdcp2_transition(struct mod_hdcp *hdcp, HDCP_FULL_DDC_TRACE(hdcp); break; case H2_A5_AUTHENTICATED: - if (input->rxstatus_read != PASS || - input->reauth_request_check != PASS) { + if (input->rxstatus_read == FAIL || + input->reauth_request_check == FAIL) { fail_and_restart_in_ms(0, &status, output); break; } else if (event_ctx->rx_id_list_ready && conn->is_repeater) { @@ -562,11 +562,11 @@ enum mod_hdcp_status mod_hdcp_hdcp2_dp_transition(struct mod_hdcp *hdcp, HDCP_FULL_DDC_TRACE(hdcp); break; case D2_A5_AUTHENTICATED: - if (input->rxstatus_read != PASS || - input->reauth_request_check != PASS) { + if (input->rxstatus_read == FAIL || + input->reauth_request_check == FAIL) { fail_and_restart_in_ms(0, &status, output); break; - } else if (input->link_integrity_check_dp != PASS) { + } else if (input->link_integrity_check_dp == FAIL) { if (hdcp->connection.hdcp2_retry_count >= 1) adjust->hdcp2.force_type = MOD_HDCP_FORCE_TYPE_0; fail_and_restart_in_ms(0, &status, output); diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c index 904ce9b88088..9d7ca316dc3f 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c @@ -914,3 +914,13 @@ enum mod_hdcp_status mod_hdcp_hdcp2_validate_stream_ready(struct mod_hdcp *hdcp) return status; } +bool mod_hdcp_is_link_encryption_enabled(struct mod_hdcp *hdcp) +{ + /* unsupported */ + return true; +} + +void mod_hdcp_save_current_encryption_states(struct mod_hdcp *hdcp) +{ + /* unsupported */ +} diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h b/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h index b64cd5bdc7b5..75a158a2514c 100644 --- a/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h +++ b/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h @@ -171,10 +171,15 @@ void mod_freesync_handle_v_update(struct mod_freesync *mod_freesync, unsigned long long mod_freesync_calc_nominal_field_rate( const struct dc_stream_state *stream); +unsigned long long mod_freesync_calc_field_rate_from_timing( + unsigned int vtotal, unsigned int htotal, unsigned int pix_clk); + bool mod_freesync_is_valid_range(uint32_t min_refresh_cap_in_uhz, uint32_t max_refresh_cap_in_uhz, uint32_t nominal_field_rate_in_uhz); - +unsigned int mod_freesync_calc_v_total_from_refresh( + const struct dc_stream_state *stream, + unsigned int refresh_in_uhz); #endif diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h b/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h index d223ed3be5d3..acbeada5215b 100644 --- a/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h +++ b/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h @@ -120,6 +120,12 @@ enum mod_hdcp_display_state { MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED }; +enum mod_hdcp_display_disable_option { + MOD_HDCP_DISPLAY_NOT_DISABLE = 0, + MOD_HDCP_DISPLAY_DISABLE_AUTHENTICATION, + MOD_HDCP_DISPLAY_DISABLE_ENCRYPTION, +}; + struct mod_hdcp_ddc { void *handle; struct { @@ -149,8 +155,8 @@ struct mod_hdcp_psp { }; struct mod_hdcp_display_adjustment { - uint8_t disable : 1; - uint8_t reserved : 7; + uint8_t disable : 2; + uint8_t reserved : 6; }; struct mod_hdcp_link_adjustment_hdcp1 { @@ -255,8 +261,6 @@ struct mod_hdcp_config { uint8_t index; }; -struct mod_hdcp; - /* dm allocates memory of mod_hdcp per dc_link on dm init based on memory size*/ size_t mod_hdcp_get_memory_size(void); |