All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mark Kettenis <mark.kettenis@xs4all.nl>
To: Simon Glass <sjg@chromium.org>
Cc: kettenis@openbsd.org, u-boot@lists.denx.de,
	oliver.graute@kococonnector.com, stephan@gerhold.net,
	masami.hiramatsu@linaro.org, priyanka.jain@nxp.com,
	ycliang@andestech.com, padmarao.begari@microchip.com,
	michael@walle.cc, kishon@ti.com, xypron.glpk@gmx.de,
	bin.meng@windriver.com, ashe@kivikakk.ee,
	michal.simek@xilinx.com, wasim.khan@nxp.com, hs@denx.de,
	igor.opaniuk@foundries.io, ye.li@nxp.com, sr@denx.de,
	takahiro.akashi@linaro.org, weijie.gao@mediatek.com,
	vabhav.sharma@nxp.com, andriy.shevchenko@linux.intel.com,
	p.yadav@ti.com
Subject: Re: [PATCH 3/5] misc: Add Apple DART driver
Date: Mon, 20 Sep 2021 10:33:47 +0200 (CEST)	[thread overview]
Message-ID: <56146d936d16f96c@bloch.sibelius.xs4all.nl> (raw)
In-Reply-To: <CAPnjgZ0s9Lr2H8tYkg1k+uOvqpmC=GdU_O6f0hXx2Whdaz2uHw@mail.gmail.com> (message from Simon Glass on Sun, 19 Sep 2021 21:16:00 -0600)

> From: Simon Glass <sjg@chromium.org>
> Date: Sun, 19 Sep 2021 21:16:00 -0600
> 
> Hi Mark,
> 
> On Sat, 18 Sept 2021 at 07:55, Mark Kettenis <kettenis@openbsd.org> wrote:
> >
> > The DART is an IOMMU that is used on Apple's M1 SoC.  This driver
> > supports the DART in bypass mode as well as in a mode where it
> > creates a 1:1 mapping of a subset of RAM as not all DARTs support
> > bypass mode.  The USB3 ports integrated on the SoC use a DART
> > that supports bypass mode.  The 1:1 mapping will be used in the
> > future to support other devices such as the PCIe host bridge
> > of the M1 SoC.
> >
> > Signed-off-by: Mark Kettenis <kettenis@openbsd.org>
> > ---
> >  drivers/misc/Kconfig      |   7 ++
> >  drivers/misc/Makefile     |   1 +
> >  drivers/misc/apple_dart.c | 171 ++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 179 insertions(+)
> >  create mode 100644 drivers/misc/apple_dart.c
> >
> > diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
> > index 997b713221..d70b060e74 100644
> > --- a/drivers/misc/Kconfig
> > +++ b/drivers/misc/Kconfig
> > @@ -38,6 +38,13 @@ config ALTERA_SYSID
> >           Select this to enable a sysid for Altera devices. Please find
> >           details on the "Embedded Peripherals IP User Guide" of Altera.
> >
> > +config APPLE_DART
> > +       bool "Apple DART support"
> > +       depends on MISC && ARCH_APPLE
> > +       default y
> > +       help
> > +         Enable support for the DART on Apple SoCs.
> 
> Should have at least 3 lines. E.g. what does DART stand for, what does
> it do and what does the driver support?

Sure.  The DART is what we usually call an IOMMU.

