diff options
author | Xiangliang Yu <Xiangliang.Yu@amd.com> | 2017-01-12 01:29:34 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2017-01-27 11:13:23 -0500 |
commit | bc992ba5a3c19c79873fab46f17dcb20a9b84a85 (patch) | |
tree | 23cf12855d672c087c867748c68fb69db7fcf551 /drivers/gpu/drm/amd/amdgpu | |
parent | 5ec9f06e105dabaaa6b7b9f3b230ddff39b6837f (diff) |
drm/amdgpu/virt: use kiq to access registers (v2)
For virtualization, it is must for driver to use KIQ to access
registers when it is out of GPU full access mode.
v2: agd: rebase
Signed-off-by: Xiangliang Yu <Xiangliang.Yu@amd.com>
Signed-off-by: Monk Liu <Monk.Liu@amd.com>
Reviewed-by: Monk Liu <Monk.Liu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 58 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/vi.c | 3 |
4 files changed, 75 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 121b8440cf40..6eabeaaa3c30 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |||
@@ -94,6 +94,11 @@ uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg, | |||
94 | { | 94 | { |
95 | uint32_t ret; | 95 | uint32_t ret; |
96 | 96 | ||
97 | if (amdgpu_sriov_runtime(adev)) { | ||
98 | BUG_ON(in_interrupt()); | ||
99 | return amdgpu_virt_kiq_rreg(adev, reg); | ||
100 | } | ||
101 | |||
97 | if ((reg * 4) < adev->rmmio_size && !always_indirect) | 102 | if ((reg * 4) < adev->rmmio_size && !always_indirect) |
98 | ret = readl(((void __iomem *)adev->rmmio) + (reg * 4)); | 103 | ret = readl(((void __iomem *)adev->rmmio) + (reg * 4)); |
99 | else { | 104 | else { |
@@ -113,6 +118,11 @@ void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v, | |||
113 | { | 118 | { |
114 | trace_amdgpu_mm_wreg(adev->pdev->device, reg, v); | 119 | trace_amdgpu_mm_wreg(adev->pdev->device, reg, v); |
115 | 120 | ||
121 | if (amdgpu_sriov_runtime(adev)) { | ||
122 | BUG_ON(in_interrupt()); | ||
123 | return amdgpu_virt_kiq_wreg(adev, reg, v); | ||
124 | } | ||
125 | |||
116 | if ((reg * 4) < adev->rmmio_size && !always_indirect) | 126 | if ((reg * 4) < adev->rmmio_size && !always_indirect) |
117 | writel(v, ((void __iomem *)adev->rmmio) + (reg * 4)); | 127 | writel(v, ((void __iomem *)adev->rmmio) + (reg * 4)); |
118 | else { | 128 | else { |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c index cfc47214161a..00583baab132 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | |||
@@ -91,3 +91,61 @@ int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm) | |||
91 | ttm_eu_backoff_reservation(&ticket, &list); | 91 | ttm_eu_backoff_reservation(&ticket, &list); |
92 | return 0; | 92 | return 0; |
93 | } | 93 | } |
94 | |||
95 | void amdgpu_virt_init_setting(struct amdgpu_device *adev) | ||
96 | { | ||
97 | mutex_init(&adev->virt.lock); | ||
98 | } | ||
99 | |||
100 | uint32_t amdgpu_virt_kiq_rreg(struct amdgpu_device *adev, uint32_t reg) | ||
101 | { | ||
102 | signed long r; | ||
103 | uint32_t val; | ||
104 | struct dma_fence *f; | ||
105 | struct amdgpu_kiq *kiq = &adev->gfx.kiq; | ||
106 | struct amdgpu_ring *ring = &kiq->ring; | ||
107 | |||
108 | BUG_ON(!ring->funcs->emit_rreg); | ||
109 | |||
110 | mutex_lock(&adev->virt.lock); | ||
111 | amdgpu_ring_alloc(ring, 32); | ||
112 | amdgpu_ring_emit_hdp_flush(ring); | ||
113 | amdgpu_ring_emit_rreg(ring, reg); | ||
114 | amdgpu_ring_emit_hdp_invalidate(ring); | ||
115 | amdgpu_fence_emit(ring, &f); | ||
116 | amdgpu_ring_commit(ring); | ||
117 | mutex_unlock(&adev->virt.lock); | ||
118 | |||
119 | r = dma_fence_wait(f, false); | ||
120 | if (r) | ||
121 | DRM_ERROR("wait for kiq fence error: %ld.\n", r); | ||
122 | dma_fence_put(f); | ||
123 | |||
124 | val = adev->wb.wb[adev->virt.reg_val_offs]; | ||
125 | |||
126 | return val; | ||
127 | } | ||
128 | |||
129 | void amdgpu_virt_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v) | ||
130 | { | ||
131 | signed long r; | ||
132 | struct dma_fence *f; | ||
133 | struct amdgpu_kiq *kiq = &adev->gfx.kiq; | ||
134 | struct amdgpu_ring *ring = &kiq->ring; | ||
135 | |||
136 | BUG_ON(!ring->funcs->emit_wreg); | ||
137 | |||
138 | mutex_lock(&adev->virt.lock); | ||
139 | amdgpu_ring_alloc(ring, 32); | ||
140 | amdgpu_ring_emit_hdp_flush(ring); | ||
141 | amdgpu_ring_emit_wreg(ring, reg, v); | ||
142 | amdgpu_ring_emit_hdp_invalidate(ring); | ||
143 | amdgpu_fence_emit(ring, &f); | ||
144 | amdgpu_ring_commit(ring); | ||
145 | mutex_unlock(&adev->virt.lock); | ||
146 | |||
147 | r = dma_fence_wait(f, false); | ||
148 | if (r) | ||
149 | DRM_ERROR("wait for kiq fence error: %ld.\n", r); | ||
150 | dma_fence_put(f); | ||
151 | } | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h index 8bb9e5d307cb..433f559bc4a1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h | |||
@@ -36,6 +36,7 @@ struct amdgpu_virt { | |||
36 | struct amdgpu_bo *csa_obj; | 36 | struct amdgpu_bo *csa_obj; |
37 | uint64_t csa_vmid0_addr; | 37 | uint64_t csa_vmid0_addr; |
38 | uint32_t reg_val_offs; | 38 | uint32_t reg_val_offs; |
39 | struct mutex lock; | ||
39 | }; | 40 | }; |
40 | 41 | ||
41 | #define AMDGPU_CSA_SIZE (8 * 1024) | 42 | #define AMDGPU_CSA_SIZE (8 * 1024) |
@@ -68,5 +69,8 @@ static inline bool is_virtual_machine(void) | |||
68 | struct amdgpu_vm; | 69 | struct amdgpu_vm; |
69 | int amdgpu_allocate_static_csa(struct amdgpu_device *adev); | 70 | int amdgpu_allocate_static_csa(struct amdgpu_device *adev); |
70 | int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm); | 71 | int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm); |
72 | void amdgpu_virt_init_setting(struct amdgpu_device *adev); | ||
73 | uint32_t amdgpu_virt_kiq_rreg(struct amdgpu_device *adev, uint32_t reg); | ||
74 | void amdgpu_virt_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v); | ||
71 | 75 | ||
72 | #endif | 76 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index 95029e2e2650..abdb80b812a6 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c | |||
@@ -921,6 +921,9 @@ static int vi_common_early_init(void *handle) | |||
921 | (amdgpu_ip_block_mask & (1 << AMD_IP_BLOCK_TYPE_SMC))) | 921 | (amdgpu_ip_block_mask & (1 << AMD_IP_BLOCK_TYPE_SMC))) |
922 | smc_enabled = true; | 922 | smc_enabled = true; |
923 | 923 | ||
924 | if (amdgpu_sriov_vf(adev)) | ||
925 | amdgpu_virt_init_setting(adev); | ||
926 | |||
924 | adev->rev_id = vi_get_rev_id(adev); | 927 | adev->rev_id = vi_get_rev_id(adev); |
925 | adev->external_rev_id = 0xFF; | 928 | adev->external_rev_id = 0xFF; |
926 | switch (adev->asic_type) { | 929 | switch (adev->asic_type) { |