Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 442ec4c0 authored by Kishon Vijay Abraham I's avatar Kishon Vijay Abraham I Committed by Bjorn Helgaas
Browse files

PCI: dwc: all: Split struct pcie_port into host-only and core structures



Keep only the host-specific members in struct pcie_port and move the common
members (i.e common to both host and endpoint) to struct dw_pcie.  This is
in preparation for adding endpoint mode support to designware driver.

While at that also fix checkpatch warnings.

Signed-off-by: default avatarKishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
CC: Jingoo Han <jingoohan1@gmail.com>
CC: Richard Zhu <hongxing.zhu@nxp.com>
CC: Lucas Stach <l.stach@pengutronix.de>
CC: Murali Karicheri <m-karicheri2@ti.com>
CC: Minghuan Lian <minghuan.Lian@freescale.com>
CC: Mingkai Hu <mingkai.hu@freescale.com>
CC: Roy Zang <tie-fei.zang@freescale.com>
CC: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
CC: Niklas Cassel <niklas.cassel@axis.com>
CC: Jesper Nilsson <jesper.nilsson@axis.com>
CC: Joao Pinto <Joao.Pinto@synopsys.com>
CC: Zhou Wang <wangzhou1@hisilicon.com>
CC: Gabriele Paoloni <gabriele.paoloni@huawei.com>
CC: Stanimir Varbanov <svarbanov@mm-sol.com>
CC: Pratyush Anand <pratyush.anand@gmail.com>
parent 40f67fb2
Loading
Loading
Loading
Loading
+48 −32
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@
#define EXP_CAP_ID_OFFSET				0x70

struct dra7xx_pcie {
	struct pcie_port	pp;
	struct dw_pcie		*pci;
	void __iomem		*base;		/* DT ti_conf */
	int			phy_count;	/* DT phy-names count */
	struct phy		**phy;
@@ -75,7 +75,7 @@ struct dra7xx_pcie {
	struct irq_domain	*irq_domain;
};

#define to_dra7xx_pcie(x)	container_of((x), struct dra7xx_pcie, pp)
#define to_dra7xx_pcie(x)	dev_get_drvdata((x)->dev)

static inline u32 dra7xx_pcie_readl(struct dra7xx_pcie *pcie, u32 offset)
{
@@ -88,9 +88,9 @@ static inline void dra7xx_pcie_writel(struct dra7xx_pcie *pcie, u32 offset,
	writel(value, pcie->base + offset);
}

static int dra7xx_pcie_link_up(struct pcie_port *pp)
static int dra7xx_pcie_link_up(struct dw_pcie *pci)
{
	struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pp);
	struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci);
	u32 reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_PHY_CS);

	return !!(reg & LINK_UP);
@@ -98,32 +98,32 @@ static int dra7xx_pcie_link_up(struct pcie_port *pp)

