From: Spencer O. <nt...@us...> - 2010-07-19 17:21:37
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 4611f87f0aeba42d21fc6c197e904a0c97731bf7 (commit) via 0345667642e13ef2c78dc904677541d2b935d831 (commit) via 8f5e84bf8dabfddc6b853c522fdc29be90c93746 (commit) via d249057adfeb3f652df86ad321577744910b6e21 (commit) from 20c1d4cc9a2ce8864b59ef6414f9cf5649b9f046 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4611f87f0aeba42d21fc6c197e904a0c97731bf7 Author: Spencer Oliver <nt...@us...> Date: Mon Jul 19 12:22:18 2010 +0100 flash: add nuc910 nand driver This adds a nand driver support for the nuc910 target. Note that ECC is not currently supported by this driver, although it is supported by the peripheral. Signed-off-by: Spencer Oliver <nt...@us...> diff --git a/src/flash/nand/Makefile.am b/src/flash/nand/Makefile.am index 259a9cb..8ea7b36 100644 --- a/src/flash/nand/Makefile.am +++ b/src/flash/nand/Makefile.am @@ -27,7 +27,8 @@ NAND_DRIVERS = \ s3c2440.c \ s3c2443.c \ s3c6400.c \ - at91sam9.c + at91sam9.c \ + nuc910.c noinst_HEADERS = \ arm_io.h \ @@ -39,6 +40,7 @@ noinst_HEADERS = \ mx2.h \ mx3.h \ s3c24xx.h \ - s3c24xx_regs.h + s3c24xx_regs.h \ + nuc910.h MAINTAINERCLEANFILES = $(srcdir)/Makefile.in diff --git a/src/flash/nand/driver.c b/src/flash/nand/driver.c index 597d78a..522dfa4 100644 --- a/src/flash/nand/driver.c +++ b/src/flash/nand/driver.c @@ -40,6 +40,7 @@ extern struct nand_flash_controller s3c6400_nand_controller; extern struct nand_flash_controller imx27_nand_flash_controller; extern struct nand_flash_controller imx31_nand_flash_controller; extern struct nand_flash_controller at91sam9_nand_controller; +extern struct nand_flash_controller nuc910_nand_controller; /* extern struct nand_flash_controller boundary_scan_nand_controller; */ @@ -57,6 +58,7 @@ static struct nand_flash_controller *nand_flash_controllers[] = &imx27_nand_flash_controller, &imx31_nand_flash_controller, &at91sam9_nand_controller, + &nuc910_nand_controller, /* &boundary_scan_nand_controller, */ NULL }; diff --git a/src/flash/nand/nuc910.c b/src/flash/nand/nuc910.c new file mode 100644 index 0000000..26d377f --- /dev/null +++ b/src/flash/nand/nuc910.c @@ -0,0 +1,240 @@ +/*************************************************************************** + * Copyright (C) 2010 by Spencer Oliver * + * sp...@sp... * + * * + * 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. * + ***************************************************************************/ + +/* + * NAND controller interface for Nuvoton NUC910 + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "imp.h" +#include "nuc910.h" +#include "arm_io.h" +#include <target/arm.h> + +struct nuc910_nand_controller +{ + struct target *target; + struct arm_nand_data io; +}; + +static int validate_target_state(struct nand_device *nand) +{ + struct nuc910_nand_controller *nuc910_nand = nand->controller_priv; + struct target *target = nuc910_nand->target; + + if (target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); + return ERROR_NAND_OPERATION_FAILED; + } + + return ERROR_OK; +} + +static int nuc910_nand_command(struct nand_device *nand, uint8_t command) +{ + struct nuc910_nand_controller *nuc910_nand = nand->controller_priv; + struct target *target = nuc910_nand->target; + int result; + + if ((result = validate_target_state(nand)) != ERROR_OK) + return result; + + target_write_u8(target, NUC910_SMCMD, command); + return ERROR_OK; +} + +static int nuc910_nand_address(struct nand_device *nand, uint8_t address) +{ + struct nuc910_nand_controller *nuc910_nand = nand->controller_priv; + struct target *target = nuc910_nand->target; + int result; + + if ((result = validate_target_state(nand)) != ERROR_OK) + return result; + + target_write_u32(target, NUC910_SMADDR, ((address & 0xff) | NUC910_SMADDR_EOA)); + return ERROR_OK; +} + +static int nuc910_nand_read(struct nand_device *nand, void *data) +{ + struct nuc910_nand_controller *nuc910_nand = nand->controller_priv; + struct target *target = nuc910_nand->target; + int result; + + if ((result = validate_target_state(nand)) != ERROR_OK) + return result; + + target_read_u8(target, NUC910_SMDATA, data); + return ERROR_OK; +} + +static int nuc910_nand_write(struct nand_device *nand, uint16_t data) +{ + struct nuc910_nand_controller *nuc910_nand = nand->controller_priv; + struct target *target = nuc910_nand->target; + int result; + + if ((result = validate_target_state(nand)) != ERROR_OK) + return result; + + target_write_u8(target, NUC910_SMDATA, data); + return ERROR_OK; +} + +static int nuc910_nand_read_block_data(struct nand_device *nand, + uint8_t *data, int data_size) +{ + struct nuc910_nand_controller *nuc910_nand = nand->controller_priv; + int result; + + if ((result = validate_target_state(nand)) != ERROR_OK) + return result; + + nuc910_nand->io.chunk_size = nand->page_size; + + /* try the fast way first */ + result = arm_nandread(&nuc910_nand->io, data, data_size); + if (result != ERROR_NAND_NO_BUFFER) + return result; + + /* else do it slowly */ + while (data_size--) + nuc910_nand_read(nand, data++); + + return ERROR_OK; +} + +static int nuc910_nand_write_block_data(struct nand_device *nand, + uint8_t *data, int data_size) +{ + struct nuc910_nand_controller *nuc910_nand = nand->controller_priv; + int result; + + if ((result = validate_target_state(nand)) != ERROR_OK) + return result; + + nuc910_nand->io.chunk_size = nand->page_size; + + /* try the fast way first */ + result = arm_nandwrite(&nuc910_nand->io, data, data_size); + if (result != ERROR_NAND_NO_BUFFER) + return result; + + /* else do it slowly */ + while (data_size--) + nuc910_nand_write(nand, *data++); + + return ERROR_OK; +} + +static int nuc910_nand_reset(struct nand_device *nand) +{ + return nuc910_nand_command(nand, NAND_CMD_RESET); +} + +static int nuc910_nand_ready(struct nand_device *nand, int timeout) +{ + struct nuc910_nand_controller *nuc910_nand = nand->controller_priv; + struct target *target = nuc910_nand->target; + uint32_t status; + + do { + target_read_u32(target, NUC910_SMISR, &status); + if (status & NUC910_SMISR_RB_) { + return 1; + } + alive_sleep(1); + } while (timeout-- > 0); + + return 0; +} + +NAND_DEVICE_COMMAND_HANDLER(nuc910_nand_device_command) +{ + struct nuc910_nand_controller *nuc910_nand; + + nuc910_nand = calloc(1, sizeof(struct nuc910_nand_controller)); + if (!nuc910_nand) { + LOG_ERROR("no memory for nand controller\n"); + return ERROR_NAND_DEVICE_INVALID; + } + + nand->controller_priv = nuc910_nand; + nuc910_nand->target = get_target(CMD_ARGV[1]); + if (!nuc910_nand->target) { + LOG_ERROR("target '%s' not defined", CMD_ARGV[1]); + free(nuc910_nand); + return ERROR_NAND_DEVICE_INVALID; + } + + return ERROR_OK; +} + +static int nuc910_nand_init(struct nand_device *nand) +{ + struct nuc910_nand_controller *nuc910_nand = nand->controller_priv; + struct target *target = nuc910_nand->target; + int bus_width = nand->bus_width ? : 8; + int result; + + if ((result = validate_target_state(nand)) != ERROR_OK) + return result; + + /* nuc910 only supports 8bit */ + if (bus_width != 8) + { + LOG_ERROR("nuc910 only supports 8 bit bus width, not %i", bus_width); + return ERROR_NAND_OPERATION_NOT_SUPPORTED; + } + + /* inform calling code about selected bus width */ + nand->bus_width = bus_width; + + nuc910_nand->io.target = target; + nuc910_nand->io.data = NUC910_SMDATA; + nuc910_nand->io.op = ARM_NAND_NONE; + + /* configure nand controller */ + target_write_u32(target, NUC910_FMICSR, NUC910_FMICSR_SM_EN); + target_write_u32(target, NUC910_SMCSR, 0x010000a8); /* 2048 page size */ + target_write_u32(target, NUC910_SMTCR, 0x00010204); + target_write_u32(target, NUC910_SMIER, 0x00000000); + + return ERROR_OK; +} + +struct nand_flash_controller nuc910_nand_controller = +{ + .name = "nuc910", + .command = nuc910_nand_command, + .address = nuc910_nand_address, + .read_data = nuc910_nand_read, + .write_data = nuc910_nand_write, + .write_block_data = nuc910_nand_write_block_data, + .read_block_data = nuc910_nand_read_block_data, + .nand_ready = nuc910_nand_ready, + .reset = nuc910_nand_reset, + .nand_device_command = nuc910_nand_device_command, + .init = nuc910_nand_init, +}; diff --git a/src/flash/nand/nuc910.h b/src/flash/nand/nuc910.h new file mode 100644 index 0000000..644502f --- /dev/null +++ b/src/flash/nand/nuc910.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (C) 2010 by Spencer Oliver * + * sp...@sp... * + * * + * 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. * + ***************************************************************************/ + +/* + * NAND controller interface for Nuvoton NUC910 + */ + +#ifndef NUC910_H +#define NUC910_H + +#define NUC910_FMICSR 0xB000D000 +#define NUC910_SMCSR 0xB000D0A0 +#define NUC910_SMTCR 0xB000D0A4 +#define NUC910_SMIER 0xB000D0A8 +#define NUC910_SMISR 0xB000D0AC +#define NUC910_SMCMD 0xB000D0B0 +#define NUC910_SMADDR 0xB000D0B4 +#define NUC910_SMDATA 0xB000D0B8 + +#define NUC910_SMECC0 0xB000D0BC +#define NUC910_SMECC1 0xB000D0C0 +#define NUC910_SMECC2 0xB000D0C4 +#define NUC910_SMECC3 0xB000D0C8 +#define NUC910_ECC4ST 0xB000D114 + +/* Global Control and Status Register (FMICSR) */ +#define NUC910_FMICSR_SM_EN (1<<3) + +/* NAND Flash Address Port Register (SMADDR) */ +#define NUC910_SMADDR_EOA (1<<31) + +/* NAND Flash Control and Status Register (SMCSR) */ +#define NUC910_SMCSR_PSIZE (1<<3) +#define NUC910_SMCSR_DBW (1<<4) + +/* NAND Flash Interrupt Status Register (SMISR) */ +#define NUC910_SMISR_ECC_IF (1<<2) +#define NUC910_SMISR_RB_ (1<<18) + +/* ECC4 Correction Status (ECC4ST) */ + +#endif /* NUC910_H */ + diff --git a/tcl/board/rsc-w910.cfg b/tcl/board/rsc-w910.cfg index eba44f6..423fb8f 100644 --- a/tcl/board/rsc-w910.cfg +++ b/tcl/board/rsc-w910.cfg @@ -21,6 +21,9 @@ $_TARGETNAME configure -work-area-phys 0x00000000 -work-area-size 0x04000000 -wo set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME cfi 0x20000000 0x00200000 2 2 $_TARGETNAME +set _NANDNAME $_CHIPNAME.nand +nand device $_NANDNAME nuc910 $_TARGETNAME + # # Target events # commit 0345667642e13ef2c78dc904677541d2b935d831 Author: Spencer Oliver <nt...@us...> Date: Fri Jul 16 17:01:32 2010 +0100 nand: nand probe also outputs manufacturer The nand probe now outputs the manufacturer if found. Signed-off-by: Spencer Oliver <nt...@us...> diff --git a/src/flash/nand/tcl.c b/src/flash/nand/tcl.c index 592277e..7b84888 100644 --- a/src/flash/nand/tcl.c +++ b/src/flash/nand/tcl.c @@ -147,7 +147,8 @@ COMMAND_HANDLER(handle_nand_probe_command) if ((retval = nand_probe(p)) == ERROR_OK) { - command_print(CMD_CTX, "NAND flash device '%s' found", p->device->name); + command_print(CMD_CTX, "NAND flash device '%s (%s)' found", + p->device->name, p->manufacturer->name); } else if (retval == ERROR_NAND_OPERATION_FAILED) { commit 8f5e84bf8dabfddc6b853c522fdc29be90c93746 Author: Spencer Oliver <nt...@us...> Date: Fri Jul 16 16:59:35 2010 +0100 cfg: update rsc-w910 script - Only enable the FMI (NAND) and DMA clocks. - Select NAND interface on the MFSEL. Signed-off-by: Spencer Oliver <nt...@us...> diff --git a/tcl/board/rsc-w910.cfg b/tcl/board/rsc-w910.cfg index f7095a6..eba44f6 100644 --- a/tcl/board/rsc-w910.cfg +++ b/tcl/board/rsc-w910.cfg @@ -31,11 +31,12 @@ $_TARGETNAME configure -event reset-init { # switch on PLL for 200MHz operation # running from 15MHz input clock - mww 0xB0000200 0x45180bb1 # CLKEN + mww 0xB0000200 0x00000030 # CLKEN mww 0xB0000204 0x00000f3c # CLKSEL mww 0xB0000208 0x05007000 # CLKDIV mww 0xB000020C 0x00004f24 # PLLCON0 mww 0xB0000210 0x00002b63 # PLLCON1 + mww 0xB000000C 0x08817fa6 # MFSEL sleep 10 # we are now running @ 200MHz commit d249057adfeb3f652df86ad321577744910b6e21 Author: Spencer Oliver <nt...@us...> Date: Fri Jul 16 16:56:41 2010 +0100 docs: missing parameter from nand check_bad_blocks Signed-off-by: Spencer Oliver <nt...@us...> diff --git a/doc/openocd.texi b/doc/openocd.texi index 8f47cd1..08578fa 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -5160,7 +5160,7 @@ be removed in a future release. @section Other NAND commands @cindex NAND other commands -@deffn Command {nand check_bad_blocks} [offset length] +@deffn Command {nand check_bad_blocks} num [offset length] Checks for manufacturer bad block markers on the specified NAND device. If no parameters are provided, checks the whole device; otherwise, starts at the specified @var{offset} and ----------------------------------------------------------------------- Summary of changes: doc/openocd.texi | 2 +- src/flash/nand/Makefile.am | 6 +- src/flash/nand/driver.c | 2 + src/flash/nand/nuc910.c | 240 ++++++++++++++++++++ .../libdcc/example.c => src/flash/nand/nuc910.h | 80 ++++---- src/flash/nand/tcl.c | 3 +- tcl/board/rsc-w910.cfg | 6 +- 7 files changed, 295 insertions(+), 44 deletions(-) create mode 100644 src/flash/nand/nuc910.c copy contrib/libdcc/example.c => src/flash/nand/nuc910.h (57%) hooks/post-receive -- Main OpenOCD repository |