aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4173-drm-amd-display-Add-renoir-hw_seq.patch
diff options
context:
space:
mode:
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.patch449
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
+