mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-10 23:29:46 +00:00
Merge tag 'drm-next-5.4-2019-08-30' of git://people.freedesktop.org/~agd5f/linux into drm-next
drm-next-5.4-2019-08-30: amdgpu: - Add DC support for Renoir - Add some GPUVM hw bug workarounds - add support for the smu11 i2c controller - GPU reset vram lost bug fixes - Navi1x powergating fixes - Navi12 power fixes - Renoir power fixes - Misc bug fixes and cleanups Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexdeucher@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190830212650.5055-1-alexander.deucher@amd.com
This commit is contained in:
commit
9ed45a209a
@ -63,7 +63,6 @@ obj-$(CONFIG_DRM_TTM) += ttm/
|
||||
obj-$(CONFIG_DRM_SCHED) += scheduler/
|
||||
obj-$(CONFIG_DRM_TDFX) += tdfx/
|
||||
obj-$(CONFIG_DRM_R128) += r128/
|
||||
obj-$(CONFIG_HSA_AMD) += amd/amdkfd/
|
||||
obj-$(CONFIG_DRM_RADEON)+= radeon/
|
||||
obj-$(CONFIG_DRM_AMDGPU)+= amd/amdgpu/
|
||||
obj-$(CONFIG_DRM_MGA) += mga/
|
||||
|
@ -54,7 +54,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \
|
||||
amdgpu_gtt_mgr.o amdgpu_vram_mgr.o amdgpu_virt.o amdgpu_atomfirmware.o \
|
||||
amdgpu_vf_error.o amdgpu_sched.o amdgpu_debugfs.o amdgpu_ids.o \
|
||||
amdgpu_gmc.o amdgpu_xgmi.o amdgpu_csa.o amdgpu_ras.o amdgpu_vm_cpu.o \
|
||||
amdgpu_vm_sdma.o amdgpu_discovery.o
|
||||
amdgpu_vm_sdma.o amdgpu_pmu.o amdgpu_discovery.o amdgpu_ras_eeprom.o smu_v11_0_i2c.o
|
||||
|
||||
amdgpu-$(CONFIG_PERF_EVENTS) += amdgpu_pmu.o
|
||||
|
||||
|
@ -1151,6 +1151,7 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
|
||||
#define amdgpu_asic_get_pcie_usage(adev, cnt0, cnt1) ((adev)->asic_funcs->get_pcie_usage((adev), (cnt0), (cnt1)))
|
||||
#define amdgpu_asic_need_reset_on_init(adev) (adev)->asic_funcs->need_reset_on_init((adev))
|
||||
#define amdgpu_asic_get_pcie_replay_count(adev) ((adev)->asic_funcs->get_pcie_replay_count((adev)))
|
||||
#define amdgpu_inc_vram_lost(adev) atomic_inc(&((adev)->vram_lost_counter));
|
||||
|
||||
/* Common functions */
|
||||
bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev);
|
||||
|
@ -574,6 +574,7 @@ static const struct amdgpu_px_quirk amdgpu_px_quirk_list[] = {
|
||||
{ 0x1002, 0x6900, 0x1002, 0x0124, AMDGPU_PX_QUIRK_FORCE_ATPX },
|
||||
{ 0x1002, 0x6900, 0x1028, 0x0812, AMDGPU_PX_QUIRK_FORCE_ATPX },
|
||||
{ 0x1002, 0x6900, 0x1028, 0x0813, AMDGPU_PX_QUIRK_FORCE_ATPX },
|
||||
{ 0x1002, 0x699f, 0x1028, 0x0814, AMDGPU_PX_QUIRK_FORCE_ATPX },
|
||||
{ 0x1002, 0x6900, 0x1025, 0x125A, AMDGPU_PX_QUIRK_FORCE_ATPX },
|
||||
{ 0x1002, 0x6900, 0x17AA, 0x3806, AMDGPU_PX_QUIRK_FORCE_ATPX },
|
||||
{ 0, 0, 0, 0, 0 },
|
||||
|
@ -2518,6 +2518,9 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type)
|
||||
case CHIP_NAVI10:
|
||||
case CHIP_NAVI14:
|
||||
case CHIP_NAVI12:
|
||||
#endif
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
case CHIP_RENOIR:
|
||||
#endif
|
||||
return amdgpu_dc != 0;
|
||||
#endif
|
||||
@ -3483,7 +3486,7 @@ error:
|
||||
amdgpu_virt_init_data_exchange(adev);
|
||||
amdgpu_virt_release_full_gpu(adev, true);
|
||||
if (!r && adev->virt.gim_feature & AMDGIM_FEATURE_GIM_FLR_VRAMLOST) {
|
||||
atomic_inc(&adev->vram_lost_counter);
|
||||
amdgpu_inc_vram_lost(adev);
|
||||
r = amdgpu_device_recover_vram(adev);
|
||||
}
|
||||
|
||||
@ -3649,7 +3652,7 @@ static int amdgpu_do_asic_reset(struct amdgpu_hive_info *hive,
|
||||
vram_lost = amdgpu_device_check_vram_lost(tmp_adev);
|
||||
if (vram_lost) {
|
||||
DRM_INFO("VRAM is lost due to GPU reset!\n");
|
||||
atomic_inc(&tmp_adev->vram_lost_counter);
|
||||
amdgpu_inc_vram_lost(tmp_adev);
|
||||
}
|
||||
|
||||
r = amdgpu_gtt_mgr_recover(
|
||||
@ -3791,14 +3794,14 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
||||
|
||||
if (hive && !mutex_trylock(&hive->reset_lock)) {
|
||||
DRM_INFO("Bailing on TDR for s_job:%llx, hive: %llx as another already in progress",
|
||||
job->base.id, hive->hive_id);
|
||||
job ? job->base.id : -1, hive->hive_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Start with adev pre asic reset first for soft reset check.*/
|
||||
if (!amdgpu_device_lock_adev(adev, !hive)) {
|
||||
DRM_INFO("Bailing on TDR for s_job:%llx, as another already in progress",
|
||||
job->base.id);
|
||||
job ? job->base.id : -1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3839,7 +3842,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
||||
if (!ring || !ring->sched.thread)
|
||||
continue;
|
||||
|
||||
drm_sched_stop(&ring->sched, &job->base);
|
||||
drm_sched_stop(&ring->sched, job ? &job->base : NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3864,9 +3867,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
||||
|
||||
|
||||
/* Guilty job will be freed after this*/
|
||||
r = amdgpu_device_pre_asic_reset(adev,
|
||||
job,
|
||||
&need_full_reset);
|
||||
r = amdgpu_device_pre_asic_reset(adev, job, &need_full_reset);
|
||||
if (r) {
|
||||
/*TODO Should we stop ?*/
|
||||
DRM_ERROR("GPU pre asic reset failed with err, %d for drm dev, %s ",
|
||||
|
@ -2349,7 +2349,9 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj,
|
||||
effective_mode &= ~S_IWUSR;
|
||||
}
|
||||
|
||||
if ((adev->flags & AMD_IS_APU) &&
|
||||
if (((adev->flags & AMD_IS_APU) ||
|
||||
adev->family == AMDGPU_FAMILY_SI || /* not implemented yet */
|
||||
adev->family == AMDGPU_FAMILY_KV) && /* not implemented yet */
|
||||
(attr == &sensor_dev_attr_power1_average.dev_attr.attr ||
|
||||
attr == &sensor_dev_attr_power1_cap_max.dev_attr.attr ||
|
||||
attr == &sensor_dev_attr_power1_cap_min.dev_attr.attr||
|
||||
@ -2373,6 +2375,12 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((adev->family == AMDGPU_FAMILY_SI || /* not implemented yet */
|
||||
adev->family == AMDGPU_FAMILY_KV) && /* not implemented yet */
|
||||
(attr == &sensor_dev_attr_in0_input.dev_attr.attr ||
|
||||
attr == &sensor_dev_attr_in0_label.dev_attr.attr))
|
||||
return 0;
|
||||
|
||||
/* only APUs have vddnb */
|
||||
if (!(adev->flags & AMD_IS_APU) &&
|
||||
(attr == &sensor_dev_attr_in1_input.dev_attr.attr ||
|
||||
|
@ -239,6 +239,8 @@ static int psp_tmr_init(struct psp_context *psp)
|
||||
{
|
||||
int ret;
|
||||
int tmr_size;
|
||||
void *tmr_buf;
|
||||
void **pptr;
|
||||
|
||||
/*
|
||||
* According to HW engineer, they prefer the TMR address be "naturally
|
||||
@ -261,9 +263,10 @@ static int psp_tmr_init(struct psp_context *psp)
|
||||
}
|
||||
}
|
||||
|
||||
pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL;
|
||||
ret = amdgpu_bo_create_kernel(psp->adev, tmr_size, PSP_TMR_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
&psp->tmr_bo, &psp->tmr_mc_addr, NULL);
|
||||
&psp->tmr_bo, &psp->tmr_mc_addr, pptr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1206,6 +1209,8 @@ static int psp_hw_fini(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct psp_context *psp = &adev->psp;
|
||||
void *tmr_buf;
|
||||
void **pptr;
|
||||
|
||||
if (adev->gmc.xgmi.num_physical_nodes > 1 &&
|
||||
psp->xgmi_context.initialized == 1)
|
||||
@ -1216,7 +1221,8 @@ static int psp_hw_fini(void *handle)
|
||||
|
||||
psp_ring_destroy(psp, PSP_RING_TYPE__KM);
|
||||
|
||||
amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, NULL);
|
||||
pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL;
|
||||
amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, pptr);
|
||||
amdgpu_bo_free_kernel(&psp->fw_pri_bo,
|
||||
&psp->fw_pri_mc_addr, &psp->fw_pri_buf);
|
||||
amdgpu_bo_free_kernel(&psp->fence_buf_bo,
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_psp.h"
|
||||
#include "ta_ras_if.h"
|
||||
#include "amdgpu_ras_eeprom.h"
|
||||
|
||||
enum amdgpu_ras_block {
|
||||
AMDGPU_RAS_BLOCK__UMC = 0,
|
||||
@ -333,6 +334,8 @@ struct amdgpu_ras {
|
||||
struct mutex recovery_lock;
|
||||
|
||||
uint32_t flags;
|
||||
|
||||
struct amdgpu_ras_eeprom_control eeprom_control;
|
||||
};
|
||||
|
||||
struct ras_fs_data {
|
||||
|
493
drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c
Normal file
493
drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c
Normal file
@ -0,0 +1,493 @@
|
||||
/*
|
||||
* 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_ras_eeprom.h"
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_ras.h"
|
||||
#include <linux/bits.h>
|
||||
#include "smu_v11_0_i2c.h"
|
||||
|
||||
#define EEPROM_I2C_TARGET_ADDR 0xA0
|
||||
|
||||
/*
|
||||
* The 2 macros bellow represent the actual size in bytes that
|
||||
* those entities occupy in the EEPROM memory.
|
||||
* EEPROM_TABLE_RECORD_SIZE is different than sizeof(eeprom_table_record) which
|
||||
* uses uint64 to store 6b fields such as retired_page.
|
||||
*/
|
||||
#define EEPROM_TABLE_HEADER_SIZE 20
|
||||
#define EEPROM_TABLE_RECORD_SIZE 24
|
||||
|
||||
#define EEPROM_ADDRESS_SIZE 0x2
|
||||
|
||||
/* Table hdr is 'AMDR' */
|
||||
#define EEPROM_TABLE_HDR_VAL 0x414d4452
|
||||
#define EEPROM_TABLE_VER 0x00010000
|
||||
|
||||
/* Assume 2 Mbit size */
|
||||
#define EEPROM_SIZE_BYTES 256000
|
||||
#define EEPROM_PAGE__SIZE_BYTES 256
|
||||
#define EEPROM_HDR_START 0
|
||||
#define EEPROM_RECORD_START (EEPROM_HDR_START + EEPROM_TABLE_HEADER_SIZE)
|
||||
#define EEPROM_MAX_RECORD_NUM ((EEPROM_SIZE_BYTES - EEPROM_TABLE_HEADER_SIZE) / EEPROM_TABLE_RECORD_SIZE)
|
||||
#define EEPROM_ADDR_MSB_MASK GENMASK(17, 8)
|
||||
|
||||
#define to_amdgpu_device(x) (container_of(x, struct amdgpu_ras, eeprom_control))->adev
|
||||
|
||||
static void __encode_table_header_to_buff(struct amdgpu_ras_eeprom_table_header *hdr,
|
||||
unsigned char *buff)
|
||||
{
|
||||
uint32_t *pp = (uint32_t *) buff;
|
||||
|
||||
pp[0] = cpu_to_le32(hdr->header);
|
||||
pp[1] = cpu_to_le32(hdr->version);
|
||||
pp[2] = cpu_to_le32(hdr->first_rec_offset);
|
||||
pp[3] = cpu_to_le32(hdr->tbl_size);
|
||||
pp[4] = cpu_to_le32(hdr->checksum);
|
||||
}
|
||||
|
||||
static void __decode_table_header_from_buff(struct amdgpu_ras_eeprom_table_header *hdr,
|
||||
unsigned char *buff)
|
||||
{
|
||||
uint32_t *pp = (uint32_t *)buff;
|
||||
|
||||
hdr->header = le32_to_cpu(pp[0]);
|
||||
hdr->version = le32_to_cpu(pp[1]);
|
||||
hdr->first_rec_offset = le32_to_cpu(pp[2]);
|
||||
hdr->tbl_size = le32_to_cpu(pp[3]);
|
||||
hdr->checksum = le32_to_cpu(pp[4]);
|
||||
}
|
||||
|
||||
static int __update_table_header(struct amdgpu_ras_eeprom_control *control,
|
||||
unsigned char *buff)
|
||||
{
|
||||
int ret = 0;
|
||||
struct i2c_msg msg = {
|
||||
.addr = EEPROM_I2C_TARGET_ADDR,
|
||||
.flags = 0,
|
||||
.len = EEPROM_ADDRESS_SIZE + EEPROM_TABLE_HEADER_SIZE,
|
||||
.buf = buff,
|
||||
};
|
||||
|
||||
|
||||
*(uint16_t *)buff = EEPROM_HDR_START;
|
||||
__encode_table_header_to_buff(&control->tbl_hdr, buff + EEPROM_ADDRESS_SIZE);
|
||||
|
||||
ret = i2c_transfer(&control->eeprom_accessor, &msg, 1);
|
||||
if (ret < 1)
|
||||
DRM_ERROR("Failed to write EEPROM table header, ret:%d", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint32_t __calc_hdr_byte_sum(struct amdgpu_ras_eeprom_control *control);
|
||||
|
||||
int amdgpu_ras_eeprom_init(struct amdgpu_ras_eeprom_control *control)
|
||||
{
|
||||
int ret = 0;
|
||||
struct amdgpu_device *adev = to_amdgpu_device(control);
|
||||
unsigned char buff[EEPROM_ADDRESS_SIZE + EEPROM_TABLE_HEADER_SIZE] = { 0 };
|
||||
struct amdgpu_ras_eeprom_table_header *hdr = &control->tbl_hdr;
|
||||
struct i2c_msg msg = {
|
||||
.addr = EEPROM_I2C_TARGET_ADDR,
|
||||
.flags = I2C_M_RD,
|
||||
.len = EEPROM_ADDRESS_SIZE + EEPROM_TABLE_HEADER_SIZE,
|
||||
.buf = buff,
|
||||
};
|
||||
|
||||
mutex_init(&control->tbl_mutex);
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VEGA20:
|
||||
ret = smu_v11_0_i2c_eeprom_control_init(&control->eeprom_accessor);
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to init I2C controller, ret:%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Read/Create table header from EEPROM address 0 */
|
||||
ret = i2c_transfer(&control->eeprom_accessor, &msg, 1);
|
||||
if (ret < 1) {
|
||||
DRM_ERROR("Failed to read EEPROM table header, ret:%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
__decode_table_header_from_buff(hdr, &buff[2]);
|
||||
|
||||
if (hdr->header == EEPROM_TABLE_HDR_VAL) {
|
||||
control->num_recs = (hdr->tbl_size - EEPROM_TABLE_HEADER_SIZE) /
|
||||
EEPROM_TABLE_RECORD_SIZE;
|
||||
DRM_DEBUG_DRIVER("Found existing EEPROM table with %d records",
|
||||
control->num_recs);
|
||||
|
||||
} else {
|
||||
DRM_INFO("Creating new EEPROM table");
|
||||
|
||||
hdr->header = EEPROM_TABLE_HDR_VAL;
|
||||
hdr->version = EEPROM_TABLE_VER;
|
||||
hdr->first_rec_offset = EEPROM_RECORD_START;
|
||||
hdr->tbl_size = EEPROM_TABLE_HEADER_SIZE;
|
||||
|
||||
adev->psp.ras.ras->eeprom_control.tbl_byte_sum =
|
||||
__calc_hdr_byte_sum(&adev->psp.ras.ras->eeprom_control);
|
||||
ret = __update_table_header(control, buff);
|
||||
}
|
||||
|
||||
/* Start inserting records from here */
|
||||
adev->psp.ras.ras->eeprom_control.next_addr = EEPROM_RECORD_START;
|
||||
|
||||
return ret == 1 ? 0 : -EIO;
|
||||
}
|
||||
|
||||
void amdgpu_ras_eeprom_fini(struct amdgpu_ras_eeprom_control *control)
|
||||
{
|
||||
struct amdgpu_device *adev = to_amdgpu_device(control);
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VEGA20:
|
||||
smu_v11_0_i2c_eeprom_control_fini(&control->eeprom_accessor);
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void __encode_table_record_to_buff(struct amdgpu_ras_eeprom_control *control,
|
||||
struct eeprom_table_record *record,
|
||||
unsigned char *buff)
|
||||
{
|
||||
__le64 tmp = 0;
|
||||
int i = 0;
|
||||
|
||||
/* Next are all record fields according to EEPROM page spec in LE foramt */
|
||||
buff[i++] = record->err_type;
|
||||
|
||||
buff[i++] = record->bank;
|
||||
|
||||
tmp = cpu_to_le64(record->ts);
|
||||
memcpy(buff + i, &tmp, 8);
|
||||
i += 8;
|
||||
|
||||
tmp = cpu_to_le64((record->offset & 0xffffffffffff));
|
||||
memcpy(buff + i, &tmp, 6);
|
||||
i += 6;
|
||||
|
||||
buff[i++] = record->mem_channel;
|
||||
buff[i++] = record->mcumc_id;
|
||||
|
||||
tmp = cpu_to_le64((record->retired_page & 0xffffffffffff));
|
||||
memcpy(buff + i, &tmp, 6);
|
||||
}
|
||||
|
||||
static void __decode_table_record_from_buff(struct amdgpu_ras_eeprom_control *control,
|
||||
struct eeprom_table_record *record,
|
||||
unsigned char *buff)
|
||||
{
|
||||
__le64 tmp = 0;
|
||||
int i = 0;
|
||||
|
||||
/* Next are all record fields according to EEPROM page spec in LE foramt */
|
||||
record->err_type = buff[i++];
|
||||
|
||||
record->bank = buff[i++];
|
||||
|
||||
memcpy(&tmp, buff + i, 8);
|
||||
record->ts = le64_to_cpu(tmp);
|
||||
i += 8;
|
||||
|
||||
memcpy(&tmp, buff + i, 6);
|
||||
record->offset = (le64_to_cpu(tmp) & 0xffffffffffff);
|
||||
i += 6;
|
||||
|
||||
buff[i++] = record->mem_channel;
|
||||
buff[i++] = record->mcumc_id;
|
||||
|
||||
memcpy(&tmp, buff + i, 6);
|
||||
record->retired_page = (le64_to_cpu(tmp) & 0xffffffffffff);
|
||||
}
|
||||
|
||||
/*
|
||||
* When reaching end of EEPROM memory jump back to 0 record address
|
||||
* When next record access will go beyond EEPROM page boundary modify bits A17/A8
|
||||
* in I2C selector to go to next page
|
||||
*/
|
||||
static uint32_t __correct_eeprom_dest_address(uint32_t curr_address)
|
||||
{
|
||||
uint32_t next_address = curr_address + EEPROM_TABLE_RECORD_SIZE;
|
||||
|
||||
/* When all EEPROM memory used jump back to 0 address */
|
||||
if (next_address > EEPROM_SIZE_BYTES) {
|
||||
DRM_INFO("Reached end of EEPROM memory, jumping to 0 "
|
||||
"and overriding old record");
|
||||
return EEPROM_RECORD_START;
|
||||
}
|
||||
|
||||
/*
|
||||
* To check if we overflow page boundary compare next address with
|
||||
* current and see if bits 17/8 of the EEPROM address will change
|
||||
* If they do start from the next 256b page
|
||||
*
|
||||
* https://www.st.com/resource/en/datasheet/m24m02-dr.pdf sec. 5.1.2
|
||||
*/
|
||||
if ((curr_address & EEPROM_ADDR_MSB_MASK) != (next_address & EEPROM_ADDR_MSB_MASK)) {
|
||||
DRM_DEBUG_DRIVER("Reached end of EEPROM memory page, jumping to next: %lx",
|
||||
(next_address & EEPROM_ADDR_MSB_MASK));
|
||||
|
||||
return (next_address & EEPROM_ADDR_MSB_MASK);
|
||||
}
|
||||
|
||||
return curr_address;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t __calc_hdr_byte_sum(struct amdgpu_ras_eeprom_control *control)
|
||||
{
|
||||
int i;
|
||||
uint32_t tbl_sum = 0;
|
||||
|
||||
/* Header checksum, skip checksum field in the calculation */
|
||||
for (i = 0; i < sizeof(control->tbl_hdr) - sizeof(control->tbl_hdr.checksum); i++)
|
||||
tbl_sum += *(((unsigned char *)&control->tbl_hdr) + i);
|
||||
|
||||
return tbl_sum;
|
||||
}
|
||||
|
||||
static uint32_t __calc_recs_byte_sum(struct eeprom_table_record *records,
|
||||
int num)
|
||||
{
|
||||
int i, j;
|
||||
uint32_t tbl_sum = 0;
|
||||
|
||||
/* Records checksum */
|
||||
for (i = 0; i < num; i++) {
|
||||
struct eeprom_table_record *record = &records[i];
|
||||
|
||||
for (j = 0; j < sizeof(*record); j++) {
|
||||
tbl_sum += *(((unsigned char *)record) + j);
|
||||
}
|
||||
}
|
||||
|
||||
return tbl_sum;
|
||||
}
|
||||
|
||||
static inline uint32_t __calc_tbl_byte_sum(struct amdgpu_ras_eeprom_control *control,
|
||||
struct eeprom_table_record *records, int num)
|
||||
{
|
||||
return __calc_hdr_byte_sum(control) + __calc_recs_byte_sum(records, num);
|
||||
}
|
||||
|
||||
/* Checksum = 256 -((sum of all table entries) mod 256) */
|
||||
static void __update_tbl_checksum(struct amdgpu_ras_eeprom_control *control,
|
||||
struct eeprom_table_record *records, int num,
|
||||
uint32_t old_hdr_byte_sum)
|
||||
{
|
||||
/*
|
||||
* This will update the table sum with new records.
|
||||
*
|
||||
* TODO: What happens when the EEPROM table is to be wrapped around
|
||||
* and old records from start will get overridden.
|
||||
*/
|
||||
|
||||
/* need to recalculate updated header byte sum */
|
||||
control->tbl_byte_sum -= old_hdr_byte_sum;
|
||||
control->tbl_byte_sum += __calc_tbl_byte_sum(control, records, num);
|
||||
|
||||
control->tbl_hdr.checksum = 256 - (control->tbl_byte_sum % 256);
|
||||
}
|
||||
|
||||
/* table sum mod 256 + checksum must equals 256 */
|
||||
static bool __validate_tbl_checksum(struct amdgpu_ras_eeprom_control *control,
|
||||
struct eeprom_table_record *records, int num)
|
||||
{
|
||||
control->tbl_byte_sum = __calc_tbl_byte_sum(control, records, num);
|
||||
|
||||
if (control->tbl_hdr.checksum + (control->tbl_byte_sum % 256) != 256) {
|
||||
DRM_WARN("Checksum mismatch, checksum: %u ", control->tbl_hdr.checksum);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int amdgpu_ras_eeprom_process_recods(struct amdgpu_ras_eeprom_control *control,
|
||||
struct eeprom_table_record *records,
|
||||
bool write,
|
||||
int num)
|
||||
{
|
||||
int i, ret = 0;
|
||||
struct i2c_msg *msgs;
|
||||
unsigned char *buffs;
|
||||
struct amdgpu_device *adev = to_amdgpu_device(control);
|
||||
|
||||
if (adev->asic_type != CHIP_VEGA20)
|
||||
return 0;
|
||||
|
||||
buffs = kcalloc(num, EEPROM_ADDRESS_SIZE + EEPROM_TABLE_RECORD_SIZE,
|
||||
GFP_KERNEL);
|
||||
if (!buffs)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_lock(&control->tbl_mutex);
|
||||
|
||||
msgs = kcalloc(num, sizeof(*msgs), GFP_KERNEL);
|
||||
if (!msgs) {
|
||||
ret = -ENOMEM;
|
||||
goto free_buff;
|
||||
}
|
||||
|
||||
/* In case of overflow just start from beginning to not lose newest records */
|
||||
if (write && (control->next_addr + EEPROM_TABLE_RECORD_SIZE * num > EEPROM_SIZE_BYTES))
|
||||
control->next_addr = EEPROM_RECORD_START;
|
||||
|
||||
|
||||
/*
|
||||
* TODO Currently makes EEPROM writes for each record, this creates
|
||||
* internal fragmentation. Optimized the code to do full page write of
|
||||
* 256b
|
||||
*/
|
||||
for (i = 0; i < num; i++) {
|
||||
unsigned char *buff = &buffs[i * (EEPROM_ADDRESS_SIZE + EEPROM_TABLE_RECORD_SIZE)];
|
||||
struct eeprom_table_record *record = &records[i];
|
||||
struct i2c_msg *msg = &msgs[i];
|
||||
|
||||
control->next_addr = __correct_eeprom_dest_address(control->next_addr);
|
||||
|
||||
/*
|
||||
* Update bits 16,17 of EEPROM address in I2C address by setting them
|
||||
* to bits 1,2 of Device address byte
|
||||
*/
|
||||
msg->addr = EEPROM_I2C_TARGET_ADDR |
|
||||
((control->next_addr & EEPROM_ADDR_MSB_MASK) >> 15);
|
||||
msg->flags = write ? 0 : I2C_M_RD;
|
||||
msg->len = EEPROM_ADDRESS_SIZE + EEPROM_TABLE_RECORD_SIZE;
|
||||
msg->buf = buff;
|
||||
|
||||
/* Insert the EEPROM dest addess, bits 0-15 */
|
||||
buff[0] = ((control->next_addr >> 8) & 0xff);
|
||||
buff[1] = (control->next_addr & 0xff);
|
||||
|
||||
/* EEPROM table content is stored in LE format */
|
||||
if (write)
|
||||
__encode_table_record_to_buff(control, record, buff + EEPROM_ADDRESS_SIZE);
|
||||
|
||||
/*
|
||||
* The destination EEPROM address might need to be corrected to account
|
||||
* for page or entire memory wrapping
|
||||
*/
|
||||
control->next_addr += EEPROM_TABLE_RECORD_SIZE;
|
||||
}
|
||||
|
||||
ret = i2c_transfer(&control->eeprom_accessor, msgs, num);
|
||||
if (ret < 1) {
|
||||
DRM_ERROR("Failed to process EEPROM table records, ret:%d", ret);
|
||||
|
||||
/* TODO Restore prev next EEPROM address ? */
|
||||
goto free_msgs;
|
||||
}
|
||||
|
||||
|
||||
if (!write) {
|
||||
for (i = 0; i < num; i++) {
|
||||
unsigned char *buff = &buffs[i*(EEPROM_ADDRESS_SIZE + EEPROM_TABLE_RECORD_SIZE)];
|
||||
struct eeprom_table_record *record = &records[i];
|
||||
|
||||
__decode_table_record_from_buff(control, record, buff + EEPROM_ADDRESS_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
if (write) {
|
||||
uint32_t old_hdr_byte_sum = __calc_hdr_byte_sum(control);
|
||||
|
||||
/*
|
||||
* Update table header with size and CRC and account for table
|
||||
* wrap around where the assumption is that we treat it as empty
|
||||
* table
|
||||
*
|
||||
* TODO - Check the assumption is correct
|
||||
*/
|
||||
control->num_recs += num;
|
||||
control->num_recs %= EEPROM_MAX_RECORD_NUM;
|
||||
control->tbl_hdr.tbl_size += EEPROM_TABLE_RECORD_SIZE * num;
|
||||
if (control->tbl_hdr.tbl_size > EEPROM_SIZE_BYTES)
|
||||
control->tbl_hdr.tbl_size = EEPROM_TABLE_HEADER_SIZE +
|
||||
control->num_recs * EEPROM_TABLE_RECORD_SIZE;
|
||||
|
||||
__update_tbl_checksum(control, records, num, old_hdr_byte_sum);
|
||||
|
||||
__update_table_header(control, buffs);
|
||||
} else if (!__validate_tbl_checksum(control, records, num)) {
|
||||
DRM_WARN("EEPROM Table checksum mismatch!");
|
||||
/* TODO Uncomment when EEPROM read/write is relliable */
|
||||
/* ret = -EIO; */
|
||||
}
|
||||
|
||||
free_msgs:
|
||||
kfree(msgs);
|
||||
|
||||
free_buff:
|
||||
kfree(buffs);
|
||||
|
||||
mutex_unlock(&control->tbl_mutex);
|
||||
|
||||
return ret == num ? 0 : -EIO;
|
||||
}
|
||||
|
||||
/* Used for testing if bugs encountered */
|
||||
#if 0
|
||||
void amdgpu_ras_eeprom_test(struct amdgpu_ras_eeprom_control *control)
|
||||
{
|
||||
int i;
|
||||
struct eeprom_table_record *recs = kcalloc(1, sizeof(*recs), GFP_KERNEL);
|
||||
|
||||
if (!recs)
|
||||
return;
|
||||
|
||||
for (i = 0; i < 1 ; i++) {
|
||||
recs[i].address = 0xdeadbeef;
|
||||
recs[i].retired_page = i;
|
||||
}
|
||||
|
||||
if (!amdgpu_ras_eeprom_process_recods(control, recs, true, 1)) {
|
||||
|
||||
memset(recs, 0, sizeof(*recs) * 1);
|
||||
|
||||
control->next_addr = EEPROM_RECORD_START;
|
||||
|
||||
if (!amdgpu_ras_eeprom_process_recods(control, recs, false, 1)) {
|
||||
for (i = 0; i < 1; i++)
|
||||
DRM_INFO("rec.address :0x%llx, rec.retired_page :%llu",
|
||||
recs[i].address, recs[i].retired_page);
|
||||
} else
|
||||
DRM_ERROR("Failed in reading from table");
|
||||
|
||||
} else
|
||||
DRM_ERROR("Failed in writing to table");
|
||||
}
|
||||
#endif
|
90
drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.h
Normal file
90
drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.h
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _AMDGPU_RAS_EEPROM_H
|
||||
#define _AMDGPU_RAS_EEPROM_H
|
||||
|
||||
#include <linux/i2c.h>
|
||||
|
||||
struct amdgpu_device;
|
||||
|
||||
enum amdgpu_ras_eeprom_err_type{
|
||||
AMDGPU_RAS_EEPROM_ERR_PLACE_HOLDER,
|
||||
AMDGPU_RAS_EEPROM_ERR_RECOVERABLE,
|
||||
AMDGPU_RAS_EEPROM_ERR_NON_RECOVERABLE
|
||||
};
|
||||
|
||||
struct amdgpu_ras_eeprom_table_header {
|
||||
uint32_t header;
|
||||
uint32_t version;
|
||||
uint32_t first_rec_offset;
|
||||
uint32_t tbl_size;
|
||||
uint32_t checksum;
|
||||
}__attribute__((__packed__));
|
||||
|
||||
struct amdgpu_ras_eeprom_control {
|
||||
struct amdgpu_ras_eeprom_table_header tbl_hdr;
|
||||
struct i2c_adapter eeprom_accessor;
|
||||
uint32_t next_addr;
|
||||
unsigned int num_recs;
|
||||
struct mutex tbl_mutex;
|
||||
bool bus_locked;
|
||||
uint32_t tbl_byte_sum;
|
||||
};
|
||||
|
||||
/*
|
||||
* Represents single table record. Packed to be easily serialized into byte
|
||||
* stream.
|
||||
*/
|
||||
struct eeprom_table_record {
|
||||
|
||||
union {
|
||||
uint64_t address;
|
||||
uint64_t offset;
|
||||
};
|
||||
|
||||
uint64_t retired_page;
|
||||
uint64_t ts;
|
||||
|
||||
enum amdgpu_ras_eeprom_err_type err_type;
|
||||
|
||||
union {
|
||||
unsigned char bank;
|
||||
unsigned char cu;
|
||||
};
|
||||
|
||||
unsigned char mem_channel;
|
||||
unsigned char mcumc_id;
|
||||
}__attribute__((__packed__));
|
||||
|
||||
int amdgpu_ras_eeprom_init(struct amdgpu_ras_eeprom_control *control);
|
||||
void amdgpu_ras_eeprom_fini(struct amdgpu_ras_eeprom_control *control);
|
||||
|
||||
int amdgpu_ras_eeprom_process_recods(struct amdgpu_ras_eeprom_control *control,
|
||||
struct eeprom_table_record *records,
|
||||
bool write,
|
||||
int num);
|
||||
|
||||
void amdgpu_ras_eeprom_test(struct amdgpu_ras_eeprom_control *control);
|
||||
|
||||
#endif // _AMDGPU_RAS_EEPROM_H
|
@ -1738,6 +1738,7 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
|
||||
uint64_t gtt_size;
|
||||
int r;
|
||||
u64 vis_vram_limit;
|
||||
void *stolen_vga_buf;
|
||||
|
||||
mutex_init(&adev->mman.gtt_window_lock);
|
||||
|
||||
@ -1792,7 +1793,7 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
|
||||
r = amdgpu_bo_create_kernel(adev, adev->gmc.stolen_size, PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
&adev->stolen_vga_memory,
|
||||
NULL, NULL);
|
||||
NULL, &stolen_vga_buf);
|
||||
if (r)
|
||||
return r;
|
||||
DRM_INFO("amdgpu: %uM of VRAM memory ready\n",
|
||||
@ -1856,8 +1857,9 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
|
||||
*/
|
||||
void amdgpu_ttm_late_init(struct amdgpu_device *adev)
|
||||
{
|
||||
void *stolen_vga_buf;
|
||||
/* return the VGA stolen memory (if any) back to VRAM */
|
||||
amdgpu_bo_free_kernel(&adev->stolen_vga_memory, NULL, NULL);
|
||||
amdgpu_bo_free_kernel(&adev->stolen_vga_memory, NULL, &stolen_vga_buf);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -454,17 +454,8 @@ static int dce_virtual_hw_init(void *handle)
|
||||
#endif
|
||||
/* no DCE */
|
||||
break;
|
||||
case CHIP_VEGA10:
|
||||
case CHIP_VEGA12:
|
||||
case CHIP_VEGA20:
|
||||
case CHIP_ARCTURUS:
|
||||
case CHIP_RENOIR:
|
||||
case CHIP_NAVI10:
|
||||
case CHIP_NAVI14:
|
||||
case CHIP_NAVI12:
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Virtual display unsupported ASIC type: 0x%X\n", adev->asic_type);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -3781,20 +3781,12 @@ static int gfx_v10_0_hw_fini(void *handle)
|
||||
|
||||
static int gfx_v10_0_suspend(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
adev->in_suspend = true;
|
||||
return gfx_v10_0_hw_fini(adev);
|
||||
return gfx_v10_0_hw_fini(handle);
|
||||
}
|
||||
|
||||
static int gfx_v10_0_resume(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int r;
|
||||
|
||||
r = gfx_v10_0_hw_init(adev);
|
||||
adev->in_suspend = false;
|
||||
return r;
|
||||
return gfx_v10_0_hw_init(handle);
|
||||
}
|
||||
|
||||
static bool gfx_v10_0_is_idle(void *handle)
|
||||
|
@ -1031,14 +1031,14 @@ static void gfx_v9_0_check_if_need_gfxoff(struct amdgpu_device *adev)
|
||||
case CHIP_VEGA20:
|
||||
break;
|
||||
case CHIP_RAVEN:
|
||||
if (adev->rev_id >= 0x8 || adev->pdev->device == 0x15d8)
|
||||
break;
|
||||
if ((adev->gfx.rlc_fw_version != 106 &&
|
||||
adev->gfx.rlc_fw_version < 531) ||
|
||||
(adev->gfx.rlc_fw_version == 53815) ||
|
||||
(adev->gfx.rlc_feature_version < 1) ||
|
||||
!adev->gfx.rlc.is_rlc_v2_1)
|
||||
if (!(adev->rev_id >= 0x8 || adev->pdev->device == 0x15d8)
|
||||
&&((adev->gfx.rlc_fw_version != 106 &&
|
||||
adev->gfx.rlc_fw_version < 531) ||
|
||||
(adev->gfx.rlc_fw_version == 53815) ||
|
||||
(adev->gfx.rlc_feature_version < 1) ||
|
||||
!adev->gfx.rlc.is_rlc_v2_1))
|
||||
adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
|
||||
|
||||
if (adev->pm.pp_feature & PP_GFXOFF_MASK)
|
||||
adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG |
|
||||
AMD_PG_SUPPORT_CP |
|
||||
|
@ -136,6 +136,14 @@ static int gmc_v10_0_process_interrupt(struct amdgpu_device *adev,
|
||||
addr |= ((u64)entry->src_data[1] & 0xf) << 44;
|
||||
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
/*
|
||||
* Issue a dummy read to wait for the status register to
|
||||
* be updated to avoid reading an incorrect value due to
|
||||
* the new fast GRBM interface.
|
||||
*/
|
||||
if (entry->vmid_src == AMDGPU_GFXHUB_0)
|
||||
RREG32(hub->vm_l2_pro_fault_status);
|
||||
|
||||
status = RREG32(hub->vm_l2_pro_fault_status);
|
||||
WREG32_P(hub->vm_l2_pro_fault_cntl, 1, ~1);
|
||||
}
|
||||
@ -229,6 +237,13 @@ static void gmc_v10_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid,
|
||||
|
||||
WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, tmp);
|
||||
|
||||
/*
|
||||
* Issue a dummy read to wait for the ACK register to be cleared
|
||||
* to avoid a false ACK due to the new fast GRBM interface.
|
||||
*/
|
||||
if (vmhub == AMDGPU_GFXHUB_0)
|
||||
RREG32_NO_KIQ(hub->vm_inv_eng0_req + eng);
|
||||
|
||||
/* Wait for ACK with a delay.*/
|
||||
for (i = 0; i < adev->usec_timeout; i++) {
|
||||
tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_ack + eng);
|
||||
|
@ -356,6 +356,14 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev,
|
||||
|
||||
/* If it's the first fault for this address, process it normally */
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
/*
|
||||
* Issue a dummy read to wait for the status register to
|
||||
* be updated to avoid reading an incorrect value due to
|
||||
* the new fast GRBM interface.
|
||||
*/
|
||||
if (entry->vmid_src == AMDGPU_GFXHUB_0)
|
||||
RREG32(hub->vm_l2_pro_fault_status);
|
||||
|
||||
status = RREG32(hub->vm_l2_pro_fault_status);
|
||||
WREG32_P(hub->vm_l2_pro_fault_cntl, 1, ~1);
|
||||
}
|
||||
@ -484,6 +492,14 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
||||
|
||||
spin_lock(&adev->gmc.invalidate_lock);
|
||||
WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, tmp);
|
||||
|
||||
/*
|
||||
* Issue a dummy read to wait for the ACK register to be cleared
|
||||
* to avoid a false ACK due to the new fast GRBM interface.
|
||||
*/
|
||||
if (vmhub == AMDGPU_GFXHUB_0)
|
||||
RREG32_NO_KIQ(hub->vm_inv_eng0_req + eng);
|
||||
|
||||
for (j = 0; j < adev->usec_timeout; j++) {
|
||||
tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_ack + eng);
|
||||
if (tmp & (1 << vmid))
|
||||
@ -1222,6 +1238,7 @@ static int gmc_v9_0_sw_init(void *handle)
|
||||
static int gmc_v9_0_sw_fini(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
void *stolen_vga_buf;
|
||||
|
||||
if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__UMC) &&
|
||||
adev->gmc.umc_ras_if) {
|
||||
@ -1254,7 +1271,7 @@ static int gmc_v9_0_sw_fini(void *handle)
|
||||
amdgpu_vm_manager_fini(adev);
|
||||
|
||||
if (gmc_v9_0_keep_stolen_memory(adev))
|
||||
amdgpu_bo_free_kernel(&adev->stolen_vga_memory, NULL, NULL);
|
||||
amdgpu_bo_free_kernel(&adev->stolen_vga_memory, NULL, &stolen_vga_buf);
|
||||
|
||||
amdgpu_gart_table_vram_free(adev);
|
||||
amdgpu_bo_fini(adev);
|
||||
|
@ -316,10 +316,13 @@ static int nv_asic_reset(struct amdgpu_device *adev)
|
||||
int ret = 0;
|
||||
struct smu_context *smu = &adev->smu;
|
||||
|
||||
if (nv_asic_reset_method(adev) == AMD_RESET_METHOD_BACO)
|
||||
if (nv_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) {
|
||||
amdgpu_inc_vram_lost(adev);
|
||||
ret = smu_baco_reset(smu);
|
||||
else
|
||||
} else {
|
||||
amdgpu_inc_vram_lost(adev);
|
||||
ret = nv_asic_mode1_reset(adev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -457,8 +460,10 @@ int nv_set_ip_blocks(struct amdgpu_device *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, &dce_virtual_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 &&
|
||||
@ -650,7 +655,9 @@ static int nv_common_early_init(void *handle)
|
||||
AMD_CG_SUPPORT_ATHUB_MGCG |
|
||||
AMD_CG_SUPPORT_ATHUB_LS |
|
||||
AMD_CG_SUPPORT_VCN_MGCG;
|
||||
adev->pg_flags = AMD_PG_SUPPORT_VCN_DPG;
|
||||
adev->pg_flags = AMD_PG_SUPPORT_VCN |
|
||||
AMD_PG_SUPPORT_VCN_DPG |
|
||||
AMD_PG_SUPPORT_ATHUB;
|
||||
adev->external_rev_id = adev->rev_id + 0xa;
|
||||
break;
|
||||
default:
|
||||
|
@ -1206,6 +1206,7 @@ static void sdma_v4_0_init_pg(struct amdgpu_device *adev)
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_RAVEN:
|
||||
case CHIP_RENOIR:
|
||||
sdma_v4_1_init_power_gating(adev);
|
||||
sdma_v4_1_update_power_gating(adev, true);
|
||||
break;
|
||||
@ -2503,8 +2504,8 @@ static const struct amdgpu_buffer_funcs sdma_v4_0_buffer_funcs = {
|
||||
static void sdma_v4_0_set_buffer_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
adev->mman.buffer_funcs = &sdma_v4_0_buffer_funcs;
|
||||
if (adev->sdma.has_page_queue && adev->sdma.num_instances > 1)
|
||||
adev->mman.buffer_funcs_ring = &adev->sdma.instance[1].page;
|
||||
if (adev->sdma.has_page_queue)
|
||||
adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].page;
|
||||
else
|
||||
adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring;
|
||||
}
|
||||
@ -2523,22 +2524,15 @@ static void sdma_v4_0_set_vm_pte_funcs(struct amdgpu_device *adev)
|
||||
unsigned i;
|
||||
|
||||
adev->vm_manager.vm_pte_funcs = &sdma_v4_0_vm_pte_funcs;
|
||||
if (adev->sdma.has_page_queue && adev->sdma.num_instances > 1) {
|
||||
for (i = 1; i < adev->sdma.num_instances; i++) {
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
if (adev->sdma.has_page_queue)
|
||||
sched = &adev->sdma.instance[i].page.sched;
|
||||
adev->vm_manager.vm_pte_rqs[i - 1] =
|
||||
&sched->sched_rq[DRM_SCHED_PRIORITY_KERNEL];
|
||||
}
|
||||
adev->vm_manager.vm_pte_num_rqs = adev->sdma.num_instances - 1;
|
||||
adev->vm_manager.page_fault = &adev->sdma.instance[0].page;
|
||||
} else {
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
else
|
||||
sched = &adev->sdma.instance[i].ring.sched;
|
||||
adev->vm_manager.vm_pte_rqs[i] =
|
||||
&sched->sched_rq[DRM_SCHED_PRIORITY_KERNEL];
|
||||
}
|
||||
adev->vm_manager.vm_pte_num_rqs = adev->sdma.num_instances;
|
||||
adev->vm_manager.vm_pte_rqs[i] =
|
||||
&sched->sched_rq[DRM_SCHED_PRIORITY_KERNEL];
|
||||
}
|
||||
adev->vm_manager.vm_pte_num_rqs = adev->sdma.num_instances;
|
||||
}
|
||||
|
||||
const struct amdgpu_ip_block_version sdma_v4_0_ip_block = {
|
||||
|
@ -1888,7 +1888,7 @@ static void si_program_aspm(struct amdgpu_device *adev)
|
||||
if (orig != data)
|
||||
si_pif_phy1_wreg(adev,PB1_PIF_PWRDOWN_1, data);
|
||||
|
||||
if ((adev->family != CHIP_OLAND) && (adev->family != CHIP_HAINAN)) {
|
||||
if ((adev->asic_type != CHIP_OLAND) && (adev->asic_type != CHIP_HAINAN)) {
|
||||
orig = data = si_pif_phy0_rreg(adev,PB0_PIF_PWRDOWN_0);
|
||||
data &= ~PLL_RAMP_UP_TIME_0_MASK;
|
||||
if (orig != data)
|
||||
@ -1937,14 +1937,14 @@ static void si_program_aspm(struct amdgpu_device *adev)
|
||||
|
||||
orig = data = si_pif_phy0_rreg(adev,PB0_PIF_CNTL);
|
||||
data &= ~LS2_EXIT_TIME_MASK;
|
||||
if ((adev->family == CHIP_OLAND) || (adev->family == CHIP_HAINAN))
|
||||
if ((adev->asic_type == CHIP_OLAND) || (adev->asic_type == CHIP_HAINAN))
|
||||
data |= LS2_EXIT_TIME(5);
|
||||
if (orig != data)
|
||||
si_pif_phy0_wreg(adev,PB0_PIF_CNTL, data);
|
||||
|
||||
orig = data = si_pif_phy1_rreg(adev,PB1_PIF_CNTL);
|
||||
data &= ~LS2_EXIT_TIME_MASK;
|
||||
if ((adev->family == CHIP_OLAND) || (adev->family == CHIP_HAINAN))
|
||||
if ((adev->asic_type == CHIP_OLAND) || (adev->asic_type == CHIP_HAINAN))
|
||||
data |= LS2_EXIT_TIME(5);
|
||||
if (orig != data)
|
||||
si_pif_phy1_wreg(adev,PB1_PIF_CNTL, data);
|
||||
|
724
drivers/gpu/drm/amd/amdgpu/smu_v11_0_i2c.c
Normal file
724
drivers/gpu/drm/amd/amdgpu/smu_v11_0_i2c.c
Normal file
@ -0,0 +1,724 @@
|
||||
/*
|
||||
* 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 "smuio/smuio_11_0_0_offset.h"
|
||||
#include "smuio/smuio_11_0_0_sh_mask.h"
|
||||
|
||||
#include "smu_v11_0_i2c.h"
|
||||
#include "amdgpu.h"
|
||||
#include "soc15_common.h"
|
||||
#include <drm/drm_fixed.h>
|
||||
#include <drm/drm_drv.h>
|
||||
#include "amdgpu_amdkfd.h"
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/pci.h>
|
||||
#include "amdgpu_ras.h"
|
||||
|
||||
/* error codes */
|
||||
#define I2C_OK 0
|
||||
#define I2C_NAK_7B_ADDR_NOACK 1
|
||||
#define I2C_NAK_TXDATA_NOACK 2
|
||||
#define I2C_TIMEOUT 4
|
||||
#define I2C_SW_TIMEOUT 8
|
||||
#define I2C_ABORT 0x10
|
||||
|
||||
/* I2C transaction flags */
|
||||
#define I2C_NO_STOP 1
|
||||
#define I2C_RESTART 2
|
||||
|
||||
#define to_amdgpu_device(x) (container_of(x, struct amdgpu_ras, eeprom_control.eeprom_accessor))->adev
|
||||
#define to_eeprom_control(x) container_of(x, struct amdgpu_ras_eeprom_control, eeprom_accessor)
|
||||
|
||||
static void smu_v11_0_i2c_set_clock_gating(struct i2c_adapter *control, bool en)
|
||||
{
|
||||
struct amdgpu_device *adev = to_amdgpu_device(control);
|
||||
uint32_t reg = RREG32_SOC15(SMUIO, 0, mmSMUIO_PWRMGT);
|
||||
|
||||
reg = REG_SET_FIELD(reg, SMUIO_PWRMGT, i2c_clk_gate_en, en ? 1 : 0);
|
||||
WREG32_SOC15(SMUIO, 0, mmSMUIO_PWRMGT, reg);
|
||||
}
|
||||
|
||||
|
||||
static void smu_v11_0_i2c_enable(struct i2c_adapter *control, bool enable)
|
||||
{
|
||||
struct amdgpu_device *adev = to_amdgpu_device(control);
|
||||
|
||||
WREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_ENABLE, enable ? 1 : 0);
|
||||
}
|
||||
|
||||
static void smu_v11_0_i2c_clear_status(struct i2c_adapter *control)
|
||||
{
|
||||
struct amdgpu_device *adev = to_amdgpu_device(control);
|
||||
/* do */
|
||||
{
|
||||
RREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_CLR_INTR);
|
||||
|
||||
} /* while (reg_CKSVII2C_ic_clr_intr == 0) */
|
||||
}
|
||||
|
||||
static void smu_v11_0_i2c_configure(struct i2c_adapter *control)
|
||||
{
|
||||
struct amdgpu_device *adev = to_amdgpu_device(control);
|
||||
uint32_t reg = 0;
|
||||
|
||||
reg = REG_SET_FIELD(reg, CKSVII2C_IC_CON, IC_SLAVE_DISABLE, 1);
|
||||
reg = REG_SET_FIELD(reg, CKSVII2C_IC_CON, IC_RESTART_EN, 1);
|
||||
reg = REG_SET_FIELD(reg, CKSVII2C_IC_CON, IC_10BITADDR_MASTER, 0);
|
||||
reg = REG_SET_FIELD(reg, CKSVII2C_IC_CON, IC_10BITADDR_SLAVE, 0);
|
||||
/* Standard mode */
|
||||
reg = REG_SET_FIELD(reg, CKSVII2C_IC_CON, IC_MAX_SPEED_MODE, 2);
|
||||
reg = REG_SET_FIELD(reg, CKSVII2C_IC_CON, IC_MASTER_MODE, 1);
|
||||
|
||||
WREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_CON, reg);
|
||||
}
|
||||
|
||||
static void smu_v11_0_i2c_set_clock(struct i2c_adapter *control)
|
||||
{
|
||||
struct amdgpu_device *adev = to_amdgpu_device(control);
|
||||
|
||||
/*
|
||||
* Standard mode speed, These values are taken from SMUIO MAS,
|
||||
* but are different from what is given is
|
||||
* Synopsys spec. The values here are based on assumption
|
||||
* that refclock is 100MHz
|
||||
*
|
||||
* Configuration for standard mode; Speed = 100kbps
|
||||
* Scale linearly, for now only support standard speed clock
|
||||
* This will work only with 100M ref clock
|
||||
*
|
||||
* TBD:Change the calculation to take into account ref clock values also.
|
||||
*/
|
||||
|
||||
WREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_FS_SPKLEN, 2);
|
||||
WREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_SS_SCL_HCNT, 120);
|
||||
WREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_SS_SCL_LCNT, 130);
|
||||
WREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_SDA_HOLD, 20);
|
||||
}
|
||||
|
||||
static void smu_v11_0_i2c_set_address(struct i2c_adapter *control, uint8_t address)
|
||||
{
|
||||
struct amdgpu_device *adev = to_amdgpu_device(control);
|
||||
|
||||
/* Convert fromr 8-bit to 7-bit address */
|
||||
address >>= 1;
|
||||
WREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_TAR, (address & 0xFF));
|
||||
}
|
||||
|
||||
static uint32_t smu_v11_0_i2c_poll_tx_status(struct i2c_adapter *control)
|
||||
{
|
||||
struct amdgpu_device *adev = to_amdgpu_device(control);
|
||||
uint32_t ret = I2C_OK;
|
||||
uint32_t reg, reg_c_tx_abrt_source;
|
||||
|
||||
/*Check if transmission is completed */
|
||||
unsigned long timeout_counter = jiffies + msecs_to_jiffies(20);
|
||||
|
||||
do {
|
||||
if (time_after(jiffies, timeout_counter)) {
|
||||
ret |= I2C_SW_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
|
||||
reg = RREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_STATUS);
|
||||
|
||||
} while (REG_GET_FIELD(reg, CKSVII2C_IC_STATUS, TFE) == 0);
|
||||
|
||||
if (ret != I2C_OK)
|
||||
return ret;
|
||||
|
||||
/* This only checks if NAK is received and transaction got aborted */
|
||||
reg = RREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_INTR_STAT);
|
||||
|
||||
if (REG_GET_FIELD(reg, CKSVII2C_IC_INTR_STAT, R_TX_ABRT) == 1) {
|
||||
reg_c_tx_abrt_source = RREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_TX_ABRT_SOURCE);
|
||||
DRM_INFO("TX was terminated, IC_TX_ABRT_SOURCE val is:%x", reg_c_tx_abrt_source);
|
||||
|
||||
/* Check for stop due to NACK */
|
||||
if (REG_GET_FIELD(reg_c_tx_abrt_source,
|
||||
CKSVII2C_IC_TX_ABRT_SOURCE,
|
||||
ABRT_TXDATA_NOACK) == 1) {
|
||||
|
||||
ret |= I2C_NAK_TXDATA_NOACK;
|
||||
|
||||
} else if (REG_GET_FIELD(reg_c_tx_abrt_source,
|
||||
CKSVII2C_IC_TX_ABRT_SOURCE,
|
||||
ABRT_7B_ADDR_NOACK) == 1) {
|
||||
|
||||
ret |= I2C_NAK_7B_ADDR_NOACK;
|
||||
} else {
|
||||
ret |= I2C_ABORT;
|
||||
}
|
||||
|
||||
smu_v11_0_i2c_clear_status(control);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint32_t smu_v11_0_i2c_poll_rx_status(struct i2c_adapter *control)
|
||||
{
|
||||
struct amdgpu_device *adev = to_amdgpu_device(control);
|
||||
uint32_t ret = I2C_OK;
|
||||
uint32_t reg_ic_status, reg_c_tx_abrt_source;
|
||||
|
||||
reg_c_tx_abrt_source = RREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_TX_ABRT_SOURCE);
|
||||
|
||||
/* If slave is not present */
|
||||
if (REG_GET_FIELD(reg_c_tx_abrt_source,
|
||||
CKSVII2C_IC_TX_ABRT_SOURCE,
|
||||
ABRT_7B_ADDR_NOACK) == 1) {
|
||||
ret |= I2C_NAK_7B_ADDR_NOACK;
|
||||
|
||||
smu_v11_0_i2c_clear_status(control);
|
||||
} else { /* wait till some data is there in RXFIFO */
|
||||
/* Poll for some byte in RXFIFO */
|
||||
unsigned long timeout_counter = jiffies + msecs_to_jiffies(20);
|
||||
|
||||
do {
|
||||
if (time_after(jiffies, timeout_counter)) {
|
||||
ret |= I2C_SW_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
|
||||
reg_ic_status = RREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_STATUS);
|
||||
|
||||
} while (REG_GET_FIELD(reg_ic_status, CKSVII2C_IC_STATUS, RFNE) == 0);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* smu_v11_0_i2c_transmit - Send a block of data over the I2C bus to a slave device.
|
||||
*
|
||||
* @address: The I2C address of the slave device.
|
||||
* @data: The data to transmit over the bus.
|
||||
* @numbytes: The amount of data to transmit.
|
||||
* @i2c_flag: Flags for transmission
|
||||
*
|
||||
* Returns 0 on success or error.
|
||||
*/
|
||||
static uint32_t smu_v11_0_i2c_transmit(struct i2c_adapter *control,
|
||||
uint8_t address, uint8_t *data,
|
||||
uint32_t numbytes, uint32_t i2c_flag)
|
||||
{
|
||||
struct amdgpu_device *adev = to_amdgpu_device(control);
|
||||
uint32_t bytes_sent, reg, ret = 0;
|
||||
unsigned long timeout_counter;
|
||||
|
||||
bytes_sent = 0;
|
||||
|
||||
DRM_DEBUG_DRIVER("I2C_Transmit(), address = %x, bytes = %d , data: ",
|
||||
(uint16_t)address, numbytes);
|
||||
|
||||
if (drm_debug & DRM_UT_DRIVER) {
|
||||
print_hex_dump(KERN_INFO, "data: ", DUMP_PREFIX_NONE,
|
||||
16, 1, data, numbytes, false);
|
||||
}
|
||||
|
||||
/* Set the I2C slave address */
|
||||
smu_v11_0_i2c_set_address(control, address);
|
||||
/* Enable I2C */
|
||||
smu_v11_0_i2c_enable(control, true);
|
||||
|
||||
/* Clear status bits */
|
||||
smu_v11_0_i2c_clear_status(control);
|
||||
|
||||
|
||||
timeout_counter = jiffies + msecs_to_jiffies(20);
|
||||
|
||||
while (numbytes > 0) {
|
||||
reg = RREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_STATUS);
|
||||
if (REG_GET_FIELD(reg, CKSVII2C_IC_STATUS, TFNF)) {
|
||||
do {
|
||||
reg = 0;
|
||||
/*
|
||||
* Prepare transaction, no need to set RESTART. I2C engine will send
|
||||
* START as soon as it sees data in TXFIFO
|
||||
*/
|
||||
if (bytes_sent == 0)
|
||||
reg = REG_SET_FIELD(reg, CKSVII2C_IC_DATA_CMD, RESTART,
|
||||
(i2c_flag & I2C_RESTART) ? 1 : 0);
|
||||
reg = REG_SET_FIELD(reg, CKSVII2C_IC_DATA_CMD, DAT, data[bytes_sent]);
|
||||
|
||||
/* determine if we need to send STOP bit or not */
|
||||
if (numbytes == 1)
|
||||
/* Final transaction, so send stop unless I2C_NO_STOP */
|
||||
reg = REG_SET_FIELD(reg, CKSVII2C_IC_DATA_CMD, STOP,
|
||||
(i2c_flag & I2C_NO_STOP) ? 0 : 1);
|
||||
/* Write */
|
||||
reg = REG_SET_FIELD(reg, CKSVII2C_IC_DATA_CMD, CMD, 0);
|
||||
WREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_DATA_CMD, reg);
|
||||
|
||||
/* Record that the bytes were transmitted */
|
||||
bytes_sent++;
|
||||
numbytes--;
|
||||
|
||||
reg = RREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_STATUS);
|
||||
|
||||
} while (numbytes && REG_GET_FIELD(reg, CKSVII2C_IC_STATUS, TFNF));
|
||||
}
|
||||
|
||||
/*
|
||||
* We waited too long for the transmission FIFO to become not-full.
|
||||
* Exit the loop with error.
|
||||
*/
|
||||
if (time_after(jiffies, timeout_counter)) {
|
||||
ret |= I2C_SW_TIMEOUT;
|
||||
goto Err;
|
||||
}
|
||||
}
|
||||
|
||||
ret = smu_v11_0_i2c_poll_tx_status(control);
|
||||
|
||||
Err:
|
||||
/* Any error, no point in proceeding */
|
||||
if (ret != I2C_OK) {
|
||||
if (ret & I2C_SW_TIMEOUT)
|
||||
DRM_ERROR("TIMEOUT ERROR !!!");
|
||||
|
||||
if (ret & I2C_NAK_7B_ADDR_NOACK)
|
||||
DRM_ERROR("Received I2C_NAK_7B_ADDR_NOACK !!!");
|
||||
|
||||
|
||||
if (ret & I2C_NAK_TXDATA_NOACK)
|
||||
DRM_ERROR("Received I2C_NAK_TXDATA_NOACK !!!");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* smu_v11_0_i2c_receive - Receive a block of data over the I2C bus from a slave device.
|
||||
*
|
||||
* @address: The I2C address of the slave device.
|
||||
* @numbytes: The amount of data to transmit.
|
||||
* @i2c_flag: Flags for transmission
|
||||
*
|
||||
* Returns 0 on success or error.
|
||||
*/
|
||||
static uint32_t smu_v11_0_i2c_receive(struct i2c_adapter *control,
|
||||
uint8_t address, uint8_t *data,
|
||||
uint32_t numbytes, uint8_t i2c_flag)
|
||||
{
|
||||
struct amdgpu_device *adev = to_amdgpu_device(control);
|
||||
uint32_t bytes_received, ret = I2C_OK;
|
||||
|
||||
bytes_received = 0;
|
||||
|
||||
/* Set the I2C slave address */
|
||||
smu_v11_0_i2c_set_address(control, address);
|
||||
|
||||
/* Enable I2C */
|
||||
smu_v11_0_i2c_enable(control, true);
|
||||
|
||||
while (numbytes > 0) {
|
||||
uint32_t reg = 0;
|
||||
|
||||
smu_v11_0_i2c_clear_status(control);
|
||||
|
||||
|
||||
/* Prepare transaction */
|
||||
|
||||
/* Each time we disable I2C, so this is not a restart */
|
||||
if (bytes_received == 0)
|
||||
reg = REG_SET_FIELD(reg, CKSVII2C_IC_DATA_CMD, RESTART,
|
||||
(i2c_flag & I2C_RESTART) ? 1 : 0);
|
||||
|
||||
reg = REG_SET_FIELD(reg, CKSVII2C_IC_DATA_CMD, DAT, 0);
|
||||
/* Read */
|
||||
reg = REG_SET_FIELD(reg, CKSVII2C_IC_DATA_CMD, CMD, 1);
|
||||
|
||||
/* Transmitting last byte */
|
||||
if (numbytes == 1)
|
||||
/* Final transaction, so send stop if requested */
|
||||
reg = REG_SET_FIELD(reg, CKSVII2C_IC_DATA_CMD, STOP,
|
||||
(i2c_flag & I2C_NO_STOP) ? 0 : 1);
|
||||
|
||||
WREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_DATA_CMD, reg);
|
||||
|
||||
ret = smu_v11_0_i2c_poll_rx_status(control);
|
||||
|
||||
/* Any error, no point in proceeding */
|
||||
if (ret != I2C_OK) {
|
||||
if (ret & I2C_SW_TIMEOUT)
|
||||
DRM_ERROR("TIMEOUT ERROR !!!");
|
||||
|
||||
if (ret & I2C_NAK_7B_ADDR_NOACK)
|
||||
DRM_ERROR("Received I2C_NAK_7B_ADDR_NOACK !!!");
|
||||
|
||||
if (ret & I2C_NAK_TXDATA_NOACK)
|
||||
DRM_ERROR("Received I2C_NAK_TXDATA_NOACK !!!");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
reg = RREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_DATA_CMD);
|
||||
data[bytes_received] = REG_GET_FIELD(reg, CKSVII2C_IC_DATA_CMD, DAT);
|
||||
|
||||
/* Record that the bytes were received */
|
||||
bytes_received++;
|
||||
numbytes--;
|
||||
}
|
||||
|
||||
DRM_DEBUG_DRIVER("I2C_Receive(), address = %x, bytes = %d, data :",
|
||||
(uint16_t)address, bytes_received);
|
||||
|
||||
if (drm_debug & DRM_UT_DRIVER) {
|
||||
print_hex_dump(KERN_INFO, "data: ", DUMP_PREFIX_NONE,
|
||||
16, 1, data, bytes_received, false);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void smu_v11_0_i2c_abort(struct i2c_adapter *control)
|
||||
{
|
||||
struct amdgpu_device *adev = to_amdgpu_device(control);
|
||||
uint32_t reg = 0;
|
||||
|
||||
/* Enable I2C engine; */
|
||||
reg = REG_SET_FIELD(reg, CKSVII2C_IC_ENABLE, ENABLE, 1);
|
||||
WREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_ENABLE, reg);
|
||||
|
||||
/* Abort previous transaction */
|
||||
reg = REG_SET_FIELD(reg, CKSVII2C_IC_ENABLE, ABORT, 1);
|
||||
WREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_ENABLE, reg);
|
||||
|
||||
DRM_DEBUG_DRIVER("I2C_Abort() Done.");
|
||||
}
|
||||
|
||||
|
||||
static bool smu_v11_0_i2c_activity_done(struct i2c_adapter *control)
|
||||
{
|
||||
struct amdgpu_device *adev = to_amdgpu_device(control);
|
||||
|
||||
const uint32_t IDLE_TIMEOUT = 1024;
|
||||
uint32_t timeout_count = 0;
|
||||
uint32_t reg_ic_enable, reg_ic_enable_status, reg_ic_clr_activity;
|
||||
|
||||
reg_ic_enable_status = RREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_ENABLE_STATUS);
|
||||
reg_ic_enable = RREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_ENABLE);
|
||||
|
||||
|
||||
if ((REG_GET_FIELD(reg_ic_enable, CKSVII2C_IC_ENABLE, ENABLE) == 0) &&
|
||||
(REG_GET_FIELD(reg_ic_enable_status, CKSVII2C_IC_ENABLE_STATUS, IC_EN) == 1)) {
|
||||
/*
|
||||
* Nobody is using I2C engine, but engine remains active because
|
||||
* someone missed to send STOP
|
||||
*/
|
||||
smu_v11_0_i2c_abort(control);
|
||||
} else if (REG_GET_FIELD(reg_ic_enable, CKSVII2C_IC_ENABLE, ENABLE) == 0) {
|
||||
/* Nobody is using I2C engine */
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Keep reading activity bit until it's cleared */
|
||||
do {
|
||||
reg_ic_clr_activity = RREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_CLR_ACTIVITY);
|
||||
|
||||
if (REG_GET_FIELD(reg_ic_clr_activity,
|
||||
CKSVII2C_IC_CLR_ACTIVITY, CLR_ACTIVITY) == 0)
|
||||
return true;
|
||||
|
||||
++timeout_count;
|
||||
|
||||
} while (timeout_count < IDLE_TIMEOUT);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void smu_v11_0_i2c_init(struct i2c_adapter *control)
|
||||
{
|
||||
/* Disable clock gating */
|
||||
smu_v11_0_i2c_set_clock_gating(control, false);
|
||||
|
||||
if (!smu_v11_0_i2c_activity_done(control))
|
||||
DRM_WARN("I2C busy !");
|
||||
|
||||
/* Disable I2C */
|
||||
smu_v11_0_i2c_enable(control, false);
|
||||
|
||||
/* Configure I2C to operate as master and in standard mode */
|
||||
smu_v11_0_i2c_configure(control);
|
||||
|
||||
/* Initialize the clock to 50 kHz default */
|
||||
smu_v11_0_i2c_set_clock(control);
|
||||
|
||||
}
|
||||
|
||||
static void smu_v11_0_i2c_fini(struct i2c_adapter *control)
|
||||
{
|
||||
struct amdgpu_device *adev = to_amdgpu_device(control);
|
||||
uint32_t reg_ic_enable_status, reg_ic_enable;
|
||||
|
||||
smu_v11_0_i2c_enable(control, false);
|
||||
|
||||
/* Double check if disabled, else force abort */
|
||||
reg_ic_enable_status = RREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_ENABLE_STATUS);
|
||||
reg_ic_enable = RREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_ENABLE);
|
||||
|
||||
if ((REG_GET_FIELD(reg_ic_enable, CKSVII2C_IC_ENABLE, ENABLE) == 0) &&
|
||||
(REG_GET_FIELD(reg_ic_enable_status,
|
||||
CKSVII2C_IC_ENABLE_STATUS, IC_EN) == 1)) {
|
||||
/*
|
||||
* Nobody is using I2C engine, but engine remains active because
|
||||
* someone missed to send STOP
|
||||
*/
|
||||
smu_v11_0_i2c_abort(control);
|
||||
}
|
||||
|
||||
/* Restore clock gating */
|
||||
smu_v11_0_i2c_set_clock_gating(control, true);
|
||||
|
||||
}
|
||||
|
||||
static bool smu_v11_0_i2c_bus_lock(struct i2c_adapter *control)
|
||||
{
|
||||
struct amdgpu_device *adev = to_amdgpu_device(control);
|
||||
|
||||
/* Send PPSMC_MSG_RequestI2CBus */
|
||||
if (!adev->powerplay.pp_funcs->smu_i2c_bus_access)
|
||||
goto Fail;
|
||||
|
||||
|
||||
if (!adev->powerplay.pp_funcs->smu_i2c_bus_access(adev->powerplay.pp_handle, true))
|
||||
return true;
|
||||
|
||||
Fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool smu_v11_0_i2c_bus_unlock(struct i2c_adapter *control)
|
||||
{
|
||||
struct amdgpu_device *adev = to_amdgpu_device(control);
|
||||
|
||||
/* Send PPSMC_MSG_RequestI2CBus */
|
||||
if (!adev->powerplay.pp_funcs->smu_i2c_bus_access)
|
||||
goto Fail;
|
||||
|
||||
/* Send PPSMC_MSG_ReleaseI2CBus */
|
||||
if (!adev->powerplay.pp_funcs->smu_i2c_bus_access(adev->powerplay.pp_handle,
|
||||
false))
|
||||
return true;
|
||||
|
||||
Fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
/***************************** EEPROM I2C GLUE ****************************/
|
||||
|
||||
static uint32_t smu_v11_0_i2c_eeprom_read_data(struct i2c_adapter *control,
|
||||
uint8_t address,
|
||||
uint8_t *data,
|
||||
uint32_t numbytes)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
|
||||
/* First 2 bytes are dummy write to set EEPROM address */
|
||||
ret = smu_v11_0_i2c_transmit(control, address, data, 2, I2C_NO_STOP);
|
||||
if (ret != I2C_OK)
|
||||
goto Fail;
|
||||
|
||||
/* Now read data starting with that address */
|
||||
ret = smu_v11_0_i2c_receive(control, address, data + 2, numbytes - 2,
|
||||
I2C_RESTART);
|
||||
|
||||
Fail:
|
||||
if (ret != I2C_OK)
|
||||
DRM_ERROR("ReadData() - I2C error occurred :%x", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint32_t smu_v11_0_i2c_eeprom_write_data(struct i2c_adapter *control,
|
||||
uint8_t address,
|
||||
uint8_t *data,
|
||||
uint32_t numbytes)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
ret = smu_v11_0_i2c_transmit(control, address, data, numbytes, 0);
|
||||
|
||||
if (ret != I2C_OK)
|
||||
DRM_ERROR("WriteI2CData() - I2C error occurred :%x", ret);
|
||||
else
|
||||
/*
|
||||
* According to EEPROM spec there is a MAX of 10 ms required for
|
||||
* EEPROM to flush internal RX buffer after STOP was issued at the
|
||||
* end of write transaction. During this time the EEPROM will not be
|
||||
* responsive to any more commands - so wait a bit more.
|
||||
*
|
||||
* TODO Improve to wait for first ACK for slave address after
|
||||
* internal write cycle done.
|
||||
*/
|
||||
msleep(10);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
static void lock_bus(struct i2c_adapter *i2c, unsigned int flags)
|
||||
{
|
||||
struct amdgpu_ras_eeprom_control *control = to_eeprom_control(i2c);
|
||||
|
||||
if (!smu_v11_0_i2c_bus_lock(i2c)) {
|
||||
DRM_ERROR("Failed to lock the bus from SMU");
|
||||
return;
|
||||
}
|
||||
|
||||
control->bus_locked = true;
|
||||
}
|
||||
|
||||
static int trylock_bus(struct i2c_adapter *i2c, unsigned int flags)
|
||||
{
|
||||
WARN_ONCE(1, "This operation not supposed to run in atomic context!");
|
||||
return false;
|
||||
}
|
||||
|
||||
static void unlock_bus(struct i2c_adapter *i2c, unsigned int flags)
|
||||
{
|
||||
struct amdgpu_ras_eeprom_control *control = to_eeprom_control(i2c);
|
||||
|
||||
if (!smu_v11_0_i2c_bus_unlock(i2c)) {
|
||||
DRM_ERROR("Failed to unlock the bus from SMU");
|
||||
return;
|
||||
}
|
||||
|
||||
control->bus_locked = false;
|
||||
}
|
||||
|
||||
static const struct i2c_lock_operations smu_v11_0_i2c_i2c_lock_ops = {
|
||||
.lock_bus = lock_bus,
|
||||
.trylock_bus = trylock_bus,
|
||||
.unlock_bus = unlock_bus,
|
||||
};
|
||||
|
||||
static int smu_v11_0_i2c_eeprom_i2c_xfer(struct i2c_adapter *i2c_adap,
|
||||
struct i2c_msg *msgs, int num)
|
||||
{
|
||||
int i, ret;
|
||||
struct amdgpu_ras_eeprom_control *control = to_eeprom_control(i2c_adap);
|
||||
|
||||
if (!control->bus_locked) {
|
||||
DRM_ERROR("I2C bus unlocked, stopping transaction!");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
smu_v11_0_i2c_init(i2c_adap);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
if (msgs[i].flags & I2C_M_RD)
|
||||
ret = smu_v11_0_i2c_eeprom_read_data(i2c_adap,
|
||||
(uint8_t)msgs[i].addr,
|
||||
msgs[i].buf, msgs[i].len);
|
||||
else
|
||||
ret = smu_v11_0_i2c_eeprom_write_data(i2c_adap,
|
||||
(uint8_t)msgs[i].addr,
|
||||
msgs[i].buf, msgs[i].len);
|
||||
|
||||
if (ret != I2C_OK) {
|
||||
num = -EIO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
smu_v11_0_i2c_fini(i2c_adap);
|
||||
return num;
|
||||
}
|
||||
|
||||
static u32 smu_v11_0_i2c_eeprom_i2c_func(struct i2c_adapter *adap)
|
||||
{
|
||||
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
|
||||
}
|
||||
|
||||
|
||||
static const struct i2c_algorithm smu_v11_0_i2c_eeprom_i2c_algo = {
|
||||
.master_xfer = smu_v11_0_i2c_eeprom_i2c_xfer,
|
||||
.functionality = smu_v11_0_i2c_eeprom_i2c_func,
|
||||
};
|
||||
|
||||
int smu_v11_0_i2c_eeprom_control_init(struct i2c_adapter *control)
|
||||
{
|
||||
struct amdgpu_device *adev = to_amdgpu_device(control);
|
||||
int res;
|
||||
|
||||
control->owner = THIS_MODULE;
|
||||
control->class = I2C_CLASS_SPD;
|
||||
control->dev.parent = &adev->pdev->dev;
|
||||
control->algo = &smu_v11_0_i2c_eeprom_i2c_algo;
|
||||
snprintf(control->name, sizeof(control->name), "RAS EEPROM");
|
||||
control->lock_ops = &smu_v11_0_i2c_i2c_lock_ops;
|
||||
|
||||
res = i2c_add_adapter(control);
|
||||
if (res)
|
||||
DRM_ERROR("Failed to register hw i2c, err: %d\n", res);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void smu_v11_0_i2c_eeprom_control_fini(struct i2c_adapter *control)
|
||||
{
|
||||
i2c_del_adapter(control);
|
||||
}
|
||||
|
||||
/*
|
||||
* Keep this for future unit test if bugs arise
|
||||
*/
|
||||
#if 0
|
||||
#define I2C_TARGET_ADDR 0xA0
|
||||
|
||||
bool smu_v11_0_i2c_test_bus(struct i2c_adapter *control)
|
||||
{
|
||||
|
||||
uint32_t ret = I2C_OK;
|
||||
uint8_t data[6] = {0xf, 0, 0xde, 0xad, 0xbe, 0xef};
|
||||
|
||||
|
||||
DRM_INFO("Begin");
|
||||
|
||||
if (!smu_v11_0_i2c_bus_lock(control)) {
|
||||
DRM_ERROR("Failed to lock the bus!.");
|
||||
return false;
|
||||
}
|
||||
|
||||
smu_v11_0_i2c_init(control);
|
||||
|
||||
/* Write 0xde to address 0x0000 on the EEPROM */
|
||||
ret = smu_v11_0_i2c_eeprom_write_data(control, I2C_TARGET_ADDR, data, 6);
|
||||
|
||||
ret = smu_v11_0_i2c_eeprom_read_data(control, I2C_TARGET_ADDR, data, 6);
|
||||
|
||||
smu_v11_0_i2c_fini(control);
|
||||
|
||||
smu_v11_0_i2c_bus_unlock(control);
|
||||
|
||||
|
||||
DRM_INFO("End");
|
||||
return true;
|
||||
}
|
||||
#endif
|
34
drivers/gpu/drm/amd/amdgpu/smu_v11_0_i2c.h
Normal file
34
drivers/gpu/drm/amd/amdgpu/smu_v11_0_i2c.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SMU_V11_I2C_CONTROL_H
|
||||
#define SMU_V11_I2C_CONTROL_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct i2c_adapter;
|
||||
|
||||
int smu_v11_0_i2c_eeprom_control_init(struct i2c_adapter *control);
|
||||
void smu_v11_0_i2c_eeprom_control_fini(struct i2c_adapter *control);
|
||||
|
||||
#endif
|
@ -558,10 +558,12 @@ static int soc15_asic_reset(struct amdgpu_device *adev)
|
||||
{
|
||||
switch (soc15_asic_reset_method(adev)) {
|
||||
case AMD_RESET_METHOD_BACO:
|
||||
amdgpu_inc_vram_lost(adev);
|
||||
return soc15_asic_baco_reset(adev);
|
||||
case AMD_RESET_METHOD_MODE2:
|
||||
return soc15_mode2_reset(adev);
|
||||
default:
|
||||
amdgpu_inc_vram_lost(adev);
|
||||
return soc15_asic_mode1_reset(adev);
|
||||
}
|
||||
}
|
||||
@ -766,6 +768,12 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
|
||||
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, &dce_virtual_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);
|
||||
#else
|
||||
# warning "Enable CONFIG_DRM_AMD_DC for display support on SOC15."
|
||||
#endif
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block);
|
||||
break;
|
||||
default:
|
||||
|
@ -234,7 +234,13 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI, (ih->gpu_addr >> 40) & 0xff);
|
||||
|
||||
ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL);
|
||||
ih_chicken = RREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN);
|
||||
ih_rb_cntl = vega10_ih_rb_cntl(ih, ih_rb_cntl);
|
||||
if (adev->irq.ih.use_bus_addr) {
|
||||
ih_chicken = REG_SET_FIELD(ih_chicken, IH_CHICKEN, MC_SPACE_GPA_ENABLE, 1);
|
||||
} else {
|
||||
ih_chicken = REG_SET_FIELD(ih_chicken, IH_CHICKEN, MC_SPACE_FBPA_ENABLE, 1);
|
||||
}
|
||||
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RPTR_REARM,
|
||||
!!adev->irq.msi_enabled);
|
||||
|
||||
@ -247,14 +253,10 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
|
||||
}
|
||||
|
||||
if ((adev->asic_type == CHIP_ARCTURUS || adev->asic_type == CHIP_RENOIR) &&
|
||||
adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) {
|
||||
if (adev->irq.ih.use_bus_addr) {
|
||||
ih_chicken = RREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN);
|
||||
ih_chicken |= 0x00000010;
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN, ih_chicken);
|
||||
}
|
||||
}
|
||||
if ((adev->asic_type == CHIP_ARCTURUS
|
||||
&& adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT)
|
||||
|| adev->asic_type == CHIP_RENOIR)
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN, ih_chicken);
|
||||
|
||||
/* set the writeback address whether it's enabled or not */
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_LO,
|
||||
|
@ -26,6 +26,14 @@ config DRM_AMD_DC_DCN2_0
|
||||
Choose this option if you want to have
|
||||
Navi support for display engine
|
||||
|
||||
config DRM_AMD_DC_DCN2_1
|
||||
bool "DCN 2.1 family"
|
||||
depends on DRM_AMD_DC && X86
|
||||
depends on DRM_AMD_DC_DCN2_0
|
||||
help
|
||||
Choose this option if you want to have
|
||||
Renoir support for display engine
|
||||
|
||||
config DRM_AMD_DC_DSC_SUPPORT
|
||||
bool "DSC support"
|
||||
default y
|
||||
|
@ -814,6 +814,7 @@ static int load_dmcu_fw(struct amdgpu_device *adev)
|
||||
case CHIP_NAVI10:
|
||||
case CHIP_NAVI14:
|
||||
case CHIP_NAVI12:
|
||||
case CHIP_RENOIR:
|
||||
return 0;
|
||||
case CHIP_RAVEN:
|
||||
if (ASICREV_IS_PICASSO(adev->external_rev_id))
|
||||
@ -2366,6 +2367,9 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
|
||||
case CHIP_NAVI12:
|
||||
case CHIP_NAVI10:
|
||||
case CHIP_NAVI14:
|
||||
#endif
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
case CHIP_RENOIR:
|
||||
#endif
|
||||
if (dcn10_register_irq_handlers(dm->adev)) {
|
||||
DRM_ERROR("DM: Failed to initialize IRQ\n");
|
||||
@ -2531,6 +2535,13 @@ static int dm_early_init(void *handle)
|
||||
adev->mode_info.num_hpd = 5;
|
||||
adev->mode_info.num_dig = 5;
|
||||
break;
|
||||
#endif
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
case CHIP_RENOIR:
|
||||
adev->mode_info.num_crtc = 4;
|
||||
adev->mode_info.num_hpd = 4;
|
||||
adev->mode_info.num_dig = 4;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
DRM_ERROR("Unsupported ASIC type: 0x%X\n", adev->asic_type);
|
||||
@ -2828,6 +2839,9 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
|
||||
adev->asic_type == CHIP_NAVI10 ||
|
||||
adev->asic_type == CHIP_NAVI14 ||
|
||||
adev->asic_type == CHIP_NAVI12 ||
|
||||
#endif
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
adev->asic_type == CHIP_RENOIR ||
|
||||
#endif
|
||||
adev->asic_type == CHIP_RAVEN) {
|
||||
/* Fill GFX9 params */
|
||||
@ -5727,7 +5741,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
||||
false,
|
||||
msecs_to_jiffies(5000));
|
||||
if (unlikely(r <= 0))
|
||||
DRM_ERROR("Waiting for fences timed out or interrupted!");
|
||||
DRM_ERROR("Waiting for fences timed out!");
|
||||
|
||||
/*
|
||||
* TODO This might fail and hence better not used, wait
|
||||
|
@ -37,6 +37,9 @@ endif
|
||||
ifdef CONFIG_DRM_AMD_DC_DCN1_0
|
||||
DC_LIBS += dcn10 dml
|
||||
endif
|
||||
ifdef CONFIG_DRM_AMD_DC_DCN2_1
|
||||
DC_LIBS += dcn21
|
||||
endif
|
||||
|
||||
DC_LIBS += dce120
|
||||
|
||||
|
@ -66,6 +66,11 @@ bool dal_bios_parser_init_cmd_tbl_helper2(
|
||||
case DCN_VERSION_2_0:
|
||||
*h = dal_cmd_tbl_helper_dce112_get_table2();
|
||||
return true;
|
||||
#endif
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
case DCN_VERSION_2_1:
|
||||
*h = dal_cmd_tbl_helper_dce112_get_table2();
|
||||
return true;
|
||||
#endif
|
||||
case DCE_VERSION_12_0:
|
||||
case DCE_VERSION_12_1:
|
||||
|
@ -85,3 +85,13 @@ AMD_DAL_CLK_MGR_DCN20 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn20/,$(CLK_MGR_DC
|
||||
AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN20)
|
||||
endif
|
||||
|
||||
ifdef CONFIG_DRM_AMD_DC_DCN2_1
|
||||
###############################################################################
|
||||
# DCN21
|
||||
###############################################################################
|
||||
CLK_MGR_DCN21 = rn_clk_mgr.o rn_clk_mgr_vbios_smu.o
|
||||
|
||||
AMD_DAL_CLK_MGR_DCN21 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn21/,$(CLK_MGR_DCN21))
|
||||
|
||||
AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN21)
|
||||
endif
|
||||
|
@ -37,6 +37,9 @@
|
||||
#include "dcn10/rv1_clk_mgr.h"
|
||||
#include "dcn10/rv2_clk_mgr.h"
|
||||
#include "dcn20/dcn20_clk_mgr.h"
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
#include "dcn21/rn_clk_mgr.h"
|
||||
#endif
|
||||
|
||||
|
||||
int clk_mgr_helper_get_active_display_cnt(
|
||||
@ -108,6 +111,12 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
|
||||
case FAMILY_RV:
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
if (ASICREV_IS_RENOIR(asic_id.hw_internal_rev)) {
|
||||
rn_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg);
|
||||
break;
|
||||
}
|
||||
#endif /* DCN2_1 */
|
||||
if (ASICREV_IS_RAVEN2(asic_id.hw_internal_rev)) {
|
||||
rv2_clk_mgr_construct(ctx, clk_mgr, pp_smu);
|
||||
break;
|
||||
|
590
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c
Normal file
590
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c
Normal file
@ -0,0 +1,590 @@
|
||||
/*
|
||||
* Copyright 2018 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#include "dccg.h"
|
||||
#include "clk_mgr_internal.h"
|
||||
|
||||
|
||||
#include "dcn20/dcn20_clk_mgr.h"
|
||||
#include "rn_clk_mgr.h"
|
||||
|
||||
|
||||
#include "dce100/dce_clk_mgr.h"
|
||||
#include "rn_clk_mgr_vbios_smu.h"
|
||||
#include "reg_helper.h"
|
||||
#include "core_types.h"
|
||||
#include "dm_helpers.h"
|
||||
|
||||
#include "atomfirmware.h"
|
||||
#include "clk/clk_10_0_2_offset.h"
|
||||
#include "clk/clk_10_0_2_sh_mask.h"
|
||||
#include "renoir_ip_offset.h"
|
||||
|
||||
|
||||
/* Constants */
|
||||
|
||||
#define LPDDR_MEM_RETRAIN_LATENCY 4.977 /* Number obtained from LPDDR4 Training Counter Requirement doc */
|
||||
|
||||
/* Macros */
|
||||
|
||||
#define REG(reg_name) \
|
||||
(CLK_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name)
|
||||
|
||||
void rn_update_clocks(struct clk_mgr *clk_mgr_base,
|
||||
struct dc_state *context,
|
||||
bool safe_to_lower)
|
||||
{
|
||||
struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
|
||||
struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk;
|
||||
struct dc *dc = clk_mgr_base->ctx->dc;
|
||||
int display_count;
|
||||
bool update_dppclk = false;
|
||||
bool update_dispclk = false;
|
||||
bool enter_display_off = false;
|
||||
bool dpp_clock_lowered = false;
|
||||
struct dmcu *dmcu = clk_mgr_base->ctx->dc->res_pool->dmcu;
|
||||
|
||||
display_count = clk_mgr_helper_get_active_display_cnt(dc, context);
|
||||
|
||||
if (display_count == 0)
|
||||
enter_display_off = true;
|
||||
|
||||
if (enter_display_off == safe_to_lower) {
|
||||
rn_vbios_smu_set_display_count(clk_mgr, display_count);
|
||||
}
|
||||
|
||||
if (should_set_clock(safe_to_lower, new_clocks->phyclk_khz, clk_mgr_base->clks.phyclk_khz)) {
|
||||
clk_mgr_base->clks.phyclk_khz = new_clocks->phyclk_khz;
|
||||
rn_vbios_smu_set_phyclk(clk_mgr, clk_mgr_base->clks.phyclk_khz);
|
||||
}
|
||||
|
||||
if (should_set_clock(safe_to_lower, new_clocks->dcfclk_khz, clk_mgr_base->clks.dcfclk_khz)) {
|
||||
clk_mgr_base->clks.dcfclk_khz = new_clocks->dcfclk_khz;
|
||||
rn_vbios_smu_set_hard_min_dcfclk(clk_mgr, clk_mgr_base->clks.dcfclk_khz);
|
||||
}
|
||||
|
||||
if (should_set_clock(safe_to_lower,
|
||||
new_clocks->dcfclk_deep_sleep_khz, clk_mgr_base->clks.dcfclk_deep_sleep_khz)) {
|
||||
clk_mgr_base->clks.dcfclk_deep_sleep_khz = new_clocks->dcfclk_deep_sleep_khz;
|
||||
rn_vbios_smu_set_min_deep_sleep_dcfclk(clk_mgr, clk_mgr_base->clks.dcfclk_deep_sleep_khz);
|
||||
}
|
||||
|
||||
if (should_set_clock(safe_to_lower, new_clocks->dppclk_khz, clk_mgr->base.clks.dppclk_khz)) {
|
||||
if (clk_mgr->base.clks.dppclk_khz > new_clocks->dppclk_khz)
|
||||
dpp_clock_lowered = true;
|
||||
clk_mgr_base->clks.dppclk_khz = new_clocks->dppclk_khz;
|
||||
update_dppclk = true;
|
||||
}
|
||||
|
||||
if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) {
|
||||
clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz;
|
||||
rn_vbios_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz);
|
||||
|
||||
update_dispclk = true;
|
||||
}
|
||||
|
||||
if (dpp_clock_lowered) {
|
||||
// if clock is being lowered, increase DTO before lowering refclk
|
||||
dcn20_update_clocks_update_dpp_dto(clk_mgr, context);
|
||||
rn_vbios_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz);
|
||||
} else {
|
||||
// if clock is being raised, increase refclk before lowering DTO
|
||||
if (update_dppclk || update_dispclk)
|
||||
rn_vbios_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz);
|
||||
if (update_dppclk)
|
||||
dcn20_update_clocks_update_dpp_dto(clk_mgr, context);
|
||||
}
|
||||
|
||||
if (update_dispclk &&
|
||||
dmcu && dmcu->funcs->is_dmcu_initialized(dmcu)) {
|
||||
/*update dmcu for wait_loop count*/
|
||||
dmcu->funcs->set_psr_wait_loop(dmcu,
|
||||
clk_mgr_base->clks.dispclk_khz / 1000 / 7);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int get_vco_frequency_from_reg(struct clk_mgr_internal *clk_mgr)
|
||||
{
|
||||
/* get FbMult value */
|
||||
struct fixed31_32 pll_req;
|
||||
unsigned int fbmult_frac_val = 0;
|
||||
unsigned int fbmult_int_val = 0;
|
||||
|
||||
|
||||
/*
|
||||
* Register value of fbmult is in 8.16 format, we are converting to 31.32
|
||||
* to leverage the fix point operations available in driver
|
||||
*/
|
||||
|
||||
REG_GET(CLK1_CLK_PLL_REQ, FbMult_frac, &fbmult_frac_val); /* 16 bit fractional part*/
|
||||
REG_GET(CLK1_CLK_PLL_REQ, FbMult_int, &fbmult_int_val); /* 8 bit integer part */
|
||||
|
||||
pll_req = dc_fixpt_from_int(fbmult_int_val);
|
||||
|
||||
/*
|
||||
* since fractional part is only 16 bit in register definition but is 32 bit
|
||||
* in our fix point definiton, need to shift left by 16 to obtain correct value
|
||||
*/
|
||||
pll_req.value |= fbmult_frac_val << 16;
|
||||
|
||||
/* multiply by REFCLK period */
|
||||
pll_req = dc_fixpt_mul_int(pll_req, clk_mgr->dfs_ref_freq_khz);
|
||||
|
||||
/* integer part is now VCO frequency in kHz */
|
||||
return dc_fixpt_floor(pll_req);
|
||||
}
|
||||
|
||||
static void rn_dump_clk_registers_internal(struct rn_clk_internal *internal, struct clk_mgr *clk_mgr_base)
|
||||
{
|
||||
struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
|
||||
|
||||
internal->CLK1_CLK3_CURRENT_CNT = REG_READ(CLK1_CLK3_CURRENT_CNT);
|
||||
internal->CLK1_CLK3_BYPASS_CNTL = REG_READ(CLK1_CLK3_BYPASS_CNTL);
|
||||
|
||||
internal->CLK1_CLK3_DS_CNTL = REG_READ(CLK1_CLK3_DS_CNTL); //dcf deep sleep divider
|
||||
internal->CLK1_CLK3_ALLOW_DS = REG_READ(CLK1_CLK3_ALLOW_DS);
|
||||
|
||||
internal->CLK1_CLK1_CURRENT_CNT = REG_READ(CLK1_CLK1_CURRENT_CNT);
|
||||
internal->CLK1_CLK1_BYPASS_CNTL = REG_READ(CLK1_CLK1_BYPASS_CNTL);
|
||||
|
||||
internal->CLK1_CLK2_CURRENT_CNT = REG_READ(CLK1_CLK2_CURRENT_CNT);
|
||||
internal->CLK1_CLK2_BYPASS_CNTL = REG_READ(CLK1_CLK2_BYPASS_CNTL);
|
||||
|
||||
internal->CLK1_CLK0_CURRENT_CNT = REG_READ(CLK1_CLK0_CURRENT_CNT);
|
||||
internal->CLK1_CLK0_BYPASS_CNTL = REG_READ(CLK1_CLK0_BYPASS_CNTL);
|
||||
}
|
||||
|
||||
/* This function collect raw clk register values */
|
||||
static void rn_dump_clk_registers(struct clk_state_registers_and_bypass *regs_and_bypass,
|
||||
struct clk_mgr *clk_mgr_base, struct clk_log_info *log_info)
|
||||
{
|
||||
struct rn_clk_internal internal = {0};
|
||||
char *bypass_clks[5] = {"0x0 DFS", "0x1 REFCLK", "0x2 ERROR", "0x3 400 FCH", "0x4 600 FCH"};
|
||||
unsigned int chars_printed = 0;
|
||||
unsigned int remaining_buffer = log_info->bufSize;
|
||||
|
||||
rn_dump_clk_registers_internal(&internal, clk_mgr_base);
|
||||
|
||||
regs_and_bypass->dcfclk = internal.CLK1_CLK3_CURRENT_CNT / 10;
|
||||
regs_and_bypass->dcf_deep_sleep_divider = internal.CLK1_CLK3_DS_CNTL / 10;
|
||||
regs_and_bypass->dcf_deep_sleep_allow = internal.CLK1_CLK3_ALLOW_DS;
|
||||
regs_and_bypass->dprefclk = internal.CLK1_CLK2_CURRENT_CNT / 10;
|
||||
regs_and_bypass->dispclk = internal.CLK1_CLK0_CURRENT_CNT / 10;
|
||||
regs_and_bypass->dppclk = internal.CLK1_CLK1_CURRENT_CNT / 10;
|
||||
|
||||
regs_and_bypass->dppclk_bypass = internal.CLK1_CLK1_BYPASS_CNTL & 0x0007;
|
||||
if (regs_and_bypass->dppclk_bypass < 0 || regs_and_bypass->dppclk_bypass > 4)
|
||||
regs_and_bypass->dppclk_bypass = 0;
|
||||
regs_and_bypass->dcfclk_bypass = internal.CLK1_CLK3_BYPASS_CNTL & 0x0007;
|
||||
if (regs_and_bypass->dcfclk_bypass < 0 || regs_and_bypass->dcfclk_bypass > 4)
|
||||
regs_and_bypass->dcfclk_bypass = 0;
|
||||
regs_and_bypass->dispclk_bypass = internal.CLK1_CLK0_BYPASS_CNTL & 0x0007;
|
||||
if (regs_and_bypass->dispclk_bypass < 0 || regs_and_bypass->dispclk_bypass > 4)
|
||||
regs_and_bypass->dispclk_bypass = 0;
|
||||
regs_and_bypass->dprefclk_bypass = internal.CLK1_CLK2_BYPASS_CNTL & 0x0007;
|
||||
if (regs_and_bypass->dprefclk_bypass < 0 || regs_and_bypass->dprefclk_bypass > 4)
|
||||
regs_and_bypass->dprefclk_bypass = 0;
|
||||
|
||||
if (log_info->enabled) {
|
||||
chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "clk_type,clk_value,deepsleep_cntl,deepsleep_allow,bypass\n");
|
||||
remaining_buffer -= chars_printed;
|
||||
*log_info->sum_chars_printed += chars_printed;
|
||||
log_info->pBuf += chars_printed;
|
||||
|
||||
chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "dcfclk,%d,%d,%d,%s\n",
|
||||
regs_and_bypass->dcfclk,
|
||||
regs_and_bypass->dcf_deep_sleep_divider,
|
||||
regs_and_bypass->dcf_deep_sleep_allow,
|
||||
bypass_clks[(int) regs_and_bypass->dcfclk_bypass]);
|
||||
remaining_buffer -= chars_printed;
|
||||
*log_info->sum_chars_printed += chars_printed;
|
||||
log_info->pBuf += chars_printed;
|
||||
|
||||
chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "dprefclk,%d,N/A,N/A,%s\n",
|
||||
regs_and_bypass->dprefclk,
|
||||
bypass_clks[(int) regs_and_bypass->dprefclk_bypass]);
|
||||
remaining_buffer -= chars_printed;
|
||||
*log_info->sum_chars_printed += chars_printed;
|
||||
log_info->pBuf += chars_printed;
|
||||
|
||||
chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "dispclk,%d,N/A,N/A,%s\n",
|
||||
regs_and_bypass->dispclk,
|
||||
bypass_clks[(int) regs_and_bypass->dispclk_bypass]);
|
||||
remaining_buffer -= chars_printed;
|
||||
*log_info->sum_chars_printed += chars_printed;
|
||||
log_info->pBuf += chars_printed;
|
||||
|
||||
//split
|
||||
chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "SPLIT\n");
|
||||
remaining_buffer -= chars_printed;
|
||||
*log_info->sum_chars_printed += chars_printed;
|
||||
log_info->pBuf += chars_printed;
|
||||
|
||||
// REGISTER VALUES
|
||||
chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "reg_name,value,clk_type\n");
|
||||
remaining_buffer -= chars_printed;
|
||||
*log_info->sum_chars_printed += chars_printed;
|
||||
log_info->pBuf += chars_printed;
|
||||
|
||||
chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK3_CURRENT_CNT,%d,dcfclk\n",
|
||||
internal.CLK1_CLK3_CURRENT_CNT);
|
||||
remaining_buffer -= chars_printed;
|
||||
*log_info->sum_chars_printed += chars_printed;
|
||||
log_info->pBuf += chars_printed;
|
||||
|
||||
chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK3_DS_CNTL,%d,dcf_deep_sleep_divider\n",
|
||||
internal.CLK1_CLK3_DS_CNTL);
|
||||
remaining_buffer -= chars_printed;
|
||||
*log_info->sum_chars_printed += chars_printed;
|
||||
log_info->pBuf += chars_printed;
|
||||
|
||||
chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK3_ALLOW_DS,%d,dcf_deep_sleep_allow\n",
|
||||
internal.CLK1_CLK3_ALLOW_DS);
|
||||
remaining_buffer -= chars_printed;
|
||||
*log_info->sum_chars_printed += chars_printed;
|
||||
log_info->pBuf += chars_printed;
|
||||
|
||||
chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK2_CURRENT_CNT,%d,dprefclk\n",
|
||||
internal.CLK1_CLK2_CURRENT_CNT);
|
||||
remaining_buffer -= chars_printed;
|
||||
*log_info->sum_chars_printed += chars_printed;
|
||||
log_info->pBuf += chars_printed;
|
||||
|
||||
chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK0_CURRENT_CNT,%d,dispclk\n",
|
||||
internal.CLK1_CLK0_CURRENT_CNT);
|
||||
remaining_buffer -= chars_printed;
|
||||
*log_info->sum_chars_printed += chars_printed;
|
||||
log_info->pBuf += chars_printed;
|
||||
|
||||
chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK1_CURRENT_CNT,%d,dppclk\n",
|
||||
internal.CLK1_CLK1_CURRENT_CNT);
|
||||
remaining_buffer -= chars_printed;
|
||||
*log_info->sum_chars_printed += chars_printed;
|
||||
log_info->pBuf += chars_printed;
|
||||
|
||||
chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK3_BYPASS_CNTL,%d,dcfclk_bypass\n",
|
||||
internal.CLK1_CLK3_BYPASS_CNTL);
|
||||
remaining_buffer -= chars_printed;
|
||||
*log_info->sum_chars_printed += chars_printed;
|
||||
log_info->pBuf += chars_printed;
|
||||
|
||||
chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK2_BYPASS_CNTL,%d,dprefclk_bypass\n",
|
||||
internal.CLK1_CLK2_BYPASS_CNTL);
|
||||
remaining_buffer -= chars_printed;
|
||||
*log_info->sum_chars_printed += chars_printed;
|
||||
log_info->pBuf += chars_printed;
|
||||
|
||||
chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK0_BYPASS_CNTL,%d,dispclk_bypass\n",
|
||||
internal.CLK1_CLK0_BYPASS_CNTL);
|
||||
remaining_buffer -= chars_printed;
|
||||
*log_info->sum_chars_printed += chars_printed;
|
||||
log_info->pBuf += chars_printed;
|
||||
|
||||
chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK1_BYPASS_CNTL,%d,dppclk_bypass\n",
|
||||
internal.CLK1_CLK1_BYPASS_CNTL);
|
||||
remaining_buffer -= chars_printed;
|
||||
*log_info->sum_chars_printed += chars_printed;
|
||||
log_info->pBuf += chars_printed;
|
||||
}
|
||||
}
|
||||
|
||||
/* This function produce translated logical clk state values*/
|
||||
void rn_get_clk_states(struct clk_mgr *clk_mgr_base, struct clk_states *s)
|
||||
{
|
||||
struct clk_state_registers_and_bypass sb = { 0 };
|
||||
struct clk_log_info log_info = { 0 };
|
||||
|
||||
rn_dump_clk_registers(&sb, clk_mgr_base, &log_info);
|
||||
|
||||
s->dprefclk_khz = sb.dprefclk;
|
||||
}
|
||||
|
||||
void rn_enable_pme_wa(struct clk_mgr *clk_mgr_base)
|
||||
{
|
||||
struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
|
||||
|
||||
rn_vbios_smu_enable_pme_wa(clk_mgr);
|
||||
}
|
||||
|
||||
static struct clk_mgr_funcs dcn21_funcs = {
|
||||
.get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
|
||||
.update_clocks = rn_update_clocks,
|
||||
.init_clocks = dcn2_init_clocks,
|
||||
.enable_pme_wa = rn_enable_pme_wa,
|
||||
/* .dump_clk_registers = rn_dump_clk_registers */
|
||||
};
|
||||
|
||||
struct clk_bw_params rn_bw_params = {
|
||||
.vram_type = Ddr4MemType,
|
||||
.num_channels = 1,
|
||||
.clk_table = {
|
||||
.entries = {
|
||||
{
|
||||
.voltage = 0,
|
||||
.dcfclk_mhz = 400,
|
||||
.fclk_mhz = 400,
|
||||
.memclk_mhz = 800,
|
||||
.socclk_mhz = 0,
|
||||
},
|
||||
{
|
||||
.voltage = 0,
|
||||
.dcfclk_mhz = 483,
|
||||
.fclk_mhz = 800,
|
||||
.memclk_mhz = 1600,
|
||||
.socclk_mhz = 0,
|
||||
},
|
||||
{
|
||||
.voltage = 0,
|
||||
.dcfclk_mhz = 602,
|
||||
.fclk_mhz = 1067,
|
||||
.memclk_mhz = 1067,
|
||||
.socclk_mhz = 0,
|
||||
},
|
||||
{
|
||||
.voltage = 0,
|
||||
.dcfclk_mhz = 738,
|
||||
.fclk_mhz = 1333,
|
||||
.memclk_mhz = 1600,
|
||||
.socclk_mhz = 0,
|
||||
},
|
||||
},
|
||||
|
||||
.num_entries = 4,
|
||||
},
|
||||
|
||||
.wm_table = {
|
||||
.entries = {
|
||||
{
|
||||
.wm_inst = WM_A,
|
||||
.wm_type = WM_TYPE_PSTATE_CHG,
|
||||
.pstate_latency_us = 23.84,
|
||||
.valid = true,
|
||||
},
|
||||
{
|
||||
.wm_inst = WM_B,
|
||||
.wm_type = WM_TYPE_PSTATE_CHG,
|
||||
.pstate_latency_us = 23.84,
|
||||
.valid = true,
|
||||
},
|
||||
{
|
||||
.wm_inst = WM_C,
|
||||
.wm_type = WM_TYPE_PSTATE_CHG,
|
||||
.pstate_latency_us = 23.84,
|
||||
.valid = true,
|
||||
},
|
||||
{
|
||||
.wm_inst = WM_D,
|
||||
.wm_type = WM_TYPE_PSTATE_CHG,
|
||||
.pstate_latency_us = 23.84,
|
||||
.valid = true,
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
void build_watermark_ranges(struct clk_bw_params *bw_params, struct pp_smu_wm_range_sets *ranges)
|
||||
{
|
||||
int i, num_valid_sets;
|
||||
|
||||
num_valid_sets = 0;
|
||||
|
||||
for (i = 0; i < WM_SET_COUNT; i++) {
|
||||
/* skip empty entries, the smu array has no holes*/
|
||||
if (!bw_params->wm_table.entries[i].valid)
|
||||
continue;
|
||||
|
||||
ranges->reader_wm_sets[num_valid_sets].wm_inst = bw_params->wm_table.entries[i].wm_inst;
|
||||
ranges->reader_wm_sets[num_valid_sets].wm_type = bw_params->wm_table.entries[i].wm_type;;
|
||||
/* We will not select WM based on dcfclk, so leave it as unconstrained */
|
||||
ranges->reader_wm_sets[num_valid_sets].min_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
|
||||
ranges->reader_wm_sets[num_valid_sets].max_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
|
||||
/* fclk wil be used to select WM*/
|
||||
|
||||
if (ranges->reader_wm_sets[num_valid_sets].wm_type == WM_TYPE_PSTATE_CHG) {
|
||||
if (i == 0)
|
||||
ranges->reader_wm_sets[num_valid_sets].min_fill_clk_mhz = 0;
|
||||
else {
|
||||
/* add 1 to make it non-overlapping with next lvl */
|
||||
ranges->reader_wm_sets[num_valid_sets].min_fill_clk_mhz = bw_params->clk_table.entries[i - 1].fclk_mhz + 1;
|
||||
}
|
||||
ranges->reader_wm_sets[num_valid_sets].max_fill_clk_mhz = bw_params->clk_table.entries[i].fclk_mhz;
|
||||
|
||||
} else {
|
||||
/* unconstrained for memory retraining */
|
||||
ranges->reader_wm_sets[num_valid_sets].min_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
|
||||
ranges->reader_wm_sets[num_valid_sets].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
|
||||
|
||||
/* Modify previous watermark range to cover up to max */
|
||||
ranges->reader_wm_sets[num_valid_sets - 1].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
|
||||
}
|
||||
num_valid_sets++;
|
||||
}
|
||||
|
||||
ASSERT(num_valid_sets != 0); /* Must have at least one set of valid watermarks */
|
||||
ranges->num_reader_wm_sets = num_valid_sets;
|
||||
|
||||
/* modify the min and max to make sure we cover the whole range*/
|
||||
ranges->reader_wm_sets[0].min_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
|
||||
ranges->reader_wm_sets[0].min_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
|
||||
ranges->reader_wm_sets[ranges->num_reader_wm_sets - 1].max_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
|
||||
ranges->reader_wm_sets[ranges->num_reader_wm_sets - 1].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
|
||||
|
||||
/* This is for writeback only, does not matter currently as no writeback support*/
|
||||
ranges->num_writer_wm_sets = 1;
|
||||
ranges->writer_wm_sets[0].wm_inst = WM_A;
|
||||
ranges->writer_wm_sets[0].min_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
|
||||
ranges->writer_wm_sets[0].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
|
||||
ranges->writer_wm_sets[0].min_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
|
||||
ranges->writer_wm_sets[0].max_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
|
||||
|
||||
}
|
||||
|
||||
void clk_mgr_helper_populate_bw_params(struct clk_bw_params *bw_params, struct dpm_clocks *clock_table, struct hw_asic_id *asic_id)
|
||||
{
|
||||
int i;
|
||||
|
||||
ASSERT(PP_SMU_NUM_FCLK_DPM_LEVELS <= MAX_NUM_DPM_LVL);
|
||||
|
||||
for (i = 0; i < PP_SMU_NUM_FCLK_DPM_LEVELS; i++) {
|
||||
if (clock_table->FClocks[i].Freq == 0)
|
||||
break;
|
||||
|
||||
bw_params->clk_table.entries[i].dcfclk_mhz = clock_table->DcfClocks[i].Freq;
|
||||
bw_params->clk_table.entries[i].fclk_mhz = clock_table->FClocks[i].Freq;
|
||||
bw_params->clk_table.entries[i].memclk_mhz = clock_table->MemClocks[i].Freq;
|
||||
bw_params->clk_table.entries[i].socclk_mhz = clock_table->SocClocks[i].Freq;
|
||||
bw_params->clk_table.entries[i].voltage = clock_table->FClocks[i].Vol;
|
||||
}
|
||||
bw_params->clk_table.num_entries = i;
|
||||
|
||||
bw_params->vram_type = asic_id->vram_type;
|
||||
bw_params->num_channels = asic_id->vram_width / DDR4_DRAM_WIDTH;
|
||||
|
||||
for (i = 0; i < WM_SET_COUNT; i++) {
|
||||
bw_params->wm_table.entries[i].wm_inst = i;
|
||||
|
||||
if (clock_table->FClocks[i].Freq == 0) {
|
||||
bw_params->wm_table.entries[i].valid = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
bw_params->wm_table.entries[i].wm_type = WM_TYPE_PSTATE_CHG;
|
||||
bw_params->wm_table.entries[i].valid = true;
|
||||
}
|
||||
|
||||
if (bw_params->vram_type == LpDdr4MemType) {
|
||||
/*
|
||||
* WM set D will be re-purposed for memory retraining
|
||||
*/
|
||||
bw_params->wm_table.entries[WM_D].pstate_latency_us = LPDDR_MEM_RETRAIN_LATENCY;
|
||||
bw_params->wm_table.entries[WM_D].wm_inst = WM_D;
|
||||
bw_params->wm_table.entries[WM_D].wm_type = WM_TYPE_RETRAINING;
|
||||
bw_params->wm_table.entries[WM_D].valid = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void rn_clk_mgr_construct(
|
||||
struct dc_context *ctx,
|
||||
struct clk_mgr_internal *clk_mgr,
|
||||
struct pp_smu_funcs *pp_smu,
|
||||
struct dccg *dccg)
|
||||
{
|
||||
struct dc_debug_options *debug = &ctx->dc->debug;
|
||||
struct dpm_clocks clock_table = { 0 };
|
||||
struct clk_state_registers_and_bypass s = { 0 };
|
||||
|
||||
clk_mgr->base.ctx = ctx;
|
||||
clk_mgr->base.funcs = &dcn21_funcs;
|
||||
|
||||
clk_mgr->pp_smu = pp_smu;
|
||||
|
||||
clk_mgr->dccg = dccg;
|
||||
clk_mgr->dfs_bypass_disp_clk = 0;
|
||||
|
||||
clk_mgr->dprefclk_ss_percentage = 0;
|
||||
clk_mgr->dprefclk_ss_divider = 1000;
|
||||
clk_mgr->ss_on_dprefclk = false;
|
||||
clk_mgr->dfs_ref_freq_khz = 48000;
|
||||
|
||||
clk_mgr->smu_ver = rn_vbios_smu_get_smu_version(clk_mgr);
|
||||
|
||||
if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) {
|
||||
dcn21_funcs.update_clocks = dcn2_update_clocks_fpga;
|
||||
clk_mgr->dentist_vco_freq_khz = 3600000;
|
||||
clk_mgr->base.dprefclk_khz = 600000;
|
||||
} else {
|
||||
struct clk_log_info log_info = {0};
|
||||
|
||||
/* TODO: Check we get what we expect during bringup */
|
||||
clk_mgr->dentist_vco_freq_khz = get_vco_frequency_from_reg(clk_mgr);
|
||||
|
||||
/* in case we don't get a value from the register, use default */
|
||||
if (clk_mgr->dentist_vco_freq_khz == 0)
|
||||
clk_mgr->dentist_vco_freq_khz = 3600000;
|
||||
|
||||
rn_dump_clk_registers(&s, &clk_mgr->base, &log_info);
|
||||
clk_mgr->base.dprefclk_khz = s.dprefclk;
|
||||
|
||||
if (clk_mgr->base.dprefclk_khz != 600000) {
|
||||
clk_mgr->base.dprefclk_khz = 600000;
|
||||
ASSERT(1); //TODO: Renoir follow up.
|
||||
}
|
||||
|
||||
/* in case we don't get a value from the register, use default */
|
||||
if (clk_mgr->base.dprefclk_khz == 0)
|
||||
clk_mgr->base.dprefclk_khz = 600000;
|
||||
}
|
||||
|
||||
dce_clock_read_ss_info(clk_mgr);
|
||||
|
||||
clk_mgr->base.bw_params = &rn_bw_params;
|
||||
|
||||
if (pp_smu) {
|
||||
pp_smu->rn_funcs.get_dpm_clock_table(&pp_smu->rn_funcs.pp_smu, &clock_table);
|
||||
clk_mgr_helper_populate_bw_params(clk_mgr->base.bw_params, &clock_table, &ctx->asic_id);
|
||||
}
|
||||
|
||||
/*
|
||||
* Notify SMU which set of WM should be selected for different ranges of fclk
|
||||
* On Renoir there is a maximumum of 4 DF pstates supported, could be less
|
||||
* depending on DDR speed and fused maximum fclk.
|
||||
*/
|
||||
if (!debug->disable_pplib_wm_range) {
|
||||
struct pp_smu_wm_range_sets ranges = {0};
|
||||
|
||||
build_watermark_ranges(clk_mgr->base.bw_params, &ranges);
|
||||
|
||||
/* Notify PP Lib/SMU which Watermarks to use for which clock ranges */
|
||||
if (pp_smu && pp_smu->rn_funcs.set_wm_ranges)
|
||||
pp_smu->rn_funcs.set_wm_ranges(&pp_smu->rn_funcs.pp_smu, &ranges);
|
||||
}
|
||||
|
||||
/* enable powerfeatures when displaycount goes to 0 */
|
||||
if (!debug->disable_48mhz_pwrdwn)
|
||||
rn_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(clk_mgr);
|
||||
}
|
||||
|
39
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.h
Normal file
39
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2018 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __RN_CLK_MGR_H__
|
||||
#define __RN_CLK_MGR_H__
|
||||
|
||||
struct rn_clk_registers {
|
||||
uint32_t CLK1_CLK0_CURRENT_CNT; /* DPREFCLK */
|
||||
};
|
||||
|
||||
|
||||
void rn_clk_mgr_construct(struct dc_context *ctx,
|
||||
struct clk_mgr_internal *clk_mgr,
|
||||
struct pp_smu_funcs *pp_smu,
|
||||
struct dccg *dccg);
|
||||
|
||||
#endif //__RN_CLK_MGR_H__
|
@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright 2012-16 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#include "core_types.h"
|
||||
#include "clk_mgr_internal.h"
|
||||
#include "reg_helper.h"
|
||||
|
||||
#include "renoir_ip_offset.h"
|
||||
|
||||
#include "mp/mp_12_0_0_offset.h"
|
||||
#include "mp/mp_12_0_0_sh_mask.h"
|
||||
|
||||
#define REG(reg_name) \
|
||||
(MP1_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name)
|
||||
|
||||
#define FN(reg_name, field) \
|
||||
FD(reg_name##__##field)
|
||||
|
||||
#define VBIOSSMC_MSG_TestMessage 0x1
|
||||
#define VBIOSSMC_MSG_GetSmuVersion 0x2
|
||||
#define VBIOSSMC_MSG_PowerUpGfx 0x3
|
||||
#define VBIOSSMC_MSG_SetDispclkFreq 0x4
|
||||
#define VBIOSSMC_MSG_SetDprefclkFreq 0x5
|
||||
#define VBIOSSMC_MSG_PowerDownGfx 0x6
|
||||
#define VBIOSSMC_MSG_SetDppclkFreq 0x7
|
||||
#define VBIOSSMC_MSG_SetHardMinDcfclkByFreq 0x8
|
||||
#define VBIOSSMC_MSG_SetMinDeepSleepDcfclk 0x9
|
||||
#define VBIOSSMC_MSG_SetPhyclkVoltageByFreq 0xA
|
||||
#define VBIOSSMC_MSG_GetFclkFrequency 0xB
|
||||
#define VBIOSSMC_MSG_SetDisplayCount 0xC
|
||||
#define VBIOSSMC_MSG_EnableTmdp48MHzRefclkPwrDown 0xD
|
||||
#define VBIOSSMC_MSG_UpdatePmeRestore 0xE
|
||||
|
||||
int rn_vbios_smu_send_msg_with_param(struct clk_mgr_internal *clk_mgr, unsigned int msg_id, unsigned int param)
|
||||
{
|
||||
/* First clear response register */
|
||||
REG_WRITE(MP1_SMN_C2PMSG_91, 0);
|
||||
|
||||
/* Set the parameter register for the SMU message, unit is Mhz */
|
||||
REG_WRITE(MP1_SMN_C2PMSG_83, param);
|
||||
|
||||
/* Trigger the message transaction by writing the message ID */
|
||||
REG_WRITE(MP1_SMN_C2PMSG_67, msg_id);
|
||||
|
||||
REG_WAIT(MP1_SMN_C2PMSG_91, CONTENT, 1, 10, 200000);
|
||||
|
||||
/* Actual dispclk set is returned in the parameter register */
|
||||
return REG_READ(MP1_SMN_C2PMSG_83);
|
||||
}
|
||||
|
||||
int rn_vbios_smu_get_smu_version(struct clk_mgr_internal *clk_mgr)
|
||||
{
|
||||
return rn_vbios_smu_send_msg_with_param(
|
||||
clk_mgr,
|
||||
VBIOSSMC_MSG_GetSmuVersion,
|
||||
0);
|
||||
}
|
||||
|
||||
|
||||
int rn_vbios_smu_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_dispclk_khz)
|
||||
{
|
||||
int actual_dispclk_set_mhz = -1;
|
||||
struct dc *core_dc = clk_mgr->base.ctx->dc;
|
||||
struct dmcu *dmcu = core_dc->res_pool->dmcu;
|
||||
uint32_t clk = requested_dispclk_khz / 1000;
|
||||
|
||||
if (clk <= 100)
|
||||
clk = 101;
|
||||
|
||||
/* Unit of SMU msg parameter is Mhz */
|
||||
actual_dispclk_set_mhz = rn_vbios_smu_send_msg_with_param(
|
||||
clk_mgr,
|
||||
VBIOSSMC_MSG_SetDispclkFreq,
|
||||
clk);
|
||||
|
||||
if (!IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment)) {
|
||||
if (dmcu && dmcu->funcs->is_dmcu_initialized(dmcu)) {
|
||||
if (clk_mgr->dfs_bypass_disp_clk != actual_dispclk_set_mhz)
|
||||
dmcu->funcs->set_psr_wait_loop(dmcu,
|
||||
actual_dispclk_set_mhz / 7);
|
||||
}
|
||||
}
|
||||
|
||||
return actual_dispclk_set_mhz * 1000;
|
||||
}
|
||||
|
||||
int rn_vbios_smu_set_dprefclk(struct clk_mgr_internal *clk_mgr)
|
||||
{
|
||||
int actual_dprefclk_set_mhz = -1;
|
||||
|
||||
actual_dprefclk_set_mhz = rn_vbios_smu_send_msg_with_param(
|
||||
clk_mgr,
|
||||
VBIOSSMC_MSG_SetDprefclkFreq,
|
||||
clk_mgr->base.dprefclk_khz / 1000);
|
||||
|
||||
/* TODO: add code for programing DP DTO, currently this is down by command table */
|
||||
|
||||
return actual_dprefclk_set_mhz * 1000;
|
||||
}
|
||||
|
||||
int rn_vbios_smu_set_hard_min_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_dcfclk_khz)
|
||||
{
|
||||
int actual_dcfclk_set_mhz = -1;
|
||||
|
||||
if (clk_mgr->smu_ver < 0xFFFFFFFF)
|
||||
return actual_dcfclk_set_mhz;
|
||||
|
||||
actual_dcfclk_set_mhz = rn_vbios_smu_send_msg_with_param(
|
||||
clk_mgr,
|
||||
VBIOSSMC_MSG_SetHardMinDcfclkByFreq,
|
||||
requested_dcfclk_khz / 1000);
|
||||
|
||||
return actual_dcfclk_set_mhz * 1000;
|
||||
}
|
||||
|
||||
int rn_vbios_smu_set_min_deep_sleep_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_min_ds_dcfclk_khz)
|
||||
{
|
||||
int actual_min_ds_dcfclk_mhz = -1;
|
||||
|
||||
if (clk_mgr->smu_ver < 0xFFFFFFFF)
|
||||
return actual_min_ds_dcfclk_mhz;
|
||||
|
||||
actual_min_ds_dcfclk_mhz = rn_vbios_smu_send_msg_with_param(
|
||||
clk_mgr,
|
||||
VBIOSSMC_MSG_SetMinDeepSleepDcfclk,
|
||||
requested_min_ds_dcfclk_khz / 1000);
|
||||
|
||||
return actual_min_ds_dcfclk_mhz * 1000;
|
||||
}
|
||||
|
||||
void rn_vbios_smu_set_phyclk(struct clk_mgr_internal *clk_mgr, int requested_phyclk_khz)
|
||||
{
|
||||
rn_vbios_smu_send_msg_with_param(
|
||||
clk_mgr,
|
||||
VBIOSSMC_MSG_SetPhyclkVoltageByFreq,
|
||||
requested_phyclk_khz / 1000);
|
||||
}
|
||||
|
||||
int rn_vbios_smu_set_dppclk(struct clk_mgr_internal *clk_mgr, int requested_dpp_khz)
|
||||
{
|
||||
int actual_dppclk_set_mhz = -1;
|
||||
|
||||
uint32_t clk = requested_dpp_khz / 1000;
|
||||
|
||||
if (clk <= 100)
|
||||
clk = 101;
|
||||
|
||||
actual_dppclk_set_mhz = rn_vbios_smu_send_msg_with_param(
|
||||
clk_mgr,
|
||||
VBIOSSMC_MSG_SetDppclkFreq,
|
||||
clk);
|
||||
|
||||
return actual_dppclk_set_mhz * 1000;
|
||||
}
|
||||
|
||||
void rn_vbios_smu_set_display_count(struct clk_mgr_internal *clk_mgr, int display_count)
|
||||
{
|
||||
rn_vbios_smu_send_msg_with_param(
|
||||
clk_mgr,
|
||||
VBIOSSMC_MSG_SetDisplayCount,
|
||||
display_count);
|
||||
}
|
||||
|
||||
void rn_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr)
|
||||
{
|
||||
rn_vbios_smu_send_msg_with_param(
|
||||
clk_mgr,
|
||||
VBIOSSMC_MSG_EnableTmdp48MHzRefclkPwrDown,
|
||||
0);
|
||||
}
|
||||
|
||||
void rn_vbios_smu_enable_pme_wa(struct clk_mgr_internal *clk_mgr)
|
||||
{
|
||||
rn_vbios_smu_send_msg_with_param(
|
||||
clk_mgr,
|
||||
VBIOSSMC_MSG_UpdatePmeRestore,
|
||||
0);
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2018 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DAL_DC_RN_CLK_MGR_VBIOS_SMU_H_
|
||||
#define DAL_DC_RN_CLK_MGR_VBIOS_SMU_H_
|
||||
|
||||
int rn_vbios_smu_get_smu_version(struct clk_mgr_internal *clk_mgr);
|
||||
int rn_vbios_smu_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_dispclk_khz);
|
||||
int rn_vbios_smu_set_dprefclk(struct clk_mgr_internal *clk_mgr);
|
||||
int rn_vbios_smu_set_hard_min_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_dcfclk_khz);
|
||||
int rn_vbios_smu_set_min_deep_sleep_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_min_ds_dcfclk_khz);
|
||||
void rn_vbios_smu_set_phyclk(struct clk_mgr_internal *clk_mgr, int requested_phyclk_khz);
|
||||
int rn_vbios_smu_set_dppclk(struct clk_mgr_internal *clk_mgr, int requested_dpp_khz);
|
||||
void rn_vbios_smu_set_display_count(struct clk_mgr_internal *clk_mgr, int display_count);
|
||||
void rn_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr);
|
||||
void rn_vbios_smu_enable_pme_wa(struct clk_mgr_internal *clk_mgr);
|
||||
|
||||
#endif /* DAL_DC_DCN10_RV1_CLK_MGR_VBIOS_SMU_H_ */
|
@ -689,6 +689,11 @@ static bool construct(struct dc *dc,
|
||||
if (!dc->clk_mgr)
|
||||
goto fail;
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_DCN2_1
|
||||
if (dc->res_pool->funcs->update_bw_bounding_box)
|
||||
dc->res_pool->funcs->update_bw_bounding_box(dc, dc->clk_mgr->bw_params);
|
||||
#endif
|
||||
|
||||
/* Creation of current_state must occur after dc->dml
|
||||
* is initialized in dc_create_resource_pool because
|
||||
* on creation it copies the contents of dc->dml
|
||||
|
@ -52,6 +52,9 @@
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
|
||||
#include "dcn20/dcn20_resource.h"
|
||||
#endif
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
#include "dcn21/dcn21_resource.h"
|
||||
#endif
|
||||
#include "dce120/dce120_resource.h"
|
||||
|
||||
#define DC_LOGGER_INIT(logger)
|
||||
@ -101,6 +104,10 @@ enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id)
|
||||
dc_version = DCN_VERSION_1_0;
|
||||
if (ASICREV_IS_RAVEN2(asic_id.hw_internal_rev))
|
||||
dc_version = DCN_VERSION_1_01;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
if (ASICREV_IS_RENOIR(asic_id.hw_internal_rev))
|
||||
dc_version = DCN_VERSION_2_1;
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
|
||||
@ -168,6 +175,11 @@ struct resource_pool *dc_create_resource_pool(struct dc *dc,
|
||||
res_pool = dcn20_create_resource_pool(init_data, dc);
|
||||
break;
|
||||
#endif
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
case DCN_VERSION_2_1:
|
||||
res_pool = dcn21_create_resource_pool(init_data, dc);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
|
@ -385,6 +385,9 @@ struct dc_debug_options {
|
||||
struct dc_bw_validation_profile bw_val_profile;
|
||||
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
|
||||
bool disable_fec;
|
||||
#endif
|
||||
#ifdef CONFIG_DRM_AMD_DC_DCN2_1
|
||||
bool disable_48mhz_pwrdwn;
|
||||
#endif
|
||||
/* This forces a hard min on the DCFCLK requested to SMU/PP
|
||||
* watermarks are not affected.
|
||||
|
@ -78,6 +78,23 @@
|
||||
SRII(PIXEL_RATE_CNTL, OTG, 5)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
#define CS_COMMON_REG_LIST_DCN2_1(index, pllid) \
|
||||
SRI(PIXCLK_RESYNC_CNTL, PHYPLL, pllid),\
|
||||
SRII(PHASE, DP_DTO, 0),\
|
||||
SRII(PHASE, DP_DTO, 1),\
|
||||
SRII(PHASE, DP_DTO, 2),\
|
||||
SRII(PHASE, DP_DTO, 3),\
|
||||
SRII(MODULO, DP_DTO, 0),\
|
||||
SRII(MODULO, DP_DTO, 1),\
|
||||
SRII(MODULO, DP_DTO, 2),\
|
||||
SRII(MODULO, DP_DTO, 3),\
|
||||
SRII(PIXEL_RATE_CNTL, OTG, 0),\
|
||||
SRII(PIXEL_RATE_CNTL, OTG, 1),\
|
||||
SRII(PIXEL_RATE_CNTL, OTG, 2),\
|
||||
SRII(PIXEL_RATE_CNTL, OTG, 3)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
|
||||
#define CS_COMMON_MASK_SH_LIST_DCN2_0(mask_sh)\
|
||||
CS_SF(DP_DTO0_PHASE, DP_DTO0_PHASE, mask_sh),\
|
||||
|
@ -278,6 +278,59 @@
|
||||
BL_REG_LIST()
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
#define HWSEQ_DCN21_REG_LIST()\
|
||||
HWSEQ_DCN_REG_LIST(), \
|
||||
HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 0), \
|
||||
HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 1), \
|
||||
HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 2), \
|
||||
HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 3), \
|
||||
MMHUB_DCN_REG_LIST(), \
|
||||
SR(MICROSECOND_TIME_BASE_DIV), \
|
||||
SR(MILLISECOND_TIME_BASE_DIV), \
|
||||
SR(DISPCLK_FREQ_CHANGE_CNTL), \
|
||||
SR(RBBMIF_TIMEOUT_DIS), \
|
||||
SR(RBBMIF_TIMEOUT_DIS_2), \
|
||||
SR(DCHUBBUB_CRC_CTRL), \
|
||||
SR(DPP_TOP0_DPP_CRC_CTRL), \
|
||||
SR(DPP_TOP0_DPP_CRC_VAL_B_A), \
|
||||
SR(DPP_TOP0_DPP_CRC_VAL_R_G), \
|
||||
SR(MPC_CRC_CTRL), \
|
||||
SR(MPC_CRC_RESULT_GB), \
|
||||
SR(MPC_CRC_RESULT_C), \
|
||||
SR(MPC_CRC_RESULT_AR), \
|
||||
SR(DOMAIN0_PG_CONFIG), \
|
||||
SR(DOMAIN1_PG_CONFIG), \
|
||||
SR(DOMAIN2_PG_CONFIG), \
|
||||
SR(DOMAIN3_PG_CONFIG), \
|
||||
SR(DOMAIN4_PG_CONFIG), \
|
||||
SR(DOMAIN5_PG_CONFIG), \
|
||||
SR(DOMAIN6_PG_CONFIG), \
|
||||
SR(DOMAIN7_PG_CONFIG), \
|
||||
SR(DOMAIN16_PG_CONFIG), \
|
||||
SR(DOMAIN17_PG_CONFIG), \
|
||||
SR(DOMAIN18_PG_CONFIG), \
|
||||
SR(DOMAIN0_PG_STATUS), \
|
||||
SR(DOMAIN1_PG_STATUS), \
|
||||
SR(DOMAIN2_PG_STATUS), \
|
||||
SR(DOMAIN3_PG_STATUS), \
|
||||
SR(DOMAIN4_PG_STATUS), \
|
||||
SR(DOMAIN5_PG_STATUS), \
|
||||
SR(DOMAIN6_PG_STATUS), \
|
||||
SR(DOMAIN7_PG_STATUS), \
|
||||
SR(DOMAIN16_PG_STATUS), \
|
||||
SR(DOMAIN17_PG_STATUS), \
|
||||
SR(DOMAIN18_PG_STATUS), \
|
||||
SR(D1VGA_CONTROL), \
|
||||
SR(D2VGA_CONTROL), \
|
||||
SR(D3VGA_CONTROL), \
|
||||
SR(D4VGA_CONTROL), \
|
||||
SR(D5VGA_CONTROL), \
|
||||
SR(D6VGA_CONTROL), \
|
||||
SR(DC_IP_REQUEST_CNTL), \
|
||||
BL_REG_LIST()
|
||||
#endif
|
||||
|
||||
struct dce_hwseq_registers {
|
||||
|
||||
/* Backlight registers */
|
||||
@ -586,6 +639,50 @@ struct dce_hwseq_registers {
|
||||
HWSEQ_LVTMA_MASK_SH_LIST(mask_sh)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
#define HWSEQ_DCN21_MASK_SH_LIST(mask_sh)\
|
||||
HWSEQ_DCN_MASK_SH_LIST(mask_sh), \
|
||||
HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \
|
||||
HWS_SF(, MMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32, PAGE_DIRECTORY_ENTRY_HI32, mask_sh),\
|
||||
HWS_SF(, MMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32, PAGE_DIRECTORY_ENTRY_LO32, mask_sh),\
|
||||
HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, mask_sh), \
|
||||
HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_GATE, mask_sh), \
|
||||
HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, mask_sh), \
|
||||
HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_GATE, mask_sh), \
|
||||
HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, mask_sh), \
|
||||
HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_GATE, mask_sh), \
|
||||
HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, mask_sh), \
|
||||
HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_GATE, mask_sh), \
|
||||
HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, mask_sh), \
|
||||
HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_GATE, mask_sh), \
|
||||
HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, mask_sh), \
|
||||
HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_GATE, mask_sh), \
|
||||
HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, mask_sh), \
|
||||
HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_GATE, mask_sh), \
|
||||
HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, mask_sh), \
|
||||
HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_GATE, mask_sh), \
|
||||
HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN16_POWER_FORCEON, mask_sh), \
|
||||
HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN16_POWER_GATE, mask_sh), \
|
||||
HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN17_POWER_FORCEON, mask_sh), \
|
||||
HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN17_POWER_GATE, mask_sh), \
|
||||
HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN18_POWER_FORCEON, mask_sh), \
|
||||
HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN18_POWER_GATE, mask_sh), \
|
||||
HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, mask_sh), \
|
||||
HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN1_PGFSM_PWR_STATUS, mask_sh), \
|
||||
HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN2_PGFSM_PWR_STATUS, mask_sh), \
|
||||
HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN3_PGFSM_PWR_STATUS, mask_sh), \
|
||||
HWS_SF(, DOMAIN4_PG_STATUS, DOMAIN4_PGFSM_PWR_STATUS, mask_sh), \
|
||||
HWS_SF(, DOMAIN5_PG_STATUS, DOMAIN5_PGFSM_PWR_STATUS, mask_sh), \
|
||||
HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \
|
||||
HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \
|
||||
HWS_SF(, DOMAIN16_PG_STATUS, DOMAIN16_PGFSM_PWR_STATUS, mask_sh), \
|
||||
HWS_SF(, DOMAIN17_PG_STATUS, DOMAIN17_PGFSM_PWR_STATUS, mask_sh), \
|
||||
HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN18_PGFSM_PWR_STATUS, mask_sh), \
|
||||
HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \
|
||||
HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \
|
||||
HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh)
|
||||
#endif
|
||||
|
||||
#define HWSEQ_REG_FIELD_LIST(type) \
|
||||
type DCFE_CLOCK_ENABLE; \
|
||||
type DCFEV_CLOCK_ENABLE; \
|
||||
|
@ -121,6 +121,26 @@ struct dcn_hubbub_registers {
|
||||
uint32_t DCN_VM_AGP_BASE;
|
||||
uint32_t DCN_VM_PROTECTION_FAULT_DEFAULT_ADDR_MSB;
|
||||
uint32_t DCN_VM_PROTECTION_FAULT_DEFAULT_ADDR_LSB;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
uint32_t DCHUBBUB_ARB_FRAC_URG_BW_NOM_A;
|
||||
uint32_t DCHUBBUB_ARB_FRAC_URG_BW_NOM_B;
|
||||
uint32_t DCHUBBUB_ARB_FRAC_URG_BW_NOM_C;
|
||||
uint32_t DCHUBBUB_ARB_FRAC_URG_BW_NOM_D;
|
||||
uint32_t DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A;
|
||||
uint32_t DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B;
|
||||
uint32_t DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C;
|
||||
uint32_t DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D;
|
||||
uint32_t DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A;
|
||||
uint32_t DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B;
|
||||
uint32_t DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C;
|
||||
uint32_t DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D;
|
||||
uint32_t DCHUBBUB_ARB_HOSTVM_CNTL;
|
||||
uint32_t DCHVM_CTRL0;
|
||||
uint32_t DCHVM_MEM_CTRL;
|
||||
uint32_t DCHVM_CLK_CTRL;
|
||||
uint32_t DCHVM_RIOMMU_CTRL0;
|
||||
uint32_t DCHVM_RIOMMU_STAT0;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* set field name */
|
||||
@ -212,15 +232,68 @@ struct dcn_hubbub_registers {
|
||||
type DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C;\
|
||||
type DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
#define HUBBUB_HVM_REG_FIELD_LIST(type) \
|
||||
type DCHUBBUB_ARB_MIN_REQ_OUTSTAND_COMMIT_THRESHOLD;\
|
||||
type DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_A;\
|
||||
type DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_B;\
|
||||
type DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_C;\
|
||||
type DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_D;\
|
||||
type DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_A;\
|
||||
type DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_B;\
|
||||
type DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_C;\
|
||||
type DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_D;\
|
||||
type DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_A;\
|
||||
type DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_B;\
|
||||
type DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_C;\
|
||||
type DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_D;\
|
||||
type DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A;\
|
||||
type DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B;\
|
||||
type DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C;\
|
||||
type DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D;\
|
||||
type DCHUBBUB_ARB_FRAC_URG_BW_NOM_A;\
|
||||
type DCHUBBUB_ARB_FRAC_URG_BW_NOM_B;\
|
||||
type DCHUBBUB_ARB_FRAC_URG_BW_NOM_C;\
|
||||
type DCHUBBUB_ARB_FRAC_URG_BW_NOM_D;\
|
||||
type DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A;\
|
||||
type DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B;\
|
||||
type DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C;\
|
||||
type DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D;\
|
||||
type DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A;\
|
||||
type DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B;\
|
||||
type DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C;\
|
||||
type DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D;\
|
||||
type DCHUBBUB_ARB_MAX_QOS_COMMIT_THRESHOLD;\
|
||||
type HOSTVM_INIT_REQ; \
|
||||
type HVM_GPUVMRET_PWR_REQ_DIS; \
|
||||
type HVM_GPUVMRET_FORCE_REQ; \
|
||||
type HVM_GPUVMRET_POWER_STATUS; \
|
||||
type HVM_DISPCLK_R_GATE_DIS; \
|
||||
type HVM_DISPCLK_G_GATE_DIS; \
|
||||
type HVM_DCFCLK_R_GATE_DIS; \
|
||||
type HVM_DCFCLK_G_GATE_DIS; \
|
||||
type TR_REQ_REQCLKREQ_MODE; \
|
||||
type TW_RSP_COMPCLKREQ_MODE; \
|
||||
type HOSTVM_PREFETCH_REQ; \
|
||||
type HOSTVM_POWERSTATUS; \
|
||||
type RIOMMU_ACTIVE; \
|
||||
type HOSTVM_PREFETCH_DONE
|
||||
#endif
|
||||
|
||||
struct dcn_hubbub_shift {
|
||||
DCN_HUBBUB_REG_FIELD_LIST(uint8_t);
|
||||
HUBBUB_STUTTER_REG_FIELD_LIST(uint8_t);
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
HUBBUB_HVM_REG_FIELD_LIST(uint8_t);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct dcn_hubbub_mask {
|
||||
DCN_HUBBUB_REG_FIELD_LIST(uint32_t);
|
||||
HUBBUB_STUTTER_REG_FIELD_LIST(uint32_t);
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
HUBBUB_HVM_REG_FIELD_LIST(uint32_t);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct dc;
|
||||
|
@ -29,6 +29,16 @@
|
||||
#include "dcn10/dcn10_hubbub.h"
|
||||
#include "dcn20_vmid.h"
|
||||
|
||||
#define HUBBUB_REG_LIST_DCN20_COMMON()\
|
||||
HUBBUB_REG_LIST_DCN_COMMON(), \
|
||||
SR(DCHUBBUB_CRC_CTRL), \
|
||||
SR(DCN_VM_FB_LOCATION_BASE),\
|
||||
SR(DCN_VM_FB_LOCATION_TOP),\
|
||||
SR(DCN_VM_FB_OFFSET),\
|
||||
SR(DCN_VM_AGP_BOT),\
|
||||
SR(DCN_VM_AGP_TOP),\
|
||||
SR(DCN_VM_AGP_BASE)
|
||||
|
||||
#define TO_DCN20_HUBBUB(hubbub)\
|
||||
container_of(hubbub, struct dcn20_hubbub, base)
|
||||
|
||||
|
@ -148,6 +148,17 @@
|
||||
uint32_t VMID_SETTINGS_0
|
||||
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
#define DCN21_HUBP_REG_COMMON_VARIABLE_LIST \
|
||||
DCN2_HUBP_REG_COMMON_VARIABLE_LIST; \
|
||||
uint32_t FLIP_PARAMETERS_3;\
|
||||
uint32_t FLIP_PARAMETERS_4;\
|
||||
uint32_t FLIP_PARAMETERS_5;\
|
||||
uint32_t FLIP_PARAMETERS_6;\
|
||||
uint32_t VBLANK_PARAMETERS_5;\
|
||||
uint32_t VBLANK_PARAMETERS_6
|
||||
#endif
|
||||
|
||||
#define DCN2_HUBP_REG_FIELD_VARIABLE_LIST(type) \
|
||||
DCN_HUBP_REG_FIELD_BASE_LIST(type); \
|
||||
type DMDATA_ADDRESS_HIGH;\
|
||||
@ -173,17 +184,41 @@
|
||||
type SURFACE_TRIPLE_BUFFER_ENABLE;\
|
||||
type VMID
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_DCN2_1
|
||||
#define DCN21_HUBP_REG_FIELD_VARIABLE_LIST(type) \
|
||||
DCN2_HUBP_REG_FIELD_VARIABLE_LIST(type);\
|
||||
type REFCYC_PER_VM_GROUP_FLIP;\
|
||||
type REFCYC_PER_VM_REQ_FLIP;\
|
||||
type REFCYC_PER_VM_GROUP_VBLANK;\
|
||||
type REFCYC_PER_VM_REQ_VBLANK;\
|
||||
type REFCYC_PER_PTE_GROUP_FLIP_C; \
|
||||
type REFCYC_PER_META_CHUNK_FLIP_C; \
|
||||
type VM_GROUP_SIZE
|
||||
#endif
|
||||
|
||||
|
||||
struct dcn_hubp2_registers {
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
DCN21_HUBP_REG_COMMON_VARIABLE_LIST;
|
||||
#else
|
||||
DCN2_HUBP_REG_COMMON_VARIABLE_LIST;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct dcn_hubp2_shift {
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
DCN21_HUBP_REG_FIELD_VARIABLE_LIST(uint8_t);
|
||||
#else
|
||||
DCN2_HUBP_REG_FIELD_VARIABLE_LIST(uint8_t);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct dcn_hubp2_mask {
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
DCN21_HUBP_REG_FIELD_VARIABLE_LIST(uint32_t);
|
||||
#else
|
||||
DCN2_HUBP_REG_FIELD_VARIABLE_LIST(uint32_t);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct dcn20_hubp {
|
||||
|
@ -2124,7 +2124,11 @@ void dcn20_hw_sequencer_construct(struct dc *dc)
|
||||
dc->hwss.enable_power_gating_plane = dcn20_enable_power_gating_plane;
|
||||
dc->hwss.dpp_pg_control = dcn20_dpp_pg_control;
|
||||
dc->hwss.hubp_pg_control = dcn20_hubp_pg_control;
|
||||
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
|
||||
dc->hwss.dsc_pg_control = dcn20_dsc_pg_control;
|
||||
#else
|
||||
dc->hwss.dsc_pg_control = NULL;
|
||||
#endif
|
||||
dc->hwss.disable_vga = dcn20_disable_vga;
|
||||
|
||||
if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
|
||||
|
10
drivers/gpu/drm/amd/display/dc/dcn21/Makefile
Normal file
10
drivers/gpu/drm/amd/display/dc/dcn21/Makefile
Normal file
@ -0,0 +1,10 @@
|
||||
#
|
||||
# Makefile for DCN21.
|
||||
|
||||
DCN21 = dcn21_hubp.o dcn21_hubbub.o dcn21_resource.o
|
||||
|
||||
CFLAGS_dcn21_resource.o := -mhard-float -msse -mpreferred-stack-boundary=4
|
||||
|
||||
AMD_DAL_DCN21 = $(addprefix $(AMDDALPATH)/dc/dcn21/,$(DCN21))
|
||||
|
||||
AMD_DISPLAY_FILES += $(AMD_DAL_DCN21)
|
595
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubbub.c
Normal file
595
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubbub.c
Normal file
@ -0,0 +1,595 @@
|
||||
/*
|
||||
* Copyright 2018 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
#include "dm_services.h"
|
||||
#include "dcn20/dcn20_hubbub.h"
|
||||
#include "dcn21_hubbub.h"
|
||||
#include "reg_helper.h"
|
||||
|
||||
#define REG(reg)\
|
||||
hubbub1->regs->reg
|
||||
#define DC_LOGGER \
|
||||
hubbub1->base.ctx->logger
|
||||
#define CTX \
|
||||
hubbub1->base.ctx
|
||||
|
||||
#undef FN
|
||||
#define FN(reg_name, field_name) \
|
||||
hubbub1->shifts->field_name, hubbub1->masks->field_name
|
||||
|
||||
#define REG(reg)\
|
||||
hubbub1->regs->reg
|
||||
|
||||
#define CTX \
|
||||
hubbub1->base.ctx
|
||||
|
||||
#undef FN
|
||||
#define FN(reg_name, field_name) \
|
||||
hubbub1->shifts->field_name, hubbub1->masks->field_name
|
||||
|
||||
#ifdef NUM_VMID
|
||||
#undef NUM_VMID
|
||||
#endif
|
||||
#define NUM_VMID 1
|
||||
|
||||
static uint32_t convert_and_clamp(
|
||||
uint32_t wm_ns,
|
||||
uint32_t refclk_mhz,
|
||||
uint32_t clamp_value)
|
||||
{
|
||||
uint32_t ret_val = 0;
|
||||
ret_val = wm_ns * refclk_mhz;
|
||||
ret_val /= 1000;
|
||||
|
||||
if (ret_val > clamp_value)
|
||||
ret_val = clamp_value;
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
void dcn21_dchvm_init(struct hubbub *hubbub)
|
||||
{
|
||||
struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub);
|
||||
|
||||
//Init DCHVM block
|
||||
REG_UPDATE(DCHVM_CTRL0, HOSTVM_INIT_REQ, 1);
|
||||
|
||||
//Poll until RIOMMU_ACTIVE = 1
|
||||
//TODO: Figure out interval us and retry count
|
||||
REG_WAIT(DCHVM_RIOMMU_STAT0, RIOMMU_ACTIVE, 1, 5, 100);
|
||||
|
||||
//Reflect the power status of DCHUBBUB
|
||||
REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_POWERSTATUS, 1);
|
||||
|
||||
//Start rIOMMU prefetching
|
||||
REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_PREFETCH_REQ, 1);
|
||||
|
||||
// Enable dynamic clock gating
|
||||
REG_UPDATE_4(DCHVM_CLK_CTRL,
|
||||
HVM_DISPCLK_R_GATE_DIS, 0,
|
||||
HVM_DISPCLK_G_GATE_DIS, 0,
|
||||
HVM_DCFCLK_R_GATE_DIS, 0,
|
||||
HVM_DCFCLK_G_GATE_DIS, 0);
|
||||
|
||||
//Poll until HOSTVM_PREFETCH_DONE = 1
|
||||
//TODO: Figure out interval us and retry count
|
||||
REG_WAIT(DCHVM_RIOMMU_STAT0, HOSTVM_PREFETCH_DONE, 1, 5, 100);
|
||||
}
|
||||
|
||||
static int hubbub21_init_dchub(struct hubbub *hubbub,
|
||||
struct dcn_hubbub_phys_addr_config *pa_config)
|
||||
{
|
||||
struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub);
|
||||
|
||||
REG_SET(DCN_VM_FB_LOCATION_BASE, 0,
|
||||
FB_BASE, pa_config->system_aperture.fb_base);
|
||||
REG_SET(DCN_VM_FB_LOCATION_TOP, 0,
|
||||
FB_TOP, pa_config->system_aperture.fb_top);
|
||||
REG_SET(DCN_VM_FB_OFFSET, 0,
|
||||
FB_OFFSET, pa_config->system_aperture.fb_offset);
|
||||
REG_SET(DCN_VM_AGP_BOT, 0,
|
||||
AGP_BOT, pa_config->system_aperture.agp_bot);
|
||||
REG_SET(DCN_VM_AGP_TOP, 0,
|
||||
AGP_TOP, pa_config->system_aperture.agp_top);
|
||||
REG_SET(DCN_VM_AGP_BASE, 0,
|
||||
AGP_BASE, pa_config->system_aperture.agp_base);
|
||||
|
||||
dcn21_dchvm_init(hubbub);
|
||||
|
||||
return NUM_VMID;
|
||||
}
|
||||
|
||||
static void hubbub21_program_urgent_watermarks(
|
||||
struct hubbub *hubbub,
|
||||
struct dcn_watermark_set *watermarks,
|
||||
unsigned int refclk_mhz,
|
||||
bool safe_to_lower)
|
||||
{
|
||||
struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub);
|
||||
uint32_t prog_wm_value;
|
||||
|
||||
/* Repeat for water mark set A, B, C and D. */
|
||||
/* clock state A */
|
||||
if (safe_to_lower || watermarks->a.urgent_ns > hubbub1->watermarks.a.urgent_ns) {
|
||||
hubbub1->watermarks.a.urgent_ns = watermarks->a.urgent_ns;
|
||||
prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns,
|
||||
refclk_mhz, 0x1fffff);
|
||||
REG_SET_2(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, 0,
|
||||
DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value,
|
||||
DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_A, prog_wm_value);
|
||||
|
||||
DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_A calculated =%d\n"
|
||||
"HW register value = 0x%x\n",
|
||||
watermarks->a.urgent_ns, prog_wm_value);
|
||||
}
|
||||
|
||||
/* determine the transfer time for a quantity of data for a particular requestor.*/
|
||||
if (safe_to_lower || watermarks->a.frac_urg_bw_flip
|
||||
> hubbub1->watermarks.a.frac_urg_bw_flip) {
|
||||
hubbub1->watermarks.a.frac_urg_bw_flip = watermarks->a.frac_urg_bw_flip;
|
||||
|
||||
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, 0,
|
||||
DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, watermarks->a.frac_urg_bw_flip);
|
||||
}
|
||||
|
||||
if (safe_to_lower || watermarks->a.frac_urg_bw_nom
|
||||
> hubbub1->watermarks.a.frac_urg_bw_nom) {
|
||||
hubbub1->watermarks.a.frac_urg_bw_nom = watermarks->a.frac_urg_bw_nom;
|
||||
|
||||
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, 0,
|
||||
DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, watermarks->a.frac_urg_bw_nom);
|
||||
}
|
||||
|
||||
/* clock state B */
|
||||
if (safe_to_lower || watermarks->b.urgent_ns > hubbub1->watermarks.b.urgent_ns) {
|
||||
hubbub1->watermarks.b.urgent_ns = watermarks->b.urgent_ns;
|
||||
prog_wm_value = convert_and_clamp(watermarks->b.urgent_ns,
|
||||
refclk_mhz, 0x1fffff);
|
||||
REG_SET_2(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, 0,
|
||||
DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value,
|
||||
DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_B, prog_wm_value);
|
||||
|
||||
DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_B calculated =%d\n"
|
||||
"HW register value = 0x%x\n",
|
||||
watermarks->b.urgent_ns, prog_wm_value);
|
||||
}
|
||||
|
||||
/* determine the transfer time for a quantity of data for a particular requestor.*/
|
||||
if (safe_to_lower || watermarks->a.frac_urg_bw_flip
|
||||
> hubbub1->watermarks.a.frac_urg_bw_flip) {
|
||||
hubbub1->watermarks.a.frac_urg_bw_flip = watermarks->a.frac_urg_bw_flip;
|
||||
|
||||
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, 0,
|
||||
DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, watermarks->a.frac_urg_bw_flip);
|
||||
}
|
||||
|
||||
if (safe_to_lower || watermarks->a.frac_urg_bw_nom
|
||||
> hubbub1->watermarks.a.frac_urg_bw_nom) {
|
||||
hubbub1->watermarks.a.frac_urg_bw_nom = watermarks->a.frac_urg_bw_nom;
|
||||
|
||||
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, 0,
|
||||
DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, watermarks->a.frac_urg_bw_nom);
|
||||
}
|
||||
|
||||
/* clock state C */
|
||||
if (safe_to_lower || watermarks->c.urgent_ns > hubbub1->watermarks.c.urgent_ns) {
|
||||
hubbub1->watermarks.c.urgent_ns = watermarks->c.urgent_ns;
|
||||
prog_wm_value = convert_and_clamp(watermarks->c.urgent_ns,
|
||||
refclk_mhz, 0x1fffff);
|
||||
REG_SET_2(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, 0,
|
||||
DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value,
|
||||
DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_C, prog_wm_value);
|
||||
|
||||
DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_C calculated =%d\n"
|
||||
"HW register value = 0x%x\n",
|
||||
watermarks->c.urgent_ns, prog_wm_value);
|
||||
}
|
||||
|
||||
/* determine the transfer time for a quantity of data for a particular requestor.*/
|
||||
if (safe_to_lower || watermarks->a.frac_urg_bw_flip
|
||||
> hubbub1->watermarks.a.frac_urg_bw_flip) {
|
||||
hubbub1->watermarks.a.frac_urg_bw_flip = watermarks->a.frac_urg_bw_flip;
|
||||
|
||||
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, 0,
|
||||
DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, watermarks->a.frac_urg_bw_flip);
|
||||
}
|
||||
|
||||
if (safe_to_lower || watermarks->a.frac_urg_bw_nom
|
||||
> hubbub1->watermarks.a.frac_urg_bw_nom) {
|
||||
hubbub1->watermarks.a.frac_urg_bw_nom = watermarks->a.frac_urg_bw_nom;
|
||||
|
||||
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, 0,
|
||||
DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, watermarks->a.frac_urg_bw_nom);
|
||||
}
|
||||
|
||||
/* clock state D */
|
||||
if (safe_to_lower || watermarks->d.urgent_ns > hubbub1->watermarks.d.urgent_ns) {
|
||||
hubbub1->watermarks.d.urgent_ns = watermarks->d.urgent_ns;
|
||||
prog_wm_value = convert_and_clamp(watermarks->d.urgent_ns,
|
||||
refclk_mhz, 0x1fffff);
|
||||
REG_SET_2(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, 0,
|
||||
DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value,
|
||||
DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_D, prog_wm_value);
|
||||
|
||||
DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_D calculated =%d\n"
|
||||
"HW register value = 0x%x\n",
|
||||
watermarks->d.urgent_ns, prog_wm_value);
|
||||
}
|
||||
|
||||
/* determine the transfer time for a quantity of data for a particular requestor.*/
|
||||
if (safe_to_lower || watermarks->a.frac_urg_bw_flip
|
||||
> hubbub1->watermarks.a.frac_urg_bw_flip) {
|
||||
hubbub1->watermarks.a.frac_urg_bw_flip = watermarks->a.frac_urg_bw_flip;
|
||||
|
||||
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, 0,
|
||||
DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, watermarks->a.frac_urg_bw_flip);
|
||||
}
|
||||
|
||||
if (safe_to_lower || watermarks->a.frac_urg_bw_nom
|
||||
> hubbub1->watermarks.a.frac_urg_bw_nom) {
|
||||
hubbub1->watermarks.a.frac_urg_bw_nom = watermarks->a.frac_urg_bw_nom;
|
||||
|
||||
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, 0,
|
||||
DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, watermarks->a.frac_urg_bw_nom);
|
||||
}
|
||||
}
|
||||
|
||||
static void hubbub21_program_stutter_watermarks(
|
||||
struct hubbub *hubbub,
|
||||
struct dcn_watermark_set *watermarks,
|
||||
unsigned int refclk_mhz,
|
||||
bool safe_to_lower)
|
||||
{
|
||||
struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub);
|
||||
uint32_t prog_wm_value;
|
||||
|
||||
/* clock state A */
|
||||
if (safe_to_lower || watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns
|
||||
> hubbub1->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns) {
|
||||
hubbub1->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns =
|
||||
watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns,
|
||||
refclk_mhz, 0x1fffff);
|
||||
REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, 0,
|
||||
DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value,
|
||||
DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n"
|
||||
"HW register value = 0x%x\n",
|
||||
watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
|
||||
}
|
||||
|
||||
if (safe_to_lower || watermarks->a.cstate_pstate.cstate_exit_ns
|
||||
> hubbub1->watermarks.a.cstate_pstate.cstate_exit_ns) {
|
||||
hubbub1->watermarks.a.cstate_pstate.cstate_exit_ns =
|
||||
watermarks->a.cstate_pstate.cstate_exit_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->a.cstate_pstate.cstate_exit_ns,
|
||||
refclk_mhz, 0x1fffff);
|
||||
REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, 0,
|
||||
DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value,
|
||||
DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_A calculated =%d\n"
|
||||
"HW register value = 0x%x\n",
|
||||
watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value);
|
||||
}
|
||||
|
||||
/* clock state B */
|
||||
if (safe_to_lower || watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns
|
||||
> hubbub1->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns) {
|
||||
hubbub1->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns =
|
||||
watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns,
|
||||
refclk_mhz, 0x1fffff);
|
||||
REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, 0,
|
||||
DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value,
|
||||
DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_B calculated =%d\n"
|
||||
"HW register value = 0x%x\n",
|
||||
watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
|
||||
}
|
||||
|
||||
if (safe_to_lower || watermarks->b.cstate_pstate.cstate_exit_ns
|
||||
> hubbub1->watermarks.b.cstate_pstate.cstate_exit_ns) {
|
||||
hubbub1->watermarks.b.cstate_pstate.cstate_exit_ns =
|
||||
watermarks->b.cstate_pstate.cstate_exit_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->b.cstate_pstate.cstate_exit_ns,
|
||||
refclk_mhz, 0x1fffff);
|
||||
REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, 0,
|
||||
DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value,
|
||||
DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_B calculated =%d\n"
|
||||
"HW register value = 0x%x\n",
|
||||
watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value);
|
||||
}
|
||||
|
||||
/* clock state C */
|
||||
if (safe_to_lower || watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns
|
||||
> hubbub1->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns) {
|
||||
hubbub1->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns =
|
||||
watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns,
|
||||
refclk_mhz, 0x1fffff);
|
||||
REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, 0,
|
||||
DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value,
|
||||
DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_C calculated =%d\n"
|
||||
"HW register value = 0x%x\n",
|
||||
watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
|
||||
}
|
||||
|
||||
if (safe_to_lower || watermarks->c.cstate_pstate.cstate_exit_ns
|
||||
> hubbub1->watermarks.c.cstate_pstate.cstate_exit_ns) {
|
||||
hubbub1->watermarks.c.cstate_pstate.cstate_exit_ns =
|
||||
watermarks->c.cstate_pstate.cstate_exit_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->c.cstate_pstate.cstate_exit_ns,
|
||||
refclk_mhz, 0x1fffff);
|
||||
REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, 0,
|
||||
DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value,
|
||||
DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_C calculated =%d\n"
|
||||
"HW register value = 0x%x\n",
|
||||
watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value);
|
||||
}
|
||||
|
||||
/* clock state D */
|
||||
if (safe_to_lower || watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns
|
||||
> hubbub1->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns) {
|
||||
hubbub1->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns =
|
||||
watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns,
|
||||
refclk_mhz, 0x1fffff);
|
||||
REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, 0,
|
||||
DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value,
|
||||
DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_D calculated =%d\n"
|
||||
"HW register value = 0x%x\n",
|
||||
watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
|
||||
}
|
||||
|
||||
if (safe_to_lower || watermarks->d.cstate_pstate.cstate_exit_ns
|
||||
> hubbub1->watermarks.d.cstate_pstate.cstate_exit_ns) {
|
||||
hubbub1->watermarks.d.cstate_pstate.cstate_exit_ns =
|
||||
watermarks->d.cstate_pstate.cstate_exit_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->d.cstate_pstate.cstate_exit_ns,
|
||||
refclk_mhz, 0x1fffff);
|
||||
REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, 0,
|
||||
DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value,
|
||||
DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_D calculated =%d\n"
|
||||
"HW register value = 0x%x\n",
|
||||
watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value);
|
||||
}
|
||||
}
|
||||
|
||||
static void hubbub21_program_pstate_watermarks(
|
||||
struct hubbub *hubbub,
|
||||
struct dcn_watermark_set *watermarks,
|
||||
unsigned int refclk_mhz,
|
||||
bool safe_to_lower)
|
||||
{
|
||||
struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub);
|
||||
uint32_t prog_wm_value;
|
||||
|
||||
/* clock state A */
|
||||
if (safe_to_lower || watermarks->a.cstate_pstate.pstate_change_ns
|
||||
> hubbub1->watermarks.a.cstate_pstate.pstate_change_ns) {
|
||||
hubbub1->watermarks.a.cstate_pstate.pstate_change_ns =
|
||||
watermarks->a.cstate_pstate.pstate_change_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->a.cstate_pstate.pstate_change_ns,
|
||||
refclk_mhz, 0x1fffff);
|
||||
REG_SET_2(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, 0,
|
||||
DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value,
|
||||
DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n"
|
||||
"HW register value = 0x%x\n\n",
|
||||
watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value);
|
||||
}
|
||||
|
||||
/* clock state B */
|
||||
if (safe_to_lower || watermarks->b.cstate_pstate.pstate_change_ns
|
||||
> hubbub1->watermarks.b.cstate_pstate.pstate_change_ns) {
|
||||
hubbub1->watermarks.b.cstate_pstate.pstate_change_ns =
|
||||
watermarks->b.cstate_pstate.pstate_change_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->b.cstate_pstate.pstate_change_ns,
|
||||
refclk_mhz, 0x1fffff);
|
||||
REG_SET_2(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, 0,
|
||||
DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value,
|
||||
DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n"
|
||||
"HW register value = 0x%x\n\n",
|
||||
watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value);
|
||||
}
|
||||
|
||||
/* clock state C */
|
||||
if (safe_to_lower || watermarks->c.cstate_pstate.pstate_change_ns
|
||||
> hubbub1->watermarks.c.cstate_pstate.pstate_change_ns) {
|
||||
hubbub1->watermarks.c.cstate_pstate.pstate_change_ns =
|
||||
watermarks->c.cstate_pstate.pstate_change_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->c.cstate_pstate.pstate_change_ns,
|
||||
refclk_mhz, 0x1fffff);
|
||||
REG_SET_2(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, 0,
|
||||
DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value,
|
||||
DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n"
|
||||
"HW register value = 0x%x\n\n",
|
||||
watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value);
|
||||
}
|
||||
|
||||
/* clock state D */
|
||||
if (safe_to_lower || watermarks->d.cstate_pstate.pstate_change_ns
|
||||
> hubbub1->watermarks.d.cstate_pstate.pstate_change_ns) {
|
||||
hubbub1->watermarks.d.cstate_pstate.pstate_change_ns =
|
||||
watermarks->d.cstate_pstate.pstate_change_ns;
|
||||
prog_wm_value = convert_and_clamp(
|
||||
watermarks->d.cstate_pstate.pstate_change_ns,
|
||||
refclk_mhz, 0x1fffff);
|
||||
REG_SET_2(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, 0,
|
||||
DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value,
|
||||
DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value);
|
||||
DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n"
|
||||
"HW register value = 0x%x\n\n",
|
||||
watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value);
|
||||
}
|
||||
}
|
||||
|
||||
void hubbub21_program_watermarks(
|
||||
struct hubbub *hubbub,
|
||||
struct dcn_watermark_set *watermarks,
|
||||
unsigned int refclk_mhz,
|
||||
bool safe_to_lower)
|
||||
{
|
||||
struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub);
|
||||
|
||||
hubbub21_program_urgent_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower);
|
||||
hubbub21_program_stutter_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower);
|
||||
hubbub21_program_pstate_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower);
|
||||
|
||||
/*
|
||||
* The DCHub arbiter has a mechanism to dynamically rate limit the DCHub request stream to the fabric.
|
||||
* If the memory controller is fully utilized and the DCHub requestors are
|
||||
* well ahead of their amortized schedule, then it is safe to prevent the next winner
|
||||
* from being committed and sent to the fabric.
|
||||
* The utilization of the memory controller is approximated by ensuring that
|
||||
* the number of outstanding requests is greater than a threshold specified
|
||||
* by the ARB_MIN_REQ_OUTSTANDING. To determine that the DCHub requestors are well ahead of the amortized schedule,
|
||||
* the slack of the next winner is compared with the ARB_SAT_LEVEL in DLG RefClk cycles.
|
||||
*
|
||||
* TODO: Revisit request limit after figure out right number. request limit for Renoir isn't decided yet, set maximum value (0x1FF)
|
||||
* to turn off it for now.
|
||||
*/
|
||||
REG_SET(DCHUBBUB_ARB_SAT_LEVEL, 0,
|
||||
DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz);
|
||||
REG_UPDATE_2(DCHUBBUB_ARB_DF_REQ_OUTSTAND,
|
||||
DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 0x1FF,
|
||||
DCHUBBUB_ARB_MIN_REQ_OUTSTAND_COMMIT_THRESHOLD, 0xA);
|
||||
REG_UPDATE(DCHUBBUB_ARB_HOSTVM_CNTL,
|
||||
DCHUBBUB_ARB_MAX_QOS_COMMIT_THRESHOLD, 0xF);
|
||||
|
||||
hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter);
|
||||
}
|
||||
|
||||
void hubbub21_wm_read_state(struct hubbub *hubbub,
|
||||
struct dcn_hubbub_wm *wm)
|
||||
{
|
||||
struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub);
|
||||
struct dcn_hubbub_wm_set *s;
|
||||
|
||||
memset(wm, 0, sizeof(struct dcn_hubbub_wm));
|
||||
|
||||
s = &wm->sets[0];
|
||||
s->wm_set = 0;
|
||||
REG_GET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A,
|
||||
DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, &s->data_urgent);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A,
|
||||
DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, &s->sr_enter);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A,
|
||||
DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, &s->sr_exit);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A,
|
||||
DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, &s->dram_clk_chanage);
|
||||
|
||||
s = &wm->sets[1];
|
||||
s->wm_set = 1;
|
||||
REG_GET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B,
|
||||
DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, &s->data_urgent);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B,
|
||||
DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, &s->sr_enter);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B,
|
||||
DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, &s->sr_exit);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B,
|
||||
DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, &s->dram_clk_chanage);
|
||||
|
||||
s = &wm->sets[2];
|
||||
s->wm_set = 2;
|
||||
REG_GET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C,
|
||||
DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, &s->data_urgent);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C,
|
||||
DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, &s->sr_enter);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C,
|
||||
DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, &s->sr_exit);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C,
|
||||
DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, &s->dram_clk_chanage);
|
||||
|
||||
s = &wm->sets[3];
|
||||
s->wm_set = 3;
|
||||
REG_GET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D,
|
||||
DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, &s->data_urgent);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D,
|
||||
DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, &s->sr_enter);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D,
|
||||
DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, &s->sr_exit);
|
||||
|
||||
REG_GET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D,
|
||||
DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, &s->dram_clk_chanage);
|
||||
}
|
||||
|
||||
|
||||
static const struct hubbub_funcs hubbub21_funcs = {
|
||||
.update_dchub = hubbub2_update_dchub,
|
||||
.init_dchub_sys_ctx = hubbub21_init_dchub,
|
||||
.init_vm_ctx = NULL,
|
||||
.dcc_support_swizzle = hubbub2_dcc_support_swizzle,
|
||||
.dcc_support_pixel_format = hubbub2_dcc_support_pixel_format,
|
||||
.get_dcc_compression_cap = hubbub2_get_dcc_compression_cap,
|
||||
.wm_read_state = hubbub21_wm_read_state,
|
||||
.get_dchub_ref_freq = hubbub2_get_dchub_ref_freq,
|
||||
.program_watermarks = hubbub21_program_watermarks,
|
||||
};
|
||||
|
||||
void hubbub21_construct(struct dcn20_hubbub *hubbub,
|
||||
struct dc_context *ctx,
|
||||
const struct dcn_hubbub_registers *hubbub_regs,
|
||||
const struct dcn_hubbub_shift *hubbub_shift,
|
||||
const struct dcn_hubbub_mask *hubbub_mask)
|
||||
{
|
||||
hubbub->base.ctx = ctx;
|
||||
|
||||
hubbub->base.funcs = &hubbub21_funcs;
|
||||
|
||||
hubbub->regs = hubbub_regs;
|
||||
hubbub->shifts = hubbub_shift;
|
||||
hubbub->masks = hubbub_mask;
|
||||
|
||||
hubbub->debug_test_index_pstate = 0xB;
|
||||
}
|
132
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubbub.h
Normal file
132
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubbub.h
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright 2018 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
#ifndef DAL_DC_DCN21_DCN21_HUBBUB_H_
|
||||
#define DAL_DC_DCN21_DCN21_HUBBUB_H_
|
||||
|
||||
#include "dcn20/dcn20_hubbub.h"
|
||||
|
||||
#define HUBBUB_HVM_REG_LIST() \
|
||||
SR(DCHUBBUB_ARB_FRAC_URG_BW_NOM_A),\
|
||||
SR(DCHUBBUB_ARB_FRAC_URG_BW_NOM_B),\
|
||||
SR(DCHUBBUB_ARB_FRAC_URG_BW_NOM_C),\
|
||||
SR(DCHUBBUB_ARB_FRAC_URG_BW_NOM_D),\
|
||||
SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A),\
|
||||
SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B),\
|
||||
SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C),\
|
||||
SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D),\
|
||||
SR(DCHUBBUB_ARB_HOSTVM_CNTL), \
|
||||
SR(DCHVM_CTRL0), \
|
||||
SR(DCHVM_MEM_CTRL), \
|
||||
SR(DCHVM_CLK_CTRL), \
|
||||
SR(DCHVM_RIOMMU_CTRL0), \
|
||||
SR(DCHVM_RIOMMU_STAT0)
|
||||
|
||||
#define HUBBUB_REG_LIST_DCN21()\
|
||||
HUBBUB_REG_LIST_DCN_COMMON(), \
|
||||
HUBBUB_SR_WATERMARK_REG_LIST(), \
|
||||
HUBBUB_HVM_REG_LIST(), \
|
||||
SR(DCHUBBUB_CRC_CTRL), \
|
||||
SR(DCN_VM_FB_LOCATION_BASE),\
|
||||
SR(DCN_VM_FB_LOCATION_TOP),\
|
||||
SR(DCN_VM_FB_OFFSET),\
|
||||
SR(DCN_VM_AGP_BOT),\
|
||||
SR(DCN_VM_AGP_TOP),\
|
||||
SR(DCN_VM_AGP_BASE)
|
||||
|
||||
#define HUBBUB_MASK_SH_LIST_HVM(mask_sh) \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND_COMMIT_THRESHOLD, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_A, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_B, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_C, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_D, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_A, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_B, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_C, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_D, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_A, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_B, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_C, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_D, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_HOSTVM_CNTL, DCHUBBUB_ARB_MAX_QOS_COMMIT_THRESHOLD, mask_sh), \
|
||||
HUBBUB_SF(DCHVM_CTRL0, HOSTVM_INIT_REQ, mask_sh), \
|
||||
HUBBUB_SF(DCHVM_MEM_CTRL, HVM_GPUVMRET_PWR_REQ_DIS, mask_sh), \
|
||||
HUBBUB_SF(DCHVM_MEM_CTRL, HVM_GPUVMRET_FORCE_REQ, mask_sh), \
|
||||
HUBBUB_SF(DCHVM_MEM_CTRL, HVM_GPUVMRET_POWER_STATUS, mask_sh), \
|
||||
HUBBUB_SF(DCHVM_CLK_CTRL, HVM_DISPCLK_R_GATE_DIS, mask_sh), \
|
||||
HUBBUB_SF(DCHVM_CLK_CTRL, HVM_DISPCLK_G_GATE_DIS, mask_sh), \
|
||||
HUBBUB_SF(DCHVM_CLK_CTRL, HVM_DCFCLK_R_GATE_DIS, mask_sh), \
|
||||
HUBBUB_SF(DCHVM_CLK_CTRL, HVM_DCFCLK_G_GATE_DIS, mask_sh), \
|
||||
HUBBUB_SF(DCHVM_CLK_CTRL, TR_REQ_REQCLKREQ_MODE, mask_sh), \
|
||||
HUBBUB_SF(DCHVM_CLK_CTRL, TW_RSP_COMPCLKREQ_MODE, mask_sh), \
|
||||
HUBBUB_SF(DCHVM_RIOMMU_CTRL0, HOSTVM_PREFETCH_REQ, mask_sh), \
|
||||
HUBBUB_SF(DCHVM_RIOMMU_CTRL0, HOSTVM_POWERSTATUS, mask_sh), \
|
||||
HUBBUB_SF(DCHVM_RIOMMU_STAT0, RIOMMU_ACTIVE, mask_sh), \
|
||||
HUBBUB_SF(DCHVM_RIOMMU_STAT0, HOSTVM_PREFETCH_DONE, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, mask_sh)
|
||||
|
||||
#define HUBBUB_MASK_SH_LIST_DCN21(mask_sh)\
|
||||
HUBBUB_MASK_SH_LIST_HVM(mask_sh),\
|
||||
HUBBUB_MASK_SH_LIST_DCN_COMMON(mask_sh), \
|
||||
HUBBUB_MASK_SH_LIST_STUTTER(mask_sh), \
|
||||
HUBBUB_SF(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \
|
||||
HUBBUB_SF(DCN_VM_FB_LOCATION_BASE, FB_BASE, mask_sh), \
|
||||
HUBBUB_SF(DCN_VM_FB_LOCATION_TOP, FB_TOP, mask_sh), \
|
||||
HUBBUB_SF(DCN_VM_FB_OFFSET, FB_OFFSET, mask_sh), \
|
||||
HUBBUB_SF(DCN_VM_AGP_BOT, AGP_BOT, mask_sh), \
|
||||
HUBBUB_SF(DCN_VM_AGP_TOP, AGP_TOP, mask_sh), \
|
||||
HUBBUB_SF(DCN_VM_AGP_BASE, AGP_BASE, mask_sh)
|
||||
|
||||
void dcn21_dchvm_init(struct hubbub *hubbub);
|
||||
void hubbub21_program_watermarks(
|
||||
struct hubbub *hubbub,
|
||||
struct dcn_watermark_set *watermarks,
|
||||
unsigned int refclk_mhz,
|
||||
bool safe_to_lower);
|
||||
|
||||
void hubbub21_wm_read_state(struct hubbub *hubbub,
|
||||
struct dcn_hubbub_wm *wm);
|
||||
|
||||
void hubbub21_construct(struct dcn20_hubbub *hubbub,
|
||||
struct dc_context *ctx,
|
||||
const struct dcn_hubbub_registers *hubbub_regs,
|
||||
const struct dcn_hubbub_shift *hubbub_shift,
|
||||
const struct dcn_hubbub_mask *hubbub_mask);
|
||||
|
||||
#endif /* DAL_DC_DCN21_DCN21_HUBBUB_H_ */
|
244
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c
Normal file
244
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c
Normal file
@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Copyright 2018 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
#include "dcn21_hubp.h"
|
||||
|
||||
#include "dm_services.h"
|
||||
#include "reg_helper.h"
|
||||
|
||||
#define REG(reg)\
|
||||
hubp21->hubp_regs->reg
|
||||
|
||||
#define CTX \
|
||||
hubp21->base.ctx
|
||||
|
||||
#undef FN
|
||||
#define FN(reg_name, field_name) \
|
||||
hubp21->hubp_shift->field_name, hubp21->hubp_mask->field_name
|
||||
|
||||
/*
|
||||
* In DCN2.1, the non-double buffered version of the following 4 DLG registers are used in RTL.
|
||||
* As a result, if S/W updates any of these registers during a mode change,
|
||||
* the current frame before the mode change will use the new value right away
|
||||
* and can lead to generating incorrect request deadlines and incorrect TTU/QoS behavior.
|
||||
*
|
||||
* REFCYC_PER_VM_GROUP_FLIP[22:0]
|
||||
* REFCYC_PER_VM_GROUP_VBLANK[22:0]
|
||||
* REFCYC_PER_VM_REQ_FLIP[22:0]
|
||||
* REFCYC_PER_VM_REQ_VBLANK[22:0]
|
||||
*
|
||||
* REFCYC_PER_VM_*_FLIP affects the deadline of the VM requests generated
|
||||
* when flipping to a new surface
|
||||
*
|
||||
* REFCYC_PER_VM_*_VBLANK affects the deadline of the VM requests generated
|
||||
* during prefetch period of a frame. The prefetch starts at a pre-determined
|
||||
* number of lines before the display active per frame
|
||||
*
|
||||
* DCN may underflow due to incorrectly programming these registers
|
||||
* during VM stage of prefetch/iflip. First lines of display active
|
||||
* or a sub-region of active using a new surface will be corrupted
|
||||
* until the VM data returns at flip/mode change transitions
|
||||
*
|
||||
* Work around:
|
||||
* workaround is always opt to use the more aggressive settings.
|
||||
* On any mode switch, if the new reg values are smaller than the current values,
|
||||
* then update the regs with the new values.
|
||||
*
|
||||
* Link to the ticket: http://ontrack-internal.amd.com/browse/DEDCN21-142
|
||||
*
|
||||
*/
|
||||
void apply_DEDCN21_142_wa_for_hostvm_deadline(
|
||||
struct hubp *hubp,
|
||||
struct _vcs_dpi_display_dlg_regs_st *dlg_attr)
|
||||
{
|
||||
struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp);
|
||||
uint32_t cur_value;
|
||||
|
||||
REG_GET(VBLANK_PARAMETERS_5, REFCYC_PER_VM_GROUP_VBLANK, &cur_value);
|
||||
if (cur_value > dlg_attr->refcyc_per_vm_group_vblank)
|
||||
REG_SET(VBLANK_PARAMETERS_5, 0,
|
||||
REFCYC_PER_VM_GROUP_VBLANK, dlg_attr->refcyc_per_vm_group_vblank);
|
||||
|
||||
REG_GET(VBLANK_PARAMETERS_6,
|
||||
REFCYC_PER_VM_REQ_VBLANK,
|
||||
&cur_value);
|
||||
if (cur_value > dlg_attr->refcyc_per_vm_req_vblank)
|
||||
REG_SET(VBLANK_PARAMETERS_6, 0,
|
||||
REFCYC_PER_VM_REQ_VBLANK, dlg_attr->refcyc_per_vm_req_vblank);
|
||||
|
||||
REG_GET(FLIP_PARAMETERS_3, REFCYC_PER_VM_GROUP_FLIP, &cur_value);
|
||||
if (cur_value > dlg_attr->refcyc_per_vm_group_flip)
|
||||
REG_SET(FLIP_PARAMETERS_3, 0,
|
||||
REFCYC_PER_VM_GROUP_FLIP, dlg_attr->refcyc_per_vm_group_flip);
|
||||
|
||||
REG_GET(FLIP_PARAMETERS_4, REFCYC_PER_VM_REQ_FLIP, &cur_value);
|
||||
if (cur_value > dlg_attr->refcyc_per_vm_req_flip)
|
||||
REG_SET(FLIP_PARAMETERS_4, 0,
|
||||
REFCYC_PER_VM_REQ_FLIP, dlg_attr->refcyc_per_vm_req_flip);
|
||||
|
||||
REG_SET(FLIP_PARAMETERS_5, 0,
|
||||
REFCYC_PER_PTE_GROUP_FLIP_C, dlg_attr->refcyc_per_pte_group_flip_c);
|
||||
REG_SET(FLIP_PARAMETERS_6, 0,
|
||||
REFCYC_PER_META_CHUNK_FLIP_C, dlg_attr->refcyc_per_meta_chunk_flip_c);
|
||||
}
|
||||
|
||||
void hubp21_program_deadline(
|
||||
struct hubp *hubp,
|
||||
struct _vcs_dpi_display_dlg_regs_st *dlg_attr,
|
||||
struct _vcs_dpi_display_ttu_regs_st *ttu_attr)
|
||||
{
|
||||
hubp2_program_deadline(hubp, dlg_attr, ttu_attr);
|
||||
|
||||
apply_DEDCN21_142_wa_for_hostvm_deadline(hubp, dlg_attr);
|
||||
}
|
||||
|
||||
void hubp21_program_requestor(
|
||||
struct hubp *hubp,
|
||||
struct _vcs_dpi_display_rq_regs_st *rq_regs)
|
||||
{
|
||||
struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp);
|
||||
|
||||
REG_UPDATE(HUBPRET_CONTROL,
|
||||
DET_BUF_PLANE1_BASE_ADDRESS, rq_regs->plane1_base_address);
|
||||
REG_SET_4(DCN_EXPANSION_MODE, 0,
|
||||
DRQ_EXPANSION_MODE, rq_regs->drq_expansion_mode,
|
||||
PRQ_EXPANSION_MODE, rq_regs->prq_expansion_mode,
|
||||
MRQ_EXPANSION_MODE, rq_regs->mrq_expansion_mode,
|
||||
CRQ_EXPANSION_MODE, rq_regs->crq_expansion_mode);
|
||||
REG_SET_8(DCHUBP_REQ_SIZE_CONFIG, 0,
|
||||
CHUNK_SIZE, rq_regs->rq_regs_l.chunk_size,
|
||||
MIN_CHUNK_SIZE, rq_regs->rq_regs_l.min_chunk_size,
|
||||
META_CHUNK_SIZE, rq_regs->rq_regs_l.meta_chunk_size,
|
||||
MIN_META_CHUNK_SIZE, rq_regs->rq_regs_l.min_meta_chunk_size,
|
||||
DPTE_GROUP_SIZE, rq_regs->rq_regs_l.dpte_group_size,
|
||||
VM_GROUP_SIZE, rq_regs->rq_regs_l.mpte_group_size,
|
||||
SWATH_HEIGHT, rq_regs->rq_regs_l.swath_height,
|
||||
PTE_ROW_HEIGHT_LINEAR, rq_regs->rq_regs_l.pte_row_height_linear);
|
||||
REG_SET_7(DCHUBP_REQ_SIZE_CONFIG_C, 0,
|
||||
CHUNK_SIZE_C, rq_regs->rq_regs_c.chunk_size,
|
||||
MIN_CHUNK_SIZE_C, rq_regs->rq_regs_c.min_chunk_size,
|
||||
META_CHUNK_SIZE_C, rq_regs->rq_regs_c.meta_chunk_size,
|
||||
MIN_META_CHUNK_SIZE_C, rq_regs->rq_regs_c.min_meta_chunk_size,
|
||||
DPTE_GROUP_SIZE_C, rq_regs->rq_regs_c.dpte_group_size,
|
||||
SWATH_HEIGHT_C, rq_regs->rq_regs_c.swath_height,
|
||||
PTE_ROW_HEIGHT_LINEAR_C, rq_regs->rq_regs_c.pte_row_height_linear);
|
||||
}
|
||||
|
||||
static void hubp21_setup(
|
||||
struct hubp *hubp,
|
||||
struct _vcs_dpi_display_dlg_regs_st *dlg_attr,
|
||||
struct _vcs_dpi_display_ttu_regs_st *ttu_attr,
|
||||
struct _vcs_dpi_display_rq_regs_st *rq_regs,
|
||||
struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest)
|
||||
{
|
||||
/* otg is locked when this func is called. Register are double buffered.
|
||||
* disable the requestors is not needed
|
||||
*/
|
||||
|
||||
hubp2_vready_at_or_After_vsync(hubp, pipe_dest);
|
||||
hubp21_program_requestor(hubp, rq_regs);
|
||||
hubp21_program_deadline(hubp, dlg_attr, ttu_attr);
|
||||
|
||||
}
|
||||
|
||||
void hubp21_set_vm_system_aperture_settings(struct hubp *hubp,
|
||||
struct vm_system_aperture_param *apt)
|
||||
{
|
||||
struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp);
|
||||
|
||||
PHYSICAL_ADDRESS_LOC mc_vm_apt_default;
|
||||
PHYSICAL_ADDRESS_LOC mc_vm_apt_low;
|
||||
PHYSICAL_ADDRESS_LOC mc_vm_apt_high;
|
||||
|
||||
// The format of default addr is 48:12 of the 48 bit addr
|
||||
mc_vm_apt_default.quad_part = apt->sys_default.quad_part >> 12;
|
||||
|
||||
// The format of high/low are 48:18 of the 48 bit addr
|
||||
mc_vm_apt_low.quad_part = apt->sys_low.quad_part >> 18;
|
||||
mc_vm_apt_high.quad_part = apt->sys_high.quad_part >> 18;
|
||||
|
||||
REG_SET(DCN_VM_SYSTEM_APERTURE_LOW_ADDR, 0,
|
||||
MC_VM_SYSTEM_APERTURE_LOW_ADDR, mc_vm_apt_low.quad_part);
|
||||
|
||||
REG_SET(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR, 0,
|
||||
MC_VM_SYSTEM_APERTURE_HIGH_ADDR, mc_vm_apt_high.quad_part);
|
||||
|
||||
REG_SET_2(DCN_VM_MX_L1_TLB_CNTL, 0,
|
||||
ENABLE_L1_TLB, 1,
|
||||
SYSTEM_ACCESS_MODE, 0x3);
|
||||
}
|
||||
|
||||
void hubp21_init(struct hubp *hubp)
|
||||
{
|
||||
// DEDCN21-133: Inconsistent row starting line for flip between DPTE and Meta
|
||||
// This is a chicken bit to enable the ECO fix.
|
||||
|
||||
struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp);
|
||||
//hubp[i].HUBPREQ_DEBUG.HUBPREQ_DEBUG[26] = 1;
|
||||
REG_WRITE(HUBPREQ_DEBUG, 1 << 26);
|
||||
}
|
||||
static struct hubp_funcs dcn21_hubp_funcs = {
|
||||
.hubp_enable_tripleBuffer = hubp2_enable_triplebuffer,
|
||||
.hubp_is_triplebuffer_enabled = hubp2_is_triplebuffer_enabled,
|
||||
.hubp_program_surface_flip_and_addr = hubp2_program_surface_flip_and_addr,
|
||||
.hubp_program_surface_config = hubp2_program_surface_config,
|
||||
.hubp_is_flip_pending = hubp1_is_flip_pending,
|
||||
.hubp_setup = hubp21_setup,
|
||||
.hubp_setup_interdependent = hubp2_setup_interdependent,
|
||||
.hubp_set_vm_system_aperture_settings = hubp21_set_vm_system_aperture_settings,
|
||||
.set_blank = hubp1_set_blank,
|
||||
.dcc_control = hubp1_dcc_control,
|
||||
.mem_program_viewport = min_set_viewport,
|
||||
.set_cursor_attributes = hubp2_cursor_set_attributes,
|
||||
.set_cursor_position = hubp1_cursor_set_position,
|
||||
.hubp_clk_cntl = hubp1_clk_cntl,
|
||||
.hubp_vtg_sel = hubp1_vtg_sel,
|
||||
.dmdata_set_attributes = hubp2_dmdata_set_attributes,
|
||||
.dmdata_load = hubp2_dmdata_load,
|
||||
.dmdata_status_done = hubp2_dmdata_status_done,
|
||||
.hubp_read_state = hubp1_read_state,
|
||||
.hubp_clear_underflow = hubp1_clear_underflow,
|
||||
.hubp_set_flip_control_surface_gsl = hubp2_set_flip_control_surface_gsl,
|
||||
.hubp_init = hubp21_init,
|
||||
};
|
||||
|
||||
bool hubp21_construct(
|
||||
struct dcn21_hubp *hubp21,
|
||||
struct dc_context *ctx,
|
||||
uint32_t inst,
|
||||
const struct dcn_hubp2_registers *hubp_regs,
|
||||
const struct dcn_hubp2_shift *hubp_shift,
|
||||
const struct dcn_hubp2_mask *hubp_mask)
|
||||
{
|
||||
hubp21->base.funcs = &dcn21_hubp_funcs;
|
||||
hubp21->base.ctx = ctx;
|
||||
hubp21->hubp_regs = hubp_regs;
|
||||
hubp21->hubp_shift = hubp_shift;
|
||||
hubp21->hubp_mask = hubp_mask;
|
||||
hubp21->base.inst = inst;
|
||||
hubp21->base.opp_id = OPP_ID_INVALID;
|
||||
hubp21->base.mpcc_id = 0xf;
|
||||
|
||||
return true;
|
||||
}
|
133
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.h
Normal file
133
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.h
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2018 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DAL_DC_DCN21_DCN21_HUBP_H_
|
||||
#define DAL_DC_DCN21_DCN21_HUBP_H_
|
||||
|
||||
#include "../dcn20/dcn20_hubp.h"
|
||||
#include "../dcn10/dcn10_hubp.h"
|
||||
|
||||
#define TO_DCN21_HUBP(hubp)\
|
||||
container_of(hubp, struct dcn21_hubp, base)
|
||||
|
||||
#define HUBP_REG_LIST_DCN21(id)\
|
||||
HUBP_REG_LIST_DCN2_COMMON(id),\
|
||||
SRI(FLIP_PARAMETERS_3, HUBPREQ, id),\
|
||||
SRI(FLIP_PARAMETERS_4, HUBPREQ, id),\
|
||||
SRI(FLIP_PARAMETERS_5, HUBPREQ, id),\
|
||||
SRI(FLIP_PARAMETERS_6, HUBPREQ, id),\
|
||||
SRI(VBLANK_PARAMETERS_5, HUBPREQ, id),\
|
||||
SRI(VBLANK_PARAMETERS_6, HUBPREQ, id)
|
||||
|
||||
#define HUBP_MASK_SH_LIST_DCN21_COMMON(mask_sh)\
|
||||
HUBP_MASK_SH_LIST_DCN_SHARE_COMMON(mask_sh),\
|
||||
HUBP_MASK_SH_LIST_DCN_VM(mask_sh),\
|
||||
HUBP_SF(HUBP0_DCSURF_SURFACE_CONFIG, ROTATION_ANGLE, mask_sh),\
|
||||
HUBP_SF(HUBP0_DCSURF_SURFACE_CONFIG, H_MIRROR_EN, mask_sh),\
|
||||
HUBP_SF(HUBPREQ0_PREFETCH_SETTINGS, DST_Y_PREFETCH, mask_sh),\
|
||||
HUBP_SF(HUBPREQ0_PREFETCH_SETTINGS, VRATIO_PREFETCH, mask_sh),\
|
||||
HUBP_SF(HUBPREQ0_PREFETCH_SETTINGS_C, VRATIO_PREFETCH_C, mask_sh),\
|
||||
HUBP_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_LOW_ADDR, MC_VM_SYSTEM_APERTURE_LOW_ADDR, mask_sh),\
|
||||
HUBP_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR, MC_VM_SYSTEM_APERTURE_HIGH_ADDR, mask_sh),\
|
||||
HUBP_SF(HUBPREQ0_CURSOR_SETTINGS, CURSOR0_DST_Y_OFFSET, mask_sh), \
|
||||
HUBP_SF(HUBPREQ0_CURSOR_SETTINGS, CURSOR0_CHUNK_HDL_ADJUST, mask_sh), \
|
||||
HUBP_SF(CURSOR0_0_CURSOR_SURFACE_ADDRESS_HIGH, CURSOR_SURFACE_ADDRESS_HIGH, mask_sh), \
|
||||
HUBP_SF(CURSOR0_0_CURSOR_SURFACE_ADDRESS, CURSOR_SURFACE_ADDRESS, mask_sh), \
|
||||
HUBP_SF(CURSOR0_0_CURSOR_SIZE, CURSOR_WIDTH, mask_sh), \
|
||||
HUBP_SF(CURSOR0_0_CURSOR_SIZE, CURSOR_HEIGHT, mask_sh), \
|
||||
HUBP_SF(CURSOR0_0_CURSOR_CONTROL, CURSOR_MODE, mask_sh), \
|
||||
HUBP_SF(CURSOR0_0_CURSOR_CONTROL, CURSOR_2X_MAGNIFY, mask_sh), \
|
||||
HUBP_SF(CURSOR0_0_CURSOR_CONTROL, CURSOR_PITCH, mask_sh), \
|
||||
HUBP_SF(CURSOR0_0_CURSOR_CONTROL, CURSOR_LINES_PER_CHUNK, mask_sh), \
|
||||
HUBP_SF(CURSOR0_0_CURSOR_CONTROL, CURSOR_ENABLE, mask_sh), \
|
||||
HUBP_SF(CURSOR0_0_CURSOR_POSITION, CURSOR_X_POSITION, mask_sh), \
|
||||
HUBP_SF(CURSOR0_0_CURSOR_POSITION, CURSOR_Y_POSITION, mask_sh), \
|
||||
HUBP_SF(CURSOR0_0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_X, mask_sh), \
|
||||
HUBP_SF(CURSOR0_0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_Y, mask_sh), \
|
||||
HUBP_SF(CURSOR0_0_CURSOR_DST_OFFSET, CURSOR_DST_X_OFFSET, mask_sh), \
|
||||
HUBP_SF(CURSOR0_0_DMDATA_ADDRESS_HIGH, DMDATA_ADDRESS_HIGH, mask_sh), \
|
||||
HUBP_SF(CURSOR0_0_DMDATA_CNTL, DMDATA_MODE, mask_sh), \
|
||||
HUBP_SF(CURSOR0_0_DMDATA_CNTL, DMDATA_UPDATED, mask_sh), \
|
||||
HUBP_SF(CURSOR0_0_DMDATA_CNTL, DMDATA_REPEAT, mask_sh), \
|
||||
HUBP_SF(CURSOR0_0_DMDATA_CNTL, DMDATA_SIZE, mask_sh), \
|
||||
HUBP_SF(CURSOR0_0_DMDATA_SW_CNTL, DMDATA_SW_UPDATED, mask_sh), \
|
||||
HUBP_SF(CURSOR0_0_DMDATA_SW_CNTL, DMDATA_SW_REPEAT, mask_sh), \
|
||||
HUBP_SF(CURSOR0_0_DMDATA_SW_CNTL, DMDATA_SW_SIZE, mask_sh), \
|
||||
HUBP_SF(CURSOR0_0_DMDATA_QOS_CNTL, DMDATA_QOS_MODE, mask_sh), \
|
||||
HUBP_SF(CURSOR0_0_DMDATA_QOS_CNTL, DMDATA_QOS_LEVEL, mask_sh), \
|
||||
HUBP_SF(CURSOR0_0_DMDATA_QOS_CNTL, DMDATA_DL_DELTA, mask_sh), \
|
||||
HUBP_SF(CURSOR0_0_DMDATA_STATUS, DMDATA_DONE, mask_sh),\
|
||||
HUBP_SF(HUBPREQ0_FLIP_PARAMETERS_0, DST_Y_PER_VM_FLIP, mask_sh),\
|
||||
HUBP_SF(HUBPREQ0_FLIP_PARAMETERS_0, DST_Y_PER_ROW_FLIP, mask_sh),\
|
||||
HUBP_SF(HUBPREQ0_FLIP_PARAMETERS_1, REFCYC_PER_PTE_GROUP_FLIP_L, mask_sh),\
|
||||
HUBP_SF(HUBPREQ0_FLIP_PARAMETERS_2, REFCYC_PER_META_CHUNK_FLIP_L, mask_sh),\
|
||||
HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_VREADY_AT_OR_AFTER_VSYNC, mask_sh),\
|
||||
HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_DISABLE_STOP_DATA_DURING_VM, mask_sh),\
|
||||
HUBP_SF(HUBPREQ0_DCSURF_FLIP_CONTROL, HUBPREQ_MASTER_UPDATE_LOCK_STATUS, mask_sh),\
|
||||
HUBP_SF(HUBPREQ0_DCSURF_FLIP_CONTROL2, SURFACE_GSL_ENABLE, mask_sh),\
|
||||
HUBP_SF(HUBPREQ0_DCSURF_FLIP_CONTROL2, SURFACE_TRIPLE_BUFFER_ENABLE, mask_sh),\
|
||||
HUBP_SF(HUBPREQ0_VMID_SETTINGS_0, VMID, mask_sh),\
|
||||
HUBP_SF(HUBPREQ0_FLIP_PARAMETERS_3, REFCYC_PER_VM_GROUP_FLIP, mask_sh),\
|
||||
HUBP_SF(HUBPREQ0_FLIP_PARAMETERS_4, REFCYC_PER_VM_REQ_FLIP, mask_sh),\
|
||||
HUBP_SF(HUBPREQ0_FLIP_PARAMETERS_5, REFCYC_PER_PTE_GROUP_FLIP_C, mask_sh),\
|
||||
HUBP_SF(HUBPREQ0_FLIP_PARAMETERS_6, REFCYC_PER_META_CHUNK_FLIP_C, mask_sh),\
|
||||
HUBP_SF(HUBPREQ0_VBLANK_PARAMETERS_5, REFCYC_PER_VM_GROUP_VBLANK, mask_sh),\
|
||||
HUBP_SF(HUBPREQ0_VBLANK_PARAMETERS_6, REFCYC_PER_VM_REQ_VBLANK, mask_sh),\
|
||||
HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, VM_GROUP_SIZE, mask_sh)
|
||||
|
||||
#define HUBP_MASK_SH_LIST_DCN21(mask_sh)\
|
||||
HUBP_MASK_SH_LIST_DCN21_COMMON(mask_sh),\
|
||||
HUBP_SF(HUBP0_DCSURF_TILING_CONFIG, RB_ALIGNED, mask_sh)
|
||||
|
||||
|
||||
struct dcn21_hubp {
|
||||
struct hubp base;
|
||||
struct dcn_hubp_state state;
|
||||
const struct dcn_hubp2_registers *hubp_regs;
|
||||
const struct dcn_hubp2_shift *hubp_shift;
|
||||
const struct dcn_hubp2_mask *hubp_mask;
|
||||
};
|
||||
|
||||
bool hubp21_construct(
|
||||
struct dcn21_hubp *hubp21,
|
||||
struct dc_context *ctx,
|
||||
uint32_t inst,
|
||||
const struct dcn_hubp2_registers *hubp_regs,
|
||||
const struct dcn_hubp2_shift *hubp_shift,
|
||||
const struct dcn_hubp2_mask *hubp_mask);
|
||||
|
||||
void apply_DEDCN21_142_wa_for_hostvm_deadline(
|
||||
struct hubp *hubp,
|
||||
struct _vcs_dpi_display_dlg_regs_st *dlg_attr);
|
||||
|
||||
void hubp21_program_deadline(
|
||||
struct hubp *hubp,
|
||||
struct _vcs_dpi_display_dlg_regs_st *dlg_attr,
|
||||
struct _vcs_dpi_display_ttu_regs_st *ttu_attr);
|
||||
|
||||
void hubp21_program_requestor(
|
||||
struct hubp *hubp,
|
||||
struct _vcs_dpi_display_rq_regs_st *rq_regs);
|
||||
#endif /* DAL_DC_DCN21_DCN21_HUBP_H_ */
|
1680
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
Normal file
1680
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
Normal file
File diff suppressed because it is too large
Load Diff
45
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.h
Normal file
45
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2018 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _DCN21_RESOURCE_H_
|
||||
#define _DCN21_RESOURCE_H_
|
||||
|
||||
#include "core_types.h"
|
||||
|
||||
#define TO_DCN21_RES_POOL(pool)\
|
||||
container_of(pool, struct dcn21_resource_pool, base)
|
||||
|
||||
struct dc;
|
||||
struct resource_pool;
|
||||
struct _vcs_dpi_display_pipe_params_st;
|
||||
|
||||
struct dcn21_resource_pool {
|
||||
struct resource_pool base;
|
||||
};
|
||||
struct resource_pool *dcn21_create_resource_pool(
|
||||
const struct dc_init_data *init_data,
|
||||
struct dc *dc);
|
||||
|
||||
#endif /* _DCN21_RESOURCE_H_ */
|
@ -44,6 +44,9 @@ enum pp_smu_ver {
|
||||
#ifndef CONFIG_TRIM_DRM_AMD_DC_DCN2_0
|
||||
PP_SMU_VER_NV,
|
||||
#endif
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
PP_SMU_VER_RN,
|
||||
#endif
|
||||
|
||||
PP_SMU_VER_MAX
|
||||
};
|
||||
@ -246,6 +249,47 @@ struct pp_smu_funcs_nv {
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
|
||||
#define PP_SMU_NUM_SOCCLK_DPM_LEVELS 8
|
||||
#define PP_SMU_NUM_DCFCLK_DPM_LEVELS 4
|
||||
#define PP_SMU_NUM_FCLK_DPM_LEVELS 4
|
||||
#define PP_SMU_NUM_MEMCLK_DPM_LEVELS 4
|
||||
|
||||
struct dpm_clock {
|
||||
uint32_t Freq; // In MHz
|
||||
uint32_t Vol; // Millivolts with 2 fractional bits
|
||||
};
|
||||
|
||||
|
||||
/* this is a copy of the structure defined in smuxx_driver_if.h*/
|
||||
struct dpm_clocks {
|
||||
struct dpm_clock DcfClocks[PP_SMU_NUM_DCFCLK_DPM_LEVELS];
|
||||
struct dpm_clock SocClocks[PP_SMU_NUM_SOCCLK_DPM_LEVELS];
|
||||
struct dpm_clock FClocks[PP_SMU_NUM_FCLK_DPM_LEVELS];
|
||||
struct dpm_clock MemClocks[PP_SMU_NUM_MEMCLK_DPM_LEVELS];
|
||||
};
|
||||
|
||||
|
||||
struct pp_smu_funcs_rn {
|
||||
struct pp_smu pp_smu;
|
||||
|
||||
/*
|
||||
* reader and writer WM's are sent together as part of one table
|
||||
*
|
||||
* PPSMC_MSG_SetDriverDramAddrHigh
|
||||
* PPSMC_MSG_SetDriverDramAddrLow
|
||||
* PPSMC_MSG_TransferTableDram2Smu
|
||||
*
|
||||
*/
|
||||
enum pp_smu_status (*set_wm_ranges)(struct pp_smu *pp,
|
||||
struct pp_smu_wm_range_sets *ranges);
|
||||
|
||||
enum pp_smu_status (*get_dpm_clock_table) (struct pp_smu *pp,
|
||||
struct dpm_clocks *clock_table);
|
||||
};
|
||||
#endif
|
||||
|
||||
struct pp_smu_funcs {
|
||||
struct pp_smu ctx;
|
||||
union {
|
||||
@ -253,6 +297,9 @@ struct pp_smu_funcs {
|
||||
#ifndef CONFIG_TRIM_DRM_AMD_DC_DCN2_0
|
||||
struct pp_smu_funcs_nv nv_funcs;
|
||||
#endif
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
struct pp_smu_funcs_rn rn_funcs;
|
||||
#endif
|
||||
|
||||
};
|
||||
};
|
||||
|
@ -45,6 +45,10 @@ CFLAGS_display_rq_dlg_calc_20.o := $(dml_ccflags)
|
||||
CFLAGS_display_mode_vba_20v2.o := $(dml_ccflags)
|
||||
CFLAGS_display_rq_dlg_calc_20v2.o := $(dml_ccflags)
|
||||
endif
|
||||
ifdef CONFIG_DRM_AMD_DC_DCN2_1
|
||||
CFLAGS_display_mode_vba_21.o := $(dml_ccflags)
|
||||
CFLAGS_display_rq_dlg_calc_21.o := $(dml_ccflags)
|
||||
endif
|
||||
ifdef CONFIG_DRM_AMD_DCN3AG
|
||||
CFLAGS_display_mode_vba_3ag.o := $(dml_ccflags)
|
||||
endif
|
||||
@ -59,6 +63,10 @@ ifdef CONFIG_DRM_AMD_DC_DCN2_0
|
||||
DML += display_mode_vba.o dcn20/display_rq_dlg_calc_20.o dcn20/display_mode_vba_20.o
|
||||
DML += dcn20/display_rq_dlg_calc_20v2.o dcn20/display_mode_vba_20v2.o
|
||||
endif
|
||||
ifdef CONFIG_DRM_AMD_DC_DCN2_1
|
||||
DML += dcn21/display_rq_dlg_calc_21.o dcn21/display_mode_vba_21.o
|
||||
endif
|
||||
|
||||
|
||||
AMD_DAL_DML = $(addprefix $(AMDDALPATH)/dc/dml/,$(DML))
|
||||
|
||||
|
6123
drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c
Normal file
6123
drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2017 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DML21_DISPLAY_MODE_VBA_H__
|
||||
#define __DML21_DISPLAY_MODE_VBA_H__
|
||||
|
||||
void dml21_recalculate(struct display_mode_lib *mode_lib);
|
||||
void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib);
|
||||
|
||||
#endif /* _DML21_DISPLAY_MODE_VBA_H_ */
|
1823
drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c
Normal file
1823
drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2017 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DML21_DISPLAY_RQ_DLG_CALC_H__
|
||||
#define __DML21_DISPLAY_RQ_DLG_CALC_H__
|
||||
|
||||
#include "../dml_common_defs.h"
|
||||
#include "../display_rq_dlg_helpers.h"
|
||||
|
||||
struct display_mode_lib;
|
||||
|
||||
|
||||
// Function: dml_rq_dlg_get_rq_reg
|
||||
// Main entry point for test to get the register values out of this DML class.
|
||||
// This function calls <get_rq_param> and <extract_rq_regs> functions to calculate
|
||||
// and then populate the rq_regs struct
|
||||
// Input:
|
||||
// pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.)
|
||||
// Output:
|
||||
// rq_regs - struct that holds all the RQ registers field value.
|
||||
// See also: <display_rq_regs_st>
|
||||
void dml21_rq_dlg_get_rq_reg(
|
||||
struct display_mode_lib *mode_lib,
|
||||
display_rq_regs_st *rq_regs,
|
||||
const display_pipe_params_st pipe_param);
|
||||
|
||||
// Function: dml_rq_dlg_get_dlg_reg
|
||||
// Calculate and return DLG and TTU register struct given the system setting
|
||||
// Output:
|
||||
// dlg_regs - output DLG register struct
|
||||
// ttu_regs - output DLG TTU register struct
|
||||
// Input:
|
||||
// e2e_pipe_param - "compacted" array of e2e pipe param struct
|
||||
// num_pipes - num of active "pipe" or "route"
|
||||
// pipe_idx - index that identifies the e2e_pipe_param that corresponding to this dlg
|
||||
// cstate - 0: when calculate min_ttu_vblank it is assumed cstate is not required. 1: Normal mode, cstate is considered.
|
||||
// Added for legacy or unrealistic timing tests.
|
||||
void dml21_rq_dlg_get_dlg_reg(
|
||||
struct display_mode_lib *mode_lib,
|
||||
display_dlg_regs_st *dlg_regs,
|
||||
display_ttu_regs_st *ttu_regs,
|
||||
display_e2e_pipe_params_st *e2e_pipe_param,
|
||||
const unsigned int num_pipes,
|
||||
const unsigned int pipe_idx,
|
||||
const bool cstate_en,
|
||||
const bool pstate_en,
|
||||
const bool vm_en,
|
||||
const bool ignore_viewport_pos,
|
||||
const bool immediate_flip_support);
|
||||
|
||||
#endif
|
@ -31,6 +31,10 @@
|
||||
#include "dcn20/display_mode_vba_20v2.h"
|
||||
#include "dcn20/display_rq_dlg_calc_20v2.h"
|
||||
#endif
|
||||
#ifdef CONFIG_DRM_AMD_DC_DCN2_1
|
||||
#include "dcn21/display_mode_vba_21.h"
|
||||
#include "dcn21/display_rq_dlg_calc_21.h"
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
|
||||
const struct dml_funcs dml20_funcs = {
|
||||
@ -48,6 +52,15 @@ const struct dml_funcs dml20v2_funcs = {
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_DCN2_1
|
||||
const struct dml_funcs dml21_funcs = {
|
||||
.validate = dml21_ModeSupportAndSystemConfigurationFull,
|
||||
.recalculate = dml21_recalculate,
|
||||
.rq_dlg_get_dlg_reg = dml21_rq_dlg_get_dlg_reg,
|
||||
.rq_dlg_get_rq_reg = dml21_rq_dlg_get_rq_reg
|
||||
};
|
||||
#endif
|
||||
|
||||
void dml_init_instance(struct display_mode_lib *lib,
|
||||
const struct _vcs_dpi_soc_bounding_box_st *soc_bb,
|
||||
const struct _vcs_dpi_ip_params_st *ip_params,
|
||||
@ -65,6 +78,12 @@ void dml_init_instance(struct display_mode_lib *lib,
|
||||
lib->funcs = dml20v2_funcs;
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_DRM_AMD_DC_DCN2_1
|
||||
case DML_PROJECT_DCN21:
|
||||
lib->funcs = dml21_funcs;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -38,6 +38,9 @@ enum dml_project {
|
||||
DML_PROJECT_NAVI10,
|
||||
DML_PROJECT_NAVI10v2,
|
||||
#endif
|
||||
#ifdef CONFIG_DRM_AMD_DC_DCN2_1
|
||||
DML_PROJECT_DCN21,
|
||||
#endif
|
||||
};
|
||||
|
||||
struct display_mode_lib;
|
||||
|
@ -80,6 +80,13 @@ AMD_DAL_GPIO_DCN20 = $(addprefix $(AMDDALPATH)/dc/gpio/dcn20/,$(GPIO_DCN20))
|
||||
AMD_DISPLAY_FILES += $(AMD_DAL_GPIO_DCN20)
|
||||
endif
|
||||
|
||||
ifdef CONFIG_DRM_AMD_DC_DCN2_1
|
||||
GPIO_DCN21 = hw_translate_dcn21.o hw_factory_dcn21.o
|
||||
|
||||
AMD_DAL_GPIO_DCN21 = $(addprefix $(AMDDALPATH)/dc/gpio/dcn21/,$(GPIO_DCN21))
|
||||
|
||||
AMD_DISPLAY_FILES += $(AMD_DAL_GPIO_DCN21)
|
||||
endif
|
||||
###############################################################################
|
||||
# Diagnostics on FPGA
|
||||
###############################################################################
|
||||
|
210
drivers/gpu/drm/amd/display/dc/gpio/dcn21/hw_factory_dcn21.c
Normal file
210
drivers/gpu/drm/amd/display/dc/gpio/dcn21/hw_factory_dcn21.c
Normal file
@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright 2013-15 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
|
||||
#include "dm_services.h"
|
||||
#include "include/gpio_types.h"
|
||||
#include "../hw_factory.h"
|
||||
|
||||
|
||||
#include "../hw_gpio.h"
|
||||
#include "../hw_ddc.h"
|
||||
#include "../hw_hpd.h"
|
||||
#include "../hw_generic.h"
|
||||
|
||||
#include "hw_factory_dcn21.h"
|
||||
|
||||
|
||||
#include "dcn/dcn_2_1_0_offset.h"
|
||||
#include "dcn/dcn_2_1_0_sh_mask.h"
|
||||
#include "renoir_ip_offset.h"
|
||||
|
||||
|
||||
#include "reg_helper.h"
|
||||
#include "../hpd_regs.h"
|
||||
/* begin *********************
|
||||
* macros to expend register list macro defined in HW object header file */
|
||||
|
||||
/* DCN */
|
||||
#define block HPD
|
||||
#define reg_num 0
|
||||
|
||||
#undef BASE_INNER
|
||||
#define BASE_INNER(seg) DMU_BASE__INST0_SEG ## seg
|
||||
|
||||
#define BASE(seg) BASE_INNER(seg)
|
||||
|
||||
|
||||
|
||||
#define REG(reg_name)\
|
||||
BASE(mm ## reg_name ## _BASE_IDX) + mm ## reg_name
|
||||
|
||||
#define SF_HPD(reg_name, field_name, post_fix)\
|
||||
.field_name = HPD0_ ## reg_name ## __ ## field_name ## post_fix
|
||||
|
||||
#define REGI(reg_name, block, id)\
|
||||
BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
|
||||
mm ## block ## id ## _ ## reg_name
|
||||
|
||||
#define SF(reg_name, field_name, post_fix)\
|
||||
.field_name = reg_name ## __ ## field_name ## post_fix
|
||||
|
||||
/* macros to expend register list macro defined in HW object header file
|
||||
* end *********************/
|
||||
|
||||
|
||||
|
||||
#define hpd_regs(id) \
|
||||
{\
|
||||
HPD_REG_LIST(id)\
|
||||
}
|
||||
|
||||
static const struct hpd_registers hpd_regs[] = {
|
||||
hpd_regs(0),
|
||||
hpd_regs(1),
|
||||
hpd_regs(2),
|
||||
hpd_regs(3),
|
||||
hpd_regs(4),
|
||||
};
|
||||
|
||||
static const struct hpd_sh_mask hpd_shift = {
|
||||
HPD_MASK_SH_LIST(__SHIFT)
|
||||
};
|
||||
|
||||
static const struct hpd_sh_mask hpd_mask = {
|
||||
HPD_MASK_SH_LIST(_MASK)
|
||||
};
|
||||
|
||||
#include "../ddc_regs.h"
|
||||
|
||||
/* set field name */
|
||||
#define SF_DDC(reg_name, field_name, post_fix)\
|
||||
.field_name = reg_name ## __ ## field_name ## post_fix
|
||||
|
||||
static const struct ddc_registers ddc_data_regs_dcn[] = {
|
||||
ddc_data_regs_dcn2(1),
|
||||
ddc_data_regs_dcn2(2),
|
||||
ddc_data_regs_dcn2(3),
|
||||
ddc_data_regs_dcn2(4),
|
||||
ddc_data_regs_dcn2(5),
|
||||
};
|
||||
|
||||
static const struct ddc_registers ddc_clk_regs_dcn[] = {
|
||||
ddc_clk_regs_dcn2(1),
|
||||
ddc_clk_regs_dcn2(2),
|
||||
ddc_clk_regs_dcn2(3),
|
||||
ddc_clk_regs_dcn2(4),
|
||||
ddc_clk_regs_dcn2(5),
|
||||
};
|
||||
|
||||
static const struct ddc_sh_mask ddc_shift[] = {
|
||||
DDC_MASK_SH_LIST_DCN2(__SHIFT, 1),
|
||||
DDC_MASK_SH_LIST_DCN2(__SHIFT, 2),
|
||||
DDC_MASK_SH_LIST_DCN2(__SHIFT, 3),
|
||||
DDC_MASK_SH_LIST_DCN2(__SHIFT, 4),
|
||||
DDC_MASK_SH_LIST_DCN2(__SHIFT, 5),
|
||||
DDC_MASK_SH_LIST_DCN2(__SHIFT, 6)
|
||||
};
|
||||
|
||||
static const struct ddc_sh_mask ddc_mask[] = {
|
||||
DDC_MASK_SH_LIST_DCN2(_MASK, 1),
|
||||
DDC_MASK_SH_LIST_DCN2(_MASK, 2),
|
||||
DDC_MASK_SH_LIST_DCN2(_MASK, 3),
|
||||
DDC_MASK_SH_LIST_DCN2(_MASK, 4),
|
||||
DDC_MASK_SH_LIST_DCN2(_MASK, 5),
|
||||
DDC_MASK_SH_LIST_DCN2(_MASK, 6)
|
||||
};
|
||||
|
||||
static void define_ddc_registers(
|
||||
struct hw_gpio_pin *pin,
|
||||
uint32_t en)
|
||||
{
|
||||
struct hw_ddc *ddc = HW_DDC_FROM_BASE(pin);
|
||||
|
||||
switch (pin->id) {
|
||||
case GPIO_ID_DDC_DATA:
|
||||
ddc->regs = &ddc_data_regs_dcn[en];
|
||||
ddc->base.regs = &ddc_data_regs_dcn[en].gpio;
|
||||
break;
|
||||
case GPIO_ID_DDC_CLOCK:
|
||||
ddc->regs = &ddc_clk_regs_dcn[en];
|
||||
ddc->base.regs = &ddc_clk_regs_dcn[en].gpio;
|
||||
break;
|
||||
default:
|
||||
ASSERT_CRITICAL(false);
|
||||
return;
|
||||
}
|
||||
|
||||
ddc->shifts = &ddc_shift[en];
|
||||
ddc->masks = &ddc_mask[en];
|
||||
|
||||
}
|
||||
|
||||
static void define_hpd_registers(struct hw_gpio_pin *pin, uint32_t en)
|
||||
{
|
||||
struct hw_hpd *hpd = HW_HPD_FROM_BASE(pin);
|
||||
|
||||
hpd->regs = &hpd_regs[en];
|
||||
hpd->shifts = &hpd_shift;
|
||||
hpd->masks = &hpd_mask;
|
||||
hpd->base.regs = &hpd_regs[en].gpio;
|
||||
}
|
||||
|
||||
|
||||
/* fucntion table */
|
||||
static const struct hw_factory_funcs funcs = {
|
||||
.init_ddc_data = dal_hw_ddc_init,
|
||||
.init_generic = dal_hw_generic_init,
|
||||
.init_hpd = dal_hw_hpd_init,
|
||||
.get_ddc_pin = dal_hw_ddc_get_pin,
|
||||
.get_hpd_pin = dal_hw_hpd_get_pin,
|
||||
.get_generic_pin = dal_hw_generic_get_pin,
|
||||
.define_hpd_registers = define_hpd_registers,
|
||||
.define_ddc_registers = define_ddc_registers
|
||||
};
|
||||
/*
|
||||
* dal_hw_factory_dcn10_init
|
||||
*
|
||||
* @brief
|
||||
* Initialize HW factory function pointers and pin info
|
||||
*
|
||||
* @param
|
||||
* struct hw_factory *factory - [out] struct of function pointers
|
||||
*/
|
||||
void dal_hw_factory_dcn21_init(struct hw_factory *factory)
|
||||
{
|
||||
/*TODO check ASIC CAPs*/
|
||||
factory->number_of_pins[GPIO_ID_DDC_DATA] = 8;
|
||||
factory->number_of_pins[GPIO_ID_DDC_CLOCK] = 8;
|
||||
factory->number_of_pins[GPIO_ID_GENERIC] = 4;
|
||||
factory->number_of_pins[GPIO_ID_HPD] = 6;
|
||||
factory->number_of_pins[GPIO_ID_GPIO_PAD] = 28;
|
||||
factory->number_of_pins[GPIO_ID_VIP_PAD] = 0;
|
||||
factory->number_of_pins[GPIO_ID_SYNC] = 0;
|
||||
factory->number_of_pins[GPIO_ID_GSL] = 0;/*add this*/
|
||||
|
||||
factory->funcs = &funcs;
|
||||
}
|
||||
|
||||
#endif
|
33
drivers/gpu/drm/amd/display/dc/gpio/dcn21/hw_factory_dcn21.h
Normal file
33
drivers/gpu/drm/amd/display/dc/gpio/dcn21/hw_factory_dcn21.h
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2018 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
#ifndef __DAL_HW_FACTORY_DCN21_H__
|
||||
#define __DAL_HW_FACTORY_DCN21_H__
|
||||
|
||||
/* Initialize HW factory function pointers and pin info */
|
||||
void dal_hw_factory_dcn21_init(struct hw_factory *factory);
|
||||
|
||||
#endif /* __DAL_HW_FACTORY_DCN20_H__ */
|
||||
#endif
|
386
drivers/gpu/drm/amd/display/dc/gpio/dcn21/hw_translate_dcn21.c
Normal file
386
drivers/gpu/drm/amd/display/dc/gpio/dcn21/hw_translate_dcn21.c
Normal file
@ -0,0 +1,386 @@
|
||||
/*
|
||||
* Copyright 2018 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Pre-requisites: headers required by header of this unit
|
||||
*/
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
|
||||
#include "hw_translate_dcn21.h"
|
||||
|
||||
#include "dm_services.h"
|
||||
#include "include/gpio_types.h"
|
||||
#include "../hw_translate.h"
|
||||
|
||||
#include "dcn/dcn_2_1_0_offset.h"
|
||||
#include "dcn/dcn_2_1_0_sh_mask.h"
|
||||
#include "renoir_ip_offset.h"
|
||||
|
||||
|
||||
|
||||
|
||||
/* begin *********************
|
||||
* macros to expend register list macro defined in HW object header file */
|
||||
|
||||
/* DCN */
|
||||
#define block HPD
|
||||
#define reg_num 0
|
||||
|
||||
#undef BASE_INNER
|
||||
#define BASE_INNER(seg) DMU_BASE__INST0_SEG ## seg
|
||||
|
||||
#define BASE(seg) BASE_INNER(seg)
|
||||
|
||||
#undef REG
|
||||
#define REG(reg_name)\
|
||||
BASE(mm ## reg_name ## _BASE_IDX) + mm ## reg_name
|
||||
#define SF_HPD(reg_name, field_name, post_fix)\
|
||||
.field_name = reg_name ## __ ## field_name ## post_fix
|
||||
|
||||
|
||||
/* macros to expend register list macro defined in HW object header file
|
||||
* end *********************/
|
||||
|
||||
|
||||
static bool offset_to_id(
|
||||
uint32_t offset,
|
||||
uint32_t mask,
|
||||
enum gpio_id *id,
|
||||
uint32_t *en)
|
||||
{
|
||||
switch (offset) {
|
||||
/* GENERIC */
|
||||
case REG(DC_GENERICA):
|
||||
*id = GPIO_ID_GENERIC;
|
||||
switch (mask) {
|
||||
case DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK:
|
||||
*en = GPIO_GENERIC_A;
|
||||
return true;
|
||||
case DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK:
|
||||
*en = GPIO_GENERIC_B;
|
||||
return true;
|
||||
case DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK:
|
||||
*en = GPIO_GENERIC_C;
|
||||
return true;
|
||||
case DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK:
|
||||
*en = GPIO_GENERIC_D;
|
||||
return true;
|
||||
case DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK:
|
||||
*en = GPIO_GENERIC_E;
|
||||
return true;
|
||||
case DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK:
|
||||
*en = GPIO_GENERIC_F;
|
||||
return true;
|
||||
case DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK:
|
||||
*en = GPIO_GENERIC_G;
|
||||
return true;
|
||||
default:
|
||||
ASSERT_CRITICAL(false);
|
||||
#ifdef PALLADIUM_SUPPORTED
|
||||
*en = GPIO_DDC_LINE_DDC1;
|
||||
return true;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
/* HPD */
|
||||
case REG(DC_GPIO_HPD_A):
|
||||
*id = GPIO_ID_HPD;
|
||||
switch (mask) {
|
||||
case DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK:
|
||||
*en = GPIO_HPD_1;
|
||||
return true;
|
||||
case DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK:
|
||||
*en = GPIO_HPD_2;
|
||||
return true;
|
||||
case DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK:
|
||||
*en = GPIO_HPD_3;
|
||||
return true;
|
||||
case DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK:
|
||||
*en = GPIO_HPD_4;
|
||||
return true;
|
||||
case DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK:
|
||||
*en = GPIO_HPD_5;
|
||||
return true;
|
||||
case DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK:
|
||||
*en = GPIO_HPD_6;
|
||||
return true;
|
||||
default:
|
||||
ASSERT_CRITICAL(false);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
/* REG(DC_GPIO_GENLK_MASK */
|
||||
case REG(DC_GPIO_GENLK_A):
|
||||
*id = GPIO_ID_GSL;
|
||||
switch (mask) {
|
||||
case DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK:
|
||||
*en = GPIO_GSL_GENLOCK_CLOCK;
|
||||
return true;
|
||||
case DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK:
|
||||
*en = GPIO_GSL_GENLOCK_VSYNC;
|
||||
return true;
|
||||
case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK:
|
||||
*en = GPIO_GSL_SWAPLOCK_A;
|
||||
return true;
|
||||
case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK:
|
||||
*en = GPIO_GSL_SWAPLOCK_B;
|
||||
return true;
|
||||
default:
|
||||
ASSERT_CRITICAL(false);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
/* DDC */
|
||||
/* we don't care about the GPIO_ID for DDC
|
||||
* in DdcHandle it will use GPIO_ID_DDC_DATA/GPIO_ID_DDC_CLOCK
|
||||
* directly in the create method */
|
||||
case REG(DC_GPIO_DDC1_A):
|
||||
*en = GPIO_DDC_LINE_DDC1;
|
||||
return true;
|
||||
case REG(DC_GPIO_DDC2_A):
|
||||
*en = GPIO_DDC_LINE_DDC2;
|
||||
return true;
|
||||
case REG(DC_GPIO_DDC3_A):
|
||||
*en = GPIO_DDC_LINE_DDC3;
|
||||
return true;
|
||||
case REG(DC_GPIO_DDC4_A):
|
||||
*en = GPIO_DDC_LINE_DDC4;
|
||||
return true;
|
||||
case REG(DC_GPIO_DDC5_A):
|
||||
*en = GPIO_DDC_LINE_DDC5;
|
||||
return true;
|
||||
case REG(DC_GPIO_DDCVGA_A):
|
||||
*en = GPIO_DDC_LINE_DDC_VGA;
|
||||
return true;
|
||||
|
||||
// case REG(DC_GPIO_I2CPAD_A): not exit
|
||||
// case REG(DC_GPIO_PWRSEQ_A):
|
||||
// case REG(DC_GPIO_PAD_STRENGTH_1):
|
||||
// case REG(DC_GPIO_PAD_STRENGTH_2):
|
||||
// case REG(DC_GPIO_DEBUG):
|
||||
/* UNEXPECTED */
|
||||
default:
|
||||
// case REG(DC_GPIO_SYNCA_A): not exist
|
||||
#ifdef PALLADIUM_SUPPORTED
|
||||
*id = GPIO_ID_HPD;
|
||||
*en = GPIO_DDC_LINE_DDC1;
|
||||
return true;
|
||||
#endif
|
||||
ASSERT_CRITICAL(false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool id_to_offset(
|
||||
enum gpio_id id,
|
||||
uint32_t en,
|
||||
struct gpio_pin_info *info)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
switch (id) {
|
||||
case GPIO_ID_DDC_DATA:
|
||||
info->mask = DC_GPIO_DDC5_A__DC_GPIO_DDC5DATA_A_MASK;
|
||||
switch (en) {
|
||||
case GPIO_DDC_LINE_DDC1:
|
||||
info->offset = REG(DC_GPIO_DDC1_A);
|
||||
break;
|
||||
case GPIO_DDC_LINE_DDC2:
|
||||
info->offset = REG(DC_GPIO_DDC2_A);
|
||||
break;
|
||||
case GPIO_DDC_LINE_DDC3:
|
||||
info->offset = REG(DC_GPIO_DDC3_A);
|
||||
break;
|
||||
case GPIO_DDC_LINE_DDC4:
|
||||
info->offset = REG(DC_GPIO_DDC4_A);
|
||||
break;
|
||||
case GPIO_DDC_LINE_DDC5:
|
||||
info->offset = REG(DC_GPIO_DDC5_A);
|
||||
break;
|
||||
case GPIO_DDC_LINE_DDC_VGA:
|
||||
info->offset = REG(DC_GPIO_DDCVGA_A);
|
||||
break;
|
||||
case GPIO_DDC_LINE_I2C_PAD:
|
||||
default:
|
||||
ASSERT_CRITICAL(false);
|
||||
result = false;
|
||||
}
|
||||
break;
|
||||
case GPIO_ID_DDC_CLOCK:
|
||||
info->mask = DC_GPIO_DDC5_A__DC_GPIO_DDC5CLK_A_MASK;
|
||||
switch (en) {
|
||||
case GPIO_DDC_LINE_DDC1:
|
||||
info->offset = REG(DC_GPIO_DDC1_A);
|
||||
break;
|
||||
case GPIO_DDC_LINE_DDC2:
|
||||
info->offset = REG(DC_GPIO_DDC2_A);
|
||||
break;
|
||||
case GPIO_DDC_LINE_DDC3:
|
||||
info->offset = REG(DC_GPIO_DDC3_A);
|
||||
break;
|
||||
case GPIO_DDC_LINE_DDC4:
|
||||
info->offset = REG(DC_GPIO_DDC4_A);
|
||||
break;
|
||||
case GPIO_DDC_LINE_DDC5:
|
||||
info->offset = REG(DC_GPIO_DDC5_A);
|
||||
break;
|
||||
case GPIO_DDC_LINE_DDC_VGA:
|
||||
info->offset = REG(DC_GPIO_DDCVGA_A);
|
||||
break;
|
||||
case GPIO_DDC_LINE_I2C_PAD:
|
||||
default:
|
||||
ASSERT_CRITICAL(false);
|
||||
result = false;
|
||||
}
|
||||
break;
|
||||
case GPIO_ID_GENERIC:
|
||||
info->offset = REG(DC_GPIO_GENERIC_A);
|
||||
switch (en) {
|
||||
case GPIO_GENERIC_A:
|
||||
info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK;
|
||||
break;
|
||||
case GPIO_GENERIC_B:
|
||||
info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK;
|
||||
break;
|
||||
case GPIO_GENERIC_C:
|
||||
info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK;
|
||||
break;
|
||||
case GPIO_GENERIC_D:
|
||||
info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK;
|
||||
break;
|
||||
case GPIO_GENERIC_E:
|
||||
info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK;
|
||||
break;
|
||||
case GPIO_GENERIC_F:
|
||||
info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK;
|
||||
break;
|
||||
case GPIO_GENERIC_G:
|
||||
info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK;
|
||||
break;
|
||||
default:
|
||||
ASSERT_CRITICAL(false);
|
||||
result = false;
|
||||
}
|
||||
break;
|
||||
case GPIO_ID_HPD:
|
||||
info->offset = REG(DC_GPIO_HPD_A);
|
||||
switch (en) {
|
||||
case GPIO_HPD_1:
|
||||
info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK;
|
||||
break;
|
||||
case GPIO_HPD_2:
|
||||
info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK;
|
||||
break;
|
||||
case GPIO_HPD_3:
|
||||
info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK;
|
||||
break;
|
||||
case GPIO_HPD_4:
|
||||
info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK;
|
||||
break;
|
||||
case GPIO_HPD_5:
|
||||
info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK;
|
||||
break;
|
||||
case GPIO_HPD_6:
|
||||
info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK;
|
||||
break;
|
||||
default:
|
||||
ASSERT_CRITICAL(false);
|
||||
#ifdef PALLADIUM_SUPPORTED
|
||||
info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK;
|
||||
result = true;
|
||||
#endif
|
||||
result = false;
|
||||
}
|
||||
break;
|
||||
case GPIO_ID_GSL:
|
||||
switch (en) {
|
||||
case GPIO_GSL_GENLOCK_CLOCK:
|
||||
/*not implmented*/
|
||||
ASSERT_CRITICAL(false);
|
||||
result = false;
|
||||
break;
|
||||
case GPIO_GSL_GENLOCK_VSYNC:
|
||||
/*not implmented*/
|
||||
ASSERT_CRITICAL(false);
|
||||
result = false;
|
||||
break;
|
||||
case GPIO_GSL_SWAPLOCK_A:
|
||||
/*not implmented*/
|
||||
ASSERT_CRITICAL(false);
|
||||
result = false;
|
||||
break;
|
||||
case GPIO_GSL_SWAPLOCK_B:
|
||||
/*not implmented*/
|
||||
ASSERT_CRITICAL(false);
|
||||
result = false;
|
||||
|
||||
break;
|
||||
default:
|
||||
ASSERT_CRITICAL(false);
|
||||
result = false;
|
||||
}
|
||||
break;
|
||||
case GPIO_ID_SYNC:
|
||||
case GPIO_ID_VIP_PAD:
|
||||
default:
|
||||
ASSERT_CRITICAL(false);
|
||||
result = false;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
info->offset_y = info->offset + 2;
|
||||
info->offset_en = info->offset + 1;
|
||||
info->offset_mask = info->offset - 1;
|
||||
|
||||
info->mask_y = info->mask;
|
||||
info->mask_en = info->mask;
|
||||
info->mask_mask = info->mask;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* function table */
|
||||
static const struct hw_translate_funcs funcs = {
|
||||
.offset_to_id = offset_to_id,
|
||||
.id_to_offset = id_to_offset,
|
||||
};
|
||||
|
||||
/*
|
||||
* dal_hw_translate_dcn10_init
|
||||
*
|
||||
* @brief
|
||||
* Initialize Hw translate function pointers.
|
||||
*
|
||||
* @param
|
||||
* struct hw_translate *tr - [out] struct of function pointers
|
||||
*
|
||||
*/
|
||||
void dal_hw_translate_dcn21_init(struct hw_translate *tr)
|
||||
{
|
||||
tr->funcs = &funcs;
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2018 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
#ifndef __DAL_HW_TRANSLATE_DCN21_H__
|
||||
#define __DAL_HW_TRANSLATE_DCN21_H__
|
||||
|
||||
struct hw_translate;
|
||||
|
||||
/* Initialize Hw translate function pointers */
|
||||
void dal_hw_translate_dcn21_init(struct hw_translate *tr);
|
||||
|
||||
#endif /* __DAL_HW_TRANSLATE_DCN21_H__ */
|
||||
#endif
|
@ -51,6 +51,9 @@
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
|
||||
#include "dcn20/hw_factory_dcn20.h"
|
||||
#endif
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
#include "dcn21/hw_factory_dcn21.h"
|
||||
#endif
|
||||
|
||||
#include "diagnostics/hw_factory_diag.h"
|
||||
|
||||
@ -99,6 +102,11 @@ bool dal_hw_factory_init(
|
||||
dal_hw_factory_dcn20_init(factory);
|
||||
return true;
|
||||
#endif
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
case DCN_VERSION_2_1:
|
||||
dal_hw_factory_dcn21_init(factory);
|
||||
return true;
|
||||
#endif
|
||||
|
||||
default:
|
||||
ASSERT_CRITICAL(false);
|
||||
|
@ -49,6 +49,9 @@
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
|
||||
#include "dcn20/hw_translate_dcn20.h"
|
||||
#endif
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
#include "dcn21/hw_translate_dcn21.h"
|
||||
#endif
|
||||
|
||||
#include "diagnostics/hw_translate_diag.h"
|
||||
|
||||
@ -94,6 +97,11 @@ bool dal_hw_translate_init(
|
||||
dal_hw_translate_dcn20_init(translate);
|
||||
return true;
|
||||
#endif
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
case DCN_VERSION_2_1:
|
||||
dal_hw_translate_dcn21_init(translate);
|
||||
return true;
|
||||
#endif
|
||||
|
||||
default:
|
||||
BREAK_TO_DEBUGGER();
|
||||
|
@ -87,6 +87,9 @@ void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable);
|
||||
struct resource_pool;
|
||||
struct dc_state;
|
||||
struct resource_context;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
struct clk_bw_params;
|
||||
#endif
|
||||
|
||||
struct resource_funcs {
|
||||
void (*destroy)(struct resource_pool **pool);
|
||||
@ -142,6 +145,11 @@ struct resource_funcs {
|
||||
display_e2e_pipe_params_st *pipes,
|
||||
int pipe_cnt);
|
||||
#endif
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
void (*update_bw_bounding_box)(
|
||||
struct dc *dc,
|
||||
struct clk_bw_params *bw_params);
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
@ -31,6 +31,128 @@
|
||||
#define DCN_MINIMUM_DISPCLK_Khz 100000
|
||||
#define DCN_MINIMUM_DPPCLK_Khz 100000
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_DCN2_1
|
||||
/* Constants */
|
||||
#define DDR4_DRAM_WIDTH 64
|
||||
#define WM_A 0
|
||||
#define WM_B 1
|
||||
#define WM_C 2
|
||||
#define WM_D 3
|
||||
#define WM_SET_COUNT 4
|
||||
#endif
|
||||
|
||||
#define DCN_MINIMUM_DISPCLK_Khz 100000
|
||||
#define DCN_MINIMUM_DPPCLK_Khz 100000
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_DCN2_1
|
||||
/* Will these bw structures be ASIC specific? */
|
||||
|
||||
#define MAX_NUM_DPM_LVL 4
|
||||
#define WM_SET_COUNT 4
|
||||
|
||||
|
||||
struct clk_limit_table_entry {
|
||||
unsigned int voltage; /* milivolts withh 2 fractional bits */
|
||||
unsigned int dcfclk_mhz;
|
||||
unsigned int fclk_mhz;
|
||||
unsigned int memclk_mhz;
|
||||
unsigned int socclk_mhz;
|
||||
};
|
||||
|
||||
/* This table is contiguous */
|
||||
struct clk_limit_table {
|
||||
struct clk_limit_table_entry entries[MAX_NUM_DPM_LVL];
|
||||
unsigned int num_entries;
|
||||
};
|
||||
|
||||
struct wm_range_table_entry {
|
||||
unsigned int wm_inst;
|
||||
unsigned int wm_type;
|
||||
double pstate_latency_us;
|
||||
bool valid;
|
||||
};
|
||||
|
||||
|
||||
struct clk_log_info {
|
||||
bool enabled;
|
||||
char *pBuf;
|
||||
unsigned int bufSize;
|
||||
unsigned int *sum_chars_printed;
|
||||
};
|
||||
|
||||
struct clk_state_registers_and_bypass {
|
||||
uint32_t dcfclk;
|
||||
uint32_t dcf_deep_sleep_divider;
|
||||
uint32_t dcf_deep_sleep_allow;
|
||||
uint32_t dprefclk;
|
||||
uint32_t dispclk;
|
||||
uint32_t dppclk;
|
||||
|
||||
uint32_t dppclk_bypass;
|
||||
uint32_t dcfclk_bypass;
|
||||
uint32_t dprefclk_bypass;
|
||||
uint32_t dispclk_bypass;
|
||||
};
|
||||
|
||||
struct rv1_clk_internal {
|
||||
uint32_t CLK0_CLK8_CURRENT_CNT; //dcfclk
|
||||
uint32_t CLK0_CLK8_DS_CNTL; //dcf_deep_sleep_divider
|
||||
uint32_t CLK0_CLK8_ALLOW_DS; //dcf_deep_sleep_allow
|
||||
uint32_t CLK0_CLK10_CURRENT_CNT; //dprefclk
|
||||
uint32_t CLK0_CLK11_CURRENT_CNT; //dispclk
|
||||
|
||||
uint32_t CLK0_CLK8_BYPASS_CNTL; //dcfclk bypass
|
||||
uint32_t CLK0_CLK10_BYPASS_CNTL; //dprefclk bypass
|
||||
uint32_t CLK0_CLK11_BYPASS_CNTL; //dispclk bypass
|
||||
};
|
||||
|
||||
struct rn_clk_internal {
|
||||
uint32_t CLK1_CLK0_CURRENT_CNT; //dispclk
|
||||
uint32_t CLK1_CLK1_CURRENT_CNT; //dppclk
|
||||
uint32_t CLK1_CLK2_CURRENT_CNT; //dprefclk
|
||||
uint32_t CLK1_CLK3_CURRENT_CNT; //dcfclk
|
||||
uint32_t CLK1_CLK3_DS_CNTL; //dcf_deep_sleep_divider
|
||||
uint32_t CLK1_CLK3_ALLOW_DS; //dcf_deep_sleep_allow
|
||||
|
||||
uint32_t CLK1_CLK0_BYPASS_CNTL; //dispclk bypass
|
||||
uint32_t CLK1_CLK1_BYPASS_CNTL; //dppclk bypass
|
||||
uint32_t CLK1_CLK2_BYPASS_CNTL; //dprefclk bypass
|
||||
uint32_t CLK1_CLK3_BYPASS_CNTL; //dcfclk bypass
|
||||
|
||||
};
|
||||
|
||||
/* For dtn logging and debugging */
|
||||
struct clk_state_registers {
|
||||
uint32_t CLK0_CLK8_CURRENT_CNT; //dcfclk
|
||||
uint32_t CLK0_CLK8_DS_CNTL; //dcf_deep_sleep_divider
|
||||
uint32_t CLK0_CLK8_ALLOW_DS; //dcf_deep_sleep_allow
|
||||
uint32_t CLK0_CLK10_CURRENT_CNT; //dprefclk
|
||||
uint32_t CLK0_CLK11_CURRENT_CNT; //dispclk
|
||||
};
|
||||
|
||||
/* TODO: combine this with the above */
|
||||
struct clk_bypass {
|
||||
uint32_t dcfclk_bypass;
|
||||
uint32_t dispclk_pypass;
|
||||
uint32_t dprefclk_bypass;
|
||||
};
|
||||
/*
|
||||
* This table is not contiguous, can have holes, each
|
||||
* entry correspond to one set of WM. For example if
|
||||
* we have 2 DPM and LPDDR, we will WM set A, B and
|
||||
* D occupied, C will be emptry.
|
||||
*/
|
||||
struct wm_table {
|
||||
struct wm_range_table_entry entries[WM_SET_COUNT];
|
||||
};
|
||||
|
||||
struct clk_bw_params {
|
||||
unsigned int vram_type;
|
||||
unsigned int num_channels;
|
||||
struct clk_limit_table clk_table;
|
||||
struct wm_table wm_table;
|
||||
};
|
||||
#endif
|
||||
/* Public interfaces */
|
||||
|
||||
struct clk_states {
|
||||
@ -65,6 +187,9 @@ struct clk_mgr {
|
||||
struct clk_mgr_funcs *funcs;
|
||||
struct dc_clocks clks;
|
||||
int dprefclk_khz; // Used by program pixel clock in clock source funcs, need to figureout where this goes
|
||||
#ifdef CONFIG_DRM_AMD_DC_DCN2_1
|
||||
struct clk_bw_params *bw_params;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* forward declarations */
|
||||
|
@ -40,6 +40,10 @@ struct cstate_pstate_watermarks_st {
|
||||
struct dcn_watermarks {
|
||||
uint32_t pte_meta_urgent_ns;
|
||||
uint32_t urgent_ns;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
uint32_t frac_urg_bw_nom;
|
||||
uint32_t frac_urg_bw_flip;
|
||||
#endif
|
||||
struct cstate_pstate_watermarks_st cstate_pstate;
|
||||
};
|
||||
|
||||
|
@ -48,6 +48,7 @@ struct dce_hwseq_wa {
|
||||
bool DEGVIDCN10_253;
|
||||
bool false_optc_underflow;
|
||||
bool DEGVIDCN10_254;
|
||||
bool DEGVIDCN21;
|
||||
};
|
||||
|
||||
struct hwseq_wa_state {
|
||||
|
@ -77,3 +77,13 @@ AMD_DAL_IRQ_DCN2 = $(addprefix $(AMDDALPATH)/dc/irq/dcn20/,$(IRQ_DCN2))
|
||||
|
||||
AMD_DISPLAY_FILES += $(AMD_DAL_IRQ_DCN2)
|
||||
endif
|
||||
###############################################################################
|
||||
# DCN 21
|
||||
###############################################################################
|
||||
ifdef CONFIG_DRM_AMD_DC_DCN2_1
|
||||
IRQ_DCN21 = irq_service_dcn21.o
|
||||
|
||||
AMD_DAL_IRQ_DCN21= $(addprefix $(AMDDALPATH)/dc/irq/dcn21/,$(IRQ_DCN21))
|
||||
|
||||
AMD_DISPLAY_FILES += $(AMD_DAL_IRQ_DCN21)
|
||||
endif
|
||||
|
374
drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c
Normal file
374
drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c
Normal file
@ -0,0 +1,374 @@
|
||||
/*
|
||||
* Copyright 2018 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "dm_services.h"
|
||||
|
||||
#include "include/logger_interface.h"
|
||||
|
||||
#include "../dce110/irq_service_dce110.h"
|
||||
|
||||
#include "dcn/dcn_2_1_0_offset.h"
|
||||
#include "dcn/dcn_2_1_0_sh_mask.h"
|
||||
#include "renoir_ip_offset.h"
|
||||
|
||||
|
||||
#include "irq_service_dcn21.h"
|
||||
|
||||
#include "ivsrcid/dcn/irqsrcs_dcn_1_0.h"
|
||||
|
||||
enum dc_irq_source to_dal_irq_source_dcn21(
|
||||
struct irq_service *irq_service,
|
||||
uint32_t src_id,
|
||||
uint32_t ext_id)
|
||||
{
|
||||
switch (src_id) {
|
||||
case DCN_1_0__SRCID__DC_D1_OTG_VSTARTUP:
|
||||
return DC_IRQ_SOURCE_VBLANK1;
|
||||
case DCN_1_0__SRCID__DC_D2_OTG_VSTARTUP:
|
||||
return DC_IRQ_SOURCE_VBLANK2;
|
||||
case DCN_1_0__SRCID__DC_D3_OTG_VSTARTUP:
|
||||
return DC_IRQ_SOURCE_VBLANK3;
|
||||
case DCN_1_0__SRCID__DC_D4_OTG_VSTARTUP:
|
||||
return DC_IRQ_SOURCE_VBLANK4;
|
||||
case DCN_1_0__SRCID__DC_D5_OTG_VSTARTUP:
|
||||
return DC_IRQ_SOURCE_VBLANK5;
|
||||
case DCN_1_0__SRCID__DC_D6_OTG_VSTARTUP:
|
||||
return DC_IRQ_SOURCE_VBLANK6;
|
||||
case DCN_1_0__SRCID__HUBP0_FLIP_INTERRUPT:
|
||||
return DC_IRQ_SOURCE_PFLIP1;
|
||||
case DCN_1_0__SRCID__HUBP1_FLIP_INTERRUPT:
|
||||
return DC_IRQ_SOURCE_PFLIP2;
|
||||
case DCN_1_0__SRCID__HUBP2_FLIP_INTERRUPT:
|
||||
return DC_IRQ_SOURCE_PFLIP3;
|
||||
case DCN_1_0__SRCID__HUBP3_FLIP_INTERRUPT:
|
||||
return DC_IRQ_SOURCE_PFLIP4;
|
||||
case DCN_1_0__SRCID__HUBP4_FLIP_INTERRUPT:
|
||||
return DC_IRQ_SOURCE_PFLIP5;
|
||||
case DCN_1_0__SRCID__HUBP5_FLIP_INTERRUPT:
|
||||
return DC_IRQ_SOURCE_PFLIP6;
|
||||
case DCN_1_0__SRCID__OTG0_IHC_V_UPDATE_NO_LOCK_INTERRUPT:
|
||||
return DC_IRQ_SOURCE_VUPDATE1;
|
||||
case DCN_1_0__SRCID__OTG1_IHC_V_UPDATE_NO_LOCK_INTERRUPT:
|
||||
return DC_IRQ_SOURCE_VUPDATE2;
|
||||
case DCN_1_0__SRCID__OTG2_IHC_V_UPDATE_NO_LOCK_INTERRUPT:
|
||||
return DC_IRQ_SOURCE_VUPDATE3;
|
||||
case DCN_1_0__SRCID__OTG3_IHC_V_UPDATE_NO_LOCK_INTERRUPT:
|
||||
return DC_IRQ_SOURCE_VUPDATE4;
|
||||
case DCN_1_0__SRCID__OTG4_IHC_V_UPDATE_NO_LOCK_INTERRUPT:
|
||||
return DC_IRQ_SOURCE_VUPDATE5;
|
||||
case DCN_1_0__SRCID__OTG5_IHC_V_UPDATE_NO_LOCK_INTERRUPT:
|
||||
return DC_IRQ_SOURCE_VUPDATE6;
|
||||
|
||||
case DCN_1_0__SRCID__DC_HPD1_INT:
|
||||
/* generic src_id for all HPD and HPDRX interrupts */
|
||||
switch (ext_id) {
|
||||
case DCN_1_0__CTXID__DC_HPD1_INT:
|
||||
return DC_IRQ_SOURCE_HPD1;
|
||||
case DCN_1_0__CTXID__DC_HPD2_INT:
|
||||
return DC_IRQ_SOURCE_HPD2;
|
||||
case DCN_1_0__CTXID__DC_HPD3_INT:
|
||||
return DC_IRQ_SOURCE_HPD3;
|
||||
case DCN_1_0__CTXID__DC_HPD4_INT:
|
||||
return DC_IRQ_SOURCE_HPD4;
|
||||
case DCN_1_0__CTXID__DC_HPD5_INT:
|
||||
return DC_IRQ_SOURCE_HPD5;
|
||||
case DCN_1_0__CTXID__DC_HPD6_INT:
|
||||
return DC_IRQ_SOURCE_HPD6;
|
||||
case DCN_1_0__CTXID__DC_HPD1_RX_INT:
|
||||
return DC_IRQ_SOURCE_HPD1RX;
|
||||
case DCN_1_0__CTXID__DC_HPD2_RX_INT:
|
||||
return DC_IRQ_SOURCE_HPD2RX;
|
||||
case DCN_1_0__CTXID__DC_HPD3_RX_INT:
|
||||
return DC_IRQ_SOURCE_HPD3RX;
|
||||
case DCN_1_0__CTXID__DC_HPD4_RX_INT:
|
||||
return DC_IRQ_SOURCE_HPD4RX;
|
||||
case DCN_1_0__CTXID__DC_HPD5_RX_INT:
|
||||
return DC_IRQ_SOURCE_HPD5RX;
|
||||
case DCN_1_0__CTXID__DC_HPD6_RX_INT:
|
||||
return DC_IRQ_SOURCE_HPD6RX;
|
||||
default:
|
||||
return DC_IRQ_SOURCE_INVALID;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return DC_IRQ_SOURCE_INVALID;
|
||||
}
|
||||
|
||||
static bool hpd_ack(
|
||||
struct irq_service *irq_service,
|
||||
const struct irq_source_info *info)
|
||||
{
|
||||
uint32_t addr = info->status_reg;
|
||||
uint32_t value = dm_read_reg(irq_service->ctx, addr);
|
||||
uint32_t current_status =
|
||||
get_reg_field_value(
|
||||
value,
|
||||
HPD0_DC_HPD_INT_STATUS,
|
||||
DC_HPD_SENSE_DELAYED);
|
||||
|
||||
dal_irq_service_ack_generic(irq_service, info);
|
||||
|
||||
value = dm_read_reg(irq_service->ctx, info->enable_reg);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
current_status ? 0 : 1,
|
||||
HPD0_DC_HPD_INT_CONTROL,
|
||||
DC_HPD_INT_POLARITY);
|
||||
|
||||
dm_write_reg(irq_service->ctx, info->enable_reg, value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct irq_source_info_funcs hpd_irq_info_funcs = {
|
||||
.set = NULL,
|
||||
.ack = hpd_ack
|
||||
};
|
||||
|
||||
static const struct irq_source_info_funcs hpd_rx_irq_info_funcs = {
|
||||
.set = NULL,
|
||||
.ack = NULL
|
||||
};
|
||||
|
||||
static const struct irq_source_info_funcs pflip_irq_info_funcs = {
|
||||
.set = NULL,
|
||||
.ack = NULL
|
||||
};
|
||||
|
||||
static const struct irq_source_info_funcs vblank_irq_info_funcs = {
|
||||
.set = NULL,
|
||||
.ack = NULL
|
||||
};
|
||||
|
||||
#undef BASE_INNER
|
||||
#define BASE_INNER(seg) DMU_BASE__INST0_SEG ## seg
|
||||
|
||||
/* compile time expand base address. */
|
||||
#define BASE(seg) \
|
||||
BASE_INNER(seg)
|
||||
|
||||
|
||||
#define SRI(reg_name, block, id)\
|
||||
BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
|
||||
mm ## block ## id ## _ ## reg_name
|
||||
|
||||
|
||||
#define IRQ_REG_ENTRY(block, reg_num, reg1, mask1, reg2, mask2)\
|
||||
.enable_reg = SRI(reg1, block, reg_num),\
|
||||
.enable_mask = \
|
||||
block ## reg_num ## _ ## reg1 ## __ ## mask1 ## _MASK,\
|
||||
.enable_value = {\
|
||||
block ## reg_num ## _ ## reg1 ## __ ## mask1 ## _MASK,\
|
||||
~block ## reg_num ## _ ## reg1 ## __ ## mask1 ## _MASK \
|
||||
},\
|
||||
.ack_reg = SRI(reg2, block, reg_num),\
|
||||
.ack_mask = \
|
||||
block ## reg_num ## _ ## reg2 ## __ ## mask2 ## _MASK,\
|
||||
.ack_value = \
|
||||
block ## reg_num ## _ ## reg2 ## __ ## mask2 ## _MASK \
|
||||
|
||||
|
||||
|
||||
#define hpd_int_entry(reg_num)\
|
||||
[DC_IRQ_SOURCE_HPD1 + reg_num] = {\
|
||||
IRQ_REG_ENTRY(HPD, reg_num,\
|
||||
DC_HPD_INT_CONTROL, DC_HPD_INT_EN,\
|
||||
DC_HPD_INT_CONTROL, DC_HPD_INT_ACK),\
|
||||
.status_reg = SRI(DC_HPD_INT_STATUS, HPD, reg_num),\
|
||||
.funcs = &hpd_irq_info_funcs\
|
||||
}
|
||||
|
||||
#define hpd_rx_int_entry(reg_num)\
|
||||
[DC_IRQ_SOURCE_HPD1RX + reg_num] = {\
|
||||
IRQ_REG_ENTRY(HPD, reg_num,\
|
||||
DC_HPD_INT_CONTROL, DC_HPD_RX_INT_EN,\
|
||||
DC_HPD_INT_CONTROL, DC_HPD_RX_INT_ACK),\
|
||||
.status_reg = SRI(DC_HPD_INT_STATUS, HPD, reg_num),\
|
||||
.funcs = &hpd_rx_irq_info_funcs\
|
||||
}
|
||||
#define pflip_int_entry(reg_num)\
|
||||
[DC_IRQ_SOURCE_PFLIP1 + reg_num] = {\
|
||||
IRQ_REG_ENTRY(HUBPREQ, reg_num,\
|
||||
DCSURF_SURFACE_FLIP_INTERRUPT, SURFACE_FLIP_INT_MASK,\
|
||||
DCSURF_SURFACE_FLIP_INTERRUPT, SURFACE_FLIP_CLEAR),\
|
||||
.funcs = &pflip_irq_info_funcs\
|
||||
}
|
||||
|
||||
#define vupdate_int_entry(reg_num)\
|
||||
[DC_IRQ_SOURCE_VUPDATE1 + reg_num] = {\
|
||||
IRQ_REG_ENTRY(OTG, reg_num,\
|
||||
OTG_GLOBAL_SYNC_STATUS, VUPDATE_INT_EN,\
|
||||
OTG_GLOBAL_SYNC_STATUS, VUPDATE_EVENT_CLEAR),\
|
||||
.funcs = &vblank_irq_info_funcs\
|
||||
}
|
||||
|
||||
#define vblank_int_entry(reg_num)\
|
||||
[DC_IRQ_SOURCE_VBLANK1 + reg_num] = {\
|
||||
IRQ_REG_ENTRY(OTG, reg_num,\
|
||||
OTG_GLOBAL_SYNC_STATUS, VSTARTUP_INT_EN,\
|
||||
OTG_GLOBAL_SYNC_STATUS, VSTARTUP_EVENT_CLEAR),\
|
||||
.funcs = &vblank_irq_info_funcs\
|
||||
}
|
||||
|
||||
#define dummy_irq_entry() \
|
||||
{\
|
||||
.funcs = &dummy_irq_info_funcs\
|
||||
}
|
||||
|
||||
#define i2c_int_entry(reg_num) \
|
||||
[DC_IRQ_SOURCE_I2C_DDC ## reg_num] = dummy_irq_entry()
|
||||
|
||||
#define dp_sink_int_entry(reg_num) \
|
||||
[DC_IRQ_SOURCE_DPSINK ## reg_num] = dummy_irq_entry()
|
||||
|
||||
#define gpio_pad_int_entry(reg_num) \
|
||||
[DC_IRQ_SOURCE_GPIOPAD ## reg_num] = dummy_irq_entry()
|
||||
|
||||
#define dc_underflow_int_entry(reg_num) \
|
||||
[DC_IRQ_SOURCE_DC ## reg_num ## UNDERFLOW] = dummy_irq_entry()
|
||||
|
||||
static const struct irq_source_info_funcs dummy_irq_info_funcs = {
|
||||
.set = dal_irq_service_dummy_set,
|
||||
.ack = dal_irq_service_dummy_ack
|
||||
};
|
||||
|
||||
static const struct irq_source_info
|
||||
irq_source_info_dcn21[DAL_IRQ_SOURCES_NUMBER] = {
|
||||
[DC_IRQ_SOURCE_INVALID] = dummy_irq_entry(),
|
||||
hpd_int_entry(0),
|
||||
hpd_int_entry(1),
|
||||
hpd_int_entry(2),
|
||||
hpd_int_entry(3),
|
||||
hpd_int_entry(4),
|
||||
hpd_rx_int_entry(0),
|
||||
hpd_rx_int_entry(1),
|
||||
hpd_rx_int_entry(2),
|
||||
hpd_rx_int_entry(3),
|
||||
hpd_rx_int_entry(4),
|
||||
i2c_int_entry(1),
|
||||
i2c_int_entry(2),
|
||||
i2c_int_entry(3),
|
||||
i2c_int_entry(4),
|
||||
i2c_int_entry(5),
|
||||
i2c_int_entry(6),
|
||||
dp_sink_int_entry(1),
|
||||
dp_sink_int_entry(2),
|
||||
dp_sink_int_entry(3),
|
||||
dp_sink_int_entry(4),
|
||||
dp_sink_int_entry(5),
|
||||
dp_sink_int_entry(6),
|
||||
[DC_IRQ_SOURCE_TIMER] = dummy_irq_entry(),
|
||||
pflip_int_entry(0),
|
||||
pflip_int_entry(1),
|
||||
pflip_int_entry(2),
|
||||
pflip_int_entry(3),
|
||||
[DC_IRQ_SOURCE_PFLIP5] = dummy_irq_entry(),
|
||||
[DC_IRQ_SOURCE_PFLIP6] = dummy_irq_entry(),
|
||||
[DC_IRQ_SOURCE_PFLIP_UNDERLAY0] = dummy_irq_entry(),
|
||||
gpio_pad_int_entry(0),
|
||||
gpio_pad_int_entry(1),
|
||||
gpio_pad_int_entry(2),
|
||||
gpio_pad_int_entry(3),
|
||||
gpio_pad_int_entry(4),
|
||||
gpio_pad_int_entry(5),
|
||||
gpio_pad_int_entry(6),
|
||||
gpio_pad_int_entry(7),
|
||||
gpio_pad_int_entry(8),
|
||||
gpio_pad_int_entry(9),
|
||||
gpio_pad_int_entry(10),
|
||||
gpio_pad_int_entry(11),
|
||||
gpio_pad_int_entry(12),
|
||||
gpio_pad_int_entry(13),
|
||||
gpio_pad_int_entry(14),
|
||||
gpio_pad_int_entry(15),
|
||||
gpio_pad_int_entry(16),
|
||||
gpio_pad_int_entry(17),
|
||||
gpio_pad_int_entry(18),
|
||||
gpio_pad_int_entry(19),
|
||||
gpio_pad_int_entry(20),
|
||||
gpio_pad_int_entry(21),
|
||||
gpio_pad_int_entry(22),
|
||||
gpio_pad_int_entry(23),
|
||||
gpio_pad_int_entry(24),
|
||||
gpio_pad_int_entry(25),
|
||||
gpio_pad_int_entry(26),
|
||||
gpio_pad_int_entry(27),
|
||||
gpio_pad_int_entry(28),
|
||||
gpio_pad_int_entry(29),
|
||||
gpio_pad_int_entry(30),
|
||||
dc_underflow_int_entry(1),
|
||||
dc_underflow_int_entry(2),
|
||||
dc_underflow_int_entry(3),
|
||||
dc_underflow_int_entry(4),
|
||||
dc_underflow_int_entry(5),
|
||||
dc_underflow_int_entry(6),
|
||||
[DC_IRQ_SOURCE_DMCU_SCP] = dummy_irq_entry(),
|
||||
[DC_IRQ_SOURCE_VBIOS_SW] = dummy_irq_entry(),
|
||||
vupdate_int_entry(0),
|
||||
vupdate_int_entry(1),
|
||||
vupdate_int_entry(2),
|
||||
vupdate_int_entry(3),
|
||||
vupdate_int_entry(4),
|
||||
vupdate_int_entry(5),
|
||||
vblank_int_entry(0),
|
||||
vblank_int_entry(1),
|
||||
vblank_int_entry(2),
|
||||
vblank_int_entry(3),
|
||||
vblank_int_entry(4),
|
||||
vblank_int_entry(5),
|
||||
};
|
||||
|
||||
static const struct irq_service_funcs irq_service_funcs_dcn21 = {
|
||||
.to_dal_irq_source = to_dal_irq_source_dcn21
|
||||
};
|
||||
|
||||
static void construct(
|
||||
struct irq_service *irq_service,
|
||||
struct irq_service_init_data *init_data)
|
||||
{
|
||||
dal_irq_service_construct(irq_service, init_data);
|
||||
|
||||
irq_service->info = irq_source_info_dcn21;
|
||||
irq_service->funcs = &irq_service_funcs_dcn21;
|
||||
}
|
||||
|
||||
struct irq_service *dal_irq_service_dcn21_create(
|
||||
struct irq_service_init_data *init_data)
|
||||
{
|
||||
struct irq_service *irq_service = kzalloc(sizeof(*irq_service),
|
||||
GFP_KERNEL);
|
||||
|
||||
if (!irq_service)
|
||||
return NULL;
|
||||
|
||||
construct(irq_service, init_data);
|
||||
return irq_service;
|
||||
}
|
34
drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.h
Normal file
34
drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2018 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DAL_IRQ_SERVICE_DCN21_H__
|
||||
#define __DAL_IRQ_SERVICE_DCN21_H__
|
||||
|
||||
#include "../irq_service.h"
|
||||
|
||||
struct irq_service *dal_irq_service_dcn21_create(
|
||||
struct irq_service_init_data *init_data);
|
||||
|
||||
#endif
|
@ -162,6 +162,11 @@ enum {
|
||||
#define ASICREV_IS_NAVI12_P(eChipRev) ((eChipRev >= NV_NAVI12_P_A0) && (eChipRev < NV_NAVI14_M_A0))
|
||||
#define ASICREV_IS_NAVI14_M(eChipRev) ((eChipRev >= NV_NAVI14_M_A0) && (eChipRev < NV_UNKNOWN))
|
||||
#endif
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
#define RENOIR_A0 0x91
|
||||
#define DEVICE_ID_RENOIR_1636 0x1636 // Renoir
|
||||
#define ASICREV_IS_RENOIR(eChipRev) ((eChipRev >= RENOIR_A0) && (eChipRev < 0xFF))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ASIC chip ID
|
||||
|
@ -48,6 +48,9 @@ enum dce_version {
|
||||
DCN_VERSION_1_01,
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
|
||||
DCN_VERSION_2_0,
|
||||
#endif
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
DCN_VERSION_2_1,
|
||||
#endif
|
||||
DCN_VERSION_MAX
|
||||
};
|
||||
|
@ -114,25 +114,6 @@ enum ColorimetryYCCDP {
|
||||
ColorimetryYCC_DP_ITU2020YCbCr = 7,
|
||||
};
|
||||
|
||||
void setFieldWithMask(unsigned char *dest, unsigned int mask, unsigned int value)
|
||||
{
|
||||
unsigned int shift = 0;
|
||||
|
||||
if (!mask || !dest)
|
||||
return;
|
||||
|
||||
while (!((mask >> shift) & 1))
|
||||
shift++;
|
||||
|
||||
//reset
|
||||
*dest = *dest & ~mask;
|
||||
//set
|
||||
//dont let value span past mask
|
||||
value = value & (mask >> shift);
|
||||
//insert value
|
||||
*dest = *dest | (value << shift);
|
||||
}
|
||||
|
||||
void mod_build_vsc_infopacket(const struct dc_stream_state *stream,
|
||||
struct dc_info_packet *info_packet)
|
||||
{
|
||||
|
56
drivers/gpu/drm/amd/include/asic_reg/clk/clk_10_0_2_offset.h
Normal file
56
drivers/gpu/drm/amd/include/asic_reg/clk/clk_10_0_2_offset.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 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) 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.
|
||||
*/
|
||||
#ifndef _clk_10_0_2_OFFSET_HEADER
|
||||
#define _clk_10_0_2_OFFSET_HEADER
|
||||
|
||||
|
||||
|
||||
// addressBlock: clk_clk1_0_SmuClkDec
|
||||
// base address: 0x5b800
|
||||
#define mmCLK1_CLK_PLL_REQ 0x000f
|
||||
#define mmCLK1_CLK_PLL_REQ_BASE_IDX 1
|
||||
#define mmCLK1_CLK0_BYPASS_CNTL 0x0049
|
||||
#define mmCLK1_CLK0_BYPASS_CNTL_BASE_IDX 1
|
||||
#define mmCLK1_CLK1_BYPASS_CNTL 0x0053
|
||||
#define mmCLK1_CLK1_BYPASS_CNTL_BASE_IDX 1
|
||||
#define mmCLK1_CLK2_BYPASS_CNTL 0x005d
|
||||
#define mmCLK1_CLK2_BYPASS_CNTL_BASE_IDX 1
|
||||
#define mmCLK1_CLK2_STATUS 0x005e
|
||||
#define mmCLK1_CLK2_STATUS_BASE_IDX 1
|
||||
#define mmCLK1_CLK3_DFS_CNTL 0x005f
|
||||
#define mmCLK1_CLK3_DFS_CNTL_BASE_IDX 1
|
||||
#define mmCLK1_CLK3_DS_CNTL 0x0060
|
||||
#define mmCLK1_CLK3_DS_CNTL_BASE_IDX 1
|
||||
#define mmCLK1_CLK3_ALLOW_DS 0x0061
|
||||
#define mmCLK1_CLK3_ALLOW_DS_BASE_IDX 1
|
||||
#define mmCLK1_CLK3_BYPASS_CNTL 0x0067
|
||||
#define mmCLK1_CLK3_BYPASS_CNTL_BASE_IDX 1
|
||||
#define mmCLK1_CLK0_CURRENT_CNT 0x008a
|
||||
#define mmCLK1_CLK0_CURRENT_CNT_BASE_IDX 1
|
||||
#define mmCLK1_CLK1_CURRENT_CNT 0x008b
|
||||
#define mmCLK1_CLK1_CURRENT_CNT_BASE_IDX 1
|
||||
#define mmCLK1_CLK2_CURRENT_CNT 0x008c
|
||||
#define mmCLK1_CLK2_CURRENT_CNT_BASE_IDX 1
|
||||
#define mmCLK1_CLK3_CURRENT_CNT 0x008d
|
||||
#define mmCLK1_CLK3_CURRENT_CNT_BASE_IDX 1
|
||||
|
||||
|
||||
#endif
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (C) 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) 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.
|
||||
*/
|
||||
#ifndef _clk_10_0_2_SH_MASK_HEADER
|
||||
#define _clk_10_0_2_SH_MASK_HEADER
|
||||
|
||||
|
||||
// addressBlock: clk_clk1_0_SmuClkDec
|
||||
//CLK1_CLK_PLL_REQ
|
||||
#define CLK1_CLK_PLL_REQ__FbMult_int__SHIFT 0x0
|
||||
#define CLK1_CLK_PLL_REQ__PllSpineDiv__SHIFT 0xc
|
||||
#define CLK1_CLK_PLL_REQ__FbMult_frac__SHIFT 0x10
|
||||
#define CLK1_CLK_PLL_REQ__FbMult_int_MASK 0x000001FFL
|
||||
#define CLK1_CLK_PLL_REQ__PllSpineDiv_MASK 0x0000F000L
|
||||
#define CLK1_CLK_PLL_REQ__FbMult_frac_MASK 0xFFFF0000L
|
||||
//CLK1_CLK0_BYPASS_CNTL
|
||||
#define CLK1_CLK0_BYPASS_CNTL__CLK0_BYPASS_SEL__SHIFT 0x0
|
||||
#define CLK1_CLK0_BYPASS_CNTL__CLK0_BYPASS_DIV__SHIFT 0x10
|
||||
#define CLK1_CLK0_BYPASS_CNTL__CLK0_BYPASS_SEL_MASK 0x00000007L
|
||||
#define CLK1_CLK0_BYPASS_CNTL__CLK0_BYPASS_DIV_MASK 0x000F0000L
|
||||
//CLK1_CLK1_BYPASS_CNTL
|
||||
#define CLK1_CLK1_BYPASS_CNTL__CLK1_BYPASS_SEL__SHIFT 0x0
|
||||
#define CLK1_CLK1_BYPASS_CNTL__CLK1_BYPASS_DIV__SHIFT 0x10
|
||||
#define CLK1_CLK1_BYPASS_CNTL__CLK1_BYPASS_SEL_MASK 0x00000007L
|
||||
#define CLK1_CLK1_BYPASS_CNTL__CLK1_BYPASS_DIV_MASK 0x000F0000L
|
||||
//CLK1_CLK2_BYPASS_CNTL
|
||||
#define CLK1_CLK2_BYPASS_CNTL__CLK2_BYPASS_SEL__SHIFT 0x0
|
||||
#define CLK1_CLK2_BYPASS_CNTL__CLK2_BYPASS_DIV__SHIFT 0x10
|
||||
#define CLK1_CLK2_BYPASS_CNTL__CLK2_BYPASS_SEL_MASK 0x00000007L
|
||||
#define CLK1_CLK2_BYPASS_CNTL__CLK2_BYPASS_DIV_MASK 0x000F0000L
|
||||
//CLK1_CLK3_DS_CNTL
|
||||
#define CLK1_CLK3_DS_CNTL__CLK3_DS_DIV_ID__SHIFT 0x0
|
||||
#define CLK1_CLK3_DS_CNTL__CLK3_DS_DIV_ID_MASK 0x00000007L
|
||||
//CLK1_CLK3_ALLOW_DS
|
||||
#define CLK1_CLK3_ALLOW_DS__CLK3_ALLOW_DS__SHIFT 0x0
|
||||
#define CLK1_CLK3_ALLOW_DS__CLK3_ALLOW_DS_MASK 0x00000001L
|
||||
//CLK1_CLK3_BYPASS_CNTL
|
||||
#define CLK1_CLK3_BYPASS_CNTL__CLK3_BYPASS_SEL__SHIFT 0x0
|
||||
#define CLK1_CLK3_BYPASS_CNTL__CLK3_BYPASS_DIV__SHIFT 0x10
|
||||
#define CLK1_CLK3_BYPASS_CNTL__CLK3_BYPASS_SEL_MASK 0x00000007L
|
||||
#define CLK1_CLK3_BYPASS_CNTL__CLK3_BYPASS_DIV_MASK 0x000F0000L
|
||||
//CLK1_CLK0_CURRENT_CNT
|
||||
#define CLK1_CLK0_CURRENT_CNT__CURRENT_COUNT__SHIFT 0x0
|
||||
#define CLK1_CLK0_CURRENT_CNT__CURRENT_COUNT_MASK 0xFFFFFFFFL
|
||||
//CLK1_CLK1_CURRENT_CNT
|
||||
#define CLK1_CLK1_CURRENT_CNT__CURRENT_COUNT__SHIFT 0x0
|
||||
#define CLK1_CLK1_CURRENT_CNT__CURRENT_COUNT_MASK 0xFFFFFFFFL
|
||||
//CLK1_CLK2_CURRENT_CNT
|
||||
#define CLK1_CLK2_CURRENT_CNT__CURRENT_COUNT__SHIFT 0x0
|
||||
#define CLK1_CLK2_CURRENT_CNT__CURRENT_COUNT_MASK 0xFFFFFFFFL
|
||||
//CLK1_CLK3_CURRENT_CNT
|
||||
#define CLK1_CLK3_CURRENT_CNT__CURRENT_COUNT__SHIFT 0x0
|
||||
#define CLK1_CLK3_CURRENT_CNT__CURRENT_COUNT_MASK 0xFFFFFFFFL
|
||||
|
||||
|
||||
#endif
|
13862
drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_2_1_0_offset.h
Normal file
13862
drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_2_1_0_offset.h
Normal file
File diff suppressed because it is too large
Load Diff
56638
drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_2_1_0_sh_mask.h
Normal file
56638
drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_2_1_0_sh_mask.h
Normal file
File diff suppressed because it is too large
Load Diff
565
drivers/gpu/drm/amd/include/asic_reg/dcn/dpcs_2_1_0_offset.h
Normal file
565
drivers/gpu/drm/amd/include/asic_reg/dcn/dpcs_2_1_0_offset.h
Normal file
@ -0,0 +1,565 @@
|
||||
/*
|
||||
* Copyright (C) 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) 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.
|
||||
*/
|
||||
#ifndef _dpcs_2_1_0_OFFSET_HEADER
|
||||
#define _dpcs_2_1_0_OFFSET_HEADER
|
||||
|
||||
|
||||
|
||||
// addressBlock: dpcssys_dpcs0_dpcstx0_dispdec
|
||||
// base address: 0x0
|
||||
#define mmDPCSTX0_DPCSTX_TX_CLOCK_CNTL 0x2928
|
||||
#define mmDPCSTX0_DPCSTX_TX_CLOCK_CNTL_BASE_IDX 2
|
||||
#define mmDPCSTX0_DPCSTX_TX_CNTL 0x2929
|
||||
#define mmDPCSTX0_DPCSTX_TX_CNTL_BASE_IDX 2
|
||||
#define mmDPCSTX0_DPCSTX_CBUS_CNTL 0x292a
|
||||
#define mmDPCSTX0_DPCSTX_CBUS_CNTL_BASE_IDX 2
|
||||
#define mmDPCSTX0_DPCSTX_INTERRUPT_CNTL 0x292b
|
||||
#define mmDPCSTX0_DPCSTX_INTERRUPT_CNTL_BASE_IDX 2
|
||||
#define mmDPCSTX0_DPCSTX_PLL_UPDATE_ADDR 0x292c
|
||||
#define mmDPCSTX0_DPCSTX_PLL_UPDATE_ADDR_BASE_IDX 2
|
||||
#define mmDPCSTX0_DPCSTX_PLL_UPDATE_DATA 0x292d
|
||||
#define mmDPCSTX0_DPCSTX_PLL_UPDATE_DATA_BASE_IDX 2
|
||||
#define mmDPCSTX0_DPCSTX_DEBUG_CONFIG 0x292e
|
||||
#define mmDPCSTX0_DPCSTX_DEBUG_CONFIG_BASE_IDX 2
|
||||
|
||||
|
||||
// addressBlock: dpcssys_dpcs0_rdpcstx0_dispdec
|
||||
// base address: 0x0
|
||||
#define mmRDPCSTX0_RDPCSTX_CNTL 0x2930
|
||||
#define mmRDPCSTX0_RDPCSTX_CNTL_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_CLOCK_CNTL 0x2931
|
||||
#define mmRDPCSTX0_RDPCSTX_CLOCK_CNTL_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_INTERRUPT_CONTROL 0x2932
|
||||
#define mmRDPCSTX0_RDPCSTX_INTERRUPT_CONTROL_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_PLL_UPDATE_DATA 0x2933
|
||||
#define mmRDPCSTX0_RDPCSTX_PLL_UPDATE_DATA_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCS_TX_CR_ADDR 0x2934
|
||||
#define mmRDPCSTX0_RDPCS_TX_CR_ADDR_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCS_TX_CR_DATA 0x2935
|
||||
#define mmRDPCSTX0_RDPCS_TX_CR_DATA_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCS_TX_SRAM_CNTL 0x2936
|
||||
#define mmRDPCSTX0_RDPCS_TX_SRAM_CNTL_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_SCRATCH 0x2937
|
||||
#define mmRDPCSTX0_RDPCSTX_SCRATCH_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_SPARE 0x2938
|
||||
#define mmRDPCSTX0_RDPCSTX_SPARE_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_CNTL2 0x2939
|
||||
#define mmRDPCSTX0_RDPCSTX_CNTL2_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_DMCU_DPALT_DIS_BLOCK_REG 0x293c
|
||||
#define mmRDPCSTX0_RDPCSTX_DMCU_DPALT_DIS_BLOCK_REG_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_DEBUG_CONFIG 0x293d
|
||||
#define mmRDPCSTX0_RDPCSTX_DEBUG_CONFIG_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL0 0x2940
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL0_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL1 0x2941
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL1_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL2 0x2942
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL2_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL3 0x2943
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL3_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL4 0x2944
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL4_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL5 0x2945
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL5_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL6 0x2946
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL6_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL7 0x2947
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL7_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL8 0x2948
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL8_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL9 0x2949
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL9_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL10 0x294a
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL10_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL11 0x294b
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL11_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL12 0x294c
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL12_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL13 0x294d
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL13_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL14 0x294e
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL14_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_FUSE0 0x294f
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_FUSE0_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_FUSE1 0x2950
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_FUSE1_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_FUSE2 0x2951
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_FUSE2_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_FUSE3 0x2952
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_FUSE3_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_RX_LD_VAL 0x2953
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_RX_LD_VAL_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_DMCU_DPALT_PHY_CNTL3 0x2954
|
||||
#define mmRDPCSTX0_RDPCSTX_DMCU_DPALT_PHY_CNTL3_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_DMCU_DPALT_PHY_CNTL6 0x2955
|
||||
#define mmRDPCSTX0_RDPCSTX_DMCU_DPALT_PHY_CNTL6_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_DPALT_CONTROL_REG 0x2956
|
||||
#define mmRDPCSTX0_RDPCSTX_DPALT_CONTROL_REG_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL15 0x2958
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL15_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL16 0x2959
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL16_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL17 0x295a
|
||||
#define mmRDPCSTX0_RDPCSTX_PHY_CNTL17_BASE_IDX 2
|
||||
#define mmRDPCSTX0_RDPCSTX_DEBUG_CONFIG2 0x295b
|
||||
#define mmRDPCSTX0_RDPCSTX_DEBUG_CONFIG2_BASE_IDX 2
|
||||
|
||||
|
||||
// addressBlock: dpcssys_dpcssys_cr0_dispdec
|
||||
// base address: 0x0
|
||||
#define mmDPCSSYS_CR0_DPCSSYS_CR_ADDR 0x2934
|
||||
#define mmDPCSSYS_CR0_DPCSSYS_CR_ADDR_BASE_IDX 2
|
||||
#define mmDPCSSYS_CR0_DPCSSYS_CR_DATA 0x2935
|
||||
#define mmDPCSSYS_CR0_DPCSSYS_CR_DATA_BASE_IDX 2
|
||||
|
||||
|
||||
// addressBlock: dpcssys_dpcs0_dpcstx1_dispdec
|
||||
// base address: 0x360
|
||||
#define mmDPCSTX1_DPCSTX_TX_CLOCK_CNTL 0x2a00
|
||||
#define mmDPCSTX1_DPCSTX_TX_CLOCK_CNTL_BASE_IDX 2
|
||||
#define mmDPCSTX1_DPCSTX_TX_CNTL 0x2a01
|
||||
#define mmDPCSTX1_DPCSTX_TX_CNTL_BASE_IDX 2
|
||||
#define mmDPCSTX1_DPCSTX_CBUS_CNTL 0x2a02
|
||||
#define mmDPCSTX1_DPCSTX_CBUS_CNTL_BASE_IDX 2
|
||||
#define mmDPCSTX1_DPCSTX_INTERRUPT_CNTL 0x2a03
|
||||
#define mmDPCSTX1_DPCSTX_INTERRUPT_CNTL_BASE_IDX 2
|
||||
#define mmDPCSTX1_DPCSTX_PLL_UPDATE_ADDR 0x2a04
|
||||
#define mmDPCSTX1_DPCSTX_PLL_UPDATE_ADDR_BASE_IDX 2
|
||||
#define mmDPCSTX1_DPCSTX_PLL_UPDATE_DATA 0x2a05
|
||||
#define mmDPCSTX1_DPCSTX_PLL_UPDATE_DATA_BASE_IDX 2
|
||||
#define mmDPCSTX1_DPCSTX_DEBUG_CONFIG 0x2a06
|
||||
#define mmDPCSTX1_DPCSTX_DEBUG_CONFIG_BASE_IDX 2
|
||||
|
||||
|
||||
// addressBlock: dpcssys_dpcs0_rdpcstx1_dispdec
|
||||
// base address: 0x360
|
||||
#define mmRDPCSTX1_RDPCSTX_CNTL 0x2a08
|
||||
#define mmRDPCSTX1_RDPCSTX_CNTL_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_CLOCK_CNTL 0x2a09
|
||||
#define mmRDPCSTX1_RDPCSTX_CLOCK_CNTL_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_INTERRUPT_CONTROL 0x2a0a
|
||||
#define mmRDPCSTX1_RDPCSTX_INTERRUPT_CONTROL_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_PLL_UPDATE_DATA 0x2a0b
|
||||
#define mmRDPCSTX1_RDPCSTX_PLL_UPDATE_DATA_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCS_TX_CR_ADDR 0x2a0c
|
||||
#define mmRDPCSTX1_RDPCS_TX_CR_ADDR_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCS_TX_CR_DATA 0x2a0d
|
||||
#define mmRDPCSTX1_RDPCS_TX_CR_DATA_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCS_TX_SRAM_CNTL 0x2a0e
|
||||
#define mmRDPCSTX1_RDPCS_TX_SRAM_CNTL_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_SCRATCH 0x2a0f
|
||||
#define mmRDPCSTX1_RDPCSTX_SCRATCH_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_SPARE 0x2a10
|
||||
#define mmRDPCSTX1_RDPCSTX_SPARE_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_CNTL2 0x2a11
|
||||
#define mmRDPCSTX1_RDPCSTX_CNTL2_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_DMCU_DPALT_DIS_BLOCK_REG 0x2a14
|
||||
#define mmRDPCSTX1_RDPCSTX_DMCU_DPALT_DIS_BLOCK_REG_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_DEBUG_CONFIG 0x2a15
|
||||
#define mmRDPCSTX1_RDPCSTX_DEBUG_CONFIG_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL0 0x2a18
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL0_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL1 0x2a19
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL1_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL2 0x2a1a
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL2_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL3 0x2a1b
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL3_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL4 0x2a1c
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL4_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL5 0x2a1d
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL5_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL6 0x2a1e
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL6_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL7 0x2a1f
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL7_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL8 0x2a20
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL8_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL9 0x2a21
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL9_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL10 0x2a22
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL10_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL11 0x2a23
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL11_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL12 0x2a24
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL12_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL13 0x2a25
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL13_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL14 0x2a26
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL14_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_FUSE0 0x2a27
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_FUSE0_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_FUSE1 0x2a28
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_FUSE1_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_FUSE2 0x2a29
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_FUSE2_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_FUSE3 0x2a2a
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_FUSE3_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_RX_LD_VAL 0x2a2b
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_RX_LD_VAL_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_DMCU_DPALT_PHY_CNTL3 0x2a2c
|
||||
#define mmRDPCSTX1_RDPCSTX_DMCU_DPALT_PHY_CNTL3_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_DMCU_DPALT_PHY_CNTL6 0x2a2d
|
||||
#define mmRDPCSTX1_RDPCSTX_DMCU_DPALT_PHY_CNTL6_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_DPALT_CONTROL_REG 0x2a2e
|
||||
#define mmRDPCSTX1_RDPCSTX_DPALT_CONTROL_REG_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL15 0x2a30
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL15_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL16 0x2a31
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL16_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL17 0x2a32
|
||||
#define mmRDPCSTX1_RDPCSTX_PHY_CNTL17_BASE_IDX 2
|
||||
#define mmRDPCSTX1_RDPCSTX_DEBUG_CONFIG2 0x2a33
|
||||
#define mmRDPCSTX1_RDPCSTX_DEBUG_CONFIG2_BASE_IDX 2
|
||||
|
||||
|
||||
// addressBlock: dpcssys_dpcssys_cr1_dispdec
|
||||
// base address: 0x360
|
||||
#define mmDPCSSYS_CR1_DPCSSYS_CR_ADDR 0x2a0c
|
||||
#define mmDPCSSYS_CR1_DPCSSYS_CR_ADDR_BASE_IDX 2
|
||||
#define mmDPCSSYS_CR1_DPCSSYS_CR_DATA 0x2a0d
|
||||
#define mmDPCSSYS_CR1_DPCSSYS_CR_DATA_BASE_IDX 2
|
||||
|
||||
|
||||
// addressBlock: dpcssys_dpcs0_dpcstx2_dispdec
|
||||
// base address: 0x6c0
|
||||
#define mmDPCSTX2_DPCSTX_TX_CLOCK_CNTL 0x2ad8
|
||||
#define mmDPCSTX2_DPCSTX_TX_CLOCK_CNTL_BASE_IDX 2
|
||||
#define mmDPCSTX2_DPCSTX_TX_CNTL 0x2ad9
|
||||
#define mmDPCSTX2_DPCSTX_TX_CNTL_BASE_IDX 2
|
||||
#define mmDPCSTX2_DPCSTX_CBUS_CNTL 0x2ada
|
||||
#define mmDPCSTX2_DPCSTX_CBUS_CNTL_BASE_IDX 2
|
||||
#define mmDPCSTX2_DPCSTX_INTERRUPT_CNTL 0x2adb
|
||||
#define mmDPCSTX2_DPCSTX_INTERRUPT_CNTL_BASE_IDX 2
|
||||
#define mmDPCSTX2_DPCSTX_PLL_UPDATE_ADDR 0x2adc
|
||||
#define mmDPCSTX2_DPCSTX_PLL_UPDATE_ADDR_BASE_IDX 2
|
||||
#define mmDPCSTX2_DPCSTX_PLL_UPDATE_DATA 0x2add
|
||||
#define mmDPCSTX2_DPCSTX_PLL_UPDATE_DATA_BASE_IDX 2
|
||||
#define mmDPCSTX2_DPCSTX_DEBUG_CONFIG 0x2ade
|
||||
#define mmDPCSTX2_DPCSTX_DEBUG_CONFIG_BASE_IDX 2
|
||||
|
||||
|
||||
// addressBlock: dpcssys_dpcs0_rdpcstx2_dispdec
|
||||
// base address: 0x6c0
|
||||
#define mmRDPCSTX2_RDPCSTX_CNTL 0x2ae0
|
||||
#define mmRDPCSTX2_RDPCSTX_CNTL_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_CLOCK_CNTL 0x2ae1
|
||||
#define mmRDPCSTX2_RDPCSTX_CLOCK_CNTL_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_INTERRUPT_CONTROL 0x2ae2
|
||||
#define mmRDPCSTX2_RDPCSTX_INTERRUPT_CONTROL_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_PLL_UPDATE_DATA 0x2ae3
|
||||
#define mmRDPCSTX2_RDPCSTX_PLL_UPDATE_DATA_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCS_TX_CR_ADDR 0x2ae4
|
||||
#define mmRDPCSTX2_RDPCS_TX_CR_ADDR_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCS_TX_CR_DATA 0x2ae5
|
||||
#define mmRDPCSTX2_RDPCS_TX_CR_DATA_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCS_TX_SRAM_CNTL 0x2ae6
|
||||
#define mmRDPCSTX2_RDPCS_TX_SRAM_CNTL_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_SCRATCH 0x2ae7
|
||||
#define mmRDPCSTX2_RDPCSTX_SCRATCH_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_SPARE 0x2ae8
|
||||
#define mmRDPCSTX2_RDPCSTX_SPARE_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_CNTL2 0x2ae9
|
||||
#define mmRDPCSTX2_RDPCSTX_CNTL2_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_DMCU_DPALT_DIS_BLOCK_REG 0x2aec
|
||||
#define mmRDPCSTX2_RDPCSTX_DMCU_DPALT_DIS_BLOCK_REG_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_DEBUG_CONFIG 0x2aed
|
||||
#define mmRDPCSTX2_RDPCSTX_DEBUG_CONFIG_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL0 0x2af0
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL0_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL1 0x2af1
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL1_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL2 0x2af2
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL2_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL3 0x2af3
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL3_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL4 0x2af4
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL4_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL5 0x2af5
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL5_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL6 0x2af6
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL6_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL7 0x2af7
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL7_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL8 0x2af8
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL8_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL9 0x2af9
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL9_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL10 0x2afa
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL10_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL11 0x2afb
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL11_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL12 0x2afc
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL12_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL13 0x2afd
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL13_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL14 0x2afe
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL14_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_FUSE0 0x2aff
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_FUSE0_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_FUSE1 0x2b00
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_FUSE1_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_FUSE2 0x2b01
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_FUSE2_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_FUSE3 0x2b02
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_FUSE3_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_RX_LD_VAL 0x2b03
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_RX_LD_VAL_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_DMCU_DPALT_PHY_CNTL3 0x2b04
|
||||
#define mmRDPCSTX2_RDPCSTX_DMCU_DPALT_PHY_CNTL3_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_DMCU_DPALT_PHY_CNTL6 0x2b05
|
||||
#define mmRDPCSTX2_RDPCSTX_DMCU_DPALT_PHY_CNTL6_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_DPALT_CONTROL_REG 0x2b06
|
||||
#define mmRDPCSTX2_RDPCSTX_DPALT_CONTROL_REG_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL15 0x2b08
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL15_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL16 0x2b09
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL16_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL17 0x2b0a
|
||||
#define mmRDPCSTX2_RDPCSTX_PHY_CNTL17_BASE_IDX 2
|
||||
#define mmRDPCSTX2_RDPCSTX_DEBUG_CONFIG2 0x2b0b
|
||||
#define mmRDPCSTX2_RDPCSTX_DEBUG_CONFIG2_BASE_IDX 2
|
||||
|
||||
|
||||
// addressBlock: dpcssys_dpcssys_cr2_dispdec
|
||||
// base address: 0x6c0
|
||||
#define mmDPCSSYS_CR2_DPCSSYS_CR_ADDR 0x2ae4
|
||||
#define mmDPCSSYS_CR2_DPCSSYS_CR_ADDR_BASE_IDX 2
|
||||
#define mmDPCSSYS_CR2_DPCSSYS_CR_DATA 0x2ae5
|
||||
#define mmDPCSSYS_CR2_DPCSSYS_CR_DATA_BASE_IDX 2
|
||||
|
||||
|
||||
// addressBlock: dpcssys_dpcs0_dpcstx3_dispdec
|
||||
// base address: 0xa20
|
||||
#define mmDPCSTX3_DPCSTX_TX_CLOCK_CNTL 0x2bb0
|
||||
#define mmDPCSTX3_DPCSTX_TX_CLOCK_CNTL_BASE_IDX 2
|
||||
#define mmDPCSTX3_DPCSTX_TX_CNTL 0x2bb1
|
||||
#define mmDPCSTX3_DPCSTX_TX_CNTL_BASE_IDX 2
|
||||
#define mmDPCSTX3_DPCSTX_CBUS_CNTL 0x2bb2
|
||||
#define mmDPCSTX3_DPCSTX_CBUS_CNTL_BASE_IDX 2
|
||||
#define mmDPCSTX3_DPCSTX_INTERRUPT_CNTL 0x2bb3
|
||||
#define mmDPCSTX3_DPCSTX_INTERRUPT_CNTL_BASE_IDX 2
|
||||
#define mmDPCSTX3_DPCSTX_PLL_UPDATE_ADDR 0x2bb4
|
||||
#define mmDPCSTX3_DPCSTX_PLL_UPDATE_ADDR_BASE_IDX 2
|
||||
#define mmDPCSTX3_DPCSTX_PLL_UPDATE_DATA 0x2bb5
|
||||
#define mmDPCSTX3_DPCSTX_PLL_UPDATE_DATA_BASE_IDX 2
|
||||
#define mmDPCSTX3_DPCSTX_DEBUG_CONFIG 0x2bb6
|
||||
#define mmDPCSTX3_DPCSTX_DEBUG_CONFIG_BASE_IDX 2
|
||||
|
||||
|
||||
// addressBlock: dpcssys_dpcs0_rdpcstx3_dispdec
|
||||
// base address: 0xa20
|
||||
#define mmRDPCSTX3_RDPCSTX_CNTL 0x2bb8
|
||||
#define mmRDPCSTX3_RDPCSTX_CNTL_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_CLOCK_CNTL 0x2bb9
|
||||
#define mmRDPCSTX3_RDPCSTX_CLOCK_CNTL_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_INTERRUPT_CONTROL 0x2bba
|
||||
#define mmRDPCSTX3_RDPCSTX_INTERRUPT_CONTROL_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_PLL_UPDATE_DATA 0x2bbb
|
||||
#define mmRDPCSTX3_RDPCSTX_PLL_UPDATE_DATA_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCS_TX_CR_ADDR 0x2bbc
|
||||
#define mmRDPCSTX3_RDPCS_TX_CR_ADDR_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCS_TX_CR_DATA 0x2bbd
|
||||
#define mmRDPCSTX3_RDPCS_TX_CR_DATA_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCS_TX_SRAM_CNTL 0x2bbe
|
||||
#define mmRDPCSTX3_RDPCS_TX_SRAM_CNTL_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_SCRATCH 0x2bbf
|
||||
#define mmRDPCSTX3_RDPCSTX_SCRATCH_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_SPARE 0x2bc0
|
||||
#define mmRDPCSTX3_RDPCSTX_SPARE_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_CNTL2 0x2bc1
|
||||
#define mmRDPCSTX3_RDPCSTX_CNTL2_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_DMCU_DPALT_DIS_BLOCK_REG 0x2bc4
|
||||
#define mmRDPCSTX3_RDPCSTX_DMCU_DPALT_DIS_BLOCK_REG_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_DEBUG_CONFIG 0x2bc5
|
||||
#define mmRDPCSTX3_RDPCSTX_DEBUG_CONFIG_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL0 0x2bc8
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL0_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL1 0x2bc9
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL1_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL2 0x2bca
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL2_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL3 0x2bcb
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL3_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL4 0x2bcc
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL4_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL5 0x2bcd
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL5_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL6 0x2bce
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL6_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL7 0x2bcf
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL7_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL8 0x2bd0
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL8_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL9 0x2bd1
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL9_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL10 0x2bd2
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL10_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL11 0x2bd3
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL11_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL12 0x2bd4
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL12_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL13 0x2bd5
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL13_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL14 0x2bd6
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL14_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_FUSE0 0x2bd7
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_FUSE0_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_FUSE1 0x2bd8
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_FUSE1_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_FUSE2 0x2bd9
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_FUSE2_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_FUSE3 0x2bda
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_FUSE3_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_RX_LD_VAL 0x2bdb
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_RX_LD_VAL_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_DMCU_DPALT_PHY_CNTL3 0x2bdc
|
||||
#define mmRDPCSTX3_RDPCSTX_DMCU_DPALT_PHY_CNTL3_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_DMCU_DPALT_PHY_CNTL6 0x2bdd
|
||||
#define mmRDPCSTX3_RDPCSTX_DMCU_DPALT_PHY_CNTL6_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_DPALT_CONTROL_REG 0x2bde
|
||||
#define mmRDPCSTX3_RDPCSTX_DPALT_CONTROL_REG_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL15 0x2be0
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL15_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL16 0x2be1
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL16_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL17 0x2be2
|
||||
#define mmRDPCSTX3_RDPCSTX_PHY_CNTL17_BASE_IDX 2
|
||||
#define mmRDPCSTX3_RDPCSTX_DEBUG_CONFIG2 0x2be3
|
||||
#define mmRDPCSTX3_RDPCSTX_DEBUG_CONFIG2_BASE_IDX 2
|
||||
|
||||
|
||||
// addressBlock: dpcssys_dpcssys_cr3_dispdec
|
||||
// base address: 0xa20
|
||||
#define mmDPCSSYS_CR3_DPCSSYS_CR_ADDR 0x2bbc
|
||||
#define mmDPCSSYS_CR3_DPCSSYS_CR_ADDR_BASE_IDX 2
|
||||
#define mmDPCSSYS_CR3_DPCSSYS_CR_DATA 0x2bbd
|
||||
#define mmDPCSSYS_CR3_DPCSSYS_CR_DATA_BASE_IDX 2
|
||||
|
||||
|
||||
// addressBlock: dpcssys_dpcs0_dpcstx4_dispdec
|
||||
// base address: 0xd80
|
||||
#define mmDPCSTX4_DPCSTX_TX_CLOCK_CNTL 0x2c88
|
||||
#define mmDPCSTX4_DPCSTX_TX_CLOCK_CNTL_BASE_IDX 2
|
||||
#define mmDPCSTX4_DPCSTX_TX_CNTL 0x2c89
|
||||
#define mmDPCSTX4_DPCSTX_TX_CNTL_BASE_IDX 2
|
||||
#define mmDPCSTX4_DPCSTX_CBUS_CNTL 0x2c8a
|
||||
#define mmDPCSTX4_DPCSTX_CBUS_CNTL_BASE_IDX 2
|
||||
#define mmDPCSTX4_DPCSTX_INTERRUPT_CNTL 0x2c8b
|
||||
#define mmDPCSTX4_DPCSTX_INTERRUPT_CNTL_BASE_IDX 2
|
||||
#define mmDPCSTX4_DPCSTX_PLL_UPDATE_ADDR 0x2c8c
|
||||
#define mmDPCSTX4_DPCSTX_PLL_UPDATE_ADDR_BASE_IDX 2
|
||||
#define mmDPCSTX4_DPCSTX_PLL_UPDATE_DATA 0x2c8d
|
||||
#define mmDPCSTX4_DPCSTX_PLL_UPDATE_DATA_BASE_IDX 2
|
||||
#define mmDPCSTX4_DPCSTX_DEBUG_CONFIG 0x2c8e
|
||||
#define mmDPCSTX4_DPCSTX_DEBUG_CONFIG_BASE_IDX 2
|
||||
|
||||
|
||||
// addressBlock: dpcssys_dpcs0_rdpcstx4_dispdec
|
||||
// base address: 0xd80
|
||||
#define mmRDPCSTX4_RDPCSTX_CNTL 0x2c90
|
||||
#define mmRDPCSTX4_RDPCSTX_CNTL_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_CLOCK_CNTL 0x2c91
|
||||
#define mmRDPCSTX4_RDPCSTX_CLOCK_CNTL_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_INTERRUPT_CONTROL 0x2c92
|
||||
#define mmRDPCSTX4_RDPCSTX_INTERRUPT_CONTROL_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_PLL_UPDATE_DATA 0x2c93
|
||||
#define mmRDPCSTX4_RDPCSTX_PLL_UPDATE_DATA_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCS_TX_CR_ADDR 0x2c94
|
||||
#define mmRDPCSTX4_RDPCS_TX_CR_ADDR_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCS_TX_CR_DATA 0x2c95
|
||||
#define mmRDPCSTX4_RDPCS_TX_CR_DATA_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCS_TX_SRAM_CNTL 0x2c96
|
||||
#define mmRDPCSTX4_RDPCS_TX_SRAM_CNTL_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_SCRATCH 0x2c97
|
||||
#define mmRDPCSTX4_RDPCSTX_SCRATCH_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_SPARE 0x2c98
|
||||
#define mmRDPCSTX4_RDPCSTX_SPARE_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_CNTL2 0x2c99
|
||||
#define mmRDPCSTX4_RDPCSTX_CNTL2_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_DMCU_DPALT_DIS_BLOCK_REG 0x2c9c
|
||||
#define mmRDPCSTX4_RDPCSTX_DMCU_DPALT_DIS_BLOCK_REG_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_DEBUG_CONFIG 0x2c9d
|
||||
#define mmRDPCSTX4_RDPCSTX_DEBUG_CONFIG_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL0 0x2ca0
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL0_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL1 0x2ca1
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL1_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL2 0x2ca2
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL2_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL3 0x2ca3
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL3_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL4 0x2ca4
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL4_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL5 0x2ca5
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL5_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL6 0x2ca6
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL6_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL7 0x2ca7
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL7_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL8 0x2ca8
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL8_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL9 0x2ca9
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL9_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL10 0x2caa
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL10_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL11 0x2cab
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL11_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL12 0x2cac
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL12_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL13 0x2cad
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL13_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL14 0x2cae
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL14_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_FUSE0 0x2caf
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_FUSE0_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_FUSE1 0x2cb0
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_FUSE1_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_FUSE2 0x2cb1
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_FUSE2_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_FUSE3 0x2cb2
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_FUSE3_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_RX_LD_VAL 0x2cb3
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_RX_LD_VAL_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_DMCU_DPALT_PHY_CNTL3 0x2cb4
|
||||
#define mmRDPCSTX4_RDPCSTX_DMCU_DPALT_PHY_CNTL3_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_DMCU_DPALT_PHY_CNTL6 0x2cb5
|
||||
#define mmRDPCSTX4_RDPCSTX_DMCU_DPALT_PHY_CNTL6_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_DPALT_CONTROL_REG 0x2cb6
|
||||
#define mmRDPCSTX4_RDPCSTX_DPALT_CONTROL_REG_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL15 0x2cb8
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL15_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL16 0x2cb9
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL16_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL17 0x2cba
|
||||
#define mmRDPCSTX4_RDPCSTX_PHY_CNTL17_BASE_IDX 2
|
||||
#define mmRDPCSTX4_RDPCSTX_DEBUG_CONFIG2 0x2cbb
|
||||
#define mmRDPCSTX4_RDPCSTX_DEBUG_CONFIG2_BASE_IDX 2
|
||||
|
||||
|
||||
// addressBlock: dpcssys_dpcssys_cr4_dispdec
|
||||
// base address: 0xd80
|
||||
#define mmDPCSSYS_CR4_DPCSSYS_CR_ADDR 0x2c94
|
||||
#define mmDPCSSYS_CR4_DPCSSYS_CR_ADDR_BASE_IDX 2
|
||||
#define mmDPCSSYS_CR4_DPCSSYS_CR_DATA 0x2c95
|
||||
#define mmDPCSSYS_CR4_DPCSSYS_CR_DATA_BASE_IDX 2
|
||||
|
||||
#endif
|
3430
drivers/gpu/drm/amd/include/asic_reg/dcn/dpcs_2_1_0_sh_mask.h
Normal file
3430
drivers/gpu/drm/amd/include/asic_reg/dcn/dpcs_2_1_0_sh_mask.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -1109,7 +1109,11 @@
|
||||
#define IH_CID_REMAP_DATA__CLIENT_ID_REMAP_MASK 0x00FF0000L
|
||||
//IH_CHICKEN
|
||||
#define IH_CHICKEN__ACTIVE_FCN_ID_PROT_ENABLE__SHIFT 0x0
|
||||
#define IH_CHICKEN__MC_SPACE_FBPA_ENABLE__SHIFT 0x3
|
||||
#define IH_CHICKEN__MC_SPACE_GPA_ENABLE__SHIFT 0x4
|
||||
#define IH_CHICKEN__ACTIVE_FCN_ID_PROT_ENABLE_MASK 0x00000001L
|
||||
#define IH_CHICKEN__MC_SPACE_FBPA_ENABLE_MASK 0x00000008L
|
||||
#define IH_CHICKEN__MC_SPACE_GPA_ENABLE_MASK 0x00000010L
|
||||
//IH_MMHUB_CNTL
|
||||
#define IH_MMHUB_CNTL__UNITID__SHIFT 0x0
|
||||
#define IH_MMHUB_CNTL__IV_TLVL__SHIFT 0x8
|
||||
|
@ -29,6 +29,98 @@
|
||||
#define mmSMUSVI0_TEL_PLANE0_BASE_IDX 0
|
||||
#define mmSMUIO_MCM_CONFIG 0x0024
|
||||
#define mmSMUIO_MCM_CONFIG_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_CON 0x0040
|
||||
#define mmCKSVII2C_IC_CON_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_TAR 0x0041
|
||||
#define mmCKSVII2C_IC_TAR_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_SAR 0x0042
|
||||
#define mmCKSVII2C_IC_SAR_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_HS_MADDR 0x0043
|
||||
#define mmCKSVII2C_IC_HS_MADDR_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_DATA_CMD 0x0044
|
||||
#define mmCKSVII2C_IC_DATA_CMD_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_SS_SCL_HCNT 0x0045
|
||||
#define mmCKSVII2C_IC_SS_SCL_HCNT_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_SS_SCL_LCNT 0x0046
|
||||
#define mmCKSVII2C_IC_SS_SCL_LCNT_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_FS_SCL_HCNT 0x0047
|
||||
#define mmCKSVII2C_IC_FS_SCL_HCNT_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_FS_SCL_LCNT 0x0048
|
||||
#define mmCKSVII2C_IC_FS_SCL_LCNT_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_HS_SCL_HCNT 0x0049
|
||||
#define mmCKSVII2C_IC_HS_SCL_HCNT_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_HS_SCL_LCNT 0x004a
|
||||
#define mmCKSVII2C_IC_HS_SCL_LCNT_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_INTR_STAT 0x004b
|
||||
#define mmCKSVII2C_IC_INTR_STAT_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_INTR_MASK 0x004c
|
||||
#define mmCKSVII2C_IC_INTR_MASK_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_RAW_INTR_STAT 0x004d
|
||||
#define mmCKSVII2C_IC_RAW_INTR_STAT_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_RX_TL 0x004e
|
||||
#define mmCKSVII2C_IC_RX_TL_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_TX_TL 0x004f
|
||||
#define mmCKSVII2C_IC_TX_TL_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_CLR_INTR 0x0050
|
||||
#define mmCKSVII2C_IC_CLR_INTR_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_CLR_RX_UNDER 0x0051
|
||||
#define mmCKSVII2C_IC_CLR_RX_UNDER_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_CLR_RX_OVER 0x0052
|
||||
#define mmCKSVII2C_IC_CLR_RX_OVER_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_CLR_TX_OVER 0x0053
|
||||
#define mmCKSVII2C_IC_CLR_TX_OVER_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_CLR_RD_REQ 0x0054
|
||||
#define mmCKSVII2C_IC_CLR_RD_REQ_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_CLR_TX_ABRT 0x0055
|
||||
#define mmCKSVII2C_IC_CLR_TX_ABRT_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_CLR_RX_DONE 0x0056
|
||||
#define mmCKSVII2C_IC_CLR_RX_DONE_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_CLR_ACTIVITY 0x0057
|
||||
#define mmCKSVII2C_IC_CLR_ACTIVITY_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_CLR_STOP_DET 0x0058
|
||||
#define mmCKSVII2C_IC_CLR_STOP_DET_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_CLR_START_DET 0x0059
|
||||
#define mmCKSVII2C_IC_CLR_START_DET_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_CLR_GEN_CALL 0x005a
|
||||
#define mmCKSVII2C_IC_CLR_GEN_CALL_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_ENABLE 0x005b
|
||||
#define mmCKSVII2C_IC_ENABLE_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_STATUS 0x005c
|
||||
#define mmCKSVII2C_IC_STATUS_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_TXFLR 0x005d
|
||||
#define mmCKSVII2C_IC_TXFLR_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_RXFLR 0x005e
|
||||
#define mmCKSVII2C_IC_RXFLR_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_SDA_HOLD 0x005f
|
||||
#define mmCKSVII2C_IC_SDA_HOLD_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_TX_ABRT_SOURCE 0x0060
|
||||
#define mmCKSVII2C_IC_TX_ABRT_SOURCE_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_SLV_DATA_NACK_ONLY 0x0061
|
||||
#define mmCKSVII2C_IC_SLV_DATA_NACK_ONLY_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_DMA_CR 0x0062
|
||||
#define mmCKSVII2C_IC_DMA_CR_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_DMA_TDLR 0x0063
|
||||
#define mmCKSVII2C_IC_DMA_TDLR_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_DMA_RDLR 0x0064
|
||||
#define mmCKSVII2C_IC_DMA_RDLR_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_SDA_SETUP 0x0065
|
||||
#define mmCKSVII2C_IC_SDA_SETUP_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_ACK_GENERAL_CALL 0x0066
|
||||
#define mmCKSVII2C_IC_ACK_GENERAL_CALL_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_ENABLE_STATUS 0x0067
|
||||
#define mmCKSVII2C_IC_ENABLE_STATUS_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_FS_SPKLEN 0x0068
|
||||
#define mmCKSVII2C_IC_FS_SPKLEN_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_HS_SPKLEN 0x0069
|
||||
#define mmCKSVII2C_IC_HS_SPKLEN_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_CLR_RESTART_DET 0x006a
|
||||
#define mmCKSVII2C_IC_CLR_RESTART_DET_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_COMP_PARAM_1 0x006b
|
||||
#define mmCKSVII2C_IC_COMP_PARAM_1_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_COMP_VERSION 0x006c
|
||||
#define mmCKSVII2C_IC_COMP_VERSION_BASE_IDX 0
|
||||
#define mmCKSVII2C_IC_COMP_TYPE 0x006d
|
||||
#define mmCKSVII2C_IC_COMP_TYPE_BASE_IDX 0
|
||||
#define mmSMUIO_MP_RESET_INTR 0x00c1
|
||||
#define mmSMUIO_MP_RESET_INTR_BASE_IDX 0
|
||||
#define mmSMUIO_SOC_HALT 0x00c2
|
||||
|
@ -37,6 +37,237 @@
|
||||
#define SMUIO_MCM_CONFIG__PKG_TYPE_MASK 0x0000001CL
|
||||
#define SMUIO_MCM_CONFIG__SOCKET_ID_MASK 0x00000020L
|
||||
#define SMUIO_MCM_CONFIG__PKG_SUBTYPE_MASK 0x000000C0L
|
||||
//CKSVII2C_IC_CON
|
||||
#define CKSVII2C_IC_CON__IC_MASTER_MODE__SHIFT 0x0
|
||||
#define CKSVII2C_IC_CON__IC_MAX_SPEED_MODE__SHIFT 0x1
|
||||
#define CKSVII2C_IC_CON__IC_10BITADDR_SLAVE__SHIFT 0x3
|
||||
#define CKSVII2C_IC_CON__IC_10BITADDR_MASTER__SHIFT 0x4
|
||||
#define CKSVII2C_IC_CON__IC_RESTART_EN__SHIFT 0x5
|
||||
#define CKSVII2C_IC_CON__IC_SLAVE_DISABLE__SHIFT 0x6
|
||||
#define CKSVII2C_IC_CON__STOP_DET_IFADDRESSED__SHIFT 0x7
|
||||
#define CKSVII2C_IC_CON__TX_EMPTY_CTRL__SHIFT 0x8
|
||||
#define CKSVII2C_IC_CON__RX_FIFO_FULL_HLD_CTRL__SHIFT 0x9
|
||||
#define CKSVII2C_IC_CON__IC_MASTER_MODE_MASK 0x00000001L
|
||||
#define CKSVII2C_IC_CON__IC_MAX_SPEED_MODE_MASK 0x00000006L
|
||||
#define CKSVII2C_IC_CON__IC_10BITADDR_SLAVE_MASK 0x00000008L
|
||||
#define CKSVII2C_IC_CON__IC_10BITADDR_MASTER_MASK 0x00000010L
|
||||
#define CKSVII2C_IC_CON__IC_RESTART_EN_MASK 0x00000020L
|
||||
#define CKSVII2C_IC_CON__IC_SLAVE_DISABLE_MASK 0x00000040L
|
||||
#define CKSVII2C_IC_CON__STOP_DET_IFADDRESSED_MASK 0x00000080L
|
||||
#define CKSVII2C_IC_CON__TX_EMPTY_CTRL_MASK 0x00000100L
|
||||
#define CKSVII2C_IC_CON__RX_FIFO_FULL_HLD_CTRL_MASK 0x00000200L
|
||||
//CKSVII2C_IC_TAR
|
||||
#define CKSVII2C_IC_TAR__IC_TAR__SHIFT 0x0
|
||||
#define CKSVII2C_IC_TAR__GC_OR_START__SHIFT 0xa
|
||||
#define CKSVII2C_IC_TAR__SPECIAL__SHIFT 0xb
|
||||
#define CKSVII2C_IC_TAR__IC_10BITADDR_MASTER__SHIFT 0xc
|
||||
#define CKSVII2C_IC_TAR__IC_TAR_MASK 0x000003FFL
|
||||
#define CKSVII2C_IC_TAR__GC_OR_START_MASK 0x00000400L
|
||||
#define CKSVII2C_IC_TAR__SPECIAL_MASK 0x00000800L
|
||||
#define CKSVII2C_IC_TAR__IC_10BITADDR_MASTER_MASK 0x00001000L
|
||||
//CKSVII2C_IC_SAR
|
||||
#define CKSVII2C_IC_SAR__IC_SAR__SHIFT 0x0
|
||||
#define CKSVII2C_IC_SAR__IC_SAR_MASK 0x000003FFL
|
||||
//CKSVII2C_IC_HS_MADDR
|
||||
#define CKSVII2C_IC_HS_MADDR__IC_HS_MADDR__SHIFT 0x0
|
||||
#define CKSVII2C_IC_HS_MADDR__IC_HS_MADDR_MASK 0x00000007L
|
||||
//CKSVII2C_IC_DATA_CMD
|
||||
#define CKSVII2C_IC_DATA_CMD__DAT__SHIFT 0x0
|
||||
#define CKSVII2C_IC_DATA_CMD__CMD__SHIFT 0x8
|
||||
#define CKSVII2C_IC_DATA_CMD__STOP__SHIFT 0x9
|
||||
#define CKSVII2C_IC_DATA_CMD__RESTART__SHIFT 0xa
|
||||
#define CKSVII2C_IC_DATA_CMD__DAT_MASK 0x000000FFL
|
||||
#define CKSVII2C_IC_DATA_CMD__CMD_MASK 0x00000100L
|
||||
#define CKSVII2C_IC_DATA_CMD__STOP_MASK 0x00000200L
|
||||
#define CKSVII2C_IC_DATA_CMD__RESTART_MASK 0x00000400L
|
||||
//CKSVII2C_IC_SS_SCL_HCNT
|
||||
#define CKSVII2C_IC_SS_SCL_HCNT__IC_SS_SCL_HCNT__SHIFT 0x0
|
||||
#define CKSVII2C_IC_SS_SCL_HCNT__IC_SS_SCL_HCNT_MASK 0x0000FFFFL
|
||||
//CKSVII2C_IC_SS_SCL_LCNT
|
||||
#define CKSVII2C_IC_SS_SCL_LCNT__IC_SS_SCL_LCNT__SHIFT 0x0
|
||||
#define CKSVII2C_IC_SS_SCL_LCNT__IC_SS_SCL_LCNT_MASK 0x0000FFFFL
|
||||
//CKSVII2C_IC_FS_SCL_HCNT
|
||||
#define CKSVII2C_IC_FS_SCL_HCNT__IC_FS_SCL_HCNT__SHIFT 0x0
|
||||
#define CKSVII2C_IC_FS_SCL_HCNT__IC_FS_SCL_HCNT_MASK 0x0000FFFFL
|
||||
//CKSVII2C_IC_FS_SCL_LCNT
|
||||
#define CKSVII2C_IC_FS_SCL_LCNT__IC_FS_SCL_LCNT__SHIFT 0x0
|
||||
#define CKSVII2C_IC_FS_SCL_LCNT__IC_FS_SCL_LCNT_MASK 0x0000FFFFL
|
||||
//CKSVII2C_IC_HS_SCL_HCNT
|
||||
#define CKSVII2C_IC_HS_SCL_HCNT__IC_HS_SCL_HCNT__SHIFT 0x0
|
||||
#define CKSVII2C_IC_HS_SCL_HCNT__IC_HS_SCL_HCNT_MASK 0x0000FFFFL
|
||||
//CKSVII2C_IC_HS_SCL_LCNT
|
||||
#define CKSVII2C_IC_HS_SCL_LCNT__IC_HS_SCL_LCNT__SHIFT 0x0
|
||||
#define CKSVII2C_IC_HS_SCL_LCNT__IC_HS_SCL_LCNT_MASK 0x0000FFFFL
|
||||
//CKSVII2C_IC_INTR_STAT
|
||||
#define CKSVII2C_IC_INTR_STAT__R_RX_UNDER__SHIFT 0x0
|
||||
#define CKSVII2C_IC_INTR_STAT__R_RX_OVER__SHIFT 0x1
|
||||
#define CKSVII2C_IC_INTR_STAT__R_RX_FULL__SHIFT 0x2
|
||||
#define CKSVII2C_IC_INTR_STAT__R_TX_OVER__SHIFT 0x3
|
||||
#define CKSVII2C_IC_INTR_STAT__R_TX_EMPTY__SHIFT 0x4
|
||||
#define CKSVII2C_IC_INTR_STAT__R_RD_REQ__SHIFT 0x5
|
||||
#define CKSVII2C_IC_INTR_STAT__R_TX_ABRT__SHIFT 0x6
|
||||
#define CKSVII2C_IC_INTR_STAT__R_RX_DONE__SHIFT 0x7
|
||||
#define CKSVII2C_IC_INTR_STAT__R_ACTIVITY__SHIFT 0x8
|
||||
#define CKSVII2C_IC_INTR_STAT__R_STOP_DET__SHIFT 0x9
|
||||
#define CKSVII2C_IC_INTR_STAT__R_START_DET__SHIFT 0xa
|
||||
#define CKSVII2C_IC_INTR_STAT__R_GEN_CALL__SHIFT 0xb
|
||||
#define CKSVII2C_IC_INTR_STAT__R_RESTART_DET__SHIFT 0xc
|
||||
#define CKSVII2C_IC_INTR_STAT__R_MST_ON_HOLD__SHIFT 0xd
|
||||
#define CKSVII2C_IC_INTR_STAT__R_RX_UNDER_MASK 0x00000001L
|
||||
#define CKSVII2C_IC_INTR_STAT__R_RX_OVER_MASK 0x00000002L
|
||||
#define CKSVII2C_IC_INTR_STAT__R_RX_FULL_MASK 0x00000004L
|
||||
#define CKSVII2C_IC_INTR_STAT__R_TX_OVER_MASK 0x00000008L
|
||||
#define CKSVII2C_IC_INTR_STAT__R_TX_EMPTY_MASK 0x00000010L
|
||||
#define CKSVII2C_IC_INTR_STAT__R_RD_REQ_MASK 0x00000020L
|
||||
#define CKSVII2C_IC_INTR_STAT__R_TX_ABRT_MASK 0x00000040L
|
||||
#define CKSVII2C_IC_INTR_STAT__R_RX_DONE_MASK 0x00000080L
|
||||
#define CKSVII2C_IC_INTR_STAT__R_ACTIVITY_MASK 0x00000100L
|
||||
#define CKSVII2C_IC_INTR_STAT__R_STOP_DET_MASK 0x00000200L
|
||||
#define CKSVII2C_IC_INTR_STAT__R_START_DET_MASK 0x00000400L
|
||||
#define CKSVII2C_IC_INTR_STAT__R_GEN_CALL_MASK 0x00000800L
|
||||
#define CKSVII2C_IC_INTR_STAT__R_RESTART_DET_MASK 0x00001000L
|
||||
#define CKSVII2C_IC_INTR_STAT__R_MST_ON_HOLD_MASK 0x00002000L
|
||||
//CKSVII2C_IC_INTR_MASK
|
||||
#define CKSVII2C_IC_INTR_MASK__M_RX_UNDER__SHIFT 0x0
|
||||
#define CKSVII2C_IC_INTR_MASK__M_RX_OVER__SHIFT 0x1
|
||||
#define CKSVII2C_IC_INTR_MASK__M_RX_FULL__SHIFT 0x2
|
||||
#define CKSVII2C_IC_INTR_MASK__M_TX_OVER__SHIFT 0x3
|
||||
#define CKSVII2C_IC_INTR_MASK__M_TX_EMPTY__SHIFT 0x4
|
||||
#define CKSVII2C_IC_INTR_MASK__M_RD_REQ__SHIFT 0x5
|
||||
#define CKSVII2C_IC_INTR_MASK__M_TX_ABRT__SHIFT 0x6
|
||||
#define CKSVII2C_IC_INTR_MASK__M_RX_DONE__SHIFT 0x7
|
||||
#define CKSVII2C_IC_INTR_MASK__M_ACTIVITY__SHIFT 0x8
|
||||
#define CKSVII2C_IC_INTR_MASK__M_STOP_DET__SHIFT 0x9
|
||||
#define CKSVII2C_IC_INTR_MASK__M_START_DET__SHIFT 0xa
|
||||
#define CKSVII2C_IC_INTR_MASK__M_GEN_CALL__SHIFT 0xb
|
||||
#define CKSVII2C_IC_INTR_MASK__M_RESTART_DET__SHIFT 0xc
|
||||
#define CKSVII2C_IC_INTR_MASK__M_MST_ON_HOLD__SHIFT 0xd
|
||||
#define CKSVII2C_IC_INTR_MASK__M_RX_UNDER_MASK 0x00000001L
|
||||
#define CKSVII2C_IC_INTR_MASK__M_RX_OVER_MASK 0x00000002L
|
||||
#define CKSVII2C_IC_INTR_MASK__M_RX_FULL_MASK 0x00000004L
|
||||
#define CKSVII2C_IC_INTR_MASK__M_TX_OVER_MASK 0x00000008L
|
||||
#define CKSVII2C_IC_INTR_MASK__M_TX_EMPTY_MASK 0x00000010L
|
||||
#define CKSVII2C_IC_INTR_MASK__M_RD_REQ_MASK 0x00000020L
|
||||
#define CKSVII2C_IC_INTR_MASK__M_TX_ABRT_MASK 0x00000040L
|
||||
#define CKSVII2C_IC_INTR_MASK__M_RX_DONE_MASK 0x00000080L
|
||||
#define CKSVII2C_IC_INTR_MASK__M_ACTIVITY_MASK 0x00000100L
|
||||
#define CKSVII2C_IC_INTR_MASK__M_STOP_DET_MASK 0x00000200L
|
||||
#define CKSVII2C_IC_INTR_MASK__M_START_DET_MASK 0x00000400L
|
||||
#define CKSVII2C_IC_INTR_MASK__M_GEN_CALL_MASK 0x00000800L
|
||||
#define CKSVII2C_IC_INTR_MASK__M_RESTART_DET_MASK 0x00001000L
|
||||
#define CKSVII2C_IC_INTR_MASK__M_MST_ON_HOLD_MASK 0x00002000L
|
||||
//CKSVII2C_IC_RAW_INTR_STAT
|
||||
#define CKSVII2C_IC_RAW_INTR_STAT__R_RX_UNDER__SHIFT 0x0
|
||||
#define CKSVII2C_IC_RAW_INTR_STAT__R_RX_OVER__SHIFT 0x1
|
||||
#define CKSVII2C_IC_RAW_INTR_STAT__R_RX_FULL__SHIFT 0x2
|
||||
#define CKSVII2C_IC_RAW_INTR_STAT__R_TX_OVER__SHIFT 0x3
|
||||
#define CKSVII2C_IC__RAW_INTR_STAT__R_TX_EMPTY__SHIFT 0x4
|
||||
#define CKSVII2C_IC_RAW_INTR_STAT__R_RD_REQ__SHIFT 0x5
|
||||
#define CKSVII2C_IC_RAW_INTR_STAT__R_TX_ABRT__SHIFT 0x6
|
||||
#define CKSVII2C_IC_RAW_INTR_STAT__R_RX_DONE__SHIFT 0x7
|
||||
#define CKSVII2C_IC_RAW_INTR_STAT__R_ACTIVITY__SHIFT 0x8
|
||||
#define CKSVII2C_IC_RAW_INTR_STAT__R_STOP_DET__SHIFT 0x9
|
||||
#define CKSVII2C_IC_RAW_INTR_STAT__R_START_DET__SHIFT 0xa
|
||||
#define CKSVII2C_IC_RAW_INTR_STAT__R_GEN_CALL__SHIFT 0xb
|
||||
#define CKSVII2C_IC_RAW_INTR_STAT__R_RESTART_DET__SHIFT 0xc
|
||||
#define CKSVII2C_IC_RAW_INTR_STAT__R_MST_ON_HOLD__SHIFT 0xd
|
||||
#define CKSVII2C_IC_RAW_INTR_STAT__R_RX_UNDER_MASK 0x00000001L
|
||||
#define CKSVII2C_IC_RAW_INTR_STAT__R_RX_OVER_MASK 0x00000002L
|
||||
#define CKSVII2C_IC_RAW_INTR_STAT__R_RX_FULL_MASK 0x00000004L
|
||||
#define CKSVII2C_IC_RAW_INTR_STAT__R_TX_OVER_MASK 0x00000008L
|
||||
#define CKSVII2C_IC_RAW_INTR_STAT__R_TX_EMPTY_MASK 0x00000010L
|
||||
#define CKSVII2C_IC_RAW_INTR_STAT__R_RD_REQ_MASK 0x00000020L
|
||||
#define CKSVII2C_IC_RAW_INTR_STAT__R_TX_ABRT_MASK 0x00000040L
|
||||
#define CKSVII2C_IC_RAW_INTR_STAT__R_RX_DONE_MASK 0x00000080L
|
||||
#define CKSVII2C_IC_RAW_INTR_STAT__R_ACTIVITY_MASK 0x00000100L
|
||||
#define CKSVII2C_IC_RAW_INTR_STAT__R_STOP_DET_MASK 0x00000200L
|
||||
#define CKSVII2C_IC_RAW_INTR_STAT__R_START_DET_MASK 0x00000400L
|
||||
#define CKSVII2C_IC_RAW_INTR_STAT__R_GEN_CALL_MASK 0x00000800L
|
||||
#define CKSVII2C_IC_RAW_INTR_STAT__R_RESTART_DET_MASK 0x00001000L
|
||||
#define CKSVII2C_IC_RAW_INTR_STAT__R_MST_ON_HOLD_MASK 0x00002000L
|
||||
//CKSVII2C_IC_RX_TL
|
||||
//CKSVII2C_IC_TX_TL
|
||||
//CKSVII2C_IC_CLR_INTR
|
||||
//CKSVII2C_IC_CLR_RX_UNDER
|
||||
//CKSVII2C_IC_CLR_RX_OVER
|
||||
//CKSVII2C_IC_CLR_TX_OVER
|
||||
//CKSVII2C_IC_CLR_RD_REQ
|
||||
//CKSVII2C_IC_CLR_TX_ABRT
|
||||
//CKSVII2C_IC_CLR_RX_DONE
|
||||
//CKSVII2C_IC_CLR_ACTIVITY
|
||||
#define CKSVII2C_IC_CLR_ACTIVITY__CLR_ACTIVITY__SHIFT 0x0
|
||||
#define CKSVII2C_IC_CLR_ACTIVITY__CLR_ACTIVITY_MASK 0x00000001L
|
||||
//CKSVII2C_IC_CLR_STOP_DET
|
||||
//CKSVII2C_IC_CLR_START_DET
|
||||
//CKSVII2C_IC_CLR_GEN_CALL
|
||||
//CKSVII2C_IC_ENABLE
|
||||
#define CKSVII2C_IC_ENABLE__ENABLE__SHIFT 0x0
|
||||
#define CKSVII2C_IC_ENABLE__ABORT__SHIFT 0x1
|
||||
#define CKSVII2C_IC_ENABLE__ENABLE_MASK 0x00000001L
|
||||
#define CKSVII2C_IC_ENABLE__ABORT_MASK 0x00000002L
|
||||
//CKSVII2C_IC_STATUS
|
||||
#define CKSVII2C_IC_STATUS__ACTIVITY__SHIFT 0x0
|
||||
#define CKSVII2C_IC_STATUS__TFNF__SHIFT 0x1
|
||||
#define CKSVII2C_IC_STATUS__TFE__SHIFT 0x2
|
||||
#define CKSVII2C_IC_STATUS__RFNE__SHIFT 0x3
|
||||
#define CKSVII2C_IC_STATUS__RFF__SHIFT 0x4
|
||||
#define CKSVII2C_IC_STATUS__MST_ACTIVITY__SHIFT 0x5
|
||||
#define CKSVII2C_IC_STATUS__SLV_ACTIVITY__SHIFT 0x6
|
||||
#define CKSVII2C_IC_STATUS__ACTIVITY_MASK 0x00000001L
|
||||
#define CKSVII2C_IC_STATUS__TFNF_MASK 0x00000002L
|
||||
#define CKSVII2C_IC_STATUS__TFE_MASK 0x00000004L
|
||||
#define CKSVII2C_IC_STATUS__RFNE_MASK 0x00000008L
|
||||
#define CKSVII2C_IC_STATUS__RFF_MASK 0x00000010L
|
||||
#define CKSVII2C_IC_STATUS__MST_ACTIVITY_MASK 0x00000020L
|
||||
#define CKSVII2C_IC_STATUS__SLV_ACTIVITY_MASK 0x00000040L
|
||||
//CKSVII2C_IC_TXFLR
|
||||
//CKSVII2C_IC_RXFLR
|
||||
//CKSVII2C_IC_SDA_HOLD
|
||||
#define CKSVII2C_IC_SDA_HOLD__IC_SDA_HOLD__SHIFT 0x0
|
||||
#define CKSVII2C_IC_SDA_HOLD__IC_SDA_HOLD_MASK 0x00FFFFFFL
|
||||
//CKSVII2C_IC_TX_ABRT_SOURCE
|
||||
|
||||
#define CKSVII2C_IC_TX_ABRT_SOURCE__ABRT_7B_ADDR_NOACK__SHIFT 0x0
|
||||
#define CKSVII2C_IC_TX_ABRT_SOURCE__ABRT_10ADDR1_NOACK__SHIFT 0x1
|
||||
#define CKSVII2C_IC_TX_ABRT_SOURCE__ABRT_10ADDR2_NOACK__SHIFT 0x2
|
||||
#define CKSVII2C_IC_TX_ABRT_SOURCE__ABRT_TXDATA_NOACK__SHIFT 0x3
|
||||
#define CKSVII2C_IC_TX_ABRT_SOURCE__ABRT_7B_ADDR_NOACK_MASK 0x00000001L
|
||||
#define CKSVII2C_IC_TX_ABRT_SOURCE__ABRT_10ADDR1_NOACK_MASK 0x00000002L
|
||||
#define CKSVII2C_IC_TX_ABRT_SOURCE__ABRT_10ADDR2_NOACK_MASK 0x00000004L
|
||||
#define CKSVII2C_IC_TX_ABRT_SOURCE__ABRT_TXDATA_NOACK_MASK 0x00000008L
|
||||
//CKSVII2C_IC_SLV_DATA_NACK_ONLY
|
||||
//CKSVII2C_IC_DMA_CR
|
||||
//CKSVII2C_IC_DMA_TDLR
|
||||
//CKSVII2C_IC_DMA_RDLR
|
||||
//CKSVII2C_IC_SDA_SETUP
|
||||
#define CKSVII2C_IC_SDA_SETUP__SDA_SETUP__SHIFT 0x0
|
||||
#define CKSVII2C_IC_SDA_SETUP__SDA_SETUP_MASK 0x000000FFL
|
||||
//CKSVII2C_IC_ACK_GENERAL_CALL
|
||||
#define CKSVII2C_IC_ACK_GENERAL_CALL__ACK_GENERAL_CALL__SHIFT 0x0
|
||||
#define CKSVII2C_IC_ACK_GENERAL_CALL__ACK_GENERAL_CALL_MASK 0x00000001L
|
||||
//CKSVII2C_IC_ENABLE_STATUS
|
||||
#define CKSVII2C_IC_ENABLE_STATUS__IC_EN__SHIFT 0x0
|
||||
#define CKSVII2C_IC_ENABLE_STATUS__SLV_RX_ABORTED__SHIFT 0x1
|
||||
#define CKSVII2C_IC_ENABLE_STATUS__SLV_FIFO_FILLED_AND_FLUSHED__SHIFT 0x2
|
||||
#define CKSVII2C_IC_ENABLE_STATUS__IC_EN_MASK 0x00000001L
|
||||
#define CKSVII2C_IC_ENABLE_STATUS__SLV_RX_ABORTED_MASK 0x00000002L
|
||||
#define CKSVII2C_IC_ENABLE_STATUS__SLV_FIFO_FILLED_AND_FLUSHED_MASK 0x00000004L
|
||||
//CKSVII2C_IC_FS_SPKLEN
|
||||
#define CKSVII2C_IC_FS_SPKLEN__FS_SPKLEN__SHIFT 0x0
|
||||
#define CKSVII2C_IC_FS_SPKLEN__FS_SPKLEN_MASK 0x000000FFL
|
||||
//CKSVII2C_IC_HS_SPKLEN
|
||||
#define CKSVII2C_IC_HS_SPKLEN__HS_SPKLEN__SHIFT 0x0
|
||||
#define CKSVII2C_IC_HS_SPKLEN__HS_SPKLEN_MASK 0x000000FFL
|
||||
//CKSVII2C_IC_CLR_RESTART_DET
|
||||
//CKSVII2C_IC_COMP_PARAM_1
|
||||
#define CKSVII2C_IC_COMP_PARAM_1__COMP_PARAM_1__SHIFT 0x0
|
||||
#define CKSVII2C_IC_COMP_PARAM_1__COMP_PARAM_1_MASK 0xFFFFFFFFL
|
||||
//CKSVII2C_IC_COMP_VERSION
|
||||
#define CKSVII2C_IC_COMP_VERSION__COMP_VERSION__SHIFT 0x0
|
||||
#define CKSVII2C_IC_COMP_VERSION__COMP_VERSION_MASK 0xFFFFFFFFL
|
||||
//CKSVII2C_IC_COMP_TYPE
|
||||
#define CKSVII2C_IC_COMP_TYPE__COMP_TYPE__SHIFT 0x0
|
||||
#define CKSVII2C_IC_COMP_TYPE__COMP_TYPE_MASK 0xFFFFFFFFL
|
||||
//SMUIO_MP_RESET_INTR
|
||||
#define SMUIO_MP_RESET_INTR__SMUIO_MP_RESET_INTR__SHIFT 0x0
|
||||
#define SMUIO_MP_RESET_INTR__SMUIO_MP_RESET_INTR_MASK 0x00000001L
|
||||
|
@ -275,6 +275,7 @@ struct amd_pm_funcs {
|
||||
int (*set_power_profile_mode)(void *handle, long *input, uint32_t size);
|
||||
int (*odn_edit_dpm_table)(void *handle, uint32_t type, long *input, uint32_t size);
|
||||
int (*set_mp1_state)(void *handle, enum pp_mp1_state mp1_state);
|
||||
int (*smu_i2c_bus_access)(void *handle, bool acquire);
|
||||
/* export to DC */
|
||||
u32 (*get_sclk)(void *handle, bool low);
|
||||
u32 (*get_mclk)(void *handle, bool low);
|
||||
|
1364
drivers/gpu/drm/amd/include/renoir_ip_offset.h
Normal file
1364
drivers/gpu/drm/amd/include/renoir_ip_offset.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -1528,6 +1528,21 @@ static int pp_asic_reset_mode_2(void *handle)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pp_smu_i2c_bus_access(void *handle, bool acquire)
|
||||
{
|
||||
struct pp_hwmgr *hwmgr = handle;
|
||||
|
||||
if (!hwmgr || !hwmgr->pm_en)
|
||||
return -EINVAL;
|
||||
|
||||
if (hwmgr->hwmgr_func->smu_i2c_bus_access == NULL) {
|
||||
pr_info_ratelimited("%s was not implemented.\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return hwmgr->hwmgr_func->smu_i2c_bus_access(hwmgr, acquire);
|
||||
}
|
||||
|
||||
static const struct amd_pm_funcs pp_dpm_funcs = {
|
||||
.load_firmware = pp_dpm_load_fw,
|
||||
.wait_for_fw_loading_complete = pp_dpm_fw_loading_complete,
|
||||
@ -1585,4 +1600,5 @@ static const struct amd_pm_funcs pp_dpm_funcs = {
|
||||
.get_ppfeature_status = pp_get_ppfeature_status,
|
||||
.set_ppfeature_status = pp_set_ppfeature_status,
|
||||
.asic_reset_mode_2 = pp_asic_reset_mode_2,
|
||||
.smu_i2c_bus_access = pp_smu_i2c_bus_access,
|
||||
};
|
||||
|
@ -231,9 +231,8 @@ int smu_set_hard_freq_range(struct smu_context *smu, enum smu_clk_type clk_type,
|
||||
int smu_get_dpm_freq_range(struct smu_context *smu, enum smu_clk_type clk_type,
|
||||
uint32_t *min, uint32_t *max)
|
||||
{
|
||||
int ret = 0, clk_id = 0;
|
||||
uint32_t param = 0;
|
||||
uint32_t clock_limit;
|
||||
int ret = 0;
|
||||
|
||||
if (!min && !max)
|
||||
return -EINVAL;
|
||||
@ -264,36 +263,11 @@ int smu_get_dpm_freq_range(struct smu_context *smu, enum smu_clk_type clk_type,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
mutex_lock(&smu->mutex);
|
||||
clk_id = smu_clk_get_index(smu, clk_type);
|
||||
if (clk_id < 0) {
|
||||
ret = -EINVAL;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
param = (clk_id & 0xffff) << 16;
|
||||
|
||||
if (max) {
|
||||
ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetMaxDpmFreq, param);
|
||||
if (ret)
|
||||
goto failed;
|
||||
ret = smu_read_smc_arg(smu, max);
|
||||
if (ret)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (min) {
|
||||
ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetMinDpmFreq, param);
|
||||
if (ret)
|
||||
goto failed;
|
||||
ret = smu_read_smc_arg(smu, min);
|
||||
if (ret)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
failed:
|
||||
mutex_unlock(&smu->mutex);
|
||||
/*
|
||||
* Todo: Use each asic(ASIC_ppt funcs) control the callbacks exposed to the
|
||||
* core driver and then have helpers for stuff that is common(SMU_v11_x | SMU_v12_x funcs).
|
||||
*/
|
||||
ret = smu_get_dpm_ultimate_freq(smu, clk_type, min, max);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -636,7 +610,7 @@ int smu_feature_is_enabled(struct smu_context *smu, enum smu_feature_mask mask)
|
||||
int ret = 0;
|
||||
|
||||
if (adev->flags & AMD_IS_APU)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
feature_id = smu_feature_get_index(smu, mask);
|
||||
if (feature_id < 0)
|
||||
@ -1001,6 +975,9 @@ static int smu_override_pcie_parameters(struct smu_context *smu)
|
||||
uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg;
|
||||
int ret;
|
||||
|
||||
if (adev->flags & AMD_IS_APU)
|
||||
return 0;
|
||||
|
||||
if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4)
|
||||
pcie_gen = 3;
|
||||
else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)
|
||||
@ -1042,9 +1019,6 @@ static int smu_smc_table_hw_init(struct smu_context *smu,
|
||||
struct amdgpu_device *adev = smu->adev;
|
||||
int ret;
|
||||
|
||||
if (adev->flags & AMD_IS_APU)
|
||||
return 0;
|
||||
|
||||
if (smu_is_dpm_running(smu) && adev->in_suspend) {
|
||||
pr_info("dpm has been enabled\n");
|
||||
return 0;
|
||||
|
@ -141,6 +141,7 @@ static struct smu_11_0_cmn2aisc_mapping arcturus_feature_mask_map[SMU_FEATURE_CO
|
||||
FEA_MAP(DPM_SOCCLK),
|
||||
FEA_MAP(DPM_FCLK),
|
||||
FEA_MAP(DPM_MP0CLK),
|
||||
ARCTURUS_FEA_MAP(SMU_FEATURE_XGMI_BIT, FEATURE_DPM_XGMI_BIT),
|
||||
FEA_MAP(DS_GFXCLK),
|
||||
FEA_MAP(DS_SOCCLK),
|
||||
FEA_MAP(DS_LCLK),
|
||||
@ -149,6 +150,7 @@ static struct smu_11_0_cmn2aisc_mapping arcturus_feature_mask_map[SMU_FEATURE_CO
|
||||
FEA_MAP(GFX_ULV),
|
||||
ARCTURUS_FEA_MAP(SMU_FEATURE_VCN_PG_BIT, FEATURE_DPM_VCN_BIT),
|
||||
FEA_MAP(RSMU_SMN_CG),
|
||||
FEA_MAP(WAFL_CG),
|
||||
FEA_MAP(PPT),
|
||||
FEA_MAP(TDC),
|
||||
FEA_MAP(APCC_PLUS),
|
||||
|
@ -2353,12 +2353,16 @@ static int vega20_force_dpm_highest(struct pp_hwmgr *hwmgr)
|
||||
data->dpm_table.soc_table.dpm_state.soft_max_level =
|
||||
data->dpm_table.soc_table.dpm_levels[soft_level].value;
|
||||
|
||||
ret = vega20_upload_dpm_min_level(hwmgr, 0xFFFFFFFF);
|
||||
ret = vega20_upload_dpm_min_level(hwmgr, FEATURE_DPM_GFXCLK_MASK |
|
||||
FEATURE_DPM_UCLK_MASK |
|
||||
FEATURE_DPM_SOCCLK_MASK);
|
||||
PP_ASSERT_WITH_CODE(!ret,
|
||||
"Failed to upload boot level to highest!",
|
||||
return ret);
|
||||
|
||||
ret = vega20_upload_dpm_max_level(hwmgr, 0xFFFFFFFF);
|
||||
ret = vega20_upload_dpm_max_level(hwmgr, FEATURE_DPM_GFXCLK_MASK |
|
||||
FEATURE_DPM_UCLK_MASK |
|
||||
FEATURE_DPM_SOCCLK_MASK);
|
||||
PP_ASSERT_WITH_CODE(!ret,
|
||||
"Failed to upload dpm max level to highest!",
|
||||
return ret);
|
||||
@ -2391,12 +2395,16 @@ static int vega20_force_dpm_lowest(struct pp_hwmgr *hwmgr)
|
||||
data->dpm_table.soc_table.dpm_state.soft_max_level =
|
||||
data->dpm_table.soc_table.dpm_levels[soft_level].value;
|
||||
|
||||
ret = vega20_upload_dpm_min_level(hwmgr, 0xFFFFFFFF);
|
||||
ret = vega20_upload_dpm_min_level(hwmgr, FEATURE_DPM_GFXCLK_MASK |
|
||||
FEATURE_DPM_UCLK_MASK |
|
||||
FEATURE_DPM_SOCCLK_MASK);
|
||||
PP_ASSERT_WITH_CODE(!ret,
|
||||
"Failed to upload boot level to highest!",
|
||||
return ret);
|
||||
|
||||
ret = vega20_upload_dpm_max_level(hwmgr, 0xFFFFFFFF);
|
||||
ret = vega20_upload_dpm_max_level(hwmgr, FEATURE_DPM_GFXCLK_MASK |
|
||||
FEATURE_DPM_UCLK_MASK |
|
||||
FEATURE_DPM_SOCCLK_MASK);
|
||||
PP_ASSERT_WITH_CODE(!ret,
|
||||
"Failed to upload dpm max level to highest!",
|
||||
return ret);
|
||||
@ -2407,14 +2415,54 @@ static int vega20_force_dpm_lowest(struct pp_hwmgr *hwmgr)
|
||||
|
||||
static int vega20_unforce_dpm_levels(struct pp_hwmgr *hwmgr)
|
||||
{
|
||||
struct vega20_hwmgr *data =
|
||||
(struct vega20_hwmgr *)(hwmgr->backend);
|
||||
uint32_t soft_min_level, soft_max_level;
|
||||
int ret = 0;
|
||||
|
||||
ret = vega20_upload_dpm_min_level(hwmgr, 0xFFFFFFFF);
|
||||
/* gfxclk soft min/max settings */
|
||||
soft_min_level =
|
||||
vega20_find_lowest_dpm_level(&(data->dpm_table.gfx_table));
|
||||
soft_max_level =
|
||||
vega20_find_highest_dpm_level(&(data->dpm_table.gfx_table));
|
||||
|
||||
data->dpm_table.gfx_table.dpm_state.soft_min_level =
|
||||
data->dpm_table.gfx_table.dpm_levels[soft_min_level].value;
|
||||
data->dpm_table.gfx_table.dpm_state.soft_max_level =
|
||||
data->dpm_table.gfx_table.dpm_levels[soft_max_level].value;
|
||||
|
||||
/* uclk soft min/max settings */
|
||||
soft_min_level =
|
||||
vega20_find_lowest_dpm_level(&(data->dpm_table.mem_table));
|
||||
soft_max_level =
|
||||
vega20_find_highest_dpm_level(&(data->dpm_table.mem_table));
|
||||
|
||||
data->dpm_table.mem_table.dpm_state.soft_min_level =
|
||||
data->dpm_table.mem_table.dpm_levels[soft_min_level].value;
|
||||
data->dpm_table.mem_table.dpm_state.soft_max_level =
|
||||
data->dpm_table.mem_table.dpm_levels[soft_max_level].value;
|
||||
|
||||
/* socclk soft min/max settings */
|
||||
soft_min_level =
|
||||
vega20_find_lowest_dpm_level(&(data->dpm_table.soc_table));
|
||||
soft_max_level =
|
||||
vega20_find_highest_dpm_level(&(data->dpm_table.soc_table));
|
||||
|
||||
data->dpm_table.soc_table.dpm_state.soft_min_level =
|
||||
data->dpm_table.soc_table.dpm_levels[soft_min_level].value;
|
||||
data->dpm_table.soc_table.dpm_state.soft_max_level =
|
||||
data->dpm_table.soc_table.dpm_levels[soft_max_level].value;
|
||||
|
||||
ret = vega20_upload_dpm_min_level(hwmgr, FEATURE_DPM_GFXCLK_MASK |
|
||||
FEATURE_DPM_UCLK_MASK |
|
||||
FEATURE_DPM_SOCCLK_MASK);
|
||||
PP_ASSERT_WITH_CODE(!ret,
|
||||
"Failed to upload DPM Bootup Levels!",
|
||||
return ret);
|
||||
|
||||
ret = vega20_upload_dpm_max_level(hwmgr, 0xFFFFFFFF);
|
||||
ret = vega20_upload_dpm_max_level(hwmgr, FEATURE_DPM_GFXCLK_MASK |
|
||||
FEATURE_DPM_UCLK_MASK |
|
||||
FEATURE_DPM_SOCCLK_MASK);
|
||||
PP_ASSERT_WITH_CODE(!ret,
|
||||
"Failed to upload DPM Max Levels!",
|
||||
return ret);
|
||||
@ -4089,6 +4137,24 @@ static int vega20_get_thermal_temperature_range(struct pp_hwmgr *hwmgr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vega20_smu_i2c_bus_access(struct pp_hwmgr *hwmgr, bool acquire)
|
||||
{
|
||||
int res;
|
||||
|
||||
/* I2C bus access can happen very early, when SMU not loaded yet */
|
||||
if (!vega20_is_smc_ram_running(hwmgr))
|
||||
return 0;
|
||||
|
||||
res = smum_send_msg_to_smc_with_parameter(hwmgr,
|
||||
(acquire ?
|
||||
PPSMC_MSG_RequestI2CBus :
|
||||
PPSMC_MSG_ReleaseI2CBus),
|
||||
0);
|
||||
|
||||
PP_ASSERT_WITH_CODE(!res, "[SmuI2CAccessBus] Failed to access bus!", return res);
|
||||
return res;
|
||||
}
|
||||
|
||||
static const struct pp_hwmgr_func vega20_hwmgr_funcs = {
|
||||
/* init/fini related */
|
||||
.backend_init = vega20_hwmgr_backend_init,
|
||||
@ -4156,6 +4222,7 @@ static const struct pp_hwmgr_func vega20_hwmgr_funcs = {
|
||||
.get_asic_baco_state = vega20_baco_get_state,
|
||||
.set_asic_baco_state = vega20_baco_set_state,
|
||||
.set_mp1_state = vega20_set_mp1_state,
|
||||
.smu_i2c_bus_access = vega20_smu_i2c_bus_access,
|
||||
};
|
||||
|
||||
int vega20_hwmgr_init(struct pp_hwmgr *hwmgr)
|
||||
|
@ -458,6 +458,7 @@ struct pptable_funcs {
|
||||
int (*display_disable_memory_clock_switch)(struct smu_context *smu, bool disable_memory_clock_switch);
|
||||
void (*dump_pptable)(struct smu_context *smu);
|
||||
int (*get_power_limit)(struct smu_context *smu, uint32_t *limit, bool asic_default);
|
||||
int (*get_dpm_uclk_limited)(struct smu_context *smu, uint32_t *clock, bool max);
|
||||
};
|
||||
|
||||
struct smu_funcs
|
||||
@ -536,7 +537,7 @@ struct smu_funcs
|
||||
enum smu_baco_state (*baco_get_state)(struct smu_context *smu);
|
||||
int (*baco_set_state)(struct smu_context *smu, enum smu_baco_state state);
|
||||
int (*baco_reset)(struct smu_context *smu);
|
||||
|
||||
int (*get_dpm_ultimate_freq)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t *min, uint32_t *max);
|
||||
};
|
||||
|
||||
#define smu_init_microcode(smu) \
|
||||
@ -745,6 +746,10 @@ struct smu_funcs
|
||||
((smu)->funcs->register_irq_handler ? (smu)->funcs->register_irq_handler(smu) : 0)
|
||||
#define smu_set_azalia_d3_pme(smu) \
|
||||
((smu)->funcs->set_azalia_d3_pme ? (smu)->funcs->set_azalia_d3_pme((smu)) : 0)
|
||||
#define smu_get_dpm_ultimate_freq(smu, param, min, max) \
|
||||
((smu)->funcs->get_dpm_ultimate_freq ? (smu)->funcs->get_dpm_ultimate_freq((smu), (param), (min), (max)) : 0)
|
||||
#define smu_get_uclk_dpm_states(smu, clocks_in_khz, num_states) \
|
||||
((smu)->ppt_funcs->get_uclk_dpm_states ? (smu)->ppt_funcs->get_uclk_dpm_states((smu), (clocks_in_khz), (num_states)) : 0)
|
||||
#define smu_get_max_sustainable_clocks_by_dc(smu, max_clocks) \
|
||||
((smu)->funcs->get_max_sustainable_clocks_by_dc ? (smu)->funcs->get_max_sustainable_clocks_by_dc((smu), (max_clocks)) : 0)
|
||||
#define smu_get_uclk_dpm_states(smu, clocks_in_khz, num_states) \
|
||||
@ -759,6 +764,9 @@ struct smu_funcs
|
||||
((smu)->ppt_funcs->set_performance_level? (smu)->ppt_funcs->set_performance_level((smu), (level)) : -EINVAL);
|
||||
#define smu_dump_pptable(smu) \
|
||||
((smu)->ppt_funcs->dump_pptable ? (smu)->ppt_funcs->dump_pptable((smu)) : 0)
|
||||
#define smu_get_dpm_uclk_limited(smu, clock, max) \
|
||||
((smu)->ppt_funcs->get_dpm_uclk_limited ? (smu)->ppt_funcs->get_dpm_uclk_limited((smu), (clock), (max)) : -EINVAL)
|
||||
|
||||
|
||||
extern int smu_get_atom_data_table(struct smu_context *smu, uint32_t table,
|
||||
uint16_t *size, uint8_t *frev, uint8_t *crev,
|
||||
|
@ -354,6 +354,7 @@ struct pp_hwmgr_func {
|
||||
int (*set_ppfeature_status)(struct pp_hwmgr *hwmgr, uint64_t ppfeature_masks);
|
||||
int (*set_mp1_state)(struct pp_hwmgr *hwmgr, enum pp_mp1_state mp1_state);
|
||||
int (*asic_reset)(struct pp_hwmgr *hwmgr, enum SMU_ASIC_RESET_MODE mode);
|
||||
int (*smu_i2c_bus_access)(struct pp_hwmgr *hwmgr, bool aquire);
|
||||
};
|
||||
|
||||
struct pp_table_func {
|
||||
|
@ -251,6 +251,7 @@ enum smu_clk_type {
|
||||
__SMU_DUMMY_MAP(TEMP_DEPENDENT_VMIN), \
|
||||
__SMU_DUMMY_MAP(MMHUB_PG), \
|
||||
__SMU_DUMMY_MAP(ATHUB_PG), \
|
||||
__SMU_DUMMY_MAP(WAFL_CG),
|
||||
|
||||
#undef __SMU_DUMMY_MAP
|
||||
#define __SMU_DUMMY_MAP(feature) SMU_FEATURE_##feature##_BIT
|
||||
|
@ -213,7 +213,7 @@ static int navi10_get_smu_msg_index(struct smu_context *smc, uint32_t index)
|
||||
{
|
||||
struct smu_11_0_cmn2aisc_mapping mapping;
|
||||
|
||||
if (index > SMU_MSG_MAX_COUNT)
|
||||
if (index >= SMU_MSG_MAX_COUNT)
|
||||
return -EINVAL;
|
||||
|
||||
mapping = navi10_message_map[index];
|
||||
@ -369,7 +369,8 @@ navi10_get_allowed_feature_mask(struct smu_context *smu,
|
||||
*(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_ATHUB_PG_BIT);
|
||||
|
||||
if (smu->adev->pg_flags & AMD_PG_SUPPORT_VCN)
|
||||
*(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_VCN_PG_BIT);
|
||||
*(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_VCN_PG_BIT)
|
||||
| FEATURE_MASK(FEATURE_JPEG_PG_BIT);
|
||||
|
||||
/* disable DPM UCLK and DS SOCCLK on navi10 A0 secure board */
|
||||
if (is_asic_secure(smu)) {
|
||||
|
@ -156,11 +156,33 @@ static int renoir_tables_init(struct smu_context *smu, struct smu_table *tables)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This interface just for getting uclk ultimate freq and should't introduce
|
||||
* other likewise function result in overmuch callback.
|
||||
*/
|
||||
static int renoir_get_dpm_uclk_limited(struct smu_context *smu, uint32_t *clock, bool max)
|
||||
{
|
||||
|
||||
DpmClocks_t *table = smu->smu_table.clocks_table;
|
||||
|
||||
if (!clock || !table)
|
||||
return -EINVAL;
|
||||
|
||||
if (max)
|
||||
*clock = table->FClocks[NUM_FCLK_DPM_LEVELS-1].Freq;
|
||||
else
|
||||
*clock = table->FClocks[0].Freq;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static const struct pptable_funcs renoir_ppt_funcs = {
|
||||
.get_smu_msg_index = renoir_get_smu_msg_index,
|
||||
.get_smu_table_index = renoir_get_smu_table_index,
|
||||
.tables_init = renoir_tables_init,
|
||||
.set_power_state = NULL,
|
||||
.get_dpm_uclk_limited = renoir_get_dpm_uclk_limited,
|
||||
};
|
||||
|
||||
void renoir_set_ppt_funcs(struct smu_context *smu)
|
||||
|
@ -1718,6 +1718,43 @@ static int smu_v11_0_baco_reset(struct smu_context *smu)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int smu_v11_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk_type clk_type,
|
||||
uint32_t *min, uint32_t *max)
|
||||
{
|
||||
int ret = 0, clk_id = 0;
|
||||
uint32_t param = 0;
|
||||
|
||||
mutex_lock(&smu->mutex);
|
||||
clk_id = smu_clk_get_index(smu, clk_type);
|
||||
if (clk_id < 0) {
|
||||
ret = -EINVAL;
|
||||
goto failed;
|
||||
}
|
||||
param = (clk_id & 0xffff) << 16;
|
||||
|
||||
if (max) {
|
||||
ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetMaxDpmFreq, param);
|
||||
if (ret)
|
||||
goto failed;
|
||||
ret = smu_read_smc_arg(smu, max);
|
||||
if (ret)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (min) {
|
||||
ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetMinDpmFreq, param);
|
||||
if (ret)
|
||||
goto failed;
|
||||
ret = smu_read_smc_arg(smu, min);
|
||||
if (ret)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
failed:
|
||||
mutex_unlock(&smu->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct smu_funcs smu_v11_0_funcs = {
|
||||
.init_microcode = smu_v11_0_init_microcode,
|
||||
.load_microcode = smu_v11_0_load_microcode,
|
||||
@ -1767,6 +1804,7 @@ static const struct smu_funcs smu_v11_0_funcs = {
|
||||
.baco_get_state = smu_v11_0_baco_get_state,
|
||||
.baco_set_state = smu_v11_0_baco_set_state,
|
||||
.baco_reset = smu_v11_0_baco_reset,
|
||||
.get_dpm_ultimate_freq = smu_v11_0_get_dpm_ultimate_freq,
|
||||
};
|
||||
|
||||
void smu_v11_0_set_smu_funcs(struct smu_context *smu)
|
||||
|
@ -319,6 +319,67 @@ static int smu_v12_0_populate_smc_tables(struct smu_context *smu)
|
||||
return smu_update_table(smu, SMU_TABLE_DPMCLOCKS, 0, smu_table->clocks_table, false);
|
||||
}
|
||||
|
||||
static int smu_v12_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk_type clk_type,
|
||||
uint32_t *min, uint32_t *max)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&smu->mutex);
|
||||
|
||||
if (max) {
|
||||
switch (clk_type) {
|
||||
case SMU_GFXCLK:
|
||||
case SMU_SCLK:
|
||||
ret = smu_send_smc_msg(smu, SMU_MSG_GetMaxGfxclkFrequency);
|
||||
if (ret) {
|
||||
pr_err("Attempt to get max GX frequency from SMC Failed !\n");
|
||||
goto failed;
|
||||
}
|
||||
ret = smu_read_smc_arg(smu, max);
|
||||
if (ret)
|
||||
goto failed;
|
||||
break;
|
||||
case SMU_UCLK:
|
||||
ret = smu_get_dpm_uclk_limited(smu, max, true);
|
||||
if (ret)
|
||||
goto failed;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
goto failed;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (min) {
|
||||
switch (clk_type) {
|
||||
case SMU_GFXCLK:
|
||||
case SMU_SCLK:
|
||||
ret = smu_send_smc_msg(smu, SMU_MSG_GetMinGfxclkFrequency);
|
||||
if (ret) {
|
||||
pr_err("Attempt to get min GX frequency from SMC Failed !\n");
|
||||
goto failed;
|
||||
}
|
||||
ret = smu_read_smc_arg(smu, min);
|
||||
if (ret)
|
||||
goto failed;
|
||||
break;
|
||||
case SMU_UCLK:
|
||||
ret = smu_get_dpm_uclk_limited(smu, min, false);
|
||||
if (ret)
|
||||
goto failed;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
}
|
||||
failed:
|
||||
mutex_unlock(&smu->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct smu_funcs smu_v12_0_funcs = {
|
||||
.check_fw_status = smu_v12_0_check_fw_status,
|
||||
.check_fw_version = smu_v12_0_check_fw_version,
|
||||
@ -332,6 +393,7 @@ static const struct smu_funcs smu_v12_0_funcs = {
|
||||
.init_smc_tables = smu_v12_0_init_smc_tables,
|
||||
.fini_smc_tables = smu_v12_0_fini_smc_tables,
|
||||
.populate_smc_tables = smu_v12_0_populate_smc_tables,
|
||||
.get_dpm_ultimate_freq = smu_v12_0_get_dpm_ultimate_freq,
|
||||
};
|
||||
|
||||
void smu_v12_0_set_smu_funcs(struct smu_context *smu)
|
||||
|
@ -722,16 +722,17 @@ static int smu8_request_smu_load_fw(struct pp_hwmgr *hwmgr)
|
||||
|
||||
static int smu8_start_smu(struct pp_hwmgr *hwmgr)
|
||||
{
|
||||
struct amdgpu_device *adev = hwmgr->adev;
|
||||
struct amdgpu_device *adev;
|
||||
|
||||
uint32_t index = SMN_MP1_SRAM_START_ADDR +
|
||||
SMU8_FIRMWARE_HEADER_LOCATION +
|
||||
offsetof(struct SMU8_Firmware_Header, Version);
|
||||
|
||||
|
||||
if (hwmgr == NULL || hwmgr->device == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
adev = hwmgr->adev;
|
||||
|
||||
cgs_write_register(hwmgr->device, mmMP0PUB_IND_INDEX, index);
|
||||
hwmgr->smu_version = cgs_read_register(hwmgr->device, mmMP0PUB_IND_DATA);
|
||||
pr_info("smu version %02d.%02d.%02d\n",
|
||||
|
@ -44,7 +44,7 @@
|
||||
#define smnMP0_FW_INTF 0x30101c0
|
||||
#define smnMP1_PUB_CTRL 0x3010b14
|
||||
|
||||
static bool vega20_is_smc_ram_running(struct pp_hwmgr *hwmgr)
|
||||
bool vega20_is_smc_ram_running(struct pp_hwmgr *hwmgr)
|
||||
{
|
||||
struct amdgpu_device *adev = hwmgr->adev;
|
||||
uint32_t mp1_fw_flags;
|
||||
|
@ -57,5 +57,7 @@ int vega20_get_activity_monitor_coeff(struct pp_hwmgr *hwmgr,
|
||||
uint8_t *table, uint16_t workload_type);
|
||||
int vega20_set_pptable_driver_address(struct pp_hwmgr *hwmgr);
|
||||
|
||||
bool vega20_is_smc_ram_running(struct pp_hwmgr *hwmgr);
|
||||
|
||||
#endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user