162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2018-2019 SiFive, Inc.
462306a36Sopenharmony_ci * Wesley Terpstra
562306a36Sopenharmony_ci * Paul Walmsley
662306a36Sopenharmony_ci * Zong Li
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#ifndef __SIFIVE_CLK_SIFIVE_PRCI_H
1062306a36Sopenharmony_ci#define __SIFIVE_CLK_SIFIVE_PRCI_H
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include <linux/clk/analogbits-wrpll-cln28hpc.h>
1362306a36Sopenharmony_ci#include <linux/clk-provider.h>
1462306a36Sopenharmony_ci#include <linux/reset/reset-simple.h>
1562306a36Sopenharmony_ci#include <linux/platform_device.h>
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci/*
1862306a36Sopenharmony_ci * EXPECTED_CLK_PARENT_COUNT: how many parent clocks this driver expects:
1962306a36Sopenharmony_ci *     hfclk and rtcclk
2062306a36Sopenharmony_ci */
2162306a36Sopenharmony_ci#define EXPECTED_CLK_PARENT_COUNT 2
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci/*
2462306a36Sopenharmony_ci * Register offsets and bitmasks
2562306a36Sopenharmony_ci */
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci/* COREPLLCFG0 */
2862306a36Sopenharmony_ci#define PRCI_COREPLLCFG0_OFFSET		0x4
2962306a36Sopenharmony_ci#define PRCI_COREPLLCFG0_DIVR_SHIFT	0
3062306a36Sopenharmony_ci#define PRCI_COREPLLCFG0_DIVR_MASK	(0x3f << PRCI_COREPLLCFG0_DIVR_SHIFT)
3162306a36Sopenharmony_ci#define PRCI_COREPLLCFG0_DIVF_SHIFT	6
3262306a36Sopenharmony_ci#define PRCI_COREPLLCFG0_DIVF_MASK	(0x1ff << PRCI_COREPLLCFG0_DIVF_SHIFT)
3362306a36Sopenharmony_ci#define PRCI_COREPLLCFG0_DIVQ_SHIFT	15
3462306a36Sopenharmony_ci#define PRCI_COREPLLCFG0_DIVQ_MASK	(0x7 << PRCI_COREPLLCFG0_DIVQ_SHIFT)
3562306a36Sopenharmony_ci#define PRCI_COREPLLCFG0_RANGE_SHIFT	18
3662306a36Sopenharmony_ci#define PRCI_COREPLLCFG0_RANGE_MASK	(0x7 << PRCI_COREPLLCFG0_RANGE_SHIFT)
3762306a36Sopenharmony_ci#define PRCI_COREPLLCFG0_BYPASS_SHIFT	24
3862306a36Sopenharmony_ci#define PRCI_COREPLLCFG0_BYPASS_MASK	(0x1 << PRCI_COREPLLCFG0_BYPASS_SHIFT)
3962306a36Sopenharmony_ci#define PRCI_COREPLLCFG0_FSE_SHIFT	25
4062306a36Sopenharmony_ci#define PRCI_COREPLLCFG0_FSE_MASK	(0x1 << PRCI_COREPLLCFG0_FSE_SHIFT)
4162306a36Sopenharmony_ci#define PRCI_COREPLLCFG0_LOCK_SHIFT	31
4262306a36Sopenharmony_ci#define PRCI_COREPLLCFG0_LOCK_MASK	(0x1 << PRCI_COREPLLCFG0_LOCK_SHIFT)
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci/* COREPLLCFG1 */
4562306a36Sopenharmony_ci#define PRCI_COREPLLCFG1_OFFSET		0x8
4662306a36Sopenharmony_ci#define PRCI_COREPLLCFG1_CKE_SHIFT	31
4762306a36Sopenharmony_ci#define PRCI_COREPLLCFG1_CKE_MASK	(0x1 << PRCI_COREPLLCFG1_CKE_SHIFT)
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci/* DDRPLLCFG0 */
5062306a36Sopenharmony_ci#define PRCI_DDRPLLCFG0_OFFSET		0xc
5162306a36Sopenharmony_ci#define PRCI_DDRPLLCFG0_DIVR_SHIFT	0
5262306a36Sopenharmony_ci#define PRCI_DDRPLLCFG0_DIVR_MASK	(0x3f << PRCI_DDRPLLCFG0_DIVR_SHIFT)
5362306a36Sopenharmony_ci#define PRCI_DDRPLLCFG0_DIVF_SHIFT	6
5462306a36Sopenharmony_ci#define PRCI_DDRPLLCFG0_DIVF_MASK	(0x1ff << PRCI_DDRPLLCFG0_DIVF_SHIFT)
5562306a36Sopenharmony_ci#define PRCI_DDRPLLCFG0_DIVQ_SHIFT	15
5662306a36Sopenharmony_ci#define PRCI_DDRPLLCFG0_DIVQ_MASK	(0x7 << PRCI_DDRPLLCFG0_DIVQ_SHIFT)
5762306a36Sopenharmony_ci#define PRCI_DDRPLLCFG0_RANGE_SHIFT	18
5862306a36Sopenharmony_ci#define PRCI_DDRPLLCFG0_RANGE_MASK	(0x7 << PRCI_DDRPLLCFG0_RANGE_SHIFT)
5962306a36Sopenharmony_ci#define PRCI_DDRPLLCFG0_BYPASS_SHIFT	24
6062306a36Sopenharmony_ci#define PRCI_DDRPLLCFG0_BYPASS_MASK	(0x1 << PRCI_DDRPLLCFG0_BYPASS_SHIFT)
6162306a36Sopenharmony_ci#define PRCI_DDRPLLCFG0_FSE_SHIFT	25
6262306a36Sopenharmony_ci#define PRCI_DDRPLLCFG0_FSE_MASK	(0x1 << PRCI_DDRPLLCFG0_FSE_SHIFT)
6362306a36Sopenharmony_ci#define PRCI_DDRPLLCFG0_LOCK_SHIFT	31
6462306a36Sopenharmony_ci#define PRCI_DDRPLLCFG0_LOCK_MASK	(0x1 << PRCI_DDRPLLCFG0_LOCK_SHIFT)
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci/* DDRPLLCFG1 */
6762306a36Sopenharmony_ci#define PRCI_DDRPLLCFG1_OFFSET		0x10
6862306a36Sopenharmony_ci#define PRCI_DDRPLLCFG1_CKE_SHIFT	31
6962306a36Sopenharmony_ci#define PRCI_DDRPLLCFG1_CKE_MASK	(0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT)
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci/* PCIEAUX */
7262306a36Sopenharmony_ci#define PRCI_PCIE_AUX_OFFSET		0x14
7362306a36Sopenharmony_ci#define PRCI_PCIE_AUX_EN_SHIFT		0
7462306a36Sopenharmony_ci#define PRCI_PCIE_AUX_EN_MASK		(0x1 << PRCI_PCIE_AUX_EN_SHIFT)
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci/* GEMGXLPLLCFG0 */
7762306a36Sopenharmony_ci#define PRCI_GEMGXLPLLCFG0_OFFSET	0x1c
7862306a36Sopenharmony_ci#define PRCI_GEMGXLPLLCFG0_DIVR_SHIFT	0
7962306a36Sopenharmony_ci#define PRCI_GEMGXLPLLCFG0_DIVR_MASK	(0x3f << PRCI_GEMGXLPLLCFG0_DIVR_SHIFT)
8062306a36Sopenharmony_ci#define PRCI_GEMGXLPLLCFG0_DIVF_SHIFT	6
8162306a36Sopenharmony_ci#define PRCI_GEMGXLPLLCFG0_DIVF_MASK	(0x1ff << PRCI_GEMGXLPLLCFG0_DIVF_SHIFT)
8262306a36Sopenharmony_ci#define PRCI_GEMGXLPLLCFG0_DIVQ_SHIFT	15
8362306a36Sopenharmony_ci#define PRCI_GEMGXLPLLCFG0_DIVQ_MASK	(0x7 << PRCI_GEMGXLPLLCFG0_DIVQ_SHIFT)
8462306a36Sopenharmony_ci#define PRCI_GEMGXLPLLCFG0_RANGE_SHIFT	18
8562306a36Sopenharmony_ci#define PRCI_GEMGXLPLLCFG0_RANGE_MASK	(0x7 << PRCI_GEMGXLPLLCFG0_RANGE_SHIFT)
8662306a36Sopenharmony_ci#define PRCI_GEMGXLPLLCFG0_BYPASS_SHIFT	24
8762306a36Sopenharmony_ci#define PRCI_GEMGXLPLLCFG0_BYPASS_MASK	(0x1 << PRCI_GEMGXLPLLCFG0_BYPASS_SHIFT)
8862306a36Sopenharmony_ci#define PRCI_GEMGXLPLLCFG0_FSE_SHIFT	25
8962306a36Sopenharmony_ci#define PRCI_GEMGXLPLLCFG0_FSE_MASK	(0x1 << PRCI_GEMGXLPLLCFG0_FSE_SHIFT)
9062306a36Sopenharmony_ci#define PRCI_GEMGXLPLLCFG0_LOCK_SHIFT	31
9162306a36Sopenharmony_ci#define PRCI_GEMGXLPLLCFG0_LOCK_MASK	(0x1 << PRCI_GEMGXLPLLCFG0_LOCK_SHIFT)
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci/* GEMGXLPLLCFG1 */
9462306a36Sopenharmony_ci#define PRCI_GEMGXLPLLCFG1_OFFSET	0x20
9562306a36Sopenharmony_ci#define PRCI_GEMGXLPLLCFG1_CKE_SHIFT	31
9662306a36Sopenharmony_ci#define PRCI_GEMGXLPLLCFG1_CKE_MASK	(0x1 << PRCI_GEMGXLPLLCFG1_CKE_SHIFT)
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci/* CORECLKSEL */
9962306a36Sopenharmony_ci#define PRCI_CORECLKSEL_OFFSET			0x24
10062306a36Sopenharmony_ci#define PRCI_CORECLKSEL_CORECLKSEL_SHIFT	0
10162306a36Sopenharmony_ci#define PRCI_CORECLKSEL_CORECLKSEL_MASK					\
10262306a36Sopenharmony_ci		(0x1 << PRCI_CORECLKSEL_CORECLKSEL_SHIFT)
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci/* DEVICESRESETREG */
10562306a36Sopenharmony_ci#define PRCI_DEVICESRESETREG_OFFSET				0x28
10662306a36Sopenharmony_ci#define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_SHIFT		0
10762306a36Sopenharmony_ci#define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_MASK			\
10862306a36Sopenharmony_ci		(0x1 << PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_SHIFT)
10962306a36Sopenharmony_ci#define PRCI_DEVICESRESETREG_DDR_AXI_RST_N_SHIFT		1
11062306a36Sopenharmony_ci#define PRCI_DEVICESRESETREG_DDR_AXI_RST_N_MASK				\
11162306a36Sopenharmony_ci		(0x1 << PRCI_DEVICESRESETREG_DDR_AXI_RST_N_SHIFT)
11262306a36Sopenharmony_ci#define PRCI_DEVICESRESETREG_DDR_AHB_RST_N_SHIFT		2
11362306a36Sopenharmony_ci#define PRCI_DEVICESRESETREG_DDR_AHB_RST_N_MASK				\
11462306a36Sopenharmony_ci		(0x1 << PRCI_DEVICESRESETREG_DDR_AHB_RST_N_SHIFT)
11562306a36Sopenharmony_ci#define PRCI_DEVICESRESETREG_DDR_PHY_RST_N_SHIFT		3
11662306a36Sopenharmony_ci#define PRCI_DEVICESRESETREG_DDR_PHY_RST_N_MASK				\
11762306a36Sopenharmony_ci		(0x1 << PRCI_DEVICESRESETREG_DDR_PHY_RST_N_SHIFT)
11862306a36Sopenharmony_ci#define PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT			5
11962306a36Sopenharmony_ci#define PRCI_DEVICESRESETREG_GEMGXL_RST_N_MASK				\
12062306a36Sopenharmony_ci		(0x1 << PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT)
12162306a36Sopenharmony_ci#define PRCI_DEVICESRESETREG_CHIPLINK_RST_N_SHIFT		6
12262306a36Sopenharmony_ci#define PRCI_DEVICESRESETREG_CHIPLINK_RST_N_MASK			\
12362306a36Sopenharmony_ci		(0x1 << PRCI_DEVICESRESETREG_CHIPLINK_RST_N_SHIFT)
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci#define PRCI_RST_NR						7
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci/* CLKMUXSTATUSREG */
12862306a36Sopenharmony_ci#define PRCI_CLKMUXSTATUSREG_OFFSET				0x2c
12962306a36Sopenharmony_ci#define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT		1
13062306a36Sopenharmony_ci#define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK			\
13162306a36Sopenharmony_ci		(0x1 << PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT)
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci/* CLTXPLLCFG0 */
13462306a36Sopenharmony_ci#define PRCI_CLTXPLLCFG0_OFFSET		0x30
13562306a36Sopenharmony_ci#define PRCI_CLTXPLLCFG0_DIVR_SHIFT	0
13662306a36Sopenharmony_ci#define PRCI_CLTXPLLCFG0_DIVR_MASK	(0x3f << PRCI_CLTXPLLCFG0_DIVR_SHIFT)
13762306a36Sopenharmony_ci#define PRCI_CLTXPLLCFG0_DIVF_SHIFT	6
13862306a36Sopenharmony_ci#define PRCI_CLTXPLLCFG0_DIVF_MASK	(0x1ff << PRCI_CLTXPLLCFG0_DIVF_SHIFT)
13962306a36Sopenharmony_ci#define PRCI_CLTXPLLCFG0_DIVQ_SHIFT	15
14062306a36Sopenharmony_ci#define PRCI_CLTXPLLCFG0_DIVQ_MASK	(0x7 << PRCI_CLTXPLLCFG0_DIVQ_SHIFT)
14162306a36Sopenharmony_ci#define PRCI_CLTXPLLCFG0_RANGE_SHIFT	18
14262306a36Sopenharmony_ci#define PRCI_CLTXPLLCFG0_RANGE_MASK	(0x7 << PRCI_CLTXPLLCFG0_RANGE_SHIFT)
14362306a36Sopenharmony_ci#define PRCI_CLTXPLLCFG0_BYPASS_SHIFT	24
14462306a36Sopenharmony_ci#define PRCI_CLTXPLLCFG0_BYPASS_MASK	(0x1 << PRCI_CLTXPLLCFG0_BYPASS_SHIFT)
14562306a36Sopenharmony_ci#define PRCI_CLTXPLLCFG0_FSE_SHIFT	25
14662306a36Sopenharmony_ci#define PRCI_CLTXPLLCFG0_FSE_MASK	(0x1 << PRCI_CLTXPLLCFG0_FSE_SHIFT)
14762306a36Sopenharmony_ci#define PRCI_CLTXPLLCFG0_LOCK_SHIFT	31
14862306a36Sopenharmony_ci#define PRCI_CLTXPLLCFG0_LOCK_MASK	(0x1 << PRCI_CLTXPLLCFG0_LOCK_SHIFT)
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci/* CLTXPLLCFG1 */
15162306a36Sopenharmony_ci#define PRCI_CLTXPLLCFG1_OFFSET		0x34
15262306a36Sopenharmony_ci#define PRCI_CLTXPLLCFG1_CKE_SHIFT	31
15362306a36Sopenharmony_ci#define PRCI_CLTXPLLCFG1_CKE_MASK	(0x1 << PRCI_CLTXPLLCFG1_CKE_SHIFT)
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci/* DVFSCOREPLLCFG0 */
15662306a36Sopenharmony_ci#define PRCI_DVFSCOREPLLCFG0_OFFSET	0x38
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci/* DVFSCOREPLLCFG1 */
15962306a36Sopenharmony_ci#define PRCI_DVFSCOREPLLCFG1_OFFSET	0x3c
16062306a36Sopenharmony_ci#define PRCI_DVFSCOREPLLCFG1_CKE_SHIFT	31
16162306a36Sopenharmony_ci#define PRCI_DVFSCOREPLLCFG1_CKE_MASK	(0x1 << PRCI_DVFSCOREPLLCFG1_CKE_SHIFT)
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci/* COREPLLSEL */
16462306a36Sopenharmony_ci#define PRCI_COREPLLSEL_OFFSET			0x40
16562306a36Sopenharmony_ci#define PRCI_COREPLLSEL_COREPLLSEL_SHIFT	0
16662306a36Sopenharmony_ci#define PRCI_COREPLLSEL_COREPLLSEL_MASK					\
16762306a36Sopenharmony_ci		(0x1 << PRCI_COREPLLSEL_COREPLLSEL_SHIFT)
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci/* HFPCLKPLLCFG0 */
17062306a36Sopenharmony_ci#define PRCI_HFPCLKPLLCFG0_OFFSET		0x50
17162306a36Sopenharmony_ci#define PRCI_HFPCLKPLL_CFG0_DIVR_SHIFT		0
17262306a36Sopenharmony_ci#define PRCI_HFPCLKPLL_CFG0_DIVR_MASK					\
17362306a36Sopenharmony_ci		(0x3f << PRCI_HFPCLKPLLCFG0_DIVR_SHIFT)
17462306a36Sopenharmony_ci#define PRCI_HFPCLKPLL_CFG0_DIVF_SHIFT		6
17562306a36Sopenharmony_ci#define PRCI_HFPCLKPLL_CFG0_DIVF_MASK					\
17662306a36Sopenharmony_ci		(0x1ff << PRCI_HFPCLKPLLCFG0_DIVF_SHIFT)
17762306a36Sopenharmony_ci#define PRCI_HFPCLKPLL_CFG0_DIVQ_SHIFT		15
17862306a36Sopenharmony_ci#define PRCI_HFPCLKPLL_CFG0_DIVQ_MASK					\
17962306a36Sopenharmony_ci		(0x7 << PRCI_HFPCLKPLLCFG0_DIVQ_SHIFT)
18062306a36Sopenharmony_ci#define PRCI_HFPCLKPLL_CFG0_RANGE_SHIFT		18
18162306a36Sopenharmony_ci#define PRCI_HFPCLKPLL_CFG0_RANGE_MASK					\
18262306a36Sopenharmony_ci		(0x7 << PRCI_HFPCLKPLLCFG0_RANGE_SHIFT)
18362306a36Sopenharmony_ci#define PRCI_HFPCLKPLL_CFG0_BYPASS_SHIFT	24
18462306a36Sopenharmony_ci#define PRCI_HFPCLKPLL_CFG0_BYPASS_MASK					\
18562306a36Sopenharmony_ci		(0x1 << PRCI_HFPCLKPLLCFG0_BYPASS_SHIFT)
18662306a36Sopenharmony_ci#define PRCI_HFPCLKPLL_CFG0_FSE_SHIFT		25
18762306a36Sopenharmony_ci#define PRCI_HFPCLKPLL_CFG0_FSE_MASK					\
18862306a36Sopenharmony_ci		(0x1 << PRCI_HFPCLKPLLCFG0_FSE_SHIFT)
18962306a36Sopenharmony_ci#define PRCI_HFPCLKPLL_CFG0_LOCK_SHIFT		31
19062306a36Sopenharmony_ci#define PRCI_HFPCLKPLL_CFG0_LOCK_MASK					\
19162306a36Sopenharmony_ci		(0x1 << PRCI_HFPCLKPLLCFG0_LOCK_SHIFT)
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci/* HFPCLKPLLCFG1 */
19462306a36Sopenharmony_ci#define PRCI_HFPCLKPLLCFG1_OFFSET		0x54
19562306a36Sopenharmony_ci#define PRCI_HFPCLKPLLCFG1_CKE_SHIFT		31
19662306a36Sopenharmony_ci#define PRCI_HFPCLKPLLCFG1_CKE_MASK					\
19762306a36Sopenharmony_ci		(0x1 << PRCI_HFPCLKPLLCFG1_CKE_SHIFT)
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci/* HFPCLKPLLSEL */
20062306a36Sopenharmony_ci#define PRCI_HFPCLKPLLSEL_OFFSET		0x58
20162306a36Sopenharmony_ci#define PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_SHIFT	0
20262306a36Sopenharmony_ci#define PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_MASK				\
20362306a36Sopenharmony_ci		(0x1 << PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_SHIFT)
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci/* HFPCLKPLLDIV */
20662306a36Sopenharmony_ci#define PRCI_HFPCLKPLLDIV_OFFSET		0x5c
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_ci/* PRCIPLL */
20962306a36Sopenharmony_ci#define PRCI_PRCIPLL_OFFSET			0xe0
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci/* PROCMONCFG */
21262306a36Sopenharmony_ci#define PRCI_PROCMONCFG_OFFSET			0xf0
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ci/*
21562306a36Sopenharmony_ci * Private structures
21662306a36Sopenharmony_ci */
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci/**
21962306a36Sopenharmony_ci * struct __prci_data - per-device-instance data
22062306a36Sopenharmony_ci * @va: base virtual address of the PRCI IP block
22162306a36Sopenharmony_ci * @hw_clks: encapsulates struct clk_hw records
22262306a36Sopenharmony_ci *
22362306a36Sopenharmony_ci * PRCI per-device instance data
22462306a36Sopenharmony_ci */
22562306a36Sopenharmony_cistruct __prci_data {
22662306a36Sopenharmony_ci	void __iomem *va;
22762306a36Sopenharmony_ci	struct reset_simple_data reset;
22862306a36Sopenharmony_ci	struct clk_hw_onecell_data hw_clks;
22962306a36Sopenharmony_ci};
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci/**
23262306a36Sopenharmony_ci * struct __prci_wrpll_data - WRPLL configuration and integration data
23362306a36Sopenharmony_ci * @c: WRPLL current configuration record
23462306a36Sopenharmony_ci * @enable_bypass: fn ptr to code to bypass the WRPLL (if applicable; else NULL)
23562306a36Sopenharmony_ci * @disable_bypass: fn ptr to code to not bypass the WRPLL (or NULL)
23662306a36Sopenharmony_ci * @cfg0_offs: WRPLL CFG0 register offset (in bytes) from the PRCI base address
23762306a36Sopenharmony_ci * @cfg1_offs: WRPLL CFG1 register offset (in bytes) from the PRCI base address
23862306a36Sopenharmony_ci *
23962306a36Sopenharmony_ci * @enable_bypass and @disable_bypass are used for WRPLL instances
24062306a36Sopenharmony_ci * that contain a separate external glitchless clock mux downstream
24162306a36Sopenharmony_ci * from the PLL.  The WRPLL internal bypass mux is not glitchless.
24262306a36Sopenharmony_ci */
24362306a36Sopenharmony_cistruct __prci_wrpll_data {
24462306a36Sopenharmony_ci	struct wrpll_cfg c;
24562306a36Sopenharmony_ci	void (*enable_bypass)(struct __prci_data *pd);
24662306a36Sopenharmony_ci	void (*disable_bypass)(struct __prci_data *pd);
24762306a36Sopenharmony_ci	u8 cfg0_offs;
24862306a36Sopenharmony_ci	u8 cfg1_offs;
24962306a36Sopenharmony_ci};
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci/**
25262306a36Sopenharmony_ci * struct __prci_clock - describes a clock device managed by PRCI
25362306a36Sopenharmony_ci * @name: user-readable clock name string - should match the manual
25462306a36Sopenharmony_ci * @parent_name: parent name for this clock
25562306a36Sopenharmony_ci * @ops: struct clk_ops for the Linux clock framework to use for control
25662306a36Sopenharmony_ci * @hw: Linux-private clock data
25762306a36Sopenharmony_ci * @pwd: WRPLL-specific data, associated with this clock (if not NULL)
25862306a36Sopenharmony_ci * @pd: PRCI-specific data associated with this clock (if not NULL)
25962306a36Sopenharmony_ci *
26062306a36Sopenharmony_ci * PRCI clock data.  Used by the PRCI driver to register PRCI-provided
26162306a36Sopenharmony_ci * clocks to the Linux clock infrastructure.
26262306a36Sopenharmony_ci */
26362306a36Sopenharmony_cistruct __prci_clock {
26462306a36Sopenharmony_ci	const char *name;
26562306a36Sopenharmony_ci	const char *parent_name;
26662306a36Sopenharmony_ci	const struct clk_ops *ops;
26762306a36Sopenharmony_ci	struct clk_hw hw;
26862306a36Sopenharmony_ci	struct __prci_wrpll_data *pwd;
26962306a36Sopenharmony_ci	struct __prci_data *pd;
27062306a36Sopenharmony_ci};
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_ci#define clk_hw_to_prci_clock(pwd) container_of(pwd, struct __prci_clock, hw)
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ci/*
27562306a36Sopenharmony_ci * struct prci_clk_desc - describes the information of clocks of each SoCs
27662306a36Sopenharmony_ci * @clks: point to a array of __prci_clock
27762306a36Sopenharmony_ci * @num_clks: the number of element of clks
27862306a36Sopenharmony_ci */
27962306a36Sopenharmony_cistruct prci_clk_desc {
28062306a36Sopenharmony_ci	struct __prci_clock *clks;
28162306a36Sopenharmony_ci	size_t num_clks;
28262306a36Sopenharmony_ci};
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci/* Core clock mux control */
28562306a36Sopenharmony_civoid sifive_prci_coreclksel_use_hfclk(struct __prci_data *pd);
28662306a36Sopenharmony_civoid sifive_prci_coreclksel_use_corepll(struct __prci_data *pd);
28762306a36Sopenharmony_civoid sifive_prci_coreclksel_use_final_corepll(struct __prci_data *pd);
28862306a36Sopenharmony_civoid sifive_prci_corepllsel_use_dvfscorepll(struct __prci_data *pd);
28962306a36Sopenharmony_civoid sifive_prci_corepllsel_use_corepll(struct __prci_data *pd);
29062306a36Sopenharmony_civoid sifive_prci_hfpclkpllsel_use_hfclk(struct __prci_data *pd);
29162306a36Sopenharmony_civoid sifive_prci_hfpclkpllsel_use_hfpclkpll(struct __prci_data *pd);
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_ci/* Linux clock framework integration */
29462306a36Sopenharmony_cilong sifive_prci_wrpll_round_rate(struct clk_hw *hw, unsigned long rate,
29562306a36Sopenharmony_ci				  unsigned long *parent_rate);
29662306a36Sopenharmony_ciint sifive_prci_wrpll_set_rate(struct clk_hw *hw, unsigned long rate,
29762306a36Sopenharmony_ci			       unsigned long parent_rate);
29862306a36Sopenharmony_ciint sifive_clk_is_enabled(struct clk_hw *hw);
29962306a36Sopenharmony_ciint sifive_prci_clock_enable(struct clk_hw *hw);
30062306a36Sopenharmony_civoid sifive_prci_clock_disable(struct clk_hw *hw);
30162306a36Sopenharmony_ciunsigned long sifive_prci_wrpll_recalc_rate(struct clk_hw *hw,
30262306a36Sopenharmony_ci					    unsigned long parent_rate);
30362306a36Sopenharmony_ciunsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw,
30462306a36Sopenharmony_ci					       unsigned long parent_rate);
30562306a36Sopenharmony_ciunsigned long sifive_prci_hfpclkplldiv_recalc_rate(struct clk_hw *hw,
30662306a36Sopenharmony_ci						   unsigned long parent_rate);
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ciint sifive_prci_pcie_aux_clock_is_enabled(struct clk_hw *hw);
30962306a36Sopenharmony_ciint sifive_prci_pcie_aux_clock_enable(struct clk_hw *hw);
31062306a36Sopenharmony_civoid sifive_prci_pcie_aux_clock_disable(struct clk_hw *hw);
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_ci#endif /* __SIFIVE_CLK_SIFIVE_PRCI_H */
313