aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2018-09-17 10:13:49 -0400
committerAlex Deucher <alexander.deucher@amd.com>2019-01-14 15:04:47 -0500
commit8bb9eb480d032418bd08d0a6a39e4eaa1dec2fb8 (patch)
tree0b83e974d2b75e4d0fc1aaa6fb3e28eb838f22ab /drivers/gpu/drm/amd/amdgpu/tonga_ih.c
parent73c97fa4421fa0465a0b25a0ccf62af32e4bd01e (diff)
drm/amdgpu: add IH ring to ih_get_wptr/ih_set_rptr v2
Let's start to support multiple rings. v2: decode IV is needed as well Signed-off-by: Christian König <christian.koenig@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/tonga_ih.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/tonga_ih.c43
1 files changed, 23 insertions, 20 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
index 15da06ddeb75..30e3911dedb5 100644
--- a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
@@ -193,14 +193,15 @@ static void tonga_ih_irq_disable(struct amdgpu_device *adev)
193 * Used by cz_irq_process(VI). 193 * Used by cz_irq_process(VI).
194 * Returns the value of the wptr. 194 * Returns the value of the wptr.
195 */ 195 */
196static u32 tonga_ih_get_wptr(struct amdgpu_device *adev) 196static u32 tonga_ih_get_wptr(struct amdgpu_device *adev,
197 struct amdgpu_ih_ring *ih)
197{ 198{
198 u32 wptr, tmp; 199 u32 wptr, tmp;
199 200
200 if (adev->irq.ih.use_bus_addr) 201 if (adev->irq.ih.use_bus_addr)
201 wptr = le32_to_cpu(adev->irq.ih.ring[adev->irq.ih.wptr_offs]); 202 wptr = le32_to_cpu(ih->ring[ih->wptr_offs]);
202 else 203 else
203 wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]); 204 wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
204 205
205 if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) { 206 if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
206 wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0); 207 wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
@@ -209,13 +210,13 @@ static u32 tonga_ih_get_wptr(struct amdgpu_device *adev)
209 * this should allow us to catchup. 210 * this should allow us to catchup.
210 */ 211 */
211 dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", 212 dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
212 wptr, adev->irq.ih.rptr, (wptr + 16) & adev->irq.ih.ptr_mask); 213 wptr, ih->rptr, (wptr + 16) & ih->ptr_mask);
213 adev->irq.ih.rptr = (wptr + 16) & adev->irq.ih.ptr_mask; 214 ih->rptr = (wptr + 16) & ih->ptr_mask;
214 tmp = RREG32(mmIH_RB_CNTL); 215 tmp = RREG32(mmIH_RB_CNTL);
215 tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); 216 tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
216 WREG32(mmIH_RB_CNTL, tmp); 217 WREG32(mmIH_RB_CNTL, tmp);
217 } 218 }
218 return (wptr & adev->irq.ih.ptr_mask); 219 return (wptr & ih->ptr_mask);
219} 220}
220 221
221/** 222/**
@@ -227,16 +228,17 @@ static u32 tonga_ih_get_wptr(struct amdgpu_device *adev)
227 * position and also advance the position. 228 * position and also advance the position.
228 */ 229 */
229static void tonga_ih_decode_iv(struct amdgpu_device *adev, 230static void tonga_ih_decode_iv(struct amdgpu_device *adev,
230 struct amdgpu_iv_entry *entry) 231 struct amdgpu_ih_ring *ih,
232 struct amdgpu_iv_entry *entry)
231{ 233{
232 /* wptr/rptr are in bytes! */ 234 /* wptr/rptr are in bytes! */
233 u32 ring_index = adev->irq.ih.rptr >> 2; 235 u32 ring_index = ih->rptr >> 2;
234 uint32_t dw[4]; 236 uint32_t dw[4];
235 237
236 dw[0] = le32_to_cpu(adev->irq.ih.ring[ring_index + 0]); 238 dw[0] = le32_to_cpu(ih->ring[ring_index + 0]);
237 dw[1] = le32_to_cpu(adev->irq.ih.ring[ring_index + 1]); 239 dw[1] = le32_to_cpu(ih->ring[ring_index + 1]);
238 dw[2] = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]); 240 dw[2] = le32_to_cpu(ih->ring[ring_index + 2]);
239 dw[3] = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]); 241 dw[3] = le32_to_cpu(ih->ring[ring_index + 3]);
240 242
241 entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY; 243 entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY;
242 entry->src_id = dw[0] & 0xff; 244 entry->src_id = dw[0] & 0xff;
@@ -246,7 +248,7 @@ static void tonga_ih_decode_iv(struct amdgpu_device *adev,
246 entry->pasid = (dw[2] >> 16) & 0xffff; 248 entry->pasid = (dw[2] >> 16) & 0xffff;
247 249
248 /* wptr/rptr are in bytes! */ 250 /* wptr/rptr are in bytes! */
249 adev->irq.ih.rptr += 16; 251 ih->rptr += 16;
250} 252}
251 253
252/** 254/**
@@ -256,17 +258,18 @@ static void tonga_ih_decode_iv(struct amdgpu_device *adev,
256 * 258 *
257 * Set the IH ring buffer rptr. 259 * Set the IH ring buffer rptr.
258 */ 260 */
259static void tonga_ih_set_rptr(struct amdgpu_device *adev) 261static void tonga_ih_set_rptr(struct amdgpu_device *adev,
262 struct amdgpu_ih_ring *ih)
260{ 263{
261 if (adev->irq.ih.use_doorbell) { 264 if (ih->use_doorbell) {
262 /* XXX check if swapping is necessary on BE */ 265 /* XXX check if swapping is necessary on BE */
263 if (adev->irq.ih.use_bus_addr) 266 if (ih->use_bus_addr)
264 adev->irq.ih.ring[adev->irq.ih.rptr_offs] = adev->irq.ih.rptr; 267 ih->ring[ih->rptr_offs] = ih->rptr;
265 else 268 else
266 adev->wb.wb[adev->irq.ih.rptr_offs] = adev->irq.ih.rptr; 269 adev->wb.wb[ih->rptr_offs] = ih->rptr;
267 WDOORBELL32(adev->irq.ih.doorbell_index, adev->irq.ih.rptr); 270 WDOORBELL32(ih->doorbell_index, ih->rptr);
268 } else { 271 } else {
269 WREG32(mmIH_RB_RPTR, adev->irq.ih.rptr); 272 WREG32(mmIH_RB_RPTR, ih->rptr);
270 } 273 }
271} 274}
272 275