powerpc/corenet_ds: Master module for boot from PCIE
authorLiu Gang <Gang.Liu@freescale.com>
Thu, 9 Aug 2012 05:10:02 +0000 (05:10 +0000)
committerAndy Fleming <afleming@freescale.com>
Thu, 23 Aug 2012 15:24:15 +0000 (10:24 -0500)
For the powerpc processors with PCIE interface, boot location can be
configured from one PCIE interface by RCW. The processor booting from PCIE
can do without flash for u-boot image. The image can be fetched from another
processor's memory space by PCIE link connected between them.

The processor booting from PCIE is slave, the processor booting from normal
flash memory space is master, and it can help slave to boot from master's
memory space.

When boot from PCIE, slave's core should be in holdoff after powered on for
some specific requirements. Master will release the slave's core at the
right time by PCIE interface.

Environment and requirement:

master:
    1. NOR flash for its own u-boot image, ucode and ENV space.
    2. Slave's u-boot image is in master NOR flash.
    3. Normally boot from local NOR flash.
    4. Configure PCIE system if needed.
slave:
    1. Just has EEPROM for RCW. No flash for u-boot image, ucode and ENV.
    2. Boot location should be set to one PCIE interface by RCW.
    3. RCW should configure the SerDes, PCIE interfaces correctly.
4. Must set all the cores in holdoff by RCW.
5. Must be powered on before master's boot.

For the master module, need to finish these processes:
    1. Initialize the PCIE port and address space.
    2. Set inbound PCIE windows covered slave's u-boot image stored in
       master's NOR flash.
3. Set outbound windows in order to configure slave's registers
   for the core's releasing.
    4. Should set the environment variable "bootmaster" to "PCIE1", "PCIE2"
   or "PCIE3" using the following command:

setenv bootmaster PCIE1
saveenv

Signed-off-by: Liu Gang <Gang.Liu@freescale.com>
Signed-off-by: Andy Fleming <afleming@freescale.com>
arch/powerpc/cpu/mpc8xxx/srio.c
drivers/pci/fsl_pci_init.c
include/configs/P2041RDB.h
include/configs/corenet_ds.h

index ae83d6e1729b696870d1eea7f5df002c603ab5f6..0cb65b32e48919f2a38cebec329389be8db3dcf1 100644 (file)
@@ -108,44 +108,44 @@ void srio_boot_master(int port)
        /* configure inbound window for slave's u-boot image */
        debug("SRIOBOOT - MASTER: Inbound window for slave's image; "
                        "Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n",
-                       (u64)CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_PHYS,
-                       (u64)CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_BUS1,
-                       CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE);
+                       (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS,
+                       (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS1,
+                       CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE);
        out_be32((void *)&srio->atmu.port[port - 1].inbw[0].riwtar,
-                       CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_PHYS >> 12);
+                       CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS >> 12);
        out_be32((void *)&srio->atmu.port[port - 1].inbw[0].riwbar,
-                       CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_BUS1 >> 12);
+                       CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS1 >> 12);
        out_be32((void *)&srio->atmu.port[port - 1].inbw[0].riwar,
                        SRIO_IB_ATMU_AR
-                       | atmu_size_mask(CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE));
+                       | atmu_size_mask(CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE));
 
        /* configure inbound window for slave's u-boot image */
        debug("SRIOBOOT - MASTER: Inbound window for slave's image; "
                        "Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n",
-                       (u64)CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_PHYS,
-                       (u64)CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_BUS2,
-                       CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE);
+                       (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS,
+                       (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS2,
+                       CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE);
        out_be32((void *)&srio->atmu.port[port - 1].inbw[1].riwtar,
-                       CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_PHYS >> 12);
+                       CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS >> 12);
        out_be32((void *)&srio->atmu.port[port - 1].inbw[1].riwbar,
-                       CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_BUS2 >> 12);
+                       CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS2 >> 12);
        out_be32((void *)&srio->atmu.port[port - 1].inbw[1].riwar,
                        SRIO_IB_ATMU_AR
-                       | atmu_size_mask(CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE));
+                       | atmu_size_mask(CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE));
 
        /* configure inbound window for slave's ucode and ENV */
        debug("SRIOBOOT - MASTER: Inbound window for slave's ucode and ENV; "
                        "Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n",
-                       (u64)CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_MEM_PHYS,
-                       (u64)CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_MEM_BUS,
-                       CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_SIZE);
+                       (u64)CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_PHYS,
+                       (u64)CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_BUS,
+                       CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE);
        out_be32((void *)&srio->atmu.port[port - 1].inbw[2].riwtar,
-                       CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_MEM_PHYS >> 12);
+                       CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_PHYS >> 12);
        out_be32((void *)&srio->atmu.port[port - 1].inbw[2].riwbar,
-                       CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_MEM_BUS >> 12);
+                       CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_BUS >> 12);
        out_be32((void *)&srio->atmu.port[port - 1].inbw[2].riwar,
                        SRIO_IB_ATMU_AR
-                       | atmu_size_mask(CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_SIZE));
+                       | atmu_size_mask(CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE));
 }
 
 void srio_boot_master_release_slave(int port)
