* [RFC 0/4] arm64: Realtek RTD1295 clocks
@ 2017-08-17 11:20 Andreas Färber
2017-08-17 11:20 ` [RFC 1/4] dt-bindings: clock: Add Realtek RTD1295 Andreas Färber
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Andreas Färber @ 2017-08-17 11:20 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, linux-clk, linux-arm-kernel
Cc: linux-kernel, Roc He, 蒋丽琴,
Andreas Färber, devicetree
Hello,
This series adds two clock controllers for the Realtek RTD1295 SoC.
Based on my reset controller and IRQ mux series.
There being no public source code for RTD1295, the implementation is based on
register offsets, fields and names seen in the vendor DT, unified into 2 nodes.
The PLL calculations were experimentally found by comparing vendor Android
/sys/kernel/debug/clk/clk_summary to the register field values in /dev/mem -
thus the formulas may be incomplete or incorrect.
Together with the reset driver and IRQ mux, the clock gates allow to
initialize UART1.
Code needs cleanups - sharing this for calculation findings and design.
More experimental patches at:
https://github.com/afaerber/linux/commits/rtd1295-next
Have a lot of fun!
Cheers,
Andreas
Cc: Michael Turquette <mturquette@baylibre.com>
Cc: Stephen Boyd <sboyd@codeaurora.org>
Cc: linux-clk@vger.kernel.org
Cc: Roc He <hepeng@zidoo.tv>
Cc: 蒋丽琴 <jiang.liqin@geniatech.com>
Cc: devicetree@vger.kernel.org
Andreas Färber (4):
dt-bindings: clock: Add Realtek RTD1295
arm64: dts: realtek: Add clock nodes for RTD1295
clk: Add Realtek RTD1295
arm64: dts: realtek: Update RTD1295 UART nodes with clocks
.../devicetree/bindings/clock/realtek,rtd129x.txt | 20 ++
arch/arm64/boot/dts/realtek/rtd1295.dtsi | 28 +-
drivers/clk/Kconfig | 7 +
drivers/clk/Makefile | 1 +
drivers/clk/clk-rtd1295.c | 385 +++++++++++++++++++++
include/dt-bindings/clock/realtek,rtd1295.h | 99 ++++++
6 files changed, 537 insertions(+), 3 deletions(-)
create mode 100644 Documentation/devicetree/bindings/clock/realtek,rtd129x.txt
create mode 100644 drivers/clk/clk-rtd1295.c
create mode 100644 include/dt-bindings/clock/realtek,rtd1295.h
--
2.12.3
^ permalink raw reply [flat|nested] 6+ messages in thread* [RFC 1/4] dt-bindings: clock: Add Realtek RTD1295 2017-08-17 11:20 [RFC 0/4] arm64: Realtek RTD1295 clocks Andreas Färber @ 2017-08-17 11:20 ` Andreas Färber 2017-08-22 2:21 ` Rob Herring 2017-08-17 11:20 ` [RFC 2/4] arm64: dts: realtek: Add clock nodes for RTD1295 Andreas Färber ` (2 subsequent siblings) 3 siblings, 1 reply; 6+ messages in thread From: Andreas Färber @ 2017-08-17 11:20 UTC (permalink / raw) To: Michael Turquette, Stephen Boyd, linux-clk, linux-arm-kernel Cc: linux-kernel, Roc He, 蒋丽琴, Andreas Färber, Rob Herring, Mark Rutland, devicetree Naming inspired from Zidoo X9S Device Tree and clk_summary. Signed-off-by: Andreas Färber <afaerber@suse.de> --- .../devicetree/bindings/clock/realtek,rtd129x.txt | 20 +++++ include/dt-bindings/clock/realtek,rtd1295.h | 99 ++++++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/realtek,rtd129x.txt create mode 100644 include/dt-bindings/clock/realtek,rtd1295.h diff --git a/Documentation/devicetree/bindings/clock/realtek,rtd129x.txt b/Documentation/devicetree/bindings/clock/realtek,rtd129x.txt new file mode 100644 index 000000000000..b55da39faf58 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/realtek,rtd129x.txt @@ -0,0 +1,20 @@ +Realtek RTD129x clock controllers +================================= + +Requires properties: +- compatible : Should be one of the following: + - "realtek,rtd1295-clk" + - "realtek,rtd1295-iso-clk" +- reg : Specifies physical base address and size +- clocks : Specifies the oscillator node +- #clock-cells : Shall be 1 + + +Example: + + clock-controller@98000000 { + compatible = "realtek,rtd1295-clk"; + reg = <0x98000000 0x1000>; + clocks = <&osc27M>; + #clock-cells = <1>; + }; diff --git a/include/dt-bindings/clock/realtek,rtd1295.h b/include/dt-bindings/clock/realtek,rtd1295.h new file mode 100644 index 000000000000..278148bff2ac --- /dev/null +++ b/include/dt-bindings/clock/realtek,rtd1295.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2017 Andreas Färber + * + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) + */ +#ifndef DT_BINDINGS_CLOCK_RTD1295_H +#define DT_BINDINGS_CLOCK_RTD1295_H + +#define RTD1295_CLK_PLL_SCPU 0 +#define RTD1295_CLK_PLL_BUS 1 +#define RTD1295_CLK_PLL_BUS_DIV2 2 +#define RTD1295_CLK_SYS 3 +#define RTD1295_CLK_PLL_BUS_H 4 +#define RTD1295_CLK_SYSH 5 +#define RTD1295_CLK_PLL_DDSA 6 +#define RTD1295_CLK_PLL_DDSB 7 +#define RTD1295_CLK_PLL_VODMA 8 +#define RTD1295_CLK_PLL_VE1 9 +#define RTD1295_CLK_PLL_VE2 10 +#define RTD1295_CLK_PLL_GPU 14 +#define RTD1295_CLK_PLL_ACPU 15 + +#define RTD1295_CLK_EN_BASE 16 +#define RTD1295_CLK_EN_MISC (RTD1295_CLK_EN_BASE + 0) +#define RTD1295_CLK_EN_PCIE0 (RTD1295_CLK_EN_BASE + 1) +#define RTD1295_CLK_EN_SATA_0 (RTD1295_CLK_EN_BASE + 2) +#define RTD1295_CLK_EN_GSPI (RTD1295_CLK_EN_BASE + 3) +#define RTD1295_CLK_EN_USB (RTD1295_CLK_EN_BASE + 4) +#define RTD1295_CLK_EN_PCR (RTD1295_CLK_EN_BASE + 5) +#define RTD1295_CLK_EN_ISO_MISC (RTD1295_CLK_EN_BASE + 6) +#define RTD1295_CLK_EN_SATA_ALIVE_0 (RTD1295_CLK_EN_BASE + 7) +#define RTD1295_CLK_EN_HDMI (RTD1295_CLK_EN_BASE + 8) +#define RTD1295_CLK_EN_ETN (RTD1295_CLK_EN_BASE + 9) +#define RTD1295_CLK_EN_AIO (RTD1295_CLK_EN_BASE + 10) +#define RTD1295_CLK_EN_GPU (RTD1295_CLK_EN_BASE + 11) +#define RTD1295_CLK_EN_VE1 (RTD1295_CLK_EN_BASE + 12) +#define RTD1295_CLK_EN_VE2 (RTD1295_CLK_EN_BASE + 13) +#define RTD1295_CLK_EN_TVE (RTD1295_CLK_EN_BASE + 14) +#define RTD1295_CLK_EN_VO (RTD1295_CLK_EN_BASE + 15) +#define RTD1295_CLK_EN_LVDS (RTD1295_CLK_EN_BASE + 16) +#define RTD1295_CLK_EN_SE (RTD1295_CLK_EN_BASE + 17) +#define RTD1295_CLK_EN_DCU (RTD1295_CLK_EN_BASE + 18) +#define RTD1295_CLK_EN_CP (RTD1295_CLK_EN_BASE + 19) +#define RTD1295_CLK_EN_MD (RTD1295_CLK_EN_BASE + 20) +#define RTD1295_CLK_EN_TP (RTD1295_CLK_EN_BASE + 21) +#define RTD1295_CLK_EN_RSA (RTD1295_CLK_EN_BASE + 22) +#define RTD1295_CLK_EN_NF (RTD1295_CLK_EN_BASE + 23) +#define RTD1295_CLK_EN_EMMC (RTD1295_CLK_EN_BASE + 24) +#define RTD1295_CLK_EN_CR (RTD1295_CLK_EN_BASE + 25) +#define RTD1295_CLK_EN_SDIO_IP (RTD1295_CLK_EN_BASE + 26) +#define RTD1295_CLK_EN_MIPI (RTD1295_CLK_EN_BASE + 27) +#define RTD1295_CLK_EN_EMMC_IP (RTD1295_CLK_EN_BASE + 28) +#define RTD1295_CLK_EN_VE3 (RTD1295_CLK_EN_BASE + 29) +#define RTD1295_CLK_EN_SDIO (RTD1295_CLK_EN_BASE + 30) +#define RTD1295_CLK_EN_SD_IP (RTD1295_CLK_EN_BASE + 31) + +#define RTD1295_CLK_EN_BASE2 (RTD1295_CLK_EN_BASE + 32) +#define RTD1295_CLK_EN_NAT (RTD1295_CLK_EN_BASE2 + 0) +#define RTD1295_CLK_EN_MISC_I2C_5 (RTD1295_CLK_EN_BASE2 + 1) +#define RTD1295_CLK_EN_SCPU (RTD1295_CLK_EN_BASE2 + 2) +#define RTD1295_CLK_EN_JPEG (RTD1295_CLK_EN_BASE2 + 3) +#define RTD1295_CLK_EN_APU (RTD1295_CLK_EN_BASE2 + 4) +#define RTD1295_CLK_EN_PCIE1 (RTD1295_CLK_EN_BASE2 + 5) +#define RTD1295_CLK_EN_MISC_SC (RTD1295_CLK_EN_BASE2 + 6) +#define RTD1295_CLK_EN_CBUS_TX (RTD1295_CLK_EN_BASE2 + 7) +#define RTD1295_CLK_EN_MISC_RTC (RTD1295_CLK_EN_BASE2 + 10) +#define RTD1295_CLK_EN_MISC_I2C_4 (RTD1295_CLK_EN_BASE2 + 13) +#define RTD1295_CLK_EN_MISC_I2C_3 (RTD1295_CLK_EN_BASE2 + 14) +#define RTD1295_CLK_EN_MISC_I2C_2 (RTD1295_CLK_EN_BASE2 + 15) +#define RTD1295_CLK_EN_MISC_I2C_1 (RTD1295_CLK_EN_BASE2 + 16) +#define RTD1295_CLK_EN_AIO_AU_CODEC (RTD1295_CLK_EN_BASE2 + 17) +#define RTD1295_CLK_EN_AIO_MOD (RTD1295_CLK_EN_BASE2 + 18) +#define RTD1295_CLK_EN_AIO_DA (RTD1295_CLK_EN_BASE2 + 19) +#define RTD1295_CLK_EN_AIO_HDMI (RTD1295_CLK_EN_BASE2 + 20) +#define RTD1295_CLK_EN_AIO_SPDIF (RTD1295_CLK_EN_BASE2 + 21) +#define RTD1295_CLK_EN_AIO_I2S (RTD1295_CLK_EN_BASE2 + 22) +#define RTD1295_CLK_EN_AIO_MCLK (RTD1295_CLK_EN_BASE2 + 23) +#define RTD1295_CLK_EN_HDMIRX (RTD1295_CLK_EN_BASE2 + 24) +#define RTD1295_CLK_EN_SATA_1 (RTD1295_CLK_EN_BASE2 + 25) +#define RTD1295_CLK_EN_SATA_ALIVE_1 (RTD1295_CLK_EN_BASE2 + 26) +#define RTD1295_CLK_EN_UR2 (RTD1295_CLK_EN_BASE2 + 27) +#define RTD1295_CLK_EN_UR1 (RTD1295_CLK_EN_BASE2 + 28) +#define RTD1295_CLK_EN_FAN (RTD1295_CLK_EN_BASE2 + 29) +#define RTD1295_CLK_EN_DCPHY_0 (RTD1295_CLK_EN_BASE2 + 30) +#define RTD1295_CLK_EN_DCPHY_1 (RTD1295_CLK_EN_BASE2 + 31) + +#define RTD1295_ISO_CLK_EN_MISC_CEC0 2 +#define RTD1295_ISO_CLK_EN_CBUSRX_SYS 3 +#define RTD1295_ISO_CLK_EN_CBUSTX_SYS 4 +#define RTD1295_ISO_CLK_EN_CBUS_SYS 5 +#define RTD1295_ISO_CLK_EN_CBUS_OSC 6 +#define RTD1295_ISO_CLK_EN_MISC_IR 7 +#define RTD1295_ISO_CLK_EN_MISC_UR0 8 +#define RTD1295_ISO_CLK_EN_I2C_0 9 +#define RTD1295_ISO_CLK_EN_I2C_1 10 +#define RTD1295_ISO_CLK_EN_ETN_250M 11 +#define RTD1295_ISO_CLK_EN_ETN_SYS 12 + +#endif -- 2.12.3 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFC 1/4] dt-bindings: clock: Add Realtek RTD1295 2017-08-17 11:20 ` [RFC 1/4] dt-bindings: clock: Add Realtek RTD1295 Andreas Färber @ 2017-08-22 2:21 ` Rob Herring 0 siblings, 0 replies; 6+ messages in thread From: Rob Herring @ 2017-08-22 2:21 UTC (permalink / raw) To: Andreas Färber Cc: Michael Turquette, Stephen Boyd, linux-clk, linux-arm-kernel, linux-kernel, Roc He, 蒋丽琴, Mark Rutland, devicetree On Thu, Aug 17, 2017 at 01:20:22PM +0200, Andreas Färber wrote: > Naming inspired from Zidoo X9S Device Tree and clk_summary. > > Signed-off-by: Andreas Färber <afaerber@suse.de> > --- > .../devicetree/bindings/clock/realtek,rtd129x.txt | 20 +++++ > include/dt-bindings/clock/realtek,rtd1295.h | 99 ++++++++++++++++++++++ > 2 files changed, 119 insertions(+) > create mode 100644 Documentation/devicetree/bindings/clock/realtek,rtd129x.txt > create mode 100644 include/dt-bindings/clock/realtek,rtd1295.h Acked-by: Rob Herring <robh@kernel.org> ^ permalink raw reply [flat|nested] 6+ messages in thread
* [RFC 2/4] arm64: dts: realtek: Add clock nodes for RTD1295 2017-08-17 11:20 [RFC 0/4] arm64: Realtek RTD1295 clocks Andreas Färber 2017-08-17 11:20 ` [RFC 1/4] dt-bindings: clock: Add Realtek RTD1295 Andreas Färber @ 2017-08-17 11:20 ` Andreas Färber 2017-08-17 11:20 ` [RFC 3/4] clk: Add Realtek RTD1295 Andreas Färber 2017-08-17 11:20 ` [RFC 4/4] arm64: dts: realtek: Update RTD1295 UART nodes with clocks Andreas Färber 3 siblings, 0 replies; 6+ messages in thread From: Andreas Färber @ 2017-08-17 11:20 UTC (permalink / raw) To: Michael Turquette, Stephen Boyd, linux-clk, linux-arm-kernel Cc: linux-kernel, Roc He, 蒋丽琴, Andreas Färber, Rob Herring, Mark Rutland, Catalin Marinas, Will Deacon, devicetree Add 27 MHz oscillator and two clock controller nodes. Signed-off-by: Andreas Färber <afaerber@suse.de> --- arch/arm64/boot/dts/realtek/rtd1295.dtsi | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/arch/arm64/boot/dts/realtek/rtd1295.dtsi b/arch/arm64/boot/dts/realtek/rtd1295.dtsi index 77063e984db9..078a11506876 100644 --- a/arch/arm64/boot/dts/realtek/rtd1295.dtsi +++ b/arch/arm64/boot/dts/realtek/rtd1295.dtsi @@ -81,6 +81,13 @@ (GIC_CPU_MASK_RAW(0xf) | IRQ_TYPE_LEVEL_LOW)>; }; + osc27M: osc { + compatible = "fixed-clock"; + clock-frequency = <27000000>; + #clock-cells = <0>; + clock-output-names = "osc27M"; + }; + soc { compatible = "simple-bus"; #address-cells = <1>; @@ -88,6 +95,13 @@ /* Exclude up to 2 GiB of RAM */ ranges = <0x80000000 0x80000000 0x80000000>; + clkc: clock-controller@98000000 { + compatible = "realtek,rtd1295-clk"; + reg = <0x98000000 0x1000>; + clocks = <&osc27M>; + #clock-cells = <1>; + }; + reset1: reset-controller@98000000 { compatible = "realtek,rtd1295-reset"; reg = <0x98000000 0x4>; @@ -112,6 +126,13 @@ #reset-cells = <1>; }; + iso_clkc: clock-controller@98007000 { + compatible = "realtek,rtd1295-iso-clk"; + reg = <0x98007000 0x100>; + clocks = <&osc27M>; + #clock-cells = <1>; + }; + iso_irq_mux: interrupt-controller@98007000 { compatible = "realtek,rtd1295-iso-irq-mux"; reg = <0x98007000 0x100>; -- 2.12.3 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [RFC 3/4] clk: Add Realtek RTD1295 2017-08-17 11:20 [RFC 0/4] arm64: Realtek RTD1295 clocks Andreas Färber 2017-08-17 11:20 ` [RFC 1/4] dt-bindings: clock: Add Realtek RTD1295 Andreas Färber 2017-08-17 11:20 ` [RFC 2/4] arm64: dts: realtek: Add clock nodes for RTD1295 Andreas Färber @ 2017-08-17 11:20 ` Andreas Färber 2017-08-17 11:20 ` [RFC 4/4] arm64: dts: realtek: Update RTD1295 UART nodes with clocks Andreas Färber 3 siblings, 0 replies; 6+ messages in thread From: Andreas Färber @ 2017-08-17 11:20 UTC (permalink / raw) To: Michael Turquette, Stephen Boyd, linux-clk, linux-arm-kernel Cc: linux-kernel, Roc He, 蒋丽琴, Andreas Färber Add two clock controller drivers for RTD1295. Clock names are taken from vendor DT and clk_summary where possible. Clock rate calculations are guesses derived from Android register values and resulting rates in clk_summary. Clock gate parents are mostly unknown - osc27M is chosen for UART baudrate. Signed-off-by: Andreas Färber <afaerber@suse.de> --- drivers/clk/Kconfig | 7 + drivers/clk/Makefile | 1 + drivers/clk/clk-rtd1295.c | 385 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 393 insertions(+) create mode 100644 drivers/clk/clk-rtd1295.c diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index a874b72612d0..8e4534912f51 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -209,6 +209,13 @@ config COMMON_CLK_OXNAS ---help--- Support for the OXNAS SoC Family clocks. +config CLK_RTD129X + bool "Clock driver for the Realtek RTD129x SoC family" + default ARCH_REALTEK && ARM64 + depends on (ARCH_REALTEK && ARM64) || COMPILE_TEST + ---help--- + Support for the Realtek RTD1295 SoC. + config COMMON_CLK_VC5 tristate "Clock driver for IDT VersaClock 5,6 devices" depends on I2C diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index cd376b3fb47a..466965452d4f 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_COMMON_CLK_PALMAS) += clk-palmas.o obj-$(CONFIG_COMMON_CLK_PWM) += clk-pwm.o obj-$(CONFIG_CLK_QORIQ) += clk-qoriq.o obj-$(CONFIG_COMMON_CLK_RK808) += clk-rk808.o +obj-$(CONFIG_CLK_RTD129X) += clk-rtd1295.o obj-$(CONFIG_COMMON_CLK_HI655X) += clk-hi655x.o obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o obj-$(CONFIG_COMMON_CLK_SCPI) += clk-scpi.o diff --git a/drivers/clk/clk-rtd1295.c b/drivers/clk/clk-rtd1295.c new file mode 100644 index 000000000000..a20e71460dac --- /dev/null +++ b/drivers/clk/clk-rtd1295.c @@ -0,0 +1,385 @@ +/* + * Realtek RTD1295 + * + * Copyright (c) 2017 Andreas Färber + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <dt-bindings/clock/realtek,rtd1295.h> +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/slab.h> + +struct rtd_pll_clk { + struct clk_hw hw; + void __iomem *base; + bool gpu; +}; + +#define to_pll_clk(_hw) container_of(_hw, struct rtd_pll_clk, hw) + +static unsigned long rtd_scpu_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + struct rtd_pll_clk *pll = to_pll_clk(hw); + u32 reg1, reg2, reg3, reg4; + unsigned f1, f2, f3, f4, f5; + unsigned long rate, frac; + + reg1 = readl(pll->base + 0x4); + reg2 = readl(pll->base - (0x500 - 0x30)); + reg3 = readl(pll->base + 0x0); + reg4 = readl(pll->base + 0x1c); + f1 = (reg1 >> 11) & 0xff; + f2 = (reg1 >> 0) & 0x7ff; + f3 = (reg2 >> 7) & 0x3; + f4 = (reg3 >> 0) & 0x1; + f5 = (reg4 >> 20) & 0x1; + + rate = parent_rate * (f1 + 3) / f3; + frac = parent_rate / 2048 * f2 / BIT(f4); + rate += frac; + + pr_info("%s 0x%08x n=%u f=%u 0x%08x x=%u 0x%08x y=%u 0x%08x z=%u rate=%lu\n", + __clk_get_name(hw->clk), + reg1, f1, f2, + reg2, f3, + reg3, f4, + reg4, f5, rate); + return rate; +} + +static const struct clk_ops rtd_scpu_ops = { + .recalc_rate = rtd_scpu_recalc_rate, +}; + +static struct clk *rtd_scpu(void __iomem *base, const char *name, struct clk *parent) +{ + struct rtd_pll_clk *pll; + struct clk_init_data init; + struct clk *clk; + const char *parents[1]; + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) + return ERR_PTR(-ENOMEM); + + if (parent) + parents[0] = __clk_get_name(parent); + init.name = name; + init.ops = &rtd_scpu_ops; + init.parent_names = parent ? parents : NULL; + init.num_parents = parent ? 1 : 0; + init.flags = CLK_IGNORE_UNUSED; + + pll->hw.init = &init; + pll->base = base; + + clk = clk_register(NULL, &pll->hw); + if (IS_ERR(clk)) { + pr_err("%s: error registering clk", name); + kfree(pll); + } + return clk; +} + +static unsigned long rtd_nf_ssc_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + struct rtd_pll_clk *pll = to_pll_clk(hw); + u32 reg1, reg2, reg3; + unsigned f1, f2, f3, f4; + unsigned long rate, frac; + + reg1 = readl(pll->base + 0x4); + reg2 = readl(pll->base + 0x0); + reg3 = readl(pll->base + 0x1c); + f1 = (reg1 >> 11) & 0xff; + f2 = (reg1 >> 0) & 0x7ff; + f3 = (reg2 >> 0) & 0xf; + f4 = (reg3 >> 20) & 0x1; + + rate = parent_rate * (f1 + 3); + if (pll->gpu) { + rate /= 2; + } + frac = parent_rate * 4 * f2 / BIT(f3); + if (pll->gpu) { + frac /= 2; + } + rate += frac; + + pr_info("%s 0x%08x n=%u f=%u 0x%08x d=%u 0x%08x x=%u rate=%lu\n", __clk_get_name(hw->clk), + reg1, f1, f2, + reg2, f3, + reg3, f4, rate); + return rate; +} + +static const struct clk_ops rtd_nf_ssc_ops = { + .recalc_rate = rtd_nf_ssc_recalc_rate, +}; + +static struct clk *rtd_nf_ssc(void __iomem *base, const char *name, struct clk *parent) +{ + struct rtd_pll_clk *pll; + struct clk_init_data init; + struct clk *clk; + const char *parents[1]; + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) + return ERR_PTR(-ENOMEM); + + if (parent) + parents[0] = __clk_get_name(parent); + init.name = name; + init.ops = &rtd_nf_ssc_ops; + init.parent_names = parent ? parents : NULL; + init.num_parents = parent ? 1 : 0; + init.flags = CLK_IGNORE_UNUSED; + + pll->hw.init = &init; + pll->base = base; + pll->gpu = (strcmp(name, "pll_gpu") == 0); + + clk = clk_register(NULL, &pll->hw); + if (IS_ERR(clk)) { + pr_err("%s: error registering clk", name); + kfree(pll); + } + return clk; +} + +static unsigned long rtd_mno_ctrl_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + struct rtd_pll_clk *pll = to_pll_clk(hw); + u32 reg1, reg2; + unsigned f1, f2, f3; + unsigned long rate; + + reg1 = readl(pll->base + 0x0); + reg2 = readl(pll->base + 0x4); + f1 = (reg1 >> 4) & 0xff; + f2 = (reg1 >> 12) & 0x3; + f3 = (reg1 >> 17) & 0x3; + + rate = parent_rate * (f1 + 2) / (f2 +1) / (f3 + 1); + + pr_info("%s 0x%08x m=%u n=%u o=%u 0x%08x rate=%lu\n", __clk_get_name(hw->clk), + reg1, f1, f2, f3, + reg2, rate); + return rate; +} + +static const struct clk_ops rtd_mno_ctrl_ops = { + .recalc_rate = rtd_mno_ctrl_recalc_rate, +}; + +static struct clk *rtd_mno_ctrl(void __iomem *base, const char *name, struct clk *parent) +{ + struct rtd_pll_clk *pll; + struct clk_init_data init; + struct clk *clk; + const char *parents[1]; + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) + return ERR_PTR(-ENOMEM); + + if (parent) + parents[0] = __clk_get_name(parent); + init.name = name; + init.ops = &rtd_mno_ctrl_ops; + init.parent_names = parent ? parents : NULL; + init.num_parents = parent ? 1 : 0; + init.flags = CLK_IGNORE_UNUSED; + + pll->hw.init = &init; + pll->base = base; + + clk = clk_register(NULL, &pll->hw); + if (IS_ERR(clk)) { + pr_err("%s: error registering clk", name); + kfree(pll); + } + return clk; +} + +static const char * const rtd1295_gates1[32] = { + [ 0] = "clk_en_misc", + [ 1] = "clk_en_pcie0", + [ 2] = "clk_en_sata_0", + [ 3] = "clk_en_gspi", + [ 4] = "clk_en_usb", + [ 5] = "clk_en_pcr", + [ 6] = "clk_en_iso_misc", + [ 7] = "clk_en_sata_alive_0", + [ 8] = "clk_en_hdmi", + [ 9] = "clk_en_etn", + [10] = "clk_en_aio", + /* "*clk_en_gpu", */ + /* "*clk_en_ve1", */ + /* "*clk_en_ve2", */ + [14] = "clk_en_tve", + /* "*clk_en_vo", */ + [16] = "clk_en_lvds", + [17] = "clk_en_se", + [18] = "clk_en_dcu", + [19] = "clk_en_cp", + [20] = "clk_en_md", + [21] = "clk_en_tp", + [22] = "clk_en_rsa", + [23] = "clk_en_nf", + [24] = "clk_en_emmc", + [25] = "clk_en_cr", + [26] = "clk_en_sdio_ip", + [27] = "clk_en_mipi", + [28] = "clk_en_emmc_ip", + /* "*clk_en_ve3", */ + [30] = "clk_en_sdio", + [31] = "clk_en_sd_ip", +}; + +static const char * const rtd1295_gates2[32] = { + [ 0] = "clk_en_nat", + [ 1] = "clk_en_misc_i2c_5", + /* "*clk_en_scpu", */ + [ 3] = "clk_en_jpeg", + /* "*clk_en_apu", */ + [ 5] = "clk_en_pcie1", + [ 6] = "clk_en_misc_sc", + [ 7] = "clk_en_cbus_tx", + /* "*rvd", */ + /* "*rvd", */ + [10] = "clk_en_misc_rtc", + /* "*rvd", */ + /* "*rvd", */ + [13] = "clk_en_misc_i2c_4", + [14] = "clk_en_misc_i2c_3", + [15] = "clk_en_misc_i2c_2", + [16] = "clk_en_misc_i2c_1", + [17] = "clk_en_aio_au_codec", + [18] = "clk_en_aio_mod", + [19] = "clk_en_aio_da", + [20] = "clk_en_aio_hdmi", + [21] = "clk_en_aio_spdif", + [22] = "clk_en_aio_i2s", + [23] = "clk_en_aio_mclk", + [24] = "clk_en_hdmirx", + [25] = "clk_en_sata_1", + [26] = "clk_en_sata_alive_1", + [27] = "clk_en_ur2", + [28] = "clk_en_ur1", + [29] = "clk_en_fan", + [30] = "clk_en_dcphy_0", + [31] = "clk_en_dcphy_1", +}; + +static struct clk *clks[16 + 2 * 32] = {}; + +static struct clk_onecell_data rtd_clks = { + .clks = clks, + .clk_num = ARRAY_SIZE(clks), +}; + +static void __init rtd1295_clk_init(struct device_node *node) +{ + void __iomem *base; + struct clk *osc; + int i; + static const char *clk_sys_parents[2] = { "pll_bus", "pll_bus_div2" }; + static const char *clk_ve_parents[4] = { "clk_sysh", "pll_ve1", "pll_ve2", "pll_ve2" }; + + base = of_iomap(node, 0); + + osc = of_clk_get(node, 0); + + clks[RTD1295_CLK_PLL_SCPU] = rtd_scpu(base + 0x500, "pll_scpu", osc); + clks[RTD1295_CLK_PLL_BUS] = rtd_nf_ssc(base + 0x520, "pll_bus", osc); + clks[RTD1295_CLK_PLL_BUS_DIV2] = clk_register_fixed_factor(NULL, "pll_bus_div2", "pll_bus", 0, 1, 2); + clks[RTD1295_CLK_SYS] = clk_register_mux(NULL, "clk_sys", clk_sys_parents, 2, 0, base + 0x30, 0, 1, CLK_MUX_READ_ONLY, NULL); + clks[RTD1295_CLK_PLL_BUS_H] = rtd_nf_ssc(base + 0x540, "pll_bus_h", osc); + clks[RTD1295_CLK_SYSH] = clk_register_fixed_factor(NULL, "clk_sysh", "pll_bus_h", 0, 1, 1); + clks[RTD1295_CLK_PLL_DDSA] = rtd_nf_ssc(base + 0x560, "pll_ddsa", osc); + clks[RTD1295_CLK_PLL_DDSB] = rtd_nf_ssc(base + 0x580, "pll_ddsb", osc); + clks[RTD1295_CLK_PLL_VODMA] = rtd_mno_ctrl(base + 0x260, "pll_vodma", osc); + clk_register_fixed_factor(NULL, "clk_vodma", "pll_vodma", 0, 1, 1); + clks[RTD1295_CLK_EN_VO] = clk_register_gate(NULL, "clk_en_vo", "clk_vodma", CLK_IGNORE_UNUSED, base + 0xc, 15, 0, NULL); + clks[RTD1295_CLK_PLL_VE1] = rtd_mno_ctrl(base + 0x114, "pll_ve1", osc); + clks[RTD1295_CLK_PLL_VE2] = rtd_mno_ctrl(base + 0x1d0, "pll_ve2", osc); + clk_register_mux(NULL, "clk_ve1", clk_ve_parents, 4, 0, base + 0x4c, 0, 2, CLK_MUX_READ_ONLY, NULL); + clks[RTD1295_CLK_EN_VE1] = clk_register_gate(NULL, "clk_en_ve1", "clk_ve1", CLK_IGNORE_UNUSED, base + 0xc, 12, 0, NULL); + clk_register_mux(NULL, "clk_ve2", clk_ve_parents, 4, 0, base + 0x4c, 2, 2, CLK_MUX_READ_ONLY, NULL); + clks[RTD1295_CLK_EN_VE2] = clk_register_gate(NULL, "clk_en_ve2", "clk_ve2", CLK_IGNORE_UNUSED, base + 0xc, 13, 0, NULL); + clk_register_mux(NULL, "clk_ve3", clk_ve_parents, 4, 0, base + 0x4c, 4, 2, CLK_MUX_READ_ONLY, NULL); + clks[RTD1295_CLK_EN_VE3] = clk_register_gate(NULL, "clk_en_ve3", "clk_ve3", CLK_IGNORE_UNUSED, base + 0xc, 29, 0, NULL); + clks[RTD1295_CLK_PLL_GPU] = rtd_nf_ssc(base + 0x5a0, "pll_gpu", osc); + clk_register_fixed_factor(NULL, "clk_gpu", "pll_gpu", 0, 1, 1); + clks[RTD1295_CLK_EN_GPU] = clk_register_gate(NULL, "clk_en_gpu", "clk_gpu", CLK_IGNORE_UNUSED, base + 0xc, 11, 0, NULL); + clks[RTD1295_CLK_PLL_ACPU] = rtd_nf_ssc(base + 0x5c0, "pll_acpu", osc); + + for (i = 0; i < ARRAY_SIZE(rtd1295_gates1); i++) { + if (!rtd1295_gates1[i]) + continue; + clks[RTD1295_CLK_EN_BASE + i] = clk_register_gate(NULL, rtd1295_gates1[i], NULL, CLK_IGNORE_UNUSED, base + 0xc, i, 0, NULL); + } + + for (i = 0; i < ARRAY_SIZE(rtd1295_gates2); i++) { + if (!rtd1295_gates2[i]) + continue; + clks[RTD1295_CLK_EN_BASE2 + i] = clk_register_gate(NULL, rtd1295_gates2[i], __clk_get_name(osc), CLK_IGNORE_UNUSED, base + 0x10, i, 0, NULL); + } + + clk_put(osc); + + of_clk_add_provider(node, of_clk_src_onecell_get, &rtd_clks); +} +CLK_OF_DECLARE(rtd1295, "realtek,rtd1295-clk", rtd1295_clk_init); + +static const char * const rtd1295_iso_gates[13] = { + /* "*unused", */ + /* "*rvd", */ + [ 2] = "clk_en_misc_cec0", + [ 3] = "clk_en_cbusrx_sys", + [ 4] = "clk_en_cbustx_sys", + [ 5] = "clk_en_cbus_sys", + [ 6] = "clk_en_cbus_osc", + [ 7] = "clk_en_misc_ir", + [ 8] = "clk_en_misc_ur0", + [ 9] = "clk_en_i2c0", + [10] = "clk_en_i2c1", + [11] = "clk_en_etn_250m", + [12] = "clk_en_etn_sys", +}; + +static struct clk *iso_clks[13] = {}; + +static struct clk_onecell_data rtd_iso_clks = { + .clks = iso_clks, + .clk_num = ARRAY_SIZE(iso_clks), +}; + +static void __init rtd1295_iso_clk_init(struct device_node *node) +{ + void __iomem *base; + struct clk *osc; + int i; + + base = of_iomap(node, 0); + + osc = of_clk_get(node, 0); + + for (i = 0; i < ARRAY_SIZE(rtd1295_iso_gates); i++) { + if (!rtd1295_iso_gates[i]) + continue; + iso_clks[i] = clk_register_gate(NULL, rtd1295_iso_gates[i], __clk_get_name(osc), CLK_IGNORE_UNUSED, base + 0x8c, i, 0, NULL); + } + + clk_put(osc); + + of_clk_add_provider(node, of_clk_src_onecell_get, &rtd_iso_clks); +} +CLK_OF_DECLARE(rtd1295_iso, "realtek,rtd1295-iso-clk", rtd1295_iso_clk_init); -- 2.12.3 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [RFC 4/4] arm64: dts: realtek: Update RTD1295 UART nodes with clocks 2017-08-17 11:20 [RFC 0/4] arm64: Realtek RTD1295 clocks Andreas Färber ` (2 preceding siblings ...) 2017-08-17 11:20 ` [RFC 3/4] clk: Add Realtek RTD1295 Andreas Färber @ 2017-08-17 11:20 ` Andreas Färber 3 siblings, 0 replies; 6+ messages in thread From: Andreas Färber @ 2017-08-17 11:20 UTC (permalink / raw) To: Michael Turquette, Stephen Boyd, linux-clk, linux-arm-kernel Cc: linux-kernel, Roc He, 蒋丽琴, Andreas Färber, Rob Herring, Mark Rutland, Catalin Marinas, Will Deacon, devicetree Replace clock-frequency with a reference to the respective clock gates. Signed-off-by: Andreas Färber <afaerber@suse.de> --- arch/arm64/boot/dts/realtek/rtd1295.dtsi | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/realtek/rtd1295.dtsi b/arch/arm64/boot/dts/realtek/rtd1295.dtsi index 078a11506876..503e2d5fc334 100644 --- a/arch/arm64/boot/dts/realtek/rtd1295.dtsi +++ b/arch/arm64/boot/dts/realtek/rtd1295.dtsi @@ -6,6 +6,7 @@ * SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +#include <dt-bindings/clock/realtek,rtd1295.h> #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/reset/realtek,rtd1295.h> @@ -152,7 +153,7 @@ reg = <0x98007800 0x400>; reg-shift = <2>; reg-io-width = <4>; - clock-frequency = <27000000>; + clocks = <&iso_clkc RTD1295_ISO_CLK_EN_MISC_UR0>; interrupt-parent = <&iso_irq_mux>; interrupts = <2>; resets = <&iso_reset RTD1295_ISO_RSTN_UR0>; @@ -172,7 +173,7 @@ reg = <0x9801b200 0x100>; reg-shift = <2>; reg-io-width = <4>; - clock-frequency = <432000000>; + clocks = <&clkc RTD1295_CLK_EN_UR1>; interrupt-parent = <&irq_mux>; interrupts = <3>, <5>; resets = <&reset2 RTD1295_RSTN_UR1>; @@ -184,7 +185,7 @@ reg = <0x9801b400 0x100>; reg-shift = <2>; reg-io-width = <4>; - clock-frequency = <432000000>; + clocks = <&clkc RTD1295_CLK_EN_UR2>; interrupt-parent = <&irq_mux>; interrupts = <8>, <13>; resets = <&reset2 RTD1295_RSTN_UR2>; -- 2.12.3 ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2017-08-22 2:21 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2017-08-17 11:20 [RFC 0/4] arm64: Realtek RTD1295 clocks Andreas Färber 2017-08-17 11:20 ` [RFC 1/4] dt-bindings: clock: Add Realtek RTD1295 Andreas Färber 2017-08-22 2:21 ` Rob Herring 2017-08-17 11:20 ` [RFC 2/4] arm64: dts: realtek: Add clock nodes for RTD1295 Andreas Färber 2017-08-17 11:20 ` [RFC 3/4] clk: Add Realtek RTD1295 Andreas Färber 2017-08-17 11:20 ` [RFC 4/4] arm64: dts: realtek: Update RTD1295 UART nodes with clocks Andreas Färber
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®