> > +
> >  config ATSHA204A
> >         bool "Support for Atmel ATSHA204A module"
> >         depends on MISC
> > diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> > index b64cd2a4de..f666cd392d 100644
> > --- a/drivers/misc/Makefile
> > +++ b/drivers/misc/Makefile
> > @@ -29,6 +29,7 @@ endif
> >  endif
> >  obj-$(CONFIG_ALI152X) += ali512x.o
> >  obj-$(CONFIG_ALTERA_SYSID) += altera_sysid.o
> > +obj-$(CONFIG_APPLE_DART) += apple_dart.o
> >  obj-$(CONFIG_ATSHA204A) += atsha204a-i2c.o
> >  obj-$(CONFIG_CBMEM_CONSOLE) += cbmem_console.o
> >  obj-$(CONFIG_DS4510)  += ds4510.o
> > diff --git a/drivers/misc/apple_dart.c b/drivers/misc/apple_dart.c
> > new file mode 100644
> > index 0000000000..f619a624d0
> > --- /dev/null
> > +++ b/drivers/misc/apple_dart.c
> > @@ -0,0 +1,171 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Copyright (C) 2021 Mark Kettenis <kettenis@openbsd.org>
> > + */
> > +
> > +#include <common.h>
> > +#include <clk.h>
> > +#include <cpu_func.h>
> > +#include <dm.h>
> > +#include <mapmem.h>
> > +#include <asm/io.h>
> > +
> > +#define DART_PARAMS2           0x0004
> > +#define  DART_PARAMS2_BYPASS_SUPPORT   BIT(0)
> > +#define DART_TLB_OP            0x0020
> > +#define  DART_TLB_OP_OPMASK    (0xfff << 20)
> > +#define  DART_TLB_OP_FLUSH     (0x001 << 20)
> > +#define  DART_TLB_OP_BUSY      BIT(2)
> > +#define DART_TLB_OP_SIDMASK    0x0034
> > +#define DART_ERROR_STATUS      0x0040
> > +#define DART_TCR(sid)          (0x0100 + 4 * (sid))
> > +#define  DART_TCR_TRANSLATE_ENABLE     BIT(7)
> > +#define  DART_TCR_BYPASS_DART          BIT(8)
> > +#define  DART_TCR_BYPASS_DAPF          BIT(12)
> > +#define DART_TTBR(sid, idx)    (0x0200 + 16 * (sid) + 4 * (idx))
> > +#define  DART_TTBR_VALID       BIT(31)
> > +#define  DART_TTBR_SHIFT       12
> > +
> > +struct apple_dart_priv {
> 
> How about s/apple_dart/dart/ ?
> 
> It makes the code easier to read.

I think using apple_dart_ consistently as a prefix makes more sense.

> > +       struct clk_bulk clks;
> > +       void *base;
> > +};
> > +
> > +dma_addr_t apple_dart_bus_start;
> > +phys_addr_t apple_dart_phys_start;
> > +phys_size_t apple_dart_size = SZ_512M;
> 
> Try to avoid variables in drivers. Can these go in a priv struct?

Not really since the intent is that these variables specify a global
"window" that is mapped 1:1 into all the DARTs.

