/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
 * Author: Finley Xiao <finley.xiao@rock-chips.com>
 */

#ifndef _ASM_ARCH_CRU_RK3506_H
#define _ASM_ARCH_CRU_RK3506_H

#include <linux/bitops.h>
#include <linux/bitfield.h>

#define MHz		1000000
#define KHz		1000
#define OSC_HZ		(24 * MHz)

/* RK3506 pll id */
enum rk3506_pll_id {
	GPLL,
	V0PLL,
	V1PLL,
	PLL_COUNT,
};

struct rk3506_clk_priv {
	unsigned long gpll_hz;
	unsigned long gpll_div_hz;
	unsigned long gpll_div_100mhz;
	unsigned long v0pll_hz;
	unsigned long v0pll_div_hz;
	unsigned long v1pll_hz;
	unsigned long v1pll_div_hz;
};

struct pll_rate_table {
	unsigned long rate;
	unsigned int fbdiv;
	unsigned int postdiv1;
	unsigned int refdiv;
	unsigned int postdiv2;
	unsigned int dsmpd;
	unsigned int frac;
};

#define RK3506_CRU_BASE			0xff9a0000
#define RK3506_MODE_CON			0x0280
#define RK3506_CLKSEL_CON(x)		(RK3506_CRU_BASE + 0x0300 + (x) * 0x4)
#define RK3506_SOFTRST_CON0		0x0a00
#define RK3506_GLB_SRST_FST		0x0c08
#define RK3506_GLB_SRST_SND		0x0c0c
#define RK3506_PLL_CON(x)		(0x10000 + (x) * 0x4)
#define RK3506_SCRU_BASE		0xff9a8000
#define RK3506_PMU_CRU_BASE		0xff9b0000
#define RK3506_PMU_CLKSEL_CON(x)	(RK3506_PMU_CRU_BASE + 0x0300 + (x) * 0x4)

enum {
	/* CRU_CLKSEL_CON00 */
	CLK_GPLL_DIV_MASK		= GENMASK(9, 6),
	CLK_GPLL_DIV_100M_MASK		= GENMASK(13, 10),

	/* CRU_CLKSEL_CON01 */
	CLK_V0PLL_DIV_MASK		= GENMASK(3, 0),
	CLK_V1PLL_DIV_MASK		= GENMASK(7, 4),

	/* CRU_CLKSEL_CON15 */
	CLK_CORE_SRC_DIV_MASK		= GENMASK(4, 0),
	CLK_CORE_SRC_SEL_MASK		= GENMASK(6, 5),
	CLK_CORE_SEL_GPLL		= 0,
	CLK_CORE_SEL_V0PLL,
	CLK_CORE_SEL_V1PLL,

	ACLK_CORE_DIV_MASK		= GENMASK(12, 9),

	/* CRU_CLKSEL_CON16 */
	PCLK_CORE_DIV_MASK		= GENMASK(3, 0),

	/* CRU_CLKSEL_CON21 */
	ACLK_BUS_DIV_MASK		= GENMASK(4, 0),
	ACLK_BUS_SEL_MASK		= GENMASK(6, 5),
	ACLK_BUS_SEL_GPLL_DIV		= 0,
	ACLK_BUS_SEL_V0PLL_DIV,
	ACLK_BUS_SEL_V1PLL_DIV,

	HCLK_BUS_DIV_MASK		= GENMASK(11, 7),
	HCLK_BUS_SEL_MASK		= GENMASK(13, 12),

	/* CRU_CLKSEL_CON22 */
	PCLK_BUS_DIV_MASK		= GENMASK(4, 0),
	PCLK_BUS_SEL_MASK		= GENMASK(6, 5),

	/* CRU_CLKSEL_CON29 */
	HCLK_LSPERI_DIV_MASK		= GENMASK(4, 0),
	HCLK_LSPERI_SEL_MASK		= GENMASK(6, 5),

	/* CRU_CLKSEL_CON32 */
	CLK_I2C0_DIV_MASK		= GENMASK(3, 0),
	CLK_I2C0_SEL_MASK		= GENMASK(5, 4),
	CLK_I2C_SEL_GPLL		= 0,
	CLK_I2C_SEL_V0PLL,
	CLK_I2C_SEL_V1PLL,
	CLK_I2C1_DIV_MASK		= GENMASK(9, 6),
	CLK_I2C1_SEL_MASK		= GENMASK(11, 10),

