On Mon, Jan 21, 2019 at 5:39 PM Andre Przywara <andre.przyw...@arm.com> wrote:
>
> On Mon, 21 Jan 2019 17:34:25 +0800
> Chen-Yu Tsai <w...@csie.org> wrote:
>
> > On Mon, Jan 21, 2019 at 5:32 PM Jagan Teki
> > <ja...@amarulasolutions.com> wrote:
> > >
> > > On Sat, Jan 19, 2019 at 7:02 AM Andre Przywara
> > > <andre.przyw...@arm.com> wrote:
> > > >
> > > > The A80 handles resets and clock gates for the MMC devices
> > > > differently, outside of the CCU IP block. Consequently we have a
> > > > separate clock device with a separate binding for that.
> > > >
> > > > Implement that with the respective clock gates and resets to
> > > > allow the A80 taking part in the DM_MMC game.
> > > >
> > > > Signed-off-by: Andre Przywara <andre.przyw...@arm.com>
> > > > ---
> > > >  drivers/clk/sunxi/clk_a80.c | 28 +++++++++++++++++++++++++++-
> > > >  1 file changed, 27 insertions(+), 1 deletion(-)
> > > >
> > > > diff --git a/drivers/clk/sunxi/clk_a80.c
> > > > b/drivers/clk/sunxi/clk_a80.c index d6dd6a1fa1..2bfc2ca9f5 100644
> > > > --- a/drivers/clk/sunxi/clk_a80.c
> > > > +++ b/drivers/clk/sunxi/clk_a80.c
> > > > @@ -30,19 +30,45 @@ static const struct ccu_reset a80_resets[] = {
> > > >         [RST_BUS_UART5]         = RESET(0x5b4, BIT(21)),
> > > >  };
> > > >
> > > > +static const struct ccu_clk_gate a80_mmc_gates[] = {
> > > > +       [0]                     = GATE(0x0, BIT(16)),
> > > > +       [1]                     = GATE(0x4, BIT(16)),
> > > > +       [2]                     = GATE(0x8, BIT(16)),
> > > > +       [3]                     = GATE(0xc, BIT(16)),
> > > > +};
> > > > +
> > > > +static const struct ccu_reset a80_mmc_resets[] = {
> > > > +       [0]                     = GATE(0x0, BIT(18)),
> > > > +       [1]                     = GATE(0x4, BIT(18)),
> > > > +       [2]                     = GATE(0x8, BIT(18)),
> > > > +       [3]                     = GATE(0xc, BIT(18)),
> > > > +};
> > > > +
> > > >  static const struct ccu_desc a80_ccu_desc = {
> > > >         .gates = a80_gates,
> > > >         .resets = a80_resets,
> > > >  };
> > > >
> > > > +static const struct ccu_desc a80_mmc_clk_desc = {
> > > > +       .gates = a80_mmc_gates,
> > > > +       .resets = a80_mmc_resets,
> > > > +};
> > > > +
> > > >  static int a80_clk_bind(struct udevice *dev)
> > > >  {
> > > > -       return sunxi_reset_bind(dev, ARRAY_SIZE(a80_resets));
> > > > +       ulong count = ARRAY_SIZE(a80_resets);
> > > > +
> > > > +       if (device_is_compatible(dev,
> > > > "allwinner,allwinner,sun9i-a80-mmc"))
> > > > +               count = ARRAY_SIZE(a80_mmc_resets);
> > > > +
> > > > +       return sunxi_reset_bind(dev, count);
> > > >  }
> > > >
> > > >  static const struct udevice_id a80_ccu_ids[] = {
> > > >         { .compatible = "allwinner,sun9i-a80-ccu",
> > > >           .data = (ulong)&a80_ccu_desc },
> > > > +       { .compatible = "allwinner,allwinner,sun9i-a80-mmc",
> > >
> > > This can be "allwinner,sun9i-a80-mmc-config-clk"
> >
> > *Must*, not can. :)
>
> Indeed, thanks for spotting this, Jagan.
>
> Also I just figured that we need to enable the parent clocks and resets
> of this clock itself. I hope we can do this unconditionally, even for
> the complex CCU, as enabling fixed-clocks should be covered by the clock
> framework already.

You need to deassert the reset control for the MMC clock config block,
otherwise none of the toggles are going to work. And you can't assert
it afterwards, otherwise the bits revert to default. Also, you need to
enable the bus clock to be able to access the bits.

So yeah, you can do this unconditionally. The Linux driver simply tries
to be smarter and only enables the bus clock when toggling the bits.

Regards
ChenYu
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to