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 > 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 > > > 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