Skip to content

Commit 4bfdd2a

Browse files
committed
drm/etnaviv: rework linear window offset calculation
The current calculation based on the required_dma mask can be significantly off, so that the linear window only overlaps a small part of the DRAM address space. This can lead to the command buffer being unmappable, which is obviously bad. Rework the linear window offset calculation to be based on the command buffer physical address, making sure that the command buffer is always mappable. Tested-by: Primoz Fiser <[email protected]> Reviewed-by: Christian Gmeiner <[email protected]> Signed-off-by: Lucas Stach <[email protected]>
1 parent 0e63302 commit 4bfdd2a

File tree

1 file changed

+26
-26
lines changed

1 file changed

+26
-26
lines changed

drivers/gpu/drm/etnaviv/etnaviv_gpu.c

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,6 @@
2727
#include "state_hi.xml.h"
2828
#include "cmdstream.xml.h"
2929

30-
#ifndef PHYS_OFFSET
31-
#define PHYS_OFFSET 0
32-
#endif
33-
3430
static const struct platform_device_id gpu_ids[] = {
3531
{ .name = "etnaviv-gpu,2d" },
3632
{ },
@@ -736,6 +732,7 @@ static void etnaviv_gpu_hw_init(struct etnaviv_gpu *gpu)
736732
int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
737733
{
738734
struct etnaviv_drm_private *priv = gpu->drm->dev_private;
735+
dma_addr_t cmdbuf_paddr;
739736
int ret, i;
740737

741738
ret = pm_runtime_get_sync(gpu->dev);
@@ -778,28 +775,6 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
778775
if (ret)
779776
goto fail;
780777

781-
/*
782-
* Set the GPU linear window to be at the end of the DMA window, where
783-
* the CMA area is likely to reside. This ensures that we are able to
784-
* map the command buffers while having the linear window overlap as
785-
* much RAM as possible, so we can optimize mappings for other buffers.
786-
*
787-
* For 3D cores only do this if MC2.0 is present, as with MC1.0 it leads
788-
* to different views of the memory on the individual engines.
789-
*/
790-
if (!(gpu->identity.features & chipFeatures_PIPE_3D) ||
791-
(gpu->identity.minor_features0 & chipMinorFeatures0_MC20)) {
792-
u32 dma_mask = (u32)dma_get_required_mask(gpu->dev);
793-
if (dma_mask < PHYS_OFFSET + SZ_2G)
794-
priv->mmu_global->memory_base = PHYS_OFFSET;
795-
else
796-
priv->mmu_global->memory_base = dma_mask - SZ_2G + 1;
797-
} else if (PHYS_OFFSET >= SZ_2G) {
798-
dev_info(gpu->dev, "Need to move linear window on MC1.0, disabling TS\n");
799-
priv->mmu_global->memory_base = PHYS_OFFSET;
800-
gpu->identity.features &= ~chipFeatures_FAST_CLEAR;
801-
}
802-
803778
/*
804779
* If the GPU is part of a system with DMA addressing limitations,
805780
* request pages for our SHM backend buffers from the DMA32 zone to
@@ -816,6 +791,31 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
816791
goto fail;
817792
}
818793

794+
/*
795+
* Set the GPU linear window to cover the cmdbuf region, as the GPU
796+
* won't be able to start execution otherwise. The alignment to 128M is
797+
* chosen arbitrarily but helps in debugging, as the MMU offset
798+
* calculations are much more straight forward this way.
799+
*
800+
* On MC1.0 cores the linear window offset is ignored by the TS engine,
801+
* leading to inconsistent memory views. Avoid using the offset on those
802+
* cores if possible, otherwise disable the TS feature.
803+
*/
804+
cmdbuf_paddr = ALIGN_DOWN(etnaviv_cmdbuf_get_pa(&gpu->buffer), SZ_128M);
805+
806+
if (!(gpu->identity.features & chipFeatures_PIPE_3D) ||
807+
(gpu->identity.minor_features0 & chipMinorFeatures0_MC20)) {
808+
if (cmdbuf_paddr >= SZ_2G)
809+
priv->mmu_global->memory_base = SZ_2G;
810+
else
811+
priv->mmu_global->memory_base = cmdbuf_paddr;
812+
} else if (cmdbuf_paddr + SZ_128M >= SZ_2G) {
813+
dev_info(gpu->dev,
814+
"Need to move linear window on MC1.0, disabling TS\n");
815+
gpu->identity.features &= ~chipFeatures_FAST_CLEAR;
816+
priv->mmu_global->memory_base = SZ_2G;
817+
}
818+
819819
/* Setup event management */
820820
spin_lock_init(&gpu->event_spinlock);
821821
init_completion(&gpu->event_free);

0 commit comments

Comments
 (0)