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