mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 11:11:45 -04:00
Merge "msm: kgsl: Remove icc path from gmu device"
This commit is contained in:
commit
0300f957f5
8 changed files with 234 additions and 43 deletions
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _A6XX_REG_H
|
||||
|
|
@ -394,6 +394,7 @@
|
|||
|
||||
#define A6XX_RBBM_ISDB_CNT 0x533
|
||||
#define A6XX_RBBM_NC_MODE_CNTL 0X534
|
||||
#define A6XX_RBBM_SNAPSHOT_STATUS 0x535
|
||||
|
||||
#define A6XX_RBBM_SECVID_TRUST_CNTL 0xF400
|
||||
#define A6XX_RBBM_SECVID_TSB_TRUSTED_BASE_LO 0xF800
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "adreno.h"
|
||||
|
|
@ -805,6 +805,22 @@ static void a6xx_snapshot_shader(struct kgsl_device *device,
|
|||
}
|
||||
}
|
||||
|
||||
static void a650_snapshot_mempool(struct kgsl_device *device,
|
||||
struct kgsl_snapshot *snapshot)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
/* set CP_CHICKEN_DBG[StabilizeMVC] to stabilize it while dumping */
|
||||
kgsl_regread(device, A6XX_CP_CHICKEN_DBG, &val);
|
||||
kgsl_regwrite(device, A6XX_CP_CHICKEN_DBG, val | BIT(2));
|
||||
|
||||
kgsl_snapshot_indexed_registers(device, snapshot,
|
||||
A6XX_CP_MEM_POOL_DBG_ADDR, A6XX_CP_MEM_POOL_DBG_DATA,
|
||||
0, 0x2100);
|
||||
|
||||
kgsl_regwrite(device, A6XX_CP_CHICKEN_DBG, val);
|
||||
}
|
||||
|
||||
static void a6xx_snapshot_mempool(struct kgsl_device *device,
|
||||
struct kgsl_snapshot *snapshot)
|
||||
{
|
||||
|
|
@ -817,7 +833,7 @@ static void a6xx_snapshot_mempool(struct kgsl_device *device,
|
|||
|
||||
kgsl_snapshot_indexed_registers(device, snapshot,
|
||||
A6XX_CP_MEM_POOL_DBG_ADDR, A6XX_CP_MEM_POOL_DBG_DATA,
|
||||
0, 0x2060);
|
||||
0, 0x2100);
|
||||
|
||||
/*
|
||||
* Data at offset 0x2000 in the mempool section is the mempool size.
|
||||
|
|
@ -1765,7 +1781,7 @@ void a6xx_snapshot(struct adreno_device *adreno_dev,
|
|||
struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
|
||||
struct adreno_ringbuffer *rb;
|
||||
bool sptprac_on;
|
||||
unsigned int i, roq_size, ucode_dbg_size;
|
||||
unsigned int i, roq_size;
|
||||
|
||||
/* GMU TCM data dumped through AHB */
|
||||
gmu_core_dev_snapshot(device, snapshot);
|
||||
|
|
@ -1814,6 +1830,10 @@ void a6xx_snapshot(struct adreno_device *adreno_dev,
|
|||
if (!gmu_core_dev_gx_is_on(device))
|
||||
return;
|
||||
|
||||
/* Assert the isStatic bit before triggering snapshot */
|
||||
if (adreno_is_a660(adreno_dev))
|
||||
kgsl_regwrite(device, A6XX_RBBM_SNAPSHOT_STATUS, 0x1);
|
||||
|
||||
/* Dump the registers which get affected by crash dumper trigger */
|
||||
kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS,
|
||||
snapshot, a6xx_snapshot_pre_crashdump_regs, NULL);
|
||||
|
|
@ -1846,13 +1866,10 @@ void a6xx_snapshot(struct adreno_device *adreno_dev,
|
|||
A6XX_CP_DRAW_STATE_ADDR, A6XX_CP_DRAW_STATE_DATA,
|
||||
0, 0x100);
|
||||
|
||||
ucode_dbg_size = adreno_is_a650_family(adreno_dev)
|
||||
? 0x7000 : 0x6000;
|
||||
|
||||
/* SQE_UCODE Cache */
|
||||
kgsl_snapshot_indexed_registers(device, snapshot,
|
||||
A6XX_CP_SQE_UCODE_DBG_ADDR, A6XX_CP_SQE_UCODE_DBG_DATA,
|
||||
0, ucode_dbg_size);
|
||||
0, 0x8000);
|
||||
|
||||
/*
|
||||
* CP ROQ dump units is 4dwords. The number of units is stored
|
||||
|
|
@ -1869,7 +1886,10 @@ void a6xx_snapshot(struct adreno_device *adreno_dev,
|
|||
snapshot, a6xx_snapshot_sqe, NULL);
|
||||
|
||||
/* Mempool debug data */
|
||||
a6xx_snapshot_mempool(device, snapshot);
|
||||
if (adreno_is_a650_family(adreno_dev))
|
||||
a650_snapshot_mempool(device, snapshot);
|
||||
else
|
||||
a6xx_snapshot_mempool(device, snapshot);
|
||||
|
||||
if (sptprac_on) {
|
||||
/* Shader memory */
|
||||
|
|
@ -1882,6 +1902,18 @@ void a6xx_snapshot(struct adreno_device *adreno_dev,
|
|||
a6xx_snapshot_dbgahb_regs(device, snapshot);
|
||||
}
|
||||
|
||||
if (adreno_is_a660(adreno_dev)) {
|
||||
u32 val;
|
||||
|
||||
kgsl_regread(device, A6XX_RBBM_SNAPSHOT_STATUS, &val);
|
||||
|
||||
if (!val)
|
||||
dev_err(device->dev,
|
||||
"Interface signals may have changed during snapshot\n");
|
||||
|
||||
kgsl_regwrite(device, A6XX_RBBM_SNAPSHOT_STATUS, 0x0);
|
||||
}
|
||||
|
||||
/* Preemption record */
|
||||
if (adreno_is_preemption_enabled(adreno_dev)) {
|
||||
FOR_EACH_RINGBUFFER(adreno_dev, rb, i) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/interconnect.h>
|
||||
|
|
@ -147,15 +147,28 @@ u32 *kgsl_bus_get_table(struct platform_device *pdev,
|
|||
int kgsl_bus_init(struct kgsl_device *device, struct platform_device *pdev)
|
||||
{
|
||||
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
|
||||
int ret, count;
|
||||
int count;
|
||||
int ddr = of_fdt_get_ddrtype();
|
||||
|
||||
if (ddr >= 0) {
|
||||
char str[32];
|
||||
|
||||
snprintf(str, sizeof(str), "qcom,bus-table-ddr%d", ddr);
|
||||
|
||||
pwr->ddr_table = kgsl_bus_get_table(pdev, str, &count);
|
||||
if (!IS_ERR(pwr->ddr_table))
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Look if a generic table is present */
|
||||
pwr->ddr_table = kgsl_bus_get_table(pdev, "qcom,bus-table-ddr", &count);
|
||||
if (IS_ERR(pwr->ddr_table)) {
|
||||
ret = PTR_ERR(pwr->ddr_table);
|
||||
int ret = PTR_ERR(pwr->ddr_table);
|
||||
|
||||
pwr->ddr_table = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
done:
|
||||
pwr->ddr_table_count = count;
|
||||
|
||||
validate_pwrlevels(device, pwr->ddr_table, pwr->ddr_table_count);
|
||||
|
|
|
|||
|
|
@ -1390,8 +1390,6 @@ static int gmu_probe(struct kgsl_device *device, struct device_node *node)
|
|||
|
||||
gmu->num_gpupwrlevels = pwr->num_pwrlevels + 1;
|
||||
|
||||
gmu->icc_path = of_icc_get(&gmu->pdev->dev, NULL);
|
||||
|
||||
/* Populates RPMh configurations */
|
||||
ret = gmu_rpmh_init(device, gmu);
|
||||
if (ret)
|
||||
|
|
@ -1572,7 +1570,7 @@ static int gmu_start(struct kgsl_device *device)
|
|||
|
||||
/* Vote for minimal DDR BW for GMU to init */
|
||||
level = pwr->pwrlevels[pwr->default_pwrlevel].bus_min;
|
||||
icc_set_bw(gmu->icc_path, 0,
|
||||
icc_set_bw(pwr->icc_path, 0,
|
||||
MBps_to_icc(pwr->ddr_table[level]));
|
||||
|
||||
ret = gmu_dev_ops->rpmh_gpu_pwrctrl(device, GMU_FW_START,
|
||||
|
|
@ -1650,6 +1648,7 @@ static void gmu_stop(struct kgsl_device *device)
|
|||
{
|
||||
struct gmu_device *gmu = KGSL_GMU_DEVICE(device);
|
||||
struct gmu_dev_ops *gmu_dev_ops = GMU_DEVICE_OPS(device);
|
||||
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
|
||||
int ret = 0;
|
||||
|
||||
if (!test_bit(GMU_CLK_ON, &device->gmu_core.flags))
|
||||
|
|
@ -1676,7 +1675,7 @@ static void gmu_stop(struct kgsl_device *device)
|
|||
gmu_disable_clks(device);
|
||||
gmu_disable_gdsc(gmu);
|
||||
|
||||
icc_set_bw(gmu->icc_path, 0, 0);
|
||||
icc_set_bw(pwr->icc_path, 0, 0);
|
||||
return;
|
||||
|
||||
error:
|
||||
|
|
@ -1710,8 +1709,6 @@ static void gmu_remove(struct kgsl_device *device)
|
|||
|
||||
clear_bit(ADRENO_ACD_CTRL, &adreno_dev->pwrctrl_flag);
|
||||
|
||||
icc_put(gmu->icc_path);
|
||||
|
||||
if (gmu->fw_image) {
|
||||
release_firmware(gmu->fw_image);
|
||||
gmu->fw_image = NULL;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
#ifndef __KGSL_GMU_H
|
||||
#define __KGSL_GMU_H
|
||||
|
|
@ -210,8 +210,6 @@ struct gmu_device {
|
|||
unsigned long kmem_bitmap;
|
||||
const struct gmu_vma_entry *vma;
|
||||
unsigned int log_wptr_retention;
|
||||
/** @icc_path: Interconnect path for the GMU */
|
||||
struct icc_path *icc_path;
|
||||
};
|
||||
|
||||
struct gmu_memdesc *gmu_get_memdesc(struct gmu_device *gmu,
|
||||
|
|
|
|||
|
|
@ -567,6 +567,26 @@ iommu_context_by_name(struct kgsl_iommu *iommu, u32 name)
|
|||
return &iommu->user_context;
|
||||
}
|
||||
|
||||
static int kgsl_iommu_lpac_fault_handler(struct iommu_domain *domain,
|
||||
struct device *dev, unsigned long addr, int flags, void *token)
|
||||
{
|
||||
struct kgsl_pagetable *pt = token;
|
||||
struct kgsl_mmu *mmu = pt->mmu;
|
||||
struct kgsl_device *device = KGSL_MMU_DEVICE(mmu);
|
||||
struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu);
|
||||
struct kgsl_iommu_context *ctx = &iommu->lpac_context;
|
||||
u32 fsynr0, fsynr1;
|
||||
|
||||
fsynr0 = KGSL_IOMMU_GET_CTX_REG(ctx, FSYNR0);
|
||||
fsynr1 = KGSL_IOMMU_GET_CTX_REG(ctx, FSYNR1);
|
||||
|
||||
dev_crit(device->dev,
|
||||
"LPAC PAGE FAULT iova=0x%16lx, fsynr0=0x%x, fsynr1=0x%x\n",
|
||||
addr, fsynr0, fsynr1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
|
||||
struct device *dev, unsigned long addr, int flags, void *token)
|
||||
{
|
||||
|
|
@ -1011,11 +1031,7 @@ static int _init_global_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt)
|
|||
struct kgsl_device *device = KGSL_MMU_DEVICE(mmu);
|
||||
int ret = 0;
|
||||
struct kgsl_iommu_pt *iommu_pt = NULL;
|
||||
unsigned int mmu_idr1;
|
||||
unsigned int mmu_pagesize;
|
||||
unsigned int mmu_npages;
|
||||
unsigned int cb_num;
|
||||
unsigned int cb0_offset;
|
||||
struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu);
|
||||
struct kgsl_iommu_context *ctx = &iommu->user_context;
|
||||
|
||||
|
|
@ -1029,8 +1045,8 @@ static int _init_global_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt)
|
|||
DOMAIN_ATTR_PROCID, &pt->name);
|
||||
if (ret) {
|
||||
dev_err(device->dev,
|
||||
"set DOMAIN_ATTR_PROCID failed: %d\n",
|
||||
ret);
|
||||
"%s: set DOMAIN_ATTR_PROCID failed: %d\n",
|
||||
ctx->name, ret);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
|
@ -1048,8 +1064,8 @@ static int _init_global_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt)
|
|||
DOMAIN_ATTR_CONTEXT_BANK, &cb_num);
|
||||
if (ret) {
|
||||
dev_err(device->dev,
|
||||
"get DOMAIN_ATTR_CONTEXT_BANK failed: %d\n",
|
||||
ret);
|
||||
"%s: get DOMAIN_ATTR_CONTEXT_BANK failed: %d\n",
|
||||
ctx->name, ret);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
|
@ -1061,28 +1077,21 @@ static int _init_global_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt)
|
|||
}
|
||||
|
||||
ctx->cb_num = cb_num;
|
||||
mmu_idr1 = readl_relaxed(iommu->regbase + KGSL_IOMMU_IDR1_OFFSET);
|
||||
mmu_pagesize = FIELD_GET(IDR1_PAGESIZE, mmu_idr1) ? SZ_64K : SZ_4K;
|
||||
|
||||
/*
|
||||
* The number of pages in the global address space or translation
|
||||
* bank address space is 2^(NUMPAGENDXB + 1).
|
||||
*/
|
||||
mmu_npages = 1 << (FIELD_GET(IDR1_NUMPAGENDXB, mmu_idr1) + 1);
|
||||
cb0_offset = mmu_pagesize * mmu_npages;
|
||||
ctx->regbase = iommu->regbase + cb0_offset + (cb_num * mmu_pagesize);
|
||||
ctx->regbase = iommu->regbase + iommu->cb0_offset +
|
||||
(cb_num * iommu->pagesize);
|
||||
|
||||
ret = iommu_domain_get_attr(iommu_pt->domain,
|
||||
DOMAIN_ATTR_TTBR0, &iommu_pt->ttbr0);
|
||||
if (ret) {
|
||||
dev_err(device->dev, "get DOMAIN_ATTR_TTBR0 failed: %d\n", ret);
|
||||
dev_err(device->dev, "%s: get DOMAIN_ATTR_TTBR0 failed: %d\n",
|
||||
ctx->name, ret);
|
||||
goto done;
|
||||
}
|
||||
ret = iommu_domain_get_attr(iommu_pt->domain,
|
||||
DOMAIN_ATTR_CONTEXTIDR, &iommu_pt->contextidr);
|
||||
if (ret) {
|
||||
dev_err(device->dev, "get DOMAIN_ATTR_CONTEXTIDR failed: %d\n",
|
||||
ret);
|
||||
dev_err(device->dev, "%s: get DOMAIN_ATTR_CONTEXTIDR failed: %d\n",
|
||||
ctx->name, ret);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
|
@ -1095,6 +1104,61 @@ done:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int _init_global_lpac_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt)
|
||||
{
|
||||
struct kgsl_device *device = KGSL_MMU_DEVICE(mmu);
|
||||
int ret = 0;
|
||||
struct kgsl_iommu_pt *iommu_pt = NULL;
|
||||
unsigned int cb_num;
|
||||
struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu);
|
||||
struct kgsl_iommu_context *ctx = &iommu->lpac_context;
|
||||
|
||||
iommu_pt = _alloc_pt(&ctx->pdev->dev, mmu, pt);
|
||||
|
||||
if (IS_ERR(iommu_pt))
|
||||
return PTR_ERR(iommu_pt);
|
||||
|
||||
_enable_gpuhtw_llc(mmu, iommu_pt);
|
||||
|
||||
ret = _attach_pt(iommu_pt, ctx);
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
iommu_set_fault_handler(iommu_pt->domain,
|
||||
kgsl_iommu_lpac_fault_handler, pt);
|
||||
|
||||
/* Try to get the ID of the context bank */
|
||||
ret = iommu_domain_get_attr(iommu_pt->domain, DOMAIN_ATTR_CONTEXT_BANK,
|
||||
&cb_num);
|
||||
|
||||
/*
|
||||
* If this returns -ENODEV then we can't figure out what the current
|
||||
* context bank is. This isn't fatal, but it does limit our ability to
|
||||
* debug in a pagefault.
|
||||
*/
|
||||
if (ret) {
|
||||
if (ret != -ENODEV) {
|
||||
dev_err(device->dev,
|
||||
"%s: Unable to get DOMAIN_ATTR_CONTEXT_BANK: %d\n",
|
||||
ctx->name, ret);
|
||||
goto done;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ctx->cb_num = cb_num;
|
||||
ctx->regbase = iommu->regbase + iommu->cb0_offset +
|
||||
(cb_num * iommu->pagesize);
|
||||
|
||||
kgsl_iommu_map_globals(mmu, pt);
|
||||
|
||||
done:
|
||||
if (ret)
|
||||
_free_pt(ctx, pt);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_QCOM_SECURE_BUFFER)
|
||||
static int _init_secure_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt)
|
||||
{
|
||||
|
|
@ -1231,6 +1295,9 @@ static int kgsl_iommu_init_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt)
|
|||
case KGSL_MMU_SECURE_PT:
|
||||
return _init_secure_pt(mmu, pt);
|
||||
|
||||
case KGSL_MMU_GLOBAL_LPAC_PT:
|
||||
return _init_global_lpac_pt(mmu, pt);
|
||||
|
||||
default:
|
||||
return _init_per_process_pt(mmu, pt);
|
||||
}
|
||||
|
|
@ -1422,6 +1489,43 @@ static int _setup_user_context(struct kgsl_mmu *mmu)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int _setup_lpac_context(struct kgsl_mmu *mmu)
|
||||
{
|
||||
int ret = 0;
|
||||
struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu);
|
||||
struct kgsl_iommu_context *ctx = &iommu->lpac_context;
|
||||
struct kgsl_iommu_pt *iommu_pt = NULL;
|
||||
|
||||
/* If there was no lpac device node, then we don't need to set it up */
|
||||
if (!ctx->pdev)
|
||||
return 0;
|
||||
|
||||
if (mmu->lpac_pagetable == NULL) {
|
||||
mmu->lpac_pagetable = kgsl_mmu_getpagetable(mmu,
|
||||
KGSL_MMU_GLOBAL_LPAC_PT);
|
||||
/* if we don't have a default pagetable, nothing will work */
|
||||
if (IS_ERR(mmu->lpac_pagetable)) {
|
||||
ret = PTR_ERR(mmu->lpac_pagetable);
|
||||
mmu->lpac_pagetable = NULL;
|
||||
return ret;
|
||||
} else if (mmu->lpac_pagetable == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
iommu_pt = mmu->lpac_pagetable->priv;
|
||||
if (iommu_pt == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
ret = _attach_pt(iommu_pt, ctx);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ctx->default_pt = mmu->lpac_pagetable;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _setup_secure_context(struct kgsl_mmu *mmu)
|
||||
{
|
||||
int ret;
|
||||
|
|
@ -1450,11 +1554,37 @@ static int _setup_secure_context(struct kgsl_mmu *mmu)
|
|||
|
||||
static int kgsl_iommu_set_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt);
|
||||
|
||||
static void get_cb0_offset(struct kgsl_mmu *mmu)
|
||||
{
|
||||
struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu);
|
||||
u32 mmu_idr1, mmu_npages;
|
||||
|
||||
if (iommu->cb0_offset)
|
||||
return;
|
||||
|
||||
kgsl_mmu_enable_clk(mmu);
|
||||
|
||||
mmu_idr1 = readl_relaxed(iommu->regbase + KGSL_IOMMU_IDR1_OFFSET);
|
||||
|
||||
kgsl_mmu_disable_clk(mmu);
|
||||
|
||||
iommu->pagesize = FIELD_GET(IDR1_PAGESIZE, mmu_idr1) ? SZ_64K : SZ_4K;
|
||||
|
||||
/*
|
||||
* The number of pages in the global address space or translation
|
||||
* bank address space is 2^(NUMPAGENDXB + 1).
|
||||
*/
|
||||
mmu_npages = 1 << (FIELD_GET(IDR1_NUMPAGENDXB, mmu_idr1) + 1);
|
||||
iommu->cb0_offset = iommu->pagesize * mmu_npages;
|
||||
}
|
||||
|
||||
static int kgsl_iommu_start(struct kgsl_mmu *mmu)
|
||||
{
|
||||
int status;
|
||||
struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu);
|
||||
|
||||
get_cb0_offset(mmu);
|
||||
|
||||
/* Set the following registers only when the MMU type is QSMMU */
|
||||
if (mmu->subtype != KGSL_IOMMU_SMMU_V500) {
|
||||
/* Enable hazard check from GPU_SMMU_HUM_CFG */
|
||||
|
|
@ -1471,9 +1601,16 @@ static int kgsl_iommu_start(struct kgsl_mmu *mmu)
|
|||
if (status)
|
||||
return status;
|
||||
|
||||
status = _setup_lpac_context(mmu);
|
||||
if (status) {
|
||||
_detach_context(&iommu->user_context);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = _setup_secure_context(mmu);
|
||||
if (status) {
|
||||
_detach_context(&iommu->user_context);
|
||||
_detach_context(&iommu->lpac_context);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
@ -2430,6 +2567,10 @@ static int _kgsl_iommu_probe(struct kgsl_device *device,
|
|||
platform_device_put(pdev);
|
||||
}
|
||||
|
||||
/* Probe "lpac" context bank if the platform demands it */
|
||||
if (!ret)
|
||||
kgsl_iommu_probe_child(device, node,
|
||||
&iommu->lpac_context, "gfx3d_lpac");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -110,6 +110,8 @@ struct kgsl_iommu {
|
|||
struct kgsl_iommu_context user_context;
|
||||
/** @secure_context: Container for the secure iommu context */
|
||||
struct kgsl_iommu_context secure_context;
|
||||
/** @lpac_context: Container for the LPAC iommu context */
|
||||
struct kgsl_iommu_context lpac_context;
|
||||
void __iomem *regbase;
|
||||
unsigned long regstart;
|
||||
unsigned int regsize;
|
||||
|
|
@ -125,6 +127,10 @@ struct kgsl_iommu {
|
|||
* be mapped in all contexts
|
||||
*/
|
||||
bool ppt_active;
|
||||
/** @cb0_offset: Offset of context bank 0 from iommu register base */
|
||||
u32 cb0_offset;
|
||||
/** @pagesize: Size of each context bank register space */
|
||||
u32 pagesize;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
#define KGSL_MMU_GLOBAL_PT 0
|
||||
#define KGSL_MMU_SECURE_PT 1
|
||||
#define KGSL_MMU_GLOBAL_LPAC_PT 2
|
||||
|
||||
#define MMU_DEFAULT_TTBR0(_d) \
|
||||
(kgsl_mmu_pagetable_get_ttbr0((_d)->mmu.defaultpagetable))
|
||||
|
|
@ -144,6 +145,8 @@ struct kgsl_mmu {
|
|||
enum kgsl_mmutype type;
|
||||
u32 subtype;
|
||||
struct kgsl_pagetable *defaultpagetable;
|
||||
/** @lpac_pagetable: Default lpac pagetable object for the MMU */
|
||||
struct kgsl_pagetable *lpac_pagetable;
|
||||
struct kgsl_pagetable *securepagetable;
|
||||
const struct kgsl_mmu_ops *mmu_ops;
|
||||
bool secured;
|
||||
|
|
|
|||
Loading…
Reference in a new issue