diff options
Diffstat (limited to 'arch/arm/mach-snapdragon')
| -rw-r--r-- | arch/arm/mach-snapdragon/board.c | 87 | 
1 files changed, 76 insertions, 11 deletions
| diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c index 92492c3a033..93de516d9ea 100644 --- a/arch/arm/mach-snapdragon/board.c +++ b/arch/arm/mach-snapdragon/board.c @@ -38,9 +38,18 @@ static struct mm_region rbx_mem_map[CONFIG_NR_DRAM_BANKS + 2] = { { 0 } };  struct mm_region *mem_map = rbx_mem_map; +static struct { +	phys_addr_t start; +	phys_size_t size; +} prevbl_ddr_banks[CONFIG_NR_DRAM_BANKS] __section(".data") = { 0 }; +  int dram_init(void)  { -	return fdtdec_setup_mem_size_base(); +	/* +	 * gd->ram_base / ram_size have been setup already +	 * in qcom_parse_memory(). +	 */ +	return 0;  }  static int ddr_bank_cmp(const void *v1, const void *v2) @@ -58,21 +67,69 @@ static int ddr_bank_cmp(const void *v1, const void *v2)  	return (res1->start >> 24) - (res2->start >> 24);  } +/* This has to be done post-relocation since gd->bd isn't preserved */ +static void qcom_configure_bi_dram(void) +{ +	int i; + +	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { +		gd->bd->bi_dram[i].start = prevbl_ddr_banks[i].start; +		gd->bd->bi_dram[i].size = prevbl_ddr_banks[i].size; +	} +} +  int dram_init_banksize(void)  { -	int ret; +	qcom_configure_bi_dram(); -	ret = fdtdec_setup_memory_banksize(); -	if (ret < 0) -		return ret; +	return 0; +} -	if (CONFIG_NR_DRAM_BANKS < 2) -		return 0; +static void qcom_parse_memory(void) +{ +	ofnode node; +	const fdt64_t *memory; +	int memsize; +	phys_addr_t ram_end = 0; +	int i, j, banks; + +	node = ofnode_path("/memory"); +	if (!ofnode_valid(node)) { +		log_err("No memory node found in device tree!\n"); +		return; +	} +	memory = ofnode_read_prop(node, "reg", &memsize); +	if (!memory) { +		log_err("No memory configuration was provided by the previous bootloader!\n"); +		return; +	} + +	banks = min(memsize / (2 * sizeof(u64)), (ulong)CONFIG_NR_DRAM_BANKS); + +	if (memsize / sizeof(u64) > CONFIG_NR_DRAM_BANKS * 2) +		log_err("Provided more than the max of %d memory banks\n", CONFIG_NR_DRAM_BANKS); + +	if (banks > CONFIG_NR_DRAM_BANKS) +		log_err("Provided more memory banks than we can handle\n"); + +	for (i = 0, j = 0; i < banks * 2; i += 2, j++) { +		prevbl_ddr_banks[j].start = get_unaligned_be64(&memory[i]); +		prevbl_ddr_banks[j].size = get_unaligned_be64(&memory[i + 1]); +		/* SM8650 boards sometimes have empty regions! */ +		if (!prevbl_ddr_banks[j].size) { +			j--; +			continue; +		} +		ram_end = max(ram_end, prevbl_ddr_banks[j].start + prevbl_ddr_banks[j].size); +	}  	/* Sort our RAM banks -_- */ -	qsort(gd->bd->bi_dram, CONFIG_NR_DRAM_BANKS, sizeof(gd->bd->bi_dram[0]), ddr_bank_cmp); +	qsort(prevbl_ddr_banks, banks, sizeof(prevbl_ddr_banks[0]), ddr_bank_cmp); -	return 0; +	gd->ram_base = prevbl_ddr_banks[0].start; +	gd->ram_size = ram_end - gd->ram_base; +	debug("ram_base = %#011lx, ram_size = %#011llx, ram_end = %#011llx\n", +	      gd->ram_base, gd->ram_size, ram_end);  }  static void show_psci_version(void) @@ -110,11 +167,19 @@ void *board_fdt_blob_setup(int *err)  	if (internal_valid) {  		debug("Using built in FDT\n"); -		return (void *)gd->fdt_blob;  	} else {  		debug("Using external FDT\n"); -		return (void *)fdt; +		/* So we can use it before returning */ +		gd->fdt_blob = fdt;  	} + +	/* +	 * Parse the /memory node while we're here, +	 * this makes it easy to do other things early. +	 */ +	qcom_parse_memory(); + +	return (void *)gd->fdt_blob;  }  void reset_cpu(void) | 
