// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2022 Rockchip Electronics Co. Ltd.
* Author: Elaine Zhang <zhangqing@rock-chips.com>
*/
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <dt-bindings/clock/rockchip,rv1106-cru.h>
#include "clk.h"
/*
* Register offsets inside the CRU region. The RV1106 CRU is split into
* several sub-blocks, one per power domain, all accessed through a
* single register window.
*/
#define RV1106_TOPCRU_BASE 0x10000
#define RV1106_PERICRU_BASE 0x12000
#define RV1106_VICRU_BASE 0x14000
#define RV1106_NPUCRU_BASE 0x16000
#define RV1106_CORECRU_BASE 0x18000
#define RV1106_VEPUCRU_BASE 0x1a000
#define RV1106_VOCRU_BASE 0x1c000
#define RV1106_DDRCRU_BASE 0x1e000
#define RV1106_SUBDDRCRU_BASE 0x1f000
#define RV1106_PMUCLKSEL_CON(x) ((x) * 0x4 + 0x300)
#define RV1106_PMUCLKGATE_CON(x) ((x) * 0x4 + 0x800)
#define RV1106_PLL_CON(x) ((x) * 0x4 + RV1106_TOPCRU_BASE)
#define RV1106_MODE_CON (0x280 + RV1106_TOPCRU_BASE)
#define RV1106_CLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1106_TOPCRU_BASE)
#define RV1106_CLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1106_TOPCRU_BASE)
#define RV1106_GLB_SRST_FST (0xc08 + RV1106_TOPCRU_BASE)
#define RV1106_PERICLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1106_PERICRU_BASE)
#define RV1106_PERICLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1106_PERICRU_BASE)
#define RV1106_VICLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1106_VICRU_BASE)
#define RV1106_VICLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1106_VICRU_BASE)
#define RV1106_NPUCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1106_NPUCRU_BASE)
#define RV1106_NPUCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1106_NPUCRU_BASE)
#define RV1106_CORECLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1106_CORECRU_BASE)
#define RV1106_CORECLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1106_CORECRU_BASE)
#define RV1106_VEPUCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1106_VEPUCRU_BASE)
#define RV1106_VEPUCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1106_VEPUCRU_BASE)
#define RV1106_VOCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1106_VOCRU_BASE)
#define RV1106_VOCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1106_VOCRU_BASE)
#define RV1106_DDRCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1106_DDRCRU_BASE)
#define RV1106_DDRCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1106_DDRCRU_BASE)
#define RV1106_SUBDDRCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1106_SUBDDRCRU_BASE)
#define RV1106_SUBDDRCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1106_SUBDDRCRU_BASE)
#define RV1106_SUBDDRMODE_CON (0x280 + RV1106_SUBDDRCRU_BASE)
/* Register offsets inside the GRF region for the MMC phase clocks */
#define RV1106_VI_GRF_BASE 0x50000
#define RV1106_VO_GRF_BASE 0x60000
#define RV1106_EMMC_CON0 0x20
#define RV1106_EMMC_CON1 0x24
#define RV1106_SDMMC_CON0 (0x4 + RV1106_VI_GRF_BASE)
#define RV1106_SDMMC_CON1 (0x8 + RV1106_VI_GRF_BASE)
#define RV1106_SDIO_CON0 (0x1c + RV1106_VO_GRF_BASE)
#define RV1106_SDIO_CON1 (0x20 + RV1106_VO_GRF_BASE)
#define CRU_PVTPLL0_CON0_L 0x11000
#define CRU_PVTPLL0_CON0_H 0x11004
#define CRU_PVTPLL0_CON1_L 0x11008
#define CRU_PVTPLL0_CON2_H 0x11014
#define CRU_PVTPLL1_CON0_L 0x11030
#define CRU_PVTPLL1_CON0_H 0x11034
#define CRU_PVTPLL1_CON1_L 0x11038
#define CRU_PVTPLL1_CON2_H 0x11044
#define RV1106_GRF_SOC_STATUS0 0x10
#define CPU_PVTPLL_CON0_L 0x40000
#define CPU_PVTPLL_CON0_H 0x40004
#define PVTPLL_RING_SEL_MASK 0x7
#define PVTPLL_RING_SEL_SHIFT 8
#define PVTPLL_EN_MASK 0x3
#define PVTPLL_EN_SHIFT 0
#define PVTPLL_LENGTH_SEL_MASK 0x7f
#define PVTPLL_LENGTH_SEL_SHIFT 0
#define CPU_CLK_PATH_BASE RV1106_CORECLKSEL_CON(0)
#define CPU_PVTPLL_PATH_CORE (BIT(12) | BIT(28))
#define RV1106_FRAC_MAX_PRATE 1200000000
enum rv1106_plls {
apll, dpll, cpll, gpll,
};
static struct rockchip_pll_rate_table rv1106_pll_rates[] = {
/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
RK3036_PLL_RATE(1600000000, 3, 200, 1, 1, 1, 0),
RK3036_PLL_RATE(1584000000, 1, 132, 2, 1, 1, 0),
RK3036_PLL_RATE(1560000000, 1, 130, 2, 1, 1, 0),
RK3036_PLL_RATE(1536000000, 1, 128, 2, 1, 1, 0),
RK3036_PLL_RATE(1512000000, 1, 126, 2, 1, 1, 0),
RK3036_PLL_RATE(1488000000, 1, 124, 2, 1, 1, 0),
RK3036_PLL_RATE(1464000000, 1, 122, 2, 1, 1, 0),
RK3036_PLL_RATE(1440000000, 1, 120, 2, 1, 1, 0),
RK3036_PLL_RATE(1416000000, 1, 118, 2, 1, 1, 0),
RK3036_PLL_RATE(1400000000, 3, 350, 2, 1, 1, 0),
RK3036_PLL_RATE(1392000000, 1, 116, 2, 1, 1, 0),
RK3036_PLL_RATE(1368000000, 1, 114, 2, 1, 1, 0),
RK3036_PLL_RATE(1344000000, 1, 112, 2, 1, 1, 0),
RK3036_PLL_RATE(1320000000, 1, 110, 2, 1, 1, 0),
RK3036_PLL_RATE(1296000000, 1, 108, 2, 1, 1, 0),
RK3036_PLL_RATE(1272000000, 1, 106, 2, 1, 1, 0),
RK3036_PLL_RATE(1248000000, 1, 104, 2, 1, 1, 0),
RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0),
RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
RK3036_PLL_RATE(1104000000