Skip to contentSkip to conversation

drivers: Add AXI uclass

PATCH Superseded Mario Six 3 participants 18 messages May 23, 2018 – Jun 25, 2018 Framebuffer layer

v2 of 4 Superseded Latest is v4 →

lore
Share & tools
lore

Mario Six

author
#0 lore raw

PATCH v2 1/7 drivers: Add AXI uclass

Add a uclass for AXI (Advanced eXtensible Interface) busses, and a driver for the gdsys IHS AXI bus on IHS FPGAs.

---

v1 -> v2:
* Spelled out all abbreviations in the Kconfig help
* Split commit into uclass addition and driver addition

---
 drivers/Kconfig          |  2 ++
 drivers/Makefile         |  1 +
 drivers/axi/Kconfig      | 13 +++++++++
 drivers/axi/Makefile     |  8 ++++++
 drivers/axi/axi-uclass.c | 40 ++++++++++++++++++++++++++
 include/axi.h            | 75 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/dm/uclass-id.h   |  1 +
 7 files changed, 140 insertions(+)
 create mode 100644 drivers/axi/Kconfig
 create mode 100644 drivers/axi/Makefile
 create mode 100644 drivers/axi/axi-uclass.c
 create mode 100644 include/axi.h
drivers/Kconfig +2 -0
index c2e813f5adf..eeaaa7575cd 100644
@@ -8,6 +8,8 @@ source "drivers/adc/Kconfig"
 
 source "drivers/ata/Kconfig"
 
+source "drivers/axi/Kconfig"
+
 source "drivers/block/Kconfig"
 
 source "drivers/bootcount/Kconfig"
drivers/Makefile +1 -0
index b3f1b600a55..54b396d6368 100644
@@ -99,6 +99,7 @@ obj-y += input/
 obj-y += soc/
 obj-$(CONFIG_REMOTEPROC) += remoteproc/
 obj-y += thermal/
+obj-y += axi/
 
 obj-$(CONFIG_MACH_PIC32) += ddr/microchip/
 endif
drivers/axi/Kconfig new file +13 -0
new file mode 100644
index 00000000000..4e4153b4283
@@ -0,0 +1,13 @@
+menuconfig AXI
+	bool "AXI bus drivers"
+	help
+	  Support AXI (Advanced eXtensible Interface) busses, a on-chip
+	  interconnect specification for managing functional blocks in SoC
+	  designs, which is also often used in designs involving FPGAs (e.g.
+	  communication with IP cores in Xilinx FPGAs).
+
+	  These types of busses expose a virtual address space that can be
+	  accessed using different address widths (8, 16, and 32 are supported
+	  for now).
+
+	  Other similar bus architectures may be compatible as well.
drivers/axi/Makefile new file +8 -0
new file mode 100644
index 00000000000..100a77788a2
@@ -0,0 +1,8 @@
+#
+# (C) Copyright 2017
+# Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-$(CONFIG_AXI) += axi-uclass.o
drivers/axi/axi-uclass.c new file +40 -0
new file mode 100644
index 00000000000..3a5ddf3a46a
@@ -0,0 +1,40 @@
+/*
+ * (C) Copyright 2017
+ * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <axi.h>
+
+int axi_read(struct udevice *dev, ulong address, void *data,
+	     enum axi_size_t size)
+{
+	struct axi_ops *ops = axi_get_ops(dev);
+
+	if (!ops->read)
+		return -ENOSYS;
+
+	return ops->read(dev, address, data, size);
+}
+
+int axi_write(struct udevice *dev, ulong address, void *data,
+	      enum axi_size_t size)
+{
+	struct axi_ops *ops = axi_get_ops(dev);
+
+	if (!ops->write)
+		return -ENOSYS;
+
+	return ops->write(dev, address, data, size);
+}
+
+UCLASS_DRIVER(axi) = {
+	.id		= UCLASS_AXI,
+	.name		= "axi",
+	.post_bind	= dm_scan_fdt_dev,
+	.flags		= DM_UC_FLAG_SEQ_ALIAS,
+};
+
include/axi.h new file +75 -0

75 lines not on this page · raw message

include/dm/uclass-id.h +1 -0
index d7f9df3583a..0aad4bc14d7 100644
@@ -43,6 +43,7 @@ enum uclass_id {
 	UCLASS_I2C_GENERIC,	/* Generic I2C device */
 	UCLASS_I2C_MUX,		/* I2C multiplexer */
 	UCLASS_IDE,		/* IDE device */
+	UCLASS_AXI,		/* AXI busses */
 	UCLASS_IRQ,		/* Interrupt controller */
 	UCLASS_KEYBOARD,	/* Keyboard input device */
 	UCLASS_LED,		/* Light-emitting diode (LED) */

--
2.11.0

author
#1 lore raw

PATCH v2 2/7 axi: Add ihs_axi driver

Add a driver for the gdsys IHS AXI bus used on IHS FPGAs.

---

v1 -> v2:
New in v2

---
 drivers/axi/Kconfig   |  12 ++++
 drivers/axi/Makefile  |   1 +
 drivers/axi/ihs_axi.c | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 192 insertions(+)
 create mode 100644 drivers/axi/ihs_axi.c
drivers/axi/Kconfig +12 -0
index 4e4153b4283..ae80c98af8a 100644
@@ -11,3 +11,15 @@ menuconfig AXI
 	  for now).
 
 	  Other similar bus architectures may be compatible as well.
+
+if AXI
+
+config IHS_AXI
+	bool "Enable IHS AXI driver"
+	depends on DM
+	help
+	  Support for gdsys Integrated Hardware Systems Advanced eXtensible
+	  Interface (IHS AXI) bus on a gdsys IHS FPGA used to communicate with
+	  IP cores in the FPGA (e.g. video transmitter cores).
+
+endif
drivers/axi/Makefile +1 -0
index 100a77788a2..18d9380e9ba 100644
@@ -6,3 +6,4 @@
 #
 
 obj-$(CONFIG_AXI) += axi-uclass.o
+obj-$(CONFIG_IHS_AXI) += ihs_axi.o
drivers/axi/ihs_axi.c new file +179 -0

179 lines not on this page · raw message

--
2.11.0

#2 lore raw

PATCH v2 2/7 axi: Add ihs_axi driver

Quoted 9 lines · Mario Six

Add a driver for the gdsys IHS AXI bus used on IHS FPGAs.

---

v1 -> v2:
New in v2

Quoted 6 lines
---
 drivers/axi/Kconfig   |  12 ++++
 drivers/axi/Makefile  |   1 +
 drivers/axi/ihs_axi.c | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 192 insertions(+)
 create mode 100644 drivers/axi/ihs_axi.c
author
#3 lore raw

PATCH v2 3/7 axi: Add AXI sandbox driver and simple emulator

In reply to Mario Six

Add test infrastructure and tests for the AXI uclass.

---

v1 -> v2:
* Spelled out abbreviations in Kconfig help
* Expanded emulation documentation
* Renamed storage pointer to storep
* Expanded AXI emulator usage documentation
* Switched AXI emulator to aligned access

---
 drivers/axi/Kconfig           |   7 +++
 drivers/axi/Makefile          |   3 ++
 drivers/axi/axi-emul-uclass.c |  68 ++++++++++++++++++++++++++
 drivers/axi/axi_sandbox.c     |  77 +++++++++++++++++++++++++++++
 drivers/axi/sandbox_store.c   | 110 ++++++++++++++++++++++++++++++++++++++++++
 include/axi.h                 |  84 ++++++++++++++++++++++++++++++++
 include/dm/uclass-id.h        |   1 +
 7 files changed, 350 insertions(+)
 create mode 100644 drivers/axi/axi-emul-uclass.c
 create mode 100644 drivers/axi/axi_sandbox.c
 create mode 100644 drivers/axi/sandbox_store.c
drivers/axi/Kconfig +7 -0
index ae80c98af8a..f81d843f894 100644
@@ -22,4 +22,11 @@ config IHS_AXI
 	  Interface (IHS AXI) bus on a gdsys IHS FPGA used to communicate with
 	  IP cores in the FPGA (e.g. video transmitter cores).
 
+config AXI_SANDBOX
+	bool "Enable AXI sandbox driver"
+	depends on DM
+	help
+	  Support AXI (Advanced eXtensible Interface) emulation for the sandbox
+	  environment.
+
 endif
drivers/axi/Makefile +3 -0
index 18d9380e9ba..66b6c5a28f4 100644
@@ -7,3 +7,6 @@
 
 obj-$(CONFIG_AXI) += axi-uclass.o
 obj-$(CONFIG_IHS_AXI) += ihs_axi.o
