public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Jagan Teki <jagan@amarulasolutions.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v4 03/17] reset: Add Allwinner RESET driver
Date: Sun, 26 Aug 2018 18:08:12 +0530	[thread overview]
Message-ID: <20180826123826.19243-4-jagan@amarulasolutions.com> (raw)
In-Reply-To: <20180826123826.19243-1-jagan@amarulasolutions.com>

Add common reset driver for all Allwinner SoC's.

Since CLK and RESET share common DT compatible, it is CLK driver
job is to bind the reset driver. So add CLK bind call on respective
SoC driver by passing ccu map descriptor so-that reset deassert,
deassert operations held based on reset register map defined by
CLK driver.

Select DM_RESET via CLK_SUNXI, this make hidden section of RESET
since CLK and RESET share common DT compatible and code.

Tested-by: Jagan Teki <jagan@amarulasolutions.com> # BPI-M64
Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
---
 arch/arm/include/asm/arch-sunxi/ccu.h |  25 ++++++
 drivers/clk/sunxi/Kconfig             |   1 +
 drivers/clk/sunxi/clk_a64.c           |  22 +++++
 drivers/reset/Kconfig                 |   8 ++
 drivers/reset/Makefile                |   1 +
 drivers/reset/reset-sunxi.c           | 125 ++++++++++++++++++++++++++
 6 files changed, 182 insertions(+)
 create mode 100644 drivers/reset/reset-sunxi.c

diff --git a/arch/arm/include/asm/arch-sunxi/ccu.h b/arch/arm/include/asm/arch-sunxi/ccu.h
index 998ab38bf2..3e322a7655 100644
--- a/arch/arm/include/asm/arch-sunxi/ccu.h
+++ b/arch/arm/include/asm/arch-sunxi/ccu.h
@@ -20,15 +20,31 @@ struct ccu_clk_map {
 	int (*ccu_clk_set_rate)(void *base, u32 bit, ulong rate);
 };
 
+/**
+ * ccu_reset_map - common clock unit reset map
+ *
+ * @off:	ccu reset offset
+ * @bit:	ccu reset bit value
+ */
+struct ccu_reset_map {
+	u16 off;
+	u32 bit;
+};
+
 /**
  * struct ccu_desc - common clock unit descriptor
  *
  * @clks:		mapping clocks descriptor
  * @num_clks:		number of mapped clocks
+ * @resets:		mapping resets descriptor
+ * @num_resets:		number of mapped resets
  */
 struct ccu_desc {
 	struct ccu_clk_map *clks;
 	unsigned long num_clks;
+
+	struct ccu_reset_map *resets;
+	unsigned long num_resets;
 };
 
 /**
@@ -44,4 +60,13 @@ struct sunxi_clk_priv {
 
 extern struct clk_ops sunxi_clk_ops;
 
+/**
+ * sunxi_reset_bind() - reset binding
+ *
+ * @dev:	reset device
+ * @count:	reset count
+ * @return 0 success, or error value
+ */
+int sunxi_reset_bind(struct udevice *dev, ulong count);
+
 #endif /* _ASM_ARCH_CCU_H */
diff --git a/drivers/clk/sunxi/Kconfig b/drivers/clk/sunxi/Kconfig
index bf5ecb3801..041d711e58 100644
--- a/drivers/clk/sunxi/Kconfig
+++ b/drivers/clk/sunxi/Kconfig
@@ -1,6 +1,7 @@
 config CLK_SUNXI
 	bool "Clock support for Allwinner SoCs"
 	depends on CLK && ARCH_SUNXI
+	select DM_RESET
 	default y
 	help
 	  This enables support for common clock driver API on Allwinner
diff --git a/drivers/clk/sunxi/clk_a64.c b/drivers/clk/sunxi/clk_a64.c
index 8966472c2d..13b58aa57f 100644
--- a/drivers/clk/sunxi/clk_a64.c
+++ b/drivers/clk/sunxi/clk_a64.c
@@ -10,6 +10,7 @@
 #include <errno.h>
 #include <asm/arch/ccu.h>
 #include <dt-bindings/clock/sun50i-a64-ccu.h>
+#include <dt-bindings/reset/sun50i-a64-ccu.h>
 
 static struct ccu_clk_map a64_clks[] = {
 	[CLK_BUS_OTG]		= { 0x060, BIT(23), NULL },
@@ -26,9 +27,24 @@ static struct ccu_clk_map a64_clks[] = {
 	[CLK_USB_OHCI1]		= { 0x0cc, BIT(17), NULL },
 };
 
+static struct ccu_reset_map a64_resets[] = {
+	[RST_USB_PHY0]		= { 0x0cc, BIT(0) },
+	[RST_USB_PHY1]		= { 0x0cc, BIT(1) },
+	[RST_USB_HSIC]		= { 0x0cc, BIT(2) },
+
+	[RST_BUS_OTG]		= { 0x2c0, BIT(23) },
+	[RST_BUS_EHCI0]		= { 0x2c0, BIT(24) },
+	[RST_BUS_EHCI1]		= { 0x2c0, BIT(25) },
+	[RST_BUS_OHCI0]		= { 0x2c0, BIT(28) },
+	[RST_BUS_OHCI1]		= { 0x2c0, BIT(29) },
+};
+
 static const struct ccu_desc sun50i_a64_ccu_desc = {
 	.clks = a64_clks,
 	.num_clks = ARRAY_SIZE(a64_clks),
+
+	.resets = a64_resets,
+	.num_resets =  ARRAY_SIZE(a64_resets),
 };
 
 static int a64_clk_probe(struct udevice *dev)
@@ -46,6 +62,11 @@ static int a64_clk_probe(struct udevice *dev)
 	return 0;
 }
 
