162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (c) 2020 huangzhenwei@allwinnertech.com
462306a36Sopenharmony_ci * Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include <linux/clk-provider.h>
862306a36Sopenharmony_ci#include <linux/io.h>
962306a36Sopenharmony_ci#include <linux/module.h>
1062306a36Sopenharmony_ci#include <linux/platform_device.h>
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include "../clk.h"
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include "ccu_common.h"
1562306a36Sopenharmony_ci#include "ccu_reset.h"
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#include "ccu_div.h"
1862306a36Sopenharmony_ci#include "ccu_gate.h"
1962306a36Sopenharmony_ci#include "ccu_mp.h"
2062306a36Sopenharmony_ci#include "ccu_mult.h"
2162306a36Sopenharmony_ci#include "ccu_nk.h"
2262306a36Sopenharmony_ci#include "ccu_nkm.h"
2362306a36Sopenharmony_ci#include "ccu_nkmp.h"
2462306a36Sopenharmony_ci#include "ccu_nm.h"
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci#include "ccu-sun20i-d1.h"
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_cistatic const struct clk_parent_data osc24M[] = {
2962306a36Sopenharmony_ci	{ .fw_name = "hosc" }
3062306a36Sopenharmony_ci};
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci/*
3362306a36Sopenharmony_ci * For the CPU PLL, the output divider is described as "only for testing"
3462306a36Sopenharmony_ci * in the user manual. So it's not modelled and forced to 0.
3562306a36Sopenharmony_ci */
3662306a36Sopenharmony_ci#define SUN20I_D1_PLL_CPUX_REG		0x000
3762306a36Sopenharmony_cistatic struct ccu_mult pll_cpux_clk = {
3862306a36Sopenharmony_ci	.enable		= BIT(27),
3962306a36Sopenharmony_ci	.lock		= BIT(28),
4062306a36Sopenharmony_ci	.mult		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
4162306a36Sopenharmony_ci	.common		= {
4262306a36Sopenharmony_ci		.reg		= 0x000,
4362306a36Sopenharmony_ci		.hw.init	= CLK_HW_INIT_PARENTS_DATA("pll-cpux", osc24M,
4462306a36Sopenharmony_ci							   &ccu_mult_ops,
4562306a36Sopenharmony_ci							   CLK_SET_RATE_UNGATE),
4662306a36Sopenharmony_ci	},
4762306a36Sopenharmony_ci};
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci/* Some PLLs are input * N / div1 / P. Model them as NKMP with no K */
5062306a36Sopenharmony_ci#define SUN20I_D1_PLL_DDR0_REG		0x010
5162306a36Sopenharmony_cistatic struct ccu_nkmp pll_ddr0_clk = {
5262306a36Sopenharmony_ci	.enable		= BIT(27),
5362306a36Sopenharmony_ci	.lock		= BIT(28),
5462306a36Sopenharmony_ci	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
5562306a36Sopenharmony_ci	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
5662306a36Sopenharmony_ci	.p		= _SUNXI_CCU_DIV(0, 1), /* output divider */
5762306a36Sopenharmony_ci	.common		= {
5862306a36Sopenharmony_ci		.reg		= 0x010,
5962306a36Sopenharmony_ci		.hw.init	= CLK_HW_INIT_PARENTS_DATA("pll-ddr0", osc24M,
6062306a36Sopenharmony_ci							   &ccu_nkmp_ops,
6162306a36Sopenharmony_ci							   CLK_SET_RATE_UNGATE),
6262306a36Sopenharmony_ci	},
6362306a36Sopenharmony_ci};
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci#define SUN20I_D1_PLL_PERIPH0_REG	0x020
6662306a36Sopenharmony_cistatic struct ccu_nm pll_periph0_4x_clk = {
6762306a36Sopenharmony_ci	.enable		= BIT(27),
6862306a36Sopenharmony_ci	.lock		= BIT(28),
6962306a36Sopenharmony_ci	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
7062306a36Sopenharmony_ci	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
7162306a36Sopenharmony_ci	.common		= {
7262306a36Sopenharmony_ci		.reg		= 0x020,
7362306a36Sopenharmony_ci		.hw.init	= CLK_HW_INIT_PARENTS_DATA("pll-periph0-4x", osc24M,
7462306a36Sopenharmony_ci							   &ccu_nm_ops,
7562306a36Sopenharmony_ci							   CLK_SET_RATE_UNGATE),
7662306a36Sopenharmony_ci	},
7762306a36Sopenharmony_ci};
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_cistatic const struct clk_hw *pll_periph0_4x_hws[] = {
8062306a36Sopenharmony_ci	&pll_periph0_4x_clk.common.hw
8162306a36Sopenharmony_ci};
8262306a36Sopenharmony_cistatic SUNXI_CCU_M_HWS(pll_periph0_2x_clk, "pll-periph0-2x",
8362306a36Sopenharmony_ci		       pll_periph0_4x_hws, 0x020, 16, 3, 0);
8462306a36Sopenharmony_cistatic SUNXI_CCU_M_HWS(pll_periph0_800M_clk, "pll-periph0-800M",
8562306a36Sopenharmony_ci		       pll_periph0_4x_hws, 0x020, 20, 3, 0);
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_cistatic const struct clk_hw *pll_periph0_2x_hws[] = {
8862306a36Sopenharmony_ci	&pll_periph0_2x_clk.common.hw
8962306a36Sopenharmony_ci};
9062306a36Sopenharmony_cistatic CLK_FIXED_FACTOR_HWS(pll_periph0_clk, "pll-periph0",
9162306a36Sopenharmony_ci			    pll_periph0_2x_hws, 2, 1, 0);
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_cistatic const struct clk_hw *pll_periph0_hws[] = { &pll_periph0_clk.hw };
9462306a36Sopenharmony_cistatic CLK_FIXED_FACTOR_HWS(pll_periph0_div3_clk, "pll-periph0-div3",
9562306a36Sopenharmony_ci			    pll_periph0_2x_hws, 6, 1, 0);
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci/*
9862306a36Sopenharmony_ci * For Video PLLs, the output divider is described as "only for testing"
9962306a36Sopenharmony_ci * in the user manual. So it's not modelled and forced to 0.
10062306a36Sopenharmony_ci */
10162306a36Sopenharmony_ci#define SUN20I_D1_PLL_VIDEO0_REG	0x040
10262306a36Sopenharmony_cistatic struct ccu_nm pll_video0_4x_clk = {
10362306a36Sopenharmony_ci	.enable		= BIT(27),
10462306a36Sopenharmony_ci	.lock		= BIT(28),
10562306a36Sopenharmony_ci	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
10662306a36Sopenharmony_ci	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
10762306a36Sopenharmony_ci	.min_rate	= 252000000U,
10862306a36Sopenharmony_ci	.max_rate	= 2400000000U,
10962306a36Sopenharmony_ci	.common		= {
11062306a36Sopenharmony_ci		.reg		= 0x040,
11162306a36Sopenharmony_ci		.hw.init	= CLK_HW_INIT_PARENTS_DATA("pll-video0-4x", osc24M,
11262306a36Sopenharmony_ci							   &ccu_nm_ops,
11362306a36Sopenharmony_ci							   CLK_SET_RATE_UNGATE),
11462306a36Sopenharmony_ci	},
11562306a36Sopenharmony_ci};
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_cistatic const struct clk_hw *pll_video0_4x_hws[] = {
11862306a36Sopenharmony_ci	&pll_video0_4x_clk.common.hw
11962306a36Sopenharmony_ci};
12062306a36Sopenharmony_cistatic CLK_FIXED_FACTOR_HWS(pll_video0_2x_clk, "pll-video0-2x",
12162306a36Sopenharmony_ci			    pll_video0_4x_hws, 2, 1, CLK_SET_RATE_PARENT);
12262306a36Sopenharmony_cistatic CLK_FIXED_FACTOR_HWS(pll_video0_clk, "pll-video0",
12362306a36Sopenharmony_ci			    pll_video0_4x_hws, 4, 1, CLK_SET_RATE_PARENT);
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci#define SUN20I_D1_PLL_VIDEO1_REG	0x048
12662306a36Sopenharmony_cistatic struct ccu_nm pll_video1_4x_clk = {
12762306a36Sopenharmony_ci	.enable		= BIT(27),
12862306a36Sopenharmony_ci	.lock		= BIT(28),
12962306a36Sopenharmony_ci	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
13062306a36Sopenharmony_ci	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
13162306a36Sopenharmony_ci	.min_rate	= 252000000U,
13262306a36Sopenharmony_ci	.max_rate	= 2400000000U,
13362306a36Sopenharmony_ci	.common		= {
13462306a36Sopenharmony_ci		.reg		= 0x048,
13562306a36Sopenharmony_ci		.hw.init	= CLK_HW_INIT_PARENTS_DATA("pll-video1-4x", osc24M,
13662306a36Sopenharmony_ci							   &ccu_nm_ops,
13762306a36Sopenharmony_ci							   CLK_SET_RATE_UNGATE),
13862306a36Sopenharmony_ci	},
13962306a36Sopenharmony_ci};
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_cistatic const struct clk_hw *pll_video1_4x_hws[] = {
14262306a36Sopenharmony_ci	&pll_video1_4x_clk.common.hw
14362306a36Sopenharmony_ci};
14462306a36Sopenharmony_cistatic CLK_FIXED_FACTOR_HWS(pll_video1_2x_clk, "pll-video1-2x",
14562306a36Sopenharmony_ci			    pll_video1_4x_hws, 2, 1, CLK_SET_RATE_PARENT);
14662306a36Sopenharmony_cistatic CLK_FIXED_FACTOR_HWS(pll_video1_clk, "pll-video1",
14762306a36Sopenharmony_ci			    pll_video1_4x_hws, 4, 1, CLK_SET_RATE_PARENT);
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci#define SUN20I_D1_PLL_VE_REG		0x058
15062306a36Sopenharmony_cistatic struct ccu_nkmp pll_ve_clk = {
15162306a36Sopenharmony_ci	.enable		= BIT(27),
15262306a36Sopenharmony_ci	.lock		= BIT(28),
15362306a36Sopenharmony_ci	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
15462306a36Sopenharmony_ci	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
15562306a36Sopenharmony_ci	.p		= _SUNXI_CCU_DIV(0, 1), /* output divider */
15662306a36Sopenharmony_ci	.common		= {
15762306a36Sopenharmony_ci		.reg		= 0x058,
15862306a36Sopenharmony_ci		.hw.init	= CLK_HW_INIT_PARENTS_DATA("pll-ve", osc24M,
15962306a36Sopenharmony_ci							   &ccu_nkmp_ops,
16062306a36Sopenharmony_ci							   CLK_SET_RATE_UNGATE),
16162306a36Sopenharmony_ci	},
16262306a36Sopenharmony_ci};
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci/*
16562306a36Sopenharmony_ci * PLL_AUDIO0 has m0, m1 dividers in addition to the usual N, M factors.
16662306a36Sopenharmony_ci * Since we only need one frequency from this PLL (22.5792 x 4 == 90.3168 MHz),
16762306a36Sopenharmony_ci * ignore them for now. Enforce the default for them, which is m1 = 0, m0 = 0.
16862306a36Sopenharmony_ci * The M factor must be an even number to produce a 50% duty cycle output.
16962306a36Sopenharmony_ci */
17062306a36Sopenharmony_ci#define SUN20I_D1_PLL_AUDIO0_REG		0x078
17162306a36Sopenharmony_cistatic struct ccu_sdm_setting pll_audio0_sdm_table[] = {
17262306a36Sopenharmony_ci	{ .rate = 90316800, .pattern = 0xc001288d, .m = 6, .n = 22 },
17362306a36Sopenharmony_ci};
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_cistatic struct ccu_nm pll_audio0_4x_clk = {
17662306a36Sopenharmony_ci	.enable		= BIT(27),
17762306a36Sopenharmony_ci	.lock		= BIT(28),
17862306a36Sopenharmony_ci	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
17962306a36Sopenharmony_ci	.m		= _SUNXI_CCU_DIV(16, 6),
18062306a36Sopenharmony_ci	.sdm		= _SUNXI_CCU_SDM(pll_audio0_sdm_table, BIT(24),
18162306a36Sopenharmony_ci					 0x178, BIT(31)),
18262306a36Sopenharmony_ci	.min_rate	= 180000000U,
18362306a36Sopenharmony_ci	.max_rate	= 3000000000U,
18462306a36Sopenharmony_ci	.common		= {
18562306a36Sopenharmony_ci		.reg		= 0x078,
18662306a36Sopenharmony_ci		.features	= CCU_FEATURE_SIGMA_DELTA_MOD,
18762306a36Sopenharmony_ci		.hw.init	= CLK_HW_INIT_PARENTS_DATA("pll-audio0-4x", osc24M,
18862306a36Sopenharmony_ci							   &ccu_nm_ops,
18962306a36Sopenharmony_ci							   CLK_SET_RATE_UNGATE),
19062306a36Sopenharmony_ci	},
19162306a36Sopenharmony_ci};
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_cistatic const struct clk_hw *pll_audio0_4x_hws[] = {
19462306a36Sopenharmony_ci	&pll_audio0_4x_clk.common.hw
19562306a36Sopenharmony_ci};
19662306a36Sopenharmony_cistatic CLK_FIXED_FACTOR_HWS(pll_audio0_2x_clk, "pll-audio0-2x",
19762306a36Sopenharmony_ci			    pll_audio0_4x_hws, 2, 1, 0);
19862306a36Sopenharmony_cistatic CLK_FIXED_FACTOR_HWS(pll_audio0_clk, "pll-audio0",
19962306a36Sopenharmony_ci			    pll_audio0_4x_hws, 4, 1, 0);
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci/*
20262306a36Sopenharmony_ci * PLL_AUDIO1 doesn't need Fractional-N. The output is usually 614.4 MHz for
20362306a36Sopenharmony_ci * audio. The ADC or DAC should divide the PLL output further to 24.576 MHz.
20462306a36Sopenharmony_ci */
20562306a36Sopenharmony_ci#define SUN20I_D1_PLL_AUDIO1_REG		0x080
20662306a36Sopenharmony_cistatic struct ccu_nm pll_audio1_clk = {
20762306a36Sopenharmony_ci	.enable		= BIT(27),
20862306a36Sopenharmony_ci	.lock		= BIT(28),
20962306a36Sopenharmony_ci	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
21062306a36Sopenharmony_ci	.m		= _SUNXI_CCU_DIV(1, 1),
21162306a36Sopenharmony_ci	.min_rate	= 180000000U,
21262306a36Sopenharmony_ci	.max_rate	= 3000000000U,
21362306a36Sopenharmony_ci	.common		= {
21462306a36Sopenharmony_ci		.reg		= 0x080,
21562306a36Sopenharmony_ci		.hw.init	= CLK_HW_INIT_PARENTS_DATA("pll-audio1", osc24M,
21662306a36Sopenharmony_ci							   &ccu_nm_ops,
21762306a36Sopenharmony_ci							   CLK_SET_RATE_UNGATE),
21862306a36Sopenharmony_ci	},
21962306a36Sopenharmony_ci};
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_cistatic const struct clk_hw *pll_audio1_hws[] = {
22262306a36Sopenharmony_ci	&pll_audio1_clk.common.hw
22362306a36Sopenharmony_ci};
22462306a36Sopenharmony_cistatic SUNXI_CCU_M_HWS(pll_audio1_div2_clk, "pll-audio1-div2",
22562306a36Sopenharmony_ci		       pll_audio1_hws, 0x080, 16, 3, 0);
22662306a36Sopenharmony_cistatic SUNXI_CCU_M_HWS(pll_audio1_div5_clk, "pll-audio1-div5",
22762306a36Sopenharmony_ci		       pll_audio1_hws, 0x080, 20, 3, 0);
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ci/*
23062306a36Sopenharmony_ci * The CPUX gate is not modelled - it is in a separate register (0x504)
23162306a36Sopenharmony_ci * and has a special key field. The clock does not need to be ungated anyway.
23262306a36Sopenharmony_ci */
23362306a36Sopenharmony_cistatic const struct clk_parent_data cpux_parents[] = {
23462306a36Sopenharmony_ci	{ .fw_name = "hosc" },
23562306a36Sopenharmony_ci	{ .fw_name = "losc" },
23662306a36Sopenharmony_ci	{ .fw_name = "iosc" },
23762306a36Sopenharmony_ci	{ .hw = &pll_cpux_clk.common.hw },
23862306a36Sopenharmony_ci	{ .hw = &pll_periph0_clk.hw },
23962306a36Sopenharmony_ci	{ .hw = &pll_periph0_2x_clk.common.hw },
24062306a36Sopenharmony_ci	{ .hw = &pll_periph0_800M_clk.common.hw },
24162306a36Sopenharmony_ci};
24262306a36Sopenharmony_cistatic SUNXI_CCU_MUX_DATA(cpux_clk, "cpux", cpux_parents,
24362306a36Sopenharmony_ci			  0x500, 24, 3, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_cistatic const struct clk_hw *cpux_hws[] = { &cpux_clk.common.hw };
24662306a36Sopenharmony_cistatic SUNXI_CCU_M_HWS(cpux_axi_clk, "cpux-axi",
24762306a36Sopenharmony_ci		       cpux_hws, 0x500, 0, 2, 0);
24862306a36Sopenharmony_cistatic SUNXI_CCU_M_HWS(cpux_apb_clk, "cpux-apb",
24962306a36Sopenharmony_ci		       cpux_hws, 0x500, 8, 2, 0);
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_cistatic const struct clk_parent_data psi_ahb_parents[] = {
25262306a36Sopenharmony_ci	{ .fw_name = "hosc" },
25362306a36Sopenharmony_ci	{ .fw_name = "losc" },
25462306a36Sopenharmony_ci	{ .fw_name = "iosc" },
25562306a36Sopenharmony_ci	{ .hw = &pll_periph0_clk.hw },
25662306a36Sopenharmony_ci};
25762306a36Sopenharmony_cistatic SUNXI_CCU_MP_DATA_WITH_MUX(psi_ahb_clk, "psi-ahb", psi_ahb_parents, 0x510,
25862306a36Sopenharmony_ci				  0, 2,		/* M */
25962306a36Sopenharmony_ci				  8, 2,		/* P */
26062306a36Sopenharmony_ci				  24, 2,	/* mux */
26162306a36Sopenharmony_ci				  0);
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_cistatic const struct clk_parent_data apb0_apb1_parents[] = {
26462306a36Sopenharmony_ci	{ .fw_name = "hosc" },
26562306a36Sopenharmony_ci	{ .fw_name = "losc" },
26662306a36Sopenharmony_ci	{ .hw = &psi_ahb_clk.common.hw },
26762306a36Sopenharmony_ci	{ .hw = &pll_periph0_clk.hw },
26862306a36Sopenharmony_ci};
26962306a36Sopenharmony_cistatic SUNXI_CCU_MP_DATA_WITH_MUX(apb0_clk, "apb0", apb0_apb1_parents, 0x520,
27062306a36Sopenharmony_ci				  0, 5,		/* M */
27162306a36Sopenharmony_ci				  8, 2,		/* P */
27262306a36Sopenharmony_ci				  24, 2,	/* mux */
27362306a36Sopenharmony_ci				  0);
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_cistatic SUNXI_CCU_MP_DATA_WITH_MUX(apb1_clk, "apb1", apb0_apb1_parents, 0x524,
27662306a36Sopenharmony_ci				  0, 5,		/* M */
27762306a36Sopenharmony_ci				  8, 2,		/* P */
27862306a36Sopenharmony_ci				  24, 2,	/* mux */
27962306a36Sopenharmony_ci				  0);
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_cistatic const struct clk_hw *psi_ahb_hws[] = { &psi_ahb_clk.common.hw };
28262306a36Sopenharmony_cistatic const struct clk_hw *apb0_hws[] = { &apb0_clk.common.hw };
28362306a36Sopenharmony_cistatic const struct clk_hw *apb1_hws[] = { &apb1_clk.common.hw };
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_cistatic const struct clk_hw *de_di_g2d_parents[] = {
28662306a36Sopenharmony_ci	&pll_periph0_2x_clk.common.hw,
28762306a36Sopenharmony_ci	&pll_video0_4x_clk.common.hw,
28862306a36Sopenharmony_ci	&pll_video1_4x_clk.common.hw,
28962306a36Sopenharmony_ci	&pll_audio1_div2_clk.common.hw,
29062306a36Sopenharmony_ci};
29162306a36Sopenharmony_cistatic SUNXI_CCU_M_HW_WITH_MUX_GATE(de_clk, "de", de_di_g2d_parents, 0x600,
29262306a36Sopenharmony_ci				    0, 5,	/* M */
29362306a36Sopenharmony_ci				    24, 3,	/* mux */
29462306a36Sopenharmony_ci				    BIT(31),	/* gate */
29562306a36Sopenharmony_ci				    CLK_SET_RATE_PARENT);
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_de_clk, "bus-de", psi_ahb_hws,
29862306a36Sopenharmony_ci			  0x60c, BIT(0), 0);
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_cistatic SUNXI_CCU_M_HW_WITH_MUX_GATE(di_clk, "di", de_di_g2d_parents, 0x620,
30162306a36Sopenharmony_ci				    0, 5,	/* M */
30262306a36Sopenharmony_ci				    24, 3,	/* mux */
30362306a36Sopenharmony_ci				    BIT(31),	/* gate */
30462306a36Sopenharmony_ci				    CLK_SET_RATE_PARENT);
30562306a36Sopenharmony_ci
30662306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_di_clk, "bus-di", psi_ahb_hws,
30762306a36Sopenharmony_ci			  0x62c, BIT(0), 0);
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_cistatic SUNXI_CCU_M_HW_WITH_MUX_GATE(g2d_clk, "g2d", de_di_g2d_parents, 0x630,
31062306a36Sopenharmony_ci				    0, 5,	/* M */
31162306a36Sopenharmony_ci				    24, 3,	/* mux */
31262306a36Sopenharmony_ci				    BIT(31),	/* gate */
31362306a36Sopenharmony_ci				    0);
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_g2d_clk, "bus-g2d", psi_ahb_hws,
31662306a36Sopenharmony_ci			  0x63c, BIT(0), 0);
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_cistatic const struct clk_parent_data ce_parents[] = {
31962306a36Sopenharmony_ci	{ .fw_name = "hosc" },
32062306a36Sopenharmony_ci	{ .hw = &pll_periph0_2x_clk.common.hw },
32162306a36Sopenharmony_ci	{ .hw = &pll_periph0_clk.hw },
32262306a36Sopenharmony_ci};
32362306a36Sopenharmony_cistatic SUNXI_CCU_MP_DATA_WITH_MUX_GATE(ce_clk, "ce", ce_parents, 0x680,
32462306a36Sopenharmony_ci				       0, 4,	/* M */
32562306a36Sopenharmony_ci				       8, 2,	/* P */
32662306a36Sopenharmony_ci				       24, 3,	/* mux */
32762306a36Sopenharmony_ci				       BIT(31),	/* gate */
32862306a36Sopenharmony_ci				       0);
32962306a36Sopenharmony_ci
33062306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_ce_clk, "bus-ce", psi_ahb_hws,
33162306a36Sopenharmony_ci			  0x68c, BIT(0), 0);
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_cistatic const struct clk_hw *ve_parents[] = {
33462306a36Sopenharmony_ci	&pll_ve_clk.common.hw,
33562306a36Sopenharmony_ci	&pll_periph0_2x_clk.common.hw,
33662306a36Sopenharmony_ci};
33762306a36Sopenharmony_cistatic SUNXI_CCU_M_HW_WITH_MUX_GATE(ve_clk, "ve", ve_parents, 0x690,
33862306a36Sopenharmony_ci				    0, 5,	/* M */
33962306a36Sopenharmony_ci				    24, 1,	/* mux */
34062306a36Sopenharmony_ci				    BIT(31),	/* gate */
34162306a36Sopenharmony_ci				    CLK_SET_RATE_PARENT);
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_ve_clk, "bus-ve", psi_ahb_hws,
34462306a36Sopenharmony_ci			  0x69c, BIT(0), 0);
34562306a36Sopenharmony_ci
34662306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_dma_clk, "bus-dma", psi_ahb_hws,
34762306a36Sopenharmony_ci			  0x70c, BIT(0), 0);
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_msgbox0_clk, "bus-msgbox0", psi_ahb_hws,
35062306a36Sopenharmony_ci			  0x71c, BIT(0), 0);
35162306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_msgbox1_clk, "bus-msgbox1", psi_ahb_hws,
35262306a36Sopenharmony_ci			  0x71c, BIT(1), 0);
35362306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_msgbox2_clk, "bus-msgbox2", psi_ahb_hws,
35462306a36Sopenharmony_ci			  0x71c, BIT(2), 0);
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_spinlock_clk, "bus-spinlock", psi_ahb_hws,
35762306a36Sopenharmony_ci			  0x72c, BIT(0), 0);
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_hstimer_clk, "bus-hstimer", psi_ahb_hws,
36062306a36Sopenharmony_ci			  0x73c, BIT(0), 0);
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_cistatic SUNXI_CCU_GATE_DATA(avs_clk, "avs", osc24M,
36362306a36Sopenharmony_ci			   0x740, BIT(31), 0);
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_dbg_clk, "bus-dbg", psi_ahb_hws,
36662306a36Sopenharmony_ci			  0x78c, BIT(0), 0);
36762306a36Sopenharmony_ci
36862306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_pwm_clk, "bus-pwm", apb0_hws,
36962306a36Sopenharmony_ci			  0x7ac, BIT(0), 0);
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_iommu_clk, "bus-iommu", apb0_hws,
37262306a36Sopenharmony_ci			  0x7bc, BIT(0), 0);
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_cistatic const struct clk_hw *dram_parents[] = {
37562306a36Sopenharmony_ci	&pll_ddr0_clk.common.hw,
37662306a36Sopenharmony_ci	&pll_audio1_div2_clk.common.hw,
37762306a36Sopenharmony_ci	&pll_periph0_2x_clk.common.hw,
37862306a36Sopenharmony_ci	&pll_periph0_800M_clk.common.hw,
37962306a36Sopenharmony_ci};
38062306a36Sopenharmony_cistatic SUNXI_CCU_MP_HW_WITH_MUX_GATE(dram_clk, "dram", dram_parents, 0x800,
38162306a36Sopenharmony_ci				     0, 2,	/* M */
38262306a36Sopenharmony_ci				     8, 2,	/* P */
38362306a36Sopenharmony_ci				     24, 2,	/* mux */
38462306a36Sopenharmony_ci				     BIT(31), CLK_IS_CRITICAL);
38562306a36Sopenharmony_ci
38662306a36Sopenharmony_cistatic CLK_FIXED_FACTOR_HW(mbus_clk, "mbus",
38762306a36Sopenharmony_ci			   &dram_clk.common.hw, 4, 1, 0);
38862306a36Sopenharmony_ci
38962306a36Sopenharmony_cistatic const struct clk_hw *mbus_hws[] = { &mbus_clk.hw };
39062306a36Sopenharmony_ci
39162306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(mbus_dma_clk, "mbus-dma", mbus_hws,
39262306a36Sopenharmony_ci			  0x804, BIT(0), 0);
39362306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(mbus_ve_clk, "mbus-ve", mbus_hws,
39462306a36Sopenharmony_ci			  0x804, BIT(1), 0);
39562306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(mbus_ce_clk, "mbus-ce", mbus_hws,
39662306a36Sopenharmony_ci			  0x804, BIT(2), 0);
39762306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(mbus_tvin_clk, "mbus-tvin", mbus_hws,
39862306a36Sopenharmony_ci			  0x804, BIT(7), 0);
39962306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(mbus_csi_clk, "mbus-csi", mbus_hws,
40062306a36Sopenharmony_ci			  0x804, BIT(8), 0);
40162306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(mbus_g2d_clk, "mbus-g2d", mbus_hws,
40262306a36Sopenharmony_ci			  0x804, BIT(10), 0);
40362306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(mbus_riscv_clk, "mbus-riscv", mbus_hws,
40462306a36Sopenharmony_ci			  0x804, BIT(11), 0);
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_dram_clk, "bus-dram", psi_ahb_hws,
40762306a36Sopenharmony_ci			  0x80c, BIT(0), CLK_IS_CRITICAL);
40862306a36Sopenharmony_ci
40962306a36Sopenharmony_cistatic const struct clk_parent_data mmc0_mmc1_parents[] = {
41062306a36Sopenharmony_ci	{ .fw_name = "hosc" },
41162306a36Sopenharmony_ci	{ .hw = &pll_periph0_clk.hw },
41262306a36Sopenharmony_ci	{ .hw = &pll_periph0_2x_clk.common.hw },
41362306a36Sopenharmony_ci	{ .hw = &pll_audio1_div2_clk.common.hw },
41462306a36Sopenharmony_ci};
41562306a36Sopenharmony_cistatic SUNXI_CCU_MP_DATA_WITH_MUX_GATE(mmc0_clk, "mmc0", mmc0_mmc1_parents, 0x830,
41662306a36Sopenharmony_ci				       0, 4,	/* M */
41762306a36Sopenharmony_ci				       8, 2,	/* P */
41862306a36Sopenharmony_ci				       24, 3,	/* mux */
41962306a36Sopenharmony_ci				       BIT(31),	/* gate */
42062306a36Sopenharmony_ci				       0);
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_cistatic SUNXI_CCU_MP_DATA_WITH_MUX_GATE(mmc1_clk, "mmc1", mmc0_mmc1_parents, 0x834,
42362306a36Sopenharmony_ci				       0, 4,	/* M */
42462306a36Sopenharmony_ci				       8, 2,	/* P */
42562306a36Sopenharmony_ci				       24, 3,	/* mux */
42662306a36Sopenharmony_ci				       BIT(31),	/* gate */
42762306a36Sopenharmony_ci				       0);
42862306a36Sopenharmony_ci
42962306a36Sopenharmony_cistatic const struct clk_parent_data mmc2_parents[] = {
43062306a36Sopenharmony_ci	{ .fw_name = "hosc" },
43162306a36Sopenharmony_ci	{ .hw = &pll_periph0_clk.hw },
43262306a36Sopenharmony_ci	{ .hw = &pll_periph0_2x_clk.common.hw },
43362306a36Sopenharmony_ci	{ .hw = &pll_periph0_800M_clk.common.hw },
43462306a36Sopenharmony_ci	{ .hw = &pll_audio1_div2_clk.common.hw },
43562306a36Sopenharmony_ci};
43662306a36Sopenharmony_cistatic SUNXI_CCU_MP_DATA_WITH_MUX_GATE(mmc2_clk, "mmc2", mmc2_parents, 0x838,
43762306a36Sopenharmony_ci				       0, 4,	/* M */
43862306a36Sopenharmony_ci				       8, 2,	/* P */
43962306a36Sopenharmony_ci				       24, 3,	/* mux */
44062306a36Sopenharmony_ci				       BIT(31),	/* gate */
44162306a36Sopenharmony_ci				       0);
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_mmc0_clk, "bus-mmc0", psi_ahb_hws,
44462306a36Sopenharmony_ci			  0x84c, BIT(0), 0);
44562306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_mmc1_clk, "bus-mmc1", psi_ahb_hws,
44662306a36Sopenharmony_ci			  0x84c, BIT(1), 0);
44762306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_mmc2_clk, "bus-mmc2", psi_ahb_hws,
44862306a36Sopenharmony_ci			  0x84c, BIT(2), 0);
44962306a36Sopenharmony_ci
45062306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_uart0_clk, "bus-uart0", apb1_hws,
45162306a36Sopenharmony_ci			  0x90c, BIT(0), 0);
45262306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_uart1_clk, "bus-uart1", apb1_hws,
45362306a36Sopenharmony_ci			  0x90c, BIT(1), 0);
45462306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_uart2_clk, "bus-uart2", apb1_hws,
45562306a36Sopenharmony_ci			  0x90c, BIT(2), 0);
45662306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_uart3_clk, "bus-uart3", apb1_hws,
45762306a36Sopenharmony_ci			  0x90c, BIT(3), 0);
45862306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_uart4_clk, "bus-uart4", apb1_hws,
45962306a36Sopenharmony_ci			  0x90c, BIT(4), 0);
46062306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_uart5_clk, "bus-uart5", apb1_hws,
46162306a36Sopenharmony_ci			  0x90c, BIT(5), 0);
46262306a36Sopenharmony_ci
46362306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_i2c0_clk, "bus-i2c0", apb1_hws,
46462306a36Sopenharmony_ci			  0x91c, BIT(0), 0);
46562306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_i2c1_clk, "bus-i2c1", apb1_hws,
46662306a36Sopenharmony_ci			  0x91c, BIT(1), 0);
46762306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_i2c2_clk, "bus-i2c2", apb1_hws,
46862306a36Sopenharmony_ci			  0x91c, BIT(2), 0);
46962306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_i2c3_clk, "bus-i2c3", apb1_hws,
47062306a36Sopenharmony_ci			  0x91c, BIT(3), 0);
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_can0_clk, "bus-can0", apb1_hws,
47362306a36Sopenharmony_ci			  0x92c, BIT(0), 0);
47462306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_can1_clk, "bus-can1", apb1_hws,
47562306a36Sopenharmony_ci			  0x92c, BIT(1), 0);
47662306a36Sopenharmony_ci
47762306a36Sopenharmony_cistatic const struct clk_parent_data spi_parents[] = {
47862306a36Sopenharmony_ci	{ .fw_name = "hosc" },
47962306a36Sopenharmony_ci	{ .hw = &pll_periph0_clk.hw },
48062306a36Sopenharmony_ci	{ .hw = &pll_periph0_2x_clk.common.hw },
48162306a36Sopenharmony_ci	{ .hw = &pll_audio1_div2_clk.common.hw },
48262306a36Sopenharmony_ci	{ .hw = &pll_audio1_div5_clk.common.hw },
48362306a36Sopenharmony_ci};
48462306a36Sopenharmony_cistatic SUNXI_CCU_MP_DATA_WITH_MUX_GATE(spi0_clk, "spi0", spi_parents, 0x940,
48562306a36Sopenharmony_ci				       0, 4,	/* M */
48662306a36Sopenharmony_ci				       8, 2,	/* P */
48762306a36Sopenharmony_ci				       24, 3,	/* mux */
48862306a36Sopenharmony_ci				       BIT(31),	/* gate */
48962306a36Sopenharmony_ci				       0);
49062306a36Sopenharmony_ci
49162306a36Sopenharmony_cistatic SUNXI_CCU_MP_DATA_WITH_MUX_GATE(spi1_clk, "spi1", spi_parents, 0x944,
49262306a36Sopenharmony_ci				       0, 4,	/* M */
49362306a36Sopenharmony_ci				       8, 2,	/* P */
49462306a36Sopenharmony_ci				       24, 3,	/* mux */
49562306a36Sopenharmony_ci				       BIT(31),	/* gate */
49662306a36Sopenharmony_ci				       0);
49762306a36Sopenharmony_ci
49862306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_spi0_clk, "bus-spi0", psi_ahb_hws,
49962306a36Sopenharmony_ci			  0x96c, BIT(0), 0);
50062306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_spi1_clk, "bus-spi1", psi_ahb_hws,
50162306a36Sopenharmony_ci			  0x96c, BIT(1), 0);
50262306a36Sopenharmony_ci
50362306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS_WITH_PREDIV(emac_25M_clk, "emac-25M", pll_periph0_hws,
50462306a36Sopenharmony_ci				      0x970, BIT(31) | BIT(30), 24, 0);
50562306a36Sopenharmony_ci
50662306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_emac_clk, "bus-emac", psi_ahb_hws,
50762306a36Sopenharmony_ci			  0x97c, BIT(0), 0);
50862306a36Sopenharmony_ci
50962306a36Sopenharmony_cistatic const struct clk_parent_data ir_tx_ledc_parents[] = {
51062306a36Sopenharmony_ci	{ .fw_name = "hosc" },
51162306a36Sopenharmony_ci	{ .hw = &pll_periph0_clk.hw },
51262306a36Sopenharmony_ci};
51362306a36Sopenharmony_cistatic SUNXI_CCU_MP_DATA_WITH_MUX_GATE(ir_tx_clk, "ir-tx", ir_tx_ledc_parents, 0x9c0,
51462306a36Sopenharmony_ci				       0, 4,	/* M */
51562306a36Sopenharmony_ci				       8, 2,	/* P */
51662306a36Sopenharmony_ci				       24, 3,	/* mux */
51762306a36Sopenharmony_ci				       BIT(31),	/* gate */
51862306a36Sopenharmony_ci				       0);
51962306a36Sopenharmony_ci
52062306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_ir_tx_clk, "bus-ir-tx", apb0_hws,
52162306a36Sopenharmony_ci			  0x9cc, BIT(0), 0);
52262306a36Sopenharmony_ci
52362306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_gpadc_clk, "bus-gpadc", apb0_hws,
52462306a36Sopenharmony_ci			  0x9ec, BIT(0), 0);
52562306a36Sopenharmony_ci
52662306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_ths_clk, "bus-ths", apb0_hws,
52762306a36Sopenharmony_ci			  0x9fc, BIT(0), 0);
52862306a36Sopenharmony_ci
52962306a36Sopenharmony_cistatic const struct clk_hw *i2s_spdif_tx_parents[] = {
53062306a36Sopenharmony_ci	&pll_audio0_clk.hw,
53162306a36Sopenharmony_ci	&pll_audio0_4x_clk.common.hw,
53262306a36Sopenharmony_ci	&pll_audio1_div2_clk.common.hw,
53362306a36Sopenharmony_ci	&pll_audio1_div5_clk.common.hw,
53462306a36Sopenharmony_ci};
53562306a36Sopenharmony_cistatic SUNXI_CCU_MP_HW_WITH_MUX_GATE(i2s0_clk, "i2s0", i2s_spdif_tx_parents, 0xa10,
53662306a36Sopenharmony_ci				     0, 5,	/* M */
53762306a36Sopenharmony_ci				     8, 2,	/* P */
53862306a36Sopenharmony_ci				     24, 3,	/* mux */
53962306a36Sopenharmony_ci				     BIT(31),	/* gate */
54062306a36Sopenharmony_ci				     0);
54162306a36Sopenharmony_ci
54262306a36Sopenharmony_cistatic SUNXI_CCU_MP_HW_WITH_MUX_GATE(i2s1_clk, "i2s1", i2s_spdif_tx_parents, 0xa14,
54362306a36Sopenharmony_ci				     0, 5,	/* M */
54462306a36Sopenharmony_ci				     8, 2,	/* P */
54562306a36Sopenharmony_ci				     24, 3,	/* mux */
54662306a36Sopenharmony_ci				     BIT(31),	/* gate */
54762306a36Sopenharmony_ci				     0);
54862306a36Sopenharmony_ci
54962306a36Sopenharmony_cistatic SUNXI_CCU_MP_HW_WITH_MUX_GATE(i2s2_clk, "i2s2", i2s_spdif_tx_parents, 0xa18,
55062306a36Sopenharmony_ci				     0, 5,	/* M */
55162306a36Sopenharmony_ci				     8, 2,	/* P */
55262306a36Sopenharmony_ci				     24, 3,	/* mux */
55362306a36Sopenharmony_ci				     BIT(31),	/* gate */
55462306a36Sopenharmony_ci				     0);
55562306a36Sopenharmony_ci
55662306a36Sopenharmony_cistatic const struct clk_hw *i2s2_asrc_parents[] = {
55762306a36Sopenharmony_ci	&pll_audio0_4x_clk.common.hw,
55862306a36Sopenharmony_ci	&pll_periph0_clk.hw,
55962306a36Sopenharmony_ci	&pll_audio1_div2_clk.common.hw,
56062306a36Sopenharmony_ci	&pll_audio1_div5_clk.common.hw,
56162306a36Sopenharmony_ci};
56262306a36Sopenharmony_cistatic SUNXI_CCU_MP_HW_WITH_MUX_GATE(i2s2_asrc_clk, "i2s2-asrc", i2s2_asrc_parents, 0xa1c,
56362306a36Sopenharmony_ci				     0, 5,	/* M */
56462306a36Sopenharmony_ci				     8, 2,	/* P */
56562306a36Sopenharmony_ci				     24, 3,	/* mux */
56662306a36Sopenharmony_ci				     BIT(31),	/* gate */
56762306a36Sopenharmony_ci				     0);
56862306a36Sopenharmony_ci
56962306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_i2s0_clk, "bus-i2s0", apb0_hws,
57062306a36Sopenharmony_ci			  0xa20, BIT(0), 0);
57162306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_i2s1_clk, "bus-i2s1", apb0_hws,
57262306a36Sopenharmony_ci			  0xa20, BIT(1), 0);
57362306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_i2s2_clk, "bus-i2s2", apb0_hws,
57462306a36Sopenharmony_ci			  0xa20, BIT(2), 0);
57562306a36Sopenharmony_ci
57662306a36Sopenharmony_cistatic SUNXI_CCU_MP_HW_WITH_MUX_GATE(spdif_tx_clk, "spdif-tx", i2s_spdif_tx_parents, 0xa24,
57762306a36Sopenharmony_ci				     0, 5,	/* M */
57862306a36Sopenharmony_ci				     8, 2,	/* P */
57962306a36Sopenharmony_ci				     24, 3,	/* mux */
58062306a36Sopenharmony_ci				     BIT(31),	/* gate */
58162306a36Sopenharmony_ci				     0);
58262306a36Sopenharmony_ci
58362306a36Sopenharmony_cistatic const struct clk_hw *spdif_rx_parents[] = {
58462306a36Sopenharmony_ci	&pll_periph0_clk.hw,
58562306a36Sopenharmony_ci	&pll_audio1_div2_clk.common.hw,
58662306a36Sopenharmony_ci	&pll_audio1_div5_clk.common.hw,
58762306a36Sopenharmony_ci};
58862306a36Sopenharmony_cistatic SUNXI_CCU_MP_HW_WITH_MUX_GATE(spdif_rx_clk, "spdif-rx", spdif_rx_parents, 0xa28,
58962306a36Sopenharmony_ci				     0, 5,	/* M */
59062306a36Sopenharmony_ci				     8, 2,	/* P */
59162306a36Sopenharmony_ci				     24, 3,	/* mux */
59262306a36Sopenharmony_ci				     BIT(31),	/* gate */
59362306a36Sopenharmony_ci				     0);
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_spdif_clk, "bus-spdif", apb0_hws,
59662306a36Sopenharmony_ci			  0xa2c, BIT(0), 0);
59762306a36Sopenharmony_ci
59862306a36Sopenharmony_cistatic const struct clk_hw *dmic_codec_parents[] = {
59962306a36Sopenharmony_ci	&pll_audio0_clk.hw,
60062306a36Sopenharmony_ci	&pll_audio1_div2_clk.common.hw,
60162306a36Sopenharmony_ci	&pll_audio1_div5_clk.common.hw,
60262306a36Sopenharmony_ci};
60362306a36Sopenharmony_cistatic SUNXI_CCU_MP_HW_WITH_MUX_GATE(dmic_clk, "dmic", dmic_codec_parents, 0xa40,
60462306a36Sopenharmony_ci				     0, 5,	/* M */
60562306a36Sopenharmony_ci				     8, 2,	/* P */
60662306a36Sopenharmony_ci				     24, 3,	/* mux */
60762306a36Sopenharmony_ci				     BIT(31),	/* gate */
60862306a36Sopenharmony_ci				     0);
60962306a36Sopenharmony_ci
61062306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_dmic_clk, "bus-dmic", apb0_hws,
61162306a36Sopenharmony_ci			  0xa4c, BIT(0), 0);
61262306a36Sopenharmony_ci
61362306a36Sopenharmony_cistatic SUNXI_CCU_MP_HW_WITH_MUX_GATE(audio_dac_clk, "audio-dac", dmic_codec_parents, 0xa50,
61462306a36Sopenharmony_ci				     0, 5,	/* M */
61562306a36Sopenharmony_ci				     8, 2,	/* P */
61662306a36Sopenharmony_ci				     24, 3,	/* mux */
61762306a36Sopenharmony_ci				     BIT(31),	/* gate */
61862306a36Sopenharmony_ci				     0);
61962306a36Sopenharmony_ci
62062306a36Sopenharmony_cistatic SUNXI_CCU_MP_HW_WITH_MUX_GATE(audio_adc_clk, "audio-adc", dmic_codec_parents, 0xa54,
62162306a36Sopenharmony_ci				     0, 5,	/* M */
62262306a36Sopenharmony_ci				     8, 2,	/* P */
62362306a36Sopenharmony_ci				     24, 3,	/* mux */
62462306a36Sopenharmony_ci				     BIT(31),	/* gate */
62562306a36Sopenharmony_ci				     0);
62662306a36Sopenharmony_ci
62762306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_audio_clk, "bus-audio", apb0_hws,
62862306a36Sopenharmony_ci			  0xa5c, BIT(0), 0);
62962306a36Sopenharmony_ci
63062306a36Sopenharmony_ci
63162306a36Sopenharmony_ci/*
63262306a36Sopenharmony_ci * The first parent is a 48 MHz input clock divided by 4. That 48 MHz clock is
63362306a36Sopenharmony_ci * a 2x multiplier from osc24M synchronized by pll-periph0, and is also used by
63462306a36Sopenharmony_ci * the OHCI module.
63562306a36Sopenharmony_ci */
63662306a36Sopenharmony_cistatic const struct clk_parent_data usb_ohci_parents[] = {
63762306a36Sopenharmony_ci	{ .hw = &pll_periph0_clk.hw },
63862306a36Sopenharmony_ci	{ .fw_name = "hosc" },
63962306a36Sopenharmony_ci	{ .fw_name = "losc" },
64062306a36Sopenharmony_ci};
64162306a36Sopenharmony_cistatic const struct ccu_mux_fixed_prediv usb_ohci_predivs[] = {
64262306a36Sopenharmony_ci	{ .index = 0, .div = 50 },
64362306a36Sopenharmony_ci	{ .index = 1, .div = 2 },
64462306a36Sopenharmony_ci};
64562306a36Sopenharmony_ci
64662306a36Sopenharmony_cistatic struct ccu_mux usb_ohci0_clk = {
64762306a36Sopenharmony_ci	.enable		= BIT(31),
64862306a36Sopenharmony_ci	.mux		= {
64962306a36Sopenharmony_ci		.shift		= 24,
65062306a36Sopenharmony_ci		.width		= 2,
65162306a36Sopenharmony_ci		.fixed_predivs	= usb_ohci_predivs,
65262306a36Sopenharmony_ci		.n_predivs	= ARRAY_SIZE(usb_ohci_predivs),
65362306a36Sopenharmony_ci	},
65462306a36Sopenharmony_ci	.common		= {
65562306a36Sopenharmony_ci		.reg		= 0xa70,
65662306a36Sopenharmony_ci		.features	= CCU_FEATURE_FIXED_PREDIV,
65762306a36Sopenharmony_ci		.hw.init	= CLK_HW_INIT_PARENTS_DATA("usb-ohci0",
65862306a36Sopenharmony_ci							   usb_ohci_parents,
65962306a36Sopenharmony_ci							   &ccu_mux_ops,
66062306a36Sopenharmony_ci							   0),
66162306a36Sopenharmony_ci	},
66262306a36Sopenharmony_ci};
66362306a36Sopenharmony_ci
66462306a36Sopenharmony_cistatic struct ccu_mux usb_ohci1_clk = {
66562306a36Sopenharmony_ci	.enable		= BIT(31),
66662306a36Sopenharmony_ci	.mux		= {
66762306a36Sopenharmony_ci		.shift		= 24,
66862306a36Sopenharmony_ci		.width		= 2,
66962306a36Sopenharmony_ci		.fixed_predivs	= usb_ohci_predivs,
67062306a36Sopenharmony_ci		.n_predivs	= ARRAY_SIZE(usb_ohci_predivs),
67162306a36Sopenharmony_ci	},
67262306a36Sopenharmony_ci	.common		= {
67362306a36Sopenharmony_ci		.reg		= 0xa74,
67462306a36Sopenharmony_ci		.features	= CCU_FEATURE_FIXED_PREDIV,
67562306a36Sopenharmony_ci		.hw.init	= CLK_HW_INIT_PARENTS_DATA("usb-ohci1",
67662306a36Sopenharmony_ci							   usb_ohci_parents,
67762306a36Sopenharmony_ci							   &ccu_mux_ops,
67862306a36Sopenharmony_ci							   0),
67962306a36Sopenharmony_ci	},
68062306a36Sopenharmony_ci};
68162306a36Sopenharmony_ci
68262306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_ohci0_clk, "bus-ohci0", psi_ahb_hws,
68362306a36Sopenharmony_ci			  0xa8c, BIT(0), 0);
68462306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_ohci1_clk, "bus-ohci1", psi_ahb_hws,
68562306a36Sopenharmony_ci			  0xa8c, BIT(1), 0);
68662306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_ehci0_clk, "bus-ehci0", psi_ahb_hws,
68762306a36Sopenharmony_ci			  0xa8c, BIT(4), 0);
68862306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_ehci1_clk, "bus-ehci1", psi_ahb_hws,
68962306a36Sopenharmony_ci			  0xa8c, BIT(5), 0);
69062306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_otg_clk, "bus-otg", psi_ahb_hws,
69162306a36Sopenharmony_ci			  0xa8c, BIT(8), 0);
69262306a36Sopenharmony_ci
69362306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_lradc_clk, "bus-lradc", apb0_hws,
69462306a36Sopenharmony_ci			  0xa9c, BIT(0), 0);
69562306a36Sopenharmony_ci
69662306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_dpss_top_clk, "bus-dpss-top", psi_ahb_hws,
69762306a36Sopenharmony_ci			  0xabc, BIT(0), 0);
69862306a36Sopenharmony_ci
69962306a36Sopenharmony_cistatic SUNXI_CCU_GATE_DATA(hdmi_24M_clk, "hdmi-24M", osc24M,
70062306a36Sopenharmony_ci			   0xb04, BIT(31), 0);
70162306a36Sopenharmony_ci
70262306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS_WITH_PREDIV(hdmi_cec_32k_clk, "hdmi-cec-32k",
70362306a36Sopenharmony_ci				      pll_periph0_2x_hws,
70462306a36Sopenharmony_ci				      0xb10, BIT(30), 36621, 0);
70562306a36Sopenharmony_ci
70662306a36Sopenharmony_cistatic const struct clk_parent_data hdmi_cec_parents[] = {
70762306a36Sopenharmony_ci	{ .fw_name = "losc" },
70862306a36Sopenharmony_ci	{ .hw = &hdmi_cec_32k_clk.common.hw },
70962306a36Sopenharmony_ci};
71062306a36Sopenharmony_cistatic SUNXI_CCU_MUX_DATA_WITH_GATE(hdmi_cec_clk, "hdmi-cec", hdmi_cec_parents, 0xb10,
71162306a36Sopenharmony_ci				    24, 1,	/* mux */
71262306a36Sopenharmony_ci				    BIT(31),	/* gate */
71362306a36Sopenharmony_ci				    0);
71462306a36Sopenharmony_ci
71562306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_hdmi_clk, "bus-hdmi", psi_ahb_hws,
71662306a36Sopenharmony_ci			  0xb1c, BIT(0), 0);
71762306a36Sopenharmony_ci
71862306a36Sopenharmony_cistatic const struct clk_parent_data mipi_dsi_parents[] = {
71962306a36Sopenharmony_ci	{ .fw_name = "hosc" },
72062306a36Sopenharmony_ci	{ .hw = &pll_periph0_clk.hw },
72162306a36Sopenharmony_ci	{ .hw = &pll_video0_2x_clk.hw },
72262306a36Sopenharmony_ci	{ .hw = &pll_video1_2x_clk.hw },
72362306a36Sopenharmony_ci	{ .hw = &pll_audio1_div2_clk.common.hw },
72462306a36Sopenharmony_ci};
72562306a36Sopenharmony_cistatic SUNXI_CCU_M_DATA_WITH_MUX_GATE(mipi_dsi_clk, "mipi-dsi", mipi_dsi_parents, 0xb24,
72662306a36Sopenharmony_ci				      0, 4,	/* M */
72762306a36Sopenharmony_ci				      24, 3,	/* mux */
72862306a36Sopenharmony_ci				      BIT(31),	/* gate */
72962306a36Sopenharmony_ci				      CLK_SET_RATE_PARENT);
73062306a36Sopenharmony_ci
73162306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_mipi_dsi_clk, "bus-mipi-dsi", psi_ahb_hws,
73262306a36Sopenharmony_ci			  0xb4c, BIT(0), 0);
73362306a36Sopenharmony_ci
73462306a36Sopenharmony_cistatic const struct clk_hw *tcon_tve_parents[] = {
73562306a36Sopenharmony_ci	&pll_video0_clk.hw,
73662306a36Sopenharmony_ci	&pll_video0_4x_clk.common.hw,
73762306a36Sopenharmony_ci	&pll_video1_clk.hw,
73862306a36Sopenharmony_ci	&pll_video1_4x_clk.common.hw,
73962306a36Sopenharmony_ci	&pll_periph0_2x_clk.common.hw,
74062306a36Sopenharmony_ci	&pll_audio1_div2_clk.common.hw,
74162306a36Sopenharmony_ci};
74262306a36Sopenharmony_cistatic SUNXI_CCU_MP_HW_WITH_MUX_GATE(tcon_lcd0_clk, "tcon-lcd0", tcon_tve_parents, 0xb60,
74362306a36Sopenharmony_ci				     0, 4,	/* M */
74462306a36Sopenharmony_ci				     8, 2,	/* P */
74562306a36Sopenharmony_ci				     24, 3,	/* mux */
74662306a36Sopenharmony_ci				     BIT(31),	/* gate */
74762306a36Sopenharmony_ci				     CLK_SET_RATE_PARENT);
74862306a36Sopenharmony_ci
74962306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_tcon_lcd0_clk, "bus-tcon-lcd0", psi_ahb_hws,
75062306a36Sopenharmony_ci			  0xb7c, BIT(0), 0);
75162306a36Sopenharmony_ci
75262306a36Sopenharmony_cistatic SUNXI_CCU_MP_HW_WITH_MUX_GATE(tcon_tv_clk, "tcon-tv", tcon_tve_parents, 0xb80,
75362306a36Sopenharmony_ci				     0, 4,	/* M */
75462306a36Sopenharmony_ci				     8, 2,	/* P */
75562306a36Sopenharmony_ci				     24, 3,	/* mux */
75662306a36Sopenharmony_ci				     BIT(31),	/* gate */
75762306a36Sopenharmony_ci				     CLK_SET_RATE_PARENT);
75862306a36Sopenharmony_ci
75962306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_tcon_tv_clk, "bus-tcon-tv", psi_ahb_hws,
76062306a36Sopenharmony_ci			  0xb9c, BIT(0), 0);
76162306a36Sopenharmony_ci
76262306a36Sopenharmony_cistatic SUNXI_CCU_MP_HW_WITH_MUX_GATE(tve_clk, "tve", tcon_tve_parents, 0xbb0,
76362306a36Sopenharmony_ci				     0, 4,	/* M */
76462306a36Sopenharmony_ci				     8, 2,	/* P */
76562306a36Sopenharmony_ci				     24, 3,	/* mux */
76662306a36Sopenharmony_ci				     BIT(31),	/* gate */
76762306a36Sopenharmony_ci				     0);
76862306a36Sopenharmony_ci
76962306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_tve_top_clk, "bus-tve-top", psi_ahb_hws,
77062306a36Sopenharmony_ci			  0xbbc, BIT(0), 0);
77162306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_tve_clk, "bus-tve", psi_ahb_hws,
77262306a36Sopenharmony_ci			  0xbbc, BIT(1), 0);
77362306a36Sopenharmony_ci
77462306a36Sopenharmony_cistatic const struct clk_parent_data tvd_parents[] = {
77562306a36Sopenharmony_ci	{ .fw_name = "hosc" },
77662306a36Sopenharmony_ci	{ .hw = &pll_video0_clk.hw },
77762306a36Sopenharmony_ci	{ .hw = &pll_video1_clk.hw },
77862306a36Sopenharmony_ci	{ .hw = &pll_periph0_clk.hw },
77962306a36Sopenharmony_ci};
78062306a36Sopenharmony_cistatic SUNXI_CCU_M_DATA_WITH_MUX_GATE(tvd_clk, "tvd", tvd_parents, 0xbc0,
78162306a36Sopenharmony_ci				      0, 5,	/* M */
78262306a36Sopenharmony_ci				      24, 3,	/* mux */
78362306a36Sopenharmony_ci				      BIT(31),	/* gate */
78462306a36Sopenharmony_ci				      0);
78562306a36Sopenharmony_ci
78662306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_tvd_top_clk, "bus-tvd-top", psi_ahb_hws,
78762306a36Sopenharmony_ci			  0xbdc, BIT(0), 0);
78862306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_tvd_clk, "bus-tvd", psi_ahb_hws,
78962306a36Sopenharmony_ci			  0xbdc, BIT(1), 0);
79062306a36Sopenharmony_ci
79162306a36Sopenharmony_cistatic SUNXI_CCU_MP_DATA_WITH_MUX_GATE(ledc_clk, "ledc", ir_tx_ledc_parents, 0xbf0,
79262306a36Sopenharmony_ci				       0, 4,	/* M */
79362306a36Sopenharmony_ci				       8, 2,	/* P */
79462306a36Sopenharmony_ci				       24, 1,	/* mux */
79562306a36Sopenharmony_ci				       BIT(31),	/* gate */
79662306a36Sopenharmony_ci				       0);
79762306a36Sopenharmony_ci
79862306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_ledc_clk, "bus-ledc", psi_ahb_hws,
79962306a36Sopenharmony_ci			  0xbfc, BIT(0), 0);
80062306a36Sopenharmony_ci
80162306a36Sopenharmony_cistatic const struct clk_hw *csi_top_parents[] = {
80262306a36Sopenharmony_ci	&pll_periph0_2x_clk.common.hw,
80362306a36Sopenharmony_ci	&pll_video0_2x_clk.hw,
80462306a36Sopenharmony_ci	&pll_video1_2x_clk.hw,
80562306a36Sopenharmony_ci};
80662306a36Sopenharmony_cistatic SUNXI_CCU_M_HW_WITH_MUX_GATE(csi_top_clk, "csi-top", csi_top_parents, 0xc04,
80762306a36Sopenharmony_ci				    0, 4,	/* M */
80862306a36Sopenharmony_ci				    24, 3,	/* mux */
80962306a36Sopenharmony_ci				    BIT(31),	/* gate */
81062306a36Sopenharmony_ci				    0);
81162306a36Sopenharmony_ci
81262306a36Sopenharmony_cistatic const struct clk_parent_data csi_mclk_parents[] = {
81362306a36Sopenharmony_ci	{ .fw_name = "hosc" },
81462306a36Sopenharmony_ci	{ .hw = &pll_periph0_clk.hw },
81562306a36Sopenharmony_ci	{ .hw = &pll_video0_clk.hw },
81662306a36Sopenharmony_ci	{ .hw = &pll_video1_clk.hw },
81762306a36Sopenharmony_ci	{ .hw = &pll_audio1_div2_clk.common.hw },
81862306a36Sopenharmony_ci	{ .hw = &pll_audio1_div5_clk.common.hw },
81962306a36Sopenharmony_ci};
82062306a36Sopenharmony_cistatic SUNXI_CCU_M_DATA_WITH_MUX_GATE(csi_mclk_clk, "csi-mclk", csi_mclk_parents, 0xc08,
82162306a36Sopenharmony_ci				      0, 5,	/* M */
82262306a36Sopenharmony_ci				      24, 3,	/* mux */
82362306a36Sopenharmony_ci				      BIT(31),	/* gate */
82462306a36Sopenharmony_ci				      0);
82562306a36Sopenharmony_ci
82662306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_csi_clk, "bus-csi", psi_ahb_hws,
82762306a36Sopenharmony_ci			  0xc1c, BIT(0), 0);
82862306a36Sopenharmony_ci
82962306a36Sopenharmony_cistatic const struct clk_parent_data tpadc_parents[] = {
83062306a36Sopenharmony_ci	{ .fw_name = "hosc" },
83162306a36Sopenharmony_ci	{ .hw = &pll_audio0_clk.hw },
83262306a36Sopenharmony_ci};
83362306a36Sopenharmony_cistatic SUNXI_CCU_MUX_DATA_WITH_GATE(tpadc_clk, "tpadc", tpadc_parents, 0xc50,
83462306a36Sopenharmony_ci				    24, 3,	/* mux */
83562306a36Sopenharmony_ci				    BIT(31),	/* gate */
83662306a36Sopenharmony_ci				    0);
83762306a36Sopenharmony_ci
83862306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_tpadc_clk, "bus-tpadc", apb0_hws,
83962306a36Sopenharmony_ci			  0xc5c, BIT(0), 0);
84062306a36Sopenharmony_ci
84162306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_tzma_clk, "bus-tzma", apb0_hws,
84262306a36Sopenharmony_ci			  0xc6c, BIT(0), 0);
84362306a36Sopenharmony_ci
84462306a36Sopenharmony_cistatic const struct clk_parent_data dsp_parents[] = {
84562306a36Sopenharmony_ci	{ .fw_name = "hosc" },
84662306a36Sopenharmony_ci	{ .fw_name = "losc" },
84762306a36Sopenharmony_ci	{ .fw_name = "iosc" },
84862306a36Sopenharmony_ci	{ .hw = &pll_periph0_2x_clk.common.hw },
84962306a36Sopenharmony_ci	{ .hw = &pll_audio1_div2_clk.common.hw },
85062306a36Sopenharmony_ci};
85162306a36Sopenharmony_cistatic SUNXI_CCU_M_DATA_WITH_MUX_GATE(dsp_clk, "dsp", dsp_parents, 0xc70,
85262306a36Sopenharmony_ci				      0, 5,	/* M */
85362306a36Sopenharmony_ci				      24, 3,	/* mux */
85462306a36Sopenharmony_ci				      BIT(31),	/* gate */
85562306a36Sopenharmony_ci				      0);
85662306a36Sopenharmony_ci
85762306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_dsp_cfg_clk, "bus-dsp-cfg", psi_ahb_hws,
85862306a36Sopenharmony_ci			  0xc7c, BIT(1), 0);
85962306a36Sopenharmony_ci
86062306a36Sopenharmony_ci/*
86162306a36Sopenharmony_ci * The RISC-V gate is not modelled - it is in a separate register (0xd04)
86262306a36Sopenharmony_ci * and has a special key field. The clock is critical anyway.
86362306a36Sopenharmony_ci */
86462306a36Sopenharmony_cistatic const struct clk_parent_data riscv_parents[] = {
86562306a36Sopenharmony_ci	{ .fw_name = "hosc" },
86662306a36Sopenharmony_ci	{ .fw_name = "losc" },
86762306a36Sopenharmony_ci	{ .fw_name = "iosc" },
86862306a36Sopenharmony_ci	{ .hw = &pll_periph0_800M_clk.common.hw },
86962306a36Sopenharmony_ci	{ .hw = &pll_periph0_clk.hw },
87062306a36Sopenharmony_ci	{ .hw = &pll_cpux_clk.common.hw },
87162306a36Sopenharmony_ci	{ .hw = &pll_audio1_div2_clk.common.hw },
87262306a36Sopenharmony_ci};
87362306a36Sopenharmony_cistatic SUNXI_CCU_M_DATA_WITH_MUX(riscv_clk, "riscv", riscv_parents, 0xd00,
87462306a36Sopenharmony_ci				 0, 5,	/* M */
87562306a36Sopenharmony_ci				 24, 3,	/* mux */
87662306a36Sopenharmony_ci				 CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
87762306a36Sopenharmony_ci
87862306a36Sopenharmony_ci/* The riscv-axi clk must be divided by at least 2. */
87962306a36Sopenharmony_cistatic struct clk_div_table riscv_axi_table[] = {
88062306a36Sopenharmony_ci	{ .val = 1, .div = 2 },
88162306a36Sopenharmony_ci	{ .val = 2, .div = 3 },
88262306a36Sopenharmony_ci	{ .val = 3, .div = 4 },
88362306a36Sopenharmony_ci	{ /* Sentinel */ }
88462306a36Sopenharmony_ci};
88562306a36Sopenharmony_cistatic SUNXI_CCU_DIV_TABLE_HW(riscv_axi_clk, "riscv-axi", &riscv_clk.common.hw,
88662306a36Sopenharmony_ci			      0xd00, 8, 2, riscv_axi_table, 0);
88762306a36Sopenharmony_ci
88862306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS(bus_riscv_cfg_clk, "bus-riscv-cfg", psi_ahb_hws,
88962306a36Sopenharmony_ci			  0xd0c, BIT(0), CLK_IS_CRITICAL);
89062306a36Sopenharmony_ci
89162306a36Sopenharmony_cistatic SUNXI_CCU_GATE_DATA(fanout_24M_clk, "fanout-24M", osc24M,
89262306a36Sopenharmony_ci			   0xf30, BIT(0), 0);
89362306a36Sopenharmony_cistatic SUNXI_CCU_GATE_DATA_WITH_PREDIV(fanout_12M_clk, "fanout-12M", osc24M,
89462306a36Sopenharmony_ci				       0xf30, BIT(1), 2, 0);
89562306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS_WITH_PREDIV(fanout_16M_clk, "fanout-16M", pll_periph0_2x_hws,
89662306a36Sopenharmony_ci				      0xf30, BIT(2), 75, 0);
89762306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS_WITH_PREDIV(fanout_25M_clk, "fanout-25M", pll_periph0_hws,
89862306a36Sopenharmony_ci				      0xf30, BIT(3), 24, 0);
89962306a36Sopenharmony_cistatic SUNXI_CCU_GATE_HWS_WITH_PREDIV(fanout_32k_clk, "fanout-32k", pll_periph0_2x_hws,
90062306a36Sopenharmony_ci				      0xf30, BIT(4), 36621, 0);
90162306a36Sopenharmony_ci
90262306a36Sopenharmony_ci/* This clock has a second divider that is not modelled and forced to 0. */
90362306a36Sopenharmony_ci#define SUN20I_D1_FANOUT_27M_REG	0xf34
90462306a36Sopenharmony_cistatic const struct clk_hw *fanout_27M_parents[] = {
90562306a36Sopenharmony_ci	&pll_video0_clk.hw,
90662306a36Sopenharmony_ci	&pll_video1_clk.hw,
90762306a36Sopenharmony_ci};
90862306a36Sopenharmony_cistatic SUNXI_CCU_M_HW_WITH_MUX_GATE(fanout_27M_clk, "fanout-27M", fanout_27M_parents, 0xf34,
90962306a36Sopenharmony_ci				    0, 5,	/* M */
91062306a36Sopenharmony_ci				    24, 2,	/* mux */
91162306a36Sopenharmony_ci				    BIT(31),	/* gate */
91262306a36Sopenharmony_ci				    0);
91362306a36Sopenharmony_ci
91462306a36Sopenharmony_cistatic SUNXI_CCU_M_HWS_WITH_GATE(fanout_pclk_clk, "fanout-pclk", apb0_hws, 0xf38,
91562306a36Sopenharmony_ci				 0, 5,		/* M */
91662306a36Sopenharmony_ci				 BIT(31),	/* gate */
91762306a36Sopenharmony_ci				 0);
91862306a36Sopenharmony_ci
91962306a36Sopenharmony_cistatic const struct clk_hw *fanout_parents[] = {
92062306a36Sopenharmony_ci	&fanout_32k_clk.common.hw,
92162306a36Sopenharmony_ci	&fanout_12M_clk.common.hw,
92262306a36Sopenharmony_ci	&fanout_16M_clk.common.hw,
92362306a36Sopenharmony_ci	&fanout_24M_clk.common.hw,
92462306a36Sopenharmony_ci	&fanout_25M_clk.common.hw,
92562306a36Sopenharmony_ci	&fanout_27M_clk.common.hw,
92662306a36Sopenharmony_ci	&fanout_pclk_clk.common.hw,
92762306a36Sopenharmony_ci};
92862306a36Sopenharmony_cistatic SUNXI_CCU_MUX_HW_WITH_GATE(fanout0_clk, "fanout0", fanout_parents, 0xf3c,
92962306a36Sopenharmony_ci				  0, 3,		/* mux */
93062306a36Sopenharmony_ci				  BIT(21),	/* gate */
93162306a36Sopenharmony_ci				  0);
93262306a36Sopenharmony_cistatic SUNXI_CCU_MUX_HW_WITH_GATE(fanout1_clk, "fanout1", fanout_parents, 0xf3c,
93362306a36Sopenharmony_ci				  3, 3,		/* mux */
93462306a36Sopenharmony_ci				  BIT(22),	/* gate */
93562306a36Sopenharmony_ci				  0);
93662306a36Sopenharmony_cistatic SUNXI_CCU_MUX_HW_WITH_GATE(fanout2_clk, "fanout2", fanout_parents, 0xf3c,
93762306a36Sopenharmony_ci				  6, 3,		/* mux */
93862306a36Sopenharmony_ci				  BIT(23),	/* gate */
93962306a36Sopenharmony_ci				  0);
94062306a36Sopenharmony_ci
94162306a36Sopenharmony_cistatic struct ccu_common *sun20i_d1_ccu_clks[] = {
94262306a36Sopenharmony_ci	&pll_cpux_clk.common,
94362306a36Sopenharmony_ci	&pll_ddr0_clk.common,
94462306a36Sopenharmony_ci	&pll_periph0_4x_clk.common,
94562306a36Sopenharmony_ci	&pll_periph0_2x_clk.common,
94662306a36Sopenharmony_ci	&pll_periph0_800M_clk.common,
94762306a36Sopenharmony_ci	&pll_video0_4x_clk.common,
94862306a36Sopenharmony_ci	&pll_video1_4x_clk.common,
94962306a36Sopenharmony_ci	&pll_ve_clk.common,
95062306a36Sopenharmony_ci	&pll_audio0_4x_clk.common,
95162306a36Sopenharmony_ci	&pll_audio1_clk.common,
95262306a36Sopenharmony_ci	&pll_audio1_div2_clk.common,
95362306a36Sopenharmony_ci	&pll_audio1_div5_clk.common,
95462306a36Sopenharmony_ci	&cpux_clk.common,
95562306a36Sopenharmony_ci	&cpux_axi_clk.common,
95662306a36Sopenharmony_ci	&cpux_apb_clk.common,
95762306a36Sopenharmony_ci	&psi_ahb_clk.common,
95862306a36Sopenharmony_ci	&apb0_clk.common,
95962306a36Sopenharmony_ci	&apb1_clk.common,
96062306a36Sopenharmony_ci	&de_clk.common,
96162306a36Sopenharmony_ci	&bus_de_clk.common,
96262306a36Sopenharmony_ci	&di_clk.common,
96362306a36Sopenharmony_ci	&bus_di_clk.common,
96462306a36Sopenharmony_ci	&g2d_clk.common,
96562306a36Sopenharmony_ci	&bus_g2d_clk.common,
96662306a36Sopenharmony_ci	&ce_clk.common,
96762306a36Sopenharmony_ci	&bus_ce_clk.common,
96862306a36Sopenharmony_ci	&ve_clk.common,
96962306a36Sopenharmony_ci	&bus_ve_clk.common,
97062306a36Sopenharmony_ci	&bus_dma_clk.common,
97162306a36Sopenharmony_ci	&bus_msgbox0_clk.common,
97262306a36Sopenharmony_ci	&bus_msgbox1_clk.common,
97362306a36Sopenharmony_ci	&bus_msgbox2_clk.common,
97462306a36Sopenharmony_ci	&bus_spinlock_clk.common,
97562306a36Sopenharmony_ci	&bus_hstimer_clk.common,
97662306a36Sopenharmony_ci	&avs_clk.common,
97762306a36Sopenharmony_ci	&bus_dbg_clk.common,
97862306a36Sopenharmony_ci	&bus_pwm_clk.common,
97962306a36Sopenharmony_ci	&bus_iommu_clk.common,
98062306a36Sopenharmony_ci	&dram_clk.common,
98162306a36Sopenharmony_ci	&mbus_dma_clk.common,
98262306a36Sopenharmony_ci	&mbus_ve_clk.common,
98362306a36Sopenharmony_ci	&mbus_ce_clk.common,
98462306a36Sopenharmony_ci	&mbus_tvin_clk.common,
98562306a36Sopenharmony_ci	&mbus_csi_clk.common,
98662306a36Sopenharmony_ci	&mbus_g2d_clk.common,
98762306a36Sopenharmony_ci	&mbus_riscv_clk.common,
98862306a36Sopenharmony_ci	&bus_dram_clk.common,
98962306a36Sopenharmony_ci	&mmc0_clk.common,
99062306a36Sopenharmony_ci	&mmc1_clk.common,
99162306a36Sopenharmony_ci	&mmc2_clk.common,
99262306a36Sopenharmony_ci	&bus_mmc0_clk.common,
99362306a36Sopenharmony_ci	&bus_mmc1_clk.common,
99462306a36Sopenharmony_ci	&bus_mmc2_clk.common,
99562306a36Sopenharmony_ci	&bus_uart0_clk.common,
99662306a36Sopenharmony_ci	&bus_uart1_clk.common,
99762306a36Sopenharmony_ci	&bus_uart2_clk.common,
99862306a36Sopenharmony_ci	&bus_uart3_clk.common,
99962306a36Sopenharmony_ci	&bus_uart4_clk.common,
100062306a36Sopenharmony_ci	&bus_uart5_clk.common,
100162306a36Sopenharmony_ci	&bus_i2c0_clk.common,
100262306a36Sopenharmony_ci	&bus_i2c1_clk.common,
100362306a36Sopenharmony_ci	&bus_i2c2_clk.common,
100462306a36Sopenharmony_ci	&bus_i2c3_clk.common,
100562306a36Sopenharmony_ci	&bus_can0_clk.common,
100662306a36Sopenharmony_ci	&bus_can1_clk.common,
100762306a36Sopenharmony_ci	&spi0_clk.common,
100862306a36Sopenharmony_ci	&spi1_clk.common,
100962306a36Sopenharmony_ci	&bus_spi0_clk.common,
101062306a36Sopenharmony_ci	&bus_spi1_clk.common,
101162306a36Sopenharmony_ci	&emac_25M_clk.common,
101262306a36Sopenharmony_ci	&bus_emac_clk.common,
101362306a36Sopenharmony_ci	&ir_tx_clk.common,
101462306a36Sopenharmony_ci	&bus_ir_tx_clk.common,
101562306a36Sopenharmony_ci	&bus_gpadc_clk.common,
101662306a36Sopenharmony_ci	&bus_ths_clk.common,
101762306a36Sopenharmony_ci	&i2s0_clk.common,
101862306a36Sopenharmony_ci	&i2s1_clk.common,
101962306a36Sopenharmony_ci	&i2s2_clk.common,
102062306a36Sopenharmony_ci	&i2s2_asrc_clk.common,
102162306a36Sopenharmony_ci	&bus_i2s0_clk.common,
102262306a36Sopenharmony_ci	&bus_i2s1_clk.common,
102362306a36Sopenharmony_ci	&bus_i2s2_clk.common,
102462306a36Sopenharmony_ci	&spdif_tx_clk.common,
102562306a36Sopenharmony_ci	&spdif_rx_clk.common,
102662306a36Sopenharmony_ci	&bus_spdif_clk.common,
102762306a36Sopenharmony_ci	&dmic_clk.common,
102862306a36Sopenharmony_ci	&bus_dmic_clk.common,
102962306a36Sopenharmony_ci	&audio_dac_clk.common,
103062306a36Sopenharmony_ci	&audio_adc_clk.common,
103162306a36Sopenharmony_ci	&bus_audio_clk.common,
103262306a36Sopenharmony_ci	&usb_ohci0_clk.common,
103362306a36Sopenharmony_ci	&usb_ohci1_clk.common,
103462306a36Sopenharmony_ci	&bus_ohci0_clk.common,
103562306a36Sopenharmony_ci	&bus_ohci1_clk.common,
103662306a36Sopenharmony_ci	&bus_ehci0_clk.common,
103762306a36Sopenharmony_ci	&bus_ehci1_clk.common,
103862306a36Sopenharmony_ci	&bus_otg_clk.common,
103962306a36Sopenharmony_ci	&bus_lradc_clk.common,
104062306a36Sopenharmony_ci	&bus_dpss_top_clk.common,
104162306a36Sopenharmony_ci	&hdmi_24M_clk.common,
104262306a36Sopenharmony_ci	&hdmi_cec_32k_clk.common,
104362306a36Sopenharmony_ci	&hdmi_cec_clk.common,
104462306a36Sopenharmony_ci	&bus_hdmi_clk.common,
104562306a36Sopenharmony_ci	&mipi_dsi_clk.common,
104662306a36Sopenharmony_ci	&bus_mipi_dsi_clk.common,
104762306a36Sopenharmony_ci	&tcon_lcd0_clk.common,
104862306a36Sopenharmony_ci	&bus_tcon_lcd0_clk.common,
104962306a36Sopenharmony_ci	&tcon_tv_clk.common,
105062306a36Sopenharmony_ci	&bus_tcon_tv_clk.common,
105162306a36Sopenharmony_ci	&tve_clk.common,
105262306a36Sopenharmony_ci	&bus_tve_top_clk.common,
105362306a36Sopenharmony_ci	&bus_tve_clk.common,
105462306a36Sopenharmony_ci	&tvd_clk.common,
105562306a36Sopenharmony_ci	&bus_tvd_top_clk.common,
105662306a36Sopenharmony_ci	&bus_tvd_clk.common,
105762306a36Sopenharmony_ci	&ledc_clk.common,
105862306a36Sopenharmony_ci	&bus_ledc_clk.common,
105962306a36Sopenharmony_ci	&csi_top_clk.common,
106062306a36Sopenharmony_ci	&csi_mclk_clk.common,
106162306a36Sopenharmony_ci	&bus_csi_clk.common,
106262306a36Sopenharmony_ci	&tpadc_clk.common,
106362306a36Sopenharmony_ci	&bus_tpadc_clk.common,
106462306a36Sopenharmony_ci	&bus_tzma_clk.common,
106562306a36Sopenharmony_ci	&dsp_clk.common,
106662306a36Sopenharmony_ci	&bus_dsp_cfg_clk.common,
106762306a36Sopenharmony_ci	&riscv_clk.common,
106862306a36Sopenharmony_ci	&riscv_axi_clk.common,
106962306a36Sopenharmony_ci	&bus_riscv_cfg_clk.common,
107062306a36Sopenharmony_ci	&fanout_24M_clk.common,
107162306a36Sopenharmony_ci	&fanout_12M_clk.common,
107262306a36Sopenharmony_ci	&fanout_16M_clk.common,
107362306a36Sopenharmony_ci	&fanout_25M_clk.common,
107462306a36Sopenharmony_ci	&fanout_32k_clk.common,
107562306a36Sopenharmony_ci	&fanout_27M_clk.common,
107662306a36Sopenharmony_ci	&fanout_pclk_clk.common,
107762306a36Sopenharmony_ci	&fanout0_clk.common,
107862306a36Sopenharmony_ci	&fanout1_clk.common,
107962306a36Sopenharmony_ci	&fanout2_clk.common,
108062306a36Sopenharmony_ci};
108162306a36Sopenharmony_ci
108262306a36Sopenharmony_cistatic struct clk_hw_onecell_data sun20i_d1_hw_clks = {
108362306a36Sopenharmony_ci	.num	= CLK_NUMBER,
108462306a36Sopenharmony_ci	.hws	= {
108562306a36Sopenharmony_ci		[CLK_PLL_CPUX]		= &pll_cpux_clk.common.hw,
108662306a36Sopenharmony_ci		[CLK_PLL_DDR0]		= &pll_ddr0_clk.common.hw,
108762306a36Sopenharmony_ci		[CLK_PLL_PERIPH0_4X]	= &pll_periph0_4x_clk.common.hw,
108862306a36Sopenharmony_ci		[CLK_PLL_PERIPH0_2X]	= &pll_periph0_2x_clk.common.hw,
108962306a36Sopenharmony_ci		[CLK_PLL_PERIPH0_800M]	= &pll_periph0_800M_clk.common.hw,
109062306a36Sopenharmony_ci		[CLK_PLL_PERIPH0]	= &pll_periph0_clk.hw,
109162306a36Sopenharmony_ci		[CLK_PLL_PERIPH0_DIV3]	= &pll_periph0_div3_clk.hw,
109262306a36Sopenharmony_ci		[CLK_PLL_VIDEO0_4X]	= &pll_video0_4x_clk.common.hw,
109362306a36Sopenharmony_ci		[CLK_PLL_VIDEO0_2X]	= &pll_video0_2x_clk.hw,
109462306a36Sopenharmony_ci		[CLK_PLL_VIDEO0]	= &pll_video0_clk.hw,
109562306a36Sopenharmony_ci		[CLK_PLL_VIDEO1_4X]	= &pll_video1_4x_clk.common.hw,
109662306a36Sopenharmony_ci		[CLK_PLL_VIDEO1_2X]	= &pll_video1_2x_clk.hw,
109762306a36Sopenharmony_ci		[CLK_PLL_VIDEO1]	= &pll_video1_clk.hw,
109862306a36Sopenharmony_ci		[CLK_PLL_VE]		= &pll_ve_clk.common.hw,
109962306a36Sopenharmony_ci		[CLK_PLL_AUDIO0_4X]	= &pll_audio0_4x_clk.common.hw,
110062306a36Sopenharmony_ci		[CLK_PLL_AUDIO0_2X]	= &pll_audio0_2x_clk.hw,
110162306a36Sopenharmony_ci		[CLK_PLL_AUDIO0]	= &pll_audio0_clk.hw,
110262306a36Sopenharmony_ci		[CLK_PLL_AUDIO1]	= &pll_audio1_clk.common.hw,
110362306a36Sopenharmony_ci		[CLK_PLL_AUDIO1_DIV2]	= &pll_audio1_div2_clk.common.hw,
110462306a36Sopenharmony_ci		[CLK_PLL_AUDIO1_DIV5]	= &pll_audio1_div5_clk.common.hw,
110562306a36Sopenharmony_ci		[CLK_CPUX]		= &cpux_clk.common.hw,
110662306a36Sopenharmony_ci		[CLK_CPUX_AXI]		= &cpux_axi_clk.common.hw,
110762306a36Sopenharmony_ci		[CLK_CPUX_APB]		= &cpux_apb_clk.common.hw,
110862306a36Sopenharmony_ci		[CLK_PSI_AHB]		= &psi_ahb_clk.common.hw,
110962306a36Sopenharmony_ci		[CLK_APB0]		= &apb0_clk.common.hw,
111062306a36Sopenharmony_ci		[CLK_APB1]		= &apb1_clk.common.hw,
111162306a36Sopenharmony_ci		[CLK_MBUS]		= &mbus_clk.hw,
111262306a36Sopenharmony_ci		[CLK_DE]		= &de_clk.common.hw,
111362306a36Sopenharmony_ci		[CLK_BUS_DE]		= &bus_de_clk.common.hw,
111462306a36Sopenharmony_ci		[CLK_DI]		= &di_clk.common.hw,
111562306a36Sopenharmony_ci		[CLK_BUS_DI]		= &bus_di_clk.common.hw,
111662306a36Sopenharmony_ci		[CLK_G2D]		= &g2d_clk.common.hw,
111762306a36Sopenharmony_ci		[CLK_BUS_G2D]		= &bus_g2d_clk.common.hw,
111862306a36Sopenharmony_ci		[CLK_CE]		= &ce_clk.common.hw,
111962306a36Sopenharmony_ci		[CLK_BUS_CE]		= &bus_ce_clk.common.hw,
112062306a36Sopenharmony_ci		[CLK_VE]		= &ve_clk.common.hw,
112162306a36Sopenharmony_ci		[CLK_BUS_VE]		= &bus_ve_clk.common.hw,
112262306a36Sopenharmony_ci		[CLK_BUS_DMA]		= &bus_dma_clk.common.hw,
112362306a36Sopenharmony_ci		[CLK_BUS_MSGBOX0]	= &bus_msgbox0_clk.common.hw,
112462306a36Sopenharmony_ci		[CLK_BUS_MSGBOX1]	= &bus_msgbox1_clk.common.hw,
112562306a36Sopenharmony_ci		[CLK_BUS_MSGBOX2]	= &bus_msgbox2_clk.common.hw,
112662306a36Sopenharmony_ci		[CLK_BUS_SPINLOCK]	= &bus_spinlock_clk.common.hw,
112762306a36Sopenharmony_ci		[CLK_BUS_HSTIMER]	= &bus_hstimer_clk.common.hw,
112862306a36Sopenharmony_ci		[CLK_AVS]		= &avs_clk.common.hw,
112962306a36Sopenharmony_ci		[CLK_BUS_DBG]		= &bus_dbg_clk.common.hw,
113062306a36Sopenharmony_ci		[CLK_BUS_PWM]		= &bus_pwm_clk.common.hw,
113162306a36Sopenharmony_ci		[CLK_BUS_IOMMU]		= &bus_iommu_clk.common.hw,
113262306a36Sopenharmony_ci		[CLK_DRAM]		= &dram_clk.common.hw,
113362306a36Sopenharmony_ci		[CLK_MBUS_DMA]		= &mbus_dma_clk.common.hw,
113462306a36Sopenharmony_ci		[CLK_MBUS_VE]		= &mbus_ve_clk.common.hw,
113562306a36Sopenharmony_ci		[CLK_MBUS_CE]		= &mbus_ce_clk.common.hw,
113662306a36Sopenharmony_ci		[CLK_MBUS_TVIN]		= &mbus_tvin_clk.common.hw,
113762306a36Sopenharmony_ci		[CLK_MBUS_CSI]		= &mbus_csi_clk.common.hw,
113862306a36Sopenharmony_ci		[CLK_MBUS_G2D]		= &mbus_g2d_clk.common.hw,
113962306a36Sopenharmony_ci		[CLK_MBUS_RISCV]	= &mbus_riscv_clk.common.hw,
114062306a36Sopenharmony_ci		[CLK_BUS_DRAM]		= &bus_dram_clk.common.hw,
114162306a36Sopenharmony_ci		[CLK_MMC0]		= &mmc0_clk.common.hw,
114262306a36Sopenharmony_ci		[CLK_MMC1]		= &mmc1_clk.common.hw,
114362306a36Sopenharmony_ci		[CLK_MMC2]		= &mmc2_clk.common.hw,
114462306a36Sopenharmony_ci		[CLK_BUS_MMC0]		= &bus_mmc0_clk.common.hw,
114562306a36Sopenharmony_ci		[CLK_BUS_MMC1]		= &bus_mmc1_clk.common.hw,
114662306a36Sopenharmony_ci		[CLK_BUS_MMC2]		= &bus_mmc2_clk.common.hw,
114762306a36Sopenharmony_ci		[CLK_BUS_UART0]		= &bus_uart0_clk.common.hw,
114862306a36Sopenharmony_ci		[CLK_BUS_UART1]		= &bus_uart1_clk.common.hw,
114962306a36Sopenharmony_ci		[CLK_BUS_UART2]		= &bus_uart2_clk.common.hw,
115062306a36Sopenharmony_ci		[CLK_BUS_UART3]		= &bus_uart3_clk.common.hw,
115162306a36Sopenharmony_ci		[CLK_BUS_UART4]		= &bus_uart4_clk.common.hw,
115262306a36Sopenharmony_ci		[CLK_BUS_UART5]		= &bus_uart5_clk.common.hw,
115362306a36Sopenharmony_ci		[CLK_BUS_I2C0]		= &bus_i2c0_clk.common.hw,
115462306a36Sopenharmony_ci		[CLK_BUS_I2C1]		= &bus_i2c1_clk.common.hw,
115562306a36Sopenharmony_ci		[CLK_BUS_I2C2]		= &bus_i2c2_clk.common.hw,
115662306a36Sopenharmony_ci		[CLK_BUS_I2C3]		= &bus_i2c3_clk.common.hw,
115762306a36Sopenharmony_ci		[CLK_BUS_CAN0]		= &bus_can0_clk.common.hw,
115862306a36Sopenharmony_ci		[CLK_BUS_CAN1]		= &bus_can1_clk.common.hw,
115962306a36Sopenharmony_ci		[CLK_SPI0]		= &spi0_clk.common.hw,
116062306a36Sopenharmony_ci		[CLK_SPI1]		= &spi1_clk.common.hw,
116162306a36Sopenharmony_ci		[CLK_BUS_SPI0]		= &bus_spi0_clk.common.hw,
116262306a36Sopenharmony_ci		[CLK_BUS_SPI1]		= &bus_spi1_clk.common.hw,
116362306a36Sopenharmony_ci		[CLK_EMAC_25M]		= &emac_25M_clk.common.hw,
116462306a36Sopenharmony_ci		[CLK_BUS_EMAC]		= &bus_emac_clk.common.hw,
116562306a36Sopenharmony_ci		[CLK_IR_TX]		= &ir_tx_clk.common.hw,
116662306a36Sopenharmony_ci		[CLK_BUS_IR_TX]		= &bus_ir_tx_clk.common.hw,
116762306a36Sopenharmony_ci		[CLK_BUS_GPADC]		= &bus_gpadc_clk.common.hw,
116862306a36Sopenharmony_ci		[CLK_BUS_THS]		= &bus_ths_clk.common.hw,
116962306a36Sopenharmony_ci		[CLK_I2S0]		= &i2s0_clk.common.hw,
117062306a36Sopenharmony_ci		[CLK_I2S1]		= &i2s1_clk.common.hw,
117162306a36Sopenharmony_ci		[CLK_I2S2]		= &i2s2_clk.common.hw,
117262306a36Sopenharmony_ci		[CLK_I2S2_ASRC]		= &i2s2_asrc_clk.common.hw,
117362306a36Sopenharmony_ci		[CLK_BUS_I2S0]		= &bus_i2s0_clk.common.hw,
117462306a36Sopenharmony_ci		[CLK_BUS_I2S1]		= &bus_i2s1_clk.common.hw,
117562306a36Sopenharmony_ci		[CLK_BUS_I2S2]		= &bus_i2s2_clk.common.hw,
117662306a36Sopenharmony_ci		[CLK_SPDIF_TX]		= &spdif_tx_clk.common.hw,
117762306a36Sopenharmony_ci		[CLK_SPDIF_RX]		= &spdif_rx_clk.common.hw,
117862306a36Sopenharmony_ci		[CLK_BUS_SPDIF]		= &bus_spdif_clk.common.hw,
117962306a36Sopenharmony_ci		[CLK_DMIC]		= &dmic_clk.common.hw,
118062306a36Sopenharmony_ci		[CLK_BUS_DMIC]		= &bus_dmic_clk.common.hw,
118162306a36Sopenharmony_ci		[CLK_AUDIO_DAC]		= &audio_dac_clk.common.hw,
118262306a36Sopenharmony_ci		[CLK_AUDIO_ADC]		= &audio_adc_clk.common.hw,
118362306a36Sopenharmony_ci		[CLK_BUS_AUDIO]		= &bus_audio_clk.common.hw,
118462306a36Sopenharmony_ci		[CLK_USB_OHCI0]		= &usb_ohci0_clk.common.hw,
118562306a36Sopenharmony_ci		[CLK_USB_OHCI1]		= &usb_ohci1_clk.common.hw,
118662306a36Sopenharmony_ci		[CLK_BUS_OHCI0]		= &bus_ohci0_clk.common.hw,
118762306a36Sopenharmony_ci		[CLK_BUS_OHCI1]		= &bus_ohci1_clk.common.hw,
118862306a36Sopenharmony_ci		[CLK_BUS_EHCI0]		= &bus_ehci0_clk.common.hw,
118962306a36Sopenharmony_ci		[CLK_BUS_EHCI1]		= &bus_ehci1_clk.common.hw,
119062306a36Sopenharmony_ci		[CLK_BUS_OTG]		= &bus_otg_clk.common.hw,
119162306a36Sopenharmony_ci		[CLK_BUS_LRADC]		= &bus_lradc_clk.common.hw,
119262306a36Sopenharmony_ci		[CLK_BUS_DPSS_TOP]	= &bus_dpss_top_clk.common.hw,
119362306a36Sopenharmony_ci		[CLK_HDMI_24M]		= &hdmi_24M_clk.common.hw,
119462306a36Sopenharmony_ci		[CLK_HDMI_CEC_32K]	= &hdmi_cec_32k_clk.common.hw,
119562306a36Sopenharmony_ci		[CLK_HDMI_CEC]		= &hdmi_cec_clk.common.hw,
119662306a36Sopenharmony_ci		[CLK_BUS_HDMI]		= &bus_hdmi_clk.common.hw,
119762306a36Sopenharmony_ci		[CLK_MIPI_DSI]		= &mipi_dsi_clk.common.hw,
119862306a36Sopenharmony_ci		[CLK_BUS_MIPI_DSI]	= &bus_mipi_dsi_clk.common.hw,
119962306a36Sopenharmony_ci		[CLK_TCON_LCD0]		= &tcon_lcd0_clk.common.hw,
120062306a36Sopenharmony_ci		[CLK_BUS_TCON_LCD0]	= &bus_tcon_lcd0_clk.common.hw,
120162306a36Sopenharmony_ci		[CLK_TCON_TV]		= &tcon_tv_clk.common.hw,
120262306a36Sopenharmony_ci		[CLK_BUS_TCON_TV]	= &bus_tcon_tv_clk.common.hw,
120362306a36Sopenharmony_ci		[CLK_TVE]		= &tve_clk.common.hw,
120462306a36Sopenharmony_ci		[CLK_BUS_TVE_TOP]	= &bus_tve_top_clk.common.hw,
120562306a36Sopenharmony_ci		[CLK_BUS_TVE]		= &bus_tve_clk.common.hw,
120662306a36Sopenharmony_ci		[CLK_TVD]		= &tvd_clk.common.hw,
120762306a36Sopenharmony_ci		[CLK_BUS_TVD_TOP]	= &bus_tvd_top_clk.common.hw,
120862306a36Sopenharmony_ci		[CLK_BUS_TVD]		= &bus_tvd_clk.common.hw,
120962306a36Sopenharmony_ci		[CLK_LEDC]		= &ledc_clk.common.hw,
121062306a36Sopenharmony_ci		[CLK_BUS_LEDC]		= &bus_ledc_clk.common.hw,
121162306a36Sopenharmony_ci		[CLK_CSI_TOP]		= &csi_top_clk.common.hw,
121262306a36Sopenharmony_ci		[CLK_CSI_MCLK]		= &csi_mclk_clk.common.hw,
121362306a36Sopenharmony_ci		[CLK_BUS_CSI]		= &bus_csi_clk.common.hw,
121462306a36Sopenharmony_ci		[CLK_TPADC]		= &tpadc_clk.common.hw,
121562306a36Sopenharmony_ci		[CLK_BUS_TPADC]		= &bus_tpadc_clk.common.hw,
121662306a36Sopenharmony_ci		[CLK_BUS_TZMA]		= &bus_tzma_clk.common.hw,
121762306a36Sopenharmony_ci		[CLK_DSP]		= &dsp_clk.common.hw,
121862306a36Sopenharmony_ci		[CLK_BUS_DSP_CFG]	= &bus_dsp_cfg_clk.common.hw,
121962306a36Sopenharmony_ci		[CLK_RISCV]		= &riscv_clk.common.hw,
122062306a36Sopenharmony_ci		[CLK_RISCV_AXI]		= &riscv_axi_clk.common.hw,
122162306a36Sopenharmony_ci		[CLK_BUS_RISCV_CFG]	= &bus_riscv_cfg_clk.common.hw,
122262306a36Sopenharmony_ci		[CLK_FANOUT_24M]	= &fanout_24M_clk.common.hw,
122362306a36Sopenharmony_ci		[CLK_FANOUT_12M]	= &fanout_12M_clk.common.hw,
122462306a36Sopenharmony_ci		[CLK_FANOUT_16M]	= &fanout_16M_clk.common.hw,
122562306a36Sopenharmony_ci		[CLK_FANOUT_25M]	= &fanout_25M_clk.common.hw,
122662306a36Sopenharmony_ci		[CLK_FANOUT_32K]	= &fanout_32k_clk.common.hw,
122762306a36Sopenharmony_ci		[CLK_FANOUT_27M]	= &fanout_27M_clk.common.hw,
122862306a36Sopenharmony_ci		[CLK_FANOUT_PCLK]	= &fanout_pclk_clk.common.hw,
122962306a36Sopenharmony_ci		[CLK_FANOUT0]		= &fanout0_clk.common.hw,
123062306a36Sopenharmony_ci		[CLK_FANOUT1]		= &fanout1_clk.common.hw,
123162306a36Sopenharmony_ci		[CLK_FANOUT2]		= &fanout2_clk.common.hw,
123262306a36Sopenharmony_ci	},
123362306a36Sopenharmony_ci};
123462306a36Sopenharmony_ci
123562306a36Sopenharmony_cistatic struct ccu_reset_map sun20i_d1_ccu_resets[] = {
123662306a36Sopenharmony_ci	[RST_MBUS]		= { 0x540, BIT(30) },
123762306a36Sopenharmony_ci	[RST_BUS_DE]		= { 0x60c, BIT(16) },
123862306a36Sopenharmony_ci	[RST_BUS_DI]		= { 0x62c, BIT(16) },
123962306a36Sopenharmony_ci	[RST_BUS_G2D]		= { 0x63c, BIT(16) },
124062306a36Sopenharmony_ci	[RST_BUS_CE]		= { 0x68c, BIT(16) },
124162306a36Sopenharmony_ci	[RST_BUS_VE]		= { 0x69c, BIT(16) },
124262306a36Sopenharmony_ci	[RST_BUS_DMA]		= { 0x70c, BIT(16) },
124362306a36Sopenharmony_ci	[RST_BUS_MSGBOX0]	= { 0x71c, BIT(16) },
124462306a36Sopenharmony_ci	[RST_BUS_MSGBOX1]	= { 0x71c, BIT(17) },
124562306a36Sopenharmony_ci	[RST_BUS_MSGBOX2]	= { 0x71c, BIT(18) },
124662306a36Sopenharmony_ci	[RST_BUS_SPINLOCK]	= { 0x72c, BIT(16) },
124762306a36Sopenharmony_ci	[RST_BUS_HSTIMER]	= { 0x73c, BIT(16) },
124862306a36Sopenharmony_ci	[RST_BUS_DBG]		= { 0x78c, BIT(16) },
124962306a36Sopenharmony_ci	[RST_BUS_PWM]		= { 0x7ac, BIT(16) },
125062306a36Sopenharmony_ci	[RST_BUS_DRAM]		= { 0x80c, BIT(16) },
125162306a36Sopenharmony_ci	[RST_BUS_MMC0]		= { 0x84c, BIT(16) },
125262306a36Sopenharmony_ci	[RST_BUS_MMC1]		= { 0x84c, BIT(17) },
125362306a36Sopenharmony_ci	[RST_BUS_MMC2]		= { 0x84c, BIT(18) },
125462306a36Sopenharmony_ci	[RST_BUS_UART0]		= { 0x90c, BIT(16) },
125562306a36Sopenharmony_ci	[RST_BUS_UART1]		= { 0x90c, BIT(17) },
125662306a36Sopenharmony_ci	[RST_BUS_UART2]		= { 0x90c, BIT(18) },
125762306a36Sopenharmony_ci	[RST_BUS_UART3]		= { 0x90c, BIT(19) },
125862306a36Sopenharmony_ci	[RST_BUS_UART4]		= { 0x90c, BIT(20) },
125962306a36Sopenharmony_ci	[RST_BUS_UART5]		= { 0x90c, BIT(21) },
126062306a36Sopenharmony_ci	[RST_BUS_I2C0]		= { 0x91c, BIT(16) },
126162306a36Sopenharmony_ci	[RST_BUS_I2C1]		= { 0x91c, BIT(17) },
126262306a36Sopenharmony_ci	[RST_BUS_I2C2]		= { 0x91c, BIT(18) },
126362306a36Sopenharmony_ci	[RST_BUS_I2C3]		= { 0x91c, BIT(19) },
126462306a36Sopenharmony_ci	[RST_BUS_CAN0]		= { 0x92c, BIT(16) },
126562306a36Sopenharmony_ci	[RST_BUS_CAN1]		= { 0x92c, BIT(17) },
126662306a36Sopenharmony_ci	[RST_BUS_SPI0]		= { 0x96c, BIT(16) },
126762306a36Sopenharmony_ci	[RST_BUS_SPI1]		= { 0x96c, BIT(17) },
126862306a36Sopenharmony_ci	[RST_BUS_EMAC]		= { 0x97c, BIT(16) },
126962306a36Sopenharmony_ci	[RST_BUS_IR_TX]		= { 0x9cc, BIT(16) },
127062306a36Sopenharmony_ci	[RST_BUS_GPADC]		= { 0x9ec, BIT(16) },
127162306a36Sopenharmony_ci	[RST_BUS_THS]		= { 0x9fc, BIT(16) },
127262306a36Sopenharmony_ci	[RST_BUS_I2S0]		= { 0xa20, BIT(16) },
127362306a36Sopenharmony_ci	[RST_BUS_I2S1]		= { 0xa20, BIT(17) },
127462306a36Sopenharmony_ci	[RST_BUS_I2S2]		= { 0xa20, BIT(18) },
127562306a36Sopenharmony_ci	[RST_BUS_SPDIF]		= { 0xa2c, BIT(16) },
127662306a36Sopenharmony_ci	[RST_BUS_DMIC]		= { 0xa4c, BIT(16) },
127762306a36Sopenharmony_ci	[RST_BUS_AUDIO]		= { 0xa5c, BIT(16) },
127862306a36Sopenharmony_ci	[RST_USB_PHY0]		= { 0xa70, BIT(30) },
127962306a36Sopenharmony_ci	[RST_USB_PHY1]		= { 0xa74, BIT(30) },
128062306a36Sopenharmony_ci	[RST_BUS_OHCI0]		= { 0xa8c, BIT(16) },
128162306a36Sopenharmony_ci	[RST_BUS_OHCI1]		= { 0xa8c, BIT(17) },
128262306a36Sopenharmony_ci	[RST_BUS_EHCI0]		= { 0xa8c, BIT(20) },
128362306a36Sopenharmony_ci	[RST_BUS_EHCI1]		= { 0xa8c, BIT(21) },
128462306a36Sopenharmony_ci	[RST_BUS_OTG]		= { 0xa8c, BIT(24) },
128562306a36Sopenharmony_ci	[RST_BUS_LRADC]		= { 0xa9c, BIT(16) },
128662306a36Sopenharmony_ci	[RST_BUS_DPSS_TOP]	= { 0xabc, BIT(16) },
128762306a36Sopenharmony_ci	[RST_BUS_HDMI_MAIN]	= { 0xb1c, BIT(16) },
128862306a36Sopenharmony_ci	[RST_BUS_HDMI_SUB]	= { 0xb1c, BIT(17) },
128962306a36Sopenharmony_ci	[RST_BUS_MIPI_DSI]	= { 0xb4c, BIT(16) },
129062306a36Sopenharmony_ci	[RST_BUS_TCON_LCD0]	= { 0xb7c, BIT(16) },
129162306a36Sopenharmony_ci	[RST_BUS_TCON_TV]	= { 0xb9c, BIT(16) },
129262306a36Sopenharmony_ci	[RST_BUS_LVDS0]		= { 0xbac, BIT(16) },
129362306a36Sopenharmony_ci	[RST_BUS_TVE_TOP]	= { 0xbbc, BIT(16) },
129462306a36Sopenharmony_ci	[RST_BUS_TVE]		= { 0xbbc, BIT(17) },
129562306a36Sopenharmony_ci	[RST_BUS_TVD_TOP]	= { 0xbdc, BIT(16) },
129662306a36Sopenharmony_ci	[RST_BUS_TVD]		= { 0xbdc, BIT(17) },
129762306a36Sopenharmony_ci	[RST_BUS_LEDC]		= { 0xbfc, BIT(16) },
129862306a36Sopenharmony_ci	[RST_BUS_CSI]		= { 0xc1c, BIT(16) },
129962306a36Sopenharmony_ci	[RST_BUS_TPADC]		= { 0xc5c, BIT(16) },
130062306a36Sopenharmony_ci	[RST_DSP]		= { 0xc7c, BIT(16) },
130162306a36Sopenharmony_ci	[RST_BUS_DSP_CFG]	= { 0xc7c, BIT(17) },
130262306a36Sopenharmony_ci	[RST_BUS_DSP_DBG]	= { 0xc7c, BIT(18) },
130362306a36Sopenharmony_ci	[RST_BUS_RISCV_CFG]	= { 0xd0c, BIT(16) },
130462306a36Sopenharmony_ci};
130562306a36Sopenharmony_ci
130662306a36Sopenharmony_cistatic const struct sunxi_ccu_desc sun20i_d1_ccu_desc = {
130762306a36Sopenharmony_ci	.ccu_clks	= sun20i_d1_ccu_clks,
130862306a36Sopenharmony_ci	.num_ccu_clks	= ARRAY_SIZE(sun20i_d1_ccu_clks),
130962306a36Sopenharmony_ci
131062306a36Sopenharmony_ci	.hw_clks	= &sun20i_d1_hw_clks,
131162306a36Sopenharmony_ci
131262306a36Sopenharmony_ci	.resets		= sun20i_d1_ccu_resets,
131362306a36Sopenharmony_ci	.num_resets	= ARRAY_SIZE(sun20i_d1_ccu_resets),
131462306a36Sopenharmony_ci};
131562306a36Sopenharmony_ci
131662306a36Sopenharmony_cistatic const u32 pll_regs[] = {
131762306a36Sopenharmony_ci	SUN20I_D1_PLL_CPUX_REG,
131862306a36Sopenharmony_ci	SUN20I_D1_PLL_DDR0_REG,
131962306a36Sopenharmony_ci	SUN20I_D1_PLL_PERIPH0_REG,
132062306a36Sopenharmony_ci	SUN20I_D1_PLL_VIDEO0_REG,
132162306a36Sopenharmony_ci	SUN20I_D1_PLL_VIDEO1_REG,
132262306a36Sopenharmony_ci	SUN20I_D1_PLL_VE_REG,
132362306a36Sopenharmony_ci	SUN20I_D1_PLL_AUDIO0_REG,
132462306a36Sopenharmony_ci	SUN20I_D1_PLL_AUDIO1_REG,
132562306a36Sopenharmony_ci};
132662306a36Sopenharmony_ci
132762306a36Sopenharmony_cistatic const u32 pll_video_regs[] = {
132862306a36Sopenharmony_ci	SUN20I_D1_PLL_VIDEO0_REG,
132962306a36Sopenharmony_ci	SUN20I_D1_PLL_VIDEO1_REG,
133062306a36Sopenharmony_ci};
133162306a36Sopenharmony_ci
133262306a36Sopenharmony_cistatic struct ccu_mux_nb sun20i_d1_riscv_nb = {
133362306a36Sopenharmony_ci	.common		= &riscv_clk.common,
133462306a36Sopenharmony_ci	.cm		= &riscv_clk.mux,
133562306a36Sopenharmony_ci	.delay_us       = 1,
133662306a36Sopenharmony_ci	.bypass_index   = 4, /* index of pll-periph0 */
133762306a36Sopenharmony_ci};
133862306a36Sopenharmony_ci
133962306a36Sopenharmony_cistatic int sun20i_d1_ccu_probe(struct platform_device *pdev)
134062306a36Sopenharmony_ci{
134162306a36Sopenharmony_ci	void __iomem *reg;
134262306a36Sopenharmony_ci	u32 val;
134362306a36Sopenharmony_ci	int i, ret;
134462306a36Sopenharmony_ci
134562306a36Sopenharmony_ci	reg = devm_platform_ioremap_resource(pdev, 0);
134662306a36Sopenharmony_ci	if (IS_ERR(reg))
134762306a36Sopenharmony_ci		return PTR_ERR(reg);
134862306a36Sopenharmony_ci
134962306a36Sopenharmony_ci	/* Enable the enable, LDO, and lock bits on all PLLs. */
135062306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(pll_regs); i++) {
135162306a36Sopenharmony_ci		val = readl(reg + pll_regs[i]);
135262306a36Sopenharmony_ci		val |= BIT(31) | BIT(30) | BIT(29);
135362306a36Sopenharmony_ci		writel(val, reg + pll_regs[i]);
135462306a36Sopenharmony_ci	}
135562306a36Sopenharmony_ci
135662306a36Sopenharmony_ci	/* Force PLL_CPUX factor M to 0. */
135762306a36Sopenharmony_ci	val = readl(reg + SUN20I_D1_PLL_CPUX_REG);
135862306a36Sopenharmony_ci	val &= ~GENMASK(1, 0);
135962306a36Sopenharmony_ci	writel(val, reg + SUN20I_D1_PLL_CPUX_REG);
136062306a36Sopenharmony_ci
136162306a36Sopenharmony_ci	/*
136262306a36Sopenharmony_ci	 * Force the output divider of video PLLs to 0.
136362306a36Sopenharmony_ci	 *
136462306a36Sopenharmony_ci	 * See the comment before pll-video0 definition for the reason.
136562306a36Sopenharmony_ci	 */
136662306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(pll_video_regs); i++) {
136762306a36Sopenharmony_ci		val = readl(reg + pll_video_regs[i]);
136862306a36Sopenharmony_ci		val &= ~BIT(0);
136962306a36Sopenharmony_ci		writel(val, reg + pll_video_regs[i]);
137062306a36Sopenharmony_ci	}
137162306a36Sopenharmony_ci
137262306a36Sopenharmony_ci	/* Enforce m1 = 0, m0 = 0 for PLL_AUDIO0 */
137362306a36Sopenharmony_ci	val = readl(reg + SUN20I_D1_PLL_AUDIO0_REG);
137462306a36Sopenharmony_ci	val &= ~BIT(1) | BIT(0);
137562306a36Sopenharmony_ci	writel(val, reg + SUN20I_D1_PLL_AUDIO0_REG);
137662306a36Sopenharmony_ci
137762306a36Sopenharmony_ci	/* Force fanout-27M factor N to 0. */
137862306a36Sopenharmony_ci	val = readl(reg + SUN20I_D1_FANOUT_27M_REG);
137962306a36Sopenharmony_ci	val &= ~GENMASK(9, 8);
138062306a36Sopenharmony_ci	writel(val, reg + SUN20I_D1_FANOUT_27M_REG);
138162306a36Sopenharmony_ci
138262306a36Sopenharmony_ci	ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun20i_d1_ccu_desc);
138362306a36Sopenharmony_ci	if (ret)
138462306a36Sopenharmony_ci		return ret;
138562306a36Sopenharmony_ci
138662306a36Sopenharmony_ci	/* Reparent CPU during PLL CPUX rate changes */
138762306a36Sopenharmony_ci	ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
138862306a36Sopenharmony_ci				  &sun20i_d1_riscv_nb);
138962306a36Sopenharmony_ci
139062306a36Sopenharmony_ci	return 0;
139162306a36Sopenharmony_ci}
139262306a36Sopenharmony_ci
139362306a36Sopenharmony_cistatic const struct of_device_id sun20i_d1_ccu_ids[] = {
139462306a36Sopenharmony_ci	{ .compatible = "allwinner,sun20i-d1-ccu" },
139562306a36Sopenharmony_ci	{ }
139662306a36Sopenharmony_ci};
139762306a36Sopenharmony_ci
139862306a36Sopenharmony_cistatic struct platform_driver sun20i_d1_ccu_driver = {
139962306a36Sopenharmony_ci	.probe	= sun20i_d1_ccu_probe,
140062306a36Sopenharmony_ci	.driver	= {
140162306a36Sopenharmony_ci		.name			= "sun20i-d1-ccu",
140262306a36Sopenharmony_ci		.suppress_bind_attrs	= true,
140362306a36Sopenharmony_ci		.of_match_table		= sun20i_d1_ccu_ids,
140462306a36Sopenharmony_ci	},
140562306a36Sopenharmony_ci};
140662306a36Sopenharmony_cimodule_platform_driver(sun20i_d1_ccu_driver);
140762306a36Sopenharmony_ci
140862306a36Sopenharmony_ciMODULE_IMPORT_NS(SUNXI_CCU);
140962306a36Sopenharmony_ciMODULE_LICENSE("GPL");
1410