aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2007-12-20 23:39:24 -0500
committerJosh Boyer <jwboyer@linux.vnet.ibm.com>2007-12-23 14:12:34 -0500
commita2d2e1ec07a80946cbe812dc8c73291cad8214b2 (patch)
tree54a0daf486fccf9a9e50272c699ab2f7465ff518 /arch/powerpc/sysdev
parentc839e0eff500af03de65e560c2e21c3831586e6e (diff)
[POWERPC] 4xx: PLB to PCI Express support
This adds to the previous 2 patches the support for the 4xx PCI Express cells as found in the 440SPe revA, revB and 405EX. Unfortunately, due to significant differences between these, and other interesting "features" of those pieces of HW, the code isn't as simple as it is for PCI and PCI-X and some of the functions differ significantly between the 3 implementations. Thus, not only this code can only support those 3 implementations for now and will refuse to operate on any other, but there are added ifdef's to avoid the bloat of building a fairly large amount of code on platforms that don't need it. Also, this code currently only supports fully initializing root complex nodes, not endpoint. Some more code will have to be lifted from the arch/ppc implementation to add the endpoint support, though it's mostly differences in memory mapping, and the question on how to represent endpoint mode PCI in the device-tree is thus open. Many thanks to Stefan Roese for testing & fixing up the 405EX bits ! Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Stefan Roese <sr@denx.de> Signed-off-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>
Diffstat (limited to 'arch/powerpc/sysdev')
-rw-r--r--arch/powerpc/sysdev/Kconfig8
-rw-r--r--arch/powerpc/sysdev/ppc4xx_pci.c994
-rw-r--r--arch/powerpc/sysdev/ppc4xx_pci.h242
3 files changed, 1226 insertions, 18 deletions
diff --git a/arch/powerpc/sysdev/Kconfig b/arch/powerpc/sysdev/Kconfig
new file mode 100644
index 000000000000..72fb35b9ebca
--- /dev/null
+++ b/arch/powerpc/sysdev/Kconfig
@@ -0,0 +1,8 @@
1# For a description of the syntax of this configuration file,
2# see Documentation/kbuild/kconfig-language.txt.
3#
4
5config PPC4xx_PCI_EXPRESS
6 bool
7 depends on PCI && 4xx
8 default n
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c
index b7d79880c9b9..b986eff09f6b 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.c
+++ b/arch/powerpc/sysdev/ppc4xx_pci.c
@@ -3,16 +3,31 @@
3 * 3 *
4 * Copyright 2007 Ben. Herrenschmidt <benh@kernel.crashing.org>, IBM Corp. 4 * Copyright 2007 Ben. Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
5 * 5 *
6 * Most PCI Express code is coming from Stefan Roese implementation for
7 * arch/ppc in the Denx tree, slightly reworked by me.
8 *
9 * Copyright 2007 DENX Software Engineering, Stefan Roese <sr@denx.de>
10 *
11 * Some of that comes itself from a previous implementation for 440SPE only
12 * by Roland Dreier:
13 *
14 * Copyright (c) 2005 Cisco Systems. All rights reserved.
15 * Roland Dreier <rolandd@cisco.com>
16 *
6 */ 17 */
7 18
8#include <linux/kernel.h> 19#include <linux/kernel.h>
9#include <linux/pci.h> 20#include <linux/pci.h>
10#include <linux/init.h> 21#include <linux/init.h>
11#include <linux/of.h> 22#include <linux/of.h>
23#include <linux/bootmem.h>
24#include <linux/delay.h>
12 25
13#include <asm/io.h> 26#include <asm/io.h>
14#include <asm/pci-bridge.h> 27#include <asm/pci-bridge.h>
15#include <asm/machdep.h> 28#include <asm/machdep.h>
29#include <asm/dcr.h>
30#include <asm/dcr-regs.h>
16 31
17#include "ppc4xx_pci.h" 32#include "ppc4xx_pci.h"
18 33
@@ -21,6 +36,17 @@ static int dma_offset_set;
21/* Move that to a useable header */ 36/* Move that to a useable header */
22extern unsigned long total_memory; 37extern unsigned long total_memory;
23 38
39#define U64_TO_U32_LOW(val) ((u32)((val) & 0x00000000ffffffffULL))
40#define U64_TO_U32_HIGH(val) ((u32)((val) >> 32))
41
42#ifdef CONFIG_RESOURCES_64BIT
43#define RES_TO_U32_LOW(val) U64_TO_U32_LOW(val)
44#define RES_TO_U32_HIGH(val) U64_TO_U32_HIGH(val)
45#else
46#define RES_TO_U32_LOW(val) (val)
47#define RES_TO_U32_HIGH(val) (0)
48#endif
49
24static void fixup_ppc4xx_pci_bridge(struct pci_dev *dev) 50static void fixup_ppc4xx_pci_bridge(struct pci_dev *dev)
25{ 51{
26 struct pci_controller *hose; 52 struct pci_controller *hose;
@@ -178,13 +204,8 @@ static void __init ppc4xx_configure_pci_PMMs(struct pci_controller *hose,
178 204
179 /* Calculate register values */ 205 /* Calculate register values */
180 la = res->start; 206 la = res->start;
181#ifdef CONFIG_RESOURCES_64BIT 207 pciha = RES_TO_U32_HIGH(res->start - hose->pci_mem_offset);
182 pciha = (res->start - hose->pci_mem_offset) >> 32; 208 pcila = RES_TO_U32_LOW(res->start - hose->pci_mem_offset);
183 pcila = (res->start - hose->pci_mem_offset) & 0xffffffffu;
184#else
185 pciha = 0;
186 pcila = res->start - hose->pci_mem_offset;
187#endif
188 209
189 ma = res->end + 1 - res->start; 210 ma = res->end + 1 - res->start;
190 if (!is_power_of_2(ma) || ma < 0x1000 || ma > 0xffffffffu) { 211 if (!is_power_of_2(ma) || ma < 0x1000 || ma > 0xffffffffu) {
@@ -333,16 +354,10 @@ static void __init ppc4xx_configure_pcix_POMs(struct pci_controller *hose,
333 } 354 }
334 355
335 /* Calculate register values */ 356 /* Calculate register values */
336#ifdef CONFIG_RESOURCES_64BIT 357 lah = RES_TO_U32_HIGH(res->start);
337 lah = res->start >> 32; 358 lal = RES_TO_U32_LOW(res->start);
338 lal = res->start & 0xffffffffu; 359 pciah = RES_TO_U32_HIGH(res->start - hose->pci_mem_offset);
339 pciah = (res->start - hose->pci_mem_offset) >> 32; 360 pcial = RES_TO_U32_LOW(res->start - hose->pci_mem_offset);
340 pcial = (res->start - hose->pci_mem_offset) & 0xffffffffu;
341#else
342 lah = pciah = 0;
343 lal = res->start;
344 pcial = res->start - hose->pci_mem_offset;
345#endif
346 sa = res->end + 1 - res->start; 361 sa = res->end + 1 - res->start;
347 if (!is_power_of_2(sa) || sa < 0x100000 || 362 if (!is_power_of_2(sa) || sa < 0x100000 ||
348 sa > 0xffffffffu) { 363 sa > 0xffffffffu) {
@@ -492,20 +507,963 @@ static void __init ppc4xx_probe_pcix_bridge(struct device_node *np)
492 iounmap(reg); 507 iounmap(reg);
493} 508}
494 509
510#ifdef CONFIG_PPC4xx_PCI_EXPRESS
511
495/* 512/*
496 * 4xx PCI-Express part 513 * 4xx PCI-Express part
514 *
515 * We support 3 parts currently based on the compatible property:
516 *
517 * ibm,plb-pciex-440speA
518 * ibm,plb-pciex-440speB
519 * ibm,plb-pciex-405ex
520 *
521 * Anything else will be rejected for now as they are all subtly
522 * different unfortunately.
523 *
497 */ 524 */
525
526#define MAX_PCIE_BUS_MAPPED 0x10
527
528struct ppc4xx_pciex_port
529{
530 struct pci_controller *hose;
531 struct device_node *node;
532 unsigned int index;
533 int endpoint;
534 unsigned int sdr_base;
535 dcr_host_t dcrs;
536 struct resource cfg_space;
537 struct resource utl_regs;
538};
539
540static struct ppc4xx_pciex_port *ppc4xx_pciex_ports;
541static unsigned int ppc4xx_pciex_port_count;
542
543struct ppc4xx_pciex_hwops
544{
545 int (*core_init)(struct device_node *np);
546 int (*port_init_hw)(struct ppc4xx_pciex_port *port);
547 int (*setup_utl)(struct ppc4xx_pciex_port *port);
548};
549
550static struct ppc4xx_pciex_hwops *ppc4xx_pciex_hwops;
551
552#ifdef CONFIG_44x
553
554/* Check various reset bits of the 440SPe PCIe core */
555static int __init ppc440spe_pciex_check_reset(struct device_node *np)
556{
557 u32 valPE0, valPE1, valPE2;
558 int err = 0;
559
560 /* SDR0_PEGPLLLCT1 reset */
561 if (!(mfdcri(SDR0, PESDR0_PLLLCT1) & 0x01000000)) {
562 /*
563 * the PCIe core was probably already initialised
564 * by firmware - let's re-reset RCSSET regs
565 *
566 * -- Shouldn't we also re-reset the whole thing ? -- BenH
567 */
568 pr_debug("PCIE: SDR0_PLLLCT1 already reset.\n");
569 mtdcri(SDR0, PESDR0_440SPE_RCSSET, 0x01010000);
570 mtdcri(SDR0, PESDR1_440SPE_RCSSET, 0x01010000);
571 mtdcri(SDR0, PESDR2_440SPE_RCSSET, 0x01010000);
572 }
573
574 valPE0 = mfdcri(SDR0, PESDR0_440SPE_RCSSET);
575 valPE1 = mfdcri(SDR0, PESDR1_440SPE_RCSSET);
576 valPE2 = mfdcri(SDR0, PESDR2_440SPE_RCSSET);
577
578 /* SDR0_PExRCSSET rstgu */
579 if (!(valPE0 & 0x01000000) ||
580 !(valPE1 & 0x01000000) ||
581 !(valPE2 & 0x01000000)) {
582 printk(KERN_INFO "PCIE: SDR0_PExRCSSET rstgu error\n");
583 err = -1;
584 }
585
586 /* SDR0_PExRCSSET rstdl */
587 if (!(valPE0 & 0x00010000) ||
588 !(valPE1 & 0x00010000) ||
589 !(valPE2 & 0x00010000)) {
590 printk(KERN_INFO "PCIE: SDR0_PExRCSSET rstdl error\n");
591 err = -1;
592 }
593
594 /* SDR0_PExRCSSET rstpyn */
595 if ((valPE0 & 0x00001000) ||
596 (valPE1 & 0x00001000) ||
597 (valPE2 & 0x00001000)) {
598 printk(KERN_INFO "PCIE: SDR0_PExRCSSET rstpyn error\n");
599 err = -1;
600 }
601
602 /* SDR0_PExRCSSET hldplb */
603 if ((valPE0 & 0x10000000) ||
604 (valPE1 & 0x10000000) ||
605 (valPE2 & 0x10000000)) {
606 printk(KERN_INFO "PCIE: SDR0_PExRCSSET hldplb error\n");
607 err = -1;
608 }
609
610 /* SDR0_PExRCSSET rdy */
611 if ((valPE0 & 0x00100000) ||
612 (valPE1 & 0x00100000) ||
613 (valPE2 & 0x00100000)) {
614 printk(KERN_INFO "PCIE: SDR0_PExRCSSET rdy error\n");
615 err = -1;
616 }
617
618 /* SDR0_PExRCSSET shutdown */
619 if ((valPE0 & 0x00000100) ||
620 (valPE1 & 0x00000100) ||
621 (valPE2 & 0x00000100)) {
622 printk(KERN_INFO "PCIE: SDR0_PExRCSSET shutdown error\n");
623 err = -1;
624 }
625
626 return err;
627}
628
629/* Global PCIe core initializations for 440SPe core */
630static int __init ppc440spe_pciex_core_init(struct device_node *np)
631{
632 int time_out = 20;
633
634 /* Set PLL clock receiver to LVPECL */
635 mtdcri(SDR0, PESDR0_PLLLCT1, mfdcri(SDR0, PESDR0_PLLLCT1) | 1 << 28);
636
637 /* Shouldn't we do all the calibration stuff etc... here ? */
638 if (ppc440spe_pciex_check_reset(np))
639 return -ENXIO;
640
641 if (!(mfdcri(SDR0, PESDR0_PLLLCT2) & 0x10000)) {
642 printk(KERN_INFO "PCIE: PESDR_PLLCT2 resistance calibration "
643 "failed (0x%08x)\n",
644 mfdcri(SDR0, PESDR0_PLLLCT2));
645 return -1;
646 }
647
648 /* De-assert reset of PCIe PLL, wait for lock */
649 mtdcri(SDR0, PESDR0_PLLLCT1,
650 mfdcri(SDR0, PESDR0_PLLLCT1) & ~(1 << 24));
651 udelay(3);
652
653 while (time_out) {
654 if (!(mfdcri(SDR0, PESDR0_PLLLCT3) & 0x10000000)) {
655 time_out--;
656 udelay(1);
657 } else
658 break;
659 }
660 if (!time_out) {
661 printk(KERN_INFO "PCIE: VCO output not locked\n");
662 return -1;
663 }
664
665 pr_debug("PCIE initialization OK\n");
666
667 return 3;
668}
669
670static int ppc440spe_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
671{
672 u32 val = 1 << 24;
673
674 if (port->endpoint)
675 val = PTYPE_LEGACY_ENDPOINT << 20;
676 else
677 val = PTYPE_ROOT_PORT << 20;
678
679 if (port->index == 0)
680 val |= LNKW_X8 << 12;
681 else
682 val |= LNKW_X4 << 12;
683
684 mtdcri(SDR0, port->sdr_base + PESDRn_DLPSET, val);
685 mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET1, 0x20222222);
686 if (of_device_is_compatible(port->node, "ibm,plb-pciex-440speA"))
687 mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET2, 0x11000000);
688 mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL0SET1, 0x35000000);
689 mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL1SET1, 0x35000000);
690 mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL2SET1, 0x35000000);
691 mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL3SET1, 0x35000000);
692 if (port->index == 0) {
693 mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL4SET1,
694 0x35000000);
695 mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL5SET1,
696 0x35000000);
697 mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL6SET1,
698 0x35000000);
699 mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL7SET1,
700 0x35000000);
701 }
702 val = mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET);
703 mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET,
704 (val & ~(1 << 24 | 1 << 16)) | 1 << 12);
705
706 return 0;
707}
708
709static int ppc440speA_pciex_init_utl(struct ppc4xx_pciex_port *port)
710{
711 void __iomem *utl_base;
712
713 /* XXX Check what that value means... I hate magic */
714 dcr_write(port->dcrs, DCRO_PEGPL_SPECIAL, 0x68782800);
715
716 utl_base = ioremap(port->utl_regs.start, 0x100);
717 BUG_ON(utl_base == NULL);
718
719 /*
720 * Set buffer allocations and then assert VRB and TXE.
721 */
722 out_be32(utl_base + PEUTL_OUTTR, 0x08000000);
723 out_be32(utl_base + PEUTL_INTR, 0x02000000);
724 out_be32(utl_base + PEUTL_OPDBSZ, 0x10000000);
725 out_be32(utl_base + PEUTL_PBBSZ, 0x53000000);
726 out_be32(utl_base + PEUTL_IPHBSZ, 0x08000000);
727 out_be32(utl_base + PEUTL_IPDBSZ, 0x10000000);
728 out_be32(utl_base + PEUTL_RCIRQEN, 0x00f00000);
729 out_be32(utl_base + PEUTL_PCTL, 0x80800066);
730
731 iounmap(utl_base);
732
733 return 0;
734}
735
736static struct ppc4xx_pciex_hwops ppc440speA_pcie_hwops __initdata =
737{
738 .core_init = ppc440spe_pciex_core_init,
739 .port_init_hw = ppc440spe_pciex_init_port_hw,
740 .setup_utl = ppc440speA_pciex_init_utl,
741};
742
743static struct ppc4xx_pciex_hwops ppc440speB_pcie_hwops __initdata =
744{
745 .core_init = ppc440spe_pciex_core_init,
746 .port_init_hw = ppc440spe_pciex_init_port_hw,
747};
748
749
750#endif /* CONFIG_44x */
751
752#ifdef CONFIG_40x
753
754static int __init ppc405ex_pciex_core_init(struct device_node *np)
755{
756 /* Nothing to do, return 2 ports */
757 return 2;
758}
759
760static void ppc405ex_pcie_phy_reset(struct ppc4xx_pciex_port *port)
761{
762 /* Assert the PE0_PHY reset */
763 mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x01010000);
764 msleep(1);
765
766 /* deassert the PE0_hotreset */
767 if (port->endpoint)
768 mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x01111000);
769 else
770 mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x01101000);
771
772 /* poll for phy !reset */
773 /* XXX FIXME add timeout */
774 while (!(mfdcri(SDR0, port->sdr_base + PESDRn_405EX_PHYSTA) & 0x00001000))
775 ;
776
777 /* deassert the PE0_gpl_utl_reset */
778 mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x00101000);
779}
780
781static int ppc405ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
782{
783 u32 val;
784
785 if (port->endpoint)
786 val = PTYPE_LEGACY_ENDPOINT;
787 else
788 val = PTYPE_ROOT_PORT;
789
790 mtdcri(SDR0, port->sdr_base + PESDRn_DLPSET,
791 1 << 24 | val << 20 | LNKW_X1 << 12);
792
793 mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET1, 0x00000000);
794 mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET2, 0x01010000);
795 mtdcri(SDR0, port->sdr_base + PESDRn_405EX_PHYSET1, 0x720F0000);
796 mtdcri(SDR0, port->sdr_base + PESDRn_405EX_PHYSET2, 0x70600003);
797
798 /*
799 * Only reset the PHY when no link is currently established.
800 * This is for the Atheros PCIe board which has problems to establish
801 * the link (again) after this PHY reset. All other currently tested
802 * PCIe boards don't show this problem.
803 * This has to be re-tested and fixed in a later release!
804 */
805#if 0 /* XXX FIXME: Not resetting the PHY will leave all resources
806 * configured as done previously by U-Boot. Then Linux will currently
807 * not reassign them. So the PHY reset is now done always. This will
808 * lead to problems with the Atheros PCIe board again.
809 */
810 val = mfdcri(SDR0, port->sdr_base + PESDRn_LOOP);
811 if (!(val & 0x00001000))
812 ppc405ex_pcie_phy_reset(port);
813#else
814 ppc405ex_pcie_phy_reset(port);
815#endif
816
817 dcr_write(port->dcrs, DCRO_PEGPL_CFG, 0x10000000); /* guarded on */
818
819 return 0;
820}
821
822static int ppc405ex_pciex_init_utl(struct ppc4xx_pciex_port *port)
823{
824 void __iomem *utl_base;
825
826 dcr_write(port->dcrs, DCRO_PEGPL_SPECIAL, 0x0);
827
828 utl_base = ioremap(port->utl_regs.start, 0x100);
829 BUG_ON(utl_base == NULL);
830
831 /*
832 * Set buffer allocations and then assert VRB and TXE.
833 */
834 out_be32(utl_base + PEUTL_OUTTR, 0x02000000);
835 out_be32(utl_base + PEUTL_INTR, 0x02000000);
836 out_be32(utl_base + PEUTL_OPDBSZ, 0x04000000);
837 out_be32(utl_base + PEUTL_PBBSZ, 0x21000000);
838 out_be32(utl_base + PEUTL_IPHBSZ, 0x02000000);
839 out_be32(utl_base + PEUTL_IPDBSZ, 0x04000000);
840 out_be32(utl_base + PEUTL_RCIRQEN, 0x00f00000);
841 out_be32(utl_base + PEUTL_PCTL, 0x80800066);
842
843 out_be32(utl_base + PEUTL_PBCTL, 0x0800000c);
844 out_be32(utl_base + PEUTL_RCSTA,
845 in_be32(utl_base + PEUTL_RCSTA) | 0x000040000);
846
847 iounmap(utl_base);
848
849 return 0;
850}
851
852static struct ppc4xx_pciex_hwops ppc405ex_pcie_hwops __initdata =
853{
854 .core_init = ppc405ex_pciex_core_init,
855 .port_init_hw = ppc405ex_pciex_init_port_hw,
856 .setup_utl = ppc405ex_pciex_init_utl,
857};
858
859#endif /* CONFIG_40x */
860
861
862/* Check that the core has been initied and if not, do it */
863static int __init ppc4xx_pciex_check_core_init(struct device_node *np)
864{
865 static int core_init;
866 int count = -ENODEV;
867
868 if (core_init++)
869 return 0;
870
871#ifdef CONFIG_44x
872 if (of_device_is_compatible(np, "ibm,plb-pciex-440speA"))
873 ppc4xx_pciex_hwops = &ppc440speA_pcie_hwops;
874 else if (of_device_is_compatible(np, "ibm,plb-pciex-440speB"))
875 ppc4xx_pciex_hwops = &ppc440speB_pcie_hwops;
876#endif /* CONFIG_44x */
877#ifdef CONFIG_40x
878 if (of_device_is_compatible(np, "ibm,plb-pciex-405ex"))
879 ppc4xx_pciex_hwops = &ppc405ex_pcie_hwops;
880#endif
881 if (ppc4xx_pciex_hwops == NULL) {
882 printk(KERN_WARNING "PCIE: unknown host type %s\n",
883 np->full_name);
884 return -ENODEV;
885 }
886
887 count = ppc4xx_pciex_hwops->core_init(np);
888 if (count > 0) {
889 ppc4xx_pciex_ports =
890 kzalloc(count * sizeof(struct ppc4xx_pciex_port),
891 GFP_KERNEL);
892 if (ppc4xx_pciex_ports) {
893 ppc4xx_pciex_port_count = count;
894 return 0;
895 }
896 printk(KERN_WARNING "PCIE: failed to allocate ports array\n");
897 return -ENOMEM;
898 }
899 return -ENODEV;
900}
901
902static void __init ppc4xx_pciex_port_init_mapping(struct ppc4xx_pciex_port *port)
903{
904 /* We map PCI Express configuration based on the reg property */
905 dcr_write(port->dcrs, DCRO_PEGPL_CFGBAH,
906 RES_TO_U32_HIGH(port->cfg_space.start));
907 dcr_write(port->dcrs, DCRO_PEGPL_CFGBAL,
908 RES_TO_U32_LOW(port->cfg_space.start));
909
910 /* XXX FIXME: Use size from reg property. For now, map 512M */
911 dcr_write(port->dcrs, DCRO_PEGPL_CFGMSK, 0xe0000001);
912
913 /* We map UTL registers based on the reg property */
914 dcr_write(port->dcrs, DCRO_PEGPL_REGBAH,
915 RES_TO_U32_HIGH(port->utl_regs.start));
916 dcr_write(port->dcrs, DCRO_PEGPL_REGBAL,
917 RES_TO_U32_LOW(port->utl_regs.start));
918
919 /* XXX FIXME: Use size from reg property */
920 dcr_write(port->dcrs, DCRO_PEGPL_REGMSK, 0x00007001);
921
922 /* Disable all other outbound windows */
923 dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, 0);
924 dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKL, 0);
925 dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKL, 0);
926 dcr_write(port->dcrs, DCRO_PEGPL_MSGMSK, 0);
927}
928
929static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port)
930{
931 int attempts, rc = 0;
932 u32 val;
933
934 /* Check if it's endpoint or root complex
935 *
936 * XXX Do we want to use the device-tree instead ? --BenH.
937 */
938 val = mfdcri(SDR0, port->sdr_base + PESDRn_DLPSET);
939 port->endpoint = (((val >> 20) & 0xf) != PTYPE_ROOT_PORT);
940
941 /* Init HW */
942 if (ppc4xx_pciex_hwops->port_init_hw)
943 rc = ppc4xx_pciex_hwops->port_init_hw(port);
944 if (rc != 0)
945 return rc;
946
947 /*
948 * Notice: the following delay has critical impact on device
949 * initialization - if too short (<50ms) the link doesn't get up.
950 *
951 * XXX FIXME: There are various issues with that link up thingy,
952 * we could just wait for the link with a timeout but Stefan says
953 * some cards need more time even after the link is up. I'll
954 * investigate. For now, we keep a fixed 1s delay.
955 *
956 * Ultimately, it should be made asynchronous so all ports are
957 * brought up simultaneously though.
958 */
959 printk(KERN_INFO "PCIE%d: Waiting for link to go up...\n",
960 port->index);
961 msleep(1000);
962
963 /*
964 * Check that we exited the reset state properly
965 */
966 val = mfdcri(SDR0, port->sdr_base + PESDRn_RCSSTS);
967 if (val & (1 << 20)) {
968 printk(KERN_WARNING "PCIE%d: PGRST failed %08x\n",
969 port->index, val);
970 return -1;
971 }
972
973 /*
974 * Verify link is up
975 */
976 val = mfdcri(SDR0, port->sdr_base + PESDRn_LOOP);
977 if (!(val & 0x00001000)) {
978 printk(KERN_INFO "PCIE%d: link is not up !\n",
979 port->index);
980 return -1;
981 }
982
983 printk(KERN_INFO "PCIE%d: link is up !\n",
984 port->index);
985
986 /*
987 * Initialize mapping: disable all regions and configure
988 * CFG and REG regions based on resources in the device tree
989 */
990 ppc4xx_pciex_port_init_mapping(port);
991
992 /*
993 * Setup UTL registers - but only on revA!
994 * We use default settings for revB chip.
995 *
996 * To be reworked. We may also be able to move that to
997 * before the link wait
998 * --BenH.
999 */
1000 if (ppc4xx_pciex_hwops->setup_utl)
1001 ppc4xx_pciex_hwops->setup_utl(port);
1002
1003 /*
1004 * Check for VC0 active and assert RDY.
1005 */
1006 attempts = 10;
1007 while (!(mfdcri(SDR0, port->sdr_base + PESDRn_RCSSTS) & (1 << 16))) {
1008 if (!(attempts--)) {
1009 printk(KERN_INFO "PCIE%d: VC0 not active\n",
1010 port->index);
1011 return -1;
1012 }
1013 msleep(1000);
1014 }
1015 mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET,
1016 mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET) | 1 << 20);
1017 msleep(100);
1018
1019 return 0;
1020}
1021
1022static int ppc4xx_pciex_validate_bdf(struct ppc4xx_pciex_port *port,
1023 struct pci_bus *bus,
1024 unsigned int devfn)
1025{
1026 static int message;
1027
1028 /* Endpoint can not generate upstream(remote) config cycles */
1029 if (port->endpoint && bus->number != port->hose->first_busno)
1030 return PCIBIOS_DEVICE_NOT_FOUND;
1031
1032 /* Check we are within the mapped range */
1033 if (bus->number > port->hose->last_busno) {
1034 if (!message) {
1035 printk(KERN_WARNING "Warning! Probing bus %u"
1036 " out of range !\n", bus->number);
1037 message++;
1038 }
1039 return PCIBIOS_DEVICE_NOT_FOUND;
1040 }
1041
1042 /* The root complex has only one device / function */
1043 if (bus->number == port->hose->first_busno && devfn != 0)
1044 return PCIBIOS_DEVICE_NOT_FOUND;
1045
1046 /* The other side of the RC has only one device as well */
1047 if (bus->number == (port->hose->first_busno + 1) &&
1048 PCI_SLOT(devfn) != 0)
1049 return PCIBIOS_DEVICE_NOT_FOUND;
1050
1051 return 0;
1052}
1053
1054static void __iomem *ppc4xx_pciex_get_config_base(struct ppc4xx_pciex_port *port,
1055 struct pci_bus *bus,
1056 unsigned int devfn)
1057{
1058 int relbus;
1059
1060 /* Remove the casts when we finally remove the stupid volatile
1061 * in struct pci_controller
1062 */
1063 if (bus->number == port->hose->first_busno)
1064 return (void __iomem *)port->hose->cfg_addr;
1065
1066 relbus = bus->number - (port->hose->first_busno + 1);
1067 return (void __iomem *)port->hose->cfg_data +
1068 ((relbus << 20) | (devfn << 12));
1069}
1070
1071static int ppc4xx_pciex_read_config(struct pci_bus *bus, unsigned int devfn,
1072 int offset, int len, u32 *val)
1073{
1074 struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
1075 struct ppc4xx_pciex_port *port =
1076 &ppc4xx_pciex_ports[hose->indirect_type];
1077 void __iomem *addr;
1078 u32 gpl_cfg;
1079
1080 BUG_ON(hose != port->hose);
1081
1082 if (ppc4xx_pciex_validate_bdf(port, bus, devfn) != 0)
1083 return PCIBIOS_DEVICE_NOT_FOUND;
1084
1085 addr = ppc4xx_pciex_get_config_base(port, bus, devfn);
1086
1087 /*
1088 * Reading from configuration space of non-existing device can
1089 * generate transaction errors. For the read duration we suppress
1090 * assertion of machine check exceptions to avoid those.
1091 */
1092 gpl_cfg = dcr_read(port->dcrs, DCRO_PEGPL_CFG);
1093 dcr_write(port->dcrs, DCRO_PEGPL_CFG, gpl_cfg | GPL_DMER_MASK_DISA);
1094
1095 switch (len) {
1096 case 1:
1097 *val = in_8((u8 *)(addr + offset));
1098 break;
1099 case 2:
1100 *val = in_le16((u16 *)(addr + offset));
1101 break;
1102 default:
1103 *val = in_le32((u32 *)(addr + offset));
1104 break;
1105 }
1106
1107 pr_debug("pcie-config-read: bus=%3d [%3d..%3d] devfn=0x%04x"
1108 " offset=0x%04x len=%d, addr=0x%p val=0x%08x\n",
1109 bus->number, hose->first_busno, hose->last_busno,
1110 devfn, offset, len, addr + offset, *val);
1111
1112 dcr_write(port->dcrs, DCRO_PEGPL_CFG, gpl_cfg);
1113
1114 return PCIBIOS_SUCCESSFUL;
1115}
1116
1117static int ppc4xx_pciex_write_config(struct pci_bus *bus, unsigned int devfn,
1118 int offset, int len, u32 val)
1119{
1120 struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
1121 struct ppc4xx_pciex_port *port =
1122 &ppc4xx_pciex_ports[hose->indirect_type];
1123 void __iomem *addr;
1124 u32 gpl_cfg;
1125
1126 if (ppc4xx_pciex_validate_bdf(port, bus, devfn) != 0)
1127 return PCIBIOS_DEVICE_NOT_FOUND;
1128
1129 addr = ppc4xx_pciex_get_config_base(port, bus, devfn);
1130
1131 /*
1132 * Reading from configuration space of non-existing device can
1133 * generate transaction errors. For the read duration we suppress
1134 * assertion of machine check exceptions to avoid those.
1135 */
1136 gpl_cfg = dcr_read(port->dcrs, DCRO_PEGPL_CFG);
1137 dcr_write(port->dcrs, DCRO_PEGPL_CFG, gpl_cfg | GPL_DMER_MASK_DISA);
1138
1139 pr_debug("pcie-config-write: bus=%3d [%3d..%3d] devfn=0x%04x"
1140 " offset=0x%04x len=%d, addr=0x%p val=0x%08x\n",
1141 bus->number, hose->first_busno, hose->last_busno,
1142 devfn, offset, len, addr + offset, val);
1143
1144 switch (len) {
1145 case 1:
1146 out_8((u8 *)(addr + offset), val);
1147 break;
1148 case 2:
1149 out_le16((u16 *)(addr + offset), val);
1150 break;
1151 default:
1152 out_le32((u32 *)(addr + offset), val);
1153 break;
1154 }
1155
1156 dcr_write(port->dcrs, DCRO_PEGPL_CFG, gpl_cfg);
1157
1158 return PCIBIOS_SUCCESSFUL;
1159}
1160
1161static struct pci_ops ppc4xx_pciex_pci_ops =
1162{
1163 .read = ppc4xx_pciex_read_config,
1164 .write = ppc4xx_pciex_write_config,
1165};
1166
1167static void __init ppc4xx_configure_pciex_POMs(struct ppc4xx_pciex_port *port,
1168 struct pci_controller *hose,
1169 void __iomem *mbase)
1170{
1171 u32 lah, lal, pciah, pcial, sa;
1172 int i, j;
1173
1174 /* Setup outbound memory windows */
1175 for (i = j = 0; i < 3; i++) {
1176 struct resource *res = &hose->mem_resources[i];
1177
1178 /* we only care about memory windows */
1179 if (!(res->flags & IORESOURCE_MEM))
1180 continue;
1181 if (j > 1) {
1182 printk(KERN_WARNING "%s: Too many ranges\n",
1183 port->node->full_name);
1184 break;
1185 }
1186
1187 /* Calculate register values */
1188 lah = RES_TO_U32_HIGH(res->start);
1189 lal = RES_TO_U32_LOW(res->start);
1190 pciah = RES_TO_U32_HIGH(res->start - hose->pci_mem_offset);
1191 pcial = RES_TO_U32_LOW(res->start - hose->pci_mem_offset);
1192 sa = res->end + 1 - res->start;
1193 if (!is_power_of_2(sa) || sa < 0x100000 ||
1194 sa > 0xffffffffu) {
1195 printk(KERN_WARNING "%s: Resource out of range\n",
1196 port->node->full_name);
1197 continue;
1198 }
1199 sa = (0xffffffffu << ilog2(sa)) | 0x1;
1200
1201 /* Program register values */
1202 switch (j) {
1203 case 0:
1204 out_le32(mbase + PECFG_POM0LAH, pciah);
1205 out_le32(mbase + PECFG_POM0LAL, pcial);
1206 dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAH, lah);
1207 dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAL, lal);
1208 dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKH, 0x7fffffff);
1209 dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, sa | 3);
1210 break;
1211 case 1:
1212 out_le32(mbase + PECFG_POM1LAH, pciah);
1213 out_le32(mbase + PECFG_POM1LAL, pcial);
1214 dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAH, lah);
1215 dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAL, lal);
1216 dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKH, 0x7fffffff);
1217 dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKL, sa | 3);
1218 break;
1219 }
1220 j++;
1221 }
1222
1223 /* Configure IO, always 64K starting at 0 */
1224 if (hose->io_resource.flags & IORESOURCE_IO) {
1225 lah = RES_TO_U32_HIGH(hose->io_base_phys);
1226 lal = RES_TO_U32_LOW(hose->io_base_phys);
1227 out_le32(mbase + PECFG_POM2LAH, 0);
1228 out_le32(mbase + PECFG_POM2LAL, 0);
1229 dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAH, lah);
1230 dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAL, lal);
1231 dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKH, 0x7fffffff);
1232 dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKL, 0xffff0000 | 3);
1233 }
1234}
1235
1236static void __init ppc4xx_configure_pciex_PIMs(struct ppc4xx_pciex_port *port,
1237 struct pci_controller *hose,
1238 void __iomem *mbase,
1239 struct resource *res)
1240{
1241 resource_size_t size = res->end - res->start + 1;
1242 u64 sa;
1243
1244 /* Calculate window size */
1245 sa = (0xffffffffffffffffull << ilog2(size));;
1246 if (res->flags & IORESOURCE_PREFETCH)
1247 sa |= 0x8;
1248
1249 out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa));
1250 out_le32(mbase + PECFG_BAR0LMPA, RES_TO_U32_LOW(sa));
1251
1252 /* The setup of the split looks weird to me ... let's see if it works */
1253 out_le32(mbase + PECFG_PIM0LAL, 0x00000000);
1254 out_le32(mbase + PECFG_PIM0LAH, 0x00000000);
1255 out_le32(mbase + PECFG_PIM1LAL, 0x00000000);
1256 out_le32(mbase + PECFG_PIM1LAH, 0x00000000);
1257 out_le32(mbase + PECFG_PIM01SAH, 0xffff0000);
1258 out_le32(mbase + PECFG_PIM01SAL, 0x00000000);
1259
1260 /* Enable inbound mapping */
1261 out_le32(mbase + PECFG_PIMEN, 0x1);
1262
1263 out_le32(mbase + PCI_BASE_ADDRESS_0, RES_TO_U32_LOW(res->start));
1264 out_le32(mbase + PCI_BASE_ADDRESS_1, RES_TO_U32_HIGH(res->start));
1265
1266 /* Enable I/O, Mem, and Busmaster cycles */
1267 out_le16(mbase + PCI_COMMAND,
1268 in_le16(mbase + PCI_COMMAND) |
1269 PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
1270}
1271
1272static void __init ppc4xx_pciex_port_setup_hose(struct ppc4xx_pciex_port *port)
1273{
1274 struct resource dma_window;
1275 struct pci_controller *hose = NULL;
1276 const int *bus_range;
1277 int primary = 0, busses;
1278 void __iomem *mbase = NULL, *cfg_data = NULL;
1279
1280 /* XXX FIXME: Handle endpoint mode properly */
1281 if (port->endpoint)
1282 return;
1283
1284 /* Check if primary bridge */
1285 if (of_get_property(port->node, "primary", NULL))
1286 primary = 1;
1287
1288 /* Get bus range if any */
1289 bus_range = of_get_property(port->node, "bus-range", NULL);
1290
1291 /* Allocate the host controller data structure */
1292 hose = pcibios_alloc_controller(port->node);
1293 if (!hose)
1294 goto fail;
1295
1296 /* We stick the port number in "indirect_type" so the config space
1297 * ops can retrieve the port data structure easily
1298 */
1299 hose->indirect_type = port->index;
1300
1301 /* Get bus range */
1302 hose->first_busno = bus_range ? bus_range[0] : 0x0;
1303 hose->last_busno = bus_range ? bus_range[1] : 0xff;
1304
1305 /* Because of how big mapping the config space is (1M per bus), we
1306 * limit how many busses we support. In the long run, we could replace
1307 * that with something akin to kmap_atomic instead. We set aside 1 bus
1308 * for the host itself too.
1309 */
1310 busses = hose->last_busno - hose->first_busno; /* This is off by 1 */
1311 if (busses > MAX_PCIE_BUS_MAPPED) {
1312 busses = MAX_PCIE_BUS_MAPPED;
1313 hose->last_busno = hose->first_busno + busses;
1314 }
1315
1316 /* We map the external config space in cfg_data and the host config
1317 * space in cfg_addr. External space is 1M per bus, internal space
1318 * is 4K
1319 */
1320 cfg_data = ioremap(port->cfg_space.start +
1321 (hose->first_busno + 1) * 0x100000,
1322 busses * 0x100000);
1323 mbase = ioremap(port->cfg_space.start + 0x10000000, 0x1000);
1324 if (cfg_data == NULL || mbase == NULL) {
1325 printk(KERN_ERR "%s: Can't map config space !",
1326 port->node->full_name);
1327 goto fail;
1328 }
1329
1330 hose->cfg_data = cfg_data;
1331 hose->cfg_addr = mbase;
1332
1333 pr_debug("PCIE %s, bus %d..%d\n", port->node->full_name,
1334 hose->first_busno, hose->last_busno);
1335 pr_debug(" config space mapped at: root @0x%p, other @0x%p\n",
1336 hose->cfg_addr, hose->cfg_data);
1337
1338 /* Setup config space */
1339 hose->ops = &ppc4xx_pciex_pci_ops;
1340 port->hose = hose;
1341 mbase = (void __iomem *)hose->cfg_addr;
1342
1343 /*
1344 * Set bus numbers on our root port
1345 */
1346 out_8(mbase + PCI_PRIMARY_BUS, hose->first_busno);
1347 out_8(mbase + PCI_SECONDARY_BUS, hose->first_busno + 1);
1348 out_8(mbase + PCI_SUBORDINATE_BUS, hose->last_busno);
1349
1350 /*
1351 * OMRs are already reset, also disable PIMs
1352 */
1353 out_le32(mbase + PECFG_PIMEN, 0);
1354
1355 /* Parse outbound mapping resources */
1356 pci_process_bridge_OF_ranges(hose, port->node, primary);
1357
1358 /* Parse inbound mapping resources */
1359 if (ppc4xx_parse_dma_ranges(hose, mbase, &dma_window) != 0)
1360 goto fail;
1361
1362 /* Configure outbound ranges POMs */
1363 ppc4xx_configure_pciex_POMs(port, hose, mbase);
1364
1365 /* Configure inbound ranges PIMs */
1366 ppc4xx_configure_pciex_PIMs(port, hose, mbase, &dma_window);
1367
1368 /* The root complex doesn't show up if we don't set some vendor
1369 * and device IDs into it. Those are the same bogus one that the
1370 * initial code in arch/ppc add. We might want to change that.
1371 */
1372 out_le16(mbase + 0x200, 0xaaa0 + port->index);
1373 out_le16(mbase + 0x202, 0xbed0 + port->index);
1374
1375 /* Set Class Code to PCI-PCI bridge and Revision Id to 1 */
1376 out_le32(mbase + 0x208, 0x06040001);
1377
1378 printk(KERN_INFO "PCIE%d: successfully set as root-complex\n",
1379 port->index);
1380 return;
1381 fail:
1382 if (hose)
1383 pcibios_free_controller(hose);
1384 if (cfg_data)
1385 iounmap(cfg_data);
1386 if (mbase)
1387 iounmap(mbase);
1388}
1389
498static void __init ppc4xx_probe_pciex_bridge(struct device_node *np) 1390static void __init ppc4xx_probe_pciex_bridge(struct device_node *np)
499{ 1391{
500 /* NYI */ 1392 struct ppc4xx_pciex_port *port;
1393 const u32 *pval;
1394 int portno;
1395 unsigned int dcrs;
1396
1397 /* First, proceed to core initialization as we assume there's
1398 * only one PCIe core in the system
1399 */
1400 if (ppc4xx_pciex_check_core_init(np))
1401 return;
1402
1403 /* Get the port number from the device-tree */
1404 pval = of_get_property(np, "port", NULL);
1405 if (pval == NULL) {
1406 printk(KERN_ERR "PCIE: Can't find port number for %s\n",
1407 np->full_name);
1408 return;
1409 }
1410 portno = *pval;
1411 if (portno >= ppc4xx_pciex_port_count) {
1412 printk(KERN_ERR "PCIE: port number out of range for %s\n",
1413 np->full_name);
1414 return;
1415 }
1416 port = &ppc4xx_pciex_ports[portno];
1417 port->index = portno;
1418 port->node = of_node_get(np);
1419 pval = of_get_property(np, "sdr-base", NULL);
1420 if (pval == NULL) {
1421 printk(KERN_ERR "PCIE: missing sdr-base for %s\n",
1422 np->full_name);
1423 return;
1424 }
1425 port->sdr_base = *pval;
1426
1427 /* Fetch config space registers address */
1428 if (of_address_to_resource(np, 0, &port->cfg_space)) {
1429 printk(KERN_ERR "%s: Can't get PCI-E config space !",
1430 np->full_name);
1431 return;
1432 }
1433 /* Fetch host bridge internal registers address */
1434 if (of_address_to_resource(np, 1, &port->utl_regs)) {
1435 printk(KERN_ERR "%s: Can't get UTL register base !",
1436 np->full_name);
1437 return;
1438 }
1439
1440 /* Map DCRs */
1441 dcrs = dcr_resource_start(np, 0);
1442 if (dcrs == 0) {
1443 printk(KERN_ERR "%s: Can't get DCR register base !",
1444 np->full_name);
1445 return;
1446 }
1447 port->dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0));
1448
1449 /* Initialize the port specific registers */
1450 if (ppc4xx_pciex_port_init(port))
1451 return;
1452
1453 /* Setup the linux hose data structure */
1454 ppc4xx_pciex_port_setup_hose(port);
501} 1455}
502 1456
1457#endif /* CONFIG_PPC4xx_PCI_EXPRESS */
1458
503static int __init ppc4xx_pci_find_bridges(void) 1459static int __init ppc4xx_pci_find_bridges(void)
504{ 1460{
505 struct device_node *np; 1461 struct device_node *np;
506 1462
1463#ifdef CONFIG_PPC4xx_PCI_EXPRESS
507 for_each_compatible_node(np, NULL, "ibm,plb-pciex") 1464 for_each_compatible_node(np, NULL, "ibm,plb-pciex")
508 ppc4xx_probe_pciex_bridge(np); 1465 ppc4xx_probe_pciex_bridge(np);
1466#endif
509 for_each_compatible_node(np, NULL, "ibm,plb-pcix") 1467 for_each_compatible_node(np, NULL, "ibm,plb-pcix")
510 ppc4xx_probe_pcix_bridge(np); 1468 ppc4xx_probe_pcix_bridge(np);
511 for_each_compatible_node(np, NULL, "ibm,plb-pci") 1469 for_each_compatible_node(np, NULL, "ibm,plb-pci")
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.h b/arch/powerpc/sysdev/ppc4xx_pci.h
index 8b787bfdc8a5..43e51ce5c477 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.h
+++ b/arch/powerpc/sysdev/ppc4xx_pci.h
@@ -121,5 +121,247 @@
121#define PCIL0_PTM2MS 0x38 121#define PCIL0_PTM2MS 0x38
122#define PCIL0_PTM2LA 0x3c 122#define PCIL0_PTM2LA 0x3c
123 123
124/*
125 * 4xx PCIe bridge register definitions
126 */
127
128/* DCR offsets */
129#define DCRO_PEGPL_CFGBAH 0x00
130#define DCRO_PEGPL_CFGBAL 0x01
131#define DCRO_PEGPL_CFGMSK 0x02
132#define DCRO_PEGPL_MSGBAH 0x03
133#define DCRO_PEGPL_MSGBAL 0x04
134#define DCRO_PEGPL_MSGMSK 0x05
135#define DCRO_PEGPL_OMR1BAH 0x06
136#define DCRO_PEGPL_OMR1BAL 0x07
137#define DCRO_PEGPL_OMR1MSKH 0x08
138#define DCRO_PEGPL_OMR1MSKL 0x09
139#define DCRO_PEGPL_OMR2BAH 0x0a
140#define DCRO_PEGPL_OMR2BAL 0x0b
141#define DCRO_PEGPL_OMR2MSKH 0x0c
142#define DCRO_PEGPL_OMR2MSKL 0x0d
143#define DCRO_PEGPL_OMR3BAH 0x0e
144#define DCRO_PEGPL_OMR3BAL 0x0f
145#define DCRO_PEGPL_OMR3MSKH 0x10
146#define DCRO_PEGPL_OMR3MSKL 0x11
147#define DCRO_PEGPL_REGBAH 0x12
148#define DCRO_PEGPL_REGBAL 0x13
149#define DCRO_PEGPL_REGMSK 0x14
150#define DCRO_PEGPL_SPECIAL 0x15
151#define DCRO_PEGPL_CFG 0x16
152#define DCRO_PEGPL_ESR 0x17
153#define DCRO_PEGPL_EARH 0x18
154#define DCRO_PEGPL_EARL 0x19
155#define DCRO_PEGPL_EATR 0x1a
156
157/* DMER mask */
158#define GPL_DMER_MASK_DISA 0x02000000
159
160/*
161 * System DCRs (SDRs)
162 */
163#define PESDR0_PLLLCT1 0x03a0
164#define PESDR0_PLLLCT2 0x03a1
165#define PESDR0_PLLLCT3 0x03a2
166
167/*
168 * 440SPe additional DCRs
169 */
170#define PESDR0_440SPE_UTLSET1 0x0300
171#define PESDR0_440SPE_UTLSET2 0x0301
172#define PESDR0_440SPE_DLPSET 0x0302
173#define PESDR0_440SPE_LOOP 0x0303
174#define PESDR0_440SPE_RCSSET 0x0304
175#define PESDR0_440SPE_RCSSTS 0x0305
176#define PESDR0_440SPE_HSSL0SET1 0x0306
177#define PESDR0_440SPE_HSSL0SET2 0x0307
178#define PESDR0_440SPE_HSSL0STS 0x0308
179#define PESDR0_440SPE_HSSL1SET1 0x0309
180#define PESDR0_440SPE_HSSL1SET2 0x030a
181#define PESDR0_440SPE_HSSL1STS 0x030b
182#define PESDR0_440SPE_HSSL2SET1 0x030c
183#define PESDR0_440SPE_HSSL2SET2 0x030d
184#define PESDR0_440SPE_HSSL2STS 0x030e
185#define PESDR0_440SPE_HSSL3SET1 0x030f
186#define PESDR0_440SPE_HSSL3SET2 0x0310
187#define PESDR0_440SPE_HSSL3STS 0x0311
188#define PESDR0_440SPE_HSSL4SET1 0x0312
189#define PESDR0_440SPE_HSSL4SET2 0x0313
190#define PESDR0_440SPE_HSSL4STS 0x0314
191#define PESDR0_440SPE_HSSL5SET1 0x0315
192#define PESDR0_440SPE_HSSL5SET2 0x0316
193#define PESDR0_440SPE_HSSL5STS 0x0317
194#define PESDR0_440SPE_HSSL6SET1 0x0318
195#define PESDR0_440SPE_HSSL6SET2 0x0319
196#define PESDR0_440SPE_HSSL6STS 0x031a
197#define PESDR0_440SPE_HSSL7SET1 0x031b
198#define PESDR0_440SPE_HSSL7SET2 0x031c
199#define PESDR0_440SPE_HSSL7STS 0x031d
200#define PESDR0_440SPE_HSSCTLSET 0x031e
201#define PESDR0_440SPE_LANE_ABCD 0x031f
202#define PESDR0_440SPE_LANE_EFGH 0x0320
203
204#define PESDR1_440SPE_UTLSET1 0x0340
205#define PESDR1_440SPE_UTLSET2 0x0341
206#define PESDR1_440SPE_DLPSET 0x0342
207#define PESDR1_440SPE_LOOP 0x0343
208#define PESDR1_440SPE_RCSSET 0x0344
209#define PESDR1_440SPE_RCSSTS 0x0345
210#define PESDR1_440SPE_HSSL0SET1 0x0346
211#define PESDR1_440SPE_HSSL0SET2 0x0347
212#define PESDR1_440SPE_HSSL0STS 0x0348
213#define PESDR1_440SPE_HSSL1SET1 0x0349
214#define PESDR1_440SPE_HSSL1SET2 0x034a
215#define PESDR1_440SPE_HSSL1STS 0x034b
216#define PESDR1_440SPE_HSSL2SET1 0x034c
217#define PESDR1_440SPE_HSSL2SET2 0x034d
218#define PESDR1_440SPE_HSSL2STS 0x034e
219#define PESDR1_440SPE_HSSL3SET1 0x034f
220#define PESDR1_440SPE_HSSL3SET2 0x0350
221#define PESDR1_440SPE_HSSL3STS 0x0351
222#define PESDR1_440SPE_HSSCTLSET 0x0352
223#define PESDR1_440SPE_LANE_ABCD 0x0353
224
225#define PESDR2_440SPE_UTLSET1 0x0370
226#define PESDR2_440SPE_UTLSET2 0x0371
227#define PESDR2_440SPE_DLPSET 0x0372
228#define PESDR2_440SPE_LOOP 0x0373
229#define PESDR2_440SPE_RCSSET 0x0374
230#define PESDR2_440SPE_RCSSTS 0x0375
231#define PESDR2_440SPE_HSSL0SET1 0x0376
232#define PESDR2_440SPE_HSSL0SET2 0x0377
233#define PESDR2_440SPE_HSSL0STS 0x0378
234#define PESDR2_440SPE_HSSL1SET1 0x0379
235#define PESDR2_440SPE_HSSL1SET2 0x037a
236#define PESDR2_440SPE_HSSL1STS 0x037b
237#define PESDR2_440SPE_HSSL2SET1 0x037c
238#define PESDR2_440SPE_HSSL2SET2 0x037d
239#define PESDR2_440SPE_HSSL2STS 0x037e
240#define PESDR2_440SPE_HSSL3SET1 0x037f
241#define PESDR2_440SPE_HSSL3SET2 0x0380
242#define PESDR2_440SPE_HSSL3STS 0x0381
243#define PESDR2_440SPE_HSSCTLSET 0x0382
244#define PESDR2_440SPE_LANE_ABCD 0x0383
245
246/*
247 * 405EX additional DCRs
248 */
249#define PESDR0_405EX_UTLSET1 0x0400
250#define PESDR0_405EX_UTLSET2 0x0401
251#define PESDR0_405EX_DLPSET 0x0402
252#define PESDR0_405EX_LOOP 0x0403
253#define PESDR0_405EX_RCSSET 0x0404
254#define PESDR0_405EX_RCSSTS 0x0405
255#define PESDR0_405EX_PHYSET1 0x0406
256#define PESDR0_405EX_PHYSET2 0x0407
257#define PESDR0_405EX_BIST 0x0408
258#define PESDR0_405EX_LPB 0x040B
259#define PESDR0_405EX_PHYSTA 0x040C
260
261#define PESDR1_405EX_UTLSET1 0x0440
262#define PESDR1_405EX_UTLSET2 0x0441
263#define PESDR1_405EX_DLPSET 0x0442
264#define PESDR1_405EX_LOOP 0x0443
265#define PESDR1_405EX_RCSSET 0x0444
266#define PESDR1_405EX_RCSSTS 0x0445
267#define PESDR1_405EX_PHYSET1 0x0446
268#define PESDR1_405EX_PHYSET2 0x0447
269#define PESDR1_405EX_BIST 0x0448
270#define PESDR1_405EX_LPB 0x044B
271#define PESDR1_405EX_PHYSTA 0x044C
272
273/*
274 * Of the above, some are common offsets from the base
275 */
276#define PESDRn_UTLSET1 0x00
277#define PESDRn_UTLSET2 0x01
278#define PESDRn_DLPSET 0x02
279#define PESDRn_LOOP 0x03
280#define PESDRn_RCSSET 0x04
281#define PESDRn_RCSSTS 0x05
282
283/* 440spe only */
284#define PESDRn_440SPE_HSSL0SET1 0x06
285#define PESDRn_440SPE_HSSL0SET2 0x07
286#define PESDRn_440SPE_HSSL0STS 0x08
287#define PESDRn_440SPE_HSSL1SET1 0x09
288#define PESDRn_440SPE_HSSL1SET2 0x0a
289#define PESDRn_440SPE_HSSL1STS 0x0b
290#define PESDRn_440SPE_HSSL2SET1 0x0c
291#define PESDRn_440SPE_HSSL2SET2 0x0d
292#define PESDRn_440SPE_HSSL2STS 0x0e
293#define PESDRn_440SPE_HSSL3SET1 0x0f
294#define PESDRn_440SPE_HSSL3SET2 0x10
295#define PESDRn_440SPE_HSSL3STS 0x11
296
297/* 440spe port 0 only */
298#define PESDRn_440SPE_HSSL4SET1 0x12
299#define PESDRn_440SPE_HSSL4SET2 0x13
300#define PESDRn_440SPE_HSSL4STS 0x14
301#define PESDRn_440SPE_HSSL5SET1 0x15
302#define PESDRn_440SPE_HSSL5SET2 0x16
303#define PESDRn_440SPE_HSSL5STS 0x17
304#define PESDRn_440SPE_HSSL6SET1 0x18
305#define PESDRn_440SPE_HSSL6SET2 0x19
306#define PESDRn_440SPE_HSSL6STS 0x1a
307#define PESDRn_440SPE_HSSL7SET1 0x1b
308#define PESDRn_440SPE_HSSL7SET2 0x1c
309#define PESDRn_440SPE_HSSL7STS 0x1d
310
311/* 405ex only */
312#define PESDRn_405EX_PHYSET1 0x06
313#define PESDRn_405EX_PHYSET2 0x07
314#define PESDRn_405EX_PHYSTA 0x0c
315
316/*
317 * UTL register offsets
318 */
319#define PEUTL_PBCTL 0x00
320#define PEUTL_PBBSZ 0x20
321#define PEUTL_OPDBSZ 0x68
322#define PEUTL_IPHBSZ 0x70
323#define PEUTL_IPDBSZ 0x78
324#define PEUTL_OUTTR 0x90
325#define PEUTL_INTR 0x98
326#define PEUTL_PCTL 0xa0
327#define PEUTL_RCSTA 0xB0
328#define PEUTL_RCIRQEN 0xb8
329
330/*
331 * Config space register offsets
332 */
333#define PECFG_BAR0LMPA 0x210
334#define PECFG_BAR0HMPA 0x214
335#define PECFG_BAR1MPA 0x218
336#define PECFG_BAR2LMPA 0x220
337#define PECFG_BAR2HMPA 0x224
338
339#define PECFG_PIMEN 0x33c
340#define PECFG_PIM0LAL 0x340
341#define PECFG_PIM0LAH 0x344
342#define PECFG_PIM1LAL 0x348
343#define PECFG_PIM1LAH 0x34c
344#define PECFG_PIM01SAL 0x350
345#define PECFG_PIM01SAH 0x354
346
347#define PECFG_POM0LAL 0x380
348#define PECFG_POM0LAH 0x384
349#define PECFG_POM1LAL 0x388
350#define PECFG_POM1LAH 0x38c
351#define PECFG_POM2LAL 0x390
352#define PECFG_POM2LAH 0x394
353
354
355enum
356{
357 PTYPE_ENDPOINT = 0x0,
358 PTYPE_LEGACY_ENDPOINT = 0x1,
359 PTYPE_ROOT_PORT = 0x4,
360
361 LNKW_X1 = 0x1,
362 LNKW_X4 = 0x4,
363 LNKW_X8 = 0x8
364};
365
124 366
125#endif /* __PPC4XX_PCI_H__ */ 367#endif /* __PPC4XX_PCI_H__ */