Browse Source

FSL DDR: Provide a generic set_ddr_laws()

Provide a helper function that will setup the last available
LAWs (upto 2) for DDR.  Useful for SPD/dyanmic DDR setting code.

Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Kumar Gala 16 years ago
parent
commit
f784e32b4b
2 changed files with 40 additions and 0 deletions
  1. 39 0
      drivers/misc/fsl_law.c
  2. 1 0
      include/asm-ppc/fsl_law.h

+ 39 - 0
drivers/misc/fsl_law.c

@@ -121,6 +121,45 @@ void print_laws(void)
 	return;
 }
 
+/* use up to 2 LAWs for DDR, used the last available LAWs */
+int set_ddr_laws(u64 start, u64 sz, enum law_trgt_if id)
+{
+	u64 start_align, law_sz;
+	int law_sz_enc;
+
+	if (start == 0)
+		start_align = 1ull << (LAW_SIZE_32G + 1);
+	else
+		start_align = 1ull << (ffs64(start) - 1);
+	law_sz = min(start_align, sz);
+	law_sz_enc = __ilog2_u64(law_sz) - 1;
+
+	if (set_last_law(start, law_sz_enc, id) < 0)
+		return -1;
+
+	/* do we still have anything to map */
+	sz = sz - law_sz;
+	if (sz) {
+		start += law_sz;
+
+		start_align = 1ull << (ffs64(start) - 1);
+		law_sz = min(start_align, sz);
+		law_sz_enc = __ilog2_u64(law_sz) - 1;
+
+		if (set_last_law(start, law_sz_enc, id) < 0)
+			return -1;
+	} else {
+		return 0;
+	}
+
+	/* do we still have anything to map */
+	sz = sz - law_sz;
+	if (sz)
+		return 1;
+
+	return 0;
+}
+
 void init_laws(void)
 {
 	int i;

+ 1 - 0
include/asm-ppc/fsl_law.h

@@ -75,6 +75,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 int set_last_law(phys_addr_t addr, enum law_size sz, enum law_trgt_if id);
+extern int set_ddr_laws(u64 start, u64 sz, enum law_trgt_if id);
 extern void disable_law(u8 idx);
 extern void init_laws(void);
 extern void print_laws(void);