[PATCH 2/2] ARM: Layerscape: ls1046a: enable GPIOs

2019-09-17 Thread Steffen Trumtrar
Enable GPIOs on LS1046a.

Signed-off-by: Steffen Trumtrar 
---
 arch/arm/dts/fsl-ls1046a-rdb.dts | 12 
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/dts/fsl-ls1046a-rdb.dts b/arch/arm/dts/fsl-ls1046a-rdb.dts
index e16948bc8a51..e3ae75e42dd5 100644
--- a/arch/arm/dts/fsl-ls1046a-rdb.dts
+++ b/arch/arm/dts/fsl-ls1046a-rdb.dts
@@ -29,6 +29,18 @@
};
 };
 
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
  {
ethernet@e {
status = "disabled";
-- 
2.23.0


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


[PATCH 1/2] gpio: add driver for MPC8xxx ip core

2019-09-17 Thread Steffen Trumtrar
Import GPIO-driver for MPC512x/8349/8572/8610/QorIQ and compatible from Linux
v5.2.

Signed-off-by: Steffen Trumtrar 
---
 drivers/gpio/Kconfig|   8 +++
 drivers/gpio/Makefile   |   1 +
 drivers/gpio/gpio-mpc8xxx.c | 122 
 3 files changed, 131 insertions(+)
 create mode 100644 drivers/gpio/gpio-mpc8xxx.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 7a1503198b49..0f924d135f0e 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -67,6 +67,14 @@ config GPIO_MALTA_FPGA_I2C
  additional drivers must be enabled in order to use the
  functionality of the device.
 
+config GPIO_MPC8XXX
+   bool "MPC512x/MPC8xxx/QorIQ GPIO support"
+   depends on ARCH_LAYERSCAPE
+   select GPIO_GENERIC
+   help
+ Say Y here if you're going to use hardware that connects to the
+ MPC512x/831x/834x/837x/8572/8610/QorIQ GPIOs.
+
 config GPIO_OMAP
def_bool ARCH_OMAP
 
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 990df01788bc..bc5c500e4d27 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_GPIO_LIBFTDI1)   += gpio-libftdi1.o
 obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o
 obj-$(CONFIG_GPIO_JZ4740)  += gpio-jz4740.o
 obj-$(CONFIG_GPIO_MALTA_FPGA_I2C) += gpio-malta-fpga-i2c.o
+obj-$(CONFIG_GPIO_MPC8XXX) += gpio-mpc8xxx.o
 obj-$(CONFIG_GPIO_ORION)   += gpio-orion.o
 obj-$(CONFIG_GPIO_OMAP)+= gpio-omap.o
 obj-$(CONFIG_GPIO_PCA953X) += gpio-pca953x.o
diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c
new file mode 100644
index ..979f92ad3023
--- /dev/null
+++ b/drivers/gpio/gpio-mpc8xxx.c
@@ -0,0 +1,122 @@
+/*
+ * GPIOs on MPC512x/8349/8572/8610/QorIQ and compatible
+ *
+ * Copyright (C) 2008 Peter Korsgaard 
+ * Copyright (C) 2016 Freescale Semiconductor Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MPC8XXX_GPIO_PINS  32
+
+#define GPIO_DIR   0x00
+#define GPIO_ODR   0x04
+#define GPIO_DAT   0x08
+#define GPIO_IER   0x0c
+#define GPIO_IMR   0x10
+
+struct mpc8xxx_gpio_chip {
+   struct bgpio_chip   bgc;
+   void __iomem*regs;
+};
+
+struct mpc8xxx_gpio_devtype {
+   int (*gpio_dir_out)(struct bgpio_chip *, unsigned int, int);
+   int (*gpio_get)(struct bgpio_chip *, unsigned int);
+};
+
+static int mpc8xxx_probe(struct device_d *dev)
+{
+   struct device_node *np;
+   struct resource *iores;
+   struct mpc8xxx_gpio_chip *mpc8xxx_gc;
+   struct bgpio_chip *bgc;
+   int ret;
+
+   mpc8xxx_gc = xzalloc(sizeof(*mpc8xxx_gc));
+
+   if (dev->device_node) {
+   np = dev->device_node;
+   } else {
+   dev_err(dev, "no device_node\n");
+   return -ENODEV;
+}
+
+   iores = dev_request_mem_resource(dev, 0);
+   if (IS_ERR(iores))
+   return PTR_ERR(iores);
+
+   mpc8xxx_gc->regs = IOMEM(iores->start);
+   if (!mpc8xxx_gc->regs)
+   return -ENOMEM;
+
+bgc = _gc->bgc;
+
+   if (of_property_read_bool(np, "little-endian")) {
+   ret = bgpio_init(bgc, dev, 4,
+mpc8xxx_gc->regs + GPIO_DAT,
+NULL, NULL,
+mpc8xxx_gc->regs + GPIO_DIR, NULL, 0);
+   if (ret)
+   goto err;
+   dev_dbg(dev, "GPIO registers are LITTLE endian\n");
+   } else {
+   ret = bgpio_init(bgc, dev, 4,
+mpc8xxx_gc->regs + GPIO_DAT,
+NULL, NULL,
+mpc8xxx_gc->regs + GPIO_DIR, NULL,
+BGPIOF_BIG_ENDIAN);
+   if (ret)
+   goto err;
+   dev_dbg(dev, "GPIO registers are BIG endian\n");
+   }
+
+   ret = gpiochip_add(_gc->bgc.gc);
+   if (ret) {
+   pr_err("%pOF: GPIO chip registration failed with status %d\n",
+  np, ret);
+   goto err;
+   }
+
+   /* ack and mask all irqs */
+   bgc->write_reg(mpc8xxx_gc->regs + GPIO_IER, 0x);
+   bgc->write_reg(mpc8xxx_gc->regs + GPIO_IMR, 0);
+
+   return 0;
+
+err:
+   return ret;
+}
+
+static __maybe_unused struct of_device_id mpc8xxx_gpio_ids[] = {
+   {
+   .compatible = "fsl,qoriq-gpio",
+   },
+   {
+   /* sentinel */
+   },
+};
+

[PATCH 1/6] barebox-wrapper: add IRQ_WAKE_THREAD

2019-09-16 Thread Steffen Trumtrar
Add a new irqreturn_t IRQ_WAKE_THREAD.

Signed-off-by: Steffen Trumtrar 
---
 include/linux/barebox-wrapper.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/barebox-wrapper.h b/include/linux/barebox-wrapper.h
index e998932d1201..fee02d052d94 100644
--- a/include/linux/barebox-wrapper.h
+++ b/include/linux/barebox-wrapper.h
@@ -45,6 +45,7 @@ static inline void vfree(const void *addr)
 typedef int irqreturn_t;
 #define IRQ_NONE 0
 #define IRQ_HANDLED 0
+#define IRQ_WAKE_THREAD 2
 
 /* To ease clk drivers porting from Linux kernel */
 #define __clk_get_name(clk)(clk->name)
-- 
2.23.0


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


[PATCH 6/6] ARM: Layerscape: LS1046a: configure USB ports

2019-09-16 Thread Steffen Trumtrar
The LS1046a has three USB ports:
 - 2 USB Host ports
 - 1 USB Device port

Signed-off-by: Steffen Trumtrar 
---
 arch/arm/dts/fsl-ls1046a-rdb.dts | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm/dts/fsl-ls1046a-rdb.dts b/arch/arm/dts/fsl-ls1046a-rdb.dts
index e16948bc8a51..bb5eebcb370a 100644
--- a/arch/arm/dts/fsl-ls1046a-rdb.dts
+++ b/arch/arm/dts/fsl-ls1046a-rdb.dts
@@ -96,3 +96,17 @@
status = "disabled";
};
 };
+
+ {
+   dr_mode = "host";
+};
+
+ {
+   maximum-speed = "high-speed";
+   dr_mode = "peripheral";
+   status = "okay";
+};
+
+ {
+   dr_mode = "host";
+};
-- 
2.23.0


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


[PATCH 3/6] usb/ch9.h: add USB 3.1 isoc endpoint define

2019-09-16 Thread Steffen Trumtrar
Add a new define for USB 3.1 endpoints

Signed-off-by: Steffen Trumtrar 
---
 include/usb/ch9.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/usb/ch9.h b/include/usb/ch9.h
index 89d83e0d09be..85f3e64cac2b 100644
--- a/include/usb/ch9.h
+++ b/include/usb/ch9.h
@@ -234,6 +234,8 @@ struct usb_ctrlrequest {
 #define USB_DT_PIPE_USAGE  0x24
 /* From the USB 3.0 spec */
 #defineUSB_DT_SS_ENDPOINT_COMP 0x30
+/* From the USB 3.1 spec */
+#defineUSB_DT_SSP_ISOC_ENDPOINT_COMP   0x31
 
 /* Conventional codes for class-specific descriptors.  The convention is
  * defined in the USB "Common Class" Spec (3.11).  Individual class specs
-- 
2.23.0


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


[PATCH 5/6] usb: gadget: composite: conditionally dequeue setup requests

2019-09-16 Thread Steffen Trumtrar
From: Sascha Hauer 

This is an adoption of Kernel commit a7c12eaf2 ("usb: gadget: composite:
conditionally dequeue os_desc and setup requests"). Basically we only
want to dequeue ep0 requests when they are actually queued. Drivers like
dwc3 warn when unqueued requests are being tried to unqueued.

Signed-off-by: Sascha Hauer 
---
 drivers/usb/gadget/composite.c | 43 +++---
 include/usb/composite.h|  3 +++
 2 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 1cfc49d1c5de..b66aa6be9770 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -1194,10 +1194,45 @@ EXPORT_SYMBOL_GPL(usb_string_ids_n);
 
 static void composite_setup_complete(struct usb_ep *ep, struct usb_request 
*req)
 {
+   struct usb_composite_dev *cdev;
+
if (req->status || req->actual != req->length)
DBG((struct usb_composite_dev *) ep->driver_data,
"setup complete --> %d, %d/%d\n",
req->status, req->actual, req->length);
+
+   /*
+* REVIST The same ep0 requests are shared with function drivers
+* so they don't have to maintain the same ->complete() stubs.
+*
+* Because of that, we need to check for the validity of ->context
+* here, even though we know we've set it to something useful.
+*/
+   if (!req->context)
+   return;
+
+   cdev = req->context;
+
+   if (cdev->req == req)
+   cdev->setup_pending = false;
+   else
+   WARN(1, "unknown request %p\n", req);
+}
+
+static int composite_ep0_queue(struct usb_composite_dev *cdev,
+   struct usb_request *req)
+{
+   int ret;
+
+   ret = usb_ep_queue(cdev->gadget->ep0, req);
+   if (ret == 0) {
+   if (cdev->req == req)
+   cdev->setup_pending = true;
+   else
+   WARN(1, "unknown request %p\n", req);
+   }
+
+   return ret;
 }
 
 /*
@@ -1226,6 +1261,7 @@ composite_setup(struct usb_gadget *gadget, const struct 
usb_ctrlrequest *ctrl)
 * when we delegate to it.
 */
