From 69703a933fd2153b10aac26ea9b3dd8ae1f60076 Mon Sep 17 00:00:00 2001 From: jsg Date: Mon, 11 Dec 2023 05:18:43 +0000 Subject: [PATCH] drm/amd/display: Restore rptr/wptr for DMCUB as workaround From JinZe Xu 395a63ca1ad2e0534176cac91f5715961e744529 in linux-6.1.y/6.1.66 8f3589bb6fcea397775398cba4fbcc46829a60ed in mainline linux --- sys/dev/pci/drm/amd/display/dmub/dmub_srv.h | 14 ++++++++++++++ .../pci/drm/amd/display/dmub/src/dmub_dcn20.c | 5 +++++ .../pci/drm/amd/display/dmub/src/dmub_dcn20.h | 2 ++ .../pci/drm/amd/display/dmub/src/dmub_dcn31.c | 5 +++++ .../pci/drm/amd/display/dmub/src/dmub_dcn31.h | 2 ++ .../pci/drm/amd/display/dmub/src/dmub_dcn32.c | 5 +++++ .../pci/drm/amd/display/dmub/src/dmub_dcn32.h | 2 ++ sys/dev/pci/drm/amd/display/dmub/src/dmub_srv.c | 17 +++++++++++++++++ 8 files changed, 52 insertions(+) diff --git a/sys/dev/pci/drm/amd/display/dmub/dmub_srv.h b/sys/dev/pci/drm/amd/display/dmub/dmub_srv.h index a21fe7b037d..aaabaab4980 100644 --- a/sys/dev/pci/drm/amd/display/dmub/dmub_srv.h +++ b/sys/dev/pci/drm/amd/display/dmub/dmub_srv.h @@ -332,6 +332,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); @@ -590,6 +592,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 diff --git a/sys/dev/pci/drm/amd/display/dmub/src/dmub_dcn20.c b/sys/dev/pci/drm/amd/display/dmub/src/dmub_dcn20.c index a6540e27044..98dad0d47e7 100644 --- a/sys/dev/pci/drm/amd/display/dmub/src/dmub_dcn20.c +++ b/sys/dev/pci/drm/amd/display/dmub/src/dmub_dcn20.c @@ -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); diff --git a/sys/dev/pci/drm/amd/display/dmub/src/dmub_dcn20.h b/sys/dev/pci/drm/amd/display/dmub/src/dmub_dcn20.h index c2e5831ac52..1df128e57ed 100644 --- a/sys/dev/pci/drm/amd/display/dmub/src/dmub_dcn20.h +++ b/sys/dev/pci/drm/amd/display/dmub/src/dmub_dcn20.h @@ -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); diff --git a/sys/dev/pci/drm/amd/display/dmub/src/dmub_dcn31.c b/sys/dev/pci/drm/amd/display/dmub/src/dmub_dcn31.c index 89d24fb7024..5e952541e72 100644 --- a/sys/dev/pci/drm/amd/display/dmub/src/dmub_dcn31.c +++ b/sys/dev/pci/drm/amd/display/dmub/src/dmub_dcn31.c @@ -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); diff --git a/sys/dev/pci/drm/amd/display/dmub/src/dmub_dcn31.h b/sys/dev/pci/drm/amd/display/dmub/src/dmub_dcn31.h index eb624109414..89c5a948b67 100644 --- a/sys/dev/pci/drm/amd/display/dmub/src/dmub_dcn31.h +++ b/sys/dev/pci/drm/amd/display/dmub/src/dmub_dcn31.h @@ -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); diff --git a/sys/dev/pci/drm/amd/display/dmub/src/dmub_dcn32.c b/sys/dev/pci/drm/amd/display/dmub/src/dmub_dcn32.c index 9c20516be06..d2f03f79727 100644 --- a/sys/dev/pci/drm/amd/display/dmub/src/dmub_dcn32.c +++ b/sys/dev/pci/drm/amd/display/dmub/src/dmub_dcn32.c @@ -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); diff --git a/sys/dev/pci/drm/amd/display/dmub/src/dmub_dcn32.h b/sys/dev/pci/drm/amd/display/dmub/src/dmub_dcn32.h index 7d1a6eb4d66..f15336b6e22 100644 --- a/sys/dev/pci/drm/amd/display/dmub/src/dmub_dcn32.h +++ b/sys/dev/pci/drm/amd/display/dmub/src/dmub_dcn32.h @@ -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); diff --git a/sys/dev/pci/drm/amd/display/dmub/src/dmub_srv.c b/sys/dev/pci/drm/amd/display/dmub/src/dmub_srv.c index f58803de37c..6b8bd556c87 100644 --- a/sys/dev/pci/drm/amd/display/dmub/src/dmub_srv.c +++ b/sys/dev/pci/drm/amd/display/dmub/src/dmub_srv.c @@ -167,6 +167,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; @@ -243,6 +244,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; @@ -281,6 +283,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; @@ -666,6 +669,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) -- 2.20.1