10d0c5510SYoshihiro Shimoda // SPDX-License-Identifier: GPL-2.0-only 20d0c5510SYoshihiro Shimoda /* 30d0c5510SYoshihiro Shimoda * PCIe controller driver for Renesas R-Car Gen4 Series SoCs 40d0c5510SYoshihiro Shimoda * Copyright (C) 2022-2023 Renesas Electronics Corporation 50d0c5510SYoshihiro Shimoda */ 60d0c5510SYoshihiro Shimoda 70d0c5510SYoshihiro Shimoda #include <linux/delay.h> 80d0c5510SYoshihiro Shimoda #include <linux/interrupt.h> 90d0c5510SYoshihiro Shimoda #include <linux/io.h> 100d0c5510SYoshihiro Shimoda #include <linux/module.h> 11ec215237SRob Herring #include <linux/of.h> 120d0c5510SYoshihiro Shimoda #include <linux/pci.h> 130d0c5510SYoshihiro Shimoda #include <linux/platform_device.h> 140d0c5510SYoshihiro Shimoda #include <linux/pm_runtime.h> 150d0c5510SYoshihiro Shimoda #include <linux/reset.h> 160d0c5510SYoshihiro Shimoda 170d0c5510SYoshihiro Shimoda #include "../../pci.h" 180d0c5510SYoshihiro Shimoda #include "pcie-designware.h" 190d0c5510SYoshihiro Shimoda 200d0c5510SYoshihiro Shimoda /* Renesas-specific */ 210d0c5510SYoshihiro Shimoda /* PCIe Mode Setting Register 0 */ 220d0c5510SYoshihiro Shimoda #define PCIEMSR0 0x0000 230d0c5510SYoshihiro Shimoda #define BIFUR_MOD_SET_ON BIT(0) 24e311b383SYoshihiro Shimoda #define DEVICE_TYPE_EP 0 250d0c5510SYoshihiro Shimoda #define DEVICE_TYPE_RC BIT(4) 260d0c5510SYoshihiro Shimoda 270d0c5510SYoshihiro Shimoda /* PCIe Interrupt Status 0 */ 280d0c5510SYoshihiro Shimoda #define PCIEINTSTS0 0x0084 290d0c5510SYoshihiro Shimoda 300d0c5510SYoshihiro Shimoda /* PCIe Interrupt Status 0 Enable */ 310d0c5510SYoshihiro Shimoda #define PCIEINTSTS0EN 0x0310 320d0c5510SYoshihiro Shimoda #define MSI_CTRL_INT BIT(26) 330d0c5510SYoshihiro Shimoda #define SMLH_LINK_UP BIT(7) 340d0c5510SYoshihiro Shimoda #define RDLH_LINK_UP BIT(6) 350d0c5510SYoshihiro Shimoda 360d0c5510SYoshihiro Shimoda /* PCIe DMA Interrupt Status Enable */ 370d0c5510SYoshihiro Shimoda #define PCIEDMAINTSTSEN 0x0314 380d0c5510SYoshihiro Shimoda #define PCIEDMAINTSTSEN_INIT GENMASK(15, 0) 390d0c5510SYoshihiro Shimoda 400d0c5510SYoshihiro Shimoda /* PCIe Reset Control Register 1 */ 410d0c5510SYoshihiro Shimoda #define PCIERSTCTRL1 0x0014 420d0c5510SYoshihiro Shimoda #define APP_HOLD_PHY_RST BIT(16) 430d0c5510SYoshihiro Shimoda #define APP_LTSSM_ENABLE BIT(0) 440d0c5510SYoshihiro Shimoda 450d0c5510SYoshihiro Shimoda #define RCAR_NUM_SPEED_CHANGE_RETRIES 10 460d0c5510SYoshihiro Shimoda #define RCAR_MAX_LINK_SPEED 4 470d0c5510SYoshihiro Shimoda 48e311b383SYoshihiro Shimoda #define RCAR_GEN4_PCIE_EP_FUNC_DBI_OFFSET 0x1000 49e311b383SYoshihiro Shimoda #define RCAR_GEN4_PCIE_EP_FUNC_DBI2_OFFSET 0x800 50e311b383SYoshihiro Shimoda 510d0c5510SYoshihiro Shimoda struct rcar_gen4_pcie { 520d0c5510SYoshihiro Shimoda struct dw_pcie dw; 530d0c5510SYoshihiro Shimoda void __iomem *base; 540d0c5510SYoshihiro Shimoda struct platform_device *pdev; 550d0c5510SYoshihiro Shimoda enum dw_pcie_device_mode mode; 560d0c5510SYoshihiro Shimoda }; 570d0c5510SYoshihiro Shimoda #define to_rcar_gen4_pcie(_dw) container_of(_dw, struct rcar_gen4_pcie, dw) 580d0c5510SYoshihiro Shimoda 59e311b383SYoshihiro Shimoda /* Common */ 600d0c5510SYoshihiro Shimoda static void rcar_gen4_pcie_ltssm_enable(struct rcar_gen4_pcie *rcar, 610d0c5510SYoshihiro Shimoda bool enable) 620d0c5510SYoshihiro Shimoda { 630d0c5510SYoshihiro Shimoda u32 val; 640d0c5510SYoshihiro Shimoda 650d0c5510SYoshihiro Shimoda val = readl(rcar->base + PCIERSTCTRL1); 660d0c5510SYoshihiro Shimoda if (enable) { 670d0c5510SYoshihiro Shimoda val |= APP_LTSSM_ENABLE; 680d0c5510SYoshihiro Shimoda val &= ~APP_HOLD_PHY_RST; 690d0c5510SYoshihiro Shimoda } else { 700d0c5510SYoshihiro Shimoda /* 710d0c5510SYoshihiro Shimoda * Since the datasheet of R-Car doesn't mention how to assert 720d0c5510SYoshihiro Shimoda * the APP_HOLD_PHY_RST, don't assert it again. Otherwise, 730d0c5510SYoshihiro Shimoda * hang-up issue happened in the dw_edma_core_off() when 740d0c5510SYoshihiro Shimoda * the controller didn't detect a PCI device. 750d0c5510SYoshihiro Shimoda */ 760d0c5510SYoshihiro Shimoda val &= ~APP_LTSSM_ENABLE; 770d0c5510SYoshihiro Shimoda } 780d0c5510SYoshihiro Shimoda writel(val, rcar->base + PCIERSTCTRL1); 790d0c5510SYoshihiro Shimoda } 800d0c5510SYoshihiro Shimoda 810d0c5510SYoshihiro Shimoda static int rcar_gen4_pcie_link_up(struct dw_pcie *dw) 820d0c5510SYoshihiro Shimoda { 830d0c5510SYoshihiro Shimoda struct rcar_gen4_pcie *rcar = to_rcar_gen4_pcie(dw); 840d0c5510SYoshihiro Shimoda u32 val, mask; 850d0c5510SYoshihiro Shimoda 860d0c5510SYoshihiro Shimoda val = readl(rcar->base + PCIEINTSTS0); 870d0c5510SYoshihiro Shimoda mask = RDLH_LINK_UP | SMLH_LINK_UP; 880d0c5510SYoshihiro Shimoda 890d0c5510SYoshihiro Shimoda return (val & mask) == mask; 900d0c5510SYoshihiro Shimoda } 910d0c5510SYoshihiro Shimoda 920d0c5510SYoshihiro Shimoda /* 930d0c5510SYoshihiro Shimoda * Manually initiate the speed change. Return 0 if change succeeded; otherwise 940d0c5510SYoshihiro Shimoda * -ETIMEDOUT. 950d0c5510SYoshihiro Shimoda */ 960d0c5510SYoshihiro Shimoda static int rcar_gen4_pcie_speed_change(struct dw_pcie *dw) 970d0c5510SYoshihiro Shimoda { 980d0c5510SYoshihiro Shimoda u32 val; 990d0c5510SYoshihiro Shimoda int i; 1000d0c5510SYoshihiro Shimoda 1010d0c5510SYoshihiro Shimoda val = dw_pcie_readl_dbi(dw, PCIE_LINK_WIDTH_SPEED_CONTROL); 1020d0c5510SYoshihiro Shimoda val &= ~PORT_LOGIC_SPEED_CHANGE; 1030d0c5510SYoshihiro Shimoda dw_pcie_writel_dbi(dw, PCIE_LINK_WIDTH_SPEED_CONTROL, val); 1040d0c5510SYoshihiro Shimoda 1050d0c5510SYoshihiro Shimoda val = dw_pcie_readl_dbi(dw, PCIE_LINK_WIDTH_SPEED_CONTROL); 1060d0c5510SYoshihiro Shimoda val |= PORT_LOGIC_SPEED_CHANGE; 1070d0c5510SYoshihiro Shimoda dw_pcie_writel_dbi(dw, PCIE_LINK_WIDTH_SPEED_CONTROL, val); 1080d0c5510SYoshihiro Shimoda 1090d0c5510SYoshihiro Shimoda for (i = 0; i < RCAR_NUM_SPEED_CHANGE_RETRIES; i++) { 1100d0c5510SYoshihiro Shimoda val = dw_pcie_readl_dbi(dw, PCIE_LINK_WIDTH_SPEED_CONTROL); 1110d0c5510SYoshihiro Shimoda if (!(val & PORT_LOGIC_SPEED_CHANGE)) 1120d0c5510SYoshihiro Shimoda return 0; 1130d0c5510SYoshihiro Shimoda usleep_range(10000, 11000); 1140d0c5510SYoshihiro Shimoda } 1150d0c5510SYoshihiro Shimoda 1160d0c5510SYoshihiro Shimoda return -ETIMEDOUT; 1170d0c5510SYoshihiro Shimoda } 1180d0c5510SYoshihiro Shimoda 1190d0c5510SYoshihiro Shimoda /* 1200d0c5510SYoshihiro Shimoda * Enable LTSSM of this controller and manually initiate the speed change. 1210d0c5510SYoshihiro Shimoda * Always return 0. 1220d0c5510SYoshihiro Shimoda */ 1230d0c5510SYoshihiro Shimoda static int rcar_gen4_pcie_start_link(struct dw_pcie *dw) 1240d0c5510SYoshihiro Shimoda { 1250d0c5510SYoshihiro Shimoda struct rcar_gen4_pcie *rcar = to_rcar_gen4_pcie(dw); 1260d0c5510SYoshihiro Shimoda int i, changes; 1270d0c5510SYoshihiro Shimoda 1280d0c5510SYoshihiro Shimoda rcar_gen4_pcie_ltssm_enable(rcar, true); 1290d0c5510SYoshihiro Shimoda 1300d0c5510SYoshihiro Shimoda /* 1310d0c5510SYoshihiro Shimoda * Require direct speed change with retrying here if the link_gen is 1320d0c5510SYoshihiro Shimoda * PCIe Gen2 or higher. 1330d0c5510SYoshihiro Shimoda */ 1340d0c5510SYoshihiro Shimoda changes = min_not_zero(dw->link_gen, RCAR_MAX_LINK_SPEED) - 1; 1350d0c5510SYoshihiro Shimoda 1360d0c5510SYoshihiro Shimoda /* 1370d0c5510SYoshihiro Shimoda * Since dw_pcie_setup_rc() sets it once, PCIe Gen2 will be trained. 1380d0c5510SYoshihiro Shimoda * So, this needs remaining times for up to PCIe Gen4 if RC mode. 1390d0c5510SYoshihiro Shimoda */ 1400d0c5510SYoshihiro Shimoda if (changes && rcar->mode == DW_PCIE_RC_TYPE) 1410d0c5510SYoshihiro Shimoda changes--; 1420d0c5510SYoshihiro Shimoda 1430d0c5510SYoshihiro Shimoda for (i = 0; i < changes; i++) { 1440d0c5510SYoshihiro Shimoda /* It may not be connected in EP mode yet. So, break the loop */ 1450d0c5510SYoshihiro Shimoda if (rcar_gen4_pcie_speed_change(dw)) 1460d0c5510SYoshihiro Shimoda break; 1470d0c5510SYoshihiro Shimoda } 1480d0c5510SYoshihiro Shimoda 1490d0c5510SYoshihiro Shimoda return 0; 1500d0c5510SYoshihiro Shimoda } 1510d0c5510SYoshihiro Shimoda 1520d0c5510SYoshihiro Shimoda static void rcar_gen4_pcie_stop_link(struct dw_pcie *dw) 1530d0c5510SYoshihiro Shimoda { 1540d0c5510SYoshihiro Shimoda struct rcar_gen4_pcie *rcar = to_rcar_gen4_pcie(dw); 1550d0c5510SYoshihiro Shimoda 1560d0c5510SYoshihiro Shimoda rcar_gen4_pcie_ltssm_enable(rcar, false); 1570d0c5510SYoshihiro Shimoda } 1580d0c5510SYoshihiro Shimoda 1590d0c5510SYoshihiro Shimoda static int rcar_gen4_pcie_common_init(struct rcar_gen4_pcie *rcar) 1600d0c5510SYoshihiro Shimoda { 1610d0c5510SYoshihiro Shimoda struct dw_pcie *dw = &rcar->dw; 1620d0c5510SYoshihiro Shimoda u32 val; 1630d0c5510SYoshihiro Shimoda int ret; 1640d0c5510SYoshihiro Shimoda 1650d0c5510SYoshihiro Shimoda ret = clk_bulk_prepare_enable(DW_PCIE_NUM_CORE_CLKS, dw->core_clks); 1660d0c5510SYoshihiro Shimoda if (ret) { 1670d0c5510SYoshihiro Shimoda dev_err(dw->dev, "Enabling core clocks failed\n"); 1680d0c5510SYoshihiro Shimoda return ret; 1690d0c5510SYoshihiro Shimoda } 1700d0c5510SYoshihiro Shimoda 1710d0c5510SYoshihiro Shimoda if (!reset_control_status(dw->core_rsts[DW_PCIE_PWR_RST].rstc)) 1720d0c5510SYoshihiro Shimoda reset_control_assert(dw->core_rsts[DW_PCIE_PWR_RST].rstc); 1730d0c5510SYoshihiro Shimoda 1740d0c5510SYoshihiro Shimoda val = readl(rcar->base + PCIEMSR0); 1750d0c5510SYoshihiro Shimoda if (rcar->mode == DW_PCIE_RC_TYPE) { 1760d0c5510SYoshihiro Shimoda val |= DEVICE_TYPE_RC; 177e311b383SYoshihiro Shimoda } else if (rcar->mode == DW_PCIE_EP_TYPE) { 178e311b383SYoshihiro Shimoda val |= DEVICE_TYPE_EP; 1790d0c5510SYoshihiro Shimoda } else { 1800d0c5510SYoshihiro Shimoda ret = -EINVAL; 1810d0c5510SYoshihiro Shimoda goto err_unprepare; 1820d0c5510SYoshihiro Shimoda } 1830d0c5510SYoshihiro Shimoda 1840d0c5510SYoshihiro Shimoda if (dw->num_lanes < 4) 1850d0c5510SYoshihiro Shimoda val |= BIFUR_MOD_SET_ON; 1860d0c5510SYoshihiro Shimoda 1870d0c5510SYoshihiro Shimoda writel(val, rcar->base + PCIEMSR0); 1880d0c5510SYoshihiro Shimoda 1890d0c5510SYoshihiro Shimoda ret = reset_control_deassert(dw->core_rsts[DW_PCIE_PWR_RST].rstc); 1900d0c5510SYoshihiro Shimoda if (ret) 1910d0c5510SYoshihiro Shimoda goto err_unprepare; 1920d0c5510SYoshihiro Shimoda 1930d0c5510SYoshihiro Shimoda return 0; 1940d0c5510SYoshihiro Shimoda 1950d0c5510SYoshihiro Shimoda err_unprepare: 1960d0c5510SYoshihiro Shimoda clk_bulk_disable_unprepare(DW_PCIE_NUM_CORE_CLKS, dw->core_clks); 1970d0c5510SYoshihiro Shimoda 1980d0c5510SYoshihiro Shimoda return ret; 1990d0c5510SYoshihiro Shimoda } 2000d0c5510SYoshihiro Shimoda 2010d0c5510SYoshihiro Shimoda static void rcar_gen4_pcie_common_deinit(struct rcar_gen4_pcie *rcar) 2020d0c5510SYoshihiro Shimoda { 2030d0c5510SYoshihiro Shimoda struct dw_pcie *dw = &rcar->dw; 2040d0c5510SYoshihiro Shimoda 2050d0c5510SYoshihiro Shimoda reset_control_assert(dw->core_rsts[DW_PCIE_PWR_RST].rstc); 2060d0c5510SYoshihiro Shimoda clk_bulk_disable_unprepare(DW_PCIE_NUM_CORE_CLKS, dw->core_clks); 2070d0c5510SYoshihiro Shimoda } 2080d0c5510SYoshihiro Shimoda 2090d0c5510SYoshihiro Shimoda static int rcar_gen4_pcie_prepare(struct rcar_gen4_pcie *rcar) 2100d0c5510SYoshihiro Shimoda { 2110d0c5510SYoshihiro Shimoda struct device *dev = rcar->dw.dev; 2120d0c5510SYoshihiro Shimoda int err; 2130d0c5510SYoshihiro Shimoda 2140d0c5510SYoshihiro Shimoda pm_runtime_enable(dev); 2150d0c5510SYoshihiro Shimoda err = pm_runtime_resume_and_get(dev); 2160d0c5510SYoshihiro Shimoda if (err < 0) { 2170d0c5510SYoshihiro Shimoda dev_err(dev, "Runtime resume failed\n"); 2180d0c5510SYoshihiro Shimoda pm_runtime_disable(dev); 2190d0c5510SYoshihiro Shimoda } 2200d0c5510SYoshihiro Shimoda 2210d0c5510SYoshihiro Shimoda return err; 2220d0c5510SYoshihiro Shimoda } 2230d0c5510SYoshihiro Shimoda 2240d0c5510SYoshihiro Shimoda static void rcar_gen4_pcie_unprepare(struct rcar_gen4_pcie *rcar) 2250d0c5510SYoshihiro Shimoda { 2260d0c5510SYoshihiro Shimoda struct device *dev = rcar->dw.dev; 2270d0c5510SYoshihiro Shimoda 2280d0c5510SYoshihiro Shimoda pm_runtime_put(dev); 2290d0c5510SYoshihiro Shimoda pm_runtime_disable(dev); 2300d0c5510SYoshihiro Shimoda } 2310d0c5510SYoshihiro Shimoda 2320d0c5510SYoshihiro Shimoda static int rcar_gen4_pcie_get_resources(struct rcar_gen4_pcie *rcar) 2330d0c5510SYoshihiro Shimoda { 2340d0c5510SYoshihiro Shimoda /* Renesas-specific registers */ 2350d0c5510SYoshihiro Shimoda rcar->base = devm_platform_ioremap_resource_byname(rcar->pdev, "app"); 2360d0c5510SYoshihiro Shimoda 2370d0c5510SYoshihiro Shimoda return PTR_ERR_OR_ZERO(rcar->base); 2380d0c5510SYoshihiro Shimoda } 2390d0c5510SYoshihiro Shimoda 2400d0c5510SYoshihiro Shimoda static const struct dw_pcie_ops dw_pcie_ops = { 2410d0c5510SYoshihiro Shimoda .start_link = rcar_gen4_pcie_start_link, 2420d0c5510SYoshihiro Shimoda .stop_link = rcar_gen4_pcie_stop_link, 2430d0c5510SYoshihiro Shimoda .link_up = rcar_gen4_pcie_link_up, 2440d0c5510SYoshihiro Shimoda }; 2450d0c5510SYoshihiro Shimoda 2460d0c5510SYoshihiro Shimoda static struct rcar_gen4_pcie *rcar_gen4_pcie_alloc(struct platform_device *pdev) 2470d0c5510SYoshihiro Shimoda { 2480d0c5510SYoshihiro Shimoda struct device *dev = &pdev->dev; 2490d0c5510SYoshihiro Shimoda struct rcar_gen4_pcie *rcar; 2500d0c5510SYoshihiro Shimoda 2510d0c5510SYoshihiro Shimoda rcar = devm_kzalloc(dev, sizeof(*rcar), GFP_KERNEL); 2520d0c5510SYoshihiro Shimoda if (!rcar) 2530d0c5510SYoshihiro Shimoda return ERR_PTR(-ENOMEM); 2540d0c5510SYoshihiro Shimoda 2550d0c5510SYoshihiro Shimoda rcar->dw.ops = &dw_pcie_ops; 2560d0c5510SYoshihiro Shimoda rcar->dw.dev = dev; 2570d0c5510SYoshihiro Shimoda rcar->pdev = pdev; 258*0551abf2SManivannan Sadhasivam rcar->dw.edma.mf = EDMA_MF_EDMA_UNROLL; 2590d0c5510SYoshihiro Shimoda dw_pcie_cap_set(&rcar->dw, REQ_RES); 2600d0c5510SYoshihiro Shimoda platform_set_drvdata(pdev, rcar); 2610d0c5510SYoshihiro Shimoda 2620d0c5510SYoshihiro Shimoda return rcar; 2630d0c5510SYoshihiro Shimoda } 2640d0c5510SYoshihiro Shimoda 2650d0c5510SYoshihiro Shimoda /* Host mode */ 2660d0c5510SYoshihiro Shimoda static int rcar_gen4_pcie_host_init(struct dw_pcie_rp *pp) 2670d0c5510SYoshihiro Shimoda { 2680d0c5510SYoshihiro Shimoda struct dw_pcie *dw = to_dw_pcie_from_pp(pp); 2690d0c5510SYoshihiro Shimoda struct rcar_gen4_pcie *rcar = to_rcar_gen4_pcie(dw); 2700d0c5510SYoshihiro Shimoda int ret; 2710d0c5510SYoshihiro Shimoda u32 val; 2720d0c5510SYoshihiro Shimoda 2730d0c5510SYoshihiro Shimoda gpiod_set_value_cansleep(dw->pe_rst, 1); 2740d0c5510SYoshihiro Shimoda 2750d0c5510SYoshihiro Shimoda ret = rcar_gen4_pcie_common_init(rcar); 2760d0c5510SYoshihiro Shimoda if (ret) 2770d0c5510SYoshihiro Shimoda return ret; 2780d0c5510SYoshihiro Shimoda 2790d0c5510SYoshihiro Shimoda /* 2800d0c5510SYoshihiro Shimoda * According to the section 3.5.7.2 "RC Mode" in DWC PCIe Dual Mode 2810d0c5510SYoshihiro Shimoda * Rev.5.20a and 3.5.6.1 "RC mode" in DWC PCIe RC databook v5.20a, we 2820d0c5510SYoshihiro Shimoda * should disable two BARs to avoid unnecessary memory assignment 2830d0c5510SYoshihiro Shimoda * during device enumeration. 2840d0c5510SYoshihiro Shimoda */ 2850d0c5510SYoshihiro Shimoda dw_pcie_writel_dbi2(dw, PCI_BASE_ADDRESS_0, 0x0); 2860d0c5510SYoshihiro Shimoda dw_pcie_writel_dbi2(dw, PCI_BASE_ADDRESS_1, 0x0); 2870d0c5510SYoshihiro Shimoda 2880d0c5510SYoshihiro Shimoda /* Enable MSI interrupt signal */ 2890d0c5510SYoshihiro Shimoda val = readl(rcar->base + PCIEINTSTS0EN); 2900d0c5510SYoshihiro Shimoda val |= MSI_CTRL_INT; 2910d0c5510SYoshihiro Shimoda writel(val, rcar->base + PCIEINTSTS0EN); 2920d0c5510SYoshihiro Shimoda 2930d0c5510SYoshihiro Shimoda msleep(PCIE_T_PVPERL_MS); /* pe_rst requires 100msec delay */ 2940d0c5510SYoshihiro Shimoda 2950d0c5510SYoshihiro Shimoda gpiod_set_value_cansleep(dw->pe_rst, 0); 2960d0c5510SYoshihiro Shimoda 2970d0c5510SYoshihiro Shimoda return 0; 2980d0c5510SYoshihiro Shimoda } 2990d0c5510SYoshihiro Shimoda 3000d0c5510SYoshihiro Shimoda static void rcar_gen4_pcie_host_deinit(struct dw_pcie_rp *pp) 3010d0c5510SYoshihiro Shimoda { 3020d0c5510SYoshihiro Shimoda struct dw_pcie *dw = to_dw_pcie_from_pp(pp); 3030d0c5510SYoshihiro Shimoda struct rcar_gen4_pcie *rcar = to_rcar_gen4_pcie(dw); 3040d0c5510SYoshihiro Shimoda 3050d0c5510SYoshihiro Shimoda gpiod_set_value_cansleep(dw->pe_rst, 1); 3060d0c5510SYoshihiro Shimoda rcar_gen4_pcie_common_deinit(rcar); 3070d0c5510SYoshihiro Shimoda } 3080d0c5510SYoshihiro Shimoda 3090d0c5510SYoshihiro Shimoda static const struct dw_pcie_host_ops rcar_gen4_pcie_host_ops = { 310aea370b2SYoshihiro Shimoda .init = rcar_gen4_pcie_host_init, 311aea370b2SYoshihiro Shimoda .deinit = rcar_gen4_pcie_host_deinit, 3120d0c5510SYoshihiro Shimoda }; 3130d0c5510SYoshihiro Shimoda 3140d0c5510SYoshihiro Shimoda static int rcar_gen4_add_dw_pcie_rp(struct rcar_gen4_pcie *rcar) 3150d0c5510SYoshihiro Shimoda { 3160d0c5510SYoshihiro Shimoda struct dw_pcie_rp *pp = &rcar->dw.pp; 3170d0c5510SYoshihiro Shimoda 318e311b383SYoshihiro Shimoda if (!IS_ENABLED(CONFIG_PCIE_RCAR_GEN4_HOST)) 319e311b383SYoshihiro Shimoda return -ENODEV; 320e311b383SYoshihiro Shimoda 3210d0c5510SYoshihiro Shimoda pp->num_vectors = MAX_MSI_IRQS; 3220d0c5510SYoshihiro Shimoda pp->ops = &rcar_gen4_pcie_host_ops; 3230d0c5510SYoshihiro Shimoda 3240d0c5510SYoshihiro Shimoda return dw_pcie_host_init(pp); 3250d0c5510SYoshihiro Shimoda } 3260d0c5510SYoshihiro Shimoda 3270d0c5510SYoshihiro Shimoda static void rcar_gen4_remove_dw_pcie_rp(struct rcar_gen4_pcie *rcar) 3280d0c5510SYoshihiro Shimoda { 3290d0c5510SYoshihiro Shimoda dw_pcie_host_deinit(&rcar->dw.pp); 3300d0c5510SYoshihiro Shimoda } 3310d0c5510SYoshihiro Shimoda 332e311b383SYoshihiro Shimoda /* Endpoint mode */ 333e311b383SYoshihiro Shimoda static void rcar_gen4_pcie_ep_pre_init(struct dw_pcie_ep *ep) 334e311b383SYoshihiro Shimoda { 335e311b383SYoshihiro Shimoda struct dw_pcie *dw = to_dw_pcie_from_ep(ep); 336e311b383SYoshihiro Shimoda struct rcar_gen4_pcie *rcar = to_rcar_gen4_pcie(dw); 337e311b383SYoshihiro Shimoda int ret; 338e311b383SYoshihiro Shimoda 339e311b383SYoshihiro Shimoda ret = rcar_gen4_pcie_common_init(rcar); 340e311b383SYoshihiro Shimoda if (ret) 341e311b383SYoshihiro Shimoda return; 342e311b383SYoshihiro Shimoda 343e311b383SYoshihiro Shimoda writel(PCIEDMAINTSTSEN_INIT, rcar->base + PCIEDMAINTSTSEN); 344e311b383SYoshihiro Shimoda } 345e311b383SYoshihiro Shimoda 346e311b383SYoshihiro Shimoda static void rcar_gen4_pcie_ep_init(struct dw_pcie_ep *ep) 347e311b383SYoshihiro Shimoda { 348e311b383SYoshihiro Shimoda struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 349e311b383SYoshihiro Shimoda enum pci_barno bar; 350e311b383SYoshihiro Shimoda 351e311b383SYoshihiro Shimoda for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) 352e311b383SYoshihiro Shimoda dw_pcie_ep_reset_bar(pci, bar); 353e311b383SYoshihiro Shimoda } 354e311b383SYoshihiro Shimoda 355b7dec6b8SManivannan Sadhasivam static void rcar_gen4_pcie_ep_deinit(struct rcar_gen4_pcie *rcar) 356e311b383SYoshihiro Shimoda { 357e311b383SYoshihiro Shimoda writel(0, rcar->base + PCIEDMAINTSTSEN); 358e311b383SYoshihiro Shimoda rcar_gen4_pcie_common_deinit(rcar); 359e311b383SYoshihiro Shimoda } 360e311b383SYoshihiro Shimoda 361e311b383SYoshihiro Shimoda static int rcar_gen4_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no, 36274955cb8SDamien Le Moal unsigned int type, u16 interrupt_num) 363e311b383SYoshihiro Shimoda { 364e311b383SYoshihiro Shimoda struct dw_pcie *dw = to_dw_pcie_from_ep(ep); 365e311b383SYoshihiro Shimoda 366e311b383SYoshihiro Shimoda switch (type) { 36774955cb8SDamien Le Moal case PCI_IRQ_INTX: 368e9af4800SDamien Le Moal return dw_pcie_ep_raise_intx_irq(ep, func_no); 36974955cb8SDamien Le Moal case PCI_IRQ_MSI: 370e311b383SYoshihiro Shimoda return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num); 371e311b383SYoshihiro Shimoda default: 372e311b383SYoshihiro Shimoda dev_err(dw->dev, "Unknown IRQ type\n"); 373e311b383SYoshihiro Shimoda return -EINVAL; 374e311b383SYoshihiro Shimoda } 375e311b383SYoshihiro Shimoda 376e311b383SYoshihiro Shimoda return 0; 377e311b383SYoshihiro Shimoda } 378e311b383SYoshihiro Shimoda 379e311b383SYoshihiro Shimoda static const struct pci_epc_features rcar_gen4_pcie_epc_features = { 380e311b383SYoshihiro Shimoda .linkup_notifier = false, 381e311b383SYoshihiro Shimoda .msi_capable = true, 382e311b383SYoshihiro Shimoda .msix_capable = false, 383e01c9797SNiklas Cassel .bar[BAR_1] = { .type = BAR_RESERVED, }, 384e01c9797SNiklas Cassel .bar[BAR_3] = { .type = BAR_RESERVED, }, 385e01c9797SNiklas Cassel .bar[BAR_5] = { .type = BAR_RESERVED, }, 386e311b383SYoshihiro Shimoda .align = SZ_1M, 387e311b383SYoshihiro Shimoda }; 388e311b383SYoshihiro Shimoda 389e311b383SYoshihiro Shimoda static const struct pci_epc_features* 390e311b383SYoshihiro Shimoda rcar_gen4_pcie_ep_get_features(struct dw_pcie_ep *ep) 391e311b383SYoshihiro Shimoda { 392e311b383SYoshihiro Shimoda return &rcar_gen4_pcie_epc_features; 393e311b383SYoshihiro Shimoda } 394e311b383SYoshihiro Shimoda 395641f79beSYoshihiro Shimoda static unsigned int rcar_gen4_pcie_ep_get_dbi_offset(struct dw_pcie_ep *ep, 396e311b383SYoshihiro Shimoda u8 func_no) 397e311b383SYoshihiro Shimoda { 398e311b383SYoshihiro Shimoda return func_no * RCAR_GEN4_PCIE_EP_FUNC_DBI_OFFSET; 399e311b383SYoshihiro Shimoda } 400e311b383SYoshihiro Shimoda 401e311b383SYoshihiro Shimoda static unsigned int rcar_gen4_pcie_ep_get_dbi2_offset(struct dw_pcie_ep *ep, 402e311b383SYoshihiro Shimoda u8 func_no) 403e311b383SYoshihiro Shimoda { 404e311b383SYoshihiro Shimoda return func_no * RCAR_GEN4_PCIE_EP_FUNC_DBI2_OFFSET; 405e311b383SYoshihiro Shimoda } 406e311b383SYoshihiro Shimoda 407e311b383SYoshihiro Shimoda static const struct dw_pcie_ep_ops pcie_ep_ops = { 408e311b383SYoshihiro Shimoda .pre_init = rcar_gen4_pcie_ep_pre_init, 409756dcb5aSYoshihiro Shimoda .init = rcar_gen4_pcie_ep_init, 410e311b383SYoshihiro Shimoda .raise_irq = rcar_gen4_pcie_ep_raise_irq, 411e311b383SYoshihiro Shimoda .get_features = rcar_gen4_pcie_ep_get_features, 412641f79beSYoshihiro Shimoda .get_dbi_offset = rcar_gen4_pcie_ep_get_dbi_offset, 413e311b383SYoshihiro Shimoda .get_dbi2_offset = rcar_gen4_pcie_ep_get_dbi2_offset, 414e311b383SYoshihiro Shimoda }; 415e311b383SYoshihiro Shimoda 416e311b383SYoshihiro Shimoda static int rcar_gen4_add_dw_pcie_ep(struct rcar_gen4_pcie *rcar) 417e311b383SYoshihiro Shimoda { 418e311b383SYoshihiro Shimoda struct dw_pcie_ep *ep = &rcar->dw.ep; 419df69e17cSManivannan Sadhasivam struct device *dev = rcar->dw.dev; 420b7dec6b8SManivannan Sadhasivam int ret; 421e311b383SYoshihiro Shimoda 422e311b383SYoshihiro Shimoda if (!IS_ENABLED(CONFIG_PCIE_RCAR_GEN4_EP)) 423e311b383SYoshihiro Shimoda return -ENODEV; 424e311b383SYoshihiro Shimoda 425e311b383SYoshihiro Shimoda ep->ops = &pcie_ep_ops; 426e311b383SYoshihiro Shimoda 427b7dec6b8SManivannan Sadhasivam ret = dw_pcie_ep_init(ep); 428df69e17cSManivannan Sadhasivam if (ret) { 429b7dec6b8SManivannan Sadhasivam rcar_gen4_pcie_ep_deinit(rcar); 430df69e17cSManivannan Sadhasivam return ret; 431df69e17cSManivannan Sadhasivam } 432df69e17cSManivannan Sadhasivam 433df69e17cSManivannan Sadhasivam ret = dw_pcie_ep_init_registers(ep); 434df69e17cSManivannan Sadhasivam if (ret) { 435df69e17cSManivannan Sadhasivam dev_err(dev, "Failed to initialize DWC endpoint registers\n"); 436df69e17cSManivannan Sadhasivam dw_pcie_ep_deinit(ep); 437df69e17cSManivannan Sadhasivam rcar_gen4_pcie_ep_deinit(rcar); 438df69e17cSManivannan Sadhasivam } 439b7dec6b8SManivannan Sadhasivam 440a01e7214SManivannan Sadhasivam dw_pcie_ep_init_notify(ep); 441a01e7214SManivannan Sadhasivam 442b7dec6b8SManivannan Sadhasivam return ret; 443e311b383SYoshihiro Shimoda } 444e311b383SYoshihiro Shimoda 445e311b383SYoshihiro Shimoda static void rcar_gen4_remove_dw_pcie_ep(struct rcar_gen4_pcie *rcar) 446e311b383SYoshihiro Shimoda { 447c8682a33SManivannan Sadhasivam dw_pcie_ep_deinit(&rcar->dw.ep); 448b7dec6b8SManivannan Sadhasivam rcar_gen4_pcie_ep_deinit(rcar); 449e311b383SYoshihiro Shimoda } 450e311b383SYoshihiro Shimoda 451e311b383SYoshihiro Shimoda /* Common */ 452e311b383SYoshihiro Shimoda static int rcar_gen4_add_dw_pcie(struct rcar_gen4_pcie *rcar) 453e311b383SYoshihiro Shimoda { 4547682f19cSYoshihiro Shimoda rcar->mode = (uintptr_t)of_device_get_match_data(&rcar->pdev->dev); 455e311b383SYoshihiro Shimoda 456e311b383SYoshihiro Shimoda switch (rcar->mode) { 457e311b383SYoshihiro Shimoda case DW_PCIE_RC_TYPE: 458e311b383SYoshihiro Shimoda return rcar_gen4_add_dw_pcie_rp(rcar); 459e311b383SYoshihiro Shimoda case DW_PCIE_EP_TYPE: 460e311b383SYoshihiro Shimoda return rcar_gen4_add_dw_pcie_ep(rcar); 461e311b383SYoshihiro Shimoda default: 462e311b383SYoshihiro Shimoda return -EINVAL; 463e311b383SYoshihiro Shimoda } 464e311b383SYoshihiro Shimoda } 465e311b383SYoshihiro Shimoda 4660d0c5510SYoshihiro Shimoda static int rcar_gen4_pcie_probe(struct platform_device *pdev) 4670d0c5510SYoshihiro Shimoda { 4680d0c5510SYoshihiro Shimoda struct rcar_gen4_pcie *rcar; 4690d0c5510SYoshihiro Shimoda int err; 4700d0c5510SYoshihiro Shimoda 4710d0c5510SYoshihiro Shimoda rcar = rcar_gen4_pcie_alloc(pdev); 4720d0c5510SYoshihiro Shimoda if (IS_ERR(rcar)) 4730d0c5510SYoshihiro Shimoda return PTR_ERR(rcar); 4740d0c5510SYoshihiro Shimoda 4750d0c5510SYoshihiro Shimoda err = rcar_gen4_pcie_get_resources(rcar); 4760d0c5510SYoshihiro Shimoda if (err) 4770d0c5510SYoshihiro Shimoda return err; 4780d0c5510SYoshihiro Shimoda 4790d0c5510SYoshihiro Shimoda err = rcar_gen4_pcie_prepare(rcar); 4800d0c5510SYoshihiro Shimoda if (err) 4810d0c5510SYoshihiro Shimoda return err; 4820d0c5510SYoshihiro Shimoda 483e311b383SYoshihiro Shimoda err = rcar_gen4_add_dw_pcie(rcar); 4840d0c5510SYoshihiro Shimoda if (err) 4850d0c5510SYoshihiro Shimoda goto err_unprepare; 4860d0c5510SYoshihiro Shimoda 4870d0c5510SYoshihiro Shimoda return 0; 4880d0c5510SYoshihiro Shimoda 4890d0c5510SYoshihiro Shimoda err_unprepare: 4900d0c5510SYoshihiro Shimoda rcar_gen4_pcie_unprepare(rcar); 4910d0c5510SYoshihiro Shimoda 4920d0c5510SYoshihiro Shimoda return err; 4930d0c5510SYoshihiro Shimoda } 4940d0c5510SYoshihiro Shimoda 495e311b383SYoshihiro Shimoda static void rcar_gen4_remove_dw_pcie(struct rcar_gen4_pcie *rcar) 496e311b383SYoshihiro Shimoda { 497e311b383SYoshihiro Shimoda switch (rcar->mode) { 498e311b383SYoshihiro Shimoda case DW_PCIE_RC_TYPE: 499e311b383SYoshihiro Shimoda rcar_gen4_remove_dw_pcie_rp(rcar); 500e311b383SYoshihiro Shimoda break; 501e311b383SYoshihiro Shimoda case DW_PCIE_EP_TYPE: 502e311b383SYoshihiro Shimoda rcar_gen4_remove_dw_pcie_ep(rcar); 503e311b383SYoshihiro Shimoda break; 504e311b383SYoshihiro Shimoda default: 505e311b383SYoshihiro Shimoda break; 506e311b383SYoshihiro Shimoda } 507e311b383SYoshihiro Shimoda } 508e311b383SYoshihiro Shimoda 5090d0c5510SYoshihiro Shimoda static void rcar_gen4_pcie_remove(struct platform_device *pdev) 5100d0c5510SYoshihiro Shimoda { 5110d0c5510SYoshihiro Shimoda struct rcar_gen4_pcie *rcar = platform_get_drvdata(pdev); 5120d0c5510SYoshihiro Shimoda 513e311b383SYoshihiro Shimoda rcar_gen4_remove_dw_pcie(rcar); 5140d0c5510SYoshihiro Shimoda rcar_gen4_pcie_unprepare(rcar); 5150d0c5510SYoshihiro Shimoda } 5160d0c5510SYoshihiro Shimoda 5170d0c5510SYoshihiro Shimoda static const struct of_device_id rcar_gen4_pcie_of_match[] = { 518e311b383SYoshihiro Shimoda { 519e311b383SYoshihiro Shimoda .compatible = "renesas,rcar-gen4-pcie", 520e311b383SYoshihiro Shimoda .data = (void *)DW_PCIE_RC_TYPE, 521e311b383SYoshihiro Shimoda }, 522e311b383SYoshihiro Shimoda { 523e311b383SYoshihiro Shimoda .compatible = "renesas,rcar-gen4-pcie-ep", 524e311b383SYoshihiro Shimoda .data = (void *)DW_PCIE_EP_TYPE, 525e311b383SYoshihiro Shimoda }, 5260d0c5510SYoshihiro Shimoda {}, 5270d0c5510SYoshihiro Shimoda }; 5280d0c5510SYoshihiro Shimoda MODULE_DEVICE_TABLE(of, rcar_gen4_pcie_of_match); 5290d0c5510SYoshihiro Shimoda 5300d0c5510SYoshihiro Shimoda static struct platform_driver rcar_gen4_pcie_driver = { 5310d0c5510SYoshihiro Shimoda .driver = { 5320d0c5510SYoshihiro Shimoda .name = "pcie-rcar-gen4", 5330d0c5510SYoshihiro Shimoda .of_match_table = rcar_gen4_pcie_of_match, 5340d0c5510SYoshihiro Shimoda .probe_type = PROBE_PREFER_ASYNCHRONOUS, 5350d0c5510SYoshihiro Shimoda }, 5360d0c5510SYoshihiro Shimoda .probe = rcar_gen4_pcie_probe, 5370d0c5510SYoshihiro Shimoda .remove_new = rcar_gen4_pcie_remove, 5380d0c5510SYoshihiro Shimoda }; 5390d0c5510SYoshihiro Shimoda module_platform_driver(rcar_gen4_pcie_driver); 5400d0c5510SYoshihiro Shimoda 5410d0c5510SYoshihiro Shimoda MODULE_DESCRIPTION("Renesas R-Car Gen4 PCIe controller driver"); 5420d0c5510SYoshihiro Shimoda MODULE_LICENSE("GPL"); 543