diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/1523-drm-amd-display-Add-dmub-offload-functions.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.19.8/1523-drm-amd-display-Add-dmub-offload-functions.patch | 519 |
1 files changed, 519 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/1523-drm-amd-display-Add-dmub-offload-functions.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/1523-drm-amd-display-Add-dmub-offload-functions.patch new file mode 100644 index 00000000..bc94cf04 --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/1523-drm-amd-display-Add-dmub-offload-functions.patch @@ -0,0 +1,519 @@ +From 4cab5054e42fd9e1c3f64855615e73b23f9e6909 Mon Sep 17 00:00:00 2001 +From: Yongqiang Sun <yongqiang.sun@amd.com> +Date: Thu, 3 Jan 2019 10:32:55 -0500 +Subject: [PATCH 1523/2940] drm/amd/display: Add dmub offload functions. + +Change-Id: Ib706375b59dad877467578157ca0f9e4393d5dcd +Signed-off-by: Yongqiang Sun <yongqiang.sun@amd.com> +Reviewed-by: Tony Cheng <Tony.Cheng@amd.com> +Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com> +--- + drivers/gpu/drm/amd/display/dc/core/dc.c | 15 ++- + drivers/gpu/drm/amd/display/dc/dc.h | 14 +++ + drivers/gpu/drm/amd/display/dc/dc_helper.c | 79 +++++++++++++ + drivers/gpu/drm/amd/display/dc/dc_types.h | 9 ++ + drivers/gpu/drm/amd/display/dc/dmub_cmd.h | 110 ++++++++++++++++++ + drivers/gpu/drm/amd/display/dc/dmub_dc.h | 53 +++++++++ + .../gpu/drm/amd/display/dc/inc/reg_helper.h | 27 +++++ + .../display/dmub_fw/src/common/dmub_common.h | 55 +++++++++ + 8 files changed, 360 insertions(+), 2 deletions(-) + create mode 100644 drivers/gpu/drm/amd/display/dc/dmub_cmd.h + create mode 100644 drivers/gpu/drm/amd/display/dc/dmub_dc.h + create mode 100644 drivers/gpu/drm/amd/display/dmub_fw/src/common/dmub_common.h + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index d400b563ab8c..a0b7aa588be9 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -31,6 +31,8 @@ + #include "hw_sequencer.h" + #include "dce/dce_hwseq.h" + ++#include "reg_helper.h" ++ + #include "resource.h" + + #include "clock_source.h" +@@ -57,8 +59,12 @@ + + #include "dce/dce_i2c.h" + ++#define CTX \ ++ dc->ctx ++ + #define DC_LOGGER \ +- dc->ctx->logger ++ CTX->logger ++ + + const static char DC_BUILD_ID[] = "production-build"; + +@@ -668,6 +674,7 @@ static bool construct(struct dc *dc, + dc_ctx->asic_id = init_params->asic_id; + dc_ctx->dc_sink_id_count = 0; + dc_ctx->dc_stream_id_count = 0; ++ + dc->ctx = dc_ctx; + + dc->current_state = dc_create_state(); +@@ -833,6 +840,11 @@ struct dc *dc_create(const struct dc_init_data *init_params) + void dc_init_callbacks(struct dc *dc, + const struct dc_callback_init *init_params) + { ++ ++#ifdef CONFIG_DRM_AMD_DC_DMUB ++ dc->ctx->dmub_if = init_params->dmub_if; ++ dc->ctx->reg_helper_offload = init_params->dmub_offload; ++#endif + } + + void dc_destroy(struct dc **dc) +@@ -1766,7 +1778,6 @@ static void commit_planes_for_stream(struct dc *dc, + dc->hwss.update_plane_addr(dc, pipe_ctx); + } + } +- + dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false); + } + } +diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h +index c1f253ce68f1..6845960fb098 100644 +--- a/drivers/gpu/drm/amd/display/dc/dc.h ++++ b/drivers/gpu/drm/amd/display/dc/dc.h +@@ -29,6 +29,9 @@ + #include "dc_types.h" + #include "grph_object_defs.h" + #include "logger_types.h" ++#ifdef CONFIG_DRM_AMD_DC_DMUB ++#include "dmub_dc.h" ++#endif + #include "gpio_types.h" + #include "link_service_types.h" + #include "grph_object_ctrl_defs.h" +@@ -349,12 +352,23 @@ struct dc_init_data { + struct dc_bios *vbios_override; + enum dce_environment dce_environment; + ++#ifdef CONFIG_DRM_AMD_DC_DMUB ++ struct dmub_offload_funcs *dmub_if; ++ struct dc_reg_helper_state *dmub_offload; ++#endif + struct dc_config flags; + uint32_t log_mask; + }; + + struct dc_callback_init { ++ ++#ifdef CONFIG_DRM_AMD_DC_DMUB ++ struct dmub_offload_funcs *dmub_if; ++ struct dc_reg_helper_state *dmub_offload; ++#endif ++ + uint8_t reserved; ++ + }; + + struct dc *dc_create(const struct dc_init_data *init_params); +diff --git a/drivers/gpu/drm/amd/display/dc/dc_helper.c b/drivers/gpu/drm/amd/display/dc/dc_helper.c +index 597d38393379..5ba53947ad17 100644 +--- a/drivers/gpu/drm/amd/display/dc/dc_helper.c ++++ b/drivers/gpu/drm/amd/display/dc/dc_helper.c +@@ -29,6 +29,25 @@ + #include "dm_services.h" + #include <stdarg.h> + ++#ifdef CONFIG_DRM_AMD_DC_DMUB ++#include "dmub_dc.h" ++ ++static inline void submit_dmub_read_modify_write( ++ struct dc_reg_helper_state *offload, ++ const struct dc_context *ctx) ++{ ++ struct dmub_rb_cmd_read_modify_write *cmd_buf = &offload->cmd_data.read_modify_write; ++ struct dmub_offload_funcs *dmub_if = ctx->dmub_if; ++ ++ cmd_buf->header.type = DMUB_CMD__REG_SEQ_READ_MODIFY_WRITE; ++ cmd_buf->header.payload_bytes = sizeof(struct read_modify_write_sequence) * offload->reg_seq_count; ++ ++ dmub_if->queue_dmub_cmd(&dmub_if->dmub_cmd, &cmd_buf->header); ++ ++ offload->reg_seq_count = 0; ++} ++#endif ++ + struct dc_reg_value_masks { + uint32_t value; + uint32_t mask; +@@ -78,6 +97,28 @@ uint32_t generic_reg_update_ex(const struct dc_context *ctx, + } + va_end(ap); + ++#ifdef CONFIG_DRM_AMD_DC_DMUB ++ if (ctx->reg_helper_offload && ctx->reg_helper_offload->gather_in_progress) { ++ ++ struct dc_reg_helper_state *offload = ctx->reg_helper_offload; ++ struct dmub_rb_cmd_read_modify_write *cmd_buf = &offload->cmd_data.read_modify_write; ++ struct read_modify_write_sequence *seq; ++ ++ /* flush command if buffer is full */ ++ if (offload->reg_seq_count == DMUB_READ_MODIFY_WRITE_SEQ__MAX) ++ submit_dmub_read_modify_write(offload, ctx); ++ ++ /* pack commands */ ++ seq = &cmd_buf->seq[offload->reg_seq_count]; ++ ++ seq->addr = addr; ++ seq->modify_mask = field_value_mask.mask; ++ seq->modify_value = field_value_mask.value; ++ offload->reg_seq_count++; ++ ++ return reg_val; /* todo: return void so we can decouple code running in driver from register states */ ++ } ++#endif + + /* mmio write directly */ + reg_val = (reg_val & ~field_value_mask.mask) | field_value_mask.value; +@@ -329,3 +370,41 @@ uint32_t generic_indirect_reg_update_ex(const struct dc_context *ctx, + + return reg_val; + } ++ ++#ifdef CONFIG_DRM_AMD_DC_DMUB ++void reg_sequence_start_gather(const struct dc_context *ctx) ++{ ++ /* if reg sequence is supported and enabled, set flag to ++ * indicate we want to have REG_SET, REG_UPDATE macro build ++ * reg sequence command buffer rather than MMIO directly. ++ */ ++ ++ if (ctx->reg_helper_offload) { ++ struct dc_reg_helper_state *offload = ctx->reg_helper_offload; ++ ++ /* caller sequence mismatch. need to debug caller. offload will not work!!! */ ++ ASSERT(!offload->gather_in_progress); ++ ++ offload->gather_in_progress = true; ++ } ++} ++ ++void reg_sequence_start_execute(const struct dc_context *ctx) ++{ ++ struct dc_reg_helper_state *offload = ctx->reg_helper_offload; ++ ++ if (offload && offload->gather_in_progress) { ++ ++ submit_dmub_read_modify_write(offload, ctx); ++ ++ offload->gather_in_progress = false; ++ ++ ctx->dmub_if->execute_dmub_queue(&ctx->dmub_if->dmub_cmd); ++ } ++} ++ ++void reg_sequence_wait_done(const struct dc_context *ctx) ++{ ++ /* callback to DM to poll for last submission done*/ ++} ++#endif +diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h +index da2009a108cf..7d271a6f5b7b 100644 +--- a/drivers/gpu/drm/amd/display/dc/dc_types.h ++++ b/drivers/gpu/drm/amd/display/dc/dc_types.h +@@ -33,6 +33,10 @@ + #include "dal_types.h" + #include "grph_object_defs.h" + ++#ifdef CONFIG_DRM_AMD_DC_DMUB ++#include "dmub_dc.h" ++#endif ++ + /* forward declarations */ + struct dc_plane_state; + struct dc_stream_state; +@@ -100,6 +104,11 @@ struct dc_context { + uint32_t dc_sink_id_count; + uint32_t dc_stream_id_count; + uint64_t fbc_gpu_addr; ++ ++#ifdef CONFIG_DRM_AMD_DC_DMUB ++ struct dc_reg_helper_state *reg_helper_offload; ++ struct dmub_offload_funcs *dmub_if; ++#endif + }; + + +diff --git a/drivers/gpu/drm/amd/display/dc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dc/dmub_cmd.h +new file mode 100644 +index 000000000000..399ae71457f2 +--- /dev/null ++++ b/drivers/gpu/drm/amd/display/dc/dmub_cmd.h +@@ -0,0 +1,110 @@ ++/* ++ * Copyright 2018 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_CMD__H ++#define DMUB_CMD__H ++ ++#include "os_types.h" ++/* ++ * DMUB command definition ++ */ ++ ++ ++#define DMUB_RB_MAX_ENTRY 16 ++#define DMUB_RB_CMD_SIZE 64 ++#define DMUB_RB_SIZE (DMUB_RB_CMD_SIZE * DMUB_RB_MAX_ENTRY) ++ ++#ifdef DMUB_EMULATION ++ ++#else ++ ++#endif ++ ++ ++enum dmub_cmd_type { ++ DMUB_CMD__NULL, ++ DMUB_CMD__REG_SEQ_READ_MODIFY_WRITE, ++ DMUB_CMD__REG_SEQ_BURST_WRITE, ++}; ++ ++ ++struct dmub_cmd_header { ++ enum dmub_cmd_type type : 11; ++ unsigned int payload_bytes : 5; /* up to 60 bytes */ ++ unsigned int reserved : 16; ++}; ++ ++struct read_modify_write_sequence { ++ uint32_t addr; ++ uint32_t modify_mask; ++ uint32_t modify_value; ++}; ++ ++ ++/* read modify write ++ * ++ * 60 payload bytes can hold up to 5 sets of read modify writes, ++ * each take 3 dwords. ++ * ++ * number of sequences = header.payload_bytes / sizeof(struct read_modify_write_sequence) ++ * ++ * modify_mask = 0xffff'ffff means all fields are going to be updated. in this case ++ * command parser will skip the read and we can use modify_mask = 0xffff'ffff as reg write ++ */ ++#define DMUB_READ_MODIFY_WRITE_SEQ__MAX 5 ++struct dmub_rb_cmd_read_modify_write { ++ struct dmub_cmd_header header; // type = DMUB_CMD__REG_SEQ_READ_MODIFY_WRITE ++ struct read_modify_write_sequence seq[DMUB_READ_MODIFY_WRITE_SEQ__MAX]; ++}; ++ ++ ++/* burst write ++ * ++ * support use case such as writing out LUTs. ++ * ++ * 60 payload bytes can hold up to 14 values to write to given address ++ * ++ * number of payload = header.payload_bytes / sizeof(struct read_modify_write_sequence) ++ */ ++struct dmub_rb_cmd_burst_write { ++ struct dmub_cmd_header header; // type = DMUB_CMD__REG_SEQ_BURST_WRITE ++ uint32_t addr; ++ uint32_t write_values[14]; ++}; ++ ++#define HEAD_BYTES sizeof(struct dmub_cmd_header) / 8 ++ ++struct dmub_rb_cmd_common { ++ struct dmub_cmd_header header; ++ uint8_t cmd_buffer[DMUB_RB_CMD_SIZE - HEAD_BYTES]; ++}; ++ ++union dmub_rb_cmd { ++ struct dmub_rb_cmd_read_modify_write read_modify_write; ++ struct dmub_rb_cmd_burst_write burst_write; ++ struct dmub_rb_cmd_common cmd_common; ++}; ++ ++#endif /* DMUB_CMD__H */ +diff --git a/drivers/gpu/drm/amd/display/dc/dmub_dc.h b/drivers/gpu/drm/amd/display/dc/dmub_dc.h +new file mode 100644 +index 000000000000..a7b8c278ef33 +--- /dev/null ++++ b/drivers/gpu/drm/amd/display/dc/dmub_dc.h +@@ -0,0 +1,53 @@ ++/* ++ * Copyright 2018 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_DC__H ++#define DMUB_DC__H ++ ++#include "dmub_cmd.h" ++ ++ ++struct dmub_dc_cmd { ++ const void *dm; ++}; ++ ++ ++struct dmub_offload_funcs { ++ struct dmub_dc_cmd dmub_cmd; ++ ++ void (*queue_dmub_cmd)(struct dmub_dc_cmd *dmub_cmd, struct dmub_cmd_header *cmd); ++ void (*execute_dmub_queue)(struct dmub_dc_cmd *dmub_cmd); ++ void (*wait_queue_idle)(struct dmub_dc_cmd *dmub_cmd); ++}; ++ ++struct dc_reg_helper_state { ++ bool gather_in_progress; ++ ++ union dmub_rb_cmd cmd_data; ++ unsigned int reg_seq_count; ++}; ++ ++ ++#endif /* DMUB_DC__H */ +diff --git a/drivers/gpu/drm/amd/display/dc/inc/reg_helper.h b/drivers/gpu/drm/amd/display/dc/inc/reg_helper.h +index cf5a84b9e27c..6b808cb1895c 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/reg_helper.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/reg_helper.h +@@ -491,4 +491,31 @@ uint32_t generic_indirect_reg_update_ex(const struct dc_context *ctx, + uint8_t shift1, uint32_t mask1, uint32_t field_value1, + ...); + ++ ++#ifdef CONFIG_DRM_AMD_DC_DMUB ++/* register offload macros ++ * ++ * instead of MMIO to register directly, in some cases we want ++ * to gather register sequence and execute the register sequence ++ * from another thread so we optimize time required for lengthy ops ++ */ ++ ++/* start gathering register sequence */ ++#define REG_SEQ_START() \ ++ reg_sequence_start_gather(CTX) ++ ++/* start execution of register sequence gathered since REG_SEQ_START */ ++#define REG_SEQ_SUBMIT() \ ++ reg_sequence_start_execute(CTX) ++ ++/* wait for the last REG_SEQ_SUBMIT to finish */ ++#define REG_SEQ_WAIT_DONE() \ ++ reg_sequence_wait_done(CTX) ++ ++void reg_sequence_start_gather(const struct dc_context *ctx); ++void reg_sequence_start_execute(const struct dc_context *ctx); ++void reg_sequence_wait_done(const struct dc_context *ctx); ++ ++#endif ++ + #endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_REG_HELPER_H_ */ +diff --git a/drivers/gpu/drm/amd/display/dmub_fw/src/common/dmub_common.h b/drivers/gpu/drm/amd/display/dmub_fw/src/common/dmub_common.h +new file mode 100644 +index 000000000000..5804de88346c +--- /dev/null ++++ b/drivers/gpu/drm/amd/display/dmub_fw/src/common/dmub_common.h +@@ -0,0 +1,55 @@ ++/* ++ * Copyright 2018 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_COMMON_H_ ++#define DMUB_COMMON_H_ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#ifdef CONFIG_DRM_AMD_DC_DMUB ++struct dmub_dc_cmd; ++ ++struct dmub_inst { ++ void *ctx; ++ void (*reg_write)(struct dmub_inst *inst, uint32_t offset, uint32_t value); ++ uint32_t (*reg_read)(struct dmub_inst *inst, uint32_t offset); ++ void (*dequeque)(); ++}; ++ ++extern const struct dc_context *g_ctx; ++ ++#define mmRegWrite(offset, value) ++#define mmRegRead(offset) ++#endif ++ ++void process_ring_buffer_command(struct dmub_dc_cmd *dc_cmd); ++void ring_buffer_command_dequeue(struct dmub_dc_cmd *dmub_cmd, union dmub_rb_cmd *cmd); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* DMUB_COMMON_H_ */ +-- +2.17.1 + |