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/param.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 #include <console.h> 23 24 DECLARE_GLOBAL_DATA_PTR; 25 26 #if (CONFIG_ROCKCHIP_BOOT_MODE_REG == 0) 27 28 int setup_boot_mode(void) 29 { 30 return 0; 31 } 32 33 #else 34 35 void set_back_to_bootrom_dnl_flag(void) 36 { 37 writel(BOOT_BROM_DOWNLOAD, CONFIG_ROCKCHIP_BOOT_MODE_REG); 38 } 39 40 /* 41 * detect download key status by adc, most rockchip 42 * based boards use adc sample the download key status, 43 * but there are also some use gpio. So it's better to 44 * make this a weak function that can be override by 45 * some special boards. 46 */ 47 #define KEY_DOWN_MIN_VAL 0 48 #define KEY_DOWN_MAX_VAL 30 49 50 __weak int rockchip_dnl_key_pressed(void) 51 { 52 int keyval = false; 53 54 /* 55 * This is a generic interface to read key 56 */ 57 #if defined(CONFIG_DM_KEY) 58 keyval = key_read(KEY_VOLUMEUP); 59 60 return key_is_pressed(keyval); 61 62 #elif defined(CONFIG_ADC) 63 const void *blob = gd->fdt_blob; 64 unsigned int val; 65 int channel = 1; 66 int node; 67 int ret; 68 u32 chns[2]; 69 70 node = fdt_node_offset_by_compatible(blob, 0, "adc-keys"); 71 if (node >= 0) { 72 if (!fdtdec_get_int_array(blob, node, "io-channels", chns, 2)) 73 channel = chns[1]; 74 } 75 76 ret = adc_channel_single_shot("saradc", channel, &val); 77 if (ret) { 78 printf("%s adc_channel_single_shot fail! ret=%d\n", __func__, ret); 79 return false; 80 } 81 82 if ((val >= KEY_DOWN_MIN_VAL) && (val <= KEY_DOWN_MAX_VAL)) 83 return true; 84 else 85 return false; 86 #endif 87 88 return keyval; 89 } 90 91 void boot_devtype_init(void) 92 { 93 const char *devtype_num_set = "run rkimg_bootdev"; 94 char *devtype = NULL, *devnum = NULL; 95 static int done = 0; 96 int atags_en = 0; 97 int ret; 98 99 if (done) 100 return; 101 102 ret = param_parse_bootdev(&devtype, &devnum); 103 if (!ret) { 104 atags_en = 1; 105 env_set("devtype", devtype); 106 env_set("devnum", devnum); 107 #ifdef CONFIG_DM_MMC 108 if (!strcmp("mmc", devtype)) 109 mmc_initialize(gd->bd); 110 #endif 111 } else { 112 #ifdef CONFIG_DM_MMC 113 mmc_initialize(gd->bd); 114 #endif 115 ret = run_command_list(devtype_num_set, -1, 0); 116 if (ret) { 117 /* Set default dev type/num if command not valid */ 118 devtype = "mmc"; 119 devnum = "0"; 120 env_set("devtype", devtype); 121 env_set("devnum", devnum); 122 } 123 } 124 125 done = 1; 126 printf("Bootdev%s: %s %s\n", atags_en ? "(atags)" : "", 127 env_get("devtype"), env_get("devnum")); 128 } 129 130 void rockchip_dnl_mode_check(void) 131 { 132 /* recovery key or "ctrl+d" */ 133 if (rockchip_dnl_key_pressed() || 134 gd->console_evt == CONSOLE_EVT_CTRL_D) { 135 printf("download key pressed... "); 136 if (rockchip_u2phy_vbus_detect() > 0) { 137 printf("entering download mode...\n"); 138 /* If failed, we fall back to bootrom download mode */ 139 run_command_list("rockusb 0 ${devtype} ${devnum}", -1, 0); 140 set_back_to_bootrom_dnl_flag(); 141 do_reset(NULL, 0, 0, NULL); 142 } else { 143 printf("\n"); 144 #ifdef CONFIG_RKIMG_BOOTLOADER 145 /* If there is no recovery partition, just boot on */ 146 struct blk_desc *dev_desc; 147 disk_partition_t part_info; 148 int ret; 149 150 dev_desc = rockchip_get_bootdev(); 151 if (!dev_desc) { 152 printf("%s: dev_desc is NULL!\n", __func__); 153 return; 154 } 155 156 ret = part_get_info_by_name(dev_desc, 157 PART_RECOVERY, 158 &part_info); 159 if (ret < 0) { 160 debug("%s: no recovery partition\n", __func__); 161 return; 162 } 163 #endif 164 printf("recovery key pressed, entering recovery mode!\n"); 165 env_set("reboot_mode", "recovery"); 166 } 167 } else if (gd->console_evt == CONSOLE_EVT_CTRL_F) { 168 env_set("reboot_mode", "fastboot"); 169 } 170 } 171 172 int setup_boot_mode(void) 173 { 174 int boot_mode = BOOT_MODE_NORMAL; 175 char env_preboot[256] = {0}; 176 177 boot_devtype_init(); 178 rockchip_dnl_mode_check(); 179 #ifdef CONFIG_RKIMG_BOOTLOADER 180 boot_mode = rockchip_get_boot_mode(); 181 #endif 182 switch (boot_mode) { 183 case BOOT_MODE_BOOTLOADER: 184 printf("enter fastboot!\n"); 185 #if defined(CONFIG_FASTBOOT_FLASH_MMC_DEV) 186 snprintf(env_preboot, 256, 187 "setenv preboot; mmc dev %x; fastboot usb 0; ", 188 CONFIG_FASTBOOT_FLASH_MMC_DEV); 189 #elif defined(CONFIG_FASTBOOT_FLASH_NAND_DEV) 190 snprintf(env_preboot, 256, 191 "setenv preboot; fastboot usb 0; "); 192 #endif 193 env_set("preboot", env_preboot); 194 break; 195 case BOOT_MODE_UMS: 196 printf("enter UMS!\n"); 197 env_set("preboot", "setenv preboot; ums mmc 0"); 198 break; 199 case BOOT_MODE_LOADER: 200 printf("enter Rockusb!\n"); 201 env_set("preboot", "setenv preboot; rockusb 0 ${devtype} ${devnum}"); 202 break; 203 case BOOT_MODE_CHARGING: 204 printf("enter charging!\n"); 205 env_set("preboot", "setenv preboot; charge"); 206 break; 207 case BOOT_MODE_RECOVERY: 208 printf("enter Recovery mode!\n"); 209 env_set("reboot_mode", "recovery"); 210 break; 211 } 212 213 return 0; 214 } 215 216 #endif 217