+static int a64_clk_bind(struct udevice *dev)
+{
+	return sunxi_reset_bind(dev, 50);
+}
+
 static const struct udevice_id a64_clk_ids[] = {
 	{ .compatible = "allwinner,sun50i-a64-ccu",
 	  .data = (ulong)&sun50i_a64_ccu_desc },
@@ -59,4 +80,5 @@ U_BOOT_DRIVER(clk_sun50i_a64) = {
 	.priv_auto_alloc_size	= sizeof(struct sunxi_clk_priv),
 	.ops		= &sunxi_clk_ops,
 	.probe		= a64_clk_probe,
+	.bind		= a64_clk_bind,
 };
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 33c39b7fb6..bdc06564a0 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -98,4 +98,12 @@ config RESET_SOCFPGA
 	help
 	  Support for reset controller on SoCFPGA platform.
 
+config RESET_SUNXI
+	bool "RESET support for Allwinner SoCs"
+	depends on DM_RESET && ARCH_SUNXI
+	default y
+	help
+	  This enables support for common reset driver for
+	  Allwinner SoCs.
+
 endmenu
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index ad08be4c8c..698d15a0e0 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_AST2500_RESET) += ast2500-reset.o
 obj-$(CONFIG_RESET_ROCKCHIP) += reset-rockchip.o
 obj-$(CONFIG_RESET_MESON) += reset-meson.o
 obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
+obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
diff --git a/drivers/reset/reset-sunxi.c b/drivers/reset/reset-sunxi.c
new file mode 100644
index 0000000000..293297e98c
--- /dev/null
+++ b/drivers/reset/reset-sunxi.c
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Amarula Solutions.
+ * Author: Jagan Teki <jagan@amarulasolutions.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <reset-uclass.h>
+#include <asm/io.h>
+#include <dm/lists.h>
+#include <linux/log2.h>
+#include <asm/arch/ccu.h>
+
+struct sunxi_reset_priv {
+	void *base;
+	ulong count;
+	const struct ccu_desc *desc;
+};
+
+static int sunxi_reset_request(struct reset_ctl *reset_ctl)
+{
+	struct sunxi_reset_priv *priv = dev_get_priv(reset_ctl->dev);
+
+	debug("%s (RST#%ld)\n", __func__, reset_ctl->id);
+
+	/* check dt-bindings/reset/sun8i-h3-ccu.h for max id */
+	if (reset_ctl->id >= priv->count)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int sunxi_reset_free(struct reset_ctl *reset_ctl)
+{
+	debug("%s (RST#%ld)\n", __func__, reset_ctl->id);
+
+	return 0;
+}
+
+static int sunxi_reset_assert(struct reset_ctl *reset_ctl)
+{
+	struct sunxi_reset_priv *priv = dev_get_priv(reset_ctl->dev);
+	struct ccu_reset_map *map = &priv->desc->resets[reset_ctl->id];
+	u32 reg;
+
+	if (!map->off || !map->bit) {
+		debug("%s (RST#%ld) unhandled\n", __func__, reset_ctl->id);
+		return 0;
+	}
+
+	debug("%s(#%ld) off#0x%x, BIT(%d)\n", __func__,
+	      reset_ctl->id, map->off, ilog2(map->bit));
+
+	reg = readl(priv->base + map->off);
+	writel(reg & ~map->bit, priv->base + map->off);
+
+	return 0;
+}
+
+static int sunxi_reset_deassert(struct reset_ctl *reset_ctl)
+{
+	struct sunxi_reset_priv *priv = dev_get_priv(reset_ctl->dev);
+	struct ccu_reset_map *map = &priv->desc->resets[reset_ctl->id];
+	u32 reg;
+
+	if (!map->off || !map->bit) {
+		debug("%s (RST#%ld) unhandled\n", __func__, reset_ctl->id);
+		return 0;
+	}
+
+	debug("%s(#%ld) off#0x%x, BIT(%d)\n", __func__,
+	      reset_ctl->id, map->off, ilog2(map->bit));
+
+	reg = readl(priv->base + map->off);
+	writel(reg | map->bit, priv->base + map->off);
+
+	return 0;
+}
+
+struct reset_ops sunxi_reset_ops = {
+	.request = sunxi_reset_request,
+	.free = sunxi_reset_free,
+	.rst_assert = sunxi_reset_assert,
+	.rst_deassert = sunxi_reset_deassert,
+};
+
+static int sunxi_reset_probe(struct udevice *dev)
+{
+	struct sunxi_reset_priv *priv = dev_get_priv(dev);
+
+	priv->base = dev_read_addr_ptr(dev);
+
+	return 0;
+}
+
+int sunxi_reset_bind(struct udevice *dev, ulong count)
+{
+	struct udevice *rst_dev;
+	struct sunxi_reset_priv *priv;
+	int ret;
+
+	ret = device_bind_driver_to_node(dev, "sunxi_reset", "reset",
+					 dev_ofnode(dev), &rst_dev);
+	if (ret) {
+		debug("Warning: failed to bind sunxi_reset driver (ret=%d)\n",
+		      ret);
+		return ret;
+	}
+	priv = malloc(sizeof(struct sunxi_reset_priv));
+	priv->count = count;
+	priv->desc = (const struct ccu_desc *)dev_get_driver_data(dev);
+	rst_dev->priv = priv;
+
+	return 0;
+}
+
+U_BOOT_DRIVER(reset_sun8i_h3) = {
+	.name		= "sunxi_reset",
+	.id		= UCLASS_RESET,
+	.ops		= &sunxi_reset_ops,
+	.probe		= sunxi_reset_probe,
+	.priv_auto_alloc_size = sizeof(struct sunxi_reset_priv),
+};
-- 
2.18.0.321.gffc6fa0e3

  parent reply	other threads:[~2018-08-26 12:38 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-26 12:38 [U-Boot] [PATCH v4 00/17] clk: Add Allwinner CLK, RESET support Jagan Teki
2018-08-26 12:38 ` [U-Boot] [PATCH v4 01/17] clk: Add Allwinner A64 CLK driver Jagan Teki
2018-08-27 14:27   ` Maxime Ripard
2018-08-26 12:38 ` [U-Boot] [PATCH v4 02/17] reset: Return 0 if no request ops Jagan Teki
2018-08-30  0:28   ` Simon Glass
2018-08-26 12:38 ` Jagan Teki [this message]
2018-08-27 14:33   ` [U-Boot] [PATCH v4 03/17] reset: Add Allwinner RESET driver Maxime Ripard
2018-08-26 12:38 ` [U-Boot] [PATCH v4 04/17] clk: sunxi: Add Allwinner H3/H5 CLK driver Jagan Teki
2018-08-27 14:36   ` Maxime Ripard
2018-08-26 12:38 ` [U-Boot] [PATCH v4 05/17] clk: sunxi: Add Allwinner A10/A20 " Jagan Teki
2018-08-27 14:37   ` Maxime Ripard
2018-08-26 12:38 ` [U-Boot] [PATCH v4 06/17] clk: sunxi: Add Allwinner A10s/A13 " Jagan Teki
2018-08-27 14:38   ` Maxime Ripard
2018-08-26 12:38 ` [U-Boot] [PATCH v4 07/17] clk: sunxi: Add Allwinner A31 " Jagan Teki
2018-08-27 14:39   ` Maxime Ripard
2018-08-26 12:38 ` [U-Boot] [PATCH v4 08/17] clk: sunxi: Add Allwinner A23 " Jagan Teki
2018-08-27 14:39   ` Maxime Ripard
2018-08-26 12:38 ` [U-Boot] [PATCH v4 09/17] clk: sunxi: a23: Add CLK support for A33 Jagan Teki
2018-08-27 14:40   ` Maxime Ripard
2018-08-26 12:38 ` [U-Boot] [PATCH v4 10/17] clk: sunxi: Add Allwinner A83T CLK driver Jagan Teki
2018-08-27 14:41   ` Maxime Ripard
2018-08-26 12:38 ` [U-Boot] [PATCH v4 11/17] clk: sunxi: Add Allwinner R40 " Jagan Teki
2018-08-27 15:02   ` Maxime Ripard
2018-08-26 12:38 ` [U-Boot] [PATCH v4 12/17] clk: sunxi: Add Allwinner V3S " Jagan Teki
2018-08-27 15:02   ` Maxime Ripard
2018-08-26 12:38 ` [U-Boot] [PATCH v4 13/17] sunxi: Enable CLK Jagan Teki
2018-08-26 12:38 ` [U-Boot] [PATCH v4 14/17] phy: sun4i-usb: Use CLK and RESET support Jagan Teki
2018-08-27 15:03   ` Maxime Ripard
2018-08-26 12:38 ` [U-Boot] [PATCH v4 15/17] musb-new: sunxi: " Jagan Teki
2018-08-26 12:38 ` [U-Boot] [PATCH v4 16/17] sunxi: usb: Switch to Generic host controllers Jagan Teki
2018-08-27 15:04   ` Maxime Ripard
2018-08-26 12:38 ` [U-Boot] [PATCH v4 17/17] usb: host: Drop [e-o]hci-sunxi drivers Jagan Teki
2018-08-27 15:03   ` Maxime Ripard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180826123826.19243-4-jagan@amarulasolutions.com \
    --to=jagan@amarulasolutions.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox