[U-Boot] [PATCH v3 1/3] reset: add reset driver for HiSilicon platform

Shawn Guo shawn.guo at linaro.org
Wed Mar 20 03:13:24 UTC 2019


Hi Joe,

Thanks for the comments.

On Tue, Mar 19, 2019 at 06:42:06PM +0000, Joe Hershberger wrote:
> Hi Shawn,
> 
> On Sun, Mar 10, 2019 at 3:53 AM Shawn Guo <shawn.guo at linaro.org> wrote:
> >
> > It adds a Driver Model compatible reset driver for HiSlicon platform.
> > The driver implements a custom .of_xlate function, and uses .data field
> > as reset register offset and .id field as bit shift.
> >
> > Signed-off-by: Shawn Guo <shawn.guo at linaro.org>
> > Reviewed-by: Igor Opaniuk <igor.opaniuk at linaro.org>
> > ---
> >  drivers/reset/Kconfig           |   6 ++
> >  drivers/reset/Makefile          |   1 +
> >  drivers/reset/reset-hisilicon.c | 111 ++++++++++++++++++++++++++++++++
> >  3 files changed, 118 insertions(+)
> >  create mode 100644 drivers/reset/reset-hisilicon.c
> >
> > diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
> > index a81e76769604..6ec6f39c85f0 100644
> > --- a/drivers/reset/Kconfig
> > +++ b/drivers/reset/Kconfig
> > @@ -121,4 +121,10 @@ config RESET_SUNXI
> >           This enables support for common reset driver for
> >           Allwinner SoCs.
> >
> > +config RESET_HISILICON
> > +       bool "Reset controller driver for HiSilicon SoCs"
> > +       depends on DM_RESET
> > +       help
> > +         Support for reset controller on HiSilicon SoCs.
> > +
> >  endmenu
> > diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
> > index 4fad7d412985..7fec75bb4923 100644
> > --- a/drivers/reset/Makefile
> > +++ b/drivers/reset/Makefile
> > @@ -19,3 +19,4 @@ obj-$(CONFIG_RESET_MESON) += reset-meson.o
> >  obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
> >  obj-$(CONFIG_RESET_MEDIATEK) += reset-mediatek.o
> >  obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
> > +obj-$(CONFIG_RESET_HISILICON) += reset-hisilicon.o
> > diff --git a/drivers/reset/reset-hisilicon.c b/drivers/reset/reset-hisilicon.c
> > new file mode 100644
> > index 000000000000..7b0c11fbc82e
> > --- /dev/null
> > +++ b/drivers/reset/reset-hisilicon.c
> > @@ -0,0 +1,111 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2019, Linaro Limited
> > + */
> > +
> > +#include <asm/io.h>
> > +#include <common.h>
> > +#include <dm.h>
> > +#include <dt-bindings/reset/hisi-reset.h>
> 
> Where does this file come from?

Sorry, my bad.  It's a new file in my working tree, and I forgot to add
it.  It becomes unneeded in the next version though.

