satamv.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. * This file is part of the flashrom project.
  3. *
  4. * Copyright (C) 2010,2011 Carl-Daniel Hailfinger
  5. * Written by Carl-Daniel Hailfinger for Angelbird Ltd.
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; version 2 of the License.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. /* Datasheets are not public (yet?) */
  21. #if defined(__i386__) || defined(__x86_64__)
  22. #include <stdlib.h>
  23. #include "flash.h"
  24. #include "programmer.h"
  25. uint8_t *mv_bar;
  26. uint16_t mv_iobar;
  27. const struct pcidev_status satas_mv[] = {
  28. /* 88SX6041 and 88SX6042 are the same according to the datasheet. */
  29. {0x11ab, 0x7042, OK, "Marvell", "88SX7042 PCI-e 4-port SATA-II"},
  30. {},
  31. };
  32. #define NVRAM_PARAM 0x1045c
  33. #define FLASH_PARAM 0x1046c
  34. #define EXPANSION_ROM_BAR_CONTROL 0x00d2c
  35. #define PCI_BAR2_CONTROL 0x00c08
  36. #define GPIO_PORT_CONTROL 0x104f0
  37. static void satamv_chip_writeb(const struct flashctx *flash, uint8_t val,
  38. chipaddr addr);
  39. static uint8_t satamv_chip_readb(const struct flashctx *flash,
  40. const chipaddr addr);
  41. static const struct par_programmer par_programmer_satamv = {
  42. .chip_readb = satamv_chip_readb,
  43. .chip_readw = fallback_chip_readw,
  44. .chip_readl = fallback_chip_readl,
  45. .chip_readn = fallback_chip_readn,
  46. .chip_writeb = satamv_chip_writeb,
  47. .chip_writew = fallback_chip_writew,
  48. .chip_writel = fallback_chip_writel,
  49. .chip_writen = fallback_chip_writen,
  50. };
  51. static int satamv_shutdown(void *data)
  52. {
  53. physunmap(mv_bar, 0x20000);
  54. pci_cleanup(pacc);
  55. release_io_perms();
  56. return 0;
  57. }
  58. /*
  59. * Random notes:
  60. * FCE# Flash Chip Enable
  61. * FWE# Flash Write Enable
  62. * FOE# Flash Output Enable
  63. * FALE[1:0] Flash Address Latch Enable
  64. * FAD[7:0] Flash Multiplexed Address/Data Bus
  65. * FA[2:0] Flash Address Low
  66. *
  67. * GPIO[15,2] GPIO Port Mode
  68. * GPIO[4:3] Flash Size
  69. *
  70. * 0xd2c Expansion ROM BAR Control
  71. * 0xc08 PCI BAR2 (Flash/NVRAM) Control
  72. * 0x1046c Flash Parameters
  73. */
  74. int satamv_init(void)
  75. {
  76. uintptr_t addr;
  77. uint32_t tmp;
  78. get_io_perms();
  79. /* BAR0 has all internal registers memory mapped. */
  80. /* No need to check for errors, pcidev_init() will not return in case
  81. * of errors.
  82. */
  83. addr = pcidev_init(PCI_BASE_ADDRESS_0, satas_mv);
  84. mv_bar = physmap("Marvell 88SX7042 registers", addr, 0x20000);
  85. if (mv_bar == ERROR_PTR)
  86. goto error_out;
  87. if (register_shutdown(satamv_shutdown, NULL))
  88. return 1;
  89. tmp = pci_mmio_readl(mv_bar + FLASH_PARAM);
  90. msg_pspew("Flash Parameters:\n");
  91. msg_pspew("TurnOff=0x%01x\n", (tmp >> 0) & 0x7);
  92. msg_pspew("Acc2First=0x%01x\n", (tmp >> 3) & 0xf);
  93. msg_pspew("Acc2Next=0x%01x\n", (tmp >> 7) & 0xf);
  94. msg_pspew("ALE2Wr=0x%01x\n", (tmp >> 11) & 0x7);
  95. msg_pspew("WrLow=0x%01x\n", (tmp >> 14) & 0x7);
  96. msg_pspew("WrHigh=0x%01x\n", (tmp >> 17) & 0x7);
  97. msg_pspew("Reserved[21:20]=0x%01x\n", (tmp >> 20) & 0x3);
  98. msg_pspew("TurnOffExt=0x%01x\n", (tmp >> 22) & 0x1);
  99. msg_pspew("Acc2FirstExt=0x%01x\n", (tmp >> 23) & 0x1);
  100. msg_pspew("Acc2NextExt=0x%01x\n", (tmp >> 24) & 0x1);
  101. msg_pspew("ALE2WrExt=0x%01x\n", (tmp >> 25) & 0x1);
  102. msg_pspew("WrLowExt=0x%01x\n", (tmp >> 26) & 0x1);
  103. msg_pspew("WrHighExt=0x%01x\n", (tmp >> 27) & 0x1);
  104. msg_pspew("Reserved[31:28]=0x%01x\n", (tmp >> 28) & 0xf);
  105. tmp = pci_mmio_readl(mv_bar + EXPANSION_ROM_BAR_CONTROL);
  106. msg_pspew("Expansion ROM BAR Control:\n");
  107. msg_pspew("ExpROMSz=0x%01x\n", (tmp >> 19) & 0x7);
  108. /* Enable BAR2 mapping to flash */
  109. tmp = pci_mmio_readl(mv_bar + PCI_BAR2_CONTROL);
  110. msg_pspew("PCI BAR2 (Flash/NVRAM) Control:\n");
  111. msg_pspew("Bar2En=0x%01x\n", (tmp >> 0) & 0x1);
  112. msg_pspew("BAR2TransAttr=0x%01x\n", (tmp >> 1) & 0x1f);
  113. msg_pspew("BAR2Sz=0x%01x\n", (tmp >> 19) & 0x7);
  114. tmp &= 0xffffffc0;
  115. tmp |= 0x0000001f;
  116. pci_rmmio_writel(tmp, mv_bar + PCI_BAR2_CONTROL);
  117. /* Enable flash: GPIO Port Control Register 0x104f0 */
  118. tmp = pci_mmio_readl(mv_bar + GPIO_PORT_CONTROL);
  119. msg_pspew("GPIOPortMode=0x%01x\n", (tmp >> 0) & 0x3);
  120. if (((tmp >> 0) & 0x3) != 0x2)
  121. msg_pinfo("Warning! Either the straps are incorrect or you "
  122. "have no flash or someone overwrote the strap "
  123. "values!\n");
  124. tmp &= 0xfffffffc;
  125. tmp |= 0x2;
  126. pci_rmmio_writel(tmp, mv_bar + GPIO_PORT_CONTROL);
  127. /* Get I/O BAR location. */
  128. tmp = pci_read_long(pcidev_dev, PCI_BASE_ADDRESS_2) &
  129. PCI_BASE_ADDRESS_IO_MASK;
  130. /* Truncate to reachable range.
  131. * FIXME: Check if the I/O BAR is actually reachable.
  132. * This is an arch specific check.
  133. */
  134. mv_iobar = tmp & 0xffff;
  135. msg_pspew("Activating I/O BAR at 0x%04x\n", mv_iobar);
  136. /* 512 kByte with two 8-bit latches, and
  137. * 4 MByte with additional 3-bit latch. */
  138. max_rom_decode.parallel = 4 * 1024 * 1024;
  139. register_par_programmer(&par_programmer_satamv, BUS_PARALLEL);
  140. return 0;
  141. error_out:
  142. pci_cleanup(pacc);
  143. release_io_perms();
  144. return 1;
  145. }
  146. /* BAR2 (MEM) can map NVRAM and flash. We set it to flash in the init function.
  147. * If BAR2 is disabled, it still can be accessed indirectly via BAR1 (I/O).
  148. * This code only supports indirect accesses for now.
  149. */
  150. /* Indirect access to via the I/O BAR1. */
  151. static void satamv_indirect_chip_writeb(uint8_t val, chipaddr addr)
  152. {
  153. /* 0x80000000 selects BAR2 for remapping. */
  154. OUTL(((uint32_t)addr | 0x80000000) & 0xfffffffc, mv_iobar);
  155. OUTB(val, mv_iobar + 0x80 + (addr & 0x3));
  156. }
  157. /* Indirect access to via the I/O BAR1. */
  158. static uint8_t satamv_indirect_chip_readb(const chipaddr addr)
  159. {
  160. /* 0x80000000 selects BAR2 for remapping. */
  161. OUTL(((uint32_t)addr | 0x80000000) & 0xfffffffc, mv_iobar);
  162. return INB(mv_iobar + 0x80 + (addr & 0x3));
  163. }
  164. /* FIXME: Prefer direct access to BAR2 if BAR2 is active. */
  165. void satamv_chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
  166. {
  167. satamv_indirect_chip_writeb(val, addr);
  168. }
  169. /* FIXME: Prefer direct access to BAR2 if BAR2 is active. */
  170. uint8_t satamv_chip_readb(const struct flashctx *flash, const chipaddr addr)
  171. {
  172. return satamv_indirect_chip_readb(addr);
  173. }
  174. #else
  175. #error PCI port I/O access is not supported on this architecture yet.
  176. #endif