Skip to content

Commit

Permalink
drm/msm: Support multiple ringbuffers
Browse files Browse the repository at this point in the history
Add the infrastructure to support the idea of multiple ringbuffers.
Assign each ringbuffer an id and use that as an index for the various
ring specific operations.

The biggest delta is to support legacy fences. Each fence gets its own
sequence number but the legacy functions expect to use a unique integer.
To handle this we return a unique identifier for each submission but
map it to a specific ring/sequence under the covers. Newer users use
a dma_fence pointer anyway so they don't care about the actual sequence
ID or ring.

The actual mechanics for multiple ringbuffers are very target specific
so this code just allows for the possibility but still only defines
one ringbuffer for each target family.

Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
Signed-off-by: Rob Clark <robdclark@gmail.com>
  • Loading branch information
Jordan Crouse authored and robclark committed Oct 28, 2017
1 parent cd414f3 commit f97deca
Show file tree
Hide file tree
Showing 20 changed files with 1,251 additions and 210 deletions.
9 changes: 5 additions & 4 deletions drivers/gpu/drm/msm/adreno/a3xx_gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ static bool a3xx_idle(struct msm_gpu *gpu);

static bool a3xx_me_init(struct msm_gpu *gpu)
{
struct msm_ringbuffer *ring = gpu->rb;
struct msm_ringbuffer *ring = gpu->rb[0];

OUT_PKT3(ring, CP_ME_INIT, 17);
OUT_RING(ring, 0x000003f7);
Expand All @@ -65,7 +65,7 @@ static bool a3xx_me_init(struct msm_gpu *gpu)
OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000);

gpu->funcs->flush(gpu);
gpu->funcs->flush(gpu, ring);
return a3xx_idle(gpu);
}

Expand Down Expand Up @@ -339,7 +339,7 @@ static void a3xx_destroy(struct msm_gpu *gpu)
static bool a3xx_idle(struct msm_gpu *gpu)
{
/* wait for ringbuffer to drain: */
if (!adreno_idle(gpu))
if (!adreno_idle(gpu, gpu->rb[0]))
return false;

/* then wait for GPU to finish: */
Expand Down Expand Up @@ -446,6 +446,7 @@ static const struct adreno_gpu_funcs funcs = {
.recover = a3xx_recover,
.submit = adreno_submit,
.flush = adreno_flush,
.active_ring = adreno_active_ring,
.irq = a3xx_irq,
.destroy = a3xx_destroy,
#ifdef CONFIG_DEBUG_FS
Expand Down Expand Up @@ -491,7 +492,7 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev)
adreno_gpu->registers = a3xx_registers;
adreno_gpu->reg_offsets = a3xx_register_offsets;

ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs);
ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1);
if (ret)
goto fail;

Expand Down
9 changes: 5 additions & 4 deletions drivers/gpu/drm/msm/adreno/a4xx_gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ static void a4xx_enable_hwcg(struct msm_gpu *gpu)

static bool a4xx_me_init(struct msm_gpu *gpu)
{
struct msm_ringbuffer *ring = gpu->rb;
struct msm_ringbuffer *ring = gpu->rb[0];

OUT_PKT3(ring, CP_ME_INIT, 17);
OUT_RING(ring, 0x000003f7);
Expand All @@ -137,7 +137,7 @@ static bool a4xx_me_init(struct msm_gpu *gpu)
OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000);

gpu->funcs->flush(gpu);
gpu->funcs->flush(gpu, ring);
return a4xx_idle(gpu);
}

Expand Down Expand Up @@ -337,7 +337,7 @@ static void a4xx_destroy(struct msm_gpu *gpu)
static bool a4xx_idle(struct msm_gpu *gpu)
{
/* wait for ringbuffer to drain: */
if (!adreno_idle(gpu))
if (!adreno_idle(gpu, gpu->rb[0]))
return false;

/* then wait for GPU to finish: */
Expand Down Expand Up @@ -534,6 +534,7 @@ static const struct adreno_gpu_funcs funcs = {
.recover = a4xx_recover,
.submit = adreno_submit,
.flush = adreno_flush,
.active_ring = adreno_active_ring,
.irq = a4xx_irq,
.destroy = a4xx_destroy,
#ifdef CONFIG_DEBUG_FS
Expand Down Expand Up @@ -573,7 +574,7 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev)
adreno_gpu->registers = a4xx_registers;
adreno_gpu->reg_offsets = a4xx_register_offsets;

ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs);
ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1);
if (ret)
goto fail;

