From 11b9e1141895e719e2ad4421f746c4b5359c671b Mon Sep 17 00:00:00 2001 From: jamess_huang Date: Thu, 12 Oct 2017 11:47:27 +0800 Subject: [PATCH 36/50] auto enable ums mode when TinkerBoard is connected to PC Change-Id: Ice3f37906ab1ae0428c1d23867a58c5c720aa8ab --- arch/arm/include/asm/arch-rockchip/gpio.h | 22 ++++++++ arch/arm/mach-rockchip/rk3288-board.c | 62 +++++++++++++++++++++++ cmd/usb_mass_storage.c | 2 +- common/autoboot.c | 17 +++++++ common/board_r.c | 1 + include/common.h | 1 + 6 files changed, 104 insertions(+), 1 deletion(-) diff --git a/arch/arm/include/asm/arch-rockchip/gpio.h b/arch/arm/include/asm/arch-rockchip/gpio.h index e39218d0a9..10f4f41e67 100644 --- a/arch/arm/include/asm/arch-rockchip/gpio.h +++ b/arch/arm/include/asm/arch-rockchip/gpio.h @@ -25,4 +25,26 @@ struct rockchip_gpio_regs { }; check_member(rockchip_gpio_regs, ls_sync, 0x60); +/* + * RK3288 IO memory map: + * + */ +#define RKIO_GPIO0_PHYS 0xFF750000 +#define RKIO_GRF_PHYS 0xFF770000 +#define RKIO_GPIO1_PHYS 0xFF780000 +#define RKIO_GPIO2_PHYS 0xFF790000 +#define RKIO_GPIO3_PHYS 0xFF7A0000 +#define RKIO_GPIO4_PHYS 0xFF7B0000 +#define RKIO_GPIO5_PHYS 0xFF7C0000 +#define RKIO_GPIO6_PHYS 0xFF7D0000 + +/* gpio power down/up control */ +#define GRF_GPIO2A_P 0x150 +#define GRF_GPIO6A_P 0x190 + +/* gpio input/output control */ +#define GPIO_SWPORT_DR 0x00 +#define GPIO_SWPORT_DDR 0x04 +#define GPIO_EXT_PORT 0x50 + #endif diff --git a/arch/arm/mach-rockchip/rk3288-board.c b/arch/arm/mach-rockchip/rk3288-board.c index f1569e62b6..32f70a5920 100644 --- a/arch/arm/mach-rockchip/rk3288-board.c +++ b/arch/arm/mach-rockchip/rk3288-board.c @@ -22,6 +22,19 @@ DECLARE_GLOBAL_DATA_PTR; +enum project_id { + TinkerBoardS = 0, + TinkerBoard = 7, +}; + +enum pcb_id { + SR, + ER, + PR, +}; + +extern bool force_ums; + __weak int rk_board_late_init(void) { return 0; @@ -91,6 +104,55 @@ int board_late_init(void) return rk_board_late_init(); } +int check_force_enter_ums_mode(void) +{ + int tmp; + enum pcb_id pcbid; + enum project_id projectid; + + // GPIO2_A1/GPIO2_A2/GPIO2_A3 pull up enable + // please check TRM V1.2 part1 page 152 + tmp = readl(RKIO_GRF_PHYS + GRF_GPIO2A_P); + writel((tmp&~(0x03F<<2)) | 0x3F<<(16 + 2) | 0x15<<2, RKIO_GRF_PHYS + GRF_GPIO2A_P); + + // GPIO2_A1/GPIO2_A2/GPIO2_A3/GPIO2_B0/GPIO2_B1/GPIO2_B2 set to input + tmp = readl(RKIO_GPIO2_PHYS + GPIO_SWPORT_DDR); + writel(tmp & ~(0x70E), RKIO_GPIO2_PHYS + GPIO_SWPORT_DDR); + + // GPIO6_A5 pull up/down disable + tmp = readl(RKIO_GRF_PHYS + GRF_GPIO6A_P); + writel((tmp&~(0x03<<10)) | 0x03<<(16 + 10), RKIO_GRF_PHYS + GRF_GPIO6A_P); + + // GPIO6_A5 set to input + tmp = readl(RKIO_GPIO6_PHYS + GPIO_SWPORT_DDR); + writel(tmp & ~(0x20), RKIO_GPIO6_PHYS + GPIO_SWPORT_DDR); + + mdelay(10); + + // read GPIO2_A1/GPIO2_A2/GPIO2_A3 value + projectid = (readl(RKIO_GPIO2_PHYS + GPIO_EXT_PORT) & 0x0E) >>1; + + // read GPIO2_B0/GPIO2_B1/GPIO2_B2 value + pcbid = (readl(RKIO_GPIO2_PHYS + GPIO_EXT_PORT) & 0x700) >> 8; + + // only Tinker Board S and the PR stage PCB has this function + if(projectid!=TinkerBoard && pcbid >= ER){ + printf("PC event = 0x%x\n", readl(RKIO_GPIO6_PHYS + GPIO_EXT_PORT)&0x20); + if((readl(RKIO_GPIO6_PHYS + GPIO_EXT_PORT)&0x20)==0x20) { + // SDP detected, enable EMMC and unlock usb current limit + printf("usb connected to SDP, force enter ums mode\n"); + force_ums = true; + // unlock usb current limit and re-enable EMMC + // set GPIO6_A6, GPIO6_A7 to high + tmp = readl(RKIO_GPIO6_PHYS + GPIO_SWPORT_DR); + writel(tmp | 0xc0, RKIO_GPIO6_PHYS + GPIO_SWPORT_DR); + tmp = readl(RKIO_GPIO6_PHYS + GPIO_SWPORT_DDR); + writel(tmp | 0xc0, RKIO_GPIO6_PHYS + GPIO_SWPORT_DDR); + } + } + return 0; +} + #if !CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) static int veyron_init(void) { diff --git a/cmd/usb_mass_storage.c b/cmd/usb_mass_storage.c index 3353f95c74..cb5260b558 100644 --- a/cmd/usb_mass_storage.c +++ b/cmd/usb_mass_storage.c @@ -133,7 +133,7 @@ cleanup: return ret; } -static int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag, +int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { const char *usb_controller; diff --git a/common/autoboot.c b/common/autoboot.c index c52bad84a4..d63a4d7e79 100644 --- a/common/autoboot.c +++ b/common/autoboot.c @@ -28,6 +28,8 @@ DECLARE_GLOBAL_DATA_PTR; /* Stored value of bootdelay, used by autoboot_command() */ static int stored_bootdelay; +bool force_ums = false; + #if defined(CONFIG_AUTOBOOT_KEYED) #if defined(CONFIG_AUTOBOOT_STOP_STR_SHA256) @@ -339,10 +341,25 @@ const char *bootdelay_process(void) return s; } +extern int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); + void autoboot_command(const char *s) { debug("### main_loop: bootcmd=\"%s\"\n", s ? s : ""); + if (force_ums) { + // force to enter ums mode + char *local_args[4]; + char str1[]="ums", str2[]="1", str3[]="mmc", str4[]="0"; + + local_args[0]=str1; + local_args[1]=str2; + local_args[2]=str3; + local_args[3]=str4; + do_usb_mass_storage(NULL, 0, 4, local_args); + return; + } + if (stored_bootdelay != -1 && s && !abortboot(stored_bootdelay)) { #if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC) int prev = disable_ctrlc(1); /* disable Control C checking */ diff --git a/common/board_r.c b/common/board_r.c index ecca1edb04..77b3a05693 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -800,6 +800,7 @@ static init_fnc_t init_sequence_r[] = { #ifdef CONFIG_CMD_ONENAND initr_onenand, #endif + check_force_enter_ums_mode, #ifdef CONFIG_MMC initr_mmc, #endif diff --git a/include/common.h b/include/common.h index 751665f8a4..13a6e563c3 100644 --- a/include/common.h +++ b/include/common.h @@ -418,6 +418,7 @@ extern ssize_t spi_write (uchar *, int, uchar *, int); int board_early_init_f (void); int board_fix_fdt (void *rw_fdt_blob); /* manipulate the U-Boot fdt before its relocation */ int board_late_init (void); +int check_force_enter_ums_mode (void); int board_postclk_init (void); /* after clocks/timebase, before env/serial */ int board_early_init_r (void); void board_poweroff (void); -- 2.17.1