Re: [PATCH] firmware: zynmp-fpga: drop example bin format header

2019-12-10 Thread Thomas Hämmerle
typo in subject: zynmp-fpga -> zynqmp-fpga

On 09.12.19 14:59, Michael Tretter wrote:
> Avoid the example bitstream header to validate the bitstream that should
> be loaded into the FPGA. The header is mostly 0x with a few
> special values at a certain offsets and can be better described with the
> offsets and their magic values.
> 
> As a drive by, this fixes/removes a broken check in the header
> validation. The != operator has a higher precedence than ?: and this
> check should have had parenthesis around the ?: expression:
> 
>   bin_header[i] != (byte_order == XILINX_BYTE_ORDER_BIT) ?
>bin_format[i] : __swab32(bin_format[i])
> 
> Signed-off-by: Michael Tretter 

Reviewed-by: Thomas Haemmerle 

> ---
>   drivers/firmware/zynqmp-fpga.c | 121 +
>   1 file changed, 62 insertions(+), 59 deletions(-)
> 
> diff --git a/drivers/firmware/zynqmp-fpga.c b/drivers/firmware/zynqmp-fpga.c
> index 1728e2a954..e02667355f 100644
> --- a/drivers/firmware/zynqmp-fpga.c
> +++ b/drivers/firmware/zynqmp-fpga.c
> @@ -24,11 +24,32 @@
>   #define ZYNQMP_PM_VERSION_1_1_FEATURES  
> (ZYNQMP_PM_FEATURE_BYTE_ORDER_IRREL | \
>ZYNQMP_PM_FEATURE_SIZE_NOT_NEEDED)
>   
> +/*
> + * Xilinx KU040 Bitstream Composition:
> + *
> + * Bitstream can be provided with an optinal header (`struct bs_header`).
> + * The true bitstream starts with the binary-header composed of 21 words:
> + *
> + *  0: 0x (Dummy pad word)
> + * ...
> + * 15: 0x (Dummy pad word)
> + * 16: 0x00BB (Bus width auto detect word 1)
> + * 17: 0x11220044 (Bus width auto detect word 2)
> + * 18: 0x (Dummy pad word)
> + * 19: 0x (Dummy pad word)
> + * 20: 0xAA995566 (Sync word)
> + *
> + * See Xilinx UG570 (v1.11) September 30 2019, Chapter 9 "Configuration
> + * Details - Bitstream Composition" for further details.
> + */
>   #define DUMMY_WORD  0x
> -#define BUS_WIDTH_WORD_1 0x00BB
> -#define BUS_WIDTH_WORD_2 0x11220044
> +#define BUS_WIDTH_AUTO_DETECT1_OFFSET16
> +#define BUS_WIDTH_AUTO_DETECT1   0x00BB
> +#define BUS_WIDTH_AUTO_DETECT2_OFFSET17
> +#define BUS_WIDTH_AUTO_DETECT2   0x11220044
> +#define SYNC_WORD_OFFSET 20
>   #define SYNC_WORD   0xAA995566
> -#define SYNC_WORD_OFFS   20
> +#define BIN_HEADER_LENGTH21
>   
>   enum xilinx_byte_order {
>   XILINX_BYTE_ORDER_BIT,
> @@ -58,48 +79,6 @@ struct bs_header_entry {
>   char data[0];
>   } __attribute__ ((packed));
>   
> -/*
> - * Xilinx KU040 Bitstream Composition:
> - * Bitstream can be provided with an optinal header (`struct bs_header`).
> - * The true bitstream starts with the binary-header composed of 21 words:
> - *
> - *  1: 0x (Dummy pad word)
> - * ...
> - * 16: 0x (Dummy pad word)
> - * 17: 0x00BB (Bus width auto detect word 1)
> - * 18: 0x11220044 (Bus width auto detect word 2)
> - * 19: 0x (Dummy pad word)
> - * 20: 0x (Dummy pad word)
> - * 21: 0xAA995566 (Sync word)
> - *
> - * Please refer to  Xilinx UG570 (v1.11) September 30 2019,
> - * Chapter 9 Configuration Details - Bitstream Composition
> - * for further details!
> - */
> -static const u32 bin_format[] = {
> - DUMMY_WORD,
> - DUMMY_WORD,
> - DUMMY_WORD,
> - DUMMY_WORD,
> - DUMMY_WORD,
> - DUMMY_WORD,
> - DUMMY_WORD,
> - DUMMY_WORD,
> - DUMMY_WORD,
> - DUMMY_WORD,
> - DUMMY_WORD,
> - DUMMY_WORD,
> - DUMMY_WORD,
> - DUMMY_WORD,
> - DUMMY_WORD,
> - DUMMY_WORD,
> - BUS_WIDTH_WORD_1,
> - BUS_WIDTH_WORD_2,
> - DUMMY_WORD,
> - DUMMY_WORD,
> - SYNC_WORD,
> -};
> -
>   static void copy_words_swapped(u32 *dst, const u32 *src, size_t size)
>   {
>   int i;
> @@ -111,36 +90,59 @@ static void copy_words_swapped(u32 *dst, const u32 *src, 
> size_t size)
>   static int get_byte_order(const u32 *bin_header, size_t size,
> enum xilinx_byte_order *byte_order)
>   {
> - if (size < sizeof(bin_format))
> + if (size < BIN_HEADER_LENGTH * sizeof(*bin_header))
>   return -EINVAL;
>   
> - if (bin_header[SYNC_WORD_OFFS] == SYNC_WORD) {
> + if (bin_header[SYNC_WORD_OFFSET] == SYNC_WORD) {
>   *byte_order = XILINX_BYTE_ORDER_BIT;
>   return 0;
>   }
>   
> - if (bin_header[SYNC_WORD_OFFS] == __swab32(SYNC_WORD)) {
> - *byte_order =  XILINX_BYTE_ORDER_BIN;
> + if (bin_header[SYNC_WORD_OFFSET] == __swab32(SYNC_WORD)) {
> + *byte_order = XILINX_BYTE_ORDER_BIN;
>   return 0;
>   }
>   
>   return -EINVAL;
>   }
>   
> -static int is_bin_header_valid(const u32 *bin_header, size_t size,
> -enum xilinx_byte_order byte_order)
> +static bool is_bin_header_valid(const u32 *bin_header, size_t siz

[PATCH v2 4/4] firmware: zynqmp-fpga: print Xilinx bitstream header

2019-10-25 Thread Thomas Hämmerle
From: Michael Tretter 

The bitstream header has 5 fields, that start with a char for the type.
Four fields have a big-ending length and a null-terminated string for
the design name, the part number, and the date and time of creation. The
last field is a big-endian 32 bit unsigned int for the size of the
bitstream.

Print this info when loading the bitstream.

Signed-off-by: Michael Tretter 
---
 drivers/firmware/zynqmp-fpga.c | 51 ++
 1 file changed, 51 insertions(+)

diff --git a/drivers/firmware/zynqmp-fpga.c b/drivers/firmware/zynqmp-fpga.c
index 47862a7..8878658 100644
--- a/drivers/firmware/zynqmp-fpga.c
+++ b/drivers/firmware/zynqmp-fpga.c
@@ -45,6 +45,19 @@ struct fpgamgr {
u32 features;
 };
 
+struct bs_header {
+   __be16 length;
+   u8 padding[9];
+   __be16 size;
+   char entries[0];
+} __attribute__ ((packed));
+
+struct bs_header_entry {
+   char type;
+   __be16 length;
+   char data[0];
+} __attribute__ ((packed));
+
 /*
  * Xilinx KU040 Bitstream Composition:
  * Bitstream can be provided with an optinal header (`struct bs_header`).
@@ -143,6 +156,42 @@ static int get_header_length(const char *header, size_t 
size)
return -EINVAL;
 }
 
+static void zynqmp_fpga_show_header(const struct device_d *dev,
+struct bs_header *header, size_t size)
+{
+   struct bs_header_entry *entry;
+   unsigned int i;
+   unsigned int length;
+
+   for (i = 0; i < size - sizeof(*header); i += sizeof(*entry) + length) {
+   entry = (struct bs_header_entry *)&header->entries[i];
+   length = __be16_to_cpu(entry->length);
+
+   switch (entry->type) {
+   case 'a':
+   printf("Design: %s\n", entry->data);
+   break;
+   case 'b':
+   printf("Part number: %s\n", entry->data);
+   break;
+   case 'c':
+   printf("Date: %s\n", entry->data);
+   break;
+   case 'd':
+   printf("Time: %s\n", entry->data);
+   break;
+   case 'e':
+   /* Size entry does not have a length but is be32 int */
+   printf("Size: %d bytes\n",
+  (length << 16) + (entry->data[0] << 8) + 
entry->data[1]);
+   return;
+   default:
+   dev_warn(dev, "Invalid header entry: %c", entry->type);
+   return;
+   }
+   }
+}
+
 static int fpgamgr_program_finish(struct firmware_handler *fh)
 {
struct fpgamgr *mgr = container_of(fh, struct fpgamgr, fh);
@@ -167,6 +216,8 @@ static int fpgamgr_program_finish(struct firmware_handler 
*fh)
status = header_length;
goto err_free;
}
+   zynqmp_fpga_show_header(&mgr->dev,
+ (struct bs_header *)mgr->buf, header_length);
 
body = (u32 *)&mgr->buf[header_length];
body_length = mgr->size - header_length;
-- 
2.7.4


___
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


[PATCH v2 3/4] firmware: zynqmp-fpga: introduce driver to load bitstream to FPGA

2019-10-25 Thread Thomas Hämmerle
From: Thomas Haemmerle 

The driver provides functionalities to check and load a bitstream to FPGA.
A boolean parameter to check if FPGA is already programmed is
added.

Signed-off-by: Thomas Haemmerle 
---
 arch/arm/configs/zynqmp_defconfig |   1 +
 drivers/firmware/Kconfig  |   7 +
 drivers/firmware/Makefile |   1 +
 drivers/firmware/zynqmp-fpga.c| 359 ++
 4 files changed, 368 insertions(+)
 create mode 100644 drivers/firmware/zynqmp-fpga.c

diff --git a/arch/arm/configs/zynqmp_defconfig 
b/arch/arm/configs/zynqmp_defconfig
index 4dea964..834212e 100644
--- a/arch/arm/configs/zynqmp_defconfig
+++ b/arch/arm/configs/zynqmp_defconfig
@@ -35,4 +35,5 @@ CONFIG_CMD_OFTREE=y
 CONFIG_CMD_TIME=y
 CONFIG_DRIVER_SERIAL_CADENCE=y
 # CONFIG_SPI is not set
+CONFIG_FIRMWARE_ZYNQMP_PL=y
 CONFIG_DIGEST=y
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 710b500..90b4c0a 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -14,4 +14,11 @@ config FIRMWARE_ALTERA_SOCFPGA
bool "Altera SoCFPGA fpga loader"
depends on ARCH_SOCFPGA
select FIRMWARE
+
+config FIRMWARE_ZYNQMP_FPGA
+   bool "Xilinx ZynqMP FPGA loader"
+   depends on ARCH_ZYNQMP
+   select FIRMWARE
+   help
+ Load a bitstream to the PL of Zynq Ultrascale+
 endmenu
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index c3a3c34..b162b08 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_FIRMWARE_ALTERA_SERIAL) += altera_serial.o
 obj-$(CONFIG_FIRMWARE_ALTERA_SOCFPGA) += socfpga.o
+obj-$(CONFIG_FIRMWARE_ZYNQMP_FPGA) += zynqmp-fpga.o
diff --git a/drivers/firmware/zynqmp-fpga.c b/drivers/firmware/zynqmp-fpga.c
new file mode 100644
index 000..47862a7
--- /dev/null
+++ b/drivers/firmware/zynqmp-fpga.c
@@ -0,0 +1,359 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Zynq MPSoC PL loading
+ *
+ * Copyright (c) 2018 Thomas Haemmerle 
+ *
+ * based on U-Boot zynqmppl code
+ *
+ * (C) Copyright 2015 - 2016, Xilinx, Inc,
+ * Michal Simek 
+ * Siva Durga Prasad  *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define ZYNQMP_PM_FEATURE_BYTE_ORDER_IRREL BIT(0)
+#define ZYNQMP_PM_FEATURE_SIZE_NOT_NEEDED  BIT(1)
+
+#define ZYNQMP_PM_VERSION_1_0_FEATURES 0
+#define ZYNQMP_PM_VERSION_1_1_FEATURES (ZYNQMP_PM_FEATURE_BYTE_ORDER_IRREL | \
+ZYNQMP_PM_FEATURE_SIZE_NOT_NEEDED)
+
+#define DUMMY_WORD 0x
+#define BUS_WIDTH_WORD_1   0x00BB
+#define BUS_WIDTH_WORD_2   0x11220044
+#define SYNC_WORD  0xAA995566
+#define SYNC_WORD_OFFS 20
+
+enum xilinx_byte_order {
+   XILINX_BYTE_ORDER_BIT,
+   XILINX_BYTE_ORDER_BIN,
+};
+
+struct fpgamgr {
+   struct firmware_handler fh;
+   struct device_d dev;
+   const struct zynqmp_eemi_ops *eemi_ops;
+   int programmed;
+   char *buf;
+   size_t size;
+   u32 features;
+};
+
+/*
+ * Xilinx KU040 Bitstream Composition:
+ * Bitstream can be provided with an optinal header (`struct bs_header`).
+ * The true bitstream starts with the binary-header composed of 21 words:
+ *
+ *  1: 0x (Dummy pad word)
+ * ...
+ * 16: 0x (Dummy pad word)
+ * 17: 0x00BB (Bus width auto detect word 1)
+ * 18: 0x11220044 (Bus width auto detect word 2)
+ * 19: 0x (Dummy pad word)
+ * 20: 0x (Dummy pad word)
+ * 21: 0xAA995566 (Sync word)
+ *
+ * Please refer to  Xilinx UG570 (v1.11) September 30 2019,
+ * Chapter 9 Configuration Details - Bitstream Composition
+ * for further details!
+ */
+static const u32 bin_format[] = {
+   DUMMY_WORD,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   BUS_WIDTH_WORD_1,
+   BUS_WIDTH_WORD_2,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   SYNC_WORD,
+};
+
+static void copy_words_swapped(u32 *dst, const u32 *src, size_t size)
+{
+   int i;
+
+   for (i = 0; i < size; i++)
+   dst[i] = __swab32(src[i]);
+}
+
+static int get_byte_order(const u32 *bin_header, size_t size,
+ enum xilinx_byte_order *byte_order)
+{
+   if (size < sizeof(bin_format))
+   return -EINVAL;
+
+   if (bin_header[SYNC_WORD_OFFS] == SYNC_WORD) {
+   *byte_order = XILINX_BYTE_ORDER_BIT;
+   return 0;
+   }
+
+   if (bin_header[SYNC_WORD_OFFS] == __swab32(SYNC_WORD)) {
+   *byte_order =  XILINX_BYTE_ORDER_BIN;
+   return 0;
+   }
+
+   return -EINVAL;
+}
+
+static int is_bin_header_valid(const u32 *bin_header, size_t size,
+   

[PATCH v2 0/4] ARM: zynqmp: add support for bitstream loading

2019-10-25 Thread Thomas Hämmerle
From: Thomas Haemmerle 

Changes from v1:
- remove dts commits
- add commit for pmu and trustzone firmware virsion macro
- split bin-header validation and byte-order detection
- add description for bitstream

Michael Tretter (1):
  firmware: zynqmp-fpga: print Xilinx bitstream header

Thomas Haemmerle (3):
  firmware-zynqmp: add macros for PMU and trustzone firmware versions
  firmware-zynqmp: extend driver with fpga relavant functions
  firmware: zynqmp-fpga: introduce driver to load bitstream to FPGA

 arch/arm/configs/zynqmp_defconfig  |   1 +
 arch/arm/mach-zynqmp/firmware-zynqmp.c |  68 +++-
 .../arm/mach-zynqmp/include/mach/firmware-zynqmp.h |  14 +-
 drivers/firmware/Kconfig   |   7 +
 drivers/firmware/Makefile  |   1 +
 drivers/firmware/zynqmp-fpga.c | 410 +
 6 files changed, 488 insertions(+), 13 deletions(-)
 create mode 100644 drivers/firmware/zynqmp-fpga.c

-- 
2.7.4


___
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


[PATCH v2 2/4] firmware-zynqmp: extend driver with fpga relavant functions

2019-10-25 Thread Thomas Hämmerle
From: Thomas Haemmerle 

Port functions from xlnx-linux to get FPGA status and invoke bitstream
loading.

Signed-off-by: Thomas Haemmerle 
---
 arch/arm/mach-zynqmp/firmware-zynqmp.c | 48 +-
 .../arm/mach-zynqmp/include/mach/firmware-zynqmp.h | 14 ++-
 2 files changed, 60 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-zynqmp/firmware-zynqmp.c 
b/arch/arm/mach-zynqmp/firmware-zynqmp.c
index d91dcb0..6123aa1 100644
--- a/arch/arm/mach-zynqmp/firmware-zynqmp.c
+++ b/arch/arm/mach-zynqmp/firmware-zynqmp.c
@@ -18,7 +18,6 @@
 
 #include 
 
-#define ZYNQMP_PM_VERSION(MAJOR, MINOR)((MAJOR << 16) | MINOR)
 #define ZYNQMP_TZ_VERSION(MAJOR, MINOR)((MAJOR << 16) | MINOR)
 
 #define ZYNQMP_PM_VERSION_MAJOR1
@@ -504,6 +503,51 @@ static int zynqmp_pm_ioctl(u32 node_id, u32 ioctl_id, u32 
arg1, u32 arg2,
   arg1, arg2, out);
 }
 
