1 /* 2 * (C) Copyright 2017 Rockchip Electronics Co., Ltd. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 #include <common.h> 7 #include <clk.h> 8 #include <dm.h> 9 #include <debug_uart.h> 10 #include <ram.h> 11 #include <syscon.h> 12 #include <sysmem.h> 13 #include <asm/io.h> 14 #include <asm/arch/vendor.h> 15 #include <misc.h> 16 #include <asm/gpio.h> 17 #include <asm/arch/clock.h> 18 #include <asm/arch/periph.h> 19 #include <asm/arch/boot_mode.h> 20 #include <asm/arch/rk_atags.h> 21 #include <asm/arch/param.h> 22 #ifdef CONFIG_DM_CHARGE_DISPLAY 23 #include <power/charge_display.h> 24 #endif 25 #ifdef CONFIG_DM_DVFS 26 #include <dvfs.h> 27 #endif 28 #ifdef CONFIG_ROCKCHIP_IO_DOMAIN 29 #include <io-domain.h> 30 #endif 31 #ifdef CONFIG_DM_REGULATOR 32 #include <power/regulator.h> 33 #endif 34 #ifdef CONFIG_DRM_ROCKCHIP 35 #include <video_rockchip.h> 36 #endif 37 #ifdef CONFIG_ROCKCHIP_DEBUGGER 38 #include <rockchip_debugger.h> 39 #endif 40 #include <of_live.h> 41 #include <dm/root.h> 42 43 DECLARE_GLOBAL_DATA_PTR; 44 /* define serialno max length, the max length is 512 Bytes 45 * The remaining bytes are used to ensure that the first 512 bytes 46 * are valid when executing 'env_set("serial#", value)'. 47 */ 48 #define VENDOR_SN_MAX 513 49 #define CPUID_LEN 0x10 50 #define CPUID_OFF 0x7 51 52 static int rockchip_set_serialno(void) 53 { 54 char serialno_str[VENDOR_SN_MAX]; 55 int ret = 0, i; 56 u8 cpuid[CPUID_LEN] = {0}; 57 u8 low[CPUID_LEN / 2], high[CPUID_LEN / 2]; 58 u64 serialno; 59 60 /* Read serial number from vendor storage part */ 61 memset(serialno_str, 0, VENDOR_SN_MAX); 62 #ifdef CONFIG_ROCKCHIP_VENDOR_PARTITION 63 ret = vendor_storage_read(VENDOR_SN_ID, serialno_str, (VENDOR_SN_MAX-1)); 64 if (ret > 0) { 65 env_set("serial#", serialno_str); 66 } else { 67 #endif 68 #ifdef CONFIG_ROCKCHIP_EFUSE 69 struct udevice *dev; 70 71 /* retrieve the device */ 72 ret = uclass_get_device_by_driver(UCLASS_MISC, 73 DM_GET_DRIVER(rockchip_efuse), &dev); 74 if (ret) { 75 printf("%s: could not find efuse device\n", __func__); 76 return ret; 77 } 78 /* read the cpu_id range from the efuses */ 79 ret = misc_read(dev, CPUID_OFF, &cpuid, sizeof(cpuid)); 80 if (ret) { 81 printf("%s: reading cpuid from the efuses failed\n", __func__); 82 return ret; 83 } 84 #else 85 /* generate random cpuid */ 86 for (i = 0; i < CPUID_LEN; i++) { 87 cpuid[i] = (u8)(rand()); 88 } 89 #endif 90 /* Generate the serial number based on CPU ID */ 91 for (i = 0; i < 8; i++) { 92 low[i] = cpuid[1 + (i << 1)]; 93 high[i] = cpuid[i << 1]; 94 } 95 serialno = crc32_no_comp(0, low, 8); 96 serialno |= (u64)crc32_no_comp(serialno, high, 8) << 32; 97 snprintf(serialno_str, sizeof(serialno_str), "%llx", serialno); 98 99 env_set("serial#", serialno_str); 100 #ifdef CONFIG_ROCKCHIP_VENDOR_PARTITION 101 } 102 #endif 103 return ret; 104 } 105 106 #if defined(CONFIG_USB_FUNCTION_FASTBOOT) 107 int fb_set_reboot_flag(void) 108 { 109 printf("Setting reboot to fastboot flag ...\n"); 110 /* Set boot mode to fastboot */ 111 writel(BOOT_FASTBOOT, CONFIG_ROCKCHIP_BOOT_MODE_REG); 112 113 return 0; 114 } 115 #endif 116 117 __weak int rk_board_init(void) 118 { 119 return 0; 120 } 121 122 __weak int rk_board_late_init(void) 123 { 124 return 0; 125 } 126 127 __weak int soc_clk_dump(void) 128 { 129 return 0; 130 } 131 132 __weak int set_armclk_rate(void) 133 { 134 return 0; 135 } 136 137 int board_late_init(void) 138 { 139 rockchip_set_serialno(); 140 #if (CONFIG_ROCKCHIP_BOOT_MODE_REG > 0) 141 setup_boot_mode(); 142 #endif 143 144 #ifdef CONFIG_DM_CHARGE_DISPLAY 145 charge_display(); 146 #endif 147 148 #ifdef CONFIG_DRM_ROCKCHIP 149 rockchip_show_logo(); 150 #endif 151 152 soc_clk_dump(); 153 154 return rk_board_late_init(); 155 } 156 157 #ifdef CONFIG_USING_KERNEL_DTB 158 #include <asm/arch/resource_img.h> 159 160 int init_kernel_dtb(void) 161 { 162 int ret = 0; 163 ulong fdt_addr = 0; 164 165 fdt_addr = env_get_ulong("fdt_addr_r", 16, 0); 166 if (!fdt_addr) { 167 printf("No Found FDT Load Address.\n"); 168 return -1; 169 } 170 171 ret = rockchip_read_dtb_file((void *)fdt_addr); 172 if (ret < 0) { 173 printf("%s dtb in resource read fail\n", __func__); 174 return 0; 175 } 176 177 of_live_build((void *)fdt_addr, (struct device_node **)&gd->of_root); 178 179 dm_scan_fdt((void *)fdt_addr, false); 180 181 gd->fdt_blob = (void *)fdt_addr; 182 183 /* Reserve 'reserved-memory' */ 184 ret = boot_fdt_add_sysmem_rsv_regions((void *)gd->fdt_blob); 185 if (ret) 186 return ret; 187 188 return 0; 189 } 190 #endif 191 192 void board_env_fixup(void) 193 { 194 ulong kernel_addr_r; 195 196 if (gd->flags & GD_FLG_BL32_ENABLED) 197 return; 198 199 /* If bl32 is disabled, maybe kernel can be load to lower address. */ 200 kernel_addr_r = env_get_ulong("kernel_addr_no_bl32_r", 16, -1); 201 if (kernel_addr_r != -1) 202 env_set_hex("kernel_addr_r", kernel_addr_r); 203 } 204 205 int board_init(void) 206 { 207 int ret; 208 209 board_debug_uart_init(); 210 211 #ifdef CONFIG_USING_KERNEL_DTB 212 init_kernel_dtb(); 213 #endif 214 /* 215 * pmucru isn't referenced on some platforms, so pmucru driver can't 216 * probe that the "assigned-clocks" is unused. 217 */ 218 clks_probe(); 219 #ifdef CONFIG_DM_REGULATOR 220 ret = regulators_enable_boot_on(false); 221 if (ret) 222 debug("%s: Cannot enable boot on regulator\n", __func__); 223 #endif 224 225 #ifdef CONFIG_ROCKCHIP_IO_DOMAIN 226 io_domain_init(); 227 #endif 228 229 set_armclk_rate(); 230 231 #ifdef CONFIG_DM_DVFS 232 dvfs_init(true); 233 #endif 234 235 return rk_board_init(); 236 } 237 238 int interrupt_debugger_init(void) 239 { 240 int ret = 0; 241 242 #ifdef CONFIG_ROCKCHIP_DEBUGGER 243 ret = rockchip_debugger_init(); 244 #endif 245 return ret; 246 } 247 248 int board_fdt_fixup(void *blob) 249 { 250 __maybe_unused int ret = 0; 251 252 #ifdef CONFIG_DRM_ROCKCHIP 253 rockchip_display_fixup(blob); 254 #endif 255 256 #ifdef CONFIG_ROCKCHIP_RK3288 257 /* RK3288W HDMI Revision ID is 0x1A */ 258 if (readl(0xff980004) == 0x1A) { 259 ret = fdt_setprop_string(blob, 0, 260 "compatible", "rockchip,rk3288w"); 261 if (ret) 262 printf("fdt set compatible failed: %d\n", ret); 263 } 264 #endif 265 266 return ret; 267 } 268 269 void board_quiesce_devices(void) 270 { 271 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS 272 /* Destroy atags makes next warm boot safer */ 273 atags_destroy(); 274 #endif 275 } 276 277 void enable_caches(void) 278 { 279 icache_enable(); 280 dcache_enable(); 281 } 282 283 #ifdef CONFIG_LMB 284 /* 285 * Using last bi_dram[...] to initialize "bootm_low" and "bootm_mapsize". 286 * This makes lmb_alloc_base() always alloc from tail of sdram. 287 * If we don't assign it, bi_dram[0] is used by default and it may cause 288 * lmb_alloc_base() fail when bi_dram[0] range is small. 289 */ 290 void board_lmb_reserve(struct lmb *lmb) 291 { 292 u64 start, size; 293 char bootm_low[32]; 294 char bootm_mapsize[32]; 295 int i; 296 297 for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { 298 if (!gd->bd->bi_dram[i].size) 299 break; 300 } 301 302 start = gd->bd->bi_dram[i - 1].start; 303 size = gd->bd->bi_dram[i - 1].size; 304 305 /* 306 * 32-bit kernel: ramdisk/fdt shouldn't be loaded to highmem area(768MB+), 307 * otherwise "Unable to handle kernel paging request at virtual address ...". 308 * 309 * So that we hope limit highest address at 768M, but there comes the the 310 * problem: ramdisk is a compressed image and it expands after descompress, 311 * so it accesses 768MB+ and brings the above "Unable to handle kernel ...". 312 * 313 * We make a appointment that the highest memory address is 512MB, it 314 * makes lmb alloc safer. 315 */ 316 #ifndef CONFIG_ARM64 317 if (start >= ((u64)CONFIG_SYS_SDRAM_BASE + SZ_512M)) { 318 start = gd->bd->bi_dram[i - 2].start; 319 size = gd->bd->bi_dram[i - 2].size; 320 } 321 322 if ((start + size) > ((u64)CONFIG_SYS_SDRAM_BASE + SZ_512M)) 323 size = (u64)CONFIG_SYS_SDRAM_BASE + SZ_512M - start; 324 #endif 325 sprintf(bootm_low, "0x%llx", start); 326 sprintf(bootm_mapsize, "0x%llx", size); 327 env_set("bootm_low", bootm_low); 328 env_set("bootm_mapsize", bootm_mapsize); 329 } 330 #endif 331 332 #ifdef CONFIG_SYSMEM 333 int board_sysmem_reserve(struct sysmem *sysmem) 334 { 335 struct sysmem_property prop; 336 int ret; 337 338 /* ATF */ 339 prop = param_parse_atf_mem(); 340 ret = sysmem_reserve(prop.name, prop.base, prop.size); 341 if (ret) 342 return ret; 343 344 /* PSTORE/ATAGS/SHM */ 345 prop = param_parse_common_resv_mem(); 346 ret = sysmem_reserve(prop.name, prop.base, prop.size); 347 if (ret) 348 return ret; 349 350 /* OP-TEE */ 351 prop = param_parse_optee_mem(); 352 ret = sysmem_reserve(prop.name, prop.base, prop.size); 353 if (ret) 354 return ret; 355 356 return 0; 357 } 358 #endif 359 360 #if defined(CONFIG_ROCKCHIP_PRELOADER_SERIAL) && \ 361 defined(CONFIG_ROCKCHIP_PRELOADER_ATAGS) 362 int board_init_f_init_serial(void) 363 { 364 struct tag *t = atags_get_tag(ATAG_SERIAL); 365 366 if (t) { 367 gd->serial.using_pre_serial = t->u.serial.enable; 368 gd->serial.addr = t->u.serial.addr; 369 gd->serial.baudrate = t->u.serial.baudrate; 370 gd->serial.id = t->u.serial.id; 371 372 debug("%s: enable=%d, addr=0x%lx, baudrate=%d, id=%d\n", 373 __func__, gd->serial.using_pre_serial, 374 gd->serial.addr, gd->serial.baudrate, 375 gd->serial.id); 376 } 377 378 return 0; 379 } 380 #endif 381 382 #if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG) 383 #include <fdt_support.h> 384 #include <usb.h> 385 #include <usb/dwc2_udc.h> 386 387 static struct dwc2_plat_otg_data otg_data = { 388 .rx_fifo_sz = 512, 389 .np_tx_fifo_sz = 16, 390 .tx_fifo_sz = 128, 391 }; 392 393 int board_usb_init(int index, enum usb_init_type init) 394 { 395 int node; 396 fdt_addr_t addr; 397 const fdt32_t *reg; 398 const void *blob = gd->fdt_blob; 399 400 /* find the usb_otg node */ 401 node = fdt_node_offset_by_compatible(blob, -1, "snps,dwc2"); 402 403 retry: 404 if (node > 0) { 405 reg = fdt_getprop(blob, node, "reg", NULL); 406 if (!reg) 407 return -EINVAL; 408 409 addr = fdt_translate_address(blob, node, reg); 410 if (addr == OF_BAD_ADDR) { 411 pr_err("Not found usb_otg address\n"); 412 return -EINVAL; 413 } 414 415 #if defined(CONFIG_ROCKCHIP_RK3288) 416 if (addr != 0xff580000) { 417 node = fdt_node_offset_by_compatible(blob, node, 418 "snps,dwc2"); 419 goto retry; 420 } 421 #endif 422 } else { 423 /* 424 * With kernel dtb support, rk3288 dwc2 otg node 425 * use the rockchip legacy dwc2 driver "dwc_otg_310" 426 * with the compatible "rockchip,rk3288_usb20_otg", 427 * and rk3368 also use the "dwc_otg_310" driver with 428 * the compatible "rockchip,rk3368-usb". 429 */ 430 #if defined(CONFIG_ROCKCHIP_RK3288) 431 node = fdt_node_offset_by_compatible(blob, -1, 432 "rockchip,rk3288_usb20_otg"); 433 #elif defined(CONFIG_ROCKCHIP_RK3368) 434 node = fdt_node_offset_by_compatible(blob, -1, 435 "rockchip,rk3368-usb"); 436 #endif 437 if (node > 0) { 438 goto retry; 439 } else { 440 pr_err("Not found usb_otg device\n"); 441 return -ENODEV; 442 } 443 } 444 445 otg_data.regs_otg = (uintptr_t)addr; 446 447 return dwc2_udc_probe(&otg_data); 448 } 449 450 int board_usb_cleanup(int index, enum usb_init_type init) 451 { 452 return 0; 453 } 454 #endif 455