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 rockchip_display_fixup((void *)gd->fdt_blob); 100 #endif 101 102 return rk_board_late_init(); 103 } 104 105 #ifdef CONFIG_USING_KERNEL_DTB 106 #include <asm/arch/resource_img.h> 107 #define DTB_FILE "rk-kernel.dtb" 108 int init_kernel_dtb(void) 109 { 110 int ret = 0; 111 struct mmc *mmc; 112 struct udevice *dev; 113 ulong fdt_addr = 0; 114 115 ret = mmc_initialize(gd->bd); 116 if (ret) 117 goto scan_nand; 118 mmc = find_mmc_device(0); 119 if (!mmc) { 120 printf("no mmc device at slot 0\n"); 121 goto scan_nand; 122 } 123 ret = mmc_init(mmc); 124 if (!ret) 125 goto init_dtb; 126 printf("%s mmc init fail %d\n", __func__, ret); 127 scan_nand: 128 ret = uclass_get_device(UCLASS_RKNAND, 0, &dev); 129 if (ret) { 130 printf("%s: Cannot find rknand device\n", __func__); 131 return -1; 132 } 133 134 init_dtb: 135 fdt_addr = env_get_ulong("fdt_addr_r", 16, 0); 136 if (!fdt_addr) { 137 printf("No Found FDT Load Address.\n"); 138 return -1; 139 } 140 141 ret = rockchip_read_resource_file((void *)fdt_addr, DTB_FILE, 0, 0); 142 if (ret < 0) { 143 printf("%s dtb in resource read fail\n", __func__); 144 return 0; 145 } 146 147 of_live_build((void *)fdt_addr, (struct device_node **)&gd->of_root); 148 149 dm_scan_fdt((void *)fdt_addr, false); 150 151 gd->fdt_blob = (void *)fdt_addr; 152 153 return 0; 154 } 155 #endif 156 157 158 int board_init(void) 159 { 160 int ret; 161 162 #if !defined(CONFIG_SUPPORT_SPL) 163 board_debug_uart_init(); 164 #endif 165 #ifdef CONFIG_USING_KERNEL_DTB 166 init_kernel_dtb(); 167 #endif 168 #ifdef CONFIG_DM_REGULATOR 169 ret = regulators_enable_boot_on(false); 170 if (ret) 171 debug("%s: Cannot enable boot on regulator\n", __func__); 172 #endif 173 174 return rk_board_init(); 175 } 176 177 #if !defined(CONFIG_SYS_DCACHE_OFF) && !defined(CONFIG_ARM64) 178 void enable_caches(void) 179 { 180 /* Enable D-cache. I-cache is already enabled in start.S */ 181 dcache_enable(); 182 } 183 #endif 184 185 #if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG) 186 #include <usb.h> 187 #include <usb/dwc2_udc.h> 188 189 static struct dwc2_plat_otg_data otg_data = { 190 .rx_fifo_sz = 512, 191 .np_tx_fifo_sz = 16, 192 .tx_fifo_sz = 128, 193 }; 194 195 int board_usb_init(int index, enum usb_init_type init) 196 { 197 int node; 198 const char *mode; 199 bool matched = false; 200 const void *blob = gd->fdt_blob; 201 202 /* find the usb_otg node */ 203 node = fdt_node_offset_by_compatible(blob, -1, 204 "snps,dwc2"); 205 206 while (node > 0) { 207 mode = fdt_getprop(blob, node, "dr_mode", NULL); 208 if (mode && strcmp(mode, "otg") == 0) { 209 matched = true; 210 break; 211 } 212 213 node = fdt_node_offset_by_compatible(blob, node, 214 "snps,dwc2"); 215 } 216 if (!matched) { 217 debug("Not found usb_otg device\n"); 218 return -ENODEV; 219 } 220 otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg"); 221 222 return dwc2_udc_probe(&otg_data); 223 } 224 225 int board_usb_cleanup(int index, enum usb_init_type init) 226 { 227 return 0; 228 } 229 #endif 230