This is an automated email from Gerrit.

Adrien Destugues (pulkoma...@gmail.com) just uploaded a new patch set to 
Gerrit, which you can find at http://openocd.zylin.com/3734

-- gerrit

commit 3983859853b20d01ceae0a91d7f64d605de83376
Author: Adrien Destugues <pulkoma...@gmail.com>
Date:   Tue Sep 13 17:14:52 2016 +0200

    NAND: add command to get and set ONFI features
    
    The ONFI specification has GET_FEATURE and SET_FEATURE commands to get
    and set various parameters of NAND chips. This commit introduce a new
    command, "nand feature", to get and set those.
    
    This can be used to configure NAND chips in several ways. Some of the
    features are standardized, and other are manufacturer specific.
    
    Change-Id: I288130435f47b0fa6c0ce5f0a460cc4d4e524a48
    Signed-off-by: Adrien Destugues <pulkoma...@gmail.com>

diff --git a/doc/openocd.texi b/doc/openocd.texi
index 8146654..811e3ef 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -6413,6 +6413,15 @@ bypassing hardware ECC logic.
 with the wrong ECC data can cause them to be marked as bad.
 @end deffn
 
+@deffn Command {nand feature} num address [value]
+Manage NAND chip features
+
+If a value is given, set the feature at address to the given value.
+
+If no value is given, get the current value of the requested feature.
+
+@end deffn
+
 @anchor{nanddriverlist}
 @subsection NAND Driver List
 As noted above, the @command{nand device} command allows
diff --git a/src/flash/nand/core.c b/src/flash/nand/core.c
index 7428d22..8471388 100644
--- a/src/flash/nand/core.c
+++ b/src/flash/nand/core.c
@@ -298,6 +298,83 @@ static int nand_poll_ready(struct nand_device *nand, int 
timeout)
        return (status & NAND_STATUS_READY) != 0;
 }
 
+int nand_get_feature(struct nand_device *nand, uint8_t feature, uint32_t* 
value)
+{
+       int retval;
+       uint8_t byte;
+       int i;
+
+       if (!nand->device)
+               return ERROR_NAND_DEVICE_NOT_PROBED;
+
+
+       /* Send "get feature" command */
+       nand->controller->command(nand, NAND_CMD_GET_FEATURE);
+
+       /* Send feature address */
+       nand->controller->address(nand, feature);
+
+       alive_sleep(1);
+
+       retval = nand->controller->nand_ready ?
+               nand->controller->nand_ready(nand, 1000) : ERROR_OK;
+       if (!retval) {
+               LOG_ERROR("timeout waiting for NAND flash feature get to 
complete");
+               return ERROR_NAND_OPERATION_TIMEOUT;
+       }
+
+       alive_sleep(1);
+
+       retval = ERROR_OK;
+       for (i = 0; retval == ERROR_OK && i < 4; i++)
+       {
+               retval = nand->controller->read_data(nand, &byte);
+               if (value != NULL)
+               {
+                       *value = (*value >> 8) | (((uint32_t)byte) << 24);
+               }
+       }
+
+       return ERROR_OK;
+}
+
+int nand_set_feature(struct nand_device *nand, uint8_t feature, uint32_t value)
+{
+       int retval;
+       int i;
+
+       if (!nand->device)
+               return ERROR_NAND_DEVICE_NOT_PROBED;
+
+
+       /* Send "get feature" command */
+       nand->controller->command(nand, NAND_CMD_SET_FEATURE);
+
+       /* Send feature address */
+       nand->controller->address(nand, feature);
+
+       alive_sleep(1);
+
+       retval = ERROR_OK;
+       for (i = 0; retval == ERROR_OK && i < 4; i++)
+       {
+               retval = nand->controller->write_data(nand, value & 0xFF);
+               value >>= 8;
+       }
+
+       alive_sleep(1);
+
+       retval = nand->controller->nand_ready ?
+               nand->controller->nand_ready(nand, 1000) :
+               nand_poll_ready(nand, 1000);
+       if (!retval) {
+               LOG_ERROR("timeout waiting for NAND flash feature set to 
complete");
+               return ERROR_NAND_OPERATION_TIMEOUT;
+       }
+
+       return ERROR_OK;
+}
+
 int nand_probe(struct nand_device *nand)
 {
        uint8_t manufacturer_id, device_id;
diff --git a/src/flash/nand/core.h b/src/flash/nand/core.h
index 5bf9fb3..d542e36 100644
--- a/src/flash/nand/core.h
+++ b/src/flash/nand/core.h
@@ -160,6 +160,8 @@ enum {
        NAND_CMD_RNDIN = 0x85,
        NAND_CMD_READID = 0x90,
        NAND_CMD_ERASE2 = 0xd0,
+       NAND_CMD_GET_FEATURE = 0xee,
+       NAND_CMD_SET_FEATURE = 0xef,
        NAND_CMD_RESET = 0xff,
 
        /* Extended commands for large page devices */
@@ -209,6 +211,9 @@ int nand_write_page_raw(struct nand_device *nand, uint32_t 
page,
 
 int nand_read_status(struct nand_device *nand, uint8_t *status);
 
+int nand_get_feature(struct nand_device *nand, uint8_t feature, uint32_t* 
value);
+int nand_set_feature(struct nand_device *nand, uint8_t feature, uint32_t 
value);
+
 int nand_calculate_ecc(struct nand_device *nand,
                       const uint8_t *dat, uint8_t *ecc_code);
 int nand_calculate_ecc_kw(struct nand_device *nand,
diff --git a/src/flash/nand/tcl.c b/src/flash/nand/tcl.c
index cbdeda5..272190e 100644
--- a/src/flash/nand/tcl.c
+++ b/src/flash/nand/tcl.c
@@ -403,6 +403,39 @@ COMMAND_HANDLER(handle_nand_raw_access_command)
        return ERROR_OK;
 }
 
+COMMAND_HANDLER(handle_nand_feature_command)
+{
+       if ((CMD_ARGC < 2) || (CMD_ARGC > 3))
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       struct nand_device *p;
+       int retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p);
+       if (ERROR_OK != retval)
+               return retval;
+
+       if (NULL == p->device) {
+               command_print(CMD_CTX, "#%s: not probed", CMD_ARGV[0]);
+               return ERROR_OK;
+       }
+
+       uint8_t address;
+       uint32_t val;
+
+       COMMAND_PARSE_NUMBER(u8, CMD_ARGV[1], address);
+
+       if (CMD_ARGC == 3) {
+               COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], val);
+               retval = nand_set_feature(p, address, val);
+       } else {
+               val = 0;
+               retval = nand_get_feature(p, address, &val);
+               if (retval == ERROR_OK)
+                       command_print(CMD_CTX, "#%s feature %d: %x", 
CMD_ARGV[0], address, val);
+       }
+
+       return retval;
+}
+
 static const struct command_registration nand_exec_command_handlers[] = {
        {
                .name = "list",
@@ -469,6 +502,13 @@ static const struct command_registration 
nand_exec_command_handlers[] = {
                .usage = "bank_id ['enable'|'disable']",
                .help = "raw access to NAND flash device",
        },
+       {
+               .name = "feature",
+               .handler = handle_nand_feature_command,
+               .mode = COMMAND_EXEC,
+               .usage = "bank_id address [value]",
+               .help = "manage device features",
+       },
        COMMAND_REGISTRATION_DONE
 };
 

-- 

------------------------------------------------------------------------------
_______________________________________________
OpenOCD-devel mailing list
OpenOCD-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to