static int dra7xx_pcie_establish_link(struct dra7xx_pcie *dra7xx)
{
	struct pcie_port *pp = &dra7xx->pp;
	struct device *dev = pp->dev;
	struct dw_pcie *pci = dra7xx->pci;
	struct device *dev = pci->dev;
	u32 reg;
	u32 exp_cap_off = EXP_CAP_ID_OFFSET;

	if (dw_pcie_link_up(pp)) {
	if (dw_pcie_link_up(pci)) {
		dev_err(dev, "link is already up\n");
		return 0;
	}

	if (dra7xx->link_gen == 1) {
		dw_pcie_read(pp->dbi_base + exp_cap_off + PCI_EXP_LNKCAP,
		dw_pcie_read(pci->dbi_base + exp_cap_off + PCI_EXP_LNKCAP,
			     4, &reg);
		if ((reg & PCI_EXP_LNKCAP_SLS) != PCI_EXP_LNKCAP_SLS_2_5GB) {
			reg &= ~((u32)PCI_EXP_LNKCAP_SLS);
			reg |= PCI_EXP_LNKCAP_SLS_2_5GB;
			dw_pcie_write(pp->dbi_base + exp_cap_off +
			dw_pcie_write(pci->dbi_base + exp_cap_off +
				      PCI_EXP_LNKCAP, 4, reg);
		}

		dw_pcie_read(pp->dbi_base + exp_cap_off + PCI_EXP_LNKCTL2,
		dw_pcie_read(pci->dbi_base + exp_cap_off + PCI_EXP_LNKCTL2,
			     2, &reg);
		if ((reg & PCI_EXP_LNKCAP_SLS) != PCI_EXP_LNKCAP_SLS_2_5GB) {
			reg &= ~((u32)PCI_EXP_LNKCAP_SLS);
			reg |= PCI_EXP_LNKCAP_SLS_2_5GB;
			dw_pcie_write(pp->dbi_base + exp_cap_off +
			dw_pcie_write(pci->dbi_base + exp_cap_off +
				      PCI_EXP_LNKCTL2, 2, reg);
		}
	}
@@ -132,7 +132,7 @@ static int dra7xx_pcie_establish_link(struct dra7xx_pcie *dra7xx)
	reg |= LTSSM_EN;
	dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD, reg);

	return dw_pcie_wait_for_link(pp);
	return dw_pcie_wait_for_link(pci);
}

static void dra7xx_pcie_enable_interrupts(struct dra7xx_pcie *dra7xx)
@@ -149,7 +149,8 @@ static void dra7xx_pcie_enable_interrupts(struct dra7xx_pcie *dra7xx)

static void dra7xx_pcie_host_init(struct pcie_port *pp)
{
	struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pp);
	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
	struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci);

	pp->io_base &= DRA7XX_CPU_TO_BUS_ADDR;
	pp->mem_base &= DRA7XX_CPU_TO_BUS_ADDR;
@@ -163,8 +164,7 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp)
	dra7xx_pcie_enable_interrupts(dra7xx);
}

static struct pcie_host_ops dra7xx_pcie_host_ops = {
	.link_up = dra7xx_pcie_link_up,
static struct dw_pcie_host_ops dra7xx_pcie_host_ops = {
	.host_init = dra7xx_pcie_host_init,
};

@@ -183,8 +183,9 @@ static const struct irq_domain_ops intx_domain_ops = {

static int dra7xx_pcie_init_irq_domain(struct pcie_port *pp)
{
	struct device *dev = pp->dev;
	struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pp);
	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
	struct device *dev = pci->dev;
	struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci);
	struct device_node *node = dev->of_node;
	struct device_node *pcie_intc_node =  of_get_next_child(node, NULL);

@@ -206,7 +207,8 @@ static int dra7xx_pcie_init_irq_domain(struct pcie_port *pp)
static irqreturn_t dra7xx_pcie_msi_irq_handler(int irq, void *arg)
{
	struct dra7xx_pcie *dra7xx = arg;
	struct pcie_port *pp = &dra7xx->pp;
	struct dw_pcie *pci = dra7xx->pci;
	struct pcie_port *pp = &pci->pp;
	u32 reg;

	reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI);
@@ -233,7 +235,8 @@ static irqreturn_t dra7xx_pcie_msi_irq_handler(int irq, void *arg)
static irqreturn_t dra7xx_pcie_irq_handler(int irq, void *arg)
{
	struct dra7xx_pcie *dra7xx = arg;
	struct device *dev = dra7xx->pp.dev;
	struct dw_pcie *pci = dra7xx->pci;
	struct device *dev = pci->dev;
	u32 reg;

	reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MAIN);
@@ -288,8 +291,9 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
				       struct platform_device *pdev)
{
	int ret;
	struct pcie_port *pp = &dra7xx->pp;
	struct device *dev = pp->dev;
	struct dw_pcie *pci = dra7xx->pci;
	struct pcie_port *pp = &pci->pp;
	struct device *dev = pci->dev;
	struct resource *res;

	pp->irq = platform_get_irq(pdev, 1);
@@ -311,8 +315,8 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
		return ret;

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rc_dbics");
	pp->dbi_base = devm_ioremap(dev, res->start, resource_size(res));
	if (!pp->dbi_base)
	pci->dbi_base = devm_ioremap(dev, res->start, resource_size(res));
	if (!pci->dbi_base)
		return -ENOMEM;

	ret = dw_pcie_host_init(pp);
@@ -324,6 +328,10 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
	return 0;
}

static const struct dw_pcie_ops dw_pcie_ops = {
	.link_up = dra7xx_pcie_link_up,
};

static void dra7xx_pcie_disable_phy(struct dra7xx_pcie *dra7xx)
{
	int phy_count = dra7xx->phy_count;
@@ -373,8 +381,9 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
	struct phy **phy;
	void __iomem *base;
	struct resource *res;
	struct dra7xx_pcie *dra7xx;
	struct dw_pcie *pci;
	struct pcie_port *pp;
	struct dra7xx_pcie *dra7xx;
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	char name[10];
@@ -384,8 +393,14 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
	if (!dra7xx)
		return -ENOMEM;

	pp = &dra7xx->pp;
	pp->dev = dev;
	pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
	if (!pci)
		return -ENOMEM;

	pci->dev = dev;
	pci->ops = &dw_pcie_ops;

	pp = &pci->pp;
	pp->ops = &dra7xx_pcie_host_ops;

	irq = platform_get_irq(pdev, 0);
@@ -425,6 +440,7 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)

	dra7xx->base = base;
	dra7xx->phy = phy;
	dra7xx->pci = pci;
	dra7xx->phy_count = phy_count;

	ret = dra7xx_pcie_enable_phy(dra7xx);
@@ -477,13 +493,13 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
static int dra7xx_pcie_suspend(struct device *dev)
{
	struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev);
	struct pcie_port *pp = &dra7xx->pp;
	struct dw_pcie *pci = dra7xx->pci;
	u32 val;

	/* clear MSE */
	val = dw_pcie_readl_rc(pp, PCI_COMMAND);
	val = dw_pcie_readl_dbi(pci, PCI_COMMAND);
	val &= ~PCI_COMMAND_MEMORY;
	dw_pcie_writel_rc(pp, PCI_COMMAND, val);
	dw_pcie_writel_dbi(pci, PCI_COMMAND, val);

	return 0;
}
@@ -491,13 +507,13 @@ static int dra7xx_pcie_suspend(struct device *dev)
static int dra7xx_pcie_resume(struct device *dev)
{
	struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev);
	struct pcie_port *pp = &dra7xx->pp;
	struct dw_pcie *pci = dra7xx->pci;
	u32 val;

	/* set MSE */
	val = dw_pcie_readl_rc(pp, PCI_COMMAND);
	val = dw_pcie_readl_dbi(pci, PCI_COMMAND);
	val |= PCI_COMMAND_MEMORY;
	dw_pcie_writel_rc(pp, PCI_COMMAND, val);
	dw_pcie_writel_dbi(pci, PCI_COMMAND, val);

	return 0;
}
+46 −32
Original line number Diff line number Diff line
@@ -26,10 +26,10 @@

