cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

gcc-ipq4019.c (43419B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (c) 2015 The Linux Foundation. All rights reserved.
      4 */
      5
      6#include <linux/kernel.h>
      7#include <linux/err.h>
      8#include <linux/platform_device.h>
      9#include <linux/module.h>
     10#include <linux/of.h>
     11#include <linux/of_device.h>
     12#include <linux/clk-provider.h>
     13#include <linux/regmap.h>
     14#include <linux/reset-controller.h>
     15#include <linux/math64.h>
     16#include <linux/delay.h>
     17#include <linux/clk.h>
     18
     19#include <dt-bindings/clock/qcom,gcc-ipq4019.h>
     20
     21#include "common.h"
     22#include "clk-regmap.h"
     23#include "clk-rcg.h"
     24#include "clk-branch.h"
     25#include "reset.h"
     26#include "clk-regmap-divider.h"
     27
     28#define to_clk_regmap_div(_hw) container_of(to_clk_regmap(_hw),\
     29					struct clk_regmap_div, clkr)
     30
     31#define to_clk_fepll(_hw) container_of(to_clk_regmap_div(_hw),\
     32						struct clk_fepll, cdiv)
     33
     34enum {
     35	P_XO,
     36	P_FEPLL200,
     37	P_FEPLL500,
     38	P_DDRPLL,
     39	P_FEPLLWCSS2G,
     40	P_FEPLLWCSS5G,
     41	P_FEPLL125DLY,
     42	P_DDRPLLAPSS,
     43};
     44
     45/*
     46 * struct clk_fepll_vco - vco feedback divider corresponds for FEPLL clocks
     47 * @fdbkdiv_shift: lowest bit for FDBKDIV
     48 * @fdbkdiv_width: number of bits in FDBKDIV
     49 * @refclkdiv_shift: lowest bit for REFCLKDIV
     50 * @refclkdiv_width: number of bits in REFCLKDIV
     51 * @reg: PLL_DIV register address
     52 */
     53struct clk_fepll_vco {
     54	u32 fdbkdiv_shift;
     55	u32 fdbkdiv_width;
     56	u32 refclkdiv_shift;
     57	u32 refclkdiv_width;
     58	u32 reg;
     59};
     60
     61/*
     62 * struct clk_fepll - clk divider corresponds to FEPLL clocks
     63 * @fixed_div: fixed divider value if divider is fixed
     64 * @parent_map: map from software's parent index to hardware's src_sel field
     65 * @cdiv: divider values for PLL_DIV
     66 * @pll_vco: vco feedback divider
     67 * @div_table: mapping for actual divider value to register divider value
     68 *             in case of non fixed divider
     69 * @freq_tbl: frequency table
     70 */
     71struct clk_fepll {
     72	u32 fixed_div;
     73	const u8 *parent_map;
     74	struct clk_regmap_div cdiv;
     75	const struct clk_fepll_vco *pll_vco;
     76	const struct clk_div_table *div_table;
     77	const struct freq_tbl *freq_tbl;
     78};
     79
     80static struct parent_map gcc_xo_200_500_map[] = {
     81	{ P_XO, 0 },
     82	{ P_FEPLL200, 1 },
     83	{ P_FEPLL500, 2 },
     84};
     85
     86static const char * const gcc_xo_200_500[] = {
     87	"xo",
     88	"fepll200",
     89	"fepll500",
     90};
     91
     92static struct parent_map gcc_xo_200_map[] = {
     93	{  P_XO, 0 },
     94	{  P_FEPLL200, 1 },
     95};
     96
     97static const char * const gcc_xo_200[] = {
     98	"xo",
     99	"fepll200",
    100};
    101
    102static struct parent_map gcc_xo_200_spi_map[] = {
    103	{  P_XO, 0 },
    104	{  P_FEPLL200, 2 },
    105};
    106
    107static const char * const gcc_xo_200_spi[] = {
    108	"xo",
    109	"fepll200",
    110};
    111
    112static struct parent_map gcc_xo_sdcc1_500_map[] = {
    113	{  P_XO, 0 },
    114	{  P_DDRPLL, 1 },
    115	{  P_FEPLL500, 2 },
    116};
    117
    118static const char * const gcc_xo_sdcc1_500[] = {
    119	"xo",
    120	"ddrpllsdcc",
    121	"fepll500",
    122};
    123
    124static struct parent_map gcc_xo_wcss2g_map[] = {
    125	{  P_XO, 0 },
    126	{  P_FEPLLWCSS2G, 1 },
    127};
    128
    129static const char * const gcc_xo_wcss2g[] = {
    130	"xo",
    131	"fepllwcss2g",
    132};
    133
    134static struct parent_map gcc_xo_wcss5g_map[] = {
    135	{  P_XO, 0 },
    136	{  P_FEPLLWCSS5G, 1 },
    137};
    138
    139static const char * const gcc_xo_wcss5g[] = {
    140	"xo",
    141	"fepllwcss5g",
    142};
    143
    144static struct parent_map gcc_xo_125_dly_map[] = {
    145	{  P_XO, 0 },
    146	{  P_FEPLL125DLY, 1 },
    147};
    148
    149static const char * const gcc_xo_125_dly[] = {
    150	"xo",
    151	"fepll125dly",
    152};
    153
    154static struct parent_map gcc_xo_ddr_500_200_map[] = {
    155	{  P_XO, 0 },
    156	{  P_FEPLL200, 3 },
    157	{  P_FEPLL500, 2 },
    158	{  P_DDRPLLAPSS, 1 },
    159};
    160
    161/*
    162 * Contains index for safe clock during APSS freq change.
    163 * fepll500 is being used as safe clock so initialize it
    164 * with its index in parents list gcc_xo_ddr_500_200.
    165 */
    166static const int gcc_ipq4019_cpu_safe_parent = 2;
    167static const char * const gcc_xo_ddr_500_200[] = {
    168	"xo",
    169	"fepll200",
    170	"fepll500",
    171	"ddrpllapss",
    172};
    173
    174static const struct freq_tbl ftbl_gcc_audio_pwm_clk[] = {
    175	F(48000000, P_XO, 1, 0, 0),
    176	F(200000000, P_FEPLL200, 1, 0, 0),
    177	{ }
    178};
    179
    180static struct clk_rcg2 audio_clk_src = {
    181	.cmd_rcgr = 0x1b000,
    182	.hid_width = 5,
    183	.parent_map = gcc_xo_200_map,
    184	.freq_tbl = ftbl_gcc_audio_pwm_clk,
    185	.clkr.hw.init = &(struct clk_init_data){
    186		.name = "audio_clk_src",
    187		.parent_names = gcc_xo_200,
    188		.num_parents = 2,
    189		.ops = &clk_rcg2_ops,
    190
    191	},
    192};
    193
    194static struct clk_branch gcc_audio_ahb_clk = {
    195	.halt_reg = 0x1b010,
    196	.clkr = {
    197		.enable_reg = 0x1b010,
    198		.enable_mask = BIT(0),
    199		.hw.init = &(struct clk_init_data){
    200			.name = "gcc_audio_ahb_clk",
    201			.parent_names = (const char *[]){
    202				"pcnoc_clk_src",
    203			},
    204			.flags = CLK_SET_RATE_PARENT,
    205			.num_parents = 1,
    206			.ops = &clk_branch2_ops,
    207		},
    208	},
    209};
    210
    211static struct clk_branch gcc_audio_pwm_clk = {
    212	.halt_reg = 0x1b00C,
    213	.clkr = {
    214		.enable_reg = 0x1b00C,
    215		.enable_mask = BIT(0),
    216		.hw.init = &(struct clk_init_data){
    217			.name = "gcc_audio_pwm_clk",
    218			.parent_names = (const char *[]){
    219				"audio_clk_src",
    220			},
    221			.flags = CLK_SET_RATE_PARENT,
    222			.num_parents = 1,
    223			.ops = &clk_branch2_ops,
    224		},
    225	},
    226};
    227
    228static const struct freq_tbl ftbl_gcc_blsp1_qup1_2_i2c_apps_clk[] = {
    229	F(19050000, P_FEPLL200, 10.5, 1, 1),
    230	{ }
    231};
    232
    233static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = {
    234	.cmd_rcgr = 0x200c,
    235	.hid_width = 5,
    236	.parent_map = gcc_xo_200_map,
    237	.freq_tbl = ftbl_gcc_blsp1_qup1_2_i2c_apps_clk,
    238	.clkr.hw.init = &(struct clk_init_data){
    239		.name = "blsp1_qup1_i2c_apps_clk_src",
    240		.parent_names = gcc_xo_200,
    241		.num_parents = 2,
    242		.ops = &clk_rcg2_ops,
    243	},
    244};
    245
    246static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = {
    247	.halt_reg = 0x2008,
    248	.clkr = {
    249		.enable_reg = 0x2008,
    250		.enable_mask = BIT(0),
    251		.hw.init = &(struct clk_init_data){
    252			.name = "gcc_blsp1_qup1_i2c_apps_clk",
    253			.parent_names = (const char *[]){
    254				"blsp1_qup1_i2c_apps_clk_src",
    255			},
    256			.num_parents = 1,
    257			.ops = &clk_branch2_ops,
    258			.flags = CLK_SET_RATE_PARENT,
    259		},
    260	},
    261};
    262
    263static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = {
    264	.cmd_rcgr = 0x3000,
    265	.hid_width = 5,
    266	.parent_map = gcc_xo_200_map,
    267	.freq_tbl = ftbl_gcc_blsp1_qup1_2_i2c_apps_clk,
    268	.clkr.hw.init = &(struct clk_init_data){
    269		.name = "blsp1_qup2_i2c_apps_clk_src",
    270		.parent_names = gcc_xo_200,
    271		.num_parents = 2,
    272		.ops = &clk_rcg2_ops,
    273	},
    274};
    275
    276static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = {
    277	.halt_reg = 0x3010,
    278	.clkr = {
    279		.enable_reg = 0x3010,
    280		.enable_mask = BIT(0),
    281		.hw.init = &(struct clk_init_data){
    282			.name = "gcc_blsp1_qup2_i2c_apps_clk",
    283			.parent_names = (const char *[]){
    284				"blsp1_qup2_i2c_apps_clk_src",
    285			},
    286			.num_parents = 1,
    287			.ops = &clk_branch2_ops,
    288			.flags = CLK_SET_RATE_PARENT,
    289		},
    290	},
    291};
    292
    293static const struct freq_tbl ftbl_gcc_blsp1_qup1_2_spi_apps_clk[] = {
    294	F(960000, P_XO, 12, 1, 4),
    295	F(4800000, P_XO, 1, 1, 10),
    296	F(9600000, P_XO, 1, 1, 5),
    297	F(15000000, P_XO, 1, 1, 3),
    298	F(19200000, P_XO, 1, 2, 5),
    299	F(24000000, P_XO, 1, 1, 2),
    300	F(48000000, P_XO, 1, 0, 0),
    301	{ }
    302};
    303
    304static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = {
    305	.cmd_rcgr = 0x2024,
    306	.mnd_width = 8,
    307	.hid_width = 5,
    308	.parent_map = gcc_xo_200_spi_map,
    309	.freq_tbl = ftbl_gcc_blsp1_qup1_2_spi_apps_clk,
    310	.clkr.hw.init = &(struct clk_init_data){
    311		.name = "blsp1_qup1_spi_apps_clk_src",
    312		.parent_names = gcc_xo_200_spi,
    313		.num_parents = 2,
    314		.ops = &clk_rcg2_ops,
    315	},
    316};
    317
    318static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = {
    319	.halt_reg = 0x2004,
    320	.clkr = {
    321		.enable_reg = 0x2004,
    322		.enable_mask = BIT(0),
    323		.hw.init = &(struct clk_init_data){
    324			.name = "gcc_blsp1_qup1_spi_apps_clk",
    325			.parent_names = (const char *[]){
    326				"blsp1_qup1_spi_apps_clk_src",
    327			},
    328			.num_parents = 1,
    329			.ops = &clk_branch2_ops,
    330			.flags = CLK_SET_RATE_PARENT,
    331		},
    332	},
    333};
    334
    335static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = {
    336	.cmd_rcgr = 0x3014,
    337	.mnd_width = 8,
    338	.hid_width = 5,
    339	.freq_tbl = ftbl_gcc_blsp1_qup1_2_spi_apps_clk,
    340	.parent_map = gcc_xo_200_spi_map,
    341	.clkr.hw.init = &(struct clk_init_data){
    342		.name = "blsp1_qup2_spi_apps_clk_src",
    343		.parent_names = gcc_xo_200_spi,
    344		.num_parents = 2,
    345		.ops = &clk_rcg2_ops,
    346	},
    347};
    348
    349static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = {
    350	.halt_reg = 0x300c,
    351	.clkr = {
    352		.enable_reg = 0x300c,
    353		.enable_mask = BIT(0),
    354		.hw.init = &(struct clk_init_data){
    355			.name = "gcc_blsp1_qup2_spi_apps_clk",
    356			.parent_names = (const char *[]){
    357				"blsp1_qup2_spi_apps_clk_src",
    358			},
    359			.num_parents = 1,
    360			.ops = &clk_branch2_ops,
    361			.flags = CLK_SET_RATE_PARENT,
    362		},
    363	},
    364};
    365
    366static const struct freq_tbl ftbl_gcc_blsp1_uart1_2_apps_clk[] = {
    367	F(1843200, P_FEPLL200, 1, 144, 15625),
    368	F(3686400, P_FEPLL200, 1, 288, 15625),
    369	F(7372800, P_FEPLL200, 1, 576, 15625),
    370	F(14745600, P_FEPLL200, 1, 1152, 15625),
    371	F(16000000, P_FEPLL200, 1, 2, 25),
    372	F(24000000, P_XO, 1, 1, 2),
    373	F(32000000, P_FEPLL200, 1, 4, 25),
    374	F(40000000, P_FEPLL200, 1, 1, 5),
    375	F(46400000, P_FEPLL200, 1, 29, 125),
    376	F(48000000, P_XO, 1, 0, 0),
    377	{ }
    378};
    379
    380static struct clk_rcg2 blsp1_uart1_apps_clk_src = {
    381	.cmd_rcgr = 0x2044,
    382	.mnd_width = 16,
    383	.hid_width = 5,
    384	.freq_tbl = ftbl_gcc_blsp1_uart1_2_apps_clk,
    385	.parent_map = gcc_xo_200_spi_map,
    386	.clkr.hw.init = &(struct clk_init_data){
    387		.name = "blsp1_uart1_apps_clk_src",
    388		.parent_names = gcc_xo_200_spi,
    389		.num_parents = 2,
    390		.ops = &clk_rcg2_ops,
    391	},
    392};
    393
    394static struct clk_branch gcc_blsp1_uart1_apps_clk = {
    395	.halt_reg = 0x203c,
    396	.clkr = {
    397		.enable_reg = 0x203c,
    398		.enable_mask = BIT(0),
    399		.hw.init = &(struct clk_init_data){
    400			.name = "gcc_blsp1_uart1_apps_clk",
    401			.parent_names = (const char *[]){
    402				"blsp1_uart1_apps_clk_src",
    403			},
    404			.flags = CLK_SET_RATE_PARENT,
    405			.num_parents = 1,
    406			.ops = &clk_branch2_ops,
    407		},
    408	},
    409};
    410
    411static struct clk_rcg2 blsp1_uart2_apps_clk_src = {
    412	.cmd_rcgr = 0x3034,
    413	.mnd_width = 16,
    414	.hid_width = 5,
    415	.freq_tbl = ftbl_gcc_blsp1_uart1_2_apps_clk,
    416	.parent_map = gcc_xo_200_spi_map,
    417	.clkr.hw.init = &(struct clk_init_data){
    418		.name = "blsp1_uart2_apps_clk_src",
    419		.parent_names = gcc_xo_200_spi,
    420		.num_parents = 2,
    421		.ops = &clk_rcg2_ops,
    422	},
    423};
    424
    425static struct clk_branch gcc_blsp1_uart2_apps_clk = {
    426	.halt_reg = 0x302c,
    427	.clkr = {
    428		.enable_reg = 0x302c,
    429		.enable_mask = BIT(0),
    430		.hw.init = &(struct clk_init_data){
    431			.name = "gcc_blsp1_uart2_apps_clk",
    432			.parent_names = (const char *[]){
    433				"blsp1_uart2_apps_clk_src",
    434			},
    435			.num_parents = 1,
    436			.ops = &clk_branch2_ops,
    437			.flags = CLK_SET_RATE_PARENT,
    438		},
    439	},
    440};
    441
    442static const struct freq_tbl ftbl_gcc_gp_clk[] = {
    443	F(1250000,  P_FEPLL200, 1, 16, 0),
    444	F(2500000,  P_FEPLL200, 1,  8, 0),
    445	F(5000000,  P_FEPLL200, 1,  4, 0),
    446	{ }
    447};
    448
    449static struct clk_rcg2 gp1_clk_src = {
    450	.cmd_rcgr = 0x8004,
    451	.mnd_width = 8,
    452	.hid_width = 5,
    453	.freq_tbl = ftbl_gcc_gp_clk,
    454	.parent_map = gcc_xo_200_map,
    455	.clkr.hw.init = &(struct clk_init_data){
    456		.name = "gp1_clk_src",
    457		.parent_names = gcc_xo_200,
    458		.num_parents = 2,
    459		.ops = &clk_rcg2_ops,
    460	},
    461};
    462
    463static struct clk_branch gcc_gp1_clk = {
    464	.halt_reg = 0x8000,
    465	.clkr = {
    466		.enable_reg = 0x8000,
    467		.enable_mask = BIT(0),
    468		.hw.init = &(struct clk_init_data){
    469			.name = "gcc_gp1_clk",
    470			.parent_names = (const char *[]){
    471				"gp1_clk_src",
    472			},
    473			.num_parents = 1,
    474			.ops = &clk_branch2_ops,
    475			.flags = CLK_SET_RATE_PARENT,
    476		},
    477	},
    478};
    479
    480static struct clk_rcg2 gp2_clk_src = {
    481	.cmd_rcgr = 0x9004,
    482	.mnd_width = 8,
    483	.hid_width = 5,
    484	.freq_tbl = ftbl_gcc_gp_clk,
    485	.parent_map = gcc_xo_200_map,
    486	.clkr.hw.init = &(struct clk_init_data){
    487		.name = "gp2_clk_src",
    488		.parent_names = gcc_xo_200,
    489		.num_parents = 2,
    490		.ops = &clk_rcg2_ops,
    491	},
    492};
    493
    494static struct clk_branch gcc_gp2_clk = {
    495	.halt_reg = 0x9000,
    496	.clkr = {
    497		.enable_reg = 0x9000,
    498		.enable_mask = BIT(0),
    499		.hw.init = &(struct clk_init_data){
    500			.name = "gcc_gp2_clk",
    501			.parent_names = (const char *[]){
    502				"gp2_clk_src",
    503			},
    504			.num_parents = 1,
    505			.ops = &clk_branch2_ops,
    506			.flags = CLK_SET_RATE_PARENT,
    507		},
    508	},
    509};
    510
    511static struct clk_rcg2 gp3_clk_src = {
    512	.cmd_rcgr = 0xa004,
    513	.mnd_width = 8,
    514	.hid_width = 5,
    515	.freq_tbl = ftbl_gcc_gp_clk,
    516	.parent_map = gcc_xo_200_map,
    517	.clkr.hw.init = &(struct clk_init_data){
    518		.name = "gp3_clk_src",
    519		.parent_names = gcc_xo_200,
    520		.num_parents = 2,
    521		.ops = &clk_rcg2_ops,
    522	},
    523};
    524
    525static struct clk_branch gcc_gp3_clk = {
    526	.halt_reg = 0xa000,
    527	.clkr = {
    528		.enable_reg = 0xa000,
    529		.enable_mask = BIT(0),
    530		.hw.init = &(struct clk_init_data){
    531			.name = "gcc_gp3_clk",
    532			.parent_names = (const char *[]){
    533				"gp3_clk_src",
    534			},
    535			.num_parents = 1,
    536			.ops = &clk_branch2_ops,
    537			.flags = CLK_SET_RATE_PARENT,
    538		},
    539	},
    540};
    541
    542static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk[] = {
    543	F(144000,    P_XO,			1,  3, 240),
    544	F(400000,    P_XO,			1,  1, 0),
    545	F(20000000,  P_FEPLL500,		1,  1, 25),
    546	F(25000000,  P_FEPLL500,		1,  1, 20),
    547	F(50000000,  P_FEPLL500,		1,  1, 10),
    548	F(100000000, P_FEPLL500,		1,  1, 5),
    549	F(192000000, P_DDRPLL,			1,  0, 0),
    550	{ }
    551};
    552
    553static struct clk_rcg2  sdcc1_apps_clk_src = {
    554	.cmd_rcgr = 0x18004,
    555	.hid_width = 5,
    556	.freq_tbl = ftbl_gcc_sdcc1_apps_clk,
    557	.parent_map = gcc_xo_sdcc1_500_map,
    558	.clkr.hw.init = &(struct clk_init_data){
    559		.name = "sdcc1_apps_clk_src",
    560		.parent_names = gcc_xo_sdcc1_500,
    561		.num_parents = 3,
    562		.ops = &clk_rcg2_ops,
    563		.flags = CLK_SET_RATE_PARENT,
    564	},
    565};
    566
    567static const struct freq_tbl ftbl_gcc_apps_clk[] = {
    568	F(48000000,  P_XO,         1, 0, 0),
    569	F(200000000, P_FEPLL200,   1, 0, 0),
    570	F(384000000, P_DDRPLLAPSS, 1, 0, 0),
    571	F(413000000, P_DDRPLLAPSS, 1, 0, 0),
    572	F(448000000, P_DDRPLLAPSS, 1, 0, 0),
    573	F(488000000, P_DDRPLLAPSS, 1, 0, 0),
    574	F(500000000, P_FEPLL500,   1, 0, 0),
    575	F(512000000, P_DDRPLLAPSS, 1, 0, 0),
    576	F(537000000, P_DDRPLLAPSS, 1, 0, 0),
    577	F(565000000, P_DDRPLLAPSS, 1, 0, 0),
    578	F(597000000, P_DDRPLLAPSS, 1, 0, 0),
    579	F(632000000, P_DDRPLLAPSS, 1, 0, 0),
    580	F(672000000, P_DDRPLLAPSS, 1, 0, 0),
    581	F(716000000, P_DDRPLLAPSS, 1, 0, 0),
    582	{ }
    583};
    584
    585static struct clk_rcg2 apps_clk_src = {
    586	.cmd_rcgr = 0x1900c,
    587	.hid_width = 5,
    588	.freq_tbl = ftbl_gcc_apps_clk,
    589	.parent_map = gcc_xo_ddr_500_200_map,
    590	.clkr.hw.init = &(struct clk_init_data){
    591		.name = "apps_clk_src",
    592		.parent_names = gcc_xo_ddr_500_200,
    593		.num_parents = 4,
    594		.ops = &clk_rcg2_ops,
    595		.flags = CLK_SET_RATE_PARENT,
    596	},
    597};
    598
    599static const struct freq_tbl ftbl_gcc_apps_ahb_clk[] = {
    600	F(48000000, P_XO,	   1, 0, 0),
    601	F(100000000, P_FEPLL200,   2, 0, 0),
    602	{ }
    603};
    604
    605static struct clk_rcg2 apps_ahb_clk_src = {
    606	.cmd_rcgr = 0x19014,
    607	.hid_width = 5,
    608	.parent_map = gcc_xo_200_500_map,
    609	.freq_tbl = ftbl_gcc_apps_ahb_clk,
    610	.clkr.hw.init = &(struct clk_init_data){
    611		.name = "apps_ahb_clk_src",
    612		.parent_names = gcc_xo_200_500,
    613		.num_parents = 3,
    614		.ops = &clk_rcg2_ops,
    615	},
    616};
    617
    618static struct clk_branch gcc_apss_ahb_clk = {
    619	.halt_reg = 0x19004,
    620	.halt_check = BRANCH_HALT_VOTED,
    621	.clkr = {
    622		.enable_reg = 0x6000,
    623		.enable_mask = BIT(14),
    624		.hw.init = &(struct clk_init_data){
    625			.name = "gcc_apss_ahb_clk",
    626			.parent_names = (const char *[]){
    627				"apps_ahb_clk_src",
    628			},
    629			.num_parents = 1,
    630			.ops = &clk_branch2_ops,
    631			.flags = CLK_SET_RATE_PARENT,
    632		},
    633	},
    634};
    635
    636static struct clk_branch gcc_blsp1_ahb_clk = {
    637	.halt_reg = 0x1008,
    638	.halt_check = BRANCH_HALT_VOTED,
    639	.clkr = {
    640		.enable_reg = 0x6000,
    641		.enable_mask = BIT(10),
    642		.hw.init = &(struct clk_init_data){
    643			.name = "gcc_blsp1_ahb_clk",
    644			.parent_names = (const char *[]){
    645				"pcnoc_clk_src",
    646			},
    647			.num_parents = 1,
    648			.ops = &clk_branch2_ops,
    649		},
    650	},
    651};
    652
    653static struct clk_branch gcc_dcd_xo_clk = {
    654	.halt_reg = 0x2103c,
    655	.clkr = {
    656		.enable_reg = 0x2103c,
    657		.enable_mask = BIT(0),
    658		.hw.init = &(struct clk_init_data){
    659			.name = "gcc_dcd_xo_clk",
    660			.parent_names = (const char *[]){
    661				"xo",
    662			},
    663			.num_parents = 1,
    664			.ops = &clk_branch2_ops,
    665		},
    666	},
    667};
    668
    669static struct clk_branch gcc_boot_rom_ahb_clk = {
    670	.halt_reg = 0x1300c,
    671	.clkr = {
    672		.enable_reg = 0x1300c,
    673		.enable_mask = BIT(0),
    674		.hw.init = &(struct clk_init_data){
    675			.name = "gcc_boot_rom_ahb_clk",
    676			.parent_names = (const char *[]){
    677				"pcnoc_clk_src",
    678			},
    679			.num_parents = 1,
    680			.ops = &clk_branch2_ops,
    681			.flags = CLK_SET_RATE_PARENT,
    682		},
    683	},
    684};
    685
    686static struct clk_branch gcc_crypto_ahb_clk = {
    687	.halt_reg = 0x16024,
    688	.halt_check = BRANCH_HALT_VOTED,
    689	.clkr = {
    690		.enable_reg = 0x6000,
    691		.enable_mask = BIT(0),
    692		.hw.init = &(struct clk_init_data){
    693			.name = "gcc_crypto_ahb_clk",
    694			.parent_names = (const char *[]){
    695				"pcnoc_clk_src",
    696			},
    697			.num_parents = 1,
    698			.ops = &clk_branch2_ops,
    699		},
    700	},
    701};
    702
    703static struct clk_branch gcc_crypto_axi_clk = {
    704	.halt_reg = 0x16020,
    705	.halt_check = BRANCH_HALT_VOTED,
    706	.clkr = {
    707		.enable_reg = 0x6000,
    708		.enable_mask = BIT(1),
    709		.hw.init = &(struct clk_init_data){
    710			.name = "gcc_crypto_axi_clk",
    711			.parent_names = (const char *[]){
    712				"fepll125",
    713			},
    714			.num_parents = 1,
    715			.ops = &clk_branch2_ops,
    716		},
    717	},
    718};
    719
    720static struct clk_branch gcc_crypto_clk = {
    721	.halt_reg = 0x1601c,
    722	.halt_check = BRANCH_HALT_VOTED,
    723	.clkr = {
    724		.enable_reg = 0x6000,
    725		.enable_mask = BIT(2),
    726		.hw.init = &(struct clk_init_data){
    727			.name = "gcc_crypto_clk",
    728			.parent_names = (const char *[]){
    729				"fepll125",
    730			},
    731			.num_parents = 1,
    732			.ops = &clk_branch2_ops,
    733		},
    734	},
    735};
    736
    737static struct clk_branch gcc_ess_clk = {
    738	.halt_reg = 0x12010,
    739	.clkr = {
    740		.enable_reg = 0x12010,
    741		.enable_mask = BIT(0),
    742		.hw.init = &(struct clk_init_data){
    743			.name = "gcc_ess_clk",
    744			.parent_names = (const char *[]){
    745				"fephy_125m_dly_clk_src",
    746			},
    747			.num_parents = 1,
    748			.ops = &clk_branch2_ops,
    749			.flags = CLK_SET_RATE_PARENT,
    750		},
    751	},
    752};
    753
    754static struct clk_branch gcc_imem_axi_clk = {
    755	.halt_reg = 0xe004,
    756	.halt_check = BRANCH_HALT_VOTED,
    757	.clkr = {
    758		.enable_reg = 0x6000,
    759		.enable_mask = BIT(17),
    760		.hw.init = &(struct clk_init_data){
    761			.name = "gcc_imem_axi_clk",
    762			.parent_names = (const char *[]){
    763				"fepll200",
    764			},
    765			.num_parents = 1,
    766			.ops = &clk_branch2_ops,
    767		},
    768	},
    769};
    770
    771static struct clk_branch gcc_imem_cfg_ahb_clk = {
    772	.halt_reg = 0xe008,
    773	.clkr = {
    774		.enable_reg = 0xe008,
    775		.enable_mask = BIT(0),
    776		.hw.init = &(struct clk_init_data){
    777			.name = "gcc_imem_cfg_ahb_clk",
    778			.parent_names = (const char *[]){
    779				"pcnoc_clk_src",
    780			},
    781			.num_parents = 1,
    782			.ops = &clk_branch2_ops,
    783		},
    784	},
    785};
    786
    787static struct clk_branch gcc_pcie_ahb_clk = {
    788	.halt_reg = 0x1d00c,
    789	.clkr = {
    790		.enable_reg = 0x1d00c,
    791		.enable_mask = BIT(0),
    792		.hw.init = &(struct clk_init_data){
    793			.name = "gcc_pcie_ahb_clk",
    794			.parent_names = (const char *[]){
    795				"pcnoc_clk_src",
    796			},
    797			.num_parents = 1,
    798			.ops = &clk_branch2_ops,
    799		},
    800	},
    801};
    802
    803static struct clk_branch gcc_pcie_axi_m_clk = {
    804	.halt_reg = 0x1d004,
    805	.clkr = {
    806		.enable_reg = 0x1d004,
    807		.enable_mask = BIT(0),
    808		.hw.init = &(struct clk_init_data){
    809			.name = "gcc_pcie_axi_m_clk",
    810			.parent_names = (const char *[]){
    811				"fepll200",
    812			},
    813			.num_parents = 1,
    814			.ops = &clk_branch2_ops,
    815		},
    816	},
    817};
    818
    819static struct clk_branch gcc_pcie_axi_s_clk = {
    820	.halt_reg = 0x1d008,
    821	.clkr = {
    822		.enable_reg = 0x1d008,
    823		.enable_mask = BIT(0),
    824		.hw.init = &(struct clk_init_data){
    825			.name = "gcc_pcie_axi_s_clk",
    826			.parent_names = (const char *[]){
    827				"fepll200",
    828			},
    829			.num_parents = 1,
    830			.ops = &clk_branch2_ops,
    831		},
    832	},
    833};
    834
    835static struct clk_branch gcc_prng_ahb_clk = {
    836	.halt_reg = 0x13004,
    837	.halt_check = BRANCH_HALT_VOTED,
    838	.clkr = {
    839		.enable_reg = 0x6000,
    840		.enable_mask = BIT(8),
    841		.hw.init = &(struct clk_init_data){
    842			.name = "gcc_prng_ahb_clk",
    843			.parent_names = (const char *[]){
    844				"pcnoc_clk_src",
    845			},
    846			.num_parents = 1,
    847			.ops = &clk_branch2_ops,
    848		},
    849	},
    850};
    851
    852static struct clk_branch gcc_qpic_ahb_clk = {
    853	.halt_reg = 0x1c008,
    854	.clkr = {
    855		.enable_reg = 0x1c008,
    856		.enable_mask = BIT(0),
    857		.hw.init = &(struct clk_init_data){
    858			.name = "gcc_qpic_ahb_clk",
    859			.parent_names = (const char *[]){
    860				"pcnoc_clk_src",
    861			},
    862			.num_parents = 1,
    863			.ops = &clk_branch2_ops,
    864		},
    865	},
    866};
    867
    868static struct clk_branch gcc_qpic_clk = {
    869	.halt_reg = 0x1c004,
    870	.clkr = {
    871		.enable_reg = 0x1c004,
    872		.enable_mask = BIT(0),
    873		.hw.init = &(struct clk_init_data){
    874			.name = "gcc_qpic_clk",
    875			.parent_names = (const char *[]){
    876				"pcnoc_clk_src",
    877			},
    878			.num_parents = 1,
    879			.ops = &clk_branch2_ops,
    880		},
    881	},
    882};
    883
    884static struct clk_branch gcc_sdcc1_ahb_clk = {
    885	.halt_reg = 0x18010,
    886	.clkr = {
    887		.enable_reg = 0x18010,
    888		.enable_mask = BIT(0),
    889		.hw.init = &(struct clk_init_data){
    890			.name = "gcc_sdcc1_ahb_clk",
    891			.parent_names = (const char *[]){
    892				"pcnoc_clk_src",
    893			},
    894			.num_parents = 1,
    895			.ops = &clk_branch2_ops,
    896		},
    897	},
    898};
    899
    900static struct clk_branch gcc_sdcc1_apps_clk = {
    901	.halt_reg = 0x1800c,
    902	.clkr = {
    903		.enable_reg = 0x1800c,
    904		.enable_mask = BIT(0),
    905		.hw.init = &(struct clk_init_data){
    906			.name = "gcc_sdcc1_apps_clk",
    907			.parent_names = (const char *[]){
    908				"sdcc1_apps_clk_src",
    909			},
    910			.num_parents = 1,
    911			.ops = &clk_branch2_ops,
    912			.flags = CLK_SET_RATE_PARENT,
    913		},
    914	},
    915};
    916
    917static struct clk_branch gcc_tlmm_ahb_clk = {
    918	.halt_reg = 0x5004,
    919	.halt_check = BRANCH_HALT_VOTED,
    920	.clkr = {
    921		.enable_reg = 0x6000,
    922		.enable_mask = BIT(5),
    923		.hw.init = &(struct clk_init_data){
    924			.name = "gcc_tlmm_ahb_clk",
    925			.parent_names = (const char *[]){
    926				"pcnoc_clk_src",
    927			},
    928			.num_parents = 1,
    929			.ops = &clk_branch2_ops,
    930		},
    931	},
    932};
    933
    934static struct clk_branch gcc_usb2_master_clk = {
    935	.halt_reg = 0x1e00c,
    936	.clkr = {
    937		.enable_reg = 0x1e00c,
    938		.enable_mask = BIT(0),
    939		.hw.init = &(struct clk_init_data){
    940			.name = "gcc_usb2_master_clk",
    941			.parent_names = (const char *[]){
    942				"pcnoc_clk_src",
    943			},
    944			.num_parents = 1,
    945			.ops = &clk_branch2_ops,
    946		},
    947	},
    948};
    949
    950static struct clk_branch gcc_usb2_sleep_clk = {
    951	.halt_reg = 0x1e010,
    952	.clkr = {
    953		.enable_reg = 0x1e010,
    954		.enable_mask = BIT(0),
    955		.hw.init = &(struct clk_init_data){
    956			.name = "gcc_usb2_sleep_clk",
    957			.parent_names = (const char *[]){
    958				"gcc_sleep_clk_src",
    959			},
    960			.num_parents = 1,
    961			.ops = &clk_branch2_ops,
    962		},
    963	},
    964};
    965
    966static struct clk_branch gcc_usb2_mock_utmi_clk = {
    967	.halt_reg = 0x1e014,
    968	.clkr = {
    969		.enable_reg = 0x1e014,
    970		.enable_mask = BIT(0),
    971		.hw.init = &(struct clk_init_data){
    972			.name = "gcc_usb2_mock_utmi_clk",
    973			.parent_names = (const char *[]){
    974				"usb30_mock_utmi_clk_src",
    975			},
    976			.num_parents = 1,
    977			.ops = &clk_branch2_ops,
    978			.flags = CLK_SET_RATE_PARENT,
    979		},
    980	},
    981};
    982
    983static const struct freq_tbl ftbl_gcc_usb30_mock_utmi_clk[] = {
    984	F(2000000, P_FEPLL200, 10, 0, 0),
    985	{ }
    986};
    987
    988static struct clk_rcg2 usb30_mock_utmi_clk_src = {
    989	.cmd_rcgr = 0x1e000,
    990	.hid_width = 5,
    991	.parent_map = gcc_xo_200_map,
    992	.freq_tbl = ftbl_gcc_usb30_mock_utmi_clk,
    993	.clkr.hw.init = &(struct clk_init_data){
    994		.name = "usb30_mock_utmi_clk_src",
    995		.parent_names = gcc_xo_200,
    996		.num_parents = 2,
    997		.ops = &clk_rcg2_ops,
    998	},
    999};
   1000
   1001static struct clk_branch gcc_usb3_master_clk = {
   1002	.halt_reg = 0x1e028,
   1003	.clkr = {
   1004		.enable_reg = 0x1e028,
   1005		.enable_mask = BIT(0),
   1006		.hw.init = &(struct clk_init_data){
   1007			.name = "gcc_usb3_master_clk",
   1008			.parent_names = (const char *[]){
   1009				"fepll125",
   1010			},
   1011			.num_parents = 1,
   1012			.ops = &clk_branch2_ops,
   1013		},
   1014	},
   1015};
   1016
   1017static struct clk_branch gcc_usb3_sleep_clk = {
   1018	.halt_reg = 0x1e02C,
   1019	.clkr = {
   1020		.enable_reg = 0x1e02C,
   1021		.enable_mask = BIT(0),
   1022		.hw.init = &(struct clk_init_data){
   1023			.name = "gcc_usb3_sleep_clk",
   1024			.parent_names = (const char *[]){
   1025				"gcc_sleep_clk_src",
   1026			},
   1027			.num_parents = 1,
   1028			.ops = &clk_branch2_ops,
   1029		},
   1030	},
   1031};
   1032
   1033static struct clk_branch gcc_usb3_mock_utmi_clk = {
   1034	.halt_reg = 0x1e030,
   1035	.clkr = {
   1036		.enable_reg = 0x1e030,
   1037		.enable_mask = BIT(0),
   1038		.hw.init = &(struct clk_init_data){
   1039			.name = "gcc_usb3_mock_utmi_clk",
   1040			.parent_names = (const char *[]){
   1041				"usb30_mock_utmi_clk_src",
   1042			},
   1043			.num_parents = 1,
   1044			.ops = &clk_branch2_ops,
   1045			.flags = CLK_SET_RATE_PARENT,
   1046		},
   1047	},
   1048};
   1049
   1050static const struct freq_tbl ftbl_gcc_fephy_dly_clk[] = {
   1051	F(125000000, P_FEPLL125DLY, 1, 0, 0),
   1052	{ }
   1053};
   1054
   1055static struct clk_rcg2 fephy_125m_dly_clk_src = {
   1056	.cmd_rcgr = 0x12000,
   1057	.hid_width = 5,
   1058	.parent_map = gcc_xo_125_dly_map,
   1059	.freq_tbl = ftbl_gcc_fephy_dly_clk,
   1060	.clkr.hw.init = &(struct clk_init_data){
   1061		.name = "fephy_125m_dly_clk_src",
   1062		.parent_names = gcc_xo_125_dly,
   1063		.num_parents = 2,
   1064		.ops = &clk_rcg2_ops,
   1065	},
   1066};
   1067
   1068
   1069static const struct freq_tbl ftbl_gcc_wcss2g_clk[] = {
   1070	F(48000000, P_XO, 1, 0, 0),
   1071	F(250000000, P_FEPLLWCSS2G, 1, 0, 0),
   1072	{ }
   1073};
   1074
   1075static struct clk_rcg2 wcss2g_clk_src = {
   1076	.cmd_rcgr = 0x1f000,
   1077	.hid_width = 5,
   1078	.freq_tbl = ftbl_gcc_wcss2g_clk,
   1079	.parent_map = gcc_xo_wcss2g_map,
   1080	.clkr.hw.init = &(struct clk_init_data){
   1081		.name = "wcss2g_clk_src",
   1082		.parent_names = gcc_xo_wcss2g,
   1083		.num_parents = 2,
   1084		.ops = &clk_rcg2_ops,
   1085		.flags = CLK_SET_RATE_PARENT,
   1086	},
   1087};
   1088
   1089static struct clk_branch gcc_wcss2g_clk = {
   1090	.halt_reg = 0x1f00C,
   1091	.clkr = {
   1092		.enable_reg = 0x1f00C,
   1093		.enable_mask = BIT(0),
   1094		.hw.init = &(struct clk_init_data){
   1095			.name = "gcc_wcss2g_clk",
   1096			.parent_names = (const char *[]){
   1097				"wcss2g_clk_src",
   1098			},
   1099			.num_parents = 1,
   1100			.ops = &clk_branch2_ops,
   1101			.flags = CLK_SET_RATE_PARENT,
   1102		},
   1103	},
   1104};
   1105
   1106static struct clk_branch gcc_wcss2g_ref_clk = {
   1107	.halt_reg = 0x1f00C,
   1108	.clkr = {
   1109		.enable_reg = 0x1f00C,
   1110		.enable_mask = BIT(0),
   1111		.hw.init = &(struct clk_init_data){
   1112			.name = "gcc_wcss2g_ref_clk",
   1113			.parent_names = (const char *[]){
   1114				"xo",
   1115			},
   1116			.num_parents = 1,
   1117			.ops = &clk_branch2_ops,
   1118			.flags = CLK_SET_RATE_PARENT,
   1119		},
   1120	},
   1121};
   1122
   1123static struct clk_branch gcc_wcss2g_rtc_clk = {
   1124	.halt_reg = 0x1f010,
   1125	.clkr = {
   1126		.enable_reg = 0x1f010,
   1127		.enable_mask = BIT(0),
   1128		.hw.init = &(struct clk_init_data){
   1129			.name = "gcc_wcss2g_rtc_clk",
   1130			.parent_names = (const char *[]){
   1131				"gcc_sleep_clk_src",
   1132			},
   1133			.num_parents = 1,
   1134			.ops = &clk_branch2_ops,
   1135		},
   1136	},
   1137};
   1138
   1139static const struct freq_tbl ftbl_gcc_wcss5g_clk[] = {
   1140	F(48000000, P_XO, 1, 0, 0),
   1141	F(250000000, P_FEPLLWCSS5G, 1, 0, 0),
   1142	{ }
   1143};
   1144
   1145static struct clk_rcg2 wcss5g_clk_src = {
   1146	.cmd_rcgr = 0x20000,
   1147	.hid_width = 5,
   1148	.parent_map = gcc_xo_wcss5g_map,
   1149	.freq_tbl = ftbl_gcc_wcss5g_clk,
   1150	.clkr.hw.init = &(struct clk_init_data){
   1151		.name = "wcss5g_clk_src",
   1152		.parent_names = gcc_xo_wcss5g,
   1153		.num_parents = 2,
   1154		.ops = &clk_rcg2_ops,
   1155	},
   1156};
   1157
   1158static struct clk_branch gcc_wcss5g_clk = {
   1159	.halt_reg = 0x2000c,
   1160	.clkr = {
   1161		.enable_reg = 0x2000c,
   1162		.enable_mask = BIT(0),
   1163		.hw.init = &(struct clk_init_data){
   1164			.name = "gcc_wcss5g_clk",
   1165			.parent_names = (const char *[]){
   1166				"wcss5g_clk_src",
   1167			},
   1168			.num_parents = 1,
   1169			.ops = &clk_branch2_ops,
   1170			.flags = CLK_SET_RATE_PARENT,
   1171		},
   1172	},
   1173};
   1174
   1175static struct clk_branch gcc_wcss5g_ref_clk = {
   1176	.halt_reg = 0x2000c,
   1177	.clkr = {
   1178		.enable_reg = 0x2000c,
   1179		.enable_mask = BIT(0),
   1180		.hw.init = &(struct clk_init_data){
   1181			.name = "gcc_wcss5g_ref_clk",
   1182			.parent_names = (const char *[]){
   1183				"xo",
   1184			},
   1185			.num_parents = 1,
   1186			.ops = &clk_branch2_ops,
   1187			.flags = CLK_SET_RATE_PARENT,
   1188		},
   1189	},
   1190};
   1191
   1192static struct clk_branch gcc_wcss5g_rtc_clk = {
   1193	.halt_reg = 0x20010,
   1194	.clkr = {
   1195		.enable_reg = 0x20010,
   1196		.enable_mask = BIT(0),
   1197		.hw.init = &(struct clk_init_data){
   1198			.name = "gcc_wcss5g_rtc_clk",
   1199			.parent_names = (const char *[]){
   1200				"gcc_sleep_clk_src",
   1201			},
   1202			.num_parents = 1,
   1203			.ops = &clk_branch2_ops,
   1204			.flags = CLK_SET_RATE_PARENT,
   1205		},
   1206	},
   1207};
   1208
   1209/* Calculates the VCO rate for FEPLL. */
   1210static u64 clk_fepll_vco_calc_rate(struct clk_fepll *pll_div,
   1211				   unsigned long parent_rate)
   1212{
   1213	const struct clk_fepll_vco *pll_vco = pll_div->pll_vco;
   1214	u32 fdbkdiv, refclkdiv, cdiv;
   1215	u64 vco;
   1216
   1217	regmap_read(pll_div->cdiv.clkr.regmap, pll_vco->reg, &cdiv);
   1218	refclkdiv = (cdiv >> pll_vco->refclkdiv_shift) &
   1219		    (BIT(pll_vco->refclkdiv_width) - 1);
   1220	fdbkdiv = (cdiv >> pll_vco->fdbkdiv_shift) &
   1221		  (BIT(pll_vco->fdbkdiv_width) - 1);
   1222
   1223	vco = parent_rate / refclkdiv;
   1224	vco *= 2;
   1225	vco *= fdbkdiv;
   1226
   1227	return vco;
   1228}
   1229
   1230static const struct clk_fepll_vco gcc_apss_ddrpll_vco = {
   1231	.fdbkdiv_shift = 16,
   1232	.fdbkdiv_width = 8,
   1233	.refclkdiv_shift = 24,
   1234	.refclkdiv_width = 5,
   1235	.reg = 0x2e020,
   1236};
   1237
   1238static const struct clk_fepll_vco gcc_fepll_vco = {
   1239	.fdbkdiv_shift = 16,
   1240	.fdbkdiv_width = 8,
   1241	.refclkdiv_shift = 24,
   1242	.refclkdiv_width = 5,
   1243	.reg = 0x2f020,
   1244};
   1245
   1246/*
   1247 * Round rate function for APSS CPU PLL Clock divider.
   1248 * It looks up the frequency table and returns the next higher frequency
   1249 * supported in hardware.
   1250 */
   1251static long clk_cpu_div_round_rate(struct clk_hw *hw, unsigned long rate,
   1252				   unsigned long *p_rate)
   1253{
   1254	struct clk_fepll *pll = to_clk_fepll(hw);
   1255	struct clk_hw *p_hw;
   1256	const struct freq_tbl *f;
   1257
   1258	f = qcom_find_freq(pll->freq_tbl, rate);
   1259	if (!f)
   1260		return -EINVAL;
   1261
   1262	p_hw = clk_hw_get_parent_by_index(hw, f->src);
   1263	*p_rate = clk_hw_get_rate(p_hw);
   1264
   1265	return f->freq;
   1266};
   1267
   1268/*
   1269 * Clock set rate function for APSS CPU PLL Clock divider.
   1270 * It looks up the frequency table and updates the PLL divider to corresponding
   1271 * divider value.
   1272 */
   1273static int clk_cpu_div_set_rate(struct clk_hw *hw, unsigned long rate,
   1274				unsigned long parent_rate)
   1275{
   1276	struct clk_fepll *pll = to_clk_fepll(hw);
   1277	const struct freq_tbl *f;
   1278	u32 mask;
   1279
   1280	f = qcom_find_freq(pll->freq_tbl, rate);
   1281	if (!f)
   1282		return -EINVAL;
   1283
   1284	mask = (BIT(pll->cdiv.width) - 1) << pll->cdiv.shift;
   1285	regmap_update_bits(pll->cdiv.clkr.regmap,
   1286			   pll->cdiv.reg, mask,
   1287			   f->pre_div << pll->cdiv.shift);
   1288	/*
   1289	 * There is no status bit which can be checked for successful CPU
   1290	 * divider update operation so using delay for the same.
   1291	 */
   1292	udelay(1);
   1293
   1294	return 0;
   1295};
   1296
   1297/*
   1298 * Clock frequency calculation function for APSS CPU PLL Clock divider.
   1299 * This clock divider is nonlinear so this function calculates the actual
   1300 * divider and returns the output frequency by dividing VCO Frequency
   1301 * with this actual divider value.
   1302 */
   1303static unsigned long
   1304clk_cpu_div_recalc_rate(struct clk_hw *hw,
   1305			unsigned long parent_rate)
   1306{
   1307	struct clk_fepll *pll = to_clk_fepll(hw);
   1308	u32 cdiv, pre_div;
   1309	u64 rate;
   1310
   1311	regmap_read(pll->cdiv.clkr.regmap, pll->cdiv.reg, &cdiv);
   1312	cdiv = (cdiv >> pll->cdiv.shift) & (BIT(pll->cdiv.width) - 1);
   1313
   1314	/*
   1315	 * Some dividers have value in 0.5 fraction so multiply both VCO
   1316	 * frequency(parent_rate) and pre_div with 2 to make integer
   1317	 * calculation.
   1318	 */
   1319	if (cdiv > 10)
   1320		pre_div = (cdiv + 1) * 2;
   1321	else
   1322		pre_div = cdiv + 12;
   1323
   1324	rate = clk_fepll_vco_calc_rate(pll, parent_rate) * 2;
   1325	do_div(rate, pre_div);
   1326
   1327	return rate;
   1328};
   1329
   1330static const struct clk_ops clk_regmap_cpu_div_ops = {
   1331	.round_rate = clk_cpu_div_round_rate,
   1332	.set_rate = clk_cpu_div_set_rate,
   1333	.recalc_rate = clk_cpu_div_recalc_rate,
   1334};
   1335
   1336static const struct freq_tbl ftbl_apss_ddr_pll[] = {
   1337	{ 384000000, P_XO, 0xd, 0, 0 },
   1338	{ 413000000, P_XO, 0xc, 0, 0 },
   1339	{ 448000000, P_XO, 0xb, 0, 0 },
   1340	{ 488000000, P_XO, 0xa, 0, 0 },
   1341	{ 512000000, P_XO, 0x9, 0, 0 },
   1342	{ 537000000, P_XO, 0x8, 0, 0 },
   1343	{ 565000000, P_XO, 0x7, 0, 0 },
   1344	{ 597000000, P_XO, 0x6, 0, 0 },
   1345	{ 632000000, P_XO, 0x5, 0, 0 },
   1346	{ 672000000, P_XO, 0x4, 0, 0 },
   1347	{ 716000000, P_XO, 0x3, 0, 0 },
   1348	{ 768000000, P_XO, 0x2, 0, 0 },
   1349	{ 823000000, P_XO, 0x1, 0, 0 },
   1350	{ 896000000, P_XO, 0x0, 0, 0 },
   1351	{ }
   1352};
   1353
   1354static struct clk_fepll gcc_apss_cpu_plldiv_clk = {
   1355	.cdiv.reg = 0x2e020,
   1356	.cdiv.shift = 4,
   1357	.cdiv.width = 4,
   1358	.cdiv.clkr = {
   1359		.enable_reg = 0x2e000,
   1360		.enable_mask = BIT(0),
   1361		.hw.init = &(struct clk_init_data){
   1362			.name = "ddrpllapss",
   1363			.parent_names = (const char *[]){
   1364				"xo",
   1365			},
   1366			.num_parents = 1,
   1367			.ops = &clk_regmap_cpu_div_ops,
   1368		},
   1369	},
   1370	.freq_tbl = ftbl_apss_ddr_pll,
   1371	.pll_vco = &gcc_apss_ddrpll_vco,
   1372};
   1373
   1374/* Calculates the rate for PLL divider.
   1375 * If the divider value is not fixed then it gets the actual divider value
   1376 * from divider table. Then, it calculate the clock rate by dividing the
   1377 * parent rate with actual divider value.
   1378 */
   1379static unsigned long
   1380clk_regmap_clk_div_recalc_rate(struct clk_hw *hw,
   1381			       unsigned long parent_rate)
   1382{
   1383	struct clk_fepll *pll = to_clk_fepll(hw);
   1384	u32 cdiv, pre_div = 1;
   1385	u64 rate;
   1386	const struct clk_div_table *clkt;
   1387
   1388	if (pll->fixed_div) {
   1389		pre_div = pll->fixed_div;
   1390	} else {
   1391		regmap_read(pll->cdiv.clkr.regmap, pll->cdiv.reg, &cdiv);
   1392		cdiv = (cdiv >> pll->cdiv.shift) & (BIT(pll->cdiv.width) - 1);
   1393
   1394		for (clkt = pll->div_table; clkt->div; clkt++) {
   1395			if (clkt->val == cdiv)
   1396				pre_div = clkt->div;
   1397		}
   1398	}
   1399
   1400	rate = clk_fepll_vco_calc_rate(pll, parent_rate);
   1401	do_div(rate, pre_div);
   1402
   1403	return rate;
   1404};
   1405
   1406static const struct clk_ops clk_fepll_div_ops = {
   1407	.recalc_rate = clk_regmap_clk_div_recalc_rate,
   1408};
   1409
   1410static struct clk_fepll gcc_apss_sdcc_clk = {
   1411	.fixed_div = 28,
   1412	.cdiv.clkr = {
   1413		.hw.init = &(struct clk_init_data){
   1414			.name = "ddrpllsdcc",
   1415			.parent_names = (const char *[]){
   1416				"xo",
   1417			},
   1418			.num_parents = 1,
   1419			.ops = &clk_fepll_div_ops,
   1420		},
   1421	},
   1422	.pll_vco = &gcc_apss_ddrpll_vco,
   1423};
   1424
   1425static struct clk_fepll gcc_fepll125_clk = {
   1426	.fixed_div = 32,
   1427	.cdiv.clkr = {
   1428		.hw.init = &(struct clk_init_data){
   1429			.name = "fepll125",
   1430			.parent_names = (const char *[]){
   1431				"xo",
   1432			},
   1433			.num_parents = 1,
   1434			.ops = &clk_fepll_div_ops,
   1435		},
   1436	},
   1437	.pll_vco = &gcc_fepll_vco,
   1438};
   1439
   1440static struct clk_fepll gcc_fepll125dly_clk = {
   1441	.fixed_div = 32,
   1442	.cdiv.clkr = {
   1443		.hw.init = &(struct clk_init_data){
   1444			.name = "fepll125dly",
   1445			.parent_names = (const char *[]){
   1446				"xo",
   1447			},
   1448			.num_parents = 1,
   1449			.ops = &clk_fepll_div_ops,
   1450		},
   1451	},
   1452	.pll_vco = &gcc_fepll_vco,
   1453};
   1454
   1455static struct clk_fepll gcc_fepll200_clk = {
   1456	.fixed_div = 20,
   1457	.cdiv.clkr = {
   1458		.hw.init = &(struct clk_init_data){
   1459			.name = "fepll200",
   1460			.parent_names = (const char *[]){
   1461				"xo",
   1462			},
   1463			.num_parents = 1,
   1464			.ops = &clk_fepll_div_ops,
   1465		},
   1466	},
   1467	.pll_vco = &gcc_fepll_vco,
   1468};
   1469
   1470static struct clk_fepll gcc_fepll500_clk = {
   1471	.fixed_div = 8,
   1472	.cdiv.clkr = {
   1473		.hw.init = &(struct clk_init_data){
   1474			.name = "fepll500",
   1475			.parent_names = (const char *[]){
   1476				"xo",
   1477			},
   1478			.num_parents = 1,
   1479			.ops = &clk_fepll_div_ops,
   1480		},
   1481	},
   1482	.pll_vco = &gcc_fepll_vco,
   1483};
   1484
   1485static const struct clk_div_table fepllwcss_clk_div_table[] = {
   1486	{ 0, 15 },
   1487	{ 1, 16 },
   1488	{ 2, 18 },
   1489	{ 3, 20 },
   1490	{ },
   1491};
   1492
   1493static struct clk_fepll gcc_fepllwcss2g_clk = {
   1494	.cdiv.reg = 0x2f020,
   1495	.cdiv.shift = 8,
   1496	.cdiv.width = 2,
   1497	.cdiv.clkr = {
   1498		.hw.init = &(struct clk_init_data){
   1499			.name = "fepllwcss2g",
   1500			.parent_names = (const char *[]){
   1501				"xo",
   1502			},
   1503			.num_parents = 1,
   1504			.ops = &clk_fepll_div_ops,
   1505		},
   1506	},
   1507	.div_table = fepllwcss_clk_div_table,
   1508	.pll_vco = &gcc_fepll_vco,
   1509};
   1510
   1511static struct clk_fepll gcc_fepllwcss5g_clk = {
   1512	.cdiv.reg = 0x2f020,
   1513	.cdiv.shift = 12,
   1514	.cdiv.width = 2,
   1515	.cdiv.clkr = {
   1516		.hw.init = &(struct clk_init_data){
   1517			.name = "fepllwcss5g",
   1518			.parent_names = (const char *[]){
   1519				"xo",
   1520			},
   1521			.num_parents = 1,
   1522			.ops = &clk_fepll_div_ops,
   1523		},
   1524	},
   1525	.div_table = fepllwcss_clk_div_table,
   1526	.pll_vco = &gcc_fepll_vco,
   1527};
   1528
   1529static const struct freq_tbl ftbl_gcc_pcnoc_ahb_clk[] = {
   1530	F(48000000,  P_XO,	 1, 0, 0),
   1531	F(100000000, P_FEPLL200, 2, 0, 0),
   1532	{ }
   1533};
   1534
   1535static struct clk_rcg2 gcc_pcnoc_ahb_clk_src = {
   1536	.cmd_rcgr = 0x21024,
   1537	.hid_width = 5,
   1538	.parent_map = gcc_xo_200_500_map,
   1539	.freq_tbl = ftbl_gcc_pcnoc_ahb_clk,
   1540	.clkr.hw.init = &(struct clk_init_data){
   1541		.name = "gcc_pcnoc_ahb_clk_src",
   1542		.parent_names = gcc_xo_200_500,
   1543		.num_parents = 3,
   1544		.ops = &clk_rcg2_ops,
   1545	},
   1546};
   1547
   1548static struct clk_branch pcnoc_clk_src = {
   1549	.halt_reg = 0x21030,
   1550	.clkr = {
   1551		.enable_reg = 0x21030,
   1552		.enable_mask = BIT(0),
   1553		.hw.init = &(struct clk_init_data){
   1554			.name = "pcnoc_clk_src",
   1555			.parent_names = (const char *[]){
   1556				"gcc_pcnoc_ahb_clk_src",
   1557			},
   1558			.num_parents = 1,
   1559			.ops = &clk_branch2_ops,
   1560			.flags = CLK_SET_RATE_PARENT |
   1561				CLK_IS_CRITICAL,
   1562		},
   1563	},
   1564};
   1565
   1566static struct clk_regmap *gcc_ipq4019_clocks[] = {
   1567	[AUDIO_CLK_SRC] = &audio_clk_src.clkr,
   1568	[BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr,
   1569	[BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr,
   1570	[BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr,
   1571	[BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr,
   1572	[BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr,
   1573	[BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr,
   1574	[GCC_USB3_MOCK_UTMI_CLK_SRC] = &usb30_mock_utmi_clk_src.clkr,
   1575	[GCC_APPS_CLK_SRC] = &apps_clk_src.clkr,
   1576	[GCC_APPS_AHB_CLK_SRC] = &apps_ahb_clk_src.clkr,
   1577	[GP1_CLK_SRC] = &gp1_clk_src.clkr,
   1578	[GP2_CLK_SRC] = &gp2_clk_src.clkr,
   1579	[GP3_CLK_SRC] = &gp3_clk_src.clkr,
   1580	[SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr,
   1581	[FEPHY_125M_DLY_CLK_SRC] = &fephy_125m_dly_clk_src.clkr,
   1582	[WCSS2G_CLK_SRC] = &wcss2g_clk_src.clkr,
   1583	[WCSS5G_CLK_SRC] = &wcss5g_clk_src.clkr,
   1584	[GCC_APSS_AHB_CLK] = &gcc_apss_ahb_clk.clkr,
   1585	[GCC_AUDIO_AHB_CLK] = &gcc_audio_ahb_clk.clkr,
   1586	[GCC_AUDIO_PWM_CLK] = &gcc_audio_pwm_clk.clkr,
   1587	[GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr,
   1588	[GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr,
   1589	[GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr,
   1590	[GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr,
   1591	[GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr,
   1592	[GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr,
   1593	[GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr,
   1594	[GCC_DCD_XO_CLK] = &gcc_dcd_xo_clk.clkr,
   1595	[GCC_GP1_CLK] = &gcc_gp1_clk.clkr,
   1596	[GCC_GP2_CLK] = &gcc_gp2_clk.clkr,
   1597	[GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
   1598	[GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
   1599	[GCC_CRYPTO_AHB_CLK] = &gcc_crypto_ahb_clk.clkr,
   1600	[GCC_CRYPTO_AXI_CLK] = &gcc_crypto_axi_clk.clkr,
   1601	[GCC_CRYPTO_CLK] = &gcc_crypto_clk.clkr,
   1602	[GCC_ESS_CLK] = &gcc_ess_clk.clkr,
   1603	[GCC_IMEM_AXI_CLK] = &gcc_imem_axi_clk.clkr,
   1604	[GCC_IMEM_CFG_AHB_CLK] = &gcc_imem_cfg_ahb_clk.clkr,
   1605	[GCC_PCIE_AHB_CLK] = &gcc_pcie_ahb_clk.clkr,
   1606	[GCC_PCIE_AXI_M_CLK] = &gcc_pcie_axi_m_clk.clkr,
   1607	[GCC_PCIE_AXI_S_CLK] = &gcc_pcie_axi_s_clk.clkr,
   1608	[GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr,
   1609	[GCC_QPIC_AHB_CLK] = &gcc_qpic_ahb_clk.clkr,
   1610	[GCC_QPIC_CLK] = &gcc_qpic_clk.clkr,
   1611	[GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr,
   1612	[GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr,
   1613	[GCC_TLMM_AHB_CLK] = &gcc_tlmm_ahb_clk.clkr,
   1614	[GCC_USB2_MASTER_CLK] = &gcc_usb2_master_clk.clkr,
   1615	[GCC_USB2_SLEEP_CLK] = &gcc_usb2_sleep_clk.clkr,
   1616	[GCC_USB2_MOCK_UTMI_CLK] = &gcc_usb2_mock_utmi_clk.clkr,
   1617	[GCC_USB3_MASTER_CLK] = &gcc_usb3_master_clk.clkr,
   1618	[GCC_USB3_SLEEP_CLK] = &gcc_usb3_sleep_clk.clkr,
   1619	[GCC_USB3_MOCK_UTMI_CLK] = &gcc_usb3_mock_utmi_clk.clkr,
   1620	[GCC_WCSS2G_CLK] = &gcc_wcss2g_clk.clkr,
   1621	[GCC_WCSS2G_REF_CLK] = &gcc_wcss2g_ref_clk.clkr,
   1622	[GCC_WCSS2G_RTC_CLK] = &gcc_wcss2g_rtc_clk.clkr,
   1623	[GCC_WCSS5G_CLK] = &gcc_wcss5g_clk.clkr,
   1624	[GCC_WCSS5G_REF_CLK] = &gcc_wcss5g_ref_clk.clkr,
   1625	[GCC_WCSS5G_RTC_CLK] = &gcc_wcss5g_rtc_clk.clkr,
   1626	[GCC_SDCC_PLLDIV_CLK] = &gcc_apss_sdcc_clk.cdiv.clkr,
   1627	[GCC_FEPLL125_CLK] = &gcc_fepll125_clk.cdiv.clkr,
   1628	[GCC_FEPLL125DLY_CLK] = &gcc_fepll125dly_clk.cdiv.clkr,
   1629	[GCC_FEPLL200_CLK] = &gcc_fepll200_clk.cdiv.clkr,
   1630	[GCC_FEPLL500_CLK] = &gcc_fepll500_clk.cdiv.clkr,
   1631	[GCC_FEPLL_WCSS2G_CLK] = &gcc_fepllwcss2g_clk.cdiv.clkr,
   1632	[GCC_FEPLL_WCSS5G_CLK] = &gcc_fepllwcss5g_clk.cdiv.clkr,
   1633	[GCC_APSS_CPU_PLLDIV_CLK] = &gcc_apss_cpu_plldiv_clk.cdiv.clkr,
   1634	[GCC_PCNOC_AHB_CLK_SRC] = &gcc_pcnoc_ahb_clk_src.clkr,
   1635	[GCC_PCNOC_AHB_CLK] = &pcnoc_clk_src.clkr,
   1636};
   1637
   1638static const struct qcom_reset_map gcc_ipq4019_resets[] = {
   1639	[WIFI0_CPU_INIT_RESET] = { 0x1f008, 5 },
   1640	[WIFI0_RADIO_SRIF_RESET] = { 0x1f008, 4 },
   1641	[WIFI0_RADIO_WARM_RESET] = { 0x1f008, 3 },
   1642	[WIFI0_RADIO_COLD_RESET] = { 0x1f008, 2 },
   1643	[WIFI0_CORE_WARM_RESET] = { 0x1f008, 1 },
   1644	[WIFI0_CORE_COLD_RESET] = { 0x1f008, 0 },
   1645	[WIFI1_CPU_INIT_RESET] = { 0x20008, 5 },
   1646	[WIFI1_RADIO_SRIF_RESET] = { 0x20008, 4 },
   1647	[WIFI1_RADIO_WARM_RESET] = { 0x20008, 3 },
   1648	[WIFI1_RADIO_COLD_RESET] = { 0x20008, 2 },
   1649	[WIFI1_CORE_WARM_RESET] = { 0x20008, 1 },
   1650	[WIFI1_CORE_COLD_RESET] = { 0x20008, 0 },
   1651	[USB3_UNIPHY_PHY_ARES] = { 0x1e038, 5 },
   1652	[USB3_HSPHY_POR_ARES] = { 0x1e038, 4 },
   1653	[USB3_HSPHY_S_ARES] = { 0x1e038, 2 },
   1654	[USB2_HSPHY_POR_ARES] = { 0x1e01c, 4 },
   1655	[USB2_HSPHY_S_ARES] = { 0x1e01c, 2 },
   1656	[PCIE_PHY_AHB_ARES] = { 0x1d010, 11 },
   1657	[PCIE_AHB_ARES] = { 0x1d010, 10 },
   1658	[PCIE_PWR_ARES] = { 0x1d010, 9 },
   1659	[PCIE_PIPE_STICKY_ARES] = { 0x1d010, 8 },
   1660	[PCIE_AXI_M_STICKY_ARES] = { 0x1d010, 7 },
   1661	[PCIE_PHY_ARES] = { 0x1d010, 6 },
   1662	[PCIE_PARF_XPU_ARES] = { 0x1d010, 5 },
   1663	[PCIE_AXI_S_XPU_ARES] = { 0x1d010, 4 },
   1664	[PCIE_AXI_M_VMIDMT_ARES] = { 0x1d010, 3 },
   1665	[PCIE_PIPE_ARES] = { 0x1d010, 2 },
   1666	[PCIE_AXI_S_ARES] = { 0x1d010, 1 },
   1667	[PCIE_AXI_M_ARES] = { 0x1d010, 0 },
   1668	[ESS_RESET] = { 0x12008, 0},
   1669	[GCC_BLSP1_BCR] = {0x01000, 0},
   1670	[GCC_BLSP1_QUP1_BCR] = {0x02000, 0},
   1671	[GCC_BLSP1_UART1_BCR] = {0x02038, 0},
   1672	[GCC_BLSP1_QUP2_BCR] = {0x03008, 0},
   1673	[GCC_BLSP1_UART2_BCR] = {0x03028, 0},
   1674	[GCC_BIMC_BCR] = {0x04000, 0},
   1675	[GCC_TLMM_BCR] = {0x05000, 0},
   1676	[GCC_IMEM_BCR] = {0x0E000, 0},
   1677	[GCC_ESS_BCR] = {0x12008, 0},
   1678	[GCC_PRNG_BCR] = {0x13000, 0},
   1679	[GCC_BOOT_ROM_BCR] = {0x13008, 0},
   1680	[GCC_CRYPTO_BCR] = {0x16000, 0},
   1681	[GCC_SDCC1_BCR] = {0x18000, 0},
   1682	[GCC_SEC_CTRL_BCR] = {0x1A000, 0},
   1683	[GCC_AUDIO_BCR] = {0x1B008, 0},
   1684	[GCC_QPIC_BCR] = {0x1C000, 0},
   1685	[GCC_PCIE_BCR] = {0x1D000, 0},
   1686	[GCC_USB2_BCR] = {0x1E008, 0},
   1687	[GCC_USB2_PHY_BCR] = {0x1E018, 0},
   1688	[GCC_USB3_BCR] = {0x1E024, 0},
   1689	[GCC_USB3_PHY_BCR] = {0x1E034, 0},
   1690	[GCC_SYSTEM_NOC_BCR] = {0x21000, 0},
   1691	[GCC_PCNOC_BCR] = {0x2102C, 0},
   1692	[GCC_DCD_BCR] = {0x21038, 0},
   1693	[GCC_SNOC_BUS_TIMEOUT0_BCR] = {0x21064, 0},
   1694	[GCC_SNOC_BUS_TIMEOUT1_BCR] = {0x2106C, 0},
   1695	[GCC_SNOC_BUS_TIMEOUT2_BCR] = {0x21074, 0},
   1696	[GCC_SNOC_BUS_TIMEOUT3_BCR] = {0x2107C, 0},
   1697	[GCC_PCNOC_BUS_TIMEOUT0_BCR] = {0x21084, 0},
   1698	[GCC_PCNOC_BUS_TIMEOUT1_BCR] = {0x2108C, 0},
   1699	[GCC_PCNOC_BUS_TIMEOUT2_BCR] = {0x21094, 0},
   1700	[GCC_PCNOC_BUS_TIMEOUT3_BCR] = {0x2109C, 0},
   1701	[GCC_PCNOC_BUS_TIMEOUT4_BCR] = {0x210A4, 0},
   1702	[GCC_PCNOC_BUS_TIMEOUT5_BCR] = {0x210AC, 0},
   1703	[GCC_PCNOC_BUS_TIMEOUT6_BCR] = {0x210B4, 0},
   1704	[GCC_PCNOC_BUS_TIMEOUT7_BCR] = {0x210BC, 0},
   1705	[GCC_PCNOC_BUS_TIMEOUT8_BCR] = {0x210C4, 0},
   1706	[GCC_PCNOC_BUS_TIMEOUT9_BCR] = {0x210CC, 0},
   1707	[GCC_TCSR_BCR] = {0x22000, 0},
   1708	[GCC_MPM_BCR] = {0x24000, 0},
   1709	[GCC_SPDM_BCR] = {0x25000, 0},
   1710};
   1711
   1712static const struct regmap_config gcc_ipq4019_regmap_config = {
   1713	.reg_bits	= 32,
   1714	.reg_stride	= 4,
   1715	.val_bits	= 32,
   1716	.max_register	= 0x2ffff,
   1717	.fast_io	= true,
   1718};
   1719
   1720static const struct qcom_cc_desc gcc_ipq4019_desc = {
   1721	.config = &gcc_ipq4019_regmap_config,
   1722	.clks = gcc_ipq4019_clocks,
   1723	.num_clks = ARRAY_SIZE(gcc_ipq4019_clocks),
   1724	.resets = gcc_ipq4019_resets,
   1725	.num_resets = ARRAY_SIZE(gcc_ipq4019_resets),
   1726};
   1727
   1728static const struct of_device_id gcc_ipq4019_match_table[] = {
   1729	{ .compatible = "qcom,gcc-ipq4019" },
   1730	{ }
   1731};
   1732MODULE_DEVICE_TABLE(of, gcc_ipq4019_match_table);
   1733
   1734static int
   1735gcc_ipq4019_cpu_clk_notifier_fn(struct notifier_block *nb,
   1736				unsigned long action, void *data)
   1737{
   1738	int err = 0;
   1739
   1740	if (action == PRE_RATE_CHANGE)
   1741		err = clk_rcg2_ops.set_parent(&apps_clk_src.clkr.hw,
   1742					      gcc_ipq4019_cpu_safe_parent);
   1743
   1744	return notifier_from_errno(err);
   1745}
   1746
   1747static struct notifier_block gcc_ipq4019_cpu_clk_notifier = {
   1748	.notifier_call = gcc_ipq4019_cpu_clk_notifier_fn,
   1749};
   1750
   1751static int gcc_ipq4019_probe(struct platform_device *pdev)
   1752{
   1753	int err;
   1754
   1755	err = qcom_cc_probe(pdev, &gcc_ipq4019_desc);
   1756	if (err)
   1757		return err;
   1758
   1759	return clk_notifier_register(apps_clk_src.clkr.hw.clk,
   1760				     &gcc_ipq4019_cpu_clk_notifier);
   1761}
   1762
   1763static int gcc_ipq4019_remove(struct platform_device *pdev)
   1764{
   1765	return clk_notifier_unregister(apps_clk_src.clkr.hw.clk,
   1766				       &gcc_ipq4019_cpu_clk_notifier);
   1767}
   1768
   1769static struct platform_driver gcc_ipq4019_driver = {
   1770	.probe		= gcc_ipq4019_probe,
   1771	.remove		= gcc_ipq4019_remove,
   1772	.driver		= {
   1773		.name	= "qcom,gcc-ipq4019",
   1774		.of_match_table = gcc_ipq4019_match_table,
   1775	},
   1776};
   1777
   1778static int __init gcc_ipq4019_init(void)
   1779{
   1780	return platform_driver_register(&gcc_ipq4019_driver);
   1781}
   1782core_initcall(gcc_ipq4019_init);
   1783
   1784static void __exit gcc_ipq4019_exit(void)
   1785{
   1786	platform_driver_unregister(&gcc_ipq4019_driver);
   1787}
   1788module_exit(gcc_ipq4019_exit);
   1789
   1790MODULE_ALIAS("platform:gcc-ipq4019");
   1791MODULE_LICENSE("GPL v2");
   1792MODULE_DESCRIPTION("QCOM GCC IPQ4019 driver");