mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 12:57:06 +09:00
PCI: rockchip: rk: Add PCIe udma transfer support
Change-Id: I68b60192a90962e03fe52b907a17234e8567e4b4 Signed-off-by: Simon Xue <xxm@rock-chips.com>
This commit is contained in:
@@ -38,6 +38,37 @@
|
||||
|
||||
#include "../pci.h"
|
||||
#include "pcie-rockchip.h"
|
||||
#include "rockchip-pcie-dma.h"
|
||||
|
||||
static void rk_pcie_start_dma_rk3399(struct dma_trx_obj *obj)
|
||||
{
|
||||
struct rockchip_pcie *rockchip = dev_get_drvdata(obj->dev);
|
||||
struct dma_table *tbl = obj->cur;
|
||||
int chn = tbl->chn;
|
||||
|
||||
rockchip_pcie_write(rockchip, (u32)(tbl->phys_descs & 0xffffffff),
|
||||
PCIE_APB_CORE_UDMA_BASE + 0x14 * chn + 0x04);
|
||||
rockchip_pcie_write(rockchip, (u32)(tbl->phys_descs >> 32),
|
||||
PCIE_APB_CORE_UDMA_BASE + 0x14 * chn + 0x08);
|
||||
rockchip_pcie_write(rockchip, BIT(0) | (tbl->dir << 1),
|
||||
PCIE_APB_CORE_UDMA_BASE + 0x14 * chn + 0x00);
|
||||
}
|
||||
|
||||
static void rk_pcie_config_dma_rk3399(struct dma_table *table)
|
||||
{
|
||||
u32 *desc = table->descs;
|
||||
|
||||
*(desc + 0) = (u32)(table->local & 0xffffffff);
|
||||
*(desc + 1) = (u32)(table->local >> 32);
|
||||
*(desc + 2) = (u32)(table->bus & 0xffffffff);
|
||||
*(desc + 3) = (u32)(table->bus >> 32);
|
||||
*(desc + 4) = 0;
|
||||
*(desc + 5) = 0;
|
||||
*(desc + 6) = table->buf_size;
|
||||
*(desc + 7) = 0;
|
||||
*(desc + 8) = 0;
|
||||
*(desc + 6) |= 1 << 24;
|
||||
}
|
||||
|
||||
static void rockchip_pcie_enable_bw_int(struct rockchip_pcie *rockchip)
|
||||
{
|
||||
@@ -159,6 +190,9 @@ static int rockchip_pcie_rd_other_conf(struct rockchip_pcie *rockchip,
|
||||
{
|
||||
u32 busdev;
|
||||
|
||||
if (rockchip->in_remove)
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
|
||||
busdev = PCIE_ECAM_ADDR(bus->number, PCI_SLOT(devfn),
|
||||
PCI_FUNC(devfn), where);
|
||||
|
||||
@@ -193,6 +227,9 @@ static int rockchip_pcie_wr_other_conf(struct rockchip_pcie *rockchip,
|
||||
{
|
||||
u32 busdev;
|
||||
|
||||
if (rockchip->in_remove)
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
|
||||
busdev = PCIE_ECAM_ADDR(bus->number, PCI_SLOT(devfn),
|
||||
PCI_FUNC(devfn), where);
|
||||
if (!IS_ALIGNED(busdev, size))
|
||||
@@ -299,6 +336,7 @@ static int rockchip_pcie_host_init_port(struct rockchip_pcie *rockchip)
|
||||
struct device *dev = rockchip->dev;
|
||||
int err, i = MAX_LANE_NUM;
|
||||
u32 status;
|
||||
int timeouts = 500;
|
||||
|
||||
gpiod_set_value_cansleep(rockchip->ep_gpio, 0);
|
||||
|
||||
@@ -330,15 +368,26 @@ static int rockchip_pcie_host_init_port(struct rockchip_pcie *rockchip)
|
||||
|
||||
gpiod_set_value_cansleep(rockchip->ep_gpio, 1);
|
||||
|
||||
if (rockchip->wait_ep)
|
||||
timeouts = 10000;
|
||||
|
||||
/* 500ms timeout value should be enough for Gen1/2 training */
|
||||
err = readl_poll_timeout(rockchip->apb_base + PCIE_CLIENT_BASIC_STATUS1,
|
||||
status, PCIE_LINK_UP(status), 20,
|
||||
500 * USEC_PER_MSEC);
|
||||
timeouts * USEC_PER_MSEC);
|
||||
if (err) {
|
||||
dev_err(dev, "PCIe link training gen1 timeout!\n");
|
||||
goto err_power_off_phy;
|
||||
}
|
||||
|
||||
err = readl_poll_timeout(rockchip->apb_base + PCIE_CLIENT_DEBUG_OUT_0,
|
||||
status, PCIE_LINK_IS_L0(status), 20,
|
||||
timeouts * USEC_PER_MSEC);
|
||||
if (err) {
|
||||
dev_err(dev, "LTSSM is not L0!\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
if (rockchip->link_gen == 2) {
|
||||
/*
|
||||
* Enable retrain for gen2. This should be configured only after
|
||||
@@ -370,6 +419,11 @@ static int rockchip_pcie_host_init_port(struct rockchip_pcie *rockchip)
|
||||
}
|
||||
}
|
||||
|
||||
/* disable ltssm */
|
||||
if (rockchip->dma_trx_enabled)
|
||||
rockchip_pcie_write(rockchip, PCIE_CLIENT_LINK_TRAIN_DISABLE,
|
||||
PCIE_CLIENT_CONFIG);
|
||||
|
||||
rockchip_pcie_write(rockchip, ROCKCHIP_VENDOR_ID,
|
||||
PCIE_CORE_CONFIG_VENDOR);
|
||||
rockchip_pcie_write(rockchip,
|
||||
@@ -403,6 +457,33 @@ err_power_off_phy:
|
||||
return err;
|
||||
}
|
||||
|
||||
static inline void
|
||||
rockchip_pcie_handle_dma_interrupt(struct rockchip_pcie *rockchip)
|
||||
{
|
||||
u32 dma_status;
|
||||
struct dma_trx_obj *obj = rockchip->dma_obj;
|
||||
|
||||
dma_status = rockchip_pcie_read(rockchip,
|
||||
PCIE_APB_CORE_UDMA_BASE + PCIE_UDMA_INT_REG);
|
||||
|
||||
/* Core: clear dma interrupt */
|
||||
rockchip_pcie_write(rockchip, dma_status,
|
||||
PCIE_APB_CORE_UDMA_BASE + PCIE_UDMA_INT_REG);
|
||||
|
||||
WARN_ONCE(!(dma_status & 0x3), "dma_status 0x%x\n", dma_status);
|
||||
|
||||
if (dma_status & (1 << 0)) {
|
||||
obj->irq_num++;
|
||||
obj->dma_free = true;
|
||||
}
|
||||
|
||||
if (list_empty(&obj->tbl_list)) {
|
||||
if (obj->dma_free &&
|
||||
obj->loop_count >= obj->loop_count_threshold)
|
||||
complete(&obj->done);
|
||||
}
|
||||
}
|
||||
|
||||
static irqreturn_t rockchip_pcie_subsys_irq_handler(int irq, void *arg)
|
||||
{
|
||||
struct rockchip_pcie *rockchip = arg;
|
||||
@@ -411,9 +492,10 @@ static irqreturn_t rockchip_pcie_subsys_irq_handler(int irq, void *arg)
|
||||
u32 sub_reg;
|
||||
|
||||
reg = rockchip_pcie_read(rockchip, PCIE_CLIENT_INT_STATUS);
|
||||
sub_reg = rockchip_pcie_read(rockchip, PCIE_CORE_INT_STATUS);
|
||||
dev_dbg(dev, "reg = 0x%x, sub_reg = 0x%x\n", reg, sub_reg);
|
||||
if (reg & PCIE_CLIENT_INT_LOCAL) {
|
||||
dev_dbg(dev, "local interrupt received\n");
|
||||
sub_reg = rockchip_pcie_read(rockchip, PCIE_CORE_INT_STATUS);
|
||||
if (sub_reg & PCIE_CORE_INT_PRFPE)
|
||||
dev_dbg(dev, "parity error detected while reading from the PNP receive FIFO RAM\n");
|
||||
|
||||
@@ -463,6 +545,12 @@ static irqreturn_t rockchip_pcie_subsys_irq_handler(int irq, void *arg)
|
||||
rockchip_pcie_clr_bw_int(rockchip);
|
||||
}
|
||||
|
||||
if (reg & PCIE_CLIENT_INT_UDMA) {
|
||||
rockchip_pcie_handle_dma_interrupt(rockchip);
|
||||
rockchip_pcie_write(rockchip, sub_reg, PCIE_CLIENT_INT_STATUS);
|
||||
rockchip_pcie_write(rockchip, reg, PCIE_CLIENT_INT_STATUS);
|
||||
}
|
||||
|
||||
rockchip_pcie_write(rockchip, reg & PCIE_CLIENT_INT_LOCAL,
|
||||
PCIE_CLIENT_INT_STATUS);
|
||||
|
||||
@@ -677,6 +765,8 @@ static void rockchip_pcie_enable_interrupts(struct rockchip_pcie *rockchip)
|
||||
PCIE_CORE_INT_MASK);
|
||||
|
||||
rockchip_pcie_enable_bw_int(rockchip);
|
||||
rockchip_pcie_write(rockchip, PCIE_UDMA_INT_ENABLE_MASK,
|
||||
PCIE_APB_CORE_UDMA_BASE + PCIE_UDMA_INT_ENABLE_REG);
|
||||
}
|
||||
|
||||
static int rockchip_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
|
||||
@@ -815,6 +905,12 @@ static int rockchip_pcie_cfg_atu(struct rockchip_pcie *rockchip)
|
||||
}
|
||||
}
|
||||
|
||||
/* Workaround for PCIe DMA transfer */
|
||||
if (rockchip->dma_trx_enabled) {
|
||||
rockchip_pcie_prog_ob_atu(rockchip, 1, AXI_WRAPPER_MEM_WRITE,
|
||||
32 - 1, rockchip->mem_reserve_start, 0x0);
|
||||
}
|
||||
|
||||
err = rockchip_pcie_prog_ib_atu(rockchip, 2, 32 - 1, 0x0, 0);
|
||||
if (err) {
|
||||
dev_err(dev, "program RC mem inbound ATU failed\n");
|
||||
@@ -850,6 +946,9 @@ static int rockchip_pcie_cfg_atu(struct rockchip_pcie *rockchip)
|
||||
20 - 1, 0, 0);
|
||||
|
||||
rockchip->msg_bus_addr += ((reg_no + offset) << 20);
|
||||
rockchip->msg_region = devm_ioremap(dev, rockchip->msg_bus_addr, SZ_1M);
|
||||
if (!rockchip->msg_region)
|
||||
err = -ENOMEM;
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -858,6 +957,10 @@ static int rockchip_pcie_wait_l2(struct rockchip_pcie *rockchip)
|
||||
u32 value;
|
||||
int err;
|
||||
|
||||
/* Don't enter L2 state when no ep connected */
|
||||
if (rockchip->dma_trx_enabled == 1)
|
||||
return 0;
|
||||
|
||||
/* send PME_TURN_OFF message */
|
||||
writel(0x0, rockchip->msg_region + PCIE_RC_SEND_PME_OFF);
|
||||
|
||||
@@ -873,7 +976,7 @@ static int rockchip_pcie_wait_l2(struct rockchip_pcie *rockchip)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused rockchip_pcie_suspend_noirq(struct device *dev)
|
||||
static int rockchip_pcie_suspend_for_user(struct device *dev)
|
||||
{
|
||||
struct rockchip_pcie *rockchip = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
@@ -889,8 +992,43 @@ static int __maybe_unused rockchip_pcie_suspend_noirq(struct device *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* disable ltssm */
|
||||
rockchip_pcie_write(rockchip, PCIE_CLIENT_LINK_TRAIN_DISABLE,
|
||||
PCIE_CLIENT_CONFIG);
|
||||
|
||||
rockchip_pcie_deinit_phys(rockchip);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rockchip_pcie_resume_for_user(struct device *dev)
|
||||
{
|
||||
struct rockchip_pcie *rockchip = dev_get_drvdata(dev);
|
||||
int err;
|
||||
|
||||
err = rockchip_pcie_host_init_port(rockchip);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = rockchip_pcie_cfg_atu(rockchip);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Need this to enter L1 again */
|
||||
rockchip_pcie_update_txcredit_mui(rockchip);
|
||||
rockchip_pcie_enable_interrupts(rockchip);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused rockchip_pcie_suspend_noirq(struct device *dev)
|
||||
{
|
||||
struct rockchip_pcie *rockchip = dev_get_drvdata(dev);
|
||||
int ret = 0;
|
||||
|
||||
if (!rockchip->dma_trx_enabled)
|
||||
ret = rockchip_pcie_suspend_for_user(dev);
|
||||
|
||||
rockchip_pcie_disable_clocks(rockchip);
|
||||
|
||||
regulator_disable(rockchip->vpcie0v9);
|
||||
@@ -913,29 +1051,101 @@ static int __maybe_unused rockchip_pcie_resume_noirq(struct device *dev)
|
||||
if (err)
|
||||
goto err_disable_0v9;
|
||||
|
||||
err = rockchip_pcie_host_init_port(rockchip);
|
||||
if (!rockchip->dma_trx_enabled)
|
||||
err = rockchip_pcie_resume_for_user(dev);
|
||||
if (err)
|
||||
goto err_pcie_resume;
|
||||
|
||||
err = rockchip_pcie_cfg_atu(rockchip);
|
||||
if (err)
|
||||
goto err_err_deinit_port;
|
||||
|
||||
/* Need this to enter L1 again */
|
||||
rockchip_pcie_update_txcredit_mui(rockchip);
|
||||
rockchip_pcie_enable_interrupts(rockchip);
|
||||
goto err_disable_clocks;
|
||||
|
||||
return 0;
|
||||
|
||||
err_err_deinit_port:
|
||||
rockchip_pcie_deinit_phys(rockchip);
|
||||
err_pcie_resume:
|
||||
err_disable_clocks:
|
||||
rockchip_pcie_disable_clocks(rockchip);
|
||||
err_disable_0v9:
|
||||
regulator_disable(rockchip->vpcie0v9);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int rockchip_pcie_really_probe(struct rockchip_pcie *rockchip)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = rockchip_pcie_host_init_port(rockchip);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
rockchip_pcie_enable_interrupts(rockchip);
|
||||
|
||||
err = rockchip_pcie_cfg_atu(rockchip);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
rockchip->bridge->sysdata = rockchip;
|
||||
rockchip->bridge->ops = &rockchip_pcie_ops;
|
||||
|
||||
return pci_host_probe(rockchip->bridge);
|
||||
}
|
||||
|
||||
static ssize_t pcie_deferred_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
u32 val = 0;
|
||||
int err;
|
||||
struct rockchip_pcie *rockchip = dev_get_drvdata(dev);
|
||||
|
||||
err = kstrtou32(buf, 10, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (val) {
|
||||
rockchip->wait_ep = 1;
|
||||
err = rockchip_pcie_really_probe(rockchip);
|
||||
if (err)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t pcie_reset_ep_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
u32 val = 0;
|
||||
int err;
|
||||
struct rockchip_pcie *rockchip = dev_get_drvdata(dev);
|
||||
struct dma_trx_obj *obj = rockchip->dma_obj;
|
||||
|
||||
dev_info(dev, "loop_cout = %d\n", obj->loop_count);
|
||||
|
||||
err = kstrtou32(buf, 10, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (val == PCIE_USER_UNLINK)
|
||||
rockchip_pcie_suspend_for_user(rockchip->dev);
|
||||
else if (val == PCIE_USER_RELINK)
|
||||
rockchip_pcie_resume_for_user(rockchip->dev);
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_WO(pcie_deferred);
|
||||
static DEVICE_ATTR_WO(pcie_reset_ep);
|
||||
|
||||
static struct attribute *pcie_attrs[] = {
|
||||
&dev_attr_pcie_deferred.attr,
|
||||
&dev_attr_pcie_reset_ep.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct attribute_group pcie_attr_group = {
|
||||
.attrs = pcie_attrs,
|
||||
};
|
||||
|
||||
static int rockchip_pcie_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rockchip_pcie *rockchip;
|
||||
@@ -952,6 +1162,8 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
|
||||
|
||||
rockchip = pci_host_bridge_priv(bridge);
|
||||
|
||||
rockchip->bridge = bridge;
|
||||
|
||||
platform_set_drvdata(pdev, rockchip);
|
||||
rockchip->dev = dev;
|
||||
rockchip->is_rc = true;
|
||||
@@ -970,39 +1182,47 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
|
||||
goto err_set_vpcie;
|
||||
}
|
||||
|
||||
err = rockchip_pcie_host_init_port(rockchip);
|
||||
if (err)
|
||||
goto err_vpcie;
|
||||
|
||||
rockchip_pcie_enable_interrupts(rockchip);
|
||||
|
||||
err = rockchip_pcie_init_irq_domain(rockchip);
|
||||
if (err < 0)
|
||||
goto err_deinit_port;
|
||||
goto err_vpcie;
|
||||
|
||||
err = rockchip_pcie_cfg_atu(rockchip);
|
||||
if (err)
|
||||
goto err_remove_irq_domain;
|
||||
|
||||
rockchip->msg_region = devm_ioremap(dev, rockchip->msg_bus_addr, SZ_1M);
|
||||
if (!rockchip->msg_region) {
|
||||
err = -ENOMEM;
|
||||
goto err_remove_irq_domain;
|
||||
if (rockchip->deferred) {
|
||||
err = sysfs_create_group(&pdev->dev.kobj, &pcie_attr_group);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "SysFS group creation failed\n");
|
||||
goto err_remove_irq_domain;
|
||||
}
|
||||
} else {
|
||||
err = rockchip_pcie_really_probe(rockchip);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "deferred probe failed\n");
|
||||
goto err_deinit_port;
|
||||
}
|
||||
}
|
||||
|
||||
bridge->sysdata = rockchip;
|
||||
bridge->ops = &rockchip_pcie_ops;
|
||||
if (rockchip->dma_trx_enabled == 0)
|
||||
return 0;
|
||||
|
||||
err = pci_host_probe(bridge);
|
||||
if (err < 0)
|
||||
goto err_remove_irq_domain;
|
||||
rockchip->dma_obj = rk_pcie_dma_obj_probe(dev);
|
||||
if (IS_ERR(rockchip->dma_obj)) {
|
||||
dev_err(dev, "failed to prepare dma object\n");
|
||||
err = -EINVAL;
|
||||
goto err_deinit_port;
|
||||
}
|
||||
|
||||
if (rockchip->dma_obj) {
|
||||
rockchip->dma_obj->start_dma_func = rk_pcie_start_dma_rk3399;
|
||||
rockchip->dma_obj->config_dma_func = rk_pcie_config_dma_rk3399;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_remove_irq_domain:
|
||||
irq_domain_remove(rockchip->irq_domain);
|
||||
err_deinit_port:
|
||||
rockchip_pcie_deinit_phys(rockchip);
|
||||
if (rockchip->deferred)
|
||||
sysfs_remove_group(&pdev->dev.kobj, &pcie_attr_group);
|
||||
err_remove_irq_domain:
|
||||
irq_domain_remove(rockchip->irq_domain);
|
||||
err_vpcie:
|
||||
if (!IS_ERR(rockchip->vpcie12v))
|
||||
regulator_disable(rockchip->vpcie12v);
|
||||
@@ -1019,16 +1239,41 @@ static int rockchip_pcie_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct rockchip_pcie *rockchip = dev_get_drvdata(dev);
|
||||
u32 status1, status2;
|
||||
u32 status;
|
||||
struct pci_host_bridge *bridge = pci_host_bridge_from_priv(rockchip);
|
||||
|
||||
status1 = rockchip_pcie_read(rockchip, PCIE_CLIENT_BASIC_STATUS1);
|
||||
status2 = rockchip_pcie_read(rockchip, PCIE_CLIENT_DEBUG_OUT_0);
|
||||
|
||||
if (!PCIE_LINK_UP(status1) || !PCIE_LINK_IS_L0(status2))
|
||||
rockchip->in_remove = 1;
|
||||
|
||||
pci_stop_root_bus(bridge->bus);
|
||||
pci_remove_root_bus(bridge->bus);
|
||||
irq_domain_remove(rockchip->irq_domain);
|
||||
|
||||
/* disable link state */
|
||||
status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LCS);
|
||||
status |= BIT(4);
|
||||
rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS);
|
||||
|
||||
mdelay(1);
|
||||
|
||||
status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LCS);
|
||||
status &= ~BIT(4);
|
||||
rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS);
|
||||
|
||||
rockchip_pcie_deinit_phys(rockchip);
|
||||
|
||||
rockchip_pcie_disable_clocks(rockchip);
|
||||
|
||||
if (rockchip->dma_trx_enabled)
|
||||
rk_pcie_dma_obj_remove(rockchip->dma_obj);
|
||||
|
||||
if (rockchip->deferred)
|
||||
sysfs_remove_group(&pdev->dev.kobj, &pcie_attr_group);
|
||||
|
||||
if (!IS_ERR(rockchip->vpcie12v))
|
||||
regulator_disable(rockchip->vpcie12v);
|
||||
if (!IS_ERR(rockchip->vpcie3v3))
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#define PCIE_CLIENT_CONF_ENABLE HIWORD_UPDATE_BIT(0x0001)
|
||||
#define PCIE_CLIENT_CONF_DISABLE HIWORD_UPDATE(0x0001, 0)
|
||||
#define PCIE_CLIENT_LINK_TRAIN_ENABLE HIWORD_UPDATE_BIT(0x0002)
|
||||
#define PCIE_CLIENT_LINK_TRAIN_DISABLE HIWORD_UPDATE(0x0002, 0x0000)
|
||||
#define PCIE_CLIENT_ARI_ENABLE HIWORD_UPDATE_BIT(0x0008)
|
||||
#define PCIE_CLIENT_CONF_LANE_NUM(x) HIWORD_UPDATE(0x0030, ENCODE_LANES(x))
|
||||
#define PCIE_CLIENT_MODE_RC HIWORD_UPDATE_BIT(0x0040)
|
||||
@@ -39,6 +40,7 @@
|
||||
#define PCIE_CLIENT_GEN_SEL_2 HIWORD_UPDATE_BIT(0x0080)
|
||||
#define PCIE_CLIENT_DEBUG_OUT_0 (PCIE_CLIENT_BASE + 0x3c)
|
||||
#define PCIE_CLIENT_DEBUG_LTSSM_MASK GENMASK(5, 0)
|
||||
#define PCIE_CLIENT_DEBUG_LTSSM_L0 0x10
|
||||
#define PCIE_CLIENT_DEBUG_LTSSM_L1 0x18
|
||||
#define PCIE_CLIENT_DEBUG_LTSSM_L2 0x19
|
||||
#define PCIE_CLIENT_BASIC_STATUS1 (PCIE_CLIENT_BASE + 0x48)
|
||||
@@ -74,7 +76,20 @@
|
||||
PCIE_CLIENT_INT_FATAL_ERR | PCIE_CLIENT_INT_DPA | \
|
||||
PCIE_CLIENT_INT_HOT_RST | PCIE_CLIENT_INT_MSG | \
|
||||
PCIE_CLIENT_INT_LEGACY_DONE | PCIE_CLIENT_INT_LEGACY | \
|
||||
PCIE_CLIENT_INT_PHY)
|
||||
PCIE_CLIENT_INT_PHY | PCIE_CLIENT_INT_UDMA)
|
||||
|
||||
#define PCIE_APB_CORE_UDMA_BASE (BIT(23) | BIT(22) | BIT(21))
|
||||
#define PCIE_CH0_DONE_ENABLE BIT(0)
|
||||
#define PCIE_CH1_DONE_ENABLE BIT(1)
|
||||
#define PCIE_CH0_ERR_ENABLE BIT(8)
|
||||
#define PCIE_CH1_ERR_ENABLE BIT(9)
|
||||
|
||||
#define PCIE_UDMA_INT_REG 0xa0
|
||||
#define PCIE_UDMA_INT_ENABLE_REG 0xa4
|
||||
|
||||
#define PCIE_UDMA_INT_ENABLE_MASK \
|
||||
(PCIE_CH0_DONE_ENABLE | PCIE_CH1_DONE_ENABLE | \
|
||||
PCIE_CH0_ERR_ENABLE | PCIE_CH1_ERR_ENABLE)
|
||||
|
||||
#define PCIE_CORE_CTRL_MGMT_BASE 0x900000
|
||||
#define PCIE_CORE_CTRL (PCIE_CORE_CTRL_MGMT_BASE + 0x000)
|
||||
@@ -185,6 +200,8 @@
|
||||
#define PCIE_ECAM_ADDR(bus, dev, func, reg) \
|
||||
(PCIE_ECAM_BUS(bus) | PCIE_ECAM_DEV(dev) | \
|
||||
PCIE_ECAM_FUNC(func) | PCIE_ECAM_REG(reg))
|
||||
#define PCIE_LINK_IS_L0(x) \
|
||||
(((x) & PCIE_CLIENT_DEBUG_LTSSM_MASK) == PCIE_CLIENT_DEBUG_LTSSM_L0)
|
||||
#define PCIE_LINK_IS_L2(x) \
|
||||
(((x) & PCIE_CLIENT_DEBUG_LTSSM_MASK) == PCIE_CLIENT_DEBUG_LTSSM_L2)
|
||||
#define PCIE_LINK_UP(x) \
|
||||
@@ -275,6 +292,9 @@
|
||||
(((c) << ((b) * 8 + 5)) & \
|
||||
ROCKCHIP_PCIE_CORE_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b))
|
||||
|
||||
#define PCIE_USER_RELINK 0x1
|
||||
#define PCIE_USER_UNLINK 0x2
|
||||
|
||||
struct rockchip_pcie {
|
||||
void __iomem *reg_base; /* DT axi-base */
|
||||
void __iomem *apb_base; /* DT apb-base */
|
||||
@@ -306,6 +326,15 @@ struct rockchip_pcie {
|
||||
phys_addr_t msg_bus_addr;
|
||||
bool is_rc;
|
||||
struct resource *mem_res;
|
||||
phys_addr_t mem_reserve_start;
|
||||
size_t mem_reserve_size;
|
||||
int dma_trx_enabled;
|
||||
int deferred;
|
||||
int wait_ep;
|
||||
struct dma_trx_obj *dma_obj;
|
||||
struct list_head resources;
|
||||
struct pci_host_bridge *bridge;
|
||||
int in_remove;
|
||||
};
|
||||
|
||||
static u32 rockchip_pcie_read(struct rockchip_pcie *rockchip, u32 reg)
|
||||
|
||||
Reference in New Issue
Block a user