+obj-$(CONFIG_SANDBOX) += axi-emul-uclass.o
+obj-$(CONFIG_SANDBOX) += sandbox_store.o
+obj-$(CONFIG_AXI_SANDBOX) += axi_sandbox.o
drivers/axi/axi-emul-uclass.c new file +68 -0

68 lines not on this page · raw message

drivers/axi/axi_sandbox.c new file +77 -0

77 lines not on this page · raw message

drivers/axi/sandbox_store.c new file +110 -0

110 lines not on this page · raw message

include/axi.h +84 -0

88 lines not on this page · raw message

include/dm/uclass-id.h +1 -0
index 0aad4bc14d7..8ff1e4f1bf5 100644
@@ -23,6 +23,7 @@ enum uclass_id {
 	UCLASS_I2C_EMUL,	/* sandbox I2C device emulator */
 	UCLASS_PCI_EMUL,	/* sandbox PCI device emulator */
 	UCLASS_USB_EMUL,	/* sandbox USB bus device emulator */
+	UCLASS_AXI_EMUL,	/* sandbox AXI bus device emulator */
 	UCLASS_SIMPLE_BUS,	/* bus with child devices */
 
 	/* U-Boot uclasses start here - in alphabetical order */

--
2.11.0

#4 lore raw

PATCH v2 3/7 axi: Add AXI sandbox driver and simple emulator

Hi Mario,

Quoted 13 lines · Mario Six

Add test infrastructure and tests for the AXI uclass.

---

v1 -> v2:
* Spelled out abbreviations in Kconfig help
* Expanded emulation documentation
* Renamed storage pointer to storep
* Expanded AXI emulator usage documentation
* Switched AXI emulator to aligned access

Quoted 13 lines
---
 drivers/axi/Kconfig           |   7 +++
 drivers/axi/Makefile          |   3 ++
 drivers/axi/axi-emul-uclass.c |  68 ++++++++++++++++++++++++++
 drivers/axi/axi_sandbox.c     |  77 +++++++++++++++++++++++++++++
 drivers/axi/sandbox_store.c   | 110 ++++++++++++++++++++++++++++++++++++++++++
 include/axi.h                 |  84 ++++++++++++++++++++++++++++++++
 include/dm/uclass-id.h        |   1 +
 7 files changed, 350 insertions(+)
 create mode 100644 drivers/axi/axi-emul-uclass.c
 create mode 100644 drivers/axi/axi_sandbox.c
 create mode 100644 drivers/axi/sandbox_store.c

Some nits below.

Quoted 21 lines
drivers/axi/axi_sandbox.c new file +15 -0
new file mode 100644
index 00000000000..7a485b114bf
@@ -0,0 +1,77 @@
+/*
+ * (C) Copyright 2018
+ * Mario Six, Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <axi.h>
+#include <dm.h>
+
+/*
+ * This driver implements a AXI bus for the sandbox architecture for testing
+ * purposes.
+ *

drivers/axi/axi_sandbox.c line 25

Quoted 10 lines
drivers/axi/axi_sandbox.c new file +10 -0
+ * The bus forwards every access to it to a special AXI emulation device (which
+ * it gets via the axi_emul_get_ops function) that implements a simple
+ * read/write storage.
+ *
+ * The emulator device must still be contained in the device tree in the usual
+ * way, since configuration data for the storage is read from the DT.
+ */
+
+int axi_sandbox_read(struct udevice *bus, ulong address, void *data,
+                    enum axi_size_t size)

Can this and the write() function below be static?

Quoted 68 lines
drivers/axi/axi_sandbox.c new file +52 -0
+{
+       struct axi_emul_ops *ops;
+       struct udevice *emul;
+       int ret;
+
+       /* Get emulator device */
+       ret = axi_sandbox_get_emul(bus, address, size, &emul);
+       if (ret)
+               return ret == -ENODEV ? 0 : ret;
+       /* Forward all reads to the AXI emulator */
+       ops = axi_emul_get_ops(emul);
+       if (!ops || !ops->read)
+               return -ENOSYS;
+
+       return ops->read(emul, address, data, size);
+}
+
+int axi_sandbox_write(struct udevice *bus, ulong address, void *data,
+                     enum axi_size_t size)
+{
+       struct axi_emul_ops *ops;
+       struct udevice *emul;
+       int ret;
+
+       /* Get emulator device */
+       ret = axi_sandbox_get_emul(bus, address, size, &emul);
+       if (ret)
+               return ret == -ENODEV ? 0 : ret;
+       /* Forward all writes to the AXI emulator */
+       ops = axi_emul_get_ops(emul);
+       if (!ops || !ops->write)
+               return -ENOSYS;
+
+       return ops->write(emul, address, data, size);
+}
+
+static const struct udevice_id axi_sandbox_ids[] = {
+       { .compatible = "sandbox,axi" },
+       { /* sentinel */ }
+};
+
+static const struct axi_ops axi_sandbox_ops = {
+       .read = axi_sandbox_read,
+       .write = axi_sandbox_write,
+};
+
+U_BOOT_DRIVER(axi_sandbox_bus) = {
+       .name           = "axi_sandbox_bus",
+       .id             = UCLASS_AXI,
+       .of_match       = axi_sandbox_ids,
+       .ops            = &axi_sandbox_ops,
+};
drivers/axi/sandbox_store.c new file +10 -0
new file mode 100644
index 00000000000..61c7aea22c8
@@ -0,0 +1,110 @@
+/*
+ * (C) Copyright 2018
+ * Mario Six, Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <axi.h>
+#include <dm.h>

drivers/axi/sandbox_store.c line 20

Quoted 10 lines
drivers/axi/sandbox_store.c new file +10 -0
+
+struct sandbox_store_priv {
+       u8 *store;
+};
+
+void copy_axi_data(void *src, void *dst, enum axi_size_t size)
+{
+       u8 *dst8 = dst;
+       u16 *dst16 = dst;
+       u32 *dst32 = dst;

Can you put these declarations in the case statements instead? I'm not sure what coverity with think of this aliasing.

Quoted 56 lines
drivers/axi/sandbox_store.c new file +56 -0
+
+       switch (size) {
+       case AXI_SIZE_8:
+               *dst8 = *((u8 *)src);
+               break;
+       case AXI_SIZE_16:
+               *dst16 = be16_to_cpu(*((u16 *)src));
+               break;
+       case AXI_SIZE_32:
+               *dst32 = be32_to_cpu(*((u32 *)src));
+               break;
+       }
+}
+
+int sandbox_store_read(struct udevice *dev, ulong address, void *data,
+                      enum axi_size_t size)
+{
+       struct sandbox_store_priv *priv = dev_get_priv(dev);
+
+       copy_axi_data(priv->store + address, data, size);
+
+       return 0;
+}
+
+int sandbox_store_write(struct udevice *dev, ulong address, void *data,
+                       enum axi_size_t size)
+{
+       struct sandbox_store_priv *priv = dev_get_priv(dev);
+
+       copy_axi_data(data, priv->store + address, size);
+
+       return 0;
+}
+
+int sandbox_store_get_store(struct udevice *dev, u8 **store)
+{
+       struct sandbox_store_priv *priv = dev_get_priv(dev);
+
+       *store = priv->store;
+
+       return 0;
+}
+
+static const struct udevice_id sandbox_store_ids[] = {
+       { .compatible = "sandbox,sandbox_store" },
+       { /* sentinel */ }
+};
+
+static const struct axi_emul_ops sandbox_store_ops = {
+       .read = sandbox_store_read,
+       .write = sandbox_store_write,
+       .get_store = sandbox_store_get_store,
+};
+
+int sandbox_store_probe(struct udevice *dev)
+{

drivers/axi/sandbox_store.c line 86

Quoted 10 lines
drivers/axi/sandbox_store.c new file +10 -0
+       struct sandbox_store_priv *priv = dev_get_priv(dev);
+       u32 reg[2];
+       int ret;
+
+       ret = dev_read_u32_array(dev, "reg", reg, ARRAY_SIZE(reg));
+       if (ret)
+               return -EINVAL;
+
+       priv->store = calloc(reg[1], 1);
+

drop blank line

Quoted 90 lines
drivers/axi/sandbox_store.c new file +24 -0
+       if (!priv->store)
+               return -ENOMEM;
+
+       return 0;
+}
+
+int sandbox_store_remove(struct udevice *dev)
+{
+       struct sandbox_store_priv *priv = dev_get_priv(dev);
+
+       free(priv->store);
+
+       return 0;
+}
+
+U_BOOT_DRIVER(sandbox_axi_store) = {
+       .name           = "sandbox_axi_store",
+       .id             = UCLASS_AXI_EMUL,
+       .of_match       = sandbox_store_ids,
+       .ops            = &sandbox_store_ops,
+       .priv_auto_alloc_size = sizeof(struct sandbox_store_priv),
+       .probe          = sandbox_store_probe,
+       .remove         = sandbox_store_remove,
+};
include/axi.h +58 -0
index 317e931a6cf..5b428127f8c 100644
@@ -72,4 +72,88 @@ int axi_read(struct udevice *dev, ulong address, void *data, enum axi_size_t siz
  * @return 0 if OK, -ve on error.
  */
 int axi_write(struct udevice *dev, ulong address, void *data, enum axi_size_t size);
+
+struct axi_emul_ops {
+       /**
+        * read() - Read a single value from a specified address on a AXI bus
+        *
+        * @dev:        AXI bus to read from.
+        * @address:    The address to read from.
+        * @data:       Pointer to a variable that takes the data value read
+        *              from the address on the AXI bus.
+        * @size:       The size of the data to be read.
+        * @return 0 if OK, -ve on error.
+        */
+       int (*read)(struct udevice *dev, ulong address, void *data, enum axi_size_t size);
+
+       /**
+        * write() - Write a single value to a specified address on a AXI bus
+        *
+        * @dev:        AXI bus to write to.
+        * @address:    The address to write to.
+        * @data:       Pointer to the data value to be written to the address
+        *              on the AXI bus.
+        * @size:       The size of the data to write.
+        * @return 0 if OK, -ve on error.
+        */
+       int (*write)(struct udevice *dev, ulong address, void *data, enum axi_size_t size);
+
+       /**
+        * get_store() - Get address of internal storage of a emulated AXI
+        *               device
+        *
+        * @dev:        Emulated AXI device to get the pointer of the internal
+        *              storage for.
+        * @storep:     Pointer to the internal storage of the emulated AXI
+        *              device.
+        * @return 0 if OK, -ve on error.
+        */
+       int (*get_store)(struct udevice *dev, u8 **storep);
+};
+
+#define axi_emul_get_ops(dev)  ((struct axi_emul_ops *)(dev)->driver->ops)
+
+/**
+ * axi_sandbox_get_emul() - Retrieve a pointer to a AXI emulation device
+ *
+ * To test the AXI uclass, we implement a simple AXI emulation device, which is
+ * a virtual device on a AXI bus that exposes a simple storage interface: When
+ * reading and writing from the device, the addresses are translated to offsets
+ * within the device's storage. For write accesses the data is written to the
+ * specified storage offset, and for read accesses the data is read from the
+ * specified storage offset.
+ *
+ * A DTS entry might look like this:
+ *
+ * axi: axi at 0 {
+ *     compatible = "sandbox,axi";
+ *     #address-cells = <0x1>;
+ *     #size-cells = <0x1>;
+ *     store at 0 {

include/axi.h int axi_read(struct udevice *dev, ulong address, void *data, enum axi_size_t siz · line 142

Quoted 10 lines
include/axi.h +10 -0
+ *             compatible = "sandbox,sandbox_store";
+ *             reg = <0x0 0x400>;
+ *     };
+ * };
+ *
+ * This function may then be used to retrieve the pointer to the sandbox_store
+ * emulation device given the AXI bus device.
+ */
+int axi_sandbox_get_emul(struct udevice *bus, ulong address, uint length,
+                        struct udevice **emulp);

Can these two function declarations go in arch/sandbox/include/asm perhaps? I don't think they are needed except for sandbox?

Quoted 7 lines
include/axi.h +7 -0
+/**
+ * axi_get_store() - Get address of internal storage of a emulated AXI device
+ *
+ * To preset or read back the contents internal storage of the emulated AXI
+ * device, this function returns the pointer to the storage. Changes to the
+ * contents of the storage are reflected when using the AXI read/write API
+ * methods, and vice versa, so by using this method expected read data can be

include/axi.h int axi_read(struct udevice *dev, ulong address, void *data, enum axi_size_t siz · line 159

Quoted 10 lines
include/axi.h +9 -0
+ * set up in advance, and written data can be checked in unit tests.
+ *
+ * @dev:       Emulated AXI device to get the pointer of the internal storage
+ *             for.
+ * @storep:    Pointer to the internal storage of the emulated AXI device.
+ * @return 0 if OK, -ve on error.
+ */
+int axi_get_store(struct udevice *dev, u8 **storep);
+
 #endif

Regards,
Simon

author
#5 lore raw

PATCH v2 3/7 axi: Add AXI sandbox driver and simple emulator

Hi Simon,

Quoted 59 lines · Simon Glass

Hi Mario,

Quoted 13 lines · Mario Six

Add test infrastructure and tests for the AXI uclass.

---

v1 -> v2:
* Spelled out abbreviations in Kconfig help
* Expanded emulation documentation
* Renamed storage pointer to storep
* Expanded AXI emulator usage documentation
* Switched AXI emulator to aligned access

Quoted 13 lines
---
 drivers/axi/Kconfig           |   7 +++
 drivers/axi/Makefile          |   3 ++
 drivers/axi/axi-emul-uclass.c |  68 ++++++++++++++++++++++++++
 drivers/axi/axi_sandbox.c     |  77 +++++++++++++++++++++++++++++
 drivers/axi/sandbox_store.c   | 110 ++++++++++++++++++++++++++++++++++++++++++
 include/axi.h                 |  84 ++++++++++++++++++++++++++++++++
 include/dm/uclass-id.h        |   1 +
 7 files changed, 350 insertions(+)
 create mode 100644 drivers/axi/axi-emul-uclass.c
 create mode 100644 drivers/axi/axi_sandbox.c
 create mode 100644 drivers/axi/sandbox_store.c

Some nits below.

Quoted 25 lines
drivers/axi/axi_sandbox.c new file +19 -0
new file mode 100644
index 00000000000..7a485b114bf
@@ -0,0 +1,77 @@
+/*
+ * (C) Copyright 2018
+ * Mario Six, Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <axi.h>
+#include <dm.h>
+
+/*
+ * This driver implements a AXI bus for the sandbox architecture for testing
+ * purposes.
+ *
+ * The bus forwards every access to it to a special AXI emulation device (which
+ * it gets via the axi_emul_get_ops function) that implements a simple
+ * read/write storage.
+ *
Quoted 9 lines

drivers/axi/axi_sandbox.c line 25

Quoted 6 lines
drivers/axi/axi_sandbox.c new file +6 -0
+ * The emulator device must still be contained in the device tree in the usual
+ * way, since configuration data for the storage is read from the DT.
+ */
+
+int axi_sandbox_read(struct udevice *bus, ulong address, void *data,
+                    enum axi_size_t size)

Can this and the write() function below be static?

Yes, sure, will be fixed in v3.

Quoted 73 lines
Quoted 73 lines
drivers/axi/axi_sandbox.c new file +52 -0
+{
+       struct axi_emul_ops *ops;
+       struct udevice *emul;
+       int ret;
+
+       /* Get emulator device */
+       ret = axi_sandbox_get_emul(bus, address, size, &emul);
+       if (ret)
+               return ret == -ENODEV ? 0 : ret;
+       /* Forward all reads to the AXI emulator */
+       ops = axi_emul_get_ops(emul);
+       if (!ops || !ops->read)
+               return -ENOSYS;
+
+       return ops->read(emul, address, data, size);
+}
+
+int axi_sandbox_write(struct udevice *bus, ulong address, void *data,
+                     enum axi_size_t size)
+{
+       struct axi_emul_ops *ops;
+       struct udevice *emul;
+       int ret;
+
+       /* Get emulator device */
+       ret = axi_sandbox_get_emul(bus, address, size, &emul);
+       if (ret)
+               return ret == -ENODEV ? 0 : ret;
+       /* Forward all writes to the AXI emulator */
+       ops = axi_emul_get_ops(emul);
+       if (!ops || !ops->write)
+               return -ENOSYS;
+
+       return ops->write(emul, address, data, size);
+}
+
+static const struct udevice_id axi_sandbox_ids[] = {
+       { .compatible = "sandbox,axi" },
+       { /* sentinel */ }
+};
+
+static const struct axi_ops axi_sandbox_ops = {
+       .read = axi_sandbox_read,
+       .write = axi_sandbox_write,
+};
+
+U_BOOT_DRIVER(axi_sandbox_bus) = {
+       .name           = "axi_sandbox_bus",
+       .id             = UCLASS_AXI,
+       .of_match       = axi_sandbox_ids,
+       .ops            = &axi_sandbox_ops,
+};
drivers/axi/sandbox_store.c new file +15 -0
new file mode 100644
index 00000000000..61c7aea22c8
@@ -0,0 +1,110 @@
+/*
+ * (C) Copyright 2018
+ * Mario Six, Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <axi.h>
+#include <dm.h>
+
+struct sandbox_store_priv {
+       u8 *store;
+};
+
Quoted 9 lines

drivers/axi/sandbox_store.c line 20

Quoted 5 lines
drivers/axi/sandbox_store.c new file +5 -0
+void copy_axi_data(void *src, void *dst, enum axi_size_t size)
+{
+       u8 *dst8 = dst;
+       u16 *dst16 = dst;
+       u32 *dst32 = dst;

Can you put these declarations in the case statements instead? I'm not sure what coverity with think of this aliasing.

Yeah, coverity probably won't like that. I'll put the casts in the case statements for v3.

Quoted 60 lines
Quoted 60 lines
drivers/axi/sandbox_store.c new file +60 -0
+
+       switch (size) {
+       case AXI_SIZE_8:
+               *dst8 = *((u8 *)src);
+               break;
+       case AXI_SIZE_16:
+               *dst16 = be16_to_cpu(*((u16 *)src));
+               break;
+       case AXI_SIZE_32:
+               *dst32 = be32_to_cpu(*((u32 *)src));
+               break;
+       }
+}
+
+int sandbox_store_read(struct udevice *dev, ulong address, void *data,
+                      enum axi_size_t size)
+{
+       struct sandbox_store_priv *priv = dev_get_priv(dev);
+
+       copy_axi_data(priv->store + address, data, size);
+
+       return 0;
+}
+
+int sandbox_store_write(struct udevice *dev, ulong address, void *data,
+                       enum axi_size_t size)
+{
+       struct sandbox_store_priv *priv = dev_get_priv(dev);
+
+       copy_axi_data(data, priv->store + address, size);
+
+       return 0;
+}
+
+int sandbox_store_get_store(struct udevice *dev, u8 **store)
+{
+       struct sandbox_store_priv *priv = dev_get_priv(dev);
+
+       *store = priv->store;
+
+       return 0;
+}
+
+static const struct udevice_id sandbox_store_ids[] = {
+       { .compatible = "sandbox,sandbox_store" },
+       { /* sentinel */ }
+};
+
+static const struct axi_emul_ops sandbox_store_ops = {
+       .read = sandbox_store_read,
+       .write = sandbox_store_write,
+       .get_store = sandbox_store_get_store,
+};
+
+int sandbox_store_probe(struct udevice *dev)
+{
+       struct sandbox_store_priv *priv = dev_get_priv(dev);
+       u32 reg[2];
+       int ret;
+
Quoted 9 lines

drivers/axi/sandbox_store.c line 86

Quoted 6 lines
drivers/axi/sandbox_store.c new file +6 -0
+       ret = dev_read_u32_array(dev, "reg", reg, ARRAY_SIZE(reg));
+       if (ret)
+               return -EINVAL;
+
+       priv->store = calloc(reg[1], 1);
+

drop blank line

Will be done for v3.

Quoted 95 lines
Quoted 95 lines
drivers/axi/sandbox_store.c new file +24 -0
+       if (!priv->store)
+               return -ENOMEM;
+
+       return 0;
+}
+
+int sandbox_store_remove(struct udevice *dev)
+{
+       struct sandbox_store_priv *priv = dev_get_priv(dev);
+
+       free(priv->store);
+
+       return 0;
+}
+
+U_BOOT_DRIVER(sandbox_axi_store) = {
+       .name           = "sandbox_axi_store",
+       .id             = UCLASS_AXI_EMUL,
+       .of_match       = sandbox_store_ids,
+       .ops            = &sandbox_store_ops,
+       .priv_auto_alloc_size = sizeof(struct sandbox_store_priv),
+       .probe          = sandbox_store_probe,
+       .remove         = sandbox_store_remove,
+};
include/axi.h +63 -0
index 317e931a6cf..5b428127f8c 100644
@@ -72,4 +72,88 @@ int axi_read(struct udevice *dev, ulong address, void *data, enum axi_size_t siz
  * @return 0 if OK, -ve on error.
  */
 int axi_write(struct udevice *dev, ulong address, void *data, enum axi_size_t size);
+
+struct axi_emul_ops {
+       /**
+        * read() - Read a single value from a specified address on a AXI bus
+        *
+        * @dev:        AXI bus to read from.
+        * @address:    The address to read from.
+        * @data:       Pointer to a variable that takes the data value read
+        *              from the address on the AXI bus.
+        * @size:       The size of the data to be read.
+        * @return 0 if OK, -ve on error.
+        */
+       int (*read)(struct udevice *dev, ulong address, void *data, enum axi_size_t size);
+
+       /**
+        * write() - Write a single value to a specified address on a AXI bus
+        *
+        * @dev:        AXI bus to write to.
+        * @address:    The address to write to.
+        * @data:       Pointer to the data value to be written to the address
+        *              on the AXI bus.
+        * @size:       The size of the data to write.
+        * @return 0 if OK, -ve on error.
+        */
+       int (*write)(struct udevice *dev, ulong address, void *data, enum axi_size_t size);
+
+       /**
+        * get_store() - Get address of internal storage of a emulated AXI
+        *               device
+        *
+        * @dev:        Emulated AXI device to get the pointer of the internal
+        *              storage for.
+        * @storep:     Pointer to the internal storage of the emulated AXI
+        *              device.
+        * @return 0 if OK, -ve on error.
+        */
+       int (*get_store)(struct udevice *dev, u8 **storep);
+};
+
+#define axi_emul_get_ops(dev)  ((struct axi_emul_ops *)(dev)->driver->ops)
+
+/**
+ * axi_sandbox_get_emul() - Retrieve a pointer to a AXI emulation device
+ *
+ * To test the AXI uclass, we implement a simple AXI emulation device, which is
+ * a virtual device on a AXI bus that exposes a simple storage interface: When
+ * reading and writing from the device, the addresses are translated to offsets
+ * within the device's storage. For write accesses the data is written to the
+ * specified storage offset, and for read accesses the data is read from the
+ * specified storage offset.
+ *
+ * A DTS entry might look like this:
+ *
+ * axi: axi at 0 {
+ *     compatible = "sandbox,axi";
+ *     #address-cells = <0x1>;
+ *     #size-cells = <0x1>;
+ *     store at 0 {
+ *             compatible = "sandbox,sandbox_store";
+ *             reg = <0x0 0x400>;
+ *     };
+ * };
+ *
Quoted 9 lines

include/axi.h int axi_read(struct udevice *dev, ulong address, void *data, enum axi_size_t siz · line 142

Quoted 5 lines
include/axi.h +5 -0
+ * This function may then be used to retrieve the pointer to the sandbox_store
+ * emulation device given the AXI bus device.
+ */
+int axi_sandbox_get_emul(struct udevice *bus, ulong address, uint length,
+                        struct udevice **emulp);

Can these two function declarations go in arch/sandbox/include/asm perhaps? I don't think they are needed except for sandbox?

Yes, no problem. Will be fixed in v3.

Quoted 12 lines
Quoted 12 lines
include/axi.h +12 -0
+/**
+ * axi_get_store() - Get address of internal storage of a emulated AXI device
+ *
+ * To preset or read back the contents internal storage of the emulated AXI
+ * device, this function returns the pointer to the storage. Changes to the
+ * contents of the storage are reflected when using the AXI read/write API
+ * methods, and vice versa, so by using this method expected read data can be
+ * set up in advance, and written data can be checked in unit tests.
+ *
+ * @dev:       Emulated AXI device to get the pointer of the internal storage
+ *             for.
+ * @storep:    Pointer to the internal storage of the emulated AXI device.
Quoted 9 lines

include/axi.h int axi_read(struct udevice *dev, ulong address, void *data, enum axi_size_t siz · line 159

Quoted 5 lines
include/axi.h +4 -0
+ * @return 0 if OK, -ve on error.
+ */
+int axi_get_store(struct udevice *dev, u8 **storep);
+
 #endif

Regards,
Simon

Best regards,
Mario

author
#6 lore raw

PATCH v2 4/7 sandbox: Add and build AXI bus and device

In reply to Mario Six

Add test AXI drivers to the sandbox.

---

v1 -> v2:
No changes

---
 arch/sandbox/dts/sandbox.dts | 11 +++++++++++
 arch/sandbox/dts/test.dts    | 11 +++++++++++
 configs/sandbox_defconfig    |  3 +++
 3 files changed, 25 insertions(+)
arch/sandbox/dts/sandbox.dts +11 -0
index 86680a6b11d..8a236ea76b2 100644
@@ -12,6 +12,7 @@
 		i2c0 = &i2c_0;
 		pci0 = &pci;
 		rtc0 = &rtc_0;
+		axi0 = &axi;
 	};
 
 	chosen {
@@ -315,6 +316,16 @@
 			};
 		};
 	};
