aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJisheng Zhang <jszhang@marvell.com>2015-04-30 04:22:29 -0400
committerBjorn Helgaas <bhelgaas@google.com>2015-05-20 16:01:57 -0400
commit2d91b491d5be13602a73be789bb8a3c28d06b7f2 (patch)
tree9df5767fb59a487d5282aa675cfa7efeb27f0d1e
parent63503c87f06e0f2c8c951cada81221c5500188d8 (diff)
PCI: designware: Use iATU0 for cfg and IO, iATU1 for MEM
Most transactions' type are cfg0 and MEM, so the current iATU usage is not balanced: iATU0 is hot while iATU1 is rarely used. Refactor the iATU usage so we use iATU0 for cfg and IO and iATU1 for MEM. This allocation idea comes from Minghuan Lian <Minghuan.Lian@freescale.com>: [bhelgaas: use link with Message-ID] Link: http://lkml.kernel.org/r/1429091315-31891-3-git-send-email-Minghuan.Lian@freescale.com Signed-off-by: Jisheng Zhang <jszhang@marvell.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Acked-by: Pratyush Anand <pratyush.anand@gmail.com>
-rw-r--r--drivers/pci/host/pcie-designware.c81
1 files changed, 45 insertions, 36 deletions
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index 49a0945f5a1b..0dca08d66649 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -510,6 +510,11 @@ int dw_pcie_host_init(struct pcie_port *pp)
510 if (pp->ops->host_init) 510 if (pp->ops->host_init)
511 pp->ops->host_init(pp); 511 pp->ops->host_init(pp);
512 512
513 if (!pp->ops->rd_other_conf)
514 dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
515 PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
516 pp->mem_bus_addr, pp->mem_size);
517
513 dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0); 518 dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
514 519
515 /* program correct class for RC */ 520 /* program correct class for RC */
@@ -535,66 +540,70 @@ int dw_pcie_host_init(struct pcie_port *pp)
535static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, 540static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
536 u32 devfn, int where, int size, u32 *val) 541 u32 devfn, int where, int size, u32 *val)
537{ 542{
538 int ret = PCIBIOS_SUCCESSFUL; 543 int ret, type;
539 u32 address, busdev; 544 u32 address, busdev, cfg_size;
545 u64 cpu_addr;
546 void __iomem *va_cfg_base;
540 547
541 busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) | 548 busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) |
542 PCIE_ATU_FUNC(PCI_FUNC(devfn)); 549 PCIE_ATU_FUNC(PCI_FUNC(devfn));
543 address = where & ~0x3; 550 address = where & ~0x3;
544 551
545 if (bus->parent->number == pp->root_bus_nr) { 552 if (bus->parent->number == pp->root_bus_nr) {
546 dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0, 553 type = PCIE_ATU_TYPE_CFG0;
547 PCIE_ATU_TYPE_CFG0, pp->cfg0_mod_base, 554 cpu_addr = pp->cfg0_mod_base;
548 busdev, pp->cfg0_size); 555 cfg_size = pp->cfg0_size;
549 ret = dw_pcie_cfg_read(pp->va_cfg0_base + address, where, size, 556 va_cfg_base = pp->va_cfg0_base;
550 val);
551 dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
552 PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
553 pp->mem_bus_addr, pp->mem_size);
554 } else { 557 } else {
555 dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1, 558 type = PCIE_ATU_TYPE_CFG1;
556 PCIE_ATU_TYPE_CFG1, pp->cfg1_mod_base, 559 cpu_addr = pp->cfg1_mod_base;
557 busdev, pp->cfg1_size); 560 cfg_size = pp->cfg1_size;
558 ret = dw_pcie_cfg_read(pp->va_cfg1_base + address, where, size, 561 va_cfg_base = pp->va_cfg1_base;
559 val);
560 dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
561 PCIE_ATU_TYPE_IO, pp->io_mod_base,
562 pp->io_bus_addr, pp->io_size);
563 } 562 }
564 563
564 dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
565 type, cpu_addr,
566 busdev, cfg_size);
567 ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
568 dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
569 PCIE_ATU_TYPE_IO, pp->io_mod_base,
570 pp->io_bus_addr, pp->io_size);
571
565 return ret; 572 return ret;
566} 573}
567 574
568static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus, 575static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
569 u32 devfn, int where, int size, u32 val) 576 u32 devfn, int where, int size, u32 val)
570{ 577{
571 int ret = PCIBIOS_SUCCESSFUL; 578 int ret, type;
572 u32 address, busdev; 579 u32 address, busdev, cfg_size;
580 u64 cpu_addr;
581 void __iomem *va_cfg_base;
573 582
574 busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) | 583 busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) |
575 PCIE_ATU_FUNC(PCI_FUNC(devfn)); 584 PCIE_ATU_FUNC(PCI_FUNC(devfn));
576 address = where & ~0x3; 585 address = where & ~0x3;
577 586
578 if (bus->parent->number == pp->root_bus_nr) { 587 if (bus->parent->number == pp->root_bus_nr) {
579 dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0, 588 type = PCIE_ATU_TYPE_CFG0;
580 PCIE_ATU_TYPE_CFG0, pp->cfg0_mod_base, 589 cpu_addr = pp->cfg0_mod_base;
581 busdev, pp->cfg0_size); 590 cfg_size = pp->cfg0_size;
582 ret = dw_pcie_cfg_write(pp->va_cfg0_base + address, where, size, 591 va_cfg_base = pp->va_cfg0_base;
583 val);
584 dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
585 PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
586 pp->mem_bus_addr, pp->mem_size);
587 } else { 592 } else {
588 dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1, 593 type = PCIE_ATU_TYPE_CFG1;
589 PCIE_ATU_TYPE_CFG1, pp->cfg1_mod_base, 594 cpu_addr = pp->cfg1_mod_base;
590 busdev, pp->cfg1_size); 595 cfg_size = pp->cfg1_size;
591 ret = dw_pcie_cfg_write(pp->va_cfg1_base + address, where, size, 596 va_cfg_base = pp->va_cfg1_base;
592 val);
593 dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
594 PCIE_ATU_TYPE_IO, pp->io_mod_base,
595 pp->io_bus_addr, pp->io_size);
596 } 597 }
597 598
599 dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
600 type, cpu_addr,
601 busdev, cfg_size);
602 ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
603 dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
604 PCIE_ATU_TYPE_IO, pp->io_mod_base,
605 pp->io_bus_addr, pp->io_size);
606
598 return ret; 607 return ret;
599} 608}
600 609