Expand Down
54 changes: 28 additions & 26 deletions drivers/gpu/drm/msm/adreno/a5xx_gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
struct msm_file_private *ctx)
{
struct msm_drm_private *priv = gpu->dev->dev_private;
struct msm_ringbuffer *ring = gpu->rb;
struct msm_ringbuffer *ring = submit->ring;
unsigned int i, ibs = 0;

for (i = 0; i < submit->nr_cmds; i++) {
Expand All @@ -138,15 +138,15 @@ static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
}

OUT_PKT4(ring, REG_A5XX_CP_SCRATCH_REG(2), 1);
OUT_RING(ring, submit->fence->seqno);
OUT_RING(ring, submit->seqno);

OUT_PKT7(ring, CP_EVENT_WRITE, 4);
OUT_RING(ring, CACHE_FLUSH_TS | (1 << 31));
OUT_RING(ring, lower_32_bits(rbmemptr(gpu, fence)));
OUT_RING(ring, upper_32_bits(rbmemptr(gpu, fence)));
OUT_RING(ring, submit->fence->seqno);
OUT_RING(ring, lower_32_bits(rbmemptr(ring, fence)));
OUT_RING(ring, upper_32_bits(rbmemptr(ring, fence)));
OUT_RING(ring, submit->seqno);

gpu->funcs->flush(gpu);
gpu->funcs->flush(gpu, ring);
}

static const struct {
Expand Down Expand Up @@ -262,7 +262,7 @@ void a5xx_set_hwcg(struct msm_gpu *gpu, bool state)
static int a5xx_me_init(struct msm_gpu *gpu)
{
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
struct msm_ringbuffer *ring = gpu->rb;
struct msm_ringbuffer *ring = gpu->rb[0];

OUT_PKT7(ring, CP_ME_INIT, 8);

Expand Down Expand Up @@ -293,9 +293,8 @@ static int a5xx_me_init(struct msm_gpu *gpu)
OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000);

gpu->funcs->flush(gpu);

return a5xx_idle(gpu) ? 0 : -EINVAL;
gpu->funcs->flush(gpu, ring);
return a5xx_idle(gpu, ring) ? 0 : -EINVAL;
}

static struct drm_gem_object *a5xx_ucode_load_bo(struct msm_gpu *gpu,
Expand Down Expand Up @@ -581,11 +580,11 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
* ticking correctly
*/
if (adreno_is_a530(adreno_gpu)) {
OUT_PKT7(gpu->rb, CP_EVENT_WRITE, 1);
OUT_RING(gpu->rb, 0x0F);
OUT_PKT7(gpu->rb[0], CP_EVENT_WRITE, 1);
OUT_RING(gpu->rb[0], 0x0F);

gpu->funcs->flush(gpu);
if (!a5xx_idle(gpu))
gpu->funcs->flush(gpu, gpu->rb[0]);
if (!a5xx_idle(gpu, gpu->rb[0]))
return -EINVAL;
}

Expand All @@ -598,11 +597,11 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
*/
ret = a5xx_zap_shader_init(gpu);
if (!ret) {
OUT_PKT7(gpu->rb, CP_SET_SECURE_MODE, 1);
OUT_RING(gpu->rb, 0x00000000);
OUT_PKT7(gpu->rb[0], CP_SET_SECURE_MODE, 1);
OUT_RING(gpu->rb[0], 0x00000000);

gpu->funcs->flush(gpu);
if (!a5xx_idle(gpu))
gpu->funcs->flush(gpu, gpu->rb[0]);
if (!a5xx_idle(gpu, gpu->rb[0]))
return -EINVAL;
} else {
/* Print a warning so if we die, we know why */
Expand Down Expand Up @@ -676,18 +675,19 @@ static inline bool _a5xx_check_idle(struct msm_gpu *gpu)
A5XX_RBBM_INT_0_MASK_MISC_HANG_DETECT);
}

