mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-17 17:24:17 +08:00
Merge branch 'remotes/lorenzo/pci/cadence'
- Convert bool in structs to bitfield (Kishon Vijay Abraham I) - Work around J7200 non-PCIe SERDES lane electrical issue that prevents PCIe link training (Nadeem Athani) - Add J7200 PCIe support to j721e (Kishon Vijay Abraham I) - Add AM64 PCIe support to j721e (Kishon Vijay Abraham I) - Add J7200 and AM64 device IDs to endpoint test (Kishon Vijay Abraham I) * remotes/lorenzo/pci/cadence: misc: pci_endpoint_test: Add deviceID for AM64 and J7200 PCI: j721e: Add PCIe support for AM64 PCI: j721e: Add PCIe support for J7200 PCI: cadence: Add quirk flag to set minimum delay in LTSSM Detect.Quiet state PCI: cadence: Use bitfield for *quirk_retrain_flag* instead of bool
This commit is contained in:
commit
2b5a949eea
@ -69,6 +69,8 @@
|
||||
#define FLAG_USE_DMA BIT(0)
|
||||
|
||||
#define PCI_DEVICE_ID_TI_AM654 0xb00c
|
||||
#define PCI_DEVICE_ID_TI_J7200 0xb00f
|
||||
#define PCI_DEVICE_ID_TI_AM64 0xb010
|
||||
#define PCI_DEVICE_ID_LS1088A 0x80c0
|
||||
|
||||
#define is_am654_pci_dev(pdev) \
|
||||
@ -969,6 +971,12 @@ static const struct pci_device_id pci_endpoint_test_tbl[] = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_J721E),
|
||||
.driver_data = (kernel_ulong_t)&j721e_data,
|
||||
},
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_J7200),
|
||||
.driver_data = (kernel_ulong_t)&j721e_data,
|
||||
},
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_AM64),
|
||||
.driver_data = (kernel_ulong_t)&j721e_data,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, pci_endpoint_test_tbl);
|
||||
|
@ -27,6 +27,7 @@
|
||||
#define STATUS_REG_SYS_2 0x508
|
||||
#define STATUS_CLR_REG_SYS_2 0x708
|
||||
#define LINK_DOWN BIT(1)
|
||||
#define J7200_LINK_DOWN BIT(10)
|
||||
|
||||
#define J721E_PCIE_USER_CMD_STATUS 0x4
|
||||
#define LINK_TRAINING_ENABLE BIT(0)
|
||||
@ -57,6 +58,7 @@ struct j721e_pcie {
|
||||
struct cdns_pcie *cdns_pcie;
|
||||
void __iomem *user_cfg_base;
|
||||
void __iomem *intd_cfg_base;
|
||||
u32 linkdown_irq_regfield;
|
||||
};
|
||||
|
||||
enum j721e_pcie_mode {
|
||||
@ -66,7 +68,10 @@ enum j721e_pcie_mode {
|
||||
|
||||
struct j721e_pcie_data {
|
||||
enum j721e_pcie_mode mode;
|
||||
bool quirk_retrain_flag;
|
||||
unsigned int quirk_retrain_flag:1;
|
||||
unsigned int quirk_detect_quiet_flag:1;
|
||||
u32 linkdown_irq_regfield;
|
||||
unsigned int byte_access_allowed:1;
|
||||
};
|
||||
|
||||
static inline u32 j721e_pcie_user_readl(struct j721e_pcie *pcie, u32 offset)
|
||||
@ -98,12 +103,12 @@ static irqreturn_t j721e_pcie_link_irq_handler(int irq, void *priv)
|
||||
u32 reg;
|
||||
|
||||
reg = j721e_pcie_intd_readl(pcie, STATUS_REG_SYS_2);
|
||||
if (!(reg & LINK_DOWN))
|
||||
if (!(reg & pcie->linkdown_irq_regfield))
|
||||
return IRQ_NONE;
|
||||
|
||||
dev_err(dev, "LINK DOWN!\n");
|
||||
|
||||
j721e_pcie_intd_writel(pcie, STATUS_CLR_REG_SYS_2, LINK_DOWN);
|
||||
j721e_pcie_intd_writel(pcie, STATUS_CLR_REG_SYS_2, pcie->linkdown_irq_regfield);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@ -112,7 +117,7 @@ static void j721e_pcie_config_link_irq(struct j721e_pcie *pcie)
|
||||
u32 reg;
|
||||
|
||||
reg = j721e_pcie_intd_readl(pcie, ENABLE_REG_SYS_2);
|
||||
reg |= LINK_DOWN;
|
||||
reg |= pcie->linkdown_irq_regfield;
|
||||
j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_2, reg);
|
||||
}
|
||||
|
||||
@ -284,10 +289,36 @@ static struct pci_ops cdns_ti_pcie_host_ops = {
|
||||
static const struct j721e_pcie_data j721e_pcie_rc_data = {
|
||||
.mode = PCI_MODE_RC,
|
||||
.quirk_retrain_flag = true,
|
||||
.byte_access_allowed = false,
|
||||
.linkdown_irq_regfield = LINK_DOWN,
|
||||
};
|
||||
|
||||
static const struct j721e_pcie_data j721e_pcie_ep_data = {
|
||||
.mode = PCI_MODE_EP,
|
||||
.linkdown_irq_regfield = LINK_DOWN,
|
||||
};
|
||||
|
||||
static const struct j721e_pcie_data j7200_pcie_rc_data = {
|
||||
.mode = PCI_MODE_RC,
|
||||
.quirk_detect_quiet_flag = true,
|
||||
.linkdown_irq_regfield = J7200_LINK_DOWN,
|
||||
.byte_access_allowed = true,
|
||||
};
|
||||
|
||||
static const struct j721e_pcie_data j7200_pcie_ep_data = {
|
||||
.mode = PCI_MODE_EP,
|
||||
.quirk_detect_quiet_flag = true,
|
||||
};
|
||||
|
||||
static const struct j721e_pcie_data am64_pcie_rc_data = {
|
||||
.mode = PCI_MODE_RC,
|
||||
.linkdown_irq_regfield = J7200_LINK_DOWN,
|
||||
.byte_access_allowed = true,
|
||||
};
|
||||
|
||||
static const struct j721e_pcie_data am64_pcie_ep_data = {
|
||||
.mode = PCI_MODE_EP,
|
||||
.linkdown_irq_regfield = J7200_LINK_DOWN,
|
||||
};
|
||||
|
||||
static const struct of_device_id of_j721e_pcie_match[] = {
|
||||
@ -299,6 +330,22 @@ static const struct of_device_id of_j721e_pcie_match[] = {
|
||||
.compatible = "ti,j721e-pcie-ep",
|
||||
.data = &j721e_pcie_ep_data,
|
||||
},
|
||||
{
|
||||
.compatible = "ti,j7200-pcie-host",
|
||||
.data = &j7200_pcie_rc_data,
|
||||
},
|
||||
{
|
||||
.compatible = "ti,j7200-pcie-ep",
|
||||
.data = &j7200_pcie_ep_data,
|
||||
},
|
||||
{
|
||||
.compatible = "ti,am64-pcie-host",
|
||||
.data = &am64_pcie_rc_data,
|
||||
},
|
||||
{
|
||||
.compatible = "ti,am64-pcie-ep",
|
||||
.data = &am64_pcie_ep_data,
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
@ -332,6 +379,7 @@ static int j721e_pcie_probe(struct platform_device *pdev)
|
||||
|
||||
pcie->dev = dev;
|
||||
pcie->mode = mode;
|
||||
pcie->linkdown_irq_regfield = data->linkdown_irq_regfield;
|
||||
|
||||
base = devm_platform_ioremap_resource_byname(pdev, "intd_cfg");
|
||||
if (IS_ERR(base))
|
||||
@ -391,9 +439,11 @@ static int j721e_pcie_probe(struct platform_device *pdev)
|
||||
goto err_get_sync;
|
||||
}
|
||||
|
||||
bridge->ops = &cdns_ti_pcie_host_ops;
|
||||
if (!data->byte_access_allowed)
|
||||
bridge->ops = &cdns_ti_pcie_host_ops;
|
||||
rc = pci_host_bridge_priv(bridge);
|
||||
rc->quirk_retrain_flag = data->quirk_retrain_flag;
|
||||
rc->quirk_detect_quiet_flag = data->quirk_detect_quiet_flag;
|
||||
|
||||
cdns_pcie = &rc->pcie;
|
||||
cdns_pcie->dev = dev;
|
||||
@ -459,6 +509,7 @@ static int j721e_pcie_probe(struct platform_device *pdev)
|
||||
ret = -ENOMEM;
|
||||
goto err_get_sync;
|
||||
}
|
||||
ep->quirk_detect_quiet_flag = data->quirk_detect_quiet_flag;
|
||||
|
||||
cdns_pcie = &ep->pcie;
|
||||
cdns_pcie->dev = dev;
|
||||
|
@ -623,6 +623,10 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
|
||||
ep->irq_pci_addr = CDNS_PCIE_EP_IRQ_PCI_ADDR_NONE;
|
||||
/* Reserve region 0 for IRQs */
|
||||
set_bit(0, &ep->ob_region_map);
|
||||
|
||||
if (ep->quirk_detect_quiet_flag)
|
||||
cdns_pcie_detect_quiet_min_delay_set(&ep->pcie);
|
||||
|
||||
spin_lock_init(&ep->lock);
|
||||
|
||||
return 0;
|
||||
|
@ -498,6 +498,9 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
|
||||
return PTR_ERR(rc->cfg_base);
|
||||
rc->cfg_res = res;
|
||||
|
||||
if (rc->quirk_detect_quiet_flag)
|
||||
cdns_pcie_detect_quiet_min_delay_set(&rc->pcie);
|
||||
|
||||
ret = cdns_pcie_start_link(pcie);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to start link\n");
|
||||
|
@ -7,6 +7,22 @@
|
||||
|
||||
#include "pcie-cadence.h"
|
||||
|
||||
void cdns_pcie_detect_quiet_min_delay_set(struct cdns_pcie *pcie)
|
||||
{
|
||||
u32 delay = 0x3;
|
||||
u32 ltssm_control_cap;
|
||||
|
||||
/*
|
||||
* Set the LTSSM Detect Quiet state min. delay to 2ms.
|
||||
*/
|
||||
ltssm_control_cap = cdns_pcie_readl(pcie, CDNS_PCIE_LTSSM_CONTROL_CAP);
|
||||
ltssm_control_cap = ((ltssm_control_cap &
|
||||
~CDNS_PCIE_DETECT_QUIET_MIN_DELAY_MASK) |
|
||||
CDNS_PCIE_DETECT_QUIET_MIN_DELAY(delay));
|
||||
|
||||
cdns_pcie_writel(pcie, CDNS_PCIE_LTSSM_CONTROL_CAP, ltssm_control_cap);
|
||||
}
|
||||
|
||||
void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 busnr, u8 fn,
|
||||
u32 r, bool is_io,
|
||||
u64 cpu_addr, u64 pci_addr, size_t size)
|
||||
|
@ -189,6 +189,14 @@
|
||||
/* AXI link down register */
|
||||
#define CDNS_PCIE_AT_LINKDOWN (CDNS_PCIE_AT_BASE + 0x0824)
|
||||
|
||||
/* LTSSM Capabilities register */
|
||||
#define CDNS_PCIE_LTSSM_CONTROL_CAP (CDNS_PCIE_LM_BASE + 0x0054)
|
||||
#define CDNS_PCIE_DETECT_QUIET_MIN_DELAY_MASK GENMASK(2, 1)
|
||||
#define CDNS_PCIE_DETECT_QUIET_MIN_DELAY_SHIFT 1
|
||||
#define CDNS_PCIE_DETECT_QUIET_MIN_DELAY(delay) \
|
||||
(((delay) << CDNS_PCIE_DETECT_QUIET_MIN_DELAY_SHIFT) & \
|
||||
CDNS_PCIE_DETECT_QUIET_MIN_DELAY_MASK)
|
||||
|
||||
enum cdns_pcie_rp_bar {
|
||||
RP_BAR_UNDEFINED = -1,
|
||||
RP_BAR0,
|
||||
@ -295,6 +303,7 @@ struct cdns_pcie {
|
||||
* @avail_ib_bar: Satus of RP_BAR0, RP_BAR1 and RP_NO_BAR if it's free or
|
||||
* available
|
||||
* @quirk_retrain_flag: Retrain link as quirk for PCIe Gen2
|
||||
* @quirk_detect_quiet_flag: LTSSM Detect Quiet min delay set as quirk
|
||||
*/
|
||||
struct cdns_pcie_rc {
|
||||
struct cdns_pcie pcie;
|
||||
@ -303,7 +312,8 @@ struct cdns_pcie_rc {
|
||||
u32 vendor_id;
|
||||
u32 device_id;
|
||||
bool avail_ib_bar[CDNS_PCIE_RP_MAX_IB];
|
||||
bool quirk_retrain_flag;
|
||||
unsigned int quirk_retrain_flag:1;
|
||||
unsigned int quirk_detect_quiet_flag:1;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -334,6 +344,7 @@ struct cdns_pcie_epf {
|
||||
* registers fields (RMW) accessible by both remote RC and EP to
|
||||
* minimize time between read and write
|
||||
* @epf: Structure to hold info about endpoint function
|
||||
* @quirk_detect_quiet_flag: LTSSM Detect Quiet min delay set as quirk
|
||||
*/
|
||||
struct cdns_pcie_ep {
|
||||
struct cdns_pcie pcie;
|
||||
@ -348,6 +359,7 @@ struct cdns_pcie_ep {
|
||||
/* protect writing to PCI_STATUS while raising legacy interrupts */
|
||||
spinlock_t lock;
|
||||
struct cdns_pcie_epf *epf;
|
||||
unsigned int quirk_detect_quiet_flag:1;
|
||||
};
|
||||
|
||||
|
||||
@ -508,6 +520,9 @@ static inline int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void cdns_pcie_detect_quiet_min_delay_set(struct cdns_pcie *pcie);
|
||||
|
||||
void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 busnr, u8 fn,
|
||||
u32 r, bool is_io,
|
||||
u64 cpu_addr, u64 pci_addr, size_t size);
|
||||
|
Loading…
Reference in New Issue
Block a user