18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ci#include <linux/kernel.h>
48c2ecf20Sopenharmony_ci#include <linux/clk.h>
58c2ecf20Sopenharmony_ci#include <linux/clk-provider.h>
68c2ecf20Sopenharmony_ci#include <linux/clk/ti.h>
78c2ecf20Sopenharmony_ci#include <linux/of_platform.h>
88c2ecf20Sopenharmony_ci#include <dt-bindings/clock/dm814.h>
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include "clock.h"
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_cistatic const struct omap_clkctrl_reg_data dm814_default_clkctrl_regs[] __initconst = {
138c2ecf20Sopenharmony_ci	{ DM814_USB_OTG_HS_CLKCTRL, NULL, CLKF_SW_SUP, "pll260dcoclkldo" },
148c2ecf20Sopenharmony_ci	{ 0 },
158c2ecf20Sopenharmony_ci};
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_cistatic const struct omap_clkctrl_reg_data dm814_alwon_clkctrl_regs[] __initconst = {
188c2ecf20Sopenharmony_ci	{ DM814_UART1_CLKCTRL, NULL, CLKF_SW_SUP, "sysclk10_ck" },
198c2ecf20Sopenharmony_ci	{ DM814_UART2_CLKCTRL, NULL, CLKF_SW_SUP, "sysclk10_ck" },
208c2ecf20Sopenharmony_ci	{ DM814_UART3_CLKCTRL, NULL, CLKF_SW_SUP, "sysclk10_ck" },
218c2ecf20Sopenharmony_ci	{ DM814_GPIO1_CLKCTRL, NULL, CLKF_SW_SUP, "sysclk6_ck" },
228c2ecf20Sopenharmony_ci	{ DM814_GPIO2_CLKCTRL, NULL, CLKF_SW_SUP, "sysclk6_ck" },
238c2ecf20Sopenharmony_ci	{ DM814_I2C1_CLKCTRL, NULL, CLKF_SW_SUP, "sysclk10_ck" },
248c2ecf20Sopenharmony_ci	{ DM814_I2C2_CLKCTRL, NULL, CLKF_SW_SUP, "sysclk10_ck" },
258c2ecf20Sopenharmony_ci	{ DM814_WD_TIMER_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_NO_IDLEST, "sysclk18_ck" },
268c2ecf20Sopenharmony_ci	{ DM814_MCSPI1_CLKCTRL, NULL, CLKF_SW_SUP, "sysclk10_ck" },
278c2ecf20Sopenharmony_ci	{ DM814_GPMC_CLKCTRL, NULL, CLKF_SW_SUP, "sysclk6_ck" },
288c2ecf20Sopenharmony_ci	{ DM814_MPU_CLKCTRL, NULL, CLKF_SW_SUP, "mpu_ck" },
298c2ecf20Sopenharmony_ci	{ DM814_RTC_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_NO_IDLEST, "sysclk18_ck" },
308c2ecf20Sopenharmony_ci	{ DM814_TPCC_CLKCTRL, NULL, CLKF_SW_SUP, "sysclk4_ck" },
318c2ecf20Sopenharmony_ci	{ DM814_TPTC0_CLKCTRL, NULL, CLKF_SW_SUP, "sysclk4_ck" },
328c2ecf20Sopenharmony_ci	{ DM814_TPTC1_CLKCTRL, NULL, CLKF_SW_SUP, "sysclk4_ck" },
338c2ecf20Sopenharmony_ci	{ DM814_TPTC2_CLKCTRL, NULL, CLKF_SW_SUP, "sysclk4_ck" },
348c2ecf20Sopenharmony_ci	{ DM814_TPTC3_CLKCTRL, NULL, CLKF_SW_SUP, "sysclk4_ck" },
358c2ecf20Sopenharmony_ci	{ DM814_MMC1_CLKCTRL, NULL, CLKF_SW_SUP, "sysclk8_ck" },
368c2ecf20Sopenharmony_ci	{ DM814_MMC2_CLKCTRL, NULL, CLKF_SW_SUP, "sysclk8_ck" },
378c2ecf20Sopenharmony_ci	{ DM814_MMC3_CLKCTRL, NULL, CLKF_SW_SUP, "sysclk8_ck" },
388c2ecf20Sopenharmony_ci	{ 0 },
398c2ecf20Sopenharmony_ci};
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_cistatic const struct
428c2ecf20Sopenharmony_ciomap_clkctrl_reg_data dm814_alwon_ethernet_clkctrl_regs[] __initconst = {
438c2ecf20Sopenharmony_ci	{ 0, NULL, CLKF_SW_SUP, "cpsw_125mhz_gclk" },
448c2ecf20Sopenharmony_ci};
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ciconst struct omap_clkctrl_data dm814_clkctrl_data[] __initconst = {
478c2ecf20Sopenharmony_ci	{ 0x48180500, dm814_default_clkctrl_regs },
488c2ecf20Sopenharmony_ci	{ 0x48181400, dm814_alwon_clkctrl_regs },
498c2ecf20Sopenharmony_ci	{ 0x481815d4, dm814_alwon_ethernet_clkctrl_regs },
508c2ecf20Sopenharmony_ci	{ 0 },
518c2ecf20Sopenharmony_ci};
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_cistatic struct ti_dt_clk dm814_clks[] = {
548c2ecf20Sopenharmony_ci	DT_CLK(NULL, "timer_sys_ck", "devosc_ck"),
558c2ecf20Sopenharmony_ci	{ .node_name = NULL },
568c2ecf20Sopenharmony_ci};
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_cistatic bool timer_clocks_initialized;
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_cistatic int __init dm814x_adpll_early_init(void)
618c2ecf20Sopenharmony_ci{
628c2ecf20Sopenharmony_ci	struct device_node *np;
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci	if (!timer_clocks_initialized)
658c2ecf20Sopenharmony_ci		return -ENODEV;
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci	np = of_find_node_by_name(NULL, "pllss");
688c2ecf20Sopenharmony_ci	if (!np) {
698c2ecf20Sopenharmony_ci		pr_err("Could not find node for plls\n");
708c2ecf20Sopenharmony_ci		return -ENODEV;
718c2ecf20Sopenharmony_ci	}
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci	of_platform_populate(np, NULL, NULL, NULL);
748c2ecf20Sopenharmony_ci	of_node_put(np);
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci	return 0;
778c2ecf20Sopenharmony_ci}
788c2ecf20Sopenharmony_cicore_initcall(dm814x_adpll_early_init);
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_cistatic const char * const init_clocks[] = {
818c2ecf20Sopenharmony_ci	"pll040clkout",		/* MPU 481c5040.adpll.clkout */
828c2ecf20Sopenharmony_ci	"pll290clkout",		/* DDR 481c5290.adpll.clkout */
838c2ecf20Sopenharmony_ci};
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_cistatic int __init dm814x_adpll_enable_init_clocks(void)
868c2ecf20Sopenharmony_ci{
878c2ecf20Sopenharmony_ci	int i, err;
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci	if (!timer_clocks_initialized)
908c2ecf20Sopenharmony_ci		return -ENODEV;
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(init_clocks); i++) {
938c2ecf20Sopenharmony_ci		struct clk *clock;
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci		clock = clk_get(NULL, init_clocks[i]);
968c2ecf20Sopenharmony_ci		if (WARN(IS_ERR(clock), "could not find init clock %s\n",
978c2ecf20Sopenharmony_ci			 init_clocks[i]))
988c2ecf20Sopenharmony_ci			continue;
998c2ecf20Sopenharmony_ci		err = clk_prepare_enable(clock);
1008c2ecf20Sopenharmony_ci		if (WARN(err, "could not enable init clock %s\n",
1018c2ecf20Sopenharmony_ci			 init_clocks[i]))
1028c2ecf20Sopenharmony_ci			continue;
1038c2ecf20Sopenharmony_ci	}
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci	return 0;
1068c2ecf20Sopenharmony_ci}
1078c2ecf20Sopenharmony_cipostcore_initcall(dm814x_adpll_enable_init_clocks);
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ciint __init dm814x_dt_clk_init(void)
1108c2ecf20Sopenharmony_ci{
1118c2ecf20Sopenharmony_ci	ti_dt_clocks_register(dm814_clks);
1128c2ecf20Sopenharmony_ci	omap2_clk_disable_autoidle_all();
1138c2ecf20Sopenharmony_ci	ti_clk_add_aliases();
1148c2ecf20Sopenharmony_ci	omap2_clk_enable_init_clocks(NULL, 0);
1158c2ecf20Sopenharmony_ci	timer_clocks_initialized = true;
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci	return 0;
1188c2ecf20Sopenharmony_ci}
119