+
+	axi: axi at 0 {
+		compatible = "sandbox,axi";
+		#address-cells = <0x1>;
+		#size-cells = <0x1>;
+		store at 0 {
+			compatible = "sandbox,sandbox_store";
+			reg = <0x0 0x400>;
+		};
+	};
 };
 
 #include "cros-ec-keyboard.dtsi"
arch/sandbox/dts/test.dts +11 -0
index 5a0f187d8b7..5822c5dd59a 100644
@@ -34,6 +34,7 @@
 		usb0 = &usb_0;
 		usb1 = &usb_1;
 		usb2 = &usb_2;
+		axi0 = &axi;
 	};
 
 	a-test {
@@ -507,6 +508,16 @@
 		compatible = "sandbox,wdt";
 	};
 
+	axi: axi at 0 {
+		compatible = "sandbox,axi";
+		#address-cells = <0x1>;
+		#size-cells = <0x1>;
+		store at 0 {
+			compatible = "sandbox,sandbox_store";
+			reg = <0x0 0x400>;
+		};
+	};
+
 	chosen {
 		#address-cells = <1>;
 		#size-cells = <1>;
configs/sandbox_defconfig +3 -0
index 2fc84a16c91..83107c7f99a 100644
@@ -45,6 +45,7 @@ CONFIG_CMD_REMOTEPROC=y
 CONFIG_CMD_SF=y
 CONFIG_CMD_SPI=y
 CONFIG_CMD_USB=y
+CONFIG_CMD_AXI=y
 CONFIG_CMD_TFTPPUT=y
 CONFIG_CMD_TFTPSRV=y
 CONFIG_CMD_RARP=y
@@ -81,6 +82,8 @@ CONFIG_DEVRES=y
 CONFIG_DEBUG_DEVRES=y
 CONFIG_ADC=y
 CONFIG_ADC_SANDBOX=y
+CONFIG_AXI=y
+CONFIG_AXI_SANDBOX=y
 CONFIG_CLK=y
 CONFIG_CPU=y
 CONFIG_DM_DEMO=y

--
2.11.0

author
#7 lore raw

PATCH v2 5/7 test: Add AXI test

In reply to Mario Six

Add tests for the AXI uclass.

---

v1 -> v2:
* Fixed asserts (moved expected values first)

---
 test/dm/Makefile |  1 +
 test/dm/axi.c    | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 75 insertions(+)
 create mode 100644 test/dm/axi.c
test/dm/Makefile +1 -0
index 5511a85700c..de8b9940888 100644
@@ -43,4 +43,5 @@ obj-$(CONFIG_DM_VIDEO) += video.o
 obj-$(CONFIG_ADC) += adc.o
 obj-$(CONFIG_SPMI) += spmi.o
 obj-$(CONFIG_WDT) += wdt.o
+obj-$(CONFIG_AXI) += axi.o
 endif
test/dm/axi.c new file +74 -0

74 lines not on this page · raw message

--
2.11.0

#8 lore raw

PATCH v2 5/7 test: Add AXI test

Quoted 6 lines · Mario Six

Add tests for the AXI uclass.

---

Quoted 8 lines

v1 -> v2:
* Fixed asserts (moved expected values first)

---
 test/dm/Makefile |  1 +
 test/dm/axi.c    | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 75 insertions(+)
 create mode 100644 test/dm/axi.c

Can you please use lower-case hex?

author
#9 lore raw

PATCH v2 5/7 test: Add AXI test

Hi Simon,

Quoted 16 lines · Simon Glass
Quoted 6 lines · Mario Six

Add tests for the AXI uclass.

---

Quoted 8 lines

v1 -> v2:
* Fixed asserts (moved expected values first)

---
 test/dm/Makefile |  1 +
 test/dm/axi.c    | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 75 insertions(+)
 create mode 100644 test/dm/axi.c
Quoted 4 lines

Can you please use lower-case hex?

OK, will switch to lower-case for v3.

Best regards,
Mario

author
#10 lore raw

PATCH v2 6/7 cmd: Add axi command

In reply to Mario Six

Add a command to debug the AXI bus.

---

v1 -> v2:
No changes

---
 cmd/Kconfig  |   8 ++
 cmd/Makefile |   1 +
 cmd/axi.c    | 310 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 319 insertions(+)
 create mode 100644 cmd/axi.c
cmd/Kconfig +8 -0
index 38406fcfdac..0f730f7a397 100644
@@ -995,6 +995,14 @@ config CMD_USB_MASS_STORAGE
 	help
 	  USB mass storage support
 
+config CMD_AXI
+	bool "axi"
+	depends on AXI
+	help
+	  Enable the command "axi" for accessing AXI (Advanced eXtensible
+	  Interface) busses, a on-chip interconnect specification for managing
+	  functional blocks in SoC designs, which is also often used in designs
+	  involving FPGAs (e.g.  communication with IP cores in Xilinx FPGAs).
 endmenu
 
 
cmd/Makefile +1 -0
index 0d7322ee0a4..cfca11499ec 100644
@@ -145,6 +145,7 @@ obj-$(CONFIG_CMD_ZFS) += zfs.o
 obj-$(CONFIG_CMD_DFU) += dfu.o
 obj-$(CONFIG_CMD_GPT) += gpt.o
 obj-$(CONFIG_CMD_ETHSW) += ethsw.o
+obj-$(CONFIG_CMD_AXI) += axi.o
 
 # Power
 obj-$(CONFIG_CMD_PMIC) += pmic.o
cmd/axi.c new file +310 -0

310 lines not on this page · raw message

--
2.11.0

#11 lore raw

PATCH v2 6/7 cmd: Add axi command

Hi Mario,

Quoted 9 lines · Mario Six

Add a command to debug the AXI bus.

---

v1 -> v2:
No changes

Quoted 6 lines
---
 cmd/Kconfig  |   8 ++
 cmd/Makefile |   1 +
 cmd/axi.c    | 310 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 319 insertions(+)
 create mode 100644 cmd/axi.c

Comments below.

Quoted 84 lines
cmd/Kconfig +8 -0
index 38406fcfdac..0f730f7a397 100644
@@ -995,6 +995,14 @@ config CMD_USB_MASS_STORAGE
        help
          USB mass storage support
 
+config CMD_AXI
+       bool "axi"
+       depends on AXI
+       help
+         Enable the command "axi" for accessing AXI (Advanced eXtensible
+         Interface) busses, a on-chip interconnect specification for managing
+         functional blocks in SoC designs, which is also often used in designs
+         involving FPGAs (e.g.  communication with IP cores in Xilinx FPGAs).
 endmenu
 
 
cmd/Makefile +1 -0
index 0d7322ee0a4..cfca11499ec 100644
@@ -145,6 +145,7 @@ obj-$(CONFIG_CMD_ZFS) += zfs.o
 obj-$(CONFIG_CMD_DFU) += dfu.o
 obj-$(CONFIG_CMD_GPT) += gpt.o
 obj-$(CONFIG_CMD_ETHSW) += ethsw.o
+obj-$(CONFIG_CMD_AXI) += axi.o
 
 # Power
 obj-$(CONFIG_CMD_PMIC) += pmic.o
cmd/axi.c new file +46 -0
new file mode 100644
index 00000000000..d8001875e2c
@@ -0,0 +1,310 @@
+/*
+ * (C) Copyright 2016
+ * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach at gdsys.cc
+ *
+ * (C) Copyright 2017
+ * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <command.h>
+#include <console.h>
+#include <axi.h>
+
+static struct udevice *axi_cur_bus;
+static uint dp_last_size;
+static uint dp_last_addr;
+static uint dp_last_length = 0x40;
+
+static void show_bus(struct udevice *bus)
+{
+       struct udevice *dev;
+
+       printf("Bus %d:\t%s", bus->req_seq, bus->name);
+       if (device_active(bus))
+               printf("  (active %d)", bus->seq);
+       printf("\n");
+       for (device_find_first_child(bus, &dev);
+            dev;
+            device_find_next_child(&dev))
+               printf("  %s\n", dev->name);
+}
+
+static int do_axi_show_bus(cmd_tbl_t *cmdtp, int flag, int argc,
+                          char * const argv[])
+{
+       if (argc == 1) {
+               /* show all busses */
+               struct udevice *bus;
+
+               for (uclass_first_device(UCLASS_AXI, &bus);
+                    bus;
+                    uclass_next_device(&bus))
+                       show_bus(bus);

cmd/axi.c line 56

Quoted 10 lines
cmd/axi.c new file +10 -0
+       } else {
+               int i;
+
+               /* show specific bus */
+               i = simple_strtoul(argv[1], NULL, 10);
+
+               struct udevice *bus;
+               int ret;
+
+               ret = uclass_get_device_by_seq(UCLASS_AXI, i, &bus);

Here you probe the bus, whereas above you don't. Is that intended?

Quoted 13 lines
cmd/axi.c new file +13 -0
+               if (ret) {
+                       printf("Invalid bus %d: err=%d\n", i, ret);
+                       return CMD_RET_FAILURE;
+               }
+               show_bus(bus);
+       }
+
+       return 0;
+}
+
+static int cmd_axi_set_bus_num(unsigned int busnum)
+{
+       struct udevice *bus;

cmd/axi.c line 79

Quoted 10 lines
cmd/axi.c new file +10 -0
+       struct udevice *dummy;
+       int ret;
+
+       /* Make sure that all sequence numbers are initialized */
+       for (uclass_first_device(UCLASS_AXI, &dummy);
+            dummy;
+            uclass_next_device(&dummy))
+               ;
+
+       ret = uclass_get_device_by_seq(UCLASS_AXI, busnum, &bus);

Here you probe the bus which seems right to me.

cmd/axi.c line 88

Quoted 9 lines
cmd/axi.c new file +9 -0
+       if (ret) {
+               debug("%s: No bus %d\n", __func__, busnum);
+               return ret;
+       }
+       axi_cur_bus = bus;
+
+       return 0;
+}
+

