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:
Dave Airlie 2019-09-06 16:40:28 +10:00
commit 9ed45a209a
99 changed files with 91412 additions and 140 deletions

View file

@ -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/

View file

@ -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

View file

@ -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);

View file

@ -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 },

View file

@ -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 @@ static int amdgpu_device_reset_sriov(struct amdgpu_device *adev,
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 ",

View file

@ -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 ||

View file

@ -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,

View file

@ -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 {

View 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

View 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

View file

@ -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);
}
/**

View file

@ -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;
}

View file

@ -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)

View file

@ -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 |

View file

@ -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);

View file

@ -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);

View file

@ -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:

View file

@ -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 = {

View file

@ -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);

View 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

View 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

View file

@ -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:

View file

@ -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,

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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:

View file

@ -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

View file

@ -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;

View 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);
}

View 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__

View file

@ -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);
}

View file

@ -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_ */

View file

@ -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

View file

@ -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;

View file

@ -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.

View file

@ -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),\

View file

@ -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; \

View file

@ -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;

View file

@ -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)

View file

@ -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 {

View file

@ -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)) {

View 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)

View 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;
}

View 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_ */

View 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;
}

View 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_ */

File diff suppressed because it is too large Load diff

View 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_ */

View file

@ -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
};
};

View file

@ -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))

File diff suppressed because it is too large Load diff

View file

@ -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_ */

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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;
}

View file

@ -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;

View file

@ -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
###############################################################################

View 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

View 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

View 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

View file

@ -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

View file

@ -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);

View file

@ -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();

View file

@ -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
};

View file

@ -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 */

View file

@ -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;
};

View file

@ -48,6 +48,7 @@ struct dce_hwseq_wa {
bool DEGVIDCN10_253;
bool false_optc_underflow;
bool DEGVIDCN10_254;
bool DEGVIDCN21;
};
struct hwseq_wa_state {

View file

@ -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

View 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;
}

View 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

View file

@ -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

View file

@ -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
};

View file

@ -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)
{

View 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

View file

@ -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

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View 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

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);

File diff suppressed because it is too large Load diff

View file

@ -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,
};

View file

@ -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;

View file

@ -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),

View file

@ -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)

View file

@ -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,

View file

@ -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 {

View file

@ -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

View file

@ -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)) {

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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",

View file

@ -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;

View file

@ -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