All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/2] Add eMMC phase clock support for Hi3798CV200
@ 2018-03-05  7:01 Shawn Guo
  2018-03-05  7:01 ` [PATCH v2 1/2] clk: hisilicon: add hisi phase clock support Shawn Guo
  2018-03-05  7:01 ` [PATCH v2 2/2] clk: hi3798cv200: add emmc sample and drive clock Shawn Guo
  0 siblings, 2 replies; 4+ messages in thread
From: Shawn Guo @ 2018-03-05  7:01 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Michael Turquette, Jiancheng Xue, Jianguo Sun, linux-clk, Shawn Guo

Hi Stephen,

The series adds a phase clock type for eMMC support on Hi3798CV200 SoC.
It has a few updates on the first version posted by Jiancheng [1] as
below.

Changes for v2:
 - Rebase to v4.16-rc.
 - Use SPDX-License-Identifier.
 - Coding-style fixes and indentation improvements.
 - Make hisi_phase_clock resource managed, so that unregister function
   calls for this clock can be completely saved.
 - Name phase clock fields degrees vs. regvals to make them more
   explicit.
 - Add .get_phase function support.

[1] https://lkml.org/lkml/2017/10/17/1207

tianshuliang (2):
  clk: hisilicon: add hisi phase clock support
  clk: hi3798cv200: add emmc sample and drive clock

 drivers/clk/hisilicon/Makefile          |   2 +-
 drivers/clk/hisilicon/clk-hisi-phase.c  | 121 ++++++++++++++++++++++++++++++++
 drivers/clk/hisilicon/clk.c             |  24 +++++++
 drivers/clk/hisilicon/clk.h             |  19 +++++
 drivers/clk/hisilicon/crg-hi3798cv200.c |  20 ++++++
 5 files changed, 185 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/hisilicon/clk-hisi-phase.c

-- 
1.9.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v2 1/2] clk: hisilicon: add hisi phase clock support
  2018-03-05  7:01 [PATCH v2 0/2] Add eMMC phase clock support for Hi3798CV200 Shawn Guo
