[U-Boot] [PATCH v2 09/10] clk: boston: Providea simple driver for Boston board clocks

Simon Glass sjg at chromium.org
Mon Aug 1 03:01:53 CEST 2016


Hi Paul,

On 27 July 2016 at 08:26, Paul Burton <paul.burton at imgtec.com> wrote:
> Add a simple driver for the clocks provided by the MIPS Boston
> development board. The system provides information about 2 clocks whose
> rates are fixed by the bitfile flashed in the boards FPGA, and this
> driver simply reads the rates of these 2 clocks.
>
> Signed-off-by: Paul Burton <paul.burton at imgtec.com>
>
> ---
>
> Changes in v2:
> - New patch
>
>  drivers/clk/Kconfig                      |  8 +++
>  drivers/clk/Makefile                     |  1 +
>  drivers/clk/clk_boston.c                 | 96 ++++++++++++++++++++++++++++++++
>  include/dt-bindings/clock/boston-clock.h | 13 +++++
>  4 files changed, 118 insertions(+)
>  create mode 100644 drivers/clk/clk_boston.c
>  create mode 100644 include/dt-bindings/clock/boston-clock.h

Reviewed-by: Simon Glass <sjg at chromium.org>

>
> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
> index 6eee8eb..85eea0d 100644
> --- a/drivers/clk/Kconfig
> +++ b/drivers/clk/Kconfig
> @@ -20,6 +20,14 @@ config SPL_CLK
>           setting up clocks within SPL, and allows the same drivers to be
>           used as U-Boot proper.
>
> +config CLK_BOSTON
> +       def_bool y if TARGET_BOSTON
> +       depends on CLK
> +       select REGMAP
> +       select SYSCON
> +       help
> +         Enable this to support the clocks
> +
>  source "drivers/clk/uniphier/Kconfig"
>  source "drivers/clk/exynos/Kconfig"
>
> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> index f7a8891..9d14122 100644
> --- a/drivers/clk/Makefile
> +++ b/drivers/clk/Makefile
> @@ -13,3 +13,4 @@ obj-$(CONFIG_SANDBOX) += clk_sandbox_test.o
>  obj-$(CONFIG_MACH_PIC32) += clk_pic32.o
>  obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
>  obj-$(CONFIG_CLK_EXYNOS) += exynos/
> +obj-$(CONFIG_CLK_BOSTON) += clk_boston.o
> diff --git a/drivers/clk/clk_boston.c b/drivers/clk/clk_boston.c
> new file mode 100644
> index 0000000..dbbb05b
> --- /dev/null
> +++ b/drivers/clk/clk_boston.c
> @@ -0,0 +1,96 @@
> +/*
> + * Copyright (C) 2016 Imagination Technologies
> + *
> + * SPDX-License-Identifier:    GPL-2.0
> + */
> +
> +#include <common.h>
> +#include <clk-uclass.h>
> +#include <dm.h>
> +#include <dt-bindings/clock/boston-clock.h>
> +#include <regmap.h>
> +#include <syscon.h>
> +
> +struct clk_boston {
> +       struct regmap *regmap;
> +};
> +
> +#define BOSTON_PLAT_MMCMDIV            0x30
> +# define BOSTON_PLAT_MMCMDIV_CLK0DIV   (0xff << 0)
> +# define BOSTON_PLAT_MMCMDIV_INPUT     (0xff << 8)
> +# define BOSTON_PLAT_MMCMDIV_MUL       (0xff << 16)
> +# define BOSTON_PLAT_MMCMDIV_CLK1DIV   (0xff << 24)
> +
> +static ulong clk_boston_get_rate(struct clk *clk)
> +{
> +       struct clk_boston *state = dev_get_platdata(clk->dev);
> +       uint32_t in_rate, mul, div;
> +       uint mmcmdiv;
> +       int err;
> +
> +       err = regmap_read(state->regmap, BOSTON_PLAT_MMCMDIV, &mmcmdiv);
> +       if (err)
> +               return 0;
> +
> +#define EXT(field) ((mmcmdiv & field) >> (ffs(field) - 1))

Why not use a function for this?

> +
> +       in_rate = EXT(BOSTON_PLAT_MMCMDIV_INPUT);
> +       mul = EXT(BOSTON_PLAT_MMCMDIV_MUL);
> +
> +       switch (clk->id) {
> +       case BOSTON_CLK_SYS:
> +               div = EXT(BOSTON_PLAT_MMCMDIV_CLK0DIV);
> +               break;
> +       case BOSTON_CLK_CPU:
> +               div = EXT(BOSTON_PLAT_MMCMDIV_CLK1DIV);
> +               break;
> +       default:
> +               return 0;
> +       }
> +
> +#undef EXT
> +
> +       return (in_rate * mul * 1000000) / div;
> +}
> +
> +const struct clk_ops clk_boston_ops = {
> +       .get_rate = clk_boston_get_rate,
> +};
> +
> +static int clk_boston_ofdata_to_platdata(struct udevice *dev)
> +{
> +       struct clk_boston *state = dev_get_platdata(dev);
> +       struct udevice *syscon;
> +       int err;
> +
> +       err = uclass_get_device_by_phandle(UCLASS_SYSCON, dev,
> +                                          "regmap", &syscon);

Note that this is slow. But perhaps it doesn't matter.

> +       if (err) {
> +               error("unable to find syscon device\n");
> +               return err;
> +       }
> +
> +       state->regmap = syscon_get_regmap(syscon);
> +       if (!state->regmap) {
> +               error("unable to find regmap\n");
> +               return -ENODEV;
> +       }
> +
> +       return 0;
> +}
> +
> +static const struct udevice_id clk_boston_match[] = {
> +       {
> +               .compatible = "img,boston-clock",
> +       },
> +       { /* sentinel */ }
> +};
> +
> +U_BOOT_DRIVER(clk_boston) = {
> +       .name = "boston_clock",
> +       .id = UCLASS_CLK,
> +       .of_match = clk_boston_match,
> +       .ofdata_to_platdata = clk_boston_ofdata_to_platdata,
> +       .platdata_auto_alloc_size = sizeof(struct clk_boston),
> +       .ops = &clk_boston_ops,
> +};
> diff --git a/include/dt-bindings/clock/boston-clock.h b/include/dt-bindings/clock/boston-clock.h
> new file mode 100644
> index 0000000..25f9cd2
> --- /dev/null
> +++ b/include/dt-bindings/clock/boston-clock.h
> @@ -0,0 +1,13 @@
> +/*
> + * Copyright (C) 2016 Imagination Technologies
> + *
> + * SPDX-License-Identifier:    GPL-2.0
> + */
> +
> +#ifndef __DT_BINDINGS_CLOCK_BOSTON_CLOCK_H__
> +#define __DT_BINDINGS_CLOCK_BOSTON_CLOCK_H__
> +
> +#define BOSTON_CLK_SYS 0
> +#define BOSTON_CLK_CPU 1
> +
> +#endif /* __DT_BINDINGS_CLOCK_BOSTON_CLOCK_H__ */
> --
> 2.9.0
>

Regards,
Simon


More information about the U-Boot mailing list