android_kernel_xiaomi_sm8450/include/linux/qcom-iommu-util.h

86 lines
2.4 KiB
C
Raw Normal View History

/* SPDX-License-Identifier: GPL-2.0-only */
/*
qcom-iommu-util: Add support for calculating the IOVA range for fastmap Fastmap preallocates all of the page table memory that it will need at boot. In order to know what range of the 4 GB IOVA space that fastmap supports will be mapped, the qcom,iommu-geometry and the qcom,iommu-dma-addr-pool properties need to be examined. Thus, add support for generating the IOVA range to be used by a device that uses fastmap, prior to the page table memory being allocated. There are a few cases to consider: 1) Neither qcom,iommu-dma-addr-pool or qcom,iommu-geometry is present. In this case, we do not know what ranges the client will use, so consider the range as the entire fastmap IOVA range [0, 4 GB). 2) qcom,iommu-dma-addr-pool is present, but qcom,iommu-geometry is not present. In this case, we know the DMA range, but we do not know if the client may use the IOMMU APIs directly to map memory outside of the DMA range, so use the entire fastmap IOVA range [0, 4 GB). 3) qcom,iommu-geometry is present, but qcom,iommu-dma-addr-pool is not present. In this case, we do not know if the client will use the DMA APIs, which may allocate IOVAs outside of the range specified in qcom,iommu-geometry, so use the entire fastmap IOVA range [0, 4 GB). 4) Both qcom,iommu-geometry and qcom,iommu-dma-addr-pool are present. In this case, we need to specify the range as the union of both ranges, so the range becomes: [min(dma_base, geometry_base), max(dma_base + dma_size, geometry_base + geometry_size)). Change-Id: I6901f269a00203965f220d52bc546f26bf288dce Signed-off-by: Isaac J. Manjarres <isaacm@codeaurora.org>
2021-01-06 06:35:11 +09:00
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
*/
#ifndef __QCOM_IOMMU_UTIL_H
#define __QCOM_IOMMU_UTIL_H
#include <linux/iommu.h>
#include <linux/dma-mapping.h>
#include <linux/iova.h>
/* iommu transaction flags */
/* 1 Write, 0 Read */
#define QCOM_IOMMU_ATOS_TRANS_WRITE BIT(0)
/* 1 Privileged, 0 Unprivileged */
#define QCOM_IOMMU_ATOS_TRANS_PRIV BIT(1)
/* 1 Instruction fetch, 0 Data access */
#define QCOM_IOMMU_ATOS_TRANS_INST BIT(2)
/* Non secure unprivileged Data read operation */
#define QCOM_IOMMU_ATOS_TRANS_DEFAULT (0U)
struct qcom_iommu_atos_txn {
u64 addr;
u32 flags;
u32 id;
};
enum sid_switch_direction {
SID_SWITCH_HLOS_TO_SECURE,
SID_SWITCH_SECURE_TO_HLOS,
};
struct qcom_iommu_fault_ids {
u32 bid;
u32 pid;
u32 mid;
};
/*
* @sid_switch: add/remove all SIDS in the iommu domain containing dev from
* iommu registers.
*/
struct qcom_iommu_ops {
phys_addr_t (*iova_to_phys_hard)(struct iommu_domain *domain,
struct qcom_iommu_atos_txn *txn);
int (*sid_switch)(struct device *dev, enum sid_switch_direction dir);
int (*get_fault_ids)(struct iommu_domain *domain,
struct qcom_iommu_fault_ids *ids);
struct iommu_ops iommu_ops;
};
#define to_qcom_iommu_ops(x) (container_of(x, struct qcom_iommu_ops, iommu_ops))
struct device_node *qcom_iommu_group_parse_phandle(struct device *dev);
int qcom_iommu_generate_dma_regions(struct device *dev,
struct list_head *head);
void qcom_iommu_generate_resv_regions(struct device *dev,
struct list_head *list);
qcom-iommu-util: Add support for calculating the IOVA range for fastmap Fastmap preallocates all of the page table memory that it will need at boot. In order to know what range of the 4 GB IOVA space that fastmap supports will be mapped, the qcom,iommu-geometry and the qcom,iommu-dma-addr-pool properties need to be examined. Thus, add support for generating the IOVA range to be used by a device that uses fastmap, prior to the page table memory being allocated. There are a few cases to consider: 1) Neither qcom,iommu-dma-addr-pool or qcom,iommu-geometry is present. In this case, we do not know what ranges the client will use, so consider the range as the entire fastmap IOVA range [0, 4 GB). 2) qcom,iommu-dma-addr-pool is present, but qcom,iommu-geometry is not present. In this case, we know the DMA range, but we do not know if the client may use the IOMMU APIs directly to map memory outside of the DMA range, so use the entire fastmap IOVA range [0, 4 GB). 3) qcom,iommu-geometry is present, but qcom,iommu-dma-addr-pool is not present. In this case, we do not know if the client will use the DMA APIs, which may allocate IOVAs outside of the range specified in qcom,iommu-geometry, so use the entire fastmap IOVA range [0, 4 GB). 4) Both qcom,iommu-geometry and qcom,iommu-dma-addr-pool are present. In this case, we need to specify the range as the union of both ranges, so the range becomes: [min(dma_base, geometry_base), max(dma_base + dma_size, geometry_base + geometry_size)). Change-Id: I6901f269a00203965f220d52bc546f26bf288dce Signed-off-by: Isaac J. Manjarres <isaacm@codeaurora.org>
2021-01-06 06:35:11 +09:00
int qcom_iommu_get_fast_iova_range(struct device *dev,
dma_addr_t *ret_iova_base,
dma_addr_t *ret_iova_end);
/* Remove once these functions are exported by upstream kernel */
void qcom_iommu_get_resv_regions(struct device *dev, struct list_head *list);
void qcom_iommu_put_resv_regions(struct device *dev, struct list_head *list);
phys_addr_t qcom_iommu_iova_to_phys_hard(struct iommu_domain *domain,
struct qcom_iommu_atos_txn *txn);
extern int qcom_iommu_get_fault_ids(struct iommu_domain *domain,
struct qcom_iommu_fault_ids *f_ids);
extern int __init qcom_dma_iommu_generic_driver_init(void);
extern void qcom_dma_iommu_generic_driver_exit(void);
#ifdef CONFIG_IOMMU_IO_PGTABLE_LPAE
int __init qcom_arm_lpae_do_selftests(void);
#else
static inline int __init qcom_arm_lpae_do_selftests(void)
{
return 0;
}
#endif
#endif /* __QCOM_IOMMU_UTIL_H */