xref: /rk3399_rockchip-uboot/arch/powerpc/cpu/mpc83xx/law.c (revision d82477748d641e60ba3e1a0b55d98362aed70f80)
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