* [PATCH 0/7] clk: meson: update clock controller for audio support
@ 2017-02-28 13:29 ` Jerome Brunet
0 siblings, 0 replies; 17+ messages in thread
From: Jerome Brunet @ 2017-02-28 13:29 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Kevin Hilman, Carlo Caione
Cc: Jerome Brunet, linux-clk, linux-amlogic, linux-kernel, devicetree
This patchset is a first round of update to the meson clock controllers
to bring audio support. The patchset is based on clk-next with two
additional patches from arm-soc next (to avoid conflict later on).
commit d356a86b1b30 ("clk: meson-gxbb: Export HDMI clocks")
commit 7d753a742127 ("clk: gxbb: add the SAR ADC clocks and expose them")
The 2 first patches of the series put the generic muxes and divisors
declaration in tables so the register address fixup works in the same way
as the clock gates. We are going to add more of these clock types for
audio or gpu support, so we can't continue to fix addresses individually
like it is currently done.
Patches 3 to 6 improve the support of the mpll clocks, now allowing the
rate to be set. Among other things, the mplls are the parent clocks of the
i2s and spdif clocks.
Patch 7 expose the clock gates required to power on the i2s output.
These patches have been tested on the meson gxbb p200 board, as part of the
ongoing work to bring audio support for meson SoC family.
Jerome Brunet (7):
clk: meson8b: put dividers and muxes in tables
clk: gxbb: put dividers and muxes in tables
clk: meson: mpll: add rw operation
clk: meson: gxbb: mpll: use rw operation
clk: meson8b: add the mplls clocks 0, 1 and 2
clk: meson: mpll: correct N2 maximum value
dt-bindings: clk: gxbb: expose i2s output clock gates
drivers/clk/meson/clk-mpll.c | 152 ++++++++++++++++++++++++++++++++--
drivers/clk/meson/clkc.h | 4 +-
drivers/clk/meson/gxbb.c | 64 +++++++++++---
drivers/clk/meson/gxbb.h | 10 +--
drivers/clk/meson/meson8b.c | 126 +++++++++++++++++++++++++++-
drivers/clk/meson/meson8b.h | 20 ++++-
include/dt-bindings/clock/gxbb-clkc.h | 5 ++
7 files changed, 354 insertions(+), 27 deletions(-)
--
2.9.3
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 0/7] clk: meson: update clock controller for audio support
@ 2017-02-28 13:29 ` Jerome Brunet
0 siblings, 0 replies; 17+ messages in thread
From: Jerome Brunet @ 2017-02-28 13:29 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Kevin Hilman, Carlo Caione
Cc: Jerome Brunet, linux-clk-u79uwXL29TY76Z2rM5mHXA,
linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
This patchset is a first round of update to the meson clock controllers
to bring audio support. The patchset is based on clk-next with two
additional patches from arm-soc next (to avoid conflict later on).
commit d356a86b1b30 ("clk: meson-gxbb: Export HDMI clocks")
commit 7d753a742127 ("clk: gxbb: add the SAR ADC clocks and expose them")
The 2 first patches of the series put the generic muxes and divisors
declaration in tables so the register address fixup works in the same way
as the clock gates. We are going to add more of these clock types for
audio or gpu support, so we can't continue to fix addresses individually
like it is currently done.
Patches 3 to 6 improve the support of the mpll clocks, now allowing the
rate to be set. Among other things, the mplls are the parent clocks of the
i2s and spdif clocks.
Patch 7 expose the clock gates required to power on the i2s output.
These patches have been tested on the meson gxbb p200 board, as part of the
ongoing work to bring audio support for meson SoC family.
Jerome Brunet (7):
clk: meson8b: put dividers and muxes in tables
clk: gxbb: put dividers and muxes in tables
clk: meson: mpll: add rw operation
clk: meson: gxbb: mpll: use rw operation
clk: meson8b: add the mplls clocks 0, 1 and 2
clk: meson: mpll: correct N2 maximum value
dt-bindings: clk: gxbb: expose i2s output clock gates
drivers/clk/meson/clk-mpll.c | 152 ++++++++++++++++++++++++++++++++--
drivers/clk/meson/clkc.h | 4 +-
drivers/clk/meson/gxbb.c | 64 +++++++++++---
drivers/clk/meson/gxbb.h | 10 +--
drivers/clk/meson/meson8b.c | 126 +++++++++++++++++++++++++++-
drivers/clk/meson/meson8b.h | 20 ++++-
include/dt-bindings/clock/gxbb-clkc.h | 5 ++
7 files changed, 354 insertions(+), 27 deletions(-)
--
2.9.3
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 0/7] clk: meson: update clock controller for audio support
@ 2017-02-28 13:29 ` Jerome Brunet
0 siblings, 0 replies; 17+ messages in thread
From: Jerome Brunet @ 2017-02-28 13:29 UTC (permalink / raw)
To: linus-amlogic
This patchset is a first round of update to the meson clock controllers
to bring audio support. The patchset is based on clk-next with two
additional patches from arm-soc next (to avoid conflict later on).
commit d356a86b1b30 ("clk: meson-gxbb: Export HDMI clocks")
commit 7d753a742127 ("clk: gxbb: add the SAR ADC clocks and expose them")
The 2 first patches of the series put the generic muxes and divisors
declaration in tables so the register address fixup works in the same way
as the clock gates. We are going to add more of these clock types for
audio or gpu support, so we can't continue to fix addresses individually
like it is currently done.
Patches 3 to 6 improve the support of the mpll clocks, now allowing the
rate to be set. Among other things, the mplls are the parent clocks of the
i2s and spdif clocks.
Patch 7 expose the clock gates required to power on the i2s output.
These patches have been tested on the meson gxbb p200 board, as part of the
ongoing work to bring audio support for meson SoC family.
Jerome Brunet (7):
clk: meson8b: put dividers and muxes in tables
clk: gxbb: put dividers and muxes in tables
clk: meson: mpll: add rw operation
clk: meson: gxbb: mpll: use rw operation
clk: meson8b: add the mplls clocks 0, 1 and 2
clk: meson: mpll: correct N2 maximum value
dt-bindings: clk: gxbb: expose i2s output clock gates
drivers/clk/meson/clk-mpll.c | 152 ++++++++++++++++++++++++++++++++--
drivers/clk/meson/clkc.h | 4 +-
drivers/clk/meson/gxbb.c | 64 +++++++++++---
drivers/clk/meson/gxbb.h | 10 +--
drivers/clk/meson/meson8b.c | 126 +++++++++++++++++++++++++++-
drivers/clk/meson/meson8b.h | 20 ++++-
include/dt-bindings/clock/gxbb-clkc.h | 5 ++
7 files changed, 354 insertions(+), 27 deletions(-)
--
2.9.3
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 1/7] clk: meson8b: put dividers and muxes in tables
2017-02-28 13:29 ` Jerome Brunet
@ 2017-02-28 13:29 ` Jerome Brunet
-1 siblings, 0 replies; 17+ messages in thread
From: Jerome Brunet @ 2017-02-28 13:29 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Kevin Hilman, Carlo Caione
Cc: Jerome Brunet, linux-clk, linux-amlogic, linux-kernel
Until now, there was only 1 divider and 1 mux declared for the meson8b
platform. With the ongoing work on various system, including audio, this
is about to change. Use the same approach as gates for dividers and muxes,
putting them in tables to fix the register address at runtime.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/clk/meson/meson8b.c | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c
index 888494d4fb8a..44c24bf754cd 100644
--- a/drivers/clk/meson/meson8b.c
+++ b/drivers/clk/meson/meson8b.c
@@ -582,6 +582,15 @@ static struct clk_gate *meson8b_clk_gates[] = {
&meson8b_ao_iface,
};
+static struct clk_mux *meson8b_clk_muxes[] = {
+ &meson8b_mpeg_clk_sel,
+};
+
+static struct clk_divider *meson8b_clk_dividers[] = {
+ &meson8b_mpeg_clk_div,
+};
+
+
static int meson8b_clkc_probe(struct platform_device *pdev)
{
void __iomem *clk_base;
@@ -604,15 +613,21 @@ static int meson8b_clkc_probe(struct platform_device *pdev)
/* Populate the base address for CPU clk */
meson8b_cpu_clk.base = clk_base;
- /* Populate the base address for the MPEG clks */
- meson8b_mpeg_clk_sel.reg = clk_base + (u32)meson8b_mpeg_clk_sel.reg;
- meson8b_mpeg_clk_div.reg = clk_base + (u32)meson8b_mpeg_clk_div.reg;
-
/* Populate base address for gates */
for (i = 0; i < ARRAY_SIZE(meson8b_clk_gates); i++)
meson8b_clk_gates[i]->reg = clk_base +
(u32)meson8b_clk_gates[i]->reg;
+ /* Populate base address for muxes */
+ for (i = 0; i < ARRAY_SIZE(meson8b_clk_muxes); i++)
+ meson8b_clk_muxes[i]->reg = clk_base +
+ (u32)meson8b_clk_muxes[i]->reg;
+
+ /* Populate base address for dividers */
+ for (i = 0; i < ARRAY_SIZE(meson8b_clk_dividers); i++)
+ meson8b_clk_dividers[i]->reg = clk_base +
+ (u32)meson8b_clk_dividers[i]->reg;
+
/*
* register all clks
* CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1
--
2.9.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 1/7] clk: meson8b: put dividers and muxes in tables
@ 2017-02-28 13:29 ` Jerome Brunet
0 siblings, 0 replies; 17+ messages in thread
From: Jerome Brunet @ 2017-02-28 13:29 UTC (permalink / raw)
To: linus-amlogic
Until now, there was only 1 divider and 1 mux declared for the meson8b
platform. With the ongoing work on various system, including audio, this
is about to change. Use the same approach as gates for dividers and muxes,
putting them in tables to fix the register address at runtime.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/clk/meson/meson8b.c | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c
index 888494d4fb8a..44c24bf754cd 100644
--- a/drivers/clk/meson/meson8b.c
+++ b/drivers/clk/meson/meson8b.c
@@ -582,6 +582,15 @@ static struct clk_gate *meson8b_clk_gates[] = {
&meson8b_ao_iface,
};
+static struct clk_mux *meson8b_clk_muxes[] = {
+ &meson8b_mpeg_clk_sel,
+};
+
+static struct clk_divider *meson8b_clk_dividers[] = {
+ &meson8b_mpeg_clk_div,
+};
+
+
static int meson8b_clkc_probe(struct platform_device *pdev)
{
void __iomem *clk_base;
@@ -604,15 +613,21 @@ static int meson8b_clkc_probe(struct platform_device *pdev)
/* Populate the base address for CPU clk */
meson8b_cpu_clk.base = clk_base;
- /* Populate the base address for the MPEG clks */
- meson8b_mpeg_clk_sel.reg = clk_base + (u32)meson8b_mpeg_clk_sel.reg;
- meson8b_mpeg_clk_div.reg = clk_base + (u32)meson8b_mpeg_clk_div.reg;
-
/* Populate base address for gates */
for (i = 0; i < ARRAY_SIZE(meson8b_clk_gates); i++)
meson8b_clk_gates[i]->reg = clk_base +
(u32)meson8b_clk_gates[i]->reg;
+ /* Populate base address for muxes */
+ for (i = 0; i < ARRAY_SIZE(meson8b_clk_muxes); i++)
+ meson8b_clk_muxes[i]->reg = clk_base +
+ (u32)meson8b_clk_muxes[i]->reg;
+
+ /* Populate base address for dividers */
+ for (i = 0; i < ARRAY_SIZE(meson8b_clk_dividers); i++)
+ meson8b_clk_dividers[i]->reg = clk_base +
+ (u32)meson8b_clk_dividers[i]->reg;
+
/*
* register all clks
* CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1
--
2.9.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 2/7] clk: gxbb: put dividers and muxes in tables
2017-02-28 13:29 ` Jerome Brunet
@ 2017-02-28 13:29 ` Jerome Brunet
-1 siblings, 0 replies; 17+ messages in thread
From: Jerome Brunet @ 2017-02-28 13:29 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Kevin Hilman, Carlo Caione
Cc: Jerome Brunet, linux-clk, linux-amlogic, linux-kernel
Until now, there was only 2 dividers and 2 muxes declared for the gxbb
platform. With the ongoing work on various subsystem, including audio,
this is about to change. Use the same approach as gates for dividers and
muxes, putting them in tables to fix the register address at runtime.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/clk/meson/gxbb.c | 28 ++++++++++++++++++++--------
1 file changed, 20 insertions(+), 8 deletions(-)
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index 1c1ec137a3cc..388b0c8838af 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -902,6 +902,16 @@ static struct clk_gate *gxbb_clk_gates[] = {
&gxbb_sar_adc_clk,
};
+static struct clk_mux *gxbb_clk_muxes[] = {
+ &gxbb_mpeg_clk_sel,
+ &gxbb_sar_adc_clk_sel,
+};
+
+static struct clk_divider *gxbb_clk_dividers[] = {
+ &gxbb_mpeg_clk_div,
+ &gxbb_sar_adc_clk_div,
+};
+
static int gxbb_clkc_probe(struct platform_device *pdev)
{
void __iomem *clk_base;
@@ -928,19 +938,21 @@ static int gxbb_clkc_probe(struct platform_device *pdev)
/* Populate the base address for CPU clk */
gxbb_cpu_clk.base = clk_base;
- /* Populate the base address for the MPEG clks */
- gxbb_mpeg_clk_sel.reg = clk_base + (u64)gxbb_mpeg_clk_sel.reg;
- gxbb_mpeg_clk_div.reg = clk_base + (u64)gxbb_mpeg_clk_div.reg;
-
- /* Populate the base address for the SAR ADC clks */
- gxbb_sar_adc_clk_sel.reg = clk_base + (u64)gxbb_sar_adc_clk_sel.reg;
- gxbb_sar_adc_clk_div.reg = clk_base + (u64)gxbb_sar_adc_clk_div.reg;
-
/* Populate base address for gates */
for (i = 0; i < ARRAY_SIZE(gxbb_clk_gates); i++)
gxbb_clk_gates[i]->reg = clk_base +
(u64)gxbb_clk_gates[i]->reg;
+ /* Populate base address for muxes */
+ for (i = 0; i < ARRAY_SIZE(gxbb_clk_muxes); i++)
+ gxbb_clk_muxes[i]->reg = clk_base +
+ (u64)gxbb_clk_muxes[i]->reg;
+
+ /* Populate base address for dividers */
+ for (i = 0; i < ARRAY_SIZE(gxbb_clk_dividers); i++)
+ gxbb_clk_dividers[i]->reg = clk_base +
+ (u64)gxbb_clk_dividers[i]->reg;
+
/*
* register all clks
*/
--
2.9.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 2/7] clk: gxbb: put dividers and muxes in tables
@ 2017-02-28 13:29 ` Jerome Brunet
0 siblings, 0 replies; 17+ messages in thread
From: Jerome Brunet @ 2017-02-28 13:29 UTC (permalink / raw)
To: linus-amlogic
Until now, there was only 2 dividers and 2 muxes declared for the gxbb
platform. With the ongoing work on various subsystem, including audio,
this is about to change. Use the same approach as gates for dividers and
muxes, putting them in tables to fix the register address at runtime.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/clk/meson/gxbb.c | 28 ++++++++++++++++++++--------
1 file changed, 20 insertions(+), 8 deletions(-)
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index 1c1ec137a3cc..388b0c8838af 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -902,6 +902,16 @@ static struct clk_gate *gxbb_clk_gates[] = {
&gxbb_sar_adc_clk,
};
+static struct clk_mux *gxbb_clk_muxes[] = {
+ &gxbb_mpeg_clk_sel,
+ &gxbb_sar_adc_clk_sel,
+};
+
+static struct clk_divider *gxbb_clk_dividers[] = {
+ &gxbb_mpeg_clk_div,
+ &gxbb_sar_adc_clk_div,
+};
+
static int gxbb_clkc_probe(struct platform_device *pdev)
{
void __iomem *clk_base;
@@ -928,19 +938,21 @@ static int gxbb_clkc_probe(struct platform_device *pdev)
/* Populate the base address for CPU clk */
gxbb_cpu_clk.base = clk_base;
- /* Populate the base address for the MPEG clks */
- gxbb_mpeg_clk_sel.reg = clk_base + (u64)gxbb_mpeg_clk_sel.reg;
- gxbb_mpeg_clk_div.reg = clk_base + (u64)gxbb_mpeg_clk_div.reg;
-
- /* Populate the base address for the SAR ADC clks */
- gxbb_sar_adc_clk_sel.reg = clk_base + (u64)gxbb_sar_adc_clk_sel.reg;
- gxbb_sar_adc_clk_div.reg = clk_base + (u64)gxbb_sar_adc_clk_div.reg;
-
/* Populate base address for gates */
for (i = 0; i < ARRAY_SIZE(gxbb_clk_gates); i++)
gxbb_clk_gates[i]->reg = clk_base +
(u64)gxbb_clk_gates[i]->reg;
+ /* Populate base address for muxes */
+ for (i = 0; i < ARRAY_SIZE(gxbb_clk_muxes); i++)
+ gxbb_clk_muxes[i]->reg = clk_base +
+ (u64)gxbb_clk_muxes[i]->reg;
+
+ /* Populate base address for dividers */
+ for (i = 0; i < ARRAY_SIZE(gxbb_clk_dividers); i++)
+ gxbb_clk_dividers[i]->reg = clk_base +
+ (u64)gxbb_clk_dividers[i]->reg;
+
/*
* register all clks
*/
--
2.9.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 3/7] clk: meson: mpll: add rw operation
2017-02-28 13:29 ` Jerome Brunet
@ 2017-02-28 13:29 ` Jerome Brunet
-1 siblings, 0 replies; 17+ messages in thread
From: Jerome Brunet @ 2017-02-28 13:29 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Kevin Hilman, Carlo Caione
Cc: Jerome Brunet, linux-clk, linux-amlogic, linux-kernel
This patch adds new callbacks to the meson-mpll driver to control
and set the pll rate. For this, we also need to add the enable bit and
sdm enable bit. The corresponding parameters are added to mpll data
structure.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/clk/meson/clk-mpll.c | 152 +++++++++++++++++++++++++++++++++++++++++--
drivers/clk/meson/clkc.h | 4 +-
drivers/clk/meson/gxbb.c | 30 +++++++++
3 files changed, 180 insertions(+), 6 deletions(-)
diff --git a/drivers/clk/meson/clk-mpll.c b/drivers/clk/meson/clk-mpll.c
index 03af79005ddb..342b85d4e22a 100644
--- a/drivers/clk/meson/clk-mpll.c
+++ b/drivers/clk/meson/clk-mpll.c
@@ -64,16 +64,50 @@
#include <linux/clk-provider.h>
#include "clkc.h"
-#define SDM_MAX 16384
+#define SDM_DEN 16384
+#define SDM_MIN 1
+#define SDM_MAX 16383
+#define N2_MIN 4
+#define N2_MAX 127
#define to_meson_clk_mpll(_hw) container_of(_hw, struct meson_clk_mpll, hw)
+static unsigned long rate_from_params(unsigned long parent_rate,
+ unsigned long sdm,
+ unsigned long n2)
+{
+ return (parent_rate * SDM_DEN) / ((SDM_DEN * n2) + sdm);
+}
+
+static void params_from_rate(unsigned long requested_rate,
+ unsigned long parent_rate,
+ unsigned long *sdm,
+ unsigned long *n2)
+{
+ uint64_t div = parent_rate;
+ unsigned long rem = do_div(div, requested_rate);
+
+ if (div < N2_MIN) {
+ *n2 = N2_MIN;
+ *sdm = SDM_MIN;
+ } else if (div > N2_MAX) {
+ *n2 = N2_MAX;
+ *sdm = SDM_MAX;
+ } else {
+ *n2 = div;
+ *sdm = DIV_ROUND_UP(rem * SDM_DEN, requested_rate);
+ if (*sdm < SDM_MIN)
+ *sdm = SDM_MIN;
+ else if (*sdm > SDM_MAX)
+ *sdm = SDM_MAX;
+ }
+}
+
static unsigned long mpll_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw);
struct parm *p;
- unsigned long rate = 0;
unsigned long reg, sdm, n2;
p = &mpll->sdm;
@@ -84,11 +118,119 @@ static unsigned long mpll_recalc_rate(struct clk_hw *hw,
reg = readl(mpll->base + p->reg_off);
n2 = PARM_GET(p->width, p->shift, reg);
- rate = (parent_rate * SDM_MAX) / ((SDM_MAX * n2) + sdm);
+ return rate_from_params(parent_rate, sdm, n2);
+}
+
+static long mpll_round_rate(struct clk_hw *hw,
+ unsigned long rate,
+ unsigned long *parent_rate)
+{
+ unsigned long sdm, n2;
+
+ params_from_rate(rate, *parent_rate, &sdm, &n2);
+ return rate_from_params(*parent_rate, sdm, n2);
+}
+
+static int mpll_set_rate(struct clk_hw *hw,
+ unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw);
+ struct parm *p;
+ unsigned long reg, sdm, n2;
+ unsigned long flags = 0;
+
+ params_from_rate(rate, parent_rate, &sdm, &n2);
+
+ if (mpll->lock)
+ spin_lock_irqsave(mpll->lock, flags);
+ else
+ __acquire(mpll->lock);
+
+ p = &mpll->sdm;
+ reg = readl(mpll->base + p->reg_off);
+ reg = PARM_SET(p->width, p->shift, reg, sdm);
+ writel(reg, mpll->base + p->reg_off);
+
+ p = &mpll->sdm_en;
+ reg = readl(mpll->base + p->reg_off);
+ reg = PARM_SET(p->width, p->shift, reg, 1);
+ writel(reg, mpll->base + p->reg_off);
+
+ p = &mpll->n2;
+ reg = readl(mpll->base + p->reg_off);
+ reg = PARM_SET(p->width, p->shift, reg, n2);
+ writel(reg, mpll->base + p->reg_off);
+
+ if (mpll->lock)
+ spin_unlock_irqrestore(mpll->lock, flags);
+ else
+ __release(mpll->lock);
- return rate;
+ return 0;
+}
+
+static void mpll_enable_core(struct clk_hw *hw, int enable)
+{
+ struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw);
+ struct parm *p;
+ unsigned long reg;
+ unsigned long flags = 0;
+
+ if (mpll->lock)
+ spin_lock_irqsave(mpll->lock, flags);
+ else
+ __acquire(mpll->lock);
+
+ p = &mpll->en;
+ reg = readl(mpll->base + p->reg_off);
+ reg = PARM_SET(p->width, p->shift, reg, enable ? 1 : 0);
+ writel(reg, mpll->base + p->reg_off);
+
+ if (mpll->lock)
+ spin_unlock_irqrestore(mpll->lock, flags);
+ else
+ __release(mpll->lock);
+}
+
+
+static int mpll_enable(struct clk_hw *hw)
+{
+ mpll_enable_core(hw, 1);
+
+ return 0;
+}
+
+static void mpll_disable(struct clk_hw *hw)
+{
+ mpll_enable_core(hw, 0);
+}
+
+static int mpll_is_enabled(struct clk_hw *hw)
+{
+ struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw);
+ struct parm *p;
+ unsigned long reg;
+ int en;
+
+ p = &mpll->en;
+ reg = readl(mpll->base + p->reg_off);
+ en = PARM_GET(p->width, p->shift, reg);
+
+ return en;
}
const struct clk_ops meson_clk_mpll_ro_ops = {
- .recalc_rate = mpll_recalc_rate,
+ .recalc_rate = mpll_recalc_rate,
+ .round_rate = mpll_round_rate,
+ .is_enabled = mpll_is_enabled,
+};
+
+const struct clk_ops meson_clk_mpll_ops = {
+ .recalc_rate = mpll_recalc_rate,
+ .round_rate = mpll_round_rate,
+ .set_rate = mpll_set_rate,
+ .enable = mpll_enable,
+ .disable = mpll_disable,
+ .is_enabled = mpll_is_enabled,
};
diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h
index 9bb70e7a7d6a..54d58a465039 100644
--- a/drivers/clk/meson/clkc.h
+++ b/drivers/clk/meson/clkc.h
@@ -92,8 +92,9 @@ struct meson_clk_mpll {
struct clk_hw hw;
void __iomem *base;
struct parm sdm;
+ struct parm sdm_en;
struct parm n2;
- /* FIXME ssen gate control? */
+ struct parm en;
spinlock_t *lock;
};
@@ -116,5 +117,6 @@ extern const struct clk_ops meson_clk_pll_ro_ops;
extern const struct clk_ops meson_clk_pll_ops;
extern const struct clk_ops meson_clk_cpu_ops;
extern const struct clk_ops meson_clk_mpll_ro_ops;
+extern const struct clk_ops meson_clk_mpll_ops;
#endif /* __CLKC_H */
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index 388b0c8838af..6b97f4da1708 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -441,11 +441,21 @@ static struct meson_clk_mpll gxbb_mpll0 = {
.shift = 0,
.width = 14,
},
+ .sdm_en = {
+ .reg_off = HHI_MPLL_CNTL7,
+ .shift = 15,
+ .width = 1,
+ },
.n2 = {
.reg_off = HHI_MPLL_CNTL7,
.shift = 16,
.width = 9,
},
+ .en = {
+ .reg_off = HHI_MPLL_CNTL7,
+ .shift = 14,
+ .width = 1,
+ },
.lock = &clk_lock,
.hw.init = &(struct clk_init_data){
.name = "mpll0",
@@ -461,11 +471,21 @@ static struct meson_clk_mpll gxbb_mpll1 = {
.shift = 0,
.width = 14,
},
+ .sdm_en = {
+ .reg_off = HHI_MPLL_CNTL8,
+ .shift = 15,
+ .width = 1,
+ },
.n2 = {
.reg_off = HHI_MPLL_CNTL8,
.shift = 16,
.width = 9,
},
+ .en = {
+ .reg_off = HHI_MPLL_CNTL8,
+ .shift = 14,
+ .width = 1,
+ },
.lock = &clk_lock,
.hw.init = &(struct clk_init_data){
.name = "mpll1",
@@ -481,11 +501,21 @@ static struct meson_clk_mpll gxbb_mpll2 = {
.shift = 0,
.width = 14,
},
+ .sdm_en = {
+ .reg_off = HHI_MPLL_CNTL9,
+ .shift = 15,
+ .width = 1,
+ },
.n2 = {
.reg_off = HHI_MPLL_CNTL9,
.shift = 16,
.width = 9,
},
+ .en = {
+ .reg_off = HHI_MPLL_CNTL9,
+ .shift = 14,
+ .width = 1,
+ },
.lock = &clk_lock,
.hw.init = &(struct clk_init_data){
.name = "mpll2",
--
2.9.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 3/7] clk: meson: mpll: add rw operation
@ 2017-02-28 13:29 ` Jerome Brunet
0 siblings, 0 replies; 17+ messages in thread
From: Jerome Brunet @ 2017-02-28 13:29 UTC (permalink / raw)
To: linus-amlogic
This patch adds new callbacks to the meson-mpll driver to control
and set the pll rate. For this, we also need to add the enable bit and
sdm enable bit. The corresponding parameters are added to mpll data
structure.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/clk/meson/clk-mpll.c | 152 +++++++++++++++++++++++++++++++++++++++++--
drivers/clk/meson/clkc.h | 4 +-
drivers/clk/meson/gxbb.c | 30 +++++++++
3 files changed, 180 insertions(+), 6 deletions(-)
diff --git a/drivers/clk/meson/clk-mpll.c b/drivers/clk/meson/clk-mpll.c
index 03af79005ddb..342b85d4e22a 100644
--- a/drivers/clk/meson/clk-mpll.c
+++ b/drivers/clk/meson/clk-mpll.c
@@ -64,16 +64,50 @@
#include <linux/clk-provider.h>
#include "clkc.h"
-#define SDM_MAX 16384
+#define SDM_DEN 16384
+#define SDM_MIN 1
+#define SDM_MAX 16383
+#define N2_MIN 4
+#define N2_MAX 127
#define to_meson_clk_mpll(_hw) container_of(_hw, struct meson_clk_mpll, hw)
+static unsigned long rate_from_params(unsigned long parent_rate,
+ unsigned long sdm,
+ unsigned long n2)
+{
+ return (parent_rate * SDM_DEN) / ((SDM_DEN * n2) + sdm);
+}
+
+static void params_from_rate(unsigned long requested_rate,
+ unsigned long parent_rate,
+ unsigned long *sdm,
+ unsigned long *n2)
+{
+ uint64_t div = parent_rate;
+ unsigned long rem = do_div(div, requested_rate);
+
+ if (div < N2_MIN) {
+ *n2 = N2_MIN;
+ *sdm = SDM_MIN;
+ } else if (div > N2_MAX) {
+ *n2 = N2_MAX;
+ *sdm = SDM_MAX;
+ } else {
+ *n2 = div;
+ *sdm = DIV_ROUND_UP(rem * SDM_DEN, requested_rate);
+ if (*sdm < SDM_MIN)
+ *sdm = SDM_MIN;
+ else if (*sdm > SDM_MAX)
+ *sdm = SDM_MAX;
+ }
+}
+
static unsigned long mpll_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw);
struct parm *p;
- unsigned long rate = 0;
unsigned long reg, sdm, n2;
p = &mpll->sdm;
@@ -84,11 +118,119 @@ static unsigned long mpll_recalc_rate(struct clk_hw *hw,
reg = readl(mpll->base + p->reg_off);
n2 = PARM_GET(p->width, p->shift, reg);
- rate = (parent_rate * SDM_MAX) / ((SDM_MAX * n2) + sdm);
+ return rate_from_params(parent_rate, sdm, n2);
+}
+
+static long mpll_round_rate(struct clk_hw *hw,
+ unsigned long rate,
+ unsigned long *parent_rate)
+{
+ unsigned long sdm, n2;
+
+ params_from_rate(rate, *parent_rate, &sdm, &n2);
+ return rate_from_params(*parent_rate, sdm, n2);
+}
+
+static int mpll_set_rate(struct clk_hw *hw,
+ unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw);
+ struct parm *p;
+ unsigned long reg, sdm, n2;
+ unsigned long flags = 0;
+
+ params_from_rate(rate, parent_rate, &sdm, &n2);
+
+ if (mpll->lock)
+ spin_lock_irqsave(mpll->lock, flags);
+ else
+ __acquire(mpll->lock);
+
+ p = &mpll->sdm;
+ reg = readl(mpll->base + p->reg_off);
+ reg = PARM_SET(p->width, p->shift, reg, sdm);
+ writel(reg, mpll->base + p->reg_off);
+
+ p = &mpll->sdm_en;
+ reg = readl(mpll->base + p->reg_off);
+ reg = PARM_SET(p->width, p->shift, reg, 1);
+ writel(reg, mpll->base + p->reg_off);
+
+ p = &mpll->n2;
+ reg = readl(mpll->base + p->reg_off);
+ reg = PARM_SET(p->width, p->shift, reg, n2);
+ writel(reg, mpll->base + p->reg_off);
+
+ if (mpll->lock)
+ spin_unlock_irqrestore(mpll->lock, flags);
+ else
+ __release(mpll->lock);
- return rate;
+ return 0;
+}
+
+static void mpll_enable_core(struct clk_hw *hw, int enable)
+{
+ struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw);
+ struct parm *p;
+ unsigned long reg;
+ unsigned long flags = 0;
+
+ if (mpll->lock)
+ spin_lock_irqsave(mpll->lock, flags);
+ else
+ __acquire(mpll->lock);
+
+ p = &mpll->en;
+ reg = readl(mpll->base + p->reg_off);
+ reg = PARM_SET(p->width, p->shift, reg, enable ? 1 : 0);
+ writel(reg, mpll->base + p->reg_off);
+
+ if (mpll->lock)
+ spin_unlock_irqrestore(mpll->lock, flags);
+ else
+ __release(mpll->lock);
+}
+
+
+static int mpll_enable(struct clk_hw *hw)
+{
+ mpll_enable_core(hw, 1);
+
+ return 0;
+}
+
+static void mpll_disable(struct clk_hw *hw)
+{
+ mpll_enable_core(hw, 0);
+}
+
+static int mpll_is_enabled(struct clk_hw *hw)
+{
+ struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw);
+ struct parm *p;
+ unsigned long reg;
+ int en;
+
+ p = &mpll->en;
+ reg = readl(mpll->base + p->reg_off);
+ en = PARM_GET(p->width, p->shift, reg);
+
+ return en;
}
const struct clk_ops meson_clk_mpll_ro_ops = {
- .recalc_rate = mpll_recalc_rate,
+ .recalc_rate = mpll_recalc_rate,
+ .round_rate = mpll_round_rate,
+ .is_enabled = mpll_is_enabled,
+};
+
+const struct clk_ops meson_clk_mpll_ops = {
+ .recalc_rate = mpll_recalc_rate,
+ .round_rate = mpll_round_rate,
+ .set_rate = mpll_set_rate,
+ .enable = mpll_enable,
+ .disable = mpll_disable,
+ .is_enabled = mpll_is_enabled,
};
diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h
index 9bb70e7a7d6a..54d58a465039 100644
--- a/drivers/clk/meson/clkc.h
+++ b/drivers/clk/meson/clkc.h
@@ -92,8 +92,9 @@ struct meson_clk_mpll {
struct clk_hw hw;
void __iomem *base;
struct parm sdm;
+ struct parm sdm_en;
struct parm n2;
- /* FIXME ssen gate control? */
+ struct parm en;
spinlock_t *lock;
};
@@ -116,5 +117,6 @@ extern const struct clk_ops meson_clk_pll_ro_ops;
extern const struct clk_ops meson_clk_pll_ops;
extern const struct clk_ops meson_clk_cpu_ops;
extern const struct clk_ops meson_clk_mpll_ro_ops;
+extern const struct clk_ops meson_clk_mpll_ops;
#endif /* __CLKC_H */
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index 388b0c8838af..6b97f4da1708 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -441,11 +441,21 @@ static struct meson_clk_mpll gxbb_mpll0 = {
.shift = 0,
.width = 14,
},
+ .sdm_en = {
+ .reg_off = HHI_MPLL_CNTL7,
+ .shift = 15,
+ .width = 1,
+ },
.n2 = {
.reg_off = HHI_MPLL_CNTL7,
.shift = 16,
.width = 9,
},
+ .en = {
+ .reg_off = HHI_MPLL_CNTL7,
+ .shift = 14,
+ .width = 1,
+ },
.lock = &clk_lock,
.hw.init = &(struct clk_init_data){
.name = "mpll0",
@@ -461,11 +471,21 @@ static struct meson_clk_mpll gxbb_mpll1 = {
.shift = 0,
.width = 14,
},
+ .sdm_en = {
+ .reg_off = HHI_MPLL_CNTL8,
+ .shift = 15,
+ .width = 1,
+ },
.n2 = {
.reg_off = HHI_MPLL_CNTL8,
.shift = 16,
.width = 9,
},
+ .en = {
+ .reg_off = HHI_MPLL_CNTL8,
+ .shift = 14,
+ .width = 1,
+ },
.lock = &clk_lock,
.hw.init = &(struct clk_init_data){
.name = "mpll1",
@@ -481,11 +501,21 @@ static struct meson_clk_mpll gxbb_mpll2 = {
.shift = 0,
.width = 14,
},
+ .sdm_en = {
+ .reg_off = HHI_MPLL_CNTL9,
+ .shift = 15,
+ .width = 1,
+ },
.n2 = {
.reg_off = HHI_MPLL_CNTL9,
.shift = 16,
.width = 9,
},
+ .en = {
+ .reg_off = HHI_MPLL_CNTL9,
+ .shift = 14,
+ .width = 1,
+ },
.lock = &clk_lock,
.hw.init = &(struct clk_init_data){
.name = "mpll2",
--
2.9.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 4/7] clk: meson: gxbb: mpll: use rw operation
2017-02-28 13:29 ` Jerome Brunet
@ 2017-02-28 13:29 ` Jerome Brunet
-1 siblings, 0 replies; 17+ messages in thread
From: Jerome Brunet @ 2017-02-28 13:29 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Kevin Hilman, Carlo Caione
Cc: Jerome Brunet, linux-clk, linux-amlogic, linux-kernel
Use read/write operations for the mpll clocks instead of the
read-only ones.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/clk/meson/gxbb.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index 6b97f4da1708..a52063f57d00 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -459,7 +459,7 @@ static struct meson_clk_mpll gxbb_mpll0 = {
.lock = &clk_lock,
.hw.init = &(struct clk_init_data){
.name = "mpll0",
- .ops = &meson_clk_mpll_ro_ops,
+ .ops = &meson_clk_mpll_ops,
.parent_names = (const char *[]){ "fixed_pll" },
.num_parents = 1,
},
@@ -489,7 +489,7 @@ static struct meson_clk_mpll gxbb_mpll1 = {
.lock = &clk_lock,
.hw.init = &(struct clk_init_data){
.name = "mpll1",
- .ops = &meson_clk_mpll_ro_ops,
+ .ops = &meson_clk_mpll_ops,
.parent_names = (const char *[]){ "fixed_pll" },
.num_parents = 1,
},
@@ -519,7 +519,7 @@ static struct meson_clk_mpll gxbb_mpll2 = {
.lock = &clk_lock,
.hw.init = &(struct clk_init_data){
.name = "mpll2",
- .ops = &meson_clk_mpll_ro_ops,
+ .ops = &meson_clk_mpll_ops,
.parent_names = (const char *[]){ "fixed_pll" },
.num_parents = 1,
},
--
2.9.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 4/7] clk: meson: gxbb: mpll: use rw operation
@ 2017-02-28 13:29 ` Jerome Brunet
0 siblings, 0 replies; 17+ messages in thread
From: Jerome Brunet @ 2017-02-28 13:29 UTC (permalink / raw)
To: linus-amlogic
Use read/write operations for the mpll clocks instead of the
read-only ones.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/clk/meson/gxbb.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index 6b97f4da1708..a52063f57d00 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -459,7 +459,7 @@ static struct meson_clk_mpll gxbb_mpll0 = {
.lock = &clk_lock,
.hw.init = &(struct clk_init_data){
.name = "mpll0",
- .ops = &meson_clk_mpll_ro_ops,
+ .ops = &meson_clk_mpll_ops,
.parent_names = (const char *[]){ "fixed_pll" },
.num_parents = 1,
},
@@ -489,7 +489,7 @@ static struct meson_clk_mpll gxbb_mpll1 = {
.lock = &clk_lock,
.hw.init = &(struct clk_init_data){
.name = "mpll1",
- .ops = &meson_clk_mpll_ro_ops,
+ .ops = &meson_clk_mpll_ops,
.parent_names = (const char *[]){ "fixed_pll" },
.num_parents = 1,
},
@@ -519,7 +519,7 @@ static struct meson_clk_mpll gxbb_mpll2 = {
.lock = &clk_lock,
.hw.init = &(struct clk_init_data){
.name = "mpll2",
- .ops = &meson_clk_mpll_ro_ops,
+ .ops = &meson_clk_mpll_ops,
.parent_names = (const char *[]){ "fixed_pll" },
.num_parents = 1,
},
--
2.9.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 5/7] clk: meson8b: add the mplls clocks 0, 1 and 2
2017-02-28 13:29 ` Jerome Brunet
@ 2017-02-28 13:30 ` Jerome Brunet
-1 siblings, 0 replies; 17+ messages in thread
From: Jerome Brunet @ 2017-02-28 13:30 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Kevin Hilman, Carlo Caione
Cc: Jerome Brunet, linux-clk, linux-amlogic, linux-kernel
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/clk/meson/meson8b.c | 103 ++++++++++++++++++++++++++++++++++++++++++++
drivers/clk/meson/meson8b.h | 20 ++++++++-
2 files changed, 122 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c
index 44c24bf754cd..034df7556126 100644
--- a/drivers/clk/meson/meson8b.c
+++ b/drivers/clk/meson/meson8b.c
@@ -245,6 +245,96 @@ static struct clk_fixed_factor meson8b_fclk_div7 = {
},
};
+static struct meson_clk_mpll meson8b_mpll0 = {
+ .sdm = {
+ .reg_off = HHI_MPLL_CNTL7,
+ .shift = 0,
+ .width = 14,
+ },
+ .sdm_en = {
+ .reg_off = HHI_MPLL_CNTL7,
+ .shift = 15,
+ .width = 1,
+ },
+ .n2 = {
+ .reg_off = HHI_MPLL_CNTL7,
+ .shift = 16,
+ .width = 9,
+ },
+ .en = {
+ .reg_off = HHI_MPLL_CNTL7,
+ .shift = 14,
+ .width = 1,
+ },
+ .lock = &clk_lock,
+ .hw.init = &(struct clk_init_data){
+ .name = "mpll0",
+ .ops = &meson_clk_mpll_ops,
+ .parent_names = (const char *[]){ "fixed_pll" },
+ .num_parents = 1,
+ },
+};
+
+static struct meson_clk_mpll meson8b_mpll1 = {
+ .sdm = {
+ .reg_off = HHI_MPLL_CNTL8,
+ .shift = 0,
+ .width = 14,
+ },
+ .sdm_en = {
+ .reg_off = HHI_MPLL_CNTL8,
+ .shift = 15,
+ .width = 1,
+ },
+ .n2 = {
+ .reg_off = HHI_MPLL_CNTL8,
+ .shift = 16,
+ .width = 9,
+ },
+ .en = {
+ .reg_off = HHI_MPLL_CNTL8,
+ .shift = 14,
+ .width = 1,
+ },
+ .lock = &clk_lock,
+ .hw.init = &(struct clk_init_data){
+ .name = "mpll1",
+ .ops = &meson_clk_mpll_ops,
+ .parent_names = (const char *[]){ "fixed_pll" },
+ .num_parents = 1,
+ },
+};
+
+static struct meson_clk_mpll meson8b_mpll2 = {
+ .sdm = {
+ .reg_off = HHI_MPLL_CNTL9,
+ .shift = 0,
+ .width = 14,
+ },
+ .sdm_en = {
+ .reg_off = HHI_MPLL_CNTL9,
+ .shift = 15,
+ .width = 1,
+ },
+ .n2 = {
+ .reg_off = HHI_MPLL_CNTL9,
+ .shift = 16,
+ .width = 9,
+ },
+ .en = {
+ .reg_off = HHI_MPLL_CNTL9,
+ .shift = 14,
+ .width = 1,
+ },
+ .lock = &clk_lock,
+ .hw.init = &(struct clk_init_data){
+ .name = "mpll2",
+ .ops = &meson_clk_mpll_ops,
+ .parent_names = (const char *[]){ "fixed_pll" },
+ .num_parents = 1,
+ },
+};
+
/*
* FIXME cpu clocks and the legacy composite clocks (e.g. clk81) are both PLL
* post-dividers and should be modeled with their respective PLLs via the
@@ -491,6 +581,9 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
[CLKID_AO_AHB_SRAM] = &meson8b_ao_ahb_sram.hw,
[CLKID_AO_AHB_BUS] = &meson8b_ao_ahb_bus.hw,
[CLKID_AO_IFACE] = &meson8b_ao_iface.hw,
+ [CLKID_MPLL0] = &meson8b_mpll0.hw,
+ [CLKID_MPLL1] = &meson8b_mpll1.hw,
+ [CLKID_MPLL2] = &meson8b_mpll2.hw,
},
.num = CLK_NR_CLKS,
};
@@ -501,6 +594,12 @@ static struct meson_clk_pll *const meson8b_clk_plls[] = {
&meson8b_sys_pll,
};
+static struct meson_clk_mpll *const meson8b_clk_mplls[] = {
+ &meson8b_mpll0,
+ &meson8b_mpll1,
+ &meson8b_mpll2,
+};
+
static struct clk_gate *meson8b_clk_gates[] = {
&meson8b_clk81,
&meson8b_ddr,
@@ -610,6 +709,10 @@ static int meson8b_clkc_probe(struct platform_device *pdev)
for (i = 0; i < ARRAY_SIZE(meson8b_clk_plls); i++)
meson8b_clk_plls[i]->base = clk_base;
+ /* Populate base address for MPLLs */
+ for (i = 0; i < ARRAY_SIZE(meson8b_clk_mplls); i++)
+ meson8b_clk_mplls[i]->base = clk_base;
+
/* Populate the base address for CPU clk */
meson8b_cpu_clk.base = clk_base;
diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h
index 010e9582888d..3881defc8644 100644
--- a/drivers/clk/meson/meson8b.h
+++ b/drivers/clk/meson/meson8b.h
@@ -42,6 +42,21 @@
#define HHI_VID_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */
/*
+ * MPLL register offeset taken from the S905 datasheet. Vendor kernel source
+ * confirm these are the same for the S805.
+ */
+#define HHI_MPLL_CNTL 0x280 /* 0xa0 offset in data sheet */
+#define HHI_MPLL_CNTL2 0x284 /* 0xa1 offset in data sheet */
+#define HHI_MPLL_CNTL3 0x288 /* 0xa2 offset in data sheet */
+#define HHI_MPLL_CNTL4 0x28C /* 0xa3 offset in data sheet */
+#define HHI_MPLL_CNTL5 0x290 /* 0xa4 offset in data sheet */
+#define HHI_MPLL_CNTL6 0x294 /* 0xa5 offset in data sheet */
+#define HHI_MPLL_CNTL7 0x298 /* 0xa6 offset in data sheet */
+#define HHI_MPLL_CNTL8 0x29C /* 0xa7 offset in data sheet */
+#define HHI_MPLL_CNTL9 0x2A0 /* 0xa8 offset in data sheet */
+#define HHI_MPLL_CNTL10 0x2A4 /* 0xa9 offset in data sheet */
+
+/*
* CLKID index values
*
* These indices are entirely contrived and do not map onto the hardware.
@@ -142,8 +157,11 @@
#define CLKID_AO_AHB_SRAM 90
#define CLKID_AO_AHB_BUS 91
#define CLKID_AO_IFACE 92
+#define CLKID_MPLL0 93
+#define CLKID_MPLL1 94
+#define CLKID_MPLL2 95
-#define CLK_NR_CLKS 93
+#define CLK_NR_CLKS 96
/* include the CLKIDs that have been made part of the stable DT binding */
#include <dt-bindings/clock/meson8b-clkc.h>
--
2.9.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 5/7] clk: meson8b: add the mplls clocks 0, 1 and 2
@ 2017-02-28 13:30 ` Jerome Brunet
0 siblings, 0 replies; 17+ messages in thread
From: Jerome Brunet @ 2017-02-28 13:30 UTC (permalink / raw)
To: linus-amlogic
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/clk/meson/meson8b.c | 103 ++++++++++++++++++++++++++++++++++++++++++++
drivers/clk/meson/meson8b.h | 20 ++++++++-
2 files changed, 122 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c
index 44c24bf754cd..034df7556126 100644
--- a/drivers/clk/meson/meson8b.c
+++ b/drivers/clk/meson/meson8b.c
@@ -245,6 +245,96 @@ static struct clk_fixed_factor meson8b_fclk_div7 = {
},
};
+static struct meson_clk_mpll meson8b_mpll0 = {
+ .sdm = {
+ .reg_off = HHI_MPLL_CNTL7,
+ .shift = 0,
+ .width = 14,
+ },
+ .sdm_en = {
+ .reg_off = HHI_MPLL_CNTL7,
+ .shift = 15,
+ .width = 1,
+ },
+ .n2 = {
+ .reg_off = HHI_MPLL_CNTL7,
+ .shift = 16,
+ .width = 9,
+ },
+ .en = {
+ .reg_off = HHI_MPLL_CNTL7,
+ .shift = 14,
+ .width = 1,
+ },
+ .lock = &clk_lock,
+ .hw.init = &(struct clk_init_data){
+ .name = "mpll0",
+ .ops = &meson_clk_mpll_ops,
+ .parent_names = (const char *[]){ "fixed_pll" },
+ .num_parents = 1,
+ },
+};
+
+static struct meson_clk_mpll meson8b_mpll1 = {
+ .sdm = {
+ .reg_off = HHI_MPLL_CNTL8,
+ .shift = 0,
+ .width = 14,
+ },
+ .sdm_en = {
+ .reg_off = HHI_MPLL_CNTL8,
+ .shift = 15,
+ .width = 1,
+ },
+ .n2 = {
+ .reg_off = HHI_MPLL_CNTL8,
+ .shift = 16,
+ .width = 9,
+ },
+ .en = {
+ .reg_off = HHI_MPLL_CNTL8,
+ .shift = 14,
+ .width = 1,
+ },
+ .lock = &clk_lock,
+ .hw.init = &(struct clk_init_data){
+ .name = "mpll1",
+ .ops = &meson_clk_mpll_ops,
+ .parent_names = (const char *[]){ "fixed_pll" },
+ .num_parents = 1,
+ },
+};
+
+static struct meson_clk_mpll meson8b_mpll2 = {
+ .sdm = {
+ .reg_off = HHI_MPLL_CNTL9,
+ .shift = 0,
+ .width = 14,
+ },
+ .sdm_en = {
+ .reg_off = HHI_MPLL_CNTL9,
+ .shift = 15,
+ .width = 1,
+ },
+ .n2 = {
+ .reg_off = HHI_MPLL_CNTL9,
+ .shift = 16,
+ .width = 9,
+ },
+ .en = {
+ .reg_off = HHI_MPLL_CNTL9,
+ .shift = 14,
+ .width = 1,
+ },
+ .lock = &clk_lock,
+ .hw.init = &(struct clk_init_data){
+ .name = "mpll2",
+ .ops = &meson_clk_mpll_ops,
+ .parent_names = (const char *[]){ "fixed_pll" },
+ .num_parents = 1,
+ },
+};
+
/*
* FIXME cpu clocks and the legacy composite clocks (e.g. clk81) are both PLL
* post-dividers and should be modeled with their respective PLLs via the
@@ -491,6 +581,9 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
[CLKID_AO_AHB_SRAM] = &meson8b_ao_ahb_sram.hw,
[CLKID_AO_AHB_BUS] = &meson8b_ao_ahb_bus.hw,
[CLKID_AO_IFACE] = &meson8b_ao_iface.hw,
+ [CLKID_MPLL0] = &meson8b_mpll0.hw,
+ [CLKID_MPLL1] = &meson8b_mpll1.hw,
+ [CLKID_MPLL2] = &meson8b_mpll2.hw,
},
.num = CLK_NR_CLKS,
};
@@ -501,6 +594,12 @@ static struct meson_clk_pll *const meson8b_clk_plls[] = {
&meson8b_sys_pll,
};
+static struct meson_clk_mpll *const meson8b_clk_mplls[] = {
+ &meson8b_mpll0,
+ &meson8b_mpll1,
+ &meson8b_mpll2,
+};
+
static struct clk_gate *meson8b_clk_gates[] = {
&meson8b_clk81,
&meson8b_ddr,
@@ -610,6 +709,10 @@ static int meson8b_clkc_probe(struct platform_device *pdev)
for (i = 0; i < ARRAY_SIZE(meson8b_clk_plls); i++)
meson8b_clk_plls[i]->base = clk_base;
+ /* Populate base address for MPLLs */
+ for (i = 0; i < ARRAY_SIZE(meson8b_clk_mplls); i++)
+ meson8b_clk_mplls[i]->base = clk_base;
+
/* Populate the base address for CPU clk */
meson8b_cpu_clk.base = clk_base;
diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h
index 010e9582888d..3881defc8644 100644
--- a/drivers/clk/meson/meson8b.h
+++ b/drivers/clk/meson/meson8b.h
@@ -42,6 +42,21 @@
#define HHI_VID_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */
/*
+ * MPLL register offeset taken from the S905 datasheet. Vendor kernel source
+ * confirm these are the same for the S805.
+ */
+#define HHI_MPLL_CNTL 0x280 /* 0xa0 offset in data sheet */
+#define HHI_MPLL_CNTL2 0x284 /* 0xa1 offset in data sheet */
+#define HHI_MPLL_CNTL3 0x288 /* 0xa2 offset in data sheet */
+#define HHI_MPLL_CNTL4 0x28C /* 0xa3 offset in data sheet */
+#define HHI_MPLL_CNTL5 0x290 /* 0xa4 offset in data sheet */
+#define HHI_MPLL_CNTL6 0x294 /* 0xa5 offset in data sheet */
+#define HHI_MPLL_CNTL7 0x298 /* 0xa6 offset in data sheet */
+#define HHI_MPLL_CNTL8 0x29C /* 0xa7 offset in data sheet */
+#define HHI_MPLL_CNTL9 0x2A0 /* 0xa8 offset in data sheet */
+#define HHI_MPLL_CNTL10 0x2A4 /* 0xa9 offset in data sheet */
+
+/*
* CLKID index values
*
* These indices are entirely contrived and do not map onto the hardware.
@@ -142,8 +157,11 @@
#define CLKID_AO_AHB_SRAM 90
#define CLKID_AO_AHB_BUS 91
#define CLKID_AO_IFACE 92
+#define CLKID_MPLL0 93
+#define CLKID_MPLL1 94
+#define CLKID_MPLL2 95
-#define CLK_NR_CLKS 93
+#define CLK_NR_CLKS 96
/* include the CLKIDs that have been made part of the stable DT binding */
#include <dt-bindings/clock/meson8b-clkc.h>
--
2.9.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 6/7] clk: meson: mpll: correct N2 maximum value
2017-02-28 13:29 ` Jerome Brunet
@ 2017-02-28 13:30 ` Jerome Brunet
-1 siblings, 0 replies; 17+ messages in thread
From: Jerome Brunet @ 2017-02-28 13:30 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Kevin Hilman, Carlo Caione
Cc: Jerome Brunet, linux-clk, linux-amlogic, linux-kernel
Gxbb datasheet says N2 maximum value is 127 but the register field is
9 bits wide, the maximum value should 511.
Test shows value greater than 127, all the way to 511, works well
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/clk/meson/clk-mpll.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/meson/clk-mpll.c b/drivers/clk/meson/clk-mpll.c
index 342b85d4e22a..540dabe5adad 100644
--- a/drivers/clk/meson/clk-mpll.c
+++ b/drivers/clk/meson/clk-mpll.c
@@ -68,7 +68,7 @@
#define SDM_MIN 1
#define SDM_MAX 16383
#define N2_MIN 4
-#define N2_MAX 127
+#define N2_MAX 511
#define to_meson_clk_mpll(_hw) container_of(_hw, struct meson_clk_mpll, hw)
--
2.9.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 6/7] clk: meson: mpll: correct N2 maximum value
@ 2017-02-28 13:30 ` Jerome Brunet
0 siblings, 0 replies; 17+ messages in thread
From: Jerome Brunet @ 2017-02-28 13:30 UTC (permalink / raw)
To: linus-amlogic
Gxbb datasheet says N2 maximum value is 127 but the register field is
9 bits wide, the maximum value should 511.
Test shows value greater than 127, all the way to 511, works well
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/clk/meson/clk-mpll.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/meson/clk-mpll.c b/drivers/clk/meson/clk-mpll.c
index 342b85d4e22a..540dabe5adad 100644
--- a/drivers/clk/meson/clk-mpll.c
+++ b/drivers/clk/meson/clk-mpll.c
@@ -68,7 +68,7 @@
#define SDM_MIN 1
#define SDM_MAX 16383
#define N2_MIN 4
-#define N2_MAX 127
+#define N2_MAX 511
#define to_meson_clk_mpll(_hw) container_of(_hw, struct meson_clk_mpll, hw)
--
2.9.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 7/7] dt-bindings: clk: gxbb: expose i2s output clock gates
2017-02-28 13:29 ` Jerome Brunet
@ 2017-02-28 13:30 ` Jerome Brunet
-1 siblings, 0 replies; 17+ messages in thread
From: Jerome Brunet @ 2017-02-28 13:30 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Kevin Hilman, Carlo Caione
Cc: Jerome Brunet, linux-clk, linux-amlogic, linux-kernel, devicetree
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/clk/meson/gxbb.h | 10 +++++-----
include/dt-bindings/clock/gxbb-clkc.h | 5 +++++
2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h
index dc487180f847..95a83b7709ca 100644
--- a/drivers/clk/meson/gxbb.h
+++ b/drivers/clk/meson/gxbb.h
@@ -206,16 +206,16 @@
#define CLKID_I2S_SPDIF 35
#define CLKID_ETH 36
#define CLKID_DEMUX 37
-#define CLKID_AIU_GLUE 38
+/* CLKID_AIU_GLUE */
#define CLKID_IEC958 39
-#define CLKID_I2S_OUT 40
+/* CLKID_I2S_OUT */
#define CLKID_AMCLK 41
#define CLKID_AIFIFO2 42
#define CLKID_MIXER 43
-#define CLKID_MIXER_IFACE 44
+/* CLKID_MIXER_IFACE */
#define CLKID_ADC 45
#define CLKID_BLKMV 46
-#define CLKID_AIU 47
+/* CLKID_AIU */
#define CLKID_UART1 48
#define CLKID_G2D 49
/* CLKID_USB0 */
@@ -248,7 +248,7 @@
/* CLKID_GCLK_VENCI_INT0 */
#define CLKID_GCLK_VENCI_INT 78
#define CLKID_DAC_CLK 79
-#define CLKID_AOCLK_GATE 80
+/* CLKID_AOCLK_GATE */
#define CLKID_IEC958_GATE 81
#define CLKID_ENC480P 82
#define CLKID_RNG1 83
diff --git a/include/dt-bindings/clock/gxbb-clkc.h b/include/dt-bindings/clock/gxbb-clkc.h
index 692846c7941b..f08f06dd7702 100644
--- a/include/dt-bindings/clock/gxbb-clkc.h
+++ b/include/dt-bindings/clock/gxbb-clkc.h
@@ -16,6 +16,10 @@
#define CLKID_I2C 22
#define CLKID_SAR_ADC 23
#define CLKID_ETH 36
+#define CLKID_AIU_GLUE 38
+#define CLKID_I2S_OUT 40
+#define CLKID_MIXER_IFACE 44
+#define CLKID_AIU 47
#define CLKID_USB0 50
#define CLKID_USB1 51
#define CLKID_USB 55
@@ -24,6 +28,7 @@
#define CLKID_USB0_DDR_BRIDGE 65
#define CLKID_SANA 69
#define CLKID_GCLK_VENCI_INT0 77
+#define CLKID_AOCLK_GATE 80
#define CLKID_AO_I2C 93
#define CLKID_SD_EMMC_A 94
#define CLKID_SD_EMMC_B 95
--
2.9.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 7/7] dt-bindings: clk: gxbb: expose i2s output clock gates
@ 2017-02-28 13:30 ` Jerome Brunet
0 siblings, 0 replies; 17+ messages in thread
From: Jerome Brunet @ 2017-02-28 13:30 UTC (permalink / raw)
To: linus-amlogic
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/clk/meson/gxbb.h | 10 +++++-----
include/dt-bindings/clock/gxbb-clkc.h | 5 +++++
2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h
index dc487180f847..95a83b7709ca 100644
--- a/drivers/clk/meson/gxbb.h
+++ b/drivers/clk/meson/gxbb.h
@@ -206,16 +206,16 @@
#define CLKID_I2S_SPDIF 35
#define CLKID_ETH 36
#define CLKID_DEMUX 37
-#define CLKID_AIU_GLUE 38
+/* CLKID_AIU_GLUE */
#define CLKID_IEC958 39
-#define CLKID_I2S_OUT 40
+/* CLKID_I2S_OUT */
#define CLKID_AMCLK 41
#define CLKID_AIFIFO2 42
#define CLKID_MIXER 43
-#define CLKID_MIXER_IFACE 44
+/* CLKID_MIXER_IFACE */
#define CLKID_ADC 45
#define CLKID_BLKMV 46
-#define CLKID_AIU 47
+/* CLKID_AIU */
#define CLKID_UART1 48
#define CLKID_G2D 49
/* CLKID_USB0 */
@@ -248,7 +248,7 @@
/* CLKID_GCLK_VENCI_INT0 */
#define CLKID_GCLK_VENCI_INT 78
#define CLKID_DAC_CLK 79
-#define CLKID_AOCLK_GATE 80
+/* CLKID_AOCLK_GATE */
#define CLKID_IEC958_GATE 81
#define CLKID_ENC480P 82
#define CLKID_RNG1 83
diff --git a/include/dt-bindings/clock/gxbb-clkc.h b/include/dt-bindings/clock/gxbb-clkc.h
index 692846c7941b..f08f06dd7702 100644
--- a/include/dt-bindings/clock/gxbb-clkc.h
+++ b/include/dt-bindings/clock/gxbb-clkc.h
@@ -16,6 +16,10 @@
#define CLKID_I2C 22
#define CLKID_SAR_ADC 23
#define CLKID_ETH 36
+#define CLKID_AIU_GLUE 38
+#define CLKID_I2S_OUT 40
+#define CLKID_MIXER_IFACE 44
+#define CLKID_AIU 47
#define CLKID_USB0 50
#define CLKID_USB1 51
#define CLKID_USB 55
@@ -24,6 +28,7 @@
#define CLKID_USB0_DDR_BRIDGE 65
#define CLKID_SANA 69
#define CLKID_GCLK_VENCI_INT0 77
+#define CLKID_AOCLK_GATE 80
#define CLKID_AO_I2C 93
#define CLKID_SD_EMMC_A 94
#define CLKID_SD_EMMC_B 95
--
2.9.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
end of thread, other threads:[~2017-02-28 13:32 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-28 13:29 [PATCH 0/7] clk: meson: update clock controller for audio support Jerome Brunet
2017-02-28 13:29 ` Jerome Brunet
2017-02-28 13:29 ` Jerome Brunet
2017-02-28 13:29 ` [PATCH 1/7] clk: meson8b: put dividers and muxes in tables Jerome Brunet
2017-02-28 13:29 ` Jerome Brunet
2017-02-28 13:29 ` [PATCH 2/7] clk: gxbb: " Jerome Brunet
2017-02-28 13:29 ` Jerome Brunet
2017-02-28 13:29 ` [PATCH 3/7] clk: meson: mpll: add rw operation Jerome Brunet
2017-02-28 13:29 ` Jerome Brunet
2017-02-28 13:29 ` [PATCH 4/7] clk: meson: gxbb: mpll: use " Jerome Brunet
2017-02-28 13:29 ` Jerome Brunet
2017-02-28 13:30 ` [PATCH 5/7] clk: meson8b: add the mplls clocks 0, 1 and 2 Jerome Brunet
2017-02-28 13:30 ` Jerome Brunet
2017-02-28 13:30 ` [PATCH 6/7] clk: meson: mpll: correct N2 maximum value Jerome Brunet
2017-02-28 13:30 ` Jerome Brunet
2017-02-28 13:30 ` [PATCH 7/7] dt-bindings: clk: gxbb: expose i2s output clock gates Jerome Brunet
2017-02-28 13:30 ` Jerome Brunet
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.