* [PATCH v5 0/3] clk: meson: add a sub EMMC clock controller support
@ 2018-10-18 5:07 Jianxin Pan
2018-10-18 5:07 ` [PATCH v5 1/3] clk: meson: add emmc sub clock phase delay driver Jianxin Pan
0 siblings, 1 reply; 5+ messages in thread
From: Jianxin Pan @ 2018-10-18 5:07 UTC (permalink / raw)
To: Jerome Brunet, Neil Armstrong
Cc: Jianxin Pan, Kevin Hilman, Carlo Caione, Michael Turquette,
Stephen Boyd, Rob Herring, Miquel Raynal, Boris Brezillon,
Martin Blumenstingl, Yixun Lan, Liang Yang, Jian Hu, Qiufang Dai,
Hanjie Lin, Victor Wan, linux-clk, linux-amlogic,
linux-arm-kernel, linux-kernel, devicetree
This driver will add a MMC clock controller driver support.
The original idea about adding a clock controller is during the
discussion in the NAND driver mainline effort[1].
This driver is tested in the S400 board (AXG platform) with NAND driver.
Changes since v4 [5]:
- use struct parm in phase delay driver
- remove 0 delay releted part in phase delay driver
- don't rebuild the parent name once again
- add divider ops with .init
Changes since v3 [4]:
- separate clk-phase-delay driver
- replace clk_get_rate() with clk_hw_get_rate()
- collect Rob's R-Y
- drop 'meson-' prefix from compatible string
Changes since v2 [3]:
- squash dt-binding clock-id patch
- update license
- fix alignment
- construct a clk register helper() function
Changes since v1 [2]:
- implement phase clock
- update compatible name
- adjust file name
- divider probe() into small functions, and re-use them
[1] https://lkml.kernel.org/r/20180628090034.0637a062@xps13
[2] https://lkml.kernel.org/r/20180703145716.31860-1-yixun.lan@amlogic.com
[3] https://lkml.kernel.org/r/20180710163658.6175-1-yixun.lan@amlogic.com
[4] https://lkml.kernel.org/r/20180712211244.11428-1-yixun.lan@amlogic.com
[5] https://lkml.kernel.org/r/20180809070724.11935-4-yixun.lan@amlogic.com
Yixun Lan (3):
clk: meson: add emmc sub clock phase delay driver
clk: meson: add DT documentation for emmc clock controller
clk: meson: add sub MMC clock controller driver
.../devicetree/bindings/clock/amlogic,mmc-clkc.txt | 31 +++
drivers/clk/meson/Kconfig | 10 +
drivers/clk/meson/Makefile | 3 +-
drivers/clk/meson/clk-phase-delay.c | 79 ++++++
drivers/clk/meson/clk-regmap.c | 27 +-
drivers/clk/meson/clk-regmap.h | 1 +
drivers/clk/meson/clkc.h | 13 +
drivers/clk/meson/mmc-clkc.c | 296 +++++++++++++++++++++
include/dt-bindings/clock/amlogic,mmc-clkc.h | 17 ++
9 files changed, 475 insertions(+), 2 deletions(-)
create mode 100644 Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.txt
create mode 100644 drivers/clk/meson/clk-phase-delay.c
create mode 100644 drivers/clk/meson/mmc-clkc.c
create mode 100644 include/dt-bindings/clock/amlogic,mmc-clkc.h
--
1.9.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v5 1/3] clk: meson: add emmc sub clock phase delay driver
2018-10-18 5:07 [PATCH v5 0/3] clk: meson: add a sub EMMC clock controller support Jianxin Pan
@ 2018-10-18 5:07 ` Jianxin Pan
2018-10-18 17:14 ` Stephen Boyd
2018-10-24 8:58 ` Jerome Brunet
0 siblings, 2 replies; 5+ messages in thread
From: Jianxin Pan @ 2018-10-18 5:07 UTC (permalink / raw)
To: Jerome Brunet, Neil Armstrong
Cc: Yixun Lan, Jianxin Pan, Kevin Hilman, Carlo Caione,
Michael Turquette, Stephen Boyd, Rob Herring, Miquel Raynal,
Boris Brezillon, Martin Blumenstingl, Liang Yang, Jian Hu,
Qiufang Dai, Hanjie Lin, Victor Wan, linux-clk, linux-amlogic,
linux-arm-kernel, linux-kernel, devicetree
From: Yixun Lan <yixun.lan@amlogic.com>
Export the emmc sub clock phase delay ops which will be used
by the emmc sub clock driver itself.
Signed-off-by: Yixun Lan <yixun.lan@amlogic.com>
Signed-off-by: Jianxin Pan <jianxin.pan@amlogic.com>
---
drivers/clk/meson/Makefile | 2 +-
drivers/clk/meson/clk-phase-delay.c | 79 +++++++++++++++++++++++++++++++++++++
drivers/clk/meson/clkc.h | 13 ++++++
3 files changed, 93 insertions(+), 1 deletion(-)
create mode 100644 drivers/clk/meson/clk-phase-delay.c
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index 72ec8c4..39ce566 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -2,7 +2,7 @@
# Makefile for Meson specific clk
#
-obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o clk-phase.o
+obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o clk-phase.o clk-phase-delay.o
obj-$(CONFIG_COMMON_CLK_AMLOGIC_AUDIO) += clk-triphase.o sclk-div.o
obj-$(CONFIG_COMMON_CLK_MESON_AO) += meson-aoclk.o
obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o
diff --git a/drivers/clk/meson/clk-phase-delay.c b/drivers/clk/meson/clk-phase-delay.c
new file mode 100644
index 0000000..b9573a7
--- /dev/null
+++ b/drivers/clk/meson/clk-phase-delay.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Amlogic Meson MMC Sub Clock Controller Driver
+ *
+ * Copyright (c) 2017 Baylibre SAS.
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
+ *
+ * Copyright (c) 2018 Amlogic, inc.
+ * Author: Yixun Lan <yixun.lan@amlogic.com>
+ */
+
+#include <linux/clk-provider.h>
+#include "clkc.h"
+
+static int meson_clk_phase_delay_get_phase(struct clk_hw *hw)
+{
+ struct clk_regmap *clk = to_clk_regmap(hw);
+ struct meson_clk_phase_delay_data *ph =
+ meson_clk_get_phase_delay_data(clk);
+ unsigned long period_ps, p, d;
+ int degrees;
+ u32 val;
+
+ regmap_read(clk->map, ph->phase.reg_off, &val);
+ p = PARM_GET(ph->phase.width, ph->phase.shift, val);
+ degrees = p * 360 / (1 << (ph->phase.width));
+
+ period_ps = DIV_ROUND_UP((unsigned long)NSEC_PER_SEC * 1000,
+ clk_hw_get_rate(hw));
+
+ d = PARM_GET(ph->delay.width, ph->delay.shift, val);
+ degrees += d * ph->delay_step_ps * 360 / period_ps;
+ degrees %= 360;
+
+ return degrees;
+}
+
+static void meson_clk_apply_phase_delay(struct clk_regmap *clk,
+ unsigned int phase,
+ unsigned int delay)
+{
+ struct meson_clk_phase_delay_data *ph = clk->data;
+ u32 val;
+
+ regmap_read(clk->map, ph->delay.reg_off, &val);
+ val = PARM_SET(ph->phase.width, ph->phase.shift, val, phase);
+ val = PARM_SET(ph->delay.width, ph->delay.shift, val, delay);
+ regmap_write(clk->map, ph->delay.reg_off, val);
+}
+
+static int meson_clk_phase_delay_set_phase(struct clk_hw *hw, int degrees)
+{
+ struct clk_regmap *clk = to_clk_regmap(hw);
+ struct meson_clk_phase_delay_data *ph =
+ meson_clk_get_phase_delay_data(clk);
+ unsigned long period_ps, d = 0, r;
+ u64 p;
+
+ p = degrees % 360;
+ period_ps = DIV_ROUND_UP((unsigned long)NSEC_PER_SEC * 1000,
+ clk_hw_get_rate(hw));
+
+ /* First compute the phase index (p), the remainder (r) is the
+ * part we'll try to acheive using the delays (d).
+ */
+ r = do_div(p, 360 / (1 << (ph->phase.width)));
+ d = DIV_ROUND_CLOSEST(r * period_ps,
+ 360 * ph->delay_step_ps);
+ d = min(d, PMASK(ph->delay.width));
+
+ meson_clk_apply_phase_delay(clk, p, d);
+ return 0;
+}
+
+const struct clk_ops meson_clk_phase_delay_ops = {
+ .get_phase = meson_clk_phase_delay_get_phase,
+ .set_phase = meson_clk_phase_delay_set_phase,
+};
+EXPORT_SYMBOL_GPL(meson_clk_phase_delay_ops);
diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h
index 6b96d55..3309d78 100644
--- a/drivers/clk/meson/clkc.h
+++ b/drivers/clk/meson/clkc.h
@@ -105,6 +105,18 @@ struct clk_regmap _name = { \
}, \
};
+struct meson_clk_phase_delay_data {
+ struct parm phase;
+ struct parm delay;
+ unsigned int delay_step_ps;
+};
+
+static inline struct meson_clk_phase_delay_data *
+meson_clk_get_phase_delay_data(struct clk_regmap *clk)
+{
+ return (struct meson_clk_phase_delay_data *)clk->data;
+}
+
/* clk_ops */
extern const struct clk_ops meson_clk_pll_ro_ops;
extern const struct clk_ops meson_clk_pll_ops;
@@ -112,5 +124,6 @@ struct clk_regmap _name = { \
extern const struct clk_ops meson_clk_mpll_ro_ops;
extern const struct clk_ops meson_clk_mpll_ops;
extern const struct clk_ops meson_clk_phase_ops;
+extern const struct clk_ops meson_clk_phase_delay_ops;
#endif /* __CLKC_H */
--
1.9.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v5 1/3] clk: meson: add emmc sub clock phase delay driver
2018-10-18 5:07 ` [PATCH v5 1/3] clk: meson: add emmc sub clock phase delay driver Jianxin Pan
@ 2018-10-18 17:14 ` Stephen Boyd
2018-10-24 8:58 ` Jerome Brunet
1 sibling, 0 replies; 5+ messages in thread
From: Stephen Boyd @ 2018-10-18 17:14 UTC (permalink / raw)
To: Jerome Brunet, Neil Armstrong
Cc: Yixun Lan, Jianxin Pan, Kevin Hilman, Carlo Caione,
Michael Turquette, Rob Herring, Miquel Raynal, Boris Brezillon,
Martin Blumenstingl, Liang Yang, Jian Hu, Qiufang Dai, Hanjie Lin,
Victor Wan, linux-clk, linux-amlogic, linux-arm-kernel,
linux-kernel, devicetree
Quoting Jianxin Pan (2018-10-17 22:07:23)
> diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h
> index 6b96d55..3309d78 100644
> --- a/drivers/clk/meson/clkc.h
> +++ b/drivers/clk/meson/clkc.h
> @@ -105,6 +105,18 @@ struct clk_regmap _name = { \
> }, \
> };
>
> +struct meson_clk_phase_delay_data {
> + struct parm phase;
> + struct parm delay;
> + unsigned int delay_step_ps;
> +};
> +
> +static inline struct meson_clk_phase_delay_data *
> +meson_clk_get_phase_delay_data(struct clk_regmap *clk)
> +{
> + return (struct meson_clk_phase_delay_data *)clk->data;
Is data a void *? If so, please drop the useless cast.
> +}
> +
> /* clk_ops */
> extern const struct clk_ops meson_clk_pll_ro_ops;
> extern const struct clk_ops meson_clk_pll_ops;
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v5 1/3] clk: meson: add emmc sub clock phase delay driver
2018-10-18 5:07 ` [PATCH v5 1/3] clk: meson: add emmc sub clock phase delay driver Jianxin Pan
2018-10-18 17:14 ` Stephen Boyd
@ 2018-10-24 8:58 ` Jerome Brunet
2018-10-24 10:57 ` Jianxin Pan
1 sibling, 1 reply; 5+ messages in thread
From: Jerome Brunet @ 2018-10-24 8:58 UTC (permalink / raw)
To: Jianxin Pan, Neil Armstrong
Cc: Yixun Lan, Kevin Hilman, Carlo Caione, Michael Turquette,
Stephen Boyd, Rob Herring, Miquel Raynal, Boris Brezillon,
Martin Blumenstingl, Liang Yang, Jian Hu, Qiufang Dai, Hanjie Lin,
Victor Wan, linux-clk, linux-amlogic, linux-arm-kernel,
linux-kernel, devicetree
On Thu, 2018-10-18 at 13:07 +0800, Jianxin Pan wrote:
> From: Yixun Lan <yixun.lan@amlogic.com>
>
> Export the emmc sub clock phase delay ops which will be used
> by the emmc sub clock driver itself.
>
> Signed-off-by: Yixun Lan <yixun.lan@amlogic.com>
> Signed-off-by: Jianxin Pan <jianxin.pan@amlogic.com>
> ---
> drivers/clk/meson/Makefile | 2 +-
> drivers/clk/meson/clk-phase-delay.c | 79 +++++++++++++++++++++++++++++++++++++
> drivers/clk/meson/clkc.h | 13 ++++++
> 3 files changed, 93 insertions(+), 1 deletion(-)
> create mode 100644 drivers/clk/meson/clk-phase-delay.c
>
> diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
> index 72ec8c4..39ce566 100644
> --- a/drivers/clk/meson/Makefile
> +++ b/drivers/clk/meson/Makefile
> @@ -2,7 +2,7 @@
> # Makefile for Meson specific clk
> #
>
> -obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o clk-phase.o
> +obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o clk-phase.o clk-phase-delay.o
> obj-$(CONFIG_COMMON_CLK_AMLOGIC_AUDIO) += clk-triphase.o sclk-div.o
> obj-$(CONFIG_COMMON_CLK_MESON_AO) += meson-aoclk.o
> obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o
> diff --git a/drivers/clk/meson/clk-phase-delay.c b/drivers/clk/meson/clk-phase-delay.c
> new file mode 100644
> index 0000000..b9573a7
> --- /dev/null
> +++ b/drivers/clk/meson/clk-phase-delay.c
> @@ -0,0 +1,79 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Amlogic Meson MMC Sub Clock Controller Driver
> + *
> + * Copyright (c) 2017 Baylibre SAS.
> + * Author: Jerome Brunet <jbrunet@baylibre.com>
> + *
> + * Copyright (c) 2018 Amlogic, inc.
> + * Author: Yixun Lan <yixun.lan@amlogic.com>
> + */
> +
> +#include <linux/clk-provider.h>
> +#include "clkc.h"
> +
> +static int meson_clk_phase_delay_get_phase(struct clk_hw *hw)
> +{
> + struct clk_regmap *clk = to_clk_regmap(hw);
> + struct meson_clk_phase_delay_data *ph =
> + meson_clk_get_phase_delay_data(clk);
> + unsigned long period_ps, p, d;
> + int degrees;
> + u32 val;
> +
> + regmap_read(clk->map, ph->phase.reg_off, &val);
> + p = PARM_GET(ph->phase.width, ph->phase.shift, val);
there is an helper for this: meson_parm_read()
> + degrees = p * 360 / (1 << (ph->phase.width));
> +
> + period_ps = DIV_ROUND_UP((unsigned long)NSEC_PER_SEC * 1000,
> + clk_hw_get_rate(hw));
> +
> + d = PARM_GET(ph->delay.width, ph->delay.shift, val);
> + degrees += d * ph->delay_step_ps * 360 / period_ps;
> + degrees %= 360;
> +
> + return degrees;
> +}
> +
> +static void meson_clk_apply_phase_delay(struct clk_regmap *clk,
> + unsigned int phase,
> + unsigned int delay)
This helper function is a bit overkill.
simply call meson_parm_write() twice in meson_clk_phase_delay_set_phase().
> +{
> + struct meson_clk_phase_delay_data *ph = clk->data;
> + u32 val;
> +
> + regmap_read(clk->map, ph->delay.reg_off, &val);
> + val = PARM_SET(ph->phase.width, ph->phase.shift, val, phase);
> + val = PARM_SET(ph->delay.width, ph->delay.shift, val, delay);
> + regmap_write(clk->map, ph->delay.reg_off, val);
> +}
> +
> +static int meson_clk_phase_delay_set_phase(struct clk_hw *hw, int degrees)
> +{
> + struct clk_regmap *clk = to_clk_regmap(hw);
> + struct meson_clk_phase_delay_data *ph =
> + meson_clk_get_phase_delay_data(clk);
> + unsigned long period_ps, d = 0, r;
> + u64 p;
> +
> + p = degrees % 360;
> + period_ps = DIV_ROUND_UP((unsigned long)NSEC_PER_SEC * 1000,
> + clk_hw_get_rate(hw));
> +
> + /* First compute the phase index (p), the remainder (r) is the
> + * part we'll try to acheive using the delays (d).
> + */
> + r = do_div(p, 360 / (1 << (ph->phase.width)));
> + d = DIV_ROUND_CLOSEST(r * period_ps,
> + 360 * ph->delay_step_ps);
> + d = min(d, PMASK(ph->delay.width));
> +
> + meson_clk_apply_phase_delay(clk, p, d);
> + return 0;
> +}
> +
> +const struct clk_ops meson_clk_phase_delay_ops = {
> + .get_phase = meson_clk_phase_delay_get_phase,
> + .set_phase = meson_clk_phase_delay_set_phase,
> +};
> +EXPORT_SYMBOL_GPL(meson_clk_phase_delay_ops);
> diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h
> index 6b96d55..3309d78 100644
> --- a/drivers/clk/meson/clkc.h
> +++ b/drivers/clk/meson/clkc.h
> @@ -105,6 +105,18 @@ struct clk_regmap _name = { \
> }, \
> };
>
> +struct meson_clk_phase_delay_data {
> + struct parm phase;
> + struct parm delay;
> + unsigned int delay_step_ps;
> +};
> +
> +static inline struct meson_clk_phase_delay_data *
> +meson_clk_get_phase_delay_data(struct clk_regmap *clk)
> +{
> + return (struct meson_clk_phase_delay_data *)clk->data;
> +}
> +
> /* clk_ops */
> extern const struct clk_ops meson_clk_pll_ro_ops;
> extern const struct clk_ops meson_clk_pll_ops;
> @@ -112,5 +124,6 @@ struct clk_regmap _name = { \
> extern const struct clk_ops meson_clk_mpll_ro_ops;
> extern const struct clk_ops meson_clk_mpll_ops;
> extern const struct clk_ops meson_clk_phase_ops;
> +extern const struct clk_ops meson_clk_phase_delay_ops;
>
> #endif /* __CLKC_H */
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v5 1/3] clk: meson: add emmc sub clock phase delay driver
2018-10-24 8:58 ` Jerome Brunet
@ 2018-10-24 10:57 ` Jianxin Pan
0 siblings, 0 replies; 5+ messages in thread
From: Jianxin Pan @ 2018-10-24 10:57 UTC (permalink / raw)
To: Jerome Brunet, Neil Armstrong
Cc: Yixun Lan, Kevin Hilman, Carlo Caione, Michael Turquette,
Stephen Boyd, Rob Herring, Miquel Raynal, Boris Brezillon,
Martin Blumenstingl, Liang Yang, Jian Hu, Qiufang Dai, Hanjie Lin,
Victor Wan, linux-clk, linux-amlogic, linux-arm-kernel,
linux-kernel, devicetree
On 2018/10/24 16:58, Jerome Brunet wrote:
> On Thu, 2018-10-18 at 13:07 +0800, Jianxin Pan wrote:
>> From: Yixun Lan <yixun.lan@amlogic.com>
[...]
>>
>> --- /dev/null
>> +++ b/drivers/clk/meson/clk-phase-delay.c
>> @@ -0,0 +1,79 @@
>> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
>> +/*
>> + * Amlogic Meson MMC Sub Clock Controller Driver
>> + *
>> + * Copyright (c) 2017 Baylibre SAS.
>> + * Author: Jerome Brunet <jbrunet@baylibre.com>
>> + *
>> + * Copyright (c) 2018 Amlogic, inc.
>> + * Author: Yixun Lan <yixun.lan@amlogic.com>
>> + */
>> +
>> +#include <linux/clk-provider.h>
>> +#include "clkc.h"
>> +
>> +static int meson_clk_phase_delay_get_phase(struct clk_hw *hw)
>> +{
>> + struct clk_regmap *clk = to_clk_regmap(hw);
>> + struct meson_clk_phase_delay_data *ph =
>> + meson_clk_get_phase_delay_data(clk);
>> + unsigned long period_ps, p, d;
>> + int degrees;
>> + u32 val;
>> +
>> + regmap_read(clk->map, ph->phase.reg_off, &val);
>> + p = PARM_GET(ph->phase.width, ph->phase.shift, val);
>
> there is an helper for this: meson_parm_read()
OK. I will use meson_parm_read instead. Thanks for your review.
The result of regmap_read is shared by two PARM_GETs: phase and delay.
There will be one more register read when change to meson_parm_read, but I don't think it matters.
>
>> + degrees = p * 360 / (1 << (ph->phase.width));
>> +
>> + period_ps = DIV_ROUND_UP((unsigned long)NSEC_PER_SEC * 1000,
>> + clk_hw_get_rate(hw));
>> +
>> + d = PARM_GET(ph->delay.width, ph->delay.shift, val);
>> + degrees += d * ph->delay_step_ps * 360 / period_ps;
>> + degrees %= 360;
>> +
>> + return degrees;
>> +}
>> +
>> +static void meson_clk_apply_phase_delay(struct clk_regmap *clk,
>> + unsigned int phase,
>> + unsigned int delay)
>
> This helper function is a bit overkill.
> simply call meson_parm_write() twice in meson_clk_phase_delay_set_phase().
OK. I will use meson_parm_write() instead.
With meson_parm_write(), there will be one more register read and write
>
>> +{
>> + struct meson_clk_phase_delay_data *ph = clk->data;
>> + u32 val;
>> +
>> + regmap_read(clk->map, ph->delay.reg_off, &val);
>> + val = PARM_SET(ph->phase.width, ph->phase.shift, val, phase);
>> + val = PARM_SET(ph->delay.width, ph->delay.shift, val, delay);
>> + regmap_write(clk->map, ph->delay.reg_off, val);
>> +}
>> +
>> +static int meson_clk_phase_delay_set_phase(struct clk_hw *hw, int degrees)
>> +{
>> + struct clk_regmap *clk = to_clk_regmap(hw);
>> + struct meson_clk_phase_delay_data *ph =
>> + meson_clk_get_phase_delay_data(clk);
>> + unsigned long period_ps, d = 0, r;
>> + u64 p;
>> +
>> + p = degrees % 360;
>> + period_ps = DIV_ROUND_UP((unsigned long)NSEC_PER_SEC * 1000,
>> + clk_hw_get_rate(hw));
>> +
>> + /* First compute the phase index (p), the remainder (r) is the
>> + * part we'll try to acheive using the delays (d).
>> + */
>> + r = do_div(p, 360 / (1 << (ph->phase.width)));
>> + d = DIV_ROUND_CLOSEST(r * period_ps,
>> + 360 * ph->delay_step_ps);
>> + d = min(d, PMASK(ph->delay.width));
>> +
>> + meson_clk_apply_phase_delay(clk, p, d);
>> + return 0;
>> +}
>> +
>> +const struct clk_ops meson_clk_phase_delay_ops = {
>> + .get_phase = meson_clk_phase_delay_get_phase,
>> + .set_phase = meson_clk_phase_delay_set_phase,
>> +};
>> +EXPORT_SYMBOL_GPL(meson_clk_phase_delay_ops);
>> diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h
>> index 6b96d55..3309d78 100644
>> --- a/drivers/clk/meson/clkc.h
>> +++ b/drivers/clk/meson/clkc.h
>> @@ -105,6 +105,18 @@ struct clk_regmap _name = { \
>> }, \
>> };
>>
>> +struct meson_clk_phase_delay_data {
>> + struct parm phase;
>> + struct parm delay;
>> + unsigned int delay_step_ps;
>> +};
>> +
>> +static inline struct meson_clk_phase_delay_data *
>> +meson_clk_get_phase_delay_data(struct clk_regmap *clk)
>> +{
>> + return (struct meson_clk_phase_delay_data *)clk->data;
>> +}
>> +
>> /* clk_ops */
>> extern const struct clk_ops meson_clk_pll_ro_ops;
>> extern const struct clk_ops meson_clk_pll_ops;
>> @@ -112,5 +124,6 @@ struct clk_regmap _name = { \
>> extern const struct clk_ops meson_clk_mpll_ro_ops;
>> extern const struct clk_ops meson_clk_mpll_ops;
>> extern const struct clk_ops meson_clk_phase_ops;
>> +extern const struct clk_ops meson_clk_phase_delay_ops;
>>
>> #endif /* __CLKC_H */
>
>
> .
>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2018-10-24 10:57 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-10-18 5:07 [PATCH v5 0/3] clk: meson: add a sub EMMC clock controller support Jianxin Pan
2018-10-18 5:07 ` [PATCH v5 1/3] clk: meson: add emmc sub clock phase delay driver Jianxin Pan
2018-10-18 17:14 ` Stephen Boyd
2018-10-24 8:58 ` Jerome Brunet
2018-10-24 10:57 ` Jianxin Pan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).