Merge branch 'drm-next-4.17' of git://people.freedesktop.org/~agd5f/linux into drm-next

Last pull for 4.17.  Highlights:
- Vega12 support
- A few more bug fixes and cleanups for powerplay

* 'drm-next-4.17' of git://people.freedesktop.org/~agd5f/linux: (77 commits)
  drm/amd/pp: clean header file hwmgr.h
  drm/amd/pp: use mlck_table.count for array loop index limit
  drm/amdgpu: Add an ATPX quirk for hybrid laptop
  drm/amdgpu: fix spelling mistake: "asssert" -> "assert"
  drm/amd/pp: Add new asic support in pp_psm.c
  drm/amd/pp: Clean up powerplay code on Vega12
  drm/amd/pp: Add smu irq handlers for legacy asics
  drm/amd/pp: Fix set wrong temperature range on smu7
  drm/amdgpu: Don't change preferred domian when fallback GTT v5
  drm/amdgpu: Fix NULL ptr on driver unload due to init failure.
  drm/amdgpu: fix "mitigate workaround for i915"
  drm/amd/pp: Add smu irq handlers in sw_init instand of hw_init
  drm/amd/pp: Refine register_thermal_interrupt function
  drm/amdgpu: Remove wrapper layer of cgs irq handling
  drm/amd/powerplay: Return per DPM level clock
  drm/amd/powerplay: Remove the SOC floor voltage setting
  drm/amdgpu: no job timeout setting on compute queues
  drm/amdgpu: add vega12 pci ids (v2)
  drm/amd/powerplay: add the hw manager for vega12 (v4)
  drm/amd/powerplay: add the smu manager for vega12 (v4)
  ...
This commit is contained in:
Dave Airlie 2018-03-26 10:01:11 +10:00
commit 33d009cd88
88 changed files with 60267 additions and 737 deletions

View File

@ -25,7 +25,6 @@
#define _ACP_GFX_IF_H
#include <linux/types.h>
#include "cgs_linux.h"
#include "cgs_common.h"
int amd_acp_hw_init(struct cgs_device *cgs_device,

View File

@ -569,6 +569,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, 0x67DF, 0x1028, 0x0774, AMDGPU_PX_QUIRK_FORCE_ATPX },
{ 0, 0, 0, 0, 0 },
};

View File

@ -28,7 +28,6 @@
#include <linux/firmware.h>
#include <drm/amdgpu_drm.h>
#include "amdgpu.h"
#include "cgs_linux.h"
#include "atom.h"
#include "amdgpu_ucode.h"
@ -182,109 +181,6 @@ static int amdgpu_cgs_atom_exec_cmd_table(struct cgs_device *cgs_device, unsigne
adev->mode_info.atom_context, table, args);
}
struct cgs_irq_params {
unsigned src_id;
cgs_irq_source_set_func_t set;
cgs_irq_handler_func_t handler;
void *private_data;
};
static int cgs_set_irq_state(struct amdgpu_device *adev,
struct amdgpu_irq_src *src,
unsigned type,
enum amdgpu_interrupt_state state)
{
struct cgs_irq_params *irq_params =
(struct cgs_irq_params *)src->data;
if (!irq_params)
return -EINVAL;
if (!irq_params->set)
return -EINVAL;
return irq_params->set(irq_params->private_data,
irq_params->src_id,
type,
(int)state);
}
static int cgs_process_irq(struct amdgpu_device *adev,
struct amdgpu_irq_src *source,
struct amdgpu_iv_entry *entry)
{
struct cgs_irq_params *irq_params =
(struct cgs_irq_params *)source->data;
if (!irq_params)
return -EINVAL;
if (!irq_params->handler)
return -EINVAL;
return irq_params->handler(irq_params->private_data,
irq_params->src_id,
entry->iv_entry);
}
static const struct amdgpu_irq_src_funcs cgs_irq_funcs = {
.set = cgs_set_irq_state,
.process = cgs_process_irq,
};
static int amdgpu_cgs_add_irq_source(void *cgs_device,
unsigned client_id,
unsigned src_id,
unsigned num_types,
cgs_irq_source_set_func_t set,
cgs_irq_handler_func_t handler,
void *private_data)
{
CGS_FUNC_ADEV;
int ret = 0;
struct cgs_irq_params *irq_params;
struct amdgpu_irq_src *source =
kzalloc(sizeof(struct amdgpu_irq_src), GFP_KERNEL);
if (!source)
return -ENOMEM;
irq_params =
kzalloc(sizeof(struct cgs_irq_params), GFP_KERNEL);
if (!irq_params) {
kfree(source);
return -ENOMEM;
}
source->num_types = num_types;
source->funcs = &cgs_irq_funcs;
irq_params->src_id = src_id;
irq_params->set = set;
irq_params->handler = handler;
irq_params->private_data = private_data;
source->data = (void *)irq_params;
ret = amdgpu_irq_add_id(adev, client_id, src_id, source);
if (ret) {
kfree(irq_params);
kfree(source);
}
return ret;
}
static int amdgpu_cgs_irq_get(void *cgs_device, unsigned client_id,
unsigned src_id, unsigned type)
{
CGS_FUNC_ADEV;
if (!adev->irq.client[client_id].sources)
return -EINVAL;
return amdgpu_irq_get(adev, adev->irq.client[client_id].sources[src_id], type);
}
static int amdgpu_cgs_irq_put(void *cgs_device, unsigned client_id,
unsigned src_id, unsigned type)
{
CGS_FUNC_ADEV;
if (!adev->irq.client[client_id].sources)
return -EINVAL;
return amdgpu_irq_put(adev, adev->irq.client[client_id].sources[src_id], type);
}
static int amdgpu_cgs_set_clockgating_state(struct cgs_device *cgs_device,
enum amd_ip_block_type block_type,
enum amd_clockgating_state state)
@ -654,6 +550,9 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
else
strcpy(fw_name, "amdgpu/vega10_smc.bin");
break;
case CHIP_VEGA12:
strcpy(fw_name, "amdgpu/vega12_smc.bin");
break;
default:
DRM_ERROR("SMC firmware not supported\n");
return -EINVAL;
@ -715,12 +614,9 @@ static int amdgpu_cgs_get_active_displays_info(struct cgs_device *cgs_device,
return -EINVAL;
mode_info = info->mode_info;
if (mode_info) {
if (mode_info)
/* if the displays are off, vblank time is max */
mode_info->vblank_time_us = 0xffffffff;
/* always set the reference clock */
mode_info->ref_clock = adev->clock.spll.reference_freq;
}
if (!amdgpu_device_has_dc_support(adev)) {
struct amdgpu_crtc *amdgpu_crtc;
@ -795,12 +691,6 @@ static const struct cgs_ops amdgpu_cgs_ops = {
.lock_grbm_idx = amdgpu_cgs_lock_grbm_idx,
};
static const struct cgs_os_ops amdgpu_cgs_os_ops = {
.add_irq_source = amdgpu_cgs_add_irq_source,
.irq_get = amdgpu_cgs_irq_get,
.irq_put = amdgpu_cgs_irq_put
};
struct cgs_device *amdgpu_cgs_create_device(struct amdgpu_device *adev)
{
struct amdgpu_cgs_device *cgs_device =
@ -812,7 +702,6 @@ struct cgs_device *amdgpu_cgs_create_device(struct amdgpu_device *adev)
}
cgs_device->base.ops = &amdgpu_cgs_ops;
cgs_device->base.os_ops = &amdgpu_cgs_os_ops;
cgs_device->adev = adev;
return (struct cgs_device *)cgs_device;

View File

@ -59,6 +59,7 @@
#include "amdgpu_pm.h"
MODULE_FIRMWARE("amdgpu/vega10_gpu_info.bin");
MODULE_FIRMWARE("amdgpu/vega12_gpu_info.bin");
MODULE_FIRMWARE("amdgpu/raven_gpu_info.bin");
#define AMDGPU_RESUME_MS 2000
@ -83,12 +84,21 @@ static const char *amdgpu_asic_name[] = {
"POLARIS11",
"POLARIS12",
"VEGA10",
"VEGA12",
"RAVEN",
"LAST",
};
static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev);
/**
* amdgpu_device_is_px - Is the device is a dGPU with HG/PX power control
*
* @dev: drm_device pointer
*
* Returns true if the device is a dGPU with HG/PX power control,
* otherwise return false.
*/
bool amdgpu_device_is_px(struct drm_device *dev)
{
struct amdgpu_device *adev = dev->dev_private;
@ -101,6 +111,15 @@ bool amdgpu_device_is_px(struct drm_device *dev)
/*
* MMIO register access helper functions.
*/
/**
* amdgpu_mm_rreg - read a memory mapped IO register
*
* @adev: amdgpu_device pointer
* @reg: dword aligned register offset
* @acc_flags: access flags which require special behavior
*
* Returns the 32 bit value from the offset specified.
*/
uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg,
uint32_t acc_flags)
{
@ -129,6 +148,14 @@ uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg,
*
*/
/**
* amdgpu_mm_rreg8 - read a memory mapped IO register
*
* @adev: amdgpu_device pointer
* @offset: byte aligned register offset
*
* Returns the 8 bit value from the offset specified.
*/
uint8_t amdgpu_mm_rreg8(struct amdgpu_device *adev, uint32_t offset) {
if (offset < adev->rmmio_size)
return (readb(adev->rmmio + offset));
@ -141,6 +168,15 @@ uint8_t amdgpu_mm_rreg8(struct amdgpu_device *adev, uint32_t offset) {
* @value: the value want to be written to the register
*
*/
/**
* amdgpu_mm_wreg8 - read a memory mapped IO register
*
* @adev: amdgpu_device pointer
* @offset: byte aligned register offset
* @value: 8 bit value to write
*
* Writes the value specified to the offset specified.
*/
void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset, uint8_t value) {
if (offset < adev->rmmio_size)
writeb(value, adev->rmmio + offset);
@ -148,7 +184,16 @@ void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset, uint8_t value)
BUG();
}
/**
* amdgpu_mm_wreg - write to a memory mapped IO register
*
* @adev: amdgpu_device pointer
* @reg: dword aligned register offset
* @v: 32 bit value to write to the register
* @acc_flags: access flags which require special behavior
*
* Writes the value specified to the offset specified.
*/
void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
uint32_t acc_flags)
{
@ -177,6 +222,14 @@ void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
}
}
/**
* amdgpu_io_rreg - read an IO register
*
* @adev: amdgpu_device pointer
* @reg: dword aligned register offset
*
* Returns the 32 bit value from the offset specified.
*/
u32 amdgpu_io_rreg(struct amdgpu_device *adev, u32 reg)
{
if ((reg * 4) < adev->rio_mem_size)
@ -187,6 +240,15 @@ u32 amdgpu_io_rreg(struct amdgpu_device *adev, u32 reg)
}
}
/**
* amdgpu_io_wreg - write to an IO register
*
* @adev: amdgpu_device pointer
* @reg: dword aligned register offset
* @v: 32 bit value to write to the register
*
* Writes the value specified to the offset specified.
*/
void amdgpu_io_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
{
if (adev->asic_type >= CHIP_VEGA10 && reg == 0) {
@ -355,6 +417,14 @@ static void amdgpu_block_invalid_wreg(struct amdgpu_device *adev,
BUG();
}
/**
* amdgpu_device_vram_scratch_init - allocate the VRAM scratch page
*
* @adev: amdgpu device pointer
*
* Allocates a scratch page of VRAM for use by various things in the
* driver.
*/
static int amdgpu_device_vram_scratch_init(struct amdgpu_device *adev)
{
return amdgpu_bo_create_kernel(adev, AMDGPU_GPU_PAGE_SIZE,
@ -364,6 +434,13 @@ static int amdgpu_device_vram_scratch_init(struct amdgpu_device *adev)
(void **)&adev->vram_scratch.ptr);
}
/**
* amdgpu_device_vram_scratch_fini - Free the VRAM scratch page
*
* @adev: amdgpu device pointer
*
* Frees the VRAM scratch page.
*/
static void amdgpu_device_vram_scratch_fini(struct amdgpu_device *adev)
{
amdgpu_bo_free_kernel(&adev->vram_scratch.robj, NULL, NULL);
@ -405,6 +482,14 @@ void amdgpu_device_program_register_sequence(struct amdgpu_device *adev,
}
}
/**
* amdgpu_device_pci_config_reset - reset the GPU
*
* @adev: amdgpu_device pointer
*
* Resets the GPU using the pci config reset sequence.
* Only applicable to asics prior to vega10.
*/
void amdgpu_device_pci_config_reset(struct amdgpu_device *adev)
{
pci_write_config_dword(adev->pdev, 0x7c, AMDGPU_ASIC_RESET_DATA);
@ -565,6 +650,7 @@ void amdgpu_device_wb_free(struct amdgpu_device *adev, u32 wb)
/**
* amdgpu_device_vram_location - try to find VRAM location
*
* @adev: amdgpu device structure holding all necessary informations
* @mc: memory controller structure holding memory informations
* @base: base address at which to put VRAM
@ -588,6 +674,7 @@ void amdgpu_device_vram_location(struct amdgpu_device *adev,
/**
* amdgpu_device_gart_location - try to find GTT location
*
* @adev: amdgpu device structure holding all necessary informations
* @mc: memory controller structure holding memory informations
*
@ -774,6 +861,16 @@ static unsigned int amdgpu_device_vga_set_decode(void *cookie, bool state)
return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
}
/**
* amdgpu_device_check_block_size - validate the vm block size
*
* @adev: amdgpu_device pointer
*
* Validates the vm block size specified via module parameter.
* The vm block size defines number of bits in page table versus page directory,
* a page is 4KB so we have 12 bits offset, minimum 9 bits in the
* page table and the remaining bits are in the page directory.
*/
static void amdgpu_device_check_block_size(struct amdgpu_device *adev)
{
/* defines number of bits in page table versus page directory,
@ -789,6 +886,14 @@ static void amdgpu_device_check_block_size(struct amdgpu_device *adev)
}
}
/**
* amdgpu_device_check_vm_size - validate the vm size
*
* @adev: amdgpu_device pointer
*
* Validates the vm size in GB specified via module parameter.
* The VM size is the size of the GPU virtual memory space in GB.
*/
static void amdgpu_device_check_vm_size(struct amdgpu_device *adev)
{
/* no need to check the default value */
@ -923,6 +1028,17 @@ static const struct vga_switcheroo_client_ops amdgpu_switcheroo_ops = {
.can_switch = amdgpu_switcheroo_can_switch,
};
/**
* amdgpu_device_ip_set_clockgating_state - set the CG state
*
* @adev: amdgpu_device pointer
* @block_type: Type of hardware IP (SMU, GFX, UVD, etc.)
* @state: clockgating state (gate or ungate)
*
* Sets the requested clockgating state for all instances of
* the hardware IP specified.
* Returns the error code from the last instance.
*/
int amdgpu_device_ip_set_clockgating_state(struct amdgpu_device *adev,
enum amd_ip_block_type block_type,
enum amd_clockgating_state state)
@ -945,6 +1061,17 @@ int amdgpu_device_ip_set_clockgating_state(struct amdgpu_device *adev,
return r;
}
/**
* amdgpu_device_ip_set_powergating_state - set the PG state
*
* @adev: amdgpu_device pointer
* @block_type: Type of hardware IP (SMU, GFX, UVD, etc.)
* @state: powergating state (gate or ungate)
*
* Sets the requested powergating state for all instances of
* the hardware IP specified.
* Returns the error code from the last instance.
*/
int amdgpu_device_ip_set_powergating_state(struct amdgpu_device *adev,
enum amd_ip_block_type block_type,
enum amd_powergating_state state)
@ -967,6 +1094,17 @@ int amdgpu_device_ip_set_powergating_state(struct amdgpu_device *adev,
return r;
}
/**
* amdgpu_device_ip_get_clockgating_state - get the CG state
*
* @adev: amdgpu_device pointer
* @flags: clockgating feature flags
*
* Walks the list of IPs on the device and updates the clockgating
* flags for each IP.
* Updates @flags with the feature flags for each hardware IP where
* clockgating is enabled.
*/
void amdgpu_device_ip_get_clockgating_state(struct amdgpu_device *adev,
u32 *flags)
{
@ -980,6 +1118,15 @@ void amdgpu_device_ip_get_clockgating_state(struct amdgpu_device *adev,
}
}
/**
* amdgpu_device_ip_wait_for_idle - wait for idle
*
* @adev: amdgpu_device pointer
* @block_type: Type of hardware IP (SMU, GFX, UVD, etc.)
*
* Waits for the request hardware IP to be idle.
* Returns 0 for success or a negative error code on failure.
*/
int amdgpu_device_ip_wait_for_idle(struct amdgpu_device *adev,
enum amd_ip_block_type block_type)
{
@ -999,6 +1146,15 @@ int amdgpu_device_ip_wait_for_idle(struct amdgpu_device *adev,
}
/**
* amdgpu_device_ip_is_idle - is the hardware IP idle
*
* @adev: amdgpu_device pointer
* @block_type: Type of hardware IP (SMU, GFX, UVD, etc.)
*
* Check if the hardware IP is idle or not.
* Returns true if it the IP is idle, false if not.
*/
bool amdgpu_device_ip_is_idle(struct amdgpu_device *adev,
enum amd_ip_block_type block_type)
{
@ -1014,6 +1170,15 @@ bool amdgpu_device_ip_is_idle(struct amdgpu_device *adev,
}
/**
* amdgpu_device_ip_get_ip_block - get a hw IP pointer
*
* @adev: amdgpu_device pointer
* @block_type: Type of hardware IP (SMU, GFX, UVD, etc.)
*
* Returns a pointer to the hardware IP block structure
* if it exists for the asic, otherwise NULL.
*/
struct amdgpu_ip_block *
amdgpu_device_ip_get_ip_block(struct amdgpu_device *adev,
enum amd_ip_block_type type)
@ -1075,6 +1240,18 @@ int amdgpu_device_ip_block_add(struct amdgpu_device *adev,
return 0;
}
/**
* amdgpu_device_enable_virtual_display - enable virtual display feature
*
* @adev: amdgpu_device pointer
*
* Enabled the virtual display feature if the user has enabled it via
* the module parameter virtual_display. This feature provides a virtual
* display hardware on headless boards or in virtualized environments.
* This function parses and validates the configuration string specified by
* the user and configues the virtual display configuration (number of
* virtual connectors, crtcs, etc.) specified.
*/
static void amdgpu_device_enable_virtual_display(struct amdgpu_device *adev)
{
adev->enable_virtual_display = false;
@ -1120,6 +1297,16 @@ static void amdgpu_device_enable_virtual_display(struct amdgpu_device *adev)
}
}
/**
* amdgpu_device_parse_gpu_info_fw - parse gpu info firmware
*
* @adev: amdgpu_device pointer
*
* Parses the asic configuration parameters specified in the gpu info
* firmware and makes them availale to the driver for use in configuring
* the asic.
* Returns 0 on success, -EINVAL on failure.
*/
static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev)
{
const char *chip_name;
@ -1157,6 +1344,9 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev)
case CHIP_VEGA10:
chip_name = "vega10";
break;
case CHIP_VEGA12:
chip_name = "vega12";
break;
case CHIP_RAVEN:
chip_name = "raven";
break;
@ -1218,6 +1408,16 @@ out:
return err;
}
/**
* amdgpu_device_ip_early_init - run early init for hardware IPs
*
* @adev: amdgpu_device pointer
*
* Early initialization pass for hardware IPs. The hardware IPs that make
* up each asic are discovered each IP's early_init callback is run. This
* is the first stage in initializing the asic.
* Returns 0 on success, negative error code on failure.
*/
static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
{
int i, r;
@ -1270,8 +1470,9 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
return r;
break;
#endif
case CHIP_VEGA10:
case CHIP_RAVEN:
case CHIP_VEGA10:
case CHIP_VEGA12:
case CHIP_RAVEN:
if (adev->asic_type == CHIP_RAVEN)
adev->family = AMDGPU_FAMILY_RV;
else
@ -1327,6 +1528,17 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
return 0;
}
/**
* amdgpu_device_ip_init - run init for hardware IPs
*
* @adev: amdgpu_device pointer
*
* Main initialization pass for hardware IPs. The list of all the hardware
* IPs that make up the asic is walked and the sw_init and hw_init callbacks
* are run. sw_init initializes the software state associated with each IP
* and hw_init initializes the hardware associated with each IP.
* Returns 0 on success, negative error code on failure.
*/
static int amdgpu_device_ip_init(struct amdgpu_device *adev)
{
int i, r;
@ -1394,17 +1606,47 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
return 0;
}
/**
* amdgpu_device_fill_reset_magic - writes reset magic to gart pointer
*
* @adev: amdgpu_device pointer
*
* Writes a reset magic value to the gart pointer in VRAM. The driver calls
* this function before a GPU reset. If the value is retained after a
* GPU reset, VRAM has not been lost. Some GPU resets may destry VRAM contents.
*/
static void amdgpu_device_fill_reset_magic(struct amdgpu_device *adev)
{
memcpy(adev->reset_magic, adev->gart.ptr, AMDGPU_RESET_MAGIC_NUM);
}
/**
* amdgpu_device_check_vram_lost - check if vram is valid
*
* @adev: amdgpu_device pointer
*
* Checks the reset magic value written to the gart pointer in VRAM.
* The driver calls this after a GPU reset to see if the contents of
* VRAM is lost or now.
* returns true if vram is lost, false if not.
*/
static bool amdgpu_device_check_vram_lost(struct amdgpu_device *adev)
{
return !!memcmp(adev->gart.ptr, adev->reset_magic,
AMDGPU_RESET_MAGIC_NUM);
}
/**
* amdgpu_device_ip_late_set_cg_state - late init for clockgating
*
* @adev: amdgpu_device pointer
*
* Late initialization pass enabling clockgating for hardware IPs.
* The list of all the hardware IPs that make up the asic is walked and the
* set_clockgating_state callbacks are run. This stage is run late
* in the init process.
* Returns 0 on success, negative error code on failure.
*/
static int amdgpu_device_ip_late_set_cg_state(struct amdgpu_device *adev)
{
int i = 0, r;
@ -1432,6 +1674,18 @@ static int amdgpu_device_ip_late_set_cg_state(struct amdgpu_device *adev)
return 0;
}
/**
* amdgpu_device_ip_late_init - run late init for hardware IPs
*
* @adev: amdgpu_device pointer
*
* Late initialization pass for hardware IPs. The list of all the hardware
* IPs that make up the asic is walked and the late_init callbacks are run.
* late_init covers any special initialization that an IP requires
* after all of the have been initialized or something that needs to happen
* late in the init process.
* Returns 0 on success, negative error code on failure.
*/
static int amdgpu_device_ip_late_init(struct amdgpu_device *adev)
{
int i = 0, r;
@ -1458,6 +1712,17 @@ static int amdgpu_device_ip_late_init(struct amdgpu_device *adev)
return 0;
}
/**
* amdgpu_device_ip_fini - run fini for hardware IPs
*
* @adev: amdgpu_device pointer
*
* Main teardown pass for hardware IPs. The list of all the hardware
* IPs that make up the asic is walked and the hw_fini and sw_fini callbacks
* are run. hw_fini tears down the hardware associated with each IP
* and sw_fini tears down any software state associated with each IP.
* Returns 0 on success, negative error code on failure.
*/
static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
{
int i, r;
@ -1493,7 +1758,8 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
continue;
if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD &&
adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE) {
adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE &&
adev->ip_blocks[i].version->funcs->set_clockgating_state) {
/* ungate blocks before hw fini so that we can shutdown the blocks safely */
r = adev->ip_blocks[i].version->funcs->set_clockgating_state((void *)adev,
AMD_CG_STATE_UNGATE);
@ -1514,8 +1780,6 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
adev->ip_blocks[i].status.hw = false;
}
/* disable all interrupts */
amdgpu_irq_disable_all(adev);
for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
if (!adev->ip_blocks[i].status.sw)
@ -1552,6 +1816,15 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
return 0;
}
/**
* amdgpu_device_ip_late_init_func_handler - work handler for clockgating
*
* @work: work_struct
*
* Work handler for amdgpu_device_ip_late_set_cg_state. We put the
* clockgating setup into a worker thread to speed up driver init and
* resume from suspend.
*/
static void amdgpu_device_ip_late_init_func_handler(struct work_struct *work)
{
struct amdgpu_device *adev =
@ -1559,6 +1832,17 @@ static void amdgpu_device_ip_late_init_func_handler(struct work_struct *work)
amdgpu_device_ip_late_set_cg_state(adev);
}
/**
* amdgpu_device_ip_suspend - run suspend for hardware IPs
*
* @adev: amdgpu_device pointer
*
* Main suspend function for hardware IPs. The list of all the hardware
* IPs that make up the asic is walked, clockgating is disabled and the
* suspend callbacks are run. suspend puts the hardware and software state
* in each IP into a state suitable for suspend.
* Returns 0 on success, negative error code on failure.
*/
int amdgpu_device_ip_suspend(struct amdgpu_device *adev)
{
int i, r;
@ -1667,6 +1951,18 @@ static int amdgpu_device_ip_reinit_late_sriov(struct amdgpu_device *adev)
return 0;
}
/**
* amdgpu_device_ip_resume_phase1 - run resume for hardware IPs
*
* @adev: amdgpu_device pointer
*
* First resume function for hardware IPs. The list of all the hardware
* IPs that make up the asic is walked and the resume callbacks are run for
* COMMON, GMC, and IH. resume puts the hardware into a functional state
* after a suspend and updates the software state as necessary. This
* function is also used for restoring the GPU after a GPU reset.
* Returns 0 on success, negative error code on failure.
*/
static int amdgpu_device_ip_resume_phase1(struct amdgpu_device *adev)
{
int i, r;
@ -1675,9 +1971,8 @@ static int amdgpu_device_ip_resume_phase1(struct amdgpu_device *adev)
if (!adev->ip_blocks[i].status.valid)
continue;
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON ||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC ||
adev->ip_blocks[i].version->type ==
AMD_IP_BLOCK_TYPE_IH) {
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC ||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_IH) {
r = adev->ip_blocks[i].version->funcs->resume(adev);
if (r) {
DRM_ERROR("resume of IP block <%s> failed %d\n",
@ -1690,6 +1985,19 @@ static int amdgpu_device_ip_resume_phase1(struct amdgpu_device *adev)
return 0;
}
/**
* amdgpu_device_ip_resume_phase2 - run resume for hardware IPs
*
* @adev: amdgpu_device pointer
*
* First resume function for hardware IPs. The list of all the hardware
* IPs that make up the asic is walked and the resume callbacks are run for
* all blocks except COMMON, GMC, and IH. resume puts the hardware into a
* functional state after a suspend and updates the software state as
* necessary. This function is also used for restoring the GPU after a GPU
* reset.
* Returns 0 on success, negative error code on failure.
*/
static int amdgpu_device_ip_resume_phase2(struct amdgpu_device *adev)
{
int i, r;
@ -1698,8 +2006,8 @@ static int amdgpu_device_ip_resume_phase2(struct amdgpu_device *adev)
if (!adev->ip_blocks[i].status.valid)
continue;
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON ||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC ||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_IH )
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC ||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_IH)
continue;
r = adev->ip_blocks[i].version->funcs->resume(adev);
if (r) {
@ -1712,6 +2020,18 @@ static int amdgpu_device_ip_resume_phase2(struct amdgpu_device *adev)
return 0;
}
/**
* amdgpu_device_ip_resume - run resume for hardware IPs
*
* @adev: amdgpu_device pointer
*
* Main resume function for hardware IPs. The hardware IPs
* are split into two resume functions because they are
* are also used in in recovering from a GPU reset and some additional
* steps need to be take between them. In this case (S3/S4) they are
* run sequentially.
* Returns 0 on success, negative error code on failure.
*/
static int amdgpu_device_ip_resume(struct amdgpu_device *adev)
{
int r;
@ -1724,6 +2044,13 @@ static int amdgpu_device_ip_resume(struct amdgpu_device *adev)
return r;
}
/**
* amdgpu_device_detect_sriov_bios - determine if the board supports SR-IOV
*
* @adev: amdgpu_device pointer
*
* Query the VBIOS data tables to determine if the board supports SR-IOV.
*/
static void amdgpu_device_detect_sriov_bios(struct amdgpu_device *adev)
{
if (amdgpu_sriov_vf(adev)) {
@ -1740,6 +2067,14 @@ static void amdgpu_device_detect_sriov_bios(struct amdgpu_device *adev)
}
}
/**
* amdgpu_device_asic_has_dc_support - determine if DC supports the asic
*
* @asic_type: AMD asic type
*
* Check if there is DC (new modesetting infrastructre) support for an asic.
* returns true if DC has support, false if not.
*/
bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type)
{
switch (asic_type) {
@ -1760,6 +2095,7 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type)
return amdgpu_dc != 0;
#endif
case CHIP_VEGA10:
case CHIP_VEGA12:
#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
case CHIP_RAVEN:
#endif
@ -2017,7 +2353,6 @@ fence_driver_init:
}
dev_err(adev->dev, "amdgpu_device_ip_init failed\n");
amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_AMDGPU_INIT_FAIL, 0, 0);
amdgpu_device_ip_fini(adev);
goto failed;
}
@ -2116,9 +2451,14 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
DRM_INFO("amdgpu: finishing device.\n");
adev->shutdown = true;
if (adev->mode_info.mode_config_initialized)
drm_crtc_force_disable_all(adev->ddev);
/* disable all interrupts */
amdgpu_irq_disable_all(adev);
if (adev->mode_info.mode_config_initialized){
if (!amdgpu_device_has_dc_support(adev))
drm_crtc_force_disable_all(adev->ddev);
else
drm_atomic_helper_shutdown(adev->ddev);
}
amdgpu_ib_pool_fini(adev);
amdgpu_fence_driver_fini(adev);
amdgpu_pm_sysfs_fini(adev);
@ -2378,6 +2718,16 @@ unlock:
return r;
}
/**
* amdgpu_device_ip_check_soft_reset - did soft reset succeed
*
* @adev: amdgpu_device pointer
*
* The list of all the hardware IPs that make up the asic is walked and
* the check_soft_reset callbacks are run. check_soft_reset determines
* if the asic is still hung or not.
* Returns true if any of the IPs are still in a hung state, false if not.
*/
static bool amdgpu_device_ip_check_soft_reset(struct amdgpu_device *adev)
{
int i;
@ -2400,6 +2750,17 @@ static bool amdgpu_device_ip_check_soft_reset(struct amdgpu_device *adev)
return asic_hang;
}
/**
* amdgpu_device_ip_pre_soft_reset - prepare for soft reset
*
* @adev: amdgpu_device pointer
*
* The list of all the hardware IPs that make up the asic is walked and the
* pre_soft_reset callbacks are run if the block is hung. pre_soft_reset
* handles any IP specific hardware or software state changes that are
* necessary for a soft reset to succeed.
* Returns 0 on success, negative error code on failure.
*/
static int amdgpu_device_ip_pre_soft_reset(struct amdgpu_device *adev)
{
int i, r = 0;
@ -2418,6 +2779,15 @@ static int amdgpu_device_ip_pre_soft_reset(struct amdgpu_device *adev)
return 0;
}
/**
* amdgpu_device_ip_need_full_reset - check if a full asic reset is needed
*
* @adev: amdgpu_device pointer
*
* Some hardware IPs cannot be soft reset. If they are hung, a full gpu
* reset is necessary to recover.
* Returns true if a full asic reset is required, false if not.
*/
static bool amdgpu_device_ip_need_full_reset(struct amdgpu_device *adev)
{
int i;
@ -2439,6 +2809,17 @@ static bool amdgpu_device_ip_need_full_reset(struct amdgpu_device *adev)
return false;
}
/**
* amdgpu_device_ip_soft_reset - do a soft reset
*
* @adev: amdgpu_device pointer
*
* The list of all the hardware IPs that make up the asic is walked and the
* soft_reset callbacks are run if the block is hung. soft_reset handles any
* IP specific hardware or software state changes that are necessary to soft
* reset the IP.
* Returns 0 on success, negative error code on failure.
*/
static int amdgpu_device_ip_soft_reset(struct amdgpu_device *adev)
{
int i, r = 0;
@ -2457,6 +2838,17 @@ static int amdgpu_device_ip_soft_reset(struct amdgpu_device *adev)
return 0;
}
/**
* amdgpu_device_ip_post_soft_reset - clean up from soft reset
*
* @adev: amdgpu_device pointer
*
* The list of all the hardware IPs that make up the asic is walked and the
* post_soft_reset callbacks are run if the asic was hung. post_soft_reset
* handles any IP specific hardware or software state changes that are
* necessary after the IP has been soft reset.
* Returns 0 on success, negative error code on failure.
*/
static int amdgpu_device_ip_post_soft_reset(struct amdgpu_device *adev)
{
int i, r = 0;
@ -2474,6 +2866,19 @@ static int amdgpu_device_ip_post_soft_reset(struct amdgpu_device *adev)
return 0;
}
/**
* amdgpu_device_recover_vram_from_shadow - restore shadowed VRAM buffers
*
* @adev: amdgpu_device pointer
* @ring: amdgpu_ring for the engine handling the buffer operations
* @bo: amdgpu_bo buffer whose shadow is being restored
* @fence: dma_fence associated with the operation
*
* Restores the VRAM buffer contents from the shadow in GTT. Used to
* restore things like GPUVM page tables after a GPU reset where
* the contents of VRAM might be lost.
* Returns 0 on success, negative error code on failure.
*/
static int amdgpu_device_recover_vram_from_shadow(struct amdgpu_device *adev,
struct amdgpu_ring *ring,
struct amdgpu_bo *bo,
@ -2509,6 +2914,16 @@ err:
return r;
}
/**
* amdgpu_device_handle_vram_lost - Handle the loss of VRAM contents
*
* @adev: amdgpu_device pointer
*
* Restores the contents of VRAM buffers from the shadows in GTT. Used to
* restore things like GPUVM page tables after a GPU reset where
* the contents of VRAM might be lost.
* Returns 0 on success, 1 on failure.
*/
static int amdgpu_device_handle_vram_lost(struct amdgpu_device *adev)
{
struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
@ -2562,17 +2977,17 @@ static int amdgpu_device_handle_vram_lost(struct amdgpu_device *adev)
else
DRM_ERROR("recover vram bo from shadow failed\n");
return (r > 0?0:1);
return (r > 0) ? 0 : 1;
}
/*
/**
* amdgpu_device_reset - reset ASIC/GPU for bare-metal or passthrough
*
* @adev: amdgpu device pointer
*
* attempt to do soft-reset or full-reset and reinitialize Asic
* return 0 means successed otherwise failed
*/
*/
static int amdgpu_device_reset(struct amdgpu_device *adev)
{
bool need_full_reset, vram_lost = 0;
@ -2642,15 +3057,16 @@ out:
return r;
}
/*
/**
* amdgpu_device_reset_sriov - reset ASIC for SR-IOV vf
*
* @adev: amdgpu device pointer
*
* do VF FLR and reinitialize Asic
* return 0 means successed otherwise failed
*/
static int amdgpu_device_reset_sriov(struct amdgpu_device *adev, bool from_hypervisor)
*/
static int amdgpu_device_reset_sriov(struct amdgpu_device *adev,
bool from_hypervisor)
{
int r;
@ -2790,6 +3206,15 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
return r;
}
/**
* amdgpu_device_get_pcie_info - fence pcie info about the PCIE slot
*
* @adev: amdgpu_device pointer
*
* Fetchs and stores in the driver the PCIE capabilities (gen speed
* and lanes) of the slot the device is in. Handles APUs and
* virtualized environments where PCIE config space may not be available.
*/
static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)
{
u32 mask;

View File

@ -544,6 +544,12 @@ static const struct pci_device_id pciidlist[] = {
{0x1002, 0x6868, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10},
{0x1002, 0x686c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10},
{0x1002, 0x687f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10},
/* Vega 12 */
{0x1002, 0x69A0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA12},
{0x1002, 0x69A1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA12},
{0x1002, 0x69A2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA12},
{0x1002, 0x69A3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA12},
{0x1002, 0x69AF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA12},
/* Raven */
{0x1002, 0x15dd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RAVEN|AMD_IS_APU},

View File

@ -435,7 +435,9 @@ int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring,
if (ring->funcs->type != AMDGPU_RING_TYPE_KIQ) {
r = drm_sched_init(&ring->sched, &amdgpu_sched_ops,
num_hw_submission, amdgpu_job_hang_limit,
msecs_to_jiffies(amdgpu_lockup_timeout), ring->name);
(ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE) ?
MAX_SCHEDULE_TIMEOUT : msecs_to_jiffies(amdgpu_lockup_timeout),
ring->name);
if (r) {
DRM_ERROR("Failed to create scheduler on ring %s.\n",
ring->name);

View File

@ -56,23 +56,11 @@ int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,
alignment = PAGE_SIZE;
}
retry:
r = amdgpu_bo_create(adev, size, alignment, initial_domain,
flags, type, resv, &bo);
if (r) {
if (r != -ERESTARTSYS) {
if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) {
flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
goto retry;
}
if (initial_domain == AMDGPU_GEM_DOMAIN_VRAM) {
initial_domain |= AMDGPU_GEM_DOMAIN_GTT;
goto retry;
}
DRM_DEBUG("Failed to allocate GEM object (%ld, %d, %u, %d)\n",
size, initial_domain, alignment, r);
}
DRM_DEBUG("Failed to allocate GEM object (%ld, %d, %u, %d)\n",
size, initial_domain, alignment, r);
return r;
}
*obj = &bo->gem_base;

View File

@ -259,6 +259,7 @@ void amdgpu_irq_fini(struct amdgpu_device *adev)
}
}
kfree(adev->irq.client[i].sources);
adev->irq.client[i].sources = NULL;
}
}

