|
@@ -73,23 +73,30 @@
|
|
|
|
|
|
#include <common.h>
|
|
|
#include <command.h>
|
|
|
-#if !defined(CONFIG_440)
|
|
|
#include <asm/4xx_pci.h>
|
|
|
-#endif
|
|
|
#include <asm/processor.h>
|
|
|
+#include <asm/io.h>
|
|
|
#include <pci.h>
|
|
|
|
|
|
#ifdef CONFIG_PCI
|
|
|
|
|
|
DECLARE_GLOBAL_DATA_PTR;
|
|
|
|
|
|
+#if defined(CONFIG_405GP) || defined(CONFIG_405EP)
|
|
|
+
|
|
|
+#if defined(CONFIG_PMC405)
|
|
|
+ushort pmc405_pci_subsys_deviceid(void);
|
|
|
+#endif
|
|
|
+
|
|
|
+/*#define DEBUG*/
|
|
|
+
|
|
|
/*
|
|
|
* Board-specific pci initialization
|
|
|
* Platform code can reimplement pci_pre_init() if needed
|
|
|
*/
|
|
|
int __pci_pre_init(struct pci_controller *hose)
|
|
|
{
|
|
|
-#if defined (CONFIG_405EP)
|
|
|
+#if defined(CONFIG_405EP)
|
|
|
/*
|
|
|
* Enable the internal PCI arbiter by default.
|
|
|
*
|
|
@@ -105,15 +112,8 @@ int __pci_pre_init(struct pci_controller *hose)
|
|
|
|
|
|
return 1;
|
|
|
}
|
|
|
-int pci_pre_init(struct pci_controller *hose) __attribute__((weak, alias("__pci_pre_init")));
|
|
|
-
|
|
|
-#if defined(CONFIG_405GP) || defined(CONFIG_405EP)
|
|
|
-
|
|
|
-#if defined(CONFIG_PMC405)
|
|
|
-ushort pmc405_pci_subsys_deviceid(void);
|
|
|
-#endif
|
|
|
-
|
|
|
-/*#define DEBUG*/
|
|
|
+int pci_pre_init(struct pci_controller *hose)
|
|
|
+ __attribute__((weak, alias("__pci_pre_init")));
|
|
|
|
|
|
int __is_pci_host(struct pci_controller *hose)
|
|
|
{
|
|
@@ -231,7 +231,7 @@ void pci_405gp_init(struct pci_controller *hose)
|
|
|
pciauto_region_init(hose->pci_fb);
|
|
|
|
|
|
/* Let board change/modify hose & do initial checks */
|
|
|
- if (pci_pre_init (hose) == 0) {
|
|
|
+ if (pci_pre_init(hose) == 0) {
|
|
|
printf("PCI: Board-specific initialization failed.\n");
|
|
|
printf("PCI: Configuration aborted.\n");
|
|
|
return;
|
|
@@ -499,6 +499,211 @@ int __is_pci_host(struct pci_controller *hose)
|
|
|
int is_pci_host(struct pci_controller *hose)
|
|
|
__attribute__((weak, alias("__is_pci_host")));
|
|
|
|
|
|
+#if defined(CONFIG_440EP) || defined(CONFIG_440EPX) || \
|
|
|
+ defined(CONFIG_440GR) || defined(CONFIG_440GRX)
|
|
|
+
|
|
|
+#if defined(CONFIG_SYS_PCI_TARGET_INIT)
|
|
|
+/*
|
|
|
+ * pci_target_init
|
|
|
+ *
|
|
|
+ * The bootstrap configuration provides default settings for the pci
|
|
|
+ * inbound map (PIM). But the bootstrap config choices are limited and
|
|
|
+ * may not be sufficient for a given board.
|
|
|
+ */
|
|
|
+void __pci_target_init(struct pci_controller *hose)
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * Set up Direct MMIO registers
|
|
|
+ */
|
|
|
+
|
|
|
+ /*
|
|
|
+ * PowerPC440 EP PCI Master configuration.
|
|
|
+ * Map one 1Gig range of PLB/processor addresses to PCI memory space.
|
|
|
+ * PLB address 0xA0000000-0xDFFFFFFF ==> PCI address 0xA0000000-0xDFFFFFFF
|
|
|
+ * Use byte reversed out routines to handle endianess.
|
|
|
+ * Make this region non-prefetchable.
|
|
|
+ */
|
|
|
+ /* PMM0 Mask/Attribute - disabled b4 setting */
|
|
|
+ out_le32((void *)PCIL0_PMM0MA, 0x00000000);
|
|
|
+ /* PMM0 Local Address */
|
|
|
+ out_le32((void *)PCIL0_PMM0LA, CONFIG_SYS_PCI_MEMBASE);
|
|
|
+ /* PMM0 PCI Low Address */
|
|
|
+ out_le32((void *)PCIL0_PMM0PCILA, CONFIG_SYS_PCI_MEMBASE);
|
|
|
+ /* PMM0 PCI High Address */
|
|
|
+ out_le32((void *)PCIL0_PMM0PCIHA, 0x00000000);
|
|
|
+ /* 512M + No prefetching, and enable region */
|
|
|
+ out_le32((void *)PCIL0_PMM0MA, 0xE0000001);
|
|
|
+
|
|
|
+ /* PMM1 Mask/Attribute - disabled b4 setting */
|
|
|
+ out_le32((void *)PCIL0_PMM1MA, 0x00000000);
|
|
|
+ /* PMM1 Local Address */
|
|
|
+ out_le32((void *)PCIL0_PMM1LA, CONFIG_SYS_PCI_MEMBASE2);
|
|
|
+ /* PMM1 PCI Low Address */
|
|
|
+ out_le32((void *)PCIL0_PMM1PCILA, CONFIG_SYS_PCI_MEMBASE2);
|
|
|
+ /* PMM1 PCI High Address */
|
|
|
+ out_le32((void *)PCIL0_PMM1PCIHA, 0x00000000);
|
|
|
+ /* 512M + No prefetching, and enable region */
|
|
|
+ out_le32((void *)PCIL0_PMM1MA, 0xE0000001);
|
|
|
+
|
|
|
+ out_le32((void *)PCIL0_PTM1MS, 0x00000001); /* Memory Size/Attribute */
|
|
|
+ out_le32((void *)PCIL0_PTM1LA, 0); /* Local Addr. Reg */
|
|
|
+ out_le32((void *)PCIL0_PTM2MS, 0); /* Memory Size/Attribute */
|
|
|
+ out_le32((void *)PCIL0_PTM2LA, 0); /* Local Addr. Reg */
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Set up Configuration registers
|
|
|
+ */
|
|
|
+
|
|
|
+ /* Program the board's subsystem id/vendor id */
|
|
|
+ pci_write_config_word(0, PCI_SUBSYSTEM_VENDOR_ID,
|
|
|
+ CONFIG_SYS_PCI_SUBSYS_VENDORID);
|
|
|
+ pci_write_config_word(0, PCI_SUBSYSTEM_ID, CONFIG_SYS_PCI_SUBSYS_ID);
|
|
|
+
|
|
|
+ /* Configure command register as bus master */
|
|
|
+ pci_write_config_word(0, PCI_COMMAND, PCI_COMMAND_MASTER);
|
|
|
+
|
|
|
+ /* 240nS PCI clock */
|
|
|
+ pci_write_config_word(0, PCI_LATENCY_TIMER, 1);
|
|
|
+
|
|
|
+ /* No error reporting */
|
|
|
+ pci_write_config_word(0, PCI_ERREN, 0);
|
|
|
+
|
|
|
+ pci_write_config_dword(0, PCI_BRDGOPT2, 0x00000101);
|
|
|
+}
|
|
|
+#endif /* CONFIG_SYS_PCI_TARGET_INIT */
|
|
|
+
|
|
|
+/*
|
|
|
+ * pci_pre_init
|
|
|
+ *
|
|
|
+ * This routine is called just prior to registering the hose and gives
|
|
|
+ * the board the opportunity to check things. Returning a value of zero
|
|
|
+ * indicates that things are bad & PCI initialization should be aborted.
|
|
|
+ *
|
|
|
+ * Different boards may wish to customize the pci controller structure
|
|
|
+ * (add regions, override default access routines, etc) or perform
|
|
|
+ * certain pre-initialization actions.
|
|
|
+ *
|
|
|
+ */
|
|
|
+int __pci_pre_init(struct pci_controller *hose)
|
|
|
+{
|
|
|
+ u32 reg;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Set priority for all PLB3 devices to 0.
|
|
|
+ * Set PLB3 arbiter to fair mode.
|
|
|
+ */
|
|
|
+ mfsdr(SD0_AMP1, reg);
|
|
|
+ mtsdr(SD0_AMP1, (reg & 0x000000FF) | 0x0000FF00);
|
|
|
+ reg = mfdcr(PLB3_ACR);
|
|
|
+ mtdcr(PLB3_ACR, reg | 0x80000000);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Set priority for all PLB4 devices to 0.
|
|
|
+ */
|
|
|
+ mfsdr(SD0_AMP0, reg);
|
|
|
+ mtsdr(SD0_AMP0, (reg & 0x000000FF) | 0x0000FF00);
|
|
|
+ reg = mfdcr(PLB4_ACR) | 0xa0000000;
|
|
|
+ mtdcr(PLB4_ACR, reg);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Set Nebula PLB4 arbiter to fair mode.
|
|
|
+ */
|
|
|
+ /* Segment0 */
|
|
|
+ reg = (mfdcr(PLB0_ACR) & ~PLB0_ACR_PPM_MASK) | PLB0_ACR_PPM_FAIR;
|
|
|
+ reg = (reg & ~PLB0_ACR_HBU_MASK) | PLB0_ACR_HBU_ENABLED;
|
|
|
+ reg = (reg & ~PLB0_ACR_RDP_MASK) | PLB0_ACR_RDP_4DEEP;
|
|
|
+ reg = (reg & ~PLB0_ACR_WRP_MASK) | PLB0_ACR_WRP_2DEEP;
|
|
|
+ mtdcr(PLB0_ACR, reg);
|
|
|
+
|
|
|
+ /* Segment1 */
|
|
|
+ reg = (mfdcr(PLB1_ACR) & ~PLB1_ACR_PPM_MASK) | PLB1_ACR_PPM_FAIR;
|
|
|
+ reg = (reg & ~PLB1_ACR_HBU_MASK) | PLB1_ACR_HBU_ENABLED;
|
|
|
+ reg = (reg & ~PLB1_ACR_RDP_MASK) | PLB1_ACR_RDP_4DEEP;
|
|
|
+ reg = (reg & ~PLB1_ACR_WRP_MASK) | PLB1_ACR_WRP_2DEEP;
|
|
|
+ mtdcr(PLB1_ACR, reg);
|
|
|
+
|
|
|
+#if defined(CONFIG_SYS_PCI_BOARD_FIXUP_IRQ)
|
|
|
+ hose->fixup_irq = board_pci_fixup_irq;
|
|
|
+#endif
|
|
|
+
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+#else /* defined(CONFIG_440EP) ... */
|
|
|
+
|
|
|
+#if defined(CONFIG_SYS_PCI_TARGET_INIT)
|
|
|
+void __pci_target_init(struct pci_controller * hose)
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * Disable everything
|
|
|
+ */
|
|
|
+ out_le32((void *)PCIL0_PIM0SA, 0); /* disable */
|
|
|
+ out_le32((void *)PCIL0_PIM1SA, 0); /* disable */
|
|
|
+ out_le32((void *)PCIL0_PIM2SA, 0); /* disable */
|
|
|
+ out_le32((void *)PCIL0_EROMBA, 0); /* disable expansion rom */
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Map all of SDRAM to PCI address 0x0000_0000. Note that the 440
|
|
|
+ * strapping options do not support sizes such as 128/256 MB.
|
|
|
+ */
|
|
|
+ out_le32((void *)PCIL0_PIM0LAL, CONFIG_SYS_SDRAM_BASE);
|
|
|
+ out_le32((void *)PCIL0_PIM0LAH, 0);
|
|
|
+ out_le32((void *)PCIL0_PIM0SA, ~(gd->ram_size - 1) | 1);
|
|
|
+ out_le32((void *)PCIL0_BAR0, 0);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Program the board's subsystem id/vendor id
|
|
|
+ */
|
|
|
+ out_le16((void *)PCIL0_SBSYSVID, CONFIG_SYS_PCI_SUBSYS_VENDORID);
|
|
|
+ out_le16((void *)PCIL0_SBSYSID, CONFIG_SYS_PCI_SUBSYS_DEVICEID);
|
|
|
+
|
|
|
+ out_le16((void *)PCIL0_CMD, in_le16((void *)PCIL0_CMD) |
|
|
|
+ PCI_COMMAND_MEMORY);
|
|
|
+}
|
|
|
+#endif /* CONFIG_SYS_PCI_TARGET_INIT */
|
|
|
+
|
|
|
+int __pci_pre_init(struct pci_controller *hose)
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * This board is always configured as the host & requires the
|
|
|
+ * PCI arbiter to be enabled.
|
|
|
+ */
|
|
|
+ if (!pci_arbiter_enabled()) {
|
|
|
+ printf("PCI: PCI Arbiter disabled!\n");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+#endif /* defined(CONFIG_440EP) ... */
|
|
|
+
|
|
|
+#if defined(CONFIG_SYS_PCI_TARGET_INIT)
|
|
|
+void pci_target_init(struct pci_controller * hose)
|
|
|
+ __attribute__((weak, alias("__pci_target_init")));
|
|
|
+#endif /* CONFIG_SYS_PCI_TARGET_INIT */
|
|
|
+
|
|
|
+int pci_pre_init(struct pci_controller *hose)
|
|
|
+ __attribute__((weak, alias("__pci_pre_init")));
|
|
|
+
|
|
|
+#if defined(CONFIG_SYS_PCI_MASTER_INIT)
|
|
|
+void __pci_master_init(struct pci_controller *hose)
|
|
|
+{
|
|
|
+ u16 reg;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Write the PowerPC440 EP PCI Configuration regs.
|
|
|
+ * Enable PowerPC440 EP to be a master on the PCI bus (PMM).
|
|
|
+ * Enable PowerPC440 EP to act as a PCI memory target (PTM).
|
|
|
+ */
|
|
|
+ pci_read_config_word(0, PCI_COMMAND, ®);
|
|
|
+ pci_write_config_word(0, PCI_COMMAND, reg |
|
|
|
+ PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
|
|
|
+}
|
|
|
+void pci_master_init(struct pci_controller *hose)
|
|
|
+ __attribute__((weak, alias("__pci_master_init")));
|
|
|
+#endif /* CONFIG_SYS_PCI_MASTER_INIT */
|
|
|
+
|
|
|
int pci_440_init (struct pci_controller *hose)
|
|
|
{
|
|
|
int reg_num = 0;
|
|
@@ -568,7 +773,7 @@ int pci_440_init (struct pci_controller *hose)
|
|
|
pci_setup_indirect(hose, PCIL0_CFGADR, PCIL0_CFGDATA);
|
|
|
|
|
|
/* Let board change/modify hose & do initial checks */
|
|
|
- if (pci_pre_init (hose) == 0) {
|
|
|
+ if (pci_pre_init(hose) == 0) {
|
|
|
printf("PCI: Board-specific initialization failed.\n");
|
|
|
printf("PCI: Configuration aborted.\n");
|
|
|
return -1;
|