]> Git Repo - J-linux.git/commitdiff
Merge tag 'amd-drm-next-6.8-2023-12-08' of https://gitlab.freedesktop.org/agd5f/linux...
authorDave Airlie <[email protected]>
Wed, 13 Dec 2023 05:42:00 +0000 (15:42 +1000)
committerDave Airlie <[email protected]>
Wed, 13 Dec 2023 05:55:55 +0000 (15:55 +1000)
amd-drm-next-6.8-2023-12-08:

amdgpu:
- SR-IOV fixes
- DCN 3.5 updates
- Backlight fixes
- MST fixes
- DMCUB fixes
- DPIA fixes
- Display powergating updates
- Enable writeback connectors
- Misc code cleanups
- Add more register state debugging for aquavanjaram
- Suspend fix
- Clockgating fixes
- SMU 14 updates
- PSR fixes
- MES logging updates
- Misc fixes

amdkfd:
- SVM fix

radeon:
- Fix potential memory leaks in error paths

Signed-off-by: Dave Airlie <[email protected]>
From: Alex Deucher <[email protected]>
Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1  2 
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c

index d6e325c848eb4ca093a85085ef787ec3a4c9d0cb,90868a54d4ddf3efb051f07949d5c6bf7a116c2d..8e6fe9860cd6f6aa44e0c63d0fc971a7248fb052
@@@ -54,6 -54,7 +54,7 @@@
  #include "amdgpu_dm_crtc.h"
  #include "amdgpu_dm_hdcp.h"
  #include <drm/display/drm_hdcp_helper.h>
+ #include "amdgpu_dm_wb.h"
  #include "amdgpu_pm.h"
  #include "amdgpu_atombios.h"
  
@@@ -92,6 -93,7 +93,6 @@@
  #include <drm/drm_vblank.h>
  #include <drm/drm_audio_component.h>
  #include <drm/drm_gem_atomic_helper.h>
 -#include <drm/drm_plane_helper.h>
  
  #include <acpi/video.h>
  
