1 /* 2 * Copyright 2011 Freescale Semiconductor, Inc. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * Version 2 as published by the Free Software Foundation. 7 */ 8 9 #include <common.h> 10 #include <asm/fsl_law.h> 11 #include <asm/mmu.h> 12 13 int set_ddr_laws(u64 start, u64 sz, enum law_trgt_if id) 14 { 15 immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; 16 law83xx_t *ecm = &immap->sysconf.ddrlaw[0]; 17 u64 start_align, law_sz; 18 int law_sz_enc; 19 20 if (start == 0) 21 start_align = 1ull << (LAW_SIZE_2G + 1); 22 else 23 start_align = 1ull << (ffs64(start) - 1); 24 law_sz = min(start_align, sz); 25 law_sz_enc = __ilog2_u64(law_sz) - 1; 26 27 /* 28 * Set up LAWBAR for all of DDR. 29 */ 30 ecm->bar = start & 0xfffff000; 31 ecm->ar = (LAWAR_EN | (id << 20) | (LAWAR_SIZE & law_sz_enc)); 32 debug("DDR:bar=0x%08x\n", ecm->bar); 33 debug("DDR:ar=0x%08x\n", ecm->ar); 34 35 /* recalculate size based on what was actually covered by the law */ 36 law_sz = 1ull << __ilog2_u64(law_sz); 37 38 /* do we still have anything to map */ 39 sz = sz - law_sz; 40 if (sz) { 41 start += law_sz; 42 43 start_align = 1ull << (ffs64(start) - 1); 44 law_sz = min(start_align, sz); 45 law_sz_enc = __ilog2_u64(law_sz) - 1; 46 ecm = &immap->sysconf.ddrlaw[1]; 47 ecm->bar = start & 0xfffff000; 48 ecm->ar = (LAWAR_EN | (id << 20) | (LAWAR_SIZE & law_sz_enc)); 49 debug("DDR:bar=0x%08x\n", ecm->bar); 50 debug("DDR:ar=0x%08x\n", ecm->ar); 51 } else { 52 return 0; 53 } 54 55 /* do we still have anything to map */ 56 sz = sz - law_sz; 57 if (sz) 58 return 1; 59 60 return 0; 61 } 62