1 /* 2 * Copyright (C) 2016 Stefan Roese <sr@denx.de> 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <dm.h> 9 #include <fdtdec.h> 10 #include <libfdt.h> 11 #include <asm/io.h> 12 #include <asm/system.h> 13 #include <asm/arch/cpu.h> 14 #include <asm/arch/soc.h> 15 #include <asm/armv8/mmu.h> 16 17 DECLARE_GLOBAL_DATA_PTR; 18 19 /* 20 * Not all memory is mapped in the MMU. So we need to restrict the 21 * memory size so that U-Boot does not try to access it. Also, the 22 * internal registers are located at 0xf000.0000 - 0xffff.ffff. 23 * Currently only 2GiB are mapped for system memory. This is what 24 * we pass to the U-Boot subsystem here. 25 */ 26 #define USABLE_RAM_SIZE 0x80000000 27 28 ulong board_get_usable_ram_top(ulong total_size) 29 { 30 if (gd->ram_size > USABLE_RAM_SIZE) 31 return USABLE_RAM_SIZE; 32 33 return gd->ram_size; 34 } 35 36 /* 37 * On ARMv8, MBus is not configured in U-Boot. To enable compilation 38 * of the already implemented drivers, lets add a dummy version of 39 * this function so that linking does not fail. 40 */ 41 const struct mbus_dram_target_info *mvebu_mbus_dram_info(void) 42 { 43 return NULL; 44 } 45 46 /* DRAM init code ... */ 47 48 static const void *get_memory_reg_prop(const void *fdt, int *lenp) 49 { 50 int offset; 51 52 offset = fdt_path_offset(fdt, "/memory"); 53 if (offset < 0) 54 return NULL; 55 56 return fdt_getprop(fdt, offset, "reg", lenp); 57 } 58 59 int dram_init(void) 60 { 61 const void *fdt = gd->fdt_blob; 62 const fdt32_t *val; 63 int ac, sc, len; 64 65 ac = fdt_address_cells(fdt, 0); 66 sc = fdt_size_cells(fdt, 0); 67 if (ac < 0 || sc < 1 || sc > 2) { 68 printf("invalid address/size cells\n"); 69 return -EINVAL; 70 } 71 72 val = get_memory_reg_prop(fdt, &len); 73 if (len / sizeof(*val) < ac + sc) 74 return -EINVAL; 75 76 val += ac; 77 78 gd->ram_size = fdtdec_get_number(val, sc); 79 80 debug("DRAM size = %08lx\n", (unsigned long)gd->ram_size); 81 82 return 0; 83 } 84 85 void dram_init_banksize(void) 86 { 87 const void *fdt = gd->fdt_blob; 88 const fdt32_t *val; 89 int ac, sc, cells, len, i; 90 91 val = get_memory_reg_prop(fdt, &len); 92 if (len < 0) 93 return; 94 95 ac = fdt_address_cells(fdt, 0); 96 sc = fdt_size_cells(fdt, 0); 97 if (ac < 1 || sc > 2 || sc < 1 || sc > 2) { 98 printf("invalid address/size cells\n"); 99 return; 100 } 101 102 cells = ac + sc; 103 104 len /= sizeof(*val); 105 106 for (i = 0; i < CONFIG_NR_DRAM_BANKS && len >= cells; 107 i++, len -= cells) { 108 gd->bd->bi_dram[i].start = fdtdec_get_number(val, ac); 109 val += ac; 110 gd->bd->bi_dram[i].size = fdtdec_get_number(val, sc); 111 val += sc; 112 113 debug("DRAM bank %d: start = %08lx, size = %08lx\n", 114 i, (unsigned long)gd->bd->bi_dram[i].start, 115 (unsigned long)gd->bd->bi_dram[i].size); 116 } 117 } 118 119 int arch_cpu_init(void) 120 { 121 /* Nothing to do (yet) */ 122 return 0; 123 } 124 125 int arch_early_init_r(void) 126 { 127 struct udevice *dev; 128 int ret; 129 int i; 130 131 /* 132 * Loop over all MISC uclass drivers to call the comphy code 133 * and init all CP110 devices enabled in the DT 134 */ 135 i = 0; 136 while (1) { 137 /* Call the comphy code via the MISC uclass driver */ 138 ret = uclass_get_device(UCLASS_MISC, i++, &dev); 139 140 /* We're done, once no further CP110 device is found */ 141 if (ret) 142 break; 143 } 144 145 /* Cause the SATA device to do its early init */ 146 uclass_first_device(UCLASS_AHCI, &dev); 147 148 return 0; 149 } 150