[PATCH v3 06/12] dm: Introduce DMA constraints into the core device model
Simon Glass
sjg at chromium.org
Sat Dec 19 03:28:45 CET 2020
Hi Nicolas,
On Tue, 15 Dec 2020 at 10:23, Nicolas Saenz Julienne
<nsaenzjulienne at suse.de> wrote:
>
> Calculating the DMA offset between a bus address space and CPU's every
> time we call phys_to_bus() and bus_to_phys() isn't ideal performance
> wise, as it implies traversing the device tree from the device's node up
> to the root. Since this information is static and available before the
> device's initialization, parse it before the probe call an provide the
> DMA offset in 'struct udevice' for the address translation code to use
> it.
>
> Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne at suse.de>
>
> ---
> Changes since v2:
> - Return/Fail on error
> - Add config option
> - use ulong instead for u64 for dev->dma_offset
>
> Changes since v1:
> - Update commit message so as to explain better the reasoning behind
> this
>
> drivers/core/Kconfig | 10 ++++++++++
> drivers/core/device.c | 35 +++++++++++++++++++++++++++++++++++
> include/dm/device.h | 3 +++
> 3 files changed, 48 insertions(+)
Reviewed-by: Simon Glass <sjg at chromium.org>
nits below
>
> diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig
> index ffae6f9795..153be25351 100644
> --- a/drivers/core/Kconfig
> +++ b/drivers/core/Kconfig
> @@ -113,6 +113,16 @@ config SPL_DM_SEQ_ALIAS
> numbered devices (e.g. serial0 = &serial0). This feature can be
> disabled if it is not required, to save code space in SPL.
>
> +config DM_DMA
> + bool "Support per device DMA constraints"
per-device
> + depends on DM
> + default n
> + help
> + Enable this to extract per-device DMA constraints, only supported on
> + device-tree systems for now. This is needed in order translate
> + addresses on systems where different buses have different views of
> + the physical address space.
> +
> config REGMAP
> bool "Support register maps"
> depends on DM
> diff --git a/drivers/core/device.c b/drivers/core/device.c
> index 4b3dcb3b37..21285432d8 100644
> --- a/drivers/core/device.c
> +++ b/drivers/core/device.c
> @@ -421,6 +421,37 @@ fail:
> return ret;
> }
>
> +#if CONFIG_IS_ENABLED(DM_DMA)
I feel you could use
if (CONFIG_IS_ENABLED)
in the function below (returning at the start) and avoid an #ifdef?
To do that you'll need access macros - you can see things like that in
device.h and asm-generic/global_data.h
> +static int device_get_dma_constraints(struct udevice *dev)
Please add a comment to describe this function.
> +{
> + struct udevice *parent = dev->parent;
> + phys_addr_t cpu = 0;
> + dma_addr_t bus = 0;
> + u64 size = 0;
> + int ret;
> +
> + if (!parent || !dev_of_valid(parent))
> + return 0;
> +
> + /*
> + * We start parsing for dma-ranges from the device's bus node. This is
> + * specially important on nested buses.
> + */
> + ret = dev_get_dma_range(parent, &cpu, &bus, &size);
> + /* Don't return an error if no 'dma-ranges' were found */
> + if (ret && ret != -ENOENT) {
> + dm_warn("%s: failed to get DMA range, %d\n", dev->name, ret);
> + return ret;
> + }
> +
> + dev->dma_offset = cpu - bus;
> +
> + return 0;
> +}
> +#else
> +static int device_get_dma_constraints(struct udevice *dev) { return 0; }
> +#endif
> +
> int device_probe(struct udevice *dev)
> {
> const struct driver *drv;
> @@ -482,6 +513,10 @@ int device_probe(struct udevice *dev)
> goto fail;
> }
>
> + ret = device_get_dma_constraints(dev);
> + if (ret)
> + goto fail;
> +
> ret = uclass_pre_probe_device(dev);
> if (ret)
> goto fail;
> diff --git a/include/dm/device.h b/include/dm/device.h
> index 5bef484247..9126dc00fe 100644
> --- a/include/dm/device.h
> +++ b/include/dm/device.h
> @@ -161,6 +161,9 @@ struct udevice {
> #ifdef CONFIG_DEVRES
> struct list_head devres_head;
> #endif
> +#ifdef CONFIG_DM_DMA
> + ulong dma_offset;
Needs a comment
> +#endif
> };
>
> /* Maximum sequence number supported */
> --
> 2.29.2
>
Regards,
Simon
More information about the U-Boot
mailing list