18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (c) 2014, The Linux Foundation. All rights reserved.
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#include <linux/kernel.h>
78c2ecf20Sopenharmony_ci#include <linux/bitops.h>
88c2ecf20Sopenharmony_ci#include <linux/err.h>
98c2ecf20Sopenharmony_ci#include <linux/platform_device.h>
108c2ecf20Sopenharmony_ci#include <linux/module.h>
118c2ecf20Sopenharmony_ci#include <linux/of.h>
128c2ecf20Sopenharmony_ci#include <linux/of_device.h>
138c2ecf20Sopenharmony_ci#include <linux/clk-provider.h>
148c2ecf20Sopenharmony_ci#include <linux/regmap.h>
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci#include <dt-bindings/clock/qcom,lcc-ipq806x.h>
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#include "common.h"
198c2ecf20Sopenharmony_ci#include "clk-regmap.h"
208c2ecf20Sopenharmony_ci#include "clk-pll.h"
218c2ecf20Sopenharmony_ci#include "clk-rcg.h"
228c2ecf20Sopenharmony_ci#include "clk-branch.h"
238c2ecf20Sopenharmony_ci#include "clk-regmap-divider.h"
248c2ecf20Sopenharmony_ci#include "clk-regmap-mux.h"
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_cistatic struct clk_pll pll4 = {
278c2ecf20Sopenharmony_ci	.l_reg = 0x4,
288c2ecf20Sopenharmony_ci	.m_reg = 0x8,
298c2ecf20Sopenharmony_ci	.n_reg = 0xc,
308c2ecf20Sopenharmony_ci	.config_reg = 0x14,
318c2ecf20Sopenharmony_ci	.mode_reg = 0x0,
328c2ecf20Sopenharmony_ci	.status_reg = 0x18,
338c2ecf20Sopenharmony_ci	.status_bit = 16,
348c2ecf20Sopenharmony_ci	.clkr.hw.init = &(struct clk_init_data){
358c2ecf20Sopenharmony_ci		.name = "pll4",
368c2ecf20Sopenharmony_ci		.parent_names = (const char *[]){ "pxo" },
378c2ecf20Sopenharmony_ci		.num_parents = 1,
388c2ecf20Sopenharmony_ci		.ops = &clk_pll_ops,
398c2ecf20Sopenharmony_ci	},
408c2ecf20Sopenharmony_ci};
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_cistatic const struct pll_config pll4_config = {
438c2ecf20Sopenharmony_ci	.l = 0xf,
448c2ecf20Sopenharmony_ci	.m = 0x91,
458c2ecf20Sopenharmony_ci	.n = 0xc7,
468c2ecf20Sopenharmony_ci	.vco_val = 0x0,
478c2ecf20Sopenharmony_ci	.vco_mask = BIT(17) | BIT(16),
488c2ecf20Sopenharmony_ci	.pre_div_val = 0x0,
498c2ecf20Sopenharmony_ci	.pre_div_mask = BIT(19),
508c2ecf20Sopenharmony_ci	.post_div_val = 0x0,
518c2ecf20Sopenharmony_ci	.post_div_mask = BIT(21) | BIT(20),
528c2ecf20Sopenharmony_ci	.mn_ena_mask = BIT(22),
538c2ecf20Sopenharmony_ci	.main_output_mask = BIT(23),
548c2ecf20Sopenharmony_ci};
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_cienum {
578c2ecf20Sopenharmony_ci	P_PXO,
588c2ecf20Sopenharmony_ci	P_PLL4,
598c2ecf20Sopenharmony_ci};
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_cistatic const struct parent_map lcc_pxo_pll4_map[] = {
628c2ecf20Sopenharmony_ci	{ P_PXO, 0 },
638c2ecf20Sopenharmony_ci	{ P_PLL4, 2 }
648c2ecf20Sopenharmony_ci};
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_cistatic const char * const lcc_pxo_pll4[] = {
678c2ecf20Sopenharmony_ci	"pxo",
688c2ecf20Sopenharmony_ci	"pll4_vote",
698c2ecf20Sopenharmony_ci};
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_cistatic struct freq_tbl clk_tbl_aif_mi2s[] = {
728c2ecf20Sopenharmony_ci	{  1024000, P_PLL4, 4,  1,  96 },
738c2ecf20Sopenharmony_ci	{  1411200, P_PLL4, 4,  2, 139 },
748c2ecf20Sopenharmony_ci	{  1536000, P_PLL4, 4,  1,  64 },
758c2ecf20Sopenharmony_ci	{  2048000, P_PLL4, 4,  1,  48 },
768c2ecf20Sopenharmony_ci	{  2116800, P_PLL4, 4,  2,  93 },
778c2ecf20Sopenharmony_ci	{  2304000, P_PLL4, 4,  2,  85 },
788c2ecf20Sopenharmony_ci	{  2822400, P_PLL4, 4,  6, 209 },
798c2ecf20Sopenharmony_ci	{  3072000, P_PLL4, 4,  1,  32 },
808c2ecf20Sopenharmony_ci	{  3175200, P_PLL4, 4,  1,  31 },
818c2ecf20Sopenharmony_ci	{  4096000, P_PLL4, 4,  1,  24 },
828c2ecf20Sopenharmony_ci	{  4233600, P_PLL4, 4,  9, 209 },
838c2ecf20Sopenharmony_ci	{  4608000, P_PLL4, 4,  3,  64 },
848c2ecf20Sopenharmony_ci	{  5644800, P_PLL4, 4, 12, 209 },
858c2ecf20Sopenharmony_ci	{  6144000, P_PLL4, 4,  1,  16 },
868c2ecf20Sopenharmony_ci	{  6350400, P_PLL4, 4,  2,  31 },
878c2ecf20Sopenharmony_ci	{  8192000, P_PLL4, 4,  1,  12 },
888c2ecf20Sopenharmony_ci	{  8467200, P_PLL4, 4, 18, 209 },
898c2ecf20Sopenharmony_ci	{  9216000, P_PLL4, 4,  3,  32 },
908c2ecf20Sopenharmony_ci	{ 11289600, P_PLL4, 4, 24, 209 },
918c2ecf20Sopenharmony_ci	{ 12288000, P_PLL4, 4,  1,   8 },
928c2ecf20Sopenharmony_ci	{ 12700800, P_PLL4, 4, 27, 209 },
938c2ecf20Sopenharmony_ci	{ 13824000, P_PLL4, 4,  9,  64 },
948c2ecf20Sopenharmony_ci	{ 16384000, P_PLL4, 4,  1,   6 },
958c2ecf20Sopenharmony_ci	{ 16934400, P_PLL4, 4, 41, 238 },
968c2ecf20Sopenharmony_ci	{ 18432000, P_PLL4, 4,  3,  16 },
978c2ecf20Sopenharmony_ci	{ 22579200, P_PLL4, 2, 24, 209 },
988c2ecf20Sopenharmony_ci	{ 24576000, P_PLL4, 4,  1,   4 },
998c2ecf20Sopenharmony_ci	{ 27648000, P_PLL4, 4,  9,  32 },
1008c2ecf20Sopenharmony_ci	{ 33868800, P_PLL4, 4, 41, 119 },
1018c2ecf20Sopenharmony_ci	{ 36864000, P_PLL4, 4,  3,   8 },
1028c2ecf20Sopenharmony_ci	{ 45158400, P_PLL4, 1, 24, 209 },
1038c2ecf20Sopenharmony_ci	{ 49152000, P_PLL4, 4,  1,   2 },
1048c2ecf20Sopenharmony_ci	{ 50803200, P_PLL4, 1, 27, 209 },
1058c2ecf20Sopenharmony_ci	{ }
1068c2ecf20Sopenharmony_ci};
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_cistatic struct clk_rcg mi2s_osr_src = {
1098c2ecf20Sopenharmony_ci	.ns_reg = 0x48,
1108c2ecf20Sopenharmony_ci	.md_reg = 0x4c,
1118c2ecf20Sopenharmony_ci	.mn = {
1128c2ecf20Sopenharmony_ci		.mnctr_en_bit = 8,
1138c2ecf20Sopenharmony_ci		.mnctr_reset_bit = 7,
1148c2ecf20Sopenharmony_ci		.mnctr_mode_shift = 5,
1158c2ecf20Sopenharmony_ci		.n_val_shift = 24,
1168c2ecf20Sopenharmony_ci		.m_val_shift = 8,
1178c2ecf20Sopenharmony_ci		.width = 8,
1188c2ecf20Sopenharmony_ci	},
1198c2ecf20Sopenharmony_ci	.p = {
1208c2ecf20Sopenharmony_ci		.pre_div_shift = 3,
1218c2ecf20Sopenharmony_ci		.pre_div_width = 2,
1228c2ecf20Sopenharmony_ci	},
1238c2ecf20Sopenharmony_ci	.s = {
1248c2ecf20Sopenharmony_ci		.src_sel_shift = 0,
1258c2ecf20Sopenharmony_ci		.parent_map = lcc_pxo_pll4_map,
1268c2ecf20Sopenharmony_ci	},
1278c2ecf20Sopenharmony_ci	.freq_tbl = clk_tbl_aif_mi2s,
1288c2ecf20Sopenharmony_ci	.clkr = {
1298c2ecf20Sopenharmony_ci		.enable_reg = 0x48,
1308c2ecf20Sopenharmony_ci		.enable_mask = BIT(9),
1318c2ecf20Sopenharmony_ci		.hw.init = &(struct clk_init_data){
1328c2ecf20Sopenharmony_ci			.name = "mi2s_osr_src",
1338c2ecf20Sopenharmony_ci			.parent_names = lcc_pxo_pll4,
1348c2ecf20Sopenharmony_ci			.num_parents = 2,
1358c2ecf20Sopenharmony_ci			.ops = &clk_rcg_ops,
1368c2ecf20Sopenharmony_ci			.flags = CLK_SET_RATE_GATE,
1378c2ecf20Sopenharmony_ci		},
1388c2ecf20Sopenharmony_ci	},
1398c2ecf20Sopenharmony_ci};
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_cistatic const char * const lcc_mi2s_parents[] = {
1428c2ecf20Sopenharmony_ci	"mi2s_osr_src",
1438c2ecf20Sopenharmony_ci};
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_cistatic struct clk_branch mi2s_osr_clk = {
1468c2ecf20Sopenharmony_ci	.halt_reg = 0x50,
1478c2ecf20Sopenharmony_ci	.halt_bit = 1,
1488c2ecf20Sopenharmony_ci	.halt_check = BRANCH_HALT_ENABLE,
1498c2ecf20Sopenharmony_ci	.clkr = {
1508c2ecf20Sopenharmony_ci		.enable_reg = 0x48,
1518c2ecf20Sopenharmony_ci		.enable_mask = BIT(17),
1528c2ecf20Sopenharmony_ci		.hw.init = &(struct clk_init_data){
1538c2ecf20Sopenharmony_ci			.name = "mi2s_osr_clk",
1548c2ecf20Sopenharmony_ci			.parent_names = lcc_mi2s_parents,
1558c2ecf20Sopenharmony_ci			.num_parents = 1,
1568c2ecf20Sopenharmony_ci			.ops = &clk_branch_ops,
1578c2ecf20Sopenharmony_ci			.flags = CLK_SET_RATE_PARENT,
1588c2ecf20Sopenharmony_ci		},
1598c2ecf20Sopenharmony_ci	},
1608c2ecf20Sopenharmony_ci};
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_cistatic struct clk_regmap_div mi2s_div_clk = {
1638c2ecf20Sopenharmony_ci	.reg = 0x48,
1648c2ecf20Sopenharmony_ci	.shift = 10,
1658c2ecf20Sopenharmony_ci	.width = 4,
1668c2ecf20Sopenharmony_ci	.clkr = {
1678c2ecf20Sopenharmony_ci		.hw.init = &(struct clk_init_data){
1688c2ecf20Sopenharmony_ci			.name = "mi2s_div_clk",
1698c2ecf20Sopenharmony_ci			.parent_names = lcc_mi2s_parents,
1708c2ecf20Sopenharmony_ci			.num_parents = 1,
1718c2ecf20Sopenharmony_ci			.ops = &clk_regmap_div_ops,
1728c2ecf20Sopenharmony_ci		},
1738c2ecf20Sopenharmony_ci	},
1748c2ecf20Sopenharmony_ci};
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_cistatic struct clk_branch mi2s_bit_div_clk = {
1778c2ecf20Sopenharmony_ci	.halt_reg = 0x50,
1788c2ecf20Sopenharmony_ci	.halt_bit = 0,
1798c2ecf20Sopenharmony_ci	.halt_check = BRANCH_HALT_ENABLE,
1808c2ecf20Sopenharmony_ci	.clkr = {
1818c2ecf20Sopenharmony_ci		.enable_reg = 0x48,
1828c2ecf20Sopenharmony_ci		.enable_mask = BIT(15),
1838c2ecf20Sopenharmony_ci		.hw.init = &(struct clk_init_data){
1848c2ecf20Sopenharmony_ci			.name = "mi2s_bit_div_clk",
1858c2ecf20Sopenharmony_ci			.parent_names = (const char *[]){ "mi2s_div_clk" },
1868c2ecf20Sopenharmony_ci			.num_parents = 1,
1878c2ecf20Sopenharmony_ci			.ops = &clk_branch_ops,
1888c2ecf20Sopenharmony_ci			.flags = CLK_SET_RATE_PARENT,
1898c2ecf20Sopenharmony_ci		},
1908c2ecf20Sopenharmony_ci	},
1918c2ecf20Sopenharmony_ci};
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_cistatic struct clk_regmap_mux mi2s_bit_clk = {
1958c2ecf20Sopenharmony_ci	.reg = 0x48,
1968c2ecf20Sopenharmony_ci	.shift = 14,
1978c2ecf20Sopenharmony_ci	.width = 1,
1988c2ecf20Sopenharmony_ci	.clkr = {
1998c2ecf20Sopenharmony_ci		.hw.init = &(struct clk_init_data){
2008c2ecf20Sopenharmony_ci			.name = "mi2s_bit_clk",
2018c2ecf20Sopenharmony_ci			.parent_names = (const char *[]){
2028c2ecf20Sopenharmony_ci				"mi2s_bit_div_clk",
2038c2ecf20Sopenharmony_ci				"mi2s_codec_clk",
2048c2ecf20Sopenharmony_ci			},
2058c2ecf20Sopenharmony_ci			.num_parents = 2,
2068c2ecf20Sopenharmony_ci			.ops = &clk_regmap_mux_closest_ops,
2078c2ecf20Sopenharmony_ci			.flags = CLK_SET_RATE_PARENT,
2088c2ecf20Sopenharmony_ci		},
2098c2ecf20Sopenharmony_ci	},
2108c2ecf20Sopenharmony_ci};
2118c2ecf20Sopenharmony_ci
2128c2ecf20Sopenharmony_cistatic struct freq_tbl clk_tbl_pcm[] = {
2138c2ecf20Sopenharmony_ci	{   64000, P_PLL4, 4, 1, 1536 },
2148c2ecf20Sopenharmony_ci	{  128000, P_PLL4, 4, 1,  768 },
2158c2ecf20Sopenharmony_ci	{  256000, P_PLL4, 4, 1,  384 },
2168c2ecf20Sopenharmony_ci	{  512000, P_PLL4, 4, 1,  192 },
2178c2ecf20Sopenharmony_ci	{ 1024000, P_PLL4, 4, 1,   96 },
2188c2ecf20Sopenharmony_ci	{ 2048000, P_PLL4, 4, 1,   48 },
2198c2ecf20Sopenharmony_ci	{ },
2208c2ecf20Sopenharmony_ci};
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_cistatic struct clk_rcg pcm_src = {
2238c2ecf20Sopenharmony_ci	.ns_reg = 0x54,
2248c2ecf20Sopenharmony_ci	.md_reg = 0x58,
2258c2ecf20Sopenharmony_ci	.mn = {
2268c2ecf20Sopenharmony_ci		.mnctr_en_bit = 8,
2278c2ecf20Sopenharmony_ci		.mnctr_reset_bit = 7,
2288c2ecf20Sopenharmony_ci		.mnctr_mode_shift = 5,
2298c2ecf20Sopenharmony_ci		.n_val_shift = 16,
2308c2ecf20Sopenharmony_ci		.m_val_shift = 16,
2318c2ecf20Sopenharmony_ci		.width = 16,
2328c2ecf20Sopenharmony_ci	},
2338c2ecf20Sopenharmony_ci	.p = {
2348c2ecf20Sopenharmony_ci		.pre_div_shift = 3,
2358c2ecf20Sopenharmony_ci		.pre_div_width = 2,
2368c2ecf20Sopenharmony_ci	},
2378c2ecf20Sopenharmony_ci	.s = {
2388c2ecf20Sopenharmony_ci		.src_sel_shift = 0,
2398c2ecf20Sopenharmony_ci		.parent_map = lcc_pxo_pll4_map,
2408c2ecf20Sopenharmony_ci	},
2418c2ecf20Sopenharmony_ci	.freq_tbl = clk_tbl_pcm,
2428c2ecf20Sopenharmony_ci	.clkr = {
2438c2ecf20Sopenharmony_ci		.enable_reg = 0x54,
2448c2ecf20Sopenharmony_ci		.enable_mask = BIT(9),
2458c2ecf20Sopenharmony_ci		.hw.init = &(struct clk_init_data){
2468c2ecf20Sopenharmony_ci			.name = "pcm_src",
2478c2ecf20Sopenharmony_ci			.parent_names = lcc_pxo_pll4,
2488c2ecf20Sopenharmony_ci			.num_parents = 2,
2498c2ecf20Sopenharmony_ci			.ops = &clk_rcg_ops,
2508c2ecf20Sopenharmony_ci			.flags = CLK_SET_RATE_GATE,
2518c2ecf20Sopenharmony_ci		},
2528c2ecf20Sopenharmony_ci	},
2538c2ecf20Sopenharmony_ci};
2548c2ecf20Sopenharmony_ci
2558c2ecf20Sopenharmony_cistatic struct clk_branch pcm_clk_out = {
2568c2ecf20Sopenharmony_ci	.halt_reg = 0x5c,
2578c2ecf20Sopenharmony_ci	.halt_bit = 0,
2588c2ecf20Sopenharmony_ci	.halt_check = BRANCH_HALT_ENABLE,
2598c2ecf20Sopenharmony_ci	.clkr = {
2608c2ecf20Sopenharmony_ci		.enable_reg = 0x54,
2618c2ecf20Sopenharmony_ci		.enable_mask = BIT(11),
2628c2ecf20Sopenharmony_ci		.hw.init = &(struct clk_init_data){
2638c2ecf20Sopenharmony_ci			.name = "pcm_clk_out",
2648c2ecf20Sopenharmony_ci			.parent_names = (const char *[]){ "pcm_src" },
2658c2ecf20Sopenharmony_ci			.num_parents = 1,
2668c2ecf20Sopenharmony_ci			.ops = &clk_branch_ops,
2678c2ecf20Sopenharmony_ci			.flags = CLK_SET_RATE_PARENT,
2688c2ecf20Sopenharmony_ci		},
2698c2ecf20Sopenharmony_ci	},
2708c2ecf20Sopenharmony_ci};
2718c2ecf20Sopenharmony_ci
2728c2ecf20Sopenharmony_cistatic struct clk_regmap_mux pcm_clk = {
2738c2ecf20Sopenharmony_ci	.reg = 0x54,
2748c2ecf20Sopenharmony_ci	.shift = 10,
2758c2ecf20Sopenharmony_ci	.width = 1,
2768c2ecf20Sopenharmony_ci	.clkr = {
2778c2ecf20Sopenharmony_ci		.hw.init = &(struct clk_init_data){
2788c2ecf20Sopenharmony_ci			.name = "pcm_clk",
2798c2ecf20Sopenharmony_ci			.parent_names = (const char *[]){
2808c2ecf20Sopenharmony_ci				"pcm_clk_out",
2818c2ecf20Sopenharmony_ci				"pcm_codec_clk",
2828c2ecf20Sopenharmony_ci			},
2838c2ecf20Sopenharmony_ci			.num_parents = 2,
2848c2ecf20Sopenharmony_ci			.ops = &clk_regmap_mux_closest_ops,
2858c2ecf20Sopenharmony_ci			.flags = CLK_SET_RATE_PARENT,
2868c2ecf20Sopenharmony_ci		},
2878c2ecf20Sopenharmony_ci	},
2888c2ecf20Sopenharmony_ci};
2898c2ecf20Sopenharmony_ci
2908c2ecf20Sopenharmony_cistatic struct freq_tbl clk_tbl_aif_osr[] = {
2918c2ecf20Sopenharmony_ci	{  2822400, P_PLL4, 1, 147, 20480 },
2928c2ecf20Sopenharmony_ci	{  4096000, P_PLL4, 1,   1,    96 },
2938c2ecf20Sopenharmony_ci	{  5644800, P_PLL4, 1, 147, 10240 },
2948c2ecf20Sopenharmony_ci	{  6144000, P_PLL4, 1,   1,    64 },
2958c2ecf20Sopenharmony_ci	{ 11289600, P_PLL4, 1, 147,  5120 },
2968c2ecf20Sopenharmony_ci	{ 12288000, P_PLL4, 1,   1,    32 },
2978c2ecf20Sopenharmony_ci	{ 22579200, P_PLL4, 1, 147,  2560 },
2988c2ecf20Sopenharmony_ci	{ 24576000, P_PLL4, 1,   1,    16 },
2998c2ecf20Sopenharmony_ci	{ },
3008c2ecf20Sopenharmony_ci};
3018c2ecf20Sopenharmony_ci
3028c2ecf20Sopenharmony_cistatic struct clk_rcg spdif_src = {
3038c2ecf20Sopenharmony_ci	.ns_reg = 0xcc,
3048c2ecf20Sopenharmony_ci	.md_reg = 0xd0,
3058c2ecf20Sopenharmony_ci	.mn = {
3068c2ecf20Sopenharmony_ci		.mnctr_en_bit = 8,
3078c2ecf20Sopenharmony_ci		.mnctr_reset_bit = 7,
3088c2ecf20Sopenharmony_ci		.mnctr_mode_shift = 5,
3098c2ecf20Sopenharmony_ci		.n_val_shift = 16,
3108c2ecf20Sopenharmony_ci		.m_val_shift = 16,
3118c2ecf20Sopenharmony_ci		.width = 8,
3128c2ecf20Sopenharmony_ci	},
3138c2ecf20Sopenharmony_ci	.p = {
3148c2ecf20Sopenharmony_ci		.pre_div_shift = 3,
3158c2ecf20Sopenharmony_ci		.pre_div_width = 2,
3168c2ecf20Sopenharmony_ci	},
3178c2ecf20Sopenharmony_ci	.s = {
3188c2ecf20Sopenharmony_ci		.src_sel_shift = 0,
3198c2ecf20Sopenharmony_ci		.parent_map = lcc_pxo_pll4_map,
3208c2ecf20Sopenharmony_ci	},
3218c2ecf20Sopenharmony_ci	.freq_tbl = clk_tbl_aif_osr,
3228c2ecf20Sopenharmony_ci	.clkr = {
3238c2ecf20Sopenharmony_ci		.enable_reg = 0xcc,
3248c2ecf20Sopenharmony_ci		.enable_mask = BIT(9),
3258c2ecf20Sopenharmony_ci		.hw.init = &(struct clk_init_data){
3268c2ecf20Sopenharmony_ci			.name = "spdif_src",
3278c2ecf20Sopenharmony_ci			.parent_names = lcc_pxo_pll4,
3288c2ecf20Sopenharmony_ci			.num_parents = 2,
3298c2ecf20Sopenharmony_ci			.ops = &clk_rcg_ops,
3308c2ecf20Sopenharmony_ci			.flags = CLK_SET_RATE_GATE,
3318c2ecf20Sopenharmony_ci		},
3328c2ecf20Sopenharmony_ci	},
3338c2ecf20Sopenharmony_ci};
3348c2ecf20Sopenharmony_ci
3358c2ecf20Sopenharmony_cistatic const char * const lcc_spdif_parents[] = {
3368c2ecf20Sopenharmony_ci	"spdif_src",
3378c2ecf20Sopenharmony_ci};
3388c2ecf20Sopenharmony_ci
3398c2ecf20Sopenharmony_cistatic struct clk_branch spdif_clk = {
3408c2ecf20Sopenharmony_ci	.halt_reg = 0xd4,
3418c2ecf20Sopenharmony_ci	.halt_bit = 1,
3428c2ecf20Sopenharmony_ci	.halt_check = BRANCH_HALT_ENABLE,
3438c2ecf20Sopenharmony_ci	.clkr = {
3448c2ecf20Sopenharmony_ci		.enable_reg = 0xcc,
3458c2ecf20Sopenharmony_ci		.enable_mask = BIT(12),
3468c2ecf20Sopenharmony_ci		.hw.init = &(struct clk_init_data){
3478c2ecf20Sopenharmony_ci			.name = "spdif_clk",
3488c2ecf20Sopenharmony_ci			.parent_names = lcc_spdif_parents,
3498c2ecf20Sopenharmony_ci			.num_parents = 1,
3508c2ecf20Sopenharmony_ci			.ops = &clk_branch_ops,
3518c2ecf20Sopenharmony_ci			.flags = CLK_SET_RATE_PARENT,
3528c2ecf20Sopenharmony_ci		},
3538c2ecf20Sopenharmony_ci	},
3548c2ecf20Sopenharmony_ci};
3558c2ecf20Sopenharmony_ci
3568c2ecf20Sopenharmony_cistatic struct freq_tbl clk_tbl_ahbix[] = {
3578c2ecf20Sopenharmony_ci	{ 131072000, P_PLL4, 1, 1, 3 },
3588c2ecf20Sopenharmony_ci	{ },
3598c2ecf20Sopenharmony_ci};
3608c2ecf20Sopenharmony_ci
3618c2ecf20Sopenharmony_cistatic struct clk_rcg ahbix_clk = {
3628c2ecf20Sopenharmony_ci	.ns_reg = 0x38,
3638c2ecf20Sopenharmony_ci	.md_reg = 0x3c,
3648c2ecf20Sopenharmony_ci	.mn = {
3658c2ecf20Sopenharmony_ci		.mnctr_en_bit = 8,
3668c2ecf20Sopenharmony_ci		.mnctr_reset_bit = 7,
3678c2ecf20Sopenharmony_ci		.mnctr_mode_shift = 5,
3688c2ecf20Sopenharmony_ci		.n_val_shift = 24,
3698c2ecf20Sopenharmony_ci		.m_val_shift = 8,
3708c2ecf20Sopenharmony_ci		.width = 8,
3718c2ecf20Sopenharmony_ci	},
3728c2ecf20Sopenharmony_ci	.p = {
3738c2ecf20Sopenharmony_ci		.pre_div_shift = 3,
3748c2ecf20Sopenharmony_ci		.pre_div_width = 2,
3758c2ecf20Sopenharmony_ci	},
3768c2ecf20Sopenharmony_ci	.s = {
3778c2ecf20Sopenharmony_ci		.src_sel_shift = 0,
3788c2ecf20Sopenharmony_ci		.parent_map = lcc_pxo_pll4_map,
3798c2ecf20Sopenharmony_ci	},
3808c2ecf20Sopenharmony_ci	.freq_tbl = clk_tbl_ahbix,
3818c2ecf20Sopenharmony_ci	.clkr = {
3828c2ecf20Sopenharmony_ci		.enable_reg = 0x38,
3838c2ecf20Sopenharmony_ci		.enable_mask = BIT(11),
3848c2ecf20Sopenharmony_ci		.hw.init = &(struct clk_init_data){
3858c2ecf20Sopenharmony_ci			.name = "ahbix",
3868c2ecf20Sopenharmony_ci			.parent_names = lcc_pxo_pll4,
3878c2ecf20Sopenharmony_ci			.num_parents = 2,
3888c2ecf20Sopenharmony_ci			.ops = &clk_rcg_lcc_ops,
3898c2ecf20Sopenharmony_ci		},
3908c2ecf20Sopenharmony_ci	},
3918c2ecf20Sopenharmony_ci};
3928c2ecf20Sopenharmony_ci
3938c2ecf20Sopenharmony_cistatic struct clk_regmap *lcc_ipq806x_clks[] = {
3948c2ecf20Sopenharmony_ci	[PLL4] = &pll4.clkr,
3958c2ecf20Sopenharmony_ci	[MI2S_OSR_SRC] = &mi2s_osr_src.clkr,
3968c2ecf20Sopenharmony_ci	[MI2S_OSR_CLK] = &mi2s_osr_clk.clkr,
3978c2ecf20Sopenharmony_ci	[MI2S_DIV_CLK] = &mi2s_div_clk.clkr,
3988c2ecf20Sopenharmony_ci	[MI2S_BIT_DIV_CLK] = &mi2s_bit_div_clk.clkr,
3998c2ecf20Sopenharmony_ci	[MI2S_BIT_CLK] = &mi2s_bit_clk.clkr,
4008c2ecf20Sopenharmony_ci	[PCM_SRC] = &pcm_src.clkr,
4018c2ecf20Sopenharmony_ci	[PCM_CLK_OUT] = &pcm_clk_out.clkr,
4028c2ecf20Sopenharmony_ci	[PCM_CLK] = &pcm_clk.clkr,
4038c2ecf20Sopenharmony_ci	[SPDIF_SRC] = &spdif_src.clkr,
4048c2ecf20Sopenharmony_ci	[SPDIF_CLK] = &spdif_clk.clkr,
4058c2ecf20Sopenharmony_ci	[AHBIX_CLK] = &ahbix_clk.clkr,
4068c2ecf20Sopenharmony_ci};
4078c2ecf20Sopenharmony_ci
4088c2ecf20Sopenharmony_cistatic const struct regmap_config lcc_ipq806x_regmap_config = {
4098c2ecf20Sopenharmony_ci	.reg_bits	= 32,
4108c2ecf20Sopenharmony_ci	.reg_stride	= 4,
4118c2ecf20Sopenharmony_ci	.val_bits	= 32,
4128c2ecf20Sopenharmony_ci	.max_register	= 0xfc,
4138c2ecf20Sopenharmony_ci	.fast_io	= true,
4148c2ecf20Sopenharmony_ci};
4158c2ecf20Sopenharmony_ci
4168c2ecf20Sopenharmony_cistatic const struct qcom_cc_desc lcc_ipq806x_desc = {
4178c2ecf20Sopenharmony_ci	.config = &lcc_ipq806x_regmap_config,
4188c2ecf20Sopenharmony_ci	.clks = lcc_ipq806x_clks,
4198c2ecf20Sopenharmony_ci	.num_clks = ARRAY_SIZE(lcc_ipq806x_clks),
4208c2ecf20Sopenharmony_ci};
4218c2ecf20Sopenharmony_ci
4228c2ecf20Sopenharmony_cistatic const struct of_device_id lcc_ipq806x_match_table[] = {
4238c2ecf20Sopenharmony_ci	{ .compatible = "qcom,lcc-ipq8064" },
4248c2ecf20Sopenharmony_ci	{ }
4258c2ecf20Sopenharmony_ci};
4268c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, lcc_ipq806x_match_table);
4278c2ecf20Sopenharmony_ci
4288c2ecf20Sopenharmony_cistatic int lcc_ipq806x_probe(struct platform_device *pdev)
4298c2ecf20Sopenharmony_ci{
4308c2ecf20Sopenharmony_ci	u32 val;
4318c2ecf20Sopenharmony_ci	struct regmap *regmap;
4328c2ecf20Sopenharmony_ci
4338c2ecf20Sopenharmony_ci	regmap = qcom_cc_map(pdev, &lcc_ipq806x_desc);
4348c2ecf20Sopenharmony_ci	if (IS_ERR(regmap))
4358c2ecf20Sopenharmony_ci		return PTR_ERR(regmap);
4368c2ecf20Sopenharmony_ci
4378c2ecf20Sopenharmony_ci	/* Configure the rate of PLL4 if the bootloader hasn't already */
4388c2ecf20Sopenharmony_ci	regmap_read(regmap, 0x0, &val);
4398c2ecf20Sopenharmony_ci	if (!val)
4408c2ecf20Sopenharmony_ci		clk_pll_configure_sr(&pll4, regmap, &pll4_config, true);
4418c2ecf20Sopenharmony_ci	/* Enable PLL4 source on the LPASS Primary PLL Mux */
4428c2ecf20Sopenharmony_ci	regmap_write(regmap, 0xc4, 0x1);
4438c2ecf20Sopenharmony_ci
4448c2ecf20Sopenharmony_ci	return qcom_cc_really_probe(pdev, &lcc_ipq806x_desc, regmap);
4458c2ecf20Sopenharmony_ci}
4468c2ecf20Sopenharmony_ci
4478c2ecf20Sopenharmony_cistatic struct platform_driver lcc_ipq806x_driver = {
4488c2ecf20Sopenharmony_ci	.probe		= lcc_ipq806x_probe,
4498c2ecf20Sopenharmony_ci	.driver		= {
4508c2ecf20Sopenharmony_ci		.name	= "lcc-ipq806x",
4518c2ecf20Sopenharmony_ci		.of_match_table = lcc_ipq806x_match_table,
4528c2ecf20Sopenharmony_ci	},
4538c2ecf20Sopenharmony_ci};
4548c2ecf20Sopenharmony_cimodule_platform_driver(lcc_ipq806x_driver);
4558c2ecf20Sopenharmony_ci
4568c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("QCOM LCC IPQ806x Driver");
4578c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2");
4588c2ecf20Sopenharmony_ciMODULE_ALIAS("platform:lcc-ipq806x");
459