xref: /rk3399_ARM-atf/plat/intel/soc/stratix10/soc/s10_clock_manager.c (revision 9118bdf4011b5a54fec5c1eb80e1ad99ab7ac4bd)
19d82ef26SLoh Tien Hock /*
2*150d2be0SJit Loon Lim  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
39d82ef26SLoh Tien Hock  *
49d82ef26SLoh Tien Hock  * SPDX-License-Identifier: BSD-3-Clause
59d82ef26SLoh Tien Hock  */
69d82ef26SLoh Tien Hock 
79d82ef26SLoh Tien Hock #include <arch.h>
89d82ef26SLoh Tien Hock #include <arch_helpers.h>
99d82ef26SLoh Tien Hock #include <assert.h>
109d82ef26SLoh Tien Hock #include <drivers/delay_timer.h>
119d82ef26SLoh Tien Hock #include <lib/mmio.h>
129d82ef26SLoh Tien Hock #include <platform_def.h>
139d82ef26SLoh Tien Hock 
149d82ef26SLoh Tien Hock #include "s10_clock_manager.h"
15328718f2SHadi Asyrafi #include "socfpga_handoff.h"
1620335ca8SHadi Asyrafi #include "socfpga_system_manager.h"
179d82ef26SLoh Tien Hock 
189d82ef26SLoh Tien Hock 
wait_pll_lock(void)199d82ef26SLoh Tien Hock void wait_pll_lock(void)
209d82ef26SLoh Tien Hock {
219d82ef26SLoh Tien Hock 	uint32_t data;
229d82ef26SLoh Tien Hock 
239d82ef26SLoh Tien Hock 	do {
249d82ef26SLoh Tien Hock 		data = mmio_read_32(ALT_CLKMGR + ALT_CLKMGR_STAT);
259d82ef26SLoh Tien Hock 	} while ((ALT_CLKMGR_STAT_MAINPLLLOCKED(data) == 0) ||
269d82ef26SLoh Tien Hock 			(ALT_CLKMGR_STAT_PERPLLLOCKED(data) == 0));
279d82ef26SLoh Tien Hock }
289d82ef26SLoh Tien Hock 
wait_fsm(void)299d82ef26SLoh Tien Hock void wait_fsm(void)
309d82ef26SLoh Tien Hock {
319d82ef26SLoh Tien Hock 	uint32_t data;
329d82ef26SLoh Tien Hock 
339d82ef26SLoh Tien Hock 	do {
349d82ef26SLoh Tien Hock 		data = mmio_read_32(ALT_CLKMGR + ALT_CLKMGR_STAT);
359d82ef26SLoh Tien Hock 	} while (ALT_CLKMGR_STAT_BUSY(data) == ALT_CLKMGR_STAT_BUSY_E_BUSY);
369d82ef26SLoh Tien Hock }
379d82ef26SLoh Tien Hock 
config_clkmgr_handoff(handoff * hoff_ptr)389d82ef26SLoh Tien Hock void config_clkmgr_handoff(handoff *hoff_ptr)
399d82ef26SLoh Tien Hock {
409d82ef26SLoh Tien Hock 	uint32_t m_div, refclk_div, mscnt, hscnt;
419d82ef26SLoh Tien Hock 
429d82ef26SLoh Tien Hock 	/* Bypass all mainpllgrp's clocks */
439d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL +
449d82ef26SLoh Tien Hock 			ALT_CLKMGR_MAINPLL_BYPASS,
459d82ef26SLoh Tien Hock 			0x7);
469d82ef26SLoh Tien Hock 	wait_fsm();
479d82ef26SLoh Tien Hock 	/* Bypass all perpllgrp's clocks */
489d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_PERPLL +
499d82ef26SLoh Tien Hock 			ALT_CLKMGR_PERPLL_BYPASS,
509d82ef26SLoh Tien Hock 			0x7f);
519d82ef26SLoh Tien Hock 	wait_fsm();
529d82ef26SLoh Tien Hock 
539d82ef26SLoh Tien Hock 	/* Setup main PLL dividers */
549d82ef26SLoh Tien Hock 	m_div = ALT_CLKMGR_MAINPLL_FDBCK_MDIV(hoff_ptr->main_pll_fdbck);
559d82ef26SLoh Tien Hock 	refclk_div = ALT_CLKMGR_MAINPLL_PLLGLOB_REFCLKDIV(
569d82ef26SLoh Tien Hock 			hoff_ptr->main_pll_pllglob);
579d82ef26SLoh Tien Hock 	mscnt = 200 / ((6 + m_div) / refclk_div);
589d82ef26SLoh Tien Hock 	hscnt = (m_div + 6) * mscnt / refclk_div - 9;
599d82ef26SLoh Tien Hock 
609d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLGLOB,
619d82ef26SLoh Tien Hock 			hoff_ptr->main_pll_pllglob);
629d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_FDBCK,
639d82ef26SLoh Tien Hock 			hoff_ptr->main_pll_fdbck);
649d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_VCOCALIB,
659d82ef26SLoh Tien Hock 			ALT_CLKMGR_MAINPLL_VCOCALIB_HSCNT_SET(hscnt) |
669d82ef26SLoh Tien Hock 			ALT_CLKMGR_MAINPLL_VCOCALIB_MSCNT_SET(mscnt));
679d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLC0,
689d82ef26SLoh Tien Hock 			hoff_ptr->main_pll_pllc0);
699d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLC1,
709d82ef26SLoh Tien Hock 			hoff_ptr->main_pll_pllc1);
719d82ef26SLoh Tien Hock 
729d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_NOCDIV,
739d82ef26SLoh Tien Hock 			hoff_ptr->main_pll_nocdiv);
749d82ef26SLoh Tien Hock 
759d82ef26SLoh Tien Hock 	/* Setup peripheral PLL dividers */
769d82ef26SLoh Tien Hock 	m_div = ALT_CLKMGR_PERPLL_FDBCK_MDIV(hoff_ptr->per_pll_fdbck);
779d82ef26SLoh Tien Hock 	refclk_div = ALT_CLKMGR_PERPLL_PLLGLOB_REFCLKDIV(
789d82ef26SLoh Tien Hock 			hoff_ptr->per_pll_pllglob);
799d82ef26SLoh Tien Hock 	mscnt = 200 / ((6 + m_div) / refclk_div);
809d82ef26SLoh Tien Hock 	hscnt = (m_div + 6) * mscnt / refclk_div - 9;
819d82ef26SLoh Tien Hock 
829d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLGLOB,
839d82ef26SLoh Tien Hock 			hoff_ptr->per_pll_pllglob);
849d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_FDBCK,
859d82ef26SLoh Tien Hock 			hoff_ptr->per_pll_fdbck);
869d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_VCOCALIB,
879d82ef26SLoh Tien Hock 			ALT_CLKMGR_PERPLL_VCOCALIB_HSCNT_SET(hscnt) |
889d82ef26SLoh Tien Hock 			ALT_CLKMGR_PERPLL_VCOCALIB_MSCNT_SET(mscnt));
899d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLC0,
909d82ef26SLoh Tien Hock 			hoff_ptr->per_pll_pllc0);
919d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLC1,
929d82ef26SLoh Tien Hock 			hoff_ptr->per_pll_pllc1);
939d82ef26SLoh Tien Hock 
949d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_GPIODIV,
959d82ef26SLoh Tien Hock 			ALT_CLKMGR_PERPLL_GPIODIV_GPIODBCLK_SET(
969d82ef26SLoh Tien Hock 			hoff_ptr->per_pll_gpiodiv));
979d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_EMACCTL,
989d82ef26SLoh Tien Hock 			hoff_ptr->per_pll_emacctl);
999d82ef26SLoh Tien Hock 
1009d82ef26SLoh Tien Hock 
1019d82ef26SLoh Tien Hock 	/* Take both PLL out of reset and power up */
1029d82ef26SLoh Tien Hock 	mmio_setbits_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLGLOB,
1039d82ef26SLoh Tien Hock 			ALT_CLKMGR_MAINPLL_PLLGLOB_PD_SET_MSK |
1049d82ef26SLoh Tien Hock 			ALT_CLKMGR_MAINPLL_PLLGLOB_RST_SET_MSK);
1059d82ef26SLoh Tien Hock 	mmio_setbits_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLGLOB,
1069d82ef26SLoh Tien Hock 			ALT_CLKMGR_PERPLL_PLLGLOB_PD_SET_MSK |
1079d82ef26SLoh Tien Hock 			ALT_CLKMGR_PERPLL_PLLGLOB_RST_SET_MSK);
1089d82ef26SLoh Tien Hock 
1099d82ef26SLoh Tien Hock 	wait_pll_lock();
1109d82ef26SLoh Tien Hock 
1119d82ef26SLoh Tien Hock 	/* Dividers for C2 to C9 only init after PLLs are lock. */
1129d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_MPUCLK, 0xff);
1139d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_NOCCLK, 0xff);
1149d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR2CLK, 0xff);
1159d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR3CLK, 0xff);
1169d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR4CLK, 0xff);
1179d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR5CLK, 0xff);
1189d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR6CLK, 0xff);
1199d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR7CLK, 0xff);
1209d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR8CLK, 0xff);
1219d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR9CLK, 0xff);
1229d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR2CLK, 0xff);
1239d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR3CLK, 0xff);
1249d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR4CLK, 0xff);
1259d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR5CLK, 0xff);
1269d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR6CLK, 0xff);
1279d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR7CLK, 0xff);
1289d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR8CLK, 0xff);
1299d82ef26SLoh Tien Hock 
1309d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_MPUCLK,
1319d82ef26SLoh Tien Hock 			hoff_ptr->main_pll_mpuclk);
1329d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_NOCCLK,
1339d82ef26SLoh Tien Hock 			hoff_ptr->main_pll_nocclk);
1349d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR2CLK,
1359d82ef26SLoh Tien Hock 			hoff_ptr->main_pll_cntr2clk);
1369d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR3CLK,
1379d82ef26SLoh Tien Hock 			hoff_ptr->main_pll_cntr3clk);
1389d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR4CLK,
1399d82ef26SLoh Tien Hock 			hoff_ptr->main_pll_cntr4clk);
1409d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR5CLK,
1419d82ef26SLoh Tien Hock 			hoff_ptr->main_pll_cntr5clk);
1429d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR6CLK,
1439d82ef26SLoh Tien Hock 			hoff_ptr->main_pll_cntr6clk);
1449d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR7CLK,
1459d82ef26SLoh Tien Hock 			hoff_ptr->main_pll_cntr7clk);
1469d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR8CLK,
1479d82ef26SLoh Tien Hock 			hoff_ptr->main_pll_cntr8clk);
1489d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR9CLK,
1499d82ef26SLoh Tien Hock 			hoff_ptr->main_pll_cntr9clk);
1509d82ef26SLoh Tien Hock 
1519d82ef26SLoh Tien Hock 	/* Peripheral PLL Clock Source and Counters/Divider */
1529d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR2CLK,
1539d82ef26SLoh Tien Hock 			hoff_ptr->per_pll_cntr2clk);
1549d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR3CLK,
1559d82ef26SLoh Tien Hock 			hoff_ptr->per_pll_cntr3clk);
1569d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR4CLK,
1579d82ef26SLoh Tien Hock 			hoff_ptr->per_pll_cntr4clk);
1589d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR5CLK,
1599d82ef26SLoh Tien Hock 			hoff_ptr->per_pll_cntr5clk);
1609d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR6CLK,
1619d82ef26SLoh Tien Hock 			hoff_ptr->per_pll_cntr6clk);
1629d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR7CLK,
1639d82ef26SLoh Tien Hock 			hoff_ptr->per_pll_cntr7clk);
1649d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR8CLK,
1659d82ef26SLoh Tien Hock 			hoff_ptr->per_pll_cntr8clk);
1669d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR9CLK,
1679d82ef26SLoh Tien Hock 			hoff_ptr->per_pll_cntr9clk);
1689d82ef26SLoh Tien Hock 
1699d82ef26SLoh Tien Hock 	/* Take all PLLs out of bypass */
1709d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_BYPASS, 0);
1719d82ef26SLoh Tien Hock 	wait_fsm();
1729d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_BYPASS, 0);
1739d82ef26SLoh Tien Hock 	wait_fsm();
1749d82ef26SLoh Tien Hock 
1759d82ef26SLoh Tien Hock 	/* Set safe mode/ out of boot mode */
1769d82ef26SLoh Tien Hock 	mmio_clrbits_32(ALT_CLKMGR + ALT_CLKMGR_CTRL,
1779d82ef26SLoh Tien Hock 		ALT_CLKMGR_CTRL_BOOTMODE_SET_MSK);
1789d82ef26SLoh Tien Hock 	wait_fsm();
1799d82ef26SLoh Tien Hock 
1809d82ef26SLoh Tien Hock 	/* 10 Enable mainpllgrp's software-managed clock */
1819d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_EN,
1829d82ef26SLoh Tien Hock 			ALT_CLKMGR_MAINPLL_EN_RESET);
1839d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_EN,
1849d82ef26SLoh Tien Hock 			ALT_CLKMGR_PERPLL_EN_RESET);
1859d82ef26SLoh Tien Hock 
1869d82ef26SLoh Tien Hock 	/* Clear loss lock  interrupt status register that */
1879d82ef26SLoh Tien Hock 	/* might be set during configuration */
1889d82ef26SLoh Tien Hock 	mmio_write_32(ALT_CLKMGR + ALT_CLKMGR_INTRCLR,
1899d82ef26SLoh Tien Hock 			ALT_CLKMGR_INTRCLR_MAINLOCKLOST_SET_MSK |
1909d82ef26SLoh Tien Hock 			ALT_CLKMGR_INTRCLR_PERLOCKLOST_SET_MSK);
191fea24b88SHadi Asyrafi 
192fea24b88SHadi Asyrafi 	/* Pass clock source frequency into scratch register */
19320335ca8SHadi Asyrafi 	mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1),
194fea24b88SHadi Asyrafi 			hoff_ptr->hps_osc_clk_h);
19520335ca8SHadi Asyrafi 	mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2),
196fea24b88SHadi Asyrafi 			hoff_ptr->fpga_clk_hz);
197fea24b88SHadi Asyrafi 
1989d82ef26SLoh Tien Hock }
1999d82ef26SLoh Tien Hock 
200fea24b88SHadi Asyrafi /* Extract reference clock from platform clock source */
get_ref_clk(uint32_t pllglob)201fea24b88SHadi Asyrafi uint32_t get_ref_clk(uint32_t pllglob)
20210e70f87SMuhammad Hadi Asyrafi Abdul Halim {
203fea24b88SHadi Asyrafi 	uint32_t data32, mdiv, refclkdiv, ref_clk;
204fea24b88SHadi Asyrafi 	uint32_t scr_reg;
20510e70f87SMuhammad Hadi Asyrafi Abdul Halim 
206fea24b88SHadi Asyrafi 	switch (ALT_CLKMGR_PSRC(pllglob)) {
207fea24b88SHadi Asyrafi 	case ALT_CLKMGR_PLLGLOB_PSRC_EOSC1:
20820335ca8SHadi Asyrafi 		scr_reg = SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1);
209fea24b88SHadi Asyrafi 		ref_clk = mmio_read_32(scr_reg);
21010e70f87SMuhammad Hadi Asyrafi Abdul Halim 		break;
211fea24b88SHadi Asyrafi 	case ALT_CLKMGR_PLLGLOB_PSRC_INTOSC:
212fea24b88SHadi Asyrafi 		ref_clk = ALT_CLKMGR_INTOSC_HZ;
21310e70f87SMuhammad Hadi Asyrafi Abdul Halim 		break;
214fea24b88SHadi Asyrafi 	case ALT_CLKMGR_PLLGLOB_PSRC_F2S:
21520335ca8SHadi Asyrafi 		scr_reg = SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2);
216fea24b88SHadi Asyrafi 		ref_clk = mmio_read_32(scr_reg);
21710e70f87SMuhammad Hadi Asyrafi Abdul Halim 		break;
21810e70f87SMuhammad Hadi Asyrafi Abdul Halim 	default:
21910e70f87SMuhammad Hadi Asyrafi Abdul Halim 		ref_clk = 0;
22010e70f87SMuhammad Hadi Asyrafi Abdul Halim 		assert(0);
22110e70f87SMuhammad Hadi Asyrafi Abdul Halim 		break;
22210e70f87SMuhammad Hadi Asyrafi Abdul Halim 	}
22310e70f87SMuhammad Hadi Asyrafi Abdul Halim 
224fea24b88SHadi Asyrafi 	refclkdiv = ALT_CLKMGR_MAINPLL_PLLGLOB_REFCLKDIV(pllglob);
22510e70f87SMuhammad Hadi Asyrafi Abdul Halim 	data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_FDBCK);
22610e70f87SMuhammad Hadi Asyrafi Abdul Halim 	mdiv = ALT_CLKMGR_MAINPLL_FDBCK_MDIV(data32);
227fea24b88SHadi Asyrafi 
22810e70f87SMuhammad Hadi Asyrafi Abdul Halim 	ref_clk = (ref_clk / refclkdiv) * (6 + mdiv);
22910e70f87SMuhammad Hadi Asyrafi Abdul Halim 
230fea24b88SHadi Asyrafi 	return ref_clk;
231fea24b88SHadi Asyrafi }
23210e70f87SMuhammad Hadi Asyrafi Abdul Halim 
233*150d2be0SJit Loon Lim /* Calculate clock frequency based on parameter */
get_clk_freq(uint32_t psrc_reg,uint32_t main_pllc,uint32_t per_pllc)234*150d2be0SJit Loon Lim uint32_t get_clk_freq(uint32_t psrc_reg, uint32_t main_pllc, uint32_t per_pllc)
235*150d2be0SJit Loon Lim {
236*150d2be0SJit Loon Lim 	uint32_t clk_psrc, ref_clk;
237*150d2be0SJit Loon Lim 	uint32_t pllc_reg, pllc_div, pllglob_reg;
238*150d2be0SJit Loon Lim 
239*150d2be0SJit Loon Lim 	clk_psrc = mmio_read_32(ALT_CLKMGR_MAINPLL + psrc_reg);
240*150d2be0SJit Loon Lim 
241*150d2be0SJit Loon Lim 	switch (ALT_CLKMGR_PSRC(clk_psrc)) {
242*150d2be0SJit Loon Lim 	case ALT_CLKMGR_SRC_MAIN:
243*150d2be0SJit Loon Lim 		pllc_reg = ALT_CLKMGR_MAINPLL + main_pllc;
244*150d2be0SJit Loon Lim 		pllglob_reg = ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLGLOB;
245*150d2be0SJit Loon Lim 		break;
246*150d2be0SJit Loon Lim 	case ALT_CLKMGR_SRC_PER:
247*150d2be0SJit Loon Lim 		pllc_reg = ALT_CLKMGR_PERPLL + per_pllc;
248*150d2be0SJit Loon Lim 		pllglob_reg = ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLGLOB;
249*150d2be0SJit Loon Lim 		break;
250*150d2be0SJit Loon Lim 	default:
251*150d2be0SJit Loon Lim 		return 0;
252*150d2be0SJit Loon Lim 	}
253*150d2be0SJit Loon Lim 
254*150d2be0SJit Loon Lim 	ref_clk = get_ref_clk(mmio_read_32(pllglob_reg));
255*150d2be0SJit Loon Lim 
256*150d2be0SJit Loon Lim 	pllc_div = mmio_read_32(pllc_reg) & 0xff;
257*150d2be0SJit Loon Lim 
258*150d2be0SJit Loon Lim 	if (pllc_div != 0) {
259*150d2be0SJit Loon Lim 		ref_clk = (ref_clk / pllc_div) / (clk_psrc + 1);
260*150d2be0SJit Loon Lim 		return ref_clk;
261*150d2be0SJit Loon Lim 	} else {
262*150d2be0SJit Loon Lim 		VERBOSE("PLL DIV is 0\n");
263*150d2be0SJit Loon Lim 		return 0;
264*150d2be0SJit Loon Lim 	}
265*150d2be0SJit Loon Lim }
266*150d2be0SJit Loon Lim 
267fea24b88SHadi Asyrafi /* Calculate L3 interconnect main clock */
get_l3_clk(uint32_t ref_clk)268fea24b88SHadi Asyrafi uint32_t get_l3_clk(uint32_t ref_clk)
269fea24b88SHadi Asyrafi {
270fea24b88SHadi Asyrafi 	uint32_t noc_base_clk, l3_clk, noc_clk, data32;
271fea24b88SHadi Asyrafi 	uint32_t pllc1_reg;
272fea24b88SHadi Asyrafi 
273fea24b88SHadi Asyrafi 	noc_clk = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_NOCCLK);
274fea24b88SHadi Asyrafi 
275fea24b88SHadi Asyrafi 	switch (ALT_CLKMGR_PSRC(noc_clk)) {
276fea24b88SHadi Asyrafi 	case ALT_CLKMGR_SRC_MAIN:
277fea24b88SHadi Asyrafi 		pllc1_reg = ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLC1;
278fea24b88SHadi Asyrafi 		break;
279fea24b88SHadi Asyrafi 	case ALT_CLKMGR_SRC_PER:
280fea24b88SHadi Asyrafi 		pllc1_reg = ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLC1;
281fea24b88SHadi Asyrafi 		break;
282fea24b88SHadi Asyrafi 	default:
283fea24b88SHadi Asyrafi 		pllc1_reg = 0;
284fea24b88SHadi Asyrafi 		assert(0);
285fea24b88SHadi Asyrafi 		break;
286fea24b88SHadi Asyrafi 	}
287fea24b88SHadi Asyrafi 
288fea24b88SHadi Asyrafi 	data32 = mmio_read_32(pllc1_reg);
289fea24b88SHadi Asyrafi 	noc_base_clk = ref_clk / (data32 & 0xff);
290fea24b88SHadi Asyrafi 	l3_clk = noc_base_clk / (noc_clk + 1);
291fea24b88SHadi Asyrafi 
292fea24b88SHadi Asyrafi 	return l3_clk;
293fea24b88SHadi Asyrafi }
294fea24b88SHadi Asyrafi 
295fea24b88SHadi Asyrafi /* Calculate clock frequency to be used for watchdog timer */
get_wdt_clk(void)296fea24b88SHadi Asyrafi uint32_t get_wdt_clk(void)
297fea24b88SHadi Asyrafi {
298fea24b88SHadi Asyrafi 	uint32_t data32, ref_clk, l3_clk, l4_sys_clk;
299fea24b88SHadi Asyrafi 
300fea24b88SHadi Asyrafi 	data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLGLOB);
301fea24b88SHadi Asyrafi 	ref_clk = get_ref_clk(data32);
302fea24b88SHadi Asyrafi 
303fea24b88SHadi Asyrafi 	l3_clk = get_l3_clk(ref_clk);
304fea24b88SHadi Asyrafi 
305fea24b88SHadi Asyrafi 	l4_sys_clk = l3_clk / 4;
306fea24b88SHadi Asyrafi 
307fea24b88SHadi Asyrafi 	return l4_sys_clk;
308fea24b88SHadi Asyrafi }
309fea24b88SHadi Asyrafi 
310fea24b88SHadi Asyrafi /* Calculate clock frequency to be used for UART driver */
get_uart_clk(void)311fea24b88SHadi Asyrafi uint32_t get_uart_clk(void)
312fea24b88SHadi Asyrafi {
313fea24b88SHadi Asyrafi 	uint32_t data32, ref_clk, l3_clk, l4_sp_clk;
314fea24b88SHadi Asyrafi 
315fea24b88SHadi Asyrafi 	data32 = mmio_read_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLGLOB);
316fea24b88SHadi Asyrafi 	ref_clk = get_ref_clk(data32);
317fea24b88SHadi Asyrafi 
318fea24b88SHadi Asyrafi 	l3_clk = get_l3_clk(ref_clk);
319fea24b88SHadi Asyrafi 
320fea24b88SHadi Asyrafi 	data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_NOCDIV);
321fea24b88SHadi Asyrafi 	data32 = (data32 >> 16) & 0x3;
322fea24b88SHadi Asyrafi 	data32 = 1 << data32;
323fea24b88SHadi Asyrafi 
324fea24b88SHadi Asyrafi 	l4_sp_clk = (l3_clk / data32);
325fea24b88SHadi Asyrafi 
326fea24b88SHadi Asyrafi 	return l4_sp_clk;
327fea24b88SHadi Asyrafi }
328fea24b88SHadi Asyrafi 
329fea24b88SHadi Asyrafi /* Calculate clock frequency to be used for SDMMC driver */
get_mmc_clk(void)330fea24b88SHadi Asyrafi uint32_t get_mmc_clk(void)
331fea24b88SHadi Asyrafi {
332fea24b88SHadi Asyrafi 	uint32_t data32, ref_clk, l3_clk, mmc_clk;
333fea24b88SHadi Asyrafi 
334fea24b88SHadi Asyrafi 	data32 = mmio_read_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLGLOB);
335fea24b88SHadi Asyrafi 	ref_clk = get_ref_clk(data32);
336fea24b88SHadi Asyrafi 
337fea24b88SHadi Asyrafi 	l3_clk = get_l3_clk(ref_clk);
338fea24b88SHadi Asyrafi 
339fea24b88SHadi Asyrafi 	data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR6CLK);
340fea24b88SHadi Asyrafi 	mmc_clk = (l3_clk / (data32 + 1)) / 4;
341fea24b88SHadi Asyrafi 
342fea24b88SHadi Asyrafi 	return mmc_clk;
34310e70f87SMuhammad Hadi Asyrafi Abdul Halim }
344f65bdf3aSBenjaminLimJL 
345*150d2be0SJit Loon Lim /* Return MPU clock */
get_mpu_clk(void)346*150d2be0SJit Loon Lim uint32_t get_mpu_clk(void)
347*150d2be0SJit Loon Lim {
348*150d2be0SJit Loon Lim 	uint32_t mpu_clk;
349*150d2be0SJit Loon Lim 
350*150d2be0SJit Loon Lim 	mpu_clk = get_clk_freq(ALT_CLKMGR_MAINPLL_NOCCLK, ALT_CLKMGR_MAINPLL_PLLC0,
351*150d2be0SJit Loon Lim 				ALT_CLKMGR_PERPLL_PLLC0);
352*150d2be0SJit Loon Lim 
353*150d2be0SJit Loon Lim 	return mpu_clk;
354*150d2be0SJit Loon Lim }
355*150d2be0SJit Loon Lim 
356f65bdf3aSBenjaminLimJL /* Get cpu freq clock */
get_cpu_clk(void)357f65bdf3aSBenjaminLimJL uint32_t get_cpu_clk(void)
358f65bdf3aSBenjaminLimJL {
359f65bdf3aSBenjaminLimJL 	uint32_t data32, ref_clk, cpu_clk;
360f65bdf3aSBenjaminLimJL 
361f65bdf3aSBenjaminLimJL 	data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLGLOB);
362f65bdf3aSBenjaminLimJL 	ref_clk = get_ref_clk(data32);
363f65bdf3aSBenjaminLimJL 
3645f06bffaSJit Loon Lim 	cpu_clk = get_l3_clk(ref_clk)/PLAT_HZ_CONVERT_TO_MHZ;
365f65bdf3aSBenjaminLimJL 
366f65bdf3aSBenjaminLimJL 	return cpu_clk;
367f65bdf3aSBenjaminLimJL }
368*150d2be0SJit Loon Lim 
369*150d2be0SJit Loon Lim /* Return mpu_periph_clk clock frequency */
get_mpu_periph_clk(void)370*150d2be0SJit Loon Lim uint32_t get_mpu_periph_clk(void)
371*150d2be0SJit Loon Lim {
372*150d2be0SJit Loon Lim 	uint32_t mpu_periph_clk = 0;
373*150d2be0SJit Loon Lim 	/* mpu_periph_clk is mpu_clk, via a static /4 divider  */
374*150d2be0SJit Loon Lim 	mpu_periph_clk = (get_mpu_clk()/4)/PLAT_HZ_CONVERT_TO_MHZ;
375*150d2be0SJit Loon Lim 	return mpu_periph_clk;
376*150d2be0SJit Loon Lim }
377*150d2be0SJit Loon Lim 
378*150d2be0SJit Loon Lim /* Return mpu_periph_clk tick */
plat_get_syscnt_freq2(void)379*150d2be0SJit Loon Lim unsigned int plat_get_syscnt_freq2(void)
380*150d2be0SJit Loon Lim {
381*150d2be0SJit Loon Lim 	return PLAT_SYS_COUNTER_FREQ_IN_TICKS;
382*150d2be0SJit Loon Lim }
383