162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * IOMMU API for ARM architected SMMUv3 implementations. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2015 ARM Limited 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#ifndef _ARM_SMMU_V3_H 962306a36Sopenharmony_ci#define _ARM_SMMU_V3_H 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <linux/bitfield.h> 1262306a36Sopenharmony_ci#include <linux/iommu.h> 1362306a36Sopenharmony_ci#include <linux/kernel.h> 1462306a36Sopenharmony_ci#include <linux/mmzone.h> 1562306a36Sopenharmony_ci#include <linux/sizes.h> 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci/* MMIO registers */ 1862306a36Sopenharmony_ci#define ARM_SMMU_IDR0 0x0 1962306a36Sopenharmony_ci#define IDR0_ST_LVL GENMASK(28, 27) 2062306a36Sopenharmony_ci#define IDR0_ST_LVL_2LVL 1 2162306a36Sopenharmony_ci#define IDR0_STALL_MODEL GENMASK(25, 24) 2262306a36Sopenharmony_ci#define IDR0_STALL_MODEL_STALL 0 2362306a36Sopenharmony_ci#define IDR0_STALL_MODEL_FORCE 2 2462306a36Sopenharmony_ci#define IDR0_TTENDIAN GENMASK(22, 21) 2562306a36Sopenharmony_ci#define IDR0_TTENDIAN_MIXED 0 2662306a36Sopenharmony_ci#define IDR0_TTENDIAN_LE 2 2762306a36Sopenharmony_ci#define IDR0_TTENDIAN_BE 3 2862306a36Sopenharmony_ci#define IDR0_CD2L (1 << 19) 2962306a36Sopenharmony_ci#define IDR0_VMID16 (1 << 18) 3062306a36Sopenharmony_ci#define IDR0_PRI (1 << 16) 3162306a36Sopenharmony_ci#define IDR0_SEV (1 << 14) 3262306a36Sopenharmony_ci#define IDR0_MSI (1 << 13) 3362306a36Sopenharmony_ci#define IDR0_ASID16 (1 << 12) 3462306a36Sopenharmony_ci#define IDR0_ATS (1 << 10) 3562306a36Sopenharmony_ci#define IDR0_HYP (1 << 9) 3662306a36Sopenharmony_ci#define IDR0_COHACC (1 << 4) 3762306a36Sopenharmony_ci#define IDR0_TTF GENMASK(3, 2) 3862306a36Sopenharmony_ci#define IDR0_TTF_AARCH64 2 3962306a36Sopenharmony_ci#define IDR0_TTF_AARCH32_64 3 4062306a36Sopenharmony_ci#define IDR0_S1P (1 << 1) 4162306a36Sopenharmony_ci#define IDR0_S2P (1 << 0) 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci#define ARM_SMMU_IDR1 0x4 4462306a36Sopenharmony_ci#define IDR1_TABLES_PRESET (1 << 30) 4562306a36Sopenharmony_ci#define IDR1_QUEUES_PRESET (1 << 29) 4662306a36Sopenharmony_ci#define IDR1_REL (1 << 28) 4762306a36Sopenharmony_ci#define IDR1_CMDQS GENMASK(25, 21) 4862306a36Sopenharmony_ci#define IDR1_EVTQS GENMASK(20, 16) 4962306a36Sopenharmony_ci#define IDR1_PRIQS GENMASK(15, 11) 5062306a36Sopenharmony_ci#define IDR1_SSIDSIZE GENMASK(10, 6) 5162306a36Sopenharmony_ci#define IDR1_SIDSIZE GENMASK(5, 0) 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci#define ARM_SMMU_IDR3 0xc 5462306a36Sopenharmony_ci#define IDR3_RIL (1 << 10) 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci#define ARM_SMMU_IDR5 0x14 5762306a36Sopenharmony_ci#define IDR5_STALL_MAX GENMASK(31, 16) 5862306a36Sopenharmony_ci#define IDR5_GRAN64K (1 << 6) 5962306a36Sopenharmony_ci#define IDR5_GRAN16K (1 << 5) 6062306a36Sopenharmony_ci#define IDR5_GRAN4K (1 << 4) 6162306a36Sopenharmony_ci#define IDR5_OAS GENMASK(2, 0) 6262306a36Sopenharmony_ci#define IDR5_OAS_32_BIT 0 6362306a36Sopenharmony_ci#define IDR5_OAS_36_BIT 1 6462306a36Sopenharmony_ci#define IDR5_OAS_40_BIT 2 6562306a36Sopenharmony_ci#define IDR5_OAS_42_BIT 3 6662306a36Sopenharmony_ci#define IDR5_OAS_44_BIT 4 6762306a36Sopenharmony_ci#define IDR5_OAS_48_BIT 5 6862306a36Sopenharmony_ci#define IDR5_OAS_52_BIT 6 6962306a36Sopenharmony_ci#define IDR5_VAX GENMASK(11, 10) 7062306a36Sopenharmony_ci#define IDR5_VAX_52_BIT 1 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci#define ARM_SMMU_IIDR 0x18 7362306a36Sopenharmony_ci#define IIDR_PRODUCTID GENMASK(31, 20) 7462306a36Sopenharmony_ci#define IIDR_VARIANT GENMASK(19, 16) 7562306a36Sopenharmony_ci#define IIDR_REVISION GENMASK(15, 12) 7662306a36Sopenharmony_ci#define IIDR_IMPLEMENTER GENMASK(11, 0) 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci#define ARM_SMMU_CR0 0x20 7962306a36Sopenharmony_ci#define CR0_ATSCHK (1 << 4) 8062306a36Sopenharmony_ci#define CR0_CMDQEN (1 << 3) 8162306a36Sopenharmony_ci#define CR0_EVTQEN (1 << 2) 8262306a36Sopenharmony_ci#define CR0_PRIQEN (1 << 1) 8362306a36Sopenharmony_ci#define CR0_SMMUEN (1 << 0) 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci#define ARM_SMMU_CR0ACK 0x24 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci#define ARM_SMMU_CR1 0x28 8862306a36Sopenharmony_ci#define CR1_TABLE_SH GENMASK(11, 10) 8962306a36Sopenharmony_ci#define CR1_TABLE_OC GENMASK(9, 8) 9062306a36Sopenharmony_ci#define CR1_TABLE_IC GENMASK(7, 6) 9162306a36Sopenharmony_ci#define CR1_QUEUE_SH GENMASK(5, 4) 9262306a36Sopenharmony_ci#define CR1_QUEUE_OC GENMASK(3, 2) 9362306a36Sopenharmony_ci#define CR1_QUEUE_IC GENMASK(1, 0) 9462306a36Sopenharmony_ci/* CR1 cacheability fields don't quite follow the usual TCR-style encoding */ 9562306a36Sopenharmony_ci#define CR1_CACHE_NC 0 9662306a36Sopenharmony_ci#define CR1_CACHE_WB 1 9762306a36Sopenharmony_ci#define CR1_CACHE_WT 2 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci#define ARM_SMMU_CR2 0x2c 10062306a36Sopenharmony_ci#define CR2_PTM (1 << 2) 10162306a36Sopenharmony_ci#define CR2_RECINVSID (1 << 1) 10262306a36Sopenharmony_ci#define CR2_E2H (1 << 0) 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci#define ARM_SMMU_GBPA 0x44 10562306a36Sopenharmony_ci#define GBPA_UPDATE (1 << 31) 10662306a36Sopenharmony_ci#define GBPA_ABORT (1 << 20) 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci#define ARM_SMMU_IRQ_CTRL 0x50 10962306a36Sopenharmony_ci#define IRQ_CTRL_EVTQ_IRQEN (1 << 2) 11062306a36Sopenharmony_ci#define IRQ_CTRL_PRIQ_IRQEN (1 << 1) 11162306a36Sopenharmony_ci#define IRQ_CTRL_GERROR_IRQEN (1 << 0) 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci#define ARM_SMMU_IRQ_CTRLACK 0x54 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci#define ARM_SMMU_GERROR 0x60 11662306a36Sopenharmony_ci#define GERROR_SFM_ERR (1 << 8) 11762306a36Sopenharmony_ci#define GERROR_MSI_GERROR_ABT_ERR (1 << 7) 11862306a36Sopenharmony_ci#define GERROR_MSI_PRIQ_ABT_ERR (1 << 6) 11962306a36Sopenharmony_ci#define GERROR_MSI_EVTQ_ABT_ERR (1 << 5) 12062306a36Sopenharmony_ci#define GERROR_MSI_CMDQ_ABT_ERR (1 << 4) 12162306a36Sopenharmony_ci#define GERROR_PRIQ_ABT_ERR (1 << 3) 12262306a36Sopenharmony_ci#define GERROR_EVTQ_ABT_ERR (1 << 2) 12362306a36Sopenharmony_ci#define GERROR_CMDQ_ERR (1 << 0) 12462306a36Sopenharmony_ci#define GERROR_ERR_MASK 0x1fd 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci#define ARM_SMMU_GERRORN 0x64 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci#define ARM_SMMU_GERROR_IRQ_CFG0 0x68 12962306a36Sopenharmony_ci#define ARM_SMMU_GERROR_IRQ_CFG1 0x70 13062306a36Sopenharmony_ci#define ARM_SMMU_GERROR_IRQ_CFG2 0x74 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci#define ARM_SMMU_STRTAB_BASE 0x80 13362306a36Sopenharmony_ci#define STRTAB_BASE_RA (1UL << 62) 13462306a36Sopenharmony_ci#define STRTAB_BASE_ADDR_MASK GENMASK_ULL(51, 6) 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci#define ARM_SMMU_STRTAB_BASE_CFG 0x88 13762306a36Sopenharmony_ci#define STRTAB_BASE_CFG_FMT GENMASK(17, 16) 13862306a36Sopenharmony_ci#define STRTAB_BASE_CFG_FMT_LINEAR 0 13962306a36Sopenharmony_ci#define STRTAB_BASE_CFG_FMT_2LVL 1 14062306a36Sopenharmony_ci#define STRTAB_BASE_CFG_SPLIT GENMASK(10, 6) 14162306a36Sopenharmony_ci#define STRTAB_BASE_CFG_LOG2SIZE GENMASK(5, 0) 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci#define ARM_SMMU_CMDQ_BASE 0x90 14462306a36Sopenharmony_ci#define ARM_SMMU_CMDQ_PROD 0x98 14562306a36Sopenharmony_ci#define ARM_SMMU_CMDQ_CONS 0x9c 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci#define ARM_SMMU_EVTQ_BASE 0xa0 14862306a36Sopenharmony_ci#define ARM_SMMU_EVTQ_PROD 0xa8 14962306a36Sopenharmony_ci#define ARM_SMMU_EVTQ_CONS 0xac 15062306a36Sopenharmony_ci#define ARM_SMMU_EVTQ_IRQ_CFG0 0xb0 15162306a36Sopenharmony_ci#define ARM_SMMU_EVTQ_IRQ_CFG1 0xb8 15262306a36Sopenharmony_ci#define ARM_SMMU_EVTQ_IRQ_CFG2 0xbc 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci#define ARM_SMMU_PRIQ_BASE 0xc0 15562306a36Sopenharmony_ci#define ARM_SMMU_PRIQ_PROD 0xc8 15662306a36Sopenharmony_ci#define ARM_SMMU_PRIQ_CONS 0xcc 15762306a36Sopenharmony_ci#define ARM_SMMU_PRIQ_IRQ_CFG0 0xd0 15862306a36Sopenharmony_ci#define ARM_SMMU_PRIQ_IRQ_CFG1 0xd8 15962306a36Sopenharmony_ci#define ARM_SMMU_PRIQ_IRQ_CFG2 0xdc 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci#define ARM_SMMU_REG_SZ 0xe00 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci/* Common MSI config fields */ 16462306a36Sopenharmony_ci#define MSI_CFG0_ADDR_MASK GENMASK_ULL(51, 2) 16562306a36Sopenharmony_ci#define MSI_CFG2_SH GENMASK(5, 4) 16662306a36Sopenharmony_ci#define MSI_CFG2_MEMATTR GENMASK(3, 0) 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci/* Common memory attribute values */ 16962306a36Sopenharmony_ci#define ARM_SMMU_SH_NSH 0 17062306a36Sopenharmony_ci#define ARM_SMMU_SH_OSH 2 17162306a36Sopenharmony_ci#define ARM_SMMU_SH_ISH 3 17262306a36Sopenharmony_ci#define ARM_SMMU_MEMATTR_DEVICE_nGnRE 0x1 17362306a36Sopenharmony_ci#define ARM_SMMU_MEMATTR_OIWB 0xf 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci#define Q_IDX(llq, p) ((p) & ((1 << (llq)->max_n_shift) - 1)) 17662306a36Sopenharmony_ci#define Q_WRP(llq, p) ((p) & (1 << (llq)->max_n_shift)) 17762306a36Sopenharmony_ci#define Q_OVERFLOW_FLAG (1U << 31) 17862306a36Sopenharmony_ci#define Q_OVF(p) ((p) & Q_OVERFLOW_FLAG) 17962306a36Sopenharmony_ci#define Q_ENT(q, p) ((q)->base + \ 18062306a36Sopenharmony_ci Q_IDX(&((q)->llq), p) * \ 18162306a36Sopenharmony_ci (q)->ent_dwords) 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci#define Q_BASE_RWA (1UL << 62) 18462306a36Sopenharmony_ci#define Q_BASE_ADDR_MASK GENMASK_ULL(51, 5) 18562306a36Sopenharmony_ci#define Q_BASE_LOG2SIZE GENMASK(4, 0) 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci/* Ensure DMA allocations are naturally aligned */ 18862306a36Sopenharmony_ci#ifdef CONFIG_CMA_ALIGNMENT 18962306a36Sopenharmony_ci#define Q_MAX_SZ_SHIFT (PAGE_SHIFT + CONFIG_CMA_ALIGNMENT) 19062306a36Sopenharmony_ci#else 19162306a36Sopenharmony_ci#define Q_MAX_SZ_SHIFT (PAGE_SHIFT + MAX_ORDER) 19262306a36Sopenharmony_ci#endif 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci/* 19562306a36Sopenharmony_ci * Stream table. 19662306a36Sopenharmony_ci * 19762306a36Sopenharmony_ci * Linear: Enough to cover 1 << IDR1.SIDSIZE entries 19862306a36Sopenharmony_ci * 2lvl: 128k L1 entries, 19962306a36Sopenharmony_ci * 256 lazy entries per table (each table covers a PCI bus) 20062306a36Sopenharmony_ci */ 20162306a36Sopenharmony_ci#define STRTAB_L1_SZ_SHIFT 20 20262306a36Sopenharmony_ci#define STRTAB_SPLIT 8 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci#define STRTAB_L1_DESC_DWORDS 1 20562306a36Sopenharmony_ci#define STRTAB_L1_DESC_SPAN GENMASK_ULL(4, 0) 20662306a36Sopenharmony_ci#define STRTAB_L1_DESC_L2PTR_MASK GENMASK_ULL(51, 6) 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci#define STRTAB_STE_DWORDS 8 20962306a36Sopenharmony_ci#define STRTAB_STE_0_V (1UL << 0) 21062306a36Sopenharmony_ci#define STRTAB_STE_0_CFG GENMASK_ULL(3, 1) 21162306a36Sopenharmony_ci#define STRTAB_STE_0_CFG_ABORT 0 21262306a36Sopenharmony_ci#define STRTAB_STE_0_CFG_BYPASS 4 21362306a36Sopenharmony_ci#define STRTAB_STE_0_CFG_S1_TRANS 5 21462306a36Sopenharmony_ci#define STRTAB_STE_0_CFG_S2_TRANS 6 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci#define STRTAB_STE_0_S1FMT GENMASK_ULL(5, 4) 21762306a36Sopenharmony_ci#define STRTAB_STE_0_S1FMT_LINEAR 0 21862306a36Sopenharmony_ci#define STRTAB_STE_0_S1FMT_64K_L2 2 21962306a36Sopenharmony_ci#define STRTAB_STE_0_S1CTXPTR_MASK GENMASK_ULL(51, 6) 22062306a36Sopenharmony_ci#define STRTAB_STE_0_S1CDMAX GENMASK_ULL(63, 59) 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci#define STRTAB_STE_1_S1DSS GENMASK_ULL(1, 0) 22362306a36Sopenharmony_ci#define STRTAB_STE_1_S1DSS_TERMINATE 0x0 22462306a36Sopenharmony_ci#define STRTAB_STE_1_S1DSS_BYPASS 0x1 22562306a36Sopenharmony_ci#define STRTAB_STE_1_S1DSS_SSID0 0x2 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci#define STRTAB_STE_1_S1C_CACHE_NC 0UL 22862306a36Sopenharmony_ci#define STRTAB_STE_1_S1C_CACHE_WBRA 1UL 22962306a36Sopenharmony_ci#define STRTAB_STE_1_S1C_CACHE_WT 2UL 23062306a36Sopenharmony_ci#define STRTAB_STE_1_S1C_CACHE_WB 3UL 23162306a36Sopenharmony_ci#define STRTAB_STE_1_S1CIR GENMASK_ULL(3, 2) 23262306a36Sopenharmony_ci#define STRTAB_STE_1_S1COR GENMASK_ULL(5, 4) 23362306a36Sopenharmony_ci#define STRTAB_STE_1_S1CSH GENMASK_ULL(7, 6) 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci#define STRTAB_STE_1_S1STALLD (1UL << 27) 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci#define STRTAB_STE_1_EATS GENMASK_ULL(29, 28) 23862306a36Sopenharmony_ci#define STRTAB_STE_1_EATS_ABT 0UL 23962306a36Sopenharmony_ci#define STRTAB_STE_1_EATS_TRANS 1UL 24062306a36Sopenharmony_ci#define STRTAB_STE_1_EATS_S1CHK 2UL 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci#define STRTAB_STE_1_STRW GENMASK_ULL(31, 30) 24362306a36Sopenharmony_ci#define STRTAB_STE_1_STRW_NSEL1 0UL 24462306a36Sopenharmony_ci#define STRTAB_STE_1_STRW_EL2 2UL 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci#define STRTAB_STE_1_SHCFG GENMASK_ULL(45, 44) 24762306a36Sopenharmony_ci#define STRTAB_STE_1_SHCFG_INCOMING 1UL 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci#define STRTAB_STE_2_S2VMID GENMASK_ULL(15, 0) 25062306a36Sopenharmony_ci#define STRTAB_STE_2_VTCR GENMASK_ULL(50, 32) 25162306a36Sopenharmony_ci#define STRTAB_STE_2_VTCR_S2T0SZ GENMASK_ULL(5, 0) 25262306a36Sopenharmony_ci#define STRTAB_STE_2_VTCR_S2SL0 GENMASK_ULL(7, 6) 25362306a36Sopenharmony_ci#define STRTAB_STE_2_VTCR_S2IR0 GENMASK_ULL(9, 8) 25462306a36Sopenharmony_ci#define STRTAB_STE_2_VTCR_S2OR0 GENMASK_ULL(11, 10) 25562306a36Sopenharmony_ci#define STRTAB_STE_2_VTCR_S2SH0 GENMASK_ULL(13, 12) 25662306a36Sopenharmony_ci#define STRTAB_STE_2_VTCR_S2TG GENMASK_ULL(15, 14) 25762306a36Sopenharmony_ci#define STRTAB_STE_2_VTCR_S2PS GENMASK_ULL(18, 16) 25862306a36Sopenharmony_ci#define STRTAB_STE_2_S2AA64 (1UL << 51) 25962306a36Sopenharmony_ci#define STRTAB_STE_2_S2ENDI (1UL << 52) 26062306a36Sopenharmony_ci#define STRTAB_STE_2_S2PTW (1UL << 54) 26162306a36Sopenharmony_ci#define STRTAB_STE_2_S2R (1UL << 58) 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci#define STRTAB_STE_3_S2TTB_MASK GENMASK_ULL(51, 4) 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci/* 26662306a36Sopenharmony_ci * Context descriptors. 26762306a36Sopenharmony_ci * 26862306a36Sopenharmony_ci * Linear: when less than 1024 SSIDs are supported 26962306a36Sopenharmony_ci * 2lvl: at most 1024 L1 entries, 27062306a36Sopenharmony_ci * 1024 lazy entries per table. 27162306a36Sopenharmony_ci */ 27262306a36Sopenharmony_ci#define CTXDESC_SPLIT 10 27362306a36Sopenharmony_ci#define CTXDESC_L2_ENTRIES (1 << CTXDESC_SPLIT) 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci#define CTXDESC_L1_DESC_DWORDS 1 27662306a36Sopenharmony_ci#define CTXDESC_L1_DESC_V (1UL << 0) 27762306a36Sopenharmony_ci#define CTXDESC_L1_DESC_L2PTR_MASK GENMASK_ULL(51, 12) 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci#define CTXDESC_CD_DWORDS 8 28062306a36Sopenharmony_ci#define CTXDESC_CD_0_TCR_T0SZ GENMASK_ULL(5, 0) 28162306a36Sopenharmony_ci#define CTXDESC_CD_0_TCR_TG0 GENMASK_ULL(7, 6) 28262306a36Sopenharmony_ci#define CTXDESC_CD_0_TCR_IRGN0 GENMASK_ULL(9, 8) 28362306a36Sopenharmony_ci#define CTXDESC_CD_0_TCR_ORGN0 GENMASK_ULL(11, 10) 28462306a36Sopenharmony_ci#define CTXDESC_CD_0_TCR_SH0 GENMASK_ULL(13, 12) 28562306a36Sopenharmony_ci#define CTXDESC_CD_0_TCR_EPD0 (1ULL << 14) 28662306a36Sopenharmony_ci#define CTXDESC_CD_0_TCR_EPD1 (1ULL << 30) 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci#define CTXDESC_CD_0_ENDI (1UL << 15) 28962306a36Sopenharmony_ci#define CTXDESC_CD_0_V (1UL << 31) 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ci#define CTXDESC_CD_0_TCR_IPS GENMASK_ULL(34, 32) 29262306a36Sopenharmony_ci#define CTXDESC_CD_0_TCR_TBI0 (1ULL << 38) 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci#define CTXDESC_CD_0_AA64 (1UL << 41) 29562306a36Sopenharmony_ci#define CTXDESC_CD_0_S (1UL << 44) 29662306a36Sopenharmony_ci#define CTXDESC_CD_0_R (1UL << 45) 29762306a36Sopenharmony_ci#define CTXDESC_CD_0_A (1UL << 46) 29862306a36Sopenharmony_ci#define CTXDESC_CD_0_ASET (1UL << 47) 29962306a36Sopenharmony_ci#define CTXDESC_CD_0_ASID GENMASK_ULL(63, 48) 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci#define CTXDESC_CD_1_TTB0_MASK GENMASK_ULL(51, 4) 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci/* 30462306a36Sopenharmony_ci * When the SMMU only supports linear context descriptor tables, pick a 30562306a36Sopenharmony_ci * reasonable size limit (64kB). 30662306a36Sopenharmony_ci */ 30762306a36Sopenharmony_ci#define CTXDESC_LINEAR_CDMAX ilog2(SZ_64K / (CTXDESC_CD_DWORDS << 3)) 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_ci/* Command queue */ 31062306a36Sopenharmony_ci#define CMDQ_ENT_SZ_SHIFT 4 31162306a36Sopenharmony_ci#define CMDQ_ENT_DWORDS ((1 << CMDQ_ENT_SZ_SHIFT) >> 3) 31262306a36Sopenharmony_ci#define CMDQ_MAX_SZ_SHIFT (Q_MAX_SZ_SHIFT - CMDQ_ENT_SZ_SHIFT) 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci#define CMDQ_CONS_ERR GENMASK(30, 24) 31562306a36Sopenharmony_ci#define CMDQ_ERR_CERROR_NONE_IDX 0 31662306a36Sopenharmony_ci#define CMDQ_ERR_CERROR_ILL_IDX 1 31762306a36Sopenharmony_ci#define CMDQ_ERR_CERROR_ABT_IDX 2 31862306a36Sopenharmony_ci#define CMDQ_ERR_CERROR_ATC_INV_IDX 3 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci#define CMDQ_PROD_OWNED_FLAG Q_OVERFLOW_FLAG 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci/* 32362306a36Sopenharmony_ci * This is used to size the command queue and therefore must be at least 32462306a36Sopenharmony_ci * BITS_PER_LONG so that the valid_map works correctly (it relies on the 32562306a36Sopenharmony_ci * total number of queue entries being a multiple of BITS_PER_LONG). 32662306a36Sopenharmony_ci */ 32762306a36Sopenharmony_ci#define CMDQ_BATCH_ENTRIES BITS_PER_LONG 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_ci#define CMDQ_0_OP GENMASK_ULL(7, 0) 33062306a36Sopenharmony_ci#define CMDQ_0_SSV (1UL << 11) 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci#define CMDQ_PREFETCH_0_SID GENMASK_ULL(63, 32) 33362306a36Sopenharmony_ci#define CMDQ_PREFETCH_1_SIZE GENMASK_ULL(4, 0) 33462306a36Sopenharmony_ci#define CMDQ_PREFETCH_1_ADDR_MASK GENMASK_ULL(63, 12) 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci#define CMDQ_CFGI_0_SSID GENMASK_ULL(31, 12) 33762306a36Sopenharmony_ci#define CMDQ_CFGI_0_SID GENMASK_ULL(63, 32) 33862306a36Sopenharmony_ci#define CMDQ_CFGI_1_LEAF (1UL << 0) 33962306a36Sopenharmony_ci#define CMDQ_CFGI_1_RANGE GENMASK_ULL(4, 0) 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci#define CMDQ_TLBI_0_NUM GENMASK_ULL(16, 12) 34262306a36Sopenharmony_ci#define CMDQ_TLBI_RANGE_NUM_MAX 31 34362306a36Sopenharmony_ci#define CMDQ_TLBI_0_SCALE GENMASK_ULL(24, 20) 34462306a36Sopenharmony_ci#define CMDQ_TLBI_0_VMID GENMASK_ULL(47, 32) 34562306a36Sopenharmony_ci#define CMDQ_TLBI_0_ASID GENMASK_ULL(63, 48) 34662306a36Sopenharmony_ci#define CMDQ_TLBI_1_LEAF (1UL << 0) 34762306a36Sopenharmony_ci#define CMDQ_TLBI_1_TTL GENMASK_ULL(9, 8) 34862306a36Sopenharmony_ci#define CMDQ_TLBI_1_TG GENMASK_ULL(11, 10) 34962306a36Sopenharmony_ci#define CMDQ_TLBI_1_VA_MASK GENMASK_ULL(63, 12) 35062306a36Sopenharmony_ci#define CMDQ_TLBI_1_IPA_MASK GENMASK_ULL(51, 12) 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_ci#define CMDQ_ATC_0_SSID GENMASK_ULL(31, 12) 35362306a36Sopenharmony_ci#define CMDQ_ATC_0_SID GENMASK_ULL(63, 32) 35462306a36Sopenharmony_ci#define CMDQ_ATC_0_GLOBAL (1UL << 9) 35562306a36Sopenharmony_ci#define CMDQ_ATC_1_SIZE GENMASK_ULL(5, 0) 35662306a36Sopenharmony_ci#define CMDQ_ATC_1_ADDR_MASK GENMASK_ULL(63, 12) 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ci#define CMDQ_PRI_0_SSID GENMASK_ULL(31, 12) 35962306a36Sopenharmony_ci#define CMDQ_PRI_0_SID GENMASK_ULL(63, 32) 36062306a36Sopenharmony_ci#define CMDQ_PRI_1_GRPID GENMASK_ULL(8, 0) 36162306a36Sopenharmony_ci#define CMDQ_PRI_1_RESP GENMASK_ULL(13, 12) 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci#define CMDQ_RESUME_0_RESP_TERM 0UL 36462306a36Sopenharmony_ci#define CMDQ_RESUME_0_RESP_RETRY 1UL 36562306a36Sopenharmony_ci#define CMDQ_RESUME_0_RESP_ABORT 2UL 36662306a36Sopenharmony_ci#define CMDQ_RESUME_0_RESP GENMASK_ULL(13, 12) 36762306a36Sopenharmony_ci#define CMDQ_RESUME_0_SID GENMASK_ULL(63, 32) 36862306a36Sopenharmony_ci#define CMDQ_RESUME_1_STAG GENMASK_ULL(15, 0) 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ci#define CMDQ_SYNC_0_CS GENMASK_ULL(13, 12) 37162306a36Sopenharmony_ci#define CMDQ_SYNC_0_CS_NONE 0 37262306a36Sopenharmony_ci#define CMDQ_SYNC_0_CS_IRQ 1 37362306a36Sopenharmony_ci#define CMDQ_SYNC_0_CS_SEV 2 37462306a36Sopenharmony_ci#define CMDQ_SYNC_0_MSH GENMASK_ULL(23, 22) 37562306a36Sopenharmony_ci#define CMDQ_SYNC_0_MSIATTR GENMASK_ULL(27, 24) 37662306a36Sopenharmony_ci#define CMDQ_SYNC_0_MSIDATA GENMASK_ULL(63, 32) 37762306a36Sopenharmony_ci#define CMDQ_SYNC_1_MSIADDR_MASK GENMASK_ULL(51, 2) 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_ci/* Event queue */ 38062306a36Sopenharmony_ci#define EVTQ_ENT_SZ_SHIFT 5 38162306a36Sopenharmony_ci#define EVTQ_ENT_DWORDS ((1 << EVTQ_ENT_SZ_SHIFT) >> 3) 38262306a36Sopenharmony_ci#define EVTQ_MAX_SZ_SHIFT (Q_MAX_SZ_SHIFT - EVTQ_ENT_SZ_SHIFT) 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_ci#define EVTQ_0_ID GENMASK_ULL(7, 0) 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ci#define EVT_ID_TRANSLATION_FAULT 0x10 38762306a36Sopenharmony_ci#define EVT_ID_ADDR_SIZE_FAULT 0x11 38862306a36Sopenharmony_ci#define EVT_ID_ACCESS_FAULT 0x12 38962306a36Sopenharmony_ci#define EVT_ID_PERMISSION_FAULT 0x13 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_ci#define EVTQ_0_SSV (1UL << 11) 39262306a36Sopenharmony_ci#define EVTQ_0_SSID GENMASK_ULL(31, 12) 39362306a36Sopenharmony_ci#define EVTQ_0_SID GENMASK_ULL(63, 32) 39462306a36Sopenharmony_ci#define EVTQ_1_STAG GENMASK_ULL(15, 0) 39562306a36Sopenharmony_ci#define EVTQ_1_STALL (1UL << 31) 39662306a36Sopenharmony_ci#define EVTQ_1_PnU (1UL << 33) 39762306a36Sopenharmony_ci#define EVTQ_1_InD (1UL << 34) 39862306a36Sopenharmony_ci#define EVTQ_1_RnW (1UL << 35) 39962306a36Sopenharmony_ci#define EVTQ_1_S2 (1UL << 39) 40062306a36Sopenharmony_ci#define EVTQ_1_CLASS GENMASK_ULL(41, 40) 40162306a36Sopenharmony_ci#define EVTQ_1_TT_READ (1UL << 44) 40262306a36Sopenharmony_ci#define EVTQ_2_ADDR GENMASK_ULL(63, 0) 40362306a36Sopenharmony_ci#define EVTQ_3_IPA GENMASK_ULL(51, 12) 40462306a36Sopenharmony_ci 40562306a36Sopenharmony_ci/* PRI queue */ 40662306a36Sopenharmony_ci#define PRIQ_ENT_SZ_SHIFT 4 40762306a36Sopenharmony_ci#define PRIQ_ENT_DWORDS ((1 << PRIQ_ENT_SZ_SHIFT) >> 3) 40862306a36Sopenharmony_ci#define PRIQ_MAX_SZ_SHIFT (Q_MAX_SZ_SHIFT - PRIQ_ENT_SZ_SHIFT) 40962306a36Sopenharmony_ci 41062306a36Sopenharmony_ci#define PRIQ_0_SID GENMASK_ULL(31, 0) 41162306a36Sopenharmony_ci#define PRIQ_0_SSID GENMASK_ULL(51, 32) 41262306a36Sopenharmony_ci#define PRIQ_0_PERM_PRIV (1UL << 58) 41362306a36Sopenharmony_ci#define PRIQ_0_PERM_EXEC (1UL << 59) 41462306a36Sopenharmony_ci#define PRIQ_0_PERM_READ (1UL << 60) 41562306a36Sopenharmony_ci#define PRIQ_0_PERM_WRITE (1UL << 61) 41662306a36Sopenharmony_ci#define PRIQ_0_PRG_LAST (1UL << 62) 41762306a36Sopenharmony_ci#define PRIQ_0_SSID_V (1UL << 63) 41862306a36Sopenharmony_ci 41962306a36Sopenharmony_ci#define PRIQ_1_PRG_IDX GENMASK_ULL(8, 0) 42062306a36Sopenharmony_ci#define PRIQ_1_ADDR_MASK GENMASK_ULL(63, 12) 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_ci/* High-level queue structures */ 42362306a36Sopenharmony_ci#define ARM_SMMU_POLL_TIMEOUT_US 1000000 /* 1s! */ 42462306a36Sopenharmony_ci#define ARM_SMMU_POLL_SPIN_COUNT 10 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_ci#define MSI_IOVA_BASE 0x8000000 42762306a36Sopenharmony_ci#define MSI_IOVA_LENGTH 0x100000 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_cienum pri_resp { 43062306a36Sopenharmony_ci PRI_RESP_DENY = 0, 43162306a36Sopenharmony_ci PRI_RESP_FAIL = 1, 43262306a36Sopenharmony_ci PRI_RESP_SUCC = 2, 43362306a36Sopenharmony_ci}; 43462306a36Sopenharmony_ci 43562306a36Sopenharmony_cistruct arm_smmu_cmdq_ent { 43662306a36Sopenharmony_ci /* Common fields */ 43762306a36Sopenharmony_ci u8 opcode; 43862306a36Sopenharmony_ci bool substream_valid; 43962306a36Sopenharmony_ci 44062306a36Sopenharmony_ci /* Command-specific fields */ 44162306a36Sopenharmony_ci union { 44262306a36Sopenharmony_ci #define CMDQ_OP_PREFETCH_CFG 0x1 44362306a36Sopenharmony_ci struct { 44462306a36Sopenharmony_ci u32 sid; 44562306a36Sopenharmony_ci } prefetch; 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_ci #define CMDQ_OP_CFGI_STE 0x3 44862306a36Sopenharmony_ci #define CMDQ_OP_CFGI_ALL 0x4 44962306a36Sopenharmony_ci #define CMDQ_OP_CFGI_CD 0x5 45062306a36Sopenharmony_ci #define CMDQ_OP_CFGI_CD_ALL 0x6 45162306a36Sopenharmony_ci struct { 45262306a36Sopenharmony_ci u32 sid; 45362306a36Sopenharmony_ci u32 ssid; 45462306a36Sopenharmony_ci union { 45562306a36Sopenharmony_ci bool leaf; 45662306a36Sopenharmony_ci u8 span; 45762306a36Sopenharmony_ci }; 45862306a36Sopenharmony_ci } cfgi; 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_ci #define CMDQ_OP_TLBI_NH_ASID 0x11 46162306a36Sopenharmony_ci #define CMDQ_OP_TLBI_NH_VA 0x12 46262306a36Sopenharmony_ci #define CMDQ_OP_TLBI_EL2_ALL 0x20 46362306a36Sopenharmony_ci #define CMDQ_OP_TLBI_EL2_ASID 0x21 46462306a36Sopenharmony_ci #define CMDQ_OP_TLBI_EL2_VA 0x22 46562306a36Sopenharmony_ci #define CMDQ_OP_TLBI_S12_VMALL 0x28 46662306a36Sopenharmony_ci #define CMDQ_OP_TLBI_S2_IPA 0x2a 46762306a36Sopenharmony_ci #define CMDQ_OP_TLBI_NSNH_ALL 0x30 46862306a36Sopenharmony_ci struct { 46962306a36Sopenharmony_ci u8 num; 47062306a36Sopenharmony_ci u8 scale; 47162306a36Sopenharmony_ci u16 asid; 47262306a36Sopenharmony_ci u16 vmid; 47362306a36Sopenharmony_ci bool leaf; 47462306a36Sopenharmony_ci u8 ttl; 47562306a36Sopenharmony_ci u8 tg; 47662306a36Sopenharmony_ci u64 addr; 47762306a36Sopenharmony_ci } tlbi; 47862306a36Sopenharmony_ci 47962306a36Sopenharmony_ci #define CMDQ_OP_ATC_INV 0x40 48062306a36Sopenharmony_ci #define ATC_INV_SIZE_ALL 52 48162306a36Sopenharmony_ci struct { 48262306a36Sopenharmony_ci u32 sid; 48362306a36Sopenharmony_ci u32 ssid; 48462306a36Sopenharmony_ci u64 addr; 48562306a36Sopenharmony_ci u8 size; 48662306a36Sopenharmony_ci bool global; 48762306a36Sopenharmony_ci } atc; 48862306a36Sopenharmony_ci 48962306a36Sopenharmony_ci #define CMDQ_OP_PRI_RESP 0x41 49062306a36Sopenharmony_ci struct { 49162306a36Sopenharmony_ci u32 sid; 49262306a36Sopenharmony_ci u32 ssid; 49362306a36Sopenharmony_ci u16 grpid; 49462306a36Sopenharmony_ci enum pri_resp resp; 49562306a36Sopenharmony_ci } pri; 49662306a36Sopenharmony_ci 49762306a36Sopenharmony_ci #define CMDQ_OP_RESUME 0x44 49862306a36Sopenharmony_ci struct { 49962306a36Sopenharmony_ci u32 sid; 50062306a36Sopenharmony_ci u16 stag; 50162306a36Sopenharmony_ci u8 resp; 50262306a36Sopenharmony_ci } resume; 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_ci #define CMDQ_OP_CMD_SYNC 0x46 50562306a36Sopenharmony_ci struct { 50662306a36Sopenharmony_ci u64 msiaddr; 50762306a36Sopenharmony_ci } sync; 50862306a36Sopenharmony_ci }; 50962306a36Sopenharmony_ci}; 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_cistruct arm_smmu_ll_queue { 51262306a36Sopenharmony_ci union { 51362306a36Sopenharmony_ci u64 val; 51462306a36Sopenharmony_ci struct { 51562306a36Sopenharmony_ci u32 prod; 51662306a36Sopenharmony_ci u32 cons; 51762306a36Sopenharmony_ci }; 51862306a36Sopenharmony_ci struct { 51962306a36Sopenharmony_ci atomic_t prod; 52062306a36Sopenharmony_ci atomic_t cons; 52162306a36Sopenharmony_ci } atomic; 52262306a36Sopenharmony_ci u8 __pad[SMP_CACHE_BYTES]; 52362306a36Sopenharmony_ci } ____cacheline_aligned_in_smp; 52462306a36Sopenharmony_ci u32 max_n_shift; 52562306a36Sopenharmony_ci}; 52662306a36Sopenharmony_ci 52762306a36Sopenharmony_cistruct arm_smmu_queue { 52862306a36Sopenharmony_ci struct arm_smmu_ll_queue llq; 52962306a36Sopenharmony_ci int irq; /* Wired interrupt */ 53062306a36Sopenharmony_ci 53162306a36Sopenharmony_ci __le64 *base; 53262306a36Sopenharmony_ci dma_addr_t base_dma; 53362306a36Sopenharmony_ci u64 q_base; 53462306a36Sopenharmony_ci 53562306a36Sopenharmony_ci size_t ent_dwords; 53662306a36Sopenharmony_ci 53762306a36Sopenharmony_ci u32 __iomem *prod_reg; 53862306a36Sopenharmony_ci u32 __iomem *cons_reg; 53962306a36Sopenharmony_ci}; 54062306a36Sopenharmony_ci 54162306a36Sopenharmony_cistruct arm_smmu_queue_poll { 54262306a36Sopenharmony_ci ktime_t timeout; 54362306a36Sopenharmony_ci unsigned int delay; 54462306a36Sopenharmony_ci unsigned int spin_cnt; 54562306a36Sopenharmony_ci bool wfe; 54662306a36Sopenharmony_ci}; 54762306a36Sopenharmony_ci 54862306a36Sopenharmony_cistruct arm_smmu_cmdq { 54962306a36Sopenharmony_ci struct arm_smmu_queue q; 55062306a36Sopenharmony_ci atomic_long_t *valid_map; 55162306a36Sopenharmony_ci atomic_t owner_prod; 55262306a36Sopenharmony_ci atomic_t lock; 55362306a36Sopenharmony_ci}; 55462306a36Sopenharmony_ci 55562306a36Sopenharmony_cistruct arm_smmu_cmdq_batch { 55662306a36Sopenharmony_ci u64 cmds[CMDQ_BATCH_ENTRIES * CMDQ_ENT_DWORDS]; 55762306a36Sopenharmony_ci int num; 55862306a36Sopenharmony_ci}; 55962306a36Sopenharmony_ci 56062306a36Sopenharmony_cistruct arm_smmu_evtq { 56162306a36Sopenharmony_ci struct arm_smmu_queue q; 56262306a36Sopenharmony_ci struct iopf_queue *iopf; 56362306a36Sopenharmony_ci u32 max_stalls; 56462306a36Sopenharmony_ci}; 56562306a36Sopenharmony_ci 56662306a36Sopenharmony_cistruct arm_smmu_priq { 56762306a36Sopenharmony_ci struct arm_smmu_queue q; 56862306a36Sopenharmony_ci}; 56962306a36Sopenharmony_ci 57062306a36Sopenharmony_ci/* High-level stream table and context descriptor structures */ 57162306a36Sopenharmony_cistruct arm_smmu_strtab_l1_desc { 57262306a36Sopenharmony_ci u8 span; 57362306a36Sopenharmony_ci 57462306a36Sopenharmony_ci __le64 *l2ptr; 57562306a36Sopenharmony_ci dma_addr_t l2ptr_dma; 57662306a36Sopenharmony_ci}; 57762306a36Sopenharmony_ci 57862306a36Sopenharmony_cistruct arm_smmu_ctx_desc { 57962306a36Sopenharmony_ci u16 asid; 58062306a36Sopenharmony_ci u64 ttbr; 58162306a36Sopenharmony_ci u64 tcr; 58262306a36Sopenharmony_ci u64 mair; 58362306a36Sopenharmony_ci 58462306a36Sopenharmony_ci refcount_t refs; 58562306a36Sopenharmony_ci struct mm_struct *mm; 58662306a36Sopenharmony_ci}; 58762306a36Sopenharmony_ci 58862306a36Sopenharmony_cistruct arm_smmu_l1_ctx_desc { 58962306a36Sopenharmony_ci __le64 *l2ptr; 59062306a36Sopenharmony_ci dma_addr_t l2ptr_dma; 59162306a36Sopenharmony_ci}; 59262306a36Sopenharmony_ci 59362306a36Sopenharmony_cistruct arm_smmu_ctx_desc_cfg { 59462306a36Sopenharmony_ci __le64 *cdtab; 59562306a36Sopenharmony_ci dma_addr_t cdtab_dma; 59662306a36Sopenharmony_ci struct arm_smmu_l1_ctx_desc *l1_desc; 59762306a36Sopenharmony_ci unsigned int num_l1_ents; 59862306a36Sopenharmony_ci}; 59962306a36Sopenharmony_ci 60062306a36Sopenharmony_cistruct arm_smmu_s1_cfg { 60162306a36Sopenharmony_ci struct arm_smmu_ctx_desc_cfg cdcfg; 60262306a36Sopenharmony_ci struct arm_smmu_ctx_desc cd; 60362306a36Sopenharmony_ci u8 s1fmt; 60462306a36Sopenharmony_ci u8 s1cdmax; 60562306a36Sopenharmony_ci}; 60662306a36Sopenharmony_ci 60762306a36Sopenharmony_cistruct arm_smmu_s2_cfg { 60862306a36Sopenharmony_ci u16 vmid; 60962306a36Sopenharmony_ci u64 vttbr; 61062306a36Sopenharmony_ci u64 vtcr; 61162306a36Sopenharmony_ci}; 61262306a36Sopenharmony_ci 61362306a36Sopenharmony_cistruct arm_smmu_strtab_cfg { 61462306a36Sopenharmony_ci __le64 *strtab; 61562306a36Sopenharmony_ci dma_addr_t strtab_dma; 61662306a36Sopenharmony_ci struct arm_smmu_strtab_l1_desc *l1_desc; 61762306a36Sopenharmony_ci unsigned int num_l1_ents; 61862306a36Sopenharmony_ci 61962306a36Sopenharmony_ci u64 strtab_base; 62062306a36Sopenharmony_ci u32 strtab_base_cfg; 62162306a36Sopenharmony_ci}; 62262306a36Sopenharmony_ci 62362306a36Sopenharmony_ci/* An SMMUv3 instance */ 62462306a36Sopenharmony_cistruct arm_smmu_device { 62562306a36Sopenharmony_ci struct device *dev; 62662306a36Sopenharmony_ci void __iomem *base; 62762306a36Sopenharmony_ci void __iomem *page1; 62862306a36Sopenharmony_ci 62962306a36Sopenharmony_ci#define ARM_SMMU_FEAT_2_LVL_STRTAB (1 << 0) 63062306a36Sopenharmony_ci#define ARM_SMMU_FEAT_2_LVL_CDTAB (1 << 1) 63162306a36Sopenharmony_ci#define ARM_SMMU_FEAT_TT_LE (1 << 2) 63262306a36Sopenharmony_ci#define ARM_SMMU_FEAT_TT_BE (1 << 3) 63362306a36Sopenharmony_ci#define ARM_SMMU_FEAT_PRI (1 << 4) 63462306a36Sopenharmony_ci#define ARM_SMMU_FEAT_ATS (1 << 5) 63562306a36Sopenharmony_ci#define ARM_SMMU_FEAT_SEV (1 << 6) 63662306a36Sopenharmony_ci#define ARM_SMMU_FEAT_MSI (1 << 7) 63762306a36Sopenharmony_ci#define ARM_SMMU_FEAT_COHERENCY (1 << 8) 63862306a36Sopenharmony_ci#define ARM_SMMU_FEAT_TRANS_S1 (1 << 9) 63962306a36Sopenharmony_ci#define ARM_SMMU_FEAT_TRANS_S2 (1 << 10) 64062306a36Sopenharmony_ci#define ARM_SMMU_FEAT_STALLS (1 << 11) 64162306a36Sopenharmony_ci#define ARM_SMMU_FEAT_HYP (1 << 12) 64262306a36Sopenharmony_ci#define ARM_SMMU_FEAT_STALL_FORCE (1 << 13) 64362306a36Sopenharmony_ci#define ARM_SMMU_FEAT_VAX (1 << 14) 64462306a36Sopenharmony_ci#define ARM_SMMU_FEAT_RANGE_INV (1 << 15) 64562306a36Sopenharmony_ci#define ARM_SMMU_FEAT_BTM (1 << 16) 64662306a36Sopenharmony_ci#define ARM_SMMU_FEAT_SVA (1 << 17) 64762306a36Sopenharmony_ci#define ARM_SMMU_FEAT_E2H (1 << 18) 64862306a36Sopenharmony_ci#define ARM_SMMU_FEAT_NESTING (1 << 19) 64962306a36Sopenharmony_ci u32 features; 65062306a36Sopenharmony_ci 65162306a36Sopenharmony_ci#define ARM_SMMU_OPT_SKIP_PREFETCH (1 << 0) 65262306a36Sopenharmony_ci#define ARM_SMMU_OPT_PAGE0_REGS_ONLY (1 << 1) 65362306a36Sopenharmony_ci#define ARM_SMMU_OPT_MSIPOLL (1 << 2) 65462306a36Sopenharmony_ci#define ARM_SMMU_OPT_CMDQ_FORCE_SYNC (1 << 3) 65562306a36Sopenharmony_ci u32 options; 65662306a36Sopenharmony_ci 65762306a36Sopenharmony_ci struct arm_smmu_cmdq cmdq; 65862306a36Sopenharmony_ci struct arm_smmu_evtq evtq; 65962306a36Sopenharmony_ci struct arm_smmu_priq priq; 66062306a36Sopenharmony_ci 66162306a36Sopenharmony_ci int gerr_irq; 66262306a36Sopenharmony_ci int combined_irq; 66362306a36Sopenharmony_ci 66462306a36Sopenharmony_ci unsigned long ias; /* IPA */ 66562306a36Sopenharmony_ci unsigned long oas; /* PA */ 66662306a36Sopenharmony_ci unsigned long pgsize_bitmap; 66762306a36Sopenharmony_ci 66862306a36Sopenharmony_ci#define ARM_SMMU_MAX_ASIDS (1 << 16) 66962306a36Sopenharmony_ci unsigned int asid_bits; 67062306a36Sopenharmony_ci 67162306a36Sopenharmony_ci#define ARM_SMMU_MAX_VMIDS (1 << 16) 67262306a36Sopenharmony_ci unsigned int vmid_bits; 67362306a36Sopenharmony_ci struct ida vmid_map; 67462306a36Sopenharmony_ci 67562306a36Sopenharmony_ci unsigned int ssid_bits; 67662306a36Sopenharmony_ci unsigned int sid_bits; 67762306a36Sopenharmony_ci 67862306a36Sopenharmony_ci struct arm_smmu_strtab_cfg strtab_cfg; 67962306a36Sopenharmony_ci 68062306a36Sopenharmony_ci /* IOMMU core code handle */ 68162306a36Sopenharmony_ci struct iommu_device iommu; 68262306a36Sopenharmony_ci 68362306a36Sopenharmony_ci struct rb_root streams; 68462306a36Sopenharmony_ci struct mutex streams_mutex; 68562306a36Sopenharmony_ci}; 68662306a36Sopenharmony_ci 68762306a36Sopenharmony_cistruct arm_smmu_stream { 68862306a36Sopenharmony_ci u32 id; 68962306a36Sopenharmony_ci struct arm_smmu_master *master; 69062306a36Sopenharmony_ci struct rb_node node; 69162306a36Sopenharmony_ci}; 69262306a36Sopenharmony_ci 69362306a36Sopenharmony_ci/* SMMU private data for each master */ 69462306a36Sopenharmony_cistruct arm_smmu_master { 69562306a36Sopenharmony_ci struct arm_smmu_device *smmu; 69662306a36Sopenharmony_ci struct device *dev; 69762306a36Sopenharmony_ci struct arm_smmu_domain *domain; 69862306a36Sopenharmony_ci struct list_head domain_head; 69962306a36Sopenharmony_ci struct arm_smmu_stream *streams; 70062306a36Sopenharmony_ci unsigned int num_streams; 70162306a36Sopenharmony_ci bool ats_enabled; 70262306a36Sopenharmony_ci bool stall_enabled; 70362306a36Sopenharmony_ci bool sva_enabled; 70462306a36Sopenharmony_ci bool iopf_enabled; 70562306a36Sopenharmony_ci struct list_head bonds; 70662306a36Sopenharmony_ci unsigned int ssid_bits; 70762306a36Sopenharmony_ci}; 70862306a36Sopenharmony_ci 70962306a36Sopenharmony_ci/* SMMU private data for an IOMMU domain */ 71062306a36Sopenharmony_cienum arm_smmu_domain_stage { 71162306a36Sopenharmony_ci ARM_SMMU_DOMAIN_S1 = 0, 71262306a36Sopenharmony_ci ARM_SMMU_DOMAIN_S2, 71362306a36Sopenharmony_ci ARM_SMMU_DOMAIN_NESTED, 71462306a36Sopenharmony_ci ARM_SMMU_DOMAIN_BYPASS, 71562306a36Sopenharmony_ci}; 71662306a36Sopenharmony_ci 71762306a36Sopenharmony_cistruct arm_smmu_domain { 71862306a36Sopenharmony_ci struct arm_smmu_device *smmu; 71962306a36Sopenharmony_ci struct mutex init_mutex; /* Protects smmu pointer */ 72062306a36Sopenharmony_ci 72162306a36Sopenharmony_ci struct io_pgtable_ops *pgtbl_ops; 72262306a36Sopenharmony_ci bool stall_enabled; 72362306a36Sopenharmony_ci atomic_t nr_ats_masters; 72462306a36Sopenharmony_ci 72562306a36Sopenharmony_ci enum arm_smmu_domain_stage stage; 72662306a36Sopenharmony_ci union { 72762306a36Sopenharmony_ci struct arm_smmu_s1_cfg s1_cfg; 72862306a36Sopenharmony_ci struct arm_smmu_s2_cfg s2_cfg; 72962306a36Sopenharmony_ci }; 73062306a36Sopenharmony_ci 73162306a36Sopenharmony_ci struct iommu_domain domain; 73262306a36Sopenharmony_ci 73362306a36Sopenharmony_ci struct list_head devices; 73462306a36Sopenharmony_ci spinlock_t devices_lock; 73562306a36Sopenharmony_ci 73662306a36Sopenharmony_ci struct list_head mmu_notifiers; 73762306a36Sopenharmony_ci}; 73862306a36Sopenharmony_ci 73962306a36Sopenharmony_cistatic inline struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom) 74062306a36Sopenharmony_ci{ 74162306a36Sopenharmony_ci return container_of(dom, struct arm_smmu_domain, domain); 74262306a36Sopenharmony_ci} 74362306a36Sopenharmony_ci 74462306a36Sopenharmony_ciextern struct xarray arm_smmu_asid_xa; 74562306a36Sopenharmony_ciextern struct mutex arm_smmu_asid_lock; 74662306a36Sopenharmony_ciextern struct arm_smmu_ctx_desc quiet_cd; 74762306a36Sopenharmony_ci 74862306a36Sopenharmony_ciint arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid, 74962306a36Sopenharmony_ci struct arm_smmu_ctx_desc *cd); 75062306a36Sopenharmony_civoid arm_smmu_tlb_inv_asid(struct arm_smmu_device *smmu, u16 asid); 75162306a36Sopenharmony_civoid arm_smmu_tlb_inv_range_asid(unsigned long iova, size_t size, int asid, 75262306a36Sopenharmony_ci size_t granule, bool leaf, 75362306a36Sopenharmony_ci struct arm_smmu_domain *smmu_domain); 75462306a36Sopenharmony_cibool arm_smmu_free_asid(struct arm_smmu_ctx_desc *cd); 75562306a36Sopenharmony_ciint arm_smmu_atc_inv_domain(struct arm_smmu_domain *smmu_domain, int ssid, 75662306a36Sopenharmony_ci unsigned long iova, size_t size); 75762306a36Sopenharmony_ci 75862306a36Sopenharmony_ci#ifdef CONFIG_ARM_SMMU_V3_SVA 75962306a36Sopenharmony_cibool arm_smmu_sva_supported(struct arm_smmu_device *smmu); 76062306a36Sopenharmony_cibool arm_smmu_master_sva_supported(struct arm_smmu_master *master); 76162306a36Sopenharmony_cibool arm_smmu_master_sva_enabled(struct arm_smmu_master *master); 76262306a36Sopenharmony_ciint arm_smmu_master_enable_sva(struct arm_smmu_master *master); 76362306a36Sopenharmony_ciint arm_smmu_master_disable_sva(struct arm_smmu_master *master); 76462306a36Sopenharmony_cibool arm_smmu_master_iopf_supported(struct arm_smmu_master *master); 76562306a36Sopenharmony_civoid arm_smmu_sva_notifier_synchronize(void); 76662306a36Sopenharmony_cistruct iommu_domain *arm_smmu_sva_domain_alloc(void); 76762306a36Sopenharmony_civoid arm_smmu_sva_remove_dev_pasid(struct iommu_domain *domain, 76862306a36Sopenharmony_ci struct device *dev, ioasid_t id); 76962306a36Sopenharmony_ci#else /* CONFIG_ARM_SMMU_V3_SVA */ 77062306a36Sopenharmony_cistatic inline bool arm_smmu_sva_supported(struct arm_smmu_device *smmu) 77162306a36Sopenharmony_ci{ 77262306a36Sopenharmony_ci return false; 77362306a36Sopenharmony_ci} 77462306a36Sopenharmony_ci 77562306a36Sopenharmony_cistatic inline bool arm_smmu_master_sva_supported(struct arm_smmu_master *master) 77662306a36Sopenharmony_ci{ 77762306a36Sopenharmony_ci return false; 77862306a36Sopenharmony_ci} 77962306a36Sopenharmony_ci 78062306a36Sopenharmony_cistatic inline bool arm_smmu_master_sva_enabled(struct arm_smmu_master *master) 78162306a36Sopenharmony_ci{ 78262306a36Sopenharmony_ci return false; 78362306a36Sopenharmony_ci} 78462306a36Sopenharmony_ci 78562306a36Sopenharmony_cistatic inline int arm_smmu_master_enable_sva(struct arm_smmu_master *master) 78662306a36Sopenharmony_ci{ 78762306a36Sopenharmony_ci return -ENODEV; 78862306a36Sopenharmony_ci} 78962306a36Sopenharmony_ci 79062306a36Sopenharmony_cistatic inline int arm_smmu_master_disable_sva(struct arm_smmu_master *master) 79162306a36Sopenharmony_ci{ 79262306a36Sopenharmony_ci return -ENODEV; 79362306a36Sopenharmony_ci} 79462306a36Sopenharmony_ci 79562306a36Sopenharmony_cistatic inline bool arm_smmu_master_iopf_supported(struct arm_smmu_master *master) 79662306a36Sopenharmony_ci{ 79762306a36Sopenharmony_ci return false; 79862306a36Sopenharmony_ci} 79962306a36Sopenharmony_ci 80062306a36Sopenharmony_cistatic inline void arm_smmu_sva_notifier_synchronize(void) {} 80162306a36Sopenharmony_ci 80262306a36Sopenharmony_cistatic inline struct iommu_domain *arm_smmu_sva_domain_alloc(void) 80362306a36Sopenharmony_ci{ 80462306a36Sopenharmony_ci return NULL; 80562306a36Sopenharmony_ci} 80662306a36Sopenharmony_ci 80762306a36Sopenharmony_cistatic inline void arm_smmu_sva_remove_dev_pasid(struct iommu_domain *domain, 80862306a36Sopenharmony_ci struct device *dev, 80962306a36Sopenharmony_ci ioasid_t id) 81062306a36Sopenharmony_ci{ 81162306a36Sopenharmony_ci} 81262306a36Sopenharmony_ci#endif /* CONFIG_ARM_SMMU_V3_SVA */ 81362306a36Sopenharmony_ci#endif /* _ARM_SMMU_V3_H */ 814