> > +
> > +static void apple_dart_flush_tlb(struct apple_dart_priv *priv)
> 
> comments on these functions
> 
> > +{
> > +       u32 status;
> > +
> > +       writel(0xffffffff, priv->base + DART_TLB_OP_SIDMASK);
> > +       writel(DART_TLB_OP_FLUSH, priv->base + DART_TLB_OP);
> > +
> > +       for (;;) {
> > +               status = readl(priv->base + DART_TLB_OP);
> > +               if ((status & DART_TLB_OP_OPMASK) == 0)
> > +                       break;
> > +               if ((status & DART_TLB_OP_BUSY) == 0)
> > +                       break;
> > +       }
> > +}
> > +
> > +static int apple_dart_clk_init(struct udevice *dev,
> > +                              struct apple_dart_priv *priv)
> > +{
> > +       int ret;
> > +
> > +       ret = clk_get_bulk(dev, &priv->clks);
> > +       if (ret == -ENOSYS || ret == -ENOENT)
> 
> Does -ENOSYS not indicate an error? If it doesn't, I think a comment
> would help here.

So we just learned that what we previously considered to be clocks are
really better modelled as power domains.  So this code will go away.

> > +               return 0;
> > +       if (ret)
> > +               return ret;
> > +
> > +       ret = clk_enable_bulk(&priv->clks);
> > +       if (ret) {
> > +               clk_release_bulk(&priv->clks);
> > +               return ret;
> > +       }
> > +
> > +       return 0;
> > +}
> > +
> > +static int apple_dart_bind(struct udevice *dev)
> > +{
> > +       void *base;
> > +       int sid, i;
> > +
> > +       base = dev_read_addr_ptr(dev);
> > +       if (!base)
> > +               return -EINVAL;
> > +
> > +       u32 params2 = readl(base + DART_PARAMS2);
> > +       if (params2 & DART_PARAMS2_BYPASS_SUPPORT) {
> > +               for (sid = 0; sid < 16; sid++) {
> > +                       writel(DART_TCR_BYPASS_DART | DART_TCR_BYPASS_DAPF,
> > +                              base + DART_TCR(sid));
> > +                       for (i = 0; i < 4; i++)
> > +                               writel(0, base + DART_TTBR(sid, i));
> > +               }
> > +       }
> 
> Not allowed hardware access in bind(). Can this more to probe() ?

Well, I need to make sure that this happens before other drivers get
probed (in particular the xhci-dwc3 driver).  Is there a better
mechanism to achieve that?

> > +
> > +       return 0;
> > +}
> > +
> > +static int apple_dart_probe(struct udevice *dev)
> > +{
> > +       struct apple_dart_priv *priv = dev_get_priv(dev);
> > +       phys_addr_t phys;
> > +       u64 *l1, *l2;
> > +       int sid, i, j;
> > +       int ret;
> > +
> > +       apple_dart_phys_start = gd->ram_top - apple_dart_size;
> > +
> > +       priv->base = dev_read_addr_ptr(dev);
> > +       if (!priv->base)
> > +               return -EINVAL;
> > +
> > +       ret = apple_dart_clk_init(dev, priv);
> > +       if (ret)
> > +               return ret;
> > +
> > +       l1 = memalign(SZ_64K, SZ_64K);
> > +       memset(l1, 0, SZ_64K);
> > +
> > +       i = 0;
> > +       phys = apple_dart_phys_start;
> > +       while (phys < apple_dart_phys_start + apple_dart_size) {
> > +               l2 = memalign(SZ_16K, SZ_16K);
> 
> check for error
> 
> > +               memset(l2, 0, SZ_16K);
> > +
> > +               for (j = 0; j < 2048; j++) {
> > +                       l2[j] = phys | 0x3;
> > +                       phys += SZ_16K;
> > +               }
> > +               flush_dcache_range((unsigned long)l2,
> > +                                  (unsigned long)l2 + SZ_16K);
> > +
> > +               l1[i++] = (phys_addr_t)l2 | 0x8 | 0x3;
> 
> Do you need the cast? What are the magic numbers here? Can you use an
> enum/#define ?

Not sure if we know the exact meaning of those bits yet.  But there is
a Linux driver now, so maybe I need to look at it again.

> > +       }
> > +
> > +       flush_dcache_range((unsigned long)l1, (unsigned long)l1 + SZ_64K);
> > +
> > +       for (sid = 0; sid < 16; sid++) {
> 
> comment,...what is this doing?
> 
> > +               for (i = 0; i < 4; i++)
> > +                       writel(0, priv->base + DART_TTBR(sid, i));
> > +       }
> > +
> > +       apple_dart_flush_tlb(priv);
> > +
> > +       for (sid = 0; sid < 16; sid++) {
> > +               phys = (phys_addr_t)l1;
> > +               for (i = 0; i < 4; i++) {
> > +                       writel((phys >> DART_TTBR_SHIFT) | DART_TTBR_VALID,
> > +                              priv->base + DART_TTBR(sid, i));
> > +                       phys += SZ_16K;
> > +               }
> > +       }
> > +
> > +       apple_dart_flush_tlb(priv);
> > +
> > +       for (sid = 0; sid < 16; sid++)
> > +               writel(DART_TCR_TRANSLATE_ENABLE, priv->base + DART_TCR(sid));
> > +
> > +       return 0;
> > +}
> > +
> > +static const struct udevice_id apple_dart_ids[] = {
> > +       { .compatible = "apple,t8103-dart" },
> > +       { /* sentinel */ }
> > +};
> > +
> > +U_BOOT_DRIVER(apple_dart) = {
> > +       .name = "apple_dart",
> > +       .id = UCLASS_MISC,
> > +       .of_match = apple_dart_ids,
> > +       .priv_auto = sizeof(struct apple_dart_priv),
> > +       .bind = apple_dart_bind,
> > +       .probe = apple_dart_probe
> > +};
> > --
> > 2.33.0
> >
> 
> Regards,
> Simon
> 

  reply	other threads:[~2021-09-20  8:33 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-18 13:54 [PATCH 0/5] Apple M1 Support Mark Kettenis
2021-09-18 13:54 ` [PATCH 1/5] arm: apple: Add initial support for Apple's M1 SoC Mark Kettenis
2021-09-19  1:04   ` Bin Meng
2021-09-19  1:17     ` Bin Meng
2021-09-19 20:33       ` Mark Kettenis
2021-09-21 12:42         ` Tom Rini
2021-09-21 15:53           ` Bin Meng
2021-09-21 16:04             ` Tom Rini
2021-09-21 16:08             ` Mark Kettenis
2021-09-25 13:27               ` Simon Glass
2021-09-19 20:05     ` Mark Kettenis
2021-09-20  3:15   ` Simon Glass
2021-09-20  8:49     ` Mark Kettenis
2021-09-21  1:11       ` Simon Glass
2021-09-18 13:54 ` [PATCH 2/5] serial: s5p: Add Apple M1 support Mark Kettenis
2021-09-19  1:11   ` Bin Meng
2021-09-19 20:30     ` Mark Kettenis
2021-09-20  3:15   ` Simon Glass
2021-09-25 13:27     ` Simon Glass
2021-10-02 22:15     ` Mark Kettenis
2021-10-03  2:01       ` Simon Glass
2021-09-18 13:54 ` [PATCH 3/5] misc: Add Apple DART driver Mark Kettenis
2021-09-20  3:16   ` Simon Glass
2021-09-20  8:33     ` Mark Kettenis [this message]
2021-09-21  1:11       ` Simon Glass
2021-09-25 13:27         ` Simon Glass
2021-09-26 20:53         ` Mark Kettenis
2021-09-27 20:14           ` Simon Glass
2021-09-18 13:54 ` [PATCH 4/5] arm: dts: apple: Add preliminary device trees Mark Kettenis
2021-09-20  3:16   ` Simon Glass
2021-09-25 13:27     ` Simon Glass
2021-09-18 13:54 ` [PATCH 5/5] doc: board: apple: Add Apple M1 documentation Mark Kettenis
2021-09-19  1:22   ` Bin Meng
2021-09-20  3:16   ` Simon Glass
2021-09-25 13:27     ` Simon Glass
2021-09-20  8:45   ` Igor Opaniuk
2021-09-25  1:20 ` [PATCH 0/5] Apple M1 Support Simon Glass
2021-09-25  8:11   ` Mark Kettenis
2021-09-25 13:27     ` Simon Glass
2021-09-25 13:52       ` Mark Kettenis
2021-09-25 14:42         ` Simon Glass
2021-09-25 16:45           ` Mark Kettenis
2021-09-26 15:53             ` Simon Glass
2021-09-28  3:46               ` Simon Glass
2021-09-28  7:36                 ` Mark Kettenis
2021-09-28 12:07                   ` Simon Glass

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=56146d936d16f96c@bloch.sibelius.xs4all.nl \
    --to=mark.kettenis@xs4all.nl \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=ashe@kivikakk.ee \
    --cc=bin.meng@windriver.com \
    --cc=hs@denx.de \
    --cc=igor.opaniuk@foundries.io \
    --cc=kettenis@openbsd.org \
    --cc=kishon@ti.com \
    --cc=masami.hiramatsu@linaro.org \
    --cc=michael@walle.cc \
    --cc=michal.simek@xilinx.com \
    --cc=oliver.graute@kococonnector.com \
    --cc=p.yadav@ti.com \
    --cc=padmarao.begari@microchip.com \
    --cc=priyanka.jain@nxp.com \
    --cc=sjg@chromium.org \
    --cc=sr@denx.de \
    --cc=stephan@gerhold.net \
    --cc=takahiro.akashi@linaro.org \
    --cc=u-boot@lists.denx.de \
    --cc=vabhav.sharma@nxp.com \
    --cc=wasim.khan@nxp.com \
    --cc=weijie.gao@mediatek.com \
    --cc=xypron.glpk@gmx.de \
    --cc=ycliang@andestech.com \
    --cc=ye.li@nxp.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.