1d29d17d7SYork Sun /*
2d29d17d7SYork Sun * Copyright 2011 Freescale Semiconductor, Inc.
3d29d17d7SYork Sun *
45b8031ccSTom Rini * SPDX-License-Identifier: GPL-2.0
5d29d17d7SYork Sun */
6d29d17d7SYork Sun
7d29d17d7SYork Sun #include <common.h>
8d29d17d7SYork Sun #include <asm/fsl_law.h>
9d29d17d7SYork Sun #include <asm/mmu.h>
102d2f490dSFabio Estevam #include <linux/log2.h>
11d29d17d7SYork Sun
set_ddr_laws(u64 start,u64 sz,enum law_trgt_if id)12d29d17d7SYork Sun int set_ddr_laws(u64 start, u64 sz, enum law_trgt_if id)
13d29d17d7SYork Sun {
14d29d17d7SYork Sun immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
15d29d17d7SYork Sun law83xx_t *ecm = &immap->sysconf.ddrlaw[0];
16d29d17d7SYork Sun u64 start_align, law_sz;
17d29d17d7SYork Sun int law_sz_enc;
18d29d17d7SYork Sun
19d29d17d7SYork Sun if (start == 0)
20d29d17d7SYork Sun start_align = 1ull << (LAW_SIZE_2G + 1);
21d29d17d7SYork Sun else
22*43381474SAshish kumar start_align = 1ull << (__ffs64(start));
23d29d17d7SYork Sun law_sz = min(start_align, sz);
24d29d17d7SYork Sun law_sz_enc = __ilog2_u64(law_sz) - 1;
25d29d17d7SYork Sun
26d29d17d7SYork Sun /*
27d29d17d7SYork Sun * Set up LAWBAR for all of DDR.
28d29d17d7SYork Sun */
29d29d17d7SYork Sun ecm->bar = start & 0xfffff000;
30d29d17d7SYork Sun ecm->ar = (LAWAR_EN | (id << 20) | (LAWAR_SIZE & law_sz_enc));
31d29d17d7SYork Sun debug("DDR:bar=0x%08x\n", ecm->bar);
32d29d17d7SYork Sun debug("DDR:ar=0x%08x\n", ecm->ar);
33d29d17d7SYork Sun
34d29d17d7SYork Sun /* recalculate size based on what was actually covered by the law */
35d29d17d7SYork Sun law_sz = 1ull << __ilog2_u64(law_sz);
36d29d17d7SYork Sun
37d29d17d7SYork Sun /* do we still have anything to map */
38d29d17d7SYork Sun sz = sz - law_sz;
39d29d17d7SYork Sun if (sz) {
40d29d17d7SYork Sun start += law_sz;
41d29d17d7SYork Sun
42*43381474SAshish kumar start_align = 1ull << (__ffs64(start));
43d29d17d7SYork Sun law_sz = min(start_align, sz);
44d29d17d7SYork Sun law_sz_enc = __ilog2_u64(law_sz) - 1;
45d29d17d7SYork Sun ecm = &immap->sysconf.ddrlaw[1];
46d29d17d7SYork Sun ecm->bar = start & 0xfffff000;
47d29d17d7SYork Sun ecm->ar = (LAWAR_EN | (id << 20) | (LAWAR_SIZE & law_sz_enc));
48d29d17d7SYork Sun debug("DDR:bar=0x%08x\n", ecm->bar);
49d29d17d7SYork Sun debug("DDR:ar=0x%08x\n", ecm->ar);
50d29d17d7SYork Sun } else {
51d29d17d7SYork Sun return 0;
52d29d17d7SYork Sun }
53d29d17d7SYork Sun
54d29d17d7SYork Sun /* do we still have anything to map */
55d29d17d7SYork Sun sz = sz - law_sz;
56d29d17d7SYork Sun if (sz)
57d29d17d7SYork Sun return 1;
58d29d17d7SYork Sun
59d29d17d7SYork Sun return 0;
60d29d17d7SYork Sun }
61