@@ -227,8 +227,8 @@ void srio_boot_master_release_slave(int port)
                                 */
                                out_be32((void *)CONFIG_SYS_SRIO2_MEM_VIRT
                                        + SRIO_MAINT_WIN_SIZE
-                                       + CONFIG_SRIOBOOT_SLAVE_BRR_OFFSET,
-                                       CONFIG_SRIOBOOT_SLAVE_RELEASE_MASK);
+                                       + CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET,
+                                       CONFIG_SRIO_PCIE_BOOT_RELEASE_MASK);
                        } else {
                                out_be32((void *)CONFIG_SYS_SRIO1_MEM_VIRT
                                        + SRIO_LCSBA1CSR_OFFSET,
@@ -243,8 +243,8 @@ void srio_boot_master_release_slave(int port)
                                 */
                                out_be32((void *)CONFIG_SYS_SRIO1_MEM_VIRT
                                        + SRIO_MAINT_WIN_SIZE
-                                       + CONFIG_SRIOBOOT_SLAVE_BRR_OFFSET,
-                                       CONFIG_SRIOBOOT_SLAVE_RELEASE_MASK);
+                                       + CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET,
+                                       CONFIG_SRIO_PCIE_BOOT_RELEASE_MASK);
                        }
                        debug("SRIOBOOT - MASTER: "
                                        "Release slave successfully! Now the slave should start up!\n");
index 1d75a82bc3d4dc1213926b9c41ae3632e42b419e..0d46c963128736f6a70a8b97d9253a50bbe4d09c 100644 (file)
@@ -211,6 +211,95 @@ static int fsl_pci_setup_inbound_windows(struct pci_controller *hose,
        return 1;
 }
 
