diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4696-drm-amd-display-Add-shared-DMCUB-driver-firmware-sta.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4696-drm-amd-display-Add-shared-DMCUB-driver-firmware-sta.patch | 333 |
1 files changed, 333 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4696-drm-amd-display-Add-shared-DMCUB-driver-firmware-sta.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4696-drm-amd-display-Add-shared-DMCUB-driver-firmware-sta.patch new file mode 100644 index 00000000..358f5acc --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4696-drm-amd-display-Add-shared-DMCUB-driver-firmware-sta.patch @@ -0,0 +1,333 @@ +From 740f33a5fe33c62249db788bd90ce46dcbe72499 Mon Sep 17 00:00:00 2001 +From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> +Date: Tue, 12 Nov 2019 13:46:34 -0500 +Subject: [PATCH 4696/4736] drm/amd/display: Add shared DMCUB/driver firmware + state cache window + +[Why] +Scratch registers are limited on the DMCUB and we have an expanding +list of state to track between driver and DMCUB. + +[How] +Place shared state in cache window 6. The cache window size is aligned +to the size of the cache line on the DMCUB to make it easy to +invalidate. + +The shared state is intended to be read only from driver side so +it's been marked as const. + +The use of volatile is intentional. The memory for the shared firmware +state is memory mapped from the framebuffer memory. The DMCUB will +flush its cache after modifying the region. There's no way for x86 +to known whether this data is stale or not so we want to intentionally +disable optimization to force the read at every access. + +Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> +Reviewed-by: Tony Cheng <Tony.Cheng@amd.com> +Acked-by: Leo Li <sunpeng.li@amd.com> +--- + .../drm/amd/display/dmub/inc/dmub_fw_state.h | 73 +++++++++++++++++++ + .../gpu/drm/amd/display/dmub/inc/dmub_srv.h | 8 +- + .../gpu/drm/amd/display/dmub/src/dmub_dcn20.c | 10 ++- + .../gpu/drm/amd/display/dmub/src/dmub_dcn20.h | 3 +- + .../gpu/drm/amd/display/dmub/src/dmub_dcn21.c | 12 ++- + .../gpu/drm/amd/display/dmub/src/dmub_dcn21.h | 3 +- + .../gpu/drm/amd/display/dmub/src/dmub_srv.c | 27 +++++-- + 7 files changed, 125 insertions(+), 11 deletions(-) + create mode 100644 drivers/gpu/drm/amd/display/dmub/inc/dmub_fw_state.h + +diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_fw_state.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_fw_state.h +new file mode 100644 +index 000000000000..c87b1ba7590e +--- /dev/null ++++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_fw_state.h +@@ -0,0 +1,73 @@ ++/* ++ * Copyright 2019 Advanced Micro Devices, Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: AMD ++ * ++ */ ++ ++#ifndef _DMUB_FW_STATE_H_ ++#define _DMUB_FW_STATE_H_ ++ ++#include "dmub_types.h" ++ ++#pragma pack(push, 1) ++ ++struct dmub_fw_state { ++ /** ++ * @phy_initialized_during_fw_boot: ++ * ++ * Detects if VBIOS/VBL has ran before firmware boot. ++ * A value of 1 will usually mean S0i3 boot. ++ */ ++ uint8_t phy_initialized_during_fw_boot; ++ ++ /** ++ * @intialized_phy: ++ * ++ * Bit vector of initialized PHY. ++ */ ++ uint8_t initialized_phy; ++ ++ /** ++ * @enabled_phy: ++ * ++ * Bit vector of enabled PHY for DP alt mode switch tracking. ++ */ ++ uint8_t enabled_phy; ++ ++ /** ++ * @dmcu_fw_loaded: ++ * ++ * DMCU auto load state. ++ */ ++ uint8_t dmcu_fw_loaded; ++ ++ /** ++ * @psr_state: ++ * ++ * PSR state tracking. ++ */ ++ uint8_t psr_state; ++}; ++ ++#pragma pack(pop) ++ ++#endif /* _DMUB_FW_STATE_H_ */ +diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_srv.h +index 046885940dba..d678b6f0313f 100644 +--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_srv.h ++++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_srv.h +@@ -67,6 +67,7 @@ + #include "dmub_types.h" + #include "dmub_cmd.h" + #include "dmub_rb.h" ++#include "dmub_fw_state.h" + + #if defined(__cplusplus) + extern "C" { +@@ -102,7 +103,7 @@ enum dmub_window_id { + DMUB_WINDOW_3_VBIOS, + DMUB_WINDOW_4_MAILBOX, + DMUB_WINDOW_5_TRACEBUFF, +- DMUB_WINDOW_6_RESERVED, ++ DMUB_WINDOW_6_FW_STATE, + DMUB_WINDOW_7_RESERVED, + DMUB_WINDOW_TOTAL, + }; +@@ -241,7 +242,8 @@ struct dmub_srv_hw_funcs { + const struct dmub_window *cw2, + const struct dmub_window *cw3, + const struct dmub_window *cw4, +- const struct dmub_window *cw5); ++ const struct dmub_window *cw5, ++ const struct dmub_window *cw6); + + void (*setup_mailbox)(struct dmub_srv *dmub, + const struct dmub_region *inbox1); +@@ -296,11 +298,13 @@ struct dmub_srv_hw_params { + * @asic: dmub asic identifier + * @user_ctx: user provided context for the dmub_srv + * @is_virtual: false if hardware support only ++ * @fw_state: dmub firmware state pointer + */ + struct dmub_srv { + enum dmub_asic asic; + void *user_ctx; + bool is_virtual; ++ volatile const struct dmub_fw_state *fw_state; + + /* private: internal use only */ + struct dmub_srv_base_funcs funcs; +diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c +index 302dd3d4b77d..951ea7053c7e 100644 +--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c ++++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c +@@ -76,7 +76,8 @@ void dmub_dcn20_setup_windows(struct dmub_srv *dmub, + const struct dmub_window *cw2, + const struct dmub_window *cw3, + const struct dmub_window *cw4, +- const struct dmub_window *cw5) ++ const struct dmub_window *cw5, ++ const struct dmub_window *cw6) + { + REG_WRITE(DMCUB_REGION3_CW2_OFFSET, cw2->offset.u.low_part); + REG_WRITE(DMCUB_REGION3_CW2_OFFSET_HIGH, cw2->offset.u.high_part); +@@ -106,6 +107,13 @@ void dmub_dcn20_setup_windows(struct dmub_srv *dmub, + REG_SET_2(DMCUB_REGION3_CW5_TOP_ADDRESS, 0, + DMCUB_REGION3_CW5_TOP_ADDRESS, cw5->region.top, + DMCUB_REGION3_CW5_ENABLE, 1); ++ ++ REG_WRITE(DMCUB_REGION3_CW6_OFFSET, cw6->offset.u.low_part); ++ REG_WRITE(DMCUB_REGION3_CW6_OFFSET_HIGH, cw6->offset.u.high_part); ++ REG_WRITE(DMCUB_REGION3_CW6_BASE_ADDRESS, cw6->region.base); ++ REG_SET_2(DMCUB_REGION3_CW6_TOP_ADDRESS, 0, ++ DMCUB_REGION3_CW6_TOP_ADDRESS, cw6->region.top, ++ DMCUB_REGION3_CW6_ENABLE, 1); + } + + void dmub_dcn20_setup_mailbox(struct dmub_srv *dmub, +diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h +index ca7db03b94f7..e70a57573467 100644 +--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h ++++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h +@@ -46,7 +46,8 @@ void dmub_dcn20_setup_windows(struct dmub_srv *dmub, + const struct dmub_window *cw2, + const struct dmub_window *cw3, + const struct dmub_window *cw4, +- const struct dmub_window *cw5); ++ const struct dmub_window *cw5, ++ const struct dmub_window *cw6); + + void dmub_dcn20_setup_mailbox(struct dmub_srv *dmub, + const struct dmub_region *inbox1); +diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.c +index b9dc2dd645eb..9cea7a2d8dbf 100644 +--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.c ++++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.c +@@ -78,7 +78,8 @@ void dmub_dcn21_setup_windows(struct dmub_srv *dmub, + const struct dmub_window *cw2, + const struct dmub_window *cw3, + const struct dmub_window *cw4, +- const struct dmub_window *cw5) ++ const struct dmub_window *cw5, ++ const struct dmub_window *cw6) + { + union dmub_addr offset; + uint64_t fb_base = dmub->fb_base, fb_offset = dmub->fb_offset; +@@ -118,6 +119,15 @@ void dmub_dcn21_setup_windows(struct dmub_srv *dmub, + REG_SET_2(DMCUB_REGION3_CW5_TOP_ADDRESS, 0, + DMCUB_REGION3_CW5_TOP_ADDRESS, cw5->region.top, + DMCUB_REGION3_CW5_ENABLE, 1); ++ ++ dmub_dcn21_translate_addr(&cw6->offset, fb_base, fb_offset, &offset); ++ ++ REG_WRITE(DMCUB_REGION3_CW6_OFFSET, offset.u.low_part); ++ REG_WRITE(DMCUB_REGION3_CW6_OFFSET_HIGH, offset.u.high_part); ++ REG_WRITE(DMCUB_REGION3_CW6_BASE_ADDRESS, cw6->region.base); ++ REG_SET_2(DMCUB_REGION3_CW6_TOP_ADDRESS, 0, ++ DMCUB_REGION3_CW6_TOP_ADDRESS, cw6->region.top, ++ DMCUB_REGION3_CW6_ENABLE, 1); + } + + bool dmub_dcn21_is_auto_load_done(struct dmub_srv *dmub) +diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.h +index 9e5f195e288f..f7a93a5dcfa5 100644 +--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.h ++++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.h +@@ -38,7 +38,8 @@ void dmub_dcn21_setup_windows(struct dmub_srv *dmub, + const struct dmub_window *cw2, + const struct dmub_window *cw3, + const struct dmub_window *cw4, +- const struct dmub_window *cw5); ++ const struct dmub_window *cw5, ++ const struct dmub_window *cw6); + + bool dmub_dcn21_is_auto_load_done(struct dmub_srv *dmub); + +diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +index 70c7a4be9ccc..5f39166d3c08 100644 +--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c ++++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +@@ -48,13 +48,14 @@ + + + /* Number of windows in use. */ +-#define DMUB_NUM_WINDOWS (DMUB_WINDOW_5_TRACEBUFF + 1) ++#define DMUB_NUM_WINDOWS (DMUB_WINDOW_6_FW_STATE + 1) + /* Base addresses. */ + + #define DMUB_CW0_BASE (0x60000000) + #define DMUB_CW1_BASE (0x61000000) + #define DMUB_CW3_BASE (0x63000000) + #define DMUB_CW5_BASE (0x65000000) ++#define DMUB_CW6_BASE (0x66000000) + + static inline uint32_t dmub_align(uint32_t val, uint32_t factor) + { +@@ -158,6 +159,7 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub, + struct dmub_region *bios = &out->regions[DMUB_WINDOW_3_VBIOS]; + struct dmub_region *mail = &out->regions[DMUB_WINDOW_4_MAILBOX]; + struct dmub_region *trace_buff = &out->regions[DMUB_WINDOW_5_TRACEBUFF]; ++ struct dmub_region *fw_state = &out->regions[DMUB_WINDOW_6_FW_STATE]; + + if (!dmub->sw_init) + return DMUB_STATUS_INVALID; +@@ -184,7 +186,13 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub, + trace_buff->base = dmub_align(mail->top, 256); + trace_buff->top = trace_buff->base + TRACE_BUF_SIZE; + +- out->fb_size = dmub_align(trace_buff->top, 4096); ++ fw_state->base = dmub_align(trace_buff->top, 256); ++ ++ /* Align firmware state to size of cache line. */ ++ fw_state->top = ++ fw_state->base + dmub_align(sizeof(struct dmub_fw_state), 64); ++ ++ out->fb_size = dmub_align(fw_state->top, 4096); + + return DMUB_STATUS_OK; + } +@@ -258,9 +266,10 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub, + struct dmub_fb *bios_fb = params->fb[DMUB_WINDOW_3_VBIOS]; + struct dmub_fb *mail_fb = params->fb[DMUB_WINDOW_4_MAILBOX]; + struct dmub_fb *tracebuff_fb = params->fb[DMUB_WINDOW_5_TRACEBUFF]; ++ struct dmub_fb *fw_state_fb = params->fb[DMUB_WINDOW_6_FW_STATE]; + + struct dmub_rb_init_params rb_params; +- struct dmub_window cw0, cw1, cw2, cw3, cw4, cw5; ++ struct dmub_window cw0, cw1, cw2, cw3, cw4, cw5, cw6; + struct dmub_region inbox1; + + if (!dmub->sw_init) +@@ -286,7 +295,8 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub, + if (dmub->hw_funcs.reset) + dmub->hw_funcs.reset(dmub); + +- if (inst_fb && data_fb && bios_fb && mail_fb) { ++ if (inst_fb && data_fb && bios_fb && mail_fb && tracebuff_fb && ++ fw_state_fb) { + cw2.offset.quad_part = data_fb->gpu_addr; + cw2.region.base = DMUB_CW0_BASE + inst_fb->size; + cw2.region.top = cw2.region.base + data_fb->size; +@@ -306,8 +316,15 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub, + cw5.region.base = DMUB_CW5_BASE; + cw5.region.top = cw5.region.base + tracebuff_fb->size; + ++ cw6.offset.quad_part = fw_state_fb->gpu_addr; ++ cw6.region.base = DMUB_CW6_BASE; ++ cw6.region.top = cw6.region.base + fw_state_fb->size; ++ ++ dmub->fw_state = fw_state_fb->cpu_addr; ++ + if (dmub->hw_funcs.setup_windows) +- dmub->hw_funcs.setup_windows(dmub, &cw2, &cw3, &cw4, &cw5); ++ dmub->hw_funcs.setup_windows(dmub, &cw2, &cw3, &cw4, ++ &cw5, &cw6); + + if (dmub->hw_funcs.setup_mailbox) + dmub->hw_funcs.setup_mailbox(dmub, &inbox1); +-- +2.17.1 + |