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