> 
> 
> > +#include <reset-uclass.h>
> > +
> > +struct hisi_reset_priv {
> > +       void __iomem *base;
> > +};
> > +
> > +static int hisi_reset_deassert(struct reset_ctl *rst)
> > +{
> > +       struct hisi_reset_priv *priv = dev_get_priv(rst->dev);
> > +       u32 offset = rst->data & 0xffff;
> > +       u32 shift = rst->data >> 16;
> > +       int polarity = rst->id;
> > +       u32 val;
> > +
> > +       val = readl(priv->base + offset);
> > +       if (polarity == HISI_RESET_ACTIVE_HIGH)
> > +               val &= ~BIT(shift);
> > +       else
> > +               val |= BIT(shift);
> > +       writel(val, priv->base + offset);
> > +
> > +       return 0;
> > +}
> > +
> > +static int hisi_reset_assert(struct reset_ctl *rst)
> > +{
> > +       struct hisi_reset_priv *priv = dev_get_priv(rst->dev);
> > +       u32 offset = rst->data & 0xffff;
> > +       u32 shift = rst->data >> 16;
> > +       int polarity = rst->id;
> > +       u32 val;
> > +
> > +       val = readl(priv->base + offset);
> > +       if (polarity == HISI_RESET_ACTIVE_HIGH)
> > +               val |= BIT(shift);
> > +       else
> > +               val &= ~BIT(shift);
> > +       writel(val, priv->base + offset);
> > +
> > +       return 0;
> > +}
> > +
> > +static int hisi_reset_free(struct reset_ctl *rst)
> > +{
> > +       return 0;
> > +}
> > +
> > +static int hisi_reset_request(struct reset_ctl *rst)
> > +{
> > +       return 0;
> > +}
> > +
> > +static int hisi_reset_of_xlate(struct reset_ctl *rst,
> > +                              struct ofnode_phandle_args *args)
> > +{
> > +       if (args->args_count != 3) {
> > +               debug("Invalid args_count: %d\n", args->args_count);
> > +               return -EINVAL;
> > +       }
> > +
> > +       /*
> > +        * Encode register offset in .data[15..0] and bit shift in
> > +        * .data[31..16], and use .id field as polarity.
> > +        */
> 
> I don't like going through these contortions to avoid changing the
> struct in reset.h
> 
> I think you should add a "polarity" field to that struct and instead
> of defining a specific constant for HISI_RESET_ACTIVE_HIGH, instead
> make a generic one that everyone can use, such as the ASSERT_CLEAR and
> friends in Linux.

Okay, will do in the next version.  As the ASSERT_CLEAR and friends are
defined in include/dt-bindings/reset/ti-syscon.h (already copied into
U-Boot from Linux), I will just use this header.

> 
> I also hope you can get rid of the register offset and either include
> it in the DT base address if it is something that needs to be selected
> or simply make a #define for the 0xCC for what the register is called
> and go from there.

Although the resets we need for GMAC happen to be in a single register,
the controller includes resets for other modules, that spread in
different registers.  I would like to get the driver ready for other
clients to use in the future.

> If both are not acceptable, I think it makes sense
> to use "data" as the register.
> 
> > +       rst->data = (args->args[1] << 16) | (args->args[0] & 0xffff);
> > +       rst->id = args->args[2];
> 
> I think "id" should be used to hold the "shift" or bit number of the reset.

Yes.  This is exactly what v2 does - use 'data' as register offset and
'id' as shift.  Will go back to this in the next version.

Shawn

> 
> 
> 
> 
> > +
> > +       return 0;
> > +}
> > +
> > +static const struct reset_ops hisi_reset_reset_ops = {
> > +       .of_xlate = hisi_reset_of_xlate,
> > +       .request = hisi_reset_request,
> > +       .free = hisi_reset_free,
> > +       .rst_assert = hisi_reset_assert,
> > +       .rst_deassert = hisi_reset_deassert,
> > +};
> > +
> > +static const struct udevice_id hisi_reset_ids[] = {
> > +       { .compatible = "hisilicon,hi3798cv200-reset" },
> > +       { }
> > +};
> > +
> > +static int hisi_reset_probe(struct udevice *dev)
> > +{
> > +       struct hisi_reset_priv *priv = dev_get_priv(dev);
> > +
> > +       priv->base = dev_remap_addr(dev);
> > +       if (!priv->base)
> > +               return -ENOMEM;
> > +
> > +       return 0;
> > +}
> > +
> > +U_BOOT_DRIVER(hisi_reset) = {
> > +       .name = "hisilicon_reset",
> > +       .id = UCLASS_RESET,
> > +       .of_match = hisi_reset_ids,
> > +       .ops = &hisi_reset_reset_ops,
> > +       .probe = hisi_reset_probe,
> > +       .priv_auto_alloc_size = sizeof(struct hisi_reset_priv),
> > +};
> > --
> > 2.18.0
> >
> > _______________________________________________
> > U-Boot mailing list
> > U-Boot at lists.denx.de
> > https://lists.denx.de/listinfo/u-boot


More information about the U-Boot mailing list