summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/etnaviv/etnaviv_gpu.c')
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gpu.c52
1 files changed, 47 insertions, 5 deletions
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
index 799ec20b267d..a31eeff2b297 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
@@ -333,9 +333,13 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu)
gpu->identity.revision = etnaviv_field(chipIdentity,
VIVS_HI_CHIP_IDENTITY_REVISION);
} else {
+ u32 chipDate = gpu_read(gpu, VIVS_HI_CHIP_DATE);
gpu->identity.model = gpu_read(gpu, VIVS_HI_CHIP_MODEL);
gpu->identity.revision = gpu_read(gpu, VIVS_HI_CHIP_REV);
+ gpu->identity.product_id = gpu_read(gpu, VIVS_HI_CHIP_PRODUCT_ID);
+ gpu->identity.customer_id = gpu_read(gpu, VIVS_HI_CHIP_CUSTOMER_ID);
+ gpu->identity.eco_id = gpu_read(gpu, VIVS_HI_CHIP_ECO_ID);
/*
* !!!! HACK ALERT !!!!
@@ -350,7 +354,6 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu)
/* Another special case */
if (etnaviv_is_model_rev(gpu, GC300, 0x2201)) {
- u32 chipDate = gpu_read(gpu, VIVS_HI_CHIP_DATE);
u32 chipTime = gpu_read(gpu, VIVS_HI_CHIP_TIME);
if (chipDate == 0x20080814 && chipTime == 0x12051100) {
@@ -373,6 +376,12 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu)
gpu->identity.model = chipModel_GC3000;
gpu->identity.revision &= 0xffff;
}
+
+ if (etnaviv_is_model_rev(gpu, GC1000, 0x5037) && (chipDate == 0x20120617))
+ gpu->identity.eco_id = 1;
+
+ if (etnaviv_is_model_rev(gpu, GC320, 0x5303) && (chipDate == 0x20140511))
+ gpu->identity.eco_id = 1;
}
dev_info(gpu->dev, "model: GC%x, revision: %x\n",
@@ -506,7 +515,7 @@ static int etnaviv_hw_reset(struct etnaviv_gpu *gpu)
/* read idle register. */
idle = gpu_read(gpu, VIVS_HI_IDLE_STATE);
- /* try reseting again if FE it not idle */
+ /* try resetting again if FE is not idle */
if ((idle & VIVS_HI_IDLE_STATE_FE) == 0) {
dev_dbg(gpu->dev, "FE is not idle\n");
continue;
@@ -772,6 +781,14 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
gpu->identity.features &= ~chipFeatures_FAST_CLEAR;
}
+ /*
+ * If the GPU is part of a system with DMA addressing limitations,
+ * request pages for our SHM backend buffers from the DMA32 zone to
+ * hopefully avoid performance killing SWIOTLB bounce buffering.
+ */
+ if (dma_addressing_limited(gpu->dev))
+ priv->shm_gfp_mask |= GFP_DMA32;
+
/* Create buffer: */
ret = etnaviv_cmdbuf_init(priv->cmdbuf_suballoc, &gpu->buffer,
PAGE_SIZE);
@@ -851,6 +868,13 @@ int etnaviv_gpu_debugfs(struct etnaviv_gpu *gpu, struct seq_file *m)
verify_dma(gpu, &debug);
+ seq_puts(m, "\tidentity\n");
+ seq_printf(m, "\t model: 0x%x\n", gpu->identity.model);
+ seq_printf(m, "\t revision: 0x%x\n", gpu->identity.revision);
+ seq_printf(m, "\t product_id: 0x%x\n", gpu->identity.product_id);
+ seq_printf(m, "\t customer_id: 0x%x\n", gpu->identity.customer_id);
+ seq_printf(m, "\t eco_id: 0x%x\n", gpu->identity.eco_id);
+
seq_puts(m, "\tfeatures\n");
seq_printf(m, "\t major_features: 0x%08x\n",
gpu->identity.features);
@@ -930,6 +954,20 @@ int etnaviv_gpu_debugfs(struct etnaviv_gpu *gpu, struct seq_file *m)
seq_puts(m, "\t FP is not idle\n");
if ((idle & VIVS_HI_IDLE_STATE_TS) == 0)
seq_puts(m, "\t TS is not idle\n");
+ if ((idle & VIVS_HI_IDLE_STATE_BL) == 0)
+ seq_puts(m, "\t BL is not idle\n");
+ if ((idle & VIVS_HI_IDLE_STATE_ASYNCFE) == 0)
+ seq_puts(m, "\t ASYNCFE is not idle\n");
+ if ((idle & VIVS_HI_IDLE_STATE_MC) == 0)
+ seq_puts(m, "\t MC is not idle\n");
+ if ((idle & VIVS_HI_IDLE_STATE_PPA) == 0)
+ seq_puts(m, "\t PPA is not idle\n");
+ if ((idle & VIVS_HI_IDLE_STATE_WD) == 0)
+ seq_puts(m, "\t WD is not idle\n");
+ if ((idle & VIVS_HI_IDLE_STATE_NN) == 0)
+ seq_puts(m, "\t NN is not idle\n");
+ if ((idle & VIVS_HI_IDLE_STATE_TP) == 0)
+ seq_puts(m, "\t TP is not idle\n");
if (idle & VIVS_HI_IDLE_STATE_AXI_LP)
seq_puts(m, "\t AXI low power mode\n");
@@ -1805,11 +1843,15 @@ static int etnaviv_gpu_rpm_suspend(struct device *dev)
if (atomic_read(&gpu->sched.hw_rq_count))
return -EBUSY;
- /* Check whether the hardware (except FE) is idle */
- mask = gpu->idle_mask & ~VIVS_HI_IDLE_STATE_FE;
+ /* Check whether the hardware (except FE and MC) is idle */
+ mask = gpu->idle_mask & ~(VIVS_HI_IDLE_STATE_FE |
+ VIVS_HI_IDLE_STATE_MC);
idle = gpu_read(gpu, VIVS_HI_IDLE_STATE) & mask;
- if (idle != mask)
+ if (idle != mask) {
+ dev_warn_ratelimited(dev, "GPU not yet idle, mask: 0x%08x\n",
+ idle);
return -EBUSY;
+ }
return etnaviv_gpu_hw_suspend(gpu);
}