diff options
author | Christian König <christian.koenig@amd.com> | 2018-09-17 10:13:49 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2019-01-14 15:04:47 -0500 |
commit | 8bb9eb480d032418bd08d0a6a39e4eaa1dec2fb8 (patch) | |
tree | 0b83e974d2b75e4d0fc1aaa6fb3e28eb838f22ab | |
parent | 73c97fa4421fa0465a0b25a0ccf62af32e4bd01e (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.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/cik_ih.c | 29 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/cz_ih.c | 31 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 29 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/si_ih.c | 31 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 43 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 56 |
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 | ||
142 | restart_ih: | 142 | restart_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 */ |
51 | struct amdgpu_ih_funcs { | 51 | struct 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 | ||
63 | int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, | 64 | int 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 | */ |
186 | static u32 cik_ih_get_wptr(struct amdgpu_device *adev) | 186 | static 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 | */ |
239 | static void cik_ih_decode_iv(struct amdgpu_device *adev, | 240 | static 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 | */ |
269 | static void cik_ih_set_rptr(struct amdgpu_device *adev) | 271 | static 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 | ||
274 | static int cik_ih_early_init(void *handle) | 277 | static 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 | */ |
188 | static u32 cz_ih_get_wptr(struct amdgpu_device *adev) | 188 | static 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 | */ |
218 | static void cz_ih_decode_iv(struct amdgpu_device *adev, | 219 | static 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 | */ |
248 | static void cz_ih_set_rptr(struct amdgpu_device *adev) | 250 | static 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 | ||
253 | static int cz_ih_early_init(void *handle) | 256 | static 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 | */ |
188 | static u32 iceland_ih_get_wptr(struct amdgpu_device *adev) | 188 | static 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 | */ |
218 | static void iceland_ih_decode_iv(struct amdgpu_device *adev, | 219 | static 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 | */ |
248 | static void iceland_ih_set_rptr(struct amdgpu_device *adev) | 250 | static 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 | ||
253 | static int iceland_ih_early_init(void *handle) | 256 | static 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 | ||
103 | static u32 si_ih_get_wptr(struct amdgpu_device *adev) | 103 | static 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 | ||
121 | static void si_ih_decode_iv(struct amdgpu_device *adev, | 122 | static 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 | ||
141 | static void si_ih_set_rptr(struct amdgpu_device *adev) | 143 | static 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 | ||
146 | static int si_ih_early_init(void *handle) | 149 | static 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 | */ |
196 | static u32 tonga_ih_get_wptr(struct amdgpu_device *adev) | 196 | static 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 | */ |
229 | static void tonga_ih_decode_iv(struct amdgpu_device *adev, | 230 | static 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 | */ |
259 | static void tonga_ih_set_rptr(struct amdgpu_device *adev) | 261 | static 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 | */ |
194 | static u32 vega10_ih_get_wptr(struct amdgpu_device *adev) | 194 | static 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 | */ |
230 | static void vega10_ih_decode_iv(struct amdgpu_device *adev, | 231 | static 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 | */ |
272 | static void vega10_ih_set_rptr(struct amdgpu_device *adev) | 273 | static 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 | ||