Commit 9f72f51d authored by Amy Zhang's avatar Amy Zhang Committed by Alex Deucher
Browse files

drm/amd/display: Refactor to call set PSR wait loop in dce_dmcu instead of dce_clocks

parent 1a2c82a2
Loading
Loading
Loading
Loading
+26 −26
Original line number Diff line number Diff line
@@ -1458,17 +1458,17 @@ bool dc_link_get_psr_state(const struct dc_link *dc_link, uint32_t *psr_state)
}

bool dc_link_setup_psr(const struct dc_link *dc_link,
		const struct dc_stream *stream, struct psr_config *psr_config)
		const struct dc_stream *stream, struct psr_config *psr_config,
		struct psr_context *psr_context)
{
	struct core_link *link = DC_LINK_TO_CORE(dc_link);
	struct dc_context *ctx = link->ctx;
	struct core_dc *core_dc = DC_TO_CORE(ctx->dc);
	struct dmcu *dmcu = core_dc->res_pool->dmcu;
	struct core_stream *core_stream = DC_STREAM_TO_CORE(stream);
	struct psr_context psr_context = {0};
	int i;

	psr_context.controllerId = CONTROLLER_ID_UNDEFINED;
	psr_context->controllerId = CONTROLLER_ID_UNDEFINED;

