提交 29a73d90 编写于 作者: D Dave Airlie

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

This is the main feature pull for radeon and amdgpu for 4.11.  Highlights:
- Power and clockgating improvements
- Preliminary SR-IOV support
- ttm buffer priority support
- ttm eviction fixes
- Removal of the ttm lru callbacks
- Remove SI DPM quirks due to MC firmware issues
- Handle VFCT with multiple vbioses
- Powerplay improvements
- Lots of driver cleanups

* 'drm-next-4.11' of git://people.freedesktop.org/~agd5f/linux: (120 commits)
  drm/amdgpu: fix amdgpu_bo_va_mapping flags
  drm/amdgpu: access stolen VRAM directly on CZ (v2)
  drm/amdgpu: access stolen VRAM directly on KV/KB (v2)
  drm/amdgpu: fix kernel panic when dpm disabled on Kv.
  drm/amdgpu: fix dpm bug on Kv.
  drm/amd/powerplay: fix regresstion issue can't set manual dpm mode.
  drm/amdgpu: handle vfct with multiple vbios images
  drm/radeon: handle vfct with multiple vbios images
  drm/amdgpu: move misc si headers into amdgpu
  drm/amdgpu: remove unused header si_reg.h
  drm/radeon: drop pitcairn dpm quirks
  drm/amdgpu: drop pitcairn dpm quirks
  drm: radeon: radeon_ttm: Handle return NULL error from ioremap_nocache
  drm/amd/amdgpu/amdgpu_ttm: Handle return NULL error from ioremap_nocache
  drm/amdgpu: add new virtual display ID
  drm/amd/amdgpu: remove the uncessary parameter for ib scheduler
  drm/amdgpu: Bring bo creation in line with radeon driver (v2)
  drm/amd/powerplay: fix misspelling in header guard
  drm/ttm: revert "add optional LRU removal callback v2"
  drm/ttm: revert "implement LRU add callbacks v2"
  ...
