[RFC PATCH 2/3] drivers: pci: refactor SiFive pcie to use designware common code
Green Wan
green.wan at sifive.com
Tue Mar 30 09:36:13 CEST 2021
Refactor pcie_sifive.c to use pcie_dw_common.c.
- Add DW_COMMON to defconfig and Kconfig
- Move common iomem base address into 'struct pcie_dw'
- Remove unnecessary/unused functions after code merge
- Rename 'perstn-gpios' to 'reset-gpios'
- Remove drivers/pci/pcie_sifive.h
Signed-off-by: Green Wan <green.wan at sifive.com>
---
configs/sifive_unmatched_defconfig | 1 +
drivers/pci/Kconfig | 1 +
drivers/pci/pcie_sifive.c | 735 +++++++++--------------------
drivers/pci/pcie_sifive.h | 374 ---------------
4 files changed, 225 insertions(+), 886 deletions(-)
delete mode 100644 drivers/pci/pcie_sifive.h
diff --git a/configs/sifive_unmatched_defconfig b/configs/sifive_unmatched_defconfig
index c5ca0be0bf..7769e366dc 100644
--- a/configs/sifive_unmatched_defconfig
+++ b/configs/sifive_unmatched_defconfig
@@ -51,3 +51,4 @@ CONFIG_CLK_SIFIVE_PRCI=y
CONFIG_DM_PWM=y
CONFIG_PWM_SIFIVE=y
CONFIG_CMD_PWM=y
+CONFIG_PCIE_DW_COMMON=y
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 842240ba42..fd24cef45f 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -102,6 +102,7 @@ config PCIE_SIFIVE_FU740
depends on CLK_SIFIVE_PRCI
depends on RESET_SIFIVE
depends on SIFIVE_GPIO
+ select PCIE_DW_COMMON
help
Say Y here if you want to enable PCIe controller support on
FU740.
diff --git a/drivers/pci/pcie_sifive.c b/drivers/pci/pcie_sifive.c
index ada60876bc..599eb0ece2 100644
--- a/drivers/pci/pcie_sifive.c
+++ b/drivers/pci/pcie_sifive.c
@@ -11,24 +11,131 @@
*
* Based on driver from author: Alan Mikhak <amikhak at wirelessfabric.com>
*/
-#include "pcie_sifive.h"
+#include <asm/io.h>
+#include <asm-generic/gpio.h>
+#include <clk.h>
#include <common.h>
#include <dm.h>
+#include <dm/device_compat.h>
+#include <generic-phy.h>
+#include <linux/bitops.h>
+#include <linux/log2.h>
+#include <pci.h>
+#include <pci_ep.h>
+#include <pci_ids.h>
+#include <regmap.h>
+#include <reset.h>
+#include <syscon.h>
+
+#include "pcie_dw_common.h"
+
+struct pcie_sifive {
+ /* Must be first member of the struct */
+ struct pcie_dw dw;
+
+ /* private control regs */
+ void __iomem *priv_base;
+
+ /* reset, power, clock resources */
+ int sys_int_pin;
+ struct gpio_desc pwren_gpio;
+ struct gpio_desc reset_gpio;
+ struct clk aux_ck;
+ struct reset_ctl reset;
+};
+
+enum pcie_sifive_devtype {
+ SV_PCIE_UNKNOWN_TYPE = 0,
+ SV_PCIE_ENDPOINT_TYPE = 1,
+ SV_PCIE_HOST_TYPE = 3
+};
-/* Host Bridge Identification */
-#define DEVICE_NAME "SiFive FU740 PCIe Host Controller"
-#define VENDOR_ID 0x51fe
-#define DEVICE_ID 0x51fe
+#define ASSERTION_DELAY 100
+#define PCIE_PERST_ASSERT 0x0
+#define PCIE_PERST_DEASSERT 0x1
+#define PCIE_PHY_RESET 0x1
+#define PCIE_PHY_RESET_DEASSERT 0x0
+#define GPIO_LOW 0x0
+#define GPIO_HIGH 0x1
+#define PCIE_PHY_SEL 0x1
+
+#define sv_info(sv, fmt, arg...) printf(fmt, ## arg)
+#define sv_warn(sv, fmt, arg...) printf(fmt, ## arg)
+#define sv_debug(sv, fmt, arg...) debug(fmt, ## arg)
+#define sv_err(sv, fmt, arg...) printf(fmt, ## arg)
+
+/* Doorbell Interface */
+#define DBI_OFFSET 0x0
+#define DBI_SIZE 0x1000
+
+#define PL_OFFSET 0x700
+
+#define PHY_DEBUG_R0 (PL_OFFSET + 0x28)
+
+#define PHY_DEBUG_R1 (PL_OFFSET + 0x2c)
+#define PHY_DEBUG_R1_LINK_UP (0x1 << 4)
+#define PHY_DEBUG_R1_LINK_IN_TRAINING (0x1 << 29)
+
+#define PCIE_MISC_CONTROL_1 0x8bc
+#define DBI_RO_WR_EN BIT(0)
+
+/* pcie reset */
+#define PCIEX8MGMT_PERST_N 0x0
+
+/* LTSSM */
+#define PCIEX8MGMT_APP_LTSSM_ENABLE 0x10
+#define LTSSM_ENABLE_BIT BIT(0)
+
+/* phy reset */
+#define PCIEX8MGMT_APP_HOLD_PHY_RST 0x18
+
+/* device type */
+#define PCIEX8MGMT_DEVICE_TYPE 0x708
+#define DEVICE_TYPE_EP 0x0
+#define DEVICE_TYPE_RC 0x4
+
+/* phy control registers*/
+#define PCIEX8MGMT_PHY0_CR_PARA_ADDR 0x860
+#define PCIEX8MGMT_PHY0_CR_PARA_RD_EN 0x870
+#define PCIEX8MGMT_PHY0_CR_PARA_RD_DATA 0x878
+#define PCIEX8MGMT_PHY0_CR_PARA_SEL 0x880
+#define PCIEX8MGMT_PHY0_CR_PARA_WR_DATA 0x888
+#define PCIEX8MGMT_PHY0_CR_PARA_WR_EN 0x890
+#define PCIEX8MGMT_PHY0_CR_PARA_ACK 0x898
+#define PCIEX8MGMT_PHY1_CR_PARA_ADDR 0x8a0
+#define PCIEX8MGMT_PHY1_CR_PARA_RD_EN 0x8b0
+#define PCIEX8MGMT_PHY1_CR_PARA_RD_DATA 0x8b8
+#define PCIEX8MGMT_PHY1_CR_PARA_SEL 0x8c0
+#define PCIEX8MGMT_PHY1_CR_PARA_WR_DATA 0x8c8
+#define PCIEX8MGMT_PHY1_CR_PARA_WR_EN 0x8d0
+#define PCIEX8MGMT_PHY1_CR_PARA_ACK 0x8d8
+
+#define PCIEX8MGMT_LANE_NUM 8
+#define PCIEX8MGMT_LANE 0x1008
+#define PCIEX8MGMT_LANE_OFF 0x100
+#define PCIEX8MGMT_TERM_MODE 0x0e21
+
+#define PCIE_CAP_BASE 0x70
+#define PCI_CONFIG(r) (DBI_OFFSET + (r))
+#define PCIE_CAPABILITIES(r) PCI_CONFIG(PCIE_CAP_BASE + (r))
+
+/* Link capability */
+#define PF0_PCIE_CAP_LINK_CAP PCIE_CAPABILITIES(0xc)
+#define PCIE_LINK_CAP_MAX_SPEED_MASK 0xf
+#define PCIE_LINK_CAP_MAX_SPEED_GEN1 BIT(0)
+#define PCIE_LINK_CAP_MAX_SPEED_GEN2 BIT(1)
+#define PCIE_LINK_CAP_MAX_SPEED_GEN3 BIT(2)
+#define PCIE_LINK_CAP_MAX_SPEED_GEN4 BIT(3)
static enum pcie_sifive_devtype pcie_sifive_get_devtype(struct pcie_sifive *sv)
{
u32 val;
- val = readl(sv->priv.iobase + MGMT_MISC_DEVICE_TYPE_OFFSET);
+ val = readl(sv->priv_base + PCIEX8MGMT_DEVICE_TYPE);
switch (val) {
- case MGMT_MISC_DEVICE_TYPE_RC:
+ case DEVICE_TYPE_RC:
return SV_PCIE_HOST_TYPE;
- case MGMT_MISC_DEVICE_TYPE_EP:
+ case DEVICE_TYPE_EP:
return SV_PCIE_ENDPOINT_TYPE;
default:
return SV_PCIE_UNKNOWN_TYPE;
@@ -40,29 +147,29 @@ static void pcie_sifive_priv_set_state(struct pcie_sifive *sv, u32 reg,
{
u32 val;
- val = readl(sv->priv.iobase + reg);
+ val = readl(sv->priv_base + reg);
val = state ? (val | bits) : (val & !bits);
- writel(val, sv->priv.iobase + reg);
+ writel(val, sv->priv_base + reg);
}
-static void pcie_sifive_assert_perstn(struct pcie_sifive *sv)
+static void pcie_sifive_assert_reset(struct pcie_sifive *sv)
{
- dm_gpio_set_value(&sv->perstn_gpio, 0);
- writel(0x0, sv->priv.iobase + PCIEX8MGMT_PERST_N);
- mdelay(100);
+ dm_gpio_set_value(&sv->reset_gpio, GPIO_LOW);
+ writel(PCIE_PERST_ASSERT, sv->priv_base + PCIEX8MGMT_PERST_N);
+ mdelay(ASSERTION_DELAY);
}
static void pcie_sifive_power_on(struct pcie_sifive *sv)
{
- dm_gpio_set_value(&sv->pwren_gpio, 1);
- mdelay(100);
+ dm_gpio_set_value(&sv->pwren_gpio, GPIO_HIGH);
+ mdelay(ASSERTION_DELAY);
}
-static void pcie_sifive_deassert_perstn(struct pcie_sifive *sv)
+static void pcie_sifive_deassert_reset(struct pcie_sifive *sv)
{
- writel(0x1, sv->priv.iobase + PCIEX8MGMT_PERST_N);
- dm_gpio_set_value(&sv->perstn_gpio, 1);
- mdelay(100);
+ writel(PCIE_PERST_DEASSERT, sv->priv_base + PCIEX8MGMT_PERST_N);
+ dm_gpio_set_value(&sv->reset_gpio, GPIO_HIGH);
+ mdelay(ASSERTION_DELAY);
}
static int pcie_sifive_setphy(const u8 phy, const u8 write,
@@ -75,22 +182,22 @@ static int pcie_sifive_setphy(const u8 phy, const u8 write,
return -2;
/* setup phy para */
- writel(addr, sv->priv.iobase +
+ writel(addr, sv->priv_base +
(phy ? PCIEX8MGMT_PHY1_CR_PARA_ADDR :
PCIEX8MGMT_PHY0_CR_PARA_ADDR));
if (write)
- writel(wrdata, sv->priv.iobase +
+ writel(wrdata, sv->priv_base +
(phy ? PCIEX8MGMT_PHY1_CR_PARA_WR_DATA :
PCIEX8MGMT_PHY0_CR_PARA_WR_DATA));
/* enable access if write */
if (write)
- writel(1, sv->priv.iobase +
+ writel(1, sv->priv_base +
(phy ? PCIEX8MGMT_PHY1_CR_PARA_WR_EN :
PCIEX8MGMT_PHY0_CR_PARA_WR_EN));
else
- writel(1, sv->priv.iobase +
+ writel(1, sv->priv_base +
(phy ? PCIEX8MGMT_PHY1_CR_PARA_RD_EN :
PCIEX8MGMT_PHY0_CR_PARA_RD_EN));
@@ -98,13 +205,13 @@ static int pcie_sifive_setphy(const u8 phy, const u8 write,
do {
u32 val;
- val = readl(sv->priv.iobase +
+ val = readl(sv->priv_base +
(phy ? PCIEX8MGMT_PHY1_CR_PARA_ACK :
PCIEX8MGMT_PHY0_CR_PARA_ACK));
if (val) {
ack = 1;
if (!write)
- readl(sv->priv.iobase +
+ readl(sv->priv_base +
(phy ? PCIEX8MGMT_PHY1_CR_PARA_RD_DATA :
PCIEX8MGMT_PHY0_CR_PARA_RD_DATA));
mdelay(1);
@@ -113,15 +220,15 @@ static int pcie_sifive_setphy(const u8 phy, const u8 write,
/* clear */
if (write)
- writel(0, sv->priv.iobase +
+ writel(0, sv->priv_base +
(phy ? PCIEX8MGMT_PHY1_CR_PARA_WR_EN :
PCIEX8MGMT_PHY0_CR_PARA_WR_EN));
else
- writel(0, sv->priv.iobase +
+ writel(0, sv->priv_base +
(phy ? PCIEX8MGMT_PHY1_CR_PARA_RD_EN :
PCIEX8MGMT_PHY0_CR_PARA_RD_EN));
- while (readl(sv->priv.iobase +
+ while (readl(sv->priv_base +
(phy ? PCIEX8MGMT_PHY1_CR_PARA_ACK :
PCIEX8MGMT_PHY0_CR_PARA_ACK))) {
/* wait for ~wait_idle */
@@ -135,8 +242,8 @@ static void pcie_sifive_init_phy(struct pcie_sifive *sv)
int lane;
/* enable phy cr_para_sel interfaces */
- writel(0x1, sv->priv.iobase + PCIEX8MGMT_PHY0_CR_PARA_SEL);
- writel(0x1, sv->priv.iobase + PCIEX8MGMT_PHY1_CR_PARA_SEL);
+ writel(PCIE_PHY_SEL, sv->priv_base + PCIEX8MGMT_PHY0_CR_PARA_SEL);
+ writel(PCIE_PHY_SEL, sv->priv_base + PCIEX8MGMT_PHY1_CR_PARA_SEL);
mdelay(1);
/* set PHY AC termination mode */
@@ -152,103 +259,11 @@ static void pcie_sifive_init_phy(struct pcie_sifive *sv)
}
}
-static void pcie_sifive_set_pci_int_pin(struct pcie_sifive *sv,
- enum pci_interrupt_pin pin)
-{
- u32 val;
-
- /* ctrl_ro_wr_enable */
- val = readl(sv->ctrl.iobase + PCIE_MISC_CONTROL_1);
- val |= DBI_RO_WR_EN;
- writel(val, sv->ctrl.iobase + PCIE_MISC_CONTROL_1);
-
- writeb(pin, sv->ctrl.iobase + PCI_CONFIG(PCI_INTERRUPT_PIN));
-
- /* ctrl_ro_wr_disable */
- val &= ~DBI_RO_WR_EN;
- writel(val, sv->ctrl.iobase + PCIE_MISC_CONTROL_1);
-}
-
-static int pcie_sifive_get_property(struct pcie_sifive *sv,
- const char *property)
-{
- u32 value = 0;
-
- if (dev_read_u32(sv->pci.dev, property, &value))
- return 0;
-
- return value;
-}
-
-static int pcie_sifive_get_required_property(struct pcie_sifive *sv,
- const char *property)
-{
- int value;
-
- value = pcie_sifive_get_property(sv, property);
- if (value == -EINVAL)
- sv_err(sv, "Unable to read %s property\n", property);
-
- return value;
-}
-
-static u32 pcie_sifive_get_link_width_mask(struct pcie_sifive *sv, int lanes)
-{
- switch (lanes) {
- case 1: return LINK_WIDTH_1_LANE;
- case 2: return LINK_WIDTH_2_LANES;
- case 4: return LINK_WIDTH_4_LANES;
- case 8: return LINK_WIDTH_8_LANES;
- default: return 0;
- }
-}
-
-static u32 pcie_sifive_get_link_lanes_mask(struct pcie_sifive *sv, int lanes)
-{
- switch (lanes) {
- case 1: return LINK_MODE_1_LANE;
- case 2: return LINK_MODE_2_LANES;
- case 4: return LINK_MODE_4_LANES;
- case 8: return LINK_MODE_8_LANES;
- default: return 0;
- }
-}
-
-static void pcie_sifive_set_link_num_lanes(struct pcie_sifive *sv, int lanes)
-{
- u32 mode;
-
- mode = pcie_sifive_get_link_lanes_mask(sv, lanes);
- if (mode) {
- u32 val;
-
- val = readl(sv->ctrl.iobase + LINK_CONTROL);
- val &= ~LINK_MODE_MASK;
- val |= mode;
- writel(val, sv->ctrl.iobase + LINK_CONTROL);
- }
-}
-
-static void pcie_sifive_set_link_width(struct pcie_sifive *sv, int lanes)
-{
- u32 lwidth;
-
- lwidth = pcie_sifive_get_link_width_mask(sv, lanes);
- if (lwidth) {
- u32 val;
-
- val = readl(sv->ctrl.iobase + LINK_WIDTH_SPEED_CONTROL);
- val &= ~LINK_WIDTH_MASK;
- val |= lwidth;
- writel(val, sv->ctrl.iobase + LINK_WIDTH_SPEED_CONTROL);
- }
-}
-
static int pcie_sifive_check_link(struct pcie_sifive *sv)
{
u32 val;
- val = readl(sv->ctrl.iobase + PHY_DEBUG_R1);
+ val = readl(sv->dw.dbi_base + PHY_DEBUG_R1);
return (val & PHY_DEBUG_R1_LINK_UP) &&
!(val & PHY_DEBUG_R1_LINK_IN_TRAINING);
}
@@ -264,141 +279,25 @@ static void pcie_sifive_force_gen1(struct pcie_sifive *sv)
*/
/* ctrl_ro_wr_enable */
- val = readl(sv->ctrl.iobase + PCIE_MISC_CONTROL_1);
+ val = readl(sv->dw.dbi_base + PCIE_MISC_CONTROL_1);
val |= DBI_RO_WR_EN;
- writel(val, sv->ctrl.iobase + PCIE_MISC_CONTROL_1);
+ writel(val, sv->dw.dbi_base + PCIE_MISC_CONTROL_1);
/* configure link cap */
- linkcap = readl(sv->ctrl.iobase + PF0_PCIE_CAP_LINK_CAP);
+ linkcap = readl(sv->dw.dbi_base + PF0_PCIE_CAP_LINK_CAP);
linkcap |= PCIE_LINK_CAP_MAX_SPEED_MASK;
- writel(linkcap, sv->ctrl.iobase + PF0_PCIE_CAP_LINK_CAP);
+ writel(linkcap, sv->dw.dbi_base + PF0_PCIE_CAP_LINK_CAP);
/* ctrl_ro_wr_disable */
val &= ~DBI_RO_WR_EN;
- writel(val, sv->ctrl.iobase + PCIE_MISC_CONTROL_1);
+ writel(val, sv->dw.dbi_base + PCIE_MISC_CONTROL_1);
}
static void pcie_sifive_print_phy_debug(struct pcie_sifive *sv)
{
sv_err(sv, "PHY DEBUG_R0=0x%08x DEBUG_R1=0x%08x\n",
- readl(sv->ctrl.iobase + PHY_DEBUG_R0),
- readl(sv->ctrl.iobase + PHY_DEBUG_R1));
-}
-
-static int pcie_sifive_set_check_atu(struct pcie_sifive *sv, u32 region)
-{
- u32 retries, val;
-
- /*
- * Make sure ATU enable takes effect before any subsequent config
- * and I/O accesses.
- */
- for (retries = 0; retries < ATU_WAIT_MAX_RETRIES; retries++) {
- val = readl(sv->ctrl.iobase + region + ATU_REGION_CTRL2);
- if (val & ATU_ENABLE)
- return 0;
-
- mdelay(ATU_WAIT);
- }
-
- return -EBUSY;
-}
-
-static void pcie_sifive_set_atu(struct pcie_sifive *sv, u32 region,
- u32 ctrl1, u32 ctrl2, u64 size,
- u64 base_addr, u64 target_addr)
-{
- u64 limit_addr = base_addr + size - 1;
-
- if (upper_32_bits(size))
- ctrl1 |= ATU_INCREASE_REGION_SIZE;
-
- writel(lower_32_bits(base_addr),
- sv->ctrl.iobase + region + ATU_LOWER_BASE);
- writel(upper_32_bits(base_addr),
- sv->ctrl.iobase + region + ATU_UPPER_BASE);
- writel(lower_32_bits(limit_addr),
- sv->ctrl.iobase + region + ATU_LOWER_LIMIT);
- writel(upper_32_bits(limit_addr),
- sv->ctrl.iobase + region + ATU_UPPER_LIMIT);
- writel(lower_32_bits(target_addr),
- sv->ctrl.iobase + region + ATU_LOWER_TARGET);
- writel(upper_32_bits(target_addr),
- sv->ctrl.iobase + region + ATU_UPPER_TARGET);
- writel(ctrl1, sv->ctrl.iobase + region + ATU_REGION_CTRL1);
- writel(ctrl2 | ATU_ENABLE, sv->ctrl.iobase + region + ATU_REGION_CTRL2);
-}
-
-static void pcie_sifive_set_outbound_atu(struct pcie_sifive *sv,
- u32 index, u32 ctrl1, u32 ctrl2,
- u64 size, u64 cpu_addr, u64 pci_addr)
-{
- u32 region = ATU_CONFIG(ATU_OUTBOUND_REGION(index));
-
- pcie_sifive_set_atu(sv, region, ctrl1, ctrl2, size, cpu_addr, pci_addr);
-
- if (pcie_sifive_set_check_atu(sv, region))
- sv_err(sv, "Outbound ATU could not be enabled\n");
-}
-
-static void __iomem *pcie_sifive_cfg_outbound_atu(struct pcie_sifive *sv,
- u32 bdf, u32 where)
-{
- u32 bus, ctrl1;
-
- where &= ~0x3;
-
- bus = ((bdf >> 16) & 0xff) - sv->pci.pp.root_bus_nr;
- if (!bus)
- return sv->ctrl.iobase + PCI_CONFIG(where);
-
- if (bus == 1)
- ctrl1 = ATU_TYPE_CFG0;
- else
- ctrl1 = ATU_TYPE_CFG1;
-
- bdf = (bus << 16) | (bdf & 0xffff);
- pcie_sifive_set_outbound_atu(sv, 1, ctrl1, 0, SZ_4K,
- sv->pci.pp.cfg1_base,
- (u64)(bdf << 8));
-
- return sv->pci.pp.va_cfg1_base + where;
-}
-
-static void pcie_sifive_set_outbound_mem_atu(struct pcie_sifive *sv, u32 index,
- u64 size, u64 cpu_addr,
- u64 pci_addr)
-{
- pcie_sifive_set_outbound_atu(sv, index, ATU_TYPE_MEM, 0,
- size, cpu_addr, pci_addr);
-}
-
-static void pcie_sifive_set_outbound_io_atu(struct pcie_sifive *sv, u32 index,
- u64 size, u64 cpu_addr,
- u64 pci_addr)
-{
- pcie_sifive_set_outbound_atu(sv, index, ATU_TYPE_IO, 0,
- size, cpu_addr, pci_addr);
-}
-
-static int pcie_sifive_set_outbound_ecam_atu(struct pcie_sifive *sv, u32 index,
- u64 cpu_addr)
-{
- pcie_sifive_set_outbound_atu(sv, index++,
- ATU_TYPE_CFG0, ATU_CFG_SHIFT_MODE,
- SZ_4K, cpu_addr, 0);
-
- pcie_sifive_set_outbound_atu(sv, index++,
- ATU_TYPE_CFG1, ATU_CFG_SHIFT_MODE,
- SZ_256M - SZ_1M,
- cpu_addr + SZ_1M,
- SZ_1M);
- return index;
-}
-
-static void pcie_sifive_assert_phy_reset(struct pcie_sifive *sv)
-{
- writel(0x1, sv->priv.iobase + PCIEX8MGMT_APP_HOLD_PHY_RST);
+ readl(sv->dw.dbi_base + PHY_DEBUG_R0),
+ readl(sv->dw.dbi_base + PHY_DEBUG_R1));
}
static int pcie_sifive_wait_for_link(struct pcie_sifive *sv)
@@ -414,33 +313,19 @@ static int pcie_sifive_wait_for_link(struct pcie_sifive *sv)
mdelay(1);
} while (--timeout && !pcie_sifive_check_link(sv));
- val = readl(sv->ctrl.iobase + PHY_DEBUG_R1);
+ val = readl(sv->dw.dbi_base + PHY_DEBUG_R1);
if (!(val & PHY_DEBUG_R1_LINK_UP) ||
(val & PHY_DEBUG_R1_LINK_IN_TRAINING)) {
sv_info(sv, "Failed to negotiate PCIe link!\n");
pcie_sifive_print_phy_debug(sv);
- pcie_sifive_assert_phy_reset(sv);
+ writel(PCIE_PHY_RESET,
+ sv->priv_base + PCIEX8MGMT_APP_HOLD_PHY_RST);
return -ETIMEDOUT;
}
- sv_info(sv, "PCIe Link up, Gen%i\n",
- readw(sv->ctrl.iobase + PF0_PCIE_CAP_LINK_STATUS) &
- PCIE_LINK_STATUS_SPEED_MASK);
-
return 0;
}
-static void pcie_sifive_setup_link(struct pcie_sifive *sv)
-{
- u32 lanes;
-
- lanes = pcie_sifive_get_required_property(sv, "num-lanes");
- if (lanes > 0) {
- pcie_sifive_set_link_num_lanes(sv, lanes);
- pcie_sifive_set_link_width(sv, lanes);
- }
-}
-
static int pcie_sifive_start_link(struct pcie_sifive *sv)
{
if (pcie_sifive_check_link(sv))
@@ -449,226 +334,72 @@ static int pcie_sifive_start_link(struct pcie_sifive *sv)
pcie_sifive_force_gen1(sv);
/* set ltssm */
- pcie_sifive_priv_set_state(sv, MGMT_MISC_LTSSM_ENABLE_OFFSET,
- MGMT_MISC_LTSSM_ENABLE_BIT, 1);
- return 0;
-}
-
-static void pcie_sifive_setup_host_atu(struct pcie_sifive *sv)
-{
- pcie_sifive_set_outbound_mem_atu(sv, 0,
- sv->pci.pp.mem_size,
- sv->pci.pp.mem_base,
- sv->pci.pp.mem_bus_addr);
-
- if (sv->pci.num_viewport > 2)
- pcie_sifive_set_outbound_io_atu(sv, 2,
- sv->pci.pp.io_size,
- sv->pci.pp.io_base,
- sv->pci.pp.io_bus_addr);
-
- if (sv->pci.pp.ecam.iobase)
- pcie_sifive_set_outbound_ecam_atu(sv, 3,
- (u64)sv->pci.pp.ecam.iobase);
-}
-
-static void pcie_sifive_setup_host_prefetch(struct pcie_sifive *sv)
-{
- u32 val;
-
- /* ctrl_ro_wr_enable */
- val = readl(sv->ctrl.iobase + PCIE_MISC_CONTROL_1);
- val |= DBI_RO_WR_EN;
- writel(val, sv->ctrl.iobase + PCIE_MISC_CONTROL_1);
-
- writew(0xf, sv->ctrl.iobase + PCI_CONFIG(PCI_PREF_MEMORY_BASE));
- writew(0xf, sv->ctrl.iobase + PCI_CONFIG(PCI_PREF_MEMORY_LIMIT));
- writel(0x20, sv->ctrl.iobase + PCI_CONFIG(PCI_PREF_BASE_UPPER32));
- writel(0x40, sv->ctrl.iobase + PCI_CONFIG(PCI_PREF_LIMIT_UPPER32));
-
- /* ctrl_ro_wr_disable */
- val &= ~DBI_RO_WR_EN;
- writel(val, sv->ctrl.iobase + PCIE_MISC_CONTROL_1);
-}
-
-static void pcie_sifive_setup_host(struct pcie_sifive *sv)
-{
- u32 val;
-
- sv->pci.iatu_unroll_enabled = true;
-
- pcie_sifive_setup_link(sv);
-
- /* ctrl_ro_wr_enable */
- val = readl(sv->ctrl.iobase + PCIE_MISC_CONTROL_1);
- val |= DBI_RO_WR_EN;
- writel(val, sv->ctrl.iobase + PCIE_MISC_CONTROL_1);
-
- /* Setup correct class code for host bridge */
- writew(PCI_CLASS_BRIDGE_PCI,
- sv->ctrl.iobase + PCI_CONFIG(PCI_CLASS_DEVICE));
-
- /* ctrl_ro_wr_disable */
- val &= ~DBI_RO_WR_EN;
- writel(val, sv->ctrl.iobase + PCIE_MISC_CONTROL_1);
-
- writeb(PCI_HEADER_TYPE_BRIDGE,
- sv->ctrl.iobase + PCI_CONFIG(PCI_HEADER_TYPE));
-
- /* Setup RC BARs */
- writel(0x4, sv->ctrl.iobase + PCI_CONFIG(PCI_BASE_ADDRESS_0));
- writel(0x0, sv->ctrl.iobase + PCI_CONFIG(PCI_BASE_ADDRESS_1));
-
- pcie_sifive_set_pci_int_pin(sv, PCI_INTERRUPT_INTA);
-
- /* Setup bus numbers */
- val = readl(sv->ctrl.iobase + PCI_CONFIG(PCI_PRIMARY_BUS)) &
- ~0x00ffffff;
- val |= 0x00ff0100;
- writel(val, sv->ctrl.iobase + PCI_CONFIG(PCI_PRIMARY_BUS));
-
- /* Setup command register */
- writew(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
- PCI_COMMAND_SERR, sv->ctrl.iobase + PCI_CONFIG(PCI_COMMAND));
-
- pcie_sifive_setup_host_atu(sv);
-
- writel(0x0, sv->ctrl.iobase + PCI_CONFIG(PCI_BASE_ADDRESS_0));
-
- pcie_sifive_setup_host_prefetch(sv);
-}
-
-static int pcie_sifive_init_host(struct pcie_sifive *sv)
-{
- pcie_sifive_setup_host(sv);
-
- if (pcie_sifive_start_link(sv) == -EALREADY)
- sv_info(sv, "PCIe link is already up\n");
- else if (pcie_sifive_wait_for_link(sv) == -ETIMEDOUT)
- return -ETIMEDOUT;
-
- return 0;
-}
-
-static int pcie_sifive_addr_valid(struct pcie_sifive *sv, pci_dev_t bdf)
-{
- if ((PCI_BUS(bdf) == sv->pci.pp.root_bus_nr) && (PCI_DEV(bdf) > 0))
- return 0;
- if ((PCI_BUS(bdf) == sv->pci.pp.root_bus_nr + 1) && (PCI_DEV(bdf) > 0))
- return 0;
-
- return 1;
-}
-
-static int pcie_sifive_read_config(const struct udevice *bus, pci_dev_t bdf,
- uint offset, ulong *valuep,
- enum pci_size_t size)
-{
- struct pcie_sifive *sv = dev_get_priv(bus);
- void __iomem *va;
- ulong value;
-
- sv_debug(sv, "PCIe CFG read: (b,d,f)=(%2d,%2d,%2d) ",
- PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
-
- if (!pcie_sifive_addr_valid(sv, bdf)) {
- sv_debug(sv, "- out of range\n");
- *valuep = pci_get_ff(size);
- return 0;
- }
-
- va = pcie_sifive_cfg_outbound_atu(sv, bdf, offset);
- value = readl(va);
-
- sv_debug(sv, "(addr,val)=(0x%04x, 0x%08lx)\n", offset, value);
- *valuep = pci_conv_32_to_size(value, offset, size);
-
- if (sv->pci.num_viewport <= 2)
- pcie_sifive_set_outbound_io_atu(sv, 1,
- sv->pci.pp.io_size,
- sv->pci.pp.io_base,
- sv->pci.pp.io_bus_addr);
- return 0;
-}
-
-static int pcie_sifive_write_config(struct udevice *bus, pci_dev_t bdf,
- uint offset, ulong value,
- enum pci_size_t size)
-{
- struct pcie_sifive *sv = dev_get_priv(bus);
- void __iomem *va;
- ulong old;
-
- sv_debug(sv, "PCIe CFG write: (b,d,f)=(%2d,%2d,%2d) ",
- PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
- sv_debug(sv, "(addr,val)=(0x%04x, 0x%08lx)\n", offset, value);
-
- if (!pcie_sifive_addr_valid(sv, bdf)) {
- sv_debug(sv, "- out of range\n");
- return 0;
- }
-
- va = pcie_sifive_cfg_outbound_atu(sv, bdf, offset);
- old = readl(va);
- value = pci_conv_size_to_32(old, value, offset, size);
- writel(value, va);
-
- if (sv->pci.num_viewport <= 2)
- pcie_sifive_set_outbound_io_atu(sv, 1,
- sv->pci.pp.io_size,
- sv->pci.pp.io_base,
- sv->pci.pp.io_bus_addr);
+ pcie_sifive_priv_set_state(sv, PCIEX8MGMT_APP_LTSSM_ENABLE,
+ LTSSM_ENABLE_BIT, 1);
return 0;
}
-bool pcie_sifive_set_mode(struct pcie_sifive *sv, enum pcie_sifive_devtype mode)
+static int pcie_sifive_init_port(struct udevice *dev,
+ enum pcie_sifive_devtype mode)
{
+ struct pcie_sifive *sv = dev_get_priv(dev);
int ret;
- pcie_sifive_assert_perstn(sv);
+ /* Power on reset */
+ pcie_sifive_assert_reset(sv);
pcie_sifive_power_on(sv);
- pcie_sifive_deassert_perstn(sv);
+ pcie_sifive_deassert_reset(sv);
- clk_enable(&sv->aux_ck);
+ /* Enable pcieauxclk */
+ ret = clk_enable(&sv->aux_ck);
+ if (ret)
+ dev_err(dev, "unable to enable pcie_aux clock\n");
/*
* assert hold_phy_rst (hold the controller LTSSM in reset
* after power_up_rst_n for register programming with cr_para)
*/
- pcie_sifive_assert_phy_reset(sv);
+ writel(PCIE_PHY_RESET, sv->priv_base + PCIEX8MGMT_APP_HOLD_PHY_RST);
/* deassert power_up_rst_n */
ret = reset_deassert(&sv->reset);
if (ret < 0) {
- pr_err("reset_assert() failed: %d", ret);
- return false;
+ dev_err(dev, "failed to deassert reset");
+ return -EINVAL;
}
pcie_sifive_init_phy(sv);
+ /* disable pcieauxclk */
clk_disable(&sv->aux_ck);
- /* deassert phy reset */
- writel(0x0, sv->priv.iobase + PCIEX8MGMT_APP_HOLD_PHY_RST);
+ /* deassert hold_phy_rst */
+ writel(PCIE_PHY_RESET_DEASSERT,
+ sv->priv_base + PCIEX8MGMT_APP_HOLD_PHY_RST);
/* enable pcieauxclk */
clk_enable(&sv->aux_ck);
/* Set desired mode while core is not operational */
if (mode == SV_PCIE_HOST_TYPE)
- writel(MGMT_MISC_DEVICE_TYPE_RC,
- sv->priv.iobase + MGMT_MISC_DEVICE_TYPE_OFFSET);
+ writel(DEVICE_TYPE_RC,
+ sv->priv_base + PCIEX8MGMT_DEVICE_TYPE);
else
- writel(MGMT_MISC_DEVICE_TYPE_EP,
- sv->priv.iobase + MGMT_MISC_DEVICE_TYPE_OFFSET);
+ writel(DEVICE_TYPE_EP,
+ sv->priv_base + PCIEX8MGMT_DEVICE_TYPE);
/* Confirm desired mode from operational core */
if (pcie_sifive_get_devtype(sv) != mode)
- return false;
+ return -EINVAL;
- sv->mode = mode;
+ pcie_dw_setup_host(&sv->dw);
- return true;
+ if (pcie_sifive_start_link(sv) == -EALREADY)
+ sv_info(sv, "PCIe link is already up\n");
+ else if (pcie_sifive_wait_for_link(sv) == -ETIMEDOUT)
+ return -ETIMEDOUT;
+
+ return 0;
}
static int pcie_sifive_probe(struct udevice *dev)
@@ -678,32 +409,51 @@ static int pcie_sifive_probe(struct udevice *dev)
struct pci_controller *hose = dev_get_uclass_priv(parent);
int err;
- sv->ctrl.iobase = (void __iomem *)sv->ctrl.phys_base;
- sv->priv.iobase = (void __iomem *)sv->priv.phys_base;
+ sv->dw.first_busno = dev_seq(dev);
+ sv->dw.dev = dev;
+
+ err = pcie_sifive_init_port(dev, SV_PCIE_HOST_TYPE);
+ if (err) {
+ sv_info(sv, "Failed to init port.\n");
+ return err;
+ }
- sv->pci.dev = dev;
- sv->pci.pp.root_bus_nr = dev_seq(dev);
+ printf("PCIE-%d: Link up (Gen%d-x%d, Bus%d)\n",
+ dev_seq(dev), pcie_dw_get_link_speed(&sv->dw),
+ pcie_dw_get_link_width(&sv->dw),
+ hose->first_busno);
- sv->pci.pp.io_size = hose->regions[0].size;
- sv->pci.pp.io_base = hose->regions[0].phys_start;
- sv->pci.pp.io_bus_addr = hose->regions[0].bus_start;
+ return pcie_dw_prog_outbound_atu_unroll(&sv->dw,
+ PCIE_ATU_REGION_INDEX0,
+ PCIE_ATU_TYPE_MEM,
+ sv->dw.mem.phys_start,
+ sv->dw.mem.bus_start,
+ sv->dw.mem.size);
+}
+
+static void __iomem *get_fdt_addr(struct udevice *dev, const char *name)
+{
+ fdt_addr_t addr;
- sv->pci.pp.mem_size = hose->regions[1].size;
- sv->pci.pp.mem_base = hose->regions[1].phys_start;
- sv->pci.pp.mem_bus_addr = hose->regions[1].bus_start;
+ addr = dev_read_addr_name(dev, name);
- sv->pci.pp.config.iobase = (void __iomem *)sv->pci.pp.config.phys_base;
- sv->pci.pp.ecam.iobase = (void __iomem *)sv->pci.pp.ecam.phys_base;
+ return (addr == FDT_ADDR_T_NONE) ? NULL : (void __iomem *)addr;
+}
- sv->pci.pp.cfg0_base = sv->pci.pp.config.phys_base;
- sv->pci.pp.va_cfg0_base = (void __iomem *)sv->pci.pp.cfg0_base;
- sv->pci.pp.cfg0_size = SZ_4K;
+static int pcie_sifive_of_to_plat(struct udevice *dev)
+{
+ struct pcie_sifive *sv = dev_get_priv(dev);
+ int err;
- sv->pci.pp.cfg1_base = sv->pci.pp.cfg0_base + sv->pci.pp.cfg0_size;
- sv->pci.pp.va_cfg1_base = (void __iomem *)sv->pci.pp.cfg1_base;
- sv->pci.pp.cfg1_size = SZ_4K;
+ /* get designware DBI base addr */
+ sv->dw.dbi_base = get_fdt_addr(dev, "dbi");
+ if (!sv->dw.dbi_base)
+ return -EINVAL;
- sv->pci.pp.msi_data = sv->pci.pp.cfg1_base + sv->pci.pp.cfg1_size;
+ /* get private control base addr */
+ sv->priv_base = get_fdt_addr(dev, "mgmt");
+ if (!sv->priv_base)
+ return -EINVAL;
gpio_request_by_name(dev, "pwren-gpios", 0, &sv->pwren_gpio,
GPIOD_IS_OUT);
@@ -713,11 +463,11 @@ static int pcie_sifive_probe(struct udevice *dev)
return -EINVAL;
}
- gpio_request_by_name(dev, "perstn-gpios", 0, &sv->perstn_gpio,
+ gpio_request_by_name(dev, "reset-gpios", 0, &sv->reset_gpio,
GPIOD_IS_OUT);
- if (!dm_gpio_is_valid(&sv->perstn_gpio)) {
- sv_info(sv, "perstn_gpio is invalid\n");
+ if (!dm_gpio_is_valid(&sv->reset_gpio)) {
+ sv_info(sv, "reset_gpio is invalid\n");
return -EINVAL;
}
@@ -733,51 +483,12 @@ static int pcie_sifive_probe(struct udevice *dev)
return err;
}
- if (!pcie_sifive_set_mode(sv, SV_PCIE_HOST_TYPE)) {
- sv_info(sv, "Unable to set desired PCIe operation mode\n");
- return -EINVAL;
- }
-
- return pcie_sifive_init_host(sv);
-}
-
-static int pcie_sifive_of_to_plat(struct udevice *dev)
-{
- struct pcie_sifive *sv = dev_get_priv(dev);
-
- sv->pci.dev = dev;
-
- sv->ctrl.phys_base = dev_read_addr_size_name(dev, "dbi",
- &sv->ctrl.iosize);
- if (sv->ctrl.phys_base == FDT_ADDR_T_NONE)
- return -EINVAL;
-
- sv->priv.phys_base = dev_read_addr_size_name(dev, "mgmt",
- &sv->priv.iosize);
- if (sv->priv.phys_base == FDT_ADDR_T_NONE)
- return -EINVAL;
-
- sv->pci.pp.config.phys_base =
- dev_read_addr_size_name(dev, "config",
- &sv->pci.pp.config.iosize);
- if (sv->pci.pp.config.phys_base == FDT_ADDR_T_NONE)
- return -EINVAL;
-
- sv->pci.pp.ecam.phys_base =
- dev_read_addr_size_name(dev, "ecam", &sv->pci.pp.ecam.iosize);
- if (sv->pci.pp.config.phys_base == FDT_ADDR_T_NONE)
- sv->pci.pp.ecam.phys_base = 0;
-
- sv->pci.num_viewport = pcie_sifive_get_property(sv, "num-viewport");
- if (sv->pci.num_viewport == 0)
- sv->pci.num_viewport = 2;
-
return 0;
}
static const struct dm_pci_ops pcie_sifive_ops = {
- .read_config = pcie_sifive_read_config,
- .write_config = pcie_sifive_write_config
+ .read_config = pcie_dw_read_config,
+ .write_config = pcie_dw_write_config,
};
static const struct udevice_id pcie_sifive_ids[] = {
diff --git a/drivers/pci/pcie_sifive.h b/drivers/pci/pcie_sifive.h
deleted file mode 100644
index d12c1f715e..0000000000
--- a/drivers/pci/pcie_sifive.h
+++ /dev/null
@@ -1,374 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * SiFive FU740 DesignWare PCIe Controller
- *
- * Copyright (C) 2020-2021 SiFive, Inc.
- *
- * Based in early part on the i.MX6 PCIe host controller shim which is:
- *
- * Copyright (C) 2013 Kosagi
- * http://www.kosagi.com
- *
- * Based on driver from author: Alan Mikhak <amikhak at wirelessfabric.com>
- */
-
-#ifndef __PCIE_SIFIVE_H__
-#define __PCIE_SIFIVE_H__
-
-#include <clk.h>
-#include <pci.h>
-#include <asm/io.h>
-#include <linux/bitops.h>
-#include <linux/log2.h>
-#include <pci_ep.h>
-#include <pci_ids.h>
-#include <generic-phy.h>
-#include <regmap.h>
-#include <reset.h>
-#include <syscon.h>
-#include <asm-generic/gpio.h>
-
-#define MAX_MSI_IRQS 256
-#define MAX_MSI_IRQS_PER_CTRL 32
-#define MAX_MSI_CTRLS (MAX_MSI_IRQS / MAX_MSI_IRQS_PER_CTRL)
-
-enum pcie_sifive_devtype {
- SV_PCIE_UNKNOWN_TYPE = 0,
- SV_PCIE_ENDPOINT_TYPE = 1,
- SV_PCIE_HOST_TYPE = 3
-};
-
-struct sv_iomem {
- fdt_size_t iosize;
- void __iomem *iobase;
- fdt_addr_t phys_base;
-};
-
-struct pcie_sifive {
- struct {
- struct udevice *dev;
- u32 num_viewport;
- u8 iatu_unroll_enabled;
- struct {
- u8 root_bus_nr;
- u64 cfg0_base;
- void __iomem *va_cfg0_base;
- fdt_size_t cfg0_size;
- u64 cfg1_base;
- void __iomem *va_cfg1_base;
- fdt_size_t cfg1_size;
- u32 io_size;
- u64 io_base;
- u64 io_bus_addr;
- u64 mem_size;
- u64 mem_base;
- u64 mem_bus_addr;
- u64 msi_data;
- u32 num_vectors;
- u32 irq_mask[MAX_MSI_CTRLS];
- struct sv_iomem config;
- struct sv_iomem ecam;
- } pp;
- } pci;
- struct sv_iomem ctrl;
- struct sv_iomem priv;
- enum pcie_sifive_devtype mode;
- int sys_int_pin;
- struct gpio_desc pwren_gpio;
- struct gpio_desc perstn_gpio;
- struct clk aux_ck;
- struct reset_ctl reset;
-};
-
-#define sv_info(sv, fmt, arg...) printf(fmt, ## arg)
-#define sv_warn(sv, fmt, arg...) printf(fmt, ## arg)
-#define sv_debug(sv, fmt, arg...) debug(fmt, ## arg)
-#define sv_err(sv, fmt, arg...) printf(fmt, ## arg)
-
-#define pci_epf_header pci_ep_header
-
-#define VENDOR_ID_MASK GENMASK(15, 0)
-#define DEVICE_ID_SHIFT 16
-
-#ifndef PCI_MSIX_FLAGS
-#define PCI_MSIX_FLAGS 2 /* Message Control */
-#define PCI_MSIX_FLAGS_QSIZE 0x07FF /* Table size */
-#define PCI_MSIX_FLAGS_MASKALL 0x4000 /* Mask all vectors */
-#define PCI_MSIX_FLAGS_ENABLE 0x8000 /* MSI-X enable */
-#endif
-
-#ifndef PCI_REBAR_CAP
-#define PCI_REBAR_CAP 4 /* capability register */
-#define PCI_REBAR_CAP_SIZES 0x00FFFFF0 /* supported BAR sizes */
-#endif
-
-#ifndef PCI_REBAR_CTRL
-#define PCI_REBAR_CTRL 8 /* control register */
-#define PCI_REBAR_CTRL_BAR_IDX 0x00000007 /* BAR index */
-#define PCI_REBAR_CTRL_NBAR_MASK 0x000000E0 /* # of resizable BARs */
-#define PCI_REBAR_CTRL_NBAR_SHIFT 5 /* shift for # of BARs */
-#define PCI_REBAR_CTRL_BAR_SIZE 0x00001F00 /* BAR size */
-#define PCI_REBAR_CTRL_BAR_SHIFT 8 /* shift for BAR size */
-#endif
-
-#define MGMT_MISC_LTSSM_ENABLE_OFFSET 0x10
-#define MGMT_MISC_SYS_INT_OFFSET 0x238
-#define MGMT_MISC_EDMA_XFER_PEND_OFFSET 0x4d0
-#define MGMT_MISC_EDMA_INT_OFFSET 0x630
-#define MGMT_MISC_DEVICE_TYPE_OFFSET 0x708
-
-#define MGMT_MISC_LTSSM_ENABLE_BIT BIT(0)
-#define MGMT_MISC_EDMA_XFER_PEND_BIT BIT(0)
-#define MGMT_MISC_EDMA_INT_BITS (BIT(1) | BIT(0))
-
-#define MGMT_MISC_DEVICE_TYPE_EP 0x0
-#define MGMT_MISC_DEVICE_TYPE_RC 0x4
-
-/* Doorbell Interface */
-#define DBI_OFFSET 0x0
-#define DBI_SIZE 0x1000
-
-/* Doorbell Interface 2 */
-#define DBI2_OFFSET 0x100000
-#define DBI2_SIZE 0x80
-
-/* Address Translation Units */
-#define ATU_OFFSET 0x300000
-#define ATU_SIZE 0x80000
-
-/* DMA Engines */
-#define DMA_OFFSET 0x380000
-#define DMA_SIZE 0x80000
-
-#define DMA_WRITE_ENGINE_EN_OFFSET 0x0C
-
-#define DMA_WRITE_DOORBELL_OFFSET 0x10
-
-#define DMA_READ_ENGINE_EN_OFFSET 0x2C
-
-#define DMA_READ_DOORBELL_OFFSET 0x30
-
-#define DMA_WRITE_INT_STATUS_OFFSET 0x4C
-#define DMA_WRITE_INT_MASK_OFFSET 0x54
-#define DMA_WRITE_INT_CLEAR_OFFSET 0x58
-
-#define DMA_READ_INT_STATUS_OFFSET 0xA0
-#define DMA_READ_INT_MASK_OFFSET 0xA8
-#define DMA_READ_INT_CLEAR_OFFSET 0xAC
-
-#define DMA_WRITE_LL_ERR_EN_OFFSET 0x90
-
-#define DMA_READ_LL_ERR_EN_OFFSET 0xC4
-
-#define DMA_WRITE_CONTROL1_OFFSET 0x200
-#define DMA_WRITE_TRANSFER_SIZE_OFFSET 0x208
-#define DMA_WRITE_SAR_LOW_OFFSET 0x20C
-#define DMA_WRITE_SAR_HI_OFFSET 0x210
-#define DMA_WRITE_DAR_LOW_OFFSET 0x214
-#define DMA_WRITE_DAR_HI_OFFSET 0x218
-
-#define DMA_READ_CONTROL1_OFFSET 0x300
-#define DMA_READ_TRANSFER_SIZE_OFFSET 0x308
-#define DMA_READ_SAR_LOW_OFFSET 0x30C
-#define DMA_READ_SAR_HI_OFFSET 0x310
-#define DMA_READ_DAR_LOW_OFFSET 0x314
-#define DMA_READ_DAR_HI_OFFSET 0x318
-
-#define DMA_CHAN_BIT(chan) (BIT(chan))
-#define DMA_ENABLE_BIT_CHAN(chan) DMA_CHAN_BIT(chan)
-#define DMA_LLLAIE_BIT_CHAN(chan) DMA_CHAN_BIT(chan)
-#define DMA_INT_DONE_BIT_CHAN(chan) DMA_CHAN_BIT(chan)
-#define DMA_INT_ABORT_BIT_CHAN(chan) (BIT((chan) + 16))
-
-/* PCIe Port Logic registers (memory-mapped) */
-#define PL_OFFSET 0x700
-#define PCIE_PL_PFLR (PL_OFFSET + 0x08)
-#define PCIE_PL_PFLR_LINK_STATE (0x3f << 16)
-#define PCIE_PL_PFLR_FORCE_LINK BIT(15)
-
-#define LINK_CONTROL (PL_OFFSET + 0x10)
-#define LINK_MODE(n) ((n) << 16)
-#define LINK_MODE_MASK LINK_MODE(0x3f)
-#define LINK_MODE_1_LANE LINK_MODE(0x1)
-#define LINK_MODE_2_LANES LINK_MODE(0x3)
-#define LINK_MODE_4_LANES LINK_MODE(0x7)
-#define LINK_MODE_8_LANES LINK_MODE(0xf)
-
-#define PHY_DEBUG_R0 (PL_OFFSET + 0x28)
-
-#define PHY_DEBUG_R1 (PL_OFFSET + 0x2c)
-#define PHY_DEBUG_R1_LINK_UP (0x1 << 4)
-#define PHY_DEBUG_R1_LINK_IN_TRAINING (0x1 << 29)
-
-#define LINK_WIDTH_SPEED_CONTROL (PL_OFFSET + 0x10c)
-#define LINK_WIDTH(n) ((n) << 8)
-#define LINK_WIDTH_MASK LINK_WIDTH(0x1f)
-#define LINK_WIDTH_1_LANE LINK_WIDTH(0x1)
-#define LINK_WIDTH_2_LANES LINK_WIDTH(0x2)
-#define LINK_WIDTH_4_LANES LINK_WIDTH(0x4)
-#define LINK_WIDTH_8_LANES LINK_WIDTH(0x8)
-
-#define PHY_STAT (PL_OFFSET + 0x110)
-#define PHY_STAT_ACK_LOC 16
-
-#define PHY_CTRL (PL_OFFSET + 0x114)
-#define PHY_CTRL_DATA_LOC 0
-#define PHY_CTRL_CAP_ADR_LOC 16
-#define PHY_CTRL_CAP_DAT_LOC 17
-#define PHY_CTRL_WR_LOC 18
-#define PHY_CTRL_RD_LOC 19
-
-#define MSI_CTRL_BLOCK_SIZE 12
-#define MSI_CTRL_BLOCK(ctrl) ((ctrl) * MSI_CTRL_BLOCK_SIZE)
-#define MSI_CTRL_INT_ENABLE(ctrl) (0x828 + MSI_CTRL_BLOCK(ctrl))
-#define MSI_CTRL_INT_MASK(ctrl) (0x82c + MSI_CTRL_BLOCK(ctrl))
-#define MSI_CTRL_INT_STATUS(ctrl) (0x830 + MSI_CTRL_BLOCK(ctrl))
-
-#define PCIE_MISC_CONTROL_1 0x8bc
-#define DBI_RO_WR_EN BIT(0)
-
-#define ATU_VIEWPORT 0x900
-#define ATU_REGION_MIN_SIZE BIT(16)
-#define ATU_REGION_INBOUND BIT(31)
-#define ATU_REGION_OUTBOUND 0
-
-#define ATU_VIEWPORT_CTRL_1 0x904
-#define ATU_TYPE_MASK 0xf
-#define ATU_TYPE_MEM 0x0
-#define ATU_TYPE_IO 0x2
-#define ATU_TYPE_CFG0 0x4
-#define ATU_TYPE_CFG1 0x5
-#ifdef CONFIG_PCI_ALMOND_FPGA_REV8
-#define ATU_INCREASE_REGION_SIZE 0
-#else
-#define ATU_INCREASE_REGION_SIZE BIT(13)
-#endif
-
-#define ATU_VIEWPORT_CTRL_2 0x908
-#define ATU_CFG_SHIFT_MODE BIT(28)
-#define ATU_BAR_MATCH_MODE BIT(30)
-#define ATU_ENABLE BIT(31)
-#define ATU_DISABLE (u32)~ATU_ENABLE
-
-#define ATU_MAX_IN 16
-#define ATU_MAX_OUT 16
-
-#define ATU_WAIT_MAX_RETRIES 5
-#define ATU_WAIT 9
-
-/*
- * iATU Unroll-specific register definitions
- * From 4.80 core version the address translation will be made by unroll
- */
-#define ATU_REGION_CTRL1 0x00
-#define ATU_REGION_CTRL2 0x04
-#define ATU_LOWER_BASE 0x08
-#define ATU_UPPER_BASE 0x0C
-#define ATU_LOWER_LIMIT 0x10
-#define ATU_LOWER_TARGET 0x14
-#define ATU_UPPER_TARGET 0x18
-#define ATU_UPPER_LIMIT 0x20
-
-#define ATU_OUTBOUND_REGION(region) ((region) << 9)
-#define ATU_INBOUND_REGION(region) (((region) << 9) | BIT(8))
-
-#define SIFIVE_PCIEAUXGATECFG 0x14
-#define SIFIVE_DEVICESRESETREG 0x28
-
-#define PCIEX8MGMT_PERST_N 0x0
-#define PCIEX8MGMT_APP_LTSSM_ENABLE 0x10
-#define PCIEX8MGMT_APP_HOLD_PHY_RST 0x18
-#define PCIEX8MGMT_DEVICE_TYPE 0x708
-#define PCIEX8MGMT_PHY0_CR_PARA_ADDR 0x860
-#define PCIEX8MGMT_PHY0_CR_PARA_RD_EN 0x870
-#define PCIEX8MGMT_PHY0_CR_PARA_RD_DATA 0x878
-#define PCIEX8MGMT_PHY0_CR_PARA_SEL 0x880
-#define PCIEX8MGMT_PHY0_CR_PARA_WR_DATA 0x888
-#define PCIEX8MGMT_PHY0_CR_PARA_WR_EN 0x890
-#define PCIEX8MGMT_PHY0_CR_PARA_ACK 0x898
-#define PCIEX8MGMT_PHY1_CR_PARA_ADDR 0x8a0
-#define PCIEX8MGMT_PHY1_CR_PARA_RD_EN 0x8b0
-#define PCIEX8MGMT_PHY1_CR_PARA_RD_DATA 0x8b8
-#define PCIEX8MGMT_PHY1_CR_PARA_SEL 0x8c0
-#define PCIEX8MGMT_PHY1_CR_PARA_WR_DATA 0x8c8
-#define PCIEX8MGMT_PHY1_CR_PARA_WR_EN 0x8d0
-#define PCIEX8MGMT_PHY1_CR_PARA_ACK 0x8d8
-
-#define PCIEX8MGMT_LANE_NUM 8
-#define PCIEX8MGMT_LANE 0x1008
-#define PCIEX8MGMT_LANE_OFF 0x100
-#define PCIEX8MGMT_TERM_MODE 0x0e21
-
-/* PCIe Port Logic registers (memory-mapped) */
-#define PL_OFFSET 0x700
-#define PCIE_PL_PFLR (PL_OFFSET + 0x08)
-#define PCIE_PL_PFLR_LINK_STATE_MASK (0x3f << 16)
-#define PCIE_PL_PFLR_FORCE_LINK BIT(15)
-#define PCIE_PHY_DEBUG_R0 (PL_OFFSET + 0x28)
-#define PCIE_PHY_DEBUG_R1 (PL_OFFSET + 0x2c)
-#define PCIE_PL_GEN2_CTRL_OFF (PL_OFFSET + 0x10c)
-#define PCIE_PL_DIRECTED_SPEED_CHANGE_OFF 0x20000
-
-#define PCIE_PHY_CTRL (PL_OFFSET + 0x114)
-#define PCIE_PHY_CTRL_DATA_LOC 0
-#define PCIE_PHY_CTRL_CAP_ADR_LOC 16
-#define PCIE_PHY_CTRL_CAP_DAT_LOC 17
-#define PCIE_PHY_CTRL_WR_LOC 18
-#define PCIE_PHY_CTRL_RD_LOC 19
-
-#define PCIE_PHY_STAT (PL_OFFSET + 0x110)
-#define PCIE_PHY_STAT_ACK_LOC 16
-
-#define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C
-
-/* PCIe Root Complex registers (memory-mapped) */
-#define PCIE_RC_PF0_MSI_CAP 0x50
-#define PCI_MSI_CAP_ID_NEXT_CTRL_REG (PCIE_RC_PF0_MSI_CAP + 0x0)
-
-#define PCIE_RC_PF0_MSIX_CAP 0x0
-
-#define PCIE_DSP_PF0_PCIE_CAP_BASE 0x70
-#define PCIE_RC_LCR (PCIE_DSP_PF0_PCIE_CAP_BASE + 0xc)
-#define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1 0x1
-#define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2 0x2
-#define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN3 0x3
-#define PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK 0xf
-
-#define PCIE_RC_LCSR (PCIE_DSP_PF0_PCIE_CAP_BASE + 0x10)
-
-#define DMA_CONFIG(r) (DMA_OFFSET + (r))
-#define ATU_CONFIG(r) (ATU_OFFSET + (r))
-#define PCI_SHADOW(r) (DBI2_OFFSET + (r))
-#define PCI_CONFIG(r) (DBI_OFFSET + (r))
-#define MSI_CAPABILITIES(r) PCI_CONFIG(PCIE_RC_PF0_MSI_CAP + (r))
-#define MSIX_CAPABILITIES(r) PCI_CONFIG(PCIE_RC_PF0_MSIX_CAP + (r))
-#define PCIE_CAPABILITIES(r) PCI_CONFIG(PCIE_DSP_PF0_PCIE_CAP_BASE + (r))
-
-#define PF0_PCIE_CAP_LINK_CAP PCIE_CAPABILITIES(0xc)
-#define PCIE_LINK_CAP_MAX_SPEED_MASK 0xf
-#define PCIE_LINK_CAP_MAX_SPEED_GEN1 BIT(0)
-#define PCIE_LINK_CAP_MAX_SPEED_GEN2 BIT(1)
-#define PCIE_LINK_CAP_MAX_SPEED_GEN3 BIT(2)
-#define PCIE_LINK_CAP_MAX_SPEED_GEN4 BIT(3)
-
-#define PF0_PCIE_CAP_LINK_CONTROL PCIE_CAPABILITIES(0x10)
-
-#define PF0_PCIE_CAP_LINK_STATUS PCIE_CAPABILITIES(0x12)
-#define PCIE_LINK_STATUS_SPEED_MASK 0xf
-
-#define PCI_CFG0_REGION_OFFSET 0x00000000
-#define PCI_CFG0_REGION_SIZE 0x00001000 /* 2^12 = 4KB */
-#define PCI_CFG1_REGION_OFFSET 0x00001000
-#define PCI_CFG1_REGION_SIZE 0x00001000 /* 2^12 = 4KB */
-#define PCI_MSI_REGION_OFFSET 0x00002000
-#define PCI_MSI_REGION_SIZE 0x00001000 /* 2^12 = 4KB */
-#define PCI_IO_REGION_OFFSET 0x00080000
-#define PCI_IO_REGION_SIZE 0x00010000 /* 2^16 = 64KB */
-#define PCI_MEM_REGION_OFFSET 0x04000000
-#define PCI_MEM_REGION_SIZE 0x04000000 /* 2^26 = 64MB */
-#define PCI_AUTOCFG_REGION_OFFSET 0x08000000
-#define PCI_AUTOCFG_REGION_SIZE 0x08000000 /* 2^27 = 128MB */
-#define PCI_ECAM_REGION_OFFSET 0x10000000
-#define PCI_ECAM_REGION_SIZE 0x10000000 /* 2^28 = 256MB */
-
-#endif /* __PCIE_SIFIVE_H__ */
--
2.31.0
More information about the U-Boot
mailing list