summaryrefslogtreecommitdiff
path: root/tools/imximage.c
diff options
context:
space:
mode:
authorPeng Fan <Peng.Fan@freescale.com>2015-01-30 17:07:56 +0800
committerPeng Fan <Peng.Fan@freescale.com>2015-04-29 14:56:33 +0800
commit0393e813c0ab5050125cd19bc78d6e5b2d487e0d (patch)
treedecea93cfeea06c7fbb1838decb5f9685a7096a1 /tools/imximage.c
parent3d52e221ed444dab96038a2417d1dcb2217ad593 (diff)
downloadu-boot-imx-0393e813c0ab5050125cd19bc78d6e5b2d487e0d.zip
u-boot-imx-0393e813c0ab5050125cd19bc78d6e5b2d487e0d.tar.gz
u-boot-imx-0393e813c0ab5050125cd19bc78d6e5b2d487e0d.tar.bz2
MLK-10186-2 imximage: support new command
Since rom code supports clear bit and check data command, and new ddrc needs such commands, add clear bit and check data command in imximage.c. CHECK_DATA 4 xxxx bit This command is dead loop until bit set at address xxxx. CLR_BIT 4 xxxx bit This command is to clear bit at address xxxx. Signed-off-by: Peng Fan <Peng.Fan@freescale.com> (cherry picked from commit 257600d197bf9a58a2b8d08419296aaf901d850d) Conflicts: tools/imximage.c
Diffstat (limited to 'tools/imximage.c')
-rw-r--r--tools/imximage.c85
1 files changed, 70 insertions, 15 deletions
diff --git a/tools/imximage.c b/tools/imximage.c
index 7952210..a3af2c8 100644
--- a/tools/imximage.c
+++ b/tools/imximage.c
@@ -6,6 +6,8 @@
* Marvell Semiconductor <www.marvell.com>
* Written-by: Prafulla Wadaskar <prafulla@marvell.com>
*
+ * Copyright (C) 2014-2015 Freescale Semiconductor, Inc.
+ *
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -22,6 +24,8 @@ static table_entry_t imximage_cmds[] = {
{CMD_BOOT_FROM, "BOOT_FROM", "boot command", },
{CMD_BOOT_OFFSET, "BOOT_OFFSET", "Boot offset", },
{CMD_DATA, "DATA", "Reg Write Data", },
+ {CMD_CLR_BIT, "CLR_BIT", "Reg clear bit", },
+ {CMD_CHECK_DATA, "CHECK_DATA", "Reg Check Data", },
{CMD_CSF, "CSF", "Command Sequence File", },
{CMD_IMAGE_VERSION, "IMAGE_VERSION", "image version", },
#ifdef CONFIG_USE_PLUGIN
@@ -89,6 +93,7 @@ static set_imx_hdr_t set_imx_hdr;
static uint32_t max_dcd_entries;
static uint32_t *header_size_ptr;
static uint32_t *csf_ptr;
+static uint32_t dataindex;
static uint32_t get_cfg_value(char *token, char *name, int linenr)
{
@@ -138,7 +143,7 @@ static void err_imximage_version(int version)
}
static void set_dcd_val_v1(struct imx_header *imxhdr, char *name, int lineno,
- int fld, uint32_t value, uint32_t off)
+ int fld, int cmd, uint32_t value, uint32_t off)
{
dcd_v1_t *dcd_v1 = &imxhdr->header.hdr_v1.dcd_table;
@@ -166,16 +171,39 @@ static void set_dcd_val_v1(struct imx_header *imxhdr, char *name, int lineno,
}
static void set_dcd_val_v2(struct imx_header *imxhdr, char *name, int lineno,
- int fld, uint32_t value, uint32_t off)
+ int fld, int cmd, uint32_t value, uint32_t off)
{
dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.data.dcd_table;
+ dcd_command_t *dcd_command_block = (dcd_command_t *)&
+ dcd_v2->dcd_data[dataindex];
switch (fld) {
+ case CFG_COMMAND:
+ /* update header */
+ if (cmd == CMD_DATA) {
+ dcd_command_block->tag = DCD_WRITE_DATA_COMMAND_TAG;
+ dcd_command_block->length = cpu_to_be16(off *
+ sizeof(dcd_addr_data_t) + 4);
+ dcd_command_block->param = DCD_WRITE_DATA_PARAM;
+ } else if (cmd == CMD_CLR_BIT) {
+ dcd_command_block->tag = DCD_WRITE_DATA_COMMAND_TAG;
+ dcd_command_block->length = cpu_to_be16(off *
+ sizeof(dcd_addr_data_t) + 4);
+ dcd_command_block->param = DCD_CLR_BIT_PARAM;
+ } else if (CMD_CHECK_DATA) {
+ dcd_command_block->tag = DCD_CHECK_DATA_COMMAND_TAG;
+ /*
+ * check data command only supports one entry,
+ * so use 0xC = size(address + value + command).
+ */
+ dcd_command_block->length = cpu_to_be16(0xC);
+ dcd_command_block->param = DCD_CHECK_DATA_PARAM;
+ }
case CFG_REG_ADDRESS:
- dcd_v2->addr_data[off].addr = cpu_to_be32(value);
+ dcd_command_block->addr_data[off].addr = cpu_to_be32(value);
break;
case CFG_REG_VALUE:
- dcd_v2->addr_data[off].value = cpu_to_be32(value);
+ dcd_command_block->addr_data[off].value = cpu_to_be32(value);
break;
default:
break;
@@ -207,13 +235,14 @@ static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len,
dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.data.dcd_table;
dcd_v2->header.tag = DCD_HEADER_TAG;
+ /*
+ * dataindex does not contain the last dcd block,
+ * see how dataindex is updated.
+ */
dcd_v2->header.length = cpu_to_be16(
- dcd_len * sizeof(dcd_addr_data_t) + 8);
+ (dataindex + 1) * 4 + dcd_len *
+ sizeof(dcd_addr_data_t) + 4);
dcd_v2->header.version = DCD_VERSION;
- dcd_v2->write_dcd_command.tag = DCD_COMMAND_TAG;
- dcd_v2->write_dcd_command.length = cpu_to_be16(
- dcd_len * sizeof(dcd_addr_data_t) + 4);
- dcd_v2->write_dcd_command.param = DCD_COMMAND_PARAM;
}
}
@@ -543,7 +572,7 @@ static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token,
break;
case CMD_DATA:
value = get_cfg_value(token, name, lineno);
- (*set_dcd_val)(imxhdr, name, lineno, fld, value, dcd_len);
+ (*set_dcd_val)(imxhdr, name, lineno, fld, cmd, value, dcd_len);
if (unlikely(cmd_ver_first != 1))
cmd_ver_first = 0;
break;
@@ -567,7 +596,8 @@ static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token,
}
static void parse_cfg_fld(struct imx_header *imxhdr, int32_t *cmd,
- char *token, char *name, int lineno, int fld, int *dcd_len)
+ int32_t *precmd, char *token, char *name,
+ int lineno, int fld, int *dcd_len)
{
int value;
@@ -580,6 +610,28 @@ static void parse_cfg_fld(struct imx_header *imxhdr, int32_t *cmd,
"(%s)\n", name, lineno, token);
exit(EXIT_FAILURE);
}
+
+ if ((*precmd == CMD_DATA) || (*precmd == CMD_CLR_BIT) ||
+ (*precmd == CMD_CHECK_DATA)) {
+ if (*cmd != *precmd) {
+ dataindex += ((*dcd_len) *
+ sizeof(dcd_addr_data_t) + 4) >> 2;
+ *dcd_len = 0;
+ }
+ }
+
+ if ((*cmd == CMD_DATA) || (*cmd == CMD_CLR_BIT) ||
+ (*cmd == CMD_CHECK_DATA)) {
+ /*
+ * Reserve the first entry for command header,
+ * So use *dcd_len + 1 as the off.
+ */
+ (*set_dcd_val)(imxhdr, name, lineno, fld,
+ *cmd, 0, *dcd_len + 1);
+ }
+
+ *precmd = *cmd;
+
break;
case CFG_REG_SIZE:
parse_cfg_cmd(imxhdr, *cmd, token, name, lineno, fld, *dcd_len);
@@ -587,9 +639,11 @@ static void parse_cfg_fld(struct imx_header *imxhdr, int32_t *cmd,
case CFG_REG_ADDRESS:
case CFG_REG_VALUE:
switch (*cmd) {
+ case CMD_CHECK_DATA:
case CMD_DATA:
+ case CMD_CLR_BIT:
value = get_cfg_value(token, name, lineno);
- (*set_dcd_val)(imxhdr, name, lineno, fld, value,
+ (*set_dcd_val)(imxhdr, name, lineno, fld, *cmd, value,
*dcd_len);
if (fld == CFG_REG_VALUE) {
@@ -626,7 +680,7 @@ static uint32_t parse_cfg_file(struct imx_header *imxhdr, char *name)
int fld;
size_t len;
int dcd_len = 0;
- int32_t cmd;
+ int32_t cmd, precmd = CMD_INVALID;
fd = fopen(name, "r");
if (fd == 0) {
@@ -634,6 +688,7 @@ static uint32_t parse_cfg_file(struct imx_header *imxhdr, char *name)
exit(EXIT_FAILURE);
}
+ dataindex = 0;
/*
* Very simple parsing, line starting with # are comments
* and are dropped
@@ -656,8 +711,8 @@ static uint32_t parse_cfg_file(struct imx_header *imxhdr, char *name)
if (token[0] == '#')
break;
- parse_cfg_fld(imxhdr, &cmd, token, name,
- lineno, fld, &dcd_len);
+ parse_cfg_fld(imxhdr, &cmd, &precmd, token, name,
+ lineno, fld, &dcd_len);
}
}