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 ***************************************************************************/
9 * NAND controller interface for Marvell Orion/Kirkwood SoCs.
18 #include <target/arm.h>
20 struct orion_nand_controller {
21 struct arm_nand_data io;
28 #define CHECK_HALTED \
30 if (target->state != TARGET_HALTED) { \
31 LOG_ERROR("NAND flash access requires halted target"); \
32 return ERROR_NAND_OPERATION_FAILED; \
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;
42 target_write_u8(target, hw->cmd, command);
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;
52 target_write_u8(target, hw->addr, address);
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;
62 target_read_u8(target, hw->data, data);
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;
72 target_write_u8(target, hw->data, data);
76 static int orion_nand_slow_block_write(struct nand_device *nand, uint8_t *data, int size)
79 orion_nand_write(nand, *data++);
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;
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);
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;
109 return ERROR_COMMAND_SYNTAX_ERROR;
111 hw = calloc(1, sizeof(*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);
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;
134 static int orion_nand_init(struct nand_device *nand)
139 struct nand_flash_controller orion_nand_controller = {
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,