提交 aaa36a97 编写于 作者: A Alex Deucher

drm/amdgpu: Add initial VI support

This adds initial support for VI asics.  This
includes Iceland, Tonga, and Carrizo.  Our inital
focus as been Carrizo, so there are still gaps in
support for Tonga and Iceland, notably power
management.
Acked-by: NChristian König <christian.koenig@amd.com>
Acked-by: NJammy Zhou <Jammy.Zhou@amd.com>
Signed-off-by: NAlex Deucher <alexander.deucher@amd.com>
上级 a2e73f56
......@@ -18,29 +18,57 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \
amdgpu_prime.o amdgpu_vm.o amdgpu_ib.o amdgpu_pll.o \
amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o
# add asic specific block
amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o gmc_v7_0.o cik_ih.o kv_smc.o kv_dpm.o \
ci_smc.o ci_dpm.o dce_v8_0.o gfx_v7_0.o cik_sdma.o uvd_v4_2.o vce_v2_0.o
amdgpu-y += \
vi.o
# add GMC block
amdgpu-y += \
gmc_v8_0.o
# add IH block
amdgpu-y += \
amdgpu_irq.o \
amdgpu_ih.o
amdgpu_ih.o \
iceland_ih.o \
tonga_ih.o \
cz_ih.o
# add SMC block
amdgpu-y += \
amdgpu_dpm.o
amdgpu_dpm.o \
cz_smc.o cz_dpm.o \
tonga_smc.o tonga_dpm.o \
iceland_smc.o iceland_dpm.o
# add DCE block
amdgpu-y += \
dce_v10_0.o \
dce_v11_0.o
# add GFX block
amdgpu-y += \
amdgpu_gfx.o
amdgpu_gfx.o \
gfx_v8_0.o
# add async DMA block
amdgpu-y += \
sdma_v2_4.o \
sdma_v3_0.o
# add UVD block
amdgpu-y += \
amdgpu_uvd.o
amdgpu_uvd.o \
uvd_v5_0.o \
uvd_v6_0.o
# add VCE block
amdgpu-y += \
amdgpu_vce.o
amdgpu_vce.o \
vce_v3_0.o
amdgpu-$(CONFIG_COMPAT) += amdgpu_ioc32.o
amdgpu-$(CONFIG_VGA_SWITCHEROO) += amdgpu_atpx_handler.o
......
......@@ -41,6 +41,7 @@
#ifdef CONFIG_DRM_AMDGPU_CIK
#include "cik.h"
#endif
#include "vi.h"
#include "bif/bif_4_1_d.h"
static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev);
......@@ -1154,9 +1155,21 @@ int amdgpu_ip_block_version_cmp(struct amdgpu_device *adev,
static int amdgpu_early_init(struct amdgpu_device *adev)
{
int i, r = -EINVAL;
int i, r;
switch (adev->asic_type) {
case CHIP_TOPAZ:
case CHIP_TONGA:
case CHIP_CARRIZO:
if (adev->asic_type == CHIP_CARRIZO)
adev->family = AMDGPU_FAMILY_CZ;
else
adev->family = AMDGPU_FAMILY_VI;
r = vi_set_ip_blocks(adev);
if (r)
return r;
break;
#ifdef CONFIG_DRM_AMDGPU_CIK
case CHIP_BONAIRE:
case CHIP_HAWAII:
......
此差异已折叠。
此差异已折叠。
/*
* Copyright 2014 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 __CZ_DPM_H__
#define __CZ_DPM_H__
#include "smu8_fusion.h"
#define CZ_AT_DFLT 30
#define CZ_NUM_NBPSTATES 4
#define CZ_NUM_NBPMEMORY_CLOCK 2
#define CZ_MAX_HARDWARE_POWERLEVELS 8
#define CZ_MAX_DISPLAY_CLOCK_LEVEL 8
#define CZ_MAX_DISPLAYPHY_IDS 10
#define PPCZ_VOTINGRIGHTSCLIENTS_DFLT0 0x3FFFC102
#define SMC_RAM_END 0x40000
#define DPMFlags_SCLK_Enabled 0x00000001
#define DPMFlags_UVD_Enabled 0x00000002
#define DPMFlags_VCE_Enabled 0x00000004
#define DPMFlags_ACP_Enabled 0x00000008
#define DPMFlags_ForceHighestValid 0x40000000
#define DPMFlags_Debug 0x80000000
/* Do not change the following, it is also defined in SMU8.h */
#define SMU_EnabledFeatureScoreboard_AcpDpmOn 0x00000001
#define SMU_EnabledFeatureScoreboard_SclkDpmOn 0x00100000
#define SMU_EnabledFeatureScoreboard_UvdDpmOn 0x00800000
#define SMU_EnabledFeatureScoreboard_VceDpmOn 0x01000000
/* temporary solution to SetMinDeepSleepSclk
* should indicate by display adaptor
* 10k Hz unit*/
#define CZ_MIN_DEEP_SLEEP_SCLK 800
enum cz_pt_config_reg_type {
CZ_CONFIGREG_MMR = 0,
CZ_CONFIGREG_SMC_IND,
CZ_CONFIGREG_DIDT_IND,
CZ_CONFIGREG_CACHE,
CZ_CONFIGREG_MAX
};
struct cz_pt_config_reg {
uint32_t offset;
uint32_t mask;
uint32_t shift;
uint32_t value;
enum cz_pt_config_reg_type type;
};
struct cz_dpm_entry {
uint32_t soft_min_clk;
uint32_t hard_min_clk;
uint32_t soft_max_clk;
uint32_t hard_max_clk;
};
struct cz_pl {
uint32_t sclk;
uint8_t vddc_index;
uint8_t ds_divider_index;
uint8_t ss_divider_index;
uint8_t allow_gnb_slow;
uint8_t force_nbp_state;
uint8_t display_wm;
uint8_t vce_wm;
};
struct cz_ps {
struct cz_pl levels[CZ_MAX_HARDWARE_POWERLEVELS];
uint32_t num_levels;
bool need_dfs_bypass;
uint8_t dpm0_pg_nb_ps_lo;
uint8_t dpm0_pg_nb_ps_hi;
uint8_t dpmx_nb_ps_lo;
uint8_t dpmx_nb_ps_hi;
bool force_high;
};
struct cz_displayphy_entry {
uint8_t phy_present;
uint8_t active_lane_mapping;
uint8_t display_conf_type;
uint8_t num_active_lanes;
};
struct cz_displayphy_info {
bool phy_access_initialized;
struct cz_displayphy_entry entries[CZ_MAX_DISPLAYPHY_IDS];
};
struct cz_sys_info {
uint32_t bootup_uma_clk;
uint32_t bootup_sclk;
uint32_t dentist_vco_freq;
uint32_t nb_dpm_enable;
uint32_t nbp_memory_clock[CZ_NUM_NBPMEMORY_CLOCK];
uint32_t nbp_n_clock[CZ_NUM_NBPSTATES];
uint8_t nbp_voltage_index[CZ_NUM_NBPSTATES];
uint32_t display_clock[CZ_MAX_DISPLAY_CLOCK_LEVEL];
uint16_t bootup_nb_voltage_index;
uint8_t htc_tmp_lmt;
uint8_t htc_hyst_lmt;
uint32_t uma_channel_number;
};
struct cz_power_info {
uint32_t active_target[CZ_MAX_HARDWARE_POWERLEVELS];
struct cz_sys_info sys_info;
struct cz_pl boot_pl;
bool disable_nb_ps3_in_battery;
bool battery_state;
uint32_t lowest_valid;
uint32_t highest_valid;
uint16_t high_voltage_threshold;
/* smc offsets */
uint32_t sram_end;
uint32_t dpm_table_start;
uint32_t soft_regs_start;
/* dpm SMU tables */
uint8_t uvd_level_count;
uint8_t vce_level_count;
uint8_t acp_level_count;
uint32_t fps_high_threshold;
uint32_t fps_low_threshold;
/* dpm table */
uint32_t dpm_flags;
struct cz_dpm_entry sclk_dpm;
struct cz_dpm_entry uvd_dpm;
struct cz_dpm_entry vce_dpm;
struct cz_dpm_entry acp_dpm;
uint8_t uvd_boot_level;
uint8_t uvd_interval;
uint8_t vce_boot_level;
uint8_t vce_interval;
uint8_t acp_boot_level;
uint8_t acp_interval;
uint8_t graphics_boot_level;
uint8_t graphics_interval;
uint8_t graphics_therm_throttle_enable;
uint8_t graphics_voltage_change_enable;
uint8_t graphics_clk_slow_enable;
uint8_t graphics_clk_slow_divider;
uint32_t low_sclk_interrupt_threshold;
bool uvd_power_gated;
bool vce_power_gated;
bool acp_power_gated;
uint32_t active_process_mask;
uint32_t mgcg_cgtt_local0;
uint32_t mgcg_cgtt_local1;
uint32_t clock_slow_down_step;
uint32_t skip_clock_slow_down;
bool enable_nb_ps_policy;
uint32_t voting_clients;
uint32_t voltage_drop_threshold;
uint32_t gfx_pg_threshold;
uint32_t max_sclk_level;
/* flags */
bool didt_enabled;
bool video_start;
bool cac_enabled;
bool bapm_enabled;
bool nb_dpm_enabled_by_driver;
bool nb_dpm_enabled;
bool auto_thermal_throttling_enabled;
bool dpm_enabled;
bool need_pptable_upload;
/* caps */
bool caps_cac;
bool caps_power_containment;
bool caps_sq_ramping;
bool caps_db_ramping;
bool caps_td_ramping;
bool caps_tcp_ramping;
bool caps_sclk_throttle_low_notification;
bool caps_fps;
bool caps_uvd_dpm;
bool caps_uvd_pg;
bool caps_vce_dpm;
bool caps_vce_pg;
bool caps_acp_dpm;
bool caps_acp_pg;
bool caps_stable_power_state;
bool caps_enable_dfs_bypass;
bool caps_sclk_ds;
bool caps_voltage_island;
/* power state */
struct amdgpu_ps current_rps;
struct cz_ps current_ps;
struct amdgpu_ps requested_rps;
struct cz_ps requested_ps;
bool uvd_power_down;
bool vce_power_down;
bool acp_power_down;
};
/* cz_smc.c */
uint32_t cz_get_argument(struct amdgpu_device *adev);
int cz_send_msg_to_smc(struct amdgpu_device *adev, uint16_t msg);
int cz_send_msg_to_smc_with_parameter(struct amdgpu_device *adev,
uint16_t msg, uint32_t parameter);
int cz_read_smc_sram_dword(struct amdgpu_device *adev,
uint32_t smc_address, uint32_t *value, uint32_t limit);
int cz_smu_upload_pptable(struct amdgpu_device *adev);
int cz_smu_download_pptable(struct amdgpu_device *adev, void **table);
#endif
/*
* Copyright 2014 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 "drmP.h"
#include "amdgpu.h"
#include "amdgpu_ih.h"
#include "vid.h"
#include "oss/oss_3_0_1_d.h"
#include "oss/oss_3_0_1_sh_mask.h"
#include "bif/bif_5_1_d.h"
#include "bif/bif_5_1_sh_mask.h"
/*
* Interrupts
* Starting with r6xx, interrupts are handled via a ring buffer.
* Ring buffers are areas of GPU accessible memory that the GPU
* writes interrupt vectors into and the host reads vectors out of.
* There is a rptr (read pointer) that determines where the
* host is currently reading, and a wptr (write pointer)
* which determines where the GPU has written. When the
* pointers are equal, the ring is idle. When the GPU
* writes vectors to the ring buffer, it increments the
* wptr. When there is an interrupt, the host then starts
* fetching commands and processing them until the pointers are
* equal again at which point it updates the rptr.
*/
static void cz_ih_set_interrupt_funcs(struct amdgpu_device *adev);
/**
* cz_ih_enable_interrupts - Enable the interrupt ring buffer
*
* @adev: amdgpu_device pointer
*
* Enable the interrupt ring buffer (VI).
*/
static void cz_ih_enable_interrupts(struct amdgpu_device *adev)
{
u32 ih_cntl = RREG32(mmIH_CNTL);
u32 ih_rb_cntl = RREG32(mmIH_RB_CNTL);
ih_cntl = REG_SET_FIELD(ih_cntl, IH_CNTL, ENABLE_INTR, 1);
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_ENABLE, 1);
WREG32(mmIH_CNTL, ih_cntl);
WREG32(mmIH_RB_CNTL, ih_rb_cntl);
adev->irq.ih.enabled = true;
}
/**
* cz_ih_disable_interrupts - Disable the interrupt ring buffer
*
* @adev: amdgpu_device pointer
*
* Disable the interrupt ring buffer (VI).
*/
static void cz_ih_disable_interrupts(struct amdgpu_device *adev)
{
u32 ih_rb_cntl = RREG32(mmIH_RB_CNTL);
u32 ih_cntl = RREG32(mmIH_CNTL);
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_ENABLE, 0);
ih_cntl = REG_SET_FIELD(ih_cntl, IH_CNTL, ENABLE_INTR, 0);
WREG32(mmIH_RB_CNTL, ih_rb_cntl);
WREG32(mmIH_CNTL, ih_cntl);
/* set rptr, wptr to 0 */
WREG32(mmIH_RB_RPTR, 0);
WREG32(mmIH_RB_WPTR, 0);
adev->irq.ih.enabled = false;
adev->irq.ih.rptr = 0;
}
/**
* cz_ih_irq_init - init and enable the interrupt ring
*
* @adev: amdgpu_device pointer
*
* Allocate a ring buffer for the interrupt controller,
* enable the RLC, disable interrupts, enable the IH
* ring buffer and enable it (VI).
* Called at device load and reume.
* Returns 0 for success, errors for failure.
*/
static int cz_ih_irq_init(struct amdgpu_device *adev)
{
int ret = 0;
int rb_bufsz;
u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
u64 wptr_off;
/* disable irqs */
cz_ih_disable_interrupts(adev);
/* setup interrupt control */
WREG32(mmINTERRUPT_CNTL2, adev->dummy_page.addr >> 8);
interrupt_cntl = RREG32(mmINTERRUPT_CNTL);
/* INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=0 - dummy read disabled with msi, enabled without msi
* INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=1 - dummy read controlled by IH_DUMMY_RD_EN
*/
interrupt_cntl = REG_SET_FIELD(interrupt_cntl, INTERRUPT_CNTL, IH_DUMMY_RD_OVERRIDE, 0);
/* INTERRUPT_CNTL__IH_REQ_NONSNOOP_EN_MASK=1 if ring is in non-cacheable memory, e.g., vram */
interrupt_cntl = REG_SET_FIELD(interrupt_cntl, INTERRUPT_CNTL, IH_REQ_NONSNOOP_EN, 0);
WREG32(mmINTERRUPT_CNTL, interrupt_cntl);
/* Ring Buffer base. [39:8] of 40-bit address of the beginning of the ring buffer*/
WREG32(mmIH_RB_BASE, adev->irq.ih.gpu_addr >> 8);
rb_bufsz = order_base_2(adev->irq.ih.ring_size / 4);
ih_rb_cntl = REG_SET_FIELD(0, IH_RB_CNTL, WPTR_OVERFLOW_ENABLE, 1);
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_SIZE, rb_bufsz);
/* Ring Buffer write pointer writeback. If enabled, IH_RB_WPTR register value is written to memory */
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_WRITEBACK_ENABLE, 1);
/* set the writeback address whether it's enabled or not */
wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4);
WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off));
WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFF);
WREG32(mmIH_RB_CNTL, ih_rb_cntl);
/* set rptr, wptr to 0 */
WREG32(mmIH_RB_RPTR, 0);
WREG32(mmIH_RB_WPTR, 0);
/* Default settings for IH_CNTL (disabled at first) */
ih_cntl = RREG32(mmIH_CNTL);
ih_cntl = REG_SET_FIELD(ih_cntl, IH_CNTL, MC_VMID, 0);
if (adev->irq.msi_enabled)
ih_cntl = REG_SET_FIELD(ih_cntl, IH_CNTL, RPTR_REARM, 1);
WREG32(mmIH_CNTL, ih_cntl);
pci_set_master(adev->pdev);
/* enable interrupts */
cz_ih_enable_interrupts(adev);
return ret;
}
/**
* cz_ih_irq_disable - disable interrupts
*
* @adev: amdgpu_device pointer
*
* Disable interrupts on the hw (VI).
*/
static void cz_ih_irq_disable(struct amdgpu_device *adev)
{
cz_ih_disable_interrupts(adev);
/* Wait and acknowledge irq */
mdelay(1);
}
/**
* cz_ih_get_wptr - get the IH ring buffer wptr
*
* @adev: amdgpu_device pointer
*
* Get the IH ring buffer wptr from either the register
* or the writeback memory buffer (VI). Also check for
* ring buffer overflow and deal with it.
* Used by cz_irq_process(VI).
* Returns the value of the wptr.
*/
static u32 cz_ih_get_wptr(struct amdgpu_device *adev)
{
u32 wptr, tmp;
wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]);
if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
/* When a ring buffer overflow happen start parsing interrupt
* from the last not overwritten vector (wptr + 16). Hopefully
* this should allow us to catchup.
*/
dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
wptr, adev->irq.ih.rptr, (wptr + 16) & adev->irq.ih.ptr_mask);
adev->irq.ih.rptr = (wptr + 16) & adev->irq.ih.ptr_mask;
tmp = RREG32(mmIH_RB_CNTL);
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
WREG32(mmIH_RB_CNTL, tmp);
}
return (wptr & adev->irq.ih.ptr_mask);
}
/**
* cz_ih_decode_iv - decode an interrupt vector
*
* @adev: amdgpu_device pointer
*
* Decodes the interrupt vector at the current rptr
* position and also advance the position.
*/
static void cz_ih_decode_iv(struct amdgpu_device *adev,
struct amdgpu_iv_entry *entry)
{
/* wptr/rptr are in bytes! */
u32 ring_index = adev->irq.ih.rptr >> 2;
uint32_t dw[4];
dw[0] = le32_to_cpu(adev->irq.ih.ring[ring_index + 0]);
dw[1] = le32_to_cpu(adev->irq.ih.ring[ring_index + 1]);
dw[2] = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]);
dw[3] = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]);
entry->src_id = dw[0] & 0xff;
entry->src_data = dw[1] & 0xfffffff;
entry->ring_id = dw[2] & 0xff;
entry->vm_id = (dw[2] >> 8) & 0xff;
entry->pas_id = (dw[2] >> 16) & 0xffff;
/* wptr/rptr are in bytes! */
adev->irq.ih.rptr += 16;
}
/**
* cz_ih_set_rptr - set the IH ring buffer rptr
*
* @adev: amdgpu_device pointer
*
* Set the IH ring buffer rptr.
*/
static void cz_ih_set_rptr(struct amdgpu_device *adev)
{
WREG32(mmIH_RB_RPTR, adev->irq.ih.rptr);
}
static int cz_ih_early_init(struct amdgpu_device *adev)
{
cz_ih_set_interrupt_funcs(adev);
return 0;
}
static int cz_ih_sw_init(struct amdgpu_device *adev)
{
int r;
r = amdgpu_ih_ring_init(adev, 64 * 1024, false);
if (r)
return r;
r = amdgpu_irq_init(adev);
return r;
}
static int cz_ih_sw_fini(struct amdgpu_device *adev)
{
amdgpu_irq_fini(adev);
amdgpu_ih_ring_fini(adev);
return 0;
}
static int cz_ih_hw_init(struct amdgpu_device *adev)
{
int r;
r = cz_ih_irq_init(adev);
if (r)
return r;
return 0;
}
static int cz_ih_hw_fini(struct amdgpu_device *adev)
{
cz_ih_irq_disable(adev);
return 0;
}
static int cz_ih_suspend(struct amdgpu_device *adev)
{
return cz_ih_hw_fini(adev);
}
static int cz_ih_resume(struct amdgpu_device *adev)
{
return cz_ih_hw_init(adev);
}
static bool cz_ih_is_idle(struct amdgpu_device *adev)
{
u32 tmp = RREG32(mmSRBM_STATUS);
if (REG_GET_FIELD(tmp, SRBM_STATUS, IH_BUSY))
return false;
return true;
}
static int cz_ih_wait_for_idle(struct amdgpu_device *adev)
{
unsigned i;
u32 tmp;
for (i = 0; i < adev->usec_timeout; i++) {
/* read MC_STATUS */
tmp = RREG32(mmSRBM_STATUS);
if (!REG_GET_FIELD(tmp, SRBM_STATUS, IH_BUSY))
return 0;
udelay(1);
}
return -ETIMEDOUT;
}
static void cz_ih_print_status(struct amdgpu_device *adev)
{
dev_info(adev->dev, "CZ IH registers\n");
dev_info(adev->dev, " SRBM_STATUS=0x%08X\n",
RREG32(mmSRBM_STATUS));
dev_info(adev->dev, " SRBM_STATUS2=0x%08X\n",
RREG32(mmSRBM_STATUS2));
dev_info(adev->dev, " INTERRUPT_CNTL=0x%08X\n",
RREG32(mmINTERRUPT_CNTL));
dev_info(adev->dev, " INTERRUPT_CNTL2=0x%08X\n",
RREG32(mmINTERRUPT_CNTL2));
dev_info(adev->dev, " IH_CNTL=0x%08X\n",
RREG32(mmIH_CNTL));
dev_info(adev->dev, " IH_RB_CNTL=0x%08X\n",
RREG32(mmIH_RB_CNTL));
dev_info(adev->dev, " IH_RB_BASE=0x%08X\n",
RREG32(mmIH_RB_BASE));
dev_info(adev->dev, " IH_RB_WPTR_ADDR_LO=0x%08X\n",
RREG32(mmIH_RB_WPTR_ADDR_LO));
dev_info(adev->dev, " IH_RB_WPTR_ADDR_HI=0x%08X\n",
RREG32(mmIH_RB_WPTR_ADDR_HI));
dev_info(adev->dev, " IH_RB_RPTR=0x%08X\n",
RREG32(mmIH_RB_RPTR));
dev_info(adev->dev, " IH_RB_WPTR=0x%08X\n",
RREG32(mmIH_RB_WPTR));
}
static int cz_ih_soft_reset(struct amdgpu_device *adev)
{
u32 srbm_soft_reset = 0;
u32 tmp = RREG32(mmSRBM_STATUS);
if (tmp & SRBM_STATUS__IH_BUSY_MASK)
srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET,
SOFT_RESET_IH, 1);
if (srbm_soft_reset) {
cz_ih_print_status(adev);
tmp = RREG32(mmSRBM_SOFT_RESET);
tmp |= srbm_soft_reset;
dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
WREG32(mmSRBM_SOFT_RESET, tmp);
tmp = RREG32(mmSRBM_SOFT_RESET);
udelay(50);
tmp &= ~srbm_soft_reset;
WREG32(mmSRBM_SOFT_RESET, tmp);
tmp = RREG32(mmSRBM_SOFT_RESET);
/* Wait a little for things to settle down */
udelay(50);
cz_ih_print_status(adev);
}
return 0;
}
static int cz_ih_set_clockgating_state(struct amdgpu_device *adev,
enum amdgpu_clockgating_state state)
{
// TODO
return 0;
}
static int cz_ih_set_powergating_state(struct amdgpu_device *adev,
enum amdgpu_powergating_state state)
{
// TODO
return 0;
}
const struct amdgpu_ip_funcs cz_ih_ip_funcs = {
.early_init = cz_ih_early_init,
.late_init = NULL,
.sw_init = cz_ih_sw_init,
.sw_fini = cz_ih_sw_fini,
.hw_init = cz_ih_hw_init,
.hw_fini = cz_ih_hw_fini,
.suspend = cz_ih_suspend,
.resume = cz_ih_resume,
.is_idle = cz_ih_is_idle,
.wait_for_idle = cz_ih_wait_for_idle,
.soft_reset = cz_ih_soft_reset,
.print_status = cz_ih_print_status,
.set_clockgating_state = cz_ih_set_clockgating_state,
.set_powergating_state = cz_ih_set_powergating_state,
};
static const struct amdgpu_ih_funcs cz_ih_funcs = {
.get_wptr = cz_ih_get_wptr,
.decode_iv = cz_ih_decode_iv,
.set_rptr = cz_ih_set_rptr
};
static void cz_ih_set_interrupt_funcs(struct amdgpu_device *adev)
{
if (adev->irq.ih_funcs == NULL)
adev->irq.ih_funcs = &cz_ih_funcs;
}
/*
* Copyright 2014 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 __CZ_IH_H__
#define __CZ_IH_H__
extern const struct amdgpu_ip_funcs cz_ih_ip_funcs;
#endif /* __CZ_IH_H__ */
/*
* Copyright 2014 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 CZ_PP_SMC_H
#define CZ_PP_SMC_H
#pragma pack(push, 1)
/* Fan control algorithm:*/
#define FDO_MODE_HARDWARE 0
#define FDO_MODE_PIECE_WISE_LINEAR 1
enum FAN_CONTROL {
FAN_CONTROL_FUZZY,
FAN_CONTROL_TABLE
};
enum DPM_ARRAY {
DPM_ARRAY_HARD_MAX,
DPM_ARRAY_HARD_MIN,
DPM_ARRAY_SOFT_MAX,
DPM_ARRAY_SOFT_MIN
};
/*
* Return codes for driver to SMC communication.
* Leave these #define-s, enums might not be exactly 8-bits on the microcontroller.
*/
#define PPSMC_Result_OK ((uint16_t)0x01)
#define PPSMC_Result_NoMore ((uint16_t)0x02)
#define PPSMC_Result_NotNow ((uint16_t)0x03)
#define PPSMC_Result_Failed ((uint16_t)0xFF)
#define PPSMC_Result_UnknownCmd ((uint16_t)0xFE)
#define PPSMC_Result_UnknownVT ((uint16_t)0xFD)
#define PPSMC_isERROR(x) ((uint16_t)0x80 & (x))
/*
* Supported driver messages
*/
#define PPSMC_MSG_Test ((uint16_t) 0x1)
#define PPSMC_MSG_GetFeatureStatus ((uint16_t) 0x2)
#define PPSMC_MSG_EnableAllSmuFeatures ((uint16_t) 0x3)
#define PPSMC_MSG_DisableAllSmuFeatures ((uint16_t) 0x4)
#define PPSMC_MSG_OptimizeBattery ((uint16_t) 0x5)
#define PPSMC_MSG_MaximizePerf ((uint16_t) 0x6)
#define PPSMC_MSG_UVDPowerOFF ((uint16_t) 0x7)
#define PPSMC_MSG_UVDPowerON ((uint16_t) 0x8)
#define PPSMC_MSG_VCEPowerOFF ((uint16_t) 0x9)
#define PPSMC_MSG_VCEPowerON ((uint16_t) 0xA)
#define PPSMC_MSG_ACPPowerOFF ((uint16_t) 0xB)
#define PPSMC_MSG_ACPPowerON ((uint16_t) 0xC)
#define PPSMC_MSG_SDMAPowerOFF ((uint16_t) 0xD)
#define PPSMC_MSG_SDMAPowerON ((uint16_t) 0xE)
#define PPSMC_MSG_XDMAPowerOFF ((uint16_t) 0xF)
#define PPSMC_MSG_XDMAPowerON ((uint16_t) 0x10)
#define PPSMC_MSG_SetMinDeepSleepSclk ((uint16_t) 0x11)
#define PPSMC_MSG_SetSclkSoftMin ((uint16_t) 0x12)
#define PPSMC_MSG_SetSclkSoftMax ((uint16_t) 0x13)
#define PPSMC_MSG_SetSclkHardMin ((uint16_t) 0x14)
#define PPSMC_MSG_SetSclkHardMax ((uint16_t) 0x15)
#define PPSMC_MSG_SetLclkSoftMin ((uint16_t) 0x16)
#define PPSMC_MSG_SetLclkSoftMax ((uint16_t) 0x17)
#define PPSMC_MSG_SetLclkHardMin ((uint16_t) 0x18)
#define PPSMC_MSG_SetLclkHardMax ((uint16_t) 0x19)
#define PPSMC_MSG_SetUvdSoftMin ((uint16_t) 0x1A)
#define PPSMC_MSG_SetUvdSoftMax ((uint16_t) 0x1B)
#define PPSMC_MSG_SetUvdHardMin ((uint16_t) 0x1C)
#define PPSMC_MSG_SetUvdHardMax ((uint16_t) 0x1D)
#define PPSMC_MSG_SetEclkSoftMin ((uint16_t) 0x1E)
#define PPSMC_MSG_SetEclkSoftMax ((uint16_t) 0x1F)
#define PPSMC_MSG_SetEclkHardMin ((uint16_t) 0x20)
#define PPSMC_MSG_SetEclkHardMax ((uint16_t) 0x21)
#define PPSMC_MSG_SetAclkSoftMin ((uint16_t) 0x22)
#define PPSMC_MSG_SetAclkSoftMax ((uint16_t) 0x23)
#define PPSMC_MSG_SetAclkHardMin ((uint16_t) 0x24)
#define PPSMC_MSG_SetAclkHardMax ((uint16_t) 0x25)
#define PPSMC_MSG_SetNclkSoftMin ((uint16_t) 0x26)
#define PPSMC_MSG_SetNclkSoftMax ((uint16_t) 0x27)
#define PPSMC_MSG_SetNclkHardMin ((uint16_t) 0x28)
#define PPSMC_MSG_SetNclkHardMax ((uint16_t) 0x29)
#define PPSMC_MSG_SetPstateSoftMin ((uint16_t) 0x2A)
#define PPSMC_MSG_SetPstateSoftMax ((uint16_t) 0x2B)
#define PPSMC_MSG_SetPstateHardMin ((uint16_t) 0x2C)
#define PPSMC_MSG_SetPstateHardMax ((uint16_t) 0x2D)
#define PPSMC_MSG_DisableLowMemoryPstate ((uint16_t) 0x2E)
#define PPSMC_MSG_EnableLowMemoryPstate ((uint16_t) 0x2F)
#define PPSMC_MSG_UcodeAddressLow ((uint16_t) 0x30)
#define PPSMC_MSG_UcodeAddressHigh ((uint16_t) 0x31)
#define PPSMC_MSG_UcodeLoadStatus ((uint16_t) 0x32)
#define PPSMC_MSG_DriverDramAddrHi ((uint16_t) 0x33)
#define PPSMC_MSG_DriverDramAddrLo ((uint16_t) 0x34)
#define PPSMC_MSG_CondExecDramAddrHi ((uint16_t) 0x35)
#define PPSMC_MSG_CondExecDramAddrLo ((uint16_t) 0x36)
#define PPSMC_MSG_LoadUcodes ((uint16_t) 0x37)
#define PPSMC_MSG_DriverResetMode ((uint16_t) 0x38)
#define PPSMC_MSG_PowerStateNotify ((uint16_t) 0x39)
#define PPSMC_MSG_SetDisplayPhyConfig ((uint16_t) 0x3A)
#define PPSMC_MSG_GetMaxSclkLevel ((uint16_t) 0x3B)
#define PPSMC_MSG_GetMaxLclkLevel ((uint16_t) 0x3C)
#define PPSMC_MSG_GetMaxUvdLevel ((uint16_t) 0x3D)
#define PPSMC_MSG_GetMaxEclkLevel ((uint16_t) 0x3E)
#define PPSMC_MSG_GetMaxAclkLevel ((uint16_t) 0x3F)
#define PPSMC_MSG_GetMaxNclkLevel ((uint16_t) 0x40)
#define PPSMC_MSG_GetMaxPstate ((uint16_t) 0x41)
#define PPSMC_MSG_DramAddrHiVirtual ((uint16_t) 0x42)
#define PPSMC_MSG_DramAddrLoVirtual ((uint16_t) 0x43)
#define PPSMC_MSG_DramAddrHiPhysical ((uint16_t) 0x44)
#define PPSMC_MSG_DramAddrLoPhysical ((uint16_t) 0x45)
#define PPSMC_MSG_DramBufferSize ((uint16_t) 0x46)
#define PPSMC_MSG_SetMmPwrLogDramAddrHi ((uint16_t) 0x47)
#define PPSMC_MSG_SetMmPwrLogDramAddrLo ((uint16_t) 0x48)
#define PPSMC_MSG_SetClkTableAddrHi ((uint16_t) 0x49)
#define PPSMC_MSG_SetClkTableAddrLo ((uint16_t) 0x4A)
#define PPSMC_MSG_GetConservativePowerLimit ((uint16_t) 0x4B)
#define PPSMC_MSG_InitJobs ((uint16_t) 0x252)
#define PPSMC_MSG_ExecuteJob ((uint16_t) 0x254)
#define PPSMC_MSG_NBDPM_Enable ((uint16_t) 0x140)
#define PPSMC_MSG_NBDPM_Disable ((uint16_t) 0x141)
#define PPSMC_MSG_DPM_FPS_Mode ((uint16_t) 0x15d)
#define PPSMC_MSG_DPM_Activity_Mode ((uint16_t) 0x15e)
#define PPSMC_MSG_PmStatusLogStart ((uint16_t) 0x170)
#define PPSMC_MSG_PmStatusLogSample ((uint16_t) 0x171)
#define PPSMC_MSG_AllowLowSclkInterrupt ((uint16_t) 0x184)
#define PPSMC_MSG_MmPowerMonitorStart ((uint16_t) 0x18F)
#define PPSMC_MSG_MmPowerMonitorStop ((uint16_t) 0x190)
#define PPSMC_MSG_MmPowerMonitorRestart ((uint16_t) 0x191)
#define PPSMC_MSG_SetClockGateMask ((uint16_t) 0x260)
#define PPSMC_MSG_SetFpsThresholdLo ((uint16_t) 0x264)
#define PPSMC_MSG_SetFpsThresholdHi ((uint16_t) 0x265)
#define PPSMC_MSG_SetLowSclkIntrThreshold ((uint16_t) 0x266)
#define PPSMC_MSG_ClkTableXferToDram ((uint16_t) 0x267)
#define PPSMC_MSG_ClkTableXferToSmu ((uint16_t) 0x268)
#define PPSMC_MSG_GetAverageGraphicsActivity ((uint16_t) 0x269)
#define PPSMC_MSG_GetAverageGioActivity ((uint16_t) 0x26A)
#define PPSMC_MSG_SetLoggerBufferSize ((uint16_t) 0x26B)
#define PPSMC_MSG_SetLoggerAddressHigh ((uint16_t) 0x26C)
#define PPSMC_MSG_SetLoggerAddressLow ((uint16_t) 0x26D)
#define PPSMC_MSG_SetWatermarkFrequency ((uint16_t) 0x26E)
/* REMOVE LATER*/
#define PPSMC_MSG_DPM_ForceState ((uint16_t) 0x104)
/* Feature Enable Masks*/
#define NB_DPM_MASK 0x00000800
#define VDDGFX_MASK 0x00800000
#define VCE_DPM_MASK 0x00400000
#define ACP_DPM_MASK 0x00040000
#define UVD_DPM_MASK 0x00010000
#define GFX_CU_PG_MASK 0x00004000
#define SCLK_DPM_MASK 0x00080000
#if !defined(SMC_MICROCODE)
#pragma pack(pop)
#endif
#endif
此差异已折叠。
/*
* Copyright 2014 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 __CZ_SMC_H__
#define __CZ_SMC_H__
#define MAX_NUM_FIRMWARE 8
#define MAX_NUM_SCRATCH 11
#define CZ_SCRATCH_SIZE_NONGFX_CLOCKGATING 1024
#define CZ_SCRATCH_SIZE_NONGFX_GOLDENSETTING 2048
#define CZ_SCRATCH_SIZE_SDMA_METADATA 1024
#define CZ_SCRATCH_SIZE_IH ((2*256+1)*4)
enum cz_scratch_entry {
CZ_SCRATCH_ENTRY_UCODE_ID_SDMA0 = 0,
CZ_SCRATCH_ENTRY_UCODE_ID_SDMA1,
CZ_SCRATCH_ENTRY_UCODE_ID_CP_CE,
CZ_SCRATCH_ENTRY_UCODE_ID_CP_PFP,
CZ_SCRATCH_ENTRY_UCODE_ID_CP_ME,
CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1,
CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2,
CZ_SCRATCH_ENTRY_UCODE_ID_GMCON_RENG,
CZ_SCRATCH_ENTRY_UCODE_ID_RLC_G,
CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SCRATCH,
CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_ARAM,
CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_DRAM,
CZ_SCRATCH_ENTRY_UCODE_ID_DMCU_ERAM,
CZ_SCRATCH_ENTRY_UCODE_ID_DMCU_IRAM,
CZ_SCRATCH_ENTRY_UCODE_ID_POWER_PROFILING,
CZ_SCRATCH_ENTRY_DATA_ID_SDMA_HALT,
CZ_SCRATCH_ENTRY_DATA_ID_SYS_CLOCKGATING,
CZ_SCRATCH_ENTRY_DATA_ID_SDMA_RING_REGS,
CZ_SCRATCH_ENTRY_DATA_ID_NONGFX_REINIT,
CZ_SCRATCH_ENTRY_DATA_ID_SDMA_START,
CZ_SCRATCH_ENTRY_DATA_ID_IH_REGISTERS,
CZ_SCRATCH_ENTRY_SMU8_FUSION_CLKTABLE
};
struct cz_buffer_entry {
uint32_t data_size;
uint32_t mc_addr_low;
uint32_t mc_addr_high;
void *kaddr;
enum cz_scratch_entry firmware_ID;
};
struct cz_register_index_data_pair {
uint32_t offset;
uint32_t value;
};
struct cz_ih_meta_data {
uint32_t command;
struct cz_register_index_data_pair register_index_value_pair[1];
};
struct cz_smu_private_data {
uint8_t driver_buffer_length;
uint8_t scratch_buffer_length;
uint16_t toc_entry_used_count;
uint16_t toc_entry_initialize_index;
uint16_t toc_entry_power_profiling_index;
uint16_t toc_entry_aram;
uint16_t toc_entry_ih_register_restore_task_index;
uint16_t toc_entry_clock_table;
uint16_t ih_register_restore_task_size;
uint16_t smu_buffer_used_bytes;
struct cz_buffer_entry toc_buffer;
struct cz_buffer_entry smu_buffer;
struct cz_buffer_entry driver_buffer[MAX_NUM_FIRMWARE];
struct cz_buffer_entry scratch_buffer[MAX_NUM_SCRATCH];
};
#endif
此差异已折叠。
/*
* Copyright 2014 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 __DCE_V10_0_H__
#define __DCE_V10_0_H__
extern const struct amdgpu_ip_funcs dce_v10_0_ip_funcs;
#endif
此差异已折叠。
/*
* Copyright 2014 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 __DCE_V11_0_H__
#define __DCE_V11_0_H__
extern const struct amdgpu_ip_funcs dce_v11_0_ip_funcs;
#endif
此差异已折叠。
/*
* Copyright 2014 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 __GFX_V8_0_H__
#define __GFX_V8_0_H__
extern const struct amdgpu_ip_funcs gfx_v8_0_ip_funcs;
uint64_t gfx_v8_0_get_gpu_clock_counter(struct amdgpu_device *adev);
void gfx_v8_0_select_se_sh(struct amdgpu_device *adev, u32 se_num, u32 sh_num);
int gfx_v8_0_get_cu_info(struct amdgpu_device *adev, struct amdgpu_cu_info *cu_info);
#endif
此差异已折叠。
/*
* Copyright 2014 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 __GMC_V8_0_H__
#define __GMC_V8_0_H__
extern const struct amdgpu_ip_funcs gmc_v8_0_ip_funcs;
/* XXX these shouldn't be exported */
void gmc_v8_0_mc_stop(struct amdgpu_device *adev,
struct amdgpu_mode_mc_save *save);
void gmc_v8_0_mc_resume(struct amdgpu_device *adev,
struct amdgpu_mode_mc_save *save);
int gmc_v8_0_mc_wait_for_idle(struct amdgpu_device *adev);
#endif
/*
* Copyright 2014 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/firmware.h>
#include "drmP.h"
#include "amdgpu.h"
#include "iceland_smumgr.h"
MODULE_FIRMWARE("radeon/topaz_smc.bin");
static void iceland_dpm_set_funcs(struct amdgpu_device *adev);
static int iceland_dpm_early_init(struct amdgpu_device *adev)
{
iceland_dpm_set_funcs(adev);
return 0;
}
static int iceland_dpm_init_microcode(struct amdgpu_device *adev)
{
char fw_name[30] = "radeon/topaz_smc.bin";
int err;
err = request_firmware(&adev->pm.fw, fw_name, adev->dev);
if (err)
goto out;
err = amdgpu_ucode_validate(adev->pm.fw);
out:
if (err) {
DRM_ERROR("Failed to load firmware \"%s\"", fw_name);
release_firmware(adev->pm.fw);
adev->pm.fw = NULL;
}
return err;
}
static int iceland_dpm_sw_init(struct amdgpu_device *adev)
{
int ret;
ret = iceland_dpm_init_microcode(adev);
if (ret)
return ret;
return 0;
}
static int iceland_dpm_sw_fini(struct amdgpu_device *adev)
{
return 0;
}
static int iceland_dpm_hw_init(struct amdgpu_device *adev)
{
int ret;
mutex_lock(&adev->pm.mutex);
ret = iceland_smu_init(adev);
if (ret) {
DRM_ERROR("SMU initialization failed\n");
goto fail;
}
ret = iceland_smu_start(adev);
if (ret) {
DRM_ERROR("SMU start failed\n");
goto fail;
}
mutex_unlock(&adev->pm.mutex);
return 0;
fail:
adev->firmware.smu_load = false;
mutex_unlock(&adev->pm.mutex);
return -EINVAL;
}
static int iceland_dpm_hw_fini(struct amdgpu_device *adev)
{
mutex_lock(&adev->pm.mutex);
iceland_smu_fini(adev);
mutex_unlock(&adev->pm.mutex);
return 0;
}
static int iceland_dpm_suspend(struct amdgpu_device *adev)
{
iceland_dpm_hw_fini(adev);
return 0;
}
static int iceland_dpm_resume(struct amdgpu_device *adev)
{
iceland_dpm_hw_init(adev);
return 0;
}
static int iceland_dpm_set_clockgating_state(struct amdgpu_device *adev,
enum amdgpu_clockgating_state state)
{
return 0;
}
static int iceland_dpm_set_powergating_state(struct amdgpu_device *adev,
enum amdgpu_powergating_state state)
{
return 0;
}
const struct amdgpu_ip_funcs iceland_dpm_ip_funcs = {
.early_init = iceland_dpm_early_init,
.late_init = NULL,
.sw_init = iceland_dpm_sw_init,
.sw_fini = iceland_dpm_sw_fini,
.hw_init = iceland_dpm_hw_init,
.hw_fini = iceland_dpm_hw_fini,
.suspend = iceland_dpm_suspend,
.resume = iceland_dpm_resume,
.is_idle = NULL,
.wait_for_idle = NULL,
.soft_reset = NULL,
.print_status = NULL,
.set_clockgating_state = iceland_dpm_set_clockgating_state,
.set_powergating_state = iceland_dpm_set_powergating_state,
};
static const struct amdgpu_dpm_funcs iceland_dpm_funcs = {
.get_temperature = NULL,
.pre_set_power_state = NULL,
.set_power_state = NULL,
.post_set_power_state = NULL,
.display_configuration_changed = NULL,
.get_sclk = NULL,
.get_mclk = NULL,
.print_power_state = NULL,
.debugfs_print_current_performance_level = NULL,
.force_performance_level = NULL,
.vblank_too_short = NULL,
.powergate_uvd = NULL,
};
static void iceland_dpm_set_funcs(struct amdgpu_device *adev)
{
if (NULL == adev->pm.funcs)
adev->pm.funcs = &iceland_dpm_funcs;
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册