mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-27 19:29:37 +00:00
drm/amd/display: Engage PSR synchronously
[Why & How] The intended use is to force PSR into active state and ignore all events until explicit EXIT. A new event force_static is added to power module. It is then sent to FW. Signed-off-by: Krunoslav Kovac <Krunoslav.Kovac@amd.com> Acked-by: Bindu Ramamurthy <bindu.r@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
fa896813b4
commit
1d496907f1
12 changed files with 129 additions and 76 deletions
|
@ -9611,7 +9611,7 @@ bool amdgpu_dm_psr_enable(struct dc_stream_state *stream)
|
||||||
&stream, 1,
|
&stream, 1,
|
||||||
¶ms);
|
¶ms);
|
||||||
|
|
||||||
return dc_link_set_psr_allow_active(link, true, false);
|
return dc_link_set_psr_allow_active(link, true, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -9625,7 +9625,7 @@ static bool amdgpu_dm_psr_disable(struct dc_stream_state *stream)
|
||||||
|
|
||||||
DRM_DEBUG_DRIVER("Disabling psr...\n");
|
DRM_DEBUG_DRIVER("Disabling psr...\n");
|
||||||
|
|
||||||
return dc_link_set_psr_allow_active(stream->link, false, true);
|
return dc_link_set_psr_allow_active(stream->link, false, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -2333,11 +2333,11 @@ static int psr_get(void *data, u64 *val)
|
||||||
{
|
{
|
||||||
struct amdgpu_dm_connector *connector = data;
|
struct amdgpu_dm_connector *connector = data;
|
||||||
struct dc_link *link = connector->dc_link;
|
struct dc_link *link = connector->dc_link;
|
||||||
uint32_t psr_state = 0;
|
enum dc_psr_state state = PSR_STATE0;
|
||||||
|
|
||||||
dc_link_get_psr_state(link, &psr_state);
|
dc_link_get_psr_state(link, &state);
|
||||||
|
|
||||||
*val = psr_state;
|
*val = state;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,7 +94,7 @@ void clk_mgr_exit_optimized_pwr_state(const struct dc *dc, struct clk_mgr *clk_m
|
||||||
|
|
||||||
if (edp_link) {
|
if (edp_link) {
|
||||||
clk_mgr->psr_allow_active_cache = edp_link->psr_settings.psr_allow_active;
|
clk_mgr->psr_allow_active_cache = edp_link->psr_settings.psr_allow_active;
|
||||||
dc_link_set_psr_allow_active(edp_link, false, false);
|
dc_link_set_psr_allow_active(edp_link, false, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,8 @@ void clk_mgr_optimize_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr)
|
||||||
struct dc_link *edp_link = get_edp_link(dc);
|
struct dc_link *edp_link = get_edp_link(dc);
|
||||||
|
|
||||||
if (edp_link)
|
if (edp_link)
|
||||||
dc_link_set_psr_allow_active(edp_link, clk_mgr->psr_allow_active_cache, false);
|
dc_link_set_psr_allow_active(edp_link,
|
||||||
|
clk_mgr->psr_allow_active_cache, false, false);
|
||||||
|
|
||||||
if (dc->hwss.optimize_pwr_state)
|
if (dc->hwss.optimize_pwr_state)
|
||||||
dc->hwss.optimize_pwr_state(dc, dc->current_state);
|
dc->hwss.optimize_pwr_state(dc, dc->current_state);
|
||||||
|
|
|
@ -3058,9 +3058,9 @@ bool dc_set_psr_allow_active(struct dc *dc, bool enable)
|
||||||
|
|
||||||
if (link->psr_settings.psr_feature_enabled) {
|
if (link->psr_settings.psr_feature_enabled) {
|
||||||
if (enable && !link->psr_settings.psr_allow_active)
|
if (enable && !link->psr_settings.psr_allow_active)
|
||||||
return dc_link_set_psr_allow_active(link, true, false);
|
return dc_link_set_psr_allow_active(link, true, false, false);
|
||||||
else if (!enable && link->psr_settings.psr_allow_active)
|
else if (!enable && link->psr_settings.psr_allow_active)
|
||||||
return dc_link_set_psr_allow_active(link, false, true);
|
return dc_link_set_psr_allow_active(link, false, true, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2565,17 +2565,23 @@ bool dc_link_set_backlight_level(const struct dc_link *link,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dc_link_set_psr_allow_active(struct dc_link *link, bool allow_active, bool wait)
|
bool dc_link_set_psr_allow_active(struct dc_link *link, bool allow_active,
|
||||||
|
bool wait, bool force_static)
|
||||||
{
|
{
|
||||||
struct dc *dc = link->ctx->dc;
|
struct dc *dc = link->ctx->dc;
|
||||||
struct dmcu *dmcu = dc->res_pool->dmcu;
|
struct dmcu *dmcu = dc->res_pool->dmcu;
|
||||||
struct dmub_psr *psr = dc->res_pool->psr;
|
struct dmub_psr *psr = dc->res_pool->psr;
|
||||||
|
|
||||||
|
if (psr == NULL && force_static)
|
||||||
|
return false;
|
||||||
|
|
||||||
link->psr_settings.psr_allow_active = allow_active;
|
link->psr_settings.psr_allow_active = allow_active;
|
||||||
|
|
||||||
if (psr != NULL && link->psr_settings.psr_feature_enabled)
|
if (psr != NULL && link->psr_settings.psr_feature_enabled) {
|
||||||
|
if (force_static && psr->funcs->psr_force_static)
|
||||||
|
psr->funcs->psr_force_static(psr);
|
||||||
psr->funcs->psr_enable(psr, allow_active, wait);
|
psr->funcs->psr_enable(psr, allow_active, wait);
|
||||||
else if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) && link->psr_settings.psr_feature_enabled)
|
} else if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) && link->psr_settings.psr_feature_enabled)
|
||||||
dmcu->funcs->set_psr_enable(dmcu, allow_active, wait);
|
dmcu->funcs->set_psr_enable(dmcu, allow_active, wait);
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
@ -2583,16 +2589,16 @@ 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)
|
bool dc_link_get_psr_state(const struct dc_link *link, enum dc_psr_state *state)
|
||||||
{
|
{
|
||||||
struct dc *dc = link->ctx->dc;
|
struct dc *dc = link->ctx->dc;
|
||||||
struct dmcu *dmcu = dc->res_pool->dmcu;
|
struct dmcu *dmcu = dc->res_pool->dmcu;
|
||||||
struct dmub_psr *psr = dc->res_pool->psr;
|
struct dmub_psr *psr = dc->res_pool->psr;
|
||||||
|
|
||||||
if (psr != NULL && link->psr_settings.psr_feature_enabled)
|
if (psr != NULL && link->psr_settings.psr_feature_enabled)
|
||||||
psr->funcs->psr_get_state(psr, psr_state);
|
psr->funcs->psr_get_state(psr, state);
|
||||||
else if (dmcu != NULL && link->psr_settings.psr_feature_enabled)
|
else if (dmcu != NULL && link->psr_settings.psr_feature_enabled)
|
||||||
dmcu->funcs->get_psr_state(dmcu, psr_state);
|
dmcu->funcs->get_psr_state(dmcu, state);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2575,8 +2575,8 @@ static bool handle_hpd_irq_psr_sink(struct dc_link *link)
|
||||||
sizeof(psr_error_status.raw));
|
sizeof(psr_error_status.raw));
|
||||||
|
|
||||||
/* PSR error, disable and re-enable PSR */
|
/* PSR error, disable and re-enable PSR */
|
||||||
dc_link_set_psr_allow_active(link, false, true);
|
dc_link_set_psr_allow_active(link, false, true, false);
|
||||||
dc_link_set_psr_allow_active(link, true, true);
|
dc_link_set_psr_allow_active(link, true, true, false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else if (psr_sink_psr_status.bits.SINK_SELF_REFRESH_STATUS ==
|
} else if (psr_sink_psr_status.bits.SINK_SELF_REFRESH_STATUS ==
|
||||||
|
|
|
@ -219,9 +219,10 @@ int dc_link_get_backlight_level(const struct dc_link *dc_link);
|
||||||
|
|
||||||
int dc_link_get_target_backlight_pwm(const struct dc_link *link);
|
int dc_link_get_target_backlight_pwm(const struct dc_link *link);
|
||||||
|
|
||||||
bool dc_link_set_psr_allow_active(struct dc_link *dc_link, bool enable, bool wait);
|
bool dc_link_set_psr_allow_active(struct dc_link *dc_link, bool enable,
|
||||||
|
bool wait, bool force_static);
|
||||||
|
|
||||||
bool dc_link_get_psr_state(const struct dc_link *dc_link, uint32_t *psr_state);
|
bool dc_link_get_psr_state(const struct dc_link *dc_link, enum dc_psr_state *state);
|
||||||
|
|
||||||
bool dc_link_setup_psr(struct dc_link *dc_link,
|
bool dc_link_setup_psr(struct dc_link *dc_link,
|
||||||
const struct dc_stream_state *stream, struct psr_config *psr_config,
|
const struct dc_stream_state *stream, struct psr_config *psr_config,
|
||||||
|
|
|
@ -671,6 +671,25 @@ struct dc_plane_flip_time {
|
||||||
unsigned int prev_update_time_in_us;
|
unsigned int prev_update_time_in_us;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum dc_psr_state {
|
||||||
|
PSR_STATE0 = 0x0,
|
||||||
|
PSR_STATE1,
|
||||||
|
PSR_STATE1a,
|
||||||
|
PSR_STATE2,
|
||||||
|
PSR_STATE2a,
|
||||||
|
PSR_STATE3,
|
||||||
|
PSR_STATE3Init,
|
||||||
|
PSR_STATE4,
|
||||||
|
PSR_STATE4a,
|
||||||
|
PSR_STATE4b,
|
||||||
|
PSR_STATE4c,
|
||||||
|
PSR_STATE4d,
|
||||||
|
PSR_STATE5,
|
||||||
|
PSR_STATE5a,
|
||||||
|
PSR_STATE5b,
|
||||||
|
PSR_STATE5c
|
||||||
|
};
|
||||||
|
|
||||||
struct psr_config {
|
struct psr_config {
|
||||||
unsigned char psr_version;
|
unsigned char psr_version;
|
||||||
unsigned int psr_rfb_setup_time;
|
unsigned int psr_rfb_setup_time;
|
||||||
|
|
|
@ -99,7 +99,7 @@ bool dce_dmcu_load_iram(struct dmcu *dmcu,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dce_get_dmcu_psr_state(struct dmcu *dmcu, uint32_t *psr_state)
|
static void dce_get_dmcu_psr_state(struct dmcu *dmcu, enum dc_psr_state *state)
|
||||||
{
|
{
|
||||||
struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);
|
struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ static void dce_get_dmcu_psr_state(struct dmcu *dmcu, uint32_t *psr_state)
|
||||||
REG_WRITE(DMCU_IRAM_RD_CTRL, psr_state_offset);
|
REG_WRITE(DMCU_IRAM_RD_CTRL, psr_state_offset);
|
||||||
|
|
||||||
/* Read data from IRAM_RD_DATA in DMCU_IRAM_RD_DATA*/
|
/* Read data from IRAM_RD_DATA in DMCU_IRAM_RD_DATA*/
|
||||||
*psr_state = REG_READ(DMCU_IRAM_RD_DATA);
|
*state = (enum dc_psr_state)REG_READ(DMCU_IRAM_RD_DATA);
|
||||||
|
|
||||||
/* Disable write access to IRAM after finished using IRAM
|
/* Disable write access to IRAM after finished using IRAM
|
||||||
* in order to allow dynamic sleep state
|
* in order to allow dynamic sleep state
|
||||||
|
@ -129,7 +129,7 @@ static void dce_dmcu_set_psr_enable(struct dmcu *dmcu, bool enable, bool wait)
|
||||||
unsigned int dmcu_wait_reg_ready_interval = 100;
|
unsigned int dmcu_wait_reg_ready_interval = 100;
|
||||||
|
|
||||||
unsigned int retryCount;
|
unsigned int retryCount;
|
||||||
uint32_t psr_state = 0;
|
enum dc_psr_state state = PSR_STATE0;
|
||||||
|
|
||||||
/* waitDMCUReadyForCmd */
|
/* waitDMCUReadyForCmd */
|
||||||
REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0,
|
REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0,
|
||||||
|
@ -148,12 +148,12 @@ static void dce_dmcu_set_psr_enable(struct dmcu *dmcu, bool enable, bool wait)
|
||||||
REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
|
REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
|
||||||
if (wait == true) {
|
if (wait == true) {
|
||||||
for (retryCount = 0; retryCount <= 100; retryCount++) {
|
for (retryCount = 0; retryCount <= 100; retryCount++) {
|
||||||
dce_get_dmcu_psr_state(dmcu, &psr_state);
|
dce_get_dmcu_psr_state(dmcu, &state);
|
||||||
if (enable) {
|
if (enable) {
|
||||||
if (psr_state != 0)
|
if (state != PSR_STATE0)
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
if (psr_state == 0)
|
if (state == PSR_STATE0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
udelay(10);
|
udelay(10);
|
||||||
|
@ -513,7 +513,7 @@ static bool dcn10_dmcu_load_iram(struct dmcu *dmcu,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dcn10_get_dmcu_psr_state(struct dmcu *dmcu, uint32_t *psr_state)
|
static void dcn10_get_dmcu_psr_state(struct dmcu *dmcu, enum dc_psr_state *state)
|
||||||
{
|
{
|
||||||
struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);
|
struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);
|
||||||
|
|
||||||
|
@ -532,7 +532,7 @@ static void dcn10_get_dmcu_psr_state(struct dmcu *dmcu, uint32_t *psr_state)
|
||||||
REG_WRITE(DMCU_IRAM_RD_CTRL, psr_state_offset);
|
REG_WRITE(DMCU_IRAM_RD_CTRL, psr_state_offset);
|
||||||
|
|
||||||
/* Read data from IRAM_RD_DATA in DMCU_IRAM_RD_DATA*/
|
/* Read data from IRAM_RD_DATA in DMCU_IRAM_RD_DATA*/
|
||||||
*psr_state = REG_READ(DMCU_IRAM_RD_DATA);
|
*state = (enum dc_psr_state)REG_READ(DMCU_IRAM_RD_DATA);
|
||||||
|
|
||||||
/* Disable write access to IRAM after finished using IRAM
|
/* Disable write access to IRAM after finished using IRAM
|
||||||
* in order to allow dynamic sleep state
|
* in order to allow dynamic sleep state
|
||||||
|
@ -547,7 +547,7 @@ static void dcn10_dmcu_set_psr_enable(struct dmcu *dmcu, bool enable, bool wait)
|
||||||
unsigned int dmcu_wait_reg_ready_interval = 100;
|
unsigned int dmcu_wait_reg_ready_interval = 100;
|
||||||
|
|
||||||
unsigned int retryCount;
|
unsigned int retryCount;
|
||||||
uint32_t psr_state = 0;
|
enum dc_psr_state state = PSR_STATE0;
|
||||||
|
|
||||||
/* If microcontroller is not running, do nothing */
|
/* If microcontroller is not running, do nothing */
|
||||||
if (dmcu->dmcu_state != DMCU_RUNNING)
|
if (dmcu->dmcu_state != DMCU_RUNNING)
|
||||||
|
@ -575,12 +575,12 @@ static void dcn10_dmcu_set_psr_enable(struct dmcu *dmcu, bool enable, bool wait)
|
||||||
*/
|
*/
|
||||||
if (wait == true) {
|
if (wait == true) {
|
||||||
for (retryCount = 0; retryCount <= 1000; retryCount++) {
|
for (retryCount = 0; retryCount <= 1000; retryCount++) {
|
||||||
dcn10_get_dmcu_psr_state(dmcu, &psr_state);
|
dcn10_get_dmcu_psr_state(dmcu, &state);
|
||||||
if (enable) {
|
if (enable) {
|
||||||
if (psr_state != 0)
|
if (state != PSR_STATE0)
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
if (psr_state == 0)
|
if (state == PSR_STATE0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
udelay(500);
|
udelay(500);
|
||||||
|
|
|
@ -34,55 +34,60 @@
|
||||||
/**
|
/**
|
||||||
* Convert dmcub psr state to dmcu psr state.
|
* Convert dmcub psr state to dmcu psr state.
|
||||||
*/
|
*/
|
||||||
static void convert_psr_state(uint32_t *psr_state)
|
static enum dc_psr_state convert_psr_state(uint32_t raw_state)
|
||||||
{
|
{
|
||||||
if (*psr_state == 0)
|
enum dc_psr_state state = PSR_STATE0;
|
||||||
*psr_state = 0;
|
|
||||||
else if (*psr_state == 0x10)
|
if (raw_state == 0)
|
||||||
*psr_state = 1;
|
state = PSR_STATE0;
|
||||||
else if (*psr_state == 0x11)
|
else if (raw_state == 0x10)
|
||||||
*psr_state = 2;
|
state = PSR_STATE1;
|
||||||
else if (*psr_state == 0x20)
|
else if (raw_state == 0x11)
|
||||||
*psr_state = 3;
|
state = PSR_STATE1a;
|
||||||
else if (*psr_state == 0x21)
|
else if (raw_state == 0x20)
|
||||||
*psr_state = 4;
|
state = PSR_STATE2;
|
||||||
else if (*psr_state == 0x30)
|
else if (raw_state == 0x21)
|
||||||
*psr_state = 5;
|
state = PSR_STATE2a;
|
||||||
else if (*psr_state == 0x31)
|
else if (raw_state == 0x30)
|
||||||
*psr_state = 6;
|
state = PSR_STATE3;
|
||||||
else if (*psr_state == 0x40)
|
else if (raw_state == 0x31)
|
||||||
*psr_state = 7;
|
state = PSR_STATE3Init;
|
||||||
else if (*psr_state == 0x41)
|
else if (raw_state == 0x40)
|
||||||
*psr_state = 8;
|
state = PSR_STATE4;
|
||||||
else if (*psr_state == 0x42)
|
else if (raw_state == 0x41)
|
||||||
*psr_state = 9;
|
state = PSR_STATE4a;
|
||||||
else if (*psr_state == 0x43)
|
else if (raw_state == 0x42)
|
||||||
*psr_state = 10;
|
state = PSR_STATE4b;
|
||||||
else if (*psr_state == 0x44)
|
else if (raw_state == 0x43)
|
||||||
*psr_state = 11;
|
state = PSR_STATE4c;
|
||||||
else if (*psr_state == 0x50)
|
else if (raw_state == 0x44)
|
||||||
*psr_state = 12;
|
state = PSR_STATE4d;
|
||||||
else if (*psr_state == 0x51)
|
else if (raw_state == 0x50)
|
||||||
*psr_state = 13;
|
state = PSR_STATE5;
|
||||||
else if (*psr_state == 0x52)
|
else if (raw_state == 0x51)
|
||||||
*psr_state = 14;
|
state = PSR_STATE5a;
|
||||||
else if (*psr_state == 0x53)
|
else if (raw_state == 0x52)
|
||||||
*psr_state = 15;
|
state = PSR_STATE5b;
|
||||||
|
else if (raw_state == 0x53)
|
||||||
|
state = PSR_STATE5c;
|
||||||
|
|
||||||
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get PSR state from firmware.
|
* Get PSR state from firmware.
|
||||||
*/
|
*/
|
||||||
static void dmub_psr_get_state(struct dmub_psr *dmub, uint32_t *psr_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;
|
struct dmub_srv *srv = dmub->ctx->dmub_srv->dmub;
|
||||||
|
uint32_t raw_state;
|
||||||
|
|
||||||
// Send gpint command and wait for ack
|
// Send gpint command and wait for ack
|
||||||
dmub_srv_send_gpint_command(srv, DMUB_GPINT__GET_PSR_STATE, 0, 30);
|
dmub_srv_send_gpint_command(srv, DMUB_GPINT__GET_PSR_STATE, 0, 30);
|
||||||
|
|
||||||
dmub_srv_get_gpint_response(srv, psr_state);
|
dmub_srv_get_gpint_response(srv, &raw_state);
|
||||||
|
|
||||||
convert_psr_state(psr_state);
|
*state = convert_psr_state(raw_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -123,7 +128,9 @@ static void dmub_psr_enable(struct dmub_psr *dmub, bool enable, bool wait)
|
||||||
{
|
{
|
||||||
union dmub_rb_cmd cmd;
|
union dmub_rb_cmd cmd;
|
||||||
struct dc_context *dc = dmub->ctx;
|
struct dc_context *dc = dmub->ctx;
|
||||||
uint32_t retry_count, psr_state = 0;
|
uint32_t retry_count;
|
||||||
|
enum dc_psr_state state = PSR_STATE0;
|
||||||
|
|
||||||
|
|
||||||
cmd.psr_enable.header.type = DMUB_CMD__PSR;
|
cmd.psr_enable.header.type = DMUB_CMD__PSR;
|
||||||
|
|
||||||
|
@ -144,13 +151,13 @@ static void dmub_psr_enable(struct dmub_psr *dmub, bool enable, bool wait)
|
||||||
*/
|
*/
|
||||||
if (wait) {
|
if (wait) {
|
||||||
for (retry_count = 0; retry_count <= 1000; retry_count++) {
|
for (retry_count = 0; retry_count <= 1000; retry_count++) {
|
||||||
dmub_psr_get_state(dmub, &psr_state);
|
dmub_psr_get_state(dmub, &state);
|
||||||
|
|
||||||
if (enable) {
|
if (enable) {
|
||||||
if (psr_state != 0)
|
if (state != PSR_STATE0)
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
if (psr_state == 0)
|
if (state == PSR_STATE0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,12 +176,12 @@ static void dmub_psr_enable(struct dmub_psr *dmub, bool enable, bool wait)
|
||||||
static void dmub_psr_set_level(struct dmub_psr *dmub, uint16_t psr_level)
|
static void dmub_psr_set_level(struct dmub_psr *dmub, uint16_t psr_level)
|
||||||
{
|
{
|
||||||
union dmub_rb_cmd cmd;
|
union dmub_rb_cmd cmd;
|
||||||
uint32_t psr_state = 0;
|
enum dc_psr_state state = PSR_STATE0;
|
||||||
struct dc_context *dc = dmub->ctx;
|
struct dc_context *dc = dmub->ctx;
|
||||||
|
|
||||||
dmub_psr_get_state(dmub, &psr_state);
|
dmub_psr_get_state(dmub, &state);
|
||||||
|
|
||||||
if (psr_state == 0)
|
if (state == PSR_STATE0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cmd.psr_set_level.header.type = DMUB_CMD__PSR;
|
cmd.psr_set_level.header.type = DMUB_CMD__PSR;
|
||||||
|
@ -269,11 +276,29 @@ static bool dmub_psr_copy_settings(struct dmub_psr *dmub,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send command to PSR to force static ENTER and ignore all state changes until exit
|
||||||
|
*/
|
||||||
|
static void dmub_psr_force_static(struct dmub_psr *dmub)
|
||||||
|
{
|
||||||
|
union dmub_rb_cmd cmd;
|
||||||
|
struct dc_context *dc = dmub->ctx;
|
||||||
|
|
||||||
|
cmd.psr_force_static.header.type = DMUB_CMD__PSR;
|
||||||
|
cmd.psr_force_static.header.sub_type = DMUB_CMD__PSR_FORCE_STATIC;
|
||||||
|
cmd.psr_enable.header.payload_bytes = 0;
|
||||||
|
|
||||||
|
dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
|
||||||
|
dc_dmub_srv_cmd_execute(dc->dmub_srv);
|
||||||
|
dc_dmub_srv_wait_idle(dc->dmub_srv);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct dmub_psr_funcs psr_funcs = {
|
static const struct dmub_psr_funcs psr_funcs = {
|
||||||
.psr_copy_settings = dmub_psr_copy_settings,
|
.psr_copy_settings = dmub_psr_copy_settings,
|
||||||
.psr_enable = dmub_psr_enable,
|
.psr_enable = dmub_psr_enable,
|
||||||
.psr_get_state = dmub_psr_get_state,
|
.psr_get_state = dmub_psr_get_state,
|
||||||
.psr_set_level = dmub_psr_set_level,
|
.psr_set_level = dmub_psr_set_level,
|
||||||
|
.psr_force_static = dmub_psr_force_static,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -37,8 +37,9 @@ struct dmub_psr {
|
||||||
struct dmub_psr_funcs {
|
struct dmub_psr_funcs {
|
||||||
bool (*psr_copy_settings)(struct dmub_psr *dmub, struct dc_link *link, struct psr_context *psr_context);
|
bool (*psr_copy_settings)(struct dmub_psr *dmub, struct dc_link *link, struct psr_context *psr_context);
|
||||||
void (*psr_enable)(struct dmub_psr *dmub, bool enable, bool wait);
|
void (*psr_enable)(struct dmub_psr *dmub, bool enable, bool wait);
|
||||||
void (*psr_get_state)(struct dmub_psr *dmub, uint32_t *psr_state);
|
void (*psr_get_state)(struct dmub_psr *dmub, enum dc_psr_state *dc_psr_state);
|
||||||
void (*psr_set_level)(struct dmub_psr *dmub, uint16_t psr_level);
|
void (*psr_set_level)(struct dmub_psr *dmub, uint16_t psr_level);
|
||||||
|
void (*psr_force_static)(struct dmub_psr *dmub);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dmub_psr *dmub_psr_create(struct dc_context *ctx);
|
struct dmub_psr *dmub_psr_create(struct dc_context *ctx);
|
||||||
|
|
|
@ -66,7 +66,7 @@ struct dmcu_funcs {
|
||||||
bool (*setup_psr)(struct dmcu *dmcu,
|
bool (*setup_psr)(struct dmcu *dmcu,
|
||||||
struct dc_link *link,
|
struct dc_link *link,
|
||||||
struct psr_context *psr_context);
|
struct psr_context *psr_context);
|
||||||
void (*get_psr_state)(struct dmcu *dmcu, uint32_t *psr_state);
|
void (*get_psr_state)(struct dmcu *dmcu, enum dc_psr_state *dc_psr_state);
|
||||||
void (*set_psr_wait_loop)(struct dmcu *dmcu,
|
void (*set_psr_wait_loop)(struct dmcu *dmcu,
|
||||||
unsigned int wait_loop_number);
|
unsigned int wait_loop_number);
|
||||||
void (*get_psr_wait_loop)(struct dmcu *dmcu,
|
void (*get_psr_wait_loop)(struct dmcu *dmcu,
|
||||||
|
|
Loading…
Reference in a new issue