summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c94
1 files changed, 79 insertions, 15 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
index ba2b7ac0c02d..f7e66bf0f647 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
@@ -45,8 +45,10 @@
#include "nbio_v2_3.h"
#include "gfxhub_v2_0.h"
+#include "gfxhub_v2_1.h"
#include "mmhub_v2_0.h"
#include "athub_v2_0.h"
+#include "athub_v2_1.h"
/* XXX Move this macro to navi10 header file, which is like vid.h for VI.*/
#define AMDGPU_NUM_OF_VMIDS 8
@@ -348,6 +350,24 @@ static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
/* flush hdp cache */
adev->nbio.funcs->hdp_flush(adev, NULL);
+ /* For SRIOV run time, driver shouldn't access the register through MMIO
+ * Directly use kiq to do the vm invalidation instead
+ */
+ if (adev->gfx.kiq.ring.sched.ready &&
+ (amdgpu_sriov_runtime(adev) || !amdgpu_sriov_vf(adev)) &&
+ !adev->in_gpu_reset) {
+
+ struct amdgpu_vmhub *hub = &adev->vmhub[vmhub];
+ const unsigned eng = 17;
+ u32 inv_req = gmc_v10_0_get_invalidate_req(vmid, flush_type);
+ u32 req = hub->vm_inv_eng0_req + eng;
+ u32 ack = hub->vm_inv_eng0_ack + eng;
+
+ amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, inv_req,
+ 1 << vmid);
+ return;
+ }
+
mutex_lock(&adev->mman.gtt_window_lock);
if (vmhub == AMDGPU_MMHUB_0) {
@@ -666,13 +686,26 @@ static void gmc_v10_0_vram_gtt_location(struct amdgpu_device *adev,
{
u64 base = 0;
- base = gfxhub_v2_0_get_fb_location(adev);
+ if (adev->asic_type == CHIP_SIENNA_CICHLID)
+ base = gfxhub_v2_1_get_fb_location(adev);
+ else
+ base = gfxhub_v2_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, &adev->gmc, base);
amdgpu_gmc_gart_location(adev, mc);
/* base offset of vram pages */
- adev->vm_manager.vram_base_offset = gfxhub_v2_0_get_mc_fb_offset(adev);
+ if (adev->asic_type == CHIP_SIENNA_CICHLID)
+ adev->vm_manager.vram_base_offset = gfxhub_v2_1_get_mc_fb_offset(adev);
+ else
+ adev->vm_manager.vram_base_offset = gfxhub_v2_0_get_mc_fb_offset(adev);
+
+ /* add the xgmi offset of the physical node */
+ adev->vm_manager.vram_base_offset +=
+ adev->gmc.xgmi.physical_node_id * adev->gmc.xgmi.node_segment_size;
}
/**
@@ -712,6 +745,7 @@ static int gmc_v10_0_mc_init(struct amdgpu_device *adev)
case CHIP_NAVI10:
case CHIP_NAVI14:
case CHIP_NAVI12:
+ case CHIP_SIENNA_CICHLID:
default:
adev->gmc.gart_size = 512ULL << 20;
break;
@@ -780,24 +814,32 @@ static int gmc_v10_0_sw_init(void *handle)
int r, vram_width = 0, vram_type = 0, vram_vendor = 0;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- gfxhub_v2_0_init(adev);
+ if (adev->asic_type == CHIP_SIENNA_CICHLID)
+ gfxhub_v2_1_init(adev);
+ else
+ gfxhub_v2_0_init(adev);
+
mmhub_v2_0_init(adev);
spin_lock_init(&adev->gmc.invalidate_lock);
- r = amdgpu_atomfirmware_get_vram_info(adev,
- &vram_width, &vram_type, &vram_vendor);
- if (!amdgpu_emu_mode)
- adev->gmc.vram_width = vram_width;
- else
+ if (adev->asic_type == CHIP_SIENNA_CICHLID && amdgpu_emu_mode == 1) {
+ adev->gmc.vram_type = AMDGPU_VRAM_TYPE_GDDR6;
adev->gmc.vram_width = 1 * 128; /* numchan * chansize */
+ } else {
+ r = amdgpu_atomfirmware_get_vram_info(adev,
+ &vram_width, &vram_type, &vram_vendor);
+ adev->gmc.vram_width = vram_width;
+
+ adev->gmc.vram_type = vram_type;
+ adev->gmc.vram_vendor = vram_vendor;
+ }
- adev->gmc.vram_type = vram_type;
- adev->gmc.vram_vendor = vram_vendor;
switch (adev->asic_type) {
case CHIP_NAVI10:
case CHIP_NAVI14:
case CHIP_NAVI12:
+ case CHIP_SIENNA_CICHLID:
adev->num_vmhubs = 2;
/*
* To fulfill 4-level page support,
@@ -836,6 +878,12 @@ static int gmc_v10_0_sw_init(void *handle)
return r;
}
+ if (adev->gmc.xgmi.supported) {
+ r = gfxhub_v2_1_get_xgmi_info(adev);
+ if (r)
+ return r;
+ }
+
r = gmc_v10_0_mc_init(adev);
if (r)
return r;
@@ -896,6 +944,7 @@ static void gmc_v10_0_init_golden_registers(struct amdgpu_device *adev)
case CHIP_NAVI10:
case CHIP_NAVI14:
case CHIP_NAVI12:
+ case CHIP_SIENNA_CICHLID:
break;
default:
break;
@@ -922,7 +971,10 @@ static int gmc_v10_0_gart_enable(struct amdgpu_device *adev)
if (r)
return r;
- r = gfxhub_v2_0_gart_enable(adev);
+ if (adev->asic_type == CHIP_SIENNA_CICHLID)
+ r = gfxhub_v2_1_gart_enable(adev);
+ else
+ r = gfxhub_v2_0_gart_enable(adev);
if (r)
return r;
@@ -943,7 +995,10 @@ static int gmc_v10_0_gart_enable(struct amdgpu_device *adev)
value = (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) ?
false : true;
- gfxhub_v2_0_set_fault_enable_default(adev, value);
+ if (adev->asic_type == CHIP_SIENNA_CICHLID)
+ gfxhub_v2_1_set_fault_enable_default(adev, value);
+ else
+ 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, AMDGPU_MMHUB_0, 0);
gmc_v10_0_flush_gpu_tlb(adev, 0, AMDGPU_GFXHUB_0, 0);
@@ -981,7 +1036,10 @@ static int gmc_v10_0_hw_init(void *handle)
*/
static void gmc_v10_0_gart_disable(struct amdgpu_device *adev)
{
- gfxhub_v2_0_gart_disable(adev);
+ if (adev->asic_type == CHIP_SIENNA_CICHLID)
+ gfxhub_v2_1_gart_disable(adev);
+ else
+ gfxhub_v2_0_gart_disable(adev);
mmhub_v2_0_gart_disable(adev);
amdgpu_gart_table_vram_unpin(adev);
}
@@ -1052,7 +1110,10 @@ static int gmc_v10_0_set_clockgating_state(void *handle,
if (r)
return r;
- return athub_v2_0_set_clockgating(adev, state);
+ if (adev->asic_type == CHIP_SIENNA_CICHLID)
+ return athub_v2_1_set_clockgating(adev, state);
+ else
+ return athub_v2_0_set_clockgating(adev, state);
}
static void gmc_v10_0_get_clockgating_state(void *handle, u32 *flags)
@@ -1061,7 +1122,10 @@ static void gmc_v10_0_get_clockgating_state(void *handle, u32 *flags)
mmhub_v2_0_get_clockgating(adev, flags);
- athub_v2_0_get_clockgating(adev, flags);
+ if (adev->asic_type == CHIP_SIENNA_CICHLID)
+ athub_v2_1_get_clockgating(adev, flags);
+ else
+ athub_v2_0_get_clockgating(adev, flags);
}
static int gmc_v10_0_set_powergating_state(void *handle,