diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4173-drm-amd-display-Add-renoir-hw_seq.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4173-drm-amd-display-Add-renoir-hw_seq.patch | 449 |
1 files changed, 449 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4173-drm-amd-display-Add-renoir-hw_seq.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4173-drm-amd-display-Add-renoir-hw_seq.patch new file mode 100644 index 00000000..8f133525 --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4173-drm-amd-display-Add-renoir-hw_seq.patch @@ -0,0 +1,449 @@ +From 8e48ee9e07fb0aa2b88f1e157660f182afafd7cc Mon Sep 17 00:00:00 2001 +From: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com> +Date: Wed, 2 Oct 2019 11:54:56 -0400 +Subject: [PATCH 4173/4736] drm/amd/display: Add renoir hw_seq + +This change adds renoir hw_seq, needed to do renoir +specific hw programing + +Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com> +Reviewed-by: Roman Li <Roman.Li@amd.com> +--- + .../gpu/drm/amd/display/dc/dce/dce_hwseq.h | 1 + + .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 4 + + drivers/gpu/drm/amd/display/dc/dcn21/Makefile | 2 +- + .../drm/amd/display/dc/dcn21/dcn21_hwseq.c | 122 ++++++++++++++++++ + .../drm/amd/display/dc/dcn21/dcn21_hwseq.h | 33 +++++ + .../drm/amd/display/dc/dcn21/dcn21_resource.c | 118 +++++++++++++---- + .../gpu/drm/amd/display/dc/inc/hw_sequencer.h | 3 + + 7 files changed, 255 insertions(+), 28 deletions(-) + create mode 100644 drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c + create mode 100644 drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.h + +diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h +index ac04d77058f0..32d145a0d6fc 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h ++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h +@@ -679,6 +679,7 @@ struct dce_hwseq_registers { + HWS_SF(, DOMAIN17_PG_STATUS, DOMAIN17_PGFSM_PWR_STATUS, mask_sh), \ + HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN18_PGFSM_PWR_STATUS, mask_sh), \ + HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \ ++ HWSEQ_LVTMA_MASK_SH_LIST(mask_sh), \ + HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \ + HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh) + #endif +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +index 3b55716bf63b..7c02f646feed 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +@@ -669,6 +669,10 @@ static void dcn10_bios_golden_init(struct dc *dc) + int i; + bool allow_self_fresh_force_enable = true; + ++#if defined(CONFIG_DRM_AMD_DC_DCN2_1) ++ if (dc->hwss.s0i3_golden_init_wa && dc->hwss.s0i3_golden_init_wa(dc)) ++ return; ++#endif + if (dc->res_pool->hubbub->funcs->is_allow_self_refresh_enabled) + allow_self_fresh_force_enable = + dc->res_pool->hubbub->funcs->is_allow_self_refresh_enabled(dc->res_pool->hubbub); +diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/Makefile b/drivers/gpu/drm/amd/display/dc/dcn21/Makefile +index b2b39090fb57..5b8f42ae2334 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn21/Makefile ++++ b/drivers/gpu/drm/amd/display/dc/dcn21/Makefile +@@ -1,7 +1,7 @@ + # + # Makefile for DCN21. + +-DCN21 = dcn21_hubp.o dcn21_hubbub.o dcn21_resource.o ++DCN21 = dcn21_hubp.o dcn21_hubbub.o dcn21_resource.o dcn21_hwseq.o + + CFLAGS_dcn21_resource.o := -mhard-float -msse -mpreferred-stack-boundary=4 + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c +new file mode 100644 +index 000000000000..b25215cadf85 +--- /dev/null ++++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c +@@ -0,0 +1,122 @@ ++/* ++ * Copyright 2016 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 ++ * ++ */ ++ ++#include "dm_services.h" ++#include "dm_helpers.h" ++#include "core_types.h" ++#include "resource.h" ++#include "dce/dce_hwseq.h" ++#include "dcn20/dcn20_hwseq.h" ++#include "vmid.h" ++#include "reg_helper.h" ++#include "hw/clk_mgr.h" ++ ++ ++#define DC_LOGGER_INIT(logger) ++ ++#define CTX \ ++ hws->ctx ++#define REG(reg)\ ++ hws->regs->reg ++ ++#undef FN ++#define FN(reg_name, field_name) \ ++ hws->shifts->field_name, hws->masks->field_name ++ ++/* Temporary read settings, future will get values from kmd directly */ ++static void mmhub_update_page_table_config(struct dcn_hubbub_phys_addr_config *config, ++ struct dce_hwseq *hws) ++{ ++ uint32_t page_table_base_hi; ++ uint32_t page_table_base_lo; ++ ++ REG_GET(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32, ++ PAGE_DIRECTORY_ENTRY_HI32, &page_table_base_hi); ++ REG_GET(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32, ++ PAGE_DIRECTORY_ENTRY_LO32, &page_table_base_lo); ++ ++ config->gart_config.page_table_base_addr = ((uint64_t)page_table_base_hi << 32) | page_table_base_lo; ++ ++} ++ ++static int dcn21_init_sys_ctx(struct dce_hwseq *hws, struct dc *dc, struct dc_phy_addr_space_config *pa_config) ++{ ++ struct dcn_hubbub_phys_addr_config config; ++ ++ config.system_aperture.fb_top = pa_config->system_aperture.fb_top; ++ config.system_aperture.fb_offset = pa_config->system_aperture.fb_offset; ++ config.system_aperture.fb_base = pa_config->system_aperture.fb_base; ++ config.system_aperture.agp_top = pa_config->system_aperture.agp_top; ++ config.system_aperture.agp_bot = pa_config->system_aperture.agp_bot; ++ config.system_aperture.agp_base = pa_config->system_aperture.agp_base; ++ config.gart_config.page_table_start_addr = pa_config->gart_config.page_table_start_addr; ++ config.gart_config.page_table_end_addr = pa_config->gart_config.page_table_end_addr; ++ config.gart_config.page_table_base_addr = pa_config->gart_config.page_table_base_addr; ++ ++ mmhub_update_page_table_config(&config, hws); ++ ++ return dc->res_pool->hubbub->funcs->init_dchub_sys_ctx(dc->res_pool->hubbub, &config); ++} ++ ++// work around for Renoir s0i3, if register is programmed, bypass golden init. ++ ++static bool dcn21_s0i3_golden_init_wa(struct dc *dc) ++{ ++ struct dce_hwseq *hws = dc->hwseq; ++ uint32_t value = 0; ++ ++ value = REG_READ(MICROSECOND_TIME_BASE_DIV); ++ ++ return value != 0x00120464; ++} ++ ++void dcn21_exit_optimized_pwr_state( ++ const struct dc *dc, ++ struct dc_state *context) ++{ ++ dc->clk_mgr->funcs->update_clocks( ++ dc->clk_mgr, ++ context, ++ false); ++} ++ ++void dcn21_optimize_pwr_state( ++ const struct dc *dc, ++ struct dc_state *context) ++{ ++ dc->clk_mgr->funcs->update_clocks( ++ dc->clk_mgr, ++ context, ++ true); ++} ++ ++void dcn21_hw_sequencer_construct(struct dc *dc) ++{ ++ dcn20_hw_sequencer_construct(dc); ++ dc->hwss.init_sys_ctx = dcn21_init_sys_ctx; ++ dc->hwss.s0i3_golden_init_wa = dcn21_s0i3_golden_init_wa; ++ dc->hwss.optimize_pwr_state = dcn21_optimize_pwr_state; ++ dc->hwss.exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state; ++} +diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.h +new file mode 100644 +index 000000000000..be67b62e6fb1 +--- /dev/null ++++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.h +@@ -0,0 +1,33 @@ ++/* ++* Copyright 2016 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 __DC_HWSS_DCN21_H__ ++#define __DC_HWSS_DCN21_H__ ++ ++struct dc; ++ ++void dcn21_hw_sequencer_construct(struct dc *dc); ++ ++#endif /* __DC_HWSS_DCN21_H__ */ +diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +index 86005cb05c2a..1bac7eca5963 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +@@ -23,8 +23,6 @@ + * + */ + +-#include <linux/slab.h> +- + #include "dm_services.h" + #include "dc.h" + +@@ -42,7 +40,7 @@ + #include "irq/dcn21/irq_service_dcn21.h" + #include "dcn20/dcn20_dpp.h" + #include "dcn20/dcn20_optc.h" +-#include "dcn20/dcn20_hwseq.h" ++#include "dcn21/dcn21_hwseq.h" + #include "dce110/dce110_hw_sequencer.h" + #include "dcn20/dcn20_opp.h" + #include "dcn20/dcn20_dsc.h" +@@ -350,6 +348,30 @@ static const struct bios_registers bios_regs = { + NBIO_SR(BIOS_SCRATCH_6) + }; + ++static const struct dce_dmcu_registers dmcu_regs = { ++ DMCU_DCN10_REG_LIST() ++}; ++ ++static const struct dce_dmcu_shift dmcu_shift = { ++ DMCU_MASK_SH_LIST_DCN10(__SHIFT) ++}; ++ ++static const struct dce_dmcu_mask dmcu_mask = { ++ DMCU_MASK_SH_LIST_DCN10(_MASK) ++}; ++ ++static const struct dce_abm_registers abm_regs = { ++ ABM_DCN20_REG_LIST() ++}; ++ ++static const struct dce_abm_shift abm_shift = { ++ ABM_MASK_SH_LIST_DCN20(__SHIFT) ++}; ++ ++static const struct dce_abm_mask abm_mask = { ++ ABM_MASK_SH_LIST_DCN20(_MASK) ++}; ++ + #ifdef CONFIG_DRM_AMD_DC_DMUB + static const struct dcn21_dmcub_registers dmcub_regs = { + DMCUB_REG_LIST_DCN() +@@ -1491,6 +1513,19 @@ static struct link_encoder *dcn21_link_encoder_create( + return &enc21->enc10.base; + } + ++#define CTX ctx ++ ++#define REG(reg_name) \ ++ (DCN_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name) ++ ++static uint32_t read_pipe_fuses(struct dc_context *ctx) ++{ ++ uint32_t value = REG_READ(CC_DC_PIPE_DIS); ++ /* RV1 support max 4 pipes */ ++ value = value & 0xf; ++ return value; ++} ++ + static struct resource_funcs dcn21_res_pool_funcs = { + .destroy = dcn21_destroy_resource_pool, + .link_enc_create = dcn20_link_encoder_create, +@@ -1510,9 +1545,10 @@ static bool construct( + struct dc *dc, + struct dcn21_resource_pool *pool) + { +- int i; ++ int i, j; + struct dc_context *ctx = dc->ctx; + struct irq_service_init_data init_data; ++ uint32_t pipe_fuses = read_pipe_fuses(ctx); + + ctx->dc_bios->regs = &bios_regs; + +@@ -1530,7 +1566,9 @@ static bool construct( + *************************************************/ + pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE; + +- pool->base.pipe_count = 4; ++ /* max pipe num for ASIC before check pipe fuses */ ++ pool->base.pipe_count = pool->base.res_cap->num_timing_generator; ++ + dc->caps.max_downscale_ratio = 200; + dc->caps.i2c_speed_in_khz = 100; + dc->caps.max_cursor_size = 256; +@@ -1590,6 +1628,26 @@ static bool construct( + goto create_fail; + } + ++ pool->base.dmcu = dcn20_dmcu_create(ctx, ++ &dmcu_regs, ++ &dmcu_shift, ++ &dmcu_mask); ++ if (pool->base.dmcu == NULL) { ++ dm_error("DC: failed to create dmcu!\n"); ++ BREAK_TO_DEBUGGER(); ++ goto create_fail; ++ } ++ ++ pool->base.abm = dce_abm_create(ctx, ++ &abm_regs, ++ &abm_shift, ++ &abm_mask); ++ if (pool->base.abm == NULL) { ++ dm_error("DC: failed to create abm!\n"); ++ BREAK_TO_DEBUGGER(); ++ goto create_fail; ++ } ++ + #ifdef CONFIG_DRM_AMD_DC_DMUB + pool->base.dmcub = dcn21_dmcub_create(ctx, + &dmcub_regs, +@@ -1611,8 +1669,15 @@ static bool construct( + if (!pool->base.irqs) + goto create_fail; + ++ j = 0; + /* mem input -> ipp -> dpp -> opp -> TG */ + for (i = 0; i < pool->base.pipe_count; i++) { ++ /* if pipe is disabled, skip instance of HW pipe, ++ * i.e, skip ASIC register instance ++ */ ++ if ((pipe_fuses & (1 << i)) != 0) ++ continue; ++ + pool->base.hubps[i] = dcn21_hubp_create(ctx, i); + if (pool->base.hubps[i] == NULL) { + BREAK_TO_DEBUGGER(); +@@ -1636,6 +1701,23 @@ static bool construct( + "DC: failed to create dpps!\n"); + goto create_fail; + } ++ ++ pool->base.opps[i] = dcn21_opp_create(ctx, i); ++ if (pool->base.opps[i] == NULL) { ++ BREAK_TO_DEBUGGER(); ++ dm_error( ++ "DC: failed to create output pixel processor!\n"); ++ goto create_fail; ++ } ++ ++ pool->base.timing_generators[i] = dcn21_timing_generator_create( ++ ctx, i); ++ if (pool->base.timing_generators[i] == NULL) { ++ BREAK_TO_DEBUGGER(); ++ dm_error("DC: failed to create tg!\n"); ++ goto create_fail; ++ } ++ j++; + } + + for (i = 0; i < pool->base.res_cap->num_ddc; i++) { +@@ -1656,27 +1738,9 @@ static bool construct( + pool->base.sw_i2cs[i] = NULL; + } + +- for (i = 0; i < pool->base.res_cap->num_opp; i++) { +- pool->base.opps[i] = dcn21_opp_create(ctx, i); +- if (pool->base.opps[i] == NULL) { +- BREAK_TO_DEBUGGER(); +- dm_error( +- "DC: failed to create output pixel processor!\n"); +- goto create_fail; +- } +- } +- +- for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) { +- pool->base.timing_generators[i] = dcn21_timing_generator_create( +- ctx, i); +- if (pool->base.timing_generators[i] == NULL) { +- BREAK_TO_DEBUGGER(); +- dm_error("DC: failed to create tg!\n"); +- goto create_fail; +- } +- } +- +- pool->base.timing_generator_count = i; ++ pool->base.timing_generator_count = j; ++ pool->base.pipe_count = j; ++ pool->base.mpcc_count = j; + + pool->base.mpc = dcn21_mpc_create(ctx); + if (pool->base.mpc == NULL) { +@@ -1719,7 +1783,7 @@ static bool construct( + &res_create_funcs : &res_create_maximus_funcs))) + goto create_fail; + +- dcn20_hw_sequencer_construct(dc); ++ dcn21_hw_sequencer_construct(dc); + + dc->caps.max_planes = pool->base.pipe_count; + +diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +index e775d7aa062f..d39c1e11def5 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +@@ -349,6 +349,9 @@ struct hw_sequencer_funcs { + enum dc_clock_type clock_type, + struct dc_clock_config *clock_cfg); + ++#if defined(CONFIG_DRM_AMD_DC_DCN2_1) ++ bool (*s0i3_golden_init_wa)(struct dc *dc); ++#endif + }; + + void color_space_to_black_color( +-- +2.17.1 + |