From: Roman Li <roman...@amd.com>

[Why]
For upcoming PSR stupport it's useful to have debug entry
to verify psr state.

[How]
 - Enable psr dc api for Linux
 - Add psr_state file to eDP connector debugfs
usage e.g.: cat /sys/kernel/debug/dri/0/DP-1/psr_state

Signed-off-by: Roman Li <roman...@amd.com>
Reviewed-by: Nicholas Kazlauskas <nicholas.kazlaus...@amd.com>
Acked-by: Leo Li <sunpeng...@amd.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c |  21 +++
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 149 ++++++++++++++++++
 2 files changed, 170 insertions(+)

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 e29c6314f98c..bdb37e611015 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
@@ -969,6 +969,25 @@ static int force_yuv420_output_get(void *data, u64 *val)
 DEFINE_DEBUGFS_ATTRIBUTE(force_yuv420_output_fops, force_yuv420_output_get,
                         force_yuv420_output_set, "%llu\n");
 
+/*
+ *  Read PSR state
+ */
+static int psr_get(void *data, u64 *val)
+{
+       struct amdgpu_dm_connector *connector = data;
+       struct dc_link *link = connector->dc_link;
+       uint32_t psr_state = 0;
+
+       dc_link_get_psr_state(link, &psr_state);
+
+       *val = psr_state;
+
+       return 0;
+}
+
+
+DEFINE_DEBUGFS_ATTRIBUTE(psr_fops, psr_get, NULL, "%llu\n");
+
 void connector_debugfs_init(struct amdgpu_dm_connector *connector)
 {
        int i;
@@ -982,6 +1001,8 @@ void connector_debugfs_init(struct amdgpu_dm_connector 
*connector)
                                            dp_debugfs_entries[i].fops);
                }
        }
+       if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)
+               debugfs_create_file_unsafe("psr_state", 0444, dir, connector, 
&psr_fops);
 
        debugfs_create_file_unsafe("force_yuv420_output", 0644, dir, connector,
                                   &force_yuv420_output_fops);
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 935053664160..10a04565535c 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -2436,6 +2436,155 @@ bool dc_link_set_psr_allow_active(struct dc_link *link, 
bool allow_active, bool
        return true;
 }
 
