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 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_dtb_file((void *)fdt_addr); 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 /* 168 * pmucru isn't referenced on some platforms, so pmucru driver can't 169 * probe that the "assigned-clocks" is unused. 170 */ 171 clks_probe(); 172 #ifdef CONFIG_DM_REGULATOR 173 ret = regulators_enable_boot_on(false); 174 if (ret) 175 debug("%s: Cannot enable boot on regulator\n", __func__); 176 #endif 177 178 return rk_board_init(); 179 } 180 181 #if !defined(CONFIG_SYS_DCACHE_OFF) && !defined(CONFIG_ARM64) 182 void enable_caches(void) 183 { 184 /* Enable D-cache. I-cache is already enabled in start.S */ 185 dcache_enable(); 186 } 187 #endif 188 189 #if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG) 190 #include <fdt_support.h> 191 #include <usb.h> 192 #include <usb/dwc2_udc.h> 193 194 static struct dwc2_plat_otg_data otg_data = { 195 .rx_fifo_sz = 512, 196 .np_tx_fifo_sz = 16, 197 .tx_fifo_sz = 128, 198 }; 199 200 int board_usb_init(int index, enum usb_init_type init) 201 { 202 int node; 203 const char *mode; 204 fdt_addr_t addr; 205 const fdt32_t *reg; 206 bool matched = false; 207 const void *blob = gd->fdt_blob; 208 209 /* find the usb_otg node */ 210 node = fdt_node_offset_by_compatible(blob, -1, 211 "snps,dwc2"); 212 213 while (node > 0) { 214 mode = fdt_getprop(blob, node, "dr_mode", NULL); 215 if (mode && strcmp(mode, "otg") == 0) { 216 matched = true; 217 break; 218 } 219 220 node = fdt_node_offset_by_compatible(blob, node, 221 "snps,dwc2"); 222 } 223 if (!matched) { 224 debug("Not found usb_otg device\n"); 225 return -ENODEV; 226 } 227 228 reg = fdt_getprop(blob, node, "reg", NULL); 229 if (!reg) 230 return -EINVAL; 231 232 addr = fdt_translate_address(blob, node, reg); 233 if (addr == OF_BAD_ADDR) { 234 pr_err("Not found usb_otg address\n"); 235 return -EINVAL; 236 } 237 238 otg_data.regs_otg = (uintptr_t)addr; 239 240 return dwc2_udc_probe(&otg_data); 241 } 242 243 int board_usb_cleanup(int index, enum usb_init_type init) 244 { 245 return 0; 246 } 247 #endif 248