Merge tag 'drm-next-5.4-2019-08-23' of git://people.freedesktop.org/~agd5f/linux into drm-next
drm-next-5.4-2019-08-23: amdgpu: - Enable power features on Navi12 - Enable power features on Arcturus - RAS updates - Initial Renoir APU support - Enable power featyres on Renoir - DC gamma fixes - DCN2 fixes - GPU reset support for Picasso - Misc cleanups and fixes scheduler: - Possible race fix Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexdeucher@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190823202620.3870-1-alexander.deucher@amd.com
This commit is contained in:
@@ -100,7 +100,8 @@ amdgpu-y += \
|
||||
amdgpu_psp.o \
|
||||
psp_v3_1.o \
|
||||
psp_v10_0.o \
|
||||
psp_v11_0.o
|
||||
psp_v11_0.o \
|
||||
psp_v12_0.o
|
||||
|
||||
# add SMC block
|
||||
amdgpu-y += \
|
||||
@@ -154,6 +155,7 @@ amdgpu-y += \
|
||||
|
||||
# add ATHUB block
|
||||
amdgpu-y += \
|
||||
athub_v1_0.o \
|
||||
athub_v2_0.o
|
||||
|
||||
# add amdkfd interfaces
|
||||
|
@@ -87,6 +87,7 @@
|
||||
#include "amdgpu_discovery.h"
|
||||
#include "amdgpu_mes.h"
|
||||
#include "amdgpu_umc.h"
|
||||
#include "amdgpu_mmhub.h"
|
||||
|
||||
#define MAX_GPU_INSTANCE 16
|
||||
|
||||
@@ -788,7 +789,6 @@ struct amdgpu_device {
|
||||
int usec_timeout;
|
||||
const struct amdgpu_asic_funcs *asic_funcs;
|
||||
bool shutdown;
|
||||
bool need_dma32;
|
||||
bool need_swiotlb;
|
||||
bool accel_working;
|
||||
struct notifier_block acpi_nb;
|
||||
@@ -976,6 +976,7 @@ struct amdgpu_device {
|
||||
|
||||
const struct amdgpu_nbio_funcs *nbio_funcs;
|
||||
const struct amdgpu_df_funcs *df_funcs;
|
||||
const struct amdgpu_mmhub_funcs *mmhub_funcs;
|
||||
|
||||
/* delayed work_func for deferring clockgating during resume */
|
||||
struct delayed_work delayed_init_work;
|
||||
|
@@ -801,42 +801,6 @@ static uint16_t get_atc_vmid_pasid_mapping_pasid(struct kgd_dev *kgd,
|
||||
return reg & ATC_VMID0_PASID_MAPPING__PASID_MASK;
|
||||
}
|
||||
|
||||
static void write_vmid_invalidate_request(struct kgd_dev *kgd, uint8_t vmid)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
|
||||
uint32_t req = (1 << vmid) |
|
||||
(0 << GCVM_INVALIDATE_ENG0_REQ__FLUSH_TYPE__SHIFT) |/* legacy */
|
||||
GCVM_INVALIDATE_ENG0_REQ__INVALIDATE_L2_PTES_MASK |
|
||||
GCVM_INVALIDATE_ENG0_REQ__INVALIDATE_L2_PDE0_MASK |
|
||||
GCVM_INVALIDATE_ENG0_REQ__INVALIDATE_L2_PDE1_MASK |
|
||||
GCVM_INVALIDATE_ENG0_REQ__INVALIDATE_L2_PDE2_MASK |
|
||||
GCVM_INVALIDATE_ENG0_REQ__INVALIDATE_L1_PTES_MASK;
|
||||
|
||||
mutex_lock(&adev->srbm_mutex);
|
||||
|
||||
/* Use light weight invalidation.
|
||||
*
|
||||
* TODO 1: agree on the right set of invalidation registers for
|
||||
* KFD use. Use the last one for now. Invalidate only GCHUB as
|
||||
* SDMA is now moved to GCHUB
|
||||
*
|
||||
* TODO 2: support range-based invalidation, requires kfg2kgd
|
||||
* interface change
|
||||
*/
|
||||
WREG32(SOC15_REG_OFFSET(GC, 0, mmGCVM_INVALIDATE_ENG0_ADDR_RANGE_LO32),
|
||||
0xffffffff);
|
||||
WREG32(SOC15_REG_OFFSET(GC, 0, mmGCVM_INVALIDATE_ENG0_ADDR_RANGE_HI32),
|
||||
0x0000001f);
|
||||
|
||||
WREG32(SOC15_REG_OFFSET(GC, 0, mmGCVM_INVALIDATE_ENG0_REQ), req);
|
||||
|
||||
while (!(RREG32(SOC15_REG_OFFSET(GC, 0, mmGCVM_INVALIDATE_ENG0_ACK)) &
|
||||
(1 << vmid)))
|
||||
cpu_relax();
|
||||
|
||||
mutex_unlock(&adev->srbm_mutex);
|
||||
}
|
||||
|
||||
static int invalidate_tlbs_with_kiq(struct amdgpu_device *adev, uint16_t pasid)
|
||||
{
|
||||
signed long r;
|
||||
@@ -877,7 +841,8 @@ static int invalidate_tlbs(struct kgd_dev *kgd, uint16_t pasid)
|
||||
if (get_atc_vmid_pasid_mapping_valid(kgd, vmid)) {
|
||||
if (get_atc_vmid_pasid_mapping_pasid(kgd, vmid)
|
||||
== pasid) {
|
||||
write_vmid_invalidate_request(kgd, vmid);
|
||||
amdgpu_gmc_flush_gpu_tlb(adev, vmid,
|
||||
AMDGPU_GFXHUB_0, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -895,7 +860,7 @@ static int invalidate_tlbs_vmid(struct kgd_dev *kgd, uint16_t vmid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
write_vmid_invalidate_request(kgd, vmid);
|
||||
amdgpu_gmc_flush_gpu_tlb(adev, vmid, AMDGPU_GFXHUB_0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -670,7 +670,7 @@ static int invalidate_tlbs_with_kiq(struct amdgpu_device *adev, uint16_t pasid,
|
||||
int kgd_gfx_v9_invalidate_tlbs(struct kgd_dev *kgd, uint16_t pasid)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
|
||||
int vmid;
|
||||
int vmid, i;
|
||||
struct amdgpu_ring *ring = &adev->gfx.kiq.ring;
|
||||
uint32_t flush_type = 0;
|
||||
|
||||
@@ -689,8 +689,9 @@ int kgd_gfx_v9_invalidate_tlbs(struct kgd_dev *kgd, uint16_t pasid)
|
||||
if (kgd_gfx_v9_get_atc_vmid_pasid_mapping_valid(kgd, vmid)) {
|
||||
if (kgd_gfx_v9_get_atc_vmid_pasid_mapping_pasid(kgd, vmid)
|
||||
== pasid) {
|
||||
amdgpu_gmc_flush_gpu_tlb(adev, vmid,
|
||||
flush_type);
|
||||
for (i = 0; i < adev->num_vmhubs; i++)
|
||||
amdgpu_gmc_flush_gpu_tlb(adev, vmid,
|
||||
i, flush_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -702,6 +703,7 @@ int kgd_gfx_v9_invalidate_tlbs(struct kgd_dev *kgd, uint16_t pasid)
|
||||
int kgd_gfx_v9_invalidate_tlbs_vmid(struct kgd_dev *kgd, uint16_t vmid)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
|
||||
int i;
|
||||
|
||||
if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid)) {
|
||||
pr_err("non kfd vmid %d\n", vmid);
|
||||
@@ -723,7 +725,9 @@ int kgd_gfx_v9_invalidate_tlbs_vmid(struct kgd_dev *kgd, uint16_t vmid)
|
||||
* TODO 2: support range-based invalidation, requires kfg2kgd
|
||||
* interface change
|
||||
*/
|
||||
amdgpu_gmc_flush_gpu_tlb(adev, vmid, 0);
|
||||
for (i = 0; i < adev->num_vmhubs; i++)
|
||||
amdgpu_gmc_flush_gpu_tlb(adev, vmid, i, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -1143,6 +1143,9 @@ static int amdgpu_cs_process_syncobj_out_dep(struct amdgpu_cs_parser *p,
|
||||
num_deps = chunk->length_dw * 4 /
|
||||
sizeof(struct drm_amdgpu_cs_chunk_sem);
|
||||
|
||||
if (p->post_deps)
|
||||
return -EINVAL;
|
||||
|
||||
p->post_deps = kmalloc_array(num_deps, sizeof(*p->post_deps),
|
||||
GFP_KERNEL);
|
||||
p->num_post_deps = 0;
|
||||
@@ -1166,8 +1169,7 @@ static int amdgpu_cs_process_syncobj_out_dep(struct amdgpu_cs_parser *p,
|
||||
|
||||
|
||||
static int amdgpu_cs_process_syncobj_timeline_out_dep(struct amdgpu_cs_parser *p,
|
||||
struct amdgpu_cs_chunk
|
||||
*chunk)
|
||||
struct amdgpu_cs_chunk *chunk)
|
||||
{
|
||||
struct drm_amdgpu_cs_chunk_syncobj *syncobj_deps;
|
||||
unsigned num_deps;
|
||||
@@ -1177,6 +1179,9 @@ static int amdgpu_cs_process_syncobj_timeline_out_dep(struct amdgpu_cs_parser *p
|
||||
num_deps = chunk->length_dw * 4 /
|
||||
sizeof(struct drm_amdgpu_cs_chunk_syncobj);
|
||||
|
||||
if (p->post_deps)
|
||||
return -EINVAL;
|
||||
|
||||
p->post_deps = kmalloc_array(num_deps, sizeof(*p->post_deps),
|
||||
GFP_KERNEL);
|
||||
p->num_post_deps = 0;
|
||||
|
@@ -42,7 +42,7 @@ const unsigned int amdgpu_ctx_num_entities[AMDGPU_HW_IP_NUM] = {
|
||||
[AMDGPU_HW_IP_VCN_JPEG] = 1,
|
||||
};
|
||||
|
||||
static int amdgput_ctx_total_num_entities(void)
|
||||
static int amdgpu_ctx_total_num_entities(void)
|
||||
{
|
||||
unsigned i, num_entities = 0;
|
||||
|
||||
@@ -73,7 +73,7 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev,
|
||||
struct drm_file *filp,
|
||||
struct amdgpu_ctx *ctx)
|
||||
{
|
||||
unsigned num_entities = amdgput_ctx_total_num_entities();
|
||||
unsigned num_entities = amdgpu_ctx_total_num_entities();
|
||||
unsigned i, j, k;
|
||||
int r;
|
||||
|
||||
@@ -207,7 +207,7 @@ error_free_fences:
|
||||
static void amdgpu_ctx_fini(struct kref *ref)
|
||||
{
|
||||
struct amdgpu_ctx *ctx = container_of(ref, struct amdgpu_ctx, refcount);
|
||||
unsigned num_entities = amdgput_ctx_total_num_entities();
|
||||
unsigned num_entities = amdgpu_ctx_total_num_entities();
|
||||
struct amdgpu_device *adev = ctx->adev;
|
||||
unsigned i, j;
|
||||
|
||||
@@ -289,10 +289,7 @@ static void amdgpu_ctx_do_release(struct kref *ref)
|
||||
|
||||
ctx = container_of(ref, struct amdgpu_ctx, refcount);
|
||||
|
||||
num_entities = 0;
|
||||
for (i = 0; i < AMDGPU_HW_IP_NUM; i++)
|
||||
num_entities += amdgpu_ctx_num_entities[i];
|
||||
|
||||
num_entities = amdgpu_ctx_total_num_entities();
|
||||
for (i = 0; i < num_entities; i++)
|
||||
drm_sched_entity_destroy(&ctx->entities[0][i].entity);
|
||||
|
||||
@@ -354,7 +351,7 @@ static int amdgpu_ctx_query2(struct amdgpu_device *adev,
|
||||
{
|
||||
struct amdgpu_ctx *ctx;
|
||||
struct amdgpu_ctx_mgr *mgr;
|
||||
uint32_t ras_counter;
|
||||
unsigned long ras_counter;
|
||||
|
||||
if (!fpriv)
|
||||
return -EINVAL;
|
||||
@@ -524,7 +521,7 @@ struct dma_fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx,
|
||||
void amdgpu_ctx_priority_override(struct amdgpu_ctx *ctx,
|
||||
enum drm_sched_priority priority)
|
||||
{
|
||||
unsigned num_entities = amdgput_ctx_total_num_entities();
|
||||
unsigned num_entities = amdgpu_ctx_total_num_entities();
|
||||
enum drm_sched_priority ctx_prio;
|
||||
unsigned i;
|
||||
|
||||
@@ -544,21 +541,24 @@ int amdgpu_ctx_wait_prev_fence(struct amdgpu_ctx *ctx,
|
||||
struct drm_sched_entity *entity)
|
||||
{
|
||||
struct amdgpu_ctx_entity *centity = to_amdgpu_ctx_entity(entity);
|
||||
unsigned idx = centity->sequence & (amdgpu_sched_jobs - 1);
|
||||
struct dma_fence *other = centity->fences[idx];
|
||||
struct dma_fence *other;
|
||||
unsigned idx;
|
||||
long r;
|
||||
|
||||
if (other) {
|
||||
signed long r;
|
||||
r = dma_fence_wait(other, true);
|
||||
if (r < 0) {
|
||||
if (r != -ERESTARTSYS)
|
||||
DRM_ERROR("Error (%ld) waiting for fence!\n", r);
|
||||
spin_lock(&ctx->ring_lock);
|
||||
idx = centity->sequence & (amdgpu_sched_jobs - 1);
|
||||
other = dma_fence_get(centity->fences[idx]);
|
||||
spin_unlock(&ctx->ring_lock);
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
if (!other)
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
r = dma_fence_wait(other, true);
|
||||
if (r < 0 && r != -ERESTARTSYS)
|
||||
DRM_ERROR("Error (%ld) waiting for fence!\n", r);
|
||||
|
||||
dma_fence_put(other);
|
||||
return r;
|
||||
}
|
||||
|
||||
void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr)
|
||||
@@ -569,7 +569,7 @@ void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr)
|
||||
|
||||
long amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr, long timeout)
|
||||
{
|
||||
unsigned num_entities = amdgput_ctx_total_num_entities();
|
||||
unsigned num_entities = amdgpu_ctx_total_num_entities();
|
||||
struct amdgpu_ctx *ctx;
|
||||
struct idr *idp;
|
||||
uint32_t id, i;
|
||||
@@ -591,7 +591,7 @@ long amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr, long timeout)
|
||||
|
||||
void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr)
|
||||
{
|
||||
unsigned num_entities = amdgput_ctx_total_num_entities();
|
||||
unsigned num_entities = amdgpu_ctx_total_num_entities();
|
||||
struct amdgpu_ctx *ctx;
|
||||
struct idr *idp;
|
||||
uint32_t id, i;
|
||||
|
@@ -49,8 +49,8 @@ struct amdgpu_ctx {
|
||||
enum drm_sched_priority override_priority;
|
||||
struct mutex lock;
|
||||
atomic_t guilty;
|
||||
uint32_t ras_counter_ce;
|
||||
uint32_t ras_counter_ue;
|
||||
unsigned long ras_counter_ce;
|
||||
unsigned long ras_counter_ue;
|
||||
};
|
||||
|
||||
struct amdgpu_ctx_mgr {
|
||||
|
@@ -71,6 +71,7 @@ MODULE_FIRMWARE("amdgpu/raven_gpu_info.bin");
|
||||
MODULE_FIRMWARE("amdgpu/picasso_gpu_info.bin");
|
||||
MODULE_FIRMWARE("amdgpu/raven2_gpu_info.bin");
|
||||
MODULE_FIRMWARE("amdgpu/arcturus_gpu_info.bin");
|
||||
MODULE_FIRMWARE("amdgpu/renoir_gpu_info.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navi10_gpu_info.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navi14_gpu_info.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navi12_gpu_info.bin");
|
||||
@@ -102,6 +103,7 @@ static const char *amdgpu_asic_name[] = {
|
||||
"VEGA20",
|
||||
"RAVEN",
|
||||
"ARCTURUS",
|
||||
"RENOIR",
|
||||
"NAVI10",
|
||||
"NAVI14",
|
||||
"NAVI12",
|
||||
@@ -1427,6 +1429,9 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev)
|
||||
case CHIP_ARCTURUS:
|
||||
chip_name = "arcturus";
|
||||
break;
|
||||
case CHIP_RENOIR:
|
||||
chip_name = "renoir";
|
||||
break;
|
||||
case CHIP_NAVI10:
|
||||
chip_name = "navi10";
|
||||
break;
|
||||
@@ -1579,7 +1584,9 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
|
||||
case CHIP_VEGA20:
|
||||
case CHIP_RAVEN:
|
||||
case CHIP_ARCTURUS:
|
||||
if (adev->asic_type == CHIP_RAVEN)
|
||||
case CHIP_RENOIR:
|
||||
if (adev->asic_type == CHIP_RAVEN ||
|
||||
adev->asic_type == CHIP_RENOIR)
|
||||
adev->family = AMDGPU_FAMILY_RV;
|
||||
else
|
||||
adev->family = AMDGPU_FAMILY_AI;
|
||||
@@ -3518,6 +3525,7 @@ bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev)
|
||||
case CHIP_VEGA20:
|
||||
case CHIP_VEGA10:
|
||||
case CHIP_VEGA12:
|
||||
case CHIP_RAVEN:
|
||||
break;
|
||||
default:
|
||||
goto disabled;
|
||||
|
@@ -79,9 +79,10 @@
|
||||
* - 3.31.0 - Add support for per-flip tiling attribute changes with DC
|
||||
* - 3.32.0 - Add syncobj timeline support to AMDGPU_CS.
|
||||
* - 3.33.0 - Fixes for GDS ENOMEM failures in AMDGPU_CS.
|
||||
* - 3.34.0 - Non-DC can flip correctly between buffers with different pitches
|
||||
*/
|
||||
#define KMS_DRIVER_MAJOR 3
|
||||
#define KMS_DRIVER_MINOR 33
|
||||
#define KMS_DRIVER_MINOR 34
|
||||
#define KMS_DRIVER_PATCHLEVEL 0
|
||||
|
||||
#define AMDGPU_MAX_TIMEOUT_PARAM_LENTH 256
|
||||
@@ -142,7 +143,7 @@ int amdgpu_async_gfx_ring = 1;
|
||||
int amdgpu_mcbp = 0;
|
||||
int amdgpu_discovery = -1;
|
||||
int amdgpu_mes = 0;
|
||||
int amdgpu_noretry;
|
||||
int amdgpu_noretry = 1;
|
||||
|
||||
struct amdgpu_mgpu_info mgpu_info = {
|
||||
.mutex = __MUTEX_INITIALIZER(mgpu_info.mutex),
|
||||
@@ -610,7 +611,7 @@ MODULE_PARM_DESC(mes,
|
||||
module_param_named(mes, amdgpu_mes, int, 0444);
|
||||
|
||||
MODULE_PARM_DESC(noretry,
|
||||
"Disable retry faults (0 = retry enabled (default), 1 = retry disabled)");
|
||||
"Disable retry faults (0 = retry enabled, 1 = retry disabled (default))");
|
||||
module_param_named(noretry, amdgpu_noretry, int, 0644);
|
||||
|
||||
#ifdef CONFIG_HSA_AMD
|
||||
@@ -1000,6 +1001,7 @@ static const struct pci_device_id pciidlist[] = {
|
||||
{0x1002, 0x738C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARCTURUS|AMD_EXP_HW_SUPPORT},
|
||||
{0x1002, 0x7388, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARCTURUS|AMD_EXP_HW_SUPPORT},
|
||||
{0x1002, 0x738E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARCTURUS|AMD_EXP_HW_SUPPORT},
|
||||
{0x1002, 0x7390, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARCTURUS|AMD_EXP_HW_SUPPORT},
|
||||
/* Navi10 */
|
||||
{0x1002, 0x7310, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI10},
|
||||
{0x1002, 0x7312, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI10},
|
||||
@@ -1008,6 +1010,11 @@ static const struct pci_device_id pciidlist[] = {
|
||||
{0x1002, 0x731A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI10},
|
||||
{0x1002, 0x731B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI10},
|
||||
{0x1002, 0x731F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI10},
|
||||
/* Navi14 */
|
||||
{0x1002, 0x7340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI14},
|
||||
|
||||
/* Renoir */
|
||||
{0x1002, 0x1636, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RENOIR|AMD_IS_APU|AMD_EXP_HW_SUPPORT},
|
||||
|
||||
{0, 0, 0}
|
||||
};
|
||||
|
@@ -251,7 +251,9 @@ int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
|
||||
}
|
||||
mb();
|
||||
amdgpu_asic_flush_hdp(adev, NULL);
|
||||
amdgpu_gmc_flush_gpu_tlb(adev, 0, 0);
|
||||
for (i = 0; i < adev->num_vmhubs; i++)
|
||||
amdgpu_gmc_flush_gpu_tlb(adev, 0, i, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -310,9 +312,9 @@ int amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset,
|
||||
uint64_t flags)
|
||||
{
|
||||
#ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS
|
||||
unsigned i,t,p;
|
||||
unsigned t,p;
|
||||
#endif
|
||||
int r;
|
||||
int r, i;
|
||||
|
||||
if (!adev->gart.ready) {
|
||||
WARN(1, "trying to bind memory to uninitialized GART !\n");
|
||||
@@ -336,7 +338,8 @@ int amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset,
|
||||
|
||||
mb();
|
||||
amdgpu_asic_flush_hdp(adev, NULL);
|
||||
amdgpu_gmc_flush_gpu_tlb(adev, 0, 0);
|
||||
for (i = 0; i < adev->num_vmhubs; i++)
|
||||
amdgpu_gmc_flush_gpu_tlb(adev, 0, i, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -32,7 +32,6 @@ struct amdgpu_gds {
|
||||
uint32_t gws_size;
|
||||
uint32_t oa_size;
|
||||
uint32_t gds_compute_max_wave_id;
|
||||
uint32_t vgt_gs_max_wave_id;
|
||||
};
|
||||
|
||||
struct amdgpu_gds_reg_offset {
|
||||
|
@@ -220,6 +220,14 @@ void amdgpu_gmc_agp_location(struct amdgpu_device *adev, struct amdgpu_gmc *mc)
|
||||
const uint64_t sixteen_gb_mask = ~(sixteen_gb - 1);
|
||||
u64 size_af, size_bf;
|
||||
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
mc->agp_start = 0xffffffff;
|
||||
mc->agp_end = 0x0;
|
||||
mc->agp_size = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (mc->fb_start > mc->gart_start) {
|
||||
size_bf = (mc->fb_start & sixteen_gb_mask) -
|
||||
ALIGN(mc->gart_end + 1, sixteen_gb);
|
||||
|
@@ -89,8 +89,8 @@ struct amdgpu_vmhub {
|
||||
*/
|
||||
struct amdgpu_gmc_funcs {
|
||||
/* flush the vm tlb via mmio */
|
||||
void (*flush_gpu_tlb)(struct amdgpu_device *adev,
|
||||
uint32_t vmid, uint32_t flush_type);
|
||||
void (*flush_gpu_tlb)(struct amdgpu_device *adev, uint32_t vmid,
|
||||
uint32_t vmhub, uint32_t flush_type);
|
||||
/* flush the vm tlb via ring */
|
||||
uint64_t (*emit_flush_gpu_tlb)(struct amdgpu_ring *ring, unsigned vmid,
|
||||
uint64_t pd_addr);
|
||||
@@ -177,10 +177,11 @@ struct amdgpu_gmc {
|
||||
|
||||
struct amdgpu_xgmi xgmi;
|
||||
struct amdgpu_irq_src ecc_irq;
|
||||
struct ras_common_if *ras_if;
|
||||
struct ras_common_if *umc_ras_if;
|
||||
struct ras_common_if *mmhub_ras_if;
|
||||
};
|
||||
|
||||
#define amdgpu_gmc_flush_gpu_tlb(adev, vmid, type) (adev)->gmc.gmc_funcs->flush_gpu_tlb((adev), (vmid), (type))
|
||||
#define amdgpu_gmc_flush_gpu_tlb(adev, vmid, vmhub, type) ((adev)->gmc.gmc_funcs->flush_gpu_tlb((adev), (vmid), (vmhub), (type)))
|
||||
#define amdgpu_gmc_emit_flush_gpu_tlb(r, vmid, addr) (r)->adev->gmc.gmc_funcs->emit_flush_gpu_tlb((r), (vmid), (addr))
|
||||
#define amdgpu_gmc_emit_pasid_mapping(r, vmid, pasid) (r)->adev->gmc.gmc_funcs->emit_pasid_mapping((r), (vmid), (pasid))
|
||||
#define amdgpu_gmc_get_vm_pde(adev, level, dst, flags) (adev)->gmc.gmc_funcs->get_vm_pde((adev), (level), (dst), (flags))
|
||||
|
31
drivers/gpu/drm/amd/amdgpu/amdgpu_mmhub.h
Normal file
31
drivers/gpu/drm/amd/amdgpu/amdgpu_mmhub.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef __AMDGPU_MMHUB_H__
|
||||
#define __AMDGPU_MMHUB_H__
|
||||
|
||||
struct amdgpu_mmhub_funcs {
|
||||
void (*ras_init)(struct amdgpu_device *adev);
|
||||
void (*query_ras_error_count)(struct amdgpu_device *adev,
|
||||
void *ras_error_status);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -246,8 +246,9 @@ int amdgpu_bo_create_reserved(struct amdgpu_device *adev,
|
||||
bp.size = size;
|
||||
bp.byte_align = align;
|
||||
bp.domain = domain;
|
||||
bp.flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
|
||||
AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS;
|
||||
bp.flags = cpu_addr ? AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED
|
||||
: AMDGPU_GEM_CREATE_NO_CPU_ACCESS;
|
||||
bp.flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS;
|
||||
bp.type = ttm_bo_type_kernel;
|
||||
bp.resv = NULL;
|
||||
|
||||
|
@@ -2828,10 +2828,12 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
|
||||
DRM_ERROR("failed to create device file pp_dpm_socclk\n");
|
||||
return ret;
|
||||
}
|
||||
ret = device_create_file(adev->dev, &dev_attr_pp_dpm_dcefclk);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to create device file pp_dpm_dcefclk\n");
|
||||
return ret;
|
||||
if (adev->asic_type != CHIP_ARCTURUS) {
|
||||
ret = device_create_file(adev->dev, &dev_attr_pp_dpm_dcefclk);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to create device file pp_dpm_dcefclk\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (adev->asic_type >= CHIP_VEGA20) {
|
||||
@@ -2841,10 +2843,12 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
ret = device_create_file(adev->dev, &dev_attr_pp_dpm_pcie);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to create device file pp_dpm_pcie\n");
|
||||
return ret;
|
||||
if (adev->asic_type != CHIP_ARCTURUS) {
|
||||
ret = device_create_file(adev->dev, &dev_attr_pp_dpm_pcie);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to create device file pp_dpm_pcie\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
ret = device_create_file(adev->dev, &dev_attr_pp_sclk_od);
|
||||
if (ret) {
|
||||
@@ -2948,9 +2952,11 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev)
|
||||
device_remove_file(adev->dev, &dev_attr_pp_dpm_mclk);
|
||||
if (adev->asic_type >= CHIP_VEGA10) {
|
||||
device_remove_file(adev->dev, &dev_attr_pp_dpm_socclk);
|
||||
device_remove_file(adev->dev, &dev_attr_pp_dpm_dcefclk);
|
||||
if (adev->asic_type != CHIP_ARCTURUS)
|
||||
device_remove_file(adev->dev, &dev_attr_pp_dpm_dcefclk);
|
||||
}
|
||||
device_remove_file(adev->dev, &dev_attr_pp_dpm_pcie);
|
||||
if (adev->asic_type != CHIP_ARCTURUS)
|
||||
device_remove_file(adev->dev, &dev_attr_pp_dpm_pcie);
|
||||
if (adev->asic_type >= CHIP_VEGA20)
|
||||
device_remove_file(adev->dev, &dev_attr_pp_dpm_fclk);
|
||||
device_remove_file(adev->dev, &dev_attr_pp_sclk_od);
|
||||
|
@@ -32,6 +32,7 @@
|
||||
#include "psp_v3_1.h"
|
||||
#include "psp_v10_0.h"
|
||||
#include "psp_v11_0.h"
|
||||
#include "psp_v12_0.h"
|
||||
|
||||
static void psp_set_funcs(struct amdgpu_device *adev);
|
||||
|
||||
@@ -63,6 +64,9 @@ static int psp_early_init(void *handle)
|
||||
psp_v11_0_set_psp_funcs(psp);
|
||||
psp->autoload_supported = true;
|
||||
break;
|
||||
case CHIP_RENOIR:
|
||||
psp_v12_0_set_psp_funcs(psp);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -140,8 +144,7 @@ psp_cmd_submit_buf(struct psp_context *psp,
|
||||
memcpy(psp->cmd_buf_mem, cmd, sizeof(struct psp_gfx_cmd_resp));
|
||||
|
||||
index = atomic_inc_return(&psp->fence_value);
|
||||
ret = psp_cmd_submit(psp, ucode, psp->cmd_buf_mc_addr,
|
||||
fence_mc_addr, index);
|
||||
ret = psp_cmd_submit(psp, psp->cmd_buf_mc_addr, fence_mc_addr, index);
|
||||
if (ret) {
|
||||
atomic_dec(&psp->fence_value);
|
||||
mutex_unlock(&psp->mutex);
|
||||
@@ -260,7 +263,7 @@ static int psp_tmr_init(struct psp_context *psp)
|
||||
|
||||
ret = amdgpu_bo_create_kernel(psp->adev, tmr_size, PSP_TMR_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
&psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf);
|
||||
&psp->tmr_bo, &psp->tmr_mc_addr, NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -940,6 +943,60 @@ static int psp_get_fw_type(struct amdgpu_firmware_info *ucode,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void psp_print_fw_hdr(struct psp_context *psp,
|
||||
struct amdgpu_firmware_info *ucode)
|
||||
{
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
const struct sdma_firmware_header_v1_0 *sdma_hdr =
|
||||
(const struct sdma_firmware_header_v1_0 *)
|
||||
adev->sdma.instance[ucode->ucode_id - AMDGPU_UCODE_ID_SDMA0].fw->data;
|
||||
const struct gfx_firmware_header_v1_0 *ce_hdr =
|
||||
(const struct gfx_firmware_header_v1_0 *)adev->gfx.ce_fw->data;
|
||||
const struct gfx_firmware_header_v1_0 *pfp_hdr =
|
||||
(const struct gfx_firmware_header_v1_0 *)adev->gfx.pfp_fw->data;
|
||||
const struct gfx_firmware_header_v1_0 *me_hdr =
|
||||
(const struct gfx_firmware_header_v1_0 *)adev->gfx.me_fw->data;
|
||||
const struct gfx_firmware_header_v1_0 *mec_hdr =
|
||||
(const struct gfx_firmware_header_v1_0 *)adev->gfx.mec_fw->data;
|
||||
const struct rlc_firmware_header_v2_0 *rlc_hdr =
|
||||
(const struct rlc_firmware_header_v2_0 *)adev->gfx.rlc_fw->data;
|
||||
const struct smc_firmware_header_v1_0 *smc_hdr =
|
||||
(const struct smc_firmware_header_v1_0 *)adev->pm.fw->data;
|
||||
|
||||
switch (ucode->ucode_id) {
|
||||
case AMDGPU_UCODE_ID_SDMA0:
|
||||
case AMDGPU_UCODE_ID_SDMA1:
|
||||
case AMDGPU_UCODE_ID_SDMA2:
|
||||
case AMDGPU_UCODE_ID_SDMA3:
|
||||
case AMDGPU_UCODE_ID_SDMA4:
|
||||
case AMDGPU_UCODE_ID_SDMA5:
|
||||
case AMDGPU_UCODE_ID_SDMA6:
|
||||
case AMDGPU_UCODE_ID_SDMA7:
|
||||
amdgpu_ucode_print_sdma_hdr(&sdma_hdr->header);
|
||||
break;
|
||||
case AMDGPU_UCODE_ID_CP_CE:
|
||||
amdgpu_ucode_print_gfx_hdr(&ce_hdr->header);
|
||||
break;
|
||||
case AMDGPU_UCODE_ID_CP_PFP:
|
||||
amdgpu_ucode_print_gfx_hdr(&pfp_hdr->header);
|
||||
break;
|
||||
case AMDGPU_UCODE_ID_CP_ME:
|
||||
amdgpu_ucode_print_gfx_hdr(&me_hdr->header);
|
||||
break;
|
||||
case AMDGPU_UCODE_ID_CP_MEC1:
|
||||
amdgpu_ucode_print_gfx_hdr(&mec_hdr->header);
|
||||
break;
|
||||
case AMDGPU_UCODE_ID_RLC_G:
|
||||
amdgpu_ucode_print_rlc_hdr(&rlc_hdr->header);
|
||||
break;
|
||||
case AMDGPU_UCODE_ID_SMC:
|
||||
amdgpu_ucode_print_smc_hdr(&smc_hdr->header);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int psp_prep_load_ip_fw_cmd_buf(struct amdgpu_firmware_info *ucode,
|
||||
struct psp_gfx_cmd_resp *cmd)
|
||||
{
|
||||
@@ -1019,14 +1076,19 @@ out:
|
||||
ucode->ucode_id == AMDGPU_UCODE_ID_CP_MEC2_JT))
|
||||
/* skip mec JT when autoload is enabled */
|
||||
continue;
|
||||
/* Renoir only needs to load mec jump table one time */
|
||||
if (adev->asic_type == CHIP_RENOIR &&
|
||||
ucode->ucode_id == AMDGPU_UCODE_ID_CP_MEC2_JT)
|
||||
continue;
|
||||
|
||||
psp_print_fw_hdr(psp, ucode);
|
||||
|
||||
ret = psp_execute_np_fw_load(psp, ucode);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Start rlc autoload after psp recieved all the gfx firmware */
|
||||
if (ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM ||
|
||||
(adev->asic_type == CHIP_NAVI12 && ucode->ucode_id == AMDGPU_UCODE_ID_RLC_G)) {
|
||||
if (ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM) {
|
||||
ret = psp_rlc_autoload(psp);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to start rlc autoload\n");
|
||||
@@ -1154,7 +1216,7 @@ static int psp_hw_fini(void *handle)
|
||||
|
||||
psp_ring_destroy(psp, PSP_RING_TYPE__KM);
|
||||
|
||||
amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf);
|
||||
amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, NULL);
|
||||
amdgpu_bo_free_kernel(&psp->fw_pri_bo,
|
||||
&psp->fw_pri_mc_addr, &psp->fw_pri_buf);
|
||||
amdgpu_bo_free_kernel(&psp->fence_buf_bo,
|
||||
@@ -1358,3 +1420,12 @@ const struct amdgpu_ip_block_version psp_v11_0_ip_block =
|
||||
.rev = 0,
|
||||
.funcs = &psp_ip_funcs,
|
||||
};
|
||||
|
||||
const struct amdgpu_ip_block_version psp_v12_0_ip_block =
|
||||
{
|
||||
.type = AMD_IP_BLOCK_TYPE_PSP,
|
||||
.major = 12,
|
||||
.minor = 0,
|
||||
.rev = 0,
|
||||
.funcs = &psp_ip_funcs,
|
||||
};
|
||||
|
@@ -90,7 +90,6 @@ struct psp_funcs
|
||||
int (*ring_destroy)(struct psp_context *psp,
|
||||
enum psp_ring_type ring_type);
|
||||
int (*cmd_submit)(struct psp_context *psp,
|
||||
struct amdgpu_firmware_info *ucode,
|
||||
uint64_t cmd_buf_mc_addr, uint64_t fence_mc_addr,
|
||||
int index);
|
||||
bool (*compare_sram_data)(struct psp_context *psp,
|
||||
@@ -172,7 +171,6 @@ struct psp_context
|
||||
/* tmr buffer */
|
||||
struct amdgpu_bo *tmr_bo;
|
||||
uint64_t tmr_mc_addr;
|
||||
void *tmr_buf;
|
||||
|
||||
/* asd firmware and buffer */
|
||||
const struct firmware *asd_fw;
|
||||
@@ -223,8 +221,8 @@ struct amdgpu_psp_funcs {
|
||||
#define psp_ring_create(psp, type) (psp)->funcs->ring_create((psp), (type))
|
||||
#define psp_ring_stop(psp, type) (psp)->funcs->ring_stop((psp), (type))
|
||||
#define psp_ring_destroy(psp, type) ((psp)->funcs->ring_destroy((psp), (type)))
|
||||
#define psp_cmd_submit(psp, ucode, cmd_mc, fence_mc, index) \
|
||||
(psp)->funcs->cmd_submit((psp), (ucode), (cmd_mc), (fence_mc), (index))
|
||||
#define psp_cmd_submit(psp, cmd_mc, fence_mc, index) \
|
||||
(psp)->funcs->cmd_submit((psp), (cmd_mc), (fence_mc), (index))
|
||||
#define psp_compare_sram_data(psp, ucode, type) \
|
||||
(psp)->funcs->compare_sram_data((psp), (ucode), (type))
|
||||
#define psp_init_microcode(psp) \
|
||||
@@ -270,6 +268,7 @@ extern int psp_wait_for(struct psp_context *psp, uint32_t reg_index,
|
||||
uint32_t field_val, uint32_t mask, bool check_changed);
|
||||
|
||||
extern const struct amdgpu_ip_block_version psp_v10_0_ip_block;
|
||||
extern const struct amdgpu_ip_block_version psp_v12_0_ip_block;
|
||||
|
||||
int psp_gpu_reset(struct amdgpu_device *adev);
|
||||
int psp_update_vcn_sram(struct amdgpu_device *adev, int inst_idx,
|
||||
|
@@ -131,6 +131,7 @@ static int amdgpu_ras_debugfs_ctrl_parse_data(struct file *f,
|
||||
char err[9] = "ue";
|
||||
int op = -1;
|
||||
int block_id;
|
||||
uint32_t sub_block;
|
||||
u64 address, value;
|
||||
|
||||
if (*pos)
|
||||
@@ -169,11 +170,12 @@ static int amdgpu_ras_debugfs_ctrl_parse_data(struct file *f,
|
||||
data->op = op;
|
||||
|
||||
if (op == 2) {
|
||||
if (sscanf(str, "%*s %*s %*s %llu %llu",
|
||||
&address, &value) != 2)
|
||||
if (sscanf(str, "%*s %*s %*s 0x%llx 0x%llx",
|
||||
&address, &value) != 2)
|
||||
if (sscanf(str, "%*s %*s %*s %u %llu %llu",
|
||||
&sub_block, &address, &value) != 3)
|
||||
if (sscanf(str, "%*s %*s %*s 0x%x 0x%llx 0x%llx",
|
||||
&sub_block, &address, &value) != 3)
|
||||
return -EINVAL;
|
||||
data->head.sub_block_index = sub_block;
|
||||
data->inject.address = address;
|
||||
data->inject.value = value;
|
||||
}
|
||||
@@ -218,7 +220,7 @@ static int amdgpu_ras_debugfs_ctrl_parse_data(struct file *f,
|
||||
* write the struct to the control node.
|
||||
*
|
||||
* bash:
|
||||
* echo op block [error [address value]] > .../ras/ras_ctrl
|
||||
* echo op block [error [sub_blcok address value]] > .../ras/ras_ctrl
|
||||
* op: disable, enable, inject
|
||||
* disable: only block is needed
|
||||
* enable: block and error are needed
|
||||
@@ -228,10 +230,11 @@ static int amdgpu_ras_debugfs_ctrl_parse_data(struct file *f,
|
||||
* error: ue, ce
|
||||
* ue: multi_uncorrectable
|
||||
* ce: single_correctable
|
||||
* sub_block: sub block index, pass 0 if there is no sub block
|
||||
*
|
||||
* here are some examples for bash commands,
|
||||
* echo inject umc ue 0x0 0x0 > /sys/kernel/debug/dri/0/ras/ras_ctrl
|
||||
* echo inject umc ce 0 0 > /sys/kernel/debug/dri/0/ras/ras_ctrl
|
||||
* echo inject umc ue 0x0 0x0 0x0 > /sys/kernel/debug/dri/0/ras/ras_ctrl
|
||||
* echo inject umc ce 0 0 0 > /sys/kernel/debug/dri/0/ras/ras_ctrl
|
||||
* echo disable umc > /sys/kernel/debug/dri/0/ras/ras_ctrl
|
||||
*
|
||||
* How to check the result?
|
||||
@@ -611,6 +614,10 @@ int amdgpu_ras_error_query(struct amdgpu_device *adev,
|
||||
if (adev->gfx.funcs->query_ras_error_count)
|
||||
adev->gfx.funcs->query_ras_error_count(adev, &err_data);
|
||||
break;
|
||||
case AMDGPU_RAS_BLOCK__MMHUB:
|
||||
if (adev->mmhub_funcs->query_ras_error_count)
|
||||
adev->mmhub_funcs->query_ras_error_count(adev, &err_data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -656,6 +663,7 @@ int amdgpu_ras_error_inject(struct amdgpu_device *adev,
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
case AMDGPU_RAS_BLOCK__UMC:
|
||||
case AMDGPU_RAS_BLOCK__MMHUB:
|
||||
ret = psp_ras_trigger_error(&adev->psp, &block_info);
|
||||
break;
|
||||
default:
|
||||
@@ -680,7 +688,7 @@ int amdgpu_ras_error_cure(struct amdgpu_device *adev,
|
||||
}
|
||||
|
||||
/* get the total error counts on all IPs */
|
||||
int amdgpu_ras_query_error_count(struct amdgpu_device *adev,
|
||||
unsigned long amdgpu_ras_query_error_count(struct amdgpu_device *adev,
|
||||
bool is_ce)
|
||||
{
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
@@ -688,7 +696,7 @@ int amdgpu_ras_query_error_count(struct amdgpu_device *adev,
|
||||
struct ras_err_data data = {0, 0};
|
||||
|
||||
if (!con)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
|
||||
list_for_each_entry(obj, &con->head, node) {
|
||||
struct ras_query_if info = {
|
||||
@@ -696,7 +704,7 @@ int amdgpu_ras_query_error_count(struct amdgpu_device *adev,
|
||||
};
|
||||
|
||||
if (amdgpu_ras_error_query(adev, &info))
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
|
||||
data.ce_count += info.ce_count;
|
||||
data.ue_count += info.ue_count;
|
||||
@@ -785,25 +793,8 @@ static ssize_t amdgpu_ras_sysfs_features_read(struct device *dev,
|
||||
{
|
||||
struct amdgpu_ras *con =
|
||||
container_of(attr, struct amdgpu_ras, features_attr);
|
||||
struct drm_device *ddev = dev_get_drvdata(dev);
|
||||
struct amdgpu_device *adev = ddev->dev_private;
|
||||
struct ras_common_if head;
|
||||
int ras_block_count = AMDGPU_RAS_BLOCK_COUNT;
|
||||
int i, enabled;
|
||||
ssize_t s;
|
||||
|
||||
s = scnprintf(buf, PAGE_SIZE, "feature mask: 0x%x\n", con->features);
|
||||
|
||||
for (i = 0; i < ras_block_count; i++) {
|
||||
head.block = i;
|
||||
enabled = amdgpu_ras_is_feature_enabled(adev, &head);
|
||||
|
||||
s += scnprintf(&buf[s], PAGE_SIZE - s,
|
||||
"%s ras feature mask: %s\n",
|
||||
ras_block_str(i), enabled?"on":"off");
|
||||
}
|
||||
|
||||
return s;
|
||||
return scnprintf(buf, PAGE_SIZE, "feature mask: 0x%x\n", con->features);
|
||||
}
|
||||
|
||||
static int amdgpu_ras_sysfs_create_feature_node(struct amdgpu_device *adev)
|
||||
|
@@ -484,7 +484,7 @@ int amdgpu_ras_request_reset_on_boot(struct amdgpu_device *adev,
|
||||
void amdgpu_ras_resume(struct amdgpu_device *adev);
|
||||
void amdgpu_ras_suspend(struct amdgpu_device *adev);
|
||||
|
||||
int amdgpu_ras_query_error_count(struct amdgpu_device *adev,
|
||||
unsigned long amdgpu_ras_query_error_count(struct amdgpu_device *adev,
|
||||
bool is_ce);
|
||||
|
||||
/* error handling functions */
|
||||
|
@@ -1745,7 +1745,7 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
|
||||
r = ttm_bo_device_init(&adev->mman.bdev,
|
||||
&amdgpu_bo_driver,
|
||||
adev->ddev->anon_inode->i_mapping,
|
||||
adev->need_dma32);
|
||||
dma_addressing_limited(adev->dev));
|
||||
if (r) {
|
||||
DRM_ERROR("failed initializing buffer object driver(%d).\n", r);
|
||||
return r;
|
||||
|
@@ -83,8 +83,8 @@ void amdgpu_ucode_print_smc_hdr(const struct common_firmware_header *hdr)
|
||||
const struct smc_firmware_header_v2_0 *v2_hdr =
|
||||
container_of(v1_hdr, struct smc_firmware_header_v2_0, v1_0);
|
||||
|
||||
DRM_INFO("ppt_offset_bytes: %u\n", le32_to_cpu(v2_hdr->ppt_offset_bytes));
|
||||
DRM_INFO("ppt_size_bytes: %u\n", le32_to_cpu(v2_hdr->ppt_size_bytes));
|
||||
DRM_DEBUG("ppt_offset_bytes: %u\n", le32_to_cpu(v2_hdr->ppt_offset_bytes));
|
||||
DRM_DEBUG("ppt_size_bytes: %u\n", le32_to_cpu(v2_hdr->ppt_size_bytes));
|
||||
} else {
|
||||
DRM_ERROR("Unknown SMC ucode version: %u.%u\n", version_major, version_minor);
|
||||
}
|
||||
@@ -360,6 +360,7 @@ amdgpu_ucode_get_load_type(struct amdgpu_device *adev, int load_type)
|
||||
case CHIP_RAVEN:
|
||||
case CHIP_VEGA12:
|
||||
case CHIP_VEGA20:
|
||||
case CHIP_RENOIR:
|
||||
case CHIP_NAVI10:
|
||||
case CHIP_NAVI14:
|
||||
case CHIP_NAVI12:
|
||||
@@ -369,6 +370,7 @@ amdgpu_ucode_get_load_type(struct amdgpu_device *adev, int load_type)
|
||||
return AMDGPU_FW_LOAD_PSP;
|
||||
case CHIP_ARCTURUS:
|
||||
return AMDGPU_FW_LOAD_DIRECT;
|
||||
|
||||
default:
|
||||
DRM_ERROR("Unknown firmware load type\n");
|
||||
}
|
||||
|
@@ -47,6 +47,7 @@
|
||||
#define FIRMWARE_PICASSO "amdgpu/picasso_vcn.bin"
|
||||
#define FIRMWARE_RAVEN2 "amdgpu/raven2_vcn.bin"
|
||||
#define FIRMWARE_ARCTURUS "amdgpu/arcturus_vcn.bin"
|
||||
#define FIRMWARE_RENOIR "amdgpu/renoir_vcn.bin"
|
||||
#define FIRMWARE_NAVI10 "amdgpu/navi10_vcn.bin"
|
||||
#define FIRMWARE_NAVI14 "amdgpu/navi14_vcn.bin"
|
||||
#define FIRMWARE_NAVI12 "amdgpu/navi12_vcn.bin"
|
||||
@@ -55,6 +56,7 @@ MODULE_FIRMWARE(FIRMWARE_RAVEN);
|
||||
MODULE_FIRMWARE(FIRMWARE_PICASSO);
|
||||
MODULE_FIRMWARE(FIRMWARE_RAVEN2);
|
||||
MODULE_FIRMWARE(FIRMWARE_ARCTURUS);
|
||||
MODULE_FIRMWARE(FIRMWARE_RENOIR);
|
||||
MODULE_FIRMWARE(FIRMWARE_NAVI10);
|
||||
MODULE_FIRMWARE(FIRMWARE_NAVI14);
|
||||
MODULE_FIRMWARE(FIRMWARE_NAVI12);
|
||||
@@ -83,6 +85,12 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
|
||||
case CHIP_ARCTURUS:
|
||||
fw_name = FIRMWARE_ARCTURUS;
|
||||
break;
|
||||
case CHIP_RENOIR:
|
||||
fw_name = FIRMWARE_RENOIR;
|
||||
if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
|
||||
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
|
||||
adev->vcn.indirect_sram = true;
|
||||
break;
|
||||
case CHIP_NAVI10:
|
||||
fw_name = FIRMWARE_NAVI10;
|
||||
if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
|
||||
|
@@ -2863,6 +2863,13 @@ int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm, uns
|
||||
WARN_ONCE((vm->use_cpu_for_update && !amdgpu_gmc_vram_full_visible(&adev->gmc)),
|
||||
"CPU update of VM recommended only for large BAR system\n");
|
||||
|
||||
if (vm->use_cpu_for_update)
|
||||
vm->update_funcs = &amdgpu_vm_cpu_funcs;
|
||||
else
|
||||
vm->update_funcs = &amdgpu_vm_sdma_funcs;
|
||||
dma_fence_put(vm->last_update);
|
||||
vm->last_update = NULL;
|
||||
|
||||
if (vm->pasid) {
|
||||
unsigned long flags;
|
||||
|
||||
|
103
drivers/gpu/drm/amd/amdgpu/athub_v1_0.c
Normal file
103
drivers/gpu/drm/amd/amdgpu/athub_v1_0.c
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* 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"
|
||||
#include "athub_v1_0.h"
|
||||
|
||||
#include "athub/athub_1_0_offset.h"
|
||||
#include "athub/athub_1_0_sh_mask.h"
|
||||
#include "vega10_enum.h"
|
||||
|
||||
#include "soc15_common.h"
|
||||
|
||||
static void athub_update_medium_grain_clock_gating(struct amdgpu_device *adev,
|
||||
bool enable)
|
||||
{
|
||||
uint32_t def, data;
|
||||
|
||||
def = data = RREG32_SOC15(ATHUB, 0, mmATHUB_MISC_CNTL);
|
||||
|
||||
if (enable && (adev->cg_flags & AMD_CG_SUPPORT_MC_MGCG))
|
||||
data |= ATHUB_MISC_CNTL__CG_ENABLE_MASK;
|
||||
else
|
||||
data &= ~ATHUB_MISC_CNTL__CG_ENABLE_MASK;
|
||||
|
||||
if (def != data)
|
||||
WREG32_SOC15(ATHUB, 0, mmATHUB_MISC_CNTL, data);
|
||||
}
|
||||
|
||||
static void athub_update_medium_grain_light_sleep(struct amdgpu_device *adev,
|
||||
bool enable)
|
||||
{
|
||||
uint32_t def, data;
|
||||
|
||||
def = data = RREG32_SOC15(ATHUB, 0, mmATHUB_MISC_CNTL);
|
||||
|
||||
if (enable && (adev->cg_flags & AMD_CG_SUPPORT_MC_LS) &&
|
||||
(adev->cg_flags & AMD_CG_SUPPORT_HDP_LS))
|
||||
data |= ATHUB_MISC_CNTL__CG_MEM_LS_ENABLE_MASK;
|
||||
else
|
||||
data &= ~ATHUB_MISC_CNTL__CG_MEM_LS_ENABLE_MASK;
|
||||
|
||||
if(def != data)
|
||||
WREG32_SOC15(ATHUB, 0, mmATHUB_MISC_CNTL, data);
|
||||
}
|
||||
|
||||
int athub_v1_0_set_clockgating(struct amdgpu_device *adev,
|
||||
enum amd_clockgating_state state)
|
||||
{
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return 0;
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VEGA10:
|
||||
case CHIP_VEGA12:
|
||||
case CHIP_VEGA20:
|
||||
case CHIP_RAVEN:
|
||||
athub_update_medium_grain_clock_gating(adev,
|
||||
state == AMD_CG_STATE_GATE ? true : false);
|
||||
athub_update_medium_grain_light_sleep(adev,
|
||||
state == AMD_CG_STATE_GATE ? true : false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void athub_v1_0_get_clockgating(struct amdgpu_device *adev, u32 *flags)
|
||||
{
|
||||
int data;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
*flags = 0;
|
||||
|
||||
/* AMD_CG_SUPPORT_ATHUB_MGCG */
|
||||
data = RREG32_SOC15(ATHUB, 0, mmATHUB_MISC_CNTL);
|
||||
if (data & ATHUB_MISC_CNTL__CG_ENABLE_MASK)
|
||||
*flags |= AMD_CG_SUPPORT_ATHUB_MGCG;
|
||||
|
||||
/* AMD_CG_SUPPORT_ATHUB_LS */
|
||||
if (data & ATHUB_MISC_CNTL__CG_MEM_LS_ENABLE_MASK)
|
||||
*flags |= AMD_CG_SUPPORT_ATHUB_LS;
|
||||
}
|
30
drivers/gpu/drm/amd/amdgpu/athub_v1_0.h
Normal file
30
drivers/gpu/drm/amd/amdgpu/athub_v1_0.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#ifndef __ATHUB_V1_0_H__
|
||||
#define __ATHUB_V1_0_H__
|
||||
|
||||
int athub_v1_0_set_clockgating(struct amdgpu_device *adev,
|
||||
enum amd_clockgating_state state);
|
||||
void athub_v1_0_get_clockgating(struct amdgpu_device *adev, u32 *flags);
|
||||
|
||||
#endif
|
@@ -75,6 +75,7 @@ int athub_v2_0_set_clockgating(struct amdgpu_device *adev,
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_NAVI10:
|
||||
case CHIP_NAVI14:
|
||||
case CHIP_NAVI12:
|
||||
athub_v2_0_update_medium_grain_clock_gating(adev,
|
||||
state == AMD_CG_STATE_GATE ? true : false);
|
||||
athub_v2_0_update_medium_grain_light_sleep(adev,
|
||||
|
@@ -236,6 +236,7 @@ static void dce_v10_0_page_flip(struct amdgpu_device *adev,
|
||||
int crtc_id, u64 crtc_base, bool async)
|
||||
{
|
||||
struct amdgpu_crtc *amdgpu_crtc = adev->mode_info.crtcs[crtc_id];
|
||||
struct drm_framebuffer *fb = amdgpu_crtc->base.primary->fb;
|
||||
u32 tmp;
|
||||
|
||||
/* flip at hsync for async, default is vsync */
|
||||
@@ -243,6 +244,9 @@ static void dce_v10_0_page_flip(struct amdgpu_device *adev,
|
||||
tmp = REG_SET_FIELD(tmp, GRPH_FLIP_CONTROL,
|
||||
GRPH_SURFACE_UPDATE_H_RETRACE_EN, async ? 1 : 0);
|
||||
WREG32(mmGRPH_FLIP_CONTROL + amdgpu_crtc->crtc_offset, tmp);
|
||||
/* update pitch */
|
||||
WREG32(mmGRPH_PITCH + amdgpu_crtc->crtc_offset,
|
||||
fb->pitches[0] / fb->format->cpp[0]);
|
||||
/* update the primary scanout address */
|
||||
WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS_HIGH + amdgpu_crtc->crtc_offset,
|
||||
upper_32_bits(crtc_base));
|
||||
|
@@ -254,6 +254,7 @@ static void dce_v11_0_page_flip(struct amdgpu_device *adev,
|
||||
int crtc_id, u64 crtc_base, bool async)
|
||||
{
|
||||
struct amdgpu_crtc *amdgpu_crtc = adev->mode_info.crtcs[crtc_id];
|
||||
struct drm_framebuffer *fb = amdgpu_crtc->base.primary->fb;
|
||||
u32 tmp;
|
||||
|
||||
/* flip immediate for async, default is vsync */
|
||||
@@ -261,6 +262,9 @@ static void dce_v11_0_page_flip(struct amdgpu_device *adev,
|
||||
tmp = REG_SET_FIELD(tmp, GRPH_FLIP_CONTROL,
|
||||
GRPH_SURFACE_UPDATE_IMMEDIATE_EN, async ? 1 : 0);
|
||||
WREG32(mmGRPH_FLIP_CONTROL + amdgpu_crtc->crtc_offset, tmp);
|
||||
/* update pitch */
|
||||
WREG32(mmGRPH_PITCH + amdgpu_crtc->crtc_offset,
|
||||
fb->pitches[0] / fb->format->cpp[0]);
|
||||
/* update the scanout addresses */
|
||||
WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS_HIGH + amdgpu_crtc->crtc_offset,
|
||||
upper_32_bits(crtc_base));
|
||||
|
@@ -191,10 +191,14 @@ static void dce_v6_0_page_flip(struct amdgpu_device *adev,
|
||||
int crtc_id, u64 crtc_base, bool async)
|
||||
{
|
||||
struct amdgpu_crtc *amdgpu_crtc = adev->mode_info.crtcs[crtc_id];
|
||||
struct drm_framebuffer *fb = amdgpu_crtc->base.primary->fb;
|
||||
|
||||
/* flip at hsync for async, default is vsync */
|
||||
WREG32(mmGRPH_FLIP_CONTROL + amdgpu_crtc->crtc_offset, async ?
|
||||
GRPH_FLIP_CONTROL__GRPH_SURFACE_UPDATE_H_RETRACE_EN_MASK : 0);
|
||||
/* update pitch */
|
||||
WREG32(mmGRPH_PITCH + amdgpu_crtc->crtc_offset,
|
||||
fb->pitches[0] / fb->format->cpp[0]);
|
||||
/* update the scanout addresses */
|
||||
WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS_HIGH + amdgpu_crtc->crtc_offset,
|
||||
upper_32_bits(crtc_base));
|
||||
|
@@ -184,10 +184,14 @@ static void dce_v8_0_page_flip(struct amdgpu_device *adev,
|
||||
int crtc_id, u64 crtc_base, bool async)
|
||||
{
|
||||
struct amdgpu_crtc *amdgpu_crtc = adev->mode_info.crtcs[crtc_id];
|
||||
struct drm_framebuffer *fb = amdgpu_crtc->base.primary->fb;
|
||||
|
||||
/* flip at hsync for async, default is vsync */
|
||||
WREG32(mmGRPH_FLIP_CONTROL + amdgpu_crtc->crtc_offset, async ?
|
||||
GRPH_FLIP_CONTROL__GRPH_SURFACE_UPDATE_H_RETRACE_EN_MASK : 0);
|
||||
/* update pitch */
|
||||
WREG32(mmGRPH_PITCH + amdgpu_crtc->crtc_offset,
|
||||
fb->pitches[0] / fb->format->cpp[0]);
|
||||
/* update the primary scanout addresses */
|
||||
WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS_HIGH + amdgpu_crtc->crtc_offset,
|
||||
upper_32_bits(crtc_base));
|
||||
|
@@ -458,6 +458,7 @@ static int dce_virtual_hw_init(void *handle)
|
||||
case CHIP_VEGA12:
|
||||
case CHIP_VEGA20:
|
||||
case CHIP_ARCTURUS:
|
||||
case CHIP_RENOIR:
|
||||
case CHIP_NAVI10:
|
||||
case CHIP_NAVI14:
|
||||
case CHIP_NAVI12:
|
||||
|
@@ -1748,9 +1748,12 @@ static void gfx_v10_0_init_csb(struct amdgpu_device *adev)
|
||||
|
||||
static void gfx_v10_0_init_pg(struct amdgpu_device *adev)
|
||||
{
|
||||
int i;
|
||||
|
||||
gfx_v10_0_init_csb(adev);
|
||||
|
||||
amdgpu_gmc_flush_gpu_tlb(adev, 0, 0);
|
||||
for (i = 0; i < adev->num_vmhubs; i++)
|
||||
amdgpu_gmc_flush_gpu_tlb(adev, 0, i, 0);
|
||||
|
||||
/* TODO: init power gating */
|
||||
return;
|
||||
@@ -4373,15 +4376,6 @@ static void gfx_v10_0_ring_emit_ib_gfx(struct amdgpu_ring *ring,
|
||||
unsigned vmid = AMDGPU_JOB_GET_VMID(job);
|
||||
u32 header, control = 0;
|
||||
|
||||
/* Prevent a hw deadlock due to a wave ID mismatch between ME and GDS.
|
||||
* This resets the wave ID counters. (needed by transform feedback)
|
||||
* TODO: This might only be needed on a VMID switch when we change
|
||||
* the GDS OA mapping, not sure.
|
||||
*/
|
||||
amdgpu_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
|
||||
amdgpu_ring_write(ring, mmVGT_GS_MAX_WAVE_ID);
|
||||
amdgpu_ring_write(ring, ring->adev->gds.vgt_gs_max_wave_id);
|
||||
|
||||
if (ib->flags & AMDGPU_IB_FLAG_CE)
|
||||
header = PACKET3(PACKET3_INDIRECT_BUFFER_CNST, 2);
|
||||
else
|
||||
@@ -5128,7 +5122,7 @@ static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_gfx = {
|
||||
5 + /* HDP_INVL */
|
||||
8 + 8 + /* FENCE x2 */
|
||||
2, /* SWITCH_BUFFER */
|
||||
.emit_ib_size = 7, /* gfx_v10_0_ring_emit_ib_gfx */
|
||||
.emit_ib_size = 4, /* gfx_v10_0_ring_emit_ib_gfx */
|
||||
.emit_ib = gfx_v10_0_ring_emit_ib_gfx,
|
||||
.emit_fence = gfx_v10_0_ring_emit_fence,
|
||||
.emit_pipeline_sync = gfx_v10_0_ring_emit_pipeline_sync,
|
||||
@@ -5281,7 +5275,6 @@ static void gfx_v10_0_set_gds_init(struct amdgpu_device *adev)
|
||||
default:
|
||||
adev->gds.gds_size = 0x10000;
|
||||
adev->gds.gds_compute_max_wave_id = 0x4ff;
|
||||
adev->gds.vgt_gs_max_wave_id = 0x3ff;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@@ -36,10 +36,10 @@
|
||||
|
||||
#include "gc/gc_9_0_offset.h"
|
||||
#include "gc/gc_9_0_sh_mask.h"
|
||||
|
||||
#include "vega10_enum.h"
|
||||
#include "hdp/hdp_4_0_offset.h"
|
||||
|
||||
#include "soc15.h"
|
||||
#include "soc15_common.h"
|
||||
#include "clearstate_gfx9.h"
|
||||
#include "v9_structs.h"
|
||||
@@ -60,6 +60,9 @@
|
||||
#define PWR_MISC_CNTL_STATUS__PWR_GFX_RLC_CGPG_EN_MASK 0x00000001L
|
||||
#define PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS_MASK 0x00000006L
|
||||
|
||||
#define mmGCEA_PROBE_MAP 0x070c
|
||||
#define mmGCEA_PROBE_MAP_BASE_IDX 0
|
||||
|
||||
MODULE_FIRMWARE("amdgpu/vega10_ce.bin");
|
||||
MODULE_FIRMWARE("amdgpu/vega10_pfp.bin");
|
||||
MODULE_FIRMWARE("amdgpu/vega10_me.bin");
|
||||
@@ -108,6 +111,13 @@ MODULE_FIRMWARE("amdgpu/arcturus_mec.bin");
|
||||
MODULE_FIRMWARE("amdgpu/arcturus_mec2.bin");
|
||||
MODULE_FIRMWARE("amdgpu/arcturus_rlc.bin");
|
||||
|
||||
MODULE_FIRMWARE("amdgpu/renoir_ce.bin");
|
||||
MODULE_FIRMWARE("amdgpu/renoir_pfp.bin");
|
||||
MODULE_FIRMWARE("amdgpu/renoir_me.bin");
|
||||
MODULE_FIRMWARE("amdgpu/renoir_mec.bin");
|
||||
MODULE_FIRMWARE("amdgpu/renoir_mec2.bin");
|
||||
MODULE_FIRMWARE("amdgpu/renoir_rlc.bin");
|
||||
|
||||
#define mmTCP_CHAN_STEER_0_ARCT 0x0b03
|
||||
#define mmTCP_CHAN_STEER_0_ARCT_BASE_IDX 0
|
||||
#define mmTCP_CHAN_STEER_1_ARCT 0x0b04
|
||||
@@ -611,6 +621,22 @@ static const struct soc15_reg_golden golden_settings_gc_9_1_rv2[] =
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmWD_UTCL1_CNTL, 0x3f8fffff, 0x08000080),
|
||||
};
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_gc_9_1_rn[] =
|
||||
{
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL, 0xfffdf3cf, 0x00014104),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL_2, 0xff7fffff, 0x0a000000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG2, 0xf00fffff, 0x00000400),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGB_ADDR_CONFIG, 0xf3e777ff, 0x24000042),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGB_ADDR_CONFIG_READ, 0xf3e777ff, 0x24000042),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE, 0x3fffffff, 0x00000001),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE_1, 0xffffffff, 0x04040000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_LINE_STIPPLE_STATE, 0x0000ff0f, 0x00000000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0xfffffeef, 0x010b0000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_HI, 0xffffffff, 0x00000000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_LO, 0xffffffff, 0x00003120),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGCEA_PROBE_MAP, 0xffffffff, 0x0000cccc),
|
||||
};
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_gc_9_x_common[] =
|
||||
{
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_SD_CNTL, 0xffffffff, 0x000001ff),
|
||||
@@ -755,6 +781,11 @@ static void gfx_v9_0_init_golden_registers(struct amdgpu_device *adev)
|
||||
golden_settings_gc_9_1_rv1,
|
||||
ARRAY_SIZE(golden_settings_gc_9_1_rv1));
|
||||
break;
|
||||
case CHIP_RENOIR:
|
||||
soc15_program_register_sequence(adev,
|
||||
golden_settings_gc_9_1_rn,
|
||||
ARRAY_SIZE(golden_settings_gc_9_1_rn));
|
||||
return; /* for renoir, don't need common goldensetting */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1008,6 +1039,10 @@ static void gfx_v9_0_check_if_need_gfxoff(struct amdgpu_device *adev)
|
||||
(adev->gfx.rlc_feature_version < 1) ||
|
||||
!adev->gfx.rlc.is_rlc_v2_1)
|
||||
adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
|
||||
if (adev->pm.pp_feature & PP_GFXOFF_MASK)
|
||||
adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG |
|
||||
AMD_PG_SUPPORT_CP |
|
||||
AMD_PG_SUPPORT_RLC_SMU_HS;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -1343,6 +1378,9 @@ static int gfx_v9_0_init_microcode(struct amdgpu_device *adev)
|
||||
case CHIP_ARCTURUS:
|
||||
chip_name = "arcturus";
|
||||
break;
|
||||
case CHIP_RENOIR:
|
||||
chip_name = "renoir";
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
@@ -1602,7 +1640,7 @@ static int gfx_v9_0_rlc_init(struct amdgpu_device *adev)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (adev->asic_type == CHIP_RAVEN) {
|
||||
if (adev->asic_type == CHIP_RAVEN || adev->asic_type == CHIP_RENOIR) {
|
||||
/* TODO: double check the cp_table_size for RV */
|
||||
adev->gfx.rlc.cp_table_size = ALIGN(96 * 5 * 4, 2048) + (64 * 1024); /* JT + GDS */
|
||||
r = amdgpu_gfx_rlc_init_cpt(adev);
|
||||
@@ -1612,6 +1650,7 @@ static int gfx_v9_0_rlc_init(struct amdgpu_device *adev)
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_RAVEN:
|
||||
case CHIP_RENOIR:
|
||||
gfx_v9_0_init_lbpw(adev);
|
||||
break;
|
||||
case CHIP_VEGA20:
|
||||
@@ -1863,6 +1902,16 @@ static int gfx_v9_0_gpu_early_init(struct amdgpu_device *adev)
|
||||
gb_addr_config &= ~0xf3e777ff;
|
||||
gb_addr_config |= 0x22014042;
|
||||
break;
|
||||
case CHIP_RENOIR:
|
||||
adev->gfx.config.max_hw_contexts = 8;
|
||||
adev->gfx.config.sc_prim_fifo_size_frontend = 0x20;
|
||||
adev->gfx.config.sc_prim_fifo_size_backend = 0x100;
|
||||
adev->gfx.config.sc_hiz_tile_fifo_size = 0x80;
|
||||
adev->gfx.config.sc_earlyz_tile_fifo_size = 0x4C0;
|
||||
gb_addr_config = RREG32_SOC15(GC, 0, mmGB_ADDR_CONFIG);
|
||||
gb_addr_config &= ~0xf3e777ff;
|
||||
gb_addr_config |= 0x22010042;
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
break;
|
||||
@@ -2140,6 +2189,7 @@ static int gfx_v9_0_sw_init(void *handle)
|
||||
case CHIP_VEGA20:
|
||||
case CHIP_RAVEN:
|
||||
case CHIP_ARCTURUS:
|
||||
case CHIP_RENOIR:
|
||||
adev->gfx.mec.num_mec = 2;
|
||||
break;
|
||||
default:
|
||||
@@ -2297,7 +2347,7 @@ static int gfx_v9_0_sw_fini(void *handle)
|
||||
gfx_v9_0_mec_fini(adev);
|
||||
gfx_v9_0_ngg_fini(adev);
|
||||
amdgpu_bo_unref(&adev->gfx.rlc.clear_state_obj);
|
||||
if (adev->asic_type == CHIP_RAVEN) {
|
||||
if (adev->asic_type == CHIP_RAVEN || adev->asic_type == CHIP_RENOIR) {
|
||||
amdgpu_bo_free_kernel(&adev->gfx.rlc.cp_table_obj,
|
||||
&adev->gfx.rlc.cp_table_gpu_addr,
|
||||
(void **)&adev->gfx.rlc.cp_table_ptr);
|
||||
@@ -2976,6 +3026,7 @@ static int gfx_v9_0_rlc_resume(struct amdgpu_device *adev)
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_RAVEN:
|
||||
case CHIP_RENOIR:
|
||||
if (amdgpu_lbpw == 0)
|
||||
gfx_v9_0_enable_lbpw(adev, false);
|
||||
else
|
||||
@@ -4511,6 +4562,9 @@ static void gfx_v9_0_update_gfx_cg_power_gating(struct amdgpu_device *adev,
|
||||
{
|
||||
amdgpu_gfx_rlc_enter_safe_mode(adev);
|
||||
|
||||
if (is_support_sw_smu(adev) && !enable)
|
||||
smu_set_gfx_cgpg(&adev->smu, enable);
|
||||
|
||||
if ((adev->pg_flags & AMD_PG_SUPPORT_GFX_PG) && enable) {
|
||||
gfx_v9_0_enable_gfx_cg_power_gating(adev, true);
|
||||
if (adev->pg_flags & AMD_PG_SUPPORT_GFX_PIPELINE)
|
||||
@@ -4622,6 +4676,9 @@ static void gfx_v9_0_update_3d_clock_gating(struct amdgpu_device *adev,
|
||||
{
|
||||
uint32_t data, def;
|
||||
|
||||
if (adev->asic_type == CHIP_ARCTURUS)
|
||||
return;
|
||||
|
||||
amdgpu_gfx_rlc_enter_safe_mode(adev);
|
||||
|
||||
/* Enable 3D CGCG/CGLS */
|
||||
@@ -4687,8 +4744,12 @@ static void gfx_v9_0_update_coarse_grain_clock_gating(struct amdgpu_device *adev
|
||||
/* enable cgcg FSM(0x0000363F) */
|
||||
def = RREG32_SOC15(GC, 0, mmRLC_CGCG_CGLS_CTRL);
|
||||
|
||||
data = (0x36 << RLC_CGCG_CGLS_CTRL__CGCG_GFX_IDLE_THRESHOLD__SHIFT) |
|
||||
RLC_CGCG_CGLS_CTRL__CGCG_EN_MASK;
|
||||
if (adev->asic_type == CHIP_ARCTURUS)
|
||||
data = (0x2000 << RLC_CGCG_CGLS_CTRL__CGCG_GFX_IDLE_THRESHOLD__SHIFT) |
|
||||
RLC_CGCG_CGLS_CTRL__CGCG_EN_MASK;
|
||||
else
|
||||
data = (0x36 << RLC_CGCG_CGLS_CTRL__CGCG_GFX_IDLE_THRESHOLD__SHIFT) |
|
||||
RLC_CGCG_CGLS_CTRL__CGCG_EN_MASK;
|
||||
if (adev->cg_flags & AMD_CG_SUPPORT_GFX_CGLS)
|
||||
data |= (0x000F << RLC_CGCG_CGLS_CTRL__CGLS_REP_COMPANSAT_DELAY__SHIFT) |
|
||||
RLC_CGCG_CGLS_CTRL__CGLS_EN_MASK;
|
||||
@@ -4760,6 +4821,7 @@ static int gfx_v9_0_set_powergating_state(void *handle,
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_RAVEN:
|
||||
case CHIP_RENOIR:
|
||||
if (!enable) {
|
||||
amdgpu_gfx_off_ctrl(adev, false);
|
||||
cancel_delayed_work_sync(&adev->gfx.gfx_off_delay_work);
|
||||
@@ -4778,6 +4840,8 @@ static int gfx_v9_0_set_powergating_state(void *handle,
|
||||
gfx_v9_0_enable_cp_power_gating(adev, false);
|
||||
|
||||
/* update gfx cgpg state */
|
||||
if (is_support_sw_smu(adev) && enable)
|
||||
smu_set_gfx_cgpg(&adev->smu, enable);
|
||||
gfx_v9_0_update_gfx_cg_power_gating(adev, enable);
|
||||
|
||||
/* update mgcg state */
|
||||
@@ -4814,6 +4878,8 @@ static int gfx_v9_0_set_clockgating_state(void *handle,
|
||||
case CHIP_VEGA12:
|
||||
case CHIP_VEGA20:
|
||||
case CHIP_RAVEN:
|
||||
case CHIP_ARCTURUS:
|
||||
case CHIP_RENOIR:
|
||||
gfx_v9_0_update_gfx_clock_gating(adev,
|
||||
state == AMD_CG_STATE_GATE ? true : false);
|
||||
break;
|
||||
@@ -5396,7 +5462,7 @@ static void gfx_v9_0_ring_soft_recovery(struct amdgpu_ring *ring, unsigned vmid)
|
||||
value = REG_SET_FIELD(value, SQ_CMD, MODE, 0x01);
|
||||
value = REG_SET_FIELD(value, SQ_CMD, CHECK_VMID, 1);
|
||||
value = REG_SET_FIELD(value, SQ_CMD, VM_ID, vmid);
|
||||
WREG32(mmSQ_CMD, value);
|
||||
WREG32_SOC15(GC, 0, mmSQ_CMD, value);
|
||||
}
|
||||
|
||||
static void gfx_v9_0_set_gfx_eop_interrupt_state(struct amdgpu_device *adev,
|
||||
@@ -5978,6 +6044,9 @@ static int gfx_v9_0_ras_error_inject(struct amdgpu_device *adev,
|
||||
if (adev->asic_type != CHIP_VEGA20)
|
||||
return -EINVAL;
|
||||
|
||||
if (info->head.sub_block_index >= ARRAY_SIZE(ras_gfx_subblocks))
|
||||
return -EINVAL;
|
||||
|
||||
if (!ras_gfx_subblocks[info->head.sub_block_index].name)
|
||||
return -EPERM;
|
||||
|
||||
@@ -6285,6 +6354,7 @@ static void gfx_v9_0_set_rlc_funcs(struct amdgpu_device *adev)
|
||||
case CHIP_VEGA20:
|
||||
case CHIP_RAVEN:
|
||||
case CHIP_ARCTURUS:
|
||||
case CHIP_RENOIR:
|
||||
adev->gfx.rlc.funcs = &gfx_v9_0_rlc_funcs;
|
||||
break;
|
||||
default:
|
||||
|
@@ -140,7 +140,7 @@ static void gfxhub_v2_0_init_cache_regs(struct amdgpu_device *adev)
|
||||
/* XXX for emulation, Refer to closed source code.*/
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL,
|
||||
L2_PDE0_CACHE_TAG_GENERATION_MODE, 0);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL, PDE_FAULT_CLASSIFICATION, 1);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL, PDE_FAULT_CLASSIFICATION, 0);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL, CONTEXT1_IDENTITY_ACCESS_MODE, 1);
|
||||
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL, IDENTITY_MODE_FRAGMENT_SIZE, 0);
|
||||
WREG32_SOC15(GC, 0, mmGCVM_L2_CNTL, tmp);
|
||||
|
@@ -141,17 +141,40 @@ static int gmc_v10_0_process_interrupt(struct amdgpu_device *adev,
|
||||
}
|
||||
|
||||
if (printk_ratelimit()) {
|
||||
struct amdgpu_task_info task_info;
|
||||
|
||||
memset(&task_info, 0, sizeof(struct amdgpu_task_info));
|
||||
amdgpu_vm_get_task_info(adev, entry->pasid, &task_info);
|
||||
|
||||
dev_err(adev->dev,
|
||||
"[%s] VMC page fault (src_id:%u ring:%u vmid:%u pasid:%u)\n",
|
||||
"[%s] page fault (src_id:%u ring:%u vmid:%u pasid:%u, "
|
||||
"for process %s pid %d thread %s pid %d)\n",
|
||||
entry->vmid_src ? "mmhub" : "gfxhub",
|
||||
entry->src_id, entry->ring_id, entry->vmid,
|
||||
entry->pasid);
|
||||
dev_err(adev->dev, " at page 0x%016llx from %d\n",
|
||||
entry->pasid, task_info.process_name, task_info.tgid,
|
||||
task_info.task_name, task_info.pid);
|
||||
dev_err(adev->dev, " in page starting at address 0x%016llx from client %d\n",
|
||||
addr, entry->client_id);
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
dev_err(adev->dev,
|
||||
"VM_L2_PROTECTION_FAULT_STATUS:0x%08X\n",
|
||||
"GCVM_L2_PROTECTION_FAULT_STATUS:0x%08X\n",
|
||||
status);
|
||||
dev_err(adev->dev, "\t MORE_FAULTS: 0x%lx\n",
|
||||
REG_GET_FIELD(status,
|
||||
GCVM_L2_PROTECTION_FAULT_STATUS, MORE_FAULTS));
|
||||
dev_err(adev->dev, "\t WALKER_ERROR: 0x%lx\n",
|
||||
REG_GET_FIELD(status,
|
||||
GCVM_L2_PROTECTION_FAULT_STATUS, WALKER_ERROR));
|
||||
dev_err(adev->dev, "\t PERMISSION_FAULTS: 0x%lx\n",
|
||||
REG_GET_FIELD(status,
|
||||
GCVM_L2_PROTECTION_FAULT_STATUS, PERMISSION_FAULTS));
|
||||
dev_err(adev->dev, "\t MAPPING_ERROR: 0x%lx\n",
|
||||
REG_GET_FIELD(status,
|
||||
GCVM_L2_PROTECTION_FAULT_STATUS, MAPPING_ERROR));
|
||||
dev_err(adev->dev, "\t RW: 0x%lx\n",
|
||||
REG_GET_FIELD(status,
|
||||
GCVM_L2_PROTECTION_FAULT_STATUS, RW));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -230,8 +253,8 @@ static void gmc_v10_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid,
|
||||
*
|
||||
* Flush the TLB for the requested page table.
|
||||
*/
|
||||
static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device *adev,
|
||||
uint32_t vmid, uint32_t flush_type)
|
||||
static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
||||
uint32_t vmhub, uint32_t flush_type)
|
||||
{
|
||||
struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
|
||||
struct dma_fence *fence;
|
||||
@@ -244,7 +267,14 @@ static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device *adev,
|
||||
|
||||
mutex_lock(&adev->mman.gtt_window_lock);
|
||||
|
||||
gmc_v10_0_flush_vm_hub(adev, vmid, AMDGPU_MMHUB_0, 0);
|
||||
if (vmhub == AMDGPU_MMHUB_0) {
|
||||
gmc_v10_0_flush_vm_hub(adev, vmid, AMDGPU_MMHUB_0, 0);
|
||||
mutex_unlock(&adev->mman.gtt_window_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
BUG_ON(vmhub != AMDGPU_GFXHUB_0);
|
||||
|
||||
if (!adev->mman.buffer_funcs_enabled ||
|
||||
!adev->ib_pool_ready ||
|
||||
adev->in_gpu_reset) {
|
||||
@@ -592,7 +622,6 @@ static unsigned gmc_v10_0_get_vbios_fb_size(struct amdgpu_device *adev)
|
||||
static int gmc_v10_0_sw_init(void *handle)
|
||||
{
|
||||
int r;
|
||||
int dma_bits;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
gfxhub_v2_0_init(adev);
|
||||
@@ -642,26 +671,10 @@ static int gmc_v10_0_sw_init(void *handle)
|
||||
else
|
||||
adev->gmc.stolen_size = 9 * 1024 *1024;
|
||||
|
||||
/*
|
||||
* Set DMA mask + need_dma32 flags.
|
||||
* PCIE - can handle 44-bits.
|
||||
* IGP - can handle 44-bits
|
||||
* PCI - dma32 for legacy pci gart, 44 bits on navi10
|
||||
*/
|
||||
adev->need_dma32 = false;
|
||||
dma_bits = adev->need_dma32 ? 32 : 44;
|
||||
|
||||
r = pci_set_dma_mask(adev->pdev, DMA_BIT_MASK(dma_bits));
|
||||
r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(44));
|
||||
if (r) {
|
||||
adev->need_dma32 = true;
|
||||
dma_bits = 32;
|
||||
printk(KERN_WARNING "amdgpu: No suitable DMA available.\n");
|
||||
}
|
||||
|
||||
r = pci_set_consistent_dma_mask(adev->pdev, DMA_BIT_MASK(dma_bits));
|
||||
if (r) {
|
||||
pci_set_consistent_dma_mask(adev->pdev, DMA_BIT_MASK(32));
|
||||
printk(KERN_WARNING "amdgpu: No coherent DMA available.\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
r = gmc_v10_0_mc_init(adev);
|
||||
@@ -773,7 +786,8 @@ static int gmc_v10_0_gart_enable(struct amdgpu_device *adev)
|
||||
|
||||
gfxhub_v2_0_set_fault_enable_default(adev, value);
|
||||
mmhub_v2_0_set_fault_enable_default(adev, value);
|
||||
gmc_v10_0_flush_gpu_tlb(adev, 0, 0);
|
||||
gmc_v10_0_flush_gpu_tlb(adev, 0, AMDGPU_MMHUB_0, 0);
|
||||
gmc_v10_0_flush_gpu_tlb(adev, 0, AMDGPU_GFXHUB_0, 0);
|
||||
|
||||
DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
|
||||
(unsigned)(adev->gmc.gart_size >> 20),
|
||||
|
@@ -362,8 +362,8 @@ static int gmc_v6_0_mc_init(struct amdgpu_device *adev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gmc_v6_0_flush_gpu_tlb(struct amdgpu_device *adev,
|
||||
uint32_t vmid, uint32_t flush_type)
|
||||
static void gmc_v6_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
||||
uint32_t vmhub, uint32_t flush_type)
|
||||
{
|
||||
WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid);
|
||||
}
|
||||
@@ -571,7 +571,7 @@ static int gmc_v6_0_gart_enable(struct amdgpu_device *adev)
|
||||
else
|
||||
gmc_v6_0_set_fault_enable_default(adev, true);
|
||||
|
||||
gmc_v6_0_flush_gpu_tlb(adev, 0, 0);
|
||||
gmc_v6_0_flush_gpu_tlb(adev, 0, 0, 0);
|
||||
dev_info(adev->dev, "PCIE GART of %uM enabled (table at 0x%016llX).\n",
|
||||
(unsigned)(adev->gmc.gart_size >> 20),
|
||||
(unsigned long long)table_addr);
|
||||
@@ -839,9 +839,10 @@ static unsigned gmc_v6_0_get_vbios_fb_size(struct amdgpu_device *adev)
|
||||
static int gmc_v6_0_sw_init(void *handle)
|
||||
{
|
||||
int r;
|
||||
int dma_bits;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
adev->num_vmhubs = 1;
|
||||
|
||||
if (adev->flags & AMD_IS_APU) {
|
||||
adev->gmc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
|
||||
} else {
|
||||
@@ -862,20 +863,12 @@ static int gmc_v6_0_sw_init(void *handle)
|
||||
|
||||
adev->gmc.mc_mask = 0xffffffffffULL;
|
||||
|
||||
adev->need_dma32 = false;
|
||||
dma_bits = adev->need_dma32 ? 32 : 40;
|
||||
r = pci_set_dma_mask(adev->pdev, DMA_BIT_MASK(dma_bits));
|
||||
r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(44));
|
||||
if (r) {
|
||||
adev->need_dma32 = true;
|
||||
dma_bits = 32;
|
||||
dev_warn(adev->dev, "amdgpu: No suitable DMA available.\n");
|
||||
return r;
|
||||
}
|
||||
r = pci_set_consistent_dma_mask(adev->pdev, DMA_BIT_MASK(dma_bits));
|
||||
if (r) {
|
||||
pci_set_consistent_dma_mask(adev->pdev, DMA_BIT_MASK(32));
|
||||
dev_warn(adev->dev, "amdgpu: No coherent DMA available.\n");
|
||||
}
|
||||
adev->need_swiotlb = drm_need_swiotlb(dma_bits);
|
||||
adev->need_swiotlb = drm_need_swiotlb(44);
|
||||
|
||||
r = gmc_v6_0_init_microcode(adev);
|
||||
if (r) {
|
||||
|
@@ -433,8 +433,8 @@ static int gmc_v7_0_mc_init(struct amdgpu_device *adev)
|
||||
*
|
||||
* Flush the TLB for the requested page table (CIK).
|
||||
*/
|
||||
static void gmc_v7_0_flush_gpu_tlb(struct amdgpu_device *adev,
|
||||
uint32_t vmid, uint32_t flush_type)
|
||||
static void gmc_v7_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
||||
uint32_t vmhub, uint32_t flush_type)
|
||||
{
|
||||
/* bits 0-15 are the VM contexts0-15 */
|
||||
WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid);
|
||||
@@ -677,7 +677,7 @@ static int gmc_v7_0_gart_enable(struct amdgpu_device *adev)
|
||||
WREG32(mmCHUB_CONTROL, tmp);
|
||||
}
|
||||
|
||||
gmc_v7_0_flush_gpu_tlb(adev, 0, 0);
|
||||
gmc_v7_0_flush_gpu_tlb(adev, 0, 0, 0);
|
||||
DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
|
||||
(unsigned)(adev->gmc.gart_size >> 20),
|
||||
(unsigned long long)table_addr);
|
||||
@@ -959,9 +959,10 @@ static unsigned gmc_v7_0_get_vbios_fb_size(struct amdgpu_device *adev)
|
||||
static int gmc_v7_0_sw_init(void *handle)
|
||||
{
|
||||
int r;
|
||||
int dma_bits;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
adev->num_vmhubs = 1;
|
||||
|
||||
if (adev->flags & AMD_IS_APU) {
|
||||
adev->gmc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
|
||||
} else {
|
||||
@@ -990,25 +991,12 @@ static int gmc_v7_0_sw_init(void *handle)
|
||||
*/
|
||||
adev->gmc.mc_mask = 0xffffffffffULL; /* 40 bit MC */
|
||||
|
||||
/* set DMA mask + need_dma32 flags.
|
||||
* PCIE - can handle 40-bits.
|
||||
* IGP - can handle 40-bits
|
||||
* PCI - dma32 for legacy pci gart, 40 bits on newer asics
|
||||
*/
|
||||
adev->need_dma32 = false;
|
||||
dma_bits = adev->need_dma32 ? 32 : 40;
|
||||
r = pci_set_dma_mask(adev->pdev, DMA_BIT_MASK(dma_bits));
|
||||
r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(40));
|
||||
if (r) {
|
||||
adev->need_dma32 = true;
|
||||
dma_bits = 32;
|
||||
pr_warn("amdgpu: No suitable DMA available\n");
|
||||
return r;
|
||||
}
|
||||
r = pci_set_consistent_dma_mask(adev->pdev, DMA_BIT_MASK(dma_bits));
|
||||
if (r) {
|
||||
pci_set_consistent_dma_mask(adev->pdev, DMA_BIT_MASK(32));
|
||||
pr_warn("amdgpu: No coherent DMA available\n");
|
||||
}
|
||||
adev->need_swiotlb = drm_need_swiotlb(dma_bits);
|
||||
adev->need_swiotlb = drm_need_swiotlb(40);
|
||||
|
||||
r = gmc_v7_0_init_microcode(adev);
|
||||
if (r) {
|
||||
|
@@ -635,8 +635,8 @@ static int gmc_v8_0_mc_init(struct amdgpu_device *adev)
|
||||
*
|
||||
* Flush the TLB for the requested page table (VI).
|
||||
*/
|
||||
static void gmc_v8_0_flush_gpu_tlb(struct amdgpu_device *adev,
|
||||
uint32_t vmid, uint32_t flush_type)
|
||||
static void gmc_v8_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
||||
uint32_t vmhub, uint32_t flush_type)
|
||||
{
|
||||
/* bits 0-15 are the VM contexts0-15 */
|
||||
WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid);
|
||||
@@ -921,7 +921,7 @@ static int gmc_v8_0_gart_enable(struct amdgpu_device *adev)
|
||||
else
|
||||
gmc_v8_0_set_fault_enable_default(adev, true);
|
||||
|
||||
gmc_v8_0_flush_gpu_tlb(adev, 0, 0);
|
||||
gmc_v8_0_flush_gpu_tlb(adev, 0, 0, 0);
|
||||
DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
|
||||
(unsigned)(adev->gmc.gart_size >> 20),
|
||||
(unsigned long long)table_addr);
|
||||
@@ -1079,9 +1079,10 @@ static unsigned gmc_v8_0_get_vbios_fb_size(struct amdgpu_device *adev)
|
||||
static int gmc_v8_0_sw_init(void *handle)
|
||||
{
|
||||
int r;
|
||||
int dma_bits;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
adev->num_vmhubs = 1;
|
||||
|
||||
if (adev->flags & AMD_IS_APU) {
|
||||
adev->gmc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
|
||||
} else {
|
||||
@@ -1116,25 +1117,12 @@ static int gmc_v8_0_sw_init(void *handle)
|
||||
*/
|
||||
adev->gmc.mc_mask = 0xffffffffffULL; /* 40 bit MC */
|
||||
|
||||
/* set DMA mask + need_dma32 flags.
|
||||
* PCIE - can handle 40-bits.
|
||||
* IGP - can handle 40-bits
|
||||
* PCI - dma32 for legacy pci gart, 40 bits on newer asics
|
||||
*/
|
||||
adev->need_dma32 = false;
|
||||
dma_bits = adev->need_dma32 ? 32 : 40;
|
||||
r = pci_set_dma_mask(adev->pdev, DMA_BIT_MASK(dma_bits));
|
||||
r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(40));
|
||||
if (r) {
|
||||
adev->need_dma32 = true;
|
||||
dma_bits = 32;
|
||||
pr_warn("amdgpu: No suitable DMA available\n");
|
||||
return r;
|
||||
}
|
||||
r = pci_set_consistent_dma_mask(adev->pdev, DMA_BIT_MASK(dma_bits));
|
||||
if (r) {
|
||||
pci_set_consistent_dma_mask(adev->pdev, DMA_BIT_MASK(32));
|
||||
pr_warn("amdgpu: No coherent DMA available\n");
|
||||
}
|
||||
adev->need_swiotlb = drm_need_swiotlb(dma_bits);
|
||||
adev->need_swiotlb = drm_need_swiotlb(40);
|
||||
|
||||
r = gmc_v8_0_init_microcode(adev);
|
||||
if (r) {
|
||||
|
@@ -47,6 +47,7 @@
|
||||
|
||||
#include "gfxhub_v1_0.h"
|
||||
#include "mmhub_v1_0.h"
|
||||
#include "athub_v1_0.h"
|
||||
#include "gfxhub_v1_1.h"
|
||||
#include "mmhub_v9_4.h"
|
||||
#include "umc_v6_1.h"
|
||||
@@ -266,7 +267,7 @@ static int gmc_v9_0_process_ecc_irq(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *source,
|
||||
struct amdgpu_iv_entry *entry)
|
||||
{
|
||||
struct ras_common_if *ras_if = adev->gmc.ras_if;
|
||||
struct ras_common_if *ras_if = adev->gmc.umc_ras_if;
|
||||
struct ras_dispatch_if ih_data = {
|
||||
.entry = entry,
|
||||
};
|
||||
@@ -390,6 +391,9 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev,
|
||||
dev_err(adev->dev, "\t MAPPING_ERROR: 0x%lx\n",
|
||||
REG_GET_FIELD(status,
|
||||
VM_L2_PROTECTION_FAULT_STATUS, MAPPING_ERROR));
|
||||
dev_err(adev->dev, "\t RW: 0x%lx\n",
|
||||
REG_GET_FIELD(status,
|
||||
VM_L2_PROTECTION_FAULT_STATUS, RW));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -452,44 +456,45 @@ static uint32_t gmc_v9_0_get_invalidate_req(unsigned int vmid,
|
||||
*
|
||||
* Flush the TLB for the requested page table using certain type.
|
||||
*/
|
||||
static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev,
|
||||
uint32_t vmid, uint32_t flush_type)
|
||||
static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
||||
uint32_t vmhub, uint32_t flush_type)
|
||||
{
|
||||
const unsigned eng = 17;
|
||||
unsigned i, j;
|
||||
u32 j, tmp;
|
||||
struct amdgpu_vmhub *hub;
|
||||
|
||||
for (i = 0; i < adev->num_vmhubs; ++i) {
|
||||
struct amdgpu_vmhub *hub = &adev->vmhub[i];
|
||||
u32 tmp = gmc_v9_0_get_invalidate_req(vmid, flush_type);
|
||||
BUG_ON(vmhub >= adev->num_vmhubs);
|
||||
|
||||
/* This is necessary for a HW workaround under SRIOV as well
|
||||
* as GFXOFF under bare metal
|
||||
*/
|
||||
if (adev->gfx.kiq.ring.sched.ready &&
|
||||
(amdgpu_sriov_runtime(adev) || !amdgpu_sriov_vf(adev)) &&
|
||||
!adev->in_gpu_reset) {
|
||||
uint32_t req = hub->vm_inv_eng0_req + eng;
|
||||
uint32_t ack = hub->vm_inv_eng0_ack + eng;
|
||||
hub = &adev->vmhub[vmhub];
|
||||
tmp = gmc_v9_0_get_invalidate_req(vmid, flush_type);
|
||||
|
||||
amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, tmp,
|
||||
1 << vmid);
|
||||
continue;
|
||||
}
|
||||
/* This is necessary for a HW workaround under SRIOV as well
|
||||
* as GFXOFF under bare metal
|
||||
*/
|
||||
if (adev->gfx.kiq.ring.sched.ready &&
|
||||
(amdgpu_sriov_runtime(adev) || !amdgpu_sriov_vf(adev)) &&
|
||||
!adev->in_gpu_reset) {
|
||||
uint32_t req = hub->vm_inv_eng0_req + eng;
|
||||
uint32_t ack = hub->vm_inv_eng0_ack + eng;
|
||||
|
||||
spin_lock(&adev->gmc.invalidate_lock);
|
||||
WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, tmp);
|
||||
for (j = 0; j < adev->usec_timeout; j++) {
|
||||
tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_ack + eng);
|
||||
if (tmp & (1 << vmid))
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
spin_unlock(&adev->gmc.invalidate_lock);
|
||||
if (j < adev->usec_timeout)
|
||||
continue;
|
||||
|
||||
DRM_ERROR("Timeout waiting for VM flush ACK!\n");
|
||||
amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, tmp,
|
||||
1 << vmid);
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock(&adev->gmc.invalidate_lock);
|
||||
WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, tmp);
|
||||
for (j = 0; j < adev->usec_timeout; j++) {
|
||||
tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_ack + eng);
|
||||
if (tmp & (1 << vmid))
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
spin_unlock(&adev->gmc.invalidate_lock);
|
||||
if (j < adev->usec_timeout)
|
||||
return;
|
||||
|
||||
DRM_ERROR("Timeout waiting for VM flush ACK!\n");
|
||||
}
|
||||
|
||||
static uint64_t gmc_v9_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring,
|
||||
@@ -656,6 +661,17 @@ static void gmc_v9_0_set_umc_funcs(struct amdgpu_device *adev)
|
||||
}
|
||||
}
|
||||
|
||||
static void gmc_v9_0_set_mmhub_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VEGA20:
|
||||
adev->mmhub_funcs = &mmhub_v1_0_funcs;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int gmc_v9_0_early_init(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
@@ -663,6 +679,7 @@ static int gmc_v9_0_early_init(void *handle)
|
||||
gmc_v9_0_set_gmc_funcs(adev);
|
||||
gmc_v9_0_set_irq_funcs(adev);
|
||||
gmc_v9_0_set_umc_funcs(adev);
|
||||
gmc_v9_0_set_mmhub_funcs(adev);
|
||||
|
||||
adev->gmc.shared_aperture_start = 0x2000000000000000ULL;
|
||||
adev->gmc.shared_aperture_end =
|
||||
@@ -690,6 +707,7 @@ static bool gmc_v9_0_keep_stolen_memory(struct amdgpu_device *adev)
|
||||
case CHIP_VEGA10:
|
||||
case CHIP_RAVEN:
|
||||
case CHIP_ARCTURUS:
|
||||
case CHIP_RENOIR:
|
||||
return true;
|
||||
case CHIP_VEGA12:
|
||||
case CHIP_VEGA20:
|
||||
@@ -728,27 +746,25 @@ static int gmc_v9_0_allocate_vm_inv_eng(struct amdgpu_device *adev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gmc_v9_0_ecc_late_init(void *handle)
|
||||
static int gmc_v9_0_ecc_ras_block_late_init(void *handle,
|
||||
struct ras_fs_if *fs_info, struct ras_common_if *ras_block)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct ras_common_if **ras_if = &adev->gmc.ras_if;
|
||||
struct ras_common_if **ras_if = NULL;
|
||||
struct ras_ih_if ih_info = {
|
||||
.cb = gmc_v9_0_process_ras_data_cb,
|
||||
};
|
||||
struct ras_fs_if fs_info = {
|
||||
.sysfs_name = "umc_err_count",
|
||||
.debugfs_name = "umc_err_inject",
|
||||
};
|
||||
struct ras_common_if ras_block = {
|
||||
.block = AMDGPU_RAS_BLOCK__UMC,
|
||||
.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE,
|
||||
.sub_block_index = 0,
|
||||
.name = "umc",
|
||||
};
|
||||
int r;
|
||||
|
||||
if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__UMC)) {
|
||||
amdgpu_ras_feature_enable_on_boot(adev, &ras_block, 0);
|
||||
if (ras_block->block == AMDGPU_RAS_BLOCK__UMC)
|
||||
ras_if = &adev->gmc.umc_ras_if;
|
||||
else if (ras_block->block == AMDGPU_RAS_BLOCK__MMHUB)
|
||||
ras_if = &adev->gmc.mmhub_ras_if;
|
||||
else
|
||||
BUG();
|
||||
|
||||
if (!amdgpu_ras_is_supported(adev, ras_block->block)) {
|
||||
amdgpu_ras_feature_enable_on_boot(adev, ras_block, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -763,7 +779,7 @@ static int gmc_v9_0_ecc_late_init(void *handle)
|
||||
if (r == -EAGAIN) {
|
||||
/* request a gpu reset. will run again. */
|
||||
amdgpu_ras_request_reset_on_boot(adev,
|
||||
AMDGPU_RAS_BLOCK__UMC);
|
||||
ras_block->block);
|
||||
return 0;
|
||||
}
|
||||
/* fail to enable ras, cleanup all. */
|
||||
@@ -777,41 +793,46 @@ static int gmc_v9_0_ecc_late_init(void *handle)
|
||||
if (!*ras_if)
|
||||
return -ENOMEM;
|
||||
|
||||
**ras_if = ras_block;
|
||||
**ras_if = *ras_block;
|
||||
|
||||
r = amdgpu_ras_feature_enable_on_boot(adev, *ras_if, 1);
|
||||
if (r) {
|
||||
if (r == -EAGAIN) {
|
||||
amdgpu_ras_request_reset_on_boot(adev,
|
||||
AMDGPU_RAS_BLOCK__UMC);
|
||||
ras_block->block);
|
||||
r = 0;
|
||||
}
|
||||
goto feature;
|
||||
}
|
||||
|
||||
ih_info.head = **ras_if;
|
||||
fs_info.head = **ras_if;
|
||||
fs_info->head = **ras_if;
|
||||
|
||||
r = amdgpu_ras_interrupt_add_handler(adev, &ih_info);
|
||||
if (r)
|
||||
goto interrupt;
|
||||
if (ras_block->block == AMDGPU_RAS_BLOCK__UMC) {
|
||||
r = amdgpu_ras_interrupt_add_handler(adev, &ih_info);
|
||||
if (r)
|
||||
goto interrupt;
|
||||
}
|
||||
|
||||
amdgpu_ras_debugfs_create(adev, &fs_info);
|
||||
amdgpu_ras_debugfs_create(adev, fs_info);
|
||||
|
||||
r = amdgpu_ras_sysfs_create(adev, &fs_info);
|
||||
r = amdgpu_ras_sysfs_create(adev, fs_info);
|
||||
if (r)
|
||||
goto sysfs;
|
||||
resume:
|
||||
r = amdgpu_irq_get(adev, &adev->gmc.ecc_irq, 0);
|
||||
if (r)
|
||||
goto irq;
|
||||
if (ras_block->block == AMDGPU_RAS_BLOCK__UMC) {
|
||||
r = amdgpu_irq_get(adev, &adev->gmc.ecc_irq, 0);
|
||||
if (r)
|
||||
goto irq;
|
||||
}
|
||||
|
||||
return 0;
|
||||
irq:
|
||||
amdgpu_ras_sysfs_remove(adev, *ras_if);
|
||||
sysfs:
|
||||
amdgpu_ras_debugfs_remove(adev, *ras_if);
|
||||
amdgpu_ras_interrupt_remove_handler(adev, &ih_info);
|
||||
if (ras_block->block == AMDGPU_RAS_BLOCK__UMC)
|
||||
amdgpu_ras_interrupt_remove_handler(adev, &ih_info);
|
||||
interrupt:
|
||||
amdgpu_ras_feature_enable(adev, *ras_if, 0);
|
||||
feature:
|
||||
@@ -820,6 +841,40 @@ feature:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int gmc_v9_0_ecc_late_init(void *handle)
|
||||
{
|
||||
int r;
|
||||
|
||||
struct ras_fs_if umc_fs_info = {
|
||||
.sysfs_name = "umc_err_count",
|
||||
.debugfs_name = "umc_err_inject",
|
||||
};
|
||||
struct ras_common_if umc_ras_block = {
|
||||
.block = AMDGPU_RAS_BLOCK__UMC,
|
||||
.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE,
|
||||
.sub_block_index = 0,
|
||||
.name = "umc",
|
||||
};
|
||||
struct ras_fs_if mmhub_fs_info = {
|
||||
.sysfs_name = "mmhub_err_count",
|
||||
.debugfs_name = "mmhub_err_inject",
|
||||
};
|
||||
struct ras_common_if mmhub_ras_block = {
|
||||
.block = AMDGPU_RAS_BLOCK__MMHUB,
|
||||
.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE,
|
||||
.sub_block_index = 0,
|
||||
.name = "mmhub",
|
||||
};
|
||||
|
||||
r = gmc_v9_0_ecc_ras_block_late_init(handle,
|
||||
&umc_fs_info, &umc_ras_block);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = gmc_v9_0_ecc_ras_block_late_init(handle,
|
||||
&mmhub_fs_info, &mmhub_ras_block);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int gmc_v9_0_late_init(void *handle)
|
||||
{
|
||||
@@ -869,18 +924,17 @@ static void gmc_v9_0_vram_gtt_location(struct amdgpu_device *adev,
|
||||
struct amdgpu_gmc *mc)
|
||||
{
|
||||
u64 base = 0;
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
if (adev->asic_type == CHIP_ARCTURUS)
|
||||
base = mmhub_v9_4_get_fb_location(adev);
|
||||
else
|
||||
base = mmhub_v1_0_get_fb_location(adev);
|
||||
}
|
||||
|
||||
if (adev->asic_type == CHIP_ARCTURUS)
|
||||
base = mmhub_v9_4_get_fb_location(adev);
|
||||
else if (!amdgpu_sriov_vf(adev))
|
||||
base = mmhub_v1_0_get_fb_location(adev);
|
||||
|
||||
/* add the xgmi offset of the physical node */
|
||||
base += adev->gmc.xgmi.physical_node_id * adev->gmc.xgmi.node_segment_size;
|
||||
amdgpu_gmc_vram_location(adev, mc, base);
|
||||
amdgpu_gmc_gart_location(adev, mc);
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
amdgpu_gmc_agp_location(adev, mc);
|
||||
amdgpu_gmc_agp_location(adev, mc);
|
||||
/* base offset of vram pages */
|
||||
adev->vm_manager.vram_base_offset = gfxhub_v1_0_get_mc_fb_offset(adev);
|
||||
|
||||
@@ -959,6 +1013,7 @@ static int gmc_v9_0_mc_init(struct amdgpu_device *adev)
|
||||
adev->gmc.gart_size = 512ULL << 20;
|
||||
break;
|
||||
case CHIP_RAVEN: /* DCE SG support */
|
||||
case CHIP_RENOIR:
|
||||
adev->gmc.gart_size = 1024ULL << 20;
|
||||
break;
|
||||
}
|
||||
@@ -1009,6 +1064,7 @@ static unsigned gmc_v9_0_get_vbios_fb_size(struct amdgpu_device *adev)
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_RAVEN:
|
||||
case CHIP_RENOIR:
|
||||
viewport = RREG32_SOC15(DCE, 0, mmHUBP0_DCSURF_PRI_VIEWPORT_DIMENSION);
|
||||
size = (REG_GET_FIELD(viewport,
|
||||
HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION, PRI_VIEWPORT_HEIGHT) *
|
||||
@@ -1037,7 +1093,6 @@ static unsigned gmc_v9_0_get_vbios_fb_size(struct amdgpu_device *adev)
|
||||
static int gmc_v9_0_sw_init(void *handle)
|
||||
{
|
||||
int r;
|
||||
int dma_bits;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
gfxhub_v1_0_init(adev);
|
||||
@@ -1065,8 +1120,10 @@ static int gmc_v9_0_sw_init(void *handle)
|
||||
case CHIP_VEGA10:
|
||||
case CHIP_VEGA12:
|
||||
case CHIP_VEGA20:
|
||||
case CHIP_RENOIR:
|
||||
adev->num_vmhubs = 2;
|
||||
|
||||
|
||||
/*
|
||||
* To fulfill 4-level page support,
|
||||
* vm size is 256TB (48bit), maximum size of Vega10,
|
||||
@@ -1119,25 +1176,12 @@ static int gmc_v9_0_sw_init(void *handle)
|
||||
*/
|
||||
adev->gmc.mc_mask = 0xffffffffffffULL; /* 48 bit MC */
|
||||
|
||||
/* set DMA mask + need_dma32 flags.
|
||||
* PCIE - can handle 44-bits.
|
||||
* IGP - can handle 44-bits
|
||||
* PCI - dma32 for legacy pci gart, 44 bits on vega10
|
||||
*/
|
||||
adev->need_dma32 = false;
|
||||
dma_bits = adev->need_dma32 ? 32 : 44;
|
||||
r = pci_set_dma_mask(adev->pdev, DMA_BIT_MASK(dma_bits));
|
||||
r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(44));
|
||||
if (r) {
|
||||
adev->need_dma32 = true;
|
||||
dma_bits = 32;
|
||||
printk(KERN_WARNING "amdgpu: No suitable DMA available.\n");
|
||||
return r;
|
||||
}
|
||||
r = pci_set_consistent_dma_mask(adev->pdev, DMA_BIT_MASK(dma_bits));
|
||||
if (r) {
|
||||
pci_set_consistent_dma_mask(adev->pdev, DMA_BIT_MASK(32));
|
||||
printk(KERN_WARNING "amdgpu: No coherent DMA available.\n");
|
||||
}
|
||||
adev->need_swiotlb = drm_need_swiotlb(dma_bits);
|
||||
adev->need_swiotlb = drm_need_swiotlb(44);
|
||||
|
||||
if (adev->gmc.xgmi.supported) {
|
||||
r = gfxhub_v1_1_get_xgmi_info(adev);
|
||||
@@ -1180,21 +1224,32 @@ static int gmc_v9_0_sw_fini(void *handle)
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__UMC) &&
|
||||
adev->gmc.ras_if) {
|
||||
struct ras_common_if *ras_if = adev->gmc.ras_if;
|
||||
adev->gmc.umc_ras_if) {
|
||||
struct ras_common_if *ras_if = adev->gmc.umc_ras_if;
|
||||
struct ras_ih_if ih_info = {
|
||||
.head = *ras_if,
|
||||
};
|
||||
|
||||
/*remove fs first*/
|
||||
/* remove fs first */
|
||||
amdgpu_ras_debugfs_remove(adev, ras_if);
|
||||
amdgpu_ras_sysfs_remove(adev, ras_if);
|
||||
/*remove the IH*/
|
||||
/* remove the IH */
|
||||
amdgpu_ras_interrupt_remove_handler(adev, &ih_info);
|
||||
amdgpu_ras_feature_enable(adev, ras_if, 0);
|
||||
kfree(ras_if);
|
||||
}
|
||||
|
||||
if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__MMHUB) &&
|
||||
adev->gmc.mmhub_ras_if) {
|
||||
struct ras_common_if *ras_if = adev->gmc.mmhub_ras_if;
|
||||
|
||||
/* remove fs and disable ras feature */
|
||||
amdgpu_ras_debugfs_remove(adev, ras_if);
|
||||
amdgpu_ras_sysfs_remove(adev, ras_if);
|
||||
amdgpu_ras_feature_enable(adev, ras_if, 0);
|
||||
kfree(ras_if);
|
||||
}
|
||||
|
||||
amdgpu_gem_force_release(adev);
|
||||
amdgpu_vm_manager_fini(adev);
|
||||
|
||||
@@ -1227,6 +1282,7 @@ static void gmc_v9_0_init_golden_registers(struct amdgpu_device *adev)
|
||||
case CHIP_VEGA12:
|
||||
break;
|
||||
case CHIP_RAVEN:
|
||||
/* TODO for renoir */
|
||||
soc15_program_register_sequence(adev,
|
||||
golden_settings_athub_1_0_0,
|
||||
ARRAY_SIZE(golden_settings_athub_1_0_0));
|
||||
@@ -1243,7 +1299,7 @@ static void gmc_v9_0_init_golden_registers(struct amdgpu_device *adev)
|
||||
*/
|
||||
static int gmc_v9_0_gart_enable(struct amdgpu_device *adev)
|
||||
{
|
||||
int r;
|
||||
int r, i;
|
||||
bool value;
|
||||
u32 tmp;
|
||||
|
||||
@@ -1261,6 +1317,7 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev)
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_RAVEN:
|
||||
/* TODO for renoir */
|
||||
mmhub_v1_0_update_power_gating(adev, true);
|
||||
break;
|
||||
default:
|
||||
@@ -1299,7 +1356,9 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev)
|
||||
mmhub_v9_4_set_fault_enable_default(adev, value);
|
||||
else
|
||||
mmhub_v1_0_set_fault_enable_default(adev, value);
|
||||
gmc_v9_0_flush_gpu_tlb(adev, 0, 0);
|
||||
|
||||
for (i = 0; i < adev->num_vmhubs; ++i)
|
||||
gmc_v9_0_flush_gpu_tlb(adev, 0, i, 0);
|
||||
|
||||
DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
|
||||
(unsigned)(adev->gmc.gart_size >> 20),
|
||||
@@ -1408,9 +1467,13 @@ static int gmc_v9_0_set_clockgating_state(void *handle,
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if (adev->asic_type == CHIP_ARCTURUS)
|
||||
return 0;
|
||||
mmhub_v9_4_set_clockgating(adev, state);
|
||||
else
|
||||
mmhub_v1_0_set_clockgating(adev, state);
|
||||
|
||||
return mmhub_v1_0_set_clockgating(adev, state);
|
||||
athub_v1_0_set_clockgating(adev, state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gmc_v9_0_get_clockgating_state(void *handle, u32 *flags)
|
||||
@@ -1418,9 +1481,11 @@ static void gmc_v9_0_get_clockgating_state(void *handle, u32 *flags)
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if (adev->asic_type == CHIP_ARCTURUS)
|
||||
return;
|
||||
mmhub_v9_4_get_clockgating(adev, flags);
|
||||
else
|
||||
mmhub_v1_0_get_clockgating(adev, flags);
|
||||
|
||||
mmhub_v1_0_get_clockgating(adev, flags);
|
||||
athub_v1_0_get_clockgating(adev, flags);
|
||||
}
|
||||
|
||||
static int gmc_v9_0_set_powergating_state(void *handle,
|
||||
|
@@ -21,13 +21,13 @@
|
||||
*
|
||||
*/
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_ras.h"
|
||||
#include "mmhub_v1_0.h"
|
||||
|
||||
#include "mmhub/mmhub_1_0_offset.h"
|
||||
#include "mmhub/mmhub_1_0_sh_mask.h"
|
||||
#include "mmhub/mmhub_1_0_default.h"
|
||||
#include "athub/athub_1_0_offset.h"
|
||||
#include "athub/athub_1_0_sh_mask.h"
|
||||
#include "mmhub/mmhub_9_4_0_offset.h"
|
||||
#include "vega10_enum.h"
|
||||
|
||||
#include "soc15_common.h"
|
||||
@@ -35,6 +35,9 @@
|
||||
#define mmDAGB0_CNTL_MISC2_RV 0x008f
|
||||
#define mmDAGB0_CNTL_MISC2_RV_BASE_IDX 0
|
||||
|
||||
#define EA_EDC_CNT_MASK 0x3
|
||||
#define EA_EDC_CNT_SHIFT 0x2
|
||||
|
||||
u64 mmhub_v1_0_get_fb_location(struct amdgpu_device *adev)
|
||||
{
|
||||
u64 base = RREG32_SOC15(MMHUB, 0, mmMC_VM_FB_LOCATION_BASE);
|
||||
@@ -491,22 +494,6 @@ static void mmhub_v1_0_update_medium_grain_clock_gating(struct amdgpu_device *ad
|
||||
WREG32_SOC15(MMHUB, 0, mmDAGB1_CNTL_MISC2, data2);
|
||||
}
|
||||
|
||||
static void athub_update_medium_grain_clock_gating(struct amdgpu_device *adev,
|
||||
bool enable)
|
||||
{
|
||||
uint32_t def, data;
|
||||
|
||||
def = data = RREG32_SOC15(ATHUB, 0, mmATHUB_MISC_CNTL);
|
||||
|
||||
if (enable && (adev->cg_flags & AMD_CG_SUPPORT_MC_MGCG))
|
||||
data |= ATHUB_MISC_CNTL__CG_ENABLE_MASK;
|
||||
else
|
||||
data &= ~ATHUB_MISC_CNTL__CG_ENABLE_MASK;
|
||||
|
||||
if (def != data)
|
||||
WREG32_SOC15(ATHUB, 0, mmATHUB_MISC_CNTL, data);
|
||||
}
|
||||
|
||||
static void mmhub_v1_0_update_medium_grain_light_sleep(struct amdgpu_device *adev,
|
||||
bool enable)
|
||||
{
|
||||
@@ -523,23 +510,6 @@ static void mmhub_v1_0_update_medium_grain_light_sleep(struct amdgpu_device *ade
|
||||
WREG32_SOC15(MMHUB, 0, mmATC_L2_MISC_CG, data);
|
||||
}
|
||||
|
||||
static void athub_update_medium_grain_light_sleep(struct amdgpu_device *adev,
|
||||
bool enable)
|
||||
{
|
||||
uint32_t def, data;
|
||||
|
||||
def = data = RREG32_SOC15(ATHUB, 0, mmATHUB_MISC_CNTL);
|
||||
|
||||
if (enable && (adev->cg_flags & AMD_CG_SUPPORT_MC_LS) &&
|
||||
(adev->cg_flags & AMD_CG_SUPPORT_HDP_LS))
|
||||
data |= ATHUB_MISC_CNTL__CG_MEM_LS_ENABLE_MASK;
|
||||
else
|
||||
data &= ~ATHUB_MISC_CNTL__CG_MEM_LS_ENABLE_MASK;
|
||||
|
||||
if(def != data)
|
||||
WREG32_SOC15(ATHUB, 0, mmATHUB_MISC_CNTL, data);
|
||||
}
|
||||
|
||||
int mmhub_v1_0_set_clockgating(struct amdgpu_device *adev,
|
||||
enum amd_clockgating_state state)
|
||||
{
|
||||
@@ -551,14 +521,11 @@ int mmhub_v1_0_set_clockgating(struct amdgpu_device *adev,
|
||||
case CHIP_VEGA12:
|
||||
case CHIP_VEGA20:
|
||||
case CHIP_RAVEN:
|
||||
case CHIP_RENOIR:
|
||||
mmhub_v1_0_update_medium_grain_clock_gating(adev,
|
||||
state == AMD_CG_STATE_GATE ? true : false);
|
||||
athub_update_medium_grain_clock_gating(adev,
|
||||
state == AMD_CG_STATE_GATE ? true : false);
|
||||
mmhub_v1_0_update_medium_grain_light_sleep(adev,
|
||||
state == AMD_CG_STATE_GATE ? true : false);
|
||||
athub_update_medium_grain_light_sleep(adev,
|
||||
state == AMD_CG_STATE_GATE ? true : false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -569,18 +536,85 @@ int mmhub_v1_0_set_clockgating(struct amdgpu_device *adev,
|
||||
|
||||
void mmhub_v1_0_get_clockgating(struct amdgpu_device *adev, u32 *flags)
|
||||
{
|
||||
int data;
|
||||
int data, data1;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
*flags = 0;
|
||||
|
||||
data = RREG32_SOC15(MMHUB, 0, mmATC_L2_MISC_CG);
|
||||
|
||||
data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2);
|
||||
|
||||
/* AMD_CG_SUPPORT_MC_MGCG */
|
||||
data = RREG32_SOC15(ATHUB, 0, mmATHUB_MISC_CNTL);
|
||||
if (data & ATHUB_MISC_CNTL__CG_ENABLE_MASK)
|
||||
if ((data & ATC_L2_MISC_CG__ENABLE_MASK) &&
|
||||
!(data1 & (DAGB0_CNTL_MISC2__DISABLE_WRREQ_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_WRRET_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_RDREQ_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_RDRET_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_TLBWR_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_TLBRD_CG_MASK)))
|
||||
*flags |= AMD_CG_SUPPORT_MC_MGCG;
|
||||
|
||||
/* AMD_CG_SUPPORT_MC_LS */
|
||||
data = RREG32_SOC15(MMHUB, 0, mmATC_L2_MISC_CG);
|
||||
if (data & ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK)
|
||||
*flags |= AMD_CG_SUPPORT_MC_LS;
|
||||
}
|
||||
|
||||
static void mmhub_v1_0_query_ras_error_count(struct amdgpu_device *adev,
|
||||
void *ras_error_status)
|
||||
{
|
||||
int i;
|
||||
uint32_t ea0_edc_cnt, ea0_edc_cnt2;
|
||||
uint32_t ea1_edc_cnt, ea1_edc_cnt2;
|
||||
struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status;
|
||||
|
||||
/* EDC CNT will be cleared automatically after read */
|
||||
ea0_edc_cnt = RREG32_SOC15(MMHUB, 0, mmMMEA0_EDC_CNT_VG20);
|
||||
ea0_edc_cnt2 = RREG32_SOC15(MMHUB, 0, mmMMEA0_EDC_CNT2_VG20);
|
||||
ea1_edc_cnt = RREG32_SOC15(MMHUB, 0, mmMMEA1_EDC_CNT_VG20);
|
||||
ea1_edc_cnt2 = RREG32_SOC15(MMHUB, 0, mmMMEA1_EDC_CNT2_VG20);
|
||||
|
||||
/* error count of each error type is recorded by 2 bits,
|
||||
* ce and ue count in EDC_CNT
|
||||
*/
|
||||
for (i = 0; i < 5; i++) {
|
||||
err_data->ce_count += (ea0_edc_cnt & EA_EDC_CNT_MASK);
|
||||
err_data->ce_count += (ea1_edc_cnt & EA_EDC_CNT_MASK);
|
||||
ea0_edc_cnt >>= EA_EDC_CNT_SHIFT;
|
||||
ea1_edc_cnt >>= EA_EDC_CNT_SHIFT;
|
||||
err_data->ue_count += (ea0_edc_cnt & EA_EDC_CNT_MASK);
|
||||
err_data->ue_count += (ea1_edc_cnt & EA_EDC_CNT_MASK);
|
||||
ea0_edc_cnt >>= EA_EDC_CNT_SHIFT;
|
||||
ea1_edc_cnt >>= EA_EDC_CNT_SHIFT;
|
||||
}
|
||||
/* successive ue count in EDC_CNT */
|
||||
for (i = 0; i < 5; i++) {
|
||||
err_data->ue_count += (ea0_edc_cnt & EA_EDC_CNT_MASK);
|
||||
err_data->ue_count += (ea1_edc_cnt & EA_EDC_CNT_MASK);
|
||||
ea0_edc_cnt >>= EA_EDC_CNT_SHIFT;
|
||||
ea1_edc_cnt >>= EA_EDC_CNT_SHIFT;
|
||||
}
|
||||
|
||||
/* ce and ue count in EDC_CNT2 */
|
||||
for (i = 0; i < 3; i++) {
|
||||
err_data->ce_count += (ea0_edc_cnt2 & EA_EDC_CNT_MASK);
|
||||
err_data->ce_count += (ea1_edc_cnt2 & EA_EDC_CNT_MASK);
|
||||
ea0_edc_cnt2 >>= EA_EDC_CNT_SHIFT;
|
||||
ea1_edc_cnt2 >>= EA_EDC_CNT_SHIFT;
|
||||
err_data->ue_count += (ea0_edc_cnt2 & EA_EDC_CNT_MASK);
|
||||
err_data->ue_count += (ea1_edc_cnt2 & EA_EDC_CNT_MASK);
|
||||
ea0_edc_cnt2 >>= EA_EDC_CNT_SHIFT;
|
||||
ea1_edc_cnt2 >>= EA_EDC_CNT_SHIFT;
|
||||
}
|
||||
/* successive ue count in EDC_CNT2 */
|
||||
for (i = 0; i < 6; i++) {
|
||||
err_data->ue_count += (ea0_edc_cnt2 & EA_EDC_CNT_MASK);
|
||||
err_data->ue_count += (ea1_edc_cnt2 & EA_EDC_CNT_MASK);
|
||||
ea0_edc_cnt2 >>= EA_EDC_CNT_SHIFT;
|
||||
ea1_edc_cnt2 >>= EA_EDC_CNT_SHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
const struct amdgpu_mmhub_funcs mmhub_v1_0_funcs = {
|
||||
.query_ras_error_count = mmhub_v1_0_query_ras_error_count,
|
||||
};
|
||||
|
@@ -23,6 +23,8 @@
|
||||
#ifndef __MMHUB_V1_0_H__
|
||||
#define __MMHUB_V1_0_H__
|
||||
|
||||
extern const struct amdgpu_mmhub_funcs mmhub_v1_0_funcs;
|
||||
|
||||
u64 mmhub_v1_0_get_fb_location(struct amdgpu_device *adev);
|
||||
int mmhub_v1_0_gart_enable(struct amdgpu_device *adev);
|
||||
void mmhub_v1_0_gart_disable(struct amdgpu_device *adev);
|
||||
|
@@ -126,7 +126,7 @@ static void mmhub_v2_0_init_cache_regs(struct amdgpu_device *adev)
|
||||
/* XXX for emulation, Refer to closed source code.*/
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, L2_PDE0_CACHE_TAG_GENERATION_MODE,
|
||||
0);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, PDE_FAULT_CLASSIFICATION, 1);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, PDE_FAULT_CLASSIFICATION, 0);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, CONTEXT1_IDENTITY_ACCESS_MODE, 1);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, IDENTITY_MODE_FRAGMENT_SIZE, 0);
|
||||
WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL, tmp);
|
||||
@@ -407,6 +407,7 @@ int mmhub_v2_0_set_clockgating(struct amdgpu_device *adev,
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_NAVI10:
|
||||
case CHIP_NAVI14:
|
||||
case CHIP_NAVI12:
|
||||
mmhub_v2_0_update_medium_grain_clock_gating(adev,
|
||||
state == AMD_CG_STATE_GATE ? true : false);
|
||||
mmhub_v2_0_update_medium_grain_light_sleep(adev,
|
||||
|
@@ -515,3 +515,128 @@ void mmhub_v9_4_init(struct amdgpu_device *adev)
|
||||
i * MMHUB_INSTANCE_REGISTER_OFFSET;
|
||||
}
|
||||
}
|
||||
|
||||
static void mmhub_v9_4_update_medium_grain_clock_gating(struct amdgpu_device *adev,
|
||||
bool enable)
|
||||
{
|
||||
uint32_t def, data, def1, data1;
|
||||
int i, j;
|
||||
int dist = mmDAGB1_CNTL_MISC2 - mmDAGB0_CNTL_MISC2;
|
||||
|
||||
for (i = 0; i < MMHUB_NUM_INSTANCES; i++) {
|
||||
def = data = RREG32_SOC15_OFFSET(MMHUB, 0,
|
||||
mmATCL2_0_ATC_L2_MISC_CG,
|
||||
i * MMHUB_INSTANCE_REGISTER_OFFSET);
|
||||
|
||||
if (enable && (adev->cg_flags & AMD_CG_SUPPORT_MC_MGCG))
|
||||
data |= ATCL2_0_ATC_L2_MISC_CG__ENABLE_MASK;
|
||||
else
|
||||
data &= ~ATCL2_0_ATC_L2_MISC_CG__ENABLE_MASK;
|
||||
|
||||
if (def != data)
|
||||
WREG32_SOC15_OFFSET(MMHUB, 0, mmATCL2_0_ATC_L2_MISC_CG,
|
||||
i * MMHUB_INSTANCE_REGISTER_OFFSET, data);
|
||||
|
||||
for (j = 0; j < 5; j++) {
|
||||
def1 = data1 = RREG32_SOC15_OFFSET(MMHUB, 0,
|
||||
mmDAGB0_CNTL_MISC2,
|
||||
i * MMHUB_INSTANCE_REGISTER_OFFSET +
|
||||
j * dist);
|
||||
if (enable &&
|
||||
(adev->cg_flags & AMD_CG_SUPPORT_MC_MGCG)) {
|
||||
data1 &=
|
||||
~(DAGB0_CNTL_MISC2__DISABLE_WRREQ_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_WRRET_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_RDREQ_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_RDRET_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_TLBWR_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_TLBRD_CG_MASK);
|
||||
} else {
|
||||
data1 |=
|
||||
(DAGB0_CNTL_MISC2__DISABLE_WRREQ_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_WRRET_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_RDREQ_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_RDRET_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_TLBWR_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_TLBRD_CG_MASK);
|
||||
}
|
||||
|
||||
if (def1 != data1)
|
||||
WREG32_SOC15_OFFSET(MMHUB, 0,
|
||||
mmDAGB0_CNTL_MISC2,
|
||||
i * MMHUB_INSTANCE_REGISTER_OFFSET +
|
||||
j * dist, data1);
|
||||
|
||||
if (i == 1 && j == 3)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void mmhub_v9_4_update_medium_grain_light_sleep(struct amdgpu_device *adev,
|
||||
bool enable)
|
||||
{
|
||||
uint32_t def, data;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MMHUB_NUM_INSTANCES; i++) {
|
||||
def = data = RREG32_SOC15_OFFSET(MMHUB, 0,
|
||||
mmATCL2_0_ATC_L2_MISC_CG,
|
||||
i * MMHUB_INSTANCE_REGISTER_OFFSET);
|
||||
|
||||
if (enable && (adev->cg_flags & AMD_CG_SUPPORT_MC_LS))
|
||||
data |= ATCL2_0_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK;
|
||||
else
|
||||
data &= ~ATCL2_0_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK;
|
||||
|
||||
if (def != data)
|
||||
WREG32_SOC15_OFFSET(MMHUB, 0, mmATCL2_0_ATC_L2_MISC_CG,
|
||||
i * MMHUB_INSTANCE_REGISTER_OFFSET, data);
|
||||
}
|
||||
}
|
||||
|
||||
int mmhub_v9_4_set_clockgating(struct amdgpu_device *adev,
|
||||
enum amd_clockgating_state state)
|
||||
{
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return 0;
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_ARCTURUS:
|
||||
mmhub_v9_4_update_medium_grain_clock_gating(adev,
|
||||
state == AMD_CG_STATE_GATE ? true : false);
|
||||
mmhub_v9_4_update_medium_grain_light_sleep(adev,
|
||||
state == AMD_CG_STATE_GATE ? true : false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mmhub_v9_4_get_clockgating(struct amdgpu_device *adev, u32 *flags)
|
||||
{
|
||||
int data, data1;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
*flags = 0;
|
||||
|
||||
/* AMD_CG_SUPPORT_MC_MGCG */
|
||||
data = RREG32_SOC15(MMHUB, 0, mmATCL2_0_ATC_L2_MISC_CG);
|
||||
|
||||
data1 = RREG32_SOC15(MMHUB, 0, mmATCL2_0_ATC_L2_MISC_CG);
|
||||
|
||||
if ((data & ATCL2_0_ATC_L2_MISC_CG__ENABLE_MASK) &&
|
||||
!(data1 & (DAGB0_CNTL_MISC2__DISABLE_WRREQ_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_WRRET_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_RDREQ_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_RDRET_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_TLBWR_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_TLBRD_CG_MASK)))
|
||||
*flags |= AMD_CG_SUPPORT_MC_MGCG;
|
||||
|
||||
/* AMD_CG_SUPPORT_MC_LS */
|
||||
if (data & ATCL2_0_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK)
|
||||
*flags |= AMD_CG_SUPPORT_MC_LS;
|
||||
}
|
||||
|
@@ -29,5 +29,8 @@ void mmhub_v9_4_gart_disable(struct amdgpu_device *adev);
|
||||
void mmhub_v9_4_set_fault_enable_default(struct amdgpu_device *adev,
|
||||
bool value);
|
||||
void mmhub_v9_4_init(struct amdgpu_device *adev);
|
||||
int mmhub_v9_4_set_clockgating(struct amdgpu_device *adev,
|
||||
enum amd_clockgating_state state);
|
||||
void mmhub_v9_4_get_clockgating(struct amdgpu_device *adev, u32 *flags);
|
||||
|
||||
#endif
|
||||
|
@@ -91,6 +91,26 @@ static void nbio_v7_0_sdma_doorbell_range(struct amdgpu_device *adev, int instan
|
||||
WREG32(reg, doorbell_range);
|
||||
}
|
||||
|
||||
static void nbio_v7_0_vcn_doorbell_range(struct amdgpu_device *adev, bool use_doorbell,
|
||||
int doorbell_index, int instance)
|
||||
{
|
||||
u32 reg = SOC15_REG_OFFSET(NBIO, 0, mmBIF_MMSCH0_DOORBELL_RANGE);
|
||||
|
||||
u32 doorbell_range = RREG32(reg);
|
||||
|
||||
if (use_doorbell) {
|
||||
doorbell_range = REG_SET_FIELD(doorbell_range,
|
||||
BIF_MMSCH0_DOORBELL_RANGE, OFFSET,
|
||||
doorbell_index);
|
||||
doorbell_range = REG_SET_FIELD(doorbell_range,
|
||||
BIF_MMSCH0_DOORBELL_RANGE, SIZE, 8);
|
||||
} else
|
||||
doorbell_range = REG_SET_FIELD(doorbell_range,
|
||||
BIF_MMSCH0_DOORBELL_RANGE, SIZE, 0);
|
||||
|
||||
WREG32(reg, doorbell_range);
|
||||
}
|
||||
|
||||
static void nbio_v7_0_enable_doorbell_aperture(struct amdgpu_device *adev,
|
||||
bool enable)
|
||||
{
|
||||
@@ -282,6 +302,7 @@ const struct amdgpu_nbio_funcs nbio_v7_0_funcs = {
|
||||
.hdp_flush = nbio_v7_0_hdp_flush,
|
||||
.get_memsize = nbio_v7_0_get_memsize,
|
||||
.sdma_doorbell_range = nbio_v7_0_sdma_doorbell_range,
|
||||
.vcn_doorbell_range = nbio_v7_0_vcn_doorbell_range,
|
||||
.enable_doorbell_aperture = nbio_v7_0_enable_doorbell_aperture,
|
||||
.enable_doorbell_selfring_aperture = nbio_v7_0_enable_doorbell_selfring_aperture,
|
||||
.ih_doorbell_range = nbio_v7_0_ih_doorbell_range,
|
||||
|
@@ -576,7 +576,6 @@ static const struct amdgpu_asic_funcs nv_asic_funcs =
|
||||
|
||||
static int nv_common_early_init(void *handle)
|
||||
{
|
||||
bool psp_enabled = false;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
adev->smc_rreg = NULL;
|
||||
@@ -593,10 +592,6 @@ static int nv_common_early_init(void *handle)
|
||||
|
||||
adev->asic_funcs = &nv_asic_funcs;
|
||||
|
||||
if (amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_PSP) &&
|
||||
(amdgpu_ip_block_mask & (1 << AMD_IP_BLOCK_TYPE_PSP)))
|
||||
psp_enabled = true;
|
||||
|
||||
adev->rev_id = nv_get_rev_id(adev);
|
||||
adev->external_rev_id = 0xff;
|
||||
switch (adev->asic_type) {
|
||||
@@ -617,7 +612,6 @@ static int nv_common_early_init(void *handle)
|
||||
AMD_CG_SUPPORT_BIF_LS;
|
||||
adev->pg_flags = AMD_PG_SUPPORT_VCN |
|
||||
AMD_PG_SUPPORT_VCN_DPG |
|
||||
AMD_PG_SUPPORT_MMHUB |
|
||||
AMD_PG_SUPPORT_ATHUB;
|
||||
adev->external_rev_id = adev->rev_id + 0x1;
|
||||
break;
|
||||
@@ -641,7 +635,21 @@ static int nv_common_early_init(void *handle)
|
||||
adev->external_rev_id = adev->rev_id + 20;
|
||||
break;
|
||||
case CHIP_NAVI12:
|
||||
adev->cg_flags = 0;
|
||||
adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
|
||||
AMD_CG_SUPPORT_GFX_MGLS |
|
||||
AMD_CG_SUPPORT_GFX_CGCG |
|
||||
AMD_CG_SUPPORT_GFX_CP_LS |
|
||||
AMD_CG_SUPPORT_GFX_RLC_LS |
|
||||
AMD_CG_SUPPORT_IH_CG |
|
||||
AMD_CG_SUPPORT_HDP_MGCG |
|
||||
AMD_CG_SUPPORT_HDP_LS |
|
||||
AMD_CG_SUPPORT_SDMA_MGCG |
|
||||
AMD_CG_SUPPORT_SDMA_LS |
|
||||
AMD_CG_SUPPORT_MC_MGCG |
|
||||
AMD_CG_SUPPORT_MC_LS |
|
||||
AMD_CG_SUPPORT_ATHUB_MGCG |
|
||||
AMD_CG_SUPPORT_ATHUB_LS |
|
||||
AMD_CG_SUPPORT_VCN_MGCG;
|
||||
adev->pg_flags = AMD_PG_SUPPORT_VCN_DPG;
|
||||
adev->external_rev_id = adev->rev_id + 0xa;
|
||||
break;
|
||||
|
@@ -190,7 +190,6 @@ static int psp_v10_0_ring_destroy(struct psp_context *psp,
|
||||
}
|
||||
|
||||
static int psp_v10_0_cmd_submit(struct psp_context *psp,
|
||||
struct amdgpu_firmware_info *ucode,
|
||||
uint64_t cmd_buf_mc_addr, uint64_t fence_mc_addr,
|
||||
int index)
|
||||
{
|
||||
|
@@ -498,7 +498,6 @@ static int psp_v11_0_ring_destroy(struct psp_context *psp,
|
||||
}
|
||||
|
||||
static int psp_v11_0_cmd_submit(struct psp_context *psp,
|
||||
struct amdgpu_firmware_info *ucode,
|
||||
uint64_t cmd_buf_mc_addr, uint64_t fence_mc_addr,
|
||||
int index)
|
||||
{
|
||||
|
565
drivers/gpu/drm/amd/amdgpu/psp_v12_0.c
Normal file
565
drivers/gpu/drm/amd/amdgpu/psp_v12_0.c
Normal file
@@ -0,0 +1,565 @@
|
||||
/*
|
||||
* Copyright 2019 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/module.h>
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_psp.h"
|
||||
#include "amdgpu_ucode.h"
|
||||
#include "soc15_common.h"
|
||||
#include "psp_v12_0.h"
|
||||
|
||||
#include "mp/mp_12_0_0_offset.h"
|
||||
#include "mp/mp_12_0_0_sh_mask.h"
|
||||
#include "gc/gc_9_0_offset.h"
|
||||
#include "sdma0/sdma0_4_0_offset.h"
|
||||
#include "nbio/nbio_7_4_offset.h"
|
||||
|
||||
#include "oss/osssys_4_0_offset.h"
|
||||
#include "oss/osssys_4_0_sh_mask.h"
|
||||
|
||||
MODULE_FIRMWARE("amdgpu/renoir_asd.bin");
|
||||
/* address block */
|
||||
#define smnMP1_FIRMWARE_FLAGS 0x3010024
|
||||
|
||||
static int psp_v12_0_init_microcode(struct psp_context *psp)
|
||||
{
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
const char *chip_name;
|
||||
char fw_name[30];
|
||||
int err = 0;
|
||||
const struct psp_firmware_header_v1_0 *asd_hdr;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_RENOIR:
|
||||
chip_name = "renoir";
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_asd.bin", chip_name);
|
||||
err = request_firmware(&adev->psp.asd_fw, fw_name, adev->dev);
|
||||
if (err)
|
||||
goto out1;
|
||||
|
||||
err = amdgpu_ucode_validate(adev->psp.asd_fw);
|
||||
if (err)
|
||||
goto out1;
|
||||
|
||||
asd_hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.asd_fw->data;
|
||||
adev->psp.asd_fw_version = le32_to_cpu(asd_hdr->header.ucode_version);
|
||||
adev->psp.asd_feature_version = le32_to_cpu(asd_hdr->ucode_feature_version);
|
||||
adev->psp.asd_ucode_size = le32_to_cpu(asd_hdr->header.ucode_size_bytes);
|
||||
adev->psp.asd_start_addr = (uint8_t *)asd_hdr +
|
||||
le32_to_cpu(asd_hdr->header.ucode_array_offset_bytes);
|
||||
|
||||
return 0;
|
||||
|
||||
out1:
|
||||
release_firmware(adev->psp.asd_fw);
|
||||
adev->psp.asd_fw = NULL;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int psp_v12_0_bootloader_load_sysdrv(struct psp_context *psp)
|
||||
{
|
||||
int ret;
|
||||
uint32_t psp_gfxdrv_command_reg = 0;
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
uint32_t sol_reg;
|
||||
|
||||
/* Check sOS sign of life register to confirm sys driver and sOS
|
||||
* are already been loaded.
|
||||
*/
|
||||
sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
|
||||
if (sol_reg) {
|
||||
psp->sos_fw_version = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_58);
|
||||
printk("sos fw version = 0x%x.\n", psp->sos_fw_version);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Wait for bootloader to signify that is ready having bit 31 of C2PMSG_35 set to 1 */
|
||||
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_35),
|
||||
0x80000000, 0x80000000, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
memset(psp->fw_pri_buf, 0, PSP_1_MEG);
|
||||
|
||||
/* Copy PSP System Driver binary to memory */
|
||||
memcpy(psp->fw_pri_buf, psp->sys_start_addr, psp->sys_bin_size);
|
||||
|
||||
/* Provide the sys driver to bootloader */
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36,
|
||||
(uint32_t)(psp->fw_pri_mc_addr >> 20));
|
||||
psp_gfxdrv_command_reg = 1 << 16;
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_35,
|
||||
psp_gfxdrv_command_reg);
|
||||
|
||||
/* there might be handshake issue with hardware which needs delay */
|
||||
mdelay(20);
|
||||
|
||||
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_35),
|
||||
0x80000000, 0x80000000, false);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int psp_v12_0_bootloader_load_sos(struct psp_context *psp)
|
||||
{
|
||||
int ret;
|
||||
unsigned int psp_gfxdrv_command_reg = 0;
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
uint32_t sol_reg;
|
||||
|
||||
/* Check sOS sign of life register to confirm sys driver and sOS
|
||||
* are already been loaded.
|
||||
*/
|
||||
sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
|
||||
if (sol_reg)
|
||||
return 0;
|
||||
|
||||
/* Wait for bootloader to signify that is ready having bit 31 of C2PMSG_35 set to 1 */
|
||||
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_35),
|
||||
0x80000000, 0x80000000, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
memset(psp->fw_pri_buf, 0, PSP_1_MEG);
|
||||
|
||||
/* Copy Secure OS binary to PSP memory */
|
||||
memcpy(psp->fw_pri_buf, psp->sos_start_addr, psp->sos_bin_size);
|
||||
|
||||
/* Provide the PSP secure OS to bootloader */
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36,
|
||||
(uint32_t)(psp->fw_pri_mc_addr >> 20));
|
||||
psp_gfxdrv_command_reg = 2 << 16;
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_35,
|
||||
psp_gfxdrv_command_reg);
|
||||
|
||||
/* there might be handshake issue with hardware which needs delay */
|
||||
mdelay(20);
|
||||
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_81),
|
||||
RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81),
|
||||
0, true);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void psp_v12_0_reroute_ih(struct psp_context *psp)
|
||||
{
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
uint32_t tmp;
|
||||
|
||||
/* Change IH ring for VMC */
|
||||
tmp = REG_SET_FIELD(0, IH_CLIENT_CFG_DATA, CREDIT_RETURN_ADDR, 0x1244b);
|
||||
tmp = REG_SET_FIELD(tmp, IH_CLIENT_CFG_DATA, CLIENT_TYPE, 1);
|
||||
tmp = REG_SET_FIELD(tmp, IH_CLIENT_CFG_DATA, RING_ID, 1);
|
||||
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_69, 3);
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_70, tmp);
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64, GFX_CTRL_CMD_ID_GBR_IH_SET);
|
||||
|
||||
mdelay(20);
|
||||
psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64),
|
||||
0x80000000, 0x8000FFFF, false);
|
||||
|
||||
/* Change IH ring for UMC */
|
||||
tmp = REG_SET_FIELD(0, IH_CLIENT_CFG_DATA, CREDIT_RETURN_ADDR, 0x1216b);
|
||||
tmp = REG_SET_FIELD(tmp, IH_CLIENT_CFG_DATA, RING_ID, 1);
|
||||
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_69, 4);
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_70, tmp);
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64, GFX_CTRL_CMD_ID_GBR_IH_SET);
|
||||
|
||||
mdelay(20);
|
||||
psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64),
|
||||
0x80000000, 0x8000FFFF, false);
|
||||
}
|
||||
|
||||
static int psp_v12_0_ring_init(struct psp_context *psp,
|
||||
enum psp_ring_type ring_type)
|
||||
{
|
||||
int ret = 0;
|
||||
struct psp_ring *ring;
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
|
||||
psp_v12_0_reroute_ih(psp);
|
||||
|
||||
ring = &psp->km_ring;
|
||||
|
||||
ring->ring_type = ring_type;
|
||||
|
||||
/* allocate 4k Page of Local Frame Buffer memory for ring */
|
||||
ring->ring_size = 0x1000;
|
||||
ret = amdgpu_bo_create_kernel(adev, ring->ring_size, PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
&adev->firmware.rbuf,
|
||||
&ring->ring_mem_mc_addr,
|
||||
(void **)&ring->ring_mem);
|
||||
if (ret) {
|
||||
ring->ring_size = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool psp_v12_0_support_vmr_ring(struct psp_context *psp)
|
||||
{
|
||||
if (amdgpu_sriov_vf(psp->adev) && psp->sos_fw_version > 0x80045)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static int psp_v12_0_ring_create(struct psp_context *psp,
|
||||
enum psp_ring_type ring_type)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int psp_ring_reg = 0;
|
||||
struct psp_ring *ring = &psp->km_ring;
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
|
||||
if (psp_v12_0_support_vmr_ring(psp)) {
|
||||
/* Write low address of the ring to C2PMSG_102 */
|
||||
psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr);
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102, psp_ring_reg);
|
||||
/* Write high address of the ring to C2PMSG_103 */
|
||||
psp_ring_reg = upper_32_bits(ring->ring_mem_mc_addr);
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_103, psp_ring_reg);
|
||||
|
||||
/* Write the ring initialization command to C2PMSG_101 */
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101,
|
||||
GFX_CTRL_CMD_ID_INIT_GPCOM_RING);
|
||||
|
||||
/* there might be handshake issue with hardware which needs delay */
|
||||
mdelay(20);
|
||||
|
||||
/* Wait for response flag (bit 31) in C2PMSG_101 */
|
||||
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_101),
|
||||
0x80000000, 0x8000FFFF, false);
|
||||
|
||||
} else {
|
||||
/* Write low address of the ring to C2PMSG_69 */
|
||||
psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr);
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_69, psp_ring_reg);
|
||||
/* Write high address of the ring to C2PMSG_70 */
|
||||
psp_ring_reg = upper_32_bits(ring->ring_mem_mc_addr);
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_70, psp_ring_reg);
|
||||
/* Write size of ring to C2PMSG_71 */
|
||||
psp_ring_reg = ring->ring_size;
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_71, psp_ring_reg);
|
||||
/* Write the ring initialization command to C2PMSG_64 */
|
||||
psp_ring_reg = ring_type;
|
||||
psp_ring_reg = psp_ring_reg << 16;
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64, psp_ring_reg);
|
||||
|
||||
/* there might be handshake issue with hardware which needs delay */
|
||||
mdelay(20);
|
||||
|
||||
/* Wait for response flag (bit 31) in C2PMSG_64 */
|
||||
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64),
|
||||
0x80000000, 0x8000FFFF, false);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int psp_v12_0_ring_stop(struct psp_context *psp,
|
||||
enum psp_ring_type ring_type)
|
||||
{
|
||||
int ret = 0;
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
|
||||
/* Write the ring destroy command*/
|
||||
if (psp_v12_0_support_vmr_ring(psp))
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101,
|
||||
GFX_CTRL_CMD_ID_DESTROY_GPCOM_RING);
|
||||
else
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64,
|
||||
GFX_CTRL_CMD_ID_DESTROY_RINGS);
|
||||
|
||||
/* there might be handshake issue with hardware which needs delay */
|
||||
mdelay(20);
|
||||
|
||||
/* Wait for response flag (bit 31) */
|
||||
if (psp_v12_0_support_vmr_ring(psp))
|
||||
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_101),
|
||||
0x80000000, 0x80000000, false);
|
||||
else
|
||||
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64),
|
||||
0x80000000, 0x80000000, false);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int psp_v12_0_ring_destroy(struct psp_context *psp,
|
||||
enum psp_ring_type ring_type)
|
||||
{
|
||||
int ret = 0;
|
||||
struct psp_ring *ring = &psp->km_ring;
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
|
||||
ret = psp_v12_0_ring_stop(psp, ring_type);
|
||||
if (ret)
|
||||
DRM_ERROR("Fail to stop psp ring\n");
|
||||
|
||||
amdgpu_bo_free_kernel(&adev->firmware.rbuf,
|
||||
&ring->ring_mem_mc_addr,
|
||||
(void **)&ring->ring_mem);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int psp_v12_0_cmd_submit(struct psp_context *psp,
|
||||
uint64_t cmd_buf_mc_addr, uint64_t fence_mc_addr,
|
||||
int index)
|
||||
{
|
||||
unsigned int psp_write_ptr_reg = 0;
|
||||
struct psp_gfx_rb_frame *write_frame = psp->km_ring.ring_mem;
|
||||
struct psp_ring *ring = &psp->km_ring;
|
||||
struct psp_gfx_rb_frame *ring_buffer_start = ring->ring_mem;
|
||||
struct psp_gfx_rb_frame *ring_buffer_end = ring_buffer_start +
|
||||
ring->ring_size / sizeof(struct psp_gfx_rb_frame) - 1;
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
uint32_t ring_size_dw = ring->ring_size / 4;
|
||||
uint32_t rb_frame_size_dw = sizeof(struct psp_gfx_rb_frame) / 4;
|
||||
|
||||
/* KM (GPCOM) prepare write pointer */
|
||||
if (psp_v12_0_support_vmr_ring(psp))
|
||||
psp_write_ptr_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102);
|
||||
else
|
||||
psp_write_ptr_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67);
|
||||
|
||||
/* Update KM RB frame pointer to new frame */
|
||||
/* write_frame ptr increments by size of rb_frame in bytes */
|
||||
/* psp_write_ptr_reg increments by size of rb_frame in DWORDs */
|
||||
if ((psp_write_ptr_reg % ring_size_dw) == 0)
|
||||
write_frame = ring_buffer_start;
|
||||
else
|
||||
write_frame = ring_buffer_start + (psp_write_ptr_reg / rb_frame_size_dw);
|
||||
/* Check invalid write_frame ptr address */
|
||||
if ((write_frame < ring_buffer_start) || (ring_buffer_end < write_frame)) {
|
||||
DRM_ERROR("ring_buffer_start = %p; ring_buffer_end = %p; write_frame = %p\n",
|
||||
ring_buffer_start, ring_buffer_end, write_frame);
|
||||
DRM_ERROR("write_frame is pointing to address out of bounds\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Initialize KM RB frame */
|
||||
memset(write_frame, 0, sizeof(struct psp_gfx_rb_frame));
|
||||
|
||||
/* Update KM RB frame */
|
||||
write_frame->cmd_buf_addr_hi = upper_32_bits(cmd_buf_mc_addr);
|
||||
write_frame->cmd_buf_addr_lo = lower_32_bits(cmd_buf_mc_addr);
|
||||
write_frame->fence_addr_hi = upper_32_bits(fence_mc_addr);
|
||||
write_frame->fence_addr_lo = lower_32_bits(fence_mc_addr);
|
||||
write_frame->fence_value = index;
|
||||
|
||||
/* Update the write Pointer in DWORDs */
|
||||
psp_write_ptr_reg = (psp_write_ptr_reg + rb_frame_size_dw) % ring_size_dw;
|
||||
if (psp_v12_0_support_vmr_ring(psp)) {
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102, psp_write_ptr_reg);
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101, GFX_CTRL_CMD_ID_CONSUME_CMD);
|
||||
} else
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67, psp_write_ptr_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
psp_v12_0_sram_map(struct amdgpu_device *adev,
|
||||
unsigned int *sram_offset, unsigned int *sram_addr_reg_offset,
|
||||
unsigned int *sram_data_reg_offset,
|
||||
enum AMDGPU_UCODE_ID ucode_id)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
switch (ucode_id) {
|
||||
/* TODO: needs to confirm */
|
||||
#if 0
|
||||
case AMDGPU_UCODE_ID_SMC:
|
||||
*sram_offset = 0;
|
||||
*sram_addr_reg_offset = 0;
|
||||
*sram_data_reg_offset = 0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case AMDGPU_UCODE_ID_CP_CE:
|
||||
*sram_offset = 0x0;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_CE_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_CE_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_CP_PFP:
|
||||
*sram_offset = 0x0;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_PFP_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_PFP_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_CP_ME:
|
||||
*sram_offset = 0x0;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_HYP_ME_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_HYP_ME_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_CP_MEC1:
|
||||
*sram_offset = 0x10000;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_MEC_ME1_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_MEC_ME1_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_CP_MEC2:
|
||||
*sram_offset = 0x10000;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_HYP_MEC2_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_HYP_MEC2_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_RLC_G:
|
||||
*sram_offset = 0x2000;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmRLC_GPM_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmRLC_GPM_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_SDMA0:
|
||||
*sram_offset = 0x0;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_UCODE_DATA);
|
||||
break;
|
||||
|
||||
/* TODO: needs to confirm */
|
||||
#if 0
|
||||
case AMDGPU_UCODE_ID_SDMA1:
|
||||
*sram_offset = ;
|
||||
*sram_addr_reg_offset = ;
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_UVD:
|
||||
*sram_offset = ;
|
||||
*sram_addr_reg_offset = ;
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_VCE:
|
||||
*sram_offset = ;
|
||||
*sram_addr_reg_offset = ;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case AMDGPU_UCODE_ID_MAXIMUM:
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool psp_v12_0_compare_sram_data(struct psp_context *psp,
|
||||
struct amdgpu_firmware_info *ucode,
|
||||
enum AMDGPU_UCODE_ID ucode_type)
|
||||
{
|
||||
int err = 0;
|
||||
unsigned int fw_sram_reg_val = 0;
|
||||
unsigned int fw_sram_addr_reg_offset = 0;
|
||||
unsigned int fw_sram_data_reg_offset = 0;
|
||||
unsigned int ucode_size;
|
||||
uint32_t *ucode_mem = NULL;
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
|
||||
err = psp_v12_0_sram_map(adev, &fw_sram_reg_val, &fw_sram_addr_reg_offset,
|
||||
&fw_sram_data_reg_offset, ucode_type);
|
||||
if (err)
|
||||
return false;
|
||||
|
||||
WREG32(fw_sram_addr_reg_offset, fw_sram_reg_val);
|
||||
|
||||
ucode_size = ucode->ucode_size;
|
||||
ucode_mem = (uint32_t *)ucode->kaddr;
|
||||
while (ucode_size) {
|
||||
fw_sram_reg_val = RREG32(fw_sram_data_reg_offset);
|
||||
|
||||
if (*ucode_mem != fw_sram_reg_val)
|
||||
return false;
|
||||
|
||||
ucode_mem++;
|
||||
/* 4 bytes */
|
||||
ucode_size -= 4;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int psp_v12_0_mode1_reset(struct psp_context *psp)
|
||||
{
|
||||
int ret;
|
||||
uint32_t offset;
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
|
||||
offset = SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64);
|
||||
|
||||
ret = psp_wait_for(psp, offset, 0x80000000, 0x8000FFFF, false);
|
||||
|
||||
if (ret) {
|
||||
DRM_INFO("psp is not working correctly before mode1 reset!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*send the mode 1 reset command*/
|
||||
WREG32(offset, GFX_CTRL_CMD_ID_MODE1_RST);
|
||||
|
||||
msleep(500);
|
||||
|
||||
offset = SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_33);
|
||||
|
||||
ret = psp_wait_for(psp, offset, 0x80000000, 0x80000000, false);
|
||||
|
||||
if (ret) {
|
||||
DRM_INFO("psp mode 1 reset failed!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DRM_INFO("psp mode1 reset succeed \n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct psp_funcs psp_v12_0_funcs = {
|
||||
.init_microcode = psp_v12_0_init_microcode,
|
||||
.bootloader_load_sysdrv = psp_v12_0_bootloader_load_sysdrv,
|
||||
.bootloader_load_sos = psp_v12_0_bootloader_load_sos,
|
||||
.ring_init = psp_v12_0_ring_init,
|
||||
.ring_create = psp_v12_0_ring_create,
|
||||
.ring_stop = psp_v12_0_ring_stop,
|
||||
.ring_destroy = psp_v12_0_ring_destroy,
|
||||
.cmd_submit = psp_v12_0_cmd_submit,
|
||||
.compare_sram_data = psp_v12_0_compare_sram_data,
|
||||
.mode1_reset = psp_v12_0_mode1_reset,
|
||||
};
|
||||
|
||||
void psp_v12_0_set_psp_funcs(struct psp_context *psp)
|
||||
{
|
||||
psp->funcs = &psp_v12_0_funcs;
|
||||
}
|
30
drivers/gpu/drm/amd/amdgpu/psp_v12_0.h
Normal file
30
drivers/gpu/drm/amd/amdgpu/psp_v12_0.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2019 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef __PSP_V12_0_H__
|
||||
#define __PSP_V12_0_H__
|
||||
|
||||
#include "amdgpu_psp.h"
|
||||
|
||||
void psp_v12_0_set_psp_funcs(struct psp_context *psp);
|
||||
|
||||
#endif
|
@@ -411,7 +411,6 @@ static int psp_v3_1_ring_destroy(struct psp_context *psp,
|
||||
}
|
||||
|
||||
static int psp_v3_1_cmd_submit(struct psp_context *psp,
|
||||
struct amdgpu_firmware_info *ucode,
|
||||
uint64_t cmd_buf_mc_addr, uint64_t fence_mc_addr,
|
||||
int index)
|
||||
{
|
||||
|
@@ -68,6 +68,7 @@ MODULE_FIRMWARE("amdgpu/raven_sdma.bin");
|
||||
MODULE_FIRMWARE("amdgpu/picasso_sdma.bin");
|
||||
MODULE_FIRMWARE("amdgpu/raven2_sdma.bin");
|
||||
MODULE_FIRMWARE("amdgpu/arcturus_sdma.bin");
|
||||
MODULE_FIRMWARE("amdgpu/renoir_sdma.bin");
|
||||
|
||||
#define SDMA0_POWER_CNTL__ON_OFF_CONDITION_HOLD_TIME_MASK 0x000000F8L
|
||||
#define SDMA0_POWER_CNTL__ON_OFF_STATUS_DURATION_TIME_MASK 0xFC000000L
|
||||
@@ -243,6 +244,18 @@ static const struct soc15_reg_golden golden_settings_sdma_arct[] =
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA7, 0, mmSDMA7_GB_ADDR_CONFIG_READ, 0x0000773f, 0x00004002)
|
||||
};
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_sdma_4_3[] = {
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_CHICKEN_BITS, 0xfe931f07, 0x02831f07),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_CLK_CTRL, 0xffffffff, 0x3f000100),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_GB_ADDR_CONFIG, 0x0018773f, 0x00000002),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_GB_ADDR_CONFIG_READ, 0x0018773f, 0x00000002),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_GFX_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_POWER_CNTL, 0x003fff07, 0x40000051),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC0_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC1_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0),
|
||||
};
|
||||
|
||||
static u32 sdma_v4_0_get_reg_offset(struct amdgpu_device *adev,
|
||||
u32 instance, u32 offset)
|
||||
{
|
||||
@@ -367,6 +380,11 @@ static void sdma_v4_0_init_golden_registers(struct amdgpu_device *adev)
|
||||
golden_settings_sdma_rv1,
|
||||
ARRAY_SIZE(golden_settings_sdma_rv1));
|
||||
break;
|
||||
case CHIP_RENOIR:
|
||||
soc15_program_register_sequence(adev,
|
||||
golden_settings_sdma_4_3,
|
||||
ARRAY_SIZE(golden_settings_sdma_4_3));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -452,6 +470,9 @@ static int sdma_v4_0_init_microcode(struct amdgpu_device *adev)
|
||||
case CHIP_ARCTURUS:
|
||||
chip_name = "arcturus";
|
||||
break;
|
||||
case CHIP_RENOIR:
|
||||
chip_name = "renoir";
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
@@ -1640,7 +1661,7 @@ static int sdma_v4_0_early_init(void *handle)
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int r;
|
||||
|
||||
if (adev->asic_type == CHIP_RAVEN)
|
||||
if (adev->asic_type == CHIP_RAVEN || adev->asic_type == CHIP_RENOIR)
|
||||
adev->sdma.num_instances = 1;
|
||||
else if (adev->asic_type == CHIP_ARCTURUS)
|
||||
adev->sdma.num_instances = 8;
|
||||
@@ -2086,61 +2107,35 @@ static void sdma_v4_0_update_medium_grain_clock_gating(
|
||||
bool enable)
|
||||
{
|
||||
uint32_t data, def;
|
||||
int i;
|
||||
|
||||
if (enable && (adev->cg_flags & AMD_CG_SUPPORT_SDMA_MGCG)) {
|
||||
/* enable sdma0 clock gating */
|
||||
def = data = RREG32(SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_CLK_CTRL));
|
||||
data &= ~(SDMA0_CLK_CTRL__SOFT_OVERRIDE7_MASK |
|
||||
SDMA0_CLK_CTRL__SOFT_OVERRIDE6_MASK |
|
||||
SDMA0_CLK_CTRL__SOFT_OVERRIDE5_MASK |
|
||||
SDMA0_CLK_CTRL__SOFT_OVERRIDE4_MASK |
|
||||
SDMA0_CLK_CTRL__SOFT_OVERRIDE3_MASK |
|
||||
SDMA0_CLK_CTRL__SOFT_OVERRIDE2_MASK |
|
||||
SDMA0_CLK_CTRL__SOFT_OVERRIDE1_MASK |
|
||||
SDMA0_CLK_CTRL__SOFT_OVERRIDE0_MASK);
|
||||
if (def != data)
|
||||
WREG32(SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_CLK_CTRL), data);
|
||||
|
||||
if (adev->sdma.num_instances > 1) {
|
||||
def = data = RREG32(SOC15_REG_OFFSET(SDMA1, 0, mmSDMA1_CLK_CTRL));
|
||||
data &= ~(SDMA1_CLK_CTRL__SOFT_OVERRIDE7_MASK |
|
||||
SDMA1_CLK_CTRL__SOFT_OVERRIDE6_MASK |
|
||||
SDMA1_CLK_CTRL__SOFT_OVERRIDE5_MASK |
|
||||
SDMA1_CLK_CTRL__SOFT_OVERRIDE4_MASK |
|
||||
SDMA1_CLK_CTRL__SOFT_OVERRIDE3_MASK |
|
||||
SDMA1_CLK_CTRL__SOFT_OVERRIDE2_MASK |
|
||||
SDMA1_CLK_CTRL__SOFT_OVERRIDE1_MASK |
|
||||
SDMA1_CLK_CTRL__SOFT_OVERRIDE0_MASK);
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
def = data = RREG32_SDMA(i, mmSDMA0_CLK_CTRL);
|
||||
data &= ~(SDMA0_CLK_CTRL__SOFT_OVERRIDE7_MASK |
|
||||
SDMA0_CLK_CTRL__SOFT_OVERRIDE6_MASK |
|
||||
SDMA0_CLK_CTRL__SOFT_OVERRIDE5_MASK |
|
||||
SDMA0_CLK_CTRL__SOFT_OVERRIDE4_MASK |
|
||||
SDMA0_CLK_CTRL__SOFT_OVERRIDE3_MASK |
|
||||
SDMA0_CLK_CTRL__SOFT_OVERRIDE2_MASK |
|
||||
SDMA0_CLK_CTRL__SOFT_OVERRIDE1_MASK |
|
||||
SDMA0_CLK_CTRL__SOFT_OVERRIDE0_MASK);
|
||||
if (def != data)
|
||||
WREG32(SOC15_REG_OFFSET(SDMA1, 0, mmSDMA1_CLK_CTRL), data);
|
||||
WREG32_SDMA(i, mmSDMA0_CLK_CTRL, data);
|
||||
}
|
||||
} else {
|
||||
/* disable sdma0 clock gating */
|
||||
def = data = RREG32(SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_CLK_CTRL));
|
||||
data |= (SDMA0_CLK_CTRL__SOFT_OVERRIDE7_MASK |
|
||||
SDMA0_CLK_CTRL__SOFT_OVERRIDE6_MASK |
|
||||
SDMA0_CLK_CTRL__SOFT_OVERRIDE5_MASK |
|
||||
SDMA0_CLK_CTRL__SOFT_OVERRIDE4_MASK |
|
||||
SDMA0_CLK_CTRL__SOFT_OVERRIDE3_MASK |
|
||||
SDMA0_CLK_CTRL__SOFT_OVERRIDE2_MASK |
|
||||
SDMA0_CLK_CTRL__SOFT_OVERRIDE1_MASK |
|
||||
SDMA0_CLK_CTRL__SOFT_OVERRIDE0_MASK);
|
||||
|
||||
if (def != data)
|
||||
WREG32(SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_CLK_CTRL), data);
|
||||
|
||||
if (adev->sdma.num_instances > 1) {
|
||||
def = data = RREG32(SOC15_REG_OFFSET(SDMA1, 0, mmSDMA1_CLK_CTRL));
|
||||
data |= (SDMA1_CLK_CTRL__SOFT_OVERRIDE7_MASK |
|
||||
SDMA1_CLK_CTRL__SOFT_OVERRIDE6_MASK |
|
||||
SDMA1_CLK_CTRL__SOFT_OVERRIDE5_MASK |
|
||||
SDMA1_CLK_CTRL__SOFT_OVERRIDE4_MASK |
|
||||
SDMA1_CLK_CTRL__SOFT_OVERRIDE3_MASK |
|
||||
SDMA1_CLK_CTRL__SOFT_OVERRIDE2_MASK |
|
||||
SDMA1_CLK_CTRL__SOFT_OVERRIDE1_MASK |
|
||||
SDMA1_CLK_CTRL__SOFT_OVERRIDE0_MASK);
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
def = data = RREG32_SDMA(i, mmSDMA0_CLK_CTRL);
|
||||
data |= (SDMA0_CLK_CTRL__SOFT_OVERRIDE7_MASK |
|
||||
SDMA0_CLK_CTRL__SOFT_OVERRIDE6_MASK |
|
||||
SDMA0_CLK_CTRL__SOFT_OVERRIDE5_MASK |
|
||||
SDMA0_CLK_CTRL__SOFT_OVERRIDE4_MASK |
|
||||
SDMA0_CLK_CTRL__SOFT_OVERRIDE3_MASK |
|
||||
SDMA0_CLK_CTRL__SOFT_OVERRIDE2_MASK |
|
||||
SDMA0_CLK_CTRL__SOFT_OVERRIDE1_MASK |
|
||||
SDMA0_CLK_CTRL__SOFT_OVERRIDE0_MASK);
|
||||
if (def != data)
|
||||
WREG32(SOC15_REG_OFFSET(SDMA1, 0, mmSDMA1_CLK_CTRL), data);
|
||||
WREG32_SDMA(i, mmSDMA0_CLK_CTRL, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2151,34 +2146,23 @@ static void sdma_v4_0_update_medium_grain_light_sleep(
|
||||
bool enable)
|
||||
{
|
||||
uint32_t data, def;
|
||||
int i;
|
||||
|
||||
if (enable && (adev->cg_flags & AMD_CG_SUPPORT_SDMA_LS)) {
|
||||
/* 1-not override: enable sdma0 mem light sleep */
|
||||
def = data = RREG32(SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_POWER_CNTL));
|
||||
data |= SDMA0_POWER_CNTL__MEM_POWER_OVERRIDE_MASK;
|
||||
if (def != data)
|
||||
WREG32(SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_POWER_CNTL), data);
|
||||
|
||||
/* 1-not override: enable sdma1 mem light sleep */
|
||||
if (adev->sdma.num_instances > 1) {
|
||||
def = data = RREG32(SOC15_REG_OFFSET(SDMA1, 0, mmSDMA1_POWER_CNTL));
|
||||
data |= SDMA1_POWER_CNTL__MEM_POWER_OVERRIDE_MASK;
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
/* 1-not override: enable sdma mem light sleep */
|
||||
def = data = RREG32_SDMA(0, mmSDMA0_POWER_CNTL);
|
||||
data |= SDMA0_POWER_CNTL__MEM_POWER_OVERRIDE_MASK;
|
||||
if (def != data)
|
||||
WREG32(SOC15_REG_OFFSET(SDMA1, 0, mmSDMA1_POWER_CNTL), data);
|
||||
WREG32_SDMA(0, mmSDMA0_POWER_CNTL, data);
|
||||
}
|
||||
} else {
|
||||
/* 0-override:disable sdma0 mem light sleep */
|
||||
def = data = RREG32(SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_POWER_CNTL));
|
||||
data &= ~SDMA0_POWER_CNTL__MEM_POWER_OVERRIDE_MASK;
|
||||
if (def != data)
|
||||
WREG32(SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_POWER_CNTL), data);
|
||||
|
||||
/* 0-override:disable sdma1 mem light sleep */
|
||||
if (adev->sdma.num_instances > 1) {
|
||||
def = data = RREG32(SOC15_REG_OFFSET(SDMA1, 0, mmSDMA1_POWER_CNTL));
|
||||
data &= ~SDMA1_POWER_CNTL__MEM_POWER_OVERRIDE_MASK;
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
/* 0-override:disable sdma mem light sleep */
|
||||
def = data = RREG32_SDMA(0, mmSDMA0_POWER_CNTL);
|
||||
data &= ~SDMA0_POWER_CNTL__MEM_POWER_OVERRIDE_MASK;
|
||||
if (def != data)
|
||||
WREG32(SOC15_REG_OFFSET(SDMA1, 0, mmSDMA1_POWER_CNTL), data);
|
||||
WREG32_SDMA(0, mmSDMA0_POWER_CNTL, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2196,6 +2180,8 @@ static int sdma_v4_0_set_clockgating_state(void *handle,
|
||||
case CHIP_VEGA12:
|
||||
case CHIP_VEGA20:
|
||||
case CHIP_RAVEN:
|
||||
case CHIP_ARCTURUS:
|
||||
case CHIP_RENOIR:
|
||||
sdma_v4_0_update_medium_grain_clock_gating(adev,
|
||||
state == AMD_CG_STATE_GATE ? true : false);
|
||||
sdma_v4_0_update_medium_grain_light_sleep(adev,
|
||||
|
@@ -1516,6 +1516,7 @@ static int sdma_v5_0_set_clockgating_state(void *handle,
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_NAVI10:
|
||||
case CHIP_NAVI14:
|
||||
case CHIP_NAVI12:
|
||||
sdma_v5_0_update_medium_grain_clock_gating(adev,
|
||||
state == AMD_CG_STATE_GATE ? true : false);
|
||||
sdma_v5_0_update_medium_grain_light_sleep(adev,
|
||||
@@ -1627,7 +1628,8 @@ static const struct amdgpu_irq_src_funcs sdma_v5_0_illegal_inst_irq_funcs = {
|
||||
|
||||
static void sdma_v5_0_set_irq_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
adev->sdma.trap_irq.num_types = AMDGPU_SDMA_IRQ_LAST;
|
||||
adev->sdma.trap_irq.num_types = AMDGPU_SDMA_IRQ_INSTANCE0 +
|
||||
adev->sdma.num_instances;
|
||||
adev->sdma.trap_irq.funcs = &sdma_v5_0_trap_irq_funcs;
|
||||
adev->sdma.illegal_inst_irq.funcs = &sdma_v5_0_illegal_inst_irq_funcs;
|
||||
}
|
||||
|
@@ -63,6 +63,7 @@
|
||||
#include "uvd_v7_0.h"
|
||||
#include "vce_v4_0.h"
|
||||
#include "vcn_v1_0.h"
|
||||
#include "vcn_v2_0.h"
|
||||
#include "vcn_v2_5.h"
|
||||
#include "dce_virtual.h"
|
||||
#include "mxgpu_ai.h"
|
||||
@@ -508,6 +509,15 @@ static int soc15_asic_baco_reset(struct amdgpu_device *adev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int soc15_mode2_reset(struct amdgpu_device *adev)
|
||||
{
|
||||
if (!adev->powerplay.pp_funcs ||
|
||||
!adev->powerplay.pp_funcs->asic_reset_mode_2)
|
||||
return -ENOENT;
|
||||
|
||||
return adev->powerplay.pp_funcs->asic_reset_mode_2(adev->powerplay.pp_handle);
|
||||
}
|
||||
|
||||
static enum amd_reset_method
|
||||
soc15_asic_reset_method(struct amdgpu_device *adev)
|
||||
{
|
||||
@@ -546,14 +556,14 @@ soc15_asic_reset_method(struct amdgpu_device *adev)
|
||||
|
||||
static int soc15_asic_reset(struct amdgpu_device *adev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (soc15_asic_reset_method(adev) == AMD_RESET_METHOD_BACO)
|
||||
ret = soc15_asic_baco_reset(adev);
|
||||
else
|
||||
ret = soc15_asic_mode1_reset(adev);
|
||||
|
||||
return ret;
|
||||
switch (soc15_asic_reset_method(adev)) {
|
||||
case AMD_RESET_METHOD_BACO:
|
||||
return soc15_asic_baco_reset(adev);
|
||||
case AMD_RESET_METHOD_MODE2:
|
||||
return soc15_mode2_reset(adev);
|
||||
default:
|
||||
return soc15_asic_mode1_reset(adev);
|
||||
}
|
||||
}
|
||||
|
||||
/*static int soc15_set_uvd_clock(struct amdgpu_device *adev, u32 clock,
|
||||
@@ -637,6 +647,7 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
|
||||
case CHIP_VEGA10:
|
||||
case CHIP_VEGA12:
|
||||
case CHIP_RAVEN:
|
||||
case CHIP_RENOIR:
|
||||
vega10_reg_base_init(adev);
|
||||
break;
|
||||
case CHIP_VEGA20:
|
||||
@@ -743,6 +754,20 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v2_5_ip_block);
|
||||
break;
|
||||
case CHIP_RENOIR:
|
||||
amdgpu_device_ip_block_add(adev, &vega10_common_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gmc_v9_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block);
|
||||
if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP))
|
||||
amdgpu_device_ip_block_add(adev, &psp_v12_0_ip_block);
|
||||
if (is_support_sw_smu(adev))
|
||||
amdgpu_device_ip_block_add(adev, &smu_v12_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -1111,18 +1136,54 @@ static int soc15_common_early_init(void *handle)
|
||||
|
||||
adev->pg_flags = AMD_PG_SUPPORT_SDMA | AMD_PG_SUPPORT_VCN;
|
||||
}
|
||||
break;
|
||||
case CHIP_ARCTURUS:
|
||||
adev->asic_funcs = &vega20_asic_funcs;
|
||||
adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
|
||||
AMD_CG_SUPPORT_GFX_MGLS |
|
||||
AMD_CG_SUPPORT_GFX_CGCG |
|
||||
AMD_CG_SUPPORT_GFX_CGLS |
|
||||
AMD_CG_SUPPORT_GFX_CP_LS |
|
||||
AMD_CG_SUPPORT_HDP_MGCG |
|
||||
AMD_CG_SUPPORT_HDP_LS |
|
||||
AMD_CG_SUPPORT_SDMA_MGCG |
|
||||
AMD_CG_SUPPORT_SDMA_LS |
|
||||
AMD_CG_SUPPORT_MC_MGCG |
|
||||
AMD_CG_SUPPORT_MC_LS;
|
||||
adev->pg_flags = 0;
|
||||
adev->external_rev_id = adev->rev_id + 0x32;
|
||||
break;
|
||||
case CHIP_RENOIR:
|
||||
adev->asic_funcs = &soc15_asic_funcs;
|
||||
adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
|
||||
AMD_CG_SUPPORT_GFX_MGLS |
|
||||
AMD_CG_SUPPORT_GFX_3D_CGCG |
|
||||
AMD_CG_SUPPORT_GFX_3D_CGLS |
|
||||
AMD_CG_SUPPORT_GFX_CGCG |
|
||||
AMD_CG_SUPPORT_GFX_CGLS |
|
||||
AMD_CG_SUPPORT_GFX_CP_LS |
|
||||
AMD_CG_SUPPORT_MC_MGCG |
|
||||
AMD_CG_SUPPORT_MC_LS |
|
||||
AMD_CG_SUPPORT_SDMA_MGCG |
|
||||
AMD_CG_SUPPORT_SDMA_LS |
|
||||
AMD_CG_SUPPORT_BIF_LS |
|
||||
AMD_CG_SUPPORT_HDP_LS |
|
||||
AMD_CG_SUPPORT_ROM_MGCG |
|
||||
AMD_CG_SUPPORT_VCN_MGCG |
|
||||
AMD_CG_SUPPORT_IH_CG |
|
||||
AMD_CG_SUPPORT_ATHUB_LS |
|
||||
AMD_CG_SUPPORT_ATHUB_MGCG |
|
||||
AMD_CG_SUPPORT_DF_MGCG;
|
||||
adev->pg_flags = AMD_PG_SUPPORT_SDMA |
|
||||
AMD_PG_SUPPORT_VCN |
|
||||
AMD_PG_SUPPORT_VCN_DPG;
|
||||
adev->external_rev_id = adev->rev_id + 0x91;
|
||||
|
||||
if (adev->pm.pp_feature & PP_GFXOFF_MASK)
|
||||
adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG |
|
||||
AMD_PG_SUPPORT_CP |
|
||||
AMD_PG_SUPPORT_RLC_SMU_HS;
|
||||
break;
|
||||
case CHIP_ARCTURUS:
|
||||
adev->asic_funcs = &vega20_asic_funcs;
|
||||
adev->cg_flags = 0;
|
||||
adev->pg_flags = 0;
|
||||
adev->external_rev_id = adev->rev_id + 0x32;
|
||||
break;
|
||||
default:
|
||||
/* FIXME: not supported yet */
|
||||
return -EINVAL;
|
||||
@@ -1256,7 +1317,8 @@ static void soc15_update_hdp_light_sleep(struct amdgpu_device *adev, bool enable
|
||||
{
|
||||
uint32_t def, data;
|
||||
|
||||
if (adev->asic_type == CHIP_VEGA20) {
|
||||
if (adev->asic_type == CHIP_VEGA20 ||
|
||||
adev->asic_type == CHIP_ARCTURUS) {
|
||||
def = data = RREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_CTRL));
|
||||
|
||||
if (enable && (adev->cg_flags & AMD_CG_SUPPORT_HDP_LS))
|
||||
@@ -1375,6 +1437,7 @@ static int soc15_common_set_clockgating_state(void *handle,
|
||||
state == AMD_CG_STATE_GATE ? true : false);
|
||||
break;
|
||||
case CHIP_RAVEN:
|
||||
case CHIP_RENOIR:
|
||||
adev->nbio_funcs->update_medium_grain_clock_gating(adev,
|
||||
state == AMD_CG_STATE_GATE ? true : false);
|
||||
adev->nbio_funcs->update_medium_grain_light_sleep(adev,
|
||||
@@ -1388,6 +1451,10 @@ static int soc15_common_set_clockgating_state(void *handle,
|
||||
soc15_update_rom_medium_grain_clock_gating(adev,
|
||||
state == AMD_CG_STATE_GATE ? true : false);
|
||||
break;
|
||||
case CHIP_ARCTURUS:
|
||||
soc15_update_hdp_light_sleep(adev,
|
||||
state == AMD_CG_STATE_GATE ? true : false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@@ -247,7 +247,7 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
|
||||
}
|
||||
|
||||
if (adev->asic_type == CHIP_ARCTURUS &&
|
||||
if ((adev->asic_type == CHIP_ARCTURUS || adev->asic_type == CHIP_RENOIR) &&
|
||||
adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) {
|
||||
if (adev->irq.ih.use_bus_addr) {
|
||||
ih_chicken = RREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN);
|
||||
|
@@ -81,6 +81,10 @@ void vega10_doorbell_index_init(struct amdgpu_device *adev)
|
||||
adev->doorbell_index.uvd_vce.vce_ring2_3 = AMDGPU_DOORBELL64_VCE_RING2_3;
|
||||
adev->doorbell_index.uvd_vce.vce_ring4_5 = AMDGPU_DOORBELL64_VCE_RING4_5;
|
||||
adev->doorbell_index.uvd_vce.vce_ring6_7 = AMDGPU_DOORBELL64_VCE_RING6_7;
|
||||
adev->doorbell_index.vcn.vcn_ring0_1 = AMDGPU_DOORBELL64_VCN0_1;
|
||||
adev->doorbell_index.vcn.vcn_ring2_3 = AMDGPU_DOORBELL64_VCN2_3;
|
||||
adev->doorbell_index.vcn.vcn_ring4_5 = AMDGPU_DOORBELL64_VCN4_5;
|
||||
adev->doorbell_index.vcn.vcn_ring6_7 = AMDGPU_DOORBELL64_VCN6_7;
|
||||
|
||||
adev->doorbell_index.first_non_cp = AMDGPU_DOORBELL64_FIRST_NON_CP;
|
||||
adev->doorbell_index.last_non_cp = AMDGPU_DOORBELL64_LAST_NON_CP;
|
||||
|
مرجع در شماره جدید
Block a user