#include "pcie-designware.h"

#define to_exynos_pcie(x)	container_of(x, struct exynos_pcie, pp)
#define to_exynos_pcie(x)	dev_get_drvdata((x)->dev)

struct exynos_pcie {
	struct pcie_port	pp;
	struct dw_pcie		*pci;
	void __iomem		*elbi_base;	/* DT 0th resource */
	void __iomem		*phy_base;	/* DT 1st resource */
	void __iomem		*block_base;	/* DT 2nd resource */
@@ -297,8 +297,8 @@ static void exynos_pcie_init_phy(struct exynos_pcie *exynos_pcie)

static void exynos_pcie_assert_reset(struct exynos_pcie *exynos_pcie)
{
	struct pcie_port *pp = &exynos_pcie->pp;
	struct device *dev = pp->dev;
	struct dw_pcie *pci = exynos_pcie->pci;
	struct device *dev = pci->dev;

	if (exynos_pcie->reset_gpio >= 0)
		devm_gpio_request_one(dev, exynos_pcie->reset_gpio,
@@ -307,11 +307,12 @@ static void exynos_pcie_assert_reset(struct exynos_pcie *exynos_pcie)

static int exynos_pcie_establish_link(struct exynos_pcie *exynos_pcie)
{
	struct pcie_port *pp = &exynos_pcie->pp;
	struct device *dev = pp->dev;
	struct dw_pcie *pci = exynos_pcie->pci;
	struct pcie_port *pp = &pci->pp;
	struct device *dev = pci->dev;
	u32 val;

	if (dw_pcie_link_up(pp)) {
	if (dw_pcie_link_up(pci)) {
		dev_err(dev, "Link already up\n");
		return 0;
	}
@@ -336,7 +337,7 @@ static int exynos_pcie_establish_link(struct exynos_pcie *exynos_pcie)
			  PCIE_APP_LTSSM_ENABLE);

	/* check if the link is up or not */
	if (!dw_pcie_wait_for_link(pp))
	if (!dw_pcie_wait_for_link(pci))
		return 0;

	while (exynos_phy_readl(exynos_pcie, PCIE_PHY_PLL_LOCKED) == 0) {
@@ -376,14 +377,16 @@ static irqreturn_t exynos_pcie_irq_handler(int irq, void *arg)
static irqreturn_t exynos_pcie_msi_irq_handler(int irq, void *arg)
{
	struct exynos_pcie *exynos_pcie = arg;
	struct pcie_port *pp = &exynos_pcie->pp;
	struct dw_pcie *pci = exynos_pcie->pci;
	struct pcie_port *pp = &pci->pp;

	return dw_handle_msi_irq(pp);
}

static void exynos_pcie_msi_init(struct exynos_pcie *exynos_pcie)
{
	struct pcie_port *pp = &exynos_pcie->pp;
	struct dw_pcie *pci = exynos_pcie->pci;
	struct pcie_port *pp = &pci->pp;
	u32 val;

	dw_pcie_msi_init(pp);
@@ -402,34 +405,35 @@ static void exynos_pcie_enable_interrupts(struct exynos_pcie *exynos_pcie)
		exynos_pcie_msi_init(exynos_pcie);
}

static u32 exynos_pcie_readl_rc(struct pcie_port *pp, u32 reg)
static u32 exynos_pcie_readl_dbi(struct dw_pcie *pci, u32 reg)
{
	struct exynos_pcie *exynos_pcie = to_exynos_pcie(pp);
	struct exynos_pcie *exynos_pcie = to_exynos_pcie(pci);
	u32 val;

	exynos_pcie_sideband_dbi_r_mode(exynos_pcie, true);
	val = readl(pp->dbi_base + reg);
	val = readl(pci->dbi_base + reg);
	exynos_pcie_sideband_dbi_r_mode(exynos_pcie, false);
	return val;
}

static void exynos_pcie_writel_rc(struct pcie_port *pp, u32 reg, u32 val)
static void exynos_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val)
{
	struct exynos_pcie *exynos_pcie = to_exynos_pcie(pp);
	struct exynos_pcie *exynos_pcie = to_exynos_pcie(pci);

	exynos_pcie_sideband_dbi_w_mode(exynos_pcie, true);
	writel(val, pp->dbi_base + reg);
	writel(val, pci->dbi_base + reg);
	exynos_pcie_sideband_dbi_w_mode(exynos_pcie, false);
}

static int exynos_pcie_rd_own_conf(struct pcie_port *pp, int where, int size,
				u32 *val)
{
	struct exynos_pcie *exynos_pcie = to_exynos_pcie(pp);
	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
	struct exynos_pcie *exynos_pcie = to_exynos_pcie(pci);
	int ret;

	exynos_pcie_sideband_dbi_r_mode(exynos_pcie, true);
	ret = dw_pcie_read(pp->dbi_base + where, size, val);
	ret = dw_pcie_read(pci->dbi_base + where, size, val);
	exynos_pcie_sideband_dbi_r_mode(exynos_pcie, false);
	return ret;
}
@@ -437,18 +441,19 @@ static int exynos_pcie_rd_own_conf(struct pcie_port *pp, int where, int size,
static int exynos_pcie_wr_own_conf(struct pcie_port *pp, int where, int size,
				u32 val)
{
	struct exynos_pcie *exynos_pcie = to_exynos_pcie(pp);
	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
	struct exynos_pcie *exynos_pcie = to_exynos_pcie(pci);
	int ret;

	exynos_pcie_sideband_dbi_w_mode(exynos_pcie, true);
	ret = dw_pcie_write(pp->dbi_base + where, size, val);
	ret = dw_pcie_write(pci->dbi_base + where, size, val);
	exynos_pcie_sideband_dbi_w_mode(exynos_pcie, false);
	return ret;
}

static int exynos_pcie_link_up(struct pcie_port *pp)
static int exynos_pcie_link_up(struct dw_pcie *pci)
{
	struct exynos_pcie *exynos_pcie = to_exynos_pcie(pp);
	struct exynos_pcie *exynos_pcie = to_exynos_pcie(pci);
	u32 val;

	val = exynos_elb_readl(exynos_pcie, PCIE_ELBI_RDLH_LINKUP);
@@ -460,26 +465,25 @@ static int exynos_pcie_link_up(struct pcie_port *pp)

static void exynos_pcie_host_init(struct pcie_port *pp)
{
	struct exynos_pcie *exynos_pcie = to_exynos_pcie(pp);
	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
	struct exynos_pcie *exynos_pcie = to_exynos_pcie(pci);

	exynos_pcie_establish_link(exynos_pcie);
	exynos_pcie_enable_interrupts(exynos_pcie);
}

static struct pcie_host_ops exynos_pcie_host_ops = {
	.readl_rc = exynos_pcie_readl_rc,
	.writel_rc = exynos_pcie_writel_rc,
static struct dw_pcie_host_ops exynos_pcie_host_ops = {
	.rd_own_conf = exynos_pcie_rd_own_conf,
	.wr_own_conf = exynos_pcie_wr_own_conf,
	.link_up = exynos_pcie_link_up,
	.host_init = exynos_pcie_host_init,
};

static int __init exynos_add_pcie_port(struct exynos_pcie *exynos_pcie,
				       struct platform_device *pdev)
{
	struct pcie_port *pp = &exynos_pcie->pp;
	struct device *dev = pp->dev;
	struct dw_pcie *pci = exynos_pcie->pci;
	struct pcie_port *pp = &pci->pp;
	struct device *dev = &pdev->dev;
	int ret;

	pp->irq = platform_get_irq(pdev, 1);
@@ -523,11 +527,17 @@ static int __init exynos_add_pcie_port(struct exynos_pcie *exynos_pcie,
	return 0;
}

static const struct dw_pcie_ops dw_pcie_ops = {
	.readl_dbi = exynos_pcie_readl_dbi,
	.writel_dbi = exynos_pcie_writel_dbi,
	.link_up = exynos_pcie_link_up,
};

static int __init exynos_pcie_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct dw_pcie *pci;
	struct exynos_pcie *exynos_pcie;
	struct pcie_port *pp;
	struct device_node *np = dev->of_node;
	struct resource *elbi_base;
	struct resource *phy_base;
@@ -538,8 +548,12 @@ static int __init exynos_pcie_probe(struct platform_device *pdev)
	if (!exynos_pcie)
		return -ENOMEM;

	pp = &exynos_pcie->pp;
	pp->dev = dev;
	pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
	if (!pci)
		return -ENOMEM;

	pci->dev = dev;
	pci->ops = &dw_pcie_ops;

	exynos_pcie->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0);

+69 −59
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@

#include "pcie-designware.h"

#define to_imx6_pcie(x)	container_of(x, struct imx6_pcie, pp)
#define to_imx6_pcie(x)	dev_get_drvdata((x)->dev)

enum imx6_pcie_variants {
	IMX6Q,
@@ -39,7 +39,7 @@ enum imx6_pcie_variants {
};

struct imx6_pcie {
	struct pcie_port	pp;	/* pp.dbi_base is DT 0th resource */
	struct dw_pcie		*pci;
	int			reset_gpio;
	bool			gpio_active_high;
	struct clk		*pcie_bus;
@@ -97,13 +97,13 @@ struct imx6_pcie {

static int pcie_phy_poll_ack(struct imx6_pcie *imx6_pcie, int exp_val)
{
	struct pcie_port *pp = &imx6_pcie->pp;
	struct dw_pcie *pci = imx6_pcie->pci;
	u32 val;
	u32 max_iterations = 10;
	u32 wait_counter = 0;

	do {
		val = dw_pcie_readl_rc(pp, PCIE_PHY_STAT);
		val = dw_pcie_readl_dbi(pci, PCIE_PHY_STAT);
		val = (val >> PCIE_PHY_STAT_ACK_LOC) & 0x1;
		wait_counter++;

@@ -118,22 +118,22 @@ static int pcie_phy_poll_ack(struct imx6_pcie *imx6_pcie, int exp_val)

static int pcie_phy_wait_ack(struct imx6_pcie *imx6_pcie, int addr)
{
	struct pcie_port *pp = &imx6_pcie->pp;
	struct dw_pcie *pci = imx6_pcie->pci;
	u32 val;
	int ret;

	val = addr << PCIE_PHY_CTRL_DATA_LOC;
	dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, val);
	dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, val);

	val |= (0x1 << PCIE_PHY_CTRL_CAP_ADR_LOC);
	dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, val);
	dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, val);

	ret = pcie_phy_poll_ack(imx6_pcie, 1);
	if (ret)
		return ret;

	val = addr << PCIE_PHY_CTRL_DATA_LOC;
	dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, val);
	dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, val);

	return pcie_phy_poll_ack(imx6_pcie, 0);
}
@@ -141,7 +141,7 @@ static int pcie_phy_wait_ack(struct imx6_pcie *imx6_pcie, int addr)
/* Read from the 16-bit PCIe PHY control registers (not memory-mapped) */
static int pcie_phy_read(struct imx6_pcie *imx6_pcie, int addr, int *data)
{
	struct pcie_port *pp = &imx6_pcie->pp;
	struct dw_pcie *pci = imx6_pcie->pci;
	u32 val, phy_ctl;
	int ret;

@@ -151,24 +151,24 @@ static int pcie_phy_read(struct imx6_pcie *imx6_pcie, int addr, int *data)

	/* assert Read signal */
	phy_ctl = 0x1 << PCIE_PHY_CTRL_RD_LOC;
	dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, phy_ctl);
	dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, phy_ctl);

	ret = pcie_phy_poll_ack(imx6_pcie, 1);
	if (ret)
		return ret;

	val = dw_pcie_readl_rc(pp, PCIE_PHY_STAT);
	val = dw_pcie_readl_dbi(pci, PCIE_PHY_STAT);
	*data = val & 0xffff;

	/* deassert Read signal */
	dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, 0x00);
	dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, 0x00);

	return pcie_phy_poll_ack(imx6_pcie, 0);
}

static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, int data)
{
	struct pcie_port *pp = &imx6_pcie->pp;
	struct dw_pcie *pci = imx6_pcie->pci;
	u32 var;
	int ret;

@@ -179,11 +179,11 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, int data)
		return ret;

