msm_11ad: 11AD SMMU changes to allow enabling of SMMU stage1
Add the following changes to support enabling of SMMU stage1: - Enable DMA coherency and PAGE_TABLE_FORCE_COHERENT attr to allow cache coherency when SMMU stage1 is enabled - Add the option to define SMMU base address and size in DT - Add DT node flag to determine if stage1 is enabled Change-Id: I38b0ee3d5c4bf533f91077ee69bd464dfdd358c8 Signed-off-by: Maya Erez <merez@codeaurora.org>
This commit is contained in:
parent
ba53c4518c
commit
b30b481b14
2 changed files with 66 additions and 17 deletions
|
@ -10,6 +10,10 @@ Required properties:
|
||||||
|
|
||||||
- compatible: "qcom,wil6210"
|
- compatible: "qcom,wil6210"
|
||||||
- qcom,smmu-support: Boolean flag indicating whether PCIe has SMMU support
|
- qcom,smmu-support: Boolean flag indicating whether PCIe has SMMU support
|
||||||
|
- qcom,smmu-s1-en: Boolean flag indicating whether SMMU stage1 should be enabled
|
||||||
|
- qcom,smmu-fast-map: Boolean flag indicating whether SMMU fast mapping should be enabled
|
||||||
|
- qcom,smmu-coherent: Boolean flag indicating SMMU dma and page table coherency
|
||||||
|
- qcom,smmu-mapping: specifies the base address and size of SMMU space
|
||||||
- qcom,pcie-parent: phandle for the PCIe root complex to which 11ad card is connected
|
- qcom,pcie-parent: phandle for the PCIe root complex to which 11ad card is connected
|
||||||
- Refer to "Documentation/devicetree/bindings/arm/msm/msm_bus.txt" for
|
- Refer to "Documentation/devicetree/bindings/arm/msm/msm_bus.txt" for
|
||||||
the below optional properties:
|
the below optional properties:
|
||||||
|
@ -33,6 +37,10 @@ Example:
|
||||||
wil6210: qcom,wil6210 {
|
wil6210: qcom,wil6210 {
|
||||||
compatible = "qcom,wil6210";
|
compatible = "qcom,wil6210";
|
||||||
qcom,smmu-support;
|
qcom,smmu-support;
|
||||||
|
qcom,smmu-s1-en;
|
||||||
|
qcom,smmu-fast-map;
|
||||||
|
qcom,smmu-coherent;
|
||||||
|
qcom,smmu-mapping = <0x20000000 0xe0000000>;
|
||||||
qcom,pcie-parent = <&pcie1>;
|
qcom,pcie-parent = <&pcie1>;
|
||||||
qcom,wigig-en = <&tlmm 94 0>;
|
qcom,wigig-en = <&tlmm 94 0>;
|
||||||
qcom,msm-bus,name = "wil6210";
|
qcom,msm-bus,name = "wil6210";
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
#define WIGIG_VENDOR (0x1ae9)
|
#define WIGIG_VENDOR (0x1ae9)
|
||||||
#define WIGIG_DEVICE (0x0310)
|
#define WIGIG_DEVICE (0x0310)
|
||||||
|
|
||||||
#define SMMU_BASE 0x10000000 /* Device address range base */
|
#define SMMU_BASE 0x20000000 /* Device address range base */
|
||||||
#define SMMU_SIZE ((SZ_1G * 4ULL) - SMMU_BASE)
|
#define SMMU_SIZE ((SZ_1G * 4ULL) - SMMU_BASE)
|
||||||
|
|
||||||
#define WIGIG_ENABLE_DELAY 50
|
#define WIGIG_ENABLE_DELAY 50
|
||||||
|
@ -93,9 +93,12 @@ struct msm11ad_ctx {
|
||||||
|
|
||||||
/* SMMU */
|
/* SMMU */
|
||||||
bool use_smmu; /* have SMMU enabled? */
|
bool use_smmu; /* have SMMU enabled? */
|
||||||
int smmu_bypass;
|
int smmu_s1_en;
|
||||||
int smmu_fast_map;
|
int smmu_fast_map;
|
||||||
|
int smmu_coherent;
|
||||||
struct dma_iommu_mapping *mapping;
|
struct dma_iommu_mapping *mapping;
|
||||||
|
u32 smmu_base;
|
||||||
|
u32 smmu_size;
|
||||||
|
|
||||||
/* bus frequency scaling */
|
/* bus frequency scaling */
|
||||||
struct msm_bus_scale_pdata *bus_scale;
|
struct msm_bus_scale_pdata *bus_scale;
|
||||||
|
@ -638,15 +641,17 @@ static int msm_11ad_smmu_init(struct msm11ad_ctx *ctx)
|
||||||
{
|
{
|
||||||
int atomic_ctx = 1;
|
int atomic_ctx = 1;
|
||||||
int rc;
|
int rc;
|
||||||
|
int force_pt_coherent = 1;
|
||||||
|
int smmu_bypass = !ctx->smmu_s1_en;
|
||||||
|
|
||||||
if (!ctx->use_smmu)
|
if (!ctx->use_smmu)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
dev_info(ctx->dev, "Initialize SMMU, bypass = %d, fastmap = %d\n",
|
dev_info(ctx->dev, "Initialize SMMU, bypass=%d, fastmap=%d, coherent=%d\n",
|
||||||
ctx->smmu_bypass, ctx->smmu_fast_map);
|
smmu_bypass, ctx->smmu_fast_map, ctx->smmu_coherent);
|
||||||
|
|
||||||
ctx->mapping = arm_iommu_create_mapping(&platform_bus_type,
|
ctx->mapping = arm_iommu_create_mapping(&platform_bus_type,
|
||||||
SMMU_BASE, SMMU_SIZE);
|
ctx->smmu_base, ctx->smmu_size);
|
||||||
if (IS_ERR_OR_NULL(ctx->mapping)) {
|
if (IS_ERR_OR_NULL(ctx->mapping)) {
|
||||||
rc = PTR_ERR(ctx->mapping) ?: -ENODEV;
|
rc = PTR_ERR(ctx->mapping) ?: -ENODEV;
|
||||||
dev_err(ctx->dev, "Failed to create IOMMU mapping (%d)\n", rc);
|
dev_err(ctx->dev, "Failed to create IOMMU mapping (%d)\n", rc);
|
||||||
|
@ -662,23 +667,39 @@ static int msm_11ad_smmu_init(struct msm11ad_ctx *ctx)
|
||||||
goto release_mapping;
|
goto release_mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->smmu_bypass) {
|
if (smmu_bypass) {
|
||||||
rc = iommu_domain_set_attr(ctx->mapping->domain,
|
rc = iommu_domain_set_attr(ctx->mapping->domain,
|
||||||
DOMAIN_ATTR_S1_BYPASS,
|
DOMAIN_ATTR_S1_BYPASS,
|
||||||
&ctx->smmu_bypass);
|
&smmu_bypass);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
dev_err(ctx->dev, "Set bypass attribute to SMMU failed (%d)\n",
|
dev_err(ctx->dev, "Set bypass attribute to SMMU failed (%d)\n",
|
||||||
rc);
|
rc);
|
||||||
goto release_mapping;
|
goto release_mapping;
|
||||||
}
|
}
|
||||||
} else if (ctx->smmu_fast_map) {
|
} else {
|
||||||
rc = iommu_domain_set_attr(ctx->mapping->domain,
|
/* Set dma-coherent and page table coherency */
|
||||||
DOMAIN_ATTR_FAST,
|
if (ctx->smmu_coherent) {
|
||||||
&ctx->smmu_fast_map);
|
arch_setup_dma_ops(&ctx->pcidev->dev, 0, 0, NULL, true);
|
||||||
if (rc) {
|
rc = iommu_domain_set_attr(ctx->mapping->domain,
|
||||||
dev_err(ctx->dev, "Set fast attribute to SMMU failed (%d)\n",
|
DOMAIN_ATTR_PAGE_TABLE_FORCE_COHERENT,
|
||||||
rc);
|
&force_pt_coherent);
|
||||||
goto release_mapping;
|
if (rc) {
|
||||||
|
dev_err(ctx->dev,
|
||||||
|
"Set SMMU PAGE_TABLE_FORCE_COHERENT attr failed (%d)\n",
|
||||||
|
rc);
|
||||||
|
goto release_mapping;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx->smmu_fast_map) {
|
||||||
|
rc = iommu_domain_set_attr(ctx->mapping->domain,
|
||||||
|
DOMAIN_ATTR_FAST,
|
||||||
|
&ctx->smmu_fast_map);
|
||||||
|
if (rc) {
|
||||||
|
dev_err(ctx->dev, "Set fast attribute to SMMU failed (%d)\n",
|
||||||
|
rc);
|
||||||
|
goto release_mapping;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -900,6 +921,7 @@ static int msm_11ad_probe(struct platform_device *pdev)
|
||||||
struct device_node *of_node = dev->of_node;
|
struct device_node *of_node = dev->of_node;
|
||||||
struct device_node *rc_node;
|
struct device_node *rc_node;
|
||||||
struct pci_dev *pcidev = NULL;
|
struct pci_dev *pcidev = NULL;
|
||||||
|
u32 smmu_mapping[2];
|
||||||
int rc;
|
int rc;
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
|
@ -954,8 +976,27 @@ static int msm_11ad_probe(struct platform_device *pdev)
|
||||||
ctx->use_smmu = of_property_read_bool(of_node, "qcom,smmu-support");
|
ctx->use_smmu = of_property_read_bool(of_node, "qcom,smmu-support");
|
||||||
ctx->bus_scale = msm_bus_cl_get_pdata(pdev);
|
ctx->bus_scale = msm_bus_cl_get_pdata(pdev);
|
||||||
|
|
||||||
ctx->smmu_bypass = 1;
|
ctx->smmu_s1_en = of_property_read_bool(of_node, "qcom,smmu-s1-en");
|
||||||
ctx->smmu_fast_map = 0;
|
if (ctx->smmu_s1_en) {
|
||||||
|
ctx->smmu_fast_map = of_property_read_bool(
|
||||||
|
of_node, "qcom,smmu-fast-map");
|
||||||
|
ctx->smmu_coherent = of_property_read_bool(
|
||||||
|
of_node, "qcom,smmu-coherent");
|
||||||
|
}
|
||||||
|
rc = of_property_read_u32_array(dev->of_node, "qcom,smmu-mapping",
|
||||||
|
smmu_mapping, 2);
|
||||||
|
if (rc) {
|
||||||
|
dev_err(ctx->dev,
|
||||||
|
"Failed to read base/size smmu addresses %d, fallback to default\n",
|
||||||
|
rc);
|
||||||
|
ctx->smmu_base = SMMU_BASE;
|
||||||
|
ctx->smmu_size = SMMU_SIZE;
|
||||||
|
} else {
|
||||||
|
ctx->smmu_base = smmu_mapping[0];
|
||||||
|
ctx->smmu_size = smmu_mapping[1];
|
||||||
|
}
|
||||||
|
dev_dbg(ctx->dev, "smmu_base=0x%x smmu_sise=0x%x\n",
|
||||||
|
ctx->smmu_base, ctx->smmu_size);
|
||||||
|
|
||||||
/*== execute ==*/
|
/*== execute ==*/
|
||||||
/* turn device on */
|
/* turn device on */
|
||||||
|
|
Loading…
Add table
Reference in a new issue