Rayagonda Kokatanur | 1d8fa36 | 2020-07-15 22:48:55 +0530 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0+ |
| 2 | /* |
| 3 | * Copyright 2020 Broadcom. |
| 4 | * |
| 5 | */ |
| 6 | |
| 7 | #include <common.h> |
Rayagonda Kokatanur | 237417d | 2020-07-15 22:49:04 +0530 | [diff] [blame] | 8 | #include <fdt_support.h> |
Rayagonda Kokatanur | 1d8fa36 | 2020-07-15 22:48:55 +0530 | [diff] [blame] | 9 | #include <asm/io.h> |
Rayagonda Kokatanur | 73069ca | 2020-07-15 22:49:01 +0530 | [diff] [blame] | 10 | #include <asm/gic-v3.h> |
Simon Glass | 3ba929a | 2020-10-30 21:38:53 -0600 | [diff] [blame] | 11 | #include <asm/global_data.h> |
Rayagonda Kokatanur | 1d8fa36 | 2020-07-15 22:48:55 +0530 | [diff] [blame] | 12 | #include <asm/system.h> |
| 13 | #include <asm/armv8/mmu.h> |
Abhishek Shah | a2936da | 2020-07-15 22:48:59 +0530 | [diff] [blame] | 14 | #include <asm/arch-bcmns3/bl33_info.h> |
Rayagonda Kokatanur | 237417d | 2020-07-15 22:49:04 +0530 | [diff] [blame] | 15 | #include <dt-bindings/memory/bcm-ns3-mc.h> |
Rayagonda Kokatanur | 6d7656e | 2020-08-25 23:16:37 +0530 | [diff] [blame] | 16 | #include <broadcom/chimp.h> |
Rayagonda Kokatanur | 1d8fa36 | 2020-07-15 22:48:55 +0530 | [diff] [blame] | 17 | |
Rayagonda Kokatanur | 237417d | 2020-07-15 22:49:04 +0530 | [diff] [blame] | 18 | #define BANK_OFFSET(bank) ((u64)BCM_NS3_DDR_INFO_BASE + 8 + ((bank) * 16)) |
| 19 | |
| 20 | /* |
| 21 | * ns3_dram_bank - DDR bank details |
| 22 | * |
| 23 | * @start: DDR bank start address |
| 24 | * @len: DDR bank length |
| 25 | */ |
| 26 | struct ns3_dram_bank { |
| 27 | u64 start[BCM_NS3_MAX_NR_BANKS]; |
| 28 | u64 len[BCM_NS3_MAX_NR_BANKS]; |
| 29 | }; |
| 30 | |
| 31 | /* |
| 32 | * ns3_dram_hdr - DDR header info |
| 33 | * |
| 34 | * @sig: DDR info signature |
| 35 | * @bank: DDR bank details |
| 36 | */ |
| 37 | struct ns3_dram_hdr { |
| 38 | u32 sig; |
| 39 | struct ns3_dram_bank bank; |
| 40 | }; |
| 41 | |
Rayagonda Kokatanur | 1d8fa36 | 2020-07-15 22:48:55 +0530 | [diff] [blame] | 42 | static struct mm_region ns3_mem_map[] = { |
| 43 | { |
| 44 | .virt = 0x0UL, |
| 45 | .phys = 0x0UL, |
| 46 | .size = 0x80000000UL, |
| 47 | .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | |
| 48 | PTE_BLOCK_NON_SHARE | |
| 49 | PTE_BLOCK_PXN | PTE_BLOCK_UXN |
| 50 | }, { |
Rayagonda Kokatanur | 237417d | 2020-07-15 22:49:04 +0530 | [diff] [blame] | 51 | .virt = BCM_NS3_MEM_START, |
| 52 | .phys = BCM_NS3_MEM_START, |
| 53 | .size = BCM_NS3_MEM_LEN, |
Rayagonda Kokatanur | 1d8fa36 | 2020-07-15 22:48:55 +0530 | [diff] [blame] | 54 | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | |
| 55 | PTE_BLOCK_INNER_SHARE |
| 56 | }, { |
Rayagonda Kokatanur | 237417d | 2020-07-15 22:49:04 +0530 | [diff] [blame] | 57 | .virt = BCM_NS3_BANK_1_MEM_START, |
| 58 | .phys = BCM_NS3_BANK_1_MEM_START, |
| 59 | .size = BCM_NS3_BANK_1_MEM_LEN, |
| 60 | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | |
| 61 | PTE_BLOCK_INNER_SHARE |
| 62 | }, { |
Rayagonda Kokatanur | 1d8fa36 | 2020-07-15 22:48:55 +0530 | [diff] [blame] | 63 | /* List terminator */ |
| 64 | 0, |
| 65 | } |
| 66 | }; |
| 67 | |
| 68 | struct mm_region *mem_map = ns3_mem_map; |
| 69 | |
| 70 | DECLARE_GLOBAL_DATA_PTR; |
| 71 | |
Abhishek Shah | a2936da | 2020-07-15 22:48:59 +0530 | [diff] [blame] | 72 | /* |
| 73 | * Force the bl33_info to the data-section, as .bss will not be valid |
| 74 | * when save_boot_params is invoked. |
| 75 | */ |
| 76 | struct bl33_info *bl33_info __section(".data"); |
| 77 | |
Rayagonda Kokatanur | 237417d | 2020-07-15 22:49:04 +0530 | [diff] [blame] | 78 | /* |
| 79 | * Run modulo 256 checksum calculation and return the calculated checksum |
| 80 | */ |
| 81 | static u8 checksum_calc(u8 *p, unsigned int len) |
| 82 | { |
| 83 | unsigned int i; |
| 84 | u8 chksum = 0; |
| 85 | |
| 86 | for (i = 0; i < len; i++) |
| 87 | chksum += p[i]; |
| 88 | |
| 89 | return chksum; |
| 90 | } |
| 91 | |
| 92 | /* |
| 93 | * This function parses the memory layout information from a reserved area in |
| 94 | * DDR, and then fix up the FDT before passing it to Linux. |
| 95 | * |
| 96 | * In the case of error, do nothing and the default memory layout in DT will |
| 97 | * be used |
| 98 | */ |
| 99 | static int mem_info_parse_fixup(void *fdt) |
| 100 | { |
| 101 | struct ns3_dram_hdr hdr; |
| 102 | u32 *p32, i, nr_banks; |
| 103 | u64 *p64; |
| 104 | |
| 105 | /* validate signature */ |
| 106 | p32 = (u32 *)BCM_NS3_DDR_INFO_BASE; |
| 107 | hdr.sig = *p32; |
| 108 | if (hdr.sig != BCM_NS3_DDR_INFO_SIG) { |
| 109 | printf("DDR info signature 0x%x invalid\n", hdr.sig); |
| 110 | return -EINVAL; |
| 111 | } |
| 112 | |
| 113 | /* run checksum test to validate data */ |
| 114 | if (checksum_calc((u8 *)p32, BCM_NS3_DDR_INFO_LEN) != 0) { |
| 115 | printf("Checksum on DDR info failed\n"); |
| 116 | return -EINVAL; |
| 117 | } |
| 118 | |
| 119 | /* parse information for each bank */ |
| 120 | nr_banks = 0; |
| 121 | for (i = 0; i < BCM_NS3_MAX_NR_BANKS; i++) { |
| 122 | /* skip banks with a length of zero */ |
| 123 | p64 = (u64 *)BANK_OFFSET(i); |
| 124 | if (*(p64 + 1) == 0) |
| 125 | continue; |
| 126 | |
| 127 | hdr.bank.start[i] = *p64; |
| 128 | hdr.bank.len[i] = *(p64 + 1); |
| 129 | |
| 130 | printf("mem[%u] 0x%llx - 0x%llx\n", i, hdr.bank.start[i], |
| 131 | hdr.bank.start[i] + hdr.bank.len[i] - 1); |
| 132 | nr_banks++; |
| 133 | } |
| 134 | |
| 135 | if (!nr_banks) { |
| 136 | printf("No DDR banks detected\n"); |
| 137 | return -ENOMEM; |
| 138 | } |
| 139 | |
| 140 | return fdt_fixup_memory_banks(fdt, hdr.bank.start, hdr.bank.len, |
| 141 | nr_banks); |
| 142 | } |
| 143 | |
Rayagonda Kokatanur | 1d8fa36 | 2020-07-15 22:48:55 +0530 | [diff] [blame] | 144 | int board_init(void) |
| 145 | { |
Bharat Kumar Reddy Gooty | ffc7604 | 2020-07-15 22:49:05 +0530 | [diff] [blame] | 146 | /* Setup memory using "memory" node from DTB */ |
| 147 | if (fdtdec_setup_mem_size_base() != 0) |
| 148 | return -EINVAL; |
| 149 | fdtdec_setup_memory_banksize(); |
| 150 | |
Abhishek Shah | a2936da | 2020-07-15 22:48:59 +0530 | [diff] [blame] | 151 | if (bl33_info->version != BL33_INFO_VERSION) |
| 152 | printf("*** warning: ATF BL31 and U-Boot not in sync! ***\n"); |
| 153 | |
Rayagonda Kokatanur | 1d8fa36 | 2020-07-15 22:48:55 +0530 | [diff] [blame] | 154 | return 0; |
| 155 | } |
| 156 | |
| 157 | int board_late_init(void) |
| 158 | { |
| 159 | return 0; |
| 160 | } |
| 161 | |
| 162 | int dram_init(void) |
| 163 | { |
Bharat Kumar Reddy Gooty | ffc7604 | 2020-07-15 22:49:05 +0530 | [diff] [blame] | 164 | /* |
| 165 | * Mark ram base as the last 16MB of 2GB DDR, which is 0xFF00_0000. |
| 166 | * So that relocation happens with in the last 16MB memory. |
| 167 | */ |
| 168 | gd->ram_base = (phys_size_t)(BCM_NS3_MEM_END - SZ_16M); |
| 169 | gd->ram_size = (unsigned long)SZ_16M; |
Rayagonda Kokatanur | 1d8fa36 | 2020-07-15 22:48:55 +0530 | [diff] [blame] | 170 | |
| 171 | return 0; |
| 172 | } |
| 173 | |
| 174 | int dram_init_banksize(void) |
| 175 | { |
Bharat Kumar Reddy Gooty | ffc7604 | 2020-07-15 22:49:05 +0530 | [diff] [blame] | 176 | gd->bd->bi_dram[0].start = (BCM_NS3_MEM_END - SZ_16M); |
| 177 | gd->bd->bi_dram[0].size = SZ_16M; |
Rayagonda Kokatanur | 1d8fa36 | 2020-07-15 22:48:55 +0530 | [diff] [blame] | 178 | |
| 179 | return 0; |
| 180 | } |
| 181 | |
Bharat Kumar Reddy Gooty | ffc7604 | 2020-07-15 22:49:05 +0530 | [diff] [blame] | 182 | /* Limit RAM used by U-Boot to the DDR first bank End region */ |
| 183 | ulong board_get_usable_ram_top(ulong total_size) |
| 184 | { |
| 185 | return BCM_NS3_MEM_END; |
| 186 | } |
| 187 | |
Harald Seiler | 6f14d5f | 2020-12-15 16:47:52 +0100 | [diff] [blame] | 188 | void reset_cpu(void) |
Rayagonda Kokatanur | 1d8fa36 | 2020-07-15 22:48:55 +0530 | [diff] [blame] | 189 | { |
Harald Seiler | 2cfae26 | 2020-12-15 16:47:50 +0100 | [diff] [blame] | 190 | /* Perform a level 3 reset */ |
| 191 | psci_system_reset2(3, 0); |
Rayagonda Kokatanur | 1d8fa36 | 2020-07-15 22:48:55 +0530 | [diff] [blame] | 192 | } |
Rayagonda Kokatanur | 73069ca | 2020-07-15 22:49:01 +0530 | [diff] [blame] | 193 | |
| 194 | #ifdef CONFIG_OF_BOARD_SETUP |
| 195 | int ft_board_setup(void *fdt, struct bd_info *bd) |
| 196 | { |
Rayagonda Kokatanur | 6d7656e | 2020-08-25 23:16:37 +0530 | [diff] [blame] | 197 | u32 chimp_hs = CHIMP_HANDSHAKE_WAIT_TIMEOUT; |
| 198 | |
Rayagonda Kokatanur | 73069ca | 2020-07-15 22:49:01 +0530 | [diff] [blame] | 199 | gic_lpi_tables_init(); |
| 200 | |
Rayagonda Kokatanur | 6d7656e | 2020-08-25 23:16:37 +0530 | [diff] [blame] | 201 | /* |
| 202 | * Check for chimp handshake status. |
| 203 | * Zero timeout value will actually fall to default timeout. |
| 204 | * |
| 205 | * System boot is independent of chimp handshake. |
| 206 | * chimp handshake failure is not a catastrophic error. |
| 207 | * Hence continue booting if chimp handshake fails. |
| 208 | */ |
| 209 | chimp_handshake_status_optee(0, &chimp_hs); |
| 210 | if (chimp_hs == CHIMP_HANDSHAKE_SUCCESS) |
| 211 | printf("ChiMP handshake successful\n"); |
| 212 | else |
| 213 | printf("ERROR: ChiMP handshake status 0x%x\n", chimp_hs); |
| 214 | |
Rayagonda Kokatanur | 237417d | 2020-07-15 22:49:04 +0530 | [diff] [blame] | 215 | return mem_info_parse_fixup(fdt); |
Rayagonda Kokatanur | 73069ca | 2020-07-15 22:49:01 +0530 | [diff] [blame] | 216 | } |
| 217 | #endif /* CONFIG_OF_BOARD_SETUP */ |