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