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