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/gpio.h> 14 #include <asm/arch/clock.h> 15 #include <asm/arch/periph.h> 16 #include <asm/arch/boot_mode.h> 17 #ifdef CONFIG_DM_CHARGE_DISPLAY 18 #include <power/charge_display.h> 19 #endif 20 #ifdef CONFIG_DM_REGULATOR 21 #include <power/regulator.h> 22 #endif 23 #ifdef CONFIG_DRM_ROCKCHIP 24 #include <video_rockchip.h> 25 #endif 26 #include <mmc.h> 27 #include <of_live.h> 28 #include <dm/root.h> 29 30 DECLARE_GLOBAL_DATA_PTR; 31 32 #if defined(CONFIG_USB_FUNCTION_FASTBOOT) 33 int fb_set_reboot_flag(void) 34 { 35 printf("Setting reboot to fastboot flag ...\n"); 36 /* Set boot mode to fastboot */ 37 writel(BOOT_FASTBOOT, CONFIG_ROCKCHIP_BOOT_MODE_REG); 38 39 return 0; 40 } 41 42 #define FASTBOOT_KEY_GPIO 43 /* GPIO1_B3 */ 43 static int fastboot_key_pressed(void) 44 { 45 gpio_request(FASTBOOT_KEY_GPIO, "fastboot_key"); 46 gpio_direction_input(FASTBOOT_KEY_GPIO); 47 return !gpio_get_value(FASTBOOT_KEY_GPIO); 48 } 49 #endif 50 51 #ifdef CONFIG_DM_CHARGE_DISPLAY 52 static int charge_display(void) 53 { 54 int ret; 55 struct udevice *dev; 56 57 ret = uclass_get_device(UCLASS_CHARGE_DISPLAY, 0, &dev); 58 if (ret) { 59 if (ret != -ENODEV) { 60 printf("Get UCLASS CHARGE DISPLAY failed: %d\n", ret); 61 return ret; 62 } 63 return 0; 64 } 65 66 return charge_display_show(dev); 67 } 68 #endif 69 70 __weak int rk_board_init(void) 71 { 72 return 0; 73 } 74 75 __weak int rk_board_late_init(void) 76 { 77 return 0; 78 } 79 80 int board_late_init(void) 81 { 82 #if defined(CONFIG_USB_FUNCTION_FASTBOOT) 83 if (fastboot_key_pressed()) { 84 printf("fastboot key pressed!\n"); 85 fb_set_reboot_flag(); 86 } 87 #endif 88 89 #if (CONFIG_ROCKCHIP_BOOT_MODE_REG > 0) 90 setup_boot_mode(); 91 #endif 92 93 #ifdef CONFIG_DM_CHARGE_DISPLAY 94 charge_display(); 95 #endif 96 97 #ifdef CONFIG_DRM_ROCKCHIP 98 rockchip_show_logo(); 99 #endif 100 101 return rk_board_late_init(); 102 } 103 104 #ifdef CONFIG_USING_KERNEL_DTB 105 #include <asm/arch/resource_img.h> 106 #define DTB_FILE "rk-kernel.dtb" 107 int init_kernel_dtb(void) 108 { 109 int ret = 0; 110 struct mmc *mmc; 111 struct udevice *dev; 112 ulong fdt_addr = 0; 113 114 ret = mmc_initialize(gd->bd); 115 if (ret) 116 goto scan_nand; 117 mmc = find_mmc_device(0); 118 if (!mmc) { 119 printf("no mmc device at slot 0\n"); 120 goto scan_nand; 121 } 122 ret = mmc_init(mmc); 123 if (!ret) 124 goto init_dtb; 125 printf("%s mmc init fail %d\n", __func__, ret); 126 scan_nand: 127 ret = uclass_get_device(UCLASS_RKNAND, 0, &dev); 128 if (ret) { 129 printf("%s: Cannot find rknand device\n", __func__); 130 return -1; 131 } 132 133 init_dtb: 134 fdt_addr = env_get_ulong("fdt_addr_r", 16, 0); 135 if (!fdt_addr) { 136 printf("No Found FDT Load Address.\n"); 137 return -1; 138 } 139 140 ret = rockchip_read_resource_file((void *)fdt_addr, DTB_FILE, 0, 0); 141 if (ret < 0) { 142 printf("%s dtb in resource read fail\n", __func__); 143 return 0; 144 } 145 146 of_live_build((void *)fdt_addr, (struct device_node **)&gd->of_root); 147 148 dm_scan_fdt((void *)fdt_addr, false); 149 150 gd->fdt_blob = (void *)fdt_addr; 151 152 return 0; 153 } 154 #endif 155 156 157 int board_init(void) 158 { 159 int ret; 160 161 #if !defined(CONFIG_SUPPORT_SPL) 162 board_debug_uart_init(); 163 #endif 164 #ifdef CONFIG_USING_KERNEL_DTB 165 init_kernel_dtb(); 166 #endif 167 #ifdef CONFIG_DM_REGULATOR 168 ret = regulators_enable_boot_on(false); 169 if (ret) 170 debug("%s: Cannot enable boot on regulator\n", __func__); 171 #endif 172 173 return rk_board_init(); 174 } 175 176 #if !defined(CONFIG_SYS_DCACHE_OFF) && !defined(CONFIG_ARM64) 177 void enable_caches(void) 178 { 179 /* Enable D-cache. I-cache is already enabled in start.S */ 180 dcache_enable(); 181 } 182 #endif 183 184 #if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG) 185 #include <usb.h> 186 #include <usb/dwc2_udc.h> 187 188 static struct dwc2_plat_otg_data otg_data = { 189 .rx_fifo_sz = 512, 190 .np_tx_fifo_sz = 16, 191 .tx_fifo_sz = 128, 192 }; 193 194 int board_usb_init(int index, enum usb_init_type init) 195 { 196 int node; 197 const char *mode; 198 bool matched = false; 199 const void *blob = gd->fdt_blob; 200 201 /* find the usb_otg node */ 202 node = fdt_node_offset_by_compatible(blob, -1, 203 "snps,dwc2"); 204 205 while (node > 0) { 206 mode = fdt_getprop(blob, node, "dr_mode", NULL); 207 if (mode && strcmp(mode, "otg") == 0) { 208 matched = true; 209 break; 210 } 211 212 node = fdt_node_offset_by_compatible(blob, node, 213 "snps,dwc2"); 214 } 215 if (!matched) { 216 debug("Not found usb_otg device\n"); 217 return -ENODEV; 218 } 219 otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg"); 220 221 return dwc2_udc_probe(&otg_data); 222 } 223 224 int board_usb_cleanup(int index, enum usb_init_type init) 225 { 226 return 0; 227 } 228 #endif 229