From nobody Sun Oct 5 02:11:47 2025 Received: from mailout2.samsung.com (mailout2.samsung.com [203.254.224.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EB88A2E62A5 for ; Tue, 12 Aug 2025 05:02:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.254.224.25 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754974961; cv=none; b=fx/sX9uGTW3zTMXdCTupnoDF72RFPBvV7JiL0y5nq3YZ4o0o8YAgmTiF8B6jhbvx9Oxz2+Y64nkrKw6SyEVdt9vUd254kxYT7gRqbb6uxMEbYfvby49h2MPQR6VRdhCkobbFrtBN/nDtvr9JJ6uZ3WKuCUL7YtYowOSGP84ZUlQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754974961; c=relaxed/simple; bh=BcZ/53a0Mr4/tlPAal01W0B8+jcsnyyWtfj6HFXx8wo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:MIME-Version: Content-Type:References; b=tbui1ZahvKTE9pMFldKEsci/ShxHgJu4cdv8xH/LLbIT5CJ6gy0xeJ4mmWds6Y0oOzh1YWnuADzoaylwyX5YM48khWOAB8N97iKUZz1CUR+JmHncBigGC3pNE5ReqMQi+6+STrKDxf8Pz8A4umrEpMVHMK6vqbaDB442euhcih4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com; spf=pass smtp.mailfrom=samsung.com; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b=pOZ0NPS6; arc=none smtp.client-ip=203.254.224.25 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=samsung.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="pOZ0NPS6" Received: from epcas5p4.samsung.com (unknown [182.195.41.42]) by mailout2.samsung.com (KnoxPortal) with ESMTP id 20250812050237epoutp02fbd031198619fd1763713e2ab3ea4c91~a7GzkDUJx0908809088epoutp02K for ; Tue, 12 Aug 2025 05:02:37 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.samsung.com 20250812050237epoutp02fbd031198619fd1763713e2ab3ea4c91~a7GzkDUJx0908809088epoutp02K DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1754974957; bh=4NS8tYI0r1nmofDk8XefvAQBTXQ4W1F7r+dj3X9Hwwg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pOZ0NPS6jzgcqLh+23XxNpUSyCpTTIRf9FxHW2Aq11ZZ/VqBxsKx51yVkmikKQmMw 0pJK0yArYzpVyNcTpQ/NUmF8o1UPNeJLQimhnzrk8CFSP2x9iDbuDIyEQ7oTyYQOB4 YGWvax0cQojlafzwp6AHuNlw9/hKu4kxceD+pC30= Received: from epsnrtp04.localdomain (unknown [182.195.42.156]) by epcas5p1.samsung.com (KnoxPortal) with ESMTPS id 20250812050236epcas5p1e74516e0580cf8a08e86cbd79ab2dc45~a7Gy5hUEW1538515385epcas5p1K; Tue, 12 Aug 2025 05:02:36 +0000 (GMT) Received: from epcas5p2.samsung.com (unknown [182.195.38.86]) by epsnrtp04.localdomain (Postfix) with ESMTP id 4c1KBM39mLz6B9m6; Tue, 12 Aug 2025 05:02:35 +0000 (GMT) Received: from epsmtip1.samsung.com (unknown [182.195.34.30]) by epcas5p3.samsung.com (KnoxPortal) with ESMTPA id 20250811154742epcas5p3276c7c053bedc526d9ce370dda83e195~awQv9dmns2815828158epcas5p3S; Mon, 11 Aug 2025 15:47:42 +0000 (GMT) Received: from cheetah.samsungds.net (unknown [107.109.115.53]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20250811154739epsmtip19674dea8703440bc1f7b4a0340d60e0c~awQtVjeu32101521015epsmtip1X; Mon, 11 Aug 2025 15:47:39 +0000 (GMT) From: Shradha Todi To: linux-pci@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-samsung-soc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org Cc: mani@kernel.org, lpieralisi@kernel.org, kwilczynski@kernel.org, robh@kernel.org, bhelgaas@google.com, jingoohan1@gmail.com, krzk+dt@kernel.org, conor+dt@kernel.org, alim.akhtar@samsung.com, vkoul@kernel.org, kishon@kernel.org, arnd@arndb.de, m.szyprowski@samsung.com, jh80.chung@samsung.com, pankaj.dubey@samsung.com, Shradha Todi Subject: [PATCH v3 11/12] PCI: exynos: Add support for Tesla FSD SoC Date: Mon, 11 Aug 2025 21:16:37 +0530 Message-ID: <20250811154638.95732-12-shradha.t@samsung.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250811154638.95732-1-shradha.t@samsung.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CMS-MailID: 20250811154742epcas5p3276c7c053bedc526d9ce370dda83e195 X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" X-Sendblock-Type: REQ_APPROVE CMS-TYPE: 105P cpgsPolicy: CPGSC10-541,Y X-CFilter-Loop: Reflected X-CMS-RootMailID: 20250811154742epcas5p3276c7c053bedc526d9ce370dda83e195 References: <20250811154638.95732-1-shradha.t@samsung.com> Add host and endpoint controller driver support for FSD SoC. Signed-off-by: Shradha Todi --- drivers/pci/controller/dwc/pci-exynos.c | 278 ++++++++++++++++++++++++ 1 file changed, 278 insertions(+) diff --git a/drivers/pci/controller/dwc/pci-exynos.c b/drivers/pci/controll= er/dwc/pci-exynos.c index ef1f42236575..9aabfecdc147 100644 --- a/drivers/pci/controller/dwc/pci-exynos.c +++ b/drivers/pci/controller/dwc/pci-exynos.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include =20 @@ -49,15 +51,35 @@ #define EXYNOS_PCIE_ELBI_SLV_ARMISC 0x120 #define EXYNOS_PCIE_ELBI_SLV_DBI_ENABLE BIT(21) =20 +#define FSD_IRQ2_STS 0x008 +#define FSD_IRQ_MSI_ENABLE BIT(17) +#define FSD_IRQ2_EN 0x018 +#define FSD_PCIE_APP_LTSSM_ENABLE 0x054 +#define FSD_PCIE_LTSSM_ENABLE 0x1 +#define FSD_PCIE_DEVICE_TYPE 0x080 +#define FSD_DEVICE_TYPE_RC 0x4 +#define FSD_DEVICE_TYPE_EP 0x0 +#define FSD_PCIE_CXPL_DEBUG_00_31 0x2c8 + /* to store different SoC variants of Samsung */ enum samsung_pcie_variants { + FSD, EXYNOS_5433, }; =20 +/* Values to be written to SYSREG to view DBI space as CDM/DBI2/IATU/DMA */ +enum fsd_pcie_addr_type { + ADDR_TYPE_DBI =3D 0x0, + ADDR_TYPE_DBI2 =3D 0x12, + ADDR_TYPE_ATU =3D 0x36, + ADDR_TYPE_DMA =3D 0x3f, +}; + struct samsung_pcie_pdata { struct pci_ops *pci_ops; const struct dw_pcie_ops *dwc_ops; const struct dw_pcie_host_ops *host_ops; + const struct dw_pcie_ep_ops *ep_ops; const struct samsung_res_ops *res_ops; unsigned int soc_variant; enum dw_pcie_device_mode device_mode; @@ -67,6 +89,8 @@ struct exynos_pcie { struct dw_pcie pci; void __iomem *elbi_base; const struct samsung_pcie_pdata *pdata; + struct regmap *sysreg; + unsigned int sysreg_offset; struct clk_bulk_data *clks; struct phy *phy; struct regulator_bulk_data *supplies; @@ -334,11 +358,201 @@ static const struct dw_pcie_ops exynos_dw_pcie_ops = =3D { .start_link =3D exynos_pcie_start_link, }; =20 +static void fsd_pcie_stop_link(struct dw_pcie *pci) +{ + u32 val; + struct exynos_pcie *ep =3D to_exynos_pcie(pci); + + val =3D readl(ep->elbi_base + FSD_PCIE_APP_LTSSM_ENABLE); + val &=3D ~FSD_PCIE_LTSSM_ENABLE; + writel(val, ep->elbi_base + FSD_PCIE_APP_LTSSM_ENABLE); +} + +static int fsd_pcie_start_link(struct dw_pcie *pci) +{ + struct exynos_pcie *ep =3D to_exynos_pcie(pci); + struct dw_pcie_ep *dw_ep =3D &pci->ep; + + if (dw_pcie_link_up(pci)) + return 0; + + writel(FSD_PCIE_LTSSM_ENABLE, ep->elbi_base + FSD_PCIE_APP_LTSSM_ENABLE); + + /* no need to wait for link in case of host as core files take care */ + if (ep->pdata->device_mode =3D=3D DW_PCIE_RC_TYPE) + return 0; + + /* check if the link is up or not in case of EP */ + if (!dw_pcie_wait_for_link(pci)) { + dw_pcie_ep_linkup(dw_ep); + return 0; + } + + return -ETIMEDOUT; +} + +static irqreturn_t fsd_pcie_irq_handler(int irq, void *arg) +{ + u32 val; + struct exynos_pcie *ep =3D arg; + struct dw_pcie *pci =3D &ep->pci; + struct dw_pcie_rp *pp =3D &pci->pp; + + val =3D readl(ep->elbi_base + FSD_IRQ2_STS); + if ((val & FSD_IRQ_MSI_ENABLE) =3D=3D FSD_IRQ_MSI_ENABLE) { + val &=3D FSD_IRQ_MSI_ENABLE; + writel(val, ep->elbi_base + FSD_IRQ2_STS); + dw_handle_msi_irq(pp); + } + + return IRQ_HANDLED; +} + +static void fsd_pcie_msi_init(struct exynos_pcie *ep) +{ + int val; + + val =3D readl(ep->elbi_base + FSD_IRQ2_EN); + val |=3D FSD_IRQ_MSI_ENABLE; + writel(val, ep->elbi_base + FSD_IRQ2_EN); +} + +static void __iomem *fsd_atu_setting(struct dw_pcie *pci, void __iomem *ba= se) +{ + struct exynos_pcie *ep =3D to_exynos_pcie(pci); + + if (base >=3D pci->atu_base) { + regmap_write(ep->sysreg, ep->sysreg_offset, ADDR_TYPE_ATU); + return (base - DEFAULT_DBI_ATU_OFFSET); + } else if (base =3D=3D pci->dbi_base) { + regmap_write(ep->sysreg, ep->sysreg_offset, ADDR_TYPE_DBI); + } else if (base =3D=3D pci->dbi_base2) { + regmap_write(ep->sysreg, ep->sysreg_offset, ADDR_TYPE_DBI2); + } + + return base; +} + +static u32 fsd_pcie_read_dbi(struct dw_pcie *pci, void __iomem *base, + u32 reg, size_t size) +{ + void __iomem *addr; + u32 val; + + addr =3D fsd_atu_setting(pci, base); + dw_pcie_read(addr + reg, size, &val); + + return val; +} + +static void fsd_pcie_write_dbi(struct dw_pcie *pci, void __iomem *base, + u32 reg, size_t size, u32 val) +{ + void __iomem *addr; + + addr =3D fsd_atu_setting(pci, base); + dw_pcie_write(addr + reg, size, val); +} + +static void fsd_pcie_write_dbi2(struct dw_pcie *pci, void __iomem *base, + u32 reg, size_t size, u32 val) +{ + struct exynos_pcie *ep =3D to_exynos_pcie(pci); + + fsd_atu_setting(pci, base); + dw_pcie_write(pci->dbi_base + reg, size, val); + regmap_write(ep->sysreg, ep->sysreg_offset, ADDR_TYPE_DBI); +} + +static bool fsd_pcie_link_up(struct dw_pcie *pci) +{ + u32 val; + struct exynos_pcie *ep =3D to_exynos_pcie(pci); + + val =3D readl(ep->elbi_base + FSD_PCIE_CXPL_DEBUG_00_31); + val &=3D PORT_LOGIC_LTSSM_STATE_MASK; + + return (val =3D=3D PORT_LOGIC_LTSSM_STATE_L0); +} + +static int fsd_pcie_host_init(struct dw_pcie_rp *pp) +{ + struct dw_pcie *pci =3D to_dw_pcie_from_pp(pp); + struct exynos_pcie *ep =3D to_exynos_pcie(pci); + + phy_init(ep->phy); + fsd_pcie_msi_init(ep); + + return 0; +} + +static const struct dw_pcie_host_ops fsd_pcie_host_ops =3D { + .init =3D fsd_pcie_host_init, +}; + +static int fsd_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no, + unsigned int type, u16 interrupt_num) +{ + struct dw_pcie *pci =3D to_dw_pcie_from_ep(ep); + + switch (type) { + case PCI_IRQ_INTX: + return dw_pcie_ep_raise_intx_irq(ep, func_no); + case PCI_IRQ_MSIX: + dev_err(pci->dev, "EP does not support MSI-X\n"); + return -EINVAL; + case PCI_IRQ_MSI: + return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num); + default: + dev_err(pci->dev, "UNKNOWN IRQ type\n"); + } + + return 0; +} + +static const struct pci_epc_features fsd_pcie_epc_features =3D { + .linkup_notifier =3D false, + .msi_capable =3D true, + .msix_capable =3D false, +}; + +static const struct pci_epc_features *fsd_pcie_get_features(struct dw_pcie= _ep *ep) +{ + return &fsd_pcie_epc_features; +} + +static const struct dw_pcie_ep_ops fsd_ep_ops =3D { + .raise_irq =3D fsd_pcie_raise_irq, + .get_features =3D fsd_pcie_get_features, +}; + +static void fsd_set_device_mode(struct exynos_pcie *ep) +{ + if (ep->pdata->device_mode =3D=3D DW_PCIE_RC_TYPE) + writel(FSD_DEVICE_TYPE_RC, ep->elbi_base + FSD_PCIE_DEVICE_TYPE); + else + writel(FSD_DEVICE_TYPE_EP, ep->elbi_base + FSD_PCIE_DEVICE_TYPE); +} + +static const struct dw_pcie_ops fsd_dw_pcie_ops =3D { + .read_dbi =3D fsd_pcie_read_dbi, + .write_dbi =3D fsd_pcie_write_dbi, + .write_dbi2 =3D fsd_pcie_write_dbi2, + .start_link =3D fsd_pcie_start_link, + .stop_link =3D fsd_pcie_stop_link, + .link_up =3D fsd_pcie_link_up, +}; + static const struct samsung_res_ops exynos_res_ops_data =3D { .init_regulator =3D exynos_init_regulator, .pcie_irq_handler =3D exynos_pcie_irq_handler, }; =20 +static const struct samsung_res_ops fsd_res_ops_data =3D { + .pcie_irq_handler =3D fsd_pcie_irq_handler, + .set_device_mode =3D fsd_set_device_mode, +}; + static int exynos_pcie_probe(struct platform_device *pdev) { struct device *dev =3D &pdev->dev; @@ -361,6 +575,26 @@ static int exynos_pcie_probe(struct platform_device *p= dev) if (IS_ERR(ep->phy)) return PTR_ERR(ep->phy); =20 + if (ep->pdata->soc_variant =3D=3D FSD) { + ret =3D dma_set_mask_and_coherent(dev, DMA_BIT_MASK(36)); + if (ret) + return ret; + + ep->sysreg =3D syscon_regmap_lookup_by_phandle(dev->of_node, + "samsung,syscon-pcie"); + if (IS_ERR(ep->sysreg)) { + dev_err(dev, "sysreg regmap lookup failed.\n"); + return PTR_ERR(ep->sysreg); + } + + ret =3D of_property_read_u32_index(dev->of_node, "samsung,syscon-pcie", = 1, + &ep->sysreg_offset); + if (ret) { + dev_err(dev, "couldn't get the register offset for syscon!\n"); + return ret; + } + } + /* External Local Bus interface (ELBI) registers */ ep->elbi_base =3D devm_platform_ioremap_resource_byname(pdev, "elbi"); if (IS_ERR(ep->elbi_base)) @@ -397,6 +631,22 @@ static int exynos_pcie_probe(struct platform_device *p= dev) if (ret < 0) goto fail_phy_init; =20 + break; + case DW_PCIE_EP_TYPE: + phy_init(ep->phy); + + ep->pci.ep.ops =3D pdata->ep_ops; + + ret =3D dw_pcie_ep_init(&ep->pci.ep); + if (ret < 0) + goto fail_phy_init; + + ret =3D dw_pcie_ep_init_registers(&ep->pci.ep); + if (ret) + goto fail_phy_init; + + pci_epc_init_notify(ep->pci.ep.epc); + break; default: dev_err(dev, "invalid device type\n"); @@ -436,6 +686,9 @@ static int exynos_pcie_suspend_noirq(struct device *dev) if (ep->pdata->device_mode =3D=3D DW_PCIE_EP_TYPE) return 0; =20 + if (ep->pdata->dwc_ops->stop_link) + ep->pdata->dwc_ops->stop_link(pci); + if (ep->pdata->soc_variant =3D=3D EXYNOS_5433) exynos_pcie_assert_core_reset(ep); phy_power_off(ep->phy); @@ -471,6 +724,23 @@ static const struct dev_pm_ops exynos_pcie_pm_ops =3D { exynos_pcie_resume_noirq) }; =20 + +static const struct samsung_pcie_pdata fsd_hw3_pcie_rc_pdata =3D { + .dwc_ops =3D &fsd_dw_pcie_ops, + .host_ops =3D &fsd_pcie_host_ops, + .res_ops =3D &fsd_res_ops_data, + .soc_variant =3D FSD, + .device_mode =3D DW_PCIE_RC_TYPE, +}; + +static const struct samsung_pcie_pdata fsd_hw3_pcie_ep_pdata =3D { + .dwc_ops =3D &fsd_dw_pcie_ops, + .ep_ops =3D &fsd_ep_ops, + .res_ops =3D &fsd_res_ops_data, + .soc_variant =3D FSD, + .device_mode =3D DW_PCIE_EP_TYPE, +}; + static const struct samsung_pcie_pdata exynos_5433_pcie_rc_pdata =3D { .dwc_ops =3D &exynos_dw_pcie_ops, .pci_ops =3D &exynos_pci_ops, @@ -485,6 +755,14 @@ static const struct of_device_id exynos_pcie_of_match[= ] =3D { .compatible =3D "samsung,exynos5433-pcie", .data =3D (void *) &exynos_5433_pcie_rc_pdata, }, + { + .compatible =3D "tesla,fsd-pcie", + .data =3D (void *) &fsd_hw3_pcie_rc_pdata, + }, + { + .compatible =3D "tesla,fsd-pcie-ep", + .data =3D (void *) &fsd_hw3_pcie_ep_pdata, + }, { }, }; =20 --=20 2.49.0