@ 2018-03-05  7:01 ` Shawn Guo
  2018-03-12  7:56   ` Shawn Guo
  2018-03-05  7:01 ` [PATCH v2 2/2] clk: hi3798cv200: add emmc sample and drive clock Shawn Guo
  1 sibling, 1 reply; 4+ messages in thread
From: Shawn Guo @ 2018-03-05  7:01 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Michael Turquette, Jiancheng Xue, Jianguo Sun, linux-clk, tianshuliang

From: tianshuliang <tianshuliang@hisilicon.com>

Add a phase clock type for HiSilicon SoCs,which supports
clk_set_phase operation.

Signed-off-by: tianshuliang <tianshuliang@hisilicon.com>
Signed-off-by: Jiancheng Xue <xuejiancheng@hisilicon.com>
---
 drivers/clk/hisilicon/Makefile         |   2 +-
 drivers/clk/hisilicon/clk-hisi-phase.c | 121 +++++++++++++++++++++++++++++++++
 drivers/clk/hisilicon/clk.c            |  24 +++++++
 drivers/clk/hisilicon/clk.h            |  19 ++++++
 4 files changed, 165 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/hisilicon/clk-hisi-phase.c

diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile
index 4806fc2cb4ac..2a714c0f9657 100644
--- a/drivers/clk/hisilicon/Makefile
+++ b/drivers/clk/hisilicon/Makefile
@@ -3,7 +3,7 @@
 # Hisilicon Clock specific Makefile
 #
 
-obj-y	+= clk.o clkgate-separated.o clkdivider-hi6220.o
+obj-y	+= clk.o clkgate-separated.o clkdivider-hi6220.o clk-hisi-phase.o
 
 obj-$(CONFIG_ARCH_HI3xxx)	+= clk-hi3620.o
 obj-$(CONFIG_ARCH_HIP04)	+= clk-hip04.o
diff --git a/drivers/clk/hisilicon/clk-hisi-phase.c b/drivers/clk/hisilicon/clk-hisi-phase.c
new file mode 100644
index 000000000000..42ce157ff828
--- /dev/null
+++ b/drivers/clk/hisilicon/clk-hisi-phase.c
@@ -0,0 +1,121 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2017 HiSilicon Technologies Co., Ltd.
+ *
+ * Simple HiSilicon phase clock implementation.
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "clk.h"
+
+struct clk_hisi_phase {
+	struct clk_hw	hw;
+	void __iomem	*reg;
+	u32		*phase_degrees;
+	u32		*phase_regvals;
+	u8		phase_num;
+	u32		mask;
+	u8		shift;
+	u8		flags;
+	spinlock_t	*lock;
+};
+
+#define to_clk_hisi_phase(_hw) container_of(_hw, struct clk_hisi_phase, hw)
+
+static int hisi_phase_regval_to_degrees(struct clk_hisi_phase *phase,
+					u32 regval)
+{
+	int i;
+
+	for (i = 0; i < phase->phase_num; i++)
+		if (phase->phase_regvals[i] == regval)
+			return phase->phase_degrees[i];
+
+	return -EINVAL;
+}
+
+static int hisi_clk_get_phase(struct clk_hw *hw)
+{
+	struct clk_hisi_phase *phase = to_clk_hisi_phase(hw);
+	u32 regval;
+
+	regval = readl(phase->reg);
+	regval = (regval & phase->mask) >> phase->shift;
+
+	return hisi_phase_regval_to_degrees(phase, regval);
+}
+
+static int hisi_phase_degrees_to_regval(struct clk_hisi_phase *phase,
+					int degrees)
+{
+	int i;
+
+	for (i = 0; i < phase->phase_num; i++)
+		if (phase->phase_degrees[i] == degrees)
+			return phase->phase_regvals[i];
+
+	return -EINVAL;
+}
+
+static int hisi_clk_set_phase(struct clk_hw *hw, int degrees)
+{
+	struct clk_hisi_phase *phase = to_clk_hisi_phase(hw);
+	unsigned long flags = 0;
+	int regval;
+	u32 val;
+
+	regval = hisi_phase_degrees_to_regval(phase, degrees);
+	if (regval < 0)
+		return regval;
+
+	spin_lock_irqsave(phase->lock, flags);
+
+	val = clk_readl(phase->reg);
+	val &= ~phase->mask;
+	val |= regval << phase->shift;
+	clk_writel(val, phase->reg);
+
+	spin_unlock_irqrestore(phase->lock, flags);
+
+	return 0;
+}
+
+const struct clk_ops clk_phase_ops = {
+	.get_phase = hisi_clk_get_phase,
+	.set_phase = hisi_clk_set_phase,
+};
+
+struct clk *clk_register_hisi_phase(struct device *dev,
+		const struct hisi_phase_clock *clks,
+		void __iomem *base, spinlock_t *lock)
+{
+	struct clk_hisi_phase *phase;
+	struct clk_init_data init;
+
+	phase = devm_kzalloc(dev, sizeof(struct clk_hisi_phase), GFP_KERNEL);
+	if (!phase)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = clks->name;
+	init.ops = &clk_phase_ops;
+	init.flags = clks->flags | CLK_IS_BASIC;
+	init.parent_names = clks->parent_names ? &clks->parent_names : NULL;
+	init.num_parents = clks->parent_names ? 1 : 0;
+
+	phase->reg = base + clks->offset;
+	phase->shift = clks->shift;
+	phase->mask = (BIT(clks->width) - 1) << clks->shift;
+	phase->lock = lock;
+	phase->phase_degrees = clks->phase_degrees;
+	phase->phase_regvals = clks->phase_regvals;
+	phase->phase_num = clks->phase_num;
+	phase->hw.init = &init;
+
+	return devm_clk_register(dev, &phase->hw);
+}
+EXPORT_SYMBOL_GPL(clk_register_hisi_phase);
diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c
index b73c1dfae7f1..29046b8334c2 100644
--- a/drivers/clk/hisilicon/clk.c
+++ b/drivers/clk/hisilicon/clk.c
@@ -197,6 +197,30 @@ int hisi_clk_register_mux(const struct hisi_mux_clock *clks,
 }
 EXPORT_SYMBOL_GPL(hisi_clk_register_mux);
 
+int hisi_clk_register_phase(struct device *dev,
+			    const struct hisi_phase_clock *clks,
+			    int nums, struct hisi_clock_data *data)
+{
+	void __iomem *base = data->base;
+	struct clk *clk;
+	int i;
+
+	for (i = 0; i < nums; i++) {
+		clk = clk_register_hisi_phase(dev, &clks[i], base,
+					      &hisi_clk_lock);
+		if (IS_ERR(clk)) {
+			pr_err("%s: failed to register clock %s\n", __func__,
+			       clks[i].name);
+			return PTR_ERR(clk);
+		}
+
+		data->clk_data.clks[clks[i].id] = clk;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(hisi_clk_register_phase);
+
 int hisi_clk_register_divider(const struct hisi_divider_clock *clks,
 				      int nums, struct hisi_clock_data *data)
 {
diff --git a/drivers/clk/hisilicon/clk.h b/drivers/clk/hisilicon/clk.h
index 4e1d1affc6f5..8d7ee5c3231b 100644
--- a/drivers/clk/hisilicon/clk.h
+++ b/drivers/clk/hisilicon/clk.h
@@ -68,6 +68,19 @@ struct hisi_mux_clock {
 	const char		*alias;
 };
 
+struct hisi_phase_clock {
+	unsigned int		id;
+	const char		*name;
+	const char		*parent_names;
+	unsigned long		flags;
+	unsigned long		offset;
+	u8			shift;
+	u8			width;
+	u32			*phase_degrees;
+	u32			*phase_regvals;
+	u8			phase_num;
+};
+
 struct hisi_divider_clock {
 	unsigned int		id;
 	const char		*name;
@@ -120,6 +133,12 @@ int hisi_clk_register_fixed_factor(const struct hisi_fixed_factor_clock *,
 				int, struct hisi_clock_data *);
 int hisi_clk_register_mux(const struct hisi_mux_clock *, int,
 				struct hisi_clock_data *);
+struct clk *clk_register_hisi_phase(struct device *dev,
+				const struct hisi_phase_clock *clks,
+				void __iomem *base, spinlock_t *lock);
+int hisi_clk_register_phase(struct device *dev,
+				const struct hisi_phase_clock *clks,
+				int nums, struct hisi_clock_data *data);
 int hisi_clk_register_divider(const struct hisi_divider_clock *,
 				int, struct hisi_clock_data *);
 int hisi_clk_register_gate(const struct hisi_gate_clock *,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v2 2/2] clk: hi3798cv200: add emmc sample and drive clock
  2018-03-05  7:01 [PATCH v2 0/2] Add eMMC phase clock support for Hi3798CV200 Shawn Guo
  2018-03-05  7:01 ` [PATCH v2 1/2] clk: hisilicon: add hisi phase clock support Shawn Guo
