diff options
Diffstat (limited to 'drivers/gpu/drm/etnaviv/etnaviv_gpu.c')
-rw-r--r-- | drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 52 |
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); } |