blob: a8e814c652fe6746ae41f2305e6324cccd74fe68 [file] [log] [blame]
Andrew Murray2d7ca2c2018-10-10 11:29:26 +01001// SPDX-License-Identifier: GPL-2.0
Will Deacon48ec83b2015-05-27 17:25:59 +01002/*
3 * IOMMU API for ARM architected SMMUv3 implementations.
4 *
Will Deacon48ec83b2015-05-27 17:25:59 +01005 * Copyright (C) 2015 ARM Limited
6 *
7 * Author: Will Deacon <will.deacon@arm.com>
8 *
9 * This driver is powered by bad coffee and bombay mix.
10 */
11
Lorenzo Pieralisie4dadfa2016-11-21 10:01:43 +000012#include <linux/acpi.h>
13#include <linux/acpi_iort.h>
Robin Murphycbcee192018-03-26 13:35:10 +010014#include <linux/bitfield.h>
Robin Murphy1cf9e542018-03-26 13:35:09 +010015#include <linux/bitops.h>
Will Deaconb63b3432018-07-25 15:58:43 +010016#include <linux/crash_dump.h>
Will Deacon48ec83b2015-05-27 17:25:59 +010017#include <linux/delay.h>
Robin Murphy9adb9592016-01-26 18:06:36 +000018#include <linux/dma-iommu.h>
Will Deacon48ec83b2015-05-27 17:25:59 +010019#include <linux/err.h>
20#include <linux/interrupt.h>
Rob Herringb77cf112019-02-05 10:37:31 -060021#include <linux/io-pgtable.h>
Will Deacon48ec83b2015-05-27 17:25:59 +010022#include <linux/iommu.h>
23#include <linux/iopoll.h>
Will Deacon6e8fa742019-12-19 12:03:44 +000024#include <linux/module.h>
Marc Zyngier166bdbd2015-10-13 18:32:30 +010025#include <linux/msi.h>
Will Deacon48ec83b2015-05-27 17:25:59 +010026#include <linux/of.h>
27#include <linux/of_address.h>
Robin Murphy8f785152016-09-12 17:13:45 +010028#include <linux/of_iommu.h>
Will Deacon941a8022015-08-11 16:25:10 +010029#include <linux/of_platform.h>
Will Deacon48ec83b2015-05-27 17:25:59 +010030#include <linux/pci.h>
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +010031#include <linux/pci-ats.h>
Will Deacon48ec83b2015-05-27 17:25:59 +010032#include <linux/platform_device.h>
33
Robin Murphy08d4ca22016-09-12 17:13:46 +010034#include <linux/amba/bus.h>
35
Will Deacon48ec83b2015-05-27 17:25:59 +010036/* MMIO registers */
37#define ARM_SMMU_IDR0 0x0
Robin Murphycbcee192018-03-26 13:35:10 +010038#define IDR0_ST_LVL GENMASK(28, 27)
39#define IDR0_ST_LVL_2LVL 1
40#define IDR0_STALL_MODEL GENMASK(25, 24)
41#define IDR0_STALL_MODEL_STALL 0
42#define IDR0_STALL_MODEL_FORCE 2
43#define IDR0_TTENDIAN GENMASK(22, 21)
44#define IDR0_TTENDIAN_MIXED 0
45#define IDR0_TTENDIAN_LE 2
46#define IDR0_TTENDIAN_BE 3
Will Deacon48ec83b2015-05-27 17:25:59 +010047#define IDR0_CD2L (1 << 19)
48#define IDR0_VMID16 (1 << 18)
49#define IDR0_PRI (1 << 16)
50#define IDR0_SEV (1 << 14)
51#define IDR0_MSI (1 << 13)
52#define IDR0_ASID16 (1 << 12)
53#define IDR0_ATS (1 << 10)
54#define IDR0_HYP (1 << 9)
55#define IDR0_COHACC (1 << 4)
Robin Murphycbcee192018-03-26 13:35:10 +010056#define IDR0_TTF GENMASK(3, 2)
57#define IDR0_TTF_AARCH64 2
58#define IDR0_TTF_AARCH32_64 3
Will Deacon48ec83b2015-05-27 17:25:59 +010059#define IDR0_S1P (1 << 1)
60#define IDR0_S2P (1 << 0)
61
62#define ARM_SMMU_IDR1 0x4
63#define IDR1_TABLES_PRESET (1 << 30)
64#define IDR1_QUEUES_PRESET (1 << 29)
65#define IDR1_REL (1 << 28)
Robin Murphycbcee192018-03-26 13:35:10 +010066#define IDR1_CMDQS GENMASK(25, 21)
67#define IDR1_EVTQS GENMASK(20, 16)
68#define IDR1_PRIQS GENMASK(15, 11)
69#define IDR1_SSIDSIZE GENMASK(10, 6)
70#define IDR1_SIDSIZE GENMASK(5, 0)
Will Deacon48ec83b2015-05-27 17:25:59 +010071
Rob Herring6a481a92020-02-24 16:31:29 -060072#define ARM_SMMU_IDR3 0xc
73#define IDR3_RIL (1 << 10)
74
Will Deacon48ec83b2015-05-27 17:25:59 +010075#define ARM_SMMU_IDR5 0x14
Robin Murphycbcee192018-03-26 13:35:10 +010076#define IDR5_STALL_MAX GENMASK(31, 16)
Will Deacon48ec83b2015-05-27 17:25:59 +010077#define IDR5_GRAN64K (1 << 6)
78#define IDR5_GRAN16K (1 << 5)
79#define IDR5_GRAN4K (1 << 4)
Robin Murphycbcee192018-03-26 13:35:10 +010080#define IDR5_OAS GENMASK(2, 0)
81#define IDR5_OAS_32_BIT 0
82#define IDR5_OAS_36_BIT 1
83#define IDR5_OAS_40_BIT 2
84#define IDR5_OAS_42_BIT 3
85#define IDR5_OAS_44_BIT 4
86#define IDR5_OAS_48_BIT 5
Robin Murphy6619c912018-03-26 13:35:14 +010087#define IDR5_OAS_52_BIT 6
Robin Murphydcd189e2018-03-26 13:35:15 +010088#define IDR5_VAX GENMASK(11, 10)
89#define IDR5_VAX_52_BIT 1
Will Deacon48ec83b2015-05-27 17:25:59 +010090
91#define ARM_SMMU_CR0 0x20
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +010092#define CR0_ATSCHK (1 << 4)
Will Deacon48ec83b2015-05-27 17:25:59 +010093#define CR0_CMDQEN (1 << 3)
94#define CR0_EVTQEN (1 << 2)
95#define CR0_PRIQEN (1 << 1)
96#define CR0_SMMUEN (1 << 0)
97
98#define ARM_SMMU_CR0ACK 0x24
99
100#define ARM_SMMU_CR1 0x28
Robin Murphycbcee192018-03-26 13:35:10 +0100101#define CR1_TABLE_SH GENMASK(11, 10)
102#define CR1_TABLE_OC GENMASK(9, 8)
103#define CR1_TABLE_IC GENMASK(7, 6)
104#define CR1_QUEUE_SH GENMASK(5, 4)
105#define CR1_QUEUE_OC GENMASK(3, 2)
106#define CR1_QUEUE_IC GENMASK(1, 0)
107/* CR1 cacheability fields don't quite follow the usual TCR-style encoding */
Will Deacon48ec83b2015-05-27 17:25:59 +0100108#define CR1_CACHE_NC 0
109#define CR1_CACHE_WB 1
110#define CR1_CACHE_WT 2
Will Deacon48ec83b2015-05-27 17:25:59 +0100111
112#define ARM_SMMU_CR2 0x2c
113#define CR2_PTM (1 << 2)
114#define CR2_RECINVSID (1 << 1)
115#define CR2_E2H (1 << 0)
116
Robin Murphydc87a982016-09-12 17:13:44 +0100117#define ARM_SMMU_GBPA 0x44
Robin Murphydc87a982016-09-12 17:13:44 +0100118#define GBPA_UPDATE (1 << 31)
Robin Murphycbcee192018-03-26 13:35:10 +0100119#define GBPA_ABORT (1 << 20)
Robin Murphydc87a982016-09-12 17:13:44 +0100120
Will Deacon48ec83b2015-05-27 17:25:59 +0100121#define ARM_SMMU_IRQ_CTRL 0x50
122#define IRQ_CTRL_EVTQ_IRQEN (1 << 2)
Marc Zyngierccd63852015-07-15 11:55:18 +0100123#define IRQ_CTRL_PRIQ_IRQEN (1 << 1)
Will Deacon48ec83b2015-05-27 17:25:59 +0100124#define IRQ_CTRL_GERROR_IRQEN (1 << 0)
125
126#define ARM_SMMU_IRQ_CTRLACK 0x54
127
128#define ARM_SMMU_GERROR 0x60
129#define GERROR_SFM_ERR (1 << 8)
130#define GERROR_MSI_GERROR_ABT_ERR (1 << 7)
131#define GERROR_MSI_PRIQ_ABT_ERR (1 << 6)
132#define GERROR_MSI_EVTQ_ABT_ERR (1 << 5)
133#define GERROR_MSI_CMDQ_ABT_ERR (1 << 4)
134#define GERROR_PRIQ_ABT_ERR (1 << 3)
135#define GERROR_EVTQ_ABT_ERR (1 << 2)
136#define GERROR_CMDQ_ERR (1 << 0)
137#define GERROR_ERR_MASK 0xfd
138
139#define ARM_SMMU_GERRORN 0x64
140
141#define ARM_SMMU_GERROR_IRQ_CFG0 0x68
142#define ARM_SMMU_GERROR_IRQ_CFG1 0x70
143#define ARM_SMMU_GERROR_IRQ_CFG2 0x74
144
145#define ARM_SMMU_STRTAB_BASE 0x80
146#define STRTAB_BASE_RA (1UL << 62)
Robin Murphy6619c912018-03-26 13:35:14 +0100147#define STRTAB_BASE_ADDR_MASK GENMASK_ULL(51, 6)
Will Deacon48ec83b2015-05-27 17:25:59 +0100148
149#define ARM_SMMU_STRTAB_BASE_CFG 0x88
Robin Murphycbcee192018-03-26 13:35:10 +0100150#define STRTAB_BASE_CFG_FMT GENMASK(17, 16)
151#define STRTAB_BASE_CFG_FMT_LINEAR 0
152#define STRTAB_BASE_CFG_FMT_2LVL 1
153#define STRTAB_BASE_CFG_SPLIT GENMASK(10, 6)
154#define STRTAB_BASE_CFG_LOG2SIZE GENMASK(5, 0)
Will Deacon48ec83b2015-05-27 17:25:59 +0100155
156#define ARM_SMMU_CMDQ_BASE 0x90
157#define ARM_SMMU_CMDQ_PROD 0x98
158#define ARM_SMMU_CMDQ_CONS 0x9c
159
160#define ARM_SMMU_EVTQ_BASE 0xa0
161#define ARM_SMMU_EVTQ_PROD 0x100a8
162#define ARM_SMMU_EVTQ_CONS 0x100ac
163#define ARM_SMMU_EVTQ_IRQ_CFG0 0xb0
164#define ARM_SMMU_EVTQ_IRQ_CFG1 0xb8
165#define ARM_SMMU_EVTQ_IRQ_CFG2 0xbc
166
167#define ARM_SMMU_PRIQ_BASE 0xc0
168#define ARM_SMMU_PRIQ_PROD 0x100c8
169#define ARM_SMMU_PRIQ_CONS 0x100cc
170#define ARM_SMMU_PRIQ_IRQ_CFG0 0xd0
171#define ARM_SMMU_PRIQ_IRQ_CFG1 0xd8
172#define ARM_SMMU_PRIQ_IRQ_CFG2 0xdc
173
Jean-Philippe Brucker52f3fab2020-05-13 13:02:57 +0200174#define ARM_SMMU_REG_SZ 0xe00
175
Will Deacon48ec83b2015-05-27 17:25:59 +0100176/* Common MSI config fields */
Robin Murphy6619c912018-03-26 13:35:14 +0100177#define MSI_CFG0_ADDR_MASK GENMASK_ULL(51, 2)
Robin Murphycbcee192018-03-26 13:35:10 +0100178#define MSI_CFG2_SH GENMASK(5, 4)
179#define MSI_CFG2_MEMATTR GENMASK(3, 0)
180
181/* Common memory attribute values */
182#define ARM_SMMU_SH_NSH 0
183#define ARM_SMMU_SH_OSH 2
184#define ARM_SMMU_SH_ISH 3
185#define ARM_SMMU_MEMATTR_DEVICE_nGnRE 0x1
Robin Murphy7417b992018-03-26 13:35:12 +0100186#define ARM_SMMU_MEMATTR_OIWB 0xf
Will Deacon48ec83b2015-05-27 17:25:59 +0100187
Will Deacon7c288a52019-07-02 17:16:16 +0100188#define Q_IDX(llq, p) ((p) & ((1 << (llq)->max_n_shift) - 1))
189#define Q_WRP(llq, p) ((p) & (1 << (llq)->max_n_shift))
Will Deacon587e6c12019-07-02 17:16:25 +0100190#define Q_OVERFLOW_FLAG (1U << 31)
Will Deacon8a073da2019-07-02 17:15:50 +0100191#define Q_OVF(p) ((p) & Q_OVERFLOW_FLAG)
Will Deacon48ec83b2015-05-27 17:25:59 +0100192#define Q_ENT(q, p) ((q)->base + \
Will Deacon7c288a52019-07-02 17:16:16 +0100193 Q_IDX(&((q)->llq), p) * \
194 (q)->ent_dwords)
Will Deacon48ec83b2015-05-27 17:25:59 +0100195
196#define Q_BASE_RWA (1UL << 62)
Robin Murphy6619c912018-03-26 13:35:14 +0100197#define Q_BASE_ADDR_MASK GENMASK_ULL(51, 5)
Robin Murphycbcee192018-03-26 13:35:10 +0100198#define Q_BASE_LOG2SIZE GENMASK(4, 0)
Will Deacon900a85c2019-07-02 12:53:18 +0100199
200/* Ensure DMA allocations are naturally aligned */
201#ifdef CONFIG_CMA_ALIGNMENT
Will Deacond25f6ea2019-05-16 16:08:47 +0100202#define Q_MAX_SZ_SHIFT (PAGE_SHIFT + CONFIG_CMA_ALIGNMENT)
Will Deacon900a85c2019-07-02 12:53:18 +0100203#else
204#define Q_MAX_SZ_SHIFT (PAGE_SHIFT + MAX_ORDER - 1)
205#endif
Will Deacon48ec83b2015-05-27 17:25:59 +0100206
207/*
208 * Stream table.
209 *
210 * Linear: Enough to cover 1 << IDR1.SIDSIZE entries
Zhen Leie2f4c232015-07-07 04:30:17 +0100211 * 2lvl: 128k L1 entries,
212 * 256 lazy entries per table (each table covers a PCI bus)
Will Deacon48ec83b2015-05-27 17:25:59 +0100213 */
Zhen Leie2f4c232015-07-07 04:30:17 +0100214#define STRTAB_L1_SZ_SHIFT 20
Will Deacon48ec83b2015-05-27 17:25:59 +0100215#define STRTAB_SPLIT 8
216
217#define STRTAB_L1_DESC_DWORDS 1
Robin Murphyba08bdc2018-03-26 13:35:11 +0100218#define STRTAB_L1_DESC_SPAN GENMASK_ULL(4, 0)
Robin Murphy6619c912018-03-26 13:35:14 +0100219#define STRTAB_L1_DESC_L2PTR_MASK GENMASK_ULL(51, 6)
Will Deacon48ec83b2015-05-27 17:25:59 +0100220
221#define STRTAB_STE_DWORDS 8
222#define STRTAB_STE_0_V (1UL << 0)
Robin Murphyba08bdc2018-03-26 13:35:11 +0100223#define STRTAB_STE_0_CFG GENMASK_ULL(3, 1)
224#define STRTAB_STE_0_CFG_ABORT 0
225#define STRTAB_STE_0_CFG_BYPASS 4
226#define STRTAB_STE_0_CFG_S1_TRANS 5
227#define STRTAB_STE_0_CFG_S2_TRANS 6
Will Deacon48ec83b2015-05-27 17:25:59 +0100228
Robin Murphyba08bdc2018-03-26 13:35:11 +0100229#define STRTAB_STE_0_S1FMT GENMASK_ULL(5, 4)
230#define STRTAB_STE_0_S1FMT_LINEAR 0
Jean-Philippe Brucker73af06f2020-01-15 13:52:36 +0100231#define STRTAB_STE_0_S1FMT_64K_L2 2
Robin Murphy6619c912018-03-26 13:35:14 +0100232#define STRTAB_STE_0_S1CTXPTR_MASK GENMASK_ULL(51, 6)
Robin Murphyba08bdc2018-03-26 13:35:11 +0100233#define STRTAB_STE_0_S1CDMAX GENMASK_ULL(63, 59)
Will Deacon48ec83b2015-05-27 17:25:59 +0100234
Jean-Philippe Brucker87f42392020-01-15 13:52:33 +0100235#define STRTAB_STE_1_S1DSS GENMASK_ULL(1, 0)
236#define STRTAB_STE_1_S1DSS_TERMINATE 0x0
237#define STRTAB_STE_1_S1DSS_BYPASS 0x1
238#define STRTAB_STE_1_S1DSS_SSID0 0x2
239
Will Deacon48ec83b2015-05-27 17:25:59 +0100240#define STRTAB_STE_1_S1C_CACHE_NC 0UL
241#define STRTAB_STE_1_S1C_CACHE_WBRA 1UL
242#define STRTAB_STE_1_S1C_CACHE_WT 2UL
243#define STRTAB_STE_1_S1C_CACHE_WB 3UL
Robin Murphyba08bdc2018-03-26 13:35:11 +0100244#define STRTAB_STE_1_S1CIR GENMASK_ULL(3, 2)
245#define STRTAB_STE_1_S1COR GENMASK_ULL(5, 4)
246#define STRTAB_STE_1_S1CSH GENMASK_ULL(7, 6)
Will Deacon48ec83b2015-05-27 17:25:59 +0100247
248#define STRTAB_STE_1_S1STALLD (1UL << 27)
249
Robin Murphyba08bdc2018-03-26 13:35:11 +0100250#define STRTAB_STE_1_EATS GENMASK_ULL(29, 28)
Will Deacon48ec83b2015-05-27 17:25:59 +0100251#define STRTAB_STE_1_EATS_ABT 0UL
252#define STRTAB_STE_1_EATS_TRANS 1UL
253#define STRTAB_STE_1_EATS_S1CHK 2UL
Will Deacon48ec83b2015-05-27 17:25:59 +0100254
Robin Murphyba08bdc2018-03-26 13:35:11 +0100255#define STRTAB_STE_1_STRW GENMASK_ULL(31, 30)
Will Deacon48ec83b2015-05-27 17:25:59 +0100256#define STRTAB_STE_1_STRW_NSEL1 0UL
257#define STRTAB_STE_1_STRW_EL2 2UL
Will Deacon48ec83b2015-05-27 17:25:59 +0100258
Robin Murphyba08bdc2018-03-26 13:35:11 +0100259#define STRTAB_STE_1_SHCFG GENMASK_ULL(45, 44)
Will Deacona0eacd82015-11-18 18:15:51 +0000260#define STRTAB_STE_1_SHCFG_INCOMING 1UL
Will Deacona0eacd82015-11-18 18:15:51 +0000261
Robin Murphyba08bdc2018-03-26 13:35:11 +0100262#define STRTAB_STE_2_S2VMID GENMASK_ULL(15, 0)
263#define STRTAB_STE_2_VTCR GENMASK_ULL(50, 32)
Will Deaconac4b80e2020-01-10 14:51:59 +0000264#define STRTAB_STE_2_VTCR_S2T0SZ GENMASK_ULL(5, 0)
265#define STRTAB_STE_2_VTCR_S2SL0 GENMASK_ULL(7, 6)
266#define STRTAB_STE_2_VTCR_S2IR0 GENMASK_ULL(9, 8)
267#define STRTAB_STE_2_VTCR_S2OR0 GENMASK_ULL(11, 10)
268#define STRTAB_STE_2_VTCR_S2SH0 GENMASK_ULL(13, 12)
269#define STRTAB_STE_2_VTCR_S2TG GENMASK_ULL(15, 14)
270#define STRTAB_STE_2_VTCR_S2PS GENMASK_ULL(18, 16)
Will Deacon48ec83b2015-05-27 17:25:59 +0100271#define STRTAB_STE_2_S2AA64 (1UL << 51)
272#define STRTAB_STE_2_S2ENDI (1UL << 52)
273#define STRTAB_STE_2_S2PTW (1UL << 54)
274#define STRTAB_STE_2_S2R (1UL << 58)
275
Robin Murphy6619c912018-03-26 13:35:14 +0100276#define STRTAB_STE_3_S2TTB_MASK GENMASK_ULL(51, 4)
Will Deacon48ec83b2015-05-27 17:25:59 +0100277
Jean-Philippe Brucker73af06f2020-01-15 13:52:36 +0100278/*
279 * Context descriptors.
280 *
281 * Linear: when less than 1024 SSIDs are supported
282 * 2lvl: at most 1024 L1 entries,
283 * 1024 lazy entries per table.
284 */
285#define CTXDESC_SPLIT 10
286#define CTXDESC_L2_ENTRIES (1 << CTXDESC_SPLIT)
287
288#define CTXDESC_L1_DESC_DWORDS 1
289#define CTXDESC_L1_DESC_V (1UL << 0)
290#define CTXDESC_L1_DESC_L2PTR_MASK GENMASK_ULL(51, 12)
291
Will Deacon48ec83b2015-05-27 17:25:59 +0100292#define CTXDESC_CD_DWORDS 8
Robin Murphyba08bdc2018-03-26 13:35:11 +0100293#define CTXDESC_CD_0_TCR_T0SZ GENMASK_ULL(5, 0)
Robin Murphyba08bdc2018-03-26 13:35:11 +0100294#define CTXDESC_CD_0_TCR_TG0 GENMASK_ULL(7, 6)
Robin Murphyba08bdc2018-03-26 13:35:11 +0100295#define CTXDESC_CD_0_TCR_IRGN0 GENMASK_ULL(9, 8)
Robin Murphyba08bdc2018-03-26 13:35:11 +0100296#define CTXDESC_CD_0_TCR_ORGN0 GENMASK_ULL(11, 10)
Robin Murphyba08bdc2018-03-26 13:35:11 +0100297#define CTXDESC_CD_0_TCR_SH0 GENMASK_ULL(13, 12)
Robin Murphyba08bdc2018-03-26 13:35:11 +0100298#define CTXDESC_CD_0_TCR_EPD0 (1ULL << 14)
Robin Murphyba08bdc2018-03-26 13:35:11 +0100299#define CTXDESC_CD_0_TCR_EPD1 (1ULL << 30)
Will Deacon48ec83b2015-05-27 17:25:59 +0100300
301#define CTXDESC_CD_0_ENDI (1UL << 15)
302#define CTXDESC_CD_0_V (1UL << 31)
303
Robin Murphyba08bdc2018-03-26 13:35:11 +0100304#define CTXDESC_CD_0_TCR_IPS GENMASK_ULL(34, 32)
Robin Murphyba08bdc2018-03-26 13:35:11 +0100305#define CTXDESC_CD_0_TCR_TBI0 (1ULL << 38)
Will Deacon48ec83b2015-05-27 17:25:59 +0100306
307#define CTXDESC_CD_0_AA64 (1UL << 41)
Yisheng Xie9cff86fd22017-09-21 20:36:07 +0800308#define CTXDESC_CD_0_S (1UL << 44)
Will Deacon48ec83b2015-05-27 17:25:59 +0100309#define CTXDESC_CD_0_R (1UL << 45)
310#define CTXDESC_CD_0_A (1UL << 46)
Robin Murphyba08bdc2018-03-26 13:35:11 +0100311#define CTXDESC_CD_0_ASET (1UL << 47)
312#define CTXDESC_CD_0_ASID GENMASK_ULL(63, 48)
Will Deacon48ec83b2015-05-27 17:25:59 +0100313
Robin Murphy6619c912018-03-26 13:35:14 +0100314#define CTXDESC_CD_1_TTB0_MASK GENMASK_ULL(51, 4)
Will Deacon48ec83b2015-05-27 17:25:59 +0100315
Jean-Philippe Brucker89535822020-01-15 13:52:29 +0100316/*
317 * When the SMMU only supports linear context descriptor tables, pick a
318 * reasonable size limit (64kB).
319 */
320#define CTXDESC_LINEAR_CDMAX ilog2(SZ_64K / (CTXDESC_CD_DWORDS << 3))
Will Deacon48ec83b2015-05-27 17:25:59 +0100321
322/* Command queue */
Will Deacond25f6ea2019-05-16 16:08:47 +0100323#define CMDQ_ENT_SZ_SHIFT 4
324#define CMDQ_ENT_DWORDS ((1 << CMDQ_ENT_SZ_SHIFT) >> 3)
325#define CMDQ_MAX_SZ_SHIFT (Q_MAX_SZ_SHIFT - CMDQ_ENT_SZ_SHIFT)
Will Deacon48ec83b2015-05-27 17:25:59 +0100326
Robin Murphycbcee192018-03-26 13:35:10 +0100327#define CMDQ_CONS_ERR GENMASK(30, 24)
Will Deacon48ec83b2015-05-27 17:25:59 +0100328#define CMDQ_ERR_CERROR_NONE_IDX 0
329#define CMDQ_ERR_CERROR_ILL_IDX 1
330#define CMDQ_ERR_CERROR_ABT_IDX 2
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +0100331#define CMDQ_ERR_CERROR_ATC_INV_IDX 3
Will Deacon48ec83b2015-05-27 17:25:59 +0100332
Will Deacon587e6c12019-07-02 17:16:25 +0100333#define CMDQ_PROD_OWNED_FLAG Q_OVERFLOW_FLAG
334
Will Deacon2af2e722019-07-02 17:16:33 +0100335/*
336 * This is used to size the command queue and therefore must be at least
337 * BITS_PER_LONG so that the valid_map works correctly (it relies on the
338 * total number of queue entries being a multiple of BITS_PER_LONG).
339 */
340#define CMDQ_BATCH_ENTRIES BITS_PER_LONG
341
Robin Murphy7417b992018-03-26 13:35:12 +0100342#define CMDQ_0_OP GENMASK_ULL(7, 0)
Will Deacon48ec83b2015-05-27 17:25:59 +0100343#define CMDQ_0_SSV (1UL << 11)
344
Robin Murphy7417b992018-03-26 13:35:12 +0100345#define CMDQ_PREFETCH_0_SID GENMASK_ULL(63, 32)
346#define CMDQ_PREFETCH_1_SIZE GENMASK_ULL(4, 0)
Robin Murphy1cf9e542018-03-26 13:35:09 +0100347#define CMDQ_PREFETCH_1_ADDR_MASK GENMASK_ULL(63, 12)
Will Deacon48ec83b2015-05-27 17:25:59 +0100348
Jean-Philippe Brucker87f42392020-01-15 13:52:33 +0100349#define CMDQ_CFGI_0_SSID GENMASK_ULL(31, 12)
Robin Murphy7417b992018-03-26 13:35:12 +0100350#define CMDQ_CFGI_0_SID GENMASK_ULL(63, 32)
Will Deacon48ec83b2015-05-27 17:25:59 +0100351#define CMDQ_CFGI_1_LEAF (1UL << 0)
Robin Murphy7417b992018-03-26 13:35:12 +0100352#define CMDQ_CFGI_1_RANGE GENMASK_ULL(4, 0)
Will Deacon48ec83b2015-05-27 17:25:59 +0100353
Rob Herring6a481a92020-02-24 16:31:29 -0600354#define CMDQ_TLBI_0_NUM GENMASK_ULL(16, 12)
355#define CMDQ_TLBI_RANGE_NUM_MAX 31
356#define CMDQ_TLBI_0_SCALE GENMASK_ULL(24, 20)
Robin Murphy7417b992018-03-26 13:35:12 +0100357#define CMDQ_TLBI_0_VMID GENMASK_ULL(47, 32)
358#define CMDQ_TLBI_0_ASID GENMASK_ULL(63, 48)
Will Deacon48ec83b2015-05-27 17:25:59 +0100359#define CMDQ_TLBI_1_LEAF (1UL << 0)
Rob Herring6a481a92020-02-24 16:31:29 -0600360#define CMDQ_TLBI_1_TTL GENMASK_ULL(9, 8)
361#define CMDQ_TLBI_1_TG GENMASK_ULL(11, 10)
Robin Murphy1cf9e542018-03-26 13:35:09 +0100362#define CMDQ_TLBI_1_VA_MASK GENMASK_ULL(63, 12)
Robin Murphy6619c912018-03-26 13:35:14 +0100363#define CMDQ_TLBI_1_IPA_MASK GENMASK_ULL(51, 12)
Will Deacon48ec83b2015-05-27 17:25:59 +0100364
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +0100365#define CMDQ_ATC_0_SSID GENMASK_ULL(31, 12)
366#define CMDQ_ATC_0_SID GENMASK_ULL(63, 32)
367#define CMDQ_ATC_0_GLOBAL (1UL << 9)
368#define CMDQ_ATC_1_SIZE GENMASK_ULL(5, 0)
369#define CMDQ_ATC_1_ADDR_MASK GENMASK_ULL(63, 12)
370
Robin Murphy7417b992018-03-26 13:35:12 +0100371#define CMDQ_PRI_0_SSID GENMASK_ULL(31, 12)
372#define CMDQ_PRI_0_SID GENMASK_ULL(63, 32)
373#define CMDQ_PRI_1_GRPID GENMASK_ULL(8, 0)
374#define CMDQ_PRI_1_RESP GENMASK_ULL(13, 12)
Will Deacon48ec83b2015-05-27 17:25:59 +0100375
Robin Murphy7417b992018-03-26 13:35:12 +0100376#define CMDQ_SYNC_0_CS GENMASK_ULL(13, 12)
377#define CMDQ_SYNC_0_CS_NONE 0
378#define CMDQ_SYNC_0_CS_IRQ 1
379#define CMDQ_SYNC_0_CS_SEV 2
380#define CMDQ_SYNC_0_MSH GENMASK_ULL(23, 22)
381#define CMDQ_SYNC_0_MSIATTR GENMASK_ULL(27, 24)
382#define CMDQ_SYNC_0_MSIDATA GENMASK_ULL(63, 32)
Robin Murphy6619c912018-03-26 13:35:14 +0100383#define CMDQ_SYNC_1_MSIADDR_MASK GENMASK_ULL(51, 2)
Will Deacon48ec83b2015-05-27 17:25:59 +0100384
385/* Event queue */
Will Deacond25f6ea2019-05-16 16:08:47 +0100386#define EVTQ_ENT_SZ_SHIFT 5
387#define EVTQ_ENT_DWORDS ((1 << EVTQ_ENT_SZ_SHIFT) >> 3)
388#define EVTQ_MAX_SZ_SHIFT (Q_MAX_SZ_SHIFT - EVTQ_ENT_SZ_SHIFT)
Will Deacon48ec83b2015-05-27 17:25:59 +0100389
Robin Murphy7417b992018-03-26 13:35:12 +0100390#define EVTQ_0_ID GENMASK_ULL(7, 0)
Will Deacon48ec83b2015-05-27 17:25:59 +0100391
392/* PRI queue */
Will Deacond25f6ea2019-05-16 16:08:47 +0100393#define PRIQ_ENT_SZ_SHIFT 4
394#define PRIQ_ENT_DWORDS ((1 << PRIQ_ENT_SZ_SHIFT) >> 3)
395#define PRIQ_MAX_SZ_SHIFT (Q_MAX_SZ_SHIFT - PRIQ_ENT_SZ_SHIFT)
Will Deacon48ec83b2015-05-27 17:25:59 +0100396
Robin Murphy7417b992018-03-26 13:35:12 +0100397#define PRIQ_0_SID GENMASK_ULL(31, 0)
398#define PRIQ_0_SSID GENMASK_ULL(51, 32)
Will Deacon48ec83b2015-05-27 17:25:59 +0100399#define PRIQ_0_PERM_PRIV (1UL << 58)
400#define PRIQ_0_PERM_EXEC (1UL << 59)
401#define PRIQ_0_PERM_READ (1UL << 60)
402#define PRIQ_0_PERM_WRITE (1UL << 61)
403#define PRIQ_0_PRG_LAST (1UL << 62)
404#define PRIQ_0_SSID_V (1UL << 63)
405
Robin Murphy7417b992018-03-26 13:35:12 +0100406#define PRIQ_1_PRG_IDX GENMASK_ULL(8, 0)
Robin Murphy1cf9e542018-03-26 13:35:09 +0100407#define PRIQ_1_ADDR_MASK GENMASK_ULL(63, 12)
Will Deacon48ec83b2015-05-27 17:25:59 +0100408
409/* High-level queue structures */
Will Deacon587e6c12019-07-02 17:16:25 +0100410#define ARM_SMMU_POLL_TIMEOUT_US 1000000 /* 1s! */
411#define ARM_SMMU_POLL_SPIN_COUNT 10
Will Deacon48ec83b2015-05-27 17:25:59 +0100412
Eric Auger50019f02017-01-19 20:57:56 +0000413#define MSI_IOVA_BASE 0x8000000
414#define MSI_IOVA_LENGTH 0x100000
415
Zhen Leia71792d2018-07-12 17:28:43 +0800416static bool disable_bypass = 1;
Will Deacon48ec83b2015-05-27 17:25:59 +0100417module_param_named(disable_bypass, disable_bypass, bool, S_IRUGO);
418MODULE_PARM_DESC(disable_bypass,
419 "Disable bypass streams such that incoming transactions from devices that are not attached to an iommu domain will report an abort back to the device and will not be allowed to pass through the SMMU.");
420
421enum pri_resp {
Robin Murphy7417b992018-03-26 13:35:12 +0100422 PRI_RESP_DENY = 0,
423 PRI_RESP_FAIL = 1,
424 PRI_RESP_SUCC = 2,
Will Deacon48ec83b2015-05-27 17:25:59 +0100425};
426
Marc Zyngier166bdbd2015-10-13 18:32:30 +0100427enum arm_smmu_msi_index {
428 EVTQ_MSI_INDEX,
429 GERROR_MSI_INDEX,
430 PRIQ_MSI_INDEX,
431 ARM_SMMU_MAX_MSIS,
432};
433
434static phys_addr_t arm_smmu_msi_cfg[ARM_SMMU_MAX_MSIS][3] = {
435 [EVTQ_MSI_INDEX] = {
436 ARM_SMMU_EVTQ_IRQ_CFG0,
437 ARM_SMMU_EVTQ_IRQ_CFG1,
438 ARM_SMMU_EVTQ_IRQ_CFG2,
439 },
440 [GERROR_MSI_INDEX] = {
441 ARM_SMMU_GERROR_IRQ_CFG0,
442 ARM_SMMU_GERROR_IRQ_CFG1,
443 ARM_SMMU_GERROR_IRQ_CFG2,
444 },
445 [PRIQ_MSI_INDEX] = {
446 ARM_SMMU_PRIQ_IRQ_CFG0,
447 ARM_SMMU_PRIQ_IRQ_CFG1,
448 ARM_SMMU_PRIQ_IRQ_CFG2,
449 },
450};
451
Will Deacon48ec83b2015-05-27 17:25:59 +0100452struct arm_smmu_cmdq_ent {
453 /* Common fields */
454 u8 opcode;
455 bool substream_valid;
456
457 /* Command-specific fields */
458 union {
459 #define CMDQ_OP_PREFETCH_CFG 0x1
460 struct {
461 u32 sid;
462 u8 size;
463 u64 addr;
464 } prefetch;
465
466 #define CMDQ_OP_CFGI_STE 0x3
467 #define CMDQ_OP_CFGI_ALL 0x4
Jean-Philippe Brucker87f42392020-01-15 13:52:33 +0100468 #define CMDQ_OP_CFGI_CD 0x5
469 #define CMDQ_OP_CFGI_CD_ALL 0x6
Will Deacon48ec83b2015-05-27 17:25:59 +0100470 struct {
471 u32 sid;
Jean-Philippe Brucker87f42392020-01-15 13:52:33 +0100472 u32 ssid;
Will Deacon48ec83b2015-05-27 17:25:59 +0100473 union {
474 bool leaf;
475 u8 span;
476 };
477 } cfgi;
478
479 #define CMDQ_OP_TLBI_NH_ASID 0x11
480 #define CMDQ_OP_TLBI_NH_VA 0x12
481 #define CMDQ_OP_TLBI_EL2_ALL 0x20
482 #define CMDQ_OP_TLBI_S12_VMALL 0x28
483 #define CMDQ_OP_TLBI_S2_IPA 0x2a
484 #define CMDQ_OP_TLBI_NSNH_ALL 0x30
485 struct {
Rob Herring6a481a92020-02-24 16:31:29 -0600486 u8 num;
487 u8 scale;
Will Deacon48ec83b2015-05-27 17:25:59 +0100488 u16 asid;
489 u16 vmid;
490 bool leaf;
Rob Herring6a481a92020-02-24 16:31:29 -0600491 u8 ttl;
492 u8 tg;
Will Deacon48ec83b2015-05-27 17:25:59 +0100493 u64 addr;
494 } tlbi;
495
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +0100496 #define CMDQ_OP_ATC_INV 0x40
497 #define ATC_INV_SIZE_ALL 52
498 struct {
499 u32 sid;
500 u32 ssid;
501 u64 addr;
502 u8 size;
503 bool global;
504 } atc;
505
Will Deacon48ec83b2015-05-27 17:25:59 +0100506 #define CMDQ_OP_PRI_RESP 0x41
507 struct {
508 u32 sid;
509 u32 ssid;
510 u16 grpid;
511 enum pri_resp resp;
512 } pri;
513
514 #define CMDQ_OP_CMD_SYNC 0x46
Robin Murphy37de98f2017-10-18 15:04:26 +0100515 struct {
Robin Murphy37de98f2017-10-18 15:04:26 +0100516 u64 msiaddr;
517 } sync;
Will Deacon48ec83b2015-05-27 17:25:59 +0100518 };
519};
520
Will Deacon52be8632019-07-02 17:16:08 +0100521struct arm_smmu_ll_queue {
Will Deacon587e6c12019-07-02 17:16:25 +0100522 union {
523 u64 val;
524 struct {
525 u32 prod;
526 u32 cons;
527 };
528 struct {
529 atomic_t prod;
530 atomic_t cons;
531 } atomic;
532 u8 __pad[SMP_CACHE_BYTES];
533 } ____cacheline_aligned_in_smp;
Will Deacon52be8632019-07-02 17:16:08 +0100534 u32 max_n_shift;
535};
536
Will Deacon48ec83b2015-05-27 17:25:59 +0100537struct arm_smmu_queue {
Will Deacon52be8632019-07-02 17:16:08 +0100538 struct arm_smmu_ll_queue llq;
Will Deacon48ec83b2015-05-27 17:25:59 +0100539 int irq; /* Wired interrupt */
540
541 __le64 *base;
542 dma_addr_t base_dma;
543 u64 q_base;
544
545 size_t ent_dwords;
Will Deacon48ec83b2015-05-27 17:25:59 +0100546
547 u32 __iomem *prod_reg;
548 u32 __iomem *cons_reg;
549};
550
Will Deacon587e6c12019-07-02 17:16:25 +0100551struct arm_smmu_queue_poll {
552 ktime_t timeout;
553 unsigned int delay;
554 unsigned int spin_cnt;
555 bool wfe;
556};
557
Will Deacon48ec83b2015-05-27 17:25:59 +0100558struct arm_smmu_cmdq {
559 struct arm_smmu_queue q;
Will Deacon587e6c12019-07-02 17:16:25 +0100560 atomic_long_t *valid_map;
561 atomic_t owner_prod;
562 atomic_t lock;
Will Deacon48ec83b2015-05-27 17:25:59 +0100563};
564
Jean-Philippe Brucker4ce8da42020-02-24 17:58:44 +0100565struct arm_smmu_cmdq_batch {
566 u64 cmds[CMDQ_BATCH_ENTRIES * CMDQ_ENT_DWORDS];
567 int num;
568};
569
Will Deacon48ec83b2015-05-27 17:25:59 +0100570struct arm_smmu_evtq {
571 struct arm_smmu_queue q;
572 u32 max_stalls;
573};
574
575struct arm_smmu_priq {
576 struct arm_smmu_queue q;
577};
578
579/* High-level stream table and context descriptor structures */
580struct arm_smmu_strtab_l1_desc {
581 u8 span;
582
583 __le64 *l2ptr;
584 dma_addr_t l2ptr_dma;
585};
586
Jean-Philippe Brucker7bc4f3f2020-01-15 13:52:31 +0100587struct arm_smmu_ctx_desc {
588 u16 asid;
589 u64 ttbr;
590 u64 tcr;
591 u64 mair;
592};
Will Deacon48ec83b2015-05-27 17:25:59 +0100593
Jean-Philippe Brucker73af06f2020-01-15 13:52:36 +0100594struct arm_smmu_l1_ctx_desc {
595 __le64 *l2ptr;
596 dma_addr_t l2ptr_dma;
597};
598
Jean-Philippe Brucker7bc4f3f2020-01-15 13:52:31 +0100599struct arm_smmu_ctx_desc_cfg {
600 __le64 *cdtab;
601 dma_addr_t cdtab_dma;
Jean-Philippe Brucker73af06f2020-01-15 13:52:36 +0100602 struct arm_smmu_l1_ctx_desc *l1_desc;
Jean-Philippe Bruckera557aff2020-01-15 13:52:32 +0100603 unsigned int num_l1_ents;
Jean-Philippe Brucker7bc4f3f2020-01-15 13:52:31 +0100604};
605
606struct arm_smmu_s1_cfg {
607 struct arm_smmu_ctx_desc_cfg cdcfg;
608 struct arm_smmu_ctx_desc cd;
Jean-Philippe Brucker87f42392020-01-15 13:52:33 +0100609 u8 s1fmt;
Jean-Philippe Bruckera557aff2020-01-15 13:52:32 +0100610 u8 s1cdmax;
Will Deacon48ec83b2015-05-27 17:25:59 +0100611};
612
613struct arm_smmu_s2_cfg {
614 u16 vmid;
615 u64 vttbr;
616 u64 vtcr;
617};
618
Will Deacon48ec83b2015-05-27 17:25:59 +0100619struct arm_smmu_strtab_cfg {
620 __le64 *strtab;
621 dma_addr_t strtab_dma;
622 struct arm_smmu_strtab_l1_desc *l1_desc;
623 unsigned int num_l1_ents;
624
625 u64 strtab_base;
626 u32 strtab_base_cfg;
627};
628
629/* An SMMUv3 instance */
630struct arm_smmu_device {
631 struct device *dev;
632 void __iomem *base;
Jean-Philippe Brucker52f3fab2020-05-13 13:02:57 +0200633 void __iomem *page1;
Will Deacon48ec83b2015-05-27 17:25:59 +0100634
635#define ARM_SMMU_FEAT_2_LVL_STRTAB (1 << 0)
636#define ARM_SMMU_FEAT_2_LVL_CDTAB (1 << 1)
637#define ARM_SMMU_FEAT_TT_LE (1 << 2)
638#define ARM_SMMU_FEAT_TT_BE (1 << 3)
639#define ARM_SMMU_FEAT_PRI (1 << 4)
640#define ARM_SMMU_FEAT_ATS (1 << 5)
641#define ARM_SMMU_FEAT_SEV (1 << 6)
642#define ARM_SMMU_FEAT_MSI (1 << 7)
643#define ARM_SMMU_FEAT_COHERENCY (1 << 8)
644#define ARM_SMMU_FEAT_TRANS_S1 (1 << 9)
645#define ARM_SMMU_FEAT_TRANS_S2 (1 << 10)
646#define ARM_SMMU_FEAT_STALLS (1 << 11)
647#define ARM_SMMU_FEAT_HYP (1 << 12)
Yisheng Xie9cff86fd22017-09-21 20:36:07 +0800648#define ARM_SMMU_FEAT_STALL_FORCE (1 << 13)
Robin Murphydcd189e2018-03-26 13:35:15 +0100649#define ARM_SMMU_FEAT_VAX (1 << 14)
Rob Herring6a481a92020-02-24 16:31:29 -0600650#define ARM_SMMU_FEAT_RANGE_INV (1 << 15)
Will Deacon48ec83b2015-05-27 17:25:59 +0100651 u32 features;
652
Zhen Lei5e929462015-07-07 04:30:18 +0100653#define ARM_SMMU_OPT_SKIP_PREFETCH (1 << 0)
Linu Cheriane5b829d2017-06-22 17:35:37 +0530654#define ARM_SMMU_OPT_PAGE0_REGS_ONLY (1 << 1)
Zhen Lei5e929462015-07-07 04:30:18 +0100655 u32 options;
656
Will Deacon48ec83b2015-05-27 17:25:59 +0100657 struct arm_smmu_cmdq cmdq;
658 struct arm_smmu_evtq evtq;
659 struct arm_smmu_priq priq;
660
661 int gerr_irq;
Geetha Sowjanyaf9354482017-06-23 19:04:36 +0530662 int combined_irq;
Will Deacon48ec83b2015-05-27 17:25:59 +0100663
664 unsigned long ias; /* IPA */
665 unsigned long oas; /* PA */
Robin Murphyd5466352016-05-09 17:20:09 +0100666 unsigned long pgsize_bitmap;
Will Deacon48ec83b2015-05-27 17:25:59 +0100667
668#define ARM_SMMU_MAX_ASIDS (1 << 16)
669 unsigned int asid_bits;
Will Deacon48ec83b2015-05-27 17:25:59 +0100670
671#define ARM_SMMU_MAX_VMIDS (1 << 16)
672 unsigned int vmid_bits;
673 DECLARE_BITMAP(vmid_map, ARM_SMMU_MAX_VMIDS);
674
675 unsigned int ssid_bits;
676 unsigned int sid_bits;
677
678 struct arm_smmu_strtab_cfg strtab_cfg;
Joerg Roedel9648cbc2017-02-01 18:11:36 +0100679
680 /* IOMMU core code handle */
681 struct iommu_device iommu;
Will Deacon48ec83b2015-05-27 17:25:59 +0100682};
683
Robin Murphy8f785152016-09-12 17:13:45 +0100684/* SMMU private data for each master */
Jean-Philippe Bruckerb54f4262019-04-17 19:24:43 +0100685struct arm_smmu_master {
Will Deacon48ec83b2015-05-27 17:25:59 +0100686 struct arm_smmu_device *smmu;
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +0100687 struct device *dev;
Jean-Philippe Brucker8be39a12019-04-17 19:24:45 +0100688 struct arm_smmu_domain *domain;
Jean-Philippe Brucker2a7e62f2019-04-17 19:24:46 +0100689 struct list_head domain_head;
Jean-Philippe Bruckerbcecaee2019-04-17 19:24:44 +0100690 u32 *sids;
691 unsigned int num_sids;
Will Deaconf75d8e32019-08-20 17:32:18 +0100692 bool ats_enabled;
Jean-Philippe Brucker89535822020-01-15 13:52:29 +0100693 unsigned int ssid_bits;
Will Deacon48ec83b2015-05-27 17:25:59 +0100694};
695
696/* SMMU private data for an IOMMU domain */
697enum arm_smmu_domain_stage {
698 ARM_SMMU_DOMAIN_S1 = 0,
699 ARM_SMMU_DOMAIN_S2,
700 ARM_SMMU_DOMAIN_NESTED,
Will Deaconbeb3c6a2017-01-06 16:27:30 +0000701 ARM_SMMU_DOMAIN_BYPASS,
Will Deacon48ec83b2015-05-27 17:25:59 +0100702};
703
704struct arm_smmu_domain {
705 struct arm_smmu_device *smmu;
706 struct mutex init_mutex; /* Protects smmu pointer */
707
708 struct io_pgtable_ops *pgtbl_ops;
Zhen Lei9662b992018-09-20 17:10:25 +0100709 bool non_strict;
Will Deaconcdb8a3c2019-08-20 16:28:54 +0100710 atomic_t nr_ats_masters;
Will Deacon48ec83b2015-05-27 17:25:59 +0100711
712 enum arm_smmu_domain_stage stage;
713 union {
714 struct arm_smmu_s1_cfg s1_cfg;
715 struct arm_smmu_s2_cfg s2_cfg;
716 };
717
718 struct iommu_domain domain;
Jean-Philippe Brucker2a7e62f2019-04-17 19:24:46 +0100719
720 struct list_head devices;
721 spinlock_t devices_lock;
Will Deacon48ec83b2015-05-27 17:25:59 +0100722};
723
Zhen Lei5e929462015-07-07 04:30:18 +0100724struct arm_smmu_option_prop {
725 u32 opt;
726 const char *prop;
727};
728
Jean-Philippe Brucker0299a1a2020-05-19 19:54:46 +0200729static DEFINE_XARRAY_ALLOC1(asid_xa);
730
Zhen Lei5e929462015-07-07 04:30:18 +0100731static struct arm_smmu_option_prop arm_smmu_options[] = {
732 { ARM_SMMU_OPT_SKIP_PREFETCH, "hisilicon,broken-prefetch-cmd" },
Linu Cheriane5b829d2017-06-22 17:35:37 +0530733 { ARM_SMMU_OPT_PAGE0_REGS_ONLY, "cavium,cn9900-broken-page1-regspace"},
Zhen Lei5e929462015-07-07 04:30:18 +0100734 { 0, NULL},
735};
736
Linu Cheriane5b829d2017-06-22 17:35:37 +0530737static inline void __iomem *arm_smmu_page1_fixup(unsigned long offset,
738 struct arm_smmu_device *smmu)
739{
Jean-Philippe Brucker52f3fab2020-05-13 13:02:57 +0200740 if (offset > SZ_64K)
741 return smmu->page1 + offset - SZ_64K;
Linu Cheriane5b829d2017-06-22 17:35:37 +0530742
743 return smmu->base + offset;
744}
745
Will Deacon48ec83b2015-05-27 17:25:59 +0100746static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom)
747{
748 return container_of(dom, struct arm_smmu_domain, domain);
749}
750
Zhen Lei5e929462015-07-07 04:30:18 +0100751static void parse_driver_options(struct arm_smmu_device *smmu)
752{
753 int i = 0;
754
755 do {
756 if (of_property_read_bool(smmu->dev->of_node,
757 arm_smmu_options[i].prop)) {
758 smmu->options |= arm_smmu_options[i].opt;
759 dev_notice(smmu->dev, "option %s\n",
760 arm_smmu_options[i].prop);
761 }
762 } while (arm_smmu_options[++i].opt);
763}
764
Will Deacon48ec83b2015-05-27 17:25:59 +0100765/* Low-level queue manipulation functions */
Will Deacon587e6c12019-07-02 17:16:25 +0100766static bool queue_has_space(struct arm_smmu_ll_queue *q, u32 n)
767{
768 u32 space, prod, cons;
769
770 prod = Q_IDX(q, q->prod);
771 cons = Q_IDX(q, q->cons);
772
773 if (Q_WRP(q, q->prod) == Q_WRP(q, q->cons))
774 space = (1 << q->max_n_shift) - (prod - cons);
775 else
776 space = cons - prod;
777
778 return space >= n;
779}
780
Will Deacon7c288a52019-07-02 17:16:16 +0100781static bool queue_full(struct arm_smmu_ll_queue *q)
Will Deacon48ec83b2015-05-27 17:25:59 +0100782{
783 return Q_IDX(q, q->prod) == Q_IDX(q, q->cons) &&
784 Q_WRP(q, q->prod) != Q_WRP(q, q->cons);
785}
786
Will Deacon7c288a52019-07-02 17:16:16 +0100787static bool queue_empty(struct arm_smmu_ll_queue *q)
Will Deacon48ec83b2015-05-27 17:25:59 +0100788{
789 return Q_IDX(q, q->prod) == Q_IDX(q, q->cons) &&
790 Q_WRP(q, q->prod) == Q_WRP(q, q->cons);
791}
792
Will Deacon587e6c12019-07-02 17:16:25 +0100793static bool queue_consumed(struct arm_smmu_ll_queue *q, u32 prod)
Will Deacon48ec83b2015-05-27 17:25:59 +0100794{
Will Deacon587e6c12019-07-02 17:16:25 +0100795 return ((Q_WRP(q, q->cons) == Q_WRP(q, prod)) &&
796 (Q_IDX(q, q->cons) > Q_IDX(q, prod))) ||
797 ((Q_WRP(q, q->cons) != Q_WRP(q, prod)) &&
798 (Q_IDX(q, q->cons) <= Q_IDX(q, prod)));
Will Deacon48ec83b2015-05-27 17:25:59 +0100799}
800
Will Deacon2a8868f2019-07-02 17:12:24 +0100801static void queue_sync_cons_out(struct arm_smmu_queue *q)
Will Deacon48ec83b2015-05-27 17:25:59 +0100802{
Will Deacona868e852018-11-07 22:58:24 +0000803 /*
804 * Ensure that all CPU accesses (reads and writes) to the queue
805 * are complete before we update the cons pointer.
806 */
807 mb();
Will Deacon52be8632019-07-02 17:16:08 +0100808 writel_relaxed(q->llq.cons, q->cons_reg);
Will Deacon48ec83b2015-05-27 17:25:59 +0100809}
810
Will Deacon7c288a52019-07-02 17:16:16 +0100811static void queue_inc_cons(struct arm_smmu_ll_queue *q)
Will Deacon2a8868f2019-07-02 17:12:24 +0100812{
Will Deacon7c288a52019-07-02 17:16:16 +0100813 u32 cons = (Q_WRP(q, q->cons) | Q_IDX(q, q->cons)) + 1;
814 q->cons = Q_OVF(q->cons) | Q_WRP(q, cons) | Q_IDX(q, cons);
Will Deacon2a8868f2019-07-02 17:12:24 +0100815}
816
817static int queue_sync_prod_in(struct arm_smmu_queue *q)
Will Deacon48ec83b2015-05-27 17:25:59 +0100818{
819 int ret = 0;
820 u32 prod = readl_relaxed(q->prod_reg);
821
Will Deacon52be8632019-07-02 17:16:08 +0100822 if (Q_OVF(prod) != Q_OVF(q->llq.prod))
Will Deacon48ec83b2015-05-27 17:25:59 +0100823 ret = -EOVERFLOW;
824
Will Deacon52be8632019-07-02 17:16:08 +0100825 q->llq.prod = prod;
Will Deacon48ec83b2015-05-27 17:25:59 +0100826 return ret;
827}
828
Will Deacon587e6c12019-07-02 17:16:25 +0100829static u32 queue_inc_prod_n(struct arm_smmu_ll_queue *q, int n)
Will Deacon48ec83b2015-05-27 17:25:59 +0100830{
Will Deacon587e6c12019-07-02 17:16:25 +0100831 u32 prod = (Q_WRP(q, q->prod) | Q_IDX(q, q->prod)) + n;
832 return Q_OVF(q->prod) | Q_WRP(q, prod) | Q_IDX(q, prod);
Will Deacon48ec83b2015-05-27 17:25:59 +0100833}
834
Will Deacon587e6c12019-07-02 17:16:25 +0100835static void queue_poll_init(struct arm_smmu_device *smmu,
836 struct arm_smmu_queue_poll *qp)
Will Deacon48ec83b2015-05-27 17:25:59 +0100837{
Will Deacon587e6c12019-07-02 17:16:25 +0100838 qp->delay = 1;
839 qp->spin_cnt = 0;
840 qp->wfe = !!(smmu->features & ARM_SMMU_FEAT_SEV);
841 qp->timeout = ktime_add_us(ktime_get(), ARM_SMMU_POLL_TIMEOUT_US);
Will Deacon48ec83b2015-05-27 17:25:59 +0100842}
Sunil Gouthamb847de42017-05-05 16:47:46 +0530843
Will Deacon587e6c12019-07-02 17:16:25 +0100844static int queue_poll(struct arm_smmu_queue_poll *qp)
Will Deacon48ec83b2015-05-27 17:25:59 +0100845{
Will Deacon587e6c12019-07-02 17:16:25 +0100846 if (ktime_compare(ktime_get(), qp->timeout) > 0)
847 return -ETIMEDOUT;
Will Deacon48ec83b2015-05-27 17:25:59 +0100848
Will Deacon587e6c12019-07-02 17:16:25 +0100849 if (qp->wfe) {
850 wfe();
851 } else if (++qp->spin_cnt < ARM_SMMU_POLL_SPIN_COUNT) {
852 cpu_relax();
853 } else {
854 udelay(qp->delay);
855 qp->delay *= 2;
856 qp->spin_cnt = 0;
Will Deacon48ec83b2015-05-27 17:25:59 +0100857 }
858
859 return 0;
860}
861
862static void queue_write(__le64 *dst, u64 *src, size_t n_dwords)
863{
864 int i;
865
866 for (i = 0; i < n_dwords; ++i)
867 *dst++ = cpu_to_le64(*src++);
868}
869
Will Deacon48ec83b2015-05-27 17:25:59 +0100870static void queue_read(__le64 *dst, u64 *src, size_t n_dwords)
871{
872 int i;
873
874 for (i = 0; i < n_dwords; ++i)
875 *dst++ = le64_to_cpu(*src++);
876}
877
878static int queue_remove_raw(struct arm_smmu_queue *q, u64 *ent)
879{
Will Deacon7c288a52019-07-02 17:16:16 +0100880 if (queue_empty(&q->llq))
Will Deacon48ec83b2015-05-27 17:25:59 +0100881 return -EAGAIN;
882
Will Deacon52be8632019-07-02 17:16:08 +0100883 queue_read(ent, Q_ENT(q, q->llq.cons), q->ent_dwords);
Will Deacon7c288a52019-07-02 17:16:16 +0100884 queue_inc_cons(&q->llq);
Will Deacon2a8868f2019-07-02 17:12:24 +0100885 queue_sync_cons_out(q);
Will Deacon48ec83b2015-05-27 17:25:59 +0100886 return 0;
887}
888
889/* High-level queue accessors */
890static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
891{
Will Deacond25f6ea2019-05-16 16:08:47 +0100892 memset(cmd, 0, 1 << CMDQ_ENT_SZ_SHIFT);
Robin Murphy7417b992018-03-26 13:35:12 +0100893 cmd[0] |= FIELD_PREP(CMDQ_0_OP, ent->opcode);
Will Deacon48ec83b2015-05-27 17:25:59 +0100894
895 switch (ent->opcode) {
896 case CMDQ_OP_TLBI_EL2_ALL:
897 case CMDQ_OP_TLBI_NSNH_ALL:
898 break;
899 case CMDQ_OP_PREFETCH_CFG:
Robin Murphy7417b992018-03-26 13:35:12 +0100900 cmd[0] |= FIELD_PREP(CMDQ_PREFETCH_0_SID, ent->prefetch.sid);
901 cmd[1] |= FIELD_PREP(CMDQ_PREFETCH_1_SIZE, ent->prefetch.size);
Will Deacon48ec83b2015-05-27 17:25:59 +0100902 cmd[1] |= ent->prefetch.addr & CMDQ_PREFETCH_1_ADDR_MASK;
903 break;
Jean-Philippe Brucker87f42392020-01-15 13:52:33 +0100904 case CMDQ_OP_CFGI_CD:
905 cmd[0] |= FIELD_PREP(CMDQ_CFGI_0_SSID, ent->cfgi.ssid);
906 /* Fallthrough */
Will Deacon48ec83b2015-05-27 17:25:59 +0100907 case CMDQ_OP_CFGI_STE:
Robin Murphy7417b992018-03-26 13:35:12 +0100908 cmd[0] |= FIELD_PREP(CMDQ_CFGI_0_SID, ent->cfgi.sid);
909 cmd[1] |= FIELD_PREP(CMDQ_CFGI_1_LEAF, ent->cfgi.leaf);
Will Deacon48ec83b2015-05-27 17:25:59 +0100910 break;
Jean-Philippe Brucker87f42392020-01-15 13:52:33 +0100911 case CMDQ_OP_CFGI_CD_ALL:
912 cmd[0] |= FIELD_PREP(CMDQ_CFGI_0_SID, ent->cfgi.sid);
913 break;
Will Deacon48ec83b2015-05-27 17:25:59 +0100914 case CMDQ_OP_CFGI_ALL:
915 /* Cover the entire SID range */
Robin Murphy7417b992018-03-26 13:35:12 +0100916 cmd[1] |= FIELD_PREP(CMDQ_CFGI_1_RANGE, 31);
Will Deacon48ec83b2015-05-27 17:25:59 +0100917 break;
918 case CMDQ_OP_TLBI_NH_VA:
Rob Herring6a481a92020-02-24 16:31:29 -0600919 cmd[0] |= FIELD_PREP(CMDQ_TLBI_0_NUM, ent->tlbi.num);
920 cmd[0] |= FIELD_PREP(CMDQ_TLBI_0_SCALE, ent->tlbi.scale);
Shameer Kolothum935d43b2019-11-13 16:11:38 +0000921 cmd[0] |= FIELD_PREP(CMDQ_TLBI_0_VMID, ent->tlbi.vmid);
Robin Murphy7417b992018-03-26 13:35:12 +0100922 cmd[0] |= FIELD_PREP(CMDQ_TLBI_0_ASID, ent->tlbi.asid);
923 cmd[1] |= FIELD_PREP(CMDQ_TLBI_1_LEAF, ent->tlbi.leaf);
Rob Herring6a481a92020-02-24 16:31:29 -0600924 cmd[1] |= FIELD_PREP(CMDQ_TLBI_1_TTL, ent->tlbi.ttl);
925 cmd[1] |= FIELD_PREP(CMDQ_TLBI_1_TG, ent->tlbi.tg);
Will Deacon1c27df12015-09-18 16:12:56 +0100926 cmd[1] |= ent->tlbi.addr & CMDQ_TLBI_1_VA_MASK;
927 break;
Will Deacon48ec83b2015-05-27 17:25:59 +0100928 case CMDQ_OP_TLBI_S2_IPA:
Rob Herring6a481a92020-02-24 16:31:29 -0600929 cmd[0] |= FIELD_PREP(CMDQ_TLBI_0_NUM, ent->tlbi.num);
930 cmd[0] |= FIELD_PREP(CMDQ_TLBI_0_SCALE, ent->tlbi.scale);
Robin Murphy7417b992018-03-26 13:35:12 +0100931 cmd[0] |= FIELD_PREP(CMDQ_TLBI_0_VMID, ent->tlbi.vmid);
932 cmd[1] |= FIELD_PREP(CMDQ_TLBI_1_LEAF, ent->tlbi.leaf);
Rob Herring6a481a92020-02-24 16:31:29 -0600933 cmd[1] |= FIELD_PREP(CMDQ_TLBI_1_TTL, ent->tlbi.ttl);
934 cmd[1] |= FIELD_PREP(CMDQ_TLBI_1_TG, ent->tlbi.tg);
Will Deacon1c27df12015-09-18 16:12:56 +0100935 cmd[1] |= ent->tlbi.addr & CMDQ_TLBI_1_IPA_MASK;
Will Deacon48ec83b2015-05-27 17:25:59 +0100936 break;
937 case CMDQ_OP_TLBI_NH_ASID:
Robin Murphy7417b992018-03-26 13:35:12 +0100938 cmd[0] |= FIELD_PREP(CMDQ_TLBI_0_ASID, ent->tlbi.asid);
Will Deacon48ec83b2015-05-27 17:25:59 +0100939 /* Fallthrough */
940 case CMDQ_OP_TLBI_S12_VMALL:
Robin Murphy7417b992018-03-26 13:35:12 +0100941 cmd[0] |= FIELD_PREP(CMDQ_TLBI_0_VMID, ent->tlbi.vmid);
Will Deacon48ec83b2015-05-27 17:25:59 +0100942 break;
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +0100943 case CMDQ_OP_ATC_INV:
944 cmd[0] |= FIELD_PREP(CMDQ_0_SSV, ent->substream_valid);
945 cmd[0] |= FIELD_PREP(CMDQ_ATC_0_GLOBAL, ent->atc.global);
946 cmd[0] |= FIELD_PREP(CMDQ_ATC_0_SSID, ent->atc.ssid);
947 cmd[0] |= FIELD_PREP(CMDQ_ATC_0_SID, ent->atc.sid);
948 cmd[1] |= FIELD_PREP(CMDQ_ATC_1_SIZE, ent->atc.size);
949 cmd[1] |= ent->atc.addr & CMDQ_ATC_1_ADDR_MASK;
950 break;
Will Deacon48ec83b2015-05-27 17:25:59 +0100951 case CMDQ_OP_PRI_RESP:
Robin Murphy7417b992018-03-26 13:35:12 +0100952 cmd[0] |= FIELD_PREP(CMDQ_0_SSV, ent->substream_valid);
953 cmd[0] |= FIELD_PREP(CMDQ_PRI_0_SSID, ent->pri.ssid);
954 cmd[0] |= FIELD_PREP(CMDQ_PRI_0_SID, ent->pri.sid);
955 cmd[1] |= FIELD_PREP(CMDQ_PRI_1_GRPID, ent->pri.grpid);
Will Deacon48ec83b2015-05-27 17:25:59 +0100956 switch (ent->pri.resp) {
957 case PRI_RESP_DENY:
Will Deacon48ec83b2015-05-27 17:25:59 +0100958 case PRI_RESP_FAIL:
Will Deacon48ec83b2015-05-27 17:25:59 +0100959 case PRI_RESP_SUCC:
Will Deacon48ec83b2015-05-27 17:25:59 +0100960 break;
961 default:
962 return -EINVAL;
963 }
Robin Murphy7417b992018-03-26 13:35:12 +0100964 cmd[1] |= FIELD_PREP(CMDQ_PRI_1_RESP, ent->pri.resp);
Will Deacon48ec83b2015-05-27 17:25:59 +0100965 break;
966 case CMDQ_OP_CMD_SYNC:
Will Deacon587e6c12019-07-02 17:16:25 +0100967 if (ent->sync.msiaddr) {
Robin Murphy7417b992018-03-26 13:35:12 +0100968 cmd[0] |= FIELD_PREP(CMDQ_SYNC_0_CS, CMDQ_SYNC_0_CS_IRQ);
Will Deacon587e6c12019-07-02 17:16:25 +0100969 cmd[1] |= ent->sync.msiaddr & CMDQ_SYNC_1_MSIADDR_MASK;
970 } else {
Robin Murphy7417b992018-03-26 13:35:12 +0100971 cmd[0] |= FIELD_PREP(CMDQ_SYNC_0_CS, CMDQ_SYNC_0_CS_SEV);
Will Deacon587e6c12019-07-02 17:16:25 +0100972 }
Robin Murphy7417b992018-03-26 13:35:12 +0100973 cmd[0] |= FIELD_PREP(CMDQ_SYNC_0_MSH, ARM_SMMU_SH_ISH);
974 cmd[0] |= FIELD_PREP(CMDQ_SYNC_0_MSIATTR, ARM_SMMU_MEMATTR_OIWB);
Will Deacon48ec83b2015-05-27 17:25:59 +0100975 break;
976 default:
977 return -ENOENT;
978 }
979
980 return 0;
981}
982
Will Deacon587e6c12019-07-02 17:16:25 +0100983static void arm_smmu_cmdq_build_sync_cmd(u64 *cmd, struct arm_smmu_device *smmu,
984 u32 prod)
985{
986 struct arm_smmu_queue *q = &smmu->cmdq.q;
987 struct arm_smmu_cmdq_ent ent = {
988 .opcode = CMDQ_OP_CMD_SYNC,
989 };
990
991 /*
992 * Beware that Hi16xx adds an extra 32 bits of goodness to its MSI
993 * payload, so the write will zero the entire command on that platform.
994 */
995 if (smmu->features & ARM_SMMU_FEAT_MSI &&
996 smmu->features & ARM_SMMU_FEAT_COHERENCY) {
997 ent.sync.msiaddr = q->base_dma + Q_IDX(&q->llq, prod) *
998 q->ent_dwords * 8;
999 }
1000
1001 arm_smmu_cmdq_build_cmd(cmd, &ent);
1002}
1003
Will Deacon48ec83b2015-05-27 17:25:59 +01001004static void arm_smmu_cmdq_skip_err(struct arm_smmu_device *smmu)
1005{
1006 static const char *cerror_str[] = {
1007 [CMDQ_ERR_CERROR_NONE_IDX] = "No error",
1008 [CMDQ_ERR_CERROR_ILL_IDX] = "Illegal command",
1009 [CMDQ_ERR_CERROR_ABT_IDX] = "Abort on command fetch",
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +01001010 [CMDQ_ERR_CERROR_ATC_INV_IDX] = "ATC invalidate timeout",
Will Deacon48ec83b2015-05-27 17:25:59 +01001011 };
1012
1013 int i;
1014 u64 cmd[CMDQ_ENT_DWORDS];
1015 struct arm_smmu_queue *q = &smmu->cmdq.q;
1016 u32 cons = readl_relaxed(q->cons_reg);
Robin Murphycbcee192018-03-26 13:35:10 +01001017 u32 idx = FIELD_GET(CMDQ_CONS_ERR, cons);
Will Deacon48ec83b2015-05-27 17:25:59 +01001018 struct arm_smmu_cmdq_ent cmd_sync = {
1019 .opcode = CMDQ_OP_CMD_SYNC,
1020 };
1021
1022 dev_err(smmu->dev, "CMDQ error (cons 0x%08x): %s\n", cons,
Will Deacona0d5c042015-12-04 12:00:29 +00001023 idx < ARRAY_SIZE(cerror_str) ? cerror_str[idx] : "Unknown");
Will Deacon48ec83b2015-05-27 17:25:59 +01001024
1025 switch (idx) {
Will Deacon48ec83b2015-05-27 17:25:59 +01001026 case CMDQ_ERR_CERROR_ABT_IDX:
1027 dev_err(smmu->dev, "retrying command fetch\n");
1028 case CMDQ_ERR_CERROR_NONE_IDX:
1029 return;
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +01001030 case CMDQ_ERR_CERROR_ATC_INV_IDX:
1031 /*
1032 * ATC Invalidation Completion timeout. CONS is still pointing
1033 * at the CMD_SYNC. Attempt to complete other pending commands
1034 * by repeating the CMD_SYNC, though we might well end up back
1035 * here since the ATC invalidation may still be pending.
1036 */
1037 return;
Will Deacona0d5c042015-12-04 12:00:29 +00001038 case CMDQ_ERR_CERROR_ILL_IDX:
1039 /* Fallthrough */
1040 default:
1041 break;
Will Deacon48ec83b2015-05-27 17:25:59 +01001042 }
1043
1044 /*
1045 * We may have concurrent producers, so we need to be careful
1046 * not to touch any of the shadow cmdq state.
1047 */
Will Deaconaea20372016-07-29 11:15:37 +01001048 queue_read(cmd, Q_ENT(q, cons), q->ent_dwords);
Will Deacon48ec83b2015-05-27 17:25:59 +01001049 dev_err(smmu->dev, "skipping command in error state:\n");
1050 for (i = 0; i < ARRAY_SIZE(cmd); ++i)
1051 dev_err(smmu->dev, "\t0x%016llx\n", (unsigned long long)cmd[i]);
1052
1053 /* Convert the erroneous command into a CMD_SYNC */
1054 if (arm_smmu_cmdq_build_cmd(cmd, &cmd_sync)) {
1055 dev_err(smmu->dev, "failed to convert to CMD_SYNC\n");
1056 return;
1057 }
1058
Will Deaconaea20372016-07-29 11:15:37 +01001059 queue_write(Q_ENT(q, cons), cmd, q->ent_dwords);
Will Deacon48ec83b2015-05-27 17:25:59 +01001060}
1061
Will Deacon587e6c12019-07-02 17:16:25 +01001062/*
1063 * Command queue locking.
1064 * This is a form of bastardised rwlock with the following major changes:
1065 *
1066 * - The only LOCK routines are exclusive_trylock() and shared_lock().
1067 * Neither have barrier semantics, and instead provide only a control
1068 * dependency.
1069 *
1070 * - The UNLOCK routines are supplemented with shared_tryunlock(), which
1071 * fails if the caller appears to be the last lock holder (yes, this is
1072 * racy). All successful UNLOCK routines have RELEASE semantics.
1073 */
1074static void arm_smmu_cmdq_shared_lock(struct arm_smmu_cmdq *cmdq)
Robin Murphy2f657ad2017-08-31 14:44:25 +01001075{
Will Deacon587e6c12019-07-02 17:16:25 +01001076 int val;
Robin Murphy2f657ad2017-08-31 14:44:25 +01001077
Will Deacon587e6c12019-07-02 17:16:25 +01001078 /*
1079 * We can try to avoid the cmpxchg() loop by simply incrementing the
1080 * lock counter. When held in exclusive state, the lock counter is set
1081 * to INT_MIN so these increments won't hurt as the value will remain
1082 * negative.
1083 */
1084 if (atomic_fetch_inc_relaxed(&cmdq->lock) >= 0)
1085 return;
Zhen Lei901510e2018-08-19 15:51:11 +08001086
Will Deacon587e6c12019-07-02 17:16:25 +01001087 do {
1088 val = atomic_cond_read_relaxed(&cmdq->lock, VAL >= 0);
1089 } while (atomic_cmpxchg_relaxed(&cmdq->lock, val, val + 1) != val);
1090}
1091
1092static void arm_smmu_cmdq_shared_unlock(struct arm_smmu_cmdq *cmdq)
1093{
1094 (void)atomic_dec_return_release(&cmdq->lock);
1095}
1096
1097static bool arm_smmu_cmdq_shared_tryunlock(struct arm_smmu_cmdq *cmdq)
1098{
1099 if (atomic_read(&cmdq->lock) == 1)
1100 return false;
1101
1102 arm_smmu_cmdq_shared_unlock(cmdq);
1103 return true;
1104}
1105
1106#define arm_smmu_cmdq_exclusive_trylock_irqsave(cmdq, flags) \
1107({ \
1108 bool __ret; \
1109 local_irq_save(flags); \
1110 __ret = !atomic_cmpxchg_relaxed(&cmdq->lock, 0, INT_MIN); \
1111 if (!__ret) \
1112 local_irq_restore(flags); \
1113 __ret; \
1114})
1115
1116#define arm_smmu_cmdq_exclusive_unlock_irqrestore(cmdq, flags) \
1117({ \
1118 atomic_set_release(&cmdq->lock, 0); \
1119 local_irq_restore(flags); \
1120})
1121
1122
1123/*
1124 * Command queue insertion.
1125 * This is made fiddly by our attempts to achieve some sort of scalability
1126 * since there is one queue shared amongst all of the CPUs in the system. If
1127 * you like mixed-size concurrency, dependency ordering and relaxed atomics,
1128 * then you'll *love* this monstrosity.
1129 *
1130 * The basic idea is to split the queue up into ranges of commands that are
1131 * owned by a given CPU; the owner may not have written all of the commands
1132 * itself, but is responsible for advancing the hardware prod pointer when
1133 * the time comes. The algorithm is roughly:
1134 *
1135 * 1. Allocate some space in the queue. At this point we also discover
1136 * whether the head of the queue is currently owned by another CPU,
1137 * or whether we are the owner.
1138 *
1139 * 2. Write our commands into our allocated slots in the queue.
1140 *
1141 * 3. Mark our slots as valid in arm_smmu_cmdq.valid_map.
1142 *
1143 * 4. If we are an owner:
1144 * a. Wait for the previous owner to finish.
1145 * b. Mark the queue head as unowned, which tells us the range
1146 * that we are responsible for publishing.
1147 * c. Wait for all commands in our owned range to become valid.
1148 * d. Advance the hardware prod pointer.
1149 * e. Tell the next owner we've finished.
1150 *
1151 * 5. If we are inserting a CMD_SYNC (we may or may not have been an
1152 * owner), then we need to stick around until it has completed:
1153 * a. If we have MSIs, the SMMU can write back into the CMD_SYNC
1154 * to clear the first 4 bytes.
1155 * b. Otherwise, we spin waiting for the hardware cons pointer to
1156 * advance past our command.
1157 *
1158 * The devil is in the details, particularly the use of locking for handling
1159 * SYNC completion and freeing up space in the queue before we think that it is
1160 * full.
1161 */
1162static void __arm_smmu_cmdq_poll_set_valid_map(struct arm_smmu_cmdq *cmdq,
1163 u32 sprod, u32 eprod, bool set)
1164{
1165 u32 swidx, sbidx, ewidx, ebidx;
1166 struct arm_smmu_ll_queue llq = {
1167 .max_n_shift = cmdq->q.llq.max_n_shift,
1168 .prod = sprod,
1169 };
1170
1171 ewidx = BIT_WORD(Q_IDX(&llq, eprod));
1172 ebidx = Q_IDX(&llq, eprod) % BITS_PER_LONG;
1173
1174 while (llq.prod != eprod) {
1175 unsigned long mask;
1176 atomic_long_t *ptr;
1177 u32 limit = BITS_PER_LONG;
1178
1179 swidx = BIT_WORD(Q_IDX(&llq, llq.prod));
1180 sbidx = Q_IDX(&llq, llq.prod) % BITS_PER_LONG;
1181
1182 ptr = &cmdq->valid_map[swidx];
1183
1184 if ((swidx == ewidx) && (sbidx < ebidx))
1185 limit = ebidx;
1186
1187 mask = GENMASK(limit - 1, sbidx);
1188
1189 /*
1190 * The valid bit is the inverse of the wrap bit. This means
1191 * that a zero-initialised queue is invalid and, after marking
1192 * all entries as valid, they become invalid again when we
1193 * wrap.
1194 */
1195 if (set) {
1196 atomic_long_xor(mask, ptr);
1197 } else { /* Poll */
1198 unsigned long valid;
1199
1200 valid = (ULONG_MAX + !!Q_WRP(&llq, llq.prod)) & mask;
1201 atomic_long_cond_read_relaxed(ptr, (VAL & mask) == valid);
1202 }
1203
1204 llq.prod = queue_inc_prod_n(&llq, limit - sbidx);
Robin Murphy2f657ad2017-08-31 14:44:25 +01001205 }
1206}
1207
Will Deacon587e6c12019-07-02 17:16:25 +01001208/* Mark all entries in the range [sprod, eprod) as valid */
1209static void arm_smmu_cmdq_set_valid_map(struct arm_smmu_cmdq *cmdq,
1210 u32 sprod, u32 eprod)
1211{
1212 __arm_smmu_cmdq_poll_set_valid_map(cmdq, sprod, eprod, true);
1213}
1214
1215/* Wait for all entries in the range [sprod, eprod) to become valid */
1216static void arm_smmu_cmdq_poll_valid_map(struct arm_smmu_cmdq *cmdq,
1217 u32 sprod, u32 eprod)
1218{
1219 __arm_smmu_cmdq_poll_set_valid_map(cmdq, sprod, eprod, false);
1220}
1221
1222/* Wait for the command queue to become non-full */
1223static int arm_smmu_cmdq_poll_until_not_full(struct arm_smmu_device *smmu,
1224 struct arm_smmu_ll_queue *llq)
1225{
1226 unsigned long flags;
1227 struct arm_smmu_queue_poll qp;
1228 struct arm_smmu_cmdq *cmdq = &smmu->cmdq;
1229 int ret = 0;
1230
1231 /*
1232 * Try to update our copy of cons by grabbing exclusive cmdq access. If
1233 * that fails, spin until somebody else updates it for us.
1234 */
1235 if (arm_smmu_cmdq_exclusive_trylock_irqsave(cmdq, flags)) {
1236 WRITE_ONCE(cmdq->q.llq.cons, readl_relaxed(cmdq->q.cons_reg));
1237 arm_smmu_cmdq_exclusive_unlock_irqrestore(cmdq, flags);
1238 llq->val = READ_ONCE(cmdq->q.llq.val);
1239 return 0;
1240 }
1241
1242 queue_poll_init(smmu, &qp);
1243 do {
1244 llq->val = READ_ONCE(smmu->cmdq.q.llq.val);
1245 if (!queue_full(llq))
1246 break;
1247
1248 ret = queue_poll(&qp);
1249 } while (!ret);
1250
1251 return ret;
1252}
1253
1254/*
1255 * Wait until the SMMU signals a CMD_SYNC completion MSI.
1256 * Must be called with the cmdq lock held in some capacity.
1257 */
1258static int __arm_smmu_cmdq_poll_until_msi(struct arm_smmu_device *smmu,
1259 struct arm_smmu_ll_queue *llq)
1260{
1261 int ret = 0;
1262 struct arm_smmu_queue_poll qp;
1263 struct arm_smmu_cmdq *cmdq = &smmu->cmdq;
1264 u32 *cmd = (u32 *)(Q_ENT(&cmdq->q, llq->prod));
1265
1266 queue_poll_init(smmu, &qp);
1267
1268 /*
1269 * The MSI won't generate an event, since it's being written back
1270 * into the command queue.
1271 */
1272 qp.wfe = false;
1273 smp_cond_load_relaxed(cmd, !VAL || (ret = queue_poll(&qp)));
1274 llq->cons = ret ? llq->prod : queue_inc_prod_n(llq, 1);
1275 return ret;
1276}
1277
1278/*
1279 * Wait until the SMMU cons index passes llq->prod.
1280 * Must be called with the cmdq lock held in some capacity.
1281 */
1282static int __arm_smmu_cmdq_poll_until_consumed(struct arm_smmu_device *smmu,
1283 struct arm_smmu_ll_queue *llq)
1284{
1285 struct arm_smmu_queue_poll qp;
1286 struct arm_smmu_cmdq *cmdq = &smmu->cmdq;
1287 u32 prod = llq->prod;
1288 int ret = 0;
1289
1290 queue_poll_init(smmu, &qp);
1291 llq->val = READ_ONCE(smmu->cmdq.q.llq.val);
1292 do {
1293 if (queue_consumed(llq, prod))
1294 break;
1295
1296 ret = queue_poll(&qp);
1297
1298 /*
1299 * This needs to be a readl() so that our subsequent call
1300 * to arm_smmu_cmdq_shared_tryunlock() can fail accurately.
1301 *
1302 * Specifically, we need to ensure that we observe all
1303 * shared_lock()s by other CMD_SYNCs that share our owner,
1304 * so that a failing call to tryunlock() means that we're
1305 * the last one out and therefore we can safely advance
1306 * cmdq->q.llq.cons. Roughly speaking:
1307 *
1308 * CPU 0 CPU1 CPU2 (us)
1309 *
1310 * if (sync)
1311 * shared_lock();
1312 *
1313 * dma_wmb();
1314 * set_valid_map();
1315 *
1316 * if (owner) {
1317 * poll_valid_map();
1318 * <control dependency>
1319 * writel(prod_reg);
1320 *
1321 * readl(cons_reg);
1322 * tryunlock();
1323 *
1324 * Requires us to see CPU 0's shared_lock() acquisition.
1325 */
1326 llq->cons = readl(cmdq->q.cons_reg);
1327 } while (!ret);
1328
1329 return ret;
1330}
1331
1332static int arm_smmu_cmdq_poll_until_sync(struct arm_smmu_device *smmu,
1333 struct arm_smmu_ll_queue *llq)
1334{
1335 if (smmu->features & ARM_SMMU_FEAT_MSI &&
1336 smmu->features & ARM_SMMU_FEAT_COHERENCY)
1337 return __arm_smmu_cmdq_poll_until_msi(smmu, llq);
1338
1339 return __arm_smmu_cmdq_poll_until_consumed(smmu, llq);
1340}
1341
1342static void arm_smmu_cmdq_write_entries(struct arm_smmu_cmdq *cmdq, u64 *cmds,
1343 u32 prod, int n)
1344{
1345 int i;
1346 struct arm_smmu_ll_queue llq = {
1347 .max_n_shift = cmdq->q.llq.max_n_shift,
1348 .prod = prod,
1349 };
1350
1351 for (i = 0; i < n; ++i) {
1352 u64 *cmd = &cmds[i * CMDQ_ENT_DWORDS];
1353
1354 prod = queue_inc_prod_n(&llq, i);
1355 queue_write(Q_ENT(&cmdq->q, prod), cmd, CMDQ_ENT_DWORDS);
1356 }
1357}
1358
Will Deacon05cbaf42019-08-20 13:25:36 +01001359/*
1360 * This is the actual insertion function, and provides the following
1361 * ordering guarantees to callers:
1362 *
1363 * - There is a dma_wmb() before publishing any commands to the queue.
1364 * This can be relied upon to order prior writes to data structures
1365 * in memory (such as a CD or an STE) before the command.
1366 *
1367 * - On completion of a CMD_SYNC, there is a control dependency.
1368 * This can be relied upon to order subsequent writes to memory (e.g.
1369 * freeing an IOVA) after completion of the CMD_SYNC.
1370 *
1371 * - Command insertion is totally ordered, so if two CPUs each race to
1372 * insert their own list of commands then all of the commands from one
1373 * CPU will appear before any of the commands from the other CPU.
1374 */
Will Deacon587e6c12019-07-02 17:16:25 +01001375static int arm_smmu_cmdq_issue_cmdlist(struct arm_smmu_device *smmu,
1376 u64 *cmds, int n, bool sync)
1377{
1378 u64 cmd_sync[CMDQ_ENT_DWORDS];
1379 u32 prod;
1380 unsigned long flags;
1381 bool owner;
1382 struct arm_smmu_cmdq *cmdq = &smmu->cmdq;
1383 struct arm_smmu_ll_queue llq = {
1384 .max_n_shift = cmdq->q.llq.max_n_shift,
1385 }, head = llq;
1386 int ret = 0;
1387
1388 /* 1. Allocate some space in the queue */
1389 local_irq_save(flags);
1390 llq.val = READ_ONCE(cmdq->q.llq.val);
1391 do {
1392 u64 old;
1393
1394 while (!queue_has_space(&llq, n + sync)) {
1395 local_irq_restore(flags);
1396 if (arm_smmu_cmdq_poll_until_not_full(smmu, &llq))
1397 dev_err_ratelimited(smmu->dev, "CMDQ timeout\n");
1398 local_irq_save(flags);
1399 }
1400
1401 head.cons = llq.cons;
1402 head.prod = queue_inc_prod_n(&llq, n + sync) |
1403 CMDQ_PROD_OWNED_FLAG;
1404
1405 old = cmpxchg_relaxed(&cmdq->q.llq.val, llq.val, head.val);
1406 if (old == llq.val)
1407 break;
1408
1409 llq.val = old;
1410 } while (1);
1411 owner = !(llq.prod & CMDQ_PROD_OWNED_FLAG);
1412 head.prod &= ~CMDQ_PROD_OWNED_FLAG;
1413 llq.prod &= ~CMDQ_PROD_OWNED_FLAG;
1414
1415 /*
1416 * 2. Write our commands into the queue
1417 * Dependency ordering from the cmpxchg() loop above.
1418 */
1419 arm_smmu_cmdq_write_entries(cmdq, cmds, llq.prod, n);
1420 if (sync) {
1421 prod = queue_inc_prod_n(&llq, n);
1422 arm_smmu_cmdq_build_sync_cmd(cmd_sync, smmu, prod);
1423 queue_write(Q_ENT(&cmdq->q, prod), cmd_sync, CMDQ_ENT_DWORDS);
1424
1425 /*
1426 * In order to determine completion of our CMD_SYNC, we must
1427 * ensure that the queue can't wrap twice without us noticing.
1428 * We achieve that by taking the cmdq lock as shared before
1429 * marking our slot as valid.
1430 */
1431 arm_smmu_cmdq_shared_lock(cmdq);
1432 }
1433
1434 /* 3. Mark our slots as valid, ensuring commands are visible first */
1435 dma_wmb();
1436 arm_smmu_cmdq_set_valid_map(cmdq, llq.prod, head.prod);
1437
1438 /* 4. If we are the owner, take control of the SMMU hardware */
1439 if (owner) {
1440 /* a. Wait for previous owner to finish */
1441 atomic_cond_read_relaxed(&cmdq->owner_prod, VAL == llq.prod);
1442
1443 /* b. Stop gathering work by clearing the owned flag */
1444 prod = atomic_fetch_andnot_relaxed(CMDQ_PROD_OWNED_FLAG,
1445 &cmdq->q.llq.atomic.prod);
1446 prod &= ~CMDQ_PROD_OWNED_FLAG;
1447
1448 /*
1449 * c. Wait for any gathered work to be written to the queue.
1450 * Note that we read our own entries so that we have the control
1451 * dependency required by (d).
1452 */
1453 arm_smmu_cmdq_poll_valid_map(cmdq, llq.prod, prod);
1454
1455 /*
1456 * d. Advance the hardware prod pointer
1457 * Control dependency ordering from the entries becoming valid.
1458 */
1459 writel_relaxed(prod, cmdq->q.prod_reg);
1460
1461 /*
1462 * e. Tell the next owner we're done
1463 * Make sure we've updated the hardware first, so that we don't
1464 * race to update prod and potentially move it backwards.
1465 */
1466 atomic_set_release(&cmdq->owner_prod, prod);
1467 }
1468
1469 /* 5. If we are inserting a CMD_SYNC, we must wait for it to complete */
1470 if (sync) {
1471 llq.prod = queue_inc_prod_n(&llq, n);
1472 ret = arm_smmu_cmdq_poll_until_sync(smmu, &llq);
1473 if (ret) {
1474 dev_err_ratelimited(smmu->dev,
1475 "CMD_SYNC timeout at 0x%08x [hwprod 0x%08x, hwcons 0x%08x]\n",
1476 llq.prod,
1477 readl_relaxed(cmdq->q.prod_reg),
1478 readl_relaxed(cmdq->q.cons_reg));
1479 }
1480
1481 /*
John Garry49fbb252020-06-23 01:28:37 +08001482 * Try to unlock the cmdq lock. This will fail if we're the last
Will Deacon587e6c12019-07-02 17:16:25 +01001483 * reader, in which case we can safely update cmdq->q.llq.cons
1484 */
1485 if (!arm_smmu_cmdq_shared_tryunlock(cmdq)) {
1486 WRITE_ONCE(cmdq->q.llq.cons, llq.cons);
1487 arm_smmu_cmdq_shared_unlock(cmdq);
1488 }
1489 }
1490
1491 local_irq_restore(flags);
1492 return ret;
1493}
1494
1495static int arm_smmu_cmdq_issue_cmd(struct arm_smmu_device *smmu,
1496 struct arm_smmu_cmdq_ent *ent)
Will Deacon48ec83b2015-05-27 17:25:59 +01001497{
Will Deacon48ec83b2015-05-27 17:25:59 +01001498 u64 cmd[CMDQ_ENT_DWORDS];
Will Deacon48ec83b2015-05-27 17:25:59 +01001499
1500 if (arm_smmu_cmdq_build_cmd(cmd, ent)) {
1501 dev_warn(smmu->dev, "ignoring unknown CMDQ opcode 0x%x\n",
1502 ent->opcode);
Will Deacon587e6c12019-07-02 17:16:25 +01001503 return -EINVAL;
Will Deacon48ec83b2015-05-27 17:25:59 +01001504 }
1505
Will Deacon587e6c12019-07-02 17:16:25 +01001506 return arm_smmu_cmdq_issue_cmdlist(smmu, cmd, 1, false);
Will Deacon49806592017-10-19 16:41:53 +01001507}
1508
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +01001509static int arm_smmu_cmdq_issue_sync(struct arm_smmu_device *smmu)
Will Deacon49806592017-10-19 16:41:53 +01001510{
Will Deacon587e6c12019-07-02 17:16:25 +01001511 return arm_smmu_cmdq_issue_cmdlist(smmu, NULL, 0, true);
Robin Murphy2f657ad2017-08-31 14:44:25 +01001512}
1513
Jean-Philippe Brucker4ce8da42020-02-24 17:58:44 +01001514static void arm_smmu_cmdq_batch_add(struct arm_smmu_device *smmu,
1515 struct arm_smmu_cmdq_batch *cmds,
1516 struct arm_smmu_cmdq_ent *cmd)
1517{
1518 if (cmds->num == CMDQ_BATCH_ENTRIES) {
1519 arm_smmu_cmdq_issue_cmdlist(smmu, cmds->cmds, cmds->num, false);
1520 cmds->num = 0;
1521 }
1522 arm_smmu_cmdq_build_cmd(&cmds->cmds[cmds->num * CMDQ_ENT_DWORDS], cmd);
1523 cmds->num++;
1524}
1525
1526static int arm_smmu_cmdq_batch_submit(struct arm_smmu_device *smmu,
1527 struct arm_smmu_cmdq_batch *cmds)
1528{
1529 return arm_smmu_cmdq_issue_cmdlist(smmu, cmds->cmds, cmds->num, true);
1530}
1531
Will Deacon48ec83b2015-05-27 17:25:59 +01001532/* Context descriptor manipulation functions */
Jean-Philippe Brucker87f42392020-01-15 13:52:33 +01001533static void arm_smmu_sync_cd(struct arm_smmu_domain *smmu_domain,
1534 int ssid, bool leaf)
Will Deacon48ec83b2015-05-27 17:25:59 +01001535{
Jean-Philippe Brucker87f42392020-01-15 13:52:33 +01001536 size_t i;
1537 unsigned long flags;
1538 struct arm_smmu_master *master;
Jean-Philippe Bruckeredd03512020-02-24 17:58:45 +01001539 struct arm_smmu_cmdq_batch cmds = {};
Jean-Philippe Brucker87f42392020-01-15 13:52:33 +01001540 struct arm_smmu_device *smmu = smmu_domain->smmu;
1541 struct arm_smmu_cmdq_ent cmd = {
1542 .opcode = CMDQ_OP_CFGI_CD,
1543 .cfgi = {
1544 .ssid = ssid,
1545 .leaf = leaf,
1546 },
1547 };
Will Deacon48ec83b2015-05-27 17:25:59 +01001548
Jean-Philippe Brucker87f42392020-01-15 13:52:33 +01001549 spin_lock_irqsave(&smmu_domain->devices_lock, flags);
1550 list_for_each_entry(master, &smmu_domain->devices, domain_head) {
1551 for (i = 0; i < master->num_sids; i++) {
1552 cmd.cfgi.sid = master->sids[i];
Jean-Philippe Bruckeredd03512020-02-24 17:58:45 +01001553 arm_smmu_cmdq_batch_add(smmu, &cmds, &cmd);
Jean-Philippe Brucker87f42392020-01-15 13:52:33 +01001554 }
1555 }
1556 spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
Will Deacon48ec83b2015-05-27 17:25:59 +01001557
Jean-Philippe Bruckeredd03512020-02-24 17:58:45 +01001558 arm_smmu_cmdq_batch_submit(smmu, &cmds);
Will Deacon48ec83b2015-05-27 17:25:59 +01001559}
1560
Jean-Philippe Brucker73af06f2020-01-15 13:52:36 +01001561static int arm_smmu_alloc_cd_leaf_table(struct arm_smmu_device *smmu,
1562 struct arm_smmu_l1_ctx_desc *l1_desc)
Will Deacon48ec83b2015-05-27 17:25:59 +01001563{
Jean-Philippe Brucker73af06f2020-01-15 13:52:36 +01001564 size_t size = CTXDESC_L2_ENTRIES * (CTXDESC_CD_DWORDS << 3);
1565
1566 l1_desc->l2ptr = dmam_alloc_coherent(smmu->dev, size,
1567 &l1_desc->l2ptr_dma, GFP_KERNEL);
1568 if (!l1_desc->l2ptr) {
1569 dev_warn(smmu->dev,
1570 "failed to allocate context descriptor table\n");
1571 return -ENOMEM;
1572 }
1573 return 0;
1574}
1575
1576static void arm_smmu_write_cd_l1_desc(__le64 *dst,
1577 struct arm_smmu_l1_ctx_desc *l1_desc)
1578{
1579 u64 val = (l1_desc->l2ptr_dma & CTXDESC_L1_DESC_L2PTR_MASK) |
1580 CTXDESC_L1_DESC_V;
1581
Jean-Philippe Brucker87e5fe52020-02-24 17:58:43 +01001582 /* See comment in arm_smmu_write_ctx_desc() */
Jean-Philippe Brucker73af06f2020-01-15 13:52:36 +01001583 WRITE_ONCE(*dst, cpu_to_le64(val));
1584}
1585
1586static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_domain *smmu_domain,
1587 u32 ssid)
1588{
1589 __le64 *l1ptr;
1590 unsigned int idx;
1591 struct arm_smmu_l1_ctx_desc *l1_desc;
1592 struct arm_smmu_device *smmu = smmu_domain->smmu;
1593 struct arm_smmu_ctx_desc_cfg *cdcfg = &smmu_domain->s1_cfg.cdcfg;
1594
1595 if (smmu_domain->s1_cfg.s1fmt == STRTAB_STE_0_S1FMT_LINEAR)
1596 return cdcfg->cdtab + ssid * CTXDESC_CD_DWORDS;
1597
1598 idx = ssid >> CTXDESC_SPLIT;
1599 l1_desc = &cdcfg->l1_desc[idx];
1600 if (!l1_desc->l2ptr) {
1601 if (arm_smmu_alloc_cd_leaf_table(smmu, l1_desc))
1602 return NULL;
1603
1604 l1ptr = cdcfg->cdtab + idx * CTXDESC_L1_DESC_DWORDS;
1605 arm_smmu_write_cd_l1_desc(l1ptr, l1_desc);
1606 /* An invalid L1CD can be cached */
1607 arm_smmu_sync_cd(smmu_domain, ssid, false);
1608 }
1609 idx = ssid & (CTXDESC_L2_ENTRIES - 1);
1610 return l1_desc->l2ptr + idx * CTXDESC_CD_DWORDS;
1611}
1612
Jean-Philippe Brucker87f42392020-01-15 13:52:33 +01001613static int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain,
1614 int ssid, struct arm_smmu_ctx_desc *cd)
1615{
1616 /*
1617 * This function handles the following cases:
1618 *
1619 * (1) Install primary CD, for normal DMA traffic (SSID = 0).
1620 * (2) Install a secondary CD, for SID+SSID traffic.
1621 * (3) Update ASID of a CD. Atomically write the first 64 bits of the
1622 * CD, then invalidate the old entry and mappings.
1623 * (4) Remove a secondary CD.
1624 */
Will Deacon48ec83b2015-05-27 17:25:59 +01001625 u64 val;
Jean-Philippe Brucker87f42392020-01-15 13:52:33 +01001626 bool cd_live;
Jean-Philippe Brucker73af06f2020-01-15 13:52:36 +01001627 __le64 *cdptr;
Jean-Philippe Brucker87f42392020-01-15 13:52:33 +01001628 struct arm_smmu_device *smmu = smmu_domain->smmu;
Jean-Philippe Brucker73af06f2020-01-15 13:52:36 +01001629
1630 if (WARN_ON(ssid >= (1 << smmu_domain->s1_cfg.s1cdmax)))
1631 return -E2BIG;
1632
1633 cdptr = arm_smmu_get_cd_ptr(smmu_domain, ssid);
1634 if (!cdptr)
1635 return -ENOMEM;
Jean-Philippe Brucker87f42392020-01-15 13:52:33 +01001636
1637 val = le64_to_cpu(cdptr[0]);
1638 cd_live = !!(val & CTXDESC_CD_0_V);
1639
1640 if (!cd) { /* (4) */
1641 val = 0;
1642 } else if (cd_live) { /* (3) */
1643 val &= ~CTXDESC_CD_0_ASID;
1644 val |= FIELD_PREP(CTXDESC_CD_0_ASID, cd->asid);
1645 /*
1646 * Until CD+TLB invalidation, both ASIDs may be used for tagging
1647 * this substream's traffic
1648 */
1649 } else { /* (1) and (2) */
1650 cdptr[1] = cpu_to_le64(cd->ttbr & CTXDESC_CD_1_TTB0_MASK);
1651 cdptr[2] = 0;
1652 cdptr[3] = cpu_to_le64(cd->mair);
1653
1654 /*
1655 * STE is live, and the SMMU might read dwords of this CD in any
1656 * order. Ensure that it observes valid values before reading
1657 * V=1.
1658 */
1659 arm_smmu_sync_cd(smmu_domain, ssid, true);
1660
1661 val = cd->tcr |
1662#ifdef __BIG_ENDIAN
1663 CTXDESC_CD_0_ENDI |
1664#endif
1665 CTXDESC_CD_0_R | CTXDESC_CD_0_A | CTXDESC_CD_0_ASET |
1666 CTXDESC_CD_0_AA64 |
1667 FIELD_PREP(CTXDESC_CD_0_ASID, cd->asid) |
1668 CTXDESC_CD_0_V;
1669
1670 /* STALL_MODEL==0b10 && CD.S==0 is ILLEGAL */
1671 if (smmu->features & ARM_SMMU_FEAT_STALL_FORCE)
1672 val |= CTXDESC_CD_0_S;
1673 }
Will Deacon48ec83b2015-05-27 17:25:59 +01001674
1675 /*
Jean-Philippe Brucker87f42392020-01-15 13:52:33 +01001676 * The SMMU accesses 64-bit values atomically. See IHI0070Ca 3.21.3
1677 * "Configuration structures and configuration invalidation completion"
1678 *
1679 * The size of single-copy atomic reads made by the SMMU is
1680 * IMPLEMENTATION DEFINED but must be at least 64 bits. Any single
1681 * field within an aligned 64-bit span of a structure can be altered
1682 * without first making the structure invalid.
Will Deacon48ec83b2015-05-27 17:25:59 +01001683 */
Jean-Philippe Brucker87f42392020-01-15 13:52:33 +01001684 WRITE_ONCE(cdptr[0], cpu_to_le64(val));
1685 arm_smmu_sync_cd(smmu_domain, ssid, true);
1686 return 0;
Will Deacon48ec83b2015-05-27 17:25:59 +01001687}
Will Deacon48ec83b2015-05-27 17:25:59 +01001688
Jean-Philippe Bruckera557aff2020-01-15 13:52:32 +01001689static int arm_smmu_alloc_cd_tables(struct arm_smmu_domain *smmu_domain)
1690{
Jean-Philippe Brucker73af06f2020-01-15 13:52:36 +01001691 int ret;
Jean-Philippe Bruckera557aff2020-01-15 13:52:32 +01001692 size_t l1size;
Jean-Philippe Brucker73af06f2020-01-15 13:52:36 +01001693 size_t max_contexts;
Jean-Philippe Bruckera557aff2020-01-15 13:52:32 +01001694 struct arm_smmu_device *smmu = smmu_domain->smmu;
1695 struct arm_smmu_s1_cfg *cfg = &smmu_domain->s1_cfg;
1696 struct arm_smmu_ctx_desc_cfg *cdcfg = &cfg->cdcfg;
Will Deacon48ec83b2015-05-27 17:25:59 +01001697
Jean-Philippe Brucker73af06f2020-01-15 13:52:36 +01001698 max_contexts = 1 << cfg->s1cdmax;
Will Deacon48ec83b2015-05-27 17:25:59 +01001699
Jean-Philippe Brucker73af06f2020-01-15 13:52:36 +01001700 if (!(smmu->features & ARM_SMMU_FEAT_2_LVL_CDTAB) ||
1701 max_contexts <= CTXDESC_L2_ENTRIES) {
1702 cfg->s1fmt = STRTAB_STE_0_S1FMT_LINEAR;
1703 cdcfg->num_l1_ents = max_contexts;
Will Deacon48ec83b2015-05-27 17:25:59 +01001704
Jean-Philippe Brucker73af06f2020-01-15 13:52:36 +01001705 l1size = max_contexts * (CTXDESC_CD_DWORDS << 3);
1706 } else {
1707 cfg->s1fmt = STRTAB_STE_0_S1FMT_64K_L2;
1708 cdcfg->num_l1_ents = DIV_ROUND_UP(max_contexts,
1709 CTXDESC_L2_ENTRIES);
1710
1711 cdcfg->l1_desc = devm_kcalloc(smmu->dev, cdcfg->num_l1_ents,
1712 sizeof(*cdcfg->l1_desc),
1713 GFP_KERNEL);
1714 if (!cdcfg->l1_desc)
1715 return -ENOMEM;
1716
1717 l1size = cdcfg->num_l1_ents * (CTXDESC_L1_DESC_DWORDS << 3);
1718 }
1719
Jean-Philippe Bruckera557aff2020-01-15 13:52:32 +01001720 cdcfg->cdtab = dmam_alloc_coherent(smmu->dev, l1size, &cdcfg->cdtab_dma,
1721 GFP_KERNEL);
1722 if (!cdcfg->cdtab) {
1723 dev_warn(smmu->dev, "failed to allocate context descriptor\n");
Jean-Philippe Brucker73af06f2020-01-15 13:52:36 +01001724 ret = -ENOMEM;
1725 goto err_free_l1;
Jean-Philippe Bruckera557aff2020-01-15 13:52:32 +01001726 }
Jean-Philippe Brucker73af06f2020-01-15 13:52:36 +01001727
Jean-Philippe Bruckera557aff2020-01-15 13:52:32 +01001728 return 0;
Jean-Philippe Brucker73af06f2020-01-15 13:52:36 +01001729
1730err_free_l1:
1731 if (cdcfg->l1_desc) {
1732 devm_kfree(smmu->dev, cdcfg->l1_desc);
1733 cdcfg->l1_desc = NULL;
1734 }
1735 return ret;
Jean-Philippe Bruckera557aff2020-01-15 13:52:32 +01001736}
1737
1738static void arm_smmu_free_cd_tables(struct arm_smmu_domain *smmu_domain)
1739{
Jean-Philippe Brucker73af06f2020-01-15 13:52:36 +01001740 int i;
1741 size_t size, l1size;
Jean-Philippe Bruckera557aff2020-01-15 13:52:32 +01001742 struct arm_smmu_device *smmu = smmu_domain->smmu;
1743 struct arm_smmu_ctx_desc_cfg *cdcfg = &smmu_domain->s1_cfg.cdcfg;
Jean-Philippe Brucker73af06f2020-01-15 13:52:36 +01001744
1745 if (cdcfg->l1_desc) {
1746 size = CTXDESC_L2_ENTRIES * (CTXDESC_CD_DWORDS << 3);
1747
1748 for (i = 0; i < cdcfg->num_l1_ents; i++) {
1749 if (!cdcfg->l1_desc[i].l2ptr)
1750 continue;
1751
1752 dmam_free_coherent(smmu->dev, size,
1753 cdcfg->l1_desc[i].l2ptr,
1754 cdcfg->l1_desc[i].l2ptr_dma);
1755 }
1756 devm_kfree(smmu->dev, cdcfg->l1_desc);
1757 cdcfg->l1_desc = NULL;
1758
1759 l1size = cdcfg->num_l1_ents * (CTXDESC_L1_DESC_DWORDS << 3);
1760 } else {
1761 l1size = cdcfg->num_l1_ents * (CTXDESC_CD_DWORDS << 3);
1762 }
Jean-Philippe Bruckera557aff2020-01-15 13:52:32 +01001763
1764 dmam_free_coherent(smmu->dev, l1size, cdcfg->cdtab, cdcfg->cdtab_dma);
1765 cdcfg->cdtab_dma = 0;
1766 cdcfg->cdtab = NULL;
Will Deacon48ec83b2015-05-27 17:25:59 +01001767}
1768
Jean-Philippe Brucker0299a1a2020-05-19 19:54:46 +02001769static void arm_smmu_free_asid(struct arm_smmu_ctx_desc *cd)
1770{
1771 if (!cd->asid)
1772 return;
1773
1774 xa_erase(&asid_xa, cd->asid);
1775}
1776
Will Deacon48ec83b2015-05-27 17:25:59 +01001777/* Stream table manipulation functions */
1778static void
1779arm_smmu_write_strtab_l1_desc(__le64 *dst, struct arm_smmu_strtab_l1_desc *desc)
1780{
1781 u64 val = 0;
1782
Robin Murphyba08bdc2018-03-26 13:35:11 +01001783 val |= FIELD_PREP(STRTAB_L1_DESC_SPAN, desc->span);
Robin Murphy1cf9e542018-03-26 13:35:09 +01001784 val |= desc->l2ptr_dma & STRTAB_L1_DESC_L2PTR_MASK;
Will Deacon48ec83b2015-05-27 17:25:59 +01001785
Jean-Philippe Brucker87e5fe52020-02-24 17:58:43 +01001786 /* See comment in arm_smmu_write_ctx_desc() */
1787 WRITE_ONCE(*dst, cpu_to_le64(val));
Will Deacon48ec83b2015-05-27 17:25:59 +01001788}
1789
1790static void arm_smmu_sync_ste_for_sid(struct arm_smmu_device *smmu, u32 sid)
1791{
1792 struct arm_smmu_cmdq_ent cmd = {
1793 .opcode = CMDQ_OP_CFGI_STE,
1794 .cfgi = {
1795 .sid = sid,
1796 .leaf = true,
1797 },
1798 };
1799
1800 arm_smmu_cmdq_issue_cmd(smmu, &cmd);
Robin Murphy2f657ad2017-08-31 14:44:25 +01001801 arm_smmu_cmdq_issue_sync(smmu);
Will Deacon48ec83b2015-05-27 17:25:59 +01001802}
1803
Jean-Philippe Brucker8be39a12019-04-17 19:24:45 +01001804static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
1805 __le64 *dst)
Will Deacon48ec83b2015-05-27 17:25:59 +01001806{
1807 /*
1808 * This is hideously complicated, but we only really care about
1809 * three cases at the moment:
1810 *
Will Deaconbeb3c6a2017-01-06 16:27:30 +00001811 * 1. Invalid (all zero) -> bypass/fault (init)
1812 * 2. Bypass/fault -> translation/bypass (attach)
1813 * 3. Translation/bypass -> bypass/fault (detach)
Will Deacon48ec83b2015-05-27 17:25:59 +01001814 *
1815 * Given that we can't update the STE atomically and the SMMU
1816 * doesn't read the thing in a defined order, that leaves us
1817 * with the following maintenance requirements:
1818 *
1819 * 1. Update Config, return (init time STEs aren't live)
1820 * 2. Write everything apart from dword 0, sync, write dword 0, sync
1821 * 3. Update Config, sync
1822 */
1823 u64 val = le64_to_cpu(dst[0]);
1824 bool ste_live = false;
Jean-Philippe Brucker8be39a12019-04-17 19:24:45 +01001825 struct arm_smmu_device *smmu = NULL;
1826 struct arm_smmu_s1_cfg *s1_cfg = NULL;
1827 struct arm_smmu_s2_cfg *s2_cfg = NULL;
1828 struct arm_smmu_domain *smmu_domain = NULL;
Will Deacon48ec83b2015-05-27 17:25:59 +01001829 struct arm_smmu_cmdq_ent prefetch_cmd = {
1830 .opcode = CMDQ_OP_PREFETCH_CFG,
1831 .prefetch = {
1832 .sid = sid,
1833 },
1834 };
1835
Jean-Philippe Brucker8be39a12019-04-17 19:24:45 +01001836 if (master) {
1837 smmu_domain = master->domain;
1838 smmu = master->smmu;
1839 }
1840
1841 if (smmu_domain) {
1842 switch (smmu_domain->stage) {
1843 case ARM_SMMU_DOMAIN_S1:
1844 s1_cfg = &smmu_domain->s1_cfg;
1845 break;
1846 case ARM_SMMU_DOMAIN_S2:
1847 case ARM_SMMU_DOMAIN_NESTED:
1848 s2_cfg = &smmu_domain->s2_cfg;
1849 break;
1850 default:
1851 break;
1852 }
1853 }
1854
Will Deacon48ec83b2015-05-27 17:25:59 +01001855 if (val & STRTAB_STE_0_V) {
Robin Murphyba08bdc2018-03-26 13:35:11 +01001856 switch (FIELD_GET(STRTAB_STE_0_CFG, val)) {
Will Deacon48ec83b2015-05-27 17:25:59 +01001857 case STRTAB_STE_0_CFG_BYPASS:
1858 break;
1859 case STRTAB_STE_0_CFG_S1_TRANS:
1860 case STRTAB_STE_0_CFG_S2_TRANS:
1861 ste_live = true;
1862 break;
Will Deacon5bc0a112016-08-16 14:29:16 +01001863 case STRTAB_STE_0_CFG_ABORT:
Anders Roxell11f4fe92019-07-30 17:20:11 +02001864 BUG_ON(!disable_bypass);
1865 break;
Will Deacon48ec83b2015-05-27 17:25:59 +01001866 default:
1867 BUG(); /* STE corruption */
1868 }
1869 }
1870
Nate Watterson810871c2016-12-20 23:11:48 -05001871 /* Nuke the existing STE_0 value, as we're going to rewrite it */
Will Deaconbeb3c6a2017-01-06 16:27:30 +00001872 val = STRTAB_STE_0_V;
Will Deacon48ec83b2015-05-27 17:25:59 +01001873
Will Deaconbeb3c6a2017-01-06 16:27:30 +00001874 /* Bypass/fault */
Jean-Philippe Brucker8be39a12019-04-17 19:24:45 +01001875 if (!smmu_domain || !(s1_cfg || s2_cfg)) {
1876 if (!smmu_domain && disable_bypass)
Robin Murphyba08bdc2018-03-26 13:35:11 +01001877 val |= FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_ABORT);
Will Deaconbeb3c6a2017-01-06 16:27:30 +00001878 else
Robin Murphyba08bdc2018-03-26 13:35:11 +01001879 val |= FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_BYPASS);
Will Deaconbeb3c6a2017-01-06 16:27:30 +00001880
Will Deacon48ec83b2015-05-27 17:25:59 +01001881 dst[0] = cpu_to_le64(val);
Robin Murphyba08bdc2018-03-26 13:35:11 +01001882 dst[1] = cpu_to_le64(FIELD_PREP(STRTAB_STE_1_SHCFG,
1883 STRTAB_STE_1_SHCFG_INCOMING));
Will Deacon48ec83b2015-05-27 17:25:59 +01001884 dst[2] = 0; /* Nuke the VMID */
Will Deacon704c0382017-10-05 16:49:37 +01001885 /*
1886 * The SMMU can perform negative caching, so we must sync
1887 * the STE regardless of whether the old value was live.
1888 */
1889 if (smmu)
Will Deacon48ec83b2015-05-27 17:25:59 +01001890 arm_smmu_sync_ste_for_sid(smmu, sid);
1891 return;
1892 }
1893
Jean-Philippe Brucker8be39a12019-04-17 19:24:45 +01001894 if (s1_cfg) {
Will Deacon48ec83b2015-05-27 17:25:59 +01001895 BUG_ON(ste_live);
1896 dst[1] = cpu_to_le64(
Jean-Philippe Brucker87f42392020-01-15 13:52:33 +01001897 FIELD_PREP(STRTAB_STE_1_S1DSS, STRTAB_STE_1_S1DSS_SSID0) |
Robin Murphyba08bdc2018-03-26 13:35:11 +01001898 FIELD_PREP(STRTAB_STE_1_S1CIR, STRTAB_STE_1_S1C_CACHE_WBRA) |
1899 FIELD_PREP(STRTAB_STE_1_S1COR, STRTAB_STE_1_S1C_CACHE_WBRA) |
1900 FIELD_PREP(STRTAB_STE_1_S1CSH, ARM_SMMU_SH_ISH) |
Robin Murphyba08bdc2018-03-26 13:35:11 +01001901 FIELD_PREP(STRTAB_STE_1_STRW, STRTAB_STE_1_STRW_NSEL1));
Will Deacon48ec83b2015-05-27 17:25:59 +01001902
Yisheng Xie9cff86fd22017-09-21 20:36:07 +08001903 if (smmu->features & ARM_SMMU_FEAT_STALLS &&
1904 !(smmu->features & ARM_SMMU_FEAT_STALL_FORCE))
Prem Mallappa6380be02015-12-14 22:01:23 +05301905 dst[1] |= cpu_to_le64(STRTAB_STE_1_S1STALLD);
1906
Jean-Philippe Brucker7bc4f3f2020-01-15 13:52:31 +01001907 val |= (s1_cfg->cdcfg.cdtab_dma & STRTAB_STE_0_S1CTXPTR_MASK) |
Jean-Philippe Brucker87f42392020-01-15 13:52:33 +01001908 FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_S1_TRANS) |
1909 FIELD_PREP(STRTAB_STE_0_S1CDMAX, s1_cfg->s1cdmax) |
1910 FIELD_PREP(STRTAB_STE_0_S1FMT, s1_cfg->s1fmt);
Will Deacon48ec83b2015-05-27 17:25:59 +01001911 }
1912
Jean-Philippe Brucker8be39a12019-04-17 19:24:45 +01001913 if (s2_cfg) {
Will Deacon48ec83b2015-05-27 17:25:59 +01001914 BUG_ON(ste_live);
1915 dst[2] = cpu_to_le64(
Jean-Philippe Brucker8be39a12019-04-17 19:24:45 +01001916 FIELD_PREP(STRTAB_STE_2_S2VMID, s2_cfg->vmid) |
1917 FIELD_PREP(STRTAB_STE_2_VTCR, s2_cfg->vtcr) |
Will Deacon48ec83b2015-05-27 17:25:59 +01001918#ifdef __BIG_ENDIAN
1919 STRTAB_STE_2_S2ENDI |
1920#endif
1921 STRTAB_STE_2_S2PTW | STRTAB_STE_2_S2AA64 |
1922 STRTAB_STE_2_S2R);
1923
Jean-Philippe Brucker8be39a12019-04-17 19:24:45 +01001924 dst[3] = cpu_to_le64(s2_cfg->vttbr & STRTAB_STE_3_S2TTB_MASK);
Will Deacon48ec83b2015-05-27 17:25:59 +01001925
Robin Murphyba08bdc2018-03-26 13:35:11 +01001926 val |= FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_S2_TRANS);
Will Deacon48ec83b2015-05-27 17:25:59 +01001927 }
1928
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +01001929 if (master->ats_enabled)
1930 dst[1] |= cpu_to_le64(FIELD_PREP(STRTAB_STE_1_EATS,
1931 STRTAB_STE_1_EATS_TRANS));
1932
Will Deacon48ec83b2015-05-27 17:25:59 +01001933 arm_smmu_sync_ste_for_sid(smmu, sid);
Will Deacond71e0172020-01-15 15:21:47 +00001934 /* See comment in arm_smmu_write_ctx_desc() */
1935 WRITE_ONCE(dst[0], cpu_to_le64(val));
Will Deacon48ec83b2015-05-27 17:25:59 +01001936 arm_smmu_sync_ste_for_sid(smmu, sid);
1937
1938 /* It's likely that we'll want to use the new STE soon */
Zhen Lei5e929462015-07-07 04:30:18 +01001939 if (!(smmu->options & ARM_SMMU_OPT_SKIP_PREFETCH))
1940 arm_smmu_cmdq_issue_cmd(smmu, &prefetch_cmd);
Will Deacon48ec83b2015-05-27 17:25:59 +01001941}
1942
1943static void arm_smmu_init_bypass_stes(u64 *strtab, unsigned int nent)
1944{
1945 unsigned int i;
Will Deacon48ec83b2015-05-27 17:25:59 +01001946
1947 for (i = 0; i < nent; ++i) {
Jean-Philippe Brucker8be39a12019-04-17 19:24:45 +01001948 arm_smmu_write_strtab_ent(NULL, -1, strtab);
Will Deacon48ec83b2015-05-27 17:25:59 +01001949 strtab += STRTAB_STE_DWORDS;
1950 }
1951}
1952
1953static int arm_smmu_init_l2_strtab(struct arm_smmu_device *smmu, u32 sid)
1954{
1955 size_t size;
1956 void *strtab;
1957 struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
1958 struct arm_smmu_strtab_l1_desc *desc = &cfg->l1_desc[sid >> STRTAB_SPLIT];
1959
1960 if (desc->l2ptr)
1961 return 0;
1962
1963 size = 1 << (STRTAB_SPLIT + ilog2(STRTAB_STE_DWORDS) + 3);
Zhen Lei69146e72015-06-26 09:32:58 +01001964 strtab = &cfg->strtab[(sid >> STRTAB_SPLIT) * STRTAB_L1_DESC_DWORDS];
Will Deacon48ec83b2015-05-27 17:25:59 +01001965
1966 desc->span = STRTAB_SPLIT + 1;
Will Deacon04fa26c2015-10-30 18:12:41 +00001967 desc->l2ptr = dmam_alloc_coherent(smmu->dev, size, &desc->l2ptr_dma,
Jean-Philippe Brucker9bb90692020-01-15 13:52:27 +01001968 GFP_KERNEL);
Will Deacon48ec83b2015-05-27 17:25:59 +01001969 if (!desc->l2ptr) {
1970 dev_err(smmu->dev,
1971 "failed to allocate l2 stream table for SID %u\n",
1972 sid);
1973 return -ENOMEM;
1974 }
1975
1976 arm_smmu_init_bypass_stes(desc->l2ptr, 1 << STRTAB_SPLIT);
1977 arm_smmu_write_strtab_l1_desc(strtab, desc);
1978 return 0;
1979}
1980
1981/* IRQ and event handlers */
1982static irqreturn_t arm_smmu_evtq_thread(int irq, void *dev)
1983{
1984 int i;
1985 struct arm_smmu_device *smmu = dev;
1986 struct arm_smmu_queue *q = &smmu->evtq.q;
Will Deacon7c288a52019-07-02 17:16:16 +01001987 struct arm_smmu_ll_queue *llq = &q->llq;
Will Deacon48ec83b2015-05-27 17:25:59 +01001988 u64 evt[EVTQ_ENT_DWORDS];
1989
Jean-Philippe Bruckerb4163fb2016-08-22 14:42:24 +01001990 do {
1991 while (!queue_remove_raw(q, evt)) {
Robin Murphy7417b992018-03-26 13:35:12 +01001992 u8 id = FIELD_GET(EVTQ_0_ID, evt[0]);
Will Deacon48ec83b2015-05-27 17:25:59 +01001993
Jean-Philippe Bruckerb4163fb2016-08-22 14:42:24 +01001994 dev_info(smmu->dev, "event 0x%02x received:\n", id);
1995 for (i = 0; i < ARRAY_SIZE(evt); ++i)
1996 dev_info(smmu->dev, "\t0x%016llx\n",
1997 (unsigned long long)evt[i]);
1998
1999 }
2000
2001 /*
2002 * Not much we can do on overflow, so scream and pretend we're
2003 * trying harder.
2004 */
Will Deacon2a8868f2019-07-02 17:12:24 +01002005 if (queue_sync_prod_in(q) == -EOVERFLOW)
Jean-Philippe Bruckerb4163fb2016-08-22 14:42:24 +01002006 dev_err(smmu->dev, "EVTQ overflow detected -- events lost\n");
Will Deacon7c288a52019-07-02 17:16:16 +01002007 } while (!queue_empty(llq));
Will Deacon48ec83b2015-05-27 17:25:59 +01002008
2009 /* Sync our overflow flag, as we believe we're up to speed */
Will Deacon7c288a52019-07-02 17:16:16 +01002010 llq->cons = Q_OVF(llq->prod) | Q_WRP(llq, llq->cons) |
2011 Q_IDX(llq, llq->cons);
Will Deacon48ec83b2015-05-27 17:25:59 +01002012 return IRQ_HANDLED;
2013}
2014
Jean-Philippe Bruckerb4163fb2016-08-22 14:42:24 +01002015static void arm_smmu_handle_ppr(struct arm_smmu_device *smmu, u64 *evt)
Will Deacon48ec83b2015-05-27 17:25:59 +01002016{
Jean-Philippe Bruckerb4163fb2016-08-22 14:42:24 +01002017 u32 sid, ssid;
2018 u16 grpid;
2019 bool ssv, last;
Will Deacon48ec83b2015-05-27 17:25:59 +01002020
Robin Murphy7417b992018-03-26 13:35:12 +01002021 sid = FIELD_GET(PRIQ_0_SID, evt[0]);
2022 ssv = FIELD_GET(PRIQ_0_SSID_V, evt[0]);
2023 ssid = ssv ? FIELD_GET(PRIQ_0_SSID, evt[0]) : 0;
2024 last = FIELD_GET(PRIQ_0_PRG_LAST, evt[0]);
2025 grpid = FIELD_GET(PRIQ_1_PRG_IDX, evt[1]);
Will Deacon48ec83b2015-05-27 17:25:59 +01002026
Jean-Philippe Bruckerb4163fb2016-08-22 14:42:24 +01002027 dev_info(smmu->dev, "unexpected PRI request received:\n");
2028 dev_info(smmu->dev,
2029 "\tsid 0x%08x.0x%05x: [%u%s] %sprivileged %s%s%s access at iova 0x%016llx\n",
2030 sid, ssid, grpid, last ? "L" : "",
2031 evt[0] & PRIQ_0_PERM_PRIV ? "" : "un",
2032 evt[0] & PRIQ_0_PERM_READ ? "R" : "",
2033 evt[0] & PRIQ_0_PERM_WRITE ? "W" : "",
2034 evt[0] & PRIQ_0_PERM_EXEC ? "X" : "",
Robin Murphy1cf9e542018-03-26 13:35:09 +01002035 evt[1] & PRIQ_1_ADDR_MASK);
Jean-Philippe Bruckerb4163fb2016-08-22 14:42:24 +01002036
2037 if (last) {
2038 struct arm_smmu_cmdq_ent cmd = {
2039 .opcode = CMDQ_OP_PRI_RESP,
2040 .substream_valid = ssv,
2041 .pri = {
2042 .sid = sid,
2043 .ssid = ssid,
2044 .grpid = grpid,
2045 .resp = PRI_RESP_DENY,
2046 },
2047 };
2048
2049 arm_smmu_cmdq_issue_cmd(smmu, &cmd);
2050 }
Will Deacon48ec83b2015-05-27 17:25:59 +01002051}
2052
2053static irqreturn_t arm_smmu_priq_thread(int irq, void *dev)
2054{
2055 struct arm_smmu_device *smmu = dev;
2056 struct arm_smmu_queue *q = &smmu->priq.q;
Will Deacon7c288a52019-07-02 17:16:16 +01002057 struct arm_smmu_ll_queue *llq = &q->llq;
Will Deacon48ec83b2015-05-27 17:25:59 +01002058 u64 evt[PRIQ_ENT_DWORDS];
2059
Jean-Philippe Bruckerb4163fb2016-08-22 14:42:24 +01002060 do {
2061 while (!queue_remove_raw(q, evt))
2062 arm_smmu_handle_ppr(smmu, evt);
Will Deacon48ec83b2015-05-27 17:25:59 +01002063
Will Deacon2a8868f2019-07-02 17:12:24 +01002064 if (queue_sync_prod_in(q) == -EOVERFLOW)
Jean-Philippe Bruckerb4163fb2016-08-22 14:42:24 +01002065 dev_err(smmu->dev, "PRIQ overflow detected -- requests lost\n");
Will Deacon7c288a52019-07-02 17:16:16 +01002066 } while (!queue_empty(llq));
Will Deacon48ec83b2015-05-27 17:25:59 +01002067
2068 /* Sync our overflow flag, as we believe we're up to speed */
Will Deacon7c288a52019-07-02 17:16:16 +01002069 llq->cons = Q_OVF(llq->prod) | Q_WRP(llq, llq->cons) |
2070 Q_IDX(llq, llq->cons);
2071 queue_sync_cons_out(q);
Will Deacon48ec83b2015-05-27 17:25:59 +01002072 return IRQ_HANDLED;
2073}
2074
Will Deacon48ec83b2015-05-27 17:25:59 +01002075static int arm_smmu_device_disable(struct arm_smmu_device *smmu);
2076
2077static irqreturn_t arm_smmu_gerror_handler(int irq, void *dev)
2078{
Prem Mallappa324ba102015-12-14 22:01:14 +05302079 u32 gerror, gerrorn, active;
Will Deacon48ec83b2015-05-27 17:25:59 +01002080 struct arm_smmu_device *smmu = dev;
2081
2082 gerror = readl_relaxed(smmu->base + ARM_SMMU_GERROR);
2083 gerrorn = readl_relaxed(smmu->base + ARM_SMMU_GERRORN);
2084
Prem Mallappa324ba102015-12-14 22:01:14 +05302085 active = gerror ^ gerrorn;
2086 if (!(active & GERROR_ERR_MASK))
Will Deacon48ec83b2015-05-27 17:25:59 +01002087 return IRQ_NONE; /* No errors pending */
2088
2089 dev_warn(smmu->dev,
2090 "unexpected global error reported (0x%08x), this could be serious\n",
Prem Mallappa324ba102015-12-14 22:01:14 +05302091 active);
Will Deacon48ec83b2015-05-27 17:25:59 +01002092
Prem Mallappa324ba102015-12-14 22:01:14 +05302093 if (active & GERROR_SFM_ERR) {
Will Deacon48ec83b2015-05-27 17:25:59 +01002094 dev_err(smmu->dev, "device has entered Service Failure Mode!\n");
2095 arm_smmu_device_disable(smmu);
2096 }
2097
Prem Mallappa324ba102015-12-14 22:01:14 +05302098 if (active & GERROR_MSI_GERROR_ABT_ERR)
Will Deacon48ec83b2015-05-27 17:25:59 +01002099 dev_warn(smmu->dev, "GERROR MSI write aborted\n");
2100
Jean-Philippe Bruckerb4163fb2016-08-22 14:42:24 +01002101 if (active & GERROR_MSI_PRIQ_ABT_ERR)
Will Deacon48ec83b2015-05-27 17:25:59 +01002102 dev_warn(smmu->dev, "PRIQ MSI write aborted\n");
Will Deacon48ec83b2015-05-27 17:25:59 +01002103
Jean-Philippe Bruckerb4163fb2016-08-22 14:42:24 +01002104 if (active & GERROR_MSI_EVTQ_ABT_ERR)
Will Deacon48ec83b2015-05-27 17:25:59 +01002105 dev_warn(smmu->dev, "EVTQ MSI write aborted\n");
Will Deacon48ec83b2015-05-27 17:25:59 +01002106
Robin Murphydce032a2017-08-31 14:44:26 +01002107 if (active & GERROR_MSI_CMDQ_ABT_ERR)
Will Deacon48ec83b2015-05-27 17:25:59 +01002108 dev_warn(smmu->dev, "CMDQ MSI write aborted\n");
Will Deacon48ec83b2015-05-27 17:25:59 +01002109
Prem Mallappa324ba102015-12-14 22:01:14 +05302110 if (active & GERROR_PRIQ_ABT_ERR)
Will Deacon48ec83b2015-05-27 17:25:59 +01002111 dev_err(smmu->dev, "PRIQ write aborted -- events may have been lost\n");
2112
Prem Mallappa324ba102015-12-14 22:01:14 +05302113 if (active & GERROR_EVTQ_ABT_ERR)
Will Deacon48ec83b2015-05-27 17:25:59 +01002114 dev_err(smmu->dev, "EVTQ write aborted -- events may have been lost\n");
2115
Prem Mallappa324ba102015-12-14 22:01:14 +05302116 if (active & GERROR_CMDQ_ERR)
Will Deacon48ec83b2015-05-27 17:25:59 +01002117 arm_smmu_cmdq_skip_err(smmu);
2118
2119 writel(gerror, smmu->base + ARM_SMMU_GERRORN);
2120 return IRQ_HANDLED;
2121}
2122
Geetha Sowjanyaf9354482017-06-23 19:04:36 +05302123static irqreturn_t arm_smmu_combined_irq_thread(int irq, void *dev)
2124{
2125 struct arm_smmu_device *smmu = dev;
2126
2127 arm_smmu_evtq_thread(irq, dev);
2128 if (smmu->features & ARM_SMMU_FEAT_PRI)
2129 arm_smmu_priq_thread(irq, dev);
2130
2131 return IRQ_HANDLED;
2132}
2133
2134static irqreturn_t arm_smmu_combined_irq_handler(int irq, void *dev)
2135{
2136 arm_smmu_gerror_handler(irq, dev);
Geetha Sowjanyaf9354482017-06-23 19:04:36 +05302137 return IRQ_WAKE_THREAD;
2138}
2139
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +01002140static void
2141arm_smmu_atc_inv_to_cmd(int ssid, unsigned long iova, size_t size,
2142 struct arm_smmu_cmdq_ent *cmd)
2143{
2144 size_t log2_span;
2145 size_t span_mask;
2146 /* ATC invalidates are always on 4096-bytes pages */
2147 size_t inval_grain_shift = 12;
2148 unsigned long page_start, page_end;
2149
2150 *cmd = (struct arm_smmu_cmdq_ent) {
2151 .opcode = CMDQ_OP_ATC_INV,
2152 .substream_valid = !!ssid,
2153 .atc.ssid = ssid,
2154 };
2155
2156 if (!size) {
2157 cmd->atc.size = ATC_INV_SIZE_ALL;
2158 return;
2159 }
2160
2161 page_start = iova >> inval_grain_shift;
2162 page_end = (iova + size - 1) >> inval_grain_shift;
2163
2164 /*
2165 * In an ATS Invalidate Request, the address must be aligned on the
2166 * range size, which must be a power of two number of page sizes. We
2167 * thus have to choose between grossly over-invalidating the region, or
2168 * splitting the invalidation into multiple commands. For simplicity
2169 * we'll go with the first solution, but should refine it in the future
2170 * if multiple commands are shown to be more efficient.
2171 *
2172 * Find the smallest power of two that covers the range. The most
2173 * significant differing bit between the start and end addresses,
2174 * fls(start ^ end), indicates the required span. For example:
2175 *
2176 * We want to invalidate pages [8; 11]. This is already the ideal range:
2177 * x = 0b1000 ^ 0b1011 = 0b11
2178 * span = 1 << fls(x) = 4
2179 *
2180 * To invalidate pages [7; 10], we need to invalidate [0; 15]:
2181 * x = 0b0111 ^ 0b1010 = 0b1101
2182 * span = 1 << fls(x) = 16
2183 */
2184 log2_span = fls_long(page_start ^ page_end);
2185 span_mask = (1ULL << log2_span) - 1;
2186
2187 page_start &= ~span_mask;
2188
2189 cmd->atc.addr = page_start << inval_grain_shift;
2190 cmd->atc.size = log2_span;
2191}
2192
Rob Herring9e773ae2020-02-24 17:58:46 +01002193static int arm_smmu_atc_inv_master(struct arm_smmu_master *master)
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +01002194{
2195 int i;
Rob Herring9e773ae2020-02-24 17:58:46 +01002196 struct arm_smmu_cmdq_ent cmd;
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +01002197
Rob Herring9e773ae2020-02-24 17:58:46 +01002198 arm_smmu_atc_inv_to_cmd(0, 0, 0, &cmd);
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +01002199
2200 for (i = 0; i < master->num_sids; i++) {
Rob Herring9e773ae2020-02-24 17:58:46 +01002201 cmd.atc.sid = master->sids[i];
2202 arm_smmu_cmdq_issue_cmd(master->smmu, &cmd);
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +01002203 }
2204
2205 return arm_smmu_cmdq_issue_sync(master->smmu);
2206}
2207
2208static int arm_smmu_atc_inv_domain(struct arm_smmu_domain *smmu_domain,
2209 int ssid, unsigned long iova, size_t size)
2210{
Rob Herring9e773ae2020-02-24 17:58:46 +01002211 int i;
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +01002212 unsigned long flags;
2213 struct arm_smmu_cmdq_ent cmd;
2214 struct arm_smmu_master *master;
Rob Herring9e773ae2020-02-24 17:58:46 +01002215 struct arm_smmu_cmdq_batch cmds = {};
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +01002216
2217 if (!(smmu_domain->smmu->features & ARM_SMMU_FEAT_ATS))
2218 return 0;
2219
Will Deaconcdb8a3c2019-08-20 16:28:54 +01002220 /*
2221 * Ensure that we've completed prior invalidation of the main TLBs
2222 * before we read 'nr_ats_masters' in case of a concurrent call to
2223 * arm_smmu_enable_ats():
2224 *
2225 * // unmap() // arm_smmu_enable_ats()
2226 * TLBI+SYNC atomic_inc(&nr_ats_masters);
2227 * smp_mb(); [...]
2228 * atomic_read(&nr_ats_masters); pci_enable_ats() // writel()
2229 *
2230 * Ensures that we always see the incremented 'nr_ats_masters' count if
2231 * ATS was enabled at the PCI device before completion of the TLBI.
2232 */
2233 smp_mb();
2234 if (!atomic_read(&smmu_domain->nr_ats_masters))
2235 return 0;
2236
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +01002237 arm_smmu_atc_inv_to_cmd(ssid, iova, size, &cmd);
2238
2239 spin_lock_irqsave(&smmu_domain->devices_lock, flags);
Rob Herring9e773ae2020-02-24 17:58:46 +01002240 list_for_each_entry(master, &smmu_domain->devices, domain_head) {
2241 if (!master->ats_enabled)
2242 continue;
2243
2244 for (i = 0; i < master->num_sids; i++) {
2245 cmd.atc.sid = master->sids[i];
2246 arm_smmu_cmdq_batch_add(smmu_domain->smmu, &cmds, &cmd);
2247 }
2248 }
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +01002249 spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
2250
Rob Herring9e773ae2020-02-24 17:58:46 +01002251 return arm_smmu_cmdq_batch_submit(smmu_domain->smmu, &cmds);
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +01002252}
2253
Will Deacon48ec83b2015-05-27 17:25:59 +01002254/* IO_PGTABLE API */
Will Deacon48ec83b2015-05-27 17:25:59 +01002255static void arm_smmu_tlb_inv_context(void *cookie)
2256{
2257 struct arm_smmu_domain *smmu_domain = cookie;
2258 struct arm_smmu_device *smmu = smmu_domain->smmu;
2259 struct arm_smmu_cmdq_ent cmd;
2260
2261 if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) {
2262 cmd.opcode = CMDQ_OP_TLBI_NH_ASID;
2263 cmd.tlbi.asid = smmu_domain->s1_cfg.cd.asid;
2264 cmd.tlbi.vmid = 0;
2265 } else {
2266 cmd.opcode = CMDQ_OP_TLBI_S12_VMALL;
2267 cmd.tlbi.vmid = smmu_domain->s2_cfg.vmid;
2268 }
2269
Zhen Lei9662b992018-09-20 17:10:25 +01002270 /*
2271 * NOTE: when io-pgtable is in non-strict mode, we may get here with
2272 * PTEs previously cleared by unmaps on the current CPU not yet visible
Will Deacon587e6c12019-07-02 17:16:25 +01002273 * to the SMMU. We are relying on the dma_wmb() implicit during cmd
2274 * insertion to guarantee those are observed before the TLBI. Do be
2275 * careful, 007.
Zhen Lei9662b992018-09-20 17:10:25 +01002276 */
Will Deacon48ec83b2015-05-27 17:25:59 +01002277 arm_smmu_cmdq_issue_cmd(smmu, &cmd);
Andrew Murray5e731072018-10-10 11:29:27 +01002278 arm_smmu_cmdq_issue_sync(smmu);
Will Deacon353e3cf2019-08-20 15:12:12 +01002279 arm_smmu_atc_inv_domain(smmu_domain, 0, 0, 0);
Will Deacon48ec83b2015-05-27 17:25:59 +01002280}
2281
Will Deacon2af2e722019-07-02 17:16:33 +01002282static void arm_smmu_tlb_inv_range(unsigned long iova, size_t size,
2283 size_t granule, bool leaf,
2284 struct arm_smmu_domain *smmu_domain)
Will Deacon48ec83b2015-05-27 17:25:59 +01002285{
Will Deacon48ec83b2015-05-27 17:25:59 +01002286 struct arm_smmu_device *smmu = smmu_domain->smmu;
Rob Herring6a481a92020-02-24 16:31:29 -06002287 unsigned long start = iova, end = iova + size, num_pages = 0, tg = 0;
2288 size_t inv_range = granule;
Jean-Philippe Brucker4ce8da42020-02-24 17:58:44 +01002289 struct arm_smmu_cmdq_batch cmds = {};
Will Deacon48ec83b2015-05-27 17:25:59 +01002290 struct arm_smmu_cmdq_ent cmd = {
2291 .tlbi = {
2292 .leaf = leaf,
Will Deacon48ec83b2015-05-27 17:25:59 +01002293 },
2294 };
2295
Will Deacon7314ca82019-08-21 12:38:15 +01002296 if (!size)
2297 return;
2298
Will Deacon48ec83b2015-05-27 17:25:59 +01002299 if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) {
2300 cmd.opcode = CMDQ_OP_TLBI_NH_VA;
2301 cmd.tlbi.asid = smmu_domain->s1_cfg.cd.asid;
2302 } else {
2303 cmd.opcode = CMDQ_OP_TLBI_S2_IPA;
2304 cmd.tlbi.vmid = smmu_domain->s2_cfg.vmid;
2305 }
2306
Rob Herring6a481a92020-02-24 16:31:29 -06002307 if (smmu->features & ARM_SMMU_FEAT_RANGE_INV) {
2308 /* Get the leaf page size */
2309 tg = __ffs(smmu_domain->domain.pgsize_bitmap);
2310
2311 /* Convert page size of 12,14,16 (log2) to 1,2,3 */
2312 cmd.tlbi.tg = (tg - 10) / 2;
2313
2314 /* Determine what level the granule is at */
2315 cmd.tlbi.ttl = 4 - ((ilog2(granule) - 3) / (tg - 3));
2316
2317 num_pages = size >> tg;
2318 }
2319
Will Deacon2af2e722019-07-02 17:16:33 +01002320 while (iova < end) {
Rob Herring6a481a92020-02-24 16:31:29 -06002321 if (smmu->features & ARM_SMMU_FEAT_RANGE_INV) {
2322 /*
2323 * On each iteration of the loop, the range is 5 bits
2324 * worth of the aligned size remaining.
2325 * The range in pages is:
2326 *
2327 * range = (num_pages & (0x1f << __ffs(num_pages)))
2328 */
2329 unsigned long scale, num;
2330
2331 /* Determine the power of 2 multiple number of pages */
2332 scale = __ffs(num_pages);
2333 cmd.tlbi.scale = scale;
2334
2335 /* Determine how many chunks of 2^scale size we have */
2336 num = (num_pages >> scale) & CMDQ_TLBI_RANGE_NUM_MAX;
2337 cmd.tlbi.num = num - 1;
2338
2339 /* range is num * 2^scale * pgsize */
2340 inv_range = num << (scale + tg);
2341
2342 /* Clear out the lower order bits for the next iteration */
2343 num_pages -= num << scale;
Will Deacon2af2e722019-07-02 17:16:33 +01002344 }
2345
2346 cmd.tlbi.addr = iova;
Jean-Philippe Brucker4ce8da42020-02-24 17:58:44 +01002347 arm_smmu_cmdq_batch_add(smmu, &cmds, &cmd);
Rob Herring6a481a92020-02-24 16:31:29 -06002348 iova += inv_range;
Will Deacon2af2e722019-07-02 17:16:33 +01002349 }
Jean-Philippe Brucker4ce8da42020-02-24 17:58:44 +01002350 arm_smmu_cmdq_batch_submit(smmu, &cmds);
Will Deacon353e3cf2019-08-20 15:12:12 +01002351
2352 /*
2353 * Unfortunately, this can't be leaf-only since we may have
2354 * zapped an entire table.
2355 */
2356 arm_smmu_atc_inv_domain(smmu_domain, 0, start, size);
Will Deacon48ec83b2015-05-27 17:25:59 +01002357}
2358
Will Deacon3951c412019-07-02 16:45:15 +01002359static void arm_smmu_tlb_inv_page_nosync(struct iommu_iotlb_gather *gather,
2360 unsigned long iova, size_t granule,
Will Deaconabfd6fe2019-07-02 16:44:41 +01002361 void *cookie)
2362{
Will Deacon2af2e722019-07-02 17:16:33 +01002363 struct arm_smmu_domain *smmu_domain = cookie;
2364 struct iommu_domain *domain = &smmu_domain->domain;
2365
2366 iommu_iotlb_gather_add_page(domain, gather, iova, granule);
Will Deaconabfd6fe2019-07-02 16:44:41 +01002367}
2368
Will Deacon05aed942019-07-02 16:44:25 +01002369static void arm_smmu_tlb_inv_walk(unsigned long iova, size_t size,
2370 size_t granule, void *cookie)
2371{
Will Deacon2af2e722019-07-02 17:16:33 +01002372 arm_smmu_tlb_inv_range(iova, size, granule, false, cookie);
Will Deacon05aed942019-07-02 16:44:25 +01002373}
2374
2375static void arm_smmu_tlb_inv_leaf(unsigned long iova, size_t size,
2376 size_t granule, void *cookie)
2377{
Will Deacon2af2e722019-07-02 17:16:33 +01002378 arm_smmu_tlb_inv_range(iova, size, granule, true, cookie);
Will Deacon05aed942019-07-02 16:44:25 +01002379}
2380
Will Deacon298f78892019-07-02 16:43:34 +01002381static const struct iommu_flush_ops arm_smmu_flush_ops = {
Will Deacon48ec83b2015-05-27 17:25:59 +01002382 .tlb_flush_all = arm_smmu_tlb_inv_context,
Will Deacon05aed942019-07-02 16:44:25 +01002383 .tlb_flush_walk = arm_smmu_tlb_inv_walk,
2384 .tlb_flush_leaf = arm_smmu_tlb_inv_leaf,
Will Deaconabfd6fe2019-07-02 16:44:41 +01002385 .tlb_add_page = arm_smmu_tlb_inv_page_nosync,
Will Deacon48ec83b2015-05-27 17:25:59 +01002386};
2387
2388/* IOMMU API */
2389static bool arm_smmu_capable(enum iommu_cap cap)
2390{
2391 switch (cap) {
2392 case IOMMU_CAP_CACHE_COHERENCY:
2393 return true;
Will Deacon48ec83b2015-05-27 17:25:59 +01002394 case IOMMU_CAP_NOEXEC:
2395 return true;
2396 default:
2397 return false;
2398 }
2399}
2400
2401static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
2402{
2403 struct arm_smmu_domain *smmu_domain;
2404
Will Deaconbeb3c6a2017-01-06 16:27:30 +00002405 if (type != IOMMU_DOMAIN_UNMANAGED &&
2406 type != IOMMU_DOMAIN_DMA &&
2407 type != IOMMU_DOMAIN_IDENTITY)
Will Deacon48ec83b2015-05-27 17:25:59 +01002408 return NULL;
2409
2410 /*
2411 * Allocate the domain and initialise some of its data structures.
2412 * We can't really do anything meaningful until we've added a
2413 * master.
2414 */
2415 smmu_domain = kzalloc(sizeof(*smmu_domain), GFP_KERNEL);
2416 if (!smmu_domain)
2417 return NULL;
2418
Robin Murphy9adb9592016-01-26 18:06:36 +00002419 if (type == IOMMU_DOMAIN_DMA &&
2420 iommu_get_dma_cookie(&smmu_domain->domain)) {
2421 kfree(smmu_domain);
2422 return NULL;
2423 }
2424
Will Deacon48ec83b2015-05-27 17:25:59 +01002425 mutex_init(&smmu_domain->init_mutex);
Jean-Philippe Brucker2a7e62f2019-04-17 19:24:46 +01002426 INIT_LIST_HEAD(&smmu_domain->devices);
2427 spin_lock_init(&smmu_domain->devices_lock);
2428
Will Deacon48ec83b2015-05-27 17:25:59 +01002429 return &smmu_domain->domain;
2430}
2431
2432static int arm_smmu_bitmap_alloc(unsigned long *map, int span)
2433{
2434 int idx, size = 1 << span;
2435
2436 do {
2437 idx = find_first_zero_bit(map, size);
2438 if (idx == size)
2439 return -ENOSPC;
2440 } while (test_and_set_bit(idx, map));
2441
2442 return idx;
2443}
2444
2445static void arm_smmu_bitmap_free(unsigned long *map, int idx)
2446{
2447 clear_bit(idx, map);
2448}
2449
2450static void arm_smmu_domain_free(struct iommu_domain *domain)
2451{
2452 struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
2453 struct arm_smmu_device *smmu = smmu_domain->smmu;
2454
Robin Murphy9adb9592016-01-26 18:06:36 +00002455 iommu_put_dma_cookie(domain);
Markus Elfringa6e08fb2015-06-29 17:47:43 +01002456 free_io_pgtable_ops(smmu_domain->pgtbl_ops);
Will Deacon48ec83b2015-05-27 17:25:59 +01002457
2458 /* Free the CD and ASID, if we allocated them */
2459 if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) {
2460 struct arm_smmu_s1_cfg *cfg = &smmu_domain->s1_cfg;
2461
Jean-Philippe Brucker0299a1a2020-05-19 19:54:46 +02002462 if (cfg->cdcfg.cdtab)
Jean-Philippe Bruckera557aff2020-01-15 13:52:32 +01002463 arm_smmu_free_cd_tables(smmu_domain);
Jean-Philippe Brucker0299a1a2020-05-19 19:54:46 +02002464 arm_smmu_free_asid(&cfg->cd);
Will Deacon48ec83b2015-05-27 17:25:59 +01002465 } else {
2466 struct arm_smmu_s2_cfg *cfg = &smmu_domain->s2_cfg;
2467 if (cfg->vmid)
2468 arm_smmu_bitmap_free(smmu->vmid_map, cfg->vmid);
2469 }
2470
2471 kfree(smmu_domain);
2472}
2473
2474static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
Jean-Philippe Brucker2505ec62020-01-15 13:52:34 +01002475 struct arm_smmu_master *master,
Will Deacon48ec83b2015-05-27 17:25:59 +01002476 struct io_pgtable_cfg *pgtbl_cfg)
2477{
2478 int ret;
Jean-Philippe Brucker0299a1a2020-05-19 19:54:46 +02002479 u32 asid;
Will Deacon48ec83b2015-05-27 17:25:59 +01002480 struct arm_smmu_device *smmu = smmu_domain->smmu;
2481 struct arm_smmu_s1_cfg *cfg = &smmu_domain->s1_cfg;
Robin Murphyfb485eb2019-10-25 19:08:38 +01002482 typeof(&pgtbl_cfg->arm_lpae_s1_cfg.tcr) tcr = &pgtbl_cfg->arm_lpae_s1_cfg.tcr;
Will Deacon48ec83b2015-05-27 17:25:59 +01002483
Jean-Philippe Brucker0299a1a2020-05-19 19:54:46 +02002484 ret = xa_alloc(&asid_xa, &asid, &cfg->cd,
2485 XA_LIMIT(1, (1 << smmu->asid_bits) - 1), GFP_KERNEL);
2486 if (ret)
2487 return ret;
Will Deacon48ec83b2015-05-27 17:25:59 +01002488
Jean-Philippe Brucker2505ec62020-01-15 13:52:34 +01002489 cfg->s1cdmax = master->ssid_bits;
2490
Jean-Philippe Bruckera557aff2020-01-15 13:52:32 +01002491 ret = arm_smmu_alloc_cd_tables(smmu_domain);
2492 if (ret)
Will Deacon48ec83b2015-05-27 17:25:59 +01002493 goto out_free_asid;
Will Deacon48ec83b2015-05-27 17:25:59 +01002494
Will Deaconc0733a22015-10-13 17:51:14 +01002495 cfg->cd.asid = (u16)asid;
Robin Murphyd1e5f262019-10-25 19:08:37 +01002496 cfg->cd.ttbr = pgtbl_cfg->arm_lpae_s1_cfg.ttbr;
Robin Murphyfb485eb2019-10-25 19:08:38 +01002497 cfg->cd.tcr = FIELD_PREP(CTXDESC_CD_0_TCR_T0SZ, tcr->tsz) |
2498 FIELD_PREP(CTXDESC_CD_0_TCR_TG0, tcr->tg) |
2499 FIELD_PREP(CTXDESC_CD_0_TCR_IRGN0, tcr->irgn) |
2500 FIELD_PREP(CTXDESC_CD_0_TCR_ORGN0, tcr->orgn) |
2501 FIELD_PREP(CTXDESC_CD_0_TCR_SH0, tcr->sh) |
2502 FIELD_PREP(CTXDESC_CD_0_TCR_IPS, tcr->ips) |
2503 CTXDESC_CD_0_TCR_EPD1 | CTXDESC_CD_0_AA64;
Robin Murphy205577a2019-10-25 19:08:36 +01002504 cfg->cd.mair = pgtbl_cfg->arm_lpae_s1_cfg.mair;
Jean-Philippe Brucker492ddc72020-01-15 13:52:35 +01002505
2506 /*
2507 * Note that this will end up calling arm_smmu_sync_cd() before
2508 * the master has been added to the devices list for this domain.
2509 * This isn't an issue because the STE hasn't been installed yet.
2510 */
2511 ret = arm_smmu_write_ctx_desc(smmu_domain, 0, &cfg->cd);
2512 if (ret)
2513 goto out_free_cd_tables;
2514
Will Deacon48ec83b2015-05-27 17:25:59 +01002515 return 0;
2516
Jean-Philippe Brucker492ddc72020-01-15 13:52:35 +01002517out_free_cd_tables:
2518 arm_smmu_free_cd_tables(smmu_domain);
Will Deacon48ec83b2015-05-27 17:25:59 +01002519out_free_asid:
Jean-Philippe Brucker0299a1a2020-05-19 19:54:46 +02002520 arm_smmu_free_asid(&cfg->cd);
Will Deacon48ec83b2015-05-27 17:25:59 +01002521 return ret;
2522}
2523
2524static int arm_smmu_domain_finalise_s2(struct arm_smmu_domain *smmu_domain,
Jean-Philippe Brucker2505ec62020-01-15 13:52:34 +01002525 struct arm_smmu_master *master,
Will Deacon48ec83b2015-05-27 17:25:59 +01002526 struct io_pgtable_cfg *pgtbl_cfg)
2527{
Will Deaconc0733a22015-10-13 17:51:14 +01002528 int vmid;
Will Deacon48ec83b2015-05-27 17:25:59 +01002529 struct arm_smmu_device *smmu = smmu_domain->smmu;
2530 struct arm_smmu_s2_cfg *cfg = &smmu_domain->s2_cfg;
Will Deaconac4b80e2020-01-10 14:51:59 +00002531 typeof(&pgtbl_cfg->arm_lpae_s2_cfg.vtcr) vtcr;
Will Deacon48ec83b2015-05-27 17:25:59 +01002532
2533 vmid = arm_smmu_bitmap_alloc(smmu->vmid_map, smmu->vmid_bits);
Arnd Bergmann287980e2016-05-27 23:23:25 +02002534 if (vmid < 0)
Will Deacon48ec83b2015-05-27 17:25:59 +01002535 return vmid;
2536
Will Deaconac4b80e2020-01-10 14:51:59 +00002537 vtcr = &pgtbl_cfg->arm_lpae_s2_cfg.vtcr;
Will Deaconc0733a22015-10-13 17:51:14 +01002538 cfg->vmid = (u16)vmid;
Will Deacon48ec83b2015-05-27 17:25:59 +01002539 cfg->vttbr = pgtbl_cfg->arm_lpae_s2_cfg.vttbr;
Will Deaconac4b80e2020-01-10 14:51:59 +00002540 cfg->vtcr = FIELD_PREP(STRTAB_STE_2_VTCR_S2T0SZ, vtcr->tsz) |
2541 FIELD_PREP(STRTAB_STE_2_VTCR_S2SL0, vtcr->sl) |
2542 FIELD_PREP(STRTAB_STE_2_VTCR_S2IR0, vtcr->irgn) |
2543 FIELD_PREP(STRTAB_STE_2_VTCR_S2OR0, vtcr->orgn) |
2544 FIELD_PREP(STRTAB_STE_2_VTCR_S2SH0, vtcr->sh) |
2545 FIELD_PREP(STRTAB_STE_2_VTCR_S2TG, vtcr->tg) |
2546 FIELD_PREP(STRTAB_STE_2_VTCR_S2PS, vtcr->ps);
Will Deacon48ec83b2015-05-27 17:25:59 +01002547 return 0;
2548}
2549
Jean-Philippe Brucker2505ec62020-01-15 13:52:34 +01002550static int arm_smmu_domain_finalise(struct iommu_domain *domain,
2551 struct arm_smmu_master *master)
Will Deacon48ec83b2015-05-27 17:25:59 +01002552{
2553 int ret;
2554 unsigned long ias, oas;
2555 enum io_pgtable_fmt fmt;
2556 struct io_pgtable_cfg pgtbl_cfg;
2557 struct io_pgtable_ops *pgtbl_ops;
2558 int (*finalise_stage_fn)(struct arm_smmu_domain *,
Jean-Philippe Brucker2505ec62020-01-15 13:52:34 +01002559 struct arm_smmu_master *,
Will Deacon48ec83b2015-05-27 17:25:59 +01002560 struct io_pgtable_cfg *);
2561 struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
2562 struct arm_smmu_device *smmu = smmu_domain->smmu;
2563
Will Deaconbeb3c6a2017-01-06 16:27:30 +00002564 if (domain->type == IOMMU_DOMAIN_IDENTITY) {
2565 smmu_domain->stage = ARM_SMMU_DOMAIN_BYPASS;
2566 return 0;
2567 }
2568
Will Deacon48ec83b2015-05-27 17:25:59 +01002569 /* Restrict the stage to what we can actually support */
2570 if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S1))
2571 smmu_domain->stage = ARM_SMMU_DOMAIN_S2;
2572 if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S2))
2573 smmu_domain->stage = ARM_SMMU_DOMAIN_S1;
2574
2575 switch (smmu_domain->stage) {
2576 case ARM_SMMU_DOMAIN_S1:
Robin Murphydcd189e2018-03-26 13:35:15 +01002577 ias = (smmu->features & ARM_SMMU_FEAT_VAX) ? 52 : 48;
2578 ias = min_t(unsigned long, ias, VA_BITS);
Will Deacon48ec83b2015-05-27 17:25:59 +01002579 oas = smmu->ias;
2580 fmt = ARM_64_LPAE_S1;
2581 finalise_stage_fn = arm_smmu_domain_finalise_s1;
2582 break;
2583 case ARM_SMMU_DOMAIN_NESTED:
2584 case ARM_SMMU_DOMAIN_S2:
2585 ias = smmu->ias;
2586 oas = smmu->oas;
2587 fmt = ARM_64_LPAE_S2;
2588 finalise_stage_fn = arm_smmu_domain_finalise_s2;
2589 break;
2590 default:
2591 return -EINVAL;
2592 }
2593
2594 pgtbl_cfg = (struct io_pgtable_cfg) {
Robin Murphyd5466352016-05-09 17:20:09 +01002595 .pgsize_bitmap = smmu->pgsize_bitmap,
Will Deacon48ec83b2015-05-27 17:25:59 +01002596 .ias = ias,
2597 .oas = oas,
Will Deacon4f418452019-06-25 12:51:25 +01002598 .coherent_walk = smmu->features & ARM_SMMU_FEAT_COHERENCY,
Will Deacon298f78892019-07-02 16:43:34 +01002599 .tlb = &arm_smmu_flush_ops,
Robin Murphybdc6d972015-07-29 19:46:07 +01002600 .iommu_dev = smmu->dev,
Will Deacon48ec83b2015-05-27 17:25:59 +01002601 };
2602
Zhen Lei9662b992018-09-20 17:10:25 +01002603 if (smmu_domain->non_strict)
2604 pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_NON_STRICT;
2605
Will Deacon48ec83b2015-05-27 17:25:59 +01002606 pgtbl_ops = alloc_io_pgtable_ops(fmt, &pgtbl_cfg, smmu_domain);
2607 if (!pgtbl_ops)
2608 return -ENOMEM;
2609
Robin Murphyd5466352016-05-09 17:20:09 +01002610 domain->pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;
Robin Murphy6619c912018-03-26 13:35:14 +01002611 domain->geometry.aperture_end = (1UL << pgtbl_cfg.ias) - 1;
Robin Murphy455eb7d2016-09-12 17:13:58 +01002612 domain->geometry.force_aperture = true;
Will Deacon48ec83b2015-05-27 17:25:59 +01002613
Jean-Philippe Brucker2505ec62020-01-15 13:52:34 +01002614 ret = finalise_stage_fn(smmu_domain, master, &pgtbl_cfg);
Jean-Philippe Brucker57d72e12017-12-14 11:03:01 +00002615 if (ret < 0) {
Will Deacon48ec83b2015-05-27 17:25:59 +01002616 free_io_pgtable_ops(pgtbl_ops);
Jean-Philippe Brucker57d72e12017-12-14 11:03:01 +00002617 return ret;
2618 }
Will Deacon48ec83b2015-05-27 17:25:59 +01002619
Jean-Philippe Brucker57d72e12017-12-14 11:03:01 +00002620 smmu_domain->pgtbl_ops = pgtbl_ops;
2621 return 0;
Will Deacon48ec83b2015-05-27 17:25:59 +01002622}
2623
Will Deacon48ec83b2015-05-27 17:25:59 +01002624static __le64 *arm_smmu_get_step_for_sid(struct arm_smmu_device *smmu, u32 sid)
2625{
2626 __le64 *step;
2627 struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
2628
2629 if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB) {
2630 struct arm_smmu_strtab_l1_desc *l1_desc;
2631 int idx;
2632
2633 /* Two-level walk */
2634 idx = (sid >> STRTAB_SPLIT) * STRTAB_L1_DESC_DWORDS;
2635 l1_desc = &cfg->l1_desc[idx];
2636 idx = (sid & ((1 << STRTAB_SPLIT) - 1)) * STRTAB_STE_DWORDS;
2637 step = &l1_desc->l2ptr[idx];
2638 } else {
2639 /* Simple linear lookup */
2640 step = &cfg->strtab[sid * STRTAB_STE_DWORDS];
2641 }
2642
2643 return step;
2644}
2645
Jean-Philippe Bruckerbcecaee2019-04-17 19:24:44 +01002646static void arm_smmu_install_ste_for_dev(struct arm_smmu_master *master)
Will Deacon48ec83b2015-05-27 17:25:59 +01002647{
Robin Murphy563b5cb2018-01-02 12:33:14 +00002648 int i, j;
Robin Murphy8f785152016-09-12 17:13:45 +01002649 struct arm_smmu_device *smmu = master->smmu;
Will Deacon48ec83b2015-05-27 17:25:59 +01002650
Jean-Philippe Bruckerbcecaee2019-04-17 19:24:44 +01002651 for (i = 0; i < master->num_sids; ++i) {
2652 u32 sid = master->sids[i];
Will Deacon48ec83b2015-05-27 17:25:59 +01002653 __le64 *step = arm_smmu_get_step_for_sid(smmu, sid);
2654
Robin Murphy563b5cb2018-01-02 12:33:14 +00002655 /* Bridged PCI devices may end up with duplicated IDs */
2656 for (j = 0; j < i; j++)
Jean-Philippe Bruckerbcecaee2019-04-17 19:24:44 +01002657 if (master->sids[j] == sid)
Robin Murphy563b5cb2018-01-02 12:33:14 +00002658 break;
2659 if (j < i)
2660 continue;
2661
Jean-Philippe Brucker8be39a12019-04-17 19:24:45 +01002662 arm_smmu_write_strtab_ent(master, sid, step);
Will Deacon48ec83b2015-05-27 17:25:59 +01002663 }
Will Deacon48ec83b2015-05-27 17:25:59 +01002664}
2665
Will Deaconbfff88e2019-08-20 14:28:59 +01002666static bool arm_smmu_ats_supported(struct arm_smmu_master *master)
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +01002667{
Jean-Philippe Brucker0b2527a2020-05-20 17:22:02 +02002668 struct device *dev = master->dev;
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +01002669 struct arm_smmu_device *smmu = master->smmu;
Jean-Philippe Brucker0b2527a2020-05-20 17:22:02 +02002670 struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +01002671
Jean-Philippe Brucker0b2527a2020-05-20 17:22:02 +02002672 if (!(smmu->features & ARM_SMMU_FEAT_ATS))
Will Deaconbfff88e2019-08-20 14:28:59 +01002673 return false;
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +01002674
Jean-Philippe Brucker0b2527a2020-05-20 17:22:02 +02002675 if (!(fwspec->flags & IOMMU_FWSPEC_PCI_RC_ATS))
2676 return false;
2677
2678 return dev_is_pci(dev) && pci_ats_supported(to_pci_dev(dev));
Will Deaconbfff88e2019-08-20 14:28:59 +01002679}
2680
2681static void arm_smmu_enable_ats(struct arm_smmu_master *master)
2682{
2683 size_t stu;
2684 struct pci_dev *pdev;
2685 struct arm_smmu_device *smmu = master->smmu;
Will Deaconcdb8a3c2019-08-20 16:28:54 +01002686 struct arm_smmu_domain *smmu_domain = master->domain;
Will Deaconbfff88e2019-08-20 14:28:59 +01002687
2688 /* Don't enable ATS at the endpoint if it's not enabled in the STE */
2689 if (!master->ats_enabled)
2690 return;
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +01002691
2692 /* Smallest Translation Unit: log2 of the smallest supported granule */
2693 stu = __ffs(smmu->pgsize_bitmap);
Will Deaconbfff88e2019-08-20 14:28:59 +01002694 pdev = to_pci_dev(master->dev);
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +01002695
Will Deaconcdb8a3c2019-08-20 16:28:54 +01002696 atomic_inc(&smmu_domain->nr_ats_masters);
2697 arm_smmu_atc_inv_domain(smmu_domain, 0, 0, 0);
Will Deaconbfff88e2019-08-20 14:28:59 +01002698 if (pci_enable_ats(pdev, stu))
2699 dev_err(master->dev, "Failed to enable ATS (STU %zu)\n", stu);
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +01002700}
2701
2702static void arm_smmu_disable_ats(struct arm_smmu_master *master)
2703{
Will Deaconcdb8a3c2019-08-20 16:28:54 +01002704 struct arm_smmu_domain *smmu_domain = master->domain;
Jean-Philippe Brucker8dd8f002019-07-03 12:19:20 +01002705
Will Deaconbfff88e2019-08-20 14:28:59 +01002706 if (!master->ats_enabled)
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +01002707 return;
2708
Will Deaconbfff88e2019-08-20 14:28:59 +01002709 pci_disable_ats(to_pci_dev(master->dev));
2710 /*
2711 * Ensure ATS is disabled at the endpoint before we issue the
2712 * ATC invalidation via the SMMU.
2713 */
2714 wmb();
Rob Herring9e773ae2020-02-24 17:58:46 +01002715 arm_smmu_atc_inv_master(master);
Will Deaconcdb8a3c2019-08-20 16:28:54 +01002716 atomic_dec(&smmu_domain->nr_ats_masters);
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +01002717}
2718
Jean-Philippe Brucker058c59a2020-02-24 17:58:42 +01002719static int arm_smmu_enable_pasid(struct arm_smmu_master *master)
2720{
2721 int ret;
2722 int features;
2723 int num_pasids;
2724 struct pci_dev *pdev;
2725
2726 if (!dev_is_pci(master->dev))
2727 return -ENODEV;
2728
2729 pdev = to_pci_dev(master->dev);
2730
2731 features = pci_pasid_features(pdev);
2732 if (features < 0)
2733 return features;
2734
2735 num_pasids = pci_max_pasids(pdev);
2736 if (num_pasids <= 0)
2737 return num_pasids;
2738
2739 ret = pci_enable_pasid(pdev, features);
2740 if (ret) {
2741 dev_err(&pdev->dev, "Failed to enable PASID\n");
2742 return ret;
2743 }
2744
2745 master->ssid_bits = min_t(u8, ilog2(num_pasids),
2746 master->smmu->ssid_bits);
2747 return 0;
2748}
2749
2750static void arm_smmu_disable_pasid(struct arm_smmu_master *master)
2751{
2752 struct pci_dev *pdev;
2753
2754 if (!dev_is_pci(master->dev))
2755 return;
2756
2757 pdev = to_pci_dev(master->dev);
2758
2759 if (!pdev->pasid_enabled)
2760 return;
2761
2762 master->ssid_bits = 0;
2763 pci_disable_pasid(pdev);
2764}
2765
Jean-Philippe Bruckerbcecaee2019-04-17 19:24:44 +01002766static void arm_smmu_detach_dev(struct arm_smmu_master *master)
Will Deaconbc7f2ce2016-02-17 17:41:57 +00002767{
Jean-Philippe Brucker2a7e62f2019-04-17 19:24:46 +01002768 unsigned long flags;
2769 struct arm_smmu_domain *smmu_domain = master->domain;
2770
2771 if (!smmu_domain)
Jean-Philippe Brucker8be39a12019-04-17 19:24:45 +01002772 return;
2773
Will Deaconcdb8a3c2019-08-20 16:28:54 +01002774 arm_smmu_disable_ats(master);
2775
Jean-Philippe Brucker2a7e62f2019-04-17 19:24:46 +01002776 spin_lock_irqsave(&smmu_domain->devices_lock, flags);
2777 list_del(&master->domain_head);
2778 spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
2779
Jean-Philippe Brucker8be39a12019-04-17 19:24:45 +01002780 master->domain = NULL;
Will Deaconbfff88e2019-08-20 14:28:59 +01002781 master->ats_enabled = false;
Jean-Philippe Bruckerbcecaee2019-04-17 19:24:44 +01002782 arm_smmu_install_ste_for_dev(master);
Will Deaconbc7f2ce2016-02-17 17:41:57 +00002783}
2784
Will Deacon48ec83b2015-05-27 17:25:59 +01002785static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
2786{
2787 int ret = 0;
Jean-Philippe Brucker2a7e62f2019-04-17 19:24:46 +01002788 unsigned long flags;
Joerg Roedel9b468f72018-11-29 14:01:00 +01002789 struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
Will Deacon48ec83b2015-05-27 17:25:59 +01002790 struct arm_smmu_device *smmu;
2791 struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
Jean-Philippe Bruckerb54f4262019-04-17 19:24:43 +01002792 struct arm_smmu_master *master;
Will Deacon48ec83b2015-05-27 17:25:59 +01002793
Joerg Roedel9b468f72018-11-29 14:01:00 +01002794 if (!fwspec)
Will Deacon48ec83b2015-05-27 17:25:59 +01002795 return -ENOENT;
2796
Joerg Roedelb7a96622020-03-26 16:08:34 +01002797 master = dev_iommu_priv_get(dev);
Robin Murphy8f785152016-09-12 17:13:45 +01002798 smmu = master->smmu;
Robin Murphy8f785152016-09-12 17:13:45 +01002799
Jean-Philippe Brucker8be39a12019-04-17 19:24:45 +01002800 arm_smmu_detach_dev(master);
Will Deacon48ec83b2015-05-27 17:25:59 +01002801
Will Deacon48ec83b2015-05-27 17:25:59 +01002802 mutex_lock(&smmu_domain->init_mutex);
2803
2804 if (!smmu_domain->smmu) {
2805 smmu_domain->smmu = smmu;
Jean-Philippe Brucker2505ec62020-01-15 13:52:34 +01002806 ret = arm_smmu_domain_finalise(domain, master);
Will Deacon48ec83b2015-05-27 17:25:59 +01002807 if (ret) {
2808 smmu_domain->smmu = NULL;
2809 goto out_unlock;
2810 }
2811 } else if (smmu_domain->smmu != smmu) {
2812 dev_err(dev,
2813 "cannot attach to SMMU %s (upstream of %s)\n",
2814 dev_name(smmu_domain->smmu->dev),
2815 dev_name(smmu->dev));
2816 ret = -ENXIO;
2817 goto out_unlock;
Jean-Philippe Brucker2505ec62020-01-15 13:52:34 +01002818 } else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1 &&
2819 master->ssid_bits != smmu_domain->s1_cfg.s1cdmax) {
2820 dev_err(dev,
2821 "cannot attach to incompatible domain (%u SSID bits != %u)\n",
2822 smmu_domain->s1_cfg.s1cdmax, master->ssid_bits);
2823 ret = -EINVAL;
2824 goto out_unlock;
Will Deacon48ec83b2015-05-27 17:25:59 +01002825 }
2826
Jean-Philippe Brucker8be39a12019-04-17 19:24:45 +01002827 master->domain = smmu_domain;
Will Deacon48ec83b2015-05-27 17:25:59 +01002828
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +01002829 if (smmu_domain->stage != ARM_SMMU_DOMAIN_BYPASS)
Will Deaconbfff88e2019-08-20 14:28:59 +01002830 master->ats_enabled = arm_smmu_ats_supported(master);
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +01002831
Jean-Philippe Bruckerbcecaee2019-04-17 19:24:44 +01002832 arm_smmu_install_ste_for_dev(master);
Will Deaconcdb8a3c2019-08-20 16:28:54 +01002833
2834 spin_lock_irqsave(&smmu_domain->devices_lock, flags);
2835 list_add(&master->domain_head, &smmu_domain->devices);
2836 spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
2837
Will Deaconbfff88e2019-08-20 14:28:59 +01002838 arm_smmu_enable_ats(master);
Will Deaconcdb8a3c2019-08-20 16:28:54 +01002839
Will Deacon48ec83b2015-05-27 17:25:59 +01002840out_unlock:
2841 mutex_unlock(&smmu_domain->init_mutex);
2842 return ret;
2843}
2844
Will Deacon48ec83b2015-05-27 17:25:59 +01002845static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova,
Tom Murphy781ca2d2019-09-08 09:56:38 -07002846 phys_addr_t paddr, size_t size, int prot, gfp_t gfp)
Will Deacon48ec83b2015-05-27 17:25:59 +01002847{
Robin Murphy58188af2017-06-22 16:53:57 +01002848 struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
Will Deacon48ec83b2015-05-27 17:25:59 +01002849
2850 if (!ops)
2851 return -ENODEV;
2852
Robin Murphy58188af2017-06-22 16:53:57 +01002853 return ops->map(ops, iova, paddr, size, prot);
Will Deacon48ec83b2015-05-27 17:25:59 +01002854}
2855
Will Deacon56f8af52019-07-02 16:44:06 +01002856static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
2857 size_t size, struct iommu_iotlb_gather *gather)
Will Deacon48ec83b2015-05-27 17:25:59 +01002858{
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +01002859 struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
2860 struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops;
Will Deacon48ec83b2015-05-27 17:25:59 +01002861
2862 if (!ops)
2863 return 0;
2864
Will Deacon353e3cf2019-08-20 15:12:12 +01002865 return ops->unmap(ops, iova, size, gather);
Will Deacon48ec83b2015-05-27 17:25:59 +01002866}
2867
Zhen Lei07fdef32018-09-20 17:10:21 +01002868static void arm_smmu_flush_iotlb_all(struct iommu_domain *domain)
2869{
2870 struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
2871
2872 if (smmu_domain->smmu)
2873 arm_smmu_tlb_inv_context(smmu_domain);
2874}
2875
Will Deacon56f8af52019-07-02 16:44:06 +01002876static void arm_smmu_iotlb_sync(struct iommu_domain *domain,
2877 struct iommu_iotlb_gather *gather)
Robin Murphy32b12442017-09-28 15:55:01 +01002878{
Will Deacon2af2e722019-07-02 17:16:33 +01002879 struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
Robin Murphy32b12442017-09-28 15:55:01 +01002880
Will Deacon2af2e722019-07-02 17:16:33 +01002881 arm_smmu_tlb_inv_range(gather->start, gather->end - gather->start,
2882 gather->pgsize, true, smmu_domain);
Robin Murphy32b12442017-09-28 15:55:01 +01002883}
2884
Will Deacon48ec83b2015-05-27 17:25:59 +01002885static phys_addr_t
2886arm_smmu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova)
2887{
Robin Murphy58188af2017-06-22 16:53:57 +01002888 struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
Will Deacon48ec83b2015-05-27 17:25:59 +01002889
Sunil Gouthambdf95922017-04-25 15:27:52 +05302890 if (domain->type == IOMMU_DOMAIN_IDENTITY)
2891 return iova;
2892
Will Deacon48ec83b2015-05-27 17:25:59 +01002893 if (!ops)
2894 return 0;
2895
Robin Murphy58188af2017-06-22 16:53:57 +01002896 return ops->iova_to_phys(ops, iova);
Will Deacon48ec83b2015-05-27 17:25:59 +01002897}
2898
Robin Murphy8f785152016-09-12 17:13:45 +01002899static struct platform_driver arm_smmu_driver;
2900
Lorenzo Pieralisi778de072016-11-21 10:01:38 +00002901static
2902struct arm_smmu_device *arm_smmu_get_by_fwnode(struct fwnode_handle *fwnode)
Will Deacon48ec83b2015-05-27 17:25:59 +01002903{
Suzuki K Poulose67843bb2019-07-23 23:18:34 +01002904 struct device *dev = driver_find_device_by_fwnode(&arm_smmu_driver.driver,
2905 fwnode);
Robin Murphy8f785152016-09-12 17:13:45 +01002906 put_device(dev);
2907 return dev ? dev_get_drvdata(dev) : NULL;
Will Deacon48ec83b2015-05-27 17:25:59 +01002908}
2909
2910static bool arm_smmu_sid_in_range(struct arm_smmu_device *smmu, u32 sid)
2911{
2912 unsigned long limit = smmu->strtab_cfg.num_l1_ents;
2913
2914 if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB)
2915 limit *= 1UL << STRTAB_SPLIT;
2916
2917 return sid < limit;
2918}
2919
Robin Murphy8f785152016-09-12 17:13:45 +01002920static struct iommu_ops arm_smmu_ops;
2921
Joerg Roedelcefa0d52020-04-29 15:36:55 +02002922static struct iommu_device *arm_smmu_probe_device(struct device *dev)
Will Deacon48ec83b2015-05-27 17:25:59 +01002923{
2924 int i, ret;
Will Deacon48ec83b2015-05-27 17:25:59 +01002925 struct arm_smmu_device *smmu;
Jean-Philippe Bruckerb54f4262019-04-17 19:24:43 +01002926 struct arm_smmu_master *master;
Joerg Roedel9b468f72018-11-29 14:01:00 +01002927 struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
Will Deacon48ec83b2015-05-27 17:25:59 +01002928
Robin Murphy8f785152016-09-12 17:13:45 +01002929 if (!fwspec || fwspec->ops != &arm_smmu_ops)
Joerg Roedelcefa0d52020-04-29 15:36:55 +02002930 return ERR_PTR(-ENODEV);
Robin Murphy8f785152016-09-12 17:13:45 +01002931
Joerg Roedelb7a96622020-03-26 16:08:34 +01002932 if (WARN_ON_ONCE(dev_iommu_priv_get(dev)))
Joerg Roedelcefa0d52020-04-29 15:36:55 +02002933 return ERR_PTR(-EBUSY);
Will Deacon92c1d362020-01-15 15:35:16 +00002934
2935 smmu = arm_smmu_get_by_fwnode(fwspec->iommu_fwnode);
2936 if (!smmu)
Joerg Roedelcefa0d52020-04-29 15:36:55 +02002937 return ERR_PTR(-ENODEV);
Will Deacon92c1d362020-01-15 15:35:16 +00002938
2939 master = kzalloc(sizeof(*master), GFP_KERNEL);
2940 if (!master)
Joerg Roedelcefa0d52020-04-29 15:36:55 +02002941 return ERR_PTR(-ENOMEM);
Will Deacon92c1d362020-01-15 15:35:16 +00002942
2943 master->dev = dev;
2944 master->smmu = smmu;
2945 master->sids = fwspec->ids;
2946 master->num_sids = fwspec->num_ids;
Joerg Roedelb7a96622020-03-26 16:08:34 +01002947 dev_iommu_priv_set(dev, master);
Will Deacon48ec83b2015-05-27 17:25:59 +01002948
Robin Murphy8f785152016-09-12 17:13:45 +01002949 /* Check the SIDs are in range of the SMMU and our stream table */
Jean-Philippe Bruckerbcecaee2019-04-17 19:24:44 +01002950 for (i = 0; i < master->num_sids; i++) {
2951 u32 sid = master->sids[i];
Robin Murphy8f785152016-09-12 17:13:45 +01002952
Jean-Philippe Bruckera2be6212020-01-15 13:52:37 +01002953 if (!arm_smmu_sid_in_range(smmu, sid)) {
2954 ret = -ERANGE;
2955 goto err_free_master;
2956 }
Robin Murphy8f785152016-09-12 17:13:45 +01002957
2958 /* Ensure l2 strtab is initialised */
2959 if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB) {
2960 ret = arm_smmu_init_l2_strtab(smmu, sid);
2961 if (ret)
Jean-Philippe Bruckera2be6212020-01-15 13:52:37 +01002962 goto err_free_master;
Robin Murphy8f785152016-09-12 17:13:45 +01002963 }
Will Deacon48ec83b2015-05-27 17:25:59 +01002964 }
2965
Jean-Philippe Brucker89535822020-01-15 13:52:29 +01002966 master->ssid_bits = min(smmu->ssid_bits, fwspec->num_pasid_bits);
2967
Jean-Philippe Brucker058c59a2020-02-24 17:58:42 +01002968 /*
2969 * Note that PASID must be enabled before, and disabled after ATS:
2970 * PCI Express Base 4.0r1.0 - 10.5.1.3 ATS Control Register
2971 *
2972 * Behavior is undefined if this bit is Set and the value of the PASID
2973 * Enable, Execute Requested Enable, or Privileged Mode Requested bits
2974 * are changed.
2975 */
2976 arm_smmu_enable_pasid(master);
2977
Jean-Philippe Brucker89535822020-01-15 13:52:29 +01002978 if (!(smmu->features & ARM_SMMU_FEAT_2_LVL_CDTAB))
2979 master->ssid_bits = min_t(u8, master->ssid_bits,
2980 CTXDESC_LINEAR_CDMAX);
2981
Joerg Roedelcefa0d52020-04-29 15:36:55 +02002982 return &smmu->iommu;
Jean-Philippe Bruckera2be6212020-01-15 13:52:37 +01002983
Jean-Philippe Bruckera2be6212020-01-15 13:52:37 +01002984err_free_master:
2985 kfree(master);
Joerg Roedelb7a96622020-03-26 16:08:34 +01002986 dev_iommu_priv_set(dev, NULL);
Joerg Roedelcefa0d52020-04-29 15:36:55 +02002987 return ERR_PTR(ret);
Will Deacon48ec83b2015-05-27 17:25:59 +01002988}
2989
Joerg Roedelcefa0d52020-04-29 15:36:55 +02002990static void arm_smmu_release_device(struct device *dev)
Will Deacon48ec83b2015-05-27 17:25:59 +01002991{
Joerg Roedel9b468f72018-11-29 14:01:00 +01002992 struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
Jean-Philippe Bruckerb54f4262019-04-17 19:24:43 +01002993 struct arm_smmu_master *master;
Robin Murphy8f785152016-09-12 17:13:45 +01002994
2995 if (!fwspec || fwspec->ops != &arm_smmu_ops)
2996 return;
2997
Joerg Roedelb7a96622020-03-26 16:08:34 +01002998 master = dev_iommu_priv_get(dev);
Jean-Philippe Brucker8be39a12019-04-17 19:24:45 +01002999 arm_smmu_detach_dev(master);
Jean-Philippe Brucker058c59a2020-02-24 17:58:42 +01003000 arm_smmu_disable_pasid(master);
Robin Murphy8f785152016-09-12 17:13:45 +01003001 kfree(master);
3002 iommu_fwspec_free(dev);
Will Deacon48ec83b2015-05-27 17:25:59 +01003003}
3004
Robin Murphy08d4ca22016-09-12 17:13:46 +01003005static struct iommu_group *arm_smmu_device_group(struct device *dev)
3006{
3007 struct iommu_group *group;
3008
3009 /*
3010 * We don't support devices sharing stream IDs other than PCI RID
3011 * aliases, since the necessary ID-to-device lookup becomes rather
3012 * impractical given a potential sparse 32-bit stream ID space.
3013 */
3014 if (dev_is_pci(dev))
3015 group = pci_device_group(dev);
3016 else
3017 group = generic_device_group(dev);
3018
3019 return group;
3020}
3021
Will Deacon48ec83b2015-05-27 17:25:59 +01003022static int arm_smmu_domain_get_attr(struct iommu_domain *domain,
3023 enum iommu_attr attr, void *data)
3024{
3025 struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
3026
Zhen Lei9662b992018-09-20 17:10:25 +01003027 switch (domain->type) {
3028 case IOMMU_DOMAIN_UNMANAGED:
3029 switch (attr) {
3030 case DOMAIN_ATTR_NESTING:
3031 *(int *)data = (smmu_domain->stage == ARM_SMMU_DOMAIN_NESTED);
3032 return 0;
3033 default:
3034 return -ENODEV;
3035 }
3036 break;
3037 case IOMMU_DOMAIN_DMA:
3038 switch (attr) {
3039 case DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE:
3040 *(int *)data = smmu_domain->non_strict;
3041 return 0;
3042 default:
3043 return -ENODEV;
3044 }
3045 break;
Will Deacon48ec83b2015-05-27 17:25:59 +01003046 default:
Zhen Lei9662b992018-09-20 17:10:25 +01003047 return -EINVAL;
Will Deacon48ec83b2015-05-27 17:25:59 +01003048 }
3049}
3050
3051static int arm_smmu_domain_set_attr(struct iommu_domain *domain,
3052 enum iommu_attr attr, void *data)
3053{
3054 int ret = 0;
3055 struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
3056
3057 mutex_lock(&smmu_domain->init_mutex);
3058
Zhen Lei9662b992018-09-20 17:10:25 +01003059 switch (domain->type) {
3060 case IOMMU_DOMAIN_UNMANAGED:
3061 switch (attr) {
3062 case DOMAIN_ATTR_NESTING:
3063 if (smmu_domain->smmu) {
3064 ret = -EPERM;
3065 goto out_unlock;
3066 }
3067
3068 if (*(int *)data)
3069 smmu_domain->stage = ARM_SMMU_DOMAIN_NESTED;
3070 else
3071 smmu_domain->stage = ARM_SMMU_DOMAIN_S1;
3072 break;
3073 default:
3074 ret = -ENODEV;
Will Deacon48ec83b2015-05-27 17:25:59 +01003075 }
Zhen Lei9662b992018-09-20 17:10:25 +01003076 break;
3077 case IOMMU_DOMAIN_DMA:
3078 switch(attr) {
3079 case DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE:
3080 smmu_domain->non_strict = *(int *)data;
3081 break;
3082 default:
3083 ret = -ENODEV;
3084 }
Will Deacon48ec83b2015-05-27 17:25:59 +01003085 break;
3086 default:
Zhen Lei9662b992018-09-20 17:10:25 +01003087 ret = -EINVAL;
Will Deacon48ec83b2015-05-27 17:25:59 +01003088 }
3089
3090out_unlock:
3091 mutex_unlock(&smmu_domain->init_mutex);
3092 return ret;
3093}
3094
Robin Murphy8f785152016-09-12 17:13:45 +01003095static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
3096{
Robin Murphy8f785152016-09-12 17:13:45 +01003097 return iommu_fwspec_add_ids(dev, args->args, 1);
3098}
3099
Eric Auger50019f02017-01-19 20:57:56 +00003100static void arm_smmu_get_resv_regions(struct device *dev,
3101 struct list_head *head)
3102{
3103 struct iommu_resv_region *region;
3104 int prot = IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_MMIO;
3105
3106 region = iommu_alloc_resv_region(MSI_IOVA_BASE, MSI_IOVA_LENGTH,
Robin Murphy9d3a4de2017-03-16 17:00:16 +00003107 prot, IOMMU_RESV_SW_MSI);
Eric Auger50019f02017-01-19 20:57:56 +00003108 if (!region)
3109 return;
3110
3111 list_add_tail(&region->list, head);
Robin Murphy273df962017-03-16 17:00:19 +00003112
3113 iommu_dma_get_resv_regions(dev, head);
Eric Auger50019f02017-01-19 20:57:56 +00003114}
3115
Will Deacon48ec83b2015-05-27 17:25:59 +01003116static struct iommu_ops arm_smmu_ops = {
3117 .capable = arm_smmu_capable,
3118 .domain_alloc = arm_smmu_domain_alloc,
3119 .domain_free = arm_smmu_domain_free,
3120 .attach_dev = arm_smmu_attach_dev,
Will Deacon48ec83b2015-05-27 17:25:59 +01003121 .map = arm_smmu_map,
3122 .unmap = arm_smmu_unmap,
Zhen Lei07fdef32018-09-20 17:10:21 +01003123 .flush_iotlb_all = arm_smmu_flush_iotlb_all,
Robin Murphy32b12442017-09-28 15:55:01 +01003124 .iotlb_sync = arm_smmu_iotlb_sync,
Will Deacon48ec83b2015-05-27 17:25:59 +01003125 .iova_to_phys = arm_smmu_iova_to_phys,
Joerg Roedelcefa0d52020-04-29 15:36:55 +02003126 .probe_device = arm_smmu_probe_device,
3127 .release_device = arm_smmu_release_device,
Robin Murphy08d4ca22016-09-12 17:13:46 +01003128 .device_group = arm_smmu_device_group,
Will Deacon48ec83b2015-05-27 17:25:59 +01003129 .domain_get_attr = arm_smmu_domain_get_attr,
3130 .domain_set_attr = arm_smmu_domain_set_attr,
Robin Murphy8f785152016-09-12 17:13:45 +01003131 .of_xlate = arm_smmu_of_xlate,
Eric Auger50019f02017-01-19 20:57:56 +00003132 .get_resv_regions = arm_smmu_get_resv_regions,
Thierry Redinga66c5dc2019-12-18 14:42:02 +01003133 .put_resv_regions = generic_iommu_put_resv_regions,
Will Deacon48ec83b2015-05-27 17:25:59 +01003134 .pgsize_bitmap = -1UL, /* Restricted during device attach */
3135};
3136
3137/* Probing and initialisation functions */
3138static int arm_smmu_init_one_queue(struct arm_smmu_device *smmu,
3139 struct arm_smmu_queue *q,
3140 unsigned long prod_off,
3141 unsigned long cons_off,
Will Deacond25f6ea2019-05-16 16:08:47 +01003142 size_t dwords, const char *name)
Will Deacon48ec83b2015-05-27 17:25:59 +01003143{
Will Deacond25f6ea2019-05-16 16:08:47 +01003144 size_t qsz;
Will Deacon48ec83b2015-05-27 17:25:59 +01003145
Will Deacond25f6ea2019-05-16 16:08:47 +01003146 do {
Will Deacon52be8632019-07-02 17:16:08 +01003147 qsz = ((1 << q->llq.max_n_shift) * dwords) << 3;
Will Deacond25f6ea2019-05-16 16:08:47 +01003148 q->base = dmam_alloc_coherent(smmu->dev, qsz, &q->base_dma,
3149 GFP_KERNEL);
3150 if (q->base || qsz < PAGE_SIZE)
3151 break;
3152
Will Deacon52be8632019-07-02 17:16:08 +01003153 q->llq.max_n_shift--;
Will Deacond25f6ea2019-05-16 16:08:47 +01003154 } while (1);
3155
Will Deacon48ec83b2015-05-27 17:25:59 +01003156 if (!q->base) {
Will Deacond25f6ea2019-05-16 16:08:47 +01003157 dev_err(smmu->dev,
3158 "failed to allocate queue (0x%zx bytes) for %s\n",
3159 qsz, name);
Will Deacon48ec83b2015-05-27 17:25:59 +01003160 return -ENOMEM;
3161 }
3162
Will Deacond25f6ea2019-05-16 16:08:47 +01003163 if (!WARN_ON(q->base_dma & (qsz - 1))) {
3164 dev_info(smmu->dev, "allocated %u entries for %s\n",
Will Deacon52be8632019-07-02 17:16:08 +01003165 1 << q->llq.max_n_shift, name);
Will Deacond25f6ea2019-05-16 16:08:47 +01003166 }
3167
Linu Cheriane5b829d2017-06-22 17:35:37 +05303168 q->prod_reg = arm_smmu_page1_fixup(prod_off, smmu);
3169 q->cons_reg = arm_smmu_page1_fixup(cons_off, smmu);
Will Deacon48ec83b2015-05-27 17:25:59 +01003170 q->ent_dwords = dwords;
3171
3172 q->q_base = Q_BASE_RWA;
Robin Murphy1cf9e542018-03-26 13:35:09 +01003173 q->q_base |= q->base_dma & Q_BASE_ADDR_MASK;
Will Deacon52be8632019-07-02 17:16:08 +01003174 q->q_base |= FIELD_PREP(Q_BASE_LOG2SIZE, q->llq.max_n_shift);
Will Deacon48ec83b2015-05-27 17:25:59 +01003175
Will Deacon52be8632019-07-02 17:16:08 +01003176 q->llq.prod = q->llq.cons = 0;
Will Deacon48ec83b2015-05-27 17:25:59 +01003177 return 0;
3178}
3179
Will Deacon587e6c12019-07-02 17:16:25 +01003180static void arm_smmu_cmdq_free_bitmap(void *data)
3181{
3182 unsigned long *bitmap = data;
3183 bitmap_free(bitmap);
3184}
3185
3186static int arm_smmu_cmdq_init(struct arm_smmu_device *smmu)
3187{
3188 int ret = 0;
3189 struct arm_smmu_cmdq *cmdq = &smmu->cmdq;
3190 unsigned int nents = 1 << cmdq->q.llq.max_n_shift;
3191 atomic_long_t *bitmap;
3192
3193 atomic_set(&cmdq->owner_prod, 0);
3194 atomic_set(&cmdq->lock, 0);
3195
3196 bitmap = (atomic_long_t *)bitmap_zalloc(nents, GFP_KERNEL);
3197 if (!bitmap) {
3198 dev_err(smmu->dev, "failed to allocate cmdq bitmap\n");
3199 ret = -ENOMEM;
3200 } else {
3201 cmdq->valid_map = bitmap;
3202 devm_add_action(smmu->dev, arm_smmu_cmdq_free_bitmap, bitmap);
3203 }
3204
3205 return ret;
3206}
3207
Will Deacon48ec83b2015-05-27 17:25:59 +01003208static int arm_smmu_init_queues(struct arm_smmu_device *smmu)
3209{
3210 int ret;
3211
3212 /* cmdq */
Will Deacon48ec83b2015-05-27 17:25:59 +01003213 ret = arm_smmu_init_one_queue(smmu, &smmu->cmdq.q, ARM_SMMU_CMDQ_PROD,
Will Deacond25f6ea2019-05-16 16:08:47 +01003214 ARM_SMMU_CMDQ_CONS, CMDQ_ENT_DWORDS,
3215 "cmdq");
Will Deacon48ec83b2015-05-27 17:25:59 +01003216 if (ret)
Will Deacon04fa26c2015-10-30 18:12:41 +00003217 return ret;
Will Deacon48ec83b2015-05-27 17:25:59 +01003218
Will Deacon587e6c12019-07-02 17:16:25 +01003219 ret = arm_smmu_cmdq_init(smmu);
3220 if (ret)
3221 return ret;
3222
Will Deacon48ec83b2015-05-27 17:25:59 +01003223 /* evtq */
3224 ret = arm_smmu_init_one_queue(smmu, &smmu->evtq.q, ARM_SMMU_EVTQ_PROD,
Will Deacond25f6ea2019-05-16 16:08:47 +01003225 ARM_SMMU_EVTQ_CONS, EVTQ_ENT_DWORDS,
3226 "evtq");
Will Deacon48ec83b2015-05-27 17:25:59 +01003227 if (ret)
Will Deacon04fa26c2015-10-30 18:12:41 +00003228 return ret;
Will Deacon48ec83b2015-05-27 17:25:59 +01003229
3230 /* priq */
3231 if (!(smmu->features & ARM_SMMU_FEAT_PRI))
3232 return 0;
3233
Will Deacon04fa26c2015-10-30 18:12:41 +00003234 return arm_smmu_init_one_queue(smmu, &smmu->priq.q, ARM_SMMU_PRIQ_PROD,
Will Deacond25f6ea2019-05-16 16:08:47 +01003235 ARM_SMMU_PRIQ_CONS, PRIQ_ENT_DWORDS,
3236 "priq");
Will Deacon48ec83b2015-05-27 17:25:59 +01003237}
3238
3239static int arm_smmu_init_l1_strtab(struct arm_smmu_device *smmu)
3240{
3241 unsigned int i;
3242 struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
3243 size_t size = sizeof(*cfg->l1_desc) * cfg->num_l1_ents;
3244 void *strtab = smmu->strtab_cfg.strtab;
3245
3246 cfg->l1_desc = devm_kzalloc(smmu->dev, size, GFP_KERNEL);
3247 if (!cfg->l1_desc) {
3248 dev_err(smmu->dev, "failed to allocate l1 stream table desc\n");
3249 return -ENOMEM;
3250 }
3251
3252 for (i = 0; i < cfg->num_l1_ents; ++i) {
3253 arm_smmu_write_strtab_l1_desc(strtab, &cfg->l1_desc[i]);
3254 strtab += STRTAB_L1_DESC_DWORDS << 3;
3255 }
3256
3257 return 0;
3258}
3259
3260static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu)
3261{
3262 void *strtab;
3263 u64 reg;
Will Deacond2e88e72015-06-30 10:02:28 +01003264 u32 size, l1size;
Will Deacon48ec83b2015-05-27 17:25:59 +01003265 struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
3266
Nate Watterson692c4e42017-01-10 14:47:13 -05003267 /* Calculate the L1 size, capped to the SIDSIZE. */
3268 size = STRTAB_L1_SZ_SHIFT - (ilog2(STRTAB_L1_DESC_DWORDS) + 3);
3269 size = min(size, smmu->sid_bits - STRTAB_SPLIT);
Will Deacond2e88e72015-06-30 10:02:28 +01003270 cfg->num_l1_ents = 1 << size;
3271
3272 size += STRTAB_SPLIT;
3273 if (size < smmu->sid_bits)
Will Deacon48ec83b2015-05-27 17:25:59 +01003274 dev_warn(smmu->dev,
3275 "2-level strtab only covers %u/%u bits of SID\n",
Will Deacond2e88e72015-06-30 10:02:28 +01003276 size, smmu->sid_bits);
Will Deacon48ec83b2015-05-27 17:25:59 +01003277
Will Deacond2e88e72015-06-30 10:02:28 +01003278 l1size = cfg->num_l1_ents * (STRTAB_L1_DESC_DWORDS << 3);
Will Deacon04fa26c2015-10-30 18:12:41 +00003279 strtab = dmam_alloc_coherent(smmu->dev, l1size, &cfg->strtab_dma,
Jean-Philippe Brucker9bb90692020-01-15 13:52:27 +01003280 GFP_KERNEL);
Will Deacon48ec83b2015-05-27 17:25:59 +01003281 if (!strtab) {
3282 dev_err(smmu->dev,
3283 "failed to allocate l1 stream table (%u bytes)\n",
3284 size);
3285 return -ENOMEM;
3286 }
3287 cfg->strtab = strtab;
3288
3289 /* Configure strtab_base_cfg for 2 levels */
Robin Murphycbcee192018-03-26 13:35:10 +01003290 reg = FIELD_PREP(STRTAB_BASE_CFG_FMT, STRTAB_BASE_CFG_FMT_2LVL);
3291 reg |= FIELD_PREP(STRTAB_BASE_CFG_LOG2SIZE, size);
3292 reg |= FIELD_PREP(STRTAB_BASE_CFG_SPLIT, STRTAB_SPLIT);
Will Deacon48ec83b2015-05-27 17:25:59 +01003293 cfg->strtab_base_cfg = reg;
3294
Will Deacon04fa26c2015-10-30 18:12:41 +00003295 return arm_smmu_init_l1_strtab(smmu);
Will Deacon48ec83b2015-05-27 17:25:59 +01003296}
3297
3298static int arm_smmu_init_strtab_linear(struct arm_smmu_device *smmu)
3299{
3300 void *strtab;
3301 u64 reg;
3302 u32 size;
3303 struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
3304
3305 size = (1 << smmu->sid_bits) * (STRTAB_STE_DWORDS << 3);
Will Deacon04fa26c2015-10-30 18:12:41 +00003306 strtab = dmam_alloc_coherent(smmu->dev, size, &cfg->strtab_dma,
Jean-Philippe Brucker9bb90692020-01-15 13:52:27 +01003307 GFP_KERNEL);
Will Deacon48ec83b2015-05-27 17:25:59 +01003308 if (!strtab) {
3309 dev_err(smmu->dev,
3310 "failed to allocate linear stream table (%u bytes)\n",
3311 size);
3312 return -ENOMEM;
3313 }
3314 cfg->strtab = strtab;
3315 cfg->num_l1_ents = 1 << smmu->sid_bits;
3316
3317 /* Configure strtab_base_cfg for a linear table covering all SIDs */
Robin Murphycbcee192018-03-26 13:35:10 +01003318 reg = FIELD_PREP(STRTAB_BASE_CFG_FMT, STRTAB_BASE_CFG_FMT_LINEAR);
3319 reg |= FIELD_PREP(STRTAB_BASE_CFG_LOG2SIZE, smmu->sid_bits);
Will Deacon48ec83b2015-05-27 17:25:59 +01003320 cfg->strtab_base_cfg = reg;
3321
3322 arm_smmu_init_bypass_stes(strtab, cfg->num_l1_ents);
3323 return 0;
3324}
3325
3326static int arm_smmu_init_strtab(struct arm_smmu_device *smmu)
3327{
3328 u64 reg;
3329 int ret;
3330
3331 if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB)
3332 ret = arm_smmu_init_strtab_2lvl(smmu);
3333 else
3334 ret = arm_smmu_init_strtab_linear(smmu);
3335
3336 if (ret)
3337 return ret;
3338
3339 /* Set the strtab base address */
Robin Murphy1cf9e542018-03-26 13:35:09 +01003340 reg = smmu->strtab_cfg.strtab_dma & STRTAB_BASE_ADDR_MASK;
Will Deacon48ec83b2015-05-27 17:25:59 +01003341 reg |= STRTAB_BASE_RA;
3342 smmu->strtab_cfg.strtab_base = reg;
3343
3344 /* Allocate the first VMID for stage-2 bypass STEs */
3345 set_bit(0, smmu->vmid_map);
3346 return 0;
3347}
3348
Will Deacon48ec83b2015-05-27 17:25:59 +01003349static int arm_smmu_init_structures(struct arm_smmu_device *smmu)
3350{
3351 int ret;
3352
3353 ret = arm_smmu_init_queues(smmu);
3354 if (ret)
3355 return ret;
3356
Will Deacon04fa26c2015-10-30 18:12:41 +00003357 return arm_smmu_init_strtab(smmu);
Will Deacon48ec83b2015-05-27 17:25:59 +01003358}
3359
3360static int arm_smmu_write_reg_sync(struct arm_smmu_device *smmu, u32 val,
3361 unsigned int reg_off, unsigned int ack_off)
3362{
3363 u32 reg;
3364
3365 writel_relaxed(val, smmu->base + reg_off);
3366 return readl_relaxed_poll_timeout(smmu->base + ack_off, reg, reg == val,
3367 1, ARM_SMMU_POLL_TIMEOUT_US);
3368}
3369
Robin Murphydc87a982016-09-12 17:13:44 +01003370/* GBPA is "special" */
3371static int arm_smmu_update_gbpa(struct arm_smmu_device *smmu, u32 set, u32 clr)
3372{
3373 int ret;
3374 u32 reg, __iomem *gbpa = smmu->base + ARM_SMMU_GBPA;
3375
3376 ret = readl_relaxed_poll_timeout(gbpa, reg, !(reg & GBPA_UPDATE),
3377 1, ARM_SMMU_POLL_TIMEOUT_US);
3378 if (ret)
3379 return ret;
3380
3381 reg &= ~clr;
3382 reg |= set;
3383 writel_relaxed(reg | GBPA_UPDATE, gbpa);
Will Deaconb63b3432018-07-25 15:58:43 +01003384 ret = readl_relaxed_poll_timeout(gbpa, reg, !(reg & GBPA_UPDATE),
3385 1, ARM_SMMU_POLL_TIMEOUT_US);
3386
3387 if (ret)
3388 dev_err(smmu->dev, "GBPA not responding to update\n");
3389 return ret;
Robin Murphydc87a982016-09-12 17:13:44 +01003390}
3391
Marc Zyngier166bdbd2015-10-13 18:32:30 +01003392static void arm_smmu_free_msis(void *data)
3393{
3394 struct device *dev = data;
3395 platform_msi_domain_free_irqs(dev);
3396}
3397
3398static void arm_smmu_write_msi_msg(struct msi_desc *desc, struct msi_msg *msg)
3399{
3400 phys_addr_t doorbell;
3401 struct device *dev = msi_desc_to_dev(desc);
3402 struct arm_smmu_device *smmu = dev_get_drvdata(dev);
3403 phys_addr_t *cfg = arm_smmu_msi_cfg[desc->platform.msi_index];
3404
3405 doorbell = (((u64)msg->address_hi) << 32) | msg->address_lo;
Robin Murphy1cf9e542018-03-26 13:35:09 +01003406 doorbell &= MSI_CFG0_ADDR_MASK;
Marc Zyngier166bdbd2015-10-13 18:32:30 +01003407
3408 writeq_relaxed(doorbell, smmu->base + cfg[0]);
3409 writel_relaxed(msg->data, smmu->base + cfg[1]);
Robin Murphycbcee192018-03-26 13:35:10 +01003410 writel_relaxed(ARM_SMMU_MEMATTR_DEVICE_nGnRE, smmu->base + cfg[2]);
Marc Zyngier166bdbd2015-10-13 18:32:30 +01003411}
3412
3413static void arm_smmu_setup_msis(struct arm_smmu_device *smmu)
3414{
3415 struct msi_desc *desc;
3416 int ret, nvec = ARM_SMMU_MAX_MSIS;
3417 struct device *dev = smmu->dev;
3418
3419 /* Clear the MSI address regs */
3420 writeq_relaxed(0, smmu->base + ARM_SMMU_GERROR_IRQ_CFG0);
3421 writeq_relaxed(0, smmu->base + ARM_SMMU_EVTQ_IRQ_CFG0);
3422
3423 if (smmu->features & ARM_SMMU_FEAT_PRI)
3424 writeq_relaxed(0, smmu->base + ARM_SMMU_PRIQ_IRQ_CFG0);
3425 else
3426 nvec--;
3427
3428 if (!(smmu->features & ARM_SMMU_FEAT_MSI))
3429 return;
3430
Nate Watterson940ded92018-01-20 13:08:04 -05003431 if (!dev->msi_domain) {
3432 dev_info(smmu->dev, "msi_domain absent - falling back to wired irqs\n");
3433 return;
3434 }
3435
Marc Zyngier166bdbd2015-10-13 18:32:30 +01003436 /* Allocate MSIs for evtq, gerror and priq. Ignore cmdq */
3437 ret = platform_msi_domain_alloc_irqs(dev, nvec, arm_smmu_write_msi_msg);
3438 if (ret) {
Nate Watterson940ded92018-01-20 13:08:04 -05003439 dev_warn(dev, "failed to allocate MSIs - falling back to wired irqs\n");
Marc Zyngier166bdbd2015-10-13 18:32:30 +01003440 return;
3441 }
3442
3443 for_each_msi_entry(desc, dev) {
3444 switch (desc->platform.msi_index) {
3445 case EVTQ_MSI_INDEX:
3446 smmu->evtq.q.irq = desc->irq;
3447 break;
3448 case GERROR_MSI_INDEX:
3449 smmu->gerr_irq = desc->irq;
3450 break;
3451 case PRIQ_MSI_INDEX:
3452 smmu->priq.q.irq = desc->irq;
3453 break;
3454 default: /* Unknown */
3455 continue;
3456 }
3457 }
3458
3459 /* Add callback to free MSIs on teardown */
3460 devm_add_action(dev, arm_smmu_free_msis, dev);
3461}
3462
Geetha Sowjanyaf9354482017-06-23 19:04:36 +05303463static void arm_smmu_setup_unique_irqs(struct arm_smmu_device *smmu)
Will Deacon48ec83b2015-05-27 17:25:59 +01003464{
Geetha Sowjanyaf9354482017-06-23 19:04:36 +05303465 int irq, ret;
Will Deacon48ec83b2015-05-27 17:25:59 +01003466
Marc Zyngier166bdbd2015-10-13 18:32:30 +01003467 arm_smmu_setup_msis(smmu);
Will Deacon48ec83b2015-05-27 17:25:59 +01003468
Marc Zyngier166bdbd2015-10-13 18:32:30 +01003469 /* Request interrupt lines */
Will Deacon48ec83b2015-05-27 17:25:59 +01003470 irq = smmu->evtq.q.irq;
3471 if (irq) {
Jean-Philippe Bruckerb4163fb2016-08-22 14:42:24 +01003472 ret = devm_request_threaded_irq(smmu->dev, irq, NULL,
Will Deacon48ec83b2015-05-27 17:25:59 +01003473 arm_smmu_evtq_thread,
Jean-Philippe Bruckerb4163fb2016-08-22 14:42:24 +01003474 IRQF_ONESHOT,
3475 "arm-smmu-v3-evtq", smmu);
Arnd Bergmann287980e2016-05-27 23:23:25 +02003476 if (ret < 0)
Will Deacon48ec83b2015-05-27 17:25:59 +01003477 dev_warn(smmu->dev, "failed to enable evtq irq\n");
Robin Murphy4c8996d2017-10-30 12:14:02 +00003478 } else {
3479 dev_warn(smmu->dev, "no evtq irq - events will not be reported!\n");
Will Deacon48ec83b2015-05-27 17:25:59 +01003480 }
3481
Will Deacon48ec83b2015-05-27 17:25:59 +01003482 irq = smmu->gerr_irq;
3483 if (irq) {
3484 ret = devm_request_irq(smmu->dev, irq, arm_smmu_gerror_handler,
3485 0, "arm-smmu-v3-gerror", smmu);
Arnd Bergmann287980e2016-05-27 23:23:25 +02003486 if (ret < 0)
Will Deacon48ec83b2015-05-27 17:25:59 +01003487 dev_warn(smmu->dev, "failed to enable gerror irq\n");
Robin Murphy4c8996d2017-10-30 12:14:02 +00003488 } else {
3489 dev_warn(smmu->dev, "no gerr irq - errors will not be reported!\n");
Will Deacon48ec83b2015-05-27 17:25:59 +01003490 }
3491
3492 if (smmu->features & ARM_SMMU_FEAT_PRI) {
Will Deacon48ec83b2015-05-27 17:25:59 +01003493 irq = smmu->priq.q.irq;
3494 if (irq) {
Jean-Philippe Bruckerb4163fb2016-08-22 14:42:24 +01003495 ret = devm_request_threaded_irq(smmu->dev, irq, NULL,
Will Deacon48ec83b2015-05-27 17:25:59 +01003496 arm_smmu_priq_thread,
Jean-Philippe Bruckerb4163fb2016-08-22 14:42:24 +01003497 IRQF_ONESHOT,
3498 "arm-smmu-v3-priq",
Will Deacon48ec83b2015-05-27 17:25:59 +01003499 smmu);
Arnd Bergmann287980e2016-05-27 23:23:25 +02003500 if (ret < 0)
Will Deacon48ec83b2015-05-27 17:25:59 +01003501 dev_warn(smmu->dev,
3502 "failed to enable priq irq\n");
Robin Murphy4c8996d2017-10-30 12:14:02 +00003503 } else {
3504 dev_warn(smmu->dev, "no priq irq - PRI will be broken\n");
Will Deacon48ec83b2015-05-27 17:25:59 +01003505 }
3506 }
Geetha Sowjanyaf9354482017-06-23 19:04:36 +05303507}
3508
3509static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu)
3510{
3511 int ret, irq;
3512 u32 irqen_flags = IRQ_CTRL_EVTQ_IRQEN | IRQ_CTRL_GERROR_IRQEN;
3513
3514 /* Disable IRQs first */
3515 ret = arm_smmu_write_reg_sync(smmu, 0, ARM_SMMU_IRQ_CTRL,
3516 ARM_SMMU_IRQ_CTRLACK);
3517 if (ret) {
3518 dev_err(smmu->dev, "failed to disable irqs\n");
3519 return ret;
3520 }
3521
3522 irq = smmu->combined_irq;
3523 if (irq) {
3524 /*
John Garry657135f2018-08-17 23:42:22 +08003525 * Cavium ThunderX2 implementation doesn't support unique irq
3526 * lines. Use a single irq line for all the SMMUv3 interrupts.
Geetha Sowjanyaf9354482017-06-23 19:04:36 +05303527 */
3528 ret = devm_request_threaded_irq(smmu->dev, irq,
3529 arm_smmu_combined_irq_handler,
3530 arm_smmu_combined_irq_thread,
3531 IRQF_ONESHOT,
3532 "arm-smmu-v3-combined-irq", smmu);
3533 if (ret < 0)
3534 dev_warn(smmu->dev, "failed to enable combined irq\n");
3535 } else
3536 arm_smmu_setup_unique_irqs(smmu);
3537
3538 if (smmu->features & ARM_SMMU_FEAT_PRI)
3539 irqen_flags |= IRQ_CTRL_PRIQ_IRQEN;
Will Deacon48ec83b2015-05-27 17:25:59 +01003540
3541 /* Enable interrupt generation on the SMMU */
Marc Zyngierccd63852015-07-15 11:55:18 +01003542 ret = arm_smmu_write_reg_sync(smmu, irqen_flags,
Will Deacon48ec83b2015-05-27 17:25:59 +01003543 ARM_SMMU_IRQ_CTRL, ARM_SMMU_IRQ_CTRLACK);
3544 if (ret)
3545 dev_warn(smmu->dev, "failed to enable irqs\n");
3546
3547 return 0;
3548}
3549
3550static int arm_smmu_device_disable(struct arm_smmu_device *smmu)
3551{
3552 int ret;
3553
3554 ret = arm_smmu_write_reg_sync(smmu, 0, ARM_SMMU_CR0, ARM_SMMU_CR0ACK);
3555 if (ret)
3556 dev_err(smmu->dev, "failed to clear cr0\n");
3557
3558 return ret;
3559}
3560
Robin Murphydc87a982016-09-12 17:13:44 +01003561static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
Will Deacon48ec83b2015-05-27 17:25:59 +01003562{
3563 int ret;
3564 u32 reg, enables;
3565 struct arm_smmu_cmdq_ent cmd;
3566
3567 /* Clear CR0 and sync (disables SMMU and queue processing) */
3568 reg = readl_relaxed(smmu->base + ARM_SMMU_CR0);
Will Deaconb63b3432018-07-25 15:58:43 +01003569 if (reg & CR0_SMMUEN) {
Will Deacon48ec83b2015-05-27 17:25:59 +01003570 dev_warn(smmu->dev, "SMMU currently enabled! Resetting...\n");
Will Deacon3f54c442019-04-23 11:59:36 +01003571 WARN_ON(is_kdump_kernel() && !disable_bypass);
3572 arm_smmu_update_gbpa(smmu, GBPA_ABORT, 0);
Will Deaconb63b3432018-07-25 15:58:43 +01003573 }
Will Deacon48ec83b2015-05-27 17:25:59 +01003574
3575 ret = arm_smmu_device_disable(smmu);
3576 if (ret)
3577 return ret;
3578
3579 /* CR1 (table and queue memory attributes) */
Robin Murphycbcee192018-03-26 13:35:10 +01003580 reg = FIELD_PREP(CR1_TABLE_SH, ARM_SMMU_SH_ISH) |
3581 FIELD_PREP(CR1_TABLE_OC, CR1_CACHE_WB) |
3582 FIELD_PREP(CR1_TABLE_IC, CR1_CACHE_WB) |
3583 FIELD_PREP(CR1_QUEUE_SH, ARM_SMMU_SH_ISH) |
3584 FIELD_PREP(CR1_QUEUE_OC, CR1_CACHE_WB) |
3585 FIELD_PREP(CR1_QUEUE_IC, CR1_CACHE_WB);
Will Deacon48ec83b2015-05-27 17:25:59 +01003586 writel_relaxed(reg, smmu->base + ARM_SMMU_CR1);
3587
3588 /* CR2 (random crap) */
3589 reg = CR2_PTM | CR2_RECINVSID | CR2_E2H;
3590 writel_relaxed(reg, smmu->base + ARM_SMMU_CR2);
3591
3592 /* Stream table */
3593 writeq_relaxed(smmu->strtab_cfg.strtab_base,
3594 smmu->base + ARM_SMMU_STRTAB_BASE);
3595 writel_relaxed(smmu->strtab_cfg.strtab_base_cfg,
3596 smmu->base + ARM_SMMU_STRTAB_BASE_CFG);
3597
3598 /* Command queue */
3599 writeq_relaxed(smmu->cmdq.q.q_base, smmu->base + ARM_SMMU_CMDQ_BASE);
Will Deacon52be8632019-07-02 17:16:08 +01003600 writel_relaxed(smmu->cmdq.q.llq.prod, smmu->base + ARM_SMMU_CMDQ_PROD);
3601 writel_relaxed(smmu->cmdq.q.llq.cons, smmu->base + ARM_SMMU_CMDQ_CONS);
Will Deacon48ec83b2015-05-27 17:25:59 +01003602
3603 enables = CR0_CMDQEN;
3604 ret = arm_smmu_write_reg_sync(smmu, enables, ARM_SMMU_CR0,
3605 ARM_SMMU_CR0ACK);
3606 if (ret) {
3607 dev_err(smmu->dev, "failed to enable command queue\n");
3608 return ret;
3609 }
3610
3611 /* Invalidate any cached configuration */
3612 cmd.opcode = CMDQ_OP_CFGI_ALL;
3613 arm_smmu_cmdq_issue_cmd(smmu, &cmd);
Robin Murphy2f657ad2017-08-31 14:44:25 +01003614 arm_smmu_cmdq_issue_sync(smmu);
Will Deacon48ec83b2015-05-27 17:25:59 +01003615
3616 /* Invalidate any stale TLB entries */
3617 if (smmu->features & ARM_SMMU_FEAT_HYP) {
3618 cmd.opcode = CMDQ_OP_TLBI_EL2_ALL;
3619 arm_smmu_cmdq_issue_cmd(smmu, &cmd);
3620 }
3621
3622 cmd.opcode = CMDQ_OP_TLBI_NSNH_ALL;
3623 arm_smmu_cmdq_issue_cmd(smmu, &cmd);
Robin Murphy2f657ad2017-08-31 14:44:25 +01003624 arm_smmu_cmdq_issue_sync(smmu);
Will Deacon48ec83b2015-05-27 17:25:59 +01003625
3626 /* Event queue */
3627 writeq_relaxed(smmu->evtq.q.q_base, smmu->base + ARM_SMMU_EVTQ_BASE);
Will Deacon52be8632019-07-02 17:16:08 +01003628 writel_relaxed(smmu->evtq.q.llq.prod,
Linu Cheriane5b829d2017-06-22 17:35:37 +05303629 arm_smmu_page1_fixup(ARM_SMMU_EVTQ_PROD, smmu));
Will Deacon52be8632019-07-02 17:16:08 +01003630 writel_relaxed(smmu->evtq.q.llq.cons,
Linu Cheriane5b829d2017-06-22 17:35:37 +05303631 arm_smmu_page1_fixup(ARM_SMMU_EVTQ_CONS, smmu));
Will Deacon48ec83b2015-05-27 17:25:59 +01003632
3633 enables |= CR0_EVTQEN;
3634 ret = arm_smmu_write_reg_sync(smmu, enables, ARM_SMMU_CR0,
3635 ARM_SMMU_CR0ACK);
3636 if (ret) {
3637 dev_err(smmu->dev, "failed to enable event queue\n");
3638 return ret;
3639 }
3640
3641 /* PRI queue */
3642 if (smmu->features & ARM_SMMU_FEAT_PRI) {
3643 writeq_relaxed(smmu->priq.q.q_base,
3644 smmu->base + ARM_SMMU_PRIQ_BASE);
Will Deacon52be8632019-07-02 17:16:08 +01003645 writel_relaxed(smmu->priq.q.llq.prod,
Linu Cheriane5b829d2017-06-22 17:35:37 +05303646 arm_smmu_page1_fixup(ARM_SMMU_PRIQ_PROD, smmu));
Will Deacon52be8632019-07-02 17:16:08 +01003647 writel_relaxed(smmu->priq.q.llq.cons,
Linu Cheriane5b829d2017-06-22 17:35:37 +05303648 arm_smmu_page1_fixup(ARM_SMMU_PRIQ_CONS, smmu));
Will Deacon48ec83b2015-05-27 17:25:59 +01003649
3650 enables |= CR0_PRIQEN;
3651 ret = arm_smmu_write_reg_sync(smmu, enables, ARM_SMMU_CR0,
3652 ARM_SMMU_CR0ACK);
3653 if (ret) {
3654 dev_err(smmu->dev, "failed to enable PRI queue\n");
3655 return ret;
3656 }
3657 }
3658
Jean-Philippe Brucker9ce27af2019-04-17 19:24:47 +01003659 if (smmu->features & ARM_SMMU_FEAT_ATS) {
3660 enables |= CR0_ATSCHK;
3661 ret = arm_smmu_write_reg_sync(smmu, enables, ARM_SMMU_CR0,
3662 ARM_SMMU_CR0ACK);
3663 if (ret) {
3664 dev_err(smmu->dev, "failed to enable ATS check\n");
3665 return ret;
3666 }
3667 }
3668
Will Deacon48ec83b2015-05-27 17:25:59 +01003669 ret = arm_smmu_setup_irqs(smmu);
3670 if (ret) {
3671 dev_err(smmu->dev, "failed to setup irqs\n");
3672 return ret;
3673 }
3674
Will Deacon3f54c442019-04-23 11:59:36 +01003675 if (is_kdump_kernel())
3676 enables &= ~(CR0_EVTQEN | CR0_PRIQEN);
Robin Murphydc87a982016-09-12 17:13:44 +01003677
3678 /* Enable the SMMU interface, or ensure bypass */
3679 if (!bypass || disable_bypass) {
3680 enables |= CR0_SMMUEN;
3681 } else {
3682 ret = arm_smmu_update_gbpa(smmu, 0, GBPA_ABORT);
Will Deaconb63b3432018-07-25 15:58:43 +01003683 if (ret)
Robin Murphydc87a982016-09-12 17:13:44 +01003684 return ret;
Robin Murphydc87a982016-09-12 17:13:44 +01003685 }
Will Deacon48ec83b2015-05-27 17:25:59 +01003686 ret = arm_smmu_write_reg_sync(smmu, enables, ARM_SMMU_CR0,
3687 ARM_SMMU_CR0ACK);
3688 if (ret) {
3689 dev_err(smmu->dev, "failed to enable SMMU interface\n");
3690 return ret;
3691 }
3692
3693 return 0;
3694}
3695
Lorenzo Pieralisi2985b522016-11-21 10:01:42 +00003696static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
Will Deacon48ec83b2015-05-27 17:25:59 +01003697{
3698 u32 reg;
Lorenzo Pieralisi2985b522016-11-21 10:01:42 +00003699 bool coherent = smmu->features & ARM_SMMU_FEAT_COHERENCY;
Will Deacon48ec83b2015-05-27 17:25:59 +01003700
3701 /* IDR0 */
3702 reg = readl_relaxed(smmu->base + ARM_SMMU_IDR0);
3703
3704 /* 2-level structures */
Robin Murphycbcee192018-03-26 13:35:10 +01003705 if (FIELD_GET(IDR0_ST_LVL, reg) == IDR0_ST_LVL_2LVL)
Will Deacon48ec83b2015-05-27 17:25:59 +01003706 smmu->features |= ARM_SMMU_FEAT_2_LVL_STRTAB;
3707
3708 if (reg & IDR0_CD2L)
3709 smmu->features |= ARM_SMMU_FEAT_2_LVL_CDTAB;
3710
3711 /*
3712 * Translation table endianness.
3713 * We currently require the same endianness as the CPU, but this
3714 * could be changed later by adding a new IO_PGTABLE_QUIRK.
3715 */
Robin Murphycbcee192018-03-26 13:35:10 +01003716 switch (FIELD_GET(IDR0_TTENDIAN, reg)) {
Will Deacon48ec83b2015-05-27 17:25:59 +01003717 case IDR0_TTENDIAN_MIXED:
3718 smmu->features |= ARM_SMMU_FEAT_TT_LE | ARM_SMMU_FEAT_TT_BE;
3719 break;
3720#ifdef __BIG_ENDIAN
3721 case IDR0_TTENDIAN_BE:
3722 smmu->features |= ARM_SMMU_FEAT_TT_BE;
3723 break;
3724#else
3725 case IDR0_TTENDIAN_LE:
3726 smmu->features |= ARM_SMMU_FEAT_TT_LE;
3727 break;
3728#endif
3729 default:
3730 dev_err(smmu->dev, "unknown/unsupported TT endianness!\n");
3731 return -ENXIO;
3732 }
3733
3734 /* Boolean feature flags */
3735 if (IS_ENABLED(CONFIG_PCI_PRI) && reg & IDR0_PRI)
3736 smmu->features |= ARM_SMMU_FEAT_PRI;
3737
3738 if (IS_ENABLED(CONFIG_PCI_ATS) && reg & IDR0_ATS)
3739 smmu->features |= ARM_SMMU_FEAT_ATS;
3740
3741 if (reg & IDR0_SEV)
3742 smmu->features |= ARM_SMMU_FEAT_SEV;
3743
3744 if (reg & IDR0_MSI)
3745 smmu->features |= ARM_SMMU_FEAT_MSI;
3746
3747 if (reg & IDR0_HYP)
3748 smmu->features |= ARM_SMMU_FEAT_HYP;
3749
3750 /*
Lorenzo Pieralisi2985b522016-11-21 10:01:42 +00003751 * The coherency feature as set by FW is used in preference to the ID
Will Deacon48ec83b2015-05-27 17:25:59 +01003752 * register, but warn on mismatch.
3753 */
Will Deacon48ec83b2015-05-27 17:25:59 +01003754 if (!!(reg & IDR0_COHACC) != coherent)
Robin Murphy2a22baa2017-09-25 14:55:40 +01003755 dev_warn(smmu->dev, "IDR0.COHACC overridden by FW configuration (%s)\n",
Will Deacon48ec83b2015-05-27 17:25:59 +01003756 coherent ? "true" : "false");
3757
Robin Murphycbcee192018-03-26 13:35:10 +01003758 switch (FIELD_GET(IDR0_STALL_MODEL, reg)) {
Prem Mallappa6380be02015-12-14 22:01:23 +05303759 case IDR0_STALL_MODEL_FORCE:
Yisheng Xie9cff86fd22017-09-21 20:36:07 +08003760 smmu->features |= ARM_SMMU_FEAT_STALL_FORCE;
3761 /* Fallthrough */
3762 case IDR0_STALL_MODEL_STALL:
Will Deacon48ec83b2015-05-27 17:25:59 +01003763 smmu->features |= ARM_SMMU_FEAT_STALLS;
Prem Mallappa6380be02015-12-14 22:01:23 +05303764 }
Will Deacon48ec83b2015-05-27 17:25:59 +01003765
3766 if (reg & IDR0_S1P)
3767 smmu->features |= ARM_SMMU_FEAT_TRANS_S1;
3768
3769 if (reg & IDR0_S2P)
3770 smmu->features |= ARM_SMMU_FEAT_TRANS_S2;
3771
3772 if (!(reg & (IDR0_S1P | IDR0_S2P))) {
3773 dev_err(smmu->dev, "no translation support!\n");
3774 return -ENXIO;
3775 }
3776
3777 /* We only support the AArch64 table format at present */
Robin Murphycbcee192018-03-26 13:35:10 +01003778 switch (FIELD_GET(IDR0_TTF, reg)) {
Will Deaconf0c453d2015-08-20 12:12:32 +01003779 case IDR0_TTF_AARCH32_64:
3780 smmu->ias = 40;
3781 /* Fallthrough */
3782 case IDR0_TTF_AARCH64:
3783 break;
3784 default:
Will Deacon48ec83b2015-05-27 17:25:59 +01003785 dev_err(smmu->dev, "AArch64 table format not supported!\n");
3786 return -ENXIO;
3787 }
3788
3789 /* ASID/VMID sizes */
3790 smmu->asid_bits = reg & IDR0_ASID16 ? 16 : 8;
3791 smmu->vmid_bits = reg & IDR0_VMID16 ? 16 : 8;
3792
3793 /* IDR1 */
3794 reg = readl_relaxed(smmu->base + ARM_SMMU_IDR1);
3795 if (reg & (IDR1_TABLES_PRESET | IDR1_QUEUES_PRESET | IDR1_REL)) {
3796 dev_err(smmu->dev, "embedded implementation not supported\n");
3797 return -ENXIO;
3798 }
3799
Will Deacond25f6ea2019-05-16 16:08:47 +01003800 /* Queue sizes, capped to ensure natural alignment */
Will Deacon52be8632019-07-02 17:16:08 +01003801 smmu->cmdq.q.llq.max_n_shift = min_t(u32, CMDQ_MAX_SZ_SHIFT,
3802 FIELD_GET(IDR1_CMDQS, reg));
Will Deacon2af2e722019-07-02 17:16:33 +01003803 if (smmu->cmdq.q.llq.max_n_shift <= ilog2(CMDQ_BATCH_ENTRIES)) {
Will Deacon587e6c12019-07-02 17:16:25 +01003804 /*
Will Deacon2af2e722019-07-02 17:16:33 +01003805 * We don't support splitting up batches, so one batch of
3806 * commands plus an extra sync needs to fit inside the command
3807 * queue. There's also no way we can handle the weird alignment
3808 * restrictions on the base pointer for a unit-length queue.
Will Deacon587e6c12019-07-02 17:16:25 +01003809 */
Will Deacon2af2e722019-07-02 17:16:33 +01003810 dev_err(smmu->dev, "command queue size <= %d entries not supported\n",
3811 CMDQ_BATCH_ENTRIES);
Will Deacon48ec83b2015-05-27 17:25:59 +01003812 return -ENXIO;
3813 }
3814
Will Deacon52be8632019-07-02 17:16:08 +01003815 smmu->evtq.q.llq.max_n_shift = min_t(u32, EVTQ_MAX_SZ_SHIFT,
3816 FIELD_GET(IDR1_EVTQS, reg));
3817 smmu->priq.q.llq.max_n_shift = min_t(u32, PRIQ_MAX_SZ_SHIFT,
3818 FIELD_GET(IDR1_PRIQS, reg));
Will Deacon48ec83b2015-05-27 17:25:59 +01003819
3820 /* SID/SSID sizes */
Robin Murphycbcee192018-03-26 13:35:10 +01003821 smmu->ssid_bits = FIELD_GET(IDR1_SSIDSIZE, reg);
3822 smmu->sid_bits = FIELD_GET(IDR1_SIDSIZE, reg);
Will Deacon48ec83b2015-05-27 17:25:59 +01003823
Nate Watterson692c4e42017-01-10 14:47:13 -05003824 /*
3825 * If the SMMU supports fewer bits than would fill a single L2 stream
3826 * table, use a linear table instead.
3827 */
3828 if (smmu->sid_bits <= STRTAB_SPLIT)
3829 smmu->features &= ~ARM_SMMU_FEAT_2_LVL_STRTAB;
3830
Rob Herring6a481a92020-02-24 16:31:29 -06003831 /* IDR3 */
3832 reg = readl_relaxed(smmu->base + ARM_SMMU_IDR3);
3833 if (FIELD_GET(IDR3_RIL, reg))
3834 smmu->features |= ARM_SMMU_FEAT_RANGE_INV;
3835
Will Deacon48ec83b2015-05-27 17:25:59 +01003836 /* IDR5 */
3837 reg = readl_relaxed(smmu->base + ARM_SMMU_IDR5);
3838
3839 /* Maximum number of outstanding stalls */
Robin Murphycbcee192018-03-26 13:35:10 +01003840 smmu->evtq.max_stalls = FIELD_GET(IDR5_STALL_MAX, reg);
Will Deacon48ec83b2015-05-27 17:25:59 +01003841
3842 /* Page sizes */
3843 if (reg & IDR5_GRAN64K)
Robin Murphyd5466352016-05-09 17:20:09 +01003844 smmu->pgsize_bitmap |= SZ_64K | SZ_512M;
Will Deacon48ec83b2015-05-27 17:25:59 +01003845 if (reg & IDR5_GRAN16K)
Robin Murphyd5466352016-05-09 17:20:09 +01003846 smmu->pgsize_bitmap |= SZ_16K | SZ_32M;
Will Deacon48ec83b2015-05-27 17:25:59 +01003847 if (reg & IDR5_GRAN4K)
Robin Murphyd5466352016-05-09 17:20:09 +01003848 smmu->pgsize_bitmap |= SZ_4K | SZ_2M | SZ_1G;
Will Deacon48ec83b2015-05-27 17:25:59 +01003849
Robin Murphydcd189e2018-03-26 13:35:15 +01003850 /* Input address size */
3851 if (FIELD_GET(IDR5_VAX, reg) == IDR5_VAX_52_BIT)
3852 smmu->features |= ARM_SMMU_FEAT_VAX;
3853
Will Deacon48ec83b2015-05-27 17:25:59 +01003854 /* Output address size */
Robin Murphycbcee192018-03-26 13:35:10 +01003855 switch (FIELD_GET(IDR5_OAS, reg)) {
Will Deacon48ec83b2015-05-27 17:25:59 +01003856 case IDR5_OAS_32_BIT:
3857 smmu->oas = 32;
3858 break;
3859 case IDR5_OAS_36_BIT:
3860 smmu->oas = 36;
3861 break;
3862 case IDR5_OAS_40_BIT:
3863 smmu->oas = 40;
3864 break;
3865 case IDR5_OAS_42_BIT:
3866 smmu->oas = 42;
3867 break;
3868 case IDR5_OAS_44_BIT:
3869 smmu->oas = 44;
3870 break;
Robin Murphy6619c912018-03-26 13:35:14 +01003871 case IDR5_OAS_52_BIT:
3872 smmu->oas = 52;
3873 smmu->pgsize_bitmap |= 1ULL << 42; /* 4TB */
3874 break;
Will Deacon85430962015-08-03 10:35:40 +01003875 default:
3876 dev_info(smmu->dev,
3877 "unknown output address size. Truncating to 48-bit\n");
3878 /* Fallthrough */
Will Deacon48ec83b2015-05-27 17:25:59 +01003879 case IDR5_OAS_48_BIT:
3880 smmu->oas = 48;
Will Deacon48ec83b2015-05-27 17:25:59 +01003881 }
3882
Robin Murphy6619c912018-03-26 13:35:14 +01003883 if (arm_smmu_ops.pgsize_bitmap == -1UL)
3884 arm_smmu_ops.pgsize_bitmap = smmu->pgsize_bitmap;
3885 else
3886 arm_smmu_ops.pgsize_bitmap |= smmu->pgsize_bitmap;
3887
Will Deacon48ec83b2015-05-27 17:25:59 +01003888 /* Set the DMA mask for our table walker */
3889 if (dma_set_mask_and_coherent(smmu->dev, DMA_BIT_MASK(smmu->oas)))
3890 dev_warn(smmu->dev,
3891 "failed to set DMA mask for table walker\n");
3892
Will Deaconf0c453d2015-08-20 12:12:32 +01003893 smmu->ias = max(smmu->ias, smmu->oas);
Will Deacon48ec83b2015-05-27 17:25:59 +01003894
3895 dev_info(smmu->dev, "ias %lu-bit, oas %lu-bit (features 0x%08x)\n",
3896 smmu->ias, smmu->oas, smmu->features);
3897 return 0;
3898}
3899
Lorenzo Pieralisie4dadfa2016-11-21 10:01:43 +00003900#ifdef CONFIG_ACPI
Linu Cheriane5b829d2017-06-22 17:35:37 +05303901static void acpi_smmu_get_options(u32 model, struct arm_smmu_device *smmu)
3902{
shameer99caf172017-05-17 10:12:05 +01003903 switch (model) {
3904 case ACPI_IORT_SMMU_V3_CAVIUM_CN99XX:
Linu Cheriane5b829d2017-06-22 17:35:37 +05303905 smmu->options |= ARM_SMMU_OPT_PAGE0_REGS_ONLY;
shameer99caf172017-05-17 10:12:05 +01003906 break;
Robin Murphy6948d4a2017-09-22 15:04:00 +01003907 case ACPI_IORT_SMMU_V3_HISILICON_HI161X:
shameer99caf172017-05-17 10:12:05 +01003908 smmu->options |= ARM_SMMU_OPT_SKIP_PREFETCH;
3909 break;
3910 }
Linu Cheriane5b829d2017-06-22 17:35:37 +05303911
3912 dev_notice(smmu->dev, "option mask 0x%x\n", smmu->options);
3913}
3914
Lorenzo Pieralisie4dadfa2016-11-21 10:01:43 +00003915static int arm_smmu_device_acpi_probe(struct platform_device *pdev,
3916 struct arm_smmu_device *smmu)
3917{
3918 struct acpi_iort_smmu_v3 *iort_smmu;
3919 struct device *dev = smmu->dev;
3920 struct acpi_iort_node *node;
3921
3922 node = *(struct acpi_iort_node **)dev_get_platdata(dev);
3923
3924 /* Retrieve SMMUv3 specific data */
3925 iort_smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
3926
Linu Cheriane5b829d2017-06-22 17:35:37 +05303927 acpi_smmu_get_options(iort_smmu->model, smmu);
3928
Lorenzo Pieralisie4dadfa2016-11-21 10:01:43 +00003929 if (iort_smmu->flags & ACPI_IORT_SMMU_V3_COHACC_OVERRIDE)
3930 smmu->features |= ARM_SMMU_FEAT_COHERENCY;
3931
3932 return 0;
3933}
3934#else
3935static inline int arm_smmu_device_acpi_probe(struct platform_device *pdev,
3936 struct arm_smmu_device *smmu)
3937{
3938 return -ENODEV;
3939}
3940#endif
3941
Lorenzo Pieralisi2985b522016-11-21 10:01:42 +00003942static int arm_smmu_device_dt_probe(struct platform_device *pdev,
3943 struct arm_smmu_device *smmu)
Will Deacon48ec83b2015-05-27 17:25:59 +01003944{
Will Deacon48ec83b2015-05-27 17:25:59 +01003945 struct device *dev = &pdev->dev;
Robin Murphydc87a982016-09-12 17:13:44 +01003946 u32 cells;
Lorenzo Pieralisi2985b522016-11-21 10:01:42 +00003947 int ret = -EINVAL;
Robin Murphydc87a982016-09-12 17:13:44 +01003948
3949 if (of_property_read_u32(dev->of_node, "#iommu-cells", &cells))
3950 dev_err(dev, "missing #iommu-cells property\n");
3951 else if (cells != 1)
3952 dev_err(dev, "invalid #iommu-cells value (%d)\n", cells);
3953 else
Lorenzo Pieralisi2985b522016-11-21 10:01:42 +00003954 ret = 0;
3955
3956 parse_driver_options(smmu);
3957
3958 if (of_dma_is_coherent(dev->of_node))
3959 smmu->features |= ARM_SMMU_FEAT_COHERENCY;
3960
3961 return ret;
3962}
3963
Linu Cheriane5b829d2017-06-22 17:35:37 +05303964static unsigned long arm_smmu_resource_size(struct arm_smmu_device *smmu)
3965{
3966 if (smmu->options & ARM_SMMU_OPT_PAGE0_REGS_ONLY)
3967 return SZ_64K;
3968 else
3969 return SZ_128K;
3970}
3971
Will Deaconab246772019-12-19 12:03:47 +00003972static int arm_smmu_set_bus_ops(struct iommu_ops *ops)
3973{
3974 int err;
3975
3976#ifdef CONFIG_PCI
3977 if (pci_bus_type.iommu_ops != ops) {
Will Deaconab246772019-12-19 12:03:47 +00003978 err = bus_set_iommu(&pci_bus_type, ops);
3979 if (err)
3980 return err;
3981 }
3982#endif
3983#ifdef CONFIG_ARM_AMBA
3984 if (amba_bustype.iommu_ops != ops) {
3985 err = bus_set_iommu(&amba_bustype, ops);
3986 if (err)
3987 goto err_reset_pci_ops;
3988 }
3989#endif
3990 if (platform_bus_type.iommu_ops != ops) {
3991 err = bus_set_iommu(&platform_bus_type, ops);
3992 if (err)
3993 goto err_reset_amba_ops;
3994 }
3995
3996 return 0;
3997
3998err_reset_amba_ops:
3999#ifdef CONFIG_ARM_AMBA
4000 bus_set_iommu(&amba_bustype, NULL);
4001#endif
4002err_reset_pci_ops: __maybe_unused;
4003#ifdef CONFIG_PCI
4004 bus_set_iommu(&pci_bus_type, NULL);
4005#endif
4006 return err;
4007}
4008
Jean-Philippe Brucker52f3fab2020-05-13 13:02:57 +02004009static void __iomem *arm_smmu_ioremap(struct device *dev, resource_size_t start,
4010 resource_size_t size)
4011{
4012 struct resource res = {
4013 .flags = IORESOURCE_MEM,
4014 .start = start,
4015 .end = start + size - 1,
4016 };
4017
4018 return devm_ioremap_resource(dev, &res);
4019}
4020
Lorenzo Pieralisi2985b522016-11-21 10:01:42 +00004021static int arm_smmu_device_probe(struct platform_device *pdev)
4022{
4023 int irq, ret;
4024 struct resource *res;
Joerg Roedel9648cbc2017-02-01 18:11:36 +01004025 resource_size_t ioaddr;
Lorenzo Pieralisi2985b522016-11-21 10:01:42 +00004026 struct arm_smmu_device *smmu;
4027 struct device *dev = &pdev->dev;
4028 bool bypass;
Will Deacon48ec83b2015-05-27 17:25:59 +01004029
4030 smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL);
4031 if (!smmu) {
4032 dev_err(dev, "failed to allocate arm_smmu_device\n");
4033 return -ENOMEM;
4034 }
4035 smmu->dev = dev;
4036
Linu Cheriane5b829d2017-06-22 17:35:37 +05304037 if (dev->of_node) {
4038 ret = arm_smmu_device_dt_probe(pdev, smmu);
4039 } else {
4040 ret = arm_smmu_device_acpi_probe(pdev, smmu);
4041 if (ret == -ENODEV)
4042 return ret;
4043 }
4044
4045 /* Set bypass mode according to firmware probing result */
4046 bypass = !!ret;
4047
Will Deacon48ec83b2015-05-27 17:25:59 +01004048 /* Base address */
4049 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
Masahiro Yamada322a9bb2019-12-26 18:50:56 +09004050 if (resource_size(res) < arm_smmu_resource_size(smmu)) {
Will Deacon48ec83b2015-05-27 17:25:59 +01004051 dev_err(dev, "MMIO region too small (%pr)\n", res);
4052 return -EINVAL;
4053 }
Joerg Roedel9648cbc2017-02-01 18:11:36 +01004054 ioaddr = res->start;
Will Deacon48ec83b2015-05-27 17:25:59 +01004055
Jean-Philippe Brucker52f3fab2020-05-13 13:02:57 +02004056 /*
4057 * Don't map the IMPLEMENTATION DEFINED regions, since they may contain
4058 * the PMCG registers which are reserved by the PMU driver.
4059 */
4060 smmu->base = arm_smmu_ioremap(dev, ioaddr, ARM_SMMU_REG_SZ);
Will Deacon48ec83b2015-05-27 17:25:59 +01004061 if (IS_ERR(smmu->base))
4062 return PTR_ERR(smmu->base);
4063
Jean-Philippe Brucker52f3fab2020-05-13 13:02:57 +02004064 if (arm_smmu_resource_size(smmu) > SZ_64K) {
4065 smmu->page1 = arm_smmu_ioremap(dev, ioaddr + SZ_64K,
4066 ARM_SMMU_REG_SZ);
4067 if (IS_ERR(smmu->page1))
4068 return PTR_ERR(smmu->page1);
4069 } else {
4070 smmu->page1 = smmu->base;
4071 }
4072
Will Deacon48ec83b2015-05-27 17:25:59 +01004073 /* Interrupt lines */
Will Deacon48ec83b2015-05-27 17:25:59 +01004074
Jean-Philippe Bruckerf7aff1a2019-11-11 12:17:20 +01004075 irq = platform_get_irq_byname_optional(pdev, "combined");
Will Deacon48ec83b2015-05-27 17:25:59 +01004076 if (irq > 0)
Geetha Sowjanyaf9354482017-06-23 19:04:36 +05304077 smmu->combined_irq = irq;
4078 else {
Jean-Philippe Bruckerf7aff1a2019-11-11 12:17:20 +01004079 irq = platform_get_irq_byname_optional(pdev, "eventq");
Geetha Sowjanyaf9354482017-06-23 19:04:36 +05304080 if (irq > 0)
4081 smmu->evtq.q.irq = irq;
Will Deacon48ec83b2015-05-27 17:25:59 +01004082
Jean-Philippe Bruckerf7aff1a2019-11-11 12:17:20 +01004083 irq = platform_get_irq_byname_optional(pdev, "priq");
Geetha Sowjanyaf9354482017-06-23 19:04:36 +05304084 if (irq > 0)
4085 smmu->priq.q.irq = irq;
Will Deacon48ec83b2015-05-27 17:25:59 +01004086
Jean-Philippe Bruckerf7aff1a2019-11-11 12:17:20 +01004087 irq = platform_get_irq_byname_optional(pdev, "gerror");
Geetha Sowjanyaf9354482017-06-23 19:04:36 +05304088 if (irq > 0)
4089 smmu->gerr_irq = irq;
4090 }
Will Deacon48ec83b2015-05-27 17:25:59 +01004091 /* Probe the h/w */
Lorenzo Pieralisi2985b522016-11-21 10:01:42 +00004092 ret = arm_smmu_device_hw_probe(smmu);
Will Deacon48ec83b2015-05-27 17:25:59 +01004093 if (ret)
4094 return ret;
4095
4096 /* Initialise in-memory data structures */
4097 ret = arm_smmu_init_structures(smmu);
4098 if (ret)
4099 return ret;
4100
Marc Zyngier166bdbd2015-10-13 18:32:30 +01004101 /* Record our private device structure */
4102 platform_set_drvdata(pdev, smmu);
4103
Will Deacon48ec83b2015-05-27 17:25:59 +01004104 /* Reset the device */
Robin Murphy8f785152016-09-12 17:13:45 +01004105 ret = arm_smmu_device_reset(smmu, bypass);
4106 if (ret)
4107 return ret;
4108
4109 /* And we're up. Go go go! */
Joerg Roedel9648cbc2017-02-01 18:11:36 +01004110 ret = iommu_device_sysfs_add(&smmu->iommu, dev, NULL,
4111 "smmu3.%pa", &ioaddr);
Robin Murphy08d4ca22016-09-12 17:13:46 +01004112 if (ret)
4113 return ret;
Joerg Roedel9648cbc2017-02-01 18:11:36 +01004114
4115 iommu_device_set_ops(&smmu->iommu, &arm_smmu_ops);
4116 iommu_device_set_fwnode(&smmu->iommu, dev->fwnode);
4117
4118 ret = iommu_device_register(&smmu->iommu);
Arvind Yadav5c2d0212017-06-22 12:57:42 +05304119 if (ret) {
4120 dev_err(dev, "Failed to register iommu\n");
4121 return ret;
4122 }
Lorenzo Pieralisi778de072016-11-21 10:01:38 +00004123
Will Deaconab246772019-12-19 12:03:47 +00004124 return arm_smmu_set_bus_ops(&arm_smmu_ops);
Will Deacon48ec83b2015-05-27 17:25:59 +01004125}
4126
Will Deacon6e8fa742019-12-19 12:03:44 +00004127static int arm_smmu_device_remove(struct platform_device *pdev)
Will Deacon48ec83b2015-05-27 17:25:59 +01004128{
Will Deacon941a8022015-08-11 16:25:10 +01004129 struct arm_smmu_device *smmu = platform_get_drvdata(pdev);
Will Deacon48ec83b2015-05-27 17:25:59 +01004130
Will Deaconab246772019-12-19 12:03:47 +00004131 arm_smmu_set_bus_ops(NULL);
4132 iommu_device_unregister(&smmu->iommu);
4133 iommu_device_sysfs_remove(&smmu->iommu);
Will Deacon48ec83b2015-05-27 17:25:59 +01004134 arm_smmu_device_disable(smmu);
Will Deacon6e8fa742019-12-19 12:03:44 +00004135
Will Deacon48ec83b2015-05-27 17:25:59 +01004136 return 0;
4137}
4138
4139static void arm_smmu_device_shutdown(struct platform_device *pdev)
4140{
Will Deacon6e8fa742019-12-19 12:03:44 +00004141 arm_smmu_device_remove(pdev);
Nate Watterson7aa86192017-06-29 18:18:15 -04004142}
4143
Arvind Yadavebdd13c2017-06-22 12:51:00 +05304144static const struct of_device_id arm_smmu_of_match[] = {
Will Deacon48ec83b2015-05-27 17:25:59 +01004145 { .compatible = "arm,smmu-v3", },
4146 { },
4147};
Will Deacon6e8fa742019-12-19 12:03:44 +00004148MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
Will Deacon48ec83b2015-05-27 17:25:59 +01004149
4150static struct platform_driver arm_smmu_driver = {
4151 .driver = {
Will Deacon34debdc2019-12-19 12:03:46 +00004152 .name = "arm-smmu-v3",
Masahiro Yamada8efda062019-12-24 17:14:59 +09004153 .of_match_table = arm_smmu_of_match,
Will Deacon34debdc2019-12-19 12:03:46 +00004154 .suppress_bind_attrs = true,
Will Deacon48ec83b2015-05-27 17:25:59 +01004155 },
Lorenzo Pieralisi2985b522016-11-21 10:01:42 +00004156 .probe = arm_smmu_device_probe,
Will Deacon6e8fa742019-12-19 12:03:44 +00004157 .remove = arm_smmu_device_remove,
Nate Watterson7aa86192017-06-29 18:18:15 -04004158 .shutdown = arm_smmu_device_shutdown,
Will Deacon48ec83b2015-05-27 17:25:59 +01004159};
Will Deacon6e8fa742019-12-19 12:03:44 +00004160module_platform_driver(arm_smmu_driver);
4161
4162MODULE_DESCRIPTION("IOMMU API for ARM architected SMMUv3 implementations");
Will Deacon1ea27ee2019-12-19 12:03:52 +00004163MODULE_AUTHOR("Will Deacon <will@kernel.org>");
Ard Biesheuveld3daf662019-12-19 12:03:48 +00004164MODULE_ALIAS("platform:arm-smmu-v3");
Will Deacon6e8fa742019-12-19 12:03:44 +00004165MODULE_LICENSE("GPL v2");