+bool dc_link_get_psr_state(const struct dc_link *link, uint32_t *psr_state)
+{
+       struct dc  *core_dc = link->ctx->dc;
+       struct dmcu *dmcu = core_dc->res_pool->dmcu;
+
+       if (dmcu != NULL && link->psr_feature_enabled)
+               dmcu->funcs->get_psr_state(dmcu, psr_state);
+
+       return true;
+}
+
+bool dc_link_setup_psr(struct dc_link *link,
+               const struct dc_stream_state *stream, struct psr_config 
*psr_config,
+               struct psr_context *psr_context)
+{
+       struct dc *core_dc;
+       struct dmcu *dmcu;
+       int i;
+       /* updateSinkPsrDpcdConfig*/
+       union dpcd_psr_configuration psr_configuration;
+
+       psr_context->controllerId = CONTROLLER_ID_UNDEFINED;
+
+       if (!link)
+               return false;
+
+       core_dc = link->ctx->dc;
+       dmcu = core_dc->res_pool->dmcu;
+
+       if (!dmcu)
+               return false;
+
+
+       memset(&psr_configuration, 0, sizeof(psr_configuration));
+
+       psr_configuration.bits.ENABLE                    = 1;
+       psr_configuration.bits.CRC_VERIFICATION          = 1;
+       psr_configuration.bits.FRAME_CAPTURE_INDICATION  =
+                       psr_config->psr_frame_capture_indication_req;
+
+       /* Check for PSR v2*/
+       if (psr_config->psr_version == 0x2) {
+               /* For PSR v2 selective update.
+                * Indicates whether sink should start capturing
+                * immediately following active scan line,
+                * or starting with the 2nd active scan line.
+                */
+               psr_configuration.bits.LINE_CAPTURE_INDICATION = 0;
+               /*For PSR v2, determines whether Sink should generate
+                * IRQ_HPD when CRC mismatch is detected.
+                */
+               psr_configuration.bits.IRQ_HPD_WITH_CRC_ERROR    = 1;
+       }
+
+       dm_helpers_dp_write_dpcd(
+               link->ctx,
+               link,
+               368,
+               &psr_configuration.raw,
+               sizeof(psr_configuration.raw));
+
+       psr_context->channel = link->ddc->ddc_pin->hw_info.ddc_channel;
+       psr_context->transmitterId = link->link_enc->transmitter;
+       psr_context->engineId = link->link_enc->preferred_engine;
+
+       for (i = 0; i < MAX_PIPES; i++) {
+               if (core_dc->current_state->res_ctx.pipe_ctx[i].stream
+                               == stream) {
+                       /* dmcu -1 for all controller id values,
+                        * therefore +1 here
+                        */
+                       psr_context->controllerId =
+                               core_dc->current_state->res_ctx.
+                               pipe_ctx[i].stream_res.tg->inst + 1;
+                       break;
+               }
+       }
+
+       /* Hardcoded for now.  Can be Pcie or Uniphy (or Unknown)*/
+       psr_context->phyType = PHY_TYPE_UNIPHY;
+       /*PhyId is associated with the transmitter id*/
+       psr_context->smuPhyId = link->link_enc->transmitter;
+
+       psr_context->crtcTimingVerticalTotal = stream->timing.v_total;
+       psr_context->vsyncRateHz = div64_u64(div64_u64((stream->
+                                       timing.pix_clk_100hz * 100),
+                                       stream->timing.v_total),
+                                       stream->timing.h_total);
+
+       psr_context->psrSupportedDisplayConfig = true;
+       psr_context->psrExitLinkTrainingRequired =
+               psr_config->psr_exit_link_training_required;
+       psr_context->sdpTransmitLineNumDeadline =
+               psr_config->psr_sdp_transmit_line_num_deadline;
+       psr_context->psrFrameCaptureIndicationReq =
+               psr_config->psr_frame_capture_indication_req;
+
+       psr_context->skipPsrWaitForPllLock = 0; /* only = 1 in KV */
+
+       psr_context->numberOfControllers =
+                       link->dc->res_pool->timing_generator_count;
+
+       psr_context->rfb_update_auto_en = true;
+
+       /* 2 frames before enter PSR. */
+       psr_context->timehyst_frames = 2;
+       /* half a frame
+        * (units in 100 lines, i.e. a value of 1 represents 100 lines)
+        */
+       psr_context->hyst_lines = stream->timing.v_total / 2 / 100;
+       psr_context->aux_repeats = 10;
+
+       psr_context->psr_level.u32all = 0;
+
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
+       /*skip power down the single pipe since it blocks the cstate*/
+       if (ASICREV_IS_RAVEN(link->ctx->asic_id.hw_internal_rev))
+               psr_context->psr_level.bits.SKIP_CRTC_DISABLE = true;
+#endif
+
+       /* SMU will perform additional powerdown sequence.
+        * For unsupported ASICs, set psr_level flag to skip PSR
+        *  static screen notification to SMU.
+        *  (Always set for DAL2, did not check ASIC)
+        */
+       psr_context->allow_smu_optimizations = 
psr_config->allow_smu_optimizations;
+
+       /* Complete PSR entry before aborting to prevent intermittent
+        * freezes on certain eDPs
+        */
+       psr_context->psr_level.bits.DISABLE_PSR_ENTRY_ABORT = 1;
+
+       /* Controls additional delay after remote frame capture before
+        * continuing power down, default = 0
+        */
+       psr_context->frame_delay = 0;
+
+       link->psr_feature_enabled = dmcu->funcs->setup_psr(dmcu, link, 
psr_context);
+
+       /* psr_enabled == 0 indicates setup_psr did not succeed, but this
+        * should not happen since firmware should be running at this point
+        */
+       if (link->psr_feature_enabled == 0)
+               ASSERT(0);
+
+       return true;
+
+}
+
 const struct dc_link_status *dc_link_get_status(const struct dc_link *link)
 {
        return &link->link_status;
-- 
2.23.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to