[PATCH 3/7] clk: meson: add triple phase clock driver
Neil Armstrong
narmstrong at baylibre.com
Thu Apr 26 01:47:04 PDT 2018
On 25/04/2018 18:33, Jerome Brunet wrote:
> Add a driver to control the output of the sample clock generator found
> in the axg audio clock controller.
>
> The goal of this driver is to coherently control the phase provided to
> the different element using the sample clock generator. This simplify
> the usage of the sample clock generator a lot, without comprising the
> ability of the SoC.
>
> Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
> ---
> drivers/clk/meson/Kconfig | 5 +++
> drivers/clk/meson/Makefile | 1 +
> drivers/clk/meson/clk-triphase.c | 68 ++++++++++++++++++++++++++++++++++++++++
> drivers/clk/meson/clkc-audio.h | 20 ++++++++++++
> 4 files changed, 94 insertions(+)
> create mode 100644 drivers/clk/meson/clk-triphase.c
> create mode 100644 drivers/clk/meson/clkc-audio.h
>
> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
> index 87d69573e172..7f7fd6fb3809 100644
> --- a/drivers/clk/meson/Kconfig
> +++ b/drivers/clk/meson/Kconfig
> @@ -3,6 +3,11 @@ config COMMON_CLK_AMLOGIC
> depends on ARCH_MESON || COMPILE_TEST
> select COMMON_CLK_REGMAP_MESON
>
> +config COMMON_CLK_AMLOGIC_AUDIO
> + bool
> + depends on ARCH_MESON || COMPILE_TEST
> + select COMMON_CLK_AMLOGIC
> +
> config COMMON_CLK_REGMAP_MESON
> bool
> select REGMAP
> diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
> index 352fb848c406..64bb917fe1f0 100644
> --- a/drivers/clk/meson/Makefile
> +++ b/drivers/clk/meson/Makefile
> @@ -4,6 +4,7 @@
>
> obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o clk-audio-divider.o
> obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-phase.o
> +obj-$(CONFIG_COMMON_CLK_AMLOGIC_AUDIO) += clk-triphase.o
> obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o
> obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o gxbb-aoclk-32k.o
> obj-$(CONFIG_COMMON_CLK_AXG) += axg.o
> diff --git a/drivers/clk/meson/clk-triphase.c b/drivers/clk/meson/clk-triphase.c
> new file mode 100644
> index 000000000000..9508c03c73c1
> --- /dev/null
> +++ b/drivers/clk/meson/clk-triphase.c
> @@ -0,0 +1,68 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2018 BayLibre, SAS.
> + * Author: Jerome Brunet <jbrunet at baylibre.com>
> + */
> +
> +#include <linux/clk-provider.h>
> +#include "clkc-audio.h"
> +
> +/*
> + * This is a special clock for the audio controller.
> + * The phase of mst_sclk clock output can be controlled independently
> + * for the outside world (ph0), the tdmout (ph1) and tdmin (ph2).
> + * Controlling these 3 phases as just one makes things simpler and
> + * give the same clock view to all the element on the i2s bus.
> + * If necessary, we can still control the phase in the tdm block
> + * which makes these independent control redundant.
> + */
> +static inline struct meson_clk_triphase_data *
> +meson_clk_triphase_data(struct clk_regmap *clk)
> +{
> + return (struct meson_clk_triphase_data *)clk->data;
> +}
> +
> +static void meson_clk_triphase_sync(struct clk_hw *hw)
> +{
> + struct clk_regmap *clk = to_clk_regmap(hw);
> + struct meson_clk_triphase_data *tph = meson_clk_triphase_data(clk);
> + unsigned int val;
> +
> + /* Get phase 0 and sync it to phase 1 and 2 */
> + val = meson_parm_read(clk->map, &tph->ph0);
> + meson_parm_write(clk->map, &tph->ph1, val);
> + meson_parm_write(clk->map, &tph->ph2, val);
> +}
> +
> +static int meson_clk_triphase_get_phase(struct clk_hw *hw)
> +{
> + struct clk_regmap *clk = to_clk_regmap(hw);
> + struct meson_clk_triphase_data *tph = meson_clk_triphase_data(clk);
> + unsigned int val;
> +
> + /* Phase are in sync, reading phase 0 is enough */
> + val = meson_parm_read(clk->map, &tph->ph0);
> +
> + return meson_clk_degrees_from_val(val, tph->ph0.width);
> +}
> +
> +static int meson_clk_triphase_set_phase(struct clk_hw *hw, int degrees)
> +{
> + struct clk_regmap *clk = to_clk_regmap(hw);
> + struct meson_clk_triphase_data *tph = meson_clk_triphase_data(clk);
> + unsigned int val;
> +
> + val = meson_clk_degrees_to_val(degrees, tph->ph0.width);
> + meson_parm_write(clk->map, &tph->ph0, val);
> + meson_parm_write(clk->map, &tph->ph1, val);
> + meson_parm_write(clk->map, &tph->ph2, val);
> +
> + return 0;
> +}
> +
> +const struct clk_ops meson_clk_triphase_ops = {
> + .init = meson_clk_triphase_sync,
> + .get_phase = meson_clk_triphase_get_phase,
> + .set_phase = meson_clk_triphase_set_phase,
> +};
> +EXPORT_SYMBOL_GPL(meson_clk_triphase_ops);
> diff --git a/drivers/clk/meson/clkc-audio.h b/drivers/clk/meson/clkc-audio.h
> new file mode 100644
> index 000000000000..286ff1201258
> --- /dev/null
> +++ b/drivers/clk/meson/clkc-audio.h
> @@ -0,0 +1,20 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
// SPDX-License-Identifier: GPL-2.0
Checkpatch should have warned about this !
> +/*
> + * Copyright (c) 2018 BayLibre, SAS.
> + * Author: Jerome Brunet <jbrunet at baylibre.com>
> + */
> +
> +#ifndef __MESON_CLKC_AUDIO_H
> +#define __MESON_CLKC_AUDIO_H
> +
> +#include "clkc.h"
> +
> +struct meson_clk_triphase_data {
> + struct parm ph0;
> + struct parm ph1;
> + struct parm ph2;
> +};
> +
> +extern const struct clk_ops meson_clk_triphase_ops;
> +
> +#endif /* __MESON_CLKC_AUDIO_H */
>
Apart that :
Acked-by: Neil Armstrong <narmstrong at baylibre.com>
More information about the linux-amlogic
mailing list