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 <dm.h> 12 #include <fdtdec.h> 13 14 DECLARE_GLOBAL_DATA_PTR; 15 16 void set_back_to_bootrom_dnl_flag(void) 17 { 18 writel(BOOT_BROM_DOWNLOAD, CONFIG_ROCKCHIP_BOOT_MODE_REG); 19 } 20 21 /* 22 * detect download key status by adc, most rockchip 23 * based boards use adc sample the download key status, 24 * but there are also some use gpio. So it's better to 25 * make this a weak function that can be override by 26 * some special boards. 27 */ 28 #define KEY_DOWN_MIN_VAL 0 29 #define KEY_DOWN_MAX_VAL 30 30 31 __weak int rockchip_dnl_key_pressed(void) 32 { 33 const void *blob = gd->fdt_blob; 34 unsigned int val; 35 int channel = 1; 36 int node; 37 u32 chns[2]; 38 39 node = fdt_node_offset_by_compatible(blob, 0, "adc-keys"); 40 if (node >= 0) { 41 if (!fdtdec_get_int_array(blob, node, "io-channels", chns, 2)) 42 channel = chns[1]; 43 } 44 45 if (adc_channel_single_shot("saradc", channel, &val)) { 46 printf("%s adc_channel_single_shot fail!\n", __func__); 47 return false; 48 } 49 50 if ((val >= KEY_DOWN_MIN_VAL) && (val <= KEY_DOWN_MAX_VAL)) 51 return true; 52 else 53 return false; 54 } 55 56 void rockchip_dnl_mode_check(void) 57 { 58 if (rockchip_dnl_key_pressed()) { 59 printf("download key pressed, entering download mode..."); 60 set_back_to_bootrom_dnl_flag(); 61 do_reset(NULL, 0, 0, NULL); 62 } 63 } 64 65 int setup_boot_mode(void) 66 { 67 void *reg; 68 int boot_mode; 69 70 rockchip_dnl_mode_check(); 71 72 if (of_machine_is_compatible("rockchip,rk3128")) 73 reg = (void *)0x100a0038; 74 else 75 reg = (void *)CONFIG_ROCKCHIP_BOOT_MODE_REG; 76 77 boot_mode = readl(reg); 78 79 debug("boot mode %x.\n", boot_mode); 80 81 /* Clear boot mode */ 82 writel(BOOT_NORMAL, reg); 83 84 switch (boot_mode) { 85 case BOOT_FASTBOOT: 86 printf("enter fastboot!\n"); 87 env_set("preboot", "setenv preboot; fastboot usb0"); 88 break; 89 case BOOT_UMS: 90 printf("enter UMS!\n"); 91 env_set("preboot", "setenv preboot; ums mmc 0"); 92 break; 93 case BOOT_LOADER: 94 printf("enter Rockusb!\n"); 95 env_set("preboot", "setenv preboot; rockusb 0 mmc 0"); 96 break; 97 } 98 99 return 0; 100 } 101