+#ifdef CONFIG_FSL_CORENET
+static void fsl_pcie_boot_master(pit_t *pi)
+{
+       /* configure inbound window for slave's u-boot image */
+       debug("PCIEBOOT - MASTER: Inbound window for slave's image; "
+                       "Local = 0x%llx, Bus = 0x%llx, Size = 0x%x\n",
+                       (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS,
+                       (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS1,
+                       CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE);
+       struct pci_region r_inbound;
+       u32 sz_inbound = __ilog2_u64(CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE)
+                                       - 1;
+       pci_set_region(&r_inbound,
+               CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS1,
+               CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS,
+               sz_inbound,
+               PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
+
+       set_inbound_window(pi--, &r_inbound,
+               CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE);
+
+       /* configure inbound window for slave's u-boot image */
+       debug("PCIEBOOT - MASTER: Inbound window for slave's image; "
+                       "Local = 0x%llx, Bus = 0x%llx, Size = 0x%x\n",
+                       (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS,
+                       (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS2,
+                       CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE);
+       pci_set_region(&r_inbound,
+               CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS2,
+               CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS,
+               sz_inbound,
+               PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
+
+       set_inbound_window(pi--, &r_inbound,
+               CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE);
+
+       /* configure inbound window for slave's ucode and ENV */
+       debug("PCIEBOOT - MASTER: Inbound window for slave's "
+                       "ucode and ENV; "
+                       "Local = 0x%llx, Bus = 0x%llx, Size = 0x%x\n",
+                       (u64)CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_PHYS,
+                       (u64)CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_BUS,
+                       CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE);
+       sz_inbound = __ilog2_u64(CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE)
+                               - 1;
+       pci_set_region(&r_inbound,
+               CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_BUS,
+               CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_PHYS,
+               sz_inbound,
+               PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
+
+       set_inbound_window(pi--, &r_inbound,
+               CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE);
+}
+
+static void fsl_pcie_boot_master_release_slave(int port)
+{
+       unsigned long release_addr;
+
+       /* now release slave's core 0 */
+       switch (port) {
+       case 1:
+               release_addr = CONFIG_SYS_PCIE1_MEM_VIRT
+                       + CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET;
+               break;
+       case 2:
+               release_addr = CONFIG_SYS_PCIE2_MEM_VIRT
+                       + CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET;
+               break;
+       case 3:
+               release_addr = CONFIG_SYS_PCIE3_MEM_VIRT
+                       + CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET;
+               break;
+       default:
+               release_addr = 0;
+               break;
+       }
+       if (release_addr != 0) {
+               out_be32((void *)release_addr,
+                       CONFIG_SRIO_PCIE_BOOT_RELEASE_MASK);
+               debug("PCIEBOOT - MASTER: "
+                       "Release slave successfully! Now the slave should start up!\n");
+       } else {
+               debug("PCIEBOOT - MASTER: "
+                       "Release slave failed!\n");
+       }
+}
+#endif
+
 void fsl_pci_init(struct pci_controller *hose, struct fsl_pci_info *pci_info)
 {
        u32 cfg_addr = (u32)&((ccsr_fsl_pci_t *)pci_info->regs)->cfg_addr;
@@ -295,8 +384,25 @@ void fsl_pci_init(struct pci_controller *hose, struct fsl_pci_info *pci_info)
        /* see if we are a PCIe or PCI controller */
        pci_hose_read_config_byte(hose, dev, FSL_PCIE_CAP_ID, &pcie_cap);
 
+#ifdef CONFIG_FSL_CORENET
+       /* boot from PCIE --master */
+       char *s = getenv("bootmaster");
+       char pcie[6];
+       sprintf(pcie, "PCIE%d", pci_info->pci_num);
+
+       if (s && (strcmp(s, pcie) == 0)) {
+               debug("PCIEBOOT - MASTER: Master port [ %d ] for pcie boot.\n",
+                               pci_info->pci_num);
+               fsl_pcie_boot_master((pit_t *)pi);
+       } else {
+               /* inbound */
+               inbound = fsl_pci_setup_inbound_windows(hose,
+                                       out_lo, pcie_cap, pi);
+       }
+#else
        /* inbound */
        inbound = fsl_pci_setup_inbound_windows(hose, out_lo, pcie_cap, pi);
+#endif
 
        for (r = 0; r < hose->region_count; r++)
                debug("PCI reg:%d %016llx:%016llx %016llx %08lx\n", r,
@@ -488,6 +594,16 @@ int fsl_pci_init_port(struct fsl_pci_info *pci_info,
        if (fsl_is_pci_agent(hose)) {
                fsl_pci_config_unlock(hose);
                hose->last_busno = hose->first_busno;
+#ifdef CONFIG_FSL_CORENET
+       } else {
+               /* boot from PCIE --master releases slave's core 0 */
+               char *s = getenv("bootmaster");
+               char pcie[6];
+               sprintf(pcie, "PCIE%d", pci_info->pci_num);
+
+               if (s && (strcmp(s, pcie) == 0))
+                       fsl_pcie_boot_master_release_slave(pci_info->pci_num);
+#endif
        }
 
        pci_hose_read_config_byte(hose, dev, FSL_PCIE_CAP_ID, &pcie_cap);
index 9d884a3d27773ea48f1c3cca21af75fddc4277d6..18e4bce083fd51bbe12360dd57c6ce88585e4e32 100644 (file)
@@ -390,21 +390,21 @@ unsigned long get_board_sys_clk(unsigned long dummy);
  * for slave u-boot IMAGE instored in master memory space,
  * PHYS must be aligned based on the SIZE
  */
-#define CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_PHYS 0xfef080000ull
-#define CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_BUS1 0xfff80000ull
-#define CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE 0x80000       /* 512K */
-#define CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_BUS2 0x3fff80000ull
+#define CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS 0xfef080000ull
+#define CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS1 0xfff80000ull
+#define CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE 0x80000       /* 512K */
+#define CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS2 0x3fff80000ull
 /*
  * for slave UCODE and ENV instored in master memory space,
  * PHYS must be aligned based on the SIZE
  */
-#define CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_MEM_PHYS 0xfef040000ull
-#define CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_MEM_BUS 0x3ffe00000ull
-#define CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_SIZE 0x40000   /* 256K */
+#define CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_PHYS 0xfef040000ull
+#define CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_BUS 0x3ffe00000ull
+#define CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE 0x40000   /* 256K */
 
 /* slave core release by master*/
-#define CONFIG_SRIOBOOT_SLAVE_BRR_OFFSET 0xe00e4
-#define CONFIG_SRIOBOOT_SLAVE_RELEASE_MASK 0x00000001 /* release core 0 */
+#define CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET 0xe00e4
+#define CONFIG_SRIO_PCIE_BOOT_RELEASE_MASK 0x00000001 /* release core 0 */
 
 /*
  * SRIOBOOT - SLAVE
index 847e607577301ca67315af8185d6f16b8e62ed30..1d25fc1909b2037a809ca82d163fd6c7f1492900 100644 (file)
  * for slave u-boot IMAGE instored in master memory space,
  * PHYS must be aligned based on the SIZE
  */
-#define CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_PHYS 0xfef080000ull
-#define CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_BUS1 0xfff80000ull
-#define CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE 0x80000       /* 512K */
-#define CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_BUS2 0x3fff80000ull
+#define CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS 0xfef080000ull
+#define CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS1 0xfff80000ull
+#define CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE 0x80000       /* 512K */
+#define CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS2 0x3fff80000ull
 /*
  * for slave UCODE and ENV instored in master memory space,
  * PHYS must be aligned based on the SIZE
  */
-#define CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_MEM_PHYS 0xfef040000ull
-#define CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_MEM_BUS 0x3ffe00000ull
-#define CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_SIZE 0x40000   /* 256K */
+#define CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_PHYS 0xfef040000ull
+#define CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_BUS 0x3ffe00000ull
+#define CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE 0x40000   /* 256K */
 
 /* slave core release by master*/
-#define CONFIG_SRIOBOOT_SLAVE_BRR_OFFSET 0xe00e4
-#define CONFIG_SRIOBOOT_SLAVE_RELEASE_MASK 0x00000001 /* release core 0 */
+#define CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET 0xe00e4
+#define CONFIG_SRIO_PCIE_BOOT_RELEASE_MASK 0x00000001 /* release core 0 */
 
 /*
  * SRIOBOOT - SLAVE