bool a5xx_idle(struct msm_gpu *gpu)
bool a5xx_idle(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
{
/* wait for CP to drain ringbuffer: */
if (!adreno_idle(gpu))
if (!adreno_idle(gpu, ring))
return false;

if (spin_until(_a5xx_check_idle(gpu))) {
DRM_ERROR("%s: %ps: timeout waiting for GPU to idle: status %8.8X irq %8.8X\n",
DRM_ERROR("%s: %ps: timeout waiting for GPU to idle: status %8.8X irq %8.8X rptr/wptr %d/%d\n",
gpu->name, __builtin_return_address(0),
gpu_read(gpu, REG_A5XX_RBBM_STATUS),
gpu_read(gpu, REG_A5XX_RBBM_INT_0_STATUS));

gpu_read(gpu, REG_A5XX_RBBM_INT_0_STATUS),
gpu_read(gpu, REG_A5XX_CP_RB_RPTR),
gpu_read(gpu, REG_A5XX_CP_RB_WPTR));
return false;
}

Expand Down Expand Up @@ -818,9 +818,10 @@ static void a5xx_fault_detect_irq(struct msm_gpu *gpu)
{
struct drm_device *dev = gpu->dev;
struct msm_drm_private *priv = dev->dev_private;
struct msm_ringbuffer *ring = gpu->funcs->active_ring(gpu);

dev_err(dev->dev, "gpu fault fence %x status %8.8X rb %4.4x/%4.4x ib1 %16.16llX/%4.4x ib2 %16.16llX/%4.4x\n",
gpu->memptrs->fence,
dev_err(dev->dev, "gpu fault ring %d fence %x status %8.8X rb %4.4x/%4.4x ib1 %16.16llX/%4.4x ib2 %16.16llX/%4.4x\n",
ring ? ring->id : -1, ring ? ring->seqno : 0,
gpu_read(gpu, REG_A5XX_RBBM_STATUS),
gpu_read(gpu, REG_A5XX_CP_RB_RPTR),
gpu_read(gpu, REG_A5XX_CP_RB_WPTR),
Expand Down Expand Up @@ -1010,6 +1011,7 @@ static const struct adreno_gpu_funcs funcs = {
.recover = a5xx_recover,
.submit = a5xx_submit,
.flush = adreno_flush,
.active_ring = adreno_active_ring,
.irq = a5xx_irq,
.destroy = a5xx_destroy,
#ifdef CONFIG_DEBUG_FS
Expand Down Expand Up @@ -1045,7 +1047,7 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)

a5xx_gpu->lm_leakage = 0x4E001A;

ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs);
ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1);
if (ret) {
a5xx_destroy(&(a5xx_gpu->base.base));
return ERR_PTR(ret);
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/msm/adreno/a5xx_gpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ static inline int spin_usecs(struct msm_gpu *gpu, uint32_t usecs,
return -ETIMEDOUT;
}

bool a5xx_idle(struct msm_gpu *gpu);
bool a5xx_idle(struct msm_gpu *gpu, struct msm_ringbuffer *ring);
void a5xx_set_hwcg(struct msm_gpu *gpu, bool state);

#endif /* __A5XX_GPU_H__ */
6 changes: 3 additions & 3 deletions drivers/gpu/drm/msm/adreno/a5xx_power.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ static int a5xx_gpmu_init(struct msm_gpu *gpu)
{
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
struct msm_ringbuffer *ring = gpu->rb;
struct msm_ringbuffer *ring = gpu->rb[0];

if (!a5xx_gpu->gpmu_dwords)
return 0;
Expand All @@ -192,9 +192,9 @@ static int a5xx_gpmu_init(struct msm_gpu *gpu)
OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1);
OUT_RING(ring, 1);

gpu->funcs->flush(gpu);
gpu->funcs->flush(gpu, ring);

if (!a5xx_idle(gpu)) {
if (!a5xx_idle(gpu, ring)) {
DRM_ERROR("%s: Unable to load GPMU firmware. GPMU will not be active\n",
gpu->name);
return -EINVAL;
Expand Down
Loading

0 comments on commit f97deca

Please sign in to comment.