[RESEND: RFC PATCH 2/3] pci: designware: enhancements to support keystone pcie

2014-03-24 Thread Murali Karicheri
keystone pcie hardware is based on designware hw version 3.65.
There is no support for ATU port and have registers in
application space to configure inbound/outbound access. Also
doesn't support PCI PVM option. So the MSI IRQ registers available
in application space is used to mask/unmask/enable the MSI IRQs.
This requires changes to designware core driver to support the
keystone pcie driver.

Also modified affected drivers to work with the APIs that
are modified for to keystone pcie driver.

CC: Jingoo Han 
CC: Bjorn Helgaas 
CC: Kukjin Kim 
CC: Richard Zhu 
CC: Shawn Guo 
CC: Mohit Kumar 
CC: Santosh Shilimkar 

Signed-off-by: Murali Karicheri 
---
 drivers/pci/host/pci-exynos.c  |2 +-
 drivers/pci/host/pci-imx6.c|2 +-
 drivers/pci/host/pcie-designware.c |   99 
 drivers/pci/host/pcie-designware.h |   14 -
 4 files changed, 81 insertions(+), 36 deletions(-)

diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c
index 24beed3..3cae9b1 100644
--- a/drivers/pci/host/pci-exynos.c
+++ b/drivers/pci/host/pci-exynos.c
@@ -546,7 +546,7 @@ static int add_pcie_port(struct pcie_port *pp, struct 
platform_device *pdev)
pp->ops = &exynos_pcie_host_ops;
 
spin_lock_init(&pp->conf_lock);
-   ret = dw_pcie_host_init(pp);
+   ret = dw_pcie_host_init(pp, NULL, NULL);
if (ret) {
dev_err(&pdev->dev, "failed to initialize host\n");
return ret;
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
index bd70af8..0d77047 100644
--- a/drivers/pci/host/pci-imx6.c
+++ b/drivers/pci/host/pci-imx6.c
@@ -397,7 +397,7 @@ static int imx6_add_pcie_port(struct pcie_port *pp,
pp->ops = &imx6_pcie_host_ops;
 
spin_lock_init(&pp->conf_lock);
-   ret = dw_pcie_host_init(pp);
+   ret = dw_pcie_host_init(pp, NULL, NULL);
if (ret) {
dev_err(&pdev->dev, "failed to initialize host\n");
return ret;
diff --git a/drivers/pci/host/pcie-designware.c 
b/drivers/pci/host/pcie-designware.c
index e33b68b..02d4d25 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -248,11 +248,15 @@ static int assign_irq(int no_irqs, struct msi_desc *desc, 
int *pos)
irq_alloc_descs((irq + i), (irq + i), 1, 0);
irq_set_msi_desc(irq + i, desc);
/*Enable corresponding interrupt in MSI interrupt controller */
-   res = ((pos0 + i) / 32) * 12;
-   bit = (pos0 + i) % 32;
-   dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, &val);
-   val |= 1 << bit;
-   dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, val);
+   if (!(pp->version & DW_VERSION_PRE_3_70)) {
+   res = ((pos0 + i) / 32) * 12;
+   bit = (pos0 + i) % 32;
+   dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res,
+4, &val);
+   val |= 1 << bit;
+   dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res,
+4, val);
+   }
i++;
}
 
@@ -288,11 +292,13 @@ static void clear_irq(unsigned int irq)
clear_bit(pos, pp->msi_irq_in_use);
 
/* Disable corresponding interrupt on MSI interrupt controller */
-   res = (pos / 32) * 12;
-   bit = pos % 32;
-   dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, &val);
-   val &= ~(1 << bit);
-   dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, val);
+   if (!(pp->version & DW_VERSION_PRE_3_70)) {
+   res = (pos / 32) * 12;
+   bit = pos % 32;
+   dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, &val);
+   val &= ~(1 << bit);
+   dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, val);
+   }
 }
 
 static int dw_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
@@ -326,7 +332,10 @@ static int dw_msi_setup_irq(struct msi_chip *chip, struct 
pci_dev *pdev,
msg_ctr);
desc->msi_attrib.multiple = msgvec;
 
-   msg.address_lo = virt_to_phys((void *)pp->msi_data);
+   if (pp->ops->get_msi_data)
+   msg.address_lo = pp->ops->get_msi_data(pp);
+   else
+   msg.address_lo = virt_to_phys((void *)pp->msi_data);
msg.address_hi = 0x0;
msg.data = pos;
write_msi_msg(irq, &msg);
@@ -366,14 +375,27 @@ static const struct irq_domain_ops msi_domain_ops = {
.map = dw_pcie_msi_map,
 };
 
