jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / src / flash / nand / orion.c
blob7b19cbd24162ea4fef9fe8fa019b40523c02b561
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2009 by Marvell Semiconductors, Inc. *
5 * Written by Nicolas Pitre <nico at marvell.com> *
6 ***************************************************************************/
8 /*
9 * NAND controller interface for Marvell Orion/Kirkwood SoCs.
12 #ifdef HAVE_CONFIG_H
13 #include "config.h"
14 #endif
16 #include "imp.h"
17 #include "arm_io.h"
18 #include <target/arm.h>
20 struct orion_nand_controller {
21 struct arm_nand_data io;
23 uint32_t cmd;
24 uint32_t addr;
25 uint32_t data;
28 #define CHECK_HALTED \
29 do { \
30 if (target->state != TARGET_HALTED) { \
31 LOG_ERROR("NAND flash access requires halted target"); \
32 return ERROR_NAND_OPERATION_FAILED; \
33 } \
34 } while (0)
36 static int orion_nand_command(struct nand_device *nand, uint8_t command)
38 struct orion_nand_controller *hw = nand->controller_priv;
39 struct target *target = nand->target;
41 CHECK_HALTED;
42 target_write_u8(target, hw->cmd, command);
43 return ERROR_OK;
46 static int orion_nand_address(struct nand_device *nand, uint8_t address)
48 struct orion_nand_controller *hw = nand->controller_priv;
49 struct target *target = nand->target;
51 CHECK_HALTED;
52 target_write_u8(target, hw->addr, address);
53 return ERROR_OK;
56 static int orion_nand_read(struct nand_device *nand, void *data)
58 struct orion_nand_controller *hw = nand->controller_priv;
59 struct target *target = nand->target;
61 CHECK_HALTED;
62 target_read_u8(target, hw->data, data);
63 return ERROR_OK;
66 static int orion_nand_write(struct nand_device *nand, uint16_t data)
68 struct orion_nand_controller *hw = nand->controller_priv;
69 struct target *target = nand->target;
71 CHECK_HALTED;
72 target_write_u8(target, hw->data, data);
73 return ERROR_OK;
76 static int orion_nand_slow_block_write(struct nand_device *nand, uint8_t *data, int size)
78 while (size--)
79 orion_nand_write(nand, *data++);
80 return ERROR_OK;
83 static int orion_nand_fast_block_write(struct nand_device *nand, uint8_t *data, int size)
85 struct orion_nand_controller *hw = nand->controller_priv;
86 int retval;
88 hw->io.chunk_size = nand->page_size;
90 retval = arm_nandwrite(&hw->io, data, size);
91 if (retval == ERROR_NAND_NO_BUFFER)
92 retval = orion_nand_slow_block_write(nand, data, size);
94 return retval;
97 static int orion_nand_reset(struct nand_device *nand)
99 return orion_nand_command(nand, NAND_CMD_RESET);
102 NAND_DEVICE_COMMAND_HANDLER(orion_nand_device_command)
104 struct orion_nand_controller *hw;
105 uint32_t base;
106 uint8_t ale, cle;
108 if (CMD_ARGC != 3)
109 return ERROR_COMMAND_SYNTAX_ERROR;
111 hw = calloc(1, sizeof(*hw));
112 if (!hw) {
113 LOG_ERROR("no memory for nand controller");
114 return ERROR_NAND_DEVICE_INVALID;
117 nand->controller_priv = hw;
119 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], base);
120 cle = 0;
121 ale = 1;
123 hw->data = base;
124 hw->cmd = base + (1 << cle);
125 hw->addr = base + (1 << ale);
127 hw->io.target = nand->target;
128 hw->io.data = hw->data;
129 hw->io.op = ARM_NAND_NONE;
131 return ERROR_OK;
134 static int orion_nand_init(struct nand_device *nand)
136 return ERROR_OK;
139 struct nand_flash_controller orion_nand_controller = {
140 .name = "orion",
141 .usage = "<target_id> <NAND_address>",
142 .command = orion_nand_command,
143 .address = orion_nand_address,
144 .read_data = orion_nand_read,
145 .write_data = orion_nand_write,
146 .write_block_data = orion_nand_fast_block_write,
147 .reset = orion_nand_reset,
148 .nand_device_command = orion_nand_device_command,
149 .init = orion_nand_init,