mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-02 15:43:35 -04:00
Merge tag 'amd-drm-next-5.16-2021-10-22' of https://gitlab.freedesktop.org/agd5f/linux into drm-next
amd-drm-next-5.16-2021-10-22: amdgpu: - PSP fix for resume - XGMI fixes - Interrupt fix in device tear down - Renoir USB-C DP alt mode fix for resume - DP 2.0 fixes - Yellow Carp display fixes - Misc display fixes - RAS fixes - IP Discovery enumeration fixes - VGH fixes - SR-IOV fixes - Revert ChromeOS workaround in display code - Cyan Skillfish fixes amdkfd: - Fix error handling in gpu memory allocation - Fix build warnings with some configs - SVM fixes Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20211022183112.4574-1-alexander.deucher@amd.com
This commit is contained in:
@@ -902,6 +902,7 @@ F: include/uapi/linux/psp-sev.h
|
||||
AMD DISPLAY CORE
|
||||
M: Harry Wentland <harry.wentland@amd.com>
|
||||
M: Leo Li <sunpeng.li@amd.com>
|
||||
M: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
|
||||
L: amd-gfx@lists.freedesktop.org
|
||||
S: Supported
|
||||
T: git https://gitlab.freedesktop.org/agd5f/linux.git
|
||||
|
||||
@@ -73,10 +73,8 @@ amdgpu-$(CONFIG_DRM_AMDGPU_SI)+= si.o gmc_v6_0.o gfx_v6_0.o si_ih.o si_dma.o dce
|
||||
|
||||
amdgpu-y += \
|
||||
vi.o mxgpu_vi.o nbio_v6_1.o soc15.o emu_soc.o mxgpu_ai.o nbio_v7_0.o vega10_reg_init.o \
|
||||
vega20_reg_init.o nbio_v7_4.o nbio_v2_3.o nv.o navi10_reg_init.o navi14_reg_init.o \
|
||||
arct_reg_init.o navi12_reg_init.o mxgpu_nv.o sienna_cichlid_reg_init.o vangogh_reg_init.o \
|
||||
nbio_v7_2.o dimgrey_cavefish_reg_init.o hdp_v4_0.o hdp_v5_0.o aldebaran_reg_init.o aldebaran.o \
|
||||
beige_goby_reg_init.o yellow_carp_reg_init.o cyan_skillfish_reg_init.o
|
||||
vega20_reg_init.o nbio_v7_4.o nbio_v2_3.o nv.o arct_reg_init.o mxgpu_nv.o \
|
||||
nbio_v7_2.o hdp_v4_0.o hdp_v5_0.o aldebaran_reg_init.o aldebaran.o
|
||||
|
||||
# add DF block
|
||||
amdgpu-y += \
|
||||
|
||||
@@ -307,6 +307,8 @@ static int aldebaran_mode2_restore_ip(struct amdgpu_device *adev)
|
||||
adev->ip_blocks[i].status.late_initialized = true;
|
||||
}
|
||||
|
||||
amdgpu_ras_set_error_query_ready(adev, true);
|
||||
|
||||
amdgpu_device_set_cg_state(adev, AMD_CG_STATE_GATE);
|
||||
amdgpu_device_set_pg_state(adev, AMD_PG_STATE_GATE);
|
||||
|
||||
|
||||
@@ -1503,7 +1503,7 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
|
||||
remove_kgd_mem_from_kfd_bo_list(*mem, avm->process_info);
|
||||
drm_vma_node_revoke(&gobj->vma_node, drm_priv);
|
||||
err_node_allow:
|
||||
amdgpu_bo_unref(&bo);
|
||||
drm_gem_object_put(gobj);
|
||||
/* Don't unreserve system mem limit twice */
|
||||
goto err_reserve_limit;
|
||||
err_bo_create:
|
||||
|
||||
@@ -2398,10 +2398,6 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
|
||||
if (!adev->gmc.xgmi.pending_reset)
|
||||
amdgpu_amdkfd_device_init(adev);
|
||||
|
||||
r = amdgpu_amdkfd_resume_iommu(adev);
|
||||
if (r)
|
||||
goto init_failed;
|
||||
|
||||
amdgpu_fru_get_product_info(adev);
|
||||
|
||||
init_failed:
|
||||
@@ -3839,10 +3835,10 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
|
||||
|
||||
amdgpu_fbdev_fini(adev);
|
||||
|
||||
amdgpu_irq_fini_hw(adev);
|
||||
|
||||
amdgpu_device_ip_fini_early(adev);
|
||||
|
||||
amdgpu_irq_fini_hw(adev);
|
||||
|
||||
ttm_device_clear_dma_mappings(&adev->mman.bdev);
|
||||
|
||||
amdgpu_gart_dummy_page_fini(adev);
|
||||
|
||||
@@ -108,6 +108,8 @@ static const char *hw_id_names[HW_ID_MAX] = {
|
||||
[HDP_HWID] = "HDP",
|
||||
[SDMA0_HWID] = "SDMA0",
|
||||
[SDMA1_HWID] = "SDMA1",
|
||||
[SDMA2_HWID] = "SDMA2",
|
||||
[SDMA3_HWID] = "SDMA3",
|
||||
[ISP_HWID] = "ISP",
|
||||
[DBGU_IO_HWID] = "DBGU_IO",
|
||||
[DF_HWID] = "DF",
|
||||
@@ -505,6 +507,10 @@ void amdgpu_discovery_harvest_ip(struct amdgpu_device *adev)
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* some IP discovery tables on Navy Flounder don't have this set correctly */
|
||||
if ((adev->ip_versions[UVD_HWIP][1] == IP_VERSION(3, 0, 1)) &&
|
||||
(adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 2)))
|
||||
adev->vcn.harvest_config |= AMDGPU_VCN_HARVEST_VCN1;
|
||||
if (vcn_harvest_count == adev->vcn.num_vcn_inst) {
|
||||
adev->harvest_ip_mask |= AMD_HARVEST_IP_VCN_MASK;
|
||||
adev->harvest_ip_mask |= AMD_HARVEST_IP_JPEG_MASK;
|
||||
@@ -736,6 +742,7 @@ static int amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device *adev)
|
||||
case IP_VERSION(1, 0, 1):
|
||||
case IP_VERSION(2, 0, 2):
|
||||
case IP_VERSION(2, 0, 0):
|
||||
case IP_VERSION(2, 0, 3):
|
||||
case IP_VERSION(2, 1, 0):
|
||||
case IP_VERSION(3, 0, 0):
|
||||
case IP_VERSION(3, 0, 2):
|
||||
@@ -745,8 +752,6 @@ static int amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device *adev)
|
||||
case IP_VERSION(3, 1, 3):
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
break;
|
||||
case IP_VERSION(2, 0, 3):
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -1120,10 +1125,13 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
||||
break;
|
||||
case IP_VERSION(7, 4, 0):
|
||||
case IP_VERSION(7, 4, 1):
|
||||
case IP_VERSION(7, 4, 4):
|
||||
adev->nbio.funcs = &nbio_v7_4_funcs;
|
||||
adev->nbio.hdp_flush_reg = &nbio_v7_4_hdp_flush_reg;
|
||||
break;
|
||||
case IP_VERSION(7, 4, 4):
|
||||
adev->nbio.funcs = &nbio_v7_4_funcs;
|
||||
adev->nbio.hdp_flush_reg = &nbio_v7_4_hdp_flush_reg_ald;
|
||||
break;
|
||||
case IP_VERSION(7, 2, 0):
|
||||
case IP_VERSION(7, 2, 1):
|
||||
case IP_VERSION(7, 5, 0):
|
||||
@@ -1134,12 +1142,15 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
||||
case IP_VERSION(2, 3, 0):
|
||||
case IP_VERSION(2, 3, 1):
|
||||
case IP_VERSION(2, 3, 2):
|
||||
adev->nbio.funcs = &nbio_v2_3_funcs;
|
||||
adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg;
|
||||
break;
|
||||
case IP_VERSION(3, 3, 0):
|
||||
case IP_VERSION(3, 3, 1):
|
||||
case IP_VERSION(3, 3, 2):
|
||||
case IP_VERSION(3, 3, 3):
|
||||
adev->nbio.funcs = &nbio_v2_3_funcs;
|
||||
adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg;
|
||||
adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg_sc;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -65,7 +65,6 @@ static int psp_securedisplay_terminate(struct psp_context *psp);
|
||||
*
|
||||
* This new sequence is required for
|
||||
* - Arcturus and onwards
|
||||
* - Navi12 and onwards
|
||||
*/
|
||||
static void psp_check_pmfw_centralized_cstate_management(struct psp_context *psp)
|
||||
{
|
||||
@@ -77,7 +76,9 @@ static void psp_check_pmfw_centralized_cstate_management(struct psp_context *psp
|
||||
}
|
||||
|
||||
switch (adev->ip_versions[MP0_HWIP][0]) {
|
||||
case IP_VERSION(11, 0, 0):
|
||||
case IP_VERSION(11, 0, 4):
|
||||
case IP_VERSION(11, 0, 5):
|
||||
case IP_VERSION(11, 0, 7):
|
||||
case IP_VERSION(11, 0, 9):
|
||||
case IP_VERSION(11, 0, 11):
|
||||
@@ -1291,6 +1292,29 @@ static int psp_ras_unload(struct psp_context *psp)
|
||||
return psp_ta_unload(psp, &psp->ras_context.context);
|
||||
}
|
||||
|
||||
static void psp_ras_ta_check_status(struct psp_context *psp)
|
||||
{
|
||||
struct ta_ras_shared_memory *ras_cmd =
|
||||
(struct ta_ras_shared_memory *)psp->ras_context.context.mem_context.shared_buf;
|
||||
|
||||
switch (ras_cmd->ras_status) {
|
||||
case TA_RAS_STATUS__ERROR_UNSUPPORTED_IP:
|
||||
dev_warn(psp->adev->dev,
|
||||
"RAS WARNING: cmd failed due to unsupported ip\n");
|
||||
break;
|
||||
case TA_RAS_STATUS__ERROR_UNSUPPORTED_ERROR_INJ:
|
||||
dev_warn(psp->adev->dev,
|
||||
"RAS WARNING: cmd failed due to unsupported error injection\n");
|
||||
break;
|
||||
case TA_RAS_STATUS__SUCCESS:
|
||||
break;
|
||||
default:
|
||||
dev_warn(psp->adev->dev,
|
||||
"RAS WARNING: ras status = 0x%X\n", ras_cmd->ras_status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int psp_ras_invoke(struct psp_context *psp, uint32_t ta_cmd_id)
|
||||
{
|
||||
struct ta_ras_shared_memory *ras_cmd;
|
||||
@@ -1325,10 +1349,7 @@ int psp_ras_invoke(struct psp_context *psp, uint32_t ta_cmd_id)
|
||||
dev_warn(psp->adev->dev,
|
||||
"RAS internal register access blocked\n");
|
||||
|
||||
if (ras_cmd->ras_status == TA_RAS_STATUS__ERROR_UNSUPPORTED_IP)
|
||||
dev_warn(psp->adev->dev, "RAS WARNING: cmd failed due to unsupported ip\n");
|
||||
else if (ras_cmd->ras_status)
|
||||
dev_warn(psp->adev->dev, "RAS WARNING: ras status = 0x%X\n", ras_cmd->ras_status);
|
||||
psp_ras_ta_check_status(psp);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -2622,6 +2643,12 @@ static int psp_resume(void *handle)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
ret = psp_rl_load(adev);
|
||||
if (ret) {
|
||||
dev_err(adev->dev, "PSP load RL failed!\n");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (adev->gmc.xgmi.num_physical_nodes > 1) {
|
||||
ret = psp_xgmi_initialize(psp, false, true);
|
||||
/* Warning the XGMI seesion initialize failure
|
||||
|
||||
@@ -112,7 +112,12 @@ static bool amdgpu_ras_check_bad_page_unlock(struct amdgpu_ras *con,
|
||||
static bool amdgpu_ras_check_bad_page(struct amdgpu_device *adev,
|
||||
uint64_t addr);
|
||||
#ifdef CONFIG_X86_MCE_AMD
|
||||
static void amdgpu_register_bad_pages_mca_notifier(void);
|
||||
static void amdgpu_register_bad_pages_mca_notifier(struct amdgpu_device *adev);
|
||||
struct mce_notifier_adev_list {
|
||||
struct amdgpu_device *devs[MAX_GPU_INSTANCE];
|
||||
int num_gpu;
|
||||
};
|
||||
static struct mce_notifier_adev_list mce_adev_list;
|
||||
#endif
|
||||
|
||||
void amdgpu_ras_set_error_query_ready(struct amdgpu_device *adev, bool ready)
|
||||
@@ -2108,7 +2113,7 @@ int amdgpu_ras_recovery_init(struct amdgpu_device *adev)
|
||||
#ifdef CONFIG_X86_MCE_AMD
|
||||
if ((adev->asic_type == CHIP_ALDEBARAN) &&
|
||||
(adev->gmc.xgmi.connected_to_cpu))
|
||||
amdgpu_register_bad_pages_mca_notifier();
|
||||
amdgpu_register_bad_pages_mca_notifier(adev);
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
@@ -2605,24 +2610,18 @@ void amdgpu_release_ras_context(struct amdgpu_device *adev)
|
||||
#ifdef CONFIG_X86_MCE_AMD
|
||||
static struct amdgpu_device *find_adev(uint32_t node_id)
|
||||
{
|
||||
struct amdgpu_gpu_instance *gpu_instance;
|
||||
int i;
|
||||
struct amdgpu_device *adev = NULL;
|
||||
|
||||
mutex_lock(&mgpu_info.mutex);
|
||||
for (i = 0; i < mce_adev_list.num_gpu; i++) {
|
||||
adev = mce_adev_list.devs[i];
|
||||
|
||||
for (i = 0; i < mgpu_info.num_gpu; i++) {
|
||||
gpu_instance = &(mgpu_info.gpu_ins[i]);
|
||||
adev = gpu_instance->adev;
|
||||
|
||||
if (adev->gmc.xgmi.connected_to_cpu &&
|
||||
if (adev && adev->gmc.xgmi.connected_to_cpu &&
|
||||
adev->gmc.xgmi.physical_node_id == node_id)
|
||||
break;
|
||||
adev = NULL;
|
||||
}
|
||||
|
||||
mutex_unlock(&mgpu_info.mutex);
|
||||
|
||||
return adev;
|
||||
}
|
||||
|
||||
@@ -2718,8 +2717,18 @@ static struct notifier_block amdgpu_bad_page_nb = {
|
||||
.priority = MCE_PRIO_UC,
|
||||
};
|
||||
|
||||
static void amdgpu_register_bad_pages_mca_notifier(void)
|
||||
static void amdgpu_register_bad_pages_mca_notifier(struct amdgpu_device *adev)
|
||||
{
|
||||
/*
|
||||
* Add the adev to the mce_adev_list.
|
||||
* During mode2 reset, amdgpu device is temporarily
|
||||
* removed from the mgpu_info list which can cause
|
||||
* page retirement to fail.
|
||||
* Use this list instead of mgpu_info to find the amdgpu
|
||||
* device on which the UMC error was reported.
|
||||
*/
|
||||
mce_adev_list.devs[mce_adev_list.num_gpu++] = adev;
|
||||
|
||||
/*
|
||||
* Register the x86 notifier only once
|
||||
* with MCE subsystem.
|
||||
|
||||
@@ -1101,7 +1101,7 @@ int amdgpu_ras_eeprom_init(struct amdgpu_ras_eeprom_control *control,
|
||||
*exceed_err_limit = true;
|
||||
dev_err(adev->dev,
|
||||
"RAS records:%d exceed threshold:%d, "
|
||||
"maybe retire this GPU?",
|
||||
"GPU will not be initialized. Replace this GPU or increase the threshold",
|
||||
control->ras_num_recs, ras->bad_page_cnt_threshold);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -1235,7 +1235,7 @@ struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm)
|
||||
*
|
||||
*/
|
||||
bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start,
|
||||
unsigned long end)
|
||||
unsigned long end, unsigned long *userptr)
|
||||
{
|
||||
struct amdgpu_ttm_tt *gtt = (void *)ttm;
|
||||
unsigned long size;
|
||||
@@ -1250,6 +1250,8 @@ bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start,
|
||||
if (gtt->userptr > end || gtt->userptr + size <= start)
|
||||
return false;
|
||||
|
||||
if (userptr)
|
||||
*userptr = gtt->userptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -182,7 +182,7 @@ int amdgpu_ttm_tt_set_userptr(struct ttm_buffer_object *bo,
|
||||
bool amdgpu_ttm_tt_has_userptr(struct ttm_tt *ttm);
|
||||
struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm);
|
||||
bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start,
|
||||
unsigned long end);
|
||||
unsigned long end, unsigned long *userptr);
|
||||
bool amdgpu_ttm_tt_userptr_invalidated(struct ttm_tt *ttm,
|
||||
int *last_invalidated);
|
||||
bool amdgpu_ttm_tt_is_userptr(struct ttm_tt *ttm);
|
||||
|
||||
@@ -509,7 +509,7 @@ static ssize_t show_##name(struct device *dev, \
|
||||
struct drm_device *ddev = dev_get_drvdata(dev); \
|
||||
struct amdgpu_device *adev = drm_to_adev(ddev); \
|
||||
\
|
||||
return snprintf(buf, PAGE_SIZE, "0x%08x\n", adev->field); \
|
||||
return sysfs_emit(buf, "0x%08x\n", adev->field); \
|
||||
} \
|
||||
static DEVICE_ATTR(name, mode, show_##name, NULL)
|
||||
|
||||
|
||||
@@ -949,3 +949,30 @@ enum amdgpu_ring_priority_level amdgpu_vcn_get_enc_ring_prio(int ring)
|
||||
return AMDGPU_RING_PRIO_0;
|
||||
}
|
||||
}
|
||||
|
||||
void amdgpu_vcn_setup_ucode(struct amdgpu_device *adev)
|
||||
{
|
||||
int i;
|
||||
unsigned int idx;
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
const struct common_firmware_header *hdr;
|
||||
hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
|
||||
|
||||
for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
|
||||
if (adev->vcn.harvest_config & (1 << i))
|
||||
continue;
|
||||
/* currently only support 2 FW instances */
|
||||
if (i >= 2) {
|
||||
dev_info(adev->dev, "More then 2 VCN FW instances!\n");
|
||||
break;
|
||||
}
|
||||
idx = AMDGPU_UCODE_ID_VCN + i;
|
||||
adev->firmware.ucode[idx].ucode_id = idx;
|
||||
adev->firmware.ucode[idx].fw = adev->vcn.fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE);
|
||||
}
|
||||
dev_info(adev->dev, "Will use PSP to load VCN firmware\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,4 +310,6 @@ int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout);
|
||||
|
||||
enum amdgpu_ring_priority_level amdgpu_vcn_get_enc_ring_prio(int ring);
|
||||
|
||||
void amdgpu_vcn_setup_ucode(struct amdgpu_device *adev);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -584,6 +584,7 @@ static int amdgpu_virt_write_vf2pf_data(struct amdgpu_device *adev)
|
||||
vf2pf_info->encode_usage = 0;
|
||||
vf2pf_info->decode_usage = 0;
|
||||
|
||||
vf2pf_info->dummy_page_addr = (uint64_t)adev->dummy_page_addr;
|
||||
vf2pf_info->checksum =
|
||||
amd_sriov_msg_checksum(
|
||||
vf2pf_info, vf2pf_info->header.size, 0, 0);
|
||||
|
||||
@@ -261,9 +261,10 @@ struct amd_sriov_msg_vf2pf_info {
|
||||
uint8_t id;
|
||||
uint32_t version;
|
||||
} ucode_info[AMD_SRIOV_MSG_RESERVE_UCODE];
|
||||
uint64_t dummy_page_addr;
|
||||
|
||||
/* reserved */
|
||||
uint32_t reserved[256-68];
|
||||
uint32_t reserved[256-70];
|
||||
};
|
||||
|
||||
/* mailbox message send from guest to host */
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 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 "amdgpu.h"
|
||||
#include "nv.h"
|
||||
|
||||
#include "soc15_common.h"
|
||||
#include "soc15_hw_ip.h"
|
||||
#include "beige_goby_ip_offset.h"
|
||||
|
||||
int beige_goby_reg_base_init(struct amdgpu_device *adev)
|
||||
{
|
||||
/* HW has more IP blocks, only initialize the block needed by driver */
|
||||
uint32_t i;
|
||||
for (i = 0 ; i < MAX_INSTANCE ; ++i) {
|
||||
adev->reg_offset[GC_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[HDP_HWIP][i] = (uint32_t *)(&(HDP_BASE.instance[i]));
|
||||
adev->reg_offset[MMHUB_HWIP][i] = (uint32_t *)(&(MMHUB_BASE.instance[i]));
|
||||
adev->reg_offset[ATHUB_HWIP][i] = (uint32_t *)(&(ATHUB_BASE.instance[i]));
|
||||
adev->reg_offset[NBIO_HWIP][i] = (uint32_t *)(&(NBIO_BASE.instance[i]));
|
||||
adev->reg_offset[MP0_HWIP][i] = (uint32_t *)(&(MP0_BASE.instance[i]));
|
||||
adev->reg_offset[MP1_HWIP][i] = (uint32_t *)(&(MP1_BASE.instance[i]));
|
||||
adev->reg_offset[VCN_HWIP][i] = (uint32_t *)(&(VCN0_BASE.instance[i]));
|
||||
adev->reg_offset[DF_HWIP][i] = (uint32_t *)(&(DF_BASE.instance[i]));
|
||||
adev->reg_offset[DCE_HWIP][i] = (uint32_t *)(&(DCN_BASE.instance[i]));
|
||||
adev->reg_offset[OSSSYS_HWIP][i] = (uint32_t *)(&(OSSSYS_BASE.instance[i]));
|
||||
adev->reg_offset[SDMA0_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[SDMA1_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[SDMA2_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[SDMA3_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[SMUIO_HWIP][i] = (uint32_t *)(&(SMUIO_BASE.instance[i]));
|
||||
adev->reg_offset[THM_HWIP][i] = (uint32_t *)(&(THM_BASE.instance[i]));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#include "amdgpu.h"
|
||||
#include "nv.h"
|
||||
|
||||
#include "soc15_common.h"
|
||||
#include "soc15_hw_ip.h"
|
||||
#include "cyan_skillfish_ip_offset.h"
|
||||
|
||||
int cyan_skillfish_reg_base_init(struct amdgpu_device *adev)
|
||||
{
|
||||
/* HW has more IP blocks, only initialized the blocke needed by driver */
|
||||
uint32_t i;
|
||||
for (i = 0 ; i < MAX_INSTANCE ; ++i) {
|
||||
adev->reg_offset[GC_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[HDP_HWIP][i] = (uint32_t *)(&(HDP_BASE.instance[i]));
|
||||
adev->reg_offset[MMHUB_HWIP][i] = (uint32_t *)(&(MMHUB_BASE.instance[i]));
|
||||
adev->reg_offset[ATHUB_HWIP][i] = (uint32_t *)(&(ATHUB_BASE.instance[i]));
|
||||
adev->reg_offset[NBIO_HWIP][i] = (uint32_t *)(&(NBIO_BASE.instance[i]));
|
||||
adev->reg_offset[MP0_HWIP][i] = (uint32_t *)(&(MP0_BASE.instance[i]));
|
||||
adev->reg_offset[MP1_HWIP][i] = (uint32_t *)(&(MP1_BASE.instance[i]));
|
||||
adev->reg_offset[VCN_HWIP][i] = (uint32_t *)(&(UVD0_BASE.instance[i]));
|
||||
adev->reg_offset[DF_HWIP][i] = (uint32_t *)(&(DF_BASE.instance[i]));
|
||||
adev->reg_offset[DCE_HWIP][i] = (uint32_t *)(&(DMU_BASE.instance[i]));
|
||||
adev->reg_offset[OSSSYS_HWIP][i] = (uint32_t *)(&(OSSSYS_BASE.instance[i]));
|
||||
adev->reg_offset[SDMA0_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[SDMA1_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[SMUIO_HWIP][i] = (uint32_t *)(&(SMUIO_BASE.instance[i]));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -270,25 +270,6 @@ MODULE_FIRMWARE("amdgpu/cyan_skillfish2_mec.bin");
|
||||
MODULE_FIRMWARE("amdgpu/cyan_skillfish2_mec2.bin");
|
||||
MODULE_FIRMWARE("amdgpu/cyan_skillfish2_rlc.bin");
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_gc_10_0[] =
|
||||
{
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_CAM_INDEX, 0xffffffff, 0x00000000),
|
||||
/* TA_GRAD_ADJ_UCONFIG -> TA_GRAD_ADJ */
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_CAM_DATA, 0xffffffff, 0x2544c382),
|
||||
/* VGT_TF_RING_SIZE_UMD -> VGT_TF_RING_SIZE */
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_CAM_DATA, 0xffffffff, 0x2262c24e),
|
||||
/* VGT_HS_OFFCHIP_PARAM_UMD -> VGT_HS_OFFCHIP_PARAM */
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_CAM_DATA, 0xffffffff, 0x226cc24f),
|
||||
/* VGT_TF_MEMORY_BASE_UMD -> VGT_TF_MEMORY_BASE */
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_CAM_DATA, 0xffffffff, 0x226ec250),
|
||||
/* VGT_TF_MEMORY_BASE_HI_UMD -> VGT_TF_MEMORY_BASE_HI */
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_CAM_DATA, 0xffffffff, 0x2278c261),
|
||||
/* VGT_ESGS_RING_SIZE_UMD -> VGT_ESGS_RING_SIZE */
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_CAM_DATA, 0xffffffff, 0x2232c240),
|
||||
/* VGT_GSVS_RING_SIZE_UMD -> VGT_GSVS_RING_SIZE */
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_CAM_DATA, 0xffffffff, 0x2233c241),
|
||||
};
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_gc_10_1[] =
|
||||
{
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL_4, 0xffffffff, 0x00400014),
|
||||
@@ -3809,9 +3790,6 @@ static void gfx_v10_0_init_golden_registers(struct amdgpu_device *adev)
|
||||
(const u32)ARRAY_SIZE(golden_settings_gc_10_3_5));
|
||||
break;
|
||||
case IP_VERSION(10, 1, 3):
|
||||
soc15_program_register_sequence(adev,
|
||||
golden_settings_gc_10_0,
|
||||
(const u32)ARRAY_SIZE(golden_settings_gc_10_0));
|
||||
soc15_program_register_sequence(adev,
|
||||
golden_settings_gc_10_0_cyan_skillfish,
|
||||
(const u32)ARRAY_SIZE(golden_settings_gc_10_0_cyan_skillfish));
|
||||
@@ -8238,8 +8216,9 @@ static int gfx_v10_0_update_gfx_clock_gating(struct amdgpu_device *adev,
|
||||
/* === CGCG + CGLS === */
|
||||
gfx_v10_0_update_coarse_grain_clock_gating(adev, enable);
|
||||
|
||||
if ((adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 1, 10)) &&
|
||||
(adev->ip_versions[GC_HWIP][0] <= IP_VERSION(10, 1, 2)))
|
||||
if ((adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 1, 10)) ||
|
||||
(adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 1, 1)) ||
|
||||
(adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 1, 2)))
|
||||
gfx_v10_0_apply_medium_grain_clock_gating_workaround(adev);
|
||||
} else {
|
||||
/* CGCG/CGLS should be disabled before MGCG/MGLS
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#include "amdgpu.h"
|
||||
#include "nv.h"
|
||||
|
||||
#include "soc15_common.h"
|
||||
#include "navi10_ip_offset.h"
|
||||
|
||||
int navi10_reg_base_init(struct amdgpu_device *adev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0 ; i < MAX_INSTANCE ; ++i) {
|
||||
adev->reg_offset[GC_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[HDP_HWIP][i] = (uint32_t *)(&(HDP_BASE.instance[i]));
|
||||
adev->reg_offset[MMHUB_HWIP][i] = (uint32_t *)(&(MMHUB_BASE.instance[i]));
|
||||
adev->reg_offset[ATHUB_HWIP][i] = (uint32_t *)(&(ATHUB_BASE.instance[i]));
|
||||
adev->reg_offset[NBIO_HWIP][i] = (uint32_t *)(&(NBIO_BASE.instance[i]));
|
||||
adev->reg_offset[MP0_HWIP][i] = (uint32_t *)(&(MP0_BASE.instance[i]));
|
||||
adev->reg_offset[MP1_HWIP][i] = (uint32_t *)(&(MP1_BASE.instance[i]));
|
||||
adev->reg_offset[VCN_HWIP][i] = (uint32_t *)(&(VCN_BASE.instance[i]));
|
||||
adev->reg_offset[DF_HWIP][i] = (uint32_t *)(&(DF_BASE.instance[i]));
|
||||
adev->reg_offset[DCE_HWIP][i] = (uint32_t *)(&(DCN_BASE.instance[i]));
|
||||
adev->reg_offset[OSSSYS_HWIP][i] = (uint32_t *)(&(OSSSYS_BASE.instance[i]));
|
||||
adev->reg_offset[SDMA0_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[SDMA1_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[SMUIO_HWIP][i] = (uint32_t *)(&(SMUIO_BASE.instance[i]));
|
||||
adev->reg_offset[THM_HWIP][i] = (uint32_t *)(&(THM_BASE.instance[i]));
|
||||
adev->reg_offset[CLK_HWIP][i] = (uint32_t *)(&(CLK_BASE.instance[i]));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#include "amdgpu.h"
|
||||
#include "nv.h"
|
||||
|
||||
#include "soc15_common.h"
|
||||
#include "navi12_ip_offset.h"
|
||||
|
||||
int navi12_reg_base_init(struct amdgpu_device *adev)
|
||||
{
|
||||
/* HW has more IP blocks, only initialized the blocks needed by driver */
|
||||
uint32_t i;
|
||||
for (i = 0 ; i < MAX_INSTANCE ; ++i) {
|
||||
adev->reg_offset[GC_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[HDP_HWIP][i] = (uint32_t *)(&(HDP_BASE.instance[i]));
|
||||
adev->reg_offset[MMHUB_HWIP][i] = (uint32_t *)(&(MMHUB_BASE.instance[i]));
|
||||
adev->reg_offset[ATHUB_HWIP][i] = (uint32_t *)(&(ATHUB_BASE.instance[i]));
|
||||
adev->reg_offset[NBIO_HWIP][i] = (uint32_t *)(&(NBIF0_BASE.instance[i]));
|
||||
adev->reg_offset[MP0_HWIP][i] = (uint32_t *)(&(MP0_BASE.instance[i]));
|
||||
adev->reg_offset[MP1_HWIP][i] = (uint32_t *)(&(MP1_BASE.instance[i]));
|
||||
adev->reg_offset[VCN_HWIP][i] = (uint32_t *)(&(UVD0_BASE.instance[i]));
|
||||
adev->reg_offset[DF_HWIP][i] = (uint32_t *)(&(DF_BASE.instance[i]));
|
||||
adev->reg_offset[DCE_HWIP][i] = (uint32_t *)(&(DMU_BASE.instance[i]));
|
||||
adev->reg_offset[OSSSYS_HWIP][i] = (uint32_t *)(&(OSSSYS_BASE.instance[i]));
|
||||
adev->reg_offset[SDMA0_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[SDMA1_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[SMUIO_HWIP][i] = (uint32_t *)(&(SMUIO_BASE.instance[i]));
|
||||
adev->reg_offset[THM_HWIP][i] = (uint32_t *)(&(THM_BASE.instance[i]));
|
||||
adev->reg_offset[CLK_HWIP][i] = (uint32_t *)(&(CLK_BASE.instance[i]));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#include "amdgpu.h"
|
||||
#include "nv.h"
|
||||
|
||||
#include "soc15_common.h"
|
||||
#include "navi14_ip_offset.h"
|
||||
|
||||
int navi14_reg_base_init(struct amdgpu_device *adev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0 ; i < MAX_INSTANCE ; ++i) {
|
||||
adev->reg_offset[GC_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[HDP_HWIP][i] = (uint32_t *)(&(HDP_BASE.instance[i]));
|
||||
adev->reg_offset[MMHUB_HWIP][i] = (uint32_t *)(&(MMHUB_BASE.instance[i]));
|
||||
adev->reg_offset[ATHUB_HWIP][i] = (uint32_t *)(&(ATHUB_BASE.instance[i]));
|
||||
adev->reg_offset[NBIO_HWIP][i] = (uint32_t *)(&(NBIF0_BASE.instance[i]));
|
||||
adev->reg_offset[MP0_HWIP][i] = (uint32_t *)(&(MP0_BASE.instance[i]));
|
||||
adev->reg_offset[MP1_HWIP][i] = (uint32_t *)(&(MP1_BASE.instance[i]));
|
||||
adev->reg_offset[VCN_HWIP][i] = (uint32_t *)(&(UVD0_BASE.instance[i]));
|
||||
adev->reg_offset[DF_HWIP][i] = (uint32_t *)(&(DF_BASE.instance[i]));
|
||||
adev->reg_offset[DCE_HWIP][i] = (uint32_t *)(&(DMU_BASE.instance[i]));
|
||||
adev->reg_offset[OSSSYS_HWIP][i] = (uint32_t *)(&(OSSSYS_BASE.instance[i]));
|
||||
adev->reg_offset[SDMA0_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[SDMA1_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[SMUIO_HWIP][i] = (uint32_t *)(&(SMUIO_BASE.instance[i]));
|
||||
adev->reg_offset[THM_HWIP][i] = (uint32_t *)(&(THM_BASE.instance[i]));
|
||||
adev->reg_offset[CLK_HWIP][i] = (uint32_t *)(&(CLK_BASE.instance[i]));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -53,6 +53,16 @@
|
||||
|
||||
#define smnPCIE_LC_LINK_WIDTH_CNTL 0x11140288
|
||||
|
||||
#define GPU_HDP_FLUSH_DONE__RSVD_ENG0_MASK 0x00001000L /* Don't use. Firmware uses this bit internally */
|
||||
#define GPU_HDP_FLUSH_DONE__RSVD_ENG1_MASK 0x00002000L
|
||||
#define GPU_HDP_FLUSH_DONE__RSVD_ENG2_MASK 0x00004000L
|
||||
#define GPU_HDP_FLUSH_DONE__RSVD_ENG3_MASK 0x00008000L
|
||||
#define GPU_HDP_FLUSH_DONE__RSVD_ENG4_MASK 0x00010000L
|
||||
#define GPU_HDP_FLUSH_DONE__RSVD_ENG5_MASK 0x00020000L
|
||||
#define GPU_HDP_FLUSH_DONE__RSVD_ENG6_MASK 0x00040000L
|
||||
#define GPU_HDP_FLUSH_DONE__RSVD_ENG7_MASK 0x00080000L
|
||||
#define GPU_HDP_FLUSH_DONE__RSVD_ENG8_MASK 0x00100000L
|
||||
|
||||
static void nbio_v2_3_remap_hdp_registers(struct amdgpu_device *adev)
|
||||
{
|
||||
WREG32_SOC15(NBIO, 0, mmREMAP_HDP_MEM_FLUSH_CNTL,
|
||||
@@ -318,6 +328,27 @@ const struct nbio_hdp_flush_reg nbio_v2_3_hdp_flush_reg = {
|
||||
.ref_and_mask_sdma1 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__SDMA1_MASK,
|
||||
};
|
||||
|
||||
const struct nbio_hdp_flush_reg nbio_v2_3_hdp_flush_reg_sc = {
|
||||
.ref_and_mask_cp0 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP0_MASK,
|
||||
.ref_and_mask_cp1 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP1_MASK,
|
||||
.ref_and_mask_cp2 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP2_MASK,
|
||||
.ref_and_mask_cp3 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP3_MASK,
|
||||
.ref_and_mask_cp4 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP4_MASK,
|
||||
.ref_and_mask_cp5 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP5_MASK,
|
||||
.ref_and_mask_cp6 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP6_MASK,
|
||||
.ref_and_mask_cp7 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP7_MASK,
|
||||
.ref_and_mask_cp8 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP8_MASK,
|
||||
.ref_and_mask_cp9 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP9_MASK,
|
||||
.ref_and_mask_sdma0 = GPU_HDP_FLUSH_DONE__RSVD_ENG1_MASK,
|
||||
.ref_and_mask_sdma1 = GPU_HDP_FLUSH_DONE__RSVD_ENG2_MASK,
|
||||
.ref_and_mask_sdma2 = GPU_HDP_FLUSH_DONE__RSVD_ENG3_MASK,
|
||||
.ref_and_mask_sdma3 = GPU_HDP_FLUSH_DONE__RSVD_ENG4_MASK,
|
||||
.ref_and_mask_sdma4 = GPU_HDP_FLUSH_DONE__RSVD_ENG5_MASK,
|
||||
.ref_and_mask_sdma5 = GPU_HDP_FLUSH_DONE__RSVD_ENG6_MASK,
|
||||
.ref_and_mask_sdma6 = GPU_HDP_FLUSH_DONE__RSVD_ENG7_MASK,
|
||||
.ref_and_mask_sdma7 = GPU_HDP_FLUSH_DONE__RSVD_ENG8_MASK,
|
||||
};
|
||||
|
||||
static void nbio_v2_3_init_registers(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t def, data;
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "soc15_common.h"
|
||||
|
||||
extern const struct nbio_hdp_flush_reg nbio_v2_3_hdp_flush_reg;
|
||||
extern const struct nbio_hdp_flush_reg nbio_v2_3_hdp_flush_reg_sc;
|
||||
extern const struct amdgpu_nbio_funcs nbio_v2_3_funcs;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -56,12 +56,15 @@
|
||||
* These are nbio v7_4_1 registers mask. Temporarily define these here since
|
||||
* nbio v7_4_1 header is incomplete.
|
||||
*/
|
||||
#define GPU_HDP_FLUSH_DONE__RSVD_ENG0_MASK 0x00001000L
|
||||
#define GPU_HDP_FLUSH_DONE__RSVD_ENG0_MASK 0x00001000L /* Don't use. Firmware uses this bit internally */
|
||||
#define GPU_HDP_FLUSH_DONE__RSVD_ENG1_MASK 0x00002000L
|
||||
#define GPU_HDP_FLUSH_DONE__RSVD_ENG2_MASK 0x00004000L
|
||||
#define GPU_HDP_FLUSH_DONE__RSVD_ENG3_MASK 0x00008000L
|
||||
#define GPU_HDP_FLUSH_DONE__RSVD_ENG4_MASK 0x00010000L
|
||||
#define GPU_HDP_FLUSH_DONE__RSVD_ENG5_MASK 0x00020000L
|
||||
#define GPU_HDP_FLUSH_DONE__RSVD_ENG6_MASK 0x00040000L
|
||||
#define GPU_HDP_FLUSH_DONE__RSVD_ENG7_MASK 0x00080000L
|
||||
#define GPU_HDP_FLUSH_DONE__RSVD_ENG8_MASK 0x00100000L
|
||||
|
||||
#define mmBIF_MMSCH1_DOORBELL_RANGE 0x01dc
|
||||
#define mmBIF_MMSCH1_DOORBELL_RANGE_BASE_IDX 2
|
||||
@@ -334,12 +337,27 @@ const struct nbio_hdp_flush_reg nbio_v7_4_hdp_flush_reg = {
|
||||
.ref_and_mask_cp9 = GPU_HDP_FLUSH_DONE__CP9_MASK,
|
||||
.ref_and_mask_sdma0 = GPU_HDP_FLUSH_DONE__SDMA0_MASK,
|
||||
.ref_and_mask_sdma1 = GPU_HDP_FLUSH_DONE__SDMA1_MASK,
|
||||
.ref_and_mask_sdma2 = GPU_HDP_FLUSH_DONE__RSVD_ENG0_MASK,
|
||||
.ref_and_mask_sdma3 = GPU_HDP_FLUSH_DONE__RSVD_ENG1_MASK,
|
||||
.ref_and_mask_sdma4 = GPU_HDP_FLUSH_DONE__RSVD_ENG2_MASK,
|
||||
.ref_and_mask_sdma5 = GPU_HDP_FLUSH_DONE__RSVD_ENG3_MASK,
|
||||
.ref_and_mask_sdma6 = GPU_HDP_FLUSH_DONE__RSVD_ENG4_MASK,
|
||||
.ref_and_mask_sdma7 = GPU_HDP_FLUSH_DONE__RSVD_ENG5_MASK,
|
||||
};
|
||||
|
||||
const struct nbio_hdp_flush_reg nbio_v7_4_hdp_flush_reg_ald = {
|
||||
.ref_and_mask_cp0 = GPU_HDP_FLUSH_DONE__CP0_MASK,
|
||||
.ref_and_mask_cp1 = GPU_HDP_FLUSH_DONE__CP1_MASK,
|
||||
.ref_and_mask_cp2 = GPU_HDP_FLUSH_DONE__CP2_MASK,
|
||||
.ref_and_mask_cp3 = GPU_HDP_FLUSH_DONE__CP3_MASK,
|
||||
.ref_and_mask_cp4 = GPU_HDP_FLUSH_DONE__CP4_MASK,
|
||||
.ref_and_mask_cp5 = GPU_HDP_FLUSH_DONE__CP5_MASK,
|
||||
.ref_and_mask_cp6 = GPU_HDP_FLUSH_DONE__CP6_MASK,
|
||||
.ref_and_mask_cp7 = GPU_HDP_FLUSH_DONE__CP7_MASK,
|
||||
.ref_and_mask_cp8 = GPU_HDP_FLUSH_DONE__CP8_MASK,
|
||||
.ref_and_mask_cp9 = GPU_HDP_FLUSH_DONE__CP9_MASK,
|
||||
.ref_and_mask_sdma0 = GPU_HDP_FLUSH_DONE__RSVD_ENG1_MASK,
|
||||
.ref_and_mask_sdma1 = GPU_HDP_FLUSH_DONE__RSVD_ENG2_MASK,
|
||||
.ref_and_mask_sdma2 = GPU_HDP_FLUSH_DONE__RSVD_ENG3_MASK,
|
||||
.ref_and_mask_sdma3 = GPU_HDP_FLUSH_DONE__RSVD_ENG4_MASK,
|
||||
.ref_and_mask_sdma4 = GPU_HDP_FLUSH_DONE__RSVD_ENG5_MASK,
|
||||
.ref_and_mask_sdma5 = GPU_HDP_FLUSH_DONE__RSVD_ENG6_MASK,
|
||||
.ref_and_mask_sdma6 = GPU_HDP_FLUSH_DONE__RSVD_ENG7_MASK,
|
||||
.ref_and_mask_sdma7 = GPU_HDP_FLUSH_DONE__RSVD_ENG8_MASK,
|
||||
};
|
||||
|
||||
static void nbio_v7_4_init_registers(struct amdgpu_device *adev)
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "soc15_common.h"
|
||||
|
||||
extern const struct nbio_hdp_flush_reg nbio_v7_4_hdp_flush_reg;
|
||||
extern const struct nbio_hdp_flush_reg nbio_v7_4_hdp_flush_reg_ald;
|
||||
extern const struct amdgpu_nbio_funcs nbio_v7_4_funcs;
|
||||
extern const struct amdgpu_nbio_ras_funcs nbio_v7_4_ras_funcs;
|
||||
|
||||
|
||||
@@ -607,304 +607,11 @@ const struct amdgpu_ip_block_version nv_common_ip_block =
|
||||
.funcs = &nv_common_ip_funcs,
|
||||
};
|
||||
|
||||
static int nv_reg_base_init(struct amdgpu_device *adev)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (amdgpu_discovery) {
|
||||
r = amdgpu_discovery_reg_base_init(adev);
|
||||
if (r) {
|
||||
DRM_WARN("failed to init reg base from ip discovery table, "
|
||||
"fallback to legacy init method\n");
|
||||
goto legacy_init;
|
||||
}
|
||||
|
||||
amdgpu_discovery_harvest_ip(adev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
legacy_init:
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_NAVI10:
|
||||
navi10_reg_base_init(adev);
|
||||
break;
|
||||
case CHIP_NAVI14:
|
||||
navi14_reg_base_init(adev);
|
||||
break;
|
||||
case CHIP_NAVI12:
|
||||
navi12_reg_base_init(adev);
|
||||
break;
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
sienna_cichlid_reg_base_init(adev);
|
||||
break;
|
||||
case CHIP_VANGOGH:
|
||||
vangogh_reg_base_init(adev);
|
||||
break;
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
dimgrey_cavefish_reg_base_init(adev);
|
||||
break;
|
||||
case CHIP_BEIGE_GOBY:
|
||||
beige_goby_reg_base_init(adev);
|
||||
break;
|
||||
case CHIP_YELLOW_CARP:
|
||||
yellow_carp_reg_base_init(adev);
|
||||
break;
|
||||
case CHIP_CYAN_SKILLFISH:
|
||||
cyan_skillfish_reg_base_init(adev);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nv_set_virt_ops(struct amdgpu_device *adev)
|
||||
{
|
||||
adev->virt.ops = &xgpu_nv_virt_ops;
|
||||
}
|
||||
|
||||
int nv_set_ip_blocks(struct amdgpu_device *adev)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (adev->asic_type == CHIP_CYAN_SKILLFISH) {
|
||||
adev->nbio.funcs = &nbio_v2_3_funcs;
|
||||
adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg;
|
||||
} else if (adev->flags & AMD_IS_APU) {
|
||||
adev->nbio.funcs = &nbio_v7_2_funcs;
|
||||
adev->nbio.hdp_flush_reg = &nbio_v7_2_hdp_flush_reg;
|
||||
} else {
|
||||
adev->nbio.funcs = &nbio_v2_3_funcs;
|
||||
adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg;
|
||||
}
|
||||
adev->hdp.funcs = &hdp_v5_0_funcs;
|
||||
|
||||
if (adev->asic_type >= CHIP_SIENNA_CICHLID)
|
||||
adev->smuio.funcs = &smuio_v11_0_6_funcs;
|
||||
else
|
||||
adev->smuio.funcs = &smuio_v11_0_funcs;
|
||||
|
||||
if (adev->asic_type == CHIP_SIENNA_CICHLID)
|
||||
adev->gmc.xgmi.supported = true;
|
||||
|
||||
/* Set IP register base before any HW register access */
|
||||
r = nv_reg_base_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_NAVI10:
|
||||
case CHIP_NAVI14:
|
||||
amdgpu_device_ip_block_add(adev, &nv_common_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP &&
|
||||
!amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
#endif
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v5_0_ip_block);
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT &&
|
||||
!amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &jpeg_v2_0_ip_block);
|
||||
if (adev->enable_mes)
|
||||
amdgpu_device_ip_block_add(adev, &mes_v10_1_ip_block);
|
||||
break;
|
||||
case CHIP_NAVI12:
|
||||
amdgpu_device_ip_block_add(adev, &nv_common_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block);
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
|
||||
} else {
|
||||
amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block);
|
||||
}
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
#endif
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v5_0_ip_block);
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT &&
|
||||
!amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block);
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &jpeg_v2_0_ip_block);
|
||||
break;
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
amdgpu_device_ip_block_add(adev, &nv_common_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block);
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block);
|
||||
if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP))
|
||||
amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
|
||||
} else {
|
||||
if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP))
|
||||
amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block);
|
||||
}
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP &&
|
||||
is_support_sw_smu(adev))
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
#endif
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block);
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &jpeg_v3_0_ip_block);
|
||||
if (adev->enable_mes)
|
||||
amdgpu_device_ip_block_add(adev, &mes_v10_1_ip_block);
|
||||
break;
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
amdgpu_device_ip_block_add(adev, &nv_common_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block);
|
||||
if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP))
|
||||
amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP &&
|
||||
is_support_sw_smu(adev))
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
#endif
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &jpeg_v3_0_ip_block);
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT &&
|
||||
is_support_sw_smu(adev))
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
break;
|
||||
case CHIP_VANGOGH:
|
||||
amdgpu_device_ip_block_add(adev, &nv_common_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block);
|
||||
if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP))
|
||||
amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
#endif
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &jpeg_v3_0_ip_block);
|
||||
break;
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
amdgpu_device_ip_block_add(adev, &nv_common_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block);
|
||||
if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP))
|
||||
amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP &&
|
||||
is_support_sw_smu(adev))
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
#endif
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &jpeg_v3_0_ip_block);
|
||||
break;
|
||||
case CHIP_BEIGE_GOBY:
|
||||
amdgpu_device_ip_block_add(adev, &nv_common_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block);
|
||||
if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP))
|
||||
amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP &&
|
||||
is_support_sw_smu(adev))
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
#endif
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT &&
|
||||
is_support_sw_smu(adev))
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block);
|
||||
break;
|
||||
case CHIP_YELLOW_CARP:
|
||||
amdgpu_device_ip_block_add(adev, &nv_common_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block);
|
||||
if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP))
|
||||
amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
#endif
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &jpeg_v3_0_ip_block);
|
||||
break;
|
||||
case CHIP_CYAN_SKILLFISH:
|
||||
amdgpu_device_ip_block_add(adev, &nv_common_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block);
|
||||
if (adev->apu_flags & AMD_APU_IS_CYAN_SKILLFISH2) {
|
||||
if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP))
|
||||
amdgpu_device_ip_block_add(adev, &psp_v11_0_8_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
}
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
#endif
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v5_0_ip_block);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t nv_get_rev_id(struct amdgpu_device *adev)
|
||||
{
|
||||
return adev->nbio.funcs->get_rev_id(adev);
|
||||
@@ -1248,7 +955,7 @@ static int nv_common_early_init(void *handle)
|
||||
AMD_PG_SUPPORT_VCN_DPG |
|
||||
AMD_PG_SUPPORT_JPEG;
|
||||
if (adev->pdev->device == 0x1681)
|
||||
adev->external_rev_id = adev->rev_id + 0x19;
|
||||
adev->external_rev_id = 0x20;
|
||||
else
|
||||
adev->external_rev_id = adev->rev_id + 0x01;
|
||||
break;
|
||||
|
||||
@@ -31,15 +31,5 @@ extern const struct amdgpu_ip_block_version nv_common_ip_block;
|
||||
void nv_grbm_select(struct amdgpu_device *adev,
|
||||
u32 me, u32 pipe, u32 queue, u32 vmid);
|
||||
void nv_set_virt_ops(struct amdgpu_device *adev);
|
||||
int nv_set_ip_blocks(struct amdgpu_device *adev);
|
||||
int navi10_reg_base_init(struct amdgpu_device *adev);
|
||||
int navi14_reg_base_init(struct amdgpu_device *adev);
|
||||
int navi12_reg_base_init(struct amdgpu_device *adev);
|
||||
int sienna_cichlid_reg_base_init(struct amdgpu_device *adev);
|
||||
void vangogh_reg_base_init(struct amdgpu_device *adev);
|
||||
int dimgrey_cavefish_reg_base_init(struct amdgpu_device *adev);
|
||||
int beige_goby_reg_base_init(struct amdgpu_device *adev);
|
||||
int yellow_carp_reg_base_init(struct amdgpu_device *adev);
|
||||
int cyan_skillfish_reg_base_init(struct amdgpu_device *adev);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 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 "amdgpu.h"
|
||||
#include "nv.h"
|
||||
|
||||
#include "soc15_common.h"
|
||||
#include "soc15_hw_ip.h"
|
||||
#include "sienna_cichlid_ip_offset.h"
|
||||
|
||||
int sienna_cichlid_reg_base_init(struct amdgpu_device *adev)
|
||||
{
|
||||
/* HW has more IP blocks, only initialized the blocke needed by driver */
|
||||
uint32_t i;
|
||||
for (i = 0 ; i < MAX_INSTANCE ; ++i) {
|
||||
adev->reg_offset[GC_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[HDP_HWIP][i] = (uint32_t *)(&(HDP_BASE.instance[i]));
|
||||
adev->reg_offset[MMHUB_HWIP][i] = (uint32_t *)(&(MMHUB_BASE.instance[i]));
|
||||
adev->reg_offset[ATHUB_HWIP][i] = (uint32_t *)(&(ATHUB_BASE.instance[i]));
|
||||
adev->reg_offset[NBIO_HWIP][i] = (uint32_t *)(&(NBIO_BASE.instance[i]));
|
||||
adev->reg_offset[MP0_HWIP][i] = (uint32_t *)(&(MP0_BASE.instance[i]));
|
||||
adev->reg_offset[MP1_HWIP][i] = (uint32_t *)(&(MP1_BASE.instance[i]));
|
||||
adev->reg_offset[VCN_HWIP][i] = (uint32_t *)(&(VCN_BASE.instance[i]));
|
||||
adev->reg_offset[DF_HWIP][i] = (uint32_t *)(&(DF_BASE.instance[i]));
|
||||
adev->reg_offset[DCE_HWIP][i] = (uint32_t *)(&(DCN_BASE.instance[i]));
|
||||
adev->reg_offset[OSSSYS_HWIP][i] = (uint32_t *)(&(OSSSYS_BASE.instance[i]));
|
||||
adev->reg_offset[SDMA0_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[SDMA1_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[SDMA2_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[SDMA3_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[SMUIO_HWIP][i] = (uint32_t *)(&(SMUIO_BASE.instance[i]));
|
||||
adev->reg_offset[THM_HWIP][i] = (uint32_t *)(&(THM_BASE.instance[i]));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -780,185 +780,6 @@ void soc15_set_virt_ops(struct amdgpu_device *adev)
|
||||
soc15_reg_base_init(adev);
|
||||
}
|
||||
|
||||
int soc15_set_ip_blocks(struct amdgpu_device *adev)
|
||||
{
|
||||
/* for bare metal case */
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
soc15_reg_base_init(adev);
|
||||
|
||||
if (adev->flags & AMD_IS_APU) {
|
||||
adev->nbio.funcs = &nbio_v7_0_funcs;
|
||||
adev->nbio.hdp_flush_reg = &nbio_v7_0_hdp_flush_reg;
|
||||
} else if (adev->asic_type == CHIP_VEGA20 ||
|
||||
adev->asic_type == CHIP_ARCTURUS ||
|
||||
adev->asic_type == CHIP_ALDEBARAN) {
|
||||
adev->nbio.funcs = &nbio_v7_4_funcs;
|
||||
adev->nbio.hdp_flush_reg = &nbio_v7_4_hdp_flush_reg;
|
||||
} else {
|
||||
adev->nbio.funcs = &nbio_v6_1_funcs;
|
||||
adev->nbio.hdp_flush_reg = &nbio_v6_1_hdp_flush_reg;
|
||||
}
|
||||
adev->hdp.funcs = &hdp_v4_0_funcs;
|
||||
|
||||
if (adev->asic_type == CHIP_VEGA20 ||
|
||||
adev->asic_type == CHIP_ARCTURUS ||
|
||||
adev->asic_type == CHIP_ALDEBARAN)
|
||||
adev->df.funcs = &df_v3_6_funcs;
|
||||
else
|
||||
adev->df.funcs = &df_v1_7_funcs;
|
||||
|
||||
if (adev->asic_type == CHIP_VEGA20 ||
|
||||
adev->asic_type == CHIP_ARCTURUS)
|
||||
adev->smuio.funcs = &smuio_v11_0_funcs;
|
||||
else if (adev->asic_type == CHIP_ALDEBARAN)
|
||||
adev->smuio.funcs = &smuio_v13_0_funcs;
|
||||
else
|
||||
adev->smuio.funcs = &smuio_v9_0_funcs;
|
||||
|
||||
adev->rev_id = soc15_get_rev_id(adev);
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VEGA10:
|
||||
case CHIP_VEGA12:
|
||||
case CHIP_VEGA20:
|
||||
amdgpu_device_ip_block_add(adev, &vega10_common_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gmc_v9_0_ip_block);
|
||||
|
||||
/* For Vega10 SR-IOV, PSP need to be initialized before IH */
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) {
|
||||
if (adev->asic_type == CHIP_VEGA20)
|
||||
amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
|
||||
else
|
||||
amdgpu_device_ip_block_add(adev, &psp_v3_1_ip_block);
|
||||
}
|
||||
if (adev->asic_type == CHIP_VEGA20)
|
||||
amdgpu_device_ip_block_add(adev, &vega20_ih_ip_block);
|
||||
else
|
||||
amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block);
|
||||
} else {
|
||||
if (adev->asic_type == CHIP_VEGA20)
|
||||
amdgpu_device_ip_block_add(adev, &vega20_ih_ip_block);
|
||||
else
|
||||
amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block);
|
||||
if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) {
|
||||
if (adev->asic_type == CHIP_VEGA20)
|
||||
amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
|
||||
else
|
||||
amdgpu_device_ip_block_add(adev, &psp_v3_1_ip_block);
|
||||
}
|
||||
}
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
|
||||
if (is_support_sw_smu(adev)) {
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
} else {
|
||||
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
|
||||
}
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
#endif
|
||||
if (!(adev->asic_type == CHIP_VEGA20 && amdgpu_sriov_vf(adev))) {
|
||||
amdgpu_device_ip_block_add(adev, &uvd_v7_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &vce_v4_0_ip_block);
|
||||
}
|
||||
break;
|
||||
case CHIP_RAVEN:
|
||||
amdgpu_device_ip_block_add(adev, &vega10_common_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gmc_v9_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block);
|
||||
if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP))
|
||||
amdgpu_device_ip_block_add(adev, &psp_v10_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
#endif
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v1_0_ip_block);
|
||||
break;
|
||||
case CHIP_ARCTURUS:
|
||||
amdgpu_device_ip_block_add(adev, &vega10_common_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gmc_v9_0_ip_block);
|
||||
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP))
|
||||
amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &vega20_ih_ip_block);
|
||||
} else {
|
||||
amdgpu_device_ip_block_add(adev, &vega20_ih_ip_block);
|
||||
if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP))
|
||||
amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
|
||||
}
|
||||
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP))
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v2_5_ip_block);
|
||||
} else {
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v2_5_ip_block);
|
||||
}
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &jpeg_v2_5_ip_block);
|
||||
break;
|
||||
case CHIP_RENOIR:
|
||||
amdgpu_device_ip_block_add(adev, &vega10_common_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gmc_v9_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block);
|
||||
if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP))
|
||||
amdgpu_device_ip_block_add(adev, &psp_v12_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &smu_v12_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
#endif
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &jpeg_v2_0_ip_block);
|
||||
break;
|
||||
case CHIP_ALDEBARAN:
|
||||
amdgpu_device_ip_block_add(adev, &vega10_common_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gmc_v9_0_ip_block);
|
||||
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP))
|
||||
amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &vega20_ih_ip_block);
|
||||
} else {
|
||||
amdgpu_device_ip_block_add(adev, &vega20_ih_ip_block);
|
||||
if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP))
|
||||
amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block);
|
||||
}
|
||||
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
|
||||
|
||||
amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v2_6_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &jpeg_v2_6_ip_block);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool soc15_need_full_reset(struct amdgpu_device *adev)
|
||||
{
|
||||
/* change this when we implement soft reset */
|
||||
|
||||
@@ -102,7 +102,6 @@ struct soc15_ras_field_entry {
|
||||
void soc15_grbm_select(struct amdgpu_device *adev,
|
||||
u32 me, u32 pipe, u32 queue, u32 vmid);
|
||||
void soc15_set_virt_ops(struct amdgpu_device *adev);
|
||||
int soc15_set_ip_blocks(struct amdgpu_device *adev);
|
||||
|
||||
void soc15_program_register_sequence(struct amdgpu_device *adev,
|
||||
const struct soc15_reg_golden *registers,
|
||||
|
||||
@@ -59,7 +59,12 @@ enum ta_ras_status {
|
||||
TA_RAS_STATUS__ERROR_SYS_DRV_REG_ACCESS = 0xA011,
|
||||
TA_RAS_STATUS__ERROR_RAS_READ_WRITE = 0xA012,
|
||||
TA_RAS_STATUS__ERROR_NULL_PTR = 0xA013,
|
||||
TA_RAS_STATUS__ERROR_UNSUPPORTED_IP = 0xA014
|
||||
TA_RAS_STATUS__ERROR_UNSUPPORTED_IP = 0xA014,
|
||||
TA_RAS_STATUS__ERROR_PCS_STATE_QUIET = 0xA015,
|
||||
TA_RAS_STATUS__ERROR_PCS_STATE_ERROR = 0xA016,
|
||||
TA_RAS_STATUS__ERROR_PCS_STATE_HANG = 0xA017,
|
||||
TA_RAS_STATUS__ERROR_PCS_STATE_UNKNOWN = 0xA018,
|
||||
TA_RAS_STATUS__ERROR_UNSUPPORTED_ERROR_INJ = 0xA019
|
||||
};
|
||||
|
||||
enum ta_ras_block {
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 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 "amdgpu.h"
|
||||
#include "nv.h"
|
||||
|
||||
#include "soc15_common.h"
|
||||
#include "soc15_hw_ip.h"
|
||||
#include "vangogh_ip_offset.h"
|
||||
|
||||
void vangogh_reg_base_init(struct amdgpu_device *adev)
|
||||
{
|
||||
/* HW has more IP blocks, only initialized the blocke needed by driver */
|
||||
uint32_t i;
|
||||
for (i = 0 ; i < MAX_INSTANCE ; ++i) {
|
||||
adev->reg_offset[GC_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[HDP_HWIP][i] = (uint32_t *)(&(HDP_BASE.instance[i]));
|
||||
adev->reg_offset[MMHUB_HWIP][i] = (uint32_t *)(&(MMHUB_BASE.instance[i]));
|
||||
adev->reg_offset[ATHUB_HWIP][i] = (uint32_t *)(&(ATHUB_BASE.instance[i]));
|
||||
adev->reg_offset[NBIO_HWIP][i] = (uint32_t *)(&(NBIO_BASE.instance[i]));
|
||||
adev->reg_offset[MP0_HWIP][i] = (uint32_t *)(&(MP0_BASE.instance[i]));
|
||||
adev->reg_offset[MP1_HWIP][i] = (uint32_t *)(&(MP1_BASE.instance[i]));
|
||||
adev->reg_offset[VCN_HWIP][i] = (uint32_t *)(&(VCN_BASE.instance[i]));
|
||||
adev->reg_offset[DF_HWIP][i] = (uint32_t *)(&(DF_BASE.instance[i]));
|
||||
adev->reg_offset[DCE_HWIP][i] = (uint32_t *)(&(DCN_BASE.instance[i]));
|
||||
adev->reg_offset[OSSSYS_HWIP][i] = (uint32_t *)(&(OSSSYS_BASE.instance[i]));
|
||||
adev->reg_offset[SDMA0_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[SMUIO_HWIP][i] = (uint32_t *)(&(SMUIO_BASE.instance[i]));
|
||||
adev->reg_offset[THM_HWIP][i] = (uint32_t *)(&(THM_BASE.instance[i]));
|
||||
}
|
||||
}
|
||||
@@ -111,15 +111,7 @@ static int vcn_v1_0_sw_init(void *handle)
|
||||
/* Override the work func */
|
||||
adev->vcn.idle_work.work.func = vcn_v1_0_idle_work_handler;
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
const struct common_firmware_header *hdr;
|
||||
hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
|
||||
adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].ucode_id = AMDGPU_UCODE_ID_VCN;
|
||||
adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].fw = adev->vcn.fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE);
|
||||
dev_info(adev->dev, "Will use PSP to load VCN firmware\n");
|
||||
}
|
||||
amdgpu_vcn_setup_ucode(adev);
|
||||
|
||||
r = amdgpu_vcn_resume(adev);
|
||||
if (r)
|
||||
|
||||
@@ -115,15 +115,7 @@ static int vcn_v2_0_sw_init(void *handle)
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
const struct common_firmware_header *hdr;
|
||||
hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
|
||||
adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].ucode_id = AMDGPU_UCODE_ID_VCN;
|
||||
adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].fw = adev->vcn.fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE);
|
||||
dev_info(adev->dev, "Will use PSP to load VCN firmware\n");
|
||||
}
|
||||
amdgpu_vcn_setup_ucode(adev);
|
||||
|
||||
r = amdgpu_vcn_resume(adev);
|
||||
if (r)
|
||||
@@ -1884,15 +1876,14 @@ static int vcn_v2_0_start_sriov(struct amdgpu_device *adev)
|
||||
|
||||
/* mc resume*/
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
tmp = AMDGPU_UCODE_ID_VCN;
|
||||
MMSCH_V2_0_INSERT_DIRECT_WT(
|
||||
SOC15_REG_OFFSET(UVD, i,
|
||||
mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
|
||||
adev->firmware.ucode[tmp].tmr_mc_addr_lo);
|
||||
adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_lo);
|
||||
MMSCH_V2_0_INSERT_DIRECT_WT(
|
||||
SOC15_REG_OFFSET(UVD, i,
|
||||
mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
|
||||
adev->firmware.ucode[tmp].tmr_mc_addr_hi);
|
||||
adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_hi);
|
||||
offset = 0;
|
||||
} else {
|
||||
MMSCH_V2_0_INSERT_DIRECT_WT(
|
||||
|
||||
@@ -139,22 +139,7 @@ static int vcn_v2_5_sw_init(void *handle)
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
const struct common_firmware_header *hdr;
|
||||
hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
|
||||
adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].ucode_id = AMDGPU_UCODE_ID_VCN;
|
||||
adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].fw = adev->vcn.fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE);
|
||||
|
||||
if (adev->vcn.num_vcn_inst == VCN25_MAX_HW_INSTANCES_ARCTURUS) {
|
||||
adev->firmware.ucode[AMDGPU_UCODE_ID_VCN1].ucode_id = AMDGPU_UCODE_ID_VCN1;
|
||||
adev->firmware.ucode[AMDGPU_UCODE_ID_VCN1].fw = adev->vcn.fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE);
|
||||
}
|
||||
dev_info(adev->dev, "Will use PSP to load VCN firmware\n");
|
||||
}
|
||||
amdgpu_vcn_setup_ucode(adev);
|
||||
|
||||
r = amdgpu_vcn_resume(adev);
|
||||
if (r)
|
||||
|
||||
@@ -60,11 +60,6 @@ static int amdgpu_ih_clientid_vcns[] = {
|
||||
SOC15_IH_CLIENTID_VCN1
|
||||
};
|
||||
|
||||
static int amdgpu_ucode_id_vcns[] = {
|
||||
AMDGPU_UCODE_ID_VCN,
|
||||
AMDGPU_UCODE_ID_VCN1
|
||||
};
|
||||
|
||||
static int vcn_v3_0_start_sriov(struct amdgpu_device *adev);
|
||||
static void vcn_v3_0_set_dec_ring_funcs(struct amdgpu_device *adev);
|
||||
static void vcn_v3_0_set_enc_ring_funcs(struct amdgpu_device *adev);
|
||||
@@ -130,22 +125,7 @@ static int vcn_v3_0_sw_init(void *handle)
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
const struct common_firmware_header *hdr;
|
||||
hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
|
||||
adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].ucode_id = AMDGPU_UCODE_ID_VCN;
|
||||
adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].fw = adev->vcn.fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE);
|
||||
|
||||
if (adev->vcn.num_vcn_inst == VCN_INSTANCES_SIENNA_CICHLID) {
|
||||
adev->firmware.ucode[AMDGPU_UCODE_ID_VCN1].ucode_id = AMDGPU_UCODE_ID_VCN1;
|
||||
adev->firmware.ucode[AMDGPU_UCODE_ID_VCN1].fw = adev->vcn.fw;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE);
|
||||
}
|
||||
dev_info(adev->dev, "Will use PSP to load VCN firmware\n");
|
||||
}
|
||||
amdgpu_vcn_setup_ucode(adev);
|
||||
|
||||
r = amdgpu_vcn_resume(adev);
|
||||
if (r)
|
||||
@@ -1293,7 +1273,6 @@ static int vcn_v3_0_start_sriov(struct amdgpu_device *adev)
|
||||
uint32_t param, resp, expected;
|
||||
uint32_t offset, cache_size;
|
||||
uint32_t tmp, timeout;
|
||||
uint32_t id;
|
||||
|
||||
struct amdgpu_mm_table *table = &adev->virt.mm_table;
|
||||
uint32_t *table_loc;
|
||||
@@ -1337,13 +1316,12 @@ static int vcn_v3_0_start_sriov(struct amdgpu_device *adev)
|
||||
cache_size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4);
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
id = amdgpu_ucode_id_vcns[i];
|
||||
MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
|
||||
mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
|
||||
adev->firmware.ucode[id].tmr_mc_addr_lo);
|
||||
adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_lo);
|
||||
MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
|
||||
mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
|
||||
adev->firmware.ucode[id].tmr_mc_addr_hi);
|
||||
adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_hi);
|
||||
offset = 0;
|
||||
MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
|
||||
mmUVD_VCPU_CACHE_OFFSET0),
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 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 "amdgpu.h"
|
||||
#include "nv.h"
|
||||
|
||||
#include "soc15_common.h"
|
||||
#include "soc15_hw_ip.h"
|
||||
#include "yellow_carp_offset.h"
|
||||
|
||||
int yellow_carp_reg_base_init(struct amdgpu_device *adev)
|
||||
{
|
||||
/* HW has more IP blocks, only initialized the block needed by driver */
|
||||
uint32_t i;
|
||||
for (i = 0 ; i < MAX_INSTANCE ; ++i) {
|
||||
adev->reg_offset[GC_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[HDP_HWIP][i] = (uint32_t *)(&(HDP_BASE.instance[i]));
|
||||
adev->reg_offset[MMHUB_HWIP][i] = (uint32_t *)(&(MMHUB_BASE.instance[i]));
|
||||
adev->reg_offset[ATHUB_HWIP][i] = (uint32_t *)(&(ATHUB_BASE.instance[i]));
|
||||
adev->reg_offset[NBIO_HWIP][i] = (uint32_t *)(&(NBIO_BASE.instance[i]));
|
||||
adev->reg_offset[MP0_HWIP][i] = (uint32_t *)(&(MP0_BASE.instance[i]));
|
||||
adev->reg_offset[MP1_HWIP][i] = (uint32_t *)(&(MP1_BASE.instance[i]));
|
||||
adev->reg_offset[VCN_HWIP][i] = (uint32_t *)(&(VCN_BASE.instance[i]));
|
||||
adev->reg_offset[DF_HWIP][i] = (uint32_t *)(&(DF_BASE.instance[i]));
|
||||
adev->reg_offset[DCE_HWIP][i] = (uint32_t *)(&(DCN_BASE.instance[i]));
|
||||
adev->reg_offset[OSSSYS_HWIP][i] = (uint32_t *)(&(OSSSYS_BASE.instance[i]));
|
||||
adev->reg_offset[SDMA0_HWIP][i] = (uint32_t *)(&(SDMA0_BASE.instance[i]));
|
||||
adev->reg_offset[SMUIO_HWIP][i] = (uint32_t *)(&(SMUIO_BASE.instance[i]));
|
||||
adev->reg_offset[THM_HWIP][i] = (uint32_t *)(&(THM_BASE.instance[i]));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1259,6 +1259,23 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep,
|
||||
if (args->size == 0)
|
||||
return -EINVAL;
|
||||
|
||||
#if IS_ENABLED(CONFIG_HSA_AMD_SVM)
|
||||
/* Flush pending deferred work to avoid racing with deferred actions
|
||||
* from previous memory map changes (e.g. munmap).
|
||||
*/
|
||||
svm_range_list_lock_and_flush_work(&p->svms, current->mm);
|
||||
mutex_lock(&p->svms.lock);
|
||||
mmap_write_unlock(current->mm);
|
||||
if (interval_tree_iter_first(&p->svms.objects,
|
||||
args->va_addr >> PAGE_SHIFT,
|
||||
(args->va_addr + args->size - 1) >> PAGE_SHIFT)) {
|
||||
pr_err("Address: 0x%llx already allocated by SVM\n",
|
||||
args->va_addr);
|
||||
mutex_unlock(&p->svms.lock);
|
||||
return -EADDRINUSE;
|
||||
}
|
||||
mutex_unlock(&p->svms.lock);
|
||||
#endif
|
||||
dev = kfd_device_by_id(args->gpu_id);
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -93,7 +93,6 @@ static const struct kfd_device_info carrizo_device_info = {
|
||||
.num_xgmi_sdma_engines = 0,
|
||||
.num_sdma_queues_per_engine = 2,
|
||||
};
|
||||
#endif
|
||||
|
||||
static const struct kfd_device_info raven_device_info = {
|
||||
.asic_family = CHIP_RAVEN,
|
||||
@@ -113,7 +112,9 @@ static const struct kfd_device_info raven_device_info = {
|
||||
.num_xgmi_sdma_engines = 0,
|
||||
.num_sdma_queues_per_engine = 2,
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DRM_AMDGPU_CIK
|
||||
static const struct kfd_device_info hawaii_device_info = {
|
||||
.asic_family = CHIP_HAWAII,
|
||||
.asic_name = "hawaii",
|
||||
@@ -133,6 +134,7 @@ static const struct kfd_device_info hawaii_device_info = {
|
||||
.num_xgmi_sdma_engines = 0,
|
||||
.num_sdma_queues_per_engine = 2,
|
||||
};
|
||||
#endif
|
||||
|
||||
static const struct kfd_device_info tonga_device_info = {
|
||||
.asic_family = CHIP_TONGA,
|
||||
@@ -1021,6 +1023,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
|
||||
kfd_double_confirm_iommu_support(kfd);
|
||||
|
||||
if (kfd_iommu_device_init(kfd)) {
|
||||
kfd->use_iommu_v2 = false;
|
||||
dev_err(kfd_device, "Error initializing iommuv2\n");
|
||||
goto device_iommu_error;
|
||||
}
|
||||
@@ -1029,6 +1032,9 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
|
||||
|
||||
svm_migrate_init((struct amdgpu_device *)kfd->kgd);
|
||||
|
||||
if(kgd2kfd_resume_iommu(kfd))
|
||||
goto device_iommu_error;
|
||||
|
||||
if (kfd_resume(kfd))
|
||||
goto kfd_resume_error;
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/hmm.h>
|
||||
#include <linux/dma-direction.h>
|
||||
@@ -34,6 +33,11 @@
|
||||
#include "kfd_svm.h"
|
||||
#include "kfd_migrate.h"
|
||||
|
||||
#ifdef dev_fmt
|
||||
#undef dev_fmt
|
||||
#endif
|
||||
#define dev_fmt(fmt) "kfd_migrate: %s: " fmt, __func__
|
||||
|
||||
static uint64_t
|
||||
svm_migrate_direct_mapping_addr(struct amdgpu_device *adev, uint64_t addr)
|
||||
{
|
||||
@@ -151,14 +155,14 @@ svm_migrate_copy_memory_gart(struct amdgpu_device *adev, dma_addr_t *sys,
|
||||
gart_d = svm_migrate_direct_mapping_addr(adev, *vram);
|
||||
}
|
||||
if (r) {
|
||||
pr_debug("failed %d to create gart mapping\n", r);
|
||||
dev_err(adev->dev, "fail %d create gart mapping\n", r);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
r = amdgpu_copy_buffer(ring, gart_s, gart_d, size * PAGE_SIZE,
|
||||
NULL, &next, false, true, false);
|
||||
if (r) {
|
||||
pr_debug("failed %d to copy memory\n", r);
|
||||
dev_err(adev->dev, "fail %d to copy memory\n", r);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
@@ -264,6 +268,19 @@ static void svm_migrate_put_sys_page(unsigned long addr)
|
||||
put_page(page);
|
||||
}
|
||||
|
||||
static unsigned long svm_migrate_successful_pages(struct migrate_vma *migrate)
|
||||
{
|
||||
unsigned long cpages = 0;
|
||||
unsigned long i;
|
||||
|
||||
for (i = 0; i < migrate->npages; i++) {
|
||||
if (migrate->src[i] & MIGRATE_PFN_VALID &&
|
||||
migrate->src[i] & MIGRATE_PFN_MIGRATE)
|
||||
cpages++;
|
||||
}
|
||||
return cpages;
|
||||
}
|
||||
|
||||
static int
|
||||
svm_migrate_copy_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
|
||||
struct migrate_vma *migrate, struct dma_fence **mfence,
|
||||
@@ -285,7 +302,7 @@ svm_migrate_copy_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
|
||||
|
||||
r = svm_range_vram_node_new(adev, prange, true);
|
||||
if (r) {
|
||||
pr_debug("failed %d get 0x%llx pages from vram\n", r, npages);
|
||||
dev_err(adev->dev, "fail %d to alloc vram\n", r);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -305,7 +322,7 @@ svm_migrate_copy_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
|
||||
DMA_TO_DEVICE);
|
||||
r = dma_mapping_error(dev, src[i]);
|
||||
if (r) {
|
||||
pr_debug("failed %d dma_map_page\n", r);
|
||||
dev_err(adev->dev, "fail %d dma_map_page\n", r);
|
||||
goto out_free_vram_pages;
|
||||
}
|
||||
} else {
|
||||
@@ -325,8 +342,8 @@ svm_migrate_copy_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
|
||||
continue;
|
||||
}
|
||||
|
||||
pr_debug("dma mapping src to 0x%llx, page_to_pfn 0x%lx\n",
|
||||
src[i] >> PAGE_SHIFT, page_to_pfn(spage));
|
||||
pr_debug_ratelimited("dma mapping src to 0x%llx, pfn 0x%lx\n",
|
||||
src[i] >> PAGE_SHIFT, page_to_pfn(spage));
|
||||
|
||||
if (j >= (cursor.size >> PAGE_SHIFT) - 1 && i < npages - 1) {
|
||||
r = svm_migrate_copy_memory_gart(adev, src + i - j,
|
||||
@@ -372,7 +389,7 @@ svm_migrate_copy_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
static long
|
||||
svm_migrate_vma_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
|
||||
struct vm_area_struct *vma, uint64_t start,
|
||||
uint64_t end)
|
||||
@@ -381,6 +398,7 @@ svm_migrate_vma_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
|
||||
struct kfd_process_device *pdd;
|
||||
struct dma_fence *mfence = NULL;
|
||||
struct migrate_vma migrate;
|
||||
unsigned long cpages = 0;
|
||||
dma_addr_t *scratch;
|
||||
size_t size;
|
||||
void *buf;
|
||||
@@ -405,23 +423,31 @@ svm_migrate_vma_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
|
||||
|
||||
r = migrate_vma_setup(&migrate);
|
||||
if (r) {
|
||||
pr_debug("failed %d prepare migrate svms 0x%p [0x%lx 0x%lx]\n",
|
||||
r, prange->svms, prange->start, prange->last);
|
||||
dev_err(adev->dev, "vma setup fail %d range [0x%lx 0x%lx]\n", r,
|
||||
prange->start, prange->last);
|
||||
goto out_free;
|
||||
}
|
||||
if (migrate.cpages != npages) {
|
||||
pr_debug("Partial migration. 0x%lx/0x%llx pages can be migrated\n",
|
||||
migrate.cpages,
|
||||
npages);
|
||||
}
|
||||
|
||||
if (migrate.cpages) {
|
||||
r = svm_migrate_copy_to_vram(adev, prange, &migrate, &mfence,
|
||||
scratch);
|
||||
migrate_vma_pages(&migrate);
|
||||
svm_migrate_copy_done(adev, mfence);
|
||||
migrate_vma_finalize(&migrate);
|
||||
cpages = migrate.cpages;
|
||||
if (!cpages) {
|
||||
pr_debug("failed collect migrate sys pages [0x%lx 0x%lx]\n",
|
||||
prange->start, prange->last);
|
||||
goto out_free;
|
||||
}
|
||||
if (cpages != npages)
|
||||
pr_debug("partial migration, 0x%lx/0x%llx pages migrated\n",
|
||||
cpages, npages);
|
||||
else
|
||||
pr_debug("0x%lx pages migrated\n", cpages);
|
||||
|
||||
r = svm_migrate_copy_to_vram(adev, prange, &migrate, &mfence, scratch);
|
||||
migrate_vma_pages(&migrate);
|
||||
|
||||
pr_debug("successful/cpages/npages 0x%lx/0x%lx/0x%lx\n",
|
||||
svm_migrate_successful_pages(&migrate), cpages, migrate.npages);
|
||||
|
||||
svm_migrate_copy_done(adev, mfence);
|
||||
migrate_vma_finalize(&migrate);
|
||||
|
||||
svm_range_dma_unmap(adev->dev, scratch, 0, npages);
|
||||
svm_range_free_dma_mappings(prange);
|
||||
@@ -429,12 +455,13 @@ svm_migrate_vma_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
|
||||
out_free:
|
||||
kvfree(buf);
|
||||
out:
|
||||
if (!r) {
|
||||
if (!r && cpages) {
|
||||
pdd = svm_range_get_pdd_by_adev(prange, adev);
|
||||
if (pdd)
|
||||
WRITE_ONCE(pdd->page_in, pdd->page_in + migrate.cpages);
|
||||
}
|
||||
WRITE_ONCE(pdd->page_in, pdd->page_in + cpages);
|
||||
|
||||
return cpages;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -456,7 +483,8 @@ svm_migrate_ram_to_vram(struct svm_range *prange, uint32_t best_loc,
|
||||
unsigned long addr, start, end;
|
||||
struct vm_area_struct *vma;
|
||||
struct amdgpu_device *adev;
|
||||
int r = 0;
|
||||
unsigned long cpages = 0;
|
||||
long r = 0;
|
||||
|
||||
if (prange->actual_loc == best_loc) {
|
||||
pr_debug("svms 0x%p [0x%lx 0x%lx] already on best_loc 0x%x\n",
|
||||
@@ -488,17 +516,19 @@ svm_migrate_ram_to_vram(struct svm_range *prange, uint32_t best_loc,
|
||||
|
||||
next = min(vma->vm_end, end);
|
||||
r = svm_migrate_vma_to_vram(adev, prange, vma, addr, next);
|
||||
if (r) {
|
||||
pr_debug("failed to migrate\n");
|
||||
if (r < 0) {
|
||||
pr_debug("failed %ld to migrate\n", r);
|
||||
break;
|
||||
} else {
|
||||
cpages += r;
|
||||
}
|
||||
addr = next;
|
||||
}
|
||||
|
||||
if (!r)
|
||||
if (cpages)
|
||||
prange->actual_loc = best_loc;
|
||||
|
||||
return r;
|
||||
return r < 0 ? r : 0;
|
||||
}
|
||||
|
||||
static void svm_migrate_page_free(struct page *page)
|
||||
@@ -506,7 +536,7 @@ static void svm_migrate_page_free(struct page *page)
|
||||
struct svm_range_bo *svm_bo = page->zone_device_data;
|
||||
|
||||
if (svm_bo) {
|
||||
pr_debug("svm_bo ref left: %d\n", kref_read(&svm_bo->kref));
|
||||
pr_debug_ratelimited("ref: %d\n", kref_read(&svm_bo->kref));
|
||||
svm_range_bo_unref(svm_bo);
|
||||
}
|
||||
}
|
||||
@@ -572,12 +602,12 @@ svm_migrate_copy_to_ram(struct amdgpu_device *adev, struct svm_range *prange,
|
||||
dst[i] = dma_map_page(dev, dpage, 0, PAGE_SIZE, DMA_FROM_DEVICE);
|
||||
r = dma_mapping_error(dev, dst[i]);
|
||||
if (r) {
|
||||
pr_debug("failed %d dma_map_page\n", r);
|
||||
dev_err(adev->dev, "fail %d dma_map_page\n", r);
|
||||
goto out_oom;
|
||||
}
|
||||
|
||||
pr_debug("dma mapping dst to 0x%llx, page_to_pfn 0x%lx\n",
|
||||
dst[i] >> PAGE_SHIFT, page_to_pfn(dpage));
|
||||
pr_debug_ratelimited("dma mapping dst to 0x%llx, pfn 0x%lx\n",
|
||||
dst[i] >> PAGE_SHIFT, page_to_pfn(dpage));
|
||||
|
||||
migrate->dst[i] = migrate_pfn(page_to_pfn(dpage));
|
||||
migrate->dst[i] |= MIGRATE_PFN_LOCKED;
|
||||
@@ -599,7 +629,7 @@ svm_migrate_copy_to_ram(struct amdgpu_device *adev, struct svm_range *prange,
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
static long
|
||||
svm_migrate_vma_to_ram(struct amdgpu_device *adev, struct svm_range *prange,
|
||||
struct vm_area_struct *vma, uint64_t start, uint64_t end)
|
||||
{
|
||||
@@ -607,6 +637,7 @@ svm_migrate_vma_to_ram(struct amdgpu_device *adev, struct svm_range *prange,
|
||||
struct kfd_process_device *pdd;
|
||||
struct dma_fence *mfence = NULL;
|
||||
struct migrate_vma migrate;
|
||||
unsigned long cpages = 0;
|
||||
dma_addr_t *scratch;
|
||||
size_t size;
|
||||
void *buf;
|
||||
@@ -631,34 +662,43 @@ svm_migrate_vma_to_ram(struct amdgpu_device *adev, struct svm_range *prange,
|
||||
|
||||
r = migrate_vma_setup(&migrate);
|
||||
if (r) {
|
||||
pr_debug("failed %d prepare migrate svms 0x%p [0x%lx 0x%lx]\n",
|
||||
r, prange->svms, prange->start, prange->last);
|
||||
dev_err(adev->dev, "vma setup fail %d range [0x%lx 0x%lx]\n", r,
|
||||
prange->start, prange->last);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
pr_debug("cpages %ld\n", migrate.cpages);
|
||||
|
||||
if (migrate.cpages) {
|
||||
r = svm_migrate_copy_to_ram(adev, prange, &migrate, &mfence,
|
||||
scratch, npages);
|
||||
migrate_vma_pages(&migrate);
|
||||
svm_migrate_copy_done(adev, mfence);
|
||||
migrate_vma_finalize(&migrate);
|
||||
} else {
|
||||
cpages = migrate.cpages;
|
||||
if (!cpages) {
|
||||
pr_debug("failed collect migrate device pages [0x%lx 0x%lx]\n",
|
||||
prange->start, prange->last);
|
||||
goto out_free;
|
||||
}
|
||||
if (cpages != npages)
|
||||
pr_debug("partial migration, 0x%lx/0x%llx pages migrated\n",
|
||||
cpages, npages);
|
||||
else
|
||||
pr_debug("0x%lx pages migrated\n", cpages);
|
||||
|
||||
r = svm_migrate_copy_to_ram(adev, prange, &migrate, &mfence,
|
||||
scratch, npages);
|
||||
migrate_vma_pages(&migrate);
|
||||
|
||||
pr_debug("successful/cpages/npages 0x%lx/0x%lx/0x%lx\n",
|
||||
svm_migrate_successful_pages(&migrate), cpages, migrate.npages);
|
||||
|
||||
svm_migrate_copy_done(adev, mfence);
|
||||
migrate_vma_finalize(&migrate);
|
||||
svm_range_dma_unmap(adev->dev, scratch, 0, npages);
|
||||
|
||||
out_free:
|
||||
kvfree(buf);
|
||||
out:
|
||||
if (!r) {
|
||||
if (!r && cpages) {
|
||||
pdd = svm_range_get_pdd_by_adev(prange, adev);
|
||||
if (pdd)
|
||||
WRITE_ONCE(pdd->page_out,
|
||||
pdd->page_out + migrate.cpages);
|
||||
WRITE_ONCE(pdd->page_out, pdd->page_out + cpages);
|
||||
|
||||
return cpages;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
@@ -680,7 +720,8 @@ int svm_migrate_vram_to_ram(struct svm_range *prange, struct mm_struct *mm)
|
||||
unsigned long addr;
|
||||
unsigned long start;
|
||||
unsigned long end;
|
||||
int r = 0;
|
||||
unsigned long cpages = 0;
|
||||
long r = 0;
|
||||
|
||||
if (!prange->actual_loc) {
|
||||
pr_debug("[0x%lx 0x%lx] already migrated to ram\n",
|
||||
@@ -711,18 +752,21 @@ int svm_migrate_vram_to_ram(struct svm_range *prange, struct mm_struct *mm)
|
||||
|
||||
next = min(vma->vm_end, end);
|
||||
r = svm_migrate_vma_to_ram(adev, prange, vma, addr, next);
|
||||
if (r) {
|
||||
pr_debug("failed %d to migrate\n", r);
|
||||
if (r < 0) {
|
||||
pr_debug("failed %ld to migrate\n", r);
|
||||
break;
|
||||
} else {
|
||||
cpages += r;
|
||||
}
|
||||
addr = next;
|
||||
}
|
||||
|
||||
if (!r) {
|
||||
if (cpages) {
|
||||
svm_range_vram_node_free(prange);
|
||||
prange->actual_loc = 0;
|
||||
}
|
||||
return r;
|
||||
|
||||
return r < 0 ? r : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,6 +33,11 @@
|
||||
#include "kfd_svm.h"
|
||||
#include "kfd_migrate.h"
|
||||
|
||||
#ifdef dev_fmt
|
||||
#undef dev_fmt
|
||||
#endif
|
||||
#define dev_fmt(fmt) "kfd_svm: %s: " fmt, __func__
|
||||
|
||||
#define AMDGPU_SVM_RANGE_RESTORE_DELAY_MS 1
|
||||
|
||||
/* Long enough to ensure no retry fault comes after svm range is restored and
|
||||
@@ -45,7 +50,9 @@ static bool
|
||||
svm_range_cpu_invalidate_pagetables(struct mmu_interval_notifier *mni,
|
||||
const struct mmu_notifier_range *range,
|
||||
unsigned long cur_seq);
|
||||
|
||||
static int
|
||||
svm_range_check_vm(struct kfd_process *p, uint64_t start, uint64_t last,
|
||||
uint64_t *bo_s, uint64_t *bo_l);
|
||||
static const struct mmu_interval_notifier_ops svm_range_mn_ops = {
|
||||
.invalidate = svm_range_cpu_invalidate_pagetables,
|
||||
};
|
||||
@@ -158,17 +165,17 @@ svm_range_dma_map_dev(struct amdgpu_device *adev, struct svm_range *prange,
|
||||
bo_adev->vm_manager.vram_base_offset -
|
||||
bo_adev->kfd.dev->pgmap.range.start;
|
||||
addr[i] |= SVM_RANGE_VRAM_DOMAIN;
|
||||
pr_debug("vram address detected: 0x%llx\n", addr[i]);
|
||||
pr_debug_ratelimited("vram address: 0x%llx\n", addr[i]);
|
||||
continue;
|
||||
}
|
||||
addr[i] = dma_map_page(dev, page, 0, PAGE_SIZE, dir);
|
||||
r = dma_mapping_error(dev, addr[i]);
|
||||
if (r) {
|
||||
pr_debug("failed %d dma_map_page\n", r);
|
||||
dev_err(dev, "failed %d dma_map_page\n", r);
|
||||
return r;
|
||||
}
|
||||
pr_debug("dma mapping 0x%llx for page addr 0x%lx\n",
|
||||
addr[i] >> PAGE_SHIFT, page_to_pfn(page));
|
||||
pr_debug_ratelimited("dma mapping 0x%llx for page addr 0x%lx\n",
|
||||
addr[i] >> PAGE_SHIFT, page_to_pfn(page));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -217,7 +224,7 @@ void svm_range_dma_unmap(struct device *dev, dma_addr_t *dma_addr,
|
||||
for (i = offset; i < offset + npages; i++) {
|
||||
if (!svm_is_valid_dma_mapping_addr(dev, dma_addr[i]))
|
||||
continue;
|
||||
pr_debug("dma unmapping 0x%llx\n", dma_addr[i] >> PAGE_SHIFT);
|
||||
pr_debug_ratelimited("unmap 0x%llx\n", dma_addr[i] >> PAGE_SHIFT);
|
||||
dma_unmap_page(dev, dma_addr[i], PAGE_SIZE, dir);
|
||||
dma_addr[i] = 0;
|
||||
}
|
||||
@@ -1454,7 +1461,7 @@ static int svm_range_validate_and_map(struct mm_struct *mm,
|
||||
/* This should never happen. actual_loc gets set by
|
||||
* svm_migrate_ram_to_vram after allocating a BO.
|
||||
*/
|
||||
WARN(1, "VRAM BO missing during validation\n");
|
||||
WARN_ONCE(1, "VRAM BO missing during validation\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -1547,7 +1554,7 @@ static int svm_range_validate_and_map(struct mm_struct *mm,
|
||||
* Context: Returns with mmap write lock held, pending deferred work flushed
|
||||
*
|
||||
*/
|
||||
static void
|
||||
void
|
||||
svm_range_list_lock_and_flush_work(struct svm_range_list *svms,
|
||||
struct mm_struct *mm)
|
||||
{
|
||||
@@ -2303,6 +2310,7 @@ svm_range_best_restore_location(struct svm_range *prange,
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
svm_range_get_range_boundaries(struct kfd_process *p, int64_t addr,
|
||||
unsigned long *start, unsigned long *last)
|
||||
@@ -2350,8 +2358,59 @@ svm_range_get_range_boundaries(struct kfd_process *p, int64_t addr,
|
||||
vma->vm_end >> PAGE_SHIFT, *last);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
svm_range_check_vm_userptr(struct kfd_process *p, uint64_t start, uint64_t last,
|
||||
uint64_t *bo_s, uint64_t *bo_l)
|
||||
{
|
||||
struct amdgpu_bo_va_mapping *mapping;
|
||||
struct interval_tree_node *node;
|
||||
struct amdgpu_bo *bo = NULL;
|
||||
unsigned long userptr;
|
||||
uint32_t i;
|
||||
int r;
|
||||
|
||||
for (i = 0; i < p->n_pdds; i++) {
|
||||
struct amdgpu_vm *vm;
|
||||
|
||||
if (!p->pdds[i]->drm_priv)
|
||||
continue;
|
||||
|
||||
vm = drm_priv_to_vm(p->pdds[i]->drm_priv);
|
||||
r = amdgpu_bo_reserve(vm->root.bo, false);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* Check userptr by searching entire vm->va interval tree */
|
||||
node = interval_tree_iter_first(&vm->va, 0, ~0ULL);
|
||||
while (node) {
|
||||
mapping = container_of((struct rb_node *)node,
|
||||
struct amdgpu_bo_va_mapping, rb);
|
||||
bo = mapping->bo_va->base.bo;
|
||||
|
||||
if (!amdgpu_ttm_tt_affect_userptr(bo->tbo.ttm,
|
||||
start << PAGE_SHIFT,
|
||||
last << PAGE_SHIFT,
|
||||
&userptr)) {
|
||||
node = interval_tree_iter_next(node, 0, ~0ULL);
|
||||
continue;
|
||||
}
|
||||
|
||||
pr_debug("[0x%llx 0x%llx] already userptr mapped\n",
|
||||
start, last);
|
||||
if (bo_s && bo_l) {
|
||||
*bo_s = userptr >> PAGE_SHIFT;
|
||||
*bo_l = *bo_s + bo->tbo.ttm->num_pages - 1;
|
||||
}
|
||||
amdgpu_bo_unreserve(vm->root.bo);
|
||||
return -EADDRINUSE;
|
||||
}
|
||||
amdgpu_bo_unreserve(vm->root.bo);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct
|
||||
svm_range *svm_range_create_unregistered_range(struct amdgpu_device *adev,
|
||||
struct kfd_process *p,
|
||||
@@ -2361,10 +2420,26 @@ svm_range *svm_range_create_unregistered_range(struct amdgpu_device *adev,
|
||||
struct svm_range *prange = NULL;
|
||||
unsigned long start, last;
|
||||
uint32_t gpuid, gpuidx;
|
||||
uint64_t bo_s = 0;
|
||||
uint64_t bo_l = 0;
|
||||
int r;
|
||||
|
||||
if (svm_range_get_range_boundaries(p, addr, &start, &last))
|
||||
return NULL;
|
||||
|
||||
r = svm_range_check_vm(p, start, last, &bo_s, &bo_l);
|
||||
if (r != -EADDRINUSE)
|
||||
r = svm_range_check_vm_userptr(p, start, last, &bo_s, &bo_l);
|
||||
|
||||
if (r == -EADDRINUSE) {
|
||||
if (addr >= bo_s && addr <= bo_l)
|
||||
return NULL;
|
||||
|
||||
/* Create one page svm range if 2MB range overlapping */
|
||||
start = addr;
|
||||
last = addr;
|
||||
}
|
||||
|
||||
prange = svm_range_new(&p->svms, start, last);
|
||||
if (!prange) {
|
||||
pr_debug("Failed to create prange in address [0x%llx]\n", addr);
|
||||
@@ -2662,9 +2737,68 @@ int svm_range_list_init(struct kfd_process *p)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* svm_range_check_vm - check if virtual address range mapped already
|
||||
* @p: current kfd_process
|
||||
* @start: range start address, in pages
|
||||
* @last: range last address, in pages
|
||||
* @bo_s: mapping start address in pages if address range already mapped
|
||||
* @bo_l: mapping last address in pages if address range already mapped
|
||||
*
|
||||
* The purpose is to avoid virtual address ranges already allocated by
|
||||
* kfd_ioctl_alloc_memory_of_gpu ioctl.
|
||||
* It looks for each pdd in the kfd_process.
|
||||
*
|
||||
* Context: Process context
|
||||
*
|
||||
* Return 0 - OK, if the range is not mapped.
|
||||
* Otherwise error code:
|
||||
* -EADDRINUSE - if address is mapped already by kfd_ioctl_alloc_memory_of_gpu
|
||||
* -ERESTARTSYS - A wait for the buffer to become unreserved was interrupted by
|
||||
* a signal. Release all buffer reservations and return to user-space.
|
||||
*/
|
||||
static int
|
||||
svm_range_check_vm(struct kfd_process *p, uint64_t start, uint64_t last,
|
||||
uint64_t *bo_s, uint64_t *bo_l)
|
||||
{
|
||||
struct amdgpu_bo_va_mapping *mapping;
|
||||
struct interval_tree_node *node;
|
||||
uint32_t i;
|
||||
int r;
|
||||
|
||||
for (i = 0; i < p->n_pdds; i++) {
|
||||
struct amdgpu_vm *vm;
|
||||
|
||||
if (!p->pdds[i]->drm_priv)
|
||||
continue;
|
||||
|
||||
vm = drm_priv_to_vm(p->pdds[i]->drm_priv);
|
||||
r = amdgpu_bo_reserve(vm->root.bo, false);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
node = interval_tree_iter_first(&vm->va, start, last);
|
||||
if (node) {
|
||||
pr_debug("range [0x%llx 0x%llx] already TTM mapped\n",
|
||||
start, last);
|
||||
mapping = container_of((struct rb_node *)node,
|
||||
struct amdgpu_bo_va_mapping, rb);
|
||||
if (bo_s && bo_l) {
|
||||
*bo_s = mapping->start;
|
||||
*bo_l = mapping->last;
|
||||
}
|
||||
amdgpu_bo_unreserve(vm->root.bo);
|
||||
return -EADDRINUSE;
|
||||
}
|
||||
amdgpu_bo_unreserve(vm->root.bo);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* svm_range_is_valid - check if virtual address range is valid
|
||||
* @mm: current process mm_struct
|
||||
* @p: current kfd_process
|
||||
* @start: range start address, in pages
|
||||
* @size: range size, in pages
|
||||
*
|
||||
@@ -2673,28 +2807,28 @@ int svm_range_list_init(struct kfd_process *p)
|
||||
* Context: Process context
|
||||
*
|
||||
* Return:
|
||||
* true - valid svm range
|
||||
* false - invalid svm range
|
||||
* 0 - OK, otherwise error code
|
||||
*/
|
||||
static bool
|
||||
svm_range_is_valid(struct mm_struct *mm, uint64_t start, uint64_t size)
|
||||
static int
|
||||
svm_range_is_valid(struct kfd_process *p, uint64_t start, uint64_t size)
|
||||
{
|
||||
const unsigned long device_vma = VM_IO | VM_PFNMAP | VM_MIXEDMAP;
|
||||
struct vm_area_struct *vma;
|
||||
unsigned long end;
|
||||
unsigned long start_unchg = start;
|
||||
|
||||
start <<= PAGE_SHIFT;
|
||||
end = start + (size << PAGE_SHIFT);
|
||||
|
||||
do {
|
||||
vma = find_vma(mm, start);
|
||||
vma = find_vma(p->mm, start);
|
||||
if (!vma || start < vma->vm_start ||
|
||||
(vma->vm_flags & device_vma))
|
||||
return false;
|
||||
return -EFAULT;
|
||||
start = min(end, vma->vm_end);
|
||||
} while (start < end);
|
||||
|
||||
return true;
|
||||
return svm_range_check_vm(p, start_unchg, (end - 1) >> PAGE_SHIFT, NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2997,9 +3131,9 @@ svm_range_set_attr(struct kfd_process *p, uint64_t start, uint64_t size,
|
||||
|
||||
svm_range_list_lock_and_flush_work(svms, mm);
|
||||
|
||||
if (!svm_range_is_valid(mm, start, size)) {
|
||||
pr_debug("invalid range\n");
|
||||
r = -EFAULT;
|
||||
r = svm_range_is_valid(p, start, size);
|
||||
if (r) {
|
||||
pr_debug("invalid range r=%d\n", r);
|
||||
mmap_write_unlock(mm);
|
||||
goto out;
|
||||
}
|
||||
@@ -3101,6 +3235,7 @@ svm_range_get_attr(struct kfd_process *p, uint64_t start, uint64_t size,
|
||||
uint32_t flags_or = 0;
|
||||
int gpuidx;
|
||||
uint32_t i;
|
||||
int r = 0;
|
||||
|
||||
pr_debug("svms 0x%p [0x%llx 0x%llx] nattr 0x%x\n", &p->svms, start,
|
||||
start + size - 1, nattr);
|
||||
@@ -3114,12 +3249,12 @@ svm_range_get_attr(struct kfd_process *p, uint64_t start, uint64_t size,
|
||||
flush_work(&p->svms.deferred_list_work);
|
||||
|
||||
mmap_read_lock(mm);
|
||||
if (!svm_range_is_valid(mm, start, size)) {
|
||||
pr_debug("invalid range\n");
|
||||
mmap_read_unlock(mm);
|
||||
return -EINVAL;
|
||||
}
|
||||
r = svm_range_is_valid(p, start, size);
|
||||
mmap_read_unlock(mm);
|
||||
if (r) {
|
||||
pr_debug("invalid range r=%d\n", r);
|
||||
return r;
|
||||
}
|
||||
|
||||
for (i = 0; i < nattr; i++) {
|
||||
switch (attrs[i].type) {
|
||||
|
||||
@@ -188,6 +188,7 @@ void svm_range_prefault(struct svm_range *prange, struct mm_struct *mm,
|
||||
void *owner);
|
||||
struct kfd_process_device *
|
||||
svm_range_get_pdd_by_adev(struct svm_range *prange, struct amdgpu_device *adev);
|
||||
void svm_range_list_lock_and_flush_work(struct svm_range_list *svms, struct mm_struct *mm);
|
||||
|
||||
/* SVM API and HMM page migration work together, device memory type
|
||||
* is initialized to not 0 when page migration register device memory.
|
||||
|
||||
@@ -1296,6 +1296,24 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
|
||||
|
||||
proximity_domain = atomic_inc_return(&topology_crat_proximity_domain);
|
||||
|
||||
adev = (struct amdgpu_device *)(gpu->kgd);
|
||||
|
||||
/* Include the CPU in xGMI hive if xGMI connected by assigning it the hive ID. */
|
||||
if (gpu->hive_id && adev->gmc.xgmi.connected_to_cpu) {
|
||||
struct kfd_topology_device *top_dev;
|
||||
|
||||
down_read(&topology_lock);
|
||||
|
||||
list_for_each_entry(top_dev, &topology_device_list, list) {
|
||||
if (top_dev->gpu)
|
||||
break;
|
||||
|
||||
top_dev->node_props.hive_id = gpu->hive_id;
|
||||
}
|
||||
|
||||
up_read(&topology_lock);
|
||||
}
|
||||
|
||||
/* Check to see if this gpu device exists in the topology_device_list.
|
||||
* If so, assign the gpu to that device,
|
||||
* else create a Virtual CRAT for this gpu device and then parse that
|
||||
@@ -1457,7 +1475,6 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
|
||||
dev->node_props.max_waves_per_simd = 10;
|
||||
}
|
||||
|
||||
adev = (struct amdgpu_device *)(dev->gpu->kgd);
|
||||
/* kfd only concerns sram ecc on GFX and HBM ecc on UMC */
|
||||
dev->node_props.capability |=
|
||||
((adev->ras_enabled & BIT(AMDGPU_RAS_BLOCK__GFX)) != 0) ?
|
||||
|
||||
@@ -1356,8 +1356,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
|
||||
switch (adev->ip_versions[DCE_HWIP][0]) {
|
||||
case IP_VERSION(2, 1, 0):
|
||||
init_data.flags.gpu_vm_support = true;
|
||||
if (ASICREV_IS_GREEN_SARDINE(adev->external_rev_id))
|
||||
init_data.flags.disable_dmcu = true;
|
||||
init_data.flags.disable_dmcu = true;
|
||||
break;
|
||||
case IP_VERSION(1, 0, 0):
|
||||
case IP_VERSION(1, 0, 1):
|
||||
@@ -4031,6 +4030,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
|
||||
int32_t primary_planes;
|
||||
enum dc_connection_type new_connection_type = dc_connection_none;
|
||||
const struct dc_plane_cap *plane;
|
||||
bool psr_feature_enabled = false;
|
||||
|
||||
dm->display_indexes_num = dm->dc->caps.max_streams;
|
||||
/* Update the actual used number of crtc */
|
||||
@@ -4113,6 +4113,19 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
|
||||
DRM_DEBUG_KMS("Unsupported DCN IP version for outbox: 0x%X\n",
|
||||
adev->ip_versions[DCE_HWIP][0]);
|
||||
}
|
||||
|
||||
/* Determine whether to enable PSR support by default. */
|
||||
if (!(amdgpu_dc_debug_mask & DC_DISABLE_PSR)) {
|
||||
switch (adev->ip_versions[DCE_HWIP][0]) {
|
||||
case IP_VERSION(3, 1, 2):
|
||||
case IP_VERSION(3, 1, 3):
|
||||
psr_feature_enabled = true;
|
||||
break;
|
||||
default:
|
||||
psr_feature_enabled = amdgpu_dc_feature_mask & DC_PSR_MASK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* loops over all connectors on the board */
|
||||
@@ -4156,7 +4169,8 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
|
||||
} else if (dc_link_detect(link, DETECT_REASON_BOOT)) {
|
||||
amdgpu_dm_update_connector_after_detect(aconnector);
|
||||
register_backlight_device(dm, link);
|
||||
if (amdgpu_dc_feature_mask & DC_PSR_MASK)
|
||||
|
||||
if (psr_feature_enabled)
|
||||
amdgpu_dm_set_psr_caps(link);
|
||||
}
|
||||
|
||||
@@ -10535,18 +10549,18 @@ static int dm_check_crtc_cursor(struct drm_atomic_state *state,
|
||||
struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *new_crtc_state)
|
||||
{
|
||||
struct drm_plane_state *new_cursor_state, *new_primary_state;
|
||||
int cursor_scale_w, cursor_scale_h, primary_scale_w, primary_scale_h;
|
||||
struct drm_plane *cursor = crtc->cursor, *underlying;
|
||||
struct drm_plane_state *new_cursor_state, *new_underlying_state;
|
||||
int i;
|
||||
int cursor_scale_w, cursor_scale_h, underlying_scale_w, underlying_scale_h;
|
||||
|
||||
/* On DCE and DCN there is no dedicated hardware cursor plane. We get a
|
||||
* cursor per pipe but it's going to inherit the scaling and
|
||||
* positioning from the underlying pipe. Check the cursor plane's
|
||||
* blending properties match the primary plane's. */
|
||||
* blending properties match the underlying planes'. */
|
||||
|
||||
new_cursor_state = drm_atomic_get_new_plane_state(state, crtc->cursor);
|
||||
new_primary_state = drm_atomic_get_new_plane_state(state, crtc->primary);
|
||||
if (!new_cursor_state || !new_primary_state ||
|
||||
!new_cursor_state->fb || !new_primary_state->fb) {
|
||||
new_cursor_state = drm_atomic_get_new_plane_state(state, cursor);
|
||||
if (!new_cursor_state || !new_cursor_state->fb) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -10555,15 +10569,34 @@ static int dm_check_crtc_cursor(struct drm_atomic_state *state,
|
||||
cursor_scale_h = new_cursor_state->crtc_h * 1000 /
|
||||
(new_cursor_state->src_h >> 16);
|
||||
|
||||
primary_scale_w = new_primary_state->crtc_w * 1000 /
|
||||
(new_primary_state->src_w >> 16);
|
||||
primary_scale_h = new_primary_state->crtc_h * 1000 /
|
||||
(new_primary_state->src_h >> 16);
|
||||
for_each_new_plane_in_state_reverse(state, underlying, new_underlying_state, i) {
|
||||
/* Narrow down to non-cursor planes on the same CRTC as the cursor */
|
||||
if (new_underlying_state->crtc != crtc || underlying == crtc->cursor)
|
||||
continue;
|
||||
|
||||
if (cursor_scale_w != primary_scale_w ||
|
||||
cursor_scale_h != primary_scale_h) {
|
||||
drm_dbg_atomic(crtc->dev, "Cursor plane scaling doesn't match primary plane\n");
|
||||
return -EINVAL;
|
||||
/* Ignore disabled planes */
|
||||
if (!new_underlying_state->fb)
|
||||
continue;
|
||||
|
||||
underlying_scale_w = new_underlying_state->crtc_w * 1000 /
|
||||
(new_underlying_state->src_w >> 16);
|
||||
underlying_scale_h = new_underlying_state->crtc_h * 1000 /
|
||||
(new_underlying_state->src_h >> 16);
|
||||
|
||||
if (cursor_scale_w != underlying_scale_w ||
|
||||
cursor_scale_h != underlying_scale_h) {
|
||||
drm_dbg_atomic(crtc->dev,
|
||||
"Cursor [PLANE:%d:%s] scaling doesn't match underlying [PLANE:%d:%s]\n",
|
||||
cursor->base.id, cursor->name, underlying->base.id, underlying->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* If this plane covers the whole CRTC, no need to check planes underneath */
|
||||
if (new_underlying_state->crtc_x <= 0 &&
|
||||
new_underlying_state->crtc_y <= 0 &&
|
||||
new_underlying_state->crtc_x + new_underlying_state->crtc_w >= new_crtc_state->mode.hdisplay &&
|
||||
new_underlying_state->crtc_y + new_underlying_state->crtc_h >= new_crtc_state->mode.vdisplay)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -10594,53 +10627,6 @@ static int add_affected_mst_dsc_crtcs(struct drm_atomic_state *state, struct drm
|
||||
}
|
||||
#endif
|
||||
|
||||
static int validate_overlay(struct drm_atomic_state *state)
|
||||
{
|
||||
int i;
|
||||
struct drm_plane *plane;
|
||||
struct drm_plane_state *new_plane_state;
|
||||
struct drm_plane_state *primary_state, *overlay_state = NULL;
|
||||
|
||||
/* Check if primary plane is contained inside overlay */
|
||||
for_each_new_plane_in_state_reverse(state, plane, new_plane_state, i) {
|
||||
if (plane->type == DRM_PLANE_TYPE_OVERLAY) {
|
||||
if (drm_atomic_plane_disabling(plane->state, new_plane_state))
|
||||
return 0;
|
||||
|
||||
overlay_state = new_plane_state;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* check if we're making changes to the overlay plane */
|
||||
if (!overlay_state)
|
||||
return 0;
|
||||
|
||||
/* check if overlay plane is enabled */
|
||||
if (!overlay_state->crtc)
|
||||
return 0;
|
||||
|
||||
/* find the primary plane for the CRTC that the overlay is enabled on */
|
||||
primary_state = drm_atomic_get_plane_state(state, overlay_state->crtc->primary);
|
||||
if (IS_ERR(primary_state))
|
||||
return PTR_ERR(primary_state);
|
||||
|
||||
/* check if primary plane is enabled */
|
||||
if (!primary_state->crtc)
|
||||
return 0;
|
||||
|
||||
/* Perform the bounds check to ensure the overlay plane covers the primary */
|
||||
if (primary_state->crtc_x < overlay_state->crtc_x ||
|
||||
primary_state->crtc_y < overlay_state->crtc_y ||
|
||||
primary_state->crtc_x + primary_state->crtc_w > overlay_state->crtc_x + overlay_state->crtc_w ||
|
||||
primary_state->crtc_y + primary_state->crtc_h > overlay_state->crtc_y + overlay_state->crtc_h) {
|
||||
DRM_DEBUG_ATOMIC("Overlay plane is enabled with hardware cursor but does not fully cover primary plane\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_dm_atomic_check() - Atomic check implementation for AMDgpu DM.
|
||||
* @dev: The DRM device
|
||||
@@ -10822,10 +10808,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = validate_overlay(state);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
/* Add new/modified planes */
|
||||
for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) {
|
||||
ret = dm_update_plane_state(dc, state, plane,
|
||||
|
||||
@@ -264,7 +264,7 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf,
|
||||
if (!wr_buf)
|
||||
return -ENOSPC;
|
||||
|
||||
if (parse_write_buffer_into_params(wr_buf, size,
|
||||
if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
|
||||
(long *)param, buf,
|
||||
max_param_num,
|
||||
¶m_nums)) {
|
||||
|
||||
@@ -99,6 +99,10 @@ static enum bp_result get_firmware_info_v3_2(
|
||||
struct bios_parser *bp,
|
||||
struct dc_firmware_info *info);
|
||||
|
||||
static enum bp_result get_firmware_info_v3_4(
|
||||
struct bios_parser *bp,
|
||||
struct dc_firmware_info *info);
|
||||
|
||||
static struct atom_hpd_int_record *get_hpd_record(struct bios_parser *bp,
|
||||
struct atom_display_object_path_v2 *object);
|
||||
|
||||
@@ -1426,8 +1430,10 @@ static enum bp_result bios_parser_get_firmware_info(
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
result = get_firmware_info_v3_2(bp, info);
|
||||
break;
|
||||
case 4:
|
||||
result = get_firmware_info_v3_4(bp, info);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -1575,6 +1581,88 @@ static enum bp_result get_firmware_info_v3_2(
|
||||
return BP_RESULT_OK;
|
||||
}
|
||||
|
||||
static enum bp_result get_firmware_info_v3_4(
|
||||
struct bios_parser *bp,
|
||||
struct dc_firmware_info *info)
|
||||
{
|
||||
struct atom_firmware_info_v3_4 *firmware_info;
|
||||
struct atom_common_table_header *header;
|
||||
struct atom_data_revision revision;
|
||||
struct atom_display_controller_info_v4_1 *dce_info_v4_1 = NULL;
|
||||
struct atom_display_controller_info_v4_4 *dce_info_v4_4 = NULL;
|
||||
if (!info)
|
||||
return BP_RESULT_BADINPUT;
|
||||
|
||||
firmware_info = GET_IMAGE(struct atom_firmware_info_v3_4,
|
||||
DATA_TABLES(firmwareinfo));
|
||||
|
||||
if (!firmware_info)
|
||||
return BP_RESULT_BADBIOSTABLE;
|
||||
|
||||
memset(info, 0, sizeof(*info));
|
||||
|
||||
header = GET_IMAGE(struct atom_common_table_header,
|
||||
DATA_TABLES(dce_info));
|
||||
|
||||
get_atom_data_table_revision(header, &revision);
|
||||
|
||||
switch (revision.major) {
|
||||
case 4:
|
||||
switch (revision.minor) {
|
||||
case 4:
|
||||
dce_info_v4_4 = GET_IMAGE(struct atom_display_controller_info_v4_4,
|
||||
DATA_TABLES(dce_info));
|
||||
|
||||
if (!dce_info_v4_4)
|
||||
return BP_RESULT_BADBIOSTABLE;
|
||||
|
||||
/* 100MHz expected */
|
||||
info->pll_info.crystal_frequency = dce_info_v4_4->dce_refclk_10khz * 10;
|
||||
info->dp_phy_ref_clk = dce_info_v4_4->dpphy_refclk_10khz * 10;
|
||||
/* 50MHz expected */
|
||||
info->i2c_engine_ref_clk = dce_info_v4_4->i2c_engine_refclk_10khz * 10;
|
||||
|
||||
/* Get SMU Display PLL VCO Frequency in KHz*/
|
||||
info->smu_gpu_pll_output_freq = dce_info_v4_4->dispclk_pll_vco_freq * 10;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* should not come here, keep as backup, as was before */
|
||||
dce_info_v4_1 = GET_IMAGE(struct atom_display_controller_info_v4_1,
|
||||
DATA_TABLES(dce_info));
|
||||
|
||||
if (!dce_info_v4_1)
|
||||
return BP_RESULT_BADBIOSTABLE;
|
||||
|
||||
info->pll_info.crystal_frequency = dce_info_v4_1->dce_refclk_10khz * 10;
|
||||
info->dp_phy_ref_clk = dce_info_v4_1->dpphy_refclk_10khz * 10;
|
||||
info->i2c_engine_ref_clk = dce_info_v4_1->i2c_engine_refclk_10khz * 10;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
header = GET_IMAGE(struct atom_common_table_header,
|
||||
DATA_TABLES(smu_info));
|
||||
get_atom_data_table_revision(header, &revision);
|
||||
|
||||
// We need to convert from 10KHz units into KHz units.
|
||||
info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10;
|
||||
|
||||
if (firmware_info->board_i2c_feature_id == 0x2) {
|
||||
info->oem_i2c_present = true;
|
||||
info->oem_i2c_obj_id = firmware_info->board_i2c_feature_gpio_id;
|
||||
} else {
|
||||
info->oem_i2c_present = false;
|
||||
}
|
||||
|
||||
return BP_RESULT_OK;
|
||||
}
|
||||
|
||||
static enum bp_result bios_parser_get_encoder_cap_info(
|
||||
struct dc_bios *dcb,
|
||||
struct graphics_object_id object_id,
|
||||
|
||||
@@ -219,14 +219,17 @@ static void dcn31_update_clocks(struct clk_mgr *clk_mgr_base,
|
||||
update_dispclk = true;
|
||||
}
|
||||
|
||||
/* TODO: add back DTO programming when DPPCLK restore is fixed in FSDL*/
|
||||
if (dpp_clock_lowered) {
|
||||
// increase per DPP DTO before lowering global dppclk
|
||||
dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower);
|
||||
dcn31_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz);
|
||||
} else {
|
||||
// increase global DPPCLK before lowering per DPP DTO
|
||||
if (update_dppclk || update_dispclk)
|
||||
dcn31_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz);
|
||||
// always update dtos unless clock is lowered and not safe to lower
|
||||
if (new_clocks->dppclk_khz >= dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz)
|
||||
dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower);
|
||||
}
|
||||
|
||||
// notify DMCUB of latest clocks
|
||||
@@ -368,32 +371,32 @@ static struct wm_table lpddr5_wm_table = {
|
||||
.wm_inst = WM_A,
|
||||
.wm_type = WM_TYPE_PSTATE_CHG,
|
||||
.pstate_latency_us = 11.65333,
|
||||
.sr_exit_time_us = 5.32,
|
||||
.sr_enter_plus_exit_time_us = 6.38,
|
||||
.sr_exit_time_us = 11.5,
|
||||
.sr_enter_plus_exit_time_us = 14.5,
|
||||
.valid = true,
|
||||
},
|
||||
{
|
||||
.wm_inst = WM_B,
|
||||
.wm_type = WM_TYPE_PSTATE_CHG,
|
||||
.pstate_latency_us = 11.65333,
|
||||
.sr_exit_time_us = 9.82,
|
||||
.sr_enter_plus_exit_time_us = 11.196,
|
||||
.sr_exit_time_us = 11.5,
|
||||
.sr_enter_plus_exit_time_us = 14.5,
|
||||
.valid = true,
|
||||
},
|
||||
{
|
||||
.wm_inst = WM_C,
|
||||
.wm_type = WM_TYPE_PSTATE_CHG,
|
||||
.pstate_latency_us = 11.65333,
|
||||
.sr_exit_time_us = 9.89,
|
||||
.sr_enter_plus_exit_time_us = 11.24,
|
||||
.sr_exit_time_us = 11.5,
|
||||
.sr_enter_plus_exit_time_us = 14.5,
|
||||
.valid = true,
|
||||
},
|
||||
{
|
||||
.wm_inst = WM_D,
|
||||
.wm_type = WM_TYPE_PSTATE_CHG,
|
||||
.pstate_latency_us = 11.65333,
|
||||
.sr_exit_time_us = 9.748,
|
||||
.sr_enter_plus_exit_time_us = 11.102,
|
||||
.sr_exit_time_us = 11.5,
|
||||
.sr_enter_plus_exit_time_us = 14.5,
|
||||
.valid = true,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -71,8 +71,6 @@
|
||||
|
||||
#include "dmub/dmub_srv.h"
|
||||
|
||||
#include "dcn30/dcn30_vpg.h"
|
||||
|
||||
#include "i2caux_interface.h"
|
||||
#include "dce/dmub_hw_lock_mgr.h"
|
||||
|
||||
@@ -2674,9 +2672,6 @@ static void commit_planes_do_stream_update(struct dc *dc,
|
||||
enum surface_update_type update_type,
|
||||
struct dc_state *context)
|
||||
{
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
struct vpg *vpg;
|
||||
#endif
|
||||
int j;
|
||||
|
||||
// Stream updates
|
||||
@@ -2697,11 +2692,6 @@ static void commit_planes_do_stream_update(struct dc *dc,
|
||||
stream_update->vrr_infopacket ||
|
||||
stream_update->vsc_infopacket ||
|
||||
stream_update->vsp_infopacket) {
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
vpg = pipe_ctx->stream_res.stream_enc->vpg;
|
||||
if (vpg && vpg->funcs->vpg_poweron)
|
||||
vpg->funcs->vpg_poweron(vpg);
|
||||
#endif
|
||||
resource_build_info_frame(pipe_ctx);
|
||||
dc->hwss.update_info_frame(pipe_ctx);
|
||||
}
|
||||
@@ -3118,8 +3108,13 @@ void dc_commit_updates_for_stream(struct dc *dc,
|
||||
if (new_pipe->plane_state && new_pipe->plane_state != old_pipe->plane_state)
|
||||
new_pipe->plane_state->force_full_update = true;
|
||||
}
|
||||
} else if (update_type == UPDATE_TYPE_FAST) {
|
||||
/* Previous frame finished and HW is ready for optimization. */
|
||||
} else if (update_type == UPDATE_TYPE_FAST && dc_ctx->dce_version >= DCE_VERSION_MAX) {
|
||||
/*
|
||||
* Previous frame finished and HW is ready for optimization.
|
||||
*
|
||||
* Only relevant for DCN behavior where we can guarantee the optimization
|
||||
* is safe to apply - retain the legacy behavior for DCE.
|
||||
*/
|
||||
dc_post_update_surfaces_to_stream(dc);
|
||||
}
|
||||
|
||||
@@ -3178,6 +3173,12 @@ void dc_commit_updates_for_stream(struct dc *dc,
|
||||
}
|
||||
}
|
||||
|
||||
/* Legacy optimization path for DCE. */
|
||||
if (update_type >= UPDATE_TYPE_FULL && dc_ctx->dce_version < DCE_VERSION_MAX) {
|
||||
dc_post_update_surfaces_to_stream(dc);
|
||||
TRACE_DCE_CLOCK_STATE(&context->bw_ctx.bw.dce);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
@@ -674,13 +674,13 @@ static void query_hdcp_capability(enum signal_type signal, struct dc_link *link)
|
||||
|
||||
static void read_current_link_settings_on_detect(struct dc_link *link)
|
||||
{
|
||||
union lane_count_set lane_count_set = { {0} };
|
||||
union lane_count_set lane_count_set = {0};
|
||||
uint8_t link_bw_set;
|
||||
uint8_t link_rate_set;
|
||||
uint32_t read_dpcd_retry_cnt = 10;
|
||||
enum dc_status status = DC_ERROR_UNEXPECTED;
|
||||
int i;
|
||||
union max_down_spread max_down_spread = { {0} };
|
||||
union max_down_spread max_down_spread = {0};
|
||||
|
||||
// Read DPCD 00101h to find out the number of lanes currently set
|
||||
for (i = 0; i < read_dpcd_retry_cnt; i++) {
|
||||
@@ -1869,8 +1869,13 @@ static enum dc_status enable_link_dp(struct dc_state *state,
|
||||
do_fallback = true;
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
/*
|
||||
* Temporary w/a to get DP2.0 link rates to work with SST.
|
||||
* TODO DP2.0 - Workaround: Remove w/a if and when the issue is resolved.
|
||||
*/
|
||||
if (dp_get_link_encoding_format(&link_settings) == DP_128b_132b_ENCODING &&
|
||||
pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT) {
|
||||
pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT &&
|
||||
link->dc->debug.set_mst_en_for_sst) {
|
||||
dp_enable_mst_on_sink(link, true);
|
||||
}
|
||||
#endif
|
||||
@@ -1983,51 +1988,6 @@ static enum dc_status enable_link_dp_mst(
|
||||
return enable_link_dp(state, pipe_ctx);
|
||||
}
|
||||
|
||||
void blank_all_dp_displays(struct dc *dc, bool hw_init)
|
||||
{
|
||||
unsigned int i, j, fe;
|
||||
uint8_t dpcd_power_state = '\0';
|
||||
enum dc_status status = DC_ERROR_UNEXPECTED;
|
||||
|
||||
for (i = 0; i < dc->link_count; i++) {
|
||||
enum signal_type signal = dc->links[i]->connector_signal;
|
||||
|
||||
if ((signal == SIGNAL_TYPE_EDP) ||
|
||||
(signal == SIGNAL_TYPE_DISPLAY_PORT)) {
|
||||
if (hw_init && signal != SIGNAL_TYPE_EDP && dc->links[i]->priv != NULL) {
|
||||
/* DP 2.0 spec requires that we read LTTPR caps first */
|
||||
dp_retrieve_lttpr_cap(dc->links[i]);
|
||||
/* if any of the displays are lit up turn them off */
|
||||
status = core_link_read_dpcd(dc->links[i], DP_SET_POWER,
|
||||
&dpcd_power_state, sizeof(dpcd_power_state));
|
||||
}
|
||||
|
||||
if ((signal != SIGNAL_TYPE_EDP && status == DC_OK && dpcd_power_state == DP_POWER_STATE_D0) ||
|
||||
(!hw_init && dc->links[i]->link_enc &&
|
||||
dc->links[i]->link_enc->funcs->is_dig_enabled(dc->links[i]->link_enc))) {
|
||||
if (dc->links[i]->link_enc->funcs->get_dig_frontend) {
|
||||
fe = dc->links[i]->link_enc->funcs->get_dig_frontend(dc->links[i]->link_enc);
|
||||
if (fe == ENGINE_ID_UNKNOWN)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < dc->res_pool->stream_enc_count; j++) {
|
||||
if (fe == dc->res_pool->stream_enc[j]->id) {
|
||||
dc->res_pool->stream_enc[j]->funcs->dp_blank(dc->links[i],
|
||||
dc->res_pool->stream_enc[j]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!dc->links[i]->wa_flags.dp_keep_receiver_powered ||
|
||||
(hw_init && signal != SIGNAL_TYPE_EDP && dc->links[i]->priv != NULL))
|
||||
dp_receiver_power_ctrl(dc->links[i], false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static bool get_ext_hdmi_settings(struct pipe_ctx *pipe_ctx,
|
||||
enum engine_id eng_id,
|
||||
struct ext_hdmi_settings *settings)
|
||||
@@ -3274,8 +3234,7 @@ static void update_mst_stream_alloc_table(
|
||||
struct stream_encoder *stream_enc,
|
||||
const struct dp_mst_stream_allocation_table *proposed_table)
|
||||
{
|
||||
struct link_mst_stream_allocation work_table[MAX_CONTROLLER_NUM] = {
|
||||
{ 0 } };
|
||||
struct link_mst_stream_allocation work_table[MAX_CONTROLLER_NUM] = { 0 };
|
||||
struct link_mst_stream_allocation *dc_alloc;
|
||||
|
||||
int i;
|
||||
@@ -3434,7 +3393,7 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
|
||||
struct fixed31_32 avg_time_slots_per_mtp;
|
||||
struct fixed31_32 pbn;
|
||||
struct fixed31_32 pbn_per_slot;
|
||||
uint8_t i;
|
||||
int i;
|
||||
enum act_return_status ret;
|
||||
DC_LOGGER_INIT(link->ctx->logger);
|
||||
|
||||
@@ -3526,7 +3485,7 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
|
||||
struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
|
||||
struct dp_mst_stream_allocation_table proposed_table = {0};
|
||||
struct fixed31_32 avg_time_slots_per_mtp = dc_fixpt_from_int(0);
|
||||
uint8_t i;
|
||||
int i;
|
||||
bool mst_mode = (link->type == dc_connection_mst_branch);
|
||||
DC_LOGGER_INIT(link->ctx->logger);
|
||||
|
||||
|
||||
@@ -763,7 +763,7 @@ void dal_ddc_service_read_scdc_data(struct ddc_service *ddc_service)
|
||||
dal_ddc_service_query_ddc_data(ddc_service, slave_address, &offset,
|
||||
sizeof(offset), &tmds_config, sizeof(tmds_config));
|
||||
if (tmds_config & 0x1) {
|
||||
union hdmi_scdc_status_flags_data status_data = { {0} };
|
||||
union hdmi_scdc_status_flags_data status_data = {0};
|
||||
uint8_t scramble_status = 0;
|
||||
|
||||
offset = HDMI_SCDC_SCRAMBLER_STATUS;
|
||||
|
||||
@@ -259,7 +259,7 @@ static void dpcd_set_training_pattern(
|
||||
struct dc_link *link,
|
||||
enum dc_dp_training_pattern training_pattern)
|
||||
{
|
||||
union dpcd_training_pattern dpcd_pattern = { {0} };
|
||||
union dpcd_training_pattern dpcd_pattern = {0};
|
||||
|
||||
dpcd_pattern.v1_4.TRAINING_PATTERN_SET =
|
||||
dc_dp_training_pattern_to_dpcd_training_pattern(
|
||||
@@ -401,8 +401,8 @@ enum dc_status dpcd_set_link_settings(
|
||||
uint8_t rate;
|
||||
enum dc_status status;
|
||||
|
||||
union down_spread_ctrl downspread = { {0} };
|
||||
union lane_count_set lane_count_set = { {0} };
|
||||
union down_spread_ctrl downspread = {0};
|
||||
union lane_count_set lane_count_set = {0};
|
||||
|
||||
downspread.raw = (uint8_t)
|
||||
(lt_settings->link_settings.link_spread);
|
||||
@@ -520,7 +520,7 @@ static void dpcd_set_lt_pattern_and_lane_settings(
|
||||
uint32_t dpcd_base_lt_offset;
|
||||
|
||||
uint8_t dpcd_lt_buffer[5] = {0};
|
||||
union dpcd_training_pattern dpcd_pattern = { {0} };
|
||||
union dpcd_training_pattern dpcd_pattern = { 0 };
|
||||
uint32_t size_in_bytes;
|
||||
bool edp_workaround = false; /* TODO link_prop.INTERNAL */
|
||||
dpcd_base_lt_offset = DP_TRAINING_PATTERN_SET;
|
||||
@@ -1266,8 +1266,8 @@ static enum link_training_result perform_channel_equalization_sequence(
|
||||
uint32_t retries_ch_eq;
|
||||
uint32_t wait_time_microsec;
|
||||
enum dc_lane_count lane_count = lt_settings->link_settings.lane_count;
|
||||
union lane_align_status_updated dpcd_lane_status_updated = { {0} };
|
||||
union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = { { {0} } };
|
||||
union lane_align_status_updated dpcd_lane_status_updated = {0};
|
||||
union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0};
|
||||
|
||||
/* Note: also check that TPS4 is a supported feature*/
|
||||
|
||||
@@ -1487,7 +1487,7 @@ static inline enum link_training_result dp_transition_to_video_idle(
|
||||
struct link_training_settings *lt_settings,
|
||||
enum link_training_result status)
|
||||
{
|
||||
union lane_count_set lane_count_set = { {0} };
|
||||
union lane_count_set lane_count_set = {0};
|
||||
|
||||
/* 4. mainlink output idle pattern*/
|
||||
dp_set_hw_test_pattern(link, DP_TEST_PATTERN_VIDEO_MODE, NULL, 0);
|
||||
@@ -1800,7 +1800,7 @@ static enum dc_status configure_lttpr_mode_non_transparent(
|
||||
|
||||
static void repeater_training_done(struct dc_link *link, uint32_t offset)
|
||||
{
|
||||
union dpcd_training_pattern dpcd_pattern = { {0} };
|
||||
union dpcd_training_pattern dpcd_pattern = {0};
|
||||
|
||||
const uint32_t dpcd_base_lt_offset =
|
||||
DP_TRAINING_PATTERN_SET_PHY_REPEATER1 +
|
||||
@@ -2078,8 +2078,8 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence(
|
||||
uint32_t aux_rd_interval = 0;
|
||||
uint32_t wait_time = 0;
|
||||
struct link_training_settings req_settings;
|
||||
union lane_align_status_updated dpcd_lane_status_updated = { {0} };
|
||||
union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = { { {0} } };
|
||||
union lane_align_status_updated dpcd_lane_status_updated = {0};
|
||||
union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0};
|
||||
enum link_training_result status = LINK_TRAINING_SUCCESS;
|
||||
|
||||
/* Transmit 128b/132b_TPS1 over Main-Link and Set TRAINING_PATTERN_SET to 01h */
|
||||
@@ -2149,8 +2149,8 @@ static enum link_training_result dp_perform_128b_132b_cds_done_sequence(
|
||||
/* Assumption: assume hardware has transmitted eq pattern */
|
||||
enum link_training_result status = LINK_TRAINING_SUCCESS;
|
||||
struct link_training_settings req_settings;
|
||||
union lane_align_status_updated dpcd_lane_status_updated = { {0} };
|
||||
union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = { { {0} } };
|
||||
union lane_align_status_updated dpcd_lane_status_updated = {0};
|
||||
union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0};
|
||||
uint32_t wait_time = 0;
|
||||
|
||||
/* initiate CDS done sequence */
|
||||
@@ -2863,7 +2863,7 @@ bool dp_verify_link_cap(
|
||||
link->verified_link_cap = *known_limit_link_setting;
|
||||
return true;
|
||||
} else if (link->link_enc && link->dc->res_pool->funcs->link_encs_assign &&
|
||||
!link_enc_cfg_is_link_enc_avail(link->ctx->dc, link->link_enc->preferred_engine)) {
|
||||
!link_enc_cfg_is_link_enc_avail(link->ctx->dc, link->link_enc->preferred_engine, link)) {
|
||||
link->verified_link_cap = initial_link_settings;
|
||||
return true;
|
||||
}
|
||||
@@ -4065,8 +4065,8 @@ void dc_link_dp_handle_link_loss(struct dc_link *link)
|
||||
bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd_irq_dpcd_data, bool *out_link_loss,
|
||||
bool defer_handling, bool *has_left_work)
|
||||
{
|
||||
union hpd_irq_data hpd_irq_dpcd_data = { { { {0} } } };
|
||||
union device_service_irq device_service_clear = { { 0 } };
|
||||
union hpd_irq_data hpd_irq_dpcd_data = {0};
|
||||
union device_service_irq device_service_clear = {0};
|
||||
enum dc_status result;
|
||||
bool status = false;
|
||||
|
||||
@@ -5939,7 +5939,7 @@ bool is_edp_ilr_optimization_required(struct dc_link *link, struct dc_crtc_timin
|
||||
uint8_t link_bw_set;
|
||||
uint8_t link_rate_set;
|
||||
uint32_t req_bw;
|
||||
union lane_count_set lane_count_set = { {0} };
|
||||
union lane_count_set lane_count_set = {0};
|
||||
|
||||
ASSERT(link || crtc_timing); // invalid input
|
||||
|
||||
|
||||
@@ -488,16 +488,19 @@ struct link_encoder *link_enc_cfg_get_link_enc_used_by_stream(
|
||||
return link_enc;
|
||||
}
|
||||
|
||||
bool link_enc_cfg_is_link_enc_avail(struct dc *dc, enum engine_id eng_id)
|
||||
bool link_enc_cfg_is_link_enc_avail(struct dc *dc, enum engine_id eng_id, struct dc_link *link)
|
||||
{
|
||||
bool is_avail = true;
|
||||
int i;
|
||||
|
||||
/* Add assigned encoders to list. */
|
||||
/* An encoder is not available if it has already been assigned to a different endpoint. */
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
struct link_enc_assignment assignment = get_assignment(dc, i);
|
||||
struct display_endpoint_id ep_id = (struct display_endpoint_id) {
|
||||
.link_id = link->link_id,
|
||||
.ep_type = link->ep_type};
|
||||
|
||||
if (assignment.valid && assignment.eng_id == eng_id) {
|
||||
if (assignment.valid && assignment.eng_id == eng_id && !are_ep_ids_equal(&ep_id, &assignment.ep_id)) {
|
||||
is_avail = false;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3009,6 +3009,11 @@ enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *pla
|
||||
{
|
||||
enum dc_status res = DC_OK;
|
||||
|
||||
/* check if surface has invalid dimensions */
|
||||
if (plane_state->src_rect.width == 0 || plane_state->src_rect.height == 0 ||
|
||||
plane_state->dst_rect.width == 0 || plane_state->dst_rect.height == 0)
|
||||
return DC_FAIL_SURFACE_VALIDATE;
|
||||
|
||||
/* TODO For now validates pixel format only */
|
||||
if (dc->res_pool->funcs->validate_plane)
|
||||
return dc->res_pool->funcs->validate_plane(plane_state, &dc->caps);
|
||||
|
||||
@@ -202,6 +202,10 @@ struct dc_stream_state *dc_copy_stream(const struct dc_stream_state *stream)
|
||||
new_stream->stream_id = new_stream->ctx->dc_stream_id_count;
|
||||
new_stream->ctx->dc_stream_id_count++;
|
||||
|
||||
/* If using dynamic encoder assignment, wait till stream committed to assign encoder. */
|
||||
if (new_stream->ctx->dc->res_pool->funcs->link_encs_assign)
|
||||
new_stream->link_enc = NULL;
|
||||
|
||||
kref_init(&new_stream->refcount);
|
||||
|
||||
return new_stream;
|
||||
|
||||
@@ -47,7 +47,7 @@ struct aux_payload;
|
||||
struct set_config_cmd_payload;
|
||||
struct dmub_notification;
|
||||
|
||||
#define DC_VER "3.2.156"
|
||||
#define DC_VER "3.2.157"
|
||||
|
||||
#define MAX_SURFACES 3
|
||||
#define MAX_PLANES 6
|
||||
@@ -664,6 +664,7 @@ struct dc_debug_options {
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
/* TODO - remove once tested */
|
||||
bool legacy_dp2_lt;
|
||||
bool set_mst_en_for_sst;
|
||||
#endif
|
||||
union mem_low_power_enable_options enable_mem_low_power;
|
||||
union root_clock_optimization_options root_clock_optimization;
|
||||
|
||||
@@ -277,7 +277,6 @@ bool dc_link_setup_psr(struct dc_link *dc_link,
|
||||
struct psr_context *psr_context);
|
||||
|
||||
void dc_link_get_psr_residency(const struct dc_link *link, uint32_t *residency);
|
||||
void blank_all_dp_displays(struct dc *dc, bool hw_init);
|
||||
|
||||
/* Request DC to detect if there is a Panel connected.
|
||||
* boot - If this call is during initial boot.
|
||||
|
||||
@@ -653,6 +653,7 @@ enum dc_psr_state {
|
||||
PSR_STATE1a,
|
||||
PSR_STATE2,
|
||||
PSR_STATE2a,
|
||||
PSR_STATE2b,
|
||||
PSR_STATE3,
|
||||
PSR_STATE3Init,
|
||||
PSR_STATE4,
|
||||
|
||||
@@ -50,6 +50,8 @@ static enum dc_psr_state convert_psr_state(uint32_t raw_state)
|
||||
state = PSR_STATE2;
|
||||
else if (raw_state == 0x21)
|
||||
state = PSR_STATE2a;
|
||||
else if (raw_state == 0x22)
|
||||
state = PSR_STATE2b;
|
||||
else if (raw_state == 0x30)
|
||||
state = PSR_STATE3;
|
||||
else if (raw_state == 0x31)
|
||||
|
||||
@@ -1649,13 +1649,31 @@ static enum dc_status apply_single_controller_ctx_to_hw(
|
||||
|
||||
static void power_down_encoders(struct dc *dc)
|
||||
{
|
||||
int i;
|
||||
|
||||
blank_all_dp_displays(dc, false);
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < dc->link_count; i++) {
|
||||
enum signal_type signal = dc->links[i]->connector_signal;
|
||||
|
||||
if ((signal == SIGNAL_TYPE_EDP) ||
|
||||
(signal == SIGNAL_TYPE_DISPLAY_PORT)) {
|
||||
if (dc->links[i]->link_enc->funcs->get_dig_frontend &&
|
||||
dc->links[i]->link_enc->funcs->is_dig_enabled(dc->links[i]->link_enc)) {
|
||||
unsigned int fe = dc->links[i]->link_enc->funcs->get_dig_frontend(
|
||||
dc->links[i]->link_enc);
|
||||
|
||||
for (j = 0; j < dc->res_pool->stream_enc_count; j++) {
|
||||
if (fe == dc->res_pool->stream_enc[j]->id) {
|
||||
dc->res_pool->stream_enc[j]->funcs->dp_blank(dc->links[i],
|
||||
dc->res_pool->stream_enc[j]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!dc->links[i]->wa_flags.dp_keep_receiver_powered)
|
||||
dp_receiver_power_ctrl(dc->links[i], false);
|
||||
}
|
||||
|
||||
if (signal != SIGNAL_TYPE_EDP)
|
||||
signal = SIGNAL_TYPE_NONE;
|
||||
|
||||
|
||||
@@ -1366,7 +1366,7 @@ void dcn10_init_pipes(struct dc *dc, struct dc_state *context)
|
||||
|
||||
void dcn10_init_hw(struct dc *dc)
|
||||
{
|
||||
int i;
|
||||
int i, j;
|
||||
struct abm *abm = dc->res_pool->abm;
|
||||
struct dmcu *dmcu = dc->res_pool->dmcu;
|
||||
struct dce_hwseq *hws = dc->hwseq;
|
||||
@@ -1462,8 +1462,43 @@ void dcn10_init_hw(struct dc *dc)
|
||||
dmub_enable_outbox_notification(dc);
|
||||
|
||||
/* we want to turn off all dp displays before doing detection */
|
||||
if (dc->config.power_down_display_on_boot)
|
||||
blank_all_dp_displays(dc, true);
|
||||
if (dc->config.power_down_display_on_boot) {
|
||||
uint8_t dpcd_power_state = '\0';
|
||||
enum dc_status status = DC_ERROR_UNEXPECTED;
|
||||
|
||||
for (i = 0; i < dc->link_count; i++) {
|
||||
if (dc->links[i]->connector_signal != SIGNAL_TYPE_DISPLAY_PORT)
|
||||
continue;
|
||||
|
||||
/* DP 2.0 requires that LTTPR Caps be read first */
|
||||
dp_retrieve_lttpr_cap(dc->links[i]);
|
||||
|
||||
/*
|
||||
* If any of the displays are lit up turn them off.
|
||||
* The reason is that some MST hubs cannot be turned off
|
||||
* completely until we tell them to do so.
|
||||
* If not turned off, then displays connected to MST hub
|
||||
* won't light up.
|
||||
*/
|
||||
status = core_link_read_dpcd(dc->links[i], DP_SET_POWER,
|
||||
&dpcd_power_state, sizeof(dpcd_power_state));
|
||||
if (status == DC_OK && dpcd_power_state == DP_POWER_STATE_D0) {
|
||||
/* blank dp stream before power off receiver*/
|
||||
if (dc->links[i]->link_enc->funcs->get_dig_frontend) {
|
||||
unsigned int fe = dc->links[i]->link_enc->funcs->get_dig_frontend(dc->links[i]->link_enc);
|
||||
|
||||
for (j = 0; j < dc->res_pool->stream_enc_count; j++) {
|
||||
if (fe == dc->res_pool->stream_enc[j]->id) {
|
||||
dc->res_pool->stream_enc[j]->funcs->dp_blank(dc->links[i],
|
||||
dc->res_pool->stream_enc[j]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
dp_receiver_power_ctrl(dc->links[i], false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If taking control over from VBIOS, we may want to optimize our first
|
||||
* mode set, so we need to skip powering down pipes until we know which
|
||||
@@ -2304,8 +2339,8 @@ static void mmhub_read_vm_context0_settings(struct dcn10_hubp *hubp1,
|
||||
void dcn10_program_pte_vm(struct dce_hwseq *hws, struct hubp *hubp)
|
||||
{
|
||||
struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
|
||||
struct vm_system_aperture_param apt = { {{ 0 } } };
|
||||
struct vm_context0_param vm0 = { { { 0 } } };
|
||||
struct vm_system_aperture_param apt = {0};
|
||||
struct vm_context0_param vm0 = {0};
|
||||
|
||||
mmhub_read_vm_system_aperture_settings(hubp1, &apt, hws);
|
||||
mmhub_read_vm_context0_settings(hubp1, &vm0, hws);
|
||||
@@ -2478,7 +2513,7 @@ void dcn10_update_visual_confirm_color(struct dc *dc, struct pipe_ctx *pipe_ctx,
|
||||
void dcn10_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct hubp *hubp = pipe_ctx->plane_res.hubp;
|
||||
struct mpcc_blnd_cfg blnd_cfg = {{0}};
|
||||
struct mpcc_blnd_cfg blnd_cfg = {0};
|
||||
bool per_pixel_alpha = pipe_ctx->plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe;
|
||||
int mpcc_id;
|
||||
struct mpcc *new_mpcc;
|
||||
@@ -3635,7 +3670,7 @@ void dcn10_setup_vupdate_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
||||
void dcn10_unblank_stream(struct pipe_ctx *pipe_ctx,
|
||||
struct dc_link_settings *link_settings)
|
||||
{
|
||||
struct encoder_unblank_param params = { { 0 } };
|
||||
struct encoder_unblank_param params = {0};
|
||||
struct dc_stream_state *stream = pipe_ctx->stream;
|
||||
struct dc_link *link = stream->link;
|
||||
struct dce_hwseq *hws = link->dc->hwseq;
|
||||
|
||||
@@ -169,7 +169,29 @@
|
||||
type DTBCLK_DTO_DIV[MAX_PIPES];\
|
||||
type DCCG_AUDIO_DTO_SEL;\
|
||||
type DCCG_AUDIO_DTO0_SOURCE_SEL;\
|
||||
type DENTIST_DISPCLK_CHG_MODE;
|
||||
type DENTIST_DISPCLK_CHG_MODE;\
|
||||
type DSCCLK0_DTO_PHASE;\
|
||||
type DSCCLK0_DTO_MODULO;\
|
||||
type DSCCLK1_DTO_PHASE;\
|
||||
type DSCCLK1_DTO_MODULO;\
|
||||
type DSCCLK2_DTO_PHASE;\
|
||||
type DSCCLK2_DTO_MODULO;\
|
||||
type DSCCLK0_DTO_ENABLE;\
|
||||
type DSCCLK1_DTO_ENABLE;\
|
||||
type DSCCLK2_DTO_ENABLE;\
|
||||
type SYMCLK32_ROOT_SE0_GATE_DISABLE;\
|
||||
type SYMCLK32_ROOT_SE1_GATE_DISABLE;\
|
||||
type SYMCLK32_ROOT_SE2_GATE_DISABLE;\
|
||||
type SYMCLK32_ROOT_SE3_GATE_DISABLE;\
|
||||
type SYMCLK32_ROOT_LE0_GATE_DISABLE;\
|
||||
type SYMCLK32_ROOT_LE1_GATE_DISABLE;\
|
||||
type DPSTREAMCLK_ROOT_GATE_DISABLE;\
|
||||
type DPSTREAMCLK_GATE_DISABLE;\
|
||||
type HDMISTREAMCLK0_DTO_PHASE;\
|
||||
type HDMISTREAMCLK0_DTO_MODULO;\
|
||||
type HDMICHARCLK0_GATE_DISABLE;\
|
||||
type HDMICHARCLK0_ROOT_GATE_DISABLE;
|
||||
|
||||
|
||||
struct dccg_shift {
|
||||
DCCG_REG_FIELD_LIST(uint8_t)
|
||||
@@ -205,6 +227,16 @@ struct dccg_registers {
|
||||
uint32_t SYMCLK32_SE_CNTL;
|
||||
uint32_t SYMCLK32_LE_CNTL;
|
||||
uint32_t DENTIST_DISPCLK_CNTL;
|
||||
uint32_t DSCCLK_DTO_CTRL;
|
||||
uint32_t DSCCLK0_DTO_PARAM;
|
||||
uint32_t DSCCLK1_DTO_PARAM;
|
||||
uint32_t DSCCLK2_DTO_PARAM;
|
||||
uint32_t DPSTREAMCLK_ROOT_GATE_DISABLE;
|
||||
uint32_t DPSTREAMCLK_GATE_DISABLE;
|
||||
uint32_t DCCG_GATE_DISABLE_CNTL3;
|
||||
uint32_t HDMISTREAMCLK0_DTO_PARAM;
|
||||
uint32_t DCCG_GATE_DISABLE_CNTL4;
|
||||
|
||||
};
|
||||
|
||||
struct dcn_dccg {
|
||||
|
||||
@@ -2123,7 +2123,7 @@ void dcn20_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_ctx)
|
||||
void dcn20_unblank_stream(struct pipe_ctx *pipe_ctx,
|
||||
struct dc_link_settings *link_settings)
|
||||
{
|
||||
struct encoder_unblank_param params = { { 0 } };
|
||||
struct encoder_unblank_param params = {0};
|
||||
struct dc_stream_state *stream = pipe_ctx->stream;
|
||||
struct dc_link *link = stream->link;
|
||||
struct dce_hwseq *hws = link->dc->hwseq;
|
||||
@@ -2298,7 +2298,7 @@ void dcn20_update_visual_confirm_color(struct dc *dc, struct pipe_ctx *pipe_ctx,
|
||||
void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct hubp *hubp = pipe_ctx->plane_res.hubp;
|
||||
struct mpcc_blnd_cfg blnd_cfg = { {0} };
|
||||
struct mpcc_blnd_cfg blnd_cfg = {0};
|
||||
bool per_pixel_alpha = pipe_ctx->plane_state->per_pixel_alpha;
|
||||
int mpcc_id;
|
||||
struct mpcc *new_mpcc;
|
||||
|
||||
@@ -437,7 +437,7 @@ void dcn30_init_hw(struct dc *dc)
|
||||
struct dce_hwseq *hws = dc->hwseq;
|
||||
struct dc_bios *dcb = dc->ctx->dc_bios;
|
||||
struct resource_pool *res_pool = dc->res_pool;
|
||||
int i;
|
||||
int i, j;
|
||||
int edp_num;
|
||||
uint32_t backlight = MAX_BACKLIGHT_LEVEL;
|
||||
|
||||
@@ -534,8 +534,41 @@ void dcn30_init_hw(struct dc *dc)
|
||||
hws->funcs.dsc_pg_control(hws, res_pool->dscs[i]->inst, false);
|
||||
|
||||
/* we want to turn off all dp displays before doing detection */
|
||||
if (dc->config.power_down_display_on_boot)
|
||||
blank_all_dp_displays(dc, true);
|
||||
if (dc->config.power_down_display_on_boot) {
|
||||
uint8_t dpcd_power_state = '\0';
|
||||
enum dc_status status = DC_ERROR_UNEXPECTED;
|
||||
|
||||
for (i = 0; i < dc->link_count; i++) {
|
||||
if (dc->links[i]->connector_signal != SIGNAL_TYPE_DISPLAY_PORT)
|
||||
continue;
|
||||
/* DP 2.0 states that LTTPR regs must be read first */
|
||||
dp_retrieve_lttpr_cap(dc->links[i]);
|
||||
|
||||
/* if any of the displays are lit up turn them off */
|
||||
status = core_link_read_dpcd(dc->links[i], DP_SET_POWER,
|
||||
&dpcd_power_state, sizeof(dpcd_power_state));
|
||||
if (status == DC_OK && dpcd_power_state == DP_POWER_STATE_D0) {
|
||||
/* blank dp stream before power off receiver*/
|
||||
if (dc->links[i]->link_enc->funcs->get_dig_frontend) {
|
||||
unsigned int fe;
|
||||
|
||||
fe = dc->links[i]->link_enc->funcs->get_dig_frontend(
|
||||
dc->links[i]->link_enc);
|
||||
if (fe == ENGINE_ID_UNKNOWN)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < dc->res_pool->stream_enc_count; j++) {
|
||||
if (fe == dc->res_pool->stream_enc[j]->id) {
|
||||
dc->res_pool->stream_enc[j]->funcs->dp_blank(dc->links[i],
|
||||
dc->res_pool->stream_enc[j]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
dp_receiver_power_ctrl(dc->links[i], false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If taking control over from VBIOS, we may want to optimize our first
|
||||
* mode set, so we need to skip powering down pipes until we know which
|
||||
@@ -969,7 +1002,8 @@ void dcn30_set_disp_pattern_generator(const struct dc *dc,
|
||||
/* turning off DPG */
|
||||
pipe_ctx->plane_res.hubp->funcs->set_blank(pipe_ctx->plane_res.hubp, false);
|
||||
for (mpcc_pipe = pipe_ctx->bottom_pipe; mpcc_pipe; mpcc_pipe = mpcc_pipe->bottom_pipe)
|
||||
mpcc_pipe->plane_res.hubp->funcs->set_blank(mpcc_pipe->plane_res.hubp, false);
|
||||
if (mpcc_pipe->plane_res.hubp)
|
||||
mpcc_pipe->plane_res.hubp->funcs->set_blank(mpcc_pipe->plane_res.hubp, false);
|
||||
|
||||
stream_res->opp->funcs->opp_set_disp_pattern_generator(stream_res->opp, test_pattern, color_space,
|
||||
color_depth, solid_color, width, height, offset);
|
||||
|
||||
@@ -129,7 +129,7 @@ static void apg31_se_audio_setup(
|
||||
|
||||
/* When running in "pair mode", pairs of audio channels have their own enable
|
||||
* this is for really old audio drivers */
|
||||
REG_UPDATE(APG_DBG_GEN_CONTROL, APG_DBG_AUDIO_CHANNEL_ENABLE, 0xF);
|
||||
REG_UPDATE(APG_DBG_GEN_CONTROL, APG_DBG_AUDIO_CHANNEL_ENABLE, 0xFF);
|
||||
// REG_UPDATE(APG_DBG_GEN_CONTROL, APG_DBG_AUDIO_CHANNEL_ENABLE, channels);
|
||||
|
||||
/* Disable forced mem power off */
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "reg_helper.h"
|
||||
#include "core_types.h"
|
||||
#include "dcn31_dccg.h"
|
||||
#include "dal_asic_id.h"
|
||||
|
||||
#define TO_DCN_DCCG(dccg)\
|
||||
container_of(dccg, struct dcn_dccg, base)
|
||||
@@ -42,10 +43,58 @@
|
||||
#define DC_LOGGER \
|
||||
dccg->ctx->logger
|
||||
|
||||
void dccg31_set_dpstreamclk(
|
||||
struct dccg *dccg,
|
||||
enum hdmistreamclk_source src,
|
||||
int otg_inst)
|
||||
static void dccg31_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk)
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
if (dccg->ref_dppclk && req_dppclk) {
|
||||
int ref_dppclk = dccg->ref_dppclk;
|
||||
int modulo, phase;
|
||||
|
||||
// phase / modulo = dpp pipe clk / dpp global clk
|
||||
modulo = 0xff; // use FF at the end
|
||||
phase = ((modulo * req_dppclk) + ref_dppclk - 1) / ref_dppclk;
|
||||
|
||||
if (phase > 0xff) {
|
||||
ASSERT(false);
|
||||
phase = 0xff;
|
||||
}
|
||||
|
||||
REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
|
||||
DPPCLK0_DTO_PHASE, phase,
|
||||
DPPCLK0_DTO_MODULO, modulo);
|
||||
REG_UPDATE(DPPCLK_DTO_CTRL,
|
||||
DPPCLK_DTO_ENABLE[dpp_inst], 1);
|
||||
} else {
|
||||
//DTO must be enabled to generate a 0Hz clock output
|
||||
if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp) {
|
||||
REG_UPDATE(DPPCLK_DTO_CTRL,
|
||||
DPPCLK_DTO_ENABLE[dpp_inst], 1);
|
||||
REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
|
||||
DPPCLK0_DTO_PHASE, 0,
|
||||
DPPCLK0_DTO_MODULO, 1);
|
||||
} else {
|
||||
REG_UPDATE(DPPCLK_DTO_CTRL,
|
||||
DPPCLK_DTO_ENABLE[dpp_inst], 0);
|
||||
}
|
||||
}
|
||||
dccg->pipe_dppclk_khz[dpp_inst] = req_dppclk;
|
||||
}
|
||||
|
||||
static enum phyd32clk_clock_source get_phy_mux_symclk(
|
||||
struct dcn_dccg *dccg_dcn,
|
||||
enum phyd32clk_clock_source src)
|
||||
{
|
||||
if (dccg_dcn->base.ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) {
|
||||
if (src == PHYD32CLKC)
|
||||
src = PHYD32CLKF;
|
||||
if (src == PHYD32CLKD)
|
||||
src = PHYD32CLKG;
|
||||
}
|
||||
return src;
|
||||
}
|
||||
|
||||
static void dccg31_enable_dpstreamclk(struct dccg *dccg, int otg_inst)
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
@@ -53,24 +102,69 @@ void dccg31_set_dpstreamclk(
|
||||
switch (otg_inst) {
|
||||
case 0:
|
||||
REG_UPDATE(DPSTREAMCLK_CNTL,
|
||||
DPSTREAMCLK_PIPE0_EN, (src == REFCLK) ? 0 : 1);
|
||||
DPSTREAMCLK_PIPE0_EN, 1);
|
||||
break;
|
||||
case 1:
|
||||
REG_UPDATE(DPSTREAMCLK_CNTL,
|
||||
DPSTREAMCLK_PIPE1_EN, (src == REFCLK) ? 0 : 1);
|
||||
DPSTREAMCLK_PIPE1_EN, 1);
|
||||
break;
|
||||
case 2:
|
||||
REG_UPDATE(DPSTREAMCLK_CNTL,
|
||||
DPSTREAMCLK_PIPE2_EN, (src == REFCLK) ? 0 : 1);
|
||||
DPSTREAMCLK_PIPE2_EN, 1);
|
||||
break;
|
||||
case 3:
|
||||
REG_UPDATE(DPSTREAMCLK_CNTL,
|
||||
DPSTREAMCLK_PIPE3_EN, (src == REFCLK) ? 0 : 1);
|
||||
DPSTREAMCLK_PIPE3_EN, 1);
|
||||
break;
|
||||
default:
|
||||
BREAK_TO_DEBUGGER();
|
||||
return;
|
||||
}
|
||||
if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
|
||||
DPSTREAMCLK_ROOT_GATE_DISABLE, 1);
|
||||
}
|
||||
|
||||
static void dccg31_disable_dpstreamclk(struct dccg *dccg, int otg_inst)
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
|
||||
DPSTREAMCLK_ROOT_GATE_DISABLE, 0);
|
||||
|
||||
switch (otg_inst) {
|
||||
case 0:
|
||||
REG_UPDATE(DPSTREAMCLK_CNTL,
|
||||
DPSTREAMCLK_PIPE0_EN, 0);
|
||||
break;
|
||||
case 1:
|
||||
REG_UPDATE(DPSTREAMCLK_CNTL,
|
||||
DPSTREAMCLK_PIPE1_EN, 0);
|
||||
break;
|
||||
case 2:
|
||||
REG_UPDATE(DPSTREAMCLK_CNTL,
|
||||
DPSTREAMCLK_PIPE2_EN, 0);
|
||||
break;
|
||||
case 3:
|
||||
REG_UPDATE(DPSTREAMCLK_CNTL,
|
||||
DPSTREAMCLK_PIPE3_EN, 0);
|
||||
break;
|
||||
default:
|
||||
BREAK_TO_DEBUGGER();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void dccg31_set_dpstreamclk(
|
||||
struct dccg *dccg,
|
||||
enum hdmistreamclk_source src,
|
||||
int otg_inst)
|
||||
{
|
||||
if (src == REFCLK)
|
||||
dccg31_disable_dpstreamclk(dccg, otg_inst);
|
||||
else
|
||||
dccg31_enable_dpstreamclk(dccg, otg_inst);
|
||||
}
|
||||
|
||||
void dccg31_enable_symclk32_se(
|
||||
@@ -80,24 +174,38 @@ void dccg31_enable_symclk32_se(
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
phyd32clk = get_phy_mux_symclk(dccg_dcn, phyd32clk);
|
||||
|
||||
/* select one of the PHYD32CLKs as the source for symclk32_se */
|
||||
switch (hpo_se_inst) {
|
||||
case 0:
|
||||
if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
|
||||
SYMCLK32_ROOT_SE0_GATE_DISABLE, 1);
|
||||
REG_UPDATE_2(SYMCLK32_SE_CNTL,
|
||||
SYMCLK32_SE0_SRC_SEL, phyd32clk,
|
||||
SYMCLK32_SE0_EN, 1);
|
||||
break;
|
||||
case 1:
|
||||
if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
|
||||
SYMCLK32_ROOT_SE1_GATE_DISABLE, 1);
|
||||
REG_UPDATE_2(SYMCLK32_SE_CNTL,
|
||||
SYMCLK32_SE1_SRC_SEL, phyd32clk,
|
||||
SYMCLK32_SE1_EN, 1);
|
||||
break;
|
||||
case 2:
|
||||
if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
|
||||
SYMCLK32_ROOT_SE2_GATE_DISABLE, 1);
|
||||
REG_UPDATE_2(SYMCLK32_SE_CNTL,
|
||||
SYMCLK32_SE2_SRC_SEL, phyd32clk,
|
||||
SYMCLK32_SE2_EN, 1);
|
||||
break;
|
||||
case 3:
|
||||
if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
|
||||
SYMCLK32_ROOT_SE3_GATE_DISABLE, 1);
|
||||
REG_UPDATE_2(SYMCLK32_SE_CNTL,
|
||||
SYMCLK32_SE3_SRC_SEL, phyd32clk,
|
||||
SYMCLK32_SE3_EN, 1);
|
||||
@@ -120,21 +228,33 @@ void dccg31_disable_symclk32_se(
|
||||
REG_UPDATE_2(SYMCLK32_SE_CNTL,
|
||||
SYMCLK32_SE0_SRC_SEL, 0,
|
||||
SYMCLK32_SE0_EN, 0);
|
||||
if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
|
||||
SYMCLK32_ROOT_SE0_GATE_DISABLE, 0);
|
||||
break;
|
||||
case 1:
|
||||
REG_UPDATE_2(SYMCLK32_SE_CNTL,
|
||||
SYMCLK32_SE1_SRC_SEL, 0,
|
||||
SYMCLK32_SE1_EN, 0);
|
||||
if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
|
||||
SYMCLK32_ROOT_SE1_GATE_DISABLE, 0);
|
||||
break;
|
||||
case 2:
|
||||
REG_UPDATE_2(SYMCLK32_SE_CNTL,
|
||||
SYMCLK32_SE2_SRC_SEL, 0,
|
||||
SYMCLK32_SE2_EN, 0);
|
||||
if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
|
||||
SYMCLK32_ROOT_SE2_GATE_DISABLE, 0);
|
||||
break;
|
||||
case 3:
|
||||
REG_UPDATE_2(SYMCLK32_SE_CNTL,
|
||||
SYMCLK32_SE3_SRC_SEL, 0,
|
||||
SYMCLK32_SE3_EN, 0);
|
||||
if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
|
||||
SYMCLK32_ROOT_SE3_GATE_DISABLE, 0);
|
||||
break;
|
||||
default:
|
||||
BREAK_TO_DEBUGGER();
|
||||
@@ -149,14 +269,22 @@ void dccg31_enable_symclk32_le(
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
phyd32clk = get_phy_mux_symclk(dccg_dcn, phyd32clk);
|
||||
|
||||
/* select one of the PHYD32CLKs as the source for symclk32_le */
|
||||
switch (hpo_le_inst) {
|
||||
case 0:
|
||||
if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
|
||||
SYMCLK32_ROOT_LE0_GATE_DISABLE, 1);
|
||||
REG_UPDATE_2(SYMCLK32_LE_CNTL,
|
||||
SYMCLK32_LE0_SRC_SEL, phyd32clk,
|
||||
SYMCLK32_LE0_EN, 1);
|
||||
break;
|
||||
case 1:
|
||||
if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
|
||||
SYMCLK32_ROOT_LE1_GATE_DISABLE, 1);
|
||||
REG_UPDATE_2(SYMCLK32_LE_CNTL,
|
||||
SYMCLK32_LE1_SRC_SEL, phyd32clk,
|
||||
SYMCLK32_LE1_EN, 1);
|
||||
@@ -179,11 +307,87 @@ void dccg31_disable_symclk32_le(
|
||||
REG_UPDATE_2(SYMCLK32_LE_CNTL,
|
||||
SYMCLK32_LE0_SRC_SEL, 0,
|
||||
SYMCLK32_LE0_EN, 0);
|
||||
if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
|
||||
SYMCLK32_ROOT_LE0_GATE_DISABLE, 0);
|
||||
break;
|
||||
case 1:
|
||||
REG_UPDATE_2(SYMCLK32_LE_CNTL,
|
||||
SYMCLK32_LE1_SRC_SEL, 0,
|
||||
SYMCLK32_LE1_EN, 0);
|
||||
if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
|
||||
SYMCLK32_ROOT_LE1_GATE_DISABLE, 0);
|
||||
break;
|
||||
default:
|
||||
BREAK_TO_DEBUGGER();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void dccg31_disable_dscclk(struct dccg *dccg, int inst)
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)
|
||||
return;
|
||||
//DTO must be enabled to generate a 0 Hz clock output
|
||||
switch (inst) {
|
||||
case 0:
|
||||
REG_UPDATE(DSCCLK_DTO_CTRL,
|
||||
DSCCLK0_DTO_ENABLE, 1);
|
||||
REG_UPDATE_2(DSCCLK0_DTO_PARAM,
|
||||
DSCCLK0_DTO_PHASE, 0,
|
||||
DSCCLK0_DTO_MODULO, 1);
|
||||
break;
|
||||
case 1:
|
||||
REG_UPDATE(DSCCLK_DTO_CTRL,
|
||||
DSCCLK1_DTO_ENABLE, 1);
|
||||
REG_UPDATE_2(DSCCLK1_DTO_PARAM,
|
||||
DSCCLK1_DTO_PHASE, 0,
|
||||
DSCCLK1_DTO_MODULO, 1);
|
||||
break;
|
||||
case 2:
|
||||
REG_UPDATE(DSCCLK_DTO_CTRL,
|
||||
DSCCLK2_DTO_ENABLE, 1);
|
||||
REG_UPDATE_2(DSCCLK2_DTO_PARAM,
|
||||
DSCCLK2_DTO_PHASE, 0,
|
||||
DSCCLK2_DTO_MODULO, 1);
|
||||
break;
|
||||
default:
|
||||
BREAK_TO_DEBUGGER();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void dccg31_enable_dscclk(struct dccg *dccg, int inst)
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)
|
||||
return;
|
||||
//Disable DTO
|
||||
switch (inst) {
|
||||
case 0:
|
||||
REG_UPDATE_2(DSCCLK0_DTO_PARAM,
|
||||
DSCCLK0_DTO_PHASE, 0,
|
||||
DSCCLK0_DTO_MODULO, 0);
|
||||
REG_UPDATE(DSCCLK_DTO_CTRL,
|
||||
DSCCLK0_DTO_ENABLE, 0);
|
||||
break;
|
||||
case 1:
|
||||
REG_UPDATE_2(DSCCLK1_DTO_PARAM,
|
||||
DSCCLK1_DTO_PHASE, 0,
|
||||
DSCCLK1_DTO_MODULO, 0);
|
||||
REG_UPDATE(DSCCLK_DTO_CTRL,
|
||||
DSCCLK1_DTO_ENABLE, 0);
|
||||
break;
|
||||
case 2:
|
||||
REG_UPDATE_2(DSCCLK2_DTO_PARAM,
|
||||
DSCCLK2_DTO_PHASE, 0,
|
||||
DSCCLK2_DTO_MODULO, 0);
|
||||
REG_UPDATE(DSCCLK_DTO_CTRL,
|
||||
DSCCLK2_DTO_ENABLE, 0);
|
||||
break;
|
||||
default:
|
||||
BREAK_TO_DEBUGGER();
|
||||
@@ -398,10 +602,23 @@ void dccg31_init(struct dccg *dccg)
|
||||
dccg31_disable_symclk32_se(dccg, 1);
|
||||
dccg31_disable_symclk32_se(dccg, 2);
|
||||
dccg31_disable_symclk32_se(dccg, 3);
|
||||
|
||||
if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le) {
|
||||
dccg31_disable_symclk32_le(dccg, 0);
|
||||
dccg31_disable_symclk32_le(dccg, 1);
|
||||
}
|
||||
|
||||
if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) {
|
||||
dccg31_disable_dpstreamclk(dccg, 0);
|
||||
dccg31_disable_dpstreamclk(dccg, 1);
|
||||
dccg31_disable_dpstreamclk(dccg, 2);
|
||||
dccg31_disable_dpstreamclk(dccg, 3);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static const struct dccg_funcs dccg31_funcs = {
|
||||
.update_dpp_dto = dccg2_update_dpp_dto,
|
||||
.update_dpp_dto = dccg31_update_dpp_dto,
|
||||
.get_dccg_ref_freq = dccg31_get_dccg_ref_freq,
|
||||
.dccg_init = dccg31_init,
|
||||
.set_dpstreamclk = dccg31_set_dpstreamclk,
|
||||
@@ -413,6 +630,8 @@ static const struct dccg_funcs dccg31_funcs = {
|
||||
.set_dtbclk_dto = dccg31_set_dtbclk_dto,
|
||||
.set_audio_dtbclk_dto = dccg31_set_audio_dtbclk_dto,
|
||||
.set_dispclk_change_mode = dccg31_set_dispclk_change_mode,
|
||||
.disable_dsc = dccg31_disable_dscclk,
|
||||
.enable_dsc = dccg31_enable_dscclk,
|
||||
};
|
||||
|
||||
struct dccg *dccg31_create(
|
||||
|
||||
@@ -61,7 +61,13 @@
|
||||
SR(DCCG_AUDIO_DTBCLK_DTO_MODULO),\
|
||||
SR(DCCG_AUDIO_DTBCLK_DTO_PHASE),\
|
||||
SR(DCCG_AUDIO_DTO_SOURCE),\
|
||||
SR(DENTIST_DISPCLK_CNTL)
|
||||
SR(DENTIST_DISPCLK_CNTL),\
|
||||
SR(DSCCLK0_DTO_PARAM),\
|
||||
SR(DSCCLK1_DTO_PARAM),\
|
||||
SR(DSCCLK2_DTO_PARAM),\
|
||||
SR(DSCCLK_DTO_CTRL),\
|
||||
SR(DCCG_GATE_DISABLE_CNTL3),\
|
||||
SR(HDMISTREAMCLK0_DTO_PARAM)
|
||||
|
||||
|
||||
#define DCCG_MASK_SH_LIST_DCN31(mask_sh) \
|
||||
@@ -119,7 +125,26 @@
|
||||
DCCG_SFII(OTG, PIXEL_RATE_CNTL, DTBCLK_DTO, DIV, 3, mask_sh),\
|
||||
DCCG_SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO_SEL, mask_sh),\
|
||||
DCCG_SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL, mask_sh),\
|
||||
DCCG_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_MODE, mask_sh)
|
||||
DCCG_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_MODE, mask_sh), \
|
||||
DCCG_SF(DSCCLK0_DTO_PARAM, DSCCLK0_DTO_PHASE, mask_sh),\
|
||||
DCCG_SF(DSCCLK0_DTO_PARAM, DSCCLK0_DTO_MODULO, mask_sh),\
|
||||
DCCG_SF(DSCCLK1_DTO_PARAM, DSCCLK1_DTO_PHASE, mask_sh),\
|
||||
DCCG_SF(DSCCLK1_DTO_PARAM, DSCCLK1_DTO_MODULO, mask_sh),\
|
||||
DCCG_SF(DSCCLK2_DTO_PARAM, DSCCLK2_DTO_PHASE, mask_sh),\
|
||||
DCCG_SF(DSCCLK2_DTO_PARAM, DSCCLK2_DTO_MODULO, mask_sh),\
|
||||
DCCG_SF(DSCCLK_DTO_CTRL, DSCCLK0_DTO_ENABLE, mask_sh),\
|
||||
DCCG_SF(DSCCLK_DTO_CTRL, DSCCLK1_DTO_ENABLE, mask_sh),\
|
||||
DCCG_SF(DSCCLK_DTO_CTRL, DSCCLK2_DTO_ENABLE, mask_sh),\
|
||||
DCCG_SF(DCCG_GATE_DISABLE_CNTL3, DPSTREAMCLK_ROOT_GATE_DISABLE, mask_sh),\
|
||||
DCCG_SF(DCCG_GATE_DISABLE_CNTL3, DPSTREAMCLK_GATE_DISABLE, mask_sh),\
|
||||
DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_ROOT_SE0_GATE_DISABLE, mask_sh),\
|
||||
DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_ROOT_SE1_GATE_DISABLE, mask_sh),\
|
||||
DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_ROOT_SE2_GATE_DISABLE, mask_sh),\
|
||||
DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_ROOT_SE3_GATE_DISABLE, mask_sh),\
|
||||
DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_ROOT_LE0_GATE_DISABLE, mask_sh),\
|
||||
DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_ROOT_LE1_GATE_DISABLE, mask_sh),\
|
||||
DCCG_SF(HDMISTREAMCLK0_DTO_PARAM, HDMISTREAMCLK0_DTO_PHASE, mask_sh),\
|
||||
DCCG_SF(HDMISTREAMCLK0_DTO_PARAM, HDMISTREAMCLK0_DTO_MODULO, mask_sh)
|
||||
|
||||
|
||||
struct dccg *dccg31_create(
|
||||
@@ -130,6 +155,11 @@ struct dccg *dccg31_create(
|
||||
|
||||
void dccg31_init(struct dccg *dccg);
|
||||
|
||||
void dccg31_set_dpstreamclk(
|
||||
struct dccg *dccg,
|
||||
enum hdmistreamclk_source src,
|
||||
int otg_inst);
|
||||
|
||||
void dccg31_enable_symclk32_se(
|
||||
struct dccg *dccg,
|
||||
int hpo_se_inst,
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "inc/link_dpcd.h"
|
||||
#include "dcn10/dcn10_hw_sequencer.h"
|
||||
#include "inc/link_enc_cfg.h"
|
||||
#include "dcn30/dcn30_vpg.h"
|
||||
|
||||
#define DC_LOGGER_INIT(logger)
|
||||
|
||||
@@ -71,16 +72,11 @@ void dcn31_init_hw(struct dc *dc)
|
||||
struct dc_bios *dcb = dc->ctx->dc_bios;
|
||||
struct resource_pool *res_pool = dc->res_pool;
|
||||
uint32_t backlight = MAX_BACKLIGHT_LEVEL;
|
||||
int i;
|
||||
int edp_num;
|
||||
int i, j;
|
||||
|
||||
if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
|
||||
dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
|
||||
|
||||
// Initialize the dccg
|
||||
if (res_pool->dccg->funcs->dccg_init)
|
||||
res_pool->dccg->funcs->dccg_init(res_pool->dccg);
|
||||
|
||||
if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
|
||||
|
||||
REG_WRITE(REFCLK_CNTL, 0);
|
||||
@@ -107,6 +103,9 @@ void dcn31_init_hw(struct dc *dc)
|
||||
hws->funcs.bios_golden_init(dc);
|
||||
hws->funcs.disable_vga(dc->hwseq);
|
||||
}
|
||||
// Initialize the dccg
|
||||
if (res_pool->dccg->funcs->dccg_init)
|
||||
res_pool->dccg->funcs->dccg_init(res_pool->dccg);
|
||||
|
||||
if (dc->debug.enable_mem_low_power.bits.dmcu) {
|
||||
// Force ERAM to shutdown if DMCU is not enabled
|
||||
@@ -126,6 +125,18 @@ void dcn31_init_hw(struct dc *dc)
|
||||
REG_UPDATE(MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, 1);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (dc->debug.enable_mem_low_power.bits.vpg && dc->res_pool->stream_enc[0]->vpg->funcs->vpg_powerdown) {
|
||||
// Power down VPGs
|
||||
for (i = 0; i < dc->res_pool->stream_enc_count; i++)
|
||||
dc->res_pool->stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->stream_enc[i]->vpg);
|
||||
#if defined(CONFIG_DRM_AMD_DC_DP2_0)
|
||||
for (i = 0; i < dc->res_pool->hpo_dp_stream_enc_count; i++)
|
||||
dc->res_pool->hpo_dp_stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->hpo_dp_stream_enc[i]->vpg);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
if (dc->ctx->dc_bios->fw_info_valid) {
|
||||
res_pool->ref_clocks.xtalin_clock_inKhz =
|
||||
dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
|
||||
@@ -179,9 +190,40 @@ void dcn31_init_hw(struct dc *dc)
|
||||
dmub_enable_outbox_notification(dc);
|
||||
|
||||
/* we want to turn off all dp displays before doing detection */
|
||||
if (dc->config.power_down_display_on_boot)
|
||||
blank_all_dp_displays(dc, true);
|
||||
if (dc->config.power_down_display_on_boot) {
|
||||
uint8_t dpcd_power_state = '\0';
|
||||
enum dc_status status = DC_ERROR_UNEXPECTED;
|
||||
|
||||
for (i = 0; i < dc->link_count; i++) {
|
||||
if (dc->links[i]->connector_signal != SIGNAL_TYPE_DISPLAY_PORT)
|
||||
continue;
|
||||
|
||||
/* if any of the displays are lit up turn them off */
|
||||
status = core_link_read_dpcd(dc->links[i], DP_SET_POWER,
|
||||
&dpcd_power_state, sizeof(dpcd_power_state));
|
||||
if (status == DC_OK && dpcd_power_state == DP_POWER_STATE_D0) {
|
||||
/* blank dp stream before power off receiver*/
|
||||
if (dc->links[i]->ep_type == DISPLAY_ENDPOINT_PHY &&
|
||||
dc->links[i]->link_enc->funcs->get_dig_frontend) {
|
||||
unsigned int fe;
|
||||
|
||||
fe = dc->links[i]->link_enc->funcs->get_dig_frontend(
|
||||
dc->links[i]->link_enc);
|
||||
if (fe == ENGINE_ID_UNKNOWN)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < dc->res_pool->stream_enc_count; j++) {
|
||||
if (fe == dc->res_pool->stream_enc[j]->id) {
|
||||
dc->res_pool->stream_enc[j]->funcs->dp_blank(dc->links[i],
|
||||
dc->res_pool->stream_enc[j]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
dp_receiver_power_ctrl(dc->links[i], false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If taking control over from VBIOS, we may want to optimize our first
|
||||
* mode set, so we need to skip powering down pipes until we know which
|
||||
@@ -196,48 +238,6 @@ void dcn31_init_hw(struct dc *dc)
|
||||
!dc->res_pool->hubbub->ctx->dc->debug.disable_stutter);
|
||||
}
|
||||
|
||||
/* In headless boot cases, DIG may be turned
|
||||
* on which causes HW/SW discrepancies.
|
||||
* To avoid this, power down hardware on boot
|
||||
* if DIG is turned on and seamless boot not enabled
|
||||
*/
|
||||
if (dc->config.power_down_display_on_boot) {
|
||||
struct dc_link *edp_links[MAX_NUM_EDP];
|
||||
struct dc_link *edp_link;
|
||||
bool power_down = false;
|
||||
|
||||
get_edp_links(dc, edp_links, &edp_num);
|
||||
if (edp_num) {
|
||||
for (i = 0; i < edp_num; i++) {
|
||||
edp_link = edp_links[i];
|
||||
if (edp_link->link_enc->funcs->is_dig_enabled &&
|
||||
edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) &&
|
||||
dc->hwss.edp_backlight_control &&
|
||||
dc->hwss.power_down &&
|
||||
dc->hwss.edp_power_control) {
|
||||
dc->hwss.edp_backlight_control(edp_link, false);
|
||||
dc->hwss.power_down(dc);
|
||||
dc->hwss.edp_power_control(edp_link, false);
|
||||
power_down = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!power_down) {
|
||||
for (i = 0; i < dc->link_count; i++) {
|
||||
struct dc_link *link = dc->links[i];
|
||||
|
||||
if (link->ep_type == DISPLAY_ENDPOINT_PHY &&
|
||||
link->link_enc->funcs->is_dig_enabled &&
|
||||
link->link_enc->funcs->is_dig_enabled(link->link_enc) &&
|
||||
dc->hwss.power_down) {
|
||||
dc->hwss.power_down(dc);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < res_pool->audio_count; i++) {
|
||||
struct audio *audio = res_pool->audios[i];
|
||||
|
||||
@@ -300,6 +300,12 @@ void dcn31_dsc_pg_control(
|
||||
if (hws->ctx->dc->debug.disable_dsc_power_gate)
|
||||
return;
|
||||
|
||||
if (hws->ctx->dc->debug.root_clock_optimization.bits.dsc &&
|
||||
hws->ctx->dc->res_pool->dccg->funcs->enable_dsc &&
|
||||
power_on)
|
||||
hws->ctx->dc->res_pool->dccg->funcs->enable_dsc(
|
||||
hws->ctx->dc->res_pool->dccg, dsc_inst);
|
||||
|
||||
REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
|
||||
if (org_ip_request_cntl == 0)
|
||||
REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
|
||||
@@ -336,6 +342,13 @@ void dcn31_dsc_pg_control(
|
||||
|
||||
if (org_ip_request_cntl == 0)
|
||||
REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
|
||||
|
||||
if (hws->ctx->dc->debug.root_clock_optimization.bits.dsc) {
|
||||
if (hws->ctx->dc->res_pool->dccg->funcs->disable_dsc && !power_on)
|
||||
hws->ctx->dc->res_pool->dccg->funcs->disable_dsc(
|
||||
hws->ctx->dc->res_pool->dccg, dsc_inst);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -222,8 +222,8 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_1_soc = {
|
||||
.num_states = 5,
|
||||
.sr_exit_time_us = 9.0,
|
||||
.sr_enter_plus_exit_time_us = 11.0,
|
||||
.sr_exit_z8_time_us = 402.0,
|
||||
.sr_enter_plus_exit_z8_time_us = 520.0,
|
||||
.sr_exit_z8_time_us = 442.0,
|
||||
.sr_enter_plus_exit_z8_time_us = 560.0,
|
||||
.writeback_latency_us = 12.0,
|
||||
.dram_channel_width_bytes = 4,
|
||||
.round_trip_ping_latency_dcfclk_cycles = 106,
|
||||
@@ -998,7 +998,7 @@ static const struct dc_debug_options debug_defaults_drv = {
|
||||
.disable_dcc = DCC_ENABLE,
|
||||
.vsr_support = true,
|
||||
.performance_trace = false,
|
||||
.max_downscale_src_width = 3840,/*upto 4K*/
|
||||
.max_downscale_src_width = 4096,/*upto true 4K*/
|
||||
.disable_pplib_wm_range = false,
|
||||
.scl_reset_length10 = true,
|
||||
.sanity_checks = false,
|
||||
@@ -1312,10 +1312,6 @@ static struct vpg *dcn31_vpg_create(
|
||||
&vpg_shift,
|
||||
&vpg_mask);
|
||||
|
||||
// Will re-enable hw block when we enable stream
|
||||
// Check for enabled stream before powering down?
|
||||
vpg31_powerdown(&vpg31->base);
|
||||
|
||||
return &vpg31->base;
|
||||
}
|
||||
|
||||
@@ -1782,6 +1778,13 @@ static int dcn31_populate_dml_pipes_from_context(
|
||||
pipe = &res_ctx->pipe_ctx[i];
|
||||
timing = &pipe->stream->timing;
|
||||
|
||||
/*
|
||||
* Immediate flip can be set dynamically after enabling the plane.
|
||||
* We need to require support for immediate flip or underflow can be
|
||||
* intermittently experienced depending on peak b/w requirements.
|
||||
*/
|
||||
pipes[pipe_cnt].pipe.src.immediate_flip = true;
|
||||
|
||||
pipes[pipe_cnt].pipe.src.unbounded_req_mode = false;
|
||||
pipes[pipe_cnt].pipe.src.gpuvm = true;
|
||||
pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_luma = 0;
|
||||
|
||||
@@ -5398,9 +5398,9 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
|
||||
v->MaximumReadBandwidthWithPrefetch =
|
||||
v->MaximumReadBandwidthWithPrefetch
|
||||
+ dml_max4(
|
||||
v->VActivePixelBandwidth[i][j][k],
|
||||
v->VActiveCursorBandwidth[i][j][k]
|
||||
+ dml_max3(
|
||||
v->VActivePixelBandwidth[i][j][k]
|
||||
+ v->VActiveCursorBandwidth[i][j][k]
|
||||
+ v->NoOfDPP[i][j][k]
|
||||
* (v->meta_row_bandwidth[i][j][k]
|
||||
+ v->dpte_row_bandwidth[i][j][k]),
|
||||
|
||||
@@ -123,6 +123,15 @@ struct dccg_funcs {
|
||||
void (*set_dispclk_change_mode)(
|
||||
struct dccg *dccg,
|
||||
enum dentist_dispclk_change_mode change_mode);
|
||||
|
||||
void (*disable_dsc)(
|
||||
struct dccg *dccg,
|
||||
int inst);
|
||||
|
||||
void (*enable_dsc)(
|
||||
struct dccg *dccg,
|
||||
int inst);
|
||||
|
||||
};
|
||||
|
||||
#endif //__DAL_DCCG_H__
|
||||
|
||||
@@ -97,7 +97,7 @@ struct link_encoder *link_enc_cfg_get_link_enc_used_by_stream(
|
||||
const struct dc_stream_state *stream);
|
||||
|
||||
/* Return true if encoder available to use. */
|
||||
bool link_enc_cfg_is_link_enc_avail(struct dc *dc, enum engine_id eng_id);
|
||||
bool link_enc_cfg_is_link_enc_avail(struct dc *dc, enum engine_id eng_id, struct dc_link *link);
|
||||
|
||||
/* Returns true if encoder assignments in supplied state pass validity checks. */
|
||||
bool link_enc_cfg_validate(struct dc *dc, struct dc_state *state);
|
||||
|
||||
@@ -46,10 +46,10 @@
|
||||
|
||||
/* Firmware versioning. */
|
||||
#ifdef DMUB_EXPOSE_VERSION
|
||||
#define DMUB_FW_VERSION_GIT_HASH 0xf0c64c97
|
||||
#define DMUB_FW_VERSION_GIT_HASH 0xd146258f
|
||||
#define DMUB_FW_VERSION_MAJOR 0
|
||||
#define DMUB_FW_VERSION_MINOR 0
|
||||
#define DMUB_FW_VERSION_REVISION 87
|
||||
#define DMUB_FW_VERSION_REVISION 88
|
||||
#define DMUB_FW_VERSION_TEST 0
|
||||
#define DMUB_FW_VERSION_VBIOS 0
|
||||
#define DMUB_FW_VERSION_HOTFIX 0
|
||||
|
||||
@@ -228,7 +228,7 @@ enum {
|
||||
#define FAMILY_YELLOW_CARP 146
|
||||
|
||||
#define YELLOW_CARP_A0 0x01
|
||||
#define YELLOW_CARP_B0 0x1A
|
||||
#define YELLOW_CARP_B0 0x20
|
||||
#define YELLOW_CARP_UNKNOWN 0xFF
|
||||
|
||||
#ifndef ASICREV_IS_YELLOW_CARP
|
||||
|
||||
@@ -228,7 +228,7 @@ enum DC_FEATURE_MASK {
|
||||
DC_FBC_MASK = (1 << 0), //0x1, disabled by default
|
||||
DC_MULTI_MON_PP_MCLK_SWITCH_MASK = (1 << 1), //0x2, enabled by default
|
||||
DC_DISABLE_FRACTIONAL_PWM_MASK = (1 << 2), //0x4, disabled by default
|
||||
DC_PSR_MASK = (1 << 3), //0x8, disabled by default
|
||||
DC_PSR_MASK = (1 << 3), //0x8, disabled by default for dcn < 3.1
|
||||
DC_EDP_NO_POWER_SEQUENCING = (1 << 4), //0x10, disabled by default
|
||||
};
|
||||
|
||||
@@ -236,7 +236,8 @@ enum DC_DEBUG_MASK {
|
||||
DC_DISABLE_PIPE_SPLIT = 0x1,
|
||||
DC_DISABLE_STUTTER = 0x2,
|
||||
DC_DISABLE_DSC = 0x4,
|
||||
DC_DISABLE_CLOCK_GATING = 0x8
|
||||
DC_DISABLE_CLOCK_GATING = 0x8,
|
||||
DC_DISABLE_PSR = 0x10,
|
||||
};
|
||||
|
||||
enum amd_dpm_forced_level;
|
||||
|
||||
@@ -436,6 +436,8 @@
|
||||
#define regPHYESYMCLK_CLOCK_CNTL_BASE_IDX 2
|
||||
#define regDCCG_GATE_DISABLE_CNTL3 0x005a
|
||||
#define regDCCG_GATE_DISABLE_CNTL3_BASE_IDX 2
|
||||
#define regHDMISTREAMCLK0_DTO_PARAM 0x005b
|
||||
#define regHDMISTREAMCLK0_DTO_PARAM_BASE_IDX 2
|
||||
#define regDCCG_AUDIO_DTBCLK_DTO_PHASE 0x0061
|
||||
#define regDCCG_AUDIO_DTBCLK_DTO_PHASE_BASE_IDX 2
|
||||
#define regDCCG_AUDIO_DTBCLK_DTO_MODULO 0x0062
|
||||
|
||||
@@ -1438,6 +1438,14 @@
|
||||
#define DCCG_GATE_DISABLE_CNTL3__SYMCLK32_LE0_GATE_DISABLE_MASK 0x00200000L
|
||||
#define DCCG_GATE_DISABLE_CNTL3__SYMCLK32_ROOT_LE1_GATE_DISABLE_MASK 0x00400000L
|
||||
#define DCCG_GATE_DISABLE_CNTL3__SYMCLK32_LE1_GATE_DISABLE_MASK 0x00800000L
|
||||
//HDMISTREAMCLK0_DTO_PARAM
|
||||
#define HDMISTREAMCLK0_DTO_PARAM__HDMISTREAMCLK0_DTO_PHASE__SHIFT 0x0
|
||||
#define HDMISTREAMCLK0_DTO_PARAM__HDMISTREAMCLK0_DTO_MODULO__SHIFT 0x8
|
||||
#define HDMISTREAMCLK0_DTO_PARAM__HDMISTREAMCLK0_DTO_EN__SHIFT 0x10
|
||||
#define HDMISTREAMCLK0_DTO_PARAM__HDMISTREAMCLK0_DTO_PHASE_MASK 0x000000FFL
|
||||
#define HDMISTREAMCLK0_DTO_PARAM__HDMISTREAMCLK0_DTO_MODULO_MASK 0x0000FF00L
|
||||
#define HDMISTREAMCLK0_DTO_PARAM__HDMISTREAMCLK0_DTO_EN_MASK 0x00010000L
|
||||
|
||||
//DCCG_AUDIO_DTBCLK_DTO_PHASE
|
||||
#define DCCG_AUDIO_DTBCLK_DTO_PHASE__DCCG_AUDIO_DTBCLK_DTO_PHASE__SHIFT 0x0
|
||||
#define DCCG_AUDIO_DTBCLK_DTO_PHASE__DCCG_AUDIO_DTBCLK_DTO_PHASE_MASK 0xFFFFFFFFL
|
||||
|
||||
@@ -2019,15 +2019,15 @@ static struct amdgpu_device_attr amdgpu_device_attrs[] = {
|
||||
AMDGPU_DEVICE_ATTR_RW(pp_dpm_pcie, ATTR_FLAG_BASIC),
|
||||
AMDGPU_DEVICE_ATTR_RW(pp_sclk_od, ATTR_FLAG_BASIC),
|
||||
AMDGPU_DEVICE_ATTR_RW(pp_mclk_od, ATTR_FLAG_BASIC),
|
||||
AMDGPU_DEVICE_ATTR_RW(pp_power_profile_mode, ATTR_FLAG_BASIC),
|
||||
AMDGPU_DEVICE_ATTR_RW(pp_power_profile_mode, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF),
|
||||
AMDGPU_DEVICE_ATTR_RW(pp_od_clk_voltage, ATTR_FLAG_BASIC),
|
||||
AMDGPU_DEVICE_ATTR_RO(gpu_busy_percent, ATTR_FLAG_BASIC),
|
||||
AMDGPU_DEVICE_ATTR_RO(mem_busy_percent, ATTR_FLAG_BASIC),
|
||||
AMDGPU_DEVICE_ATTR_RO(gpu_busy_percent, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF),
|
||||
AMDGPU_DEVICE_ATTR_RO(mem_busy_percent, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF),
|
||||
AMDGPU_DEVICE_ATTR_RO(pcie_bw, ATTR_FLAG_BASIC),
|
||||
AMDGPU_DEVICE_ATTR_RW(pp_features, ATTR_FLAG_BASIC),
|
||||
AMDGPU_DEVICE_ATTR_RO(unique_id, ATTR_FLAG_BASIC),
|
||||
AMDGPU_DEVICE_ATTR_RW(thermal_throttling_logging, ATTR_FLAG_BASIC),
|
||||
AMDGPU_DEVICE_ATTR_RO(gpu_metrics, ATTR_FLAG_BASIC),
|
||||
AMDGPU_DEVICE_ATTR_RW(pp_features, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF),
|
||||
AMDGPU_DEVICE_ATTR_RO(unique_id, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF),
|
||||
AMDGPU_DEVICE_ATTR_RW(thermal_throttling_logging, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF),
|
||||
AMDGPU_DEVICE_ATTR_RO(gpu_metrics, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF),
|
||||
AMDGPU_DEVICE_ATTR_RO(smartshift_apu_power, ATTR_FLAG_BASIC,
|
||||
.attr_update = ss_power_attr_update),
|
||||
AMDGPU_DEVICE_ATTR_RO(smartshift_dgpu_power, ATTR_FLAG_BASIC,
|
||||
|
||||
@@ -1008,7 +1008,9 @@ struct pptable_funcs {
|
||||
/**
|
||||
* @set_power_limit: Set power limit in watts.
|
||||
*/
|
||||
int (*set_power_limit)(struct smu_context *smu, uint32_t n);
|
||||
int (*set_power_limit)(struct smu_context *smu,
|
||||
enum smu_ppt_limit_type limit_type,
|
||||
uint32_t limit);
|
||||
|
||||
/**
|
||||
* @init_max_sustainable_clocks: Populate max sustainable clock speed
|
||||
|
||||
@@ -197,7 +197,9 @@ int smu_v11_0_notify_display_change(struct smu_context *smu);
|
||||
int smu_v11_0_get_current_power_limit(struct smu_context *smu,
|
||||
uint32_t *power_limit);
|
||||
|
||||
int smu_v11_0_set_power_limit(struct smu_context *smu, uint32_t n);
|
||||
int smu_v11_0_set_power_limit(struct smu_context *smu,
|
||||
enum smu_ppt_limit_type limit_type,
|
||||
uint32_t limit);
|
||||
|
||||
int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu);
|
||||
|
||||
|
||||
@@ -163,7 +163,9 @@ int smu_v13_0_notify_display_change(struct smu_context *smu);
|
||||
int smu_v13_0_get_current_power_limit(struct smu_context *smu,
|
||||
uint32_t *power_limit);
|
||||
|
||||
int smu_v13_0_set_power_limit(struct smu_context *smu, uint32_t n);
|
||||
int smu_v13_0_set_power_limit(struct smu_context *smu,
|
||||
enum smu_ppt_limit_type limit_type,
|
||||
uint32_t limit);
|
||||
|
||||
int smu_v13_0_init_max_sustainable_clocks(struct smu_context *smu);
|
||||
|
||||
|
||||
@@ -455,6 +455,10 @@ static int smu_get_power_num_states(void *handle,
|
||||
|
||||
bool is_support_sw_smu(struct amdgpu_device *adev)
|
||||
{
|
||||
/* vega20 is 11.0.2, but it's supported via the powerplay code */
|
||||
if (adev->asic_type == CHIP_VEGA20)
|
||||
return false;
|
||||
|
||||
if (adev->ip_versions[MP1_HWIP][0] >= IP_VERSION(11, 0, 0))
|
||||
return true;
|
||||
|
||||
@@ -2344,9 +2348,10 @@ static int smu_set_power_limit(void *handle, uint32_t limit)
|
||||
|
||||
mutex_lock(&smu->mutex);
|
||||
|
||||
limit &= (1<<24)-1;
|
||||
if (limit_type != SMU_DEFAULT_PPT_LIMIT)
|
||||
if (smu->ppt_funcs->set_power_limit) {
|
||||
ret = smu->ppt_funcs->set_power_limit(smu, limit);
|
||||
ret = smu->ppt_funcs->set_power_limit(smu, limit_type, limit);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -2362,7 +2367,7 @@ static int smu_set_power_limit(void *handle, uint32_t limit)
|
||||
limit = smu->current_power_limit;
|
||||
|
||||
if (smu->ppt_funcs->set_power_limit) {
|
||||
ret = smu->ppt_funcs->set_power_limit(smu, limit);
|
||||
ret = smu->ppt_funcs->set_power_limit(smu, limit_type, limit);
|
||||
if (!ret && !(smu->user_dpm_profile.flags & SMU_DPM_USER_PROFILE_RESTORE))
|
||||
smu->user_dpm_profile.power_limit = limit;
|
||||
}
|
||||
|
||||
@@ -436,6 +436,19 @@ static void arcturus_check_bxco_support(struct smu_context *smu)
|
||||
}
|
||||
}
|
||||
|
||||
static void arcturus_check_fan_support(struct smu_context *smu)
|
||||
{
|
||||
struct smu_table_context *table_context = &smu->smu_table;
|
||||
PPTable_t *pptable = table_context->driver_pptable;
|
||||
|
||||
/* No sort of fan control possible if PPTable has it disabled */
|
||||
smu->adev->pm.no_fan =
|
||||
!(pptable->FeaturesToRun[0] & FEATURE_FAN_CONTROL_MASK);
|
||||
if (smu->adev->pm.no_fan)
|
||||
dev_info_once(smu->adev->dev,
|
||||
"PMFW based fan control disabled");
|
||||
}
|
||||
|
||||
static int arcturus_check_powerplay_table(struct smu_context *smu)
|
||||
{
|
||||
struct smu_table_context *table_context = &smu->smu_table;
|
||||
@@ -443,6 +456,7 @@ static int arcturus_check_powerplay_table(struct smu_context *smu)
|
||||
table_context->power_play_table;
|
||||
|
||||
arcturus_check_bxco_support(smu);
|
||||
arcturus_check_fan_support(smu);
|
||||
|
||||
table_context->thermal_controller_type =
|
||||
powerplay_table->thermal_controller_type;
|
||||
|
||||
@@ -47,7 +47,6 @@
|
||||
/* unit: MHz */
|
||||
#define CYAN_SKILLFISH_SCLK_MIN 1000
|
||||
#define CYAN_SKILLFISH_SCLK_MAX 2000
|
||||
#define CYAN_SKILLFISH_SCLK_DEFAULT 1800
|
||||
|
||||
/* unit: mV */
|
||||
#define CYAN_SKILLFISH_VDDC_MIN 700
|
||||
@@ -59,6 +58,8 @@ static struct gfx_user_settings {
|
||||
uint32_t vddc;
|
||||
} cyan_skillfish_user_settings;
|
||||
|
||||
static uint32_t cyan_skillfish_sclk_default;
|
||||
|
||||
#define FEATURE_MASK(feature) (1ULL << feature)
|
||||
#define SMC_DPM_FEATURE ( \
|
||||
FEATURE_MASK(FEATURE_FCLK_DPM_BIT) | \
|
||||
@@ -365,13 +366,19 @@ static bool cyan_skillfish_is_dpm_running(struct smu_context *smu)
|
||||
return false;
|
||||
|
||||
ret = smu_cmn_get_enabled_32_bits_mask(smu, feature_mask, 2);
|
||||
|
||||
if (ret)
|
||||
return false;
|
||||
|
||||
feature_enabled = (uint64_t)feature_mask[0] |
|
||||
((uint64_t)feature_mask[1] << 32);
|
||||
|
||||
/*
|
||||
* cyan_skillfish specific, query default sclk inseted of hard code.
|
||||
*/
|
||||
if (!cyan_skillfish_sclk_default)
|
||||
cyan_skillfish_get_smu_metrics_data(smu, METRICS_CURR_GFXCLK,
|
||||
&cyan_skillfish_sclk_default);
|
||||
|
||||
return !!(feature_enabled & SMC_DPM_FEATURE);
|
||||
}
|
||||
|
||||
@@ -444,14 +451,14 @@ static int cyan_skillfish_od_edit_dpm_table(struct smu_context *smu,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (input[1] <= CYAN_SKILLFISH_SCLK_MIN ||
|
||||
if (input[1] < CYAN_SKILLFISH_SCLK_MIN ||
|
||||
input[1] > CYAN_SKILLFISH_SCLK_MAX) {
|
||||
dev_err(smu->adev->dev, "Invalid sclk! Valid sclk range: %uMHz - %uMhz\n",
|
||||
CYAN_SKILLFISH_SCLK_MIN, CYAN_SKILLFISH_SCLK_MAX);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (input[2] <= CYAN_SKILLFISH_VDDC_MIN ||
|
||||
if (input[2] < CYAN_SKILLFISH_VDDC_MIN ||
|
||||
input[2] > CYAN_SKILLFISH_VDDC_MAX) {
|
||||
dev_err(smu->adev->dev, "Invalid vddc! Valid vddc range: %umV - %umV\n",
|
||||
CYAN_SKILLFISH_VDDC_MIN, CYAN_SKILLFISH_VDDC_MAX);
|
||||
@@ -468,7 +475,7 @@ static int cyan_skillfish_od_edit_dpm_table(struct smu_context *smu,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cyan_skillfish_user_settings.sclk = CYAN_SKILLFISH_SCLK_DEFAULT;
|
||||
cyan_skillfish_user_settings.sclk = cyan_skillfish_sclk_default;
|
||||
cyan_skillfish_user_settings.vddc = CYAN_SKILLFISH_VDDC_MAGIC;
|
||||
|
||||
break;
|
||||
|
||||
@@ -670,7 +670,7 @@ static int sienna_cichlid_set_default_dpm_table(struct smu_context *smu)
|
||||
struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
|
||||
struct smu_11_0_dpm_table *dpm_table;
|
||||
struct amdgpu_device *adev = smu->adev;
|
||||
int ret = 0;
|
||||
int i, ret = 0;
|
||||
DpmDescriptor_t *table_member;
|
||||
|
||||
/* socclk dpm table setup */
|
||||
@@ -746,78 +746,45 @@ static int sienna_cichlid_set_default_dpm_table(struct smu_context *smu)
|
||||
dpm_table->max = dpm_table->dpm_levels[0].value;
|
||||
}
|
||||
|
||||
/* vclk0 dpm table setup */
|
||||
dpm_table = &dpm_context->dpm_tables.vclk_table;
|
||||
if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) {
|
||||
ret = smu_v11_0_set_single_dpm_table(smu,
|
||||
SMU_VCLK,
|
||||
dpm_table);
|
||||
if (ret)
|
||||
return ret;
|
||||
dpm_table->is_fine_grained =
|
||||
!table_member[PPCLK_VCLK_0].SnapToDiscrete;
|
||||
} else {
|
||||
dpm_table->count = 1;
|
||||
dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.vclk / 100;
|
||||
dpm_table->dpm_levels[0].enabled = true;
|
||||
dpm_table->min = dpm_table->dpm_levels[0].value;
|
||||
dpm_table->max = dpm_table->dpm_levels[0].value;
|
||||
}
|
||||
/* vclk0/1 dpm table setup */
|
||||
for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
|
||||
if (adev->vcn.harvest_config & (1 << i))
|
||||
continue;
|
||||
|
||||
/* vclk1 dpm table setup */
|
||||
if (adev->vcn.num_vcn_inst > 1) {
|
||||
dpm_table = &dpm_context->dpm_tables.vclk1_table;
|
||||
dpm_table = &dpm_context->dpm_tables.vclk_table;
|
||||
if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) {
|
||||
ret = smu_v11_0_set_single_dpm_table(smu,
|
||||
SMU_VCLK1,
|
||||
i ? SMU_VCLK1 : SMU_VCLK,
|
||||
dpm_table);
|
||||
if (ret)
|
||||
return ret;
|
||||
dpm_table->is_fine_grained =
|
||||
!table_member[PPCLK_VCLK_1].SnapToDiscrete;
|
||||
!table_member[i ? PPCLK_VCLK_1 : PPCLK_VCLK_0].SnapToDiscrete;
|
||||
} else {
|
||||
dpm_table->count = 1;
|
||||
dpm_table->dpm_levels[0].value =
|
||||
smu->smu_table.boot_values.vclk / 100;
|
||||
dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.vclk / 100;
|
||||
dpm_table->dpm_levels[0].enabled = true;
|
||||
dpm_table->min = dpm_table->dpm_levels[0].value;
|
||||
dpm_table->max = dpm_table->dpm_levels[0].value;
|
||||
}
|
||||
}
|
||||
|
||||
/* dclk0 dpm table setup */
|
||||
dpm_table = &dpm_context->dpm_tables.dclk_table;
|
||||
if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) {
|
||||
ret = smu_v11_0_set_single_dpm_table(smu,
|
||||
SMU_DCLK,
|
||||
dpm_table);
|
||||
if (ret)
|
||||
return ret;
|
||||
dpm_table->is_fine_grained =
|
||||
!table_member[PPCLK_DCLK_0].SnapToDiscrete;
|
||||
} else {
|
||||
dpm_table->count = 1;
|
||||
dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dclk / 100;
|
||||
dpm_table->dpm_levels[0].enabled = true;
|
||||
dpm_table->min = dpm_table->dpm_levels[0].value;
|
||||
dpm_table->max = dpm_table->dpm_levels[0].value;
|
||||
}
|
||||
|
||||
/* dclk1 dpm table setup */
|
||||
if (adev->vcn.num_vcn_inst > 1) {
|
||||
dpm_table = &dpm_context->dpm_tables.dclk1_table;
|
||||
/* dclk0/1 dpm table setup */
|
||||
for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
|
||||
if (adev->vcn.harvest_config & (1 << i))
|
||||
continue;
|
||||
dpm_table = &dpm_context->dpm_tables.dclk_table;
|
||||
if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) {
|
||||
ret = smu_v11_0_set_single_dpm_table(smu,
|
||||
SMU_DCLK1,
|
||||
i ? SMU_DCLK1 : SMU_DCLK,
|
||||
dpm_table);
|
||||
if (ret)
|
||||
return ret;
|
||||
dpm_table->is_fine_grained =
|
||||
!table_member[PPCLK_DCLK_1].SnapToDiscrete;
|
||||
!table_member[i ? PPCLK_DCLK_1 : PPCLK_DCLK_0].SnapToDiscrete;
|
||||
} else {
|
||||
dpm_table->count = 1;
|
||||
dpm_table->dpm_levels[0].value =
|
||||
smu->smu_table.boot_values.dclk / 100;
|
||||
dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dclk / 100;
|
||||
dpm_table->dpm_levels[0].enabled = true;
|
||||
dpm_table->min = dpm_table->dpm_levels[0].value;
|
||||
dpm_table->max = dpm_table->dpm_levels[0].value;
|
||||
@@ -902,32 +869,18 @@ static int sienna_cichlid_set_default_dpm_table(struct smu_context *smu)
|
||||
static int sienna_cichlid_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
|
||||
{
|
||||
struct amdgpu_device *adev = smu->adev;
|
||||
int ret = 0;
|
||||
int i, ret = 0;
|
||||
|
||||
if (enable) {
|
||||
for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
|
||||
if (adev->vcn.harvest_config & (1 << i))
|
||||
continue;
|
||||
/* vcn dpm on is a prerequisite for vcn power gate messages */
|
||||
if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) {
|
||||
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpVcn, 0, NULL);
|
||||
ret = smu_cmn_send_smc_msg_with_param(smu, enable ?
|
||||
SMU_MSG_PowerUpVcn : SMU_MSG_PowerDownVcn,
|
||||
0x10000 * i, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (adev->vcn.num_vcn_inst > 1) {
|
||||
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpVcn,
|
||||
0x10000, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) {
|
||||
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownVcn, 0, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (adev->vcn.num_vcn_inst > 1) {
|
||||
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownVcn,
|
||||
0x10000, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -255,7 +255,7 @@ int smu_v11_0_check_fw_version(struct smu_context *smu)
|
||||
case IP_VERSION(11, 0, 11):
|
||||
smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_Navy_Flounder;
|
||||
break;
|
||||
case CHIP_VANGOGH:
|
||||
case IP_VERSION(11, 5, 0):
|
||||
smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_VANGOGH;
|
||||
break;
|
||||
case IP_VERSION(11, 0, 12):
|
||||
@@ -755,6 +755,7 @@ int smu_v11_0_init_display_count(struct smu_context *smu, uint32_t count)
|
||||
*/
|
||||
if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 11) ||
|
||||
adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 5, 0) ||
|
||||
adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 12) ||
|
||||
adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 13))
|
||||
return 0;
|
||||
|
||||
@@ -978,10 +979,16 @@ int smu_v11_0_get_current_power_limit(struct smu_context *smu,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int smu_v11_0_set_power_limit(struct smu_context *smu, uint32_t n)
|
||||
int smu_v11_0_set_power_limit(struct smu_context *smu,
|
||||
enum smu_ppt_limit_type limit_type,
|
||||
uint32_t limit)
|
||||
{
|
||||
int power_src;
|
||||
int ret = 0;
|
||||
uint32_t limit_param;
|
||||
|
||||
if (limit_type != SMU_DEFAULT_PPT_LIMIT)
|
||||
return -EINVAL;
|
||||
|
||||
if (!smu_cmn_feature_is_enabled(smu, SMU_FEATURE_PPT_BIT)) {
|
||||
dev_err(smu->adev->dev, "Setting new power limit is not supported!\n");
|
||||
@@ -1001,16 +1008,16 @@ int smu_v11_0_set_power_limit(struct smu_context *smu, uint32_t n)
|
||||
* BIT 16-23: PowerSource
|
||||
* BIT 0-15: PowerLimit
|
||||
*/
|
||||
n &= 0xFFFF;
|
||||
n |= 0 << 24;
|
||||
n |= (power_src) << 16;
|
||||
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetPptLimit, n, NULL);
|
||||
limit_param = (limit & 0xFFFF);
|
||||
limit_param |= 0 << 24;
|
||||
limit_param |= (power_src) << 16;
|
||||
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetPptLimit, limit_param, NULL);
|
||||
if (ret) {
|
||||
dev_err(smu->adev->dev, "[%s] Set power limit Failed!\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
smu->current_power_limit = n;
|
||||
smu->current_power_limit = limit;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1386,52 +1386,38 @@ static int vangogh_set_performance_level(struct smu_context *smu,
|
||||
uint32_t soc_mask, mclk_mask, fclk_mask;
|
||||
uint32_t vclk_mask = 0, dclk_mask = 0;
|
||||
|
||||
smu->cpu_actual_soft_min_freq = smu->cpu_default_soft_min_freq;
|
||||
smu->cpu_actual_soft_max_freq = smu->cpu_default_soft_max_freq;
|
||||
|
||||
switch (level) {
|
||||
case AMD_DPM_FORCED_LEVEL_HIGH:
|
||||
smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
|
||||
smu->gfx_actual_hard_min_freq = smu->gfx_default_soft_max_freq;
|
||||
smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
|
||||
|
||||
smu->cpu_actual_soft_min_freq = smu->cpu_default_soft_min_freq;
|
||||
smu->cpu_actual_soft_max_freq = smu->cpu_default_soft_max_freq;
|
||||
|
||||
ret = vangogh_force_dpm_limit_value(smu, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
case AMD_DPM_FORCED_LEVEL_LOW:
|
||||
smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
|
||||
smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
|
||||
|
||||
smu->cpu_actual_soft_min_freq = smu->cpu_default_soft_min_freq;
|
||||
smu->cpu_actual_soft_max_freq = smu->cpu_default_soft_max_freq;
|
||||
smu->gfx_actual_soft_max_freq = smu->gfx_default_hard_min_freq;
|
||||
|
||||
ret = vangogh_force_dpm_limit_value(smu, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
case AMD_DPM_FORCED_LEVEL_AUTO:
|
||||
smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
|
||||
smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
|
||||
|
||||
smu->cpu_actual_soft_min_freq = smu->cpu_default_soft_min_freq;
|
||||
smu->cpu_actual_soft_max_freq = smu->cpu_default_soft_max_freq;
|
||||
|
||||
ret = vangogh_unforce_dpm_levels(smu);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
|
||||
smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
|
||||
smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
|
||||
|
||||
smu->cpu_actual_soft_min_freq = smu->cpu_default_soft_min_freq;
|
||||
smu->cpu_actual_soft_max_freq = smu->cpu_default_soft_max_freq;
|
||||
|
||||
ret = smu_cmn_send_smc_msg_with_param(smu,
|
||||
SMU_MSG_SetHardMinGfxClk,
|
||||
VANGOGH_UMD_PSTATE_STANDARD_GFXCLK, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = smu_cmn_send_smc_msg_with_param(smu,
|
||||
SMU_MSG_SetSoftMaxGfxClk,
|
||||
VANGOGH_UMD_PSTATE_STANDARD_GFXCLK, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
smu->gfx_actual_hard_min_freq = VANGOGH_UMD_PSTATE_STANDARD_GFXCLK;
|
||||
smu->gfx_actual_soft_max_freq = VANGOGH_UMD_PSTATE_STANDARD_GFXCLK;
|
||||
|
||||
ret = vangogh_get_profiling_clk_mask(smu, level,
|
||||
&vclk_mask,
|
||||
@@ -1446,32 +1432,15 @@ static int vangogh_set_performance_level(struct smu_context *smu,
|
||||
vangogh_force_clk_levels(smu, SMU_SOCCLK, 1 << soc_mask);
|
||||
vangogh_force_clk_levels(smu, SMU_VCLK, 1 << vclk_mask);
|
||||
vangogh_force_clk_levels(smu, SMU_DCLK, 1 << dclk_mask);
|
||||
|
||||
break;
|
||||
case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
|
||||
smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
|
||||
smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
|
||||
|
||||
smu->cpu_actual_soft_min_freq = smu->cpu_default_soft_min_freq;
|
||||
smu->cpu_actual_soft_max_freq = smu->cpu_default_soft_max_freq;
|
||||
|
||||
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinVcn,
|
||||
VANGOGH_UMD_PSTATE_PEAK_DCLK, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxVcn,
|
||||
VANGOGH_UMD_PSTATE_PEAK_DCLK, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
smu->gfx_actual_soft_max_freq = smu->gfx_default_hard_min_freq;
|
||||
break;
|
||||
case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
|
||||
smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
|
||||
smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
|
||||
|
||||
smu->cpu_actual_soft_min_freq = smu->cpu_default_soft_min_freq;
|
||||
smu->cpu_actual_soft_max_freq = smu->cpu_default_soft_max_freq;
|
||||
|
||||
ret = vangogh_get_profiling_clk_mask(smu, level,
|
||||
NULL,
|
||||
NULL,
|
||||
@@ -1484,29 +1453,29 @@ static int vangogh_set_performance_level(struct smu_context *smu,
|
||||
vangogh_force_clk_levels(smu, SMU_FCLK, 1 << fclk_mask);
|
||||
break;
|
||||
case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
|
||||
smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
|
||||
smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
|
||||
|
||||
smu->cpu_actual_soft_min_freq = smu->cpu_default_soft_min_freq;
|
||||
smu->cpu_actual_soft_max_freq = smu->cpu_default_soft_max_freq;
|
||||
|
||||
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinGfxClk,
|
||||
VANGOGH_UMD_PSTATE_PEAK_GFXCLK, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk,
|
||||
VANGOGH_UMD_PSTATE_PEAK_GFXCLK, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
smu->gfx_actual_hard_min_freq = VANGOGH_UMD_PSTATE_PEAK_GFXCLK;
|
||||
smu->gfx_actual_soft_max_freq = VANGOGH_UMD_PSTATE_PEAK_GFXCLK;
|
||||
|
||||
ret = vangogh_set_peak_clock_by_device(smu);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
case AMD_DPM_FORCED_LEVEL_MANUAL:
|
||||
case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
|
||||
default:
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinGfxClk,
|
||||
smu->gfx_actual_hard_min_freq, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk,
|
||||
smu->gfx_actual_soft_max_freq, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2144,11 +2113,12 @@ static int vangogh_get_ppt_limit(struct smu_context *smu,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vangogh_set_power_limit(struct smu_context *smu, uint32_t ppt_limit)
|
||||
static int vangogh_set_power_limit(struct smu_context *smu,
|
||||
enum smu_ppt_limit_type limit_type,
|
||||
uint32_t ppt_limit)
|
||||
{
|
||||
struct smu_11_5_power_context *power_context =
|
||||
smu->smu_power.power_context;
|
||||
uint32_t limit_type = ppt_limit >> 24;
|
||||
smu->smu_power.power_context;
|
||||
int ret = 0;
|
||||
|
||||
if (!smu_cmn_feature_is_enabled(smu, SMU_FEATURE_PPT_BIT)) {
|
||||
|
||||
@@ -1241,11 +1241,13 @@ static int aldebaran_get_power_limit(struct smu_context *smu,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aldebaran_set_power_limit(struct smu_context *smu, uint32_t n)
|
||||
static int aldebaran_set_power_limit(struct smu_context *smu,
|
||||
enum smu_ppt_limit_type limit_type,
|
||||
uint32_t limit)
|
||||
{
|
||||
/* Power limit can be set only through primary die */
|
||||
if (aldebaran_is_primary(smu))
|
||||
return smu_v13_0_set_power_limit(smu, n);
|
||||
return smu_v13_0_set_power_limit(smu, limit_type, limit);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -945,22 +945,27 @@ int smu_v13_0_get_current_power_limit(struct smu_context *smu,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int smu_v13_0_set_power_limit(struct smu_context *smu, uint32_t n)
|
||||
int smu_v13_0_set_power_limit(struct smu_context *smu,
|
||||
enum smu_ppt_limit_type limit_type,
|
||||
uint32_t limit)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (limit_type != SMU_DEFAULT_PPT_LIMIT)
|
||||
return -EINVAL;
|
||||
|
||||
if (!smu_cmn_feature_is_enabled(smu, SMU_FEATURE_PPT_BIT)) {
|
||||
dev_err(smu->adev->dev, "Setting new power limit is not supported!\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetPptLimit, n, NULL);
|
||||
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetPptLimit, limit, NULL);
|
||||
if (ret) {
|
||||
dev_err(smu->adev->dev, "[%s] Set power limit Failed!\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
smu->current_power_limit = n;
|
||||
smu->current_power_limit = limit;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user