@@@ -576,6 -578,7 +577,7 @@@ static void dm_crtc_high_irq(void *inte
  {
        struct common_irq_params *irq_params = interrupt_params;
        struct amdgpu_device *adev = irq_params->adev;
+       struct drm_writeback_job *job;
        struct amdgpu_crtc *acrtc;
        unsigned long flags;
        int vrr_active;
        if (!acrtc)
                return;
  
+       if (acrtc->wb_pending) {
+               if (acrtc->wb_conn) {
+                       spin_lock_irqsave(&acrtc->wb_conn->job_lock, flags);
+                       job = list_first_entry_or_null(&acrtc->wb_conn->job_queue,
+                                                      struct drm_writeback_job,
+                                                      list_entry);
+                       spin_unlock_irqrestore(&acrtc->wb_conn->job_lock, flags);
+                       if (job) {
+                               unsigned int v_total, refresh_hz;
+                               struct dc_stream_state *stream = acrtc->dm_irq_params.stream;
+                               v_total = stream->adjust.v_total_max ?
+                                         stream->adjust.v_total_max : stream->timing.v_total;
+                               refresh_hz = div_u64((uint64_t) stream->timing.pix_clk_100hz *
+                                            100LL, (v_total * stream->timing.h_total));
+                               mdelay(1000 / refresh_hz);
+                               drm_writeback_signal_completion(acrtc->wb_conn, 0);
+                               dc_stream_fc_disable_writeback(adev->dm.dc,
+                                                              acrtc->dm_irq_params.stream, 0);
+                       }
+               } else
+                       DRM_ERROR("%s: no amdgpu_crtc wb_conn\n", __func__);
+               acrtc->wb_pending = false;
+       }
        vrr_active = amdgpu_dm_crtc_vrr_active_irq(acrtc);
  
        drm_dbg_vbl(adev_to_drm(adev),
@@@ -726,6 -756,10 +755,10 @@@ static void dmub_hpd_callback(struct am
  
        drm_connector_list_iter_begin(dev, &iter);
        drm_for_each_connector_iter(connector, &iter) {
+               if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+                       continue;
                aconnector = to_amdgpu_dm_connector(connector);
                if (link && aconnector->dc_link == link) {
                        if (notify->type == DMUB_NOTIFICATION_HPD)
@@@ -949,6 -983,10 +982,10 @@@ static int amdgpu_dm_audio_component_ge
  
        drm_connector_list_iter_begin(dev, &conn_iter);
        drm_for_each_connector_iter(connector, &conn_iter) {
+               if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+                       continue;
                aconnector = to_amdgpu_dm_connector(connector);
                if (aconnector->audio_inst != port)
                        continue;
@@@ -1674,6 -1712,10 +1711,10 @@@ static int amdgpu_dm_init(struct amdgpu
        init_data.nbio_reg_offsets = adev->reg_offset[NBIO_HWIP][0];
        init_data.clk_reg_offsets = adev->reg_offset[CLK_HWIP][0];
  
+       /* Enable DWB for tested platforms only */
+       if (adev->ip_versions[DCE_HWIP][0] >= IP_VERSION(3, 0, 0))
+               init_data.num_virtual_links = 1;
        INIT_LIST_HEAD(&adev->dm.da_list);
  
        retrieve_dmi_info(&adev->dm);
@@@ -2251,6 -2293,10 +2292,10 @@@ static int detect_mst_link_for_all_conn
  
        drm_connector_list_iter_begin(dev, &iter);
        drm_for_each_connector_iter(connector, &iter) {
+               if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+                       continue;
                aconnector = to_amdgpu_dm_connector(connector);
                if (aconnector->dc_link->type == dc_connection_mst_branch &&
                    aconnector->mst_mgr.aux) {
@@@ -2379,6 -2425,10 +2424,10 @@@ static void s3_handle_mst(struct drm_de
  
        drm_connector_list_iter_begin(dev, &iter);
        drm_for_each_connector_iter(connector, &iter) {
+               if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+                       continue;
                aconnector = to_amdgpu_dm_connector(connector);
                if (aconnector->dc_link->type != dc_connection_mst_branch ||
                    aconnector->mst_root)
@@@ -2642,7 -2692,7 +2691,7 @@@ static int dm_suspend(void *handle
        return 0;
  }
  
- struct amdgpu_dm_connector *
+ struct drm_connector *
  amdgpu_dm_find_first_crtc_matching_connector(struct drm_atomic_state *state,
                                             struct drm_crtc *crtc)
  {
                crtc_from_state = new_con_state->crtc;
  
                if (crtc_from_state == crtc)
-                       return to_amdgpu_dm_connector(connector);
+                       return connector;
        }
  
        return NULL;
@@@ -2900,6 -2950,10 +2949,10 @@@ static int dm_resume(void *handle
        /* Do detection*/
        drm_connector_list_iter_begin(ddev, &iter);
        drm_for_each_connector_iter(connector, &iter) {
+               if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+                       continue;
                aconnector = to_amdgpu_dm_connector(connector);
  
                if (!aconnector->dc_link)
@@@ -3473,6 -3527,9 +3526,9 @@@ static void register_hpd_handlers(struc
        list_for_each_entry(connector,
                        &dev->mode_config.connector_list, head) {
  
+               if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+                       continue;
                aconnector = to_amdgpu_dm_connector(connector);
                dc_link = aconnector->dc_link;
  
@@@ -4464,6 -4521,28 +4520,28 @@@ static int amdgpu_dm_initialize_drm_dev
                        continue;
                }
  
+               link = dc_get_link_at_index(dm->dc, i);
+               if (link->connector_signal == SIGNAL_TYPE_VIRTUAL) {
+                       struct amdgpu_dm_wb_connector *wbcon = kzalloc(sizeof(*wbcon), GFP_KERNEL);
+                       if (!wbcon) {
+                               DRM_ERROR("KMS: Failed to allocate writeback connector\n");
+                               continue;
+                       }
+                       if (amdgpu_dm_wb_connector_init(dm, wbcon, i)) {
+                               DRM_ERROR("KMS: Failed to initialize writeback connector\n");
+                               kfree(wbcon);
+                               continue;
+                       }
+                       link->psr_settings.psr_feature_enabled = false;
+                       link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
+                       continue;
+               }
                aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL);
                if (!aconnector)
                        goto fail;
                        goto fail;
                }
  
-               link = dc_get_link_at_index(dm->dc, i);
                if (!dc_link_detect_connection_type(link, &new_connection_type))
                        DRM_ERROR("KMS: Failed to detect connector\n");
  
@@@ -5164,6 -5241,9 +5240,9 @@@ static void fill_dc_dirty_rects(struct 
        if (plane->type == DRM_PLANE_TYPE_CURSOR)
                return;
  
+       if (new_plane_state->rotation != DRM_MODE_ROTATE_0)
+               goto ffu;
        num_clips = drm_plane_get_damage_clips_count(new_plane_state);
        clips = drm_plane_get_damage_clips(new_plane_state);
  
@@@ -5490,10 -5570,13 +5569,13 @@@ static void fill_stream_properties_from
  {
        struct dc_crtc_timing *timing_out = &stream->timing;
        const struct drm_display_info *info = &connector->display_info;
-       struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
+       struct amdgpu_dm_connector *aconnector = NULL;
        struct hdmi_vendor_infoframe hv_frame;
        struct hdmi_avi_infoframe avi_frame;
  
+       if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
+               aconnector = to_amdgpu_dm_connector(connector);
        memset(&hv_frame, 0, sizeof(hv_frame));
        memset(&avi_frame, 0, sizeof(avi_frame));
  
                        && stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
                timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
        else if (drm_mode_is_420_also(info, mode_in)
+                       && aconnector
                        && aconnector->force_yuv420_output)
                timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
        else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCBCR444)
                timing_out->hdmi_vic = hv_frame.vic;
        }
  
-       if (is_freesync_video_mode(mode_in, aconnector)) {
+       if (aconnector && 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;
@@@ -5662,13 -5746,13 +5745,13 @@@ decide_crtc_timing_for_drm_display_mode
  }
  
  static struct dc_sink *
- create_fake_sink(struct amdgpu_dm_connector *aconnector)
+ create_fake_sink(struct dc_link *link)
  {
        struct dc_sink_init_data sink_init_data = { 0 };
        struct dc_sink *sink = NULL;
  
-       sink_init_data.link = aconnector->dc_link;
-       sink_init_data.sink_signal = aconnector->dc_link->connector_signal;
+       sink_init_data.link = link;
+       sink_init_data.sink_signal = link->connector_signal;
  
        sink = dc_sink_create(&sink_init_data);
        if (!sink) {
@@@ -6018,14 -6102,14 +6101,14 @@@ static void apply_dsc_policy_for_stream
  }
  
  static struct dc_stream_state *
- create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
+ create_stream_for_sink(struct drm_connector *connector,
                       const struct drm_display_mode *drm_mode,
                       const struct dm_connector_state *dm_state,
                       const struct dc_stream_state *old_stream,
                       int requested_bpc)
  {
+       struct amdgpu_dm_connector *aconnector = NULL;
        struct drm_display_mode *preferred_mode = NULL;
-       struct drm_connector *drm_connector;
        const struct drm_connector_state *con_state = &dm_state->base;
        struct dc_stream_state *stream = NULL;
        struct drm_display_mode mode;
        enum color_transfer_func tf = TRANSFER_FUNC_UNKNOWN;
        struct dsc_dec_dpcd_caps dsc_caps;
  
+       struct dc_link *link = NULL;
        struct dc_sink *sink = NULL;
  
        drm_mode_init(&mode, drm_mode);
        memset(&saved_mode, 0, sizeof(saved_mode));
  
-       if (aconnector == NULL) {
-               DRM_ERROR("aconnector is NULL!\n");
+       if (connector == NULL) {
+               DRM_ERROR("connector is NULL!\n");
                return stream;
        }
  
-       drm_connector = &aconnector->base;
+       if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK) {
+               aconnector = NULL;
+               aconnector = to_amdgpu_dm_connector(connector);
+               link = aconnector->dc_link;
+       } else {
+               struct drm_writeback_connector *wbcon = NULL;
+               struct amdgpu_dm_wb_connector *dm_wbcon = NULL;
+               wbcon = drm_connector_to_writeback(connector);
+               dm_wbcon = to_amdgpu_dm_wb_connector(wbcon);
+               link = dm_wbcon->link;
+       }
  
-       if (!aconnector->dc_sink) {
-               sink = create_fake_sink(aconnector);
+       if (!aconnector || !aconnector->dc_sink) {
+               sink = create_fake_sink(link);
                if (!sink)
                        return stream;
        } else {
                sink = aconnector->dc_sink;
                dc_sink_retain(sink);
                goto finish;
        }
  
+       /* We leave this NULL for writeback connectors */
        stream->dm_stream_context = aconnector;
  
        stream->timing.flags.LTE_340MCSC_SCRAMBLE =
-               drm_connector->display_info.hdmi.scdc.scrambling.low_rates;
+               connector->display_info.hdmi.scdc.scrambling.low_rates;
  
-       list_for_each_entry(preferred_mode, &aconnector->base.modes, head) {
+       list_for_each_entry(preferred_mode, &connector->modes, head) {
                /* Search for preferred mode */
                if (preferred_mode->type & DRM_MODE_TYPE_PREFERRED) {
                        native_mode_found = true;
        }
        if (!native_mode_found)
                preferred_mode = list_first_entry_or_null(
-                               &aconnector->base.modes,
+                               &connector->modes,
                                struct drm_display_mode,
                                head);
  
                 * and the modelist may not be filled in time.
                 */
                DRM_DEBUG_DRIVER("No preferred mode found\n");
-       } else {
+       } else if (aconnector) {
                recalculate_timing = is_freesync_video_mode(&mode, aconnector);
                if (recalculate_timing) {
                        freesync_mode = get_highest_refresh_rate_mode(aconnector, false);
         */
        if (!scale || mode_refresh != preferred_refresh)
                fill_stream_properties_from_drm_display_mode(
-                       stream, &mode, &aconnector->base, con_state, NULL,
+                       stream, &mode, connector, con_state, NULL,
                        requested_bpc);
        else
                fill_stream_properties_from_drm_display_mode(
-                       stream, &mode, &aconnector->base, con_state, old_stream,
+                       stream, &mode, connector, con_state, old_stream,
                        requested_bpc);
  
+       /* The rest isn't needed for writeback connectors */
+       if (!aconnector)
+               goto finish;
        if (aconnector->timing_changed) {
                drm_dbg(aconnector->base.dev,
                        "overriding timing for automated test, bpc %d, changing to %d\n",
  
        fill_audio_info(
                &stream->audio_info,
-               drm_connector,
+               connector,
                sink);
  
        update_stream_signal(stream, sink);
@@@ -6610,7 -6712,7 +6711,7 @@@ create_validate_stream_for_sink(struct 
        enum dc_status dc_result = DC_OK;
  
        do {
-               stream = create_stream_for_sink(aconnector, drm_mode,
+               stream = create_stream_for_sink(connector, drm_mode,
                                                dm_state, old_stream,
                                                requested_bpc);
                if (stream == NULL) {
                        break;
                }
  
+               if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+                       return stream;
                dc_result = dc_validate_stream(adev->dm.dc, stream);
                if (dc_result == DC_OK && stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
                        dc_result = dm_dp_mst_is_port_support_mode(aconnector, stream);
@@@ -6938,6 -7043,9 +7042,9 @@@ static int dm_update_mst_vcpi_slots_for
  
        for_each_new_connector_in_state(state, connector, new_con_state, i) {
  
+               if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+                       continue;
                aconnector = to_amdgpu_dm_connector(connector);
  
                if (!aconnector->mst_output_port)
@@@ -7543,6 -7651,7 +7650,7 @@@ static int amdgpu_dm_connector_init(str
        struct dc_link *link = dc_get_link_at_index(dc, link_index);
        struct amdgpu_i2c_adapter *i2c;
  
+       /* Not needed for writeback connector */
        link->priv = aconnector;
  
  
@@@ -8497,6 -8606,9 +8605,9 @@@ static void amdgpu_dm_commit_audio(stru
                if (!drm_atomic_crtc_needs_modeset(new_crtc_state))
                        continue;
  
+               if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+                       continue;
  notify:
                aconnector = to_amdgpu_dm_connector(connector);
  
                if (!status)
                        continue;
  
+               if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+                       continue;
                aconnector = to_amdgpu_dm_connector(connector);
  
                mutex_lock(&adev->dm.audio_lock);
@@@ -8555,6 -8670,12 +8669,12 @@@ static void amdgpu_dm_crtc_copy_transie
        stream_state->mode_changed = drm_atomic_crtc_needs_modeset(crtc_state);
  }
  
+ static void dm_clear_writeback(struct amdgpu_display_manager *dm,
+                             struct dm_crtc_state *crtc_state)
+ {
+       dc_stream_remove_writeback(dm->dc, crtc_state->stream, 0);
+ }
  static void amdgpu_dm_commit_streams(struct drm_atomic_state *state,
                                        struct dc_state *dc_state)
  {
        struct drm_crtc *crtc;
        struct drm_crtc_state *old_crtc_state, *new_crtc_state;
        struct dm_crtc_state *dm_old_crtc_state, *dm_new_crtc_state;
+       struct drm_connector_state *old_con_state;
+       struct drm_connector *connector;
        bool mode_set_reset_required = false;
        u32 i;
  
+       /* Disable writeback */
+       for_each_old_connector_in_state(state, connector, old_con_state, i) {
+               struct dm_connector_state *dm_old_con_state;
+               struct amdgpu_crtc *acrtc;
+               if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
+                       continue;
+               old_crtc_state = NULL;
+               dm_old_con_state = to_dm_connector_state(old_con_state);
+               if (!dm_old_con_state->base.crtc)
+                       continue;
+               acrtc = to_amdgpu_crtc(dm_old_con_state->base.crtc);
+               if (acrtc)
+                       old_crtc_state = drm_atomic_get_old_crtc_state(state, &acrtc->base);
+               if (!acrtc->wb_enabled)
+                       continue;
+               dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
+               dm_clear_writeback(dm, dm_old_crtc_state);
+               acrtc->wb_enabled = false;
+       }
        for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
                                      new_crtc_state, i) {
                struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
        }
  }
  
+ static void dm_set_writeback(struct amdgpu_display_manager *dm,
+                             struct dm_crtc_state *crtc_state,
+                             struct drm_connector *connector,
+                             struct drm_connector_state *new_con_state)
+ {
+       struct drm_writeback_connector *wb_conn = drm_connector_to_writeback(connector);
+       struct amdgpu_device *adev = dm->adev;
+       struct amdgpu_crtc *acrtc;
+       struct dc_writeback_info *wb_info;
+       struct pipe_ctx *pipe = NULL;
+       struct amdgpu_framebuffer *afb;
+       int i = 0;
+       wb_info = kzalloc(sizeof(*wb_info), GFP_KERNEL);
+       if (!wb_info) {
+               DRM_ERROR("Failed to allocate wb_info\n");
+               return;
+       }
+       acrtc = to_amdgpu_crtc(wb_conn->encoder.crtc);
+       if (!acrtc) {
+               DRM_ERROR("no amdgpu_crtc found\n");
+               return;
+       }
+       afb = to_amdgpu_framebuffer(new_con_state->writeback_job->fb);
+       if (!afb) {
+               DRM_ERROR("No amdgpu_framebuffer found\n");
+               return;
+       }
+       for (i = 0; i < MAX_PIPES; i++) {
+               if (dm->dc->current_state->res_ctx.pipe_ctx[i].stream == crtc_state->stream) {
+                       pipe = &dm->dc->current_state->res_ctx.pipe_ctx[i];
+                       break;
+               }
+       }
+       /* fill in wb_info */
+       wb_info->wb_enabled = true;
+       wb_info->dwb_pipe_inst = 0;
+       wb_info->dwb_params.dwbscl_black_color = 0;
+       wb_info->dwb_params.hdr_mult = 0x1F000;
+       wb_info->dwb_params.csc_params.gamut_adjust_type = CM_GAMUT_ADJUST_TYPE_BYPASS;
+       wb_info->dwb_params.csc_params.gamut_coef_format = CM_GAMUT_REMAP_COEF_FORMAT_S2_13;
+       wb_info->dwb_params.output_depth = DWB_OUTPUT_PIXEL_DEPTH_10BPC;
+       wb_info->dwb_params.cnv_params.cnv_out_bpc = DWB_CNV_OUT_BPC_10BPC;
+       /* width & height from crtc */
+       wb_info->dwb_params.cnv_params.src_width = acrtc->base.mode.crtc_hdisplay;
+       wb_info->dwb_params.cnv_params.src_height = acrtc->base.mode.crtc_vdisplay;
+       wb_info->dwb_params.dest_width = acrtc->base.mode.crtc_hdisplay;
+       wb_info->dwb_params.dest_height = acrtc->base.mode.crtc_vdisplay;
+       wb_info->dwb_params.cnv_params.crop_en = false;
+       wb_info->dwb_params.stereo_params.stereo_enabled = false;
+       wb_info->dwb_params.cnv_params.out_max_pix_val = 0x3ff; // 10 bits
+       wb_info->dwb_params.cnv_params.out_min_pix_val = 0;
+       wb_info->dwb_params.cnv_params.fc_out_format = DWB_OUT_FORMAT_32BPP_ARGB;
+       wb_info->dwb_params.cnv_params.out_denorm_mode = DWB_OUT_DENORM_BYPASS;
+       wb_info->dwb_params.out_format = dwb_scaler_mode_bypass444;
+       wb_info->dwb_params.capture_rate = dwb_capture_rate_0;
+       wb_info->dwb_params.scaler_taps.h_taps = 4;
+       wb_info->dwb_params.scaler_taps.v_taps = 4;
+       wb_info->dwb_params.scaler_taps.h_taps_c = 2;
+       wb_info->dwb_params.scaler_taps.v_taps_c = 2;
+       wb_info->dwb_params.subsample_position = DWB_INTERSTITIAL_SUBSAMPLING;
+       wb_info->mcif_buf_params.luma_pitch = afb->base.pitches[0];
+       wb_info->mcif_buf_params.chroma_pitch = afb->base.pitches[1];
+       for (i = 0; i < DWB_MCIF_BUF_COUNT; i++) {
+               wb_info->mcif_buf_params.luma_address[i] = afb->address;
+               wb_info->mcif_buf_params.chroma_address[i] = 0;
+       }
+       wb_info->mcif_buf_params.p_vmid = 1;
+       if (adev->ip_versions[DCE_HWIP][0] >= IP_VERSION(3, 0, 0)) {
+               wb_info->mcif_warmup_params.start_address.quad_part = afb->address;
+               wb_info->mcif_warmup_params.region_size =
+                       wb_info->mcif_buf_params.luma_pitch * wb_info->dwb_params.dest_height;
+       }
+       wb_info->mcif_warmup_params.p_vmid = 1;
+       wb_info->writeback_source_plane = pipe->plane_state;
+       dc_stream_add_writeback(dm->dc, crtc_state->stream, wb_info);
+       acrtc->wb_pending = true;
+       acrtc->wb_conn = wb_conn;
+       drm_writeback_queue_job(wb_conn, new_con_state);
+ }
  /**
   * amdgpu_dm_atomic_commit_tail() - AMDgpu DM's commit tail implementation.
   * @state: The atomic state to commit
@@@ -8753,7 -9000,12 +8999,12 @@@ static void amdgpu_dm_atomic_commit_tai
        for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) {
                struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state);
                struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc);
-               struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
+               struct amdgpu_dm_connector *aconnector;
+               if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+                       continue;
+               aconnector = to_amdgpu_dm_connector(connector);
  
                if (!adev->dm.hdcp_workqueue)
                        continue;
                        amdgpu_dm_commit_planes(state, dev, dm, crtc, wait_for_vblank);
        }
  
+       /* Enable writeback */
+       for_each_new_connector_in_state(state, connector, new_con_state, i) {
+               struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state);
+               struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc);
+               if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
+                       continue;
+               if (!new_con_state->writeback_job)
+                       continue;
+               new_crtc_state = NULL;
+               if (acrtc)
+                       new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base);
+               if (acrtc->wb_enabled)
+                       continue;
+               dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
+               dm_set_writeback(dm, dm_new_crtc_state, connector, new_con_state);
+               acrtc->wb_enabled = true;
+       }
        /* Update audio instances for each connector. */
        amdgpu_dm_commit_audio(dev, state);
  
  void dm_restore_drm_connector_state(struct drm_device *dev,
                                    struct drm_connector *connector)
  {
-       struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
+       struct amdgpu_dm_connector *aconnector;
        struct amdgpu_crtc *disconnected_acrtc;
        struct dm_crtc_state *acrtc_state;
  
+       if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+               return;
+       aconnector = to_amdgpu_dm_connector(connector);
        if (!aconnector->dc_sink || !connector->state || !connector->encoder)
                return;
  
@@@ -9227,12 -9509,16 +9508,16 @@@ static void get_freesync_config_for_crt
        struct dm_connector_state *new_con_state)
  {
        struct mod_freesync_config config = {0};
-       struct amdgpu_dm_connector *aconnector =
-                       to_amdgpu_dm_connector(new_con_state->base.connector);
+       struct amdgpu_dm_connector *aconnector;
        struct drm_display_mode *mode = &new_crtc_state->base.mode;
        int vrefresh = drm_mode_vrefresh(mode);
        bool fs_vid_mode = false;
  
+       if (new_con_state->base.connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+               return;
+       aconnector = to_amdgpu_dm_connector(new_con_state->base.connector);
        new_crtc_state->vrr_supported = new_con_state->freesync_capable &&
                                        vrefresh >= aconnector->min_vfreq &&
                                        vrefresh <= aconnector->max_vfreq;
@@@ -9332,6 -9618,7 +9617,7 @@@ static int dm_update_crtc_state(struct 
         * update changed items
         */
        struct amdgpu_crtc *acrtc = NULL;
+       struct drm_connector *connector = NULL;
        struct amdgpu_dm_connector *aconnector = NULL;
        struct drm_connector_state *drm_new_conn_state = NULL, *drm_old_conn_state = NULL;
        struct dm_connector_state *dm_new_conn_state = NULL, *dm_old_conn_state = NULL;
        dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
        dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
        acrtc = to_amdgpu_crtc(crtc);
-       aconnector = amdgpu_dm_find_first_crtc_matching_connector(state, crtc);
+       connector = amdgpu_dm_find_first_crtc_matching_connector(state, crtc);
+       if (connector)
+               aconnector = to_amdgpu_dm_connector(connector);
  
        /* TODO This hack should go away */
-       if (aconnector && enable) {
+       if (connector && enable) {
                /* Make sure fake sink is created in plug-in scenario */
                drm_new_conn_state = drm_atomic_get_new_connector_state(state,
-                                                           &aconnector->base);
+                                                                       connector);
                drm_old_conn_state = drm_atomic_get_old_connector_state(state,
-                                                           &aconnector->base);
+                                                                       connector);
  
                if (IS_ERR(drm_new_conn_state)) {
                        ret = PTR_ERR_OR_ZERO(drm_new_conn_state);
                 * added MST connectors not found in existing crtc_state in the chained mode
                 * TODO: need to dig out the root cause of that
                 */
-               if (!aconnector)
+               if (!connector)
                        goto skip_modeset;
  
                if (modereset_required(new_crtc_state))
@@@ -9539,7 -9828,7 +9827,7 @@@ skip_modeset
         * We want to do dc stream updates that do not require a
         * full modeset below.
         */
-       if (!(enable && aconnector && new_crtc_state->active))
+       if (!(enable && connector && new_crtc_state->active))
                return 0;
        /*
         * Given above conditions, the dc state cannot be NULL because:
@@@ -10062,6 -10351,9 +10350,9 @@@ static int add_affected_mst_dsc_crtcs(s
                if (conn_state->crtc != crtc)
                        continue;
  
+               if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+                       continue;
                aconnector = to_amdgpu_dm_connector(connector);
                if (!aconnector->mst_output_port || !aconnector->mst_root)
                        aconnector = NULL;
This page took 0.14221 seconds and 4 git commands to generate.