mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
Merge branches 'clk-tenstorrent', 'clk-rockchip', 'clk-imx' and 'clk-allwinner' into clk-next
* clk-tenstorrent: clk: tenstorrent: Add Atlantis clock controller driver reset: tenstorrent: Add reset controller for Atlantis dt-bindings: clk: tenstorrent: Add tenstorrent,atlantis-prcm-rcpu * clk-rockchip: clk: rockchip: rk3568: Add PCIe pipe clock gates clk: rockchip: Add clock controller for the RV1103B dt-bindings: clock: rockchip: Add RV1103B CRU support * clk-imx: clk: imx8mq: Correct the CSI PHY sels clk: vf610: Add support for the Ethernet switch clocks dt-bindings: clock: vf610: Add definitions for MTIP L2 switch dt-bindings: clock: vf610: Drop VF610_CLK_END define clk: vf610: Move VF610_CLK_END define to clk-vf610 driver clk: imx: imx8-acm: fix flags for acm clocks clk: imx: imx6q: Fix device node reference leak in of_assigned_ldb_sels() clk: imx: imx6q: Fix device node reference leak in pll6_bypassed() clk: imx: fracn-gppll: Add 477.4MHz support clk: imx: fracn-gppll: Add 333.333333 MHz support clk: imx: pll14xx: Use unsigned format specifier dt-bindings: clock: imx6q[ul]-clock: add optional clock enet[1]_ref_pad * clk-allwinner: clk: sunxi-ng: sun55i-a523-r: Add missing r-spi module clock
This commit is contained in:
commit
522a83abc3
|
|
@ -29,20 +29,24 @@ properties:
|
|||
const: 1
|
||||
|
||||
clocks:
|
||||
minItems: 5
|
||||
items:
|
||||
- description: 24m osc
|
||||
- description: 32k osc
|
||||
- description: ckih1 clock input
|
||||
- description: anaclk1 clock input
|
||||
- description: anaclk2 clock input
|
||||
- description: clock input from enet ref pad
|
||||
|
||||
clock-names:
|
||||
minItems: 5
|
||||
items:
|
||||
- const: osc
|
||||
- const: ckil
|
||||
- const: ckih1
|
||||
- const: anaclk1
|
||||
- const: anaclk2
|
||||
- const: enet_ref_pad
|
||||
|
||||
fsl,pmic-stby-poweroff:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
|
|
|
|||
|
|
@ -29,18 +29,22 @@ properties:
|
|||
const: 1
|
||||
|
||||
clocks:
|
||||
minItems: 4
|
||||
items:
|
||||
- description: 32k osc
|
||||
- description: 24m osc
|
||||
- description: ipp_di0 clock input
|
||||
- description: ipp_di1 clock input
|
||||
- description: clock input from enet1 ref pad
|
||||
|
||||
clock-names:
|
||||
minItems: 4
|
||||
items:
|
||||
- const: ckil
|
||||
- const: osc
|
||||
- const: ipp_di0
|
||||
- const: ipp_di1
|
||||
- const: enet1_ref_pad
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ description:
|
|||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- rockchip,rv1103b-cru
|
||||
- rockchip,rv1126b-cru
|
||||
|
||||
reg:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/tenstorrent,atlantis-prcm-rcpu.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Tenstorrent Atlantis PRCM (Power, Reset, Clock Management) Module
|
||||
|
||||
maintainers:
|
||||
- Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
|
||||
|
||||
description:
|
||||
Multifunctional register block found in Tenstorrent Atlantis SoC whose main
|
||||
function is to control clocks and resets. This block is instantiated multiple
|
||||
times in the SoC, each block controls clock and resets for a different
|
||||
subsystem. RCPU prcm serves low speed IO interfaces.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- tenstorrent,atlantis-prcm-rcpu
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
"#clock-cells":
|
||||
const: 1
|
||||
description:
|
||||
See <dt-bindings/clock/tenstorrent,atlantis-prcm-rcpu.h> for valid indices.
|
||||
|
||||
"#reset-cells":
|
||||
const: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- "#clock-cells"
|
||||
- "#reset-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
clock-controller@a8000000 {
|
||||
compatible = "tenstorrent,atlantis-prcm-rcpu";
|
||||
reg = <0xa8000000 0x10000>;
|
||||
clocks = <&osc_24m>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
|
@ -22812,8 +22812,12 @@ M: Joel Stanley <jms@oss.tenstorrent.com>
|
|||
L: linux-riscv@lists.infradead.org
|
||||
S: Maintained
|
||||
T: git https://github.com/tenstorrent/linux.git
|
||||
F: Documentation/devicetree/bindings/clock/tenstorrent,atlantis-prcm-rcpu.yaml
|
||||
F: Documentation/devicetree/bindings/riscv/tenstorrent.yaml
|
||||
F: arch/riscv/boot/dts/tenstorrent/
|
||||
F: drivers/clk/tenstorrent/
|
||||
F: drivers/reset/reset-tenstorrent-atlantis.c
|
||||
F: include/dt-bindings/clock/tenstorrent,atlantis-prcm-rcpu.h
|
||||
|
||||
RISC-V THEAD SoC SUPPORT
|
||||
M: Drew Fustini <fustini@kernel.org>
|
||||
|
|
|
|||
|
|
@ -532,6 +532,7 @@ source "drivers/clk/starfive/Kconfig"
|
|||
source "drivers/clk/sunxi/Kconfig"
|
||||
source "drivers/clk/sunxi-ng/Kconfig"
|
||||
source "drivers/clk/tegra/Kconfig"
|
||||
source "drivers/clk/tenstorrent/Kconfig"
|
||||
source "drivers/clk/thead/Kconfig"
|
||||
source "drivers/clk/stm32/Kconfig"
|
||||
source "drivers/clk/ti/Kconfig"
|
||||
|
|
|
|||
|
|
@ -156,6 +156,7 @@ obj-y += starfive/
|
|||
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
|
||||
obj-y += sunxi-ng/
|
||||
obj-$(CONFIG_ARCH_TEGRA) += tegra/
|
||||
obj-y += tenstorrent/
|
||||
obj-$(CONFIG_ARCH_THEAD) += thead/
|
||||
obj-y += ti/
|
||||
obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
|
||||
|
|
|
|||
|
|
@ -85,9 +85,11 @@ static const struct imx_fracn_gppll_rate_table fracn_tbl[] = {
|
|||
PLL_FRACN_GP(519750000U, 173, 25, 100, 1, 8),
|
||||
PLL_FRACN_GP(498000000U, 166, 0, 1, 0, 8),
|
||||
PLL_FRACN_GP(484000000U, 121, 0, 1, 0, 6),
|
||||
PLL_FRACN_GP(477400000U, 119, 35, 100, 0, 6),
|
||||
PLL_FRACN_GP(445333333U, 167, 0, 1, 0, 9),
|
||||
PLL_FRACN_GP(400000000U, 200, 0, 1, 0, 12),
|
||||
PLL_FRACN_GP(393216000U, 163, 84, 100, 0, 10),
|
||||
PLL_FRACN_GP(333333333U, 125, 0, 1, 1, 9),
|
||||
PLL_FRACN_GP(332600000U, 138, 584, 1000, 0, 10),
|
||||
PLL_FRACN_GP(300000000U, 150, 0, 1, 0, 12),
|
||||
PLL_FRACN_GP(241900000U, 201, 584, 1000, 0, 20),
|
||||
|
|
|
|||
|
|
@ -188,9 +188,11 @@ static void of_assigned_ldb_sels(struct device_node *node,
|
|||
}
|
||||
if (clkspec.np != node || clkspec.args[0] >= IMX6QDL_CLK_END) {
|
||||
pr_err("ccm: parent clock %d not in ccm\n", index);
|
||||
of_node_put(clkspec.np);
|
||||
return;
|
||||
}
|
||||
parent = clkspec.args[0];
|
||||
of_node_put(clkspec.np);
|
||||
|
||||
rc = of_parse_phandle_with_args(node, "assigned-clocks",
|
||||
"#clock-cells", index, &clkspec);
|
||||
|
|
@ -198,9 +200,11 @@ static void of_assigned_ldb_sels(struct device_node *node,
|
|||
return;
|
||||
if (clkspec.np != node || clkspec.args[0] >= IMX6QDL_CLK_END) {
|
||||
pr_err("ccm: child clock %d not in ccm\n", index);
|
||||
of_node_put(clkspec.np);
|
||||
return;
|
||||
}
|
||||
child = clkspec.args[0];
|
||||
of_node_put(clkspec.np);
|
||||
|
||||
if (child != IMX6QDL_CLK_LDB_DI0_SEL &&
|
||||
child != IMX6QDL_CLK_LDB_DI1_SEL)
|
||||
|
|
@ -238,8 +242,11 @@ static bool pll6_bypassed(struct device_node *node)
|
|||
return false;
|
||||
|
||||
if (clkspec.np == node &&
|
||||
clkspec.args[0] == IMX6QDL_PLL6_BYPASS)
|
||||
clkspec.args[0] == IMX6QDL_PLL6_BYPASS) {
|
||||
of_node_put(clkspec.np);
|
||||
break;
|
||||
}
|
||||
of_node_put(clkspec.np);
|
||||
}
|
||||
|
||||
/* PLL6 bypass is not part of the assigned clock list */
|
||||
|
|
@ -249,6 +256,9 @@ static bool pll6_bypassed(struct device_node *node)
|
|||
ret = of_parse_phandle_with_args(node, "assigned-clock-parents",
|
||||
"#clock-cells", index, &clkspec);
|
||||
|
||||
if (!ret)
|
||||
of_node_put(clkspec.np);
|
||||
|
||||
if (clkspec.args[0] != IMX6QDL_CLK_PLL6)
|
||||
return true;
|
||||
|
||||
|
|
|
|||
|
|
@ -371,7 +371,8 @@ static int imx8_acm_clk_probe(struct platform_device *pdev)
|
|||
for (i = 0; i < priv->soc_data->num_sels; i++) {
|
||||
hws[sels[i].clkid] = devm_clk_hw_register_mux_parent_data_table(dev,
|
||||
sels[i].name, sels[i].parents,
|
||||
sels[i].num_parents, 0,
|
||||
sels[i].num_parents,
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
base + sels[i].reg,
|
||||
sels[i].shift, sels[i].width,
|
||||
0, NULL, NULL);
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ static const char * const imx8mq_dsi_esc_sels[] = {"osc_25m", "sys2_pll_100m", "
|
|||
static const char * const imx8mq_csi1_core_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_250m", "sys1_pll_800m",
|
||||
"sys2_pll_1000m", "sys3_pll_out", "audio_pll2_out", "video_pll1_out", };
|
||||
|
||||
static const char * const imx8mq_csi1_phy_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_100m", "sys1_pll_800m",
|
||||
static const char * const imx8mq_csi1_phy_sels[] = {"osc_25m", "sys2_pll_333m", "sys2_pll_100m", "sys1_pll_800m",
|
||||
"sys2_pll_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
|
||||
|
||||
static const char * const imx8mq_csi1_esc_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m",
|
||||
|
|
@ -246,7 +246,7 @@ static const char * const imx8mq_csi1_esc_sels[] = {"osc_25m", "sys2_pll_100m",
|
|||
static const char * const imx8mq_csi2_core_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_250m", "sys1_pll_800m",
|
||||
"sys2_pll_1000m", "sys3_pll_out", "audio_pll2_out", "video_pll1_out", };
|
||||
|
||||
static const char * const imx8mq_csi2_phy_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_100m", "sys1_pll_800m",
|
||||
static const char * const imx8mq_csi2_phy_sels[] = {"osc_25m", "sys2_pll_333m", "sys2_pll_100m", "sys1_pll_800m",
|
||||
"sys2_pll_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
|
||||
|
||||
static const char * const imx8mq_csi2_esc_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m",
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ static void imx_pll14xx_calc_settings(struct clk_pll14xx *pll, unsigned long rat
|
|||
/* First try if we can get the desired rate from one of the static entries */
|
||||
tt = imx_get_pll_settings(pll, rate);
|
||||
if (tt) {
|
||||
pr_debug("%s: in=%ld, want=%ld, Using PLL setting from table\n",
|
||||
pr_debug("%s: in=%lu, want=%lu, Using PLL setting from table\n",
|
||||
clk_hw_get_name(&pll->hw), prate, rate);
|
||||
t->rate = tt->rate;
|
||||
t->mdiv = tt->mdiv;
|
||||
|
|
@ -173,7 +173,7 @@ static void imx_pll14xx_calc_settings(struct clk_pll14xx *pll, unsigned long rat
|
|||
|
||||
if (rate >= rate_min && rate <= rate_max) {
|
||||
kdiv = pll1443x_calc_kdiv(mdiv, pdiv, sdiv, rate, prate);
|
||||
pr_debug("%s: in=%ld, want=%ld Only adjust kdiv %ld -> %d\n",
|
||||
pr_debug("%s: in=%lu, want=%lu Only adjust kdiv %ld -> %d\n",
|
||||
clk_hw_get_name(&pll->hw), prate, rate,
|
||||
FIELD_GET(KDIV_MASK, pll_div_ctl1), kdiv);
|
||||
fout = pll14xx_calc_rate(pll, mdiv, pdiv, sdiv, kdiv, prate);
|
||||
|
|
@ -211,7 +211,7 @@ static void imx_pll14xx_calc_settings(struct clk_pll14xx *pll, unsigned long rat
|
|||
}
|
||||
}
|
||||
found:
|
||||
pr_debug("%s: in=%ld, want=%ld got=%d (pdiv=%d sdiv=%d mdiv=%d kdiv=%d)\n",
|
||||
pr_debug("%s: in=%lu, want=%lu got=%u (pdiv=%d sdiv=%d mdiv=%d kdiv=%d)\n",
|
||||
clk_hw_get_name(&pll->hw), prate, rate, t->rate, t->pdiv, t->sdiv,
|
||||
t->mdiv, t->kdiv);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,13 @@
|
|||
|
||||
#include "clk.h"
|
||||
|
||||
/*
|
||||
* The VF610_CLK_END corresponds to ones defined in
|
||||
* include/dt-bindings/clock/vf610-clock.h
|
||||
* It shall be the value of the last defined clock +1
|
||||
*/
|
||||
#define VF610_CLK_END 196
|
||||
|
||||
#define CCM_CCR (ccm_base + 0x00)
|
||||
#define CCM_CSR (ccm_base + 0x04)
|
||||
#define CCM_CCSR (ccm_base + 0x08)
|
||||
|
|
@ -313,6 +320,11 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
|
|||
clk[VF610_CLK_ENET_TS] = imx_clk_gate("enet_ts", "enet_ts_sel", CCM_CSCDR1, 23);
|
||||
clk[VF610_CLK_ENET0] = imx_clk_gate2("enet0", "ipg_bus", CCM_CCGR9, CCM_CCGRx_CGn(0));
|
||||
clk[VF610_CLK_ENET1] = imx_clk_gate2("enet1", "ipg_bus", CCM_CCGR9, CCM_CCGRx_CGn(1));
|
||||
clk[VF610_CLK_ESW] = imx_clk_gate2("esw", "ipg_bus", CCM_CCGR10, CCM_CCGRx_CGn(8));
|
||||
clk[VF610_CLK_ESW_MAC_TAB0] = imx_clk_gate2("esw_tab0", "ipg_bus", CCM_CCGR10, CCM_CCGRx_CGn(12));
|
||||
clk[VF610_CLK_ESW_MAC_TAB1] = imx_clk_gate2("esw_tab1", "ipg_bus", CCM_CCGR10, CCM_CCGRx_CGn(13));
|
||||
clk[VF610_CLK_ESW_MAC_TAB2] = imx_clk_gate2("esw_tab2", "ipg_bus", CCM_CCGR10, CCM_CCGRx_CGn(14));
|
||||
clk[VF610_CLK_ESW_MAC_TAB3] = imx_clk_gate2("esw_tab3", "ipg_bus", CCM_CCGR10, CCM_CCGRx_CGn(15));
|
||||
|
||||
clk[VF610_CLK_PIT] = imx_clk_gate2("pit", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(7));
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,13 @@ config CLK_PX30
|
|||
help
|
||||
Build the driver for PX30 Clock Driver.
|
||||
|
||||
config CLK_RV1103B
|
||||
bool "Rockchip RV1103B clock controller support"
|
||||
depends on ARM || COMPILE_TEST
|
||||
default y
|
||||
help
|
||||
Build the driver for RV1103B Clock Driver.
|
||||
|
||||
config CLK_RV110X
|
||||
bool "Rockchip RV110x clock controller support"
|
||||
depends on ARM || COMPILE_TEST
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ clk-rockchip-y += gate-link.o
|
|||
clk-rockchip-$(CONFIG_RESET_CONTROLLER) += softrst.o
|
||||
|
||||
obj-$(CONFIG_CLK_PX30) += clk-px30.o
|
||||
obj-$(CONFIG_CLK_RV1103B) += clk-rv1103b.o
|
||||
obj-$(CONFIG_CLK_RV110X) += clk-rv1108.o
|
||||
obj-$(CONFIG_CLK_RV1126) += clk-rv1126.o
|
||||
obj-$(CONFIG_CLK_RV1126B) += clk-rv1126b.o rst-rv1126b.o
|
||||
|
|
|
|||
|
|
@ -827,6 +827,8 @@ static struct rockchip_clk_branch rk3568_clk_branches[] __initdata = {
|
|||
RK3568_CLKGATE_CON(12), 3, GFLAGS),
|
||||
GATE(CLK_PCIE20_AUX_NDFT, "clk_pcie20_aux_ndft", "xin24m", 0,
|
||||
RK3568_CLKGATE_CON(12), 4, GFLAGS),
|
||||
GATE(CLK_PCIE20_PIPE_DFT, "clk_pcie20_pipe_dft", "aclk_pipe", CLK_IGNORE_UNUSED,
|
||||
RK3568_CLKGATE_CON(12), 5, GFLAGS),
|
||||
GATE(ACLK_PCIE30X1_MST, "aclk_pcie30x1_mst", "aclk_pipe", 0,
|
||||
RK3568_CLKGATE_CON(12), 8, GFLAGS),
|
||||
GATE(ACLK_PCIE30X1_SLV, "aclk_pcie30x1_slv", "aclk_pipe", 0,
|
||||
|
|
@ -837,6 +839,8 @@ static struct rockchip_clk_branch rk3568_clk_branches[] __initdata = {
|
|||
RK3568_CLKGATE_CON(12), 11, GFLAGS),
|
||||
GATE(CLK_PCIE30X1_AUX_NDFT, "clk_pcie30x1_aux_ndft", "xin24m", 0,
|
||||
RK3568_CLKGATE_CON(12), 12, GFLAGS),
|
||||
GATE(CLK_PCIE30X1_PIPE_DFT, "clk_pcie30x1_pipe_dft", "aclk_pipe", CLK_IGNORE_UNUSED,
|
||||
RK3568_CLKGATE_CON(12), 13, GFLAGS),
|
||||
GATE(ACLK_PCIE30X2_MST, "aclk_pcie30x2_mst", "aclk_pipe", 0,
|
||||
RK3568_CLKGATE_CON(13), 0, GFLAGS),
|
||||
GATE(ACLK_PCIE30X2_SLV, "aclk_pcie30x2_slv", "aclk_pipe", 0,
|
||||
|
|
@ -847,6 +851,8 @@ static struct rockchip_clk_branch rk3568_clk_branches[] __initdata = {
|
|||
RK3568_CLKGATE_CON(13), 3, GFLAGS),
|
||||
GATE(CLK_PCIE30X2_AUX_NDFT, "clk_pcie30x2_aux_ndft", "xin24m", 0,
|
||||
RK3568_CLKGATE_CON(13), 4, GFLAGS),
|
||||
GATE(CLK_PCIE30X2_PIPE_DFT, "clk_pcie30x2_pipe_dft", "aclk_pipe", CLK_IGNORE_UNUSED,
|
||||
RK3568_CLKGATE_CON(13), 5, GFLAGS),
|
||||
GATE(ACLK_SATA0, "aclk_sata0", "aclk_pipe", 0,
|
||||
RK3568_CLKGATE_CON(11), 0, GFLAGS),
|
||||
GATE(CLK_SATA0_PMALIVE, "clk_sata0_pmalive", "gpll_20m", 0,
|
||||
|
|
|
|||
658
drivers/clk/rockchip/clk-rv1103b.c
Normal file
658
drivers/clk/rockchip/clk-rv1103b.c
Normal file
|
|
@ -0,0 +1,658 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2024 Rockchip Electronics Co. Ltd.
|
||||
* Author: Elaine Zhang <zhangqing@rock-chips.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <dt-bindings/clock/rockchip,rv1103b-cru.h>
|
||||
#include "clk.h"
|
||||
|
||||
#define RV1103B_GRF_SOC_STATUS0 0x10
|
||||
#define RV1103B_FRAC_MAX_PRATE 1200000000
|
||||
#define PVTPLL_SRC_SEL_PVTPLL (BIT(0) | BIT(16))
|
||||
|
||||
enum rv1103b_plls {
|
||||
dpll,
|
||||
gpll,
|
||||
};
|
||||
|
||||
static struct rockchip_pll_rate_table rv1103b_pll_rates[] = {
|
||||
/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
|
||||
RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0),
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
#define RV1103B_DIV_ACLK_CORE_MASK 0x1f
|
||||
#define RV1103B_DIV_ACLK_CORE_SHIFT 0
|
||||
#define RV1103B_DIV_PCLK_DBG_MASK 0x1f
|
||||
#define RV1103B_DIV_PCLK_DBG_SHIFT 8
|
||||
|
||||
#define RV1103B_CLKSEL0(_aclk_core) \
|
||||
{ \
|
||||
.reg = RV1103B_CORECLKSEL_CON(2), \
|
||||
.val = HIWORD_UPDATE(_aclk_core - 1, RV1103B_DIV_ACLK_CORE_MASK, \
|
||||
RV1103B_DIV_ACLK_CORE_SHIFT), \
|
||||
}
|
||||
|
||||
#define RV1103B_CLKSEL1(_pclk_dbg) \
|
||||
{ \
|
||||
.reg = RV1103B_CORECLKSEL_CON(2), \
|
||||
.val = HIWORD_UPDATE(_pclk_dbg - 1, RV1103B_DIV_PCLK_DBG_MASK, \
|
||||
RV1103B_DIV_PCLK_DBG_SHIFT), \
|
||||
}
|
||||
|
||||
#define RV1103B_CPUCLK_RATE(_prate, _aclk_core, _pclk_dbg) \
|
||||
{ \
|
||||
.prate = _prate, \
|
||||
.divs = { \
|
||||
RV1103B_CLKSEL0(_aclk_core), \
|
||||
RV1103B_CLKSEL1(_pclk_dbg), \
|
||||
}, \
|
||||
}
|
||||
|
||||
static struct rockchip_cpuclk_rate_table rv1103b_cpuclk_rates[] __initdata = {
|
||||
RV1103B_CPUCLK_RATE(1608000000, 4, 10),
|
||||
RV1103B_CPUCLK_RATE(1512000000, 4, 10),
|
||||
RV1103B_CPUCLK_RATE(1416000000, 4, 10),
|
||||
RV1103B_CPUCLK_RATE(1296000000, 3, 10),
|
||||
RV1103B_CPUCLK_RATE(1200000000, 3, 10),
|
||||
RV1103B_CPUCLK_RATE(1188000000, 3, 8),
|
||||
RV1103B_CPUCLK_RATE(1104000000, 2, 8),
|
||||
RV1103B_CPUCLK_RATE(1008000000, 2, 8),
|
||||
RV1103B_CPUCLK_RATE(816000000, 2, 6),
|
||||
RV1103B_CPUCLK_RATE(600000000, 2, 4),
|
||||
RV1103B_CPUCLK_RATE(594000000, 2, 4),
|
||||
RV1103B_CPUCLK_RATE(408000000, 1, 3),
|
||||
RV1103B_CPUCLK_RATE(396000000, 1, 3),
|
||||
};
|
||||
|
||||
PNAME(mux_pll_p) = { "xin24m" };
|
||||
PNAME(mux_200m_100m_p) = { "clk_gpll_div6", "clk_gpll_div12" };
|
||||
PNAME(mux_gpll_24m_p) = { "gpll", "xin24m" };
|
||||
PNAME(mux_480m_400m_300m_200m_p) = { "clk_gpll_div2p5", "clk_gpll_div3", "clk_gpll_div4", "clk_gpll_div6" };
|
||||
PNAME(mux_480m_400m_300m_p) = { "clk_gpll_div2p5", "clk_gpll_div3", "clk_gpll_div4" };
|
||||
PNAME(mux_300m_200m_p) = { "clk_gpll_div4", "clk_gpll_div6" };
|
||||
PNAME(mux_600m_480m_400m_p) = { "clk_gpll_div2", "clk_gpll_div2p5", "clk_gpll_div3" };
|
||||
PNAME(mux_400m_300m_p) = { "clk_gpll_div3", "clk_gpll_div4" };
|
||||
PNAME(mux_100m_24m_p) = { "clk_gpll_div12", "xin24m" };
|
||||
PNAME(mux_200m_24m_p) = { "clk_gpll_div6", "xin24m" };
|
||||
PNAME(mux_200m_100m_50m_24m_p) = { "clk_gpll_div6", "clk_gpll_div12", "clk_gpll_div24", "xin24m" };
|
||||
PNAME(mux_300m_200m_100m_p) = { "clk_gpll_div4", "clk_gpll_div6", "clk_gpll_div12" };
|
||||
PNAME(sclk_uart0_src_p) = { "clk_uart0_src", "clk_uart0_frac", "xin24m" };
|
||||
PNAME(sclk_uart1_src_p) = { "clk_uart1_src", "clk_uart1_frac", "xin24m" };
|
||||
PNAME(sclk_uart2_src_p) = { "clk_uart2_src", "clk_uart2_frac", "xin24m" };
|
||||
PNAME(mclk_sai_src_p) = { "clk_sai_src", "clk_sai_frac", "mclk_sai_from_io", "xin_osc0_half" };
|
||||
PNAME(clk_freq_pwm0_src_p) = { "sclk_sai_from_io", "mclk_sai_from_io", "clk_testout_out" };
|
||||
PNAME(clk_counter_pwm0_src_p) = { "sclk_sai_from_io", "mclk_sai_from_io", "clk_testout_out" };
|
||||
PNAME(clk_mipi0_out2io_p) = { "clk_ref_mipi0", "xin24m" };
|
||||
PNAME(clk_mipi1_out2io_p) = { "clk_ref_mipi1", "xin24m" };
|
||||
PNAME(mclk_sai_out2io_p) = { "mclk_sai_src", "xin_osc0_half" };
|
||||
PNAME(aclk_npu_root_p) = { "clk_npu_src", "clk_npu_pvtpll" };
|
||||
PNAME(clk_core_vepu_p) = { "clk_vepu_src", "clk_vepu_pvtpll" };
|
||||
PNAME(lsclk_vi_root_p) = { "clk_gpll_div6", "lsclk_vi_100m" };
|
||||
PNAME(clk_core_isp_p) = { "clk_isp_src", "clk_isp_pvtpll_src" };
|
||||
PNAME(lsclk_pmu_root_p) = { "xin24m", "clk_rc_osc_io" };
|
||||
PNAME(xin_rc_div_p) = { "xin24m", "clk_rc_osc_io" };
|
||||
PNAME(clk_32k_p) = { "xin_rc_div", "clk_32k_rtc", "clk_32k_io" };
|
||||
PNAME(dbclk_pmu_gpio0_p) = { "xin24m", "clk_32k" };
|
||||
PNAME(sclk_sfc_2x_pmu1_p) = { "clk_gpll_div12", "clk_rc_osc_io" };
|
||||
PNAME(mux_armclk_p) = { "armclk_gpll", "clk_core_pvtpll" };
|
||||
|
||||
static struct rockchip_pll_clock rv1103b_pll_clks[] __initdata = {
|
||||
[dpll] = PLL(pll_rk3328, PLL_DPLL, "dpll", mux_pll_p,
|
||||
CLK_IS_CRITICAL, RV1103B_PLL_CON(16),
|
||||
RV1103B_MODE_CON, 0, 10, 0, rv1103b_pll_rates),
|
||||
[gpll] = PLL(pll_rk3328, PLL_GPLL, "gpll", mux_pll_p,
|
||||
CLK_IS_CRITICAL, RV1103B_PLL_CON(24),
|
||||
RV1103B_MODE_CON, 0, 10, 0, rv1103b_pll_rates),
|
||||
};
|
||||
|
||||
#define MFLAGS CLK_MUX_HIWORD_MASK
|
||||
#define DFLAGS CLK_DIVIDER_HIWORD_MASK
|
||||
#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
|
||||
|
||||
static struct rockchip_clk_branch rv1103b_clk_uart0_fracmux __initdata =
|
||||
MUX(SCLK_UART0_SRC, "sclk_uart0_src", sclk_uart0_src_p, CLK_SET_RATE_PARENT,
|
||||
RV1103B_CLKSEL_CON(32), 8, 2, MFLAGS);
|
||||
|
||||
static struct rockchip_clk_branch rv1103b_clk_uart1_fracmux __initdata =
|
||||
MUX(SCLK_UART1_SRC, "sclk_uart1_src", sclk_uart1_src_p, CLK_SET_RATE_PARENT,
|
||||
RV1103B_CLKSEL_CON(32), 10, 2, MFLAGS);
|
||||
|
||||
static struct rockchip_clk_branch rv1103b_clk_uart2_fracmux __initdata =
|
||||
MUX(SCLK_UART2_SRC, "sclk_uart2_src", sclk_uart2_src_p, CLK_SET_RATE_PARENT,
|
||||
RV1103B_CLKSEL_CON(32), 12, 2, MFLAGS);
|
||||
|
||||
static struct rockchip_clk_branch rv1103b_rcdiv_pmu_fracmux __initdata =
|
||||
MUX(CLK_32K, "clk_32k", clk_32k_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
RK3568_PMU_CLKSEL_CON(0), 0, 2, MFLAGS);
|
||||
|
||||
static struct rockchip_clk_branch rv1103b_clk_branches[] __initdata = {
|
||||
|
||||
/* Clock Definition */
|
||||
FACTOR(XIN_OSC0_HALF, "xin_osc0_half", "xin24m", 0, 1, 2),
|
||||
|
||||
COMPOSITE_NOGATE(0, "armclk_gpll", mux_gpll_24m_p, CLK_IS_CRITICAL,
|
||||
RV1103B_CLKSEL_CON(37), 12, 1, MFLAGS, 13, 3, DFLAGS),
|
||||
|
||||
/* pd_top */
|
||||
COMPOSITE_NOMUX(CLK_GPLL_DIV24, "clk_gpll_div24", "gpll", 0,
|
||||
RV1103B_CLKSEL_CON(0), 0, 5, DFLAGS,
|
||||
RV1103B_CLKGATE_CON(0), 0, GFLAGS),
|
||||
COMPOSITE_NOMUX(CLK_GPLL_DIV12, "clk_gpll_div12", "gpll", 0,
|
||||
RV1103B_CLKSEL_CON(0), 5, 5, DFLAGS,
|
||||
RV1103B_CLKGATE_CON(0), 1, GFLAGS),
|
||||
COMPOSITE_NOMUX(CLK_GPLL_DIV6, "clk_gpll_div6", "gpll", 0,
|
||||
RV1103B_CLKSEL_CON(1), 0, 5, DFLAGS,
|
||||
RV1103B_CLKGATE_CON(0), 3, GFLAGS),
|
||||
COMPOSITE_NOMUX(CLK_GPLL_DIV4, "clk_gpll_div4", "gpll", 0,
|
||||
RV1103B_CLKSEL_CON(1), 10, 5, DFLAGS,
|
||||
RV1103B_CLKGATE_CON(0), 5, GFLAGS),
|
||||
COMPOSITE_NOMUX(CLK_GPLL_DIV3, "clk_gpll_div3", "gpll", 0,
|
||||
RV1103B_CLKSEL_CON(2), 0, 5, DFLAGS,
|
||||
RV1103B_CLKGATE_CON(0), 7, GFLAGS),
|
||||
COMPOSITE_NOMUX_HALFDIV(CLK_GPLL_DIV2P5, "clk_gpll_div2p5", "gpll", 0,
|
||||
RV1103B_CLKSEL_CON(2), 5, 5, DFLAGS,
|
||||
RV1103B_CLKGATE_CON(0), 8, GFLAGS),
|
||||
COMPOSITE_NOMUX(CLK_GPLL_DIV2, "clk_gpll_div2", "gpll", 0,
|
||||
RV1103B_CLKSEL_CON(2), 10, 5, DFLAGS,
|
||||
RV1103B_CLKGATE_CON(0), 9, GFLAGS),
|
||||
COMPOSITE_NOMUX(CLK_UART0_SRC, "clk_uart0_src", "gpll", 0,
|
||||
RV1103B_CLKSEL_CON(5), 0, 5, DFLAGS,
|
||||
RV1103B_CLKGATE_CON(1), 0, GFLAGS),
|
||||
COMPOSITE_NOMUX(CLK_UART1_SRC, "clk_uart1_src", "gpll", 0,
|
||||
RV1103B_CLKSEL_CON(5), 5, 5, DFLAGS,
|
||||
RV1103B_CLKGATE_CON(1), 1, GFLAGS),
|
||||
COMPOSITE_NOMUX(CLK_UART2_SRC, "clk_uart2_src", "gpll", 0,
|
||||
RV1103B_CLKSEL_CON(5), 10, 5, DFLAGS,
|
||||
RV1103B_CLKGATE_CON(1), 2, GFLAGS),
|
||||
COMPOSITE_FRACMUX(CLK_UART0_FRAC, "clk_uart0_frac", "clk_uart0_src", 0,
|
||||
RV1103B_CLKSEL_CON(10), 0,
|
||||
RV1103B_CLKGATE_CON(1), 6, GFLAGS,
|
||||
&rv1103b_clk_uart0_fracmux),
|
||||
COMPOSITE_FRACMUX(CLK_UART1_FRAC, "clk_uart1_frac", "clk_uart1_src", 0,
|
||||
RV1103B_CLKSEL_CON(11), 0,
|
||||
RV1103B_CLKGATE_CON(1), 7, GFLAGS,
|
||||
&rv1103b_clk_uart1_fracmux),
|
||||
COMPOSITE_FRACMUX(CLK_UART2_FRAC, "clk_uart2_frac", "clk_uart2_src", 0,
|
||||
RV1103B_CLKSEL_CON(12), 0,
|
||||
RV1103B_CLKGATE_CON(1), 8, GFLAGS,
|
||||
&rv1103b_clk_uart2_fracmux),
|
||||
GATE(SCLK_UART0, "sclk_uart0", "sclk_uart0_src", 0,
|
||||
RV1103B_CLKGATE_CON(3), 3, GFLAGS),
|
||||
GATE(SCLK_UART1, "sclk_uart1", "sclk_uart1_src", 0,
|
||||
RV1103B_CLKGATE_CON(3), 4, GFLAGS),
|
||||
GATE(SCLK_UART2, "sclk_uart2", "sclk_uart2_src", 0,
|
||||
RV1103B_CLKGATE_CON(3), 8, GFLAGS),
|
||||
|
||||
COMPOSITE_NOMUX(CLK_SAI_SRC, "clk_sai_src", "gpll", 0,
|
||||
RV1103B_CLKSEL_CON(20), 0, 5, DFLAGS,
|
||||
RV1103B_CLKGATE_CON(1), 12, GFLAGS),
|
||||
MUX(MCLK_SAI_SRC, "mclk_sai_src", mclk_sai_src_p, CLK_SET_RATE_PARENT,
|
||||
RV1103B_CLKSEL_CON(35), 10, 2, MFLAGS),
|
||||
GATE(MCLK_SAI, "mclk_sai", "mclk_sai_src", 0,
|
||||
RV1103B_CLKGATE_CON(5), 5, GFLAGS),
|
||||
|
||||
COMPOSITE_NODIV(LSCLK_NPU_SRC, "lsclk_npu_src", mux_200m_100m_p, CLK_IS_CRITICAL,
|
||||
RV1103B_CLKSEL_CON(30), 0, 1, MFLAGS,
|
||||
RV1103B_CLKGATE_CON(2), 0, GFLAGS),
|
||||
COMPOSITE(CLK_NPU_SRC, "clk_npu_src", mux_gpll_24m_p, 0,
|
||||
RV1103B_CLKSEL_CON(37), 0, 1, MFLAGS, 1, 2, DFLAGS,
|
||||
RV1103B_CLKGATE_CON(5), 12, GFLAGS),
|
||||
COMPOSITE_NODIV(ACLK_VEPU_SRC, "aclk_vepu_src", mux_480m_400m_300m_200m_p, 0,
|
||||
RV1103B_CLKSEL_CON(30), 8, 2, MFLAGS,
|
||||
RV1103B_CLKGATE_CON(2), 4, GFLAGS),
|
||||
COMPOSITE(CLK_VEPU_SRC, "clk_vepu_src", mux_gpll_24m_p, 0,
|
||||
RV1103B_CLKSEL_CON(37), 4, 1, MFLAGS, 5, 2, DFLAGS,
|
||||
RV1103B_CLKGATE_CON(5), 13, GFLAGS),
|
||||
COMPOSITE_NODIV(ACLK_VI_SRC, "aclk_vi_src", mux_480m_400m_300m_p, CLK_IS_CRITICAL,
|
||||
RV1103B_CLKSEL_CON(30), 12, 2, MFLAGS,
|
||||
RV1103B_CLKGATE_CON(2), 8, GFLAGS),
|
||||
COMPOSITE(CLK_ISP_SRC, "clk_isp_src", mux_gpll_24m_p, 0,
|
||||
RV1103B_CLKSEL_CON(37), 8, 1, MFLAGS, 9, 2, DFLAGS,
|
||||
RV1103B_CLKGATE_CON(5), 14, GFLAGS),
|
||||
COMPOSITE_NODIV(DCLK_VICAP, "dclk_vicap", mux_300m_200m_p, 0,
|
||||
RV1103B_CLKSEL_CON(30), 14, 1, MFLAGS,
|
||||
RV1103B_CLKGATE_CON(2), 9, GFLAGS),
|
||||
COMPOSITE(CCLK_EMMC, "cclk_emmc", mux_gpll_24m_p, 0,
|
||||
RV1103B_CLKSEL_CON(31), 15, 1, MFLAGS, 0, 8, DFLAGS,
|
||||
RV1103B_CLKGATE_CON(2), 10, GFLAGS),
|
||||
COMPOSITE(CCLK_SDMMC0, "cclk_sdmmc0", mux_gpll_24m_p, 0,
|
||||
RV1103B_CLKSEL_CON(32), 15, 1, MFLAGS, 0, 8, DFLAGS,
|
||||
RV1103B_CLKGATE_CON(2), 11, GFLAGS),
|
||||
COMPOSITE(SCLK_SFC_2X, "sclk_sfc_2x", mux_gpll_24m_p, 0,
|
||||
RV1103B_CLKSEL_CON(33), 15, 1, MFLAGS, 0, 8, DFLAGS,
|
||||
RV1103B_CLKGATE_CON(2), 12, GFLAGS),
|
||||
COMPOSITE_NODIV(LSCLK_PERI_SRC, "lsclk_peri_src", mux_300m_200m_p, CLK_IS_CRITICAL,
|
||||
RV1103B_CLKSEL_CON(31), 9, 1, MFLAGS,
|
||||
RV1103B_CLKGATE_CON(3), 0, GFLAGS),
|
||||
COMPOSITE_NODIV(ACLK_PERI_SRC, "aclk_peri_src", mux_600m_480m_400m_p, CLK_IS_CRITICAL,
|
||||
RV1103B_CLKSEL_CON(31), 10, 2, MFLAGS,
|
||||
RV1103B_CLKGATE_CON(3), 1, GFLAGS),
|
||||
COMPOSITE_NODIV(HCLK_HPMCU, "hclk_hpmcu", mux_400m_300m_p, 0,
|
||||
RV1103B_CLKSEL_CON(31), 12, 1, MFLAGS,
|
||||
RV1103B_CLKGATE_CON(3), 2, GFLAGS),
|
||||
COMPOSITE_NODIV(CLK_I2C_PMU, "clk_i2c_pmu", mux_100m_24m_p, 0,
|
||||
RV1103B_CLKSEL_CON(34), 0, 1, MFLAGS,
|
||||
RV1103B_CLKGATE_CON(4), 0, GFLAGS),
|
||||
COMPOSITE_NODIV(CLK_I2C_PERI, "clk_i2c_peri", mux_200m_24m_p, 0,
|
||||
RV1103B_CLKSEL_CON(34), 1, 1, MFLAGS,
|
||||
RV1103B_CLKGATE_CON(4), 4, GFLAGS),
|
||||
COMPOSITE_NODIV(CLK_SPI0, "clk_spi0", mux_200m_100m_50m_24m_p, 0,
|
||||
RV1103B_CLKSEL_CON(34), 2, 2, MFLAGS,
|
||||
RV1103B_CLKGATE_CON(4), 5, GFLAGS),
|
||||
COMPOSITE_NODIV(CLK_PWM0_SRC, "clk_pwm0_src", mux_100m_24m_p, 0,
|
||||
RV1103B_CLKSEL_CON(34), 12, 1, MFLAGS,
|
||||
RV1103B_CLKGATE_CON(4), 10, GFLAGS),
|
||||
COMPOSITE_NODIV(CLK_PWM1, "clk_pwm1", mux_100m_24m_p, 0,
|
||||
RV1103B_CLKSEL_CON(34), 13, 1, MFLAGS,
|
||||
RV1103B_CLKGATE_CON(4), 11, GFLAGS),
|
||||
COMPOSITE_NODIV(CLK_PWM2, "clk_pwm2", mux_100m_24m_p, 0,
|
||||
RV1103B_CLKSEL_CON(34), 14, 1, MFLAGS,
|
||||
RV1103B_CLKGATE_CON(4), 12, GFLAGS),
|
||||
COMPOSITE_NODIV(DCLK_DECOM_SRC, "dclk_decom_src", mux_480m_400m_300m_p, 0,
|
||||
RV1103B_CLKSEL_CON(35), 0, 2, MFLAGS,
|
||||
RV1103B_CLKGATE_CON(5), 0, GFLAGS),
|
||||
COMPOSITE(CCLK_SDMMC1, "cclk_sdmmc1", mux_gpll_24m_p, 0,
|
||||
RV1103B_CLKSEL_CON(36), 15, 1, MFLAGS, 0, 8, DFLAGS,
|
||||
RV1103B_CLKGATE_CON(5), 1, GFLAGS),
|
||||
COMPOSITE_NODIV(CLK_CORE_CRYPTO, "clk_core_crypto", mux_300m_200m_100m_p, 0,
|
||||
RV1103B_CLKSEL_CON(35), 2, 2, MFLAGS,
|
||||
RV1103B_CLKGATE_CON(5), 2, GFLAGS),
|
||||
COMPOSITE_NODIV(CLK_PKA_CRYPTO, "clk_pka_crypto", mux_300m_200m_100m_p, 0,
|
||||
RV1103B_CLKSEL_CON(35), 4, 2, MFLAGS,
|
||||
RV1103B_CLKGATE_CON(5), 3, GFLAGS),
|
||||
COMPOSITE_NODIV(CLK_CORE_RGA, "clk_core_rga", mux_400m_300m_p, 0,
|
||||
RV1103B_CLKSEL_CON(35), 8, 1, MFLAGS,
|
||||
RV1103B_CLKGATE_CON(5), 4, GFLAGS),
|
||||
|
||||
GATE(PCLK_TOP_ROOT, "pclk_top_root", "clk_gpll_div12", CLK_IS_CRITICAL,
|
||||
RV1103B_CLKGATE_CON(6), 0, GFLAGS),
|
||||
COMPOSITE_NOMUX(CLK_REF_MIPI0, "clk_ref_mipi0", "clk_gpll_div2", 0,
|
||||
RV1103B_CLKSEL_CON(40), 0, 5, DFLAGS,
|
||||
RV1103B_CLKGATE_CON(6), 3, GFLAGS),
|
||||
COMPOSITE_NODIV(CLK_MIPI0_OUT2IO, "clk_mipi0_out2io", clk_mipi0_out2io_p, CLK_SET_RATE_PARENT,
|
||||
RV1103B_CLKSEL_CON(40), 6, 1, MFLAGS,
|
||||
RV1103B_CLKGATE_CON(6), 4, GFLAGS),
|
||||
COMPOSITE_NOMUX(CLK_REF_MIPI1, "clk_ref_mipi1", "clk_gpll_div2", 0,
|
||||
RV1103B_CLKSEL_CON(40), 8, 5, DFLAGS,
|
||||
RV1103B_CLKGATE_CON(6), 5, GFLAGS),
|
||||
COMPOSITE_NODIV(CLK_MIPI1_OUT2IO, "clk_mipi1_out2io", clk_mipi1_out2io_p, CLK_SET_RATE_PARENT,
|
||||
RV1103B_CLKSEL_CON(40), 14, 1, MFLAGS,
|
||||
RV1103B_CLKGATE_CON(6), 6, GFLAGS),
|
||||
COMPOSITE(MCLK_SAI_OUT2IO, "mclk_sai_out2io", mclk_sai_out2io_p, 0,
|
||||
RV1103B_CLKSEL_CON(41), 7, 1, MFLAGS, 13, 3, DFLAGS,
|
||||
RV1103B_CLKGATE_CON(6), 9, GFLAGS),
|
||||
|
||||
/* pd_vpu */
|
||||
COMPOSITE_NODIV(ACLK_NPU_ROOT, "aclk_npu_root", aclk_npu_root_p, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
|
||||
RV1103B_NPUCLKSEL_CON(0), 1, 1, MFLAGS,
|
||||
RV1103B_NPUCLKGATE_CON(0), 1, GFLAGS),
|
||||
GATE(HCLK_RKNN, "hclk_rknn", "lsclk_npu_src", 0,
|
||||
RV1103B_NPUCLKGATE_CON(0), 4, GFLAGS),
|
||||
GATE(ACLK_RKNN, "aclk_rknn", "aclk_npu_root", 0,
|
||||
RV1103B_NPUCLKGATE_CON(0), 5, GFLAGS),
|
||||
|
||||
/* pd_vepu */
|
||||
COMPOSITE_NOMUX(LSCLK_VEPU_ROOT, "lsclk_vepu_root", "aclk_vepu_src", CLK_IS_CRITICAL,
|
||||
RV1103B_VEPUCLKSEL_CON(0), 2, 2, DFLAGS,
|
||||
RV1103B_VEPUCLKGATE_CON(0), 0, GFLAGS),
|
||||
GATE(HCLK_VEPU, "hclk_vepu", "lsclk_vepu_root", 0,
|
||||
RV1103B_VEPUCLKGATE_CON(0), 4, GFLAGS),
|
||||
GATE(ACLK_VEPU, "aclk_vepu", "aclk_vepu_src", 0,
|
||||
RV1103B_VEPUCLKGATE_CON(0), 5, GFLAGS),
|
||||
COMPOSITE_NODIV(CLK_CORE_VEPU, "clk_core_vepu", clk_core_vepu_p, 0,
|
||||
RV1103B_VEPUCLKSEL_CON(0), 1, 1, MFLAGS,
|
||||
RV1103B_VEPUCLKGATE_CON(0), 6, GFLAGS),
|
||||
GATE(PCLK_ACODEC, "pclk_acodec", "lsclk_vepu_root", 0,
|
||||
RV1103B_VEPUCLKGATE_CON(0), 13, GFLAGS),
|
||||
GATE(PCLK_USBPHY, "pclk_usbphy", "lsclk_vepu_root", 0,
|
||||
RV1103B_VEPUCLKGATE_CON(0), 14, GFLAGS),
|
||||
|
||||
/* pd_vi */
|
||||
FACTOR(LSCLK_VI_100M, "lsclk_vi_100m", "clk_gpll_div6", 0, 1, 2),
|
||||
COMPOSITE_NODIV(LSCLK_VI_ROOT, "lsclk_vi_root", lsclk_vi_root_p, CLK_IS_CRITICAL,
|
||||
RV1103B_VICLKSEL_CON(0), 3, 1, MFLAGS,
|
||||
RV1103B_VICLKGATE_CON(0), 0, GFLAGS),
|
||||
GATE(HCLK_ISP, "hclk_isp", "lsclk_vi_root", 0,
|
||||
RV1103B_VICLKGATE_CON(0), 4, GFLAGS),
|
||||
GATE(ACLK_ISP, "aclk_isp", "aclk_vi_src", 0,
|
||||
RV1103B_VICLKGATE_CON(0), 5, GFLAGS),
|
||||
COMPOSITE_NODIV(CLK_CORE_ISP, "clk_core_isp", clk_core_isp_p, 0,
|
||||
RV1103B_VICLKSEL_CON(0), 1, 1, MFLAGS,
|
||||
RV1103B_VICLKGATE_CON(0), 6, GFLAGS),
|
||||
GATE(ACLK_VICAP, "aclk_vicap", "aclk_vi_src", 0,
|
||||
RV1103B_VICLKGATE_CON(1), 2, GFLAGS),
|
||||
GATE(HCLK_VICAP, "hclk_vicap", "lsclk_vi_root", 0,
|
||||
RV1103B_VICLKGATE_CON(1), 3, GFLAGS),
|
||||
GATE(ISP0CLK_VICAP, "isp0clk_vicap", "clk_core_isp", 0,
|
||||
RV1103B_VICLKGATE_CON(1), 8, GFLAGS),
|
||||
GATE(PCLK_CSI2HOST0, "pclk_csi2host0", "lsclk_vi_root", 0,
|
||||
RV1103B_VICLKGATE_CON(1), 9, GFLAGS),
|
||||
GATE(PCLK_CSI2HOST1, "pclk_csi2host1", "lsclk_vi_root", 0,
|
||||
RV1103B_VICLKGATE_CON(1), 11, GFLAGS),
|
||||
GATE(HCLK_EMMC, "hclk_emmc", "lsclk_vi_root", 0,
|
||||
RV1103B_VICLKGATE_CON(1), 13, GFLAGS),
|
||||
GATE(HCLK_SFC, "hclk_sfc", "lsclk_vi_root", 0,
|
||||
RV1103B_VICLKGATE_CON(1), 14, GFLAGS),
|
||||
GATE(HCLK_SFC_XIP, "hclk_sfc_xip", "lsclk_vi_root", 0,
|
||||
RV1103B_VICLKGATE_CON(1), 15, GFLAGS),
|
||||
GATE(HCLK_SDMMC0, "hclk_sdmmc0", "lsclk_vi_root", 0,
|
||||
RV1103B_VICLKGATE_CON(2), 0, GFLAGS),
|
||||
GATE(PCLK_CSIPHY, "pclk_csiphy", "lsclk_vi_root", 0,
|
||||
RV1103B_VICLKGATE_CON(2), 2, GFLAGS),
|
||||
GATE(PCLK_GPIO1, "pclk_gpio1", "lsclk_vi_root", 0,
|
||||
RV1103B_VICLKGATE_CON(2), 3, GFLAGS),
|
||||
GATE(DBCLK_GPIO1, "dbclk_gpio1", "xin24m", 0,
|
||||
RV1103B_VICLKGATE_CON(2), 4, GFLAGS),
|
||||
|
||||
/* pd_ddr */
|
||||
GATE(LSCLK_DDR_ROOT, "lsclk_ddr_root", "clk_gpll_div12", CLK_IS_CRITICAL,
|
||||
RV1103B_DDRCLKGATE_CON(0), 0, GFLAGS),
|
||||
GATE(CLK_TIMER_DDRMON, "clk_timer_ddrmon", "xin24m", 0,
|
||||
RV1103B_DDRCLKGATE_CON(0), 4, GFLAGS),
|
||||
FACTOR(0, "sclk_ddr", "dpll", 0, 1, 2),
|
||||
|
||||
/* pd_pmu */
|
||||
COMPOSITE(LSCLK_PMU_ROOT, "lsclk_pmu_root", lsclk_pmu_root_p, CLK_IS_CRITICAL,
|
||||
RV1103B_PMUCLKSEL_CON(2), 4, 1, MFLAGS, 0, 2, DFLAGS,
|
||||
RV1103B_PMUCLKGATE_CON(0), 0, GFLAGS),
|
||||
GATE(PCLK_PMU, "pclk_pmu", "lsclk_pmu_root", CLK_IS_CRITICAL,
|
||||
RV1103B_PMUCLKGATE_CON(0), 2, GFLAGS),
|
||||
MUX(XIN_RC_SRC, "xin_rc_src", xin_rc_div_p, 0,
|
||||
RV1103B_PMUCLKSEL_CON(0), 2, 1, MFLAGS),
|
||||
COMPOSITE_FRACMUX(XIN_RC_DIV, "xin_rc_div", "xin_rc_src", CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
|
||||
RV1103B_PMUCLKSEL_CON(1), 0,
|
||||
RV1103B_PMUCLKGATE_CON(0), 3, GFLAGS,
|
||||
&rv1103b_rcdiv_pmu_fracmux),
|
||||
GATE(PCLK_PMU_GPIO0, "pclk_pmu_gpio0", "lsclk_pmu_root", 0,
|
||||
RV1103B_PMUCLKGATE_CON(0), 4, GFLAGS),
|
||||
COMPOSITE_NODIV(DBCLK_PMU_GPIO0, "dbclk_pmu_gpio0", dbclk_pmu_gpio0_p, 0,
|
||||
RK3568_PMU_CLKSEL_CON(0), 3, 1, MFLAGS,
|
||||
RV1103B_PMUCLKGATE_CON(0), 5, GFLAGS),
|
||||
GATE(PCLK_PWM0, "pclk_pwm0", "lsclk_pmu_root", 0,
|
||||
RV1103B_PMUCLKGATE_CON(2), 0, GFLAGS),
|
||||
GATE(CLK_PWM0, "clk_pwm0", "clk_pwm0_src", 0,
|
||||
RV1103B_PMUCLKGATE_CON(2), 1, GFLAGS),
|
||||
GATE(CLK_OSC_PWM0, "clk_osc_pwm0", "xin24m", 0,
|
||||
RV1103B_PMUCLKGATE_CON(2), 2, GFLAGS),
|
||||
GATE(CLK_RC_PWM0, "clk_rc_pwm0", "clk_32k", 0,
|
||||
RV1103B_PMUCLKGATE_CON(2), 3, GFLAGS),
|
||||
GATE(PCLK_I2C0, "pclk_i2c0", "lsclk_pmu_root", 0,
|
||||
RV1103B_PMUCLKGATE_CON(0), 12, GFLAGS),
|
||||
GATE(CLK_I2C0, "clk_i2c0", "clk_i2c_pmu", 0,
|
||||
RV1103B_PMUCLKGATE_CON(0), 13, GFLAGS),
|
||||
GATE(PCLK_UART0, "pclk_uart0", "lsclk_pmu_root", 0,
|
||||
RV1103B_PMUCLKGATE_CON(0), 14, GFLAGS),
|
||||
GATE(CLK_REFOUT, "clk_refout", "xin24m", 0,
|
||||
RV1103B_PMUCLKGATE_CON(1), 4, GFLAGS),
|
||||
GATE(CLK_PREROLL, "clk_preroll", "lsclk_pmu_root", 0,
|
||||
RV1103B_PMUCLKGATE_CON(1), 6, GFLAGS),
|
||||
GATE(CLK_PREROLL_32K, "clk_preroll_32k", "clk_32k", 0,
|
||||
RV1103B_PMUCLKGATE_CON(1), 7, GFLAGS),
|
||||
GATE(CLK_LPMCU_PMU, "clk_lpmcu_pmu", "lsclk_pmu_root", 0,
|
||||
RV1103B_PMUCLKGATE_CON(2), 12, GFLAGS),
|
||||
|
||||
/* pd_pmu1 */
|
||||
GATE(PCLK_SPI2AHB, "pclk_spi2ahb", "lsclk_pmu_root", 0,
|
||||
RV1103B_PMU1CLKGATE_CON(0), 0, GFLAGS),
|
||||
GATE(HCLK_SPI2AHB, "hclk_spi2ahb", "lsclk_pmu_root", 0,
|
||||
RV1103B_PMU1CLKGATE_CON(0), 1, GFLAGS),
|
||||
GATE(PCLK_WDT_LPMCU, "pclk_wdt_lpmcu", "lsclk_pmu_root", 0,
|
||||
RV1103B_PMU1CLKGATE_CON(0), 9, GFLAGS),
|
||||
GATE(TCLK_WDT_LPMCU, "tclk_wdt_lpmcu", "xin24m", 0,
|
||||
RV1103B_PMU1CLKGATE_CON(0), 10, GFLAGS),
|
||||
GATE(HCLK_SFC_PMU1, "hclk_sfc_pmu1", "lsclk_pmu_root", 0,
|
||||
RV1103B_PMU1CLKGATE_CON(0), 12, GFLAGS),
|
||||
GATE(HCLK_SFC_XIP_PMU1, "hclk_sfc_xip_pmu1", "lsclk_pmu_root", 0,
|
||||
RV1103B_PMU1CLKGATE_CON(0), 13, GFLAGS),
|
||||
COMPOSITE_NODIV(SCLK_SFC_2X_PMU1, "sclk_sfc_2x_pmu1", sclk_sfc_2x_pmu1_p, 0,
|
||||
RV1103B_PMU1CLKSEL_CON(0), 8, 1, MFLAGS,
|
||||
RV1103B_PMU1CLKGATE_CON(0), 14, GFLAGS),
|
||||
GATE(CLK_LPMCU, "clk_lpmcu", "lsclk_pmu_root", 0,
|
||||
RV1103B_PMU1CLKGATE_CON(1), 0, GFLAGS),
|
||||
GATE(CLK_LPMCU_RTC, "clk_lpmcu_rtc", "xin24m", 0,
|
||||
RV1103B_PMU1CLKGATE_CON(1), 4, GFLAGS),
|
||||
GATE(PCLK_LPMCU_MAILBOX, "pclk_lpmcu_mailbox", "lsclk_pmu_root", 0,
|
||||
RV1103B_PMU1CLKGATE_CON(1), 8, GFLAGS),
|
||||
|
||||
/* pd_peri */
|
||||
COMPOSITE_NOMUX(PCLK_PERI_ROOT, "pclk_peri_root", "lsclk_peri_src", CLK_IS_CRITICAL,
|
||||
RV1103B_PERICLKSEL_CON(0), 0, 2, DFLAGS,
|
||||
RV1103B_PERICLKGATE_CON(0), 0, GFLAGS),
|
||||
COMPOSITE_NOMUX(PCLK_RTC_ROOT, "pclk_rtc_root", "lsclk_peri_src", CLK_IS_CRITICAL,
|
||||
RV1103B_PERICLKSEL_CON(2), 12, 4, DFLAGS,
|
||||
RV1103B_PERICLKGATE_CON(0), 8, GFLAGS),
|
||||
GATE(CLK_TIMER_ROOT, "clk_timer_root", "xin24m", 0,
|
||||
RV1103B_PERICLKGATE_CON(0), 1, GFLAGS),
|
||||
GATE(PCLK_TIMER, "pclk_timer", "pclk_peri_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(1), 0, GFLAGS),
|
||||
GATE(CLK_TIMER0, "clk_timer0", "clk_timer_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(1), 1, GFLAGS),
|
||||
GATE(CLK_TIMER1, "clk_timer1", "clk_timer_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(1), 2, GFLAGS),
|
||||
GATE(CLK_TIMER2, "clk_timer2", "clk_timer_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(1), 3, GFLAGS),
|
||||
GATE(CLK_TIMER3, "clk_timer3", "clk_timer_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(1), 4, GFLAGS),
|
||||
GATE(CLK_TIMER4, "clk_timer4", "clk_timer_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(1), 5, GFLAGS),
|
||||
GATE(CLK_TIMER5, "clk_timer5", "clk_timer_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(1), 6, GFLAGS),
|
||||
GATE(PCLK_STIMER, "pclk_stimer", "pclk_peri_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(1), 7, GFLAGS),
|
||||
GATE(CLK_STIMER0, "clk_stimer0", "clk_timer_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(1), 8, GFLAGS),
|
||||
GATE(CLK_STIMER1, "clk_stimer1", "clk_timer_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(1), 9, GFLAGS),
|
||||
GATE(PCLK_WDT_NS, "pclk_wdt_ns", "pclk_peri_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(2), 0, GFLAGS),
|
||||
GATE(TCLK_WDT_NS, "tclk_wdt_ns", "xin24m", 0,
|
||||
RV1103B_PERICLKGATE_CON(2), 1, GFLAGS),
|
||||
GATE(PCLK_WDT_S, "pclk_wdt_s", "pclk_peri_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(2), 2, GFLAGS),
|
||||
GATE(TCLK_WDT_S, "tclk_wdt_s", "xin24m", 0,
|
||||
RV1103B_PERICLKGATE_CON(2), 3, GFLAGS),
|
||||
GATE(PCLK_WDT_HPMCU, "pclk_wdt_hpmcu", "pclk_peri_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(2), 4, GFLAGS),
|
||||
GATE(TCLK_WDT_HPMCU, "tclk_wdt_hpmcu", "xin24m", 0,
|
||||
RV1103B_PERICLKGATE_CON(2), 5, GFLAGS),
|
||||
GATE(PCLK_I2C1, "pclk_i2c1", "pclk_peri_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(2), 6, GFLAGS),
|
||||
GATE(CLK_I2C1, "clk_i2c1", "clk_i2c_peri", 0,
|
||||
RV1103B_PERICLKGATE_CON(2), 7, GFLAGS),
|
||||
GATE(PCLK_I2C2, "pclk_i2c2", "pclk_peri_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(2), 8, GFLAGS),
|
||||
GATE(CLK_I2C2, "clk_i2c2", "clk_i2c_peri", 0,
|
||||
RV1103B_PERICLKGATE_CON(2), 9, GFLAGS),
|
||||
GATE(PCLK_I2C3, "pclk_i2c3", "pclk_peri_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(2), 10, GFLAGS),
|
||||
GATE(CLK_I2C3, "clk_i2c3", "clk_i2c_peri", 0,
|
||||
RV1103B_PERICLKGATE_CON(2), 11, GFLAGS),
|
||||
GATE(PCLK_I2C4, "pclk_i2c4", "pclk_peri_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(2), 12, GFLAGS),
|
||||
GATE(CLK_I2C4, "clk_i2c4", "clk_i2c_peri", 0,
|
||||
RV1103B_PERICLKGATE_CON(2), 13, GFLAGS),
|
||||
GATE(PCLK_SPI0, "pclk_spi0", "pclk_peri_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(3), 10, GFLAGS),
|
||||
GATE(PCLK_PWM1, "pclk_pwm1", "pclk_peri_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(4), 6, GFLAGS),
|
||||
GATE(CLK_OSC_PWM1, "clk_osc_pwm1", "xin24m", 0,
|
||||
RV1103B_PERICLKGATE_CON(4), 8, GFLAGS),
|
||||
GATE(PCLK_PWM2, "pclk_pwm2", "pclk_peri_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(4), 12, GFLAGS),
|
||||
GATE(CLK_OSC_PWM2, "clk_osc_pwm2", "xin24m", 0,
|
||||
RV1103B_PERICLKGATE_CON(4), 13, GFLAGS),
|
||||
GATE(PCLK_UART2, "pclk_uart2", "pclk_peri_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(3), 0, GFLAGS),
|
||||
GATE(PCLK_UART1, "pclk_uart1", "pclk_peri_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(3), 2, GFLAGS),
|
||||
GATE(ACLK_RKDMA, "aclk_rkdma", "lsclk_peri_src", 0,
|
||||
RV1103B_PERICLKGATE_CON(5), 8, GFLAGS),
|
||||
GATE(PCLK_TSADC, "pclk_tsadc", "pclk_peri_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(5), 9, GFLAGS),
|
||||
COMPOSITE_NOMUX(CLK_TSADC, "clk_tsadc", "xin24m", 0,
|
||||
RV1103B_PERICLKSEL_CON(0), 4, 5, DFLAGS,
|
||||
RV1103B_PERICLKGATE_CON(5), 10, GFLAGS),
|
||||
COMPOSITE_NOMUX(CLK_TSADC_TSEN, "clk_tsadc_tsen", "xin24m", 0,
|
||||
RV1103B_PERICLKSEL_CON(0), 10, 5, DFLAGS,
|
||||
RV1103B_PERICLKGATE_CON(5), 11, GFLAGS),
|
||||
GATE(PCLK_SARADC, "pclk_saradc", "pclk_peri_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(5), 12, GFLAGS),
|
||||
COMPOSITE_NOMUX(CLK_SARADC, "clk_saradc", "xin24m", 0,
|
||||
RV1103B_PERICLKSEL_CON(1), 0, 3, DFLAGS,
|
||||
RV1103B_PERICLKGATE_CON(5), 13, GFLAGS),
|
||||
GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_peri_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(6), 3, GFLAGS),
|
||||
GATE(DBCLK_GPIO2, "dbclk_gpio2", "xin24m", 0,
|
||||
RV1103B_PERICLKGATE_CON(6), 4, GFLAGS),
|
||||
GATE(ACLK_USBOTG, "aclk_usbotg", "lsclk_peri_src", 0,
|
||||
RV1103B_PERICLKGATE_CON(6), 9, GFLAGS),
|
||||
GATE(CLK_REF_USBOTG, "clk_ref_usbotg", "xin24m", 0,
|
||||
RV1103B_PERICLKGATE_CON(6), 10, GFLAGS),
|
||||
GATE(HCLK_SDMMC1, "hclk_sdmmc1", "lsclk_peri_src", 0,
|
||||
RV1103B_PERICLKGATE_CON(7), 0, GFLAGS),
|
||||
GATE(HCLK_SAI, "hclk_sai", "lsclk_peri_src", 0,
|
||||
RV1103B_PERICLKGATE_CON(7), 1, GFLAGS),
|
||||
GATE(ACLK_CRYPTO, "aclk_crypto", "lsclk_peri_src", 0,
|
||||
RV1103B_PERICLKGATE_CON(8), 2, GFLAGS),
|
||||
GATE(HCLK_CRYPTO, "hclk_crypto", "lsclk_peri_src", 0,
|
||||
RV1103B_PERICLKGATE_CON(8), 3, GFLAGS),
|
||||
GATE(HCLK_RK_RNG_S, "hclk_rk_rng_s", "lsclk_peri_src", 0,
|
||||
RV1103B_PERICLKGATE_CON(8), 5, GFLAGS),
|
||||
GATE(HCLK_RK_RNG_NS, "hclk_rk_rng_ns", "hclk_rk_rng_s", 0,
|
||||
RV1103B_PERICLKGATE_CON(8), 4, GFLAGS),
|
||||
GATE(PCLK_OTPC_NS, "pclk_otpc_ns", "pclk_peri_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(8), 6, GFLAGS),
|
||||
GATE(CLK_OTPC_ROOT_NS, "clk_otpc_root_ns", "xin24m", 0,
|
||||
RV1103B_PERICLKGATE_CON(8), 7, GFLAGS),
|
||||
GATE(CLK_SBPI_OTPC_NS, "clk_sbpi_otpc_ns", "clk_otpc_root_ns", 0,
|
||||
RV1103B_PERICLKGATE_CON(8), 8, GFLAGS),
|
||||
COMPOSITE_NOMUX(CLK_USER_OTPC_NS, "clk_user_otpc_ns", "clk_otpc_root_ns", 0,
|
||||
RV1103B_PERICLKSEL_CON(1), 4, 3, DFLAGS,
|
||||
RV1103B_PERICLKGATE_CON(8), 9, GFLAGS),
|
||||
GATE(PCLK_OTPC_S, "pclk_otpc_s", "pclk_peri_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(8), 10, GFLAGS),
|
||||
GATE(CLK_OTPC_ROOT_S, "clk_otpc_root_s", "xin24m", 0,
|
||||
RV1103B_PERICLKGATE_CON(8), 11, GFLAGS),
|
||||
GATE(CLK_SBPI_OTPC_S, "clk_sbpi_otpc_s", "clk_otpc_root_s", 0,
|
||||
RV1103B_PERICLKGATE_CON(8), 12, GFLAGS),
|
||||
COMPOSITE_NOMUX(CLK_USER_OTPC_S, "clk_user_otpc_s", "clk_otpc_root_s", 0,
|
||||
RV1103B_PERICLKSEL_CON(1), 8, 3, DFLAGS,
|
||||
RV1103B_PERICLKGATE_CON(8), 13, GFLAGS),
|
||||
GATE(PCLK_OTP_MASK, "pclk_otp_mask", "pclk_peri_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(8), 15, GFLAGS),
|
||||
GATE(HCLK_RGA, "hclk_rga", "lsclk_peri_src", 0,
|
||||
RV1103B_PERICLKGATE_CON(9), 0, GFLAGS),
|
||||
GATE(ACLK_RGA, "aclk_rga", "aclk_peri_src", 0,
|
||||
RV1103B_PERICLKGATE_CON(9), 1, GFLAGS),
|
||||
GATE(ACLK_MAC, "aclk_mac", "lsclk_peri_src", 0,
|
||||
RV1103B_PERICLKGATE_CON(9), 3, GFLAGS),
|
||||
GATE(PCLK_MAC, "pclk_mac", "pclk_peri_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(9), 4, GFLAGS),
|
||||
GATE(CLK_MACPHY, "clk_macphy", "xin24m", 0,
|
||||
RV1103B_PERICLKGATE_CON(9), 11, GFLAGS),
|
||||
GATE(ACLK_SPINLOCK, "aclk_spinlock", "lsclk_peri_src", 0,
|
||||
RV1103B_PERICLKGATE_CON(10), 0, GFLAGS),
|
||||
GATE(HCLK_CACHE, "hclk_cache", "hclk_hpmcu", 0,
|
||||
RV1103B_PERICLKGATE_CON(10), 1, GFLAGS),
|
||||
GATE(PCLK_HPMCU_MAILBOX, "pclk_hpmcu_mailbox", "pclk_peri_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(10), 2, GFLAGS),
|
||||
GATE(PCLK_HPMCU_INTMUX, "pclk_hpmcu_intmux", "pclk_peri_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(10), 3, GFLAGS),
|
||||
GATE(CLK_HPMCU, "clk_hpmcu", "hclk_hpmcu", 0,
|
||||
RV1103B_PERICLKGATE_CON(10), 4, GFLAGS),
|
||||
GATE(CLK_HPMCU_RTC, "clk_hpmcu_rtc", "xin24m", 0,
|
||||
RV1103B_PERICLKGATE_CON(10), 8, GFLAGS),
|
||||
GATE(DCLK_DECOM, "dclk_decom", "dclk_decom_src", 0,
|
||||
RV1103B_PERICLKGATE_CON(11), 0, GFLAGS),
|
||||
GATE(ACLK_DECOM, "aclk_decom", "aclk_peri_src", 0,
|
||||
RV1103B_PERICLKGATE_CON(11), 1, GFLAGS),
|
||||
GATE(PCLK_DECOM, "pclk_decom", "pclk_peri_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(11), 2, GFLAGS),
|
||||
GATE(ACLK_SYS_SRAM, "aclk_sys_sram", "lsclk_peri_src", CLK_IS_CRITICAL,
|
||||
RV1103B_PERICLKGATE_CON(11), 3, GFLAGS),
|
||||
GATE(PCLK_DMA2DDR, "pclk_dma2ddr", "pclk_peri_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(11), 4, GFLAGS),
|
||||
GATE(ACLK_DMA2DDR, "aclk_dma2ddr", "aclk_peri_src", 0,
|
||||
RV1103B_PERICLKGATE_CON(11), 5, GFLAGS),
|
||||
GATE(PCLK_DCF, "pclk_dcf", "pclk_peri_root", 0,
|
||||
RV1103B_PERICLKGATE_CON(11), 6, GFLAGS),
|
||||
GATE(ACLK_DCF, "aclk_dcf", "lsclk_peri_src", 0,
|
||||
RV1103B_PERICLKGATE_CON(11), 7, GFLAGS),
|
||||
COMPOSITE_NOMUX(MCLK_ACODEC_TX, "mclk_acodec_tx", "mclk_sai_src", 0,
|
||||
RV1103B_PERICLKSEL_CON(2), 0, 3, DFLAGS,
|
||||
RV1103B_PERICLKGATE_CON(11), 9, GFLAGS),
|
||||
GATE(CLK_REF_USBPHY, "clk_ref_usbphy", "xin24m", 0,
|
||||
RV1103B_PERICLKGATE_CON(11), 12, GFLAGS),
|
||||
|
||||
/* io */
|
||||
COMPOSITE_NODIV(CLK_FREQ_PWM0_SRC, "clk_freq_pwm0_src", clk_freq_pwm0_src_p, 0,
|
||||
RV1103B_CLKSEL_CON(35), 12, 2, MFLAGS,
|
||||
RV1103B_CLKGATE_CON(5), 6, GFLAGS),
|
||||
GATE(CLK_FREQ_PWM0, "clk_freq_pwm0", "clk_freq_pwm0_src", 0,
|
||||
RV1103B_PMUCLKGATE_CON(2), 4, GFLAGS),
|
||||
COMPOSITE_NODIV(CLK_COUNTER_PWM0_SRC, "clk_counter_pwm0_src", clk_counter_pwm0_src_p, 0,
|
||||
RV1103B_CLKSEL_CON(35), 14, 2, MFLAGS,
|
||||
RV1103B_CLKGATE_CON(5), 7, GFLAGS),
|
||||
GATE(CLK_COUNTER_PWM0, "clk_counter_pwm0", "clk_counter_pwm0_src", 0,
|
||||
RV1103B_PMUCLKGATE_CON(2), 5, GFLAGS),
|
||||
GATE(SCLK_SPI2AHB, "sclk_spi2ahb", "sclk_spi2ahb_io", 0,
|
||||
RV1103B_PMU1CLKGATE_CON(0), 2, GFLAGS),
|
||||
GATE(CLK_UTMI_USBOTG, "clk_utmi_usbotg", "clk_utmi_usbotg_io", 0,
|
||||
RV1103B_PERICRU_IP_CON, 14, GFLAGS),
|
||||
};
|
||||
|
||||
static struct rockchip_clk_branch rv1103b_armclk __initdata =
|
||||
MUX(ARMCLK, "armclk", mux_armclk_p, CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
|
||||
RV1103B_CORECLKSEL_CON(0), 1, 1, MFLAGS);
|
||||
|
||||
static void __init rv1103b_clk_init(struct device_node *np)
|
||||
{
|
||||
struct rockchip_clk_provider *ctx;
|
||||
unsigned long clk_nr;
|
||||
void __iomem *reg_base;
|
||||
|
||||
clk_nr = rockchip_clk_find_max_clk_id(rv1103b_clk_branches,
|
||||
ARRAY_SIZE(rv1103b_clk_branches)) + 1;
|
||||
reg_base = of_iomap(np, 0);
|
||||
if (!reg_base) {
|
||||
pr_err("%s: could not map cru region\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
ctx = rockchip_clk_init(np, reg_base, clk_nr);
|
||||
if (IS_ERR(ctx)) {
|
||||
pr_err("%s: rockchip clk init failed\n", __func__);
|
||||
iounmap(reg_base);
|
||||
return;
|
||||
}
|
||||
|
||||
rockchip_clk_register_plls(ctx, rv1103b_pll_clks,
|
||||
ARRAY_SIZE(rv1103b_pll_clks),
|
||||
RV1103B_GRF_SOC_STATUS0);
|
||||
|
||||
rockchip_clk_register_branches(ctx, rv1103b_clk_branches,
|
||||
ARRAY_SIZE(rv1103b_clk_branches));
|
||||
|
||||
rockchip_clk_register_armclk_multi_pll(ctx, &rv1103b_armclk,
|
||||
rv1103b_cpuclk_rates,
|
||||
ARRAY_SIZE(rv1103b_cpuclk_rates));
|
||||
|
||||
rockchip_register_restart_notifier(ctx, RV1103B_GLB_SRST_FST, NULL);
|
||||
|
||||
rockchip_clk_of_add_provider(np, ctx);
|
||||
|
||||
/* pvtpll src init */
|
||||
writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RV1103B_CORECLKSEL_CON(0));
|
||||
writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RV1103B_NPUCLKSEL_CON(0));
|
||||
writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RV1103B_VICLKSEL_CON(0));
|
||||
writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RV1103B_VEPUCLKSEL_CON(0));
|
||||
}
|
||||
|
||||
CLK_OF_DECLARE(rv1103b_cru, "rockchip,rv1103b-cru", rv1103b_clk_init);
|
||||
|
|
@ -66,6 +66,55 @@ struct clk;
|
|||
#define PX30_PMU_CLKGATE_CON(x) ((x) * 0x4 + 0x80)
|
||||
#define PX30_PMU_MODE 0x0020
|
||||
|
||||
#define RV1103B_TOPCRU_BASE 0x60000
|
||||
#define RV1103B_PERICRU_BASE 0x0
|
||||
#define RV1103B_VICRU_BASE 0x30000
|
||||
#define RV1103B_NPUCRU_BASE 0x20000
|
||||
#define RV1103B_CORECRU_BASE 0x40000
|
||||
#define RV1103B_VEPUCRU_BASE 0x10000
|
||||
#define RV1103B_DDRCRU_BASE 0x50000
|
||||
#define RV1103B_SUBDDRCRU_BASE 0x58000
|
||||
#define RV1103B_PMUCRU_BASE 0x70000
|
||||
#define RV1103B_PMU1CRU_BASE 0x80000
|
||||
|
||||
#define RV1103B_PMUCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1103B_PMUCRU_BASE)
|
||||
#define RV1103B_PMUCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1103B_PMUCRU_BASE)
|
||||
#define RV1103B_PMUSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1103B_PMUCRU_BASE)
|
||||
#define RV1103B_PMU1CLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1103B_PMU1CRU_BASE)
|
||||
#define RV1103B_PMU1CLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1103B_PMU1CRU_BASE)
|
||||
#define RV1103B_PMU1SOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1103B_PMU1CRU_BASE)
|
||||
#define RV1103B_PLL_CON(x) ((x) * 0x4 + RV1103B_TOPCRU_BASE)
|
||||
#define RV1103B_MODE_CON (0x280 + RV1103B_TOPCRU_BASE)
|
||||
#define RV1103B_CLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1103B_TOPCRU_BASE)
|
||||
#define RV1103B_CLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1103B_TOPCRU_BASE)
|
||||
#define RV1103B_SOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1103B_TOPCRU_BASE)
|
||||
#define RV1103B_GLB_SRST_FST (0xc08 + RV1103B_TOPCRU_BASE)
|
||||
#define RV1103B_GLB_SRST_SND (0xc0c + RV1103B_TOPCRU_BASE)
|
||||
#define RV1103B_CLK_SAI_FRAC_DIV_HIGH (0xcc0 + RV1103B_TOPCRU_BASE)
|
||||
#define RV1103B_PERICLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1103B_PERICRU_BASE)
|
||||
#define RV1103B_PERICLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1103B_PERICRU_BASE)
|
||||
#define RV1103B_PERISOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1103B_PERICRU_BASE)
|
||||
#define RV1103B_PERICRU_IP_CON (0xc08 + RV1103B_PERICRU_BASE)
|
||||
#define RV1103B_VICLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1103B_VICRU_BASE)
|
||||
#define RV1103B_VICLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1103B_VICRU_BASE)
|
||||
#define RV1103B_VISOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1103B_VICRU_BASE)
|
||||
#define RV1103B_NPUCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1103B_NPUCRU_BASE)
|
||||
#define RV1103B_NPUCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1103B_NPUCRU_BASE)
|
||||
#define RV1103B_NPUSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1103B_NPUCRU_BASE)
|
||||
#define RV1103B_CORECLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1103B_CORECRU_BASE)
|
||||
#define RV1103B_CORECLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1103B_CORECRU_BASE)
|
||||
#define RV1103B_CORESOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1103B_CORECRU_BASE)
|
||||
#define RV1103B_VEPUCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1103B_VEPUCRU_BASE)
|
||||
#define RV1103B_VEPUCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1103B_VEPUCRU_BASE)
|
||||
#define RV1103B_VEPUSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1103B_VEPUCRU_BASE)
|
||||
#define RV1103B_DDRCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1103B_DDRCRU_BASE)
|
||||
#define RV1103B_DDRCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1103B_DDRCRU_BASE)
|
||||
#define RV1103B_DDRSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1103B_DDRCRU_BASE)
|
||||
#define RV1103B_SUBDDRCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1103B_SUBDDRCRU_BASE)
|
||||
#define RV1103B_SUBDDRCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1103B_SUBDDRCRU_BASE)
|
||||
#define RV1103B_SUBDDRSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1103B_SUBDDRCRU_BASE)
|
||||
#define RV1103B_SUBDDRMODE_CON (0x280 + RV1103B_SUBDDRCRU_BASE)
|
||||
|
||||
#define RV1108_PLL_CON(x) ((x) * 0x4)
|
||||
#define RV1108_CLKSEL_CON(x) ((x) * 0x4 + 0x60)
|
||||
#define RV1108_CLKGATE_CON(x) ((x) * 0x4 + 0x120)
|
||||
|
|
|
|||
|
|
@ -83,9 +83,22 @@ static SUNXI_CCU_MUX_DATA_WITH_GATE(r_pwmctrl_clk, "r-pwmctrl",
|
|||
static SUNXI_CCU_GATE_HW(bus_r_pwmctrl_clk, "bus-r-pwmctrl",
|
||||
&r_apb0_clk.common.hw, 0x13c, BIT(0), 0);
|
||||
|
||||
/* SPI clock is /M/N (same as new MMC?) */
|
||||
static const struct clk_parent_data r_spi_parents[] = {
|
||||
{ .fw_name = "hosc" },
|
||||
{ .fw_name = "pll-periph" },
|
||||
{ .name = "pll-periph0-300M" },
|
||||
{ .name = "pll-periph1-300M" },
|
||||
{ .name = "pll-audio" },
|
||||
};
|
||||
static SUNXI_CCU_DUALDIV_MUX_GATE(r_spi_clk, "r-spi", r_spi_parents, 0x150,
|
||||
0, 5, /* M */
|
||||
8, 5, /* P */
|
||||
24, 3, /* mux */
|
||||
BIT(31), /* gate */
|
||||
0);
|
||||
static SUNXI_CCU_GATE_HW(bus_r_spi_clk, "bus-r-spi",
|
||||
&r_ahb_clk.common.hw, 0x15c, BIT(0), 0);
|
||||
|
||||
static SUNXI_CCU_GATE_HW(bus_r_spinlock_clk, "bus-r-spinlock",
|
||||
&r_ahb_clk.common.hw, 0x16c, BIT(0), 0);
|
||||
static SUNXI_CCU_GATE_HW(bus_r_msgbox_clk, "bus-r-msgbox",
|
||||
|
|
@ -138,6 +151,7 @@ static struct ccu_common *sun55i_a523_r_ccu_clks[] = {
|
|||
&bus_r_twd_clk.common,
|
||||
&r_pwmctrl_clk.common,
|
||||
&bus_r_pwmctrl_clk.common,
|
||||
&r_spi_clk.common,
|
||||
&bus_r_spi_clk.common,
|
||||
&bus_r_spinlock_clk.common,
|
||||
&bus_r_msgbox_clk.common,
|
||||
|
|
@ -169,6 +183,7 @@ static struct clk_hw_onecell_data sun55i_a523_r_hw_clks = {
|
|||
[CLK_BUS_R_TWD] = &bus_r_twd_clk.common.hw,
|
||||
[CLK_R_PWMCTRL] = &r_pwmctrl_clk.common.hw,
|
||||
[CLK_BUS_R_PWMCTRL] = &bus_r_pwmctrl_clk.common.hw,
|
||||
[CLK_R_SPI] = &r_spi_clk.common.hw,
|
||||
[CLK_BUS_R_SPI] = &bus_r_spi_clk.common.hw,
|
||||
[CLK_BUS_R_SPINLOCK] = &bus_r_spinlock_clk.common.hw,
|
||||
[CLK_BUS_R_MSGBOX] = &bus_r_msgbox_clk.common.hw,
|
||||
|
|
|
|||
14
drivers/clk/tenstorrent/Kconfig
Normal file
14
drivers/clk/tenstorrent/Kconfig
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
config TENSTORRENT_ATLANTIS_PRCM
|
||||
tristate "Support for Tenstorrent Atlantis PRCM Clock Controller"
|
||||
depends on ARCH_TENSTORRENT || COMPILE_TEST
|
||||
default ARCH_TENSTORRENT
|
||||
select REGMAP_MMIO
|
||||
select AUXILIARY_BUS
|
||||
select MFD_SYSCON
|
||||
help
|
||||
Say yes here to support the different clock
|
||||
controllers found in the Tenstorrent Atlantis SoC.
|
||||
This includes the clocks from the RCPU, HSIO, MMIO
|
||||
and PCIE domain.
|
||||
3
drivers/clk/tenstorrent/Makefile
Normal file
3
drivers/clk/tenstorrent/Makefile
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
obj-$(CONFIG_TENSTORRENT_ATLANTIS_PRCM) += atlantis-prcm.o
|
||||
870
drivers/clk/tenstorrent/atlantis-prcm.c
Normal file
870
drivers/clk/tenstorrent/atlantis-prcm.c
Normal file
|
|
@ -0,0 +1,870 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Tenstorrent Atlantis PRCM Clock Driver
|
||||
*
|
||||
* Copyright (c) 2026 Tenstorrent
|
||||
*/
|
||||
|
||||
#include <dt-bindings/clock/tenstorrent,atlantis-prcm-rcpu.h>
|
||||
#include <linux/auxiliary_bus.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
/* RCPU Clock Register Offsets */
|
||||
#define PLL_RCPU_CFG_REG 0x0000
|
||||
#define PLL_NOCC_CFG_REG 0x0004
|
||||
#define NOCC_CLK_CFG_REG 0x0008
|
||||
#define RCPU_DIV_CFG_REG 0x000C
|
||||
#define RCPU_BLK_CG_REG 0x0014
|
||||
#define LSIO_BLK_CG_REG 0x0018
|
||||
#define PLL_RCPU_EN_REG 0x011C
|
||||
#define PLL_NOCC_EN_REG 0x0120
|
||||
#define BUS_CG_REG 0x01FC
|
||||
|
||||
/* PLL Bit Definitions */
|
||||
#define PLL_CFG_EN_BIT BIT(0)
|
||||
#define PLL_CFG_BYPASS_BIT BIT(1)
|
||||
#define PLL_CFG_REFDIV_MASK GENMASK(7, 2)
|
||||
#define PLL_CFG_REFDIV_SHIFT 2
|
||||
#define PLL_CFG_POSTDIV1_MASK GENMASK(10, 8)
|
||||
#define PLL_CFG_POSTDIV1_SHIFT 8
|
||||
#define PLL_CFG_POSTDIV2_MASK GENMASK(13, 11)
|
||||
#define PLL_CFG_POSTDIV2_SHIFT 11
|
||||
#define PLL_CFG_FBDIV_MASK GENMASK(25, 14)
|
||||
#define PLL_CFG_FBDIV_SHIFT 14
|
||||
#define PLL_CFG_LKDT_BIT BIT(30)
|
||||
#define PLL_CFG_LOCK_BIT BIT(31)
|
||||
#define PLL_LOCK_TIMEOUT_US 1000
|
||||
#define PLL_BYPASS_WAIT_US 500
|
||||
|
||||
struct atlantis_clk_common {
|
||||
int clkid;
|
||||
struct regmap *regmap;
|
||||
struct clk_hw hw;
|
||||
};
|
||||
|
||||
static inline struct atlantis_clk_common *
|
||||
hw_to_atlantis_clk_common(struct clk_hw *hw)
|
||||
{
|
||||
return container_of(hw, struct atlantis_clk_common, hw);
|
||||
}
|
||||
|
||||
struct atlantis_clk_mux_config {
|
||||
u8 shift;
|
||||
u8 width;
|
||||
u32 reg_offset;
|
||||
};
|
||||
|
||||
struct atlantis_clk_mux {
|
||||
struct atlantis_clk_common common;
|
||||
struct atlantis_clk_mux_config config;
|
||||
};
|
||||
|
||||
struct atlantis_clk_gate_config {
|
||||
u32 reg_offset;
|
||||
u32 enable;
|
||||
};
|
||||
|
||||
struct atlantis_clk_gate {
|
||||
struct atlantis_clk_common common;
|
||||
struct atlantis_clk_gate_config config;
|
||||
};
|
||||
|
||||
struct atlantis_clk_divider_config {
|
||||
u8 shift;
|
||||
u8 width;
|
||||
u32 flags;
|
||||
u32 reg_offset;
|
||||
};
|
||||
|
||||
struct atlantis_clk_divider {
|
||||
struct atlantis_clk_common common;
|
||||
struct atlantis_clk_divider_config config;
|
||||
};
|
||||
|
||||
struct atlantis_clk_pll_config {
|
||||
u32 tbl_num;
|
||||
u32 reg_offset;
|
||||
u32 en_reg_offset;
|
||||
u32 cg_reg_offset;
|
||||
u32 cg_reg_enable;
|
||||
};
|
||||
|
||||
/* Models a PLL with Bypass Functionality and Enable Bit + an optional Gate Clock at it's output */
|
||||
struct atlantis_clk_pll {
|
||||
struct atlantis_clk_common common;
|
||||
struct atlantis_clk_pll_config config;
|
||||
};
|
||||
|
||||
struct atlantis_clk_gate_shared_config {
|
||||
u32 reg_offset;
|
||||
u32 enable;
|
||||
unsigned int *share_count;
|
||||
spinlock_t *refcount_lock;
|
||||
};
|
||||
|
||||
struct atlantis_clk_gate_shared {
|
||||
struct atlantis_clk_common common;
|
||||
struct atlantis_clk_gate_shared_config config;
|
||||
};
|
||||
|
||||
struct atlantis_clk_fixed_factor_config {
|
||||
unsigned int mult;
|
||||
unsigned int div;
|
||||
};
|
||||
|
||||
struct atlantis_clk_fixed_factor {
|
||||
struct atlantis_clk_fixed_factor_config config;
|
||||
struct atlantis_clk_common common;
|
||||
};
|
||||
|
||||
static inline struct atlantis_clk_mux *hw_to_atlantis_clk_mux(struct clk_hw *hw)
|
||||
{
|
||||
struct atlantis_clk_common *common = hw_to_atlantis_clk_common(hw);
|
||||
|
||||
return container_of(common, struct atlantis_clk_mux, common);
|
||||
}
|
||||
|
||||
static inline struct atlantis_clk_gate *
|
||||
hw_to_atlantis_clk_gate(struct clk_hw *hw)
|
||||
{
|
||||
struct atlantis_clk_common *common = hw_to_atlantis_clk_common(hw);
|
||||
|
||||
return container_of(common, struct atlantis_clk_gate, common);
|
||||
}
|
||||
|
||||
static inline struct atlantis_clk_divider *
|
||||
hw_to_atlantis_clk_divider(struct clk_hw *hw)
|
||||
{
|
||||
struct atlantis_clk_common *common = hw_to_atlantis_clk_common(hw);
|
||||
|
||||
return container_of(common, struct atlantis_clk_divider, common);
|
||||
}
|
||||
|
||||
static inline struct atlantis_clk_pll *hw_to_atlantis_pll(struct clk_hw *hw)
|
||||
{
|
||||
struct atlantis_clk_common *common = hw_to_atlantis_clk_common(hw);
|
||||
|
||||
return container_of(common, struct atlantis_clk_pll, common);
|
||||
}
|
||||
|
||||
static inline struct atlantis_clk_gate_shared *
|
||||
hw_to_atlantis_clk_gate_shared(struct clk_hw *hw)
|
||||
{
|
||||
struct atlantis_clk_common *common = hw_to_atlantis_clk_common(hw);
|
||||
|
||||
return container_of(common, struct atlantis_clk_gate_shared, common);
|
||||
}
|
||||
|
||||
static inline struct atlantis_clk_fixed_factor *
|
||||
hw_to_atlantis_clk_fixed_factor(struct clk_hw *hw)
|
||||
{
|
||||
struct atlantis_clk_common *common = hw_to_atlantis_clk_common(hw);
|
||||
|
||||
return container_of(common, struct atlantis_clk_fixed_factor, common);
|
||||
}
|
||||
|
||||
static u8 atlantis_clk_mux_get_parent(struct clk_hw *hw)
|
||||
{
|
||||
struct atlantis_clk_mux *mux = hw_to_atlantis_clk_mux(hw);
|
||||
u32 val;
|
||||
|
||||
regmap_read(mux->common.regmap, mux->config.reg_offset, &val);
|
||||
val >>= mux->config.shift;
|
||||
val &= (BIT(mux->config.width) - 1);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static int atlantis_clk_mux_set_parent(struct clk_hw *hw, u8 index)
|
||||
{
|
||||
struct atlantis_clk_mux *mux = hw_to_atlantis_clk_mux(hw);
|
||||
u32 val = index;
|
||||
|
||||
return regmap_update_bits(mux->common.regmap, mux->config.reg_offset,
|
||||
(BIT(mux->config.width) - 1) << mux->config.shift,
|
||||
val << mux->config.shift);
|
||||
}
|
||||
|
||||
static int atlantis_clk_mux_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
return clk_mux_determine_rate_flags(hw, req, hw->init->flags);
|
||||
}
|
||||
|
||||
static const struct clk_ops atlantis_clk_mux_ops = {
|
||||
.get_parent = atlantis_clk_mux_get_parent,
|
||||
.set_parent = atlantis_clk_mux_set_parent,
|
||||
.determine_rate = atlantis_clk_mux_determine_rate,
|
||||
};
|
||||
|
||||
static int atlantis_clk_gate_endisable(struct clk_hw *hw, int enable)
|
||||
{
|
||||
struct atlantis_clk_gate *gate = hw_to_atlantis_clk_gate(hw);
|
||||
|
||||
if (enable)
|
||||
return regmap_set_bits(gate->common.regmap,
|
||||
gate->config.reg_offset,
|
||||
gate->config.enable);
|
||||
else
|
||||
return regmap_clear_bits(gate->common.regmap,
|
||||
gate->config.reg_offset,
|
||||
gate->config.enable);
|
||||
}
|
||||
|
||||
static int atlantis_clk_gate_enable(struct clk_hw *hw)
|
||||
{
|
||||
return atlantis_clk_gate_endisable(hw, 1);
|
||||
}
|
||||
|
||||
static void atlantis_clk_gate_disable(struct clk_hw *hw)
|
||||
{
|
||||
atlantis_clk_gate_endisable(hw, 0);
|
||||
}
|
||||
|
||||
static int atlantis_clk_gate_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
struct atlantis_clk_gate *gate = hw_to_atlantis_clk_gate(hw);
|
||||
|
||||
return regmap_test_bits(gate->common.regmap, gate->config.reg_offset, gate->config.enable);
|
||||
}
|
||||
|
||||
static const struct clk_ops atlantis_clk_gate_ops = {
|
||||
.enable = atlantis_clk_gate_enable,
|
||||
.disable = atlantis_clk_gate_disable,
|
||||
.is_enabled = atlantis_clk_gate_is_enabled,
|
||||
};
|
||||
|
||||
static unsigned long atlantis_clk_divider_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct atlantis_clk_divider *divider = hw_to_atlantis_clk_divider(hw);
|
||||
u32 val;
|
||||
|
||||
regmap_read(divider->common.regmap, divider->config.reg_offset, &val);
|
||||
|
||||
val >>= divider->config.shift;
|
||||
val &= ((1 << (divider->config.width)) - 1);
|
||||
|
||||
return DIV_ROUND_UP_ULL((u64)parent_rate, val + 1);
|
||||
}
|
||||
|
||||
static const struct clk_ops atlantis_clk_divider_ops = {
|
||||
.recalc_rate = atlantis_clk_divider_recalc_rate,
|
||||
};
|
||||
|
||||
static unsigned long
|
||||
atlantis_clk_fixed_factor_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct atlantis_clk_fixed_factor *factor =
|
||||
hw_to_atlantis_clk_fixed_factor(hw);
|
||||
unsigned long long rate;
|
||||
|
||||
rate = (unsigned long long)parent_rate * factor->config.mult;
|
||||
do_div(rate, factor->config.div);
|
||||
|
||||
return (unsigned long)rate;
|
||||
}
|
||||
|
||||
static const struct clk_ops atlantis_clk_fixed_factor_ops = {
|
||||
.recalc_rate = atlantis_clk_fixed_factor_recalc_rate,
|
||||
};
|
||||
|
||||
static int atlantis_clk_pll_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
struct atlantis_clk_pll *pll = hw_to_atlantis_pll(hw);
|
||||
u32 val, en_val, cg_val;
|
||||
|
||||
regmap_read(pll->common.regmap, pll->config.reg_offset, &val);
|
||||
regmap_read(pll->common.regmap, pll->config.en_reg_offset, &en_val);
|
||||
regmap_read(pll->common.regmap, pll->config.cg_reg_offset, &cg_val);
|
||||
|
||||
/* Check if PLL is powered on, locked, not bypassed and Gate clk is enabled */
|
||||
return !!(en_val & PLL_CFG_EN_BIT) && !!(val & PLL_CFG_LOCK_BIT) &&
|
||||
(!pll->config.cg_reg_enable || (cg_val & pll->config.cg_reg_enable)) &&
|
||||
!(val & PLL_CFG_BYPASS_BIT);
|
||||
}
|
||||
|
||||
static int atlantis_clk_pll_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct atlantis_clk_pll *pll = hw_to_atlantis_pll(hw);
|
||||
u32 val, en_val, cg_val;
|
||||
int ret;
|
||||
|
||||
regmap_read(pll->common.regmap, pll->config.reg_offset, &val);
|
||||
regmap_read(pll->common.regmap, pll->config.en_reg_offset, &en_val);
|
||||
regmap_read(pll->common.regmap, pll->config.cg_reg_offset, &cg_val);
|
||||
|
||||
/* Check if PLL is already enabled, locked, not bypassed and Gate clk is enabled */
|
||||
if ((en_val & PLL_CFG_EN_BIT) && (val & PLL_CFG_LOCK_BIT) &&
|
||||
(!pll->config.cg_reg_enable || (cg_val & pll->config.cg_reg_enable)) &&
|
||||
!(val & PLL_CFG_BYPASS_BIT)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Step 1: Set bypass mode first */
|
||||
regmap_update_bits(pll->common.regmap, pll->config.reg_offset,
|
||||
PLL_CFG_BYPASS_BIT, PLL_CFG_BYPASS_BIT);
|
||||
|
||||
/* Step 2: Enable PLL (clear then set power bit) */
|
||||
regmap_update_bits(pll->common.regmap, pll->config.en_reg_offset,
|
||||
PLL_CFG_EN_BIT, 0);
|
||||
|
||||
regmap_update_bits(pll->common.regmap, pll->config.en_reg_offset,
|
||||
PLL_CFG_EN_BIT, PLL_CFG_EN_BIT);
|
||||
|
||||
/* Step 3: Wait for PLL lock */
|
||||
ret = regmap_read_poll_timeout(pll->common.regmap,
|
||||
pll->config.reg_offset, val,
|
||||
val & PLL_CFG_LOCK_BIT,
|
||||
PLL_BYPASS_WAIT_US, PLL_LOCK_TIMEOUT_US);
|
||||
if (ret) {
|
||||
pr_err("PLL failed to lock within timeout\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Step 4: Switch from bypass to PLL output */
|
||||
regmap_update_bits(pll->common.regmap, pll->config.reg_offset,
|
||||
PLL_CFG_BYPASS_BIT, 0);
|
||||
|
||||
/* Enable Gate clk at PLL Output */
|
||||
return regmap_update_bits(pll->common.regmap, pll->config.cg_reg_offset,
|
||||
pll->config.cg_reg_enable,
|
||||
pll->config.cg_reg_enable);
|
||||
}
|
||||
|
||||
static void atlantis_clk_pll_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct atlantis_clk_pll *pll = hw_to_atlantis_pll(hw);
|
||||
|
||||
/* Step 1: Switch to bypass mode before disabling */
|
||||
regmap_update_bits(pll->common.regmap, pll->config.reg_offset,
|
||||
PLL_CFG_BYPASS_BIT, PLL_CFG_BYPASS_BIT);
|
||||
/* Step 2: Power down PLL */
|
||||
regmap_update_bits(pll->common.regmap, pll->config.en_reg_offset,
|
||||
PLL_CFG_EN_BIT, 0);
|
||||
}
|
||||
|
||||
static unsigned long atlantis_clk_pll_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct atlantis_clk_pll *pll = hw_to_atlantis_pll(hw);
|
||||
|
||||
u32 val, refdiv, fbdiv, postdiv1, postdiv2;
|
||||
u64 fout;
|
||||
|
||||
regmap_read(pll->common.regmap, pll->config.reg_offset, &val);
|
||||
|
||||
if (val & PLL_CFG_BYPASS_BIT)
|
||||
return parent_rate;
|
||||
|
||||
refdiv = FIELD_GET(PLL_CFG_REFDIV_MASK, val);
|
||||
fbdiv = FIELD_GET(PLL_CFG_FBDIV_MASK, val);
|
||||
postdiv1 = FIELD_GET(PLL_CFG_POSTDIV1_MASK, val);
|
||||
postdiv2 = FIELD_GET(PLL_CFG_POSTDIV2_MASK, val);
|
||||
|
||||
if (!refdiv)
|
||||
refdiv = 1;
|
||||
if (!postdiv1)
|
||||
postdiv1 = 1;
|
||||
if (!postdiv2)
|
||||
postdiv2 = 1;
|
||||
if (!fbdiv)
|
||||
return 0;
|
||||
|
||||
fout = div64_u64((u64)parent_rate * fbdiv,
|
||||
refdiv * postdiv1 * postdiv2);
|
||||
|
||||
return fout;
|
||||
}
|
||||
|
||||
static const struct clk_ops atlantis_clk_pll_ops = {
|
||||
.enable = atlantis_clk_pll_enable,
|
||||
.disable = atlantis_clk_pll_disable,
|
||||
.recalc_rate = atlantis_clk_pll_recalc_rate,
|
||||
.is_enabled = atlantis_clk_pll_is_enabled,
|
||||
};
|
||||
|
||||
static int atlantis_clk_gate_shared_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct atlantis_clk_gate_shared *gate =
|
||||
hw_to_atlantis_clk_gate_shared(hw);
|
||||
bool need_enable;
|
||||
|
||||
scoped_guard(spinlock_irqsave, gate->config.refcount_lock)
|
||||
{
|
||||
need_enable = (*gate->config.share_count)++ == 0;
|
||||
if (need_enable) {
|
||||
regmap_set_bits(gate->common.regmap,
|
||||
gate->config.reg_offset,
|
||||
gate->config.enable);
|
||||
}
|
||||
}
|
||||
|
||||
if (need_enable) {
|
||||
if (!regmap_test_bits(gate->common.regmap,
|
||||
gate->config.reg_offset,
|
||||
gate->config.enable)) {
|
||||
pr_warn("%s: gate enable %d failed to enable\n",
|
||||
clk_hw_get_name(hw), gate->config.enable);
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void atlantis_clk_gate_shared_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct atlantis_clk_gate_shared *gate =
|
||||
hw_to_atlantis_clk_gate_shared(hw);
|
||||
|
||||
scoped_guard(spinlock_irqsave, gate->config.refcount_lock)
|
||||
{
|
||||
if (WARN_ON(*gate->config.share_count == 0))
|
||||
return;
|
||||
if (--(*gate->config.share_count) > 0)
|
||||
return;
|
||||
|
||||
regmap_clear_bits(gate->common.regmap,
|
||||
gate->config.reg_offset,
|
||||
gate->config.enable);
|
||||
}
|
||||
}
|
||||
|
||||
static int atlantis_clk_gate_shared_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
struct atlantis_clk_gate_shared *gate =
|
||||
hw_to_atlantis_clk_gate_shared(hw);
|
||||
|
||||
return regmap_test_bits(gate->common.regmap, gate->config.reg_offset, gate->config.enable);
|
||||
}
|
||||
|
||||
static void atlantis_clk_gate_shared_disable_unused(struct clk_hw *hw)
|
||||
{
|
||||
struct atlantis_clk_gate_shared *gate =
|
||||
hw_to_atlantis_clk_gate_shared(hw);
|
||||
|
||||
scoped_guard(spinlock_irqsave, gate->config.refcount_lock)
|
||||
{
|
||||
if (*gate->config.share_count == 0)
|
||||
regmap_clear_bits(gate->common.regmap,
|
||||
gate->config.reg_offset,
|
||||
gate->config.enable);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct clk_ops atlantis_clk_gate_shared_ops = {
|
||||
.enable = atlantis_clk_gate_shared_enable,
|
||||
.disable = atlantis_clk_gate_shared_disable,
|
||||
.disable_unused = atlantis_clk_gate_shared_disable_unused,
|
||||
.is_enabled = atlantis_clk_gate_shared_is_enabled,
|
||||
};
|
||||
|
||||
#define ATLANTIS_PLL_CONFIG(_reg_offset, _en_reg_offset, _cg_reg_offset, \
|
||||
_cg_reg_enable) \
|
||||
{ \
|
||||
.reg_offset = (_reg_offset), \
|
||||
.en_reg_offset = (_en_reg_offset), \
|
||||
.cg_reg_offset = (_cg_reg_offset), \
|
||||
.cg_reg_enable = (_cg_reg_enable), \
|
||||
}
|
||||
|
||||
#define ATLANTIS_PLL_DEFINE(_clkid, _name, _parent, _reg_offset, \
|
||||
_en_reg_offset, _cg_reg_offset, _cg_reg_enable, \
|
||||
_flags) \
|
||||
static struct atlantis_clk_pll _name = { \
|
||||
.config = ATLANTIS_PLL_CONFIG(_reg_offset, _en_reg_offset, \
|
||||
_cg_reg_offset, _cg_reg_enable), \
|
||||
.common = { .clkid = _clkid, \
|
||||
.hw.init = CLK_HW_INIT_PARENTS_DATA( \
|
||||
#_name, _parent, &atlantis_clk_pll_ops, \
|
||||
_flags) }, \
|
||||
}
|
||||
#define ATLANTIS_MUX_CONFIG(_shift, _width, _reg_offset) \
|
||||
{ \
|
||||
.shift = _shift, .width = _width, .reg_offset = _reg_offset \
|
||||
}
|
||||
|
||||
#define ATLANTIS_MUX_DEFINE(_clkid, _name, _parents, _reg_offset, _shift, \
|
||||
_width, _flags) \
|
||||
static struct atlantis_clk_mux _name = { \
|
||||
.config = ATLANTIS_MUX_CONFIG(_shift, _width, _reg_offset), \
|
||||
.common = { .clkid = _clkid, \
|
||||
.hw.init = CLK_HW_INIT_PARENTS_DATA( \
|
||||
#_name, _parents, &atlantis_clk_mux_ops, \
|
||||
_flags) } \
|
||||
}
|
||||
|
||||
#define ATLANTIS_DIVIDER_CONFIG(_shift, _width, _flags, _reg_offset) \
|
||||
{ \
|
||||
.shift = _shift, .width = _width, .flags = _flags, \
|
||||
.reg_offset = _reg_offset \
|
||||
}
|
||||
|
||||
#define ATLANTIS_DIVIDER_DEFINE(_clkid, _name, _parent, _reg_offset, _shift, \
|
||||
_width, _divflags, _flags) \
|
||||
static struct atlantis_clk_divider _name = { \
|
||||
.config = ATLANTIS_DIVIDER_CONFIG(_shift, _width, _divflags, \
|
||||
_reg_offset), \
|
||||
.common = { .clkid = _clkid, \
|
||||
.hw.init = CLK_HW_INIT_HW( \
|
||||
#_name, &_parent.common.hw, \
|
||||
&atlantis_clk_divider_ops, _flags) } \
|
||||
}
|
||||
#define ATLANTIS_GATE_CONFIG(_enable, _reg_offset) \
|
||||
{ \
|
||||
.enable = _enable, .reg_offset = _reg_offset \
|
||||
}
|
||||
|
||||
#define ATLANTIS_GATE_DEFINE(_clkid, _name, _parent, _reg_offset, _enable, \
|
||||
_flags) \
|
||||
static struct atlantis_clk_gate _name = { \
|
||||
.config = ATLANTIS_GATE_CONFIG(_enable, _reg_offset), \
|
||||
.common = { .clkid = _clkid, \
|
||||
.hw.init = CLK_HW_INIT_HW( \
|
||||
#_name, &_parent.common.hw, \
|
||||
&atlantis_clk_gate_ops, _flags) } \
|
||||
}
|
||||
#define ATLANTIS_GATE_SHARED_CONFIG(_reg_offset, _enable, _share_count) \
|
||||
{ \
|
||||
.reg_offset = _reg_offset, .enable = _enable, \
|
||||
.share_count = _share_count, .refcount_lock = &refcount_lock \
|
||||
}
|
||||
#define ATLANTIS_GATE_SHARED_DEFINE(_clkid, _name, _parent, _reg_offset, \
|
||||
_enable, _share_count, _flags) \
|
||||
static struct atlantis_clk_gate_shared _name = { \
|
||||
.config = ATLANTIS_GATE_SHARED_CONFIG(_reg_offset, _enable, \
|
||||
_share_count), \
|
||||
.common = { .clkid = _clkid, \
|
||||
.hw.init = CLK_HW_INIT_HW( \
|
||||
#_name, &_parent.common.hw, \
|
||||
&atlantis_clk_gate_shared_ops, _flags) } \
|
||||
}
|
||||
#define ATLANTIS_FIXED_FACTOR_DEFINE(_clkid, _name, _parent, _mult, _div, \
|
||||
_flags) \
|
||||
static struct atlantis_clk_fixed_factor _name = { \
|
||||
.config = { .mult = _mult, .div = _div }, \
|
||||
.common = { .clkid = _clkid, \
|
||||
.hw.init = CLK_HW_INIT_HW( \
|
||||
#_name, &_parent.common.hw, \
|
||||
&atlantis_clk_fixed_factor_ops, _flags) } \
|
||||
}
|
||||
|
||||
static DEFINE_SPINLOCK(refcount_lock); /* Lock for refcount value accesses */
|
||||
|
||||
static const struct regmap_config atlantis_prcm_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0xFFFC,
|
||||
.cache_type = REGCACHE_NONE,
|
||||
};
|
||||
|
||||
struct atlantis_prcm_data {
|
||||
struct clk_hw **hws;
|
||||
size_t num;
|
||||
const char *reset_name;
|
||||
};
|
||||
|
||||
static const struct clk_parent_data osc_24m_clk[] = {
|
||||
{ .index = 0 },
|
||||
};
|
||||
|
||||
ATLANTIS_PLL_DEFINE(CLK_RCPU_PLL, rcpu_pll_clk, osc_24m_clk, PLL_RCPU_CFG_REG,
|
||||
PLL_RCPU_EN_REG, BUS_CG_REG, 0, /* No Gate Clk at Output */
|
||||
CLK_GET_RATE_NOCACHE | CLK_IS_CRITICAL);
|
||||
|
||||
static const struct clk_parent_data rcpu_root_parents[] = {
|
||||
{ .index = 0 },
|
||||
{ .hw = &rcpu_pll_clk.common.hw },
|
||||
};
|
||||
|
||||
ATLANTIS_MUX_DEFINE(CLK_RCPU_ROOT, rcpu_root_clk, rcpu_root_parents,
|
||||
RCPU_DIV_CFG_REG, 0, 1, CLK_SET_RATE_NO_REPARENT);
|
||||
|
||||
ATLANTIS_DIVIDER_DEFINE(CLK_RCPU_DIV2, rcpu_div2_clk, rcpu_root_clk,
|
||||
RCPU_DIV_CFG_REG, 2, 4, 0, 0);
|
||||
ATLANTIS_DIVIDER_DEFINE(CLK_RCPU_DIV4, rcpu_div4_clk, rcpu_root_clk,
|
||||
RCPU_DIV_CFG_REG, 7, 4, 0, 0);
|
||||
ATLANTIS_DIVIDER_DEFINE(CLK_RCPU_RTC, rcpu_rtc_clk, rcpu_div4_clk,
|
||||
RCPU_DIV_CFG_REG, 12, 6, 0, 0);
|
||||
|
||||
ATLANTIS_GATE_DEFINE(CLK_SMNDMA0_ACLK, rcpu_dma0_clk, rcpu_div2_clk,
|
||||
RCPU_BLK_CG_REG, BIT(0), 0);
|
||||
ATLANTIS_GATE_DEFINE(CLK_SMNDMA1_ACLK, rcpu_dma1_clk, rcpu_div2_clk,
|
||||
RCPU_BLK_CG_REG, BIT(1), 0);
|
||||
ATLANTIS_GATE_DEFINE(CLK_WDT0_PCLK, sl_wdt0_pclk, rcpu_div4_clk,
|
||||
RCPU_BLK_CG_REG, BIT(2), 0);
|
||||
ATLANTIS_GATE_DEFINE(CLK_WDT1_PCLK, sl_wdt1_pclk, rcpu_div4_clk,
|
||||
RCPU_BLK_CG_REG, BIT(3), 0);
|
||||
ATLANTIS_GATE_DEFINE(CLK_TIMER_PCLK, sl_timer_pclk, rcpu_div4_clk,
|
||||
RCPU_BLK_CG_REG, BIT(4), 0);
|
||||
ATLANTIS_GATE_DEFINE(CLK_PVTC_PCLK, sl_pvtc_pclk, rcpu_div4_clk,
|
||||
RCPU_BLK_CG_REG, BIT(12), 0);
|
||||
ATLANTIS_GATE_DEFINE(CLK_PMU_PCLK, sl_pmu_pclk, rcpu_div4_clk, RCPU_BLK_CG_REG,
|
||||
BIT(13), 0);
|
||||
ATLANTIS_GATE_DEFINE(CLK_MAILBOX_HCLK, rcpu_ipc_clk, rcpu_div2_clk,
|
||||
RCPU_BLK_CG_REG, BIT(14), 0);
|
||||
ATLANTIS_GATE_DEFINE(CLK_SEC_SPACC_HCLK, sec_spacc_hclk, rcpu_div2_clk,
|
||||
RCPU_BLK_CG_REG, BIT(26), 0);
|
||||
ATLANTIS_GATE_DEFINE(CLK_SEC_OTP_HCLK, sec_otp_hclk, rcpu_div2_clk,
|
||||
RCPU_BLK_CG_REG, BIT(28), 0);
|
||||
ATLANTIS_GATE_DEFINE(CLK_TRNG_PCLK, sec_trng_pclk, rcpu_div4_clk,
|
||||
RCPU_BLK_CG_REG, BIT(29), 0);
|
||||
ATLANTIS_GATE_DEFINE(CLK_SEC_CRC_HCLK, sec_crc_hclk, rcpu_div2_clk,
|
||||
RCPU_BLK_CG_REG, BIT(30), 0);
|
||||
|
||||
ATLANTIS_FIXED_FACTOR_DEFINE(CLK_SMN_HCLK, rcpu_smn_hclk, rcpu_div2_clk, 1, 1,
|
||||
0);
|
||||
ATLANTIS_FIXED_FACTOR_DEFINE(CLK_AHB0_HCLK, rcpu_ahb0_hclk, rcpu_div2_clk, 1, 1,
|
||||
0);
|
||||
|
||||
ATLANTIS_FIXED_FACTOR_DEFINE(CLK_SMN_PCLK, rcpu_smn_pclk, rcpu_div4_clk, 1, 1,
|
||||
0);
|
||||
|
||||
ATLANTIS_FIXED_FACTOR_DEFINE(CLK_SMN_CLK, rcpu_smn_clk, rcpu_root_clk, 1, 1, 0);
|
||||
ATLANTIS_FIXED_FACTOR_DEFINE(CLK_SCRATCHPAD_CLK, rcpu_scratchpad_aclk,
|
||||
rcpu_root_clk, 1, 1, 0);
|
||||
ATLANTIS_FIXED_FACTOR_DEFINE(CLK_RCPU_CORE_CLK, rcpu_core_clk, rcpu_root_clk, 1,
|
||||
1, 0);
|
||||
ATLANTIS_FIXED_FACTOR_DEFINE(CLK_RCPU_ROM_CLK, rcpu_rom_aclk, rcpu_root_clk, 1,
|
||||
1, 0);
|
||||
|
||||
static struct atlantis_clk_fixed_factor
|
||||
otp_load_clk = { .config = { .mult = 1, .div = 1 },
|
||||
.common = {
|
||||
.clkid = CLK_OTP_LOAD_CLK,
|
||||
.hw.init = CLK_HW_INIT_PARENTS_DATA(
|
||||
"otp_load_clk", osc_24m_clk,
|
||||
&atlantis_clk_fixed_factor_ops,
|
||||
CLK_SET_RATE_NO_REPARENT),
|
||||
} };
|
||||
|
||||
ATLANTIS_PLL_DEFINE(CLK_NOC_PLL, nocc_pll_clk, osc_24m_clk, PLL_NOCC_CFG_REG,
|
||||
PLL_NOCC_EN_REG, BUS_CG_REG, BIT(0),
|
||||
CLK_GET_RATE_NOCACHE | CLK_IS_CRITICAL);
|
||||
|
||||
static const struct clk_parent_data nocc_mux_parents[] = {
|
||||
{ .index = 0 },
|
||||
{ .hw = &nocc_pll_clk.common.hw },
|
||||
};
|
||||
|
||||
ATLANTIS_MUX_DEFINE(CLK_NOCC_CLK, nocc_clk, nocc_mux_parents, NOCC_CLK_CFG_REG,
|
||||
0, 1, CLK_SET_RATE_NO_REPARENT);
|
||||
|
||||
ATLANTIS_DIVIDER_DEFINE(CLK_NOCC_DIV2, nocc_div2_clk, nocc_clk,
|
||||
NOCC_CLK_CFG_REG, 1, 4, 0, 0);
|
||||
ATLANTIS_DIVIDER_DEFINE(CLK_NOCC_DIV4, nocc_div4_clk, nocc_clk,
|
||||
NOCC_CLK_CFG_REG, 5, 4, 0, 0);
|
||||
ATLANTIS_DIVIDER_DEFINE(CLK_NOCC_RTC, nocc_rtc_clk, nocc_div4_clk,
|
||||
NOCC_CLK_CFG_REG, 9, 6, 0, 0);
|
||||
ATLANTIS_DIVIDER_DEFINE(CLK_NOCC_CAN, nocc_can_clk, nocc_clk, NOCC_CLK_CFG_REG,
|
||||
15, 4, 0, 0);
|
||||
|
||||
static unsigned int refcnt_qspi;
|
||||
ATLANTIS_GATE_SHARED_DEFINE(CLK_QSPI_SCLK, lsio_qspi_sclk, nocc_clk,
|
||||
LSIO_BLK_CG_REG, BIT(0), &refcnt_qspi, 0);
|
||||
ATLANTIS_GATE_SHARED_DEFINE(CLK_QSPI_HCLK, lsio_qspi_hclk, nocc_div2_clk,
|
||||
LSIO_BLK_CG_REG, BIT(0), &refcnt_qspi, 0);
|
||||
ATLANTIS_GATE_DEFINE(CLK_I2C0_PCLK, lsio_i2c0_pclk, nocc_div4_clk,
|
||||
LSIO_BLK_CG_REG, BIT(1), 0);
|
||||
ATLANTIS_GATE_DEFINE(CLK_I2C1_PCLK, lsio_i2c1_pclk, nocc_div4_clk,
|
||||
LSIO_BLK_CG_REG, BIT(2), 0);
|
||||
ATLANTIS_GATE_DEFINE(CLK_I2C2_PCLK, lsio_i2c2_pclk, nocc_div4_clk,
|
||||
LSIO_BLK_CG_REG, BIT(3), 0);
|
||||
ATLANTIS_GATE_DEFINE(CLK_I2C3_PCLK, lsio_i2c3_pclk, nocc_div4_clk,
|
||||
LSIO_BLK_CG_REG, BIT(4), 0);
|
||||
ATLANTIS_GATE_DEFINE(CLK_I2C4_PCLK, lsio_i2c4_pclk, nocc_div4_clk,
|
||||
LSIO_BLK_CG_REG, BIT(5), 0);
|
||||
|
||||
ATLANTIS_GATE_DEFINE(CLK_UART0_PCLK, lsio_uart0_pclk, nocc_div4_clk,
|
||||
LSIO_BLK_CG_REG, BIT(6), 0);
|
||||
ATLANTIS_GATE_DEFINE(CLK_UART1_PCLK, lsio_uart1_pclk, nocc_div4_clk,
|
||||
LSIO_BLK_CG_REG, BIT(7), 0);
|
||||
ATLANTIS_GATE_DEFINE(CLK_UART2_PCLK, lsio_uart2_pclk, nocc_div4_clk,
|
||||
LSIO_BLK_CG_REG, BIT(8), 0);
|
||||
ATLANTIS_GATE_DEFINE(CLK_UART3_PCLK, lsio_uart3_pclk, nocc_div4_clk,
|
||||
LSIO_BLK_CG_REG, BIT(9), 0);
|
||||
ATLANTIS_GATE_DEFINE(CLK_UART4_PCLK, lsio_uart4_pclk, nocc_div4_clk,
|
||||
LSIO_BLK_CG_REG, BIT(10), 0);
|
||||
ATLANTIS_GATE_DEFINE(CLK_SPI0_PCLK, lsio_spi0_pclk, nocc_div4_clk,
|
||||
LSIO_BLK_CG_REG, BIT(11), 0);
|
||||
ATLANTIS_GATE_DEFINE(CLK_SPI1_PCLK, lsio_spi1_pclk, nocc_div4_clk,
|
||||
LSIO_BLK_CG_REG, BIT(12), 0);
|
||||
ATLANTIS_GATE_DEFINE(CLK_SPI2_PCLK, lsio_spi2_pclk, nocc_div4_clk,
|
||||
LSIO_BLK_CG_REG, BIT(13), 0);
|
||||
ATLANTIS_GATE_DEFINE(CLK_SPI3_PCLK, lsio_spi3_pclk, nocc_div4_clk,
|
||||
LSIO_BLK_CG_REG, BIT(14), 0);
|
||||
ATLANTIS_GATE_DEFINE(CLK_GPIO_PCLK, lsio_gpio_pclk, nocc_div4_clk,
|
||||
LSIO_BLK_CG_REG, BIT(15), 0);
|
||||
|
||||
static unsigned int refcnt_can0;
|
||||
ATLANTIS_GATE_SHARED_DEFINE(CLK_CAN0_HCLK, lsio_can0_hclk, nocc_div2_clk,
|
||||
LSIO_BLK_CG_REG, BIT(17), &refcnt_can0, 0);
|
||||
ATLANTIS_GATE_SHARED_DEFINE(CLK_CAN0_CLK, lsio_can0_clk, nocc_can_clk,
|
||||
LSIO_BLK_CG_REG, BIT(17), &refcnt_can0, 0);
|
||||
|
||||
static unsigned int refcnt_can1;
|
||||
ATLANTIS_GATE_SHARED_DEFINE(CLK_CAN1_HCLK, lsio_can1_hclk, nocc_div2_clk,
|
||||
LSIO_BLK_CG_REG, BIT(18), &refcnt_can1, 0);
|
||||
ATLANTIS_GATE_SHARED_DEFINE(CLK_CAN1_CLK, lsio_can1_clk, nocc_can_clk,
|
||||
LSIO_BLK_CG_REG, BIT(18), &refcnt_can1, 0);
|
||||
|
||||
ATLANTIS_FIXED_FACTOR_DEFINE(CLK_CAN0_TIMER_CLK, lsio_can0_timer_clk,
|
||||
nocc_rtc_clk, 1, 1, 0);
|
||||
ATLANTIS_FIXED_FACTOR_DEFINE(CLK_CAN1_TIMER_CLK, lsio_can1_timer_clk,
|
||||
nocc_rtc_clk, 1, 1, 0);
|
||||
|
||||
static struct clk_hw *atlantis_rcpu_clks[] = {
|
||||
[CLK_RCPU_PLL] = &rcpu_pll_clk.common.hw,
|
||||
[CLK_RCPU_ROOT] = &rcpu_root_clk.common.hw,
|
||||
[CLK_RCPU_DIV2] = &rcpu_div2_clk.common.hw,
|
||||
[CLK_RCPU_DIV4] = &rcpu_div4_clk.common.hw,
|
||||
[CLK_RCPU_RTC] = &rcpu_rtc_clk.common.hw,
|
||||
[CLK_SMNDMA0_ACLK] = &rcpu_dma0_clk.common.hw,
|
||||
[CLK_SMNDMA1_ACLK] = &rcpu_dma1_clk.common.hw,
|
||||
[CLK_WDT0_PCLK] = &sl_wdt0_pclk.common.hw,
|
||||
[CLK_WDT1_PCLK] = &sl_wdt1_pclk.common.hw,
|
||||
[CLK_TIMER_PCLK] = &sl_timer_pclk.common.hw,
|
||||
[CLK_PVTC_PCLK] = &sl_pvtc_pclk.common.hw,
|
||||
[CLK_PMU_PCLK] = &sl_pmu_pclk.common.hw,
|
||||
[CLK_MAILBOX_HCLK] = &rcpu_ipc_clk.common.hw,
|
||||
[CLK_SEC_SPACC_HCLK] = &sec_spacc_hclk.common.hw,
|
||||
[CLK_SEC_OTP_HCLK] = &sec_otp_hclk.common.hw,
|
||||
[CLK_TRNG_PCLK] = &sec_trng_pclk.common.hw,
|
||||
[CLK_SEC_CRC_HCLK] = &sec_crc_hclk.common.hw,
|
||||
[CLK_SMN_HCLK] = &rcpu_smn_hclk.common.hw,
|
||||
[CLK_AHB0_HCLK] = &rcpu_ahb0_hclk.common.hw,
|
||||
[CLK_SMN_PCLK] = &rcpu_smn_pclk.common.hw,
|
||||
[CLK_SMN_CLK] = &rcpu_smn_clk.common.hw,
|
||||
[CLK_SCRATCHPAD_CLK] = &rcpu_scratchpad_aclk.common.hw,
|
||||
[CLK_RCPU_CORE_CLK] = &rcpu_core_clk.common.hw,
|
||||
[CLK_RCPU_ROM_CLK] = &rcpu_rom_aclk.common.hw,
|
||||
[CLK_OTP_LOAD_CLK] = &otp_load_clk.common.hw,
|
||||
[CLK_NOC_PLL] = &nocc_pll_clk.common.hw,
|
||||
[CLK_NOCC_CLK] = &nocc_clk.common.hw,
|
||||
[CLK_NOCC_DIV2] = &nocc_div2_clk.common.hw,
|
||||
[CLK_NOCC_DIV4] = &nocc_div4_clk.common.hw,
|
||||
[CLK_NOCC_RTC] = &nocc_rtc_clk.common.hw,
|
||||
[CLK_NOCC_CAN] = &nocc_can_clk.common.hw,
|
||||
[CLK_QSPI_SCLK] = &lsio_qspi_sclk.common.hw,
|
||||
[CLK_QSPI_HCLK] = &lsio_qspi_hclk.common.hw,
|
||||
[CLK_I2C0_PCLK] = &lsio_i2c0_pclk.common.hw,
|
||||
[CLK_I2C1_PCLK] = &lsio_i2c1_pclk.common.hw,
|
||||
[CLK_I2C2_PCLK] = &lsio_i2c2_pclk.common.hw,
|
||||
[CLK_I2C3_PCLK] = &lsio_i2c3_pclk.common.hw,
|
||||
[CLK_I2C4_PCLK] = &lsio_i2c4_pclk.common.hw,
|
||||
[CLK_UART0_PCLK] = &lsio_uart0_pclk.common.hw,
|
||||
[CLK_UART1_PCLK] = &lsio_uart1_pclk.common.hw,
|
||||
[CLK_UART2_PCLK] = &lsio_uart2_pclk.common.hw,
|
||||
[CLK_UART3_PCLK] = &lsio_uart3_pclk.common.hw,
|
||||
[CLK_UART4_PCLK] = &lsio_uart4_pclk.common.hw,
|
||||
[CLK_SPI0_PCLK] = &lsio_spi0_pclk.common.hw,
|
||||
[CLK_SPI1_PCLK] = &lsio_spi1_pclk.common.hw,
|
||||
[CLK_SPI2_PCLK] = &lsio_spi2_pclk.common.hw,
|
||||
[CLK_SPI3_PCLK] = &lsio_spi3_pclk.common.hw,
|
||||
[CLK_GPIO_PCLK] = &lsio_gpio_pclk.common.hw,
|
||||
[CLK_CAN0_HCLK] = &lsio_can0_hclk.common.hw,
|
||||
[CLK_CAN0_CLK] = &lsio_can0_clk.common.hw,
|
||||
[CLK_CAN1_HCLK] = &lsio_can1_hclk.common.hw,
|
||||
[CLK_CAN1_CLK] = &lsio_can1_clk.common.hw,
|
||||
[CLK_CAN0_TIMER_CLK] = &lsio_can0_timer_clk.common.hw,
|
||||
[CLK_CAN1_TIMER_CLK] = &lsio_can1_timer_clk.common.hw,
|
||||
};
|
||||
|
||||
static const struct atlantis_prcm_data atlantis_prcm_rcpu_data = {
|
||||
.hws = atlantis_rcpu_clks,
|
||||
.num = ARRAY_SIZE(atlantis_rcpu_clks),
|
||||
.reset_name = "rcpu-reset"
|
||||
};
|
||||
|
||||
static int atlantis_prcm_clocks_register(struct device *dev,
|
||||
struct regmap *regmap,
|
||||
const struct atlantis_prcm_data *data)
|
||||
{
|
||||
struct clk_hw_onecell_data *clk_data;
|
||||
int i, ret;
|
||||
size_t num_clks = data->num;
|
||||
|
||||
clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, data->num),
|
||||
GFP_KERNEL);
|
||||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < data->num; i++) {
|
||||
struct clk_hw *hw = data->hws[i];
|
||||
struct atlantis_clk_common *common =
|
||||
hw_to_atlantis_clk_common(hw);
|
||||
common->regmap = regmap;
|
||||
|
||||
ret = devm_clk_hw_register(dev, hw);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
clk_data->hws[common->clkid] = hw;
|
||||
}
|
||||
|
||||
clk_data->num = num_clks;
|
||||
|
||||
return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
|
||||
}
|
||||
|
||||
static int atlantis_prcm_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct atlantis_prcm_data *data;
|
||||
struct auxiliary_device *reset_adev;
|
||||
struct regmap *regmap;
|
||||
void __iomem *base;
|
||||
struct device *dev = &pdev->dev;
|
||||
int ret;
|
||||
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(base))
|
||||
return dev_err_probe(dev, PTR_ERR(base),
|
||||
"Failed to map registers\n");
|
||||
|
||||
regmap = devm_regmap_init_mmio(dev, base, &atlantis_prcm_regmap_config);
|
||||
if (IS_ERR(regmap))
|
||||
return dev_err_probe(dev, PTR_ERR(regmap),
|
||||
"Failed to init regmap\n");
|
||||
|
||||
data = of_device_get_match_data(dev);
|
||||
|
||||
ret = atlantis_prcm_clocks_register(dev, regmap, data);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to register clocks\n");
|
||||
|
||||
reset_adev = devm_auxiliary_device_create(dev, data->reset_name, NULL);
|
||||
if (!reset_adev)
|
||||
return dev_err_probe(dev, -ENODEV, "failed to register resets\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id atlantis_prcm_of_match[] = {
|
||||
{
|
||||
.compatible = "tenstorrent,atlantis-prcm-rcpu",
|
||||
.data = &atlantis_prcm_rcpu_data,
|
||||
},
|
||||
{}
|
||||
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, atlantis_prcm_of_match);
|
||||
|
||||
static struct platform_driver atlantis_prcm_driver = {
|
||||
.probe = atlantis_prcm_probe,
|
||||
.driver = {
|
||||
.name = "atlantis-prcm",
|
||||
.of_match_table = atlantis_prcm_of_match,
|
||||
},
|
||||
};
|
||||
module_platform_driver(atlantis_prcm_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Tenstorrent Atlantis PRCM Clock Controller Driver");
|
||||
MODULE_AUTHOR("Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -315,6 +315,17 @@ config RESET_SUNXI
|
|||
help
|
||||
This enables the reset driver for Allwinner SoCs.
|
||||
|
||||
config RESET_TENSTORRENT_ATLANTIS
|
||||
tristate "Tenstorrent atlantis reset driver"
|
||||
depends on ARCH_TENSTORRENT || COMPILE_TEST
|
||||
select AUXILIARY_BUS
|
||||
default ARCH_TENSTORRENT
|
||||
help
|
||||
This enables the driver for the reset controller
|
||||
present in the Tenstorrent Atlantis SoC.
|
||||
Enable this option to be able to use hardware
|
||||
resets on Atalantis based systems.
|
||||
|
||||
config RESET_TH1520
|
||||
tristate "T-HEAD TH1520 reset controller"
|
||||
depends on ARCH_THEAD || COMPILE_TEST
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
|
|||
obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
|
||||
obj-$(CONFIG_RESET_SUNPLUS) += reset-sunplus.o
|
||||
obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
|
||||
obj-$(CONFIG_RESET_TENSTORRENT_ATLANTIS) += reset-tenstorrent-atlantis.o
|
||||
obj-$(CONFIG_RESET_TH1520) += reset-th1520.o
|
||||
obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o
|
||||
obj-$(CONFIG_RESET_TI_SYSCON) += reset-ti-syscon.o
|
||||
|
|
|
|||
173
drivers/reset/reset-tenstorrent-atlantis.c
Normal file
173
drivers/reset/reset-tenstorrent-atlantis.c
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Tenstorrent Atlantis PRCM Reset Driver
|
||||
*
|
||||
* Copyright (c) 2026 Tenstorrent
|
||||
*/
|
||||
|
||||
#include <dt-bindings/clock/tenstorrent,atlantis-prcm-rcpu.h>
|
||||
#include <linux/auxiliary_bus.h>
|
||||
#include <linux/reset-controller.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
/* RCPU Reset Register Offsets */
|
||||
#define RCPU_BLK_RST_REG 0x001c
|
||||
#define LSIO_BLK_RST_REG 0x0020
|
||||
#define HSIO_BLK_RST_REG 0x000c
|
||||
#define PCIE_SUBS_RST_REG 0x0000
|
||||
#define MM_RSTN_REG 0x0014
|
||||
|
||||
struct atlantis_reset_data {
|
||||
u8 bit;
|
||||
u16 reg;
|
||||
bool active_low;
|
||||
};
|
||||
|
||||
struct atlantis_reset_controller_data {
|
||||
const struct atlantis_reset_data *reset_data;
|
||||
size_t count;
|
||||
};
|
||||
|
||||
struct atlantis_reset_controller {
|
||||
struct reset_controller_dev rcdev;
|
||||
const struct atlantis_reset_controller_data *data;
|
||||
struct regmap *regmap;
|
||||
};
|
||||
|
||||
static inline struct atlantis_reset_controller *
|
||||
to_atlantis_reset_controller(struct reset_controller_dev *rcdev)
|
||||
{
|
||||
return container_of(rcdev, struct atlantis_reset_controller, rcdev);
|
||||
}
|
||||
|
||||
#define RESET_DATA(_reg, _bit, _active_low) \
|
||||
{ \
|
||||
.bit = _bit, .reg = _reg, .active_low = _active_low, \
|
||||
}
|
||||
|
||||
static const struct atlantis_reset_data atlantis_rcpu_resets[] = {
|
||||
[RST_SMNDMA0] = RESET_DATA(RCPU_BLK_RST_REG, 0, true),
|
||||
[RST_SMNDMA1] = RESET_DATA(RCPU_BLK_RST_REG, 1, true),
|
||||
[RST_WDT0] = RESET_DATA(RCPU_BLK_RST_REG, 2, true),
|
||||
[RST_WDT1] = RESET_DATA(RCPU_BLK_RST_REG, 3, true),
|
||||
[RST_TMR] = RESET_DATA(RCPU_BLK_RST_REG, 4, true),
|
||||
[RST_PVTC] = RESET_DATA(RCPU_BLK_RST_REG, 12, true),
|
||||
[RST_PMU] = RESET_DATA(RCPU_BLK_RST_REG, 13, true),
|
||||
[RST_MAILBOX] = RESET_DATA(RCPU_BLK_RST_REG, 14, true),
|
||||
[RST_SPACC] = RESET_DATA(RCPU_BLK_RST_REG, 26, true),
|
||||
[RST_OTP] = RESET_DATA(RCPU_BLK_RST_REG, 28, true),
|
||||
[RST_TRNG] = RESET_DATA(RCPU_BLK_RST_REG, 29, true),
|
||||
[RST_CRC] = RESET_DATA(RCPU_BLK_RST_REG, 30, true),
|
||||
[RST_QSPI] = RESET_DATA(LSIO_BLK_RST_REG, 0, true),
|
||||
[RST_I2C0] = RESET_DATA(LSIO_BLK_RST_REG, 1, true),
|
||||
[RST_I2C1] = RESET_DATA(LSIO_BLK_RST_REG, 2, true),
|
||||
[RST_I2C2] = RESET_DATA(LSIO_BLK_RST_REG, 3, true),
|
||||
[RST_I2C3] = RESET_DATA(LSIO_BLK_RST_REG, 4, true),
|
||||
[RST_I2C4] = RESET_DATA(LSIO_BLK_RST_REG, 5, true),
|
||||
[RST_UART0] = RESET_DATA(LSIO_BLK_RST_REG, 6, true),
|
||||
[RST_UART1] = RESET_DATA(LSIO_BLK_RST_REG, 7, true),
|
||||
[RST_UART2] = RESET_DATA(LSIO_BLK_RST_REG, 8, true),
|
||||
[RST_UART3] = RESET_DATA(LSIO_BLK_RST_REG, 9, true),
|
||||
[RST_UART4] = RESET_DATA(LSIO_BLK_RST_REG, 10, true),
|
||||
[RST_SPI0] = RESET_DATA(LSIO_BLK_RST_REG, 11, true),
|
||||
[RST_SPI1] = RESET_DATA(LSIO_BLK_RST_REG, 12, true),
|
||||
[RST_SPI2] = RESET_DATA(LSIO_BLK_RST_REG, 13, true),
|
||||
[RST_SPI3] = RESET_DATA(LSIO_BLK_RST_REG, 14, true),
|
||||
[RST_GPIO] = RESET_DATA(LSIO_BLK_RST_REG, 15, true),
|
||||
[RST_CAN0] = RESET_DATA(LSIO_BLK_RST_REG, 17, true),
|
||||
[RST_CAN1] = RESET_DATA(LSIO_BLK_RST_REG, 18, true),
|
||||
[RST_I2S0] = RESET_DATA(LSIO_BLK_RST_REG, 19, true),
|
||||
[RST_I2S1] = RESET_DATA(LSIO_BLK_RST_REG, 20, true),
|
||||
|
||||
};
|
||||
|
||||
static const struct atlantis_reset_controller_data atlantis_rcpu_reset_data = {
|
||||
.reset_data = atlantis_rcpu_resets,
|
||||
.count = ARRAY_SIZE(atlantis_rcpu_resets),
|
||||
};
|
||||
|
||||
static int atlantis_reset_update(struct reset_controller_dev *rcdev,
|
||||
unsigned long id, bool assert)
|
||||
{
|
||||
unsigned int val;
|
||||
struct atlantis_reset_controller *rst =
|
||||
to_atlantis_reset_controller(rcdev);
|
||||
const struct atlantis_reset_data *data = &rst->data->reset_data[id];
|
||||
unsigned int mask = BIT(data->bit);
|
||||
struct regmap *regmap = rst->regmap;
|
||||
|
||||
if (data->active_low ^ assert)
|
||||
val = mask;
|
||||
else
|
||||
val = 0;
|
||||
|
||||
return regmap_update_bits(regmap, data->reg, mask, val);
|
||||
}
|
||||
|
||||
static int atlantis_reset_assert(struct reset_controller_dev *rcdev,
|
||||
unsigned long id)
|
||||
{
|
||||
return atlantis_reset_update(rcdev, id, true);
|
||||
}
|
||||
|
||||
static int atlantis_reset_deassert(struct reset_controller_dev *rcdev,
|
||||
unsigned long id)
|
||||
{
|
||||
return atlantis_reset_update(rcdev, id, false);
|
||||
}
|
||||
|
||||
static const struct reset_control_ops atlantis_reset_control_ops = {
|
||||
.assert = atlantis_reset_assert,
|
||||
.deassert = atlantis_reset_deassert,
|
||||
};
|
||||
|
||||
static int
|
||||
atlantis_reset_controller_register(struct device *dev,
|
||||
struct atlantis_reset_controller *controller)
|
||||
{
|
||||
struct reset_controller_dev *rcdev = &controller->rcdev;
|
||||
|
||||
rcdev->ops = &atlantis_reset_control_ops;
|
||||
rcdev->owner = THIS_MODULE;
|
||||
rcdev->of_node = dev->of_node;
|
||||
rcdev->nr_resets = controller->data->count;
|
||||
|
||||
return devm_reset_controller_register(dev, &controller->rcdev);
|
||||
}
|
||||
static int atlantis_reset_probe(struct auxiliary_device *adev,
|
||||
const struct auxiliary_device_id *id)
|
||||
{
|
||||
struct atlantis_reset_controller *controller;
|
||||
struct device *dev = &adev->dev;
|
||||
struct regmap *regmap;
|
||||
|
||||
regmap = dev_get_regmap(dev->parent, NULL);
|
||||
if (!regmap)
|
||||
return -ENODEV;
|
||||
|
||||
controller = devm_kzalloc(dev, sizeof(*controller), GFP_KERNEL);
|
||||
if (!controller)
|
||||
return -ENOMEM;
|
||||
controller->data =
|
||||
(const struct atlantis_reset_controller_data *)id->driver_data;
|
||||
controller->regmap = regmap;
|
||||
|
||||
return atlantis_reset_controller_register(dev, controller);
|
||||
}
|
||||
|
||||
static const struct auxiliary_device_id atlantis_reset_ids[] = {
|
||||
{ .name = "atlantis_prcm.rcpu-reset",
|
||||
.driver_data = (kernel_ulong_t)&atlantis_rcpu_reset_data },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(auxiliary, atlantis_reset_ids);
|
||||
|
||||
static struct auxiliary_driver atlantis_reset_driver = {
|
||||
.probe = atlantis_reset_probe,
|
||||
.id_table = atlantis_reset_ids,
|
||||
};
|
||||
module_auxiliary_driver(atlantis_reset_driver);
|
||||
|
||||
MODULE_AUTHOR("Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>");
|
||||
MODULE_DESCRIPTION("Atlantis PRCM reset controller driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
220
include/dt-bindings/clock/rockchip,rv1103b-cru.h
Normal file
220
include/dt-bindings/clock/rockchip,rv1103b-cru.h
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
|
||||
/*
|
||||
* Copyright (c) 2024 Rockchip Electronics Co. Ltd.
|
||||
* Author: Elaine Zhang <zhangqing@rock-chips.com>
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RV1103B_H
|
||||
#define _DT_BINDINGS_CLK_ROCKCHIP_RV1103B_H
|
||||
|
||||
#define PLL_GPLL 0
|
||||
#define ARMCLK 1
|
||||
#define PLL_DPLL 2
|
||||
#define XIN_OSC0_HALF 3
|
||||
#define CLK_GPLL_DIV24 4
|
||||
#define CLK_GPLL_DIV12 5
|
||||
#define CLK_GPLL_DIV6 6
|
||||
#define CLK_GPLL_DIV4 7
|
||||
#define CLK_GPLL_DIV3 8
|
||||
#define CLK_GPLL_DIV2P5 9
|
||||
#define CLK_GPLL_DIV2 10
|
||||
#define CLK_UART0_SRC 11
|
||||
#define CLK_UART1_SRC 12
|
||||
#define CLK_UART2_SRC 13
|
||||
#define CLK_UART0_FRAC 14
|
||||
#define CLK_UART1_FRAC 15
|
||||
#define CLK_UART2_FRAC 16
|
||||
#define CLK_SAI_SRC 17
|
||||
#define CLK_SAI_FRAC 18
|
||||
#define LSCLK_NPU_SRC 19
|
||||
#define CLK_NPU_SRC 20
|
||||
#define ACLK_VEPU_SRC 21
|
||||
#define CLK_VEPU_SRC 22
|
||||
#define ACLK_VI_SRC 23
|
||||
#define CLK_ISP_SRC 24
|
||||
#define DCLK_VICAP 25
|
||||
#define CCLK_EMMC 26
|
||||
#define CCLK_SDMMC0 27
|
||||
#define SCLK_SFC_2X 28
|
||||
#define LSCLK_PERI_SRC 29
|
||||
#define ACLK_PERI_SRC 30
|
||||
#define HCLK_HPMCU 31
|
||||
#define SCLK_UART0 32
|
||||
#define SCLK_UART1 33
|
||||
#define SCLK_UART2 34
|
||||
#define CLK_I2C_PMU 35
|
||||
#define CLK_I2C_PERI 36
|
||||
#define CLK_SPI0 37
|
||||
#define CLK_PWM0_SRC 38
|
||||
#define CLK_PWM1 39
|
||||
#define CLK_PWM2 40
|
||||
#define DCLK_DECOM_SRC 41
|
||||
#define CCLK_SDMMC1 42
|
||||
#define CLK_CORE_CRYPTO 43
|
||||
#define CLK_PKA_CRYPTO 44
|
||||
#define CLK_CORE_RGA 45
|
||||
#define MCLK_SAI_SRC 46
|
||||
#define CLK_FREQ_PWM0_SRC 47
|
||||
#define CLK_COUNTER_PWM0_SRC 48
|
||||
#define PCLK_TOP_ROOT 49
|
||||
#define CLK_REF_MIPI0 50
|
||||
#define CLK_MIPI0_OUT2IO 51
|
||||
#define CLK_REF_MIPI1 52
|
||||
#define CLK_MIPI1_OUT2IO 53
|
||||
#define MCLK_SAI_OUT2IO 54
|
||||
#define ACLK_NPU_ROOT 55
|
||||
#define HCLK_RKNN 56
|
||||
#define ACLK_RKNN 57
|
||||
#define LSCLK_VEPU_ROOT 58
|
||||
#define HCLK_VEPU 59
|
||||
#define ACLK_VEPU 60
|
||||
#define CLK_CORE_VEPU 61
|
||||
#define PCLK_IOC_VCCIO3 62
|
||||
#define PCLK_ACODEC 63
|
||||
#define PCLK_USBPHY 64
|
||||
#define LSCLK_VI_100M 65
|
||||
#define LSCLK_VI_ROOT 66
|
||||
#define HCLK_ISP 67
|
||||
#define ACLK_ISP 68
|
||||
#define CLK_CORE_ISP 69
|
||||
#define ACLK_VICAP 70
|
||||
#define HCLK_VICAP 71
|
||||
#define ISP0CLK_VICAP 72
|
||||
#define PCLK_CSI2HOST0 73
|
||||
#define PCLK_CSI2HOST1 74
|
||||
#define HCLK_EMMC 75
|
||||
#define HCLK_SFC 76
|
||||
#define HCLK_SFC_XIP 77
|
||||
#define HCLK_SDMMC0 78
|
||||
#define PCLK_CSIPHY 79
|
||||
#define PCLK_GPIO1 80
|
||||
#define DBCLK_GPIO1 81
|
||||
#define PCLK_IOC_VCCIO47 82
|
||||
#define LSCLK_DDR_ROOT 83
|
||||
#define CLK_TIMER_DDRMON 84
|
||||
#define LSCLK_PMU_ROOT 85
|
||||
#define PCLK_PMU 86
|
||||
#define XIN_RC_DIV 87
|
||||
#define CLK_32K 88
|
||||
#define PCLK_PMU_GPIO0 89
|
||||
#define DBCLK_PMU_GPIO0 90
|
||||
#define CLK_DDR_FAIL_SAFE 91
|
||||
#define PCLK_PMU_HP_TIMER 92
|
||||
#define CLK_PMU_32K_HP_TIMER 93
|
||||
#define PCLK_PWM0 94
|
||||
#define CLK_PWM0 95
|
||||
#define CLK_OSC_PWM0 96
|
||||
#define CLK_RC_PWM0 97
|
||||
#define CLK_FREQ_PWM0 98
|
||||
#define CLK_COUNTER_PWM0 99
|
||||
#define PCLK_I2C0 100
|
||||
#define CLK_I2C0 101
|
||||
#define PCLK_UART0 102
|
||||
#define PCLK_IOC_PMUIO0 103
|
||||
#define CLK_REFOUT 104
|
||||
#define CLK_PREROLL 105
|
||||
#define CLK_PREROLL_32K 106
|
||||
#define CLK_LPMCU_PMU 107
|
||||
#define PCLK_SPI2AHB 108
|
||||
#define HCLK_SPI2AHB 109
|
||||
#define SCLK_SPI2AHB 110
|
||||
#define PCLK_WDT_LPMCU 111
|
||||
#define TCLK_WDT_LPMCU 112
|
||||
#define HCLK_SFC_PMU1 113
|
||||
#define HCLK_SFC_XIP_PMU1 114
|
||||
#define SCLK_SFC_2X_PMU1 115
|
||||
#define CLK_LPMCU 116
|
||||
#define CLK_LPMCU_RTC 117
|
||||
#define PCLK_LPMCU_MAILBOX 118
|
||||
#define PCLK_IOC_PMUIO1 119
|
||||
#define PCLK_CRU_PMU1 120
|
||||
#define PCLK_PERI_ROOT 121
|
||||
#define PCLK_RTC_ROOT 122
|
||||
#define CLK_TIMER_ROOT 123
|
||||
#define PCLK_TIMER 124
|
||||
#define CLK_TIMER0 125
|
||||
#define CLK_TIMER1 126
|
||||
#define CLK_TIMER2 127
|
||||
#define CLK_TIMER3 128
|
||||
#define CLK_TIMER4 129
|
||||
#define CLK_TIMER5 130
|
||||
#define PCLK_STIMER 131
|
||||
#define CLK_STIMER0 132
|
||||
#define CLK_STIMER1 133
|
||||
#define PCLK_WDT_NS 134
|
||||
#define TCLK_WDT_NS 135
|
||||
#define PCLK_WDT_S 136
|
||||
#define TCLK_WDT_S 137
|
||||
#define PCLK_WDT_HPMCU 138
|
||||
#define TCLK_WDT_HPMCU 139
|
||||
#define PCLK_I2C1 140
|
||||
#define CLK_I2C1 141
|
||||
#define PCLK_I2C2 142
|
||||
#define CLK_I2C2 143
|
||||
#define PCLK_I2C3 144
|
||||
#define CLK_I2C3 145
|
||||
#define PCLK_I2C4 146
|
||||
#define CLK_I2C4 147
|
||||
#define PCLK_SPI0 148
|
||||
#define PCLK_PWM1 149
|
||||
#define CLK_OSC_PWM1 150
|
||||
#define PCLK_PWM2 151
|
||||
#define CLK_OSC_PWM2 152
|
||||
#define PCLK_UART2 153
|
||||
#define PCLK_UART1 154
|
||||
#define ACLK_RKDMA 155
|
||||
#define PCLK_TSADC 156
|
||||
#define CLK_TSADC 157
|
||||
#define CLK_TSADC_TSEN 158
|
||||
#define PCLK_SARADC 159
|
||||
#define CLK_SARADC 160
|
||||
#define PCLK_GPIO2 161
|
||||
#define DBCLK_GPIO2 162
|
||||
#define PCLK_IOC_VCCIO6 163
|
||||
#define ACLK_USBOTG 164
|
||||
#define CLK_REF_USBOTG 165
|
||||
#define HCLK_SDMMC1 166
|
||||
#define HCLK_SAI 167
|
||||
#define MCLK_SAI 168
|
||||
#define ACLK_CRYPTO 169
|
||||
#define HCLK_CRYPTO 170
|
||||
#define HCLK_RK_RNG_NS 171
|
||||
#define HCLK_RK_RNG_S 172
|
||||
#define PCLK_OTPC_NS 173
|
||||
#define CLK_OTPC_ROOT_NS 174
|
||||
#define CLK_SBPI_OTPC_NS 175
|
||||
#define CLK_USER_OTPC_NS 176
|
||||
#define PCLK_OTPC_S 177
|
||||
#define CLK_OTPC_ROOT_S 178
|
||||
#define CLK_SBPI_OTPC_S 179
|
||||
#define CLK_USER_OTPC_S 180
|
||||
#define CLK_OTPC_ARB 181
|
||||
#define PCLK_OTP_MASK 182
|
||||
#define HCLK_RGA 183
|
||||
#define ACLK_RGA 184
|
||||
#define ACLK_MAC 185
|
||||
#define PCLK_MAC 186
|
||||
#define CLK_MACPHY 187
|
||||
#define ACLK_SPINLOCK 188
|
||||
#define HCLK_CACHE 189
|
||||
#define PCLK_HPMCU_MAILBOX 190
|
||||
#define PCLK_HPMCU_INTMUX 191
|
||||
#define CLK_HPMCU 192
|
||||
#define CLK_HPMCU_RTC 193
|
||||
#define DCLK_DECOM 194
|
||||
#define ACLK_DECOM 195
|
||||
#define PCLK_DECOM 196
|
||||
#define ACLK_SYS_SRAM 197
|
||||
#define PCLK_DMA2DDR 198
|
||||
#define ACLK_DMA2DDR 199
|
||||
#define PCLK_DCF 200
|
||||
#define ACLK_DCF 201
|
||||
#define MCLK_ACODEC_TX 202
|
||||
#define SCLK_UART0_SRC 203
|
||||
#define SCLK_UART1_SRC 204
|
||||
#define SCLK_UART2_SRC 205
|
||||
#define XIN_RC_SRC 206
|
||||
#define CLK_UTMI_USBOTG 207
|
||||
#define CLK_REF_USBPHY 208
|
||||
|
||||
#endif // _DT_BINDINGS_CLK_ROCKCHIP_RV1103B_H
|
||||
103
include/dt-bindings/clock/tenstorrent,atlantis-prcm-rcpu.h
Normal file
103
include/dt-bindings/clock/tenstorrent,atlantis-prcm-rcpu.h
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
/*
|
||||
* Tenstorrent Atlantis PRCM Clock and Reset Indices
|
||||
*
|
||||
* Copyright (c) 2026 Tenstorrent
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_ATLANTIS_PRCM_RCPU_H
|
||||
#define _DT_BINDINGS_ATLANTIS_PRCM_RCPU_H
|
||||
|
||||
/*
|
||||
* RCPU Domain Clock IDs
|
||||
*/
|
||||
#define CLK_RCPU_PLL 0
|
||||
#define CLK_RCPU_ROOT 1
|
||||
#define CLK_RCPU_DIV2 2
|
||||
#define CLK_RCPU_DIV4 3
|
||||
#define CLK_RCPU_RTC 4
|
||||
#define CLK_SMNDMA0_ACLK 5
|
||||
#define CLK_SMNDMA1_ACLK 6
|
||||
#define CLK_WDT0_PCLK 7
|
||||
#define CLK_WDT1_PCLK 8
|
||||
#define CLK_TIMER_PCLK 9
|
||||
#define CLK_PVTC_PCLK 10
|
||||
#define CLK_PMU_PCLK 11
|
||||
#define CLK_MAILBOX_HCLK 12
|
||||
#define CLK_SEC_SPACC_HCLK 13
|
||||
#define CLK_SEC_OTP_HCLK 14
|
||||
#define CLK_TRNG_PCLK 15
|
||||
#define CLK_SEC_CRC_HCLK 16
|
||||
#define CLK_SMN_HCLK 17
|
||||
#define CLK_AHB0_HCLK 18
|
||||
#define CLK_SMN_PCLK 19
|
||||
#define CLK_SMN_CLK 20
|
||||
#define CLK_SCRATCHPAD_CLK 21
|
||||
#define CLK_RCPU_CORE_CLK 22
|
||||
#define CLK_RCPU_ROM_CLK 23
|
||||
#define CLK_OTP_LOAD_CLK 24
|
||||
#define CLK_NOC_PLL 25
|
||||
#define CLK_NOCC_CLK 26
|
||||
#define CLK_NOCC_DIV2 27
|
||||
#define CLK_NOCC_DIV4 28
|
||||
#define CLK_NOCC_RTC 29
|
||||
#define CLK_NOCC_CAN 30
|
||||
#define CLK_QSPI_SCLK 31
|
||||
#define CLK_QSPI_HCLK 32
|
||||
#define CLK_I2C0_PCLK 33
|
||||
#define CLK_I2C1_PCLK 34
|
||||
#define CLK_I2C2_PCLK 35
|
||||
#define CLK_I2C3_PCLK 36
|
||||
#define CLK_I2C4_PCLK 37
|
||||
#define CLK_UART0_PCLK 38
|
||||
#define CLK_UART1_PCLK 39
|
||||
#define CLK_UART2_PCLK 40
|
||||
#define CLK_UART3_PCLK 41
|
||||
#define CLK_UART4_PCLK 42
|
||||
#define CLK_SPI0_PCLK 43
|
||||
#define CLK_SPI1_PCLK 44
|
||||
#define CLK_SPI2_PCLK 45
|
||||
#define CLK_SPI3_PCLK 46
|
||||
#define CLK_GPIO_PCLK 47
|
||||
#define CLK_CAN0_HCLK 48
|
||||
#define CLK_CAN0_CLK 49
|
||||
#define CLK_CAN1_HCLK 50
|
||||
#define CLK_CAN1_CLK 51
|
||||
#define CLK_CAN0_TIMER_CLK 52
|
||||
#define CLK_CAN1_TIMER_CLK 53
|
||||
|
||||
/* RCPU domain reset */
|
||||
#define RST_SMNDMA0 0
|
||||
#define RST_SMNDMA1 1
|
||||
#define RST_WDT0 2
|
||||
#define RST_WDT1 3
|
||||
#define RST_TMR 4
|
||||
#define RST_PVTC 5
|
||||
#define RST_PMU 6
|
||||
#define RST_MAILBOX 7
|
||||
#define RST_SPACC 8
|
||||
#define RST_OTP 9
|
||||
#define RST_TRNG 10
|
||||
#define RST_CRC 11
|
||||
#define RST_QSPI 12
|
||||
#define RST_I2C0 13
|
||||
#define RST_I2C1 14
|
||||
#define RST_I2C2 15
|
||||
#define RST_I2C3 16
|
||||
#define RST_I2C4 17
|
||||
#define RST_UART0 18
|
||||
#define RST_UART1 19
|
||||
#define RST_UART2 20
|
||||
#define RST_UART3 21
|
||||
#define RST_UART4 22
|
||||
#define RST_SPI0 23
|
||||
#define RST_SPI1 24
|
||||
#define RST_SPI2 25
|
||||
#define RST_SPI3 26
|
||||
#define RST_GPIO 27
|
||||
#define RST_CAN0 28
|
||||
#define RST_CAN1 29
|
||||
#define RST_I2S0 30
|
||||
#define RST_I2S1 31
|
||||
|
||||
#endif /* _DT_BINDINGS_ATLANTIS_PRCM_RCPU_H */
|
||||
|
|
@ -197,6 +197,10 @@
|
|||
#define VF610_CLK_TCON1 188
|
||||
#define VF610_CLK_CAAM 189
|
||||
#define VF610_CLK_CRC 190
|
||||
#define VF610_CLK_END 191
|
||||
#define VF610_CLK_ESW 191
|
||||
#define VF610_CLK_ESW_MAC_TAB0 192
|
||||
#define VF610_CLK_ESW_MAC_TAB1 193
|
||||
#define VF610_CLK_ESW_MAC_TAB2 194
|
||||
#define VF610_CLK_ESW_MAC_TAB3 195
|
||||
|
||||
#endif /* __DT_BINDINGS_CLOCK_VF610_H */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user