[..]

Regards,
Simon

author
#12 lore raw

PATCH v2 6/7 cmd: Add axi command

Hi Simon,

Quoted 111 lines · Simon Glass

Hi Mario,

Quoted 9 lines · Mario Six

Add a command to debug the AXI bus.

---

v1 -> v2:
No changes

Quoted 6 lines
---
 cmd/Kconfig  |   8 ++
 cmd/Makefile |   1 +
 cmd/axi.c    | 310 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 319 insertions(+)
 create mode 100644 cmd/axi.c

Comments below.

Quoted 88 lines
cmd/Kconfig +8 -0
index 38406fcfdac..0f730f7a397 100644
@@ -995,6 +995,14 @@ config CMD_USB_MASS_STORAGE
        help
          USB mass storage support
 
+config CMD_AXI
+       bool "axi"
+       depends on AXI
+       help
+         Enable the command "axi" for accessing AXI (Advanced eXtensible
+         Interface) busses, a on-chip interconnect specification for managing
+         functional blocks in SoC designs, which is also often used in designs
+         involving FPGAs (e.g.  communication with IP cores in Xilinx FPGAs).
 endmenu
 
 
cmd/Makefile +1 -0
index 0d7322ee0a4..cfca11499ec 100644
@@ -145,6 +145,7 @@ obj-$(CONFIG_CMD_ZFS) += zfs.o
 obj-$(CONFIG_CMD_DFU) += dfu.o
 obj-$(CONFIG_CMD_GPT) += gpt.o
 obj-$(CONFIG_CMD_ETHSW) += ethsw.o
+obj-$(CONFIG_CMD_AXI) += axi.o
 
 # Power
 obj-$(CONFIG_CMD_PMIC) += pmic.o
cmd/axi.c new file +50 -0
new file mode 100644
index 00000000000..d8001875e2c
@@ -0,0 +1,310 @@
+/*
+ * (C) Copyright 2016
+ * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach at gdsys.cc
+ *
+ * (C) Copyright 2017
+ * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <command.h>
+#include <console.h>
+#include <axi.h>
+
+static struct udevice *axi_cur_bus;
+static uint dp_last_size;
+static uint dp_last_addr;
+static uint dp_last_length = 0x40;
+
+static void show_bus(struct udevice *bus)
+{
+       struct udevice *dev;
+
+       printf("Bus %d:\t%s", bus->req_seq, bus->name);
+       if (device_active(bus))
+               printf("  (active %d)", bus->seq);
+       printf("\n");
+       for (device_find_first_child(bus, &dev);
+            dev;
+            device_find_next_child(&dev))
+               printf("  %s\n", dev->name);
+}
+
+static int do_axi_show_bus(cmd_tbl_t *cmdtp, int flag, int argc,
+                          char * const argv[])
+{
+       if (argc == 1) {
+               /* show all busses */
+               struct udevice *bus;
+
+               for (uclass_first_device(UCLASS_AXI, &bus);
+                    bus;
+                    uclass_next_device(&bus))
+                       show_bus(bus);
+       } else {
+               int i;
+
+               /* show specific bus */
Quoted 9 lines

cmd/axi.c line 56

Quoted 6 lines
cmd/axi.c new file +6 -0
+               i = simple_strtoul(argv[1], NULL, 10);
+
+               struct udevice *bus;
+               int ret;
+
+               ret = uclass_get_device_by_seq(UCLASS_AXI, i, &bus);

Here you probe the bus, whereas above you don't. Is that intended?

Right, I should probably make sure that the busses are probed in either case, good point.

Will be fixed in v3.

Quoted 17 lines
Quoted 17 lines
cmd/axi.c new file +17 -0
+               if (ret) {
+                       printf("Invalid bus %d: err=%d\n", i, ret);
+                       return CMD_RET_FAILURE;
+               }
+               show_bus(bus);
+       }
+
+       return 0;
+}
+
+static int cmd_axi_set_bus_num(unsigned int busnum)
+{
+       struct udevice *bus;
+       struct udevice *dummy;
+       int ret;
+
+       /* Make sure that all sequence numbers are initialized */
Quoted 9 lines

cmd/axi.c line 79

Quoted 6 lines
cmd/axi.c new file +6 -0
+       for (uclass_first_device(UCLASS_AXI, &dummy);
+            dummy;
+            uclass_next_device(&dummy))
+               ;
+
+       ret = uclass_get_device_by_seq(UCLASS_AXI, busnum, &bus);

Here you probe the bus which seems right to me.

I'll use this same approach in the other function as well.

Quoted 11 lines
Quoted 9 lines
cmd/axi.c new file +9 -0
+       if (ret) {
+               debug("%s: No bus %d\n", __func__, busnum);
+               return ret;
+       }
+       axi_cur_bus = bus;
+
+       return 0;
+}
+

[..]

Quoted 2 lines

Regards,
Simon

Best regards,
Mario

author
#13 lore raw

PATCH v2 7/7 video_display: Add Xilinx LogiCore DP TX

In reply to Mario Six

Add a driver for the Xilinx LogiCORE DisplayPort IP core, which is a pure DP transmitter core for Xiling FPGA (no display capabilities).

---

v1 -> v2:
* Switch to display_enable
* Mentioned that the LogiCORE has no display capabilities

---
 drivers/video/Kconfig                |   11 +
 drivers/video/Makefile               |    1 +
 drivers/video/logicore_dp_dpcd.h     |  342 ++++++
 drivers/video/logicore_dp_tx.c       | 1975 ++++++++++++++++++++++++++++++++++
 drivers/video/logicore_dp_tx.h       |   40 +
 drivers/video/logicore_dp_tx_regif.h |  365 +++++++
 6 files changed, 2734 insertions(+)
 create mode 100644 drivers/video/logicore_dp_dpcd.h
 create mode 100644 drivers/video/logicore_dp_tx.c
 create mode 100644 drivers/video/logicore_dp_tx.h
 create mode 100644 drivers/video/logicore_dp_tx_regif.h
drivers/video/Kconfig +11 -0
index 4c4d2861fe7..ddec697e359 100644
@@ -423,6 +423,17 @@ config ATMEL_HLCD
 	help
 	   HLCDC supports video output to an attached LCD panel.
 
+config LOGICORE_DP_TX
+	bool "Enable Logicore DP TX driver"
+	depends on DISPLAY
+	help
+	  Enable the driver for the transmitter part of the Xilinx LogiCORE
+	  DisplayPort, a IP core for Xilinx FPGAs that implements a DisplayPort
+	  video interface as defined by VESA DisplayPort v1.2.
+
+	  Note that this is a pure transmitter device, and has no display
+	  capabilities by itself.
+
 config VIDEO_BROADWELL_IGD
 	bool "Enable Intel Broadwell integrated graphics device"
 	depends on X86
drivers/video/Makefile +1 -0
index cf7ad281c3b..fa4ac715fcf 100644
@@ -21,6 +21,7 @@ obj-$(CONFIG_VIDEO_IVYBRIDGE_IGD) += ivybridge_igd.o
 
 obj-$(CONFIG_ATI_RADEON_FB) += ati_radeon_fb.o videomodes.o
 obj-$(CONFIG_ATMEL_HLCD) += atmel_hlcdfb.o
+obj-$(CONFIG_LOGICORE_DP_TX) += logicore_dp_tx.o
 obj-$(CONFIG_ATMEL_LCD) += atmel_lcdfb.o
 obj-$(CONFIG_CFB_CONSOLE) += cfb_console.o
 obj-$(CONFIG_FSL_DIU_FB) += fsl_diu_fb.o videomodes.o
drivers/video/logicore_dp_dpcd.h new file +342 -0

342 lines not on this page · raw message

drivers/video/logicore_dp_tx.c new file +1975 -0

1,975 lines not on this page · raw message

drivers/video/logicore_dp_tx.h new file +40 -0
new file mode 100644
index 00000000000..32f9649b9ce
@@ -0,0 +1,40 @@
+/*
+ * logicore_dp_tx.h
+ *
+ * Driver for XILINX LogiCore DisplayPort v6.1 TX (Source)
+ *
+ * (C) Copyright 2016
+ * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach at gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __GDSYS_LOGICORE_DP_TX_H__
+#define __GDSYS_LOGICORE_DP_TX_H__
+
+/*
+ * this is a stripped down version of struct main_stream_attributes that contains
+ * only the parameters that are not set by cfg_msa_recalculate()
+ */
+struct logicore_dp_tx_msa {
+	u32 pixel_clock_hz;		/* The pixel clock of the stream (in Hz). */
+	u32 bits_per_color;		/* Number of bits per color component. */
+	u16 h_active;			/* Horizontal active resolution (pixels) */
+	u32 h_start;			/* Horizontal blank start (in pixels). */
+	bool h_sync_polarity;		/* Horizontal sync polarity (0=negative|1=positive) */
+	u16 h_sync_width;		/* Horizontal sync width (pixels) */
+	u16 h_total;			/* Horizontal total (pixels) */
+	u16 v_active;			/* Vertical active resolution (lines) */
+	u32 v_start;			/* Vertical blank start (in lines). */
+	bool v_sync_polarity;		/* Vertical sync polarity (0=negative|1=positive) */
+	u16 v_sync_width;		/* Vertical sync width (lines) */
+	u16 v_total;			/* Vertical total (lines) */
+	bool override_user_pixel_width;	/* If true, the value stored for
+					   user_pixel_width will be used as
+					   the pixel width. */
+	u32 user_pixel_width;		/* The width of the user data input port. */
+};
+
+int logicore_dp_tx_video_enable(struct udevice *dev, struct logicore_dp_tx_msa *msa);
+
+#endif /* __GDSYS_LOGICORE_DP_TX_H__ */
drivers/video/logicore_dp_tx_regif.h new file +365 -0

365 lines not on this page · raw message

--
2.11.0

#14 lore raw

PATCH v2 7/7 video_display: Add Xilinx LogiCore DP TX

Hi Mario,

Please test the patch with ./scripts/checkpatch.pl, there are warnings/ errors reported that need fixing:
...
total: 1 errors, 31 warnings, 26 checks, 2746 lines checked

On Wed, 23 May 2018 14:10:47 +0200
Mario Six mario.six at gdsys.cc wrote:
...

drivers/video/Makefile obj-$(CONFIG_VIDEO_IVYBRIDGE_IGD) += ivybridge_igd.o · line 24

Quoted 9 lines
drivers/video/Makefile +1 -0
index cf7ad281c3b..fa4ac715fcf 100644
@@ -21,6 +21,7 @@ obj-$(CONFIG_VIDEO_IVYBRIDGE_IGD) += ivybridge_igd.o
 
 obj-$(CONFIG_ATI_RADEON_FB) += ati_radeon_fb.o videomodes.o
 obj-$(CONFIG_ATMEL_HLCD) += atmel_hlcdfb.o
+obj-$(CONFIG_LOGICORE_DP_TX) += logicore_dp_tx.o

Please add new driver entry sorted alphabetically. I know there are already not sorted entries in the list here, but we shouldn't add more.

...

Quoted 5 lines
drivers/video/logicore_dp_dpcd.h new file +0 -0
new file mode 100644
index 00000000000..68582945514

...

drivers/video/logicore_dp_dpcd.h

Quoted 6 lines
drivers/video/logicore_dp_dpcd.h new file +6 -0
+struct main_stream_attributes {
+	/* Pixel clock of the stream (in Hz). */
+	u32 pixel_clock_hz;
+	/* Miscellaneous stream attributes 0 as specified by the DisplayPort
+	 * 1.2 specification.
+	 */

Please fix multi-line comment style throughout this patch, we use this style:

	/*
	 * multi-line
	 * comment
	 */

...

drivers/video/logicore_dp_dpcd.h

Quoted 7 lines
drivers/video/logicore_dp_dpcd.h new file +7 -0
+static u32 get_reg(struct udevice *dev, u32 reg)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	u32 value = 0;
+	int res;
+
+	// TODO error handling

please no C++ comments.

...

drivers/video/logicore_dp_dpcd.h

Quoted 2 lines
drivers/video/logicore_dp_dpcd.h new file +2 -0
+bool is_connected(struct udevice *dev)
+{

shouldn't it be static?

...

Quoted 3 lines
drivers/video/logicore_dp_dpcd.h new file +3 -0
+
+bool is_link_rate_valid(struct udevice *dev, u8 link_rate)
+{

...

drivers/video/logicore_dp_dpcd.h

Quoted 2 lines
drivers/video/logicore_dp_dpcd.h new file +2 -0
+bool is_lane_count_valid(struct udevice *dev, u8 lane_count)
+{

Are these functions supposed to be used externally? If not, please add static. Otherwise move them to /* external API */ section.

...

drivers/video/logicore_dp_dpcd.h

Quoted 3 lines
drivers/video/logicore_dp_dpcd.h new file +3 -0
+int logicore_dp_tx_enable(struct udevice *dev, int panel_bpp,
+			  const struct display_timing *timing)
+{

should be static?

...

drivers/video/logicore_dp_dpcd.h

Quoted 2 lines
drivers/video/logicore_dp_dpcd.h new file +2 -0
+int logicore_dp_tx_probe(struct udevice *dev)
+{

should be static?

...

drivers/video/logicore_dp_dpcd.h

Quoted 3 lines
drivers/video/logicore_dp_dpcd.h new file +3 -0
+struct dm_display_ops logicore_dp_tx_ops = {
+	.enable = logicore_dp_tx_enable,
+};

should be static, too.

...

Quoted 5 lines
drivers/video/logicore_dp_tx_regif.h new file +0 -0
new file mode 100644
index 00000000000..c4105605c9b

...

drivers/video/logicore_dp_tx_regif.h line 37

Quoted 3 lines
drivers/video/logicore_dp_tx_regif.h new file +3 -0
+	/* core ID */
+	REG_VERSION = 			0x0F8,
+	REG_CORE_ID = 			0x0FC,

here a space and tabs follow '=', please use tabs only.

...

drivers/video/logicore_dp_tx_regif.h line 72

Quoted 2 lines
drivers/video/logicore_dp_tx_regif.h new file +2 -0
+	REG_USER_PIXEL_WIDTH =		0x1B8,
+	REG_USER_DATA_COUNT_PER_LANE =0x1BC,

spaces around '=', checkpatch will report style issues like this.

...

Quoted 2 lines

+/*
+ * PHY_STATUS_ALL_LANES_READY_MASK seems zo be missing lanes 0 and 1 in

s/zo/to ?

Thanks,

--
Anatolij

author
#15 lore raw

PATCH v2 7/7 video_display: Add Xilinx LogiCore DP TX

Hi Anatolij,

Quoted 7 lines · Anatolij Gustschin

Hi Mario,

Please test the patch with ./scripts/checkpatch.pl, there are warnings/ errors reported that need fixing:
...
total: 1 errors, 31 warnings, 26 checks, 2746 lines checked

Right, sorry, will be fixed in v3.

Quoted 9 lines

On Wed, 23 May 2018 14:10:47 +0200
Mario Six mario.six at gdsys.cc wrote:
...

Quoted 6 lines
drivers/video/Makefile +0 -0
index cf7ad281c3b..fa4ac715fcf 100644
@@ -21,6 +21,7 @@ obj-$(CONFIG_VIDEO_IVYBRIDGE_IGD) += ivybridge_igd.o
 
Quoted 7 lines

drivers/video/Makefile obj-$(CONFIG_VIDEO_IVYBRIDGE_IGD) += ivybridge_igd.o · line 24

Quoted 3 lines
drivers/video/Makefile +1 -0
 obj-$(CONFIG_ATI_RADEON_FB) += ati_radeon_fb.o videomodes.o
 obj-$(CONFIG_ATMEL_HLCD) += atmel_hlcdfb.o
+obj-$(CONFIG_LOGICORE_DP_TX) += logicore_dp_tx.o

Please add new driver entry sorted alphabetically. I know there are already not sorted entries in the list here, but we shouldn't add more.

OK, I'll add a patch that sorts the entries, and add the new entry with respect to the new ordering.

Quoted 14 lines

...

Quoted 5 lines
drivers/video/logicore_dp_dpcd.h new file +0 -0
new file mode 100644
index 00000000000..68582945514

...

drivers/video/logicore_dp_dpcd.h

Quoted 6 lines
drivers/video/logicore_dp_dpcd.h new file +6 -0
+struct main_stream_attributes {
+     /* Pixel clock of the stream (in Hz). */
+     u32 pixel_clock_hz;
+     /* Miscellaneous stream attributes 0 as specified by the DisplayPort
+      * 1.2 specification.
+      */
Quoted 6 lines

Please fix multi-line comment style throughout this patch, we use this style:
/*
* multi-line
* comment
*/

Will be fixed in v3.

Quoted 11 lines

...

drivers/video/logicore_dp_dpcd.h

Quoted 7 lines
drivers/video/logicore_dp_dpcd.h new file +7 -0
+static u32 get_reg(struct udevice *dev, u32 reg)
+{
+     struct dp_tx *dp_tx = dev_get_priv(dev);
+     u32 value = 0;
+     int res;
+
+     // TODO error handling

please no C++ comments.

Overlooked that one. Will be fixed in v3.

Quoted 6 lines

...

drivers/video/logicore_dp_dpcd.h

Quoted 2 lines
drivers/video/logicore_dp_dpcd.h new file +2 -0
+bool is_connected(struct udevice *dev)
+{

shouldn't it be static?

Yes, good idea, I'll declare it static for v3.

Quoted 6 lines

...

Quoted 3 lines
drivers/video/logicore_dp_dpcd.h new file +3 -0
+
+bool is_link_rate_valid(struct udevice *dev, u8 link_rate)
+{

...

Quoted 6 lines

drivers/video/logicore_dp_dpcd.h

Quoted 2 lines
drivers/video/logicore_dp_dpcd.h new file +2 -0
+bool is_lane_count_valid(struct udevice *dev, u8 lane_count)
+{

Are these functions supposed to be used externally? If not, please add static. Otherwise move them to /* external API */ section.

No, the U-Boot driver doesn't use them outside the file. I'll mark them static in v3.

Quoted 7 lines

...

drivers/video/logicore_dp_dpcd.h

Quoted 3 lines
drivers/video/logicore_dp_dpcd.h new file +3 -0
+int logicore_dp_tx_enable(struct udevice *dev, int panel_bpp,
+                       const struct display_timing *timing)
+{

should be static?

Dito.

Quoted 6 lines

...

drivers/video/logicore_dp_dpcd.h

Quoted 2 lines
drivers/video/logicore_dp_dpcd.h new file +2 -0
+int logicore_dp_tx_probe(struct udevice *dev)
+{

should be static?

Quoted 7 lines

...

drivers/video/logicore_dp_dpcd.h

Quoted 3 lines
drivers/video/logicore_dp_dpcd.h new file +3 -0
+struct dm_display_ops logicore_dp_tx_ops = {
+     .enable = logicore_dp_tx_enable,
+};

should be static, too.

Dito.

Quoted 11 lines

...

Quoted 5 lines
drivers/video/logicore_dp_tx_regif.h new file +0 -0
new file mode 100644
index 00000000000..c4105605c9b

...

drivers/video/logicore_dp_tx_regif.h line 37

Quoted 3 lines
drivers/video/logicore_dp_tx_regif.h new file +3 -0
+     /* core ID */
+     REG_VERSION =                   0x0F8,
+     REG_CORE_ID =                   0x0FC,
Quoted 8 lines

here a space and tabs follow '=', please use tabs only.

...

drivers/video/logicore_dp_tx_regif.h line 72

Quoted 2 lines
drivers/video/logicore_dp_tx_regif.h new file +2 -0
+     REG_USER_PIXEL_WIDTH =          0x1B8,
+     REG_USER_DATA_COUNT_PER_LANE =0x1BC,

spaces around '=', checkpatch will report style issues like this.

I'll fix the whitespace issues in v3.

Quoted 6 lines

...

Quoted 2 lines

+/*
+ * PHY_STATUS_ALL_LANES_READY_MASK seems zo be missing lanes 0 and 1 in

s/zo/to ?

Yeah, that's a typo. Will fix in v3.

Quoted 2 lines

Thanks,

Thanks for reviewing, and best regards,
Mario

#16 lore raw

PATCH v2 1/7 drivers: Add AXI uclass

In reply to Mario Six
Quoted 11 lines · Mario Six

Add a uclass for AXI (Advanced eXtensible Interface) busses, and a driver for the gdsys IHS AXI bus on IHS FPGAs.

---

v1 -> v2:
* Spelled out all abbreviations in the Kconfig help
* Split commit into uclass addition and driver addition

Quoted 13 lines
---
 drivers/Kconfig          |  2 ++
 drivers/Makefile         |  1 +
 drivers/axi/Kconfig      | 13 +++++++++
 drivers/axi/Makefile     |  8 ++++++
 drivers/axi/axi-uclass.c | 40 ++++++++++++++++++++++++++
 include/axi.h            | 75 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/dm/uclass-id.h   |  1 +
 7 files changed, 140 insertions(+)
 create mode 100644 drivers/axi/Kconfig
 create mode 100644 drivers/axi/Makefile
 create mode 100644 drivers/axi/axi-uclass.c
 create mode 100644 include/axi.h

One little nit:

include/dm/uclass-id.h enum uclass_id { · line 46

Quoted 9 lines
include/dm/uclass-id.h +1 -0
index d7f9df3583a..0aad4bc14d7 100644
@@ -43,6 +43,7 @@ enum uclass_id {
        UCLASS_I2C_GENERIC,     /* Generic I2C device */
        UCLASS_I2C_MUX,         /* I2C multiplexer */
        UCLASS_IDE,             /* IDE device */
+       UCLASS_AXI,             /* AXI busses */

AXI bus

Quoted 6 lines
include/dm/uclass-id.h +0 -1
        UCLASS_IRQ,             /* Interrupt controller */
        UCLASS_KEYBOARD,        /* Keyboard input device */
        UCLASS_LED,             /* Light-emitting diode (LED) */
--

2.11.0

author
#17 lore raw

PATCH v2 1/7 drivers: Add AXI uclass

Hi Simon,

Quoted 30 lines · Simon Glass
Quoted 11 lines · Mario Six

Add a uclass for AXI (Advanced eXtensible Interface) busses, and a driver for the gdsys IHS AXI bus on IHS FPGAs.

---

v1 -> v2:
* Spelled out all abbreviations in the Kconfig help
* Split commit into uclass addition and driver addition

Quoted 13 lines
---
 drivers/Kconfig          |  2 ++
 drivers/Makefile         |  1 +
 drivers/axi/Kconfig      | 13 +++++++++
 drivers/axi/Makefile     |  8 ++++++
 drivers/axi/axi-uclass.c | 40 ++++++++++++++++++++++++++
 include/axi.h            | 75 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/dm/uclass-id.h   |  1 +
 7 files changed, 140 insertions(+)
 create mode 100644 drivers/axi/Kconfig
 create mode 100644 drivers/axi/Makefile
 create mode 100644 drivers/axi/axi-uclass.c
 create mode 100644 include/axi.h

One little nit:

Quoted 12 lines

include/dm/uclass-id.h enum uclass_id { · line 46

Quoted 9 lines
include/dm/uclass-id.h +1 -0
index d7f9df3583a..0aad4bc14d7 100644
@@ -43,6 +43,7 @@ enum uclass_id {
        UCLASS_I2C_GENERIC,     /* Generic I2C device */
        UCLASS_I2C_MUX,         /* I2C multiplexer */
        UCLASS_IDE,             /* IDE device */
+       UCLASS_AXI,             /* AXI busses */

AXI bus

Sure, will fix for v3.

Quoted 7 lines
Quoted 6 lines
include/dm/uclass-id.h +0 -1
        UCLASS_IRQ,             /* Interrupt controller */
        UCLASS_KEYBOARD,        /* Keyboard input device */
        UCLASS_LED,             /* Light-emitting diode (LED) */
--

2.11.0

Best regards,
Mario