From: Daniel Golle Date: Sun, 3 Mar 2019 19:34:15 +0000 (+0100) Subject: oxnas: cleanup and improve pcie driver X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=dcb08049ae1128c989f0cd5ecebaa9e31b19614f;p=openwrt%2Fstaging%2Fnbd.git oxnas: cleanup and improve pcie driver Signed-off-by: Daniel Golle --- diff --git a/target/linux/oxnas/files/drivers/pci/host/pcie-oxnas.c b/target/linux/oxnas/files/drivers/pci/host/pcie-oxnas.c index 7cf3ad1670..d69820d2aa 100644 --- a/target/linux/oxnas/files/drivers/pci/host/pcie-oxnas.c +++ b/target/linux/oxnas/files/drivers/pci/host/pcie-oxnas.c @@ -11,263 +11,24 @@ #include #include #include +#include #include #include #include -#include +#include +#include #include +#include #include -#include #include #include #include +#include #include #include #include -#define OXNAS_UART1_BASE 0x44200000 -#define OXNAS_UART1_SIZE SZ_32 -#define OXNAS_UART1_BASE_VA 0xF0000000 - -#define OXNAS_UART2_BASE 0x44300000 -#define OXNAS_UART2_SIZE SZ_32 - -#define OXNAS_PERCPU_BASE 0x47000000 -#define OXNAS_PERCPU_SIZE SZ_8K -#define OXNAS_PERCPU_BASE_VA 0xF0002000 - -#define OXNAS_SYSCRTL_BASE 0x44E00000 -#define OXNAS_SYSCRTL_SIZE SZ_4K -#define OXNAS_SYSCRTL_BASE_VA 0xF0004000 - -#define OXNAS_SECCRTL_BASE 0x44F00000 -#define OXNAS_SECCRTL_SIZE SZ_4K -#define OXNAS_SECCRTL_BASE_VA 0xF0005000 - -#define OXNAS_RPSA_BASE 0x44400000 -#define OXNAS_RPSA_SIZE SZ_4K -#define OXNAS_RPSA_BASE_VA 0xF0006000 - -#define OXNAS_RPSC_BASE 0x44500000 -#define OXNAS_RPSC_SIZE SZ_4K -#define OXNAS_RPSC_BASE_VA 0xF0007000 - - -/* - * Location of flags and vectors in SRAM for controlling the booting of the - * secondary ARM11 processors. - */ - -#define OXNAS_SCU_BASE_VA OXNAS_PERCPU_BASE_VA -#define OXNAS_GICN_BASE_VA(n) (OXNAS_PERCPU_BASE_VA + 0x200 + n*0x100) - -#define HOLDINGPEN_CPU IOMEM(OXNAS_SYSCRTL_BASE_VA + 0xc8) -#define HOLDINGPEN_LOCATION IOMEM(OXNAS_SYSCRTL_BASE_VA + 0xc4) - -/** - * System block reset and clock control - */ -#define SYS_CTRL_PCI_STAT IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x20) -#define SYSCTRL_CLK_STAT IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x24) -#define SYS_CTRL_CLK_SET_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x2C) -#define SYS_CTRL_CLK_CLR_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x30) -#define SYS_CTRL_RST_SET_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x34) -#define SYS_CTRL_RST_CLR_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x38) - -#define SYS_CTRL_PLLSYS_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x48) -#define SYS_CTRL_CLK_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x64) -#define SYS_CTRL_PLLSYS_KEY_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x6C) -#define SYS_CTRL_GMAC_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x78) -#define SYS_CTRL_GMAC_DELAY_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x100) - -/* Scratch registers */ -#define SYS_CTRL_SCRATCHWORD0 IOMEM(OXNAS_SYSCRTL_BASE_VA + 0xc4) -#define SYS_CTRL_SCRATCHWORD1 IOMEM(OXNAS_SYSCRTL_BASE_VA + 0xc8) -#define SYS_CTRL_SCRATCHWORD2 IOMEM(OXNAS_SYSCRTL_BASE_VA + 0xcc) -#define SYS_CTRL_SCRATCHWORD3 IOMEM(OXNAS_SYSCRTL_BASE_VA + 0xd0) - -#define SYS_CTRL_PLLA_CTRL0 IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x1F0) -#define SYS_CTRL_PLLA_CTRL1 IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x1F4) -#define SYS_CTRL_PLLA_CTRL2 IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x1F8) -#define SYS_CTRL_PLLA_CTRL3 IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x1FC) - -#define SYS_CTRL_USBHSMPH_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x40) -#define SYS_CTRL_USBHSMPH_STAT IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x44) -#define SYS_CTRL_REF300_DIV IOMEM(OXNAS_SYSCRTL_BASE_VA + 0xF8) -#define SYS_CTRL_USBHSPHY_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x84) -#define SYS_CTRL_USB_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x90) - -/* pcie */ -#define SYS_CTRL_HCSL_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x114) - -/* System control multi-function pin function selection */ -#define SYS_CTRL_SECONDARY_SEL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x14) -#define SYS_CTRL_TERTIARY_SEL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x8c) -#define SYS_CTRL_QUATERNARY_SEL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x94) -#define SYS_CTRL_DEBUG_SEL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x9c) -#define SYS_CTRL_ALTERNATIVE_SEL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0xa4) -#define SYS_CTRL_PULLUP_SEL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0xac) - -/* Secure control multi-function pin function selection */ -#define SEC_CTRL_SECONDARY_SEL IOMEM(OXNAS_SECCRTL_BASE_VA + 0x14) -#define SEC_CTRL_TERTIARY_SEL IOMEM(OXNAS_SECCRTL_BASE_VA + 0x8c) -#define SEC_CTRL_QUATERNARY_SEL IOMEM(OXNAS_SECCRTL_BASE_VA + 0x94) -#define SEC_CTRL_DEBUG_SEL IOMEM(OXNAS_SECCRTL_BASE_VA + 0x9c) -#define SEC_CTRL_ALTERNATIVE_SEL IOMEM(OXNAS_SECCRTL_BASE_VA + 0xa4) -#define SEC_CTRL_PULLUP_SEL IOMEM(OXNAS_SECCRTL_BASE_VA + 0xac) - -#define SEC_CTRL_COPRO_CTRL IOMEM(OXNAS_SECCRTL_BASE_VA + 0x68) -#define SEC_CTRL_SECURE_CTRL IOMEM(OXNAS_SECCRTL_BASE_VA + 0x98) -#define SEC_CTRL_LEON_DEBUG IOMEM(OXNAS_SECCRTL_BASE_VA + 0xF0) -#define SEC_CTRL_PLLB_DIV_CTRL IOMEM(OXNAS_SECCRTL_BASE_VA + 0xF8) -#define SEC_CTRL_PLLB_CTRL0 IOMEM(OXNAS_SECCRTL_BASE_VA + 0x1F0) -#define SEC_CTRL_PLLB_CTRL1 IOMEM(OXNAS_SECCRTL_BASE_VA + 0x1F4) -#define SEC_CTRL_PLLB_CTRL8 IOMEM(OXNAS_SECCRTL_BASE_VA + 0x1F4) - -#define RPSA_IRQ_SOFT IOMEM(OXNAS_RPSA_BASE_VA + 0x10) -#define RPSA_FIQ_ENABLE IOMEM(OXNAS_RPSA_BASE_VA + 0x108) -#define RPSA_FIQ_DISABLE IOMEM(OXNAS_RPSA_BASE_VA + 0x10C) -#define RPSA_FIQ_IRQ_TO_FIQ IOMEM(OXNAS_RPSA_BASE_VA + 0x1FC) - -#define RPSC_IRQ_SOFT IOMEM(OXNAS_RPSC_BASE_VA + 0x10) -#define RPSC_FIQ_ENABLE IOMEM(OXNAS_RPSC_BASE_VA + 0x108) -#define RPSC_FIQ_DISABLE IOMEM(OXNAS_RPSC_BASE_VA + 0x10C) -#define RPSC_FIQ_IRQ_TO_FIQ IOMEM(OXNAS_RPSC_BASE_VA + 0x1FC) - -#define RPSA_TIMER2_VAL IOMEM(OXNAS_RPSA_BASE_VA + 0x224) - -#define REF300_DIV_INT_SHIFT 8 -#define REF300_DIV_FRAC_SHIFT 0 -#define REF300_DIV_INT(val) ((val) << REF300_DIV_INT_SHIFT) -#define REF300_DIV_FRAC(val) ((val) << REF300_DIV_FRAC_SHIFT) - -#define USBHSPHY_SUSPENDM_MANUAL_ENABLE 16 -#define USBHSPHY_SUSPENDM_MANUAL_STATE 15 -#define USBHSPHY_ATE_ESET 14 -#define USBHSPHY_TEST_DIN 6 -#define USBHSPHY_TEST_ADD 2 -#define USBHSPHY_TEST_DOUT_SEL 1 -#define USBHSPHY_TEST_CLK 0 - -#define USB_CTRL_USBAPHY_CKSEL_SHIFT 5 -#define USB_CLK_XTAL0_XTAL1 (0 << USB_CTRL_USBAPHY_CKSEL_SHIFT) -#define USB_CLK_XTAL0 (1 << USB_CTRL_USBAPHY_CKSEL_SHIFT) -#define USB_CLK_INTERNAL (2 << USB_CTRL_USBAPHY_CKSEL_SHIFT) - -#define USBAMUX_DEVICE BIT(4) - -#define USBPHY_REFCLKDIV_SHIFT 2 -#define USB_PHY_REF_12MHZ (0 << USBPHY_REFCLKDIV_SHIFT) -#define USB_PHY_REF_24MHZ (1 << USBPHY_REFCLKDIV_SHIFT) -#define USB_PHY_REF_48MHZ (2 << USBPHY_REFCLKDIV_SHIFT) - -#define USB_CTRL_USB_CKO_SEL_BIT 0 - -#define USB_INT_CLK_XTAL 0 -#define USB_INT_CLK_REF300 2 -#define USB_INT_CLK_PLLB 3 - -#define SYS_CTRL_GMAC_CKEN_RX_IN 14 -#define SYS_CTRL_GMAC_CKEN_RXN_OUT 13 -#define SYS_CTRL_GMAC_CKEN_RX_OUT 12 -#define SYS_CTRL_GMAC_CKEN_TX_IN 10 -#define SYS_CTRL_GMAC_CKEN_TXN_OUT 9 -#define SYS_CTRL_GMAC_CKEN_TX_OUT 8 -#define SYS_CTRL_GMAC_RX_SOURCE 7 -#define SYS_CTRL_GMAC_TX_SOURCE 6 -#define SYS_CTRL_GMAC_LOW_TX_SOURCE 4 -#define SYS_CTRL_GMAC_AUTO_TX_SOURCE 3 -#define SYS_CTRL_GMAC_RGMII 2 -#define SYS_CTRL_GMAC_SIMPLE_MUX 1 -#define SYS_CTRL_GMAC_CKEN_GTX 0 -#define SYS_CTRL_GMAC_TX_VARDELAY_SHIFT 0 -#define SYS_CTRL_GMAC_TXN_VARDELAY_SHIFT 8 -#define SYS_CTRL_GMAC_RX_VARDELAY_SHIFT 16 -#define SYS_CTRL_GMAC_RXN_VARDELAY_SHIFT 24 -#define SYS_CTRL_GMAC_TX_VARDELAY(d) ((d)<outbound + PCIE_AHB_SLAVE_CTRL, + regmap_update_bits(pcie->sys_ctrl, pcie->outbound_offset + PCIE_AHB_SLAVE_CTRL, PCIE_SLAVE_BE_MASK, PCIE_SLAVE_BE(lanes)); wmb(); } @@ -418,11 +180,13 @@ static inline void set_out_lanes(struct oxnas_pcie *pcie, unsigned lanes) static int oxnas_pcie_link_up(struct oxnas_pcie *pcie) { unsigned long end; + unsigned int val; /* Poll for PCIE link up */ end = jiffies + (LINK_UP_TIMEOUT_SECONDS * HZ); while (!time_after(jiffies, end)) { - if (readl(pcie->pcie_ctrl) & PCIE_LINK_UP) + regmap_read(pcie->sys_ctrl, pcie->pcie_ctrl_offset, &val); + if (val & PCIE_LINK_UP) return 1; } return 0; @@ -464,26 +228,27 @@ static void __init oxnas_pcie_setup_hw(struct oxnas_pcie *pcie) */ /* Set PCIeA mem0 region to be 1st 16MB of the 64MB PCIeA window */ - writel_relaxed(pcie->non_mem.start, pcie->outbound + PCIE_IN0_MEM_ADDR); - writel_relaxed(pcie->non_mem.end, pcie->outbound + PCIE_IN0_MEM_LIMIT); - writel_relaxed(pcie->non_mem.start, pcie->outbound + PCIE_POM0_MEM_ADDR); + regmap_write(pcie->sys_ctrl, pcie->outbound_offset + PCIE_IN0_MEM_ADDR, pcie->non_mem.start); + regmap_write(pcie->sys_ctrl, pcie->outbound_offset + PCIE_IN0_MEM_LIMIT, pcie->non_mem.end); + regmap_write(pcie->sys_ctrl, pcie->outbound_offset + PCIE_POM0_MEM_ADDR, pcie->non_mem.start); /* Set PCIeA mem1 region to be 2nd 16MB of the 64MB PCIeA window */ - writel_relaxed(pcie->pre_mem.start, pcie->outbound + PCIE_IN1_MEM_ADDR); - writel_relaxed(pcie->pre_mem.end, pcie->outbound + PCIE_IN1_MEM_LIMIT); - writel_relaxed(pcie->pre_mem.start, pcie->outbound + PCIE_POM1_MEM_ADDR); + regmap_write(pcie->sys_ctrl, pcie->outbound_offset + PCIE_IN1_MEM_ADDR, pcie->pre_mem.start); + regmap_write(pcie->sys_ctrl, pcie->outbound_offset + PCIE_IN1_MEM_LIMIT, pcie->pre_mem.end); + regmap_write(pcie->sys_ctrl, pcie->outbound_offset + PCIE_POM1_MEM_ADDR, pcie->pre_mem.start); /* Set PCIeA io to be third 16M region of the 64MB PCIeA window*/ - writel_relaxed(pcie->io.start, pcie->outbound + PCIE_IN_IO_ADDR); - writel_relaxed(pcie->io.end, pcie->outbound + PCIE_IN_IO_LIMIT); + regmap_write(pcie->sys_ctrl, pcie->outbound_offset + PCIE_IN_IO_ADDR, pcie->io.start); + regmap_write(pcie->sys_ctrl, pcie->outbound_offset + PCIE_IN_IO_LIMIT, pcie->io.end); + /* Set PCIeA cgf0 to be last 16M region of the 64MB PCIeA window*/ - writel_relaxed(pcie->cfg.start, pcie->outbound + PCIE_IN_CFG0_ADDR); - writel_relaxed(pcie->cfg.end, pcie->outbound + PCIE_IN_CFG0_LIMIT); + regmap_write(pcie->sys_ctrl, pcie->outbound_offset + PCIE_IN_CFG0_ADDR, pcie->cfg.start); + regmap_write(pcie->sys_ctrl, pcie->outbound_offset + PCIE_IN_CFG0_LIMIT, pcie->cfg.end); wmb(); /* Enable outbound address translation */ - oxnas_register_set_mask(pcie->pcie_ctrl, PCIE_OBTRANS); + regmap_write_bits(pcie->sys_ctrl, pcie->pcie_ctrl_offset, PCIE_OBTRANS, PCIE_OBTRANS); wmb(); /* @@ -640,13 +405,14 @@ static void __init oxnas_pcie_enable(struct device *dev, struct oxnas_pcie *pcie } void oxnas_pcie_init_shared_hw(struct platform_device *pdev, - void __iomem *phybase) + void __iomem *phybase, + struct regmap *sys_ctrl) { struct reset_control *rstc; int ret; /* generate clocks from HCSL buffers, shared parts */ - writel(HCSL_BIAS_ON|HCSL_PCIE_EN, SYS_CTRL_HCSL_CTRL); + regmap_write(sys_ctrl, SYS_CTRL_HCSL_CTRL_REGOFFSET, HCSL_BIAS_ON|HCSL_PCIE_EN); /* Ensure PCIe PHY is properly reset */ rstc = reset_control_get(&pdev->dev, "phy"); @@ -663,7 +429,6 @@ void oxnas_pcie_init_shared_hw(struct platform_device *pdev, } /* Enable PCIe Pre-Emphasis: What these value means? */ - writel(ADDR_VAL(0x0014), phybase + PHY_ADDR); writel(DATA_VAL(0xce10) | CAP_DATA, phybase + PHY_DATA); writel(DATA_VAL(0xce10) | WRITE_EN, phybase + PHY_DATA); @@ -673,7 +438,7 @@ void oxnas_pcie_init_shared_hw(struct platform_device *pdev, writel(DATA_VAL(0x82c7) | WRITE_EN, phybase + PHY_DATA); } -static int oxnas_pcie_shared_init(struct platform_device *pdev) +static int oxnas_pcie_shared_init(struct platform_device *pdev, struct regmap *sys_ctrl) { if (++pcie_shared.refcount == 1) { /* we are the first */ @@ -683,7 +448,7 @@ static int oxnas_pcie_shared_init(struct platform_device *pdev) --pcie_shared.refcount; return -ENOMEM; } - oxnas_pcie_init_shared_hw(pdev, phy); + oxnas_pcie_init_shared_hw(pdev, phy, sys_ctrl); iounmap(phy); return 0; } else { @@ -730,13 +495,12 @@ oxnas_pcie_map_registers(struct platform_device *pdev, if (of_property_read_u32(np, "plxtech,pcie-outbound-offset", &outbound_ctrl_offset)) return -EINVAL; - /* SYSCRTL is shared by too many drivers, so is mapped by board file */ - pcie->outbound = IOMEM(OXNAS_SYSCRTL_BASE_VA + outbound_ctrl_offset); + pcie->outbound_offset = outbound_ctrl_offset; if (of_property_read_u32(np, "plxtech,pcie-ctrl-offset", &pcie_ctrl_offset)) return -EINVAL; - pcie->pcie_ctrl = IOMEM(OXNAS_SYSCRTL_BASE_VA + pcie_ctrl_offset); + pcie->pcie_ctrl_offset = pcie_ctrl_offset; return 0; } @@ -823,7 +587,8 @@ static void oxnas_pcie_init_hw(struct platform_device *pdev, mdelay(100); } - oxnas_register_set_mask(SYS_CTRL_HCSL_CTRL, BIT(pcie->hcsl_en)); + regmap_update_bits(pcie->sys_ctrl, SYS_CTRL_HCSL_CTRL_REGOFFSET, + BIT(pcie->hcsl_en), BIT(pcie->hcsl_en)); /* core */ ret = device_reset(&pdev->dev); @@ -845,15 +610,17 @@ static void oxnas_pcie_init_hw(struct platform_device *pdev, } /* allow entry to L23 state */ - oxnas_register_set_mask(pcie->pcie_ctrl, PCIE_READY_ENTR_L23); + regmap_write_bits(pcie->sys_ctrl, pcie->pcie_ctrl_offset, + PCIE_READY_ENTR_L23, PCIE_READY_ENTR_L23); /* Set PCIe core into RootCore mode */ - oxnas_register_value_mask(pcie->pcie_ctrl, PCIE_DEVICE_TYPE_MASK, - PCIE_DEVICE_TYPE_ROOT); + regmap_write_bits(pcie->sys_ctrl, pcie->pcie_ctrl_offset, + PCIE_DEVICE_TYPE_MASK, PCIE_DEVICE_TYPE_ROOT); wmb(); /* Bring up the PCI core */ - oxnas_register_set_mask(pcie->pcie_ctrl, PCIE_LTSSM); + regmap_write_bits(pcie->sys_ctrl, pcie->pcie_ctrl_offset, + PCIE_LTSSM, PCIE_LTSSM); wmb(); } @@ -872,6 +639,10 @@ static int __init oxnas_pcie_probe(struct platform_device *pdev) pcie->haslink = 1; spin_lock_init(&pcie->lock); + pcie->sys_ctrl = syscon_regmap_lookup_by_compatible("oxsemi,ox820-sys-ctrl"); + if (IS_ERR(pcie->sys_ctrl)) + return PTR_ERR(pcie->sys_ctrl); + ret = oxnas_pcie_init_res(pdev, pcie, np); if (ret) return ret; @@ -891,7 +662,7 @@ static int __init oxnas_pcie_probe(struct platform_device *pdev) goto err_free_gpio; } - ret = oxnas_pcie_shared_init(pdev); + ret = oxnas_pcie_shared_init(pdev, pcie->sys_ctrl); if (ret) goto err_free_gpio;