[U-Boot-Users] [PATCH v2] FSL LAW: Keep track of LAW allocations and provide a LAW allocator

Kumar Gala galak at kernel.crashing.org
Tue Jun 10 06:01:17 CEST 2008


Make it so we keep track of which LAWs have allocated and provide
a function (set_next_law) which can allocate a LAW for us if one is
free.

In the future we will move to doing more "dynamic" LAW allocation
since the majority of users dont really care about what LAW number
they are at.

Signed-off-by: Kumar Gala <galak at kernel.crashing.org>
---

Missed 8568 in the list the first time around.  Also removed CLEAR_LAW support
completely.

 cpu/mpc85xx/cpu_init.c        |   23 +++++---------------
 drivers/misc/fsl_law.c        |   46 ++++++++++++++++++++++++++++++++++------
 include/asm-ppc/fsl_law.h     |    4 +++
 include/asm-ppc/global_data.h |    3 ++
 lib_ppc/board.c               |    3 +-
 5 files changed, 54 insertions(+), 25 deletions(-)

diff --git a/cpu/mpc85xx/cpu_init.c b/cpu/mpc85xx/cpu_init.c
index e3240b5..f7a3129 100644
--- a/cpu/mpc85xx/cpu_init.c
+++ b/cpu/mpc85xx/cpu_init.c
@@ -148,6 +148,12 @@ void cpu_init_early_f(void)
 	}
 #endif

+	/* Pointer is writable since we allocated a register for it */
+	gd = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET);
+
+	/* Clear initial global data */
+	memset ((void *) gd, 0, sizeof (gd_t));
+
 	init_laws();
 	invalidate_tlb(0);
 	init_tlbs();
@@ -168,12 +174,6 @@ void cpu_init_f (void)
 	disable_tlb(14);
 	disable_tlb(15);

-	/* Pointer is writable since we allocated a register for it */
-	gd = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET);
-
-	/* Clear initial global data */
-	memset ((void *) gd, 0, sizeof (gd_t));
-
 #ifdef CONFIG_CPM2
 	config_8560_ioports((ccsr_cpm_t *)CFG_MPC85xx_CPM_ADDR);
 #endif
@@ -254,17 +254,6 @@ void cpu_init_f (void)

 int cpu_init_r(void)
 {
-#ifdef CONFIG_CLEAR_LAW0
-#ifdef CONFIG_FSL_LAW
-	disable_law(0);
-#else
-	volatile ccsr_local_ecm_t *ecm = (void *)(CFG_MPC85xx_ECM_ADDR);
-
-	/* clear alternate boot location LAW (used for sdram, or ddr bank) */
-	ecm->lawar0 = 0;
-#endif
-#endif
-
 #if defined(CONFIG_L2_CACHE)
 	volatile ccsr_l2cache_t *l2cache = (void *)CFG_MPC85xx_L2_ADDR;
 	volatile uint cache_ctl;
diff --git a/drivers/misc/fsl_law.c b/drivers/misc/fsl_law.c
index dca6a4d..d7d6c40 100644
--- a/drivers/misc/fsl_law.c
+++ b/drivers/misc/fsl_law.c
@@ -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 ;
diff --git a/include/asm-ppc/fsl_law.h b/include/asm-ppc/fsl_law.h
index e955c75..6c445a4 100644
--- a/include/asm-ppc/fsl_law.h
+++ b/include/asm-ppc/fsl_law.h
@@ -6,6 +6,9 @@
 #define SET_LAW_ENTRY(idx, a, sz, trgt) \
 	{ .index = idx, .addr = a, .size = sz, .trgt_id = trgt }

+#define SET_LAW(a, sz, trgt) \
+	{ .index = -1, .addr = a, .size = sz, .trgt_id = trgt }
+
 enum law_size {
 	LAW_SIZE_4K = 0xb,
 	LAW_SIZE_8K,
@@ -70,6 +73,7 @@ struct law_entry {
 };

 extern void set_law(u8 idx, phys_addr_t addr, enum law_size sz, enum law_trgt_if id);
+extern int set_next_law(phys_addr_t addr, enum law_size sz, enum law_trgt_if id);
 extern void disable_law(u8 idx);
 extern void init_laws(void);
 extern void print_laws(void);
diff --git a/include/asm-ppc/global_data.h b/include/asm-ppc/global_data.h
index ea70266..8cf7b6f 100644
--- a/include/asm-ppc/global_data.h
+++ b/include/asm-ppc/global_data.h
@@ -96,6 +96,9 @@ typedef	struct	global_data {
 	uint mp_alloc_base;
 	uint mp_alloc_top;
 #endif /* CONFIG_QE */
+#if defined(CONFIG_FSL_LAW)
+	u32 used_laws;
+#endif
 #if defined(CONFIG_MPC5xxx)
 	unsigned long	ipb_clk;
 	unsigned long	pci_clk;
diff --git a/lib_ppc/board.c b/lib_ppc/board.c
index a908831..c42e088 100644
--- a/lib_ppc/board.c
+++ b/lib_ppc/board.c
@@ -421,7 +421,8 @@ void board_init_f (ulong bootflag)
 	/* compiler optimization barrier needed for GCC >= 3.4 */
 	__asm__ __volatile__("": : :"memory");

-#if !defined(CONFIG_CPM2) && !defined(CONFIG_MPC83XX)
+#if !defined(CONFIG_CPM2) && !defined(CONFIG_MPC83XX) && \
+    !defined(CONFIG_MPC85xx) && !defined(CONFIG_MPC86xx)
 	/* Clear initial global data */
 	memset ((void *) gd, 0, sizeof (gd_t));
 #endif
-- 
1.5.5.1





More information about the U-Boot mailing list