	var = data << PCIE_PHY_CTRL_DATA_LOC;
	dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, var);
	dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, var);

	/* capture data */
	var |= (0x1 << PCIE_PHY_CTRL_CAP_DAT_LOC);
	dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, var);
	dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, var);

	ret = pcie_phy_poll_ack(imx6_pcie, 1);
	if (ret)
@@ -191,7 +191,7 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, int data)

	/* deassert cap data */
	var = data << PCIE_PHY_CTRL_DATA_LOC;
	dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, var);
	dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, var);

	/* wait for ack de-assertion */
	ret = pcie_phy_poll_ack(imx6_pcie, 0);
@@ -200,7 +200,7 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, int data)

	/* assert wr signal */
	var = 0x1 << PCIE_PHY_CTRL_WR_LOC;
	dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, var);
	dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, var);

	/* wait for ack */
	ret = pcie_phy_poll_ack(imx6_pcie, 1);
@@ -209,14 +209,14 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, int data)

	/* deassert wr signal */
	var = data << PCIE_PHY_CTRL_DATA_LOC;
	dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, var);
	dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, var);

	/* wait for ack de-assertion */
	ret = pcie_phy_poll_ack(imx6_pcie, 0);
	if (ret)
		return ret;

	dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, 0x0);
	dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, 0x0);

	return 0;
}
@@ -247,7 +247,7 @@ static int imx6q_pcie_abort_handler(unsigned long addr,

static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
{
	struct pcie_port *pp = &imx6_pcie->pp;
	struct dw_pcie *pci = imx6_pcie->pci;
	u32 val, gpr1, gpr12;

	switch (imx6_pcie->variant) {
@@ -284,10 +284,10 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)

		if ((gpr1 & IMX6Q_GPR1_PCIE_REF_CLK_EN) &&
		    (gpr12 & IMX6Q_GPR12_PCIE_CTL_2)) {
			val = dw_pcie_readl_rc(pp, PCIE_PL_PFLR);
			val = dw_pcie_readl_dbi(pci, PCIE_PL_PFLR);
			val &= ~PCIE_PL_PFLR_LINK_STATE_MASK;
			val |= PCIE_PL_PFLR_FORCE_LINK;
			dw_pcie_writel_rc(pp, PCIE_PL_PFLR, val);
			dw_pcie_writel_dbi(pci, PCIE_PL_PFLR, val);

			regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
					   IMX6Q_GPR12_PCIE_CTL_2, 0 << 10);
@@ -303,8 +303,8 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)

static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
{
	struct pcie_port *pp = &imx6_pcie->pp;
	struct device *dev = pp->dev;
	struct dw_pcie *pci = imx6_pcie->pci;
	struct device *dev = pci->dev;
	int ret = 0;

	switch (imx6_pcie->variant) {
@@ -340,8 +340,8 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)

static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
{
	struct pcie_port *pp = &imx6_pcie->pp;
	struct device *dev = pp->dev;
	struct dw_pcie *pci = imx6_pcie->pci;
	struct device *dev = pci->dev;
	int ret;

	ret = clk_prepare_enable(imx6_pcie->pcie_phy);
@@ -440,28 +440,28 @@ static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie)

static int imx6_pcie_wait_for_link(struct imx6_pcie *imx6_pcie)
{
	struct pcie_port *pp = &imx6_pcie->pp;
	struct device *dev = pp->dev;
	struct dw_pcie *pci = imx6_pcie->pci;
	struct device *dev = pci->dev;

	/* check if the link is up or not */
	if (!dw_pcie_wait_for_link(pp))
	if (!dw_pcie_wait_for_link(pci))
		return 0;

	dev_dbg(dev, "DEBUG_R0: 0x%08x, DEBUG_R1: 0x%08x\n",
		dw_pcie_readl_rc(pp, PCIE_PHY_DEBUG_R0),
		dw_pcie_readl_rc(pp, PCIE_PHY_DEBUG_R1));
		dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R0),
		dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R1));
	return -ETIMEDOUT;
}

