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 <cli.h> 12 #include <dm.h> 13 #include <fdtdec.h> 14 #include <boot_rkimg.h> 15 #include <linux/usb/phy-rockchip-inno-usb2.h> 16 #include <key.h> 17 18 DECLARE_GLOBAL_DATA_PTR; 19 20 #if (CONFIG_ROCKCHIP_BOOT_MODE_REG == 0) 21 22 int setup_boot_mode(void) 23 { 24 return 0; 25 } 26 27 #else 28 29 void set_back_to_bootrom_dnl_flag(void) 30 { 31 writel(BOOT_BROM_DOWNLOAD, CONFIG_ROCKCHIP_BOOT_MODE_REG); 32 } 33 34 /* 35 * detect download key status by adc, most rockchip 36 * based boards use adc sample the download key status, 37 * but there are also some use gpio. So it's better to 38 * make this a weak function that can be override by 39 * some special boards. 40 */ 41 #define KEY_DOWN_MIN_VAL 0 42 #define KEY_DOWN_MAX_VAL 30 43 44 __weak int rockchip_dnl_key_pressed(void) 45 { 46 int keyval = false; 47 48 /* 49 * This is a generic interface to read key 50 */ 51 #if defined(CONFIG_DM_KEY) 52 keyval = key_read(KEY_VOLUMEUP); 53 54 return key_is_pressed(keyval); 55 56 #elif defined(CONFIG_ADC) 57 const void *blob = gd->fdt_blob; 58 unsigned int val; 59 int channel = 1; 60 int node; 61 int ret; 62 u32 chns[2]; 63 64 node = fdt_node_offset_by_compatible(blob, 0, "adc-keys"); 65 if (node >= 0) { 66 if (!fdtdec_get_int_array(blob, node, "io-channels", chns, 2)) 67 channel = chns[1]; 68 } 69 70 ret = adc_channel_single_shot("saradc", channel, &val); 71 if (ret) { 72 printf("%s adc_channel_single_shot fail! ret=%d\n", __func__, ret); 73 return false; 74 } 75 76 if ((val >= KEY_DOWN_MIN_VAL) && (val <= KEY_DOWN_MAX_VAL)) 77 return true; 78 else 79 return false; 80 #endif 81 82 return keyval; 83 } 84 85 void devtype_num_envset(void) 86 { 87 static int done = 0; 88 int ret = 0; 89 90 if (done) 91 return; 92 93 const char *devtype_num_set = "run rkimg_bootdev"; 94 95 ret = run_command_list(devtype_num_set, -1, 0); 96 if (ret) { 97 /* Set default dev type/num if command not valid */ 98 env_set("devtype", "mmc"); 99 env_set("devnum", "0"); 100 } 101 102 done = 1; 103 } 104 105 void rockchip_dnl_mode_check(void) 106 { 107 if (rockchip_dnl_key_pressed()) { 108 if (rockchip_u2phy_vbus_detect()) { 109 printf("download key pressed, entering download mode...\n"); 110 /* If failed, we fall back to bootrom download mode */ 111 run_command_list("rockusb 0 ${devtype} ${devnum}", -1, 0); 112 set_back_to_bootrom_dnl_flag(); 113 do_reset(NULL, 0, 0, NULL); 114 } else { 115 printf("recovery key pressed, entering recovery mode!\n"); 116 env_set("reboot_mode", "recovery"); 117 } 118 } 119 } 120 121 int setup_boot_mode(void) 122 { 123 int boot_mode = BOOT_MODE_NORMAL; 124 char env_preboot[256] = {0}; 125 126 devtype_num_envset(); 127 rockchip_dnl_mode_check(); 128 #ifdef CONFIG_RKIMG_BOOTLOADER 129 boot_mode = rockchip_get_boot_mode(); 130 #endif 131 switch (boot_mode) { 132 case BOOT_MODE_BOOTLOADER: 133 printf("enter fastboot!\n"); 134 #if defined(CONFIG_FASTBOOT_FLASH_MMC_DEV) 135 snprintf(env_preboot, 256, 136 "setenv preboot; mmc dev %x; fastboot usb 0; ", 137 CONFIG_FASTBOOT_FLASH_MMC_DEV); 138 #elif defined(CONFIG_FASTBOOT_FLASH_NAND_DEV) 139 snprintf(env_preboot, 256, 140 "setenv preboot; fastboot usb 0; "); 141 #endif 142 env_set("preboot", env_preboot); 143 break; 144 case BOOT_MODE_UMS: 145 printf("enter UMS!\n"); 146 env_set("preboot", "setenv preboot; ums mmc 0"); 147 break; 148 case BOOT_MODE_LOADER: 149 printf("enter Rockusb!\n"); 150 env_set("preboot", "setenv preboot; rockusb 0 ${devtype} ${devnum}"); 151 break; 152 case BOOT_MODE_CHARGING: 153 printf("enter charging!\n"); 154 env_set("preboot", "setenv preboot; charge"); 155 break; 156 case BOOT_MODE_RECOVERY: 157 printf("enter Recovery mode!\n"); 158 env_set("reboot_mode", "recovery"); 159 break; 160 } 161 162 return 0; 163 } 164 165 #endif 166