mvsata_ide.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*
  2. * Copyright (C) 2010 Albert ARIBAUD <albert.u.boot@aribaud.net>
  3. *
  4. * Written-by: Albert ARIBAUD <albert.u.boot@aribaud.net>
  5. *
  6. * See file CREDITS for list of people who contributed to this
  7. * project.
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License as
  11. * published by the Free Software Foundation; either version 2 of
  12. * the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  22. * MA 02110-1301 USA
  23. */
  24. #include <common.h>
  25. #include <asm/io.h>
  26. #if defined(CONFIG_ORION5X)
  27. #include <asm/arch/orion5x.h>
  28. #elif defined(CONFIG_KIRKWOOD)
  29. #include <asm/arch/kirkwood.h>
  30. #endif
  31. /* SATA port registers */
  32. struct mvsata_port_registers {
  33. u32 reserved0[10];
  34. u32 edma_cmd;
  35. u32 reserved1[181];
  36. /* offset 0x300 : ATA Interface registers */
  37. u32 sstatus;
  38. u32 serror;
  39. u32 scontrol;
  40. u32 ltmode;
  41. u32 phymode3;
  42. u32 phymode4;
  43. u32 reserved2[5];
  44. u32 phymode1;
  45. u32 phymode2;
  46. u32 bist_cr;
  47. u32 bist_dw1;
  48. u32 bist_dw2;
  49. u32 serrorintrmask;
  50. };
  51. /*
  52. * Sanity checks:
  53. * - to compile at all, we need CONFIG_SYS_ATA_BASE_ADDR.
  54. * - for ide_preinit to make sense, we need at least one of
  55. * CONFIG_SYS_ATA_IDE0_OFFSET or CONFIG_SYS_ATA_IDE0_OFFSET;
  56. * - for inde_preinit to be called, we need CONFIG_IDE_PREINIT.
  57. * Fail with an explanation message if these conditions are not met.
  58. * This is particularly important for CONFIG_IDE_PREINIT, because
  59. * its lack would not cause a build error.
  60. */
  61. #if !defined(CONFIG_SYS_ATA_BASE_ADDR)
  62. #error CONFIG_SYS_ATA_BASE_ADDR must be defined
  63. #elif !defined(CONFIG_SYS_ATA_IDE0_OFFSET) \
  64. && !defined(CONFIG_SYS_ATA_IDE1_OFFSET)
  65. #error CONFIG_SYS_ATA_IDE0_OFFSET or CONFIG_SYS_ATA_IDE1_OFFSET \
  66. must be defined
  67. #elif !defined(CONFIG_IDE_PREINIT)
  68. #error CONFIG_IDE_PREINIT must be defined
  69. #endif
  70. /*
  71. * Masks and values for SControl DETection and Interface Power Management,
  72. * and for SStatus DETection.
  73. */
  74. #define MVSATA_EDMA_CMD_ATA_RST 0x00000004
  75. #define MVSATA_SCONTROL_DET_MASK 0x0000000F
  76. #define MVSATA_SCONTROL_DET_NONE 0x00000000
  77. #define MVSATA_SCONTROL_DET_INIT 0x00000001
  78. #define MVSATA_SCONTROL_IPM_MASK 0x00000F00
  79. #define MVSATA_SCONTROL_IPM_NO_LP_ALLOWED 0x00000300
  80. #define MVSATA_SCONTROL_MASK \
  81. (MVSATA_SCONTROL_DET_MASK|MVSATA_SCONTROL_IPM_MASK)
  82. #define MVSATA_PORT_INIT \
  83. (MVSATA_SCONTROL_DET_INIT|MVSATA_SCONTROL_IPM_NO_LP_ALLOWED)
  84. #define MVSATA_PORT_USE \
  85. (MVSATA_SCONTROL_DET_NONE|MVSATA_SCONTROL_IPM_NO_LP_ALLOWED)
  86. #define MVSATA_SSTATUS_DET_MASK 0x0000000F
  87. #define MVSATA_SSTATUS_DET_DEVCOMM 0x00000003
  88. /*
  89. * Status codes to return to client callers. Currently, callers ignore
  90. * exact value and only care for zero or nonzero, so no need to make this
  91. * public, it is only #define'd for clarity.
  92. * If/when standard negative codes are implemented in U-boot, then these
  93. * #defines should be moved to, or replaced by ones from, the common list
  94. * of status codes.
  95. */
  96. #define MVSATA_STATUS_OK 0
  97. #define MVSATA_STATUS_TIMEOUT -1
  98. /*
  99. * Initialize one MVSATAHC port: set SControl's IPM to "always active"
  100. * and DET to "reset", then wait for SStatus's DET to become "device and
  101. * comm ok" (or time out after 50 us if no device), then set SControl's
  102. * DET back to "no action".
  103. */
  104. static int mvsata_ide_initialize_port(struct mvsata_port_registers *port)
  105. {
  106. u32 control;
  107. u32 status;
  108. u32 timeleft = 10000; /* wait at most 10 ms for SATA reset to complete */
  109. /* Hard reset */
  110. writel(MVSATA_EDMA_CMD_ATA_RST, &port->edma_cmd);
  111. udelay(25); /* taken from original marvell port */
  112. writel(0, &port->edma_cmd);
  113. /* Set control IPM to 3 (no low power) and DET to 1 (initialize) */
  114. control = readl(&port->scontrol);
  115. control = (control & ~MVSATA_SCONTROL_MASK) | MVSATA_PORT_INIT;
  116. writel(control, &port->scontrol);
  117. /* Toggle control DET back to 0 (normal operation) */
  118. control = (control & ~MVSATA_SCONTROL_MASK) | MVSATA_PORT_USE;
  119. writel(control, &port->scontrol);
  120. /* wait for status DET to become 3 (device and communication OK) */
  121. while (--timeleft) {
  122. status = readl(&port->sstatus) & MVSATA_SSTATUS_DET_MASK;
  123. if (status == MVSATA_SSTATUS_DET_DEVCOMM)
  124. break;
  125. udelay(1);
  126. }
  127. /* return success or time-out error depending on time left */
  128. if (!timeleft)
  129. return MVSATA_STATUS_TIMEOUT;
  130. return MVSATA_STATUS_OK;
  131. }
  132. /*
  133. * ide_preinit() will be called by ide_init in cmd_ide.c and will
  134. * reset the MVSTATHC ports needed by the board.
  135. */
  136. int ide_preinit(void)
  137. {
  138. int status;
  139. /* Enable ATA port 0 (could be SATA port 0 or 1) if declared */
  140. #if defined(CONFIG_SYS_ATA_IDE0_OFFSET)
  141. status = mvsata_ide_initialize_port(
  142. (struct mvsata_port_registers *)
  143. (CONFIG_SYS_ATA_BASE_ADDR + CONFIG_SYS_ATA_IDE0_OFFSET));
  144. if (status)
  145. return status;
  146. #endif
  147. /* Enable ATA port 1 (could be SATA port 0 or 1) if declared */
  148. #if defined(CONFIG_SYS_ATA_IDE1_OFFSET)
  149. status = mvsata_ide_initialize_port(
  150. (struct mvsata_port_registers *)
  151. (CONFIG_SYS_ATA_BASE_ADDR + CONFIG_SYS_ATA_IDE1_OFFSET));
  152. if (status)
  153. return status;
  154. #endif
  155. /* return success if all ports initializations succeeded */
  156. return MVSATA_STATUS_OK;
  157. }