diff options
author | Peng Fan <Peng.Fan@freescale.com> | 2015-01-30 17:07:56 +0800 |
---|---|---|
committer | Peng Fan <Peng.Fan@freescale.com> | 2015-04-29 14:56:33 +0800 |
commit | 0393e813c0ab5050125cd19bc78d6e5b2d487e0d (patch) | |
tree | decea93cfeea06c7fbb1838decb5f9685a7096a1 /tools/imximage.c | |
parent | 3d52e221ed444dab96038a2417d1dcb2217ad593 (diff) | |
download | u-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.c | 85 |
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); } } |