summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2020-01-13 16:49:01 +1000
committerDave Airlie <airlied@redhat.com>2020-01-13 16:49:02 +1000
commitd5d88cd6ee6b668520c461b960077b5dbd440bc2 (patch)
tree5c6ed633ebfd18dcf1a65aa26e19ef5c8e6560d3 /drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
parent79f88da22b4b2d8c56c784de65e24c4b80f59c0c (diff)
parent0f899fd466b693a129b16994c1b2b4db2fcde4a4 (diff)
Merge tag 'amd-drm-next-5.6-2020-01-09' of git://people.freedesktop.org/~agd5f/linux into drm-next
amd-drm-next-5.6-2020-01-09: amdgpu: - Enable DCN support on POWER - Enable GFXOFF for Raven1 refresh - Clean up MM engine idle handlers - HDMI 2.0 audio fixes - Fixes for some 10 bpc EDP panels - Watermark fixes for renoir - SR-IOV fixes - Runtime pm robustness fixes - Arcturus VCN fixes - RAS fixes - BACO fixes for Arcturus - Stable pstate fixes for swSMU - HDCP fixes - PSP cleanup - HDMI fixes - Misc cleanups amdkfd: - Spread interrupt work across cores to reduce latency - Topology fixes for APUs - GPU reset improvements UAPI: - Enable DRIVER_SYNCOBJ_TIMELINE for vulkan - Return better error values for kfd process ioctl Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexdeucher@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/20200109230338.8022-1-alexander.deucher@amd.com
Diffstat (limited to 'drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c')
-rw-r--r--drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c57
1 files changed, 49 insertions, 8 deletions
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 5f39166d3c08..9a959f871f11 100644
--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
@@ -26,7 +26,7 @@
#include "../inc/dmub_srv.h"
#include "dmub_dcn20.h"
#include "dmub_dcn21.h"
-#include "dmub_trace_buffer.h"
+#include "dmub_fw_meta.h"
#include "os_types.h"
/*
* Note: the DMUB service is standalone. No additional headers should be
@@ -46,6 +46,11 @@
/* Mailbox size */
#define DMUB_MAILBOX_SIZE (DMUB_RB_SIZE)
+/* Default state size if meta is absent. */
+#define DMUB_FW_STATE_SIZE (1024)
+
+/* Default tracebuffer size if meta is absent. */
+#define DMUB_TRACE_BUFFER_SIZE (1024)
/* Number of windows in use. */
#define DMUB_NUM_WINDOWS (DMUB_WINDOW_6_FW_STATE + 1)
@@ -62,6 +67,27 @@ static inline uint32_t dmub_align(uint32_t val, uint32_t factor)
return (val + factor - 1) / factor * factor;
}
+static const struct dmub_fw_meta_info *
+dmub_get_fw_meta_info(const uint8_t *fw_bss_data, uint32_t fw_bss_data_size)
+{
+ const union dmub_fw_meta *meta;
+
+ if (fw_bss_data == NULL)
+ return NULL;
+
+ if (fw_bss_data_size < sizeof(union dmub_fw_meta) + DMUB_FW_META_OFFSET)
+ return NULL;
+
+ meta = (const union dmub_fw_meta *)(fw_bss_data + fw_bss_data_size -
+ DMUB_FW_META_OFFSET -
+ sizeof(union dmub_fw_meta));
+
+ if (meta->info.magic_value != DMUB_FW_META_MAGIC)
+ return NULL;
+
+ return &meta->info;
+}
+
static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic)
{
struct dmub_srv_hw_funcs *funcs = &dmub->hw_funcs;
@@ -69,6 +95,8 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic)
switch (asic) {
case DMUB_ASIC_DCN20:
case DMUB_ASIC_DCN21:
+ dmub->regs = &dmub_srv_dcn20_regs;
+
funcs->reset = dmub_dcn20_reset;
funcs->reset_release = dmub_dcn20_reset_release;
funcs->backdoor_load = dmub_dcn20_backdoor_load;
@@ -80,8 +108,8 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic)
funcs->is_hw_init = dmub_dcn20_is_hw_init;
if (asic == DMUB_ASIC_DCN21) {
- funcs->backdoor_load = dmub_dcn21_backdoor_load;
- funcs->setup_windows = dmub_dcn21_setup_windows;
+ dmub->regs = &dmub_srv_dcn21_regs;
+
funcs->is_auto_load_done = dmub_dcn21_is_auto_load_done;
funcs->is_phy_init = dmub_dcn21_is_phy_init;
}
@@ -160,6 +188,9 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub,
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];
+ const struct dmub_fw_meta_info *fw_info;
+ uint32_t fw_state_size = DMUB_FW_STATE_SIZE;
+ uint32_t trace_buffer_size = DMUB_TRACE_BUFFER_SIZE;
if (!dmub->sw_init)
return DMUB_STATUS_INVALID;
@@ -174,6 +205,11 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub,
data->base = dmub_align(inst->top, 256);
data->top = data->base + params->bss_data_size;
+ /*
+ * All cache windows below should be aligned to the size
+ * of the DMCUB cache line, 64 bytes.
+ */
+
stack->base = dmub_align(data->top, 256);
stack->top = stack->base + DMUB_STACK_SIZE + DMUB_CONTEXT_SIZE;
@@ -183,14 +219,19 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub,
mail->base = dmub_align(bios->top, 256);
mail->top = mail->base + DMUB_MAILBOX_SIZE;
+ fw_info = dmub_get_fw_meta_info(params->fw_bss_data,
+ params->bss_data_size);
+
+ if (fw_info) {
+ fw_state_size = fw_info->fw_region_size;
+ trace_buffer_size = fw_info->trace_buffer_size;
+ }
+
trace_buff->base = dmub_align(mail->top, 256);
- trace_buff->top = trace_buff->base + TRACE_BUF_SIZE;
+ trace_buff->top = trace_buff->base + dmub_align(trace_buffer_size, 64);
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);
+ fw_state->top = fw_state->base + dmub_align(fw_state_size, 64);
out->fb_size = dmub_align(fw_state->top, 4096);