X-Git-Url: http://git.monstr.eu/?p=linux-2.6-microblaze.git;a=blobdiff_plain;f=drivers%2Fgpu%2Fdrm%2Fetnaviv%2Fetnaviv_gpu.c;h=c297fffe06eb3021d1a0ac22fad55573dc5b206c;hp=c6404b8d067f10279221dad7eb925a1650ae7534;hb=432f51e7deedadceaf99a953a6f0a7b30c8155f9;hpb=0eac1102e94807023e57d032bbba51830928b78e diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index c6404b8d067f..c297fffe06eb 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; @@ -605,6 +613,12 @@ static void etnaviv_gpu_enable_mlcg(struct etnaviv_gpu *gpu) etnaviv_is_model_rev(gpu, GC2000, 0x5108)) pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_TX; + /* Disable SE, RA and TX clock gating on affected core revisions. */ + if (etnaviv_is_model_rev(gpu, GC7000, 0x6202)) + pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_SE | + VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_RA | + VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_TX; + pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_RA_HZ; pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_RA_EZ; @@ -724,6 +738,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); @@ -766,28 +781,6 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu) if (ret) 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 @@ -804,6 +797,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 +1789,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);