[U-Boot] [linux-sunxi] [PATCH 2/9] sunxi: clk: A80: add MMC clock support
Chen-Yu Tsai
wens at csie.org
Mon Jan 21 10:02:17 UTC 2019
On Mon, Jan 21, 2019 at 5:39 PM Andre Przywara <andre.przywara at arm.com> wrote:
>
> On Mon, 21 Jan 2019 17:34:25 +0800
> Chen-Yu Tsai <wens at csie.org> wrote:
>
> > On Mon, Jan 21, 2019 at 5:32 PM Jagan Teki
> > <jagan at amarulasolutions.com> wrote:
> > >
> > > On Sat, Jan 19, 2019 at 7:02 AM Andre Przywara
> > > <andre.przywara at 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.przywara at 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
More information about the U-Boot
mailing list