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