blob: 262ae7f711aad31881095c7c59bd61dd7bb0ab5b [file] [log] [blame]
York Sund29d17d2011-08-26 11:32:44 -07001/*
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>
Fabio Estevam2d2f4902015-11-05 12:43:40 -020012#include <linux/log2.h>
York Sund29d17d2011-08-26 11:32:44 -070013
14int set_ddr_laws(u64 start, u64 sz, enum law_trgt_if id)
15{
16 immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
17 law83xx_t *ecm = &immap->sysconf.ddrlaw[0];
18 u64 start_align, law_sz;
19 int law_sz_enc;
20
21 if (start == 0)
22 start_align = 1ull << (LAW_SIZE_2G + 1);
23 else
Fabio Estevam2d2f4902015-11-05 12:43:40 -020024 start_align = 1ull << (__ffs64(start) - 1);
York Sund29d17d2011-08-26 11:32:44 -070025 law_sz = min(start_align, sz);
26 law_sz_enc = __ilog2_u64(law_sz) - 1;
27
28 /*
29 * Set up LAWBAR for all of DDR.
30 */
31 ecm->bar = start & 0xfffff000;
32 ecm->ar = (LAWAR_EN | (id << 20) | (LAWAR_SIZE & law_sz_enc));
33 debug("DDR:bar=0x%08x\n", ecm->bar);
34 debug("DDR:ar=0x%08x\n", ecm->ar);
35
36 /* recalculate size based on what was actually covered by the law */
37 law_sz = 1ull << __ilog2_u64(law_sz);
38
39 /* do we still have anything to map */
40 sz = sz - law_sz;
41 if (sz) {
42 start += law_sz;
43
Fabio Estevam2d2f4902015-11-05 12:43:40 -020044 start_align = 1ull << (__ffs64(start) - 1);
York Sund29d17d2011-08-26 11:32:44 -070045 law_sz = min(start_align, sz);
46 law_sz_enc = __ilog2_u64(law_sz) - 1;
47 ecm = &immap->sysconf.ddrlaw[1];
48 ecm->bar = start & 0xfffff000;
49 ecm->ar = (LAWAR_EN | (id << 20) | (LAWAR_SIZE & law_sz_enc));
50 debug("DDR:bar=0x%08x\n", ecm->bar);
51 debug("DDR:ar=0x%08x\n", ecm->ar);
52 } else {
53 return 0;
54 }
55
56 /* do we still have anything to map */
57 sz = sz - law_sz;
58 if (sz)
59 return 1;
60
61 return 0;
62}