18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *  Port on Texas Instruments TMS320C6x architecture
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci *  Copyright (C) 2011 Texas Instruments Incorporated
68c2ecf20Sopenharmony_ci *  Author: Mark Salter <msalter@redhat.com>
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci#include <linux/kernel.h>
98c2ecf20Sopenharmony_ci#include <linux/delay.h>
108c2ecf20Sopenharmony_ci#include <linux/errno.h>
118c2ecf20Sopenharmony_ci#include <linux/string.h>
128c2ecf20Sopenharmony_ci#include <linux/ioport.h>
138c2ecf20Sopenharmony_ci#include <linux/clkdev.h>
148c2ecf20Sopenharmony_ci#include <linux/of.h>
158c2ecf20Sopenharmony_ci#include <linux/of_address.h>
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci#include <asm/clock.h>
188c2ecf20Sopenharmony_ci#include <asm/setup.h>
198c2ecf20Sopenharmony_ci#include <asm/special_insns.h>
208c2ecf20Sopenharmony_ci#include <asm/irq.h>
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci/*
238c2ecf20Sopenharmony_ci * Common SoC clock support.
248c2ecf20Sopenharmony_ci */
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci/* Default input for PLL1 */
278c2ecf20Sopenharmony_cistruct clk clkin1 = {
288c2ecf20Sopenharmony_ci	.name = "clkin1",
298c2ecf20Sopenharmony_ci	.node = LIST_HEAD_INIT(clkin1.node),
308c2ecf20Sopenharmony_ci	.children = LIST_HEAD_INIT(clkin1.children),
318c2ecf20Sopenharmony_ci	.childnode = LIST_HEAD_INIT(clkin1.childnode),
328c2ecf20Sopenharmony_ci};
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_cistruct pll_data c6x_soc_pll1 = {
358c2ecf20Sopenharmony_ci	.num	   = 1,
368c2ecf20Sopenharmony_ci	.sysclks   = {
378c2ecf20Sopenharmony_ci		{
388c2ecf20Sopenharmony_ci			.name = "pll1",
398c2ecf20Sopenharmony_ci			.parent = &clkin1,
408c2ecf20Sopenharmony_ci			.pll_data = &c6x_soc_pll1,
418c2ecf20Sopenharmony_ci			.flags = CLK_PLL,
428c2ecf20Sopenharmony_ci		},
438c2ecf20Sopenharmony_ci		{
448c2ecf20Sopenharmony_ci			.name = "pll1_sysclk1",
458c2ecf20Sopenharmony_ci			.parent = &c6x_soc_pll1.sysclks[0],
468c2ecf20Sopenharmony_ci			.flags = CLK_PLL,
478c2ecf20Sopenharmony_ci		},
488c2ecf20Sopenharmony_ci		{
498c2ecf20Sopenharmony_ci			.name = "pll1_sysclk2",
508c2ecf20Sopenharmony_ci			.parent = &c6x_soc_pll1.sysclks[0],
518c2ecf20Sopenharmony_ci			.flags = CLK_PLL,
528c2ecf20Sopenharmony_ci		},
538c2ecf20Sopenharmony_ci		{
548c2ecf20Sopenharmony_ci			.name = "pll1_sysclk3",
558c2ecf20Sopenharmony_ci			.parent = &c6x_soc_pll1.sysclks[0],
568c2ecf20Sopenharmony_ci			.flags = CLK_PLL,
578c2ecf20Sopenharmony_ci		},
588c2ecf20Sopenharmony_ci		{
598c2ecf20Sopenharmony_ci			.name = "pll1_sysclk4",
608c2ecf20Sopenharmony_ci			.parent = &c6x_soc_pll1.sysclks[0],
618c2ecf20Sopenharmony_ci			.flags = CLK_PLL,
628c2ecf20Sopenharmony_ci		},
638c2ecf20Sopenharmony_ci		{
648c2ecf20Sopenharmony_ci			.name = "pll1_sysclk5",
658c2ecf20Sopenharmony_ci			.parent = &c6x_soc_pll1.sysclks[0],
668c2ecf20Sopenharmony_ci			.flags = CLK_PLL,
678c2ecf20Sopenharmony_ci		},
688c2ecf20Sopenharmony_ci		{
698c2ecf20Sopenharmony_ci			.name = "pll1_sysclk6",
708c2ecf20Sopenharmony_ci			.parent = &c6x_soc_pll1.sysclks[0],
718c2ecf20Sopenharmony_ci			.flags = CLK_PLL,
728c2ecf20Sopenharmony_ci		},
738c2ecf20Sopenharmony_ci		{
748c2ecf20Sopenharmony_ci			.name = "pll1_sysclk7",
758c2ecf20Sopenharmony_ci			.parent = &c6x_soc_pll1.sysclks[0],
768c2ecf20Sopenharmony_ci			.flags = CLK_PLL,
778c2ecf20Sopenharmony_ci		},
788c2ecf20Sopenharmony_ci		{
798c2ecf20Sopenharmony_ci			.name = "pll1_sysclk8",
808c2ecf20Sopenharmony_ci			.parent = &c6x_soc_pll1.sysclks[0],
818c2ecf20Sopenharmony_ci			.flags = CLK_PLL,
828c2ecf20Sopenharmony_ci		},
838c2ecf20Sopenharmony_ci		{
848c2ecf20Sopenharmony_ci			.name = "pll1_sysclk9",
858c2ecf20Sopenharmony_ci			.parent = &c6x_soc_pll1.sysclks[0],
868c2ecf20Sopenharmony_ci			.flags = CLK_PLL,
878c2ecf20Sopenharmony_ci		},
888c2ecf20Sopenharmony_ci		{
898c2ecf20Sopenharmony_ci			.name = "pll1_sysclk10",
908c2ecf20Sopenharmony_ci			.parent = &c6x_soc_pll1.sysclks[0],
918c2ecf20Sopenharmony_ci			.flags = CLK_PLL,
928c2ecf20Sopenharmony_ci		},
938c2ecf20Sopenharmony_ci		{
948c2ecf20Sopenharmony_ci			.name = "pll1_sysclk11",
958c2ecf20Sopenharmony_ci			.parent = &c6x_soc_pll1.sysclks[0],
968c2ecf20Sopenharmony_ci			.flags = CLK_PLL,
978c2ecf20Sopenharmony_ci		},
988c2ecf20Sopenharmony_ci		{
998c2ecf20Sopenharmony_ci			.name = "pll1_sysclk12",
1008c2ecf20Sopenharmony_ci			.parent = &c6x_soc_pll1.sysclks[0],
1018c2ecf20Sopenharmony_ci			.flags = CLK_PLL,
1028c2ecf20Sopenharmony_ci		},
1038c2ecf20Sopenharmony_ci		{
1048c2ecf20Sopenharmony_ci			.name = "pll1_sysclk13",
1058c2ecf20Sopenharmony_ci			.parent = &c6x_soc_pll1.sysclks[0],
1068c2ecf20Sopenharmony_ci			.flags = CLK_PLL,
1078c2ecf20Sopenharmony_ci		},
1088c2ecf20Sopenharmony_ci		{
1098c2ecf20Sopenharmony_ci			.name = "pll1_sysclk14",
1108c2ecf20Sopenharmony_ci			.parent = &c6x_soc_pll1.sysclks[0],
1118c2ecf20Sopenharmony_ci			.flags = CLK_PLL,
1128c2ecf20Sopenharmony_ci		},
1138c2ecf20Sopenharmony_ci		{
1148c2ecf20Sopenharmony_ci			.name = "pll1_sysclk15",
1158c2ecf20Sopenharmony_ci			.parent = &c6x_soc_pll1.sysclks[0],
1168c2ecf20Sopenharmony_ci			.flags = CLK_PLL,
1178c2ecf20Sopenharmony_ci		},
1188c2ecf20Sopenharmony_ci		{
1198c2ecf20Sopenharmony_ci			.name = "pll1_sysclk16",
1208c2ecf20Sopenharmony_ci			.parent = &c6x_soc_pll1.sysclks[0],
1218c2ecf20Sopenharmony_ci			.flags = CLK_PLL,
1228c2ecf20Sopenharmony_ci		},
1238c2ecf20Sopenharmony_ci	},
1248c2ecf20Sopenharmony_ci};
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ci/* CPU core clock */
1278c2ecf20Sopenharmony_cistruct clk c6x_core_clk = {
1288c2ecf20Sopenharmony_ci	.name = "core",
1298c2ecf20Sopenharmony_ci};
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci/* miscellaneous IO clocks */
1328c2ecf20Sopenharmony_cistruct clk c6x_i2c_clk = {
1338c2ecf20Sopenharmony_ci	.name = "i2c",
1348c2ecf20Sopenharmony_ci};
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_cistruct clk c6x_watchdog_clk = {
1378c2ecf20Sopenharmony_ci	.name = "watchdog",
1388c2ecf20Sopenharmony_ci};
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_cistruct clk c6x_mcbsp1_clk = {
1418c2ecf20Sopenharmony_ci	.name = "mcbsp1",
1428c2ecf20Sopenharmony_ci};
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_cistruct clk c6x_mcbsp2_clk = {
1458c2ecf20Sopenharmony_ci	.name = "mcbsp2",
1468c2ecf20Sopenharmony_ci};
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_cistruct clk c6x_mdio_clk = {
1498c2ecf20Sopenharmony_ci	.name = "mdio",
1508c2ecf20Sopenharmony_ci};
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci#ifdef CONFIG_SOC_TMS320C6455
1548c2ecf20Sopenharmony_cistatic struct clk_lookup c6455_clks[] = {
1558c2ecf20Sopenharmony_ci	CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]),
1568c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk2", &c6x_soc_pll1.sysclks[2]),
1578c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk3", &c6x_soc_pll1.sysclks[3]),
1588c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk4", &c6x_soc_pll1.sysclks[4]),
1598c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk5", &c6x_soc_pll1.sysclks[5]),
1608c2ecf20Sopenharmony_ci	CLK(NULL, "core", &c6x_core_clk),
1618c2ecf20Sopenharmony_ci	CLK("i2c_davinci.1", NULL, &c6x_i2c_clk),
1628c2ecf20Sopenharmony_ci	CLK("watchdog", NULL, &c6x_watchdog_clk),
1638c2ecf20Sopenharmony_ci	CLK("2c81800.mdio", NULL, &c6x_mdio_clk),
1648c2ecf20Sopenharmony_ci	CLK("", NULL, NULL)
1658c2ecf20Sopenharmony_ci};
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_cistatic void __init c6455_setup_clocks(struct device_node *node)
1698c2ecf20Sopenharmony_ci{
1708c2ecf20Sopenharmony_ci	struct pll_data *pll = &c6x_soc_pll1;
1718c2ecf20Sopenharmony_ci	struct clk *sysclks = pll->sysclks;
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_ci	pll->flags = PLL_HAS_PRE | PLL_HAS_MUL;
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ci	sysclks[2].flags |= FIXED_DIV_PLL;
1768c2ecf20Sopenharmony_ci	sysclks[2].div = 3;
1778c2ecf20Sopenharmony_ci	sysclks[3].flags |= FIXED_DIV_PLL;
1788c2ecf20Sopenharmony_ci	sysclks[3].div = 6;
1798c2ecf20Sopenharmony_ci	sysclks[4].div = PLLDIV4;
1808c2ecf20Sopenharmony_ci	sysclks[5].div = PLLDIV5;
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ci	c6x_core_clk.parent = &sysclks[0];
1838c2ecf20Sopenharmony_ci	c6x_i2c_clk.parent = &sysclks[3];
1848c2ecf20Sopenharmony_ci	c6x_watchdog_clk.parent = &sysclks[3];
1858c2ecf20Sopenharmony_ci	c6x_mdio_clk.parent = &sysclks[3];
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci	c6x_clks_init(c6455_clks);
1888c2ecf20Sopenharmony_ci}
1898c2ecf20Sopenharmony_ci#endif /* CONFIG_SOC_TMS320C6455 */
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_ci#ifdef CONFIG_SOC_TMS320C6457
1928c2ecf20Sopenharmony_cistatic struct clk_lookup c6457_clks[] = {
1938c2ecf20Sopenharmony_ci	CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]),
1948c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk1", &c6x_soc_pll1.sysclks[1]),
1958c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk2", &c6x_soc_pll1.sysclks[2]),
1968c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk3", &c6x_soc_pll1.sysclks[3]),
1978c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk4", &c6x_soc_pll1.sysclks[4]),
1988c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk5", &c6x_soc_pll1.sysclks[5]),
1998c2ecf20Sopenharmony_ci	CLK(NULL, "core", &c6x_core_clk),
2008c2ecf20Sopenharmony_ci	CLK("i2c_davinci.1", NULL, &c6x_i2c_clk),
2018c2ecf20Sopenharmony_ci	CLK("watchdog", NULL, &c6x_watchdog_clk),
2028c2ecf20Sopenharmony_ci	CLK("2c81800.mdio", NULL, &c6x_mdio_clk),
2038c2ecf20Sopenharmony_ci	CLK("", NULL, NULL)
2048c2ecf20Sopenharmony_ci};
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_cistatic void __init c6457_setup_clocks(struct device_node *node)
2078c2ecf20Sopenharmony_ci{
2088c2ecf20Sopenharmony_ci	struct pll_data *pll = &c6x_soc_pll1;
2098c2ecf20Sopenharmony_ci	struct clk *sysclks = pll->sysclks;
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_ci	pll->flags = PLL_HAS_MUL | PLL_HAS_POST;
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_ci	sysclks[1].flags |= FIXED_DIV_PLL;
2148c2ecf20Sopenharmony_ci	sysclks[1].div = 1;
2158c2ecf20Sopenharmony_ci	sysclks[2].flags |= FIXED_DIV_PLL;
2168c2ecf20Sopenharmony_ci	sysclks[2].div = 3;
2178c2ecf20Sopenharmony_ci	sysclks[3].flags |= FIXED_DIV_PLL;
2188c2ecf20Sopenharmony_ci	sysclks[3].div = 6;
2198c2ecf20Sopenharmony_ci	sysclks[4].div = PLLDIV4;
2208c2ecf20Sopenharmony_ci	sysclks[5].div = PLLDIV5;
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_ci	c6x_core_clk.parent = &sysclks[1];
2238c2ecf20Sopenharmony_ci	c6x_i2c_clk.parent = &sysclks[3];
2248c2ecf20Sopenharmony_ci	c6x_watchdog_clk.parent = &sysclks[5];
2258c2ecf20Sopenharmony_ci	c6x_mdio_clk.parent = &sysclks[5];
2268c2ecf20Sopenharmony_ci
2278c2ecf20Sopenharmony_ci	c6x_clks_init(c6457_clks);
2288c2ecf20Sopenharmony_ci}
2298c2ecf20Sopenharmony_ci#endif /* CONFIG_SOC_TMS320C6455 */
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_ci#ifdef CONFIG_SOC_TMS320C6472
2328c2ecf20Sopenharmony_cistatic struct clk_lookup c6472_clks[] = {
2338c2ecf20Sopenharmony_ci	CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]),
2348c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk1", &c6x_soc_pll1.sysclks[1]),
2358c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk2", &c6x_soc_pll1.sysclks[2]),
2368c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk3", &c6x_soc_pll1.sysclks[3]),
2378c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk4", &c6x_soc_pll1.sysclks[4]),
2388c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk5", &c6x_soc_pll1.sysclks[5]),
2398c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk6", &c6x_soc_pll1.sysclks[6]),
2408c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk7", &c6x_soc_pll1.sysclks[7]),
2418c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk8", &c6x_soc_pll1.sysclks[8]),
2428c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk9", &c6x_soc_pll1.sysclks[9]),
2438c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk10", &c6x_soc_pll1.sysclks[10]),
2448c2ecf20Sopenharmony_ci	CLK(NULL, "core", &c6x_core_clk),
2458c2ecf20Sopenharmony_ci	CLK("i2c_davinci.1", NULL, &c6x_i2c_clk),
2468c2ecf20Sopenharmony_ci	CLK("watchdog", NULL, &c6x_watchdog_clk),
2478c2ecf20Sopenharmony_ci	CLK("2c81800.mdio", NULL, &c6x_mdio_clk),
2488c2ecf20Sopenharmony_ci	CLK("", NULL, NULL)
2498c2ecf20Sopenharmony_ci};
2508c2ecf20Sopenharmony_ci
2518c2ecf20Sopenharmony_ci/* assumptions used for delay loop calculations */
2528c2ecf20Sopenharmony_ci#define MIN_CLKIN1_KHz 15625
2538c2ecf20Sopenharmony_ci#define MAX_CORE_KHz   700000
2548c2ecf20Sopenharmony_ci#define MIN_PLLOUT_KHz MIN_CLKIN1_KHz
2558c2ecf20Sopenharmony_ci
2568c2ecf20Sopenharmony_cistatic void __init c6472_setup_clocks(struct device_node *node)
2578c2ecf20Sopenharmony_ci{
2588c2ecf20Sopenharmony_ci	struct pll_data *pll = &c6x_soc_pll1;
2598c2ecf20Sopenharmony_ci	struct clk *sysclks = pll->sysclks;
2608c2ecf20Sopenharmony_ci	int i;
2618c2ecf20Sopenharmony_ci
2628c2ecf20Sopenharmony_ci	pll->flags = PLL_HAS_MUL;
2638c2ecf20Sopenharmony_ci
2648c2ecf20Sopenharmony_ci	for (i = 1; i <= 6; i++) {
2658c2ecf20Sopenharmony_ci		sysclks[i].flags |= FIXED_DIV_PLL;
2668c2ecf20Sopenharmony_ci		sysclks[i].div = 1;
2678c2ecf20Sopenharmony_ci	}
2688c2ecf20Sopenharmony_ci
2698c2ecf20Sopenharmony_ci	sysclks[7].flags |= FIXED_DIV_PLL;
2708c2ecf20Sopenharmony_ci	sysclks[7].div = 3;
2718c2ecf20Sopenharmony_ci	sysclks[8].flags |= FIXED_DIV_PLL;
2728c2ecf20Sopenharmony_ci	sysclks[8].div = 6;
2738c2ecf20Sopenharmony_ci	sysclks[9].flags |= FIXED_DIV_PLL;
2748c2ecf20Sopenharmony_ci	sysclks[9].div = 2;
2758c2ecf20Sopenharmony_ci	sysclks[10].div = PLLDIV10;
2768c2ecf20Sopenharmony_ci
2778c2ecf20Sopenharmony_ci	c6x_core_clk.parent = &sysclks[get_coreid() + 1];
2788c2ecf20Sopenharmony_ci	c6x_i2c_clk.parent = &sysclks[8];
2798c2ecf20Sopenharmony_ci	c6x_watchdog_clk.parent = &sysclks[8];
2808c2ecf20Sopenharmony_ci	c6x_mdio_clk.parent = &sysclks[5];
2818c2ecf20Sopenharmony_ci
2828c2ecf20Sopenharmony_ci	c6x_clks_init(c6472_clks);
2838c2ecf20Sopenharmony_ci}
2848c2ecf20Sopenharmony_ci#endif /* CONFIG_SOC_TMS320C6472 */
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_ci
2878c2ecf20Sopenharmony_ci#ifdef CONFIG_SOC_TMS320C6474
2888c2ecf20Sopenharmony_cistatic struct clk_lookup c6474_clks[] = {
2898c2ecf20Sopenharmony_ci	CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]),
2908c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk7", &c6x_soc_pll1.sysclks[7]),
2918c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk9", &c6x_soc_pll1.sysclks[9]),
2928c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk10", &c6x_soc_pll1.sysclks[10]),
2938c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk11", &c6x_soc_pll1.sysclks[11]),
2948c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk12", &c6x_soc_pll1.sysclks[12]),
2958c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk13", &c6x_soc_pll1.sysclks[13]),
2968c2ecf20Sopenharmony_ci	CLK(NULL, "core", &c6x_core_clk),
2978c2ecf20Sopenharmony_ci	CLK("i2c_davinci.1", NULL, &c6x_i2c_clk),
2988c2ecf20Sopenharmony_ci	CLK("mcbsp.1", NULL, &c6x_mcbsp1_clk),
2998c2ecf20Sopenharmony_ci	CLK("mcbsp.2", NULL, &c6x_mcbsp2_clk),
3008c2ecf20Sopenharmony_ci	CLK("watchdog", NULL, &c6x_watchdog_clk),
3018c2ecf20Sopenharmony_ci	CLK("2c81800.mdio", NULL, &c6x_mdio_clk),
3028c2ecf20Sopenharmony_ci	CLK("", NULL, NULL)
3038c2ecf20Sopenharmony_ci};
3048c2ecf20Sopenharmony_ci
3058c2ecf20Sopenharmony_cistatic void __init c6474_setup_clocks(struct device_node *node)
3068c2ecf20Sopenharmony_ci{
3078c2ecf20Sopenharmony_ci	struct pll_data *pll = &c6x_soc_pll1;
3088c2ecf20Sopenharmony_ci	struct clk *sysclks = pll->sysclks;
3098c2ecf20Sopenharmony_ci
3108c2ecf20Sopenharmony_ci	pll->flags = PLL_HAS_MUL;
3118c2ecf20Sopenharmony_ci
3128c2ecf20Sopenharmony_ci	sysclks[7].flags |= FIXED_DIV_PLL;
3138c2ecf20Sopenharmony_ci	sysclks[7].div = 1;
3148c2ecf20Sopenharmony_ci	sysclks[9].flags |= FIXED_DIV_PLL;
3158c2ecf20Sopenharmony_ci	sysclks[9].div = 3;
3168c2ecf20Sopenharmony_ci	sysclks[10].flags |= FIXED_DIV_PLL;
3178c2ecf20Sopenharmony_ci	sysclks[10].div = 6;
3188c2ecf20Sopenharmony_ci
3198c2ecf20Sopenharmony_ci	sysclks[11].div = PLLDIV11;
3208c2ecf20Sopenharmony_ci
3218c2ecf20Sopenharmony_ci	sysclks[12].flags |= FIXED_DIV_PLL;
3228c2ecf20Sopenharmony_ci	sysclks[12].div = 2;
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_ci	sysclks[13].div = PLLDIV13;
3258c2ecf20Sopenharmony_ci
3268c2ecf20Sopenharmony_ci	c6x_core_clk.parent = &sysclks[7];
3278c2ecf20Sopenharmony_ci	c6x_i2c_clk.parent = &sysclks[10];
3288c2ecf20Sopenharmony_ci	c6x_watchdog_clk.parent = &sysclks[10];
3298c2ecf20Sopenharmony_ci	c6x_mcbsp1_clk.parent = &sysclks[10];
3308c2ecf20Sopenharmony_ci	c6x_mcbsp2_clk.parent = &sysclks[10];
3318c2ecf20Sopenharmony_ci
3328c2ecf20Sopenharmony_ci	c6x_clks_init(c6474_clks);
3338c2ecf20Sopenharmony_ci}
3348c2ecf20Sopenharmony_ci#endif /* CONFIG_SOC_TMS320C6474 */
3358c2ecf20Sopenharmony_ci
3368c2ecf20Sopenharmony_ci#ifdef CONFIG_SOC_TMS320C6678
3378c2ecf20Sopenharmony_cistatic struct clk_lookup c6678_clks[] = {
3388c2ecf20Sopenharmony_ci	CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]),
3398c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_refclk", &c6x_soc_pll1.sysclks[1]),
3408c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk2", &c6x_soc_pll1.sysclks[2]),
3418c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk3", &c6x_soc_pll1.sysclks[3]),
3428c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk4", &c6x_soc_pll1.sysclks[4]),
3438c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk5", &c6x_soc_pll1.sysclks[5]),
3448c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk6", &c6x_soc_pll1.sysclks[6]),
3458c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk7", &c6x_soc_pll1.sysclks[7]),
3468c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk8", &c6x_soc_pll1.sysclks[8]),
3478c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk9", &c6x_soc_pll1.sysclks[9]),
3488c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk10", &c6x_soc_pll1.sysclks[10]),
3498c2ecf20Sopenharmony_ci	CLK(NULL, "pll1_sysclk11", &c6x_soc_pll1.sysclks[11]),
3508c2ecf20Sopenharmony_ci	CLK(NULL, "core", &c6x_core_clk),
3518c2ecf20Sopenharmony_ci	CLK("", NULL, NULL)
3528c2ecf20Sopenharmony_ci};
3538c2ecf20Sopenharmony_ci
3548c2ecf20Sopenharmony_cistatic void __init c6678_setup_clocks(struct device_node *node)
3558c2ecf20Sopenharmony_ci{
3568c2ecf20Sopenharmony_ci	struct pll_data *pll = &c6x_soc_pll1;
3578c2ecf20Sopenharmony_ci	struct clk *sysclks = pll->sysclks;
3588c2ecf20Sopenharmony_ci
3598c2ecf20Sopenharmony_ci	pll->flags = PLL_HAS_MUL;
3608c2ecf20Sopenharmony_ci
3618c2ecf20Sopenharmony_ci	sysclks[1].flags |= FIXED_DIV_PLL;
3628c2ecf20Sopenharmony_ci	sysclks[1].div = 1;
3638c2ecf20Sopenharmony_ci
3648c2ecf20Sopenharmony_ci	sysclks[2].div = PLLDIV2;
3658c2ecf20Sopenharmony_ci
3668c2ecf20Sopenharmony_ci	sysclks[3].flags |= FIXED_DIV_PLL;
3678c2ecf20Sopenharmony_ci	sysclks[3].div = 2;
3688c2ecf20Sopenharmony_ci
3698c2ecf20Sopenharmony_ci	sysclks[4].flags |= FIXED_DIV_PLL;
3708c2ecf20Sopenharmony_ci	sysclks[4].div = 3;
3718c2ecf20Sopenharmony_ci
3728c2ecf20Sopenharmony_ci	sysclks[5].div = PLLDIV5;
3738c2ecf20Sopenharmony_ci
3748c2ecf20Sopenharmony_ci	sysclks[6].flags |= FIXED_DIV_PLL;
3758c2ecf20Sopenharmony_ci	sysclks[6].div = 64;
3768c2ecf20Sopenharmony_ci
3778c2ecf20Sopenharmony_ci	sysclks[7].flags |= FIXED_DIV_PLL;
3788c2ecf20Sopenharmony_ci	sysclks[7].div = 6;
3798c2ecf20Sopenharmony_ci
3808c2ecf20Sopenharmony_ci	sysclks[8].div = PLLDIV8;
3818c2ecf20Sopenharmony_ci
3828c2ecf20Sopenharmony_ci	sysclks[9].flags |= FIXED_DIV_PLL;
3838c2ecf20Sopenharmony_ci	sysclks[9].div = 12;
3848c2ecf20Sopenharmony_ci
3858c2ecf20Sopenharmony_ci	sysclks[10].flags |= FIXED_DIV_PLL;
3868c2ecf20Sopenharmony_ci	sysclks[10].div = 3;
3878c2ecf20Sopenharmony_ci
3888c2ecf20Sopenharmony_ci	sysclks[11].flags |= FIXED_DIV_PLL;
3898c2ecf20Sopenharmony_ci	sysclks[11].div = 6;
3908c2ecf20Sopenharmony_ci
3918c2ecf20Sopenharmony_ci	c6x_core_clk.parent = &sysclks[0];
3928c2ecf20Sopenharmony_ci	c6x_i2c_clk.parent = &sysclks[7];
3938c2ecf20Sopenharmony_ci
3948c2ecf20Sopenharmony_ci	c6x_clks_init(c6678_clks);
3958c2ecf20Sopenharmony_ci}
3968c2ecf20Sopenharmony_ci#endif /* CONFIG_SOC_TMS320C6678 */
3978c2ecf20Sopenharmony_ci
3988c2ecf20Sopenharmony_cistatic struct of_device_id c6x_clkc_match[] __initdata = {
3998c2ecf20Sopenharmony_ci#ifdef CONFIG_SOC_TMS320C6455
4008c2ecf20Sopenharmony_ci	{ .compatible = "ti,c6455-pll", .data = c6455_setup_clocks },
4018c2ecf20Sopenharmony_ci#endif
4028c2ecf20Sopenharmony_ci#ifdef CONFIG_SOC_TMS320C6457
4038c2ecf20Sopenharmony_ci	{ .compatible = "ti,c6457-pll", .data = c6457_setup_clocks },
4048c2ecf20Sopenharmony_ci#endif
4058c2ecf20Sopenharmony_ci#ifdef CONFIG_SOC_TMS320C6472
4068c2ecf20Sopenharmony_ci	{ .compatible = "ti,c6472-pll", .data = c6472_setup_clocks },
4078c2ecf20Sopenharmony_ci#endif
4088c2ecf20Sopenharmony_ci#ifdef CONFIG_SOC_TMS320C6474
4098c2ecf20Sopenharmony_ci	{ .compatible = "ti,c6474-pll", .data = c6474_setup_clocks },
4108c2ecf20Sopenharmony_ci#endif
4118c2ecf20Sopenharmony_ci#ifdef CONFIG_SOC_TMS320C6678
4128c2ecf20Sopenharmony_ci	{ .compatible = "ti,c6678-pll", .data = c6678_setup_clocks },
4138c2ecf20Sopenharmony_ci#endif
4148c2ecf20Sopenharmony_ci	{ .compatible = "ti,c64x+pll" },
4158c2ecf20Sopenharmony_ci	{}
4168c2ecf20Sopenharmony_ci};
4178c2ecf20Sopenharmony_ci
4188c2ecf20Sopenharmony_civoid __init c64x_setup_clocks(void)
4198c2ecf20Sopenharmony_ci{
4208c2ecf20Sopenharmony_ci	void (*__setup_clocks)(struct device_node *np);
4218c2ecf20Sopenharmony_ci	struct pll_data *pll = &c6x_soc_pll1;
4228c2ecf20Sopenharmony_ci	struct device_node *node;
4238c2ecf20Sopenharmony_ci	const struct of_device_id *id;
4248c2ecf20Sopenharmony_ci	int err;
4258c2ecf20Sopenharmony_ci	u32 val;
4268c2ecf20Sopenharmony_ci
4278c2ecf20Sopenharmony_ci	node = of_find_matching_node(NULL, c6x_clkc_match);
4288c2ecf20Sopenharmony_ci	if (!node)
4298c2ecf20Sopenharmony_ci		return;
4308c2ecf20Sopenharmony_ci
4318c2ecf20Sopenharmony_ci	pll->base = of_iomap(node, 0);
4328c2ecf20Sopenharmony_ci	if (!pll->base)
4338c2ecf20Sopenharmony_ci		goto out;
4348c2ecf20Sopenharmony_ci
4358c2ecf20Sopenharmony_ci	err = of_property_read_u32(node, "clock-frequency", &val);
4368c2ecf20Sopenharmony_ci	if (err || val == 0) {
4378c2ecf20Sopenharmony_ci		pr_err("%pOF: no clock-frequency found! Using %dMHz\n",
4388c2ecf20Sopenharmony_ci		       node, (int)val / 1000000);
4398c2ecf20Sopenharmony_ci		val = 25000000;
4408c2ecf20Sopenharmony_ci	}
4418c2ecf20Sopenharmony_ci	clkin1.rate = val;
4428c2ecf20Sopenharmony_ci
4438c2ecf20Sopenharmony_ci	err = of_property_read_u32(node, "ti,c64x+pll-bypass-delay", &val);
4448c2ecf20Sopenharmony_ci	if (err)
4458c2ecf20Sopenharmony_ci		val = 5000;
4468c2ecf20Sopenharmony_ci	pll->bypass_delay = val;
4478c2ecf20Sopenharmony_ci
4488c2ecf20Sopenharmony_ci	err = of_property_read_u32(node, "ti,c64x+pll-reset-delay", &val);
4498c2ecf20Sopenharmony_ci	if (err)
4508c2ecf20Sopenharmony_ci		val = 30000;
4518c2ecf20Sopenharmony_ci	pll->reset_delay = val;
4528c2ecf20Sopenharmony_ci
4538c2ecf20Sopenharmony_ci	err = of_property_read_u32(node, "ti,c64x+pll-lock-delay", &val);
4548c2ecf20Sopenharmony_ci	if (err)
4558c2ecf20Sopenharmony_ci		val = 30000;
4568c2ecf20Sopenharmony_ci	pll->lock_delay = val;
4578c2ecf20Sopenharmony_ci
4588c2ecf20Sopenharmony_ci	/* id->data is a pointer to SoC-specific setup */
4598c2ecf20Sopenharmony_ci	id = of_match_node(c6x_clkc_match, node);
4608c2ecf20Sopenharmony_ci	if (id && id->data) {
4618c2ecf20Sopenharmony_ci		__setup_clocks = id->data;
4628c2ecf20Sopenharmony_ci		__setup_clocks(node);
4638c2ecf20Sopenharmony_ci	}
4648c2ecf20Sopenharmony_ci
4658c2ecf20Sopenharmony_ciout:
4668c2ecf20Sopenharmony_ci	of_node_put(node);
4678c2ecf20Sopenharmony_ci}
468