* [PATCH v10 2/5] dt-bindings: clock: add Ambarella CV75 RCT
2026-10-19 4:55 [PATCH v10 0/5] arm64: add Ambarella CV75 SoC support Long Zhao via B4 Relay
2026-10-19 4:55 ` [PATCH v10 1/5] dt-bindings: arm: add Ambarella CV75 platforms Long Zhao via B4 Relay
@ 2026-10-19 4:55 ` Long Zhao via B4 Relay
2026-10-19 4:55 ` [PATCH v10 3/5] clk: ambarella: add CV75 RCT clock controller Long Zhao via B4 Relay
` (2 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Long Zhao via B4 Relay @ 2026-10-19 4:55 UTC (permalink / raw)
To: Arnd Bergmann, Krzysztof Kozlowski, Alexandre Belloni, soc,
linux-arm-kernel, Michael Turquette, Stephen Boyd
Cc: Jerome Brunet, linux-clk, Brian Masney, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Krzysztof Kozlowski,
Conor Dooley, Catalin Marinas, Will Deacon, Lee Jones, mfd,
devicetree, Long Zhao, Long Zhao, linux-kernel
From: Long Zhao <longzhao@ambarella.com>
Document the CV75 RCT clock controller and the clock ID header used by
DT consumers.
Document #reset-cells for the RCT reset-provider role. Soft-reset line
IDs and the reset provider driver are deferred; this series has no
resets= consumers.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Long Zhao <longzhao@ambarella.com>
---
.../bindings/clock/ambarella,cv75-rct.yaml | 64 ++++++++++++++++++++++
include/dt-bindings/clock/ambarella,cv75-rct.h | 14 +++++
2 files changed, 78 insertions(+)
diff --git a/Documentation/devicetree/bindings/clock/ambarella,cv75-rct.yaml b/Documentation/devicetree/bindings/clock/ambarella,cv75-rct.yaml
new file mode 100644
index 000000000000..be89bd75f9e2
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/ambarella,cv75-rct.yaml
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/ambarella,cv75-rct.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Ambarella CV75 RCT Clock Controller
+
+maintainers:
+ - Long Zhao <longzhao@ambarella.com>
+
+description: |
+ The RCT (Reset and Clock Tree) block on the Ambarella CV75 SoC provides
+ PLLs, clock muxes, dividers and soft-reset controls for on-chip
+ peripherals.
+
+ The same register region is also exposed as a syscon for other SoC
+ blocks (e.g. pin drive-strength), hence the "syscon" compatible.
+
+ Clock indices are defined in include/dt-bindings/clock/ambarella,cv75-rct.h.
+
+properties:
+
+ compatible:
+ items:
+ - const: ambarella,cv75-rct
+ - const: syscon
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ description: Reference crystal oscillator (typically 24 MHz)
+ maxItems: 1
+
+ clock-names:
+ const: osc
+
+ "#clock-cells":
+ const: 1
+
+ "#reset-cells":
+ const: 1
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - "#clock-cells"
+ - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ clock-controller@ed080000 {
+ compatible = "ambarella,cv75-rct", "syscon";
+ reg = <0xed080000 0x1000>;
+ clocks = <&osc>;
+ clock-names = "osc";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
diff --git a/include/dt-bindings/clock/ambarella,cv75-rct.h b/include/dt-bindings/clock/ambarella,cv75-rct.h
new file mode 100644
index 000000000000..b3e965b4ff2e
--- /dev/null
+++ b/include/dt-bindings/clock/ambarella,cv75-rct.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
+/*
+ * Copyright (C) 2026 Ambarella, Inc.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_AMBARELLA_CV75_RCT_H
+#define _DT_BINDINGS_CLOCK_AMBARELLA_CV75_RCT_H
+
+#define CV75_GCLK_UART0 0
+#define CV75_GCLK_CORE 1
+#define CV75_GCLK_AHB 2
+#define CV75_GCLK_APB 3
+
+#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v10 3/5] clk: ambarella: add CV75 RCT clock controller
2026-10-19 4:55 [PATCH v10 0/5] arm64: add Ambarella CV75 SoC support Long Zhao via B4 Relay
2026-10-19 4:55 ` [PATCH v10 1/5] dt-bindings: arm: add Ambarella CV75 platforms Long Zhao via B4 Relay
2026-10-19 4:55 ` [PATCH v10 2/5] dt-bindings: clock: add Ambarella CV75 RCT Long Zhao via B4 Relay
@ 2026-10-19 4:55 ` Long Zhao via B4 Relay
2026-10-19 4:55 ` [PATCH v10 4/5] arm64: ambarella: add ARCH_AMBARELLA and CV75 EVK DT Long Zhao via B4 Relay
2026-10-19 4:55 ` [PATCH v10 5/5] MAINTAINERS: add ARM/AMBARELLA SoC support Long Zhao via B4 Relay
4 siblings, 0 replies; 7+ messages in thread
From: Long Zhao via B4 Relay @ 2026-10-19 4:55 UTC (permalink / raw)
To: Arnd Bergmann, Krzysztof Kozlowski, Alexandre Belloni, soc,
linux-arm-kernel, Michael Turquette, Stephen Boyd
Cc: Jerome Brunet, linux-clk, Brian Masney, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Krzysztof Kozlowski,
Conor Dooley, Catalin Marinas, Will Deacon, Lee Jones, mfd,
devicetree, Long Zhao, Long Zhao, linux-kernel
From: Long Zhao <longzhao@ambarella.com>
Add a table-driven CCF driver for the CV75 root clock tree. Register
the core PLL, AHB/APB fixed factors and UART0 composite clock, with
osc supplied via clk_parent_data.
Signed-off-by: Long Zhao <longzhao@ambarella.com>
---
drivers/clk/Kconfig | 1 +
drivers/clk/Makefile | 1 +
drivers/clk/ambarella/Kconfig | 9 +
drivers/clk/ambarella/Makefile | 3 +
drivers/clk/ambarella/clk-cv75.c | 361 +++++++++++++++++++++++++++++++++++++++
5 files changed, 375 insertions(+)
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 1717ce75a907..fbbf4963716c 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -506,6 +506,7 @@ config COMMON_CLK_RPMI
the RISC-V platform management interface (RPMI) specification.
source "drivers/clk/actions/Kconfig"
+source "drivers/clk/ambarella/Kconfig"
source "drivers/clk/analogbits/Kconfig"
source "drivers/clk/aspeed/Kconfig"
source "drivers/clk/bcm/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index cc108a75a900..30d823ee606f 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -112,6 +112,7 @@ obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o
# please keep this section sorted lexicographically by directory path name
obj-y += actions/
+obj-y += ambarella/
obj-y += analogbits/
obj-y += aspeed/
obj-$(CONFIG_COMMON_CLK_AT91) += at91/
diff --git a/drivers/clk/ambarella/Kconfig b/drivers/clk/ambarella/Kconfig
new file mode 100644
index 000000000000..720eebdc5c9c
--- /dev/null
+++ b/drivers/clk/ambarella/Kconfig
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config CLK_AMBARELLA_CV75
+ bool "Ambarella CV75 RCT clock controller"
+ depends on ARCH_AMBARELLA || COMPILE_TEST
+ default ARCH_AMBARELLA
+ help
+ Say Y to enable the Ambarella CV75 RCT clock controller for
+ early bring-up clocks (core PLL, AHB, APB, UART0).
diff --git a/drivers/clk/ambarella/Makefile b/drivers/clk/ambarella/Makefile
new file mode 100644
index 000000000000..29555e452441
--- /dev/null
+++ b/drivers/clk/ambarella/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-$(CONFIG_CLK_AMBARELLA_CV75) += clk-cv75.o
diff --git a/drivers/clk/ambarella/clk-cv75.c b/drivers/clk/ambarella/clk-cv75.c
new file mode 100644
index 000000000000..6a8f80571958
--- /dev/null
+++ b/drivers/clk/ambarella/clk-cv75.c
@@ -0,0 +1,361 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Ambarella CV75 RCT clock controller
+ *
+ * Copyright (C) 2026 Ambarella, Inc.
+ */
+
+#include <linux/array_size.h>
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/clk-provider.h>
+#include <linux/container_of.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/math64.h>
+#include <linux/module.h>
+#include <linux/overflow.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <dt-bindings/clock/ambarella,cv75-rct.h>
+
+#define CV75_NUM_CLKS (CV75_GCLK_APB + 1)
+
+#define PLL_CTRL_BYPASS BIT(2)
+#define PLL_CTRL_FRAC_MODE BIT(3)
+#define PLL_CTRL_FORCE_RESET BIT(4)
+#define PLL_CTRL_POWER_DOWN BIT(5)
+#define PLL_CTRL_HALT_VCO BIT(6)
+#define PLL_CTRL_SDIV GENMASK(15, 12)
+#define PLL_CTRL_SOUT GENMASK(19, 16)
+#define PLL_CTRL_INTP GENMASK(30, 24)
+
+#define PLL_CTRL2_VCODIV_DIV2 BIT(8)
+#define PLL_CTRL2_FSDIV_DIV2 BIT(9)
+#define PLL_CTRL2_FSOUT_DIV2 BIT(11)
+#define PLL_CTRL2_BYPASS_HSDIV BIT(12)
+
+struct cv75_pll_regs {
+ u32 ctrl;
+ u32 frac;
+ u32 ctrl2;
+};
+
+struct cv75_pll_hw {
+ struct clk_hw hw;
+ struct cv75_pll_regs regs;
+};
+
+struct cv75_clk {
+ void __iomem *base;
+ spinlock_t lock;
+ struct cv75_pll_hw core;
+ struct cv75_pll_hw enet;
+ struct cv75_pll_hw sd;
+};
+
+struct cv75_pll {
+ const char *name;
+ struct cv75_pll_hw *hw;
+ unsigned long flags;
+ struct cv75_pll_regs regs;
+ int id;
+};
+
+struct cv75_fixed_factor {
+ const char *name;
+ u32 id;
+ struct u16_fract ratio;
+};
+
+struct cv75_composite {
+ const char *name;
+ const struct clk_parent_data *parents;
+ unsigned long flags;
+ u32 id;
+ u16 mux_reg;
+ u16 div_reg;
+ u8 num_parents;
+ u8 mux_shift;
+ u8 mux_width;
+ u8 div_shift;
+ u8 div_width;
+};
+
+struct cv75_composite_hw {
+ struct clk_mux mux;
+ struct clk_divider div;
+ struct clk_gate gate;
+};
+
+static struct cv75_clk cv75_ccu;
+
+#define CV75_PLL(_id, _name, _ctrl, _frac, _ctrl2, _flags, _hw) { \
+ .name = _name, \
+ .hw = _hw, \
+ .flags = _flags, \
+ .regs = { \
+ .ctrl = _ctrl, \
+ .frac = _frac, \
+ .ctrl2 = _ctrl2, \
+ }, \
+ .id = _id, \
+}
+
+static const struct cv75_pll cv75_plls[] = {
+ CV75_PLL(CV75_GCLK_CORE, "core", 0x000, 0x004, 0x100,
+ CLK_IS_CRITICAL, &cv75_ccu.core),
+ CV75_PLL(-1, "pll_enet", 0x520, 0x524, 0x528,
+ 0, &cv75_ccu.enet),
+ CV75_PLL(-1, "pll_sd", 0x4ac, 0x4b0, 0x4b4,
+ 0, &cv75_ccu.sd),
+};
+
+static const struct cv75_fixed_factor cv75_fixed_factors[] = {
+ { .id = CV75_GCLK_AHB, .name = "ahb", .ratio = { 1, 2 } },
+ { .id = CV75_GCLK_APB, .name = "apb", .ratio = { 1, 4 } },
+};
+
+static const struct clk_parent_data cv75_uart_parents[] = {
+ { .fw_name = "osc" },
+ { .hw = &cv75_ccu.core.hw },
+ { .hw = &cv75_ccu.enet.hw },
+ { .hw = &cv75_ccu.sd.hw },
+};
+
+#define CV75_COMPOSITE(_id, _name, _parents, _mreg, _mshift, _mwidth, \
+ _dreg, _dshift, _dwidth, _flags) \
+{ \
+ .id = _id, \
+ .name = _name, \
+ .parents = _parents, \
+ .num_parents = ARRAY_SIZE(_parents), \
+ .mux_reg = _mreg, \
+ .mux_shift = _mshift, \
+ .mux_width = _mwidth, \
+ .div_reg = _dreg, \
+ .div_shift = _dshift, \
+ .div_width = _dwidth, \
+ .flags = _flags, \
+}
+
+static const struct cv75_composite cv75_composites[] = {
+ CV75_COMPOSITE(CV75_GCLK_UART0, "uart0", cv75_uart_parents,
+ 0x1c8, 0, 2, 0x038, 0, 24,
+ CLK_SET_RATE_NO_REPARENT),
+};
+
+#define to_cv75_pll(_hw) container_of(_hw, struct cv75_pll_hw, hw)
+
+static unsigned long cv75_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct cv75_pll_hw *pll = to_cv75_pll(hw);
+ u32 ctrl, ctrl2, frac_val;
+ u32 vcodiv, fsdiv, fsout;
+ u32 intp, sdiv, sout;
+ u64 vco, frac = 0;
+
+ ctrl = readl_relaxed(cv75_ccu.base + pll->regs.ctrl);
+ if (ctrl & (PLL_CTRL_POWER_DOWN | PLL_CTRL_HALT_VCO | PLL_CTRL_FORCE_RESET))
+ return 0;
+
+ if (ctrl & PLL_CTRL_BYPASS)
+ return parent_rate;
+
+ ctrl2 = readl_relaxed(cv75_ccu.base + pll->regs.ctrl2);
+ intp = FIELD_GET(PLL_CTRL_INTP, ctrl) + 1;
+ sdiv = FIELD_GET(PLL_CTRL_SDIV, ctrl) + 1;
+ sout = FIELD_GET(PLL_CTRL_SOUT, ctrl) + 1;
+ vcodiv = (ctrl2 & PLL_CTRL2_VCODIV_DIV2) ? 2 : 1;
+ fsdiv = (ctrl2 & PLL_CTRL2_FSDIV_DIV2) ? 2 : 1;
+ fsout = (ctrl2 & PLL_CTRL2_FSOUT_DIV2) ? 2 : 1;
+
+ vco = (u64)parent_rate * vcodiv * fsdiv * intp * sdiv;
+ if (ctrl & PLL_CTRL_FRAC_MODE) {
+ frac_val = readl_relaxed(cv75_ccu.base + pll->regs.frac);
+ frac = mul_u64_u32_shr((u64)parent_rate * vcodiv * fsdiv * sdiv,
+ frac_val, 32);
+ vco += frac;
+ }
+
+ if (!(ctrl2 & PLL_CTRL2_BYPASS_HSDIV))
+ vco = div_u64(vco, (u64)vcodiv * fsout * sout);
+
+ return vco;
+}
+
+static const struct clk_ops cv75_pll_ops = {
+ .recalc_rate = cv75_pll_recalc_rate,
+};
+
+static int cv75_register_plls(struct device *dev,
+ struct clk_hw_onecell_data *data)
+{
+ struct clk_parent_data parent_data = { .fw_name = "osc" };
+
+ for (unsigned int i = 0; i < ARRAY_SIZE(cv75_plls); i++) {
+ const struct cv75_pll *desc = &cv75_plls[i];
+ struct cv75_pll_hw *pll = desc->hw;
+ struct clk_init_data init = {};
+ int ret;
+
+ pll->regs = desc->regs;
+
+ init.name = desc->name;
+ init.ops = &cv75_pll_ops;
+ init.parent_data = &parent_data;
+ init.num_parents = 1;
+ init.flags = desc->flags;
+ pll->hw.init = &init;
+
+ ret = devm_clk_hw_register(dev, &pll->hw);
+ if (ret)
+ return ret;
+
+ if (desc->id >= 0)
+ data->hws[desc->id] = &pll->hw;
+ }
+
+ return 0;
+}
+
+static int cv75_register_fixed_factors(struct device *dev,
+ struct clk_hw_onecell_data *data)
+{
+ for (unsigned int i = 0; i < ARRAY_SIZE(cv75_fixed_factors); i++) {
+ const struct cv75_fixed_factor *f = &cv75_fixed_factors[i];
+ struct clk_hw *hw;
+
+ hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, f->name,
+ &cv75_ccu.core.hw, 0,
+ f->ratio.numerator,
+ f->ratio.denominator);
+ if (IS_ERR(hw))
+ return PTR_ERR(hw);
+
+ data->hws[f->id] = hw;
+ }
+
+ return 0;
+}
+
+static struct clk_hw *cv75_register_composite(struct device *dev,
+ const struct cv75_composite *c)
+{
+ const struct clk_ops *mux_ops = NULL, *div_ops = NULL, *gate_ops = NULL;
+ struct clk_hw *mux_hw = NULL, *div_hw = NULL, *gate_hw = NULL;
+ struct cv75_composite_hw *comp;
+
+ comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
+ if (!comp)
+ return ERR_PTR(-ENOMEM);
+
+ if (c->mux_width) {
+ comp->mux.reg = cv75_ccu.base + c->mux_reg;
+ comp->mux.shift = c->mux_shift;
+ comp->mux.mask = GENMASK(c->mux_width - 1, 0);
+ comp->mux.lock = &cv75_ccu.lock;
+ mux_hw = &comp->mux.hw;
+ mux_ops = &clk_mux_ops;
+ }
+
+ if (c->div_width) {
+ comp->div.reg = cv75_ccu.base + c->div_reg;
+ comp->div.shift = c->div_shift;
+ comp->div.width = c->div_width;
+ comp->div.flags = CLK_DIVIDER_ONE_BASED;
+ comp->div.lock = &cv75_ccu.lock;
+ div_hw = &comp->div.hw;
+ div_ops = &clk_divider_ops;
+
+ comp->gate.reg = cv75_ccu.base + c->div_reg;
+ comp->gate.bit_idx = c->div_shift + c->div_width;
+ comp->gate.flags = CLK_GATE_SET_TO_DISABLE;
+ comp->gate.lock = &cv75_ccu.lock;
+ gate_hw = &comp->gate.hw;
+ gate_ops = &clk_gate_ops;
+ }
+
+ return devm_clk_hw_register_composite_pdata(dev, c->name, c->parents,
+ c->num_parents,
+ mux_hw, mux_ops,
+ div_hw, div_ops,
+ gate_hw, gate_ops, c->flags);
+}
+
+static int cv75_register_composites(struct device *dev,
+ struct clk_hw_onecell_data *data)
+{
+ for (unsigned int i = 0; i < ARRAY_SIZE(cv75_composites); i++) {
+ const struct cv75_composite *c = &cv75_composites[i];
+ struct clk_hw *hw;
+
+ hw = cv75_register_composite(dev, c);
+ if (IS_ERR(hw))
+ return PTR_ERR(hw);
+
+ data->hws[c->id] = hw;
+ }
+
+ return 0;
+}
+
+static int cv75_rct_probe(struct platform_device *pdev)
+{
+ struct clk_hw_onecell_data *data;
+ struct device *dev = &pdev->dev;
+ int ret;
+
+ cv75_ccu.base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(cv75_ccu.base))
+ return PTR_ERR(cv75_ccu.base);
+
+ data = devm_kzalloc(dev, struct_size(data, hws, CV75_NUM_CLKS), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+ data->num = CV75_NUM_CLKS;
+
+ spin_lock_init(&cv75_ccu.lock);
+
+ ret = cv75_register_plls(dev, data);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to register plls\n");
+
+ ret = cv75_register_fixed_factors(dev, data);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to register fixed factors\n");
+
+ ret = cv75_register_composites(dev, data);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to register composites\n");
+
+ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, data);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to add clock provider\n");
+
+ return 0;
+}
+
+static const struct of_device_id cv75_rct_match[] = {
+ { .compatible = "ambarella,cv75-rct" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, cv75_rct_match);
+
+static struct platform_driver cv75_rct_driver = {
+ .probe = cv75_rct_probe,
+ .driver = {
+ .name = "ambarella-cv75-rct",
+ .of_match_table = cv75_rct_match,
+ },
+};
+module_platform_driver(cv75_rct_driver);
+
+MODULE_AUTHOR("Cao Rongrong <rrcao@ambarella.com>");
+MODULE_DESCRIPTION("Ambarella CV75 RCT clock controller");
+MODULE_LICENSE("GPL");
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v10 4/5] arm64: ambarella: add ARCH_AMBARELLA and CV75 EVK DT
2026-10-19 4:55 [PATCH v10 0/5] arm64: add Ambarella CV75 SoC support Long Zhao via B4 Relay
` (2 preceding siblings ...)
2026-10-19 4:55 ` [PATCH v10 3/5] clk: ambarella: add CV75 RCT clock controller Long Zhao via B4 Relay
@ 2026-10-19 4:55 ` Long Zhao via B4 Relay
2026-10-19 5:05 ` sashiko-bot
2026-10-19 4:55 ` [PATCH v10 5/5] MAINTAINERS: add ARM/AMBARELLA SoC support Long Zhao via B4 Relay
4 siblings, 1 reply; 7+ messages in thread
From: Long Zhao via B4 Relay @ 2026-10-19 4:55 UTC (permalink / raw)
To: Arnd Bergmann, Krzysztof Kozlowski, Alexandre Belloni, soc,
linux-arm-kernel, Michael Turquette, Stephen Boyd
Cc: Jerome Brunet, linux-clk, Brian Masney, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Krzysztof Kozlowski,
Conor Dooley, Catalin Marinas, Will Deacon, Lee Jones, mfd,
devicetree, Long Zhao, Long Zhao, linux-kernel, Linus Walleij
From: Long Zhao <longzhao@ambarella.com>
Enable ARCH_AMBARELLA and add a minimal CV75 SoC / EVK device tree for
console bring-up with the RCT clocks, UART, pinctrl and GPIO banks.
Reviewed-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Long Zhao <longzhao@ambarella.com>
---
arch/arm64/Kconfig.platforms | 6 +
arch/arm64/boot/dts/Makefile | 1 +
arch/arm64/boot/dts/ambarella/Makefile | 3 +
arch/arm64/boot/dts/ambarella/cv75-evk.dts | 30 +++++
arch/arm64/boot/dts/ambarella/cv75.dtsi | 177 +++++++++++++++++++++++++++++
arch/arm64/configs/defconfig | 1 +
6 files changed, 218 insertions(+)
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index d2acfac73003..16d7e3a4c2d6 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -26,6 +26,12 @@ config ARCH_SUNXI
help
This enables support for Allwinner sunxi based SoCs like the A64.
+config ARCH_AMBARELLA
+ bool "Ambarella SoC family"
+ select PINCTRL
+ help
+ This enables support for the ARM64 based Ambarella SoCs like CV75.
+
config ARCH_ALPINE
bool "Annapurna Labs Alpine platform"
select ALPINE_MSI if PCI
diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
index fc726b215f12..f1709eb5d915 100644
--- a/arch/arm64/boot/dts/Makefile
+++ b/arch/arm64/boot/dts/Makefile
@@ -4,6 +4,7 @@ subdir-y += airoha
subdir-y += allwinner
subdir-y += altera
subdir-y += amazon
+subdir-y += ambarella
subdir-y += amd
subdir-y += amlogic
subdir-y += apm
diff --git a/arch/arm64/boot/dts/ambarella/Makefile b/arch/arm64/boot/dts/ambarella/Makefile
new file mode 100644
index 000000000000..ddca3d7b18cc
--- /dev/null
+++ b/arch/arm64/boot/dts/ambarella/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+dtb-$(CONFIG_ARCH_AMBARELLA) += cv75-evk.dtb
diff --git a/arch/arm64/boot/dts/ambarella/cv75-evk.dts b/arch/arm64/boot/dts/ambarella/cv75-evk.dts
new file mode 100644
index 000000000000..42a0fe24b83b
--- /dev/null
+++ b/arch/arm64/boot/dts/ambarella/cv75-evk.dts
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Ambarella CV75 EVK board
+ */
+
+/dts-v1/;
+
+#include "cv75.dtsi"
+
+/ {
+ model = "Ambarella CV75 EVK Board";
+ compatible = "ambarella,cv75-evk", "ambarella,cv75";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = &uart0;
+ };
+
+ memory@200000 {
+ device_type = "memory";
+ reg = <0x0 0x00200000 0x0 0x07e00000>;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/ambarella/cv75.dtsi b/arch/arm64/boot/dts/ambarella/cv75.dtsi
new file mode 100644
index 000000000000..c36b6af48237
--- /dev/null
+++ b/arch/arm64/boot/dts/ambarella/cv75.dtsi
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Ambarella CV75 SoC
+ *
+ * Boot peripheral: UART0 console.
+ * Clocks: a single ambarella,cv75-rct provider.
+ */
+
+#include <dt-bindings/clock/ambarella,cv75-rct.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ compatible = "ambarella,cv75";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a76";
+ device_type = "cpu";
+ reg = <0x000>;
+ enable-method = "psci";
+ };
+
+ cpu@1 {
+ compatible = "arm,cortex-a76";
+ device_type = "cpu";
+ reg = <0x100>;
+ enable-method = "psci";
+ };
+ };
+
+ osc: oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ clock-output-names = "osc";
+ };
+
+ psci {
+ compatible = "arm,psci-0.2";
+ method = "smc";
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ ahb@ffe0000000 {
+ compatible = "simple-bus";
+ reg = <0xff 0xe0000000 0x0 0x01000000>;
+ ranges = <0xe0000000 0xff 0xe0000000 0x01000000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ s_scratchpad_syscon: scratchpad@e002e000 {
+ compatible = "ambarella,cv75-sec-scratchpad", "syscon";
+ reg = <0xe002e000 0x1000>;
+ };
+ };
+
+ apb@ffe4000000 {
+ compatible = "simple-bus";
+ reg = <0xff 0xe4000000 0x0 0x01000000>;
+ ranges = <0xe4000000 0xff 0xe4000000 0x01000000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ uart0: serial@e4000000 {
+ compatible = "ambarella,cv75-uart", "snps,dw-apb-uart";
+ reg = <0xe4000000 0x1000>;
+ clocks = <&rct CV75_GCLK_UART0>;
+ interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+
+ status = "disabled";
+ };
+
+ pinctrl: pinctrl@e4010000 {
+ compatible = "ambarella,cv75-pinctrl";
+ reg = <0xe4010000 0x1000>;
+ ambarella,drive-strength-syscon = <&rct>;
+ ambarella,pull-syscon = <&s_scratchpad_syscon>;
+
+ uart0_pins: uart0-pins {
+ function = "uart0";
+ groups = "uart0";
+ };
+ };
+
+ gpio0: gpio@e4013000 {
+ compatible = "ambarella,cv75-gpio", "arm,primecell";
+ reg = <0xe4013000 0x1000>;
+ clocks = <&rct CV75_GCLK_APB>;
+ clock-names = "apb_pclk";
+ interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl 0 0 32>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ arm,primecell-periphid = <0x000e8061>;
+ };
+
+ gpio1: gpio@e4014000 {
+ compatible = "ambarella,cv75-gpio", "arm,primecell";
+ reg = <0xe4014000 0x1000>;
+ clocks = <&rct CV75_GCLK_APB>;
+ clock-names = "apb_pclk";
+ interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl 0 32 32>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ arm,primecell-periphid = <0x000e8061>;
+ };
+
+ gpio2: gpio@e4015000 {
+ compatible = "ambarella,cv75-gpio", "arm,primecell";
+ reg = <0xe4015000 0x1000>;
+ clocks = <&rct CV75_GCLK_APB>;
+ clock-names = "apb_pclk";
+ interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl 0 64 32>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ arm,primecell-periphid = <0x000e8061>;
+ };
+ };
+
+ rct: clock-controller@ffed080000 {
+ compatible = "ambarella,cv75-rct", "syscon";
+ reg = <0xff 0xed080000 0x0 0x1000>;
+ clocks = <&osc>;
+ clock-names = "osc";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ assigned-clocks = <&rct CV75_GCLK_UART0>;
+ assigned-clock-parents = <&osc>;
+ assigned-clock-rates = <24000000>;
+ };
+
+ gic: interrupt-controller@fff0101000 {
+ compatible = "arm,gic-400";
+ reg = <0xff 0xf0101000 0x0 0x1000>,
+ <0xff 0xf0102000 0x0 0x2000>,
+ <0xff 0xf0104000 0x0 0x2000>,
+ <0xff 0xf0106000 0x0 0x2000>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupts = <GIC_PPI 9
+ (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 12 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+};
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index ad3bd3d9507b..454f07a6a6a6 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -36,6 +36,7 @@ CONFIG_CRASH_DUMP=y
CONFIG_ARCH_ACTIONS=y
CONFIG_ARCH_AIROHA=y
CONFIG_ARCH_SUNXI=y
+CONFIG_ARCH_AMBARELLA=y
CONFIG_ARCH_ALPINE=y
CONFIG_ARCH_APPLE=y
CONFIG_ARCH_ARTPEC=y
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread