Re: [PATCH 3/8] of/fdt: add function to get the SoC wide DMA addressable memory size

From: Nicolas Saenz Julienne
Date: Tue Aug 06 2019 - 14:12:21 EST


Hi Rob,

On Mon, 2019-08-05 at 13:23 -0600, Rob Herring wrote:
> On Mon, Aug 5, 2019 at 10:03 AM Nicolas Saenz Julienne
> <nsaenzjulienne@xxxxxxx> wrote:
> > Hi Rob,
> > Thanks for the review!
> >
> > On Fri, 2019-08-02 at 11:17 -0600, Rob Herring wrote:
> > > On Wed, Jul 31, 2019 at 9:48 AM Nicolas Saenz Julienne
> > > <nsaenzjulienne@xxxxxxx> wrote:
> > > > Some SoCs might have multiple interconnects each with their own DMA
> > > > addressing limitations. This function parses the 'dma-ranges' on each of
> > > > them and tries to guess the maximum SoC wide DMA addressable memory
> > > > size.
> > > >
> > > > This is specially useful for arch code in order to properly setup CMA
> > > > and memory zones.
> > >
> > > We already have a way to setup CMA in reserved-memory, so why is this
> > > needed for that?
> >
> > Correct me if I'm wrong but I got the feeling you got the point of the patch
> > later on.
>
> No, for CMA I don't. Can't we already pass a size and location for CMA
> region under /reserved-memory. The only advantage here is perhaps the
> CMA range could be anywhere in the DMA zone vs. a fixed location.

Now I get it, sorry I wasn't aware of that interface.

Still, I'm not convinced it matches RPi's use case as this would hard-code
CMA's size. Most people won't care, but for the ones that do, it's nicer to
change the value from the kernel command line than editing the dtb. I get that
if you need to, for example, reserve some memory for the video to work, it's
silly not to hard-code it. Yet due to the board's nature and users base I say
it's important to favor flexibility. It would also break compatibility with
earlier versions of the board and diverge from the downstream kernel behaviour.
Which is a bigger issue than it seems as most users don't always understand
which kernel they are running and unknowingly copy configuration options from
forums.

As I also need to know the DMA addressing limitations to properly configure
memory zones and dma-direct. Setting up the proper CMA constraints during the
arch's init will be trivial anyway.

> > > IMO, I'd just do:
> > >
> > > if (of_fdt_machine_is_compatible(blob, "brcm,bcm2711"))
> > > dma_zone_size = XX;
> > >
> > > 2 lines of code is much easier to maintain than 10s of incomplete code
> > > and is clearer who needs this. Maybe if we have dozens of SoCs with
> > > this problem we should start parsing dma-ranges.
> >
> > FYI that's what arm32 is doing at the moment and was my first instinct. But
> > it
> > seems that arm64 has been able to survive so far without any machine
> > specific
> > code and I have the feeling Catalin and Will will not be happy about this
> > solution. Am I wrong?
>
> No doubt. I'm fine if the 2 lines live in drivers/of/.
>
> Note that I'm trying to reduce the number of early_init_dt_scan_*
> calls from arch code into the DT code so there's more commonality
> across architectures in the early DT scans. So ideally, this can all
> be handled under early_init_dt_scan() call.

How does this look? (I'll split it in two patches and add a comment explaining
why dt_dma_zone_size is needed)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index f2444c61a136..1395be40b722 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -30,6 +30,8 @@

#include "of_private.h"

+u64 dt_dma_zone_size __ro_after_init;
+
/*
* of_fdt_limit_memory - limit the number of regions in the /memory node
* @limit: maximum entries
@@ -802,6 +805,11 @@ const char * __init of_flat_dt_get_machine_name(void)
return name;
}

+static const int __init of_fdt_machine_is_compatible(char *name)
+{
+ return of_compat_cmp(of_flat_dt_get_machine_name(), name, strlen(name));
+}
+
/**
* of_flat_dt_match_machine - Iterate match tables to find matching machine.
*
@@ -1260,6 +1268,14 @@ void __init early_init_dt_scan_nodes(void)
of_scan_flat_dt(early_init_dt_scan_memory, NULL);
}

+void __init early_init_dt_get_dma_zone_size(void)
+{
+ dt_dma_zone_size = 0;
+
+ if (of_fdt_machine_is_compatible("brcm,bcm2711"))
+ dt_dma_zone_size = 0x3c000000;
+}
+
bool __init early_init_dt_scan(void *params)
{
bool status;
@@ -1269,6 +1285,7 @@ bool __init early_init_dt_scan(void *params)
return false;

early_init_dt_scan_nodes();
+ early_init_dt_get_dma_zone_size();
return true;
}
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index 2ad36b7bd4fa..b5a9f685de14 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -27,6 +27,8 @@ extern void *of_fdt_unflatten_tree(const unsigned long *blob,
struct device_node *dad,
struct device_node **mynodes);

+extern u64 dt_dma_zone_size __ro_after_init;
+
/* TBD: Temporary export of fdt globals - remove when code fully merged */
extern int __initdata dt_root_addr_cells;
extern int __initdata dt_root_size_cells;


Regards,
Nicolas


Attachment: signature.asc
Description: This is a digitally signed message part