hdmi_pll_8996.c 86 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
  4. */
  5. #include <linux/kernel.h>
  6. #include <linux/err.h>
  7. #include <linux/delay.h>
  8. #include <linux/iopoll.h>
  9. #include <linux/clk/msm-clk-provider.h>
  10. #include <linux/clk/msm-clk.h>
  11. #include <linux/clk/msm-clock-generic.h>
  12. #include <dt-bindings/clock/msm-clocks-8996.h>
  13. #include "pll_drv.h"
  14. #include "hdmi_pll.h"
  15. /* CONSTANTS */
  16. #define HDMI_BIT_CLK_TO_PIX_CLK_RATIO 10
  17. #define HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD 3400000000UL
  18. #define HDMI_DIG_FREQ_BIT_CLK_THRESHOLD 1500000000UL
  19. #define HDMI_MID_FREQ_BIT_CLK_THRESHOLD 750000000
  20. #define HDMI_CLKS_PLL_DIVSEL 0
  21. #define HDMI_CORECLK_DIV 5
  22. #define HDMI_REF_CLOCK 19200000
  23. #define HDMI_64B_ERR_VAL 0xFFFFFFFFFFFFFFFF
  24. #define HDMI_VERSION_8996_V1 1
  25. #define HDMI_VERSION_8996_V2 2
  26. #define HDMI_VERSION_8996_V3 3
  27. #define HDMI_VERSION_8996_V3_1_8 4
  28. #define HDMI_VCO_MAX_FREQ 12000000000
  29. #define HDMI_VCO_MIN_FREQ 8000000000
  30. #define HDMI_2400MHZ_BIT_CLK_HZ 2400000000UL
  31. #define HDMI_2250MHZ_BIT_CLK_HZ 2250000000UL
  32. #define HDMI_2000MHZ_BIT_CLK_HZ 2000000000UL
  33. #define HDMI_1700MHZ_BIT_CLK_HZ 1700000000UL
  34. #define HDMI_1200MHZ_BIT_CLK_HZ 1200000000UL
  35. #define HDMI_1334MHZ_BIT_CLK_HZ 1334000000UL
  36. #define HDMI_1000MHZ_BIT_CLK_HZ 1000000000UL
  37. #define HDMI_850MHZ_BIT_CLK_HZ 850000000
  38. #define HDMI_667MHZ_BIT_CLK_HZ 667000000
  39. #define HDMI_600MHZ_BIT_CLK_HZ 600000000
  40. #define HDMI_500MHZ_BIT_CLK_HZ 500000000
  41. #define HDMI_450MHZ_BIT_CLK_HZ 450000000
  42. #define HDMI_334MHZ_BIT_CLK_HZ 334000000
  43. #define HDMI_300MHZ_BIT_CLK_HZ 300000000
  44. #define HDMI_282MHZ_BIT_CLK_HZ 282000000
  45. #define HDMI_250MHZ_BIT_CLK_HZ 250000000
  46. #define HDMI_KHZ_TO_HZ 1000
  47. /* PLL REGISTERS */
  48. #define QSERDES_COM_ATB_SEL1 (0x000)
  49. #define QSERDES_COM_ATB_SEL2 (0x004)
  50. #define QSERDES_COM_FREQ_UPDATE (0x008)
  51. #define QSERDES_COM_BG_TIMER (0x00C)
  52. #define QSERDES_COM_SSC_EN_CENTER (0x010)
  53. #define QSERDES_COM_SSC_ADJ_PER1 (0x014)
  54. #define QSERDES_COM_SSC_ADJ_PER2 (0x018)
  55. #define QSERDES_COM_SSC_PER1 (0x01C)
  56. #define QSERDES_COM_SSC_PER2 (0x020)
  57. #define QSERDES_COM_SSC_STEP_SIZE1 (0x024)
  58. #define QSERDES_COM_SSC_STEP_SIZE2 (0x028)
  59. #define QSERDES_COM_POST_DIV (0x02C)
  60. #define QSERDES_COM_POST_DIV_MUX (0x030)
  61. #define QSERDES_COM_BIAS_EN_CLKBUFLR_EN (0x034)
  62. #define QSERDES_COM_CLK_ENABLE1 (0x038)
  63. #define QSERDES_COM_SYS_CLK_CTRL (0x03C)
  64. #define QSERDES_COM_SYSCLK_BUF_ENABLE (0x040)
  65. #define QSERDES_COM_PLL_EN (0x044)
  66. #define QSERDES_COM_PLL_IVCO (0x048)
  67. #define QSERDES_COM_LOCK_CMP1_MODE0 (0x04C)
  68. #define QSERDES_COM_LOCK_CMP2_MODE0 (0x050)
  69. #define QSERDES_COM_LOCK_CMP3_MODE0 (0x054)
  70. #define QSERDES_COM_LOCK_CMP1_MODE1 (0x058)
  71. #define QSERDES_COM_LOCK_CMP2_MODE1 (0x05C)
  72. #define QSERDES_COM_LOCK_CMP3_MODE1 (0x060)
  73. #define QSERDES_COM_LOCK_CMP1_MODE2 (0x064)
  74. #define QSERDES_COM_CMN_RSVD0 (0x064)
  75. #define QSERDES_COM_LOCK_CMP2_MODE2 (0x068)
  76. #define QSERDES_COM_EP_CLOCK_DETECT_CTRL (0x068)
  77. #define QSERDES_COM_LOCK_CMP3_MODE2 (0x06C)
  78. #define QSERDES_COM_SYSCLK_DET_COMP_STATUS (0x06C)
  79. #define QSERDES_COM_BG_TRIM (0x070)
  80. #define QSERDES_COM_CLK_EP_DIV (0x074)
  81. #define QSERDES_COM_CP_CTRL_MODE0 (0x078)
  82. #define QSERDES_COM_CP_CTRL_MODE1 (0x07C)
  83. #define QSERDES_COM_CP_CTRL_MODE2 (0x080)
  84. #define QSERDES_COM_CMN_RSVD1 (0x080)
  85. #define QSERDES_COM_PLL_RCTRL_MODE0 (0x084)
  86. #define QSERDES_COM_PLL_RCTRL_MODE1 (0x088)
  87. #define QSERDES_COM_PLL_RCTRL_MODE2 (0x08C)
  88. #define QSERDES_COM_CMN_RSVD2 (0x08C)
  89. #define QSERDES_COM_PLL_CCTRL_MODE0 (0x090)
  90. #define QSERDES_COM_PLL_CCTRL_MODE1 (0x094)
  91. #define QSERDES_COM_PLL_CCTRL_MODE2 (0x098)
  92. #define QSERDES_COM_CMN_RSVD3 (0x098)
  93. #define QSERDES_COM_PLL_CNTRL (0x09C)
  94. #define QSERDES_COM_PHASE_SEL_CTRL (0x0A0)
  95. #define QSERDES_COM_PHASE_SEL_DC (0x0A4)
  96. #define QSERDES_COM_CORE_CLK_IN_SYNC_SEL (0x0A8)
  97. #define QSERDES_COM_BIAS_EN_CTRL_BY_PSM (0x0A8)
  98. #define QSERDES_COM_SYSCLK_EN_SEL (0x0AC)
  99. #define QSERDES_COM_CML_SYSCLK_SEL (0x0B0)
  100. #define QSERDES_COM_RESETSM_CNTRL (0x0B4)
  101. #define QSERDES_COM_RESETSM_CNTRL2 (0x0B8)
  102. #define QSERDES_COM_RESTRIM_CTRL (0x0BC)
  103. #define QSERDES_COM_RESTRIM_CTRL2 (0x0C0)
  104. #define QSERDES_COM_RESCODE_DIV_NUM (0x0C4)
  105. #define QSERDES_COM_LOCK_CMP_EN (0x0C8)
  106. #define QSERDES_COM_LOCK_CMP_CFG (0x0CC)
  107. #define QSERDES_COM_DEC_START_MODE0 (0x0D0)
  108. #define QSERDES_COM_DEC_START_MODE1 (0x0D4)
  109. #define QSERDES_COM_DEC_START_MODE2 (0x0D8)
  110. #define QSERDES_COM_VCOCAL_DEADMAN_CTRL (0x0D8)
  111. #define QSERDES_COM_DIV_FRAC_START1_MODE0 (0x0DC)
  112. #define QSERDES_COM_DIV_FRAC_START2_MODE0 (0x0E0)
  113. #define QSERDES_COM_DIV_FRAC_START3_MODE0 (0x0E4)
  114. #define QSERDES_COM_DIV_FRAC_START1_MODE1 (0x0E8)
  115. #define QSERDES_COM_DIV_FRAC_START2_MODE1 (0x0EC)
  116. #define QSERDES_COM_DIV_FRAC_START3_MODE1 (0x0F0)
  117. #define QSERDES_COM_DIV_FRAC_START1_MODE2 (0x0F4)
  118. #define QSERDES_COM_VCO_TUNE_MINVAL1 (0x0F4)
  119. #define QSERDES_COM_DIV_FRAC_START2_MODE2 (0x0F8)
  120. #define QSERDES_COM_VCO_TUNE_MINVAL2 (0x0F8)
  121. #define QSERDES_COM_DIV_FRAC_START3_MODE2 (0x0FC)
  122. #define QSERDES_COM_CMN_RSVD4 (0x0FC)
  123. #define QSERDES_COM_INTEGLOOP_INITVAL (0x100)
  124. #define QSERDES_COM_INTEGLOOP_EN (0x104)
  125. #define QSERDES_COM_INTEGLOOP_GAIN0_MODE0 (0x108)
  126. #define QSERDES_COM_INTEGLOOP_GAIN1_MODE0 (0x10C)
  127. #define QSERDES_COM_INTEGLOOP_GAIN0_MODE1 (0x110)
  128. #define QSERDES_COM_INTEGLOOP_GAIN1_MODE1 (0x114)
  129. #define QSERDES_COM_INTEGLOOP_GAIN0_MODE2 (0x118)
  130. #define QSERDES_COM_VCO_TUNE_MAXVAL1 (0x118)
  131. #define QSERDES_COM_INTEGLOOP_GAIN1_MODE2 (0x11C)
  132. #define QSERDES_COM_VCO_TUNE_MAXVAL2 (0x11C)
  133. #define QSERDES_COM_RES_TRIM_CONTROL2 (0x120)
  134. #define QSERDES_COM_VCO_TUNE_CTRL (0x124)
  135. #define QSERDES_COM_VCO_TUNE_MAP (0x128)
  136. #define QSERDES_COM_VCO_TUNE1_MODE0 (0x12C)
  137. #define QSERDES_COM_VCO_TUNE2_MODE0 (0x130)
  138. #define QSERDES_COM_VCO_TUNE1_MODE1 (0x134)
  139. #define QSERDES_COM_VCO_TUNE2_MODE1 (0x138)
  140. #define QSERDES_COM_VCO_TUNE1_MODE2 (0x13C)
  141. #define QSERDES_COM_VCO_TUNE_INITVAL1 (0x13C)
  142. #define QSERDES_COM_VCO_TUNE2_MODE2 (0x140)
  143. #define QSERDES_COM_VCO_TUNE_INITVAL2 (0x140)
  144. #define QSERDES_COM_VCO_TUNE_TIMER1 (0x144)
  145. #define QSERDES_COM_VCO_TUNE_TIMER2 (0x148)
  146. #define QSERDES_COM_SAR (0x14C)
  147. #define QSERDES_COM_SAR_CLK (0x150)
  148. #define QSERDES_COM_SAR_CODE_OUT_STATUS (0x154)
  149. #define QSERDES_COM_SAR_CODE_READY_STATUS (0x158)
  150. #define QSERDES_COM_CMN_STATUS (0x15C)
  151. #define QSERDES_COM_RESET_SM_STATUS (0x160)
  152. #define QSERDES_COM_RESTRIM_CODE_STATUS (0x164)
  153. #define QSERDES_COM_PLLCAL_CODE1_STATUS (0x168)
  154. #define QSERDES_COM_PLLCAL_CODE2_STATUS (0x16C)
  155. #define QSERDES_COM_BG_CTRL (0x170)
  156. #define QSERDES_COM_CLK_SELECT (0x174)
  157. #define QSERDES_COM_HSCLK_SEL (0x178)
  158. #define QSERDES_COM_INTEGLOOP_BINCODE_STATUS (0x17C)
  159. #define QSERDES_COM_PLL_ANALOG (0x180)
  160. #define QSERDES_COM_CORECLK_DIV (0x184)
  161. #define QSERDES_COM_SW_RESET (0x188)
  162. #define QSERDES_COM_CORE_CLK_EN (0x18C)
  163. #define QSERDES_COM_C_READY_STATUS (0x190)
  164. #define QSERDES_COM_CMN_CONFIG (0x194)
  165. #define QSERDES_COM_CMN_RATE_OVERRIDE (0x198)
  166. #define QSERDES_COM_SVS_MODE_CLK_SEL (0x19C)
  167. #define QSERDES_COM_DEBUG_BUS0 (0x1A0)
  168. #define QSERDES_COM_DEBUG_BUS1 (0x1A4)
  169. #define QSERDES_COM_DEBUG_BUS2 (0x1A8)
  170. #define QSERDES_COM_DEBUG_BUS3 (0x1AC)
  171. #define QSERDES_COM_DEBUG_BUS_SEL (0x1B0)
  172. #define QSERDES_COM_CMN_MISC1 (0x1B4)
  173. #define QSERDES_COM_CMN_MISC2 (0x1B8)
  174. #define QSERDES_COM_CORECLK_DIV_MODE1 (0x1BC)
  175. #define QSERDES_COM_CORECLK_DIV_MODE2 (0x1C0)
  176. #define QSERDES_COM_CMN_RSVD5 (0x1C0)
  177. /* Tx Channel base addresses */
  178. #define HDMI_TX_L0_BASE_OFFSET (0x400)
  179. #define HDMI_TX_L1_BASE_OFFSET (0x600)
  180. #define HDMI_TX_L2_BASE_OFFSET (0x800)
  181. #define HDMI_TX_L3_BASE_OFFSET (0xA00)
  182. /* Tx Channel PHY registers */
  183. #define QSERDES_TX_L0_BIST_MODE_LANENO (0x000)
  184. #define QSERDES_TX_L0_BIST_INVERT (0x004)
  185. #define QSERDES_TX_L0_CLKBUF_ENABLE (0x008)
  186. #define QSERDES_TX_L0_CMN_CONTROL_ONE (0x00C)
  187. #define QSERDES_TX_L0_CMN_CONTROL_TWO (0x010)
  188. #define QSERDES_TX_L0_CMN_CONTROL_THREE (0x014)
  189. #define QSERDES_TX_L0_TX_EMP_POST1_LVL (0x018)
  190. #define QSERDES_TX_L0_TX_POST2_EMPH (0x01C)
  191. #define QSERDES_TX_L0_TX_BOOST_LVL_UP_DN (0x020)
  192. #define QSERDES_TX_L0_HP_PD_ENABLES (0x024)
  193. #define QSERDES_TX_L0_TX_IDLE_LVL_LARGE_AMP (0x028)
  194. #define QSERDES_TX_L0_TX_DRV_LVL (0x02C)
  195. #define QSERDES_TX_L0_TX_DRV_LVL_OFFSET (0x030)
  196. #define QSERDES_TX_L0_RESET_TSYNC_EN (0x034)
  197. #define QSERDES_TX_L0_PRE_STALL_LDO_BOOST_EN (0x038)
  198. #define QSERDES_TX_L0_TX_BAND (0x03C)
  199. #define QSERDES_TX_L0_SLEW_CNTL (0x040)
  200. #define QSERDES_TX_L0_INTERFACE_SELECT (0x044)
  201. #define QSERDES_TX_L0_LPB_EN (0x048)
  202. #define QSERDES_TX_L0_RES_CODE_LANE_TX (0x04C)
  203. #define QSERDES_TX_L0_RES_CODE_LANE_RX (0x050)
  204. #define QSERDES_TX_L0_RES_CODE_LANE_OFFSET (0x054)
  205. #define QSERDES_TX_L0_PERL_LENGTH1 (0x058)
  206. #define QSERDES_TX_L0_PERL_LENGTH2 (0x05C)
  207. #define QSERDES_TX_L0_SERDES_BYP_EN_OUT (0x060)
  208. #define QSERDES_TX_L0_DEBUG_BUS_SEL (0x064)
  209. #define QSERDES_TX_L0_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN (0x068)
  210. #define QSERDES_TX_L0_TX_POL_INV (0x06C)
  211. #define QSERDES_TX_L0_PARRATE_REC_DETECT_IDLE_EN (0x070)
  212. #define QSERDES_TX_L0_BIST_PATTERN1 (0x074)
  213. #define QSERDES_TX_L0_BIST_PATTERN2 (0x078)
  214. #define QSERDES_TX_L0_BIST_PATTERN3 (0x07C)
  215. #define QSERDES_TX_L0_BIST_PATTERN4 (0x080)
  216. #define QSERDES_TX_L0_BIST_PATTERN5 (0x084)
  217. #define QSERDES_TX_L0_BIST_PATTERN6 (0x088)
  218. #define QSERDES_TX_L0_BIST_PATTERN7 (0x08C)
  219. #define QSERDES_TX_L0_BIST_PATTERN8 (0x090)
  220. #define QSERDES_TX_L0_LANE_MODE (0x094)
  221. #define QSERDES_TX_L0_IDAC_CAL_LANE_MODE (0x098)
  222. #define QSERDES_TX_L0_IDAC_CAL_LANE_MODE_CONFIGURATION (0x09C)
  223. #define QSERDES_TX_L0_ATB_SEL1 (0x0A0)
  224. #define QSERDES_TX_L0_ATB_SEL2 (0x0A4)
  225. #define QSERDES_TX_L0_RCV_DETECT_LVL (0x0A8)
  226. #define QSERDES_TX_L0_RCV_DETECT_LVL_2 (0x0AC)
  227. #define QSERDES_TX_L0_PRBS_SEED1 (0x0B0)
  228. #define QSERDES_TX_L0_PRBS_SEED2 (0x0B4)
  229. #define QSERDES_TX_L0_PRBS_SEED3 (0x0B8)
  230. #define QSERDES_TX_L0_PRBS_SEED4 (0x0BC)
  231. #define QSERDES_TX_L0_RESET_GEN (0x0C0)
  232. #define QSERDES_TX_L0_RESET_GEN_MUXES (0x0C4)
  233. #define QSERDES_TX_L0_TRAN_DRVR_EMP_EN (0x0C8)
  234. #define QSERDES_TX_L0_TX_INTERFACE_MODE (0x0CC)
  235. #define QSERDES_TX_L0_PWM_CTRL (0x0D0)
  236. #define QSERDES_TX_L0_PWM_ENCODED_OR_DATA (0x0D4)
  237. #define QSERDES_TX_L0_PWM_GEAR_1_DIVIDER_BAND2 (0x0D8)
  238. #define QSERDES_TX_L0_PWM_GEAR_2_DIVIDER_BAND2 (0x0DC)
  239. #define QSERDES_TX_L0_PWM_GEAR_3_DIVIDER_BAND2 (0x0E0)
  240. #define QSERDES_TX_L0_PWM_GEAR_4_DIVIDER_BAND2 (0x0E4)
  241. #define QSERDES_TX_L0_PWM_GEAR_1_DIVIDER_BAND0_1 (0x0E8)
  242. #define QSERDES_TX_L0_PWM_GEAR_2_DIVIDER_BAND0_1 (0x0EC)
  243. #define QSERDES_TX_L0_PWM_GEAR_3_DIVIDER_BAND0_1 (0x0F0)
  244. #define QSERDES_TX_L0_PWM_GEAR_4_DIVIDER_BAND0_1 (0x0F4)
  245. #define QSERDES_TX_L0_VMODE_CTRL1 (0x0F8)
  246. #define QSERDES_TX_L0_VMODE_CTRL2 (0x0FC)
  247. #define QSERDES_TX_L0_TX_ALOG_INTF_OBSV_CNTL (0x100)
  248. #define QSERDES_TX_L0_BIST_STATUS (0x104)
  249. #define QSERDES_TX_L0_BIST_ERROR_COUNT1 (0x108)
  250. #define QSERDES_TX_L0_BIST_ERROR_COUNT2 (0x10C)
  251. #define QSERDES_TX_L0_TX_ALOG_INTF_OBSV (0x110)
  252. /* HDMI PHY REGISTERS */
  253. #define HDMI_PHY_BASE_OFFSET (0xC00)
  254. #define HDMI_PHY_CFG (0x00)
  255. #define HDMI_PHY_PD_CTL (0x04)
  256. #define HDMI_PHY_MODE (0x08)
  257. #define HDMI_PHY_MISR_CLEAR (0x0C)
  258. #define HDMI_PHY_TX0_TX1_BIST_CFG0 (0x10)
  259. #define HDMI_PHY_TX0_TX1_BIST_CFG1 (0x14)
  260. #define HDMI_PHY_TX0_TX1_PRBS_SEED_BYTE0 (0x18)
  261. #define HDMI_PHY_TX0_TX1_PRBS_SEED_BYTE1 (0x1C)
  262. #define HDMI_PHY_TX0_TX1_BIST_PATTERN0 (0x20)
  263. #define HDMI_PHY_TX0_TX1_BIST_PATTERN1 (0x24)
  264. #define HDMI_PHY_TX2_TX3_BIST_CFG0 (0x28)
  265. #define HDMI_PHY_TX2_TX3_BIST_CFG1 (0x2C)
  266. #define HDMI_PHY_TX2_TX3_PRBS_SEED_BYTE0 (0x30)
  267. #define HDMI_PHY_TX2_TX3_PRBS_SEED_BYTE1 (0x34)
  268. #define HDMI_PHY_TX2_TX3_BIST_PATTERN0 (0x38)
  269. #define HDMI_PHY_TX2_TX3_BIST_PATTERN1 (0x3C)
  270. #define HDMI_PHY_DEBUG_BUS_SEL (0x40)
  271. #define HDMI_PHY_TXCAL_CFG0 (0x44)
  272. #define HDMI_PHY_TXCAL_CFG1 (0x48)
  273. #define HDMI_PHY_TX0_TX1_LANE_CTL (0x4C)
  274. #define HDMI_PHY_TX2_TX3_LANE_CTL (0x50)
  275. #define HDMI_PHY_LANE_BIST_CONFIG (0x54)
  276. #define HDMI_PHY_CLOCK (0x58)
  277. #define HDMI_PHY_MISC1 (0x5C)
  278. #define HDMI_PHY_MISC2 (0x60)
  279. #define HDMI_PHY_TX0_TX1_BIST_STATUS0 (0x64)
  280. #define HDMI_PHY_TX0_TX1_BIST_STATUS1 (0x68)
  281. #define HDMI_PHY_TX0_TX1_BIST_STATUS2 (0x6C)
  282. #define HDMI_PHY_TX2_TX3_BIST_STATUS0 (0x70)
  283. #define HDMI_PHY_TX2_TX3_BIST_STATUS1 (0x74)
  284. #define HDMI_PHY_TX2_TX3_BIST_STATUS2 (0x78)
  285. #define HDMI_PHY_PRE_MISR_STATUS0 (0x7C)
  286. #define HDMI_PHY_PRE_MISR_STATUS1 (0x80)
  287. #define HDMI_PHY_PRE_MISR_STATUS2 (0x84)
  288. #define HDMI_PHY_PRE_MISR_STATUS3 (0x88)
  289. #define HDMI_PHY_POST_MISR_STATUS0 (0x8C)
  290. #define HDMI_PHY_POST_MISR_STATUS1 (0x90)
  291. #define HDMI_PHY_POST_MISR_STATUS2 (0x94)
  292. #define HDMI_PHY_POST_MISR_STATUS3 (0x98)
  293. #define HDMI_PHY_STATUS (0x9C)
  294. #define HDMI_PHY_MISC3_STATUS (0xA0)
  295. #define HDMI_PHY_MISC4_STATUS (0xA4)
  296. #define HDMI_PHY_DEBUG_BUS0 (0xA8)
  297. #define HDMI_PHY_DEBUG_BUS1 (0xAC)
  298. #define HDMI_PHY_DEBUG_BUS2 (0xB0)
  299. #define HDMI_PHY_DEBUG_BUS3 (0xB4)
  300. #define HDMI_PHY_PHY_REVISION_ID0 (0xB8)
  301. #define HDMI_PHY_PHY_REVISION_ID1 (0xBC)
  302. #define HDMI_PHY_PHY_REVISION_ID2 (0xC0)
  303. #define HDMI_PHY_PHY_REVISION_ID3 (0xC4)
  304. #define HDMI_PLL_POLL_MAX_READS 100
  305. #define HDMI_PLL_POLL_TIMEOUT_US 1500
  306. enum hdmi_pll_freqs {
  307. HDMI_PCLK_25200_KHZ,
  308. HDMI_PCLK_27027_KHZ,
  309. HDMI_PCLK_27000_KHZ,
  310. HDMI_PCLK_74250_KHZ,
  311. HDMI_PCLK_148500_KHZ,
  312. HDMI_PCLK_154000_KHZ,
  313. HDMI_PCLK_268500_KHZ,
  314. HDMI_PCLK_297000_KHZ,
  315. HDMI_PCLK_594000_KHZ,
  316. HDMI_PCLK_MAX
  317. };
  318. struct hdmi_8996_phy_pll_reg_cfg {
  319. u32 tx_l0_lane_mode;
  320. u32 tx_l2_lane_mode;
  321. u32 tx_l0_tx_band;
  322. u32 tx_l1_tx_band;
  323. u32 tx_l2_tx_band;
  324. u32 tx_l3_tx_band;
  325. u32 com_svs_mode_clk_sel;
  326. u32 com_hsclk_sel;
  327. u32 com_pll_cctrl_mode0;
  328. u32 com_pll_rctrl_mode0;
  329. u32 com_cp_ctrl_mode0;
  330. u32 com_dec_start_mode0;
  331. u32 com_div_frac_start1_mode0;
  332. u32 com_div_frac_start2_mode0;
  333. u32 com_div_frac_start3_mode0;
  334. u32 com_integloop_gain0_mode0;
  335. u32 com_integloop_gain1_mode0;
  336. u32 com_lock_cmp_en;
  337. u32 com_lock_cmp1_mode0;
  338. u32 com_lock_cmp2_mode0;
  339. u32 com_lock_cmp3_mode0;
  340. u32 com_core_clk_en;
  341. u32 com_coreclk_div;
  342. u32 com_restrim_ctrl;
  343. u32 com_vco_tune_ctrl;
  344. u32 tx_l0_tx_drv_lvl;
  345. u32 tx_l0_tx_emp_post1_lvl;
  346. u32 tx_l1_tx_drv_lvl;
  347. u32 tx_l1_tx_emp_post1_lvl;
  348. u32 tx_l2_tx_drv_lvl;
  349. u32 tx_l2_tx_emp_post1_lvl;
  350. u32 tx_l3_tx_drv_lvl;
  351. u32 tx_l3_tx_emp_post1_lvl;
  352. u32 tx_l0_vmode_ctrl1;
  353. u32 tx_l0_vmode_ctrl2;
  354. u32 tx_l1_vmode_ctrl1;
  355. u32 tx_l1_vmode_ctrl2;
  356. u32 tx_l2_vmode_ctrl1;
  357. u32 tx_l2_vmode_ctrl2;
  358. u32 tx_l3_vmode_ctrl1;
  359. u32 tx_l3_vmode_ctrl2;
  360. u32 tx_l0_res_code_lane_tx;
  361. u32 tx_l1_res_code_lane_tx;
  362. u32 tx_l2_res_code_lane_tx;
  363. u32 tx_l3_res_code_lane_tx;
  364. u32 phy_mode;
  365. };
  366. struct hdmi_8996_v3_post_divider {
  367. u64 vco_freq;
  368. u64 hsclk_divsel;
  369. u64 vco_ratio;
  370. u64 tx_band_sel;
  371. u64 half_rate_mode;
  372. };
  373. static inline struct hdmi_pll_vco_clk *to_hdmi_8996_vco_clk(struct clk *clk)
  374. {
  375. return container_of(clk, struct hdmi_pll_vco_clk, c);
  376. }
  377. static inline u64 hdmi_8996_v1_get_post_div_lt_2g(u64 bclk)
  378. {
  379. if (bclk >= HDMI_2400MHZ_BIT_CLK_HZ)
  380. return 2;
  381. else if (bclk >= HDMI_1700MHZ_BIT_CLK_HZ)
  382. return 3;
  383. else if (bclk >= HDMI_1200MHZ_BIT_CLK_HZ)
  384. return 4;
  385. else if (bclk >= HDMI_850MHZ_BIT_CLK_HZ)
  386. return 3;
  387. else if (bclk >= HDMI_600MHZ_BIT_CLK_HZ)
  388. return 4;
  389. else if (bclk >= HDMI_450MHZ_BIT_CLK_HZ)
  390. return 3;
  391. else if (bclk >= HDMI_300MHZ_BIT_CLK_HZ)
  392. return 4;
  393. return HDMI_64B_ERR_VAL;
  394. }
  395. static inline u64 hdmi_8996_v2_get_post_div_lt_2g(u64 bclk, u64 vco_range)
  396. {
  397. u64 hdmi_8ghz = vco_range;
  398. u64 tmp_calc;
  399. hdmi_8ghz <<= 2;
  400. tmp_calc = hdmi_8ghz;
  401. do_div(tmp_calc, 6U);
  402. if (bclk >= vco_range)
  403. return 2;
  404. else if (bclk >= tmp_calc)
  405. return 3;
  406. else if (bclk >= vco_range >> 1)
  407. return 4;
  408. tmp_calc = hdmi_8ghz;
  409. do_div(tmp_calc, 12U);
  410. if (bclk >= tmp_calc)
  411. return 3;
  412. else if (bclk >= vco_range >> 2)
  413. return 4;
  414. tmp_calc = hdmi_8ghz;
  415. do_div(tmp_calc, 24U);
  416. if (bclk >= tmp_calc)
  417. return 3;
  418. else if (bclk >= vco_range >> 3)
  419. return 4;
  420. return HDMI_64B_ERR_VAL;
  421. }
  422. static inline u64 hdmi_8996_v2_get_post_div_gt_2g(u64 hsclk)
  423. {
  424. if (hsclk >= 0 && hsclk <= 3)
  425. return hsclk + 1;
  426. return HDMI_64B_ERR_VAL;
  427. }
  428. static inline u64 hdmi_8996_get_coreclk_div_lt_2g(u64 bclk)
  429. {
  430. if (bclk >= HDMI_1334MHZ_BIT_CLK_HZ)
  431. return 1;
  432. else if (bclk >= HDMI_1000MHZ_BIT_CLK_HZ)
  433. return 1;
  434. else if (bclk >= HDMI_667MHZ_BIT_CLK_HZ)
  435. return 2;
  436. else if (bclk >= HDMI_500MHZ_BIT_CLK_HZ)
  437. return 2;
  438. else if (bclk >= HDMI_334MHZ_BIT_CLK_HZ)
  439. return 3;
  440. else if (bclk >= HDMI_250MHZ_BIT_CLK_HZ)
  441. return 3;
  442. return HDMI_64B_ERR_VAL;
  443. }
  444. static inline u64 hdmi_8996_get_coreclk_div_ratio(u64 clks_pll_divsel,
  445. u64 coreclk_div)
  446. {
  447. if (clks_pll_divsel == 0)
  448. return coreclk_div*2;
  449. else if (clks_pll_divsel == 1)
  450. return coreclk_div*4;
  451. return HDMI_64B_ERR_VAL;
  452. }
  453. static inline u64 hdmi_8996_v1_get_tx_band(u64 bclk)
  454. {
  455. if (bclk >= 2400000000UL)
  456. return 0;
  457. if (bclk >= 1200000000UL)
  458. return 1;
  459. if (bclk >= 600000000UL)
  460. return 2;
  461. if (bclk >= 300000000UL)
  462. return 3;
  463. return HDMI_64B_ERR_VAL;
  464. }
  465. static inline u64 hdmi_8996_v2_get_tx_band(u64 bclk, u64 vco_range)
  466. {
  467. if (bclk >= vco_range)
  468. return 0;
  469. else if (bclk >= vco_range >> 1)
  470. return 1;
  471. else if (bclk >= vco_range >> 2)
  472. return 2;
  473. else if (bclk >= vco_range >> 3)
  474. return 3;
  475. return HDMI_64B_ERR_VAL;
  476. }
  477. static inline u64 hdmi_8996_v1_get_hsclk(u64 fdata)
  478. {
  479. if (fdata >= 9600000000UL)
  480. return 0;
  481. else if (fdata >= 4800000000UL)
  482. return 1;
  483. else if (fdata >= 3200000000UL)
  484. return 2;
  485. else if (fdata >= 2400000000UL)
  486. return 3;
  487. return HDMI_64B_ERR_VAL;
  488. }
  489. static inline u64 hdmi_8996_v2_get_hsclk(u64 fdata, u64 vco_range)
  490. {
  491. u64 tmp_calc = vco_range;
  492. tmp_calc <<= 2;
  493. do_div(tmp_calc, 3U);
  494. if (fdata >= (vco_range << 2))
  495. return 0;
  496. else if (fdata >= (vco_range << 1))
  497. return 1;
  498. else if (fdata >= tmp_calc)
  499. return 2;
  500. else if (fdata >= vco_range)
  501. return 3;
  502. return HDMI_64B_ERR_VAL;
  503. }
  504. static inline u64 hdmi_8996_v2_get_vco_freq(u64 bclk, u64 vco_range)
  505. {
  506. u64 tx_band_div_ratio = 1U << hdmi_8996_v2_get_tx_band(bclk, vco_range);
  507. u64 pll_post_div_ratio;
  508. if (bclk >= vco_range) {
  509. u64 hsclk = hdmi_8996_v2_get_hsclk(bclk, vco_range);
  510. pll_post_div_ratio = hdmi_8996_v2_get_post_div_gt_2g(hsclk);
  511. } else {
  512. pll_post_div_ratio = hdmi_8996_v2_get_post_div_lt_2g(bclk,
  513. vco_range);
  514. }
  515. return bclk * (pll_post_div_ratio * tx_band_div_ratio);
  516. }
  517. static inline u64 hdmi_8996_v2_get_fdata(u64 bclk, u64 vco_range)
  518. {
  519. if (bclk >= vco_range)
  520. return bclk;
  521. u64 tmp_calc = hdmi_8996_v2_get_vco_freq(bclk, vco_range);
  522. u64 pll_post_div_ratio_lt_2g = hdmi_8996_v2_get_post_div_lt_2g(
  523. bclk, vco_range);
  524. if (pll_post_div_ratio_lt_2g == HDMI_64B_ERR_VAL)
  525. return HDMI_64B_ERR_VAL;
  526. do_div(tmp_calc, pll_post_div_ratio_lt_2g);
  527. return tmp_calc;
  528. }
  529. static inline u64 hdmi_8996_get_cpctrl(u64 frac_start, bool gen_ssc)
  530. {
  531. if ((frac_start != 0) || gen_ssc)
  532. /*
  533. * This should be ROUND(11/(19.2/20))).
  534. * Since ref clock does not change, hardcoding to 11
  535. */
  536. return 0xB;
  537. return 0x23;
  538. }
  539. static inline u64 hdmi_8996_get_rctrl(u64 frac_start, bool gen_ssc)
  540. {
  541. if ((frac_start != 0) || gen_ssc)
  542. return 0x16;
  543. return 0x10;
  544. }
  545. static inline u64 hdmi_8996_get_cctrl(u64 frac_start, bool gen_ssc)
  546. {
  547. if ((frac_start != 0) || (gen_ssc))
  548. return 0x28;
  549. return 0x1;
  550. }
  551. static inline u64 hdmi_8996_get_integloop_gain(u64 frac_start, bool gen_ssc)
  552. {
  553. if ((frac_start != 0) || gen_ssc)
  554. return 0x80;
  555. return 0xC4;
  556. }
  557. static inline u64 hdmi_8996_v3_get_integloop_gain(u64 frac_start, u64 bclk,
  558. bool gen_ssc)
  559. {
  560. u64 digclk_divsel = bclk >= HDMI_DIG_FREQ_BIT_CLK_THRESHOLD ? 1 : 2;
  561. u64 base = ((frac_start != 0) || gen_ssc) ? 0x40 : 0xC4;
  562. base <<= digclk_divsel;
  563. return (base <= 2046 ? base : 0x7FE);
  564. }
  565. static inline u64 hdmi_8996_get_vco_tune(u64 fdata, u64 div)
  566. {
  567. u64 vco_tune;
  568. vco_tune = fdata * div;
  569. do_div(vco_tune, 1000000);
  570. vco_tune = 13000 - vco_tune - 256;
  571. do_div(vco_tune, 5);
  572. return vco_tune;
  573. }
  574. static inline u64 hdmi_8996_get_pll_cmp(u64 pll_cmp_cnt, u64 core_clk)
  575. {
  576. u64 pll_cmp;
  577. u64 rem;
  578. pll_cmp = pll_cmp_cnt * core_clk;
  579. rem = do_div(pll_cmp, HDMI_REF_CLOCK);
  580. if (rem > (HDMI_REF_CLOCK >> 1))
  581. pll_cmp++;
  582. pll_cmp -= 1;
  583. return pll_cmp;
  584. }
  585. static inline u64 hdmi_8996_v3_get_pll_cmp(u64 pll_cmp_cnt, u64 fdata)
  586. {
  587. u64 dividend = pll_cmp_cnt * fdata;
  588. u64 divisor = HDMI_REF_CLOCK * 10;
  589. u64 rem;
  590. rem = do_div(dividend, divisor);
  591. if (rem > (divisor >> 1))
  592. dividend++;
  593. return dividend - 1;
  594. }
  595. static int hdmi_8996_v3_get_post_div(struct hdmi_8996_v3_post_divider *pd,
  596. u64 bclk)
  597. {
  598. u32 ratio[] = {2, 3, 4, 5, 6, 9, 10, 12, 14, 15, 20, 21, 25, 28, 35};
  599. u32 tx_band_sel[] = {0, 1, 2, 3};
  600. u64 vco_freq[60];
  601. u64 vco, vco_optimal, half_rate_mode = 0;
  602. int vco_optimal_index, vco_freq_index;
  603. int i, j, k, x;
  604. for (i = 0; i <= 1; i++) {
  605. vco_optimal = HDMI_VCO_MAX_FREQ;
  606. vco_optimal_index = -1;
  607. vco_freq_index = 0;
  608. for (j = 0; j < 15; j++) {
  609. for (k = 0; k < 4; k++) {
  610. u64 ratio_mult = ratio[j] << tx_band_sel[k];
  611. vco = bclk >> half_rate_mode;
  612. vco *= ratio_mult;
  613. vco_freq[vco_freq_index++] = vco;
  614. }
  615. }
  616. for (x = 0; x < 60; x++) {
  617. u64 vco_tmp = vco_freq[x];
  618. if ((vco_tmp >= HDMI_VCO_MIN_FREQ) &&
  619. (vco_tmp <= vco_optimal)) {
  620. vco_optimal = vco_tmp;
  621. vco_optimal_index = x;
  622. }
  623. }
  624. if (vco_optimal_index == -1) {
  625. if (!half_rate_mode)
  626. half_rate_mode++;
  627. else
  628. return -EINVAL;
  629. } else {
  630. pd->vco_freq = vco_optimal;
  631. pd->tx_band_sel = tx_band_sel[vco_optimal_index % 4];
  632. pd->vco_ratio = ratio[vco_optimal_index / 4];
  633. break;
  634. }
  635. }
  636. switch (pd->vco_ratio) {
  637. case 2:
  638. pd->hsclk_divsel = 0;
  639. break;
  640. case 3:
  641. pd->hsclk_divsel = 4;
  642. break;
  643. case 4:
  644. pd->hsclk_divsel = 8;
  645. break;
  646. case 5:
  647. pd->hsclk_divsel = 12;
  648. break;
  649. case 6:
  650. pd->hsclk_divsel = 1;
  651. break;
  652. case 9:
  653. pd->hsclk_divsel = 5;
  654. break;
  655. case 10:
  656. pd->hsclk_divsel = 2;
  657. break;
  658. case 12:
  659. pd->hsclk_divsel = 9;
  660. break;
  661. case 14:
  662. pd->hsclk_divsel = 3;
  663. break;
  664. case 15:
  665. pd->hsclk_divsel = 13;
  666. break;
  667. case 20:
  668. pd->hsclk_divsel = 10;
  669. break;
  670. case 21:
  671. pd->hsclk_divsel = 7;
  672. break;
  673. case 25:
  674. pd->hsclk_divsel = 14;
  675. break;
  676. case 28:
  677. pd->hsclk_divsel = 11;
  678. break;
  679. case 35:
  680. pd->hsclk_divsel = 15;
  681. break;
  682. }
  683. return 0;
  684. }
  685. static int hdmi_8996_v1_calculate(u32 pix_clk,
  686. struct hdmi_8996_phy_pll_reg_cfg *cfg)
  687. {
  688. int rc = -EINVAL;
  689. u64 fdata, clk_divtx, tmds_clk;
  690. u64 bclk;
  691. u64 post_div_gt_2g;
  692. u64 post_div_lt_2g;
  693. u64 coreclk_div1_lt_2g;
  694. u64 core_clk_div_ratio;
  695. u64 core_clk;
  696. u64 pll_cmp;
  697. u64 tx_band;
  698. u64 tx_band_div_ratio;
  699. u64 hsclk;
  700. u64 dec_start;
  701. u64 frac_start;
  702. u64 pll_divisor = 4 * HDMI_REF_CLOCK;
  703. u64 cpctrl;
  704. u64 rctrl;
  705. u64 cctrl;
  706. u64 integloop_gain;
  707. u64 vco_tune;
  708. u64 vco_freq;
  709. u64 rem;
  710. /* FDATA, CLK_DIVTX, PIXEL_CLK, TMDS_CLK */
  711. bclk = ((u64)pix_clk) * HDMI_BIT_CLK_TO_PIX_CLK_RATIO;
  712. if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD)
  713. tmds_clk = bclk/4;
  714. else
  715. tmds_clk = bclk;
  716. post_div_lt_2g = hdmi_8996_v1_get_post_div_lt_2g(bclk);
  717. if (post_div_lt_2g == HDMI_64B_ERR_VAL)
  718. goto fail;
  719. coreclk_div1_lt_2g = hdmi_8996_get_coreclk_div_lt_2g(bclk);
  720. core_clk_div_ratio = hdmi_8996_get_coreclk_div_ratio(
  721. HDMI_CLKS_PLL_DIVSEL, HDMI_CORECLK_DIV);
  722. tx_band = hdmi_8996_v1_get_tx_band(bclk);
  723. if (tx_band == HDMI_64B_ERR_VAL)
  724. goto fail;
  725. tx_band_div_ratio = 1 << tx_band;
  726. if (bclk >= HDMI_2400MHZ_BIT_CLK_HZ) {
  727. fdata = bclk;
  728. hsclk = hdmi_8996_v1_get_hsclk(fdata);
  729. if (hsclk == HDMI_64B_ERR_VAL)
  730. goto fail;
  731. post_div_gt_2g = (hsclk <= 3) ? (hsclk + 1) : HDMI_64B_ERR_VAL;
  732. if (post_div_gt_2g == HDMI_64B_ERR_VAL)
  733. goto fail;
  734. vco_freq = bclk * (post_div_gt_2g * tx_band_div_ratio);
  735. clk_divtx = vco_freq;
  736. do_div(clk_divtx, post_div_gt_2g);
  737. } else {
  738. vco_freq = bclk * (post_div_lt_2g * tx_band_div_ratio);
  739. fdata = vco_freq;
  740. do_div(fdata, post_div_lt_2g);
  741. hsclk = hdmi_8996_v1_get_hsclk(fdata);
  742. if (hsclk == HDMI_64B_ERR_VAL)
  743. goto fail;
  744. clk_divtx = vco_freq;
  745. do_div(clk_divtx, post_div_lt_2g);
  746. post_div_gt_2g = (hsclk <= 3) ? (hsclk + 1) : HDMI_64B_ERR_VAL;
  747. if (post_div_gt_2g == HDMI_64B_ERR_VAL)
  748. goto fail;
  749. }
  750. /* Decimal and fraction values */
  751. dec_start = fdata * post_div_gt_2g;
  752. do_div(dec_start, pll_divisor);
  753. frac_start = ((pll_divisor - (((dec_start + 1) * pll_divisor) -
  754. (fdata * post_div_gt_2g))) * (1 << 20));
  755. rem = do_div(frac_start, pll_divisor);
  756. /* Round off frac_start to closest integer */
  757. if (rem >= (pll_divisor >> 1))
  758. frac_start++;
  759. cpctrl = hdmi_8996_get_cpctrl(frac_start, false);
  760. rctrl = hdmi_8996_get_rctrl(frac_start, false);
  761. cctrl = hdmi_8996_get_cctrl(frac_start, false);
  762. integloop_gain = hdmi_8996_get_integloop_gain(frac_start, false);
  763. vco_tune = hdmi_8996_get_vco_tune(fdata, post_div_gt_2g);
  764. core_clk = clk_divtx;
  765. do_div(core_clk, core_clk_div_ratio);
  766. pll_cmp = hdmi_8996_get_pll_cmp(1024, core_clk);
  767. /* Debug dump */
  768. DEV_DBG("%s: VCO freq: %llu\n", __func__, vco_freq);
  769. DEV_DBG("%s: fdata: %llu\n", __func__, fdata);
  770. DEV_DBG("%s: CLK_DIVTX: %llu\n", __func__, clk_divtx);
  771. DEV_DBG("%s: pix_clk: %d\n", __func__, pix_clk);
  772. DEV_DBG("%s: tmds clk: %llu\n", __func__, tmds_clk);
  773. DEV_DBG("%s: HSCLK_SEL: %llu\n", __func__, hsclk);
  774. DEV_DBG("%s: DEC_START: %llu\n", __func__, dec_start);
  775. DEV_DBG("%s: DIV_FRAC_START: %llu\n", __func__, frac_start);
  776. DEV_DBG("%s: PLL_CPCTRL: %llu\n", __func__, cpctrl);
  777. DEV_DBG("%s: PLL_RCTRL: %llu\n", __func__, rctrl);
  778. DEV_DBG("%s: PLL_CCTRL: %llu\n", __func__, cctrl);
  779. DEV_DBG("%s: INTEGLOOP_GAIN: %llu\n", __func__, integloop_gain);
  780. DEV_DBG("%s: VCO_TUNE: %llu\n", __func__, vco_tune);
  781. DEV_DBG("%s: TX_BAND: %llu\n", __func__, tx_band);
  782. DEV_DBG("%s: PLL_CMP: %llu\n", __func__, pll_cmp);
  783. /* Convert these values to register specific values */
  784. cfg->tx_l0_lane_mode = 0x3;
  785. cfg->tx_l2_lane_mode = 0x3;
  786. cfg->tx_l0_tx_band = tx_band + 4;
  787. cfg->tx_l1_tx_band = tx_band + 4;
  788. cfg->tx_l2_tx_band = tx_band + 4;
  789. cfg->tx_l3_tx_band = tx_band + 4;
  790. cfg->tx_l0_res_code_lane_tx = 0x33;
  791. cfg->tx_l1_res_code_lane_tx = 0x33;
  792. cfg->tx_l2_res_code_lane_tx = 0x33;
  793. cfg->tx_l3_res_code_lane_tx = 0x33;
  794. cfg->com_restrim_ctrl = 0x0;
  795. cfg->com_vco_tune_ctrl = 0x1C;
  796. cfg->com_svs_mode_clk_sel =
  797. (bclk >= HDMI_DIG_FREQ_BIT_CLK_THRESHOLD ? 1 : 2);
  798. cfg->com_hsclk_sel = (0x28 | hsclk);
  799. cfg->com_pll_cctrl_mode0 = cctrl;
  800. cfg->com_pll_rctrl_mode0 = rctrl;
  801. cfg->com_cp_ctrl_mode0 = cpctrl;
  802. cfg->com_dec_start_mode0 = dec_start;
  803. cfg->com_div_frac_start1_mode0 = (frac_start & 0xFF);
  804. cfg->com_div_frac_start2_mode0 = ((frac_start & 0xFF00) >> 8);
  805. cfg->com_div_frac_start3_mode0 = ((frac_start & 0xF0000) >> 16);
  806. cfg->com_integloop_gain0_mode0 = (integloop_gain & 0xFF);
  807. cfg->com_integloop_gain1_mode0 = ((integloop_gain & 0xF00) >> 8);
  808. cfg->com_lock_cmp1_mode0 = (pll_cmp & 0xFF);
  809. cfg->com_lock_cmp2_mode0 = ((pll_cmp & 0xFF00) >> 8);
  810. cfg->com_lock_cmp3_mode0 = ((pll_cmp & 0x30000) >> 16);
  811. cfg->com_core_clk_en = (0x6C | (HDMI_CLKS_PLL_DIVSEL << 4));
  812. cfg->com_coreclk_div = HDMI_CORECLK_DIV;
  813. if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) {
  814. cfg->tx_l0_tx_drv_lvl = 0x25;
  815. cfg->tx_l0_tx_emp_post1_lvl = 0x23;
  816. cfg->tx_l1_tx_drv_lvl = 0x25;
  817. cfg->tx_l1_tx_emp_post1_lvl = 0x23;
  818. cfg->tx_l2_tx_drv_lvl = 0x25;
  819. cfg->tx_l2_tx_emp_post1_lvl = 0x23;
  820. cfg->tx_l3_tx_drv_lvl = 0x22;
  821. cfg->tx_l3_tx_emp_post1_lvl = 0x27;
  822. cfg->tx_l0_vmode_ctrl1 = 0x00;
  823. cfg->tx_l0_vmode_ctrl2 = 0x0D;
  824. cfg->tx_l1_vmode_ctrl1 = 0x00;
  825. cfg->tx_l1_vmode_ctrl2 = 0x0D;
  826. cfg->tx_l2_vmode_ctrl1 = 0x00;
  827. cfg->tx_l2_vmode_ctrl2 = 0x0D;
  828. cfg->tx_l3_vmode_ctrl1 = 0x00;
  829. cfg->tx_l3_vmode_ctrl2 = 0x00;
  830. cfg->com_restrim_ctrl = 0x0;
  831. } else if (bclk > HDMI_MID_FREQ_BIT_CLK_THRESHOLD) {
  832. cfg->tx_l0_tx_drv_lvl = 0x25;
  833. cfg->tx_l0_tx_emp_post1_lvl = 0x23;
  834. cfg->tx_l1_tx_drv_lvl = 0x25;
  835. cfg->tx_l1_tx_emp_post1_lvl = 0x23;
  836. cfg->tx_l2_tx_drv_lvl = 0x25;
  837. cfg->tx_l2_tx_emp_post1_lvl = 0x23;
  838. cfg->tx_l3_tx_drv_lvl = 0x25;
  839. cfg->tx_l3_tx_emp_post1_lvl = 0x23;
  840. cfg->tx_l0_vmode_ctrl1 = 0x00;
  841. cfg->tx_l0_vmode_ctrl2 = 0x0D;
  842. cfg->tx_l1_vmode_ctrl1 = 0x00;
  843. cfg->tx_l1_vmode_ctrl2 = 0x0D;
  844. cfg->tx_l2_vmode_ctrl1 = 0x00;
  845. cfg->tx_l2_vmode_ctrl2 = 0x0D;
  846. cfg->tx_l3_vmode_ctrl1 = 0x00;
  847. cfg->tx_l3_vmode_ctrl2 = 0x00;
  848. cfg->com_restrim_ctrl = 0x0;
  849. } else {
  850. cfg->tx_l0_tx_drv_lvl = 0x20;
  851. cfg->tx_l0_tx_emp_post1_lvl = 0x20;
  852. cfg->tx_l1_tx_drv_lvl = 0x20;
  853. cfg->tx_l1_tx_emp_post1_lvl = 0x20;
  854. cfg->tx_l2_tx_drv_lvl = 0x20;
  855. cfg->tx_l2_tx_emp_post1_lvl = 0x20;
  856. cfg->tx_l3_tx_drv_lvl = 0x20;
  857. cfg->tx_l3_tx_emp_post1_lvl = 0x20;
  858. cfg->tx_l0_vmode_ctrl1 = 0x00;
  859. cfg->tx_l0_vmode_ctrl2 = 0x0E;
  860. cfg->tx_l1_vmode_ctrl1 = 0x00;
  861. cfg->tx_l1_vmode_ctrl2 = 0x0E;
  862. cfg->tx_l2_vmode_ctrl1 = 0x00;
  863. cfg->tx_l2_vmode_ctrl2 = 0x0E;
  864. cfg->tx_l3_vmode_ctrl1 = 0x00;
  865. cfg->tx_l3_vmode_ctrl2 = 0x0E;
  866. cfg->com_restrim_ctrl = 0xD8;
  867. }
  868. cfg->phy_mode = (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) ? 0x10 : 0x0;
  869. DEV_DBG("HDMI 8996 PLL: PLL Settings\n");
  870. DEV_DBG("PLL PARAM: tx_l0_lane_mode = 0x%x\n", cfg->tx_l0_lane_mode);
  871. DEV_DBG("PLL PARAM: tx_l2_lane_mode = 0x%x\n", cfg->tx_l2_lane_mode);
  872. DEV_DBG("PLL PARAM: tx_l0_tx_band = 0x%x\n", cfg->tx_l0_tx_band);
  873. DEV_DBG("PLL PARAM: tx_l1_tx_band = 0x%x\n", cfg->tx_l1_tx_band);
  874. DEV_DBG("PLL PARAM: tx_l2_tx_band = 0x%x\n", cfg->tx_l2_tx_band);
  875. DEV_DBG("PLL PARAM: tx_l3_tx_band = 0x%x\n", cfg->tx_l3_tx_band);
  876. DEV_DBG("PLL PARAM: com_svs_mode_clk_sel = 0x%x\n",
  877. cfg->com_svs_mode_clk_sel);
  878. DEV_DBG("PLL PARAM: com_hsclk_sel = 0x%x\n", cfg->com_hsclk_sel);
  879. DEV_DBG("PLL PARAM: com_pll_cctrl_mode0 = 0x%x\n",
  880. cfg->com_pll_cctrl_mode0);
  881. DEV_DBG("PLL PARAM: com_pll_rctrl_mode0 = 0x%x\n",
  882. cfg->com_pll_rctrl_mode0);
  883. DEV_DBG("PLL PARAM: com_cp_ctrl_mode0 = 0x%x\n",
  884. cfg->com_cp_ctrl_mode0);
  885. DEV_DBG("PLL PARAM: com_dec_start_mode0 = 0x%x\n",
  886. cfg->com_dec_start_mode0);
  887. DEV_DBG("PLL PARAM: com_div_frac_start1_mode0 = 0x%x\n",
  888. cfg->com_div_frac_start1_mode0);
  889. DEV_DBG("PLL PARAM: com_div_frac_start2_mode0 = 0x%x\n",
  890. cfg->com_div_frac_start2_mode0);
  891. DEV_DBG("PLL PARAM: com_div_frac_start3_mode0 = 0x%x\n",
  892. cfg->com_div_frac_start3_mode0);
  893. DEV_DBG("PLL PARAM: com_integloop_gain0_mode0 = 0x%x\n",
  894. cfg->com_integloop_gain0_mode0);
  895. DEV_DBG("PLL PARAM: com_integloop_gain1_mode0 = 0x%x\n",
  896. cfg->com_integloop_gain1_mode0);
  897. DEV_DBG("PLL PARAM: com_lock_cmp1_mode0 = 0x%x\n",
  898. cfg->com_lock_cmp1_mode0);
  899. DEV_DBG("PLL PARAM: com_lock_cmp2_mode0 = 0x%x\n",
  900. cfg->com_lock_cmp2_mode0);
  901. DEV_DBG("PLL PARAM: com_lock_cmp3_mode0 = 0x%x\n",
  902. cfg->com_lock_cmp3_mode0);
  903. DEV_DBG("PLL PARAM: com_core_clk_en = 0x%x\n", cfg->com_core_clk_en);
  904. DEV_DBG("PLL PARAM: com_coreclk_div = 0x%x\n", cfg->com_coreclk_div);
  905. DEV_DBG("PLL PARAM: com_restrim_ctrl = 0x%x\n", cfg->com_restrim_ctrl);
  906. DEV_DBG("PLL PARAM: l0_tx_drv_lvl = 0x%x\n", cfg->tx_l0_tx_drv_lvl);
  907. DEV_DBG("PLL PARAM: l0_tx_emp_post1_lvl = 0x%x\n",
  908. cfg->tx_l0_tx_emp_post1_lvl);
  909. DEV_DBG("PLL PARAM: l1_tx_drv_lvl = 0x%x\n", cfg->tx_l1_tx_drv_lvl);
  910. DEV_DBG("PLL PARAM: l1_tx_emp_post1_lvl = 0x%x\n",
  911. cfg->tx_l1_tx_emp_post1_lvl);
  912. DEV_DBG("PLL PARAM: l2_tx_drv_lvl = 0x%x\n", cfg->tx_l2_tx_drv_lvl);
  913. DEV_DBG("PLL PARAM: l2_tx_emp_post1_lvl = 0x%x\n",
  914. cfg->tx_l2_tx_emp_post1_lvl);
  915. DEV_DBG("PLL PARAM: l3_tx_drv_lvl = 0x%x\n", cfg->tx_l3_tx_drv_lvl);
  916. DEV_DBG("PLL PARAM: l3_tx_emp_post1_lvl = 0x%x\n",
  917. cfg->tx_l3_tx_emp_post1_lvl);
  918. DEV_DBG("PLL PARAM: l0_vmode_ctrl1 = 0x%x\n", cfg->tx_l0_vmode_ctrl1);
  919. DEV_DBG("PLL PARAM: l0_vmode_ctrl2 = 0x%x\n", cfg->tx_l0_vmode_ctrl2);
  920. DEV_DBG("PLL PARAM: l1_vmode_ctrl1 = 0x%x\n", cfg->tx_l1_vmode_ctrl1);
  921. DEV_DBG("PLL PARAM: l1_vmode_ctrl2 = 0x%x\n", cfg->tx_l1_vmode_ctrl2);
  922. DEV_DBG("PLL PARAM: l2_vmode_ctrl1 = 0x%x\n", cfg->tx_l2_vmode_ctrl1);
  923. DEV_DBG("PLL PARAM: l2_vmode_ctrl2 = 0x%x\n", cfg->tx_l2_vmode_ctrl2);
  924. DEV_DBG("PLL PARAM: l3_vmode_ctrl1 = 0x%x\n", cfg->tx_l3_vmode_ctrl1);
  925. DEV_DBG("PLL PARAM: l3_vmode_ctrl2 = 0x%x\n", cfg->tx_l3_vmode_ctrl2);
  926. DEV_DBG("PLL PARAM: tx_l0_res_code_lane_tx = 0x%x\n",
  927. cfg->tx_l0_res_code_lane_tx);
  928. DEV_DBG("PLL PARAM: tx_l1_res_code_lane_tx = 0x%x\n",
  929. cfg->tx_l1_res_code_lane_tx);
  930. DEV_DBG("PLL PARAM: tx_l2_res_code_lane_tx = 0x%x\n",
  931. cfg->tx_l2_res_code_lane_tx);
  932. DEV_DBG("PLL PARAM: tx_l3_res_code_lane_tx = 0x%x\n",
  933. cfg->tx_l3_res_code_lane_tx);
  934. DEV_DBG("PLL PARAM: phy_mode = 0x%x\n", cfg->phy_mode);
  935. rc = 0;
  936. fail:
  937. return rc;
  938. }
  939. static int hdmi_8996_v2_calculate(u32 pix_clk,
  940. struct hdmi_8996_phy_pll_reg_cfg *cfg)
  941. {
  942. int rc = -EINVAL;
  943. u64 fdata, clk_divtx, tmds_clk;
  944. u64 bclk;
  945. u64 post_div;
  946. u64 core_clk_div;
  947. u64 core_clk_div_ratio;
  948. u64 core_clk;
  949. u64 pll_cmp;
  950. u64 tx_band;
  951. u64 tx_band_div_ratio;
  952. u64 hsclk;
  953. u64 dec_start;
  954. u64 frac_start;
  955. u64 pll_divisor = 4 * HDMI_REF_CLOCK;
  956. u64 cpctrl;
  957. u64 rctrl;
  958. u64 cctrl;
  959. u64 integloop_gain;
  960. u64 vco_tune;
  961. u64 vco_freq;
  962. u64 vco_range;
  963. u64 rem;
  964. /* FDATA, CLK_DIVTX, PIXEL_CLK, TMDS_CLK */
  965. bclk = ((u64)pix_clk) * HDMI_BIT_CLK_TO_PIX_CLK_RATIO;
  966. if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD)
  967. tmds_clk = pix_clk >> 2;
  968. else
  969. tmds_clk = pix_clk;
  970. vco_range = bclk < HDMI_282MHZ_BIT_CLK_HZ ? HDMI_2000MHZ_BIT_CLK_HZ :
  971. HDMI_2250MHZ_BIT_CLK_HZ;
  972. fdata = hdmi_8996_v2_get_fdata(bclk, vco_range);
  973. if (fdata == HDMI_64B_ERR_VAL)
  974. goto fail;
  975. hsclk = hdmi_8996_v2_get_hsclk(fdata, vco_range);
  976. if (hsclk == HDMI_64B_ERR_VAL)
  977. goto fail;
  978. if (bclk >= vco_range)
  979. post_div = hdmi_8996_v2_get_post_div_gt_2g(hsclk);
  980. else
  981. post_div = hdmi_8996_v2_get_post_div_lt_2g(bclk, vco_range);
  982. if (post_div == HDMI_64B_ERR_VAL)
  983. goto fail;
  984. core_clk_div = 5;
  985. core_clk_div_ratio = core_clk_div * 2;
  986. tx_band = hdmi_8996_v2_get_tx_band(bclk, vco_range);
  987. if (tx_band == HDMI_64B_ERR_VAL)
  988. goto fail;
  989. tx_band_div_ratio = 1 << tx_band;
  990. vco_freq = hdmi_8996_v2_get_vco_freq(bclk, vco_range);
  991. clk_divtx = vco_freq;
  992. do_div(clk_divtx, post_div);
  993. /* Decimal and fraction values */
  994. dec_start = fdata * post_div;
  995. do_div(dec_start, pll_divisor);
  996. frac_start = ((pll_divisor - (((dec_start + 1) * pll_divisor) -
  997. (fdata * post_div))) * (1 << 20));
  998. rem = do_div(frac_start, pll_divisor);
  999. /* Round off frac_start to closest integer */
  1000. if (rem >= (pll_divisor >> 1))
  1001. frac_start++;
  1002. cpctrl = hdmi_8996_get_cpctrl(frac_start, false);
  1003. rctrl = hdmi_8996_get_rctrl(frac_start, false);
  1004. cctrl = hdmi_8996_get_cctrl(frac_start, false);
  1005. integloop_gain = hdmi_8996_get_integloop_gain(frac_start, false);
  1006. vco_tune = hdmi_8996_get_vco_tune(fdata, post_div);
  1007. core_clk = clk_divtx;
  1008. do_div(core_clk, core_clk_div_ratio);
  1009. pll_cmp = hdmi_8996_get_pll_cmp(1024, core_clk);
  1010. /* Debug dump */
  1011. DEV_DBG("%s: VCO freq: %llu\n", __func__, vco_freq);
  1012. DEV_DBG("%s: fdata: %llu\n", __func__, fdata);
  1013. DEV_DBG("%s: CLK_DIVTX: %llu\n", __func__, clk_divtx);
  1014. DEV_DBG("%s: pix_clk: %d\n", __func__, pix_clk);
  1015. DEV_DBG("%s: tmds clk: %llu\n", __func__, tmds_clk);
  1016. DEV_DBG("%s: HSCLK_SEL: %llu\n", __func__, hsclk);
  1017. DEV_DBG("%s: DEC_START: %llu\n", __func__, dec_start);
  1018. DEV_DBG("%s: DIV_FRAC_START: %llu\n", __func__, frac_start);
  1019. DEV_DBG("%s: PLL_CPCTRL: %llu\n", __func__, cpctrl);
  1020. DEV_DBG("%s: PLL_RCTRL: %llu\n", __func__, rctrl);
  1021. DEV_DBG("%s: PLL_CCTRL: %llu\n", __func__, cctrl);
  1022. DEV_DBG("%s: INTEGLOOP_GAIN: %llu\n", __func__, integloop_gain);
  1023. DEV_DBG("%s: VCO_TUNE: %llu\n", __func__, vco_tune);
  1024. DEV_DBG("%s: TX_BAND: %llu\n", __func__, tx_band);
  1025. DEV_DBG("%s: PLL_CMP: %llu\n", __func__, pll_cmp);
  1026. /* Convert these values to register specific values */
  1027. cfg->tx_l0_lane_mode = 0x3;
  1028. cfg->tx_l2_lane_mode = 0x3;
  1029. cfg->tx_l0_tx_band = tx_band + 4;
  1030. cfg->tx_l1_tx_band = tx_band + 4;
  1031. cfg->tx_l2_tx_band = tx_band + 4;
  1032. cfg->tx_l3_tx_band = tx_band + 4;
  1033. if (bclk > HDMI_DIG_FREQ_BIT_CLK_THRESHOLD)
  1034. cfg->com_svs_mode_clk_sel = 1;
  1035. else
  1036. cfg->com_svs_mode_clk_sel = 2;
  1037. cfg->com_hsclk_sel = (0x28 | hsclk);
  1038. cfg->com_pll_cctrl_mode0 = cctrl;
  1039. cfg->com_pll_rctrl_mode0 = rctrl;
  1040. cfg->com_cp_ctrl_mode0 = cpctrl;
  1041. cfg->com_dec_start_mode0 = dec_start;
  1042. cfg->com_div_frac_start1_mode0 = (frac_start & 0xFF);
  1043. cfg->com_div_frac_start2_mode0 = ((frac_start & 0xFF00) >> 8);
  1044. cfg->com_div_frac_start3_mode0 = ((frac_start & 0xF0000) >> 16);
  1045. cfg->com_integloop_gain0_mode0 = (integloop_gain & 0xFF);
  1046. cfg->com_integloop_gain1_mode0 = ((integloop_gain & 0xF00) >> 8);
  1047. cfg->com_lock_cmp1_mode0 = (pll_cmp & 0xFF);
  1048. cfg->com_lock_cmp2_mode0 = ((pll_cmp & 0xFF00) >> 8);
  1049. cfg->com_lock_cmp3_mode0 = ((pll_cmp & 0x30000) >> 16);
  1050. cfg->com_core_clk_en = (0x6C | (HDMI_CLKS_PLL_DIVSEL << 4));
  1051. cfg->com_coreclk_div = HDMI_CORECLK_DIV;
  1052. cfg->com_vco_tune_ctrl = 0x0;
  1053. if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) {
  1054. cfg->tx_l0_tx_drv_lvl = 0x25;
  1055. cfg->tx_l0_tx_emp_post1_lvl = 0x23;
  1056. cfg->tx_l1_tx_drv_lvl = 0x25;
  1057. cfg->tx_l1_tx_emp_post1_lvl = 0x23;
  1058. cfg->tx_l2_tx_drv_lvl = 0x25;
  1059. cfg->tx_l2_tx_emp_post1_lvl = 0x23;
  1060. cfg->tx_l3_tx_drv_lvl = 0x22;
  1061. cfg->tx_l3_tx_emp_post1_lvl = 0x27;
  1062. cfg->tx_l0_vmode_ctrl1 = 0x00;
  1063. cfg->tx_l0_vmode_ctrl2 = 0x0D;
  1064. cfg->tx_l1_vmode_ctrl1 = 0x00;
  1065. cfg->tx_l1_vmode_ctrl2 = 0x0D;
  1066. cfg->tx_l2_vmode_ctrl1 = 0x00;
  1067. cfg->tx_l2_vmode_ctrl2 = 0x0D;
  1068. cfg->tx_l3_vmode_ctrl1 = 0x00;
  1069. cfg->tx_l3_vmode_ctrl2 = 0x00;
  1070. cfg->tx_l0_res_code_lane_tx = 0x3F;
  1071. cfg->tx_l1_res_code_lane_tx = 0x3F;
  1072. cfg->tx_l2_res_code_lane_tx = 0x3F;
  1073. cfg->tx_l3_res_code_lane_tx = 0x3F;
  1074. cfg->com_restrim_ctrl = 0x0;
  1075. } else if (bclk > HDMI_MID_FREQ_BIT_CLK_THRESHOLD) {
  1076. cfg->tx_l0_tx_drv_lvl = 0x25;
  1077. cfg->tx_l0_tx_emp_post1_lvl = 0x23;
  1078. cfg->tx_l1_tx_drv_lvl = 0x25;
  1079. cfg->tx_l1_tx_emp_post1_lvl = 0x23;
  1080. cfg->tx_l2_tx_drv_lvl = 0x25;
  1081. cfg->tx_l2_tx_emp_post1_lvl = 0x23;
  1082. cfg->tx_l3_tx_drv_lvl = 0x25;
  1083. cfg->tx_l3_tx_emp_post1_lvl = 0x23;
  1084. cfg->tx_l0_vmode_ctrl1 = 0x00;
  1085. cfg->tx_l0_vmode_ctrl2 = 0x0D;
  1086. cfg->tx_l1_vmode_ctrl1 = 0x00;
  1087. cfg->tx_l1_vmode_ctrl2 = 0x0D;
  1088. cfg->tx_l2_vmode_ctrl1 = 0x00;
  1089. cfg->tx_l2_vmode_ctrl2 = 0x0D;
  1090. cfg->tx_l3_vmode_ctrl1 = 0x00;
  1091. cfg->tx_l3_vmode_ctrl2 = 0x00;
  1092. cfg->tx_l0_res_code_lane_tx = 0x39;
  1093. cfg->tx_l1_res_code_lane_tx = 0x39;
  1094. cfg->tx_l2_res_code_lane_tx = 0x39;
  1095. cfg->tx_l3_res_code_lane_tx = 0x39;
  1096. cfg->com_restrim_ctrl = 0x0;
  1097. } else {
  1098. cfg->tx_l0_tx_drv_lvl = 0x20;
  1099. cfg->tx_l0_tx_emp_post1_lvl = 0x20;
  1100. cfg->tx_l1_tx_drv_lvl = 0x20;
  1101. cfg->tx_l1_tx_emp_post1_lvl = 0x20;
  1102. cfg->tx_l2_tx_drv_lvl = 0x20;
  1103. cfg->tx_l2_tx_emp_post1_lvl = 0x20;
  1104. cfg->tx_l3_tx_drv_lvl = 0x20;
  1105. cfg->tx_l3_tx_emp_post1_lvl = 0x20;
  1106. cfg->tx_l0_vmode_ctrl1 = 0x00;
  1107. cfg->tx_l0_vmode_ctrl2 = 0x0E;
  1108. cfg->tx_l1_vmode_ctrl1 = 0x00;
  1109. cfg->tx_l1_vmode_ctrl2 = 0x0E;
  1110. cfg->tx_l2_vmode_ctrl1 = 0x00;
  1111. cfg->tx_l2_vmode_ctrl2 = 0x0E;
  1112. cfg->tx_l3_vmode_ctrl1 = 0x00;
  1113. cfg->tx_l3_vmode_ctrl2 = 0x0E;
  1114. cfg->tx_l0_res_code_lane_tx = 0x3F;
  1115. cfg->tx_l1_res_code_lane_tx = 0x3F;
  1116. cfg->tx_l2_res_code_lane_tx = 0x3F;
  1117. cfg->tx_l3_res_code_lane_tx = 0x3F;
  1118. cfg->com_restrim_ctrl = 0xD8;
  1119. }
  1120. cfg->phy_mode = (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) ? 0x10 : 0x0;
  1121. DEV_DBG("HDMI 8996 PLL: PLL Settings\n");
  1122. DEV_DBG("PLL PARAM: tx_l0_lane_mode = 0x%x\n", cfg->tx_l0_lane_mode);
  1123. DEV_DBG("PLL PARAM: tx_l2_lane_mode = 0x%x\n", cfg->tx_l2_lane_mode);
  1124. DEV_DBG("PLL PARAM: tx_l0_tx_band = 0x%x\n", cfg->tx_l0_tx_band);
  1125. DEV_DBG("PLL PARAM: tx_l1_tx_band = 0x%x\n", cfg->tx_l1_tx_band);
  1126. DEV_DBG("PLL PARAM: tx_l2_tx_band = 0x%x\n", cfg->tx_l2_tx_band);
  1127. DEV_DBG("PLL PARAM: tx_l3_tx_band = 0x%x\n", cfg->tx_l3_tx_band);
  1128. DEV_DBG("PLL PARAM: com_svs_mode_clk_sel = 0x%x\n",
  1129. cfg->com_svs_mode_clk_sel);
  1130. DEV_DBG("PLL PARAM: com_vco_tune_ctrl = 0x%x\n",
  1131. cfg->com_vco_tune_ctrl);
  1132. DEV_DBG("PLL PARAM: com_hsclk_sel = 0x%x\n", cfg->com_hsclk_sel);
  1133. DEV_DBG("PLL PARAM: com_lock_cmp_en = 0x%x\n", cfg->com_lock_cmp_en);
  1134. DEV_DBG("PLL PARAM: com_pll_cctrl_mode0 = 0x%x\n",
  1135. cfg->com_pll_cctrl_mode0);
  1136. DEV_DBG("PLL PARAM: com_pll_rctrl_mode0 = 0x%x\n",
  1137. cfg->com_pll_rctrl_mode0);
  1138. DEV_DBG("PLL PARAM: com_cp_ctrl_mode0 = 0x%x\n",
  1139. cfg->com_cp_ctrl_mode0);
  1140. DEV_DBG("PLL PARAM: com_dec_start_mode0 = 0x%x\n",
  1141. cfg->com_dec_start_mode0);
  1142. DEV_DBG("PLL PARAM: com_div_frac_start1_mode0 = 0x%x\n",
  1143. cfg->com_div_frac_start1_mode0);
  1144. DEV_DBG("PLL PARAM: com_div_frac_start2_mode0 = 0x%x\n",
  1145. cfg->com_div_frac_start2_mode0);
  1146. DEV_DBG("PLL PARAM: com_div_frac_start3_mode0 = 0x%x\n",
  1147. cfg->com_div_frac_start3_mode0);
  1148. DEV_DBG("PLL PARAM: com_integloop_gain0_mode0 = 0x%x\n",
  1149. cfg->com_integloop_gain0_mode0);
  1150. DEV_DBG("PLL PARAM: com_integloop_gain1_mode0 = 0x%x\n",
  1151. cfg->com_integloop_gain1_mode0);
  1152. DEV_DBG("PLL PARAM: com_lock_cmp1_mode0 = 0x%x\n",
  1153. cfg->com_lock_cmp1_mode0);
  1154. DEV_DBG("PLL PARAM: com_lock_cmp2_mode0 = 0x%x\n",
  1155. cfg->com_lock_cmp2_mode0);
  1156. DEV_DBG("PLL PARAM: com_lock_cmp3_mode0 = 0x%x\n",
  1157. cfg->com_lock_cmp3_mode0);
  1158. DEV_DBG("PLL PARAM: com_core_clk_en = 0x%x\n", cfg->com_core_clk_en);
  1159. DEV_DBG("PLL PARAM: com_coreclk_div = 0x%x\n", cfg->com_coreclk_div);
  1160. DEV_DBG("PLL PARAM: l0_tx_drv_lvl = 0x%x\n", cfg->tx_l0_tx_drv_lvl);
  1161. DEV_DBG("PLL PARAM: l0_tx_emp_post1_lvl = 0x%x\n",
  1162. cfg->tx_l0_tx_emp_post1_lvl);
  1163. DEV_DBG("PLL PARAM: l1_tx_drv_lvl = 0x%x\n", cfg->tx_l1_tx_drv_lvl);
  1164. DEV_DBG("PLL PARAM: l1_tx_emp_post1_lvl = 0x%x\n",
  1165. cfg->tx_l1_tx_emp_post1_lvl);
  1166. DEV_DBG("PLL PARAM: l2_tx_drv_lvl = 0x%x\n", cfg->tx_l2_tx_drv_lvl);
  1167. DEV_DBG("PLL PARAM: l2_tx_emp_post1_lvl = 0x%x\n",
  1168. cfg->tx_l2_tx_emp_post1_lvl);
  1169. DEV_DBG("PLL PARAM: l3_tx_drv_lvl = 0x%x\n", cfg->tx_l3_tx_drv_lvl);
  1170. DEV_DBG("PLL PARAM: l3_tx_emp_post1_lvl = 0x%x\n",
  1171. cfg->tx_l3_tx_emp_post1_lvl);
  1172. DEV_DBG("PLL PARAM: l0_vmode_ctrl1 = 0x%x\n", cfg->tx_l0_vmode_ctrl1);
  1173. DEV_DBG("PLL PARAM: l0_vmode_ctrl2 = 0x%x\n", cfg->tx_l0_vmode_ctrl2);
  1174. DEV_DBG("PLL PARAM: l1_vmode_ctrl1 = 0x%x\n", cfg->tx_l1_vmode_ctrl1);
  1175. DEV_DBG("PLL PARAM: l1_vmode_ctrl2 = 0x%x\n", cfg->tx_l1_vmode_ctrl2);
  1176. DEV_DBG("PLL PARAM: l2_vmode_ctrl1 = 0x%x\n", cfg->tx_l2_vmode_ctrl1);
  1177. DEV_DBG("PLL PARAM: l2_vmode_ctrl2 = 0x%x\n", cfg->tx_l2_vmode_ctrl2);
  1178. DEV_DBG("PLL PARAM: l3_vmode_ctrl1 = 0x%x\n", cfg->tx_l3_vmode_ctrl1);
  1179. DEV_DBG("PLL PARAM: l3_vmode_ctrl2 = 0x%x\n", cfg->tx_l3_vmode_ctrl2);
  1180. DEV_DBG("PLL PARAM: tx_l0_res_code_lane_tx = 0x%x\n",
  1181. cfg->tx_l0_res_code_lane_tx);
  1182. DEV_DBG("PLL PARAM: tx_l1_res_code_lane_tx = 0x%x\n",
  1183. cfg->tx_l1_res_code_lane_tx);
  1184. DEV_DBG("PLL PARAM: tx_l2_res_code_lane_tx = 0x%x\n",
  1185. cfg->tx_l2_res_code_lane_tx);
  1186. DEV_DBG("PLL PARAM: tx_l3_res_code_lane_tx = 0x%x\n",
  1187. cfg->tx_l3_res_code_lane_tx);
  1188. DEV_DBG("PLL PARAM: com_restrim_ctrl = 0x%x\n", cfg->com_restrim_ctrl);
  1189. DEV_DBG("PLL PARAM: phy_mode = 0x%x\n", cfg->phy_mode);
  1190. rc = 0;
  1191. fail:
  1192. return rc;
  1193. }
  1194. static int hdmi_8996_v3_calculate(u32 pix_clk,
  1195. struct hdmi_8996_phy_pll_reg_cfg *cfg)
  1196. {
  1197. int rc = -EINVAL;
  1198. struct hdmi_8996_v3_post_divider pd;
  1199. u64 fdata, tmds_clk;
  1200. u64 bclk;
  1201. u64 pll_cmp;
  1202. u64 tx_band;
  1203. u64 hsclk;
  1204. u64 dec_start;
  1205. u64 frac_start;
  1206. u64 pll_divisor = 4 * HDMI_REF_CLOCK;
  1207. u64 cpctrl;
  1208. u64 rctrl;
  1209. u64 cctrl;
  1210. u64 integloop_gain;
  1211. u64 vco_freq;
  1212. u64 rem;
  1213. /* FDATA, HSCLK, PIXEL_CLK, TMDS_CLK */
  1214. bclk = ((u64)pix_clk) * HDMI_BIT_CLK_TO_PIX_CLK_RATIO;
  1215. if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD)
  1216. tmds_clk = pix_clk >> 2;
  1217. else
  1218. tmds_clk = pix_clk;
  1219. if (hdmi_8996_v3_get_post_div(&pd, bclk) || pd.vco_ratio <= 0 ||
  1220. pd.vco_freq <= 0)
  1221. goto fail;
  1222. vco_freq = pd.vco_freq;
  1223. fdata = pd.vco_freq;
  1224. do_div(fdata, pd.vco_ratio);
  1225. hsclk = pd.hsclk_divsel;
  1226. dec_start = vco_freq;
  1227. do_div(dec_start, pll_divisor);
  1228. frac_start = vco_freq * (1 << 20);
  1229. rem = do_div(frac_start, pll_divisor);
  1230. frac_start -= dec_start * (1 << 20);
  1231. if (rem > (pll_divisor >> 1))
  1232. frac_start++;
  1233. cpctrl = hdmi_8996_get_cpctrl(frac_start, false);
  1234. rctrl = hdmi_8996_get_rctrl(frac_start, false);
  1235. cctrl = hdmi_8996_get_cctrl(frac_start, false);
  1236. integloop_gain = hdmi_8996_v3_get_integloop_gain(frac_start, bclk,
  1237. false);
  1238. pll_cmp = hdmi_8996_v3_get_pll_cmp(1024, fdata);
  1239. tx_band = pd.tx_band_sel;
  1240. /* Debug dump */
  1241. DEV_DBG("%s: VCO freq: %llu\n", __func__, vco_freq);
  1242. DEV_DBG("%s: fdata: %llu\n", __func__, fdata);
  1243. DEV_DBG("%s: pix_clk: %d\n", __func__, pix_clk);
  1244. DEV_DBG("%s: tmds clk: %llu\n", __func__, tmds_clk);
  1245. DEV_DBG("%s: HSCLK_SEL: %llu\n", __func__, hsclk);
  1246. DEV_DBG("%s: DEC_START: %llu\n", __func__, dec_start);
  1247. DEV_DBG("%s: DIV_FRAC_START: %llu\n", __func__, frac_start);
  1248. DEV_DBG("%s: PLL_CPCTRL: %llu\n", __func__, cpctrl);
  1249. DEV_DBG("%s: PLL_RCTRL: %llu\n", __func__, rctrl);
  1250. DEV_DBG("%s: PLL_CCTRL: %llu\n", __func__, cctrl);
  1251. DEV_DBG("%s: INTEGLOOP_GAIN: %llu\n", __func__, integloop_gain);
  1252. DEV_DBG("%s: TX_BAND: %llu\n", __func__, tx_band);
  1253. DEV_DBG("%s: PLL_CMP: %llu\n", __func__, pll_cmp);
  1254. /* Convert these values to register specific values */
  1255. cfg->tx_l0_tx_band = tx_band + 4;
  1256. cfg->tx_l1_tx_band = tx_band + 4;
  1257. cfg->tx_l2_tx_band = tx_band + 4;
  1258. cfg->tx_l3_tx_band = tx_band + 4;
  1259. if (bclk > HDMI_DIG_FREQ_BIT_CLK_THRESHOLD)
  1260. cfg->com_svs_mode_clk_sel = 1;
  1261. else
  1262. cfg->com_svs_mode_clk_sel = 2;
  1263. cfg->com_hsclk_sel = (0x20 | hsclk);
  1264. cfg->com_pll_cctrl_mode0 = cctrl;
  1265. cfg->com_pll_rctrl_mode0 = rctrl;
  1266. cfg->com_cp_ctrl_mode0 = cpctrl;
  1267. cfg->com_dec_start_mode0 = dec_start;
  1268. cfg->com_div_frac_start1_mode0 = (frac_start & 0xFF);
  1269. cfg->com_div_frac_start2_mode0 = ((frac_start & 0xFF00) >> 8);
  1270. cfg->com_div_frac_start3_mode0 = ((frac_start & 0xF0000) >> 16);
  1271. cfg->com_integloop_gain0_mode0 = (integloop_gain & 0xFF);
  1272. cfg->com_integloop_gain1_mode0 = ((integloop_gain & 0xF00) >> 8);
  1273. cfg->com_lock_cmp1_mode0 = (pll_cmp & 0xFF);
  1274. cfg->com_lock_cmp2_mode0 = ((pll_cmp & 0xFF00) >> 8);
  1275. cfg->com_lock_cmp3_mode0 = ((pll_cmp & 0x30000) >> 16);
  1276. cfg->com_lock_cmp_en = 0x04;
  1277. cfg->com_core_clk_en = 0x2C;
  1278. cfg->com_coreclk_div = HDMI_CORECLK_DIV;
  1279. cfg->phy_mode = (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) ? 0x10 : 0x0;
  1280. cfg->com_vco_tune_ctrl = 0x0;
  1281. cfg->tx_l0_lane_mode = 0x43;
  1282. cfg->tx_l2_lane_mode = 0x43;
  1283. if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) {
  1284. cfg->tx_l0_tx_drv_lvl = 0x25;
  1285. cfg->tx_l0_tx_emp_post1_lvl = 0x23;
  1286. cfg->tx_l1_tx_drv_lvl = 0x25;
  1287. cfg->tx_l1_tx_emp_post1_lvl = 0x23;
  1288. cfg->tx_l2_tx_drv_lvl = 0x25;
  1289. cfg->tx_l2_tx_emp_post1_lvl = 0x23;
  1290. cfg->tx_l3_tx_drv_lvl = 0x22;
  1291. cfg->tx_l3_tx_emp_post1_lvl = 0x27;
  1292. cfg->tx_l0_vmode_ctrl1 = 0x00;
  1293. cfg->tx_l0_vmode_ctrl2 = 0x0D;
  1294. cfg->tx_l1_vmode_ctrl1 = 0x00;
  1295. cfg->tx_l1_vmode_ctrl2 = 0x0D;
  1296. cfg->tx_l2_vmode_ctrl1 = 0x00;
  1297. cfg->tx_l2_vmode_ctrl2 = 0x0D;
  1298. cfg->tx_l3_vmode_ctrl1 = 0x00;
  1299. cfg->tx_l3_vmode_ctrl2 = 0x00;
  1300. } else if (bclk > HDMI_MID_FREQ_BIT_CLK_THRESHOLD) {
  1301. cfg->tx_l0_tx_drv_lvl = 0x25;
  1302. cfg->tx_l0_tx_emp_post1_lvl = 0x23;
  1303. cfg->tx_l1_tx_drv_lvl = 0x25;
  1304. cfg->tx_l1_tx_emp_post1_lvl = 0x23;
  1305. cfg->tx_l2_tx_drv_lvl = 0x25;
  1306. cfg->tx_l2_tx_emp_post1_lvl = 0x23;
  1307. cfg->tx_l3_tx_drv_lvl = 0x25;
  1308. cfg->tx_l3_tx_emp_post1_lvl = 0x23;
  1309. cfg->tx_l0_vmode_ctrl1 = 0x00;
  1310. cfg->tx_l0_vmode_ctrl2 = 0x0D;
  1311. cfg->tx_l1_vmode_ctrl1 = 0x00;
  1312. cfg->tx_l1_vmode_ctrl2 = 0x0D;
  1313. cfg->tx_l2_vmode_ctrl1 = 0x00;
  1314. cfg->tx_l2_vmode_ctrl2 = 0x0D;
  1315. cfg->tx_l3_vmode_ctrl1 = 0x00;
  1316. cfg->tx_l3_vmode_ctrl2 = 0x00;
  1317. } else {
  1318. cfg->tx_l0_tx_drv_lvl = 0x20;
  1319. cfg->tx_l0_tx_emp_post1_lvl = 0x20;
  1320. cfg->tx_l1_tx_drv_lvl = 0x20;
  1321. cfg->tx_l1_tx_emp_post1_lvl = 0x20;
  1322. cfg->tx_l2_tx_drv_lvl = 0x20;
  1323. cfg->tx_l2_tx_emp_post1_lvl = 0x20;
  1324. cfg->tx_l3_tx_drv_lvl = 0x20;
  1325. cfg->tx_l3_tx_emp_post1_lvl = 0x20;
  1326. cfg->tx_l0_vmode_ctrl1 = 0x00;
  1327. cfg->tx_l0_vmode_ctrl2 = 0x0E;
  1328. cfg->tx_l1_vmode_ctrl1 = 0x00;
  1329. cfg->tx_l1_vmode_ctrl2 = 0x0E;
  1330. cfg->tx_l2_vmode_ctrl1 = 0x00;
  1331. cfg->tx_l2_vmode_ctrl2 = 0x0E;
  1332. cfg->tx_l3_vmode_ctrl1 = 0x00;
  1333. cfg->tx_l3_vmode_ctrl2 = 0x0E;
  1334. }
  1335. DEV_DBG("HDMI 8996 PLL: PLL Settings\n");
  1336. DEV_DBG("PLL PARAM: tx_l0_tx_band = 0x%x\n", cfg->tx_l0_tx_band);
  1337. DEV_DBG("PLL PARAM: tx_l1_tx_band = 0x%x\n", cfg->tx_l1_tx_band);
  1338. DEV_DBG("PLL PARAM: tx_l2_tx_band = 0x%x\n", cfg->tx_l2_tx_band);
  1339. DEV_DBG("PLL PARAM: tx_l3_tx_band = 0x%x\n", cfg->tx_l3_tx_band);
  1340. DEV_DBG("PLL PARAM: com_svs_mode_clk_sel = 0x%x\n",
  1341. cfg->com_svs_mode_clk_sel);
  1342. DEV_DBG("PLL PARAM: com_hsclk_sel = 0x%x\n", cfg->com_hsclk_sel);
  1343. DEV_DBG("PLL PARAM: com_lock_cmp_en = 0x%x\n", cfg->com_lock_cmp_en);
  1344. DEV_DBG("PLL PARAM: com_pll_cctrl_mode0 = 0x%x\n",
  1345. cfg->com_pll_cctrl_mode0);
  1346. DEV_DBG("PLL PARAM: com_pll_rctrl_mode0 = 0x%x\n",
  1347. cfg->com_pll_rctrl_mode0);
  1348. DEV_DBG("PLL PARAM: com_cp_ctrl_mode0 = 0x%x\n",
  1349. cfg->com_cp_ctrl_mode0);
  1350. DEV_DBG("PLL PARAM: com_dec_start_mode0 = 0x%x\n",
  1351. cfg->com_dec_start_mode0);
  1352. DEV_DBG("PLL PARAM: com_div_frac_start1_mode0 = 0x%x\n",
  1353. cfg->com_div_frac_start1_mode0);
  1354. DEV_DBG("PLL PARAM: com_div_frac_start2_mode0 = 0x%x\n",
  1355. cfg->com_div_frac_start2_mode0);
  1356. DEV_DBG("PLL PARAM: com_div_frac_start3_mode0 = 0x%x\n",
  1357. cfg->com_div_frac_start3_mode0);
  1358. DEV_DBG("PLL PARAM: com_integloop_gain0_mode0 = 0x%x\n",
  1359. cfg->com_integloop_gain0_mode0);
  1360. DEV_DBG("PLL PARAM: com_integloop_gain1_mode0 = 0x%x\n",
  1361. cfg->com_integloop_gain1_mode0);
  1362. DEV_DBG("PLL PARAM: com_lock_cmp1_mode0 = 0x%x\n",
  1363. cfg->com_lock_cmp1_mode0);
  1364. DEV_DBG("PLL PARAM: com_lock_cmp2_mode0 = 0x%x\n",
  1365. cfg->com_lock_cmp2_mode0);
  1366. DEV_DBG("PLL PARAM: com_lock_cmp3_mode0 = 0x%x\n",
  1367. cfg->com_lock_cmp3_mode0);
  1368. DEV_DBG("PLL PARAM: com_core_clk_en = 0x%x\n", cfg->com_core_clk_en);
  1369. DEV_DBG("PLL PARAM: com_coreclk_div = 0x%x\n", cfg->com_coreclk_div);
  1370. DEV_DBG("PLL PARAM: phy_mode = 0x%x\n", cfg->phy_mode);
  1371. DEV_DBG("PLL PARAM: tx_l0_lane_mode = 0x%x\n", cfg->tx_l0_lane_mode);
  1372. DEV_DBG("PLL PARAM: tx_l2_lane_mode = 0x%x\n", cfg->tx_l2_lane_mode);
  1373. DEV_DBG("PLL PARAM: l0_tx_drv_lvl = 0x%x\n", cfg->tx_l0_tx_drv_lvl);
  1374. DEV_DBG("PLL PARAM: l0_tx_emp_post1_lvl = 0x%x\n",
  1375. cfg->tx_l0_tx_emp_post1_lvl);
  1376. DEV_DBG("PLL PARAM: l1_tx_drv_lvl = 0x%x\n", cfg->tx_l1_tx_drv_lvl);
  1377. DEV_DBG("PLL PARAM: l1_tx_emp_post1_lvl = 0x%x\n",
  1378. cfg->tx_l1_tx_emp_post1_lvl);
  1379. DEV_DBG("PLL PARAM: l2_tx_drv_lvl = 0x%x\n", cfg->tx_l2_tx_drv_lvl);
  1380. DEV_DBG("PLL PARAM: l2_tx_emp_post1_lvl = 0x%x\n",
  1381. cfg->tx_l2_tx_emp_post1_lvl);
  1382. DEV_DBG("PLL PARAM: l3_tx_drv_lvl = 0x%x\n", cfg->tx_l3_tx_drv_lvl);
  1383. DEV_DBG("PLL PARAM: l3_tx_emp_post1_lvl = 0x%x\n",
  1384. cfg->tx_l3_tx_emp_post1_lvl);
  1385. DEV_DBG("PLL PARAM: l0_vmode_ctrl1 = 0x%x\n", cfg->tx_l0_vmode_ctrl1);
  1386. DEV_DBG("PLL PARAM: l0_vmode_ctrl2 = 0x%x\n", cfg->tx_l0_vmode_ctrl2);
  1387. DEV_DBG("PLL PARAM: l1_vmode_ctrl1 = 0x%x\n", cfg->tx_l1_vmode_ctrl1);
  1388. DEV_DBG("PLL PARAM: l1_vmode_ctrl2 = 0x%x\n", cfg->tx_l1_vmode_ctrl2);
  1389. DEV_DBG("PLL PARAM: l2_vmode_ctrl1 = 0x%x\n", cfg->tx_l2_vmode_ctrl1);
  1390. DEV_DBG("PLL PARAM: l2_vmode_ctrl2 = 0x%x\n", cfg->tx_l2_vmode_ctrl2);
  1391. DEV_DBG("PLL PARAM: l3_vmode_ctrl1 = 0x%x\n", cfg->tx_l3_vmode_ctrl1);
  1392. DEV_DBG("PLL PARAM: l3_vmode_ctrl2 = 0x%x\n", cfg->tx_l3_vmode_ctrl2);
  1393. rc = 0;
  1394. fail:
  1395. return rc;
  1396. }
  1397. static int hdmi_8996_calculate(u32 pix_clk,
  1398. struct hdmi_8996_phy_pll_reg_cfg *cfg, u32 ver)
  1399. {
  1400. switch (ver) {
  1401. case HDMI_VERSION_8996_V3:
  1402. case HDMI_VERSION_8996_V3_1_8:
  1403. return hdmi_8996_v3_calculate(pix_clk, cfg);
  1404. case HDMI_VERSION_8996_V2:
  1405. return hdmi_8996_v2_calculate(pix_clk, cfg);
  1406. default:
  1407. return hdmi_8996_v1_calculate(pix_clk, cfg);
  1408. }
  1409. }
  1410. static int hdmi_8996_phy_pll_set_clk_rate(struct clk *c, u32 tmds_clk, u32 ver)
  1411. {
  1412. int rc = 0;
  1413. struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c);
  1414. struct mdss_pll_resources *io = vco->priv;
  1415. struct hdmi_8996_phy_pll_reg_cfg cfg = {0};
  1416. rc = hdmi_8996_calculate(tmds_clk, &cfg, ver);
  1417. if (rc) {
  1418. DEV_ERR("%s: PLL calculation failed\n", __func__);
  1419. return rc;
  1420. }
  1421. /* Initially shut down PHY */
  1422. DEV_DBG("%s: Disabling PHY\n", __func__);
  1423. MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_PD_CTL, 0x0);
  1424. udelay(500);
  1425. /* Power up sequence */
  1426. switch (ver) {
  1427. case HDMI_VERSION_8996_V2:
  1428. case HDMI_VERSION_8996_V3:
  1429. case HDMI_VERSION_8996_V3_1_8:
  1430. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_BG_CTRL, 0x04);
  1431. break;
  1432. }
  1433. MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_PD_CTL, 0x1);
  1434. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_RESETSM_CNTRL, 0x20);
  1435. MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_TX0_TX1_LANE_CTL, 0x0F);
  1436. MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_TX2_TX3_LANE_CTL, 0x0F);
  1437. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
  1438. QSERDES_TX_L0_CLKBUF_ENABLE, 0x03);
  1439. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
  1440. QSERDES_TX_L0_CLKBUF_ENABLE, 0x03);
  1441. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
  1442. QSERDES_TX_L0_CLKBUF_ENABLE, 0x03);
  1443. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
  1444. QSERDES_TX_L0_CLKBUF_ENABLE, 0x03);
  1445. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
  1446. QSERDES_TX_L0_LANE_MODE, cfg.tx_l0_lane_mode);
  1447. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
  1448. QSERDES_TX_L0_LANE_MODE, cfg.tx_l2_lane_mode);
  1449. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
  1450. QSERDES_TX_L0_TX_BAND, cfg.tx_l0_tx_band);
  1451. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
  1452. QSERDES_TX_L0_TX_BAND, cfg.tx_l1_tx_band);
  1453. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
  1454. QSERDES_TX_L0_TX_BAND, cfg.tx_l2_tx_band);
  1455. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
  1456. QSERDES_TX_L0_TX_BAND, cfg.tx_l3_tx_band);
  1457. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
  1458. QSERDES_TX_L0_RESET_TSYNC_EN, 0x03);
  1459. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
  1460. QSERDES_TX_L0_RESET_TSYNC_EN, 0x03);
  1461. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
  1462. QSERDES_TX_L0_RESET_TSYNC_EN, 0x03);
  1463. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
  1464. QSERDES_TX_L0_RESET_TSYNC_EN, 0x03);
  1465. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SYSCLK_BUF_ENABLE, 0x1E);
  1466. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x07);
  1467. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SYSCLK_EN_SEL, 0x37);
  1468. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SYS_CLK_CTRL, 0x02);
  1469. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CLK_ENABLE1, 0x0E);
  1470. if (ver == HDMI_VERSION_8996_V1)
  1471. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_BG_CTRL, 0x06);
  1472. /* Bypass VCO calibration */
  1473. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SVS_MODE_CLK_SEL,
  1474. cfg.com_svs_mode_clk_sel);
  1475. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_BG_TRIM, 0x0F);
  1476. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_PLL_IVCO, 0x0F);
  1477. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_VCO_TUNE_CTRL,
  1478. cfg.com_vco_tune_ctrl);
  1479. switch (ver) {
  1480. case HDMI_VERSION_8996_V1:
  1481. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SVS_MODE_CLK_SEL,
  1482. cfg.com_svs_mode_clk_sel);
  1483. break;
  1484. default:
  1485. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_BG_CTRL, 0x06);
  1486. }
  1487. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CLK_SELECT, 0x30);
  1488. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_HSCLK_SEL,
  1489. cfg.com_hsclk_sel);
  1490. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_LOCK_CMP_EN,
  1491. cfg.com_lock_cmp_en);
  1492. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_PLL_CCTRL_MODE0,
  1493. cfg.com_pll_cctrl_mode0);
  1494. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_PLL_RCTRL_MODE0,
  1495. cfg.com_pll_rctrl_mode0);
  1496. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CP_CTRL_MODE0,
  1497. cfg.com_cp_ctrl_mode0);
  1498. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_DEC_START_MODE0,
  1499. cfg.com_dec_start_mode0);
  1500. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_DIV_FRAC_START1_MODE0,
  1501. cfg.com_div_frac_start1_mode0);
  1502. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_DIV_FRAC_START2_MODE0,
  1503. cfg.com_div_frac_start2_mode0);
  1504. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_DIV_FRAC_START3_MODE0,
  1505. cfg.com_div_frac_start3_mode0);
  1506. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_INTEGLOOP_GAIN0_MODE0,
  1507. cfg.com_integloop_gain0_mode0);
  1508. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_INTEGLOOP_GAIN1_MODE0,
  1509. cfg.com_integloop_gain1_mode0);
  1510. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_LOCK_CMP1_MODE0,
  1511. cfg.com_lock_cmp1_mode0);
  1512. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_LOCK_CMP2_MODE0,
  1513. cfg.com_lock_cmp2_mode0);
  1514. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_LOCK_CMP3_MODE0,
  1515. cfg.com_lock_cmp3_mode0);
  1516. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_VCO_TUNE_MAP, 0x00);
  1517. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CORE_CLK_EN,
  1518. cfg.com_core_clk_en);
  1519. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CORECLK_DIV,
  1520. cfg.com_coreclk_div);
  1521. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CMN_CONFIG, 0x02);
  1522. if (ver == HDMI_VERSION_8996_V3 || ver == HDMI_VERSION_8996_V3_1_8)
  1523. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_RESCODE_DIV_NUM, 0x15);
  1524. /* TX lanes setup (TX 0/1/2/3) */
  1525. if (ver == HDMI_VERSION_8996_V3_1_8) {
  1526. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
  1527. QSERDES_TX_L0_TX_DRV_LVL,
  1528. 0x00000023);
  1529. } else {
  1530. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
  1531. QSERDES_TX_L0_TX_DRV_LVL,
  1532. cfg.tx_l0_tx_drv_lvl);
  1533. }
  1534. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
  1535. QSERDES_TX_L0_TX_EMP_POST1_LVL,
  1536. cfg.tx_l0_tx_emp_post1_lvl);
  1537. if (ver == HDMI_VERSION_8996_V3_1_8) {
  1538. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
  1539. QSERDES_TX_L0_TX_DRV_LVL,
  1540. 0x00000023);
  1541. } else {
  1542. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
  1543. QSERDES_TX_L0_TX_DRV_LVL,
  1544. cfg.tx_l1_tx_drv_lvl);
  1545. }
  1546. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
  1547. QSERDES_TX_L0_TX_EMP_POST1_LVL,
  1548. cfg.tx_l1_tx_emp_post1_lvl);
  1549. if (ver == HDMI_VERSION_8996_V3_1_8) {
  1550. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
  1551. QSERDES_TX_L0_TX_DRV_LVL,
  1552. 0x00000023);
  1553. } else {
  1554. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
  1555. QSERDES_TX_L0_TX_DRV_LVL,
  1556. cfg.tx_l2_tx_drv_lvl);
  1557. }
  1558. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
  1559. QSERDES_TX_L0_TX_EMP_POST1_LVL,
  1560. cfg.tx_l2_tx_emp_post1_lvl);
  1561. if (ver == HDMI_VERSION_8996_V3_1_8) {
  1562. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
  1563. QSERDES_TX_L0_TX_DRV_LVL,
  1564. 0x00000020);
  1565. } else {
  1566. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
  1567. QSERDES_TX_L0_TX_DRV_LVL,
  1568. cfg.tx_l3_tx_drv_lvl);
  1569. }
  1570. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
  1571. QSERDES_TX_L0_TX_EMP_POST1_LVL,
  1572. cfg.tx_l3_tx_emp_post1_lvl);
  1573. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
  1574. QSERDES_TX_L0_VMODE_CTRL1,
  1575. cfg.tx_l0_vmode_ctrl1);
  1576. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
  1577. QSERDES_TX_L0_VMODE_CTRL2,
  1578. cfg.tx_l0_vmode_ctrl2);
  1579. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
  1580. QSERDES_TX_L0_VMODE_CTRL1,
  1581. cfg.tx_l1_vmode_ctrl1);
  1582. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
  1583. QSERDES_TX_L0_VMODE_CTRL2,
  1584. cfg.tx_l1_vmode_ctrl2);
  1585. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
  1586. QSERDES_TX_L0_VMODE_CTRL1,
  1587. cfg.tx_l2_vmode_ctrl1);
  1588. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
  1589. QSERDES_TX_L0_VMODE_CTRL2,
  1590. cfg.tx_l2_vmode_ctrl2);
  1591. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
  1592. QSERDES_TX_L0_VMODE_CTRL1,
  1593. cfg.tx_l3_vmode_ctrl1);
  1594. if (ver == HDMI_VERSION_8996_V3_1_8) {
  1595. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
  1596. QSERDES_TX_L0_VMODE_CTRL2,
  1597. 0x0000000D);
  1598. } else {
  1599. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
  1600. QSERDES_TX_L0_VMODE_CTRL2,
  1601. cfg.tx_l3_vmode_ctrl2);
  1602. }
  1603. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
  1604. QSERDES_TX_L0_TX_DRV_LVL_OFFSET, 0x00);
  1605. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
  1606. QSERDES_TX_L0_TX_DRV_LVL_OFFSET, 0x00);
  1607. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
  1608. QSERDES_TX_L0_TX_DRV_LVL_OFFSET, 0x00);
  1609. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
  1610. QSERDES_TX_L0_TX_DRV_LVL_OFFSET, 0x00);
  1611. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
  1612. QSERDES_TX_L0_RES_CODE_LANE_OFFSET, 0x00);
  1613. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
  1614. QSERDES_TX_L0_RES_CODE_LANE_OFFSET, 0x00);
  1615. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
  1616. QSERDES_TX_L0_RES_CODE_LANE_OFFSET, 0x00);
  1617. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
  1618. QSERDES_TX_L0_RES_CODE_LANE_OFFSET, 0x00);
  1619. if (ver < HDMI_VERSION_8996_V3) {
  1620. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
  1621. QSERDES_TX_L0_RES_CODE_LANE_TX,
  1622. cfg.tx_l0_res_code_lane_tx);
  1623. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
  1624. QSERDES_TX_L0_RES_CODE_LANE_TX,
  1625. cfg.tx_l1_res_code_lane_tx);
  1626. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
  1627. QSERDES_TX_L0_RES_CODE_LANE_TX,
  1628. cfg.tx_l2_res_code_lane_tx);
  1629. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
  1630. QSERDES_TX_L0_RES_CODE_LANE_TX,
  1631. cfg.tx_l3_res_code_lane_tx);
  1632. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_RESTRIM_CTRL,
  1633. cfg.com_restrim_ctrl);
  1634. MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_TXCAL_CFG0, 0x00);
  1635. MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_TXCAL_CFG1, 0x05);
  1636. }
  1637. MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_MODE, cfg.phy_mode);
  1638. MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_PD_CTL, 0x1F);
  1639. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
  1640. QSERDES_TX_L0_TRAN_DRVR_EMP_EN, 0x03);
  1641. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
  1642. QSERDES_TX_L0_TRAN_DRVR_EMP_EN, 0x03);
  1643. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
  1644. QSERDES_TX_L0_TRAN_DRVR_EMP_EN, 0x03);
  1645. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
  1646. QSERDES_TX_L0_TRAN_DRVR_EMP_EN, 0x03);
  1647. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
  1648. QSERDES_TX_L0_PARRATE_REC_DETECT_IDLE_EN, 0x40);
  1649. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
  1650. QSERDES_TX_L0_PARRATE_REC_DETECT_IDLE_EN, 0x40);
  1651. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
  1652. QSERDES_TX_L0_PARRATE_REC_DETECT_IDLE_EN, 0x40);
  1653. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
  1654. QSERDES_TX_L0_PARRATE_REC_DETECT_IDLE_EN, 0x40);
  1655. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
  1656. QSERDES_TX_L0_HP_PD_ENABLES, 0x0C);
  1657. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
  1658. QSERDES_TX_L0_HP_PD_ENABLES, 0x0C);
  1659. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
  1660. QSERDES_TX_L0_HP_PD_ENABLES, 0x0C);
  1661. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
  1662. QSERDES_TX_L0_HP_PD_ENABLES, 0x03);
  1663. if (ver == HDMI_VERSION_8996_V2) {
  1664. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_ATB_SEL1, 0x01);
  1665. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_ATB_SEL2, 0x01);
  1666. }
  1667. /*
  1668. * Ensure that vco configuration gets flushed to hardware before
  1669. * enabling the PLL
  1670. */
  1671. wmb();
  1672. return 0;
  1673. }
  1674. static int hdmi_8996_phy_ready_status(struct mdss_pll_resources *io)
  1675. {
  1676. u32 status = 0;
  1677. int phy_ready = 0;
  1678. int rc;
  1679. u32 read_count = 0;
  1680. rc = mdss_pll_resource_enable(io, true);
  1681. if (rc) {
  1682. DEV_ERR("%s: pll resource can't be enabled\n", __func__);
  1683. return rc;
  1684. }
  1685. DEV_DBG("%s: Waiting for PHY Ready\n", __func__);
  1686. /* Poll for PHY read status */
  1687. while (read_count < HDMI_PLL_POLL_MAX_READS) {
  1688. status = MDSS_PLL_REG_R(io->phy_base, HDMI_PHY_STATUS);
  1689. if ((status & BIT(0)) == 1) {
  1690. phy_ready = 1;
  1691. DEV_DBG("%s: PHY READY\n", __func__);
  1692. break;
  1693. }
  1694. udelay(HDMI_PLL_POLL_TIMEOUT_US);
  1695. read_count++;
  1696. }
  1697. if (read_count == HDMI_PLL_POLL_MAX_READS) {
  1698. phy_ready = 0;
  1699. DEV_DBG("%s: PHY READY TIMEOUT\n", __func__);
  1700. }
  1701. mdss_pll_resource_enable(io, false);
  1702. return phy_ready;
  1703. }
  1704. static int hdmi_8996_pll_lock_status(struct mdss_pll_resources *io)
  1705. {
  1706. u32 status;
  1707. int pll_locked = 0;
  1708. int rc;
  1709. u32 read_count = 0;
  1710. rc = mdss_pll_resource_enable(io, true);
  1711. if (rc) {
  1712. DEV_ERR("%s: pll resource can't be enabled\n", __func__);
  1713. return rc;
  1714. }
  1715. DEV_DBG("%s: Waiting for PLL lock\n", __func__);
  1716. while (read_count < HDMI_PLL_POLL_MAX_READS) {
  1717. status = MDSS_PLL_REG_R(io->pll_base,
  1718. QSERDES_COM_C_READY_STATUS);
  1719. if ((status & BIT(0)) == 1) {
  1720. pll_locked = 1;
  1721. DEV_DBG("%s: C READY\n", __func__);
  1722. break;
  1723. }
  1724. udelay(HDMI_PLL_POLL_TIMEOUT_US);
  1725. read_count++;
  1726. }
  1727. if (read_count == HDMI_PLL_POLL_MAX_READS) {
  1728. pll_locked = 0;
  1729. DEV_DBG("%s: C READY TIMEOUT\n", __func__);
  1730. }
  1731. mdss_pll_resource_enable(io, false);
  1732. return pll_locked;
  1733. }
  1734. static int hdmi_8996_v1_perform_sw_calibration(struct clk *c)
  1735. {
  1736. int rc = 0;
  1737. struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c);
  1738. struct mdss_pll_resources *io = vco->priv;
  1739. u32 max_code = 0x190;
  1740. u32 min_code = 0x0;
  1741. u32 max_cnt = 0;
  1742. u32 min_cnt = 0;
  1743. u32 expected_counter_value = 0;
  1744. u32 step = 0;
  1745. u32 dbus_all = 0;
  1746. u32 dbus_sel = 0;
  1747. u32 vco_code = 0;
  1748. u32 val = 0;
  1749. vco_code = 0xC8;
  1750. DEV_DBG("%s: Starting SW calibration with vco_code = %d\n", __func__,
  1751. vco_code);
  1752. expected_counter_value =
  1753. (MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_LOCK_CMP3_MODE0) << 16) |
  1754. (MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_LOCK_CMP2_MODE0) << 8) |
  1755. (MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_LOCK_CMP1_MODE0));
  1756. DEV_DBG("%s: expected_counter_value = %d\n", __func__,
  1757. expected_counter_value);
  1758. val = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_CMN_MISC1);
  1759. val |= BIT(4);
  1760. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CMN_MISC1, val);
  1761. val = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_CMN_MISC1);
  1762. val |= BIT(3);
  1763. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CMN_MISC1, val);
  1764. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_DEBUG_BUS_SEL, 0x4);
  1765. val = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_LOCK_CMP_CFG);
  1766. val |= BIT(1);
  1767. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_LOCK_CMP_CFG, val);
  1768. udelay(60);
  1769. while (1) {
  1770. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_VCO_TUNE1_MODE0,
  1771. vco_code & 0xFF);
  1772. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_VCO_TUNE2_MODE0,
  1773. (vco_code >> 8) & 0x3);
  1774. udelay(20);
  1775. val = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_LOCK_CMP_CFG);
  1776. val &= ~BIT(1);
  1777. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_LOCK_CMP_CFG, val);
  1778. udelay(60);
  1779. val = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_LOCK_CMP_CFG);
  1780. val |= BIT(1);
  1781. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_LOCK_CMP_CFG, val);
  1782. udelay(60);
  1783. dbus_all =
  1784. (MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_DEBUG_BUS3) << 24) |
  1785. (MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_DEBUG_BUS2) << 16) |
  1786. (MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_DEBUG_BUS1) << 8) |
  1787. (MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_DEBUG_BUS0));
  1788. dbus_sel = (dbus_all >> 9) & 0x3FFFF;
  1789. DEV_DBG("%s: loop[%d], dbus_all = 0x%x, dbus_sel = 0x%x\n",
  1790. __func__, step, dbus_all, dbus_sel);
  1791. if (dbus_sel == 0)
  1792. DEV_ERR("%s: CHECK HDMI REF CLK\n", __func__);
  1793. if (dbus_sel == expected_counter_value) {
  1794. max_code = vco_code;
  1795. max_cnt = dbus_sel;
  1796. min_code = vco_code;
  1797. min_cnt = dbus_sel;
  1798. } else if (dbus_sel == 0) {
  1799. max_code = vco_code;
  1800. max_cnt = dbus_sel;
  1801. vco_code = (max_code + min_code)/2;
  1802. } else if (dbus_sel > expected_counter_value) {
  1803. min_code = vco_code;
  1804. min_cnt = dbus_sel;
  1805. vco_code = (max_code + min_code)/2;
  1806. } else if (dbus_sel < expected_counter_value) {
  1807. max_code = vco_code;
  1808. max_cnt = dbus_sel;
  1809. vco_code = (max_code + min_code)/2;
  1810. }
  1811. step++;
  1812. if ((vco_code == 0) || (vco_code == 0x3FF) || (step > 0x3FF)) {
  1813. DEV_ERR("%s: VCO tune code search failed\n", __func__);
  1814. rc = -ENOTSUPP;
  1815. break;
  1816. }
  1817. if ((max_code - min_code) <= 1) {
  1818. if ((max_code - min_code) == 1) {
  1819. if (abs((int)(max_cnt - expected_counter_value))
  1820. < abs((int)(min_cnt - expected_counter_value
  1821. ))) {
  1822. vco_code = max_code;
  1823. } else {
  1824. vco_code = min_code;
  1825. }
  1826. }
  1827. break;
  1828. }
  1829. DEV_DBG("%s: loop[%d], new vco_code = %d\n", __func__, step,
  1830. vco_code);
  1831. }
  1832. DEV_DBG("%s: CALIB done. vco_code = %d\n", __func__, vco_code);
  1833. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_VCO_TUNE1_MODE0,
  1834. vco_code & 0xFF);
  1835. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_VCO_TUNE2_MODE0,
  1836. (vco_code >> 8) & 0x3);
  1837. val = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_LOCK_CMP_CFG);
  1838. val &= ~BIT(1);
  1839. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_LOCK_CMP_CFG, val);
  1840. val = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_CMN_MISC1);
  1841. val |= BIT(4);
  1842. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CMN_MISC1, val);
  1843. val = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_CMN_MISC1);
  1844. val &= ~BIT(3);
  1845. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CMN_MISC1, val);
  1846. return rc;
  1847. }
  1848. static int hdmi_8996_v2_perform_sw_calibration(struct clk *c)
  1849. {
  1850. struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c);
  1851. struct mdss_pll_resources *io = vco->priv;
  1852. u32 vco_code1, vco_code2, integral_loop, ready_poll;
  1853. u32 read_count = 0;
  1854. while (read_count < (HDMI_PLL_POLL_MAX_READS << 1)) {
  1855. ready_poll = MDSS_PLL_REG_R(io->pll_base,
  1856. QSERDES_COM_C_READY_STATUS);
  1857. if ((ready_poll & BIT(0)) == 1) {
  1858. ready_poll = 1;
  1859. DEV_DBG("%s: C READY\n", __func__);
  1860. break;
  1861. }
  1862. udelay(HDMI_PLL_POLL_TIMEOUT_US);
  1863. read_count++;
  1864. }
  1865. if (read_count == (HDMI_PLL_POLL_MAX_READS << 1)) {
  1866. ready_poll = 0;
  1867. DEV_DBG("%s: C READY TIMEOUT, TRYING SW CALIBRATION\n",
  1868. __func__);
  1869. }
  1870. vco_code1 = MDSS_PLL_REG_R(io->pll_base,
  1871. QSERDES_COM_PLLCAL_CODE1_STATUS);
  1872. vco_code2 = MDSS_PLL_REG_R(io->pll_base,
  1873. QSERDES_COM_PLLCAL_CODE2_STATUS);
  1874. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_DEBUG_BUS_SEL, 0x5);
  1875. integral_loop = MDSS_PLL_REG_R(io->pll_base,
  1876. QSERDES_COM_DEBUG_BUS0);
  1877. if (((ready_poll & 0x1) == 0) || (((ready_poll & 1) == 1) &&
  1878. (vco_code1 == 0xFF) && ((vco_code2 & 0x3) == 0x1) &&
  1879. (integral_loop > 0xC0))) {
  1880. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_ATB_SEL1, 0x04);
  1881. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_ATB_SEL2, 0x00);
  1882. MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x17);
  1883. udelay(100);
  1884. MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x11);
  1885. udelay(100);
  1886. MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x19);
  1887. }
  1888. return 0;
  1889. }
  1890. static int hdmi_8996_perform_sw_calibration(struct clk *c, u32 ver)
  1891. {
  1892. switch (ver) {
  1893. case HDMI_VERSION_8996_V1:
  1894. return hdmi_8996_v1_perform_sw_calibration(c);
  1895. case HDMI_VERSION_8996_V2:
  1896. return hdmi_8996_v2_perform_sw_calibration(c);
  1897. }
  1898. return 0;
  1899. }
  1900. static int hdmi_8996_vco_enable(struct clk *c, u32 ver)
  1901. {
  1902. int rc = 0;
  1903. struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c);
  1904. struct mdss_pll_resources *io = vco->priv;
  1905. MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x1);
  1906. udelay(100);
  1907. MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x19);
  1908. udelay(100);
  1909. rc = hdmi_8996_perform_sw_calibration(c, ver);
  1910. if (rc) {
  1911. DEV_ERR("%s: software calibration failed\n", __func__);
  1912. return rc;
  1913. }
  1914. rc = hdmi_8996_pll_lock_status(io);
  1915. if (!rc) {
  1916. DEV_ERR("%s: PLL not locked\n", __func__);
  1917. return rc;
  1918. }
  1919. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
  1920. QSERDES_TX_L0_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN,
  1921. 0x6F);
  1922. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
  1923. QSERDES_TX_L0_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN,
  1924. 0x6F);
  1925. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
  1926. QSERDES_TX_L0_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN,
  1927. 0x6F);
  1928. MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
  1929. QSERDES_TX_L0_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN,
  1930. 0x6F);
  1931. /* Disable SSC */
  1932. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SSC_PER1, 0x0);
  1933. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SSC_PER2, 0x0);
  1934. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SSC_STEP_SIZE1, 0x0);
  1935. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SSC_STEP_SIZE2, 0x0);
  1936. MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SSC_EN_CENTER, 0x2);
  1937. rc = hdmi_8996_phy_ready_status(io);
  1938. if (!rc) {
  1939. DEV_ERR("%s: PHY not READY\n", __func__);
  1940. return rc;
  1941. }
  1942. /* Restart the retiming buffer */
  1943. MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x18);
  1944. udelay(1);
  1945. MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x19);
  1946. io->pll_on = true;
  1947. return 0;
  1948. }
  1949. static int hdmi_8996_v1_vco_enable(struct clk *c)
  1950. {
  1951. return hdmi_8996_vco_enable(c, HDMI_VERSION_8996_V1);
  1952. }
  1953. static int hdmi_8996_v2_vco_enable(struct clk *c)
  1954. {
  1955. return hdmi_8996_vco_enable(c, HDMI_VERSION_8996_V2);
  1956. }
  1957. static int hdmi_8996_v3_vco_enable(struct clk *c)
  1958. {
  1959. return hdmi_8996_vco_enable(c, HDMI_VERSION_8996_V3);
  1960. }
  1961. static int hdmi_8996_v3_1p8_vco_enable(struct clk *c)
  1962. {
  1963. return hdmi_8996_vco_enable(c, HDMI_VERSION_8996_V3_1_8);
  1964. }
  1965. static int hdmi_8996_vco_get_lock_range(struct clk *c, unsigned long pixel_clk)
  1966. {
  1967. u32 rng = 64, cmp_cnt = 1024;
  1968. u32 coreclk_div = 5, clks_pll_divsel = 2;
  1969. u32 vco_freq, vco_ratio, ppm_range;
  1970. u64 bclk;
  1971. struct hdmi_8996_v3_post_divider pd;
  1972. bclk = ((u64)pixel_clk) * HDMI_BIT_CLK_TO_PIX_CLK_RATIO;
  1973. DEV_DBG("%s: rate=%ld\n", __func__, pixel_clk);
  1974. if (hdmi_8996_v3_get_post_div(&pd, bclk) ||
  1975. pd.vco_ratio <= 0 || pd.vco_freq <= 0) {
  1976. DEV_ERR("%s: couldn't get post div\n", __func__);
  1977. return -EINVAL;
  1978. }
  1979. do_div(pd.vco_freq, HDMI_KHZ_TO_HZ * HDMI_KHZ_TO_HZ);
  1980. vco_freq = (u32) pd.vco_freq;
  1981. vco_ratio = (u32) pd.vco_ratio;
  1982. DEV_DBG("%s: freq %d, ratio %d\n", __func__,
  1983. vco_freq, vco_ratio);
  1984. ppm_range = (rng * HDMI_REF_CLOCK) / cmp_cnt;
  1985. ppm_range /= vco_freq / vco_ratio;
  1986. ppm_range *= coreclk_div * clks_pll_divsel;
  1987. DEV_DBG("%s: ppm range: %d\n", __func__, ppm_range);
  1988. return ppm_range;
  1989. }
  1990. static int hdmi_8996_vco_rate_atomic_update(struct clk *c,
  1991. unsigned long rate, u32 ver)
  1992. {
  1993. struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c);
  1994. struct mdss_pll_resources *io = vco->priv;
  1995. void __iomem *pll;
  1996. struct hdmi_8996_phy_pll_reg_cfg cfg = {0};
  1997. int rc = 0;
  1998. rc = hdmi_8996_calculate(rate, &cfg, ver);
  1999. if (rc) {
  2000. DEV_ERR("%s: PLL calculation failed\n", __func__);
  2001. goto end;
  2002. }
  2003. pll = io->pll_base;
  2004. MDSS_PLL_REG_W(pll, QSERDES_COM_DEC_START_MODE0,
  2005. cfg.com_dec_start_mode0);
  2006. MDSS_PLL_REG_W(pll, QSERDES_COM_DIV_FRAC_START1_MODE0,
  2007. cfg.com_div_frac_start1_mode0);
  2008. MDSS_PLL_REG_W(pll, QSERDES_COM_DIV_FRAC_START2_MODE0,
  2009. cfg.com_div_frac_start2_mode0);
  2010. MDSS_PLL_REG_W(pll, QSERDES_COM_DIV_FRAC_START3_MODE0,
  2011. cfg.com_div_frac_start3_mode0);
  2012. MDSS_PLL_REG_W(pll, QSERDES_COM_FREQ_UPDATE, 0x01);
  2013. MDSS_PLL_REG_W(pll, QSERDES_COM_FREQ_UPDATE, 0x00);
  2014. DEV_DBG("%s: updated to rate %ld\n", __func__, rate);
  2015. end:
  2016. return rc;
  2017. }
  2018. static int hdmi_8996_vco_set_rate(struct clk *c, unsigned long rate, u32 ver)
  2019. {
  2020. struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c);
  2021. struct mdss_pll_resources *io = vco->priv;
  2022. unsigned int set_power_dwn = 0;
  2023. bool atomic_update = false;
  2024. int rc, pll_lock_range;
  2025. rc = mdss_pll_resource_enable(io, true);
  2026. if (rc) {
  2027. DEV_ERR("pll resource can't be enabled\n");
  2028. return rc;
  2029. }
  2030. DEV_DBG("%s: rate %ld\n", __func__, rate);
  2031. if (MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_C_READY_STATUS) & BIT(0) &&
  2032. MDSS_PLL_REG_R(io->phy_base, HDMI_PHY_STATUS) & BIT(0)) {
  2033. pll_lock_range = hdmi_8996_vco_get_lock_range(c, vco->rate);
  2034. if (pll_lock_range > 0 && vco->rate) {
  2035. u32 range_limit;
  2036. range_limit = vco->rate *
  2037. (pll_lock_range / HDMI_KHZ_TO_HZ);
  2038. range_limit /= HDMI_KHZ_TO_HZ;
  2039. DEV_DBG("%s: range limit %d\n", __func__, range_limit);
  2040. if (abs(rate - vco->rate) < range_limit)
  2041. atomic_update = true;
  2042. }
  2043. }
  2044. if (io->pll_on && !atomic_update)
  2045. set_power_dwn = 1;
  2046. if (atomic_update) {
  2047. hdmi_8996_vco_rate_atomic_update(c, rate, ver);
  2048. } else {
  2049. rc = hdmi_8996_phy_pll_set_clk_rate(c, rate, ver);
  2050. if (rc)
  2051. DEV_ERR("%s: Failed to set clk rate\n", __func__);
  2052. }
  2053. mdss_pll_resource_enable(io, false);
  2054. if (set_power_dwn)
  2055. hdmi_8996_vco_enable(c, ver);
  2056. vco->rate = rate;
  2057. vco->rate_set = true;
  2058. return 0;
  2059. }
  2060. static int hdmi_8996_v1_vco_set_rate(struct clk *c, unsigned long rate)
  2061. {
  2062. return hdmi_8996_vco_set_rate(c, rate, HDMI_VERSION_8996_V1);
  2063. }
  2064. static int hdmi_8996_v2_vco_set_rate(struct clk *c, unsigned long rate)
  2065. {
  2066. return hdmi_8996_vco_set_rate(c, rate, HDMI_VERSION_8996_V2);
  2067. }
  2068. static int hdmi_8996_v3_vco_set_rate(struct clk *c, unsigned long rate)
  2069. {
  2070. return hdmi_8996_vco_set_rate(c, rate, HDMI_VERSION_8996_V3);
  2071. }
  2072. static int hdmi_8996_v3_1p8_vco_set_rate(struct clk *c, unsigned long rate)
  2073. {
  2074. return hdmi_8996_vco_set_rate(c, rate, HDMI_VERSION_8996_V3_1_8);
  2075. }
  2076. static unsigned long hdmi_get_hsclk_sel_divisor(unsigned long hsclk_sel)
  2077. {
  2078. unsigned long divisor;
  2079. switch (hsclk_sel) {
  2080. case 0:
  2081. divisor = 2;
  2082. break;
  2083. case 1:
  2084. divisor = 6;
  2085. break;
  2086. case 2:
  2087. divisor = 10;
  2088. break;
  2089. case 3:
  2090. divisor = 14;
  2091. break;
  2092. case 4:
  2093. divisor = 3;
  2094. break;
  2095. case 5:
  2096. divisor = 9;
  2097. break;
  2098. case 6:
  2099. case 13:
  2100. divisor = 15;
  2101. break;
  2102. case 7:
  2103. divisor = 21;
  2104. break;
  2105. case 8:
  2106. divisor = 4;
  2107. break;
  2108. case 9:
  2109. divisor = 12;
  2110. break;
  2111. case 10:
  2112. divisor = 20;
  2113. break;
  2114. case 11:
  2115. divisor = 28;
  2116. break;
  2117. case 12:
  2118. divisor = 5;
  2119. break;
  2120. case 14:
  2121. divisor = 25;
  2122. break;
  2123. case 15:
  2124. divisor = 35;
  2125. break;
  2126. default:
  2127. divisor = 1;
  2128. DEV_ERR("%s: invalid hsclk_sel value = %lu",
  2129. __func__, hsclk_sel);
  2130. break;
  2131. }
  2132. return divisor;
  2133. }
  2134. static unsigned long hdmi_8996_vco_get_rate(struct clk *c)
  2135. {
  2136. unsigned long freq = 0, hsclk_sel = 0, tx_band = 0, dec_start = 0,
  2137. div_frac_start = 0, vco_clock_freq = 0;
  2138. struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c);
  2139. struct mdss_pll_resources *io = vco->priv;
  2140. if (mdss_pll_resource_enable(io, true)) {
  2141. DEV_ERR("%s: pll resource can't be enabled\n", __func__);
  2142. return freq;
  2143. }
  2144. dec_start = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_DEC_START_MODE0);
  2145. div_frac_start =
  2146. MDSS_PLL_REG_R(io->pll_base,
  2147. QSERDES_COM_DIV_FRAC_START1_MODE0) |
  2148. MDSS_PLL_REG_R(io->pll_base,
  2149. QSERDES_COM_DIV_FRAC_START2_MODE0) << 8 |
  2150. MDSS_PLL_REG_R(io->pll_base,
  2151. QSERDES_COM_DIV_FRAC_START3_MODE0) << 16;
  2152. vco_clock_freq = (dec_start + (div_frac_start / (1 << 20)))
  2153. * 4 * (HDMI_REF_CLOCK);
  2154. hsclk_sel = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_HSCLK_SEL) & 0x15;
  2155. hsclk_sel = hdmi_get_hsclk_sel_divisor(hsclk_sel);
  2156. tx_band = MDSS_PLL_REG_R(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
  2157. QSERDES_TX_L0_TX_BAND) & 0x3;
  2158. freq = vco_clock_freq / (10 * hsclk_sel * (1 << tx_band));
  2159. mdss_pll_resource_enable(io, false);
  2160. DEV_DBG("%s: freq = %lu\n", __func__, freq);
  2161. return freq;
  2162. }
  2163. static long hdmi_8996_vco_round_rate(struct clk *c, unsigned long rate)
  2164. {
  2165. unsigned long rrate = rate;
  2166. DEV_DBG("rrate=%ld\n", rrate);
  2167. return rrate;
  2168. }
  2169. static int hdmi_8996_vco_prepare(struct clk *c, u32 ver)
  2170. {
  2171. struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c);
  2172. struct mdss_pll_resources *io = vco->priv;
  2173. int ret = 0;
  2174. DEV_DBG("rate=%ld\n", vco->rate);
  2175. if (!vco->rate_set && vco->rate)
  2176. ret = hdmi_8996_vco_set_rate(c, vco->rate, ver);
  2177. if (!ret) {
  2178. ret = mdss_pll_resource_enable(io, true);
  2179. if (ret)
  2180. DEV_ERR("pll resource can't be enabled\n");
  2181. }
  2182. return ret;
  2183. }
  2184. static int hdmi_8996_v1_vco_prepare(struct clk *c)
  2185. {
  2186. return hdmi_8996_vco_prepare(c, HDMI_VERSION_8996_V1);
  2187. }
  2188. static int hdmi_8996_v2_vco_prepare(struct clk *c)
  2189. {
  2190. return hdmi_8996_vco_prepare(c, HDMI_VERSION_8996_V2);
  2191. }
  2192. static int hdmi_8996_v3_vco_prepare(struct clk *c)
  2193. {
  2194. return hdmi_8996_vco_prepare(c, HDMI_VERSION_8996_V3);
  2195. }
  2196. static int hdmi_8996_v3_1p8_vco_prepare(struct clk *c)
  2197. {
  2198. return hdmi_8996_vco_prepare(c, HDMI_VERSION_8996_V3_1_8);
  2199. }
  2200. static void hdmi_8996_vco_unprepare(struct clk *c)
  2201. {
  2202. struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c);
  2203. struct mdss_pll_resources *io = vco->priv;
  2204. vco->rate_set = false;
  2205. if (!io) {
  2206. DEV_ERR("Invalid input parameter\n");
  2207. return;
  2208. }
  2209. if (!io->pll_on &&
  2210. mdss_pll_resource_enable(io, true)) {
  2211. DEV_ERR("pll resource can't be enabled\n");
  2212. return;
  2213. }
  2214. io->handoff_resources = false;
  2215. mdss_pll_resource_enable(io, false);
  2216. io->pll_on = false;
  2217. }
  2218. static enum handoff hdmi_8996_vco_handoff(struct clk *c)
  2219. {
  2220. enum handoff ret = HANDOFF_DISABLED_CLK;
  2221. struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c);
  2222. struct mdss_pll_resources *io = vco->priv;
  2223. if (is_gdsc_disabled(io))
  2224. return HANDOFF_DISABLED_CLK;
  2225. if (mdss_pll_resource_enable(io, true)) {
  2226. DEV_ERR("pll resource can't be enabled\n");
  2227. return ret;
  2228. }
  2229. io->handoff_resources = true;
  2230. if (MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_C_READY_STATUS) & BIT(0)) {
  2231. if (MDSS_PLL_REG_R(io->phy_base, HDMI_PHY_STATUS) & BIT(0)) {
  2232. io->pll_on = true;
  2233. c->rate = hdmi_8996_vco_get_rate(c);
  2234. vco->rate = c->rate;
  2235. ret = HANDOFF_ENABLED_CLK;
  2236. } else {
  2237. io->handoff_resources = false;
  2238. mdss_pll_resource_enable(io, false);
  2239. DEV_DBG("%s: PHY not ready\n", __func__);
  2240. }
  2241. } else {
  2242. io->handoff_resources = false;
  2243. mdss_pll_resource_enable(io, false);
  2244. DEV_DBG("%s: PLL not locked\n", __func__);
  2245. }
  2246. DEV_DBG("done, ret=%d\n", ret);
  2247. return ret;
  2248. }
  2249. static const struct clk_ops hdmi_8996_v1_vco_clk_ops = {
  2250. .enable = hdmi_8996_v1_vco_enable,
  2251. .set_rate = hdmi_8996_v1_vco_set_rate,
  2252. .get_rate = hdmi_8996_vco_get_rate,
  2253. .round_rate = hdmi_8996_vco_round_rate,
  2254. .prepare = hdmi_8996_v1_vco_prepare,
  2255. .unprepare = hdmi_8996_vco_unprepare,
  2256. .handoff = hdmi_8996_vco_handoff,
  2257. };
  2258. static const struct clk_ops hdmi_8996_v2_vco_clk_ops = {
  2259. .enable = hdmi_8996_v2_vco_enable,
  2260. .set_rate = hdmi_8996_v2_vco_set_rate,
  2261. .get_rate = hdmi_8996_vco_get_rate,
  2262. .round_rate = hdmi_8996_vco_round_rate,
  2263. .prepare = hdmi_8996_v2_vco_prepare,
  2264. .unprepare = hdmi_8996_vco_unprepare,
  2265. .handoff = hdmi_8996_vco_handoff,
  2266. };
  2267. static const struct clk_ops hdmi_8996_v3_vco_clk_ops = {
  2268. .enable = hdmi_8996_v3_vco_enable,
  2269. .set_rate = hdmi_8996_v3_vco_set_rate,
  2270. .get_rate = hdmi_8996_vco_get_rate,
  2271. .round_rate = hdmi_8996_vco_round_rate,
  2272. .prepare = hdmi_8996_v3_vco_prepare,
  2273. .unprepare = hdmi_8996_vco_unprepare,
  2274. .handoff = hdmi_8996_vco_handoff,
  2275. };
  2276. static const struct clk_ops hdmi_8996_v3_1p8_vco_clk_ops = {
  2277. .enable = hdmi_8996_v3_1p8_vco_enable,
  2278. .set_rate = hdmi_8996_v3_1p8_vco_set_rate,
  2279. .get_rate = hdmi_8996_vco_get_rate,
  2280. .round_rate = hdmi_8996_vco_round_rate,
  2281. .prepare = hdmi_8996_v3_1p8_vco_prepare,
  2282. .unprepare = hdmi_8996_vco_unprepare,
  2283. .handoff = hdmi_8996_vco_handoff,
  2284. };
  2285. static struct hdmi_pll_vco_clk hdmi_vco_clk = {
  2286. .c = {
  2287. .dbg_name = "hdmi_8996_vco_clk",
  2288. .ops = &hdmi_8996_v1_vco_clk_ops,
  2289. CLK_INIT(hdmi_vco_clk.c),
  2290. },
  2291. };
  2292. static struct clk_lookup hdmipllcc_8996[] = {
  2293. CLK_LIST(hdmi_vco_clk),
  2294. };
  2295. int hdmi_8996_pll_clock_register(struct platform_device *pdev,
  2296. struct mdss_pll_resources *pll_res, u32 ver)
  2297. {
  2298. int rc = -ENOTSUPP;
  2299. if (!pll_res || !pll_res->phy_base || !pll_res->pll_base) {
  2300. DEV_ERR("%s: Invalid input parameters\n", __func__);
  2301. return -EPROBE_DEFER;
  2302. }
  2303. /* Set client data for vco, mux and div clocks */
  2304. hdmi_vco_clk.priv = pll_res;
  2305. switch (ver) {
  2306. case HDMI_VERSION_8996_V2:
  2307. hdmi_vco_clk.c.ops = &hdmi_8996_v2_vco_clk_ops;
  2308. break;
  2309. case HDMI_VERSION_8996_V3:
  2310. hdmi_vco_clk.c.ops = &hdmi_8996_v3_vco_clk_ops;
  2311. break;
  2312. case HDMI_VERSION_8996_V3_1_8:
  2313. hdmi_vco_clk.c.ops = &hdmi_8996_v3_1p8_vco_clk_ops;
  2314. break;
  2315. default:
  2316. hdmi_vco_clk.c.ops = &hdmi_8996_v1_vco_clk_ops;
  2317. break;
  2318. }
  2319. rc = of_msm_clock_register(pdev->dev.of_node, hdmipllcc_8996,
  2320. ARRAY_SIZE(hdmipllcc_8996));
  2321. if (rc) {
  2322. DEV_ERR("%s: Clock register failed rc=%d\n", __func__, rc);
  2323. rc = -EPROBE_DEFER;
  2324. } else {
  2325. DEV_DBG("%s SUCCESS\n", __func__);
  2326. }
  2327. return rc;
  2328. }
  2329. int hdmi_8996_v1_pll_clock_register(struct platform_device *pdev,
  2330. struct mdss_pll_resources *pll_res)
  2331. {
  2332. return hdmi_8996_pll_clock_register(pdev, pll_res,
  2333. HDMI_VERSION_8996_V1);
  2334. }
  2335. int hdmi_8996_v2_pll_clock_register(struct platform_device *pdev,
  2336. struct mdss_pll_resources *pll_res)
  2337. {
  2338. return hdmi_8996_pll_clock_register(pdev, pll_res,
  2339. HDMI_VERSION_8996_V2);
  2340. }
  2341. int hdmi_8996_v3_pll_clock_register(struct platform_device *pdev,
  2342. struct mdss_pll_resources *pll_res)
  2343. {
  2344. return hdmi_8996_pll_clock_register(pdev, pll_res,
  2345. HDMI_VERSION_8996_V3);
  2346. }
  2347. int hdmi_8996_v3_1p8_pll_clock_register(struct platform_device *pdev,
  2348. struct mdss_pll_resources *pll_res)
  2349. {
  2350. return hdmi_8996_pll_clock_register(pdev, pll_res,
  2351. HDMI_VERSION_8996_V3_1_8);
  2352. }