req->zero = 0;
+   req->context = cdev;
req->complete = composite_setup_complete;
req->length = 0;
gadget->ep0->driver_data = cdev;
@@ -1469,7 +1505,7 @@ unknown:
if (value >= 0 && value != USB_GADGET_DELAYED_STATUS) {
req->length = value;
req->zero = value < w_length;
-   value = usb_ep_queue(gadget->ep0, req);
+   value = composite_ep0_queue(cdev, req);
if (value < 0) {
DBG(cdev, "ep_queue --> %d\n", value);
req->status = 0;
@@ -1621,7 +1657,8 @@ void composite_dev_cleanup(struct usb_composite_dev *cdev)
kfree(uc);
}
if (cdev->req) {
-   usb_ep_dequeue(cdev->gadget->ep0, cdev->req);
+   if (cdev->setup_pending)
+   usb_ep_dequeue(cdev->gadget->ep0, cdev->req);
kfree(cdev->req->buf);
usb_ep_free_request(cdev->gadget->ep0, cdev->req);
}
@@ -1753,7 +1790,7 @@ void usb_composite_setup_continue(struct 
usb_composite_dev *cdev)
} else if (--cdev->delayed_status == 0) {
DBG(cdev, "%s: Completing delayed status\n", __func__);
req->length = 0;
-   value = usb_ep_queue(cdev->gadget->ep0, req);
+   value = composite_ep0_queue(cdev, req);
if (value < 0) {
DBG(cdev, "ep_queue --> %d\n", value);
req->status = 0;
diff --git a/include/usb/composite.h b/include/usb/composite.h
index f30568a54f32..ec9abe74472a 100644
--- a/include/usb/composite.h
+++ b/include/usb/composite.h
@@ -395,6 +395,9 @@ struct usb_composite_dev {
spinlock_t  lock;
 
int in_reset_config;
+
+   /* public: */
+   unsigned intsetup_pending:1;
 };
 
 extern int usb_string_id(struct usb_composite_dev *c);
-- 
2.23.0


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


[PATCH 2/6] usb: gadget: add usb_gadget_udc_reset function

2019-09-16 Thread Steffen Trumtrar
Add a function to notify the udc core, that a bus reset occured.

Signed-off-by: Steffen Trumtrar 
---
 drivers/usb/gadget/udc-core.c | 15 +++
 include/usb/gadget.h  |  4 
 2 files changed, 19 insertions(+)

diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c
index e357456098ae..096f05ed48df 100644
--- a/drivers/usb/gadget/udc-core.c
+++ b/drivers/usb/gadget/udc-core.c
@@ -108,6 +108,21 @@ void usb_gadget_set_state(struct usb_gadget *gadget,
 }
 EXPORT_SYMBOL_GPL(usb_gadget_set_state);
 
+/**
+ * usb_gadget_udc_reset - notifies the udc core that bus reset occurs
+ * @gadget: The gadget which bus reset occurs
+ * @driver: The gadget driver we want to notify
+ *
+ * If the udc driver has bus reset handler, it needs to call this when the bus
+ * reset occurs, it notifies the gadget driver that the bus reset occurs as
+ * well as updates gadget state.
+ */
+void usb_gadget_udc_reset(struct usb_gadget *gadget,
+   struct usb_gadget_driver *driver)
+{
+   usb_gadget_set_state(gadget, USB_STATE_DEFAULT);
+}
+EXPORT_SYMBOL_GPL(usb_gadget_udc_reset);
 /* - */
 
 /**
diff --git a/include/usb/gadget.h b/include/usb/gadget.h
index 80418a9cd447..afa11b2d9d8a 100644
--- a/include/usb/gadget.h
+++ b/include/usb/gadget.h
@@ -1018,6 +1018,10 @@ extern void usb_gadget_set_state(struct usb_gadget 
*gadget,
 
 /*-*/
 
+/* utility to tell udc core that the bus reset occurs */
+extern void usb_gadget_udc_reset(struct usb_gadget *gadget,
+struct usb_gadget_driver *driver);
+
 /* utility wrapping a simple endpoint selection policy */
 
 extern struct usb_ep *usb_ep_autoconfig(struct usb_gadget *,
-- 
2.23.0


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


[PATCH 4/6] usb: dwc3: add support for gadget mode

2019-09-16 Thread Steffen Trumtrar
Expand the DWC3 usb core with gadget support.
Patches imported and adopted from Linux v5.2.

Signed-off-by: Steffen Trumtrar 
---
 drivers/usb/dwc3/Kconfig  |   29 +-
 drivers/usb/dwc3/Makefile |7 +-
 drivers/usb/dwc3/core.c   |  450 -
 drivers/usb/dwc3/core.h   |  181 +-
 drivers/usb/dwc3/dwc3-of-simple.c |  122 ++
 drivers/usb/dwc3/ep0.c| 1183 +++
 drivers/usb/dwc3/gadget.c | 3015 +
 drivers/usb/dwc3/gadget.h |  127 ++
 8 files changed, 5094 insertions(+), 20 deletions(-)
 create mode 100644 drivers/usb/dwc3/dwc3-of-simple.c
 create mode 100644 drivers/usb/dwc3/ep0.c
 create mode 100644 drivers/usb/dwc3/gadget.c
 create mode 100644 drivers/usb/dwc3/gadget.h

diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index c91fd36a9532..09da1213744d 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -2,8 +2,6 @@ config USB_DWC3
tristate "DesignWare USB3 DRD Core Support"
depends on USB && HAS_DMA
select USB_XHCI
-   select USB_DWC3_HOST# Remove this once we support more
-   # than USB host
help
  Say Y or M here if your system has a Dual Role SuperSpeed
  USB controller based on the DesignWare USB3 IP Core.
@@ -13,10 +11,37 @@ config USB_DWC3
 
 if USB_DWC3
 
+choice
+   bool "DWC3 Mode Selection"
+
 config USB_DWC3_HOST
bool "Host only mode"
help
  Select this when you want to use DWC3 in host mode only,
  thereby the gadget feature will be regressed.
 
+config USB_DWC3_GADGET
+   bool "Gadget only mode"
+   depends on USB_GADGET
+   help
+ Select this when you want to use DWC3 in gadget mode only,
+ thereby the host feature will be regressed.
+
+config USB_DWC3_DUAL_ROLE
+   bool "Dual Role mode"
+   help
+ This is the default mode of working of DWC3 controller where
+ both host and gadget features are enabled.
+
+endchoice
+
+config USB_DWC3_OF_SIMPLE
+   tristate "Generic OF Simple Glue Layer"
+   depends on COMMON_CLK
+   default USB_DWC3
+   help
+Support USB2/3 functionality in simple SoC integrations.
+Currently supports Xilinx and Qualcomm DWC USB3 IP.
+Say 'Y' or 'M' if you have one such device.
+
 endif
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
index d43b23eb2d92..d0c812c883df 100644
--- a/drivers/usb/dwc3/Makefile
+++ b/drivers/usb/dwc3/Makefile
@@ -4,7 +4,12 @@ obj-$(CONFIG_USB_DWC3) += dwc3.o
 
 dwc3-y := core.o
 
-ifneq ($(filter y,$(CONFIG_USB_DWC3_HOST)),)
+ifneq ($(filter y,$(CONFIG_USB_DWC3_HOST) $(CONFIG_USB_DWC3_DUAL_ROLE)),)
dwc3-y  += host.o
 endif
 
+ifneq ($(filter y,$(CONFIG_USB_DWC3_GADGET) $(CONFIG_USB_DWC3_DUAL_ROLE)),)
+   dwc3-y  += gadget.o ep0.o
+endif
+
+obj-$(CONFIG_USB_DWC3_OF_SIMPLE)   += dwc3-of-simple.o
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 60fd6318db8e..d3f9d9ef270c 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -11,15 +11,77 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
+#include "gadget.h"
 #include "core.h"
 #include "io.h"
 
 
 #define DWC3_DEFAULT_AUTOSUSPEND_DELAY 5000 /* ms */
 
+/**
+ * dwc3_get_dr_mode - Validates and sets dr_mode
+ * @dwc: pointer to our context structure
+ */
+static int dwc3_get_dr_mode(struct dwc3 *dwc)
+{
+   enum usb_dr_mode mode;
+   struct device_d *dev = dwc->dev;
+   unsigned int hw_mode;
+
+   if (dwc->dr_mode == USB_DR_MODE_UNKNOWN)
+   dwc->dr_mode = USB_DR_MODE_OTG;
+
+   mode = dwc->dr_mode;
+   hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0);
+
+   switch (hw_mode) {
+   case DWC3_GHWPARAMS0_MODE_GADGET:
+   if (IS_ENABLED(CONFIG_USB_DWC3_HOST)) {
+   dev_err(dev,
+   "Controller does not support host mode.\n");
+   return -EINVAL;
+   }
+   mode = USB_DR_MODE_PERIPHERAL;
+   break;
+   case DWC3_GHWPARAMS0_MODE_HOST:
+   if (IS_ENABLED(CONFIG_USB_DWC3_GADGET)) {
+   dev_err(dev,
+   "Controller does not support device mode.\n");
+   return -EINVAL;
+   }
+   mode = USB_DR_MODE_HOST;
+   break;
+   default:
+   if (IS_ENABLED(CONFIG_USB_DWC3_HOST))
+   mode = USB_DR_MODE_HOST;
+   else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET))
+   mode = USB_DR_MODE_PERIPHERAL;
+
+   /*
+

[PATCH 1/2] imd: add support for checksum generation/verification

2019-12-03 Thread Steffen Trumtrar
Add a new imd type "checksum". This type consists of the CRC32 checksum
of the whole barebox image minus the checksum itself.
The checksum can be written to the imd field with the bareboximd host-tool.
It can be verified with said tool or with "imd" on the target.

Signed-off-by: Steffen Trumtrar 
---
 commands/imd.c   |   1 +
 common/imd-barebox.c |   1 +
 common/imd.c | 115 ++-
 include/image-metadata.h |  17 ++
 scripts/bareboximd.c |  32 +++
 5 files changed, 165 insertions(+), 1 deletion(-)

diff --git a/commands/imd.c b/commands/imd.c
index f1a22cef96bd..16ab7290c920 100644
--- a/commands/imd.c
+++ b/commands/imd.c
@@ -46,6 +46,7 @@ BAREBOX_CMD_HELP_TEXT("Options:")
 BAREBOX_CMD_HELP_OPT ("-t ", "only show information of ")
 BAREBOX_CMD_HELP_OPT ("-n ", "for tags with multiple strings only show 
string ")
 BAREBOX_CMD_HELP_OPT ("-s VARNAME",  "set variable VARNAME instead of showing 
information")
+BAREBOX_CMD_HELP_OPT ("-V",  "Verify checksum of image")
 BAREBOX_CMD_HELP_TEXT("")
 BAREBOX_CMD_HELP_TEXT("Without options all information available is printed. 
Valid types are:")
 BAREBOX_CMD_HELP_TEXT("release, build, model, of_compatible")
diff --git a/common/imd-barebox.c b/common/imd-barebox.c
index e9cd37d83ec8..4aec51bfbdc2 100644
--- a/common/imd-barebox.c
+++ b/common/imd-barebox.c
@@ -23,3 +23,4 @@ __BAREBOX_IMD_SECTION(.barebox_imd_end) = {
 
 BAREBOX_IMD_TAG_STRING(imd_build_tag, IMD_TYPE_BUILD, UTS_VERSION, 1);
 BAREBOX_IMD_TAG_STRING(imd_release_tag, IMD_TYPE_RELEASE, UTS_RELEASE, 1);
+BAREBOX_IMD_CRC(imd_checksum, 0x0, 1);
diff --git a/common/imd.c b/common/imd.c
index 913a01de87bf..c62507f0ad5d 100644
--- a/common/imd.c
+++ b/common/imd.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #ifndef CONFIG_CMD_IMD
 int imd_command_setenv(const char *variable_name, const char *value)
@@ -167,6 +168,9 @@ static struct imd_type_names imd_types[] = {
}, {
.type = IMD_TYPE_OF_COMPATIBLE,
.name = "of_compatible",
+   }, {
+   .type = IMD_TYPE_CHECKSUM,
+   .name = "checksum",
},
 };
 
@@ -287,6 +291,102 @@ const char *imd_get_param(const struct imd_header *imd, 
const char *name)
return NULL;
 }
 
+static int imd_calculate_crc32(void *input, const struct imd_header *imd_start,
+   const struct imd_header **imd_crc, uint32_t *crc,
+   size_t size)
+{
+   int length;
+   const struct imd_header *imd;
+   int end_ofs = (char *)imd_start - (char *)input + sizeof(char) * 8;
+
+   *crc = crc32(*crc, input, end_ofs);
+   debug("Calculated checksum from %d to %d: 0x%08x\n", 0, end_ofs, *crc);
+
+   input += end_ofs;
+
+   imd_for_each(imd_start, imd) {
+   length = imd_read_length(imd);
+   length = ALIGN(length, 4);
+   length += 8;
+
+   if (imd_read_type(imd) != IMD_TYPE_CHECKSUM) {
+   *crc = crc32(*crc, input, length);
+   debug("Calculated checksum from %d to %d: 0x%08x\n",
+ end_ofs, end_ofs + length, *crc);
+   } else {
+   *imd_crc = imd;
+   }
+
+   end_ofs += length;
+   input += length;
+   }
+
+   *crc = crc32(*crc, input, size - end_ofs);
+   debug("Calculated checksum from %d to %d: 0x%08x\n", end_ofs,
+ end_ofs + (size - end_ofs), *crc);
+
+   return 0;
+}
+
+static int imd_write_crc32(void *buf, const struct imd_header *imd_start,
+   const char *filename, size_t size)
+{
+   const struct imd_header *imd_crc;
+   uint32_t crc = 0;
+
+   imd_calculate_crc32(buf, imd_start, _crc, , size);
+   debug("Calculated crc: 0x%08x\n", crc);
+
+   if (!imd_crc) {
+   debug("No tag of type 0x%08x found\n", IMD_TYPE_CHECKSUM);
+
+   return -ENODATA;
+   } else {
+   uint32_t *p = (uint32_t *)(imd_crc + 1);
+
+   if (*p != crc) {
+   debug("Update crc 0x%08x to 0x%08x\n", *p, crc);
+   *p = crc;
+
+   write_file(filename, buf, size);
+   }
+   }
+
+   return 0;
+};
+
+int imd_verify_crc32(void *buf, size_t size)
+{
+   const struct imd_header *imd_start;
+   const struct imd_header *imd_crc;
+   uint32_t crc = 0;
+
+   imd_start = imd_get(buf, size);
+   if (IS_ERR(imd_start))
+   return PTR_ERR(imd_start);
+
+   imd_calculate_crc32(buf, imd_start, _crc, , size);
+   debug("Calculated crc: 0x%08x\n", crc);
+
+   

[PATCH 2/2] commands: bbu: add support for imd checksum

2019-12-03 Thread Steffen Trumtrar
Add support for verifying an image by use of the imd checksum.
If the checksum that is saved in the image and the one that is
calculated over the image differ, barebox_update aborts.

Signed-off-by: Steffen Trumtrar 
---
 commands/barebox-update.c | 9 +++--
 common/bbu.c  | 6 ++
 include/bbu.h | 1 +
 3 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/commands/barebox-update.c b/commands/barebox-update.c
index 53af2a851137..10ea4dd915cc 100644
--- a/commands/barebox-update.c
+++ b/commands/barebox-update.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 
 static void print_handlers_list(void)
 {
@@ -39,7 +40,7 @@ static int do_barebox_update(int argc, char *argv[])
const char *name;
const char *fmt;
 
-   while ((opt = getopt(argc, argv, "t:yf:ld:r")) > 0) {
+   while ((opt = getopt(argc, argv, "t:yf:ld:rV")) > 0) {
switch (opt) {
case 'd':
data.devicefile = optarg;
@@ -60,6 +61,9 @@ static int do_barebox_update(int argc, char *argv[])
case 'r':
repair = 1;
break;
+   case 'V':
+   data.flags |= BBU_FLAG_VERIFY;
+   break;
default:
return COMMAND_ERROR_USAGE;
}
@@ -119,12 +123,13 @@ BAREBOX_CMD_HELP_OPT("-d DEVICE", "write image to DEVICE")
 BAREBOX_CMD_HELP_OPT("-r\t", "refresh or repair. Do not update, but repair an 
existing image")
 BAREBOX_CMD_HELP_OPT("-y\t", "autom. use 'yes' when asking confirmations")
 BAREBOX_CMD_HELP_OPT("-f LEVEL", "set force level")
+BAREBOX_CMD_HELP_OPT("-V\t", "Validate checksum of image")
 BAREBOX_CMD_HELP_END
 
 BAREBOX_CMD_START(barebox_update)
.cmd= do_barebox_update,
BAREBOX_CMD_DESC("update barebox to persistent media")
-   BAREBOX_CMD_OPTS("[-ltdyfr] [IMAGE]")
+   BAREBOX_CMD_OPTS("[-ltdyfrV] [IMAGE]")
BAREBOX_CMD_GROUP(CMD_GRP_MISC)
BAREBOX_CMD_HELP(cmd_barebox_update_help)
 BAREBOX_CMD_END
diff --git a/common/bbu.c b/common/bbu.c
index 00bec32a860a..4bca4b598c4c 100644
--- a/common/bbu.c
+++ b/common/bbu.c
@@ -206,6 +206,12 @@ static int bbu_check_metadata(struct bbu_data *data)
if (ret)
return ret;
 
+   if (data->flags & BBU_FLAG_VERIFY) {
+   ret = imd_verify_crc32((void *)data->image, data->len);
+   if (ret)
+   return ret;
+   }
+
return 0;
 }
 
diff --git a/include/bbu.h b/include/bbu.h
index 9da6785d2e67..56c61093bba2 100644
--- a/include/bbu.h
+++ b/include/bbu.h
@@ -9,6 +9,7 @@
 struct bbu_data {
 #define BBU_FLAG_FORCE (1 << 0)
 #define BBU_FLAG_YES   (1 << 1)
+#define BBU_FLAG_VERIFY(1 << 2)
unsigned long flags;
int force;
const void *image;
-- 
2.24.0


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


[PATCH v2 3/4] imd: add support for checksum generation/verification

2019-12-09 Thread Steffen Trumtrar
Add a new imd type "checksum". This type consists of the CRC32 checksum
of the whole barebox image minus the checksum itself.
The checksum can be written to the imd field with the bareboximd host-tool.
It can be verified with said tool or with "imd" on the target.

Signed-off-by: Steffen Trumtrar 
---
Changes since V1:
  - add some comments
  - change the crc32 calculation over the image for better readability

 commands/imd.c   |   1 +
 common/imd-barebox.c |   1 +
 common/imd.c | 135 ++-
 include/image-metadata.h |  22 +++
 scripts/bareboximd.c |  32 ++
 5 files changed, 190 insertions(+), 1 deletion(-)

diff --git a/commands/imd.c b/commands/imd.c
index f1a22cef96bd..16ab7290c920 100644
--- a/commands/imd.c
+++ b/commands/imd.c
@@ -46,6 +46,7 @@ BAREBOX_CMD_HELP_TEXT("Options:")
 BAREBOX_CMD_HELP_OPT ("-t ", "only show information of ")
 BAREBOX_CMD_HELP_OPT ("-n ", "for tags with multiple strings only show 
string ")
 BAREBOX_CMD_HELP_OPT ("-s VARNAME",  "set variable VARNAME instead of showing 
information")
+BAREBOX_CMD_HELP_OPT ("-V",  "Verify checksum of image")
 BAREBOX_CMD_HELP_TEXT("")
 BAREBOX_CMD_HELP_TEXT("Without options all information available is printed. 
Valid types are:")
 BAREBOX_CMD_HELP_TEXT("release, build, model, of_compatible")
diff --git a/common/imd-barebox.c b/common/imd-barebox.c
index e9cd37d83ec8..4aec51bfbdc2 100644
--- a/common/imd-barebox.c
+++ b/common/imd-barebox.c
@@ -23,3 +23,4 @@ __BAREBOX_IMD_SECTION(.barebox_imd_end) = {
 
 BAREBOX_IMD_TAG_STRING(imd_build_tag, IMD_TYPE_BUILD, UTS_VERSION, 1);
 BAREBOX_IMD_TAG_STRING(imd_release_tag, IMD_TYPE_RELEASE, UTS_RELEASE, 1);
+BAREBOX_IMD_CRC(imd_checksum, 0x0, 1);
diff --git a/common/imd.c b/common/imd.c
index e0dab69644c0..280d055d2bab 100644
--- a/common/imd.c
+++ b/common/imd.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #ifndef CONFIG_CMD_IMD
 int imd_command_setenv(const char *variable_name, const char *value)
@@ -167,6 +168,9 @@ static struct imd_type_names imd_types[] = {
}, {
.type = IMD_TYPE_OF_COMPATIBLE,
.name = "of_compatible",
+   }, {
+   .type = IMD_TYPE_CHECKSUM,
+   .name = "checksum",
},
 };
 
@@ -287,6 +291,118 @@ const char *imd_get_param(const struct imd_header *imd, 
const char *name)
return NULL;
 }
 
+static int imd_calculate_crc32(void *input, const struct imd_header *imd_start,
+  struct imd_header **imd_crc, uint32_t *crc,
+  size_t size)
+{
+   const struct imd_header *imd;
+   int length;
+   int end_ofs = (char *)imd_start - (char *)input + sizeof(char) * 8;
+
+   /* search the checksum imd token */
+   imd_for_each(imd_start, imd) {
+   length = imd_read_length(imd);
+   length = ALIGN(length, 4);
+   length += sizeof(struct imd_header);
+
+   if (imd_read_type(imd) == IMD_TYPE_CHECKSUM) {
+   *imd_crc = (struct imd_header *)imd;
+   debug("Found crc token at %d\n", end_ofs);
+   break;
+   }
+
+   end_ofs += length;
+   }
+
+   /*
+* Calculate checksum from start of input up to the checksum.
+* The checksum and the flags field in the header are modified
+* after the checksum is calculated. Therefore skip them here
+* or the checksum will become invalid once it is written to the
+* checksum tag.
+*/
+   length = imd_read_length(*imd_crc);
+   length = ALIGN(length, 4);
+   length += sizeof(struct imd_header) - sizeof(uint32_t);
+   end_ofs += length;
+
+   *crc = crc32(*crc, input, end_ofs);
+   debug("Calculated checksum from %d to %d: 0x%08x\n", 0, end_ofs, *crc);
+
+   /* move past the imd_header flags and the actual checksum data field */
+   end_ofs += sizeof(uint32_t) + sizeof(uint32_t);
+   input += end_ofs;
+
+   *crc = crc32(*crc, input, size - end_ofs);
+   debug("Calculated checksum from %d to %d: 0x%08x\n", end_ofs,
+ end_ofs + (size - end_ofs), *crc);
+
+   return 0;
+}
+
+static int imd_write_crc32(void *buf, const struct imd_header *imd_start,
+  const char *filename, size_t size)
+{
+   struct imd_header *imd_crc;
+   uint32_t crc = 0;
+
+   imd_calculate_crc32(buf, imd_start, _crc, , size);
+   debug("Calculated crc: 0x%08x\n", crc);
+
+   if (!imd_crc) {
+   debug("No tag of type 0x%08x found\n", IMD_TYPE_CHECKSUM);
+
+   return -ENODATA;
+   } else {
+   uint32_t *

[PATCH v2 4/4] commands: bbu: add support for imd checksum

2019-12-09 Thread Steffen Trumtrar
Add support for verifying an image by use of the imd checksum.
If the checksum that is saved in the image and the one that is
calculated over the image differ, barebox_update aborts.

Signed-off-by: Steffen Trumtrar 
---
 common/bbu.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/common/bbu.c b/common/bbu.c
index 00bec32a860a..b976b99d7c95 100644
--- a/common/bbu.c
+++ b/common/bbu.c
@@ -206,6 +206,10 @@ static int bbu_check_metadata(struct bbu_data *data)
if (ret)
return ret;
 
+   ret = imd_verify_crc32((void *)data->image, data->len);
+   if (ret == -EILSEQ && !(data->flags & BBU_FLAG_FORCE))
+   return ret;
+
return 0;
 }
 
-- 
2.24.0


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


[PATCH v2 1/4] imd: replace magicvalue with sizeof(struct)

2019-12-09 Thread Steffen Trumtrar
Instead of using "8" as the size of an imd_header, use the sizeof operator.

Signed-off-by: Steffen Trumtrar 
---
 common/imd.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/common/imd.c b/common/imd.c
index 913a01de87bf..e0dab69644c0 100644
--- a/common/imd.c
+++ b/common/imd.c
@@ -41,7 +41,7 @@ const struct imd_header *imd_next(const struct imd_header 
*imd)
 
length = imd_read_length(imd);
length = ALIGN(length, 4);
-   length += 8;
+   length += sizeof(struct imd_header);
 
return (const void *)imd + length;
 }
@@ -63,14 +63,14 @@ static int imd_next_validate(const void *buf, int bufsize, 
int start_ofs)
 
size = bufsize - start_ofs;
 
-   if (size < 8) {
+   if (size < sizeof(struct imd_header)) {
debug("trunkated tag at offset %dd\n", start_ofs);
return -EINVAL;
}
 
length = imd_read_length(imd);
length = ALIGN(length, 4);
-   length += 8;
+   length += sizeof(struct imd_header);
 
if (size < length) {
debug("tag at offset %d with size %d exceeds bufsize %d\n",
-- 
2.24.0


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


[PATCH v2 2/4] image-metadata: add flags field to imd_header

2019-12-09 Thread Steffen Trumtrar
To allow marking an imd tag with properties, add a flags field to the 
imd_header.

Signed-off-by: Steffen Trumtrar 
---
 include/image-metadata.h | 13 +
 1 file changed, 13 insertions(+)

diff --git a/include/image-metadata.h b/include/image-metadata.h
index 5904d95acd37..ca73e6cf6ec6 100644
--- a/include/image-metadata.h
+++ b/include/image-metadata.h
@@ -28,6 +28,8 @@
 #define IMD_TYPE_END   0x640c7fff
 #define IMD_TYPE_INVALID   0x
 
+#define IMD_FLAG_TAG_VALID (1 << 0)
+
 /*
  * The IMD header. All data is stored in little endian format in the image.
  * The next header starts at the next 4 byte boundary after the data.
@@ -35,6 +37,7 @@
 struct imd_header {
uint32_t type;  /* One of IMD_TYPE_* above */
uint32_t datalength;/* Length of the data (exluding the header) */
+   uint32_t flags;
 };
 
 /*
@@ -51,6 +54,11 @@ static inline int imd_is_string(uint32_t type)
return (type & 0x8000) ? 1 : 0;
 }
 
+static inline int imd_tag_is_valid(uint32_t flags)
+{
+   return (flags & IMD_FLAG_TAG_VALID) ? 1 : 0;
+}
+
 static inline int imd_type_valid(uint32_t type)
 {
return (type & 0x) == 0x640c;
@@ -78,6 +86,11 @@ static inline uint32_t imd_read_length(const struct 
imd_header *imd)
return imd_read_le32(>datalength);
 }
 
+static inline uint32_t imd_read_flags(const struct imd_header *imd)
+{
+   return imd_read_le32(>flags);
+}
+
 const struct imd_header *imd_find_type(const struct imd_header *imd,
   uint32_t type);
 
-- 
2.24.0


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


[PATCH 3/3] ARM: socfpga: arria10-xload: fix Wmissing-prototypes

2019-10-17 Thread Steffen Trumtrar
Fix the warning:

arch/arm/mach-socfpga/arria10-xload.c:17:5: warning: no previous prototype for
'a10_update_bits' [-Wmissing-prototypes]
   17 | int a10_update_bits(unsigned int reg, unsigned int mask,
  | ^~~

Signed-off-by: Steffen Trumtrar 
---
 arch/arm/mach-socfpga/include/mach/arria10-xload.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-socfpga/include/mach/arria10-xload.h 
b/arch/arm/mach-socfpga/include/mach/arria10-xload.h
index 71f839736230..7575231bbf34 100644
--- a/arch/arm/mach-socfpga/include/mach/arria10-xload.h
+++ b/arch/arm/mach-socfpga/include/mach/arria10-xload.h
@@ -4,6 +4,7 @@
 void arria10_init_mmc(void);
 int arria10_prepare_mmc(int barebox_part, int rbf_part);
 int arria10_read_blocks(void *dst, int blocknum, size_t len);
+int a10_update_bits(unsigned int reg, unsigned int mask, unsigned int val);
 
 struct partition {
uint64_t first_sec;
-- 
2.23.0


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


[PATCH 1/3] ARM: socfpga: reset-manager: fix Wmissing-prototypes

2019-10-17 Thread Steffen Trumtrar
Fix the following warnings

arch/arm/mach-socfpga/arria10-reset-manager.c:152:6: warning: no previous 
prototype for
'arria10_reset_deassert_shared_peripherals_q1' [-Wmissing-prototypes]
  152 | void arria10_reset_deassert_shared_peripherals_q1(uint32_t *mask0,
  |  ^~~~
arch/arm/mach-socfpga/arria10-reset-manager.c:226:6: warning: no previous 
prototype for
'arria10_reset_deassert_shared_peripherals_q2' [-Wmissing-prototypes]
  226 | void arria10_reset_deassert_shared_peripherals_q2(uint32_t *mask0,
  |  ^~~~
arch/arm/mach-socfpga/arria10-reset-manager.c:272:6: warning: no previous 
prototype for
'arria10_reset_deassert_shared_peripherals_q3' [-Wmissing-prototypes]
  272 | void arria10_reset_deassert_shared_peripherals_q3(uint32_t *mask0,
  |  ^~~~
arch/arm/mach-socfpga/arria10-reset-manager.c:329:6: warning: no previous 
prototype for
'arria10_reset_deassert_shared_peripherals_q4' [-Wmissing-prototypes]
  329 | void arria10_reset_deassert_shared_peripherals_q4(uint32_t *mask0, 
uint32_t *mask1)
  |  ^~~~

Signed-off-by: Steffen Trumtrar 
---
 arch/arm/mach-socfpga/include/mach/arria10-reset-manager.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/mach-socfpga/include/mach/arria10-reset-manager.h 
b/arch/arm/mach-socfpga/include/mach/arria10-reset-manager.h
index ebd20434263a..2033de77a39f 100644
--- a/arch/arm/mach-socfpga/include/mach/arria10-reset-manager.h
+++ b/arch/arm/mach-socfpga/include/mach/arria10-reset-manager.h
@@ -108,6 +108,10 @@
 void arria10_reset_peripherals(void);
 void arria10_reset_deassert_dedicated_peripherals(void);
 void arria10_reset_deassert_shared_peripherals(void);
+void arria10_reset_deassert_shared_peripherals_q1(uint32_t *mask0, uint32_t 
*mask1);
+void arria10_reset_deassert_shared_peripherals_q2(uint32_t *mask0, uint32_t 
*mask1);
+void arria10_reset_deassert_shared_peripherals_q3(uint32_t *mask0, uint32_t 
*mask1);
+void arria10_reset_deassert_shared_peripherals_q4(uint32_t *mask0, uint32_t 
*mask1);
 void arria10_reset_deassert_fpga_peripherals(void);
 
 #endif
-- 
2.23.0


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


[PATCH 2/3] ARM: socfpga: clock-manager: fix Wmissing-prototypes

2019-10-17 Thread Steffen Trumtrar
Fix the warning

arch/arm/mach-socfpga/arria10-clock-manager.c:113:14: warning: no previous 
prototype for
'arria10_cm_get_mmc_controller_clk_hz' [-Wmissing-prototypes]
  113 | unsigned int arria10_cm_get_mmc_controller_clk_hz(void)
  |  ^~~~

Signed-off-by: Steffen Trumtrar 
---
 arch/arm/mach-socfpga/include/mach/arria10-clock-manager.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-socfpga/include/mach/arria10-clock-manager.h 
b/arch/arm/mach-socfpga/include/mach/arria10-clock-manager.h
index ee2b9b3c5ec1..c0a57439af0d 100644
--- a/arch/arm/mach-socfpga/include/mach/arria10-clock-manager.h
+++ b/arch/arm/mach-socfpga/include/mach/arria10-clock-manager.h
@@ -128,6 +128,7 @@ struct arria10_perpll_cfg {
 
 extern int arria10_cm_basic_init(struct arria10_mainpll_cfg *mainpll_cfg,
 struct arria10_perpll_cfg *perpll_cfg);
+unsigned int arria10_cm_get_mmc_controller_clk_hz(void);
 extern unsigned int cm_get_mmc_controller_clk_hz(void);
 extern void arria10_cm_use_intosc(void);
 extern uint32_t cm_l4_main_clk_hz;
-- 
2.23.0


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


[PATCH 1/3] net: designware: socfpga: fix phy setup for Arria10

2019-10-17 Thread Steffen Trumtrar
Barebox-version of the Linux v5.2 patch:

40ae25505fe834648ce4aa70b073ee934942bfdb
net: stmmac: socfpga: fix phy and ptp_ref setup for Arria10/Stratix10

On the Arria10, Agilex, and Stratix10 SoC, there are a few differences from
the Cyclone5 and Arria5:
 - The emac PHY setup bits are in separate registers.
 - The PTP reference clock select mask is different.
 - The register to enable the emac signal from FPGA is different.

Thus, this patch creates a separate function for setting the phy modes on
Arria10/Agilex/Stratix10. The separation is based a new DTS binding:
"altr,socfpga-stmmac-a10-s10".

Signed-off-by: Dinh Nguyen 
Signed-off-by: David S. Miller 

The new DTS binding is already part of v2019.10.0 and the driver doesn't
probe on Arria10 without the new binding introduced in this patch.

Signed-off-by: Steffen Trumtrar 
---
 drivers/net/designware.h |   1 +
 drivers/net/designware_socfpga.c | 133 +++
 2 files changed, 118 insertions(+), 16 deletions(-)

diff --git a/drivers/net/designware.h b/drivers/net/designware.h
index 305f674bf064..0a6a6bf1a497 100644
--- a/drivers/net/designware.h
+++ b/drivers/net/designware.h
@@ -35,6 +35,7 @@ struct dw_eth_dev {
 
 struct dw_eth_drvdata {
bool enh_desc;
+   void *priv;
 };
 
 struct dw_eth_dev *dwc_drv_probe(struct device_d *dev);
diff --git a/drivers/net/designware_socfpga.c b/drivers/net/designware_socfpga.c
index 77157c2b511f..ce3ac38ebe87 100644
--- a/drivers/net/designware_socfpga.c
+++ b/drivers/net/designware_socfpga.c
@@ -14,11 +14,27 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include "designware.h"
 
-#define SYSMGR_EMACGRP_CTRL_PTP_REF_CLK_MASK 0x0010
+#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII   0x0
+#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII  0x1
+#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII   0x2
+#define SYSMGR_EMACGRP_CTRL_PHYSEL0_LSB0
+#define SYSMGR_EMACGRP_CTRL_PHYSEL1_LSB2
+#define SYSMGR_EMACGRP_CTRL_PHYSEL_MASK0x0003
+#define SYSMGR_EMACGRP_CTRL_PTP_REF_CLK_MASK   0x0010
+#define SYSMGR_GEN10_EMACGRP_CTRL_PTP_REF_CLK_MASK 0x0100
+
+#define SYSMGR_FPGAGRP_MODULE  0x0028
+#define SYSMGR_FPGAGRP_MODULE_EMAC 0x0004
+#define SYSMGR_FPGAINTF_EMAC_REG   0x0070
+#define SYSMGR_FPGAINTF_EMAC_BIT   0x1
+
+struct socfpga_dwc_dev;
+struct socfpga_dwmac_ops {
+   int (*set_phy_mode)(struct socfpga_dwc_dev *dwmac_priv);
+};
 
 struct socfpga_dwc_dev {
struct dw_eth_dev *priv;
@@ -26,27 +42,36 @@ struct socfpga_dwc_dev {
u32reg_shift;
void __iomem  *sys_mgr_base;
bool   f2h_ptp_ref_clk;
+   const struct   socfpga_dwmac_ops *ops;
 };
 
-static int socfpga_dwc_set_phy_mode(struct socfpga_dwc_dev *dwc_dev)
+static int socfpga_set_phy_mode_common(int phymode, u32 *val)
 {
-   struct dw_eth_dev *eth_dev = dwc_dev->priv;
-   int phymode = eth_dev->interface;
-   u32 reg_offset = dwc_dev->reg_offset;
-   u32 reg_shift = dwc_dev->reg_shift;
-   u32 ctrl, val;
-
switch (phymode) {
case PHY_INTERFACE_MODE_RGMII:
case PHY_INTERFACE_MODE_RGMII_ID:
-   val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII;
+   *val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII;
break;
case PHY_INTERFACE_MODE_MII:
case PHY_INTERFACE_MODE_GMII:
case PHY_INTERFACE_MODE_SGMII:
-   val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII;
+   *val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII;
break;
default:
+   return -EINVAL;
+   }
+   return 0;
+};
+
+static int socfpga_gen5_set_phy_mode(struct socfpga_dwc_dev *dwc_dev)
+{
+   struct dw_eth_dev *eth_dev = dwc_dev->priv;
+   int phymode = eth_dev->interface;
+   u32 reg_offset = dwc_dev->reg_offset;
+   u32 reg_shift = dwc_dev->reg_shift;
+   u32 ctrl, val;
+
+   if (socfpga_set_phy_mode_common(phymode, )) {
dev_err(_dev->netdev.dev, "bad phy mode %d\n", phymode);
return -EINVAL;
}
@@ -85,6 +110,54 @@ static int socfpga_dwc_set_phy_mode(struct socfpga_dwc_dev 
*dwc_dev)
return 0;
 }
 
+static int socfpga_gen10_set_phy_mode(struct socfpga_dwc_dev *dwc_dev)
+{
+   struct dw_eth_dev *eth_dev = dwc_dev->priv;
+   int phymode = eth_dev->interface;
+   u32 reg_offset = dwc_dev->reg_offset;
+   u32 reg_shift = dwc_dev->reg_shift;
+   u32 ctrl, val;
+
+   if (socfpga_set_phy_mode_common(phymode, )) {
+   dev_err(_dev->netdev.dev, "bad phy mode %d\n", phymode);
+   return -EINVAL;
+

[PATCH 3/3] ARM: socfpga: defconfig: enable state_drv

2019-10-17 Thread Steffen Trumtrar
The Arria10 DTS uses the state framework.
Enable the driver so it gets probed.

Signed-off-by: Steffen Trumtrar 
---
 arch/arm/configs/socfpga-arria10_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/socfpga-arria10_defconfig 
b/arch/arm/configs/socfpga-arria10_defconfig
index ae420c1dd290..e47a0ab1836d 100644
--- a/arch/arm/configs/socfpga-arria10_defconfig
+++ b/arch/arm/configs/socfpga-arria10_defconfig
@@ -74,6 +74,7 @@ CONFIG_MCI=y
 CONFIG_MCI_STARTUP=y
 CONFIG_MCI_MMC_BOOT_PARTITIONS=y
 CONFIG_MCI_DW=y
+CONFIG_STATE_DRV=y
 # CONFIG_PINCTRL is not set
 CONFIG_FS_TFTP=y
 CONFIG_FS_NFS=y
-- 
2.23.0


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


[PATCH 2/3] ARM: socfpga: cyclone5-system-manager.h: remove defines

2019-10-17 Thread Steffen Trumtrar
These defines are common for arria10 and cyclone5.
Instead of having them here, they are moved to drivers/net/designware_socfpga.c.

Signed-off-by: Steffen Trumtrar 
---
 .../include/mach/cyclone5-system-manager.h| 11 ---
 1 file changed, 11 deletions(-)

diff --git a/arch/arm/mach-socfpga/include/mach/cyclone5-system-manager.h 
b/arch/arm/mach-socfpga/include/mach/cyclone5-system-manager.h
index 24f52effd886..7cec60937b84 100644
--- a/arch/arm/mach-socfpga/include/mach/cyclone5-system-manager.h
+++ b/arch/arm/mach-socfpga/include/mach/cyclone5-system-manager.h
@@ -57,15 +57,4 @@ void socfpga_sysmgr_pinmux_init(unsigned long 
*sys_mgr_init_table, int num);
 #define SYSMGR_FPGAINTF_NAND   (1<<4)
 #define SYSMGR_FPGAINTF_SDMMC  (1<<5)
 
-/* Enumeration: sysmgr::emacgrp::ctrl::physel::enum*/
-#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII 0x0
-#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII 0x1
-#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII 0x2
-#define SYSMGR_EMACGRP_CTRL_PHYSEL0_LSB 0
-#define SYSMGR_EMACGRP_CTRL_PHYSEL1_LSB 2
-#define SYSMGR_EMACGRP_CTRL_PHYSEL_MASK 0x0003
-
-#define SYSMGR_FPGAGRP_MODULE  0x0028
-#define SYSMGR_FPGAGRP_MODULE_EMAC 0x0004
-
 #endif /* _SYSTEM_MANAGER_H_ */
-- 
2.23.0


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


[PATCH] fixup! imd: add support for checksum generation/verification

2020-02-07 Thread Steffen Trumtrar
Signed-off-by: Steffen Trumtrar 
---
CRC32 is now needed for imd, but was selected by accident. In situations
where barebox is stripped down (e.g. socfpga-xload, where there is no
environment, globalvars or command_support), barebox won't compile anymore.

 common/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/common/Kconfig b/common/Kconfig
index f9ef9bd83bad..fcdeb5c30b58 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -693,6 +693,7 @@ config FLEXIBLE_BOOTARGS
  completely.
 
 config IMD
+   select CRC32
bool "barebox metadata support"
 
 config IMD_TARGET
-- 
2.25.0


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


[PATCH v4 2/3] imd: add support for checksum generation/verification

2020-01-27 Thread Steffen Trumtrar
Add a new imd type "checksum". This type consists of the CRC32 checksum
of the whole barebox image minus the checksum itself.
The checksum can be written to the imd field with the bareboximd host-tool.
It can be verified with said tool or with "imd" on the target.

Signed-off-by: Steffen Trumtrar 
---
 commands/imd.c   |   2 +
 common/imd-barebox.c |   1 +
 common/imd.c | 152 ++-
 include/image-metadata.h |  38 +-
 scripts/bareboximd.c |  34 +
 5 files changed, 225 insertions(+), 2 deletions(-)

diff --git a/commands/imd.c b/commands/imd.c
index f1a22cef96bd..fc6cc4723144 100644
--- a/commands/imd.c
+++ b/commands/imd.c
@@ -46,6 +46,8 @@ BAREBOX_CMD_HELP_TEXT("Options:")
 BAREBOX_CMD_HELP_OPT ("-t ", "only show information of ")
 BAREBOX_CMD_HELP_OPT ("-n ", "for tags with multiple strings only show 
string ")
 BAREBOX_CMD_HELP_OPT ("-s VARNAME",  "set variable VARNAME instead of showing 
information")
+BAREBOX_CMD_HELP_OPT ("-V",  "Verify checksum of FILE")
+BAREBOX_CMD_HELP_OPT ("-c", "Create checksum for FILE and write it to the 
crc32 tag.")
 BAREBOX_CMD_HELP_TEXT("")
 BAREBOX_CMD_HELP_TEXT("Without options all information available is printed. 
Valid types are:")
 BAREBOX_CMD_HELP_TEXT("release, build, model, of_compatible")
diff --git a/common/imd-barebox.c b/common/imd-barebox.c
index e9cd37d83ec8..e5cdfd1aed34 100644
--- a/common/imd-barebox.c
+++ b/common/imd-barebox.c
@@ -23,3 +23,4 @@ __BAREBOX_IMD_SECTION(.barebox_imd_end) = {
 
 BAREBOX_IMD_TAG_STRING(imd_build_tag, IMD_TYPE_BUILD, UTS_VERSION, 1);
 BAREBOX_IMD_TAG_STRING(imd_release_tag, IMD_TYPE_RELEASE, UTS_RELEASE, 1);
+BAREBOX_IMD_CRC(imd_crc32, 0x0, 1);
diff --git a/common/imd.c b/common/imd.c
index e0dab69644c0..9be07fef746d 100644
--- a/common/imd.c
+++ b/common/imd.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #ifndef CONFIG_CMD_IMD
 int imd_command_setenv(const char *variable_name, const char *value)
@@ -167,6 +168,9 @@ static struct imd_type_names imd_types[] = {
}, {
.type = IMD_TYPE_OF_COMPATIBLE,
.name = "of_compatible",
+   }, {
+   .type = IMD_TYPE_CRC32,
+   .name = "crc32",
},
 };
 
@@ -256,6 +260,23 @@ char *imd_concat_strings(const struct imd_header *imd)
return str;
 }
 
+/**
+ * imd_uint32_flags - get uint32 flags
+ * @imd: The IMD entry
+ *
+ * This function returns the flags in @imd.
+ *
+ * Return: A pointer to the flags or NULL if the entry is not uint32.
+ */
+static uint32_t *imd_crc32_flags(const struct imd_header *imd) {
+   char *p = (char *)(imd + 1);
+
+   if (!imd_is_crc32(imd_read_type(imd)))
+   return NULL;
+
+   return (uint32_t *)(p + sizeof(uint32_t));
+}
+
 /**
  * imd_get_param - get a parameter
  * @imd: The IMD entry
@@ -287,6 +308,118 @@ const char *imd_get_param(const struct imd_header *imd, 
const char *name)
return NULL;
 }
 
+static int imd_calculate_crc32(void *input, const struct imd_header *imd_start,
+  struct imd_header **imd_crc, uint32_t *crc,
+  size_t size)
+{
+   const struct imd_header *imd;
+   int length;
+   int end_ofs = (char *)imd_start - (char *)input + sizeof(char) * 8;
+
+   /* search the checksum imd token */
+   imd_for_each(imd_start, imd) {
+   length = imd_read_length(imd);
+   length = ALIGN(length, 4);
+   length += sizeof(struct imd_header);
+
+   if (imd_read_type(imd) == IMD_TYPE_CRC32) {
+   *imd_crc = (struct imd_header *)imd;
+   debug("Found crc token at %d\n", end_ofs);
+   break;
+   }
+
+   end_ofs += length;
+   }
+
+   /*
+* Calculate checksum from start of input up to the checksum.
+* The checksum and the flags field in the imd_entry_crc32 entry are
+* modified after the checksum is calculated. Therefore skip them here
+* or the checksum will become invalid once it is written to the
+* checksum tag.
+*/
+   length = sizeof(struct imd_header);
+   end_ofs += length;
+
+   *crc = crc32(*crc, input, end_ofs);
+   debug("Calculated checksum from %d to %d: 0x%08x\n", 0, end_ofs, *crc);
+
+   /* move past the checksum data and flags field */
+   end_ofs += sizeof(uint32_t) + sizeof(char);
+   input += end_ofs;
+
+   *crc = crc32(*crc, input, size - end_ofs);
+   debug("Calculated checksum from %d to %d: 0x%08x\n", end_ofs,
+ end_ofs + (size - end_ofs), *crc);
+
+   return 0;
+}
+
+static int imd_write_crc32(void *buf, const struc

[PATCH v4 1/3] imd: replace magicvalue with sizeof(struct)

2020-01-27 Thread Steffen Trumtrar
Instead of using "8" as the size of an imd_header, use the sizeof operator.

Signed-off-by: Steffen Trumtrar 
---
 common/imd.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/common/imd.c b/common/imd.c
index 913a01de87bf..e0dab69644c0 100644
--- a/common/imd.c
+++ b/common/imd.c
@@ -41,7 +41,7 @@ const struct imd_header *imd_next(const struct imd_header 
*imd)
 
length = imd_read_length(imd);
length = ALIGN(length, 4);
-   length += 8;
+   length += sizeof(struct imd_header);
 
return (const void *)imd + length;
 }
@@ -63,14 +63,14 @@ static int imd_next_validate(const void *buf, int bufsize, 
int start_ofs)
 
size = bufsize - start_ofs;
 
-   if (size < 8) {
+   if (size < sizeof(struct imd_header)) {
debug("trunkated tag at offset %dd\n", start_ofs);
return -EINVAL;
}
 
length = imd_read_length(imd);
length = ALIGN(length, 4);
-   length += 8;
+   length += sizeof(struct imd_header);
 
if (size < length) {
debug("tag at offset %d with size %d exceeds bufsize %d\n",
-- 
2.25.0


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


[PATCH v4 3/3] commands: bbu: add support for imd checksum

2020-01-27 Thread Steffen Trumtrar
Add support for verifying an image by use of the imd checksum.
If the checksum that is saved in the image and the one that is
calculated over the image differ, barebox_update aborts.

Signed-off-by: Steffen Trumtrar 
---
 common/bbu.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/common/bbu.c b/common/bbu.c
index 00bec32a860a..b976b99d7c95 100644
--- a/common/bbu.c
+++ b/common/bbu.c
@@ -206,6 +206,10 @@ static int bbu_check_metadata(struct bbu_data *data)
if (ret)
return ret;
 
+   ret = imd_verify_crc32((void *)data->image, data->len);
+   if (ret == -EILSEQ && !(data->flags & BBU_FLAG_FORCE))
+   return ret;
+
return 0;
 }
 
-- 
2.25.0


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


[PATCH v3 2/3] imd: add support for checksum generation/verification

2020-01-20 Thread Steffen Trumtrar
Add a new imd type "checksum". This type consists of the CRC32 checksum
of the whole barebox image minus the checksum itself.
The checksum can be written to the imd field with the bareboximd host-tool.
It can be verified with said tool or with "imd" on the target.

Signed-off-by: Steffen Trumtrar 
---
Changes in v3:
  - moved the flags field to the uint32_t tag

 commands/imd.c   |   1 +
 common/imd-barebox.c |   1 +
 common/imd.c | 169 ++-
 include/image-metadata.h |  42 ++
 scripts/bareboximd.c |  32 
 5 files changed, 244 insertions(+), 1 deletion(-)

diff --git a/commands/imd.c b/commands/imd.c
index f1a22cef96bd..16ab7290c920 100644
--- a/commands/imd.c
+++ b/commands/imd.c
@@ -46,6 +46,7 @@ BAREBOX_CMD_HELP_TEXT("Options:")
 BAREBOX_CMD_HELP_OPT ("-t ", "only show information of ")
 BAREBOX_CMD_HELP_OPT ("-n ", "for tags with multiple strings only show 
string ")
 BAREBOX_CMD_HELP_OPT ("-s VARNAME",  "set variable VARNAME instead of showing 
information")
+BAREBOX_CMD_HELP_OPT ("-V",  "Verify checksum of image")
 BAREBOX_CMD_HELP_TEXT("")
 BAREBOX_CMD_HELP_TEXT("Without options all information available is printed. 
Valid types are:")
 BAREBOX_CMD_HELP_TEXT("release, build, model, of_compatible")
diff --git a/common/imd-barebox.c b/common/imd-barebox.c
index e9cd37d83ec8..4aec51bfbdc2 100644
--- a/common/imd-barebox.c
+++ b/common/imd-barebox.c
@@ -23,3 +23,4 @@ __BAREBOX_IMD_SECTION(.barebox_imd_end) = {
 
 BAREBOX_IMD_TAG_STRING(imd_build_tag, IMD_TYPE_BUILD, UTS_VERSION, 1);
 BAREBOX_IMD_TAG_STRING(imd_release_tag, IMD_TYPE_RELEASE, UTS_RELEASE, 1);
+BAREBOX_IMD_CRC(imd_checksum, 0x0, 1);
diff --git a/common/imd.c b/common/imd.c
index e0dab69644c0..b8429184777b 100644
--- a/common/imd.c
+++ b/common/imd.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #ifndef CONFIG_CMD_IMD
 int imd_command_setenv(const char *variable_name, const char *value)
@@ -167,6 +168,9 @@ static struct imd_type_names imd_types[] = {
}, {
.type = IMD_TYPE_OF_COMPATIBLE,
.name = "of_compatible",
+   }, {
+   .type = IMD_TYPE_CHECKSUM,
+   .name = "checksum",
},
 };
 
@@ -256,6 +260,40 @@ char *imd_concat_strings(const struct imd_header *imd)
return str;
 }
 
+/**
+ * imd_uint32_data - get uint32 data
+ * @imd: The IMD entry
+ *
+ * This function returns the data in @imd.
+ *
+ * Return: A pointer to the uint32 or NULL if the entry is not uint32.
+ */
+const uint32_t *imd_uint32_data(const struct imd_header *imd) {
+   char *p = (char *)(imd + 1);
+
+   if (!imd_is_uint32(imd_read_type(imd)))
+   return NULL;
+
+   return (uint32_t *)p;
+}
+
+/**
+ * imd_uint32_flags - get uint32 flags
+ * @imd: The IMD entry
+ *
+ * This function returns the flags in @imd.
+ *
+ * Return: A pointer to the flags or NULL if the entry is not uint32.
+ */
+uint32_t *imd_uint32_flags(const struct imd_header *imd) {
+   char *p = (char *)(imd + 1);
+
+   if (!imd_is_uint32(imd_read_type(imd)))
+   return NULL;
+
+   return (uint32_t *)(p + sizeof(uint32_t));
+}
+
 /**
  * imd_get_param - get a parameter
  * @imd: The IMD entry
@@ -287,6 +325,118 @@ const char *imd_get_param(const struct imd_header *imd, 
const char *name)
return NULL;
 }
 
+static int imd_calculate_crc32(void *input, const struct imd_header *imd_start,
+  struct imd_header **imd_crc, uint32_t *crc,
+  size_t size)
+{
+   const struct imd_header *imd;
+   int length;
+   int end_ofs = (char *)imd_start - (char *)input + sizeof(char) * 8;
+
+   /* search the checksum imd token */
+   imd_for_each(imd_start, imd) {
+   length = imd_read_length(imd);
+   length = ALIGN(length, 4);
+   length += sizeof(struct imd_header);
+
+   if (imd_read_type(imd) == IMD_TYPE_CHECKSUM) {
+   *imd_crc = (struct imd_header *)imd;
+   debug("Found crc token at %d\n", end_ofs);
+   break;
+   }
+
+   end_ofs += length;
+   }
+
+   /*
+* Calculate checksum from start of input up to the checksum.
+* The checksum and the flags field in the imd_entry_uint32 entry are
+* modified after the checksum is calculated. Therefore skip them here
+* or the checksum will become invalid once it is written to the
+* checksum tag.
+*/
+   length = sizeof(struct imd_header);
+   end_ofs += length;
+
+   *crc = crc32(*crc, input, end_ofs);
+   debug("Calculated checksum from %d to %d: 0x%08x\n", 0, end_ofs, *crc);
+
+   /* move past t

[PATCH v3 3/3] commands: bbu: add support for imd checksum

2020-01-20 Thread Steffen Trumtrar
Add support for verifying an image by use of the imd checksum.
If the checksum that is saved in the image and the one that is
calculated over the image differ, barebox_update aborts.

Signed-off-by: Steffen Trumtrar 
---
 common/bbu.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/common/bbu.c b/common/bbu.c
index 00bec32a860a..b976b99d7c95 100644
--- a/common/bbu.c
+++ b/common/bbu.c
@@ -206,6 +206,10 @@ static int bbu_check_metadata(struct bbu_data *data)
if (ret)
return ret;
 
+   ret = imd_verify_crc32((void *)data->image, data->len);
+   if (ret == -EILSEQ && !(data->flags & BBU_FLAG_FORCE))
+   return ret;
+
return 0;
 }
 
-- 
2.25.0


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


[PATCH v3 1/3] imd: replace magicvalue with sizeof(struct)

2020-01-20 Thread Steffen Trumtrar
Instead of using "8" as the size of an imd_header, use the sizeof operator.

Signed-off-by: Steffen Trumtrar 
---
 common/imd.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/common/imd.c b/common/imd.c
index 913a01de87bf..e0dab69644c0 100644
--- a/common/imd.c
+++ b/common/imd.c
@@ -41,7 +41,7 @@ const struct imd_header *imd_next(const struct imd_header 
*imd)
 
length = imd_read_length(imd);
length = ALIGN(length, 4);
-   length += 8;
+   length += sizeof(struct imd_header);
 
return (const void *)imd + length;
 }
@@ -63,14 +63,14 @@ static int imd_next_validate(const void *buf, int bufsize, 
int start_ofs)
 
size = bufsize - start_ofs;
 
-   if (size < 8) {
+   if (size < sizeof(struct imd_header)) {
debug("trunkated tag at offset %dd\n", start_ofs);
return -EINVAL;
}
 
length = imd_read_length(imd);
length = ALIGN(length, 4);
-   length += 8;
+   length += sizeof(struct imd_header);
 
if (size < length) {
debug("tag at offset %d with size %d exceeds bufsize %d\n",
-- 
2.25.0


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


[PATCH 2/2] common: imd: handle error in imd_write_crc32

2020-05-04 Thread Steffen Trumtrar
Don't just ignore the return value of write_file.

Signed-off-by: Steffen Trumtrar 
---
 common/imd.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/common/imd.c b/common/imd.c
index 526308effa3c..5544a0131cc9 100644
--- a/common/imd.c
+++ b/common/imd.c
@@ -370,6 +370,7 @@ static int imd_write_crc32(void *buf, const struct 
imd_header *imd_start,
return -ENODATA;
} else {
uint32_t *p = (uint32_t *)(imd_crc + 1);
+   int ret;
 
if (*p != crc) {
uint32_t *flags = imd_crc32_flags(imd_crc);
@@ -377,7 +378,11 @@ static int imd_write_crc32(void *buf, const struct 
imd_header *imd_start,
debug("Update crc token from 0x%08x to 0x%08x (flags 
0x%08x)\n", *p, crc, *flags);
*p = crc;
 
-   write_file(filename, buf, size);
+   ret = write_file(filename, buf, size);
+   if (ret < 0) {
+   eprintf("CRC: write crc token to %s failed: 
%d\n", filename, ret);
+   return ret;
+   }
}
}
 
-- 
2.26.2


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


[PATCH 1/2] scripts: bareboximd: fix write_file error handling

2020-05-04 Thread Steffen Trumtrar
write will never return 0 on POSIX conformant systems. Remove this error
path.
Also, close the file on error.

Signed-off-by: Steffen Trumtrar 
---
 scripts/bareboximd.c | 17 ++---
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/scripts/bareboximd.c b/scripts/bareboximd.c
index b332d435a66f..6ba6dabf3a2c 100644
--- a/scripts/bareboximd.c
+++ b/scripts/bareboximd.c
@@ -56,7 +56,7 @@ int imd_command_setenv(const char *variable_name, const char 
*value)
 
 static int write_file(const char *filename, const void *buf, size_t size)
 {
-   int fd, ret;
+   int fd, ret = 0;
int now;
 
fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR | 
S_IRGRP | S_IROTH);
@@ -65,22 +65,17 @@ static int write_file(const char *filename, const void 
*buf, size_t size)
 
while (size) {
now = write(fd, buf, size);
-   if (now == 0) {
-   errno = ENOSPC;
-   return -1;
+   if (now < 0) {
+   ret = now;
+   goto out;
}
-   if (now < 0)
-   return now;
size -= now;
buf += now;
}
 
+out:
close(fd);
-
-   if (ret < 0)
-   return ret;
-
-   return 0;
+   return ret;
 }
 
 static int read_file_2(const char *filename, size_t *size, void **outbuf, 
size_t max_size)
-- 
2.26.2


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


Re: [PATCH 1/2] scripts: imd: fix uninitialized variable read

2020-05-04 Thread Steffen Trumtrar



Hi,

Sascha Hauer  writes:


On Wed, Apr 29, 2020 at 08:40:39AM +0200, Ahmad Fatoum wrote:
Errors are propagated in the loop and ret is never set. Remove 
it.


Signed-off-by: Ahmad Fatoum 
---
 scripts/bareboximd.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/scripts/bareboximd.c b/scripts/bareboximd.c
index b733cae61c87..d11b661fa391 100644
--- a/scripts/bareboximd.c
+++ b/scripts/bareboximd.c
@@ -53,7 +53,7 @@ int imd_command_setenv(const char 
*variable_name, const char *value)
 
 static int write_file(const char *filename, const void *buf, 
 size_t size)

 {
-   int fd, ret;
+   int fd;
int now;
 
 	fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR 
 | S_IWUSR | S_IRGRP | S_IROTH);
@@ -74,9 +74,6 @@ static int write_file(const char *filename, 
const void *buf, size_t size)
 
 	close(fd);
 
-	if (ret < 0)

-   return ret;
-


There's more wrong in this function. In the error path the file 
is never
closed. It is not an error when write() returns 0. The return 
value of
write_file() is never checked by the caller. Steffen, care to 
fix some

of these?


yes, I will have a look.


str

--
Pengutronix e.K.| Dipl.-Inform. Steffen Trumtrar |
Steuerwalder Str. 21| https://www.pengutronix.de/|
31137 Hildesheim, Germany   | Phone: +49-5121-206917-0   |
Amtsgericht Hildesheim, HRA 2686| Fax:   +49-5121-206917-|

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


[PATCH 3/4] common: globalvar: add variable for buildsystem_version_string

2020-09-23 Thread Steffen Trumtrar
Now that the buildsystem version is available, make it accessible as a
global variable for runtime usage. If the buildsystem version is not
present (i.e. empty), don't add the variable at all.

Signed-off-by: Steffen Trumtrar 
---
 common/globalvar.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/common/globalvar.c b/common/globalvar.c
index 98a028a68aa7..e38ad0c2c668 100644
--- a/common/globalvar.c
+++ b/common/globalvar.c
@@ -595,6 +595,9 @@ static int globalvar_init(void)
 
globalvar_add_simple("version", UTS_RELEASE);
 
+   if (strlen(buildsystem_version_string) > 0)
+   globalvar_add_simple("buildsystem.version", 
buildsystem_version_string);
+
return 0;
 }
 pure_initcall(globalvar_init);
-- 
2.28.0


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


[PATCH 2/4] common: print buildsystem version in barebox banner

2020-09-23 Thread Steffen Trumtrar
When the barebox banner is enabled and printed during startup, also show
information about the buildsystem version: the exact state of the
barebox binary and its config.

Signed-off-by: Steffen Trumtrar 
---
 common/version.c | 6 ++
 include/common.h | 1 +
 2 files changed, 7 insertions(+)

diff --git a/common/version.c b/common/version.c
index 8b1fd4dbe756..54cec5335d9c 100644
--- a/common/version.c
+++ b/common/version.c
@@ -10,11 +10,17 @@ const char release_string[] =
"barebox-" UTS_RELEASE;
 EXPORT_SYMBOL(release_string);
 
+const char buildsystem_version_string[] =
+   BUILDSYSTEM_VERSION;
+EXPORT_SYMBOL(buildsystem_version_string);
+
 #ifdef CONFIG_BANNER
 void barebox_banner (void)
 {
printf("\n\n");
pr_info("%s", version_string);
+   if (strlen(buildsystem_version_string) > 0)
+   pr_info("Buildsystem version: %s", buildsystem_version_string);
printf("\n\n");
pr_info("Board: %s\n", barebox_get_model());
 }
diff --git a/include/common.h b/include/common.h
index ceb0b358bd44..693f5bf97029 100644
--- a/include/common.h
+++ b/include/common.h
@@ -124,6 +124,7 @@ int memcpy_parse_options(int argc, char *argv[], int 
*sourcefd,
 
 extern const char version_string[];
 extern const char release_string[];
+extern const char buildsystem_version_string[];
 #ifdef CONFIG_BANNER
 void barebox_banner(void);
 #else
-- 
2.28.0


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


[PATCH 4/4] imd: add buildsystem version to metadata

2020-09-23 Thread Steffen Trumtrar
To have information about the exact state of a barebox binary from
userspace, add the buildsystem version to the IMD.

Signed-off-by: Steffen Trumtrar 
---
 common/imd-barebox.c | 1 +
 common/imd.c | 3 +++
 include/image-metadata.h | 1 +
 3 files changed, 5 insertions(+)

diff --git a/common/imd-barebox.c b/common/imd-barebox.c
index e5cdfd1aed34..06731d0600cf 100644
--- a/common/imd-barebox.c
+++ b/common/imd-barebox.c
@@ -23,4 +23,5 @@ __BAREBOX_IMD_SECTION(.barebox_imd_end) = {
 
 BAREBOX_IMD_TAG_STRING(imd_build_tag, IMD_TYPE_BUILD, UTS_VERSION, 1);
 BAREBOX_IMD_TAG_STRING(imd_release_tag, IMD_TYPE_RELEASE, UTS_RELEASE, 1);
+BAREBOX_IMD_TAG_STRING(imd_buildsystem_version_tag, IMD_TYPE_BUILDSYSTEM, 
BUILDSYSTEM_VERSION, 1);
 BAREBOX_IMD_CRC(imd_crc32, 0x0, 1);
diff --git a/common/imd.c b/common/imd.c
index 96496514a54a..6970edaf96f1 100644
--- a/common/imd.c
+++ b/common/imd.c
@@ -168,6 +168,9 @@ static struct imd_type_names imd_types[] = {
}, {
.type = IMD_TYPE_CRC32,
.name = "crc32",
+   }, {
+   .type = IMD_TYPE_BUILDSYSTEM,
+   .name = "buildsystem version",
},
 };
 
diff --git a/include/image-metadata.h b/include/image-metadata.h
index 42ddf2fab02a..a9cb9cfe8f16 100644
--- a/include/image-metadata.h
+++ b/include/image-metadata.h
@@ -26,6 +26,7 @@
 #define IMD_TYPE_MODEL 0x640c8004 /* The board name this image is for 
*/
 #define IMD_TYPE_OF_COMPATIBLE 0x640c8005 /* the device tree compatible string 
*/
 #define IMD_TYPE_PARAMETER 0x640c8006 /* A generic parameter. Use 
key=value as data */
+#define IMD_TYPE_BUILDSYSTEM   0x640c8007 /* The buildsystem version barebox 
was built with */
 #define IMD_TYPE_CRC32 0x640c1007 /* the checksum of the barebox 
images */
 #define IMD_TYPE_END   0x640c7fff
 #define IMD_TYPE_INVALID   0x
-- 
2.28.0


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


[PATCH] imd: change disabled checksum tag info to debug

2021-01-12 Thread Steffen Trumtrar
From: Steffen Trumtrar 

When the checksum tag is disabled the CRC is most likely invalid.
And if the checksum tag is disabled and the CRC is actually invalid the
user doesn't care for it anyway.

This information only confuses the user so make it a debug message.

Signed-off-by: Steffen Trumtrar 
---
 common/imd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/common/imd.c b/common/imd.c
index ef9eff876b..aff3b00b6b 100644
--- a/common/imd.c
+++ b/common/imd.c
@@ -406,7 +406,7 @@ int imd_verify_crc32(void *buf, size_t size)
   *p, crc);
return -EILSEQ;
} else if (*p != crc && !imd_crc32_is_valid(*flags)) {
-   printf("CRC: is invalid, but the checksum tag is not 
enabled\n");
+   debug("CRC: is invalid, but the checksum tag is not 
enabled\n");
return -EINVAL;
} else {
printf("CRC: valid\n");
-- 
2.20.1


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


[PATCH 3/3] eeprom: at24: add support for 24cs64

2020-12-16 Thread Steffen Trumtrar
The 24cs64 is a 64-Kbit eeprom with 32 byte write pages.

Signed-off-by: Steffen Trumtrar 
---
 drivers/eeprom/at24.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/eeprom/at24.c b/drivers/eeprom/at24.c
index 568aa02a4c8c..8c04c5684b61 100644
--- a/drivers/eeprom/at24.c
+++ b/drivers/eeprom/at24.c
@@ -112,6 +112,7 @@ static struct platform_device_id at24_ids[] = {
{ "24c16", AT24_DEVICE_MAGIC(16384 / 8, 0) },
{ "24c32", AT24_DEVICE_MAGIC(32768 / 8, AT24_FLAG_ADDR16) },
{ "24c64", AT24_DEVICE_MAGIC(65536 / 8, AT24_FLAG_ADDR16) },
+   { "24cs64", AT24_DEVICE_MAGIC(16, AT24_FLAG_ADDR16) },
{ "24c128", AT24_DEVICE_MAGIC(131072 / 8, AT24_FLAG_ADDR16) },
{ "24c256", AT24_DEVICE_MAGIC(262144 / 8, AT24_FLAG_ADDR16) },
{ "24c512", AT24_DEVICE_MAGIC(524288 / 8, AT24_FLAG_ADDR16) },
-- 
2.20.1


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


[PATCH 1/3] i.MX7: Add CCM definitions for UART3

2020-12-16 Thread Steffen Trumtrar
Signed-off-by: Steffen Trumtrar 
---
 arch/arm/mach-imx/include/mach/imx7-ccm-regs.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/mach-imx/include/mach/imx7-ccm-regs.h 
b/arch/arm/mach-imx/include/mach/imx7-ccm-regs.h
index de6eb1bbd10d..5c60794ca74f 100644
--- a/arch/arm/mach-imx/include/mach/imx7-ccm-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx7-ccm-regs.h
@@ -3,6 +3,7 @@
 
 #define IMX7_CCM_CCGR_UART1148
 #define IMX7_CCM_CCGR_UART2149
+#define IMX7_CCM_CCGR_UART3150
 
 #define IMX7_CLOCK_ROOT_INDEX(x)   (((x) - 0x8000) / 128)
 
@@ -16,6 +17,9 @@
 #define IMX7_UART2_CLK_ROOTIMX7_CLOCK_ROOT_INDEX(0xb000)
 #define IMX7_UART2_CLK_ROOT__OSC_24M IMX7_CCM_TARGET_ROOTn_MUX(0b000)
 
+#define IMX7_UART3_CLK_ROOTIMX7_CLOCK_ROOT_INDEX(0xb080)
+#define IMX7_UART3_CLK_ROOT__OSC_24M IMX7_CCM_TARGET_ROOTn_MUX(0b000)
+
 /* 0 <= n <= 190 */
 #define IMX7_CCM_CCGRn_SET(n)  (0x4004 + 16 * (n))
 #define IMX7_CCM_CCGRn_CLR(n)  (0x4008 + 16 * (n))
-- 
2.20.1


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


[PATCH 2/3] net: mdio:gpio: fix typos in dev_dbg

2020-12-16 Thread Steffen Trumtrar
Signed-off-by: Steffen Trumtrar 
---
 drivers/net/phy/mdio-gpio.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c
index affa31ae2c9b..80d2394f4b11 100644
--- a/drivers/net/phy/mdio-gpio.c
+++ b/drivers/net/phy/mdio-gpio.c
@@ -52,7 +52,7 @@ static struct mdio_gpio_info *mdio_gpio_of_get_info(struct 
device_d *dev)
 
ret = of_get_gpio_flags(dev->device_node, 0, );
if (ret < 0) {
-   dev_dbg(dev, "failed to get MDC inforamtion from DT\n");
+   dev_dbg(dev, "failed to get MDC information from DT\n");
goto free_info;
}
 
@@ -61,7 +61,7 @@ static struct mdio_gpio_info *mdio_gpio_of_get_info(struct 
device_d *dev)
 
ret = of_get_gpio_flags(dev->device_node, 1, );
if (ret < 0) {
-   dev_dbg(dev, "failed to get MDIO inforamtion from DT\n");
+   dev_dbg(dev, "failed to get MDIO information from DT\n");
goto free_info;
}
 
-- 
2.20.1


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


[PATCH 1/2] image-sparse: change retlen to size_t

2021-01-11 Thread Steffen Trumtrar
retlen can potentially overflow. Also, write_full() in
fastboot_handle_sparse() expects size_t anyway.

Signed-off-by: Steffen Trumtrar 
---
 common/fastboot.c  | 2 +-
 include/image-sparse.h | 2 +-
 lib/image-sparse.c | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/common/fastboot.c b/common/fastboot.c
index 1b6dc28d8e..40b92d9982 100644
--- a/common/fastboot.c
+++ b/common/fastboot.c
@@ -566,7 +566,7 @@ static int fastboot_handle_sparse(struct fastboot *fb,
}
 
while (1) {
-   int retlen;
+   size_t retlen;
loff_t pos;
 
ret = sparse_image_read(sparse, buf, , bufsiz, );
diff --git a/include/image-sparse.h b/include/image-sparse.h
index 29242f4fd5..6bff844411 100644
--- a/include/image-sparse.h
+++ b/include/image-sparse.h
@@ -60,7 +60,7 @@ struct sparse_image_ctx;
 
 struct sparse_image_ctx *sparse_image_open(const char *path);
 int sparse_image_read(struct sparse_image_ctx *si, void *buf,
- loff_t *pos, size_t len, int *retlen);
+ loff_t *pos, size_t len, size_t *retlen);
 void sparse_image_close(struct sparse_image_ctx *si);
 loff_t sparse_image_size(struct sparse_image_ctx *si);
 
diff --git a/lib/image-sparse.c b/lib/image-sparse.c
index 0c31742ab6..8e7a52fd71 100644
--- a/lib/image-sparse.c
+++ b/lib/image-sparse.c
@@ -190,7 +190,7 @@ out:
 }
 
 int sparse_image_read(struct sparse_image_ctx *si, void *buf, loff_t *pos,
- size_t len, int *retlen)
+ size_t len, size_t *retlen)
 {
size_t now;
int ret, i;
-- 
2.20.1


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


[PATCH 2/2] image-sparse: change chunk_data_sz to u64

2021-01-11 Thread Steffen Trumtrar
chunk_data_sz is set to the result of a __le32 * __le32 multiplication:

  chunk_data_sz = si->sparse.blk_sz * si->chunk.chunk_sz;

This will overflow.

Signed-off-by: Steffen Trumtrar 
---
 lib/image-sparse.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lib/image-sparse.c b/lib/image-sparse.c
index 8e7a52fd71..c375c78d63 100644
--- a/lib/image-sparse.c
+++ b/lib/image-sparse.c
@@ -62,7 +62,8 @@ struct sparse_image_ctx {
 
 static int sparse_seek(struct sparse_image_ctx *si)
 {
-   unsigned int chunk_data_sz, payload;
+   uint64_t chunk_data_sz;
+   unsigned int payload;
loff_t offs;
int ret;
 
@@ -94,7 +95,7 @@ again:
return -errno;
}
 
-   chunk_data_sz = si->sparse.blk_sz * si->chunk.chunk_sz;
+   chunk_data_sz = (uint64_t) si->sparse.blk_sz * si->chunk.chunk_sz;
payload = si->chunk.total_sz - si->sparse.chunk_hdr_sz;
 
si->processed_chunks++;
-- 
2.20.1


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


[PATCH 05/13] drivers: add fpga bridge framework

2021-01-21 Thread Steffen Trumtrar
From: Steffen Trumtrar 

Import the fpga bridge framework from linux v4.10-rc2.

Description from the initial commit adding this to linux:
21aeda950c5f84a8351b862816d832120b217a9b

fpga: add fpga bridge framework

This framework adds API functions for enabling/
disabling FPGA bridges under kernel control.

This allows the Linux kernel to disable FPGA bridges
during FPGA reprogramming and to enable FPGA bridges
when FPGA reprogramming is done.  This framework is
be manufacturer-agnostic, allowing it to be used in
interfaces that use the FPGA Manager Framework to
reprogram FPGA's.

The functions are:
* of_fpga_bridge_get
* fpga_bridge_put
   Get/put an exclusive reference to a FPGA bridge.

* fpga_bridge_enable
* fpga_bridge_disable
   Enable/Disable traffic through a bridge.

* fpga_bridge_register
* fpga_bridge_unregister
   Register/unregister a device-specific low level FPGA
   Bridge driver.

Get an exclusive reference to a bridge and add it to a list:
* fpga_bridge_get_to_list

To enable/disable/put a set of bridges that are on a list:
* fpga_bridges_enable
* fpga_bridges_disable
* fpga_bridges_put

Signed-off-by: Alan Tull 

Signed-off-by: Steffen Trumtrar 
---
 drivers/Kconfig|   1 +
 drivers/Makefile   |   1 +
 drivers/fpga/Kconfig   |  22 
 drivers/fpga/Makefile  |   6 +
 drivers/fpga/fpga-bridge.c | 226 +
 include/fpga-bridge.h  |  69 +++
 6 files changed, 325 insertions(+)
 create mode 100644 drivers/fpga/Kconfig
 create mode 100644 drivers/fpga/Makefile
 create mode 100644 drivers/fpga/fpga-bridge.c
 create mode 100644 include/fpga-bridge.h

diff --git a/drivers/Kconfig b/drivers/Kconfig
index dda2405780..3bb9c09536 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -36,6 +36,7 @@ source "drivers/reset/Kconfig"
 source "drivers/pci/Kconfig"
 source "drivers/rtc/Kconfig"
 source "drivers/firmware/Kconfig"
+source "drivers/fpga/Kconfig"
 source "drivers/phy/Kconfig"
 source "drivers/crypto/Kconfig"
 source "drivers/memory/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 5a03bdceab..5221c2ca55 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_RESET_CONTROLLER) += reset/
 obj-$(CONFIG_PCI) += pci/
 obj-y += rtc/
 obj-$(CONFIG_FIRMWARE) += firmware/
+obj-$(CONFIG_FPGA) += fpga/
 obj-$(CONFIG_GENERIC_PHY) += phy/
 obj-$(CONFIG_HAB) += hab/
 obj-$(CONFIG_CRYPTO_HW) += crypto/
diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
new file mode 100644
index 00..fccdbff6eb
--- /dev/null
+++ b/drivers/fpga/Kconfig
@@ -0,0 +1,22 @@
+#
+# FPGA framework configuration
+#
+
+menu "FPGA Configuration Support"
+
+config FPGA
+   tristate "FPGA Configuration Framework"
+   help
+ Say Y here if you want support for configuring FPGAs from barebox.
+
+if FPGA
+
+config FPGA_BRIDGE
+   tristate "FPGA Bridge Framework"
+   help
+ Say Y here if you want to support bridges connected between host
+ processors and FPGAs or between FPGAs.
+
+endif # FPGA
+
+endmenu
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
new file mode 100644
index 00..fc71a29d3b
--- /dev/null
+++ b/drivers/fpga/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for the fpga framework and fpga manager drivers.
+#
+
+# FPGA Bridge Drivers
+obj-$(CONFIG_FPGA_BRIDGE)  += fpga-bridge.o
diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c
new file mode 100644
index 00..edf29b0ecf
--- /dev/null
+++ b/drivers/fpga/fpga-bridge.c
@@ -0,0 +1,226 @@
+/*
+ * FPGA Bridge Framework Driver
+ *
+ *  Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include 
+#include 
+
+/**
+ * fpga_bridge_enable - Enable transactions on the bridge
+ *
+ * @bridge: FPGA bridge
+ *
+ * Return: 0 for success, error code otherwise.
+ */
+int fpga_bridge_enable(struct fpga_bridge *bridge)
+{
+   dev_dbg(>dev, "enable\n");
+
+   if (bridge->br_ops && bridge->br_ops->enable_set)
+   return bridge->br_ops->enable_set(bridge, 1);
+
+   return 0;
+}
+EXPORT_SYMBOL

[PATCH 06/13] drivers: fpga: add socfpga bridges

2021-01-21 Thread Steffen Trumtrar
From: Steffen Trumtrar 

Import the SoCFPGA bridges drivers from linux v4.10-rc2.

Description from the original commit:
e5f8efa5c8bf86c1fa698551d54db8f6aee221fd

ARM: socfpga: fpga bridge driver support

Supports Altera SOCFPGA bridges:
 * fpga2sdram
 * fpga2hps
 * hps2fpga
 * lwhps2fpga

Allows enabling/disabling the bridges through the FPGA
Bridge Framework API functions.

The fpga2sdram driver only supports enabling and disabling
of the ports that been configured early on.  This is due to
a hardware limitation where the read, write, and command
ports on the fpga2sdram bridge can only be reconfigured
while there are no transactions to the sdram, i.e. when
running out of OCRAM before the kernel boots.

Device tree property 'init-val' configures the driver to
enable or disable the bridge during probe.  If the property
does not exist, the driver will leave the bridge in its
current state.

Signed-off-by: Alan Tull 
Signed-off-by: Matthew Gerlach 
Signed-off-by: Dinh Nguyen 
Signed-off-by: Greg Kroah-Hartman 

Signed-off-by: Steffen Trumtrar 
---
 drivers/fpga/Kconfig |   8 +
 drivers/fpga/Makefile|   1 +
 drivers/fpga/fpga-bridge.c   |   2 +-
 drivers/fpga/socfpga-fpga2sdram-bridge.c | 139 ++
 drivers/fpga/socfpga-hps2fpga-bridge.c   | 179 +++
 5 files changed, 328 insertions(+), 1 deletion(-)
 create mode 100644 drivers/fpga/socfpga-fpga2sdram-bridge.c
 create mode 100644 drivers/fpga/socfpga-hps2fpga-bridge.c

diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index fccdbff6eb..64ce9f91b6 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -17,6 +17,14 @@ config FPGA_BRIDGE
  Say Y here if you want to support bridges connected between host
  processors and FPGAs or between FPGAs.
 
+config SOCFPGA_FPGA_BRIDGE
+   tristate "Altera SoCFPGA FPGA Bridges"
+   depends on ARCH_SOCFPGA && FPGA_BRIDGE
+   select RESET_CONTROLLER
+   help
+ Say Y to enable drivers for FPGA bridges for Altera SOCFPGA
+ devices.
+
 endif # FPGA
 
 endmenu
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index fc71a29d3b..86178fe7c0 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -4,3 +4,4 @@
 
 # FPGA Bridge Drivers
 obj-$(CONFIG_FPGA_BRIDGE)  += fpga-bridge.o
+obj-$(CONFIG_SOCFPGA_FPGA_BRIDGE)  += socfpga-hps2fpga-bridge.o 
socfpga-fpga2sdram-bridge.o
diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c
index edf29b0ecf..b5c74a6e63 100644
--- a/drivers/fpga/fpga-bridge.c
+++ b/drivers/fpga/fpga-bridge.c
@@ -68,7 +68,7 @@ struct fpga_bridge *of_fpga_bridge_get(struct device_node *np)
 {
struct device_d *dev;
struct fpga_bridge *bridge;
-   int ret = -ENODEV;
+   int ret = -EPROBE_DEFER;
 
dev = of_find_device_by_node(np);
if (!dev || !dev->priv)
diff --git a/drivers/fpga/socfpga-fpga2sdram-bridge.c 
b/drivers/fpga/socfpga-fpga2sdram-bridge.c
new file mode 100644
index 00..a9760597dd
--- /dev/null
+++ b/drivers/fpga/socfpga-fpga2sdram-bridge.c
@@ -0,0 +1,139 @@
+/*
+ * FPGA to SDRAM Bridge Driver for Altera SoCFPGA Devices
+ *
+ *  Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This driver manages a bridge between an FPGA and the SDRAM used by the ARM
+ * host processor system (HPS).
+ *
+ * The bridge contains 4 read ports, 4 write ports, and 6 command ports.
+ * Reconfiguring these ports requires that no SDRAM transactions occur during
+ * reconfiguration.  The code reconfiguring the ports cannot run out of SDRAM
+ * nor can the FPGA access the SDRAM during reconfiguration.  This driver does
+ * not support reconfiguring the ports.  The ports are configured by code
+ * running out of on chip ram before Linux is started and the configuration
+ * is passed in a handoff register in the system manager.
+ *
+ * This driver supports enabling and disabling of the configured ports, which
+ * allows for safe reprogramming of the FPGA, assuming that the new FPGA image
+ * uses the same port configuration.  Bridges must be disabled before
+ * reprogramming the FPGA and re-enabled after the FPGA has been programmed.
+ */
+
+#include 
+#in

[PATCH 08/13] firmware: import fpga-mgr.h from linux

2021-01-21 Thread Steffen Trumtrar
From: Steffen Trumtrar 

Instead of defining the fpga-mgr structure in the socfpga driver, import
the fpga-mgr.h file from linux v4.13.

Signed-off-by: Steffen Trumtrar 
---
 drivers/firmware/socfpga.c |   9 +---
 include/firmware.h |   1 +
 include/fpga-mgr.h | 102 +
 3 files changed, 104 insertions(+), 8 deletions(-)
 create mode 100644 include/fpga-mgr.h

diff --git a/drivers/firmware/socfpga.c b/drivers/firmware/socfpga.c
index 14875214b1..605c931604 100644
--- a/drivers/firmware/socfpga.c
+++ b/drivers/firmware/socfpga.c
@@ -27,6 +27,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -83,14 +84,6 @@
 extern void socfpga_sdram_apply_static_cfg(void __iomem *sdrctrlgrp);
 extern void socfpga_sdram_apply_static_cfg_end(void *);
 
-struct fpgamgr {
-   struct firmware_handler fh;
-   struct device_d dev;
-   void __iomem *regs;
-   void __iomem *regs_data;
-   int programmed;
-};
-
 /* Get the FPGA mode */
 static uint32_t socfpga_fpgamgr_get_mode(struct fpgamgr *mgr)
 {
diff --git a/include/firmware.h b/include/firmware.h
index 19777d9bf7..2fef97a48f 100644
--- a/include/firmware.h
+++ b/include/firmware.h
@@ -13,6 +13,7 @@ struct firmware_handler {
char *id; /* unique identifier for this firmware device */
char *model; /* description for this device */
struct device_d *dev;
+   void *priv;
/* called once to prepare the firmware's programming cycle */
int (*open)(struct firmware_handler*);
/* called multiple times to program the firmware with the given data */
diff --git a/include/fpga-mgr.h b/include/fpga-mgr.h
new file mode 100644
index 00..a120b39189
--- /dev/null
+++ b/include/fpga-mgr.h
@@ -0,0 +1,102 @@
+/*
+ * FPGA Framework
+ *
+ *  Copyright (C) 2013-2015 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _LINUX_FPGA_MGR_H
+#define _LINUX_FPGA_MGR_H
+
+#include 
+
+struct fpga_manager;
+
+/**
+ * enum fpga_mgr_states - fpga framework states
+ * @FPGA_MGR_STATE_UNKNOWN: can't determine state
+ * @FPGA_MGR_STATE_POWER_OFF: FPGA power is off
+ * @FPGA_MGR_STATE_POWER_UP: FPGA reports power is up
+ * @FPGA_MGR_STATE_RESET: FPGA in reset state
+ * @FPGA_MGR_STATE_FIRMWARE_REQ: firmware request in progress
+ * @FPGA_MGR_STATE_FIRMWARE_REQ_ERR: firmware request failed
+ * @FPGA_MGR_STATE_WRITE_INIT: preparing FPGA for programming
+ * @FPGA_MGR_STATE_WRITE_INIT_ERR: Error during WRITE_INIT stage
+ * @FPGA_MGR_STATE_WRITE: writing image to FPGA
+ * @FPGA_MGR_STATE_WRITE_ERR: Error while writing FPGA
+ * @FPGA_MGR_STATE_WRITE_COMPLETE: Doing post programming steps
+ * @FPGA_MGR_STATE_WRITE_COMPLETE_ERR: Error during WRITE_COMPLETE
+ * @FPGA_MGR_STATE_OPERATING: FPGA is programmed and operating
+ */
+enum fpga_mgr_states {
+   /* default FPGA states */
+   FPGA_MGR_STATE_UNKNOWN,
+   FPGA_MGR_STATE_POWER_OFF,
+   FPGA_MGR_STATE_POWER_UP,
+   FPGA_MGR_STATE_RESET,
+
+   /* getting an image for loading */
+   FPGA_MGR_STATE_FIRMWARE_REQ,
+   FPGA_MGR_STATE_FIRMWARE_REQ_ERR,
+
+   /* write sequence: init, write, complete */
+   FPGA_MGR_STATE_WRITE_INIT,
+   FPGA_MGR_STATE_WRITE_INIT_ERR,
+   FPGA_MGR_STATE_WRITE,
+   FPGA_MGR_STATE_WRITE_ERR,
+   FPGA_MGR_STATE_WRITE_COMPLETE,
+   FPGA_MGR_STATE_WRITE_COMPLETE_ERR,
+
+   /* fpga is programmed and operating */
+   FPGA_MGR_STATE_OPERATING,
+};
+
+/*
+ * FPGA Manager flags
+ * FPGA_MGR_PARTIAL_RECONFIG: do partial reconfiguration if supported
+ * FPGA_MGR_EXTERNAL_CONFIG: FPGA has been configured prior to Linux booting
+ * FPGA_MGR_BITSTREAM_LSB_FIRST: SPI bitstream bit order is LSB first
+ * FPGA_MGR_COMPRESSED_BITSTREAM: FPGA bitstream is compressed
+ */
+#define FPGA_MGR_PARTIAL_RECONFIG  BIT(0)
+#define FPGA_MGR_EXTERNAL_CONFIG   BIT(1)
+#define FPGA_MGR_ENCRYPTED_BITSTREAM   BIT(2)
+#define FPGA_MGR_BITSTREAM_LSB_FIRST   BIT(3)
+#define FPGA_MGR_COMPRESSED_BITSTREAM  BIT(4)
+
+/**
+ * struct fpga_image_info - information specific to a FPGA image
+ * @flags: boolean flags as defined above
+ * @enable_timeout_us: maximum time to enable traffic through bridge (uSec)
+ * @disable_timeout_us: maximum time to disable traffic through bridge (uSec)
+ * @config_complete_timeout_us: maximum time for FPGA to switch to operating
+ *

[PATCH 13/13] firmware: add support for compressed images

2021-01-21 Thread Steffen Trumtrar
From: Steffen Trumtrar 

At least bitstreams for FPGAs can consist of a lot of zeros depending on
device utilization. These bitstreams can be compressed very effectively.

Let the firmware code accept these images and decompress them before
handing it to the firmware-manager in question.

Signed-off-by: Steffen Trumtrar 
---
 common/firmware.c | 43 ++-
 1 file changed, 38 insertions(+), 5 deletions(-)

diff --git a/common/firmware.c b/common/firmware.c
index 58509d5da6..c617ecc0f1 100644
--- a/common/firmware.c
+++ b/common/firmware.c
@@ -14,6 +14,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #define BUFSIZ 4096
 
@@ -211,12 +213,43 @@ out:
  */
 int firmwaremgr_load_file(struct firmware_mgr *mgr, const char *firmware)
 {
-   int ret;
-   char *name = basprintf("/dev/%s", mgr->handler->id);
-
-   ret = copy_file(firmware, name, 0);
+   char *dst;
+   enum filetype type;
+   int ret = -ENOENT;
+   int srcfd = 0;
+   int dstfd = 0;
+
+   if (mgr->handler->id) {
+   dst = basprintf("/dev/%s", mgr->handler->id);
+   } else {
+   pr_err("id not defined for handler\n");
+   return -ENODEV;
+   }
 
-   free(name);
+   if (firmware) {
+   type = file_name_detect_type(firmware);
+   if (type == filetype_unknown) {
+   ret = copy_file(firmware, dst, 0);
+   } else {
+   srcfd = open(firmware, O_RDONLY);
+   if (srcfd < 0)
+   return srcfd;
+   dstfd = open(dst, O_WRONLY | O_CREAT);
+
+   if (dstfd < 0) {
+   printf("could not open %s: %s\n", dst, 
errno_str());
+   ret = dstfd;
+   goto out;
+   }
+
+   ret = uncompress_fd_to_fd(srcfd, dstfd, 
uncompress_err_stdout);
+
+   close(dstfd);
+   }
+   }
+out:
+   close(srcfd);
+   free(dst);
 
return ret;
 }
-- 
2.20.1


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


[PATCH 12/13] drivers: firmware: socfpga: remove bridges shutdown

2021-01-21 Thread Steffen Trumtrar
From: Steffen Trumtrar 

The bridges are now handled via the bridges driver. There is no
need to hardcode the memory writes anymore.

Signed-off-by: Steffen Trumtrar 
---
 drivers/firmware/socfpga.c | 9 -
 1 file changed, 9 deletions(-)

diff --git a/drivers/firmware/socfpga.c b/drivers/firmware/socfpga.c
index 605c931604..eb3fc557c7 100644
--- a/drivers/firmware/socfpga.c
+++ b/drivers/firmware/socfpga.c
@@ -294,15 +294,6 @@ static int socfpga_fpgamgr_program_start(struct 
firmware_handler *fh)
/* disable all signals from hps peripheral controller to fpga */
writel(0, SYSMGR_FPGAINTF_MODULE);
 
-   /* disable all signals from fpga to hps sdram */
-   writel(0, (CYCLONE5_SDR_ADDRESS + SDR_CTRLGRP_FPGAPORTRST_ADDRESS));
-
-   /* disable all axi bridge (hps2fpga, lwhps2fpga & fpga2hps) */
-   writel(~0, CYCLONE5_RSTMGR_ADDRESS + RESET_MGR_BRG_MOD_RESET_OFS);
-
-   /* unmap the bridges from NIC-301 */
-   writel(0x1, CYCLONE5_L3REGS_ADDRESS);
-
dev_dbg(>dev, "start programming...\n");
 
/* initialize the FPGA Manager */
-- 
2.20.1


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


[PATCH 02/13] ARM: mmu: inherit pte flags from pmd

2021-01-21 Thread Steffen Trumtrar
From: Sascha Hauer 

When creating a 2nd level page table from a section inherit the flags
from the section rather than assuming the section was mapped cached
previously. This fixes creating a 2nd level pagetable when the section
was mapped differently than we expected.

Signed-off-by: Sascha Hauer 
---
 arch/arm/cpu/mmu.c | 28 
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c
index 6af228505d..6388e1bf14 100644
--- a/arch/arm/cpu/mmu.c
+++ b/arch/arm/cpu/mmu.c
@@ -138,6 +138,29 @@ static u32 *arm_create_pte(unsigned long virt, uint32_t 
flags)
return table;
 }
 
+static u32 pmd_flags_to_pte(u32 pmd)
+{
+   u32 pte = 0;
+
+   if (pmd & PMD_SECT_BUFFERABLE)
+   pte |= PTE_BUFFERABLE;
+   if (pmd & PMD_SECT_CACHEABLE)
+   pte |= PTE_CACHEABLE;
+   if (pmd & PMD_SECT_nG)
+   pte |= PTE_EXT_NG;
+   if (pmd & PMD_SECT_XN)
+   pte |= PTE_EXT_XN;
+
+   /* TEX[2:0] */
+   pte |= PTE_EXT_TEX((pmd >> 12) & 7);
+   /* AP[1:0] */
+   pte |= ((pmd >> 10) & 0x3) << 4;
+   /* AP[2] */
+   pte |= ((pmd >> 15) & 0x1) << 9;
+
+   return pte;
+}
+
 int arch_remap_range(void *start, size_t size, unsigned flags)
 {
u32 addr = (u32)start;
@@ -206,11 +229,8 @@ int arch_remap_range(void *start, size_t size, unsigned 
flags)
 * If PTE is not found it means that
 * we needs to split this section and
 * create a new page table for it
-*
-* NOTE: Here we assume that section
-* we just split was mapped as cached
 */
-   table = arm_create_pte(addr, pte_flags_cached);
+   table = arm_create_pte(addr, 
pmd_flags_to_pte(*pgd));
pte = find_pte(addr);
BUG_ON(!pte);
}
-- 
2.20.1


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


[PATCH 11/13] commands: firmwareload: allow loading firmware from dt

2021-01-21 Thread Steffen Trumtrar
From: Steffen Trumtrar 

firmwareload can only load a bitstream into an FPGA without any
knowledge of possible additional needs (e.g. FPGA bridges).

These are defined in the fpga-region nodes in the devicetree. The
fpga-region describes the layout of the FPGA and the bridges it needs
en/disabled.

Add an option to let firmwareload go via the oftree route and load the
firmware that way.

Signed-off-by: Steffen Trumtrar 
---
 commands/firmwareload.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/commands/firmwareload.c b/commands/firmwareload.c
index b735088f61..f2b7a74be0 100644
--- a/commands/firmwareload.c
+++ b/commands/firmwareload.c
@@ -5,18 +5,23 @@
 #include 
 #include 
 #include 
+#include 
 
 static int do_firmwareload(int argc, char *argv[])
 {
int ret, opt;
const char *name = NULL, *firmware;
struct firmware_mgr *mgr;
+   int oftree = 0;
 
-   while ((opt = getopt(argc, argv, "t:l")) > 0) {
+   while ((opt = getopt(argc, argv, "t:lo")) > 0) {
switch (opt) {
case 't':
name = optarg;
break;
+   case 'o':
+   oftree = 1;
+   break;
case 'l':
firmwaremgr_list_handlers();
return 0;
@@ -30,6 +35,11 @@ static int do_firmwareload(int argc, char *argv[])
 
firmware = argv[optind];
 
+   if (oftree) {
+   ret = of_firmware_load_file(firmware);
+   return ret;
+   }
+
mgr = firmwaremgr_find(name);
 
if (!mgr) {
@@ -46,6 +56,7 @@ static int do_firmwareload(int argc, char *argv[])
 BAREBOX_CMD_HELP_START(firmwareload)
 BAREBOX_CMD_HELP_TEXT("Options:")
 BAREBOX_CMD_HELP_OPT("-t ", "define the firmware handler by name")
+BAREBOX_CMD_HELP_OPT("-o\t", "find firmware definition from devicetree")
 BAREBOX_CMD_HELP_OPT("-l\t", "list devices capable of firmware loading")
 BAREBOX_CMD_HELP_END
 
-- 
2.20.1


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


[PATCH 03/13] firmware: socfpga: set APPLYCFG after loading bitstream

2021-01-21 Thread Steffen Trumtrar
From: Steffen Trumtrar 

To make changes to the SDRAM controller effective, the APPLYCFG bit must
be set after programming the bitstream to the FPGA. This has to be done
without any SDRAM usage. Therefore copy the function to execute to the
OCRAM and execute it from there.

Signed-off-by: Steffen Trumtrar 
---
 .../mach-socfpga/include/mach/cyclone5-regs.h |  1 +
 drivers/firmware/Makefile |  2 +-
 drivers/firmware/socfpga.c| 21 +++
 drivers/firmware/socfpga_sdr.S| 17 +++
 4 files changed, 40 insertions(+), 1 deletion(-)
 create mode 100644 drivers/firmware/socfpga_sdr.S

diff --git a/arch/arm/mach-socfpga/include/mach/cyclone5-regs.h 
b/arch/arm/mach-socfpga/include/mach/cyclone5-regs.h
index e88daf7189..1a7d787a27 100644
--- a/arch/arm/mach-socfpga/include/mach/cyclone5-regs.h
+++ b/arch/arm/mach-socfpga/include/mach/cyclone5-regs.h
@@ -18,5 +18,6 @@
 #define CYCLONE5_SYSMGR_ADDRESS0xffd08000
 #define CYCLONE5_SCANMGR_ADDRESS   0xfff02000
 #define CYCLONE5_SMP_TWD_ADDRESS   0xfffec600
+#define CYCLONE5_OCRAM_ADDRESS 0x
 
 #endif /* __MACH_SOCFPGA_REGS_H */
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index b162b08b0a..bbd2bcda97 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -1,3 +1,3 @@
 obj-$(CONFIG_FIRMWARE_ALTERA_SERIAL) += altera_serial.o
-obj-$(CONFIG_FIRMWARE_ALTERA_SOCFPGA) += socfpga.o
+obj-$(CONFIG_FIRMWARE_ALTERA_SOCFPGA) += socfpga.o socfpga_sdr.o
 obj-$(CONFIG_FIRMWARE_ZYNQMP_FPGA) += zynqmp-fpga.o
diff --git a/drivers/firmware/socfpga.c b/drivers/firmware/socfpga.c
index 393c78c45d..c468c74372 100644
--- a/drivers/firmware/socfpga.c
+++ b/drivers/firmware/socfpga.c
@@ -38,6 +38,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 
 #define FPGAMGRREGS_STAT   0x0
 #define FPGAMGRREGS_CTRL   0x4
@@ -77,6 +80,9 @@
 #define CDRATIO_x4 0x2
 #define CDRATIO_x8 0x3
 
+extern void socfpga_sdram_apply_static_cfg(void __iomem *sdrctrlgrp);
+extern void socfpga_sdram_apply_static_cfg_end(void *);
+
 struct fpgamgr {
struct firmware_handler fh;
struct device_d dev;
@@ -353,6 +359,9 @@ static int fpgamgr_program_finish(struct firmware_handler 
*fh)
 {
struct fpgamgr *mgr = container_of(fh, struct fpgamgr, fh);
int status;
+   unsigned int func_size = _sdram_apply_static_cfg_end -
+_sdram_apply_static_cfg;
+   void (*ocram_func)(void __iomem *ocram_base);
 
/* Ensure the FPGA entering config done */
status = fpgamgr_program_poll_cd(mgr);
@@ -382,6 +391,18 @@ static int fpgamgr_program_finish(struct firmware_handler 
*fh)
return status;
}
 
+   remap_range((void *)CYCLONE5_OCRAM_ADDRESS, PAGE_SIZE, MAP_CACHED);
+
+   dev_dbg(>dev, "Setting APPLYCFG bit...\n");
+
+   ocram_func = fncpy((void __iomem *)CYCLONE5_OCRAM_ADDRESS,
+  _sdram_apply_static_cfg, func_size);
+
+   sync_caches_for_execution();
+
+   ocram_func((void __iomem *) (CYCLONE5_SDR_ADDRESS +
+SDR_CTRLGRP_STATICCFG_ADDRESS));
+
return 0;
 }
 
diff --git a/drivers/firmware/socfpga_sdr.S b/drivers/firmware/socfpga_sdr.S
new file mode 100644
index 00..d634d63627
--- /dev/null
+++ b/drivers/firmware/socfpga_sdr.S
@@ -0,0 +1,17 @@
+#include 
+
+   .arch   armv7-a
+   .arm
+
+/*
+ * r0 : sdram controller staticcfg
+ */
+
+ENTRY(socfpga_sdram_apply_static_cfg)
+   push {ip,lr}
+   ldr r1, [r0]
+   orr r1, r1, #8
+   str r1, [r0]
+   pop {ip,pc}
+   .align
+ENTRY(socfpga_sdram_apply_static_cfg_end)
-- 
2.20.1


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


[PATCH 04/13] reset: add of_reset_control_get to header

2021-01-21 Thread Steffen Trumtrar
From: Steffen Trumtrar 

Signed-off-by: Steffen Trumtrar 
---
 drivers/reset/core.c  | 2 +-
 include/linux/reset.h | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/reset/core.c b/drivers/reset/core.c
index 26a54f21df..1c9eeaec54 100644
--- a/drivers/reset/core.c
+++ b/drivers/reset/core.c
@@ -147,7 +147,7 @@ EXPORT_SYMBOL_GPL(reset_control_deassert);
  *
  * Use of id names is optional.
  */
-static struct reset_control *of_reset_control_get(struct device_node *node,
+struct reset_control *of_reset_control_get(struct device_node *node,
  const char *id)
 {
struct reset_control *rstc;
diff --git a/include/linux/reset.h b/include/linux/reset.h
index 4a92a177bc..76f40145d9 100644
--- a/include/linux/reset.h
+++ b/include/linux/reset.h
@@ -11,6 +11,8 @@ int reset_control_assert(struct reset_control *rstc);
 int reset_control_deassert(struct reset_control *rstc);
 
 struct reset_control *reset_control_get(struct device_d *dev, const char *id);
+struct reset_control *of_reset_control_get(struct device_node *node,
+  const char *id);
 void reset_control_put(struct reset_control *rstc);
 
 int __must_check device_reset(struct device_d *dev);
-- 
2.20.1


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


[PATCH 01/13] ARM: add fncpy.h from linux v4.6

2021-01-21 Thread Steffen Trumtrar
From: Steffen Trumtrar 

Description from the linux commit 5756e9dd0de6d5c307773f8f734c0684b3098fdd:

ARM: 6640/1: Thumb-2: Symbol manipulation macros for function body copying

In low-level board support code, there is sometimes a need to
copy a function body to another location at run-time.

A straightforward call to memcpy doesn't work in Thumb-2,
because bit 0 of external Thumb function symbols is set to 1,
indicating that the function is Thumb.  Without corrective
measures, this will cause an off-by-one copy, and the copy
may be called using the wrong instruction set.

This patch adds an fncpy() macro to help with such copies.

Particular care is needed, because C doesn't guarantee any
defined behaviour when casting a function pointer to any other
type.  This has been observed to lead to strange optimisation
side-effects when doing the arithmetic which is required in
order to copy/move function bodies correctly in Thumb-2.

Thanks to Russell King and Nicolas Pitre for their input
on this patch.

Signed-off-by: Steffen Trumtrar 
---
 arch/arm/include/asm/fncpy.h | 82 
 1 file changed, 82 insertions(+)
 create mode 100644 arch/arm/include/asm/fncpy.h

diff --git a/arch/arm/include/asm/fncpy.h b/arch/arm/include/asm/fncpy.h
new file mode 100644
index 00..d13876bffa
--- /dev/null
+++ b/arch/arm/include/asm/fncpy.h
@@ -0,0 +1,82 @@
+/*
+ * arch/arm/include/asm/fncpy.h - helper macros for function body copying
+ *
+ * Copyright (C) 2011 Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * These macros are intended for use when there is a need to copy a low-level
+ * function body into special memory.
+ *
+ * For example, when reconfiguring the SDRAM controller, the code doing the
+ * reconfiguration may need to run from SRAM.
+ *
+ * NOTE: that the copied function body must be entirely self-contained and
+ * position-independent in order for this to work properly.
+ *
+ * NOTE: in order for embedded literals and data to get referenced correctly,
+ * the alignment of functions must be preserved when copying.  To ensure this,
+ * the source and destination addresses for fncpy() must be aligned to a
+ * multiple of 8 bytes: you will be get a BUG() if this condition is not met.
+ * You will typically need a ".align 3" directive in the assembler where the
+ * function to be copied is defined, and ensure that your allocator for the
+ * destination buffer returns 8-byte-aligned pointers.
+ *
+ * Typical usage example:
+ *
+ * extern int f(args);
+ * extern uint32_t size_of_f;
+ * int (*copied_f)(args);
+ * void *sram_buffer;
+ *
+ * copied_f = fncpy(sram_buffer, , size_of_f);
+ *
+ * ... later, call the function: ...
+ *
+ * copied_f(args);
+ *
+ * The size of the function to be copied can't be determined from C:
+ * this must be determined by other means, such as adding assmbler directives
+ * in the file where f is defined.
+ */
+
+#ifndef __ASM_FNCPY_H
+#define __ASM_FNCPY_H
+
+#include 
+#include 
+
+/*
+ * Minimum alignment requirement for the source and destination addresses
+ * for function copying.
+ */
+#define FNCPY_ALIGN 8
+
+#define fncpy(dest_buf, funcp, size) ({
\
+   uintptr_t __funcp_address;  \
+   typeof(funcp) __result; \
+   \
+   asm("" : "=r" (__funcp_address) : "0" (funcp)); \
+   \
+   memcpy(dest_buf, (void const *)(__funcp_address & ~1), size);   \
+   \
+   asm("" : "=r" (__result)\
+   : "0" ((uintptr_t)(dest_buf) | (__funcp_address & 1))); \
+   \
+   __result;   \
+})
+
+#endif /* !__ASM_FNCPY_H */
-- 
2.20.1


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


[PATCH 07/13] firmware: socfpga: change function prefixes

2021-01-21 Thread Steffen Trumtrar
From: Steffen Trumtrar 

Since there is now a fpgamgr framework in barebox, the function names are
misleading. Change that to be SoCFPGA specific.

Signed-off-by: Steffen Trumtrar 
---
 drivers/firmware/socfpga.c | 58 +++---
 1 file changed, 29 insertions(+), 29 deletions(-)

diff --git a/drivers/firmware/socfpga.c b/drivers/firmware/socfpga.c
index c468c74372..14875214b1 100644
--- a/drivers/firmware/socfpga.c
+++ b/drivers/firmware/socfpga.c
@@ -92,12 +92,12 @@ struct fpgamgr {
 };
 
 /* Get the FPGA mode */
-static uint32_t fpgamgr_get_mode(struct fpgamgr *mgr)
+static uint32_t socfpga_fpgamgr_get_mode(struct fpgamgr *mgr)
 {
return readl(mgr->regs + FPGAMGRREGS_STAT) & FPGAMGRREGS_STAT_MODE_MASK;
 }
 
-static int fpgamgr_dclkcnt_set(struct fpgamgr *mgr, unsigned long cnt)
+static int socfpga_fpgamgr_dclkcnt_set(struct fpgamgr *mgr, unsigned long cnt)
 {
uint64_t start;
 
@@ -121,7 +121,7 @@ static int fpgamgr_dclkcnt_set(struct fpgamgr *mgr, 
unsigned long cnt)
 }
 
 /* Start the FPGA programming by initialize the FPGA Manager */
-static int fpgamgr_program_init(struct fpgamgr *mgr)
+static int socfpga_fpgamgr_program_init(struct fpgamgr *mgr)
 {
unsigned long reg;
uint32_t ctrl = 0, ratio;
@@ -170,7 +170,7 @@ static int fpgamgr_program_init(struct fpgamgr *mgr)
/* (1) wait until FPGA enter reset phase */
start = get_time_ns();
while (1) {
-   if (fpgamgr_get_mode(mgr) == FPGAMGRREGS_MODE_RESETPHASE)
+   if (socfpga_fpgamgr_get_mode(mgr) == 
FPGAMGRREGS_MODE_RESETPHASE)
break;
if (is_timeout(start, 100 * MSECOND))
return -ETIMEDOUT;
@@ -184,7 +184,7 @@ static int fpgamgr_program_init(struct fpgamgr *mgr)
/* (2) wait until FPGA enter configuration phase */
start = get_time_ns();
while (1) {
-   if (fpgamgr_get_mode(mgr) == FPGAMGRREGS_MODE_CFGPHASE)
+   if (socfpga_fpgamgr_get_mode(mgr) == FPGAMGRREGS_MODE_CFGPHASE)
break;
if (is_timeout(start, 100 * MSECOND))
return -ETIMEDOUT;
@@ -202,7 +202,7 @@ static int fpgamgr_program_init(struct fpgamgr *mgr)
 }
 
 /* Ensure the FPGA entering config done */
-static int fpgamgr_program_poll_cd(struct fpgamgr *mgr)
+static int socfpga_fpgamgr_program_poll_cd(struct fpgamgr *mgr)
 {
unsigned long reg;
uint32_t val;
@@ -236,18 +236,18 @@ static int fpgamgr_program_poll_cd(struct fpgamgr *mgr)
 }
 
 /* Ensure the FPGA entering init phase */
-static int fpgamgr_program_poll_initphase(struct fpgamgr *mgr)
+static int socfpga_fpgamgr_program_poll_initphase(struct fpgamgr *mgr)
 {
uint64_t start;
 
/* additional clocks for the CB to enter initialization phase */
-   if (fpgamgr_dclkcnt_set(mgr, 0x4) != 0)
+   if (socfpga_fpgamgr_dclkcnt_set(mgr, 0x4) != 0)
return -5;
 
/* (4) wait until FPGA enter init phase or user mode */
start = get_time_ns();
while (1) {
-   int mode = fpgamgr_get_mode(mgr);
+   int mode = socfpga_fpgamgr_get_mode(mgr);
 
if (mode == FPGAMGRREGS_MODE_INITPHASE ||
mode == FPGAMGRREGS_MODE_USERMODE)
@@ -261,19 +261,19 @@ static int fpgamgr_program_poll_initphase(struct fpgamgr 
*mgr)
 }
 
 /* Ensure the FPGA entering user mode */
-static int fpgamgr_program_poll_usermode(struct fpgamgr *mgr)
+static int socfpga_fpgamgr_program_poll_usermode(struct fpgamgr *mgr)
 {
uint32_t val;
uint64_t start;
 
/* additional clocks for the CB to exit initialization phase */
-   if (fpgamgr_dclkcnt_set(mgr, 0x5000) != 0)
+   if (socfpga_fpgamgr_dclkcnt_set(mgr, 0x5000) != 0)
return -7;
 
/* (5) wait until FPGA enter user mode */
start = get_time_ns();
while (1) {
-   if (fpgamgr_get_mode(mgr) == FPGAMGRREGS_MODE_USERMODE)
+   if (socfpga_fpgamgr_get_mode(mgr) == FPGAMGRREGS_MODE_USERMODE)
break;
if (is_timeout(start, 100 * MSECOND))
return -ETIMEDOUT;
@@ -291,7 +291,7 @@ static int fpgamgr_program_poll_usermode(struct fpgamgr 
*mgr)
  * Using FPGA Manager to program the FPGA
  * Return 0 for sucess
  */
-static int fpgamgr_program_start(struct firmware_handler *fh)
+static int socfpga_fpgamgr_program_start(struct firmware_handler *fh)
 {
struct fpgamgr *mgr = container_of(fh, struct fpgamgr, fh);
int status;
@@ -313,7 +313,7 @@ static int fpgamgr_program_start(struct firmware_handler 
*fh)
dev_dbg(>dev, "start programming...\n");
 
/* initialize the FPGA Manager */
-   status = fpgamgr_program_init(mgr);
+   status = socfpga_fpgamgr_program_init(mgr);
if (status) {
dev_err(>dev, "pr

[PATCH 10/13] of: of_firmware: add support for fpga bridges

2021-01-21 Thread Steffen Trumtrar
From: Steffen Trumtrar 

Add support for potentially defined FPGA-bridges in the overlay.

While at it also add support for loading the firmware directly via a
path instead of 'needing' an overlay for that.
The direct loading will be done with the existent firmwareload command.

Signed-off-by: Steffen Trumtrar 
---
 drivers/of/Makefile  |  3 +-
 drivers/of/of_firmware.c | 88 
 include/of.h | 21 +++---
 3 files changed, 96 insertions(+), 16 deletions(-)

diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index b6847752d2..6199c9791f 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -6,4 +6,5 @@ obj-y += partition.o
 obj-y += of_net.o
 obj-$(CONFIG_MTD) += of_mtd.o
 obj-$(CONFIG_OF_BAREBOX_DRIVERS) += barebox.o
-obj-$(CONFIG_OF_OVERLAY) += overlay.o resolver.o of_firmware.o
+obj-$(CONFIG_OF_OVERLAY) += overlay.o resolver.o
+obj-$(CONFIG_FIRMWARE) += of_firmware.o
diff --git a/drivers/of/of_firmware.c b/drivers/of/of_firmware.c
index 096f84572e..ef0ccd0221 100644
--- a/drivers/of/of_firmware.c
+++ b/drivers/of/of_firmware.c
@@ -4,12 +4,52 @@
  */
 #include 
 #include 
+#include 
 #include 
 
 struct overlay_info {
const char *firmware_path;
 };
 
+#ifdef CONFIG_FPGA_BRIDGE 
+static int of_get_bridges(struct device_node *region, struct list_head 
*bridges)
+{
+   struct device_node *br, *parent_br = NULL;
+   int i, ret;
+
+   /* If parent is a bridge, add to list */
+   ret = fpga_bridge_get_to_list(region->parent, bridges);
+   if (!ret) {
+   parent_br = region->parent;
+   pr_debug("Add %s to list of bridges\n", parent_br->name);
+   }
+
+   for (i = 0; ; i++) {
+   br = of_parse_phandle(region, "fpga-bridges", i);
+   if (!br)
+   break;
+
+   /* If parent bridge is in list, skip it. */
+   if (br == parent_br)
+   continue;
+
+   /* If node is a bridge, get it and add to list */
+   ret = fpga_bridge_get_to_list(br, bridges);
+   if (ret)
+   return ret;
+
+   pr_debug("Add %s to list of bridges\n", br->name);
+   }
+
+   return 0;
+}
+#else
+static int of_get_bridges(struct device_node *np, struct list_head *br)
+{
+   return 0;
+}
+#endif
+
 static struct firmware_mgr *of_node_get_mgr(struct device_node *np)
 {
struct device_node *mgr_node;
@@ -25,15 +65,49 @@ static struct firmware_mgr *of_node_get_mgr(struct 
device_node *np)
return NULL;
 }
 
-static int load_firmware(struct device_node *target,
-struct device_node *fragment, void *data)
+static int of_load_firmware(struct device_node *target, const char *path)
+{
+   struct list_head bridge_list;
+   struct firmware_mgr *mgr;
+   int err;
+
+   mgr = of_node_get_mgr(target);
+   if (!mgr)
+   return -EINVAL;
+
+   INIT_LIST_HEAD(_list);
+
+   of_get_bridges(target, _list);
+
+   fpga_bridges_disable(_list);
+
+   err = firmwaremgr_load_file(mgr, path);
+
+   fpga_bridges_enable(_list);
+
+   return err;
+}
+
+int of_firmware_load_file(const char *path)
+{
+   int err;
+   struct device_node *target;
+
+   target = of_find_compatible_node(NULL, NULL, "fpga-region");
+
+   err = of_load_firmware(target, path);
+
+   return err;
+}
+
+static int load_overlay(struct device_node *target,
+   struct device_node *fragment, void *data)
 {
struct overlay_info *info = data;
const char *firmware_name;
const char *firmware_path = info->firmware_path;
char *firmware;
int err;
-   struct firmware_mgr *mgr;
 
err = of_property_read_string(fragment,
  "firmware-name", _name);
@@ -46,15 +120,11 @@ static int load_firmware(struct device_node *target,
if (!target)
return -EINVAL;
 
-   mgr = of_node_get_mgr(target);
-   if (!mgr)
-   return -EINVAL;
-
firmware = basprintf("%s/%s", firmware_path, firmware_name);
if (!firmware)
return -ENOMEM;
 
-   err = firmwaremgr_load_file(mgr, firmware);
+   err = of_load_firmware(target, firmware);
 
free(firmware);
 
@@ -82,7 +152,7 @@ int of_firmware_load_overlay(struct device_node *overlay, 
const char *path)
ovl = resolved ? resolved : overlay;
 
err = of_process_overlay(root, ovl,
-load_firmware, );
+load_overlay, );
 
if (resolved)
of_delete_node(resolved);
diff --git a/include/of.h b/include/of.h
index 645f429bde..e3deec9b4c 100644
--- a/include/of.h
+++ b/include/of.h
@@ -1020,6 +1020,21 @@ static inline struct device_node 
*of

[PATCH 09/13] of: kconfig: of_overlay uses firmwaremgr_load_file

2021-01-21 Thread Steffen Trumtrar
As of_firmware.c uses the firmwaremgr_load_file function, it depends on
FIRMWARE.

Signed-off-by: Steffen Trumtrar 
---
 drivers/of/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 23be25d85d..e58fe50f70 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -49,6 +49,7 @@ config OF_BAREBOX_ENV_IN_FS
 
 config OF_OVERLAY
select OFTREE
+   select FIRMWARE
bool "Devicetree overlays"
help
  Overlays allow to patch the devicetree. Unlike Linux, Barebox does
-- 
2.20.1


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


Re: [PATCH 10/13] of: of_firmware: add support for fpga bridges

2021-01-26 Thread Steffen Trumtrar


Sascha Hauer  writes:

> On Thu, Jan 21, 2021 at 12:29:55PM +0100, Steffen Trumtrar wrote:
>> From: Steffen Trumtrar 
>>
>> Add support for potentially defined FPGA-bridges in the overlay.
>>
>> While at it also add support for loading the firmware directly via a
>> path instead of 'needing' an overlay for that.
>> The direct loading will be done with the existent firmwareload command.
>>
>> Signed-off-by: Steffen Trumtrar 
>> ---
>>  drivers/of/Makefile  |  3 +-
>>  drivers/of/of_firmware.c | 88 
>>  include/of.h | 21 +++---
>>  3 files changed, 96 insertions(+), 16 deletions(-)
>>
>> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
>> index b6847752d2..6199c9791f 100644
>> --- a/drivers/of/Makefile
>> +++ b/drivers/of/Makefile
>> @@ -6,4 +6,5 @@ obj-y += partition.o
>>  obj-y += of_net.o
>>  obj-$(CONFIG_MTD) += of_mtd.o
>>  obj-$(CONFIG_OF_BAREBOX_DRIVERS) += barebox.o
>> -obj-$(CONFIG_OF_OVERLAY) += overlay.o resolver.o of_firmware.o
>> +obj-$(CONFIG_OF_OVERLAY) += overlay.o resolver.o
>> +obj-$(CONFIG_FIRMWARE) += of_firmware.o
>> diff --git a/drivers/of/of_firmware.c b/drivers/of/of_firmware.c
>> index 096f84572e..ef0ccd0221 100644
>> --- a/drivers/of/of_firmware.c
>> +++ b/drivers/of/of_firmware.c
>> @@ -4,12 +4,52 @@
>>   */
>>  #include 
>>  #include 
>> +#include 
>>  #include 
>>
>>  struct overlay_info {
>>  const char *firmware_path;
>>  };
>>
>> +#ifdef CONFIG_FPGA_BRIDGE
>
> Trailing whitespace here.
>

Meh :(

>> +int of_firmware_load_file(const char *path)
>> +{
>> +int err;
>> +struct device_node *target;
>> +
>> +target = of_find_compatible_node(NULL, NULL, "fpga-region");
>
> This assumes there is only one node compatible to fpga-region. What
> about others?

Ah, right, it is actually allowed to have multiple regions in one FPGA.
I didn't think about that.


Steffen

--
Pengutronix e.K.| Dipl.-Inform. Steffen Trumtrar |
Steuerwalder Str. 21| https://www.pengutronix.de/|
31137 Hildesheim, Germany   | Phone: +49-5121-206917-0   |
Amtsgericht Hildesheim, HRA 2686| Fax:   +49-5121-206917-|

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


[PATCH v2 01/12] ARM: mmu: inherit pte flags from pmd

2021-01-27 Thread Steffen Trumtrar
From: Sascha Hauer 

When creating a 2nd level page table from a section inherit the flags
from the section rather than assuming the section was mapped cached
previously. This fixes creating a 2nd level pagetable when the section
was mapped differently than we expected.

Signed-off-by: Sascha Hauer 
---
 arch/arm/cpu/mmu.c | 28 
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c
index 6af228505dd1..6388e1bf14f6 100644
--- a/arch/arm/cpu/mmu.c
+++ b/arch/arm/cpu/mmu.c
@@ -138,6 +138,29 @@ static u32 *arm_create_pte(unsigned long virt, uint32_t 
flags)
return table;
 }
 
+static u32 pmd_flags_to_pte(u32 pmd)
+{
+   u32 pte = 0;
+
+   if (pmd & PMD_SECT_BUFFERABLE)
+   pte |= PTE_BUFFERABLE;
+   if (pmd & PMD_SECT_CACHEABLE)
+   pte |= PTE_CACHEABLE;
+   if (pmd & PMD_SECT_nG)
+   pte |= PTE_EXT_NG;
+   if (pmd & PMD_SECT_XN)
+   pte |= PTE_EXT_XN;
+
+   /* TEX[2:0] */
+   pte |= PTE_EXT_TEX((pmd >> 12) & 7);
+   /* AP[1:0] */
+   pte |= ((pmd >> 10) & 0x3) << 4;
+   /* AP[2] */
+   pte |= ((pmd >> 15) & 0x1) << 9;
+
+   return pte;
+}
+
 int arch_remap_range(void *start, size_t size, unsigned flags)
 {
u32 addr = (u32)start;
@@ -206,11 +229,8 @@ int arch_remap_range(void *start, size_t size, unsigned 
flags)
 * If PTE is not found it means that
 * we needs to split this section and
 * create a new page table for it
-*
-* NOTE: Here we assume that section
-* we just split was mapped as cached
 */
-   table = arm_create_pte(addr, pte_flags_cached);
+   table = arm_create_pte(addr, 
pmd_flags_to_pte(*pgd));
pte = find_pte(addr);
BUG_ON(!pte);
}
-- 
2.20.1


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


[PATCH v2 06/12] firmware: socfpga: change function prefixes

2021-01-27 Thread Steffen Trumtrar
Since there is now a fpgamgr framework in barebox, the function names are
misleading. Change that to be SoCFPGA specific.

Signed-off-by: Steffen Trumtrar 
---
 drivers/firmware/socfpga.c | 58 +++---
 1 file changed, 29 insertions(+), 29 deletions(-)

diff --git a/drivers/firmware/socfpga.c b/drivers/firmware/socfpga.c
index c468c743720f..14875214b1aa 100644
--- a/drivers/firmware/socfpga.c
+++ b/drivers/firmware/socfpga.c
@@ -92,12 +92,12 @@ struct fpgamgr {
 };
 
 /* Get the FPGA mode */
-static uint32_t fpgamgr_get_mode(struct fpgamgr *mgr)
+static uint32_t socfpga_fpgamgr_get_mode(struct fpgamgr *mgr)
 {
return readl(mgr->regs + FPGAMGRREGS_STAT) & FPGAMGRREGS_STAT_MODE_MASK;
 }
 
-static int fpgamgr_dclkcnt_set(struct fpgamgr *mgr, unsigned long cnt)
+static int socfpga_fpgamgr_dclkcnt_set(struct fpgamgr *mgr, unsigned long cnt)
 {
uint64_t start;
 
@@ -121,7 +121,7 @@ static int fpgamgr_dclkcnt_set(struct fpgamgr *mgr, 
unsigned long cnt)
 }
 
 /* Start the FPGA programming by initialize the FPGA Manager */
-static int fpgamgr_program_init(struct fpgamgr *mgr)
+static int socfpga_fpgamgr_program_init(struct fpgamgr *mgr)
 {
unsigned long reg;
uint32_t ctrl = 0, ratio;
@@ -170,7 +170,7 @@ static int fpgamgr_program_init(struct fpgamgr *mgr)
/* (1) wait until FPGA enter reset phase */
start = get_time_ns();
while (1) {
-   if (fpgamgr_get_mode(mgr) == FPGAMGRREGS_MODE_RESETPHASE)
+   if (socfpga_fpgamgr_get_mode(mgr) == 
FPGAMGRREGS_MODE_RESETPHASE)
break;
if (is_timeout(start, 100 * MSECOND))
return -ETIMEDOUT;
@@ -184,7 +184,7 @@ static int fpgamgr_program_init(struct fpgamgr *mgr)
/* (2) wait until FPGA enter configuration phase */
start = get_time_ns();
while (1) {
-   if (fpgamgr_get_mode(mgr) == FPGAMGRREGS_MODE_CFGPHASE)
+   if (socfpga_fpgamgr_get_mode(mgr) == FPGAMGRREGS_MODE_CFGPHASE)
break;
if (is_timeout(start, 100 * MSECOND))
return -ETIMEDOUT;
@@ -202,7 +202,7 @@ static int fpgamgr_program_init(struct fpgamgr *mgr)
 }
 
 /* Ensure the FPGA entering config done */
-static int fpgamgr_program_poll_cd(struct fpgamgr *mgr)
+static int socfpga_fpgamgr_program_poll_cd(struct fpgamgr *mgr)
 {
unsigned long reg;
uint32_t val;
@@ -236,18 +236,18 @@ static int fpgamgr_program_poll_cd(struct fpgamgr *mgr)
 }
 
 /* Ensure the FPGA entering init phase */
-static int fpgamgr_program_poll_initphase(struct fpgamgr *mgr)
+static int socfpga_fpgamgr_program_poll_initphase(struct fpgamgr *mgr)
 {
uint64_t start;
 
/* additional clocks for the CB to enter initialization phase */
-   if (fpgamgr_dclkcnt_set(mgr, 0x4) != 0)
+   if (socfpga_fpgamgr_dclkcnt_set(mgr, 0x4) != 0)
return -5;
 
/* (4) wait until FPGA enter init phase or user mode */
start = get_time_ns();
while (1) {
-   int mode = fpgamgr_get_mode(mgr);
+   int mode = socfpga_fpgamgr_get_mode(mgr);
 
if (mode == FPGAMGRREGS_MODE_INITPHASE ||
mode == FPGAMGRREGS_MODE_USERMODE)
@@ -261,19 +261,19 @@ static int fpgamgr_program_poll_initphase(struct fpgamgr 
*mgr)
 }
 
 /* Ensure the FPGA entering user mode */
-static int fpgamgr_program_poll_usermode(struct fpgamgr *mgr)
+static int socfpga_fpgamgr_program_poll_usermode(struct fpgamgr *mgr)
 {
uint32_t val;
uint64_t start;
 
/* additional clocks for the CB to exit initialization phase */
-   if (fpgamgr_dclkcnt_set(mgr, 0x5000) != 0)
+   if (socfpga_fpgamgr_dclkcnt_set(mgr, 0x5000) != 0)
return -7;
 
/* (5) wait until FPGA enter user mode */
start = get_time_ns();
while (1) {
-   if (fpgamgr_get_mode(mgr) == FPGAMGRREGS_MODE_USERMODE)
+   if (socfpga_fpgamgr_get_mode(mgr) == FPGAMGRREGS_MODE_USERMODE)
break;
if (is_timeout(start, 100 * MSECOND))
return -ETIMEDOUT;
@@ -291,7 +291,7 @@ static int fpgamgr_program_poll_usermode(struct fpgamgr 
*mgr)
  * Using FPGA Manager to program the FPGA
  * Return 0 for sucess
  */
-static int fpgamgr_program_start(struct firmware_handler *fh)
+static int socfpga_fpgamgr_program_start(struct firmware_handler *fh)
 {
struct fpgamgr *mgr = container_of(fh, struct fpgamgr, fh);
int status;
@@ -313,7 +313,7 @@ static int fpgamgr_program_start(struct firmware_handler 
*fh)
dev_dbg(>dev, "start programming...\n");
 
/* initialize the FPGA Manager */
-   status = fpgamgr_program_init(mgr);
+   status = socfpga_fpgamgr_program_init(mgr);
if (status) {
dev_err(>dev, "pr

[PATCH v2 03/12] reset: add of_reset_control_get to header

2021-01-27 Thread Steffen Trumtrar
Signed-off-by: Steffen Trumtrar 
---
 drivers/reset/core.c  | 2 +-
 include/linux/reset.h | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/reset/core.c b/drivers/reset/core.c
index 26a54f21dff0..1c9eeaec5491 100644
--- a/drivers/reset/core.c
+++ b/drivers/reset/core.c
@@ -147,7 +147,7 @@ EXPORT_SYMBOL_GPL(reset_control_deassert);
  *
  * Use of id names is optional.
  */
-static struct reset_control *of_reset_control_get(struct device_node *node,
+struct reset_control *of_reset_control_get(struct device_node *node,
  const char *id)
 {
struct reset_control *rstc;
diff --git a/include/linux/reset.h b/include/linux/reset.h
index 4a92a177bc75..76f40145d949 100644
--- a/include/linux/reset.h
+++ b/include/linux/reset.h
@@ -11,6 +11,8 @@ int reset_control_assert(struct reset_control *rstc);
 int reset_control_deassert(struct reset_control *rstc);
 
 struct reset_control *reset_control_get(struct device_d *dev, const char *id);
+struct reset_control *of_reset_control_get(struct device_node *node,
+  const char *id);
 void reset_control_put(struct reset_control *rstc);
 
 int __must_check device_reset(struct device_d *dev);
-- 
2.20.1


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


[PATCH v2 09/12] of: of_firmware: add support for fpga bridges

2021-01-27 Thread Steffen Trumtrar
Add support for potentially defined FPGA-bridges in the overlay.

While at it also add support for loading the firmware directly via a
path instead of 'needing' an overlay for that.
The direct loading will be done with the existent firmwareload command.

Signed-off-by: Steffen Trumtrar 
---
 drivers/of/Makefile  |   3 +-
 drivers/of/of_firmware.c | 130 +--
 include/of.h |  23 +--
 3 files changed, 143 insertions(+), 13 deletions(-)

diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index b6847752d247..6199c9791f52 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -6,4 +6,5 @@ obj-y += partition.o
 obj-y += of_net.o
 obj-$(CONFIG_MTD) += of_mtd.o
 obj-$(CONFIG_OF_BAREBOX_DRIVERS) += barebox.o
-obj-$(CONFIG_OF_OVERLAY) += overlay.o resolver.o of_firmware.o
+obj-$(CONFIG_OF_OVERLAY) += overlay.o resolver.o
+obj-$(CONFIG_FIRMWARE) += of_firmware.o
diff --git a/drivers/of/of_firmware.c b/drivers/of/of_firmware.c
index 096f84572e63..ff5ac60e9fd5 100644
--- a/drivers/of/of_firmware.c
+++ b/drivers/of/of_firmware.c
@@ -4,12 +4,52 @@
  */
 #include 
 #include 
+#include 
 #include 
 
 struct overlay_info {
const char *firmware_path;
 };
 
+#ifdef CONFIG_FPGA_BRIDGE
+static int of_get_bridges(struct device_node *region, struct list_head 
*bridges)
+{
+   struct device_node *br, *parent_br = NULL;
+   int i, ret;
+
+   /* If parent is a bridge, add to list */
+   ret = fpga_bridge_get_to_list(region->parent, bridges);
+   if (!ret) {
+   parent_br = region->parent;
+   pr_debug("Add %s to list of bridges\n", parent_br->name);
+   }
+
+   for (i = 0; ; i++) {
+   br = of_parse_phandle(region, "fpga-bridges", i);
+   if (!br)
+   break;
+
+   /* If parent bridge is in list, skip it. */
+   if (br == parent_br)
+   continue;
+
+   /* If node is a bridge, get it and add to list */
+   ret = fpga_bridge_get_to_list(br, bridges);
+   if (ret)
+   return ret;
+
+   pr_debug("Add %s to list of bridges\n", br->name);
+   }
+
+   return 0;
+}
+#else
+static int of_get_bridges(struct device_node *np, struct list_head *br)
+{
+   return 0;
+}
+#endif
+
 static struct firmware_mgr *of_node_get_mgr(struct device_node *np)
 {
struct device_node *mgr_node;
@@ -25,6 +65,33 @@ static struct firmware_mgr *of_node_get_mgr(struct 
device_node *np)
return NULL;
 }
 
+static int of_load_firmware(struct device_node *target, const char *path)
+{
+   struct list_head bridge_list;
+   struct firmware_mgr *mgr;
+   int err;
+
+   mgr = of_node_get_mgr(target);
+   if (!mgr)
+   return -EINVAL;
+
+   pr_debug("Found firmware manager @%s\n", target->name);
+
+   INIT_LIST_HEAD(_list);
+
+   of_get_bridges(target, _list);
+
+   fpga_bridges_disable(_list);
+
+   pr_debug("Loading %s to %s\n", path, target->name);
+
+   err = firmwaremgr_load_file(mgr, path);
+
+   fpga_bridges_enable(_list);
+
+   return err;
+}
+
 static int load_firmware(struct device_node *target,
 struct device_node *fragment, void *data)
 {
@@ -33,7 +100,6 @@ static int load_firmware(struct device_node *target,
const char *firmware_path = info->firmware_path;
char *firmware;
int err;
-   struct firmware_mgr *mgr;
 
err = of_property_read_string(fragment,
  "firmware-name", _name);
@@ -46,21 +112,73 @@ static int load_firmware(struct device_node *target,
if (!target)
return -EINVAL;
 
-   mgr = of_node_get_mgr(target);
-   if (!mgr)
-   return -EINVAL;
-
firmware = basprintf("%s/%s", firmware_path, firmware_name);
if (!firmware)
return -ENOMEM;
 
-   err = firmwaremgr_load_file(mgr, firmware);
+   err = of_load_firmware(target, firmware);
 
free(firmware);
 
return err;
 }
 
+int of_firmware_load_file(const char *path, const char *compatible,
+ const char *search_path, const char *firmware)
+{
+   struct overlay_info info = {
+   .firmware_path = search_path,
+   };
+   struct device_node *target;
+   struct device_node *node;
+   struct device_node *root;
+
+   if (!compatible) {
+   compatible = basprintf("fpga-region");
+   if (!compatible)
+   return -ENOMEM;
+   }
+
+   /*
+* firmware-name not specified. Use load_firmware function to get it 
from
+* the devicetree. This allows loading firmware to multiple devices.
+*/
+   if (!firmware && !path) {
+ 

[PATCH v2 05/12] drivers: fpga: add socfpga bridges

2021-01-27 Thread Steffen Trumtrar
Import the SoCFPGA bridges drivers from linux v4.10-rc2.

Description from the original commit:
e5f8efa5c8bf86c1fa698551d54db8f6aee221fd

ARM: socfpga: fpga bridge driver support

Supports Altera SOCFPGA bridges:
 * fpga2sdram
 * fpga2hps
 * hps2fpga
 * lwhps2fpga

Allows enabling/disabling the bridges through the FPGA
Bridge Framework API functions.

The fpga2sdram driver only supports enabling and disabling
of the ports that been configured early on.  This is due to
a hardware limitation where the read, write, and command
ports on the fpga2sdram bridge can only be reconfigured
while there are no transactions to the sdram, i.e. when
running out of OCRAM before the kernel boots.

Device tree property 'init-val' configures the driver to
enable or disable the bridge during probe.  If the property
does not exist, the driver will leave the bridge in its
current state.

Signed-off-by: Alan Tull 
Signed-off-by: Matthew Gerlach 
Signed-off-by: Dinh Nguyen 
Signed-off-by: Greg Kroah-Hartman 

Signed-off-by: Steffen Trumtrar 
---
 drivers/fpga/Kconfig |   8 +
 drivers/fpga/Makefile|   1 +
 drivers/fpga/fpga-bridge.c   |   2 +-
 drivers/fpga/socfpga-fpga2sdram-bridge.c | 139 ++
 drivers/fpga/socfpga-hps2fpga-bridge.c   | 179 +++
 5 files changed, 328 insertions(+), 1 deletion(-)
 create mode 100644 drivers/fpga/socfpga-fpga2sdram-bridge.c
 create mode 100644 drivers/fpga/socfpga-hps2fpga-bridge.c

diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index fccdbff6eb3f..64ce9f91b6a8 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -17,6 +17,14 @@ config FPGA_BRIDGE
  Say Y here if you want to support bridges connected between host
  processors and FPGAs or between FPGAs.
 
+config SOCFPGA_FPGA_BRIDGE
+   tristate "Altera SoCFPGA FPGA Bridges"
+   depends on ARCH_SOCFPGA && FPGA_BRIDGE
+   select RESET_CONTROLLER
+   help
+ Say Y to enable drivers for FPGA bridges for Altera SOCFPGA
+ devices.
+
 endif # FPGA
 
 endmenu
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index fc71a29d3b33..86178fe7c078 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -4,3 +4,4 @@
 
 # FPGA Bridge Drivers
 obj-$(CONFIG_FPGA_BRIDGE)  += fpga-bridge.o
+obj-$(CONFIG_SOCFPGA_FPGA_BRIDGE)  += socfpga-hps2fpga-bridge.o 
socfpga-fpga2sdram-bridge.o
diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c
index edf29b0ecf13..b5c74a6e63d4 100644
--- a/drivers/fpga/fpga-bridge.c
+++ b/drivers/fpga/fpga-bridge.c
@@ -68,7 +68,7 @@ struct fpga_bridge *of_fpga_bridge_get(struct device_node *np)
 {
struct device_d *dev;
struct fpga_bridge *bridge;
-   int ret = -ENODEV;
+   int ret = -EPROBE_DEFER;
 
dev = of_find_device_by_node(np);
if (!dev || !dev->priv)
diff --git a/drivers/fpga/socfpga-fpga2sdram-bridge.c 
b/drivers/fpga/socfpga-fpga2sdram-bridge.c
new file mode 100644
index ..a9760597ddb5
--- /dev/null
+++ b/drivers/fpga/socfpga-fpga2sdram-bridge.c
@@ -0,0 +1,139 @@
+/*
+ * FPGA to SDRAM Bridge Driver for Altera SoCFPGA Devices
+ *
+ *  Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This driver manages a bridge between an FPGA and the SDRAM used by the ARM
+ * host processor system (HPS).
+ *
+ * The bridge contains 4 read ports, 4 write ports, and 6 command ports.
+ * Reconfiguring these ports requires that no SDRAM transactions occur during
+ * reconfiguration.  The code reconfiguring the ports cannot run out of SDRAM
+ * nor can the FPGA access the SDRAM during reconfiguration.  This driver does
+ * not support reconfiguring the ports.  The ports are configured by code
+ * running out of on chip ram before Linux is started and the configuration
+ * is passed in a handoff register in the system manager.
+ *
+ * This driver supports enabling and disabling of the configured ports, which
+ * allows for safe reprogramming of the FPGA, assuming that the new FPGA image
+ * uses the same port configuration.  Bridges must be disabled before
+ * reprogramming the FPGA and re-enabled after the FPGA has been programmed.
+ */
+
+#include 
+#include 
+#in

[PATCH v2 07/12] firmware: import fpga-mgr.h from linux

2021-01-27 Thread Steffen Trumtrar
Instead of defining the fpga-mgr structure in the socfpga driver, import
the fpga-mgr.h file from linux v4.13.

Signed-off-by: Steffen Trumtrar 
---
 drivers/firmware/socfpga.c |   9 +---
 include/firmware.h |   1 +
 include/fpga-mgr.h | 102 +
 3 files changed, 104 insertions(+), 8 deletions(-)
 create mode 100644 include/fpga-mgr.h

diff --git a/drivers/firmware/socfpga.c b/drivers/firmware/socfpga.c
index 14875214b1aa..605c931604c9 100644
--- a/drivers/firmware/socfpga.c
+++ b/drivers/firmware/socfpga.c
@@ -27,6 +27,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -83,14 +84,6 @@
 extern void socfpga_sdram_apply_static_cfg(void __iomem *sdrctrlgrp);
 extern void socfpga_sdram_apply_static_cfg_end(void *);
 
-struct fpgamgr {
-   struct firmware_handler fh;
-   struct device_d dev;
-   void __iomem *regs;
-   void __iomem *regs_data;
-   int programmed;
-};
-
 /* Get the FPGA mode */
 static uint32_t socfpga_fpgamgr_get_mode(struct fpgamgr *mgr)
 {
diff --git a/include/firmware.h b/include/firmware.h
index 19777d9bf711..2fef97a48f56 100644
--- a/include/firmware.h
+++ b/include/firmware.h
@@ -13,6 +13,7 @@ struct firmware_handler {
char *id; /* unique identifier for this firmware device */
char *model; /* description for this device */
struct device_d *dev;
+   void *priv;
/* called once to prepare the firmware's programming cycle */
int (*open)(struct firmware_handler*);
/* called multiple times to program the firmware with the given data */
diff --git a/include/fpga-mgr.h b/include/fpga-mgr.h
new file mode 100644
index ..a120b3918990
--- /dev/null
+++ b/include/fpga-mgr.h
@@ -0,0 +1,102 @@
+/*
+ * FPGA Framework
+ *
+ *  Copyright (C) 2013-2015 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _LINUX_FPGA_MGR_H
+#define _LINUX_FPGA_MGR_H
+
+#include 
+
+struct fpga_manager;
+
+/**
+ * enum fpga_mgr_states - fpga framework states
+ * @FPGA_MGR_STATE_UNKNOWN: can't determine state
+ * @FPGA_MGR_STATE_POWER_OFF: FPGA power is off
+ * @FPGA_MGR_STATE_POWER_UP: FPGA reports power is up
+ * @FPGA_MGR_STATE_RESET: FPGA in reset state
+ * @FPGA_MGR_STATE_FIRMWARE_REQ: firmware request in progress
+ * @FPGA_MGR_STATE_FIRMWARE_REQ_ERR: firmware request failed
+ * @FPGA_MGR_STATE_WRITE_INIT: preparing FPGA for programming
+ * @FPGA_MGR_STATE_WRITE_INIT_ERR: Error during WRITE_INIT stage
+ * @FPGA_MGR_STATE_WRITE: writing image to FPGA
+ * @FPGA_MGR_STATE_WRITE_ERR: Error while writing FPGA
+ * @FPGA_MGR_STATE_WRITE_COMPLETE: Doing post programming steps
+ * @FPGA_MGR_STATE_WRITE_COMPLETE_ERR: Error during WRITE_COMPLETE
+ * @FPGA_MGR_STATE_OPERATING: FPGA is programmed and operating
+ */
+enum fpga_mgr_states {
+   /* default FPGA states */
+   FPGA_MGR_STATE_UNKNOWN,
+   FPGA_MGR_STATE_POWER_OFF,
+   FPGA_MGR_STATE_POWER_UP,
+   FPGA_MGR_STATE_RESET,
+
+   /* getting an image for loading */
+   FPGA_MGR_STATE_FIRMWARE_REQ,
+   FPGA_MGR_STATE_FIRMWARE_REQ_ERR,
+
+   /* write sequence: init, write, complete */
+   FPGA_MGR_STATE_WRITE_INIT,
+   FPGA_MGR_STATE_WRITE_INIT_ERR,
+   FPGA_MGR_STATE_WRITE,
+   FPGA_MGR_STATE_WRITE_ERR,
+   FPGA_MGR_STATE_WRITE_COMPLETE,
+   FPGA_MGR_STATE_WRITE_COMPLETE_ERR,
+
+   /* fpga is programmed and operating */
+   FPGA_MGR_STATE_OPERATING,
+};
+
+/*
+ * FPGA Manager flags
+ * FPGA_MGR_PARTIAL_RECONFIG: do partial reconfiguration if supported
+ * FPGA_MGR_EXTERNAL_CONFIG: FPGA has been configured prior to Linux booting
+ * FPGA_MGR_BITSTREAM_LSB_FIRST: SPI bitstream bit order is LSB first
+ * FPGA_MGR_COMPRESSED_BITSTREAM: FPGA bitstream is compressed
+ */
+#define FPGA_MGR_PARTIAL_RECONFIG  BIT(0)
+#define FPGA_MGR_EXTERNAL_CONFIG   BIT(1)
+#define FPGA_MGR_ENCRYPTED_BITSTREAM   BIT(2)
+#define FPGA_MGR_BITSTREAM_LSB_FIRST   BIT(3)
+#define FPGA_MGR_COMPRESSED_BITSTREAM  BIT(4)
+
+/**
+ * struct fpga_image_info - information specific to a FPGA image
+ * @flags: boolean flags as defined above
+ * @enable_timeout_us: maximum time to enable traffic through bridge (uSec)
+ * @disable_timeout_us: maximum time to disable traffic through bridge (uSec)
+ * @config_complete_timeout_us: maximum time for FPGA to switch to operating
+ *status in the write_compl

[PATCH v2 02/12] firmware: socfpga: set APPLYCFG after loading bitstream

2021-01-27 Thread Steffen Trumtrar
To make changes to the SDRAM controller effective, the APPLYCFG bit must
be set after programming the bitstream to the FPGA. This has to be done
without any SDRAM usage. Therefore copy the function to execute to the
OCRAM and execute it from there.

Signed-off-by: Steffen Trumtrar 
---
 .../mach-socfpga/include/mach/cyclone5-regs.h |  1 +
 drivers/firmware/Makefile |  2 +-
 drivers/firmware/socfpga.c| 21 +++
 drivers/firmware/socfpga_sdr.S| 17 +++
 4 files changed, 40 insertions(+), 1 deletion(-)
 create mode 100644 drivers/firmware/socfpga_sdr.S

diff --git a/arch/arm/mach-socfpga/include/mach/cyclone5-regs.h 
b/arch/arm/mach-socfpga/include/mach/cyclone5-regs.h
index e88daf718917..1a7d787a27bf 100644
--- a/arch/arm/mach-socfpga/include/mach/cyclone5-regs.h
+++ b/arch/arm/mach-socfpga/include/mach/cyclone5-regs.h
@@ -18,5 +18,6 @@
 #define CYCLONE5_SYSMGR_ADDRESS0xffd08000
 #define CYCLONE5_SCANMGR_ADDRESS   0xfff02000
 #define CYCLONE5_SMP_TWD_ADDRESS   0xfffec600
+#define CYCLONE5_OCRAM_ADDRESS 0x
 
 #endif /* __MACH_SOCFPGA_REGS_H */
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index b162b08b0a80..bbd2bcda9780 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -1,3 +1,3 @@
 obj-$(CONFIG_FIRMWARE_ALTERA_SERIAL) += altera_serial.o
-obj-$(CONFIG_FIRMWARE_ALTERA_SOCFPGA) += socfpga.o
+obj-$(CONFIG_FIRMWARE_ALTERA_SOCFPGA) += socfpga.o socfpga_sdr.o
 obj-$(CONFIG_FIRMWARE_ZYNQMP_FPGA) += zynqmp-fpga.o
diff --git a/drivers/firmware/socfpga.c b/drivers/firmware/socfpga.c
index 393c78c45d79..c468c743720f 100644
--- a/drivers/firmware/socfpga.c
+++ b/drivers/firmware/socfpga.c
@@ -38,6 +38,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 
 #define FPGAMGRREGS_STAT   0x0
 #define FPGAMGRREGS_CTRL   0x4
@@ -77,6 +80,9 @@
 #define CDRATIO_x4 0x2
 #define CDRATIO_x8 0x3
 
+extern void socfpga_sdram_apply_static_cfg(void __iomem *sdrctrlgrp);
+extern void socfpga_sdram_apply_static_cfg_end(void *);
+
 struct fpgamgr {
struct firmware_handler fh;
struct device_d dev;
@@ -353,6 +359,9 @@ static int fpgamgr_program_finish(struct firmware_handler 
*fh)
 {
struct fpgamgr *mgr = container_of(fh, struct fpgamgr, fh);
int status;
+   unsigned int func_size = _sdram_apply_static_cfg_end -
+_sdram_apply_static_cfg;
+   void (*ocram_func)(void __iomem *ocram_base);
 
/* Ensure the FPGA entering config done */
status = fpgamgr_program_poll_cd(mgr);
@@ -382,6 +391,18 @@ static int fpgamgr_program_finish(struct firmware_handler 
*fh)
return status;
}
 
+   remap_range((void *)CYCLONE5_OCRAM_ADDRESS, PAGE_SIZE, MAP_CACHED);
+
+   dev_dbg(>dev, "Setting APPLYCFG bit...\n");
+
+   ocram_func = fncpy((void __iomem *)CYCLONE5_OCRAM_ADDRESS,
+  _sdram_apply_static_cfg, func_size);
+
+   sync_caches_for_execution();
+
+   ocram_func((void __iomem *) (CYCLONE5_SDR_ADDRESS +
+SDR_CTRLGRP_STATICCFG_ADDRESS));
+
return 0;
 }
 
diff --git a/drivers/firmware/socfpga_sdr.S b/drivers/firmware/socfpga_sdr.S
new file mode 100644
index ..d634d6362722
--- /dev/null
+++ b/drivers/firmware/socfpga_sdr.S
@@ -0,0 +1,17 @@
+#include 
+
+   .arch   armv7-a
+   .arm
+
+/*
+ * r0 : sdram controller staticcfg
+ */
+
+ENTRY(socfpga_sdram_apply_static_cfg)
+   push {ip,lr}
+   ldr r1, [r0]
+   orr r1, r1, #8
+   str r1, [r0]
+   pop {ip,pc}
+   .align
+ENTRY(socfpga_sdram_apply_static_cfg_end)
-- 
2.20.1


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


[PATCH v2 04/12] drivers: add fpga bridge framework

2021-01-27 Thread Steffen Trumtrar
Import the fpga bridge framework from linux v4.10-rc2.

Description from the initial commit adding this to linux:
21aeda950c5f84a8351b862816d832120b217a9b

fpga: add fpga bridge framework

This framework adds API functions for enabling/
disabling FPGA bridges under kernel control.

This allows the Linux kernel to disable FPGA bridges
during FPGA reprogramming and to enable FPGA bridges
when FPGA reprogramming is done.  This framework is
be manufacturer-agnostic, allowing it to be used in
interfaces that use the FPGA Manager Framework to
reprogram FPGA's.

The functions are:
* of_fpga_bridge_get
* fpga_bridge_put
   Get/put an exclusive reference to a FPGA bridge.

* fpga_bridge_enable
* fpga_bridge_disable
   Enable/Disable traffic through a bridge.

* fpga_bridge_register
* fpga_bridge_unregister
   Register/unregister a device-specific low level FPGA
   Bridge driver.

Get an exclusive reference to a bridge and add it to a list:
* fpga_bridge_get_to_list

To enable/disable/put a set of bridges that are on a list:
* fpga_bridges_enable
* fpga_bridges_disable
* fpga_bridges_put

Signed-off-by: Alan Tull 

Signed-off-by: Steffen Trumtrar 
---
 drivers/Kconfig|   1 +
 drivers/Makefile   |   1 +
 drivers/fpga/Kconfig   |  22 
 drivers/fpga/Makefile  |   6 +
 drivers/fpga/fpga-bridge.c | 226 +
 include/fpga-bridge.h  |  69 +++
 6 files changed, 325 insertions(+)
 create mode 100644 drivers/fpga/Kconfig
 create mode 100644 drivers/fpga/Makefile
 create mode 100644 drivers/fpga/fpga-bridge.c
 create mode 100644 include/fpga-bridge.h

diff --git a/drivers/Kconfig b/drivers/Kconfig
index dda240578067..3bb9c09536e8 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -36,6 +36,7 @@ source "drivers/reset/Kconfig"
 source "drivers/pci/Kconfig"
 source "drivers/rtc/Kconfig"
 source "drivers/firmware/Kconfig"
+source "drivers/fpga/Kconfig"
 source "drivers/phy/Kconfig"
 source "drivers/crypto/Kconfig"
 source "drivers/memory/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 5a03bdceab81..5221c2ca5586 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_RESET_CONTROLLER) += reset/
 obj-$(CONFIG_PCI) += pci/
 obj-y += rtc/
 obj-$(CONFIG_FIRMWARE) += firmware/
+obj-$(CONFIG_FPGA) += fpga/
 obj-$(CONFIG_GENERIC_PHY) += phy/
 obj-$(CONFIG_HAB) += hab/
 obj-$(CONFIG_CRYPTO_HW) += crypto/
diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
new file mode 100644
index ..fccdbff6eb3f
--- /dev/null
+++ b/drivers/fpga/Kconfig
@@ -0,0 +1,22 @@
+#
+# FPGA framework configuration
+#
+
+menu "FPGA Configuration Support"
+
+config FPGA
+   tristate "FPGA Configuration Framework"
+   help
+ Say Y here if you want support for configuring FPGAs from barebox.
+
+if FPGA
+
+config FPGA_BRIDGE
+   tristate "FPGA Bridge Framework"
+   help
+ Say Y here if you want to support bridges connected between host
+ processors and FPGAs or between FPGAs.
+
+endif # FPGA
+
+endmenu
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
new file mode 100644
index ..fc71a29d3b33
--- /dev/null
+++ b/drivers/fpga/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for the fpga framework and fpga manager drivers.
+#
+
+# FPGA Bridge Drivers
+obj-$(CONFIG_FPGA_BRIDGE)  += fpga-bridge.o
diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c
new file mode 100644
index ..edf29b0ecf13
--- /dev/null
+++ b/drivers/fpga/fpga-bridge.c
@@ -0,0 +1,226 @@
+/*
+ * FPGA Bridge Framework Driver
+ *
+ *  Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include 
+#include 
+
+/**
+ * fpga_bridge_enable - Enable transactions on the bridge
+ *
+ * @bridge: FPGA bridge
+ *
+ * Return: 0 for success, error code otherwise.
+ */
+int fpga_bridge_enable(struct fpga_bridge *bridge)
+{
+   dev_dbg(>dev, "enable\n");
+
+   if (bridge->br_ops && bridge->br_ops->enable_set)
+   return bridge->br_ops->enable_set(bridge, 1);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(fp

[PATCH v2 11/12] drivers: firmware: socfpga: remove bridges shutdown

2021-01-27 Thread Steffen Trumtrar
The bridges are now handled via the bridges driver. There is no
need to hardcode the memory writes anymore.

Signed-off-by: Steffen Trumtrar 
---
 drivers/firmware/socfpga.c | 9 -
 1 file changed, 9 deletions(-)

diff --git a/drivers/firmware/socfpga.c b/drivers/firmware/socfpga.c
index 605c931604c9..eb3fc557c7fe 100644
--- a/drivers/firmware/socfpga.c
+++ b/drivers/firmware/socfpga.c
@@ -294,15 +294,6 @@ static int socfpga_fpgamgr_program_start(struct 
firmware_handler *fh)
/* disable all signals from hps peripheral controller to fpga */
writel(0, SYSMGR_FPGAINTF_MODULE);
 
-   /* disable all signals from fpga to hps sdram */
-   writel(0, (CYCLONE5_SDR_ADDRESS + SDR_CTRLGRP_FPGAPORTRST_ADDRESS));
-
-   /* disable all axi bridge (hps2fpga, lwhps2fpga & fpga2hps) */
-   writel(~0, CYCLONE5_RSTMGR_ADDRESS + RESET_MGR_BRG_MOD_RESET_OFS);
-
-   /* unmap the bridges from NIC-301 */
-   writel(0x1, CYCLONE5_L3REGS_ADDRESS);
-
dev_dbg(>dev, "start programming...\n");
 
/* initialize the FPGA Manager */
-- 
2.20.1


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


[PATCH v2 12/12] firmware: add support for compressed images

2021-01-27 Thread Steffen Trumtrar
At least bitstreams for FPGAs can consist of a lot of zeros depending on
device utilization. These bitstreams can be compressed very effectively.

Let the firmware code accept these images and decompress them before
handing it to the firmware-manager in question.

Signed-off-by: Steffen Trumtrar 
---
 common/firmware.c | 43 ++-
 1 file changed, 38 insertions(+), 5 deletions(-)

diff --git a/common/firmware.c b/common/firmware.c
index 58509d5da615..c617ecc0f129 100644
--- a/common/firmware.c
+++ b/common/firmware.c
@@ -14,6 +14,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #define BUFSIZ 4096
 
@@ -211,12 +213,43 @@ int firmwaremgr_register(struct firmware_handler *fh)
  */
 int firmwaremgr_load_file(struct firmware_mgr *mgr, const char *firmware)
 {
-   int ret;
-   char *name = basprintf("/dev/%s", mgr->handler->id);
-
-   ret = copy_file(firmware, name, 0);
+   char *dst;
+   enum filetype type;
+   int ret = -ENOENT;
+   int srcfd = 0;
+   int dstfd = 0;
+
+   if (mgr->handler->id) {
+   dst = basprintf("/dev/%s", mgr->handler->id);
+   } else {
+   pr_err("id not defined for handler\n");
+   return -ENODEV;
+   }
 
-   free(name);
+   if (firmware) {
+   type = file_name_detect_type(firmware);
+   if (type == filetype_unknown) {
+   ret = copy_file(firmware, dst, 0);
+   } else {
+   srcfd = open(firmware, O_RDONLY);
+   if (srcfd < 0)
+   return srcfd;
+   dstfd = open(dst, O_WRONLY | O_CREAT);
+
+   if (dstfd < 0) {
+   printf("could not open %s: %s\n", dst, 
errno_str());
+   ret = dstfd;
+   goto out;
+   }
+
+   ret = uncompress_fd_to_fd(srcfd, dstfd, 
uncompress_err_stdout);
+
+   close(dstfd);
+   }
+   }
+out:
+   close(srcfd);
+   free(dst);
 
return ret;
 }
-- 
2.20.1


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


[PATCH v2 10/12] commands: firmwareload: allow loading firmware from dt

2021-01-27 Thread Steffen Trumtrar
firmwareload can only load a bitstream into an FPGA without any
knowledge of possible additional needs (e.g. FPGA bridges).

These are defined in the fpga-region nodes in the devicetree. The
fpga-region describes the layout of the FPGA and the bridges it needs
en/disabled.

Add an option to let firmwareload go via the oftree route and load the
firmware that way.

Signed-off-by: Steffen Trumtrar 
---
 commands/firmwareload.c | 42 +++--
 1 file changed, 36 insertions(+), 6 deletions(-)

diff --git a/commands/firmwareload.c b/commands/firmwareload.c
index b735088f6117..2b1e770662d1 100644
--- a/commands/firmwareload.c
+++ b/commands/firmwareload.c
@@ -5,18 +5,38 @@
 #include 
 #include 
 #include 
+#include 
 
 static int do_firmwareload(int argc, char *argv[])
 {
-   int ret, opt;
+   int opt;
const char *name = NULL, *firmware;
struct firmware_mgr *mgr;
+   char *path = NULL;
+   char *search_path = NULL;
+   char *compatible = NULL;
+   int oftree = 0;
 
-   while ((opt = getopt(argc, argv, "t:l")) > 0) {
+   while ((opt = getopt(argc, argv, "t:c:S:D:lo")) > 0) {
switch (opt) {
case 't':
name = optarg;
break;
+   case 'c':
+   compatible = xzalloc(strlen(optarg) + 1);
+   strcpy(compatible, optarg);
+   oftree = 1;
+   break;
+   case 'S':
+   search_path = xzalloc(strlen(optarg) + 1);
+   strcpy(search_path, optarg);
+   oftree = 1;
+   break;
+   case 'D':
+   path = xzalloc(strlen(optarg) + 1);
+   strcpy(path, optarg);
+   oftree = 1;
+   break;
case 'l':
firmwaremgr_list_handlers();
return 0;
@@ -25,11 +45,20 @@ static int do_firmwareload(int argc, char *argv[])
}
}
 
-   if (!(argc - optind))
+   if (!oftree && !(argc - optind))
return COMMAND_ERROR_USAGE;
 
firmware = argv[optind];
 
+   if (oftree) {
+   if (!search_path && !firmware) {
+   printf("Provide at least a file to load or a search 
path (-S)\n");
+   return 1;
+   }
+
+   return of_firmware_load_file(path, compatible, search_path, 
firmware);
+   }
+
mgr = firmwaremgr_find(name);
 
if (!mgr) {
@@ -38,14 +67,15 @@ static int do_firmwareload(int argc, char *argv[])
return 1;
}
 
-   ret = firmwaremgr_load_file(mgr, firmware);
-
-   return ret;
+   return firmwaremgr_load_file(mgr, firmware);
 }
 
 BAREBOX_CMD_HELP_START(firmwareload)
 BAREBOX_CMD_HELP_TEXT("Options:")
 BAREBOX_CMD_HELP_OPT("-t ", "define the firmware handler by name")
+BAREBOX_CMD_HELP_OPT("-c ", "type of firmware device (e.g. 
'fpga-region')")
+BAREBOX_CMD_HELP_OPT("-D ", "load firmware to oftree path")
+BAREBOX_CMD_HELP_OPT("-S ", "load firmware using this search path")
 BAREBOX_CMD_HELP_OPT("-l\t", "list devices capable of firmware loading")
 BAREBOX_CMD_HELP_END
 
-- 
2.20.1


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


[PATCH v2 08/12] of: kconfig: of_overlay uses firmwaremgr_load_file

2021-01-27 Thread Steffen Trumtrar
From: Steffen Trumtrar 

As of_firmware.c uses the firmwaremgr_load_file function, it depends on
FIRMWARE.

Signed-off-by: Steffen Trumtrar 
---
 drivers/of/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 23be25d85d09..e58fe50f7090 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -49,6 +49,7 @@ config OF_BAREBOX_ENV_IN_FS
 
 config OF_OVERLAY
select OFTREE
+   select FIRMWARE
bool "Devicetree overlays"
help
  Overlays allow to patch the devicetree. Unlike Linux, Barebox does
-- 
2.20.1


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


[PATCH v4 03/10] drivers: fpga: add socfpga bridges

2021-06-16 Thread Steffen Trumtrar
Import the SoCFPGA bridges drivers from linux v4.10-rc2.

Description from the original commit:
e5f8efa5c8bf86c1fa698551d54db8f6aee221fd

ARM: socfpga: fpga bridge driver support

Supports Altera SOCFPGA bridges:
 * fpga2sdram
 * fpga2hps
 * hps2fpga
 * lwhps2fpga

Allows enabling/disabling the bridges through the FPGA
Bridge Framework API functions.

The fpga2sdram driver only supports enabling and disabling
of the ports that been configured early on.  This is due to
a hardware limitation where the read, write, and command
ports on the fpga2sdram bridge can only be reconfigured
while there are no transactions to the sdram, i.e. when
running out of OCRAM before the kernel boots.

Device tree property 'init-val' configures the driver to
enable or disable the bridge during probe.  If the property
does not exist, the driver will leave the bridge in its
current state.

Signed-off-by: Alan Tull 
Signed-off-by: Matthew Gerlach 
Signed-off-by: Dinh Nguyen 
Signed-off-by: Greg Kroah-Hartman 

Signed-off-by: Steffen Trumtrar 
---
 drivers/fpga/Kconfig |   8 +
 drivers/fpga/Makefile|   1 +
 drivers/fpga/fpga-bridge.c   |   2 +-
 drivers/fpga/socfpga-fpga2sdram-bridge.c | 139 ++
 drivers/fpga/socfpga-hps2fpga-bridge.c   | 179 +++
 5 files changed, 328 insertions(+), 1 deletion(-)
 create mode 100644 drivers/fpga/socfpga-fpga2sdram-bridge.c
 create mode 100644 drivers/fpga/socfpga-hps2fpga-bridge.c

diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index fccdbff6eb3f..64ce9f91b6a8 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -17,6 +17,14 @@ config FPGA_BRIDGE
  Say Y here if you want to support bridges connected between host
  processors and FPGAs or between FPGAs.
 
+config SOCFPGA_FPGA_BRIDGE
+   tristate "Altera SoCFPGA FPGA Bridges"
+   depends on ARCH_SOCFPGA && FPGA_BRIDGE
+   select RESET_CONTROLLER
+   help
+ Say Y to enable drivers for FPGA bridges for Altera SOCFPGA
+ devices.
+
 endif # FPGA
 
 endmenu
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index fc71a29d3b33..86178fe7c078 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -4,3 +4,4 @@
 
 # FPGA Bridge Drivers
 obj-$(CONFIG_FPGA_BRIDGE)  += fpga-bridge.o
+obj-$(CONFIG_SOCFPGA_FPGA_BRIDGE)  += socfpga-hps2fpga-bridge.o 
socfpga-fpga2sdram-bridge.o
diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c
index 6e8dcbfc0d16..6f9e943de904 100644
--- a/drivers/fpga/fpga-bridge.c
+++ b/drivers/fpga/fpga-bridge.c
@@ -68,7 +68,7 @@ struct fpga_bridge *of_fpga_bridge_get(struct device_node *np)
 {
struct device_d *dev;
struct fpga_bridge *bridge;
-   int ret = -ENODEV;
+   int ret = -EPROBE_DEFER;
 
dev = of_find_device_by_node(np);
if (!dev || !dev->priv)
diff --git a/drivers/fpga/socfpga-fpga2sdram-bridge.c 
b/drivers/fpga/socfpga-fpga2sdram-bridge.c
new file mode 100644
index ..a9760597ddb5
--- /dev/null
+++ b/drivers/fpga/socfpga-fpga2sdram-bridge.c
@@ -0,0 +1,139 @@
+/*
+ * FPGA to SDRAM Bridge Driver for Altera SoCFPGA Devices
+ *
+ *  Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This driver manages a bridge between an FPGA and the SDRAM used by the ARM
+ * host processor system (HPS).
+ *
+ * The bridge contains 4 read ports, 4 write ports, and 6 command ports.
+ * Reconfiguring these ports requires that no SDRAM transactions occur during
+ * reconfiguration.  The code reconfiguring the ports cannot run out of SDRAM
+ * nor can the FPGA access the SDRAM during reconfiguration.  This driver does
+ * not support reconfiguring the ports.  The ports are configured by code
+ * running out of on chip ram before Linux is started and the configuration
+ * is passed in a handoff register in the system manager.
+ *
+ * This driver supports enabling and disabling of the configured ports, which
+ * allows for safe reprogramming of the FPGA, assuming that the new FPGA image
+ * uses the same port configuration.  Bridges must be disabled before
+ * reprogramming the FPGA and re-enabled after the FPGA has been programmed.
+ */
+
+#include 
+#include 
+#in

[PATCH v4 02/10] drivers: add fpga bridge framework

2021-06-16 Thread Steffen Trumtrar
Import the fpga bridge framework from linux v4.10-rc2.

Description from the initial commit adding this to linux:
21aeda950c5f84a8351b862816d832120b217a9b

fpga: add fpga bridge framework

This framework adds API functions for enabling/
disabling FPGA bridges under kernel control.

This allows the Linux kernel to disable FPGA bridges
during FPGA reprogramming and to enable FPGA bridges
when FPGA reprogramming is done.  This framework is
be manufacturer-agnostic, allowing it to be used in
interfaces that use the FPGA Manager Framework to
reprogram FPGA's.

The functions are:
* of_fpga_bridge_get
* fpga_bridge_put
   Get/put an exclusive reference to a FPGA bridge.

* fpga_bridge_enable
* fpga_bridge_disable
   Enable/Disable traffic through a bridge.

* fpga_bridge_register
* fpga_bridge_unregister
   Register/unregister a device-specific low level FPGA
   Bridge driver.

Get an exclusive reference to a bridge and add it to a list:
* fpga_bridge_get_to_list

To enable/disable/put a set of bridges that are on a list:
* fpga_bridges_enable
* fpga_bridges_disable
* fpga_bridges_put

Signed-off-by: Alan Tull 

Signed-off-by: Steffen Trumtrar 

---

v2->v3: add fpga_bridges_put function to deallocate bridge list
---
 drivers/Kconfig|   1 +
 drivers/Makefile   |   1 +
 drivers/fpga/Kconfig   |  22 
 drivers/fpga/Makefile  |   6 +
 drivers/fpga/fpga-bridge.c | 243 +
 include/fpga-bridge.h  |  74 +++
 6 files changed, 347 insertions(+)
 create mode 100644 drivers/fpga/Kconfig
 create mode 100644 drivers/fpga/Makefile
 create mode 100644 drivers/fpga/fpga-bridge.c
 create mode 100644 include/fpga-bridge.h

diff --git a/drivers/Kconfig b/drivers/Kconfig
index 787d36693309..670e0a9f4c95 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -37,6 +37,7 @@ source "drivers/reset/Kconfig"
 source "drivers/pci/Kconfig"
 source "drivers/rtc/Kconfig"
 source "drivers/firmware/Kconfig"
+source "drivers/fpga/Kconfig"
 source "drivers/phy/Kconfig"
 source "drivers/crypto/Kconfig"
 source "drivers/memory/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index be5b0b3b04c9..e21ac7095c6c 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_RESET_CONTROLLER) += reset/
 obj-$(CONFIG_PCI) += pci/
 obj-y += rtc/
 obj-$(CONFIG_FIRMWARE) += firmware/
+obj-$(CONFIG_FPGA) += fpga/
 obj-$(CONFIG_GENERIC_PHY) += phy/
 obj-$(CONFIG_HAB) += hab/
 obj-$(CONFIG_CRYPTO_HW) += crypto/
diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
new file mode 100644
index ..fccdbff6eb3f
--- /dev/null
+++ b/drivers/fpga/Kconfig
@@ -0,0 +1,22 @@
+#
+# FPGA framework configuration
+#
+
+menu "FPGA Configuration Support"
+
+config FPGA
+   tristate "FPGA Configuration Framework"
+   help
+ Say Y here if you want support for configuring FPGAs from barebox.
+
+if FPGA
+
+config FPGA_BRIDGE
+   tristate "FPGA Bridge Framework"
+   help
+ Say Y here if you want to support bridges connected between host
+ processors and FPGAs or between FPGAs.
+
+endif # FPGA
+
+endmenu
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
new file mode 100644
index ..fc71a29d3b33
--- /dev/null
+++ b/drivers/fpga/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for the fpga framework and fpga manager drivers.
+#
+
+# FPGA Bridge Drivers
+obj-$(CONFIG_FPGA_BRIDGE)  += fpga-bridge.o
diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c
new file mode 100644
index ..6e8dcbfc0d16
--- /dev/null
+++ b/drivers/fpga/fpga-bridge.c
@@ -0,0 +1,243 @@
+/*
+ * FPGA Bridge Framework Driver
+ *
+ *  Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include 
+#include 
+
+/**
+ * fpga_bridge_enable - Enable transactions on the bridge
+ *
+ * @bridge: FPGA bridge
+ *
+ * Return: 0 for success, error code otherwise.
+ */
+int fpga_bridge_enable(struct fpga_bridge *bridge)
+{
+   dev_dbg(>dev, "enable\n");
+
+   if (bridge->br_ops && bridge->br_ops->enable_set)
+   return bridge->br_ops-&g

[PATCH v4 07/10] of: of_firmware: add support for fpga bridges

2021-06-16 Thread Steffen Trumtrar
Add support for potentially defined FPGA-bridges in the overlay.

While at it also add support for loading the firmware directly via a
path instead of 'needing' an overlay for that.
The direct loading will be done with the existent firmwareload command.

Signed-off-by: Steffen Trumtrar 

---

v2->v3 - basprintf -> plain 'compatible = "fpga-region"'
   - assign root in if-clause
---
 drivers/of/Makefile  |   3 +-
 drivers/of/of_firmware.c | 129 +--
 include/of.h |  23 +--
 3 files changed, 142 insertions(+), 13 deletions(-)

diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index b6847752d247..6199c9791f52 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -6,4 +6,5 @@ obj-y += partition.o
 obj-y += of_net.o
 obj-$(CONFIG_MTD) += of_mtd.o
 obj-$(CONFIG_OF_BAREBOX_DRIVERS) += barebox.o
-obj-$(CONFIG_OF_OVERLAY) += overlay.o resolver.o of_firmware.o
+obj-$(CONFIG_OF_OVERLAY) += overlay.o resolver.o
+obj-$(CONFIG_FIRMWARE) += of_firmware.o
diff --git a/drivers/of/of_firmware.c b/drivers/of/of_firmware.c
index 096f84572e63..26864a6a13ef 100644
--- a/drivers/of/of_firmware.c
+++ b/drivers/of/of_firmware.c
@@ -4,12 +4,52 @@
  */
 #include 
 #include 
+#include 
 #include 
 
 struct overlay_info {
const char *firmware_path;
 };
 
+#ifdef CONFIG_FPGA_BRIDGE
+static int of_get_bridges(struct device_node *region, struct list_head 
*bridges)
+{
+   struct device_node *br, *parent_br = NULL;
+   int i, ret;
+
+   /* If parent is a bridge, add to list */
+   ret = fpga_bridge_get_to_list(region->parent, bridges);
+   if (!ret) {
+   parent_br = region->parent;
+   pr_debug("Add %s to list of bridges\n", parent_br->name);
+   }
+
+   for (i = 0; ; i++) {
+   br = of_parse_phandle(region, "fpga-bridges", i);
+   if (!br)
+   break;
+
+   /* If parent bridge is in list, skip it. */
+   if (br == parent_br)
+   continue;
+
+   /* If node is a bridge, get it and add to list */
+   ret = fpga_bridge_get_to_list(br, bridges);
+   if (ret)
+   return ret;
+
+   pr_debug("Add %s to list of bridges\n", br->name);
+   }
+
+   return 0;
+}
+#else
+static int of_get_bridges(struct device_node *np, struct list_head *br)
+{
+   return 0;
+}
+#endif
+
 static struct firmware_mgr *of_node_get_mgr(struct device_node *np)
 {
struct device_node *mgr_node;
@@ -25,6 +65,35 @@ static struct firmware_mgr *of_node_get_mgr(struct 
device_node *np)
return NULL;
 }
 
+static int of_load_firmware(struct device_node *target, const char *path)
+{
+   struct list_head bridge_list;
+   struct firmware_mgr *mgr;
+   int err;
+
+   mgr = of_node_get_mgr(target);
+   if (!mgr)
+   return -EINVAL;
+
+   pr_debug("Found firmware manager @%s\n", target->name);
+
+   INIT_LIST_HEAD(_list);
+
+   of_get_bridges(target, _list);
+
+   fpga_bridges_disable(_list);
+
+   pr_debug("Loading %s to %s\n", path, target->name);
+
+   err = firmwaremgr_load_file(mgr, path);
+
+   fpga_bridges_enable(_list);
+
+   fpga_bridges_put(_list);
+
+   return err;
+}
+
 static int load_firmware(struct device_node *target,
 struct device_node *fragment, void *data)
 {
@@ -33,7 +102,6 @@ static int load_firmware(struct device_node *target,
const char *firmware_path = info->firmware_path;
char *firmware;
int err;
-   struct firmware_mgr *mgr;
 
err = of_property_read_string(fragment,
  "firmware-name", _name);
@@ -46,21 +114,70 @@ static int load_firmware(struct device_node *target,
if (!target)
return -EINVAL;
 
-   mgr = of_node_get_mgr(target);
-   if (!mgr)
-   return -EINVAL;
-
firmware = basprintf("%s/%s", firmware_path, firmware_name);
if (!firmware)
return -ENOMEM;
 
-   err = firmwaremgr_load_file(mgr, firmware);
+   err = of_load_firmware(target, firmware);
 
free(firmware);
 
return err;
 }
 
+int of_firmware_load_file(const char *path, const char *compatible,
+ const char *search_path, const char *firmware)
+{
+   struct overlay_info info = {
+   .firmware_path = search_path,
+   };
+   struct device_node *target;
+   struct device_node *node;
+   struct device_node *root;
+
+   if (!compatible)
+   compatible = "fpga-region";
+
+   /*
+* firmware-name not specified. Use load_firmware function to get it 
from
+* the devicetree. This allows loading firmware to multiple devices.
+*/
+ 

[PATCH v4 01/10] reset: add of_reset_control_get to header

2021-06-16 Thread Steffen Trumtrar
Signed-off-by: Steffen Trumtrar 
---
 drivers/reset/core.c  | 2 +-
 include/linux/reset.h | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/reset/core.c b/drivers/reset/core.c
index 26a54f21dff0..1c9eeaec5491 100644
--- a/drivers/reset/core.c
+++ b/drivers/reset/core.c
@@ -147,7 +147,7 @@ EXPORT_SYMBOL_GPL(reset_control_deassert);
  *
  * Use of id names is optional.
  */
-static struct reset_control *of_reset_control_get(struct device_node *node,
+struct reset_control *of_reset_control_get(struct device_node *node,
  const char *id)
 {
struct reset_control *rstc;
diff --git a/include/linux/reset.h b/include/linux/reset.h
index a166fe1cfe04..726cb5c2057d 100644
--- a/include/linux/reset.h
+++ b/include/linux/reset.h
@@ -11,6 +11,8 @@ int reset_control_assert(struct reset_control *rstc);
 int reset_control_deassert(struct reset_control *rstc);
 
 struct reset_control *reset_control_get(struct device_d *dev, const char *id);
+struct reset_control *of_reset_control_get(struct device_node *node,
+  const char *id);
 void reset_control_put(struct reset_control *rstc);
 
 int __must_check device_reset(struct device_d *dev);
-- 
2.29.2


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


[PATCH v4 05/10] firmware: import fpga-mgr.h from linux

2021-06-16 Thread Steffen Trumtrar
Instead of defining the fpga-mgr structure in the socfpga driver, import
the fpga-mgr.h file from linux v4.13.

Signed-off-by: Steffen Trumtrar 
---
 drivers/firmware/socfpga.c |   9 +---
 include/firmware.h |   1 +
 include/fpga-mgr.h | 102 +
 3 files changed, 104 insertions(+), 8 deletions(-)
 create mode 100644 include/fpga-mgr.h

diff --git a/drivers/firmware/socfpga.c b/drivers/firmware/socfpga.c
index 14875214b1aa..605c931604c9 100644
--- a/drivers/firmware/socfpga.c
+++ b/drivers/firmware/socfpga.c
@@ -27,6 +27,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -83,14 +84,6 @@
 extern void socfpga_sdram_apply_static_cfg(void __iomem *sdrctrlgrp);
 extern void socfpga_sdram_apply_static_cfg_end(void *);
 
-struct fpgamgr {
-   struct firmware_handler fh;
-   struct device_d dev;
-   void __iomem *regs;
-   void __iomem *regs_data;
-   int programmed;
-};
-
 /* Get the FPGA mode */
 static uint32_t socfpga_fpgamgr_get_mode(struct fpgamgr *mgr)
 {
diff --git a/include/firmware.h b/include/firmware.h
index 19777d9bf711..2fef97a48f56 100644
--- a/include/firmware.h
+++ b/include/firmware.h
@@ -13,6 +13,7 @@ struct firmware_handler {
char *id; /* unique identifier for this firmware device */
char *model; /* description for this device */
struct device_d *dev;
+   void *priv;
/* called once to prepare the firmware's programming cycle */
int (*open)(struct firmware_handler*);
/* called multiple times to program the firmware with the given data */
diff --git a/include/fpga-mgr.h b/include/fpga-mgr.h
new file mode 100644
index ..a120b3918990
--- /dev/null
+++ b/include/fpga-mgr.h
@@ -0,0 +1,102 @@
+/*
+ * FPGA Framework
+ *
+ *  Copyright (C) 2013-2015 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _LINUX_FPGA_MGR_H
+#define _LINUX_FPGA_MGR_H
+
+#include 
+
+struct fpga_manager;
+
+/**
+ * enum fpga_mgr_states - fpga framework states
+ * @FPGA_MGR_STATE_UNKNOWN: can't determine state
+ * @FPGA_MGR_STATE_POWER_OFF: FPGA power is off
+ * @FPGA_MGR_STATE_POWER_UP: FPGA reports power is up
+ * @FPGA_MGR_STATE_RESET: FPGA in reset state
+ * @FPGA_MGR_STATE_FIRMWARE_REQ: firmware request in progress
+ * @FPGA_MGR_STATE_FIRMWARE_REQ_ERR: firmware request failed
+ * @FPGA_MGR_STATE_WRITE_INIT: preparing FPGA for programming
+ * @FPGA_MGR_STATE_WRITE_INIT_ERR: Error during WRITE_INIT stage
+ * @FPGA_MGR_STATE_WRITE: writing image to FPGA
+ * @FPGA_MGR_STATE_WRITE_ERR: Error while writing FPGA
+ * @FPGA_MGR_STATE_WRITE_COMPLETE: Doing post programming steps
+ * @FPGA_MGR_STATE_WRITE_COMPLETE_ERR: Error during WRITE_COMPLETE
+ * @FPGA_MGR_STATE_OPERATING: FPGA is programmed and operating
+ */
+enum fpga_mgr_states {
+   /* default FPGA states */
+   FPGA_MGR_STATE_UNKNOWN,
+   FPGA_MGR_STATE_POWER_OFF,
+   FPGA_MGR_STATE_POWER_UP,
+   FPGA_MGR_STATE_RESET,
+
+   /* getting an image for loading */
+   FPGA_MGR_STATE_FIRMWARE_REQ,
+   FPGA_MGR_STATE_FIRMWARE_REQ_ERR,
+
+   /* write sequence: init, write, complete */
+   FPGA_MGR_STATE_WRITE_INIT,
+   FPGA_MGR_STATE_WRITE_INIT_ERR,
+   FPGA_MGR_STATE_WRITE,
+   FPGA_MGR_STATE_WRITE_ERR,
+   FPGA_MGR_STATE_WRITE_COMPLETE,
+   FPGA_MGR_STATE_WRITE_COMPLETE_ERR,
+
+   /* fpga is programmed and operating */
+   FPGA_MGR_STATE_OPERATING,
+};
+
+/*
+ * FPGA Manager flags
+ * FPGA_MGR_PARTIAL_RECONFIG: do partial reconfiguration if supported
+ * FPGA_MGR_EXTERNAL_CONFIG: FPGA has been configured prior to Linux booting
+ * FPGA_MGR_BITSTREAM_LSB_FIRST: SPI bitstream bit order is LSB first
+ * FPGA_MGR_COMPRESSED_BITSTREAM: FPGA bitstream is compressed
+ */
+#define FPGA_MGR_PARTIAL_RECONFIG  BIT(0)
+#define FPGA_MGR_EXTERNAL_CONFIG   BIT(1)
+#define FPGA_MGR_ENCRYPTED_BITSTREAM   BIT(2)
+#define FPGA_MGR_BITSTREAM_LSB_FIRST   BIT(3)
+#define FPGA_MGR_COMPRESSED_BITSTREAM  BIT(4)
+
+/**
+ * struct fpga_image_info - information specific to a FPGA image
+ * @flags: boolean flags as defined above
+ * @enable_timeout_us: maximum time to enable traffic through bridge (uSec)
+ * @disable_timeout_us: maximum time to disable traffic through bridge (uSec)
+ * @config_complete_timeout_us: maximum time for FPGA to switch to operating
+ *status in the write_compl

[PATCH v4 08/10] commands: firmwareload: allow loading firmware from dt

2021-06-16 Thread Steffen Trumtrar
firmwareload can only load a bitstream into an FPGA without any
knowledge of possible additional needs (e.g. FPGA bridges).

These are defined in the fpga-region nodes in the devicetree. The
fpga-region describes the layout of the FPGA and the bridges it needs
en/disabled.

Add an option to let firmwareload go via the oftree route and load the
firmware that way.

Signed-off-by: Steffen Trumtrar 

---

v2->v3 - remove unused arg 'o'
   - use xstrdup()
---
 commands/firmwareload.c | 39 +--
 1 file changed, 33 insertions(+), 6 deletions(-)

diff --git a/commands/firmwareload.c b/commands/firmwareload.c
index b735088f6117..c2a017c45479 100644
--- a/commands/firmwareload.c
+++ b/commands/firmwareload.c
@@ -5,18 +5,35 @@
 #include 
 #include 
 #include 
+#include 
 
 static int do_firmwareload(int argc, char *argv[])
 {
-   int ret, opt;
+   int opt;
const char *name = NULL, *firmware;
struct firmware_mgr *mgr;
+   char *path = NULL;
+   char *search_path = NULL;
+   char *compatible = NULL;
+   int oftree = 0;
 
-   while ((opt = getopt(argc, argv, "t:l")) > 0) {
+   while ((opt = getopt(argc, argv, "t:c:S:D:l")) > 0) {
switch (opt) {
case 't':
name = optarg;
break;
+   case 'c':
+   compatible = xstrdup(optarg);
+   oftree = 1;
+   break;
+   case 'S':
+   search_path = xstrdup(optarg);
+   oftree = 1;
+   break;
+   case 'D':
+   path = xstrdup(optarg);
+   oftree = 1;
+   break;
case 'l':
firmwaremgr_list_handlers();
return 0;
@@ -25,11 +42,20 @@ static int do_firmwareload(int argc, char *argv[])
}
}
 
-   if (!(argc - optind))
+   if (!oftree && !(argc - optind))
return COMMAND_ERROR_USAGE;
 
firmware = argv[optind];
 
+   if (oftree) {
+   if (!search_path && !firmware) {
+   printf("Provide at least a file to load or a search 
path (-S)\n");
+   return 1;
+   }
+
+   return of_firmware_load_file(path, compatible, search_path, 
firmware);
+   }
+
mgr = firmwaremgr_find(name);
 
if (!mgr) {
@@ -38,14 +64,15 @@ static int do_firmwareload(int argc, char *argv[])
return 1;
}
 
-   ret = firmwaremgr_load_file(mgr, firmware);
-
-   return ret;
+   return firmwaremgr_load_file(mgr, firmware);
 }
 
 BAREBOX_CMD_HELP_START(firmwareload)
 BAREBOX_CMD_HELP_TEXT("Options:")
 BAREBOX_CMD_HELP_OPT("-t ", "define the firmware handler by name")
+BAREBOX_CMD_HELP_OPT("-c ", "type of firmware device (e.g. 
'fpga-region')")
+BAREBOX_CMD_HELP_OPT("-D ", "load firmware to oftree path")
+BAREBOX_CMD_HELP_OPT("-S ", "load firmware using this search path")
 BAREBOX_CMD_HELP_OPT("-l\t", "list devices capable of firmware loading")
 BAREBOX_CMD_HELP_END
 
-- 
2.29.2


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


[PATCH v4 09/10] drivers: firmware: socfpga: remove bridges shutdown

2021-06-16 Thread Steffen Trumtrar
The bridges are now handled via the bridges driver. There is no
need to hardcode the memory writes anymore.

Signed-off-by: Steffen Trumtrar 
---
 drivers/firmware/socfpga.c | 9 -
 1 file changed, 9 deletions(-)

diff --git a/drivers/firmware/socfpga.c b/drivers/firmware/socfpga.c
index 605c931604c9..eb3fc557c7fe 100644
--- a/drivers/firmware/socfpga.c
+++ b/drivers/firmware/socfpga.c
@@ -294,15 +294,6 @@ static int socfpga_fpgamgr_program_start(struct 
firmware_handler *fh)
/* disable all signals from hps peripheral controller to fpga */
writel(0, SYSMGR_FPGAINTF_MODULE);
 
-   /* disable all signals from fpga to hps sdram */
-   writel(0, (CYCLONE5_SDR_ADDRESS + SDR_CTRLGRP_FPGAPORTRST_ADDRESS));
-
-   /* disable all axi bridge (hps2fpga, lwhps2fpga & fpga2hps) */
-   writel(~0, CYCLONE5_RSTMGR_ADDRESS + RESET_MGR_BRG_MOD_RESET_OFS);
-
-   /* unmap the bridges from NIC-301 */
-   writel(0x1, CYCLONE5_L3REGS_ADDRESS);
-
dev_dbg(>dev, "start programming...\n");
 
/* initialize the FPGA Manager */
-- 
2.29.2


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


[PATCH v4 06/10] of: kconfig: of_overlay uses firmwaremgr_load_file

2021-06-16 Thread Steffen Trumtrar
From: Steffen Trumtrar 

As of_firmware.c uses the firmwaremgr_load_file function, it depends on
FIRMWARE.

Signed-off-by: Steffen Trumtrar 
---
 drivers/of/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 23be25d85d09..e58fe50f7090 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -49,6 +49,7 @@ config OF_BAREBOX_ENV_IN_FS
 
 config OF_OVERLAY
select OFTREE
+   select FIRMWARE
bool "Devicetree overlays"
help
  Overlays allow to patch the devicetree. Unlike Linux, Barebox does
-- 
2.29.2


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


[PATCH v4 10/10] firmware: add support for compressed images

2021-06-16 Thread Steffen Trumtrar
At least bitstreams for FPGAs can consist of a lot of zeros depending on
device utilization. These bitstreams can be compressed very effectively.

Let the firmware code accept these images and decompress them before
handing it to the firmware-manager in question.

Signed-off-by: Steffen Trumtrar 

---

v3->v4: fix printf warning %s -> %d
v2->v3 - better error handling
   - fix free'ing and close'ing
   - remove O_CREAT for devicefd. Destination is always a device
 that shall be written with a firmware (FPGA etc). If it doesn't
 exist, creating it is useless.
---
 common/firmware.c | 52 +++
 1 file changed, 48 insertions(+), 4 deletions(-)

diff --git a/common/firmware.c b/common/firmware.c
index 58509d5da615..1d34090f0100 100644
--- a/common/firmware.c
+++ b/common/firmware.c
@@ -14,6 +14,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #define BUFSIZ 4096
 
@@ -211,12 +213,54 @@ int firmwaremgr_register(struct firmware_handler *fh)
  */
 int firmwaremgr_load_file(struct firmware_mgr *mgr, const char *firmware)
 {
-   int ret;
-   char *name = basprintf("/dev/%s", mgr->handler->id);
+   char *dst;
+   enum filetype type;
+   int ret = 0;
+   int firmwarefd = 0;
+   int devicefd = 0;
+
+   if (!firmware)
+   return -EINVAL;
+
+   if (!mgr->handler->id) {
+   pr_err("id not defined for handler\n");
+   return -ENODEV;
+   }
+
+   dst = basprintf("/dev/%s", mgr->handler->id);
+
+   type = file_name_detect_type(firmware);
+
+   if (type == filetype_unknown) {
+   ret = copy_file(firmware, dst, 0);
+   } else {
+   firmwarefd = open(firmware, O_RDONLY);
+   if (firmwarefd < 0) {
+   printf("could not open %d: %s\n", firmwarefd,
+  errno_str());
+   ret = firmwarefd;
+   goto out;
+   }
 
-   ret = copy_file(firmware, name, 0);
+   devicefd = open(dst, O_WRONLY);
+
+   if (devicefd < 0) {
+   printf("could not open %s: %s\n", dst, errno_str());
+   ret = devicefd;
+   goto out;
+   }
+
+   ret = uncompress_fd_to_fd(firmwarefd, devicefd,
+ uncompress_err_stdout);
+   }
+
+out:
+   free(dst);
 
-   free(name);
+   if (firmwarefd > 0)
+   close(firmwarefd);
+   if (devicefd > 0)
+   close(devicefd);
 
return ret;
 }
-- 
2.29.2


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


[PATCH v4 04/10] firmware: socfpga: change function prefixes

2021-06-16 Thread Steffen Trumtrar
Since there is now a fpgamgr framework in barebox, the function names are
misleading. Change that to be SoCFPGA specific.

Signed-off-by: Steffen Trumtrar 
---
 drivers/firmware/socfpga.c | 58 +++---
 1 file changed, 29 insertions(+), 29 deletions(-)

diff --git a/drivers/firmware/socfpga.c b/drivers/firmware/socfpga.c
index c468c743720f..14875214b1aa 100644
--- a/drivers/firmware/socfpga.c
+++ b/drivers/firmware/socfpga.c
@@ -92,12 +92,12 @@ struct fpgamgr {
 };
 
 /* Get the FPGA mode */
-static uint32_t fpgamgr_get_mode(struct fpgamgr *mgr)
+static uint32_t socfpga_fpgamgr_get_mode(struct fpgamgr *mgr)
 {
return readl(mgr->regs + FPGAMGRREGS_STAT) & FPGAMGRREGS_STAT_MODE_MASK;
 }
 
-static int fpgamgr_dclkcnt_set(struct fpgamgr *mgr, unsigned long cnt)
+static int socfpga_fpgamgr_dclkcnt_set(struct fpgamgr *mgr, unsigned long cnt)
 {
uint64_t start;
 
@@ -121,7 +121,7 @@ static int fpgamgr_dclkcnt_set(struct fpgamgr *mgr, 
unsigned long cnt)
 }
 
 /* Start the FPGA programming by initialize the FPGA Manager */
-static int fpgamgr_program_init(struct fpgamgr *mgr)
+static int socfpga_fpgamgr_program_init(struct fpgamgr *mgr)
 {
unsigned long reg;
uint32_t ctrl = 0, ratio;
@@ -170,7 +170,7 @@ static int fpgamgr_program_init(struct fpgamgr *mgr)
/* (1) wait until FPGA enter reset phase */
start = get_time_ns();
while (1) {
-   if (fpgamgr_get_mode(mgr) == FPGAMGRREGS_MODE_RESETPHASE)
+   if (socfpga_fpgamgr_get_mode(mgr) == 
FPGAMGRREGS_MODE_RESETPHASE)
break;
if (is_timeout(start, 100 * MSECOND))
return -ETIMEDOUT;
@@ -184,7 +184,7 @@ static int fpgamgr_program_init(struct fpgamgr *mgr)
/* (2) wait until FPGA enter configuration phase */
start = get_time_ns();
while (1) {
-   if (fpgamgr_get_mode(mgr) == FPGAMGRREGS_MODE_CFGPHASE)
+   if (socfpga_fpgamgr_get_mode(mgr) == FPGAMGRREGS_MODE_CFGPHASE)
break;
if (is_timeout(start, 100 * MSECOND))
return -ETIMEDOUT;
@@ -202,7 +202,7 @@ static int fpgamgr_program_init(struct fpgamgr *mgr)
 }
 
 /* Ensure the FPGA entering config done */
-static int fpgamgr_program_poll_cd(struct fpgamgr *mgr)
+static int socfpga_fpgamgr_program_poll_cd(struct fpgamgr *mgr)
 {
unsigned long reg;
uint32_t val;
@@ -236,18 +236,18 @@ static int fpgamgr_program_poll_cd(struct fpgamgr *mgr)
 }
 
 /* Ensure the FPGA entering init phase */
-static int fpgamgr_program_poll_initphase(struct fpgamgr *mgr)
+static int socfpga_fpgamgr_program_poll_initphase(struct fpgamgr *mgr)
 {
uint64_t start;
 
/* additional clocks for the CB to enter initialization phase */
-   if (fpgamgr_dclkcnt_set(mgr, 0x4) != 0)
+   if (socfpga_fpgamgr_dclkcnt_set(mgr, 0x4) != 0)
return -5;
 
/* (4) wait until FPGA enter init phase or user mode */
start = get_time_ns();
while (1) {
-   int mode = fpgamgr_get_mode(mgr);
+   int mode = socfpga_fpgamgr_get_mode(mgr);
 
if (mode == FPGAMGRREGS_MODE_INITPHASE ||
mode == FPGAMGRREGS_MODE_USERMODE)
@@ -261,19 +261,19 @@ static int fpgamgr_program_poll_initphase(struct fpgamgr 
*mgr)
 }
 
 /* Ensure the FPGA entering user mode */
-static int fpgamgr_program_poll_usermode(struct fpgamgr *mgr)
+static int socfpga_fpgamgr_program_poll_usermode(struct fpgamgr *mgr)
 {
uint32_t val;
uint64_t start;
 
/* additional clocks for the CB to exit initialization phase */
-   if (fpgamgr_dclkcnt_set(mgr, 0x5000) != 0)
+   if (socfpga_fpgamgr_dclkcnt_set(mgr, 0x5000) != 0)
return -7;
 
/* (5) wait until FPGA enter user mode */
start = get_time_ns();
while (1) {
-   if (fpgamgr_get_mode(mgr) == FPGAMGRREGS_MODE_USERMODE)
+   if (socfpga_fpgamgr_get_mode(mgr) == FPGAMGRREGS_MODE_USERMODE)
break;
if (is_timeout(start, 100 * MSECOND))
return -ETIMEDOUT;
@@ -291,7 +291,7 @@ static int fpgamgr_program_poll_usermode(struct fpgamgr 
*mgr)
  * Using FPGA Manager to program the FPGA
  * Return 0 for sucess
  */
-static int fpgamgr_program_start(struct firmware_handler *fh)
+static int socfpga_fpgamgr_program_start(struct firmware_handler *fh)
 {
struct fpgamgr *mgr = container_of(fh, struct fpgamgr, fh);
int status;
@@ -313,7 +313,7 @@ static int fpgamgr_program_start(struct firmware_handler 
*fh)
dev_dbg(>dev, "start programming...\n");
 
/* initialize the FPGA Manager */
-   status = fpgamgr_program_init(mgr);
+   status = socfpga_fpgamgr_program_init(mgr);
if (status) {
dev_err(>dev, "pr

[PATCH 2/2] firmware: socfpga: set APPLYCFG after loading bitstream

2021-06-18 Thread Steffen Trumtrar
To make changes to the SDRAM controller effective, the APPLYCFG bit must
be set after programming the bitstream to the FPGA. This has to be done
without any SDRAM usage. Therefore copy the function to execute to the
OCRAM and execute it from there.

Signed-off-by: Steffen Trumtrar 
---
 .../mach-socfpga/include/mach/cyclone5-regs.h |  1 +
 drivers/firmware/Makefile |  2 +-
 drivers/firmware/socfpga.c| 21 +++
 drivers/firmware/socfpga_sdr.S| 17 +++
 4 files changed, 40 insertions(+), 1 deletion(-)
 create mode 100644 drivers/firmware/socfpga_sdr.S

diff --git a/arch/arm/mach-socfpga/include/mach/cyclone5-regs.h 
b/arch/arm/mach-socfpga/include/mach/cyclone5-regs.h
index e88daf718917..1a7d787a27bf 100644
--- a/arch/arm/mach-socfpga/include/mach/cyclone5-regs.h
+++ b/arch/arm/mach-socfpga/include/mach/cyclone5-regs.h
@@ -18,5 +18,6 @@
 #define CYCLONE5_SYSMGR_ADDRESS0xffd08000
 #define CYCLONE5_SCANMGR_ADDRESS   0xfff02000
 #define CYCLONE5_SMP_TWD_ADDRESS   0xfffec600
+#define CYCLONE5_OCRAM_ADDRESS 0x
 
 #endif /* __MACH_SOCFPGA_REGS_H */
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index b162b08b0a80..bbd2bcda9780 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -1,3 +1,3 @@
 obj-$(CONFIG_FIRMWARE_ALTERA_SERIAL) += altera_serial.o
-obj-$(CONFIG_FIRMWARE_ALTERA_SOCFPGA) += socfpga.o
+obj-$(CONFIG_FIRMWARE_ALTERA_SOCFPGA) += socfpga.o socfpga_sdr.o
 obj-$(CONFIG_FIRMWARE_ZYNQMP_FPGA) += zynqmp-fpga.o
diff --git a/drivers/firmware/socfpga.c b/drivers/firmware/socfpga.c
index 393c78c45d79..c468c743720f 100644
--- a/drivers/firmware/socfpga.c
+++ b/drivers/firmware/socfpga.c
@@ -38,6 +38,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 
 #define FPGAMGRREGS_STAT   0x0
 #define FPGAMGRREGS_CTRL   0x4
@@ -77,6 +80,9 @@
 #define CDRATIO_x4 0x2
 #define CDRATIO_x8 0x3
 
+extern void socfpga_sdram_apply_static_cfg(void __iomem *sdrctrlgrp);
+extern void socfpga_sdram_apply_static_cfg_end(void *);
+
 struct fpgamgr {
struct firmware_handler fh;
struct device_d dev;
@@ -353,6 +359,9 @@ static int fpgamgr_program_finish(struct firmware_handler 
*fh)
 {
struct fpgamgr *mgr = container_of(fh, struct fpgamgr, fh);
int status;
+   unsigned int func_size = _sdram_apply_static_cfg_end -
+_sdram_apply_static_cfg;
+   void (*ocram_func)(void __iomem *ocram_base);
 
/* Ensure the FPGA entering config done */
status = fpgamgr_program_poll_cd(mgr);
@@ -382,6 +391,18 @@ static int fpgamgr_program_finish(struct firmware_handler 
*fh)
return status;
}
 
+   remap_range((void *)CYCLONE5_OCRAM_ADDRESS, PAGE_SIZE, MAP_CACHED);
+
+   dev_dbg(>dev, "Setting APPLYCFG bit...\n");
+
+   ocram_func = fncpy((void __iomem *)CYCLONE5_OCRAM_ADDRESS,
+  _sdram_apply_static_cfg, func_size);
+
+   sync_caches_for_execution();
+
+   ocram_func((void __iomem *) (CYCLONE5_SDR_ADDRESS +
+SDR_CTRLGRP_STATICCFG_ADDRESS));
+
return 0;
 }
 
diff --git a/drivers/firmware/socfpga_sdr.S b/drivers/firmware/socfpga_sdr.S
new file mode 100644
index ..d634d6362722
--- /dev/null
+++ b/drivers/firmware/socfpga_sdr.S
@@ -0,0 +1,17 @@
+#include 
+
+   .arch   armv7-a
+   .arm
+
+/*
+ * r0 : sdram controller staticcfg
+ */
+
+ENTRY(socfpga_sdram_apply_static_cfg)
+   push {ip,lr}
+   ldr r1, [r0]
+   orr r1, r1, #8
+   str r1, [r0]
+   pop {ip,pc}
+   .align
+ENTRY(socfpga_sdram_apply_static_cfg_end)
-- 
2.29.2


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


[PATCH 1/2] ARM: mmu: inherit pte flags from pmd

2021-06-18 Thread Steffen Trumtrar
From: Sascha Hauer 

When creating a 2nd level page table from a section inherit the flags
from the section rather than assuming the section was mapped cached
previously. This fixes creating a 2nd level pagetable when the section
was mapped differently than we expected.

Signed-off-by: Sascha Hauer 
---
 arch/arm/cpu/mmu.c | 28 
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c
index 6af228505dd1..6388e1bf14f6 100644
--- a/arch/arm/cpu/mmu.c
+++ b/arch/arm/cpu/mmu.c
@@ -138,6 +138,29 @@ static u32 *arm_create_pte(unsigned long virt, uint32_t 
flags)
return table;
 }
 
+static u32 pmd_flags_to_pte(u32 pmd)
+{
+   u32 pte = 0;
+
+   if (pmd & PMD_SECT_BUFFERABLE)
+   pte |= PTE_BUFFERABLE;
+   if (pmd & PMD_SECT_CACHEABLE)
+   pte |= PTE_CACHEABLE;
+   if (pmd & PMD_SECT_nG)
+   pte |= PTE_EXT_NG;
+   if (pmd & PMD_SECT_XN)
+   pte |= PTE_EXT_XN;
+
+   /* TEX[2:0] */
+   pte |= PTE_EXT_TEX((pmd >> 12) & 7);
+   /* AP[1:0] */
+   pte |= ((pmd >> 10) & 0x3) << 4;
+   /* AP[2] */
+   pte |= ((pmd >> 15) & 0x1) << 9;
+
+   return pte;
+}
+
 int arch_remap_range(void *start, size_t size, unsigned flags)
 {
u32 addr = (u32)start;
@@ -206,11 +229,8 @@ int arch_remap_range(void *start, size_t size, unsigned 
flags)
 * If PTE is not found it means that
 * we needs to split this section and
 * create a new page table for it
-*
-* NOTE: Here we assume that section
-* we just split was mapped as cached
 */
-   table = arm_create_pte(addr, pte_flags_cached);
+   table = arm_create_pte(addr, 
pmd_flags_to_pte(*pgd));
pte = find_pte(addr);
BUG_ON(!pte);
}
-- 
2.29.2


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


Re: [PATCH v4 07/10] of: of_firmware: add support for fpga bridges

2021-06-18 Thread Steffen Trumtrar


Steffen Trumtrar  writes:
> diff --git a/include/of.h b/include/of.h
> index 645f429bdeed..3c922bdb1414 100644
> --- a/include/of.h
> +++ b/include/of.h
> +int of_firmware_load_overlay(struct device_node *overlay, const char *path);
> +#else
> +static inline int of_firmware_load_overlay(const char *path)

Meh, don't know how that happend, but this is obviously wrong :(
Will resend.


Steffen

--
Pengutronix e.K.    | Dipl.-Inform. Steffen Trumtrar |
Steuerwalder Str. 21| https://www.pengutronix.de/|
31137 Hildesheim, Germany   | Phone: +49-5121-206917-0   |
Amtsgericht Hildesheim, HRA 2686| Fax:   +49-5121-206917-|

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


[PATCH v2] firmware: socfpga: set APPLYCFG after loading bitstream

2021-06-25 Thread Steffen Trumtrar
To make changes to the SDRAM controller effective, the APPLYCFG bit must
be set after programming the bitstream to the FPGA. This has to be done
without any SDRAM usage. Therefore copy the function to execute to the
OCRAM and execute it from there.

Signed-off-by: Steffen Trumtrar 
---

Notes:
v1: Link: 
https://lore.barebox.org/20210618080939.15343-2-s.trumt...@pengutronix.de

Changes since v1:
  - include feedback from Ahmad

 .../mach-socfpga/include/mach/cyclone5-regs.h |  1 +
 drivers/firmware/Makefile |  2 +-
 drivers/firmware/socfpga.c| 21 +++
 drivers/firmware/socfpga_sdr.S| 20 ++
 4 files changed, 43 insertions(+), 1 deletion(-)
 create mode 100644 drivers/firmware/socfpga_sdr.S

diff --git a/arch/arm/mach-socfpga/include/mach/cyclone5-regs.h 
b/arch/arm/mach-socfpga/include/mach/cyclone5-regs.h
index e88daf718917..1a7d787a27bf 100644
--- a/arch/arm/mach-socfpga/include/mach/cyclone5-regs.h
+++ b/arch/arm/mach-socfpga/include/mach/cyclone5-regs.h
@@ -18,5 +18,6 @@
 #define CYCLONE5_SYSMGR_ADDRESS0xffd08000
 #define CYCLONE5_SCANMGR_ADDRESS   0xfff02000
 #define CYCLONE5_SMP_TWD_ADDRESS   0xfffec600
+#define CYCLONE5_OCRAM_ADDRESS 0x
 
 #endif /* __MACH_SOCFPGA_REGS_H */
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index b162b08b0a80..bbd2bcda9780 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -1,3 +1,3 @@
 obj-$(CONFIG_FIRMWARE_ALTERA_SERIAL) += altera_serial.o
-obj-$(CONFIG_FIRMWARE_ALTERA_SOCFPGA) += socfpga.o
+obj-$(CONFIG_FIRMWARE_ALTERA_SOCFPGA) += socfpga.o socfpga_sdr.o
 obj-$(CONFIG_FIRMWARE_ZYNQMP_FPGA) += zynqmp-fpga.o
diff --git a/drivers/firmware/socfpga.c b/drivers/firmware/socfpga.c
index 61c2b02eca42..b16bd33de408 100644
--- a/drivers/firmware/socfpga.c
+++ b/drivers/firmware/socfpga.c
@@ -39,6 +39,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 
 #define FPGAMGRREGS_STAT   0x0
 #define FPGAMGRREGS_CTRL   0x4
@@ -78,6 +81,10 @@
 #define CDRATIO_x4 0x2
 #define CDRATIO_x8 0x3
 
+extern void socfpga_sdram_apply_static_cfg(void __iomem *sdrctrlgrp);
+extern void socfpga_sdram_apply_static_cfg_end(void *);
+extern const u32 socfpga_sdram_apply_static_cfg_sz;
+
 struct fpgamgr {
struct firmware_handler fh;
struct device_d dev;
@@ -345,6 +352,7 @@ static int socfpga_fpgamgr_program_finish(struct 
firmware_handler *fh)
 {
struct fpgamgr *mgr = container_of(fh, struct fpgamgr, fh);
int status;
+   void (*ocram_func)(void __iomem *ocram_base);
 
/* Ensure the FPGA entering config done */
status = socfpga_fpgamgr_program_poll_cd(mgr);
@@ -374,6 +382,19 @@ static int socfpga_fpgamgr_program_finish(struct 
firmware_handler *fh)
return status;
}
 
+   remap_range((void *)CYCLONE5_OCRAM_ADDRESS, PAGE_SIZE, MAP_CACHED);
+
+   dev_dbg(>dev, "Setting APPLYCFG bit...\n");
+
+   ocram_func = fncpy((void __iomem *)CYCLONE5_OCRAM_ADDRESS,
+  _sdram_apply_static_cfg,
+  socfpga_sdram_apply_static_cfg_sz);
+
+   sync_caches_for_execution();
+
+   ocram_func((void __iomem *) (CYCLONE5_SDR_ADDRESS +
+SDR_CTRLGRP_STATICCFG_ADDRESS));
+
return 0;
 }
 
diff --git a/drivers/firmware/socfpga_sdr.S b/drivers/firmware/socfpga_sdr.S
new file mode 100644
index ..b895fb293cbd
--- /dev/null
+++ b/drivers/firmware/socfpga_sdr.S
@@ -0,0 +1,20 @@
+#include 
+
+   .arch   armv7-a
+   .arm
+
+/*
+ * r0 : sdram controller staticcfg
+ */
+
+ENTRY(socfpga_sdram_apply_static_cfg)
+   push {ip,lr}
+   ldr r1, [r0]
+   orr r1, r1, #8
+   str r1, [r0]
+   pop {ip,pc}
+   .align
+ENDPROC(socfpga_sdram_apply_static_cfg)
+
+ENTRY(socfpga_sdram_apply_static_cfg_sz)
+   .word . - socfpga_sdram_apply_static_cfg;
-- 
2.30.2


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


[PATCH v3 03/10] drivers: fpga: add socfpga bridges

2021-06-15 Thread Steffen Trumtrar
Import the SoCFPGA bridges drivers from linux v4.10-rc2.

Description from the original commit:
e5f8efa5c8bf86c1fa698551d54db8f6aee221fd

ARM: socfpga: fpga bridge driver support

Supports Altera SOCFPGA bridges:
 * fpga2sdram
 * fpga2hps
 * hps2fpga
 * lwhps2fpga

Allows enabling/disabling the bridges through the FPGA
Bridge Framework API functions.

The fpga2sdram driver only supports enabling and disabling
of the ports that been configured early on.  This is due to
a hardware limitation where the read, write, and command
ports on the fpga2sdram bridge can only be reconfigured
while there are no transactions to the sdram, i.e. when
running out of OCRAM before the kernel boots.

Device tree property 'init-val' configures the driver to
enable or disable the bridge during probe.  If the property
does not exist, the driver will leave the bridge in its
current state.

Signed-off-by: Alan Tull 
Signed-off-by: Matthew Gerlach 
Signed-off-by: Dinh Nguyen 
Signed-off-by: Greg Kroah-Hartman 

Signed-off-by: Steffen Trumtrar 
---
 drivers/fpga/Kconfig |   8 +
 drivers/fpga/Makefile|   1 +
 drivers/fpga/fpga-bridge.c   |   2 +-
 drivers/fpga/socfpga-fpga2sdram-bridge.c | 139 ++
 drivers/fpga/socfpga-hps2fpga-bridge.c   | 179 +++
 5 files changed, 328 insertions(+), 1 deletion(-)
 create mode 100644 drivers/fpga/socfpga-fpga2sdram-bridge.c
 create mode 100644 drivers/fpga/socfpga-hps2fpga-bridge.c

diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index fccdbff6eb3f..64ce9f91b6a8 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -17,6 +17,14 @@ config FPGA_BRIDGE
  Say Y here if you want to support bridges connected between host
  processors and FPGAs or between FPGAs.
 
+config SOCFPGA_FPGA_BRIDGE
+   tristate "Altera SoCFPGA FPGA Bridges"
+   depends on ARCH_SOCFPGA && FPGA_BRIDGE
+   select RESET_CONTROLLER
+   help
+ Say Y to enable drivers for FPGA bridges for Altera SOCFPGA
+ devices.
+
 endif # FPGA
 
 endmenu
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index fc71a29d3b33..86178fe7c078 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -4,3 +4,4 @@
 
 # FPGA Bridge Drivers
 obj-$(CONFIG_FPGA_BRIDGE)  += fpga-bridge.o
+obj-$(CONFIG_SOCFPGA_FPGA_BRIDGE)  += socfpga-hps2fpga-bridge.o 
socfpga-fpga2sdram-bridge.o
diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c
index 6e8dcbfc0d16..6f9e943de904 100644
--- a/drivers/fpga/fpga-bridge.c
+++ b/drivers/fpga/fpga-bridge.c
@@ -68,7 +68,7 @@ struct fpga_bridge *of_fpga_bridge_get(struct device_node *np)
 {
struct device_d *dev;
struct fpga_bridge *bridge;
-   int ret = -ENODEV;
+   int ret = -EPROBE_DEFER;
 
dev = of_find_device_by_node(np);
if (!dev || !dev->priv)
diff --git a/drivers/fpga/socfpga-fpga2sdram-bridge.c 
b/drivers/fpga/socfpga-fpga2sdram-bridge.c
new file mode 100644
index ..a9760597ddb5
--- /dev/null
+++ b/drivers/fpga/socfpga-fpga2sdram-bridge.c
@@ -0,0 +1,139 @@
+/*
+ * FPGA to SDRAM Bridge Driver for Altera SoCFPGA Devices
+ *
+ *  Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This driver manages a bridge between an FPGA and the SDRAM used by the ARM
+ * host processor system (HPS).
+ *
+ * The bridge contains 4 read ports, 4 write ports, and 6 command ports.
+ * Reconfiguring these ports requires that no SDRAM transactions occur during
+ * reconfiguration.  The code reconfiguring the ports cannot run out of SDRAM
+ * nor can the FPGA access the SDRAM during reconfiguration.  This driver does
+ * not support reconfiguring the ports.  The ports are configured by code
+ * running out of on chip ram before Linux is started and the configuration
+ * is passed in a handoff register in the system manager.
+ *
+ * This driver supports enabling and disabling of the configured ports, which
+ * allows for safe reprogramming of the FPGA, assuming that the new FPGA image
+ * uses the same port configuration.  Bridges must be disabled before
+ * reprogramming the FPGA and re-enabled after the FPGA has been programmed.
+ */
+
+#include 
+#include 
+#in

[PATCH v3 05/10] firmware: import fpga-mgr.h from linux

2021-06-15 Thread Steffen Trumtrar
Instead of defining the fpga-mgr structure in the socfpga driver, import
the fpga-mgr.h file from linux v4.13.

Signed-off-by: Steffen Trumtrar 
---
 drivers/firmware/socfpga.c |   9 +---
 include/firmware.h |   1 +
 include/fpga-mgr.h | 102 +
 3 files changed, 104 insertions(+), 8 deletions(-)
 create mode 100644 include/fpga-mgr.h

diff --git a/drivers/firmware/socfpga.c b/drivers/firmware/socfpga.c
index 14875214b1aa..605c931604c9 100644
--- a/drivers/firmware/socfpga.c
+++ b/drivers/firmware/socfpga.c
@@ -27,6 +27,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -83,14 +84,6 @@
 extern void socfpga_sdram_apply_static_cfg(void __iomem *sdrctrlgrp);
 extern void socfpga_sdram_apply_static_cfg_end(void *);
 
-struct fpgamgr {
-   struct firmware_handler fh;
-   struct device_d dev;
-   void __iomem *regs;
-   void __iomem *regs_data;
-   int programmed;
-};
-
 /* Get the FPGA mode */
 static uint32_t socfpga_fpgamgr_get_mode(struct fpgamgr *mgr)
 {
diff --git a/include/firmware.h b/include/firmware.h
index 19777d9bf711..2fef97a48f56 100644
--- a/include/firmware.h
+++ b/include/firmware.h
@@ -13,6 +13,7 @@ struct firmware_handler {
char *id; /* unique identifier for this firmware device */
char *model; /* description for this device */
struct device_d *dev;
+   void *priv;
/* called once to prepare the firmware's programming cycle */
int (*open)(struct firmware_handler*);
/* called multiple times to program the firmware with the given data */
diff --git a/include/fpga-mgr.h b/include/fpga-mgr.h
new file mode 100644
index ..a120b3918990
--- /dev/null
+++ b/include/fpga-mgr.h
@@ -0,0 +1,102 @@
+/*
+ * FPGA Framework
+ *
+ *  Copyright (C) 2013-2015 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _LINUX_FPGA_MGR_H
+#define _LINUX_FPGA_MGR_H
+
+#include 
+
+struct fpga_manager;
+
+/**
+ * enum fpga_mgr_states - fpga framework states
+ * @FPGA_MGR_STATE_UNKNOWN: can't determine state
+ * @FPGA_MGR_STATE_POWER_OFF: FPGA power is off
+ * @FPGA_MGR_STATE_POWER_UP: FPGA reports power is up
+ * @FPGA_MGR_STATE_RESET: FPGA in reset state
+ * @FPGA_MGR_STATE_FIRMWARE_REQ: firmware request in progress
+ * @FPGA_MGR_STATE_FIRMWARE_REQ_ERR: firmware request failed
+ * @FPGA_MGR_STATE_WRITE_INIT: preparing FPGA for programming
+ * @FPGA_MGR_STATE_WRITE_INIT_ERR: Error during WRITE_INIT stage
+ * @FPGA_MGR_STATE_WRITE: writing image to FPGA
+ * @FPGA_MGR_STATE_WRITE_ERR: Error while writing FPGA
+ * @FPGA_MGR_STATE_WRITE_COMPLETE: Doing post programming steps
+ * @FPGA_MGR_STATE_WRITE_COMPLETE_ERR: Error during WRITE_COMPLETE
+ * @FPGA_MGR_STATE_OPERATING: FPGA is programmed and operating
+ */
+enum fpga_mgr_states {
+   /* default FPGA states */
+   FPGA_MGR_STATE_UNKNOWN,
+   FPGA_MGR_STATE_POWER_OFF,
+   FPGA_MGR_STATE_POWER_UP,
+   FPGA_MGR_STATE_RESET,
+
+   /* getting an image for loading */
+   FPGA_MGR_STATE_FIRMWARE_REQ,
+   FPGA_MGR_STATE_FIRMWARE_REQ_ERR,
+
+   /* write sequence: init, write, complete */
+   FPGA_MGR_STATE_WRITE_INIT,
+   FPGA_MGR_STATE_WRITE_INIT_ERR,
+   FPGA_MGR_STATE_WRITE,
+   FPGA_MGR_STATE_WRITE_ERR,
+   FPGA_MGR_STATE_WRITE_COMPLETE,
+   FPGA_MGR_STATE_WRITE_COMPLETE_ERR,
+
+   /* fpga is programmed and operating */
+   FPGA_MGR_STATE_OPERATING,
+};
+
+/*
+ * FPGA Manager flags
+ * FPGA_MGR_PARTIAL_RECONFIG: do partial reconfiguration if supported
+ * FPGA_MGR_EXTERNAL_CONFIG: FPGA has been configured prior to Linux booting
+ * FPGA_MGR_BITSTREAM_LSB_FIRST: SPI bitstream bit order is LSB first
+ * FPGA_MGR_COMPRESSED_BITSTREAM: FPGA bitstream is compressed
+ */
+#define FPGA_MGR_PARTIAL_RECONFIG  BIT(0)
+#define FPGA_MGR_EXTERNAL_CONFIG   BIT(1)
+#define FPGA_MGR_ENCRYPTED_BITSTREAM   BIT(2)
+#define FPGA_MGR_BITSTREAM_LSB_FIRST   BIT(3)
+#define FPGA_MGR_COMPRESSED_BITSTREAM  BIT(4)
+
+/**
+ * struct fpga_image_info - information specific to a FPGA image
+ * @flags: boolean flags as defined above
+ * @enable_timeout_us: maximum time to enable traffic through bridge (uSec)
+ * @disable_timeout_us: maximum time to disable traffic through bridge (uSec)
+ * @config_complete_timeout_us: maximum time for FPGA to switch to operating
+ *status in the write_compl

[PATCH v3 10/10] firmware: add support for compressed images

2021-06-15 Thread Steffen Trumtrar
At least bitstreams for FPGAs can consist of a lot of zeros depending on
device utilization. These bitstreams can be compressed very effectively.

Let the firmware code accept these images and decompress them before
handing it to the firmware-manager in question.

Signed-off-by: Steffen Trumtrar 

---

v2->v3 - better error handling
   - fix free'ing and close'ing
   - remove O_CREAT for devicefd. Destination is always a device
 that shall be written with a firmware (FPGA etc). If it doesn't
 exist, creating it is useless.
---
 common/firmware.c | 52 +++
 1 file changed, 48 insertions(+), 4 deletions(-)

diff --git a/common/firmware.c b/common/firmware.c
index 58509d5da615..47defbd739ca 100644
--- a/common/firmware.c
+++ b/common/firmware.c
@@ -14,6 +14,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #define BUFSIZ 4096
 
@@ -211,12 +213,54 @@ int firmwaremgr_register(struct firmware_handler *fh)
  */
 int firmwaremgr_load_file(struct firmware_mgr *mgr, const char *firmware)
 {
-   int ret;
-   char *name = basprintf("/dev/%s", mgr->handler->id);
+   char *dst;
+   enum filetype type;
+   int ret = 0;
+   int firmwarefd = 0;
+   int devicefd = 0;
+
+   if (!firmware)
+   return -EINVAL;
+
+   if (!mgr->handler->id) {
+   pr_err("id not defined for handler\n");
+   return -ENODEV;
+   }
+
+   dst = basprintf("/dev/%s", mgr->handler->id);
+
+   type = file_name_detect_type(firmware);
+
+   if (type == filetype_unknown) {
+   ret = copy_file(firmware, dst, 0);
+   } else {
+   firmwarefd = open(firmware, O_RDONLY);
+   if (firmwarefd < 0) {
+   printf("could not open %s: %s\n", firmwarefd,
+  errno_str());
+   ret = firmwarefd;
+   goto out;
+   }
 
-   ret = copy_file(firmware, name, 0);
+   devicefd = open(dst, O_WRONLY);
+
+   if (devicefd < 0) {
+   printf("could not open %s: %s\n", dst, errno_str());
+   ret = devicefd;
+   goto out;
+   }
+
+   ret = uncompress_fd_to_fd(firmwarefd, devicefd,
+ uncompress_err_stdout);
+   }
+
+out:
+   free(dst);
 
-   free(name);
+   if (firmwarefd > 0)
+   close(firmwarefd);
+   if (devicefd > 0)
+   close(devicefd);
 
return ret;
 }
-- 
2.29.2


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


[PATCH v3 07/10] of: of_firmware: add support for fpga bridges

2021-06-15 Thread Steffen Trumtrar
Add support for potentially defined FPGA-bridges in the overlay.

While at it also add support for loading the firmware directly via a
path instead of 'needing' an overlay for that.
The direct loading will be done with the existent firmwareload command.

Signed-off-by: Steffen Trumtrar 

---

v2->v3 - basprintf -> plain 'compatible = "fpga-region"'
   - assign root in if-clause
---
 drivers/of/Makefile  |   3 +-
 drivers/of/of_firmware.c | 129 +--
 include/of.h |  23 +--
 3 files changed, 142 insertions(+), 13 deletions(-)

diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index b6847752d247..6199c9791f52 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -6,4 +6,5 @@ obj-y += partition.o
 obj-y += of_net.o
 obj-$(CONFIG_MTD) += of_mtd.o
 obj-$(CONFIG_OF_BAREBOX_DRIVERS) += barebox.o
-obj-$(CONFIG_OF_OVERLAY) += overlay.o resolver.o of_firmware.o
+obj-$(CONFIG_OF_OVERLAY) += overlay.o resolver.o
+obj-$(CONFIG_FIRMWARE) += of_firmware.o
diff --git a/drivers/of/of_firmware.c b/drivers/of/of_firmware.c
index 096f84572e63..26864a6a13ef 100644
--- a/drivers/of/of_firmware.c
+++ b/drivers/of/of_firmware.c
@@ -4,12 +4,52 @@
  */
 #include 
 #include 
+#include 
 #include 
 
 struct overlay_info {
const char *firmware_path;
 };
 
+#ifdef CONFIG_FPGA_BRIDGE
+static int of_get_bridges(struct device_node *region, struct list_head 
*bridges)
+{
+   struct device_node *br, *parent_br = NULL;
+   int i, ret;
+
+   /* If parent is a bridge, add to list */
+   ret = fpga_bridge_get_to_list(region->parent, bridges);
+   if (!ret) {
+   parent_br = region->parent;
+   pr_debug("Add %s to list of bridges\n", parent_br->name);
+   }
+
+   for (i = 0; ; i++) {
+   br = of_parse_phandle(region, "fpga-bridges", i);
+   if (!br)
+   break;
+
+   /* If parent bridge is in list, skip it. */
+   if (br == parent_br)
+   continue;
+
+   /* If node is a bridge, get it and add to list */
+   ret = fpga_bridge_get_to_list(br, bridges);
+   if (ret)
+   return ret;
+
+   pr_debug("Add %s to list of bridges\n", br->name);
+   }
+
+   return 0;
+}
+#else
+static int of_get_bridges(struct device_node *np, struct list_head *br)
+{
+   return 0;
+}
+#endif
+
 static struct firmware_mgr *of_node_get_mgr(struct device_node *np)
 {
struct device_node *mgr_node;
@@ -25,6 +65,35 @@ static struct firmware_mgr *of_node_get_mgr(struct 
device_node *np)
return NULL;
 }
 
+static int of_load_firmware(struct device_node *target, const char *path)
+{
+   struct list_head bridge_list;
+   struct firmware_mgr *mgr;
+   int err;
+
+   mgr = of_node_get_mgr(target);
+   if (!mgr)
+   return -EINVAL;
+
+   pr_debug("Found firmware manager @%s\n", target->name);
+
+   INIT_LIST_HEAD(_list);
+
+   of_get_bridges(target, _list);
+
+   fpga_bridges_disable(_list);
+
+   pr_debug("Loading %s to %s\n", path, target->name);
+
+   err = firmwaremgr_load_file(mgr, path);
+
+   fpga_bridges_enable(_list);
+
+   fpga_bridges_put(_list);
+
+   return err;
+}
+
 static int load_firmware(struct device_node *target,
 struct device_node *fragment, void *data)
 {
@@ -33,7 +102,6 @@ static int load_firmware(struct device_node *target,
const char *firmware_path = info->firmware_path;
char *firmware;
int err;
-   struct firmware_mgr *mgr;
 
err = of_property_read_string(fragment,
  "firmware-name", _name);
@@ -46,21 +114,70 @@ static int load_firmware(struct device_node *target,
if (!target)
return -EINVAL;
 
-   mgr = of_node_get_mgr(target);
-   if (!mgr)
-   return -EINVAL;
-
firmware = basprintf("%s/%s", firmware_path, firmware_name);
if (!firmware)
return -ENOMEM;
 
-   err = firmwaremgr_load_file(mgr, firmware);
+   err = of_load_firmware(target, firmware);
 
free(firmware);
 
return err;
 }
 
+int of_firmware_load_file(const char *path, const char *compatible,
+ const char *search_path, const char *firmware)
+{
+   struct overlay_info info = {
+   .firmware_path = search_path,
+   };
+   struct device_node *target;
+   struct device_node *node;
+   struct device_node *root;
+
+   if (!compatible)
+   compatible = "fpga-region";
+
+   /*
+* firmware-name not specified. Use load_firmware function to get it 
from
+* the devicetree. This allows loading firmware to multiple devices.
+*/
+ 

[PATCH v3 09/10] drivers: firmware: socfpga: remove bridges shutdown

2021-06-15 Thread Steffen Trumtrar
The bridges are now handled via the bridges driver. There is no
need to hardcode the memory writes anymore.

Signed-off-by: Steffen Trumtrar 
---
 drivers/firmware/socfpga.c | 9 -
 1 file changed, 9 deletions(-)

diff --git a/drivers/firmware/socfpga.c b/drivers/firmware/socfpga.c
index 605c931604c9..eb3fc557c7fe 100644
--- a/drivers/firmware/socfpga.c
+++ b/drivers/firmware/socfpga.c
@@ -294,15 +294,6 @@ static int socfpga_fpgamgr_program_start(struct 
firmware_handler *fh)
/* disable all signals from hps peripheral controller to fpga */
writel(0, SYSMGR_FPGAINTF_MODULE);
 
-   /* disable all signals from fpga to hps sdram */
-   writel(0, (CYCLONE5_SDR_ADDRESS + SDR_CTRLGRP_FPGAPORTRST_ADDRESS));
-
-   /* disable all axi bridge (hps2fpga, lwhps2fpga & fpga2hps) */
-   writel(~0, CYCLONE5_RSTMGR_ADDRESS + RESET_MGR_BRG_MOD_RESET_OFS);
-
-   /* unmap the bridges from NIC-301 */
-   writel(0x1, CYCLONE5_L3REGS_ADDRESS);
-
dev_dbg(>dev, "start programming...\n");
 
/* initialize the FPGA Manager */
-- 
2.29.2


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


[PATCH v3 04/10] firmware: socfpga: change function prefixes

2021-06-15 Thread Steffen Trumtrar
Since there is now a fpgamgr framework in barebox, the function names are
misleading. Change that to be SoCFPGA specific.

Signed-off-by: Steffen Trumtrar 
---
 drivers/firmware/socfpga.c | 58 +++---
 1 file changed, 29 insertions(+), 29 deletions(-)

diff --git a/drivers/firmware/socfpga.c b/drivers/firmware/socfpga.c
index c468c743720f..14875214b1aa 100644
--- a/drivers/firmware/socfpga.c
+++ b/drivers/firmware/socfpga.c
@@ -92,12 +92,12 @@ struct fpgamgr {
 };
 
 /* Get the FPGA mode */
-static uint32_t fpgamgr_get_mode(struct fpgamgr *mgr)
+static uint32_t socfpga_fpgamgr_get_mode(struct fpgamgr *mgr)
 {
return readl(mgr->regs + FPGAMGRREGS_STAT) & FPGAMGRREGS_STAT_MODE_MASK;
 }
 
-static int fpgamgr_dclkcnt_set(struct fpgamgr *mgr, unsigned long cnt)
+static int socfpga_fpgamgr_dclkcnt_set(struct fpgamgr *mgr, unsigned long cnt)
 {
uint64_t start;
 
@@ -121,7 +121,7 @@ static int fpgamgr_dclkcnt_set(struct fpgamgr *mgr, 
unsigned long cnt)
 }
 
 /* Start the FPGA programming by initialize the FPGA Manager */
-static int fpgamgr_program_init(struct fpgamgr *mgr)
+static int socfpga_fpgamgr_program_init(struct fpgamgr *mgr)
 {
unsigned long reg;
uint32_t ctrl = 0, ratio;
@@ -170,7 +170,7 @@ static int fpgamgr_program_init(struct fpgamgr *mgr)
/* (1) wait until FPGA enter reset phase */
start = get_time_ns();
while (1) {
-   if (fpgamgr_get_mode(mgr) == FPGAMGRREGS_MODE_RESETPHASE)
+   if (socfpga_fpgamgr_get_mode(mgr) == 
FPGAMGRREGS_MODE_RESETPHASE)
break;
if (is_timeout(start, 100 * MSECOND))
return -ETIMEDOUT;
@@ -184,7 +184,7 @@ static int fpgamgr_program_init(struct fpgamgr *mgr)
/* (2) wait until FPGA enter configuration phase */
start = get_time_ns();
while (1) {
-   if (fpgamgr_get_mode(mgr) == FPGAMGRREGS_MODE_CFGPHASE)
+   if (socfpga_fpgamgr_get_mode(mgr) == FPGAMGRREGS_MODE_CFGPHASE)
break;
if (is_timeout(start, 100 * MSECOND))
return -ETIMEDOUT;
@@ -202,7 +202,7 @@ static int fpgamgr_program_init(struct fpgamgr *mgr)
 }
 
 /* Ensure the FPGA entering config done */
-static int fpgamgr_program_poll_cd(struct fpgamgr *mgr)
+static int socfpga_fpgamgr_program_poll_cd(struct fpgamgr *mgr)
 {
unsigned long reg;
uint32_t val;
@@ -236,18 +236,18 @@ static int fpgamgr_program_poll_cd(struct fpgamgr *mgr)
 }
 
 /* Ensure the FPGA entering init phase */
-static int fpgamgr_program_poll_initphase(struct fpgamgr *mgr)
+static int socfpga_fpgamgr_program_poll_initphase(struct fpgamgr *mgr)
 {
uint64_t start;
 
/* additional clocks for the CB to enter initialization phase */
-   if (fpgamgr_dclkcnt_set(mgr, 0x4) != 0)
+   if (socfpga_fpgamgr_dclkcnt_set(mgr, 0x4) != 0)
return -5;
 
/* (4) wait until FPGA enter init phase or user mode */
start = get_time_ns();
while (1) {
-   int mode = fpgamgr_get_mode(mgr);
+   int mode = socfpga_fpgamgr_get_mode(mgr);
 
if (mode == FPGAMGRREGS_MODE_INITPHASE ||
mode == FPGAMGRREGS_MODE_USERMODE)
@@ -261,19 +261,19 @@ static int fpgamgr_program_poll_initphase(struct fpgamgr 
*mgr)
 }
 
 /* Ensure the FPGA entering user mode */
-static int fpgamgr_program_poll_usermode(struct fpgamgr *mgr)
+static int socfpga_fpgamgr_program_poll_usermode(struct fpgamgr *mgr)
 {
uint32_t val;
uint64_t start;
 
/* additional clocks for the CB to exit initialization phase */
-   if (fpgamgr_dclkcnt_set(mgr, 0x5000) != 0)
+   if (socfpga_fpgamgr_dclkcnt_set(mgr, 0x5000) != 0)
return -7;
 
/* (5) wait until FPGA enter user mode */
start = get_time_ns();
while (1) {
-   if (fpgamgr_get_mode(mgr) == FPGAMGRREGS_MODE_USERMODE)
+   if (socfpga_fpgamgr_get_mode(mgr) == FPGAMGRREGS_MODE_USERMODE)
break;
if (is_timeout(start, 100 * MSECOND))
return -ETIMEDOUT;
@@ -291,7 +291,7 @@ static int fpgamgr_program_poll_usermode(struct fpgamgr 
*mgr)
  * Using FPGA Manager to program the FPGA
  * Return 0 for sucess
  */
-static int fpgamgr_program_start(struct firmware_handler *fh)
+static int socfpga_fpgamgr_program_start(struct firmware_handler *fh)
 {
struct fpgamgr *mgr = container_of(fh, struct fpgamgr, fh);
int status;
@@ -313,7 +313,7 @@ static int fpgamgr_program_start(struct firmware_handler 
*fh)
dev_dbg(>dev, "start programming...\n");
 
/* initialize the FPGA Manager */
-   status = fpgamgr_program_init(mgr);
+   status = socfpga_fpgamgr_program_init(mgr);
if (status) {
dev_err(>dev, "pr

[PATCH v3 02/10] drivers: add fpga bridge framework

2021-06-15 Thread Steffen Trumtrar
Import the fpga bridge framework from linux v4.10-rc2.

Description from the initial commit adding this to linux:
21aeda950c5f84a8351b862816d832120b217a9b

fpga: add fpga bridge framework

This framework adds API functions for enabling/
disabling FPGA bridges under kernel control.

This allows the Linux kernel to disable FPGA bridges
during FPGA reprogramming and to enable FPGA bridges
when FPGA reprogramming is done.  This framework is
be manufacturer-agnostic, allowing it to be used in
interfaces that use the FPGA Manager Framework to
reprogram FPGA's.

The functions are:
* of_fpga_bridge_get
* fpga_bridge_put
   Get/put an exclusive reference to a FPGA bridge.

* fpga_bridge_enable
* fpga_bridge_disable
   Enable/Disable traffic through a bridge.

* fpga_bridge_register
* fpga_bridge_unregister
   Register/unregister a device-specific low level FPGA
   Bridge driver.

Get an exclusive reference to a bridge and add it to a list:
* fpga_bridge_get_to_list

To enable/disable/put a set of bridges that are on a list:
* fpga_bridges_enable
* fpga_bridges_disable
* fpga_bridges_put

Signed-off-by: Alan Tull 

Signed-off-by: Steffen Trumtrar 

---

v2->v3: add fpga_bridges_put function to deallocate bridge list
---
 drivers/Kconfig|   1 +
 drivers/Makefile   |   1 +
 drivers/fpga/Kconfig   |  22 
 drivers/fpga/Makefile  |   6 +
 drivers/fpga/fpga-bridge.c | 243 +
 include/fpga-bridge.h  |  74 +++
 6 files changed, 347 insertions(+)
 create mode 100644 drivers/fpga/Kconfig
 create mode 100644 drivers/fpga/Makefile
 create mode 100644 drivers/fpga/fpga-bridge.c
 create mode 100644 include/fpga-bridge.h

diff --git a/drivers/Kconfig b/drivers/Kconfig
index 787d36693309..670e0a9f4c95 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -37,6 +37,7 @@ source "drivers/reset/Kconfig"
 source "drivers/pci/Kconfig"
 source "drivers/rtc/Kconfig"
 source "drivers/firmware/Kconfig"
+source "drivers/fpga/Kconfig"
 source "drivers/phy/Kconfig"
 source "drivers/crypto/Kconfig"
 source "drivers/memory/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index be5b0b3b04c9..e21ac7095c6c 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_RESET_CONTROLLER) += reset/
 obj-$(CONFIG_PCI) += pci/
 obj-y += rtc/
 obj-$(CONFIG_FIRMWARE) += firmware/
+obj-$(CONFIG_FPGA) += fpga/
 obj-$(CONFIG_GENERIC_PHY) += phy/
 obj-$(CONFIG_HAB) += hab/
 obj-$(CONFIG_CRYPTO_HW) += crypto/
diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
new file mode 100644
index ..fccdbff6eb3f
--- /dev/null
+++ b/drivers/fpga/Kconfig
@@ -0,0 +1,22 @@
+#
+# FPGA framework configuration
+#
+
+menu "FPGA Configuration Support"
+
+config FPGA
+   tristate "FPGA Configuration Framework"
+   help
+ Say Y here if you want support for configuring FPGAs from barebox.
+
+if FPGA
+
+config FPGA_BRIDGE
+   tristate "FPGA Bridge Framework"
+   help
+ Say Y here if you want to support bridges connected between host
+ processors and FPGAs or between FPGAs.
+
+endif # FPGA
+
+endmenu
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
new file mode 100644
index ..fc71a29d3b33
--- /dev/null
+++ b/drivers/fpga/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for the fpga framework and fpga manager drivers.
+#
+
+# FPGA Bridge Drivers
+obj-$(CONFIG_FPGA_BRIDGE)  += fpga-bridge.o
diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c
new file mode 100644
index ..6e8dcbfc0d16
--- /dev/null
+++ b/drivers/fpga/fpga-bridge.c
@@ -0,0 +1,243 @@
+/*
+ * FPGA Bridge Framework Driver
+ *
+ *  Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include 
+#include 
+
+/**
+ * fpga_bridge_enable - Enable transactions on the bridge
+ *
+ * @bridge: FPGA bridge
+ *
+ * Return: 0 for success, error code otherwise.
+ */
+int fpga_bridge_enable(struct fpga_bridge *bridge)
+{
+   dev_dbg(>dev, "enable\n");
+
+   if (bridge->br_ops && bridge->br_ops->enable_set)
+   return bridge->br_ops-&g

[PATCH v3 08/10] commands: firmwareload: allow loading firmware from dt

2021-06-15 Thread Steffen Trumtrar
firmwareload can only load a bitstream into an FPGA without any
knowledge of possible additional needs (e.g. FPGA bridges).

These are defined in the fpga-region nodes in the devicetree. The
fpga-region describes the layout of the FPGA and the bridges it needs
en/disabled.

Add an option to let firmwareload go via the oftree route and load the
firmware that way.

Signed-off-by: Steffen Trumtrar 

---

v2->v3 - remove unused arg 'o'
   - use xstrdup()
---
 commands/firmwareload.c | 39 +--
 1 file changed, 33 insertions(+), 6 deletions(-)

diff --git a/commands/firmwareload.c b/commands/firmwareload.c
index b735088f6117..c2a017c45479 100644
--- a/commands/firmwareload.c
+++ b/commands/firmwareload.c
@@ -5,18 +5,35 @@
 #include 
 #include 
 #include 
+#include 
 
 static int do_firmwareload(int argc, char *argv[])
 {
-   int ret, opt;
+   int opt;
const char *name = NULL, *firmware;
struct firmware_mgr *mgr;
+   char *path = NULL;
+   char *search_path = NULL;
+   char *compatible = NULL;
+   int oftree = 0;
 
-   while ((opt = getopt(argc, argv, "t:l")) > 0) {
+   while ((opt = getopt(argc, argv, "t:c:S:D:l")) > 0) {
switch (opt) {
case 't':
name = optarg;
break;
+   case 'c':
+   compatible = xstrdup(optarg);
+   oftree = 1;
+   break;
+   case 'S':
+   search_path = xstrdup(optarg);
+   oftree = 1;
+   break;
+   case 'D':
+   path = xstrdup(optarg);
+   oftree = 1;
+   break;
case 'l':
firmwaremgr_list_handlers();
return 0;
@@ -25,11 +42,20 @@ static int do_firmwareload(int argc, char *argv[])
}
}
 
-   if (!(argc - optind))
+   if (!oftree && !(argc - optind))
return COMMAND_ERROR_USAGE;
 
firmware = argv[optind];
 
+   if (oftree) {
+   if (!search_path && !firmware) {
+   printf("Provide at least a file to load or a search 
path (-S)\n");
+   return 1;
+   }
+
+   return of_firmware_load_file(path, compatible, search_path, 
firmware);
+   }
+
mgr = firmwaremgr_find(name);
 
if (!mgr) {
@@ -38,14 +64,15 @@ static int do_firmwareload(int argc, char *argv[])
return 1;
}
 
-   ret = firmwaremgr_load_file(mgr, firmware);
-
-   return ret;
+   return firmwaremgr_load_file(mgr, firmware);
 }
 
 BAREBOX_CMD_HELP_START(firmwareload)
 BAREBOX_CMD_HELP_TEXT("Options:")
 BAREBOX_CMD_HELP_OPT("-t ", "define the firmware handler by name")
+BAREBOX_CMD_HELP_OPT("-c ", "type of firmware device (e.g. 
'fpga-region')")
+BAREBOX_CMD_HELP_OPT("-D ", "load firmware to oftree path")
+BAREBOX_CMD_HELP_OPT("-S ", "load firmware using this search path")
 BAREBOX_CMD_HELP_OPT("-l\t", "list devices capable of firmware loading")
 BAREBOX_CMD_HELP_END
 
-- 
2.29.2


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


[PATCH v3 01/10] reset: add of_reset_control_get to header

2021-06-15 Thread Steffen Trumtrar
Signed-off-by: Steffen Trumtrar 
---
 drivers/reset/core.c  | 2 +-
 include/linux/reset.h | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/reset/core.c b/drivers/reset/core.c
index 26a54f21dff0..1c9eeaec5491 100644
--- a/drivers/reset/core.c
+++ b/drivers/reset/core.c
@@ -147,7 +147,7 @@ EXPORT_SYMBOL_GPL(reset_control_deassert);
  *
  * Use of id names is optional.
  */
-static struct reset_control *of_reset_control_get(struct device_node *node,
+struct reset_control *of_reset_control_get(struct device_node *node,
  const char *id)
 {
struct reset_control *rstc;
diff --git a/include/linux/reset.h b/include/linux/reset.h
index a166fe1cfe04..726cb5c2057d 100644
--- a/include/linux/reset.h
+++ b/include/linux/reset.h
@@ -11,6 +11,8 @@ int reset_control_assert(struct reset_control *rstc);
 int reset_control_deassert(struct reset_control *rstc);
 
 struct reset_control *reset_control_get(struct device_d *dev, const char *id);
+struct reset_control *of_reset_control_get(struct device_node *node,
+  const char *id);
 void reset_control_put(struct reset_control *rstc);
 
 int __must_check device_reset(struct device_d *dev);
-- 
2.29.2


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


[PATCH v3 06/10] of: kconfig: of_overlay uses firmwaremgr_load_file

2021-06-15 Thread Steffen Trumtrar
From: Steffen Trumtrar 

As of_firmware.c uses the firmwaremgr_load_file function, it depends on
FIRMWARE.

Signed-off-by: Steffen Trumtrar 
---
 drivers/of/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 23be25d85d09..e58fe50f7090 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -49,6 +49,7 @@ config OF_BAREBOX_ENV_IN_FS
 
 config OF_OVERLAY
select OFTREE
+   select FIRMWARE
bool "Devicetree overlays"
help
  Overlays allow to patch the devicetree. Unlike Linux, Barebox does
-- 
2.29.2


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


[PATCH] scripts: socfpga_import_preloader: make sdk optional

2021-06-11 Thread Steffen Trumtrar
The commit a9b2e6089d82686564220013f14e9f0ffcc725e2 allowed generating
everything needed in one step. This was however a bit too ambitious.
The script now requires that the Altera Embedded SDK is always
installed. There are situations where this is unwanted.

Beef up the code a little bit to allow having the SDK as an optional
argument and make the other input parameters location independent.

Signed-off-by: Steffen Trumtrar 
---
 Documentation/boards/socfpga.rst |  2 +-
 scripts/socfpga_import_preloader | 88 
 2 files changed, 78 insertions(+), 12 deletions(-)

diff --git a/Documentation/boards/socfpga.rst b/Documentation/boards/socfpga.rst
index 19d606030003..7e7f0619ea01 100644
--- a/Documentation/boards/socfpga.rst
+++ b/Documentation/boards/socfpga.rst
@@ -121,7 +121,7 @@ Now run the command:
 
 .. code-block:: sh
 
-  scripts/socfpga_import_preloader   

+  scripts/socfpga_import_preloader -e  -i  -b 

 
 where `` is the directory where the bsp-editor generated 
the files,
 `` is the directory where Quartus generated the handoff files, and
diff --git a/scripts/socfpga_import_preloader b/scripts/socfpga_import_preloader
index 23e3c380db12..2bec9f2d2173 100755
--- a/scripts/socfpga_import_preloader
+++ b/scripts/socfpga_import_preloader
@@ -1,16 +1,70 @@
 #!/usr/bin/env bash
 
-if [ "$#" -lt "2" ]
-then
-   echo "USAGE: $0   "
-   echo "EXAMPLE: $0 ~/altera-embedded-sdk/ 
~/cv_soc_devkit_ghrd/hps_isw_handoff/soc_system_hps_0/ 
arch/arm/boards/altera-socdk"
+usage() {
+   echo "USAGE: $0
+   parameters:
+ -s|--spl-dir 
+ -i|--isw-handoff 
+ -b|--board 
+   optional:
+ -e|--embedded-sdk "
+   echo "EXAMPLE: $0 -i 
~/cv_soc_devkit_ghrd/hps_isw_handoff/soc_system_hps_0/ -b 
arch/arm/boards/altera-socdk -e ~/altera-embedded-sdk/" 
exit 1
-fi
+}
+
+die() {
+   printf '%s\n' "$1" >&2
+   exit 1
+}
+
+generate=
+splroot=
+embeddedsw=
+handoff=
+boardroot=
+
+while :; do
+   case $1 in
+   -e|--embedded-sdk)
+   if [ "$2" ]; then
+   generate=1
+   splroot="$(mktemp -d)"
+   embeddedsw=${2}
+   shift
+   else
+   die 'ERROR: "--embedded-sdk" requires a non-empty 
option argument.'
+   fi
+   ;;
+   -s|--spl-dir)
+   if [ "$2" ]; then
+   splroot="$2"
+   shift
+   else
+   die 'ERROR: "--spl-dir" requires a non-empty option 
argument.'
+   fi
+   ;;
+   -i|--isw-handoff)
+   if [ "$2" ]; then
+   handoff="$2"
+   shift
+   else
+   die 'ERROR: "--isw-handoff" requires a non-empty option 
argument.'
+   fi
+   ;;
+   -b|--board)
+   if [ "$2" ]; then
+   boardroot="$2"
+   shift
+   else
+   die 'ERROR: "--board" requires a non-empty option 
argument.'
+   fi
+   ;;
+   *)
+   break
+   esac
+   shift
+done
 
-splroot="$(mktemp -d)"
-embeddedsw=$1
-handoff=$2
-boardroot=$3
 bareboxsrc=.
 
 cd ${bareboxsrc}
@@ -57,7 +111,17 @@ copy_source() {
sed -i 's/ $//g' $tgt
 }
 
-python2.7 ${embeddedsw}/embedded/ip/altera/preloader/scripts/iswgen.py -i 
${handoff} -o ${splroot}/
+generate_spl() {
+   python2.7 ${embeddedsw}/embedded/ip/altera/preloader/scripts/iswgen.py 
-i ${handoff} -o ${splroot}/
+}
+
+if [ -z $splroot ] || [ -z $boardroot ] || [ -z $handoff ]; then
+   usage
+fi
+
+if [ $generate ]; then
+   generate_spl
+fi
 
 copy_source ${splroot}/iocsr_config_cyclone5.c 
${boardroot}/iocsr_config_cyclone5.c
 copy_source ${splroot}/pinmux_config_cyclone5.c ${boardroot}/pinmux_config.c
@@ -69,6 +133,8 @@ copy_source ${handoff}/sequencer_auto_ac_init.c 
${boardroot}/sequencer_auto_ac_i
 copy_source ${handoff}/sequencer_auto_inst_init.c 
${boardroot}/sequencer_auto_inst_init.c
 copy_source ${handoff}/sequencer_defines.h ${boardroot}/sequencer_defines.h
 
-rm -r ${splroot}
+if [ $generate ]; then
+   rm -r ${splroot}
+fi
 
 echo "DONE"
-- 
2.29.2


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


[PATCH] watchdog: imxwd: get and enable clock

2021-04-19 Thread Steffen Trumtrar
This it (at least) necessary for i.MX7s or otherwise barebox will hang
when trying to access the registers of WDOG2/3/4.

Signed-off-by: Steffen Trumtrar 
---
 drivers/watchdog/imxwd.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/drivers/watchdog/imxwd.c b/drivers/watchdog/imxwd.c
index b2cfd1cd3a31..26c62b7bcb31 100644
--- a/drivers/watchdog/imxwd.c
+++ b/drivers/watchdog/imxwd.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 
 struct imx_wd;
 
@@ -224,6 +225,7 @@ static int imx_wd_probe(struct device_d *dev)
 {
struct resource *iores;
struct imx_wd *priv;
+   struct clk *clk;
void *ops;
int ret;
 
@@ -237,6 +239,15 @@ static int imx_wd_probe(struct device_d *dev)
dev_err(dev, "could not get memory region\n");
return PTR_ERR(iores);
}
+
+   clk = clk_get(dev, NULL);
+   if (IS_ERR(clk))
+   return PTR_ERR(clk);
+
+   ret = clk_enable(clk);
+   if (ret)
+   return ret;
+
priv->base = IOMEM(iores->start);
priv->ops = ops;
priv->wd.set_timeout = imx_watchdog_set_timeout;
-- 
2.29.2


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


[PATCH v2] mci: sdhci: fix big-endian write for blockcount/size

2021-08-31 Thread Steffen Trumtrar
From: Steffen Trumtrar 

The patch

0a47bce1b03fd236384e904dca005c0870ce8684
mci: imx-esdhc: Use common DMA helpers

converted the imx-esdhc driver to use the DMA helpers introduced with

60b608b2714472aa22862a20d04f267cbbac0863
mci: sdhci: Add DMA transfer helpers

The common DMA helpers however break support for BE-variants (e.g.
Layerscape) as the BLKATTR register seems to be a 32-bit register which
internally switches bytes when used with two 16-bit write accesses.
As the alignment should also work for LE-SDHCI-variants convert the two
16-bit accesses to one 32-bit access.

Signed-off-by: Steffen Trumtrar 
---
 drivers/mci/sdhci.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/mci/sdhci.c b/drivers/mci/sdhci.c
index aca4a5a6f911..8b5520d6827a 100644
--- a/drivers/mci/sdhci.c
+++ b/drivers/mci/sdhci.c
@@ -129,9 +129,8 @@ void sdhci_setup_data_pio(struct sdhci *sdhci, struct 
mci_data *data)
if (!data)
return;
 
-   sdhci_write16(sdhci, SDHCI_BLOCK_SIZE, sdhci->sdma_boundary |
-   SDHCI_TRANSFER_BLOCK_SIZE(data->blocksize));
-   sdhci_write16(sdhci, SDHCI_BLOCK_COUNT, data->blocks);
+   sdhci_write32(sdhci, SDHCI_BLOCK_SIZE, sdhci->sdma_boundary |
+ SDHCI_TRANSFER_BLOCK_SIZE(data->blocksize) | data->blocks 
<< 16);
 }
 
 void sdhci_setup_data_dma(struct sdhci *sdhci, struct mci_data *data,
-- 
2.30.2


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


[PATCH 2/2] watchdog: add support for wdat_wdt

2022-01-07 Thread Steffen Trumtrar
Add support for systems with the ACPI Watchdog Action Table (wdat).
Based on Linux v5.15-rc1 drivers/watchdog/wdat_wdt.c

Signed-off-by: Steffen Trumtrar 
---
 This patch depends on
  x86: : fix outl/outsl access size
  https://lore.barebox.org/20220107063644.22595-1-a.fat...@pengutronix.de

 drivers/watchdog/Kconfig|  10 +
 drivers/watchdog/Makefile   |   1 +
 drivers/watchdog/wdat_wdt.c | 496 
 3 files changed, 507 insertions(+)
 create mode 100644 drivers/watchdog/wdat_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index f91a2571d9..68dbded3ec 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -149,4 +149,14 @@ config STARFIVE_WDT
  If you say yes here you get support for the watchdog device
  on StarFive SoCs.
 
+config WDAT_WDT
+   bool "ACPI Watchdog Action Table (WDAT)"
+   depends on X86
+   depends on ACPI
+   help
+ This driver adds support for systems with ACPI Watchdog Action
+ Table (WDAT) table. Servers typically have this but it can be
+ found on some desktop machines as well. This driver will take
+ over the native iTCO watchdog driver found on many Intel CPUs.
+
 endif
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 54a833447c..aaebc459e6 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -20,3 +20,4 @@ obj-$(CONFIG_F71808E_WDT) += f71808e_wdt.o
 obj-$(CONFIG_GPIO_WATCHDOG) += gpio_wdt.o
 obj-$(CONFIG_ITCO_WDT) += itco_wdt.o
 obj-$(CONFIG_STARFIVE_WDT) += starfive_wdt.o
+obj-$(CONFIG_WDAT_WDT) += wdat_wdt.o
diff --git a/drivers/watchdog/wdat_wdt.c b/drivers/watchdog/wdat_wdt.c
new file mode 100644
index 00..39e8cc4a3d
--- /dev/null
+++ b/drivers/watchdog/wdat_wdt.c
@@ -0,0 +1,496 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * ACPI Hardware Watchdog (WDAT) driver.
+ *
+ * Copyright (C) 2016, Intel Corporation
+ * Author: Mika Westerberg 
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+enum acpi_wdat_actions {
+   ACPI_WDAT_RESET = 1,
+   ACPI_WDAT_GET_CURRENT_COUNTDOWN = 4,
+   ACPI_WDAT_GET_COUNTDOWN = 5,
+   ACPI_WDAT_SET_COUNTDOWN = 6,
+   ACPI_WDAT_GET_RUNNING_STATE = 8,
+   ACPI_WDAT_SET_RUNNING_STATE = 9,
+   ACPI_WDAT_GET_STOPPED_STATE = 10,
+   ACPI_WDAT_SET_STOPPED_STATE = 11,
+   ACPI_WDAT_GET_REBOOT = 16,
+   ACPI_WDAT_SET_REBOOT = 17,
+   ACPI_WDAT_GET_SHUTDOWN = 18,
+   ACPI_WDAT_SET_SHUTDOWN = 19,
+   ACPI_WDAT_GET_STATUS = 32,
+   ACPI_WDAT_SET_STATUS = 33,
+   ACPI_WDAT_ACTION_RESERVED = 34  /* 34 and greater are reserved */
+};
+
+enum acpi_wdat_instructions {
+   ACPI_WDAT_READ_VALUE = 0,
+   ACPI_WDAT_READ_COUNTDOWN = 1,
+   ACPI_WDAT_WRITE_VALUE = 2,
+   ACPI_WDAT_WRITE_COUNTDOWN = 3,
+   ACPI_WDAT_INSTRUCTION_RESERVED = 4, /* 4 and greater are reserved */
+   ACPI_WDAT_PRESERVE_REGISTER = 0x80  /* Except for this value */
+};
+
+#define MAX_WDAT_ACTIONS ACPI_WDAT_ACTION_RESERVED
+
+#define WDAT_DEFAULT_TIMEOUT   30
+
+/* WDAT Instruction Entries (actions) */
+
+struct __packed acpi_wdat_entry {
+   u8  action;
+   u8  instruction;
+   u16 reserved;
+   struct acpi_generic_address register_region;
+   u32 value;  /* Value used with 
Read/Write register */
+   u32 mask;   /* Bitmask required for 
this register instruction */
+};
+
+/**
+ * struct wdat_instruction - Single ACPI WDAT instruction
+ * @entry: Copy of the ACPI table instruction
+ * @reg: Register the instruction is accessing
+ * @node: Next instruction in action sequence
+ */
+struct wdat_instruction {
+   struct acpi_wdat_entry entry;
+   void __iomem *reg;
+   struct list_head node;
+};
+
+/**
+ * struct wdat_wdt - ACPI WDAT watchdog device
+ * @dev: Parent platform device
+ * @wdd: Watchdog core device
+ * @period: How long is one watchdog period in ms
+ * @stopped_in_sleep: Is this watchdog stopped by the firmware in S1-S5
+ * @stopped: Was the watchdog stopped by the driver in suspend
+ * @instructions: An array of instruction lists indexed by an action number 
from
+ *the WDAT table. There can be %NULL entries for not 
implemented
+ *actions.
+ */
+struct wdat_wdt {
+   struct watchdog wdd;
+   unsigned intperiod;
+   boolstopped_in_sleep;
+   boolstopped;
+   struct list_head*instructions[MAX_WDAT_ACTIONS];
+};
+
+struct __packed acpi_table_wdat {
+   struct acpi_table_header header;/* Common ACPI table header */
+   u32  header_length; /* Watchdog Header Length */
+   u16  p

[PATCH 1/2] acpi.h: add defines for adr_space and gas

2022-01-07 Thread Steffen Trumtrar
>From linux v5.15-rc1.

Signed-off-by: Steffen Trumtrar 
---
 include/acpi.h | 72 ++
 1 file changed, 72 insertions(+)

diff --git a/include/acpi.h b/include/acpi.h
index b8e73b35df..04f722da23 100644
--- a/include/acpi.h
+++ b/include/acpi.h
@@ -10,6 +10,78 @@
 #include 
 #include 
 
+/* Names within the namespace are 4 bytes long */
+
+#define ACPI_NAMESEG_SIZE   4  /* Fixed by ACPI spec */
+#define ACPI_PATH_SEGMENT_LENGTH5  /* 4 chars for name + 1 char 
for separator */
+#define ACPI_PATH_SEPARATOR '.'
+
+/* Sizes for ACPI table headers */
+
+#define ACPI_OEM_ID_SIZE6
+#define ACPI_OEM_TABLE_ID_SIZE  8
+
+/*
+ * Algorithm to obtain access bit or byte width.
+ * Can be used with access_width of struct acpi_generic_address and 
access_size of
+ * struct acpi_resource_generic_register.
+ */
+#define ACPI_ACCESS_BIT_WIDTH(size) (1 << ((size) + 2))
+#define ACPI_ACCESS_BYTE_WIDTH(size)(1 << ((size) - 1))
+
+/* Address Space (Operation Region) Types */
+
+typedef u8 acpi_adr_space_type;
+#define ACPI_ADR_SPACE_SYSTEM_MEMORY(acpi_adr_space_type) 0
+#define ACPI_ADR_SPACE_SYSTEM_IO(acpi_adr_space_type) 1
+#define ACPI_ADR_SPACE_PCI_CONFIG   (acpi_adr_space_type) 2
+#define ACPI_ADR_SPACE_EC   (acpi_adr_space_type) 3
+#define ACPI_ADR_SPACE_SMBUS(acpi_adr_space_type) 4
+#define ACPI_ADR_SPACE_CMOS (acpi_adr_space_type) 5
+#define ACPI_ADR_SPACE_PCI_BAR_TARGET   (acpi_adr_space_type) 6
+#define ACPI_ADR_SPACE_IPMI (acpi_adr_space_type) 7
+#define ACPI_ADR_SPACE_GPIO (acpi_adr_space_type) 8
+#define ACPI_ADR_SPACE_GSBUS(acpi_adr_space_type) 9
+#define ACPI_ADR_SPACE_PLATFORM_COMM(acpi_adr_space_type) 10
+#define ACPI_ADR_SPACE_PLATFORM_RT  (acpi_adr_space_type) 11
+
+/***
+ *
+ * Master ACPI Table Header. This common header is used by all ACPI tables
+ * except the RSDP and FACS.
+ *
+ 
**/
+
+struct __packed acpi_table_header {
+   char signature[ACPI_NAMESEG_SIZE];  /* ASCII table signature */
+   u32 length; /* Length of table in bytes, including this 
header */
+   u8 revision;/* ACPI Specification minor version number */
+   u8 checksum;/* To make sum of entire table == 0 */
+   char oem_id[ACPI_OEM_ID_SIZE];  /* ASCII OEM identification */
+   char oem_table_id[ACPI_OEM_TABLE_ID_SIZE];  /* ASCII OEM table 
identification */
+   u32 oem_revision;   /* OEM revision number */
+   char asl_compiler_id[ACPI_NAMESEG_SIZE];/* ASCII ASL compiler 
vendor ID */
+   u32 asl_compiler_revision;  /* ASL compiler version */
+};
+
+/***
+ *
+ * GAS - Generic Address Structure (ACPI 2.0+)
+ *
+ * Note: Since this structure is used in the ACPI tables, it is byte aligned.
+ * If misaligned access is not supported by the hardware, accesses to the
+ * 64-bit Address field must be performed with care.
+ *
+ 
**/
+
+struct __packed acpi_generic_address {
+   u8 space_id;/* Address space where struct or register 
exists */
+   u8 bit_width;   /* Size in bits of given register */
+   u8 bit_offset;  /* Bit offset within the register */
+   u8 access_width;/* Minimum Access size (ACPI 3.0) */
+   u64 address;/* 64-bit address of struct or register */
+};
+
 typedef char acpi_sig_t[4];
 
 struct __packed acpi_rsdp { /* root system description pointer */
-- 
2.30.2


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


[PATCH 2/2] net: phy: mv88e6xxx: add support for mv88e6250

2022-03-21 Thread Steffen Trumtrar
From: Steffen Trumtrar 

barebox port of the linux patch:

  commit 1f71836f5d96e4c87fad16db86d324bee47e1d30
  Author: Rasmus Villemoes 
  Date:   Tue Jun 4 07:34:32 2019 +

  net: dsa: mv88e6xxx: add support for mv88e6250

  This adds support for the Marvell 88E6250. I've checked that each
  member in the ops-structure makes sense, and basic switchdev
  functionality works fine.

  It uses the new dual_chip option, and since its port registers start
  at SMI address 0x08 or 0x18 (i.e., always sw_addr + 0x08), we need to
  introduce a new compatible string in order for the auto-identification
  in mv88e6xxx_detect() to work.

  The chip has four per port 16-bits statistics registers, two of which
  correspond to the existing "sw_in_filtered" and "sw_out_filtered" (but
  at offsets 0x13 and 0x10 rather than 0x12 and 0x13, because why should
  this be easy...). Wiring up those four statistics seems to require
  introducing a STATS_TYPE_PORT_6250 bit or similar, which seems a tad
  ugly, so for now this just allows access to the STATS_TYPE_BANK0 ones.

  The chip does have ptp support, and the existing
  mv88e6352_{gpio,avb,ptp}_ops at first glance seem like they would work
  out-of-the-box, but for simplicity (and lack of testing) I'm eliding
  this.

  Reviewed-by: Andrew Lunn 
  Signed-off-by: Rasmus Villemoes 
  Signed-off-by: David S. Miller 

Signed-off-by: Steffen Trumtrar 
---
 drivers/net/phy/mv88e6xxx/chip.c | 28 
 drivers/net/phy/mv88e6xxx/chip.h |  1 +
 drivers/net/phy/mv88e6xxx/port.h |  1 +
 3 files changed, 30 insertions(+)

diff --git a/drivers/net/phy/mv88e6xxx/chip.c b/drivers/net/phy/mv88e6xxx/chip.c
index ae59d134e7..a7d707095b 100644
--- a/drivers/net/phy/mv88e6xxx/chip.c
+++ b/drivers/net/phy/mv88e6xxx/chip.c
@@ -36,6 +36,7 @@ enum mv88e6xxx_model {
MV88E6190X,
MV88E6191,
MV88E6240,
+   MV88E6250,
MV88E6290,
MV88E6320,
MV88E6321,
@@ -224,6 +225,18 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
.port_link_state = mv88e6352_port_link_state,
 };
 
+static const struct mv88e6xxx_ops mv88e6250_ops = {
+   /* MV88E6XXX_FAMILY_6250 */
+   .get_eeprom = mv88e6xxx_g2_get_eeprom16,
+   .set_eeprom = mv88e6xxx_g2_set_eeprom16,
+   .phy_read = mv88e6xxx_g2_smi_phy_read,
+   .phy_write = mv88e6xxx_g2_smi_phy_write,
+   .port_set_link = mv88e6xxx_port_set_link,
+   .port_set_duplex = mv88e6xxx_port_set_duplex,
+   .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
+   .port_set_speed = mv88e6250_port_set_speed,
+};
+
 static const struct mv88e6xxx_ops mv88e6290_ops = {
/* MV88E6XXX_FAMILY_6390 */
.get_eeprom = mv88e6xxx_g2_get_eeprom8,
@@ -525,6 +538,17 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.ops = _ops,
},
 
+   [MV88E6250] = {
+   .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6250,
+   .family = MV88E6XXX_FAMILY_6250,
+   .name = "Marvell 88E6250",
+   .num_ports = 7,
+   .port_base_addr = 0x08,
+   .global1_addr = 0xf,
+   .global2_addr = 0x7,
+   .ops = _ops,
+   },
+
[MV88E6290] = {
.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6290,
.family = MV88E6XXX_FAMILY_6390,
@@ -931,6 +955,10 @@ static const struct of_device_id mv88e6xxx_of_match[] = {
.compatible = "marvell,mv88e6085",
.data = _table[MV88E6085],
},
+   {
+   .compatible = "marvell,mv88e6250",
+   .data = _table[MV88E6250],
+   },
{
.compatible = "marvell,mv88e6190",
.data = _table[MV88E6190],
diff --git a/drivers/net/phy/mv88e6xxx/chip.h b/drivers/net/phy/mv88e6xxx/chip.h
index 12037ca95c..30fdac9a9f 100644
--- a/drivers/net/phy/mv88e6xxx/chip.h
+++ b/drivers/net/phy/mv88e6xxx/chip.h
@@ -19,6 +19,7 @@ enum mv88e6xxx_family {
MV88E6XXX_FAMILY_6165,  /* 6123 6161 6165 */
MV88E6XXX_FAMILY_6185,  /* 6108 6121 6122 6131 6152 6155 6182 6185 */
MV88E6XXX_FAMILY_6320,  /* 6320 6321 */
+   MV88E6XXX_FAMILY_6250,  /* 6250 */
MV88E6XXX_FAMILY_6341,  /* 6141 6341 */
MV88E6XXX_FAMILY_6351,  /* 6171 6175 6350 6351 */
MV88E6XXX_FAMILY_6352,  /* 6172 6176 6240 6352 */
diff --git a/drivers/net/phy/mv88e6xxx/port.h b/drivers/net/phy/mv88e6xxx/port.h
index f5cf72932a..4bc5072948 100644
--- a/drivers/net/phy/mv88e6xxx/port.h
+++ b/drivers/net/phy/mv88e6xxx/port.h
@@ -90,6 +90,7 @@
 #define MV88E6XXX_PORT_SWITCH_ID_PROD_6191 0x1910
 #define MV88E6XXX_PORT_SWITCH_ID_PROD_6185 0x1a70
 #define MV88E6XXX_PORT_SWITCH_ID_PROD_6240 0x2400
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6250 0x2500
 #d

[PATCH 1/2] net: phy: mv88e6xxx: implement port_set_speed for mv88e6250

2022-03-21 Thread Steffen Trumtrar
From: Steffen Trumtrar 

barebox port of the linux patch:

  commit a528e5be6b5f8026eda029b03340dcfa23c70824
  Author: Rasmus Villemoes 
  Date:   Tue Jun 4 07:34:29 2019 +

  net: dsa: mv88e6xxx: implement port_set_speed for mv88e6250

  The data sheet also mentions the possibility of selecting 200 Mbps for
  the MII ports (ports 5 and 6) by setting the ForceSpd field to
  0x2 (aka MV88E6065_PORT_MAC_CTL_SPEED_200). However, there's a note
  that "actual speed is determined by bit 8 above", and flipping back a
  page, one finds that bits 13:8 are reserved...

  So without further information on what bit 8 means, let's stick to
  supporting just 10 and 100 Mbps on all ports.

  Reviewed-by: Andrew Lunn 
  Signed-off-by: Rasmus Villemoes 
  Signed-off-by: David S. Miller 

Signed-off-by: Steffen Trumtrar 
---
 drivers/net/phy/mv88e6xxx/port.c | 12 
 drivers/net/phy/mv88e6xxx/port.h |  1 +
 2 files changed, 13 insertions(+)

diff --git a/drivers/net/phy/mv88e6xxx/port.c b/drivers/net/phy/mv88e6xxx/port.c
index ba2b03e18d..95542d4eec 100644
--- a/drivers/net/phy/mv88e6xxx/port.c
+++ b/drivers/net/phy/mv88e6xxx/port.c
@@ -277,6 +277,18 @@ int mv88e6185_port_set_speed(struct mv88e6xxx_chip *chip, 
int port, int speed)
return mv88e6xxx_port_set_speed(chip, port, speed, false, false);
 }
 
+/* Support 10, 100 (e.g. 88E6250 family) */
+int mv88e6250_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
+{
+   if (speed == SPEED_MAX)
+   speed = 100;
+
+   if (speed > 100)
+   return -EOPNOTSUPP;
+
+   return mv88e6xxx_port_set_speed(chip, port, speed, false, false);
+}
+
 /* Support 10, 100, 200, 1000 Mbps (e.g. 88E6352 family) */
 int mv88e6352_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
 {
diff --git a/drivers/net/phy/mv88e6xxx/port.h b/drivers/net/phy/mv88e6xxx/port.h
index f47f392b87..f5cf72932a 100644
--- a/drivers/net/phy/mv88e6xxx/port.h
+++ b/drivers/net/phy/mv88e6xxx/port.h
@@ -121,6 +121,7 @@ int mv88e6xxx_port_set_link(struct mv88e6xxx_chip *chip, 
int port, int link);
 int mv88e6xxx_port_set_duplex(struct mv88e6xxx_chip *chip, int port, int dup);
 int mv88e6065_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed);
 int mv88e6185_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed);
+int mv88e6250_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed);
 int mv88e6352_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed);
 int mv88e6390_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed);
 int mv88e6390x_port_set_speed(struct mv88e6xxx_chip *chip, int port, int 
speed);
-- 
2.30.2


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


[PATCH 3/6] ata: sata_mv: handle the phy errata

2022-01-18 Thread Steffen Trumtrar
Copied from Linux v5.15

Signed-off-by: Steffen Trumtrar 
---
 drivers/ata/sata_mv.c | 36 
 1 file changed, 36 insertions(+)

diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index c94ad2ca36..b8d21525a7 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -52,6 +52,40 @@ static void ata_ioports_init(struct ata_ioports *io,
 #define REG_SCONTROL__IPM__PARTIAL 0x0100
 #define REG_SCONTROL__IPM__SLUMBER 0x0200
 
+#define PHY_MODE3  0x310
+#definePHY_MODE4   0x314   /* requires 
read-after-write */
+#define PHY_MODE9_GEN2 0x398
+#definePHY_MODE9_GEN1  0x39c
+
+static void mv_soc_65n_phy_errata(void __iomem *base)
+{
+   u32 reg;
+
+   reg = readl(base + PHY_MODE3);
+   reg &= ~(0x3 << 27);/* SELMUPF (bits 28:27) to 1 */
+   reg |= (0x1 << 27);
+   reg &= ~(0x3 << 29);/* SELMUPI (bits 30:29) to 1 */
+   reg |= (0x1 << 29);
+   writel(reg, base + PHY_MODE3);
+
+   reg = readl(base + PHY_MODE4);
+   reg &= ~0x1;/* SATU_OD8 (bit 0) to 0, reserved bit 16 must be set */
+   reg |= (0x1 << 16);
+   writel(reg, base + PHY_MODE4);
+
+   reg = readl(base + PHY_MODE9_GEN2);
+   reg &= ~0xf;/* TXAMP[3:0] (bits 3:0) to 8 */
+   reg |= 0x8;
+   reg &= ~(0x1 << 14);/* TXAMP[4] (bit 14) to 0 */
+   writel(reg, base + PHY_MODE9_GEN2);
+
+   reg = readl(base + PHY_MODE9_GEN1);
+   reg &= ~0xf;/* TXAMP[3:0] (bits 3:0) to 8 */
+   reg |= 0x8;
+   reg &= ~(0x1 << 14);/* TXAMP[4] (bit 14) to 0 */
+   writel(reg, base + PHY_MODE9_GEN1);
+}
+
 static int mv_sata_probe(struct device_d *dev)
 {
struct resource *iores;
@@ -90,6 +124,8 @@ static int mv_sata_probe(struct device_d *dev)
return ret;
}
 
+   mv_soc_65n_phy_errata(base);
+
writel(REG_EDMA_COMMAND__EATARST, base + REG_EDMA_COMMAND(0));
udelay(25);
writel(0x0, base + REG_EDMA_COMMAND(0));
-- 
2.30.2


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


[PATCH 0/6] sata_mv: cleanup and error handling

2022-01-18 Thread Steffen Trumtrar
From: Steffen Trumtrar 

Hi!

The sata_mv driver in barebox only supports the ARMADA-XP and there are
not really that many users. Therefore only copy mv6-specific setup from
the kernel to the barebox driver.

We have some specific hardware combination of ARDAMA-XP and SATA drive
that fails in probing the drive on a cold start. Not always but at least
in 2 of 10 boots.

When the error occurs, the error registers and/or the documentation
wheren't really that helpful. The only way out is hard-resetting
everything and trying again to enumerate the ATA drive. That's what we
do now.

While at it, get the phy errata from the kernel and flip some bits in
the initial setup that are also set in the kernel driver. Sadly this
wasn't enough to fix the probe error.

This series was tested on the specific, broken HW combo and with a
different combo that didn't (and still doesn't) fail probing.

Steffen Trumtrar (6):
  ata: sata_mv: cleanup alignment
  ata: sata_mv: clear SERROR and en/disable EDMA
  ata: sata_mv: handle the phy errata
  ata: sata_mv: enable Generation 2 speed support
  ata: sata_mv: issue hard-reset on probe
  ata: sata_mv: try probing multiple times

 drivers/ata/sata_mv.c | 111 +++---
 1 file changed, 104 insertions(+), 7 deletions(-)

-- 
2.30.2


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


[PATCH 1/6] ata: sata_mv: cleanup alignment

2022-01-18 Thread Steffen Trumtrar
Clean up the alignment of the defines.

Signed-off-by: Steffen Trumtrar 
---
 drivers/ata/sata_mv.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 3b55c71d67..3f77e8f2e8 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -33,15 +33,15 @@ static void ata_ioports_init(struct ata_ioports *io,
/* io->alt_dev_addr is unused */
 }
 
-#define REG_WINDOW_CONTROL(n)  ((n) * 0x10 + 0x30)
-#define REG_WINDOW_BASE(n) ((n) * 0x10 + 0x34)
+#define REG_WINDOW_CONTROL(n)  ((n) * 0x10 + 0x30)
+#define REG_WINDOW_BASE(n) ((n) * 0x10 + 0x34)
 
-#define REG_EDMA_COMMAND(n)((n) * 0x2000 + 0x2028)
+#define REG_EDMA_COMMAND(n)((n) * 0x2000 + 0x2028)
 #define REG_EDMA_COMMAND__EATARST  0x0004
 
-#define REG_ATA_BASE   0x2100
-#define REG_SSTATUS(n) ((n) * 0x2000 + 0x2300)
-#define REG_SCONTROL(n)((n) * 0x2000 + 0x2308)
+#define REG_ATA_BASE   0x2100
+#define REG_SSTATUS(n) ((n) * 0x2000 + 0x2300)
+#define REG_SCONTROL(n)((n) * 0x2000 + 0x2308)
 #define REG_SCONTROL__DET  0x000f
 #define REG_SCONTROL__DET__INIT0x0001
 #define REG_SCONTROL__DET__PHYOK   0x0002
-- 
2.30.2


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


[PATCH 2/6] ata: sata_mv: clear SERROR and en/disable EDMA

2022-01-18 Thread Steffen Trumtrar
SControl registers shouldn't be accessed when EDMA is enabled.
Also clear SError before any accesses. This register will show if
anything went wrong with the phy accesses.

Signed-off-by: Steffen Trumtrar 
---
 drivers/ata/sata_mv.c | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 3f77e8f2e8..c94ad2ca36 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -37,10 +37,13 @@ static void ata_ioports_init(struct ata_ioports *io,
 #define REG_WINDOW_BASE(n) ((n) * 0x10 + 0x34)
 
 #define REG_EDMA_COMMAND(n)((n) * 0x2000 + 0x2028)
+#define EDMA_EN(1 << 0)/* enable EDMA 
*/
+#define EDMA_DS(1 << 1)/* disable 
EDMA; self-negated */
 #define REG_EDMA_COMMAND__EATARST  0x0004
 
 #define REG_ATA_BASE   0x2100
 #define REG_SSTATUS(n) ((n) * 0x2000 + 0x2300)
+#define REG_SERROR(n)  ((n) * 0x2000 + 0x2304)
 #define REG_SCONTROL(n)((n) * 0x2000 + 0x2308)
 #define REG_SCONTROL__DET  0x000f
 #define REG_SCONTROL__DET__INIT0x0001
@@ -74,6 +77,19 @@ static int mv_sata_probe(struct device_d *dev)
writel(0x7fff0e01, base + REG_WINDOW_CONTROL(0));
writel(0, base + REG_WINDOW_BASE(0));
 
+   /* Clear SError */
+   writel(0x0, base + REG_SERROR(0));
+   /* disable EDMA */
+   writel(EDMA_DS, base + REG_EDMA_COMMAND(0));
+   /* Wait for the chip to confirm eDMA is off. */
+   ret = wait_on_timeout(10 * MSECOND,
+   (readl(base + REG_EDMA_COMMAND(0)) & EDMA_EN) 
== 0);
+   if (ret) {
+   dev_err(dev, "Failed to wait for eDMA off (sstatus=0x%08x)\n",
+   readl(base + REG_SSTATUS(0)));
+   return ret;
+   }
+
writel(REG_EDMA_COMMAND__EATARST, base + REG_EDMA_COMMAND(0));
udelay(25);
writel(0x0, base + REG_EDMA_COMMAND(0));
@@ -104,6 +120,9 @@ static int mv_sata_probe(struct device_d *dev)
 
dev->priv = ide;
 
+   /* enable EDMA */
+   writel(EDMA_EN, base + REG_EDMA_COMMAND(0));
+
ret = ide_port_register(ide);
if (ret)
free(ide);
-- 
2.30.2


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


<    1   2   3   4   5   6   7   >