You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

189 lines
5.1 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2009 by Marvell Semiconductors, Inc. *
  3. * Written by Nicolas Pitre <nico at marvell.com> *
  4. * *
  5. * This program is free software; you can redistribute it and/or modify *
  6. * it under the terms of the GNU General Public License as published by *
  7. * the Free Software Foundation; either version 2 of the License, or *
  8. * (at your option) any later version. *
  9. * *
  10. * This program is distributed in the hope that it will be useful, *
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  13. * GNU General Public License for more details. *
  14. * *
  15. * You should have received a copy of the GNU General Public License *
  16. * along with this program; if not, write to the *
  17. * Free Software Foundation, Inc., *
  18. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  19. ***************************************************************************/
  20. /*
  21. * NAND controller interface for Marvell Orion/Kirkwood SoCs.
  22. */
  23. #ifdef HAVE_CONFIG_H
  24. #include "config.h"
  25. #endif
  26. #include "arm_nandio.h"
  27. #include "armv4_5.h"
  28. typedef struct orion_nand_controller_s
  29. {
  30. struct target_s *target;
  31. struct arm_nand_data io;
  32. uint32_t cmd;
  33. uint32_t addr;
  34. uint32_t data;
  35. } orion_nand_controller_t;
  36. #define CHECK_HALTED \
  37. do { \
  38. if (target->state != TARGET_HALTED) { \
  39. LOG_ERROR("NAND flash access requires halted target"); \
  40. return ERROR_NAND_OPERATION_FAILED; \
  41. } \
  42. } while (0)
  43. static int orion_nand_command(struct nand_device_s *device, uint8_t command)
  44. {
  45. orion_nand_controller_t *hw = device->controller_priv;
  46. target_t *target = hw->target;
  47. CHECK_HALTED;
  48. target_write_u8(target, hw->cmd, command);
  49. return ERROR_OK;
  50. }
  51. static int orion_nand_address(struct nand_device_s *device, uint8_t address)
  52. {
  53. orion_nand_controller_t *hw = device->controller_priv;
  54. target_t *target = hw->target;
  55. CHECK_HALTED;
  56. target_write_u8(target, hw->addr, address);
  57. return ERROR_OK;
  58. }
  59. static int orion_nand_read(struct nand_device_s *device, void *data)
  60. {
  61. orion_nand_controller_t *hw = device->controller_priv;
  62. target_t *target = hw->target;
  63. CHECK_HALTED;
  64. target_read_u8(target, hw->data, data);
  65. return ERROR_OK;
  66. }
  67. static int orion_nand_write(struct nand_device_s *device, uint16_t data)
  68. {
  69. orion_nand_controller_t *hw = device->controller_priv;
  70. target_t *target = hw->target;
  71. CHECK_HALTED;
  72. target_write_u8(target, hw->data, data);
  73. return ERROR_OK;
  74. }
  75. static int orion_nand_slow_block_write(struct nand_device_s *device, uint8_t *data, int size)
  76. {
  77. while (size--)
  78. orion_nand_write(device, *data++);
  79. return ERROR_OK;
  80. }
  81. static int orion_nand_fast_block_write(struct nand_device_s *device, uint8_t *data, int size)
  82. {
  83. orion_nand_controller_t *hw = device->controller_priv;
  84. int retval;
  85. hw->io.chunk_size = device->page_size;
  86. retval = arm_nandwrite(&hw->io, data, size);
  87. if (retval == ERROR_NAND_NO_BUFFER)
  88. retval = orion_nand_slow_block_write(device, data, size);
  89. return retval;
  90. }
  91. static int orion_nand_reset(struct nand_device_s *device)
  92. {
  93. return orion_nand_command(device, NAND_CMD_RESET);
  94. }
  95. static int orion_nand_controller_ready(struct nand_device_s *device, int timeout)
  96. {
  97. return 1;
  98. }
  99. static int orion_nand_register_commands(struct command_context_s *cmd_ctx)
  100. {
  101. return ERROR_OK;
  102. }
  103. int orion_nand_device_command(struct command_context_s *cmd_ctx, char *cmd,
  104. char **args, int argc,
  105. struct nand_device_s *device)
  106. {
  107. orion_nand_controller_t *hw;
  108. uint32_t base;
  109. uint8_t ale, cle;
  110. if (argc != 3) {
  111. LOG_ERROR("arguments must be: <target_id> <NAND_address>\n");
  112. return ERROR_NAND_DEVICE_INVALID;
  113. }
  114. hw = calloc(1, sizeof(*hw));
  115. if (!hw) {
  116. LOG_ERROR("no memory for nand controller\n");
  117. return ERROR_NAND_DEVICE_INVALID;
  118. }
  119. device->controller_priv = hw;
  120. hw->target = get_target(args[1]);
  121. if (!hw->target) {
  122. LOG_ERROR("target '%s' not defined", args[1]);
  123. free(hw);
  124. return ERROR_NAND_DEVICE_INVALID;
  125. }
  126. base = strtoul(args[2], NULL, 0);
  127. cle = 0;
  128. ale = 1;
  129. hw->data = base;
  130. hw->cmd = base + (1 << cle);
  131. hw->addr = base + (1 << ale);
  132. hw->io.target = hw->target;
  133. hw->io.data = hw->data;
  134. return ERROR_OK;
  135. }
  136. static int orion_nand_init(struct nand_device_s *device)
  137. {
  138. return ERROR_OK;
  139. }
  140. nand_flash_controller_t orion_nand_controller =
  141. {
  142. .name = "orion",
  143. .command = orion_nand_command,
  144. .address = orion_nand_address,
  145. .read_data = orion_nand_read,
  146. .write_data = orion_nand_write,
  147. .write_block_data = orion_nand_fast_block_write,
  148. .reset = orion_nand_reset,
  149. .controller_ready = orion_nand_controller_ready,
  150. .nand_device_command = orion_nand_device_command,
  151. .register_commands = orion_nand_register_commands,
  152. .init = orion_nand_init,
  153. };