lib: bidram: add 4GB+ memory size support
- On ARMv7: LPAE seems to be not friendly that brings a lot of compile errors. - On ARMv8: MMU translate table is static defined by mem_map[] and max 4GB as usual. It is not created dynamically according to real memory size, that is different from ARMv7. - 4GB memory is enough for U-Boot on both ARMv7 an ARMv8. Considering all that, we decide to make max 4GB size to be visiable for U-Boot, but still pass the real available memory size to kernel by bidram_fixup() called at late before fixup "/memory" node. Signed-off-by: Joseph Chen <chenjh@rock-chips.com> Change-Id: Idd5fa769e940b0618446909f8f9edc39f596f072
This commit is contained in:
parent
36d452911c
commit
1d09cf29cd
|
|
@ -14,6 +14,9 @@ struct bidram {
|
||||||
struct lmb lmb;
|
struct lmb lmb;
|
||||||
struct list_head reserved_head;
|
struct list_head reserved_head;
|
||||||
bool has_init;
|
bool has_init;
|
||||||
|
bool fixup;
|
||||||
|
u64 base_u64[MEM_RESV_COUNT]; /* 4GB+ */
|
||||||
|
u64 size_u64[MEM_RESV_COUNT];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -64,6 +67,20 @@ int bidram_reserve_by_name(const char *name, phys_addr_t base, phys_size_t size)
|
||||||
*/
|
*/
|
||||||
void bidram_dump(void);
|
void bidram_dump(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bidram_fixup() - Fixup bi_dram[] for 4GB+ memory
|
||||||
|
*
|
||||||
|
* @return 0 on success, otherwise error
|
||||||
|
*/
|
||||||
|
int bidram_fixup(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bidram_append_size() - Append 4GB+ memory
|
||||||
|
*
|
||||||
|
* @return 4GB+ size
|
||||||
|
*/
|
||||||
|
u64 bidram_append_size(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bidram_reserved_is_overlap() - Check outside memory is overlap with reserved
|
* bidram_reserved_is_overlap() - Check outside memory is overlap with reserved
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#define _MEMBLK_H
|
#define _MEMBLK_H
|
||||||
|
|
||||||
#define ALIAS_COUNT_MAX 2
|
#define ALIAS_COUNT_MAX 2
|
||||||
|
#define MEM_RESV_COUNT 3
|
||||||
|
|
||||||
enum memblk_id {
|
enum memblk_id {
|
||||||
MEMBLK_ID_UNK,
|
MEMBLK_ID_UNK,
|
||||||
|
|
@ -47,6 +48,8 @@ struct memblk_attr {
|
||||||
struct memblock {
|
struct memblock {
|
||||||
phys_addr_t base;
|
phys_addr_t base;
|
||||||
phys_size_t size;
|
phys_size_t size;
|
||||||
|
u64 base_u64; /* 4GB+ */
|
||||||
|
u64 size_u64;
|
||||||
phys_addr_t orig_base;
|
phys_addr_t orig_base;
|
||||||
struct memblk_attr attr;
|
struct memblk_attr attr;
|
||||||
struct list_head node;
|
struct list_head node;
|
||||||
|
|
|
||||||
73
lib/bidram.c
73
lib/bidram.c
|
|
@ -119,6 +119,7 @@ static int bidram_add(phys_addr_t base, phys_size_t size)
|
||||||
|
|
||||||
void bidram_gen_gd_bi_dram(void)
|
void bidram_gen_gd_bi_dram(void)
|
||||||
{
|
{
|
||||||
|
struct bidram *bidram = &plat_bidram;
|
||||||
struct lmb *lmb = &plat_bidram.lmb;
|
struct lmb *lmb = &plat_bidram.lmb;
|
||||||
struct lmb_property *mem_rgn = lmb->memory.region;
|
struct lmb_property *mem_rgn = lmb->memory.region;
|
||||||
struct lmb_property *res_rgn = lmb->reserved.region;
|
struct lmb_property *res_rgn = lmb->reserved.region;
|
||||||
|
|
@ -168,14 +169,50 @@ void bidram_gen_gd_bi_dram(void)
|
||||||
gd->bd->bi_dram[idx].start;
|
gd->bd->bi_dram[idx].start;
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
for (i = 0; i < idx; i++) {
|
/* Append 4GB+ memory blocks */
|
||||||
BIDRAM_D("gd bi_dram[%d]: start=0x%08lx, end=0x%08lx\n",
|
if (bidram->fixup) {
|
||||||
i, (ulong)gd->bd->bi_dram[i].start,
|
for (i = 0; i < MEM_RESV_COUNT; i++) {
|
||||||
(ulong)gd->bd->bi_dram[i].start +
|
if (!bidram->size_u64[i])
|
||||||
(ulong)gd->bd->bi_dram[i].size);
|
continue;
|
||||||
|
gd->bd->bi_dram[idx].start = bidram->base_u64[i];
|
||||||
|
gd->bd->bi_dram[idx].size = bidram->size_u64[i];
|
||||||
|
BIDRAM_D("FIXUP: gd->bi_dram[%d]: start=0x%llx, size=0x%llx\n",
|
||||||
|
idx, bidram->base_u64[i], bidram->size_u64[i]);
|
||||||
|
idx++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < idx; i++) {
|
||||||
|
BIDRAM_D("GEN: gd->bi_dram[%d]: start=0x%llx, end=0x%llx\n",
|
||||||
|
i, (u64)gd->bd->bi_dram[i].start,
|
||||||
|
(u64)gd->bd->bi_dram[i].start +
|
||||||
|
(u64)gd->bd->bi_dram[i].size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int bidram_fixup(void)
|
||||||
|
{
|
||||||
|
struct bidram *bidram = &plat_bidram;
|
||||||
|
|
||||||
|
bidram->fixup = true;
|
||||||
|
bidram_gen_gd_bi_dram();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 bidram_append_size(void)
|
||||||
|
{
|
||||||
|
struct bidram *bidram = &plat_bidram;
|
||||||
|
u64 size = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* 4GB+ */
|
||||||
|
for (i = 0; i < MEM_RESV_COUNT; i++)
|
||||||
|
size += bidram->size_u64[i];
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
static int bidram_is_overlap(phys_addr_t base1, phys_size_t size1,
|
static int bidram_is_overlap(phys_addr_t base1, phys_size_t size1,
|
||||||
phys_addr_t base2, phys_size_t size2)
|
phys_addr_t base2, phys_size_t size2)
|
||||||
{
|
{
|
||||||
|
|
@ -341,7 +378,7 @@ phys_size_t bidram_get_ram_size(void)
|
||||||
phys_addr_t end_addr;
|
phys_addr_t end_addr;
|
||||||
parse_fn_t parse_fn;
|
parse_fn_t parse_fn;
|
||||||
int i, count, ret;
|
int i, count, ret;
|
||||||
int bad_cnt = 0;
|
int bad_cnt = 0, n = 0;
|
||||||
char bad_name[12];
|
char bad_name[12];
|
||||||
|
|
||||||
parse_fn = board_bidram_parse_fn();
|
parse_fn = board_bidram_parse_fn();
|
||||||
|
|
@ -373,19 +410,18 @@ phys_size_t bidram_get_ram_size(void)
|
||||||
i, (ulong)list[i].base,
|
i, (ulong)list[i].base,
|
||||||
(ulong)list[i].base + (ulong)list[i].size);
|
(ulong)list[i].base + (ulong)list[i].size);
|
||||||
|
|
||||||
if (!list[i].size)
|
if (!list[i].size) {
|
||||||
|
/* handle 4GB+ */
|
||||||
|
if (list[i].size_u64 && n < MEM_RESV_COUNT) {
|
||||||
|
bidram->base_u64[n] = list[i].base_u64;
|
||||||
|
bidram->size_u64[n] = list[i].size_u64;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* We assume the last block gives the ram addr end */
|
/* We assume the last block gives the ram addr end */
|
||||||
if (i == count - 1) {
|
|
||||||
ram_addr_end = list[i].base + list[i].size;
|
ram_addr_end = list[i].base + list[i].size;
|
||||||
ret = bidram_add(CONFIG_SYS_SDRAM_BASE,
|
|
||||||
ram_addr_end - CONFIG_SYS_SDRAM_BASE);
|
|
||||||
if (ret) {
|
|
||||||
BIDRAM_E("Failed to add bidram from bi_dram[%d]\n", i);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This is a bad dram bank? record it */
|
/* This is a bad dram bank? record it */
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
|
|
@ -405,6 +441,13 @@ phys_size_t bidram_get_ram_size(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = bidram_add(CONFIG_SYS_SDRAM_BASE,
|
||||||
|
ram_addr_end - CONFIG_SYS_SDRAM_BASE);
|
||||||
|
if (ret) {
|
||||||
|
BIDRAM_E("Failed to add bidram from bi_dram[%d]\n", i);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Reserve bad dram bank after bidram_add(), treat as reserved region */
|
/* Reserve bad dram bank after bidram_add(), treat as reserved region */
|
||||||
for (i = 0; i < bad_cnt; i++) {
|
for (i = 0; i < bad_cnt; i++) {
|
||||||
if (gd->flags & GD_FLG_RELOC)
|
if (gd->flags & GD_FLG_RELOC)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue