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