162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (c) 2020 Arm Ltd.
462306a36Sopenharmony_ci * Based on the H6 CCU driver, which is:
562306a36Sopenharmony_ci *   Copyright (c) 2017 Icenowy Zheng <icenowy@aosc.io>
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <linux/clk-provider.h>
962306a36Sopenharmony_ci#include <linux/io.h>
1062306a36Sopenharmony_ci#include <linux/module.h>
1162306a36Sopenharmony_ci#include <linux/platform_device.h>
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include "ccu_common.h"
1462306a36Sopenharmony_ci#include "ccu_reset.h"
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#include "ccu_div.h"
1762306a36Sopenharmony_ci#include "ccu_gate.h"
1862306a36Sopenharmony_ci#include "ccu_mp.h"
1962306a36Sopenharmony_ci#include "ccu_mult.h"
2062306a36Sopenharmony_ci#include "ccu_nk.h"
2162306a36Sopenharmony_ci#include "ccu_nkm.h"
2262306a36Sopenharmony_ci#include "ccu_nkmp.h"
2362306a36Sopenharmony_ci#include "ccu_nm.h"
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci#include "ccu-sun50i-h616.h"
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci/*
2862306a36Sopenharmony_ci * The CPU PLL is actually NP clock, with P being /1, /2 or /4. However
2962306a36Sopenharmony_ci * P should only be used for output frequencies lower than 288 MHz.
3062306a36Sopenharmony_ci *
3162306a36Sopenharmony_ci * For now we can just model it as a multiplier clock, and force P to /1.
3262306a36Sopenharmony_ci *
3362306a36Sopenharmony_ci * The M factor is present in the register's description, but not in the
3462306a36Sopenharmony_ci * frequency formula, and it's documented as "M is only used for backdoor
3562306a36Sopenharmony_ci * testing", so it's not modelled and then force to 0.
3662306a36Sopenharmony_ci */
3762306a36Sopenharmony_ci#define SUN50I_H616_PLL_CPUX_REG	0x000
3862306a36Sopenharmony_cistatic struct ccu_mult pll_cpux_clk = {
3962306a36Sopenharmony_ci	.enable		= BIT(31),
4062306a36Sopenharmony_ci	.lock		= BIT(28),
4162306a36Sopenharmony_ci	.mult		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
4262306a36Sopenharmony_ci	.common		= {
4362306a36Sopenharmony_ci		.reg		= 0x000,
4462306a36Sopenharmony_ci		.hw.init	= CLK_HW_INIT("pll-cpux", "osc24M",
4562306a36Sopenharmony_ci					      &ccu_mult_ops,
4662306a36Sopenharmony_ci					      CLK_SET_RATE_UNGATE),
4762306a36Sopenharmony_ci	},
4862306a36Sopenharmony_ci};
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci/* Some PLLs are input * N / div1 / P. Model them as NKMP with no K */
5162306a36Sopenharmony_ci#define SUN50I_H616_PLL_DDR0_REG	0x010
5262306a36Sopenharmony_cistatic struct ccu_nkmp pll_ddr0_clk = {
5362306a36Sopenharmony_ci	.enable		= BIT(31),
5462306a36Sopenharmony_ci	.lock		= BIT(28),
5562306a36Sopenharmony_ci	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
5662306a36Sopenharmony_ci	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
5762306a36Sopenharmony_ci	.p		= _SUNXI_CCU_DIV(0, 1), /* output divider */
5862306a36Sopenharmony_ci	.common		= {
5962306a36Sopenharmony_ci		.reg		= 0x010,
6062306a36Sopenharmony_ci		.hw.init	= CLK_HW_INIT("pll-ddr0", "osc24M",
6162306a36Sopenharmony_ci					      &ccu_nkmp_ops,
6262306a36Sopenharmony_ci					      CLK_SET_RATE_UNGATE),
6362306a36Sopenharmony_ci	},
6462306a36Sopenharmony_ci};
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci#define SUN50I_H616_PLL_DDR1_REG	0x018
6762306a36Sopenharmony_cistatic struct ccu_nkmp pll_ddr1_clk = {
6862306a36Sopenharmony_ci	.enable		= BIT(31),
6962306a36Sopenharmony_ci	.lock		= BIT(28),
7062306a36Sopenharmony_ci	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
7162306a36Sopenharmony_ci	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
7262306a36Sopenharmony_ci	.p		= _SUNXI_CCU_DIV(0, 1), /* output divider */
7362306a36Sopenharmony_ci	.common		= {
7462306a36Sopenharmony_ci		.reg		= 0x018,
7562306a36Sopenharmony_ci		.hw.init	= CLK_HW_INIT("pll-ddr1", "osc24M",
7662306a36Sopenharmony_ci					      &ccu_nkmp_ops,
7762306a36Sopenharmony_ci					      CLK_SET_RATE_UNGATE),
7862306a36Sopenharmony_ci	},
7962306a36Sopenharmony_ci};
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci#define SUN50I_H616_PLL_PERIPH0_REG	0x020
8262306a36Sopenharmony_cistatic struct ccu_nkmp pll_periph0_clk = {
8362306a36Sopenharmony_ci	.enable		= BIT(31),
8462306a36Sopenharmony_ci	.lock		= BIT(28),
8562306a36Sopenharmony_ci	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
8662306a36Sopenharmony_ci	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
8762306a36Sopenharmony_ci	.p		= _SUNXI_CCU_DIV(0, 1), /* output divider */
8862306a36Sopenharmony_ci	.fixed_post_div	= 2,
8962306a36Sopenharmony_ci	.common		= {
9062306a36Sopenharmony_ci		.reg		= 0x020,
9162306a36Sopenharmony_ci		.features	= CCU_FEATURE_FIXED_POSTDIV,
9262306a36Sopenharmony_ci		.hw.init	= CLK_HW_INIT("pll-periph0", "osc24M",
9362306a36Sopenharmony_ci					      &ccu_nkmp_ops,
9462306a36Sopenharmony_ci					      CLK_SET_RATE_UNGATE),
9562306a36Sopenharmony_ci	},
9662306a36Sopenharmony_ci};
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci#define SUN50I_H616_PLL_PERIPH1_REG	0x028
9962306a36Sopenharmony_cistatic struct ccu_nkmp pll_periph1_clk = {
10062306a36Sopenharmony_ci	.enable		= BIT(31),
10162306a36Sopenharmony_ci	.lock		= BIT(28),
10262306a36Sopenharmony_ci	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
10362306a36Sopenharmony_ci	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
10462306a36Sopenharmony_ci	.p		= _SUNXI_CCU_DIV(0, 1), /* output divider */
10562306a36Sopenharmony_ci	.fixed_post_div	= 2,
10662306a36Sopenharmony_ci	.common		= {
10762306a36Sopenharmony_ci		.reg		= 0x028,
10862306a36Sopenharmony_ci		.features	= CCU_FEATURE_FIXED_POSTDIV,
10962306a36Sopenharmony_ci		.hw.init	= CLK_HW_INIT("pll-periph1", "osc24M",
11062306a36Sopenharmony_ci					      &ccu_nkmp_ops,
11162306a36Sopenharmony_ci					      CLK_SET_RATE_UNGATE),
11262306a36Sopenharmony_ci	},
11362306a36Sopenharmony_ci};
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci#define SUN50I_H616_PLL_GPU_REG		0x030
11662306a36Sopenharmony_cistatic struct ccu_nkmp pll_gpu_clk = {
11762306a36Sopenharmony_ci	.enable		= BIT(31),
11862306a36Sopenharmony_ci	.lock		= BIT(28),
11962306a36Sopenharmony_ci	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
12062306a36Sopenharmony_ci	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
12162306a36Sopenharmony_ci	.p		= _SUNXI_CCU_DIV(0, 1), /* output divider */
12262306a36Sopenharmony_ci	.common		= {
12362306a36Sopenharmony_ci		.reg		= 0x030,
12462306a36Sopenharmony_ci		.hw.init	= CLK_HW_INIT("pll-gpu", "osc24M",
12562306a36Sopenharmony_ci					      &ccu_nkmp_ops,
12662306a36Sopenharmony_ci					      CLK_SET_RATE_UNGATE),
12762306a36Sopenharmony_ci	},
12862306a36Sopenharmony_ci};
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci/*
13162306a36Sopenharmony_ci * For Video PLLs, the output divider is described as "used for testing"
13262306a36Sopenharmony_ci * in the user manual. So it's not modelled and forced to 0.
13362306a36Sopenharmony_ci */
13462306a36Sopenharmony_ci#define SUN50I_H616_PLL_VIDEO0_REG	0x040
13562306a36Sopenharmony_cistatic struct ccu_nm pll_video0_clk = {
13662306a36Sopenharmony_ci	.enable		= BIT(31),
13762306a36Sopenharmony_ci	.lock		= BIT(28),
13862306a36Sopenharmony_ci	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
13962306a36Sopenharmony_ci	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
14062306a36Sopenharmony_ci	.fixed_post_div	= 4,
14162306a36Sopenharmony_ci	.min_rate	= 288000000,
14262306a36Sopenharmony_ci	.max_rate	= 2400000000UL,
14362306a36Sopenharmony_ci	.common		= {
14462306a36Sopenharmony_ci		.reg		= 0x040,
14562306a36Sopenharmony_ci		.features	= CCU_FEATURE_FIXED_POSTDIV,
14662306a36Sopenharmony_ci		.hw.init	= CLK_HW_INIT("pll-video0", "osc24M",
14762306a36Sopenharmony_ci					      &ccu_nm_ops,
14862306a36Sopenharmony_ci					      CLK_SET_RATE_UNGATE),
14962306a36Sopenharmony_ci	},
15062306a36Sopenharmony_ci};
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ci#define SUN50I_H616_PLL_VIDEO1_REG	0x048
15362306a36Sopenharmony_cistatic struct ccu_nm pll_video1_clk = {
15462306a36Sopenharmony_ci	.enable		= BIT(31),
15562306a36Sopenharmony_ci	.lock		= BIT(28),
15662306a36Sopenharmony_ci	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
15762306a36Sopenharmony_ci	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
15862306a36Sopenharmony_ci	.fixed_post_div	= 4,
15962306a36Sopenharmony_ci	.min_rate	= 288000000,
16062306a36Sopenharmony_ci	.max_rate	= 2400000000UL,
16162306a36Sopenharmony_ci	.common		= {
16262306a36Sopenharmony_ci		.reg		= 0x048,
16362306a36Sopenharmony_ci		.features	= CCU_FEATURE_FIXED_POSTDIV,
16462306a36Sopenharmony_ci		.hw.init	= CLK_HW_INIT("pll-video1", "osc24M",
16562306a36Sopenharmony_ci					      &ccu_nm_ops,
16662306a36Sopenharmony_ci					      CLK_SET_RATE_UNGATE),
16762306a36Sopenharmony_ci	},
16862306a36Sopenharmony_ci};
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci#define SUN50I_H616_PLL_VIDEO2_REG	0x050
17162306a36Sopenharmony_cistatic struct ccu_nm pll_video2_clk = {
17262306a36Sopenharmony_ci	.enable		= BIT(31),
17362306a36Sopenharmony_ci	.lock		= BIT(28),
17462306a36Sopenharmony_ci	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
17562306a36Sopenharmony_ci	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
17662306a36Sopenharmony_ci	.fixed_post_div	= 4,
17762306a36Sopenharmony_ci	.min_rate	= 288000000,
17862306a36Sopenharmony_ci	.max_rate	= 2400000000UL,
17962306a36Sopenharmony_ci	.common		= {
18062306a36Sopenharmony_ci		.reg		= 0x050,
18162306a36Sopenharmony_ci		.features	= CCU_FEATURE_FIXED_POSTDIV,
18262306a36Sopenharmony_ci		.hw.init	= CLK_HW_INIT("pll-video2", "osc24M",
18362306a36Sopenharmony_ci					      &ccu_nm_ops,
18462306a36Sopenharmony_ci					      CLK_SET_RATE_UNGATE),
18562306a36Sopenharmony_ci	},
18662306a36Sopenharmony_ci};
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci#define SUN50I_H616_PLL_VE_REG		0x058
18962306a36Sopenharmony_cistatic struct ccu_nkmp pll_ve_clk = {
19062306a36Sopenharmony_ci	.enable		= BIT(31),
19162306a36Sopenharmony_ci	.lock		= BIT(28),
19262306a36Sopenharmony_ci	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
19362306a36Sopenharmony_ci	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
19462306a36Sopenharmony_ci	.p		= _SUNXI_CCU_DIV(0, 1), /* output divider */
19562306a36Sopenharmony_ci	.common		= {
19662306a36Sopenharmony_ci		.reg		= 0x058,
19762306a36Sopenharmony_ci		.hw.init	= CLK_HW_INIT("pll-ve", "osc24M",
19862306a36Sopenharmony_ci					      &ccu_nkmp_ops,
19962306a36Sopenharmony_ci					      CLK_SET_RATE_UNGATE),
20062306a36Sopenharmony_ci	},
20162306a36Sopenharmony_ci};
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ci#define SUN50I_H616_PLL_DE_REG		0x060
20462306a36Sopenharmony_cistatic struct ccu_nkmp pll_de_clk = {
20562306a36Sopenharmony_ci	.enable		= BIT(31),
20662306a36Sopenharmony_ci	.lock		= BIT(28),
20762306a36Sopenharmony_ci	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
20862306a36Sopenharmony_ci	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
20962306a36Sopenharmony_ci	.p		= _SUNXI_CCU_DIV(0, 1), /* output divider */
21062306a36Sopenharmony_ci	.common		= {
21162306a36Sopenharmony_ci		.reg		= 0x060,
21262306a36Sopenharmony_ci		.hw.init	= CLK_HW_INIT("pll-de", "osc24M",
21362306a36Sopenharmony_ci					      &ccu_nkmp_ops,
21462306a36Sopenharmony_ci					      CLK_SET_RATE_UNGATE),
21562306a36Sopenharmony_ci	},
21662306a36Sopenharmony_ci};
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci/*
21962306a36Sopenharmony_ci * TODO: Determine SDM settings for the audio PLL. The manual suggests
22062306a36Sopenharmony_ci * PLL_FACTOR_N=16, PLL_POST_DIV_P=2, OUTPUT_DIV=2, pattern=0xe000c49b
22162306a36Sopenharmony_ci * for 24.576 MHz, and PLL_FACTOR_N=22, PLL_POST_DIV_P=3, OUTPUT_DIV=2,
22262306a36Sopenharmony_ci * pattern=0xe001288c for 22.5792 MHz.
22362306a36Sopenharmony_ci * This clashes with our fixed PLL_POST_DIV_P.
22462306a36Sopenharmony_ci */
22562306a36Sopenharmony_ci#define SUN50I_H616_PLL_AUDIO_REG	0x078
22662306a36Sopenharmony_cistatic struct ccu_nm pll_audio_hs_clk = {
22762306a36Sopenharmony_ci	.enable		= BIT(31),
22862306a36Sopenharmony_ci	.lock		= BIT(28),
22962306a36Sopenharmony_ci	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
23062306a36Sopenharmony_ci	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
23162306a36Sopenharmony_ci	.common		= {
23262306a36Sopenharmony_ci		.reg		= 0x078,
23362306a36Sopenharmony_ci		.hw.init	= CLK_HW_INIT("pll-audio-hs", "osc24M",
23462306a36Sopenharmony_ci					      &ccu_nm_ops,
23562306a36Sopenharmony_ci					      CLK_SET_RATE_UNGATE),
23662306a36Sopenharmony_ci	},
23762306a36Sopenharmony_ci};
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_cistatic const char * const cpux_parents[] = { "osc24M", "osc32k",
24062306a36Sopenharmony_ci					"iosc", "pll-cpux", "pll-periph0" };
24162306a36Sopenharmony_cistatic SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents,
24262306a36Sopenharmony_ci		     0x500, 24, 3, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
24362306a36Sopenharmony_cistatic SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x500, 0, 2, 0);
24462306a36Sopenharmony_cistatic SUNXI_CCU_M(cpux_apb_clk, "cpux-apb", "cpux", 0x500, 8, 2, 0);
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_cistatic const char * const psi_ahb1_ahb2_parents[] = { "osc24M", "osc32k",
24762306a36Sopenharmony_ci						      "iosc", "pll-periph0" };
24862306a36Sopenharmony_cistatic SUNXI_CCU_MP_WITH_MUX(psi_ahb1_ahb2_clk, "psi-ahb1-ahb2",
24962306a36Sopenharmony_ci			     psi_ahb1_ahb2_parents,
25062306a36Sopenharmony_ci			     0x510,
25162306a36Sopenharmony_ci			     0, 2,	/* M */
25262306a36Sopenharmony_ci			     8, 2,	/* P */
25362306a36Sopenharmony_ci			     24, 2,	/* mux */
25462306a36Sopenharmony_ci			     0);
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_cistatic const char * const ahb3_apb1_apb2_parents[] = { "osc24M", "osc32k",
25762306a36Sopenharmony_ci						       "psi-ahb1-ahb2",
25862306a36Sopenharmony_ci						       "pll-periph0" };
25962306a36Sopenharmony_cistatic SUNXI_CCU_MP_WITH_MUX(ahb3_clk, "ahb3", ahb3_apb1_apb2_parents, 0x51c,
26062306a36Sopenharmony_ci			     0, 2,	/* M */
26162306a36Sopenharmony_ci			     8, 2,	/* P */
26262306a36Sopenharmony_ci			     24, 2,	/* mux */
26362306a36Sopenharmony_ci			     0);
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_cistatic SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", ahb3_apb1_apb2_parents, 0x520,
26662306a36Sopenharmony_ci			     0, 2,	/* M */
26762306a36Sopenharmony_ci			     8, 2,	/* P */
26862306a36Sopenharmony_ci			     24, 2,	/* mux */
26962306a36Sopenharmony_ci			     0);
27062306a36Sopenharmony_ci
27162306a36Sopenharmony_cistatic SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", ahb3_apb1_apb2_parents, 0x524,
27262306a36Sopenharmony_ci			     0, 2,	/* M */
27362306a36Sopenharmony_ci			     8, 2,	/* P */
27462306a36Sopenharmony_ci			     24, 2,	/* mux */
27562306a36Sopenharmony_ci			     0);
27662306a36Sopenharmony_ci
27762306a36Sopenharmony_cistatic const char * const mbus_parents[] = { "osc24M", "pll-periph0-2x",
27862306a36Sopenharmony_ci					     "pll-ddr0", "pll-ddr1" };
27962306a36Sopenharmony_cistatic SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents, 0x540,
28062306a36Sopenharmony_ci					0, 3,	/* M */
28162306a36Sopenharmony_ci					24, 2,	/* mux */
28262306a36Sopenharmony_ci					BIT(31),	/* gate */
28362306a36Sopenharmony_ci					CLK_IS_CRITICAL);
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_cistatic const char * const de_parents[] = { "pll-de", "pll-periph0-2x" };
28662306a36Sopenharmony_cistatic SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents, 0x600,
28762306a36Sopenharmony_ci				       0, 4,	/* M */
28862306a36Sopenharmony_ci				       24, 1,	/* mux */
28962306a36Sopenharmony_ci				       BIT(31),	/* gate */
29062306a36Sopenharmony_ci				       CLK_SET_RATE_PARENT);
29162306a36Sopenharmony_ci
29262306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_de_clk, "bus-de", "psi-ahb1-ahb2",
29362306a36Sopenharmony_ci		      0x60c, BIT(0), 0);
29462306a36Sopenharmony_ci
29562306a36Sopenharmony_cistatic SUNXI_CCU_M_WITH_MUX_GATE(deinterlace_clk, "deinterlace",
29662306a36Sopenharmony_ci				       de_parents,
29762306a36Sopenharmony_ci				       0x620,
29862306a36Sopenharmony_ci				       0, 4,	/* M */
29962306a36Sopenharmony_ci				       24, 1,	/* mux */
30062306a36Sopenharmony_ci				       BIT(31),	/* gate */
30162306a36Sopenharmony_ci				       0);
30262306a36Sopenharmony_ci
30362306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_deinterlace_clk, "bus-deinterlace", "psi-ahb1-ahb2",
30462306a36Sopenharmony_ci		      0x62c, BIT(0), 0);
30562306a36Sopenharmony_ci
30662306a36Sopenharmony_cistatic SUNXI_CCU_M_WITH_MUX_GATE(g2d_clk, "g2d", de_parents, 0x630,
30762306a36Sopenharmony_ci				       0, 4,	/* M */
30862306a36Sopenharmony_ci				       24, 1,	/* mux */
30962306a36Sopenharmony_ci				       BIT(31),	/* gate */
31062306a36Sopenharmony_ci				       0);
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_g2d_clk, "bus-g2d", "psi-ahb1-ahb2",
31362306a36Sopenharmony_ci		      0x63c, BIT(0), 0);
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_cistatic const char * const gpu0_parents[] = { "pll-gpu", "gpu1" };
31662306a36Sopenharmony_cistatic SUNXI_CCU_M_WITH_MUX_GATE(gpu0_clk, "gpu0", gpu0_parents, 0x670,
31762306a36Sopenharmony_ci				       0, 2,	/* M */
31862306a36Sopenharmony_ci				       24, 1,	/* mux */
31962306a36Sopenharmony_ci				       BIT(31),	/* gate */
32062306a36Sopenharmony_ci				       CLK_SET_RATE_PARENT);
32162306a36Sopenharmony_cistatic SUNXI_CCU_M_WITH_GATE(gpu1_clk, "gpu1", "pll-periph0-2x", 0x674,
32262306a36Sopenharmony_ci					0, 2,	/* M */
32362306a36Sopenharmony_ci					BIT(31),/* gate */
32462306a36Sopenharmony_ci					0);
32562306a36Sopenharmony_ci
32662306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_gpu_clk, "bus-gpu", "psi-ahb1-ahb2",
32762306a36Sopenharmony_ci		      0x67c, BIT(0), 0);
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_cistatic const char * const ce_parents[] = { "osc24M", "pll-periph0-2x" };
33062306a36Sopenharmony_cistatic SUNXI_CCU_MP_WITH_MUX_GATE(ce_clk, "ce", ce_parents, 0x680,
33162306a36Sopenharmony_ci					0, 4,	/* M */
33262306a36Sopenharmony_ci					8, 2,	/* N */
33362306a36Sopenharmony_ci					24, 1,	/* mux */
33462306a36Sopenharmony_ci					BIT(31),/* gate */
33562306a36Sopenharmony_ci					0);
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_ce_clk, "bus-ce", "psi-ahb1-ahb2",
33862306a36Sopenharmony_ci		      0x68c, BIT(0), 0);
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_cistatic const char * const ve_parents[] = { "pll-ve" };
34162306a36Sopenharmony_cistatic SUNXI_CCU_M_WITH_MUX_GATE(ve_clk, "ve", ve_parents, 0x690,
34262306a36Sopenharmony_ci				       0, 3,	/* M */
34362306a36Sopenharmony_ci				       24, 1,	/* mux */
34462306a36Sopenharmony_ci				       BIT(31),	/* gate */
34562306a36Sopenharmony_ci				       CLK_SET_RATE_PARENT);
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "psi-ahb1-ahb2",
34862306a36Sopenharmony_ci		      0x69c, BIT(0), 0);
34962306a36Sopenharmony_ci
35062306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "psi-ahb1-ahb2",
35162306a36Sopenharmony_ci		      0x70c, BIT(0), 0);
35262306a36Sopenharmony_ci
35362306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer", "psi-ahb1-ahb2",
35462306a36Sopenharmony_ci		      0x73c, BIT(0), 0);
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_cistatic SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", 0x740, BIT(31), 0);
35762306a36Sopenharmony_ci
35862306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_dbg_clk, "bus-dbg", "psi-ahb1-ahb2",
35962306a36Sopenharmony_ci		      0x78c, BIT(0), 0);
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_psi_clk, "bus-psi", "psi-ahb1-ahb2",
36262306a36Sopenharmony_ci		      0x79c, BIT(0), 0);
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_pwm_clk, "bus-pwm", "apb1", 0x7ac, BIT(0), 0);
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_iommu_clk, "bus-iommu", "apb1", 0x7bc, BIT(0), 0);
36762306a36Sopenharmony_ci
36862306a36Sopenharmony_cistatic const char * const dram_parents[] = { "pll-ddr0", "pll-ddr1" };
36962306a36Sopenharmony_cistatic struct ccu_div dram_clk = {
37062306a36Sopenharmony_ci	.div		= _SUNXI_CCU_DIV(0, 2),
37162306a36Sopenharmony_ci	.mux		= _SUNXI_CCU_MUX(24, 2),
37262306a36Sopenharmony_ci	.common	= {
37362306a36Sopenharmony_ci		.reg		= 0x800,
37462306a36Sopenharmony_ci		.hw.init	= CLK_HW_INIT_PARENTS("dram",
37562306a36Sopenharmony_ci						      dram_parents,
37662306a36Sopenharmony_ci						      &ccu_div_ops,
37762306a36Sopenharmony_ci						      CLK_IS_CRITICAL),
37862306a36Sopenharmony_ci	},
37962306a36Sopenharmony_ci};
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_cistatic SUNXI_CCU_GATE(mbus_dma_clk, "mbus-dma", "mbus",
38262306a36Sopenharmony_ci		      0x804, BIT(0), 0);
38362306a36Sopenharmony_cistatic SUNXI_CCU_GATE(mbus_ve_clk, "mbus-ve", "mbus",
38462306a36Sopenharmony_ci		      0x804, BIT(1), 0);
38562306a36Sopenharmony_cistatic SUNXI_CCU_GATE(mbus_ce_clk, "mbus-ce", "mbus",
38662306a36Sopenharmony_ci		      0x804, BIT(2), 0);
38762306a36Sopenharmony_cistatic SUNXI_CCU_GATE(mbus_ts_clk, "mbus-ts", "mbus",
38862306a36Sopenharmony_ci		      0x804, BIT(3), 0);
38962306a36Sopenharmony_cistatic SUNXI_CCU_GATE(mbus_nand_clk, "mbus-nand", "mbus",
39062306a36Sopenharmony_ci		      0x804, BIT(5), 0);
39162306a36Sopenharmony_cistatic SUNXI_CCU_GATE(mbus_g2d_clk, "mbus-g2d", "mbus",
39262306a36Sopenharmony_ci		      0x804, BIT(10), 0);
39362306a36Sopenharmony_ci
39462306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "psi-ahb1-ahb2",
39562306a36Sopenharmony_ci		      0x80c, BIT(0), CLK_IS_CRITICAL);
39662306a36Sopenharmony_ci
39762306a36Sopenharmony_cistatic const char * const nand_spi_parents[] = { "osc24M", "pll-periph0",
39862306a36Sopenharmony_ci					     "pll-periph1", "pll-periph0-2x",
39962306a36Sopenharmony_ci					     "pll-periph1-2x" };
40062306a36Sopenharmony_cistatic SUNXI_CCU_MP_WITH_MUX_GATE(nand0_clk, "nand0", nand_spi_parents, 0x810,
40162306a36Sopenharmony_ci					0, 4,	/* M */
40262306a36Sopenharmony_ci					8, 2,	/* N */
40362306a36Sopenharmony_ci					24, 3,	/* mux */
40462306a36Sopenharmony_ci					BIT(31),/* gate */
40562306a36Sopenharmony_ci					0);
40662306a36Sopenharmony_ci
40762306a36Sopenharmony_cistatic SUNXI_CCU_MP_WITH_MUX_GATE(nand1_clk, "nand1", nand_spi_parents, 0x814,
40862306a36Sopenharmony_ci					0, 4,	/* M */
40962306a36Sopenharmony_ci					8, 2,	/* N */
41062306a36Sopenharmony_ci					24, 3,	/* mux */
41162306a36Sopenharmony_ci					BIT(31),/* gate */
41262306a36Sopenharmony_ci					0);
41362306a36Sopenharmony_ci
41462306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb3", 0x82c, BIT(0), 0);
41562306a36Sopenharmony_ci
41662306a36Sopenharmony_cistatic const char * const mmc_parents[] = { "osc24M", "pll-periph0-2x",
41762306a36Sopenharmony_ci					    "pll-periph1-2x" };
41862306a36Sopenharmony_cistatic SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc0_clk, "mmc0", mmc_parents, 0x830,
41962306a36Sopenharmony_ci					  0, 4,		/* M */
42062306a36Sopenharmony_ci					  8, 2,		/* N */
42162306a36Sopenharmony_ci					  24, 2,	/* mux */
42262306a36Sopenharmony_ci					  BIT(31),	/* gate */
42362306a36Sopenharmony_ci					  2,		/* post-div */
42462306a36Sopenharmony_ci					  0);
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_cistatic SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc1_clk, "mmc1", mmc_parents, 0x834,
42762306a36Sopenharmony_ci					  0, 4,		/* M */
42862306a36Sopenharmony_ci					  8, 2,		/* N */
42962306a36Sopenharmony_ci					  24, 2,	/* mux */
43062306a36Sopenharmony_ci					  BIT(31),	/* gate */
43162306a36Sopenharmony_ci					  2,		/* post-div */
43262306a36Sopenharmony_ci					  0);
43362306a36Sopenharmony_ci
43462306a36Sopenharmony_cistatic SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc2_clk, "mmc2", mmc_parents, 0x838,
43562306a36Sopenharmony_ci					  0, 4,		/* M */
43662306a36Sopenharmony_ci					  8, 2,		/* N */
43762306a36Sopenharmony_ci					  24, 2,	/* mux */
43862306a36Sopenharmony_ci					  BIT(31),	/* gate */
43962306a36Sopenharmony_ci					  2,		/* post-div */
44062306a36Sopenharmony_ci					  0);
44162306a36Sopenharmony_ci
44262306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb3", 0x84c, BIT(0), 0);
44362306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb3", 0x84c, BIT(1), 0);
44462306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_mmc2_clk, "bus-mmc2", "ahb3", 0x84c, BIT(2), 0);
44562306a36Sopenharmony_ci
44662306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb2", 0x90c, BIT(0), 0);
44762306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb2", 0x90c, BIT(1), 0);
44862306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb2", 0x90c, BIT(2), 0);
44962306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb2", 0x90c, BIT(3), 0);
45062306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_uart4_clk, "bus-uart4", "apb2", 0x90c, BIT(4), 0);
45162306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_uart5_clk, "bus-uart5", "apb2", 0x90c, BIT(5), 0);
45262306a36Sopenharmony_ci
45362306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb2", 0x91c, BIT(0), 0);
45462306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb2", 0x91c, BIT(1), 0);
45562306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_i2c2_clk, "bus-i2c2", "apb2", 0x91c, BIT(2), 0);
45662306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_i2c3_clk, "bus-i2c3", "apb2", 0x91c, BIT(3), 0);
45762306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_i2c4_clk, "bus-i2c4", "apb2", 0x91c, BIT(4), 0);
45862306a36Sopenharmony_ci
45962306a36Sopenharmony_cistatic SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", nand_spi_parents, 0x940,
46062306a36Sopenharmony_ci					0, 4,	/* M */
46162306a36Sopenharmony_ci					8, 2,	/* N */
46262306a36Sopenharmony_ci					24, 3,	/* mux */
46362306a36Sopenharmony_ci					BIT(31),/* gate */
46462306a36Sopenharmony_ci					0);
46562306a36Sopenharmony_ci
46662306a36Sopenharmony_cistatic SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", nand_spi_parents, 0x944,
46762306a36Sopenharmony_ci					0, 4,	/* M */
46862306a36Sopenharmony_ci					8, 2,	/* N */
46962306a36Sopenharmony_ci					24, 3,	/* mux */
47062306a36Sopenharmony_ci					BIT(31),/* gate */
47162306a36Sopenharmony_ci					0);
47262306a36Sopenharmony_ci
47362306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb3", 0x96c, BIT(0), 0);
47462306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb3", 0x96c, BIT(1), 0);
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_cistatic SUNXI_CCU_GATE(emac_25m_clk, "emac-25m", "ahb3", 0x970,
47762306a36Sopenharmony_ci		      BIT(31) | BIT(30), 0);
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_emac0_clk, "bus-emac0", "ahb3", 0x97c, BIT(0), 0);
48062306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_emac1_clk, "bus-emac1", "ahb3", 0x97c, BIT(1), 0);
48162306a36Sopenharmony_ci
48262306a36Sopenharmony_cistatic const char * const ts_parents[] = { "osc24M", "pll-periph0" };
48362306a36Sopenharmony_cistatic SUNXI_CCU_MP_WITH_MUX_GATE(ts_clk, "ts", ts_parents, 0x9b0,
48462306a36Sopenharmony_ci					0, 4,	/* M */
48562306a36Sopenharmony_ci					8, 2,	/* N */
48662306a36Sopenharmony_ci					24, 1,	/* mux */
48762306a36Sopenharmony_ci					BIT(31),/* gate */
48862306a36Sopenharmony_ci					0);
48962306a36Sopenharmony_ci
49062306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_ts_clk, "bus-ts", "ahb3", 0x9bc, BIT(0), 0);
49162306a36Sopenharmony_ci
49262306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_ths_clk, "bus-ths", "apb1", 0x9fc, BIT(0), 0);
49362306a36Sopenharmony_ci
49462306a36Sopenharmony_cistatic const char * const audio_parents[] = { "pll-audio-1x", "pll-audio-2x",
49562306a36Sopenharmony_ci					      "pll-audio-4x", "pll-audio-hs" };
49662306a36Sopenharmony_cistatic struct ccu_div spdif_clk = {
49762306a36Sopenharmony_ci	.enable		= BIT(31),
49862306a36Sopenharmony_ci	.div		= _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO),
49962306a36Sopenharmony_ci	.mux		= _SUNXI_CCU_MUX(24, 2),
50062306a36Sopenharmony_ci	.common		= {
50162306a36Sopenharmony_ci		.reg		= 0xa20,
50262306a36Sopenharmony_ci		.hw.init	= CLK_HW_INIT_PARENTS("spdif",
50362306a36Sopenharmony_ci						      audio_parents,
50462306a36Sopenharmony_ci						      &ccu_div_ops,
50562306a36Sopenharmony_ci						      0),
50662306a36Sopenharmony_ci	},
50762306a36Sopenharmony_ci};
50862306a36Sopenharmony_ci
50962306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_spdif_clk, "bus-spdif", "apb1", 0xa2c, BIT(0), 0);
51062306a36Sopenharmony_ci
51162306a36Sopenharmony_cistatic struct ccu_div dmic_clk = {
51262306a36Sopenharmony_ci	.enable		= BIT(31),
51362306a36Sopenharmony_ci	.div		= _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO),
51462306a36Sopenharmony_ci	.mux		= _SUNXI_CCU_MUX(24, 2),
51562306a36Sopenharmony_ci	.common		= {
51662306a36Sopenharmony_ci		.reg		= 0xa40,
51762306a36Sopenharmony_ci		.hw.init	= CLK_HW_INIT_PARENTS("dmic",
51862306a36Sopenharmony_ci						      audio_parents,
51962306a36Sopenharmony_ci						      &ccu_div_ops,
52062306a36Sopenharmony_ci						      0),
52162306a36Sopenharmony_ci	},
52262306a36Sopenharmony_ci};
52362306a36Sopenharmony_ci
52462306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_dmic_clk, "bus-dmic", "apb1", 0xa4c, BIT(0), 0);
52562306a36Sopenharmony_ci
52662306a36Sopenharmony_cistatic SUNXI_CCU_M_WITH_MUX_GATE(audio_codec_1x_clk, "audio-codec-1x",
52762306a36Sopenharmony_ci				 audio_parents, 0xa50,
52862306a36Sopenharmony_ci				 0, 4,	/* M */
52962306a36Sopenharmony_ci				 24, 2,	/* mux */
53062306a36Sopenharmony_ci				 BIT(31),	/* gate */
53162306a36Sopenharmony_ci				 CLK_SET_RATE_PARENT);
53262306a36Sopenharmony_cistatic SUNXI_CCU_M_WITH_MUX_GATE(audio_codec_4x_clk, "audio-codec-4x",
53362306a36Sopenharmony_ci				 audio_parents, 0xa54,
53462306a36Sopenharmony_ci				 0, 4,	/* M */
53562306a36Sopenharmony_ci				 24, 2,	/* mux */
53662306a36Sopenharmony_ci				 BIT(31),	/* gate */
53762306a36Sopenharmony_ci				 CLK_SET_RATE_PARENT);
53862306a36Sopenharmony_ci
53962306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_audio_codec_clk, "bus-audio-codec", "apb1", 0xa5c,
54062306a36Sopenharmony_ci		BIT(0), 0);
54162306a36Sopenharmony_ci
54262306a36Sopenharmony_cistatic struct ccu_div audio_hub_clk = {
54362306a36Sopenharmony_ci	.enable		= BIT(31),
54462306a36Sopenharmony_ci	.div		= _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO),
54562306a36Sopenharmony_ci	.mux		= _SUNXI_CCU_MUX(24, 2),
54662306a36Sopenharmony_ci	.common		= {
54762306a36Sopenharmony_ci		.reg		= 0xa60,
54862306a36Sopenharmony_ci		.hw.init	= CLK_HW_INIT_PARENTS("audio-hub",
54962306a36Sopenharmony_ci						      audio_parents,
55062306a36Sopenharmony_ci						      &ccu_div_ops,
55162306a36Sopenharmony_ci						      0),
55262306a36Sopenharmony_ci	},
55362306a36Sopenharmony_ci};
55462306a36Sopenharmony_ci
55562306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_audio_hub_clk, "bus-audio-hub", "apb1", 0xa6c, BIT(0), 0);
55662306a36Sopenharmony_ci
55762306a36Sopenharmony_ci/*
55862306a36Sopenharmony_ci * There are OHCI 12M clock source selection bits for the four USB 2.0 ports.
55962306a36Sopenharmony_ci * We will force them to 0 (12M divided from 48M).
56062306a36Sopenharmony_ci */
56162306a36Sopenharmony_ci#define SUN50I_H616_USB0_CLK_REG		0xa70
56262306a36Sopenharmony_ci#define SUN50I_H616_USB1_CLK_REG		0xa74
56362306a36Sopenharmony_ci#define SUN50I_H616_USB2_CLK_REG		0xa78
56462306a36Sopenharmony_ci#define SUN50I_H616_USB3_CLK_REG		0xa7c
56562306a36Sopenharmony_ci
56662306a36Sopenharmony_cistatic SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc12M", 0xa70, BIT(31), 0);
56762306a36Sopenharmony_cistatic SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M", 0xa70, BIT(29), 0);
56862306a36Sopenharmony_ci
56962306a36Sopenharmony_cistatic SUNXI_CCU_GATE(usb_ohci1_clk, "usb-ohci1", "osc12M", 0xa74, BIT(31), 0);
57062306a36Sopenharmony_cistatic SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M", 0xa74, BIT(29), 0);
57162306a36Sopenharmony_ci
57262306a36Sopenharmony_cistatic SUNXI_CCU_GATE(usb_ohci2_clk, "usb-ohci2", "osc12M", 0xa78, BIT(31), 0);
57362306a36Sopenharmony_cistatic SUNXI_CCU_GATE(usb_phy2_clk, "usb-phy2", "osc24M", 0xa78, BIT(29), 0);
57462306a36Sopenharmony_ci
57562306a36Sopenharmony_cistatic SUNXI_CCU_GATE(usb_ohci3_clk, "usb-ohci3", "osc12M", 0xa7c, BIT(31), 0);
57662306a36Sopenharmony_cistatic SUNXI_CCU_GATE(usb_phy3_clk, "usb-phy3", "osc24M", 0xa7c, BIT(29), 0);
57762306a36Sopenharmony_ci
57862306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_ohci0_clk, "bus-ohci0", "ahb3", 0xa8c, BIT(0), 0);
57962306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_ohci1_clk, "bus-ohci1", "ahb3", 0xa8c, BIT(1), 0);
58062306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_ohci2_clk, "bus-ohci2", "ahb3", 0xa8c, BIT(2), 0);
58162306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_ohci3_clk, "bus-ohci3", "ahb3", 0xa8c, BIT(3), 0);
58262306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_ehci0_clk, "bus-ehci0", "ahb3", 0xa8c, BIT(4), 0);
58362306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_ehci1_clk, "bus-ehci1", "ahb3", 0xa8c, BIT(5), 0);
58462306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_ehci2_clk, "bus-ehci2", "ahb3", 0xa8c, BIT(6), 0);
58562306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_ehci3_clk, "bus-ehci3", "ahb3", 0xa8c, BIT(7), 0);
58662306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb3", 0xa8c, BIT(8), 0);
58762306a36Sopenharmony_ci
58862306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_keyadc_clk, "bus-keyadc", "apb1", 0xa9c, BIT(0), 0);
58962306a36Sopenharmony_ci
59062306a36Sopenharmony_cistatic const char * const hdmi_parents[] = { "pll-video0", "pll-video0-4x",
59162306a36Sopenharmony_ci					     "pll-video2", "pll-video2-4x" };
59262306a36Sopenharmony_cistatic SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", hdmi_parents, 0xb00,
59362306a36Sopenharmony_ci				 0, 4,		/* M */
59462306a36Sopenharmony_ci				 24, 2,		/* mux */
59562306a36Sopenharmony_ci				 BIT(31),	/* gate */
59662306a36Sopenharmony_ci				 0);
59762306a36Sopenharmony_ci
59862306a36Sopenharmony_cistatic SUNXI_CCU_GATE(hdmi_slow_clk, "hdmi-slow", "osc24M", 0xb04, BIT(31), 0);
59962306a36Sopenharmony_ci
60062306a36Sopenharmony_cistatic const char * const hdmi_cec_parents[] = { "osc32k", "pll-periph0-2x" };
60162306a36Sopenharmony_cistatic const struct ccu_mux_fixed_prediv hdmi_cec_predivs[] = {
60262306a36Sopenharmony_ci	{ .index = 1, .div = 36621 },
60362306a36Sopenharmony_ci};
60462306a36Sopenharmony_ci
60562306a36Sopenharmony_ci#define SUN50I_H616_HDMI_CEC_CLK_REG		0xb10
60662306a36Sopenharmony_cistatic struct ccu_mux hdmi_cec_clk = {
60762306a36Sopenharmony_ci	.enable		= BIT(31) | BIT(30),
60862306a36Sopenharmony_ci
60962306a36Sopenharmony_ci	.mux		= {
61062306a36Sopenharmony_ci		.shift	= 24,
61162306a36Sopenharmony_ci		.width	= 2,
61262306a36Sopenharmony_ci
61362306a36Sopenharmony_ci		.fixed_predivs	= hdmi_cec_predivs,
61462306a36Sopenharmony_ci		.n_predivs	= ARRAY_SIZE(hdmi_cec_predivs),
61562306a36Sopenharmony_ci	},
61662306a36Sopenharmony_ci
61762306a36Sopenharmony_ci	.common		= {
61862306a36Sopenharmony_ci		.reg		= 0xb10,
61962306a36Sopenharmony_ci		.features	= CCU_FEATURE_FIXED_PREDIV,
62062306a36Sopenharmony_ci		.hw.init	= CLK_HW_INIT_PARENTS("hdmi-cec",
62162306a36Sopenharmony_ci						      hdmi_cec_parents,
62262306a36Sopenharmony_ci						      &ccu_mux_ops,
62362306a36Sopenharmony_ci						      0),
62462306a36Sopenharmony_ci	},
62562306a36Sopenharmony_ci};
62662306a36Sopenharmony_ci
62762306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_hdmi_clk, "bus-hdmi", "ahb3", 0xb1c, BIT(0), 0);
62862306a36Sopenharmony_ci
62962306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_tcon_top_clk, "bus-tcon-top", "ahb3",
63062306a36Sopenharmony_ci		      0xb5c, BIT(0), 0);
63162306a36Sopenharmony_ci
63262306a36Sopenharmony_cistatic const char * const tcon_tv_parents[] = { "pll-video0",
63362306a36Sopenharmony_ci						"pll-video0-4x",
63462306a36Sopenharmony_ci						"pll-video1",
63562306a36Sopenharmony_ci						"pll-video1-4x" };
63662306a36Sopenharmony_cistatic SUNXI_CCU_MP_WITH_MUX_GATE(tcon_tv0_clk, "tcon-tv0",
63762306a36Sopenharmony_ci				  tcon_tv_parents, 0xb80,
63862306a36Sopenharmony_ci				  0, 4,		/* M */
63962306a36Sopenharmony_ci				  8, 2,		/* P */
64062306a36Sopenharmony_ci				  24, 3,	/* mux */
64162306a36Sopenharmony_ci				  BIT(31),	/* gate */
64262306a36Sopenharmony_ci				  CLK_SET_RATE_PARENT);
64362306a36Sopenharmony_cistatic SUNXI_CCU_MP_WITH_MUX_GATE(tcon_tv1_clk, "tcon-tv1",
64462306a36Sopenharmony_ci				  tcon_tv_parents, 0xb84,
64562306a36Sopenharmony_ci				  0, 4,		/* M */
64662306a36Sopenharmony_ci				  8, 2,		/* P */
64762306a36Sopenharmony_ci				  24, 3,	/* mux */
64862306a36Sopenharmony_ci				  BIT(31),	/* gate */
64962306a36Sopenharmony_ci				  CLK_SET_RATE_PARENT);
65062306a36Sopenharmony_ci
65162306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_tcon_tv0_clk, "bus-tcon-tv0", "ahb3",
65262306a36Sopenharmony_ci		      0xb9c, BIT(0), 0);
65362306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_tcon_tv1_clk, "bus-tcon-tv1", "ahb3",
65462306a36Sopenharmony_ci		      0xb9c, BIT(1), 0);
65562306a36Sopenharmony_ci
65662306a36Sopenharmony_cistatic SUNXI_CCU_MP_WITH_MUX_GATE(tve0_clk, "tve0",
65762306a36Sopenharmony_ci				  tcon_tv_parents, 0xbb0,
65862306a36Sopenharmony_ci				  0, 4,		/* M */
65962306a36Sopenharmony_ci				  8, 2,		/* P */
66062306a36Sopenharmony_ci				  24, 3,	/* mux */
66162306a36Sopenharmony_ci				  BIT(31),	/* gate */
66262306a36Sopenharmony_ci				  CLK_SET_RATE_PARENT);
66362306a36Sopenharmony_ci
66462306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_tve_top_clk, "bus-tve-top", "ahb3",
66562306a36Sopenharmony_ci		      0xbbc, BIT(0), 0);
66662306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_tve0_clk, "bus-tve0", "ahb3",
66762306a36Sopenharmony_ci		      0xbbc, BIT(1), 0);
66862306a36Sopenharmony_ci
66962306a36Sopenharmony_cistatic const char * const hdcp_parents[] = { "pll-periph0", "pll-periph1" };
67062306a36Sopenharmony_cistatic SUNXI_CCU_M_WITH_MUX_GATE(hdcp_clk, "hdcp", hdcp_parents, 0xc40,
67162306a36Sopenharmony_ci				 0, 4,		/* M */
67262306a36Sopenharmony_ci				 24, 2,		/* mux */
67362306a36Sopenharmony_ci				 BIT(31),	/* gate */
67462306a36Sopenharmony_ci				 0);
67562306a36Sopenharmony_ci
67662306a36Sopenharmony_cistatic SUNXI_CCU_GATE(bus_hdcp_clk, "bus-hdcp", "ahb3", 0xc4c, BIT(0), 0);
67762306a36Sopenharmony_ci
67862306a36Sopenharmony_ci/* Fixed factor clocks */
67962306a36Sopenharmony_cistatic CLK_FIXED_FACTOR_FW_NAME(osc12M_clk, "osc12M", "hosc", 2, 1, 0);
68062306a36Sopenharmony_ci
68162306a36Sopenharmony_cistatic const struct clk_hw *clk_parent_pll_audio[] = {
68262306a36Sopenharmony_ci	&pll_audio_hs_clk.common.hw
68362306a36Sopenharmony_ci};
68462306a36Sopenharmony_ci
68562306a36Sopenharmony_ci/*
68662306a36Sopenharmony_ci * The divider of pll-audio is fixed to 24 for now, so 24576000 and 22579200
68762306a36Sopenharmony_ci * rates can be set exactly in conjunction with sigma-delta modulation.
68862306a36Sopenharmony_ci */
68962306a36Sopenharmony_cistatic CLK_FIXED_FACTOR_HWS(pll_audio_1x_clk, "pll-audio-1x",
69062306a36Sopenharmony_ci			    clk_parent_pll_audio,
69162306a36Sopenharmony_ci			    96, 1, CLK_SET_RATE_PARENT);
69262306a36Sopenharmony_cistatic CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x",
69362306a36Sopenharmony_ci			    clk_parent_pll_audio,
69462306a36Sopenharmony_ci			    48, 1, CLK_SET_RATE_PARENT);
69562306a36Sopenharmony_cistatic CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x",
69662306a36Sopenharmony_ci			    clk_parent_pll_audio,
69762306a36Sopenharmony_ci			    24, 1, CLK_SET_RATE_PARENT);
69862306a36Sopenharmony_ci
69962306a36Sopenharmony_cistatic const struct clk_hw *pll_periph0_parents[] = {
70062306a36Sopenharmony_ci	&pll_periph0_clk.common.hw
70162306a36Sopenharmony_ci};
70262306a36Sopenharmony_ci
70362306a36Sopenharmony_cistatic CLK_FIXED_FACTOR_HWS(pll_periph0_2x_clk, "pll-periph0-2x",
70462306a36Sopenharmony_ci			    pll_periph0_parents,
70562306a36Sopenharmony_ci			    1, 2, 0);
70662306a36Sopenharmony_ci
70762306a36Sopenharmony_cistatic const struct clk_hw *pll_periph0_2x_hws[] = {
70862306a36Sopenharmony_ci	&pll_periph0_2x_clk.hw
70962306a36Sopenharmony_ci};
71062306a36Sopenharmony_ci
71162306a36Sopenharmony_cistatic CLK_FIXED_FACTOR_HWS(pll_system_32k_clk, "pll-system-32k",
71262306a36Sopenharmony_ci			    pll_periph0_2x_hws, 36621, 1, 0);
71362306a36Sopenharmony_ci
71462306a36Sopenharmony_cistatic const struct clk_hw *pll_periph1_parents[] = {
71562306a36Sopenharmony_ci	&pll_periph1_clk.common.hw
71662306a36Sopenharmony_ci};
71762306a36Sopenharmony_ci
71862306a36Sopenharmony_cistatic CLK_FIXED_FACTOR_HWS(pll_periph1_2x_clk, "pll-periph1-2x",
71962306a36Sopenharmony_ci			    pll_periph1_parents,
72062306a36Sopenharmony_ci			    1, 2, 0);
72162306a36Sopenharmony_ci
72262306a36Sopenharmony_cistatic CLK_FIXED_FACTOR_HW(pll_video0_4x_clk, "pll-video0-4x",
72362306a36Sopenharmony_ci			   &pll_video0_clk.common.hw,
72462306a36Sopenharmony_ci			   1, 4, CLK_SET_RATE_PARENT);
72562306a36Sopenharmony_cistatic CLK_FIXED_FACTOR_HW(pll_video1_4x_clk, "pll-video1-4x",
72662306a36Sopenharmony_ci			   &pll_video1_clk.common.hw,
72762306a36Sopenharmony_ci			   1, 4, CLK_SET_RATE_PARENT);
72862306a36Sopenharmony_cistatic CLK_FIXED_FACTOR_HW(pll_video2_4x_clk, "pll-video2-4x",
72962306a36Sopenharmony_ci			   &pll_video2_clk.common.hw,
73062306a36Sopenharmony_ci			   1, 4, CLK_SET_RATE_PARENT);
73162306a36Sopenharmony_ci
73262306a36Sopenharmony_cistatic struct ccu_common *sun50i_h616_ccu_clks[] = {
73362306a36Sopenharmony_ci	&pll_cpux_clk.common,
73462306a36Sopenharmony_ci	&pll_ddr0_clk.common,
73562306a36Sopenharmony_ci	&pll_ddr1_clk.common,
73662306a36Sopenharmony_ci	&pll_periph0_clk.common,
73762306a36Sopenharmony_ci	&pll_periph1_clk.common,
73862306a36Sopenharmony_ci	&pll_gpu_clk.common,
73962306a36Sopenharmony_ci	&pll_video0_clk.common,
74062306a36Sopenharmony_ci	&pll_video1_clk.common,
74162306a36Sopenharmony_ci	&pll_video2_clk.common,
74262306a36Sopenharmony_ci	&pll_ve_clk.common,
74362306a36Sopenharmony_ci	&pll_de_clk.common,
74462306a36Sopenharmony_ci	&pll_audio_hs_clk.common,
74562306a36Sopenharmony_ci	&cpux_clk.common,
74662306a36Sopenharmony_ci	&axi_clk.common,
74762306a36Sopenharmony_ci	&cpux_apb_clk.common,
74862306a36Sopenharmony_ci	&psi_ahb1_ahb2_clk.common,
74962306a36Sopenharmony_ci	&ahb3_clk.common,
75062306a36Sopenharmony_ci	&apb1_clk.common,
75162306a36Sopenharmony_ci	&apb2_clk.common,
75262306a36Sopenharmony_ci	&mbus_clk.common,
75362306a36Sopenharmony_ci	&de_clk.common,
75462306a36Sopenharmony_ci	&bus_de_clk.common,
75562306a36Sopenharmony_ci	&deinterlace_clk.common,
75662306a36Sopenharmony_ci	&bus_deinterlace_clk.common,
75762306a36Sopenharmony_ci	&g2d_clk.common,
75862306a36Sopenharmony_ci	&bus_g2d_clk.common,
75962306a36Sopenharmony_ci	&gpu0_clk.common,
76062306a36Sopenharmony_ci	&bus_gpu_clk.common,
76162306a36Sopenharmony_ci	&gpu1_clk.common,
76262306a36Sopenharmony_ci	&ce_clk.common,
76362306a36Sopenharmony_ci	&bus_ce_clk.common,
76462306a36Sopenharmony_ci	&ve_clk.common,
76562306a36Sopenharmony_ci	&bus_ve_clk.common,
76662306a36Sopenharmony_ci	&bus_dma_clk.common,
76762306a36Sopenharmony_ci	&bus_hstimer_clk.common,
76862306a36Sopenharmony_ci	&avs_clk.common,
76962306a36Sopenharmony_ci	&bus_dbg_clk.common,
77062306a36Sopenharmony_ci	&bus_psi_clk.common,
77162306a36Sopenharmony_ci	&bus_pwm_clk.common,
77262306a36Sopenharmony_ci	&bus_iommu_clk.common,
77362306a36Sopenharmony_ci	&dram_clk.common,
77462306a36Sopenharmony_ci	&mbus_dma_clk.common,
77562306a36Sopenharmony_ci	&mbus_ve_clk.common,
77662306a36Sopenharmony_ci	&mbus_ce_clk.common,
77762306a36Sopenharmony_ci	&mbus_ts_clk.common,
77862306a36Sopenharmony_ci	&mbus_nand_clk.common,
77962306a36Sopenharmony_ci	&mbus_g2d_clk.common,
78062306a36Sopenharmony_ci	&bus_dram_clk.common,
78162306a36Sopenharmony_ci	&nand0_clk.common,
78262306a36Sopenharmony_ci	&nand1_clk.common,
78362306a36Sopenharmony_ci	&bus_nand_clk.common,
78462306a36Sopenharmony_ci	&mmc0_clk.common,
78562306a36Sopenharmony_ci	&mmc1_clk.common,
78662306a36Sopenharmony_ci	&mmc2_clk.common,
78762306a36Sopenharmony_ci	&bus_mmc0_clk.common,
78862306a36Sopenharmony_ci	&bus_mmc1_clk.common,
78962306a36Sopenharmony_ci	&bus_mmc2_clk.common,
79062306a36Sopenharmony_ci	&bus_uart0_clk.common,
79162306a36Sopenharmony_ci	&bus_uart1_clk.common,
79262306a36Sopenharmony_ci	&bus_uart2_clk.common,
79362306a36Sopenharmony_ci	&bus_uart3_clk.common,
79462306a36Sopenharmony_ci	&bus_uart4_clk.common,
79562306a36Sopenharmony_ci	&bus_uart5_clk.common,
79662306a36Sopenharmony_ci	&bus_i2c0_clk.common,
79762306a36Sopenharmony_ci	&bus_i2c1_clk.common,
79862306a36Sopenharmony_ci	&bus_i2c2_clk.common,
79962306a36Sopenharmony_ci	&bus_i2c3_clk.common,
80062306a36Sopenharmony_ci	&bus_i2c4_clk.common,
80162306a36Sopenharmony_ci	&spi0_clk.common,
80262306a36Sopenharmony_ci	&spi1_clk.common,
80362306a36Sopenharmony_ci	&bus_spi0_clk.common,
80462306a36Sopenharmony_ci	&bus_spi1_clk.common,
80562306a36Sopenharmony_ci	&emac_25m_clk.common,
80662306a36Sopenharmony_ci	&bus_emac0_clk.common,
80762306a36Sopenharmony_ci	&bus_emac1_clk.common,
80862306a36Sopenharmony_ci	&ts_clk.common,
80962306a36Sopenharmony_ci	&bus_ts_clk.common,
81062306a36Sopenharmony_ci	&bus_ths_clk.common,
81162306a36Sopenharmony_ci	&spdif_clk.common,
81262306a36Sopenharmony_ci	&bus_spdif_clk.common,
81362306a36Sopenharmony_ci	&dmic_clk.common,
81462306a36Sopenharmony_ci	&bus_dmic_clk.common,
81562306a36Sopenharmony_ci	&audio_codec_1x_clk.common,
81662306a36Sopenharmony_ci	&audio_codec_4x_clk.common,
81762306a36Sopenharmony_ci	&bus_audio_codec_clk.common,
81862306a36Sopenharmony_ci	&audio_hub_clk.common,
81962306a36Sopenharmony_ci	&bus_audio_hub_clk.common,
82062306a36Sopenharmony_ci	&usb_ohci0_clk.common,
82162306a36Sopenharmony_ci	&usb_phy0_clk.common,
82262306a36Sopenharmony_ci	&usb_ohci1_clk.common,
82362306a36Sopenharmony_ci	&usb_phy1_clk.common,
82462306a36Sopenharmony_ci	&usb_ohci2_clk.common,
82562306a36Sopenharmony_ci	&usb_phy2_clk.common,
82662306a36Sopenharmony_ci	&usb_ohci3_clk.common,
82762306a36Sopenharmony_ci	&usb_phy3_clk.common,
82862306a36Sopenharmony_ci	&bus_ohci0_clk.common,
82962306a36Sopenharmony_ci	&bus_ohci1_clk.common,
83062306a36Sopenharmony_ci	&bus_ohci2_clk.common,
83162306a36Sopenharmony_ci	&bus_ohci3_clk.common,
83262306a36Sopenharmony_ci	&bus_ehci0_clk.common,
83362306a36Sopenharmony_ci	&bus_ehci1_clk.common,
83462306a36Sopenharmony_ci	&bus_ehci2_clk.common,
83562306a36Sopenharmony_ci	&bus_ehci3_clk.common,
83662306a36Sopenharmony_ci	&bus_otg_clk.common,
83762306a36Sopenharmony_ci	&bus_keyadc_clk.common,
83862306a36Sopenharmony_ci	&hdmi_clk.common,
83962306a36Sopenharmony_ci	&hdmi_slow_clk.common,
84062306a36Sopenharmony_ci	&hdmi_cec_clk.common,
84162306a36Sopenharmony_ci	&bus_hdmi_clk.common,
84262306a36Sopenharmony_ci	&bus_tcon_top_clk.common,
84362306a36Sopenharmony_ci	&tcon_tv0_clk.common,
84462306a36Sopenharmony_ci	&tcon_tv1_clk.common,
84562306a36Sopenharmony_ci	&bus_tcon_tv0_clk.common,
84662306a36Sopenharmony_ci	&bus_tcon_tv1_clk.common,
84762306a36Sopenharmony_ci	&tve0_clk.common,
84862306a36Sopenharmony_ci	&bus_tve_top_clk.common,
84962306a36Sopenharmony_ci	&bus_tve0_clk.common,
85062306a36Sopenharmony_ci	&hdcp_clk.common,
85162306a36Sopenharmony_ci	&bus_hdcp_clk.common,
85262306a36Sopenharmony_ci};
85362306a36Sopenharmony_ci
85462306a36Sopenharmony_cistatic struct clk_hw_onecell_data sun50i_h616_hw_clks = {
85562306a36Sopenharmony_ci	.hws	= {
85662306a36Sopenharmony_ci		[CLK_OSC12M]		= &osc12M_clk.hw,
85762306a36Sopenharmony_ci		[CLK_PLL_CPUX]		= &pll_cpux_clk.common.hw,
85862306a36Sopenharmony_ci		[CLK_PLL_DDR0]		= &pll_ddr0_clk.common.hw,
85962306a36Sopenharmony_ci		[CLK_PLL_DDR1]		= &pll_ddr1_clk.common.hw,
86062306a36Sopenharmony_ci		[CLK_PLL_PERIPH0]	= &pll_periph0_clk.common.hw,
86162306a36Sopenharmony_ci		[CLK_PLL_PERIPH0_2X]	= &pll_periph0_2x_clk.hw,
86262306a36Sopenharmony_ci		[CLK_PLL_SYSTEM_32K]	= &pll_system_32k_clk.hw,
86362306a36Sopenharmony_ci		[CLK_PLL_PERIPH1]	= &pll_periph1_clk.common.hw,
86462306a36Sopenharmony_ci		[CLK_PLL_PERIPH1_2X]	= &pll_periph1_2x_clk.hw,
86562306a36Sopenharmony_ci		[CLK_PLL_GPU]		= &pll_gpu_clk.common.hw,
86662306a36Sopenharmony_ci		[CLK_PLL_VIDEO0]	= &pll_video0_clk.common.hw,
86762306a36Sopenharmony_ci		[CLK_PLL_VIDEO0_4X]	= &pll_video0_4x_clk.hw,
86862306a36Sopenharmony_ci		[CLK_PLL_VIDEO1]	= &pll_video1_clk.common.hw,
86962306a36Sopenharmony_ci		[CLK_PLL_VIDEO1_4X]	= &pll_video1_4x_clk.hw,
87062306a36Sopenharmony_ci		[CLK_PLL_VIDEO2]	= &pll_video2_clk.common.hw,
87162306a36Sopenharmony_ci		[CLK_PLL_VIDEO2_4X]	= &pll_video2_4x_clk.hw,
87262306a36Sopenharmony_ci		[CLK_PLL_VE]		= &pll_ve_clk.common.hw,
87362306a36Sopenharmony_ci		[CLK_PLL_DE]		= &pll_de_clk.common.hw,
87462306a36Sopenharmony_ci		[CLK_PLL_AUDIO_HS]	= &pll_audio_hs_clk.common.hw,
87562306a36Sopenharmony_ci		[CLK_PLL_AUDIO_1X]	= &pll_audio_1x_clk.hw,
87662306a36Sopenharmony_ci		[CLK_PLL_AUDIO_2X]	= &pll_audio_2x_clk.hw,
87762306a36Sopenharmony_ci		[CLK_PLL_AUDIO_4X]	= &pll_audio_4x_clk.hw,
87862306a36Sopenharmony_ci		[CLK_CPUX]		= &cpux_clk.common.hw,
87962306a36Sopenharmony_ci		[CLK_AXI]		= &axi_clk.common.hw,
88062306a36Sopenharmony_ci		[CLK_CPUX_APB]		= &cpux_apb_clk.common.hw,
88162306a36Sopenharmony_ci		[CLK_PSI_AHB1_AHB2]	= &psi_ahb1_ahb2_clk.common.hw,
88262306a36Sopenharmony_ci		[CLK_AHB3]		= &ahb3_clk.common.hw,
88362306a36Sopenharmony_ci		[CLK_APB1]		= &apb1_clk.common.hw,
88462306a36Sopenharmony_ci		[CLK_APB2]		= &apb2_clk.common.hw,
88562306a36Sopenharmony_ci		[CLK_MBUS]		= &mbus_clk.common.hw,
88662306a36Sopenharmony_ci		[CLK_DE]		= &de_clk.common.hw,
88762306a36Sopenharmony_ci		[CLK_BUS_DE]		= &bus_de_clk.common.hw,
88862306a36Sopenharmony_ci		[CLK_DEINTERLACE]	= &deinterlace_clk.common.hw,
88962306a36Sopenharmony_ci		[CLK_BUS_DEINTERLACE]	= &bus_deinterlace_clk.common.hw,
89062306a36Sopenharmony_ci		[CLK_G2D]		= &g2d_clk.common.hw,
89162306a36Sopenharmony_ci		[CLK_BUS_G2D]		= &bus_g2d_clk.common.hw,
89262306a36Sopenharmony_ci		[CLK_GPU0]		= &gpu0_clk.common.hw,
89362306a36Sopenharmony_ci		[CLK_BUS_GPU]		= &bus_gpu_clk.common.hw,
89462306a36Sopenharmony_ci		[CLK_GPU1]		= &gpu1_clk.common.hw,
89562306a36Sopenharmony_ci		[CLK_CE]		= &ce_clk.common.hw,
89662306a36Sopenharmony_ci		[CLK_BUS_CE]		= &bus_ce_clk.common.hw,
89762306a36Sopenharmony_ci		[CLK_VE]		= &ve_clk.common.hw,
89862306a36Sopenharmony_ci		[CLK_BUS_VE]		= &bus_ve_clk.common.hw,
89962306a36Sopenharmony_ci		[CLK_BUS_DMA]		= &bus_dma_clk.common.hw,
90062306a36Sopenharmony_ci		[CLK_BUS_HSTIMER]	= &bus_hstimer_clk.common.hw,
90162306a36Sopenharmony_ci		[CLK_AVS]		= &avs_clk.common.hw,
90262306a36Sopenharmony_ci		[CLK_BUS_DBG]		= &bus_dbg_clk.common.hw,
90362306a36Sopenharmony_ci		[CLK_BUS_PSI]		= &bus_psi_clk.common.hw,
90462306a36Sopenharmony_ci		[CLK_BUS_PWM]		= &bus_pwm_clk.common.hw,
90562306a36Sopenharmony_ci		[CLK_BUS_IOMMU]		= &bus_iommu_clk.common.hw,
90662306a36Sopenharmony_ci		[CLK_DRAM]		= &dram_clk.common.hw,
90762306a36Sopenharmony_ci		[CLK_MBUS_DMA]		= &mbus_dma_clk.common.hw,
90862306a36Sopenharmony_ci		[CLK_MBUS_VE]		= &mbus_ve_clk.common.hw,
90962306a36Sopenharmony_ci		[CLK_MBUS_CE]		= &mbus_ce_clk.common.hw,
91062306a36Sopenharmony_ci		[CLK_MBUS_TS]		= &mbus_ts_clk.common.hw,
91162306a36Sopenharmony_ci		[CLK_MBUS_NAND]		= &mbus_nand_clk.common.hw,
91262306a36Sopenharmony_ci		[CLK_MBUS_G2D]		= &mbus_g2d_clk.common.hw,
91362306a36Sopenharmony_ci		[CLK_BUS_DRAM]		= &bus_dram_clk.common.hw,
91462306a36Sopenharmony_ci		[CLK_NAND0]		= &nand0_clk.common.hw,
91562306a36Sopenharmony_ci		[CLK_NAND1]		= &nand1_clk.common.hw,
91662306a36Sopenharmony_ci		[CLK_BUS_NAND]		= &bus_nand_clk.common.hw,
91762306a36Sopenharmony_ci		[CLK_MMC0]		= &mmc0_clk.common.hw,
91862306a36Sopenharmony_ci		[CLK_MMC1]		= &mmc1_clk.common.hw,
91962306a36Sopenharmony_ci		[CLK_MMC2]		= &mmc2_clk.common.hw,
92062306a36Sopenharmony_ci		[CLK_BUS_MMC0]		= &bus_mmc0_clk.common.hw,
92162306a36Sopenharmony_ci		[CLK_BUS_MMC1]		= &bus_mmc1_clk.common.hw,
92262306a36Sopenharmony_ci		[CLK_BUS_MMC2]		= &bus_mmc2_clk.common.hw,
92362306a36Sopenharmony_ci		[CLK_BUS_UART0]		= &bus_uart0_clk.common.hw,
92462306a36Sopenharmony_ci		[CLK_BUS_UART1]		= &bus_uart1_clk.common.hw,
92562306a36Sopenharmony_ci		[CLK_BUS_UART2]		= &bus_uart2_clk.common.hw,
92662306a36Sopenharmony_ci		[CLK_BUS_UART3]		= &bus_uart3_clk.common.hw,
92762306a36Sopenharmony_ci		[CLK_BUS_UART4]		= &bus_uart4_clk.common.hw,
92862306a36Sopenharmony_ci		[CLK_BUS_UART5]		= &bus_uart5_clk.common.hw,
92962306a36Sopenharmony_ci		[CLK_BUS_I2C0]		= &bus_i2c0_clk.common.hw,
93062306a36Sopenharmony_ci		[CLK_BUS_I2C1]		= &bus_i2c1_clk.common.hw,
93162306a36Sopenharmony_ci		[CLK_BUS_I2C2]		= &bus_i2c2_clk.common.hw,
93262306a36Sopenharmony_ci		[CLK_BUS_I2C3]		= &bus_i2c3_clk.common.hw,
93362306a36Sopenharmony_ci		[CLK_BUS_I2C4]		= &bus_i2c4_clk.common.hw,
93462306a36Sopenharmony_ci		[CLK_SPI0]		= &spi0_clk.common.hw,
93562306a36Sopenharmony_ci		[CLK_SPI1]		= &spi1_clk.common.hw,
93662306a36Sopenharmony_ci		[CLK_BUS_SPI0]		= &bus_spi0_clk.common.hw,
93762306a36Sopenharmony_ci		[CLK_BUS_SPI1]		= &bus_spi1_clk.common.hw,
93862306a36Sopenharmony_ci		[CLK_EMAC_25M]		= &emac_25m_clk.common.hw,
93962306a36Sopenharmony_ci		[CLK_BUS_EMAC0]		= &bus_emac0_clk.common.hw,
94062306a36Sopenharmony_ci		[CLK_BUS_EMAC1]		= &bus_emac1_clk.common.hw,
94162306a36Sopenharmony_ci		[CLK_TS]		= &ts_clk.common.hw,
94262306a36Sopenharmony_ci		[CLK_BUS_TS]		= &bus_ts_clk.common.hw,
94362306a36Sopenharmony_ci		[CLK_BUS_THS]		= &bus_ths_clk.common.hw,
94462306a36Sopenharmony_ci		[CLK_SPDIF]		= &spdif_clk.common.hw,
94562306a36Sopenharmony_ci		[CLK_BUS_SPDIF]		= &bus_spdif_clk.common.hw,
94662306a36Sopenharmony_ci		[CLK_DMIC]		= &dmic_clk.common.hw,
94762306a36Sopenharmony_ci		[CLK_BUS_DMIC]		= &bus_dmic_clk.common.hw,
94862306a36Sopenharmony_ci		[CLK_AUDIO_CODEC_1X]	= &audio_codec_1x_clk.common.hw,
94962306a36Sopenharmony_ci		[CLK_AUDIO_CODEC_4X]	= &audio_codec_4x_clk.common.hw,
95062306a36Sopenharmony_ci		[CLK_BUS_AUDIO_CODEC]	= &bus_audio_codec_clk.common.hw,
95162306a36Sopenharmony_ci		[CLK_AUDIO_HUB]		= &audio_hub_clk.common.hw,
95262306a36Sopenharmony_ci		[CLK_BUS_AUDIO_HUB]	= &bus_audio_hub_clk.common.hw,
95362306a36Sopenharmony_ci		[CLK_USB_OHCI0]		= &usb_ohci0_clk.common.hw,
95462306a36Sopenharmony_ci		[CLK_USB_PHY0]		= &usb_phy0_clk.common.hw,
95562306a36Sopenharmony_ci		[CLK_USB_OHCI1]		= &usb_ohci1_clk.common.hw,
95662306a36Sopenharmony_ci		[CLK_USB_PHY1]		= &usb_phy1_clk.common.hw,
95762306a36Sopenharmony_ci		[CLK_USB_OHCI2]		= &usb_ohci2_clk.common.hw,
95862306a36Sopenharmony_ci		[CLK_USB_PHY2]		= &usb_phy2_clk.common.hw,
95962306a36Sopenharmony_ci		[CLK_USB_OHCI3]		= &usb_ohci3_clk.common.hw,
96062306a36Sopenharmony_ci		[CLK_USB_PHY3]		= &usb_phy3_clk.common.hw,
96162306a36Sopenharmony_ci		[CLK_BUS_OHCI0]		= &bus_ohci0_clk.common.hw,
96262306a36Sopenharmony_ci		[CLK_BUS_OHCI1]		= &bus_ohci1_clk.common.hw,
96362306a36Sopenharmony_ci		[CLK_BUS_OHCI2]		= &bus_ohci2_clk.common.hw,
96462306a36Sopenharmony_ci		[CLK_BUS_OHCI3]		= &bus_ohci3_clk.common.hw,
96562306a36Sopenharmony_ci		[CLK_BUS_EHCI0]		= &bus_ehci0_clk.common.hw,
96662306a36Sopenharmony_ci		[CLK_BUS_EHCI1]		= &bus_ehci1_clk.common.hw,
96762306a36Sopenharmony_ci		[CLK_BUS_EHCI2]		= &bus_ehci2_clk.common.hw,
96862306a36Sopenharmony_ci		[CLK_BUS_EHCI3]		= &bus_ehci3_clk.common.hw,
96962306a36Sopenharmony_ci		[CLK_BUS_OTG]		= &bus_otg_clk.common.hw,
97062306a36Sopenharmony_ci		[CLK_BUS_KEYADC]	= &bus_keyadc_clk.common.hw,
97162306a36Sopenharmony_ci		[CLK_HDMI]		= &hdmi_clk.common.hw,
97262306a36Sopenharmony_ci		[CLK_HDMI_SLOW]		= &hdmi_slow_clk.common.hw,
97362306a36Sopenharmony_ci		[CLK_HDMI_CEC]		= &hdmi_cec_clk.common.hw,
97462306a36Sopenharmony_ci		[CLK_BUS_HDMI]		= &bus_hdmi_clk.common.hw,
97562306a36Sopenharmony_ci		[CLK_BUS_TCON_TOP]	= &bus_tcon_top_clk.common.hw,
97662306a36Sopenharmony_ci		[CLK_TCON_TV0]		= &tcon_tv0_clk.common.hw,
97762306a36Sopenharmony_ci		[CLK_TCON_TV1]		= &tcon_tv1_clk.common.hw,
97862306a36Sopenharmony_ci		[CLK_BUS_TCON_TV0]	= &bus_tcon_tv0_clk.common.hw,
97962306a36Sopenharmony_ci		[CLK_BUS_TCON_TV1]	= &bus_tcon_tv1_clk.common.hw,
98062306a36Sopenharmony_ci		[CLK_TVE0]		= &tve0_clk.common.hw,
98162306a36Sopenharmony_ci		[CLK_BUS_TVE_TOP]	= &bus_tve_top_clk.common.hw,
98262306a36Sopenharmony_ci		[CLK_BUS_TVE0]		= &bus_tve0_clk.common.hw,
98362306a36Sopenharmony_ci		[CLK_HDCP]		= &hdcp_clk.common.hw,
98462306a36Sopenharmony_ci		[CLK_BUS_HDCP]		= &bus_hdcp_clk.common.hw,
98562306a36Sopenharmony_ci	},
98662306a36Sopenharmony_ci	.num = CLK_NUMBER,
98762306a36Sopenharmony_ci};
98862306a36Sopenharmony_ci
98962306a36Sopenharmony_cistatic struct ccu_reset_map sun50i_h616_ccu_resets[] = {
99062306a36Sopenharmony_ci	[RST_MBUS]		= { 0x540, BIT(30) },
99162306a36Sopenharmony_ci
99262306a36Sopenharmony_ci	[RST_BUS_DE]		= { 0x60c, BIT(16) },
99362306a36Sopenharmony_ci	[RST_BUS_DEINTERLACE]	= { 0x62c, BIT(16) },
99462306a36Sopenharmony_ci	[RST_BUS_GPU]		= { 0x67c, BIT(16) },
99562306a36Sopenharmony_ci	[RST_BUS_CE]		= { 0x68c, BIT(16) },
99662306a36Sopenharmony_ci	[RST_BUS_VE]		= { 0x69c, BIT(16) },
99762306a36Sopenharmony_ci	[RST_BUS_DMA]		= { 0x70c, BIT(16) },
99862306a36Sopenharmony_ci	[RST_BUS_HSTIMER]	= { 0x73c, BIT(16) },
99962306a36Sopenharmony_ci	[RST_BUS_DBG]		= { 0x78c, BIT(16) },
100062306a36Sopenharmony_ci	[RST_BUS_PSI]		= { 0x79c, BIT(16) },
100162306a36Sopenharmony_ci	[RST_BUS_PWM]		= { 0x7ac, BIT(16) },
100262306a36Sopenharmony_ci	[RST_BUS_IOMMU]		= { 0x7bc, BIT(16) },
100362306a36Sopenharmony_ci	[RST_BUS_DRAM]		= { 0x80c, BIT(16) },
100462306a36Sopenharmony_ci	[RST_BUS_NAND]		= { 0x82c, BIT(16) },
100562306a36Sopenharmony_ci	[RST_BUS_MMC0]		= { 0x84c, BIT(16) },
100662306a36Sopenharmony_ci	[RST_BUS_MMC1]		= { 0x84c, BIT(17) },
100762306a36Sopenharmony_ci	[RST_BUS_MMC2]		= { 0x84c, BIT(18) },
100862306a36Sopenharmony_ci	[RST_BUS_UART0]		= { 0x90c, BIT(16) },
100962306a36Sopenharmony_ci	[RST_BUS_UART1]		= { 0x90c, BIT(17) },
101062306a36Sopenharmony_ci	[RST_BUS_UART2]		= { 0x90c, BIT(18) },
101162306a36Sopenharmony_ci	[RST_BUS_UART3]		= { 0x90c, BIT(19) },
101262306a36Sopenharmony_ci	[RST_BUS_UART4]		= { 0x90c, BIT(20) },
101362306a36Sopenharmony_ci	[RST_BUS_UART5]		= { 0x90c, BIT(21) },
101462306a36Sopenharmony_ci	[RST_BUS_I2C0]		= { 0x91c, BIT(16) },
101562306a36Sopenharmony_ci	[RST_BUS_I2C1]		= { 0x91c, BIT(17) },
101662306a36Sopenharmony_ci	[RST_BUS_I2C2]		= { 0x91c, BIT(18) },
101762306a36Sopenharmony_ci	[RST_BUS_I2C3]		= { 0x91c, BIT(19) },
101862306a36Sopenharmony_ci	[RST_BUS_I2C4]		= { 0x91c, BIT(20) },
101962306a36Sopenharmony_ci	[RST_BUS_SPI0]		= { 0x96c, BIT(16) },
102062306a36Sopenharmony_ci	[RST_BUS_SPI1]		= { 0x96c, BIT(17) },
102162306a36Sopenharmony_ci	[RST_BUS_EMAC0]		= { 0x97c, BIT(16) },
102262306a36Sopenharmony_ci	[RST_BUS_EMAC1]		= { 0x97c, BIT(17) },
102362306a36Sopenharmony_ci	[RST_BUS_TS]		= { 0x9bc, BIT(16) },
102462306a36Sopenharmony_ci	[RST_BUS_THS]		= { 0x9fc, BIT(16) },
102562306a36Sopenharmony_ci	[RST_BUS_SPDIF]		= { 0xa2c, BIT(16) },
102662306a36Sopenharmony_ci	[RST_BUS_DMIC]		= { 0xa4c, BIT(16) },
102762306a36Sopenharmony_ci	[RST_BUS_AUDIO_CODEC]	= { 0xa5c, BIT(16) },
102862306a36Sopenharmony_ci	[RST_BUS_AUDIO_HUB]	= { 0xa6c, BIT(16) },
102962306a36Sopenharmony_ci
103062306a36Sopenharmony_ci	[RST_USB_PHY0]		= { 0xa70, BIT(30) },
103162306a36Sopenharmony_ci	[RST_USB_PHY1]		= { 0xa74, BIT(30) },
103262306a36Sopenharmony_ci	[RST_USB_PHY2]		= { 0xa78, BIT(30) },
103362306a36Sopenharmony_ci	[RST_USB_PHY3]		= { 0xa7c, BIT(30) },
103462306a36Sopenharmony_ci	[RST_BUS_OHCI0]		= { 0xa8c, BIT(16) },
103562306a36Sopenharmony_ci	[RST_BUS_OHCI1]		= { 0xa8c, BIT(17) },
103662306a36Sopenharmony_ci	[RST_BUS_OHCI2]		= { 0xa8c, BIT(18) },
103762306a36Sopenharmony_ci	[RST_BUS_OHCI3]		= { 0xa8c, BIT(19) },
103862306a36Sopenharmony_ci	[RST_BUS_EHCI0]		= { 0xa8c, BIT(20) },
103962306a36Sopenharmony_ci	[RST_BUS_EHCI1]		= { 0xa8c, BIT(21) },
104062306a36Sopenharmony_ci	[RST_BUS_EHCI2]		= { 0xa8c, BIT(22) },
104162306a36Sopenharmony_ci	[RST_BUS_EHCI3]		= { 0xa8c, BIT(23) },
104262306a36Sopenharmony_ci	[RST_BUS_OTG]		= { 0xa8c, BIT(24) },
104362306a36Sopenharmony_ci	[RST_BUS_KEYADC]	= { 0xa9c, BIT(16) },
104462306a36Sopenharmony_ci
104562306a36Sopenharmony_ci	[RST_BUS_HDMI]		= { 0xb1c, BIT(16) },
104662306a36Sopenharmony_ci	[RST_BUS_HDMI_SUB]	= { 0xb1c, BIT(17) },
104762306a36Sopenharmony_ci	[RST_BUS_TCON_TOP]	= { 0xb5c, BIT(16) },
104862306a36Sopenharmony_ci	[RST_BUS_TCON_TV0]	= { 0xb9c, BIT(16) },
104962306a36Sopenharmony_ci	[RST_BUS_TCON_TV1]	= { 0xb9c, BIT(17) },
105062306a36Sopenharmony_ci	[RST_BUS_TVE_TOP]	= { 0xbbc, BIT(16) },
105162306a36Sopenharmony_ci	[RST_BUS_TVE0]		= { 0xbbc, BIT(17) },
105262306a36Sopenharmony_ci	[RST_BUS_HDCP]		= { 0xc4c, BIT(16) },
105362306a36Sopenharmony_ci};
105462306a36Sopenharmony_ci
105562306a36Sopenharmony_cistatic const struct sunxi_ccu_desc sun50i_h616_ccu_desc = {
105662306a36Sopenharmony_ci	.ccu_clks	= sun50i_h616_ccu_clks,
105762306a36Sopenharmony_ci	.num_ccu_clks	= ARRAY_SIZE(sun50i_h616_ccu_clks),
105862306a36Sopenharmony_ci
105962306a36Sopenharmony_ci	.hw_clks	= &sun50i_h616_hw_clks,
106062306a36Sopenharmony_ci
106162306a36Sopenharmony_ci	.resets		= sun50i_h616_ccu_resets,
106262306a36Sopenharmony_ci	.num_resets	= ARRAY_SIZE(sun50i_h616_ccu_resets),
106362306a36Sopenharmony_ci};
106462306a36Sopenharmony_ci
106562306a36Sopenharmony_cistatic const u32 pll_regs[] = {
106662306a36Sopenharmony_ci	SUN50I_H616_PLL_CPUX_REG,
106762306a36Sopenharmony_ci	SUN50I_H616_PLL_DDR0_REG,
106862306a36Sopenharmony_ci	SUN50I_H616_PLL_DDR1_REG,
106962306a36Sopenharmony_ci	SUN50I_H616_PLL_PERIPH0_REG,
107062306a36Sopenharmony_ci	SUN50I_H616_PLL_PERIPH1_REG,
107162306a36Sopenharmony_ci	SUN50I_H616_PLL_GPU_REG,
107262306a36Sopenharmony_ci	SUN50I_H616_PLL_VIDEO0_REG,
107362306a36Sopenharmony_ci	SUN50I_H616_PLL_VIDEO1_REG,
107462306a36Sopenharmony_ci	SUN50I_H616_PLL_VIDEO2_REG,
107562306a36Sopenharmony_ci	SUN50I_H616_PLL_VE_REG,
107662306a36Sopenharmony_ci	SUN50I_H616_PLL_DE_REG,
107762306a36Sopenharmony_ci	SUN50I_H616_PLL_AUDIO_REG,
107862306a36Sopenharmony_ci};
107962306a36Sopenharmony_ci
108062306a36Sopenharmony_cistatic const u32 pll_video_regs[] = {
108162306a36Sopenharmony_ci	SUN50I_H616_PLL_VIDEO0_REG,
108262306a36Sopenharmony_ci	SUN50I_H616_PLL_VIDEO1_REG,
108362306a36Sopenharmony_ci	SUN50I_H616_PLL_VIDEO2_REG,
108462306a36Sopenharmony_ci};
108562306a36Sopenharmony_ci
108662306a36Sopenharmony_cistatic const u32 usb2_clk_regs[] = {
108762306a36Sopenharmony_ci	SUN50I_H616_USB0_CLK_REG,
108862306a36Sopenharmony_ci	SUN50I_H616_USB1_CLK_REG,
108962306a36Sopenharmony_ci	SUN50I_H616_USB2_CLK_REG,
109062306a36Sopenharmony_ci	SUN50I_H616_USB3_CLK_REG,
109162306a36Sopenharmony_ci};
109262306a36Sopenharmony_ci
109362306a36Sopenharmony_cistatic int sun50i_h616_ccu_probe(struct platform_device *pdev)
109462306a36Sopenharmony_ci{
109562306a36Sopenharmony_ci	void __iomem *reg;
109662306a36Sopenharmony_ci	u32 val;
109762306a36Sopenharmony_ci	int i;
109862306a36Sopenharmony_ci
109962306a36Sopenharmony_ci	reg = devm_platform_ioremap_resource(pdev, 0);
110062306a36Sopenharmony_ci	if (IS_ERR(reg))
110162306a36Sopenharmony_ci		return PTR_ERR(reg);
110262306a36Sopenharmony_ci
110362306a36Sopenharmony_ci	/* Enable the lock bits and the output enable bits on all PLLs */
110462306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(pll_regs); i++) {
110562306a36Sopenharmony_ci		val = readl(reg + pll_regs[i]);
110662306a36Sopenharmony_ci		val |= BIT(29) | BIT(27);
110762306a36Sopenharmony_ci		writel(val, reg + pll_regs[i]);
110862306a36Sopenharmony_ci	}
110962306a36Sopenharmony_ci
111062306a36Sopenharmony_ci	/*
111162306a36Sopenharmony_ci	 * Force the output divider of video PLLs to 0.
111262306a36Sopenharmony_ci	 *
111362306a36Sopenharmony_ci	 * See the comment before pll-video0 definition for the reason.
111462306a36Sopenharmony_ci	 */
111562306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(pll_video_regs); i++) {
111662306a36Sopenharmony_ci		val = readl(reg + pll_video_regs[i]);
111762306a36Sopenharmony_ci		val &= ~BIT(0);
111862306a36Sopenharmony_ci		writel(val, reg + pll_video_regs[i]);
111962306a36Sopenharmony_ci	}
112062306a36Sopenharmony_ci
112162306a36Sopenharmony_ci	/*
112262306a36Sopenharmony_ci	 * Force OHCI 12M clock sources to 00 (12MHz divided from 48MHz)
112362306a36Sopenharmony_ci	 *
112462306a36Sopenharmony_ci	 * This clock mux is still mysterious, and the code just enforces
112562306a36Sopenharmony_ci	 * it to have a valid clock parent.
112662306a36Sopenharmony_ci	 */
112762306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(usb2_clk_regs); i++) {
112862306a36Sopenharmony_ci		val = readl(reg + usb2_clk_regs[i]);
112962306a36Sopenharmony_ci		val &= ~GENMASK(25, 24);
113062306a36Sopenharmony_ci		writel(val, reg + usb2_clk_regs[i]);
113162306a36Sopenharmony_ci	}
113262306a36Sopenharmony_ci
113362306a36Sopenharmony_ci	/*
113462306a36Sopenharmony_ci	 * Force the post-divider of pll-audio to 12 and the output divider
113562306a36Sopenharmony_ci	 * of it to 2, so 24576000 and 22579200 rates can be set exactly.
113662306a36Sopenharmony_ci	 */
113762306a36Sopenharmony_ci	val = readl(reg + SUN50I_H616_PLL_AUDIO_REG);
113862306a36Sopenharmony_ci	val &= ~(GENMASK(21, 16) | BIT(0));
113962306a36Sopenharmony_ci	writel(val | (11 << 16) | BIT(0), reg + SUN50I_H616_PLL_AUDIO_REG);
114062306a36Sopenharmony_ci
114162306a36Sopenharmony_ci	/*
114262306a36Sopenharmony_ci	 * First clock parent (osc32K) is unusable for CEC. But since there
114362306a36Sopenharmony_ci	 * is no good way to force parent switch (both run with same frequency),
114462306a36Sopenharmony_ci	 * just set second clock parent here.
114562306a36Sopenharmony_ci	 */
114662306a36Sopenharmony_ci	val = readl(reg + SUN50I_H616_HDMI_CEC_CLK_REG);
114762306a36Sopenharmony_ci	val |= BIT(24);
114862306a36Sopenharmony_ci	writel(val, reg + SUN50I_H616_HDMI_CEC_CLK_REG);
114962306a36Sopenharmony_ci
115062306a36Sopenharmony_ci	return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h616_ccu_desc);
115162306a36Sopenharmony_ci}
115262306a36Sopenharmony_ci
115362306a36Sopenharmony_cistatic const struct of_device_id sun50i_h616_ccu_ids[] = {
115462306a36Sopenharmony_ci	{ .compatible = "allwinner,sun50i-h616-ccu" },
115562306a36Sopenharmony_ci	{ }
115662306a36Sopenharmony_ci};
115762306a36Sopenharmony_ci
115862306a36Sopenharmony_cistatic struct platform_driver sun50i_h616_ccu_driver = {
115962306a36Sopenharmony_ci	.probe	= sun50i_h616_ccu_probe,
116062306a36Sopenharmony_ci	.driver	= {
116162306a36Sopenharmony_ci		.name			= "sun50i-h616-ccu",
116262306a36Sopenharmony_ci		.suppress_bind_attrs	= true,
116362306a36Sopenharmony_ci		.of_match_table		= sun50i_h616_ccu_ids,
116462306a36Sopenharmony_ci	},
116562306a36Sopenharmony_ci};
116662306a36Sopenharmony_cimodule_platform_driver(sun50i_h616_ccu_driver);
116762306a36Sopenharmony_ci
116862306a36Sopenharmony_ciMODULE_IMPORT_NS(SUNXI_CCU);
116962306a36Sopenharmony_ciMODULE_LICENSE("GPL");
1170