static int imx6_pcie_wait_for_speed_change(struct imx6_pcie *imx6_pcie)
{
	struct pcie_port *pp = &imx6_pcie->pp;
	struct device *dev = pp->dev;
	struct dw_pcie *pci = imx6_pcie->pci;
	struct device *dev = pci->dev;
	u32 tmp;
	unsigned int retries;

	for (retries = 0; retries < 200; retries++) {
		tmp = dw_pcie_readl_rc(pp, PCIE_LINK_WIDTH_SPEED_CONTROL);
		tmp = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL);
		/* Test if the speed change finished. */
		if (!(tmp & PORT_LOGIC_SPEED_CHANGE))
			return 0;
@@ -475,15 +475,16 @@ static int imx6_pcie_wait_for_speed_change(struct imx6_pcie *imx6_pcie)
static irqreturn_t imx6_pcie_msi_handler(int irq, void *arg)
{
	struct imx6_pcie *imx6_pcie = arg;
	struct pcie_port *pp = &imx6_pcie->pp;
	struct dw_pcie *pci = imx6_pcie->pci;
	struct pcie_port *pp = &pci->pp;

	return dw_handle_msi_irq(pp);
}

static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
{
	struct pcie_port *pp = &imx6_pcie->pp;
	struct device *dev = pp->dev;
	struct dw_pcie *pci = imx6_pcie->pci;
	struct device *dev = pci->dev;
	u32 tmp;
	int ret;

@@ -492,10 +493,10 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
	 * started in Gen2 mode, there is a possibility the devices on the
	 * bus will not be detected at all.  This happens with PCIe switches.
	 */
	tmp = dw_pcie_readl_rc(pp, PCIE_RC_LCR);
	tmp = dw_pcie_readl_dbi(pci, PCIE_RC_LCR);
	tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK;
	tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1;
	dw_pcie_writel_rc(pp, PCIE_RC_LCR, tmp);
	dw_pcie_writel_dbi(pci, PCIE_RC_LCR, tmp);

	/* Start LTSSM. */
	regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
@@ -509,10 +510,10 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)

	if (imx6_pcie->link_gen == 2) {
		/* Allow Gen2 mode after the link is up. */
		tmp = dw_pcie_readl_rc(pp, PCIE_RC_LCR);
		tmp = dw_pcie_readl_dbi(pci, PCIE_RC_LCR);
		tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK;
		tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2;
		dw_pcie_writel_rc(pp, PCIE_RC_LCR, tmp);
		dw_pcie_writel_dbi(pci, PCIE_RC_LCR, tmp);
	} else {
		dev_info(dev, "Link: Gen2 disabled\n");
	}
@@ -521,9 +522,9 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
	 * Start Directed Speed Change so the best possible speed both link
	 * partners support can be negotiated.
	 */
	tmp = dw_pcie_readl_rc(pp, PCIE_LINK_WIDTH_SPEED_CONTROL);
	tmp = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL);
	tmp |= PORT_LOGIC_SPEED_CHANGE;
	dw_pcie_writel_rc(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, tmp);
	dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, tmp);

	ret = imx6_pcie_wait_for_speed_change(imx6_pcie);
	if (ret) {
@@ -538,21 +539,22 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
		goto err_reset_phy;
	}

	tmp = dw_pcie_readl_rc(pp, PCIE_RC_LCSR);
	tmp = dw_pcie_readl_dbi(pci, PCIE_RC_LCSR);
	dev_info(dev, "Link up, Gen%i\n", (tmp >> 16) & 0xf);
	return 0;

