mirror of https://gitee.com/openkylin/linux.git
drm/amd/display: Add debugfs entry for reading psr state
[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.Li@amd.com> Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com> Acked-by: Leo Li <sunpeng.li@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
37b970d1d7
commit
e0d08a40a6
|
@ -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,
|
DEFINE_DEBUGFS_ATTRIBUTE(force_yuv420_output_fops, force_yuv420_output_get,
|
||||||
force_yuv420_output_set, "%llu\n");
|
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)
|
void connector_debugfs_init(struct amdgpu_dm_connector *connector)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -982,6 +1001,8 @@ void connector_debugfs_init(struct amdgpu_dm_connector *connector)
|
||||||
dp_debugfs_entries[i].fops);
|
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,
|
debugfs_create_file_unsafe("force_yuv420_output", 0644, dir, connector,
|
||||||
&force_yuv420_output_fops);
|
&force_yuv420_output_fops);
|
||||||
|
|
|
@ -2436,6 +2436,155 @@ bool dc_link_set_psr_allow_active(struct dc_link *link, bool allow_active, bool
|
||||||
return true;
|
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)
|
const struct dc_link_status *dc_link_get_status(const struct dc_link *link)
|
||||||
{
|
{
|
||||||
return &link->link_status;
|
return &link->link_status;
|
||||||
|
|
Loading…
Reference in New Issue