|
@@ -27,8 +27,22 @@
|
|
|
#include <asm/fsl_law.h>
|
|
|
#include <asm/io.h>
|
|
|
|
|
|
+DECLARE_GLOBAL_DATA_PTR;
|
|
|
+
|
|
|
#define LAWAR_EN 0x80000000
|
|
|
-#define FSL_HW_NUM_LAWS 10 /* number of LAWs in the hw implementation */
|
|
|
+/* number of LAWs in the hw implementation */
|
|
|
+#if defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || \
|
|
|
+ defined(CONFIG_MPC8560) || defined(CONFIG_MPC8555)
|
|
|
+#define FSL_HW_NUM_LAWS 8
|
|
|
+#elif defined(CONFIG_MPC8548) || defined(CONFIG_MPC8544) || \
|
|
|
+ defined(CONFIG_MPC8568) || \
|
|
|
+ defined(CONFIG_MPC8641) || defined(CONFIG_MPC8610)
|
|
|
+#define FSL_HW_NUM_LAWS 10
|
|
|
+#elif defined(CONFIG_MPC8572)
|
|
|
+#define FSL_HW_NUM_LAWS 12
|
|
|
+#else
|
|
|
+#error FSL_HW_NUM_LAWS not defined for this platform
|
|
|
+#endif
|
|
|
|
|
|
void set_law(u8 idx, phys_addr_t addr, enum law_size sz, enum law_trgt_if id)
|
|
|
{
|
|
@@ -36,18 +50,34 @@ void set_law(u8 idx, phys_addr_t addr, enum law_size sz, enum law_trgt_if id)
|
|
|
volatile u32 *lawbar = base + 8 * idx;
|
|
|
volatile u32 *lawar = base + 8 * idx + 2;
|
|
|
|
|
|
+ gd->used_laws |= (1 << idx);
|
|
|
+
|
|
|
out_be32(lawbar, addr >> 12);
|
|
|
out_be32(lawar, LAWAR_EN | ((u32)id << 20) | (u32)sz);
|
|
|
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
+int set_next_law(phys_addr_t addr, enum law_size sz, enum law_trgt_if id)
|
|
|
+{
|
|
|
+ u32 idx = ffz(gd->used_laws);
|
|
|
+
|
|
|
+ if (idx >= FSL_HW_NUM_LAWS)
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ set_law(idx, addr, sz, id);
|
|
|
+
|
|
|
+ return idx;
|
|
|
+}
|
|
|
+
|
|
|
void disable_law(u8 idx)
|
|
|
{
|
|
|
volatile u32 *base = (volatile u32 *)(CFG_IMMR + 0xc08);
|
|
|
volatile u32 *lawbar = base + 8 * idx;
|
|
|
volatile u32 *lawar = base + 8 * idx + 2;
|
|
|
|
|
|
+ gd->used_laws &= ~(1 << idx);
|
|
|
+
|
|
|
out_be32(lawar, 0);
|
|
|
out_be32(lawbar, 0);
|
|
|
|
|
@@ -75,14 +105,16 @@ void print_laws(void)
|
|
|
void init_laws(void)
|
|
|
{
|
|
|
int i;
|
|
|
- u8 law_idx = 0;
|
|
|
|
|
|
- for (i = 0; i < num_law_entries; i++) {
|
|
|
- if (law_table[i].index != -1)
|
|
|
- law_idx = law_table[i].index;
|
|
|
+ gd->used_laws = ~((1 << FSL_HW_NUM_LAWS) - 1);
|
|
|
|
|
|
- set_law(law_idx++, law_table[i].addr,
|
|
|
- law_table[i].size, law_table[i].trgt_id);
|
|
|
+ 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,
|
|
|
+ law_table[i].trgt_id);
|
|
|
+ else
|
|
|
+ set_law(law_table[i].index, law_table[i].addr,
|
|
|
+ law_table[i].size, law_table[i].trgt_id);
|
|
|
}
|
|
|
|
|
|
return ;
|