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
,