err_reset_phy:
	dev_dbg(dev, "PHY DEBUG_R0=0x%08x DEBUG_R1=0x%08x\n",
		dw_pcie_readl_rc(pp, PCIE_PHY_DEBUG_R0),
		dw_pcie_readl_rc(pp, PCIE_PHY_DEBUG_R1));
		dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R0),
		dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R1));
	imx6_pcie_reset_phy(imx6_pcie);
	return ret;
}

static void imx6_pcie_host_init(struct pcie_port *pp)
{
	struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
	struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci);

	imx6_pcie_assert_core_reset(imx6_pcie);
	imx6_pcie_init_phy(imx6_pcie);
@@ -564,22 +566,22 @@ static void imx6_pcie_host_init(struct pcie_port *pp)
		dw_pcie_msi_init(pp);
}

static int imx6_pcie_link_up(struct pcie_port *pp)
static int imx6_pcie_link_up(struct dw_pcie *pci)
{
	return dw_pcie_readl_rc(pp, PCIE_PHY_DEBUG_R1) &
	return dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R1) &
			PCIE_PHY_DEBUG_R1_XMLH_LINK_UP;
}

static struct pcie_host_ops imx6_pcie_host_ops = {
	.link_up = imx6_pcie_link_up,
static struct dw_pcie_host_ops imx6_pcie_host_ops = {
	.host_init = imx6_pcie_host_init,
};

static int __init imx6_add_pcie_port(struct imx6_pcie *imx6_pcie,
				     struct platform_device *pdev)
{
	struct pcie_port *pp = &imx6_pcie->pp;
	struct device *dev = pp->dev;
	struct dw_pcie *pci = imx6_pcie->pci;
	struct pcie_port *pp = &pci->pp;
	struct device *dev = &pdev->dev;
	int ret;

