From mboxrd@z Thu Jan 1 00:00:00 1970 From: Troy Kisky Date: Thu, 09 Aug 2012 11:48:09 -0700 Subject: [U-Boot] [PATCH V3 1/3] imx-common/cmd_resetmode.c: add imx resetmode command In-Reply-To: <502364FD.6020408@denx.de> References: <1344475594-10630-1-git-send-email-troy.kisky@boundarydevices.com> <502364FD.6020408@denx.de> Message-ID: <502405E9.7010207@boundarydevices.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de On 8/9/2012 12:21 AM, Stefano Babic wrote: > On 09/08/2012 03:26, Troy Kisky wrote: >> This is useful for forcing the ROM's >> usb downloader to activate upon a watchdog reset. >> Or, you can boot from either SD Card. >> > Hi Troy, > >> Currently, support added for MX53 and MX6Q >> Signed-off-by: Troy Kisky >> >> Note: MX53 support untested. > It can help me to understand your implementation if I can find in the > documentation where this feature is implemented. I started wit MX53 and > well, in the manual I see only that LPGR is a "general purpose register" > and contains "user specific data". > > Maybe I am searching in wrong places. Where can I find the description > for the feature you have implemented ? The only documentations I've found are in the freescale release of u-boot. cpu/arm_cortexa8/mx53/generic.c void do_switch_mfgmode(void) { u32 reg; reg = readl(SRTC_BASE_ADDR + SRTC_LPGR); /* After set bit 28 of LPGR register of SRTC to 1, Set bit * [25:0] to specified value according to format of SBMR, * after trigger a watchdog reset, ROM will read Bit 28 and * then copy bit [25:0] of LPGR to SBMR, then ROM can enter * serial download mode.*/ reg |= 0x12000000; writel(reg, SRTC_BASE_ADDR + SRTC_LPGR); /* this watchdog reset will let chip enter mfgtool download * mode. */ do_reset(NULL, 0, 0, NULL); } U_BOOT_CMD( download_mode, 1, 1, do_switch_mfgmode, "download_mode - enter i.MX serial/usb download mode\n", ""); and for mx6q by disassembling iMX6DQ_SPI_to_uSDHC3.bin and iMX6DQ_SPI_to_uSDHC4.bin > >> diff --git a/arch/arm/cpu/armv7/imx-common/Makefile b/arch/arm/cpu/armv7/imx-common/Makefile >> index bf36be5..24f490e 100644 >> --- a/arch/arm/cpu/armv7/imx-common/Makefile >> +++ b/arch/arm/cpu/armv7/imx-common/Makefile >> @@ -29,6 +29,7 @@ LIB = $(obj)libimx-common.o >> >> COBJS-y = iomux-v3.o timer.o cpu.o speed.o >> COBJS-$(CONFIG_I2C_MXC) += i2c.o >> +COBJS-$(CONFIG_CMD_RESETMODE) += cmd_resetmode.o >> COBJS := $(sort $(COBJS-y)) >> >> SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) >> 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"); >> +} > Why do you not pass the mode to do_resetmode_cmd() and let this function > parse the argument, without these help functions ? Then we do not need > to add new functions if we have, for example, mmc2 or mmc3. These functions are requested shortcuts. "bootmmc0" is the same as "resetmode mmc0 && reset" > > Best regards, > Stefano Babic >