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 list_head reserved_head;
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#define _MEMBLK_H
|
||||
|
||||
#define ALIAS_COUNT_MAX 2
|
||||
#define MEM_RESV_COUNT 3
|
||||
|
||||
enum memblk_id {
|
||||
MEMBLK_ID_UNK,
|
||||
|
|
@ -47,6 +48,8 @@ struct memblk_attr {
|
|||
struct memblock {
|
||||
phys_addr_t base;
|
||||
phys_size_t size;
|
||||
u64 base_u64; /* 4GB+ */
|
||||
u64 size_u64;
|
||||
phys_addr_t orig_base;
|
||||
struct memblk_attr attr;
|
||||
struct list_head node;
|
||||
|
|
|
|||
75
lib/bidram.c
75
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)
|
||||
{
|
||||
struct bidram *bidram = &plat_bidram;
|
||||
struct lmb *lmb = &plat_bidram.lmb;
|
||||
struct lmb_property *mem_rgn = lmb->memory.region;
|
||||
struct lmb_property *res_rgn = lmb->reserved.region;
|
||||
|
|
@ -168,12 +169,48 @@ void bidram_gen_gd_bi_dram(void)
|
|||
gd->bd->bi_dram[idx].start;
|
||||
}
|
||||
done:
|
||||
for (i = 0; i < idx; i++) {
|
||||
BIDRAM_D("gd bi_dram[%d]: start=0x%08lx, end=0x%08lx\n",
|
||||
i, (ulong)gd->bd->bi_dram[i].start,
|
||||
(ulong)gd->bd->bi_dram[i].start +
|
||||
(ulong)gd->bd->bi_dram[i].size);
|
||||
/* Append 4GB+ memory blocks */
|
||||
if (bidram->fixup) {
|
||||
for (i = 0; i < MEM_RESV_COUNT; i++) {
|
||||
if (!bidram->size_u64[i])
|
||||
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,
|
||||
|
|
@ -341,7 +378,7 @@ phys_size_t bidram_get_ram_size(void)
|
|||
phys_addr_t end_addr;
|
||||
parse_fn_t parse_fn;
|
||||
int i, count, ret;
|
||||
int bad_cnt = 0;
|
||||
int bad_cnt = 0, n = 0;
|
||||
char bad_name[12];
|
||||
|
||||
parse_fn = board_bidram_parse_fn();
|
||||
|
|
@ -373,19 +410,18 @@ phys_size_t bidram_get_ram_size(void)
|
|||
i, (ulong)list[i].base,
|
||||
(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;
|
||||
}
|
||||
|
||||
/* We assume the last block gives the ram addr end */
|
||||
if (i == count - 1) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
ram_addr_end = list[i].base + list[i].size;
|
||||
|
||||
/* This is a bad dram bank? record it */
|
||||
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 */
|
||||
for (i = 0; i < bad_cnt; i++) {
|
||||
if (gd->flags & GD_FLG_RELOC)
|
||||
|
|
|
|||
Loading…
Reference in New Issue