mirror of
https://github.com/torvalds/linux.git
synced 2026-05-25 15:41:52 +02:00
drm/amd/display: Restore rptr/wptr for DMCUB as workaround
[Why] States may be desync after resume. [How] Sync sw state with hw state. Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com> Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com> Signed-off-by: JinZe.Xu <JinZe.Xu@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
278d3de675
commit
8f3589bb6f
|
|
@ -340,6 +340,8 @@ struct dmub_srv_hw_funcs {
|
|||
void (*setup_mailbox)(struct dmub_srv *dmub,
|
||||
const struct dmub_region *inbox1);
|
||||
|
||||
uint32_t (*get_inbox1_wptr)(struct dmub_srv *dmub);
|
||||
|
||||
uint32_t (*get_inbox1_rptr)(struct dmub_srv *dmub);
|
||||
|
||||
void (*set_inbox1_wptr)(struct dmub_srv *dmub, uint32_t wptr_offset);
|
||||
|
|
@ -600,6 +602,18 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub,
|
|||
*/
|
||||
enum dmub_status dmub_srv_hw_reset(struct dmub_srv *dmub);
|
||||
|
||||
/**
|
||||
* dmub_srv_sync_inbox1() - sync sw state with hw state
|
||||
* @dmub: the dmub service
|
||||
*
|
||||
* Sync sw state with hw state when resume from S0i3
|
||||
*
|
||||
* Return:
|
||||
* DMUB_STATUS_OK - success
|
||||
* DMUB_STATUS_INVALID - unspecified error
|
||||
*/
|
||||
enum dmub_status dmub_srv_sync_inbox1(struct dmub_srv *dmub);
|
||||
|
||||
/**
|
||||
* dmub_srv_cmd_queue() - queues a command to the DMUB
|
||||
* @dmub: the dmub service
|
||||
|
|
|
|||
|
|
@ -282,6 +282,11 @@ void dmub_dcn20_setup_mailbox(struct dmub_srv *dmub,
|
|||
REG_WRITE(DMCUB_INBOX1_SIZE, inbox1->top - inbox1->base);
|
||||
}
|
||||
|
||||
uint32_t dmub_dcn20_get_inbox1_wptr(struct dmub_srv *dmub)
|
||||
{
|
||||
return REG_READ(DMCUB_INBOX1_WPTR);
|
||||
}
|
||||
|
||||
uint32_t dmub_dcn20_get_inbox1_rptr(struct dmub_srv *dmub)
|
||||
{
|
||||
return REG_READ(DMCUB_INBOX1_RPTR);
|
||||
|
|
|
|||
|
|
@ -202,6 +202,8 @@ void dmub_dcn20_setup_windows(struct dmub_srv *dmub,
|
|||
void dmub_dcn20_setup_mailbox(struct dmub_srv *dmub,
|
||||
const struct dmub_region *inbox1);
|
||||
|
||||
uint32_t dmub_dcn20_get_inbox1_wptr(struct dmub_srv *dmub);
|
||||
|
||||
uint32_t dmub_dcn20_get_inbox1_rptr(struct dmub_srv *dmub);
|
||||
|
||||
void dmub_dcn20_set_inbox1_wptr(struct dmub_srv *dmub, uint32_t wptr_offset);
|
||||
|
|
|
|||
|
|
@ -242,6 +242,11 @@ void dmub_dcn31_setup_mailbox(struct dmub_srv *dmub,
|
|||
REG_WRITE(DMCUB_INBOX1_SIZE, inbox1->top - inbox1->base);
|
||||
}
|
||||
|
||||
uint32_t dmub_dcn31_get_inbox1_wptr(struct dmub_srv *dmub)
|
||||
{
|
||||
return REG_READ(DMCUB_INBOX1_WPTR);
|
||||
}
|
||||
|
||||
uint32_t dmub_dcn31_get_inbox1_rptr(struct dmub_srv *dmub)
|
||||
{
|
||||
return REG_READ(DMCUB_INBOX1_RPTR);
|
||||
|
|
|
|||
|
|
@ -204,6 +204,8 @@ void dmub_dcn31_setup_windows(struct dmub_srv *dmub,
|
|||
void dmub_dcn31_setup_mailbox(struct dmub_srv *dmub,
|
||||
const struct dmub_region *inbox1);
|
||||
|
||||
uint32_t dmub_dcn31_get_inbox1_wptr(struct dmub_srv *dmub);
|
||||
|
||||
uint32_t dmub_dcn31_get_inbox1_rptr(struct dmub_srv *dmub);
|
||||
|
||||
void dmub_dcn31_set_inbox1_wptr(struct dmub_srv *dmub, uint32_t wptr_offset);
|
||||
|
|
|
|||
|
|
@ -266,6 +266,11 @@ void dmub_dcn32_setup_mailbox(struct dmub_srv *dmub,
|
|||
REG_WRITE(DMCUB_INBOX1_SIZE, inbox1->top - inbox1->base);
|
||||
}
|
||||
|
||||
uint32_t dmub_dcn32_get_inbox1_wptr(struct dmub_srv *dmub)
|
||||
{
|
||||
return REG_READ(DMCUB_INBOX1_WPTR);
|
||||
}
|
||||
|
||||
uint32_t dmub_dcn32_get_inbox1_rptr(struct dmub_srv *dmub)
|
||||
{
|
||||
return REG_READ(DMCUB_INBOX1_RPTR);
|
||||
|
|
|
|||
|
|
@ -206,6 +206,8 @@ void dmub_dcn32_setup_windows(struct dmub_srv *dmub,
|
|||
void dmub_dcn32_setup_mailbox(struct dmub_srv *dmub,
|
||||
const struct dmub_region *inbox1);
|
||||
|
||||
uint32_t dmub_dcn32_get_inbox1_wptr(struct dmub_srv *dmub);
|
||||
|
||||
uint32_t dmub_dcn32_get_inbox1_rptr(struct dmub_srv *dmub);
|
||||
|
||||
void dmub_dcn32_set_inbox1_wptr(struct dmub_srv *dmub, uint32_t wptr_offset);
|
||||
|
|
|
|||
|
|
@ -166,6 +166,7 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic)
|
|||
funcs->backdoor_load = dmub_dcn20_backdoor_load;
|
||||
funcs->setup_windows = dmub_dcn20_setup_windows;
|
||||
funcs->setup_mailbox = dmub_dcn20_setup_mailbox;
|
||||
funcs->get_inbox1_wptr = dmub_dcn20_get_inbox1_wptr;
|
||||
funcs->get_inbox1_rptr = dmub_dcn20_get_inbox1_rptr;
|
||||
funcs->set_inbox1_wptr = dmub_dcn20_set_inbox1_wptr;
|
||||
funcs->is_supported = dmub_dcn20_is_supported;
|
||||
|
|
@ -235,6 +236,7 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic)
|
|||
funcs->backdoor_load = dmub_dcn31_backdoor_load;
|
||||
funcs->setup_windows = dmub_dcn31_setup_windows;
|
||||
funcs->setup_mailbox = dmub_dcn31_setup_mailbox;
|
||||
funcs->get_inbox1_wptr = dmub_dcn31_get_inbox1_wptr;
|
||||
funcs->get_inbox1_rptr = dmub_dcn31_get_inbox1_rptr;
|
||||
funcs->set_inbox1_wptr = dmub_dcn31_set_inbox1_wptr;
|
||||
funcs->setup_out_mailbox = dmub_dcn31_setup_out_mailbox;
|
||||
|
|
@ -273,6 +275,7 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic)
|
|||
funcs->backdoor_load_zfb_mode = dmub_dcn32_backdoor_load_zfb_mode;
|
||||
funcs->setup_windows = dmub_dcn32_setup_windows;
|
||||
funcs->setup_mailbox = dmub_dcn32_setup_mailbox;
|
||||
funcs->get_inbox1_wptr = dmub_dcn32_get_inbox1_wptr;
|
||||
funcs->get_inbox1_rptr = dmub_dcn32_get_inbox1_rptr;
|
||||
funcs->set_inbox1_wptr = dmub_dcn32_set_inbox1_wptr;
|
||||
funcs->setup_out_mailbox = dmub_dcn32_setup_out_mailbox;
|
||||
|
|
@ -642,6 +645,20 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub,
|
|||
return DMUB_STATUS_OK;
|
||||
}
|
||||
|
||||
enum dmub_status dmub_srv_sync_inbox1(struct dmub_srv *dmub)
|
||||
{
|
||||
if (!dmub->sw_init)
|
||||
return DMUB_STATUS_INVALID;
|
||||
|
||||
if (dmub->hw_funcs.get_inbox1_rptr && dmub->hw_funcs.get_inbox1_wptr) {
|
||||
dmub->inbox1_rb.rptr = dmub->hw_funcs.get_inbox1_rptr(dmub);
|
||||
dmub->inbox1_rb.wrpt = dmub->hw_funcs.get_inbox1_wptr(dmub);
|
||||
dmub->inbox1_last_wptr = dmub->inbox1_rb.wrpt;
|
||||
}
|
||||
|
||||
return DMUB_STATUS_OK;
|
||||
}
|
||||
|
||||
enum dmub_status dmub_srv_hw_reset(struct dmub_srv *dmub)
|
||||
{
|
||||
if (!dmub->sw_init)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user