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);