aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4696-drm-amd-display-Add-shared-DMCUB-driver-firmware-sta.patch
diff options
context:
space:
mode:
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.patch333
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
+