@ 2018-03-05  7:01 ` Shawn Guo
  1 sibling, 0 replies; 4+ messages in thread
From: Shawn Guo @ 2018-03-05  7:01 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Michael Turquette, Jiancheng Xue, Jianguo Sun, linux-clk,
	tianshuliang, Shawn Guo

From: tianshuliang <tianshuliang@hisilicon.com>

It adds eMMC sample clock HISTB_MMC_SAMPLE_CLK and drive clock
HISTB_MMC_DRV_CLK support for Hi3798cv200 SoC.

Signed-off-by: tianshuliang <tianshuliang@hisilicon.com>
Signed-off-by: Jiancheng Xue <xuejiancheng@hisilicon.com>
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 drivers/clk/hisilicon/crg-hi3798cv200.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/clk/hisilicon/crg-hi3798cv200.c b/drivers/clk/hisilicon/crg-hi3798cv200.c
index d6e3971bac9e..743eec131528 100644
--- a/drivers/clk/hisilicon/crg-hi3798cv200.c
+++ b/drivers/clk/hisilicon/crg-hi3798cv200.c
@@ -97,6 +97,18 @@
 		0x9c, 8, 2, 0, sdio_mux_table, },
 };
 
+static u32 mmc_phase_regvals[] = {0, 1, 2, 3, 4, 5, 6, 7};
+static u32 mmc_phase_degrees[] = {0, 45, 90, 135, 180, 225, 270, 315};
+
+static struct hisi_phase_clock hi3798cv200_phase_clks[] = {
+	{ HISTB_MMC_SAMPLE_CLK, "mmc_sample", "clk_mmc_ciu",
+		CLK_SET_RATE_PARENT, 0xa0, 12, 3, mmc_phase_degrees,
+		mmc_phase_regvals, ARRAY_SIZE(mmc_phase_regvals) },
+	{ HISTB_MMC_DRV_CLK, "mmc_drive", "clk_mmc_ciu",
+		CLK_SET_RATE_PARENT, 0xa0, 16, 3, mmc_phase_degrees,
+		mmc_phase_regvals, ARRAY_SIZE(mmc_phase_regvals) },
+};
+
 static const struct hisi_gate_clock hi3798cv200_gate_clks[] = {
 	/* UART */
 	{ HISTB_UART2_CLK, "clk_uart2", "75m",
@@ -186,6 +198,14 @@ static struct hisi_clock_data *hi3798cv200_clk_register(
 	if (!clk_data)
 		return ERR_PTR(-ENOMEM);
 
+	/* hisi_phase_clock is resource managed */
+	ret = hisi_clk_register_phase(&pdev->dev,
+				hi3798cv200_phase_clks,
+				ARRAY_SIZE(hi3798cv200_phase_clks),
+				clk_data);
+	if (ret)
+		return ERR_PTR(ret);
+
 	ret = hisi_clk_register_fixed_rate(hi3798cv200_fixed_rate_clks,
 				     ARRAY_SIZE(hi3798cv200_fixed_rate_clks),
 				     clk_data);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v2 1/2] clk: hisilicon: add hisi phase clock support
  2018-03-05  7:01 ` [PATCH v2 1/2] clk: hisilicon: add hisi phase clock support Shawn Guo
