summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKumar Gala <galak@kernel.crashing.org>2008-08-26 15:01:28 -0500
committerWolfgang Denk <wd@denx.de>2008-08-27 02:05:55 +0200
commitf784e32b4bce0013983506b11af4b85b8ca3d36e (patch)
treecbf7641b5d6cfe1e2dfd88e38298b17667d4ad67
parent0f2cbe3f5eddbdf3848265f35e4f714434929cff (diff)
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>
-rw-r--r--drivers/misc/fsl_law.c39
-rw-r--r--include/asm-ppc/fsl_law.h1
2 files changed, 40 insertions, 0 deletions
diff --git a/drivers/misc/fsl_law.c b/drivers/misc/fsl_law.c
index 48ece4f090b..e4e5c3198aa 100644
--- a/drivers/misc/fsl_law.c
+++ b/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;
diff --git a/include/asm-ppc/fsl_law.h b/include/asm-ppc/fsl_law.h
index 227bf8326c0..5bba08d44b4 100644
--- a/include/asm-ppc/fsl_law.h
+++ b/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);