1 /* 2 * (C) Copyright 2016 Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <adc.h> 9 #include <asm/io.h> 10 #include <asm/arch/boot_mode.h> 11 #include <asm/arch/rk_atags.h> 12 #include <cli.h> 13 #include <dm.h> 14 #include <fdtdec.h> 15 #include <boot_rkimg.h> 16 #include <linux/usb/phy-rockchip-inno-usb2.h> 17 #include <key.h> 18 #ifdef CONFIG_DM_RAMDISK 19 #include <ramdisk.h> 20 #endif 21 #include <mmc.h> 22 23 DECLARE_GLOBAL_DATA_PTR; 24 25 #if (CONFIG_ROCKCHIP_BOOT_MODE_REG == 0) 26 27 int setup_boot_mode(void) 28 { 29 return 0; 30 } 31 32 #else 33 34 void set_back_to_bootrom_dnl_flag(void) 35 { 36 writel(BOOT_BROM_DOWNLOAD, CONFIG_ROCKCHIP_BOOT_MODE_REG); 37 } 38 39 /* 40 * detect download key status by adc, most rockchip 41 * based boards use adc sample the download key status, 42 * but there are also some use gpio. So it's better to 43 * make this a weak function that can be override by 44 * some special boards. 45 */ 46 #define KEY_DOWN_MIN_VAL 0 47 #define KEY_DOWN_MAX_VAL 30 48 49 __weak int rockchip_dnl_key_pressed(void) 50 { 51 int keyval = false; 52 53 /* 54 * This is a generic interface to read key 55 */ 56 #if defined(CONFIG_DM_KEY) 57 keyval = key_read(KEY_VOLUMEUP); 58 59 return key_is_pressed(keyval); 60 61 #elif defined(CONFIG_ADC) 62 const void *blob = gd->fdt_blob; 63 unsigned int val; 64 int channel = 1; 65 int node; 66 int ret; 67 u32 chns[2]; 68 69 node = fdt_node_offset_by_compatible(blob, 0, "adc-keys"); 70 if (node >= 0) { 71 if (!fdtdec_get_int_array(blob, node, "io-channels", chns, 2)) 72 channel = chns[1]; 73 } 74 75 ret = adc_channel_single_shot("saradc", channel, &val); 76 if (ret) { 77 printf("%s adc_channel_single_shot fail! ret=%d\n", __func__, ret); 78 return false; 79 } 80 81 if ((val >= KEY_DOWN_MIN_VAL) && (val <= KEY_DOWN_MAX_VAL)) 82 return true; 83 else 84 return false; 85 #endif 86 87 return keyval; 88 } 89 90 void boot_devtype_init(void) 91 { 92 const char *devtype_num_set = "run rkimg_bootdev"; 93 char *devtype = NULL, *devnum = NULL; 94 static int done = 0; 95 int atags_en = 0; 96 int ret; 97 98 if (done) 99 return; 100 101 /* 102 * New way: get bootdev from preloader atags info. 103 */ 104 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS 105 struct tag *t; 106 107 t = atags_get_tag(ATAG_BOOTDEV); 108 if (t) { 109 atags_en = 1; 110 switch (t->u.bootdev.devtype) { 111 case BOOT_TYPE_EMMC: 112 devtype = "mmc"; 113 devnum = "0"; 114 break; 115 case BOOT_TYPE_SD0: 116 case BOOT_TYPE_SD1: 117 devtype = "mmc"; 118 devnum = "1"; 119 break; 120 case BOOT_TYPE_NAND: 121 devtype = "rknand"; 122 devnum = "0"; 123 break; 124 case BOOT_TYPE_SPI_NAND: 125 devtype = "spinand"; 126 devnum = "0"; 127 break; 128 case BOOT_TYPE_SPI_NOR: 129 devtype = "spinor"; 130 devnum = "1"; 131 break; 132 case BOOT_TYPE_RAM: 133 devtype = "ramdisk"; 134 devnum = "0"; 135 break; 136 default: 137 printf("Unknown bootdev type: 0x%x\n", 138 t->u.bootdev.devtype); 139 goto fallback; 140 } 141 } 142 143 debug("%s: Get bootdev from atags: %s %s\n", __func__, devtype, devnum); 144 145 if (devtype && devnum) { 146 env_set("devtype", devtype); 147 env_set("devnum", devnum); 148 #ifdef CONFIG_DM_MMC 149 if (!strcmp("mmc", devtype)) 150 mmc_initialize(gd->bd); 151 #endif 152 goto finish; 153 } 154 #endif 155 156 /* 157 * Legacy way: get bootdev by going through all boot media. 158 */ 159 fallback: 160 #ifdef CONFIG_DM_MMC 161 mmc_initialize(gd->bd); 162 #endif 163 ret = run_command_list(devtype_num_set, -1, 0); 164 if (ret) { 165 /* Set default dev type/num if command not valid */ 166 devtype = "mmc"; 167 devnum = "0"; 168 env_set("devtype", devtype); 169 env_set("devnum", devnum); 170 } 171 finish: 172 done = 1; 173 printf("Bootdev%s: %s %s\n", atags_en ? "(atags)" : "", 174 env_get("devtype"), env_get("devnum")); 175 } 176 177 void rockchip_dnl_mode_check(void) 178 { 179 if (rockchip_dnl_key_pressed()) { 180 printf("download key pressed... "); 181 if (rockchip_u2phy_vbus_detect() > 0) { 182 printf("entering download mode...\n"); 183 /* If failed, we fall back to bootrom download mode */ 184 run_command_list("rockusb 0 ${devtype} ${devnum}", -1, 0); 185 set_back_to_bootrom_dnl_flag(); 186 do_reset(NULL, 0, 0, NULL); 187 } else { 188 printf("\n"); 189 #ifdef CONFIG_RKIMG_BOOTLOADER 190 /* If there is no recovery partition, just boot on */ 191 struct blk_desc *dev_desc; 192 disk_partition_t part_info; 193 194 dev_desc = rockchip_get_bootdev(); 195 if (!dev_desc) { 196 printf("%s: dev_desc is NULL!\n", __func__); 197 return; 198 } 199 if (part_get_info_by_name(dev_desc, PART_RECOVERY, 200 &part_info)) { 201 debug("%s: no recovery partition\n", __func__); 202 return; 203 } 204 #endif 205 printf("recovery key pressed, entering recovery mode!\n"); 206 env_set("reboot_mode", "recovery"); 207 } 208 } 209 } 210 211 int setup_boot_mode(void) 212 { 213 int boot_mode = BOOT_MODE_NORMAL; 214 char env_preboot[256] = {0}; 215 216 boot_devtype_init(); 217 rockchip_dnl_mode_check(); 218 #ifdef CONFIG_RKIMG_BOOTLOADER 219 boot_mode = rockchip_get_boot_mode(); 220 #endif 221 switch (boot_mode) { 222 case BOOT_MODE_BOOTLOADER: 223 printf("enter fastboot!\n"); 224 #if defined(CONFIG_FASTBOOT_FLASH_MMC_DEV) 225 snprintf(env_preboot, 256, 226 "setenv preboot; mmc dev %x; fastboot usb 0; ", 227 CONFIG_FASTBOOT_FLASH_MMC_DEV); 228 #elif defined(CONFIG_FASTBOOT_FLASH_NAND_DEV) 229 snprintf(env_preboot, 256, 230 "setenv preboot; fastboot usb 0; "); 231 #endif 232 env_set("preboot", env_preboot); 233 break; 234 case BOOT_MODE_UMS: 235 printf("enter UMS!\n"); 236 env_set("preboot", "setenv preboot; ums mmc 0"); 237 break; 238 case BOOT_MODE_LOADER: 239 printf("enter Rockusb!\n"); 240 env_set("preboot", "setenv preboot; rockusb 0 ${devtype} ${devnum}"); 241 break; 242 case BOOT_MODE_CHARGING: 243 printf("enter charging!\n"); 244 env_set("preboot", "setenv preboot; charge"); 245 break; 246 case BOOT_MODE_RECOVERY: 247 printf("enter Recovery mode!\n"); 248 env_set("reboot_mode", "recovery"); 249 break; 250 } 251 252 return 0; 253 } 254 255 #endif 256