diff mbox series

[18/19] clk: sunxi: add DE2 clock driver

Message ID 20210223204631.1609597-19-jernej.skrabec@siol.net
State New
Delegated to: Andre Przywara
Headers show
Series video: sunxi: Rework DE2 driver | expand

Commit Message

Jernej Škrabec Feb. 23, 2021, 8:46 p.m. UTC
Video driver currently manages clocks and resets by directly writing to
registers. This is already a bit messy because each SoC has some
specifics. It's much better to implement proper clock and reset driver
which takes information from device tree file.

Note that this driver is not perfect yet. It still sets PLL and parent
by hand. Sunxi clock framework still doesn't know how to set parents or
rates. However, this is already big step in right direction.

Cc: Lukasz Majewski <lukma@denx.de>
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/clk/sunxi/Kconfig   |  5 +++
 drivers/clk/sunxi/Makefile  |  1 +
 drivers/clk/sunxi/clk_de2.c | 85 +++++++++++++++++++++++++++++++++++++
 3 files changed, 91 insertions(+)
 create mode 100644 drivers/clk/sunxi/clk_de2.c
diff mbox series

Patch

diff --git a/drivers/clk/sunxi/Kconfig b/drivers/clk/sunxi/Kconfig
index bf084fa7a84a..6c96affb1f87 100644
--- a/drivers/clk/sunxi/Kconfig
+++ b/drivers/clk/sunxi/Kconfig
@@ -44,6 +44,11 @@  config CLK_SUN8I_A83T
 	  This enables common clock driver support for platforms based
 	  on Allwinner A83T SoC.
 
+config CLK_SUN8I_DE2
+	bool "Clock driver for Allwinner Display Engine 2 and 3"
+	help
+	  This enables common clock driver support for Display Engine 2 and 3.
+
 config CLK_SUN8I_R40
 	bool "Clock driver for Allwinner R40"
 	default MACH_SUN8I_R40
diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile
index 0dfc0593fb1c..620ff96ac6f5 100644
--- a/drivers/clk/sunxi/Makefile
+++ b/drivers/clk/sunxi/Makefile
@@ -11,6 +11,7 @@  obj-$(CONFIG_CLK_SUN5I_A10S) += clk_a10s.o
 obj-$(CONFIG_CLK_SUN6I_A31) += clk_a31.o
 obj-$(CONFIG_CLK_SUN8I_A23) += clk_a23.o
 obj-$(CONFIG_CLK_SUN8I_A83T) += clk_a83t.o
+obj-$(CONFIG_CLK_SUN8I_DE2) += clk_de2.o
 obj-$(CONFIG_CLK_SUN8I_R40) += clk_r40.o
 obj-$(CONFIG_CLK_SUN8I_V3S) += clk_v3s.o
 obj-$(CONFIG_CLK_SUN9I_A80) += clk_a80.o
diff --git a/drivers/clk/sunxi/clk_de2.c b/drivers/clk/sunxi/clk_de2.c
new file mode 100644
index 000000000000..b8c45404c1b6
--- /dev/null
+++ b/drivers/clk/sunxi/clk_de2.c
@@ -0,0 +1,85 @@ 
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2021 Jernej Skrabec <jernej.skrabec@siol.net>
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/arch/ccu.h>
+#include <asm/arch/clock.h>
+#include <asm/io.h>
+#include <dt-bindings/clock/sun8i-de2.h>
+#include <dt-bindings/reset/sun8i-de2.h>
+#include <linux/bitops.h>
+
+static struct ccu_clk_gate de2_gates[] = {
+	[CLK_MIXER0]		= GATE(0x00, BIT(0)),
+	[CLK_MIXER1]		= GATE(0x00, BIT(1)),
+	[CLK_WB]		= GATE(0x00, BIT(2)),
+
+	[CLK_BUS_MIXER0]	= GATE(0x04, BIT(0)),
+	[CLK_BUS_MIXER1]	= GATE(0x04, BIT(1)),
+	[CLK_BUS_WB]		= GATE(0x04, BIT(2)),
+};
+
+static struct ccu_reset de2_resets[] = {
+	[RST_MIXER0]		= RESET(0x08, BIT(0)),
+	[RST_MIXER1]		= RESET(0x08, BIT(1)),
+	[RST_WB]		= RESET(0x08, BIT(2)),
+};
+
+static const struct ccu_desc de2_ccu_desc = {
+	.gates = de2_gates,
+	.resets = de2_resets,
+};
+
+static int de2_clk_probe(struct udevice *dev)
+{
+	struct sunxi_ccm_reg * const ccm =
+		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+	u32 val;
+
+	if (device_is_compatible(dev_get_parent(dev),
+				 "allwinner,sun50i-a64-de2")) {
+		/* set SRAM for video use */
+		val = readl(SUNXI_SRAMC_BASE + 0x04);
+		val &= ~(0x01 << 24);
+		writel(val, SUNXI_SRAMC_BASE + 0x04);
+	}
+
+	/* clock driver doesn't know how to set rate or parent yet */
+	clock_set_pll10(432000000);
+
+	/* Set DE parent to pll10 */
+	clrsetbits_le32(&ccm->de_clk_cfg, CCM_DE2_CTRL_PLL_MASK,
+			CCM_DE2_CTRL_PLL10);
+
+	return sunxi_clk_probe(dev);
+}
+
+static int de2_clk_bind(struct udevice *dev)
+{
+	return sunxi_reset_bind(dev, ARRAY_SIZE(de2_resets));
+}
+
+static const struct udevice_id de2_ccu_ids[] = {
+	{ .compatible = "allwinner,sun8i-h3-de2-clk",
+	  .data = (ulong)&de2_ccu_desc },
+	{ .compatible = "allwinner,sun50i-a64-de2-clk",
+	  .data = (ulong)&de2_ccu_desc },
+	{ .compatible = "allwinner,sun50i-h5-de2-clk",
+	  .data = (ulong)&de2_ccu_desc },
+	{ }
+};
+
+U_BOOT_DRIVER(clk_sun8i_de2) = {
+	.name		= "sun8i_de2_ccu",
+	.id		= UCLASS_CLK,
+	.of_match	= de2_ccu_ids,
+	.priv_auto	= sizeof(struct ccu_priv),
+	.ops		= &sunxi_clk_ops,
+	.probe		= de2_clk_probe,
+	.bind		= de2_clk_bind,
+};