xref: /openbmc/u-boot/arch/arm/mach-socfpga/clock_manager.c (revision 719afeb0b3c60af82f701f122978b935aa6a5217)
183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
205a21721SMasahiro Yamada /*
3de778115SLey Foon Tan  *  Copyright (C) 2013-2017 Altera Corporation <www.altera.com>
405a21721SMasahiro Yamada  */
505a21721SMasahiro Yamada 
605a21721SMasahiro Yamada #include <common.h>
7de778115SLey Foon Tan #include <wait_bit.h>
805a21721SMasahiro Yamada #include <asm/io.h>
905a21721SMasahiro Yamada #include <asm/arch/clock_manager.h>
1005a21721SMasahiro Yamada 
1105a21721SMasahiro Yamada DECLARE_GLOBAL_DATA_PTR;
1205a21721SMasahiro Yamada 
1305a21721SMasahiro Yamada static const struct socfpga_clock_manager *clock_manager_base =
1405a21721SMasahiro Yamada 	(struct socfpga_clock_manager *)SOCFPGA_CLKMGR_ADDRESS;
1505a21721SMasahiro Yamada 
cm_wait_for_lock(u32 mask)16de778115SLey Foon Tan void cm_wait_for_lock(u32 mask)
1705a21721SMasahiro Yamada {
18de778115SLey Foon Tan 	u32 inter_val;
19de778115SLey Foon Tan 	u32 retry = 0;
2005a21721SMasahiro Yamada 	do {
21177ba1f9SLey Foon Tan #if defined(CONFIG_TARGET_SOCFPGA_GEN5)
2205a21721SMasahiro Yamada 		inter_val = readl(&clock_manager_base->inter) & mask;
23508791a0SLey Foon Tan #else
24177ba1f9SLey Foon Tan 		inter_val = readl(&clock_manager_base->stat) & mask;
25177ba1f9SLey Foon Tan #endif
26177ba1f9SLey Foon Tan 		/* Wait for stable lock */
2705a21721SMasahiro Yamada 		if (inter_val == mask)
2805a21721SMasahiro Yamada 			retry++;
2905a21721SMasahiro Yamada 		else
3005a21721SMasahiro Yamada 			retry = 0;
3105a21721SMasahiro Yamada 		if (retry >= 10)
3205a21721SMasahiro Yamada 			break;
3305a21721SMasahiro Yamada 	} while (1);
3405a21721SMasahiro Yamada }
3505a21721SMasahiro Yamada 
3605a21721SMasahiro Yamada /* function to poll in the fsm busy bit */
cm_wait_for_fsm(void)37de778115SLey Foon Tan int cm_wait_for_fsm(void)
3805a21721SMasahiro Yamada {
3948263504SÁlvaro Fernández Rojas 	return wait_for_bit_le32(&clock_manager_base->stat,
40de778115SLey Foon Tan 				 CLKMGR_STAT_BUSY, false, 20000, false);
4105a21721SMasahiro Yamada }
4205a21721SMasahiro Yamada 
set_cpu_clk_info(void)4305a21721SMasahiro Yamada int set_cpu_clk_info(void)
4405a21721SMasahiro Yamada {
45*49e508e9SMarek Vasut #if defined(CONFIG_TARGET_SOCFPGA_GEN5)
4605a21721SMasahiro Yamada 	/* Calculate the clock frequencies required for drivers */
4705a21721SMasahiro Yamada 	cm_get_l4_sp_clk_hz();
4805a21721SMasahiro Yamada 	cm_get_mmc_controller_clk_hz();
49*49e508e9SMarek Vasut #endif
5005a21721SMasahiro Yamada 
5105a21721SMasahiro Yamada 	gd->bd->bi_arm_freq = cm_get_mpu_clk_hz() / 1000000;
5205a21721SMasahiro Yamada 	gd->bd->bi_dsp_freq = 0;
53177ba1f9SLey Foon Tan 
54177ba1f9SLey Foon Tan #if defined(CONFIG_TARGET_SOCFPGA_GEN5)
5505a21721SMasahiro Yamada 	gd->bd->bi_ddr_freq = cm_get_sdram_clk_hz() / 1000000;
56508791a0SLey Foon Tan #else
57177ba1f9SLey Foon Tan 	gd->bd->bi_ddr_freq = 0;
58177ba1f9SLey Foon Tan #endif
5905a21721SMasahiro Yamada 
6005a21721SMasahiro Yamada 	return 0;
6105a21721SMasahiro Yamada }
6205a21721SMasahiro Yamada 
63b4b9814fSTom Rini #ifndef CONFIG_SPL_BUILD
do_showclocks(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])64b4b9814fSTom Rini static int do_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
6505a21721SMasahiro Yamada {
6605a21721SMasahiro Yamada 	cm_print_clock_quick_summary();
6705a21721SMasahiro Yamada 	return 0;
6805a21721SMasahiro Yamada }
6905a21721SMasahiro Yamada 
7005a21721SMasahiro Yamada U_BOOT_CMD(
7105a21721SMasahiro Yamada 	clocks,	CONFIG_SYS_MAXARGS, 1, do_showclocks,
7205a21721SMasahiro Yamada 	"display clocks",
7305a21721SMasahiro Yamada 	""
7405a21721SMasahiro Yamada );
75b4b9814fSTom Rini #endif
76