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