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