12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378 |
- /*
- * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
- *
- * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
- */
- #include <assert.h>
- #include <errno.h>
- #include <limits.h>
- #include <stdint.h>
- #include <stdio.h>
- #include <arch.h>
- #include <arch_helpers.h>
- #include "clk-stm32-core.h"
- #include <common/debug.h>
- #include <common/fdt_wrappers.h>
- #include <drivers/clk.h>
- #include <drivers/delay_timer.h>
- #include <drivers/st/stm32mp13_rcc.h>
- #include <drivers/st/stm32mp1_clk.h>
- #include <drivers/st/stm32mp_clkfunc.h>
- #include <dt-bindings/clock/stm32mp13-clksrc.h>
- #include <lib/mmio.h>
- #include <lib/spinlock.h>
- #include <lib/utils_def.h>
- #include <libfdt.h>
- #include <plat/common/platform.h>
- #include <platform_def.h>
- struct stm32_osci_dt_cfg {
- unsigned long freq;
- bool bypass;
- bool digbyp;
- bool css;
- uint32_t drive;
- };
- enum pll_mn {
- PLL_CFG_M,
- PLL_CFG_N,
- PLL_DIV_MN_NB
- };
- enum pll_pqr {
- PLL_CFG_P,
- PLL_CFG_Q,
- PLL_CFG_R,
- PLL_DIV_PQR_NB
- };
- enum pll_csg {
- PLL_CSG_MOD_PER,
- PLL_CSG_INC_STEP,
- PLL_CSG_SSCG_MODE,
- PLL_CSG_NB
- };
- struct stm32_pll_vco {
- uint32_t status;
- uint32_t src;
- uint32_t div_mn[PLL_DIV_MN_NB];
- uint32_t frac;
- bool csg_enabled;
- uint32_t csg[PLL_CSG_NB];
- };
- struct stm32_pll_output {
- uint32_t output[PLL_DIV_PQR_NB];
- };
- struct stm32_pll_dt_cfg {
- struct stm32_pll_vco vco;
- struct stm32_pll_output output;
- };
- struct stm32_clk_platdata {
- uint32_t nosci;
- struct stm32_osci_dt_cfg *osci;
- uint32_t npll;
- struct stm32_pll_dt_cfg *pll;
- uint32_t nclksrc;
- uint32_t *clksrc;
- uint32_t nclkdiv;
- uint32_t *clkdiv;
- };
- enum stm32_clock {
- /* ROOT CLOCKS */
- _CK_OFF,
- _CK_HSI,
- _CK_HSE,
- _CK_CSI,
- _CK_LSI,
- _CK_LSE,
- _I2SCKIN,
- _CSI_DIV122,
- _HSE_DIV,
- _HSE_DIV2,
- _CK_PLL1,
- _CK_PLL2,
- _CK_PLL3,
- _CK_PLL4,
- _PLL1P,
- _PLL1P_DIV,
- _PLL2P,
- _PLL2Q,
- _PLL2R,
- _PLL3P,
- _PLL3Q,
- _PLL3R,
- _PLL4P,
- _PLL4Q,
- _PLL4R,
- _PCLK1,
- _PCLK2,
- _PCLK3,
- _PCLK4,
- _PCLK5,
- _PCLK6,
- _CKMPU,
- _CKAXI,
- _CKMLAHB,
- _CKPER,
- _CKTIMG1,
- _CKTIMG2,
- _CKTIMG3,
- _USB_PHY_48,
- _MCO1_K,
- _MCO2_K,
- _TRACECK,
- /* BUS and KERNEL CLOCKS */
- _DDRC1,
- _DDRC1LP,
- _DDRPHYC,
- _DDRPHYCLP,
- _DDRCAPB,
- _DDRCAPBLP,
- _AXIDCG,
- _DDRPHYCAPB,
- _DDRPHYCAPBLP,
- _SYSCFG,
- _DDRPERFM,
- _IWDG2APB,
- _USBPHY_K,
- _USBO_K,
- _RTCAPB,
- _TZC,
- _ETZPC,
- _IWDG1APB,
- _BSEC,
- _STGENC,
- _USART1_K,
- _USART2_K,
- _I2C3_K,
- _I2C4_K,
- _I2C5_K,
- _TIM12,
- _TIM15,
- _RTCCK,
- _GPIOA,
- _GPIOB,
- _GPIOC,
- _GPIOD,
- _GPIOE,
- _GPIOF,
- _GPIOG,
- _GPIOH,
- _GPIOI,
- _PKA,
- _SAES_K,
- _CRYP1,
- _HASH1,
- _RNG1_K,
- _BKPSRAM,
- _SDMMC1_K,
- _SDMMC2_K,
- _DBGCK,
- _USART3_K,
- _UART4_K,
- _UART5_K,
- _UART7_K,
- _UART8_K,
- _USART6_K,
- _MCE,
- _FMC_K,
- _QSPI_K,
- CK_LAST
- };
- /* PARENT CONFIG */
- static const uint16_t RTC_src[] = {
- _CK_OFF, _CK_LSE, _CK_LSI, _CK_HSE
- };
- static const uint16_t MCO1_src[] = {
- _CK_HSI, _CK_HSE, _CK_CSI, _CK_LSI, _CK_LSE
- };
- static const uint16_t MCO2_src[] = {
- _CKMPU, _CKAXI, _CKMLAHB, _PLL4P, _CK_HSE, _CK_HSI
- };
- static const uint16_t PLL12_src[] = {
- _CK_HSI, _CK_HSE
- };
- static const uint16_t PLL3_src[] = {
- _CK_HSI, _CK_HSE, _CK_CSI
- };
- static const uint16_t PLL4_src[] = {
- _CK_HSI, _CK_HSE, _CK_CSI, _I2SCKIN
- };
- static const uint16_t MPU_src[] = {
- _CK_HSI, _CK_HSE, _PLL1P, _PLL1P_DIV
- };
- static const uint16_t AXI_src[] = {
- _CK_HSI, _CK_HSE, _PLL2P
- };
- static const uint16_t MLAHBS_src[] = {
- _CK_HSI, _CK_HSE, _CK_CSI, _PLL3P
- };
- static const uint16_t CKPER_src[] = {
- _CK_HSI, _CK_CSI, _CK_HSE, _CK_OFF
- };
- static const uint16_t I2C12_src[] = {
- _PCLK1, _PLL4R, _CK_HSI, _CK_CSI
- };
- static const uint16_t I2C3_src[] = {
- _PCLK6, _PLL4R, _CK_HSI, _CK_CSI
- };
- static const uint16_t I2C4_src[] = {
- _PCLK6, _PLL4R, _CK_HSI, _CK_CSI
- };
- static const uint16_t I2C5_src[] = {
- _PCLK6, _PLL4R, _CK_HSI, _CK_CSI
- };
- static const uint16_t SPI1_src[] = {
- _PLL4P, _PLL3Q, _I2SCKIN, _CKPER, _PLL3R
- };
- static const uint16_t SPI23_src[] = {
- _PLL4P, _PLL3Q, _I2SCKIN, _CKPER, _PLL3R
- };
- static const uint16_t SPI4_src[] = {
- _PCLK6, _PLL4Q, _CK_HSI, _CK_CSI, _CK_HSE, _I2SCKIN
- };
- static const uint16_t SPI5_src[] = {
- _PCLK6, _PLL4Q, _CK_HSI, _CK_CSI, _CK_HSE
- };
- static const uint16_t UART1_src[] = {
- _PCLK6, _PLL3Q, _CK_HSI, _CK_CSI, _PLL4Q, _CK_HSE
- };
- static const uint16_t UART2_src[] = {
- _PCLK6, _PLL3Q, _CK_HSI, _CK_CSI, _PLL4Q, _CK_HSE
- };
- static const uint16_t UART35_src[] = {
- _PCLK1, _PLL4Q, _CK_HSI, _CK_CSI, _CK_HSE
- };
- static const uint16_t UART4_src[] = {
- _PCLK1, _PLL4Q, _CK_HSI, _CK_CSI, _CK_HSE
- };
- static const uint16_t UART6_src[] = {
- _PCLK2, _PLL4Q, _CK_HSI, _CK_CSI, _CK_HSE
- };
- static const uint16_t UART78_src[] = {
- _PCLK1, _PLL4Q, _CK_HSI, _CK_CSI, _CK_HSE
- };
- static const uint16_t LPTIM1_src[] = {
- _PCLK1, _PLL4P, _PLL3Q, _CK_LSE, _CK_LSI, _CKPER
- };
- static const uint16_t LPTIM2_src[] = {
- _PCLK3, _PLL4Q, _CKPER, _CK_LSE, _CK_LSI
- };
- static const uint16_t LPTIM3_src[] = {
- _PCLK3, _PLL4Q, _CKPER, _CK_LSE, _CK_LSI
- };
- static const uint16_t LPTIM45_src[] = {
- _PCLK3, _PLL4P, _PLL3Q, _CK_LSE, _CK_LSI, _CKPER
- };
- static const uint16_t SAI1_src[] = {
- _PLL4Q, _PLL3Q, _I2SCKIN, _CKPER, _PLL3R
- };
- static const uint16_t SAI2_src[] = {
- _PLL4Q, _PLL3Q, _I2SCKIN, _CKPER, _NO_ID, _PLL3R
- };
- static const uint16_t FDCAN_src[] = {
- _CK_HSE, _PLL3Q, _PLL4Q, _PLL4R
- };
- static const uint16_t SPDIF_src[] = {
- _PLL4P, _PLL3Q, _CK_HSI
- };
- static const uint16_t ADC1_src[] = {
- _PLL4R, _CKPER, _PLL3Q
- };
- static const uint16_t ADC2_src[] = {
- _PLL4R, _CKPER, _PLL3Q
- };
- static const uint16_t SDMMC1_src[] = {
- _CKAXI, _PLL3R, _PLL4P, _CK_HSI
- };
- static const uint16_t SDMMC2_src[] = {
- _CKAXI, _PLL3R, _PLL4P, _CK_HSI
- };
- static const uint16_t ETH1_src[] = {
- _PLL4P, _PLL3Q
- };
- static const uint16_t ETH2_src[] = {
- _PLL4P, _PLL3Q
- };
- static const uint16_t USBPHY_src[] = {
- _CK_HSE, _PLL4R, _HSE_DIV2
- };
- static const uint16_t USBO_src[] = {
- _PLL4R, _USB_PHY_48
- };
- static const uint16_t QSPI_src[] = {
- _CKAXI, _PLL3R, _PLL4P, _CKPER
- };
- static const uint16_t FMC_src[] = {
- _CKAXI, _PLL3R, _PLL4P, _CKPER
- };
- /* Position 2 of RNG1 mux is reserved */
- static const uint16_t RNG1_src[] = {
- _CK_CSI, _PLL4R, _CK_OFF, _CK_LSI
- };
- static const uint16_t STGEN_src[] = {
- _CK_HSI, _CK_HSE
- };
- static const uint16_t DCMIPP_src[] = {
- _CKAXI, _PLL2Q, _PLL4P, _CKPER
- };
- static const uint16_t SAES_src[] = {
- _CKAXI, _CKPER, _PLL4R, _CK_LSI
- };
- #define MUX_CFG(id, src, _offset, _shift, _witdh)[id] = {\
- .id_parents = src,\
- .num_parents = ARRAY_SIZE(src),\
- .mux = &(struct mux_cfg) {\
- .offset = (_offset),\
- .shift = (_shift),\
- .width = (_witdh),\
- .bitrdy = MUX_NO_BIT_RDY,\
- },\
- }
- #define MUX_RDY_CFG(id, src, _offset, _shift, _witdh)[id] = {\
- .id_parents = src,\
- .num_parents = ARRAY_SIZE(src),\
- .mux = &(struct mux_cfg) {\
- .offset = (_offset),\
- .shift = (_shift),\
- .width = (_witdh),\
- .bitrdy = 31,\
- },\
- }
- static const struct parent_cfg parent_mp13[MUX_MAX] = {
- MUX_CFG(MUX_ADC1, ADC1_src, RCC_ADC12CKSELR, 0, 2),
- MUX_CFG(MUX_ADC2, ADC2_src, RCC_ADC12CKSELR, 2, 2),
- MUX_RDY_CFG(MUX_AXI, AXI_src, RCC_ASSCKSELR, 0, 3),
- MUX_CFG(MUX_CKPER, CKPER_src, RCC_CPERCKSELR, 0, 2),
- MUX_CFG(MUX_DCMIPP, DCMIPP_src, RCC_DCMIPPCKSELR, 0, 2),
- MUX_CFG(MUX_ETH1, ETH1_src, RCC_ETH12CKSELR, 0, 2),
- MUX_CFG(MUX_ETH2, ETH2_src, RCC_ETH12CKSELR, 8, 2),
- MUX_CFG(MUX_FDCAN, FDCAN_src, RCC_FDCANCKSELR, 0, 2),
- MUX_CFG(MUX_FMC, FMC_src, RCC_FMCCKSELR, 0, 2),
- MUX_CFG(MUX_I2C12, I2C12_src, RCC_I2C12CKSELR, 0, 3),
- MUX_CFG(MUX_I2C3, I2C3_src, RCC_I2C345CKSELR, 0, 3),
- MUX_CFG(MUX_I2C4, I2C4_src, RCC_I2C345CKSELR, 3, 3),
- MUX_CFG(MUX_I2C5, I2C5_src, RCC_I2C345CKSELR, 6, 3),
- MUX_CFG(MUX_LPTIM1, LPTIM1_src, RCC_LPTIM1CKSELR, 0, 3),
- MUX_CFG(MUX_LPTIM2, LPTIM2_src, RCC_LPTIM23CKSELR, 0, 3),
- MUX_CFG(MUX_LPTIM3, LPTIM3_src, RCC_LPTIM23CKSELR, 3, 3),
- MUX_CFG(MUX_LPTIM45, LPTIM45_src, RCC_LPTIM45CKSELR, 0, 3),
- MUX_CFG(MUX_MCO1, MCO1_src, RCC_MCO1CFGR, 0, 3),
- MUX_CFG(MUX_MCO2, MCO2_src, RCC_MCO2CFGR, 0, 3),
- MUX_RDY_CFG(MUX_MLAHB, MLAHBS_src, RCC_MSSCKSELR, 0, 2),
- MUX_RDY_CFG(MUX_MPU, MPU_src, RCC_MPCKSELR, 0, 2),
- MUX_RDY_CFG(MUX_PLL12, PLL12_src, RCC_RCK12SELR, 0, 2),
- MUX_RDY_CFG(MUX_PLL3, PLL3_src, RCC_RCK3SELR, 0, 2),
- MUX_RDY_CFG(MUX_PLL4, PLL4_src, RCC_RCK4SELR, 0, 2),
- MUX_CFG(MUX_QSPI, QSPI_src, RCC_QSPICKSELR, 0, 2),
- MUX_CFG(MUX_RNG1, RNG1_src, RCC_RNG1CKSELR, 0, 2),
- MUX_CFG(MUX_RTC, RTC_src, RCC_BDCR, 16, 2),
- MUX_CFG(MUX_SAES, SAES_src, RCC_SAESCKSELR, 0, 2),
- MUX_CFG(MUX_SAI1, SAI1_src, RCC_SAI1CKSELR, 0, 3),
- MUX_CFG(MUX_SAI2, SAI2_src, RCC_SAI2CKSELR, 0, 3),
- MUX_CFG(MUX_SDMMC1, SDMMC1_src, RCC_SDMMC12CKSELR, 0, 3),
- MUX_CFG(MUX_SDMMC2, SDMMC2_src, RCC_SDMMC12CKSELR, 3, 3),
- MUX_CFG(MUX_SPDIF, SPDIF_src, RCC_SPDIFCKSELR, 0, 2),
- MUX_CFG(MUX_SPI1, SPI1_src, RCC_SPI2S1CKSELR, 0, 3),
- MUX_CFG(MUX_SPI23, SPI23_src, RCC_SPI2S23CKSELR, 0, 3),
- MUX_CFG(MUX_SPI4, SPI4_src, RCC_SPI45CKSELR, 0, 3),
- MUX_CFG(MUX_SPI5, SPI5_src, RCC_SPI45CKSELR, 3, 3),
- MUX_CFG(MUX_STGEN, STGEN_src, RCC_STGENCKSELR, 0, 2),
- MUX_CFG(MUX_UART1, UART1_src, RCC_UART12CKSELR, 0, 3),
- MUX_CFG(MUX_UART2, UART2_src, RCC_UART12CKSELR, 3, 3),
- MUX_CFG(MUX_UART35, UART35_src, RCC_UART35CKSELR, 0, 3),
- MUX_CFG(MUX_UART4, UART4_src, RCC_UART4CKSELR, 0, 3),
- MUX_CFG(MUX_UART6, UART6_src, RCC_UART6CKSELR, 0, 3),
- MUX_CFG(MUX_UART78, UART78_src, RCC_UART78CKSELR, 0, 3),
- MUX_CFG(MUX_USBO, USBO_src, RCC_USBCKSELR, 4, 1),
- MUX_CFG(MUX_USBPHY, USBPHY_src, RCC_USBCKSELR, 0, 2),
- };
- /*
- * GATE CONFIG
- */
- enum enum_gate_cfg {
- GATE_ZERO, /* reserved for no gate */
- GATE_LSE,
- GATE_RTCCK,
- GATE_LSI,
- GATE_HSI,
- GATE_CSI,
- GATE_HSE,
- GATE_LSI_RDY,
- GATE_CSI_RDY,
- GATE_LSE_RDY,
- GATE_HSE_RDY,
- GATE_HSI_RDY,
- GATE_MCO1,
- GATE_MCO2,
- GATE_DBGCK,
- GATE_TRACECK,
- GATE_PLL1,
- GATE_PLL1_DIVP,
- GATE_PLL1_DIVQ,
- GATE_PLL1_DIVR,
- GATE_PLL2,
- GATE_PLL2_DIVP,
- GATE_PLL2_DIVQ,
- GATE_PLL2_DIVR,
- GATE_PLL3,
- GATE_PLL3_DIVP,
- GATE_PLL3_DIVQ,
- GATE_PLL3_DIVR,
- GATE_PLL4,
- GATE_PLL4_DIVP,
- GATE_PLL4_DIVQ,
- GATE_PLL4_DIVR,
- GATE_DDRC1,
- GATE_DDRC1LP,
- GATE_DDRPHYC,
- GATE_DDRPHYCLP,
- GATE_DDRCAPB,
- GATE_DDRCAPBLP,
- GATE_AXIDCG,
- GATE_DDRPHYCAPB,
- GATE_DDRPHYCAPBLP,
- GATE_TIM2,
- GATE_TIM3,
- GATE_TIM4,
- GATE_TIM5,
- GATE_TIM6,
- GATE_TIM7,
- GATE_LPTIM1,
- GATE_SPI2,
- GATE_SPI3,
- GATE_USART3,
- GATE_UART4,
- GATE_UART5,
- GATE_UART7,
- GATE_UART8,
- GATE_I2C1,
- GATE_I2C2,
- GATE_SPDIF,
- GATE_TIM1,
- GATE_TIM8,
- GATE_SPI1,
- GATE_USART6,
- GATE_SAI1,
- GATE_SAI2,
- GATE_DFSDM,
- GATE_ADFSDM,
- GATE_FDCAN,
- GATE_LPTIM2,
- GATE_LPTIM3,
- GATE_LPTIM4,
- GATE_LPTIM5,
- GATE_VREF,
- GATE_DTS,
- GATE_PMBCTRL,
- GATE_HDP,
- GATE_SYSCFG,
- GATE_DCMIPP,
- GATE_DDRPERFM,
- GATE_IWDG2APB,
- GATE_USBPHY,
- GATE_STGENRO,
- GATE_LTDC,
- GATE_RTCAPB,
- GATE_TZC,
- GATE_ETZPC,
- GATE_IWDG1APB,
- GATE_BSEC,
- GATE_STGENC,
- GATE_USART1,
- GATE_USART2,
- GATE_SPI4,
- GATE_SPI5,
- GATE_I2C3,
- GATE_I2C4,
- GATE_I2C5,
- GATE_TIM12,
- GATE_TIM13,
- GATE_TIM14,
- GATE_TIM15,
- GATE_TIM16,
- GATE_TIM17,
- GATE_DMA1,
- GATE_DMA2,
- GATE_DMAMUX1,
- GATE_DMA3,
- GATE_DMAMUX2,
- GATE_ADC1,
- GATE_ADC2,
- GATE_USBO,
- GATE_TSC,
- GATE_GPIOA,
- GATE_GPIOB,
- GATE_GPIOC,
- GATE_GPIOD,
- GATE_GPIOE,
- GATE_GPIOF,
- GATE_GPIOG,
- GATE_GPIOH,
- GATE_GPIOI,
- GATE_PKA,
- GATE_SAES,
- GATE_CRYP1,
- GATE_HASH1,
- GATE_RNG1,
- GATE_BKPSRAM,
- GATE_AXIMC,
- GATE_MCE,
- GATE_ETH1CK,
- GATE_ETH1TX,
- GATE_ETH1RX,
- GATE_ETH1MAC,
- GATE_FMC,
- GATE_QSPI,
- GATE_SDMMC1,
- GATE_SDMMC2,
- GATE_CRC1,
- GATE_USBH,
- GATE_ETH2CK,
- GATE_ETH2TX,
- GATE_ETH2RX,
- GATE_ETH2MAC,
- GATE_MDMA,
- LAST_GATE
- };
- #define GATE_CFG(id, _offset, _bit_idx, _offset_clr)[id] = {\
- .offset = (_offset),\
- .bit_idx = (_bit_idx),\
- .set_clr = (_offset_clr),\
- }
- static const struct gate_cfg gates_mp13[LAST_GATE] = {
- GATE_CFG(GATE_LSE, RCC_BDCR, 0, 0),
- GATE_CFG(GATE_RTCCK, RCC_BDCR, 20, 0),
- GATE_CFG(GATE_LSI, RCC_RDLSICR, 0, 0),
- GATE_CFG(GATE_HSI, RCC_OCENSETR, 0, 1),
- GATE_CFG(GATE_CSI, RCC_OCENSETR, 4, 1),
- GATE_CFG(GATE_HSE, RCC_OCENSETR, 8, 1),
- GATE_CFG(GATE_LSI_RDY, RCC_RDLSICR, 1, 0),
- GATE_CFG(GATE_CSI_RDY, RCC_OCRDYR, 4, 0),
- GATE_CFG(GATE_LSE_RDY, RCC_BDCR, 2, 0),
- GATE_CFG(GATE_HSE_RDY, RCC_OCRDYR, 8, 0),
- GATE_CFG(GATE_HSI_RDY, RCC_OCRDYR, 0, 0),
- GATE_CFG(GATE_MCO1, RCC_MCO1CFGR, 12, 0),
- GATE_CFG(GATE_MCO2, RCC_MCO2CFGR, 12, 0),
- GATE_CFG(GATE_DBGCK, RCC_DBGCFGR, 8, 0),
- GATE_CFG(GATE_TRACECK, RCC_DBGCFGR, 9, 0),
- GATE_CFG(GATE_PLL1, RCC_PLL1CR, 0, 0),
- GATE_CFG(GATE_PLL1_DIVP, RCC_PLL1CR, 4, 0),
- GATE_CFG(GATE_PLL1_DIVQ, RCC_PLL1CR, 5, 0),
- GATE_CFG(GATE_PLL1_DIVR, RCC_PLL1CR, 6, 0),
- GATE_CFG(GATE_PLL2, RCC_PLL2CR, 0, 0),
- GATE_CFG(GATE_PLL2_DIVP, RCC_PLL2CR, 4, 0),
- GATE_CFG(GATE_PLL2_DIVQ, RCC_PLL2CR, 5, 0),
- GATE_CFG(GATE_PLL2_DIVR, RCC_PLL2CR, 6, 0),
- GATE_CFG(GATE_PLL3, RCC_PLL3CR, 0, 0),
- GATE_CFG(GATE_PLL3_DIVP, RCC_PLL3CR, 4, 0),
- GATE_CFG(GATE_PLL3_DIVQ, RCC_PLL3CR, 5, 0),
- GATE_CFG(GATE_PLL3_DIVR, RCC_PLL3CR, 6, 0),
- GATE_CFG(GATE_PLL4, RCC_PLL4CR, 0, 0),
- GATE_CFG(GATE_PLL4_DIVP, RCC_PLL4CR, 4, 0),
- GATE_CFG(GATE_PLL4_DIVQ, RCC_PLL4CR, 5, 0),
- GATE_CFG(GATE_PLL4_DIVR, RCC_PLL4CR, 6, 0),
- GATE_CFG(GATE_DDRC1, RCC_DDRITFCR, 0, 0),
- GATE_CFG(GATE_DDRC1LP, RCC_DDRITFCR, 1, 0),
- GATE_CFG(GATE_DDRPHYC, RCC_DDRITFCR, 4, 0),
- GATE_CFG(GATE_DDRPHYCLP, RCC_DDRITFCR, 5, 0),
- GATE_CFG(GATE_DDRCAPB, RCC_DDRITFCR, 6, 0),
- GATE_CFG(GATE_DDRCAPBLP, RCC_DDRITFCR, 7, 0),
- GATE_CFG(GATE_AXIDCG, RCC_DDRITFCR, 8, 0),
- GATE_CFG(GATE_DDRPHYCAPB, RCC_DDRITFCR, 9, 0),
- GATE_CFG(GATE_DDRPHYCAPBLP, RCC_DDRITFCR, 10, 0),
- GATE_CFG(GATE_TIM2, RCC_MP_APB1ENSETR, 0, 1),
- GATE_CFG(GATE_TIM3, RCC_MP_APB1ENSETR, 1, 1),
- GATE_CFG(GATE_TIM4, RCC_MP_APB1ENSETR, 2, 1),
- GATE_CFG(GATE_TIM5, RCC_MP_APB1ENSETR, 3, 1),
- GATE_CFG(GATE_TIM6, RCC_MP_APB1ENSETR, 4, 1),
- GATE_CFG(GATE_TIM7, RCC_MP_APB1ENSETR, 5, 1),
- GATE_CFG(GATE_LPTIM1, RCC_MP_APB1ENSETR, 9, 1),
- GATE_CFG(GATE_SPI2, RCC_MP_APB1ENSETR, 11, 1),
- GATE_CFG(GATE_SPI3, RCC_MP_APB1ENSETR, 12, 1),
- GATE_CFG(GATE_USART3, RCC_MP_APB1ENSETR, 15, 1),
- GATE_CFG(GATE_UART4, RCC_MP_APB1ENSETR, 16, 1),
- GATE_CFG(GATE_UART5, RCC_MP_APB1ENSETR, 17, 1),
- GATE_CFG(GATE_UART7, RCC_MP_APB1ENSETR, 18, 1),
- GATE_CFG(GATE_UART8, RCC_MP_APB1ENSETR, 19, 1),
- GATE_CFG(GATE_I2C1, RCC_MP_APB1ENSETR, 21, 1),
- GATE_CFG(GATE_I2C2, RCC_MP_APB1ENSETR, 22, 1),
- GATE_CFG(GATE_SPDIF, RCC_MP_APB1ENSETR, 26, 1),
- GATE_CFG(GATE_TIM1, RCC_MP_APB2ENSETR, 0, 1),
- GATE_CFG(GATE_TIM8, RCC_MP_APB2ENSETR, 1, 1),
- GATE_CFG(GATE_SPI1, RCC_MP_APB2ENSETR, 8, 1),
- GATE_CFG(GATE_USART6, RCC_MP_APB2ENSETR, 13, 1),
- GATE_CFG(GATE_SAI1, RCC_MP_APB2ENSETR, 16, 1),
- GATE_CFG(GATE_SAI2, RCC_MP_APB2ENSETR, 17, 1),
- GATE_CFG(GATE_DFSDM, RCC_MP_APB2ENSETR, 20, 1),
- GATE_CFG(GATE_ADFSDM, RCC_MP_APB2ENSETR, 21, 1),
- GATE_CFG(GATE_FDCAN, RCC_MP_APB2ENSETR, 24, 1),
- GATE_CFG(GATE_LPTIM2, RCC_MP_APB3ENSETR, 0, 1),
- GATE_CFG(GATE_LPTIM3, RCC_MP_APB3ENSETR, 1, 1),
- GATE_CFG(GATE_LPTIM4, RCC_MP_APB3ENSETR, 2, 1),
- GATE_CFG(GATE_LPTIM5, RCC_MP_APB3ENSETR, 3, 1),
- GATE_CFG(GATE_VREF, RCC_MP_APB3ENSETR, 13, 1),
- GATE_CFG(GATE_DTS, RCC_MP_APB3ENSETR, 16, 1),
- GATE_CFG(GATE_PMBCTRL, RCC_MP_APB3ENSETR, 17, 1),
- GATE_CFG(GATE_HDP, RCC_MP_APB3ENSETR, 20, 1),
- GATE_CFG(GATE_SYSCFG, RCC_MP_S_APB3ENSETR, 0, 1),
- GATE_CFG(GATE_DCMIPP, RCC_MP_APB4ENSETR, 1, 1),
- GATE_CFG(GATE_DDRPERFM, RCC_MP_APB4ENSETR, 8, 1),
- GATE_CFG(GATE_IWDG2APB, RCC_MP_APB4ENSETR, 15, 1),
- GATE_CFG(GATE_USBPHY, RCC_MP_APB4ENSETR, 16, 1),
- GATE_CFG(GATE_STGENRO, RCC_MP_APB4ENSETR, 20, 1),
- GATE_CFG(GATE_LTDC, RCC_MP_S_APB4ENSETR, 0, 1),
- GATE_CFG(GATE_RTCAPB, RCC_MP_APB5ENSETR, 8, 1),
- GATE_CFG(GATE_TZC, RCC_MP_APB5ENSETR, 11, 1),
- GATE_CFG(GATE_ETZPC, RCC_MP_APB5ENSETR, 13, 1),
- GATE_CFG(GATE_IWDG1APB, RCC_MP_APB5ENSETR, 15, 1),
- GATE_CFG(GATE_BSEC, RCC_MP_APB5ENSETR, 16, 1),
- GATE_CFG(GATE_STGENC, RCC_MP_APB5ENSETR, 20, 1),
- GATE_CFG(GATE_USART1, RCC_MP_APB6ENSETR, 0, 1),
- GATE_CFG(GATE_USART2, RCC_MP_APB6ENSETR, 1, 1),
- GATE_CFG(GATE_SPI4, RCC_MP_APB6ENSETR, 2, 1),
- GATE_CFG(GATE_SPI5, RCC_MP_APB6ENSETR, 3, 1),
- GATE_CFG(GATE_I2C3, RCC_MP_APB6ENSETR, 4, 1),
- GATE_CFG(GATE_I2C4, RCC_MP_APB6ENSETR, 5, 1),
- GATE_CFG(GATE_I2C5, RCC_MP_APB6ENSETR, 6, 1),
- GATE_CFG(GATE_TIM12, RCC_MP_APB6ENSETR, 7, 1),
- GATE_CFG(GATE_TIM13, RCC_MP_APB6ENSETR, 8, 1),
- GATE_CFG(GATE_TIM14, RCC_MP_APB6ENSETR, 9, 1),
- GATE_CFG(GATE_TIM15, RCC_MP_APB6ENSETR, 10, 1),
- GATE_CFG(GATE_TIM16, RCC_MP_APB6ENSETR, 11, 1),
- GATE_CFG(GATE_TIM17, RCC_MP_APB6ENSETR, 12, 1),
- GATE_CFG(GATE_DMA1, RCC_MP_AHB2ENSETR, 0, 1),
- GATE_CFG(GATE_DMA2, RCC_MP_AHB2ENSETR, 1, 1),
- GATE_CFG(GATE_DMAMUX1, RCC_MP_AHB2ENSETR, 2, 1),
- GATE_CFG(GATE_DMA3, RCC_MP_AHB2ENSETR, 3, 1),
- GATE_CFG(GATE_DMAMUX2, RCC_MP_AHB2ENSETR, 4, 1),
- GATE_CFG(GATE_ADC1, RCC_MP_AHB2ENSETR, 5, 1),
- GATE_CFG(GATE_ADC2, RCC_MP_AHB2ENSETR, 6, 1),
- GATE_CFG(GATE_USBO, RCC_MP_AHB2ENSETR, 8, 1),
- GATE_CFG(GATE_TSC, RCC_MP_AHB4ENSETR, 15, 1),
- GATE_CFG(GATE_GPIOA, RCC_MP_S_AHB4ENSETR, 0, 1),
- GATE_CFG(GATE_GPIOB, RCC_MP_S_AHB4ENSETR, 1, 1),
- GATE_CFG(GATE_GPIOC, RCC_MP_S_AHB4ENSETR, 2, 1),
- GATE_CFG(GATE_GPIOD, RCC_MP_S_AHB4ENSETR, 3, 1),
- GATE_CFG(GATE_GPIOE, RCC_MP_S_AHB4ENSETR, 4, 1),
- GATE_CFG(GATE_GPIOF, RCC_MP_S_AHB4ENSETR, 5, 1),
- GATE_CFG(GATE_GPIOG, RCC_MP_S_AHB4ENSETR, 6, 1),
- GATE_CFG(GATE_GPIOH, RCC_MP_S_AHB4ENSETR, 7, 1),
- GATE_CFG(GATE_GPIOI, RCC_MP_S_AHB4ENSETR, 8, 1),
- GATE_CFG(GATE_PKA, RCC_MP_AHB5ENSETR, 2, 1),
- GATE_CFG(GATE_SAES, RCC_MP_AHB5ENSETR, 3, 1),
- GATE_CFG(GATE_CRYP1, RCC_MP_AHB5ENSETR, 4, 1),
- GATE_CFG(GATE_HASH1, RCC_MP_AHB5ENSETR, 5, 1),
- GATE_CFG(GATE_RNG1, RCC_MP_AHB5ENSETR, 6, 1),
- GATE_CFG(GATE_BKPSRAM, RCC_MP_AHB5ENSETR, 8, 1),
- GATE_CFG(GATE_AXIMC, RCC_MP_AHB5ENSETR, 16, 1),
- GATE_CFG(GATE_MCE, RCC_MP_AHB6ENSETR, 1, 1),
- GATE_CFG(GATE_ETH1CK, RCC_MP_AHB6ENSETR, 7, 1),
- GATE_CFG(GATE_ETH1TX, RCC_MP_AHB6ENSETR, 8, 1),
- GATE_CFG(GATE_ETH1RX, RCC_MP_AHB6ENSETR, 9, 1),
- GATE_CFG(GATE_ETH1MAC, RCC_MP_AHB6ENSETR, 10, 1),
- GATE_CFG(GATE_FMC, RCC_MP_AHB6ENSETR, 12, 1),
- GATE_CFG(GATE_QSPI, RCC_MP_AHB6ENSETR, 14, 1),
- GATE_CFG(GATE_SDMMC1, RCC_MP_AHB6ENSETR, 16, 1),
- GATE_CFG(GATE_SDMMC2, RCC_MP_AHB6ENSETR, 17, 1),
- GATE_CFG(GATE_CRC1, RCC_MP_AHB6ENSETR, 20, 1),
- GATE_CFG(GATE_USBH, RCC_MP_AHB6ENSETR, 24, 1),
- GATE_CFG(GATE_ETH2CK, RCC_MP_AHB6ENSETR, 27, 1),
- GATE_CFG(GATE_ETH2TX, RCC_MP_AHB6ENSETR, 28, 1),
- GATE_CFG(GATE_ETH2RX, RCC_MP_AHB6ENSETR, 29, 1),
- GATE_CFG(GATE_ETH2MAC, RCC_MP_AHB6ENSETR, 30, 1),
- GATE_CFG(GATE_MDMA, RCC_MP_S_AHB6ENSETR, 0, 1),
- };
- /*
- * DIV CONFIG
- */
- static const struct clk_div_table axi_div_table[] = {
- { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 },
- { 4, 4 }, { 5, 4 }, { 6, 4 }, { 7, 4 },
- { 0 },
- };
- static const struct clk_div_table mlahb_div_table[] = {
- { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 },
- { 4, 16 }, { 5, 32 }, { 6, 64 }, { 7, 128 },
- { 8, 256 }, { 9, 512 }, { 10, 512}, { 11, 512 },
- { 12, 512 }, { 13, 512 }, { 14, 512}, { 15, 512 },
- { 0 },
- };
- static const struct clk_div_table apb_div_table[] = {
- { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 },
- { 4, 16 }, { 5, 16 }, { 6, 16 }, { 7, 16 },
- { 0 },
- };
- #define DIV_CFG(id, _offset, _shift, _width, _flags, _table, _bitrdy)[id] = {\
- .offset = _offset,\
- .shift = _shift,\
- .width = _width,\
- .flags = _flags,\
- .table = _table,\
- .bitrdy = _bitrdy,\
- }
- static const struct div_cfg dividers_mp13[DIV_MAX] = {
- DIV_CFG(DIV_PLL1DIVP, RCC_PLL1CFGR2, 0, 7, 0, NULL, DIV_NO_BIT_RDY),
- DIV_CFG(DIV_PLL2DIVP, RCC_PLL2CFGR2, 0, 7, 0, NULL, DIV_NO_BIT_RDY),
- DIV_CFG(DIV_PLL2DIVQ, RCC_PLL2CFGR2, 8, 7, 0, NULL, DIV_NO_BIT_RDY),
- DIV_CFG(DIV_PLL2DIVR, RCC_PLL2CFGR2, 16, 7, 0, NULL, DIV_NO_BIT_RDY),
- DIV_CFG(DIV_PLL3DIVP, RCC_PLL3CFGR2, 0, 7, 0, NULL, DIV_NO_BIT_RDY),
- DIV_CFG(DIV_PLL3DIVQ, RCC_PLL3CFGR2, 8, 7, 0, NULL, DIV_NO_BIT_RDY),
- DIV_CFG(DIV_PLL3DIVR, RCC_PLL3CFGR2, 16, 7, 0, NULL, DIV_NO_BIT_RDY),
- DIV_CFG(DIV_PLL4DIVP, RCC_PLL4CFGR2, 0, 7, 0, NULL, DIV_NO_BIT_RDY),
- DIV_CFG(DIV_PLL4DIVQ, RCC_PLL4CFGR2, 8, 7, 0, NULL, DIV_NO_BIT_RDY),
- DIV_CFG(DIV_PLL4DIVR, RCC_PLL4CFGR2, 16, 7, 0, NULL, DIV_NO_BIT_RDY),
- DIV_CFG(DIV_MPU, RCC_MPCKDIVR, 0, 4, 0, NULL, DIV_NO_BIT_RDY),
- DIV_CFG(DIV_AXI, RCC_AXIDIVR, 0, 3, 0, axi_div_table, 31),
- DIV_CFG(DIV_MLAHB, RCC_MLAHBDIVR, 0, 4, 0, mlahb_div_table, 31),
- DIV_CFG(DIV_APB1, RCC_APB1DIVR, 0, 3, 0, apb_div_table, 31),
- DIV_CFG(DIV_APB2, RCC_APB2DIVR, 0, 3, 0, apb_div_table, 31),
- DIV_CFG(DIV_APB3, RCC_APB3DIVR, 0, 3, 0, apb_div_table, 31),
- DIV_CFG(DIV_APB4, RCC_APB4DIVR, 0, 3, 0, apb_div_table, 31),
- DIV_CFG(DIV_APB5, RCC_APB5DIVR, 0, 3, 0, apb_div_table, 31),
- DIV_CFG(DIV_APB6, RCC_APB6DIVR, 0, 3, 0, apb_div_table, 31),
- DIV_CFG(DIV_RTC, RCC_RTCDIVR, 0, 6, 0, NULL, DIV_NO_BIT_RDY),
- DIV_CFG(DIV_MCO1, RCC_MCO1CFGR, 4, 4, 0, NULL, DIV_NO_BIT_RDY),
- DIV_CFG(DIV_MCO2, RCC_MCO2CFGR, 4, 4, 0, NULL, DIV_NO_BIT_RDY),
- DIV_CFG(DIV_HSI, RCC_HSICFGR, 0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL, DIV_NO_BIT_RDY),
- DIV_CFG(DIV_TRACE, RCC_DBGCFGR, 0, 3, CLK_DIVIDER_POWER_OF_TWO, NULL, DIV_NO_BIT_RDY),
- DIV_CFG(DIV_ETH1PTP, RCC_ETH12CKSELR, 4, 4, 0, NULL, DIV_NO_BIT_RDY),
- DIV_CFG(DIV_ETH2PTP, RCC_ETH12CKSELR, 12, 4, 0, NULL, DIV_NO_BIT_RDY),
- };
- #define MAX_HSI_HZ 64000000
- #define USB_PHY_48_MHZ 48000000
- #define TIMEOUT_US_200MS U(200000)
- #define TIMEOUT_US_1S U(1000000)
- #define PLLRDY_TIMEOUT TIMEOUT_US_200MS
- #define CLKSRC_TIMEOUT TIMEOUT_US_200MS
- #define CLKDIV_TIMEOUT TIMEOUT_US_200MS
- #define HSIDIV_TIMEOUT TIMEOUT_US_200MS
- #define OSCRDY_TIMEOUT TIMEOUT_US_1S
- enum stm32_osc {
- OSC_HSI,
- OSC_HSE,
- OSC_CSI,
- OSC_LSI,
- OSC_LSE,
- OSC_I2SCKIN,
- NB_OSCILLATOR
- };
- enum stm32mp1_pll_id {
- _PLL1,
- _PLL2,
- _PLL3,
- _PLL4,
- _PLL_NB
- };
- enum stm32mp1_plltype {
- PLL_800,
- PLL_1600,
- PLL_2000,
- PLL_TYPE_NB
- };
- #define RCC_OFFSET_PLLXCR 0
- #define RCC_OFFSET_PLLXCFGR1 4
- #define RCC_OFFSET_PLLXCFGR2 8
- #define RCC_OFFSET_PLLXFRACR 12
- #define RCC_OFFSET_PLLXCSGR 16
- struct stm32_clk_pll {
- enum stm32mp1_plltype plltype;
- uint16_t clk_id;
- uint16_t reg_pllxcr;
- };
- struct stm32mp1_pll {
- uint8_t refclk_min;
- uint8_t refclk_max;
- };
- /* Define characteristic of PLL according type */
- static const struct stm32mp1_pll stm32mp1_pll[PLL_TYPE_NB] = {
- [PLL_800] = {
- .refclk_min = 4,
- .refclk_max = 16,
- },
- [PLL_1600] = {
- .refclk_min = 8,
- .refclk_max = 16,
- },
- [PLL_2000] = {
- .refclk_min = 8,
- .refclk_max = 16,
- },
- };
- #if STM32MP_USB_PROGRAMMER
- static bool pll4_bootrom;
- #endif
- /* RCC clock device driver private */
- static uint8_t refcounts_mp13[CK_LAST];
- static const struct stm32_clk_pll *clk_st32_pll_data(unsigned int idx);
- #if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER
- static void clk_oscillator_check_bypass(struct stm32_clk_priv *priv, int idx,
- bool digbyp, bool bypass)
- {
- struct clk_oscillator_data *osc_data = clk_oscillator_get_data(priv, idx);
- struct stm32_clk_bypass *bypass_data = osc_data->bypass;
- uintptr_t address;
- if (bypass_data == NULL) {
- return;
- }
- address = priv->base + bypass_data->offset;
- if ((mmio_read_32(address) & RCC_OCENR_HSEBYP) &&
- (!(digbyp || bypass))) {
- panic();
- }
- }
- #endif
- static void stm32_enable_oscillator_hse(struct stm32_clk_priv *priv)
- {
- struct stm32_clk_platdata *pdata = priv->pdata;
- struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_HSE];
- bool digbyp = osci->digbyp;
- bool bypass = osci->bypass;
- bool css = osci->css;
- if (_clk_stm32_get_rate(priv, _CK_HSE) == 0U) {
- return;
- }
- clk_oscillator_set_bypass(priv, _CK_HSE, digbyp, bypass);
- _clk_stm32_enable(priv, _CK_HSE);
- #if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER
- clk_oscillator_check_bypass(priv, _CK_HSE, digbyp, bypass);
- #endif
- clk_oscillator_set_css(priv, _CK_HSE, css);
- }
- static void stm32_enable_oscillator_lse(struct stm32_clk_priv *priv)
- {
- struct clk_oscillator_data *osc_data = clk_oscillator_get_data(priv, _CK_LSE);
- struct stm32_clk_platdata *pdata = priv->pdata;
- struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_LSE];
- bool digbyp = osci->digbyp;
- bool bypass = osci->bypass;
- uint8_t drive = osci->drive;
- if (_clk_stm32_get_rate(priv, _CK_LSE) == 0U) {
- return;
- }
- /* Do not reconfigure LSE if already enabled */
- if (_clk_stm32_gate_is_enabled(priv, osc_data->gate_id)) {
- return;
- }
- clk_oscillator_set_bypass(priv, _CK_LSE, digbyp, bypass);
- clk_oscillator_set_drive(priv, _CK_LSE, drive);
- _clk_stm32_gate_enable(priv, osc_data->gate_id);
- }
- static int stm32mp1_set_hsidiv(uint8_t hsidiv)
- {
- uint64_t timeout;
- uintptr_t rcc_base = stm32mp_rcc_base();
- uintptr_t address = rcc_base + RCC_OCRDYR;
- mmio_clrsetbits_32(rcc_base + RCC_HSICFGR,
- RCC_HSICFGR_HSIDIV_MASK,
- RCC_HSICFGR_HSIDIV_MASK & (uint32_t)hsidiv);
- timeout = timeout_init_us(HSIDIV_TIMEOUT);
- while ((mmio_read_32(address) & RCC_OCRDYR_HSIDIVRDY) == 0U) {
- if (timeout_elapsed(timeout)) {
- EARLY_ERROR("HSIDIV failed @ 0x%lx: 0x%x\n",
- address, mmio_read_32(address));
- return -ETIMEDOUT;
- }
- }
- return 0;
- }
- static int stm32mp1_hsidiv(unsigned long hsifreq)
- {
- uint8_t hsidiv;
- uint32_t hsidivfreq = MAX_HSI_HZ;
- for (hsidiv = 0; hsidiv < 4U; hsidiv++) {
- if (hsidivfreq == hsifreq) {
- break;
- }
- hsidivfreq /= 2U;
- }
- if (hsidiv == 4U) {
- EARLY_ERROR("Invalid clk-hsi frequency\n");
- return -EINVAL;
- }
- if (hsidiv != 0U) {
- return stm32mp1_set_hsidiv(hsidiv);
- }
- return 0;
- }
- static int stm32_clk_oscillators_lse_set_css(struct stm32_clk_priv *priv)
- {
- struct stm32_clk_platdata *pdata = priv->pdata;
- struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_LSE];
- clk_oscillator_set_css(priv, _CK_LSE, osci->css);
- return 0;
- }
- static int stm32mp1_come_back_to_hsi(void)
- {
- int ret;
- struct stm32_clk_priv *priv = clk_stm32_get_priv();
- /* Come back to HSI */
- ret = _clk_stm32_set_parent(priv, _CKMPU, _CK_HSI);
- if (ret != 0) {
- return ret;
- }
- ret = _clk_stm32_set_parent(priv, _CKAXI, _CK_HSI);
- if (ret != 0) {
- return ret;
- }
- ret = _clk_stm32_set_parent(priv, _CKMLAHB, _CK_HSI);
- if (ret != 0) {
- return ret;
- }
- return 0;
- }
- static int stm32_clk_configure_clk_get_binding_id(struct stm32_clk_priv *priv, uint32_t data)
- {
- unsigned long binding_id = ((unsigned long)data & CLK_ID_MASK) >> CLK_ID_SHIFT;
- return clk_get_index(priv, binding_id);
- }
- static int stm32_clk_configure_clk(struct stm32_clk_priv *priv, uint32_t data)
- {
- int sel = (data & CLK_SEL_MASK) >> CLK_SEL_SHIFT;
- int enable = (data & CLK_ON_MASK) >> CLK_ON_SHIFT;
- int clk_id;
- int ret;
- clk_id = stm32_clk_configure_clk_get_binding_id(priv, data);
- if (clk_id < 0) {
- return clk_id;
- }
- ret = _clk_stm32_set_parent_by_index(priv, clk_id, sel);
- if (ret != 0) {
- return ret;
- }
- if (enable != 0) {
- clk_stm32_enable_call_ops(priv, clk_id);
- } else {
- clk_stm32_disable_call_ops(priv, clk_id);
- }
- return 0;
- }
- static int stm32_clk_configure_mux(struct stm32_clk_priv *priv, uint32_t data)
- {
- int mux = (data & MUX_ID_MASK) >> MUX_ID_SHIFT;
- int sel = (data & MUX_SEL_MASK) >> MUX_SEL_SHIFT;
- return clk_mux_set_parent(priv, mux, sel);
- }
- static int stm32_clk_dividers_configure(struct stm32_clk_priv *priv)
- {
- struct stm32_clk_platdata *pdata = priv->pdata;
- uint32_t i;
- for (i = 0; i < pdata->nclkdiv; i++) {
- int div_id, div_n;
- int val;
- int ret;
- val = pdata->clkdiv[i] & CMD_DATA_MASK;
- div_id = (val & DIV_ID_MASK) >> DIV_ID_SHIFT;
- div_n = (val & DIV_DIVN_MASK) >> DIV_DIVN_SHIFT;
- ret = clk_stm32_set_div(priv, div_id, div_n);
- if (ret != 0) {
- return ret;
- }
- }
- return 0;
- }
- static int stm32_clk_source_configure(struct stm32_clk_priv *priv)
- {
- struct stm32_clk_platdata *pdata = priv->pdata;
- bool ckper_disabled = false;
- int clk_id;
- int ret;
- uint32_t i;
- for (i = 0; i < pdata->nclksrc; i++) {
- uint32_t val = pdata->clksrc[i];
- uint32_t cmd, cmd_data;
- if (val == (uint32_t)CLK_CKPER_DISABLED) {
- ckper_disabled = true;
- continue;
- }
- if (val == (uint32_t)CLK_RTC_DISABLED) {
- continue;
- }
- cmd = (val & CMD_MASK) >> CMD_SHIFT;
- cmd_data = val & ~CMD_MASK;
- switch (cmd) {
- case CMD_MUX:
- ret = stm32_clk_configure_mux(priv, cmd_data);
- break;
- case CMD_CLK:
- clk_id = stm32_clk_configure_clk_get_binding_id(priv, cmd_data);
- if (clk_id == _RTCCK) {
- if ((_clk_stm32_is_enabled(priv, _RTCCK) == true)) {
- continue;
- }
- }
- ret = stm32_clk_configure_clk(priv, cmd_data);
- break;
- default:
- ret = -EINVAL;
- break;
- }
- if (ret != 0) {
- return ret;
- }
- }
- /*
- * CKPER is source for some peripheral clocks
- * (FMC-NAND / QPSI-NOR) and switching source is allowed
- * only if previous clock is still ON
- * => deactivate CKPER only after switching clock
- */
- if (ckper_disabled) {
- ret = stm32_clk_configure_mux(priv, CLK_CKPER_DISABLED);
- if (ret != 0) {
- return ret;
- }
- }
- return 0;
- }
- static int stm32_clk_stgen_configure(struct stm32_clk_priv *priv, int id)
- {
- unsigned long stgen_freq;
- stgen_freq = _clk_stm32_get_rate(priv, id);
- stm32mp_stgen_config(stgen_freq);
- return 0;
- }
- #define CLK_PLL_CFG(_idx, _clk_id, _type, _reg)\
- [(_idx)] = {\
- .clk_id = (_clk_id),\
- .plltype = (_type),\
- .reg_pllxcr = (_reg),\
- }
- static int clk_stm32_pll_compute_cfgr1(struct stm32_clk_priv *priv,
- const struct stm32_clk_pll *pll,
- struct stm32_pll_vco *vco,
- uint32_t *value)
- {
- uint32_t divm = vco->div_mn[PLL_CFG_M];
- uint32_t divn = vco->div_mn[PLL_CFG_N];
- unsigned long prate = 0UL;
- unsigned long refclk = 0UL;
- prate = _clk_stm32_get_parent_rate(priv, pll->clk_id);
- refclk = prate / (divm + 1U);
- if ((refclk < (stm32mp1_pll[pll->plltype].refclk_min * 1000000U)) ||
- (refclk > (stm32mp1_pll[pll->plltype].refclk_max * 1000000U))) {
- return -EINVAL;
- }
- *value = 0;
- if ((pll->plltype == PLL_800) && (refclk >= 8000000U)) {
- *value = 1U << RCC_PLLNCFGR1_IFRGE_SHIFT;
- }
- *value |= (divn << RCC_PLLNCFGR1_DIVN_SHIFT) & RCC_PLLNCFGR1_DIVN_MASK;
- *value |= (divm << RCC_PLLNCFGR1_DIVM_SHIFT) & RCC_PLLNCFGR1_DIVM_MASK;
- return 0;
- }
- static uint32_t clk_stm32_pll_compute_cfgr2(struct stm32_pll_output *out)
- {
- uint32_t value = 0;
- value |= (out->output[PLL_CFG_P] << RCC_PLLNCFGR2_DIVP_SHIFT) & RCC_PLLNCFGR2_DIVP_MASK;
- value |= (out->output[PLL_CFG_Q] << RCC_PLLNCFGR2_DIVQ_SHIFT) & RCC_PLLNCFGR2_DIVQ_MASK;
- value |= (out->output[PLL_CFG_R] << RCC_PLLNCFGR2_DIVR_SHIFT) & RCC_PLLNCFGR2_DIVR_MASK;
- return value;
- }
- static void clk_stm32_pll_config_vco(struct stm32_clk_priv *priv,
- const struct stm32_clk_pll *pll,
- struct stm32_pll_vco *vco)
- {
- uintptr_t pll_base = priv->base + pll->reg_pllxcr;
- uint32_t value = 0;
- if (clk_stm32_pll_compute_cfgr1(priv, pll, vco, &value) != 0) {
- EARLY_ERROR("Invalid Vref clock !\n");
- panic();
- }
- /* Write N / M / IFREGE fields */
- mmio_write_32(pll_base + RCC_OFFSET_PLLXCFGR1, value);
- /* Fractional configuration */
- mmio_write_32(pll_base + RCC_OFFSET_PLLXFRACR, 0);
- /* Frac must be enabled only once its configuration is loaded */
- mmio_write_32(pll_base + RCC_OFFSET_PLLXFRACR, vco->frac << RCC_PLLNFRACR_FRACV_SHIFT);
- mmio_setbits_32(pll_base + RCC_OFFSET_PLLXFRACR, RCC_PLLNFRACR_FRACLE);
- }
- static void clk_stm32_pll_config_csg(struct stm32_clk_priv *priv,
- const struct stm32_clk_pll *pll,
- struct stm32_pll_vco *vco)
- {
- uintptr_t pll_base = priv->base + pll->reg_pllxcr;
- uint32_t mod_per = 0;
- uint32_t inc_step = 0;
- uint32_t sscg_mode = 0;
- uint32_t value = 0;
- if (!vco->csg_enabled) {
- return;
- }
- mod_per = vco->csg[PLL_CSG_MOD_PER];
- inc_step = vco->csg[PLL_CSG_INC_STEP];
- sscg_mode = vco->csg[PLL_CSG_SSCG_MODE];
- value |= (mod_per << RCC_PLLNCSGR_MOD_PER_SHIFT) & RCC_PLLNCSGR_MOD_PER_MASK;
- value |= (inc_step << RCC_PLLNCSGR_INC_STEP_SHIFT) & RCC_PLLNCSGR_INC_STEP_MASK;
- value |= (sscg_mode << RCC_PLLNCSGR_SSCG_MODE_SHIFT) & RCC_PLLNCSGR_SSCG_MODE_MASK;
- mmio_write_32(pll_base + RCC_OFFSET_PLLXCSGR, value);
- mmio_setbits_32(pll_base + RCC_OFFSET_PLLXCR, RCC_PLLNCR_SSCG_CTRL);
- }
- static void clk_stm32_pll_config_out(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll,
- struct stm32_pll_output *out)
- {
- uintptr_t pll_base = priv->base + pll->reg_pllxcr;
- uint32_t value = 0;
- value = clk_stm32_pll_compute_cfgr2(out);
- mmio_write_32(pll_base + RCC_OFFSET_PLLXCFGR2, value);
- }
- static inline struct stm32_pll_dt_cfg *clk_stm32_pll_get_pdata(int pll_idx)
- {
- struct stm32_clk_priv *priv = clk_stm32_get_priv();
- struct stm32_clk_platdata *pdata = priv->pdata;
- return &pdata->pll[pll_idx];
- }
- /* Define characteristic for PLL1 : PLL_2000 */
- #define POST_DIVM_MIN 8000000U
- #define POST_DIVM_MAX 16000000U
- #define DIVM_MIN 0U
- #define DIVM_MAX 63U
- #define DIVN_MIN 24U
- #define DIVN_MAX 99U
- #define DIVP_MIN 0U
- #define DIVP_MAX 127U
- #define FRAC_MAX 8192U
- #define VCO_MIN 992000000U
- #define VCO_MAX 2000000000U
- static int clk_compute_pll1_settings(uint32_t freq_khz)
- {
- struct stm32_clk_priv *priv = clk_stm32_get_priv();
- struct stm32_pll_dt_cfg *pll1 = clk_stm32_pll_get_pdata(_PLL1);
- struct stm32_pll_dt_cfg *pll2 = clk_stm32_pll_get_pdata(_PLL2);
- unsigned long long best_diff = ULLONG_MAX;
- unsigned int divm;
- unsigned long input_freq = 0UL;
- uint32_t src = pll2->vco.src;
- /* PLL1 share the same clock source than PLL2 */
- switch (src) {
- case CLK_PLL12_HSI:
- input_freq = _clk_stm32_get_rate(priv, _CK_HSI);
- break;
- case CLK_PLL12_HSE:
- input_freq = _clk_stm32_get_rate(priv, _CK_HSE);
- break;
- default:
- break;
- }
- if (input_freq == 0UL) {
- panic();
- }
- /* Following parameters have always the same value */
- pll1->output.output[PLL_CFG_Q] = 0U;
- pll1->output.output[PLL_CFG_R] = 0U;
- for (divm = (DIVM_MAX + 1U); divm != DIVM_MIN; divm--) {
- unsigned long post_divm = input_freq / divm;
- unsigned int divp;
- if ((post_divm < POST_DIVM_MIN) || (post_divm > POST_DIVM_MAX)) {
- continue;
- }
- for (divp = DIVP_MIN; divp <= DIVP_MAX; divp++) {
- unsigned long long output_freq = freq_khz * 1000ULL;
- unsigned long long freq;
- unsigned long long divn;
- unsigned long long frac;
- unsigned int i;
- freq = output_freq * divm * (divp + 1U);
- divn = (freq / input_freq) - 1U;
- if ((divn < DIVN_MIN) || (divn > DIVN_MAX)) {
- continue;
- }
- frac = ((freq * FRAC_MAX) / input_freq) - ((divn + 1U) * FRAC_MAX);
- /* 2 loops to refine the fractional part */
- for (i = 2U; i != 0U; i--) {
- unsigned long long diff;
- unsigned long long vco;
- if (frac > FRAC_MAX) {
- break;
- }
- vco = (post_divm * (divn + 1U)) + ((post_divm * frac) / FRAC_MAX);
- if ((vco < (VCO_MIN / 2U)) || (vco > (VCO_MAX / 2U))) {
- frac++;
- continue;
- }
- freq = vco / (divp + 1U);
- if (output_freq < freq) {
- diff = freq - output_freq;
- } else {
- diff = output_freq - freq;
- }
- if (diff < best_diff) {
- pll1->vco.src = src;
- pll1->vco.status = RCC_PLLNCR_DIVPEN | RCC_PLLNCR_PLLON;
- pll1->vco.div_mn[PLL_CFG_M] = divm - 1U;
- pll1->vco.div_mn[PLL_CFG_N] = (uint32_t)divn;
- pll1->vco.frac = (uint32_t)frac;
- pll1->output.output[PLL_CFG_P] = divp;
- if (diff == 0U) {
- return 0;
- }
- best_diff = diff;
- }
- frac++;
- }
- }
- }
- if (best_diff == ULLONG_MAX) {
- return -EINVAL;
- }
- return 0;
- }
- static bool _clk_stm32_pll_is_enabled(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
- {
- uintptr_t pll_base = priv->base + pll->reg_pllxcr;
- return ((mmio_read_32(pll_base) & RCC_PLLNCR_PLLON) != 0U);
- }
- static void _clk_stm32_pll_set_on(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
- {
- uintptr_t pll_base = priv->base + pll->reg_pllxcr;
- /* Preserve RCC_PLLNCR_SSCG_CTRL value */
- mmio_clrsetbits_32(pll_base, RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | RCC_PLLNCR_DIVREN,
- RCC_PLLNCR_PLLON);
- }
- static void _clk_stm32_pll_set_off(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
- {
- uintptr_t pll_base = priv->base + pll->reg_pllxcr;
- /* Stop all output */
- mmio_clrbits_32(pll_base, RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | RCC_PLLNCR_DIVREN);
- /* Stop PLL */
- mmio_clrbits_32(pll_base, RCC_PLLNCR_PLLON);
- }
- static int _clk_stm32_pll_wait_ready_on(struct stm32_clk_priv *priv,
- const struct stm32_clk_pll *pll)
- {
- uintptr_t pll_base = priv->base + pll->reg_pllxcr;
- uint64_t timeout = timeout_init_us(PLLRDY_TIMEOUT);
- /* Wait PLL lock */
- while ((mmio_read_32(pll_base) & RCC_PLLNCR_PLLRDY) == 0U) {
- if (timeout_elapsed(timeout)) {
- ERROR("PLL%d start failed @ 0x%x: 0x%x\n",
- pll->clk_id - _CK_PLL1 + 1, pll->reg_pllxcr, mmio_read_32(pll_base));
- return -EINVAL;
- }
- }
- return 0;
- }
- static int _clk_stm32_pll_wait_ready_off(struct stm32_clk_priv *priv,
- const struct stm32_clk_pll *pll)
- {
- uintptr_t pll_base = priv->base + pll->reg_pllxcr;
- uint64_t timeout = timeout_init_us(PLLRDY_TIMEOUT);
- /* Wait PLL lock */
- while ((mmio_read_32(pll_base) & RCC_PLLNCR_PLLRDY) != 0U) {
- if (timeout_elapsed(timeout)) {
- ERROR("PLL%d stop failed @ 0x%x: 0x%x\n",
- pll->clk_id - _CK_PLL1 + 1, pll->reg_pllxcr, mmio_read_32(pll_base));
- return -EINVAL;
- }
- }
- return 0;
- }
- static int _clk_stm32_pll_enable(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
- {
- if (_clk_stm32_pll_is_enabled(priv, pll)) {
- return 0;
- }
- /* Preserve RCC_PLLNCR_SSCG_CTRL value */
- _clk_stm32_pll_set_on(priv, pll);
- /* Wait PLL lock */
- return _clk_stm32_pll_wait_ready_on(priv, pll);
- }
- static void _clk_stm32_pll_disable(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
- {
- if (!_clk_stm32_pll_is_enabled(priv, pll)) {
- return;
- }
- /* Stop all outputs and the PLL */
- _clk_stm32_pll_set_off(priv, pll);
- /* Wait PLL stopped */
- _clk_stm32_pll_wait_ready_off(priv, pll);
- }
- static int _clk_stm32_pll_init(struct stm32_clk_priv *priv, int pll_idx,
- struct stm32_pll_dt_cfg *pll_conf)
- {
- const struct stm32_clk_pll *pll = clk_st32_pll_data(pll_idx);
- uintptr_t pll_base = priv->base + pll->reg_pllxcr;
- int ret = 0;
- /* Configure PLLs source */
- ret = stm32_clk_configure_mux(priv, pll_conf->vco.src);
- if (ret != 0) {
- return ret;
- }
- #if STM32MP_USB_PROGRAMMER
- if ((pll_idx == _PLL4) && pll4_bootrom) {
- clk_stm32_pll_config_out(priv, pll, &pll_conf->output);
- mmio_setbits_32(pll_base,
- RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | RCC_PLLNCR_DIVREN);
- return 0;
- }
- #endif
- /* Stop the PLL before */
- _clk_stm32_pll_disable(priv, pll);
- clk_stm32_pll_config_vco(priv, pll, &pll_conf->vco);
- clk_stm32_pll_config_out(priv, pll, &pll_conf->output);
- clk_stm32_pll_config_csg(priv, pll, &pll_conf->vco);
- ret = _clk_stm32_pll_enable(priv, pll);
- if (ret != 0) {
- return ret;
- }
- mmio_setbits_32(pll_base, RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | RCC_PLLNCR_DIVREN);
- return 0;
- }
- static int clk_stm32_pll_init(struct stm32_clk_priv *priv, int pll_idx)
- {
- struct stm32_pll_dt_cfg *pll_conf = clk_stm32_pll_get_pdata(pll_idx);
- if (pll_conf->vco.status != 0U) {
- return _clk_stm32_pll_init(priv, pll_idx, pll_conf);
- }
- return 0;
- }
- static int stm32_clk_pll_configure(struct stm32_clk_priv *priv)
- {
- int err = 0;
- err = clk_stm32_pll_init(priv, _PLL1);
- if (err != 0) {
- return err;
- }
- err = clk_stm32_pll_init(priv, _PLL2);
- if (err != 0) {
- return err;
- }
- err = clk_stm32_pll_init(priv, _PLL3);
- if (err != 0) {
- return err;
- }
- err = clk_stm32_pll_init(priv, _PLL4);
- if (err != 0) {
- return err;
- }
- return 0;
- }
- static int stm32_clk_oscillators_wait_lse_ready(struct stm32_clk_priv *priv)
- {
- int ret = 0;
- if (_clk_stm32_get_rate(priv, _CK_LSE) != 0U) {
- ret = clk_oscillator_wait_ready_on(priv, _CK_LSE);
- }
- return ret;
- }
- static void stm32_clk_oscillators_enable(struct stm32_clk_priv *priv)
- {
- stm32_enable_oscillator_hse(priv);
- stm32_enable_oscillator_lse(priv);
- _clk_stm32_enable(priv, _CK_LSI);
- _clk_stm32_enable(priv, _CK_CSI);
- }
- static int stm32_clk_hsidiv_configure(struct stm32_clk_priv *priv)
- {
- return stm32mp1_hsidiv(_clk_stm32_get_rate(priv, _CK_HSI));
- }
- #if STM32MP_USB_PROGRAMMER
- static bool stm32mp1_clk_is_pll4_used_by_bootrom(struct stm32_clk_priv *priv, int usbphy_p)
- {
- /* Don't initialize PLL4, when used by BOOTROM */
- if ((stm32mp_get_boot_itf_selected() ==
- BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB) &&
- (usbphy_p == _PLL4R)) {
- return true;
- }
- return false;
- }
- static int stm32mp1_clk_check_usb_conflict(struct stm32_clk_priv *priv, int usbphy_p, int usbo_p)
- {
- int _usbo_p;
- int _usbphy_p;
- if (!pll4_bootrom) {
- return 0;
- }
- _usbo_p = _clk_stm32_get_parent(priv, _USBO_K);
- _usbphy_p = _clk_stm32_get_parent(priv, _USBPHY_K);
- if ((_usbo_p != usbo_p) || (_usbphy_p != usbphy_p)) {
- return -FDT_ERR_BADVALUE;
- }
- return 0;
- }
- #endif
- static struct clk_oscillator_data stm32mp13_osc_data[NB_OSCILLATOR] = {
- OSCILLATOR(OSC_HSI, _CK_HSI, "clk-hsi", GATE_HSI, GATE_HSI_RDY,
- NULL, NULL, NULL),
- OSCILLATOR(OSC_LSI, _CK_LSI, "clk-lsi", GATE_LSI, GATE_LSI_RDY,
- NULL, NULL, NULL),
- OSCILLATOR(OSC_CSI, _CK_CSI, "clk-csi", GATE_CSI, GATE_CSI_RDY,
- NULL, NULL, NULL),
- OSCILLATOR(OSC_LSE, _CK_LSE, "clk-lse", GATE_LSE, GATE_LSE_RDY,
- BYPASS(RCC_BDCR, 1, 3),
- CSS(RCC_BDCR, 8),
- DRIVE(RCC_BDCR, 4, 2, 2)),
- OSCILLATOR(OSC_HSE, _CK_HSE, "clk-hse", GATE_HSE, GATE_HSE_RDY,
- BYPASS(RCC_OCENSETR, 10, 7),
- CSS(RCC_OCENSETR, 11),
- NULL),
- OSCILLATOR(OSC_I2SCKIN, _I2SCKIN, "i2s_ckin", NO_GATE, NO_GATE,
- NULL, NULL, NULL),
- };
- static const char *clk_stm32_get_oscillator_name(enum stm32_osc id)
- {
- if (id < NB_OSCILLATOR) {
- return stm32mp13_osc_data[id].name;
- }
- return NULL;
- }
- #define CLK_PLL_CFG(_idx, _clk_id, _type, _reg)\
- [(_idx)] = {\
- .clk_id = (_clk_id),\
- .plltype = (_type),\
- .reg_pllxcr = (_reg),\
- }
- static const struct stm32_clk_pll stm32_mp13_clk_pll[_PLL_NB] = {
- CLK_PLL_CFG(_PLL1, _CK_PLL1, PLL_2000, RCC_PLL1CR),
- CLK_PLL_CFG(_PLL2, _CK_PLL2, PLL_1600, RCC_PLL2CR),
- CLK_PLL_CFG(_PLL3, _CK_PLL3, PLL_800, RCC_PLL3CR),
- CLK_PLL_CFG(_PLL4, _CK_PLL4, PLL_800, RCC_PLL4CR),
- };
- static const struct stm32_clk_pll *clk_st32_pll_data(unsigned int idx)
- {
- return &stm32_mp13_clk_pll[idx];
- }
- struct stm32_pll_cfg {
- uint8_t pll_id;
- };
- static unsigned long clk_stm32_pll_recalc_rate(struct stm32_clk_priv *priv, int id,
- unsigned long prate)
- {
- const struct clk_stm32 *clk = _clk_get(priv, id);
- struct stm32_pll_cfg *pll_cfg = clk->clock_cfg;
- const struct stm32_clk_pll *pll = clk_st32_pll_data(pll_cfg->pll_id);
- uintptr_t pll_base = priv->base + pll->reg_pllxcr;
- uint32_t cfgr1, fracr, divm, divn;
- unsigned long fvco;
- cfgr1 = mmio_read_32(pll_base + RCC_OFFSET_PLLXCFGR1);
- fracr = mmio_read_32(pll_base + RCC_OFFSET_PLLXFRACR);
- divm = (cfgr1 & (RCC_PLLNCFGR1_DIVM_MASK)) >> RCC_PLLNCFGR1_DIVM_SHIFT;
- divn = cfgr1 & RCC_PLLNCFGR1_DIVN_MASK;
- /*
- * With FRACV :
- * Fvco = Fck_ref * ((DIVN + 1) + FRACV / 2^13) / (DIVM + 1)
- * Without FRACV
- * Fvco = Fck_ref * ((DIVN + 1) / (DIVM + 1)
- */
- if ((fracr & RCC_PLLNFRACR_FRACLE) != 0U) {
- uint32_t fracv = (fracr & RCC_PLLNFRACR_FRACV_MASK) >>
- RCC_PLLNFRACR_FRACV_SHIFT;
- unsigned long long numerator, denominator;
- numerator = (((unsigned long long)divn + 1U) << 13) + fracv;
- numerator = prate * numerator;
- denominator = ((unsigned long long)divm + 1U) << 13;
- fvco = (unsigned long)(numerator / denominator);
- } else {
- fvco = (unsigned long)(prate * (divn + 1U) / (divm + 1U));
- }
- return fvco;
- };
- static bool clk_stm32_pll_is_enabled(struct stm32_clk_priv *priv, int id)
- {
- const struct clk_stm32 *clk = _clk_get(priv, id);
- struct stm32_pll_cfg *pll_cfg = clk->clock_cfg;
- const struct stm32_clk_pll *pll = clk_st32_pll_data(pll_cfg->pll_id);
- return _clk_stm32_pll_is_enabled(priv, pll);
- }
- static int clk_stm32_pll_enable(struct stm32_clk_priv *priv, int id)
- {
- const struct clk_stm32 *clk = _clk_get(priv, id);
- struct stm32_pll_cfg *pll_cfg = clk->clock_cfg;
- const struct stm32_clk_pll *pll = clk_st32_pll_data(pll_cfg->pll_id);
- return _clk_stm32_pll_enable(priv, pll);
- }
- static void clk_stm32_pll_disable(struct stm32_clk_priv *priv, int id)
- {
- const struct clk_stm32 *clk = _clk_get(priv, id);
- struct stm32_pll_cfg *pll_cfg = clk->clock_cfg;
- const struct stm32_clk_pll *pll = clk_st32_pll_data(pll_cfg->pll_id);
- _clk_stm32_pll_disable(priv, pll);
- }
- static const struct stm32_clk_ops clk_stm32_pll_ops = {
- .recalc_rate = clk_stm32_pll_recalc_rate,
- .enable = clk_stm32_pll_enable,
- .disable = clk_stm32_pll_disable,
- .is_enabled = clk_stm32_pll_is_enabled,
- };
- #define CLK_PLL(idx, _idx, _parent, _gate, _pll_id, _flags)[idx] = {\
- .binding = _idx,\
- .parent = _parent,\
- .flags = (_flags),\
- .clock_cfg = &(struct stm32_pll_cfg) {\
- .pll_id = _pll_id,\
- },\
- .ops = STM32_PLL_OPS,\
- }
- struct clk_stm32_composite_cfg {
- uint8_t gate_id;
- uint8_t div_id;
- };
- static unsigned long clk_stm32_composite_recalc_rate(struct stm32_clk_priv *priv,
- int idx, unsigned long prate)
- {
- const struct clk_stm32 *clk = _clk_get(priv, idx);
- struct clk_stm32_composite_cfg *composite_cfg = clk->clock_cfg;
- return _clk_stm32_divider_recalc(priv, composite_cfg->div_id, prate);
- };
- static bool clk_stm32_composite_gate_is_enabled(struct stm32_clk_priv *priv, int idx)
- {
- const struct clk_stm32 *clk = _clk_get(priv, idx);
- struct clk_stm32_composite_cfg *composite_cfg = clk->clock_cfg;
- return _clk_stm32_gate_is_enabled(priv, composite_cfg->gate_id);
- }
- static int clk_stm32_composite_gate_enable(struct stm32_clk_priv *priv, int idx)
- {
- const struct clk_stm32 *clk = _clk_get(priv, idx);
- struct clk_stm32_composite_cfg *composite_cfg = clk->clock_cfg;
- return _clk_stm32_gate_enable(priv, composite_cfg->gate_id);
- }
- static void clk_stm32_composite_gate_disable(struct stm32_clk_priv *priv, int idx)
- {
- const struct clk_stm32 *clk = _clk_get(priv, idx);
- struct clk_stm32_composite_cfg *composite_cfg = clk->clock_cfg;
- _clk_stm32_gate_disable(priv, composite_cfg->gate_id);
- }
- static const struct stm32_clk_ops clk_stm32_composite_ops = {
- .recalc_rate = clk_stm32_composite_recalc_rate,
- .is_enabled = clk_stm32_composite_gate_is_enabled,
- .enable = clk_stm32_composite_gate_enable,
- .disable = clk_stm32_composite_gate_disable,
- };
- #define STM32_COMPOSITE(idx, _binding, _parent, _flags, _gate_id,\
- _div_id)[idx] = {\
- .binding = (_binding),\
- .parent = (_parent),\
- .flags = (_flags),\
- .clock_cfg = &(struct clk_stm32_composite_cfg) {\
- .gate_id = (_gate_id),\
- .div_id = (_div_id),\
- },\
- .ops = STM32_COMPOSITE_OPS,\
- }
- enum {
- STM32_PLL_OPS = STM32_LAST_OPS,
- STM32_COMPOSITE_OPS,
- MP13_LAST_OPS
- };
- static const struct stm32_clk_ops *ops_array_mp13[MP13_LAST_OPS] = {
- [NO_OPS] = NULL,
- [FIXED_FACTOR_OPS] = &clk_fixed_factor_ops,
- [GATE_OPS] = &clk_gate_ops,
- [STM32_MUX_OPS] = &clk_mux_ops,
- [STM32_DIVIDER_OPS] = &clk_stm32_divider_ops,
- [STM32_GATE_OPS] = &clk_stm32_gate_ops,
- [STM32_TIMER_OPS] = &clk_timer_ops,
- [STM32_FIXED_RATE_OPS] = &clk_stm32_fixed_rate_ops,
- [STM32_OSC_OPS] = &clk_stm32_osc_ops,
- [STM32_OSC_NOGATE_OPS] = &clk_stm32_osc_nogate_ops,
- [STM32_PLL_OPS] = &clk_stm32_pll_ops,
- [STM32_COMPOSITE_OPS] = &clk_stm32_composite_ops
- };
- static const struct clk_stm32 stm32mp13_clk[CK_LAST] = {
- /* ROOT CLOCKS */
- CLK_FIXED_RATE(_CK_OFF, _NO_ID, 0),
- CLK_OSC(_CK_HSE, CK_HSE, CLK_IS_ROOT, OSC_HSE),
- CLK_OSC(_CK_HSI, CK_HSI, CLK_IS_ROOT, OSC_HSI),
- CLK_OSC(_CK_CSI, CK_CSI, CLK_IS_ROOT, OSC_CSI),
- CLK_OSC(_CK_LSI, CK_LSI, CLK_IS_ROOT, OSC_LSI),
- CLK_OSC(_CK_LSE, CK_LSE, CLK_IS_ROOT, OSC_LSE),
- CLK_OSC_FIXED(_I2SCKIN, _NO_ID, CLK_IS_ROOT, OSC_I2SCKIN),
- CLK_FIXED_RATE(_USB_PHY_48, _NO_ID, USB_PHY_48_MHZ),
- STM32_DIV(_HSE_DIV, _NO_ID, _CK_HSE, 0, DIV_RTC),
- FIXED_FACTOR(_HSE_DIV2, CK_HSE_DIV2, _CK_HSE, 1, 2),
- FIXED_FACTOR(_CSI_DIV122, _NO_ID, _CK_CSI, 1, 122),
- CLK_PLL(_CK_PLL1, PLL1, MUX(MUX_PLL12), GATE_PLL1, _PLL1, 0),
- CLK_PLL(_CK_PLL2, PLL2, MUX(MUX_PLL12), GATE_PLL2, _PLL2, 0),
- CLK_PLL(_CK_PLL3, PLL3, MUX(MUX_PLL3), GATE_PLL3, _PLL3, 0),
- CLK_PLL(_CK_PLL4, PLL4, MUX(MUX_PLL4), GATE_PLL4, _PLL4, 0),
- STM32_COMPOSITE(_PLL1P, PLL1_P, _CK_PLL1, CLK_IS_CRITICAL, GATE_PLL1_DIVP, DIV_PLL1DIVP),
- STM32_DIV(_PLL1P_DIV, _NO_ID, _CK_PLL1, 0, DIV_MPU),
- STM32_COMPOSITE(_PLL2P, PLL2_P, _CK_PLL2, CLK_IS_CRITICAL, GATE_PLL2_DIVP, DIV_PLL2DIVP),
- STM32_COMPOSITE(_PLL2Q, PLL2_Q, _CK_PLL2, 0, GATE_PLL2_DIVQ, DIV_PLL2DIVQ),
- STM32_COMPOSITE(_PLL2R, PLL2_R, _CK_PLL2, CLK_IS_CRITICAL, GATE_PLL2_DIVR, DIV_PLL2DIVR),
- STM32_COMPOSITE(_PLL3P, PLL3_P, _CK_PLL3, 0, GATE_PLL3_DIVP, DIV_PLL3DIVP),
- STM32_COMPOSITE(_PLL3Q, PLL3_Q, _CK_PLL3, 0, GATE_PLL3_DIVQ, DIV_PLL3DIVQ),
- STM32_COMPOSITE(_PLL3R, PLL3_R, _CK_PLL3, 0, GATE_PLL3_DIVR, DIV_PLL3DIVR),
- STM32_COMPOSITE(_PLL4P, PLL4_P, _CK_PLL4, 0, GATE_PLL4_DIVP, DIV_PLL4DIVP),
- STM32_COMPOSITE(_PLL4Q, PLL4_Q, _CK_PLL4, 0, GATE_PLL4_DIVQ, DIV_PLL4DIVQ),
- STM32_COMPOSITE(_PLL4R, PLL4_R, _CK_PLL4, 0, GATE_PLL4_DIVR, DIV_PLL4DIVR),
- STM32_MUX(_CKMPU, CK_MPU, MUX_MPU, 0),
- STM32_DIV(_CKAXI, CK_AXI, MUX(MUX_AXI), 0, DIV_AXI),
- STM32_DIV(_CKMLAHB, CK_MLAHB, MUX(MUX_MLAHB), CLK_IS_CRITICAL, DIV_MLAHB),
- STM32_MUX(_CKPER, CK_PER, MUX(MUX_CKPER), 0),
- STM32_DIV(_PCLK1, PCLK1, _CKMLAHB, 0, DIV_APB1),
- STM32_DIV(_PCLK2, PCLK2, _CKMLAHB, 0, DIV_APB2),
- STM32_DIV(_PCLK3, PCLK3, _CKMLAHB, 0, DIV_APB3),
- STM32_DIV(_PCLK4, PCLK4, _CKAXI, 0, DIV_APB4),
- STM32_DIV(_PCLK5, PCLK5, _CKAXI, 0, DIV_APB5),
- STM32_DIV(_PCLK6, PCLK6, _CKMLAHB, 0, DIV_APB6),
- CK_TIMER(_CKTIMG1, CK_TIMG1, _PCLK1, 0, RCC_APB1DIVR, RCC_TIMG1PRER),
- CK_TIMER(_CKTIMG2, CK_TIMG2, _PCLK2, 0, RCC_APB2DIVR, RCC_TIMG2PRER),
- CK_TIMER(_CKTIMG3, CK_TIMG3, _PCLK6, 0, RCC_APB6DIVR, RCC_TIMG3PRER),
- /* END ROOT CLOCKS */
- STM32_GATE(_DDRC1, DDRC1, _CKAXI, CLK_IS_CRITICAL, GATE_DDRC1),
- STM32_GATE(_DDRC1LP, DDRC1LP, _CKAXI, CLK_IS_CRITICAL, GATE_DDRC1LP),
- STM32_GATE(_DDRPHYC, DDRPHYC, _PLL2R, CLK_IS_CRITICAL, GATE_DDRPHYC),
- STM32_GATE(_DDRPHYCLP, DDRPHYCLP, _PLL2R, CLK_IS_CRITICAL, GATE_DDRPHYCLP),
- STM32_GATE(_DDRCAPB, DDRCAPB, _PCLK4, CLK_IS_CRITICAL, GATE_DDRCAPB),
- STM32_GATE(_DDRCAPBLP, DDRCAPBLP, _PCLK4, CLK_IS_CRITICAL, GATE_DDRCAPBLP),
- STM32_GATE(_AXIDCG, AXIDCG, _CKAXI, CLK_IS_CRITICAL, GATE_AXIDCG),
- STM32_GATE(_DDRPHYCAPB, DDRPHYCAPB, _PCLK4, CLK_IS_CRITICAL, GATE_DDRPHYCAPB),
- STM32_GATE(_DDRPHYCAPBLP, DDRPHYCAPBLP, _PCLK4, CLK_IS_CRITICAL, GATE_DDRPHYCAPBLP),
- STM32_GATE(_SYSCFG, SYSCFG, _PCLK3, 0, GATE_SYSCFG),
- STM32_GATE(_DDRPERFM, DDRPERFM, _PCLK4, 0, GATE_DDRPERFM),
- STM32_GATE(_IWDG2APB, IWDG2, _PCLK4, 0, GATE_IWDG2APB),
- STM32_GATE(_USBPHY_K, USBPHY_K, MUX(MUX_USBPHY), 0, GATE_USBPHY),
- STM32_GATE(_USBO_K, USBO_K, MUX(MUX_USBO), 0, GATE_USBO),
- STM32_GATE(_RTCAPB, RTCAPB, _PCLK5, CLK_IS_CRITICAL, GATE_RTCAPB),
- STM32_GATE(_TZC, TZC, _PCLK5, CLK_IS_CRITICAL, GATE_TZC),
- STM32_GATE(_ETZPC, TZPC, _PCLK5, CLK_IS_CRITICAL, GATE_ETZPC),
- STM32_GATE(_IWDG1APB, IWDG1, _PCLK5, 0, GATE_IWDG1APB),
- STM32_GATE(_BSEC, BSEC, _PCLK5, CLK_IS_CRITICAL, GATE_BSEC),
- STM32_GATE(_STGENC, STGEN_K, MUX(MUX_STGEN), CLK_IS_CRITICAL, GATE_STGENC),
- STM32_GATE(_USART1_K, USART1_K, MUX(MUX_UART1), 0, GATE_USART1),
- STM32_GATE(_USART2_K, USART2_K, MUX(MUX_UART2), 0, GATE_USART2),
- STM32_GATE(_I2C3_K, I2C3_K, MUX(MUX_I2C3), 0, GATE_I2C3),
- STM32_GATE(_I2C4_K, I2C4_K, MUX(MUX_I2C4), 0, GATE_I2C4),
- STM32_GATE(_I2C5_K, I2C5_K, MUX(MUX_I2C5), 0, GATE_I2C5),
- STM32_GATE(_TIM12, TIM12_K, _CKTIMG3, 0, GATE_TIM12),
- STM32_GATE(_TIM15, TIM15_K, _CKTIMG3, 0, GATE_TIM15),
- STM32_GATE(_RTCCK, RTC, MUX(MUX_RTC), 0, GATE_RTCCK),
- STM32_GATE(_GPIOA, GPIOA, _CKMLAHB, 0, GATE_GPIOA),
- STM32_GATE(_GPIOB, GPIOB, _CKMLAHB, 0, GATE_GPIOB),
- STM32_GATE(_GPIOC, GPIOC, _CKMLAHB, 0, GATE_GPIOC),
- STM32_GATE(_GPIOD, GPIOD, _CKMLAHB, 0, GATE_GPIOD),
- STM32_GATE(_GPIOE, GPIOE, _CKMLAHB, 0, GATE_GPIOE),
- STM32_GATE(_GPIOF, GPIOF, _CKMLAHB, 0, GATE_GPIOF),
- STM32_GATE(_GPIOG, GPIOG, _CKMLAHB, 0, GATE_GPIOG),
- STM32_GATE(_GPIOH, GPIOH, _CKMLAHB, 0, GATE_GPIOH),
- STM32_GATE(_GPIOI, GPIOI, _CKMLAHB, 0, GATE_GPIOI),
- STM32_GATE(_PKA, PKA, _CKAXI, 0, GATE_PKA),
- STM32_GATE(_SAES_K, SAES_K, MUX(MUX_SAES), 0, GATE_SAES),
- STM32_GATE(_CRYP1, CRYP1, _PCLK5, 0, GATE_CRYP1),
- STM32_GATE(_HASH1, HASH1, _PCLK5, 0, GATE_HASH1),
- STM32_GATE(_RNG1_K, RNG1_K, MUX(MUX_RNG1), 0, GATE_RNG1),
- STM32_GATE(_BKPSRAM, BKPSRAM, _PCLK5, CLK_IS_CRITICAL, GATE_BKPSRAM),
- STM32_GATE(_SDMMC1_K, SDMMC1_K, MUX(MUX_SDMMC1), 0, GATE_SDMMC1),
- STM32_GATE(_SDMMC2_K, SDMMC2_K, MUX(MUX_SDMMC2), 0, GATE_SDMMC2),
- STM32_GATE(_DBGCK, CK_DBG, _CKAXI, 0, GATE_DBGCK),
- STM32_GATE(_USART3_K, USART3_K, MUX(MUX_UART35), 0, GATE_USART3),
- STM32_GATE(_UART4_K, UART4_K, MUX(MUX_UART4), 0, GATE_UART4),
- STM32_GATE(_UART5_K, UART5_K, MUX(MUX_UART35), 0, GATE_UART5),
- STM32_GATE(_UART7_K, UART7_K, MUX(MUX_UART78), 0, GATE_UART7),
- STM32_GATE(_UART8_K, UART8_K, MUX(MUX_UART78), 0, GATE_UART8),
- STM32_GATE(_USART6_K, USART6_K, MUX(MUX_UART6), 0, GATE_USART6),
- STM32_GATE(_MCE, MCE, _CKAXI, CLK_IS_CRITICAL, GATE_MCE),
- STM32_GATE(_FMC_K, FMC_K, MUX(MUX_FMC), 0, GATE_FMC),
- STM32_GATE(_QSPI_K, QSPI_K, MUX(MUX_QSPI), 0, GATE_QSPI),
- STM32_COMPOSITE(_MCO1_K, CK_MCO1, MUX(MUX_MCO1), 0, GATE_MCO1, DIV_MCO1),
- STM32_COMPOSITE(_MCO2_K, CK_MCO2, MUX(MUX_MCO2), 0, GATE_MCO2, DIV_MCO2),
- STM32_COMPOSITE(_TRACECK, CK_TRACE, _CKAXI, 0, GATE_TRACECK, DIV_TRACE),
- };
- static struct stm32_pll_dt_cfg mp13_pll[_PLL_NB];
- static struct stm32_osci_dt_cfg mp13_osci[NB_OSCILLATOR];
- static uint32_t mp13_clksrc[MUX_MAX];
- static uint32_t mp13_clkdiv[DIV_MAX];
- static struct stm32_clk_platdata stm32mp13_clock_pdata = {
- .osci = mp13_osci,
- .nosci = NB_OSCILLATOR,
- .pll = mp13_pll,
- .npll = _PLL_NB,
- .clksrc = mp13_clksrc,
- .nclksrc = MUX_MAX,
- .clkdiv = mp13_clkdiv,
- .nclkdiv = DIV_MAX,
- };
- static struct stm32_clk_priv stm32mp13_clock_data = {
- .base = RCC_BASE,
- .num = ARRAY_SIZE(stm32mp13_clk),
- .clks = stm32mp13_clk,
- .parents = parent_mp13,
- .nb_parents = ARRAY_SIZE(parent_mp13),
- .gates = gates_mp13,
- .nb_gates = ARRAY_SIZE(gates_mp13),
- .div = dividers_mp13,
- .nb_div = ARRAY_SIZE(dividers_mp13),
- .osci_data = stm32mp13_osc_data,
- .nb_osci_data = ARRAY_SIZE(stm32mp13_osc_data),
- .gate_refcounts = refcounts_mp13,
- .pdata = &stm32mp13_clock_pdata,
- .ops_array = ops_array_mp13,
- };
- static int stm32mp1_init_clock_tree(void)
- {
- struct stm32_clk_priv *priv = clk_stm32_get_priv();
- int ret;
- #if STM32MP_USB_PROGRAMMER
- int usbphy_p = _clk_stm32_get_parent(priv, _USBPHY_K);
- int usbo_p = _clk_stm32_get_parent(priv, _USBO_K);
- /* Don't initialize PLL4, when used by BOOTROM */
- pll4_bootrom = stm32mp1_clk_is_pll4_used_by_bootrom(priv, usbphy_p);
- #endif
- /*
- * Switch ON oscillators found in device-tree.
- * Note: HSI already ON after BootROM stage.
- */
- stm32_clk_oscillators_enable(priv);
- /* Come back to HSI */
- ret = stm32mp1_come_back_to_hsi();
- if (ret != 0) {
- return ret;
- }
- ret = stm32_clk_hsidiv_configure(priv);
- if (ret != 0) {
- return ret;
- }
- ret = stm32_clk_stgen_configure(priv, _STGENC);
- if (ret != 0) {
- panic();
- }
- ret = stm32_clk_dividers_configure(priv);
- if (ret != 0) {
- panic();
- }
- ret = stm32_clk_pll_configure(priv);
- if (ret != 0) {
- panic();
- }
- /* Wait LSE ready before to use it */
- ret = stm32_clk_oscillators_wait_lse_ready(priv);
- if (ret != 0) {
- panic();
- }
- /* Configure with expected clock source */
- ret = stm32_clk_source_configure(priv);
- if (ret != 0) {
- panic();
- }
- /* Configure LSE css after RTC source configuration */
- ret = stm32_clk_oscillators_lse_set_css(priv);
- if (ret != 0) {
- panic();
- }
- #if STM32MP_USB_PROGRAMMER
- ret = stm32mp1_clk_check_usb_conflict(priv, usbphy_p, usbo_p);
- if (ret != 0) {
- return ret;
- }
- #endif
- /* reconfigure STGEN with DT config */
- ret = stm32_clk_stgen_configure(priv, _STGENC);
- if (ret != 0) {
- panic();
- }
- /* Software Self-Refresh mode (SSR) during DDR initilialization */
- mmio_clrsetbits_32(priv->base + RCC_DDRITFCR,
- RCC_DDRITFCR_DDRCKMOD_MASK,
- RCC_DDRITFCR_DDRCKMOD_SSR <<
- RCC_DDRITFCR_DDRCKMOD_SHIFT);
- return 0;
- }
- static int clk_stm32_parse_oscillator_fdt(void *fdt, int node, const char *name,
- struct stm32_osci_dt_cfg *osci)
- {
- int subnode = 0;
- /* default value oscillator not found, freq=0 */
- osci->freq = 0;
- fdt_for_each_subnode(subnode, fdt, node) {
- const char *cchar = NULL;
- const fdt32_t *cuint = NULL;
- int ret = 0;
- cchar = fdt_get_name(fdt, subnode, &ret);
- if (cchar == NULL) {
- return ret;
- }
- if (strncmp(cchar, name, (size_t)ret) ||
- fdt_get_status(subnode) == DT_DISABLED) {
- continue;
- }
- cuint = fdt_getprop(fdt, subnode, "clock-frequency", &ret);
- if (cuint == NULL) {
- return ret;
- }
- osci->freq = fdt32_to_cpu(*cuint);
- if (fdt_getprop(fdt, subnode, "st,bypass", NULL) != NULL) {
- osci->bypass = true;
- }
- if (fdt_getprop(fdt, subnode, "st,digbypass", NULL) != NULL) {
- osci->digbyp = true;
- }
- if (fdt_getprop(fdt, subnode, "st,css", NULL) != NULL) {
- osci->css = true;
- }
- osci->drive = fdt_read_uint32_default(fdt, subnode, "st,drive", LSEDRV_MEDIUM_HIGH);
- return 0;
- }
- return 0;
- }
- static int stm32_clk_parse_fdt_all_oscillator(void *fdt, struct stm32_clk_platdata *pdata)
- {
- int fdt_err = 0;
- uint32_t i = 0;
- int node = 0;
- node = fdt_path_offset(fdt, "/clocks");
- if (node < 0) {
- return -FDT_ERR_NOTFOUND;
- }
- for (i = 0; i < pdata->nosci; i++) {
- const char *name = NULL;
- name = clk_stm32_get_oscillator_name((enum stm32_osc)i);
- if (name == NULL) {
- continue;
- }
- fdt_err = clk_stm32_parse_oscillator_fdt(fdt, node, name, &pdata->osci[i]);
- if (fdt_err < 0) {
- panic();
- }
- }
- return 0;
- }
- #define RCC_PLL_NAME_SIZE 12
- static int clk_stm32_load_vco_config(void *fdt, int subnode, struct stm32_pll_vco *vco)
- {
- int err = 0;
- err = fdt_read_uint32_array(fdt, subnode, "divmn", (int)PLL_DIV_MN_NB, vco->div_mn);
- if (err != 0) {
- return err;
- }
- err = fdt_read_uint32_array(fdt, subnode, "csg", (int)PLL_CSG_NB, vco->csg);
- vco->csg_enabled = (err == 0);
- if (err == -FDT_ERR_NOTFOUND) {
- err = 0;
- }
- if (err != 0) {
- return err;
- }
- vco->status = RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | RCC_PLLNCR_DIVREN | RCC_PLLNCR_PLLON;
- vco->frac = fdt_read_uint32_default(fdt, subnode, "frac", 0);
- vco->src = fdt_read_uint32_default(fdt, subnode, "src", UINT32_MAX);
- return 0;
- }
- static int clk_stm32_load_output_config(void *fdt, int subnode, struct stm32_pll_output *output)
- {
- int err = 0;
- err = fdt_read_uint32_array(fdt, subnode, "st,pll_div_pqr", (int)PLL_DIV_PQR_NB,
- output->output);
- if (err != 0) {
- return err;
- }
- return 0;
- }
- static int clk_stm32_parse_pll_fdt(void *fdt, int subnode, struct stm32_pll_dt_cfg *pll)
- {
- const fdt32_t *cuint = NULL;
- int subnode_pll = 0;
- int subnode_vco = 0;
- int err = 0;
- cuint = fdt_getprop(fdt, subnode, "st,pll", NULL);
- if (!cuint) {
- return -FDT_ERR_NOTFOUND;
- }
- subnode_pll = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
- if (subnode_pll < 0) {
- return -FDT_ERR_NOTFOUND;
- }
- cuint = fdt_getprop(fdt, subnode_pll, "st,pll_vco", NULL);
- if (!cuint) {
- return -FDT_ERR_NOTFOUND;
- }
- subnode_vco = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
- if (subnode_vco < 0) {
- return -FDT_ERR_NOTFOUND;
- }
- err = clk_stm32_load_vco_config(fdt, subnode_vco, &pll->vco);
- if (err != 0) {
- return err;
- }
- err = clk_stm32_load_output_config(fdt, subnode_pll, &pll->output);
- if (err != 0) {
- return err;
- }
- return 0;
- }
- static int stm32_clk_parse_fdt_all_pll(void *fdt, int node, struct stm32_clk_platdata *pdata)
- {
- size_t i = 0U;
- /* PLL1 is not configurable with device tree */
- for (i = _PLL2; i < pdata->npll; i++) {
- struct stm32_pll_dt_cfg *pll = &pdata->pll[i];
- char name[RCC_PLL_NAME_SIZE];
- int subnode = 0;
- int err = 0;
- snprintf(name, sizeof(name), "st,pll@%u", i);
- subnode = fdt_subnode_offset(fdt, node, name);
- if (!fdt_check_node(subnode)) {
- continue;
- }
- err = clk_stm32_parse_pll_fdt(fdt, subnode, pll);
- if (err != 0) {
- panic();
- }
- }
- return 0;
- }
- static int stm32_clk_parse_fdt(struct stm32_clk_platdata *pdata)
- {
- void *fdt = NULL;
- int node;
- uint32_t err;
- if (fdt_get_address(&fdt) == 0) {
- return -ENOENT;
- }
- node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
- if (node < 0) {
- panic();
- }
- err = stm32_clk_parse_fdt_all_oscillator(fdt, pdata);
- if (err != 0) {
- return err;
- }
- err = stm32_clk_parse_fdt_all_pll(fdt, node, pdata);
- if (err != 0) {
- return err;
- }
- err = stm32_clk_parse_fdt_by_name(fdt, node, "st,clkdiv", pdata->clkdiv, &pdata->nclkdiv);
- if (err != 0) {
- return err;
- }
- err = stm32_clk_parse_fdt_by_name(fdt, node, "st,clksrc", pdata->clksrc, &pdata->nclksrc);
- if (err != 0) {
- return err;
- }
- return 0;
- }
- void stm32mp1_clk_rcc_regs_lock(void)
- {
- clk_stm32_rcc_regs_lock();
- }
- void stm32mp1_clk_rcc_regs_unlock(void)
- {
- clk_stm32_rcc_regs_unlock();
- }
- int stm32mp1_clk_init(void)
- {
- int ret;
- /* compute the PLL1 settings, not read in device tree */
- ret = clk_compute_pll1_settings(PLL1_NOMINAL_FREQ_IN_KHZ);
- if (ret != 0) {
- return ret;
- }
- ret = stm32mp1_init_clock_tree();
- if (ret != 0) {
- return ret;
- }
- clk_stm32_enable_critical_clocks();
- return 0;
- }
- int stm32mp1_clk_probe(void)
- {
- uintptr_t base = RCC_BASE;
- int ret;
- ret = stm32_clk_parse_fdt(&stm32mp13_clock_pdata);
- if (ret != 0) {
- return ret;
- }
- ret = clk_stm32_init(&stm32mp13_clock_data, base);
- return ret;
- }
|