/* * Copyright 2017 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. * */ #include "pp_debug.h" #include "smumgr.h" #include "smu_ucode_xfer_vi.h" #include "vegam_smumgr.h" #include "smu/smu_7_1_3_d.h" #include "smu/smu_7_1_3_sh_mask.h" #include "gmc/gmc_8_1_d.h" #include "gmc/gmc_8_1_sh_mask.h" #include "oss/oss_3_0_d.h" #include "gca/gfx_8_0_d.h" #include "bif/bif_5_0_d.h" #include "bif/bif_5_0_sh_mask.h" #include "ppatomctrl.h" #include "cgs_common.h" #include "smu7_ppsmc.h" #include "smu7_dyn_defaults.h" #include "smu7_hwmgr.h" #include "hardwaremanager.h" #include "ppatomctrl.h" #include "atombios.h" #include "pppcielanes.h" #include "dce/dce_11_2_d.h" #include "dce/dce_11_2_sh_mask.h" #define PPVEGAM_TARGETACTIVITY_DFLT 50 #define VOLTAGE_VID_OFFSET_SCALE1 625 #define VOLTAGE_VID_OFFSET_SCALE2 100 #define POWERTUNE_DEFAULT_SET_MAX 1 #define VDDC_VDDCI_DELTA 200 #define MC_CG_ARB_FREQ_F1 0x0b #define STRAP_ASIC_RO_LSB 2168 #define STRAP_ASIC_RO_MSB 2175 #define PPSMC_MSG_ApplyAvfsCksOffVoltage ((uint16_t) 0x415) #define PPSMC_MSG_EnableModeSwitchRLCNotification ((uint16_t) 0x305) static const struct vegam_pt_defaults vegam_power_tune_data_set_array[POWERTUNE_DEFAULT_SET_MAX] = { /* sviLoadLIneEn, SviLoadLineVddC, TDC_VDDC_ThrottleReleaseLimitPerc, TDC_MAWt, * TdcWaterfallCtl, DTEAmbientTempBase, DisplayCac, BAPM_TEMP_GRADIENT */ { 1, 0xF, 0xFD, 0x19, 5, 45, 0, 0xB0000, { 0x79, 0x253, 0x25D, 0xAE, 0x72, 0x80, 0x83, 0x86, 0x6F, 0xC8, 0xC9, 0xC9, 0x2F, 0x4D, 0x61}, { 0x17C, 0x172, 0x180, 0x1BC, 0x1B3, 0x1BD, 0x206, 0x200, 0x203, 0x25D, 0x25A, 0x255, 0x2C3, 0x2C5, 0x2B4 } }, }; static const sclkFcwRange_t Range_Table[NUM_SCLK_RANGE] = { {VCO_2_4, POSTDIV_DIV_BY_16, 75, 160, 112}, {VCO_3_6, POSTDIV_DIV_BY_16, 112, 224, 160}, {VCO_2_4, POSTDIV_DIV_BY_8, 75, 160, 112}, {VCO_3_6, POSTDIV_DIV_BY_8, 112, 224, 160}, {VCO_2_4, POSTDIV_DIV_BY_4, 75, 160, 112}, {VCO_3_6, POSTDIV_DIV_BY_4, 112, 216, 160}, {VCO_2_4, POSTDIV_DIV_BY_2, 75, 160, 108}, {VCO_3_6, POSTDIV_DIV_BY_2, 112, 216, 160} }; static int vegam_smu_init(struct pp_hwmgr *hwmgr) { struct vegam_smumgr *smu_data; smu_data = kzalloc(sizeof(struct vegam_smumgr), GFP_KERNEL); if (smu_data == NULL) return -ENOMEM; hwmgr->smu_backend = smu_data; if (smu7_init(hwmgr)) { kfree(smu_data); return -EINVAL; } return 0; } static int vegam_start_smu_in_protection_mode(struct pp_hwmgr *hwmgr) { int result = 0; /* Wait for smc boot up */ /* PHM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(smumgr, SMC_IND, RCU_UC_EVENTS, boot_seq_done, 0) */ /* Assert reset */ PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SMC_SYSCON_RESET_CNTL, rst_reg, 1); result = smu7_upload_smu_firmware_image(hwmgr); if (result != 0) return result; /* Clear status */ cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixSMU_STATUS, 0); PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0); /* De-assert reset */ PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SMC_SYSCON_RESET_CNTL, rst_reg, 0); PHM_WAIT_VFPF_INDIRECT_FIELD(hwmgr, SMC_IND, RCU_UC_EVENTS, INTERRUPTS_ENABLED, 1); /* Call Test SMU message with 0x20000 offset to trigger SMU start */ smu7_send_msg_to_smc_offset(hwmgr); /* Wait done bit to be set */ /* Check pass/failed indicator */ PHM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(hwmgr, SMC_IND, SMU_STATUS, SMU_DONE, 0); if (1 != PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SMU_STATUS, SMU_PASS)) PP_ASSERT_WITH_CODE(false, "SMU Firmware start failed!", return -1); cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixFIRMWARE_FLAGS, 0); PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SMC_SYSCON_RESET_CNTL, rst_reg, 1); PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SMC_SYSCON_RESET_CNTL, rst_reg, 0); /* Wait for firmware to initialize */ PHM_WAIT_VFPF_INDIRECT_FIELD(hwmgr, SMC_IND, FIRMWARE_FLAGS, INTERRUPTS_ENABLED, 1); return result; } static int vegam_start_smu_in_non_protection_mode(struct pp_hwmgr *hwmgr) { int result = 0; /* wait for smc boot up */ PHM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(hwmgr, SMC_IND, RCU_UC_EVENTS, boot_seq_done, 0); /* Clear firmware interrupt enable flag */ /* PHM_WRITE_VFPF_INDIRECT_FIELD(pSmuMgr, SMC_IND, SMC_SYSCON_MISC_CNTL, pre_fetcher_en, 1); */ cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixFIRMWARE_FLAGS, 0); PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SMC_SYSCON_RESET_CNTL, rst_reg, 1); result = smu7_upload_smu_firmware_image(hwmgr); if (result != 0) return result; /* Set smc instruct start point at 0x0 */ smu7_program_jump_on_start(hwmgr); PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0); PHM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SMC_SYSCON_RESET_CNTL, rst_reg, 0); /* Wait for firmware to initialize */ PHM_WAIT_VFPF_INDIRECT_FIELD(hwmgr, SMC_IND, FIRMWARE_FLAGS, INTERRUPTS_ENABLED, 1); return result; } static int vegam_start_smu(struct pp_hwmgr *hwmgr) { int result = 0; struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend); /* Only start SMC if SMC RAM is not running */ if (!smu7_is_smc_ram_running(hwmgr) && hwmgr->not_vf) { smu_data->protected_mode = (uint8_t)(PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SMU_FIRMWARE, SMU_MODE)); smu_data->smu7_data.security_hard_key = (uint8_t)(PHM_READ_VFPF_INDIRECT_FIELD( hwmgr->device, CGS_IND_REG__SMC, SMU_FIRMWARE, SMU_SEL)); /* Check if SMU is running in protected mode */ if (smu_data->protected_mode == 0) result = vegam_start_smu_in_non_protection_mode(hwmgr); else result = vegam_start_smu_in_protection_mode(hwmgr); if (result != 0) PP_ASSERT_WITH_CODE(0, "Failed to load SMU ucode.", return result);
From bcb5aad1a584510d05a5fcbc22b8a3217e814503 Mon Sep 17 00:00:00 2001
From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Date: Mon, 1 Apr 2019 09:43:34 -0400
Subject: [PATCH 1783/2940] drm/amd/display: Add basic downscale and upscale
valdiation
[Why]
Planes have downscaling limits and upscaling limits per format and DM
is expected to validate these using DC caps. We should fail atomic
check validation if we aren't capable of doing the scaling.
[How]
We don't currently create store which DC plane maps to which DRM plane
so we can't easily check the caps directly. For now add basic
constraints that cover the absolute min and max downscale / upscale
limits for most RGB and YUV formats across ASICs.
Leave a TODO indicating that these should really be done with DC caps.
We'll probably need to subclass DRM planes again in order to correctly
identify which DC plane maps to it.
Change-Id: I18524d0e5d8a96ae3ae0e5d0eb3906092201a125
Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Reviewed-by: Harry Wentland <Harry.Wentland@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Acked-by: Bhawanpreet Lakha <Bhawanpreet Lakha@amd.com>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index ba7bb3338abf..b86e9aeca3c8 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2477,6 +2477,8 @@ static const struct drm_encoder_funcs amdgpu_dm_encoder_funcs = {
static int fill_dc_scaling_info(const struct drm_plane_state *state,
struct dc_scaling_info *scaling_info)
{
+ int scale_w, scale_h;
+
memset(scaling_info, 0, sizeof(*scaling_info));
/* Source is fixed 16.16 but we ignore mantissa for now... */
@@ -2507,6 +2509,19 @@ static int fill_dc_scaling_info(const struct drm_plane_state *state,
/* DRM doesn't specify clipping on destination output. */
scaling_info->clip_rect = scaling_info->dst_rect;
+ /* TODO: Validate scaling per-format with DC plane caps */
+ scale_w = scaling_info->dst_rect.width * 1000 /
+ scaling_info->src_rect.width;
+
+ if (scale_w < 250 || scale_w > 16000)
+ return -EINVAL;
+
+ scale_h = scaling_info->dst_rect.height * 1000 /
+ scaling_info->src_rect.height;
+
+ if (scale_h < 250 || scale_h > 16000)
+ return -EINVAL;
+
/*
* The "scaling_quality" can be ignored for now, quality = 0 has DC
* assume reasonable defaults based on the format.
--
2.17.1