]> git.sur5r.net Git - u-boot/blobdiff - drivers/misc/fsl_law.c
powerpc/usb: fix bug of CPU hang when missing USB PHY clock
[u-boot] / drivers / misc / fsl_law.c
index 031c9748f4d0692a2707ea7689c0b778a5055714..223cd5d65c816aac52f969e05332a970b73e7e51 100644 (file)
@@ -24,6 +24,7 @@
  */
 
 #include <common.h>
+#include <linux/compiler.h>
 #include <asm/fsl_law.h>
 #include <asm/io.h>
 
@@ -246,6 +247,25 @@ void init_laws(void)
 #error FSL_HW_NUM_LAWS can not be greater than 32 w/o code changes
 #endif
 
+       /*
+        * Any LAWs that were set up before we booted assume they are meant to
+        * be around and mark them used.
+        */
+       for (i = 0; i < FSL_HW_NUM_LAWS; i++) {
+               u32 lawar = in_be32(LAWAR_ADDR(i));
+
+               if (lawar & LAW_EN)
+                       gd->used_laws |= (1 << i);
+       }
+
+#if defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)
+       /*
+        * in NAND boot we've already parsed the law_table and setup those LAWs
+        * so don't do it again.
+        */
+       return;
+#endif
+
        for (i = 0; i < num_law_entries; i++) {
                if (law_table[i].index == -1)
                        set_next_law(law_table[i].addr, law_table[i].size,
@@ -255,5 +275,59 @@ void init_laws(void)
                                law_table[i].size, law_table[i].trgt_id);
        }
 
+#ifdef CONFIG_SRIO_PCIE_BOOT_SLAVE
+       /* check RCW to get which port is used for boot */
+       ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
+       u32 bootloc = in_be32(&gur->rcwsr[6]);
+       /*
+        * in SRIO or PCIE boot we need to set specail LAWs for
+        * SRIO or PCIE interfaces.
+        */
+       switch ((bootloc & FSL_CORENET_RCWSR6_BOOT_LOC) >> 23) {
+       case 0x0: /* boot from PCIE1 */
+               set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS,
+                               LAW_SIZE_1M,
+                               LAW_TRGT_IF_PCIE_1);
+               set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS,
+                               LAW_SIZE_1M,
+                               LAW_TRGT_IF_PCIE_1);
+               break;
+       case 0x1: /* boot from PCIE2 */
+               set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS,
+                               LAW_SIZE_1M,
+                               LAW_TRGT_IF_PCIE_2);
+               set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS,
+                               LAW_SIZE_1M,
+                               LAW_TRGT_IF_PCIE_2);
+               break;
+       case 0x2: /* boot from PCIE3 */
+               set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS,
+                               LAW_SIZE_1M,
+                               LAW_TRGT_IF_PCIE_3);
+               set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS,
+                               LAW_SIZE_1M,
+                               LAW_TRGT_IF_PCIE_3);
+               break;
+       case 0x8: /* boot from SRIO1 */
+               set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS,
+                               LAW_SIZE_1M,
+                               LAW_TRGT_IF_RIO_1);
+               set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS,
+                               LAW_SIZE_1M,
+                               LAW_TRGT_IF_RIO_1);
+               break;
+       case 0x9: /* boot from SRIO2 */
+               set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS,
+                               LAW_SIZE_1M,
+                               LAW_TRGT_IF_RIO_2);
+               set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS,
+                               LAW_SIZE_1M,
+                               LAW_TRGT_IF_RIO_2);
+               break;
+       default:
+               break;
+       }
+#endif
+
        return ;
 }