From: Chen-Yu Tsai <wens@csie.org> To: Maxime Ripard <maxime.ripard@free-electrons.com>, Michael Turquette <mturquette@baylibre.com>, Stephen Boyd <sboyd@codeaurora.org>, Rob Herring <robh+dt@kernel.org>, Mark Rutland <mark.rutland@arm.com> Cc: Chen-Yu Tsai <wens@csie.org>, linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, linux-sunxi@googlegroups.com Subject: [PATCH v2 3/8] clk: sunxi-ng: Add class of phase clocks supporting MMC new timing modes Date: Wed, 3 May 2017 11:09:24 +0800 [thread overview] Message-ID: <20170503030929.28763-4-wens@csie.org> (raw) In-Reply-To: <20170503030929.28763-1-wens@csie.org> The MMC clocks on newer SoCs, such as the A83T and H3, support the "new timing mode". Under this mode, the output of the clock is divided by 2, and the clock delays no longer apply. Due to how the clock tree is modeled and setup, we need to model this function in two places, the master mmc clock and the two child phase clocks. In the mmc clock, we can easily model the mode bit as an extra variable post-divider. In the phase clocks, we check the bit and return -ENOTSUPP if the bit is set, signaling that the phase clocks are not to be used. This patch introduces a class of phase clocks that checks the timing mode bit. Signed-off-by: Chen-Yu Tsai <wens@csie.org> --- drivers/clk/sunxi-ng/ccu_phase.c | 47 ++++++++++++++++++++++++++++++++++++++++ drivers/clk/sunxi-ng/ccu_phase.h | 16 ++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/drivers/clk/sunxi-ng/ccu_phase.c b/drivers/clk/sunxi-ng/ccu_phase.c index 400c58ad72fd..e6ff7551c855 100644 --- a/drivers/clk/sunxi-ng/ccu_phase.c +++ b/drivers/clk/sunxi-ng/ccu_phase.c @@ -8,6 +8,7 @@ * the License, or (at your option) any later version. */ +#include <linux/bitops.h> #include <linux/clk-provider.h> #include <linux/spinlock.h> @@ -124,3 +125,49 @@ const struct clk_ops ccu_phase_ops = { .get_phase = ccu_phase_get_phase, .set_phase = ccu_phase_set_phase, }; + +/* + * The MMC clocks on newer SoCs support the "new timing mode". Under + * this mode, the output of the clock is divided by 2, and the clock + * delays no longer apply. + * + * Due to how the clock tree is modeled and setup, we need to model + * this function in two places, the master mmc clock and the two + * child phase clocks. In the mmc clock, we can easily model the + * mode bit as an extra variable post-divider. In the phase clocks, + * we check the bit and return -ENOTSUPP if the bit is set, signaling + * that the phase clocks are not to be used. + * + * We do not support runtime configuration of the modes. Instead a + * mode is enforced at CCU probe time. + */ +#define CCU_MMC_NEW_TIMING_MODE BIT(30) + +static int ccu_phase_mmc_new_timing_get_phase(struct clk_hw *hw) +{ + struct ccu_phase *phase = hw_to_ccu_phase(hw); + u32 reg; + + reg = readl(phase->common.base + phase->common.reg); + if (reg & CCU_MMC_NEW_TIMING_MODE) + return -ENOTSUPP; + + return ccu_phase_get_phase(hw); +} + +static int ccu_phase_mmc_new_timing_set_phase(struct clk_hw *hw, int degrees) +{ + struct ccu_phase *phase = hw_to_ccu_phase(hw); + u32 reg; + + reg = readl(phase->common.base + phase->common.reg); + if (reg & CCU_MMC_NEW_TIMING_MODE) + return -ENOTSUPP; + + return ccu_phase_set_phase(hw, degrees); +} + +const struct clk_ops ccu_phase_mmc_new_timing_ops = { + .get_phase = ccu_phase_mmc_new_timing_get_phase, + .set_phase = ccu_phase_mmc_new_timing_set_phase, +}; diff --git a/drivers/clk/sunxi-ng/ccu_phase.h b/drivers/clk/sunxi-ng/ccu_phase.h index 75a091a4c565..c514d1798cdd 100644 --- a/drivers/clk/sunxi-ng/ccu_phase.h +++ b/drivers/clk/sunxi-ng/ccu_phase.h @@ -38,6 +38,20 @@ struct ccu_phase { } \ } +#define SUNXI_CCU_PHASE_MMC_NEW_TIMING(_struct, _name, _parent, _reg, \ + _shift, _width, _flags) \ + struct ccu_phase _struct = { \ + .shift = _shift, \ + .width = _width, \ + .common = { \ + .reg = _reg, \ + .hw.init = CLK_HW_INIT(_name, \ + _parent, \ + &ccu_phase_mmc_new_timing_ops, \ + _flags), \ + } \ + } + static inline struct ccu_phase *hw_to_ccu_phase(struct clk_hw *hw) { struct ccu_common *common = hw_to_ccu_common(hw); @@ -47,4 +61,6 @@ static inline struct ccu_phase *hw_to_ccu_phase(struct clk_hw *hw) extern const struct clk_ops ccu_phase_ops; +extern const struct clk_ops ccu_phase_mmc_new_timing_ops; + #endif /* _CCU_PHASE_H_ */ -- 2.11.0
WARNING: multiple messages have this Message-ID (diff)
From: wens@csie.org (Chen-Yu Tsai) To: linux-arm-kernel@lists.infradead.org Subject: [PATCH v2 3/8] clk: sunxi-ng: Add class of phase clocks supporting MMC new timing modes Date: Wed, 3 May 2017 11:09:24 +0800 [thread overview] Message-ID: <20170503030929.28763-4-wens@csie.org> (raw) In-Reply-To: <20170503030929.28763-1-wens@csie.org> The MMC clocks on newer SoCs, such as the A83T and H3, support the "new timing mode". Under this mode, the output of the clock is divided by 2, and the clock delays no longer apply. Due to how the clock tree is modeled and setup, we need to model this function in two places, the master mmc clock and the two child phase clocks. In the mmc clock, we can easily model the mode bit as an extra variable post-divider. In the phase clocks, we check the bit and return -ENOTSUPP if the bit is set, signaling that the phase clocks are not to be used. This patch introduces a class of phase clocks that checks the timing mode bit. Signed-off-by: Chen-Yu Tsai <wens@csie.org> --- drivers/clk/sunxi-ng/ccu_phase.c | 47 ++++++++++++++++++++++++++++++++++++++++ drivers/clk/sunxi-ng/ccu_phase.h | 16 ++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/drivers/clk/sunxi-ng/ccu_phase.c b/drivers/clk/sunxi-ng/ccu_phase.c index 400c58ad72fd..e6ff7551c855 100644 --- a/drivers/clk/sunxi-ng/ccu_phase.c +++ b/drivers/clk/sunxi-ng/ccu_phase.c @@ -8,6 +8,7 @@ * the License, or (at your option) any later version. */ +#include <linux/bitops.h> #include <linux/clk-provider.h> #include <linux/spinlock.h> @@ -124,3 +125,49 @@ const struct clk_ops ccu_phase_ops = { .get_phase = ccu_phase_get_phase, .set_phase = ccu_phase_set_phase, }; + +/* + * The MMC clocks on newer SoCs support the "new timing mode". Under + * this mode, the output of the clock is divided by 2, and the clock + * delays no longer apply. + * + * Due to how the clock tree is modeled and setup, we need to model + * this function in two places, the master mmc clock and the two + * child phase clocks. In the mmc clock, we can easily model the + * mode bit as an extra variable post-divider. In the phase clocks, + * we check the bit and return -ENOTSUPP if the bit is set, signaling + * that the phase clocks are not to be used. + * + * We do not support runtime configuration of the modes. Instead a + * mode is enforced at CCU probe time. + */ +#define CCU_MMC_NEW_TIMING_MODE BIT(30) + +static int ccu_phase_mmc_new_timing_get_phase(struct clk_hw *hw) +{ + struct ccu_phase *phase = hw_to_ccu_phase(hw); + u32 reg; + + reg = readl(phase->common.base + phase->common.reg); + if (reg & CCU_MMC_NEW_TIMING_MODE) + return -ENOTSUPP; + + return ccu_phase_get_phase(hw); +} + +static int ccu_phase_mmc_new_timing_set_phase(struct clk_hw *hw, int degrees) +{ + struct ccu_phase *phase = hw_to_ccu_phase(hw); + u32 reg; + + reg = readl(phase->common.base + phase->common.reg); + if (reg & CCU_MMC_NEW_TIMING_MODE) + return -ENOTSUPP; + + return ccu_phase_set_phase(hw, degrees); +} + +const struct clk_ops ccu_phase_mmc_new_timing_ops = { + .get_phase = ccu_phase_mmc_new_timing_get_phase, + .set_phase = ccu_phase_mmc_new_timing_set_phase, +}; diff --git a/drivers/clk/sunxi-ng/ccu_phase.h b/drivers/clk/sunxi-ng/ccu_phase.h index 75a091a4c565..c514d1798cdd 100644 --- a/drivers/clk/sunxi-ng/ccu_phase.h +++ b/drivers/clk/sunxi-ng/ccu_phase.h @@ -38,6 +38,20 @@ struct ccu_phase { } \ } +#define SUNXI_CCU_PHASE_MMC_NEW_TIMING(_struct, _name, _parent, _reg, \ + _shift, _width, _flags) \ + struct ccu_phase _struct = { \ + .shift = _shift, \ + .width = _width, \ + .common = { \ + .reg = _reg, \ + .hw.init = CLK_HW_INIT(_name, \ + _parent, \ + &ccu_phase_mmc_new_timing_ops, \ + _flags), \ + } \ + } + static inline struct ccu_phase *hw_to_ccu_phase(struct clk_hw *hw) { struct ccu_common *common = hw_to_ccu_common(hw); @@ -47,4 +61,6 @@ static inline struct ccu_phase *hw_to_ccu_phase(struct clk_hw *hw) extern const struct clk_ops ccu_phase_ops; +extern const struct clk_ops ccu_phase_mmc_new_timing_ops; + #endif /* _CCU_PHASE_H_ */ -- 2.11.0
next prev parent reply other threads:[~2017-05-03 3:10 UTC|newest] Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top 2017-05-03 3:09 [PATCH v2 0/8] clk: sunxi-ng: Add support for A83T CCU Chen-Yu Tsai 2017-05-03 3:09 ` Chen-Yu Tsai 2017-05-03 3:09 ` [PATCH v2 1/8] dt-bindings: clock: sunxi-ccu: Add compatible string " Chen-Yu Tsai 2017-05-03 3:09 ` Chen-Yu Tsai 2017-05-03 3:09 ` [PATCH v2 2/8] clk: Provide option to query hardware for clk phase Chen-Yu Tsai 2017-05-03 3:09 ` Chen-Yu Tsai 2017-05-03 3:09 ` Chen-Yu Tsai [this message] 2017-05-03 3:09 ` [PATCH v2 3/8] clk: sunxi-ng: Add class of phase clocks supporting MMC new timing modes Chen-Yu Tsai 2017-05-03 3:09 ` [PATCH v2 4/8] clk: sunxi-ng: Support multiple variable pre-dividers Chen-Yu Tsai 2017-05-03 3:09 ` Chen-Yu Tsai 2017-05-03 3:09 ` [PATCH v2 5/8] clk: sunxi-ng: Add driver for A83T CCU Chen-Yu Tsai 2017-05-03 3:09 ` Chen-Yu Tsai 2017-05-03 3:09 ` [PATCH v2 6/8] ARM: sun8i: a83t: Add CCU device nodes Chen-Yu Tsai 2017-05-03 3:09 ` Chen-Yu Tsai 2017-05-03 3:09 ` [PATCH v2 7/8] ARM: sun8i: a83t: Set clock accuracy for 24MHz oscillator Chen-Yu Tsai 2017-05-03 3:09 ` Chen-Yu Tsai 2017-05-03 3:09 ` [PATCH v2 8/8] ARM: sun8i: a83t: Switch to CCU device tree binding macros Chen-Yu Tsai 2017-05-03 3:09 ` Chen-Yu Tsai 2017-05-03 3:16 [PATCH v2 0/8] clk: sunxi-ng: Add support for A83T CCU Chen-Yu Tsai 2017-05-03 3:16 ` [PATCH v2 3/8] clk: sunxi-ng: Add class of phase clocks supporting MMC new timing modes Chen-Yu Tsai 2017-05-03 3:16 ` Chen-Yu Tsai 2017-05-03 3:16 ` Chen-Yu Tsai 2017-05-03 20:34 ` Maxime Ripard 2017-05-03 20:34 ` Maxime Ripard 2017-05-03 20:34 ` Maxime Ripard 2017-05-04 3:08 ` Chen-Yu Tsai 2017-05-04 3:08 ` Chen-Yu Tsai 2017-05-04 3:08 ` Chen-Yu Tsai 2017-05-05 7:58 ` Maxime Ripard 2017-05-05 7:58 ` Maxime Ripard 2017-05-05 7:58 ` 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=20170503030929.28763-4-wens@csie.org \ --to=wens@csie.org \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-clk@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-sunxi@googlegroups.com \ --cc=mark.rutland@arm.com \ --cc=maxime.ripard@free-electrons.com \ --cc=mturquette@baylibre.com \ --cc=robh+dt@kernel.org \ --cc=sboyd@codeaurora.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: linkBe 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.