From patchwork Thu Jun 14 01:01:53 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Troy Kisky X-Patchwork-Id: 164779 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id D30DAB7008 for ; Thu, 14 Jun 2012 11:01:45 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id A070428139; Thu, 14 Jun 2012 03:01:42 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Ar3kGUwTEA3m; Thu, 14 Jun 2012 03:01:42 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 84ABE28131; Thu, 14 Jun 2012 03:01:41 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 3B7F228131 for ; Thu, 14 Jun 2012 03:01:40 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id WFzf+hBNEcOx for ; Thu, 14 Jun 2012 03:01:38 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-pz0-f44.google.com (mail-pz0-f44.google.com [209.85.210.44]) by theia.denx.de (Postfix) with ESMTPS id 479EE2812E for ; Thu, 14 Jun 2012 03:01:36 +0200 (CEST) Received: by dacx6 with SMTP id x6so1629794dac.3 for ; Wed, 13 Jun 2012 18:01:35 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:x-gm-message-state; bh=0Kr8YVC+iY0mANsEMyzVkSSzHDBCOfcbk05DCIojHQM=; b=QULNgVHBq6rOzzFHIBmhkdgOhnJ6Vzhqt2SaDHdzMIKW94Pf5cNb3CmMZ0GC0hQ0nG v2A6vttvbE/v9s5uwhmlZ8BYz+9lHtzKg9mqpy5g5hI/rxSATQ4Pn38plAlmz1WZgZGa SktiiYgBgCns1kyAt+cCmemiMbg6rk1zDBZSDj7GaTroNq7ENBfovAnWyYFZ7Tw9WuY3 emHagj7+DGSy5Fa+BFu3oxM9S6zFWF63v8EXHrECwVw2HS/D8JyzVheLcxye+h3jGKNS WyH6SO8wRakTGQp1xOSI1YqJjgiasLjmRkOK/vAhpnDb9lruEUwxHeYFwCPEkxT2nbhU LWPQ== Received: by 10.68.130.67 with SMTP id oc3mr1759755pbb.18.1339635694915; Wed, 13 Jun 2012 18:01:34 -0700 (PDT) Received: from officeserver-2 ([70.96.116.236]) by mx.google.com with ESMTPS id io2sm7543920pbc.24.2012.06.13.18.01.33 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 13 Jun 2012 18:01:34 -0700 (PDT) Received: from tkisky by officeserver-2 with local (Exim 4.76) (envelope-from ) id 1SeyRf-0000I8-KK; Wed, 13 Jun 2012 18:01:55 -0700 From: Troy Kisky To: sbabic@denx.de Date: Wed, 13 Jun 2012 18:01:53 -0700 Message-Id: <1339635713-1088-1-git-send-email-troy.kisky@boundarydevices.com> X-Mailer: git-send-email 1.7.5.4 X-Gm-Message-State: ALoCoQn4PmOmTEYLAVh4ofdNvFVJp4V4yPaCPRA8F/JYuUucxM1qaYXb4H9rGTRoGm10CMwqRdsJ Cc: u-boot@lists.denx.de Subject: [U-Boot] [RFC v2 1/3] imx-common/cmd_resetmode.c: add imx resetmode command X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de This is useful for forcing the ROM's usb downloader to activate upon a watchdog reset. Or, you can boot from either SD Card. Currently, support added for MX53 and MX6Q Signed-off-by: Troy Kisky Note: MX53 support untested. --- arch/arm/cpu/armv7/imx-common/Makefile | 4 +- arch/arm/cpu/armv7/imx-common/cmd_resetmode.c | 152 +++++++++++++++++++++++++ arch/arm/cpu/armv7/mx5/soc.c | 31 +++++ arch/arm/cpu/armv7/mx6/soc.c | 36 ++++++ arch/arm/include/asm/arch-mx5/imx-regs.h | 18 +++ arch/arm/include/asm/arch-mx6/imx-regs.h | 21 ++++ arch/arm/include/asm/imx-common/resetmode.h | 36 ++++++ 7 files changed, 297 insertions(+), 1 deletions(-) create mode 100644 arch/arm/cpu/armv7/imx-common/cmd_resetmode.c create mode 100644 arch/arm/include/asm/imx-common/resetmode.h diff --git a/arch/arm/cpu/armv7/imx-common/Makefile b/arch/arm/cpu/armv7/imx-common/Makefile index e5ff375..aed8262 100644 --- a/arch/arm/cpu/armv7/imx-common/Makefile +++ b/arch/arm/cpu/armv7/imx-common/Makefile @@ -27,7 +27,9 @@ include $(TOPDIR)/config.mk LIB = $(obj)libimx-common.o -COBJS = timer.o cpu.o speed.o +COBJS-y = timer.o cpu.o speed.o +COBJS-$(CONFIG_CMD_RESETMODE) += cmd_resetmode.o +COBJS := $(sort $(COBJS-y)) SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/arch/arm/cpu/armv7/imx-common/cmd_resetmode.c b/arch/arm/cpu/armv7/imx-common/cmd_resetmode.c new file mode 100644 index 0000000..d1c50e1 --- /dev/null +++ b/arch/arm/cpu/armv7/imx-common/cmd_resetmode.c @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2012 Boundary Devices Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include +#include +#include +#include +#include + +const struct reset_mode *modes[2]; + +const struct reset_mode *search_modes(char *arg) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(modes); i++) { + const struct reset_mode *p = modes[i]; + if (p) { + while (p->name) { + if (!strcmp(p->name, arg)) + return p; + p++; + } + } + } + return NULL; +} + +int create_usage(char *dest) +{ + int i; + int size = 0; + + for (i = 0; i < ARRAY_SIZE(modes); i++) { + const struct reset_mode *p = modes[i]; + if (p) { + while (p->name) { + int len = strlen(p->name); + if (dest) { + memcpy(dest, p->name, len); + dest += len; + *dest++ = '|'; + } + size += len + 1; + p++; + } + } + } + if (dest) + dest[-1] = 0; + return size; +} + +int do_resetmode(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + const struct reset_mode *p; + + if (argc < 2) + return CMD_RET_USAGE; + p = search_modes(argv[1]); + if (!p) + return CMD_RET_USAGE; + reset_mode_apply(p->cfg_val); + return 0; +} + +U_BOOT_CMD( + resetmode, 2, 0, do_resetmode, + NULL, + ""); + +void add_board_resetmodes(const struct reset_mode *p) +{ + int size; + char *dest; + + if (__u_boot_cmd_resetmode.usage) { + free(__u_boot_cmd_resetmode.usage); + __u_boot_cmd_resetmode.usage = NULL; + } + + modes[0] = p; + modes[1] = soc_reset_modes; + size = create_usage(NULL); + dest = malloc(size); + if (dest) { + create_usage(dest); + __u_boot_cmd_resetmode.usage = dest; + } +} + +int do_resetmode_cmd(char *arg) +{ + const struct reset_mode *p; + + p = search_modes(arg); + if (!p) { + printf("%s not found\n", arg); + return CMD_RET_FAILURE; + } + reset_mode_apply(p->cfg_val); + do_reset(NULL, 0, 0, NULL); + return 0; +} + +int do_bootmmc0(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + return do_resetmode_cmd("mmc0"); +} + +int do_bootmmc1(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + return do_resetmode_cmd("mmc1"); +} + +int do_download_mode(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + return do_resetmode_cmd("usb"); +} + +U_BOOT_CMD( + bootmmc0, 1, 0, do_bootmmc0, + "boot to mmc 0", + ""); + +U_BOOT_CMD( + bootmmc1, 1, 0, do_bootmmc1, + "boot to mmc 1", + ""); + +U_BOOT_CMD( + download_mode, 1, 0, do_download_mode, + "start rom loader", + ""); diff --git a/arch/arm/cpu/armv7/mx5/soc.c b/arch/arm/cpu/armv7/mx5/soc.c index 3f5a4f7..9cd363b 100644 --- a/arch/arm/cpu/armv7/mx5/soc.c +++ b/arch/arm/cpu/armv7/mx5/soc.c @@ -30,6 +30,7 @@ #include #include +#include #if !(defined(CONFIG_MX51) || defined(CONFIG_MX53)) #error "CPU_TYPE not defined" @@ -115,3 +116,33 @@ void set_chipselect_size(int const cs_size) writel(reg, &iomuxc_regs->gpr1); } + +#ifdef CONFIG_MX53 +void reset_mode_apply(unsigned cfg_val) +{ + writel(cfg_val, &((struct srtc_regs *)SRTC_BASE_ADDR)->lpgr); +} +/* + * cfg_val will be used for + * Boot_cfg3[7:0]:Boot_cfg2[7:0]:Boot_cfg1[7:0] + * + * If bit 28 of LPGR is set upon watchdog reset, + * bits[25:0] of LPGR will move to SBMR. + */ +const struct reset_mode soc_reset_modes[] = { + {"normal", MAKE_CFGVAL(0x00, 0x00, 0x00, 0x00)}, + /* usb or serial download */ + {"usb", MAKE_CFGVAL(0x00, 0x00, 0x00, 0x13)}, + {"sata", MAKE_CFGVAL(0x28, 0x00, 0x00, 0x12)}, + {"escpi1:0", MAKE_CFGVAL(0x38, 0x20, 0x00, 0x12)}, + {"escpi1:1", MAKE_CFGVAL(0x38, 0x20, 0x04, 0x12)}, + {"escpi1:2", MAKE_CFGVAL(0x38, 0x20, 0x08, 0x12)}, + {"escpi1:3", MAKE_CFGVAL(0x38, 0x20, 0x0c, 0x12)}, + /* 4 bit bus width */ + {"esdhc1", MAKE_CFGVAL(0x40, 0x20, 0x00, 0x12)}, + {"esdhc2", MAKE_CFGVAL(0x40, 0x20, 0x08, 0x12)}, + {"esdhc3", MAKE_CFGVAL(0x40, 0x20, 0x10, 0x12)}, + {"esdhc4", MAKE_CFGVAL(0x40, 0x20, 0x18, 0x12)}, + {NULL, 0}, +}; +#endif diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c index 90f2088..5d94492 100644 --- a/arch/arm/cpu/armv7/mx6/soc.c +++ b/arch/arm/cpu/armv7/mx6/soc.c @@ -29,6 +29,7 @@ #include #include #include +#include u32 get_cpu_rev(void) { @@ -143,3 +144,38 @@ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) } #endif + +void reset_mode_apply(unsigned cfg_val) +{ + unsigned reg; + struct src_regs *psrc = (struct src_regs *)SRC_BASE_ADDR; + writel(cfg_val, &psrc->gpr9); + reg = readl(&psrc->gpr10); + if (cfg_val) + reg |= 1 << 28; + else + reg &= ~(1 << 28); + writel(reg, &psrc->gpr10); +} +/* + * cfg_val will be used for + * Boot_cfg4[7:0]:Boot_cfg3[7:0]:Boot_cfg2[7:0]:Boot_cfg1[7:0] + * After reset, if GPR10[28] is 1, ROM will copy GPR9[25:0] + * to SBMR1, which will determine the boot device. + */ +const struct reset_mode soc_reset_modes[] = { + {"normal", MAKE_CFGVAL(0x00, 0x00, 0x00, 0x00)}, + /* reserved value should start rom usb */ + {"usb", MAKE_CFGVAL(0x01, 0x00, 0x00, 0x00)}, + {"sata", MAKE_CFGVAL(0x20, 0x00, 0x00, 0x00)}, + {"escpi1:0", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x08)}, + {"escpi1:1", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x18)}, + {"escpi1:2", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x28)}, + {"escpi1:3", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x38)}, + /* 4 bit bus width */ + {"esdhc1", MAKE_CFGVAL(0x40, 0x20, 0x00, 0x00)}, + {"esdhc2", MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)}, + {"esdhc3", MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)}, + {"esdhc4", MAKE_CFGVAL(0x40, 0x38, 0x00, 0x00)}, + {NULL, 0}, +}; diff --git a/arch/arm/include/asm/arch-mx5/imx-regs.h b/arch/arm/include/asm/arch-mx5/imx-regs.h index cef4190..4f27c00 100644 --- a/arch/arm/include/asm/arch-mx5/imx-regs.h +++ b/arch/arm/include/asm/arch-mx5/imx-regs.h @@ -456,6 +456,24 @@ struct src { u32 simr; }; +struct srtc_regs { + u32 lpscmr; /* 0x00 */ + u32 lpsclr; /* 0x04 */ + u32 lpsar; /* 0x08 */ + u32 lpsmcr; /* 0x0c */ + u32 lpcr; /* 0x10 */ + u32 lpsr; /* 0x14 */ + u32 lppdr; /* 0x18 */ + u32 lpgr; /* 0x1c */ + u32 hpcmr; /* 0x20 */ + u32 hpclr; /* 0x24 */ + u32 hpamr; /* 0x28 */ + u32 hpalr; /* 0x2c */ + u32 hpcr; /* 0x30 */ + u32 hpisr; /* 0x34 */ + u32 hpienr; /* 0x38 */ +}; + /* CSPI registers */ struct cspi_regs { u32 rxdata; diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h index e165810..5acc9ca 100644 --- a/arch/arm/include/asm/arch-mx6/imx-regs.h +++ b/arch/arm/include/asm/arch-mx6/imx-regs.h @@ -445,5 +445,26 @@ struct iomuxc_base_regs { u32 daisy[104]; /* 0x7b0..94c */ }; +struct src_regs { + u32 scr; /* 0x00 */ + u32 sbmr1; /* 0x04 */ + u32 srsr; /* 0x08 */ + u32 reserved1; /* 0x0c */ + u32 reserved2; /* 0x10 */ + u32 sisr; /* 0x14 */ + u32 simr; /* 0x18 */ + u32 sbmr2; /* 0x1c */ + u32 gpr1; /* 0x20 */ + u32 gpr2; /* 0x24 */ + u32 gpr3; /* 0x28 */ + u32 gpr4; /* 0x2c */ + u32 gpr5; /* 0x30 */ + u32 gpr6; /* 0x34 */ + u32 gpr7; /* 0x38 */ + u32 gpr8; /* 0x3c */ + u32 gpr9; /* 0x40 */ + u32 gpr10; /* 0x44 */ +}; + #endif /* __ASSEMBLER__*/ #endif /* __ASM_ARCH_MX6_IMX_REGS_H__ */ diff --git a/arch/arm/include/asm/imx-common/resetmode.h b/arch/arm/include/asm/imx-common/resetmode.h new file mode 100644 index 0000000..76216d0 --- /dev/null +++ b/arch/arm/include/asm/imx-common/resetmode.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2012 Boundary Devices Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _ASM_RESETMODE_H +#define _ASM_RESETMODE_H +#define MAKE_CFGVAL(cfg1, cfg2, cfg3, cfg4) \ + ((cfg4) << 24) | ((cfg3) << 16) | ((cfg2) << 8) | (cfg1) + +struct reset_mode { + const char *name; + unsigned cfg_val; +}; + +void add_board_resetmodes(const struct reset_mode *p); +void reset_mode_apply(unsigned cfg_val); +extern const struct reset_mode soc_reset_modes[]; +#endif