-int __init dw_pcie_host_init(struct pcie_port *pp)
+int __init dw_pcie_host_init(struct pcie_port *pp, struct hw_pci *hw,
+   const struct irq_domain_ops *irq_ops)
 {
struct device_node *np = pp->dev->of_node;
-   struct of_pci_ran

[PATCH 2/3] pci: designware: enhancements to support keystone pcie

2014-03-24 Thread Murali Karicheri
keystone pcie hardware is based on designware hw version 3.65.
There is no support for ATU port and have registers in
application space to configure inbound/outbound access. Also
doesn't support PCI PVM option. So the MSI IRQ registers available
in application space is used to mask/unmask/enable the MSI IRQs.
This requires changes to designware core driver to support the
keystone pcie driver.

Also modified affected drivers to work with the APIs that
are modified for to keystone pcie driver.

CC: Jingoo Han 
CC: Bjorn Helgaas 
CC: Kukjin Kim 
CC: Richard Zhu 
CC: Shawn Guo 
CC: Mohit Kumar 
CC: Santosh Shilimkar 

Signed-off-by: Murali Karicheri 
---
 drivers/pci/host/pci-exynos.c  |2 +-
 drivers/pci/host/pci-imx6.c|2 +-
 drivers/pci/host/pcie-designware.c |   99 
 drivers/pci/host/pcie-designware.h |   14 -
 4 files changed, 81 insertions(+), 36 deletions(-)

diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c
index 24beed3..3cae9b1 100644
--- a/drivers/pci/host/pci-exynos.c
+++ b/drivers/pci/host/pci-exynos.c
@@ -546,7 +546,7 @@ static int add_pcie_port(struct pcie_port *pp, struct 
platform_device *pdev)
pp->ops = &exynos_pcie_host_ops;
 
spin_lock_init(&pp->conf_lock);
-   ret = dw_pcie_host_init(pp);
+   ret = dw_pcie_host_init(pp, NULL, NULL);
if (ret) {
dev_err(&pdev->dev, "failed to initialize host\n");
return ret;
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
index bd70af8..0d77047 100644
--- a/drivers/pci/host/pci-imx6.c
+++ b/drivers/pci/host/pci-imx6.c
@@ -397,7 +397,7 @@ static int imx6_add_pcie_port(struct pcie_port *pp,
pp->ops = &imx6_pcie_host_ops;
 
spin_lock_init(&pp->conf_lock);
-   ret = dw_pcie_host_init(pp);
+   ret = dw_pcie_host_init(pp, NULL, NULL);
if (ret) {
dev_err(&pdev->dev, "failed to initialize host\n");
return ret;
diff --git a/drivers/pci/host/pcie-designware.c 
b/drivers/pci/host/pcie-designware.c
index e33b68b..02d4d25 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -248,11 +248,15 @@ static int assign_irq(int no_irqs, struct msi_desc *desc, 
int *pos)
irq_alloc_descs((irq + i), (irq + i), 1, 0);
irq_set_msi_desc(irq + i, desc);
/*Enable corresponding interrupt in MSI interrupt controller */
-   res = ((pos0 + i) / 32) * 12;
-   bit = (pos0 + i) % 32;
-   dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, &val);
-   val |= 1 << bit;
-   dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, val);
+   if (!(pp->version & DW_VERSION_PRE_3_70)) {
+   res = ((pos0 + i) / 32) * 12;
+   bit = (pos0 + i) % 32;
+   dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res,
+4, &val);
+   val |= 1 << bit;
+   dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res,
+4, val);
+   }
i++;
}
 
@@ -288,11 +292,13 @@ static void clear_irq(unsigned int irq)
clear_bit(pos, pp->msi_irq_in_use);
 
/* Disable corresponding interrupt on MSI interrupt controller */
-   res = (pos / 32) * 12;
-   bit = pos % 32;
-   dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, &val);
-   val &= ~(1 << bit);
-   dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, val);
+   if (!(pp->version & DW_VERSION_PRE_3_70)) {
+   res = (pos / 32) * 12;
+   bit = pos % 32;
+   dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, &val);
+   val &= ~(1 << bit);
+   dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, val);
+   }
 }
 
 static int dw_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
@@ -326,7 +332,10 @@ static int dw_msi_setup_irq(struct msi_chip *chip, struct 
pci_dev *pdev,
msg_ctr);
desc->msi_attrib.multiple = msgvec;
 
-   msg.address_lo = virt_to_phys((void *)pp->msi_data);
+   if (pp->ops->get_msi_data)
+   msg.address_lo = pp->ops->get_msi_data(pp);
+   else
+   msg.address_lo = virt_to_phys((void *)pp->msi_data);
msg.address_hi = 0x0;
msg.data = pos;
write_msi_msg(irq, &msg);
@@ -366,14 +375,27 @@ static const struct irq_domain_ops msi_domain_ops = {
.map = dw_pcie_msi_map,
 };
 
-int __init dw_pcie_host_init(struct pcie_port *pp)
+int __init dw_pcie_host_init(struct pcie_port *pp, struct hw_pci *hw,
+   const struct irq_domain_ops *irq_ops)
 {
struct device_node *np = pp->dev->of_node;
-   struct of_pci_ran