FSL DDR: Provide a generic set_ddr_laws()
authorKumar Gala <galak@kernel.crashing.org>
Tue, 26 Aug 2008 20:01:28 +0000 (15:01 -0500)
committerWolfgang Denk <wd@denx.de>
Wed, 27 Aug 2008 00:05:55 +0000 (02:05 +0200)
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>
drivers/misc/fsl_law.c
include/asm-ppc/fsl_law.h

index 48ece4f090b8c2af5e9705529ad22fafa43f7de1..e4e5c3198aa9fb87a5e8474c5b869de67d2c1374 100644 (file)
@@ -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;
index 227bf8326c0979bd6384d2873463269cd047be71..5bba08d44b419b0fc64b0c413a0c99248a097108 100644 (file)
@@ -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);