diff options
author | Krunoslav Kovac <Krunoslav.Kovac@amd.com> | 2020-10-20 23:23:15 +0300 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2020-11-10 22:24:55 +0300 |
commit | 1d496907f1c50c1c5f9617d4b7628a635fdd9cb1 (patch) | |
tree | 39636f147b62ff6153f11b530793e2c3c8365e71 /drivers/gpu/drm/amd/display/dc/dce | |
parent | fa896813b441115545349752e15a7d66f3fa2240 (diff) | |
download | linux-1d496907f1c50c1c5f9617d4b7628a635fdd9cb1.tar.xz |
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>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dce')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c | 24 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c | 111 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h | 3 |
3 files changed, 82 insertions, 56 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c index f0cebe721bcc..f3ed8b619caf 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c @@ -99,7 +99,7 @@ bool dce_dmcu_load_iram(struct dmcu *dmcu, 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); @@ -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); /* 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 * 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 retryCount; - uint32_t psr_state = 0; + enum dc_psr_state state = PSR_STATE0; /* waitDMCUReadyForCmd */ 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); if (wait == true) { for (retryCount = 0; retryCount <= 100; retryCount++) { - dce_get_dmcu_psr_state(dmcu, &psr_state); + dce_get_dmcu_psr_state(dmcu, &state); if (enable) { - if (psr_state != 0) + if (state != PSR_STATE0) break; } else { - if (psr_state == 0) + if (state == PSR_STATE0) break; } udelay(10); @@ -513,7 +513,7 @@ static bool dcn10_dmcu_load_iram(struct dmcu *dmcu, 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); @@ -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); /* 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 * 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 retryCount; - uint32_t psr_state = 0; + enum dc_psr_state state = PSR_STATE0; /* If microcontroller is not running, do nothing */ 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) { for (retryCount = 0; retryCount <= 1000; retryCount++) { - dcn10_get_dmcu_psr_state(dmcu, &psr_state); + dcn10_get_dmcu_psr_state(dmcu, &state); if (enable) { - if (psr_state != 0) + if (state != PSR_STATE0) break; } else { - if (psr_state == 0) + if (state == PSR_STATE0) break; } udelay(500); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c index 67af67ef2865..df3879c713c5 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c @@ -34,55 +34,60 @@ /** * 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) - *psr_state = 0; - else if (*psr_state == 0x10) - *psr_state = 1; - else if (*psr_state == 0x11) - *psr_state = 2; - else if (*psr_state == 0x20) - *psr_state = 3; - else if (*psr_state == 0x21) - *psr_state = 4; - else if (*psr_state == 0x30) - *psr_state = 5; - else if (*psr_state == 0x31) - *psr_state = 6; - else if (*psr_state == 0x40) - *psr_state = 7; - else if (*psr_state == 0x41) - *psr_state = 8; - else if (*psr_state == 0x42) - *psr_state = 9; - else if (*psr_state == 0x43) - *psr_state = 10; - else if (*psr_state == 0x44) - *psr_state = 11; - else if (*psr_state == 0x50) - *psr_state = 12; - else if (*psr_state == 0x51) - *psr_state = 13; - else if (*psr_state == 0x52) - *psr_state = 14; - else if (*psr_state == 0x53) - *psr_state = 15; + enum dc_psr_state state = PSR_STATE0; + + if (raw_state == 0) + state = PSR_STATE0; + else if (raw_state == 0x10) + state = PSR_STATE1; + else if (raw_state == 0x11) + state = PSR_STATE1a; + else if (raw_state == 0x20) + state = PSR_STATE2; + else if (raw_state == 0x21) + state = PSR_STATE2a; + else if (raw_state == 0x30) + state = PSR_STATE3; + else if (raw_state == 0x31) + state = PSR_STATE3Init; + else if (raw_state == 0x40) + state = PSR_STATE4; + else if (raw_state == 0x41) + state = PSR_STATE4a; + else if (raw_state == 0x42) + state = PSR_STATE4b; + else if (raw_state == 0x43) + state = PSR_STATE4c; + else if (raw_state == 0x44) + state = PSR_STATE4d; + else if (raw_state == 0x50) + state = PSR_STATE5; + else if (raw_state == 0x51) + state = PSR_STATE5a; + else if (raw_state == 0x52) + state = PSR_STATE5b; + else if (raw_state == 0x53) + state = PSR_STATE5c; + + return state; } /** * 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; + uint32_t raw_state; // Send gpint command and wait for ack 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; 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; @@ -144,13 +151,13 @@ static void dmub_psr_enable(struct dmub_psr *dmub, bool enable, bool wait) */ if (wait) { 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 (psr_state != 0) + if (state != PSR_STATE0) break; } else { - if (psr_state == 0) + if (state == PSR_STATE0) 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) { union dmub_rb_cmd cmd; - uint32_t psr_state = 0; + enum dc_psr_state state = PSR_STATE0; 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; 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; } +/** + * 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 = { .psr_copy_settings = dmub_psr_copy_settings, .psr_enable = dmub_psr_enable, .psr_get_state = dmub_psr_get_state, .psr_set_level = dmub_psr_set_level, + .psr_force_static = dmub_psr_force_static, }; /** diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h index dc121ed92d2e..4e113ac5a56b 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h @@ -37,8 +37,9 @@ struct dmub_psr { struct dmub_psr_funcs { 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_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_force_static)(struct dmub_psr *dmub); }; struct dmub_psr *dmub_psr_create(struct dc_context *ctx); |