xref: /openbmc/u-boot/arch/powerpc/cpu/mpc83xx/law.c (revision 83d290c56fab2d38cd1ab4c4cc7099559c1d5046)
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