	if (IS_ENABLED(CONFIG_PCI_MSI)) {
@@ -611,11 +613,15 @@ static int __init imx6_add_pcie_port(struct imx6_pcie *imx6_pcie,
	return 0;
}

static const struct dw_pcie_ops dw_pcie_ops = {
	.link_up = imx6_pcie_link_up,
};

static int __init imx6_pcie_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct dw_pcie *pci;
	struct imx6_pcie *imx6_pcie;
	struct pcie_port *pp;
	struct resource *dbi_base;
	struct device_node *node = dev->of_node;
	int ret;
@@ -624,8 +630,12 @@ static int __init imx6_pcie_probe(struct platform_device *pdev)
	if (!imx6_pcie)
		return -ENOMEM;

	pp = &imx6_pcie->pp;
	pp->dev = dev;
	pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
	if (!pci)
		return -ENOMEM;

	pci->dev = dev;
	pci->ops = &dw_pcie_ops;

	imx6_pcie->variant =
		(enum imx6_pcie_variants)of_device_get_match_data(dev);
@@ -635,9 +645,9 @@ static int __init imx6_pcie_probe(struct platform_device *pdev)
		"imprecise external abort");

	dbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	pp->dbi_base = devm_ioremap_resource(dev, dbi_base);
	if (IS_ERR(pp->dbi_base))
		return PTR_ERR(pp->dbi_base);
	pci->dbi_base = devm_ioremap_resource(dev, dbi_base);
	if (IS_ERR(pci->dbi_base))
		return PTR_ERR(pci->dbi_base);

	/* Fetch GPIOs */
	imx6_pcie->reset_gpio = of_get_named_gpio(node, "reset-gpio", 0);
+50 −33

File changed.

Preview size limit exceeded, changes collapsed.

+32 −22

File changed.

Preview size limit exceeded, changes collapsed.

Loading