	/* CRU_CLKSEL_CON33 */
	CLK_I2C2_DIV_MASK		= GENMASK(3, 0),
	CLK_I2C2_SEL_MASK		= GENMASK(5, 4),
	CLK_PWM1_DIV_MASK		= GENMASK(9, 6),
	CLK_PWM1_SEL_MASK		= GENMASK(11, 10),
	CLK_PWM1_SEL_GPLL_DIV		= 0,
	CLK_PWM1_SEL_V0PLL_DIV,
	CLK_PWM1_SEL_V1PLL_DIV,

	/* CRU_CLKSEL_CON34 */
	CLK_SPI0_DIV_MASK		= GENMASK(7, 4),
	CLK_SPI0_SEL_MASK		= GENMASK(9, 8),
	CLK_SPI_SEL_24M			= 0,
	CLK_SPI_SEL_GPLL_DIV,
	CLK_SPI_SEL_V0PLL_DIV,
	CLK_SPI_SEL_V1PLL_DIV,
	CLK_SPI1_DIV_MASK		= GENMASK(13, 10),
	CLK_SPI1_SEL_MASK		= GENMASK(15, 14),

	/* CRU_CLKSEL_CON49 */
	ACLK_HSPERI_DIV_MASK		= GENMASK(4, 0),
	ACLK_HSPERI_SEL_MASK		= GENMASK(6, 5),
	ACLK_HSPERI_SEL_GPLL_DIV	= 0,
	ACLK_HSPERI_SEL_V0PLL_DIV,
	ACLK_HSPERI_SEL_V1PLL_DIV,

	CCLK_SDMMC_DIV_MASK		= GENMASK(12, 7),
	CCLK_SDMMC_SEL_MASK		= GENMASK(14, 13),
	CCLK_SDMMC_SEL_24M		= 0,
	CCLK_SDMMC_SEL_GPLL,
	CCLK_SDMMC_SEL_V0PLL,
	CCLK_SDMMC_SEL_V1PLL,

	/* CRU_CLKSEL_CON50 */
	SCLK_FSPI_DIV_MASK		= GENMASK(4, 0),
	SCLK_FSPI_SEL_MASK		= GENMASK(6, 5),
	SCLK_FSPI_SEL_24M		= 0,
	SCLK_FSPI_SEL_GPLL,
	SCLK_FSPI_SEL_V0PLL,
	SCLK_FSPI_SEL_V1PLL,
	CLK_MAC_DIV_MASK		= GENMASK(11, 7),

	/* CRU_CLKSEL_CON54 */
	CLK_SARADC_DIV_MASK		= GENMASK(3, 0),
	CLK_SARADC_SEL_MASK		= GENMASK(5, 4),
	CLK_SARADC_SEL_24M		= 0,
	CLK_SARADC_SEL_400K,
	CLK_SARADC_SEL_32K,

	/* CRU_CLKSEL_CON60 */
	DCLK_VOP_DIV_MASK		= GENMASK(7, 0),
	DCLK_VOP_SEL_MASK		= GENMASK(10, 8),
	DCLK_VOP_SEL_24M		= 0,
	DCLK_VOP_SEL_GPLL,
	DCLK_VOP_SEL_V0PLL,
	DCLK_VOP_SEL_V1PLL,
	DCLK_VOP_SEL_FRAC_VOIC1,
	DCLK_VOP_SEL_FRAC_COMMON0,
	DCLK_VOP_SEL_FRAC_COMMON1,
	DCLK_VOP_SEL_FRAC_COMMON2,

	/* CRU_CLKSEL_CON61 */
	CLK_TSADC_DIV_MASK		= GENMASK(7, 0),
	CLK_TSADC_TSEN_DIV_MASK		= GENMASK(10, 8),

	/* PMUCRU_CLKSEL_CON00 */
	CLK_PWM0_DIV_MASK		= GENMASK(9, 6),
	CLK_MAC_OUT_DIV_MASK		= GENMASK(15, 10),

	/* SCRU_CLKSEL_CON104 */
	CLK_PKA_CRYPTO_DIV_MASK		= GENMASK(11, 7),
	CLK_PKA_CRYPTO_SEL_MASK		= GENMASK(13, 12),
	CLK_PKA_CRYPTO_SEL_GPLL		= 0,
	CLK_PKA_CRYPTO_SEL_V0PLL,
	CLK_PKA_CRYPTO_SEL_V1PLL,
};

#endif /* _ASM_ARCH_CRU_RK3506_H */