...@@ -24,7 +24,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \ ...@@ -24,7 +24,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \
atombios_encoders.o amdgpu_sa.o atombios_i2c.o \ atombios_encoders.o amdgpu_sa.o atombios_i2c.o \
amdgpu_prime.o amdgpu_vm.o amdgpu_ib.o amdgpu_pll.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 \ amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o \
amdgpu_gtt_mgr.o amdgpu_vram_mgr.o amdgpu_gtt_mgr.o amdgpu_vram_mgr.o amdgpu_virt.o
# add asic specific block # add asic specific block
amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \ amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \
...@@ -34,7 +34,7 @@ amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \ ...@@ -34,7 +34,7 @@ amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \
amdgpu-$(CONFIG_DRM_AMDGPU_SI)+= si.o gmc_v6_0.o gfx_v6_0.o si_ih.o si_dma.o dce_v6_0.o si_dpm.o si_smc.o amdgpu-$(CONFIG_DRM_AMDGPU_SI)+= si.o gmc_v6_0.o gfx_v6_0.o si_ih.o si_dma.o dce_v6_0.o si_dpm.o si_smc.o
amdgpu-y += \ amdgpu-y += \
vi.o vi.o mxgpu_vi.o
# add GMC block # add GMC block
amdgpu-y += \ amdgpu-y += \
...@@ -52,8 +52,7 @@ amdgpu-y += \ ...@@ -52,8 +52,7 @@ amdgpu-y += \
# add SMC block # add SMC block
amdgpu-y += \ amdgpu-y += \
amdgpu_dpm.o \ amdgpu_dpm.o \
amdgpu_powerplay.o \ amdgpu_powerplay.o
cz_smc.o cz_dpm.o
# add DCE block # add DCE block
amdgpu-y += \ amdgpu-y += \
......
...@@ -91,7 +91,6 @@ extern int amdgpu_vm_fault_stop; ...@@ -91,7 +91,6 @@ extern int amdgpu_vm_fault_stop;
extern int amdgpu_vm_debug; extern int amdgpu_vm_debug;
extern int amdgpu_sched_jobs; extern int amdgpu_sched_jobs;
extern int amdgpu_sched_hw_submission; extern int amdgpu_sched_hw_submission;
extern int amdgpu_powerplay;
extern int amdgpu_no_evict; extern int amdgpu_no_evict;
extern int amdgpu_direct_gma_size; extern int amdgpu_direct_gma_size;
extern unsigned amdgpu_pcie_gen_cap; extern unsigned amdgpu_pcie_gen_cap;
...@@ -184,12 +183,18 @@ enum amdgpu_thermal_irq { ...@@ -184,12 +183,18 @@ enum amdgpu_thermal_irq {
AMDGPU_THERMAL_IRQ_LAST AMDGPU_THERMAL_IRQ_LAST
}; };
enum amdgpu_kiq_irq {
AMDGPU_CP_KIQ_IRQ_DRIVER0 = 0,
AMDGPU_CP_KIQ_IRQ_LAST
};
int amdgpu_set_clockgating_state(struct amdgpu_device *adev, int amdgpu_set_clockgating_state(struct amdgpu_device *adev,
enum amd_ip_block_type block_type, enum amd_ip_block_type block_type,
enum amd_clockgating_state state); enum amd_clockgating_state state);
int amdgpu_set_powergating_state(struct amdgpu_device *adev, int amdgpu_set_powergating_state(struct amdgpu_device *adev,
enum amd_ip_block_type block_type, enum amd_ip_block_type block_type,
enum amd_powergating_state state); enum amd_powergating_state state);
void amdgpu_get_clockgating_state(struct amdgpu_device *adev, u32 *flags);
int amdgpu_wait_for_idle(struct amdgpu_device *adev, int amdgpu_wait_for_idle(struct amdgpu_device *adev,
enum amd_ip_block_type block_type); enum amd_ip_block_type block_type);
bool amdgpu_is_idle(struct amdgpu_device *adev, bool amdgpu_is_idle(struct amdgpu_device *adev,
...@@ -352,7 +357,7 @@ struct amdgpu_bo_va_mapping { ...@@ -352,7 +357,7 @@ struct amdgpu_bo_va_mapping {
struct list_head list; struct list_head list;
struct interval_tree_node it; struct interval_tree_node it;
uint64_t offset; uint64_t offset;
uint32_t flags; uint64_t flags;
}; };
/* bo virtual addresses in a specific vm */ /* bo virtual addresses in a specific vm */
...@@ -776,14 +781,20 @@ struct amdgpu_mec { ...@@ -776,14 +781,20 @@ struct amdgpu_mec {
u32 num_queue; u32 num_queue;
}; };
struct amdgpu_kiq {
u64 eop_gpu_addr;
struct amdgpu_bo *eop_obj;
struct amdgpu_ring ring;
struct amdgpu_irq_src irq;
};
/* /*
* GPU scratch registers structures, functions & helpers * GPU scratch registers structures, functions & helpers
*/ */
struct amdgpu_scratch { struct amdgpu_scratch {
unsigned num_reg; unsigned num_reg;
uint32_t reg_base; uint32_t reg_base;
bool free[32]; uint32_t free_mask;
uint32_t reg[32];
}; };
/* /*
...@@ -851,6 +862,7 @@ struct amdgpu_gfx { ...@@ -851,6 +862,7 @@ struct amdgpu_gfx {
struct amdgpu_gca_config config; struct amdgpu_gca_config config;
struct amdgpu_rlc rlc; struct amdgpu_rlc rlc;
struct amdgpu_mec mec; struct amdgpu_mec mec;
struct amdgpu_kiq kiq;
struct amdgpu_scratch scratch; struct amdgpu_scratch scratch;
const struct firmware *me_fw; /* ME firmware */ const struct firmware *me_fw; /* ME firmware */
uint32_t me_fw_version; uint32_t me_fw_version;
...@@ -894,8 +906,8 @@ int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, ...@@ -894,8 +906,8 @@ int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm,
void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib, void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib,
struct dma_fence *f); struct dma_fence *f);
int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
struct amdgpu_ib *ib, struct dma_fence *last_vm_update, struct amdgpu_ib *ibs, struct amdgpu_job *job,
struct amdgpu_job *job, struct dma_fence **f); struct dma_fence **f);
int amdgpu_ib_pool_init(struct amdgpu_device *adev); int amdgpu_ib_pool_init(struct amdgpu_device *adev);
void amdgpu_ib_pool_fini(struct amdgpu_device *adev); void amdgpu_ib_pool_fini(struct amdgpu_device *adev);
int amdgpu_ib_ring_tests(struct amdgpu_device *adev); int amdgpu_ib_ring_tests(struct amdgpu_device *adev);
...@@ -938,6 +950,7 @@ struct amdgpu_cs_parser { ...@@ -938,6 +950,7 @@ struct amdgpu_cs_parser {
#define AMDGPU_PREAMBLE_IB_PRESENT (1 << 0) /* bit set means command submit involves a preamble IB */ #define AMDGPU_PREAMBLE_IB_PRESENT (1 << 0) /* bit set means command submit involves a preamble IB */
#define AMDGPU_PREAMBLE_IB_PRESENT_FIRST (1 << 1) /* bit set means preamble IB is first presented in belonging context */ #define AMDGPU_PREAMBLE_IB_PRESENT_FIRST (1 << 1) /* bit set means preamble IB is first presented in belonging context */
#define AMDGPU_HAVE_CTX_SWITCH (1 << 2) /* bit set means context switch occured */ #define AMDGPU_HAVE_CTX_SWITCH (1 << 2) /* bit set means context switch occured */
#define AMDGPU_VM_DOMAIN (1 << 3) /* bit set means in virtual memory context */
struct amdgpu_job { struct amdgpu_job {
struct amd_sched_job base; struct amd_sched_job base;
...@@ -1024,6 +1037,7 @@ struct amdgpu_uvd { ...@@ -1024,6 +1037,7 @@ struct amdgpu_uvd {
bool use_ctx_buf; bool use_ctx_buf;
struct amd_sched_entity entity; struct amd_sched_entity entity;
uint32_t srbm_soft_reset; uint32_t srbm_soft_reset;
bool is_powergated;
}; };
/* /*
...@@ -1052,6 +1066,7 @@ struct amdgpu_vce { ...@@ -1052,6 +1066,7 @@ struct amdgpu_vce {
struct amd_sched_entity entity; struct amd_sched_entity entity;
uint32_t srbm_soft_reset; uint32_t srbm_soft_reset;
unsigned num_rings; unsigned num_rings;
bool is_powergated;
}; };
/* /*
...@@ -1177,7 +1192,6 @@ struct amdgpu_asic_funcs { ...@@ -1177,7 +1192,6 @@ struct amdgpu_asic_funcs {
bool (*read_disabled_bios)(struct amdgpu_device *adev); bool (*read_disabled_bios)(struct amdgpu_device *adev);
bool (*read_bios_from_rom)(struct amdgpu_device *adev, bool (*read_bios_from_rom)(struct amdgpu_device *adev,
u8 *bios, u32 length_bytes); u8 *bios, u32 length_bytes);
void (*detect_hw_virtualization) (struct amdgpu_device *adev);
int (*read_register)(struct amdgpu_device *adev, u32 se_num, int (*read_register)(struct amdgpu_device *adev, u32 se_num,
u32 sh_num, u32 reg_offset, u32 *value); u32 sh_num, u32 reg_offset, u32 *value);
void (*set_vga_state)(struct amdgpu_device *adev, bool state); void (*set_vga_state)(struct amdgpu_device *adev, bool state);
...@@ -1332,7 +1346,6 @@ struct amdgpu_device { ...@@ -1332,7 +1346,6 @@ struct amdgpu_device {
/* BIOS */ /* BIOS */
uint8_t *bios; uint8_t *bios;
uint32_t bios_size; uint32_t bios_size;
bool is_atom_bios;
struct amdgpu_bo *stollen_vga_memory; struct amdgpu_bo *stollen_vga_memory;
uint32_t bios_scratch[AMDGPU_BIOS_NUM_SCRATCH]; uint32_t bios_scratch[AMDGPU_BIOS_NUM_SCRATCH];
...@@ -1462,7 +1475,7 @@ struct amdgpu_device { ...@@ -1462,7 +1475,7 @@ struct amdgpu_device {
/* amdkfd interface */ /* amdkfd interface */
struct kfd_dev *kfd; struct kfd_dev *kfd;
struct amdgpu_virtualization virtualization; struct amdgpu_virt virt;
/* link all shadow bo */ /* link all shadow bo */
struct list_head shadow_list; struct list_head shadow_list;
...@@ -1575,6 +1588,37 @@ static inline void amdgpu_ring_write(struct amdgpu_ring *ring, uint32_t v) ...@@ -1575,6 +1588,37 @@ static inline void amdgpu_ring_write(struct amdgpu_ring *ring, uint32_t v)
ring->count_dw--; ring->count_dw--;
} }
static inline void amdgpu_ring_write_multiple(struct amdgpu_ring *ring, void *src, int count_dw)
{
unsigned occupied, chunk1, chunk2;
void *dst;
if (ring->count_dw < count_dw) {
DRM_ERROR("amdgpu: writing more dwords to the ring than expected!\n");
} else {
occupied = ring->wptr & ring->ptr_mask;
dst = (void *)&ring->ring[occupied];
chunk1 = ring->ptr_mask + 1 - occupied;
chunk1 = (chunk1 >= count_dw) ? count_dw: chunk1;
chunk2 = count_dw - chunk1;
chunk1 <<= 2;
chunk2 <<= 2;
if (chunk1)
memcpy(dst, src, chunk1);
if (chunk2) {
src += chunk1;
dst = (void *)ring->ring;
memcpy(dst, src, chunk2);
}
ring->wptr += count_dw;
ring->wptr &= ring->ptr_mask;
ring->count_dw -= count_dw;
}
}
static inline struct amdgpu_sdma_instance * static inline struct amdgpu_sdma_instance *
amdgpu_get_sdma_instance(struct amdgpu_ring *ring) amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
{ {
...@@ -1604,7 +1648,6 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring) ...@@ -1604,7 +1648,6 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
#define amdgpu_asic_get_gpu_clock_counter(adev) (adev)->asic_funcs->get_gpu_clock_counter((adev)) #define amdgpu_asic_get_gpu_clock_counter(adev) (adev)->asic_funcs->get_gpu_clock_counter((adev))
#define amdgpu_asic_read_disabled_bios(adev) (adev)->asic_funcs->read_disabled_bios((adev)) #define amdgpu_asic_read_disabled_bios(adev) (adev)->asic_funcs->read_disabled_bios((adev))
#define amdgpu_asic_read_bios_from_rom(adev, b, l) (adev)->asic_funcs->read_bios_from_rom((adev), (b), (l)) #define amdgpu_asic_read_bios_from_rom(adev, b, l) (adev)->asic_funcs->read_bios_from_rom((adev), (b), (l))
#define amdgpu_asic_detect_hw_virtualization(adev) (adev)->asic_funcs->detect_hw_virtualization((adev))
#define amdgpu_asic_read_register(adev, se, sh, offset, v)((adev)->asic_funcs->read_register((adev), (se), (sh), (offset), (v))) #define amdgpu_asic_read_register(adev, se, sh, offset, v)((adev)->asic_funcs->read_register((adev), (se), (sh), (offset), (v)))
#define amdgpu_gart_flush_gpu_tlb(adev, vmid) (adev)->gart.gart_funcs->flush_gpu_tlb((adev), (vmid)) #define amdgpu_gart_flush_gpu_tlb(adev, vmid) (adev)->gart.gart_funcs->flush_gpu_tlb((adev), (vmid))
#define amdgpu_gart_set_pte_pde(adev, pt, idx, addr, flags) (adev)->gart.gart_funcs->set_pte_pde((adev), (pt), (idx), (addr), (flags)) #define amdgpu_gart_set_pte_pde(adev, pt, idx, addr, flags) (adev)->gart.gart_funcs->set_pte_pde((adev), (pt), (idx), (addr), (flags))
...@@ -1626,6 +1669,8 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring) ...@@ -1626,6 +1669,8 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
#define amdgpu_ring_emit_hdp_invalidate(r) (r)->funcs->emit_hdp_invalidate((r)) #define amdgpu_ring_emit_hdp_invalidate(r) (r)->funcs->emit_hdp_invalidate((r))
#define amdgpu_ring_emit_switch_buffer(r) (r)->funcs->emit_switch_buffer((r)) #define amdgpu_ring_emit_switch_buffer(r) (r)->funcs->emit_switch_buffer((r))
#define amdgpu_ring_emit_cntxcntl(r, d) (r)->funcs->emit_cntxcntl((r), (d)) #define amdgpu_ring_emit_cntxcntl(r, d) (r)->funcs->emit_cntxcntl((r), (d))
#define amdgpu_ring_emit_rreg(r, d) (r)->funcs->emit_rreg((r), (d))
#define amdgpu_ring_emit_wreg(r, d, v) (r)->funcs->emit_wreg((r), (d), (v))
#define amdgpu_ring_pad_ib(r, ib) ((r)->funcs->pad_ib((r), (ib))) #define amdgpu_ring_pad_ib(r, ib) ((r)->funcs->pad_ib((r), (ib)))
#define amdgpu_ring_init_cond_exec(r) (r)->funcs->init_cond_exec((r)) #define amdgpu_ring_init_cond_exec(r) (r)->funcs->init_cond_exec((r))
#define amdgpu_ring_patch_cond_exec(r,o) (r)->funcs->patch_cond_exec((r),(o)) #define amdgpu_ring_patch_cond_exec(r,o) (r)->funcs->patch_cond_exec((r),(o))
......
...@@ -672,12 +672,10 @@ int amdgpu_acpi_init(struct amdgpu_device *adev) ...@@ -672,12 +672,10 @@ int amdgpu_acpi_init(struct amdgpu_device *adev)
if ((enc->devices & (ATOM_DEVICE_LCD_SUPPORT)) && if ((enc->devices & (ATOM_DEVICE_LCD_SUPPORT)) &&
enc->enc_priv) { enc->enc_priv) {
if (adev->is_atom_bios) { struct amdgpu_encoder_atom_dig *dig = enc->enc_priv;
struct amdgpu_encoder_atom_dig *dig = enc->enc_priv; if (dig->bl_dev) {
if (dig->bl_dev) { atif->encoder_for_bl = enc;
atif->encoder_for_bl = enc; break;
break;
}
} }
} }
} }
......
...@@ -42,6 +42,51 @@ ...@@ -42,6 +42,51 @@
#define AMD_IS_VALID_VBIOS(p) ((p)[0] == 0x55 && (p)[1] == 0xAA) #define AMD_IS_VALID_VBIOS(p) ((p)[0] == 0x55 && (p)[1] == 0xAA)
#define AMD_VBIOS_LENGTH(p) ((p)[2] << 9) #define AMD_VBIOS_LENGTH(p) ((p)[2] << 9)
/* Check if current bios is an ATOM BIOS.
* Return true if it is ATOM BIOS. Otherwise, return false.
*/
static bool check_atom_bios(uint8_t *bios, size_t size)
{
uint16_t tmp, bios_header_start;
if (!bios || size < 0x49) {
DRM_INFO("vbios mem is null or mem size is wrong\n");
return false;
}
if (!AMD_IS_VALID_VBIOS(bios)) {
DRM_INFO("BIOS signature incorrect %x %x\n", bios[0], bios[1]);
return false;
}
tmp = bios[0x18] | (bios[0x19] << 8);
if (bios[tmp + 0x14] != 0x0) {
DRM_INFO("Not an x86 BIOS ROM\n");
return false;
}
bios_header_start = bios[0x48] | (bios[0x49] << 8);
if (!bios_header_start) {
DRM_INFO("Can't locate bios header\n");
return false;
}
tmp = bios_header_start + 4;
if (size < tmp) {
DRM_INFO("BIOS header is broken\n");
return false;
}
if (!memcmp(bios + tmp, "ATOM", 4) ||
!memcmp(bios + tmp, "MOTA", 4)) {
DRM_DEBUG("ATOMBIOS detected\n");
return true;
}
return false;
}
/* If you boot an IGP board with a discrete card as the primary, /* If you boot an IGP board with a discrete card as the primary,
* the IGP rom is not accessible via the rom bar as the IGP rom is * the IGP rom is not accessible via the rom bar as the IGP rom is
* part of the system bios. On boot, the system bios puts a * part of the system bios. On boot, the system bios puts a
...@@ -65,10 +110,6 @@ static bool igp_read_bios_from_vram(struct amdgpu_device *adev) ...@@ -65,10 +110,6 @@ static bool igp_read_bios_from_vram(struct amdgpu_device *adev)
return false; return false;
} }
if (size == 0 || !AMD_IS_VALID_VBIOS(bios)) {
iounmap(bios);
return false;
}
adev->bios = kmalloc(size, GFP_KERNEL); adev->bios = kmalloc(size, GFP_KERNEL);
if (!adev->bios) { if (!adev->bios) {
iounmap(bios); iounmap(bios);
...@@ -77,12 +118,18 @@ static bool igp_read_bios_from_vram(struct amdgpu_device *adev) ...@@ -77,12 +118,18 @@ static bool igp_read_bios_from_vram(struct amdgpu_device *adev)
adev->bios_size = size; adev->bios_size = size;
memcpy_fromio(adev->bios, bios, size); memcpy_fromio(adev->bios, bios, size);
iounmap(bios); iounmap(bios);
if (!check_atom_bios(adev->bios, size)) {
kfree(adev->bios);
return false;
}
return true; return true;
} }
bool amdgpu_read_bios(struct amdgpu_device *adev) bool amdgpu_read_bios(struct amdgpu_device *adev)
{ {
uint8_t __iomem *bios, val[2]; uint8_t __iomem *bios;
size_t size; size_t size;
adev->bios = NULL; adev->bios = NULL;
...@@ -92,13 +139,6 @@ bool amdgpu_read_bios(struct amdgpu_device *adev) ...@@ -92,13 +139,6 @@ bool amdgpu_read_bios(struct amdgpu_device *adev)
return false; return false;
} }
val[0] = readb(&bios[0]);
val[1] = readb(&bios[1]);
if (size == 0 || !AMD_IS_VALID_VBIOS(val)) {
pci_unmap_rom(adev->pdev, bios);
return false;
}
adev->bios = kzalloc(size, GFP_KERNEL); adev->bios = kzalloc(size, GFP_KERNEL);
if (adev->bios == NULL) { if (adev->bios == NULL) {
pci_unmap_rom(adev->pdev, bios); pci_unmap_rom(adev->pdev, bios);
...@@ -107,6 +147,12 @@ bool amdgpu_read_bios(struct amdgpu_device *adev) ...@@ -107,6 +147,12 @@ bool amdgpu_read_bios(struct amdgpu_device *adev)
adev->bios_size = size; adev->bios_size = size;
memcpy_fromio(adev->bios, bios, size); memcpy_fromio(adev->bios, bios, size);
pci_unmap_rom(adev->pdev, bios); pci_unmap_rom(adev->pdev, bios);
if (!check_atom_bios(adev->bios, size)) {
kfree(adev->bios);
return false;
}
return true; return true;
} }
...@@ -140,7 +186,14 @@ static bool amdgpu_read_bios_from_rom(struct amdgpu_device *adev) ...@@ -140,7 +186,14 @@ static bool amdgpu_read_bios_from_rom(struct amdgpu_device *adev)
adev->bios_size = len; adev->bios_size = len;
/* read complete BIOS */ /* read complete BIOS */
return amdgpu_asic_read_bios_from_rom(adev, adev->bios, len); amdgpu_asic_read_bios_from_rom(adev, adev->bios, len);
if (!check_atom_bios(adev->bios, len)) {
kfree(adev->bios);
return false;
}
return true;
} }
static bool amdgpu_read_platform_bios(struct amdgpu_device *adev) static bool amdgpu_read_platform_bios(struct amdgpu_device *adev)
...@@ -155,13 +208,17 @@ static bool amdgpu_read_platform_bios(struct amdgpu_device *adev) ...@@ -155,13 +208,17 @@ static bool amdgpu_read_platform_bios(struct amdgpu_device *adev)
return false; return false;
} }
if (size == 0 || !AMD_IS_VALID_VBIOS(bios)) { adev->bios = kzalloc(size, GFP_KERNEL);
if (adev->bios == NULL)
return false; return false;
}
adev->bios = kmemdup(bios, size, GFP_KERNEL); memcpy_fromio(adev->bios, bios, size);
if (adev->bios == NULL) {
if (!check_atom_bios(adev->bios, size)) {
kfree(adev->bios);
return false; return false;
} }
adev->bios_size = size; adev->bios_size = size;
return true; return true;
...@@ -273,7 +330,7 @@ static bool amdgpu_atrm_get_bios(struct amdgpu_device *adev) ...@@ -273,7 +330,7 @@ static bool amdgpu_atrm_get_bios(struct amdgpu_device *adev)
break; break;
} }
if (i == 0 || !AMD_IS_VALID_VBIOS(adev->bios)) { if (!check_atom_bios(adev->bios, size)) {
kfree(adev->bios); kfree(adev->bios);
return false; return false;
} }
...@@ -298,53 +355,59 @@ static bool amdgpu_read_disabled_bios(struct amdgpu_device *adev) ...@@ -298,53 +355,59 @@ static bool amdgpu_read_disabled_bios(struct amdgpu_device *adev)
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
static bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev) static bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev)
{ {
bool ret = false;
struct acpi_table_header *hdr; struct acpi_table_header *hdr;
acpi_size tbl_size; acpi_size tbl_size;
UEFI_ACPI_VFCT *vfct; UEFI_ACPI_VFCT *vfct;
GOP_VBIOS_CONTENT *vbios; unsigned offset;
VFCT_IMAGE_HEADER *vhdr;
if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr))) if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr)))
return false; return false;
tbl_size = hdr->length; tbl_size = hdr->length;
if (tbl_size < sizeof(UEFI_ACPI_VFCT)) { if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n"); DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n");
goto out_unmap; return false;
} }
vfct = (UEFI_ACPI_VFCT *)hdr; vfct = (UEFI_ACPI_VFCT *)hdr;
if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) > tbl_size) { offset = vfct->VBIOSImageOffset;
DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n");
goto out_unmap;
}
vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + vfct->VBIOSImageOffset); while (offset < tbl_size) {
vhdr = &vbios->VbiosHeader; GOP_VBIOS_CONTENT *vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + offset);
DRM_INFO("ACPI VFCT contains a BIOS for %02x:%02x.%d %04x:%04x, size %d\n", VFCT_IMAGE_HEADER *vhdr = &vbios->VbiosHeader;
vhdr->PCIBus, vhdr->PCIDevice, vhdr->PCIFunction,
vhdr->VendorID, vhdr->DeviceID, vhdr->ImageLength);
if (vhdr->PCIBus != adev->pdev->bus->number ||
vhdr->PCIDevice != PCI_SLOT(adev->pdev->devfn) ||
vhdr->PCIFunction != PCI_FUNC(adev->pdev->devfn) ||
vhdr->VendorID != adev->pdev->vendor ||
vhdr->DeviceID != adev->pdev->device) {
DRM_INFO("ACPI VFCT table is not for this card\n");
goto out_unmap;
}
if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) + vhdr->ImageLength > tbl_size) { offset += sizeof(VFCT_IMAGE_HEADER);
DRM_ERROR("ACPI VFCT image truncated\n"); if (offset > tbl_size) {
goto out_unmap; DRM_ERROR("ACPI VFCT image header truncated\n");
} return false;
}
offset += vhdr->ImageLength;
if (offset > tbl_size) {
DRM_ERROR("ACPI VFCT image truncated\n");
return false;
}
adev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength, GFP_KERNEL); if (vhdr->ImageLength &&
adev->bios_size = vhdr->ImageLength; vhdr->PCIBus == adev->pdev->bus->number &&
ret = !!adev->bios; vhdr->PCIDevice == PCI_SLOT(adev->pdev->devfn) &&
vhdr->PCIFunction == PCI_FUNC(adev->pdev->devfn) &&
vhdr->VendorID == adev->pdev->vendor &&
vhdr->DeviceID == adev->pdev->device) {
adev->bios = kmemdup(&vbios->VbiosContent,
vhdr->ImageLength,
GFP_KERNEL);
if (!check_atom_bios(adev->bios, vhdr->ImageLength)) {
kfree(adev->bios);
return false;
}
adev->bios_size = vhdr->ImageLength;
return true;
}
}
out_unmap: DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n");
return ret; return false;
} }
#else #else
static inline bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev) static inline bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev)
...@@ -355,57 +418,27 @@ static inline bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev) ...@@ -355,57 +418,27 @@ static inline bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev)
bool amdgpu_get_bios(struct amdgpu_device *adev) bool amdgpu_get_bios(struct amdgpu_device *adev)
{ {
bool r; if (amdgpu_atrm_get_bios(adev))
uint16_t tmp, bios_header_start; return true;
r = amdgpu_atrm_get_bios(adev); if (amdgpu_acpi_vfct_bios(adev))
if (!r) return true;
r = amdgpu_acpi_vfct_bios(adev);
if (!r)
r = igp_read_bios_from_vram(adev);
if (!r)
r = amdgpu_read_bios(adev);
if (!r) {
r = amdgpu_read_bios_from_rom(adev);
}
if (!r) {
r = amdgpu_read_disabled_bios(adev);
}
if (!r) {
r = amdgpu_read_platform_bios(adev);
}
if (!r || adev->bios == NULL) {
DRM_ERROR("Unable to locate a BIOS ROM\n");
adev->bios = NULL;
return false;
}
if (!AMD_IS_VALID_VBIOS(adev->bios)) {
printk("BIOS signature incorrect %x %x\n", adev->bios[0], adev->bios[1]);
goto free_bios;
}
tmp = RBIOS16(0x18); if (igp_read_bios_from_vram(adev))
if (RBIOS8(tmp + 0x14) != 0x0) { return true;
DRM_INFO("Not an x86 BIOS ROM, not using.\n");
goto free_bios;
}
bios_header_start = RBIOS16(0x48); if (amdgpu_read_bios(adev))
if (!bios_header_start) { return true;
goto free_bios;
}
tmp = bios_header_start + 4;
if (!memcmp(adev->bios + tmp, "ATOM", 4) ||
!memcmp(adev->bios + tmp, "MOTA", 4)) {
adev->is_atom_bios = true;
} else {
adev->is_atom_bios = false;
}
DRM_DEBUG("%sBIOS detected\n", adev->is_atom_bios ? "ATOM" : "COM"); if (amdgpu_read_bios_from_rom(adev))
return true; return true;
free_bios:
kfree(adev->bios); if (amdgpu_read_disabled_bios(adev))
adev->bios = NULL; return true;
if (amdgpu_read_platform_bios(adev))
return true;
DRM_ERROR("Unable to locate a BIOS ROM\n");
return false; return false;
} }
...@@ -713,6 +713,7 @@ static int amdgpu_cgs_rel_firmware(struct cgs_device *cgs_device, enum cgs_ucode ...@@ -713,6 +713,7 @@ static int amdgpu_cgs_rel_firmware(struct cgs_device *cgs_device, enum cgs_ucode
CGS_FUNC_ADEV; CGS_FUNC_ADEV;
if ((CGS_UCODE_ID_SMU == type) || (CGS_UCODE_ID_SMU_SK == type)) { if ((CGS_UCODE_ID_SMU == type) || (CGS_UCODE_ID_SMU_SK == type)) {
release_firmware(adev->pm.fw); release_firmware(adev->pm.fw);
adev->pm.fw = NULL;
return 0; return 0;
} }
/* cannot release other firmware because they are not created by cgs */ /* cannot release other firmware because they are not created by cgs */
...@@ -762,6 +763,23 @@ static uint16_t amdgpu_get_firmware_version(struct cgs_device *cgs_device, ...@@ -762,6 +763,23 @@ static uint16_t amdgpu_get_firmware_version(struct cgs_device *cgs_device,
return fw_version; return fw_version;
} }
static int amdgpu_cgs_enter_safe_mode(struct cgs_device *cgs_device,
bool en)
{
CGS_FUNC_ADEV;
if (adev->gfx.rlc.funcs->enter_safe_mode == NULL ||
adev->gfx.rlc.funcs->exit_safe_mode == NULL)
return 0;
if (en)
adev->gfx.rlc.funcs->enter_safe_mode(adev);
else
adev->gfx.rlc.funcs->exit_safe_mode(adev);
return 0;
}
static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
enum cgs_ucode_id type, enum cgs_ucode_id type,
struct cgs_firmware_info *info) struct cgs_firmware_info *info)
...@@ -808,6 +826,9 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, ...@@ -808,6 +826,9 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
const uint8_t *src; const uint8_t *src;
const struct smc_firmware_header_v1_0 *hdr; const struct smc_firmware_header_v1_0 *hdr;
if (CGS_UCODE_ID_SMU_SK == type)
amdgpu_cgs_rel_firmware(cgs_device, CGS_UCODE_ID_SMU);
if (!adev->pm.fw) { if (!adev->pm.fw) {
switch (adev->asic_type) { switch (adev->asic_type) {
case CHIP_TOPAZ: case CHIP_TOPAZ:
...@@ -1200,51 +1221,52 @@ static int amdgpu_cgs_call_acpi_method(struct cgs_device *cgs_device, ...@@ -1200,51 +1221,52 @@ static int amdgpu_cgs_call_acpi_method(struct cgs_device *cgs_device,
} }
static const struct cgs_ops amdgpu_cgs_ops = { static const struct cgs_ops amdgpu_cgs_ops = {
amdgpu_cgs_gpu_mem_info, .gpu_mem_info = amdgpu_cgs_gpu_mem_info,
amdgpu_cgs_gmap_kmem, .gmap_kmem = amdgpu_cgs_gmap_kmem,
amdgpu_cgs_gunmap_kmem, .gunmap_kmem = amdgpu_cgs_gunmap_kmem,
amdgpu_cgs_alloc_gpu_mem, .alloc_gpu_mem = amdgpu_cgs_alloc_gpu_mem,
amdgpu_cgs_free_gpu_mem, .free_gpu_mem = amdgpu_cgs_free_gpu_mem,
amdgpu_cgs_gmap_gpu_mem, .gmap_gpu_mem = amdgpu_cgs_gmap_gpu_mem,
amdgpu_cgs_gunmap_gpu_mem, .gunmap_gpu_mem = amdgpu_cgs_gunmap_gpu_mem,
amdgpu_cgs_kmap_gpu_mem, .kmap_gpu_mem = amdgpu_cgs_kmap_gpu_mem,
amdgpu_cgs_kunmap_gpu_mem, .kunmap_gpu_mem = amdgpu_cgs_kunmap_gpu_mem,
amdgpu_cgs_read_register, .read_register = amdgpu_cgs_read_register,
amdgpu_cgs_write_register, .write_register = amdgpu_cgs_write_register,
amdgpu_cgs_read_ind_register, .read_ind_register = amdgpu_cgs_read_ind_register,
amdgpu_cgs_write_ind_register, .write_ind_register = amdgpu_cgs_write_ind_register,
amdgpu_cgs_read_pci_config_byte, .read_pci_config_byte = amdgpu_cgs_read_pci_config_byte,
amdgpu_cgs_read_pci_config_word, .read_pci_config_word = amdgpu_cgs_read_pci_config_word,
amdgpu_cgs_read_pci_config_dword, .read_pci_config_dword = amdgpu_cgs_read_pci_config_dword,
amdgpu_cgs_write_pci_config_byte, .write_pci_config_byte = amdgpu_cgs_write_pci_config_byte,
amdgpu_cgs_write_pci_config_word, .write_pci_config_word = amdgpu_cgs_write_pci_config_word,
amdgpu_cgs_write_pci_config_dword, .write_pci_config_dword = amdgpu_cgs_write_pci_config_dword,
amdgpu_cgs_get_pci_resource, .get_pci_resource = amdgpu_cgs_get_pci_resource,
amdgpu_cgs_atom_get_data_table, .atom_get_data_table = amdgpu_cgs_atom_get_data_table,
amdgpu_cgs_atom_get_cmd_table_revs, .atom_get_cmd_table_revs = amdgpu_cgs_atom_get_cmd_table_revs,
amdgpu_cgs_atom_exec_cmd_table, .atom_exec_cmd_table = amdgpu_cgs_atom_exec_cmd_table,
amdgpu_cgs_create_pm_request, .create_pm_request = amdgpu_cgs_create_pm_request,
amdgpu_cgs_destroy_pm_request, .destroy_pm_request = amdgpu_cgs_destroy_pm_request,
amdgpu_cgs_set_pm_request, .set_pm_request = amdgpu_cgs_set_pm_request,
amdgpu_cgs_pm_request_clock, .pm_request_clock = amdgpu_cgs_pm_request_clock,
amdgpu_cgs_pm_request_engine, .pm_request_engine = amdgpu_cgs_pm_request_engine,
amdgpu_cgs_pm_query_clock_limits, .pm_query_clock_limits = amdgpu_cgs_pm_query_clock_limits,
amdgpu_cgs_set_camera_voltages, .set_camera_voltages = amdgpu_cgs_set_camera_voltages,
amdgpu_cgs_get_firmware_info, .get_firmware_info = amdgpu_cgs_get_firmware_info,
amdgpu_cgs_rel_firmware, .rel_firmware = amdgpu_cgs_rel_firmware,
amdgpu_cgs_set_powergating_state, .set_powergating_state = amdgpu_cgs_set_powergating_state,
amdgpu_cgs_set_clockgating_state, .set_clockgating_state = amdgpu_cgs_set_clockgating_state,
amdgpu_cgs_get_active_displays_info, .get_active_displays_info = amdgpu_cgs_get_active_displays_info,
amdgpu_cgs_notify_dpm_enabled, .notify_dpm_enabled = amdgpu_cgs_notify_dpm_enabled,
amdgpu_cgs_call_acpi_method, .call_acpi_method = amdgpu_cgs_call_acpi_method,
amdgpu_cgs_query_system_info, .query_system_info = amdgpu_cgs_query_system_info,
amdgpu_cgs_is_virtualization_enabled .is_virtualization_enabled = amdgpu_cgs_is_virtualization_enabled,
.enter_safe_mode = amdgpu_cgs_enter_safe_mode,
}; };
static const struct cgs_os_ops amdgpu_cgs_os_ops = { static const struct cgs_os_ops amdgpu_cgs_os_ops = {
amdgpu_cgs_add_irq_source, .add_irq_source = amdgpu_cgs_add_irq_source,
amdgpu_cgs_irq_get, .irq_get = amdgpu_cgs_irq_get,
amdgpu_cgs_irq_put .irq_put = amdgpu_cgs_irq_put
}; };
struct cgs_device *amdgpu_cgs_create_device(struct amdgpu_device *adev) struct cgs_device *amdgpu_cgs_create_device(struct amdgpu_device *adev)
......
...@@ -75,10 +75,10 @@ int amdgpu_cs_get_ring(struct amdgpu_device *adev, u32 ip_type, ...@@ -75,10 +75,10 @@ int amdgpu_cs_get_ring(struct amdgpu_device *adev, u32 ip_type,
*out_ring = &adev->uvd.ring; *out_ring = &adev->uvd.ring;
break; break;
case AMDGPU_HW_IP_VCE: case AMDGPU_HW_IP_VCE:
if (ring < 2){ if (ring < adev->vce.num_rings){
*out_ring = &adev->vce.ring[ring]; *out_ring = &adev->vce.ring[ring];
} else { } else {
DRM_ERROR("only two VCE rings are supported\n"); DRM_ERROR("only %d VCE rings are supported\n", adev->vce.num_rings);
return -EINVAL; return -EINVAL;
} }
break; break;
...@@ -771,6 +771,20 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, ...@@ -771,6 +771,20 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p,
if (r) if (r)
return r; return r;
if (amdgpu_sriov_vf(adev)) {
struct dma_fence *f;
bo_va = vm->csa_bo_va;
BUG_ON(!bo_va);
r = amdgpu_vm_bo_update(adev, bo_va, false);
if (r)
return r;
f = bo_va->last_pt_update;
r = amdgpu_sync_fence(adev, &p->job->sync, f);
if (r)
return r;
}
if (p->bo_list) { if (p->bo_list) {
for (i = 0; i < p->bo_list->num_entries; i++) { for (i = 0; i < p->bo_list->num_entries; i++) {
struct dma_fence *f; struct dma_fence *f;
......
...@@ -94,6 +94,11 @@ uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg, ...@@ -94,6 +94,11 @@ uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg,
{ {
uint32_t ret; uint32_t ret;
if (amdgpu_sriov_runtime(adev)) {
BUG_ON(in_interrupt());
return amdgpu_virt_kiq_rreg(adev, reg);
}
if ((reg * 4) < adev->rmmio_size && !always_indirect) if ((reg * 4) < adev->rmmio_size && !always_indirect)
ret = readl(((void __iomem *)adev->rmmio) + (reg * 4)); ret = readl(((void __iomem *)adev->rmmio) + (reg * 4));
else { else {
...@@ -113,6 +118,11 @@ void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v, ...@@ -113,6 +118,11 @@ void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
{ {
trace_amdgpu_mm_wreg(adev->pdev->device, reg, v); trace_amdgpu_mm_wreg(adev->pdev->device, reg, v);
if (amdgpu_sriov_runtime(adev)) {
BUG_ON(in_interrupt());
return amdgpu_virt_kiq_wreg(adev, reg, v);
}
if ((reg * 4) < adev->rmmio_size && !always_indirect) if ((reg * 4) < adev->rmmio_size && !always_indirect)
writel(v, ((void __iomem *)adev->rmmio) + (reg * 4)); writel(v, ((void __iomem *)adev->rmmio) + (reg * 4));
else { else {
...@@ -885,7 +895,7 @@ static int amdgpu_atombios_init(struct amdgpu_device *adev) ...@@ -885,7 +895,7 @@ static int amdgpu_atombios_init(struct amdgpu_device *adev)
atom_card_info->ioreg_read = cail_ioreg_read; atom_card_info->ioreg_read = cail_ioreg_read;
atom_card_info->ioreg_write = cail_ioreg_write; atom_card_info->ioreg_write = cail_ioreg_write;
} else { } else {
DRM_ERROR("Unable to find PCI I/O BAR; using MMIO for ATOM IIO\n"); DRM_INFO("PCI I/O BAR is not found. Using MMIO to access ATOM BIOS\n");
atom_card_info->ioreg_read = cail_reg_read; atom_card_info->ioreg_read = cail_reg_read;
atom_card_info->ioreg_write = cail_reg_write; atom_card_info->ioreg_write = cail_reg_write;
} }
...@@ -1131,6 +1141,18 @@ int amdgpu_set_powergating_state(struct amdgpu_device *adev, ...@@ -1131,6 +1141,18 @@ int amdgpu_set_powergating_state(struct amdgpu_device *adev,
return r; return r;
} }
void amdgpu_get_clockgating_state(struct amdgpu_device *adev, u32 *flags)
{
int i;
for (i = 0; i < adev->num_ip_blocks; i++) {
if (!adev->ip_blocks[i].status.valid)
continue;
if (adev->ip_blocks[i].version->funcs->get_clockgating_state)
adev->ip_blocks[i].version->funcs->get_clockgating_state((void *)adev, flags);
}
}
int amdgpu_wait_for_idle(struct amdgpu_device *adev, int amdgpu_wait_for_idle(struct amdgpu_device *adev,
enum amd_ip_block_type block_type) enum amd_ip_block_type block_type)
{ {
...@@ -1235,7 +1257,8 @@ static void amdgpu_device_enable_virtual_display(struct amdgpu_device *adev) ...@@ -1235,7 +1257,8 @@ static void amdgpu_device_enable_virtual_display(struct amdgpu_device *adev)
pciaddstr_tmp = pciaddstr; pciaddstr_tmp = pciaddstr;
while ((pciaddname_tmp = strsep(&pciaddstr_tmp, ";"))) { while ((pciaddname_tmp = strsep(&pciaddstr_tmp, ";"))) {
pciaddname = strsep(&pciaddname_tmp, ","); pciaddname = strsep(&pciaddname_tmp, ",");
if (!strcmp(pci_address_name, pciaddname)) { if (!strcmp("all", pciaddname)
|| !strcmp(pci_address_name, pciaddname)) {
long num_crtc; long num_crtc;
int res = -1; int res = -1;
...@@ -1323,6 +1346,12 @@ static int amdgpu_early_init(struct amdgpu_device *adev) ...@@ -1323,6 +1346,12 @@ static int amdgpu_early_init(struct amdgpu_device *adev)
return -EINVAL; return -EINVAL;
} }
if (amdgpu_sriov_vf(adev)) {
r = amdgpu_virt_request_full_gpu(adev, true);
if (r)
return r;
}
for (i = 0; i < adev->num_ip_blocks; i++) { for (i = 0; i < adev->num_ip_blocks; i++) {
if ((amdgpu_ip_block_mask & (1 << i)) == 0) { if ((amdgpu_ip_block_mask & (1 << i)) == 0) {
DRM_ERROR("disabled ip block: %d\n", i); DRM_ERROR("disabled ip block: %d\n", i);
...@@ -1383,6 +1412,15 @@ static int amdgpu_init(struct amdgpu_device *adev) ...@@ -1383,6 +1412,15 @@ static int amdgpu_init(struct amdgpu_device *adev)
return r; return r;
} }
adev->ip_blocks[i].status.hw = true; adev->ip_blocks[i].status.hw = true;
/* right after GMC hw init, we create CSA */
if (amdgpu_sriov_vf(adev)) {
r = amdgpu_allocate_static_csa(adev);
if (r) {
DRM_ERROR("allocate CSA failed %d\n", r);
return r;
}
}
} }
} }
...@@ -1516,6 +1554,11 @@ static int amdgpu_fini(struct amdgpu_device *adev) ...@@ -1516,6 +1554,11 @@ static int amdgpu_fini(struct amdgpu_device *adev)
adev->ip_blocks[i].status.late_initialized = false; adev->ip_blocks[i].status.late_initialized = false;
} }
if (amdgpu_sriov_vf(adev)) {
amdgpu_bo_free_kernel(&adev->virt.csa_obj, &adev->virt.csa_vmid0_addr, NULL);
amdgpu_virt_release_full_gpu(adev, false);
}
return 0; return 0;
} }
...@@ -1523,6 +1566,9 @@ int amdgpu_suspend(struct amdgpu_device *adev) ...@@ -1523,6 +1566,9 @@ int amdgpu_suspend(struct amdgpu_device *adev)
{ {
int i, r; int i, r;
if (amdgpu_sriov_vf(adev))
amdgpu_virt_request_full_gpu(adev, false);
/* ungate SMC block first */ /* ungate SMC block first */
r = amdgpu_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_SMC, r = amdgpu_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_SMC,
AMD_CG_STATE_UNGATE); AMD_CG_STATE_UNGATE);
...@@ -1551,6 +1597,9 @@ int amdgpu_suspend(struct amdgpu_device *adev) ...@@ -1551,6 +1597,9 @@ int amdgpu_suspend(struct amdgpu_device *adev)
} }
} }
if (amdgpu_sriov_vf(adev))
amdgpu_virt_release_full_gpu(adev, false);
return 0; return 0;
} }
...@@ -1575,7 +1624,7 @@ static int amdgpu_resume(struct amdgpu_device *adev) ...@@ -1575,7 +1624,7 @@ static int amdgpu_resume(struct amdgpu_device *adev)
static void amdgpu_device_detect_sriov_bios(struct amdgpu_device *adev) static void amdgpu_device_detect_sriov_bios(struct amdgpu_device *adev)
{ {
if (amdgpu_atombios_has_gpu_virtualization_table(adev)) if (amdgpu_atombios_has_gpu_virtualization_table(adev))
adev->virtualization.virtual_caps |= AMDGPU_SRIOV_CAPS_SRIOV_VBIOS; adev->virt.caps |= AMDGPU_SRIOV_CAPS_SRIOV_VBIOS;
} }
/** /**
...@@ -1605,7 +1654,6 @@ int amdgpu_device_init(struct amdgpu_device *adev, ...@@ -1605,7 +1654,6 @@ int amdgpu_device_init(struct amdgpu_device *adev,
adev->pdev = pdev; adev->pdev = pdev;
adev->flags = flags; adev->flags = flags;
adev->asic_type = flags & AMD_ASIC_MASK; adev->asic_type = flags & AMD_ASIC_MASK;
adev->is_atom_bios = false;
adev->usec_timeout = AMDGPU_MAX_USEC_TIMEOUT; adev->usec_timeout = AMDGPU_MAX_USEC_TIMEOUT;
adev->mc.gtt_size = 512 * 1024 * 1024; adev->mc.gtt_size = 512 * 1024 * 1024;
adev->accel_working = false; adev->accel_working = false;
...@@ -1695,7 +1743,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, ...@@ -1695,7 +1743,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
} }
} }
if (adev->rio_mem == NULL) if (adev->rio_mem == NULL)
DRM_ERROR("Unable to find PCI I/O BAR\n"); DRM_INFO("PCI I/O BAR is not found.\n");
/* early init functions */ /* early init functions */
r = amdgpu_early_init(adev); r = amdgpu_early_init(adev);
...@@ -1720,12 +1768,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, ...@@ -1720,12 +1768,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
r = -EINVAL; r = -EINVAL;
goto failed; goto failed;
} }
/* Must be an ATOMBIOS */
if (!adev->is_atom_bios) {
dev_err(adev->dev, "Expecting atombios for GPU\n");
r = -EINVAL;
goto failed;
}
r = amdgpu_atombios_init(adev); r = amdgpu_atombios_init(adev);
if (r) { if (r) {
dev_err(adev->dev, "amdgpu_atombios_init failed\n"); dev_err(adev->dev, "amdgpu_atombios_init failed\n");
...@@ -2249,6 +2292,9 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev) ...@@ -2249,6 +2292,9 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev)
int resched; int resched;
bool need_full_reset; bool need_full_reset;
if (amdgpu_sriov_vf(adev))
return 0;
if (!amdgpu_check_soft_reset(adev)) { if (!amdgpu_check_soft_reset(adev)) {
DRM_INFO("No hardware hang detected. Did some blocks stall?\n"); DRM_INFO("No hardware hang detected. Did some blocks stall?\n");
return 0; return 0;
...@@ -2837,7 +2883,7 @@ static ssize_t amdgpu_debugfs_gca_config_read(struct file *f, char __user *buf, ...@@ -2837,7 +2883,7 @@ static ssize_t amdgpu_debugfs_gca_config_read(struct file *f, char __user *buf,
return -ENOMEM; return -ENOMEM;
/* version, increment each time something is added */ /* version, increment each time something is added */
config[no_regs++] = 2; config[no_regs++] = 3;
config[no_regs++] = adev->gfx.config.max_shader_engines; config[no_regs++] = adev->gfx.config.max_shader_engines;
config[no_regs++] = adev->gfx.config.max_tile_pipes; config[no_regs++] = adev->gfx.config.max_tile_pipes;
config[no_regs++] = adev->gfx.config.max_cu_per_sh; config[no_regs++] = adev->gfx.config.max_cu_per_sh;
...@@ -2871,6 +2917,12 @@ static ssize_t amdgpu_debugfs_gca_config_read(struct file *f, char __user *buf, ...@@ -2871,6 +2917,12 @@ static ssize_t amdgpu_debugfs_gca_config_read(struct file *f, char __user *buf,
config[no_regs++] = adev->family; config[no_regs++] = adev->family;
config[no_regs++] = adev->external_rev_id; config[no_regs++] = adev->external_rev_id;
/* rev==3 */
config[no_regs++] = adev->pdev->device;
config[no_regs++] = adev->pdev->revision;
config[no_regs++] = adev->pdev->subsystem_device;
config[no_regs++] = adev->pdev->subsystem_vendor;
while (size && (*pos < no_regs * 4)) { while (size && (*pos < no_regs * 4)) {
uint32_t value; uint32_t value;
......
...@@ -138,10 +138,52 @@ static void amdgpu_unpin_work_func(struct work_struct *__work) ...@@ -138,10 +138,52 @@ static void amdgpu_unpin_work_func(struct work_struct *__work)
kfree(work); kfree(work);
} }
int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc,
struct drm_framebuffer *fb, static void amdgpu_flip_work_cleanup(struct amdgpu_flip_work *work)
struct drm_pending_vblank_event *event, {
uint32_t page_flip_flags, uint32_t target) int i;
amdgpu_bo_unref(&work->old_abo);
dma_fence_put(work->excl);
for (i = 0; i < work->shared_count; ++i)
dma_fence_put(work->shared[i]);
kfree(work->shared);
kfree(work);
}
static void amdgpu_flip_cleanup_unreserve(struct amdgpu_flip_work *work,
struct amdgpu_bo *new_abo)
{
amdgpu_bo_unreserve(new_abo);
amdgpu_flip_work_cleanup(work);
}
static void amdgpu_flip_cleanup_unpin(struct amdgpu_flip_work *work,
struct amdgpu_bo *new_abo)
{
if (unlikely(amdgpu_bo_unpin(new_abo) != 0))
DRM_ERROR("failed to unpin new abo in error path\n");
amdgpu_flip_cleanup_unreserve(work, new_abo);
}
void amdgpu_crtc_cleanup_flip_ctx(struct amdgpu_flip_work *work,
struct amdgpu_bo *new_abo)
{
if (unlikely(amdgpu_bo_reserve(new_abo, false) != 0)) {
DRM_ERROR("failed to reserve new abo in error path\n");
amdgpu_flip_work_cleanup(work);
return;
}
amdgpu_flip_cleanup_unpin(work, new_abo);
}
int amdgpu_crtc_prepare_flip(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event,
uint32_t page_flip_flags,
uint32_t target,
struct amdgpu_flip_work **work_p,
struct amdgpu_bo **new_abo_p)
{ {
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct amdgpu_device *adev = dev->dev_private; struct amdgpu_device *adev = dev->dev_private;
...@@ -154,7 +196,7 @@ int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc, ...@@ -154,7 +196,7 @@ int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc,
unsigned long flags; unsigned long flags;
u64 tiling_flags; u64 tiling_flags;
u64 base; u64 base;
int i, r; int r;
work = kzalloc(sizeof *work, GFP_KERNEL); work = kzalloc(sizeof *work, GFP_KERNEL);
if (work == NULL) if (work == NULL)
...@@ -189,7 +231,6 @@ int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc, ...@@ -189,7 +231,6 @@ int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc,
r = amdgpu_bo_pin(new_abo, AMDGPU_GEM_DOMAIN_VRAM, &base); r = amdgpu_bo_pin(new_abo, AMDGPU_GEM_DOMAIN_VRAM, &base);
if (unlikely(r != 0)) { if (unlikely(r != 0)) {
r = -EINVAL;
DRM_ERROR("failed to pin new abo buffer before flip\n"); DRM_ERROR("failed to pin new abo buffer before flip\n");
goto unreserve; goto unreserve;
} }
...@@ -216,41 +257,79 @@ int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc, ...@@ -216,41 +257,79 @@ int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc,
spin_unlock_irqrestore(&crtc->dev->event_lock, flags); spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
r = -EBUSY; r = -EBUSY;
goto pflip_cleanup; goto pflip_cleanup;
} }
spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
*work_p = work;
*new_abo_p = new_abo;
return 0;
pflip_cleanup:
amdgpu_crtc_cleanup_flip_ctx(work, new_abo);
return r;
unpin:
amdgpu_flip_cleanup_unpin(work, new_abo);
return r;
unreserve:
amdgpu_flip_cleanup_unreserve(work, new_abo);
return r;
cleanup:
amdgpu_flip_work_cleanup(work);
return r;
}
void amdgpu_crtc_submit_flip(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct amdgpu_flip_work *work,
struct amdgpu_bo *new_abo)
{
unsigned long flags;
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
spin_lock_irqsave(&crtc->dev->event_lock, flags);
amdgpu_crtc->pflip_status = AMDGPU_FLIP_PENDING; amdgpu_crtc->pflip_status = AMDGPU_FLIP_PENDING;
amdgpu_crtc->pflip_works = work; amdgpu_crtc->pflip_works = work;
DRM_DEBUG_DRIVER("crtc:%d[%p], pflip_stat:AMDGPU_FLIP_PENDING, work: %p,\n",
amdgpu_crtc->crtc_id, amdgpu_crtc, work);
/* update crtc fb */ /* update crtc fb */
crtc->primary->fb = fb; crtc->primary->fb = fb;
spin_unlock_irqrestore(&crtc->dev->event_lock, flags); spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
DRM_DEBUG_DRIVER(
"crtc:%d[%p], pflip_stat:AMDGPU_FLIP_PENDING, work: %p,\n",
amdgpu_crtc->crtc_id, amdgpu_crtc, work);
amdgpu_flip_work_func(&work->flip_work.work); amdgpu_flip_work_func(&work->flip_work.work);
return 0; }
pflip_cleanup: int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc,
if (unlikely(amdgpu_bo_reserve(new_abo, false) != 0)) { struct drm_framebuffer *fb,
DRM_ERROR("failed to reserve new abo in error path\n"); struct drm_pending_vblank_event *event,
goto cleanup; uint32_t page_flip_flags,
} uint32_t target)
unpin: {
if (unlikely(amdgpu_bo_unpin(new_abo) != 0)) { struct amdgpu_bo *new_abo;
DRM_ERROR("failed to unpin new abo in error path\n"); struct amdgpu_flip_work *work;
} int r;
unreserve:
amdgpu_bo_unreserve(new_abo);
cleanup: r = amdgpu_crtc_prepare_flip(crtc,
amdgpu_bo_unref(&work->old_abo); fb,
dma_fence_put(work->excl); event,
for (i = 0; i < work->shared_count; ++i) page_flip_flags,
dma_fence_put(work->shared[i]); target,
kfree(work->shared); &work,
kfree(work); &new_abo);
if (r)
return r;
return r; amdgpu_crtc_submit_flip(crtc, fb, work, new_abo);
return 0;
} }
int amdgpu_crtc_set_config(struct drm_mode_set *set) int amdgpu_crtc_set_config(struct drm_mode_set *set)
...@@ -582,12 +661,10 @@ int amdgpu_modeset_create_props(struct amdgpu_device *adev) ...@@ -582,12 +661,10 @@ int amdgpu_modeset_create_props(struct amdgpu_device *adev)
{ {
int sz; int sz;
if (adev->is_atom_bios) { adev->mode_info.coherent_mode_property =
adev->mode_info.coherent_mode_property = drm_property_create_range(adev->ddev, 0 , "coherent", 0, 1);
drm_property_create_range(adev->ddev, 0 , "coherent", 0, 1); if (!adev->mode_info.coherent_mode_property)
if (!adev->mode_info.coherent_mode_property) return -ENOMEM;
return -ENOMEM;
}
adev->mode_info.load_detect_property = adev->mode_info.load_detect_property =
drm_property_create_range(adev->ddev, 0, "load detection", 0, 1); drm_property_create_range(adev->ddev, 0, "load detection", 0, 1);
......
...@@ -241,13 +241,6 @@ enum amdgpu_pcie_gen { ...@@ -241,13 +241,6 @@ enum amdgpu_pcie_gen {
AMDGPU_PCIE_GEN_INVALID = 0xffff AMDGPU_PCIE_GEN_INVALID = 0xffff
}; };
enum amdgpu_dpm_forced_level {
AMDGPU_DPM_FORCED_LEVEL_AUTO = 0,
AMDGPU_DPM_FORCED_LEVEL_LOW = 1,
AMDGPU_DPM_FORCED_LEVEL_HIGH = 2,
AMDGPU_DPM_FORCED_LEVEL_MANUAL = 3,
};
struct amdgpu_dpm_funcs { struct amdgpu_dpm_funcs {
int (*get_temperature)(struct amdgpu_device *adev); int (*get_temperature)(struct amdgpu_device *adev);
int (*pre_set_power_state)(struct amdgpu_device *adev); int (*pre_set_power_state)(struct amdgpu_device *adev);
...@@ -258,7 +251,7 @@ struct amdgpu_dpm_funcs { ...@@ -258,7 +251,7 @@ struct amdgpu_dpm_funcs {
u32 (*get_mclk)(struct amdgpu_device *adev, bool low); u32 (*get_mclk)(struct amdgpu_device *adev, bool low);
void (*print_power_state)(struct amdgpu_device *adev, struct amdgpu_ps *ps); void (*print_power_state)(struct amdgpu_device *adev, struct amdgpu_ps *ps);
void (*debugfs_print_current_performance_level)(struct amdgpu_device *adev, struct seq_file *m); void (*debugfs_print_current_performance_level)(struct amdgpu_device *adev, struct seq_file *m);
int (*force_performance_level)(struct amdgpu_device *adev, enum amdgpu_dpm_forced_level level); int (*force_performance_level)(struct amdgpu_device *adev, enum amd_dpm_forced_level level);
bool (*vblank_too_short)(struct amdgpu_device *adev); bool (*vblank_too_short)(struct amdgpu_device *adev);
void (*powergate_uvd)(struct amdgpu_device *adev, bool gate); void (*powergate_uvd)(struct amdgpu_device *adev, bool gate);
void (*powergate_vce)(struct amdgpu_device *adev, bool gate); void (*powergate_vce)(struct amdgpu_device *adev, bool gate);
...@@ -353,9 +346,6 @@ struct amdgpu_dpm_funcs { ...@@ -353,9 +346,6 @@ struct amdgpu_dpm_funcs {
#define amdgpu_dpm_get_current_power_state(adev) \ #define amdgpu_dpm_get_current_power_state(adev) \
(adev)->powerplay.pp_funcs->get_current_power_state((adev)->powerplay.pp_handle) (adev)->powerplay.pp_funcs->get_current_power_state((adev)->powerplay.pp_handle)
#define amdgpu_dpm_get_performance_level(adev) \
(adev)->powerplay.pp_funcs->get_performance_level((adev)->powerplay.pp_handle)
#define amdgpu_dpm_get_pp_num_states(adev, data) \ #define amdgpu_dpm_get_pp_num_states(adev, data) \
(adev)->powerplay.pp_funcs->get_pp_num_states((adev)->powerplay.pp_handle, data) (adev)->powerplay.pp_funcs->get_pp_num_states((adev)->powerplay.pp_handle, data)
...@@ -393,6 +383,11 @@ struct amdgpu_dpm_funcs { ...@@ -393,6 +383,11 @@ struct amdgpu_dpm_funcs {
(adev)->powerplay.pp_funcs->get_vce_clock_state((adev)->powerplay.pp_handle, (i)) : \ (adev)->powerplay.pp_funcs->get_vce_clock_state((adev)->powerplay.pp_handle, (i)) : \
(adev)->pm.funcs->get_vce_clock_state((adev), (i))) (adev)->pm.funcs->get_vce_clock_state((adev), (i)))
#define amdgpu_dpm_get_performance_level(adev) \
((adev)->pp_enabled ? \
(adev)->powerplay.pp_funcs->get_performance_level((adev)->powerplay.pp_handle) : \
(adev)->pm.dpm.forced_level)
struct amdgpu_dpm { struct amdgpu_dpm {
struct amdgpu_ps *ps; struct amdgpu_ps *ps;
/* number of valid power states */ /* number of valid power states */
...@@ -440,7 +435,7 @@ struct amdgpu_dpm { ...@@ -440,7 +435,7 @@ struct amdgpu_dpm {
/* thermal handling */ /* thermal handling */
struct amdgpu_dpm_thermal thermal; struct amdgpu_dpm_thermal thermal;
/* forced levels */ /* forced levels */
enum amdgpu_dpm_forced_level forced_level; enum amd_dpm_forced_level forced_level;
}; };
struct amdgpu_pm { struct amdgpu_pm {
......
...@@ -90,7 +90,6 @@ int amdgpu_vram_page_split = 1024; ...@@ -90,7 +90,6 @@ int amdgpu_vram_page_split = 1024;
int amdgpu_exp_hw_support = 0; int amdgpu_exp_hw_support = 0;
int amdgpu_sched_jobs = 32; int amdgpu_sched_jobs = 32;
int amdgpu_sched_hw_submission = 2; int amdgpu_sched_hw_submission = 2;
int amdgpu_powerplay = -1;
int amdgpu_no_evict = 0; int amdgpu_no_evict = 0;
int amdgpu_direct_gma_size = 0; int amdgpu_direct_gma_size = 0;
unsigned amdgpu_pcie_gen_cap = 0; unsigned amdgpu_pcie_gen_cap = 0;
...@@ -179,9 +178,6 @@ module_param_named(sched_jobs, amdgpu_sched_jobs, int, 0444); ...@@ -179,9 +178,6 @@ module_param_named(sched_jobs, amdgpu_sched_jobs, int, 0444);
MODULE_PARM_DESC(sched_hw_submission, "the max number of HW submissions (default 2)"); MODULE_PARM_DESC(sched_hw_submission, "the max number of HW submissions (default 2)");
module_param_named(sched_hw_submission, amdgpu_sched_hw_submission, int, 0444); module_param_named(sched_hw_submission, amdgpu_sched_hw_submission, int, 0444);
MODULE_PARM_DESC(powerplay, "Powerplay component (1 = enable, 0 = disable, -1 = auto (default))");
module_param_named(powerplay, amdgpu_powerplay, int, 0444);
MODULE_PARM_DESC(ppfeaturemask, "all power features enabled (default))"); MODULE_PARM_DESC(ppfeaturemask, "all power features enabled (default))");
module_param_named(ppfeaturemask, amdgpu_pp_feature_mask, int, 0444); module_param_named(ppfeaturemask, amdgpu_pp_feature_mask, int, 0444);
......
...@@ -471,12 +471,15 @@ int amdgpu_gem_metadata_ioctl(struct drm_device *dev, void *data, ...@@ -471,12 +471,15 @@ int amdgpu_gem_metadata_ioctl(struct drm_device *dev, void *data,
static int amdgpu_gem_va_check(void *param, struct amdgpu_bo *bo) static int amdgpu_gem_va_check(void *param, struct amdgpu_bo *bo)
{ {
unsigned domain = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type);
/* if anything is swapped out don't swap it in here, /* if anything is swapped out don't swap it in here,
just abort and wait for the next CS */ just abort and wait for the next CS */
if (!amdgpu_bo_gpu_accessible(bo))
return -ERESTARTSYS;
if (bo->shadow && !amdgpu_bo_gpu_accessible(bo->shadow))
return -ERESTARTSYS;
return domain == AMDGPU_GEM_DOMAIN_CPU ? -ERESTARTSYS : 0; return 0;
} }
/** /**
...@@ -496,7 +499,6 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev, ...@@ -496,7 +499,6 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
struct amdgpu_bo_list_entry vm_pd; struct amdgpu_bo_list_entry vm_pd;
struct ww_acquire_ctx ticket; struct ww_acquire_ctx ticket;
struct list_head list, duplicates; struct list_head list, duplicates;
unsigned domain;
int r; int r;
INIT_LIST_HEAD(&list); INIT_LIST_HEAD(&list);
...@@ -514,12 +516,18 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev, ...@@ -514,12 +516,18 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
goto error_print; goto error_print;
list_for_each_entry(entry, &list, head) { list_for_each_entry(entry, &list, head) {
domain = amdgpu_mem_type_to_domain(entry->bo->mem.mem_type); struct amdgpu_bo *bo =
container_of(entry->bo, struct amdgpu_bo, tbo);
/* if anything is swapped out don't swap it in here, /* if anything is swapped out don't swap it in here,
just abort and wait for the next CS */ just abort and wait for the next CS */
if (domain == AMDGPU_GEM_DOMAIN_CPU) if (!amdgpu_bo_gpu_accessible(bo))
goto error_unreserve;
if (bo->shadow && !amdgpu_bo_gpu_accessible(bo->shadow))
goto error_unreserve; goto error_unreserve;
} }
r = amdgpu_vm_validate_pt_bos(adev, bo_va->vm, amdgpu_gem_va_check, r = amdgpu_vm_validate_pt_bos(adev, bo_va->vm, amdgpu_gem_va_check,
NULL); NULL);
if (r) if (r)
......
...@@ -42,12 +42,12 @@ int amdgpu_gfx_scratch_get(struct amdgpu_device *adev, uint32_t *reg) ...@@ -42,12 +42,12 @@ int amdgpu_gfx_scratch_get(struct amdgpu_device *adev, uint32_t *reg)
{ {
int i; int i;
for (i = 0; i < adev->gfx.scratch.num_reg; i++) { i = ffs(adev->gfx.scratch.free_mask);
if (adev->gfx.scratch.free[i]) { if (i != 0 && i <= adev->gfx.scratch.num_reg) {
adev->gfx.scratch.free[i] = false; i--;
*reg = adev->gfx.scratch.reg[i]; adev->gfx.scratch.free_mask &= ~(1u << i);
return 0; *reg = adev->gfx.scratch.reg_base + i;
} return 0;
} }
return -EINVAL; return -EINVAL;
} }
...@@ -62,14 +62,7 @@ int amdgpu_gfx_scratch_get(struct amdgpu_device *adev, uint32_t *reg) ...@@ -62,14 +62,7 @@ int amdgpu_gfx_scratch_get(struct amdgpu_device *adev, uint32_t *reg)
*/ */
void amdgpu_gfx_scratch_free(struct amdgpu_device *adev, uint32_t reg) void amdgpu_gfx_scratch_free(struct amdgpu_device *adev, uint32_t reg)
{ {
int i; adev->gfx.scratch.free_mask |= 1u << (reg - adev->gfx.scratch.reg_base);
for (i = 0; i < adev->gfx.scratch.num_reg; i++) {
if (adev->gfx.scratch.reg[i] == reg) {
adev->gfx.scratch.free[i] = true;
return;
}
}
} }
/** /**
......
...@@ -243,9 +243,9 @@ static void amdgpu_gtt_mgr_debug(struct ttm_mem_type_manager *man, ...@@ -243,9 +243,9 @@ static void amdgpu_gtt_mgr_debug(struct ttm_mem_type_manager *man,
} }
const struct ttm_mem_type_manager_func amdgpu_gtt_mgr_func = { const struct ttm_mem_type_manager_func amdgpu_gtt_mgr_func = {
amdgpu_gtt_mgr_init, .init = amdgpu_gtt_mgr_init,
amdgpu_gtt_mgr_fini, .takedown = amdgpu_gtt_mgr_fini,
amdgpu_gtt_mgr_new, .get_node = amdgpu_gtt_mgr_new,
amdgpu_gtt_mgr_del, .put_node = amdgpu_gtt_mgr_del,
amdgpu_gtt_mgr_debug .debug = amdgpu_gtt_mgr_debug
}; };
...@@ -231,8 +231,7 @@ void amdgpu_i2c_init(struct amdgpu_device *adev) ...@@ -231,8 +231,7 @@ void amdgpu_i2c_init(struct amdgpu_device *adev)
if (amdgpu_hw_i2c) if (amdgpu_hw_i2c)
DRM_INFO("hw_i2c forced on, you may experience display detection problems!\n"); DRM_INFO("hw_i2c forced on, you may experience display detection problems!\n");
if (adev->is_atom_bios) amdgpu_atombios_i2c_init(adev);
amdgpu_atombios_i2c_init(adev);
} }
/* remove all the buses */ /* remove all the buses */
......
...@@ -116,8 +116,8 @@ void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib, ...@@ -116,8 +116,8 @@ void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib,
* to SI there was just a DE IB. * to SI there was just a DE IB.
*/ */
int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
struct amdgpu_ib *ibs, struct dma_fence *last_vm_update, struct amdgpu_ib *ibs, struct amdgpu_job *job,
struct amdgpu_job *job, struct dma_fence **f) struct dma_fence **f)
{ {
struct amdgpu_device *adev = ring->adev; struct amdgpu_device *adev = ring->adev;
struct amdgpu_ib *ib = &ibs[0]; struct amdgpu_ib *ib = &ibs[0];
...@@ -175,15 +175,15 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, ...@@ -175,15 +175,15 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
if (ring->funcs->emit_hdp_flush) if (ring->funcs->emit_hdp_flush)
amdgpu_ring_emit_hdp_flush(ring); amdgpu_ring_emit_hdp_flush(ring);
/* always set cond_exec_polling to CONTINUE */
*ring->cond_exe_cpu_addr = 1;
skip_preamble = ring->current_ctx == fence_ctx; skip_preamble = ring->current_ctx == fence_ctx;
need_ctx_switch = ring->current_ctx != fence_ctx; need_ctx_switch = ring->current_ctx != fence_ctx;
if (job && ring->funcs->emit_cntxcntl) { if (job && ring->funcs->emit_cntxcntl) {
if (need_ctx_switch) if (need_ctx_switch)
status |= AMDGPU_HAVE_CTX_SWITCH; status |= AMDGPU_HAVE_CTX_SWITCH;
status |= job->preamble_status; status |= job->preamble_status;
if (vm)
status |= AMDGPU_VM_DOMAIN;
amdgpu_ring_emit_cntxcntl(ring, status); amdgpu_ring_emit_cntxcntl(ring, status);
} }
...@@ -193,7 +193,8 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, ...@@ -193,7 +193,8 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
/* drop preamble IBs if we don't have a context switch */ /* drop preamble IBs if we don't have a context switch */
if ((ib->flags & AMDGPU_IB_FLAG_PREAMBLE) && if ((ib->flags & AMDGPU_IB_FLAG_PREAMBLE) &&
skip_preamble && skip_preamble &&
!(status & AMDGPU_PREAMBLE_IB_PRESENT_FIRST)) !(status & AMDGPU_PREAMBLE_IB_PRESENT_FIRST) &&
!amdgpu_sriov_vf(adev)) /* for SRIOV preemption, Preamble CE ib must be inserted anyway */
continue; continue;
amdgpu_ring_emit_ib(ring, ib, job ? job->vm_id : 0, amdgpu_ring_emit_ib(ring, ib, job ? job->vm_id : 0,
...@@ -223,7 +224,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, ...@@ -223,7 +224,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
amdgpu_ring_patch_cond_exec(ring, patch_offset); amdgpu_ring_patch_cond_exec(ring, patch_offset);
ring->current_ctx = fence_ctx; ring->current_ctx = fence_ctx;
if (ring->funcs->emit_switch_buffer) if (vm && ring->funcs->emit_switch_buffer)
amdgpu_ring_emit_switch_buffer(ring); amdgpu_ring_emit_switch_buffer(ring);
amdgpu_ring_commit(ring); amdgpu_ring_commit(ring);
return 0; return 0;
......
...@@ -170,8 +170,7 @@ static struct dma_fence *amdgpu_job_run(struct amd_sched_job *sched_job) ...@@ -170,8 +170,7 @@ static struct dma_fence *amdgpu_job_run(struct amd_sched_job *sched_job)
BUG_ON(amdgpu_sync_peek_fence(&job->sync, NULL)); BUG_ON(amdgpu_sync_peek_fence(&job->sync, NULL));
trace_amdgpu_sched_run_job(job); trace_amdgpu_sched_run_job(job);
r = amdgpu_ib_schedule(job->ring, job->num_ibs, job->ibs, r = amdgpu_ib_schedule(job->ring, job->num_ibs, job->ibs, job, &fence);
job->sync.last_vm_update, job, &fence);
if (r) if (r)
DRM_ERROR("Error scheduling IBs (%d)\n", r); DRM_ERROR("Error scheduling IBs (%d)\n", r);
......
...@@ -60,6 +60,9 @@ void amdgpu_driver_unload_kms(struct drm_device *dev) ...@@ -60,6 +60,9 @@ void amdgpu_driver_unload_kms(struct drm_device *dev)
if (adev->rmmio == NULL) if (adev->rmmio == NULL)
goto done_free; goto done_free;
if (amdgpu_sriov_vf(adev))
amdgpu_virt_request_full_gpu(adev, false);
if (amdgpu_device_is_px(dev)) { if (amdgpu_device_is_px(dev)) {
pm_runtime_get_sync(dev->dev); pm_runtime_get_sync(dev->dev);
pm_runtime_forbid(dev->dev); pm_runtime_forbid(dev->dev);
...@@ -138,6 +141,9 @@ int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags) ...@@ -138,6 +141,9 @@ int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags)
pm_runtime_put_autosuspend(dev->dev); pm_runtime_put_autosuspend(dev->dev);
} }
if (amdgpu_sriov_vf(adev))
amdgpu_virt_release_full_gpu(adev, true);
out: out:
if (r) { if (r) {
/* balance pm_runtime_get_sync in amdgpu_driver_unload_kms */ /* balance pm_runtime_get_sync in amdgpu_driver_unload_kms */
...@@ -569,6 +575,27 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file ...@@ -569,6 +575,27 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
return -EINVAL; return -EINVAL;
} }
} }
case AMDGPU_INFO_NUM_HANDLES: {
struct drm_amdgpu_info_num_handles handle;
switch (info->query_hw_ip.type) {
case AMDGPU_HW_IP_UVD:
/* Starting Polaris, we support unlimited UVD handles */
if (adev->asic_type < CHIP_POLARIS10) {
handle.uvd_max_handles = adev->uvd.max_handles;
handle.uvd_used_handles = amdgpu_uvd_used_handles(adev);
return copy_to_user(out, &handle,
min((size_t)size, sizeof(handle))) ? -EFAULT : 0;
} else {
return -ENODATA;
}
break;
default:
return -EINVAL;
}
}
default: default:
DRM_DEBUG_KMS("Invalid request %d\n", info->query); DRM_DEBUG_KMS("Invalid request %d\n", info->query);
return -EINVAL; return -EINVAL;
...@@ -628,6 +655,12 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) ...@@ -628,6 +655,12 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
goto out_suspend; goto out_suspend;
} }
if (amdgpu_sriov_vf(adev)) {
r = amdgpu_map_static_csa(adev, &fpriv->vm);
if (r)
goto out_suspend;
}
mutex_init(&fpriv->bo_list_lock); mutex_init(&fpriv->bo_list_lock);
idr_init(&fpriv->bo_list_handles); idr_init(&fpriv->bo_list_handles);
...@@ -666,6 +699,14 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev, ...@@ -666,6 +699,14 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
amdgpu_uvd_free_handles(adev, file_priv); amdgpu_uvd_free_handles(adev, file_priv);
amdgpu_vce_free_handles(adev, file_priv); amdgpu_vce_free_handles(adev, file_priv);
if (amdgpu_sriov_vf(adev)) {
/* TODO: how to handle reserve failure */
BUG_ON(amdgpu_bo_reserve(adev->virt.csa_obj, false));
amdgpu_vm_bo_rmv(adev, fpriv->vm.csa_bo_va);
fpriv->vm.csa_bo_va = NULL;
amdgpu_bo_unreserve(adev->virt.csa_obj);
}
amdgpu_vm_fini(adev, &fpriv->vm); amdgpu_vm_fini(adev, &fpriv->vm);
idr_for_each_entry(&fpriv->bo_list_handles, list, handle) idr_for_each_entry(&fpriv->bo_list_handles, list, handle)
......
...@@ -595,6 +595,21 @@ int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc, ...@@ -595,6 +595,21 @@ int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc,
struct drm_framebuffer *fb, struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event, struct drm_pending_vblank_event *event,
uint32_t page_flip_flags, uint32_t target); uint32_t page_flip_flags, uint32_t target);
void amdgpu_crtc_cleanup_flip_ctx(struct amdgpu_flip_work *work,
struct amdgpu_bo *new_abo);
int amdgpu_crtc_prepare_flip(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event,
uint32_t page_flip_flags,
uint32_t target,
struct amdgpu_flip_work **work,
struct amdgpu_bo **new_abo);
void amdgpu_crtc_submit_flip(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct amdgpu_flip_work *work,
struct amdgpu_bo *new_abo);
extern const struct drm_mode_config_funcs amdgpu_mode_funcs; extern const struct drm_mode_config_funcs amdgpu_mode_funcs;
#endif #endif
...@@ -363,11 +363,31 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev, ...@@ -363,11 +363,31 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev,
bo->flags = flags; bo->flags = flags;
#ifdef CONFIG_X86_32
/* XXX: Write-combined CPU mappings of GTT seem broken on 32-bit
* See https://bugs.freedesktop.org/show_bug.cgi?id=84627
*/
bo->flags &= ~AMDGPU_GEM_CREATE_CPU_GTT_USWC;
#elif defined(CONFIG_X86) && !defined(CONFIG_X86_PAT)
/* Don't try to enable write-combining when it can't work, or things
* may be slow
* See https://bugs.freedesktop.org/show_bug.cgi?id=88758
*/
#warning Please enable CONFIG_MTRR and CONFIG_X86_PAT for better performance \
thanks to write-combining
if (bo->flags & AMDGPU_GEM_CREATE_CPU_GTT_USWC)
DRM_INFO_ONCE("Please enable CONFIG_MTRR and CONFIG_X86_PAT for "
"better performance thanks to write-combining\n");
bo->flags &= ~AMDGPU_GEM_CREATE_CPU_GTT_USWC;
#else
/* For architectures that don't support WC memory, /* For architectures that don't support WC memory,
* mask out the WC flag from the BO * mask out the WC flag from the BO
*/ */
if (!drm_arch_can_wc_memory()) if (!drm_arch_can_wc_memory())
bo->flags &= ~AMDGPU_GEM_CREATE_CPU_GTT_USWC; bo->flags &= ~AMDGPU_GEM_CREATE_CPU_GTT_USWC;
#endif
amdgpu_fill_placement_to_bo(bo, placement); amdgpu_fill_placement_to_bo(bo, placement);
/* Kernel allocation are uninterruptible */ /* Kernel allocation are uninterruptible */
...@@ -386,6 +406,11 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev, ...@@ -386,6 +406,11 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev,
if (unlikely(r != 0)) if (unlikely(r != 0))
return r; return r;
bo->tbo.priority = ilog2(bo->tbo.num_pages);
if (kernel)
bo->tbo.priority *= 2;
bo->tbo.priority = min(bo->tbo.priority, (unsigned)(TTM_MAX_BO_PRIORITY - 1));
if (flags & AMDGPU_GEM_CREATE_VRAM_CLEARED && if (flags & AMDGPU_GEM_CREATE_VRAM_CLEARED &&
bo->tbo.mem.placement & TTM_PL_FLAG_VRAM) { bo->tbo.mem.placement & TTM_PL_FLAG_VRAM) {
struct dma_fence *fence; struct dma_fence *fence;
...@@ -408,7 +433,8 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev, ...@@ -408,7 +433,8 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev,
return 0; return 0;
fail_unreserve: fail_unreserve:
ww_mutex_unlock(&bo->tbo.resv->lock); if (!resv)
ww_mutex_unlock(&bo->tbo.resv->lock);
amdgpu_bo_unref(&bo); amdgpu_bo_unref(&bo);
return r; return r;
} }
...@@ -472,7 +498,16 @@ int amdgpu_bo_create(struct amdgpu_device *adev, ...@@ -472,7 +498,16 @@ int amdgpu_bo_create(struct amdgpu_device *adev,
return r; return r;
if (amdgpu_need_backup(adev) && (flags & AMDGPU_GEM_CREATE_SHADOW)) { if (amdgpu_need_backup(adev) && (flags & AMDGPU_GEM_CREATE_SHADOW)) {
if (!resv) {
r = ww_mutex_lock(&(*bo_ptr)->tbo.resv->lock, NULL);
WARN_ON(r != 0);
}
r = amdgpu_bo_create_shadow(adev, size, byte_align, (*bo_ptr)); r = amdgpu_bo_create_shadow(adev, size, byte_align, (*bo_ptr));
if (!resv)
ww_mutex_unlock(&(*bo_ptr)->tbo.resv->lock);
if (r) if (r)
amdgpu_bo_unref(bo_ptr); amdgpu_bo_unref(bo_ptr);
} }
...@@ -849,6 +884,7 @@ int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer, ...@@ -849,6 +884,7 @@ int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer,
} }
void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, void amdgpu_bo_move_notify(struct ttm_buffer_object *bo,
bool evict,
struct ttm_mem_reg *new_mem) struct ttm_mem_reg *new_mem)
{ {
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev); struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);
...@@ -861,6 +897,10 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, ...@@ -861,6 +897,10 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo,
abo = container_of(bo, struct amdgpu_bo, tbo); abo = container_of(bo, struct amdgpu_bo, tbo);
amdgpu_vm_bo_invalidate(adev, abo); amdgpu_vm_bo_invalidate(adev, abo);
/* remember the eviction */
if (evict)
atomic64_inc(&adev->num_evictions);
/* update statistics */ /* update statistics */
if (!new_mem) if (!new_mem)
return; return;
......
...@@ -114,6 +114,15 @@ static inline u64 amdgpu_bo_mmap_offset(struct amdgpu_bo *bo) ...@@ -114,6 +114,15 @@ static inline u64 amdgpu_bo_mmap_offset(struct amdgpu_bo *bo)
return drm_vma_node_offset_addr(&bo->tbo.vma_node); return drm_vma_node_offset_addr(&bo->tbo.vma_node);
} }
/**
* amdgpu_bo_gpu_accessible - return whether the bo is currently in memory that
* is accessible to the GPU.
*/
static inline bool amdgpu_bo_gpu_accessible(struct amdgpu_bo *bo)
{
return bo->tbo.mem.mem_type != TTM_PL_SYSTEM;
}
int amdgpu_bo_create(struct amdgpu_device *adev, int amdgpu_bo_create(struct amdgpu_device *adev,
unsigned long size, int byte_align, unsigned long size, int byte_align,
bool kernel, u32 domain, u64 flags, bool kernel, u32 domain, u64 flags,
...@@ -155,7 +164,8 @@ int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer, ...@@ -155,7 +164,8 @@ int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer,
size_t buffer_size, uint32_t *metadata_size, size_t buffer_size, uint32_t *metadata_size,
uint64_t *flags); uint64_t *flags);
void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, void amdgpu_bo_move_notify(struct ttm_buffer_object *bo,
struct ttm_mem_reg *new_mem); bool evict,
struct ttm_mem_reg *new_mem);
int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo); int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo);
void amdgpu_bo_fence(struct amdgpu_bo *bo, struct dma_fence *fence, void amdgpu_bo_fence(struct amdgpu_bo *bo, struct dma_fence *fence,
bool shared); bool shared);
......
...@@ -34,6 +34,28 @@ ...@@ -34,6 +34,28 @@
static int amdgpu_debugfs_pm_init(struct amdgpu_device *adev); static int amdgpu_debugfs_pm_init(struct amdgpu_device *adev);
static const struct cg_flag_name clocks[] = {
{AMD_CG_SUPPORT_GFX_MGCG, "Graphics Medium Grain Clock Gating"},
{AMD_CG_SUPPORT_GFX_MGLS, "Graphics Medium Grain memory Light Sleep"},
{AMD_CG_SUPPORT_GFX_CGCG, "Graphics Coarse Grain Clock Gating"},
{AMD_CG_SUPPORT_GFX_CGLS, "Graphics Coarse Grain memory Light Sleep"},
{AMD_CG_SUPPORT_GFX_CGTS, "Graphics Coarse Grain Tree Shader Clock Gating"},
{AMD_CG_SUPPORT_GFX_CGTS_LS, "Graphics Coarse Grain Tree Shader Light Sleep"},
{AMD_CG_SUPPORT_GFX_CP_LS, "Graphics Command Processor Light Sleep"},
{AMD_CG_SUPPORT_GFX_RLC_LS, "Graphics Run List Controller Light Sleep"},
{AMD_CG_SUPPORT_MC_LS, "Memory Controller Light Sleep"},
{AMD_CG_SUPPORT_MC_MGCG, "Memory Controller Medium Grain Clock Gating"},
{AMD_CG_SUPPORT_SDMA_LS, "System Direct Memory Access Light Sleep"},
{AMD_CG_SUPPORT_SDMA_MGCG, "System Direct Memory Access Medium Grain Clock Gating"},
{AMD_CG_SUPPORT_BIF_LS, "Bus Interface Light Sleep"},
{AMD_CG_SUPPORT_UVD_MGCG, "Unified Video Decoder Medium Grain Clock Gating"},
{AMD_CG_SUPPORT_VCE_MGCG, "Video Compression Engine Medium Grain Clock Gating"},
{AMD_CG_SUPPORT_HDP_LS, "Host Data Path Light Sleep"},
{AMD_CG_SUPPORT_HDP_MGCG, "Host Data Path Medium Grain Clock Gating"},
{AMD_CG_SUPPORT_ROM_MGCG, "Rom Medium Grain Clock Gating"},
{0, NULL},
};
void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev) void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev)
{ {
if (adev->pp_enabled) if (adev->pp_enabled)
...@@ -112,28 +134,23 @@ static ssize_t amdgpu_get_dpm_forced_performance_level(struct device *dev, ...@@ -112,28 +134,23 @@ static ssize_t amdgpu_get_dpm_forced_performance_level(struct device *dev,
{ {
struct drm_device *ddev = dev_get_drvdata(dev); struct drm_device *ddev = dev_get_drvdata(dev);
struct amdgpu_device *adev = ddev->dev_private; struct amdgpu_device *adev = ddev->dev_private;
enum amd_dpm_forced_level level;
if ((adev->flags & AMD_IS_PX) && if ((adev->flags & AMD_IS_PX) &&
(ddev->switch_power_state != DRM_SWITCH_POWER_ON)) (ddev->switch_power_state != DRM_SWITCH_POWER_ON))
return snprintf(buf, PAGE_SIZE, "off\n"); return snprintf(buf, PAGE_SIZE, "off\n");
if (adev->pp_enabled) { level = amdgpu_dpm_get_performance_level(adev);
enum amd_dpm_forced_level level; return snprintf(buf, PAGE_SIZE, "%s\n",
(level == AMD_DPM_FORCED_LEVEL_AUTO) ? "auto" :
level = amdgpu_dpm_get_performance_level(adev); (level == AMD_DPM_FORCED_LEVEL_LOW) ? "low" :
return snprintf(buf, PAGE_SIZE, "%s\n", (level == AMD_DPM_FORCED_LEVEL_HIGH) ? "high" :
(level == AMD_DPM_FORCED_LEVEL_AUTO) ? "auto" : (level == AMD_DPM_FORCED_LEVEL_MANUAL) ? "manual" :
(level == AMD_DPM_FORCED_LEVEL_LOW) ? "low" : (level == AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD) ? "profile_standard" :
(level == AMD_DPM_FORCED_LEVEL_HIGH) ? "high" : (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK) ? "profile_min_sclk" :
(level == AMD_DPM_FORCED_LEVEL_MANUAL) ? "manual" : "unknown"); (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK) ? "profile_min_mclk" :
} else { (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) ? "profile_peak" :
enum amdgpu_dpm_forced_level level; "unknown");
level = adev->pm.dpm.forced_level;
return snprintf(buf, PAGE_SIZE, "%s\n",
(level == AMDGPU_DPM_FORCED_LEVEL_AUTO) ? "auto" :
(level == AMDGPU_DPM_FORCED_LEVEL_LOW) ? "low" : "high");
}
} }
static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev, static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev,
...@@ -143,7 +160,8 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev, ...@@ -143,7 +160,8 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev,
{ {
struct drm_device *ddev = dev_get_drvdata(dev); struct drm_device *ddev = dev_get_drvdata(dev);
struct amdgpu_device *adev = ddev->dev_private; struct amdgpu_device *adev = ddev->dev_private;
enum amdgpu_dpm_forced_level level; enum amd_dpm_forced_level level;
enum amd_dpm_forced_level current_level;
int ret = 0; int ret = 0;
/* Can't force performance level when the card is off */ /* Can't force performance level when the card is off */
...@@ -151,19 +169,34 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev, ...@@ -151,19 +169,34 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev,
(ddev->switch_power_state != DRM_SWITCH_POWER_ON)) (ddev->switch_power_state != DRM_SWITCH_POWER_ON))
return -EINVAL; return -EINVAL;
current_level = amdgpu_dpm_get_performance_level(adev);
if (strncmp("low", buf, strlen("low")) == 0) { if (strncmp("low", buf, strlen("low")) == 0) {
level = AMDGPU_DPM_FORCED_LEVEL_LOW; level = AMD_DPM_FORCED_LEVEL_LOW;
} else if (strncmp("high", buf, strlen("high")) == 0) { } else if (strncmp("high", buf, strlen("high")) == 0) {
level = AMDGPU_DPM_FORCED_LEVEL_HIGH; level = AMD_DPM_FORCED_LEVEL_HIGH;
} else if (strncmp("auto", buf, strlen("auto")) == 0) { } else if (strncmp("auto", buf, strlen("auto")) == 0) {
level = AMDGPU_DPM_FORCED_LEVEL_AUTO; level = AMD_DPM_FORCED_LEVEL_AUTO;
} else if (strncmp("manual", buf, strlen("manual")) == 0) { } else if (strncmp("manual", buf, strlen("manual")) == 0) {
level = AMDGPU_DPM_FORCED_LEVEL_MANUAL; level = AMD_DPM_FORCED_LEVEL_MANUAL;
} else { } else if (strncmp("profile_exit", buf, strlen("profile_exit")) == 0) {
level = AMD_DPM_FORCED_LEVEL_PROFILE_EXIT;
} else if (strncmp("profile_standard", buf, strlen("profile_standard")) == 0) {
level = AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD;
} else if (strncmp("profile_min_sclk", buf, strlen("profile_min_sclk")) == 0) {
level = AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK;
} else if (strncmp("profile_min_mclk", buf, strlen("profile_min_mclk")) == 0) {
level = AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK;
} else if (strncmp("profile_peak", buf, strlen("profile_peak")) == 0) {
level = AMD_DPM_FORCED_LEVEL_PROFILE_PEAK;
} else {
count = -EINVAL; count = -EINVAL;
goto fail; goto fail;
} }
if (current_level == level)
return count;
if (adev->pp_enabled) if (adev->pp_enabled)
amdgpu_dpm_force_performance_level(adev, level); amdgpu_dpm_force_performance_level(adev, level);
else { else {
...@@ -180,6 +213,7 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev, ...@@ -180,6 +213,7 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev,
adev->pm.dpm.forced_level = level; adev->pm.dpm.forced_level = level;
mutex_unlock(&adev->pm.mutex); mutex_unlock(&adev->pm.mutex);
} }
fail: fail:
return count; return count;
} }
...@@ -1060,9 +1094,9 @@ static void amdgpu_dpm_change_power_state_locked(struct amdgpu_device *adev) ...@@ -1060,9 +1094,9 @@ static void amdgpu_dpm_change_power_state_locked(struct amdgpu_device *adev)
if (adev->pm.funcs->force_performance_level) { if (adev->pm.funcs->force_performance_level) {
if (adev->pm.dpm.thermal_active) { if (adev->pm.dpm.thermal_active) {
enum amdgpu_dpm_forced_level level = adev->pm.dpm.forced_level; enum amd_dpm_forced_level level = adev->pm.dpm.forced_level;
/* force low perf level for thermal */ /* force low perf level for thermal */
amdgpu_dpm_force_performance_level(adev, AMDGPU_DPM_FORCED_LEVEL_LOW); amdgpu_dpm_force_performance_level(adev, AMD_DPM_FORCED_LEVEL_LOW);
/* save the user's level */ /* save the user's level */
adev->pm.dpm.forced_level = level; adev->pm.dpm.forced_level = level;
} else { } else {
...@@ -1351,12 +1385,27 @@ static int amdgpu_debugfs_pm_info_pp(struct seq_file *m, struct amdgpu_device *a ...@@ -1351,12 +1385,27 @@ static int amdgpu_debugfs_pm_info_pp(struct seq_file *m, struct amdgpu_device *a
return 0; return 0;
} }
static void amdgpu_parse_cg_state(struct seq_file *m, u32 flags)
{
int i;
for (i = 0; clocks[i].flag; i++)
seq_printf(m, "\t%s: %s\n", clocks[i].name,
(flags & clocks[i].flag) ? "On" : "Off");
}
static int amdgpu_debugfs_pm_info(struct seq_file *m, void *data) static int amdgpu_debugfs_pm_info(struct seq_file *m, void *data)
{ {
struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev; struct drm_device *dev = node->minor->dev;
struct amdgpu_device *adev = dev->dev_private; struct amdgpu_device *adev = dev->dev_private;
struct drm_device *ddev = adev->ddev; struct drm_device *ddev = adev->ddev;
u32 flags = 0;
amdgpu_get_clockgating_state(adev, &flags);
seq_printf(m, "Clock Gating Flags Mask: 0x%x\n", flags);
amdgpu_parse_cg_state(m, flags);
seq_printf(m, "\n");
if (!adev->pm.dpm_enabled) { if (!adev->pm.dpm_enabled) {
seq_printf(m, "dpm not enabled\n"); seq_printf(m, "dpm not enabled\n");
......
...@@ -24,6 +24,12 @@ ...@@ -24,6 +24,12 @@
#ifndef __AMDGPU_PM_H__ #ifndef __AMDGPU_PM_H__
#define __AMDGPU_PM_H__ #define __AMDGPU_PM_H__
struct cg_flag_name
{
u32 flag;
const char *name;
};
int amdgpu_pm_sysfs_init(struct amdgpu_device *adev); int amdgpu_pm_sysfs_init(struct amdgpu_device *adev);
void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev); void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev);
void amdgpu_pm_print_power_states(struct amdgpu_device *adev); void amdgpu_pm_print_power_states(struct amdgpu_device *adev);
......
...@@ -34,67 +34,34 @@ ...@@ -34,67 +34,34 @@
#include "cik_dpm.h" #include "cik_dpm.h"
#include "vi_dpm.h" #include "vi_dpm.h"
static int amdgpu_powerplay_init(struct amdgpu_device *adev) static int amdgpu_create_pp_handle(struct amdgpu_device *adev)
{ {
int ret = 0; struct amd_pp_init pp_init;
struct amd_powerplay *amd_pp; struct amd_powerplay *amd_pp;
int ret;
amd_pp = &(adev->powerplay); amd_pp = &(adev->powerplay);
pp_init.chip_family = adev->family;
if (adev->pp_enabled) { pp_init.chip_id = adev->asic_type;
struct amd_pp_init *pp_init; pp_init.pm_en = amdgpu_dpm != 0 ? true : false;
pp_init.feature_mask = amdgpu_pp_feature_mask;
pp_init = kzalloc(sizeof(struct amd_pp_init), GFP_KERNEL); pp_init.device = amdgpu_cgs_create_device(adev);
ret = amd_powerplay_create(&pp_init, &(amd_pp->pp_handle));
if (pp_init == NULL) if (ret)
return -ENOMEM; return -EINVAL;
return 0;
pp_init->chip_family = adev->family;
pp_init->chip_id = adev->asic_type;
pp_init->device = amdgpu_cgs_create_device(adev);
ret = amd_powerplay_init(pp_init, amd_pp);
kfree(pp_init);
} else {
amd_pp->pp_handle = (void *)adev;
switch (adev->asic_type) {
#ifdef CONFIG_DRM_AMDGPU_SI
case CHIP_TAHITI:
case CHIP_PITCAIRN:
case CHIP_VERDE:
case CHIP_OLAND:
case CHIP_HAINAN:
amd_pp->ip_funcs = &si_dpm_ip_funcs;
break;
#endif
#ifdef CONFIG_DRM_AMDGPU_CIK
case CHIP_BONAIRE:
case CHIP_HAWAII:
amd_pp->ip_funcs = &ci_dpm_ip_funcs;
break;
case CHIP_KABINI:
case CHIP_MULLINS:
case CHIP_KAVERI:
amd_pp->ip_funcs = &kv_dpm_ip_funcs;
break;
#endif
case CHIP_CARRIZO:
case CHIP_STONEY:
amd_pp->ip_funcs = &cz_dpm_ip_funcs;
break;
default:
ret = -EINVAL;
break;
}
}
return ret;
} }
static int amdgpu_pp_early_init(void *handle) static int amdgpu_pp_early_init(void *handle)
{ {
struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct amd_powerplay *amd_pp;
int ret = 0; int ret = 0;
amd_pp = &(adev->powerplay);
adev->pp_enabled = false;
amd_pp->pp_handle = (void *)adev;
switch (adev->asic_type) { switch (adev->asic_type) {
case CHIP_POLARIS11: case CHIP_POLARIS11:
case CHIP_POLARIS10: case CHIP_POLARIS10:
...@@ -102,30 +69,48 @@ static int amdgpu_pp_early_init(void *handle) ...@@ -102,30 +69,48 @@ static int amdgpu_pp_early_init(void *handle)
case CHIP_TONGA: case CHIP_TONGA:
case CHIP_FIJI: case CHIP_FIJI:
case CHIP_TOPAZ: case CHIP_TOPAZ:
adev->pp_enabled = true;
break;
case CHIP_CARRIZO: case CHIP_CARRIZO:
case CHIP_STONEY: case CHIP_STONEY:
adev->pp_enabled = (amdgpu_powerplay == 0) ? false : true; adev->pp_enabled = true;
if (amdgpu_create_pp_handle(adev))
return -EINVAL;
amd_pp->ip_funcs = &pp_ip_funcs;
amd_pp->pp_funcs = &pp_dpm_funcs;
break; break;
/* These chips don't have powerplay implemenations */ /* These chips don't have powerplay implemenations */
#ifdef CONFIG_DRM_AMDGPU_SI
case CHIP_TAHITI:
case CHIP_PITCAIRN:
case CHIP_VERDE:
case CHIP_OLAND:
case CHIP_HAINAN:
amd_pp->ip_funcs = &si_dpm_ip_funcs;
break;
#endif
#ifdef CONFIG_DRM_AMDGPU_CIK
case CHIP_BONAIRE: case CHIP_BONAIRE:
case CHIP_HAWAII: case CHIP_HAWAII:
amd_pp->ip_funcs = &ci_dpm_ip_funcs;
break;
case CHIP_KABINI: case CHIP_KABINI:
case CHIP_MULLINS: case CHIP_MULLINS:
case CHIP_KAVERI: case CHIP_KAVERI:
amd_pp->ip_funcs = &kv_dpm_ip_funcs;
break;
#endif
default: default:
adev->pp_enabled = false; ret = -EINVAL;
break; break;
} }
ret = amdgpu_powerplay_init(adev);
if (ret)
return ret;
if (adev->powerplay.ip_funcs->early_init) if (adev->powerplay.ip_funcs->early_init)
ret = adev->powerplay.ip_funcs->early_init( ret = adev->powerplay.ip_funcs->early_init(
adev->powerplay.pp_handle); adev->powerplay.pp_handle);
if (ret == PP_DPM_DISABLED) {
adev->pm.dpm_enabled = false;
return 0;
}
return ret; return ret;
} }
...@@ -185,6 +170,11 @@ static int amdgpu_pp_hw_init(void *handle) ...@@ -185,6 +170,11 @@ static int amdgpu_pp_hw_init(void *handle)
ret = adev->powerplay.ip_funcs->hw_init( ret = adev->powerplay.ip_funcs->hw_init(
adev->powerplay.pp_handle); adev->powerplay.pp_handle);
if (ret == PP_DPM_DISABLED) {
adev->pm.dpm_enabled = false;
return 0;
}
if ((amdgpu_dpm != 0) && !amdgpu_sriov_vf(adev)) if ((amdgpu_dpm != 0) && !amdgpu_sriov_vf(adev))
adev->pm.dpm_enabled = true; adev->pm.dpm_enabled = true;
...@@ -210,14 +200,14 @@ static void amdgpu_pp_late_fini(void *handle) ...@@ -210,14 +200,14 @@ static void amdgpu_pp_late_fini(void *handle)
{ {
struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct amdgpu_device *adev = (struct amdgpu_device *)handle;
if (adev->pp_enabled) {
amdgpu_pm_sysfs_fini(adev);
amd_powerplay_fini(adev->powerplay.pp_handle);
}
if (adev->powerplay.ip_funcs->late_fini) if (adev->powerplay.ip_funcs->late_fini)
adev->powerplay.ip_funcs->late_fini( adev->powerplay.ip_funcs->late_fini(
adev->powerplay.pp_handle); adev->powerplay.pp_handle);
if (adev->pp_enabled && adev->pm.dpm_enabled)
amdgpu_pm_sysfs_fini(adev);
amd_powerplay_destroy(adev->powerplay.pp_handle);
} }
static int amdgpu_pp_suspend(void *handle) static int amdgpu_pp_suspend(void *handle)
......
...@@ -207,6 +207,8 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, ...@@ -207,6 +207,8 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
} }
ring->cond_exe_gpu_addr = adev->wb.gpu_addr + (ring->cond_exe_offs * 4); ring->cond_exe_gpu_addr = adev->wb.gpu_addr + (ring->cond_exe_offs * 4);
ring->cond_exe_cpu_addr = &adev->wb.wb[ring->cond_exe_offs]; ring->cond_exe_cpu_addr = &adev->wb.wb[ring->cond_exe_offs];
/* always set cond_exec_polling to CONTINUE */
*ring->cond_exe_cpu_addr = 1;
r = amdgpu_fence_driver_start_ring(ring, irq_src, irq_type); r = amdgpu_fence_driver_start_ring(ring, irq_src, irq_type);
if (r) { if (r) {
...@@ -307,7 +309,7 @@ static ssize_t amdgpu_debugfs_ring_read(struct file *f, char __user *buf, ...@@ -307,7 +309,7 @@ static ssize_t amdgpu_debugfs_ring_read(struct file *f, char __user *buf,
while (size) { while (size) {
if (*pos >= (ring->ring_size + 12)) if (*pos >= (ring->ring_size + 12))
return result; return result;
value = ring->ring[(*pos - 12)/4]; value = ring->ring[(*pos - 12)/4];
r = put_user(value, (uint32_t*)buf); r = put_user(value, (uint32_t*)buf);
if (r) if (r)
......
...@@ -135,6 +135,8 @@ struct amdgpu_ring_funcs { ...@@ -135,6 +135,8 @@ struct amdgpu_ring_funcs {
void (*end_use)(struct amdgpu_ring *ring); void (*end_use)(struct amdgpu_ring *ring);
void (*emit_switch_buffer) (struct amdgpu_ring *ring); void (*emit_switch_buffer) (struct amdgpu_ring *ring);
void (*emit_cntxcntl) (struct amdgpu_ring *ring, uint32_t flags); void (*emit_cntxcntl) (struct amdgpu_ring *ring, uint32_t flags);
void (*emit_rreg)(struct amdgpu_ring *ring, uint32_t reg);
void (*emit_wreg)(struct amdgpu_ring *ring, uint32_t reg, uint32_t val);
}; };
struct amdgpu_ring { struct amdgpu_ring {
......
...@@ -24,7 +24,7 @@ TRACE_EVENT(amdgpu_mm_rreg, ...@@ -24,7 +24,7 @@ TRACE_EVENT(amdgpu_mm_rreg,
__entry->reg = reg; __entry->reg = reg;
__entry->value = value; __entry->value = value;
), ),
TP_printk("0x%04lx, 0x%04lx, 0x%08lx", TP_printk("0x%04lx, 0x%08lx, 0x%08lx",
(unsigned long)__entry->did, (unsigned long)__entry->did,
(unsigned long)__entry->reg, (unsigned long)__entry->reg,
(unsigned long)__entry->value) (unsigned long)__entry->value)
...@@ -43,7 +43,7 @@ TRACE_EVENT(amdgpu_mm_wreg, ...@@ -43,7 +43,7 @@ TRACE_EVENT(amdgpu_mm_wreg,
__entry->reg = reg; __entry->reg = reg;
__entry->value = value; __entry->value = value;
), ),
TP_printk("0x%04lx, 0x%04lx, 0x%08lx", TP_printk("0x%04lx, 0x%08lx, 0x%08lx",
(unsigned long)__entry->did, (unsigned long)__entry->did,
(unsigned long)__entry->reg, (unsigned long)__entry->reg,
(unsigned long)__entry->value) (unsigned long)__entry->value)
......
...@@ -466,10 +466,6 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, ...@@ -466,10 +466,6 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo,
adev = amdgpu_ttm_adev(bo->bdev); adev = amdgpu_ttm_adev(bo->bdev);
/* remember the eviction */
if (evict)
atomic64_inc(&adev->num_evictions);
if (old_mem->mem_type == TTM_PL_SYSTEM && bo->ttm == NULL) { if (old_mem->mem_type == TTM_PL_SYSTEM && bo->ttm == NULL) {
amdgpu_move_null(bo, new_mem); amdgpu_move_null(bo, new_mem);
return 0; return 0;
...@@ -552,6 +548,8 @@ static int amdgpu_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_ ...@@ -552,6 +548,8 @@ static int amdgpu_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_
mem->bus.addr = mem->bus.addr =
ioremap_nocache(mem->bus.base + mem->bus.offset, ioremap_nocache(mem->bus.base + mem->bus.offset,
mem->bus.size); mem->bus.size);
if (!mem->bus.addr)
return -ENOMEM;
/* /*
* Alpha: Use just the bus offset plus * Alpha: Use just the bus offset plus
...@@ -1052,56 +1050,6 @@ uint32_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm, ...@@ -1052,56 +1050,6 @@ uint32_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm,
return flags; return flags;
} }
static void amdgpu_ttm_lru_removal(struct ttm_buffer_object *tbo)
{
struct amdgpu_device *adev = amdgpu_ttm_adev(tbo->bdev);
unsigned i, j;
for (i = 0; i < AMDGPU_TTM_LRU_SIZE; ++i) {
struct amdgpu_mman_lru *lru = &adev->mman.log2_size[i];
for (j = 0; j < TTM_NUM_MEM_TYPES; ++j)
if (&tbo->lru == lru->lru[j])
lru->lru[j] = tbo->lru.prev;
if (&tbo->swap == lru->swap_lru)
lru->swap_lru = tbo->swap.prev;
}
}
static struct amdgpu_mman_lru *amdgpu_ttm_lru(struct ttm_buffer_object *tbo)
{
struct amdgpu_device *adev = amdgpu_ttm_adev(tbo->bdev);
unsigned log2_size = min(ilog2(tbo->num_pages),
AMDGPU_TTM_LRU_SIZE - 1);
return &adev->mman.log2_size[log2_size];
}
static struct list_head *amdgpu_ttm_lru_tail(struct ttm_buffer_object *tbo)
{
struct amdgpu_mman_lru *lru = amdgpu_ttm_lru(tbo);
struct list_head *res = lru->lru[tbo->mem.mem_type];
lru->lru[tbo->mem.mem_type] = &tbo->lru;
while ((++lru)->lru[tbo->mem.mem_type] == res)
lru->lru[tbo->mem.mem_type] = &tbo->lru;
return res;
}
static struct list_head *amdgpu_ttm_swap_lru_tail(struct ttm_buffer_object *tbo)
{
struct amdgpu_mman_lru *lru = amdgpu_ttm_lru(tbo);
struct list_head *res = lru->swap_lru;
lru->swap_lru = &tbo->swap;
while ((++lru)->swap_lru == res)
lru->swap_lru = &tbo->swap;
return res;
}
static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo, static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
const struct ttm_place *place) const struct ttm_place *place)
{ {
...@@ -1140,14 +1088,10 @@ static struct ttm_bo_driver amdgpu_bo_driver = { ...@@ -1140,14 +1088,10 @@ static struct ttm_bo_driver amdgpu_bo_driver = {
.fault_reserve_notify = &amdgpu_bo_fault_reserve_notify, .fault_reserve_notify = &amdgpu_bo_fault_reserve_notify,
.io_mem_reserve = &amdgpu_ttm_io_mem_reserve, .io_mem_reserve = &amdgpu_ttm_io_mem_reserve,
.io_mem_free = &amdgpu_ttm_io_mem_free, .io_mem_free = &amdgpu_ttm_io_mem_free,
.lru_removal = &amdgpu_ttm_lru_removal,
.lru_tail = &amdgpu_ttm_lru_tail,
.swap_lru_tail = &amdgpu_ttm_swap_lru_tail,
}; };
int amdgpu_ttm_init(struct amdgpu_device *adev) int amdgpu_ttm_init(struct amdgpu_device *adev)
{ {
unsigned i, j;
int r; int r;
r = amdgpu_ttm_global_init(adev); r = amdgpu_ttm_global_init(adev);
...@@ -1165,19 +1109,6 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) ...@@ -1165,19 +1109,6 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
DRM_ERROR("failed initializing buffer object driver(%d).\n", r); DRM_ERROR("failed initializing buffer object driver(%d).\n", r);
return r; return r;
} }
for (i = 0; i < AMDGPU_TTM_LRU_SIZE; ++i) {
struct amdgpu_mman_lru *lru = &adev->mman.log2_size[i];
for (j = 0; j < TTM_NUM_MEM_TYPES; ++j)
lru->lru[j] = &adev->mman.bdev.man[j].lru;
lru->swap_lru = &adev->mman.bdev.glob->swap_lru;
}
for (j = 0; j < TTM_NUM_MEM_TYPES; ++j)
adev->mman.guard.lru[j] = NULL;
adev->mman.guard.swap_lru = NULL;
adev->mman.initialized = true; adev->mman.initialized = true;
r = ttm_bo_init_mm(&adev->mman.bdev, TTM_PL_VRAM, r = ttm_bo_init_mm(&adev->mman.bdev, TTM_PL_VRAM,
adev->mc.real_vram_size >> PAGE_SHIFT); adev->mc.real_vram_size >> PAGE_SHIFT);
...@@ -1365,7 +1296,7 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, ...@@ -1365,7 +1296,7 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring,
WARN_ON(job->ibs[0].length_dw > num_dw); WARN_ON(job->ibs[0].length_dw > num_dw);
if (direct_submit) { if (direct_submit) {
r = amdgpu_ib_schedule(ring, job->num_ibs, job->ibs, r = amdgpu_ib_schedule(ring, job->num_ibs, job->ibs,
NULL, NULL, fence); NULL, fence);
job->fence = dma_fence_get(*fence); job->fence = dma_fence_get(*fence);
if (r) if (r)
DRM_ERROR("Error scheduling IBs (%d)\n", r); DRM_ERROR("Error scheduling IBs (%d)\n", r);
......
...@@ -34,13 +34,6 @@ ...@@ -34,13 +34,6 @@
#define AMDGPU_PL_FLAG_GWS (TTM_PL_FLAG_PRIV << 1) #define AMDGPU_PL_FLAG_GWS (TTM_PL_FLAG_PRIV << 1)
#define AMDGPU_PL_FLAG_OA (TTM_PL_FLAG_PRIV << 2) #define AMDGPU_PL_FLAG_OA (TTM_PL_FLAG_PRIV << 2)
#define AMDGPU_TTM_LRU_SIZE 20
struct amdgpu_mman_lru {
struct list_head *lru[TTM_NUM_MEM_TYPES];
struct list_head *swap_lru;
};
struct amdgpu_mman { struct amdgpu_mman {
struct ttm_bo_global_ref bo_global_ref; struct ttm_bo_global_ref bo_global_ref;
struct drm_global_reference mem_global_ref; struct drm_global_reference mem_global_ref;
...@@ -58,11 +51,6 @@ struct amdgpu_mman { ...@@ -58,11 +51,6 @@ struct amdgpu_mman {
struct amdgpu_ring *buffer_funcs_ring; struct amdgpu_ring *buffer_funcs_ring;
/* Scheduler entity for buffer moves */ /* Scheduler entity for buffer moves */
struct amd_sched_entity entity; struct amd_sched_entity entity;
/* custom LRU management */
struct amdgpu_mman_lru log2_size[AMDGPU_TTM_LRU_SIZE];
/* guard for log2_size array, don't add anything in between */
struct amdgpu_mman_lru guard;
}; };
extern const struct ttm_mem_type_manager_func amdgpu_gtt_mgr_func; extern const struct ttm_mem_type_manager_func amdgpu_gtt_mgr_func;
......
...@@ -976,7 +976,7 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo, ...@@ -976,7 +976,7 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo,
ib->length_dw = 16; ib->length_dw = 16;
if (direct) { if (direct) {
r = amdgpu_ib_schedule(ring, 1, ib, NULL, NULL, &f); r = amdgpu_ib_schedule(ring, 1, ib, NULL, &f);
job->fence = dma_fence_get(f); job->fence = dma_fence_get(f);
if (r) if (r)
goto err_free; goto err_free;
...@@ -1178,3 +1178,28 @@ int amdgpu_uvd_ring_test_ib(struct amdgpu_ring *ring, long timeout) ...@@ -1178,3 +1178,28 @@ int amdgpu_uvd_ring_test_ib(struct amdgpu_ring *ring, long timeout)
error: error:
return r; return r;
} }
/**
* amdgpu_uvd_used_handles - returns used UVD handles
*
* @adev: amdgpu_device pointer
*
* Returns the number of UVD handles in use
*/
uint32_t amdgpu_uvd_used_handles(struct amdgpu_device *adev)
{
unsigned i;
uint32_t used_handles = 0;
for (i = 0; i < adev->uvd.max_handles; ++i) {
/*
* Handles can be freed in any order, and not
* necessarily linear. So we need to count
* all non-zero handles.
*/
if (atomic_read(&adev->uvd.handles[i]))
used_handles++;
}
return used_handles;
}
...@@ -38,5 +38,6 @@ int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser, uint32_t ib_idx); ...@@ -38,5 +38,6 @@ int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser, uint32_t ib_idx);
void amdgpu_uvd_ring_begin_use(struct amdgpu_ring *ring); void amdgpu_uvd_ring_begin_use(struct amdgpu_ring *ring);
void amdgpu_uvd_ring_end_use(struct amdgpu_ring *ring); void amdgpu_uvd_ring_end_use(struct amdgpu_ring *ring);
int amdgpu_uvd_ring_test_ib(struct amdgpu_ring *ring, long timeout); int amdgpu_uvd_ring_test_ib(struct amdgpu_ring *ring, long timeout);
uint32_t amdgpu_uvd_used_handles(struct amdgpu_device *adev);
#endif #endif
...@@ -455,7 +455,7 @@ int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, ...@@ -455,7 +455,7 @@ int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
for (i = ib->length_dw; i < ib_size_dw; ++i) for (i = ib->length_dw; i < ib_size_dw; ++i)
ib->ptr[i] = 0x0; ib->ptr[i] = 0x0;
r = amdgpu_ib_schedule(ring, 1, ib, NULL, NULL, &f); r = amdgpu_ib_schedule(ring, 1, ib, NULL, &f);
job->fence = dma_fence_get(f); job->fence = dma_fence_get(f);
if (r) if (r)
goto err; goto err;
...@@ -518,7 +518,7 @@ int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, ...@@ -518,7 +518,7 @@ int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
ib->ptr[i] = 0x0; ib->ptr[i] = 0x0;
if (direct) { if (direct) {
r = amdgpu_ib_schedule(ring, 1, ib, NULL, NULL, &f); r = amdgpu_ib_schedule(ring, 1, ib, NULL, &f);
job->fence = dma_fence_get(f); job->fence = dma_fence_get(f);
if (r) if (r)
goto err; goto err;
......
/*
* Copyright 2016 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "amdgpu.h"
int amdgpu_allocate_static_csa(struct amdgpu_device *adev)
{
int r;
void *ptr;
r = amdgpu_bo_create_kernel(adev, AMDGPU_CSA_SIZE, PAGE_SIZE,
AMDGPU_GEM_DOMAIN_VRAM, &adev->virt.csa_obj,
&adev->virt.csa_vmid0_addr, &ptr);
if (r)
return r;
memset(ptr, 0, AMDGPU_CSA_SIZE);
return 0;
}
/*
* amdgpu_map_static_csa should be called during amdgpu_vm_init
* it maps virtual address "AMDGPU_VA_RESERVED_SIZE - AMDGPU_CSA_SIZE"
* to this VM, and each command submission of GFX should use this virtual
* address within META_DATA init package to support SRIOV gfx preemption.
*/
int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm)
{
int r;
struct amdgpu_bo_va *bo_va;
struct ww_acquire_ctx ticket;
struct list_head list;
struct amdgpu_bo_list_entry pd;
struct ttm_validate_buffer csa_tv;
INIT_LIST_HEAD(&list);
INIT_LIST_HEAD(&csa_tv.head);
csa_tv.bo = &adev->virt.csa_obj->tbo;
csa_tv.shared = true;
list_add(&csa_tv.head, &list);
amdgpu_vm_get_pd_bo(vm, &list, &pd);
r = ttm_eu_reserve_buffers(&ticket, &list, true, NULL);
if (r) {
DRM_ERROR("failed to reserve CSA,PD BOs: err=%d\n", r);
return r;
}
bo_va = amdgpu_vm_bo_add(adev, vm, adev->virt.csa_obj);
if (!bo_va) {
ttm_eu_backoff_reservation(&ticket, &list);
DRM_ERROR("failed to create bo_va for static CSA\n");
return -ENOMEM;
}
r = amdgpu_vm_bo_map(adev, bo_va, AMDGPU_CSA_VADDR, 0,AMDGPU_CSA_SIZE,
AMDGPU_PTE_READABLE | AMDGPU_PTE_WRITEABLE |
AMDGPU_PTE_EXECUTABLE);
if (r) {
DRM_ERROR("failed to do bo_map on static CSA, err=%d\n", r);
amdgpu_vm_bo_rmv(adev, bo_va);
ttm_eu_backoff_reservation(&ticket, &list);
kfree(bo_va);
return r;
}
vm->csa_bo_va = bo_va;
ttm_eu_backoff_reservation(&ticket, &list);
return 0;
}
void amdgpu_virt_init_setting(struct amdgpu_device *adev)
{
/* enable virtual display */
adev->mode_info.num_crtc = 1;
adev->enable_virtual_display = true;
mutex_init(&adev->virt.lock);
}
uint32_t amdgpu_virt_kiq_rreg(struct amdgpu_device *adev, uint32_t reg)
{
signed long r;
uint32_t val;
struct dma_fence *f;
struct amdgpu_kiq *kiq = &adev->gfx.kiq;
struct amdgpu_ring *ring = &kiq->ring;
BUG_ON(!ring->funcs->emit_rreg);
mutex_lock(&adev->virt.lock);
amdgpu_ring_alloc(ring, 32);
amdgpu_ring_emit_hdp_flush(ring);
amdgpu_ring_emit_rreg(ring, reg);
amdgpu_ring_emit_hdp_invalidate(ring);
amdgpu_fence_emit(ring, &f);
amdgpu_ring_commit(ring);
mutex_unlock(&adev->virt.lock);
r = dma_fence_wait(f, false);
if (r)
DRM_ERROR("wait for kiq fence error: %ld.\n", r);
dma_fence_put(f);
val = adev->wb.wb[adev->virt.reg_val_offs];
return val;
}
void amdgpu_virt_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v)
{
signed long r;
struct dma_fence *f;
struct amdgpu_kiq *kiq = &adev->gfx.kiq;
struct amdgpu_ring *ring = &kiq->ring;
BUG_ON(!ring->funcs->emit_wreg);
mutex_lock(&adev->virt.lock);
amdgpu_ring_alloc(ring, 32);
amdgpu_ring_emit_hdp_flush(ring);
amdgpu_ring_emit_wreg(ring, reg, v);
amdgpu_ring_emit_hdp_invalidate(ring);
amdgpu_fence_emit(ring, &f);
amdgpu_ring_commit(ring);
mutex_unlock(&adev->virt.lock);
r = dma_fence_wait(f, false);
if (r)
DRM_ERROR("wait for kiq fence error: %ld.\n", r);
dma_fence_put(f);
}
/**
* amdgpu_virt_request_full_gpu() - request full gpu access
* @amdgpu: amdgpu device.
* @init: is driver init time.
* When start to init/fini driver, first need to request full gpu access.
* Return: Zero if request success, otherwise will return error.
*/
int amdgpu_virt_request_full_gpu(struct amdgpu_device *adev, bool init)
{
struct amdgpu_virt *virt = &adev->virt;
int r;
if (virt->ops && virt->ops->req_full_gpu) {
r = virt->ops->req_full_gpu(adev, init);
if (r)
return r;
adev->virt.caps &= ~AMDGPU_SRIOV_CAPS_RUNTIME;
}
return 0;
}
/**
* amdgpu_virt_release_full_gpu() - release full gpu access
* @amdgpu: amdgpu device.
* @init: is driver init time.
* When finishing driver init/fini, need to release full gpu access.
* Return: Zero if release success, otherwise will returen error.
*/
int amdgpu_virt_release_full_gpu(struct amdgpu_device *adev, bool init)
{
struct amdgpu_virt *virt = &adev->virt;
int r;
if (virt->ops && virt->ops->rel_full_gpu) {
r = virt->ops->rel_full_gpu(adev, init);
if (r)
return r;
adev->virt.caps |= AMDGPU_SRIOV_CAPS_RUNTIME;
}
return 0;
}
/**
* amdgpu_virt_reset_gpu() - reset gpu
* @amdgpu: amdgpu device.
* Send reset command to GPU hypervisor to reset GPU that VM is using
* Return: Zero if reset success, otherwise will return error.
*/
int amdgpu_virt_reset_gpu(struct amdgpu_device *adev)
{
struct amdgpu_virt *virt = &adev->virt;
int r;
if (virt->ops && virt->ops->reset_gpu) {
r = virt->ops->reset_gpu(adev);
if (r)
return r;
adev->virt.caps &= ~AMDGPU_SRIOV_CAPS_RUNTIME;
}
return 0;
}
...@@ -28,22 +28,48 @@ ...@@ -28,22 +28,48 @@
#define AMDGPU_SRIOV_CAPS_ENABLE_IOV (1 << 1) /* sr-iov is enabled on this GPU */ #define AMDGPU_SRIOV_CAPS_ENABLE_IOV (1 << 1) /* sr-iov is enabled on this GPU */
#define AMDGPU_SRIOV_CAPS_IS_VF (1 << 2) /* this GPU is a virtual function */ #define AMDGPU_SRIOV_CAPS_IS_VF (1 << 2) /* this GPU is a virtual function */
#define AMDGPU_PASSTHROUGH_MODE (1 << 3) /* thw whole GPU is pass through for VM */ #define AMDGPU_PASSTHROUGH_MODE (1 << 3) /* thw whole GPU is pass through for VM */
#define AMDGPU_SRIOV_CAPS_RUNTIME (1 << 4) /* is out of full access mode */
/**
* struct amdgpu_virt_ops - amdgpu device virt operations
*/
struct amdgpu_virt_ops {
int (*req_full_gpu)(struct amdgpu_device *adev, bool init);
int (*rel_full_gpu)(struct amdgpu_device *adev, bool init);
int (*reset_gpu)(struct amdgpu_device *adev);
};
/* GPU virtualization */ /* GPU virtualization */
struct amdgpu_virtualization { struct amdgpu_virt {
uint32_t virtual_caps; uint32_t caps;
struct amdgpu_bo *csa_obj;
uint64_t csa_vmid0_addr;
bool chained_ib_support;
uint32_t reg_val_offs;
struct mutex lock;
struct amdgpu_irq_src ack_irq;
struct amdgpu_irq_src rcv_irq;
struct delayed_work flr_work;
const struct amdgpu_virt_ops *ops;
}; };
#define AMDGPU_CSA_SIZE (8 * 1024)
#define AMDGPU_CSA_VADDR (AMDGPU_VA_RESERVED_SIZE - AMDGPU_CSA_SIZE)
#define amdgpu_sriov_enabled(adev) \ #define amdgpu_sriov_enabled(adev) \
((adev)->virtualization.virtual_caps & AMDGPU_SRIOV_CAPS_ENABLE_IOV) ((adev)->virt.caps & AMDGPU_SRIOV_CAPS_ENABLE_IOV)
#define amdgpu_sriov_vf(adev) \ #define amdgpu_sriov_vf(adev) \
((adev)->virtualization.virtual_caps & AMDGPU_SRIOV_CAPS_IS_VF) ((adev)->virt.caps & AMDGPU_SRIOV_CAPS_IS_VF)
#define amdgpu_sriov_bios(adev) \ #define amdgpu_sriov_bios(adev) \
((adev)->virtualization.virtual_caps & AMDGPU_SRIOV_CAPS_SRIOV_VBIOS) ((adev)->virt.caps & AMDGPU_SRIOV_CAPS_SRIOV_VBIOS)
#define amdgpu_sriov_runtime(adev) \
((adev)->virt.caps & AMDGPU_SRIOV_CAPS_RUNTIME)
#define amdgpu_passthrough(adev) \ #define amdgpu_passthrough(adev) \
((adev)->virtualization.virtual_caps & AMDGPU_PASSTHROUGH_MODE) ((adev)->virt.caps & AMDGPU_PASSTHROUGH_MODE)
static inline bool is_virtual_machine(void) static inline bool is_virtual_machine(void)
{ {
...@@ -54,4 +80,14 @@ static inline bool is_virtual_machine(void) ...@@ -54,4 +80,14 @@ static inline bool is_virtual_machine(void)
#endif #endif
} }
#endif struct amdgpu_vm;
\ No newline at end of file int amdgpu_allocate_static_csa(struct amdgpu_device *adev);
int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm);
void amdgpu_virt_init_setting(struct amdgpu_device *adev);
uint32_t amdgpu_virt_kiq_rreg(struct amdgpu_device *adev, uint32_t reg);
void amdgpu_virt_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v);
int amdgpu_virt_request_full_gpu(struct amdgpu_device *adev, bool init);
int amdgpu_virt_release_full_gpu(struct amdgpu_device *adev, bool init);
int amdgpu_virt_reset_gpu(struct amdgpu_device *adev);
#endif
...@@ -1293,7 +1293,7 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev, ...@@ -1293,7 +1293,7 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev,
int amdgpu_vm_bo_map(struct amdgpu_device *adev, int amdgpu_vm_bo_map(struct amdgpu_device *adev,
struct amdgpu_bo_va *bo_va, struct amdgpu_bo_va *bo_va,
uint64_t saddr, uint64_t offset, uint64_t saddr, uint64_t offset,
uint64_t size, uint32_t flags) uint64_t size, uint64_t flags)
{ {
struct amdgpu_bo_va_mapping *mapping; struct amdgpu_bo_va_mapping *mapping;
struct amdgpu_vm *vm = bo_va->vm; struct amdgpu_vm *vm = bo_va->vm;
......
...@@ -111,6 +111,8 @@ struct amdgpu_vm { ...@@ -111,6 +111,8 @@ struct amdgpu_vm {
/* client id */ /* client id */
u64 client_id; u64 client_id;
/* each VM will map on CSA */
struct amdgpu_bo_va *csa_bo_va;
}; };
struct amdgpu_vm_id { struct amdgpu_vm_id {
...@@ -195,7 +197,7 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev, ...@@ -195,7 +197,7 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev,
int amdgpu_vm_bo_map(struct amdgpu_device *adev, int amdgpu_vm_bo_map(struct amdgpu_device *adev,
struct amdgpu_bo_va *bo_va, struct amdgpu_bo_va *bo_va,
uint64_t addr, uint64_t offset, uint64_t addr, uint64_t offset,
uint64_t size, uint32_t flags); uint64_t size, uint64_t flags);
int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
struct amdgpu_bo_va *bo_va, struct amdgpu_bo_va *bo_va,
uint64_t addr); uint64_t addr);
......
...@@ -181,9 +181,6 @@ void amdgpu_atombios_encoder_init_backlight(struct amdgpu_encoder *amdgpu_encode ...@@ -181,9 +181,6 @@ void amdgpu_atombios_encoder_init_backlight(struct amdgpu_encoder *amdgpu_encode
if (!amdgpu_encoder->enc_priv) if (!amdgpu_encoder->enc_priv)
return; return;
if (!adev->is_atom_bios)
return;
if (!(adev->mode_info.firmware_flags & ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU)) if (!(adev->mode_info.firmware_flags & ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU))
return; return;
...@@ -236,9 +233,6 @@ amdgpu_atombios_encoder_fini_backlight(struct amdgpu_encoder *amdgpu_encoder) ...@@ -236,9 +233,6 @@ amdgpu_atombios_encoder_fini_backlight(struct amdgpu_encoder *amdgpu_encoder)
if (!amdgpu_encoder->enc_priv) if (!amdgpu_encoder->enc_priv)
return; return;
if (!adev->is_atom_bios)
return;
if (!(adev->mode_info.firmware_flags & ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU)) if (!(adev->mode_info.firmware_flags & ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU))
return; return;
......
...@@ -889,7 +889,16 @@ static void ci_dpm_powergate_uvd(struct amdgpu_device *adev, bool gate) ...@@ -889,7 +889,16 @@ static void ci_dpm_powergate_uvd(struct amdgpu_device *adev, bool gate)
pi->uvd_power_gated = gate; pi->uvd_power_gated = gate;
ci_update_uvd_dpm(adev, gate); if (gate) {
/* stop the UVD block */
amdgpu_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_UVD,
AMD_PG_STATE_GATE);
ci_update_uvd_dpm(adev, gate);
} else {
amdgpu_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_UVD,
AMD_PG_STATE_UNGATE);
ci_update_uvd_dpm(adev, gate);
}
} }
static bool ci_dpm_vblank_too_short(struct amdgpu_device *adev) static bool ci_dpm_vblank_too_short(struct amdgpu_device *adev)
...@@ -4336,13 +4345,13 @@ static u32 ci_get_lowest_enabled_level(struct amdgpu_device *adev, ...@@ -4336,13 +4345,13 @@ static u32 ci_get_lowest_enabled_level(struct amdgpu_device *adev,
static int ci_dpm_force_performance_level(struct amdgpu_device *adev, static int ci_dpm_force_performance_level(struct amdgpu_device *adev,
enum amdgpu_dpm_forced_level level) enum amd_dpm_forced_level level)
{ {
struct ci_power_info *pi = ci_get_pi(adev); struct ci_power_info *pi = ci_get_pi(adev);
u32 tmp, levels, i; u32 tmp, levels, i;
int ret; int ret;
if (level == AMDGPU_DPM_FORCED_LEVEL_HIGH) { if (level == AMD_DPM_FORCED_LEVEL_HIGH) {
if ((!pi->pcie_dpm_key_disabled) && if ((!pi->pcie_dpm_key_disabled) &&
pi->dpm_level_enable_mask.pcie_dpm_enable_mask) { pi->dpm_level_enable_mask.pcie_dpm_enable_mask) {
levels = 0; levels = 0;
...@@ -4403,7 +4412,7 @@ static int ci_dpm_force_performance_level(struct amdgpu_device *adev, ...@@ -4403,7 +4412,7 @@ static int ci_dpm_force_performance_level(struct amdgpu_device *adev,
} }
} }
} }
} else if (level == AMDGPU_DPM_FORCED_LEVEL_LOW) { } else if (level == AMD_DPM_FORCED_LEVEL_LOW) {
if ((!pi->sclk_dpm_key_disabled) && if ((!pi->sclk_dpm_key_disabled) &&
pi->dpm_level_enable_mask.sclk_dpm_enable_mask) { pi->dpm_level_enable_mask.sclk_dpm_enable_mask) {
levels = ci_get_lowest_enabled_level(adev, levels = ci_get_lowest_enabled_level(adev,
...@@ -4452,7 +4461,7 @@ static int ci_dpm_force_performance_level(struct amdgpu_device *adev, ...@@ -4452,7 +4461,7 @@ static int ci_dpm_force_performance_level(struct amdgpu_device *adev,
udelay(1); udelay(1);
} }
} }
} else if (level == AMDGPU_DPM_FORCED_LEVEL_AUTO) { } else if (level == AMD_DPM_FORCED_LEVEL_AUTO) {
if (!pi->pcie_dpm_key_disabled) { if (!pi->pcie_dpm_key_disabled) {
PPSMC_Result smc_result; PPSMC_Result smc_result;
...@@ -6262,7 +6271,7 @@ static int ci_dpm_sw_init(void *handle) ...@@ -6262,7 +6271,7 @@ static int ci_dpm_sw_init(void *handle)
/* default to balanced state */ /* default to balanced state */
adev->pm.dpm.state = POWER_STATE_TYPE_BALANCED; adev->pm.dpm.state = POWER_STATE_TYPE_BALANCED;
adev->pm.dpm.user_state = POWER_STATE_TYPE_BALANCED; adev->pm.dpm.user_state = POWER_STATE_TYPE_BALANCED;
adev->pm.dpm.forced_level = AMDGPU_DPM_FORCED_LEVEL_AUTO; adev->pm.dpm.forced_level = AMD_DPM_FORCED_LEVEL_AUTO;
adev->pm.default_sclk = adev->clock.default_sclk; adev->pm.default_sclk = adev->clock.default_sclk;
adev->pm.default_mclk = adev->clock.default_mclk; adev->pm.default_mclk = adev->clock.default_mclk;
adev->pm.current_sclk = adev->clock.default_sclk; adev->pm.current_sclk = adev->clock.default_sclk;
...@@ -6571,8 +6580,9 @@ static int ci_dpm_force_clock_level(struct amdgpu_device *adev, ...@@ -6571,8 +6580,9 @@ static int ci_dpm_force_clock_level(struct amdgpu_device *adev,
{ {
struct ci_power_info *pi = ci_get_pi(adev); struct ci_power_info *pi = ci_get_pi(adev);
if (adev->pm.dpm.forced_level if (adev->pm.dpm.forced_level & (AMD_DPM_FORCED_LEVEL_AUTO |
!= AMDGPU_DPM_FORCED_LEVEL_MANUAL) AMD_DPM_FORCED_LEVEL_LOW |
AMD_DPM_FORCED_LEVEL_HIGH))
return -EINVAL; return -EINVAL;
switch (type) { switch (type) {
...@@ -6739,12 +6749,3 @@ static void ci_dpm_set_irq_funcs(struct amdgpu_device *adev) ...@@ -6739,12 +6749,3 @@ static void ci_dpm_set_irq_funcs(struct amdgpu_device *adev)
adev->pm.dpm.thermal.irq.num_types = AMDGPU_THERMAL_IRQ_LAST; adev->pm.dpm.thermal.irq.num_types = AMDGPU_THERMAL_IRQ_LAST;
adev->pm.dpm.thermal.irq.funcs = &ci_dpm_irq_funcs; adev->pm.dpm.thermal.irq.funcs = &ci_dpm_irq_funcs;
} }
const struct amdgpu_ip_block_version ci_dpm_ip_block =
{
.type = AMD_IP_BLOCK_TYPE_SMC,
.major = 7,
.minor = 0,
.rev = 0,
.funcs = &ci_dpm_ip_funcs,
};
...@@ -1627,14 +1627,13 @@ static uint32_t cik_get_rev_id(struct amdgpu_device *adev) ...@@ -1627,14 +1627,13 @@ static uint32_t cik_get_rev_id(struct amdgpu_device *adev)
static void cik_detect_hw_virtualization(struct amdgpu_device *adev) static void cik_detect_hw_virtualization(struct amdgpu_device *adev)
{ {
if (is_virtual_machine()) /* passthrough mode */ if (is_virtual_machine()) /* passthrough mode */
adev->virtualization.virtual_caps |= AMDGPU_PASSTHROUGH_MODE; adev->virt.caps |= AMDGPU_PASSTHROUGH_MODE;
} }
static const struct amdgpu_asic_funcs cik_asic_funcs = static const struct amdgpu_asic_funcs cik_asic_funcs =
{ {
.read_disabled_bios = &cik_read_disabled_bios, .read_disabled_bios = &cik_read_disabled_bios,
.read_bios_from_rom = &cik_read_bios_from_rom, .read_bios_from_rom = &cik_read_bios_from_rom,
.detect_hw_virtualization = cik_detect_hw_virtualization,
.read_register = &cik_read_register, .read_register = &cik_read_register,
.reset = &cik_asic_reset, .reset = &cik_asic_reset,
.set_vga_state = &cik_vga_set_state, .set_vga_state = &cik_vga_set_state,
...@@ -1890,6 +1889,8 @@ static const struct amdgpu_ip_block_version cik_common_ip_block = ...@@ -1890,6 +1889,8 @@ static const struct amdgpu_ip_block_version cik_common_ip_block =
int cik_set_ip_blocks(struct amdgpu_device *adev) int cik_set_ip_blocks(struct amdgpu_device *adev)
{ {
cik_detect_hw_virtualization(adev);
switch (adev->asic_type) { switch (adev->asic_type) {
case CHIP_BONAIRE: case CHIP_BONAIRE:
amdgpu_ip_block_add(adev, &cik_common_ip_block); amdgpu_ip_block_add(adev, &cik_common_ip_block);
......
...@@ -651,7 +651,7 @@ static int cik_sdma_ring_test_ib(struct amdgpu_ring *ring, long timeout) ...@@ -651,7 +651,7 @@ static int cik_sdma_ring_test_ib(struct amdgpu_ring *ring, long timeout)
ib.ptr[3] = 1; ib.ptr[3] = 1;
ib.ptr[4] = 0xDEADBEEF; ib.ptr[4] = 0xDEADBEEF;
ib.length_dw = 5; ib.length_dw = 5;
r = amdgpu_ib_schedule(ring, 1, &ib, NULL, NULL, &f); r = amdgpu_ib_schedule(ring, 1, &ib, NULL, &f);
if (r) if (r)
goto err1; goto err1;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include "amdgpu_ih.h" #include "amdgpu_ih.h"
#include "amdgpu_gfx.h" #include "amdgpu_gfx.h"
#include "amdgpu_ucode.h" #include "amdgpu_ucode.h"
#include "si/clearstate_si.h" #include "clearstate_si.h"
#include "bif/bif_3_0_d.h" #include "bif/bif_3_0_d.h"
#include "bif/bif_3_0_sh_mask.h" #include "bif/bif_3_0_sh_mask.h"
#include "oss/oss_1_0_d.h" #include "oss/oss_1_0_d.h"
...@@ -1794,14 +1794,9 @@ static void gfx_v6_0_gpu_init(struct amdgpu_device *adev) ...@@ -1794,14 +1794,9 @@ static void gfx_v6_0_gpu_init(struct amdgpu_device *adev)
static void gfx_v6_0_scratch_init(struct amdgpu_device *adev) static void gfx_v6_0_scratch_init(struct amdgpu_device *adev)
{ {
int i;
adev->gfx.scratch.num_reg = 7; adev->gfx.scratch.num_reg = 7;
adev->gfx.scratch.reg_base = mmSCRATCH_REG0; adev->gfx.scratch.reg_base = mmSCRATCH_REG0;
for (i = 0; i < adev->gfx.scratch.num_reg; i++) { adev->gfx.scratch.free_mask = (1u << adev->gfx.scratch.num_reg) - 1;
adev->gfx.scratch.free[i] = true;
adev->gfx.scratch.reg[i] = adev->gfx.scratch.reg_base + i;
}
} }
static int gfx_v6_0_ring_test_ring(struct amdgpu_ring *ring) static int gfx_v6_0_ring_test_ring(struct amdgpu_ring *ring)
...@@ -1975,7 +1970,7 @@ static int gfx_v6_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) ...@@ -1975,7 +1970,7 @@ static int gfx_v6_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
ib.ptr[2] = 0xDEADBEEF; ib.ptr[2] = 0xDEADBEEF;
ib.length_dw = 3; ib.length_dw = 3;
r = amdgpu_ib_schedule(ring, 1, &ib, NULL, NULL, &f); r = amdgpu_ib_schedule(ring, 1, &ib, NULL, &f);
if (r) if (r)
goto err2; goto err2;
......
...@@ -2003,14 +2003,9 @@ static void gfx_v7_0_gpu_init(struct amdgpu_device *adev) ...@@ -2003,14 +2003,9 @@ static void gfx_v7_0_gpu_init(struct amdgpu_device *adev)
*/ */
static void gfx_v7_0_scratch_init(struct amdgpu_device *adev) static void gfx_v7_0_scratch_init(struct amdgpu_device *adev)
{ {
int i;
adev->gfx.scratch.num_reg = 7; adev->gfx.scratch.num_reg = 7;
adev->gfx.scratch.reg_base = mmSCRATCH_REG0; adev->gfx.scratch.reg_base = mmSCRATCH_REG0;
for (i = 0; i < adev->gfx.scratch.num_reg; i++) { adev->gfx.scratch.free_mask = (1u << adev->gfx.scratch.num_reg) - 1;
adev->gfx.scratch.free[i] = true;
adev->gfx.scratch.reg[i] = adev->gfx.scratch.reg_base + i;
}
} }
/** /**
...@@ -2321,7 +2316,7 @@ static int gfx_v7_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) ...@@ -2321,7 +2316,7 @@ static int gfx_v7_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
ib.ptr[2] = 0xDEADBEEF; ib.ptr[2] = 0xDEADBEEF;
ib.length_dw = 3; ib.length_dw = 3;
r = amdgpu_ib_schedule(ring, 1, &ib, NULL, NULL, &f); r = amdgpu_ib_schedule(ring, 1, &ib, NULL, &f);
if (r) if (r)
goto err2; goto err2;
......
...@@ -375,9 +375,16 @@ static int gmc_v7_0_mc_init(struct amdgpu_device *adev) ...@@ -375,9 +375,16 @@ static int gmc_v7_0_mc_init(struct amdgpu_device *adev)
/* size in MB on si */ /* size in MB on si */
adev->mc.mc_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL; adev->mc.mc_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL;
adev->mc.real_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL; adev->mc.real_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL;
adev->mc.visible_vram_size = adev->mc.aper_size;
#ifdef CONFIG_X86_64
if (adev->flags & AMD_IS_APU) {
adev->mc.aper_base = ((u64)RREG32(mmMC_VM_FB_OFFSET)) << 22;
adev->mc.aper_size = adev->mc.real_vram_size;
}
#endif
/* In case the PCI BAR is larger than the actual amount of vram */ /* In case the PCI BAR is larger than the actual amount of vram */
adev->mc.visible_vram_size = adev->mc.aper_size;
if (adev->mc.visible_vram_size > adev->mc.real_vram_size) if (adev->mc.visible_vram_size > adev->mc.real_vram_size)
adev->mc.visible_vram_size = adev->mc.real_vram_size; adev->mc.visible_vram_size = adev->mc.real_vram_size;
......
...@@ -467,9 +467,16 @@ static int gmc_v8_0_mc_init(struct amdgpu_device *adev) ...@@ -467,9 +467,16 @@ static int gmc_v8_0_mc_init(struct amdgpu_device *adev)
/* size in MB on si */ /* size in MB on si */
adev->mc.mc_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL; adev->mc.mc_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL;
adev->mc.real_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL; adev->mc.real_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL;
adev->mc.visible_vram_size = adev->mc.aper_size;
#ifdef CONFIG_X86_64
if (adev->flags & AMD_IS_APU) {
adev->mc.aper_base = ((u64)RREG32(mmMC_VM_FB_OFFSET)) << 22;
adev->mc.aper_size = adev->mc.real_vram_size;
}
#endif
/* In case the PCI BAR is larger than the actual amount of vram */ /* In case the PCI BAR is larger than the actual amount of vram */
adev->mc.visible_vram_size = adev->mc.aper_size;
if (adev->mc.visible_vram_size > adev->mc.real_vram_size) if (adev->mc.visible_vram_size > adev->mc.real_vram_size)
adev->mc.visible_vram_size = adev->mc.real_vram_size; adev->mc.visible_vram_size = adev->mc.real_vram_size;
...@@ -1439,6 +1446,21 @@ static int gmc_v8_0_set_powergating_state(void *handle, ...@@ -1439,6 +1446,21 @@ static int gmc_v8_0_set_powergating_state(void *handle,
return 0; return 0;
} }
static void gmc_v8_0_get_clockgating_state(void *handle, u32 *flags)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
int data;
/* AMD_CG_SUPPORT_MC_MGCG */
data = RREG32(mmMC_HUB_MISC_HUB_CG);
if (data & MC_HUB_MISC_HUB_CG__ENABLE_MASK)
*flags |= AMD_CG_SUPPORT_MC_MGCG;
/* AMD_CG_SUPPORT_MC_LS */
if (data & MC_HUB_MISC_HUB_CG__MEM_LS_ENABLE_MASK)
*flags |= AMD_CG_SUPPORT_MC_LS;
}
static const struct amd_ip_funcs gmc_v8_0_ip_funcs = { static const struct amd_ip_funcs gmc_v8_0_ip_funcs = {
.name = "gmc_v8_0", .name = "gmc_v8_0",
.early_init = gmc_v8_0_early_init, .early_init = gmc_v8_0_early_init,
...@@ -1457,6 +1479,7 @@ static const struct amd_ip_funcs gmc_v8_0_ip_funcs = { ...@@ -1457,6 +1479,7 @@ static const struct amd_ip_funcs gmc_v8_0_ip_funcs = {
.post_soft_reset = gmc_v8_0_post_soft_reset, .post_soft_reset = gmc_v8_0_post_soft_reset,
.set_clockgating_state = gmc_v8_0_set_clockgating_state, .set_clockgating_state = gmc_v8_0_set_clockgating_state,
.set_powergating_state = gmc_v8_0_set_powergating_state, .set_powergating_state = gmc_v8_0_set_powergating_state,
.get_clockgating_state = gmc_v8_0_get_clockgating_state,
}; };
static const struct amdgpu_gart_funcs gmc_v8_0_gart_funcs = { static const struct amdgpu_gart_funcs gmc_v8_0_gart_funcs = {
......
此差异已折叠。
此差异已折叠。
...@@ -701,7 +701,7 @@ static int sdma_v2_4_ring_test_ib(struct amdgpu_ring *ring, long timeout) ...@@ -701,7 +701,7 @@ static int sdma_v2_4_ring_test_ib(struct amdgpu_ring *ring, long timeout)
ib.ptr[7] = SDMA_PKT_HEADER_OP(SDMA_OP_NOP); ib.ptr[7] = SDMA_PKT_HEADER_OP(SDMA_OP_NOP);
ib.length_dw = 8; ib.length_dw = 8;
r = amdgpu_ib_schedule(ring, 1, &ib, NULL, NULL, &f); r = amdgpu_ib_schedule(ring, 1, &ib, NULL, &f);
if (r) if (r)
goto err1; goto err1;
......
...@@ -910,7 +910,7 @@ static int sdma_v3_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) ...@@ -910,7 +910,7 @@ static int sdma_v3_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
ib.ptr[7] = SDMA_PKT_NOP_HEADER_OP(SDMA_OP_NOP); ib.ptr[7] = SDMA_PKT_NOP_HEADER_OP(SDMA_OP_NOP);
ib.length_dw = 8; ib.length_dw = 8;
r = amdgpu_ib_schedule(ring, 1, &ib, NULL, NULL, &f); r = amdgpu_ib_schedule(ring, 1, &ib, NULL, &f);
if (r) if (r)
goto err1; goto err1;
...@@ -1533,6 +1533,22 @@ static int sdma_v3_0_set_powergating_state(void *handle, ...@@ -1533,6 +1533,22 @@ static int sdma_v3_0_set_powergating_state(void *handle,
return 0; return 0;
} }
static void sdma_v3_0_get_clockgating_state(void *handle, u32 *flags)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
int data;
/* AMD_CG_SUPPORT_SDMA_MGCG */
data = RREG32(mmSDMA0_CLK_CTRL + sdma_offsets[0]);
if (!(data & SDMA0_CLK_CTRL__SOFT_OVERRIDE0_MASK))
*flags |= AMD_CG_SUPPORT_SDMA_MGCG;
/* AMD_CG_SUPPORT_SDMA_LS */
data = RREG32(mmSDMA0_POWER_CNTL + sdma_offsets[0]);
if (data & SDMA0_POWER_CNTL__MEM_POWER_OVERRIDE_MASK)
*flags |= AMD_CG_SUPPORT_SDMA_LS;
}
static const struct amd_ip_funcs sdma_v3_0_ip_funcs = { static const struct amd_ip_funcs sdma_v3_0_ip_funcs = {
.name = "sdma_v3_0", .name = "sdma_v3_0",
.early_init = sdma_v3_0_early_init, .early_init = sdma_v3_0_early_init,
...@@ -1551,6 +1567,7 @@ static const struct amd_ip_funcs sdma_v3_0_ip_funcs = { ...@@ -1551,6 +1567,7 @@ static const struct amd_ip_funcs sdma_v3_0_ip_funcs = {
.soft_reset = sdma_v3_0_soft_reset, .soft_reset = sdma_v3_0_soft_reset,
.set_clockgating_state = sdma_v3_0_set_clockgating_state, .set_clockgating_state = sdma_v3_0_set_clockgating_state,
.set_powergating_state = sdma_v3_0_set_powergating_state, .set_powergating_state = sdma_v3_0_set_powergating_state,
.get_clockgating_state = sdma_v3_0_get_clockgating_state,
}; };
static const struct amdgpu_ring_funcs sdma_v3_0_ring_funcs = { static const struct amdgpu_ring_funcs sdma_v3_0_ring_funcs = {
......
此差异已折叠。
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include <drm/drmP.h> #include <drm/drmP.h>
#include "amdgpu.h" #include "amdgpu.h"
#include "amdgpu_trace.h" #include "amdgpu_trace.h"
#include "si/sid.h" #include "sid.h"
const u32 sdma_offsets[SDMA_MAX_INSTANCE] = const u32 sdma_offsets[SDMA_MAX_INSTANCE] =
{ {
...@@ -301,7 +301,7 @@ static int si_dma_ring_test_ib(struct amdgpu_ring *ring, long timeout) ...@@ -301,7 +301,7 @@ static int si_dma_ring_test_ib(struct amdgpu_ring *ring, long timeout)
ib.ptr[2] = upper_32_bits(gpu_addr) & 0xff; ib.ptr[2] = upper_32_bits(gpu_addr) & 0xff;
ib.ptr[3] = 0xDEADBEEF; ib.ptr[3] = 0xDEADBEEF;
ib.length_dw = 4; ib.length_dw = 4;
r = amdgpu_ib_schedule(ring, 1, &ib, NULL, NULL, &f); r = amdgpu_ib_schedule(ring, 1, &ib, NULL, &f);
if (r) if (r)
goto err1; goto err1;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册