android_kernel_samsung_sm86.../qcom/opensource/graphics-kernel/kgsl_iommu.h
David Wronek 880d405719 Add 'qcom/opensource/graphics-kernel/' from commit 'b4fdc4c04295ac59109ae19d64747522740c3f14'
git-subtree-dir: qcom/opensource/graphics-kernel
git-subtree-mainline: 992813d9c1
git-subtree-split: b4fdc4c042
Change-Id:
repo: https://git.codelinaro.org/clo/la/platform/vendor/qcom/opensource/graphics-kernel
tag: GRAPHICS.LA.14.0.r1-07700-lanai.0
2024-10-06 16:44:56 +02:00

215 lines
7.0 KiB
C

/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __KGSL_IOMMU_H
#define __KGSL_IOMMU_H
#include <linux/adreno-smmu-priv.h>
#include <linux/io-pgtable.h>
/*
* These defines control the address range for allocations that
* are mapped into all pagetables.
*/
#define KGSL_IOMMU_GLOBAL_MEM_SIZE (20 * SZ_1M)
#define KGSL_IOMMU_GLOBAL_MEM_BASE32 0xf8000000
#define KGSL_IOMMU_GLOBAL_MEM_BASE64 \
(KGSL_MEMSTORE_TOKEN_ADDRESS - KGSL_IOMMU_GLOBAL_MEM_SIZE)
/*
* This is a dummy token address that we use to identify memstore when the user
* wants to map it. mmap() uses a unsigned long for the offset so we need a 32
* bit value that works with all sized apps. We chose a value that was purposely
* unmapped so if you increase the global memory size make sure it doesn't
* conflict
*/
#define KGSL_MEMSTORE_TOKEN_ADDRESS (KGSL_IOMMU_SECURE_BASE32 - SZ_4K)
#define KGSL_IOMMU_GLOBAL_MEM_BASE(__mmu) \
(test_bit(KGSL_MMU_64BIT, &(__mmu)->features) ? \
KGSL_IOMMU_GLOBAL_MEM_BASE64 : KGSL_IOMMU_GLOBAL_MEM_BASE32)
#define KGSL_IOMMU_SVM_BASE32(__mmu) \
(ADRENO_DEVICE(KGSL_MMU_DEVICE(__mmu))->uche_gmem_base + \
ADRENO_DEVICE(KGSL_MMU_DEVICE(__mmu))->gpucore->gmem_size)
#define KGSL_IOMMU_SVM_END32(__mmu) \
(test_bit(KGSL_MMU_64BIT, &(__mmu)->features) ? \
(test_bit(KGSL_MMU_IOPGTABLE, &(__mmu)->features) ? \
KGSL_MEMSTORE_TOKEN_ADDRESS : \
KGSL_IOMMU_GLOBAL_MEM_BASE64) : \
(0xC0000000 - SZ_16M))
/*
* Limit secure size to 256MB for 32bit kernels.
*/
#define KGSL_IOMMU_SECURE_SIZE32 SZ_256M
#define KGSL_IOMMU_SECURE_BASE32 \
(KGSL_IOMMU_SECURE_BASE64 - KGSL_IOMMU_SECURE_SIZE32)
#define KGSL_IOMMU_SECURE_END32 KGSL_IOMMU_SECURE_BASE64
#define KGSL_IOMMU_SECURE_BASE64 0x100000000ULL
#define KGSL_IOMMU_SECURE_END64 \
(KGSL_IOMMU_SECURE_BASE64 + KGSL_IOMMU_SECURE_SIZE64)
#define KGSL_IOMMU_MAX_SECURE_SIZE 0xFFFFF000
#define KGSL_IOMMU_SECURE_SIZE64 \
(KGSL_IOMMU_MAX_SECURE_SIZE - KGSL_IOMMU_SECURE_SIZE32)
#define KGSL_IOMMU_SECURE_BASE(_mmu) (test_bit(KGSL_MMU_64BIT, \
&(_mmu)->features) ? KGSL_IOMMU_SECURE_BASE64 : \
KGSL_IOMMU_SECURE_BASE32)
#define KGSL_IOMMU_SECURE_END(_mmu) (test_bit(KGSL_MMU_64BIT, \
&(_mmu)->features) ? KGSL_IOMMU_SECURE_END64 : \
KGSL_IOMMU_SECURE_END32)
#define KGSL_IOMMU_SECURE_SIZE(_mmu) (test_bit(KGSL_MMU_64BIT, \
&(_mmu)->features) ? KGSL_IOMMU_MAX_SECURE_SIZE : \
KGSL_IOMMU_SECURE_SIZE32)
/* The CPU supports 39 bit addresses */
#define KGSL_IOMMU_SVM_BASE64 0x1000000000ULL
#define KGSL_IOMMU_SVM_END64 0x4000000000ULL
#define KGSL_IOMMU_VA_BASE64 0x4000000000ULL
#define KGSL_IOMMU_VA_END64 0x8000000000ULL
#define CP_APERTURE_REG 0
#define CP_SMMU_APERTURE_ID 0x1B
/* Global SMMU register offsets */
#define KGSL_IOMMU_PRR_CFG_LADDR 0x6008
#define KGSL_IOMMU_PRR_CFG_UADDR 0x600c
/* Register offsets */
#define KGSL_IOMMU_CTX_SCTLR 0x0000
#define KGSL_IOMMU_CTX_ACTLR 0x0004
#define KGSL_IOMMU_CTX_TTBR0 0x0020
#define KGSL_IOMMU_CTX_CONTEXTIDR 0x0034
#define KGSL_IOMMU_CTX_FSR 0x0058
#define KGSL_IOMMU_CTX_TLBIALL 0x0618
#define KGSL_IOMMU_CTX_RESUME 0x0008
#define KGSL_IOMMU_CTX_FSYNR0 0x0068
#define KGSL_IOMMU_CTX_FSYNR1 0x006c
#define KGSL_IOMMU_CTX_TLBSYNC 0x07f0
#define KGSL_IOMMU_CTX_TLBSTATUS 0x07f4
/* TLBSTATUS register fields */
#define KGSL_IOMMU_CTX_TLBSTATUS_SACTIVE BIT(0)
/* SCTLR fields */
#define KGSL_IOMMU_SCTLR_HUPCF_SHIFT 8
#define KGSL_IOMMU_SCTLR_CFCFG_SHIFT 7
#define KGSL_IOMMU_SCTLR_CFIE_SHIFT 6
#define KGSL_IOMMU_ACTLR_PRR_ENABLE BIT(5)
/* FSR fields */
#define KGSL_IOMMU_FSR_SS_SHIFT 30
/* ASID field in TTBR register */
#define KGSL_IOMMU_ASID_START_BIT 48
/* offset at which a nop command is placed in setstate */
#define KGSL_IOMMU_SETSTATE_NOP_OFFSET 1024
/*
* struct kgsl_iommu_context - Structure holding data about an iommu context
* bank
* @pdev: pointer to the iommu context's platform device
* @name: context name
* @id: The id of the context, used for deciding how it is used.
* @cb_num: The hardware context bank number, used for calculating register
* offsets.
* @kgsldev: The kgsl device that uses this context.
* @stalled_on_fault: Flag when set indicates that this iommu device is stalled
* on a page fault
*/
struct kgsl_iommu_context {
struct platform_device *pdev;
const char *name;
int cb_num;
struct kgsl_device *kgsldev;
bool stalled_on_fault;
/** ratelimit: Ratelimit state for the context */
struct ratelimit_state ratelimit;
struct iommu_domain *domain;
struct adreno_smmu_priv adreno_smmu;
};
/*
* struct kgsl_iommu - Structure holding iommu data for kgsl driver
* @regbase: Virtual address of the IOMMU register base
* @regstart: Physical address of the iommu registers
* @regsize: Length of the iommu register region.
* @setstate: Scratch GPU memory for IOMMU operations
* @clk_enable_count: The ref count of clock enable calls
* @clks: Array of pointers to IOMMU clocks
* @smmu_info: smmu info used in a5xx preemption
*/
struct kgsl_iommu {
/** @user_context: Container for the user iommu context */
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;
struct kgsl_memdesc *setstate;
atomic_t clk_enable_count;
struct clk_bulk_data *clks;
int num_clks;
struct kgsl_memdesc *smmu_info;
/** @pdev: Pointer to the platform device for the IOMMU device */
struct platform_device *pdev;
/**
* @ppt_active: Set when the first per process pagetable is created.
* This is used to warn when global buffers are created that might not
* 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;
/** @cx_gdsc: CX GDSC handle in case the IOMMU needs it */
struct regulator *cx_gdsc;
};
/*
* struct kgsl_iommu_pt - Iommu pagetable structure private to kgsl driver
* @base: Container of the base kgsl pagetable
* @ttbr0: register value to set when using this pagetable
* @pgtbl_ops: Pagetable operations for mapping/unmapping buffers
* @info: Pagetable info used to allocate pagetable operations
*/
struct kgsl_iommu_pt {
struct kgsl_pagetable base;
u64 ttbr0;
struct io_pgtable_ops *pgtbl_ops;
struct qcom_io_pgtable_info info;
};
/**
* kgsl_set_smmu_aperture - set SMMU Aperture for user context
* @device: A GPU device handle
*
* Return: 0 on success or negative on failure.
*/
int kgsl_set_smmu_aperture(struct kgsl_device *device,
struct kgsl_iommu_context *context);
/**
* kgsl_set_smmu_lpac_aperture - set SMMU Aperture for LPAC context
* @device: Pointer to the KGSL device
* @context: Pointer to the LPAC iommu context
*
* Return: 0 on success or negative on failure.
*/
int kgsl_set_smmu_lpac_aperture(struct kgsl_device *device,
struct kgsl_iommu_context *context);
#endif