aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h13
-rw-r--r--drivers/gpu/drm/amd/amdgpu/cik_ih.c29
-rw-r--r--drivers/gpu/drm/amd/amdgpu/cz_ih.c31
-rw-r--r--drivers/gpu/drm/amd/amdgpu/iceland_ih.c29
-rw-r--r--drivers/gpu/drm/amd/amdgpu/si_ih.c31
-rw-r--r--drivers/gpu/drm/amd/amdgpu/tonga_ih.c43
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vega10_ih.c56
8 files changed, 128 insertions, 110 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
index 8af67f649660..fb8dd6179926 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
@@ -137,7 +137,7 @@ int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
137 if (!ih->enabled || adev->shutdown) 137 if (!ih->enabled || adev->shutdown)
138 return IRQ_NONE; 138 return IRQ_NONE;
139 139
140 wptr = amdgpu_ih_get_wptr(adev); 140 wptr = amdgpu_ih_get_wptr(adev, ih);
141 141
142restart_ih: 142restart_ih:
143 /* is somebody else already processing irqs? */ 143 /* is somebody else already processing irqs? */
@@ -154,11 +154,11 @@ restart_ih:
154 ih->rptr &= ih->ptr_mask; 154 ih->rptr &= ih->ptr_mask;
155 } 155 }
156 156
157 amdgpu_ih_set_rptr(adev); 157 amdgpu_ih_set_rptr(adev, ih);
158 atomic_set(&ih->lock, 0); 158 atomic_set(&ih->lock, 0);
159 159
160 /* make sure wptr hasn't changed while processing */ 160 /* make sure wptr hasn't changed while processing */
161 wptr = amdgpu_ih_get_wptr(adev); 161 wptr = amdgpu_ih_get_wptr(adev, ih);
162 if (wptr != ih->rptr) 162 if (wptr != ih->rptr)
163 goto restart_ih; 163 goto restart_ih;
164 164
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
index f877bb78d10a..d810fd73d574 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
@@ -50,15 +50,16 @@ struct amdgpu_ih_ring {
50/* provided by the ih block */ 50/* provided by the ih block */
51struct amdgpu_ih_funcs { 51struct amdgpu_ih_funcs {
52 /* ring read/write ptr handling, called from interrupt context */ 52 /* ring read/write ptr handling, called from interrupt context */
53 u32 (*get_wptr)(struct amdgpu_device *adev); 53 u32 (*get_wptr)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih);
54 void (*decode_iv)(struct amdgpu_device *adev, 54 void (*decode_iv)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
55 struct amdgpu_iv_entry *entry); 55 struct amdgpu_iv_entry *entry);
56 void (*set_rptr)(struct amdgpu_device *adev); 56 void (*set_rptr)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih);
57}; 57};
58 58
59#define amdgpu_ih_get_wptr(adev) (adev)->irq.ih_funcs->get_wptr((adev)) 59#define amdgpu_ih_get_wptr(adev, ih) (adev)->irq.ih_funcs->get_wptr((adev), (ih))
60#define amdgpu_ih_decode_iv(adev, iv) (adev)->irq.ih_funcs->decode_iv((adev), (iv)) 60#define amdgpu_ih_decode_iv(adev, iv) \
61#define amdgpu_ih_set_rptr(adev) (adev)->irq.ih_funcs->set_rptr((adev)) 61 (adev)->irq.ih_funcs->decode_iv((adev), (ih), (iv))
62#define amdgpu_ih_set_rptr(adev, ih) (adev)->irq.ih_funcs->set_rptr((adev), (ih))
62 63
63int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, 64int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
64 unsigned ring_size, bool use_bus_addr); 65 unsigned ring_size, bool use_bus_addr);
diff --git a/drivers/gpu/drm/amd/amdgpu/cik_ih.c b/drivers/gpu/drm/amd/amdgpu/cik_ih.c
index 8a8b4967a101..884aa9b81e86 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/cik_ih.c
@@ -183,11 +183,12 @@ static void cik_ih_irq_disable(struct amdgpu_device *adev)
183 * Used by cik_irq_process(). 183 * Used by cik_irq_process().
184 * Returns the value of the wptr. 184 * Returns the value of the wptr.
185 */ 185 */
186static u32 cik_ih_get_wptr(struct amdgpu_device *adev) 186static u32 cik_ih_get_wptr(struct amdgpu_device *adev,
187 struct amdgpu_ih_ring *ih)
187{ 188{
188 u32 wptr, tmp; 189 u32 wptr, tmp;
189 190
190 wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]); 191 wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
191 192
192 if (wptr & IH_RB_WPTR__RB_OVERFLOW_MASK) { 193 if (wptr & IH_RB_WPTR__RB_OVERFLOW_MASK) {
193 wptr &= ~IH_RB_WPTR__RB_OVERFLOW_MASK; 194 wptr &= ~IH_RB_WPTR__RB_OVERFLOW_MASK;
@@ -196,13 +197,13 @@ static u32 cik_ih_get_wptr(struct amdgpu_device *adev)
196 * this should allow us to catchup. 197 * this should allow us to catchup.
197 */ 198 */
198 dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", 199 dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
199 wptr, adev->irq.ih.rptr, (wptr + 16) & adev->irq.ih.ptr_mask); 200 wptr, ih->rptr, (wptr + 16) & ih->ptr_mask);
200 adev->irq.ih.rptr = (wptr + 16) & adev->irq.ih.ptr_mask; 201 ih->rptr = (wptr + 16) & ih->ptr_mask;
201 tmp = RREG32(mmIH_RB_CNTL); 202 tmp = RREG32(mmIH_RB_CNTL);
202 tmp |= IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK; 203 tmp |= IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK;
203 WREG32(mmIH_RB_CNTL, tmp); 204 WREG32(mmIH_RB_CNTL, tmp);
204 } 205 }
205 return (wptr & adev->irq.ih.ptr_mask); 206 return (wptr & ih->ptr_mask);
206} 207}
207 208
208/* CIK IV Ring 209/* CIK IV Ring
@@ -237,16 +238,17 @@ static u32 cik_ih_get_wptr(struct amdgpu_device *adev)
237 * position and also advance the position. 238 * position and also advance the position.
238 */ 239 */
239static void cik_ih_decode_iv(struct amdgpu_device *adev, 240static void cik_ih_decode_iv(struct amdgpu_device *adev,
241 struct amdgpu_ih_ring *ih,
240 struct amdgpu_iv_entry *entry) 242 struct amdgpu_iv_entry *entry)
241{ 243{
242 /* wptr/rptr are in bytes! */ 244 /* wptr/rptr are in bytes! */
243 u32 ring_index = adev->irq.ih.rptr >> 2; 245 u32 ring_index = ih->rptr >> 2;
244 uint32_t dw[4]; 246 uint32_t dw[4];
245 247
246 dw[0] = le32_to_cpu(adev->irq.ih.ring[ring_index + 0]); 248 dw[0] = le32_to_cpu(ih->ring[ring_index + 0]);
247 dw[1] = le32_to_cpu(adev->irq.ih.ring[ring_index + 1]); 249 dw[1] = le32_to_cpu(ih->ring[ring_index + 1]);
248 dw[2] = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]); 250 dw[2] = le32_to_cpu(ih->ring[ring_index + 2]);
249 dw[3] = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]); 251 dw[3] = le32_to_cpu(ih->ring[ring_index + 3]);
250 252
251 entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY; 253 entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY;
252 entry->src_id = dw[0] & 0xff; 254 entry->src_id = dw[0] & 0xff;
@@ -256,7 +258,7 @@ static void cik_ih_decode_iv(struct amdgpu_device *adev,
256 entry->pasid = (dw[2] >> 16) & 0xffff; 258 entry->pasid = (dw[2] >> 16) & 0xffff;
257 259
258 /* wptr/rptr are in bytes! */ 260 /* wptr/rptr are in bytes! */
259 adev->irq.ih.rptr += 16; 261 ih->rptr += 16;
260} 262}
261 263
262/** 264/**
@@ -266,9 +268,10 @@ static void cik_ih_decode_iv(struct amdgpu_device *adev,
266 * 268 *
267 * Set the IH ring buffer rptr. 269 * Set the IH ring buffer rptr.
268 */ 270 */
269static void cik_ih_set_rptr(struct amdgpu_device *adev) 271static void cik_ih_set_rptr(struct amdgpu_device *adev,
272 struct amdgpu_ih_ring *ih)
270{ 273{
271 WREG32(mmIH_RB_RPTR, adev->irq.ih.rptr); 274 WREG32(mmIH_RB_RPTR, ih->rptr);
272} 275}
273 276
274static int cik_ih_early_init(void *handle) 277static int cik_ih_early_init(void *handle)
diff --git a/drivers/gpu/drm/amd/amdgpu/cz_ih.c b/drivers/gpu/drm/amd/amdgpu/cz_ih.c
index 9d3ea298e116..c59eed041fb5 100644
--- a/drivers/gpu/drm/amd/amdgpu/cz_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/cz_ih.c
@@ -185,11 +185,12 @@ static void cz_ih_irq_disable(struct amdgpu_device *adev)
185 * Used by cz_irq_process(VI). 185 * Used by cz_irq_process(VI).
186 * Returns the value of the wptr. 186 * Returns the value of the wptr.
187 */ 187 */
188static u32 cz_ih_get_wptr(struct amdgpu_device *adev) 188static u32 cz_ih_get_wptr(struct amdgpu_device *adev,
189 struct amdgpu_ih_ring *ih)
189{ 190{
190 u32 wptr, tmp; 191 u32 wptr, tmp;
191 192
192 wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]); 193 wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
193 194
194 if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) { 195 if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
195 wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0); 196 wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
@@ -198,13 +199,13 @@ static u32 cz_ih_get_wptr(struct amdgpu_device *adev)
198 * this should allow us to catchup. 199 * this should allow us to catchup.
199 */ 200 */
200 dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", 201 dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
201 wptr, adev->irq.ih.rptr, (wptr + 16) & adev->irq.ih.ptr_mask); 202 wptr, ih->rptr, (wptr + 16) & ih->ptr_mask);
202 adev->irq.ih.rptr = (wptr + 16) & adev->irq.ih.ptr_mask; 203 ih->rptr = (wptr + 16) & ih->ptr_mask;
203 tmp = RREG32(mmIH_RB_CNTL); 204 tmp = RREG32(mmIH_RB_CNTL);
204 tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); 205 tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
205 WREG32(mmIH_RB_CNTL, tmp); 206 WREG32(mmIH_RB_CNTL, tmp);
206 } 207 }
207 return (wptr & adev->irq.ih.ptr_mask); 208 return (wptr & ih->ptr_mask);
208} 209}
209 210
210/** 211/**
@@ -216,16 +217,17 @@ static u32 cz_ih_get_wptr(struct amdgpu_device *adev)
216 * position and also advance the position. 217 * position and also advance the position.
217 */ 218 */
218static void cz_ih_decode_iv(struct amdgpu_device *adev, 219static void cz_ih_decode_iv(struct amdgpu_device *adev,
219 struct amdgpu_iv_entry *entry) 220 struct amdgpu_ih_ring *ih,
221 struct amdgpu_iv_entry *entry)
220{ 222{
221 /* wptr/rptr are in bytes! */ 223 /* wptr/rptr are in bytes! */
222 u32 ring_index = adev->irq.ih.rptr >> 2; 224 u32 ring_index = ih->rptr >> 2;
223 uint32_t dw[4]; 225 uint32_t dw[4];
224 226
225 dw[0] = le32_to_cpu(adev->irq.ih.ring[ring_index + 0]); 227 dw[0] = le32_to_cpu(ih->ring[ring_index + 0]);
226 dw[1] = le32_to_cpu(adev->irq.ih.ring[ring_index + 1]); 228 dw[1] = le32_to_cpu(ih->ring[ring_index + 1]);
227 dw[2] = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]); 229 dw[2] = le32_to_cpu(ih->ring[ring_index + 2]);
228 dw[3] = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]); 230 dw[3] = le32_to_cpu(ih->ring[ring_index + 3]);
229 231
230 entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY; 232 entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY;
231 entry->src_id = dw[0] & 0xff; 233 entry->src_id = dw[0] & 0xff;
@@ -235,7 +237,7 @@ static void cz_ih_decode_iv(struct amdgpu_device *adev,
235 entry->pasid = (dw[2] >> 16) & 0xffff; 237 entry->pasid = (dw[2] >> 16) & 0xffff;
236 238
237 /* wptr/rptr are in bytes! */ 239 /* wptr/rptr are in bytes! */
238 adev->irq.ih.rptr += 16; 240 ih->rptr += 16;
239} 241}
240 242
241/** 243/**
@@ -245,9 +247,10 @@ static void cz_ih_decode_iv(struct amdgpu_device *adev,
245 * 247 *
246 * Set the IH ring buffer rptr. 248 * Set the IH ring buffer rptr.
247 */ 249 */
248static void cz_ih_set_rptr(struct amdgpu_device *adev) 250static void cz_ih_set_rptr(struct amdgpu_device *adev,
251 struct amdgpu_ih_ring *ih)
249{ 252{
250 WREG32(mmIH_RB_RPTR, adev->irq.ih.rptr); 253 WREG32(mmIH_RB_RPTR, ih->rptr);
251} 254}
252 255
253static int cz_ih_early_init(void *handle) 256static int cz_ih_early_init(void *handle)
diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
index a3984d10b604..f006ed509db3 100644
--- a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
@@ -185,11 +185,12 @@ static void iceland_ih_irq_disable(struct amdgpu_device *adev)
185 * Used by cz_irq_process(VI). 185 * Used by cz_irq_process(VI).
186 * Returns the value of the wptr. 186 * Returns the value of the wptr.
187 */ 187 */
188static u32 iceland_ih_get_wptr(struct amdgpu_device *adev) 188static u32 iceland_ih_get_wptr(struct amdgpu_device *adev,
189 struct amdgpu_ih_ring *ih)
189{ 190{
190 u32 wptr, tmp; 191 u32 wptr, tmp;
191 192
192 wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]); 193 wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
193 194
194 if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) { 195 if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
195 wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0); 196 wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
@@ -198,13 +199,13 @@ static u32 iceland_ih_get_wptr(struct amdgpu_device *adev)
198 * this should allow us to catchup. 199 * this should allow us to catchup.
199 */ 200 */
200 dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", 201 dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
201 wptr, adev->irq.ih.rptr, (wptr + 16) & adev->irq.ih.ptr_mask); 202 wptr, ih->rptr, (wptr + 16) & ih->ptr_mask);
202 adev->irq.ih.rptr = (wptr + 16) & adev->irq.ih.ptr_mask; 203 ih->rptr = (wptr + 16) & ih->ptr_mask;
203 tmp = RREG32(mmIH_RB_CNTL); 204 tmp = RREG32(mmIH_RB_CNTL);
204 tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); 205 tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
205 WREG32(mmIH_RB_CNTL, tmp); 206 WREG32(mmIH_RB_CNTL, tmp);
206 } 207 }
207 return (wptr & adev->irq.ih.ptr_mask); 208 return (wptr & ih->ptr_mask);
208} 209}
209 210
210/** 211/**
@@ -216,16 +217,17 @@ static u32 iceland_ih_get_wptr(struct amdgpu_device *adev)
216 * position and also advance the position. 217 * position and also advance the position.
217 */ 218 */
218static void iceland_ih_decode_iv(struct amdgpu_device *adev, 219static void iceland_ih_decode_iv(struct amdgpu_device *adev,
220 struct amdgpu_ih_ring *ih,
219 struct amdgpu_iv_entry *entry) 221 struct amdgpu_iv_entry *entry)
220{ 222{
221 /* wptr/rptr are in bytes! */ 223 /* wptr/rptr are in bytes! */
222 u32 ring_index = adev->irq.ih.rptr >> 2; 224 u32 ring_index = ih->rptr >> 2;
223 uint32_t dw[4]; 225 uint32_t dw[4];
224 226
225 dw[0] = le32_to_cpu(adev->irq.ih.ring[ring_index + 0]); 227 dw[0] = le32_to_cpu(ih->ring[ring_index + 0]);
226 dw[1] = le32_to_cpu(adev->irq.ih.ring[ring_index + 1]); 228 dw[1] = le32_to_cpu(ih->ring[ring_index + 1]);
227 dw[2] = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]); 229 dw[2] = le32_to_cpu(ih->ring[ring_index + 2]);
228 dw[3] = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]); 230 dw[3] = le32_to_cpu(ih->ring[ring_index + 3]);
229 231
230 entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY; 232 entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY;
231 entry->src_id = dw[0] & 0xff; 233 entry->src_id = dw[0] & 0xff;
@@ -235,7 +237,7 @@ static void iceland_ih_decode_iv(struct amdgpu_device *adev,
235 entry->pasid = (dw[2] >> 16) & 0xffff; 237 entry->pasid = (dw[2] >> 16) & 0xffff;
236 238
237 /* wptr/rptr are in bytes! */ 239 /* wptr/rptr are in bytes! */
238 adev->irq.ih.rptr += 16; 240 ih->rptr += 16;
239} 241}
240 242
241/** 243/**
@@ -245,9 +247,10 @@ static void iceland_ih_decode_iv(struct amdgpu_device *adev,
245 * 247 *
246 * Set the IH ring buffer rptr. 248 * Set the IH ring buffer rptr.
247 */ 249 */
248static void iceland_ih_set_rptr(struct amdgpu_device *adev) 250static void iceland_ih_set_rptr(struct amdgpu_device *adev,
251 struct amdgpu_ih_ring *ih)
249{ 252{
250 WREG32(mmIH_RB_RPTR, adev->irq.ih.rptr); 253 WREG32(mmIH_RB_RPTR, ih->rptr);
251} 254}
252 255
253static int iceland_ih_early_init(void *handle) 256static int iceland_ih_early_init(void *handle)
diff --git a/drivers/gpu/drm/amd/amdgpu/si_ih.c b/drivers/gpu/drm/amd/amdgpu/si_ih.c
index 2938fb9f17cc..5cabc9687f76 100644
--- a/drivers/gpu/drm/amd/amdgpu/si_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/si_ih.c
@@ -100,34 +100,36 @@ static void si_ih_irq_disable(struct amdgpu_device *adev)
100 mdelay(1); 100 mdelay(1);
101} 101}
102 102
103static u32 si_ih_get_wptr(struct amdgpu_device *adev) 103static u32 si_ih_get_wptr(struct amdgpu_device *adev,
104 struct amdgpu_ih_ring *ih)
104{ 105{
105 u32 wptr, tmp; 106 u32 wptr, tmp;
106 107
107 wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]); 108 wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
108 109
109 if (wptr & IH_RB_WPTR__RB_OVERFLOW_MASK) { 110 if (wptr & IH_RB_WPTR__RB_OVERFLOW_MASK) {
110 wptr &= ~IH_RB_WPTR__RB_OVERFLOW_MASK; 111 wptr &= ~IH_RB_WPTR__RB_OVERFLOW_MASK;
111 dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", 112 dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
112 wptr, adev->irq.ih.rptr, (wptr + 16) & adev->irq.ih.ptr_mask); 113 wptr, ih->rptr, (wptr + 16) & ih->ptr_mask);
113 adev->irq.ih.rptr = (wptr + 16) & adev->irq.ih.ptr_mask; 114 ih->rptr = (wptr + 16) & ih->ptr_mask;
114 tmp = RREG32(IH_RB_CNTL); 115 tmp = RREG32(IH_RB_CNTL);
115 tmp |= IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK; 116 tmp |= IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK;
116 WREG32(IH_RB_CNTL, tmp); 117 WREG32(IH_RB_CNTL, tmp);
117 } 118 }
118 return (wptr & adev->irq.ih.ptr_mask); 119 return (wptr & ih->ptr_mask);
119} 120}
120 121
121static void si_ih_decode_iv(struct amdgpu_device *adev, 122static void si_ih_decode_iv(struct amdgpu_device *adev,
122 struct amdgpu_iv_entry *entry) 123 struct amdgpu_ih_ring *ih,
124 struct amdgpu_iv_entry *entry)
123{ 125{
124 u32 ring_index = adev->irq.ih.rptr >> 2; 126 u32 ring_index = ih->rptr >> 2;
125 uint32_t dw[4]; 127 uint32_t dw[4];
126 128
127 dw[0] = le32_to_cpu(adev->irq.ih.ring[ring_index + 0]); 129 dw[0] = le32_to_cpu(ih->ring[ring_index + 0]);
128 dw[1] = le32_to_cpu(adev->irq.ih.ring[ring_index + 1]); 130 dw[1] = le32_to_cpu(ih->ring[ring_index + 1]);
129 dw[2] = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]); 131 dw[2] = le32_to_cpu(ih->ring[ring_index + 2]);
130 dw[3] = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]); 132 dw[3] = le32_to_cpu(ih->ring[ring_index + 3]);
131 133
132 entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY; 134 entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY;
133 entry->src_id = dw[0] & 0xff; 135 entry->src_id = dw[0] & 0xff;
@@ -135,12 +137,13 @@ static void si_ih_decode_iv(struct amdgpu_device *adev,
135 entry->ring_id = dw[2] & 0xff; 137 entry->ring_id = dw[2] & 0xff;
136 entry->vmid = (dw[2] >> 8) & 0xff; 138 entry->vmid = (dw[2] >> 8) & 0xff;
137 139
138 adev->irq.ih.rptr += 16; 140 ih->rptr += 16;
139} 141}
140 142
141static void si_ih_set_rptr(struct amdgpu_device *adev) 143static void si_ih_set_rptr(struct amdgpu_device *adev,
144 struct amdgpu_ih_ring *ih)
142{ 145{
143 WREG32(IH_RB_RPTR, adev->irq.ih.rptr); 146 WREG32(IH_RB_RPTR, ih->rptr);
144} 147}
145 148
146static int si_ih_early_init(void *handle) 149static int si_ih_early_init(void *handle)
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
diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
index 2c250b01a903..28b0e9a6cc42 100644
--- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
@@ -191,14 +191,15 @@ static void vega10_ih_irq_disable(struct amdgpu_device *adev)
191 * ring buffer overflow and deal with it. 191 * ring buffer overflow and deal with it.
192 * Returns the value of the wptr. 192 * Returns the value of the wptr.
193 */ 193 */
194static u32 vega10_ih_get_wptr(struct amdgpu_device *adev) 194static u32 vega10_ih_get_wptr(struct amdgpu_device *adev,
195 struct amdgpu_ih_ring *ih)
195{ 196{
196 u32 wptr, tmp; 197 u32 wptr, tmp;
197 198
198 if (adev->irq.ih.use_bus_addr) 199 if (ih->use_bus_addr)
199 wptr = le32_to_cpu(adev->irq.ih.ring[adev->irq.ih.wptr_offs]); 200 wptr = le32_to_cpu(ih->ring[ih->wptr_offs]);
200 else 201 else
201 wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]); 202 wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
202 203
203 if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) { 204 if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
204 wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0); 205 wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
@@ -207,16 +208,16 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev)
207 * from the last not overwritten vector (wptr + 32). Hopefully 208 * from the last not overwritten vector (wptr + 32). Hopefully
208 * this should allow us to catchup. 209 * this should allow us to catchup.
209 */ 210 */
210 tmp = (wptr + 32) & adev->irq.ih.ptr_mask; 211 tmp = (wptr + 32) & ih->ptr_mask;
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, tmp); 213 wptr, ih->rptr, tmp);
213 adev->irq.ih.rptr = tmp; 214 ih->rptr = tmp;
214 215
215 tmp = RREG32_NO_KIQ(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL)); 216 tmp = RREG32_NO_KIQ(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL));
216 tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); 217 tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
217 WREG32_NO_KIQ(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL), tmp); 218 WREG32_NO_KIQ(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL), tmp);
218 } 219 }
219 return (wptr & adev->irq.ih.ptr_mask); 220 return (wptr & ih->ptr_mask);
220} 221}
221 222
222/** 223/**
@@ -228,20 +229,21 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev)
228 * position and also advance the position. 229 * position and also advance the position.
229 */ 230 */
230static void vega10_ih_decode_iv(struct amdgpu_device *adev, 231static void vega10_ih_decode_iv(struct amdgpu_device *adev,
231 struct amdgpu_iv_entry *entry) 232 struct amdgpu_ih_ring *ih,
233 struct amdgpu_iv_entry *entry)
232{ 234{
233 /* wptr/rptr are in bytes! */ 235 /* wptr/rptr are in bytes! */
234 u32 ring_index = adev->irq.ih.rptr >> 2; 236 u32 ring_index = ih->rptr >> 2;
235 uint32_t dw[8]; 237 uint32_t dw[8];
236 238
237 dw[0] = le32_to_cpu(adev->irq.ih.ring[ring_index + 0]); 239 dw[0] = le32_to_cpu(ih->ring[ring_index + 0]);
238 dw[1] = le32_to_cpu(adev->irq.ih.ring[ring_index + 1]); 240 dw[1] = le32_to_cpu(ih->ring[ring_index + 1]);
239 dw[2] = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]); 241 dw[2] = le32_to_cpu(ih->ring[ring_index + 2]);
240 dw[3] = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]); 242 dw[3] = le32_to_cpu(ih->ring[ring_index + 3]);
241 dw[4] = le32_to_cpu(adev->irq.ih.ring[ring_index + 4]); 243 dw[4] = le32_to_cpu(ih->ring[ring_index + 4]);
242 dw[5] = le32_to_cpu(adev->irq.ih.ring[ring_index + 5]); 244 dw[5] = le32_to_cpu(ih->ring[ring_index + 5]);
243 dw[6] = le32_to_cpu(adev->irq.ih.ring[ring_index + 6]); 245 dw[6] = le32_to_cpu(ih->ring[ring_index + 6]);
244 dw[7] = le32_to_cpu(adev->irq.ih.ring[ring_index + 7]); 246 dw[7] = le32_to_cpu(ih->ring[ring_index + 7]);
245 247
246 entry->client_id = dw[0] & 0xff; 248 entry->client_id = dw[0] & 0xff;
247 entry->src_id = (dw[0] >> 8) & 0xff; 249 entry->src_id = (dw[0] >> 8) & 0xff;
@@ -257,9 +259,8 @@ static void vega10_ih_decode_iv(struct amdgpu_device *adev,
257 entry->src_data[2] = dw[6]; 259 entry->src_data[2] = dw[6];
258 entry->src_data[3] = dw[7]; 260 entry->src_data[3] = dw[7];
259 261
260
261 /* wptr/rptr are in bytes! */ 262 /* wptr/rptr are in bytes! */
262 adev->irq.ih.rptr += 32; 263 ih->rptr += 32;
263} 264}
264 265
265/** 266/**
@@ -269,17 +270,18 @@ static void vega10_ih_decode_iv(struct amdgpu_device *adev,
269 * 270 *
270 * Set the IH ring buffer rptr. 271 * Set the IH ring buffer rptr.
271 */ 272 */
272static void vega10_ih_set_rptr(struct amdgpu_device *adev) 273static void vega10_ih_set_rptr(struct amdgpu_device *adev,
274 struct amdgpu_ih_ring *ih)
273{ 275{
274 if (adev->irq.ih.use_doorbell) { 276 if (ih->use_doorbell) {
275 /* XXX check if swapping is necessary on BE */ 277 /* XXX check if swapping is necessary on BE */
276 if (adev->irq.ih.use_bus_addr) 278 if (ih->use_bus_addr)
277 adev->irq.ih.ring[adev->irq.ih.rptr_offs] = adev->irq.ih.rptr; 279 ih->ring[ih->rptr_offs] = ih->rptr;
278 else 280 else
279 adev->wb.wb[adev->irq.ih.rptr_offs] = adev->irq.ih.rptr; 281 adev->wb.wb[ih->rptr_offs] = ih->rptr;
280 WDOORBELL32(adev->irq.ih.doorbell_index, adev->irq.ih.rptr); 282 WDOORBELL32(ih->doorbell_index, ih->rptr);
281 } else { 283 } else {
282 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, adev->irq.ih.rptr); 284 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, ih->rptr);
283 } 285 }
284} 286}
285 287