+/**
+ * zynqmp_pm_fpga_load - Perform the fpga load
+ * @address:   Address to write to
+ * @size:  pl bitstream size
+ * @flags: Flags are used to specify the type of Bitstream file -
+ * defined in ZYNQMP_FPGA_BIT_*-macros
+ *
+ * This function provides access to xilfpga library to transfer
+ * the required bitstream into PL.
+ *
+ * Return: Returns status, either success or error+reason
+ */
+static int zynqmp_pm_fpga_load(u64 address, u32 size, u32 flags)
+{
+   if (!address || !size)
+   return -EINVAL;
+
+   return zynqmp_pm_invoke_fn(PM_FPGA_LOAD,
+   lower_32_bits(address), upper_32_bits(address),
+   size, flags, NULL);
+}
+
+/**
+ * zynqmp_pm_fpga_get_status - Read value from PCAP status register
+ * @value: Value to read
+ *
+ * This function provides access to the xilfpga library to get
+ * the PCAP status
+ *
+ * Return: Returns status, either success or error+reason
+ */
+static int zynqmp_pm_fpga_get_status(u32 *value)
+{
+   u32 ret_payload[PAYLOAD_ARG_CNT];
+   int ret = 0;
+
+   if (!value)
+   return -EINVAL;
+
+   ret = zynqmp_pm_invoke_fn(PM_FPGA_GET_STATUS, 0, 0, 0, 0, ret_payload);
+   *value = ret_payload[1];
+
+   return ret;
+}
+
 static const struct zynqmp_eemi_ops eemi_ops = {
.get_api_version = zynqmp_pm_get_api_version,
.query_data = zynqmp_pm_query_data,
@@ -517,6 +561,8 @@ static const struct zynqmp_eemi_ops eemi_ops = {
.clock_setparent = zynqmp_pm_clock_setparent,
.clock_getparent = zynqmp_pm_clock_getparent,
.ioctl = zynqmp_pm_ioctl,
+   .fpga_getstatus = zynqmp_pm_fpga_get_status,
+   .fpga_load = zynqmp_pm_fpga_load,
 };
 
 /**
diff --git a/arch/arm/mach-zynqmp/include/mach/firmware-zynqmp.h 
b/arch/arm/mach-zynqmp/include/mach/firmware-zynqmp.h
index 9e7a2e3..a044822 100644
--- a/arch/arm/mach-zynqmp/include/mach/firmware-zynqmp.h
+++ b/arch/arm/mach-zynqmp/include/mach/firmware-zynqmp.h
@@ -15,7 +15,17 @@
 #ifndef FIRMWARE_ZYNQMP_H_
 #define FIRMWARE_ZYNQMP_H_
 
-#define PAYLOAD_ARG_CNT 4
+#define PAYLOAD_ARG_CNT4
+
+#define ZYNQMP_PM_VERSION(MAJOR, MINOR)((MAJOR << 16) | MINOR)
+
+#define ZYNQMP_FPGA_BIT_AUTH_DDR   BIT(1)
+#define ZYNQMP_FPGA_BIT_AUTH_OCM   BIT(2)
+#define ZYNQMP_FPGA_BIT_ENC_USR_KEYBIT(3)
+#define ZYNQMP_FPGA_BIT_ENC_DEV_KEYBIT(4)
+#define ZYNQMP_FPGA_BIT_ONLY_BIN   BIT(5)
+
+#define ZYNQMP_PCAP_STATUS_FPGA_DONE   BIT(3)
 
 enum pm_ioctl_id {
IOCTL_SET_PLL_FRAC_MODE = 8,
@@ -61,6 +71,8 @@ struct zynqmp_eemi_ops {
int (*clock_setparent)(u32 clock_id, u32 parent_id);
int (*clock_getparent)(u32 clock_id, u32 *parent_id);
int (*ioctl)(u32 node_id, u32 ioctl_id, u32 arg1, u32 arg2, u32 *out);
+   int (*fpga_getstatus)(u32 *status);
+   int (*fpga_load)(u64 address, u32 size, u32 flags);
 };
 
 const struct zynqmp_eemi_ops *zynqmp_pm_get_eemi_ops(void);
-- 
2.7.4


___
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


[PATCH v2 1/4] firmware-zynqmp: add macros for PMU and trustzone firmware versions

2019-10-25 Thread Thomas Hämmerle
From: Thomas Haemmerle 

Signed-off-by: Thomas Haemmerle 
---
 arch/arm/mach-zynqmp/firmware-zynqmp.c | 22 ++
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/arch/arm/mach-zynqmp/firmware-zynqmp.c 
b/arch/arm/mach-zynqmp/firmware-zynqmp.c
index f2187e9..d91dcb0 100644
--- a/arch/arm/mach-zynqmp/firmware-zynqmp.c
+++ b/arch/arm/mach-zynqmp/firmware-zynqmp.c
@@ -18,17 +18,13 @@
 
 #include 
 
-#define ZYNQMP_PM_VERSION_MAJOR1
-#define ZYNQMP_PM_VERSION_MINOR0
+#define ZYNQMP_PM_VERSION(MAJOR, MINOR)((MAJOR << 16) | MINOR)
+#define ZYNQMP_TZ_VERSION(MAJOR, MINOR)((MAJOR << 16) | MINOR)
 
-#define ZYNQMP_PM_VERSION  ((ZYNQMP_PM_VERSION_MAJOR << 16) | \
-   ZYNQMP_PM_VERSION_MINOR)
-
-#define ZYNQMP_TZ_VERSION_MAJOR 1
-#define ZYNQMP_TZ_VERSION_MINOR 0
-
-#define ZYNQMP_TZ_VERSION  ((ZYNQMP_TZ_VERSION_MAJOR << 16) | \
-   ZYNQMP_TZ_VERSION_MINOR)
+#define ZYNQMP_PM_VERSION_MAJOR1
+#define ZYNQMP_PM_VERSION_MINOR0
+#define ZYNQMP_TZ_VERSION_MAJOR1
+#define ZYNQMP_TZ_VERSION_MINOR0
 
 /* SMC SIP service Call Function Identifier Prefix */
 #define PM_SIP_SVC 0xC200
@@ -544,7 +540,8 @@ static int zynqmp_firmware_probe(struct device_d *dev)
goto out;
 
zynqmp_pm_get_api_version(&pm_api_version);
-   if (pm_api_version < ZYNQMP_PM_VERSION) {
+   if (pm_api_version < ZYNQMP_PM_VERSION(ZYNQMP_PM_VERSION_MAJOR,
+  ZYNQMP_PM_VERSION_MINOR)) {
dev_err(dev, "Platform Management API version error."
"Expected: v%d.%d - Found: v%d.%d\n",
ZYNQMP_PM_VERSION_MAJOR,
@@ -563,7 +560,8 @@ static int zynqmp_firmware_probe(struct device_d *dev)
goto out;
}
 
-   if (pm_tz_version < ZYNQMP_TZ_VERSION) {
+   if (pm_tz_version < ZYNQMP_TZ_VERSION(ZYNQMP_TZ_VERSION_MAJOR,
+ ZYNQMP_TZ_VERSION_MINOR)) {
dev_err(dev, "Trustzone version error."
"Expected: v%d.%d - Found: v%d.%d\n",
ZYNQMP_TZ_VERSION_MAJOR,
-- 
2.7.4


___
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


[PATCH 5/5] firmware: zynqmp-fpga: print Xilinx bitstream header

2019-10-24 Thread Thomas Hämmerle
From: Michael Tretter 

The bitstream header has 5 fields, that start with a char for the type.
Four fields have a big-ending length and a null-terminated string for
the design name, the part number, and the date and time of creation. The
last field is a big-endian 32 bit unsigned int for the size of the
bitstream.

Print this info when loading the bitstream.

Signed-off-by: Michael Tretter 
---
 drivers/firmware/zynqmp-fpga.c | 51 ++
 1 file changed, 51 insertions(+)

diff --git a/drivers/firmware/zynqmp-fpga.c b/drivers/firmware/zynqmp-fpga.c
index 6a32d28..7bf880f 100644
--- a/drivers/firmware/zynqmp-fpga.c
+++ b/drivers/firmware/zynqmp-fpga.c
@@ -39,6 +39,19 @@ struct fpgamgr {
u32 features;
 };
 
+struct bs_header {
+   __be16 length;
+   u8 padding[9];
+   __be16 size;
+   char entries[0];
+} __attribute__ ((packed));
+
+struct bs_header_entry {
+   char type;
+   __be16 length;
+   char data[0];
+} __attribute__ ((packed));
+
 /* Xilinx binary format header */
 static const u32 bin_format[] = {
DUMMY_WORD,
@@ -100,6 +113,42 @@ static int get_header_length(const char *buf, size_t size)
return -EINVAL;
 }
 
+static void zynqmp_fpga_show_header(const struct device_d *dev,
+struct bs_header *header, size_t size)
+{
+   struct bs_header_entry *entry;
+   unsigned int i;
+   unsigned int length;
+
+   for (i = 0; i < size - sizeof(*header); i += sizeof(*entry) + length) {
+   entry = (struct bs_header_entry *)&header->entries[i];
+   length = __be16_to_cpu(entry->length);
+
+   switch (entry->type) {
+   case 'a':
+   printf("Design: %s\n", entry->data);
+   break;
+   case 'b':
+   printf("Part number: %s\n", entry->data);
+   break;
+   case 'c':
+   printf("Date: %s\n", entry->data);
+   break;
+   case 'd':
+   printf("Time: %s\n", entry->data);
+   break;
+   case 'e':
+   /* Size entry does not have a length but is be32 int */
+   printf("Size: %d bytes\n",
+  (length << 16) + (entry->data[0] << 8) + 
entry->data[1]);
+   return;
+   default:
+   dev_warn(dev, "Invalid header entry: %c", entry->type);
+   return;
+   }
+   }
+}
+
 static int fpgamgr_program_finish(struct firmware_handler *fh)
 {
struct fpgamgr *mgr = container_of(fh, struct fpgamgr, fh);
@@ -121,6 +170,8 @@ static int fpgamgr_program_finish(struct firmware_handler 
*fh)
status = header_length;
goto err_free;
}
+   zynqmp_fpga_show_header(&mgr->dev,
+ (struct bs_header *)mgr->buf, header_length);
 
byte_order = get_byte_order((u32 *)&mgr->buf[header_length],
mgr->size - header_length);
-- 
2.7.4


___
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


[PATCH 1/5] ARM: zynqmp: dts: move firmware node to src tree

2019-10-24 Thread Thomas Hämmerle
From: Michael Tretter 

The firmware node will be added to the mainline device tree. As it will
eventually enter Barebox via a device tree sync, add it to the src tree
already.

Signed-off-by: Michael Tretter 
---
 arch/arm/dts/zynqmp-zcu104-revA.dts |  1 -
 arch/arm/dts/zynqmp.dtsi| 17 -
 dts/src/arm64/xilinx/zynqmp.dtsi|  7 +++
 3 files changed, 7 insertions(+), 18 deletions(-)
 delete mode 100644 arch/arm/dts/zynqmp.dtsi

diff --git a/arch/arm/dts/zynqmp-zcu104-revA.dts 
b/arch/arm/dts/zynqmp-zcu104-revA.dts
index c03112d..8b8dd84 100644
--- a/arch/arm/dts/zynqmp-zcu104-revA.dts
+++ b/arch/arm/dts/zynqmp-zcu104-revA.dts
@@ -8,5 +8,4 @@
  */
 
 #include 
-#include "zynqmp.dtsi"
 #include "zynqmp-clk.dtsi"
diff --git a/arch/arm/dts/zynqmp.dtsi b/arch/arm/dts/zynqmp.dtsi
deleted file mode 100644
index 59984ee..000
--- a/arch/arm/dts/zynqmp.dtsi
+++ /dev/null
@@ -1,17 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * dts file for Xilinx ZynqMP
- *
- * (C) Copyright 2014 - 2015, Xilinx, Inc.
- *
- * Michal Simek 
- */
-
-/ {
-   firmware {
-   zynqmp_firmware: zynqmp-firmware {
-   compatible = "xlnx,zynqmp-firmware";
-   method = "smc";
-   };
-   };
-};
diff --git a/dts/src/arm64/xilinx/zynqmp.dtsi b/dts/src/arm64/xilinx/zynqmp.dtsi
index 9aa6734..9115eae 100644
--- a/dts/src/arm64/xilinx/zynqmp.dtsi
+++ b/dts/src/arm64/xilinx/zynqmp.dtsi
@@ -115,6 +115,13 @@
method = "smc";
};
 
+   firmware {
+   zynqmp_firmware: zynqmp-firmware {
+   compatible = "xlnx,zynqmp-firmware";
+   method = "smc";
+   };
+   };
+
timer {
compatible = "arm,armv8-timer";
interrupt-parent = <&gic>;
-- 
2.7.4


___
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


[PATCH 2/5] firmware-zynqmp: extend driver with fpga relavant functions

2019-10-24 Thread Thomas Hämmerle
From: Thomas Haemmerle 

Port functions from xlnx-linux to get FPGA status and invoke bitstream
loading.

Signed-off-by: Thomas Haemmerle 
---
 arch/arm/mach-zynqmp/firmware-zynqmp.c | 47 ++
 .../arm/mach-zynqmp/include/mach/firmware-zynqmp.h |  8 
 2 files changed, 55 insertions(+)

diff --git a/arch/arm/mach-zynqmp/firmware-zynqmp.c 
b/arch/arm/mach-zynqmp/firmware-zynqmp.c
index f2187e9..18a1a51 100644
--- a/arch/arm/mach-zynqmp/firmware-zynqmp.c
+++ b/arch/arm/mach-zynqmp/firmware-zynqmp.c
@@ -508,6 +508,51 @@ static int zynqmp_pm_ioctl(u32 node_id, u32 ioctl_id, u32 
arg1, u32 arg2,
   arg1, arg2, out);
 }
 
+/**
+ * zynqmp_pm_fpga_load - Perform the fpga load
+ * @address:   Address to write to
+ * @size:  pl bitstream size
+ * @flags: Flags are used to specify the type of Bitstream file -
+ * defined in ZYNQMP_FPGA_BIT_*-macros
+ *
+ * This function provides access to xilfpga library to transfer
+ * the required bitstream into PL.
+ *
+ * Return: Returns status, either success or error+reason
+ */
+static int zynqmp_pm_fpga_load(u64 address, u32 size, u32 flags)
+{
+   if (!address || !size)
+   return -EINVAL;
+
+   return zynqmp_pm_invoke_fn(PM_FPGA_LOAD,
+   lower_32_bits(address), upper_32_bits(address),
+   size, flags, NULL);
+}
+
+/**
+ * zynqmp_pm_fpga_get_status - Read value from PCAP status register
+ * @value: Value to read
+ *
+ * This function provides access to the xilfpga library to get
+ * the PCAP status
+ *
+ * Return: Returns status, either success or error+reason
+ */
+static int zynqmp_pm_fpga_get_status(u32 *value)
+{
+   u32 ret_payload[PAYLOAD_ARG_CNT];
+   int ret = 0;
+
+   if (!value)
+   return -EINVAL;
+
+   ret = zynqmp_pm_invoke_fn(PM_FPGA_GET_STATUS, 0, 0, 0, 0, ret_payload);
+   *value = ret_payload[1];
+
+   return ret;
+}
+
 static const struct zynqmp_eemi_ops eemi_ops = {
.get_api_version = zynqmp_pm_get_api_version,
.query_data = zynqmp_pm_query_data,
@@ -521,6 +566,8 @@ static const struct zynqmp_eemi_ops eemi_ops = {
.clock_setparent = zynqmp_pm_clock_setparent,
.clock_getparent = zynqmp_pm_clock_getparent,
.ioctl = zynqmp_pm_ioctl,
+   .fpga_getstatus = zynqmp_pm_fpga_get_status,
+   .fpga_load = zynqmp_pm_fpga_load,
 };
 
 /**
diff --git a/arch/arm/mach-zynqmp/include/mach/firmware-zynqmp.h 
b/arch/arm/mach-zynqmp/include/mach/firmware-zynqmp.h
index 9e7a2e3..f19d73d 100644
--- a/arch/arm/mach-zynqmp/include/mach/firmware-zynqmp.h
+++ b/arch/arm/mach-zynqmp/include/mach/firmware-zynqmp.h
@@ -17,6 +17,12 @@
 
 #define PAYLOAD_ARG_CNT 4
 
+#define ZYNQMP_FPGA_BIT_AUTH_DDR   BIT(1)
+#define ZYNQMP_FPGA_BIT_AUTH_OCM   BIT(2)
+#define ZYNQMP_FPGA_BIT_ENC_USR_KEYBIT(3)
+#define ZYNQMP_FPGA_BIT_ENC_DEV_KEYBIT(4)
+#define ZYNQMP_FPGA_BIT_ONLY_BIN   BIT(5)
+
 enum pm_ioctl_id {
IOCTL_SET_PLL_FRAC_MODE = 8,
IOCTL_GET_PLL_FRAC_MODE,
@@ -61,6 +67,8 @@ struct zynqmp_eemi_ops {
int (*clock_setparent)(u32 clock_id, u32 parent_id);
int (*clock_getparent)(u32 clock_id, u32 *parent_id);
int (*ioctl)(u32 node_id, u32 ioctl_id, u32 arg1, u32 arg2, u32 *out);
+   int (*fpga_getstatus)(u32 *status);
+   int (*fpga_load)(u64 address, u32 size, u32 flags);
 };
 
 const struct zynqmp_eemi_ops *zynqmp_pm_get_eemi_ops(void);
-- 
2.7.4


___
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


[PATCH 4/5] ARM: zynqmp: dts: move pcap node to src tree

2019-10-24 Thread Thomas Hämmerle
From: Thomas Haemmerle 

The pcap node will be added to the mainline device tree. As it will
eventually enter Barebox via a device tree sync, add it to the src tree
already.

Signed-off-by: Thomas Haemmerle 
---
 dts/src/arm64/xilinx/zynqmp.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/dts/src/arm64/xilinx/zynqmp.dtsi b/dts/src/arm64/xilinx/zynqmp.dtsi
index 9115eae..1d1e531 100644
--- a/dts/src/arm64/xilinx/zynqmp.dtsi
+++ b/dts/src/arm64/xilinx/zynqmp.dtsi
@@ -119,6 +119,9 @@
zynqmp_firmware: zynqmp-firmware {
compatible = "xlnx,zynqmp-firmware";
method = "smc";
+   zynqmp_pcap: pcap {
+   compatible = "xlnx,zynqmp-pcap-fpga";
+   };
};
};
 
-- 
2.7.4


___
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


[PATCH 3/5] firmware: zynqmp-fpga: introduce driver to load bitstream to FPGA

2019-10-24 Thread Thomas Hämmerle
From: Thomas Haemmerle 

The driver provides functionalities to check and load a bitstream to FPGA.
A boolean parameter to check if FPGA is already programmed is
added.

Signed-off-by: Thomas Haemmerle 
---
 arch/arm/configs/zynqmp_defconfig  |   1 +
 .../arm/mach-zynqmp/include/mach/firmware-zynqmp.h |   2 +
 drivers/firmware/Kconfig   |   5 +
 drivers/firmware/Makefile  |   1 +
 drivers/firmware/zynqmp-fpga.c | 315 +
 5 files changed, 324 insertions(+)
 create mode 100644 drivers/firmware/zynqmp-fpga.c

diff --git a/arch/arm/configs/zynqmp_defconfig 
b/arch/arm/configs/zynqmp_defconfig
index 4dea964..834212e 100644
--- a/arch/arm/configs/zynqmp_defconfig
+++ b/arch/arm/configs/zynqmp_defconfig
@@ -35,4 +35,5 @@ CONFIG_CMD_OFTREE=y
 CONFIG_CMD_TIME=y
 CONFIG_DRIVER_SERIAL_CADENCE=y
 # CONFIG_SPI is not set
+CONFIG_FIRMWARE_ZYNQMP_PL=y
 CONFIG_DIGEST=y
diff --git a/arch/arm/mach-zynqmp/include/mach/firmware-zynqmp.h 
b/arch/arm/mach-zynqmp/include/mach/firmware-zynqmp.h
index f19d73d..6fcfba5 100644
--- a/arch/arm/mach-zynqmp/include/mach/firmware-zynqmp.h
+++ b/arch/arm/mach-zynqmp/include/mach/firmware-zynqmp.h
@@ -23,6 +23,8 @@
 #define ZYNQMP_FPGA_BIT_ENC_DEV_KEYBIT(4)
 #define ZYNQMP_FPGA_BIT_ONLY_BIN   BIT(5)
 
+#define ZYNQMP_PCAP_STATUS_FPGA_DONE   BIT(3)
+
 enum pm_ioctl_id {
IOCTL_SET_PLL_FRAC_MODE = 8,
IOCTL_GET_PLL_FRAC_MODE,
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 710b500..3113f40 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -14,4 +14,9 @@ config FIRMWARE_ALTERA_SOCFPGA
bool "Altera SoCFPGA fpga loader"
depends on ARCH_SOCFPGA
select FIRMWARE
+   
+config FIRMWARE_ZYNQMP_FPGA
+   bool "Xilinx ZynqMP FPGA loader"
+   depends on ARCH_ZYNQMP
+   select FIRMWARE
 endmenu
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index c3a3c34..b162b08 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_FIRMWARE_ALTERA_SERIAL) += altera_serial.o
 obj-$(CONFIG_FIRMWARE_ALTERA_SOCFPGA) += socfpga.o
+obj-$(CONFIG_FIRMWARE_ZYNQMP_FPGA) += zynqmp-fpga.o
diff --git a/drivers/firmware/zynqmp-fpga.c b/drivers/firmware/zynqmp-fpga.c
new file mode 100644
index 000..6a32d28
--- /dev/null
+++ b/drivers/firmware/zynqmp-fpga.c
@@ -0,0 +1,315 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Xilinx Zynq MPSoC PL loading
+ *
+ * Copyright (c) 2018 Thomas Haemmerle 
+ *
+ * based on U-Boot zynqmppl code
+ *
+ * (C) Copyright 2015 - 2016, Xilinx, Inc,
+ * Michal Simek 
+ * Siva Durga Prasad  *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define ZYNQMP_PM_VERSION_1_1  ((1 << 16) | 1)
+
+#define ZYNQMP_PM_FEATURE_BYTE_ORDER_IRREL BIT(0)
+
+#define ZYNQMP_PM_VERSION_1_0_FEATURES 0
+#define ZYNQMP_PM_VERSION_1_1_FEATURES  ZYNQMP_PM_FEATURE_BYTE_ORDER_IRREL
+
+#define DUMMY_WORD 0x
+
+#define XILINX_BYTE_ORDER_BIT  0
+#define XILINX_BYTE_ORDER_BIN  1
+
+struct fpgamgr {
+   struct firmware_handler fh;
+   struct device_d dev;
+   const struct zynqmp_eemi_ops *eemi_ops;
+   int programmed;
+   char *buf;
+   size_t size;
+   u32 features;
+};
+
+/* Xilinx binary format header */
+static const u32 bin_format[] = {
+   DUMMY_WORD,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   0x00bb,
+   0x11220044,
+   DUMMY_WORD,
+   DUMMY_WORD,
+   0xaa995566,
+};
+
+static void copy_words_swapped(u32 *dst, const u32 *src, size_t size)
+{
+   int i;
+
+   for (i = 0; i < size; i++)
+   dst[i] = __swab32(src[i]);
+}
+
+static int get_byte_order(const u32 *buf, size_t size)
+{
+   u32 buf_check[ARRAY_SIZE(bin_format)];
+
+   memcpy(buf_check, buf, ARRAY_SIZE(buf_check));
+   if (memcmp(buf_check, bin_format, sizeof(buf_check)) == 0)
+   return XILINX_BYTE_ORDER_BIT;
+
+   copy_words_swapped(buf_check, buf, ARRAY_SIZE(buf_check));
+   if (memcmp(buf_check, bin_format, sizeof(buf_check)) == 0)
+   return XILINX_BYTE_ORDER_BIN;
+
+   return -EINVAL;
+}
+
+static int get_header_length(const char *buf, size_t size)
+{
+   u32 *buf_u32;
+   int p;
+
+   for (p = 0; p < size; p++) {
+   buf_u32 = (u32 *)&buf[p];
+   if (*buf_u32 == DUMMY_WORD)
+   return p;
+   }
+   return -EINVAL;
+}
+
+static int fpgamgr_program_finish(struct firmware_handler *fh)
+{
+   struct fpgamgr *mgr = container_of(fh, struct fpgamgr, fh);
+   char *buf_align

[PATCH 0/5] ARM: zynqmp: add support for bitstream loading

2019-10-24 Thread Thomas Hämmerle
From: Thomas Haemmerle 

Michael Tretter (2):
  ARM: zynqmp: dts: move firmware node to src tree
  firmware: zynqmp-fpga: print Xilinx bitstream header

Thomas Haemmerle (3):
  firmware-zynqmp: extend driver with fpga relavant functions
  firmware: zynqmp-fpga: introduce driver to load bitstream to FPGA
  ARM: zynqmp: dts: move pcap node to src tree

 arch/arm/configs/zynqmp_defconfig  |   1 +
 arch/arm/dts/zynqmp-zcu104-revA.dts|   1 -
 arch/arm/dts/zynqmp.dtsi   |  17 -
 arch/arm/mach-zynqmp/firmware-zynqmp.c |  47 +++
 .../arm/mach-zynqmp/include/mach/firmware-zynqmp.h |  10 +
 drivers/firmware/Kconfig   |   5 +
 drivers/firmware/Makefile  |   1 +
 drivers/firmware/zynqmp-fpga.c | 366 +
 dts/src/arm64/xilinx/zynqmp.dtsi   |  10 +
 9 files changed, 440 insertions(+), 18 deletions(-)
 delete mode 100644 arch/arm/dts/zynqmp.dtsi
 create mode 100644 drivers/firmware/zynqmp-fpga.c

-- 
2.7.4


___
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


[PATCH v2] firmware-zynqmp: port from linux

2019-02-21 Thread Thomas Hämmerle
From: Thomas Haemmerle 

Changes since v1:
- return -EIO (instead of -1) if API version or trustzone version are 
  earlier than v1.0 in probe function

Thomas Haemmerle (1):
  firmware-zynqmp: port from linux

 arch/arm/Kconfig   |   1 +
 arch/arm/mach-zynqmp/Makefile  |   2 +-
 arch/arm/mach-zynqmp/firmware-zynqmp.c | 601 +
 .../arm/mach-zynqmp/include/mach/firmware-zynqmp.h |  66 +++
 4 files changed, 669 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-zynqmp/firmware-zynqmp.c
 create mode 100644 arch/arm/mach-zynqmp/include/mach/firmware-zynqmp.h

-- 
2.7.4


___
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


Re: [PATCH] firmware-zynqmp: port from linux

2019-02-14 Thread Thomas Hämmerle
Hi Sascha,

On 12.02.19 09:31, Sascha Hauer wrote:
> Hi Thomas,
> 
> On Mon, Feb 11, 2019 at 02:10:40PM +0000, Thomas Hämmerle wrote:
>> From: Thomas Haemmerle 
>>
>> Port Xilinx Zynq MPSoC Firmware layer driver from linux.
>>
>> Signed-off-by: Thomas Haemmerle 
>> ---
>>   arch/arm/Kconfig   |   1 +
>>   arch/arm/mach-zynqmp/Makefile  |   2 +-
>>   arch/arm/mach-zynqmp/firmware-zynqmp.c | 601 
>> +
>>   .../arm/mach-zynqmp/include/mach/firmware-zynqmp.h |  66 +++
>>   4 files changed, 669 insertions(+), 1 deletion(-)
>>   create mode 100644 arch/arm/mach-zynqmp/firmware-zynqmp.c
>>   create mode 100644 arch/arm/mach-zynqmp/include/mach/firmware-zynqmp.h
>>
>> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
>> index c1f385b..fdbe5b7 100644
>> --- a/arch/arm/Kconfig
>> +++ b/arch/arm/Kconfig
>> @@ -250,6 +250,7 @@ config ARCH_ZYNQMP
>>  select CPU_V8
>>  select HAS_DEBUG_LL
>>  select HAVE_PBL_MULTI_IMAGES
>> +select ARM_SMCCC
>>  select COMMON_CLK
>>  select COMMON_CLK_OF_PROVIDER
>>  select CLKDEV_LOOKUP
>> diff --git a/arch/arm/mach-zynqmp/Makefile b/arch/arm/mach-zynqmp/Makefile
>> index c601374..021efc9 100644
>> --- a/arch/arm/mach-zynqmp/Makefile
>> +++ b/arch/arm/mach-zynqmp/Makefile
>> @@ -1,2 +1,2 @@
>>   # SPDX-License-Identifier: GPL-2.0-or-later
>> -obj- := __dummy__.o
>> +obj-y += firmware-zynqmp.o
>> diff --git a/arch/arm/mach-zynqmp/firmware-zynqmp.c 
>> b/arch/arm/mach-zynqmp/firmware-zynqmp.c
> 
> 
> Maybe drivers/firmware/ would be a more appropriate directory to put
> this driver in.

I was not sure where to put the this driver in:

In linux drivers/firmware is the location for drivers which communicate
with a firmware (like this one).

In barebox, this directory contains drivers to load firmware to devices
(socfpga.c for example). Since I will also create a driver to load the
PL (programmable logic) of ZynqMP which I will place in
drivers/firmware, I decided to put this driver to arch/arm.

> 
>> +static int zynqmp_firmware_probe(struct device_d *dev)
>> +{
>> +int ret;
>> +
>> +ret = get_set_conduit_method(dev->device_node);
>> +if (ret)
>> +goto out;
>> +
>> +zynqmp_pm_get_api_version(&pm_api_version);
>> +if (pm_api_version < ZYNQMP_PM_VERSION) {
>> +dev_err(dev, "Platform Management API version error."
>> +"Expected: v%d.%d - Found: v%d.%d\n",
>> +ZYNQMP_PM_VERSION_MAJOR,
>> +ZYNQMP_PM_VERSION_MINOR,
>> +pm_api_version >> 16, pm_api_version & 0x);
>> +ret = -1;
>> +goto out;
> 
> -1 is -EPERM which is not a meaningful error code here. Please pick
> something appropriate from errno.h.

Of course - will fix this.

> 
> Otherwise looks good. This looks like clock support. Are you planning to
> create a clk driver aswell?

Yes, a clk driver is also planned.

Thomas
___
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


[PATCH 5/6] macb: disable second priority queue for zynqmp gem support

2019-01-08 Thread Thomas Hämmerle
Provide descriptors for second priority rx and tx queues and disable the
the queues if hardware is GEM. Otherwise the function macb_send() will run
into a timeout.

Signed-off-by: Thomas Haemmerle 
---
 drivers/net/macb.c | 21 +
 drivers/net/macb.h |  2 ++
 2 files changed, 23 insertions(+)

diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index c129282..2a30457 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -46,9 +46,11 @@
 #define RX_BUFFER_MULTIPLE 64  /* bytes */
 #define RX_NB_PACKET   10
 #define TX_RING_SIZE   2 /* must be power of 2 */
+#define GEM_Q1_DESCS   2
 
 #define RX_RING_BYTES(bp)  (sizeof(struct macb_dma_desc) * 
bp->rx_ring_size)
 #define TX_RING_BYTES  (sizeof(struct macb_dma_desc) * TX_RING_SIZE)
+#define GEM_Q1_DESC_BYTES  (sizeof(struct macb_dma_desc) * GEM_Q1_DESCS)
 
 struct macb_device {
void__iomem *regs;
@@ -60,6 +62,7 @@ struct macb_device {
void*tx_buffer;
struct macb_dma_desc*rx_ring;
struct macb_dma_desc*tx_ring;
+   struct macb_dma_desc*gem_q1_descs;
 
int rx_buffer_size;
int rx_ring_size;
@@ -340,6 +343,20 @@ static void macb_init(struct macb_device *macb)
macb_writel(macb, RBQP, (ulong)macb->rx_ring);
macb_writel(macb, TBQP, (ulong)macb->tx_ring);
 
+   if (macb->is_gem && macb->gem_q1_descs) {
+   /* Disable the second priority queue */
+   macb->gem_q1_descs[0].addr = 0;
+   macb->gem_q1_descs[0].ctrl = MACB_BIT(TX_WRAP) |
+   MACB_BIT(TX_LAST) |
+   MACB_BIT(TX_USED);
+   macb->gem_q1_descs[1].addr = MACB_BIT(RX_USED) |
+   MACB_BIT(RX_WRAP);
+   macb->gem_q1_descs[1].ctrl = 0;
+
+   gem_writel(macb, TQ1, (ulong)&macb->gem_q1_descs[0]);
+   gem_writel(macb, RQ1, (ulong)&macb->gem_q1_descs[1]);
+   }
+
switch(macb->interface) {
case PHY_INTERFACE_MODE_RGMII:
val = GEM_BIT(RGMII);
@@ -689,6 +706,10 @@ static int macb_probe(struct device_d *dev)
macb->rx_ring = dma_alloc_coherent(RX_RING_BYTES(macb), 
DMA_ADDRESS_BROKEN);
macb->tx_ring = dma_alloc_coherent(TX_RING_BYTES, DMA_ADDRESS_BROKEN);
 
+   if (macb->is_gem)
+   macb->gem_q1_descs = dma_alloc_coherent(GEM_Q1_DESC_BYTES,
+   DMA_ADDRESS_BROKEN);
+
macb_reset_hw(macb);
ncfgr = macb_mdc_clk_div(macb);
ncfgr |= MACB_BIT(PAE); /* PAuse Enable */
diff --git a/drivers/net/macb.h b/drivers/net/macb.h
index 6be9732..979f53c 100644
--- a/drivers/net/macb.h
+++ b/drivers/net/macb.h
@@ -72,6 +72,8 @@
 #define GEM_DCFG5  0x0290
 #define GEM_DCFG6  0x0294
 #define GEM_DCFG7  0x0298
+#define GEM_TQ10x0440
+#define GEM_RQ10x0480
 
 /* Bitfields in NCR */
 #define MACB_LB_OFFSET 0
-- 
2.7.4


Thomas Hämmerle
Research and Development 

Wolfvision GmbH
 | 6833 Klaus | Austria 
Tel: +43 5523 52250 | Mail: thomas.haemme...@wolfvision.net 

Webpage: www.wolfvision.com | www.wolfvision.com/green
Firmenbuch / Commercial Register: FN283521v Feldkirch/Austria


___
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


[PATCH 1/6] dp83867: port from linux

2019-01-08 Thread Thomas Hämmerle
  phy_write(phydev, MII_BMCR, BMCR_ANENABLE |
+   BMCR_FULLDPLX |
+   BMCR_SPEED1000);
+
+   cfg2 = phy_read(phydev, MII_DP83867_CFG2);
+   cfg2 &= MII_DP83867_CFG2_MASK;
+   cfg2 |= MII_DP83867_CFG2_SPEEDOPT_10EN |
+   MII_DP83867_CFG2_SGMII_AUTONEGEN |
+   MII_DP83867_CFG2_SPEEDOPT_ENH |
+   MII_DP83867_CFG2_SPEEDOPT_CNT |
+   MII_DP83867_CFG2_SPEEDOPT_INTLOW;
+
+   phy_write(phydev, MII_DP83867_CFG2, cfg2);
+
+   phy_write_mmd_indirect(phydev, DP83867_RGMIICTL,
+   DP83867_DEVADDR, 0x0);
+
+   val = DP83867_PHYCTRL_SGMIIEN |
+   DP83867_MDI_CROSSOVER_MDIX << DP83867_MDI_CROSSOVER |
+   dp83867->fifo_depth << DP83867_PHYCTRL_RXFIFO_SHIFT |
+   dp83867->fifo_depth << DP83867_PHYCTRL_TXFIFO_SHIFT;
+
+   phy_write(phydev, MII_DP83867_PHYCTRL, val);
+   phy_write(phydev, MII_DP83867_BISCR, 0x0);
+   }
+
+   if (phy_interface_is_rgmii(phydev)) {
+   val = phy_read_mmd_indirect(phydev, DP83867_RGMIICTL,
+   DP83867_DEVADDR);
+
+   switch (phydev->interface) {
+   case PHY_INTERFACE_MODE_RGMII_ID:
+   val |= (DP83867_RGMII_TX_CLK_DELAY_EN
+   | DP83867_RGMII_RX_CLK_DELAY_EN);
+   break;
+   case PHY_INTERFACE_MODE_RGMII_TXID:
+   val |= DP83867_RGMII_TX_CLK_DELAY_EN;
+   break;
+   case PHY_INTERFACE_MODE_RGMII_RXID:
+   val |= DP83867_RGMII_RX_CLK_DELAY_EN;
+   break;
+   default:
+   break;
+   }
+   phy_write_mmd_indirect(phydev, DP83867_RGMIICTL,
+   DP83867_DEVADDR, val);
+
+   delay = (dp83867->rx_id_delay |
+   (dp83867->tx_id_delay << 
DP83867_RGMII_TX_CLK_DELAY_SHIFT));
+
+   phy_write_mmd_indirect(phydev, DP83867_RGMIIDCTL,
+   DP83867_DEVADDR, delay);
+
+   if (dp83867->io_impedance >= 0) {
+   val = phy_read_mmd_indirect(phydev, DP83867_IO_MUX_CFG,
+   DP83867_DEVADDR);
+   val &= ~DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL;
+   val |= dp83867->io_impedance
+   & DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL;
+
+   phy_write_mmd_indirect(phydev, DP83867_IO_MUX_CFG,
+   DP83867_DEVADDR, val);
+   }
+   }
+
+   genphy_config_aneg(phydev);
+
+   if (dp83867->port_mirroring != DP83867_PORT_MIRROING_KEEP)
+   dp83867_config_port_mirroring(phydev);
+
+   dev_info(&phydev->dev, "DP83867\n");
+
+   return 0;
+}
+
+static struct phy_driver dp83867_driver[] = {
+   {
+   .phy_id = DP83867_PHY_ID,
+   .phy_id_mask = 0xfff0,
+   .drv.name = "TI DP83867",
+   .features = PHY_GBIT_FEATURES,
+
+   .config_init = dp83867_config_init,
+
+   .config_aneg = genphy_config_aneg,
+   .read_status = genphy_read_status,
+   },
+};
+
+static int dp83867_phy_init(void)
+{
+   return phy_drivers_register(dp83867_driver, ARRAY_SIZE(dp83867_driver));
+}
+fs_initcall(dp83867_phy_init);
-- 
2.7.4


Thomas Hämmerle
Research and Development 

Wolfvision GmbH
 | 6833 Klaus | Austria 
Tel: +43 5523 52250 | Mail: thomas.haemme...@wolfvision.net 

Webpage: www.wolfvision.com | www.wolfvision.com/green
Firmenbuch / Commercial Register: FN283521v Feldkirch/Austria


___
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


[PATCH 6/6] zynqmp: enable macb Ethernet support

2019-01-08 Thread Thomas Hämmerle
Signed-off-by: Thomas Haemmerle 
---
 arch/arm/configs/zynqmp_defconfig | 1 +
 drivers/net/macb.c| 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm/configs/zynqmp_defconfig 
b/arch/arm/configs/zynqmp_defconfig
index 4dea964..a358a50 100644
--- a/arch/arm/configs/zynqmp_defconfig
+++ b/arch/arm/configs/zynqmp_defconfig
@@ -33,6 +33,7 @@ CONFIG_CMD_TIMEOUT=y
 CONFIG_CMD_CLK=y
 CONFIG_CMD_OFTREE=y
 CONFIG_CMD_TIME=y
+CONFIG_DRIVER_NET_MACB=y
 CONFIG_DRIVER_SERIAL_CADENCE=y
 # CONFIG_SPI is not set
 CONFIG_DIGEST=y
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 2a30457..0c0d17e 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -738,6 +738,7 @@ static void macb_remove(struct device_d *dev)
 static const struct of_device_id macb_dt_ids[] = {
{ .compatible = "cdns,at91sam9260-macb",},
{ .compatible = "atmel,sama5d3-gem",},
+   { .compatible = "cdns,zynqmp-gem",},
{ /* sentinel */ }
 };
 
-- 
2.7.4


Thomas Hämmerle
Research and Development 

Wolfvision GmbH
 | 6833 Klaus | Austria 
Tel: +43 5523 52250 | Mail: thomas.haemme...@wolfvision.net 

Webpage: www.wolfvision.com | www.wolfvision.com/green
Firmenbuch / Commercial Register: FN283521v Feldkirch/Austria


___
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


[PATCH 2/6] macb: fix format specifiers for debug output

2019-01-08 Thread Thomas Hämmerle
Fixes compiler warning "format '%d' expects argument of type 'int', but
argument 4 has type 'size_t {aka long unsigned int}' [-Wformat=]".

Signed-off-by: Thomas Haemmerle 
---
 drivers/net/macb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 1a8f6da..240802e 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -596,7 +596,7 @@ static void macb_init_rx_buffer_size(struct macb_device 
*bp, size_t size)
   DMA_ADDRESS_BROKEN);
}
 
-   dev_dbg(bp->dev, "[%d] rx_buffer_size [%d]\n",
+   dev_dbg(bp->dev, "[%zu] rx_buffer_size [%d]\n",
       size, bp->rx_buffer_size);
 }
 
-- 
2.7.4


Thomas Hämmerle
Research and Development 

Wolfvision GmbH
 | 6833 Klaus | Austria 
Tel: +43 5523 52250 | Mail: thomas.haemme...@wolfvision.net 

Webpage: www.wolfvision.com | www.wolfvision.com/green
Firmenbuch / Commercial Register: FN283521v Feldkirch/Austria


___
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


[PATCH 3/6] macb: fix check if hw is gem

2019-01-08 Thread Thomas Hämmerle
Fix check for peripheral version in MACB_MID register to treat Xilinx
ZynqMP as GEM. All MIDs >= 2 indicate a GEM not only MID == 2.

Signed-off-by: Thomas Haemmerle 
---
 drivers/net/macb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 240802e..c776535 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -86,7 +86,7 @@ static inline bool macb_is_gem(struct macb_device *macb)
 
 static inline bool read_is_gem(struct macb_device *macb)
 {
-   return MACB_BFEXT(IDNUM, macb_readl(macb, MID)) == 0x2;
+   return MACB_BFEXT(IDNUM, macb_readl(macb, MID)) >= 0x2;
 }
 
 static int macb_send(struct eth_device *edev, void *packet,
-- 
2.7.4


Thomas Hämmerle
Research and Development 

Wolfvision GmbH
 | 6833 Klaus | Austria 
Tel: +43 5523 52250 | Mail: thomas.haemme...@wolfvision.net 

Webpage: www.wolfvision.com | www.wolfvision.com/green
Firmenbuch / Commercial Register: FN283521v Feldkirch/Austria


___
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


[PATCH 4/6] macb: fix memory leakage due to double allocation of rx_buffer

2019-01-08 Thread Thomas Hämmerle
Remove memory allocation of rx buffer in function
macb_init_rx_buffer_size, which caused a memory leak since it also is
alocated in macb_probe().

Signed-off-by: Thomas Haemmerle 
---
 drivers/net/macb.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index c776535..c129282 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -592,8 +592,6 @@ static void macb_init_rx_buffer_size(struct macb_device 
*bp, size_t size)
bp->rx_buffer_size =
roundup(bp->rx_buffer_size, RX_BUFFER_MULTIPLE);
}
-   bp->rx_buffer = dma_alloc_coherent(bp->rx_buffer_size * 
bp->rx_ring_size,
-  DMA_ADDRESS_BROKEN);
}
 
dev_dbg(bp->dev, "[%zu] rx_buffer_size [%d]\n",
-- 
2.7.4


Thomas Hämmerle
Research and Development 

Wolfvision GmbH
 | 6833 Klaus | Austria 
Tel: +43 5523 52250 | Mail: thomas.haemme...@wolfvision.net 

Webpage: www.wolfvision.com | www.wolfvision.com/green
Firmenbuch / Commercial Register: FN283521v Feldkirch/Austria


___
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox