u-boot/0020-dm-Introduce-DMA-constraints-into-t.patch
Guillaume GARDET 111c122751 Accepting request 872955 from hardware👢staging
- Add qemu-riscv64spl
Patch queue updated from git://github.com/openSUSE/u-boot.git tumbleweed-2021.01
* Patches added:
  0031-efi_loader-Avoid-emitting-efi_var_b.patch
- Drop pcm051rev3 for Phytec Wega board 
- Fix binary extension for sunxi based boards
- Add Pinephone
- Fix documentation location 
Update to v2021.01.
Patch queue updated from git://github.com/openSUSE/u-boot.git tumbleweed-2021.01
* Patches dropped:
  0028-usb-xhci-xhci_bulk_tx-Don-t-BUG-whe.patch
  0029-Revert-Fix-data-abort-caused-by-mis.patch
  0030-usb-xhci-pci-Add-DM_FLAG_OS_PREPARE.patch
  0031-pci-brcmstb-Cleanup-controller-stat.patch
* Patches added:
  0028-usb-xhci-pci-Add-DM_FLAG_OS_PREPARE.patch
  0029-pci-brcmstb-Cleanup-controller-stat.patch
  0030-fs-btrfs-Select-SHA256-in-Kconfig.patch

OBS-URL: https://build.opensuse.org/request/show/872955
OBS-URL: https://build.opensuse.org/package/show/hardware:boot/u-boot?expand=0&rev=127
2021-02-17 07:37:34 +00:00

141 lines
4.4 KiB
Diff

From d327db89d06e0532645a2ec5151aaca7299939fd Mon Sep 17 00:00:00 2001
From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
Date: Tue, 12 Jan 2021 13:55:24 +0100
Subject: [PATCH] dm: Introduce DMA constraints into the core device model
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@suse.de>
Reviewed-by: Simon Glass <sjg@chromium.org>
Tested-by: Peter Robinson <pbrobinson@gmail.com>
---
drivers/core/Kconfig | 10 ++++++++++
drivers/core/device.c | 41 +++++++++++++++++++++++++++++++++++++++++
include/dm/device.h | 13 +++++++++++++
3 files changed, 64 insertions(+)
diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig
index ffae6f9795..295cf2dd00 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"
+ 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..788ce6046a 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -421,6 +421,43 @@ fail:
return ret;
}
+/**
+ * device_get_dma_constraints() - Populate device's DMA constraints
+ *
+ * Gets a device's DMA constraints from firmware. This information is later
+ * used by drivers to translate physcal addresses to the device's bus address
+ * space. For now only device-tree is supported.
+ *
+ * @dev: Pointer to target device
+ * Return: 0 if OK or if no DMA constraints were found, error otherwise
+ */
+static int device_get_dma_constraints(struct udevice *dev)
+{
+ struct udevice *parent = dev->parent;
+ phys_addr_t cpu = 0;
+ dma_addr_t bus = 0;
+ u64 size = 0;
+ int ret;
+
+ if (!CONFIG_IS_ENABLED(DM_DMA) || !parent || !dev_has_of_node(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_set_dma_offset(dev, cpu - bus);
+
+ return 0;
+}
+
int device_probe(struct udevice *dev)
{
const struct driver *drv;
@@ -482,6 +519,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..b27889af01 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -138,6 +138,8 @@ enum {
* When CONFIG_DEVRES is enabled, devm_kmalloc() and friends will
* add to this list. Memory so-allocated will be freed
* automatically when the device is removed / unbound
+ * @dma_offset: Offset between the physical address space (CPU's) and the
+ * device's bus address space
*/
struct udevice {
const struct driver *driver;
@@ -161,6 +163,9 @@ struct udevice {
#ifdef CONFIG_DEVRES
struct list_head devres_head;
#endif
+#if CONFIG_IS_ENABLED(DM_DMA)
+ ulong dma_offset;
+#endif
};
/* Maximum sequence number supported */
@@ -172,6 +177,14 @@ struct udevice {
/* Returns non-zero if the device is active (probed and not removed) */
#define device_active(dev) ((dev)->flags & DM_FLAG_ACTIVATED)
+#if CONFIG_IS_ENABLED(DM_DMA)
+#define dev_set_dma_offset(_dev, _offset) _dev->dma_offset = _offset
+#define dev_get_dma_offset(_dev) _dev->dma_offset
+#else
+#define dev_set_dma_offset(_dev, _offset)
+#define dev_get_dma_offset(_dev) 0
+#endif
+
static inline int dev_of_offset(const struct udevice *dev)
{
return ofnode_to_offset(dev->node);