]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - arch/powerpc/cpu/mpc8xxx/srio.c
powerpc/corenet_ds: Slave core in holdoff when boot from SRIO
[karo-tx-uboot.git] / arch / powerpc / cpu / mpc8xxx / srio.c
index 5694561eba54615d3454a0a800b667d15b484a5b..c7f394972bf0d334b29ec3af94777f1fbfddd1f4 100644 (file)
 
 #define SRIO_PORT_ACCEPT_ALL 0x10000001
 #define SRIO_IB_ATMU_AR 0x80f55000
+#define SRIO_OB_ATMU_AR_MAINT 0x80077000
+#define SRIO_OB_ATMU_AR_RW 0x80045000
+#define SRIO_LCSBA1CSR_OFFSET 0x5c
+#define SRIO_MAINT_WIN_SIZE 0x1000000 /* 16M */
+#define SRIO_RW_WIN_SIZE 0x100000 /* 1M */
+#define SRIO_LCSBA1CSR 0x60000000
 
 #if defined(CONFIG_FSL_CORENET)
        #define _DEVDISR_SRIO1 FSL_CORENET_DEVDISR_SRIO1
@@ -168,4 +174,123 @@ void srio_boot_master(void)
                        SRIO_IB_ATMU_AR
                        | atmu_size_mask(CONFIG_SRIOBOOT_SLAVE_ENV_SIZE));
 }
+
+#ifdef CONFIG_SRIOBOOT_SLAVE_HOLDOFF
+void srio_boot_master_release_slave(void)
+{
+       struct ccsr_rio *srio = (void *)CONFIG_SYS_FSL_SRIO_ADDR;
+       u32 escsr;
+       debug("SRIOBOOT - MASTER: "
+                       "Check the port status and release slave core ...\n");
+
+       escsr = in_be32((void *)&srio->lp_serial
+                       .port[CONFIG_SRIOBOOT_MASTER_PORT].pescsr);
+       if (escsr & 0x2) {
+               if (escsr & 0x10100) {
+                       debug("SRIOBOOT - MASTER: Port [ %d ] is error.\n",
+                                       CONFIG_SRIOBOOT_MASTER_PORT);
+               } else {
+                       debug("SRIOBOOT - MASTER: "
+                                       "Port [ %d ] is ready, now release slave's core ...\n",
+                                       CONFIG_SRIOBOOT_MASTER_PORT);
+                       /*
+                        * configure outbound window
+                        * with maintenance attribute to set slave's LCSBA1CSR
+                        */
+                       out_be32((void *)&srio->atmu
+                               .port[CONFIG_SRIOBOOT_MASTER_PORT]
+                               .outbw[1].rowtar, 0);
+                       out_be32((void *)&srio->atmu
+                               .port[CONFIG_SRIOBOOT_MASTER_PORT]
+                               .outbw[1].rowtear, 0);
+                       if (CONFIG_SRIOBOOT_MASTER_PORT)
+                               out_be32((void *)&srio->atmu
+                                       .port[CONFIG_SRIOBOOT_MASTER_PORT]
+                                       .outbw[1].rowbar,
+                                       CONFIG_SYS_SRIO2_MEM_PHYS >> 12);
+                       else
+                               out_be32((void *)&srio->atmu
+                                       .port[CONFIG_SRIOBOOT_MASTER_PORT]
+                                       .outbw[1].rowbar,
+                                       CONFIG_SYS_SRIO1_MEM_PHYS >> 12);
+                       out_be32((void *)&srio->atmu
+                                       .port[CONFIG_SRIOBOOT_MASTER_PORT]
+                                       .outbw[1].rowar,
+                                       SRIO_OB_ATMU_AR_MAINT
+                                       | atmu_size_mask(SRIO_MAINT_WIN_SIZE));
+
+                       /*
+                        * configure outbound window
+                        * with R/W attribute to set slave's BRR
+                        */
+                       out_be32((void *)&srio->atmu
+                               .port[CONFIG_SRIOBOOT_MASTER_PORT]
+                               .outbw[2].rowtar,
+                               SRIO_LCSBA1CSR >> 9);
+                       out_be32((void *)&srio->atmu
+                               .port[CONFIG_SRIOBOOT_MASTER_PORT]
+                               .outbw[2].rowtear, 0);
+                       if (CONFIG_SRIOBOOT_MASTER_PORT)
+                               out_be32((void *)&srio->atmu
+                                       .port[CONFIG_SRIOBOOT_MASTER_PORT]
+                                       .outbw[2].rowbar,
+                                       (CONFIG_SYS_SRIO2_MEM_PHYS
+                                       + SRIO_MAINT_WIN_SIZE) >> 12);
+                       else
+                               out_be32((void *)&srio->atmu
+                                       .port[CONFIG_SRIOBOOT_MASTER_PORT]
+                                       .outbw[2].rowbar,
+                                       (CONFIG_SYS_SRIO1_MEM_PHYS
+                                       + SRIO_MAINT_WIN_SIZE) >> 12);
+                       out_be32((void *)&srio->atmu
+                               .port[CONFIG_SRIOBOOT_MASTER_PORT]
+                               .outbw[2].rowar,
+                               SRIO_OB_ATMU_AR_RW
+                               | atmu_size_mask(SRIO_RW_WIN_SIZE));
+
+                       /*
+                        * Set the LCSBA1CSR register in slave
+                        * by the maint-outbound window
+                        */
+                       if (CONFIG_SRIOBOOT_MASTER_PORT) {
+                               out_be32((void *)CONFIG_SYS_SRIO2_MEM_VIRT
+                                       + SRIO_LCSBA1CSR_OFFSET,
+                                       SRIO_LCSBA1CSR);
+                               while (in_be32((void *)CONFIG_SYS_SRIO2_MEM_VIRT
+                                       + SRIO_LCSBA1CSR_OFFSET)
+                                       != SRIO_LCSBA1CSR)
+                                       ;
+                               /*
+                                * And then set the BRR register
+                                * to release slave core
+                                */
+                               out_be32((void *)CONFIG_SYS_SRIO2_MEM_VIRT
+                                       + SRIO_MAINT_WIN_SIZE
+                                       + CONFIG_SRIOBOOT_SLAVE_BRR_OFFSET,
+                                       CONFIG_SRIOBOOT_SLAVE_RELEASE_MASK);
+                       } else {
+                               out_be32((void *)CONFIG_SYS_SRIO1_MEM_VIRT
+                                       + SRIO_LCSBA1CSR_OFFSET,
+                                       SRIO_LCSBA1CSR);
+                               while (in_be32((void *)CONFIG_SYS_SRIO1_MEM_VIRT
+                                       + SRIO_LCSBA1CSR_OFFSET)
+                                       != SRIO_LCSBA1CSR)
+                                       ;
+                               /*
+                                * And then set the BRR register
+                                * to release slave core
+                                */
+                               out_be32((void *)CONFIG_SYS_SRIO1_MEM_VIRT
+                                       + SRIO_MAINT_WIN_SIZE
+                                       + CONFIG_SRIOBOOT_SLAVE_BRR_OFFSET,
+                                       CONFIG_SRIOBOOT_SLAVE_RELEASE_MASK);
+                       }
+                       debug("SRIOBOOT - MASTER: "
+                                       "Release slave successfully! Now the slave should start up!\n");
+               }
+       } else
+               debug("SRIOBOOT - MASTER: Port [ %d ] is not ready.\n",
+                               CONFIG_SRIOBOOT_MASTER_PORT);
+}
+#endif
 #endif