cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

pcie-visconti.c (8928B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * DWC PCIe RC driver for Toshiba Visconti ARM SoC
      4 *
      5 * Copyright (C) 2021 Toshiba Electronic Device & Storage Corporation
      6 * Copyright (C) 2021 TOSHIBA CORPORATION
      7 *
      8 * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
      9 */
     10
     11#include <linux/clk.h>
     12#include <linux/delay.h>
     13#include <linux/gpio.h>
     14#include <linux/interrupt.h>
     15#include <linux/init.h>
     16#include <linux/iopoll.h>
     17#include <linux/kernel.h>
     18#include <linux/of_platform.h>
     19#include <linux/pci.h>
     20#include <linux/platform_device.h>
     21#include <linux/resource.h>
     22#include <linux/types.h>
     23
     24#include "pcie-designware.h"
     25#include "../../pci.h"
     26
     27struct visconti_pcie {
     28	struct dw_pcie pci;
     29	void __iomem *ulreg_base;
     30	void __iomem *smu_base;
     31	void __iomem *mpu_base;
     32	struct clk *refclk;
     33	struct clk *coreclk;
     34	struct clk *auxclk;
     35};
     36
     37#define PCIE_UL_REG_S_PCIE_MODE		0x00F4
     38#define  PCIE_UL_REG_S_PCIE_MODE_EP	0x00
     39#define  PCIE_UL_REG_S_PCIE_MODE_RC	0x04
     40
     41#define PCIE_UL_REG_S_PERSTN_CTRL	0x00F8
     42#define  PCIE_UL_IOM_PCIE_PERSTN_I_EN	BIT(3)
     43#define  PCIE_UL_DIRECT_PERSTN_EN	BIT(2)
     44#define  PCIE_UL_PERSTN_OUT		BIT(1)
     45#define  PCIE_UL_DIRECT_PERSTN		BIT(0)
     46#define  PCIE_UL_REG_S_PERSTN_CTRL_INIT	(PCIE_UL_IOM_PCIE_PERSTN_I_EN | \
     47					 PCIE_UL_DIRECT_PERSTN_EN | \
     48					 PCIE_UL_DIRECT_PERSTN)
     49
     50#define PCIE_UL_REG_S_PHY_INIT_02	0x0104
     51#define  PCIE_UL_PHY0_SRAM_EXT_LD_DONE	BIT(0)
     52
     53#define PCIE_UL_REG_S_PHY_INIT_03	0x0108
     54#define  PCIE_UL_PHY0_SRAM_INIT_DONE	BIT(0)
     55
     56#define PCIE_UL_REG_S_INT_EVENT_MASK1	0x0138
     57#define  PCIE_UL_CFG_PME_INT		BIT(0)
     58#define  PCIE_UL_CFG_LINK_EQ_REQ_INT	BIT(1)
     59#define  PCIE_UL_EDMA_INT0		BIT(2)
     60#define  PCIE_UL_EDMA_INT1		BIT(3)
     61#define  PCIE_UL_EDMA_INT2		BIT(4)
     62#define  PCIE_UL_EDMA_INT3		BIT(5)
     63#define  PCIE_UL_S_INT_EVENT_MASK1_ALL  (PCIE_UL_CFG_PME_INT | \
     64					 PCIE_UL_CFG_LINK_EQ_REQ_INT | \
     65					 PCIE_UL_EDMA_INT0 | \
     66					 PCIE_UL_EDMA_INT1 | \
     67					 PCIE_UL_EDMA_INT2 | \
     68					 PCIE_UL_EDMA_INT3)
     69
     70#define PCIE_UL_REG_S_SB_MON		0x0198
     71#define PCIE_UL_REG_S_SIG_MON		0x019C
     72#define  PCIE_UL_CORE_RST_N_MON		BIT(0)
     73
     74#define PCIE_UL_REG_V_SII_DBG_00	0x0844
     75#define PCIE_UL_REG_V_SII_GEN_CTRL_01	0x0860
     76#define  PCIE_UL_APP_LTSSM_ENABLE	BIT(0)
     77
     78#define PCIE_UL_REG_V_PHY_ST_00		0x0864
     79#define  PCIE_UL_SMLH_LINK_UP		BIT(0)
     80
     81#define PCIE_UL_REG_V_PHY_ST_02		0x0868
     82#define  PCIE_UL_S_DETECT_ACT		0x01
     83#define  PCIE_UL_S_L0			0x11
     84
     85#define PISMU_CKON_PCIE			0x0038
     86#define  PISMU_CKON_PCIE_AUX_CLK	BIT(1)
     87#define  PISMU_CKON_PCIE_MSTR_ACLK	BIT(0)
     88
     89#define PISMU_RSOFF_PCIE		0x0538
     90#define  PISMU_RSOFF_PCIE_ULREG_RST_N	BIT(1)
     91#define  PISMU_RSOFF_PCIE_PWR_UP_RST_N	BIT(0)
     92
     93#define PCIE_MPU_REG_MP_EN		0x0
     94#define  MPU_MP_EN_DISABLE		BIT(0)
     95
     96/* Access registers in PCIe ulreg */
     97static void visconti_ulreg_writel(struct visconti_pcie *pcie, u32 val, u32 reg)
     98{
     99	writel_relaxed(val, pcie->ulreg_base + reg);
    100}
    101
    102static u32 visconti_ulreg_readl(struct visconti_pcie *pcie, u32 reg)
    103{
    104	return readl_relaxed(pcie->ulreg_base + reg);
    105}
    106
    107/* Access registers in PCIe smu */
    108static void visconti_smu_writel(struct visconti_pcie *pcie, u32 val, u32 reg)
    109{
    110	writel_relaxed(val, pcie->smu_base + reg);
    111}
    112
    113/* Access registers in PCIe mpu */
    114static void visconti_mpu_writel(struct visconti_pcie *pcie, u32 val, u32 reg)
    115{
    116	writel_relaxed(val, pcie->mpu_base + reg);
    117}
    118
    119static u32 visconti_mpu_readl(struct visconti_pcie *pcie, u32 reg)
    120{
    121	return readl_relaxed(pcie->mpu_base + reg);
    122}
    123
    124static int visconti_pcie_link_up(struct dw_pcie *pci)
    125{
    126	struct visconti_pcie *pcie = dev_get_drvdata(pci->dev);
    127	void __iomem *addr = pcie->ulreg_base;
    128	u32 val = readl_relaxed(addr + PCIE_UL_REG_V_PHY_ST_02);
    129
    130	return !!(val & PCIE_UL_S_L0);
    131}
    132
    133static int visconti_pcie_start_link(struct dw_pcie *pci)
    134{
    135	struct visconti_pcie *pcie = dev_get_drvdata(pci->dev);
    136	void __iomem *addr = pcie->ulreg_base;
    137	u32 val;
    138	int ret;
    139
    140	visconti_ulreg_writel(pcie, PCIE_UL_APP_LTSSM_ENABLE,
    141			      PCIE_UL_REG_V_SII_GEN_CTRL_01);
    142
    143	ret = readl_relaxed_poll_timeout(addr + PCIE_UL_REG_V_PHY_ST_02,
    144					 val, (val & PCIE_UL_S_L0),
    145					 90000, 100000);
    146	if (ret)
    147		return ret;
    148
    149	visconti_ulreg_writel(pcie, PCIE_UL_S_INT_EVENT_MASK1_ALL,
    150			      PCIE_UL_REG_S_INT_EVENT_MASK1);
    151
    152	if (dw_pcie_link_up(pci)) {
    153		val = visconti_mpu_readl(pcie, PCIE_MPU_REG_MP_EN);
    154		visconti_mpu_writel(pcie, val & ~MPU_MP_EN_DISABLE,
    155				    PCIE_MPU_REG_MP_EN);
    156	}
    157
    158	return 0;
    159}
    160
    161static void visconti_pcie_stop_link(struct dw_pcie *pci)
    162{
    163	struct visconti_pcie *pcie = dev_get_drvdata(pci->dev);
    164	u32 val;
    165
    166	val = visconti_ulreg_readl(pcie, PCIE_UL_REG_V_SII_GEN_CTRL_01);
    167	val &= ~PCIE_UL_APP_LTSSM_ENABLE;
    168	visconti_ulreg_writel(pcie, val, PCIE_UL_REG_V_SII_GEN_CTRL_01);
    169
    170	val = visconti_mpu_readl(pcie, PCIE_MPU_REG_MP_EN);
    171	visconti_mpu_writel(pcie, val | MPU_MP_EN_DISABLE, PCIE_MPU_REG_MP_EN);
    172}
    173
    174/*
    175 * In this SoC specification, the CPU bus outputs the offset value from
    176 * 0x40000000 to the PCIe bus, so 0x40000000 is subtracted from the CPU
    177 * bus address. This 0x40000000 is also based on io_base from DT.
    178 */
    179static u64 visconti_pcie_cpu_addr_fixup(struct dw_pcie *pci, u64 cpu_addr)
    180{
    181	struct pcie_port *pp = &pci->pp;
    182
    183	return cpu_addr & ~pp->io_base;
    184}
    185
    186static const struct dw_pcie_ops dw_pcie_ops = {
    187	.cpu_addr_fixup = visconti_pcie_cpu_addr_fixup,
    188	.link_up = visconti_pcie_link_up,
    189	.start_link = visconti_pcie_start_link,
    190	.stop_link = visconti_pcie_stop_link,
    191};
    192
    193static int visconti_pcie_host_init(struct pcie_port *pp)
    194{
    195	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
    196	struct visconti_pcie *pcie = dev_get_drvdata(pci->dev);
    197	void __iomem *addr;
    198	int err;
    199	u32 val;
    200
    201	visconti_smu_writel(pcie,
    202			    PISMU_CKON_PCIE_AUX_CLK | PISMU_CKON_PCIE_MSTR_ACLK,
    203			    PISMU_CKON_PCIE);
    204	ndelay(250);
    205
    206	visconti_smu_writel(pcie, PISMU_RSOFF_PCIE_ULREG_RST_N,
    207			    PISMU_RSOFF_PCIE);
    208	visconti_ulreg_writel(pcie, PCIE_UL_REG_S_PCIE_MODE_RC,
    209			      PCIE_UL_REG_S_PCIE_MODE);
    210
    211	val = PCIE_UL_REG_S_PERSTN_CTRL_INIT;
    212	visconti_ulreg_writel(pcie, val, PCIE_UL_REG_S_PERSTN_CTRL);
    213	udelay(100);
    214
    215	val |= PCIE_UL_PERSTN_OUT;
    216	visconti_ulreg_writel(pcie, val, PCIE_UL_REG_S_PERSTN_CTRL);
    217	udelay(100);
    218
    219	visconti_smu_writel(pcie, PISMU_RSOFF_PCIE_PWR_UP_RST_N,
    220			    PISMU_RSOFF_PCIE);
    221
    222	addr = pcie->ulreg_base + PCIE_UL_REG_S_PHY_INIT_03;
    223	err = readl_relaxed_poll_timeout(addr, val,
    224					 (val & PCIE_UL_PHY0_SRAM_INIT_DONE),
    225					 100, 1000);
    226	if (err)
    227		return err;
    228
    229	visconti_ulreg_writel(pcie, PCIE_UL_PHY0_SRAM_EXT_LD_DONE,
    230			      PCIE_UL_REG_S_PHY_INIT_02);
    231
    232	addr = pcie->ulreg_base + PCIE_UL_REG_S_SIG_MON;
    233	return readl_relaxed_poll_timeout(addr, val,
    234					  (val & PCIE_UL_CORE_RST_N_MON), 100,
    235					  1000);
    236}
    237
    238static const struct dw_pcie_host_ops visconti_pcie_host_ops = {
    239	.host_init = visconti_pcie_host_init,
    240};
    241
    242static int visconti_get_resources(struct platform_device *pdev,
    243				  struct visconti_pcie *pcie)
    244{
    245	struct device *dev = &pdev->dev;
    246
    247	pcie->ulreg_base = devm_platform_ioremap_resource_byname(pdev, "ulreg");
    248	if (IS_ERR(pcie->ulreg_base))
    249		return PTR_ERR(pcie->ulreg_base);
    250
    251	pcie->smu_base = devm_platform_ioremap_resource_byname(pdev, "smu");
    252	if (IS_ERR(pcie->smu_base))
    253		return PTR_ERR(pcie->smu_base);
    254
    255	pcie->mpu_base = devm_platform_ioremap_resource_byname(pdev, "mpu");
    256	if (IS_ERR(pcie->mpu_base))
    257		return PTR_ERR(pcie->mpu_base);
    258
    259	pcie->refclk = devm_clk_get(dev, "ref");
    260	if (IS_ERR(pcie->refclk))
    261		return dev_err_probe(dev, PTR_ERR(pcie->refclk),
    262				     "Failed to get ref clock\n");
    263
    264	pcie->coreclk = devm_clk_get(dev, "core");
    265	if (IS_ERR(pcie->coreclk))
    266		return dev_err_probe(dev, PTR_ERR(pcie->coreclk),
    267				     "Failed to get core clock\n");
    268
    269	pcie->auxclk = devm_clk_get(dev, "aux");
    270	if (IS_ERR(pcie->auxclk))
    271		return dev_err_probe(dev, PTR_ERR(pcie->auxclk),
    272				     "Failed to get aux clock\n");
    273
    274	return 0;
    275}
    276
    277static int visconti_add_pcie_port(struct visconti_pcie *pcie,
    278				  struct platform_device *pdev)
    279{
    280	struct dw_pcie *pci = &pcie->pci;
    281	struct pcie_port *pp = &pci->pp;
    282
    283	pp->irq = platform_get_irq_byname(pdev, "intr");
    284	if (pp->irq < 0)
    285		return pp->irq;
    286
    287	pp->ops = &visconti_pcie_host_ops;
    288
    289	return dw_pcie_host_init(pp);
    290}
    291
    292static int visconti_pcie_probe(struct platform_device *pdev)
    293{
    294	struct device *dev = &pdev->dev;
    295	struct visconti_pcie *pcie;
    296	struct dw_pcie *pci;
    297	int ret;
    298
    299	pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
    300	if (!pcie)
    301		return -ENOMEM;
    302
    303	pci = &pcie->pci;
    304	pci->dev = dev;
    305	pci->ops = &dw_pcie_ops;
    306
    307	ret = visconti_get_resources(pdev, pcie);
    308	if (ret)
    309		return ret;
    310
    311	platform_set_drvdata(pdev, pcie);
    312
    313	return visconti_add_pcie_port(pcie, pdev);
    314}
    315
    316static const struct of_device_id visconti_pcie_match[] = {
    317	{ .compatible = "toshiba,visconti-pcie" },
    318	{},
    319};
    320
    321static struct platform_driver visconti_pcie_driver = {
    322	.probe = visconti_pcie_probe,
    323	.driver = {
    324		.name = "visconti-pcie",
    325		.of_match_table = visconti_pcie_match,
    326		.suppress_bind_attrs = true,
    327	},
    328};
    329builtin_platform_driver(visconti_pcie_driver);