	if (dc_link != NULL &&
		dmcu != NULL) {
@@ -1503,9 +1503,9 @@ bool dc_link_setup_psr(const struct dc_link *dc_link,
			&psr_configuration.raw,
			sizeof(psr_configuration.raw));

		psr_context.channel = link->public.ddc->ddc_pin->hw_info.ddc_channel;
		psr_context.transmitterId = link->link_enc->transmitter;
		psr_context.engineId = link->link_enc->preferred_engine;
		psr_context->channel = link->public.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_context->res_ctx.pipe_ctx[i].stream
@@ -1513,7 +1513,7 @@ bool dc_link_setup_psr(const struct dc_link *dc_link,
				/* dmcu -1 for all controller id values,
				 * therefore +1 here
				 */
				psr_context.controllerId =
				psr_context->controllerId =
					core_dc->current_context->res_ctx.
					pipe_ctx[i].tg->inst + 1;
				break;
@@ -1521,60 +1521,60 @@ bool dc_link_setup_psr(const struct dc_link *dc_link,
		}

		/* Hardcoded for now.  Can be Pcie or Uniphy (or Unknown)*/
		psr_context.phyType = PHY_TYPE_UNIPHY;
		psr_context->phyType = PHY_TYPE_UNIPHY;
		/*PhyId is associated with the transmitter id*/
		psr_context.smuPhyId = link->link_enc->transmitter;
		psr_context->smuPhyId = link->link_enc->transmitter;

		psr_context.crtcTimingVerticalTotal = stream->timing.v_total;
		psr_context.vsyncRateHz = div64_u64(div64_u64((stream->
		psr_context->crtcTimingVerticalTotal = stream->timing.v_total;
		psr_context->vsyncRateHz = div64_u64(div64_u64((stream->
						timing.pix_clk_khz * 1000),
						stream->timing.v_total),
						stream->timing.h_total);

		psr_context.psrSupportedDisplayConfig = true;
		psr_context.psrExitLinkTrainingRequired =
		psr_context->psrSupportedDisplayConfig = true;
		psr_context->psrExitLinkTrainingRequired =
			psr_config->psr_exit_link_training_required;
		psr_context.sdpTransmitLineNumDeadline =
		psr_context->sdpTransmitLineNumDeadline =
			psr_config->psr_sdp_transmit_line_num_deadline;
		psr_context.psrFrameCaptureIndicationReq =
		psr_context->psrFrameCaptureIndicationReq =
			psr_config->psr_frame_capture_indication_req;

		psr_context.skipPsrWaitForPllLock = 0; /* only = 1 in KV */
		psr_context->skipPsrWaitForPllLock = 0; /* only = 1 in KV */

		psr_context.numberOfControllers =
		psr_context->numberOfControllers =
				link->dc->res_pool->res_cap->num_timing_generator;

		psr_context.rfb_update_auto_en = true;
		psr_context->rfb_update_auto_en = true;

		/* 2 frames before enter PSR. */
		psr_context.timehyst_frames = 2;
		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->hyst_lines = stream->timing.v_total / 2 / 100;
		psr_context->aux_repeats = 10;

		psr_context.psr_level.u32all = 0;
		psr_context->psr_level.u32all = 0;

		/* 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.psr_level.bits.SKIP_SMU_NOTIFICATION = 1;
		psr_context->psr_level.bits.SKIP_SMU_NOTIFICATION = 1;

		/* Complete PSR entry before aborting to prevent intermittent
		 * freezes on certain eDPs
		 */
		psr_context.psr_level.bits.DISABLE_PSR_ENTRY_ABORT = 1;
		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;
		psr_context->frame_delay = 0;

		link->psr_enabled = true;
		dmcu->funcs->setup_psr(dmcu, link, &psr_context);
		dmcu->funcs->setup_psr(dmcu, link, psr_context);
		return true;
	} else
		return false;
+2 −1
Original line number Diff line number Diff line
@@ -705,7 +705,8 @@ bool dc_link_set_psr_enable(const struct dc_link *dc_link, bool enable);
bool dc_link_get_psr_state(const struct dc_link *dc_link, uint32_t *psr_state);

bool dc_link_setup_psr(const struct dc_link *dc_link,
		const struct dc_stream *stream, struct psr_config *psr_config);
		const struct dc_stream *stream, struct psr_config *psr_config,
		struct psr_context *psr_context);

/* Request DC to detect if there is a Panel connected.
 * boot - If this call is during initial boot.
+101 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include "dc_dp_types.h"
#include "dc_hw_types.h"
#include "dal_types.h"
#include "grph_object_defs.h"

/* forward declarations */
struct dc_surface;
@@ -493,6 +494,106 @@ struct psr_config {
	unsigned int psr_sdp_transmit_line_num_deadline;
};

union dmcu_psr_level {
	struct {
		unsigned int SKIP_CRC:1;
		unsigned int SKIP_DP_VID_STREAM_DISABLE:1;
		unsigned int SKIP_PHY_POWER_DOWN:1;
		unsigned int SKIP_AUX_ACK_CHECK:1;
		unsigned int SKIP_CRTC_DISABLE:1;
		unsigned int SKIP_AUX_RFB_CAPTURE_CHECK:1;
		unsigned int SKIP_SMU_NOTIFICATION:1;
		unsigned int SKIP_AUTO_STATE_ADVANCE:1;
		unsigned int DISABLE_PSR_ENTRY_ABORT:1;
		unsigned int RESERVED:23;
	} bits;
	unsigned int u32all;
};

enum physical_phy_id {
	PHYLD_0,
	PHYLD_1,
	PHYLD_2,
	PHYLD_3,
	PHYLD_4,
	PHYLD_5,
	PHYLD_6,
	PHYLD_7,
	PHYLD_8,
	PHYLD_9,
	PHYLD_COUNT,
	PHYLD_UNKNOWN = (-1L)
};

enum phy_type {
	PHY_TYPE_UNKNOWN  = 1,
	PHY_TYPE_PCIE_PHY = 2,
	PHY_TYPE_UNIPHY = 3,
};

struct psr_context {
	/* ddc line */
	enum channel_id channel;
	/* Transmitter id */
	enum transmitter transmitterId;
	/* Engine Id is used for Dig Be source select */
	enum engine_id engineId;
	/* Controller Id used for Dig Fe source select */
	enum controller_id controllerId;
	/* Pcie or Uniphy */
	enum phy_type phyType;
	/* Physical PHY Id used by SMU interpretation */
	enum physical_phy_id smuPhyId;
	/* Vertical total pixels from crtc timing.
	 * This is used for static screen detection.
	 * ie. If we want to detect half a frame,
	 * we use this to determine the hyst lines.
	 */
	unsigned int crtcTimingVerticalTotal;
	/* PSR supported from panel capabilities and
	 * current display configuration
	 */
	bool psrSupportedDisplayConfig;
	/* Whether fast link training is supported by the panel */
	bool psrExitLinkTrainingRequired;
	/* If RFB setup time is greater than the total VBLANK time,
	 * it is not possible for the sink to capture the video frame
	 * in the same frame the SDP is sent. In this case,
	 * the frame capture indication bit should be set and an extra
	 * static frame should be transmitted to the sink.
	 */
	bool psrFrameCaptureIndicationReq;
	/* Set the last possible line SDP may be transmitted without violating
	 * the RFB setup time or entering the active video frame.
	 */
	unsigned int sdpTransmitLineNumDeadline;
	/* The VSync rate in Hz used to calculate the
	 * step size for smooth brightness feature
	 */
	unsigned int vsyncRateHz;
	unsigned int skipPsrWaitForPllLock;
	unsigned int numberOfControllers;
	/* Unused, for future use. To indicate that first changed frame from
	 * state3 shouldn't result in psr_inactive, but rather to perform
	 * an automatic single frame rfb_update.
	 */
	bool rfb_update_auto_en;
	/* Number of frame before entering static screen */
	unsigned int timehyst_frames;
	/* Partial frames before entering static screen */
	unsigned int hyst_lines;
	/* # of repeated AUX transaction attempts to make before
	 * indicating failure to the driver
	 */
	unsigned int aux_repeats;
	/* Controls hw blocks to power down during PSR active state */
	union dmcu_psr_level psr_level;
	/* Controls additional delay after remote frame capture before
	 * continuing powerd own
	 */
	unsigned int frame_delay;
};

struct colorspace_transform {
	struct fixed31_32 matrix[12];
	bool enable_remap;
+9 −32
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include "dc.h"
#include "core_dc.h"
#include "dce_abm.h"
#include "dmcu.h"
#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
#include "dcn_calcs.h"
#include "core_dc.h"
@@ -331,44 +332,18 @@ static void dce_set_clock(
		clk->cur_min_clks_state = DM_PP_CLOCKS_STATE_NOMINAL;
}

#define PSR_SET_WAITLOOP 0x31

union dce110_dmcu_psr_config_data_wait_loop_reg1 {
	struct {
		unsigned int wait_loop:16; /* [15:0] */
		unsigned int reserved:16; /* [31:16] */
	} bits;
	unsigned int u32;
};

static void dce_psr_wait_loop(
		struct dce_disp_clk *clk_dce, unsigned int display_clk_khz)
{
	struct dc_context *ctx = clk_dce->base.ctx;
	union dce110_dmcu_psr_config_data_wait_loop_reg1 masterCmdData1;

	/* waitDMCUReadyForCmd */
	REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 100);

	masterCmdData1.u32 = 0;
	masterCmdData1.bits.wait_loop = display_clk_khz / 1000 / 7;
	dm_write_reg(ctx, REG(MASTER_COMM_DATA_REG1), masterCmdData1.u32);

	/* setDMCUParam_Cmd */
	REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, PSR_SET_WAITLOOP);

	/* notifyDMCUMsg */
	REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
}

static void dce_psr_set_clock(
	struct display_clock *clk,
	int requested_clk_khz)
{
	struct dce_disp_clk *clk_dce = TO_DCE_CLOCKS(clk);
	struct dc_context *ctx = clk_dce->base.ctx;
	struct core_dc *core_dc = DC_TO_CORE(ctx->dc);
	struct dmcu *dmcu = core_dc->res_pool->dmcu;

	dce_set_clock(clk, requested_clk_khz);
	dce_psr_wait_loop(clk_dce, requested_clk_khz);

	dmcu->funcs->set_psr_wait_loop(dmcu, requested_clk_khz / 1000 / 7);
}

static void dce112_set_clock(
@@ -380,6 +355,7 @@ static void dce112_set_clock(
	struct dc_bios *bp = clk->ctx->dc_bios;
	struct core_dc *core_dc = DC_TO_CORE(clk->ctx->dc);
	struct abm *abm =  core_dc->res_pool->abm;
	struct dmcu *dmcu = core_dc->res_pool->dmcu;

	/* Prepare to program display clock*/
	memset(&dce_clk_params, 0, sizeof(dce_clk_params));
@@ -411,7 +387,8 @@ static void dce112_set_clock(
	bp->funcs->set_dce_clock(bp, &dce_clk_params);

	if (abm->funcs->is_dmcu_initialized(abm))
		dce_psr_wait_loop(clk_dce, requested_clk_khz);
		dmcu->funcs->set_psr_wait_loop(dmcu,
				requested_clk_khz / 1000 / 7);

}

+64 −2
Original line number Diff line number Diff line
@@ -48,7 +48,9 @@
#define PSR_ENABLE 0x20
#define PSR_EXIT 0x21
#define PSR_SET 0x23
#define PSR_SET_WAITLOOP 0x31
#define MASTER_COMM_CNTL_REG__MASTER_COMM_INTERRUPT_MASK   0x00000001L
unsigned int cached_wait_loop_number = 0;

bool dce_dmcu_load_iram(struct dmcu *dmcu,
		unsigned int start_offset,
@@ -252,6 +254,34 @@ static void dce_dmcu_setup_psr(struct dmcu *dmcu,
	REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
}

static void dce_psr_wait_loop(
	struct dmcu *dmcu,
	unsigned int wait_loop_number)
{
	struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);
	union dce_dmcu_psr_config_data_wait_loop_reg1 masterCmdData1;

	/* waitDMCUReadyForCmd */
	REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 100);

	masterCmdData1.u32 = 0;
	masterCmdData1.bits.wait_loop = wait_loop_number;
	cached_wait_loop_number = wait_loop_number;
	dm_write_reg(dmcu->ctx, REG(MASTER_COMM_DATA_REG1), masterCmdData1.u32);

	/* setDMCUParam_Cmd */
	REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, PSR_SET_WAITLOOP);

	/* notifyDMCUMsg */
	REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
}

static void dce_get_psr_wait_loop(unsigned int *psr_wait_loop_number)
{
	*psr_wait_loop_number = cached_wait_loop_number;
	return;
}

#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
bool dcn10_dmcu_load_iram(struct dmcu *dmcu,
		unsigned int start_offset,
@@ -464,13 +494,43 @@ static void dcn10_dmcu_setup_psr(struct dmcu *dmcu,
	REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
}

static void dcn10_psr_wait_loop(
	struct dmcu *dmcu,
	unsigned int wait_loop_number)
{
	struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);
	union dce_dmcu_psr_config_data_wait_loop_reg1 masterCmdData1;

	/* waitDMCUReadyForCmd */
	REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 100);

	masterCmdData1.u32 = 0;
	masterCmdData1.bits.wait_loop = wait_loop_number;
	cached_wait_loop_number = wait_loop_number;
	dm_write_reg(dmcu->ctx, REG(MASTER_COMM_DATA_REG1), masterCmdData1.u32);

	/* setDMCUParam_Cmd */
	REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, PSR_SET_WAITLOOP);

	/* notifyDMCUMsg */
	REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
}

static void dcn10_get_psr_wait_loop(unsigned int *psr_wait_loop_number)
{
	*psr_wait_loop_number = cached_wait_loop_number;
	return;
}

#endif

static const struct dmcu_funcs dce_funcs = {
	.load_iram = dce_dmcu_load_iram,
	.set_psr_enable = dce_dmcu_set_psr_enable,
	.setup_psr = dce_dmcu_setup_psr,
	.get_psr_state = dce_get_dmcu_psr_state
	.get_psr_state = dce_get_dmcu_psr_state,
	.set_psr_wait_loop = dce_psr_wait_loop,
	.get_psr_wait_loop = dce_get_psr_wait_loop
};

#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
@@ -478,7 +538,9 @@ static const struct dmcu_funcs dcn10_funcs = {
	.load_iram = dcn10_dmcu_load_iram,
	.set_psr_enable = dcn10_dmcu_set_psr_enable,
	.setup_psr = dcn10_dmcu_setup_psr,
	.get_psr_state = dcn10_get_dmcu_psr_state
	.get_psr_state = dcn10_get_dmcu_psr_state,
	.set_psr_wait_loop = dcn10_psr_wait_loop,
	.get_psr_wait_loop = dcn10_get_psr_wait_loop
};
#endif

Loading