@ 2018-03-12  7:56   ` Shawn Guo
  0 siblings, 0 replies; 4+ messages in thread
From: Shawn Guo @ 2018-03-12  7:56 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Michael Turquette, Jiancheng Xue, Jianguo Sun, linux-clk, tianshuliang

Hi Stephen,

On Mon, Mar 05, 2018 at 03:01:31PM +0800, Shawn Guo wrote:
> From: tianshuliang <tianshuliang@hisilicon.com>
> 
> Add a phase clock type for HiSilicon SoCs,which supports
> clk_set_phase operation.
> 
> Signed-off-by: tianshuliang <tianshuliang@hisilicon.com>
> Signed-off-by: Jiancheng Xue <xuejiancheng@hisilicon.com>

It misses the SoB of myself.  I will add it and include these two
patches into the PR sent to you.

Shawn

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2018-03-12  7:56 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-05  7:01 [PATCH v2 0/2] Add eMMC phase clock support for Hi3798CV200 Shawn Guo
2018-03-05  7:01 ` [PATCH v2 1/2] clk: hisilicon: add hisi phase clock support Shawn Guo
2018-03-12  7:56   ` Shawn Guo
2018-03-05  7:01 ` [PATCH v2 2/2] clk: hi3798cv200: add emmc sample and drive clock Shawn Guo

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.