aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2013-12-20 14:41:01 -0500
committerBjorn Helgaas <bhelgaas@google.com>2013-12-20 14:41:01 -0500
commit9dc1d43ff95152e7ffdf45def855ea6931d95a15 (patch)
tree231387cc832cac8a5942b7ad1d1a73cb657f7d45
parentfc05ea771af6e1b59b92bfd169909526f0a314ad (diff)
parentfce8591f73c6a30c231f220d1092362aae0b985c (diff)
Merge branch 'pci/host-designware' into next
* pci/host-designware: PCI: designware: Fix I/O transfers by using CPU (not realio) address PCI: designware: Add dw_pcie prefix before cfg_read/write PCI: designware: Fix missing MSI IRQs
-rw-r--r--drivers/pci/host/pci-exynos.c5
-rw-r--r--drivers/pci/host/pcie-designware.c32
-rw-r--r--drivers/pci/host/pcie-designware.h4
3 files changed, 24 insertions, 17 deletions
diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c
index 24beed38ddc7..3de6bfbbe8e9 100644
--- a/drivers/pci/host/pci-exynos.c
+++ b/drivers/pci/host/pci-exynos.c
@@ -468,7 +468,7 @@ static int exynos_pcie_rd_own_conf(struct pcie_port *pp, int where, int size,
468 int ret; 468 int ret;
469 469
470 exynos_pcie_sideband_dbi_r_mode(pp, true); 470 exynos_pcie_sideband_dbi_r_mode(pp, true);
471 ret = cfg_read(pp->dbi_base + (where & ~0x3), where, size, val); 471 ret = dw_pcie_cfg_read(pp->dbi_base + (where & ~0x3), where, size, val);
472 exynos_pcie_sideband_dbi_r_mode(pp, false); 472 exynos_pcie_sideband_dbi_r_mode(pp, false);
473 return ret; 473 return ret;
474} 474}
@@ -479,7 +479,8 @@ static int exynos_pcie_wr_own_conf(struct pcie_port *pp, int where, int size,
479 int ret; 479 int ret;
480 480
481 exynos_pcie_sideband_dbi_w_mode(pp, true); 481 exynos_pcie_sideband_dbi_w_mode(pp, true);
482 ret = cfg_write(pp->dbi_base + (where & ~0x3), where, size, val); 482 ret = dw_pcie_cfg_write(pp->dbi_base + (where & ~0x3),
483 where, size, val);
483 exynos_pcie_sideband_dbi_w_mode(pp, false); 484 exynos_pcie_sideband_dbi_w_mode(pp, false);
484 return ret; 485 return ret;
485} 486}
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index 1c92833a4ed3..4a08d30548ce 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -74,7 +74,7 @@ static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
74 return sys->private_data; 74 return sys->private_data;
75} 75}
76 76
77int cfg_read(void __iomem *addr, int where, int size, u32 *val) 77int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val)
78{ 78{
79 *val = readl(addr); 79 *val = readl(addr);
80 80
@@ -88,7 +88,7 @@ int cfg_read(void __iomem *addr, int where, int size, u32 *val)
88 return PCIBIOS_SUCCESSFUL; 88 return PCIBIOS_SUCCESSFUL;
89} 89}
90 90
91int cfg_write(void __iomem *addr, int where, int size, u32 val) 91int dw_pcie_cfg_write(void __iomem *addr, int where, int size, u32 val)
92{ 92{
93 if (size == 4) 93 if (size == 4)
94 writel(val, addr); 94 writel(val, addr);
@@ -126,7 +126,8 @@ static int dw_pcie_rd_own_conf(struct pcie_port *pp, int where, int size,
126 if (pp->ops->rd_own_conf) 126 if (pp->ops->rd_own_conf)
127 ret = pp->ops->rd_own_conf(pp, where, size, val); 127 ret = pp->ops->rd_own_conf(pp, where, size, val);
128 else 128 else
129 ret = cfg_read(pp->dbi_base + (where & ~0x3), where, size, val); 129 ret = dw_pcie_cfg_read(pp->dbi_base + (where & ~0x3), where,
130 size, val);
130 131
131 return ret; 132 return ret;
132} 133}
@@ -139,8 +140,8 @@ static int dw_pcie_wr_own_conf(struct pcie_port *pp, int where, int size,
139 if (pp->ops->wr_own_conf) 140 if (pp->ops->wr_own_conf)
140 ret = pp->ops->wr_own_conf(pp, where, size, val); 141 ret = pp->ops->wr_own_conf(pp, where, size, val);
141 else 142 else
142 ret = cfg_write(pp->dbi_base + (where & ~0x3), where, size, 143 ret = dw_pcie_cfg_write(pp->dbi_base + (where & ~0x3), where,
143 val); 144 size, val);
144 145
145 return ret; 146 return ret;
146} 147}
@@ -167,11 +168,13 @@ void dw_handle_msi_irq(struct pcie_port *pp)
167 while ((pos = find_next_bit(&val, 32, pos)) != 32) { 168 while ((pos = find_next_bit(&val, 32, pos)) != 32) {
168 irq = irq_find_mapping(pp->irq_domain, 169 irq = irq_find_mapping(pp->irq_domain,
169 i * 32 + pos); 170 i * 32 + pos);
171 dw_pcie_wr_own_conf(pp,
172 PCIE_MSI_INTR0_STATUS + i * 12,
173 4, 1 << pos);
170 generic_handle_irq(irq); 174 generic_handle_irq(irq);
171 pos++; 175 pos++;
172 } 176 }
173 } 177 }
174 dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_STATUS + i * 12, 4, val);
175 } 178 }
176} 179}
177 180
@@ -415,6 +418,7 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
415 + global_io_offset); 418 + global_io_offset);
416 pp->config.io_size = resource_size(&pp->io); 419 pp->config.io_size = resource_size(&pp->io);
417 pp->config.io_bus_addr = range.pci_addr; 420 pp->config.io_bus_addr = range.pci_addr;
421 pp->io_base = range.cpu_addr;
418 } 422 }
419 if (restype == IORESOURCE_MEM) { 423 if (restype == IORESOURCE_MEM) {
420 of_pci_range_to_resource(&range, np, &pp->mem); 424 of_pci_range_to_resource(&range, np, &pp->mem);
@@ -440,7 +444,6 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
440 444
441 pp->cfg0_base = pp->cfg.start; 445 pp->cfg0_base = pp->cfg.start;
442 pp->cfg1_base = pp->cfg.start + pp->config.cfg0_size; 446 pp->cfg1_base = pp->cfg.start + pp->config.cfg0_size;
443 pp->io_base = pp->io.start;
444 pp->mem_base = pp->mem.start; 447 pp->mem_base = pp->mem.start;
445 448
446 pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base, 449 pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base,
@@ -572,11 +575,13 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
572 575
573 if (bus->parent->number == pp->root_bus_nr) { 576 if (bus->parent->number == pp->root_bus_nr) {
574 dw_pcie_prog_viewport_cfg0(pp, busdev); 577 dw_pcie_prog_viewport_cfg0(pp, busdev);
575 ret = cfg_read(pp->va_cfg0_base + address, where, size, val); 578 ret = dw_pcie_cfg_read(pp->va_cfg0_base + address, where, size,
579 val);
576 dw_pcie_prog_viewport_mem_outbound(pp); 580 dw_pcie_prog_viewport_mem_outbound(pp);
577 } else { 581 } else {
578 dw_pcie_prog_viewport_cfg1(pp, busdev); 582 dw_pcie_prog_viewport_cfg1(pp, busdev);
579 ret = cfg_read(pp->va_cfg1_base + address, where, size, val); 583 ret = dw_pcie_cfg_read(pp->va_cfg1_base + address, where, size,
584 val);
580 dw_pcie_prog_viewport_io_outbound(pp); 585 dw_pcie_prog_viewport_io_outbound(pp);
581 } 586 }
582 587
@@ -595,18 +600,19 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
595 600
596 if (bus->parent->number == pp->root_bus_nr) { 601 if (bus->parent->number == pp->root_bus_nr) {
597 dw_pcie_prog_viewport_cfg0(pp, busdev); 602 dw_pcie_prog_viewport_cfg0(pp, busdev);
598 ret = cfg_write(pp->va_cfg0_base + address, where, size, val); 603 ret = dw_pcie_cfg_write(pp->va_cfg0_base + address, where, size,
604 val);
599 dw_pcie_prog_viewport_mem_outbound(pp); 605 dw_pcie_prog_viewport_mem_outbound(pp);
600 } else { 606 } else {
601 dw_pcie_prog_viewport_cfg1(pp, busdev); 607 dw_pcie_prog_viewport_cfg1(pp, busdev);
602 ret = cfg_write(pp->va_cfg1_base + address, where, size, val); 608 ret = dw_pcie_cfg_write(pp->va_cfg1_base + address, where, size,
609 val);
603 dw_pcie_prog_viewport_io_outbound(pp); 610 dw_pcie_prog_viewport_io_outbound(pp);
604 } 611 }
605 612
606 return ret; 613 return ret;
607} 614}
608 615
609
610static int dw_pcie_valid_config(struct pcie_port *pp, 616static int dw_pcie_valid_config(struct pcie_port *pp,
611 struct pci_bus *bus, int dev) 617 struct pci_bus *bus, int dev)
612{ 618{
@@ -700,7 +706,7 @@ static int dw_pcie_setup(int nr, struct pci_sys_data *sys)
700 706
701 if (global_io_offset < SZ_1M && pp->config.io_size > 0) { 707 if (global_io_offset < SZ_1M && pp->config.io_size > 0) {
702 sys->io_offset = global_io_offset - pp->config.io_bus_addr; 708 sys->io_offset = global_io_offset - pp->config.io_bus_addr;
703 pci_ioremap_io(sys->io_offset, pp->io.start); 709 pci_ioremap_io(global_io_offset, pp->io_base);
704 global_io_offset += SZ_64K; 710 global_io_offset += SZ_64K;
705 pci_add_resource_offset(&sys->resources, &pp->io, 711 pci_add_resource_offset(&sys->resources, &pp->io,
706 sys->io_offset); 712 sys->io_offset);
diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
index c15379be2372..3063b3594d88 100644
--- a/drivers/pci/host/pcie-designware.h
+++ b/drivers/pci/host/pcie-designware.h
@@ -66,8 +66,8 @@ struct pcie_host_ops {
66 void (*host_init)(struct pcie_port *pp); 66 void (*host_init)(struct pcie_port *pp);
67}; 67};
68 68
69int cfg_read(void __iomem *addr, int where, int size, u32 *val); 69int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val);
70int cfg_write(void __iomem *addr, int where, int size, u32 val); 70int dw_pcie_cfg_write(void __iomem *addr, int where, int size, u32 val);
71void dw_handle_msi_irq(struct pcie_port *pp); 71void dw_handle_msi_irq(struct pcie_port *pp);
72void dw_pcie_msi_init(struct pcie_port *pp); 72void dw_pcie_msi_init(struct pcie_port *pp);
73int dw_pcie_link_up(struct pcie_port *pp); 73int dw_pcie_link_up(struct pcie_port *pp);