drm/msm: implement a2xx mmu
A2XX has its own very simple MMU. Added a msm_use_mmu() function because we can't rely on iommu_present to decide to use MMU or not. Signed-off-by: Jonathan Marek <jonathan@marek.ca> Signed-off-by: Rob Clark <robdclark@gmail.com>
This commit is contained in:

committed by
Rob Clark

parent
d1d9d0e172
commit
c2052a4e5c
@@ -2,6 +2,8 @@
|
||||
/* Copyright (c) 2018 The Linux Foundation. All rights reserved. */
|
||||
|
||||
#include "a2xx_gpu.h"
|
||||
#include "msm_gem.h"
|
||||
#include "msm_mmu.h"
|
||||
|
||||
extern bool hang_debug;
|
||||
|
||||
@@ -58,9 +60,12 @@ static bool a2xx_me_init(struct msm_gpu *gpu)
|
||||
static int a2xx_hw_init(struct msm_gpu *gpu)
|
||||
{
|
||||
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
|
||||
dma_addr_t pt_base, tran_error;
|
||||
uint32_t *ptr, len;
|
||||
int i, ret;
|
||||
|
||||
msm_gpummu_params(gpu->aspace->mmu, &pt_base, &tran_error);
|
||||
|
||||
DBG("%s", gpu->name);
|
||||
|
||||
/* halt ME to avoid ucode upload issues on a20x */
|
||||
@@ -80,9 +85,34 @@ static int a2xx_hw_init(struct msm_gpu *gpu)
|
||||
/* note: kgsl uses 0x0000ffff for a20x */
|
||||
gpu_write(gpu, REG_A2XX_RBBM_CNTL, 0x00004442);
|
||||
|
||||
gpu_write(gpu, REG_A2XX_MH_MMU_CONFIG, 0);
|
||||
gpu_write(gpu, REG_A2XX_MH_MMU_MPU_BASE, 0);
|
||||
/* MPU: physical range */
|
||||
gpu_write(gpu, REG_A2XX_MH_MMU_MPU_BASE, 0x00000000);
|
||||
gpu_write(gpu, REG_A2XX_MH_MMU_MPU_END, 0xfffff000);
|
||||
|
||||
gpu_write(gpu, REG_A2XX_MH_MMU_CONFIG, A2XX_MH_MMU_CONFIG_MMU_ENABLE |
|
||||
A2XX_MH_MMU_CONFIG_RB_W_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
|
||||
A2XX_MH_MMU_CONFIG_CP_W_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
|
||||
A2XX_MH_MMU_CONFIG_CP_R0_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
|
||||
A2XX_MH_MMU_CONFIG_CP_R1_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
|
||||
A2XX_MH_MMU_CONFIG_CP_R2_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
|
||||
A2XX_MH_MMU_CONFIG_CP_R3_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
|
||||
A2XX_MH_MMU_CONFIG_CP_R4_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
|
||||
A2XX_MH_MMU_CONFIG_VGT_R0_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
|
||||
A2XX_MH_MMU_CONFIG_VGT_R1_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
|
||||
A2XX_MH_MMU_CONFIG_TC_R_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
|
||||
A2XX_MH_MMU_CONFIG_PA_W_CLNT_BEHAVIOR(BEH_TRAN_RNG));
|
||||
|
||||
/* same as parameters in adreno_gpu */
|
||||
gpu_write(gpu, REG_A2XX_MH_MMU_VA_RANGE, SZ_16M |
|
||||
A2XX_MH_MMU_VA_RANGE_NUM_64KB_REGIONS(0xfff));
|
||||
|
||||
gpu_write(gpu, REG_A2XX_MH_MMU_PT_BASE, pt_base);
|
||||
gpu_write(gpu, REG_A2XX_MH_MMU_TRAN_ERROR, tran_error);
|
||||
|
||||
gpu_write(gpu, REG_A2XX_MH_MMU_INVALIDATE,
|
||||
A2XX_MH_MMU_INVALIDATE_INVALIDATE_ALL |
|
||||
A2XX_MH_MMU_INVALIDATE_INVALIDATE_TC);
|
||||
|
||||
gpu_write(gpu, REG_A2XX_MH_ARBITER_CONFIG,
|
||||
A2XX_MH_ARBITER_CONFIG_SAME_PAGE_LIMIT(16) |
|
||||
A2XX_MH_ARBITER_CONFIG_L1_ARB_ENABLE |
|
||||
@@ -109,9 +139,21 @@ static int a2xx_hw_init(struct msm_gpu *gpu)
|
||||
/* note: gsl doesn't set this */
|
||||
gpu_write(gpu, REG_A2XX_RBBM_DEBUG, 0x00080000);
|
||||
|
||||
gpu_write(gpu, REG_A2XX_RBBM_INT_CNTL, 0);
|
||||
gpu_write(gpu, REG_AXXX_CP_INT_CNTL, 0x80000000); /* RB INT */
|
||||
gpu_write(gpu, REG_A2XX_RBBM_INT_CNTL,
|
||||
A2XX_RBBM_INT_CNTL_RDERR_INT_MASK);
|
||||
gpu_write(gpu, REG_AXXX_CP_INT_CNTL,
|
||||
AXXX_CP_INT_CNTL_T0_PACKET_IN_IB_MASK |
|
||||
AXXX_CP_INT_CNTL_OPCODE_ERROR_MASK |
|
||||
AXXX_CP_INT_CNTL_PROTECTED_MODE_ERROR_MASK |
|
||||
AXXX_CP_INT_CNTL_RESERVED_BIT_ERROR_MASK |
|
||||
AXXX_CP_INT_CNTL_IB_ERROR_MASK |
|
||||
AXXX_CP_INT_CNTL_IB1_INT_MASK |
|
||||
AXXX_CP_INT_CNTL_RB_INT_MASK);
|
||||
gpu_write(gpu, REG_A2XX_SQ_INT_CNTL, 0);
|
||||
gpu_write(gpu, REG_A2XX_MH_INTERRUPT_MASK,
|
||||
A2XX_MH_INTERRUPT_MASK_AXI_READ_ERROR |
|
||||
A2XX_MH_INTERRUPT_MASK_AXI_WRITE_ERROR |
|
||||
A2XX_MH_INTERRUPT_MASK_MMU_PAGE_FAULT);
|
||||
|
||||
for (i = 3; i <= 5; i++)
|
||||
if ((SZ_16K << i) == adreno_gpu->gmem)
|
||||
|
@@ -307,6 +307,7 @@ static int adreno_bind(struct device *dev, struct device *master, void *data)
|
||||
static struct adreno_platform_config config = {};
|
||||
const struct adreno_info *info;
|
||||
struct drm_device *drm = dev_get_drvdata(master);
|
||||
struct msm_drm_private *priv = drm->dev_private;
|
||||
struct msm_gpu *gpu;
|
||||
int ret;
|
||||
|
||||
@@ -329,6 +330,8 @@ static int adreno_bind(struct device *dev, struct device *master, void *data)
|
||||
DBG("Found GPU: %u.%u.%u.%u", config.rev.core, config.rev.major,
|
||||
config.rev.minor, config.rev.patchid);
|
||||
|
||||
priv->is_a2xx = config.rev.core == 2;
|
||||
|
||||
gpu = info->init(drm);
|
||||
if (IS_ERR(gpu)) {
|
||||
dev_warn(drm->dev, "failed to load adreno gpu\n");
|
||||
|
@@ -769,6 +769,9 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
|
||||
|
||||
adreno_gpu_config.va_start = SZ_16M;
|
||||
adreno_gpu_config.va_end = 0xffffffff;
|
||||
/* maximum range of a2xx mmu */
|
||||
if (adreno_is_a2xx(adreno_gpu))
|
||||
adreno_gpu_config.va_end = SZ_16M + 0xfff * SZ_64K;
|
||||
|
||||
adreno_gpu_config.nr_rings = nr_rings;
|
||||
|
||||
|
Reference in New Issue
Block a user