Commit 2b5a949e authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

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
parents 540267e2 7c52009d
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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);
+56 −5
Original line number Diff line number Diff line
@@ -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;
		}

		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;
+4 −0
Original line number Diff line number Diff line
@@ -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;
+3 −0
Original line number Diff line number Diff line
@@ -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");
+16 −0
Original line number Diff line number Diff line
@@ -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)
Loading