diff options
Diffstat (limited to 'drivers/pci/controller/dwc')
-rw-r--r-- | drivers/pci/controller/dwc/pcie-designware-host.c | 61 |
1 files changed, 23 insertions, 38 deletions
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index 45ff5e4f8af6..0c18ab63811f 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c | |||
@@ -512,8 +512,9 @@ error: | |||
512 | return ret; | 512 | return ret; |
513 | } | 513 | } |
514 | 514 | ||
515 | static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, | 515 | static int dw_pcie_access_other_conf(struct pcie_port *pp, struct pci_bus *bus, |
516 | u32 devfn, int where, int size, u32 *val) | 516 | u32 devfn, int where, int size, u32 *val, |
517 | bool write) | ||
517 | { | 518 | { |
518 | int ret, type; | 519 | int ret, type; |
519 | u32 busdev, cfg_size; | 520 | u32 busdev, cfg_size; |
@@ -521,9 +522,6 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, | |||
521 | void __iomem *va_cfg_base; | 522 | void __iomem *va_cfg_base; |
522 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | 523 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); |
523 | 524 | ||
524 | if (pp->ops->rd_other_conf) | ||
525 | return pp->ops->rd_other_conf(pp, bus, devfn, where, size, val); | ||
526 | |||
527 | busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) | | 525 | busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) | |
528 | PCIE_ATU_FUNC(PCI_FUNC(devfn)); | 526 | PCIE_ATU_FUNC(PCI_FUNC(devfn)); |
529 | 527 | ||
@@ -542,7 +540,11 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, | |||
542 | dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1, | 540 | dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1, |
543 | type, cpu_addr, | 541 | type, cpu_addr, |
544 | busdev, cfg_size); | 542 | busdev, cfg_size); |
545 | ret = dw_pcie_read(va_cfg_base + where, size, val); | 543 | if (write) |
544 | ret = dw_pcie_write(va_cfg_base + where, size, *val); | ||
545 | else | ||
546 | ret = dw_pcie_read(va_cfg_base + where, size, val); | ||
547 | |||
546 | if (pci->num_viewport <= 2) | 548 | if (pci->num_viewport <= 2) |
547 | dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1, | 549 | dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1, |
548 | PCIE_ATU_TYPE_IO, pp->io_base, | 550 | PCIE_ATU_TYPE_IO, pp->io_base, |
@@ -551,43 +553,26 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, | |||
551 | return ret; | 553 | return ret; |
552 | } | 554 | } |
553 | 555 | ||
556 | static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, | ||
557 | u32 devfn, int where, int size, u32 *val) | ||
558 | { | ||
559 | if (pp->ops->rd_other_conf) | ||
560 | return pp->ops->rd_other_conf(pp, bus, devfn, where, | ||
561 | size, val); | ||
562 | |||
563 | return dw_pcie_access_other_conf(pp, bus, devfn, where, size, val, | ||
564 | false); | ||
565 | } | ||
566 | |||
554 | static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus, | 567 | static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus, |
555 | u32 devfn, int where, int size, u32 val) | 568 | u32 devfn, int where, int size, u32 val) |
556 | { | 569 | { |
557 | int ret, type; | ||
558 | u32 busdev, cfg_size; | ||
559 | u64 cpu_addr; | ||
560 | void __iomem *va_cfg_base; | ||
561 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | ||
562 | |||
563 | if (pp->ops->wr_other_conf) | 570 | if (pp->ops->wr_other_conf) |
564 | return pp->ops->wr_other_conf(pp, bus, devfn, where, size, val); | 571 | return pp->ops->wr_other_conf(pp, bus, devfn, where, |
565 | 572 | size, val); | |
566 | busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) | | ||
567 | PCIE_ATU_FUNC(PCI_FUNC(devfn)); | ||
568 | 573 | ||
569 | if (bus->parent->number == pp->root_bus_nr) { | 574 | return dw_pcie_access_other_conf(pp, bus, devfn, where, size, &val, |
570 | type = PCIE_ATU_TYPE_CFG0; | 575 | true); |
571 | cpu_addr = pp->cfg0_base; | ||
572 | cfg_size = pp->cfg0_size; | ||
573 | va_cfg_base = pp->va_cfg0_base; | ||
574 | } else { | ||
575 | type = PCIE_ATU_TYPE_CFG1; | ||
576 | cpu_addr = pp->cfg1_base; | ||
577 | cfg_size = pp->cfg1_size; | ||
578 | va_cfg_base = pp->va_cfg1_base; | ||
579 | } | ||
580 | |||
581 | dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1, | ||
582 | type, cpu_addr, | ||
583 | busdev, cfg_size); | ||
584 | ret = dw_pcie_write(va_cfg_base + where, size, val); | ||
585 | if (pci->num_viewport <= 2) | ||
586 | dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1, | ||
587 | PCIE_ATU_TYPE_IO, pp->io_base, | ||
588 | pp->io_bus_addr, pp->io_size); | ||
589 | |||
590 | return ret; | ||
591 | } | 576 | } |
592 | 577 | ||
593 | static int dw_pcie_valid_device(struct pcie_port *pp, struct pci_bus *bus, | 578 | static int dw_pcie_valid_device(struct pcie_port *pp, struct pci_bus *bus, |