From 3226dac8efe4a2622009394e96126c69a9b01bce Mon Sep 17 00:00:00 2001 From: Liang Chen Date: Tue, 2 Jul 2024 16:26:26 +0800 Subject: [PATCH] clk: rockchip: clk-pvtpll: add support for rk3506 Signed-off-by: Liang Chen Change-Id: Ie5f7e94a716ce2e2483cfd8f1604b6007c4d8c0d --- drivers/clk/rockchip/Kconfig | 2 +- drivers/clk/rockchip/clk-pvtpll.c | 56 +++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/Kconfig b/drivers/clk/rockchip/Kconfig index 23c1b879974c..b2c4d8b99092 100644 --- a/drivers/clk/rockchip/Kconfig +++ b/drivers/clk/rockchip/Kconfig @@ -182,7 +182,7 @@ config ROCKCHIP_CLK_PVTM config ROCKCHIP_CLK_PVTPLL tristate "Rockchip Clk Pvtpll" - default y if CPU_RV1103B + default y if CPU_RV1103B || CPU_RK3506 help Say y here to enable clk pvtpll. diff --git a/drivers/clk/rockchip/clk-pvtpll.c b/drivers/clk/rockchip/clk-pvtpll.c index ab44eb93e6de..3ce4fdf7ae65 100644 --- a/drivers/clk/rockchip/clk-pvtpll.c +++ b/drivers/clk/rockchip/clk-pvtpll.c @@ -28,6 +28,15 @@ #define RV1103B_GCK_RING_SEL_OFFSET 10 #define RV1103B_GCK_RING_SEL_MASK 0x07 +#define RK3506_GRF_CORE_PVTPLL_CON0_L 0x00 +#define RK3506_GRF_CORE_PVTPLL_CON0_H 0x04 +#define RK3506_OSC_RING_SEL_OFFSET 8 +#define RK3506_OSC_RING_SEL_MASK 0x03 +#define RK3506_OSC_EN BIT(1) +#define RK3506_START BIT(0) +#define RK3506_RING_LENGTH_SEL_OFFSET 0 +#define RK3506_RING_LENGTH_SEL_MASK 0x7f + static DEFINE_MUTEX(pvtpll_reg_mutex); struct rockchip_clock_pvtpll; @@ -84,6 +93,16 @@ static struct pvtpll_table rv1103b_npu_pvtpll_table[] = { ROCKCHIP_PVTPLL(700000000, 1, 36), }; +static struct pvtpll_table rk3506_core_pvtpll_table[] = { + /* rate_hz, ring_sel, length */ + ROCKCHIP_PVTPLL(1608000000, 0, 6), + ROCKCHIP_PVTPLL(1512000000, 0, 6), + ROCKCHIP_PVTPLL(1416000000, 0, 6), + ROCKCHIP_PVTPLL(1296000000, 0, 6), + ROCKCHIP_PVTPLL(1200000000, 0, 8), + ROCKCHIP_PVTPLL(1008000000, 0, 15), +}; + static struct pvtpll_table *rockchip_get_pvtpll_settings(struct rockchip_clock_pvtpll *pvtpll, unsigned long rate) @@ -130,6 +149,33 @@ static int rv1103b_pvtpll_configs(struct rockchip_clock_pvtpll *pvtpll, return ret; } +static int rk3506_pvtpll_configs(struct rockchip_clock_pvtpll *pvtpll, + struct pvtpll_table *table) +{ + u32 val; + int ret = 0; + + val = HIWORD_UPDATE(table->ring_sel, RK3506_OSC_RING_SEL_MASK, + RK3506_OSC_RING_SEL_OFFSET); + ret = regmap_write(pvtpll->regmap, RK3506_GRF_CORE_PVTPLL_CON0_L, val); + if (ret) + return ret; + + val = HIWORD_UPDATE(table->length, RK3506_RING_LENGTH_SEL_MASK, + RK3506_RING_LENGTH_SEL_OFFSET); + ret = regmap_write(pvtpll->regmap, RK3506_GRF_CORE_PVTPLL_CON0_H, val); + if (ret) + return ret; + + ret = regmap_write(pvtpll->regmap, RK3506_GRF_CORE_PVTPLL_CON0_L, + RK3506_START | (RK3506_START << 16) | + RK3506_OSC_EN | (RK3506_OSC_EN << 16)); + if (ret) + return ret; + + return ret; +} + static int rockchip_clock_pvtpll_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) @@ -227,6 +273,12 @@ static const struct rockchip_clock_pvtpll_info rv1103b_npu_pvtpll_data = { .table = rv1103b_npu_pvtpll_table, }; +static const struct rockchip_clock_pvtpll_info rk3506_core_pvtpll_data = { + .config = rk3506_pvtpll_configs, + .table_size = ARRAY_SIZE(rk3506_core_pvtpll_table), + .table = rk3506_core_pvtpll_table, +}; + static const struct of_device_id rockchip_clock_pvtpll_match[] = { { .compatible = "rockchip,rv1103b-core-pvtpll", @@ -236,6 +288,10 @@ static const struct of_device_id rockchip_clock_pvtpll_match[] = { .compatible = "rockchip,rv1103b-npu-pvtpll", .data = (void *)&rv1103b_npu_pvtpll_data, }, + { + .compatible = "rockchip,rk3506-core-pvtpll", + .data = (void *)&rk3506_core_pvtpll_data, + }, {} }; MODULE_DEVICE_TABLE(of, rockchip_clock_pvtpll_match);