All of lore.kernel.org
 help / color / mirror / Atom feed
From: heiko@sntech.de (Heiko Stübner)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v5 06/14] clk: rockchip: add reset controller
Date: Thu, 03 Jul 2014 01:59:39 +0200	[thread overview]
Message-ID: <1852259.YsR8kY9Vr2@diego> (raw)
In-Reply-To: <156042792.J76K6jxIGl@diego>

All Rockchip SoCs at least down to the ARM9-based RK28xx include the reset-
controller for SoC peripherals in their clock controller.
While the older SoCs (ARM9 and Cortex-A8) use a regular scheme to change
register values, the Cortex-A9 SoCs use a hiword-mask making locking unecessary.
To be compatible with both schemes the reset controller takes a flag to
decide which scheme to use, similar to the other HIWORD_MASK flags used in the
clock framework.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Acked-By: Max Schwarz <max.schwarz@online.de>
Tested-By: Max Schwarz <max.schwarz@online.de>
---
 drivers/clk/rockchip/Makefile  |   1 +
 drivers/clk/rockchip/clk.h     |  14 +++++
 drivers/clk/rockchip/softrst.c | 118 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 133 insertions(+)
 create mode 100644 drivers/clk/rockchip/softrst.c

diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index 2cb9164..85f8a55 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -5,3 +5,4 @@
 obj-y	+= clk-rockchip.o
 obj-y	+= clk.o
 obj-y	+= clk-pll.o
