aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/Kconfig1
-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
4 files changed, 1227 insertions, 18 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index d40844f9b047..66a3d8cee5cf 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -166,6 +166,7 @@ config PPC_OF_PLATFORM_PCI
166 166
167source "init/Kconfig" 167source "init/Kconfig"
168 168
169source "arch/powerpc/sysdev/Kconfig"
169source "arch/powerpc/platforms/Kconfig" 170source "arch/powerpc/platforms/Kconfig"
170 171
171menu "Kernel options" 172menu "Kernel options"
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__ */