brintos

brintos / linux-shallow public Read only

0
0
Text · 24.9 KiB · 45e7264 Raw
893 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2021, The Linux Foundation. All rights reserved.4 */5 6#include <linux/clk-provider.h>7#include <linux/err.h>8#include <linux/kernel.h>9#include <linux/module.h>10#include <linux/of.h>11#include <linux/platform_device.h>12#include <linux/pm_clock.h>13#include <linux/pm_runtime.h>14#include <linux/regmap.h>15 16#include <dt-bindings/clock/qcom,lpass-sc7280.h>17#include <dt-bindings/clock/qcom,lpassaudiocc-sc7280.h>18 19#include "clk-alpha-pll.h"20#include "clk-branch.h"21#include "clk-rcg.h"22#include "clk-regmap.h"23#include "clk-regmap-divider.h"24#include "clk-regmap-mux.h"25#include "common.h"26#include "gdsc.h"27#include "reset.h"28 29enum {30	P_BI_TCXO,31	P_LPASS_AON_CC_PLL_OUT_EVEN,32	P_LPASS_AON_CC_PLL_OUT_MAIN,33	P_LPASS_AON_CC_PLL_OUT_MAIN_CDIV_DIV_CLK_SRC,34	P_LPASS_AON_CC_PLL_OUT_ODD,35	P_LPASS_AUDIO_CC_PLL_OUT_AUX,36	P_LPASS_AUDIO_CC_PLL_OUT_AUX2_DIV_CLK_SRC,37	P_LPASS_AUDIO_CC_PLL_MAIN_DIV_CLK,38};39 40static const struct pll_vco zonda_vco[] = {41	{ 595200000UL, 3600000000UL, 0 },42};43 44static struct clk_branch lpass_q6ss_ahbm_clk = {45	.halt_reg = 0x901c,46	.halt_check = BRANCH_HALT,47	.clkr = {48		.enable_reg = 0x901c,49		.enable_mask = BIT(0),50		.hw.init = &(struct clk_init_data){51				.name = "lpass_q6ss_ahbm_clk",52				.ops = &clk_branch2_ops,53		},54	},55};56 57static struct clk_branch lpass_q6ss_ahbs_clk = {58	.halt_reg = 0x9020,59	.halt_check = BRANCH_HALT_VOTED,60	.clkr = {61		.enable_reg = 0x9020,62		.enable_mask = BIT(0),63		.hw.init = &(struct clk_init_data){64			.name = "lpass_q6ss_ahbs_clk",65			.ops = &clk_branch2_ops,66		},67	},68};69 70/* 1128.96MHz configuration */71static const struct alpha_pll_config lpass_audio_cc_pll_config = {72	.l = 0x3a,73	.alpha = 0xcccc,74	.config_ctl_val = 0x08200920,75	.config_ctl_hi_val = 0x05002001,76	.config_ctl_hi1_val = 0x00000000,77	.user_ctl_val = 0x03000101,78};79 80static struct clk_alpha_pll lpass_audio_cc_pll = {81	.offset = 0x0,82	.vco_table = zonda_vco,83	.num_vco = ARRAY_SIZE(zonda_vco),84	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_ZONDA],85	.clkr = {86		.hw.init = &(const struct clk_init_data){87			.name = "lpass_audio_cc_pll",88			.parent_data = &(const struct clk_parent_data){89				.index = 0,90			},91			.num_parents = 1,92			.ops = &clk_alpha_pll_zonda_ops,93		},94	},95};96 97static const struct clk_div_table post_div_table_lpass_audio_cc_pll_out_aux2[] = {98	{ 0x1, 2 },99	{ }100};101 102static struct clk_alpha_pll_postdiv lpass_audio_cc_pll_out_aux2 = {103	.offset = 0x0,104	.post_div_shift = 8,105	.post_div_table = post_div_table_lpass_audio_cc_pll_out_aux2,106	.num_post_div = ARRAY_SIZE(post_div_table_lpass_audio_cc_pll_out_aux2),107	.width = 2,108	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_ZONDA],109	.clkr.hw.init = &(const struct clk_init_data){110		.name = "lpass_audio_cc_pll_out_aux2",111		.parent_hws = (const struct clk_hw*[]){112			&lpass_audio_cc_pll.clkr.hw,113		},114		.num_parents = 1,115		.ops = &clk_alpha_pll_postdiv_zonda_ops,116	},117};118 119static const struct pll_vco lucid_vco[] = {120	{ 249600000, 2000000000, 0 },121};122 123/* 614.4 MHz configuration */124static const struct alpha_pll_config lpass_aon_cc_pll_config = {125	.l = 0x20,126	.alpha = 0x0,127	.config_ctl_val = 0x20485699,128	.config_ctl_hi_val = 0x00002261,129	.config_ctl_hi1_val = 0x329A299C,130	.user_ctl_val = 0x00005100,131	.user_ctl_hi_val = 0x00000805,132	.user_ctl_hi1_val = 0x00000000,133};134 135static struct clk_alpha_pll lpass_aon_cc_pll = {136	.offset = 0x0,137	.vco_table = lucid_vco,138	.num_vco = ARRAY_SIZE(lucid_vco),139	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],140	.clkr = {141		.hw.init = &(const struct clk_init_data){142			.name = "lpass_aon_cc_pll",143			.parent_data = &(const struct clk_parent_data){144				.index = 0,145			},146			.num_parents = 1,147			.ops = &clk_alpha_pll_lucid_ops,148		},149	},150};151 152static const struct clk_div_table post_div_table_lpass_aon_cc_pll_out_even[] = {153	{ 0x1, 2 },154	{ }155};156 157static struct clk_alpha_pll_postdiv lpass_aon_cc_pll_out_even = {158	.offset = 0x0,159	.post_div_shift = 8,160	.post_div_table = post_div_table_lpass_aon_cc_pll_out_even,161	.num_post_div = ARRAY_SIZE(post_div_table_lpass_aon_cc_pll_out_even),162	.width = 4,163	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],164	.clkr.hw.init = &(const struct clk_init_data){165		.name = "lpass_aon_cc_pll_out_even",166		.parent_hws = (const struct clk_hw*[]){167			&lpass_aon_cc_pll.clkr.hw,168		},169		.num_parents = 1,170		.ops = &clk_alpha_pll_postdiv_lucid_ops,171	},172};173 174static const struct clk_div_table post_div_table_lpass_aon_cc_pll_out_odd[] = {175	{ 0x5, 5 },176	{ }177};178 179static struct clk_alpha_pll_postdiv lpass_aon_cc_pll_out_odd = {180	.offset = 0x0,181	.post_div_shift = 12,182	.post_div_table = post_div_table_lpass_aon_cc_pll_out_odd,183	.num_post_div = ARRAY_SIZE(post_div_table_lpass_aon_cc_pll_out_odd),184	.width = 4,185	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],186	.clkr.hw.init = &(const struct clk_init_data){187		.name = "lpass_aon_cc_pll_out_odd",188		.parent_hws = (const struct clk_hw*[]){189			&lpass_aon_cc_pll.clkr.hw,190		},191		.num_parents = 1,192		.ops = &clk_alpha_pll_postdiv_lucid_ops,193	},194};195 196static const struct parent_map lpass_audio_cc_parent_map_0[] = {197	{ P_BI_TCXO, 0 },198	{ P_LPASS_AUDIO_CC_PLL_OUT_AUX, 3 },199	{ P_LPASS_AON_CC_PLL_OUT_ODD, 5 },200	{ P_LPASS_AUDIO_CC_PLL_OUT_AUX2_DIV_CLK_SRC, 6 },201};202 203static struct clk_regmap_div lpass_audio_cc_pll_out_aux2_div_clk_src;204static struct clk_regmap_div lpass_audio_cc_pll_out_main_div_clk_src;205 206static const struct clk_parent_data lpass_audio_cc_parent_data_0[] = {207	{ .index = 0 },208	{ .hw = &lpass_audio_cc_pll.clkr.hw },209	{ .hw = &lpass_aon_cc_pll_out_odd.clkr.hw },210	{ .hw = &lpass_audio_cc_pll_out_aux2_div_clk_src.clkr.hw },211};212 213static const struct parent_map lpass_aon_cc_parent_map_0[] = {214	{ P_BI_TCXO, 0 },215	{ P_LPASS_AON_CC_PLL_OUT_EVEN, 4 },216};217 218static const struct clk_parent_data lpass_aon_cc_parent_data_0[] = {219	{ .index = 0 },220	{ .hw = &lpass_aon_cc_pll_out_even.clkr.hw },221};222 223static const struct parent_map lpass_aon_cc_parent_map_1[] = {224	{ P_BI_TCXO, 0 },225	{ P_LPASS_AON_CC_PLL_OUT_ODD, 1 },226	{ P_LPASS_AUDIO_CC_PLL_MAIN_DIV_CLK, 6 },227};228 229static const struct clk_parent_data lpass_aon_cc_parent_data_1[] = {230	{ .index = 0 },231	{ .hw = &lpass_aon_cc_pll_out_odd.clkr.hw },232	{ .hw = &lpass_audio_cc_pll_out_main_div_clk_src.clkr.hw },233};234 235static const struct freq_tbl ftbl_lpass_aon_cc_main_rcg_clk_src[] = {236	F(38400000, P_LPASS_AON_CC_PLL_OUT_EVEN, 8, 0, 0),237	F(76800000, P_LPASS_AON_CC_PLL_OUT_EVEN, 4, 0, 0),238	F(153600000, P_LPASS_AON_CC_PLL_OUT_EVEN, 2, 0, 0),239	{ }240};241 242static struct clk_rcg2 lpass_aon_cc_main_rcg_clk_src = {243	.cmd_rcgr = 0x1000,244	.mnd_width = 0,245	.hid_width = 5,246	.parent_map = lpass_aon_cc_parent_map_0,247	.freq_tbl = ftbl_lpass_aon_cc_main_rcg_clk_src,248	.clkr.hw.init = &(const struct clk_init_data){249		.name = "lpass_aon_cc_main_rcg_clk_src",250		.parent_data = lpass_aon_cc_parent_data_0,251		.num_parents = ARRAY_SIZE(lpass_aon_cc_parent_data_0),252		.flags = CLK_OPS_PARENT_ENABLE,253		.ops = &clk_rcg2_shared_ops,254	},255};256 257static const struct freq_tbl ftbl_lpass_aon_cc_tx_mclk_rcg_clk_src[] = {258	F(19200000, P_BI_TCXO, 1, 0, 0),259	F(24576000, P_LPASS_AON_CC_PLL_OUT_ODD, 5, 0, 0),260	{ }261};262 263static struct clk_rcg2 lpass_aon_cc_tx_mclk_rcg_clk_src = {264	.cmd_rcgr = 0x13004,265	.mnd_width = 0,266	.hid_width = 5,267	.parent_map = lpass_aon_cc_parent_map_1,268	.freq_tbl = ftbl_lpass_aon_cc_tx_mclk_rcg_clk_src,269	.clkr.hw.init = &(const struct clk_init_data){270		.name = "lpass_aon_cc_tx_mclk_rcg_clk_src",271		.parent_data = lpass_aon_cc_parent_data_1,272		.num_parents = ARRAY_SIZE(lpass_aon_cc_parent_data_1),273		.ops = &clk_rcg2_ops,274	},275};276 277static struct clk_regmap_div lpass_audio_cc_pll_out_aux2_div_clk_src = {278	.reg = 0x48,279	.shift = 0,280	.width = 4,281	.clkr.hw.init = &(const struct clk_init_data) {282		.name = "lpass_audio_cc_pll_out_aux2_div_clk_src",283		.parent_hws = (const struct clk_hw*[]){284			&lpass_audio_cc_pll_out_aux2.clkr.hw,285		},286		.num_parents = 1,287		.flags = CLK_SET_RATE_PARENT,288		.ops = &clk_regmap_div_ro_ops,289	},290};291 292static struct clk_regmap_div lpass_audio_cc_pll_out_main_div_clk_src = {293	.reg = 0x3c,294	.shift = 0,295	.width = 4,296	.clkr.hw.init = &(const struct clk_init_data) {297		.name = "lpass_audio_cc_pll_out_main_div_clk_src",298		.parent_hws = (const struct clk_hw*[]){299			&lpass_audio_cc_pll.clkr.hw,300		},301		.num_parents = 1,302		.flags = CLK_SET_RATE_PARENT,303		.ops = &clk_regmap_div_ro_ops,304	},305};306 307static struct clk_regmap_div lpass_aon_cc_cdiv_tx_mclk_div_clk_src = {308	.reg = 0x13010,309	.shift = 0,310	.width = 4,311	.clkr.hw.init = &(const struct clk_init_data) {312		.name = "lpass_aon_cc_cdiv_tx_mclk_div_clk_src",313		.parent_hws = (const struct clk_hw*[]){314			&lpass_aon_cc_tx_mclk_rcg_clk_src.clkr.hw,315		},316		.num_parents = 1,317		.flags = CLK_SET_RATE_PARENT,318		.ops = &clk_regmap_div_ro_ops,319	},320};321 322static struct clk_regmap_div lpass_aon_cc_pll_out_main_cdiv_div_clk_src = {323	.reg = 0x80,324	.shift = 0,325	.width = 4,326	.clkr.hw.init = &(const struct clk_init_data) {327		.name = "lpass_aon_cc_pll_out_main_cdiv_div_clk_src",328		.parent_hws = (const struct clk_hw*[]){329			&lpass_aon_cc_pll.clkr.hw,330		},331		.num_parents = 1,332		.flags = CLK_SET_RATE_PARENT,333		.ops = &clk_regmap_div_ro_ops,334	},335};336 337static const struct freq_tbl ftbl_lpass_audio_cc_ext_mclk0_clk_src[] = {338	F(256000, P_LPASS_AON_CC_PLL_OUT_ODD, 15, 1, 32),339	F(352800, P_LPASS_AUDIO_CC_PLL_OUT_AUX2_DIV_CLK_SRC, 10, 1, 32),340	F(512000, P_LPASS_AON_CC_PLL_OUT_ODD, 15, 1, 16),341	F(705600, P_LPASS_AUDIO_CC_PLL_OUT_AUX2_DIV_CLK_SRC, 10, 1, 16),342	F(768000, P_LPASS_AON_CC_PLL_OUT_ODD, 10, 1, 16),343	F(1024000, P_LPASS_AON_CC_PLL_OUT_ODD, 15, 1, 8),344	F(1411200, P_LPASS_AUDIO_CC_PLL_OUT_AUX2_DIV_CLK_SRC, 10, 1, 8),345	F(1536000, P_LPASS_AON_CC_PLL_OUT_ODD, 10, 1, 8),346	F(2048000, P_LPASS_AON_CC_PLL_OUT_ODD, 15, 1, 4),347	F(2822400, P_LPASS_AUDIO_CC_PLL_OUT_AUX2_DIV_CLK_SRC, 10, 1, 4),348	F(3072000, P_LPASS_AON_CC_PLL_OUT_ODD, 10, 1, 4),349	F(4096000, P_LPASS_AON_CC_PLL_OUT_ODD, 15, 1, 2),350	F(5644800, P_LPASS_AUDIO_CC_PLL_OUT_AUX2_DIV_CLK_SRC, 10, 1, 2),351	F(6144000, P_LPASS_AON_CC_PLL_OUT_ODD, 10, 1, 2),352	F(8192000, P_LPASS_AON_CC_PLL_OUT_ODD, 15, 0, 0),353	F(9600000, P_BI_TCXO, 2, 0, 0),354	F(11289600, P_LPASS_AUDIO_CC_PLL_OUT_AUX2_DIV_CLK_SRC, 10, 0, 0),355	F(12288000, P_LPASS_AON_CC_PLL_OUT_ODD, 10, 0, 0),356	F(19200000, P_BI_TCXO, 1, 0, 0),357	F(22579200, P_LPASS_AUDIO_CC_PLL_OUT_AUX2_DIV_CLK_SRC, 5, 0, 0),358	F(24576000, P_LPASS_AON_CC_PLL_OUT_ODD, 5, 0, 0),359	{ }360};361 362static struct clk_rcg2 lpass_audio_cc_ext_mclk0_clk_src = {363	.cmd_rcgr = 0x20004,364	.mnd_width = 8,365	.hid_width = 5,366	.parent_map = lpass_audio_cc_parent_map_0,367	.freq_tbl = ftbl_lpass_audio_cc_ext_mclk0_clk_src,368	.clkr.hw.init = &(const struct clk_init_data){369		.name = "lpass_audio_cc_ext_mclk0_clk_src",370		.parent_data = lpass_audio_cc_parent_data_0,371		.num_parents = ARRAY_SIZE(lpass_audio_cc_parent_data_0),372		.ops = &clk_rcg2_ops,373	},374};375 376static struct clk_rcg2 lpass_audio_cc_ext_mclk1_clk_src = {377	.cmd_rcgr = 0x21004,378	.mnd_width = 8,379	.hid_width = 5,380	.parent_map = lpass_audio_cc_parent_map_0,381	.freq_tbl = ftbl_lpass_audio_cc_ext_mclk0_clk_src,382	.clkr.hw.init = &(const struct clk_init_data){383		.name = "lpass_audio_cc_ext_mclk1_clk_src",384		.parent_data = lpass_audio_cc_parent_data_0,385		.num_parents = ARRAY_SIZE(lpass_audio_cc_parent_data_0),386		.ops = &clk_rcg2_ops,387	},388};389 390static struct clk_rcg2 lpass_audio_cc_rx_mclk_clk_src = {391	.cmd_rcgr = 0x24004,392	.mnd_width = 8,393	.hid_width = 5,394	.parent_map = lpass_audio_cc_parent_map_0,395	.freq_tbl = ftbl_lpass_audio_cc_ext_mclk0_clk_src,396	.clkr.hw.init = &(const struct clk_init_data){397		.name = "lpass_audio_cc_rx_mclk_clk_src",398		.parent_data = lpass_audio_cc_parent_data_0,399		.num_parents = ARRAY_SIZE(lpass_audio_cc_parent_data_0),400		.ops = &clk_rcg2_ops,401	},402};403 404static struct clk_regmap_div lpass_audio_cc_cdiv_rx_mclk_div_clk_src = {405	.reg = 0x240d0,406	.shift = 0,407	.width = 4,408	.clkr.hw.init = &(const struct clk_init_data) {409		.name = "lpass_audio_cc_cdiv_rx_mclk_div_clk_src",410		.parent_hws = (const struct clk_hw*[]){411			&lpass_audio_cc_rx_mclk_clk_src.clkr.hw,412		},413		.num_parents = 1,414		.flags = CLK_SET_RATE_PARENT,415		.ops = &clk_regmap_div_ro_ops,416	},417};418 419static struct clk_branch lpass_aon_cc_audio_hm_h_clk;420 421static struct clk_branch lpass_audio_cc_codec_mem0_clk = {422	.halt_reg = 0x1e004,423	.halt_check = BRANCH_HALT,424	.clkr = {425		.enable_reg = 0x1e004,426		.enable_mask = BIT(0),427		.hw.init = &(const struct clk_init_data){428			.name = "lpass_audio_cc_codec_mem0_clk",429			.parent_hws = (const struct clk_hw*[]){430				&lpass_aon_cc_audio_hm_h_clk.clkr.hw,431			},432			.num_parents = 1,433			.flags = CLK_SET_RATE_PARENT,434			.ops = &clk_branch2_ops,435		},436	},437};438 439static struct clk_branch lpass_audio_cc_codec_mem1_clk = {440	.halt_reg = 0x1e008,441	.halt_check = BRANCH_HALT,442	.clkr = {443		.enable_reg = 0x1e008,444		.enable_mask = BIT(0),445		.hw.init = &(const struct clk_init_data){446			.name = "lpass_audio_cc_codec_mem1_clk",447			.parent_hws = (const struct clk_hw*[]){448				&lpass_aon_cc_audio_hm_h_clk.clkr.hw,449			},450			.num_parents = 1,451			.flags = CLK_SET_RATE_PARENT,452			.ops = &clk_branch2_ops,453		},454	},455};456 457static struct clk_branch lpass_audio_cc_codec_mem2_clk = {458	.halt_reg = 0x1e00c,459	.halt_check = BRANCH_HALT,460	.clkr = {461		.enable_reg = 0x1e00c,462		.enable_mask = BIT(0),463		.hw.init = &(const struct clk_init_data){464			.name = "lpass_audio_cc_codec_mem2_clk",465			.parent_hws = (const struct clk_hw*[]){466				&lpass_aon_cc_audio_hm_h_clk.clkr.hw,467			},468			.num_parents = 1,469			.flags = CLK_SET_RATE_PARENT,470			.ops = &clk_branch2_ops,471		},472	},473};474 475static struct clk_branch lpass_audio_cc_codec_mem_clk = {476	.halt_reg = 0x1e000,477	.halt_check = BRANCH_HALT,478	.clkr = {479		.enable_reg = 0x1e000,480		.enable_mask = BIT(0),481		.hw.init = &(const struct clk_init_data){482			.name = "lpass_audio_cc_codec_mem_clk",483			.parent_hws = (const struct clk_hw*[]){484				&lpass_aon_cc_audio_hm_h_clk.clkr.hw,485			},486			.num_parents = 1,487			.flags = CLK_SET_RATE_PARENT,488			.ops = &clk_branch2_ops,489		},490	},491};492 493static struct clk_branch lpass_audio_cc_ext_mclk0_clk = {494	.halt_reg = 0x20018,495	.halt_check = BRANCH_HALT,496	.clkr = {497		.enable_reg = 0x20018,498		.enable_mask = BIT(0),499		.hw.init = &(const struct clk_init_data){500			.name = "lpass_audio_cc_ext_mclk0_clk",501			.parent_hws = (const struct clk_hw*[]){502				&lpass_audio_cc_ext_mclk0_clk_src.clkr.hw,503			},504			.num_parents = 1,505			.flags = CLK_SET_RATE_PARENT,506			.ops = &clk_branch2_ops,507		},508	},509};510 511static struct clk_branch lpass_audio_cc_ext_mclk1_clk = {512	.halt_reg = 0x21018,513	.halt_check = BRANCH_HALT,514	.clkr = {515		.enable_reg = 0x21018,516		.enable_mask = BIT(0),517		.hw.init = &(const struct clk_init_data){518			.name = "lpass_audio_cc_ext_mclk1_clk",519			.parent_hws = (const struct clk_hw*[]){520				&lpass_audio_cc_ext_mclk1_clk_src.clkr.hw,521			},522			.num_parents = 1,523			.flags = CLK_SET_RATE_PARENT,524			.ops = &clk_branch2_ops,525		},526	},527};528 529static struct clk_branch lpass_audio_cc_rx_mclk_2x_clk = {530	.halt_reg = 0x240cc,531	.halt_check = BRANCH_HALT,532	.clkr = {533		.enable_reg = 0x240cc,534		.enable_mask = BIT(0),535		.hw.init = &(const struct clk_init_data){536			.name = "lpass_audio_cc_rx_mclk_2x_clk",537			.parent_hws = (const struct clk_hw*[]){538				&lpass_audio_cc_rx_mclk_clk_src.clkr.hw,539			},540			.num_parents = 1,541			.flags = CLK_SET_RATE_PARENT,542			.ops = &clk_branch2_ops,543		},544	},545};546 547static struct clk_branch lpass_audio_cc_rx_mclk_clk = {548	.halt_reg = 0x240d4,549	.halt_check = BRANCH_HALT,550	.clkr = {551		.enable_reg = 0x240d4,552		.enable_mask = BIT(0),553		.hw.init = &(const struct clk_init_data){554			.name = "lpass_audio_cc_rx_mclk_clk",555			.parent_hws = (const struct clk_hw*[]){556				&lpass_audio_cc_cdiv_rx_mclk_div_clk_src.clkr.hw,557			},558			.num_parents = 1,559			.flags = CLK_SET_RATE_PARENT,560			.ops = &clk_branch2_ops,561		},562	},563};564 565static struct clk_branch lpass_aon_cc_audio_hm_h_clk = {566	.halt_reg = 0x9014,567	.halt_check = BRANCH_HALT,568	.clkr = {569		.enable_reg = 0x9014,570		.enable_mask = BIT(0),571		.hw.init = &(const struct clk_init_data){572			.name = "lpass_aon_cc_audio_hm_h_clk",573			.parent_hws = (const struct clk_hw*[]){574				&lpass_aon_cc_main_rcg_clk_src.clkr.hw,575			},576			.num_parents = 1,577			.flags = CLK_SET_RATE_PARENT,578			.ops = &clk_branch2_aon_ops,579		},580	},581};582 583static struct clk_branch lpass_aon_cc_va_mem0_clk = {584	.halt_reg = 0x9028,585	.halt_check = BRANCH_HALT,586	.clkr = {587		.enable_reg = 0x9028,588		.enable_mask = BIT(0),589		.hw.init = &(const struct clk_init_data){590			.name = "lpass_aon_cc_va_mem0_clk",591			.parent_hws = (const struct clk_hw*[]){592				&lpass_aon_cc_main_rcg_clk_src.clkr.hw,593			},594			.num_parents = 1,595			.flags = CLK_SET_RATE_PARENT,596			.ops = &clk_branch2_ops,597		},598	},599};600 601static struct clk_branch lpass_aon_cc_tx_mclk_2x_clk = {602	.halt_reg = 0x1300c,603	.halt_check = BRANCH_HALT,604	.clkr = {605		.enable_reg = 0x1300c,606		.enable_mask = BIT(0),607		.hw.init = &(const struct clk_init_data){608			.name = "lpass_aon_cc_tx_mclk_2x_clk",609			.parent_hws = (const struct clk_hw*[]){610				&lpass_aon_cc_tx_mclk_rcg_clk_src.clkr.hw,611			},612			.num_parents = 1,613			.flags = CLK_SET_RATE_PARENT,614			.ops = &clk_branch2_ops,615		},616	},617};618 619static struct clk_branch lpass_aon_cc_tx_mclk_clk = {620	.halt_reg = 0x13014,621	.halt_check = BRANCH_HALT,622	.clkr = {623		.enable_reg = 0x13014,624		.enable_mask = BIT(0),625		.hw.init = &(const struct clk_init_data){626			.name = "lpass_aon_cc_tx_mclk_clk",627			.parent_hws = (const struct clk_hw*[]){628				&lpass_aon_cc_cdiv_tx_mclk_div_clk_src.clkr.hw,629			},630			.num_parents = 1,631			.flags = CLK_SET_RATE_PARENT,632			.ops = &clk_branch2_ops,633		},634	},635};636 637static struct gdsc lpass_aon_cc_lpass_audio_hm_gdsc = {638	.gdscr = 0x9090,639	.pd = {640		.name = "lpass_aon_cc_lpass_audio_hm_gdsc",641	},642	.pwrsts = PWRSTS_OFF_ON,643	.flags = RETAIN_FF_ENABLE,644};645 646static struct clk_regmap *lpass_cc_sc7280_clocks[] = {647	[LPASS_Q6SS_AHBM_CLK] = &lpass_q6ss_ahbm_clk.clkr,648	[LPASS_Q6SS_AHBS_CLK] = &lpass_q6ss_ahbs_clk.clkr,649};650 651static struct clk_regmap *lpass_aon_cc_sc7280_clocks[] = {652	[LPASS_AON_CC_AUDIO_HM_H_CLK] = &lpass_aon_cc_audio_hm_h_clk.clkr,653	[LPASS_AON_CC_VA_MEM0_CLK] = &lpass_aon_cc_va_mem0_clk.clkr,654	[LPASS_AON_CC_CDIV_TX_MCLK_DIV_CLK_SRC] = &lpass_aon_cc_cdiv_tx_mclk_div_clk_src.clkr,655	[LPASS_AON_CC_MAIN_RCG_CLK_SRC] = &lpass_aon_cc_main_rcg_clk_src.clkr,656	[LPASS_AON_CC_PLL] = &lpass_aon_cc_pll.clkr,657	[LPASS_AON_CC_PLL_OUT_EVEN] = &lpass_aon_cc_pll_out_even.clkr,658	[LPASS_AON_CC_PLL_OUT_MAIN_CDIV_DIV_CLK_SRC] =659		&lpass_aon_cc_pll_out_main_cdiv_div_clk_src.clkr,660	[LPASS_AON_CC_PLL_OUT_ODD] = &lpass_aon_cc_pll_out_odd.clkr,661	[LPASS_AON_CC_TX_MCLK_2X_CLK] = &lpass_aon_cc_tx_mclk_2x_clk.clkr,662	[LPASS_AON_CC_TX_MCLK_CLK] = &lpass_aon_cc_tx_mclk_clk.clkr,663	[LPASS_AON_CC_TX_MCLK_RCG_CLK_SRC] = &lpass_aon_cc_tx_mclk_rcg_clk_src.clkr,664};665 666static struct gdsc *lpass_aon_cc_sc7280_gdscs[] = {667	[LPASS_AON_CC_LPASS_AUDIO_HM_GDSC] = &lpass_aon_cc_lpass_audio_hm_gdsc,668};669 670static struct clk_regmap *lpass_audio_cc_sc7280_clocks[] = {671	[LPASS_AUDIO_CC_CDIV_RX_MCLK_DIV_CLK_SRC] = &lpass_audio_cc_cdiv_rx_mclk_div_clk_src.clkr,672	[LPASS_AUDIO_CC_CODEC_MEM0_CLK] = &lpass_audio_cc_codec_mem0_clk.clkr,673	[LPASS_AUDIO_CC_CODEC_MEM1_CLK] = &lpass_audio_cc_codec_mem1_clk.clkr,674	[LPASS_AUDIO_CC_CODEC_MEM2_CLK] = &lpass_audio_cc_codec_mem2_clk.clkr,675	[LPASS_AUDIO_CC_CODEC_MEM_CLK] = &lpass_audio_cc_codec_mem_clk.clkr,676	[LPASS_AUDIO_CC_EXT_MCLK0_CLK] = &lpass_audio_cc_ext_mclk0_clk.clkr,677	[LPASS_AUDIO_CC_EXT_MCLK0_CLK_SRC] = &lpass_audio_cc_ext_mclk0_clk_src.clkr,678	[LPASS_AUDIO_CC_EXT_MCLK1_CLK] = &lpass_audio_cc_ext_mclk1_clk.clkr,679	[LPASS_AUDIO_CC_EXT_MCLK1_CLK_SRC] = &lpass_audio_cc_ext_mclk1_clk_src.clkr,680	[LPASS_AUDIO_CC_PLL] = &lpass_audio_cc_pll.clkr,681	[LPASS_AUDIO_CC_PLL_OUT_AUX2] = &lpass_audio_cc_pll_out_aux2.clkr,682	[LPASS_AUDIO_CC_PLL_OUT_AUX2_DIV_CLK_SRC] = &lpass_audio_cc_pll_out_aux2_div_clk_src.clkr,683	[LPASS_AUDIO_CC_PLL_OUT_MAIN_DIV_CLK_SRC] = &lpass_audio_cc_pll_out_main_div_clk_src.clkr,684	[LPASS_AUDIO_CC_RX_MCLK_2X_CLK] = &lpass_audio_cc_rx_mclk_2x_clk.clkr,685	[LPASS_AUDIO_CC_RX_MCLK_CLK] = &lpass_audio_cc_rx_mclk_clk.clkr,686	[LPASS_AUDIO_CC_RX_MCLK_CLK_SRC] = &lpass_audio_cc_rx_mclk_clk_src.clkr,687};688 689static struct regmap_config lpass_audio_cc_sc7280_regmap_config = {690	.reg_bits = 32,691	.reg_stride = 4,692	.val_bits = 32,693	.fast_io = true,694};695 696static const struct qcom_cc_desc lpass_cc_sc7280_desc = {697	.config = &lpass_audio_cc_sc7280_regmap_config,698	.clks = lpass_cc_sc7280_clocks,699	.num_clks = ARRAY_SIZE(lpass_cc_sc7280_clocks),700	.gdscs = lpass_aon_cc_sc7280_gdscs,701	.num_gdscs = ARRAY_SIZE(lpass_aon_cc_sc7280_gdscs),702};703 704static const struct qcom_cc_desc lpass_audio_cc_sc7280_desc = {705	.config = &lpass_audio_cc_sc7280_regmap_config,706	.clks = lpass_audio_cc_sc7280_clocks,707	.num_clks = ARRAY_SIZE(lpass_audio_cc_sc7280_clocks),708};709 710static const struct qcom_reset_map lpass_audio_cc_sc7280_resets[] = {711	[LPASS_AUDIO_SWR_RX_CGCR] =  { 0xa0, 1 },712	[LPASS_AUDIO_SWR_TX_CGCR] =  { 0xa8, 1 },713	[LPASS_AUDIO_SWR_WSA_CGCR] = { 0xb0, 1 },714};715 716static const struct qcom_cc_desc lpass_audio_cc_reset_sc7280_desc = {717	.config = &lpass_audio_cc_sc7280_regmap_config,718	.resets = lpass_audio_cc_sc7280_resets,719	.num_resets = ARRAY_SIZE(lpass_audio_cc_sc7280_resets),720};721 722static const struct of_device_id lpass_audio_cc_sc7280_match_table[] = {723	{ .compatible = "qcom,sc7280-lpassaudiocc" },724	{ }725};726MODULE_DEVICE_TABLE(of, lpass_audio_cc_sc7280_match_table);727 728static int lpass_audio_setup_runtime_pm(struct platform_device *pdev)729{730	int ret;731 732	pm_runtime_use_autosuspend(&pdev->dev);733	pm_runtime_set_autosuspend_delay(&pdev->dev, 50);734	ret = devm_pm_runtime_enable(&pdev->dev);735	if (ret)736		return ret;737 738	ret = devm_pm_clk_create(&pdev->dev);739	if (ret)740		return ret;741 742	ret = pm_clk_add(&pdev->dev, "iface");743	if (ret < 0)744		dev_err(&pdev->dev, "failed to acquire iface clock\n");745 746	return pm_runtime_resume_and_get(&pdev->dev);747}748 749static int lpass_audio_cc_sc7280_probe(struct platform_device *pdev)750{751	const struct qcom_cc_desc *desc;752	struct regmap *regmap;753	int ret;754 755	ret = lpass_audio_setup_runtime_pm(pdev);756	if (ret)757		return ret;758 759	lpass_audio_cc_sc7280_regmap_config.name = "lpassaudio_cc";760	lpass_audio_cc_sc7280_regmap_config.max_register = 0x2f000;761	desc = &lpass_audio_cc_sc7280_desc;762 763	regmap = qcom_cc_map(pdev, desc);764	if (IS_ERR(regmap)) {765		ret = PTR_ERR(regmap);766		goto exit;767	}768 769	clk_zonda_pll_configure(&lpass_audio_cc_pll, regmap, &lpass_audio_cc_pll_config);770 771	/* PLL settings */772	regmap_write(regmap, 0x4, 0x3b);773	regmap_write(regmap, 0x8, 0xff05);774 775	ret = qcom_cc_really_probe(&pdev->dev, &lpass_audio_cc_sc7280_desc, regmap);776	if (ret) {777		dev_err(&pdev->dev, "Failed to register LPASS AUDIO CC clocks\n");778		goto exit;779	}780 781	ret = qcom_cc_probe_by_index(pdev, 1, &lpass_audio_cc_reset_sc7280_desc);782	if (ret) {783		dev_err(&pdev->dev, "Failed to register LPASS AUDIO CC Resets\n");784		goto exit;785	}786 787	pm_runtime_mark_last_busy(&pdev->dev);788exit:789	pm_runtime_put_autosuspend(&pdev->dev);790 791	return ret;792}793 794static const struct dev_pm_ops lpass_audio_cc_pm_ops = {795	SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)796};797 798static struct platform_driver lpass_audio_cc_sc7280_driver = {799	.probe = lpass_audio_cc_sc7280_probe,800	.driver = {801		.name = "lpass_audio_cc-sc7280",802		.of_match_table = lpass_audio_cc_sc7280_match_table,803		.pm = &lpass_audio_cc_pm_ops,804	},805};806 807static const struct qcom_cc_desc lpass_aon_cc_sc7280_desc = {808	.config = &lpass_audio_cc_sc7280_regmap_config,809	.clks = lpass_aon_cc_sc7280_clocks,810	.num_clks = ARRAY_SIZE(lpass_aon_cc_sc7280_clocks),811	.gdscs = lpass_aon_cc_sc7280_gdscs,812	.num_gdscs = ARRAY_SIZE(lpass_aon_cc_sc7280_gdscs),813};814 815static const struct of_device_id lpass_aon_cc_sc7280_match_table[] = {816	{ .compatible = "qcom,sc7280-lpassaoncc" },817	{ }818};819MODULE_DEVICE_TABLE(of, lpass_aon_cc_sc7280_match_table);820 821static int lpass_aon_cc_sc7280_probe(struct platform_device *pdev)822{823	const struct qcom_cc_desc *desc;824	struct regmap *regmap;825	int ret;826 827	ret = lpass_audio_setup_runtime_pm(pdev);828	if (ret)829		return ret;830 831	if (of_property_read_bool(pdev->dev.of_node, "qcom,adsp-pil-mode")) {832		lpass_audio_cc_sc7280_regmap_config.name = "cc";833		desc = &lpass_cc_sc7280_desc;834		ret = qcom_cc_probe(pdev, desc);835		goto exit;836	}837 838	lpass_audio_cc_sc7280_regmap_config.name = "lpasscc_aon";839	lpass_audio_cc_sc7280_regmap_config.max_register = 0xa0008;840	desc = &lpass_aon_cc_sc7280_desc;841 842	regmap = qcom_cc_map(pdev, desc);843	if (IS_ERR(regmap)) {844		ret = PTR_ERR(regmap);845		goto exit;846	}847 848	clk_lucid_pll_configure(&lpass_aon_cc_pll, regmap, &lpass_aon_cc_pll_config);849 850	ret = qcom_cc_really_probe(&pdev->dev, &lpass_aon_cc_sc7280_desc, regmap);851	if (ret) {852		dev_err(&pdev->dev, "Failed to register LPASS AON CC clocks\n");853		goto exit;854	}855 856	pm_runtime_mark_last_busy(&pdev->dev);857exit:858	pm_runtime_put_autosuspend(&pdev->dev);859 860	return ret;861}862 863static struct platform_driver lpass_aon_cc_sc7280_driver = {864	.probe = lpass_aon_cc_sc7280_probe,865	.driver = {866		.name = "lpass_aon_cc-sc7280",867		.of_match_table = lpass_aon_cc_sc7280_match_table,868		.pm = &lpass_audio_cc_pm_ops,869	},870};871 872static int __init lpass_audio_cc_sc7280_init(void)873{874	int ret;875 876	ret = platform_driver_register(&lpass_aon_cc_sc7280_driver);877	if (ret)878		return ret;879 880	return platform_driver_register(&lpass_audio_cc_sc7280_driver);881}882subsys_initcall(lpass_audio_cc_sc7280_init);883 884static void __exit lpass_audio_cc_sc7280_exit(void)885{886	platform_driver_unregister(&lpass_audio_cc_sc7280_driver);887	platform_driver_unregister(&lpass_aon_cc_sc7280_driver);888}889module_exit(lpass_audio_cc_sc7280_exit);890 891MODULE_DESCRIPTION("QTI LPASS_AUDIO_CC SC7280 Driver");892MODULE_LICENSE("GPL v2");893