View File

@ -190,6 +190,10 @@ static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info,
fw_info->ver = adev->uvd.fw_version;
fw_info->feature = 0;
break;
case AMDGPU_INFO_FW_VCN:
fw_info->ver = adev->vcn.fw_version;
fw_info->feature = 0;
break;
case AMDGPU_INFO_FW_GMC:
fw_info->ver = adev->gmc.fw_version;
fw_info->feature = 0;
@ -1198,6 +1202,14 @@ static int amdgpu_debugfs_firmware_info(struct seq_file *m, void *data)
i, fw_info.feature, fw_info.ver);
}
/* VCN */
query_fw.fw_type = AMDGPU_INFO_FW_VCN;
ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
if (ret)
return ret;
seq_printf(m, "VCN feature version: %u, firmware version: 0x%08x\n",
fw_info.feature, fw_info.ver);
return 0;
}

View File

@ -356,6 +356,7 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev, unsigned long size,
struct amdgpu_bo *bo;
unsigned long page_align;
size_t acc_size;
u32 domains;
int r;
page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT;
@ -417,12 +418,23 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev, unsigned long size,
#endif
bo->tbo.bdev = &adev->mman.bdev;
amdgpu_ttm_placement_from_domain(bo, domain);
domains = bo->preferred_domains;
retry:
amdgpu_ttm_placement_from_domain(bo, domains);
r = ttm_bo_init_reserved(&adev->mman.bdev, &bo->tbo, size, type,
&bo->placement, page_align, &ctx, acc_size,
NULL, resv, &amdgpu_ttm_bo_destroy);
if (unlikely(r != 0))
if (unlikely(r && r != -ERESTARTSYS)) {
if (bo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) {
bo->flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
goto retry;
} else if (domains != bo->preferred_domains) {
domains = bo->allowed_domains;
goto retry;
}
}
if (unlikely(r))
return r;
if (adev->gmc.visible_vram_size < adev->gmc.real_vram_size &&

View File

@ -132,6 +132,7 @@ static int amdgpu_gem_map_attach(struct dma_buf *dma_buf,
{
struct drm_gem_object *obj = dma_buf->priv;
struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
long r;
r = drm_gem_map_attach(dma_buf, target_dev, attach);
@ -143,7 +144,7 @@ static int amdgpu_gem_map_attach(struct dma_buf *dma_buf,
goto error_detach;
if (dma_buf->ops != &amdgpu_dmabuf_ops) {
if (attach->dev->driver != adev->dev->driver) {
/*
* Wait for all shared fences to complete before we switch to future
* use of exclusive fence on this prime shared bo.
@ -162,7 +163,7 @@ static int amdgpu_gem_map_attach(struct dma_buf *dma_buf,
if (r)
goto error_unreserve;
if (dma_buf->ops != &amdgpu_dmabuf_ops)
if (attach->dev->driver != adev->dev->driver)
bo->prime_shared_count++;
error_unreserve:
@ -179,6 +180,7 @@ static void amdgpu_gem_map_detach(struct dma_buf *dma_buf,
{
struct drm_gem_object *obj = dma_buf->priv;
struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
int ret = 0;
ret = amdgpu_bo_reserve(bo, true);
@ -186,7 +188,7 @@ static void amdgpu_gem_map_detach(struct dma_buf *dma_buf,
goto error;
amdgpu_bo_unpin(bo);
if (dma_buf->ops != &amdgpu_dmabuf_ops && bo->prime_shared_count)
if (attach->dev->driver != adev->dev->driver && bo->prime_shared_count)
bo->prime_shared_count--;
amdgpu_bo_unreserve(bo);

View File

@ -51,6 +51,7 @@ static int psp_sw_init(void *handle)
switch (adev->asic_type) {
case CHIP_VEGA10:
case CHIP_VEGA12:
psp_v3_1_set_psp_funcs(psp);
break;
case CHIP_RAVEN:

View File

@ -2021,7 +2021,7 @@ static ssize_t amdgpu_iomem_read(struct file *f, char __user *buf,
return -EPERM;
ptr = kmap(p);
r = copy_to_user(buf, ptr, bytes);
r = copy_to_user(buf, ptr + off, bytes);
kunmap(p);
if (r)
return -EFAULT;
@ -2065,7 +2065,7 @@ static ssize_t amdgpu_iomem_write(struct file *f, const char __user *buf,
return -EPERM;
ptr = kmap(p);
r = copy_from_user(ptr, buf, bytes);
r = copy_from_user(ptr + off, buf, bytes);
kunmap(p);
if (r)
return -EFAULT;

View File

@ -271,6 +271,7 @@ amdgpu_ucode_get_load_type(struct amdgpu_device *adev, int load_type)
return AMDGPU_FW_LOAD_SMU;
case CHIP_VEGA10:
case CHIP_RAVEN:
case CHIP_VEGA12:
if (!load_type)
return AMDGPU_FW_LOAD_DIRECT;
else

View File

@ -68,6 +68,7 @@
#define FIRMWARE_POLARIS12 "amdgpu/polaris12_uvd.bin"
#define FIRMWARE_VEGA10 "amdgpu/vega10_uvd.bin"
#define FIRMWARE_VEGA12 "amdgpu/vega12_uvd.bin"
#define mmUVD_GPCOM_VCPU_DATA0_VEGA10 (0x03c4 + 0x7e00)
#define mmUVD_GPCOM_VCPU_DATA1_VEGA10 (0x03c5 + 0x7e00)
@ -110,6 +111,7 @@ MODULE_FIRMWARE(FIRMWARE_POLARIS11);
MODULE_FIRMWARE(FIRMWARE_POLARIS12);
MODULE_FIRMWARE(FIRMWARE_VEGA10);
MODULE_FIRMWARE(FIRMWARE_VEGA12);
static void amdgpu_uvd_idle_work_handler(struct work_struct *work);
@ -161,11 +163,14 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev)
case CHIP_POLARIS11:
fw_name = FIRMWARE_POLARIS11;
break;
case CHIP_POLARIS12:
fw_name = FIRMWARE_POLARIS12;
break;
case CHIP_VEGA10:
fw_name = FIRMWARE_VEGA10;
break;
case CHIP_POLARIS12:
fw_name = FIRMWARE_POLARIS12;
case CHIP_VEGA12:
fw_name = FIRMWARE_VEGA12;
break;
default:
return -EINVAL;

View File

@ -55,6 +55,7 @@
#define FIRMWARE_POLARIS12 "amdgpu/polaris12_vce.bin"
#define FIRMWARE_VEGA10 "amdgpu/vega10_vce.bin"
#define FIRMWARE_VEGA12 "amdgpu/vega12_vce.bin"
#ifdef CONFIG_DRM_AMDGPU_CIK
MODULE_FIRMWARE(FIRMWARE_BONAIRE);
@ -72,6 +73,7 @@ MODULE_FIRMWARE(FIRMWARE_POLARIS11);
MODULE_FIRMWARE(FIRMWARE_POLARIS12);
MODULE_FIRMWARE(FIRMWARE_VEGA10);
MODULE_FIRMWARE(FIRMWARE_VEGA12);
static void amdgpu_vce_idle_work_handler(struct work_struct *work);
@ -127,11 +129,14 @@ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size)
case CHIP_POLARIS11:
fw_name = FIRMWARE_POLARIS11;
break;
case CHIP_POLARIS12:
fw_name = FIRMWARE_POLARIS12;
break;
case CHIP_VEGA10:
fw_name = FIRMWARE_VEGA10;
break;
case CHIP_POLARIS12:
fw_name = FIRMWARE_POLARIS12;
case CHIP_VEGA12:
fw_name = FIRMWARE_VEGA12;
break;
default:

View File

@ -6244,6 +6244,7 @@ static int ci_dpm_early_init(void *handle)
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
adev->powerplay.pp_funcs = &ci_dpm_funcs;
adev->powerplay.pp_handle = adev;
ci_dpm_set_irq_funcs(adev);
return 0;

View File

@ -473,6 +473,7 @@ static int dce_virtual_hw_init(void *handle)
/* no DCE */
break;
case CHIP_VEGA10:
case CHIP_VEGA12:
break;
default:
DRM_ERROR("Virtual display unsupported ASIC type: 0x%X\n", adev->asic_type);

View File

@ -57,6 +57,13 @@ MODULE_FIRMWARE("amdgpu/vega10_mec.bin");
MODULE_FIRMWARE("amdgpu/vega10_mec2.bin");
MODULE_FIRMWARE("amdgpu/vega10_rlc.bin");
MODULE_FIRMWARE("amdgpu/vega12_ce.bin");
MODULE_FIRMWARE("amdgpu/vega12_pfp.bin");
MODULE_FIRMWARE("amdgpu/vega12_me.bin");
MODULE_FIRMWARE("amdgpu/vega12_mec.bin");
MODULE_FIRMWARE("amdgpu/vega12_mec2.bin");
MODULE_FIRMWARE("amdgpu/vega12_rlc.bin");
MODULE_FIRMWARE("amdgpu/raven_ce.bin");
MODULE_FIRMWARE("amdgpu/raven_pfp.bin");
MODULE_FIRMWARE("amdgpu/raven_me.bin");
@ -144,7 +151,42 @@ static const struct soc15_reg_golden golden_settings_gc_9_x_common[] =
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_CAM_DATA, 0xffffffff, 0x2544c382)
};
static const struct soc15_reg_golden golden_settings_gc_9_2_1[] =
{
SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG2, 0xf00fffff, 0x00000420),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGB_GPU_ID, 0x0000000f, 0x00000000),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_BINNER_EVENT_CNTL_3, 0x00000003, 0x82400024),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE, 0x3fffffff, 0x00000001),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_LINE_STIPPLE_STATE, 0x0000ff0f, 0x00000000),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSH_MEM_CONFIG, 0x00001000, 0x00001000),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_RESOURCE_RESERVE_CU_0, 0x0007ffff, 0x00000800),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_RESOURCE_RESERVE_CU_1, 0x0007ffff, 0x00000800),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_RESOURCE_RESERVE_EN_CU_0, 0x01ffffff, 0x0000ff87),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_RESOURCE_RESERVE_EN_CU_1, 0x01ffffff, 0x0000ff8f),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQC_CONFIG, 0x03000000, 0x020a2000),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0xfffffeef, 0x010b0000),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_HI, 0xffffffff, 0x4a2c0e68),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_LO, 0xffffffff, 0xb5d3f197),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmVGT_CACHE_INVALIDATION, 0x3fff3af3, 0x19200000),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmVGT_GS_MAX_WAVE_ID, 0x00000fff, 0x000003ff)
};
static const struct soc15_reg_golden golden_settings_gc_9_2_1_vg12[] =
{
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_DCC_CONFIG, 0x00000080, 0x04000080),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL, 0xfffdf3cf, 0x00014104),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL_2, 0x0f000000, 0x0a000000),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGB_ADDR_CONFIG, 0xffff77ff, 0x24104041),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGB_ADDR_CONFIG_READ, 0xffff77ff, 0x24104041),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE_1, 0xffffffff, 0x04040000),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_CONFIG_CNTL_1, 0xffff03ff, 0x01000107),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_HI, 0xffffffff, 0x00000000),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_LO, 0xffffffff, 0x76325410),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmTD_CNTL, 0x01bd9f33, 0x01000000)
};
#define VEGA10_GB_ADDR_CONFIG_GOLDEN 0x2a114042
#define VEGA12_GB_ADDR_CONFIG_GOLDEN 0x24104041
#define RAVEN_GB_ADDR_CONFIG_GOLDEN 0x24000042
static void gfx_v9_0_set_ring_funcs(struct amdgpu_device *adev);
@ -168,6 +210,14 @@ static void gfx_v9_0_init_golden_registers(struct amdgpu_device *adev)
golden_settings_gc_9_0_vg10,
ARRAY_SIZE(golden_settings_gc_9_0_vg10));
break;
case CHIP_VEGA12:
soc15_program_register_sequence(adev,
golden_settings_gc_9_2_1,
ARRAY_SIZE(golden_settings_gc_9_2_1));
soc15_program_register_sequence(adev,
golden_settings_gc_9_2_1_vg12,
ARRAY_SIZE(golden_settings_gc_9_2_1_vg12));
break;
case CHIP_RAVEN:
soc15_program_register_sequence(adev,
golden_settings_gc_9_1,
@ -369,6 +419,9 @@ static int gfx_v9_0_init_microcode(struct amdgpu_device *adev)
case CHIP_VEGA10:
chip_name = "vega10";
break;
case CHIP_VEGA12:
chip_name = "vega12";
break;
case CHIP_RAVEN:
chip_name = "raven";
break;
@ -968,6 +1021,15 @@ static void gfx_v9_0_gpu_early_init(struct amdgpu_device *adev)
adev->gfx.config.sc_earlyz_tile_fifo_size = 0x4C0;
gb_addr_config = VEGA10_GB_ADDR_CONFIG_GOLDEN;
break;
case CHIP_VEGA12:
adev->gfx.config.max_hw_contexts = 8;
adev->gfx.config.sc_prim_fifo_size_frontend = 0x20;
adev->gfx.config.sc_prim_fifo_size_backend = 0x100;
adev->gfx.config.sc_hiz_tile_fifo_size = 0x30;
adev->gfx.config.sc_earlyz_tile_fifo_size = 0x4C0;
gb_addr_config = VEGA12_GB_ADDR_CONFIG_GOLDEN;
DRM_INFO("fix gfx.config for vega12\n");
break;
case CHIP_RAVEN:
adev->gfx.config.max_hw_contexts = 8;
adev->gfx.config.sc_prim_fifo_size_frontend = 0x20;
@ -1249,6 +1311,7 @@ static int gfx_v9_0_sw_init(void *handle)
switch (adev->asic_type) {
case CHIP_VEGA10:
case CHIP_VEGA12:
case CHIP_RAVEN:
adev->gfx.mec.num_mec = 2;
break;
@ -3482,6 +3545,7 @@ static int gfx_v9_0_set_clockgating_state(void *handle,
switch (adev->asic_type) {
case CHIP_VEGA10:
case CHIP_VEGA12:
case CHIP_RAVEN:
gfx_v9_0_update_gfx_clock_gating(adev,
state == AMD_CG_STATE_GATE ? true : false);
@ -4453,6 +4517,7 @@ static void gfx_v9_0_set_rlc_funcs(struct amdgpu_device *adev)
{
switch (adev->asic_type) {
case CHIP_VEGA10:
case CHIP_VEGA12:
case CHIP_RAVEN:
adev->gfx.rlc.funcs = &gfx_v9_0_rlc_funcs;
break;

View File

@ -791,6 +791,7 @@ static int gmc_v9_0_mc_init(struct amdgpu_device *adev)
if (amdgpu_gart_size == -1) {
switch (adev->asic_type) {
case CHIP_VEGA10: /* all engines support GPUVM */
case CHIP_VEGA12: /* all engines support GPUVM */
default:
adev->gmc.gart_size = 512ULL << 20;
break;
@ -849,6 +850,7 @@ static int gmc_v9_0_sw_init(void *handle)
}
break;
case CHIP_VEGA10:
case CHIP_VEGA12:
/*
* To fulfill 4-level page support,
* vm size is 256TB (48bit), maximum size of Vega10,
@ -965,6 +967,8 @@ static void gmc_v9_0_init_golden_registers(struct amdgpu_device *adev)
golden_settings_athub_1_0_0,
ARRAY_SIZE(golden_settings_athub_1_0_0));
break;
case CHIP_VEGA12:
break;
case CHIP_RAVEN:
soc15_program_register_sequence(adev,
golden_settings_athub_1_0_0,

View File

@ -2963,6 +2963,7 @@ static int kv_dpm_early_init(void *handle)
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
adev->powerplay.pp_funcs = &kv_dpm_funcs;
adev->powerplay.pp_handle = adev;
kv_dpm_set_irq_funcs(adev);
return 0;

View File

@ -733,6 +733,7 @@ int mmhub_v1_0_set_clockgating(struct amdgpu_device *adev,
switch (adev->asic_type) {
case CHIP_VEGA10:
case CHIP_VEGA12:
case CHIP_RAVEN:
mmhub_v1_0_update_medium_grain_clock_gating(adev,
state == AMD_CG_STATE_GATE ? true : false);

View File

@ -129,7 +129,7 @@ static void xgpu_ai_mailbox_trans_msg (struct amdgpu_device *adev,
xgpu_ai_mailbox_set_valid(adev, false);
trn = xgpu_ai_peek_ack(adev);
if (trn) {
pr_err("trn=%x ACK should not asssert! wait again !\n", trn);
pr_err("trn=%x ACK should not assert! wait again !\n", trn);
msleep(1);
}
} while(trn);

View File

@ -220,12 +220,12 @@ static u32 nbio_v6_1_get_hdp_flush_done_offset(struct amdgpu_device *adev)
static u32 nbio_v6_1_get_pcie_index_offset(struct amdgpu_device *adev)
{
return SOC15_REG_OFFSET(NBIO, 0, mmPCIE_INDEX);
return SOC15_REG_OFFSET(NBIO, 0, mmPCIE_INDEX2);
}
static u32 nbio_v6_1_get_pcie_data_offset(struct amdgpu_device *adev)
{
return SOC15_REG_OFFSET(NBIO, 0, mmPCIE_DATA);
return SOC15_REG_OFFSET(NBIO, 0, mmPCIE_DATA2);
}
static const struct nbio_hdp_flush_reg nbio_v6_1_hdp_flush_reg = {

View File

@ -39,6 +39,8 @@
MODULE_FIRMWARE("amdgpu/vega10_sos.bin");
MODULE_FIRMWARE("amdgpu/vega10_asd.bin");
MODULE_FIRMWARE("amdgpu/vega12_sos.bin");
MODULE_FIRMWARE("amdgpu/vega12_asd.bin");
#define smnMP1_FIRMWARE_FLAGS 0x3010028
@ -107,6 +109,9 @@ static int psp_v3_1_init_microcode(struct psp_context *psp)
case CHIP_VEGA10:
chip_name = "vega10";
break;
case CHIP_VEGA12:
chip_name = "vega12";
break;
default: BUG();
}

View File

@ -40,6 +40,8 @@
MODULE_FIRMWARE("amdgpu/vega10_sdma.bin");
MODULE_FIRMWARE("amdgpu/vega10_sdma1.bin");
MODULE_FIRMWARE("amdgpu/vega12_sdma.bin");
MODULE_FIRMWARE("amdgpu/vega12_sdma1.bin");
MODULE_FIRMWARE("amdgpu/raven_sdma.bin");
#define SDMA0_POWER_CNTL__ON_OFF_CONDITION_HOLD_TIME_MASK 0x000000F8L
@ -84,6 +86,13 @@ static const struct soc15_reg_golden golden_settings_sdma_vg10[] = {
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_GB_ADDR_CONFIG_READ, 0x0018773f, 0x00104002)
};
static const struct soc15_reg_golden golden_settings_sdma_vg12[] = {
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_GB_ADDR_CONFIG, 0x0018773f, 0x00104001),
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_GB_ADDR_CONFIG_READ, 0x0018773f, 0x00104001),
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_GB_ADDR_CONFIG, 0x0018773f, 0x00104001),
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_GB_ADDR_CONFIG_READ, 0x0018773f, 0x00104001)
};
static const struct soc15_reg_golden golden_settings_sdma_4_1[] =
{
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_CHICKEN_BITS, 0xfe931f07, 0x02831d07),
@ -122,6 +131,14 @@ static void sdma_v4_0_init_golden_registers(struct amdgpu_device *adev)
golden_settings_sdma_vg10,
ARRAY_SIZE(golden_settings_sdma_vg10));
break;
case CHIP_VEGA12:
soc15_program_register_sequence(adev,
golden_settings_sdma_4,
ARRAY_SIZE(golden_settings_sdma_4));
soc15_program_register_sequence(adev,
golden_settings_sdma_vg12,
ARRAY_SIZE(golden_settings_sdma_vg12));
break;
case CHIP_RAVEN:
soc15_program_register_sequence(adev,
golden_settings_sdma_4_1,
@ -162,6 +179,9 @@ static int sdma_v4_0_init_microcode(struct amdgpu_device *adev)
case CHIP_VEGA10:
chip_name = "vega10";
break;
case CHIP_VEGA12:
chip_name = "vega12";
break;
case CHIP_RAVEN:
chip_name = "raven";
break;
@ -1489,6 +1509,7 @@ static int sdma_v4_0_set_clockgating_state(void *handle,
switch (adev->asic_type) {
case CHIP_VEGA10:
case CHIP_VEGA12:
case CHIP_RAVEN:
sdma_v4_0_update_medium_grain_clock_gating(adev,
state == AMD_CG_STATE_GATE ? true : false);
@ -1618,7 +1639,7 @@ static void sdma_v4_0_set_irq_funcs(struct amdgpu_device *adev)
* @dst_offset: dst GPU address
* @byte_count: number of bytes to xfer
*
* Copy GPU buffers using the DMA engine (VEGA10).
* Copy GPU buffers using the DMA engine (VEGA10/12).
* Used by the amdgpu ttm implementation to move pages if
* registered as the asic copy callback.
*/
@ -1645,7 +1666,7 @@ static void sdma_v4_0_emit_copy_buffer(struct amdgpu_ib *ib,
* @dst_offset: dst GPU address
* @byte_count: number of bytes to xfer
*
* Fill GPU buffers using the DMA engine (VEGA10).
* Fill GPU buffers using the DMA engine (VEGA10/12).
*/
static void sdma_v4_0_emit_fill_buffer(struct amdgpu_ib *ib,
uint32_t src_data,

View File

@ -7917,6 +7917,7 @@ static int si_dpm_early_init(void *handle)
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
adev->powerplay.pp_funcs = &si_dpm_funcs;
adev->powerplay.pp_handle = adev;
si_dpm_set_irq_funcs(adev);
return 0;
}

View File

@ -508,6 +508,7 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
/* Set IP register base before any HW register access */
switch (adev->asic_type) {
case CHIP_VEGA10:
case CHIP_VEGA12:
case CHIP_RAVEN:
vega10_reg_base_init(adev);
break;
@ -527,6 +528,7 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
switch (adev->asic_type) {
case CHIP_VEGA10:
case CHIP_VEGA12:
amdgpu_device_ip_block_add(adev, &vega10_common_ip_block);
amdgpu_device_ip_block_add(adev, &gmc_v9_0_ip_block);
amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block);
@ -608,7 +610,6 @@ static const struct amdgpu_asic_funcs soc15_asic_funcs =
static int soc15_common_early_init(void *handle)
{
bool psp_enabled = false;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
adev->smc_rreg = NULL;
@ -626,10 +627,6 @@ static int soc15_common_early_init(void *handle)
adev->asic_funcs = &soc15_asic_funcs;
if (amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_PSP) &&
(amdgpu_ip_block_mask & (1 << AMD_IP_BLOCK_TYPE_PSP)))
psp_enabled = true;
adev->rev_id = soc15_get_rev_id(adev);
adev->external_rev_id = 0xFF;
switch (adev->asic_type) {
@ -656,6 +653,28 @@ static int soc15_common_early_init(void *handle)
adev->pg_flags = 0;
adev->external_rev_id = 0x1;
break;
case CHIP_VEGA12:
adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
AMD_CG_SUPPORT_GFX_MGLS |
AMD_CG_SUPPORT_GFX_CGCG |
AMD_CG_SUPPORT_GFX_CGLS |
AMD_CG_SUPPORT_GFX_3D_CGCG |
AMD_CG_SUPPORT_GFX_3D_CGLS |
AMD_CG_SUPPORT_GFX_CP_LS |
AMD_CG_SUPPORT_MC_LS |
AMD_CG_SUPPORT_MC_MGCG |
AMD_CG_SUPPORT_SDMA_MGCG |
AMD_CG_SUPPORT_SDMA_LS |
AMD_CG_SUPPORT_BIF_MGCG |
AMD_CG_SUPPORT_BIF_LS |
AMD_CG_SUPPORT_HDP_MGCG |
AMD_CG_SUPPORT_HDP_LS |
AMD_CG_SUPPORT_ROM_MGCG |
AMD_CG_SUPPORT_VCE_MGCG |
AMD_CG_SUPPORT_UVD_MGCG;
adev->pg_flags = 0;
adev->external_rev_id = adev->rev_id + 0x14;
break;
case CHIP_RAVEN:
adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
AMD_CG_SUPPORT_GFX_MGLS |
@ -888,6 +907,7 @@ static int soc15_common_set_clockgating_state(void *handle,
switch (adev->asic_type) {
case CHIP_VEGA10:
case CHIP_VEGA12:
adev->nbio_funcs->update_medium_grain_clock_gating(adev,
state == AMD_CG_STATE_GATE ? true : false);
adev->nbio_funcs->update_medium_grain_light_sleep(adev,

View File

@ -896,7 +896,6 @@ static const struct amdgpu_asic_funcs vi_asic_funcs =
static int vi_common_early_init(void *handle)
{
bool smc_enabled = false;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
if (adev->flags & AMD_IS_APU) {
@ -917,10 +916,6 @@ static int vi_common_early_init(void *handle)
adev->asic_funcs = &vi_asic_funcs;
if (amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_SMC) &&
(amdgpu_ip_block_mask & (1 << AMD_IP_BLOCK_TYPE_SMC)))
smc_enabled = true;
adev->rev_id = vi_get_rev_id(adev);
adev->external_rev_id = 0xFF;
switch (adev->asic_type) {

View File

@ -1130,6 +1130,7 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev)
unsigned client_id = AMDGPU_IH_CLIENTID_LEGACY;
if (adev->asic_type == CHIP_VEGA10 ||
adev->asic_type == CHIP_VEGA12 ||
adev->asic_type == CHIP_RAVEN)
client_id = SOC15_IH_CLIENTID_DCE;
@ -1501,6 +1502,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
case CHIP_POLARIS10:
case CHIP_POLARIS12:
case CHIP_VEGA10:
case CHIP_VEGA12:
if (dce110_register_irq_handlers(dm->adev)) {
DRM_ERROR("DM: Failed to initialize IRQ\n");
goto fail;
@ -1698,6 +1700,7 @@ static int dm_early_init(void *handle)
adev->mode_info.plane_type = dm_plane_type_default;
break;
case CHIP_VEGA10:
case CHIP_VEGA12:
adev->mode_info.num_crtc = 6;
adev->mode_info.num_hpd = 6;
adev->mode_info.num_dig = 6;
@ -1945,6 +1948,7 @@ static int fill_plane_attributes_from_fb(struct amdgpu_device *adev,
AMDGPU_TILING_GET(tiling_flags, PIPE_CONFIG);
if (adev->asic_type == CHIP_VEGA10 ||
adev->asic_type == CHIP_VEGA12 ||
adev->asic_type == CHIP_RAVEN) {
/* Fill GFX9 params */
plane_state->tiling_info.gfx9.num_pipes =

View File

@ -1321,6 +1321,7 @@ static enum bp_result bios_parser_get_firmware_info(
case 3:
switch (revision.minor) {
case 1:
case 2:
result = get_firmware_info_v3_1(bp, info);
break;
default:

View File

@ -32,7 +32,7 @@
#include <linux/kref.h>
#include "cgs_linux.h"
#include "cgs_common.h"
#if defined(__BIG_ENDIAN) && !defined(BIGENDIAN_CPU)
#define BIGENDIAN_CPU

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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,337 @@
/*
* Copyright (C) 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) 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 _osssys_4_0_1_OFFSET_HEADER
#define _osssys_4_0_1_OFFSET_HEADER
// addressBlock: osssys_osssysdec
// base address: 0x4280
#define mmIH_VMID_0_LUT 0x0000
#define mmIH_VMID_0_LUT_BASE_IDX 0
#define mmIH_VMID_1_LUT 0x0001
#define mmIH_VMID_1_LUT_BASE_IDX 0
#define mmIH_VMID_2_LUT 0x0002
#define mmIH_VMID_2_LUT_BASE_IDX 0
#define mmIH_VMID_3_LUT 0x0003
#define mmIH_VMID_3_LUT_BASE_IDX 0
#define mmIH_VMID_4_LUT 0x0004
#define mmIH_VMID_4_LUT_BASE_IDX 0
#define mmIH_VMID_5_LUT 0x0005
#define mmIH_VMID_5_LUT_BASE_IDX 0
#define mmIH_VMID_6_LUT 0x0006
#define mmIH_VMID_6_LUT_BASE_IDX 0
#define mmIH_VMID_7_LUT 0x0007
#define mmIH_VMID_7_LUT_BASE_IDX 0
#define mmIH_VMID_8_LUT 0x0008
#define mmIH_VMID_8_LUT_BASE_IDX 0
#define mmIH_VMID_9_LUT 0x0009
#define mmIH_VMID_9_LUT_BASE_IDX 0
#define mmIH_VMID_10_LUT 0x000a
#define mmIH_VMID_10_LUT_BASE_IDX 0
#define mmIH_VMID_11_LUT 0x000b
#define mmIH_VMID_11_LUT_BASE_IDX 0
#define mmIH_VMID_12_LUT 0x000c
#define mmIH_VMID_12_LUT_BASE_IDX 0
#define mmIH_VMID_13_LUT 0x000d
#define mmIH_VMID_13_LUT_BASE_IDX 0
#define mmIH_VMID_14_LUT 0x000e
#define mmIH_VMID_14_LUT_BASE_IDX 0
#define mmIH_VMID_15_LUT 0x000f
#define mmIH_VMID_15_LUT_BASE_IDX 0
#define mmIH_VMID_0_LUT_MM 0x0010
#define mmIH_VMID_0_LUT_MM_BASE_IDX 0
#define mmIH_VMID_1_LUT_MM 0x0011
#define mmIH_VMID_1_LUT_MM_BASE_IDX 0
#define mmIH_VMID_2_LUT_MM 0x0012
#define mmIH_VMID_2_LUT_MM_BASE_IDX 0
#define mmIH_VMID_3_LUT_MM 0x0013
#define mmIH_VMID_3_LUT_MM_BASE_IDX 0
#define mmIH_VMID_4_LUT_MM 0x0014
#define mmIH_VMID_4_LUT_MM_BASE_IDX 0
#define mmIH_VMID_5_LUT_MM 0x0015
#define mmIH_VMID_5_LUT_MM_BASE_IDX 0
#define mmIH_VMID_6_LUT_MM 0x0016
#define mmIH_VMID_6_LUT_MM_BASE_IDX 0
#define mmIH_VMID_7_LUT_MM 0x0017
#define mmIH_VMID_7_LUT_MM_BASE_IDX 0
#define mmIH_VMID_8_LUT_MM 0x0018
#define mmIH_VMID_8_LUT_MM_BASE_IDX 0
#define mmIH_VMID_9_LUT_MM 0x0019
#define mmIH_VMID_9_LUT_MM_BASE_IDX 0
#define mmIH_VMID_10_LUT_MM 0x001a
#define mmIH_VMID_10_LUT_MM_BASE_IDX 0
#define mmIH_VMID_11_LUT_MM 0x001b
#define mmIH_VMID_11_LUT_MM_BASE_IDX 0
#define mmIH_VMID_12_LUT_MM 0x001c
#define mmIH_VMID_12_LUT_MM_BASE_IDX 0
#define mmIH_VMID_13_LUT_MM 0x001d
#define mmIH_VMID_13_LUT_MM_BASE_IDX 0
#define mmIH_VMID_14_LUT_MM 0x001e
#define mmIH_VMID_14_LUT_MM_BASE_IDX 0
#define mmIH_VMID_15_LUT_MM 0x001f
#define mmIH_VMID_15_LUT_MM_BASE_IDX 0
#define mmIH_COOKIE_0 0x0020
#define mmIH_COOKIE_0_BASE_IDX 0
#define mmIH_COOKIE_1 0x0021
#define mmIH_COOKIE_1_BASE_IDX 0
#define mmIH_COOKIE_2 0x0022
#define mmIH_COOKIE_2_BASE_IDX 0
#define mmIH_COOKIE_3 0x0023
#define mmIH_COOKIE_3_BASE_IDX 0
#define mmIH_COOKIE_4 0x0024
#define mmIH_COOKIE_4_BASE_IDX 0
#define mmIH_COOKIE_5 0x0025
#define mmIH_COOKIE_5_BASE_IDX 0
#define mmIH_COOKIE_6 0x0026
#define mmIH_COOKIE_6_BASE_IDX 0
#define mmIH_COOKIE_7 0x0027
#define mmIH_COOKIE_7_BASE_IDX 0
#define mmIH_REGISTER_LAST_PART0 0x003f
#define mmIH_REGISTER_LAST_PART0_BASE_IDX 0
#define mmSEM_REQ_INPUT_0 0x0040
#define mmSEM_REQ_INPUT_0_BASE_IDX 0
#define mmSEM_REQ_INPUT_1 0x0041
#define mmSEM_REQ_INPUT_1_BASE_IDX 0
#define mmSEM_REQ_INPUT_2 0x0042
#define mmSEM_REQ_INPUT_2_BASE_IDX 0
#define mmSEM_REQ_INPUT_3 0x0043
#define mmSEM_REQ_INPUT_3_BASE_IDX 0
#define mmSEM_REGISTER_LAST_PART0 0x007f
#define mmSEM_REGISTER_LAST_PART0_BASE_IDX 0
#define mmIH_RB_CNTL 0x0080
#define mmIH_RB_CNTL_BASE_IDX 0
#define mmIH_RB_BASE 0x0081
#define mmIH_RB_BASE_BASE_IDX 0
#define mmIH_RB_BASE_HI 0x0082
#define mmIH_RB_BASE_HI_BASE_IDX 0
#define mmIH_RB_RPTR 0x0083
#define mmIH_RB_RPTR_BASE_IDX 0
#define mmIH_RB_WPTR 0x0084
#define mmIH_RB_WPTR_BASE_IDX 0
#define mmIH_RB_WPTR_ADDR_HI 0x0085
#define mmIH_RB_WPTR_ADDR_HI_BASE_IDX 0
#define mmIH_RB_WPTR_ADDR_LO 0x0086
#define mmIH_RB_WPTR_ADDR_LO_BASE_IDX 0
#define mmIH_DOORBELL_RPTR 0x0087
#define mmIH_DOORBELL_RPTR_BASE_IDX 0
#define mmIH_RB_CNTL_RING1 0x0088
#define mmIH_RB_CNTL_RING1_BASE_IDX 0
#define mmIH_RB_BASE_RING1 0x0089
#define mmIH_RB_BASE_RING1_BASE_IDX 0
#define mmIH_RB_BASE_HI_RING1 0x008a
#define mmIH_RB_BASE_HI_RING1_BASE_IDX 0
#define mmIH_RB_RPTR_RING1 0x008b
#define mmIH_RB_RPTR_RING1_BASE_IDX 0
#define mmIH_RB_WPTR_RING1 0x008c
#define mmIH_RB_WPTR_RING1_BASE_IDX 0
#define mmIH_DOORBELL_RPTR_RING1 0x008f
#define mmIH_DOORBELL_RPTR_RING1_BASE_IDX 0
#define mmIH_RB_CNTL_RING2 0x0090
#define mmIH_RB_CNTL_RING2_BASE_IDX 0
#define mmIH_RB_BASE_RING2 0x0091
#define mmIH_RB_BASE_RING2_BASE_IDX 0
#define mmIH_RB_BASE_HI_RING2 0x0092
#define mmIH_RB_BASE_HI_RING2_BASE_IDX 0
#define mmIH_RB_RPTR_RING2 0x0093
#define mmIH_RB_RPTR_RING2_BASE_IDX 0
#define mmIH_RB_WPTR_RING2 0x0094
#define mmIH_RB_WPTR_RING2_BASE_IDX 0
#define mmIH_DOORBELL_RPTR_RING2 0x0097
#define mmIH_DOORBELL_RPTR_RING2_BASE_IDX 0
#define mmIH_VERSION 0x0098
#define mmIH_VERSION_BASE_IDX 0
#define mmIH_CNTL 0x00c0
#define mmIH_CNTL_BASE_IDX 0
#define mmIH_CNTL2 0x00c1
#define mmIH_CNTL2_BASE_IDX 0
#define mmIH_STATUS 0x00c2
#define mmIH_STATUS_BASE_IDX 0
#define mmIH_PERFMON_CNTL 0x00c3
#define mmIH_PERFMON_CNTL_BASE_IDX 0
#define mmIH_PERFCOUNTER0_RESULT 0x00c4
#define mmIH_PERFCOUNTER0_RESULT_BASE_IDX 0
#define mmIH_PERFCOUNTER1_RESULT 0x00c5
#define mmIH_PERFCOUNTER1_RESULT_BASE_IDX 0
#define mmIH_DSM_MATCH_VALUE_BIT_31_0 0x00c7
#define mmIH_DSM_MATCH_VALUE_BIT_31_0_BASE_IDX 0
#define mmIH_DSM_MATCH_VALUE_BIT_63_32 0x00c8
#define mmIH_DSM_MATCH_VALUE_BIT_63_32_BASE_IDX 0
#define mmIH_DSM_MATCH_VALUE_BIT_95_64 0x00c9
#define mmIH_DSM_MATCH_VALUE_BIT_95_64_BASE_IDX 0
#define mmIH_DSM_MATCH_FIELD_CONTROL 0x00ca
#define mmIH_DSM_MATCH_FIELD_CONTROL_BASE_IDX 0
#define mmIH_DSM_MATCH_DATA_CONTROL 0x00cb
#define mmIH_DSM_MATCH_DATA_CONTROL_BASE_IDX 0
#define mmIH_DSM_MATCH_FCN_ID 0x00cc
#define mmIH_DSM_MATCH_FCN_ID_BASE_IDX 0
#define mmIH_LIMIT_INT_RATE_CNTL 0x00cd
#define mmIH_LIMIT_INT_RATE_CNTL_BASE_IDX 0
#define mmIH_VF_RB_STATUS 0x00ce
#define mmIH_VF_RB_STATUS_BASE_IDX 0
#define mmIH_VF_RB_STATUS2 0x00cf
#define mmIH_VF_RB_STATUS2_BASE_IDX 0
#define mmIH_VF_RB1_STATUS 0x00d0
#define mmIH_VF_RB1_STATUS_BASE_IDX 0
#define mmIH_VF_RB1_STATUS2 0x00d1
#define mmIH_VF_RB1_STATUS2_BASE_IDX 0
#define mmIH_VF_RB2_STATUS 0x00d2
#define mmIH_VF_RB2_STATUS_BASE_IDX 0
#define mmIH_VF_RB2_STATUS2 0x00d3
#define mmIH_VF_RB2_STATUS2_BASE_IDX 0
#define mmIH_INT_FLOOD_CNTL 0x00d5
#define mmIH_INT_FLOOD_CNTL_BASE_IDX 0
#define mmIH_RB0_INT_FLOOD_STATUS 0x00d6
#define mmIH_RB0_INT_FLOOD_STATUS_BASE_IDX 0
#define mmIH_RB1_INT_FLOOD_STATUS 0x00d7
#define mmIH_RB1_INT_FLOOD_STATUS_BASE_IDX 0
#define mmIH_RB2_INT_FLOOD_STATUS 0x00d8
#define mmIH_RB2_INT_FLOOD_STATUS_BASE_IDX 0
#define mmIH_INT_FLOOD_STATUS 0x00d9
#define mmIH_INT_FLOOD_STATUS_BASE_IDX 0
#define mmIH_STORM_CLIENT_LIST_CNTL 0x00da
#define mmIH_STORM_CLIENT_LIST_CNTL_BASE_IDX 0
#define mmIH_CLK_CTRL 0x00db
#define mmIH_CLK_CTRL_BASE_IDX 0
#define mmIH_INT_FLAGS 0x00dc
#define mmIH_INT_FLAGS_BASE_IDX 0
#define mmIH_LAST_INT_INFO0 0x00dd
#define mmIH_LAST_INT_INFO0_BASE_IDX 0
#define mmIH_LAST_INT_INFO1 0x00de
#define mmIH_LAST_INT_INFO1_BASE_IDX 0
#define mmIH_LAST_INT_INFO2 0x00df
#define mmIH_LAST_INT_INFO2_BASE_IDX 0
#define mmIH_SCRATCH 0x00e0
#define mmIH_SCRATCH_BASE_IDX 0
#define mmIH_CLIENT_CREDIT_ERROR 0x00e1
#define mmIH_CLIENT_CREDIT_ERROR_BASE_IDX 0
#define mmIH_GPU_IOV_VIOLATION_LOG 0x00e2
#define mmIH_GPU_IOV_VIOLATION_LOG_BASE_IDX 0
#define mmIH_COOKIE_REC_VIOLATION_LOG 0x00e3
#define mmIH_COOKIE_REC_VIOLATION_LOG_BASE_IDX 0
#define mmIH_CREDIT_STATUS 0x00e4
#define mmIH_CREDIT_STATUS_BASE_IDX 0
#define mmIH_MMHUB_ERROR 0x00e5
#define mmIH_MMHUB_ERROR_BASE_IDX 0
#define mmIH_REGISTER_LAST_PART2 0x00ff
#define mmIH_REGISTER_LAST_PART2_BASE_IDX 0
#define mmSEM_CLK_CTRL 0x0100
#define mmSEM_CLK_CTRL_BASE_IDX 0
#define mmSEM_UTC_CREDIT 0x0101
#define mmSEM_UTC_CREDIT_BASE_IDX 0
#define mmSEM_UTC_CONFIG 0x0102
#define mmSEM_UTC_CONFIG_BASE_IDX 0
#define mmSEM_UTCL2_TRAN_EN_LUT 0x0103
#define mmSEM_UTCL2_TRAN_EN_LUT_BASE_IDX 0
#define mmSEM_MCIF_CONFIG 0x0104
#define mmSEM_MCIF_CONFIG_BASE_IDX 0
#define mmSEM_PERFMON_CNTL 0x0105
#define mmSEM_PERFMON_CNTL_BASE_IDX 0
#define mmSEM_PERFCOUNTER0_RESULT 0x0106
#define mmSEM_PERFCOUNTER0_RESULT_BASE_IDX 0
#define mmSEM_PERFCOUNTER1_RESULT 0x0107
#define mmSEM_PERFCOUNTER1_RESULT_BASE_IDX 0
#define mmSEM_STATUS 0x0108
#define mmSEM_STATUS_BASE_IDX 0
#define mmSEM_MAILBOX_CLIENTCONFIG 0x0109
#define mmSEM_MAILBOX_CLIENTCONFIG_BASE_IDX 0
#define mmSEM_MAILBOX 0x010a
#define mmSEM_MAILBOX_BASE_IDX 0
#define mmSEM_MAILBOX_CONTROL 0x010b
#define mmSEM_MAILBOX_CONTROL_BASE_IDX 0
#define mmSEM_CHICKEN_BITS 0x010c
#define mmSEM_CHICKEN_BITS_BASE_IDX 0
#define mmSEM_MAILBOX_CLIENTCONFIG_EXTRA 0x010d
#define mmSEM_MAILBOX_CLIENTCONFIG_EXTRA_BASE_IDX 0
#define mmSEM_GPU_IOV_VIOLATION_LOG 0x010e
#define mmSEM_GPU_IOV_VIOLATION_LOG_BASE_IDX 0
#define mmSEM_OUTSTANDING_THRESHOLD 0x010f
#define mmSEM_OUTSTANDING_THRESHOLD_BASE_IDX 0
#define mmSEM_REGISTER_LAST_PART2 0x017f
#define mmSEM_REGISTER_LAST_PART2_BASE_IDX 0
#define mmIH_ACTIVE_FCN_ID 0x0180
#define mmIH_ACTIVE_FCN_ID_BASE_IDX 0
#define mmIH_VIRT_RESET_REQ 0x0181
#define mmIH_VIRT_RESET_REQ_BASE_IDX 0
#define mmIH_CLIENT_CFG 0x0184
#define mmIH_CLIENT_CFG_BASE_IDX 0
#define mmIH_CLIENT_CFG_INDEX 0x0188
#define mmIH_CLIENT_CFG_INDEX_BASE_IDX 0
#define mmIH_CLIENT_CFG_DATA 0x0189
#define mmIH_CLIENT_CFG_DATA_BASE_IDX 0
#define mmIH_CID_REMAP_INDEX 0x018a
#define mmIH_CID_REMAP_INDEX_BASE_IDX 0
#define mmIH_CID_REMAP_DATA 0x018b
#define mmIH_CID_REMAP_DATA_BASE_IDX 0
#define mmIH_CHICKEN 0x018c
#define mmIH_CHICKEN_BASE_IDX 0
#define mmIH_MMHUB_CNTL 0x018d
#define mmIH_MMHUB_CNTL_BASE_IDX 0
#define mmIH_INT_DROP_CNTL 0x018e
#define mmIH_INT_DROP_CNTL_BASE_IDX 0
#define mmIH_INT_DROP_MATCH_VALUE0 0x018f
#define mmIH_INT_DROP_MATCH_VALUE0_BASE_IDX 0
#define mmIH_INT_DROP_MATCH_VALUE1 0x0190
#define mmIH_INT_DROP_MATCH_VALUE1_BASE_IDX 0
#define mmIH_INT_DROP_MATCH_MASK0 0x0191
#define mmIH_INT_DROP_MATCH_MASK0_BASE_IDX 0
#define mmIH_INT_DROP_MATCH_MASK1 0x0192
#define mmIH_INT_DROP_MATCH_MASK1_BASE_IDX 0
#define mmIH_REGISTER_LAST_PART1 0x019f
#define mmIH_REGISTER_LAST_PART1_BASE_IDX 0
#define mmSEM_ACTIVE_FCN_ID 0x01a0
#define mmSEM_ACTIVE_FCN_ID_BASE_IDX 0
#define mmSEM_VIRT_RESET_REQ 0x01a1
#define mmSEM_VIRT_RESET_REQ_BASE_IDX 0
#define mmSEM_RESP_SDMA0 0x01a4
#define mmSEM_RESP_SDMA0_BASE_IDX 0
#define mmSEM_RESP_SDMA1 0x01a5
#define mmSEM_RESP_SDMA1_BASE_IDX 0
#define mmSEM_RESP_UVD 0x01a6
#define mmSEM_RESP_UVD_BASE_IDX 0
#define mmSEM_RESP_VCE_0 0x01a7
#define mmSEM_RESP_VCE_0_BASE_IDX 0
#define mmSEM_RESP_ACP 0x01a8
#define mmSEM_RESP_ACP_BASE_IDX 0
#define mmSEM_RESP_ISP 0x01a9
#define mmSEM_RESP_ISP_BASE_IDX 0
#define mmSEM_RESP_VCE_1 0x01aa
#define mmSEM_RESP_VCE_1_BASE_IDX 0
#define mmSEM_RESP_VP8 0x01ab
#define mmSEM_RESP_VP8_BASE_IDX 0
#define mmSEM_RESP_GC 0x01ac
#define mmSEM_RESP_GC_BASE_IDX 0
#define mmSEM_CID_REMAP_INDEX 0x01b0
#define mmSEM_CID_REMAP_INDEX_BASE_IDX 0
#define mmSEM_CID_REMAP_DATA 0x01b1
#define mmSEM_CID_REMAP_DATA_BASE_IDX 0
#define mmSEM_ATOMIC_OP_LUT 0x01b2
#define mmSEM_ATOMIC_OP_LUT_BASE_IDX 0
#define mmSEM_EDC_CONFIG 0x01b3
#define mmSEM_EDC_CONFIG_BASE_IDX 0
#define mmSEM_CHICKEN_BITS2 0x01b4
#define mmSEM_CHICKEN_BITS2_BASE_IDX 0
#define mmSEM_MMHUB_CNTL 0x01b5
#define mmSEM_MMHUB_CNTL_BASE_IDX 0
#define mmSEM_REGISTER_LAST_PART1 0x01bf
#define mmSEM_REGISTER_LAST_PART1_BASE_IDX 0
#endif

File diff suppressed because it is too large Load Diff

View File

@ -381,7 +381,7 @@ struct atom_rom_hw_function_header
struct atom_master_list_of_data_tables_v2_1{
uint16_t utilitypipeline; /* Offest for the utility to get parser info,Don't change this position!*/
uint16_t multimedia_info;
uint16_t sw_datatable2;
uint16_t smc_dpm_info;
uint16_t sw_datatable3;
uint16_t firmwareinfo; /* Shared by various SW components */
uint16_t sw_datatable5;
@ -1198,6 +1198,86 @@ struct atom_smu_info_v3_1
uint8_t fw_ctf_polarity; // GPIO polarity for CTF
};
/*
***************************************************************************
Data Table smc_dpm_info structure
***************************************************************************
*/
struct atom_smc_dpm_info_v4_1
{
struct atom_common_table_header table_header;
uint8_t liquid1_i2c_address;
uint8_t liquid2_i2c_address;
uint8_t vr_i2c_address;
uint8_t plx_i2c_address;
uint8_t liquid_i2c_linescl;
uint8_t liquid_i2c_linesda;
uint8_t vr_i2c_linescl;
uint8_t vr_i2c_linesda;
uint8_t plx_i2c_linescl;
uint8_t plx_i2c_linesda;
uint8_t vrsensorpresent;
uint8_t liquidsensorpresent;
uint16_t maxvoltagestepgfx;
uint16_t maxvoltagestepsoc;
uint8_t vddgfxvrmapping;
uint8_t vddsocvrmapping;
uint8_t vddmem0vrmapping;
uint8_t vddmem1vrmapping;
uint8_t gfxulvphasesheddingmask;
uint8_t soculvphasesheddingmask;
uint8_t padding8_v[2];
uint16_t gfxmaxcurrent;
uint8_t gfxoffset;
uint8_t padding_telemetrygfx;
uint16_t socmaxcurrent;
uint8_t socoffset;
uint8_t padding_telemetrysoc;
uint16_t mem0maxcurrent;
uint8_t mem0offset;
uint8_t padding_telemetrymem0;
uint16_t mem1maxcurrent;
uint8_t mem1offset;
uint8_t padding_telemetrymem1;
uint8_t acdcgpio;
uint8_t acdcpolarity;
uint8_t vr0hotgpio;
uint8_t vr0hotpolarity;
uint8_t vr1hotgpio;
uint8_t vr1hotpolarity;
uint8_t padding1;
uint8_t padding2;
uint8_t ledpin0;
uint8_t ledpin1;
uint8_t ledpin2;
uint8_t padding8_4;
uint8_t gfxclkspreadenabled;
uint8_t gfxclkspreadpercent;
uint16_t gfxclkspreadfreq;
uint8_t uclkspreadenabled;
uint8_t uclkspreadpercent;
uint16_t uclkspreadfreq;
uint8_t socclkspreadenabled;
uint8_t socclkspreadpercent;
uint16_t socclkspreadfreq;
uint32_t boardreserved[3];
};
/*

View File

@ -106,7 +106,6 @@ struct cgs_firmware_info {
struct cgs_mode_info {
uint32_t refresh_rate;
uint32_t ref_clock;
uint32_t vblank_time_us;
};
@ -291,7 +290,6 @@ struct cgs_os_ops; /* To be define in OS-specific CGS header */
struct cgs_device
{
const struct cgs_ops *ops;
const struct cgs_os_ops *os_ops;
/* to be embedded at the start of driver private structure */
};

View File

@ -1,119 +0,0 @@
/*
* Copyright 2015 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 _CGS_LINUX_H
#define _CGS_LINUX_H
#include "cgs_common.h"
/**
* cgs_irq_source_set_func() - Callback for enabling/disabling interrupt sources
* @private_data: private data provided to cgs_add_irq_source
* @src_id: interrupt source ID
* @type: interrupt type
* @enabled: 0 = disable source, non-0 = enable source
*
* Return: 0 on success, -errno otherwise
*/
typedef int (*cgs_irq_source_set_func_t)(void *private_data,
unsigned src_id, unsigned type,
int enabled);
/**
* cgs_irq_handler_func() - Interrupt handler callback
* @private_data: private data provided to cgs_add_irq_source
* @src_id: interrupt source ID
* @iv_entry: pointer to raw ih ring entry
*
* This callback runs in interrupt context.
*
* Return: 0 on success, -errno otherwise
*/
typedef int (*cgs_irq_handler_func_t)(void *private_data,
unsigned src_id, const uint32_t *iv_entry);
/**
* cgs_add_irq_source() - Add an IRQ source
* @cgs_device: opaque device handle
* @src_id: interrupt source ID
* @num_types: number of interrupt types that can be independently enabled
* @set: callback function to enable/disable an interrupt type
* @handler: interrupt handler callback
* @private_data: private data to pass to callback functions
*
* The same IRQ source can be added only once. Adding an IRQ source
* indicates ownership of that IRQ source and all its IRQ types.
*
* Return: 0 on success, -errno otherwise
*/
typedef int (*cgs_add_irq_source_t)(void *cgs_device, unsigned client_id,
unsigned src_id,
unsigned num_types,
cgs_irq_source_set_func_t set,
cgs_irq_handler_func_t handler,
void *private_data);
/**
* cgs_irq_get() - Request enabling an IRQ source and type
* @cgs_device: opaque device handle
* @src_id: interrupt source ID
* @type: interrupt type
*
* cgs_irq_get and cgs_irq_put calls must be balanced. They count
* "references" to IRQ sources.
*
* Return: 0 on success, -errno otherwise
*/
typedef int (*cgs_irq_get_t)(void *cgs_device, unsigned client_id, unsigned src_id, unsigned type);
/**
* cgs_irq_put() - Indicate IRQ source is no longer needed
* @cgs_device: opaque device handle
* @src_id: interrupt source ID
* @type: interrupt type
*
* cgs_irq_get and cgs_irq_put calls must be balanced. They count
* "references" to IRQ sources. Even after cgs_irq_put is called, the
* IRQ handler may still be called if there are more refecences to
* the IRQ source.
*
* Return: 0 on success, -errno otherwise
*/
typedef int (*cgs_irq_put_t)(void *cgs_device, unsigned client_id, unsigned src_id, unsigned type);
struct cgs_os_ops {
/* IRQ handling */
cgs_add_irq_source_t add_irq_source;
cgs_irq_get_t irq_get;
cgs_irq_put_t irq_put;
};
#define cgs_add_irq_source(dev,client_id,src_id,num_types,set,handler,private_data) \
CGS_OS_CALL(add_irq_source,dev,client_id,src_id,num_types,set,handler, \
private_data)
#define cgs_irq_get(dev,client_id,src_id,type) \
CGS_OS_CALL(irq_get,dev,client_id,src_id,type)
#define cgs_irq_put(dev,client_id,src_id,type) \
CGS_OS_CALL(irq_put,dev,client_id,src_id,type)
#endif /* _CGS_LINUX_H */

View File

@ -23,7 +23,7 @@
#ifndef _DM_PP_INTERFACE_
#define _DM_PP_INTERFACE_
#define PP_MAX_CLOCK_LEVELS 8
#define PP_MAX_CLOCK_LEVELS 16
enum amd_pp_display_config_type{
AMD_PP_DisplayConfigType_None = 0,

View File

@ -117,6 +117,8 @@ static int pp_sw_init(void *handle)
ret = hwmgr->smumgr_funcs->smu_init(hwmgr);
phm_register_irq_handlers(hwmgr);
pr_debug("amdgpu: powerplay sw initialized\n");
}
@ -286,6 +288,12 @@ static int pp_resume(void *handle)
return hwmgr_hw_resume(hwmgr);
}
static int pp_set_clockgating_state(void *handle,
enum amd_clockgating_state state)
{
return 0;
}
static const struct amd_ip_funcs pp_ip_funcs = {
.name = "powerplay",
.early_init = pp_early_init,
@ -300,7 +308,7 @@ static const struct amd_ip_funcs pp_ip_funcs = {
.is_idle = pp_is_idle,
.wait_for_idle = pp_wait_for_idle,
.soft_reset = pp_sw_reset,
.set_clockgating_state = NULL,
.set_clockgating_state = pp_set_clockgating_state,
.set_powergating_state = pp_set_powergating_state,
};
@ -732,7 +740,7 @@ static int amd_powerplay_reset(void *handle)
if (ret)
return ret;
ret = pp_hw_fini(hwmgr);
ret = hwmgr_hw_fini(hwmgr);
if (ret)
return ret;

View File

@ -31,6 +31,8 @@ HARDWARE_MGR = hwmgr.o processpptables.o \
smu7_clockpowergating.o \
vega10_processpptables.o vega10_hwmgr.o vega10_powertune.o \
vega10_thermal.o smu10_hwmgr.o pp_psm.o\
vega12_processpptables.o vega12_hwmgr.o \
vega12_powertune.o vega12_thermal.o \
pp_overdriver.o smu_helper.o
AMD_PP_HWMGR = $(addprefix $(AMD_PP_PATH)/hwmgr/,$(HARDWARE_MGR))

View File

@ -202,12 +202,12 @@ int phm_stop_thermal_controller(struct pp_hwmgr *hwmgr)
return hwmgr->hwmgr_func->stop_thermal_controller(hwmgr);
}
int phm_register_thermal_interrupt(struct pp_hwmgr *hwmgr, const void *info)
int phm_register_irq_handlers(struct pp_hwmgr *hwmgr)
{
PHM_FUNC_CHECK(hwmgr);
if (hwmgr->hwmgr_func->register_internal_thermal_interrupt != NULL)
return hwmgr->hwmgr_func->register_internal_thermal_interrupt(hwmgr, info);
if (hwmgr->hwmgr_func->register_irq_handlers != NULL)
return hwmgr->hwmgr_func->register_irq_handlers(hwmgr);
return 0;
}

View File

@ -41,11 +41,13 @@ extern const struct pp_smumgr_func tonga_smu_funcs;
extern const struct pp_smumgr_func fiji_smu_funcs;
extern const struct pp_smumgr_func polaris10_smu_funcs;
extern const struct pp_smumgr_func vega10_smu_funcs;
extern const struct pp_smumgr_func vega12_smu_funcs;
extern const struct pp_smumgr_func smu10_smu_funcs;
extern int smu7_init_function_pointers(struct pp_hwmgr *hwmgr);
extern int smu8_init_function_pointers(struct pp_hwmgr *hwmgr);
extern int vega10_hwmgr_init(struct pp_hwmgr *hwmgr);
extern int vega12_hwmgr_init(struct pp_hwmgr *hwmgr);
extern int smu10_init_function_pointers(struct pp_hwmgr *hwmgr);
static int polaris_set_asic_special_caps(struct pp_hwmgr *hwmgr);
@ -56,50 +58,6 @@ static int tonga_set_asic_special_caps(struct pp_hwmgr *hwmgr);
static int topaz_set_asic_special_caps(struct pp_hwmgr *hwmgr);
static int ci_set_asic_special_caps(struct pp_hwmgr *hwmgr);
static int phm_thermal_l2h_irq(void *private_data,
unsigned src_id, const uint32_t *iv_entry)
{
struct pp_hwmgr *hwmgr = (struct pp_hwmgr *)private_data;
struct amdgpu_device *adev = hwmgr->adev;
pr_warn("GPU over temperature range detected on PCIe %d:%d.%d!\n",
PCI_BUS_NUM(adev->pdev->devfn),
PCI_SLOT(adev->pdev->devfn),
PCI_FUNC(adev->pdev->devfn));
return 0;
}
static int phm_thermal_h2l_irq(void *private_data,
unsigned src_id, const uint32_t *iv_entry)
{
struct pp_hwmgr *hwmgr = (struct pp_hwmgr *)private_data;
struct amdgpu_device *adev = hwmgr->adev;
pr_warn("GPU under temperature range detected on PCIe %d:%d.%d!\n",
PCI_BUS_NUM(adev->pdev->devfn),
PCI_SLOT(adev->pdev->devfn),
PCI_FUNC(adev->pdev->devfn));
return 0;
}
static int phm_ctf_irq(void *private_data,
unsigned src_id, const uint32_t *iv_entry)
{
struct pp_hwmgr *hwmgr = (struct pp_hwmgr *)private_data;
struct amdgpu_device *adev = hwmgr->adev;
pr_warn("GPU Critical Temperature Fault detected on PCIe %d:%d.%d!\n",
PCI_BUS_NUM(adev->pdev->devfn),
PCI_SLOT(adev->pdev->devfn),
PCI_FUNC(adev->pdev->devfn));
return 0;
}
static const struct cgs_irq_src_funcs thermal_irq_src[3] = {
{ .handler = phm_thermal_l2h_irq },
{ .handler = phm_thermal_h2l_irq },
{ .handler = phm_ctf_irq }
};
static void hwmgr_init_workload_prority(struct pp_hwmgr *hwmgr)
{
@ -186,6 +144,10 @@ int hwmgr_early_init(struct pp_hwmgr *hwmgr)
hwmgr->smumgr_funcs = &vega10_smu_funcs;
vega10_hwmgr_init(hwmgr);
break;
case CHIP_VEGA12:
hwmgr->smumgr_funcs = &vega12_smu_funcs;
vega12_hwmgr_init(hwmgr);
break;
default:
return -EINVAL;
}
@ -244,10 +206,6 @@ int hwmgr_hw_init(struct pp_hwmgr *hwmgr)
if (ret)
goto err2;
ret = phm_register_thermal_interrupt(hwmgr, &thermal_irq_src);
if (ret)
goto err2;
return 0;
err2:
if (hwmgr->hwmgr_func->backend_fini)

View File

@ -35,16 +35,21 @@ int psm_init_power_state_table(struct pp_hwmgr *hwmgr)
int size;
if (hwmgr->hwmgr_func->get_num_of_pp_table_entries == NULL)
return -EINVAL;
return 0;
if (hwmgr->hwmgr_func->get_power_state_size == NULL)
return -EINVAL;
return 0;
hwmgr->num_ps = table_entries = hwmgr->hwmgr_func->get_num_of_pp_table_entries(hwmgr);
hwmgr->ps_size = size = hwmgr->hwmgr_func->get_power_state_size(hwmgr) +
sizeof(struct pp_power_state);
if (table_entries == 0 || size == 0) {
pr_warn("Please check whether power state management is suppported on this asic\n");
return 0;
}
hwmgr->ps = kzalloc(size * table_entries, GFP_KERNEL);
if (hwmgr->ps == NULL)
return -ENOMEM;
@ -91,6 +96,9 @@ int psm_fini_power_state_table(struct pp_hwmgr *hwmgr)
if (hwmgr == NULL)
return -EINVAL;
if (!hwmgr->ps)
return 0;
kfree(hwmgr->current_ps);
kfree(hwmgr->request_ps);
kfree(hwmgr->ps);
@ -167,6 +175,9 @@ int psm_set_boot_states(struct pp_hwmgr *hwmgr)
unsigned long state_id;
int ret = -EINVAL;
if (!hwmgr->ps)
return 0;
if (!psm_get_state_by_classification(hwmgr, PP_StateClassificationFlag_Boot,
&state_id))
ret = psm_set_states(hwmgr, state_id);
@ -179,6 +190,9 @@ int psm_set_performance_states(struct pp_hwmgr *hwmgr)
unsigned long state_id;
int ret = -EINVAL;
if (!hwmgr->ps)
return 0;
if (!psm_get_ui_state(hwmgr, PP_StateUILabel_Performance,
&state_id))
ret = psm_set_states(hwmgr, state_id);
@ -193,6 +207,9 @@ int psm_set_user_performance_state(struct pp_hwmgr *hwmgr,
int table_entries;
int i;
if (!hwmgr->ps)
return 0;
table_entries = hwmgr->num_ps;
*state = hwmgr->ps;
@ -214,19 +231,12 @@ restart_search:
return -EINVAL;
}
int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip,
static void power_state_management(struct pp_hwmgr *hwmgr,
struct pp_power_state *new_ps)
{
struct pp_power_state *pcurrent;
struct pp_power_state *requested;
bool equal;
uint32_t index;
long workload;
if (skip)
return 0;
phm_display_configuration_changed(hwmgr);
if (new_ps != NULL)
requested = new_ps;
@ -244,8 +254,24 @@ int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip,
phm_set_power_state(hwmgr, &pcurrent->hardware, &requested->hardware);
memcpy(hwmgr->current_ps, hwmgr->request_ps, hwmgr->ps_size);
}
}
int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip,
struct pp_power_state *new_ps)
{
uint32_t index;
long workload;
if (skip)
return 0;
phm_display_configuration_changed(hwmgr);
if (hwmgr->ps)
power_state_management(hwmgr, new_ps);
phm_notify_smc_display_config_after_ps_adjustment(hwmgr);
if (!phm_force_dpm_levels(hwmgr, hwmgr->request_dpm_level))
hwmgr->dpm_level = hwmgr->request_dpm_level;

View File

@ -532,6 +532,7 @@ int pp_atomfwctrl_get_vbios_bootup_values(struct pp_hwmgr *hwmgr,
boot_values->usVddci = info->bootup_vddci_mv;
boot_values->usMvddc = info->bootup_mvddc_mv;
boot_values->usVddGfx = info->bootup_vddgfx_mv;
boot_values->ucCoolingID = info->coolingsolution_id;
boot_values->ulSocClk = 0;
boot_values->ulDCEFClk = 0;
@ -543,3 +544,89 @@ int pp_atomfwctrl_get_vbios_bootup_values(struct pp_hwmgr *hwmgr,
return 0;
}
int pp_atomfwctrl_get_smc_dpm_information(struct pp_hwmgr *hwmgr,
struct pp_atomfwctrl_smc_dpm_parameters *param)
{
struct atom_smc_dpm_info_v4_1 *info;
uint16_t ix;
ix = GetIndexIntoMasterDataTable(smc_dpm_info);
info = (struct atom_smc_dpm_info_v4_1 *)
cgs_atom_get_data_table(hwmgr->device,
ix, NULL, NULL, NULL);
if (!info) {
pr_info("Error retrieving BIOS Table Address!");
return -EINVAL;
}
param->liquid1_i2c_address = info->liquid1_i2c_address;
param->liquid2_i2c_address = info->liquid2_i2c_address;
param->vr_i2c_address = info->vr_i2c_address;
param->plx_i2c_address = info->plx_i2c_address;
param->liquid_i2c_linescl = info->liquid_i2c_linescl;
param->liquid_i2c_linesda = info->liquid_i2c_linesda;
param->vr_i2c_linescl = info->vr_i2c_linescl;
param->vr_i2c_linesda = info->vr_i2c_linesda;
param->plx_i2c_linescl = info->plx_i2c_linescl;
param->plx_i2c_linesda = info->plx_i2c_linesda;
param->vrsensorpresent = info->vrsensorpresent;
param->liquidsensorpresent = info->liquidsensorpresent;
param->maxvoltagestepgfx = info->maxvoltagestepgfx;
param->maxvoltagestepsoc = info->maxvoltagestepsoc;
param->vddgfxvrmapping = info->vddgfxvrmapping;
param->vddsocvrmapping = info->vddsocvrmapping;
param->vddmem0vrmapping = info->vddmem0vrmapping;
param->vddmem1vrmapping = info->vddmem1vrmapping;
param->gfxulvphasesheddingmask = info->gfxulvphasesheddingmask;
param->soculvphasesheddingmask = info->soculvphasesheddingmask;
param->gfxmaxcurrent = info->gfxmaxcurrent;
param->gfxoffset = info->gfxoffset;
param->padding_telemetrygfx = info->padding_telemetrygfx;
param->socmaxcurrent = info->socmaxcurrent;
param->socoffset = info->socoffset;
param->padding_telemetrysoc = info->padding_telemetrysoc;
param->mem0maxcurrent = info->mem0maxcurrent;
param->mem0offset = info->mem0offset;
param->padding_telemetrymem0 = info->padding_telemetrymem0;
param->mem1maxcurrent = info->mem1maxcurrent;
param->mem1offset = info->mem1offset;
param->padding_telemetrymem1 = info->padding_telemetrymem1;
param->acdcgpio = info->acdcgpio;
param->acdcpolarity = info->acdcpolarity;
param->vr0hotgpio = info->vr0hotgpio;
param->vr0hotpolarity = info->vr0hotpolarity;
param->vr1hotgpio = info->vr1hotgpio;
param->vr1hotpolarity = info->vr1hotpolarity;
param->padding1 = info->padding1;
param->padding2 = info->padding2;
param->ledpin0 = info->ledpin0;
param->ledpin1 = info->ledpin1;
param->ledpin2 = info->ledpin2;
param->gfxclkspreadenabled = info->gfxclkspreadenabled;
param->gfxclkspreadpercent = info->gfxclkspreadpercent;
param->gfxclkspreadfreq = info->gfxclkspreadfreq;
param->uclkspreadenabled = info->uclkspreadenabled;
param->uclkspreadpercent = info->uclkspreadpercent;
param->uclkspreadfreq = info->uclkspreadfreq;
param->socclkspreadenabled = info->socclkspreadenabled;
param->socclkspreadpercent = info->socclkspreadpercent;
param->socclkspreadfreq = info->socclkspreadfreq;
return 0;
}

View File

@ -140,6 +140,69 @@ struct pp_atomfwctrl_bios_boot_up_values {
uint16_t usVddci;
uint16_t usMvddc;
uint16_t usVddGfx;
uint8_t ucCoolingID;
};
struct pp_atomfwctrl_smc_dpm_parameters
{
uint8_t liquid1_i2c_address;
uint8_t liquid2_i2c_address;
uint8_t vr_i2c_address;
uint8_t plx_i2c_address;
uint8_t liquid_i2c_linescl;
uint8_t liquid_i2c_linesda;
uint8_t vr_i2c_linescl;
uint8_t vr_i2c_linesda;
uint8_t plx_i2c_linescl;
uint8_t plx_i2c_linesda;
uint8_t vrsensorpresent;
uint8_t liquidsensorpresent;
uint16_t maxvoltagestepgfx;
uint16_t maxvoltagestepsoc;
uint8_t vddgfxvrmapping;
uint8_t vddsocvrmapping;
uint8_t vddmem0vrmapping;
uint8_t vddmem1vrmapping;
uint8_t gfxulvphasesheddingmask;
uint8_t soculvphasesheddingmask;
uint16_t gfxmaxcurrent;
uint8_t gfxoffset;
uint8_t padding_telemetrygfx;
uint16_t socmaxcurrent;
uint8_t socoffset;
uint8_t padding_telemetrysoc;
uint16_t mem0maxcurrent;
uint8_t mem0offset;
uint8_t padding_telemetrymem0;
uint16_t mem1maxcurrent;
uint8_t mem1offset;
uint8_t padding_telemetrymem1;
uint8_t acdcgpio;
uint8_t acdcpolarity;
uint8_t vr0hotgpio;
uint8_t vr0hotpolarity;
uint8_t vr1hotgpio;
uint8_t vr1hotpolarity;
uint8_t padding1;
uint8_t padding2;
uint8_t ledpin0;
uint8_t ledpin1;
uint8_t ledpin2;
uint8_t gfxclkspreadenabled;
uint8_t gfxclkspreadpercent;
uint16_t gfxclkspreadfreq;
uint8_t uclkspreadenabled;
uint8_t uclkspreadpercent;
uint16_t uclkspreadfreq;
uint8_t socclkspreadenabled;
uint8_t socclkspreadpercent;
uint16_t socclkspreadfreq;
};
int pp_atomfwctrl_get_gpu_pll_dividers_vega10(struct pp_hwmgr *hwmgr,
@ -161,6 +224,8 @@ int pp_atomfwctrl_get_gpio_information(struct pp_hwmgr *hwmgr,
int pp_atomfwctrl_get_vbios_bootup_values(struct pp_hwmgr *hwmgr,
struct pp_atomfwctrl_bios_boot_up_values *boot_values);
int pp_atomfwctrl_get_smc_dpm_information(struct pp_hwmgr *hwmgr,
struct pp_atomfwctrl_smc_dpm_parameters *param);
#endif

View File

@ -833,6 +833,7 @@ static int smu7_odn_initial_default_setting(struct pp_hwmgr *hwmgr)
struct phm_ppt_v1_clock_voltage_dependency_table *dep_sclk_table;
struct phm_ppt_v1_clock_voltage_dependency_table *dep_mclk_table;
struct phm_odn_performance_level *entries;
if (table_info == NULL)
return -EINVAL;
@ -842,11 +843,11 @@ static int smu7_odn_initial_default_setting(struct pp_hwmgr *hwmgr)
odn_table->odn_core_clock_dpm_levels.num_of_pl =
data->golden_dpm_table.sclk_table.count;
entries = odn_table->odn_core_clock_dpm_levels.entries;
for (i=0; i<data->golden_dpm_table.sclk_table.count; i++) {
odn_table->odn_core_clock_dpm_levels.entries[i].clock =
data->golden_dpm_table.sclk_table.dpm_levels[i].value;
odn_table->odn_core_clock_dpm_levels.entries[i].enabled = true;
odn_table->odn_core_clock_dpm_levels.entries[i].vddc = dep_sclk_table->entries[i].vddc;
entries[i].clock = data->golden_dpm_table.sclk_table.dpm_levels[i].value;
entries[i].enabled = true;
entries[i].vddc = dep_sclk_table->entries[i].vddc;
}
smu7_get_voltage_dependency_table(dep_sclk_table,
@ -854,11 +855,11 @@ static int smu7_odn_initial_default_setting(struct pp_hwmgr *hwmgr)
odn_table->odn_memory_clock_dpm_levels.num_of_pl =
data->golden_dpm_table.mclk_table.count;
for (i=0; i<data->golden_dpm_table.sclk_table.count; i++) {
odn_table->odn_memory_clock_dpm_levels.entries[i].clock =
data->golden_dpm_table.mclk_table.dpm_levels[i].value;
odn_table->odn_memory_clock_dpm_levels.entries[i].enabled = true;
odn_table->odn_memory_clock_dpm_levels.entries[i].vddc = dep_mclk_table->entries[i].vddc;
entries = odn_table->odn_memory_clock_dpm_levels.entries;
for (i=0; i<data->golden_dpm_table.mclk_table.count; i++) {
entries[i].clock = data->golden_dpm_table.mclk_table.dpm_levels[i].value;
entries[i].enabled = true;
entries[i].vddc = dep_mclk_table->entries[i].vddc;
}
smu7_get_voltage_dependency_table(dep_mclk_table,
@ -891,30 +892,6 @@ static int smu7_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
return 0;
}
uint32_t smu7_get_xclk(struct pp_hwmgr *hwmgr)
{
uint32_t reference_clock, tmp;
struct cgs_display_info info = {0};
struct cgs_mode_info mode_info = {0};
info.mode_info = &mode_info;
tmp = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_CLKPIN_CNTL_2, MUX_TCLK_TO_XCLK);
if (tmp)
return TCLK;
cgs_get_active_displays_info(hwmgr->device, &info);
reference_clock = mode_info.ref_clock;
tmp = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, CG_CLKPIN_CNTL, XTALIN_DIVIDE);
if (0 != tmp)
return reference_clock / 4;
return reference_clock;
}
static int smu7_enable_vrhot_gpio_interrupt(struct pp_hwmgr *hwmgr)
{
@ -3970,7 +3947,8 @@ static int smu7_program_display_gap(struct pp_hwmgr *hwmgr)
display_gap = PHM_SET_FIELD(display_gap, CG_DISPLAY_GAP_CNTL, DISP_GAP, (num_active_displays > 0) ? DISPLAY_GAP_VBLANK_OR_WM : DISPLAY_GAP_IGNORE);
cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_DISPLAY_GAP_CNTL, display_gap);
ref_clock = mode_info.ref_clock;
ref_clock = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev);
refresh_rate = mode_info.refresh_rate;
if (0 == refresh_rate)
@ -4021,9 +3999,35 @@ static int smu7_set_max_fan_rpm_output(struct pp_hwmgr *hwmgr, uint16_t us_max_f
PPSMC_MSG_SetFanRpmMax, us_max_fan_rpm);
}
static int smu7_register_internal_thermal_interrupt(struct pp_hwmgr *hwmgr,
const void *thermal_interrupt_info)
static const struct amdgpu_irq_src_funcs smu7_irq_funcs = {
.process = phm_irq_process,
};
static int smu7_register_irq_handlers(struct pp_hwmgr *hwmgr)
{
struct amdgpu_irq_src *source =
kzalloc(sizeof(struct amdgpu_irq_src), GFP_KERNEL);
if (!source)
return -ENOMEM;
source->funcs = &smu7_irq_funcs;
amdgpu_irq_add_id((struct amdgpu_device *)(hwmgr->adev),
AMDGPU_IH_CLIENTID_LEGACY,
230,
source);
amdgpu_irq_add_id((struct amdgpu_device *)(hwmgr->adev),
AMDGPU_IH_CLIENTID_LEGACY,
231,
source);
/* Register CTF(GPIO_19) interrupt */
amdgpu_irq_add_id((struct amdgpu_device *)(hwmgr->adev),
AMDGPU_IH_CLIENTID_LEGACY,
83,
source);
return 0;
}
@ -4725,7 +4729,7 @@ static void smu7_check_dpm_table_updated(struct pp_hwmgr *hwmgr)
}
}
for (i=0; i<data->dpm_table.sclk_table.count; i++) {
for (i=0; i<data->dpm_table.mclk_table.count; i++) {
if (odn_table->odn_memory_clock_dpm_levels.entries[i].clock !=
data->dpm_table.mclk_table.dpm_levels[i].value) {
data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_MCLK;
@ -5007,7 +5011,7 @@ static const struct pp_hwmgr_func smu7_hwmgr_funcs = {
.get_fan_speed_rpm = smu7_fan_ctrl_get_fan_speed_rpm,
.set_fan_speed_rpm = smu7_fan_ctrl_set_fan_speed_rpm,
.uninitialize_thermal_controller = smu7_thermal_ctrl_uninitialize_thermal_controller,
.register_internal_thermal_interrupt = smu7_register_internal_thermal_interrupt,
.register_irq_handlers = smu7_register_irq_handlers,
.check_smc_update_required_for_display_configuration = smu7_check_smc_update_required_for_display_configuration,
.check_states_equal = smu7_check_states_equal,
.set_fan_control_mode = smu7_set_fan_control_mode,

View File

@ -361,7 +361,6 @@ enum SMU7_I2CLineID {
#define SMU7_I2C_DDCVGACLK 0x4d
#define SMU7_UNUSED_GPIO_PIN 0x7F
uint32_t smu7_get_xclk(struct pp_hwmgr *hwmgr);
uint8_t smu7_get_sleep_divider_id_from_clock(uint32_t clock,
uint32_t clock_insr);
#endif

View File

@ -95,7 +95,7 @@ int smu7_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed)
if (tach_period == 0)
return -EINVAL;
crystal_clock_freq = smu7_get_xclk(hwmgr);
crystal_clock_freq = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev);
*speed = 60 * crystal_clock_freq * 10000 / tach_period;
@ -267,7 +267,7 @@ int smu7_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t speed)
if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl))
smu7_fan_ctrl_stop_smc_fan_control(hwmgr);
crystal_clock_freq = smu7_get_xclk(hwmgr);
crystal_clock_freq = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev);
tach_period = 60 * crystal_clock_freq * 10000 / (8 * speed);
@ -308,7 +308,7 @@ int smu7_thermal_get_temperature(struct pp_hwmgr *hwmgr)
* @exception PP_Result_BadInput if the input data is not valid.
*/
static int smu7_thermal_set_temperature_range(struct pp_hwmgr *hwmgr,
uint32_t low_temp, uint32_t high_temp)
int low_temp, int high_temp)
{
int low = SMU7_THERMAL_MINIMUM_ALERT_TEMP *
PP_TEMPERATURE_UNITS_PER_CENTIGRADES;

View File

@ -534,3 +534,77 @@ int phm_get_voltage_evv_on_sclk(struct pp_hwmgr *hwmgr, uint8_t voltage_type,
}
int phm_irq_process(struct amdgpu_device *adev,
struct amdgpu_irq_src *source,
struct amdgpu_iv_entry *entry)
{
uint32_t client_id = entry->client_id;
uint32_t src_id = entry->src_id;
if (client_id == AMDGPU_IH_CLIENTID_LEGACY) {
if (src_id == 230)
pr_warn("GPU over temperature range detected on PCIe %d:%d.%d!\n",
PCI_BUS_NUM(adev->pdev->devfn),
PCI_SLOT(adev->pdev->devfn),
PCI_FUNC(adev->pdev->devfn));
else if (src_id == 231)
pr_warn("GPU under temperature range detected on PCIe %d:%d.%d!\n",
PCI_BUS_NUM(adev->pdev->devfn),
PCI_SLOT(adev->pdev->devfn),
PCI_FUNC(adev->pdev->devfn));
else if (src_id == 83)
pr_warn("GPU Critical Temperature Fault detected on PCIe %d:%d.%d!\n",
PCI_BUS_NUM(adev->pdev->devfn),
PCI_SLOT(adev->pdev->devfn),
PCI_FUNC(adev->pdev->devfn));
} else if (client_id == SOC15_IH_CLIENTID_THM) {
if (src_id == 0)
pr_warn("GPU over temperature range detected on PCIe %d:%d.%d!\n",
PCI_BUS_NUM(adev->pdev->devfn),
PCI_SLOT(adev->pdev->devfn),
PCI_FUNC(adev->pdev->devfn));
else
pr_warn("GPU under temperature range detected on PCIe %d:%d.%d!\n",
PCI_BUS_NUM(adev->pdev->devfn),
PCI_SLOT(adev->pdev->devfn),
PCI_FUNC(adev->pdev->devfn));
} else if (client_id == SOC15_IH_CLIENTID_ROM_SMUIO)
pr_warn("GPU Critical Temperature Fault detected on PCIe %d:%d.%d!\n",
PCI_BUS_NUM(adev->pdev->devfn),
PCI_SLOT(adev->pdev->devfn),
PCI_FUNC(adev->pdev->devfn));
return 0;
}
static const struct amdgpu_irq_src_funcs smu9_irq_funcs = {
.process = phm_irq_process,
};
int smu9_register_irq_handlers(struct pp_hwmgr *hwmgr)
{
struct amdgpu_irq_src *source =
kzalloc(sizeof(struct amdgpu_irq_src), GFP_KERNEL);
if (!source)
return -ENOMEM;
source->funcs = &smu9_irq_funcs;
amdgpu_irq_add_id((struct amdgpu_device *)(hwmgr->adev),
SOC15_IH_CLIENTID_THM,
0,
source);
amdgpu_irq_add_id((struct amdgpu_device *)(hwmgr->adev),
SOC15_IH_CLIENTID_THM,
1,
source);
/* Register CTF(GPIO_19) interrupt */
amdgpu_irq_add_id((struct amdgpu_device *)(hwmgr->adev),
SOC15_IH_CLIENTID_ROM_SMUIO,
83,
source);
return 0;
}

View File

@ -27,6 +27,9 @@ struct pp_atomctrl_voltage_table;
struct pp_hwmgr;
struct phm_ppt_v1_voltage_lookup_table;
uint8_t convert_to_vid(uint16_t vddc);
uint16_t convert_to_vddc(uint8_t vid);
extern int phm_wait_for_register_unequal(struct pp_hwmgr *hwmgr,
uint32_t index,
uint32_t value, uint32_t mask);
@ -73,6 +76,12 @@ extern int phm_wait_on_indirect_register(struct pp_hwmgr *hwmgr,
uint32_t value,
uint32_t mask);
int phm_irq_process(struct amdgpu_device *adev,
struct amdgpu_irq_src *source,
struct amdgpu_iv_entry *entry);
int smu9_register_irq_handlers(struct pp_hwmgr *hwmgr);
#define PHM_FIELD_SHIFT(reg, field) reg##__##field##__SHIFT
#define PHM_FIELD_MASK(reg, field) reg##__##field##_MASK

View File

@ -28,7 +28,6 @@
#include "hwmgr.h"
#include "amd_powerplay.h"
#include "vega10_smumgr.h"
#include "hardwaremanager.h"
#include "ppatomfwctrl.h"
#include "atomfirmware.h"
@ -45,7 +44,6 @@
#include "vega10_thermal.h"
#include "pp_debug.h"
#include "amd_pcie_helpers.h"
#include "cgs_linux.h"
#include "ppinterrupt.h"
#include "pp_overdriver.h"
#include "pp_thermal.h"
@ -108,8 +106,7 @@ const struct vega10_power_state *cast_const_phw_vega10_power_state(
static void vega10_set_default_registry_data(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
data->registry_data.sclk_dpm_key_disabled =
hwmgr->feature_mask & PP_SCLK_DPM_MASK ? false : true;
@ -186,8 +183,7 @@ static void vega10_set_default_registry_data(struct pp_hwmgr *hwmgr)
static int vega10_set_features_platform_caps(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
struct phm_ppt_v2_information *table_info =
(struct phm_ppt_v2_information *)hwmgr->pptable;
struct amdgpu_device *adev = hwmgr->adev;
@ -297,7 +293,7 @@ static int vega10_set_features_platform_caps(struct pp_hwmgr *hwmgr)
static void vega10_init_dpm_defaults(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
int i;
uint32_t sub_vendor_id, hw_revision;
struct amdgpu_device *adev = hwmgr->adev;
@ -427,7 +423,7 @@ static void vega10_init_dpm_defaults(struct pp_hwmgr *hwmgr)
data->smu_features[GNLD_VR0HOT].supported = true;
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetSmuVersion);
vega10_read_arg_from_smc(hwmgr, &(hwmgr->smu_version));
hwmgr->smu_version = smum_get_argument(hwmgr);
/* ACG firmware has major version 5 */
if ((hwmgr->smu_version & 0xff000000) == 0x5000000)
data->smu_features[GNLD_ACG].supported = true;
@ -485,7 +481,7 @@ static int vega10_get_socclk_for_voltage_evv(struct pp_hwmgr *hwmgr,
*/
static int vega10_get_evv_voltages(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
uint16_t vv_id;
uint32_t vddc = 0;
uint16_t i, j;
@ -676,7 +672,7 @@ static int vega10_complete_dependency_tables(struct pp_hwmgr *hwmgr)
struct phm_ppt_v2_information *table_info =
(struct phm_ppt_v2_information *)(hwmgr->pptable);
#ifdef PPLIB_VEGA10_EVV_SUPPORT
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
tmp_result = vega10_patch_lookup_table_with_leakage(hwmgr,
table_info->vddc_lookup_table, &(data->vddc_leakage));
@ -879,8 +875,7 @@ static int vega10_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
static int vega10_init_sclk_threshold(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
data->low_sclk_interrupt_threshold = 0;
@ -889,8 +884,7 @@ static int vega10_init_sclk_threshold(struct pp_hwmgr *hwmgr)
static int vega10_setup_dpm_led_config(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
PPTable_t *pp_table = &(data->smc_state_table.pp_table);
struct pp_atomfwctrl_voltage_table table;
@ -1093,7 +1087,7 @@ static void vega10_trim_voltage_table_to_fit_state_table(
*/
static int vega10_construct_voltage_tables(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
struct phm_ppt_v2_information *table_info =
(struct phm_ppt_v2_information *)hwmgr->pptable;
int result;
@ -1181,8 +1175,7 @@ static void vega10_setup_default_single_dpm_table(struct pp_hwmgr *hwmgr,
}
static int vega10_setup_default_pcie_table(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
struct vega10_pcie_table *pcie_table = &(data->dpm_table.pcie_table);
struct phm_ppt_v2_information *table_info =
(struct phm_ppt_v2_information *)(hwmgr->pptable);
@ -1231,8 +1224,7 @@ static int vega10_setup_default_pcie_table(struct pp_hwmgr *hwmgr)
*/
static int vega10_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
struct phm_ppt_v2_information *table_info =
(struct phm_ppt_v2_information *)(hwmgr->pptable);
struct vega10_single_dpm_table *dpm_table;
@ -1432,8 +1424,7 @@ static int vega10_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
*/
static int vega10_populate_ulv_state(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
struct phm_ppt_v2_information *table_info =
(struct phm_ppt_v2_information *)(hwmgr->pptable);
@ -1474,8 +1465,7 @@ static int vega10_populate_single_lclk_level(struct pp_hwmgr *hwmgr,
static int vega10_populate_smc_link_levels(struct pp_hwmgr *hwmgr)
{
int result = -1;
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
PPTable_t *pp_table = &(data->smc_state_table.pp_table);
struct vega10_pcie_table *pcie_table =
&(data->dpm_table.pcie_table);
@ -1526,8 +1516,7 @@ static int vega10_populate_single_gfx_level(struct pp_hwmgr *hwmgr,
(struct phm_ppt_v2_information *)(hwmgr->pptable);
struct phm_ppt_v1_clock_voltage_dependency_table *dep_on_sclk =
table_info->vdd_dep_on_sclk;
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
struct pp_atomfwctrl_clock_dividers_soc15 dividers;
uint32_t gfx_max_clock =
hwmgr->platform_descriptor.overdriveLimit.engineClock;
@ -1639,8 +1628,7 @@ uint16_t vega10_locate_vddc_given_clock(struct pp_hwmgr *hwmgr,
*/
static int vega10_populate_all_graphic_levels(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
struct phm_ppt_v2_information *table_info =
(struct phm_ppt_v2_information *)(hwmgr->pptable);
struct phm_ppt_v1_clock_voltage_dependency_table *dep_table =
@ -1714,8 +1702,7 @@ static int vega10_populate_single_memory_level(struct pp_hwmgr *hwmgr,
uint32_t mem_clock, uint8_t *current_mem_vid,
PllSetting_t *current_memclk_level, uint8_t *current_mem_soc_vind)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
struct phm_ppt_v2_information *table_info =
(struct phm_ppt_v2_information *)(hwmgr->pptable);
struct phm_ppt_v1_clock_voltage_dependency_table *dep_on_mclk =
@ -1773,8 +1760,7 @@ static int vega10_populate_single_memory_level(struct pp_hwmgr *hwmgr,
*/
static int vega10_populate_all_memory_levels(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
PPTable_t *pp_table = &(data->smc_state_table.pp_table);
struct vega10_single_dpm_table *dpm_table =
&(data->dpm_table.mem_table);
@ -1817,8 +1803,7 @@ static int vega10_populate_all_memory_levels(struct pp_hwmgr *hwmgr)
static int vega10_populate_single_display_type(struct pp_hwmgr *hwmgr,
DSPCLK_e disp_clock)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
PPTable_t *pp_table = &(data->smc_state_table.pp_table);
struct phm_ppt_v2_information *table_info =
(struct phm_ppt_v2_information *)
@ -1913,8 +1898,7 @@ static int vega10_populate_single_eclock_level(struct pp_hwmgr *hwmgr,
static int vega10_populate_smc_vce_levels(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
PPTable_t *pp_table = &(data->smc_state_table.pp_table);
struct vega10_single_dpm_table *dpm_table = &(data->dpm_table.eclk_table);
int result = -EINVAL;
@ -1977,8 +1961,7 @@ static int vega10_populate_single_dclock_level(struct pp_hwmgr *hwmgr,
static int vega10_populate_smc_uvd_levels(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
PPTable_t *pp_table = &(data->smc_state_table.pp_table);
struct vega10_single_dpm_table *vclk_dpm_table =
&(data->dpm_table.vclk_table);
@ -2049,8 +2032,7 @@ static int vega10_populate_smc_uvd_levels(struct pp_hwmgr *hwmgr)
static int vega10_populate_clock_stretcher_table(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
PPTable_t *pp_table = &(data->smc_state_table.pp_table);
struct phm_ppt_v2_information *table_info =
(struct phm_ppt_v2_information *)(hwmgr->pptable);
@ -2069,8 +2051,7 @@ static int vega10_populate_clock_stretcher_table(struct pp_hwmgr *hwmgr)
static int vega10_populate_avfs_parameters(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
PPTable_t *pp_table = &(data->smc_state_table.pp_table);
struct phm_ppt_v2_information *table_info =
(struct phm_ppt_v2_information *)(hwmgr->pptable);
@ -2261,8 +2242,7 @@ static int vega10_populate_avfs_parameters(struct pp_hwmgr *hwmgr)
static int vega10_acg_enable(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
uint32_t agc_btc_response;
if (data->smu_features[GNLD_ACG].supported) {
@ -2273,7 +2253,7 @@ static int vega10_acg_enable(struct pp_hwmgr *hwmgr)
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_InitializeAcg);
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_RunAcgBtc);
vega10_read_arg_from_smc(hwmgr, &agc_btc_response);
agc_btc_response = smum_get_argument(hwmgr);
if (1 == agc_btc_response) {
if (1 == data->acg_loop_state)
@ -2294,8 +2274,7 @@ static int vega10_acg_enable(struct pp_hwmgr *hwmgr)
static int vega10_acg_disable(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
if (data->smu_features[GNLD_ACG].supported &&
data->smu_features[GNLD_ACG].enabled)
@ -2308,8 +2287,7 @@ static int vega10_acg_disable(struct pp_hwmgr *hwmgr)
static int vega10_populate_gpio_parameters(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
PPTable_t *pp_table = &(data->smc_state_table.pp_table);
struct pp_atomfwctrl_gpio_parameters gpio_params = {0};
int result;
@ -2344,8 +2322,7 @@ static int vega10_populate_gpio_parameters(struct pp_hwmgr *hwmgr)
static int vega10_avfs_enable(struct pp_hwmgr *hwmgr, bool enable)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
if (data->smu_features[GNLD_AVFS].supported) {
if (enable) {
@ -2376,14 +2353,14 @@ static int vega10_populate_and_upload_avfs_fuse_override(struct pp_hwmgr *hwmgr)
uint32_t top32, bottom32;
struct phm_fuses_default fuse;
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
AvfsFuseOverride_t *avfs_fuse_table = &(data->smc_state_table.avfs_fuse_override_table);
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32);
vega10_read_arg_from_smc(hwmgr, &top32);
top32 = smum_get_argument(hwmgr);
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32);
vega10_read_arg_from_smc(hwmgr, &bottom32);
bottom32 = smum_get_argument(hwmgr);
serial_number = ((uint64_t)bottom32 << 32) | top32;
@ -2397,8 +2374,8 @@ static int vega10_populate_and_upload_avfs_fuse_override(struct pp_hwmgr *hwmgr)
avfs_fuse_table->VFT2_b = fuse.VFT2_b;
avfs_fuse_table->VFT2_m1 = fuse.VFT2_m1;
avfs_fuse_table->VFT2_m2 = fuse.VFT2_m2;
result = vega10_copy_table_to_smc(hwmgr,
(uint8_t *)avfs_fuse_table, AVFSFUSETABLE);
result = smum_smc_table_manager(hwmgr, (uint8_t *)avfs_fuse_table,
AVFSFUSETABLE, false);
PP_ASSERT_WITH_CODE(!result,
"Failed to upload FuseOVerride!",
);
@ -2417,8 +2394,7 @@ static int vega10_populate_and_upload_avfs_fuse_override(struct pp_hwmgr *hwmgr)
static int vega10_init_smc_table(struct pp_hwmgr *hwmgr)
{
int result;
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
struct phm_ppt_v2_information *table_info =
(struct phm_ppt_v2_information *)(hwmgr->pptable);
PPTable_t *pp_table = &(data->smc_state_table.pp_table);
@ -2541,8 +2517,8 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr)
vega10_populate_and_upload_avfs_fuse_override(hwmgr);
result = vega10_copy_table_to_smc(hwmgr,
(uint8_t *)pp_table, PPTABLE);
result = smum_smc_table_manager(hwmgr, (uint8_t *)pp_table, PPTABLE, false);
PP_ASSERT_WITH_CODE(!result,
"Failed to upload PPtable!", return result);
@ -2556,7 +2532,7 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr)
static int vega10_enable_thermal_protection(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
if (data->smu_features[GNLD_THERMAL].supported) {
if (data->smu_features[GNLD_THERMAL].enabled)
@ -2576,7 +2552,7 @@ static int vega10_enable_thermal_protection(struct pp_hwmgr *hwmgr)
static int vega10_disable_thermal_protection(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
if (data->smu_features[GNLD_THERMAL].supported) {
if (!data->smu_features[GNLD_THERMAL].enabled)
@ -2596,8 +2572,7 @@ static int vega10_disable_thermal_protection(struct pp_hwmgr *hwmgr)
static int vega10_enable_vrhot_feature(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
if (PP_CAP(PHM_PlatformCaps_RegulatorHot)) {
if (data->smu_features[GNLD_VR0HOT].supported) {
@ -2625,8 +2600,7 @@ static int vega10_enable_vrhot_feature(struct pp_hwmgr *hwmgr)
static int vega10_enable_ulv(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
if (data->registry_data.ulv_support) {
PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
@ -2641,8 +2615,7 @@ static int vega10_enable_ulv(struct pp_hwmgr *hwmgr)
static int vega10_disable_ulv(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
if (data->registry_data.ulv_support) {
PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
@ -2657,8 +2630,7 @@ static int vega10_disable_ulv(struct pp_hwmgr *hwmgr)
static int vega10_enable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
if (data->smu_features[GNLD_DS_GFXCLK].supported) {
PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
@ -2697,8 +2669,7 @@ static int vega10_enable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr)
static int vega10_disable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
if (data->smu_features[GNLD_DS_GFXCLK].supported) {
PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
@ -2737,8 +2708,7 @@ static int vega10_disable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr)
static int vega10_stop_dpm(struct pp_hwmgr *hwmgr, uint32_t bitmap)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
uint32_t i, feature_mask = 0;
@ -2775,8 +2745,7 @@ static int vega10_stop_dpm(struct pp_hwmgr *hwmgr, uint32_t bitmap)
*/
static int vega10_start_dpm(struct pp_hwmgr *hwmgr, uint32_t bitmap)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
uint32_t i, feature_mask = 0;
for (i = 0; i < GNLD_DPM_MAX; i++) {
@ -2828,8 +2797,7 @@ static int vega10_start_dpm(struct pp_hwmgr *hwmgr, uint32_t bitmap)
static int vega10_enable_disable_PCC_limit_feature(struct pp_hwmgr *hwmgr, bool enable)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
if (data->smu_features[GNLD_PCC_LIMIT].supported) {
if (enable == data->smu_features[GNLD_PCC_LIMIT].enabled)
@ -2846,8 +2814,7 @@ static int vega10_enable_disable_PCC_limit_feature(struct pp_hwmgr *hwmgr, bool
static int vega10_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
int tmp_result, result = 0;
vega10_enable_disable_PCC_limit_feature(hwmgr, true);
@ -3064,7 +3031,7 @@ static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
struct cgs_display_info info = {0};
const struct phm_clock_and_voltage_limits *max_limits;
uint32_t i;
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
struct phm_ppt_v2_information *table_info =
(struct phm_ppt_v2_information *)(hwmgr->pptable);
int32_t count;
@ -3208,8 +3175,7 @@ static int vega10_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, co
(const struct phm_set_power_state_input *)input;
const struct vega10_power_state *vega10_ps =
cast_const_phw_vega10_power_state(states->pnew_state);
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
struct vega10_single_dpm_table *sclk_table =
&(data->dpm_table.gfx_table);
uint32_t sclk = vega10_ps->performance_levels
@ -3297,8 +3263,7 @@ static int vega10_populate_and_upload_sclk_mclk_dpm_levels(
(const struct phm_set_power_state_input *)input;
const struct vega10_power_state *vega10_ps =
cast_const_phw_vega10_power_state(states->pnew_state);
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
uint32_t sclk = vega10_ps->performance_levels
[vega10_ps->performance_level_count - 1].gfx_clock;
uint32_t mclk = vega10_ps->performance_levels
@ -3523,8 +3488,7 @@ static int vega10_trim_single_dpm_states_with_mask(struct pp_hwmgr *hwmgr,
static int vega10_trim_dpm_states(struct pp_hwmgr *hwmgr,
const struct vega10_power_state *vega10_ps)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
uint32_t high_limit_count;
PP_ASSERT_WITH_CODE((vega10_ps->performance_level_count >= 1),
@ -3602,8 +3566,7 @@ static int vega10_get_soc_index_for_max_uclk(struct pp_hwmgr *hwmgr)
static int vega10_upload_dpm_bootup_level(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
uint32_t socclk_idx;
vega10_apply_dal_minimum_voltage_request(hwmgr);
@ -3642,8 +3605,7 @@ static int vega10_upload_dpm_bootup_level(struct pp_hwmgr *hwmgr)
static int vega10_upload_dpm_max_level(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
vega10_apply_dal_minimum_voltage_request(hwmgr);
@ -3675,8 +3637,7 @@ static int vega10_upload_dpm_max_level(struct pp_hwmgr *hwmgr)
static int vega10_generate_dpm_level_enable_mask(
struct pp_hwmgr *hwmgr, const void *input)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
const struct phm_set_power_state_input *states =
(const struct phm_set_power_state_input *)input;
const struct vega10_power_state *vega10_ps =
@ -3714,8 +3675,7 @@ static int vega10_generate_dpm_level_enable_mask(
int vega10_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
if (data->smu_features[GNLD_DPM_VCE].supported) {
PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
@ -3731,8 +3691,7 @@ int vega10_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable)
static int vega10_update_sclk_threshold(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
uint32_t low_sclk_interrupt_threshold = 0;
if (PP_CAP(PHM_PlatformCaps_SclkThrottleLowNotification) &&
@ -3756,8 +3715,7 @@ static int vega10_set_power_state_tasks(struct pp_hwmgr *hwmgr,
const void *input)
{
int tmp_result, result = 0;
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
PPTable_t *pp_table = &(data->smc_state_table.pp_table);
tmp_result = vega10_find_dpm_states_clocks_in_dpm_table(hwmgr, input);
@ -3780,8 +3738,7 @@ static int vega10_set_power_state_tasks(struct pp_hwmgr *hwmgr,
"Failed to update SCLK threshold!",
result = tmp_result);
result = vega10_copy_table_to_smc(hwmgr,
(uint8_t *)pp_table, PPTABLE);
result = smum_smc_table_manager(hwmgr, (uint8_t *)pp_table, PPTABLE, false);
PP_ASSERT_WITH_CODE(!result,
"Failed to upload PPtable!", return result);
@ -3841,7 +3798,7 @@ static int vega10_get_gpu_power(struct pp_hwmgr *hwmgr,
uint32_t value;
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrPkgPwr);
vega10_read_arg_from_smc(hwmgr, &value);
value = smum_get_argument(hwmgr);
/* power value is an integer */
memset(query, 0, sizeof *query);
@ -3854,7 +3811,7 @@ static int vega10_read_sensor(struct pp_hwmgr *hwmgr, int idx,
void *value, int *size)
{
uint32_t sclk_idx, mclk_idx, activity_percent = 0;
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
struct vega10_dpm_table *dpm_table = &data->dpm_table;
int ret = 0;
uint32_t reg, val_vid;
@ -3862,7 +3819,7 @@ static int vega10_read_sensor(struct pp_hwmgr *hwmgr, int idx,
switch (idx) {
case AMDGPU_PP_SENSOR_GFX_SCLK:
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentGfxclkIndex);
vega10_read_arg_from_smc(hwmgr, &sclk_idx);
sclk_idx = smum_get_argument(hwmgr);
if (sclk_idx < dpm_table->gfx_table.count) {
*((uint32_t *)value) = dpm_table->gfx_table.dpm_levels[sclk_idx].value;
*size = 4;
@ -3872,7 +3829,7 @@ static int vega10_read_sensor(struct pp_hwmgr *hwmgr, int idx,
break;
case AMDGPU_PP_SENSOR_GFX_MCLK:
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentUclkIndex);
vega10_read_arg_from_smc(hwmgr, &mclk_idx);
mclk_idx = smum_get_argument(hwmgr);
if (mclk_idx < dpm_table->mem_table.count) {
*((uint32_t *)value) = dpm_table->mem_table.dpm_levels[mclk_idx].value;
*size = 4;
@ -3882,7 +3839,7 @@ static int vega10_read_sensor(struct pp_hwmgr *hwmgr, int idx,
break;
case AMDGPU_PP_SENSOR_GPU_LOAD:
smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetAverageGfxActivity, 0);
vega10_read_arg_from_smc(hwmgr, &activity_percent);
activity_percent = smum_get_argument(hwmgr);
*((uint32_t *)value) = activity_percent > 100 ? 100 : activity_percent;
*size = 4;
break;
@ -3992,8 +3949,7 @@ static uint8_t vega10_get_uclk_index(struct pp_hwmgr *hwmgr,
static int vega10_notify_smc_display_config_after_ps_adjustment(
struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
struct vega10_single_dpm_table *dpm_table =
&data->dpm_table.dcef_table;
struct phm_ppt_v2_information *table_info =
@ -4051,8 +4007,7 @@ static int vega10_notify_smc_display_config_after_ps_adjustment(
static int vega10_force_dpm_highest(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
data->smc_state_table.gfx_boot_level =
data->smc_state_table.gfx_max_level =
@ -4074,8 +4029,7 @@ static int vega10_force_dpm_highest(struct pp_hwmgr *hwmgr)
static int vega10_force_dpm_lowest(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
data->smc_state_table.gfx_boot_level =
data->smc_state_table.gfx_max_level =
@ -4098,7 +4052,7 @@ static int vega10_force_dpm_lowest(struct pp_hwmgr *hwmgr)
static int vega10_unforce_dpm_levels(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
data->smc_state_table.gfx_boot_level =
vega10_find_lowest_dpm_level(&(data->dpm_table.gfx_table));
@ -4215,7 +4169,7 @@ static int vega10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr,
static uint32_t vega10_get_fan_control_mode(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
if (data->smu_features[GNLD_FAN_CONTROL].enabled == false)
return AMD_FAN_CTRL_MANUAL;
@ -4275,7 +4229,7 @@ static void vega10_get_memclocks(struct pp_hwmgr *hwmgr,
(struct phm_ppt_v2_information *)hwmgr->pptable;
struct phm_ppt_v1_clock_voltage_dependency_table *dep_table =
table_info->vdd_dep_on_mclk;
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
uint32_t i;
clocks->num_levels = 0;
@ -4399,7 +4353,7 @@ static int vega10_get_clock_by_type_with_voltage(struct pp_hwmgr *hwmgr,
static int vega10_set_watermarks_for_clocks_ranges(struct pp_hwmgr *hwmgr,
struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
Watermarks_t *table = &(data->smc_state_table.water_marks_table);
int result = 0;
uint32_t i;
@ -4455,7 +4409,7 @@ static int vega10_set_watermarks_for_clocks_ranges(struct pp_hwmgr *hwmgr,
static int vega10_force_clock_level(struct pp_hwmgr *hwmgr,
enum pp_clock_type type, uint32_t mask)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
switch (type) {
case PP_SCLK:
@ -4496,7 +4450,7 @@ static int vega10_force_clock_level(struct pp_hwmgr *hwmgr,
static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
enum pp_clock_type type, char *buf)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table);
struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table);
struct vega10_pcie_table *pcie_table = &(data->dpm_table.pcie_table);
@ -4508,7 +4462,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
break;
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentGfxclkIndex);
vega10_read_arg_from_smc(hwmgr, &now);
now = smum_get_argument(hwmgr);
for (i = 0; i < sclk_table->count; i++)
size += sprintf(buf + size, "%d: %uMhz %s\n",
@ -4520,7 +4474,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
break;
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentUclkIndex);
vega10_read_arg_from_smc(hwmgr, &now);
now = smum_get_argument(hwmgr);
for (i = 0; i < mclk_table->count; i++)
size += sprintf(buf + size, "%d: %uMhz %s\n",
@ -4529,7 +4483,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
break;
case PP_PCIE:
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentLinkIndex);
vega10_read_arg_from_smc(hwmgr, &now);
now = smum_get_argument(hwmgr);
for (i = 0; i < pcie_table->count; i++)
size += sprintf(buf + size, "%d: %s %s\n", i,
@ -4546,7 +4500,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
static int vega10_display_configuration_changed_task(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
int result = 0;
uint32_t num_turned_on_displays = 1;
Watermarks_t *wm_table = &(data->smc_state_table.water_marks_table);
@ -4554,8 +4508,7 @@ static int vega10_display_configuration_changed_task(struct pp_hwmgr *hwmgr)
if ((data->water_marks_bitmap & WaterMarksExist) &&
!(data->water_marks_bitmap & WaterMarksLoaded)) {
result = vega10_copy_table_to_smc(hwmgr,
(uint8_t *)wm_table, WMTABLE);
result = smum_smc_table_manager(hwmgr, (uint8_t *)wm_table, WMTABLE, false);
PP_ASSERT_WITH_CODE(result, "Failed to update WMTABLE!", return EINVAL);
data->water_marks_bitmap |= WaterMarksLoaded;
}
@ -4572,8 +4525,7 @@ static int vega10_display_configuration_changed_task(struct pp_hwmgr *hwmgr)
int vega10_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
if (data->smu_features[GNLD_DPM_UVD].supported) {
PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
@ -4588,7 +4540,7 @@ int vega10_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable)
static void vega10_power_gate_vce(struct pp_hwmgr *hwmgr, bool bgate)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
data->vce_power_gated = bgate;
vega10_enable_disable_vce_dpm(hwmgr, !bgate);
@ -4596,7 +4548,7 @@ static void vega10_power_gate_vce(struct pp_hwmgr *hwmgr, bool bgate)
static void vega10_power_gate_uvd(struct pp_hwmgr *hwmgr, bool bgate)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
data->uvd_power_gated = bgate;
vega10_enable_disable_uvd_dpm(hwmgr, !bgate);
@ -4649,7 +4601,7 @@ static int vega10_check_states_equal(struct pp_hwmgr *hwmgr,
static bool
vega10_check_smc_update_required_for_display_configuration(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
bool is_update_required = false;
struct cgs_display_info info = {0, 0, NULL};
@ -4707,7 +4659,7 @@ static int vega10_disable_dpm_tasks(struct pp_hwmgr *hwmgr)
static int vega10_power_off_asic(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
int result;
result = vega10_disable_dpm_tasks(hwmgr);
@ -4721,7 +4673,7 @@ static int vega10_power_off_asic(struct pp_hwmgr *hwmgr)
static int vega10_get_sclk_od(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table);
struct vega10_single_dpm_table *golden_sclk_table =
&(data->golden_dpm_table.gfx_table);
@ -4739,7 +4691,7 @@ static int vega10_get_sclk_od(struct pp_hwmgr *hwmgr)
static int vega10_set_sclk_od(struct pp_hwmgr *hwmgr, uint32_t value)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
struct vega10_single_dpm_table *golden_sclk_table =
&(data->golden_dpm_table.gfx_table);
struct pp_power_state *ps;
@ -4772,7 +4724,7 @@ static int vega10_set_sclk_od(struct pp_hwmgr *hwmgr, uint32_t value)
static int vega10_get_mclk_od(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table);
struct vega10_single_dpm_table *golden_mclk_table =
&(data->golden_dpm_table.mem_table);
@ -4791,7 +4743,7 @@ static int vega10_get_mclk_od(struct pp_hwmgr *hwmgr)
static int vega10_set_mclk_od(struct pp_hwmgr *hwmgr, uint32_t value)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
struct vega10_single_dpm_table *golden_mclk_table =
&(data->golden_dpm_table.mem_table);
struct pp_power_state *ps;
@ -4863,41 +4815,9 @@ static int vega10_get_thermal_temperature_range(struct pp_hwmgr *hwmgr,
return 0;
}
static int vega10_register_thermal_interrupt(struct pp_hwmgr *hwmgr,
const void *info)
{
struct cgs_irq_src_funcs *irq_src =
(struct cgs_irq_src_funcs *)info;
if (hwmgr->thermal_controller.ucType ==
ATOM_VEGA10_PP_THERMALCONTROLLER_VEGA10 ||
hwmgr->thermal_controller.ucType ==
ATOM_VEGA10_PP_THERMALCONTROLLER_EMC2103_WITH_INTERNAL) {
PP_ASSERT_WITH_CODE(!cgs_add_irq_source(hwmgr->device,
SOC15_IH_CLIENTID_THM,
0, 0, irq_src[0].set, irq_src[0].handler, hwmgr),
"Failed to register high thermal interrupt!",
return -EINVAL);
PP_ASSERT_WITH_CODE(!cgs_add_irq_source(hwmgr->device,
SOC15_IH_CLIENTID_THM,
1, 0, irq_src[1].set, irq_src[1].handler, hwmgr),
"Failed to register low thermal interrupt!",
return -EINVAL);
}
/* Register CTF(GPIO_19) interrupt */
PP_ASSERT_WITH_CODE(!cgs_add_irq_source(hwmgr->device,
SOC15_IH_CLIENTID_ROM_SMUIO,
83, 0, irq_src[2].set, irq_src[2].handler, hwmgr),
"Failed to register CTF thermal interrupt!",
return -EINVAL);
return 0;
}
static int vega10_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
uint32_t i, size = 0;
static const uint8_t profile_mode_setting[5][4] = {{70, 60, 1, 3,},
{90, 60, 0, 0,},
@ -4938,7 +4858,7 @@ static int vega10_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf)
static int vega10_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, uint32_t size)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
uint8_t busy_set_point;
uint8_t FPS;
uint8_t use_rlc_busy;
@ -5019,13 +4939,23 @@ static const struct pp_hwmgr_func vega10_hwmgr_funcs = {
.avfs_control = vega10_avfs_enable,
.notify_cac_buffer_info = vega10_notify_cac_buffer_info,
.get_thermal_temperature_range = vega10_get_thermal_temperature_range,
.register_internal_thermal_interrupt = vega10_register_thermal_interrupt,
.register_irq_handlers = smu9_register_irq_handlers,
.start_thermal_controller = vega10_start_thermal_controller,
.get_power_profile_mode = vega10_get_power_profile_mode,
.set_power_profile_mode = vega10_set_power_profile_mode,
.set_power_limit = vega10_set_power_limit,
};
int vega10_enable_smc_features(struct pp_hwmgr *hwmgr,
bool enable, uint32_t feature_mask)
{
int msg = enable ? PPSMC_MSG_EnableSmuFeatures :
PPSMC_MSG_DisableSmuFeatures;
return smum_send_msg_to_smc_with_parameter(hwmgr,
msg, feature_mask);
}
int vega10_hwmgr_init(struct pp_hwmgr *hwmgr)
{
hwmgr->hwmgr_func = &vega10_hwmgr_funcs;

View File

@ -440,5 +440,7 @@ int vega10_update_uvd_dpm(struct pp_hwmgr *hwmgr, bool bgate);
int vega10_update_samu_dpm(struct pp_hwmgr *hwmgr, bool bgate);
int vega10_update_acp_dpm(struct pp_hwmgr *hwmgr, bool bgate);
int vega10_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable);
int vega10_enable_smc_features(struct pp_hwmgr *hwmgr,
bool enable, uint32_t feature_mask);
#endif /* _VEGA10_HWMGR_H_ */

View File

@ -24,7 +24,6 @@
#include "hwmgr.h"
#include "vega10_hwmgr.h"
#include "vega10_powertune.h"
#include "vega10_smumgr.h"
#include "vega10_ppsmc.h"
#include "vega10_inc.h"
#include "pp_debug.h"
@ -1194,7 +1193,7 @@ static int vega10_disable_se_edc_force_stall_config(struct pp_hwmgr *hwmgr)
int vega10_enable_didt_config(struct pp_hwmgr *hwmgr)
{
int result = 0;
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
if (data->smu_features[GNLD_DIDT].supported) {
if (data->smu_features[GNLD_DIDT].enabled)
@ -1241,7 +1240,7 @@ int vega10_enable_didt_config(struct pp_hwmgr *hwmgr)
int vega10_disable_didt_config(struct pp_hwmgr *hwmgr)
{
int result = 0;
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
if (data->smu_features[GNLD_DIDT].supported) {
if (!data->smu_features[GNLD_DIDT].enabled)
@ -1287,7 +1286,7 @@ int vega10_disable_didt_config(struct pp_hwmgr *hwmgr)
void vega10_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
struct phm_ppt_v2_information *table_info =
(struct phm_ppt_v2_information *)(hwmgr->pptable);
struct phm_tdp_table *tdp_table = table_info->tdp_table;
@ -1326,8 +1325,7 @@ void vega10_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr)
int vega10_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
if (data->registry_data.enable_pkg_pwr_tracking_feature)
smum_send_msg_to_smc_with_parameter(hwmgr,
@ -1338,8 +1336,7 @@ int vega10_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n)
int vega10_enable_power_containment(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
struct phm_ppt_v2_information *table_info =
(struct phm_ppt_v2_information *)(hwmgr->pptable);
struct phm_tdp_table *tdp_table = table_info->tdp_table;
@ -1372,8 +1369,7 @@ int vega10_enable_power_containment(struct pp_hwmgr *hwmgr)
int vega10_disable_power_containment(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
if (PP_CAP(PHM_PlatformCaps_PowerContainment)) {
if (data->smu_features[GNLD_PPT].supported)

View File

@ -23,7 +23,6 @@
#include "vega10_thermal.h"
#include "vega10_hwmgr.h"
#include "vega10_smumgr.h"
#include "vega10_ppsmc.h"
#include "vega10_inc.h"
#include "pp_soc15.h"
@ -32,7 +31,7 @@
static int vega10_get_current_rpm(struct pp_hwmgr *hwmgr, uint32_t *current_rpm)
{
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentRpm);
vega10_read_arg_from_smc(hwmgr, current_rpm);
*current_rpm = smum_get_argument(hwmgr);
return 0;
}
@ -90,7 +89,7 @@ int vega10_fan_ctrl_get_fan_speed_percent(struct pp_hwmgr *hwmgr,
int vega10_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
uint32_t tach_period;
uint32_t crystal_clock_freq;
int result = 0;
@ -111,7 +110,7 @@ int vega10_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed)
if (tach_period == 0)
return -EINVAL;
crystal_clock_freq = smu7_get_xclk(hwmgr);
crystal_clock_freq = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev);
*speed = 60 * crystal_clock_freq * 10000 / tach_period;
}
@ -189,7 +188,7 @@ int vega10_fan_ctrl_set_default_mode(struct pp_hwmgr *hwmgr)
*/
static int vega10_enable_fan_control_feature(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
if (data->smu_features[GNLD_FAN_CONTROL].supported) {
PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(
@ -206,7 +205,7 @@ static int vega10_enable_fan_control_feature(struct pp_hwmgr *hwmgr)
static int vega10_disable_fan_control_feature(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
if (data->smu_features[GNLD_FAN_CONTROL].supported) {
PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(
@ -236,7 +235,7 @@ int vega10_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr)
int vega10_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
if (hwmgr->thermal_controller.fanInfo.bNoFan)
return -1;
@ -332,7 +331,7 @@ int vega10_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t speed)
result = vega10_fan_ctrl_stop_smc_fan_control(hwmgr);
if (!result) {
crystal_clock_freq = smu7_get_xclk(hwmgr);
crystal_clock_freq = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev);
tach_period = 60 * crystal_clock_freq * 10000 / (8 * speed);
reg = soc15_get_register_offset(THM_HWID, 0,
mmCG_TACH_STATUS_BASE_IDX, mmCG_TACH_STATUS);
@ -446,7 +445,7 @@ static int vega10_thermal_initialize(struct pp_hwmgr *hwmgr)
*/
static int vega10_thermal_enable_alert(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
uint32_t val = 0;
uint32_t reg;
@ -478,7 +477,7 @@ static int vega10_thermal_enable_alert(struct pp_hwmgr *hwmgr)
*/
int vega10_thermal_disable_alert(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
uint32_t reg;
if (data->smu_features[GNLD_FW_CTF].supported) {
@ -527,7 +526,7 @@ int vega10_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr)
int vega10_thermal_setup_fan_table(struct pp_hwmgr *hwmgr)
{
int ret;
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
struct vega10_hwmgr *data = hwmgr->backend;
PPTable_t *table = &(data->smc_state_table.pp_table);
if (!data->smu_features[GNLD_FAN_CONTROL].supported)
@ -571,8 +570,9 @@ int vega10_thermal_setup_fan_table(struct pp_hwmgr *hwmgr)
table->FanStartTemp = hwmgr->thermal_controller.
advanceFanControlParameters.usZeroRPMStartTemperature;
ret = vega10_copy_table_to_smc(hwmgr,
(uint8_t *)(&(data->smc_state_table.pp_table)), PPTABLE);
ret = smum_smc_table_manager(hwmgr,
(uint8_t *)(&(data->smc_state_table.pp_table)),
PPTABLE, false);
if (ret)
pr_info("Failed to update Fan Control Table in PPTable!");

View File

@ -73,7 +73,7 @@ extern int vega10_thermal_disable_alert(struct pp_hwmgr *hwmgr);
extern int vega10_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr);
extern int vega10_start_thermal_controller(struct pp_hwmgr *hwmgr,
struct PP_TemperatureRange *range);
extern uint32_t smu7_get_xclk(struct pp_hwmgr *hwmgr);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,438 @@
/*
* 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.
*
*/
#ifndef _VEGA12_HWMGR_H_
#define _VEGA12_HWMGR_H_
#include "hwmgr.h"
#include "vega12/smu9_driver_if.h"
#include "ppatomfwctrl.h"
#define VEGA12_MAX_HARDWARE_POWERLEVELS 2
#define WaterMarksExist 1
#define WaterMarksLoaded 2
#define VG12_PSUEDO_NUM_GFXCLK_DPM_LEVELS 8
#define VG12_PSUEDO_NUM_SOCCLK_DPM_LEVELS 8
#define VG12_PSUEDO_NUM_DCEFCLK_DPM_LEVELS 8
#define VG12_PSUEDO_NUM_UCLK_DPM_LEVELS 4
enum
{
GNLD_DPM_PREFETCHER = 0,
GNLD_DPM_GFXCLK,
GNLD_DPM_UCLK,
GNLD_DPM_SOCCLK,
GNLD_DPM_UVD,
GNLD_DPM_VCE,
GNLD_ULV,
GNLD_DPM_MP0CLK,
GNLD_DPM_LINK,
GNLD_DPM_DCEFCLK,
GNLD_DS_GFXCLK,
GNLD_DS_SOCCLK,
GNLD_DS_LCLK,
GNLD_PPT,
GNLD_TDC,
GNLD_THERMAL,
GNLD_GFX_PER_CU_CG,
GNLD_RM,
GNLD_DS_DCEFCLK,
GNLD_ACDC,
GNLD_VR0HOT,
GNLD_VR1HOT,
GNLD_FW_CTF,
GNLD_LED_DISPLAY,
GNLD_FAN_CONTROL,
GNLD_DIDT,
GNLD_GFXOFF,
GNLD_CG,
GNLD_ACG,
GNLD_FEATURES_MAX
};
#define GNLD_DPM_MAX (GNLD_DPM_DCEFCLK + 1)
#define SMC_DPM_FEATURES 0x30F
struct smu_features {
bool supported;
bool enabled;
bool allowed;
uint32_t smu_feature_id;
uint64_t smu_feature_bitmap;
};
struct vega12_dpm_level {
bool enabled;
uint32_t value;
uint32_t param1;
};
#define VEGA12_MAX_DEEPSLEEP_DIVIDER_ID 5
#define MAX_REGULAR_DPM_NUMBER 16
#define MAX_PCIE_CONF 2
#define VEGA12_MINIMUM_ENGINE_CLOCK 2500
struct vega12_dpm_state {
uint32_t soft_min_level;
uint32_t soft_max_level;
uint32_t hard_min_level;
uint32_t hard_max_level;
};
struct vega12_single_dpm_table {
uint32_t count;
struct vega12_dpm_state dpm_state;
struct vega12_dpm_level dpm_levels[MAX_REGULAR_DPM_NUMBER];
};
struct vega12_odn_dpm_control {
uint32_t count;
uint32_t entries[MAX_REGULAR_DPM_NUMBER];
};
struct vega12_pcie_table {
uint16_t count;
uint8_t pcie_gen[MAX_PCIE_CONF];
uint8_t pcie_lane[MAX_PCIE_CONF];
uint32_t lclk[MAX_PCIE_CONF];
};
struct vega12_dpm_table {
struct vega12_single_dpm_table soc_table;
struct vega12_single_dpm_table gfx_table;
struct vega12_single_dpm_table mem_table;
struct vega12_single_dpm_table eclk_table;
struct vega12_single_dpm_table vclk_table;
struct vega12_single_dpm_table dclk_table;
struct vega12_single_dpm_table dcef_table;
struct vega12_single_dpm_table pixel_table;
struct vega12_single_dpm_table display_table;
struct vega12_single_dpm_table phy_table;
struct vega12_pcie_table pcie_table;
};
#define VEGA12_MAX_LEAKAGE_COUNT 8
struct vega12_leakage_voltage {
uint16_t count;
uint16_t leakage_id[VEGA12_MAX_LEAKAGE_COUNT];
uint16_t actual_voltage[VEGA12_MAX_LEAKAGE_COUNT];
};
struct vega12_display_timing {
uint32_t min_clock_in_sr;
uint32_t num_existing_displays;
};
struct vega12_dpmlevel_enable_mask {
uint32_t uvd_dpm_enable_mask;
uint32_t vce_dpm_enable_mask;
uint32_t samu_dpm_enable_mask;
uint32_t sclk_dpm_enable_mask;
uint32_t mclk_dpm_enable_mask;
};
struct vega12_vbios_boot_state {
bool bsoc_vddc_lock;
uint8_t uc_cooling_id;
uint16_t vddc;
uint16_t vddci;
uint16_t mvddc;
uint16_t vdd_gfx;
uint32_t gfx_clock;
uint32_t mem_clock;
uint32_t soc_clock;
uint32_t dcef_clock;
};
#define DPMTABLE_OD_UPDATE_SCLK 0x00000001
#define DPMTABLE_OD_UPDATE_MCLK 0x00000002
#define DPMTABLE_UPDATE_SCLK 0x00000004
#define DPMTABLE_UPDATE_MCLK 0x00000008
#define DPMTABLE_OD_UPDATE_VDDC 0x00000010
struct vega12_smc_state_table {
uint32_t soc_boot_level;
uint32_t gfx_boot_level;
uint32_t dcef_boot_level;
uint32_t mem_boot_level;
uint32_t uvd_boot_level;
uint32_t vce_boot_level;
uint32_t gfx_max_level;
uint32_t mem_max_level;
uint8_t vr_hot_gpio;
uint8_t ac_dc_gpio;
uint8_t therm_out_gpio;
uint8_t therm_out_polarity;
uint8_t therm_out_mode;
PPTable_t pp_table;
Watermarks_t water_marks_table;
AvfsDebugTable_t avfs_debug_table;
AvfsFuseOverride_t avfs_fuse_override_table;
SmuMetrics_t smu_metrics;
DriverSmuConfig_t driver_smu_config;
DpmActivityMonitorCoeffInt_t dpm_activity_monitor_coeffint;
OverDriveTable_t overdrive_table;
};
struct vega12_mclk_latency_entries {
uint32_t frequency;
uint32_t latency;
};
struct vega12_mclk_latency_table {
uint32_t count;
struct vega12_mclk_latency_entries entries[MAX_REGULAR_DPM_NUMBER];
};
struct vega12_registry_data {
uint64_t disallowed_features;
uint8_t ac_dc_switch_gpio_support;
uint8_t acg_loop_support;
uint8_t clock_stretcher_support;
uint8_t db_ramping_support;
uint8_t didt_mode;
uint8_t didt_support;
uint8_t edc_didt_support;
uint8_t force_dpm_high;
uint8_t fuzzy_fan_control_support;
uint8_t mclk_dpm_key_disabled;
uint8_t od_state_in_dc_support;
uint8_t pcie_lane_override;
uint8_t pcie_speed_override;
uint32_t pcie_clock_override;
uint8_t pcie_dpm_key_disabled;
uint8_t dcefclk_dpm_key_disabled;
uint8_t prefetcher_dpm_key_disabled;
uint8_t quick_transition_support;
uint8_t regulator_hot_gpio_support;
uint8_t master_deep_sleep_support;
uint8_t gfx_clk_deep_sleep_support;
uint8_t sclk_deep_sleep_support;
uint8_t lclk_deep_sleep_support;
uint8_t dce_fclk_deep_sleep_support;
uint8_t sclk_dpm_key_disabled;
uint8_t sclk_throttle_low_notification;
uint8_t skip_baco_hardware;
uint8_t socclk_dpm_key_disabled;
uint8_t sq_ramping_support;
uint8_t tcp_ramping_support;
uint8_t td_ramping_support;
uint8_t dbr_ramping_support;
uint8_t gc_didt_support;
uint8_t psm_didt_support;
uint8_t thermal_support;
uint8_t fw_ctf_enabled;
uint8_t led_dpm_enabled;
uint8_t fan_control_support;
uint8_t ulv_support;
uint8_t odn_feature_enable;
uint8_t disable_water_mark;
uint8_t disable_workload_policy;
uint32_t force_workload_policy_mask;
uint8_t disable_3d_fs_detection;
uint8_t disable_pp_tuning;
uint8_t disable_xlpp_tuning;
uint32_t perf_ui_tuning_profile_turbo;
uint32_t perf_ui_tuning_profile_powerSave;
uint32_t perf_ui_tuning_profile_xl;
uint16_t zrpm_stop_temp;
uint16_t zrpm_start_temp;
uint32_t stable_pstate_sclk_dpm_percentage;
uint8_t fps_support;
uint8_t vr0hot;
uint8_t vr1hot;
uint8_t disable_auto_wattman;
uint32_t auto_wattman_debug;
uint32_t auto_wattman_sample_period;
uint8_t auto_wattman_threshold;
uint8_t log_avfs_param;
uint8_t enable_enginess;
uint8_t custom_fan_support;
uint8_t disable_pcc_limit_control;
};
struct vega12_odn_clock_voltage_dependency_table {
uint32_t count;
struct phm_ppt_v1_clock_voltage_dependency_record
entries[MAX_REGULAR_DPM_NUMBER];
};
struct vega12_odn_dpm_table {
struct vega12_odn_dpm_control control_gfxclk_state;
struct vega12_odn_dpm_control control_memclk_state;
struct phm_odn_clock_levels odn_core_clock_dpm_levels;
struct phm_odn_clock_levels odn_memory_clock_dpm_levels;
struct vega12_odn_clock_voltage_dependency_table vdd_dependency_on_sclk;
struct vega12_odn_clock_voltage_dependency_table vdd_dependency_on_mclk;
struct vega12_odn_clock_voltage_dependency_table vdd_dependency_on_socclk;
uint32_t odn_mclk_min_limit;
};
struct vega12_odn_fan_table {
uint32_t target_fan_speed;
uint32_t target_temperature;
uint32_t min_performance_clock;
uint32_t min_fan_limit;
bool force_fan_pwm;
};
struct vega12_hwmgr {
struct vega12_dpm_table dpm_table;
struct vega12_dpm_table golden_dpm_table;
struct vega12_registry_data registry_data;
struct vega12_vbios_boot_state vbios_boot_state;
struct vega12_mclk_latency_table mclk_latency_table;
struct vega12_leakage_voltage vddc_leakage;
uint32_t vddc_control;
struct pp_atomfwctrl_voltage_table vddc_voltage_table;
uint32_t mvdd_control;
struct pp_atomfwctrl_voltage_table mvdd_voltage_table;
uint32_t vddci_control;
struct pp_atomfwctrl_voltage_table vddci_voltage_table;
uint32_t active_auto_throttle_sources;
uint32_t water_marks_bitmap;
struct vega12_odn_dpm_table odn_dpm_table;
struct vega12_odn_fan_table odn_fan_table;
/* ---- General data ---- */
uint8_t need_update_dpm_table;
bool cac_enabled;
bool battery_state;
bool is_tlu_enabled;
bool avfs_exist;
uint32_t low_sclk_interrupt_threshold;
uint32_t total_active_cus;
struct vega12_display_timing display_timing;
/* ---- Vega12 Dyn Register Settings ---- */
uint32_t debug_settings;
uint32_t lowest_uclk_reserved_for_ulv;
uint32_t gfxclk_average_alpha;
uint32_t socclk_average_alpha;
uint32_t uclk_average_alpha;
uint32_t gfx_activity_average_alpha;
uint32_t display_voltage_mode;
uint32_t dcef_clk_quad_eqn_a;
uint32_t dcef_clk_quad_eqn_b;
uint32_t dcef_clk_quad_eqn_c;
uint32_t disp_clk_quad_eqn_a;
uint32_t disp_clk_quad_eqn_b;
uint32_t disp_clk_quad_eqn_c;
uint32_t pixel_clk_quad_eqn_a;
uint32_t pixel_clk_quad_eqn_b;
uint32_t pixel_clk_quad_eqn_c;
uint32_t phy_clk_quad_eqn_a;
uint32_t phy_clk_quad_eqn_b;
uint32_t phy_clk_quad_eqn_c;
/* ---- Thermal Temperature Setting ---- */
struct vega12_dpmlevel_enable_mask dpm_level_enable_mask;
/* ---- Power Gating States ---- */
bool uvd_power_gated;
bool vce_power_gated;
bool samu_power_gated;
bool need_long_memory_training;
/* Internal settings to apply the application power optimization parameters */
bool apply_optimized_settings;
uint32_t disable_dpm_mask;
/* ---- Overdrive next setting ---- */
uint32_t apply_overdrive_next_settings_mask;
/* ---- Workload Mask ---- */
uint32_t workload_mask;
/* ---- SMU9 ---- */
uint32_t smu_version;
struct smu_features smu_features[GNLD_FEATURES_MAX];
struct vega12_smc_state_table smc_state_table;
};
#define VEGA12_DPM2_NEAR_TDP_DEC 10
#define VEGA12_DPM2_ABOVE_SAFE_INC 5
#define VEGA12_DPM2_BELOW_SAFE_INC 20
#define VEGA12_DPM2_LTA_WINDOW_SIZE 7
#define VEGA12_DPM2_LTS_TRUNCATE 0
#define VEGA12_DPM2_TDP_SAFE_LIMIT_PERCENT 80
#define VEGA12_DPM2_MAXPS_PERCENT_M 90
#define VEGA12_DPM2_MAXPS_PERCENT_H 90
#define VEGA12_DPM2_PWREFFICIENCYRATIO_MARGIN 50
#define VEGA12_DPM2_SQ_RAMP_MAX_POWER 0x3FFF
#define VEGA12_DPM2_SQ_RAMP_MIN_POWER 0x12
#define VEGA12_DPM2_SQ_RAMP_MAX_POWER_DELTA 0x15
#define VEGA12_DPM2_SQ_RAMP_SHORT_TERM_INTERVAL_SIZE 0x1E
#define VEGA12_DPM2_SQ_RAMP_LONG_TERM_INTERVAL_RATIO 0xF
#define VEGA12_VOLTAGE_CONTROL_NONE 0x0
#define VEGA12_VOLTAGE_CONTROL_BY_GPIO 0x1
#define VEGA12_VOLTAGE_CONTROL_BY_SVID2 0x2
#define VEGA12_VOLTAGE_CONTROL_MERGED 0x3
/* To convert to Q8.8 format for firmware */
#define VEGA12_Q88_FORMAT_CONVERSION_UNIT 256
#define VEGA12_UNUSED_GPIO_PIN 0x7F
#define VEGA12_THERM_OUT_MODE_DISABLE 0x0
#define VEGA12_THERM_OUT_MODE_THERM_ONLY 0x1
#define VEGA12_THERM_OUT_MODE_THERM_VRHOT 0x2
#define PPVEGA12_VEGA12DISPLAYVOLTAGEMODE_DFLT 0xffffffff
#define PPREGKEY_VEGA12QUADRATICEQUATION_DFLT 0xffffffff
#define PPVEGA12_VEGA12GFXCLKAVERAGEALPHA_DFLT 25 /* 10% * 255 = 25 */
#define PPVEGA12_VEGA12SOCCLKAVERAGEALPHA_DFLT 25 /* 10% * 255 = 25 */
#define PPVEGA12_VEGA12UCLKCLKAVERAGEALPHA_DFLT 25 /* 10% * 255 = 25 */
#define PPVEGA12_VEGA12GFXACTIVITYAVERAGEALPHA_DFLT 25 /* 10% * 255 = 25 */
#define PPVEGA12_VEGA12LOWESTUCLKRESERVEDFORULV_DFLT 0xffffffff
#define PPVEGA12_VEGA12DISPLAYVOLTAGEMODE_DFLT 0xffffffff
#define PPREGKEY_VEGA12QUADRATICEQUATION_DFLT 0xffffffff
#define VEGA12_UMD_PSTATE_GFXCLK_LEVEL 0x3
#define VEGA12_UMD_PSTATE_SOCCLK_LEVEL 0x3
#define VEGA12_UMD_PSTATE_MCLK_LEVEL 0x2
int vega12_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable);
#endif /* _VEGA12_HWMGR_H_ */

View File

@ -0,0 +1,39 @@
/*
* 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.
*
*/
#ifndef VEGA12_INC_H
#define VEGA12_INC_H
#include "asic_reg/thm/thm_9_0_default.h"
#include "asic_reg/thm/thm_9_0_offset.h"
#include "asic_reg/thm/thm_9_0_sh_mask.h"
#include "asic_reg/mp/mp_9_0_offset.h"
#include "asic_reg/mp/mp_9_0_sh_mask.h"
#include "asic_reg/gc/gc_9_2_1_offset.h"
#include "asic_reg/gc/gc_9_2_1_sh_mask.h"
#include "asic_reg/nbio/nbio_6_1_offset.h"
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,53 @@
/*
* 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.
*
*/
#ifndef _VEGA12_POWERTUNE_H_
#define _VEGA12_POWERTUNE_H_
enum vega12_didt_config_reg_type {
VEGA12_CONFIGREG_DIDT = 0,
VEGA12_CONFIGREG_GCCAC,
VEGA12_CONFIGREG_SECAC
};
/* PowerContainment Features */
#define POWERCONTAINMENT_FEATURE_DTE 0x00000001
#define POWERCONTAINMENT_FEATURE_TDCLimit 0x00000002
#define POWERCONTAINMENT_FEATURE_PkgPwrLimit 0x00000004
struct vega12_didt_config_reg {
uint32_t offset;
uint32_t mask;
uint32_t shift;
uint32_t value;
};
int vega12_enable_power_containment(struct pp_hwmgr *hwmgr);
int vega12_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n);
int vega12_power_control_set_level(struct pp_hwmgr *hwmgr);
int vega12_disable_power_containment(struct pp_hwmgr *hwmgr);
int vega12_enable_didt_config(struct pp_hwmgr *hwmgr);
int vega12_disable_didt_config(struct pp_hwmgr *hwmgr);
#endif /* _VEGA12_POWERTUNE_H_ */

View File

@ -0,0 +1,109 @@
/*
* 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.
*
*/
#ifndef _VEGA12_PPTABLE_H_
#define _VEGA12_PPTABLE_H_
#pragma pack(push, 1)
#define ATOM_VEGA12_PP_THERMALCONTROLLER_NONE 0
#define ATOM_VEGA12_PP_THERMALCONTROLLER_VEGA12 25
#define ATOM_VEGA12_PP_PLATFORM_CAP_POWERPLAY 0x1
#define ATOM_VEGA12_PP_PLATFORM_CAP_SBIOSPOWERSOURCE 0x2
#define ATOM_VEGA12_PP_PLATFORM_CAP_HARDWAREDC 0x4
#define ATOM_VEGA12_PP_PLATFORM_CAP_BACO 0x8
#define ATOM_VEGA12_PP_PLATFORM_CAP_BAMACO 0x10
#define ATOM_VEGA12_PP_PLATFORM_CAP_ENABLESHADOWPSTATE 0x20
#define ATOM_VEGA12_TABLE_REVISION_VEGA12 9
enum ATOM_VEGA12_ODSETTING_ID {
ATOM_VEGA12_ODSETTING_GFXCLKFMAX = 0,
ATOM_VEGA12_ODSETTING_GFXCLKFMIN,
ATOM_VEGA12_ODSETTING_VDDGFXCURVEFREQ_P1,
ATOM_VEGA12_ODSETTING_VDDGFXCURVEVOLTAGEOFFSET_P1,
ATOM_VEGA12_ODSETTING_VDDGFXCURVEFREQ_P2,
ATOM_VEGA12_ODSETTING_VDDGFXCURVEVOLTAGEOFFSET_P2,
ATOM_VEGA12_ODSETTING_VDDGFXCURVEFREQ_P3,
ATOM_VEGA12_ODSETTING_VDDGFXCURVEVOLTAGEOFFSET_P3,
ATOM_VEGA12_ODSETTING_UCLKFMAX,
ATOM_VEGA12_ODSETTING_POWERPERCENTAGE,
ATOM_VEGA12_ODSETTING_FANRPMMIN,
ATOM_VEGA12_ODSETTING_FANRPMACOUSTICLIMIT,
ATOM_VEGA12_ODSETTING_FANTARGETTEMPERATURE,
ATOM_VEGA12_ODSETTING_OPERATINGTEMPMAX,
ATOM_VEGA12_ODSETTING_COUNT,
};
typedef enum ATOM_VEGA12_ODSETTING_ID ATOM_VEGA12_ODSETTING_ID;
enum ATOM_VEGA12_PPCLOCK_ID {
ATOM_VEGA12_PPCLOCK_GFXCLK = 0,
ATOM_VEGA12_PPCLOCK_VCLK,
ATOM_VEGA12_PPCLOCK_DCLK,
ATOM_VEGA12_PPCLOCK_ECLK,
ATOM_VEGA12_PPCLOCK_SOCCLK,
ATOM_VEGA12_PPCLOCK_UCLK,
ATOM_VEGA12_PPCLOCK_DCEFCLK,
ATOM_VEGA12_PPCLOCK_DISPCLK,
ATOM_VEGA12_PPCLOCK_PIXCLK,
ATOM_VEGA12_PPCLOCK_PHYCLK,
ATOM_VEGA12_PPCLOCK_COUNT,
};
typedef enum ATOM_VEGA12_PPCLOCK_ID ATOM_VEGA12_PPCLOCK_ID;
typedef struct _ATOM_VEGA12_POWERPLAYTABLE
{
struct atom_common_table_header sHeader;
UCHAR ucTableRevision;
USHORT usTableSize;
ULONG ulGoldenPPID;
ULONG ulGoldenRevision;
USHORT usFormatID;
ULONG ulPlatformCaps;
UCHAR ucThermalControllerType;
USHORT usSmallPowerLimit1;
USHORT usSmallPowerLimit2;
USHORT usBoostPowerLimit;
USHORT usODTurboPowerLimit;
USHORT usODPowerSavePowerLimit;
USHORT usSoftwareShutdownTemp;
ULONG PowerSavingClockMax [ATOM_VEGA12_PPCLOCK_COUNT];
ULONG PowerSavingClockMin [ATOM_VEGA12_PPCLOCK_COUNT];
ULONG ODSettingsMax [ATOM_VEGA12_ODSETTING_COUNT];
ULONG ODSettingsMin [ATOM_VEGA12_ODSETTING_COUNT];
USHORT usReserve[5];
PPTable_t smcPPTable;
} ATOM_Vega12_POWERPLAYTABLE;
#pragma pack(pop)
#endif

View File

@ -0,0 +1,430 @@
/*
* Copyright 2017 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/fb.h>
#include "vega12/smu9_driver_if.h"
#include "vega12_processpptables.h"
#include "ppatomfwctrl.h"
#include "atomfirmware.h"
#include "pp_debug.h"
#include "cgs_common.h"
#include "vega12_pptable.h"
static void set_hw_cap(struct pp_hwmgr *hwmgr, bool enable,
enum phm_platform_caps cap)
{
if (enable)
phm_cap_set(hwmgr->platform_descriptor.platformCaps, cap);
else
phm_cap_unset(hwmgr->platform_descriptor.platformCaps, cap);
}
static const void *get_powerplay_table(struct pp_hwmgr *hwmgr)
{
int index = GetIndexIntoMasterDataTable(powerplayinfo);
u16 size;
u8 frev, crev;
const void *table_address = hwmgr->soft_pp_table;
if (!table_address) {
table_address = (ATOM_Vega12_POWERPLAYTABLE *)
cgs_atom_get_data_table(hwmgr->device, index,
&size, &frev, &crev);
hwmgr->soft_pp_table = table_address; /*Cache the result in RAM.*/
hwmgr->soft_pp_table_size = size;
}
return table_address;
}
static int check_powerplay_tables(
struct pp_hwmgr *hwmgr,
const ATOM_Vega12_POWERPLAYTABLE *powerplay_table)
{
PP_ASSERT_WITH_CODE((powerplay_table->sHeader.format_revision >=
ATOM_VEGA12_TABLE_REVISION_VEGA12),
"Unsupported PPTable format!", return -1);
PP_ASSERT_WITH_CODE(powerplay_table->sHeader.structuresize > 0,
"Invalid PowerPlay Table!", return -1);
return 0;
}
static int set_platform_caps(struct pp_hwmgr *hwmgr, uint32_t powerplay_caps)
{
set_hw_cap(
hwmgr,
0 != (powerplay_caps & ATOM_VEGA12_PP_PLATFORM_CAP_POWERPLAY),
PHM_PlatformCaps_PowerPlaySupport);
set_hw_cap(
hwmgr,
0 != (powerplay_caps & ATOM_VEGA12_PP_PLATFORM_CAP_SBIOSPOWERSOURCE),
PHM_PlatformCaps_BiosPowerSourceControl);
set_hw_cap(
hwmgr,
0 != (powerplay_caps & ATOM_VEGA12_PP_PLATFORM_CAP_BACO),
PHM_PlatformCaps_BACO);
set_hw_cap(
hwmgr,
0 != (powerplay_caps & ATOM_VEGA12_PP_PLATFORM_CAP_BAMACO),
PHM_PlatformCaps_BAMACO);
return 0;
}
static int copy_clock_limits_array(
struct pp_hwmgr *hwmgr,
uint32_t **pptable_info_array,
const uint32_t *pptable_array)
{
uint32_t array_size, i;
uint32_t *table;
array_size = sizeof(uint32_t) * ATOM_VEGA12_PPCLOCK_COUNT;
table = kzalloc(array_size, GFP_KERNEL);
if (NULL == table)
return -ENOMEM;
for (i = 0; i < ATOM_VEGA12_PPCLOCK_COUNT; i++)
table[i] = pptable_array[i];
*pptable_info_array = table;
return 0;
}
static int copy_overdrive_settings_limits_array(
struct pp_hwmgr *hwmgr,
uint32_t **pptable_info_array,
const uint32_t *pptable_array)
{
uint32_t array_size, i;
uint32_t *table;
array_size = sizeof(uint32_t) * ATOM_VEGA12_ODSETTING_COUNT;
table = kzalloc(array_size, GFP_KERNEL);
if (NULL == table)
return -ENOMEM;
for (i = 0; i < ATOM_VEGA12_ODSETTING_COUNT; i++)
table[i] = pptable_array[i];
*pptable_info_array = table;
return 0;
}
static int append_vbios_pptable(struct pp_hwmgr *hwmgr, PPTable_t *ppsmc_pptable)
{
struct pp_atomfwctrl_smc_dpm_parameters smc_dpm_table;
PP_ASSERT_WITH_CODE(
pp_atomfwctrl_get_smc_dpm_information(hwmgr, &smc_dpm_table) == 0,
"[appendVbiosPPTable] Failed to retrieve Smc Dpm Table from VBIOS!",
return -1);
ppsmc_pptable->Liquid1_I2C_address = smc_dpm_table.liquid1_i2c_address;
ppsmc_pptable->Liquid2_I2C_address = smc_dpm_table.liquid2_i2c_address;
ppsmc_pptable->Vr_I2C_address = smc_dpm_table.vr_i2c_address;
ppsmc_pptable->Plx_I2C_address = smc_dpm_table.plx_i2c_address;
ppsmc_pptable->Liquid_I2C_LineSCL = smc_dpm_table.liquid_i2c_linescl;
ppsmc_pptable->Liquid_I2C_LineSDA = smc_dpm_table.liquid_i2c_linesda;
ppsmc_pptable->Vr_I2C_LineSCL = smc_dpm_table.vr_i2c_linescl;
ppsmc_pptable->Vr_I2C_LineSDA = smc_dpm_table.vr_i2c_linesda;
ppsmc_pptable->Plx_I2C_LineSCL = smc_dpm_table.plx_i2c_linescl;
ppsmc_pptable->Plx_I2C_LineSDA = smc_dpm_table.plx_i2c_linesda;
ppsmc_pptable->VrSensorPresent = smc_dpm_table.vrsensorpresent;
ppsmc_pptable->LiquidSensorPresent = smc_dpm_table.liquidsensorpresent;
ppsmc_pptable->MaxVoltageStepGfx = smc_dpm_table.maxvoltagestepgfx;
ppsmc_pptable->MaxVoltageStepSoc = smc_dpm_table.maxvoltagestepsoc;
ppsmc_pptable->VddGfxVrMapping = smc_dpm_table.vddgfxvrmapping;
ppsmc_pptable->VddSocVrMapping = smc_dpm_table.vddsocvrmapping;
ppsmc_pptable->VddMem0VrMapping = smc_dpm_table.vddmem0vrmapping;
ppsmc_pptable->VddMem1VrMapping = smc_dpm_table.vddmem1vrmapping;
ppsmc_pptable->GfxUlvPhaseSheddingMask = smc_dpm_table.gfxulvphasesheddingmask;
ppsmc_pptable->SocUlvPhaseSheddingMask = smc_dpm_table.soculvphasesheddingmask;
ppsmc_pptable->GfxMaxCurrent = smc_dpm_table.gfxmaxcurrent;
ppsmc_pptable->GfxOffset = smc_dpm_table.gfxoffset;
ppsmc_pptable->Padding_TelemetryGfx = smc_dpm_table.padding_telemetrygfx;
ppsmc_pptable->SocMaxCurrent = smc_dpm_table.socmaxcurrent;
ppsmc_pptable->SocOffset = smc_dpm_table.socoffset;
ppsmc_pptable->Padding_TelemetrySoc = smc_dpm_table.padding_telemetrysoc;
ppsmc_pptable->Mem0MaxCurrent = smc_dpm_table.mem0maxcurrent;
ppsmc_pptable->Mem0Offset = smc_dpm_table.mem0offset;
ppsmc_pptable->Padding_TelemetryMem0 = smc_dpm_table.padding_telemetrymem0;
ppsmc_pptable->Mem1MaxCurrent = smc_dpm_table.mem1maxcurrent;
ppsmc_pptable->Mem1Offset = smc_dpm_table.mem1offset;
ppsmc_pptable->Padding_TelemetryMem1 = smc_dpm_table.padding_telemetrymem1;
ppsmc_pptable->AcDcGpio = smc_dpm_table.acdcgpio;
ppsmc_pptable->AcDcPolarity = smc_dpm_table.acdcpolarity;
ppsmc_pptable->VR0HotGpio = smc_dpm_table.vr0hotgpio;
ppsmc_pptable->VR0HotPolarity = smc_dpm_table.vr0hotpolarity;
ppsmc_pptable->VR1HotGpio = smc_dpm_table.vr1hotgpio;
ppsmc_pptable->VR1HotPolarity = smc_dpm_table.vr1hotpolarity;
ppsmc_pptable->Padding1 = smc_dpm_table.padding1;
ppsmc_pptable->Padding2 = smc_dpm_table.padding2;
ppsmc_pptable->LedPin0 = smc_dpm_table.ledpin0;
ppsmc_pptable->LedPin1 = smc_dpm_table.ledpin1;
ppsmc_pptable->LedPin2 = smc_dpm_table.ledpin2;
ppsmc_pptable->GfxclkSpreadEnabled = smc_dpm_table.gfxclkspreadenabled;
ppsmc_pptable->GfxclkSpreadPercent = smc_dpm_table.gfxclkspreadpercent;
ppsmc_pptable->GfxclkSpreadFreq = smc_dpm_table.gfxclkspreadfreq;
ppsmc_pptable->UclkSpreadEnabled = 0;
ppsmc_pptable->UclkSpreadPercent = smc_dpm_table.uclkspreadpercent;
ppsmc_pptable->UclkSpreadFreq = smc_dpm_table.uclkspreadfreq;
ppsmc_pptable->SocclkSpreadEnabled = 0;
ppsmc_pptable->SocclkSpreadPercent = smc_dpm_table.socclkspreadpercent;
ppsmc_pptable->SocclkSpreadFreq = smc_dpm_table.socclkspreadfreq;
return 0;
}
#define VEGA12_ENGINECLOCK_HARDMAX 198000
static int init_powerplay_table_information(
struct pp_hwmgr *hwmgr,
const ATOM_Vega12_POWERPLAYTABLE *powerplay_table)
{
struct phm_ppt_v3_information *pptable_information =
(struct phm_ppt_v3_information *)hwmgr->pptable;
uint32_t disable_power_control = 0;
int result;
hwmgr->thermal_controller.ucType = powerplay_table->ucThermalControllerType;
pptable_information->uc_thermal_controller_type = powerplay_table->ucThermalControllerType;
set_hw_cap(hwmgr,
ATOM_VEGA12_PP_THERMALCONTROLLER_NONE != hwmgr->thermal_controller.ucType,
PHM_PlatformCaps_ThermalController);
phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl);
if (powerplay_table->ODSettingsMax[ATOM_VEGA12_ODSETTING_GFXCLKFMAX] > VEGA12_ENGINECLOCK_HARDMAX)
hwmgr->platform_descriptor.overdriveLimit.engineClock = VEGA12_ENGINECLOCK_HARDMAX;
else
hwmgr->platform_descriptor.overdriveLimit.engineClock = powerplay_table->ODSettingsMax[ATOM_VEGA12_ODSETTING_GFXCLKFMAX];
hwmgr->platform_descriptor.overdriveLimit.memoryClock = powerplay_table->ODSettingsMax[ATOM_VEGA12_ODSETTING_UCLKFMAX];
copy_overdrive_settings_limits_array(hwmgr, &pptable_information->od_settings_max, powerplay_table->ODSettingsMax);
copy_overdrive_settings_limits_array(hwmgr, &pptable_information->od_settings_min, powerplay_table->ODSettingsMin);
/* hwmgr->platformDescriptor.minOverdriveVDDC = 0;
hwmgr->platformDescriptor.maxOverdriveVDDC = 0;
hwmgr->platformDescriptor.overdriveVDDCStep = 0; */
if (hwmgr->platform_descriptor.overdriveLimit.engineClock > 0
&& hwmgr->platform_descriptor.overdriveLimit.memoryClock > 0)
phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_ACOverdriveSupport);
pptable_information->us_small_power_limit1 = powerplay_table->usSmallPowerLimit1;
pptable_information->us_small_power_limit2 = powerplay_table->usSmallPowerLimit2;
pptable_information->us_boost_power_limit = powerplay_table->usBoostPowerLimit;
pptable_information->us_od_turbo_power_limit = powerplay_table->usODTurboPowerLimit;
pptable_information->us_od_powersave_power_limit = powerplay_table->usODPowerSavePowerLimit;
pptable_information->us_software_shutdown_temp = powerplay_table->usSoftwareShutdownTemp;
hwmgr->platform_descriptor.TDPODLimit = (uint16_t)powerplay_table->ODSettingsMax[ATOM_VEGA12_ODSETTING_POWERPERCENTAGE];
disable_power_control = 0;
if (!disable_power_control) {
/* enable TDP overdrive (PowerControl) feature as well if supported */
if (hwmgr->platform_descriptor.TDPODLimit)
phm_cap_set(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_PowerControl);
}
copy_clock_limits_array(hwmgr, &pptable_information->power_saving_clock_max, powerplay_table->PowerSavingClockMax);
copy_clock_limits_array(hwmgr, &pptable_information->power_saving_clock_min, powerplay_table->PowerSavingClockMin);
pptable_information->smc_pptable = (PPTable_t *)kmalloc(sizeof(PPTable_t), GFP_KERNEL);
if (pptable_information->smc_pptable == NULL)
return -ENOMEM;
memcpy(pptable_information->smc_pptable, &(powerplay_table->smcPPTable), sizeof(PPTable_t));
result = append_vbios_pptable(hwmgr, (pptable_information->smc_pptable));
return result;
}
int vega12_pp_tables_initialize(struct pp_hwmgr *hwmgr)
{
int result = 0;
const ATOM_Vega12_POWERPLAYTABLE *powerplay_table;
hwmgr->pptable = kzalloc(sizeof(struct phm_ppt_v3_information), GFP_KERNEL);
PP_ASSERT_WITH_CODE((hwmgr->pptable != NULL),
"Failed to allocate hwmgr->pptable!", return -ENOMEM);
powerplay_table = get_powerplay_table(hwmgr);
PP_ASSERT_WITH_CODE((powerplay_table != NULL),
"Missing PowerPlay Table!", return -1);
result = check_powerplay_tables(hwmgr, powerplay_table);
PP_ASSERT_WITH_CODE((result == 0),
"check_powerplay_tables failed", return result);
result = set_platform_caps(hwmgr,
le32_to_cpu(powerplay_table->ulPlatformCaps));
PP_ASSERT_WITH_CODE((result == 0),
"set_platform_caps failed", return result);
result = init_powerplay_table_information(hwmgr, powerplay_table);
PP_ASSERT_WITH_CODE((result == 0),
"init_powerplay_table_information failed", return result);
return result;
}
static int vega12_pp_tables_uninitialize(struct pp_hwmgr *hwmgr)
{
struct phm_ppt_v3_information *pp_table_info =
(struct phm_ppt_v3_information *)(hwmgr->pptable);
kfree(pp_table_info->power_saving_clock_max);
pp_table_info->power_saving_clock_max = NULL;
kfree(pp_table_info->power_saving_clock_min);
pp_table_info->power_saving_clock_min = NULL;
kfree(pp_table_info->od_settings_max);
pp_table_info->od_settings_max = NULL;
kfree(pp_table_info->od_settings_min);
pp_table_info->od_settings_min = NULL;
kfree(pp_table_info->smc_pptable);
pp_table_info->smc_pptable = NULL;
kfree(hwmgr->pptable);
hwmgr->pptable = NULL;
return 0;
}
const struct pp_table_func vega12_pptable_funcs = {
.pptable_init = vega12_pp_tables_initialize,
.pptable_fini = vega12_pp_tables_uninitialize,
};
#if 0
static uint32_t make_classification_flags(struct pp_hwmgr *hwmgr,
uint16_t classification, uint16_t classification2)
{
uint32_t result = 0;
if (classification & ATOM_PPLIB_CLASSIFICATION_BOOT)
result |= PP_StateClassificationFlag_Boot;
if (classification & ATOM_PPLIB_CLASSIFICATION_THERMAL)
result |= PP_StateClassificationFlag_Thermal;
if (classification & ATOM_PPLIB_CLASSIFICATION_LIMITEDPOWERSOURCE)
result |= PP_StateClassificationFlag_LimitedPowerSource;
if (classification & ATOM_PPLIB_CLASSIFICATION_REST)
result |= PP_StateClassificationFlag_Rest;
if (classification & ATOM_PPLIB_CLASSIFICATION_FORCED)
result |= PP_StateClassificationFlag_Forced;
if (classification & ATOM_PPLIB_CLASSIFICATION_ACPI)
result |= PP_StateClassificationFlag_ACPI;
if (classification2 & ATOM_PPLIB_CLASSIFICATION2_LIMITEDPOWERSOURCE_2)
result |= PP_StateClassificationFlag_LimitedPowerSource_2;
return result;
}
int vega12_get_powerplay_table_entry(struct pp_hwmgr *hwmgr,
uint32_t entry_index, struct pp_power_state *power_state,
int (*call_back_func)(struct pp_hwmgr *, void *,
struct pp_power_state *, void *, uint32_t))
{
int result = 0;
const ATOM_Vega12_State_Array *state_arrays;
const ATOM_Vega12_State *state_entry;
const ATOM_Vega12_POWERPLAYTABLE *pp_table =
get_powerplay_table(hwmgr);
PP_ASSERT_WITH_CODE(pp_table, "Missing PowerPlay Table!",
return -1;);
power_state->classification.bios_index = entry_index;
if (pp_table->sHeader.format_revision >=
ATOM_Vega12_TABLE_REVISION_VEGA12) {
state_arrays = (ATOM_Vega12_State_Array *)
(((unsigned long)pp_table) +
le16_to_cpu(pp_table->usStateArrayOffset));
PP_ASSERT_WITH_CODE(pp_table->usStateArrayOffset > 0,
"Invalid PowerPlay Table State Array Offset.",
return -1);
PP_ASSERT_WITH_CODE(state_arrays->ucNumEntries > 0,
"Invalid PowerPlay Table State Array.",
return -1);
PP_ASSERT_WITH_CODE((entry_index <= state_arrays->ucNumEntries),
"Invalid PowerPlay Table State Array Entry.",
return -1);
state_entry = &(state_arrays->states[entry_index]);
result = call_back_func(hwmgr, (void *)state_entry, power_state,
(void *)pp_table,
make_classification_flags(hwmgr,
le16_to_cpu(state_entry->usClassification),
le16_to_cpu(state_entry->usClassification2)));
}
if (!result && (power_state->classification.flags &
PP_StateClassificationFlag_Boot))
result = hwmgr->hwmgr_func->patch_boot_state(hwmgr, &(power_state->hardware));
return result;
}
#endif

View File

@ -0,0 +1,58 @@
/*
* 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.
*
*/
#ifndef VEGA12_PROCESSPPTABLES_H
#define VEGA12_PROCESSPPTABLES_H
#include "hwmgr.h"
enum Vega12_I2CLineID {
Vega12_I2CLineID_DDC1 = 0x90,
Vega12_I2CLineID_DDC2 = 0x91,
Vega12_I2CLineID_DDC3 = 0x92,
Vega12_I2CLineID_DDC4 = 0x93,
Vega12_I2CLineID_DDC5 = 0x94,
Vega12_I2CLineID_DDC6 = 0x95,
Vega12_I2CLineID_SCLSDA = 0x96,
Vega12_I2CLineID_DDCVGA = 0x97
};
#define Vega12_I2C_DDC1DATA 0
#define Vega12_I2C_DDC1CLK 1
#define Vega12_I2C_DDC2DATA 2
#define Vega12_I2C_DDC2CLK 3
#define Vega12_I2C_DDC3DATA 4
#define Vega12_I2C_DDC3CLK 5
#define Vega12_I2C_SDA 40
#define Vega12_I2C_SCL 41
#define Vega12_I2C_DDC4DATA 65
#define Vega12_I2C_DDC4CLK 66
#define Vega12_I2C_DDC5DATA 0x48
#define Vega12_I2C_DDC5CLK 0x49
#define Vega12_I2C_DDC6DATA 0x4a
#define Vega12_I2C_DDC6CLK 0x4b
#define Vega12_I2C_DDCVGADATA 0x4c
#define Vega12_I2C_DDCVGACLK 0x4d
extern const struct pp_table_func vega12_pptable_funcs;
#endif

View File

@ -0,0 +1,324 @@
/*
* Copyright 2017 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "vega12_thermal.h"
#include "vega12_hwmgr.h"
#include "vega12_smumgr.h"
#include "vega12_ppsmc.h"
#include "vega12_inc.h"
#include "pp_soc15.h"
#include "pp_debug.h"
static int vega12_get_current_rpm(struct pp_hwmgr *hwmgr, uint32_t *current_rpm)
{
PP_ASSERT_WITH_CODE(!smum_send_msg_to_smc(hwmgr,
PPSMC_MSG_GetCurrentRpm),
"Attempt to get current RPM from SMC Failed!",
return -1);
PP_ASSERT_WITH_CODE(!vega12_read_arg_from_smc(hwmgr,
current_rpm),
"Attempt to read current RPM from SMC Failed!",
return -1);
return 0;
}
int vega12_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr,
struct phm_fan_speed_info *fan_speed_info)
{
memset(fan_speed_info, 0, sizeof(*fan_speed_info));
fan_speed_info->supports_percent_read = false;
fan_speed_info->supports_percent_write = false;
fan_speed_info->supports_rpm_read = true;
fan_speed_info->supports_rpm_write = true;
return 0;
}
int vega12_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed)
{
*speed = 0;
return vega12_get_current_rpm(hwmgr, speed);
}
/**
* @fn vega12_enable_fan_control_feature
* @brief Enables the SMC Fan Control Feature.
*
* @param hwmgr - the address of the powerplay hardware manager.
* @return 0 on success. -1 otherwise.
*/
static int vega12_enable_fan_control_feature(struct pp_hwmgr *hwmgr)
{
#if 0
struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
if (data->smu_features[GNLD_FAN_CONTROL].supported) {
PP_ASSERT_WITH_CODE(!vega12_enable_smc_features(
hwmgr, true,
data->smu_features[GNLD_FAN_CONTROL].
smu_feature_bitmap),
"Attempt to Enable FAN CONTROL feature Failed!",
return -1);
data->smu_features[GNLD_FAN_CONTROL].enabled = true;
}
#endif
return 0;
}
static int vega12_disable_fan_control_feature(struct pp_hwmgr *hwmgr)
{
#if 0
struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
if (data->smu_features[GNLD_FAN_CONTROL].supported) {
PP_ASSERT_WITH_CODE(!vega12_enable_smc_features(
hwmgr, false,
data->smu_features[GNLD_FAN_CONTROL].
smu_feature_bitmap),
"Attempt to Enable FAN CONTROL feature Failed!",
return -1);
data->smu_features[GNLD_FAN_CONTROL].enabled = false;
}
#endif
return 0;
}
int vega12_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr)
{
struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
if (data->smu_features[GNLD_FAN_CONTROL].supported)
PP_ASSERT_WITH_CODE(
!vega12_enable_fan_control_feature(hwmgr),
"Attempt to Enable SMC FAN CONTROL Feature Failed!",
return -1);
return 0;
}
int vega12_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr)
{
struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
if (data->smu_features[GNLD_FAN_CONTROL].supported)
PP_ASSERT_WITH_CODE(!vega12_disable_fan_control_feature(hwmgr),
"Attempt to Disable SMC FAN CONTROL Feature Failed!",
return -1);
return 0;
}
/**
* Reset Fan Speed to default.
* @param hwmgr the address of the powerplay hardware manager.
* @exception Always succeeds.
*/
int vega12_fan_ctrl_reset_fan_speed_to_default(struct pp_hwmgr *hwmgr)
{
return vega12_fan_ctrl_start_smc_fan_control(hwmgr);
}
/**
* Reads the remote temperature from the SIslands thermal controller.
*
* @param hwmgr The address of the hardware manager.
*/
int vega12_thermal_get_temperature(struct pp_hwmgr *hwmgr)
{
int temp = 0;
uint32_t reg;
reg = soc15_get_register_offset(THM_HWID, 0,
mmCG_MULT_THERMAL_STATUS_BASE_IDX, mmCG_MULT_THERMAL_STATUS);
temp = cgs_read_register(hwmgr->device, reg);
temp = (temp & CG_MULT_THERMAL_STATUS__CTF_TEMP_MASK) >>
CG_MULT_THERMAL_STATUS__CTF_TEMP__SHIFT;
temp = temp & 0x1ff;
temp *= PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
return temp;
}
/**
* Set the requested temperature range for high and low alert signals
*
* @param hwmgr The address of the hardware manager.
* @param range Temperature range to be programmed for
* high and low alert signals
* @exception PP_Result_BadInput if the input data is not valid.
*/
static int vega12_thermal_set_temperature_range(struct pp_hwmgr *hwmgr,
struct PP_TemperatureRange *range)
{
int low = VEGA12_THERMAL_MINIMUM_ALERT_TEMP *
PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
int high = VEGA12_THERMAL_MAXIMUM_ALERT_TEMP *
PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
uint32_t val, reg;
if (low < range->min)
low = range->min;
if (high > range->max)
high = range->max;
if (low > high)
return -EINVAL;
reg = soc15_get_register_offset(THM_HWID, 0,
mmTHM_THERMAL_INT_CTRL_BASE_IDX, mmTHM_THERMAL_INT_CTRL);
val = cgs_read_register(hwmgr->device, reg);
val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5);
val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1);
val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
val = val & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK);
cgs_write_register(hwmgr->device, reg, val);
return 0;
}
/**
* Enable thermal alerts on the RV770 thermal controller.
*
* @param hwmgr The address of the hardware manager.
*/
static int vega12_thermal_enable_alert(struct pp_hwmgr *hwmgr)
{
uint32_t val = 0;
uint32_t reg;
val |= (1 << THM_THERMAL_INT_ENA__THERM_INTH_CLR__SHIFT);
val |= (1 << THM_THERMAL_INT_ENA__THERM_INTL_CLR__SHIFT);
val |= (1 << THM_THERMAL_INT_ENA__THERM_TRIGGER_CLR__SHIFT);
reg = soc15_get_register_offset(THM_HWID, 0, mmTHM_THERMAL_INT_ENA_BASE_IDX, mmTHM_THERMAL_INT_ENA);
cgs_write_register(hwmgr->device, reg, val);
return 0;
}
/**
* Disable thermal alerts on the RV770 thermal controller.
* @param hwmgr The address of the hardware manager.
*/
int vega12_thermal_disable_alert(struct pp_hwmgr *hwmgr)
{
uint32_t reg;
reg = soc15_get_register_offset(THM_HWID, 0, mmTHM_THERMAL_INT_ENA_BASE_IDX, mmTHM_THERMAL_INT_ENA);
cgs_write_register(hwmgr->device, reg, 0);
return 0;
}
/**
* Uninitialize the thermal controller.
* Currently just disables alerts.
* @param hwmgr The address of the hardware manager.
*/
int vega12_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr)
{
int result = vega12_thermal_disable_alert(hwmgr);
return result;
}
/**
* Set up the fan table to control the fan using the SMC.
* @param hwmgr the address of the powerplay hardware manager.
* @param pInput the pointer to input data
* @param pOutput the pointer to output data
* @param pStorage the pointer to temporary storage
* @param Result the last failure code
* @return result from set temperature range routine
*/
int vega12_thermal_setup_fan_table(struct pp_hwmgr *hwmgr)
{
int ret;
struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
PPTable_t *table = &(data->smc_state_table.pp_table);
ret = smum_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_SetFanTemperatureTarget,
(uint32_t)table->FanTargetTemperature);
return ret;
}
/**
* Start the fan control on the SMC.
* @param hwmgr the address of the powerplay hardware manager.
* @param pInput the pointer to input data
* @param pOutput the pointer to output data
* @param pStorage the pointer to temporary storage
* @param Result the last failure code
* @return result from set temperature range routine
*/
int vega12_thermal_start_smc_fan_control(struct pp_hwmgr *hwmgr)
{
/* If the fantable setup has failed we could have disabled
* PHM_PlatformCaps_MicrocodeFanControl even after
* this function was included in the table.
* Make sure that we still think controlling the fan is OK.
*/
if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl))
vega12_fan_ctrl_start_smc_fan_control(hwmgr);
return 0;
}
int vega12_start_thermal_controller(struct pp_hwmgr *hwmgr,
struct PP_TemperatureRange *range)
{
int ret = 0;
if (range == NULL)
return -EINVAL;
ret = vega12_thermal_set_temperature_range(hwmgr, range);
if (ret)
return -EINVAL;
vega12_thermal_enable_alert(hwmgr);
/* We should restrict performance levels to low before we halt the SMC.
* On the other hand we are still in boot state when we do this
* so it would be pointless.
* If this assumption changes we have to revisit this table.
*/
ret = vega12_thermal_setup_fan_table(hwmgr);
if (ret)
return -EINVAL;
vega12_thermal_start_smc_fan_control(hwmgr);
return 0;
};

View File

@ -0,0 +1,66 @@
/*
* 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.
*
*/
#ifndef VEGA12_THERMAL_H
#define VEGA12_THERMAL_H
#include "hwmgr.h"
struct vega12_temperature {
uint16_t edge_temp;
uint16_t hot_spot_temp;
uint16_t hbm_temp;
uint16_t vr_soc_temp;
uint16_t vr_mem_temp;
uint16_t liquid1_temp;
uint16_t liquid2_temp;
uint16_t plx_temp;
};
#define VEGA12_THERMAL_HIGH_ALERT_MASK 0x1
#define VEGA12_THERMAL_LOW_ALERT_MASK 0x2
#define VEGA12_THERMAL_MINIMUM_TEMP_READING -256
#define VEGA12_THERMAL_MAXIMUM_TEMP_READING 255
#define VEGA12_THERMAL_MINIMUM_ALERT_TEMP 0
#define VEGA12_THERMAL_MAXIMUM_ALERT_TEMP 255
#define FDO_PWM_MODE_STATIC 1
#define FDO_PWM_MODE_STATIC_RPM 5
extern int vega12_thermal_get_temperature(struct pp_hwmgr *hwmgr);
extern int vega12_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr);
extern int vega12_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr,
struct phm_fan_speed_info *fan_speed_info);
extern int vega12_fan_ctrl_reset_fan_speed_to_default(struct pp_hwmgr *hwmgr);
extern int vega12_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr,
uint32_t *speed);
extern int vega12_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr);
extern int vega12_thermal_disable_alert(struct pp_hwmgr *hwmgr);
extern int vega12_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr);
extern int vega12_start_thermal_controller(struct pp_hwmgr *hwmgr,
struct PP_TemperatureRange *range);
#endif

View File

@ -232,6 +232,20 @@ enum phm_platform_caps {
PHM_PlatformCaps_UVDClientMCTuning,
PHM_PlatformCaps_ODNinACSupport,
PHM_PlatformCaps_ODNinDCSupport,
PHM_PlatformCaps_UMDPState,
PHM_PlatformCaps_AutoWattmanSupport,
PHM_PlatformCaps_AutoWattmanEnable_CCCState,
PHM_PlatformCaps_FreeSyncActive,
PHM_PlatformCaps_EnableShadowPstate,
PHM_PlatformCaps_customThermalManagement,
PHM_PlatformCaps_staticFanControl,
PHM_PlatformCaps_Virtual_System,
PHM_PlatformCaps_LowestUclkReservedForUlv,
PHM_PlatformCaps_EnableBoostState,
PHM_PlatformCaps_AVFSSupport,
PHM_PlatformCaps_ThermalPolicyDelay,
PHM_PlatformCaps_CustomFanControlSupport,
PHM_PlatformCaps_BAMACO,
PHM_PlatformCaps_Max
};
@ -403,7 +417,7 @@ extern int phm_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
extern int phm_force_dpm_levels(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_level level);
extern int phm_display_configuration_changed(struct pp_hwmgr *hwmgr);
extern int phm_notify_smc_display_config_after_ps_adjustment(struct pp_hwmgr *hwmgr);
extern int phm_register_thermal_interrupt(struct pp_hwmgr *hwmgr, const void *info);
extern int phm_register_irq_handlers(struct pp_hwmgr *hwmgr);
extern int phm_start_thermal_controller(struct pp_hwmgr *hwmgr);
extern int phm_stop_thermal_controller(struct pp_hwmgr *hwmgr);
extern bool phm_check_smc_update_required_for_display_configuration(struct pp_hwmgr *hwmgr);

View File

@ -39,9 +39,6 @@ struct pp_atomctrl_voltage_table;
#define VOLTAGE_SCALE 4
uint8_t convert_to_vid(uint16_t vddc);
uint16_t convert_to_vddc(uint8_t vid);
enum DISPLAY_GAP {
DISPLAY_GAP_VBLANK_OR_WM = 0, /* Wait for vblank or MCHG watermark. */
DISPLAY_GAP_VBLANK = 1, /* Wait for vblank. */
@ -287,8 +284,7 @@ struct pp_hwmgr_func {
int (*get_fan_speed_rpm)(struct pp_hwmgr *hwmgr, uint32_t *speed);
int (*reset_fan_speed_to_default)(struct pp_hwmgr *hwmgr);
int (*uninitialize_thermal_controller)(struct pp_hwmgr *hwmgr);
int (*register_internal_thermal_interrupt)(struct pp_hwmgr *hwmgr,
const void *thermal_interrupt_info);
int (*register_irq_handlers)(struct pp_hwmgr *hwmgr);
bool (*check_smc_update_required_for_display_configuration)(struct pp_hwmgr *hwmgr);
int (*check_states_equal)(struct pp_hwmgr *hwmgr,
const struct pp_hw_power_state *pstate1,
@ -585,6 +581,27 @@ struct phm_ppt_v2_information {
uint8_t uc_dcef_dpm_voltage_mode;
};
struct phm_ppt_v3_information
{
uint8_t uc_thermal_controller_type;
uint16_t us_small_power_limit1;
uint16_t us_small_power_limit2;
uint16_t us_boost_power_limit;
uint16_t us_od_turbo_power_limit;
uint16_t us_od_powersave_power_limit;
uint16_t us_software_shutdown_temp;
uint32_t *power_saving_clock_max;
uint32_t *power_saving_clock_min;
uint32_t *od_settings_max;
uint32_t *od_settings_min;
void *smc_pptable;
};
struct phm_dynamic_state_info {
struct phm_clock_voltage_dependency_table *vddc_dependency_on_sclk;
struct phm_clock_voltage_dependency_table *vddci_dependency_on_mclk;
@ -764,17 +781,12 @@ struct pp_hwmgr {
uint32_t workload_setting[Workload_Policy_Max];
};
struct cgs_irq_src_funcs {
cgs_irq_source_set_func_t set;
cgs_irq_handler_func_t handler;
};
extern int hwmgr_early_init(struct pp_hwmgr *hwmgr);
extern int hwmgr_hw_init(struct pp_hwmgr *hwmgr);
extern int hwmgr_hw_fini(struct pp_hwmgr *hwmgr);
extern int hwmgr_hw_suspend(struct pp_hwmgr *hwmgr);
extern int hwmgr_hw_resume(struct pp_hwmgr *hwmgr);
extern int hwmgr_handle_task(struct pp_hwmgr *hwmgr,
int hwmgr_early_init(struct pp_hwmgr *hwmgr);
int hwmgr_hw_init(struct pp_hwmgr *hwmgr);
int hwmgr_hw_fini(struct pp_hwmgr *hwmgr);
int hwmgr_hw_suspend(struct pp_hwmgr *hwmgr);
int hwmgr_hw_resume(struct pp_hwmgr *hwmgr);
int hwmgr_handle_task(struct pp_hwmgr *hwmgr,
enum amd_pp_task task_id,
enum amd_pm_state_type *user_state);

View File

@ -69,6 +69,14 @@ enum SMU_MAC_DEFINITION {
SMU_UVD_MCLK_HANDSHAKE_DISABLE,
};
enum SMU9_TABLE_ID {
PPTABLE = 0,
WMTABLE,
AVFSTABLE,
TOOLSTABLE,
AVFSFUSETABLE
};
enum SMU10_TABLE_ID {
SMU10_WMTABLE = 0,
SMU10_CLOCKTABLE,

View File

@ -0,0 +1,758 @@
/*
* 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.
*
*/
#ifndef VEGA12_SMU9_DRIVER_IF_H
#define VEGA12_SMU9_DRIVER_IF_H
/**** IMPORTANT ***
* SMU TEAM: Always increment the interface version if
* any structure is changed in this file
*/
#define SMU9_DRIVER_IF_VERSION 0x10
#define PPTABLE_V12_SMU_VERSION 1
#define NUM_GFXCLK_DPM_LEVELS 16
#define NUM_VCLK_DPM_LEVELS 8
#define NUM_DCLK_DPM_LEVELS 8
#define NUM_ECLK_DPM_LEVELS 8
#define NUM_MP0CLK_DPM_LEVELS 2
#define NUM_UCLK_DPM_LEVELS 4
#define NUM_SOCCLK_DPM_LEVELS 8
#define NUM_DCEFCLK_DPM_LEVELS 8
#define NUM_DISPCLK_DPM_LEVELS 8
#define NUM_PIXCLK_DPM_LEVELS 8
#define NUM_PHYCLK_DPM_LEVELS 8
#define NUM_LINK_LEVELS 2
#define MAX_GFXCLK_DPM_LEVEL (NUM_GFXCLK_DPM_LEVELS - 1)
#define MAX_VCLK_DPM_LEVEL (NUM_VCLK_DPM_LEVELS - 1)
#define MAX_DCLK_DPM_LEVEL (NUM_DCLK_DPM_LEVELS - 1)
#define MAX_ECLK_DPM_LEVEL (NUM_ECLK_DPM_LEVELS - 1)
#define MAX_MP0CLK_DPM_LEVEL (NUM_MP0CLK_DPM_LEVELS - 1)
#define MAX_UCLK_DPM_LEVEL (NUM_UCLK_DPM_LEVELS - 1)
#define MAX_SOCCLK_DPM_LEVEL (NUM_SOCCLK_DPM_LEVELS - 1)
#define MAX_DCEFCLK_DPM_LEVEL (NUM_DCEFCLK_DPM_LEVELS - 1)
#define MAX_DISPCLK_DPM_LEVEL (NUM_DISPCLK_DPM_LEVELS - 1)
#define MAX_PIXCLK_DPM_LEVEL (NUM_PIXCLK_DPM_LEVELS - 1)
#define MAX_PHYCLK_DPM_LEVEL (NUM_PHYCLK_DPM_LEVELS - 1)
#define MAX_LINK_LEVEL (NUM_LINK_LEVELS - 1)
#define PPSMC_GeminiModeNone 0
#define PPSMC_GeminiModeMaster 1
#define PPSMC_GeminiModeSlave 2
#define FEATURE_DPM_PREFETCHER_BIT 0
#define FEATURE_DPM_GFXCLK_BIT 1
#define FEATURE_DPM_UCLK_BIT 2
#define FEATURE_DPM_SOCCLK_BIT 3
#define FEATURE_DPM_UVD_BIT 4
#define FEATURE_DPM_VCE_BIT 5
#define FEATURE_ULV_BIT 6
#define FEATURE_DPM_MP0CLK_BIT 7
#define FEATURE_DPM_LINK_BIT 8
#define FEATURE_DPM_DCEFCLK_BIT 9
#define FEATURE_DS_GFXCLK_BIT 10
#define FEATURE_DS_SOCCLK_BIT 11
#define FEATURE_DS_LCLK_BIT 12
#define FEATURE_PPT_BIT 13
#define FEATURE_TDC_BIT 14
#define FEATURE_THERMAL_BIT 15
#define FEATURE_GFX_PER_CU_CG_BIT 16
#define FEATURE_RM_BIT 17
#define FEATURE_DS_DCEFCLK_BIT 18
#define FEATURE_ACDC_BIT 19
#define FEATURE_VR0HOT_BIT 20
#define FEATURE_VR1HOT_BIT 21
#define FEATURE_FW_CTF_BIT 22
#define FEATURE_LED_DISPLAY_BIT 23
#define FEATURE_FAN_CONTROL_BIT 24
#define FEATURE_GFX_EDC_BIT 25
#define FEATURE_GFXOFF_BIT 26
#define FEATURE_CG_BIT 27
#define FEATURE_ACG_BIT 28
#define FEATURE_SPARE_29_BIT 29
#define FEATURE_SPARE_30_BIT 30
#define FEATURE_SPARE_31_BIT 31
#define NUM_FEATURES 32
#define FEATURE_DPM_PREFETCHER_MASK (1 << FEATURE_DPM_PREFETCHER_BIT )
#define FEATURE_DPM_GFXCLK_MASK (1 << FEATURE_DPM_GFXCLK_BIT )
#define FEATURE_DPM_UCLK_MASK (1 << FEATURE_DPM_UCLK_BIT )
#define FEATURE_DPM_SOCCLK_MASK (1 << FEATURE_DPM_SOCCLK_BIT )
#define FEATURE_DPM_UVD_MASK (1 << FEATURE_DPM_UVD_BIT )
#define FEATURE_DPM_VCE_MASK (1 << FEATURE_DPM_VCE_BIT )
#define FEATURE_ULV_MASK (1 << FEATURE_ULV_BIT )
#define FEATURE_DPM_MP0CLK_MASK (1 << FEATURE_DPM_MP0CLK_BIT )
#define FEATURE_DPM_LINK_MASK (1 << FEATURE_DPM_LINK_BIT )
#define FEATURE_DPM_DCEFCLK_MASK (1 << FEATURE_DPM_DCEFCLK_BIT )
#define FEATURE_DS_GFXCLK_MASK (1 << FEATURE_DS_GFXCLK_BIT )
#define FEATURE_DS_SOCCLK_MASK (1 << FEATURE_DS_SOCCLK_BIT )
#define FEATURE_DS_LCLK_MASK (1 << FEATURE_DS_LCLK_BIT )
#define FEATURE_PPT_MASK (1 << FEATURE_PPT_BIT )
#define FEATURE_TDC_MASK (1 << FEATURE_TDC_BIT )
#define FEATURE_THERMAL_MASK (1 << FEATURE_THERMAL_BIT )
#define FEATURE_GFX_PER_CU_CG_MASK (1 << FEATURE_GFX_PER_CU_CG_BIT )
#define FEATURE_RM_MASK (1 << FEATURE_RM_BIT )
#define FEATURE_DS_DCEFCLK_MASK (1 << FEATURE_DS_DCEFCLK_BIT )
#define FEATURE_ACDC_MASK (1 << FEATURE_ACDC_BIT )
#define FEATURE_VR0HOT_MASK (1 << FEATURE_VR0HOT_BIT )
#define FEATURE_VR1HOT_MASK (1 << FEATURE_VR1HOT_BIT )
#define FEATURE_FW_CTF_MASK (1 << FEATURE_FW_CTF_BIT )
#define FEATURE_LED_DISPLAY_MASK (1 << FEATURE_LED_DISPLAY_BIT )
#define FEATURE_FAN_CONTROL_MASK (1 << FEATURE_FAN_CONTROL_BIT )
#define FEATURE_GFX_EDC_MASK (1 << FEATURE_GFX_EDC_BIT )
#define FEATURE_GFXOFF_MASK (1 << FEATURE_GFXOFF_BIT )
#define FEATURE_CG_MASK (1 << FEATURE_CG_BIT )
#define FEATURE_ACG_MASK (1 << FEATURE_ACG_BIT )
#define FEATURE_SPARE_29_MASK (1 << FEATURE_SPARE_29_BIT )
#define FEATURE_SPARE_30_MASK (1 << FEATURE_SPARE_30_BIT )
#define FEATURE_SPARE_31_MASK (1 << FEATURE_SPARE_31_BIT )
#define DPM_OVERRIDE_DISABLE_SOCCLK_PID 0x00000001
#define DPM_OVERRIDE_DISABLE_UCLK_PID 0x00000002
#define DPM_OVERRIDE_ENABLE_VOLT_LINK_UVD_SOCCLK 0x00000004
#define DPM_OVERRIDE_ENABLE_VOLT_LINK_UVD_UCLK 0x00000008
#define DPM_OVERRIDE_ENABLE_FREQ_LINK_VCLK_SOCCLK 0x00000010
#define DPM_OVERRIDE_ENABLE_FREQ_LINK_VCLK_UCLK 0x00000020
#define DPM_OVERRIDE_ENABLE_FREQ_LINK_DCLK_SOCCLK 0x00000040
#define DPM_OVERRIDE_ENABLE_FREQ_LINK_DCLK_UCLK 0x00000080
#define DPM_OVERRIDE_ENABLE_VOLT_LINK_VCE_SOCCLK 0x00000100
#define DPM_OVERRIDE_ENABLE_VOLT_LINK_VCE_UCLK 0x00000200
#define DPM_OVERRIDE_ENABLE_FREQ_LINK_ECLK_SOCCLK 0x00000400
#define DPM_OVERRIDE_ENABLE_FREQ_LINK_ECLK_UCLK 0x00000800
#define DPM_OVERRIDE_ENABLE_FREQ_LINK_GFXCLK_SOCCLK 0x00001000
#define DPM_OVERRIDE_ENABLE_FREQ_LINK_GFXCLK_UCLK 0x00002000
#define DPM_OVERRIDE_ENABLE_GFXOFF_GFXCLK_SWITCH 0x00004000
#define DPM_OVERRIDE_ENABLE_GFXOFF_SOCCLK_SWITCH 0x00008000
#define DPM_OVERRIDE_ENABLE_GFXOFF_UCLK_SWITCH 0x00010000
#define VR_MAPPING_VR_SELECT_MASK 0x01
#define VR_MAPPING_VR_SELECT_SHIFT 0x00
#define VR_MAPPING_PLANE_SELECT_MASK 0x02
#define VR_MAPPING_PLANE_SELECT_SHIFT 0x01
#define PSI_SEL_VR0_PLANE0_PSI0 0x01
#define PSI_SEL_VR0_PLANE0_PSI1 0x02
#define PSI_SEL_VR0_PLANE1_PSI0 0x04
#define PSI_SEL_VR0_PLANE1_PSI1 0x08
#define PSI_SEL_VR1_PLANE0_PSI0 0x10
#define PSI_SEL_VR1_PLANE0_PSI1 0x20
#define PSI_SEL_VR1_PLANE1_PSI0 0x40
#define PSI_SEL_VR1_PLANE1_PSI1 0x80
#define THROTTLER_STATUS_PADDING_BIT 0
#define THROTTLER_STATUS_TEMP_EDGE_BIT 1
#define THROTTLER_STATUS_TEMP_HOTSPOT_BIT 2
#define THROTTLER_STATUS_TEMP_HBM_BIT 3
#define THROTTLER_STATUS_TEMP_VR_GFX_BIT 4
#define THROTTLER_STATUS_TEMP_VR_MEM_BIT 5
#define THROTTLER_STATUS_TEMP_LIQUID_BIT 6
#define THROTTLER_STATUS_TEMP_PLX_BIT 7
#define THROTTLER_STATUS_TEMP_SKIN_BIT 8
#define THROTTLER_STATUS_TDC_GFX_BIT 9
#define THROTTLER_STATUS_TDC_SOC_BIT 10
#define THROTTLER_STATUS_PPT_BIT 11
#define THROTTLER_STATUS_FIT_BIT 12
#define THROTTLER_STATUS_PPM_BIT 13
#define TABLE_TRANSFER_OK 0x0
#define TABLE_TRANSFER_FAILED 0xFF
#define WORKLOAD_DEFAULT_BIT 0
#define WORKLOAD_PPLIB_FULL_SCREEN_3D_BIT 1
#define WORKLOAD_PPLIB_POWER_SAVING_BIT 2
#define WORKLOAD_PPLIB_VIDEO_BIT 3
#define WORKLOAD_PPLIB_VR_BIT 4
#define WORKLOAD_PPLIB_COMPUTE_BIT 5
#define WORKLOAD_PPLIB_CUSTOM_BIT 6
#define WORKLOAD_PPLIB_COUNT 7
typedef struct {
uint32_t a;
uint32_t b;
uint32_t c;
} QuadraticInt_t;
typedef struct {
uint32_t m;
uint32_t b;
} LinearInt_t;
typedef struct {
uint32_t a;
uint32_t b;
uint32_t c;
} DroopInt_t;
typedef enum {
PPCLK_GFXCLK,
PPCLK_VCLK,
PPCLK_DCLK,
PPCLK_ECLK,
PPCLK_SOCCLK,
PPCLK_UCLK,
PPCLK_DCEFCLK,
PPCLK_DISPCLK,
PPCLK_PIXCLK,
PPCLK_PHYCLK,
PPCLK_COUNT,
} PPCLK_e;
enum {
VOLTAGE_MODE_AVFS,
VOLTAGE_MODE_AVFS_SS,
VOLTAGE_MODE_SS,
VOLTAGE_MODE_COUNT,
};
typedef struct {
uint8_t VoltageMode;
uint8_t SnapToDiscrete;
uint8_t NumDiscreteLevels;
uint8_t padding;
LinearInt_t ConversionToAvfsClk;
QuadraticInt_t SsCurve;
} DpmDescriptor_t;
typedef struct {
uint32_t Version;
uint32_t FeaturesToRun[2];
uint16_t SocketPowerLimitAc0;
uint16_t SocketPowerLimitAc0Tau;
uint16_t SocketPowerLimitAc1;
uint16_t SocketPowerLimitAc1Tau;
uint16_t SocketPowerLimitAc2;
uint16_t SocketPowerLimitAc2Tau;
uint16_t SocketPowerLimitAc3;
uint16_t SocketPowerLimitAc3Tau;
uint16_t SocketPowerLimitDc;
uint16_t SocketPowerLimitDcTau;
uint16_t TdcLimitSoc;
uint16_t TdcLimitSocTau;
uint16_t TdcLimitGfx;
uint16_t TdcLimitGfxTau;
uint16_t TedgeLimit;
uint16_t ThotspotLimit;
uint16_t ThbmLimit;
uint16_t Tvr_gfxLimit;
uint16_t Tvr_memLimit;
uint16_t Tliquid1Limit;
uint16_t Tliquid2Limit;
uint16_t TplxLimit;
uint32_t FitLimit;
uint16_t PpmPowerLimit;
uint16_t PpmTemperatureThreshold;
uint8_t MemoryOnPackage;
uint8_t padding8_limits[3];
uint16_t UlvVoltageOffsetSoc;
uint16_t UlvVoltageOffsetGfx;
uint8_t UlvSmnclkDid;
uint8_t UlvMp1clkDid;
uint8_t UlvGfxclkBypass;
uint8_t Padding234;
uint16_t MinVoltageGfx;
uint16_t MinVoltageSoc;
uint16_t MaxVoltageGfx;
uint16_t MaxVoltageSoc;
uint16_t LoadLineResistance;
uint16_t LoadLine_padding;
DpmDescriptor_t DpmDescriptor[PPCLK_COUNT];
uint16_t FreqTableGfx [NUM_GFXCLK_DPM_LEVELS ];
uint16_t FreqTableVclk [NUM_VCLK_DPM_LEVELS ];
uint16_t FreqTableDclk [NUM_DCLK_DPM_LEVELS ];
uint16_t FreqTableEclk [NUM_ECLK_DPM_LEVELS ];
uint16_t FreqTableSocclk [NUM_SOCCLK_DPM_LEVELS ];
uint16_t FreqTableUclk [NUM_UCLK_DPM_LEVELS ];
uint16_t FreqTableDcefclk [NUM_DCEFCLK_DPM_LEVELS ];
uint16_t FreqTableDispclk [NUM_DISPCLK_DPM_LEVELS ];
uint16_t FreqTablePixclk [NUM_PIXCLK_DPM_LEVELS ];
uint16_t FreqTablePhyclk [NUM_PHYCLK_DPM_LEVELS ];
uint16_t DcModeMaxFreq [PPCLK_COUNT ];
uint16_t Mp0clkFreq [NUM_MP0CLK_DPM_LEVELS];
uint16_t Mp0DpmVoltage [NUM_MP0CLK_DPM_LEVELS];
uint16_t GfxclkFidle;
uint16_t GfxclkSlewRate;
uint16_t CksEnableFreq;
uint16_t Padding789;
QuadraticInt_t CksVoltageOffset;
uint16_t AcgThresholdFreqHigh;
uint16_t AcgThresholdFreqLow;
uint16_t GfxclkDsMaxFreq;
uint8_t Padding456[2];
uint8_t LowestUclkReservedForUlv;
uint8_t Padding8_Uclk[3];
uint8_t PcieGenSpeed[NUM_LINK_LEVELS];
uint8_t PcieLaneCount[NUM_LINK_LEVELS];
uint16_t LclkFreq[NUM_LINK_LEVELS];
uint16_t EnableTdpm;
uint16_t TdpmHighHystTemperature;
uint16_t TdpmLowHystTemperature;
uint16_t GfxclkFreqHighTempLimit;
uint16_t FanStopTemp;
uint16_t FanStartTemp;
uint16_t FanGainEdge;
uint16_t FanGainHotspot;
uint16_t FanGainLiquid;
uint16_t FanGainVrVddc;
uint16_t FanGainVrMvdd;
uint16_t FanGainPlx;
uint16_t FanGainHbm;
uint16_t FanPwmMin;
uint16_t FanAcousticLimitRpm;
uint16_t FanThrottlingRpm;
uint16_t FanMaximumRpm;
uint16_t FanTargetTemperature;
uint16_t FanTargetGfxclk;
uint8_t FanZeroRpmEnable;
uint8_t FanTachEdgePerRev;
int16_t FuzzyFan_ErrorSetDelta;
int16_t FuzzyFan_ErrorRateSetDelta;
int16_t FuzzyFan_PwmSetDelta;
uint16_t FuzzyFan_Reserved;
uint8_t OverrideAvfsGb;
uint8_t Padding8_Avfs[3];
QuadraticInt_t qAvfsGb;
DroopInt_t dBtcGbGfxCksOn;
DroopInt_t dBtcGbGfxCksOff;
DroopInt_t dBtcGbGfxAcg;
DroopInt_t dBtcGbSoc;
LinearInt_t qAgingGbGfx;
LinearInt_t qAgingGbSoc;
QuadraticInt_t qStaticVoltageOffsetGfx;
QuadraticInt_t qStaticVoltageOffsetSoc;
uint16_t DcTolGfx;
uint16_t DcTolSoc;
uint8_t DcBtcGfxEnabled;
uint8_t DcBtcSocEnabled;
uint8_t Padding8_GfxBtc[2];
uint16_t DcBtcGfxMin;
uint16_t DcBtcGfxMax;
uint16_t DcBtcSocMin;
uint16_t DcBtcSocMax;
uint32_t DebugOverrides;
QuadraticInt_t ReservedEquation0;
QuadraticInt_t ReservedEquation1;
QuadraticInt_t ReservedEquation2;
QuadraticInt_t ReservedEquation3;
uint32_t Reserved[15];
uint8_t Liquid1_I2C_address;
uint8_t Liquid2_I2C_address;
uint8_t Vr_I2C_address;
uint8_t Plx_I2C_address;
uint8_t Liquid_I2C_LineSCL;
uint8_t Liquid_I2C_LineSDA;
uint8_t Vr_I2C_LineSCL;
uint8_t Vr_I2C_LineSDA;
uint8_t Plx_I2C_LineSCL;
uint8_t Plx_I2C_LineSDA;
uint8_t VrSensorPresent;
uint8_t LiquidSensorPresent;
uint16_t MaxVoltageStepGfx;
uint16_t MaxVoltageStepSoc;
uint8_t VddGfxVrMapping;
uint8_t VddSocVrMapping;
uint8_t VddMem0VrMapping;
uint8_t VddMem1VrMapping;
uint8_t GfxUlvPhaseSheddingMask;
uint8_t SocUlvPhaseSheddingMask;
uint8_t ExternalSensorPresent;
uint8_t Padding8_V;
uint16_t GfxMaxCurrent;
int8_t GfxOffset;
uint8_t Padding_TelemetryGfx;
uint16_t SocMaxCurrent;
int8_t SocOffset;
uint8_t Padding_TelemetrySoc;
uint16_t Mem0MaxCurrent;
int8_t Mem0Offset;
uint8_t Padding_TelemetryMem0;
uint16_t Mem1MaxCurrent;
int8_t Mem1Offset;
uint8_t Padding_TelemetryMem1;
uint8_t AcDcGpio;
uint8_t AcDcPolarity;
uint8_t VR0HotGpio;
uint8_t VR0HotPolarity;
uint8_t VR1HotGpio;
uint8_t VR1HotPolarity;
uint8_t Padding1;
uint8_t Padding2;
uint8_t LedPin0;
uint8_t LedPin1;
uint8_t LedPin2;
uint8_t padding8_4;
uint8_t GfxclkSpreadEnabled;
uint8_t GfxclkSpreadPercent;
uint16_t GfxclkSpreadFreq;
uint8_t UclkSpreadEnabled;
uint8_t UclkSpreadPercent;
uint16_t UclkSpreadFreq;
uint8_t SocclkSpreadEnabled;
uint8_t SocclkSpreadPercent;
uint16_t SocclkSpreadFreq;
uint32_t BoardReserved[3];
uint32_t MmHubPadding[7];
} PPTable_t;
typedef struct {
uint16_t GfxclkAverageLpfTau;
uint16_t SocclkAverageLpfTau;
uint16_t UclkAverageLpfTau;
uint16_t GfxActivityLpfTau;
uint16_t UclkActivityLpfTau;
uint32_t MmHubPadding[7];
} DriverSmuConfig_t;
typedef struct {
uint16_t GfxclkFmin;
uint16_t GfxclkFmax;
uint16_t GfxclkFreq1;
uint16_t GfxclkOffsetVolt1;
uint16_t GfxclkFreq2;
uint16_t GfxclkOffsetVolt2;
uint16_t GfxclkFreq3;
uint16_t GfxclkOffsetVolt3;
uint16_t UclkFmax;
int16_t OverDrivePct;
uint16_t FanMaximumRpm;
uint16_t FanMinimumPwm;
uint16_t FanTargetTemperature;
uint16_t MaxOpTemp;
} OverDriveTable_t;
typedef struct {
uint16_t CurrClock[PPCLK_COUNT];
uint16_t AverageGfxclkFrequency;
uint16_t AverageSocclkFrequency;
uint16_t AverageUclkFrequency ;
uint16_t AverageGfxActivity ;
uint16_t AverageUclkActivity ;
uint8_t CurrSocVoltageOffset ;
uint8_t CurrGfxVoltageOffset ;
uint8_t CurrMemVidOffset ;
uint8_t Padding8 ;
uint16_t CurrSocketPower ;
uint16_t TemperatureEdge ;
uint16_t TemperatureHotspot ;
uint16_t TemperatureHBM ;
uint16_t TemperatureVrGfx ;
uint16_t TemperatureVrMem ;
uint16_t TemperatureLiquid ;
uint16_t TemperaturePlx ;
uint32_t ThrottlerStatus ;
uint8_t LinkDpmLevel;
uint8_t Padding[3];
uint32_t MmHubPadding[7];
} SmuMetrics_t;
typedef struct {
uint16_t MinClock;
uint16_t MaxClock;
uint16_t MinUclk;
uint16_t MaxUclk;
uint8_t WmSetting;
uint8_t Padding[3];
} WatermarkRowGeneric_t;
#define NUM_WM_RANGES 4
typedef enum {
WM_SOCCLK = 0,
WM_DCEFCLK,
WM_COUNT_PP,
} WM_CLOCK_e;
typedef struct {
WatermarkRowGeneric_t WatermarkRow[WM_COUNT_PP][NUM_WM_RANGES];
uint32_t MmHubPadding[7];
} Watermarks_t;
typedef struct {
uint16_t avgPsmCount[30];
uint16_t minPsmCount[30];
float avgPsmVoltage[30];
float minPsmVoltage[30];
uint32_t MmHubPadding[7];
} AvfsDebugTable_t;
typedef struct {
uint8_t AvfsEn;
uint8_t AvfsVersion;
uint8_t OverrideVFT;
uint8_t OverrideAvfsGb;
uint8_t OverrideTemperatures;
uint8_t OverrideVInversion;
uint8_t OverrideP2V;
uint8_t OverrideP2VCharzFreq;
int32_t VFT0_m1;
int32_t VFT0_m2;
int32_t VFT0_b;
int32_t VFT1_m1;
int32_t VFT1_m2;
int32_t VFT1_b;
int32_t VFT2_m1;
int32_t VFT2_m2;
int32_t VFT2_b;
int32_t AvfsGb0_m1;
int32_t AvfsGb0_m2;
int32_t AvfsGb0_b;
int32_t AcBtcGb_m1;
int32_t AcBtcGb_m2;
int32_t AcBtcGb_b;
uint32_t AvfsTempCold;
uint32_t AvfsTempMid;
uint32_t AvfsTempHot;
uint32_t GfxVInversion;
uint32_t SocVInversion;
int32_t P2V_m1;
int32_t P2V_m2;
int32_t P2V_b;
uint32_t P2VCharzFreq;
uint32_t EnabledAvfsModules;
uint32_t MmHubPadding[7];
} AvfsFuseOverride_t;
typedef struct {
uint8_t Gfx_ActiveHystLimit;
uint8_t Gfx_IdleHystLimit;
uint8_t Gfx_FPS;
uint8_t Gfx_MinActiveFreqType;
uint8_t Gfx_BoosterFreqType;
uint8_t Gfx_UseRlcBusy;
uint16_t Gfx_MinActiveFreq;
uint16_t Gfx_BoosterFreq;
uint16_t Gfx_PD_Data_time_constant;
uint32_t Gfx_PD_Data_limit_a;
uint32_t Gfx_PD_Data_limit_b;
uint32_t Gfx_PD_Data_limit_c;
uint32_t Gfx_PD_Data_error_coeff;
uint32_t Gfx_PD_Data_error_rate_coeff;
uint8_t Soc_ActiveHystLimit;
uint8_t Soc_IdleHystLimit;
uint8_t Soc_FPS;
uint8_t Soc_MinActiveFreqType;
uint8_t Soc_BoosterFreqType;
uint8_t Soc_UseRlcBusy;
uint16_t Soc_MinActiveFreq;
uint16_t Soc_BoosterFreq;
uint16_t Soc_PD_Data_time_constant;
uint32_t Soc_PD_Data_limit_a;
uint32_t Soc_PD_Data_limit_b;
uint32_t Soc_PD_Data_limit_c;
uint32_t Soc_PD_Data_error_coeff;
uint32_t Soc_PD_Data_error_rate_coeff;
uint8_t Mem_ActiveHystLimit;
uint8_t Mem_IdleHystLimit;
uint8_t Mem_FPS;
uint8_t Mem_MinActiveFreqType;
uint8_t Mem_BoosterFreqType;
uint8_t Mem_UseRlcBusy;
uint16_t Mem_MinActiveFreq;
uint16_t Mem_BoosterFreq;
uint16_t Mem_PD_Data_time_constant;
uint32_t Mem_PD_Data_limit_a;
uint32_t Mem_PD_Data_limit_b;
uint32_t Mem_PD_Data_limit_c;
uint32_t Mem_PD_Data_error_coeff;
uint32_t Mem_PD_Data_error_rate_coeff;
} DpmActivityMonitorCoeffInt_t;
#define TABLE_PPTABLE 0
#define TABLE_WATERMARKS 1
#define TABLE_AVFS 2
#define TABLE_AVFS_PSM_DEBUG 3
#define TABLE_AVFS_FUSE_OVERRIDE 4
#define TABLE_PMSTATUSLOG 5
#define TABLE_SMU_METRICS 6
#define TABLE_DRIVER_SMU_CONFIG 7
#define TABLE_ACTIVITY_MONITOR_COEFF 8
#define TABLE_OVERDRIVE 9
#define TABLE_COUNT 10
#define UCLK_SWITCH_SLOW 0
#define UCLK_SWITCH_FAST 1
#define SQ_Enable_MASK 0x1
#define SQ_IR_MASK 0x2
#define SQ_PCC_MASK 0x4
#define SQ_EDC_MASK 0x8
#define TCP_Enable_MASK 0x100
#define TCP_IR_MASK 0x200
#define TCP_PCC_MASK 0x400
#define TCP_EDC_MASK 0x800
#define TD_Enable_MASK 0x10000
#define TD_IR_MASK 0x20000
#define TD_PCC_MASK 0x40000
#define TD_EDC_MASK 0x80000
#define DB_Enable_MASK 0x1000000
#define DB_IR_MASK 0x2000000
#define DB_PCC_MASK 0x4000000
#define DB_EDC_MASK 0x8000000
#define SQ_Enable_SHIFT 0
#define SQ_IR_SHIFT 1
#define SQ_PCC_SHIFT 2
#define SQ_EDC_SHIFT 3
#define TCP_Enable_SHIFT 8
#define TCP_IR_SHIFT 9
#define TCP_PCC_SHIFT 10
#define TCP_EDC_SHIFT 11
#define TD_Enable_SHIFT 16
#define TD_IR_SHIFT 17
#define TD_PCC_SHIFT 18
#define TD_EDC_SHIFT 19
#define DB_Enable_SHIFT 24
#define DB_IR_SHIFT 25
#define DB_PCC_SHIFT 26
#define DB_EDC_SHIFT 27
#define REMOVE_FMAX_MARGIN_BIT 0x0
#define REMOVE_DCTOL_MARGIN_BIT 0x1
#define REMOVE_PLATFORM_MARGIN_BIT 0x2
#endif

View File

@ -0,0 +1,123 @@
/*
* 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.
*
*/
#ifndef VEGA12_PP_SMC_H
#define VEGA12_PP_SMC_H
#pragma pack(push, 1)
#define SMU_UCODE_VERSION 0x00270a00
/* SMU Response Codes: */
#define PPSMC_Result_OK 0x1
#define PPSMC_Result_Failed 0xFF
#define PPSMC_Result_UnknownCmd 0xFE
#define PPSMC_Result_CmdRejectedPrereq 0xFD
#define PPSMC_Result_CmdRejectedBusy 0xFC
#define PPSMC_MSG_TestMessage 0x1
#define PPSMC_MSG_GetSmuVersion 0x2
#define PPSMC_MSG_GetDriverIfVersion 0x3
#define PPSMC_MSG_SetAllowedFeaturesMaskLow 0x4
#define PPSMC_MSG_SetAllowedFeaturesMaskHigh 0x5
#define PPSMC_MSG_EnableAllSmuFeatures 0x6
#define PPSMC_MSG_DisableAllSmuFeatures 0x7
#define PPSMC_MSG_EnableSmuFeaturesLow 0x8
#define PPSMC_MSG_EnableSmuFeaturesHigh 0x9
#define PPSMC_MSG_DisableSmuFeaturesLow 0xA
#define PPSMC_MSG_DisableSmuFeaturesHigh 0xB
#define PPSMC_MSG_GetEnabledSmuFeaturesLow 0xC
#define PPSMC_MSG_GetEnabledSmuFeaturesHigh 0xD
#define PPSMC_MSG_SetWorkloadMask 0xE
#define PPSMC_MSG_SetPptLimit 0xF
#define PPSMC_MSG_SetDriverDramAddrHigh 0x10
#define PPSMC_MSG_SetDriverDramAddrLow 0x11
#define PPSMC_MSG_SetToolsDramAddrHigh 0x12
#define PPSMC_MSG_SetToolsDramAddrLow 0x13
#define PPSMC_MSG_TransferTableSmu2Dram 0x14
#define PPSMC_MSG_TransferTableDram2Smu 0x15
#define PPSMC_MSG_UseDefaultPPTable 0x16
#define PPSMC_MSG_UseBackupPPTable 0x17
#define PPSMC_MSG_RunBtc 0x18
#define PPSMC_MSG_RequestI2CBus 0x19
#define PPSMC_MSG_ReleaseI2CBus 0x1A
#define PPSMC_MSG_SetFloorSocVoltage 0x21
#define PPSMC_MSG_SoftReset 0x22
#define PPSMC_MSG_StartBacoMonitor 0x23
#define PPSMC_MSG_CancelBacoMonitor 0x24
#define PPSMC_MSG_EnterBaco 0x25
#define PPSMC_MSG_SetSoftMinByFreq 0x26
#define PPSMC_MSG_SetSoftMaxByFreq 0x27
#define PPSMC_MSG_SetHardMinByFreq 0x28
#define PPSMC_MSG_SetHardMaxByFreq 0x29
#define PPSMC_MSG_GetMinDpmFreq 0x2A
#define PPSMC_MSG_GetMaxDpmFreq 0x2B
#define PPSMC_MSG_GetDpmFreqByIndex 0x2C
#define PPSMC_MSG_GetDpmClockFreq 0x2D
#define PPSMC_MSG_GetSsVoltageByDpm 0x2E
#define PPSMC_MSG_SetMemoryChannelConfig 0x2F
#define PPSMC_MSG_SetGeminiMode 0x30
#define PPSMC_MSG_SetGeminiApertureHigh 0x31
#define PPSMC_MSG_SetGeminiApertureLow 0x32
#define PPSMC_MSG_SetMinLinkDpmByIndex 0x33
#define PPSMC_MSG_OverridePcieParameters 0x34
#define PPSMC_MSG_OverDriveSetPercentage 0x35
#define PPSMC_MSG_SetMinDeepSleepDcefclk 0x36
#define PPSMC_MSG_ReenableAcDcInterrupt 0x37
#define PPSMC_MSG_NotifyPowerSource 0x38
#define PPSMC_MSG_SetUclkFastSwitch 0x39
#define PPSMC_MSG_SetUclkDownHyst 0x3A
#define PPSMC_MSG_GfxDeviceDriverReset 0x3B
#define PPSMC_MSG_GetCurrentRpm 0x3C
#define PPSMC_MSG_SetVideoFps 0x3D
#define PPSMC_MSG_SetTjMax 0x3E
#define PPSMC_MSG_SetFanTemperatureTarget 0x3F
#define PPSMC_MSG_PrepareMp1ForUnload 0x40
#define PPSMC_MSG_DramLogSetDramAddrHigh 0x41
#define PPSMC_MSG_DramLogSetDramAddrLow 0x42
#define PPSMC_MSG_DramLogSetDramSize 0x43
#define PPSMC_MSG_SetFanMaxRpm 0x44
#define PPSMC_MSG_SetFanMinPwm 0x45
#define PPSMC_MSG_ConfigureGfxDidt 0x46
#define PPSMC_MSG_NumOfDisplays 0x47
#define PPSMC_MSG_RemoveMargins 0x48
#define PPSMC_MSG_ReadSerialNumTop32 0x49
#define PPSMC_MSG_ReadSerialNumBottom32 0x4A
#define PPSMC_MSG_SetSystemVirtualDramAddrHigh 0x4B
#define PPSMC_MSG_SetSystemVirtualDramAddrLow 0x4C
#define PPSMC_MSG_RunAcgBtc 0x4D
#define PPSMC_MSG_InitializeAcg 0x4E
#define PPSMC_MSG_EnableAcgBtcTestMode 0x4F
#define PPSMC_MSG_EnableAcgSpreadSpectrum 0x50
#define PPSMC_MSG_AllowGfxOff 0x51
#define PPSMC_MSG_DisallowGfxOff 0x52
#define PPSMC_MSG_GetPptLimit 0x53
#define PPSMC_MSG_GetDcModeMaxDpmFreq 0x54
#define PPSMC_Message_Count 0x56
typedef uint16_t PPSMC_Result;
typedef int PPSMC_Msg;
#pragma pack(pop)
#endif

View File

@ -25,7 +25,8 @@
SMU_MGR = smumgr.o smu8_smumgr.o tonga_smumgr.o fiji_smumgr.o \
polaris10_smumgr.o iceland_smumgr.o \
smu7_smumgr.o vega10_smumgr.o smu10_smumgr.o ci_smumgr.o
smu7_smumgr.o vega10_smumgr.o smu10_smumgr.o ci_smumgr.o \
vega12_smumgr.o
AMD_PP_SMUMGR = $(addprefix $(AMD_PP_PATH)/smumgr/,$(SMU_MGR))

View File

@ -2222,7 +2222,7 @@ static int ci_thermal_setup_fan_table(struct pp_hwmgr *hwmgr)
fan_table.TempRespLim = cpu_to_be16(5);
reference_clock = smu7_get_xclk(hwmgr);
reference_clock = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev);
fan_table.RefreshPeriod = cpu_to_be32((hwmgr->thermal_controller.advanceFanControlParameters.ulCycleDelay * reference_clock) / 1600);

View File

@ -263,6 +263,9 @@ static int fiji_setup_graphics_level_structure(struct pp_hwmgr *hwmgr)
static int fiji_avfs_event_mgr(struct pp_hwmgr *hwmgr)
{
if (!hwmgr->avfs_supported)
return 0;
PP_ASSERT_WITH_CODE(0 == fiji_setup_graphics_level_structure(hwmgr),
"[AVFS][fiji_avfs_event_mgr] Could not Copy Graphics Level"
" table over to SMU",
@ -2254,7 +2257,7 @@ static int fiji_thermal_setup_fan_table(struct pp_hwmgr *hwmgr)
fan_table.TempRespLim = cpu_to_be16(5);
reference_clock = smu7_get_xclk(hwmgr);
reference_clock = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev);
fan_table.RefreshPeriod = cpu_to_be32((hwmgr->
thermal_controller.advanceFanControlParameters.ulCycleDelay *

View File

@ -2158,7 +2158,7 @@ int iceland_thermal_setup_fan_table(struct pp_hwmgr *hwmgr)
fan_table.TempRespLim = cpu_to_be16(5);
reference_clock = smu7_get_xclk(hwmgr);
reference_clock = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev);
fan_table.RefreshPeriod = cpu_to_be32((hwmgr->thermal_controller.advanceFanControlParameters.ulCycleDelay * reference_clock) / 1600);

View File

@ -172,11 +172,13 @@ static int polaris10_setup_graphics_level_structure(struct pp_hwmgr *hwmgr)
}
static int
polaris10_avfs_event_mgr(struct pp_hwmgr *hwmgr)
static int polaris10_avfs_event_mgr(struct pp_hwmgr *hwmgr)
{
struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(hwmgr->smu_backend);
if (!hwmgr->avfs_supported)
return 0;
PP_ASSERT_WITH_CODE(0 == polaris10_setup_graphics_level_structure(hwmgr),
"[AVFS][Polaris10_AVFSEventMgr] Could not Copy Graphics Level table over to SMU",
return -EINVAL);
@ -811,7 +813,7 @@ static void polaris10_get_sclk_range_table(struct pp_hwmgr *hwmgr,
struct pp_atom_ctrl_sclk_range_table range_table_from_vbios = { { {0} } };
ref_clk = smu7_get_xclk(hwmgr);
ref_clk = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev);
if (0 == atomctrl_get_smc_sclk_range_table(hwmgr, &range_table_from_vbios)) {
for (i = 0; i < NUM_SCLK_RANGE; i++) {
@ -876,7 +878,7 @@ static int polaris10_calculate_sclk_params(struct pp_hwmgr *hwmgr,
return result;
}
ref_clock = smu7_get_xclk(hwmgr);
ref_clock = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev);
for (i = 0; i < NUM_SCLK_RANGE; i++) {
if (clock > smu_data->range_table[i].trans_lower_frequency
@ -2132,7 +2134,7 @@ static int polaris10_thermal_setup_fan_table(struct pp_hwmgr *hwmgr)
fan_table.TempRespLim = cpu_to_be16(5);
reference_clock = smu7_get_xclk(hwmgr);
reference_clock = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev);
fan_table.RefreshPeriod = cpu_to_be32((hwmgr->
thermal_controller.advanceFanControlParameters.ulCycleDelay *

View File

@ -52,7 +52,7 @@ static const enum smu8_scratch_entry firmware_list[] = {
SMU8_SCRATCH_ENTRY_UCODE_ID_RLC_G,
};
static int smu8_smum_get_argument(struct pp_hwmgr *hwmgr)
static int smu8_get_argument(struct pp_hwmgr *hwmgr)
{
if (hwmgr == NULL || hwmgr->device == NULL)
return -EINVAL;
@ -881,7 +881,7 @@ const struct pp_smumgr_func smu8_smu_funcs = {
.check_fw_load_finish = smu8_check_fw_load_finish,
.request_smu_load_fw = NULL,
.request_smu_load_specific_fw = NULL,
.get_argument = smu8_smum_get_argument,
.get_argument = smu8_get_argument,
.send_msg_to_smc = smu8_send_msg_to_smc,
.send_msg_to_smc_with_parameter = smu8_send_msg_to_smc_with_parameter,
.download_pptable_settings = smu8_download_pptable_settings,

View File

@ -43,6 +43,7 @@ MODULE_FIRMWARE("amdgpu/polaris11_k_smc.bin");
MODULE_FIRMWARE("amdgpu/polaris12_smc.bin");
MODULE_FIRMWARE("amdgpu/vega10_smc.bin");
MODULE_FIRMWARE("amdgpu/vega10_acg_smc.bin");
MODULE_FIRMWARE("amdgpu/vega12_smc.bin");
int smum_thermal_avfs_enable(struct pp_hwmgr *hwmgr)
{

View File

@ -2574,7 +2574,7 @@ static int tonga_thermal_setup_fan_table(struct pp_hwmgr *hwmgr)
fan_table.TempRespLim = cpu_to_be16(5);
reference_clock = smu7_get_xclk(hwmgr);
reference_clock = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev);
fan_table.RefreshPeriod = cpu_to_be32((hwmgr->thermal_controller.advanceFanControlParameters.ulCycleDelay * reference_clock) / 1600);

View File

@ -25,6 +25,7 @@
#include "vega10_inc.h"
#include "pp_soc15.h"
#include "vega10_smumgr.h"
#include "vega10_hwmgr.h"
#include "vega10_ppsmc.h"
#include "smu9_driver_if.h"
#include "ppatomctrl.h"
@ -101,7 +102,7 @@ static uint32_t vega10_wait_for_response(struct pp_hwmgr *hwmgr)
* @param msg the message to send.
* @return Always return 0.
*/
int vega10_send_msg_to_smc_without_waiting(struct pp_hwmgr *hwmgr,
static int vega10_send_msg_to_smc_without_waiting(struct pp_hwmgr *hwmgr,
uint16_t msg)
{
uint32_t reg;
@ -119,7 +120,7 @@ int vega10_send_msg_to_smc_without_waiting(struct pp_hwmgr *hwmgr,
* @param msg the message to send.
* @return Always return 0.
*/
int vega10_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg)
static int vega10_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg)
{
uint32_t reg;
uint32_t ret;
@ -146,7 +147,7 @@ int vega10_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg)
* @param parameter: the parameter to send
* @return Always return 0.
*/
int vega10_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr,
static int vega10_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr,
uint16_t msg, uint32_t parameter)
{
uint32_t reg;
@ -171,54 +172,20 @@ int vega10_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr,
return 0;
}
/*
* Send a message to the SMC with parameter, do not wait for response
* @param hwmgr: the address of the powerplay hardware manager.
* @param msg: the message to send.
* @param parameter: the parameter to send
* @return The response that came from the SMC.
*/
int vega10_send_msg_to_smc_with_parameter_without_waiting(
struct pp_hwmgr *hwmgr, uint16_t msg, uint32_t parameter)
{
uint32_t reg;
reg = soc15_get_register_offset(MP1_HWID, 0,
mmMP1_SMN_C2PMSG_82_BASE_IDX, mmMP1_SMN_C2PMSG_82);
cgs_write_register(hwmgr->device, reg, parameter);
return vega10_send_msg_to_smc_without_waiting(hwmgr, msg);
}
/*
* Retrieve an argument from SMC.
* @param hwmgr the address of the powerplay hardware manager.
* @param arg pointer to store the argument from SMC.
* @return Always return 0.
*/
int vega10_read_arg_from_smc(struct pp_hwmgr *hwmgr, uint32_t *arg)
static int vega10_get_argument(struct pp_hwmgr *hwmgr)
{
uint32_t reg;
reg = soc15_get_register_offset(MP1_HWID, 0,
mmMP1_SMN_C2PMSG_82_BASE_IDX, mmMP1_SMN_C2PMSG_82);
*arg = cgs_read_register(hwmgr->device, reg);
return 0;
return cgs_read_register(hwmgr->device, reg);
}
/*
* Copy table from SMC into driver FB
* @param hwmgr the address of the HW manager
* @param table_id the driver's table ID to copy from
*/
int vega10_copy_table_from_smc(struct pp_hwmgr *hwmgr,
static int vega10_copy_table_from_smc(struct pp_hwmgr *hwmgr,
uint8_t *table, int16_t table_id)
{
struct vega10_smumgr *priv =
(struct vega10_smumgr *)(hwmgr->smu_backend);
struct vega10_smumgr *priv = hwmgr->smu_backend;
PP_ASSERT_WITH_CODE(table_id < MAX_SMU_TABLE,
"Invalid SMU Table ID!", return -EINVAL);
@ -242,16 +209,10 @@ int vega10_copy_table_from_smc(struct pp_hwmgr *hwmgr,
return 0;
}
/*
* Copy table from Driver FB into SMC
* @param hwmgr the address of the HW manager
* @param table_id the table to copy from
*/
int vega10_copy_table_to_smc(struct pp_hwmgr *hwmgr,
static int vega10_copy_table_to_smc(struct pp_hwmgr *hwmgr,
uint8_t *table, int16_t table_id)
{
struct vega10_smumgr *priv =
(struct vega10_smumgr *)(hwmgr->smu_backend);
struct vega10_smumgr *priv = hwmgr->smu_backend;
PP_ASSERT_WITH_CODE(table_id < MAX_SMU_TABLE,
"Invalid SMU Table ID!", return -EINVAL);
@ -276,42 +237,15 @@ int vega10_copy_table_to_smc(struct pp_hwmgr *hwmgr,
return 0;
}
int vega10_save_vft_table(struct pp_hwmgr *hwmgr, uint8_t *avfs_table)
{
PP_ASSERT_WITH_CODE(avfs_table,
"No access to SMC AVFS Table",
return -EINVAL);
return vega10_copy_table_from_smc(hwmgr, avfs_table, AVFSTABLE);
}
int vega10_restore_vft_table(struct pp_hwmgr *hwmgr, uint8_t *avfs_table)
{
PP_ASSERT_WITH_CODE(avfs_table,
"No access to SMC AVFS Table",
return -EINVAL);
return vega10_copy_table_to_smc(hwmgr, avfs_table, AVFSTABLE);
}
int vega10_enable_smc_features(struct pp_hwmgr *hwmgr,
bool enable, uint32_t feature_mask)
{
int msg = enable ? PPSMC_MSG_EnableSmuFeatures :
PPSMC_MSG_DisableSmuFeatures;
return vega10_send_msg_to_smc_with_parameter(hwmgr,
msg, feature_mask);
}
int vega10_get_smc_features(struct pp_hwmgr *hwmgr,
static int vega10_get_smc_features(struct pp_hwmgr *hwmgr,
uint32_t *features_enabled)
{
if (features_enabled == NULL)
return -EINVAL;
vega10_send_msg_to_smc(hwmgr, PPSMC_MSG_GetEnabledSmuFeatures);
vega10_read_arg_from_smc(hwmgr, features_enabled);
*features_enabled = vega10_get_argument(hwmgr);
return 0;
}
@ -327,10 +261,9 @@ static bool vega10_is_dpm_running(struct pp_hwmgr *hwmgr)
return false;
}
int vega10_set_tools_address(struct pp_hwmgr *hwmgr)
static int vega10_set_tools_address(struct pp_hwmgr *hwmgr)
{
struct vega10_smumgr *priv =
(struct vega10_smumgr *)(hwmgr->smu_backend);
struct vega10_smumgr *priv = hwmgr->smu_backend;
if (priv->smu_tables.entry[TOOLSTABLE].mc_addr) {
vega10_send_msg_to_smc_with_parameter(hwmgr,
@ -354,7 +287,7 @@ static int vega10_verify_smc_interface(struct pp_hwmgr *hwmgr)
PPSMC_MSG_GetDriverIfVersion),
"Attempt to get SMC IF Version Number Failed!",
return -EINVAL);
vega10_read_arg_from_smc(hwmgr, &smc_driver_if_version);
smc_driver_if_version = vega10_get_argument(hwmgr);
dev_id = adev->pdev->device;
rev_id = adev->pdev->revision;
@ -499,8 +432,7 @@ free_backend:
static int vega10_smu_fini(struct pp_hwmgr *hwmgr)
{
struct vega10_smumgr *priv =
(struct vega10_smumgr *)(hwmgr->smu_backend);
struct vega10_smumgr *priv = hwmgr->smu_backend;
if (priv) {
amdgpu_bo_free_kernel(&priv->smu_tables.entry[PPTABLE].handle,
@ -539,6 +471,18 @@ static int vega10_start_smu(struct pp_hwmgr *hwmgr)
return 0;
}
static int vega10_smc_table_manager(struct pp_hwmgr *hwmgr, uint8_t *table, uint16_t table_id, bool rw)
{
int ret;
if (rw)
ret = vega10_copy_table_from_smc(hwmgr, table, table_id);
else
ret = vega10_copy_table_to_smc(hwmgr, table, table_id);
return ret;
}
const struct pp_smumgr_func vega10_smu_funcs = {
.smu_init = &vega10_smu_init,
.smu_fini = &vega10_smu_fini,
@ -549,4 +493,6 @@ const struct pp_smumgr_func vega10_smu_funcs = {
.download_pptable_settings = NULL,
.upload_pptable_settings = NULL,
.is_dpm_running = vega10_is_dpm_running,
.get_argument = vega10_get_argument,
.smc_table_manager = vega10_smc_table_manager,
};

View File

@ -23,16 +23,7 @@
#ifndef _VEGA10_SMUMANAGER_H_
#define _VEGA10_SMUMANAGER_H_
#include "vega10_hwmgr.h"
enum smu_table_id {
PPTABLE = 0,
WMTABLE,
AVFSTABLE,
TOOLSTABLE,
AVFSFUSETABLE,
MAX_SMU_TABLE,
};
#define MAX_SMU_TABLE 5
struct smu_table_entry {
uint32_t version;
@ -51,19 +42,6 @@ struct vega10_smumgr {
struct smu_table_array smu_tables;
};
int vega10_read_arg_from_smc(struct pp_hwmgr *hwmgr, uint32_t *arg);
int vega10_copy_table_from_smc(struct pp_hwmgr *hwmgr,
uint8_t *table, int16_t table_id);
int vega10_copy_table_to_smc(struct pp_hwmgr *hwmgr,
uint8_t *table, int16_t table_id);
int vega10_enable_smc_features(struct pp_hwmgr *hwmgr,
bool enable, uint32_t feature_mask);
int vega10_get_smc_features(struct pp_hwmgr *hwmgr,
uint32_t *features_enabled);
int vega10_save_vft_table(struct pp_hwmgr *hwmgr, uint8_t *avfs_table);
int vega10_restore_vft_table(struct pp_hwmgr *hwmgr, uint8_t *avfs_table);
int vega10_set_tools_address(struct pp_hwmgr *hwmgr);
#endif

View File

@ -0,0 +1,561 @@
/*
* Copyright 2017 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "smumgr.h"
#include "vega12_inc.h"
#include "pp_soc15.h"
#include "vega12_smumgr.h"
#include "vega12_ppsmc.h"
#include "vega12/smu9_driver_if.h"
#include "ppatomctrl.h"
#include "pp_debug.h"
#include "smu_ucode_xfer_vi.h"
#include "smu7_smumgr.h"
/* MP Apertures */
#define MP0_Public 0x03800000
#define MP0_SRAM 0x03900000
#define MP1_Public 0x03b00000
#define MP1_SRAM 0x03c00004
#define smnMP1_FIRMWARE_FLAGS 0x3010028
#define smnMP0_FW_INTF 0x3010104
#define smnMP1_PUB_CTRL 0x3010b14
static bool vega12_is_smc_ram_running(struct pp_hwmgr *hwmgr)
{
uint32_t mp1_fw_flags, reg;
reg = soc15_get_register_offset(NBIF_HWID, 0,
mmPCIE_INDEX2_BASE_IDX, mmPCIE_INDEX2);
cgs_write_register(hwmgr->device, reg,
(MP1_Public | (smnMP1_FIRMWARE_FLAGS & 0xffffffff)));
reg = soc15_get_register_offset(NBIF_HWID, 0,
mmPCIE_DATA2_BASE_IDX, mmPCIE_DATA2);
mp1_fw_flags = cgs_read_register(hwmgr->device, reg);
if ((mp1_fw_flags & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) >>
MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED__SHIFT)
return true;
return false;
}
/*
* Check if SMC has responded to previous message.
*
* @param smumgr the address of the powerplay hardware manager.
* @return TRUE SMC has responded, FALSE otherwise.
*/
static uint32_t vega12_wait_for_response(struct pp_hwmgr *hwmgr)
{
uint32_t reg;
reg = soc15_get_register_offset(MP1_HWID, 0,
mmMP1_SMN_C2PMSG_90_BASE_IDX, mmMP1_SMN_C2PMSG_90);
phm_wait_for_register_unequal(hwmgr, reg,
0, MP1_C2PMSG_90__CONTENT_MASK);
return cgs_read_register(hwmgr->device, reg);
}
/*
* Send a message to the SMC, and do not wait for its response.
* @param smumgr the address of the powerplay hardware manager.
* @param msg the message to send.
* @return Always return 0.
*/
int vega12_send_msg_to_smc_without_waiting(struct pp_hwmgr *hwmgr,
uint16_t msg)
{
uint32_t reg;
reg = soc15_get_register_offset(MP1_HWID, 0,
mmMP1_SMN_C2PMSG_66_BASE_IDX, mmMP1_SMN_C2PMSG_66);
cgs_write_register(hwmgr->device, reg, msg);
return 0;
}
/*
* Send a message to the SMC, and wait for its response.
* @param hwmgr the address of the powerplay hardware manager.
* @param msg the message to send.
* @return Always return 0.
*/
int vega12_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg)
{
uint32_t reg;
vega12_wait_for_response(hwmgr);
reg = soc15_get_register_offset(MP1_HWID, 0,
mmMP1_SMN_C2PMSG_90_BASE_IDX, mmMP1_SMN_C2PMSG_90);
cgs_write_register(hwmgr->device, reg, 0);
vega12_send_msg_to_smc_without_waiting(hwmgr, msg);
if (vega12_wait_for_response(hwmgr) != 1)
pr_err("Failed to send message: 0x%x\n", msg);
return 0;
}
/*
* Send a message to the SMC with parameter
* @param hwmgr: the address of the powerplay hardware manager.
* @param msg: the message to send.
* @param parameter: the parameter to send
* @return Always return 0.
*/
int vega12_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr,
uint16_t msg, uint32_t parameter)
{
uint32_t reg;
vega12_wait_for_response(hwmgr);
reg = soc15_get_register_offset(MP1_HWID, 0,
mmMP1_SMN_C2PMSG_90_BASE_IDX, mmMP1_SMN_C2PMSG_90);
cgs_write_register(hwmgr->device, reg, 0);
reg = soc15_get_register_offset(MP1_HWID, 0,
mmMP1_SMN_C2PMSG_82_BASE_IDX, mmMP1_SMN_C2PMSG_82);
cgs_write_register(hwmgr->device, reg, parameter);
vega12_send_msg_to_smc_without_waiting(hwmgr, msg);
if (vega12_wait_for_response(hwmgr) != 1)
pr_err("Failed to send message: 0x%x\n", msg);
return 0;
}
/*
* Send a message to the SMC with parameter, do not wait for response
* @param hwmgr: the address of the powerplay hardware manager.
* @param msg: the message to send.
* @param parameter: the parameter to send
* @return The response that came from the SMC.
*/
int vega12_send_msg_to_smc_with_parameter_without_waiting(
struct pp_hwmgr *hwmgr, uint16_t msg, uint32_t parameter)
{
uint32_t reg;
reg = soc15_get_register_offset(MP1_HWID, 0,
mmMP1_SMN_C2PMSG_66_BASE_IDX, mmMP1_SMN_C2PMSG_66);
cgs_write_register(hwmgr->device, reg, parameter);
return vega12_send_msg_to_smc_without_waiting(hwmgr, msg);
}
/*
* Retrieve an argument from SMC.
* @param hwmgr the address of the powerplay hardware manager.
* @param arg pointer to store the argument from SMC.
* @return Always return 0.
*/
int vega12_read_arg_from_smc(struct pp_hwmgr *hwmgr, uint32_t *arg)
{
uint32_t reg;
reg = soc15_get_register_offset(MP1_HWID, 0,
mmMP1_SMN_C2PMSG_82_BASE_IDX, mmMP1_SMN_C2PMSG_82);
*arg = cgs_read_register(hwmgr->device, reg);
return 0;
}
/*
* Copy table from SMC into driver FB
* @param hwmgr the address of the HW manager
* @param table_id the driver's table ID to copy from
*/
int vega12_copy_table_from_smc(struct pp_hwmgr *hwmgr,
uint8_t *table, int16_t table_id)
{
struct vega12_smumgr *priv =
(struct vega12_smumgr *)(hwmgr->smu_backend);
PP_ASSERT_WITH_CODE(table_id < TABLE_COUNT,
"Invalid SMU Table ID!", return -EINVAL);
PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].version != 0,
"Invalid SMU Table version!", return -EINVAL);
PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].size != 0,
"Invalid SMU Table Length!", return -EINVAL);
PP_ASSERT_WITH_CODE(vega12_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_SetDriverDramAddrHigh,
upper_32_bits(priv->smu_tables.entry[table_id].mc_addr)) == 0,
"[CopyTableFromSMC] Attempt to Set Dram Addr High Failed!", return -EINVAL);
PP_ASSERT_WITH_CODE(vega12_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_SetDriverDramAddrLow,
lower_32_bits(priv->smu_tables.entry[table_id].mc_addr)) == 0,
"[CopyTableFromSMC] Attempt to Set Dram Addr Low Failed!",
return -EINVAL);
PP_ASSERT_WITH_CODE(vega12_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_TransferTableSmu2Dram,
table_id) == 0,
"[CopyTableFromSMC] Attempt to Transfer Table From SMU Failed!",
return -EINVAL);
memcpy(table, priv->smu_tables.entry[table_id].table,
priv->smu_tables.entry[table_id].size);
return 0;
}
/*
* Copy table from Driver FB into SMC
* @param hwmgr the address of the HW manager
* @param table_id the table to copy from
*/
int vega12_copy_table_to_smc(struct pp_hwmgr *hwmgr,
uint8_t *table, int16_t table_id)
{
struct vega12_smumgr *priv =
(struct vega12_smumgr *)(hwmgr->smu_backend);
PP_ASSERT_WITH_CODE(table_id < TABLE_COUNT,
"Invalid SMU Table ID!", return -EINVAL);
PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].version != 0,
"Invalid SMU Table version!", return -EINVAL);
PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].size != 0,
"Invalid SMU Table Length!", return -EINVAL);
memcpy(priv->smu_tables.entry[table_id].table, table,
priv->smu_tables.entry[table_id].size);
PP_ASSERT_WITH_CODE(vega12_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_SetDriverDramAddrHigh,
upper_32_bits(priv->smu_tables.entry[table_id].mc_addr)) == 0,
"[CopyTableToSMC] Attempt to Set Dram Addr High Failed!",
return -EINVAL;);
PP_ASSERT_WITH_CODE(vega12_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_SetDriverDramAddrLow,
lower_32_bits(priv->smu_tables.entry[table_id].mc_addr)) == 0,
"[CopyTableToSMC] Attempt to Set Dram Addr Low Failed!",
return -EINVAL);
PP_ASSERT_WITH_CODE(vega12_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_TransferTableDram2Smu,
table_id) == 0,
"[CopyTableToSMC] Attempt to Transfer Table To SMU Failed!",
return -EINVAL);
return 0;
}
int vega12_enable_smc_features(struct pp_hwmgr *hwmgr,
bool enable, uint64_t feature_mask)
{
uint32_t smu_features_low, smu_features_high;
smu_features_low = (uint32_t)((feature_mask & SMU_FEATURES_LOW_MASK) >> SMU_FEATURES_LOW_SHIFT);
smu_features_high = (uint32_t)((feature_mask & SMU_FEATURES_HIGH_MASK) >> SMU_FEATURES_HIGH_SHIFT);
if (enable) {
PP_ASSERT_WITH_CODE(vega12_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_EnableSmuFeaturesLow, smu_features_low) == 0,
"[EnableDisableSMCFeatures] Attemp to enable SMU features Low failed!",
return -EINVAL);
PP_ASSERT_WITH_CODE(vega12_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_EnableSmuFeaturesHigh, smu_features_high) == 0,
"[EnableDisableSMCFeatures] Attemp to enable SMU features High failed!",
return -EINVAL);
} else {
PP_ASSERT_WITH_CODE(vega12_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_DisableSmuFeaturesLow, smu_features_low) == 0,
"[EnableDisableSMCFeatures] Attemp to disable SMU features Low failed!",
return -EINVAL);
PP_ASSERT_WITH_CODE(vega12_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_DisableSmuFeaturesHigh, smu_features_high) == 0,
"[EnableDisableSMCFeatures] Attemp to disable SMU features High failed!",
return -EINVAL);
}
return 0;
}
int vega12_get_enabled_smc_features(struct pp_hwmgr *hwmgr,
uint64_t *features_enabled)
{
uint32_t smc_features_low, smc_features_high;
if (features_enabled == NULL)
return -EINVAL;
PP_ASSERT_WITH_CODE(vega12_send_msg_to_smc(hwmgr,
PPSMC_MSG_GetEnabledSmuFeaturesLow) == 0,
"[GetEnabledSMCFeatures] Attemp to get SMU features Low failed!",
return -EINVAL);
PP_ASSERT_WITH_CODE(vega12_read_arg_from_smc(hwmgr,
&smc_features_low) == 0,
"[GetEnabledSMCFeatures] Attemp to read SMU features Low argument failed!",
return -EINVAL);
PP_ASSERT_WITH_CODE(vega12_send_msg_to_smc(hwmgr,
PPSMC_MSG_GetEnabledSmuFeaturesHigh) == 0,
"[GetEnabledSMCFeatures] Attemp to get SMU features High failed!",
return -EINVAL);
PP_ASSERT_WITH_CODE(vega12_read_arg_from_smc(hwmgr,
&smc_features_high) == 0,
"[GetEnabledSMCFeatures] Attemp to read SMU features High argument failed!",
return -EINVAL);
*features_enabled = ((((uint64_t)smc_features_low << SMU_FEATURES_LOW_SHIFT) & SMU_FEATURES_LOW_MASK) |
(((uint64_t)smc_features_high << SMU_FEATURES_HIGH_SHIFT) & SMU_FEATURES_HIGH_MASK));
return 0;
}
static bool vega12_is_dpm_running(struct pp_hwmgr *hwmgr)
{
uint64_t features_enabled = 0;
vega12_get_enabled_smc_features(hwmgr, &features_enabled);
if (features_enabled & SMC_DPM_FEATURES)
return true;
else
return false;
}
static int vega12_set_tools_address(struct pp_hwmgr *hwmgr)
{
struct vega12_smumgr *priv =
(struct vega12_smumgr *)(hwmgr->smu_backend);
if (priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr) {
if (!vega12_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_SetToolsDramAddrHigh,
upper_32_bits(priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr)))
vega12_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_SetToolsDramAddrLow,
lower_32_bits(priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr));
}
return 0;
}
#if 0 /* tentatively remove */
static int vega12_verify_smc_interface(struct pp_hwmgr *hwmgr)
{
uint32_t smc_driver_if_version;
PP_ASSERT_WITH_CODE(!vega12_send_msg_to_smc(hwmgr,
PPSMC_MSG_GetDriverIfVersion),
"Attempt to get SMC IF Version Number Failed!",
return -EINVAL);
vega12_read_arg_from_smc(hwmgr, &smc_driver_if_version);
if (smc_driver_if_version != SMU9_DRIVER_IF_VERSION) {
pr_err("Your firmware(0x%x) doesn't match \
SMU9_DRIVER_IF_VERSION(0x%x). \
Please update your firmware!\n",
smc_driver_if_version, SMU9_DRIVER_IF_VERSION);
return -EINVAL;
}
return 0;
}
#endif
static int vega12_smu_init(struct pp_hwmgr *hwmgr)
{
struct vega12_smumgr *priv;
unsigned long tools_size;
struct cgs_firmware_info info = {0};
int ret;
ret = cgs_get_firmware_info(hwmgr->device,
smu7_convert_fw_type_to_cgs(UCODE_ID_SMU),
&info);
if (ret || !info.kptr)
return -EINVAL;
priv = kzalloc(sizeof(struct vega12_smumgr), GFP_KERNEL);
if (!priv)
return -ENOMEM;
hwmgr->smu_backend = priv;
/* allocate space for pptable */
ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
sizeof(PPTable_t),
PAGE_SIZE,
AMDGPU_GEM_DOMAIN_VRAM,
&priv->smu_tables.entry[TABLE_PPTABLE].handle,
&priv->smu_tables.entry[TABLE_PPTABLE].mc_addr,
&priv->smu_tables.entry[TABLE_PPTABLE].table);
if (ret)
goto free_backend;
priv->smu_tables.entry[TABLE_PPTABLE].version = 0x01;
priv->smu_tables.entry[TABLE_PPTABLE].size = sizeof(PPTable_t);
/* allocate space for watermarks table */
ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
sizeof(Watermarks_t),
PAGE_SIZE,
AMDGPU_GEM_DOMAIN_VRAM,
&priv->smu_tables.entry[TABLE_WATERMARKS].handle,
&priv->smu_tables.entry[TABLE_WATERMARKS].mc_addr,
&priv->smu_tables.entry[TABLE_WATERMARKS].table);
if (ret)
goto err0;
priv->smu_tables.entry[TABLE_WATERMARKS].version = 0x01;
priv->smu_tables.entry[TABLE_WATERMARKS].size = sizeof(Watermarks_t);
tools_size = 0x19000;
if (tools_size) {
ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
tools_size,
PAGE_SIZE,
AMDGPU_GEM_DOMAIN_VRAM,
&priv->smu_tables.entry[TABLE_PMSTATUSLOG].handle,
&priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr,
&priv->smu_tables.entry[TABLE_PMSTATUSLOG].table);
if (ret)
goto err1;
priv->smu_tables.entry[TABLE_PMSTATUSLOG].version = 0x01;
priv->smu_tables.entry[TABLE_PMSTATUSLOG].size = tools_size;
}
/* allocate space for AVFS Fuse table */
ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
sizeof(AvfsFuseOverride_t),
PAGE_SIZE,
AMDGPU_GEM_DOMAIN_VRAM,
&priv->smu_tables.entry[TABLE_AVFS_FUSE_OVERRIDE].handle,
&priv->smu_tables.entry[TABLE_AVFS_FUSE_OVERRIDE].mc_addr,
&priv->smu_tables.entry[TABLE_AVFS_FUSE_OVERRIDE].table);
if (ret)
goto err2;
priv->smu_tables.entry[TABLE_AVFS_FUSE_OVERRIDE].version = 0x01;
priv->smu_tables.entry[TABLE_AVFS_FUSE_OVERRIDE].size = sizeof(AvfsFuseOverride_t);
/* allocate space for OverDrive table */
ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
sizeof(OverDriveTable_t),
PAGE_SIZE,
AMDGPU_GEM_DOMAIN_VRAM,
&priv->smu_tables.entry[TABLE_OVERDRIVE].handle,
&priv->smu_tables.entry[TABLE_OVERDRIVE].mc_addr,
&priv->smu_tables.entry[TABLE_OVERDRIVE].table);
if (ret)
goto err3;
priv->smu_tables.entry[TABLE_OVERDRIVE].version = 0x01;
priv->smu_tables.entry[TABLE_OVERDRIVE].size = sizeof(OverDriveTable_t);
return 0;
err3:
amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_AVFS_FUSE_OVERRIDE].handle,
&priv->smu_tables.entry[TABLE_AVFS_FUSE_OVERRIDE].mc_addr,
&priv->smu_tables.entry[TABLE_AVFS_FUSE_OVERRIDE].table);
err2:
if (priv->smu_tables.entry[TABLE_PMSTATUSLOG].table)
amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_PMSTATUSLOG].handle,
&priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr,
&priv->smu_tables.entry[TABLE_PMSTATUSLOG].table);
err1:
amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_WATERMARKS].handle,
&priv->smu_tables.entry[TABLE_WATERMARKS].mc_addr,
&priv->smu_tables.entry[TABLE_WATERMARKS].table);
err0:
amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_PPTABLE].handle,
&priv->smu_tables.entry[TABLE_PPTABLE].mc_addr,
&priv->smu_tables.entry[TABLE_PPTABLE].table);
free_backend:
kfree(hwmgr->smu_backend);
return -EINVAL;
}
static int vega12_smu_fini(struct pp_hwmgr *hwmgr)
{
struct vega12_smumgr *priv =
(struct vega12_smumgr *)(hwmgr->smu_backend);
if (priv) {
amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_PPTABLE].handle,
&priv->smu_tables.entry[TABLE_PPTABLE].mc_addr,
&priv->smu_tables.entry[TABLE_PPTABLE].table);
amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_WATERMARKS].handle,
&priv->smu_tables.entry[TABLE_WATERMARKS].mc_addr,
&priv->smu_tables.entry[TABLE_WATERMARKS].table);
if (priv->smu_tables.entry[TABLE_PMSTATUSLOG].table)
amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_PMSTATUSLOG].handle,
&priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr,
&priv->smu_tables.entry[TABLE_PMSTATUSLOG].table);
amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_AVFS_FUSE_OVERRIDE].handle,
&priv->smu_tables.entry[TABLE_AVFS_FUSE_OVERRIDE].mc_addr,
&priv->smu_tables.entry[TABLE_AVFS_FUSE_OVERRIDE].table);
amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_OVERDRIVE].handle,
&priv->smu_tables.entry[TABLE_OVERDRIVE].mc_addr,
&priv->smu_tables.entry[TABLE_OVERDRIVE].table);
kfree(hwmgr->smu_backend);
hwmgr->smu_backend = NULL;
}
return 0;
}
static int vega12_start_smu(struct pp_hwmgr *hwmgr)
{
PP_ASSERT_WITH_CODE(vega12_is_smc_ram_running(hwmgr),
"SMC is not running!",
return -EINVAL);
#if 0 /* tentatively remove */
PP_ASSERT_WITH_CODE(!vega12_verify_smc_interface(hwmgr),
"Failed to verify SMC interface!",
return -EINVAL);
#endif
vega12_set_tools_address(hwmgr);
return 0;
}
const struct pp_smumgr_func vega12_smu_funcs = {
.smu_init = &vega12_smu_init,
.smu_fini = &vega12_smu_fini,
.start_smu = &vega12_start_smu,
.request_smu_load_specific_fw = NULL,
.send_msg_to_smc = &vega12_send_msg_to_smc,
.send_msg_to_smc_with_parameter = &vega12_send_msg_to_smc_with_parameter,
.download_pptable_settings = NULL,
.upload_pptable_settings = NULL,
.is_dpm_running = vega12_is_dpm_running,
};

View File

@ -0,0 +1,62 @@
/*
* 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.
*
*/
#ifndef _VEGA12_SMUMANAGER_H_
#define _VEGA12_SMUMANAGER_H_
#include "hwmgr.h"
#include "vega12/smu9_driver_if.h"
#include "vega12_hwmgr.h"
struct smu_table_entry {
uint32_t version;
uint32_t size;
uint64_t mc_addr;
void *table;
struct amdgpu_bo *handle;
};
struct smu_table_array {
struct smu_table_entry entry[TABLE_COUNT];
};
struct vega12_smumgr {
struct smu_table_array smu_tables;
};
#define SMU_FEATURES_LOW_MASK 0x00000000FFFFFFFF
#define SMU_FEATURES_LOW_SHIFT 0
#define SMU_FEATURES_HIGH_MASK 0xFFFFFFFF00000000
#define SMU_FEATURES_HIGH_SHIFT 32
int vega12_read_arg_from_smc(struct pp_hwmgr *hwmgr, uint32_t *arg);
int vega12_copy_table_from_smc(struct pp_hwmgr *hwmgr,
uint8_t *table, int16_t table_id);
int vega12_copy_table_to_smc(struct pp_hwmgr *hwmgr,
uint8_t *table, int16_t table_id);
int vega12_enable_smc_features(struct pp_hwmgr *hwmgr,
bool enable, uint64_t feature_mask);
int vega12_get_enabled_smc_features(struct pp_hwmgr *hwmgr,
uint64_t *features_enabled);
#endif

View File

@ -45,6 +45,7 @@ enum amd_asic_type {
CHIP_POLARIS11,
CHIP_POLARIS12,
CHIP_VEGA10,
CHIP_VEGA12,
CHIP_RAVEN,
CHIP_LAST,
};

View File

@ -618,6 +618,8 @@ struct drm_amdgpu_cs_chunk_data {
#define AMDGPU_INFO_FW_SOS 0x0c
/* Subquery id: Query PSP ASD firmware version */
#define AMDGPU_INFO_FW_ASD 0x0d
/* Subquery id: Query VCN firmware version */
#define AMDGPU_INFO_FW_VCN 0x0e
/* number of bytes moved for TTM migration */
#define AMDGPU_INFO_NUM_BYTES_MOVED 0x0f
/* the used VRAM size */