Loading Documentation/devicetree/bindings/pci/msm_ep_pcie.txt +1 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ Optional Properties: 1, 2 or 3. - qcom,pcie-active-config: boolean type; active configuration of PCIe addressing. - qcom,pcie-edma: boolean type; edma usage for PCIe. - qcom,pcie-aggregated-irq: boolean type; interrupts are aggregated. - qcom,pcie-mhi-a7-irq: boolean type; MHI a7 has separate irq. - qcom,pcie-perst-enum: Link enumeration will be triggered by PERST Loading drivers/platform/msm/ep_pcie/ep_pcie_com.h +7 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <linux/uaccess.h> #include <linux/delay.h> #include <linux/msm_ep_pcie.h> #include <linux/iommu.h> #define PCIE20_PARF_SYS_CTRL 0x00 #define PCIE20_PARF_DB_CTRL 0x10 Loading Loading @@ -56,6 +57,8 @@ #define PCIE20_PARF_ATU_BASE_ADDR 0x634 #define PCIE20_PARF_ATU_BASE_ADDR_HI 0x638 #define PCIE20_PARF_DEVICE_TYPE 0x1000 #define PCIE20_PARF_EDMA_BASE_ADDR 0x64C #define PCIE20_PARF_EDMA_BASE_ADDR_HI 0x650 #define PCIE20_ELBI_VERSION 0x00 #define PCIE20_ELBI_SYS_CTRL 0x04 Loading Loading @@ -229,6 +232,7 @@ enum ep_pcie_res { EP_PCIE_RES_DM_CORE, EP_PCIE_RES_ELBI, EP_PCIE_RES_IATU, EP_PCIE_RES_EDMA, EP_PCIE_MAX_RES, }; Loading Loading @@ -318,6 +322,7 @@ struct ep_pcie_dev_t { void __iomem *mmio; void __iomem *msi; void __iomem *dm_core; void __iomem *edma; void __iomem *elbi; void __iomem *iatu; Loading @@ -327,6 +332,7 @@ struct ep_pcie_dev_t { bool active_config; bool aggregated_irq; bool mhi_a7_irq; bool pcie_edma; u32 dbi_base_reg; u32 slv_space_reg; u32 phy_status_reg; Loading Loading @@ -418,5 +424,6 @@ extern bool ep_pcie_phy_is_ready(struct ep_pcie_dev_t *dev); extern void ep_pcie_reg_dump(struct ep_pcie_dev_t *dev, u32 sel, bool linkdown); extern void ep_pcie_debugfs_init(struct ep_pcie_dev_t *ep_dev); extern void ep_pcie_debugfs_exit(void); extern int qcom_edma_init(struct device *dev); #endif drivers/platform/msm/ep_pcie/ep_pcie_core.c +76 −2 Original line number Diff line number Diff line Loading @@ -35,6 +35,9 @@ #include <linux/irq.h> #include "ep_pcie_com.h" #include <asm/dma-iommu.h> #include <linux/dma-mapping.h> #include <linux/platform_device.h> /* debug mask sys interface */ static int ep_pcie_debug_mask; Loading Loading @@ -92,6 +95,7 @@ static const struct ep_pcie_res_info_t ep_pcie_res_info[EP_PCIE_MAX_RES] = { {"dm_core", NULL, NULL}, {"elbi", NULL, NULL}, {"iatu", NULL, NULL}, {"edma", NULL, NULL}, }; static const struct ep_pcie_irq_info_t ep_pcie_irq_info[EP_PCIE_MAX_IRQ] = { Loading Loading @@ -597,6 +601,25 @@ static void ep_pcie_core_init(struct ep_pcie_dev_t *dev, bool configured) "PCIe V%d: LSB of ATU base:0x%x\n", dev->rev, readl_relaxed(dev->parf + PCIE20_PARF_ATU_BASE_ADDR)); if (dev->pcie_edma) { struct resource *edma = dev->res[EP_PCIE_RES_EDMA].resource; u32 edma_lo = edma->start; ep_pcie_write_reg(dev->parf, PCIE20_PARF_EDMA_BASE_ADDR_HI, 0x100); EP_PCIE_DBG(dev, "PCIe V%d: EDMA base HI :0x%x\n", dev->rev, readl_relaxed(dev->parf + PCIE20_PARF_EDMA_BASE_ADDR_HI)); ep_pcie_write_reg(dev->parf, PCIE20_PARF_EDMA_BASE_ADDR, edma_lo); EP_PCIE_DBG(dev, "PCIe V%d: EDMA base:0x%x\n", dev->rev, readl_relaxed(dev->parf + PCIE20_PARF_EDMA_BASE_ADDR)); } } } Loading Loading @@ -710,6 +733,10 @@ static void ep_pcie_core_init(struct ep_pcie_dev_t *dev, bool configured) ep_pcie_write_mask(dev->parf + PCIE20_PARF_INT_ALL_MASK, 0, BIT(EP_PCIE_INT_EVT_MHI_A7)); if (dev->pcie_edma) ep_pcie_write_mask(dev->parf + PCIE20_PARF_INT_ALL_MASK, 0, BIT(EP_PCIE_INT_EVT_EDMA)); EP_PCIE_DBG(dev, "PCIe V%d: PCIE20_PARF_INT_ALL_MASK:0x%x\n", dev->rev, Loading Loading @@ -806,8 +833,15 @@ static void ep_pcie_config_outbound_iatu_entry(struct ep_pcie_dev_t *dev, tgt_lower); ep_pcie_write_reg(dev->iatu, PCIE20_IATU_O_UTAR(region), tgt_upper); ep_pcie_write_mask(dev->iatu + PCIE20_IATU_O_CTRL2(region), 0, BIT(31)); /* Set DMA Bypass bit for eDMA */ if (dev->pcie_edma) ep_pcie_write_mask(dev->iatu + PCIE20_IATU_O_CTRL2(region), 0, BIT(31)|BIT(27)); else ep_pcie_write_mask(dev->iatu + PCIE20_IATU_O_CTRL2(region), 0, BIT(31)); EP_PCIE_DBG(dev, "PCIe V%d: Outbound iATU configuration\n", dev->rev); Loading Loading @@ -1166,6 +1200,7 @@ static int ep_pcie_get_resources(struct ep_pcie_dev_t *dev, dev->mmio = dev->res[EP_PCIE_RES_MMIO].base; dev->msi = dev->res[EP_PCIE_RES_MSI].base; dev->dm_core = dev->res[EP_PCIE_RES_DM_CORE].base; dev->edma = dev->res[EP_PCIE_RES_EDMA].base; dev->elbi = dev->res[EP_PCIE_RES_ELBI].base; dev->iatu = dev->res[EP_PCIE_RES_IATU].base; Loading @@ -1179,6 +1214,7 @@ static void ep_pcie_release_resources(struct ep_pcie_dev_t *dev) dev->parf = NULL; dev->elbi = NULL; dev->dm_core = NULL; dev->edma = NULL; dev->phy = NULL; dev->mmio = NULL; dev->msi = NULL; Loading Loading @@ -2459,6 +2495,8 @@ struct ep_pcie_hw hw_drv = { static int ep_pcie_probe(struct platform_device *pdev) { int ret; struct dma_iommu_mapping *mapping; int bypass_en = 1; pr_debug("%s\n", __func__); Loading Loading @@ -2519,6 +2557,12 @@ static int ep_pcie_probe(struct platform_device *pdev) EP_PCIE_DBG(&ep_pcie_dev, "PCIe V%d: pcie-phy-ver:%d\n", ep_pcie_dev.rev, ep_pcie_dev.phy_rev); ep_pcie_dev.pcie_edma = of_property_read_bool((&pdev->dev)->of_node, "qcom,pcie-edma"); EP_PCIE_DBG(&ep_pcie_dev, "PCIe V%d: pcie edma is %s enabled\n", ep_pcie_dev.rev, ep_pcie_dev.pcie_edma ? "" : "not"); ep_pcie_dev.active_config = of_property_read_bool((&pdev->dev)->of_node, "qcom,pcie-active-config"); EP_PCIE_DBG(&ep_pcie_dev, Loading Loading @@ -2602,7 +2646,37 @@ static int ep_pcie_probe(struct platform_device *pdev) "PCIe V%d: %s got resources successfully; start turning on the link\n", ep_pcie_dev.rev, dev_name(&(pdev->dev))); if (ep_pcie_dev.pcie_edma) { mapping = arm_iommu_create_mapping (&platform_bus_type, 0, SZ_4K); if (IS_ERR_OR_NULL(mapping)) { EP_PCIE_ERR(&ep_pcie_dev, "PCIe V%d: Failed to create_mapping\n", ep_pcie_dev.rev); goto skip_mapping; } ret = iommu_domain_set_attr(mapping->domain, DOMAIN_ATTR_S1_BYPASS, &bypass_en); if (ret < 0) EP_PCIE_ERR(&ep_pcie_dev, "PCIe V%d: Failed to set bypass\n", ep_pcie_dev.rev); ret = arm_iommu_attach_device(&pdev->dev, mapping); if (ret) EP_PCIE_ERR(&ep_pcie_dev, "PCIe V%d: arm_iommu_attach_device failed %d\n", ep_pcie_dev.rev, ret); else EP_PCIE_ERR(&ep_pcie_dev, "PCIe V%d: arm_iommu_attach_device successful\n", ep_pcie_dev.rev); } skip_mapping: ret = ep_pcie_enumeration(&ep_pcie_dev); if (IS_ENABLED(CONFIG_QCOM_PCI_EDMA)) qcom_edma_init(&pdev->dev); if (!ret || ep_pcie_debug_keep_resource) return 0; Loading include/linux/msm_ep_pcie.h +2 −1 Original line number Diff line number Diff line /* Copyright (c) 2015, 2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2015, 2017, 2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -47,6 +47,7 @@ enum ep_pcie_irq_event { EP_PCIE_INT_EVT_CFG_WRITE, EP_PCIE_INT_EVT_BRIDGE_FLUSH_N, EP_PCIE_INT_EVT_LINK_UP, EP_PCIE_INT_EVT_EDMA = 22, EP_PCIE_INT_EVT_MAX = 13, }; Loading Loading
Documentation/devicetree/bindings/pci/msm_ep_pcie.txt +1 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ Optional Properties: 1, 2 or 3. - qcom,pcie-active-config: boolean type; active configuration of PCIe addressing. - qcom,pcie-edma: boolean type; edma usage for PCIe. - qcom,pcie-aggregated-irq: boolean type; interrupts are aggregated. - qcom,pcie-mhi-a7-irq: boolean type; MHI a7 has separate irq. - qcom,pcie-perst-enum: Link enumeration will be triggered by PERST Loading
drivers/platform/msm/ep_pcie/ep_pcie_com.h +7 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <linux/uaccess.h> #include <linux/delay.h> #include <linux/msm_ep_pcie.h> #include <linux/iommu.h> #define PCIE20_PARF_SYS_CTRL 0x00 #define PCIE20_PARF_DB_CTRL 0x10 Loading Loading @@ -56,6 +57,8 @@ #define PCIE20_PARF_ATU_BASE_ADDR 0x634 #define PCIE20_PARF_ATU_BASE_ADDR_HI 0x638 #define PCIE20_PARF_DEVICE_TYPE 0x1000 #define PCIE20_PARF_EDMA_BASE_ADDR 0x64C #define PCIE20_PARF_EDMA_BASE_ADDR_HI 0x650 #define PCIE20_ELBI_VERSION 0x00 #define PCIE20_ELBI_SYS_CTRL 0x04 Loading Loading @@ -229,6 +232,7 @@ enum ep_pcie_res { EP_PCIE_RES_DM_CORE, EP_PCIE_RES_ELBI, EP_PCIE_RES_IATU, EP_PCIE_RES_EDMA, EP_PCIE_MAX_RES, }; Loading Loading @@ -318,6 +322,7 @@ struct ep_pcie_dev_t { void __iomem *mmio; void __iomem *msi; void __iomem *dm_core; void __iomem *edma; void __iomem *elbi; void __iomem *iatu; Loading @@ -327,6 +332,7 @@ struct ep_pcie_dev_t { bool active_config; bool aggregated_irq; bool mhi_a7_irq; bool pcie_edma; u32 dbi_base_reg; u32 slv_space_reg; u32 phy_status_reg; Loading Loading @@ -418,5 +424,6 @@ extern bool ep_pcie_phy_is_ready(struct ep_pcie_dev_t *dev); extern void ep_pcie_reg_dump(struct ep_pcie_dev_t *dev, u32 sel, bool linkdown); extern void ep_pcie_debugfs_init(struct ep_pcie_dev_t *ep_dev); extern void ep_pcie_debugfs_exit(void); extern int qcom_edma_init(struct device *dev); #endif
drivers/platform/msm/ep_pcie/ep_pcie_core.c +76 −2 Original line number Diff line number Diff line Loading @@ -35,6 +35,9 @@ #include <linux/irq.h> #include "ep_pcie_com.h" #include <asm/dma-iommu.h> #include <linux/dma-mapping.h> #include <linux/platform_device.h> /* debug mask sys interface */ static int ep_pcie_debug_mask; Loading Loading @@ -92,6 +95,7 @@ static const struct ep_pcie_res_info_t ep_pcie_res_info[EP_PCIE_MAX_RES] = { {"dm_core", NULL, NULL}, {"elbi", NULL, NULL}, {"iatu", NULL, NULL}, {"edma", NULL, NULL}, }; static const struct ep_pcie_irq_info_t ep_pcie_irq_info[EP_PCIE_MAX_IRQ] = { Loading Loading @@ -597,6 +601,25 @@ static void ep_pcie_core_init(struct ep_pcie_dev_t *dev, bool configured) "PCIe V%d: LSB of ATU base:0x%x\n", dev->rev, readl_relaxed(dev->parf + PCIE20_PARF_ATU_BASE_ADDR)); if (dev->pcie_edma) { struct resource *edma = dev->res[EP_PCIE_RES_EDMA].resource; u32 edma_lo = edma->start; ep_pcie_write_reg(dev->parf, PCIE20_PARF_EDMA_BASE_ADDR_HI, 0x100); EP_PCIE_DBG(dev, "PCIe V%d: EDMA base HI :0x%x\n", dev->rev, readl_relaxed(dev->parf + PCIE20_PARF_EDMA_BASE_ADDR_HI)); ep_pcie_write_reg(dev->parf, PCIE20_PARF_EDMA_BASE_ADDR, edma_lo); EP_PCIE_DBG(dev, "PCIe V%d: EDMA base:0x%x\n", dev->rev, readl_relaxed(dev->parf + PCIE20_PARF_EDMA_BASE_ADDR)); } } } Loading Loading @@ -710,6 +733,10 @@ static void ep_pcie_core_init(struct ep_pcie_dev_t *dev, bool configured) ep_pcie_write_mask(dev->parf + PCIE20_PARF_INT_ALL_MASK, 0, BIT(EP_PCIE_INT_EVT_MHI_A7)); if (dev->pcie_edma) ep_pcie_write_mask(dev->parf + PCIE20_PARF_INT_ALL_MASK, 0, BIT(EP_PCIE_INT_EVT_EDMA)); EP_PCIE_DBG(dev, "PCIe V%d: PCIE20_PARF_INT_ALL_MASK:0x%x\n", dev->rev, Loading Loading @@ -806,8 +833,15 @@ static void ep_pcie_config_outbound_iatu_entry(struct ep_pcie_dev_t *dev, tgt_lower); ep_pcie_write_reg(dev->iatu, PCIE20_IATU_O_UTAR(region), tgt_upper); ep_pcie_write_mask(dev->iatu + PCIE20_IATU_O_CTRL2(region), 0, BIT(31)); /* Set DMA Bypass bit for eDMA */ if (dev->pcie_edma) ep_pcie_write_mask(dev->iatu + PCIE20_IATU_O_CTRL2(region), 0, BIT(31)|BIT(27)); else ep_pcie_write_mask(dev->iatu + PCIE20_IATU_O_CTRL2(region), 0, BIT(31)); EP_PCIE_DBG(dev, "PCIe V%d: Outbound iATU configuration\n", dev->rev); Loading Loading @@ -1166,6 +1200,7 @@ static int ep_pcie_get_resources(struct ep_pcie_dev_t *dev, dev->mmio = dev->res[EP_PCIE_RES_MMIO].base; dev->msi = dev->res[EP_PCIE_RES_MSI].base; dev->dm_core = dev->res[EP_PCIE_RES_DM_CORE].base; dev->edma = dev->res[EP_PCIE_RES_EDMA].base; dev->elbi = dev->res[EP_PCIE_RES_ELBI].base; dev->iatu = dev->res[EP_PCIE_RES_IATU].base; Loading @@ -1179,6 +1214,7 @@ static void ep_pcie_release_resources(struct ep_pcie_dev_t *dev) dev->parf = NULL; dev->elbi = NULL; dev->dm_core = NULL; dev->edma = NULL; dev->phy = NULL; dev->mmio = NULL; dev->msi = NULL; Loading Loading @@ -2459,6 +2495,8 @@ struct ep_pcie_hw hw_drv = { static int ep_pcie_probe(struct platform_device *pdev) { int ret; struct dma_iommu_mapping *mapping; int bypass_en = 1; pr_debug("%s\n", __func__); Loading Loading @@ -2519,6 +2557,12 @@ static int ep_pcie_probe(struct platform_device *pdev) EP_PCIE_DBG(&ep_pcie_dev, "PCIe V%d: pcie-phy-ver:%d\n", ep_pcie_dev.rev, ep_pcie_dev.phy_rev); ep_pcie_dev.pcie_edma = of_property_read_bool((&pdev->dev)->of_node, "qcom,pcie-edma"); EP_PCIE_DBG(&ep_pcie_dev, "PCIe V%d: pcie edma is %s enabled\n", ep_pcie_dev.rev, ep_pcie_dev.pcie_edma ? "" : "not"); ep_pcie_dev.active_config = of_property_read_bool((&pdev->dev)->of_node, "qcom,pcie-active-config"); EP_PCIE_DBG(&ep_pcie_dev, Loading Loading @@ -2602,7 +2646,37 @@ static int ep_pcie_probe(struct platform_device *pdev) "PCIe V%d: %s got resources successfully; start turning on the link\n", ep_pcie_dev.rev, dev_name(&(pdev->dev))); if (ep_pcie_dev.pcie_edma) { mapping = arm_iommu_create_mapping (&platform_bus_type, 0, SZ_4K); if (IS_ERR_OR_NULL(mapping)) { EP_PCIE_ERR(&ep_pcie_dev, "PCIe V%d: Failed to create_mapping\n", ep_pcie_dev.rev); goto skip_mapping; } ret = iommu_domain_set_attr(mapping->domain, DOMAIN_ATTR_S1_BYPASS, &bypass_en); if (ret < 0) EP_PCIE_ERR(&ep_pcie_dev, "PCIe V%d: Failed to set bypass\n", ep_pcie_dev.rev); ret = arm_iommu_attach_device(&pdev->dev, mapping); if (ret) EP_PCIE_ERR(&ep_pcie_dev, "PCIe V%d: arm_iommu_attach_device failed %d\n", ep_pcie_dev.rev, ret); else EP_PCIE_ERR(&ep_pcie_dev, "PCIe V%d: arm_iommu_attach_device successful\n", ep_pcie_dev.rev); } skip_mapping: ret = ep_pcie_enumeration(&ep_pcie_dev); if (IS_ENABLED(CONFIG_QCOM_PCI_EDMA)) qcom_edma_init(&pdev->dev); if (!ret || ep_pcie_debug_keep_resource) return 0; Loading
include/linux/msm_ep_pcie.h +2 −1 Original line number Diff line number Diff line /* Copyright (c) 2015, 2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2015, 2017, 2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -47,6 +47,7 @@ enum ep_pcie_irq_event { EP_PCIE_INT_EVT_CFG_WRITE, EP_PCIE_INT_EVT_BRIDGE_FLUSH_N, EP_PCIE_INT_EVT_LINK_UP, EP_PCIE_INT_EVT_EDMA = 22, EP_PCIE_INT_EVT_MAX = 13, }; Loading