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.c68
1 files changed, 39 insertions, 29 deletions
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
index c6404b8d067f..4102bcea3341 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
@@ -27,10 +27,6 @@
#include "state_hi.xml.h"
#include "cmdstream.xml.h"
-#ifndef PHYS_OFFSET
-#define PHYS_OFFSET 0
-#endif
-
static const struct platform_device_id gpu_ids[] = {
{ .name = "etnaviv-gpu,2d" },
{ },
@@ -156,6 +152,18 @@ int etnaviv_gpu_get_param(struct etnaviv_gpu *gpu, u32 param, u64 *value)
*value = ~0ULL;
break;
+ case ETNAVIV_PARAM_GPU_PRODUCT_ID:
+ *value = gpu->identity.product_id;
+ break;
+
+ case ETNAVIV_PARAM_GPU_CUSTOMER_ID:
+ *value = gpu->identity.customer_id;
+ break;
+
+ case ETNAVIV_PARAM_GPU_ECO_ID:
+ *value = gpu->identity.eco_id;
+ break;
+
default:
DBG("%s: invalid param: %u", dev_name(gpu->dev), param);
return -EINVAL;
@@ -724,6 +732,7 @@ static void etnaviv_gpu_hw_init(struct etnaviv_gpu *gpu)
int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
{
struct etnaviv_drm_private *priv = gpu->drm->dev_private;
+ dma_addr_t cmdbuf_paddr;
int ret, i;
ret = pm_runtime_get_sync(gpu->dev);
@@ -767,28 +776,6 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
goto fail;
/*
- * Set the GPU linear window to be at the end of the DMA window, where
- * the CMA area is likely to reside. This ensures that we are able to
- * map the command buffers while having the linear window overlap as
- * much RAM as possible, so we can optimize mappings for other buffers.
- *
- * For 3D cores only do this if MC2.0 is present, as with MC1.0 it leads
- * to different views of the memory on the individual engines.
- */
- if (!(gpu->identity.features & chipFeatures_PIPE_3D) ||
- (gpu->identity.minor_features0 & chipMinorFeatures0_MC20)) {
- u32 dma_mask = (u32)dma_get_required_mask(gpu->dev);
- if (dma_mask < PHYS_OFFSET + SZ_2G)
- priv->mmu_global->memory_base = PHYS_OFFSET;
- else
- priv->mmu_global->memory_base = dma_mask - SZ_2G + 1;
- } else if (PHYS_OFFSET >= SZ_2G) {
- dev_info(gpu->dev, "Need to move linear window on MC1.0, disabling TS\n");
- priv->mmu_global->memory_base = PHYS_OFFSET;
- 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.
@@ -804,6 +791,31 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
goto fail;
}
+ /*
+ * Set the GPU linear window to cover the cmdbuf region, as the GPU
+ * won't be able to start execution otherwise. The alignment to 128M is
+ * chosen arbitrarily but helps in debugging, as the MMU offset
+ * calculations are much more straight forward this way.
+ *
+ * On MC1.0 cores the linear window offset is ignored by the TS engine,
+ * leading to inconsistent memory views. Avoid using the offset on those
+ * cores if possible, otherwise disable the TS feature.
+ */
+ cmdbuf_paddr = ALIGN_DOWN(etnaviv_cmdbuf_get_pa(&gpu->buffer), SZ_128M);
+
+ if (!(gpu->identity.features & chipFeatures_PIPE_3D) ||
+ (gpu->identity.minor_features0 & chipMinorFeatures0_MC20)) {
+ if (cmdbuf_paddr >= SZ_2G)
+ priv->mmu_global->memory_base = SZ_2G;
+ else
+ priv->mmu_global->memory_base = cmdbuf_paddr;
+ } else if (cmdbuf_paddr + SZ_128M >= SZ_2G) {
+ dev_info(gpu->dev,
+ "Need to move linear window on MC1.0, disabling TS\n");
+ gpu->identity.features &= ~chipFeatures_FAST_CLEAR;
+ priv->mmu_global->memory_base = SZ_2G;
+ }
+
/* Setup event management */
spin_lock_init(&gpu->event_spinlock);
init_completion(&gpu->event_free);
@@ -1771,10 +1783,8 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev)
/* Get Interrupt: */
gpu->irq = platform_get_irq(pdev, 0);
- if (gpu->irq < 0) {
- dev_err(dev, "failed to get irq: %d\n", gpu->irq);
+ if (gpu->irq < 0)
return gpu->irq;
- }
err = devm_request_irq(&pdev->dev, gpu->irq, irq_handler, 0,
dev_name(gpu->dev), gpu);