+obj-$(CONFIG_RESET_CONTROLLER)	+= softrst.o
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index fb7ce85..32c334d 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -321,4 +321,18 @@ void rockchip_clk_register_branches(struct rockchip_clk_branch *clk_list,
 void rockchip_clk_register_plls(struct rockchip_pll_clock *pll_list,
 				unsigned int nr_pll, int grf_lock_offset);
 
+#define ROCKCHIP_SOFTRST_HIWORD_MASK	BIT(0)
+
+#ifdef CONFIG_RESET_CONTROLLER
+void rockchip_register_softrst(struct device_node *np,
+			       unsigned int num_regs,
+			       void __iomem *base, u8 flags);
+#else
+static inline void rockchip_register_softrst(struct device_node *np,
+			       unsigned int num_regs,
+			       void __iomem *base, u8 flags)
+{
+}
+#endif
+
 #endif
diff --git a/drivers/clk/rockchip/softrst.c b/drivers/clk/rockchip/softrst.c
new file mode 100644
index 0000000..552f7bb
--- /dev/null
+++ b/drivers/clk/rockchip/softrst.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2014 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/reset-controller.h>
+#include <linux/spinlock.h>
+#include "clk.h"
+
+struct rockchip_softrst {
+	struct reset_controller_dev	rcdev;
+	void __iomem			*reg_base;
+	int				num_regs;
+	int				num_per_reg;
+	u8				flags;
+	spinlock_t			lock;
+};
+
+static int rockchip_softrst_assert(struct reset_controller_dev *rcdev,
+			      unsigned long id)
+{
+	struct rockchip_softrst *softrst = container_of(rcdev,
+						     struct rockchip_softrst,
+						     rcdev);
+	int bank = id / softrst->num_per_reg;
+	int offset = id % softrst->num_per_reg;
+
+	if (softrst->flags & ROCKCHIP_SOFTRST_HIWORD_MASK) {
+		writel(BIT(offset) | (BIT(offset) << 16),
+		       softrst->reg_base + (bank * 4));
+	} else {
+		unsigned long flags;
+		u32 reg;
+
+		spin_lock_irqsave(&softrst->lock, flags);
+
+		reg = readl(softrst->reg_base + (bank * 4));
+		writel(reg | BIT(offset), softrst->reg_base + (bank * 4));
+
+		spin_unlock_irqrestore(&softrst->lock, flags);
+	}
+
+	return 0;
+}
+
+static int rockchip_softrst_deassert(struct reset_controller_dev *rcdev,
+				unsigned long id)
+{
+	struct rockchip_softrst *softrst = container_of(rcdev,
+						     struct rockchip_softrst,
+						     rcdev);
+	int bank = id / softrst->num_per_reg;
+	int offset = id % softrst->num_per_reg;
+
+	if (softrst->flags & ROCKCHIP_SOFTRST_HIWORD_MASK) {
+		writel((BIT(offset) << 16), softrst->reg_base + (bank * 4));
+	} else {
+		unsigned long flags;
+		u32 reg;
+
+		spin_lock_irqsave(&softrst->lock, flags);
+
+		reg = readl(softrst->reg_base + (bank * 4));
+		writel(reg & ~BIT(offset), softrst->reg_base + (bank * 4));
+
+		spin_unlock_irqrestore(&softrst->lock, flags);
+	}
+
+	return 0;
+}
+
+static struct reset_control_ops rockchip_softrst_ops = {
+	.assert		= rockchip_softrst_assert,
+	.deassert	= rockchip_softrst_deassert,
+};
+
+void __init rockchip_register_softrst(struct device_node *np,
+				      unsigned int num_regs,
+				      void __iomem *base, u8 flags)
+{
+	struct rockchip_softrst *softrst;
+	int ret;
+
+	softrst = kzalloc(sizeof(*softrst), GFP_KERNEL);
+	if (!softrst)
+		return;
+
+	spin_lock_init(&softrst->lock);
+
+	softrst->reg_base = base;
+	softrst->flags = flags;
+	softrst->num_regs = num_regs;
+	softrst->num_per_reg = (flags & ROCKCHIP_SOFTRST_HIWORD_MASK) ? 16
+								      : 32;
+
+	softrst->rcdev.owner = THIS_MODULE;
+	softrst->rcdev.nr_resets =  num_regs * softrst->num_per_reg;
+	softrst->rcdev.ops = &rockchip_softrst_ops;
+	softrst->rcdev.of_node = np;
+	ret = reset_controller_register(&softrst->rcdev);
+	if (ret) {
+		pr_err("%s: could not register reset controller, %d\n",
+		       __func__, ret);
+		kfree(softrst);
+	}
+};
-- 
1.9.0

  parent reply	other threads:[~2014-07-02 23:59 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-02 23:53 [PATCH v5 00/14] Clock support for rk3066,rk3188 and rk3288 Heiko Stübner
2014-07-02 23:56 ` [PATCH v5 01/14] clk: composite: support determine_rate using rate_ops->round_rate + mux_ops->set_parent Heiko Stübner
2014-07-18 13:55   ` Gabriel Fernandez
2014-07-18 16:00     ` Heiko Stübner
2014-07-02 23:57 ` [PATCH v5 02/14] clk: composite: allow read-only clocks Heiko Stübner
2014-07-02 23:58 ` [PATCH v5 03/14] clk: composite: improve rate_hw sanity check logic Heiko Stübner
2014-07-02 23:58 ` [PATCH v5 04/14] clk: rockchip: add basic infrastructure for clock branches Heiko Stübner
2014-07-02 23:59 ` [PATCH v5 05/14] clk: rockchip: add clock type for pll clocks and pll used on rk3066 Heiko Stübner
2014-07-02 23:59 ` Heiko Stübner [this message]
2014-07-03  0:00 ` [PATCH v5 07/14] dt-bindings: add documentation for rk3188 clock and reset unit Heiko Stübner
2014-07-03  0:00   ` Heiko Stübner
2014-07-03  0:01 ` [PATCH v5 08/14] clk: rockchip: add clock driver for rk3188 and rk3066 clocks Heiko Stübner
2014-07-03  0:02 ` [PATCH v5 09/14] dt-bindings: add documentation for rk3288 cru Heiko Stübner
2014-07-03  0:02   ` Heiko Stübner
2014-07-03  0:02 ` [PATCH v5 10/14] clk: rockchip: add clock controller for rk3288 Heiko Stübner
2014-07-03  0:02 ` [PATCH v5 11/14] ARM: rockchip: Select ARCH_HAS_RESET_CONTROLLER Heiko Stübner
2014-07-03  0:03 ` [PATCH v5 12/14] ARM: dts: rockchip: add cru nodes and update device clocks to use it Heiko Stübner
2014-07-03  0:03 ` [PATCH v5 13/14] ARM: dts: rockchip: move oscillator input clock into main dtsi Heiko Stübner
2014-07-03  0:04 ` [PATCH v5 14/14] arm: dts: rockchip: remove obsolete clock gate definitions Heiko Stübner
2014-07-13 19:46 ` [PATCH v5 00/14] Clock support for rk3066,rk3188 and rk3288 Mike Turquette
2014-07-14  3:12   ` Olof Johansson
2014-07-14  8:07     ` Heiko Stübner
2014-07-22 15:45       ` Heiko Stübner
2014-07-24  2:44         ` Mike Turquette

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=1852259.YsR8kY9Vr2@diego \
    --to=heiko@sntech.de \
    --cc=linux-arm-kernel@lists.infradead.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.