mv_chips.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Marvell 88SE64xx/88SE94xx register IO interface
  4. *
  5. * Copyright 2007 Red Hat, Inc.
  6. * Copyright 2008 Marvell. <[email protected]>
  7. * Copyright 2009-2011 Marvell. <[email protected]>
  8. */
  9. #ifndef _MV_CHIPS_H_
  10. #define _MV_CHIPS_H_
  11. #define mr32(reg) readl(regs + reg)
  12. #define mw32(reg, val) writel((val), regs + reg)
  13. #define mw32_f(reg, val) do { \
  14. mw32(reg, val); \
  15. mr32(reg); \
  16. } while (0)
  17. #define iow32(reg, val) outl(val, (unsigned long)(regs + reg))
  18. #define ior32(reg) inl((unsigned long)(regs + reg))
  19. #define iow16(reg, val) outw((unsigned long)(val, regs + reg))
  20. #define ior16(reg) inw((unsigned long)(regs + reg))
  21. #define iow8(reg, val) outb((unsigned long)(val, regs + reg))
  22. #define ior8(reg) inb((unsigned long)(regs + reg))
  23. static inline u32 mvs_cr32(struct mvs_info *mvi, u32 addr)
  24. {
  25. void __iomem *regs = mvi->regs;
  26. mw32(MVS_CMD_ADDR, addr);
  27. return mr32(MVS_CMD_DATA);
  28. }
  29. static inline void mvs_cw32(struct mvs_info *mvi, u32 addr, u32 val)
  30. {
  31. void __iomem *regs = mvi->regs;
  32. mw32(MVS_CMD_ADDR, addr);
  33. mw32(MVS_CMD_DATA, val);
  34. }
  35. static inline u32 mvs_read_phy_ctl(struct mvs_info *mvi, u32 port)
  36. {
  37. void __iomem *regs = mvi->regs;
  38. return (port < 4) ? mr32(MVS_P0_SER_CTLSTAT + port * 4) :
  39. mr32(MVS_P4_SER_CTLSTAT + (port - 4) * 4);
  40. }
  41. static inline void mvs_write_phy_ctl(struct mvs_info *mvi, u32 port, u32 val)
  42. {
  43. void __iomem *regs = mvi->regs;
  44. if (port < 4)
  45. mw32(MVS_P0_SER_CTLSTAT + port * 4, val);
  46. else
  47. mw32(MVS_P4_SER_CTLSTAT + (port - 4) * 4, val);
  48. }
  49. static inline u32 mvs_read_port(struct mvs_info *mvi, u32 off,
  50. u32 off2, u32 port)
  51. {
  52. void __iomem *regs = mvi->regs + off;
  53. void __iomem *regs2 = mvi->regs + off2;
  54. return (port < 4) ? readl(regs + port * 8) :
  55. readl(regs2 + (port - 4) * 8);
  56. }
  57. static inline void mvs_write_port(struct mvs_info *mvi, u32 off, u32 off2,
  58. u32 port, u32 val)
  59. {
  60. void __iomem *regs = mvi->regs + off;
  61. void __iomem *regs2 = mvi->regs + off2;
  62. if (port < 4)
  63. writel(val, regs + port * 8);
  64. else
  65. writel(val, regs2 + (port - 4) * 8);
  66. }
  67. static inline u32 mvs_read_port_cfg_data(struct mvs_info *mvi, u32 port)
  68. {
  69. return mvs_read_port(mvi, MVS_P0_CFG_DATA,
  70. MVS_P4_CFG_DATA, port);
  71. }
  72. static inline void mvs_write_port_cfg_data(struct mvs_info *mvi,
  73. u32 port, u32 val)
  74. {
  75. mvs_write_port(mvi, MVS_P0_CFG_DATA,
  76. MVS_P4_CFG_DATA, port, val);
  77. }
  78. static inline void mvs_write_port_cfg_addr(struct mvs_info *mvi,
  79. u32 port, u32 addr)
  80. {
  81. mvs_write_port(mvi, MVS_P0_CFG_ADDR,
  82. MVS_P4_CFG_ADDR, port, addr);
  83. mdelay(10);
  84. }
  85. static inline u32 mvs_read_port_vsr_data(struct mvs_info *mvi, u32 port)
  86. {
  87. return mvs_read_port(mvi, MVS_P0_VSR_DATA,
  88. MVS_P4_VSR_DATA, port);
  89. }
  90. static inline void mvs_write_port_vsr_data(struct mvs_info *mvi,
  91. u32 port, u32 val)
  92. {
  93. mvs_write_port(mvi, MVS_P0_VSR_DATA,
  94. MVS_P4_VSR_DATA, port, val);
  95. }
  96. static inline void mvs_write_port_vsr_addr(struct mvs_info *mvi,
  97. u32 port, u32 addr)
  98. {
  99. mvs_write_port(mvi, MVS_P0_VSR_ADDR,
  100. MVS_P4_VSR_ADDR, port, addr);
  101. mdelay(10);
  102. }
  103. static inline u32 mvs_read_port_irq_stat(struct mvs_info *mvi, u32 port)
  104. {
  105. return mvs_read_port(mvi, MVS_P0_INT_STAT,
  106. MVS_P4_INT_STAT, port);
  107. }
  108. static inline void mvs_write_port_irq_stat(struct mvs_info *mvi,
  109. u32 port, u32 val)
  110. {
  111. mvs_write_port(mvi, MVS_P0_INT_STAT,
  112. MVS_P4_INT_STAT, port, val);
  113. }
  114. static inline u32 mvs_read_port_irq_mask(struct mvs_info *mvi, u32 port)
  115. {
  116. return mvs_read_port(mvi, MVS_P0_INT_MASK,
  117. MVS_P4_INT_MASK, port);
  118. }
  119. static inline void mvs_write_port_irq_mask(struct mvs_info *mvi,
  120. u32 port, u32 val)
  121. {
  122. mvs_write_port(mvi, MVS_P0_INT_MASK,
  123. MVS_P4_INT_MASK, port, val);
  124. }
  125. static inline void mvs_phy_hacks(struct mvs_info *mvi)
  126. {
  127. u32 tmp;
  128. tmp = mvs_cr32(mvi, CMD_PHY_TIMER);
  129. tmp &= ~(1 << 9);
  130. tmp |= (1 << 10);
  131. mvs_cw32(mvi, CMD_PHY_TIMER, tmp);
  132. /* enable retry 127 times */
  133. mvs_cw32(mvi, CMD_SAS_CTL1, 0x7f7f);
  134. /* extend open frame timeout to max */
  135. tmp = mvs_cr32(mvi, CMD_SAS_CTL0);
  136. tmp &= ~0xffff;
  137. tmp |= 0x3fff;
  138. mvs_cw32(mvi, CMD_SAS_CTL0, tmp);
  139. mvs_cw32(mvi, CMD_WD_TIMER, 0x7a0000);
  140. /* not to halt for different port op during wideport link change */
  141. mvs_cw32(mvi, CMD_APP_ERR_CONFIG, 0xffefbf7d);
  142. }
  143. static inline void mvs_int_sata(struct mvs_info *mvi)
  144. {
  145. u32 tmp;
  146. void __iomem *regs = mvi->regs;
  147. tmp = mr32(MVS_INT_STAT_SRS_0);
  148. if (tmp)
  149. mw32(MVS_INT_STAT_SRS_0, tmp);
  150. MVS_CHIP_DISP->clear_active_cmds(mvi);
  151. }
  152. static inline void mvs_int_full(struct mvs_info *mvi)
  153. {
  154. void __iomem *regs = mvi->regs;
  155. u32 tmp, stat;
  156. int i;
  157. stat = mr32(MVS_INT_STAT);
  158. mvs_int_rx(mvi, false);
  159. for (i = 0; i < mvi->chip->n_phy; i++) {
  160. tmp = (stat >> i) & (CINT_PORT | CINT_PORT_STOPPED);
  161. if (tmp)
  162. mvs_int_port(mvi, i, tmp);
  163. }
  164. if (stat & CINT_NON_SPEC_NCQ_ERROR)
  165. MVS_CHIP_DISP->non_spec_ncq_error(mvi);
  166. if (stat & CINT_SRS)
  167. mvs_int_sata(mvi);
  168. mw32(MVS_INT_STAT, stat);
  169. }
  170. static inline void mvs_start_delivery(struct mvs_info *mvi, u32 tx)
  171. {
  172. void __iomem *regs = mvi->regs;
  173. mw32(MVS_TX_PROD_IDX, tx);
  174. }
  175. static inline u32 mvs_rx_update(struct mvs_info *mvi)
  176. {
  177. void __iomem *regs = mvi->regs;
  178. return mr32(MVS_RX_CONS_IDX);
  179. }
  180. static inline u32 mvs_get_prd_size(void)
  181. {
  182. return sizeof(struct mvs_prd);
  183. }
  184. static inline u32 mvs_get_prd_count(void)
  185. {
  186. return MAX_SG_ENTRY;
  187. }
  188. static inline void mvs_show_pcie_usage(struct mvs_info *mvi)
  189. {
  190. u16 link_stat, link_spd;
  191. const char *spd[] = {
  192. "UnKnown",
  193. "2.5",
  194. "5.0",
  195. };
  196. if (mvi->flags & MVF_FLAG_SOC || mvi->id > 0)
  197. return;
  198. pci_read_config_word(mvi->pdev, PCR_LINK_STAT, &link_stat);
  199. link_spd = (link_stat & PLS_LINK_SPD) >> PLS_LINK_SPD_OFFS;
  200. if (link_spd >= 3)
  201. link_spd = 0;
  202. dev_printk(KERN_INFO, mvi->dev,
  203. "mvsas: PCI-E x%u, Bandwidth Usage: %s Gbps\n",
  204. (link_stat & PLS_NEG_LINK_WD) >> PLS_NEG_LINK_WD_OFFS,
  205. spd[link_spd]);
  206. }
  207. static inline u32 mvs_hw_max_link_rate(void)
  208. {
  209. return MAX_LINK_RATE;
  210. }
  211. #endif /* _MV_CHIPS_H_ */