openocd: fix SPDX tag format for files .c
[fw/openocd] / src / flash / nand / at91sam9.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /*
4  * Copyright (C) 2009 by Dean Glazeski
5  * dnglaze@gmail.com
6  */
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11
12 #include <target/arm.h>
13 #include <helper/log.h>
14 #include "imp.h"
15 #include "arm_io.h"
16
17 #define AT91C_PIOX_SODR (0x30)  /**< Offset to PIO SODR. */
18 #define AT91C_PIOX_CODR (0x34)  /**< Offset to PIO CODR. */
19 #define AT91C_PIOX_PDSR (0x3C)  /**< Offset to PIO PDSR. */
20 #define AT91C_ECCX_CR (0x00)    /**< Offset to ECC CR. */
21 #define AT91C_ECCX_SR (0x08)    /**< Offset to ECC SR. */
22 #define AT91C_ECCX_PR (0x0C)    /**< Offset to ECC PR. */
23 #define AT91C_ECCX_NPR (0x10)   /**< Offset to ECC NPR. */
24
25 /**
26  * Representation of a pin on an AT91SAM9 chip.
27  */
28 struct at91sam9_pin {
29         /** Address of the PIO controller. */
30         uint32_t pioc;
31
32         /** Pin number. */
33         uint32_t num;
34 };
35
36 /**
37  * Private data for the controller that is stored in the NAND device structure.
38  */
39 struct at91sam9_nand {
40         /** Address of the ECC controller for NAND. */
41         uint32_t ecc;
42
43         /** Address data is written to. */
44         uint32_t data;
45
46         /** Address commands are written to. */
47         uint32_t cmd;
48
49         /** Address addresses are written to. */
50         uint32_t addr;
51
52         /** I/O structure for hosted reads/writes. */
53         struct arm_nand_data io;
54
55         /** Pin representing the ready/~busy line. */
56         struct at91sam9_pin busy;
57
58         /** Pin representing the chip enable. */
59         struct at91sam9_pin ce;
60 };
61
62 /**
63  * Checks if the target is halted and prints an error message if it isn't.
64  *
65  * @param target Target to be checked.
66  * @param label String label for where function is called from.
67  * @return True if the target is halted.
68  */
69 static int at91sam9_halted(struct target *target, const char *label)
70 {
71         if (target->state == TARGET_HALTED)
72                 return true;
73
74         LOG_ERROR("Target must be halted to use NAND controller (%s)", label);
75         return false;
76 }
77
78 /**
79  * Initialize the AT91SAM9 NAND controller.
80  *
81  * @param nand NAND device the controller is attached to.
82  * @return Success or failure of initialization.
83  */
84 static int at91sam9_init(struct nand_device *nand)
85 {
86         struct target *target = nand->target;
87
88         if (!at91sam9_halted(target, "init"))
89                 return ERROR_NAND_OPERATION_FAILED;
90
91         return ERROR_OK;
92 }
93
94 /**
95  * Enable NAND device attached to a controller.
96  *
97  * @param nand NAND controller information for controlling NAND device.
98  * @return Success or failure of the enabling.
99  */
100 static int at91sam9_enable(struct nand_device *nand)
101 {
102         struct at91sam9_nand *info = nand->controller_priv;
103         struct target *target = nand->target;
104
105         return target_write_u32(target, info->ce.pioc + AT91C_PIOX_CODR, 1 << info->ce.num);
106 }
107
108 /**
109  * Disable NAND device attached to a controller.
110  *
111  * @param nand NAND controller information for controlling NAND device.
112  * @return Success or failure of the disabling.
113  */
114 static int at91sam9_disable(struct nand_device *nand)
115 {
116         struct at91sam9_nand *info = nand->controller_priv;
117         struct target *target = nand->target;
118
119         return target_write_u32(target, info->ce.pioc + AT91C_PIOX_SODR, 1 << info->ce.num);
120 }
121
122 /**
123  * Send a command to the NAND device.
124  *
125  * @param nand NAND device to write the command to.
126  * @param command Command to be written.
127  * @return Success or failure of writing the command.
128  */
129 static int at91sam9_command(struct nand_device *nand, uint8_t command)
130 {
131         struct at91sam9_nand *info = nand->controller_priv;
132         struct target *target = nand->target;
133
134         if (!at91sam9_halted(target, "command"))
135                 return ERROR_NAND_OPERATION_FAILED;
136
137         at91sam9_enable(nand);
138
139         return target_write_u8(target, info->cmd, command);
140 }
141
142 /**
143  * Reset the AT91SAM9 NAND controller.
144  *
145  * @param nand NAND device to be reset.
146  * @return Success or failure of reset.
147  */
148 static int at91sam9_reset(struct nand_device *nand)
149 {
150         if (!at91sam9_halted(nand->target, "reset"))
151                 return ERROR_NAND_OPERATION_FAILED;
152
153         return at91sam9_disable(nand);
154 }
155
156 /**
157  * Send an address to the NAND device attached to an AT91SAM9 NAND controller.
158  *
159  * @param nand NAND device to send the address to.
160  * @param address Address to be sent.
161  * @return Success or failure of sending the address.
162  */
163 static int at91sam9_address(struct nand_device *nand, uint8_t address)
164 {
165         struct at91sam9_nand *info = nand->controller_priv;
166         struct target *target = nand->target;
167
168         if (!at91sam9_halted(nand->target, "address"))
169                 return ERROR_NAND_OPERATION_FAILED;
170
171         return target_write_u8(target, info->addr, address);
172 }
173
174 /**
175  * Read data directly from the NAND device attached to an AT91SAM9 NAND
176  * controller.
177  *
178  * @param nand NAND device to read from.
179  * @param data Pointer to where the data should be put.
180  * @return Success or failure of reading the data.
181  */
182 static int at91sam9_read_data(struct nand_device *nand, void *data)
183 {
184         struct at91sam9_nand *info = nand->controller_priv;
185         struct target *target = nand->target;
186
187         if (!at91sam9_halted(nand->target, "read data"))
188                 return ERROR_NAND_OPERATION_FAILED;
189
190         return target_read_u8(target, info->data, data);
191 }
192
193 /**
194  * Write data directly to the NAND device attached to an AT91SAM9 NAND
195  * controller.
196  *
197  * @param nand NAND device to be written to.
198  * @param data Data to be written.
199  * @return Success or failure of the data write.
200  */
201 static int at91sam9_write_data(struct nand_device *nand, uint16_t data)
202 {
203         struct at91sam9_nand *info = nand->controller_priv;
204         struct target *target = nand->target;
205
206         if (!at91sam9_halted(target, "write data"))
207                 return ERROR_NAND_OPERATION_FAILED;
208
209         return target_write_u8(target, info->data, data);
210 }
211
212 /**
213  * Determine if the NAND device is ready by looking at the ready/~busy pin.
214  *
215  * @param nand NAND device to check.
216  * @param timeout Time in milliseconds to wait for NAND to be ready.
217  * @return True if the NAND is ready in the timeout period.
218  */
219 static int at91sam9_nand_ready(struct nand_device *nand, int timeout)
220 {
221         struct at91sam9_nand *info = nand->controller_priv;
222         struct target *target = nand->target;
223         uint32_t status;
224
225         if (!at91sam9_halted(target, "nand ready"))
226                 return 0;
227
228         do {
229                 target_read_u32(target, info->busy.pioc + AT91C_PIOX_PDSR, &status);
230
231                 if (status & (1 << info->busy.num))
232                         return 1;
233
234                 alive_sleep(1);
235         } while (timeout-- > 0);
236
237         return 0;
238 }
239
240 /**
241  * Read a block of data from the NAND device attached to an AT91SAM9.  This
242  * utilizes the ARM hosted NAND read function.
243  *
244  * @param nand NAND device to read from.
245  * @param data Pointer to where the read data should be placed.
246  * @param size Size of the data being read.
247  * @return Success or failure of the hosted read.
248  */
249 static int at91sam9_read_block_data(struct nand_device *nand, uint8_t *data, int size)
250 {
251         struct at91sam9_nand *info = nand->controller_priv;
252         struct arm_nand_data *io = &info->io;
253         int status;
254
255         if (!at91sam9_halted(nand->target, "read block"))
256                 return ERROR_NAND_OPERATION_FAILED;
257
258         io->chunk_size = nand->page_size;
259         status = arm_nandread(io, data, size);
260
261         return status;
262 }
263
264 /**
265  * Write a block of data to a NAND device attached to an AT91SAM9.  This uses
266  * the ARM hosted write function to write the data.
267  *
268  * @param nand NAND device to write to.
269  * @param data Data to be written to device.
270  * @param size Size of the data being written.
271  * @return Success or failure of the hosted write.
272  */
273 static int at91sam9_write_block_data(struct nand_device *nand, uint8_t *data, int size)
274 {
275         struct at91sam9_nand *info = nand->controller_priv;
276         struct arm_nand_data *io = &info->io;
277         int status;
278
279         if (!at91sam9_halted(nand->target, "write block"))
280                 return ERROR_NAND_OPERATION_FAILED;
281
282         io->chunk_size = nand->page_size;
283         status = arm_nandwrite(io, data, size);
284
285         return status;
286 }
287
288 /**
289  * Initialize the ECC controller on the AT91SAM9.
290  *
291  * @param target Target to configure ECC on.
292  * @param info NAND controller information for where the ECC is.
293  * @return Success or failure of initialization.
294  */
295 static int at91sam9_ecc_init(struct target *target, struct at91sam9_nand *info)
296 {
297         if (!info->ecc) {
298                 LOG_ERROR("ECC controller address must be set when not reading raw NAND data");
299                 return ERROR_NAND_OPERATION_FAILED;
300         }
301
302         /* reset ECC parity registers */
303         return target_write_u32(target, info->ecc + AT91C_ECCX_CR, 1);
304 }
305
306 /**
307  * Initialize an area for the OOB based on whether a user is requesting the OOB
308  * data.  This determines the size of the OOB and allocates the space in case
309  * the user has not requested the OOB data.
310  *
311  * @param nand NAND device we are creating an OOB for.
312  * @param oob Pointer to the user supplied OOB area.
313  * @param size Size of the OOB.
314  * @return Pointer to an area to store OOB data.
315  */
316 static uint8_t *at91sam9_oob_init(struct nand_device *nand, uint8_t *oob, uint32_t *size)
317 {
318         if (!oob) {
319                 /* user doesn't want OOB, allocate it */
320                 if (nand->page_size == 512)
321                         *size = 16;
322                 else if (nand->page_size == 2048)
323                         *size = 64;
324
325                 oob = malloc(*size);
326                 if (!oob) {
327                         LOG_ERROR("Unable to allocate space for OOB");
328                         return NULL;
329                 }
330
331                 memset(oob, 0xFF, *size);
332         }
333
334         return oob;
335 }
336
337 /**
338  * Reads a page from an AT91SAM9 NAND controller and verifies using 1-bit ECC
339  * controller on chip.  This makes an attempt to correct any errors that are
340  * encountered while reading the page of data.
341  *
342  * @param nand NAND device to read from
343  * @param page Page to be read.
344  * @param data Pointer to where data should be read to.
345  * @param data_size Size of the data to be read.
346  * @param oob Pointer to where OOB data should be read to.
347  * @param oob_size Size of the OOB data to be read.
348  * @return Success or failure of reading the NAND page.
349  */
350 static int at91sam9_read_page(struct nand_device *nand, uint32_t page,
351         uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
352 {
353         int retval;
354         struct at91sam9_nand *info = nand->controller_priv;
355         struct target *target = nand->target;
356         uint8_t *oob_data;
357         uint32_t status;
358
359         retval = at91sam9_ecc_init(target, info);
360         if (retval != ERROR_OK)
361                 return retval;
362
363         retval = nand_page_command(nand, page, NAND_CMD_READ0, !data);
364         if (retval != ERROR_OK)
365                 return retval;
366
367         if (data) {
368                 retval = nand_read_data_page(nand, data, data_size);
369                 if (retval != ERROR_OK)
370                         return retval;
371         }
372
373         oob_data = at91sam9_oob_init(nand, oob, &oob_size);
374         retval = nand_read_data_page(nand, oob_data, oob_size);
375         if (retval == ERROR_OK && data) {
376                 target_read_u32(target, info->ecc + AT91C_ECCX_SR, &status);
377                 if (status & 1) {
378                         LOG_ERROR("Error detected!");
379                         if (status & 4)
380                                 LOG_ERROR("Multiple errors encountered; unrecoverable!");
381                         else {
382                                 /* attempt recovery */
383                                 uint32_t parity;
384
385                                 target_read_u32(target,
386                                         info->ecc + AT91C_ECCX_PR,
387                                         &parity);
388                                 uint32_t word = (parity & 0x0000FFF0) >> 4;
389                                 uint32_t bit = parity & 0x0F;
390
391                                 data[word] ^= (0x1) << bit;
392                                 LOG_INFO("Data word %d, bit %d corrected.",
393                                         (unsigned) word,
394                                         (unsigned) bit);
395                         }
396                 }
397
398                 if (status & 2) {
399                         /* we could write back correct ECC data */
400                         LOG_ERROR("Error in ECC bytes detected");
401                 }
402         }
403
404         if (!oob) {
405                 /* if it wasn't asked for, free it */
406                 free(oob_data);
407         }
408
409         return retval;
410 }
411
412 /**
413  * Write a page of data including 1-bit ECC information to a NAND device
414  * attached to an AT91SAM9 controller.  If there is OOB data to be written,
415  * this will ignore the computed ECC from the ECC controller.
416  *
417  * @param nand NAND device to write to.
418  * @param page Page to write.
419  * @param data Pointer to data being written.
420  * @param data_size Size of the data being written.
421  * @param oob Pointer to OOB data being written.
422  * @param oob_size Size of the OOB data.
423  * @return Success or failure of the page write.
424  */
425 static int at91sam9_write_page(struct nand_device *nand, uint32_t page,
426         uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
427 {
428         struct at91sam9_nand *info = nand->controller_priv;
429         struct target *target = nand->target;
430         int retval;
431         uint8_t *oob_data = oob;
432         uint32_t parity, nparity;
433
434         retval = at91sam9_ecc_init(target, info);
435         if (retval != ERROR_OK)
436                 return retval;
437
438         retval = nand_page_command(nand, page, NAND_CMD_SEQIN, !data);
439         if (retval != ERROR_OK)
440                 return retval;
441
442         if (data) {
443                 retval = nand_write_data_page(nand, data, data_size);
444                 if (retval != ERROR_OK) {
445                         LOG_ERROR("Unable to write data to NAND device");
446                         return retval;
447                 }
448         }
449
450         oob_data = at91sam9_oob_init(nand, oob, &oob_size);
451
452         if (!oob) {
453                 /* no OOB given, so read in the ECC parity from the ECC controller */
454                 target_read_u32(target, info->ecc + AT91C_ECCX_PR, &parity);
455                 target_read_u32(target, info->ecc + AT91C_ECCX_NPR, &nparity);
456
457                 oob_data[0] = (uint8_t) parity;
458                 oob_data[1] = (uint8_t) (parity >> 8);
459                 oob_data[2] = (uint8_t) nparity;
460                 oob_data[3] = (uint8_t) (nparity >> 8);
461         }
462
463         retval = nand_write_data_page(nand, oob_data, oob_size);
464
465         if (!oob)
466                 free(oob_data);
467
468         if (retval != ERROR_OK) {
469                 LOG_ERROR("Unable to write OOB data to NAND");
470                 return retval;
471         }
472
473         retval = nand_write_finish(nand);
474
475         return retval;
476 }
477
478 /**
479  * Handle the initial NAND device command for AT91SAM9 controllers.  This
480  * initializes much of the controller information struct to be ready for future
481  * reads and writes.
482  */
483 NAND_DEVICE_COMMAND_HANDLER(at91sam9_nand_device_command)
484 {
485         unsigned long chip = 0, ecc = 0;
486         struct at91sam9_nand *info = NULL;
487
488         LOG_DEBUG("AT91SAM9 NAND Device Command");
489
490         if (CMD_ARGC < 3 || CMD_ARGC > 4) {
491                 LOG_ERROR("parameters: %s target chip_addr", CMD_ARGV[0]);
492                 return ERROR_NAND_OPERATION_FAILED;
493         }
494
495         COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[2], chip);
496         if (chip == 0) {
497                 LOG_ERROR("invalid NAND chip address: %s", CMD_ARGV[2]);
498                 return ERROR_NAND_OPERATION_FAILED;
499         }
500
501         if (CMD_ARGC == 4) {
502                 COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[3], ecc);
503                 if (ecc == 0) {
504                         LOG_ERROR("invalid ECC controller address: %s", CMD_ARGV[3]);
505                         return ERROR_NAND_OPERATION_FAILED;
506                 }
507         }
508
509         info = calloc(1, sizeof(*info));
510         if (!info) {
511                 LOG_ERROR("unable to allocate space for controller private data");
512                 return ERROR_NAND_OPERATION_FAILED;
513         }
514
515         info->data = chip;
516         info->cmd = chip | (1 << 22);
517         info->addr = chip | (1 << 21);
518         info->ecc = ecc;
519
520         nand->controller_priv = info;
521         info->io.target = nand->target;
522         info->io.data = info->data;
523         info->io.op = ARM_NAND_NONE;
524
525         return ERROR_OK;
526 }
527
528 /**
529  * Handle the AT91SAM9 CLE command for specifying the address line to use for
530  * writing commands to a NAND device.
531  */
532 COMMAND_HANDLER(handle_at91sam9_cle_command)
533 {
534         struct nand_device *nand = NULL;
535         struct at91sam9_nand *info = NULL;
536         unsigned num, address_line;
537
538         if (CMD_ARGC != 2) {
539                 command_print(CMD, "incorrect number of arguments for 'at91sam9 cle' command");
540                 return ERROR_OK;
541         }
542
543         COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);
544         nand = get_nand_device_by_num(num);
545         if (!nand) {
546                 command_print(CMD, "invalid nand device number: %s", CMD_ARGV[0]);
547                 return ERROR_OK;
548         }
549
550         info = nand->controller_priv;
551
552         COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], address_line);
553         info->cmd = info->data | (1 << address_line);
554
555         return ERROR_OK;
556 }
557
558 /**
559  * Handle the AT91SAM9 ALE command for specifying the address line to use for
560  * writing addresses to the NAND device.
561  */
562 COMMAND_HANDLER(handle_at91sam9_ale_command)
563 {
564         struct nand_device *nand = NULL;
565         struct at91sam9_nand *info = NULL;
566         unsigned num, address_line;
567
568         if (CMD_ARGC != 2)
569                 return ERROR_COMMAND_SYNTAX_ERROR;
570
571         COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);
572         nand = get_nand_device_by_num(num);
573         if (!nand) {
574                 command_print(CMD, "invalid nand device number: %s", CMD_ARGV[0]);
575                 return ERROR_COMMAND_ARGUMENT_INVALID;
576         }
577
578         info = nand->controller_priv;
579
580         COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], address_line);
581         info->addr = info->data | (1 << address_line);
582
583         return ERROR_OK;
584 }
585
586 /**
587  * Handle the AT91SAM9 RDY/~BUSY command for specifying the pin that watches the
588  * RDY/~BUSY line from the NAND device.
589  */
590 COMMAND_HANDLER(handle_at91sam9_rdy_busy_command)
591 {
592         struct nand_device *nand = NULL;
593         struct at91sam9_nand *info = NULL;
594         unsigned num, base_pioc, pin_num;
595
596         if (CMD_ARGC != 3)
597                 return ERROR_COMMAND_SYNTAX_ERROR;
598
599         COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);
600         nand = get_nand_device_by_num(num);
601         if (!nand) {
602                 command_print(CMD, "invalid nand device number: %s", CMD_ARGV[0]);
603                 return ERROR_COMMAND_ARGUMENT_INVALID;
604         }
605
606         info = nand->controller_priv;
607
608         COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], base_pioc);
609         info->busy.pioc = base_pioc;
610
611         COMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], pin_num);
612         info->busy.num = pin_num;
613
614         return ERROR_OK;
615 }
616
617 /**
618  * Handle the AT91SAM9 CE command for specifying the pin that is used to enable
619  * or disable the NAND device.
620  */
621 COMMAND_HANDLER(handle_at91sam9_ce_command)
622 {
623         struct nand_device *nand = NULL;
624         struct at91sam9_nand *info = NULL;
625         unsigned num, base_pioc, pin_num;
626
627         if (CMD_ARGC != 3)
628                 return ERROR_COMMAND_SYNTAX_ERROR;
629
630         COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);
631         nand = get_nand_device_by_num(num);
632         if (!nand) {
633                 command_print(CMD, "invalid nand device number: %s", CMD_ARGV[0]);
634                 return ERROR_COMMAND_ARGUMENT_INVALID;
635         }
636
637         info = nand->controller_priv;
638
639         COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], base_pioc);
640         info->ce.pioc = base_pioc;
641
642         COMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], pin_num);
643         info->ce.num = pin_num;
644
645         return ERROR_OK;
646 }
647
648 static const struct command_registration at91sam9_sub_command_handlers[] = {
649         {
650                 .name = "cle",
651                 .handler = handle_at91sam9_cle_command,
652                 .mode = COMMAND_CONFIG,
653                 .help = "set command latch enable address line (default is 22)",
654                 .usage = "bank_id address_line",
655         },
656         {
657                 .name = "ale",
658                 .handler = handle_at91sam9_ale_command,
659                 .mode = COMMAND_CONFIG,
660                 .help = "set address latch enable address line (default is 21)",
661                 .usage = "bank_id address_line",
662         },
663         {
664                 .name = "rdy_busy",
665                 .handler = handle_at91sam9_rdy_busy_command,
666                 .mode = COMMAND_CONFIG,
667                 .help = "set the GPIO input pin connected to "
668                         "the RDY/~BUSY signal (no default)",
669                 .usage = "bank_id pio_base_addr pin_num",
670         },
671         {
672                 .name = "ce",
673                 .handler = handle_at91sam9_ce_command,
674                 .mode = COMMAND_CONFIG,
675                 .help = "set the GPIO output pin connected to "
676                         "the chip enable signal (no default)",
677                 .usage = "bank_id pio_base_addr pin_num",
678         },
679         COMMAND_REGISTRATION_DONE
680 };
681
682 static const struct command_registration at91sam9_command_handler[] = {
683         {
684                 .name = "at91sam9",
685                 .mode = COMMAND_ANY,
686                 .help = "AT91SAM9 NAND flash controller commands",
687                 .usage = "",
688                 .chain = at91sam9_sub_command_handlers,
689         },
690         COMMAND_REGISTRATION_DONE
691 };
692
693 /**
694  * Structure representing the AT91SAM9 NAND controller.
695  */
696 struct nand_flash_controller at91sam9_nand_controller = {
697         .name = "at91sam9",
698         .nand_device_command = at91sam9_nand_device_command,
699         .commands = at91sam9_command_handler,
700         .init = at91sam9_init,
701         .command = at91sam9_command,
702         .reset = at91sam9_reset,
703         .address = at91sam9_address,
704         .read_data = at91sam9_read_data,
705         .write_data = at91sam9_write_data,
706         .nand_ready = at91sam9_nand_ready,
707         .read_block_data = at91sam9_read_block_data,
708         .write_block_data = at91sam9_write_block_data,
709         .read_page = at91sam9_read_page,
710         .write_page = at91sam9_write_page,
711 };