phy-qcom-qmp-ufs.c 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2017, The Linux Foundation. All rights reserved.
  4. */
  5. #include <linux/clk.h>
  6. #include <linux/clk-provider.h>
  7. #include <linux/delay.h>
  8. #include <linux/err.h>
  9. #include <linux/io.h>
  10. #include <linux/iopoll.h>
  11. #include <linux/kernel.h>
  12. #include <linux/module.h>
  13. #include <linux/of.h>
  14. #include <linux/of_device.h>
  15. #include <linux/of_address.h>
  16. #include <linux/phy/phy.h>
  17. #include <linux/platform_device.h>
  18. #include <linux/regulator/consumer.h>
  19. #include <linux/reset.h>
  20. #include <linux/slab.h>
  21. #include <dt-bindings/phy/phy.h>
  22. #include "phy-qcom-qmp.h"
  23. /* QPHY_SW_RESET bit */
  24. #define SW_RESET BIT(0)
  25. /* QPHY_POWER_DOWN_CONTROL */
  26. #define SW_PWRDN BIT(0)
  27. /* QPHY_START_CONTROL bits */
  28. #define SERDES_START BIT(0)
  29. #define PCS_START BIT(1)
  30. /* QPHY_PCS_STATUS bit */
  31. #define PHYSTATUS BIT(6)
  32. /* QPHY_PCS_READY_STATUS bit */
  33. #define PCS_READY BIT(0)
  34. #define PHY_INIT_COMPLETE_TIMEOUT 10000
  35. struct qmp_phy_init_tbl {
  36. unsigned int offset;
  37. unsigned int val;
  38. /*
  39. * register part of layout ?
  40. * if yes, then offset gives index in the reg-layout
  41. */
  42. bool in_layout;
  43. /*
  44. * mask of lanes for which this register is written
  45. * for cases when second lane needs different values
  46. */
  47. u8 lane_mask;
  48. };
  49. #define QMP_PHY_INIT_CFG(o, v) \
  50. { \
  51. .offset = o, \
  52. .val = v, \
  53. .lane_mask = 0xff, \
  54. }
  55. #define QMP_PHY_INIT_CFG_L(o, v) \
  56. { \
  57. .offset = o, \
  58. .val = v, \
  59. .in_layout = true, \
  60. .lane_mask = 0xff, \
  61. }
  62. #define QMP_PHY_INIT_CFG_LANE(o, v, l) \
  63. { \
  64. .offset = o, \
  65. .val = v, \
  66. .lane_mask = l, \
  67. }
  68. /* set of registers with offsets different per-PHY */
  69. enum qphy_reg_layout {
  70. /* PCS registers */
  71. QPHY_SW_RESET,
  72. QPHY_START_CTRL,
  73. QPHY_PCS_READY_STATUS,
  74. QPHY_PCS_POWER_DOWN_CONTROL,
  75. /* Keep last to ensure regs_layout arrays are properly initialized */
  76. QPHY_LAYOUT_SIZE
  77. };
  78. static const unsigned int msm8996_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
  79. [QPHY_START_CTRL] = 0x00,
  80. [QPHY_PCS_READY_STATUS] = 0x168,
  81. };
  82. static const unsigned int sdm845_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
  83. [QPHY_START_CTRL] = 0x00,
  84. [QPHY_PCS_READY_STATUS] = 0x160,
  85. };
  86. static const unsigned int sm6115_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
  87. [QPHY_START_CTRL] = 0x00,
  88. [QPHY_PCS_READY_STATUS] = 0x168,
  89. };
  90. static const unsigned int sm8150_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
  91. [QPHY_START_CTRL] = QPHY_V4_PCS_UFS_PHY_START,
  92. [QPHY_PCS_READY_STATUS] = QPHY_V4_PCS_UFS_READY_STATUS,
  93. [QPHY_SW_RESET] = QPHY_V4_PCS_UFS_SW_RESET,
  94. };
  95. static const struct qmp_phy_init_tbl msm8996_ufs_serdes_tbl[] = {
  96. QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e),
  97. QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0xd7),
  98. QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
  99. QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06),
  100. QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
  101. QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
  102. QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x05),
  103. QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
  104. QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a),
  105. QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01),
  106. QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x10),
  107. QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
  108. QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
  109. QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
  110. QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
  111. QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f),
  112. QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x54),
  113. QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05),
  114. QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
  115. QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
  116. QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00),
  117. QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00),
  118. QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
  119. QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
  120. QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
  121. QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
  122. QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
  123. QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x28),
  124. QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02),
  125. QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff),
  126. QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c),
  127. QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
  128. QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98),
  129. QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00),
  130. QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00),
  131. QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00),
  132. QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b),
  133. QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16),
  134. QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28),
  135. QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80),
  136. QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
  137. QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6),
  138. QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00),
  139. QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32),
  140. QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f),
  141. QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00),
  142. };
  143. static const struct qmp_phy_init_tbl msm8996_ufs_tx_tbl[] = {
  144. QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
  145. QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x02),
  146. };
  147. static const struct qmp_phy_init_tbl msm8996_ufs_rx_tbl[] = {
  148. QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24),
  149. QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x02),
  150. QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x00),
  151. QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x18),
  152. QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B),
  153. QMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5b),
  154. QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xff),
  155. QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3f),
  156. QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xff),
  157. QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x0f),
  158. QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0E),
  159. };
  160. static const struct qmp_phy_init_tbl sm6115_ufsphy_serdes_tbl[] = {
  161. QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e),
  162. QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
  163. QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
  164. QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x02),
  165. QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
  166. QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
  167. QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
  168. QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
  169. QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a),
  170. QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01),
  171. QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00),
  172. QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
  173. QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
  174. QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
  175. QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
  176. QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f),
  177. QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x04),
  178. QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05),
  179. QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
  180. QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
  181. QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00),
  182. QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00),
  183. QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
  184. QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
  185. QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
  186. QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
  187. QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
  188. QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x28),
  189. QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02),
  190. QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff),
  191. QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c),
  192. QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
  193. QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98),
  194. QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00),
  195. QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00),
  196. QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00),
  197. QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b),
  198. QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16),
  199. QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28),
  200. QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80),
  201. QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
  202. QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6),
  203. QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00),
  204. QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32),
  205. QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f),
  206. QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00),
  207. QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
  208. QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
  209. QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL1, 0xff),
  210. QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL2, 0x00),
  211. /* Rate B */
  212. QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x44),
  213. };
  214. static const struct qmp_phy_init_tbl sm6115_ufsphy_tx_tbl[] = {
  215. QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
  216. QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),
  217. };
  218. static const struct qmp_phy_init_tbl sm6115_ufsphy_rx_tbl[] = {
  219. QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24),
  220. QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x0F),
  221. QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x40),
  222. QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x1E),
  223. QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B),
  224. QMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5B),
  225. QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xFF),
  226. QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3F),
  227. QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xFF),
  228. QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x3F),
  229. QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0D),
  230. QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),
  231. QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),
  232. QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN, 0x04),
  233. QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5B),
  234. };
  235. static const struct qmp_phy_init_tbl sm6115_ufsphy_pcs_tbl[] = {
  236. QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_PWM_GEAR_BAND, 0x15),
  237. QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_SIGDET_CTRL2, 0x6d),
  238. QMP_PHY_INIT_CFG(QPHY_V2_PCS_TX_LARGE_AMP_DRV_LVL, 0x0f),
  239. QMP_PHY_INIT_CFG(QPHY_V2_PCS_TX_SMALL_AMP_DRV_LVL, 0x02),
  240. QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_MIN_STALL_NOCONFIG_TIME_CAP, 0x28),
  241. QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_SYM_RESYNC_CTRL, 0x03),
  242. QMP_PHY_INIT_CFG(QPHY_V2_PCS_TX_LARGE_AMP_POST_EMP_LVL, 0x12),
  243. QMP_PHY_INIT_CFG(QPHY_V2_PCS_TX_SMALL_AMP_POST_EMP_LVL, 0x0f),
  244. QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_MIN_HIBERN8_TIME, 0x9a), /* 8 us */
  245. };
  246. static const struct qmp_phy_init_tbl sdm845_ufsphy_serdes_tbl[] = {
  247. QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
  248. QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
  249. QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),
  250. QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
  251. QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
  252. QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0xd5),
  253. QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL, 0x20),
  254. QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
  255. QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
  256. QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x01),
  257. QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_CTRL, 0x00),
  258. QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
  259. QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x04),
  260. QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x05),
  261. QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL1, 0xff),
  262. QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL2, 0x00),
  263. QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
  264. QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
  265. QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
  266. QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
  267. QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
  268. QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
  269. QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xda),
  270. QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
  271. QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0xff),
  272. QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0c),
  273. QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE1, 0x98),
  274. QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE1, 0x06),
  275. QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE1, 0x16),
  276. QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE1, 0x36),
  277. QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE1, 0x3f),
  278. QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
  279. QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE1, 0xc1),
  280. QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE1, 0x00),
  281. QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE1, 0x32),
  282. QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE1, 0x0f),
  283. /* Rate B */
  284. QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x44),
  285. };
  286. static const struct qmp_phy_init_tbl sdm845_ufsphy_tx_tbl[] = {
  287. QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06),
  288. QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x04),
  289. QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x07),
  290. };
  291. static const struct qmp_phy_init_tbl sdm845_ufsphy_rx_tbl[] = {
  292. QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_LVL, 0x24),
  293. QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x0f),
  294. QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
  295. QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40),
  296. QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
  297. QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_TERM_BW, 0x5b),
  298. QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
  299. QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
  300. QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1b),
  301. QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),
  302. QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),
  303. QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN, 0x04),
  304. QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
  305. QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x81),
  306. QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
  307. QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x59),
  308. };
  309. static const struct qmp_phy_init_tbl sdm845_ufsphy_pcs_tbl[] = {
  310. QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SIGDET_CTRL2, 0x6e),
  311. QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
  312. QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
  313. QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SYM_RESYNC_CTRL, 0x03),
  314. QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
  315. QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SIGDET_CTRL1, 0x0f),
  316. QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_MIN_HIBERN8_TIME, 0x9a),
  317. QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
  318. };
  319. static const struct qmp_phy_init_tbl sm8150_ufsphy_serdes_tbl[] = {
  320. QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0xd9),
  321. QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x11),
  322. QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL, 0x00),
  323. QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x01),
  324. QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
  325. QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
  326. QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_INITVAL2, 0x00),
  327. QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
  328. QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
  329. QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
  330. QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
  331. QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
  332. QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0xff),
  333. QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x0c),
  334. QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac),
  335. QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
  336. QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x98),
  337. QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
  338. QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
  339. QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
  340. QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x32),
  341. QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x0f),
  342. QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd),
  343. QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23),
  344. /* Rate B */
  345. QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x06),
  346. };
  347. static const struct qmp_phy_init_tbl sm8150_ufsphy_tx_tbl[] = {
  348. QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),
  349. QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),
  350. QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),
  351. QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00),
  352. QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x05),
  353. QMP_PHY_INIT_CFG(QSERDES_V4_TX_TRAN_DRVR_EMP_EN, 0x0c),
  354. };
  355. static const struct qmp_phy_init_tbl sm8150_ufsphy_rx_tbl[] = {
  356. QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_LVL, 0x24),
  357. QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x0f),
  358. QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
  359. QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_BAND, 0x18),
  360. QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
  361. QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
  362. QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0xf1),
  363. QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
  364. QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x80),
  365. QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
  366. QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x04),
  367. QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x1b),
  368. QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
  369. QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
  370. QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1d),
  371. QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
  372. QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x10),
  373. QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
  374. QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
  375. QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x36),
  376. QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x36),
  377. QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xf6),
  378. QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x3b),
  379. QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x3d),
  380. QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xe0),
  381. QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xc8),
  382. QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xc8),
  383. QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b),
  384. QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb1),
  385. QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xe0),
  386. QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0xc8),
  387. QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xc8),
  388. QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),
  389. QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0xb1),
  390. };
  391. static const struct qmp_phy_init_tbl sm8150_ufsphy_pcs_tbl[] = {
  392. QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
  393. QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
  394. QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
  395. QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
  396. QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f),
  397. QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),
  398. QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
  399. };
  400. static const struct qmp_phy_init_tbl sm8350_ufsphy_serdes_tbl[] = {
  401. QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0xd9),
  402. QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_SEL, 0x11),
  403. QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_HS_SWITCH_SEL, 0x00),
  404. QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_EN, 0x42),
  405. QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x02),
  406. QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f),
  407. QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_INITVAL2, 0x00),
  408. QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
  409. QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE0, 0x82),
  410. QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE0, 0x14),
  411. QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x18),
  412. QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x18),
  413. QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE0, 0xff),
  414. QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x19),
  415. QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac),
  416. QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
  417. QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE1, 0x98),
  418. QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE1, 0x14),
  419. QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE1, 0x18),
  420. QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE1, 0x18),
  421. QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE1, 0x65),
  422. QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE1, 0x1e),
  423. QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd),
  424. QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23),
  425. /* Rate B */
  426. QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x06),
  427. };
  428. static const struct qmp_phy_init_tbl sm8350_ufsphy_tx_tbl[] = {
  429. QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),
  430. QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),
  431. QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),
  432. QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00),
  433. QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xf5),
  434. QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f),
  435. QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x09),
  436. QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x09),
  437. QMP_PHY_INIT_CFG(QSERDES_V5_TX_TRAN_DRVR_EMP_EN, 0x0c),
  438. };
  439. static const struct qmp_phy_init_tbl sm8350_ufsphy_rx_tbl[] = {
  440. QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_LVL, 0x24),
  441. QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x0f),
  442. QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
  443. QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_BAND, 0x18),
  444. QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
  445. QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a),
  446. QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0xf1),
  447. QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
  448. QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CTRL2, 0x80),
  449. QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0e),
  450. QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x04),
  451. QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_TERM_BW, 0x1b),
  452. QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04),
  453. QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
  454. QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
  455. QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1a),
  456. QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
  457. QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
  458. QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_MEASURE_TIME, 0x10),
  459. QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
  460. QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
  461. QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0x6d),
  462. QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x6d),
  463. QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xed),
  464. QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3b),
  465. QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0x3c),
  466. QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0xe0),
  467. QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0xc8),
  468. QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xc8),
  469. QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x3b),
  470. QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xb7),
  471. QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_LOW, 0xe0),
  472. QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH, 0xc8),
  473. QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH2, 0xc8),
  474. QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH3, 0x3b),
  475. QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH4, 0xb7),
  476. QMP_PHY_INIT_CFG(QSERDES_V5_RX_DCC_CTRL1, 0x0c),
  477. };
  478. static const struct qmp_phy_init_tbl sm8350_ufsphy_pcs_tbl[] = {
  479. QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
  480. QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
  481. QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
  482. QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
  483. QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f),
  484. QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),
  485. QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_PLL_CNTL, 0x03),
  486. QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TIMER_20US_CORECLK_STEPS_MSB, 0x16),
  487. QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TIMER_20US_CORECLK_STEPS_LSB, 0xd8),
  488. QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_PWM_GEAR_BAND, 0xaa),
  489. QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_HS_GEAR_BAND, 0x06),
  490. QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x03),
  491. QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x03),
  492. QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_SIGDET_CTRL1, 0x0e),
  493. QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
  494. };
  495. /* struct qmp_phy_cfg - per-PHY initialization config */
  496. struct qmp_phy_cfg {
  497. int lanes;
  498. /* Init sequence for PHY blocks - serdes, tx, rx, pcs */
  499. const struct qmp_phy_init_tbl *serdes_tbl;
  500. int serdes_tbl_num;
  501. const struct qmp_phy_init_tbl *tx_tbl;
  502. int tx_tbl_num;
  503. const struct qmp_phy_init_tbl *rx_tbl;
  504. int rx_tbl_num;
  505. const struct qmp_phy_init_tbl *pcs_tbl;
  506. int pcs_tbl_num;
  507. /* clock ids to be requested */
  508. const char * const *clk_list;
  509. int num_clks;
  510. /* regulators to be requested */
  511. const char * const *vreg_list;
  512. int num_vregs;
  513. /* array of registers with different offsets */
  514. const unsigned int *regs;
  515. unsigned int start_ctrl;
  516. unsigned int pwrdn_ctrl;
  517. /* bit offset of PHYSTATUS in QPHY_PCS_STATUS register */
  518. unsigned int phy_status;
  519. /* true, if PCS block has no separate SW_RESET register */
  520. bool no_pcs_sw_reset;
  521. };
  522. /**
  523. * struct qmp_phy - per-lane phy descriptor
  524. *
  525. * @phy: generic phy
  526. * @cfg: phy specific configuration
  527. * @serdes: iomapped memory space for phy's serdes (i.e. PLL)
  528. * @tx: iomapped memory space for lane's tx
  529. * @rx: iomapped memory space for lane's rx
  530. * @pcs: iomapped memory space for lane's pcs
  531. * @tx2: iomapped memory space for second lane's tx (in dual lane PHYs)
  532. * @rx2: iomapped memory space for second lane's rx (in dual lane PHYs)
  533. * @pcs_misc: iomapped memory space for lane's pcs_misc
  534. * @qmp: QMP phy to which this lane belongs
  535. */
  536. struct qmp_phy {
  537. struct phy *phy;
  538. const struct qmp_phy_cfg *cfg;
  539. void __iomem *serdes;
  540. void __iomem *tx;
  541. void __iomem *rx;
  542. void __iomem *pcs;
  543. void __iomem *tx2;
  544. void __iomem *rx2;
  545. void __iomem *pcs_misc;
  546. struct qcom_qmp *qmp;
  547. };
  548. /**
  549. * struct qcom_qmp - structure holding QMP phy block attributes
  550. *
  551. * @dev: device
  552. *
  553. * @clks: array of clocks required by phy
  554. * @resets: array of resets required by phy
  555. * @vregs: regulator supplies bulk data
  556. *
  557. * @phys: array of per-lane phy descriptors
  558. * @ufs_reset: optional UFS PHY reset handle
  559. */
  560. struct qcom_qmp {
  561. struct device *dev;
  562. struct clk_bulk_data *clks;
  563. struct regulator_bulk_data *vregs;
  564. struct qmp_phy **phys;
  565. struct reset_control *ufs_reset;
  566. };
  567. static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
  568. {
  569. u32 reg;
  570. reg = readl(base + offset);
  571. reg |= val;
  572. writel(reg, base + offset);
  573. /* ensure that above write is through */
  574. readl(base + offset);
  575. }
  576. static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
  577. {
  578. u32 reg;
  579. reg = readl(base + offset);
  580. reg &= ~val;
  581. writel(reg, base + offset);
  582. /* ensure that above write is through */
  583. readl(base + offset);
  584. }
  585. /* list of clocks required by phy */
  586. static const char * const msm8996_ufs_phy_clk_l[] = {
  587. "ref",
  588. };
  589. /* the primary usb3 phy on sm8250 doesn't have a ref clock */
  590. static const char * const sm8450_ufs_phy_clk_l[] = {
  591. "qref", "ref", "ref_aux",
  592. };
  593. static const char * const sdm845_ufs_phy_clk_l[] = {
  594. "ref", "ref_aux",
  595. };
  596. /* list of regulators */
  597. static const char * const qmp_phy_vreg_l[] = {
  598. "vdda-phy", "vdda-pll",
  599. };
  600. static const struct qmp_phy_cfg msm8996_ufs_cfg = {
  601. .lanes = 1,
  602. .serdes_tbl = msm8996_ufs_serdes_tbl,
  603. .serdes_tbl_num = ARRAY_SIZE(msm8996_ufs_serdes_tbl),
  604. .tx_tbl = msm8996_ufs_tx_tbl,
  605. .tx_tbl_num = ARRAY_SIZE(msm8996_ufs_tx_tbl),
  606. .rx_tbl = msm8996_ufs_rx_tbl,
  607. .rx_tbl_num = ARRAY_SIZE(msm8996_ufs_rx_tbl),
  608. .clk_list = msm8996_ufs_phy_clk_l,
  609. .num_clks = ARRAY_SIZE(msm8996_ufs_phy_clk_l),
  610. .vreg_list = qmp_phy_vreg_l,
  611. .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
  612. .regs = msm8996_ufsphy_regs_layout,
  613. .start_ctrl = SERDES_START,
  614. .pwrdn_ctrl = SW_PWRDN,
  615. .phy_status = PHYSTATUS,
  616. .no_pcs_sw_reset = true,
  617. };
  618. static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {
  619. .lanes = 2,
  620. .serdes_tbl = sdm845_ufsphy_serdes_tbl,
  621. .serdes_tbl_num = ARRAY_SIZE(sdm845_ufsphy_serdes_tbl),
  622. .tx_tbl = sdm845_ufsphy_tx_tbl,
  623. .tx_tbl_num = ARRAY_SIZE(sdm845_ufsphy_tx_tbl),
  624. .rx_tbl = sdm845_ufsphy_rx_tbl,
  625. .rx_tbl_num = ARRAY_SIZE(sdm845_ufsphy_rx_tbl),
  626. .pcs_tbl = sdm845_ufsphy_pcs_tbl,
  627. .pcs_tbl_num = ARRAY_SIZE(sdm845_ufsphy_pcs_tbl),
  628. .clk_list = sdm845_ufs_phy_clk_l,
  629. .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
  630. .vreg_list = qmp_phy_vreg_l,
  631. .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
  632. .regs = sdm845_ufsphy_regs_layout,
  633. .start_ctrl = SERDES_START,
  634. .pwrdn_ctrl = SW_PWRDN,
  635. .phy_status = PHYSTATUS,
  636. .no_pcs_sw_reset = true,
  637. };
  638. static const struct qmp_phy_cfg sm6115_ufsphy_cfg = {
  639. .lanes = 1,
  640. .serdes_tbl = sm6115_ufsphy_serdes_tbl,
  641. .serdes_tbl_num = ARRAY_SIZE(sm6115_ufsphy_serdes_tbl),
  642. .tx_tbl = sm6115_ufsphy_tx_tbl,
  643. .tx_tbl_num = ARRAY_SIZE(sm6115_ufsphy_tx_tbl),
  644. .rx_tbl = sm6115_ufsphy_rx_tbl,
  645. .rx_tbl_num = ARRAY_SIZE(sm6115_ufsphy_rx_tbl),
  646. .pcs_tbl = sm6115_ufsphy_pcs_tbl,
  647. .pcs_tbl_num = ARRAY_SIZE(sm6115_ufsphy_pcs_tbl),
  648. .clk_list = sdm845_ufs_phy_clk_l,
  649. .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
  650. .vreg_list = qmp_phy_vreg_l,
  651. .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
  652. .regs = sm6115_ufsphy_regs_layout,
  653. .start_ctrl = SERDES_START,
  654. .pwrdn_ctrl = SW_PWRDN,
  655. .no_pcs_sw_reset = true,
  656. };
  657. static const struct qmp_phy_cfg sm8150_ufsphy_cfg = {
  658. .lanes = 2,
  659. .serdes_tbl = sm8150_ufsphy_serdes_tbl,
  660. .serdes_tbl_num = ARRAY_SIZE(sm8150_ufsphy_serdes_tbl),
  661. .tx_tbl = sm8150_ufsphy_tx_tbl,
  662. .tx_tbl_num = ARRAY_SIZE(sm8150_ufsphy_tx_tbl),
  663. .rx_tbl = sm8150_ufsphy_rx_tbl,
  664. .rx_tbl_num = ARRAY_SIZE(sm8150_ufsphy_rx_tbl),
  665. .pcs_tbl = sm8150_ufsphy_pcs_tbl,
  666. .pcs_tbl_num = ARRAY_SIZE(sm8150_ufsphy_pcs_tbl),
  667. .clk_list = sdm845_ufs_phy_clk_l,
  668. .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
  669. .vreg_list = qmp_phy_vreg_l,
  670. .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
  671. .regs = sm8150_ufsphy_regs_layout,
  672. .start_ctrl = SERDES_START,
  673. .pwrdn_ctrl = SW_PWRDN,
  674. .phy_status = PHYSTATUS,
  675. };
  676. static const struct qmp_phy_cfg sm8350_ufsphy_cfg = {
  677. .lanes = 2,
  678. .serdes_tbl = sm8350_ufsphy_serdes_tbl,
  679. .serdes_tbl_num = ARRAY_SIZE(sm8350_ufsphy_serdes_tbl),
  680. .tx_tbl = sm8350_ufsphy_tx_tbl,
  681. .tx_tbl_num = ARRAY_SIZE(sm8350_ufsphy_tx_tbl),
  682. .rx_tbl = sm8350_ufsphy_rx_tbl,
  683. .rx_tbl_num = ARRAY_SIZE(sm8350_ufsphy_rx_tbl),
  684. .pcs_tbl = sm8350_ufsphy_pcs_tbl,
  685. .pcs_tbl_num = ARRAY_SIZE(sm8350_ufsphy_pcs_tbl),
  686. .clk_list = sdm845_ufs_phy_clk_l,
  687. .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
  688. .vreg_list = qmp_phy_vreg_l,
  689. .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
  690. .regs = sm8150_ufsphy_regs_layout,
  691. .start_ctrl = SERDES_START,
  692. .pwrdn_ctrl = SW_PWRDN,
  693. .phy_status = PHYSTATUS,
  694. };
  695. static const struct qmp_phy_cfg sm8450_ufsphy_cfg = {
  696. .lanes = 2,
  697. .serdes_tbl = sm8350_ufsphy_serdes_tbl,
  698. .serdes_tbl_num = ARRAY_SIZE(sm8350_ufsphy_serdes_tbl),
  699. .tx_tbl = sm8350_ufsphy_tx_tbl,
  700. .tx_tbl_num = ARRAY_SIZE(sm8350_ufsphy_tx_tbl),
  701. .rx_tbl = sm8350_ufsphy_rx_tbl,
  702. .rx_tbl_num = ARRAY_SIZE(sm8350_ufsphy_rx_tbl),
  703. .pcs_tbl = sm8350_ufsphy_pcs_tbl,
  704. .pcs_tbl_num = ARRAY_SIZE(sm8350_ufsphy_pcs_tbl),
  705. .clk_list = sm8450_ufs_phy_clk_l,
  706. .num_clks = ARRAY_SIZE(sm8450_ufs_phy_clk_l),
  707. .vreg_list = qmp_phy_vreg_l,
  708. .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
  709. .regs = sm8150_ufsphy_regs_layout,
  710. .start_ctrl = SERDES_START,
  711. .pwrdn_ctrl = SW_PWRDN,
  712. .phy_status = PHYSTATUS,
  713. };
  714. static void qmp_ufs_configure_lane(void __iomem *base,
  715. const unsigned int *regs,
  716. const struct qmp_phy_init_tbl tbl[],
  717. int num,
  718. u8 lane_mask)
  719. {
  720. int i;
  721. const struct qmp_phy_init_tbl *t = tbl;
  722. if (!t)
  723. return;
  724. for (i = 0; i < num; i++, t++) {
  725. if (!(t->lane_mask & lane_mask))
  726. continue;
  727. if (t->in_layout)
  728. writel(t->val, base + regs[t->offset]);
  729. else
  730. writel(t->val, base + t->offset);
  731. }
  732. }
  733. static void qmp_ufs_configure(void __iomem *base,
  734. const unsigned int *regs,
  735. const struct qmp_phy_init_tbl tbl[],
  736. int num)
  737. {
  738. qmp_ufs_configure_lane(base, regs, tbl, num, 0xff);
  739. }
  740. static int qmp_ufs_serdes_init(struct qmp_phy *qphy)
  741. {
  742. const struct qmp_phy_cfg *cfg = qphy->cfg;
  743. void __iomem *serdes = qphy->serdes;
  744. const struct qmp_phy_init_tbl *serdes_tbl = cfg->serdes_tbl;
  745. int serdes_tbl_num = cfg->serdes_tbl_num;
  746. qmp_ufs_configure(serdes, cfg->regs, serdes_tbl, serdes_tbl_num);
  747. return 0;
  748. }
  749. static int qmp_ufs_com_init(struct qmp_phy *qphy)
  750. {
  751. struct qcom_qmp *qmp = qphy->qmp;
  752. const struct qmp_phy_cfg *cfg = qphy->cfg;
  753. void __iomem *pcs = qphy->pcs;
  754. int ret;
  755. /* turn on regulator supplies */
  756. ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs);
  757. if (ret) {
  758. dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret);
  759. return ret;
  760. }
  761. ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
  762. if (ret)
  763. goto err_disable_regulators;
  764. if (cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL])
  765. qphy_setbits(pcs,
  766. cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
  767. cfg->pwrdn_ctrl);
  768. else
  769. qphy_setbits(pcs, QPHY_V2_PCS_POWER_DOWN_CONTROL,
  770. cfg->pwrdn_ctrl);
  771. return 0;
  772. err_disable_regulators:
  773. regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
  774. return ret;
  775. }
  776. static int qmp_ufs_com_exit(struct qmp_phy *qphy)
  777. {
  778. struct qcom_qmp *qmp = qphy->qmp;
  779. const struct qmp_phy_cfg *cfg = qphy->cfg;
  780. reset_control_assert(qmp->ufs_reset);
  781. clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
  782. regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
  783. return 0;
  784. }
  785. static int qmp_ufs_init(struct phy *phy)
  786. {
  787. struct qmp_phy *qphy = phy_get_drvdata(phy);
  788. struct qcom_qmp *qmp = qphy->qmp;
  789. const struct qmp_phy_cfg *cfg = qphy->cfg;
  790. int ret;
  791. dev_vdbg(qmp->dev, "Initializing QMP phy\n");
  792. if (cfg->no_pcs_sw_reset) {
  793. /*
  794. * Get UFS reset, which is delayed until now to avoid a
  795. * circular dependency where UFS needs its PHY, but the PHY
  796. * needs this UFS reset.
  797. */
  798. if (!qmp->ufs_reset) {
  799. qmp->ufs_reset =
  800. devm_reset_control_get_exclusive(qmp->dev,
  801. "ufsphy");
  802. if (IS_ERR(qmp->ufs_reset)) {
  803. ret = PTR_ERR(qmp->ufs_reset);
  804. dev_err(qmp->dev,
  805. "failed to get UFS reset: %d\n",
  806. ret);
  807. qmp->ufs_reset = NULL;
  808. return ret;
  809. }
  810. }
  811. ret = reset_control_assert(qmp->ufs_reset);
  812. if (ret)
  813. return ret;
  814. }
  815. ret = qmp_ufs_com_init(qphy);
  816. if (ret)
  817. return ret;
  818. return 0;
  819. }
  820. static int qmp_ufs_power_on(struct phy *phy)
  821. {
  822. struct qmp_phy *qphy = phy_get_drvdata(phy);
  823. struct qcom_qmp *qmp = qphy->qmp;
  824. const struct qmp_phy_cfg *cfg = qphy->cfg;
  825. void __iomem *tx = qphy->tx;
  826. void __iomem *rx = qphy->rx;
  827. void __iomem *pcs = qphy->pcs;
  828. void __iomem *status;
  829. unsigned int mask, val, ready;
  830. int ret;
  831. qmp_ufs_serdes_init(qphy);
  832. /* Tx, Rx, and PCS configurations */
  833. qmp_ufs_configure_lane(tx, cfg->regs, cfg->tx_tbl, cfg->tx_tbl_num, 1);
  834. if (cfg->lanes >= 2) {
  835. qmp_ufs_configure_lane(qphy->tx2, cfg->regs,
  836. cfg->tx_tbl, cfg->tx_tbl_num, 2);
  837. }
  838. qmp_ufs_configure_lane(rx, cfg->regs, cfg->rx_tbl, cfg->rx_tbl_num, 1);
  839. if (cfg->lanes >= 2) {
  840. qmp_ufs_configure_lane(qphy->rx2, cfg->regs,
  841. cfg->rx_tbl, cfg->rx_tbl_num, 2);
  842. }
  843. qmp_ufs_configure(pcs, cfg->regs, cfg->pcs_tbl, cfg->pcs_tbl_num);
  844. ret = reset_control_deassert(qmp->ufs_reset);
  845. if (ret)
  846. return ret;
  847. /* Pull PHY out of reset state */
  848. if (!cfg->no_pcs_sw_reset)
  849. qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
  850. /* start SerDes and Phy-Coding-Sublayer */
  851. qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
  852. status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
  853. mask = PCS_READY;
  854. ready = PCS_READY;
  855. ret = readl_poll_timeout(status, val, (val & mask) == ready, 10,
  856. PHY_INIT_COMPLETE_TIMEOUT);
  857. if (ret) {
  858. dev_err(qmp->dev, "phy initialization timed-out\n");
  859. return ret;
  860. }
  861. return 0;
  862. }
  863. static int qmp_ufs_power_off(struct phy *phy)
  864. {
  865. struct qmp_phy *qphy = phy_get_drvdata(phy);
  866. const struct qmp_phy_cfg *cfg = qphy->cfg;
  867. /* PHY reset */
  868. if (!cfg->no_pcs_sw_reset)
  869. qphy_setbits(qphy->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
  870. /* stop SerDes and Phy-Coding-Sublayer */
  871. qphy_clrbits(qphy->pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
  872. /* Put PHY into POWER DOWN state: active low */
  873. if (cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL]) {
  874. qphy_clrbits(qphy->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
  875. cfg->pwrdn_ctrl);
  876. } else {
  877. qphy_clrbits(qphy->pcs, QPHY_V2_PCS_POWER_DOWN_CONTROL,
  878. cfg->pwrdn_ctrl);
  879. }
  880. return 0;
  881. }
  882. static int qmp_ufs_exit(struct phy *phy)
  883. {
  884. struct qmp_phy *qphy = phy_get_drvdata(phy);
  885. qmp_ufs_com_exit(qphy);
  886. return 0;
  887. }
  888. static int qmp_ufs_enable(struct phy *phy)
  889. {
  890. int ret;
  891. ret = qmp_ufs_init(phy);
  892. if (ret)
  893. return ret;
  894. ret = qmp_ufs_power_on(phy);
  895. if (ret)
  896. qmp_ufs_exit(phy);
  897. return ret;
  898. }
  899. static int qmp_ufs_disable(struct phy *phy)
  900. {
  901. int ret;
  902. ret = qmp_ufs_power_off(phy);
  903. if (ret)
  904. return ret;
  905. return qmp_ufs_exit(phy);
  906. }
  907. static int qmp_ufs_vreg_init(struct device *dev, const struct qmp_phy_cfg *cfg)
  908. {
  909. struct qcom_qmp *qmp = dev_get_drvdata(dev);
  910. int num = cfg->num_vregs;
  911. int i;
  912. qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);
  913. if (!qmp->vregs)
  914. return -ENOMEM;
  915. for (i = 0; i < num; i++)
  916. qmp->vregs[i].supply = cfg->vreg_list[i];
  917. return devm_regulator_bulk_get(dev, num, qmp->vregs);
  918. }
  919. static int qmp_ufs_clk_init(struct device *dev, const struct qmp_phy_cfg *cfg)
  920. {
  921. struct qcom_qmp *qmp = dev_get_drvdata(dev);
  922. int num = cfg->num_clks;
  923. int i;
  924. qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL);
  925. if (!qmp->clks)
  926. return -ENOMEM;
  927. for (i = 0; i < num; i++)
  928. qmp->clks[i].id = cfg->clk_list[i];
  929. return devm_clk_bulk_get(dev, num, qmp->clks);
  930. }
  931. static const struct phy_ops qcom_qmp_ufs_ops = {
  932. .power_on = qmp_ufs_enable,
  933. .power_off = qmp_ufs_disable,
  934. .owner = THIS_MODULE,
  935. };
  936. static int qmp_ufs_create(struct device *dev, struct device_node *np, int id,
  937. void __iomem *serdes, const struct qmp_phy_cfg *cfg)
  938. {
  939. struct qcom_qmp *qmp = dev_get_drvdata(dev);
  940. struct phy *generic_phy;
  941. struct qmp_phy *qphy;
  942. int ret;
  943. qphy = devm_kzalloc(dev, sizeof(*qphy), GFP_KERNEL);
  944. if (!qphy)
  945. return -ENOMEM;
  946. qphy->cfg = cfg;
  947. qphy->serdes = serdes;
  948. /*
  949. * Get memory resources for each phy lane:
  950. * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2.
  951. * For dual lane PHYs: tx2 -> 3, rx2 -> 4, pcs_misc (optional) -> 5
  952. * For single lane PHYs: pcs_misc (optional) -> 3.
  953. */
  954. qphy->tx = devm_of_iomap(dev, np, 0, NULL);
  955. if (IS_ERR(qphy->tx))
  956. return PTR_ERR(qphy->tx);
  957. qphy->rx = devm_of_iomap(dev, np, 1, NULL);
  958. if (IS_ERR(qphy->rx))
  959. return PTR_ERR(qphy->rx);
  960. qphy->pcs = devm_of_iomap(dev, np, 2, NULL);
  961. if (IS_ERR(qphy->pcs))
  962. return PTR_ERR(qphy->pcs);
  963. if (cfg->lanes >= 2) {
  964. qphy->tx2 = devm_of_iomap(dev, np, 3, NULL);
  965. if (IS_ERR(qphy->tx2))
  966. return PTR_ERR(qphy->tx2);
  967. qphy->rx2 = devm_of_iomap(dev, np, 4, NULL);
  968. if (IS_ERR(qphy->rx2))
  969. return PTR_ERR(qphy->rx2);
  970. qphy->pcs_misc = devm_of_iomap(dev, np, 5, NULL);
  971. } else {
  972. qphy->pcs_misc = devm_of_iomap(dev, np, 3, NULL);
  973. }
  974. if (IS_ERR(qphy->pcs_misc))
  975. dev_vdbg(dev, "PHY pcs_misc-reg not used\n");
  976. generic_phy = devm_phy_create(dev, np, &qcom_qmp_ufs_ops);
  977. if (IS_ERR(generic_phy)) {
  978. ret = PTR_ERR(generic_phy);
  979. dev_err(dev, "failed to create qphy %d\n", ret);
  980. return ret;
  981. }
  982. qphy->phy = generic_phy;
  983. qphy->qmp = qmp;
  984. qmp->phys[id] = qphy;
  985. phy_set_drvdata(generic_phy, qphy);
  986. return 0;
  987. }
  988. static const struct of_device_id qmp_ufs_of_match_table[] = {
  989. {
  990. .compatible = "qcom,msm8996-qmp-ufs-phy",
  991. .data = &msm8996_ufs_cfg,
  992. }, {
  993. .compatible = "qcom,msm8998-qmp-ufs-phy",
  994. .data = &sdm845_ufsphy_cfg,
  995. }, {
  996. .compatible = "qcom,sc8180x-qmp-ufs-phy",
  997. .data = &sm8150_ufsphy_cfg,
  998. }, {
  999. .compatible = "qcom,sc8280xp-qmp-ufs-phy",
  1000. .data = &sm8350_ufsphy_cfg,
  1001. }, {
  1002. .compatible = "qcom,sdm845-qmp-ufs-phy",
  1003. .data = &sdm845_ufsphy_cfg,
  1004. }, {
  1005. .compatible = "qcom,sm6115-qmp-ufs-phy",
  1006. .data = &sm6115_ufsphy_cfg,
  1007. }, {
  1008. .compatible = "qcom,sm6350-qmp-ufs-phy",
  1009. .data = &sdm845_ufsphy_cfg,
  1010. }, {
  1011. .compatible = "qcom,sm8150-qmp-ufs-phy",
  1012. .data = &sm8150_ufsphy_cfg,
  1013. }, {
  1014. .compatible = "qcom,sm8250-qmp-ufs-phy",
  1015. .data = &sm8150_ufsphy_cfg,
  1016. }, {
  1017. .compatible = "qcom,sm8350-qmp-ufs-phy",
  1018. .data = &sm8350_ufsphy_cfg,
  1019. }, {
  1020. .compatible = "qcom,sm8450-qmp-ufs-phy",
  1021. .data = &sm8450_ufsphy_cfg,
  1022. },
  1023. { },
  1024. };
  1025. MODULE_DEVICE_TABLE(of, qmp_ufs_of_match_table);
  1026. static int qmp_ufs_probe(struct platform_device *pdev)
  1027. {
  1028. struct qcom_qmp *qmp;
  1029. struct device *dev = &pdev->dev;
  1030. struct device_node *child;
  1031. struct phy_provider *phy_provider;
  1032. void __iomem *serdes;
  1033. const struct qmp_phy_cfg *cfg = NULL;
  1034. int num, id;
  1035. int ret;
  1036. qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
  1037. if (!qmp)
  1038. return -ENOMEM;
  1039. qmp->dev = dev;
  1040. dev_set_drvdata(dev, qmp);
  1041. /* Get the specific init parameters of QMP phy */
  1042. cfg = of_device_get_match_data(dev);
  1043. if (!cfg)
  1044. return -EINVAL;
  1045. /* per PHY serdes; usually located at base address */
  1046. serdes = devm_platform_ioremap_resource(pdev, 0);
  1047. if (IS_ERR(serdes))
  1048. return PTR_ERR(serdes);
  1049. ret = qmp_ufs_clk_init(dev, cfg);
  1050. if (ret)
  1051. return ret;
  1052. ret = qmp_ufs_vreg_init(dev, cfg);
  1053. if (ret)
  1054. return dev_err_probe(dev, ret,
  1055. "failed to get regulator supplies\n");
  1056. num = of_get_available_child_count(dev->of_node);
  1057. /* do we have a rogue child node ? */
  1058. if (num > 1)
  1059. return -EINVAL;
  1060. qmp->phys = devm_kcalloc(dev, num, sizeof(*qmp->phys), GFP_KERNEL);
  1061. if (!qmp->phys)
  1062. return -ENOMEM;
  1063. id = 0;
  1064. for_each_available_child_of_node(dev->of_node, child) {
  1065. /* Create per-lane phy */
  1066. ret = qmp_ufs_create(dev, child, id, serdes, cfg);
  1067. if (ret) {
  1068. dev_err(dev, "failed to create lane%d phy, %d\n",
  1069. id, ret);
  1070. goto err_node_put;
  1071. }
  1072. id++;
  1073. }
  1074. phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
  1075. return PTR_ERR_OR_ZERO(phy_provider);
  1076. err_node_put:
  1077. of_node_put(child);
  1078. return ret;
  1079. }
  1080. static struct platform_driver qmp_ufs_driver = {
  1081. .probe = qmp_ufs_probe,
  1082. .driver = {
  1083. .name = "qcom-qmp-ufs-phy",
  1084. .of_match_table = qmp_ufs_of_match_table,
  1085. },
  1086. };
  1087. module_platform_driver(qmp_ufs_driver);
  1088. MODULE_AUTHOR("Vivek Gautam <[email protected]>");
  1089. MODULE_DESCRIPTION("Qualcomm QMP UFS PHY driver");
  1090. MODULE_LICENSE("GPL v2");