12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675 |
- // SPDX-License-Identifier: GPL-2.0-only
- /*
- * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
- */
- #include <linux/kernel.h>
- #include <linux/err.h>
- #include <linux/delay.h>
- #include <linux/iopoll.h>
- #include <linux/clk/msm-clk-provider.h>
- #include <linux/clk/msm-clk.h>
- #include <linux/clk/msm-clock-generic.h>
- #include <dt-bindings/clock/msm-clocks-8996.h>
- #include "pll_drv.h"
- #include "hdmi_pll.h"
- /* CONSTANTS */
- #define HDMI_BIT_CLK_TO_PIX_CLK_RATIO 10
- #define HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD 3400000000UL
- #define HDMI_DIG_FREQ_BIT_CLK_THRESHOLD 1500000000UL
- #define HDMI_MID_FREQ_BIT_CLK_THRESHOLD 750000000
- #define HDMI_CLKS_PLL_DIVSEL 0
- #define HDMI_CORECLK_DIV 5
- #define HDMI_REF_CLOCK 19200000
- #define HDMI_64B_ERR_VAL 0xFFFFFFFFFFFFFFFF
- #define HDMI_VERSION_8996_V1 1
- #define HDMI_VERSION_8996_V2 2
- #define HDMI_VERSION_8996_V3 3
- #define HDMI_VERSION_8996_V3_1_8 4
- #define HDMI_VCO_MAX_FREQ 12000000000
- #define HDMI_VCO_MIN_FREQ 8000000000
- #define HDMI_2400MHZ_BIT_CLK_HZ 2400000000UL
- #define HDMI_2250MHZ_BIT_CLK_HZ 2250000000UL
- #define HDMI_2000MHZ_BIT_CLK_HZ 2000000000UL
- #define HDMI_1700MHZ_BIT_CLK_HZ 1700000000UL
- #define HDMI_1200MHZ_BIT_CLK_HZ 1200000000UL
- #define HDMI_1334MHZ_BIT_CLK_HZ 1334000000UL
- #define HDMI_1000MHZ_BIT_CLK_HZ 1000000000UL
- #define HDMI_850MHZ_BIT_CLK_HZ 850000000
- #define HDMI_667MHZ_BIT_CLK_HZ 667000000
- #define HDMI_600MHZ_BIT_CLK_HZ 600000000
- #define HDMI_500MHZ_BIT_CLK_HZ 500000000
- #define HDMI_450MHZ_BIT_CLK_HZ 450000000
- #define HDMI_334MHZ_BIT_CLK_HZ 334000000
- #define HDMI_300MHZ_BIT_CLK_HZ 300000000
- #define HDMI_282MHZ_BIT_CLK_HZ 282000000
- #define HDMI_250MHZ_BIT_CLK_HZ 250000000
- #define HDMI_KHZ_TO_HZ 1000
- /* PLL REGISTERS */
- #define QSERDES_COM_ATB_SEL1 (0x000)
- #define QSERDES_COM_ATB_SEL2 (0x004)
- #define QSERDES_COM_FREQ_UPDATE (0x008)
- #define QSERDES_COM_BG_TIMER (0x00C)
- #define QSERDES_COM_SSC_EN_CENTER (0x010)
- #define QSERDES_COM_SSC_ADJ_PER1 (0x014)
- #define QSERDES_COM_SSC_ADJ_PER2 (0x018)
- #define QSERDES_COM_SSC_PER1 (0x01C)
- #define QSERDES_COM_SSC_PER2 (0x020)
- #define QSERDES_COM_SSC_STEP_SIZE1 (0x024)
- #define QSERDES_COM_SSC_STEP_SIZE2 (0x028)
- #define QSERDES_COM_POST_DIV (0x02C)
- #define QSERDES_COM_POST_DIV_MUX (0x030)
- #define QSERDES_COM_BIAS_EN_CLKBUFLR_EN (0x034)
- #define QSERDES_COM_CLK_ENABLE1 (0x038)
- #define QSERDES_COM_SYS_CLK_CTRL (0x03C)
- #define QSERDES_COM_SYSCLK_BUF_ENABLE (0x040)
- #define QSERDES_COM_PLL_EN (0x044)
- #define QSERDES_COM_PLL_IVCO (0x048)
- #define QSERDES_COM_LOCK_CMP1_MODE0 (0x04C)
- #define QSERDES_COM_LOCK_CMP2_MODE0 (0x050)
- #define QSERDES_COM_LOCK_CMP3_MODE0 (0x054)
- #define QSERDES_COM_LOCK_CMP1_MODE1 (0x058)
- #define QSERDES_COM_LOCK_CMP2_MODE1 (0x05C)
- #define QSERDES_COM_LOCK_CMP3_MODE1 (0x060)
- #define QSERDES_COM_LOCK_CMP1_MODE2 (0x064)
- #define QSERDES_COM_CMN_RSVD0 (0x064)
- #define QSERDES_COM_LOCK_CMP2_MODE2 (0x068)
- #define QSERDES_COM_EP_CLOCK_DETECT_CTRL (0x068)
- #define QSERDES_COM_LOCK_CMP3_MODE2 (0x06C)
- #define QSERDES_COM_SYSCLK_DET_COMP_STATUS (0x06C)
- #define QSERDES_COM_BG_TRIM (0x070)
- #define QSERDES_COM_CLK_EP_DIV (0x074)
- #define QSERDES_COM_CP_CTRL_MODE0 (0x078)
- #define QSERDES_COM_CP_CTRL_MODE1 (0x07C)
- #define QSERDES_COM_CP_CTRL_MODE2 (0x080)
- #define QSERDES_COM_CMN_RSVD1 (0x080)
- #define QSERDES_COM_PLL_RCTRL_MODE0 (0x084)
- #define QSERDES_COM_PLL_RCTRL_MODE1 (0x088)
- #define QSERDES_COM_PLL_RCTRL_MODE2 (0x08C)
- #define QSERDES_COM_CMN_RSVD2 (0x08C)
- #define QSERDES_COM_PLL_CCTRL_MODE0 (0x090)
- #define QSERDES_COM_PLL_CCTRL_MODE1 (0x094)
- #define QSERDES_COM_PLL_CCTRL_MODE2 (0x098)
- #define QSERDES_COM_CMN_RSVD3 (0x098)
- #define QSERDES_COM_PLL_CNTRL (0x09C)
- #define QSERDES_COM_PHASE_SEL_CTRL (0x0A0)
- #define QSERDES_COM_PHASE_SEL_DC (0x0A4)
- #define QSERDES_COM_CORE_CLK_IN_SYNC_SEL (0x0A8)
- #define QSERDES_COM_BIAS_EN_CTRL_BY_PSM (0x0A8)
- #define QSERDES_COM_SYSCLK_EN_SEL (0x0AC)
- #define QSERDES_COM_CML_SYSCLK_SEL (0x0B0)
- #define QSERDES_COM_RESETSM_CNTRL (0x0B4)
- #define QSERDES_COM_RESETSM_CNTRL2 (0x0B8)
- #define QSERDES_COM_RESTRIM_CTRL (0x0BC)
- #define QSERDES_COM_RESTRIM_CTRL2 (0x0C0)
- #define QSERDES_COM_RESCODE_DIV_NUM (0x0C4)
- #define QSERDES_COM_LOCK_CMP_EN (0x0C8)
- #define QSERDES_COM_LOCK_CMP_CFG (0x0CC)
- #define QSERDES_COM_DEC_START_MODE0 (0x0D0)
- #define QSERDES_COM_DEC_START_MODE1 (0x0D4)
- #define QSERDES_COM_DEC_START_MODE2 (0x0D8)
- #define QSERDES_COM_VCOCAL_DEADMAN_CTRL (0x0D8)
- #define QSERDES_COM_DIV_FRAC_START1_MODE0 (0x0DC)
- #define QSERDES_COM_DIV_FRAC_START2_MODE0 (0x0E0)
- #define QSERDES_COM_DIV_FRAC_START3_MODE0 (0x0E4)
- #define QSERDES_COM_DIV_FRAC_START1_MODE1 (0x0E8)
- #define QSERDES_COM_DIV_FRAC_START2_MODE1 (0x0EC)
- #define QSERDES_COM_DIV_FRAC_START3_MODE1 (0x0F0)
- #define QSERDES_COM_DIV_FRAC_START1_MODE2 (0x0F4)
- #define QSERDES_COM_VCO_TUNE_MINVAL1 (0x0F4)
- #define QSERDES_COM_DIV_FRAC_START2_MODE2 (0x0F8)
- #define QSERDES_COM_VCO_TUNE_MINVAL2 (0x0F8)
- #define QSERDES_COM_DIV_FRAC_START3_MODE2 (0x0FC)
- #define QSERDES_COM_CMN_RSVD4 (0x0FC)
- #define QSERDES_COM_INTEGLOOP_INITVAL (0x100)
- #define QSERDES_COM_INTEGLOOP_EN (0x104)
- #define QSERDES_COM_INTEGLOOP_GAIN0_MODE0 (0x108)
- #define QSERDES_COM_INTEGLOOP_GAIN1_MODE0 (0x10C)
- #define QSERDES_COM_INTEGLOOP_GAIN0_MODE1 (0x110)
- #define QSERDES_COM_INTEGLOOP_GAIN1_MODE1 (0x114)
- #define QSERDES_COM_INTEGLOOP_GAIN0_MODE2 (0x118)
- #define QSERDES_COM_VCO_TUNE_MAXVAL1 (0x118)
- #define QSERDES_COM_INTEGLOOP_GAIN1_MODE2 (0x11C)
- #define QSERDES_COM_VCO_TUNE_MAXVAL2 (0x11C)
- #define QSERDES_COM_RES_TRIM_CONTROL2 (0x120)
- #define QSERDES_COM_VCO_TUNE_CTRL (0x124)
- #define QSERDES_COM_VCO_TUNE_MAP (0x128)
- #define QSERDES_COM_VCO_TUNE1_MODE0 (0x12C)
- #define QSERDES_COM_VCO_TUNE2_MODE0 (0x130)
- #define QSERDES_COM_VCO_TUNE1_MODE1 (0x134)
- #define QSERDES_COM_VCO_TUNE2_MODE1 (0x138)
- #define QSERDES_COM_VCO_TUNE1_MODE2 (0x13C)
- #define QSERDES_COM_VCO_TUNE_INITVAL1 (0x13C)
- #define QSERDES_COM_VCO_TUNE2_MODE2 (0x140)
- #define QSERDES_COM_VCO_TUNE_INITVAL2 (0x140)
- #define QSERDES_COM_VCO_TUNE_TIMER1 (0x144)
- #define QSERDES_COM_VCO_TUNE_TIMER2 (0x148)
- #define QSERDES_COM_SAR (0x14C)
- #define QSERDES_COM_SAR_CLK (0x150)
- #define QSERDES_COM_SAR_CODE_OUT_STATUS (0x154)
- #define QSERDES_COM_SAR_CODE_READY_STATUS (0x158)
- #define QSERDES_COM_CMN_STATUS (0x15C)
- #define QSERDES_COM_RESET_SM_STATUS (0x160)
- #define QSERDES_COM_RESTRIM_CODE_STATUS (0x164)
- #define QSERDES_COM_PLLCAL_CODE1_STATUS (0x168)
- #define QSERDES_COM_PLLCAL_CODE2_STATUS (0x16C)
- #define QSERDES_COM_BG_CTRL (0x170)
- #define QSERDES_COM_CLK_SELECT (0x174)
- #define QSERDES_COM_HSCLK_SEL (0x178)
- #define QSERDES_COM_INTEGLOOP_BINCODE_STATUS (0x17C)
- #define QSERDES_COM_PLL_ANALOG (0x180)
- #define QSERDES_COM_CORECLK_DIV (0x184)
- #define QSERDES_COM_SW_RESET (0x188)
- #define QSERDES_COM_CORE_CLK_EN (0x18C)
- #define QSERDES_COM_C_READY_STATUS (0x190)
- #define QSERDES_COM_CMN_CONFIG (0x194)
- #define QSERDES_COM_CMN_RATE_OVERRIDE (0x198)
- #define QSERDES_COM_SVS_MODE_CLK_SEL (0x19C)
- #define QSERDES_COM_DEBUG_BUS0 (0x1A0)
- #define QSERDES_COM_DEBUG_BUS1 (0x1A4)
- #define QSERDES_COM_DEBUG_BUS2 (0x1A8)
- #define QSERDES_COM_DEBUG_BUS3 (0x1AC)
- #define QSERDES_COM_DEBUG_BUS_SEL (0x1B0)
- #define QSERDES_COM_CMN_MISC1 (0x1B4)
- #define QSERDES_COM_CMN_MISC2 (0x1B8)
- #define QSERDES_COM_CORECLK_DIV_MODE1 (0x1BC)
- #define QSERDES_COM_CORECLK_DIV_MODE2 (0x1C0)
- #define QSERDES_COM_CMN_RSVD5 (0x1C0)
- /* Tx Channel base addresses */
- #define HDMI_TX_L0_BASE_OFFSET (0x400)
- #define HDMI_TX_L1_BASE_OFFSET (0x600)
- #define HDMI_TX_L2_BASE_OFFSET (0x800)
- #define HDMI_TX_L3_BASE_OFFSET (0xA00)
- /* Tx Channel PHY registers */
- #define QSERDES_TX_L0_BIST_MODE_LANENO (0x000)
- #define QSERDES_TX_L0_BIST_INVERT (0x004)
- #define QSERDES_TX_L0_CLKBUF_ENABLE (0x008)
- #define QSERDES_TX_L0_CMN_CONTROL_ONE (0x00C)
- #define QSERDES_TX_L0_CMN_CONTROL_TWO (0x010)
- #define QSERDES_TX_L0_CMN_CONTROL_THREE (0x014)
- #define QSERDES_TX_L0_TX_EMP_POST1_LVL (0x018)
- #define QSERDES_TX_L0_TX_POST2_EMPH (0x01C)
- #define QSERDES_TX_L0_TX_BOOST_LVL_UP_DN (0x020)
- #define QSERDES_TX_L0_HP_PD_ENABLES (0x024)
- #define QSERDES_TX_L0_TX_IDLE_LVL_LARGE_AMP (0x028)
- #define QSERDES_TX_L0_TX_DRV_LVL (0x02C)
- #define QSERDES_TX_L0_TX_DRV_LVL_OFFSET (0x030)
- #define QSERDES_TX_L0_RESET_TSYNC_EN (0x034)
- #define QSERDES_TX_L0_PRE_STALL_LDO_BOOST_EN (0x038)
- #define QSERDES_TX_L0_TX_BAND (0x03C)
- #define QSERDES_TX_L0_SLEW_CNTL (0x040)
- #define QSERDES_TX_L0_INTERFACE_SELECT (0x044)
- #define QSERDES_TX_L0_LPB_EN (0x048)
- #define QSERDES_TX_L0_RES_CODE_LANE_TX (0x04C)
- #define QSERDES_TX_L0_RES_CODE_LANE_RX (0x050)
- #define QSERDES_TX_L0_RES_CODE_LANE_OFFSET (0x054)
- #define QSERDES_TX_L0_PERL_LENGTH1 (0x058)
- #define QSERDES_TX_L0_PERL_LENGTH2 (0x05C)
- #define QSERDES_TX_L0_SERDES_BYP_EN_OUT (0x060)
- #define QSERDES_TX_L0_DEBUG_BUS_SEL (0x064)
- #define QSERDES_TX_L0_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN (0x068)
- #define QSERDES_TX_L0_TX_POL_INV (0x06C)
- #define QSERDES_TX_L0_PARRATE_REC_DETECT_IDLE_EN (0x070)
- #define QSERDES_TX_L0_BIST_PATTERN1 (0x074)
- #define QSERDES_TX_L0_BIST_PATTERN2 (0x078)
- #define QSERDES_TX_L0_BIST_PATTERN3 (0x07C)
- #define QSERDES_TX_L0_BIST_PATTERN4 (0x080)
- #define QSERDES_TX_L0_BIST_PATTERN5 (0x084)
- #define QSERDES_TX_L0_BIST_PATTERN6 (0x088)
- #define QSERDES_TX_L0_BIST_PATTERN7 (0x08C)
- #define QSERDES_TX_L0_BIST_PATTERN8 (0x090)
- #define QSERDES_TX_L0_LANE_MODE (0x094)
- #define QSERDES_TX_L0_IDAC_CAL_LANE_MODE (0x098)
- #define QSERDES_TX_L0_IDAC_CAL_LANE_MODE_CONFIGURATION (0x09C)
- #define QSERDES_TX_L0_ATB_SEL1 (0x0A0)
- #define QSERDES_TX_L0_ATB_SEL2 (0x0A4)
- #define QSERDES_TX_L0_RCV_DETECT_LVL (0x0A8)
- #define QSERDES_TX_L0_RCV_DETECT_LVL_2 (0x0AC)
- #define QSERDES_TX_L0_PRBS_SEED1 (0x0B0)
- #define QSERDES_TX_L0_PRBS_SEED2 (0x0B4)
- #define QSERDES_TX_L0_PRBS_SEED3 (0x0B8)
- #define QSERDES_TX_L0_PRBS_SEED4 (0x0BC)
- #define QSERDES_TX_L0_RESET_GEN (0x0C0)
- #define QSERDES_TX_L0_RESET_GEN_MUXES (0x0C4)
- #define QSERDES_TX_L0_TRAN_DRVR_EMP_EN (0x0C8)
- #define QSERDES_TX_L0_TX_INTERFACE_MODE (0x0CC)
- #define QSERDES_TX_L0_PWM_CTRL (0x0D0)
- #define QSERDES_TX_L0_PWM_ENCODED_OR_DATA (0x0D4)
- #define QSERDES_TX_L0_PWM_GEAR_1_DIVIDER_BAND2 (0x0D8)
- #define QSERDES_TX_L0_PWM_GEAR_2_DIVIDER_BAND2 (0x0DC)
- #define QSERDES_TX_L0_PWM_GEAR_3_DIVIDER_BAND2 (0x0E0)
- #define QSERDES_TX_L0_PWM_GEAR_4_DIVIDER_BAND2 (0x0E4)
- #define QSERDES_TX_L0_PWM_GEAR_1_DIVIDER_BAND0_1 (0x0E8)
- #define QSERDES_TX_L0_PWM_GEAR_2_DIVIDER_BAND0_1 (0x0EC)
- #define QSERDES_TX_L0_PWM_GEAR_3_DIVIDER_BAND0_1 (0x0F0)
- #define QSERDES_TX_L0_PWM_GEAR_4_DIVIDER_BAND0_1 (0x0F4)
- #define QSERDES_TX_L0_VMODE_CTRL1 (0x0F8)
- #define QSERDES_TX_L0_VMODE_CTRL2 (0x0FC)
- #define QSERDES_TX_L0_TX_ALOG_INTF_OBSV_CNTL (0x100)
- #define QSERDES_TX_L0_BIST_STATUS (0x104)
- #define QSERDES_TX_L0_BIST_ERROR_COUNT1 (0x108)
- #define QSERDES_TX_L0_BIST_ERROR_COUNT2 (0x10C)
- #define QSERDES_TX_L0_TX_ALOG_INTF_OBSV (0x110)
- /* HDMI PHY REGISTERS */
- #define HDMI_PHY_BASE_OFFSET (0xC00)
- #define HDMI_PHY_CFG (0x00)
- #define HDMI_PHY_PD_CTL (0x04)
- #define HDMI_PHY_MODE (0x08)
- #define HDMI_PHY_MISR_CLEAR (0x0C)
- #define HDMI_PHY_TX0_TX1_BIST_CFG0 (0x10)
- #define HDMI_PHY_TX0_TX1_BIST_CFG1 (0x14)
- #define HDMI_PHY_TX0_TX1_PRBS_SEED_BYTE0 (0x18)
- #define HDMI_PHY_TX0_TX1_PRBS_SEED_BYTE1 (0x1C)
- #define HDMI_PHY_TX0_TX1_BIST_PATTERN0 (0x20)
- #define HDMI_PHY_TX0_TX1_BIST_PATTERN1 (0x24)
- #define HDMI_PHY_TX2_TX3_BIST_CFG0 (0x28)
- #define HDMI_PHY_TX2_TX3_BIST_CFG1 (0x2C)
- #define HDMI_PHY_TX2_TX3_PRBS_SEED_BYTE0 (0x30)
- #define HDMI_PHY_TX2_TX3_PRBS_SEED_BYTE1 (0x34)
- #define HDMI_PHY_TX2_TX3_BIST_PATTERN0 (0x38)
- #define HDMI_PHY_TX2_TX3_BIST_PATTERN1 (0x3C)
- #define HDMI_PHY_DEBUG_BUS_SEL (0x40)
- #define HDMI_PHY_TXCAL_CFG0 (0x44)
- #define HDMI_PHY_TXCAL_CFG1 (0x48)
- #define HDMI_PHY_TX0_TX1_LANE_CTL (0x4C)
- #define HDMI_PHY_TX2_TX3_LANE_CTL (0x50)
- #define HDMI_PHY_LANE_BIST_CONFIG (0x54)
- #define HDMI_PHY_CLOCK (0x58)
- #define HDMI_PHY_MISC1 (0x5C)
- #define HDMI_PHY_MISC2 (0x60)
- #define HDMI_PHY_TX0_TX1_BIST_STATUS0 (0x64)
- #define HDMI_PHY_TX0_TX1_BIST_STATUS1 (0x68)
- #define HDMI_PHY_TX0_TX1_BIST_STATUS2 (0x6C)
- #define HDMI_PHY_TX2_TX3_BIST_STATUS0 (0x70)
- #define HDMI_PHY_TX2_TX3_BIST_STATUS1 (0x74)
- #define HDMI_PHY_TX2_TX3_BIST_STATUS2 (0x78)
- #define HDMI_PHY_PRE_MISR_STATUS0 (0x7C)
- #define HDMI_PHY_PRE_MISR_STATUS1 (0x80)
- #define HDMI_PHY_PRE_MISR_STATUS2 (0x84)
- #define HDMI_PHY_PRE_MISR_STATUS3 (0x88)
- #define HDMI_PHY_POST_MISR_STATUS0 (0x8C)
- #define HDMI_PHY_POST_MISR_STATUS1 (0x90)
- #define HDMI_PHY_POST_MISR_STATUS2 (0x94)
- #define HDMI_PHY_POST_MISR_STATUS3 (0x98)
- #define HDMI_PHY_STATUS (0x9C)
- #define HDMI_PHY_MISC3_STATUS (0xA0)
- #define HDMI_PHY_MISC4_STATUS (0xA4)
- #define HDMI_PHY_DEBUG_BUS0 (0xA8)
- #define HDMI_PHY_DEBUG_BUS1 (0xAC)
- #define HDMI_PHY_DEBUG_BUS2 (0xB0)
- #define HDMI_PHY_DEBUG_BUS3 (0xB4)
- #define HDMI_PHY_PHY_REVISION_ID0 (0xB8)
- #define HDMI_PHY_PHY_REVISION_ID1 (0xBC)
- #define HDMI_PHY_PHY_REVISION_ID2 (0xC0)
- #define HDMI_PHY_PHY_REVISION_ID3 (0xC4)
- #define HDMI_PLL_POLL_MAX_READS 100
- #define HDMI_PLL_POLL_TIMEOUT_US 1500
- enum hdmi_pll_freqs {
- HDMI_PCLK_25200_KHZ,
- HDMI_PCLK_27027_KHZ,
- HDMI_PCLK_27000_KHZ,
- HDMI_PCLK_74250_KHZ,
- HDMI_PCLK_148500_KHZ,
- HDMI_PCLK_154000_KHZ,
- HDMI_PCLK_268500_KHZ,
- HDMI_PCLK_297000_KHZ,
- HDMI_PCLK_594000_KHZ,
- HDMI_PCLK_MAX
- };
- struct hdmi_8996_phy_pll_reg_cfg {
- u32 tx_l0_lane_mode;
- u32 tx_l2_lane_mode;
- u32 tx_l0_tx_band;
- u32 tx_l1_tx_band;
- u32 tx_l2_tx_band;
- u32 tx_l3_tx_band;
- u32 com_svs_mode_clk_sel;
- u32 com_hsclk_sel;
- u32 com_pll_cctrl_mode0;
- u32 com_pll_rctrl_mode0;
- u32 com_cp_ctrl_mode0;
- u32 com_dec_start_mode0;
- u32 com_div_frac_start1_mode0;
- u32 com_div_frac_start2_mode0;
- u32 com_div_frac_start3_mode0;
- u32 com_integloop_gain0_mode0;
- u32 com_integloop_gain1_mode0;
- u32 com_lock_cmp_en;
- u32 com_lock_cmp1_mode0;
- u32 com_lock_cmp2_mode0;
- u32 com_lock_cmp3_mode0;
- u32 com_core_clk_en;
- u32 com_coreclk_div;
- u32 com_restrim_ctrl;
- u32 com_vco_tune_ctrl;
- u32 tx_l0_tx_drv_lvl;
- u32 tx_l0_tx_emp_post1_lvl;
- u32 tx_l1_tx_drv_lvl;
- u32 tx_l1_tx_emp_post1_lvl;
- u32 tx_l2_tx_drv_lvl;
- u32 tx_l2_tx_emp_post1_lvl;
- u32 tx_l3_tx_drv_lvl;
- u32 tx_l3_tx_emp_post1_lvl;
- u32 tx_l0_vmode_ctrl1;
- u32 tx_l0_vmode_ctrl2;
- u32 tx_l1_vmode_ctrl1;
- u32 tx_l1_vmode_ctrl2;
- u32 tx_l2_vmode_ctrl1;
- u32 tx_l2_vmode_ctrl2;
- u32 tx_l3_vmode_ctrl1;
- u32 tx_l3_vmode_ctrl2;
- u32 tx_l0_res_code_lane_tx;
- u32 tx_l1_res_code_lane_tx;
- u32 tx_l2_res_code_lane_tx;
- u32 tx_l3_res_code_lane_tx;
- u32 phy_mode;
- };
- struct hdmi_8996_v3_post_divider {
- u64 vco_freq;
- u64 hsclk_divsel;
- u64 vco_ratio;
- u64 tx_band_sel;
- u64 half_rate_mode;
- };
- static inline struct hdmi_pll_vco_clk *to_hdmi_8996_vco_clk(struct clk *clk)
- {
- return container_of(clk, struct hdmi_pll_vco_clk, c);
- }
- static inline u64 hdmi_8996_v1_get_post_div_lt_2g(u64 bclk)
- {
- if (bclk >= HDMI_2400MHZ_BIT_CLK_HZ)
- return 2;
- else if (bclk >= HDMI_1700MHZ_BIT_CLK_HZ)
- return 3;
- else if (bclk >= HDMI_1200MHZ_BIT_CLK_HZ)
- return 4;
- else if (bclk >= HDMI_850MHZ_BIT_CLK_HZ)
- return 3;
- else if (bclk >= HDMI_600MHZ_BIT_CLK_HZ)
- return 4;
- else if (bclk >= HDMI_450MHZ_BIT_CLK_HZ)
- return 3;
- else if (bclk >= HDMI_300MHZ_BIT_CLK_HZ)
- return 4;
- return HDMI_64B_ERR_VAL;
- }
- static inline u64 hdmi_8996_v2_get_post_div_lt_2g(u64 bclk, u64 vco_range)
- {
- u64 hdmi_8ghz = vco_range;
- u64 tmp_calc;
- hdmi_8ghz <<= 2;
- tmp_calc = hdmi_8ghz;
- do_div(tmp_calc, 6U);
- if (bclk >= vco_range)
- return 2;
- else if (bclk >= tmp_calc)
- return 3;
- else if (bclk >= vco_range >> 1)
- return 4;
- tmp_calc = hdmi_8ghz;
- do_div(tmp_calc, 12U);
- if (bclk >= tmp_calc)
- return 3;
- else if (bclk >= vco_range >> 2)
- return 4;
- tmp_calc = hdmi_8ghz;
- do_div(tmp_calc, 24U);
- if (bclk >= tmp_calc)
- return 3;
- else if (bclk >= vco_range >> 3)
- return 4;
- return HDMI_64B_ERR_VAL;
- }
- static inline u64 hdmi_8996_v2_get_post_div_gt_2g(u64 hsclk)
- {
- if (hsclk >= 0 && hsclk <= 3)
- return hsclk + 1;
- return HDMI_64B_ERR_VAL;
- }
- static inline u64 hdmi_8996_get_coreclk_div_lt_2g(u64 bclk)
- {
- if (bclk >= HDMI_1334MHZ_BIT_CLK_HZ)
- return 1;
- else if (bclk >= HDMI_1000MHZ_BIT_CLK_HZ)
- return 1;
- else if (bclk >= HDMI_667MHZ_BIT_CLK_HZ)
- return 2;
- else if (bclk >= HDMI_500MHZ_BIT_CLK_HZ)
- return 2;
- else if (bclk >= HDMI_334MHZ_BIT_CLK_HZ)
- return 3;
- else if (bclk >= HDMI_250MHZ_BIT_CLK_HZ)
- return 3;
- return HDMI_64B_ERR_VAL;
- }
- static inline u64 hdmi_8996_get_coreclk_div_ratio(u64 clks_pll_divsel,
- u64 coreclk_div)
- {
- if (clks_pll_divsel == 0)
- return coreclk_div*2;
- else if (clks_pll_divsel == 1)
- return coreclk_div*4;
- return HDMI_64B_ERR_VAL;
- }
- static inline u64 hdmi_8996_v1_get_tx_band(u64 bclk)
- {
- if (bclk >= 2400000000UL)
- return 0;
- if (bclk >= 1200000000UL)
- return 1;
- if (bclk >= 600000000UL)
- return 2;
- if (bclk >= 300000000UL)
- return 3;
- return HDMI_64B_ERR_VAL;
- }
- static inline u64 hdmi_8996_v2_get_tx_band(u64 bclk, u64 vco_range)
- {
- if (bclk >= vco_range)
- return 0;
- else if (bclk >= vco_range >> 1)
- return 1;
- else if (bclk >= vco_range >> 2)
- return 2;
- else if (bclk >= vco_range >> 3)
- return 3;
- return HDMI_64B_ERR_VAL;
- }
- static inline u64 hdmi_8996_v1_get_hsclk(u64 fdata)
- {
- if (fdata >= 9600000000UL)
- return 0;
- else if (fdata >= 4800000000UL)
- return 1;
- else if (fdata >= 3200000000UL)
- return 2;
- else if (fdata >= 2400000000UL)
- return 3;
- return HDMI_64B_ERR_VAL;
- }
- static inline u64 hdmi_8996_v2_get_hsclk(u64 fdata, u64 vco_range)
- {
- u64 tmp_calc = vco_range;
- tmp_calc <<= 2;
- do_div(tmp_calc, 3U);
- if (fdata >= (vco_range << 2))
- return 0;
- else if (fdata >= (vco_range << 1))
- return 1;
- else if (fdata >= tmp_calc)
- return 2;
- else if (fdata >= vco_range)
- return 3;
- return HDMI_64B_ERR_VAL;
- }
- static inline u64 hdmi_8996_v2_get_vco_freq(u64 bclk, u64 vco_range)
- {
- u64 tx_band_div_ratio = 1U << hdmi_8996_v2_get_tx_band(bclk, vco_range);
- u64 pll_post_div_ratio;
- if (bclk >= vco_range) {
- u64 hsclk = hdmi_8996_v2_get_hsclk(bclk, vco_range);
- pll_post_div_ratio = hdmi_8996_v2_get_post_div_gt_2g(hsclk);
- } else {
- pll_post_div_ratio = hdmi_8996_v2_get_post_div_lt_2g(bclk,
- vco_range);
- }
- return bclk * (pll_post_div_ratio * tx_band_div_ratio);
- }
- static inline u64 hdmi_8996_v2_get_fdata(u64 bclk, u64 vco_range)
- {
- if (bclk >= vco_range)
- return bclk;
- u64 tmp_calc = hdmi_8996_v2_get_vco_freq(bclk, vco_range);
- u64 pll_post_div_ratio_lt_2g = hdmi_8996_v2_get_post_div_lt_2g(
- bclk, vco_range);
- if (pll_post_div_ratio_lt_2g == HDMI_64B_ERR_VAL)
- return HDMI_64B_ERR_VAL;
- do_div(tmp_calc, pll_post_div_ratio_lt_2g);
- return tmp_calc;
- }
- static inline u64 hdmi_8996_get_cpctrl(u64 frac_start, bool gen_ssc)
- {
- if ((frac_start != 0) || gen_ssc)
- /*
- * This should be ROUND(11/(19.2/20))).
- * Since ref clock does not change, hardcoding to 11
- */
- return 0xB;
- return 0x23;
- }
- static inline u64 hdmi_8996_get_rctrl(u64 frac_start, bool gen_ssc)
- {
- if ((frac_start != 0) || gen_ssc)
- return 0x16;
- return 0x10;
- }
- static inline u64 hdmi_8996_get_cctrl(u64 frac_start, bool gen_ssc)
- {
- if ((frac_start != 0) || (gen_ssc))
- return 0x28;
- return 0x1;
- }
- static inline u64 hdmi_8996_get_integloop_gain(u64 frac_start, bool gen_ssc)
- {
- if ((frac_start != 0) || gen_ssc)
- return 0x80;
- return 0xC4;
- }
- static inline u64 hdmi_8996_v3_get_integloop_gain(u64 frac_start, u64 bclk,
- bool gen_ssc)
- {
- u64 digclk_divsel = bclk >= HDMI_DIG_FREQ_BIT_CLK_THRESHOLD ? 1 : 2;
- u64 base = ((frac_start != 0) || gen_ssc) ? 0x40 : 0xC4;
- base <<= digclk_divsel;
- return (base <= 2046 ? base : 0x7FE);
- }
- static inline u64 hdmi_8996_get_vco_tune(u64 fdata, u64 div)
- {
- u64 vco_tune;
- vco_tune = fdata * div;
- do_div(vco_tune, 1000000);
- vco_tune = 13000 - vco_tune - 256;
- do_div(vco_tune, 5);
- return vco_tune;
- }
- static inline u64 hdmi_8996_get_pll_cmp(u64 pll_cmp_cnt, u64 core_clk)
- {
- u64 pll_cmp;
- u64 rem;
- pll_cmp = pll_cmp_cnt * core_clk;
- rem = do_div(pll_cmp, HDMI_REF_CLOCK);
- if (rem > (HDMI_REF_CLOCK >> 1))
- pll_cmp++;
- pll_cmp -= 1;
- return pll_cmp;
- }
- static inline u64 hdmi_8996_v3_get_pll_cmp(u64 pll_cmp_cnt, u64 fdata)
- {
- u64 dividend = pll_cmp_cnt * fdata;
- u64 divisor = HDMI_REF_CLOCK * 10;
- u64 rem;
- rem = do_div(dividend, divisor);
- if (rem > (divisor >> 1))
- dividend++;
- return dividend - 1;
- }
- static int hdmi_8996_v3_get_post_div(struct hdmi_8996_v3_post_divider *pd,
- u64 bclk)
- {
- u32 ratio[] = {2, 3, 4, 5, 6, 9, 10, 12, 14, 15, 20, 21, 25, 28, 35};
- u32 tx_band_sel[] = {0, 1, 2, 3};
- u64 vco_freq[60];
- u64 vco, vco_optimal, half_rate_mode = 0;
- int vco_optimal_index, vco_freq_index;
- int i, j, k, x;
- for (i = 0; i <= 1; i++) {
- vco_optimal = HDMI_VCO_MAX_FREQ;
- vco_optimal_index = -1;
- vco_freq_index = 0;
- for (j = 0; j < 15; j++) {
- for (k = 0; k < 4; k++) {
- u64 ratio_mult = ratio[j] << tx_band_sel[k];
- vco = bclk >> half_rate_mode;
- vco *= ratio_mult;
- vco_freq[vco_freq_index++] = vco;
- }
- }
- for (x = 0; x < 60; x++) {
- u64 vco_tmp = vco_freq[x];
- if ((vco_tmp >= HDMI_VCO_MIN_FREQ) &&
- (vco_tmp <= vco_optimal)) {
- vco_optimal = vco_tmp;
- vco_optimal_index = x;
- }
- }
- if (vco_optimal_index == -1) {
- if (!half_rate_mode)
- half_rate_mode++;
- else
- return -EINVAL;
- } else {
- pd->vco_freq = vco_optimal;
- pd->tx_band_sel = tx_band_sel[vco_optimal_index % 4];
- pd->vco_ratio = ratio[vco_optimal_index / 4];
- break;
- }
- }
- switch (pd->vco_ratio) {
- case 2:
- pd->hsclk_divsel = 0;
- break;
- case 3:
- pd->hsclk_divsel = 4;
- break;
- case 4:
- pd->hsclk_divsel = 8;
- break;
- case 5:
- pd->hsclk_divsel = 12;
- break;
- case 6:
- pd->hsclk_divsel = 1;
- break;
- case 9:
- pd->hsclk_divsel = 5;
- break;
- case 10:
- pd->hsclk_divsel = 2;
- break;
- case 12:
- pd->hsclk_divsel = 9;
- break;
- case 14:
- pd->hsclk_divsel = 3;
- break;
- case 15:
- pd->hsclk_divsel = 13;
- break;
- case 20:
- pd->hsclk_divsel = 10;
- break;
- case 21:
- pd->hsclk_divsel = 7;
- break;
- case 25:
- pd->hsclk_divsel = 14;
- break;
- case 28:
- pd->hsclk_divsel = 11;
- break;
- case 35:
- pd->hsclk_divsel = 15;
- break;
- }
- return 0;
- }
- static int hdmi_8996_v1_calculate(u32 pix_clk,
- struct hdmi_8996_phy_pll_reg_cfg *cfg)
- {
- int rc = -EINVAL;
- u64 fdata, clk_divtx, tmds_clk;
- u64 bclk;
- u64 post_div_gt_2g;
- u64 post_div_lt_2g;
- u64 coreclk_div1_lt_2g;
- u64 core_clk_div_ratio;
- u64 core_clk;
- u64 pll_cmp;
- u64 tx_band;
- u64 tx_band_div_ratio;
- u64 hsclk;
- u64 dec_start;
- u64 frac_start;
- u64 pll_divisor = 4 * HDMI_REF_CLOCK;
- u64 cpctrl;
- u64 rctrl;
- u64 cctrl;
- u64 integloop_gain;
- u64 vco_tune;
- u64 vco_freq;
- u64 rem;
- /* FDATA, CLK_DIVTX, PIXEL_CLK, TMDS_CLK */
- bclk = ((u64)pix_clk) * HDMI_BIT_CLK_TO_PIX_CLK_RATIO;
- if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD)
- tmds_clk = bclk/4;
- else
- tmds_clk = bclk;
- post_div_lt_2g = hdmi_8996_v1_get_post_div_lt_2g(bclk);
- if (post_div_lt_2g == HDMI_64B_ERR_VAL)
- goto fail;
- coreclk_div1_lt_2g = hdmi_8996_get_coreclk_div_lt_2g(bclk);
- core_clk_div_ratio = hdmi_8996_get_coreclk_div_ratio(
- HDMI_CLKS_PLL_DIVSEL, HDMI_CORECLK_DIV);
- tx_band = hdmi_8996_v1_get_tx_band(bclk);
- if (tx_band == HDMI_64B_ERR_VAL)
- goto fail;
- tx_band_div_ratio = 1 << tx_band;
- if (bclk >= HDMI_2400MHZ_BIT_CLK_HZ) {
- fdata = bclk;
- hsclk = hdmi_8996_v1_get_hsclk(fdata);
- if (hsclk == HDMI_64B_ERR_VAL)
- goto fail;
- post_div_gt_2g = (hsclk <= 3) ? (hsclk + 1) : HDMI_64B_ERR_VAL;
- if (post_div_gt_2g == HDMI_64B_ERR_VAL)
- goto fail;
- vco_freq = bclk * (post_div_gt_2g * tx_band_div_ratio);
- clk_divtx = vco_freq;
- do_div(clk_divtx, post_div_gt_2g);
- } else {
- vco_freq = bclk * (post_div_lt_2g * tx_band_div_ratio);
- fdata = vco_freq;
- do_div(fdata, post_div_lt_2g);
- hsclk = hdmi_8996_v1_get_hsclk(fdata);
- if (hsclk == HDMI_64B_ERR_VAL)
- goto fail;
- clk_divtx = vco_freq;
- do_div(clk_divtx, post_div_lt_2g);
- post_div_gt_2g = (hsclk <= 3) ? (hsclk + 1) : HDMI_64B_ERR_VAL;
- if (post_div_gt_2g == HDMI_64B_ERR_VAL)
- goto fail;
- }
- /* Decimal and fraction values */
- dec_start = fdata * post_div_gt_2g;
- do_div(dec_start, pll_divisor);
- frac_start = ((pll_divisor - (((dec_start + 1) * pll_divisor) -
- (fdata * post_div_gt_2g))) * (1 << 20));
- rem = do_div(frac_start, pll_divisor);
- /* Round off frac_start to closest integer */
- if (rem >= (pll_divisor >> 1))
- frac_start++;
- cpctrl = hdmi_8996_get_cpctrl(frac_start, false);
- rctrl = hdmi_8996_get_rctrl(frac_start, false);
- cctrl = hdmi_8996_get_cctrl(frac_start, false);
- integloop_gain = hdmi_8996_get_integloop_gain(frac_start, false);
- vco_tune = hdmi_8996_get_vco_tune(fdata, post_div_gt_2g);
- core_clk = clk_divtx;
- do_div(core_clk, core_clk_div_ratio);
- pll_cmp = hdmi_8996_get_pll_cmp(1024, core_clk);
- /* Debug dump */
- DEV_DBG("%s: VCO freq: %llu\n", __func__, vco_freq);
- DEV_DBG("%s: fdata: %llu\n", __func__, fdata);
- DEV_DBG("%s: CLK_DIVTX: %llu\n", __func__, clk_divtx);
- DEV_DBG("%s: pix_clk: %d\n", __func__, pix_clk);
- DEV_DBG("%s: tmds clk: %llu\n", __func__, tmds_clk);
- DEV_DBG("%s: HSCLK_SEL: %llu\n", __func__, hsclk);
- DEV_DBG("%s: DEC_START: %llu\n", __func__, dec_start);
- DEV_DBG("%s: DIV_FRAC_START: %llu\n", __func__, frac_start);
- DEV_DBG("%s: PLL_CPCTRL: %llu\n", __func__, cpctrl);
- DEV_DBG("%s: PLL_RCTRL: %llu\n", __func__, rctrl);
- DEV_DBG("%s: PLL_CCTRL: %llu\n", __func__, cctrl);
- DEV_DBG("%s: INTEGLOOP_GAIN: %llu\n", __func__, integloop_gain);
- DEV_DBG("%s: VCO_TUNE: %llu\n", __func__, vco_tune);
- DEV_DBG("%s: TX_BAND: %llu\n", __func__, tx_band);
- DEV_DBG("%s: PLL_CMP: %llu\n", __func__, pll_cmp);
- /* Convert these values to register specific values */
- cfg->tx_l0_lane_mode = 0x3;
- cfg->tx_l2_lane_mode = 0x3;
- cfg->tx_l0_tx_band = tx_band + 4;
- cfg->tx_l1_tx_band = tx_band + 4;
- cfg->tx_l2_tx_band = tx_band + 4;
- cfg->tx_l3_tx_band = tx_band + 4;
- cfg->tx_l0_res_code_lane_tx = 0x33;
- cfg->tx_l1_res_code_lane_tx = 0x33;
- cfg->tx_l2_res_code_lane_tx = 0x33;
- cfg->tx_l3_res_code_lane_tx = 0x33;
- cfg->com_restrim_ctrl = 0x0;
- cfg->com_vco_tune_ctrl = 0x1C;
- cfg->com_svs_mode_clk_sel =
- (bclk >= HDMI_DIG_FREQ_BIT_CLK_THRESHOLD ? 1 : 2);
- cfg->com_hsclk_sel = (0x28 | hsclk);
- cfg->com_pll_cctrl_mode0 = cctrl;
- cfg->com_pll_rctrl_mode0 = rctrl;
- cfg->com_cp_ctrl_mode0 = cpctrl;
- cfg->com_dec_start_mode0 = dec_start;
- cfg->com_div_frac_start1_mode0 = (frac_start & 0xFF);
- cfg->com_div_frac_start2_mode0 = ((frac_start & 0xFF00) >> 8);
- cfg->com_div_frac_start3_mode0 = ((frac_start & 0xF0000) >> 16);
- cfg->com_integloop_gain0_mode0 = (integloop_gain & 0xFF);
- cfg->com_integloop_gain1_mode0 = ((integloop_gain & 0xF00) >> 8);
- cfg->com_lock_cmp1_mode0 = (pll_cmp & 0xFF);
- cfg->com_lock_cmp2_mode0 = ((pll_cmp & 0xFF00) >> 8);
- cfg->com_lock_cmp3_mode0 = ((pll_cmp & 0x30000) >> 16);
- cfg->com_core_clk_en = (0x6C | (HDMI_CLKS_PLL_DIVSEL << 4));
- cfg->com_coreclk_div = HDMI_CORECLK_DIV;
- if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) {
- cfg->tx_l0_tx_drv_lvl = 0x25;
- cfg->tx_l0_tx_emp_post1_lvl = 0x23;
- cfg->tx_l1_tx_drv_lvl = 0x25;
- cfg->tx_l1_tx_emp_post1_lvl = 0x23;
- cfg->tx_l2_tx_drv_lvl = 0x25;
- cfg->tx_l2_tx_emp_post1_lvl = 0x23;
- cfg->tx_l3_tx_drv_lvl = 0x22;
- cfg->tx_l3_tx_emp_post1_lvl = 0x27;
- cfg->tx_l0_vmode_ctrl1 = 0x00;
- cfg->tx_l0_vmode_ctrl2 = 0x0D;
- cfg->tx_l1_vmode_ctrl1 = 0x00;
- cfg->tx_l1_vmode_ctrl2 = 0x0D;
- cfg->tx_l2_vmode_ctrl1 = 0x00;
- cfg->tx_l2_vmode_ctrl2 = 0x0D;
- cfg->tx_l3_vmode_ctrl1 = 0x00;
- cfg->tx_l3_vmode_ctrl2 = 0x00;
- cfg->com_restrim_ctrl = 0x0;
- } else if (bclk > HDMI_MID_FREQ_BIT_CLK_THRESHOLD) {
- cfg->tx_l0_tx_drv_lvl = 0x25;
- cfg->tx_l0_tx_emp_post1_lvl = 0x23;
- cfg->tx_l1_tx_drv_lvl = 0x25;
- cfg->tx_l1_tx_emp_post1_lvl = 0x23;
- cfg->tx_l2_tx_drv_lvl = 0x25;
- cfg->tx_l2_tx_emp_post1_lvl = 0x23;
- cfg->tx_l3_tx_drv_lvl = 0x25;
- cfg->tx_l3_tx_emp_post1_lvl = 0x23;
- cfg->tx_l0_vmode_ctrl1 = 0x00;
- cfg->tx_l0_vmode_ctrl2 = 0x0D;
- cfg->tx_l1_vmode_ctrl1 = 0x00;
- cfg->tx_l1_vmode_ctrl2 = 0x0D;
- cfg->tx_l2_vmode_ctrl1 = 0x00;
- cfg->tx_l2_vmode_ctrl2 = 0x0D;
- cfg->tx_l3_vmode_ctrl1 = 0x00;
- cfg->tx_l3_vmode_ctrl2 = 0x00;
- cfg->com_restrim_ctrl = 0x0;
- } else {
- cfg->tx_l0_tx_drv_lvl = 0x20;
- cfg->tx_l0_tx_emp_post1_lvl = 0x20;
- cfg->tx_l1_tx_drv_lvl = 0x20;
- cfg->tx_l1_tx_emp_post1_lvl = 0x20;
- cfg->tx_l2_tx_drv_lvl = 0x20;
- cfg->tx_l2_tx_emp_post1_lvl = 0x20;
- cfg->tx_l3_tx_drv_lvl = 0x20;
- cfg->tx_l3_tx_emp_post1_lvl = 0x20;
- cfg->tx_l0_vmode_ctrl1 = 0x00;
- cfg->tx_l0_vmode_ctrl2 = 0x0E;
- cfg->tx_l1_vmode_ctrl1 = 0x00;
- cfg->tx_l1_vmode_ctrl2 = 0x0E;
- cfg->tx_l2_vmode_ctrl1 = 0x00;
- cfg->tx_l2_vmode_ctrl2 = 0x0E;
- cfg->tx_l3_vmode_ctrl1 = 0x00;
- cfg->tx_l3_vmode_ctrl2 = 0x0E;
- cfg->com_restrim_ctrl = 0xD8;
- }
- cfg->phy_mode = (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) ? 0x10 : 0x0;
- DEV_DBG("HDMI 8996 PLL: PLL Settings\n");
- DEV_DBG("PLL PARAM: tx_l0_lane_mode = 0x%x\n", cfg->tx_l0_lane_mode);
- DEV_DBG("PLL PARAM: tx_l2_lane_mode = 0x%x\n", cfg->tx_l2_lane_mode);
- DEV_DBG("PLL PARAM: tx_l0_tx_band = 0x%x\n", cfg->tx_l0_tx_band);
- DEV_DBG("PLL PARAM: tx_l1_tx_band = 0x%x\n", cfg->tx_l1_tx_band);
- DEV_DBG("PLL PARAM: tx_l2_tx_band = 0x%x\n", cfg->tx_l2_tx_band);
- DEV_DBG("PLL PARAM: tx_l3_tx_band = 0x%x\n", cfg->tx_l3_tx_band);
- DEV_DBG("PLL PARAM: com_svs_mode_clk_sel = 0x%x\n",
- cfg->com_svs_mode_clk_sel);
- DEV_DBG("PLL PARAM: com_hsclk_sel = 0x%x\n", cfg->com_hsclk_sel);
- DEV_DBG("PLL PARAM: com_pll_cctrl_mode0 = 0x%x\n",
- cfg->com_pll_cctrl_mode0);
- DEV_DBG("PLL PARAM: com_pll_rctrl_mode0 = 0x%x\n",
- cfg->com_pll_rctrl_mode0);
- DEV_DBG("PLL PARAM: com_cp_ctrl_mode0 = 0x%x\n",
- cfg->com_cp_ctrl_mode0);
- DEV_DBG("PLL PARAM: com_dec_start_mode0 = 0x%x\n",
- cfg->com_dec_start_mode0);
- DEV_DBG("PLL PARAM: com_div_frac_start1_mode0 = 0x%x\n",
- cfg->com_div_frac_start1_mode0);
- DEV_DBG("PLL PARAM: com_div_frac_start2_mode0 = 0x%x\n",
- cfg->com_div_frac_start2_mode0);
- DEV_DBG("PLL PARAM: com_div_frac_start3_mode0 = 0x%x\n",
- cfg->com_div_frac_start3_mode0);
- DEV_DBG("PLL PARAM: com_integloop_gain0_mode0 = 0x%x\n",
- cfg->com_integloop_gain0_mode0);
- DEV_DBG("PLL PARAM: com_integloop_gain1_mode0 = 0x%x\n",
- cfg->com_integloop_gain1_mode0);
- DEV_DBG("PLL PARAM: com_lock_cmp1_mode0 = 0x%x\n",
- cfg->com_lock_cmp1_mode0);
- DEV_DBG("PLL PARAM: com_lock_cmp2_mode0 = 0x%x\n",
- cfg->com_lock_cmp2_mode0);
- DEV_DBG("PLL PARAM: com_lock_cmp3_mode0 = 0x%x\n",
- cfg->com_lock_cmp3_mode0);
- DEV_DBG("PLL PARAM: com_core_clk_en = 0x%x\n", cfg->com_core_clk_en);
- DEV_DBG("PLL PARAM: com_coreclk_div = 0x%x\n", cfg->com_coreclk_div);
- DEV_DBG("PLL PARAM: com_restrim_ctrl = 0x%x\n", cfg->com_restrim_ctrl);
- DEV_DBG("PLL PARAM: l0_tx_drv_lvl = 0x%x\n", cfg->tx_l0_tx_drv_lvl);
- DEV_DBG("PLL PARAM: l0_tx_emp_post1_lvl = 0x%x\n",
- cfg->tx_l0_tx_emp_post1_lvl);
- DEV_DBG("PLL PARAM: l1_tx_drv_lvl = 0x%x\n", cfg->tx_l1_tx_drv_lvl);
- DEV_DBG("PLL PARAM: l1_tx_emp_post1_lvl = 0x%x\n",
- cfg->tx_l1_tx_emp_post1_lvl);
- DEV_DBG("PLL PARAM: l2_tx_drv_lvl = 0x%x\n", cfg->tx_l2_tx_drv_lvl);
- DEV_DBG("PLL PARAM: l2_tx_emp_post1_lvl = 0x%x\n",
- cfg->tx_l2_tx_emp_post1_lvl);
- DEV_DBG("PLL PARAM: l3_tx_drv_lvl = 0x%x\n", cfg->tx_l3_tx_drv_lvl);
- DEV_DBG("PLL PARAM: l3_tx_emp_post1_lvl = 0x%x\n",
- cfg->tx_l3_tx_emp_post1_lvl);
- DEV_DBG("PLL PARAM: l0_vmode_ctrl1 = 0x%x\n", cfg->tx_l0_vmode_ctrl1);
- DEV_DBG("PLL PARAM: l0_vmode_ctrl2 = 0x%x\n", cfg->tx_l0_vmode_ctrl2);
- DEV_DBG("PLL PARAM: l1_vmode_ctrl1 = 0x%x\n", cfg->tx_l1_vmode_ctrl1);
- DEV_DBG("PLL PARAM: l1_vmode_ctrl2 = 0x%x\n", cfg->tx_l1_vmode_ctrl2);
- DEV_DBG("PLL PARAM: l2_vmode_ctrl1 = 0x%x\n", cfg->tx_l2_vmode_ctrl1);
- DEV_DBG("PLL PARAM: l2_vmode_ctrl2 = 0x%x\n", cfg->tx_l2_vmode_ctrl2);
- DEV_DBG("PLL PARAM: l3_vmode_ctrl1 = 0x%x\n", cfg->tx_l3_vmode_ctrl1);
- DEV_DBG("PLL PARAM: l3_vmode_ctrl2 = 0x%x\n", cfg->tx_l3_vmode_ctrl2);
- DEV_DBG("PLL PARAM: tx_l0_res_code_lane_tx = 0x%x\n",
- cfg->tx_l0_res_code_lane_tx);
- DEV_DBG("PLL PARAM: tx_l1_res_code_lane_tx = 0x%x\n",
- cfg->tx_l1_res_code_lane_tx);
- DEV_DBG("PLL PARAM: tx_l2_res_code_lane_tx = 0x%x\n",
- cfg->tx_l2_res_code_lane_tx);
- DEV_DBG("PLL PARAM: tx_l3_res_code_lane_tx = 0x%x\n",
- cfg->tx_l3_res_code_lane_tx);
- DEV_DBG("PLL PARAM: phy_mode = 0x%x\n", cfg->phy_mode);
- rc = 0;
- fail:
- return rc;
- }
- static int hdmi_8996_v2_calculate(u32 pix_clk,
- struct hdmi_8996_phy_pll_reg_cfg *cfg)
- {
- int rc = -EINVAL;
- u64 fdata, clk_divtx, tmds_clk;
- u64 bclk;
- u64 post_div;
- u64 core_clk_div;
- u64 core_clk_div_ratio;
- u64 core_clk;
- u64 pll_cmp;
- u64 tx_band;
- u64 tx_band_div_ratio;
- u64 hsclk;
- u64 dec_start;
- u64 frac_start;
- u64 pll_divisor = 4 * HDMI_REF_CLOCK;
- u64 cpctrl;
- u64 rctrl;
- u64 cctrl;
- u64 integloop_gain;
- u64 vco_tune;
- u64 vco_freq;
- u64 vco_range;
- u64 rem;
- /* FDATA, CLK_DIVTX, PIXEL_CLK, TMDS_CLK */
- bclk = ((u64)pix_clk) * HDMI_BIT_CLK_TO_PIX_CLK_RATIO;
- if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD)
- tmds_clk = pix_clk >> 2;
- else
- tmds_clk = pix_clk;
- vco_range = bclk < HDMI_282MHZ_BIT_CLK_HZ ? HDMI_2000MHZ_BIT_CLK_HZ :
- HDMI_2250MHZ_BIT_CLK_HZ;
- fdata = hdmi_8996_v2_get_fdata(bclk, vco_range);
- if (fdata == HDMI_64B_ERR_VAL)
- goto fail;
- hsclk = hdmi_8996_v2_get_hsclk(fdata, vco_range);
- if (hsclk == HDMI_64B_ERR_VAL)
- goto fail;
- if (bclk >= vco_range)
- post_div = hdmi_8996_v2_get_post_div_gt_2g(hsclk);
- else
- post_div = hdmi_8996_v2_get_post_div_lt_2g(bclk, vco_range);
- if (post_div == HDMI_64B_ERR_VAL)
- goto fail;
- core_clk_div = 5;
- core_clk_div_ratio = core_clk_div * 2;
- tx_band = hdmi_8996_v2_get_tx_band(bclk, vco_range);
- if (tx_band == HDMI_64B_ERR_VAL)
- goto fail;
- tx_band_div_ratio = 1 << tx_band;
- vco_freq = hdmi_8996_v2_get_vco_freq(bclk, vco_range);
- clk_divtx = vco_freq;
- do_div(clk_divtx, post_div);
- /* Decimal and fraction values */
- dec_start = fdata * post_div;
- do_div(dec_start, pll_divisor);
- frac_start = ((pll_divisor - (((dec_start + 1) * pll_divisor) -
- (fdata * post_div))) * (1 << 20));
- rem = do_div(frac_start, pll_divisor);
- /* Round off frac_start to closest integer */
- if (rem >= (pll_divisor >> 1))
- frac_start++;
- cpctrl = hdmi_8996_get_cpctrl(frac_start, false);
- rctrl = hdmi_8996_get_rctrl(frac_start, false);
- cctrl = hdmi_8996_get_cctrl(frac_start, false);
- integloop_gain = hdmi_8996_get_integloop_gain(frac_start, false);
- vco_tune = hdmi_8996_get_vco_tune(fdata, post_div);
- core_clk = clk_divtx;
- do_div(core_clk, core_clk_div_ratio);
- pll_cmp = hdmi_8996_get_pll_cmp(1024, core_clk);
- /* Debug dump */
- DEV_DBG("%s: VCO freq: %llu\n", __func__, vco_freq);
- DEV_DBG("%s: fdata: %llu\n", __func__, fdata);
- DEV_DBG("%s: CLK_DIVTX: %llu\n", __func__, clk_divtx);
- DEV_DBG("%s: pix_clk: %d\n", __func__, pix_clk);
- DEV_DBG("%s: tmds clk: %llu\n", __func__, tmds_clk);
- DEV_DBG("%s: HSCLK_SEL: %llu\n", __func__, hsclk);
- DEV_DBG("%s: DEC_START: %llu\n", __func__, dec_start);
- DEV_DBG("%s: DIV_FRAC_START: %llu\n", __func__, frac_start);
- DEV_DBG("%s: PLL_CPCTRL: %llu\n", __func__, cpctrl);
- DEV_DBG("%s: PLL_RCTRL: %llu\n", __func__, rctrl);
- DEV_DBG("%s: PLL_CCTRL: %llu\n", __func__, cctrl);
- DEV_DBG("%s: INTEGLOOP_GAIN: %llu\n", __func__, integloop_gain);
- DEV_DBG("%s: VCO_TUNE: %llu\n", __func__, vco_tune);
- DEV_DBG("%s: TX_BAND: %llu\n", __func__, tx_band);
- DEV_DBG("%s: PLL_CMP: %llu\n", __func__, pll_cmp);
- /* Convert these values to register specific values */
- cfg->tx_l0_lane_mode = 0x3;
- cfg->tx_l2_lane_mode = 0x3;
- cfg->tx_l0_tx_band = tx_band + 4;
- cfg->tx_l1_tx_band = tx_band + 4;
- cfg->tx_l2_tx_band = tx_band + 4;
- cfg->tx_l3_tx_band = tx_band + 4;
- if (bclk > HDMI_DIG_FREQ_BIT_CLK_THRESHOLD)
- cfg->com_svs_mode_clk_sel = 1;
- else
- cfg->com_svs_mode_clk_sel = 2;
- cfg->com_hsclk_sel = (0x28 | hsclk);
- cfg->com_pll_cctrl_mode0 = cctrl;
- cfg->com_pll_rctrl_mode0 = rctrl;
- cfg->com_cp_ctrl_mode0 = cpctrl;
- cfg->com_dec_start_mode0 = dec_start;
- cfg->com_div_frac_start1_mode0 = (frac_start & 0xFF);
- cfg->com_div_frac_start2_mode0 = ((frac_start & 0xFF00) >> 8);
- cfg->com_div_frac_start3_mode0 = ((frac_start & 0xF0000) >> 16);
- cfg->com_integloop_gain0_mode0 = (integloop_gain & 0xFF);
- cfg->com_integloop_gain1_mode0 = ((integloop_gain & 0xF00) >> 8);
- cfg->com_lock_cmp1_mode0 = (pll_cmp & 0xFF);
- cfg->com_lock_cmp2_mode0 = ((pll_cmp & 0xFF00) >> 8);
- cfg->com_lock_cmp3_mode0 = ((pll_cmp & 0x30000) >> 16);
- cfg->com_core_clk_en = (0x6C | (HDMI_CLKS_PLL_DIVSEL << 4));
- cfg->com_coreclk_div = HDMI_CORECLK_DIV;
- cfg->com_vco_tune_ctrl = 0x0;
- if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) {
- cfg->tx_l0_tx_drv_lvl = 0x25;
- cfg->tx_l0_tx_emp_post1_lvl = 0x23;
- cfg->tx_l1_tx_drv_lvl = 0x25;
- cfg->tx_l1_tx_emp_post1_lvl = 0x23;
- cfg->tx_l2_tx_drv_lvl = 0x25;
- cfg->tx_l2_tx_emp_post1_lvl = 0x23;
- cfg->tx_l3_tx_drv_lvl = 0x22;
- cfg->tx_l3_tx_emp_post1_lvl = 0x27;
- cfg->tx_l0_vmode_ctrl1 = 0x00;
- cfg->tx_l0_vmode_ctrl2 = 0x0D;
- cfg->tx_l1_vmode_ctrl1 = 0x00;
- cfg->tx_l1_vmode_ctrl2 = 0x0D;
- cfg->tx_l2_vmode_ctrl1 = 0x00;
- cfg->tx_l2_vmode_ctrl2 = 0x0D;
- cfg->tx_l3_vmode_ctrl1 = 0x00;
- cfg->tx_l3_vmode_ctrl2 = 0x00;
- cfg->tx_l0_res_code_lane_tx = 0x3F;
- cfg->tx_l1_res_code_lane_tx = 0x3F;
- cfg->tx_l2_res_code_lane_tx = 0x3F;
- cfg->tx_l3_res_code_lane_tx = 0x3F;
- cfg->com_restrim_ctrl = 0x0;
- } else if (bclk > HDMI_MID_FREQ_BIT_CLK_THRESHOLD) {
- cfg->tx_l0_tx_drv_lvl = 0x25;
- cfg->tx_l0_tx_emp_post1_lvl = 0x23;
- cfg->tx_l1_tx_drv_lvl = 0x25;
- cfg->tx_l1_tx_emp_post1_lvl = 0x23;
- cfg->tx_l2_tx_drv_lvl = 0x25;
- cfg->tx_l2_tx_emp_post1_lvl = 0x23;
- cfg->tx_l3_tx_drv_lvl = 0x25;
- cfg->tx_l3_tx_emp_post1_lvl = 0x23;
- cfg->tx_l0_vmode_ctrl1 = 0x00;
- cfg->tx_l0_vmode_ctrl2 = 0x0D;
- cfg->tx_l1_vmode_ctrl1 = 0x00;
- cfg->tx_l1_vmode_ctrl2 = 0x0D;
- cfg->tx_l2_vmode_ctrl1 = 0x00;
- cfg->tx_l2_vmode_ctrl2 = 0x0D;
- cfg->tx_l3_vmode_ctrl1 = 0x00;
- cfg->tx_l3_vmode_ctrl2 = 0x00;
- cfg->tx_l0_res_code_lane_tx = 0x39;
- cfg->tx_l1_res_code_lane_tx = 0x39;
- cfg->tx_l2_res_code_lane_tx = 0x39;
- cfg->tx_l3_res_code_lane_tx = 0x39;
- cfg->com_restrim_ctrl = 0x0;
- } else {
- cfg->tx_l0_tx_drv_lvl = 0x20;
- cfg->tx_l0_tx_emp_post1_lvl = 0x20;
- cfg->tx_l1_tx_drv_lvl = 0x20;
- cfg->tx_l1_tx_emp_post1_lvl = 0x20;
- cfg->tx_l2_tx_drv_lvl = 0x20;
- cfg->tx_l2_tx_emp_post1_lvl = 0x20;
- cfg->tx_l3_tx_drv_lvl = 0x20;
- cfg->tx_l3_tx_emp_post1_lvl = 0x20;
- cfg->tx_l0_vmode_ctrl1 = 0x00;
- cfg->tx_l0_vmode_ctrl2 = 0x0E;
- cfg->tx_l1_vmode_ctrl1 = 0x00;
- cfg->tx_l1_vmode_ctrl2 = 0x0E;
- cfg->tx_l2_vmode_ctrl1 = 0x00;
- cfg->tx_l2_vmode_ctrl2 = 0x0E;
- cfg->tx_l3_vmode_ctrl1 = 0x00;
- cfg->tx_l3_vmode_ctrl2 = 0x0E;
- cfg->tx_l0_res_code_lane_tx = 0x3F;
- cfg->tx_l1_res_code_lane_tx = 0x3F;
- cfg->tx_l2_res_code_lane_tx = 0x3F;
- cfg->tx_l3_res_code_lane_tx = 0x3F;
- cfg->com_restrim_ctrl = 0xD8;
- }
- cfg->phy_mode = (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) ? 0x10 : 0x0;
- DEV_DBG("HDMI 8996 PLL: PLL Settings\n");
- DEV_DBG("PLL PARAM: tx_l0_lane_mode = 0x%x\n", cfg->tx_l0_lane_mode);
- DEV_DBG("PLL PARAM: tx_l2_lane_mode = 0x%x\n", cfg->tx_l2_lane_mode);
- DEV_DBG("PLL PARAM: tx_l0_tx_band = 0x%x\n", cfg->tx_l0_tx_band);
- DEV_DBG("PLL PARAM: tx_l1_tx_band = 0x%x\n", cfg->tx_l1_tx_band);
- DEV_DBG("PLL PARAM: tx_l2_tx_band = 0x%x\n", cfg->tx_l2_tx_band);
- DEV_DBG("PLL PARAM: tx_l3_tx_band = 0x%x\n", cfg->tx_l3_tx_band);
- DEV_DBG("PLL PARAM: com_svs_mode_clk_sel = 0x%x\n",
- cfg->com_svs_mode_clk_sel);
- DEV_DBG("PLL PARAM: com_vco_tune_ctrl = 0x%x\n",
- cfg->com_vco_tune_ctrl);
- DEV_DBG("PLL PARAM: com_hsclk_sel = 0x%x\n", cfg->com_hsclk_sel);
- DEV_DBG("PLL PARAM: com_lock_cmp_en = 0x%x\n", cfg->com_lock_cmp_en);
- DEV_DBG("PLL PARAM: com_pll_cctrl_mode0 = 0x%x\n",
- cfg->com_pll_cctrl_mode0);
- DEV_DBG("PLL PARAM: com_pll_rctrl_mode0 = 0x%x\n",
- cfg->com_pll_rctrl_mode0);
- DEV_DBG("PLL PARAM: com_cp_ctrl_mode0 = 0x%x\n",
- cfg->com_cp_ctrl_mode0);
- DEV_DBG("PLL PARAM: com_dec_start_mode0 = 0x%x\n",
- cfg->com_dec_start_mode0);
- DEV_DBG("PLL PARAM: com_div_frac_start1_mode0 = 0x%x\n",
- cfg->com_div_frac_start1_mode0);
- DEV_DBG("PLL PARAM: com_div_frac_start2_mode0 = 0x%x\n",
- cfg->com_div_frac_start2_mode0);
- DEV_DBG("PLL PARAM: com_div_frac_start3_mode0 = 0x%x\n",
- cfg->com_div_frac_start3_mode0);
- DEV_DBG("PLL PARAM: com_integloop_gain0_mode0 = 0x%x\n",
- cfg->com_integloop_gain0_mode0);
- DEV_DBG("PLL PARAM: com_integloop_gain1_mode0 = 0x%x\n",
- cfg->com_integloop_gain1_mode0);
- DEV_DBG("PLL PARAM: com_lock_cmp1_mode0 = 0x%x\n",
- cfg->com_lock_cmp1_mode0);
- DEV_DBG("PLL PARAM: com_lock_cmp2_mode0 = 0x%x\n",
- cfg->com_lock_cmp2_mode0);
- DEV_DBG("PLL PARAM: com_lock_cmp3_mode0 = 0x%x\n",
- cfg->com_lock_cmp3_mode0);
- DEV_DBG("PLL PARAM: com_core_clk_en = 0x%x\n", cfg->com_core_clk_en);
- DEV_DBG("PLL PARAM: com_coreclk_div = 0x%x\n", cfg->com_coreclk_div);
- DEV_DBG("PLL PARAM: l0_tx_drv_lvl = 0x%x\n", cfg->tx_l0_tx_drv_lvl);
- DEV_DBG("PLL PARAM: l0_tx_emp_post1_lvl = 0x%x\n",
- cfg->tx_l0_tx_emp_post1_lvl);
- DEV_DBG("PLL PARAM: l1_tx_drv_lvl = 0x%x\n", cfg->tx_l1_tx_drv_lvl);
- DEV_DBG("PLL PARAM: l1_tx_emp_post1_lvl = 0x%x\n",
- cfg->tx_l1_tx_emp_post1_lvl);
- DEV_DBG("PLL PARAM: l2_tx_drv_lvl = 0x%x\n", cfg->tx_l2_tx_drv_lvl);
- DEV_DBG("PLL PARAM: l2_tx_emp_post1_lvl = 0x%x\n",
- cfg->tx_l2_tx_emp_post1_lvl);
- DEV_DBG("PLL PARAM: l3_tx_drv_lvl = 0x%x\n", cfg->tx_l3_tx_drv_lvl);
- DEV_DBG("PLL PARAM: l3_tx_emp_post1_lvl = 0x%x\n",
- cfg->tx_l3_tx_emp_post1_lvl);
- DEV_DBG("PLL PARAM: l0_vmode_ctrl1 = 0x%x\n", cfg->tx_l0_vmode_ctrl1);
- DEV_DBG("PLL PARAM: l0_vmode_ctrl2 = 0x%x\n", cfg->tx_l0_vmode_ctrl2);
- DEV_DBG("PLL PARAM: l1_vmode_ctrl1 = 0x%x\n", cfg->tx_l1_vmode_ctrl1);
- DEV_DBG("PLL PARAM: l1_vmode_ctrl2 = 0x%x\n", cfg->tx_l1_vmode_ctrl2);
- DEV_DBG("PLL PARAM: l2_vmode_ctrl1 = 0x%x\n", cfg->tx_l2_vmode_ctrl1);
- DEV_DBG("PLL PARAM: l2_vmode_ctrl2 = 0x%x\n", cfg->tx_l2_vmode_ctrl2);
- DEV_DBG("PLL PARAM: l3_vmode_ctrl1 = 0x%x\n", cfg->tx_l3_vmode_ctrl1);
- DEV_DBG("PLL PARAM: l3_vmode_ctrl2 = 0x%x\n", cfg->tx_l3_vmode_ctrl2);
- DEV_DBG("PLL PARAM: tx_l0_res_code_lane_tx = 0x%x\n",
- cfg->tx_l0_res_code_lane_tx);
- DEV_DBG("PLL PARAM: tx_l1_res_code_lane_tx = 0x%x\n",
- cfg->tx_l1_res_code_lane_tx);
- DEV_DBG("PLL PARAM: tx_l2_res_code_lane_tx = 0x%x\n",
- cfg->tx_l2_res_code_lane_tx);
- DEV_DBG("PLL PARAM: tx_l3_res_code_lane_tx = 0x%x\n",
- cfg->tx_l3_res_code_lane_tx);
- DEV_DBG("PLL PARAM: com_restrim_ctrl = 0x%x\n", cfg->com_restrim_ctrl);
- DEV_DBG("PLL PARAM: phy_mode = 0x%x\n", cfg->phy_mode);
- rc = 0;
- fail:
- return rc;
- }
- static int hdmi_8996_v3_calculate(u32 pix_clk,
- struct hdmi_8996_phy_pll_reg_cfg *cfg)
- {
- int rc = -EINVAL;
- struct hdmi_8996_v3_post_divider pd;
- u64 fdata, tmds_clk;
- u64 bclk;
- u64 pll_cmp;
- u64 tx_band;
- u64 hsclk;
- u64 dec_start;
- u64 frac_start;
- u64 pll_divisor = 4 * HDMI_REF_CLOCK;
- u64 cpctrl;
- u64 rctrl;
- u64 cctrl;
- u64 integloop_gain;
- u64 vco_freq;
- u64 rem;
- /* FDATA, HSCLK, PIXEL_CLK, TMDS_CLK */
- bclk = ((u64)pix_clk) * HDMI_BIT_CLK_TO_PIX_CLK_RATIO;
- if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD)
- tmds_clk = pix_clk >> 2;
- else
- tmds_clk = pix_clk;
- if (hdmi_8996_v3_get_post_div(&pd, bclk) || pd.vco_ratio <= 0 ||
- pd.vco_freq <= 0)
- goto fail;
- vco_freq = pd.vco_freq;
- fdata = pd.vco_freq;
- do_div(fdata, pd.vco_ratio);
- hsclk = pd.hsclk_divsel;
- dec_start = vco_freq;
- do_div(dec_start, pll_divisor);
- frac_start = vco_freq * (1 << 20);
- rem = do_div(frac_start, pll_divisor);
- frac_start -= dec_start * (1 << 20);
- if (rem > (pll_divisor >> 1))
- frac_start++;
- cpctrl = hdmi_8996_get_cpctrl(frac_start, false);
- rctrl = hdmi_8996_get_rctrl(frac_start, false);
- cctrl = hdmi_8996_get_cctrl(frac_start, false);
- integloop_gain = hdmi_8996_v3_get_integloop_gain(frac_start, bclk,
- false);
- pll_cmp = hdmi_8996_v3_get_pll_cmp(1024, fdata);
- tx_band = pd.tx_band_sel;
- /* Debug dump */
- DEV_DBG("%s: VCO freq: %llu\n", __func__, vco_freq);
- DEV_DBG("%s: fdata: %llu\n", __func__, fdata);
- DEV_DBG("%s: pix_clk: %d\n", __func__, pix_clk);
- DEV_DBG("%s: tmds clk: %llu\n", __func__, tmds_clk);
- DEV_DBG("%s: HSCLK_SEL: %llu\n", __func__, hsclk);
- DEV_DBG("%s: DEC_START: %llu\n", __func__, dec_start);
- DEV_DBG("%s: DIV_FRAC_START: %llu\n", __func__, frac_start);
- DEV_DBG("%s: PLL_CPCTRL: %llu\n", __func__, cpctrl);
- DEV_DBG("%s: PLL_RCTRL: %llu\n", __func__, rctrl);
- DEV_DBG("%s: PLL_CCTRL: %llu\n", __func__, cctrl);
- DEV_DBG("%s: INTEGLOOP_GAIN: %llu\n", __func__, integloop_gain);
- DEV_DBG("%s: TX_BAND: %llu\n", __func__, tx_band);
- DEV_DBG("%s: PLL_CMP: %llu\n", __func__, pll_cmp);
- /* Convert these values to register specific values */
- cfg->tx_l0_tx_band = tx_band + 4;
- cfg->tx_l1_tx_band = tx_band + 4;
- cfg->tx_l2_tx_band = tx_band + 4;
- cfg->tx_l3_tx_band = tx_band + 4;
- if (bclk > HDMI_DIG_FREQ_BIT_CLK_THRESHOLD)
- cfg->com_svs_mode_clk_sel = 1;
- else
- cfg->com_svs_mode_clk_sel = 2;
- cfg->com_hsclk_sel = (0x20 | hsclk);
- cfg->com_pll_cctrl_mode0 = cctrl;
- cfg->com_pll_rctrl_mode0 = rctrl;
- cfg->com_cp_ctrl_mode0 = cpctrl;
- cfg->com_dec_start_mode0 = dec_start;
- cfg->com_div_frac_start1_mode0 = (frac_start & 0xFF);
- cfg->com_div_frac_start2_mode0 = ((frac_start & 0xFF00) >> 8);
- cfg->com_div_frac_start3_mode0 = ((frac_start & 0xF0000) >> 16);
- cfg->com_integloop_gain0_mode0 = (integloop_gain & 0xFF);
- cfg->com_integloop_gain1_mode0 = ((integloop_gain & 0xF00) >> 8);
- cfg->com_lock_cmp1_mode0 = (pll_cmp & 0xFF);
- cfg->com_lock_cmp2_mode0 = ((pll_cmp & 0xFF00) >> 8);
- cfg->com_lock_cmp3_mode0 = ((pll_cmp & 0x30000) >> 16);
- cfg->com_lock_cmp_en = 0x04;
- cfg->com_core_clk_en = 0x2C;
- cfg->com_coreclk_div = HDMI_CORECLK_DIV;
- cfg->phy_mode = (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) ? 0x10 : 0x0;
- cfg->com_vco_tune_ctrl = 0x0;
- cfg->tx_l0_lane_mode = 0x43;
- cfg->tx_l2_lane_mode = 0x43;
- if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) {
- cfg->tx_l0_tx_drv_lvl = 0x25;
- cfg->tx_l0_tx_emp_post1_lvl = 0x23;
- cfg->tx_l1_tx_drv_lvl = 0x25;
- cfg->tx_l1_tx_emp_post1_lvl = 0x23;
- cfg->tx_l2_tx_drv_lvl = 0x25;
- cfg->tx_l2_tx_emp_post1_lvl = 0x23;
- cfg->tx_l3_tx_drv_lvl = 0x22;
- cfg->tx_l3_tx_emp_post1_lvl = 0x27;
- cfg->tx_l0_vmode_ctrl1 = 0x00;
- cfg->tx_l0_vmode_ctrl2 = 0x0D;
- cfg->tx_l1_vmode_ctrl1 = 0x00;
- cfg->tx_l1_vmode_ctrl2 = 0x0D;
- cfg->tx_l2_vmode_ctrl1 = 0x00;
- cfg->tx_l2_vmode_ctrl2 = 0x0D;
- cfg->tx_l3_vmode_ctrl1 = 0x00;
- cfg->tx_l3_vmode_ctrl2 = 0x00;
- } else if (bclk > HDMI_MID_FREQ_BIT_CLK_THRESHOLD) {
- cfg->tx_l0_tx_drv_lvl = 0x25;
- cfg->tx_l0_tx_emp_post1_lvl = 0x23;
- cfg->tx_l1_tx_drv_lvl = 0x25;
- cfg->tx_l1_tx_emp_post1_lvl = 0x23;
- cfg->tx_l2_tx_drv_lvl = 0x25;
- cfg->tx_l2_tx_emp_post1_lvl = 0x23;
- cfg->tx_l3_tx_drv_lvl = 0x25;
- cfg->tx_l3_tx_emp_post1_lvl = 0x23;
- cfg->tx_l0_vmode_ctrl1 = 0x00;
- cfg->tx_l0_vmode_ctrl2 = 0x0D;
- cfg->tx_l1_vmode_ctrl1 = 0x00;
- cfg->tx_l1_vmode_ctrl2 = 0x0D;
- cfg->tx_l2_vmode_ctrl1 = 0x00;
- cfg->tx_l2_vmode_ctrl2 = 0x0D;
- cfg->tx_l3_vmode_ctrl1 = 0x00;
- cfg->tx_l3_vmode_ctrl2 = 0x00;
- } else {
- cfg->tx_l0_tx_drv_lvl = 0x20;
- cfg->tx_l0_tx_emp_post1_lvl = 0x20;
- cfg->tx_l1_tx_drv_lvl = 0x20;
- cfg->tx_l1_tx_emp_post1_lvl = 0x20;
- cfg->tx_l2_tx_drv_lvl = 0x20;
- cfg->tx_l2_tx_emp_post1_lvl = 0x20;
- cfg->tx_l3_tx_drv_lvl = 0x20;
- cfg->tx_l3_tx_emp_post1_lvl = 0x20;
- cfg->tx_l0_vmode_ctrl1 = 0x00;
- cfg->tx_l0_vmode_ctrl2 = 0x0E;
- cfg->tx_l1_vmode_ctrl1 = 0x00;
- cfg->tx_l1_vmode_ctrl2 = 0x0E;
- cfg->tx_l2_vmode_ctrl1 = 0x00;
- cfg->tx_l2_vmode_ctrl2 = 0x0E;
- cfg->tx_l3_vmode_ctrl1 = 0x00;
- cfg->tx_l3_vmode_ctrl2 = 0x0E;
- }
- DEV_DBG("HDMI 8996 PLL: PLL Settings\n");
- DEV_DBG("PLL PARAM: tx_l0_tx_band = 0x%x\n", cfg->tx_l0_tx_band);
- DEV_DBG("PLL PARAM: tx_l1_tx_band = 0x%x\n", cfg->tx_l1_tx_band);
- DEV_DBG("PLL PARAM: tx_l2_tx_band = 0x%x\n", cfg->tx_l2_tx_band);
- DEV_DBG("PLL PARAM: tx_l3_tx_band = 0x%x\n", cfg->tx_l3_tx_band);
- DEV_DBG("PLL PARAM: com_svs_mode_clk_sel = 0x%x\n",
- cfg->com_svs_mode_clk_sel);
- DEV_DBG("PLL PARAM: com_hsclk_sel = 0x%x\n", cfg->com_hsclk_sel);
- DEV_DBG("PLL PARAM: com_lock_cmp_en = 0x%x\n", cfg->com_lock_cmp_en);
- DEV_DBG("PLL PARAM: com_pll_cctrl_mode0 = 0x%x\n",
- cfg->com_pll_cctrl_mode0);
- DEV_DBG("PLL PARAM: com_pll_rctrl_mode0 = 0x%x\n",
- cfg->com_pll_rctrl_mode0);
- DEV_DBG("PLL PARAM: com_cp_ctrl_mode0 = 0x%x\n",
- cfg->com_cp_ctrl_mode0);
- DEV_DBG("PLL PARAM: com_dec_start_mode0 = 0x%x\n",
- cfg->com_dec_start_mode0);
- DEV_DBG("PLL PARAM: com_div_frac_start1_mode0 = 0x%x\n",
- cfg->com_div_frac_start1_mode0);
- DEV_DBG("PLL PARAM: com_div_frac_start2_mode0 = 0x%x\n",
- cfg->com_div_frac_start2_mode0);
- DEV_DBG("PLL PARAM: com_div_frac_start3_mode0 = 0x%x\n",
- cfg->com_div_frac_start3_mode0);
- DEV_DBG("PLL PARAM: com_integloop_gain0_mode0 = 0x%x\n",
- cfg->com_integloop_gain0_mode0);
- DEV_DBG("PLL PARAM: com_integloop_gain1_mode0 = 0x%x\n",
- cfg->com_integloop_gain1_mode0);
- DEV_DBG("PLL PARAM: com_lock_cmp1_mode0 = 0x%x\n",
- cfg->com_lock_cmp1_mode0);
- DEV_DBG("PLL PARAM: com_lock_cmp2_mode0 = 0x%x\n",
- cfg->com_lock_cmp2_mode0);
- DEV_DBG("PLL PARAM: com_lock_cmp3_mode0 = 0x%x\n",
- cfg->com_lock_cmp3_mode0);
- DEV_DBG("PLL PARAM: com_core_clk_en = 0x%x\n", cfg->com_core_clk_en);
- DEV_DBG("PLL PARAM: com_coreclk_div = 0x%x\n", cfg->com_coreclk_div);
- DEV_DBG("PLL PARAM: phy_mode = 0x%x\n", cfg->phy_mode);
- DEV_DBG("PLL PARAM: tx_l0_lane_mode = 0x%x\n", cfg->tx_l0_lane_mode);
- DEV_DBG("PLL PARAM: tx_l2_lane_mode = 0x%x\n", cfg->tx_l2_lane_mode);
- DEV_DBG("PLL PARAM: l0_tx_drv_lvl = 0x%x\n", cfg->tx_l0_tx_drv_lvl);
- DEV_DBG("PLL PARAM: l0_tx_emp_post1_lvl = 0x%x\n",
- cfg->tx_l0_tx_emp_post1_lvl);
- DEV_DBG("PLL PARAM: l1_tx_drv_lvl = 0x%x\n", cfg->tx_l1_tx_drv_lvl);
- DEV_DBG("PLL PARAM: l1_tx_emp_post1_lvl = 0x%x\n",
- cfg->tx_l1_tx_emp_post1_lvl);
- DEV_DBG("PLL PARAM: l2_tx_drv_lvl = 0x%x\n", cfg->tx_l2_tx_drv_lvl);
- DEV_DBG("PLL PARAM: l2_tx_emp_post1_lvl = 0x%x\n",
- cfg->tx_l2_tx_emp_post1_lvl);
- DEV_DBG("PLL PARAM: l3_tx_drv_lvl = 0x%x\n", cfg->tx_l3_tx_drv_lvl);
- DEV_DBG("PLL PARAM: l3_tx_emp_post1_lvl = 0x%x\n",
- cfg->tx_l3_tx_emp_post1_lvl);
- DEV_DBG("PLL PARAM: l0_vmode_ctrl1 = 0x%x\n", cfg->tx_l0_vmode_ctrl1);
- DEV_DBG("PLL PARAM: l0_vmode_ctrl2 = 0x%x\n", cfg->tx_l0_vmode_ctrl2);
- DEV_DBG("PLL PARAM: l1_vmode_ctrl1 = 0x%x\n", cfg->tx_l1_vmode_ctrl1);
- DEV_DBG("PLL PARAM: l1_vmode_ctrl2 = 0x%x\n", cfg->tx_l1_vmode_ctrl2);
- DEV_DBG("PLL PARAM: l2_vmode_ctrl1 = 0x%x\n", cfg->tx_l2_vmode_ctrl1);
- DEV_DBG("PLL PARAM: l2_vmode_ctrl2 = 0x%x\n", cfg->tx_l2_vmode_ctrl2);
- DEV_DBG("PLL PARAM: l3_vmode_ctrl1 = 0x%x\n", cfg->tx_l3_vmode_ctrl1);
- DEV_DBG("PLL PARAM: l3_vmode_ctrl2 = 0x%x\n", cfg->tx_l3_vmode_ctrl2);
- rc = 0;
- fail:
- return rc;
- }
- static int hdmi_8996_calculate(u32 pix_clk,
- struct hdmi_8996_phy_pll_reg_cfg *cfg, u32 ver)
- {
- switch (ver) {
- case HDMI_VERSION_8996_V3:
- case HDMI_VERSION_8996_V3_1_8:
- return hdmi_8996_v3_calculate(pix_clk, cfg);
- case HDMI_VERSION_8996_V2:
- return hdmi_8996_v2_calculate(pix_clk, cfg);
- default:
- return hdmi_8996_v1_calculate(pix_clk, cfg);
- }
- }
- static int hdmi_8996_phy_pll_set_clk_rate(struct clk *c, u32 tmds_clk, u32 ver)
- {
- int rc = 0;
- struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c);
- struct mdss_pll_resources *io = vco->priv;
- struct hdmi_8996_phy_pll_reg_cfg cfg = {0};
- rc = hdmi_8996_calculate(tmds_clk, &cfg, ver);
- if (rc) {
- DEV_ERR("%s: PLL calculation failed\n", __func__);
- return rc;
- }
- /* Initially shut down PHY */
- DEV_DBG("%s: Disabling PHY\n", __func__);
- MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_PD_CTL, 0x0);
- udelay(500);
- /* Power up sequence */
- switch (ver) {
- case HDMI_VERSION_8996_V2:
- case HDMI_VERSION_8996_V3:
- case HDMI_VERSION_8996_V3_1_8:
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_BG_CTRL, 0x04);
- break;
- }
- MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_PD_CTL, 0x1);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_RESETSM_CNTRL, 0x20);
- MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_TX0_TX1_LANE_CTL, 0x0F);
- MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_TX2_TX3_LANE_CTL, 0x0F);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
- QSERDES_TX_L0_CLKBUF_ENABLE, 0x03);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
- QSERDES_TX_L0_CLKBUF_ENABLE, 0x03);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
- QSERDES_TX_L0_CLKBUF_ENABLE, 0x03);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
- QSERDES_TX_L0_CLKBUF_ENABLE, 0x03);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
- QSERDES_TX_L0_LANE_MODE, cfg.tx_l0_lane_mode);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
- QSERDES_TX_L0_LANE_MODE, cfg.tx_l2_lane_mode);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
- QSERDES_TX_L0_TX_BAND, cfg.tx_l0_tx_band);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
- QSERDES_TX_L0_TX_BAND, cfg.tx_l1_tx_band);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
- QSERDES_TX_L0_TX_BAND, cfg.tx_l2_tx_band);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
- QSERDES_TX_L0_TX_BAND, cfg.tx_l3_tx_band);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
- QSERDES_TX_L0_RESET_TSYNC_EN, 0x03);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
- QSERDES_TX_L0_RESET_TSYNC_EN, 0x03);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
- QSERDES_TX_L0_RESET_TSYNC_EN, 0x03);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
- QSERDES_TX_L0_RESET_TSYNC_EN, 0x03);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SYSCLK_BUF_ENABLE, 0x1E);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x07);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SYSCLK_EN_SEL, 0x37);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SYS_CLK_CTRL, 0x02);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CLK_ENABLE1, 0x0E);
- if (ver == HDMI_VERSION_8996_V1)
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_BG_CTRL, 0x06);
- /* Bypass VCO calibration */
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SVS_MODE_CLK_SEL,
- cfg.com_svs_mode_clk_sel);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_BG_TRIM, 0x0F);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_PLL_IVCO, 0x0F);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_VCO_TUNE_CTRL,
- cfg.com_vco_tune_ctrl);
- switch (ver) {
- case HDMI_VERSION_8996_V1:
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SVS_MODE_CLK_SEL,
- cfg.com_svs_mode_clk_sel);
- break;
- default:
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_BG_CTRL, 0x06);
- }
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CLK_SELECT, 0x30);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_HSCLK_SEL,
- cfg.com_hsclk_sel);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_LOCK_CMP_EN,
- cfg.com_lock_cmp_en);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_PLL_CCTRL_MODE0,
- cfg.com_pll_cctrl_mode0);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_PLL_RCTRL_MODE0,
- cfg.com_pll_rctrl_mode0);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CP_CTRL_MODE0,
- cfg.com_cp_ctrl_mode0);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_DEC_START_MODE0,
- cfg.com_dec_start_mode0);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_DIV_FRAC_START1_MODE0,
- cfg.com_div_frac_start1_mode0);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_DIV_FRAC_START2_MODE0,
- cfg.com_div_frac_start2_mode0);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_DIV_FRAC_START3_MODE0,
- cfg.com_div_frac_start3_mode0);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_INTEGLOOP_GAIN0_MODE0,
- cfg.com_integloop_gain0_mode0);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_INTEGLOOP_GAIN1_MODE0,
- cfg.com_integloop_gain1_mode0);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_LOCK_CMP1_MODE0,
- cfg.com_lock_cmp1_mode0);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_LOCK_CMP2_MODE0,
- cfg.com_lock_cmp2_mode0);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_LOCK_CMP3_MODE0,
- cfg.com_lock_cmp3_mode0);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_VCO_TUNE_MAP, 0x00);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CORE_CLK_EN,
- cfg.com_core_clk_en);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CORECLK_DIV,
- cfg.com_coreclk_div);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CMN_CONFIG, 0x02);
- if (ver == HDMI_VERSION_8996_V3 || ver == HDMI_VERSION_8996_V3_1_8)
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_RESCODE_DIV_NUM, 0x15);
- /* TX lanes setup (TX 0/1/2/3) */
- if (ver == HDMI_VERSION_8996_V3_1_8) {
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
- QSERDES_TX_L0_TX_DRV_LVL,
- 0x00000023);
- } else {
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
- QSERDES_TX_L0_TX_DRV_LVL,
- cfg.tx_l0_tx_drv_lvl);
- }
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
- QSERDES_TX_L0_TX_EMP_POST1_LVL,
- cfg.tx_l0_tx_emp_post1_lvl);
- if (ver == HDMI_VERSION_8996_V3_1_8) {
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
- QSERDES_TX_L0_TX_DRV_LVL,
- 0x00000023);
- } else {
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
- QSERDES_TX_L0_TX_DRV_LVL,
- cfg.tx_l1_tx_drv_lvl);
- }
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
- QSERDES_TX_L0_TX_EMP_POST1_LVL,
- cfg.tx_l1_tx_emp_post1_lvl);
- if (ver == HDMI_VERSION_8996_V3_1_8) {
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
- QSERDES_TX_L0_TX_DRV_LVL,
- 0x00000023);
- } else {
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
- QSERDES_TX_L0_TX_DRV_LVL,
- cfg.tx_l2_tx_drv_lvl);
- }
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
- QSERDES_TX_L0_TX_EMP_POST1_LVL,
- cfg.tx_l2_tx_emp_post1_lvl);
- if (ver == HDMI_VERSION_8996_V3_1_8) {
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
- QSERDES_TX_L0_TX_DRV_LVL,
- 0x00000020);
- } else {
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
- QSERDES_TX_L0_TX_DRV_LVL,
- cfg.tx_l3_tx_drv_lvl);
- }
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
- QSERDES_TX_L0_TX_EMP_POST1_LVL,
- cfg.tx_l3_tx_emp_post1_lvl);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
- QSERDES_TX_L0_VMODE_CTRL1,
- cfg.tx_l0_vmode_ctrl1);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
- QSERDES_TX_L0_VMODE_CTRL2,
- cfg.tx_l0_vmode_ctrl2);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
- QSERDES_TX_L0_VMODE_CTRL1,
- cfg.tx_l1_vmode_ctrl1);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
- QSERDES_TX_L0_VMODE_CTRL2,
- cfg.tx_l1_vmode_ctrl2);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
- QSERDES_TX_L0_VMODE_CTRL1,
- cfg.tx_l2_vmode_ctrl1);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
- QSERDES_TX_L0_VMODE_CTRL2,
- cfg.tx_l2_vmode_ctrl2);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
- QSERDES_TX_L0_VMODE_CTRL1,
- cfg.tx_l3_vmode_ctrl1);
- if (ver == HDMI_VERSION_8996_V3_1_8) {
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
- QSERDES_TX_L0_VMODE_CTRL2,
- 0x0000000D);
- } else {
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
- QSERDES_TX_L0_VMODE_CTRL2,
- cfg.tx_l3_vmode_ctrl2);
- }
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
- QSERDES_TX_L0_TX_DRV_LVL_OFFSET, 0x00);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
- QSERDES_TX_L0_TX_DRV_LVL_OFFSET, 0x00);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
- QSERDES_TX_L0_TX_DRV_LVL_OFFSET, 0x00);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
- QSERDES_TX_L0_TX_DRV_LVL_OFFSET, 0x00);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
- QSERDES_TX_L0_RES_CODE_LANE_OFFSET, 0x00);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
- QSERDES_TX_L0_RES_CODE_LANE_OFFSET, 0x00);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
- QSERDES_TX_L0_RES_CODE_LANE_OFFSET, 0x00);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
- QSERDES_TX_L0_RES_CODE_LANE_OFFSET, 0x00);
- if (ver < HDMI_VERSION_8996_V3) {
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
- QSERDES_TX_L0_RES_CODE_LANE_TX,
- cfg.tx_l0_res_code_lane_tx);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
- QSERDES_TX_L0_RES_CODE_LANE_TX,
- cfg.tx_l1_res_code_lane_tx);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
- QSERDES_TX_L0_RES_CODE_LANE_TX,
- cfg.tx_l2_res_code_lane_tx);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
- QSERDES_TX_L0_RES_CODE_LANE_TX,
- cfg.tx_l3_res_code_lane_tx);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_RESTRIM_CTRL,
- cfg.com_restrim_ctrl);
- MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_TXCAL_CFG0, 0x00);
- MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_TXCAL_CFG1, 0x05);
- }
- MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_MODE, cfg.phy_mode);
- MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_PD_CTL, 0x1F);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
- QSERDES_TX_L0_TRAN_DRVR_EMP_EN, 0x03);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
- QSERDES_TX_L0_TRAN_DRVR_EMP_EN, 0x03);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
- QSERDES_TX_L0_TRAN_DRVR_EMP_EN, 0x03);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
- QSERDES_TX_L0_TRAN_DRVR_EMP_EN, 0x03);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
- QSERDES_TX_L0_PARRATE_REC_DETECT_IDLE_EN, 0x40);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
- QSERDES_TX_L0_PARRATE_REC_DETECT_IDLE_EN, 0x40);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
- QSERDES_TX_L0_PARRATE_REC_DETECT_IDLE_EN, 0x40);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
- QSERDES_TX_L0_PARRATE_REC_DETECT_IDLE_EN, 0x40);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
- QSERDES_TX_L0_HP_PD_ENABLES, 0x0C);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
- QSERDES_TX_L0_HP_PD_ENABLES, 0x0C);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
- QSERDES_TX_L0_HP_PD_ENABLES, 0x0C);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
- QSERDES_TX_L0_HP_PD_ENABLES, 0x03);
- if (ver == HDMI_VERSION_8996_V2) {
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_ATB_SEL1, 0x01);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_ATB_SEL2, 0x01);
- }
- /*
- * Ensure that vco configuration gets flushed to hardware before
- * enabling the PLL
- */
- wmb();
- return 0;
- }
- static int hdmi_8996_phy_ready_status(struct mdss_pll_resources *io)
- {
- u32 status = 0;
- int phy_ready = 0;
- int rc;
- u32 read_count = 0;
- rc = mdss_pll_resource_enable(io, true);
- if (rc) {
- DEV_ERR("%s: pll resource can't be enabled\n", __func__);
- return rc;
- }
- DEV_DBG("%s: Waiting for PHY Ready\n", __func__);
- /* Poll for PHY read status */
- while (read_count < HDMI_PLL_POLL_MAX_READS) {
- status = MDSS_PLL_REG_R(io->phy_base, HDMI_PHY_STATUS);
- if ((status & BIT(0)) == 1) {
- phy_ready = 1;
- DEV_DBG("%s: PHY READY\n", __func__);
- break;
- }
- udelay(HDMI_PLL_POLL_TIMEOUT_US);
- read_count++;
- }
- if (read_count == HDMI_PLL_POLL_MAX_READS) {
- phy_ready = 0;
- DEV_DBG("%s: PHY READY TIMEOUT\n", __func__);
- }
- mdss_pll_resource_enable(io, false);
- return phy_ready;
- }
- static int hdmi_8996_pll_lock_status(struct mdss_pll_resources *io)
- {
- u32 status;
- int pll_locked = 0;
- int rc;
- u32 read_count = 0;
- rc = mdss_pll_resource_enable(io, true);
- if (rc) {
- DEV_ERR("%s: pll resource can't be enabled\n", __func__);
- return rc;
- }
- DEV_DBG("%s: Waiting for PLL lock\n", __func__);
- while (read_count < HDMI_PLL_POLL_MAX_READS) {
- status = MDSS_PLL_REG_R(io->pll_base,
- QSERDES_COM_C_READY_STATUS);
- if ((status & BIT(0)) == 1) {
- pll_locked = 1;
- DEV_DBG("%s: C READY\n", __func__);
- break;
- }
- udelay(HDMI_PLL_POLL_TIMEOUT_US);
- read_count++;
- }
- if (read_count == HDMI_PLL_POLL_MAX_READS) {
- pll_locked = 0;
- DEV_DBG("%s: C READY TIMEOUT\n", __func__);
- }
- mdss_pll_resource_enable(io, false);
- return pll_locked;
- }
- static int hdmi_8996_v1_perform_sw_calibration(struct clk *c)
- {
- int rc = 0;
- struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c);
- struct mdss_pll_resources *io = vco->priv;
- u32 max_code = 0x190;
- u32 min_code = 0x0;
- u32 max_cnt = 0;
- u32 min_cnt = 0;
- u32 expected_counter_value = 0;
- u32 step = 0;
- u32 dbus_all = 0;
- u32 dbus_sel = 0;
- u32 vco_code = 0;
- u32 val = 0;
- vco_code = 0xC8;
- DEV_DBG("%s: Starting SW calibration with vco_code = %d\n", __func__,
- vco_code);
- expected_counter_value =
- (MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_LOCK_CMP3_MODE0) << 16) |
- (MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_LOCK_CMP2_MODE0) << 8) |
- (MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_LOCK_CMP1_MODE0));
- DEV_DBG("%s: expected_counter_value = %d\n", __func__,
- expected_counter_value);
- val = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_CMN_MISC1);
- val |= BIT(4);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CMN_MISC1, val);
- val = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_CMN_MISC1);
- val |= BIT(3);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CMN_MISC1, val);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_DEBUG_BUS_SEL, 0x4);
- val = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_LOCK_CMP_CFG);
- val |= BIT(1);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_LOCK_CMP_CFG, val);
- udelay(60);
- while (1) {
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_VCO_TUNE1_MODE0,
- vco_code & 0xFF);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_VCO_TUNE2_MODE0,
- (vco_code >> 8) & 0x3);
- udelay(20);
- val = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_LOCK_CMP_CFG);
- val &= ~BIT(1);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_LOCK_CMP_CFG, val);
- udelay(60);
- val = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_LOCK_CMP_CFG);
- val |= BIT(1);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_LOCK_CMP_CFG, val);
- udelay(60);
- dbus_all =
- (MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_DEBUG_BUS3) << 24) |
- (MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_DEBUG_BUS2) << 16) |
- (MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_DEBUG_BUS1) << 8) |
- (MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_DEBUG_BUS0));
- dbus_sel = (dbus_all >> 9) & 0x3FFFF;
- DEV_DBG("%s: loop[%d], dbus_all = 0x%x, dbus_sel = 0x%x\n",
- __func__, step, dbus_all, dbus_sel);
- if (dbus_sel == 0)
- DEV_ERR("%s: CHECK HDMI REF CLK\n", __func__);
- if (dbus_sel == expected_counter_value) {
- max_code = vco_code;
- max_cnt = dbus_sel;
- min_code = vco_code;
- min_cnt = dbus_sel;
- } else if (dbus_sel == 0) {
- max_code = vco_code;
- max_cnt = dbus_sel;
- vco_code = (max_code + min_code)/2;
- } else if (dbus_sel > expected_counter_value) {
- min_code = vco_code;
- min_cnt = dbus_sel;
- vco_code = (max_code + min_code)/2;
- } else if (dbus_sel < expected_counter_value) {
- max_code = vco_code;
- max_cnt = dbus_sel;
- vco_code = (max_code + min_code)/2;
- }
- step++;
- if ((vco_code == 0) || (vco_code == 0x3FF) || (step > 0x3FF)) {
- DEV_ERR("%s: VCO tune code search failed\n", __func__);
- rc = -ENOTSUPP;
- break;
- }
- if ((max_code - min_code) <= 1) {
- if ((max_code - min_code) == 1) {
- if (abs((int)(max_cnt - expected_counter_value))
- < abs((int)(min_cnt - expected_counter_value
- ))) {
- vco_code = max_code;
- } else {
- vco_code = min_code;
- }
- }
- break;
- }
- DEV_DBG("%s: loop[%d], new vco_code = %d\n", __func__, step,
- vco_code);
- }
- DEV_DBG("%s: CALIB done. vco_code = %d\n", __func__, vco_code);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_VCO_TUNE1_MODE0,
- vco_code & 0xFF);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_VCO_TUNE2_MODE0,
- (vco_code >> 8) & 0x3);
- val = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_LOCK_CMP_CFG);
- val &= ~BIT(1);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_LOCK_CMP_CFG, val);
- val = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_CMN_MISC1);
- val |= BIT(4);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CMN_MISC1, val);
- val = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_CMN_MISC1);
- val &= ~BIT(3);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_CMN_MISC1, val);
- return rc;
- }
- static int hdmi_8996_v2_perform_sw_calibration(struct clk *c)
- {
- struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c);
- struct mdss_pll_resources *io = vco->priv;
- u32 vco_code1, vco_code2, integral_loop, ready_poll;
- u32 read_count = 0;
- while (read_count < (HDMI_PLL_POLL_MAX_READS << 1)) {
- ready_poll = MDSS_PLL_REG_R(io->pll_base,
- QSERDES_COM_C_READY_STATUS);
- if ((ready_poll & BIT(0)) == 1) {
- ready_poll = 1;
- DEV_DBG("%s: C READY\n", __func__);
- break;
- }
- udelay(HDMI_PLL_POLL_TIMEOUT_US);
- read_count++;
- }
- if (read_count == (HDMI_PLL_POLL_MAX_READS << 1)) {
- ready_poll = 0;
- DEV_DBG("%s: C READY TIMEOUT, TRYING SW CALIBRATION\n",
- __func__);
- }
- vco_code1 = MDSS_PLL_REG_R(io->pll_base,
- QSERDES_COM_PLLCAL_CODE1_STATUS);
- vco_code2 = MDSS_PLL_REG_R(io->pll_base,
- QSERDES_COM_PLLCAL_CODE2_STATUS);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_DEBUG_BUS_SEL, 0x5);
- integral_loop = MDSS_PLL_REG_R(io->pll_base,
- QSERDES_COM_DEBUG_BUS0);
- if (((ready_poll & 0x1) == 0) || (((ready_poll & 1) == 1) &&
- (vco_code1 == 0xFF) && ((vco_code2 & 0x3) == 0x1) &&
- (integral_loop > 0xC0))) {
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_ATB_SEL1, 0x04);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_ATB_SEL2, 0x00);
- MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x17);
- udelay(100);
- MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x11);
- udelay(100);
- MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x19);
- }
- return 0;
- }
- static int hdmi_8996_perform_sw_calibration(struct clk *c, u32 ver)
- {
- switch (ver) {
- case HDMI_VERSION_8996_V1:
- return hdmi_8996_v1_perform_sw_calibration(c);
- case HDMI_VERSION_8996_V2:
- return hdmi_8996_v2_perform_sw_calibration(c);
- }
- return 0;
- }
- static int hdmi_8996_vco_enable(struct clk *c, u32 ver)
- {
- int rc = 0;
- struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c);
- struct mdss_pll_resources *io = vco->priv;
- MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x1);
- udelay(100);
- MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x19);
- udelay(100);
- rc = hdmi_8996_perform_sw_calibration(c, ver);
- if (rc) {
- DEV_ERR("%s: software calibration failed\n", __func__);
- return rc;
- }
- rc = hdmi_8996_pll_lock_status(io);
- if (!rc) {
- DEV_ERR("%s: PLL not locked\n", __func__);
- return rc;
- }
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
- QSERDES_TX_L0_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN,
- 0x6F);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L1_BASE_OFFSET,
- QSERDES_TX_L0_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN,
- 0x6F);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L2_BASE_OFFSET,
- QSERDES_TX_L0_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN,
- 0x6F);
- MDSS_PLL_REG_W(io->pll_base + HDMI_TX_L3_BASE_OFFSET,
- QSERDES_TX_L0_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN,
- 0x6F);
- /* Disable SSC */
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SSC_PER1, 0x0);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SSC_PER2, 0x0);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SSC_STEP_SIZE1, 0x0);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SSC_STEP_SIZE2, 0x0);
- MDSS_PLL_REG_W(io->pll_base, QSERDES_COM_SSC_EN_CENTER, 0x2);
- rc = hdmi_8996_phy_ready_status(io);
- if (!rc) {
- DEV_ERR("%s: PHY not READY\n", __func__);
- return rc;
- }
- /* Restart the retiming buffer */
- MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x18);
- udelay(1);
- MDSS_PLL_REG_W(io->phy_base, HDMI_PHY_CFG, 0x19);
- io->pll_on = true;
- return 0;
- }
- static int hdmi_8996_v1_vco_enable(struct clk *c)
- {
- return hdmi_8996_vco_enable(c, HDMI_VERSION_8996_V1);
- }
- static int hdmi_8996_v2_vco_enable(struct clk *c)
- {
- return hdmi_8996_vco_enable(c, HDMI_VERSION_8996_V2);
- }
- static int hdmi_8996_v3_vco_enable(struct clk *c)
- {
- return hdmi_8996_vco_enable(c, HDMI_VERSION_8996_V3);
- }
- static int hdmi_8996_v3_1p8_vco_enable(struct clk *c)
- {
- return hdmi_8996_vco_enable(c, HDMI_VERSION_8996_V3_1_8);
- }
- static int hdmi_8996_vco_get_lock_range(struct clk *c, unsigned long pixel_clk)
- {
- u32 rng = 64, cmp_cnt = 1024;
- u32 coreclk_div = 5, clks_pll_divsel = 2;
- u32 vco_freq, vco_ratio, ppm_range;
- u64 bclk;
- struct hdmi_8996_v3_post_divider pd;
- bclk = ((u64)pixel_clk) * HDMI_BIT_CLK_TO_PIX_CLK_RATIO;
- DEV_DBG("%s: rate=%ld\n", __func__, pixel_clk);
- if (hdmi_8996_v3_get_post_div(&pd, bclk) ||
- pd.vco_ratio <= 0 || pd.vco_freq <= 0) {
- DEV_ERR("%s: couldn't get post div\n", __func__);
- return -EINVAL;
- }
- do_div(pd.vco_freq, HDMI_KHZ_TO_HZ * HDMI_KHZ_TO_HZ);
- vco_freq = (u32) pd.vco_freq;
- vco_ratio = (u32) pd.vco_ratio;
- DEV_DBG("%s: freq %d, ratio %d\n", __func__,
- vco_freq, vco_ratio);
- ppm_range = (rng * HDMI_REF_CLOCK) / cmp_cnt;
- ppm_range /= vco_freq / vco_ratio;
- ppm_range *= coreclk_div * clks_pll_divsel;
- DEV_DBG("%s: ppm range: %d\n", __func__, ppm_range);
- return ppm_range;
- }
- static int hdmi_8996_vco_rate_atomic_update(struct clk *c,
- unsigned long rate, u32 ver)
- {
- struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c);
- struct mdss_pll_resources *io = vco->priv;
- void __iomem *pll;
- struct hdmi_8996_phy_pll_reg_cfg cfg = {0};
- int rc = 0;
- rc = hdmi_8996_calculate(rate, &cfg, ver);
- if (rc) {
- DEV_ERR("%s: PLL calculation failed\n", __func__);
- goto end;
- }
- pll = io->pll_base;
- MDSS_PLL_REG_W(pll, QSERDES_COM_DEC_START_MODE0,
- cfg.com_dec_start_mode0);
- MDSS_PLL_REG_W(pll, QSERDES_COM_DIV_FRAC_START1_MODE0,
- cfg.com_div_frac_start1_mode0);
- MDSS_PLL_REG_W(pll, QSERDES_COM_DIV_FRAC_START2_MODE0,
- cfg.com_div_frac_start2_mode0);
- MDSS_PLL_REG_W(pll, QSERDES_COM_DIV_FRAC_START3_MODE0,
- cfg.com_div_frac_start3_mode0);
- MDSS_PLL_REG_W(pll, QSERDES_COM_FREQ_UPDATE, 0x01);
- MDSS_PLL_REG_W(pll, QSERDES_COM_FREQ_UPDATE, 0x00);
- DEV_DBG("%s: updated to rate %ld\n", __func__, rate);
- end:
- return rc;
- }
- static int hdmi_8996_vco_set_rate(struct clk *c, unsigned long rate, u32 ver)
- {
- struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c);
- struct mdss_pll_resources *io = vco->priv;
- unsigned int set_power_dwn = 0;
- bool atomic_update = false;
- int rc, pll_lock_range;
- rc = mdss_pll_resource_enable(io, true);
- if (rc) {
- DEV_ERR("pll resource can't be enabled\n");
- return rc;
- }
- DEV_DBG("%s: rate %ld\n", __func__, rate);
- if (MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_C_READY_STATUS) & BIT(0) &&
- MDSS_PLL_REG_R(io->phy_base, HDMI_PHY_STATUS) & BIT(0)) {
- pll_lock_range = hdmi_8996_vco_get_lock_range(c, vco->rate);
- if (pll_lock_range > 0 && vco->rate) {
- u32 range_limit;
- range_limit = vco->rate *
- (pll_lock_range / HDMI_KHZ_TO_HZ);
- range_limit /= HDMI_KHZ_TO_HZ;
- DEV_DBG("%s: range limit %d\n", __func__, range_limit);
- if (abs(rate - vco->rate) < range_limit)
- atomic_update = true;
- }
- }
- if (io->pll_on && !atomic_update)
- set_power_dwn = 1;
- if (atomic_update) {
- hdmi_8996_vco_rate_atomic_update(c, rate, ver);
- } else {
- rc = hdmi_8996_phy_pll_set_clk_rate(c, rate, ver);
- if (rc)
- DEV_ERR("%s: Failed to set clk rate\n", __func__);
- }
- mdss_pll_resource_enable(io, false);
- if (set_power_dwn)
- hdmi_8996_vco_enable(c, ver);
- vco->rate = rate;
- vco->rate_set = true;
- return 0;
- }
- static int hdmi_8996_v1_vco_set_rate(struct clk *c, unsigned long rate)
- {
- return hdmi_8996_vco_set_rate(c, rate, HDMI_VERSION_8996_V1);
- }
- static int hdmi_8996_v2_vco_set_rate(struct clk *c, unsigned long rate)
- {
- return hdmi_8996_vco_set_rate(c, rate, HDMI_VERSION_8996_V2);
- }
- static int hdmi_8996_v3_vco_set_rate(struct clk *c, unsigned long rate)
- {
- return hdmi_8996_vco_set_rate(c, rate, HDMI_VERSION_8996_V3);
- }
- static int hdmi_8996_v3_1p8_vco_set_rate(struct clk *c, unsigned long rate)
- {
- return hdmi_8996_vco_set_rate(c, rate, HDMI_VERSION_8996_V3_1_8);
- }
- static unsigned long hdmi_get_hsclk_sel_divisor(unsigned long hsclk_sel)
- {
- unsigned long divisor;
- switch (hsclk_sel) {
- case 0:
- divisor = 2;
- break;
- case 1:
- divisor = 6;
- break;
- case 2:
- divisor = 10;
- break;
- case 3:
- divisor = 14;
- break;
- case 4:
- divisor = 3;
- break;
- case 5:
- divisor = 9;
- break;
- case 6:
- case 13:
- divisor = 15;
- break;
- case 7:
- divisor = 21;
- break;
- case 8:
- divisor = 4;
- break;
- case 9:
- divisor = 12;
- break;
- case 10:
- divisor = 20;
- break;
- case 11:
- divisor = 28;
- break;
- case 12:
- divisor = 5;
- break;
- case 14:
- divisor = 25;
- break;
- case 15:
- divisor = 35;
- break;
- default:
- divisor = 1;
- DEV_ERR("%s: invalid hsclk_sel value = %lu",
- __func__, hsclk_sel);
- break;
- }
- return divisor;
- }
- static unsigned long hdmi_8996_vco_get_rate(struct clk *c)
- {
- unsigned long freq = 0, hsclk_sel = 0, tx_band = 0, dec_start = 0,
- div_frac_start = 0, vco_clock_freq = 0;
- struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c);
- struct mdss_pll_resources *io = vco->priv;
- if (mdss_pll_resource_enable(io, true)) {
- DEV_ERR("%s: pll resource can't be enabled\n", __func__);
- return freq;
- }
- dec_start = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_DEC_START_MODE0);
- div_frac_start =
- MDSS_PLL_REG_R(io->pll_base,
- QSERDES_COM_DIV_FRAC_START1_MODE0) |
- MDSS_PLL_REG_R(io->pll_base,
- QSERDES_COM_DIV_FRAC_START2_MODE0) << 8 |
- MDSS_PLL_REG_R(io->pll_base,
- QSERDES_COM_DIV_FRAC_START3_MODE0) << 16;
- vco_clock_freq = (dec_start + (div_frac_start / (1 << 20)))
- * 4 * (HDMI_REF_CLOCK);
- hsclk_sel = MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_HSCLK_SEL) & 0x15;
- hsclk_sel = hdmi_get_hsclk_sel_divisor(hsclk_sel);
- tx_band = MDSS_PLL_REG_R(io->pll_base + HDMI_TX_L0_BASE_OFFSET,
- QSERDES_TX_L0_TX_BAND) & 0x3;
- freq = vco_clock_freq / (10 * hsclk_sel * (1 << tx_band));
- mdss_pll_resource_enable(io, false);
- DEV_DBG("%s: freq = %lu\n", __func__, freq);
- return freq;
- }
- static long hdmi_8996_vco_round_rate(struct clk *c, unsigned long rate)
- {
- unsigned long rrate = rate;
- DEV_DBG("rrate=%ld\n", rrate);
- return rrate;
- }
- static int hdmi_8996_vco_prepare(struct clk *c, u32 ver)
- {
- struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c);
- struct mdss_pll_resources *io = vco->priv;
- int ret = 0;
- DEV_DBG("rate=%ld\n", vco->rate);
- if (!vco->rate_set && vco->rate)
- ret = hdmi_8996_vco_set_rate(c, vco->rate, ver);
- if (!ret) {
- ret = mdss_pll_resource_enable(io, true);
- if (ret)
- DEV_ERR("pll resource can't be enabled\n");
- }
- return ret;
- }
- static int hdmi_8996_v1_vco_prepare(struct clk *c)
- {
- return hdmi_8996_vco_prepare(c, HDMI_VERSION_8996_V1);
- }
- static int hdmi_8996_v2_vco_prepare(struct clk *c)
- {
- return hdmi_8996_vco_prepare(c, HDMI_VERSION_8996_V2);
- }
- static int hdmi_8996_v3_vco_prepare(struct clk *c)
- {
- return hdmi_8996_vco_prepare(c, HDMI_VERSION_8996_V3);
- }
- static int hdmi_8996_v3_1p8_vco_prepare(struct clk *c)
- {
- return hdmi_8996_vco_prepare(c, HDMI_VERSION_8996_V3_1_8);
- }
- static void hdmi_8996_vco_unprepare(struct clk *c)
- {
- struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c);
- struct mdss_pll_resources *io = vco->priv;
- vco->rate_set = false;
- if (!io) {
- DEV_ERR("Invalid input parameter\n");
- return;
- }
- if (!io->pll_on &&
- mdss_pll_resource_enable(io, true)) {
- DEV_ERR("pll resource can't be enabled\n");
- return;
- }
- io->handoff_resources = false;
- mdss_pll_resource_enable(io, false);
- io->pll_on = false;
- }
- static enum handoff hdmi_8996_vco_handoff(struct clk *c)
- {
- enum handoff ret = HANDOFF_DISABLED_CLK;
- struct hdmi_pll_vco_clk *vco = to_hdmi_8996_vco_clk(c);
- struct mdss_pll_resources *io = vco->priv;
- if (is_gdsc_disabled(io))
- return HANDOFF_DISABLED_CLK;
- if (mdss_pll_resource_enable(io, true)) {
- DEV_ERR("pll resource can't be enabled\n");
- return ret;
- }
- io->handoff_resources = true;
- if (MDSS_PLL_REG_R(io->pll_base, QSERDES_COM_C_READY_STATUS) & BIT(0)) {
- if (MDSS_PLL_REG_R(io->phy_base, HDMI_PHY_STATUS) & BIT(0)) {
- io->pll_on = true;
- c->rate = hdmi_8996_vco_get_rate(c);
- vco->rate = c->rate;
- ret = HANDOFF_ENABLED_CLK;
- } else {
- io->handoff_resources = false;
- mdss_pll_resource_enable(io, false);
- DEV_DBG("%s: PHY not ready\n", __func__);
- }
- } else {
- io->handoff_resources = false;
- mdss_pll_resource_enable(io, false);
- DEV_DBG("%s: PLL not locked\n", __func__);
- }
- DEV_DBG("done, ret=%d\n", ret);
- return ret;
- }
- static const struct clk_ops hdmi_8996_v1_vco_clk_ops = {
- .enable = hdmi_8996_v1_vco_enable,
- .set_rate = hdmi_8996_v1_vco_set_rate,
- .get_rate = hdmi_8996_vco_get_rate,
- .round_rate = hdmi_8996_vco_round_rate,
- .prepare = hdmi_8996_v1_vco_prepare,
- .unprepare = hdmi_8996_vco_unprepare,
- .handoff = hdmi_8996_vco_handoff,
- };
- static const struct clk_ops hdmi_8996_v2_vco_clk_ops = {
- .enable = hdmi_8996_v2_vco_enable,
- .set_rate = hdmi_8996_v2_vco_set_rate,
- .get_rate = hdmi_8996_vco_get_rate,
- .round_rate = hdmi_8996_vco_round_rate,
- .prepare = hdmi_8996_v2_vco_prepare,
- .unprepare = hdmi_8996_vco_unprepare,
- .handoff = hdmi_8996_vco_handoff,
- };
- static const struct clk_ops hdmi_8996_v3_vco_clk_ops = {
- .enable = hdmi_8996_v3_vco_enable,
- .set_rate = hdmi_8996_v3_vco_set_rate,
- .get_rate = hdmi_8996_vco_get_rate,
- .round_rate = hdmi_8996_vco_round_rate,
- .prepare = hdmi_8996_v3_vco_prepare,
- .unprepare = hdmi_8996_vco_unprepare,
- .handoff = hdmi_8996_vco_handoff,
- };
- static const struct clk_ops hdmi_8996_v3_1p8_vco_clk_ops = {
- .enable = hdmi_8996_v3_1p8_vco_enable,
- .set_rate = hdmi_8996_v3_1p8_vco_set_rate,
- .get_rate = hdmi_8996_vco_get_rate,
- .round_rate = hdmi_8996_vco_round_rate,
- .prepare = hdmi_8996_v3_1p8_vco_prepare,
- .unprepare = hdmi_8996_vco_unprepare,
- .handoff = hdmi_8996_vco_handoff,
- };
- static struct hdmi_pll_vco_clk hdmi_vco_clk = {
- .c = {
- .dbg_name = "hdmi_8996_vco_clk",
- .ops = &hdmi_8996_v1_vco_clk_ops,
- CLK_INIT(hdmi_vco_clk.c),
- },
- };
- static struct clk_lookup hdmipllcc_8996[] = {
- CLK_LIST(hdmi_vco_clk),
- };
- int hdmi_8996_pll_clock_register(struct platform_device *pdev,
- struct mdss_pll_resources *pll_res, u32 ver)
- {
- int rc = -ENOTSUPP;
- if (!pll_res || !pll_res->phy_base || !pll_res->pll_base) {
- DEV_ERR("%s: Invalid input parameters\n", __func__);
- return -EPROBE_DEFER;
- }
- /* Set client data for vco, mux and div clocks */
- hdmi_vco_clk.priv = pll_res;
- switch (ver) {
- case HDMI_VERSION_8996_V2:
- hdmi_vco_clk.c.ops = &hdmi_8996_v2_vco_clk_ops;
- break;
- case HDMI_VERSION_8996_V3:
- hdmi_vco_clk.c.ops = &hdmi_8996_v3_vco_clk_ops;
- break;
- case HDMI_VERSION_8996_V3_1_8:
- hdmi_vco_clk.c.ops = &hdmi_8996_v3_1p8_vco_clk_ops;
- break;
- default:
- hdmi_vco_clk.c.ops = &hdmi_8996_v1_vco_clk_ops;
- break;
- }
- rc = of_msm_clock_register(pdev->dev.of_node, hdmipllcc_8996,
- ARRAY_SIZE(hdmipllcc_8996));
- if (rc) {
- DEV_ERR("%s: Clock register failed rc=%d\n", __func__, rc);
- rc = -EPROBE_DEFER;
- } else {
- DEV_DBG("%s SUCCESS\n", __func__);
- }
- return rc;
- }
- int hdmi_8996_v1_pll_clock_register(struct platform_device *pdev,
- struct mdss_pll_resources *pll_res)
- {
- return hdmi_8996_pll_clock_register(pdev, pll_res,
- HDMI_VERSION_8996_V1);
- }
- int hdmi_8996_v2_pll_clock_register(struct platform_device *pdev,
- struct mdss_pll_resources *pll_res)
- {
- return hdmi_8996_pll_clock_register(pdev, pll_res,
- HDMI_VERSION_8996_V2);
- }
- int hdmi_8996_v3_pll_clock_register(struct platform_device *pdev,
- struct mdss_pll_resources *pll_res)
- {
- return hdmi_8996_pll_clock_register(pdev, pll_res,
- HDMI_VERSION_8996_V3);
- }
- int hdmi_8996_v3_1p8_pll_clock_register(struct platform_device *pdev,
- struct mdss_pll_resources *pll_res)
- {
- return hdmi_8996_pll_clock_register(pdev, pll_res,
- HDMI_VERSION_8996_V3_1_8);
- }
|