Re: [PATCH v3 2/9] usb: xhci: create one unified function to calculate TRB TD remainder.

2020-09-07 Thread Bin Meng
On Mon, Sep 7, 2020 at 3:14 PM Chunfeng Yun  wrote:
>

nits: please remove the ending period in the commit title

> xhci versions 1.0 and later report the untransferred data remaining in a
> TD a bit differently than older hosts.
>
> We used to have separate functions for these, and needed to check host
> version before calling the right function.
>
> Now Mediatek host has an additional quirk on how it uses the TD Size
> field for remaining data. To prevent yet another function for calculating
> remainder we instead want to make one quirk friendly unified function.
>
> Porting from the Linux:
> c840d6ce772d("xhci: create one unified function to calculate TRB TD 
> remainder.")
> 124c39371114("xhci: use boolean to indicate last trb in td remainder 
> calculation")
>
> Signed-off-by: Chunfeng Yun 
> ---
> v2~v3: no changes
> ---
>  drivers/usb/host/xhci-ring.c | 105 
> +--
>  include/usb/xhci.h   |   2 +
>  2 files changed, 52 insertions(+), 55 deletions(-)
>
> diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
> index 79bfc34..0f86b01 100644
> --- a/drivers/usb/host/xhci-ring.c
> +++ b/drivers/usb/host/xhci-ring.c
> @@ -298,55 +298,52 @@ void xhci_queue_command(struct xhci_ctrl *ctrl, u8 
> *ptr, u32 slot_id,
> xhci_writel(>dba->doorbell[0], DB_VALUE_HOST);
>  }
>
> -/**
> - * The TD size is the number of bytes remaining in the TD (including this 
> TRB),
> - * right shifted by 10.
> - * It must fit in bits 21:17, so it can't be bigger than 31.
> +/*
> + * For xHCI 1.0 host controllers, TD size is the number of max packet sized
> + * packets remaining in the TD (*not* including this TRB).
>   *
> - * @param remainderremaining packets to be sent
> - * @return remainder if remainder is less than max else max
> - */
> -static u32 xhci_td_remainder(unsigned int remainder)
> -{
> -   u32 max = (1 << (21 - 17 + 1)) - 1;
> -
> -   if ((remainder >> 10) >= max)
> -   return max << 17;
> -   else
> -   return (remainder >> 10) << 17;
> -}
> -
> -/**
> - * Finds out the remanining packets to be sent
> + * Total TD packet count = total_packet_count =
> + * DIV_ROUND_UP(TD size in bytes / wMaxPacketSize)
> + *
> + * Packets transferred up to and including this TRB = packets_transferred =
> + * rounddown(total bytes transferred including this TRB / wMaxPacketSize)
> + *
> + * TD size = total_packet_count - packets_transferred
>   *
> - * @param running_totaltotal size sent so far
> + * For xHCI 0.96 and older, TD size field should be the remaining bytes
> + * including this TRB, right shifted by 10
> + *
> + * For all hosts it must fit in bits 21:17, so it can't be bigger than 31.
> + * This is taken care of in the TRB_TD_SIZE() macro
> + *
> + * The last TRB in a TD must have the TD size set to zero.
> + *
> + * @param ctrl host controller data structure
> + * @param transferred  total size sent so far
>   * @param trb_buff_len length of the TRB Buffer
> - * @param total_packet_count   total packet count
> - * @param maxpacketsizemax packet size of current pipe
> - * @param num_trbs_leftnumber of TRBs left to be processed
> - * @return 0 if running_total or trb_buff_len is 0, else remainder
> + * @param td_total_len total packet count
> + * @param maxp max packet size of current pipe
> + * @param more_trbs_coming indicate last trb in TD
> + * @return remainder
>   */
> -static u32 xhci_v1_0_td_remainder(int running_total,
> -   int trb_buff_len,
> -   unsigned int total_packet_count,
> -   int maxpacketsize,
> -   unsigned int num_trbs_left)
> +static u32 xhci_td_remainder(struct xhci_ctrl *ctrl, int transferred,
> +int trb_buff_len, unsigned int td_total_len,
> +int maxp, bool more_trbs_coming)
>  {
> -   int packets_transferred;
> +   u32 total_packet_count;
> +
> +   if (ctrl->hci_version < 0x100)
> +   return ((td_total_len - transferred) >> 10);
>
> /* One TRB with a zero-length data packet. */
> -   if (num_trbs_left == 0 || (running_total == 0 && trb_buff_len == 0))
> +   if (!more_trbs_coming || (transferred == 0 && trb_buff_len == 0) ||
> +   trb_buff_len == td_total_len)
> return 0;
>
> -   /*
> -* All the TRB queueing functions don't count the current TRB in
> -* running_total.
> -*/
> -   packets_transferred = (running_total + trb_buff_len) / maxpacketsize;
> +   total_packet_count = DIV_ROUND_UP(td_total_len, maxp);
>
> -   if ((total_packet_count - packets_transferred) > 31)
> -   return 31 << 17;
> -   return (total_packet_count - packets_transferred) << 17;
> +   /* Queueing functions don't count the current TRB into transferred */
> +   return 

[PATCH v4 2/2] test: gpio: Add tests for the managed API

2020-09-07 Thread Pratyush Yadav
From: Jean-Jacques Hiblot 

Add a test to verify that GPIOs can be acquired/released using the managed
API. Also check that the GPIOs are released when the consumer device is
removed.

Signed-off-by: Jean-Jacques Hiblot 
Signed-off-by: Pratyush Yadav 
---
 arch/sandbox/dts/test.dts |  10 
 test/dm/bus.c |   2 +-
 test/dm/gpio.c| 102 ++
 test/dm/test-fdt.c|   6 +--
 4 files changed, 116 insertions(+), 4 deletions(-)

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 9f45c48e4e..d35aa6d1f5 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -121,6 +121,9 @@
<_c 5 GPIO_IN>,
<_c 6 (GPIO_ACTIVE_LOW|GPIO_OUT|GPIO_OPEN_DRAIN)>,
<_c 7 (GPIO_ACTIVE_LOW|GPIO_OUT|GPIO_OPEN_SOURCE)>;
+   test4-gpios = <_a 14>, <_b 4 1 3 2 1>;
+   test5-gpios = <_a 19>;
+
int-value = <1234>;
uint-value = <(-1234)>;
int64-value = /bits/ 64 <0x>;
@@ -270,6 +273,13 @@
compatible = "denx,u-boot-devres-test";
};

+   another-test {
+   reg = <0 2>;
+   compatible = "denx,u-boot-fdt-test";
+   test4-gpios = <_a 14>, <_b 4 1 3 2 1>;
+   test5-gpios = <_a 19>;
+   };
+
acpi_test1: acpi-test {
compatible = "denx,u-boot-acpi-test";
acpi-ssdt-test-data = "ab";
diff --git a/test/dm/bus.c b/test/dm/bus.c
index 865e8bd9fb..27b7266645 100644
--- a/test/dm/bus.c
+++ b/test/dm/bus.c
@@ -120,7 +120,7 @@ UCLASS_DRIVER(testbus) = {
 /* Test that we can probe for children */
 static int dm_test_bus_children(struct unit_test_state *uts)
 {
-   int num_devices = 8;
+   int num_devices = 9;
struct udevice *bus;
struct uclass *uc;

diff --git a/test/dm/gpio.c b/test/dm/gpio.c
index 4848152644..54e960b185 100644
--- a/test/dm/gpio.c
+++ b/test/dm/gpio.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -480,3 +481,104 @@ static int dm_test_gpio_get_acpi_irq(struct 
unit_test_state *uts)
return 0;
 }
 DM_TEST(dm_test_gpio_get_acpi_irq, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+
+/* Test that we can get/release GPIOs using managed API */
+static int dm_test_gpio_devm(struct unit_test_state *uts)
+{
+   static const u32 flags = GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE;
+   struct gpio_desc *desc1, *desc2, *desc3, *desc_err;
+   struct udevice *dev;
+   struct udevice *dev2;
+
+   ut_assertok(uclass_get_device_by_name(UCLASS_TEST_FDT, "a-test",
+ ));
+   ut_assertok(uclass_get_device_by_name(UCLASS_TEST_FDT, "another-test",
+ ));
+
+   /* Get 3 GPIOs from 'a-test' dev */
+   desc1 = devm_gpiod_get_index(dev, "test4", 0, flags);
+   ut_assert(!IS_ERR(desc1));
+   desc2 = devm_gpiod_get_index(dev, "test4", 1, flags);
+   ut_assert(!IS_ERR(desc2));
+   desc3 = devm_gpiod_get_index_optional(dev, "test5", 0, flags);
+   ut_assert(!IS_ERR(desc3));
+   ut_assert(desc3);
+
+   /*
+* Try get the same 3 GPIOs from 'a-test' and 'another-test' devices.
+* check that it fails
+*/
+   desc_err = devm_gpiod_get_index(dev, "test4", 0, flags);
+   ut_asserteq(-EBUSY, PTR_ERR(desc_err));
+   desc_err = devm_gpiod_get_index(dev2, "test4", 0, flags);
+   ut_asserteq(-EBUSY, PTR_ERR(desc_err));
+   desc_err = devm_gpiod_get_index(dev, "test4", 1, flags);
+   ut_asserteq(-EBUSY, PTR_ERR(desc_err));
+   desc_err = devm_gpiod_get_index(dev2, "test4", 1, flags);
+   ut_asserteq(-EBUSY, PTR_ERR(desc_err));
+   desc_err = devm_gpiod_get_index_optional(dev, "test5", 0, flags);
+   ut_asserteq_ptr(NULL, desc_err);
+   desc_err = devm_gpiod_get_index_optional(dev2, "test5", 0, flags);
+   ut_asserteq_ptr(NULL, desc_err);
+
+   /* Try get GPIOs outside of the list */
+   desc_err = devm_gpiod_get_index(dev, "test4", 2, flags);
+   ut_assert(IS_ERR(desc_err));
+   desc_err = devm_gpiod_get_index_optional(dev, "test5", 1, flags);
+   ut_asserteq_ptr(NULL, desc_err);
+
+   /* Manipulate the GPIOs */
+   ut_assertok(dm_gpio_set_value(desc1, 1));
+   ut_asserteq(1, dm_gpio_get_value(desc1));
+   ut_assertok(dm_gpio_set_value(desc1, 0));
+   ut_asserteq(0, dm_gpio_get_value(desc1));
+
+   ut_assertok(dm_gpio_set_value(desc2, 1));
+   ut_asserteq(1, dm_gpio_get_value(desc2));
+   ut_assertok(dm_gpio_set_value(desc2, 0));
+   ut_asserteq(0, dm_gpio_get_value(desc2));
+
+   ut_assertok(dm_gpio_set_value(desc3, 1));
+   ut_asserteq(1, dm_gpio_get_value(desc3));
+   ut_assertok(dm_gpio_set_value(desc3, 0));
+   ut_asserteq(0, dm_gpio_get_value(desc3));
+
+ 

[PATCH v4 1/2] drivers: gpio: Add a managed API to get a GPIO from the device-tree

2020-09-07 Thread Pratyush Yadav
From: Jean-Jacques Hiblot 

Add managed functions to get a gpio from the devce-tree, based on a
property name (minus the '-gpios' suffix) and optionally an index.

When the device is unbound, the GPIO is automatically released and the
data structure is freed.

Signed-off-by: Jean-Jacques Hiblot 
Reviewed-by: Simon Glass 
Signed-off-by: Pratyush Yadav 
---
 drivers/gpio/gpio-uclass.c | 71 ++
 include/asm-generic/gpio.h | 47 +
 2 files changed, 118 insertions(+)

diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index 9c53299b6a..0c01413b58 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -6,6 +6,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -1209,6 +1211,75 @@ int gpio_dev_request_index(struct udevice *dev, const 
char *nodename,
 flags, 0, dev);
 }

+static void devm_gpiod_release(struct udevice *dev, void *res)
+{
+   dm_gpio_free(dev, res);
+}
+
+static int devm_gpiod_match(struct udevice *dev, void *res, void *data)
+{
+   return res == data;
+}
+
+struct gpio_desc *devm_gpiod_get_index(struct udevice *dev, const char *id,
+  unsigned int index, int flags)
+{
+   int rc;
+   struct gpio_desc *desc;
+   char *propname;
+   static const char suffix[] = "-gpios";
+
+   propname = malloc(strlen(id) + sizeof(suffix));
+   if (!propname) {
+   rc = -ENOMEM;
+   goto end;
+   }
+
+   strcpy(propname, id);
+   strcat(propname, suffix);
+
+   desc = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc),
+   __GFP_ZERO);
+   if (unlikely(!desc)) {
+   rc = -ENOMEM;
+   goto end;
+   }
+
+   rc = gpio_request_by_name(dev, propname, index, desc, flags);
+
+end:
+   if (propname)
+   free(propname);
+
+   if (rc)
+   return ERR_PTR(rc);
+
+   devres_add(dev, desc);
+
+   return desc;
+}
+
+struct gpio_desc *devm_gpiod_get_index_optional(struct udevice *dev,
+   const char *id,
+   unsigned int index,
+   int flags)
+{
+   struct gpio_desc *desc = devm_gpiod_get_index(dev, id, index, flags);
+
+   if (IS_ERR(desc))
+   return NULL;
+
+   return desc;
+}
+
+void devm_gpiod_put(struct udevice *dev, struct gpio_desc *desc)
+{
+   int rc;
+
+   rc = devres_release(dev, devm_gpiod_release, devm_gpiod_match, desc);
+   WARN_ON(rc);
+}
+
 static int gpio_post_bind(struct udevice *dev)
 {
struct udevice *child;
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index a57dd2665c..ad6979a8ce 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -701,4 +701,51 @@ int gpio_get_number(const struct gpio_desc *desc);
  */
 int gpio_get_acpi(const struct gpio_desc *desc, struct acpi_gpio *gpio);

+/**
+ * devm_gpiod_get_index - Resource-managed gpiod_get()
+ * @dev:   GPIO consumer
+ * @con_id:function within the GPIO consumer
+ * @index: index of the GPIO to obtain in the consumer
+ * @flags: optional GPIO initialization flags
+ *
+ * Managed gpiod_get(). GPIO descriptors returned from this function are
+ * automatically disposed on driver detach.
+ * Return the GPIO descriptor corresponding to the function con_id of device
+ * dev, -ENOENT if no GPIO has been assigned to the requested function, or
+ * another IS_ERR() code if an error occurred while trying to acquire the GPIO.
+ */
+struct gpio_desc *devm_gpiod_get_index(struct udevice *dev, const char *id,
+  unsigned int index, int flags);
+
+#define devm_gpiod_get(dev, id, flags) devm_gpiod_get_index(dev, id, 0, flags)
+/**
+ * gpiod_get_optional - obtain an optional GPIO for a given GPIO function
+ * @dev: GPIO consumer, can be NULL for system-global GPIOs
+ * @con_id: function within the GPIO consumer
+ * @index: index of the GPIO to obtain in the consumer
+ * @flags: optional GPIO initialization flags
+ *
+ * This is equivalent to devm_gpiod_get(), except that when no GPIO was
+ * assigned to the requested function it will return NULL. This is convenient
+ * for drivers that need to handle optional GPIOs.
+ */
+struct gpio_desc *devm_gpiod_get_index_optional(struct udevice *dev,
+   const char *id,
+   unsigned int index,
+   int flags);
+
+#define devm_gpiod_get_optional(dev, id, flags) \
+   devm_gpiod_get_index_optional(dev, id, 0, flags)
+
+/**
+ * devm_gpiod_put - Resource-managed gpiod_put()
+ * @dev:   GPIO consumer
+ * @desc:  GPIO descriptor to dispose of
+ *
+ * 

[PATCH v4 0/2] gpio: Add a managed API

2020-09-07 Thread Pratyush Yadav
Hi,

This is a re-submission of Jean-Jacques' earlier work in October last
year. It can be found at [0]. The goal is to facilitate porting drivers
from the Linux kernel. Most of the series will be about adding managed
APIs to existing infrastructure (GPIO, reset, regmap).

This particular series is about GPIOs. It adds a managed API using the
API as Linux. To make it 100% compatible with linux, there is a small
deviation from u-boot's way of naming the gpio lists: the managed
equivalent of gpio_request_by_name(..,"blabla-gpios", ...) is
devm_gpiod_get_index(..., "blabla", ...)

Travis CI run: https://travis-ci.org/github/prati0100/uboot/builds/725044296

Changes in v4:
- Rebase on latest master and fix merge conflicts.
- Move "another-test" node down the order to make sure
  dm_test_fdt_uclass_seq() continues to work.
- Bump num_devices to 9 in dm_test_bus_children(), dm_test_fdt(), and
  dm_test_uclass_foreach() to fix broken tests.
- s/DM_TESTF/UT_TESTF/g

Changes in v3:
- Add a blank line before return in devm_gpiod_get_index().
- Add Simon's Reviwed-by in both patches.

Changes in v2:
- The original series had a patch that checked for NULL pointers in the
  core GPIO functions. The checks were needed because of the addition of
  devm_gpiod_get_index_optional() which would return NULL when when no
  GPIO was assigned to the requested function. This is convenient for
  drivers that need to handle optional GPIOs.

  Simon argued that those should be behind a Kconfig option because of
  code size concerns. He also argued against implicit return in the
  macro that checked for the optional GPIOs.

  This submission removes the controversial patch so that base
  functionality can get merged.

  We still need to take a stance on who is responsible for the NULL
  check: the driver or the GPIO core? Do we want to trust drivers to
  take care of the NULL checks, or do we want to distrust them and make
  sure they don't send us anything bogus in the GPIO core. I will send a
  separate RFC of the NULL check patch and we can probably discuss the
  issue there.

[0] 
https://patchwork.ozlabs.org/project/uboot/cover/20191001115130.18886-1-jjhib...@ti.com/

Jean-Jacques Hiblot (2):
  drivers: gpio: Add a managed API to get a GPIO from the device-tree
  test: gpio: Add tests for the managed API

 arch/sandbox/dts/test.dts  |  10 
 drivers/gpio/gpio-uclass.c |  71 ++
 include/asm-generic/gpio.h |  47 +
 test/dm/bus.c  |   2 +-
 test/dm/gpio.c | 102 +
 test/dm/test-fdt.c |   6 +--
 6 files changed, 234 insertions(+), 4 deletions(-)

--
2.28.0



RE: [PATCH v2] arm: dts: fix ast2500-evb inclusion for the correct soc family

2020-09-07 Thread Ryan Chen
> -Original Message-
> From: Thirupathaiah Annapureddy 
> Sent: Wednesday, September 2, 2020 4:43 AM
> To: u-boot@lists.denx.de
> Cc: Maxim Sloyko ; Marek Vasut ;
> thir...@microsoft.com; thir...@linux.microsoft.com; Tom Rini
> ; ChiaWei Wang ;
> Ryan Chen 
> Subject: [PATCH v2] arm: dts: fix ast2500-evb inclusion for the correct soc
> family
> 
> Include ast2500-evb.dtb for CONFIG_ASPEED_AST2500 instead of for all
> aspeed targets.
> 
> ast2400 is based on ARM926EJ-S processor (ARMv5-architecture).
> ast2500 is based on ARM1176JZS processor (ARMv6-architecture).
> ast2600 is based on Cortex A7 processor (ARMv7-A architecture).
> Each of the above SOC is using a different ARM CPU(s) with different ARM
> architecture revision. It is not possible to support all 3 of these families 
> in a
> single binary. So there is no need to build ast2500-evb.dtb for other SOC
> families.
> 
> Signed-off-by: Thirupathaiah Annapureddy 
> ---
> 
> Changes in v2:
> - Incorporated the feedback from Tom Rini and Ryan Chen.
> 
>  arch/arm/dts/Makefile | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index
> 7e29b9096b..33d40a05f9 100644
> --- a/arch/arm/dts/Makefile
> +++ b/arch/arm/dts/Makefile
> @@ -938,7 +938,7 @@ dtb-$(CONFIG_ARCH_BCM6858) += \
> 
>  dtb-$(CONFIG_TARGET_BCMNS3) += ns3-board.dtb
> 
> -dtb-$(CONFIG_ARCH_ASPEED) += ast2500-evb.dtb
> +dtb-$(CONFIG_ASPEED_AST2500) += ast2500-evb.dtb
> 
I prefer keep the Makefile logic clear use one CONFIG_ARCH_ASPEED to make all 
ASPEED SoC dtb.
And also align with kernel tree " 
https://elixir.bootlin.com/linux/latest/source/arch/arm/boot/dts/Makefile;.
Another point of view, For example, There also have AST2520 SoC which share the 
same CPU architecture with AST2500,
And that will need another CONFIG_ASPEED_AST2520, That will cause more 
complicated dts Makefile.
 
>  dtb-$(CONFIG_ARCH_STI) += stih410-b2260.dtb
> 
> --
> 2.25.2



RE: [PATCH v1] arm: socfpga: soc64: Disable CONFIG_PSCI_RESET

2020-09-07 Thread Tan, Ley Foon



> -Original Message-
> From: Ang, Chee Hong 
> Sent: Friday, August 14, 2020 11:07 AM
> To: u-boot@lists.denx.de
> Cc: Marek Vasut ; Simon Goldschmidt
> ; Tom Rini ; See,
> Chin Liang ; Tan, Ley Foon
> ; Ang, Chee Hong ;
> Chee, Tien Fong ; Lim, Elly Siew Chin
> 
> Subject: [PATCH v1] arm: socfpga: soc64: Disable CONFIG_PSCI_RESET
> 
> Don't invoke 'SYSTEM_RESET' PSCI function because PSCI function calls are
> not supported by u-boot running in EL3.
> 
> Signed-off-by: Chee Hong Ang 
> ---
>  configs/socfpga_agilex_defconfig| 1 +
>  configs/socfpga_stratix10_defconfig | 1 +
>  2 files changed, 2 insertions(+)
> 
> diff --git a/configs/socfpga_agilex_defconfig
> b/configs/socfpga_agilex_defconfig
> index a08f66e248..feaab00249 100644
> --- a/configs/socfpga_agilex_defconfig
> +++ b/configs/socfpga_agilex_defconfig
> @@ -12,6 +12,7 @@ CONFIG_TARGET_SOCFPGA_AGILEX_SOCDK=y
>  CONFIG_IDENT_STRING="socfpga_agilex"
>  CONFIG_SPL_FS_FAT=y
>  CONFIG_DEFAULT_DEVICE_TREE="socfpga_agilex_socdk"
> +# CONFIG_PSCI_RESET is not set
>  CONFIG_BOOTDELAY=5
>  CONFIG_USE_BOOTARGS=y
>  CONFIG_BOOTARGS="earlycon"
> diff --git a/configs/socfpga_stratix10_defconfig
> b/configs/socfpga_stratix10_defconfig
> index 04e354f59e..e7c7550112 100644
> --- a/configs/socfpga_stratix10_defconfig
> +++ b/configs/socfpga_stratix10_defconfig
> @@ -14,6 +14,7 @@ CONFIG_SPL_FS_FAT=y
>  CONFIG_DEFAULT_DEVICE_TREE="socfpga_stratix10_socdk"
>  CONFIG_OPTIMIZE_INLINING=y
>  CONFIG_SPL_OPTIMIZE_INLINING=y
> +# CONFIG_PSCI_RESET is not set
>  CONFIG_BOOTDELAY=5
>  CONFIG_USE_BOOTARGS=y
>  CONFIG_BOOTARGS="earlycon"
> --


Reviewed-by: Ley Foon Tan 

Regards
Ley Foon


RE: [PATCH 0/3] net: tftp: Fixes for tftp rollover

2020-09-07 Thread Tan, Ley Foon



> -Original Message-
> From: Tan, Ley Foon 
> Sent: Tuesday, August 25, 2020 10:27 AM
> To: u-boot@lists.denx.de
> Cc: Joe Hershberger ; Ley Foon Tan
> ; See, Chin Liang ; Tan,
> Ley Foon 
> Subject: [PATCH 0/3] net: tftp: Fixes for tftp rollover
> 
> This patch series fix the tftp block number rollover bugs when sending and
> receiving large file (block number greater than 16-bit).
> 
> Tested receiving and sending large file with block number greater than 0x,
> verified content is 100% matched. Tested file size 128MB and 256MB.
> 
> Ley Foon Tan (3):
>   net: tftp: Fix tftp_prev_block counter update
>   net: tftp: Fix store_block offset calculation
>   net: tftp: Fix load_block offset calculation
> 
>  net/tftp.c | 9 ++---
>  1 file changed, 6 insertions(+), 3 deletions(-)

Hi Joe

Any comment for these 3 patches?

Thanks.

Regards
Ley Foon


Re: [PATCH v3 9/9] usb: xhci: convert to readx_poll_sleep_timeout()

2020-09-07 Thread Bin Meng
On Mon, Sep 7, 2020 at 3:14 PM Chunfeng Yun  wrote:
>
> Use readx_poll_sleep_timeout() to poll the register status
>
> Signed-off-by: Chunfeng Yun 
> ---
> v3: no changes
>
> v2: fix typo of title suggested by Frank
> ---
>  drivers/usb/host/xhci.c | 25 +++--
>  1 file changed, 11 insertions(+), 14 deletions(-)
>

Reviewed-by: Bin Meng 


Re: [PATCH v3 8/9] usb: xhci: use macros with parameter to fill ep_info2

2020-09-07 Thread Bin Meng
On Mon, Sep 7, 2020 at 3:14 PM Chunfeng Yun  wrote:
>
> Use macros with parameter to fill ep_info2, then some macros
> for MASK and SHIFT can be removed
>
> Signed-off-by: Chunfeng Yun 
> ---
> v3: merge patch [v2 9/11] and [v2 10/11] into one, both for ep_info2
>
> v2: no changes
> ---
>  drivers/usb/host/xhci-mem.c | 15 +--
>  drivers/usb/host/xhci.c |  6 ++
>  include/usb/xhci.h  |  6 --
>  3 files changed, 7 insertions(+), 20 deletions(-)
>

Reviewed-by: Bin Meng 


Re: [PATCH v3 7/9] usb: xhci: convert to TRB_TX_TYPE()

2020-09-07 Thread Bin Meng
On Mon, Sep 7, 2020 at 3:14 PM Chunfeng Yun  wrote:
>
> Use TRB_TX_TYPE() instead of (TRB_DATA_OUT/IN << TRB_TX_TYPE_SHIFT)
>
> Signed-off-by: Chunfeng Yun 
> ---
> v2: no changes
> ---
>  drivers/usb/host/xhci-ring.c | 4 ++--
>  include/usb/xhci.h   | 1 -
>  2 files changed, 2 insertions(+), 3 deletions(-)
>

Reviewed-by: Bin Meng 


Re: [PATCH v3 6/9] usb: xhci: convert to TRB_LEN() and TRB_INTR_TARGET()

2020-09-07 Thread Bin Meng
On Mon, Sep 7, 2020 at 3:14 PM Chunfeng Yun  wrote:
>
> For normal TRB fields:
> use TRB_LEN(x) instead of ((x) & TRB_LEN_MASK);
> and use TRB_INTR_TARGET(x) instead of
> (((x) & TRB_INTR_TARGET_MASK) << TRB_INTR_TARGET_SHIFT)
>
> Signed-off-by: Chunfeng Yun 
> ---
> v3: merge patch [v2 6/11] and [v2 7/11] into one, both for normal TRB fileds
>
> v2: no changes
> ---
>  drivers/usb/host/xhci-ring.c | 16 +++-
>  include/usb/xhci.h   |  3 ---
>  2 files changed, 7 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
> index 87891fd..99c84f9 100644
> --- a/drivers/usb/host/xhci-ring.c
> +++ b/drivers/usb/host/xhci-ring.c
> @@ -688,10 +688,9 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long 
> pipe,
>   length, maxpacketsize,
>   more_trbs_coming);
>
> -   length_field = ((trb_buff_len & TRB_LEN_MASK) |
> +   length_field = (TRB_LEN(trb_buff_len) |
> TRB_TD_SIZE(remainder) |
> -   ((0 & TRB_INTR_TARGET_MASK) <<
> -   TRB_INTR_TARGET_SHIFT));
> +   TRB_INTR_TARGET(0));

nits: should be aligned to TRB_LEN(length)

>
> trb_fields[0] = lower_32_bits(addr);
> trb_fields[1] = upper_32_bits(addr);
> @@ -849,8 +848,7 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long 
> pipe,
> trb_fields[1] = le16_to_cpu(req->index) |
> le16_to_cpu(req->length) << 16;
> /* TRB_LEN | (TRB_INTR_TARGET) */
> -   trb_fields[2] = (8 | ((0 & TRB_INTR_TARGET_MASK) <<
> -   TRB_INTR_TARGET_SHIFT));
> +   trb_fields[2] = (TRB_LEN(8) | TRB_INTR_TARGET(0));
> /* Immediate data in pointer */
> trb_fields[3] = field;
> queue_trb(ctrl, ep_ring, true, trb_fields);
> @@ -866,11 +864,11 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long 
> pipe,
>
> remainder = xhci_td_remainder(ctrl, 0, length, length,
>   usb_maxpacket(udev, pipe), 1);
> -   length_field = (length & TRB_LEN_MASK) | TRB_TD_SIZE(remainder) |
> -   ((0 & TRB_INTR_TARGET_MASK) << TRB_INTR_TARGET_SHIFT);
> +   length_field = TRB_LEN(length) | TRB_TD_SIZE(remainder) |
> +   TRB_INTR_TARGET(0);
> debug("length_field = %d, length = %d,"
> "xhci_td_remainder(length) = %d , TRB_INTR_TARGET(0) = %d\n",
> -   length_field, (length & TRB_LEN_MASK),
> +   length_field, TRB_LEN(length),
> TRB_TD_SIZE(remainder), 0);
>
> if (length > 0) {
> @@ -901,7 +899,7 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long 
> pipe,
>
> trb_fields[0] = 0;
> trb_fields[1] = 0;
> -   trb_fields[2] = ((0 & TRB_INTR_TARGET_MASK) << TRB_INTR_TARGET_SHIFT);
> +   trb_fields[2] = TRB_INTR_TARGET(0);
> /* Event on completion */
> trb_fields[3] = field | TRB_IOC |
> TRB_TYPE(TRB_STATUS) | ep_ring->cycle_state;
> diff --git a/include/usb/xhci.h b/include/usb/xhci.h
> index bdba51d..35c6604 100644
> --- a/include/usb/xhci.h
> +++ b/include/usb/xhci.h
> @@ -847,12 +847,9 @@ struct xhci_event_cmd {
>  /* Normal TRB fields */
>  /* transfer_len bitmasks - bits 0:16 */
>  #defineTRB_LEN(p)  ((p) & 0x1)
> -#defineTRB_LEN_MASK(0x1)
>  /* TD Size, packets remaining in this TD, bits 21:17 (5 bits, so max 31) */
>  #define TRB_TD_SIZE(p)  (min((p), (u32)31) << 17)
>  /* Interrupter Target - which MSI-X vector to target the completion event at 
> */
> -#defineTRB_INTR_TARGET_SHIFT   (22)
> -#defineTRB_INTR_TARGET_MASK(0x3ff)
>  #define TRB_INTR_TARGET(p) (((p) & 0x3ff) << 22)
>  #define GET_INTR_TARGET(p) (((p) >> 22) & 0x3ff)
>  #define TRB_TBC(p) (((p) & 0x3) << 7)
> --

Reviewed-by: Bin Meng 


RE: [v4, 00/11] mmc: fsl_esdhc: support eMMC HS200/HS400 modes

2020-09-07 Thread Peng Fan
Hi Y.b

> Subject: RE: [v4, 00/11] mmc: fsl_esdhc: support eMMC HS200/HS400 modes
> 
> Hi Jaehoon and Peng,
> 
> Any comments on the v4 patch-set?

Sorry for late. I need postpone the pick up this patchset until next.
I'll give a check, if no issues, I'll pick this into next branch.

Thanks,
Peng.

> Thank you.
> 
> Best regards,
> Yangbo Lu
> 
> > -Original Message-
> > From: Yangbo Lu 
> > Sent: Tuesday, September 1, 2020 4:58 PM
> > To: u-boot@lists.denx.de; Peng Fan ; Priyanka Jain
> > ; 'Jaehoon Chung' 
> > Cc: Y.b. Lu 
> > Subject: [v4, 00/11] mmc: fsl_esdhc: support eMMC HS200/HS400 modes
> >
> > This patch-set is to support eMMC HS200 and HS400 speed modes for
> > eSDHC, and enable them on LX2160ARDB board.
> >
> > CI build link
> > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Ftrav
> > is-ci
> > .org%2Fgithub%2Fyangbolu1991%2Fu-boot-test%2Fbuilds%2F720875619&
> a
> >
> mp;data=02%7C01%7Cyangbo.lu%40nxp.com%7Caf6b8adab90444f93e1208
> d
> >
> 84e563a07%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C637345
> >
> 479527036436sdata=L26QnuiL3ETvLbr4P1oJqxVJAoVlYY3ROg%2FWpb
> > J%2B6cc%3Dreserved=0
> >
> > Changes for v2:
> > - Added two patches to fix stability issue.
> > Changes for v3:
> > - Explained more in commit messages.
> > - Added HS400 exit code for downgrade.
> > Changes for v4:
> > - Checked returning of mmc_hs400_prepare_ddr().
> > - Added Reviewed-by.
> > - Rebased.
> >
> > Yangbo Lu (11):
> >   mmc: add a reinit() API
> >   mmc: fsl_esdhc: add a reinit() callback
> >   mmc: fsl_esdhc: support tuning for eMMC HS200
> >   mmc: fsl_esdhc: clean TBCTL[TB_EN] manually during init
> >   mmc: add a hs400_tuning flag
> >   mmc: add a mmc_hs400_prepare_ddr() interface
> >   mmc: fsl_esdhc: support eMMC HS400 mode
> >   mmc: fsl_esdhc: fix mmc->clock with actual clock
> >   mmc: fsl_esdhc: fix eMMC HS400 stability issue
> >   arm: dts: lx2160ardb: support eMMC HS400 mode
> >   configs: lx2160ardb: enable eMMC HS400 mode support
> >
> >  arch/arm/dts/fsl-lx2160a-rdb.dts |   2 +
> >  configs/lx2160ardb_tfa_SECURE_BOOT_defconfig |   1 +
> >  configs/lx2160ardb_tfa_defconfig |   1 +
> >  configs/lx2160ardb_tfa_stmm_defconfig|   1 +
> >  drivers/mmc/fsl_esdhc.c  | 176
> > ++-
> >  drivers/mmc/mmc-uclass.c |  30 +
> >  drivers/mmc/mmc.c|  14 ++-
> >  include/fsl_esdhc.h  |  29 -
> >  include/mmc.h|  26 +++-
> >  9 files changed, 270 insertions(+), 10 deletions(-)
> >
> > --
> > 2.7.4



Re: [PATCH U-BOOT v3 25/30] fs: btrfs: Implement btrfs_file_read()

2020-09-07 Thread Qu Wenruo



On 2020/9/8 上午8:56, Tom Rini wrote:
> On Tue, Sep 08, 2020 at 08:26:27AM +0800, Qu Wenruo wrote:
>>
>>
>> On 2020/9/8 上午6:35, Tom Rini wrote:
>>> On Wed, Jun 24, 2020 at 06:03:11PM +0200, Marek Behún wrote:
>>>
 From: Qu Wenruo 

 This version of btrfs_file_read() has the following new features:
 - Tries all mirrors
 - More handling on unaligned size
 - Better compressed extent handling
   The old implementation doesn't handle compressed extent with offset
   properly: we need to read out the whole compressed extent, then
   decompress the whole extent, and only then copy the requested part.

 Signed-off-by: Qu Wenruo 
 Reviewed-by: Marek Behún 
>>>
>>> Note that this introduces a warning with LLVM-10:
>>> fs/btrfs/btrfs.c:246:6: warning: variable 'real_size' is used uninitialized 
>>> whenever 'if' condition is false [-Wsometimes-uninitialized]
>>> if (!len) {
>>> ^~~~
>>> fs/btrfs/btrfs.c:255:12: note: uninitialized use occurs here
>>> if (len > real_size - offset)
>>>   ^
>>> fs/btrfs/btrfs.c:246:2: note: remove the 'if' if its condition is always 
>>> true
>>> if (!len) {
>>> ^~
>>> fs/btrfs/btrfs.c:228:18: note: initialize the variable 'real_size' to 
>>> silence this warning
>>> loff_t real_size;
>>> ^
>>>  = 0
>>> 1 warning generated.
>>>
>>> and I have silenced as suggested.  I'm not 100% happy with that, but
>>> leave fixing it here and in upstream btrfs-progs to the btrfs-experts.
>>
>> My bad. The warning is correct, and since the code is U-boot specific,
>> it doesn't affect kernel (using page) nor btrfs-progs (not really do
>> file read with offset).
>>
>> The fix is a little complex.
>>
>> In fact we need to always call btrfs_size() to grab the real_size, and
>> then modify @len using real_size, either using real_size directly, or do
>> some basic calculation.
> 
> Ah, thanks.  I'll fold in your changes.
> 
>>
>> BTW, I didn't see the btrfs rebuild work merged upstream. Is this
>> planned or you just grab from some specific branch?
> 
> Yes, I'm testing them for -next right now.
> 
That's awesome!

Thanks for your effort,
Qu



Re: [PATCH U-BOOT v3 25/30] fs: btrfs: Implement btrfs_file_read()

2020-09-07 Thread Tom Rini
On Tue, Sep 08, 2020 at 08:26:27AM +0800, Qu Wenruo wrote:
> 
> 
> On 2020/9/8 上午6:35, Tom Rini wrote:
> > On Wed, Jun 24, 2020 at 06:03:11PM +0200, Marek Behún wrote:
> > 
> >> From: Qu Wenruo 
> >>
> >> This version of btrfs_file_read() has the following new features:
> >> - Tries all mirrors
> >> - More handling on unaligned size
> >> - Better compressed extent handling
> >>   The old implementation doesn't handle compressed extent with offset
> >>   properly: we need to read out the whole compressed extent, then
> >>   decompress the whole extent, and only then copy the requested part.
> >>
> >> Signed-off-by: Qu Wenruo 
> >> Reviewed-by: Marek Behún 
> > 
> > Note that this introduces a warning with LLVM-10:
> > fs/btrfs/btrfs.c:246:6: warning: variable 'real_size' is used uninitialized 
> > whenever 'if' condition is false [-Wsometimes-uninitialized]
> > if (!len) {
> > ^~~~
> > fs/btrfs/btrfs.c:255:12: note: uninitialized use occurs here
> > if (len > real_size - offset)
> >   ^
> > fs/btrfs/btrfs.c:246:2: note: remove the 'if' if its condition is always 
> > true
> > if (!len) {
> > ^~
> > fs/btrfs/btrfs.c:228:18: note: initialize the variable 'real_size' to 
> > silence this warning
> > loff_t real_size;
> > ^
> >  = 0
> > 1 warning generated.
> > 
> > and I have silenced as suggested.  I'm not 100% happy with that, but
> > leave fixing it here and in upstream btrfs-progs to the btrfs-experts.
> 
> My bad. The warning is correct, and since the code is U-boot specific,
> it doesn't affect kernel (using page) nor btrfs-progs (not really do
> file read with offset).
> 
> The fix is a little complex.
> 
> In fact we need to always call btrfs_size() to grab the real_size, and
> then modify @len using real_size, either using real_size directly, or do
> some basic calculation.

Ah, thanks.  I'll fold in your changes.

> 
> BTW, I didn't see the btrfs rebuild work merged upstream. Is this
> planned or you just grab from some specific branch?

Yes, I'm testing them for -next right now.

-- 
Tom


signature.asc
Description: PGP signature


Re: [PATCH U-BOOT v3 25/30] fs: btrfs: Implement btrfs_file_read()

2020-09-07 Thread Qu Wenruo


On 2020/9/8 上午6:35, Tom Rini wrote:
> On Wed, Jun 24, 2020 at 06:03:11PM +0200, Marek Behún wrote:
> 
>> From: Qu Wenruo 
>>
>> This version of btrfs_file_read() has the following new features:
>> - Tries all mirrors
>> - More handling on unaligned size
>> - Better compressed extent handling
>>   The old implementation doesn't handle compressed extent with offset
>>   properly: we need to read out the whole compressed extent, then
>>   decompress the whole extent, and only then copy the requested part.
>>
>> Signed-off-by: Qu Wenruo 
>> Reviewed-by: Marek Behún 
> 
> Note that this introduces a warning with LLVM-10:
> fs/btrfs/btrfs.c:246:6: warning: variable 'real_size' is used uninitialized 
> whenever 'if' condition is false [-Wsometimes-uninitialized]
> if (!len) {
> ^~~~
> fs/btrfs/btrfs.c:255:12: note: uninitialized use occurs here
> if (len > real_size - offset)
>   ^
> fs/btrfs/btrfs.c:246:2: note: remove the 'if' if its condition is always true
> if (!len) {
> ^~
> fs/btrfs/btrfs.c:228:18: note: initialize the variable 'real_size' to silence 
> this warning
> loff_t real_size;
> ^
>  = 0
> 1 warning generated.
> 
> and I have silenced as suggested.  I'm not 100% happy with that, but
> leave fixing it here and in upstream btrfs-progs to the btrfs-experts.

My bad. The warning is correct, and since the code is U-boot specific,
it doesn't affect kernel (using page) nor btrfs-progs (not really do
file read with offset).

The fix is a little complex.

In fact we need to always call btrfs_size() to grab the real_size, and
then modify @len using real_size, either using real_size directly, or do
some basic calculation.


BTW, I didn't see the btrfs rebuild work merged upstream. Is this
planned or you just grab from some specific branch?

The proper fix would look like this:

diff --git a/fs/btrfs/btrfs.c b/fs/btrfs/btrfs.c
index 786bb4733fbd..a1a7b3cf1afb 100644
--- a/fs/btrfs/btrfs.c
+++ b/fs/btrfs/btrfs.c
@@ -243,14 +243,13 @@ int btrfs_read(const char *file, void *buf, loff_t
offset, loff_t len,
return -EINVAL;
}

-   if (!len) {
-   ret = btrfs_size(file, _size);
-   if (ret < 0) {
-   error("Failed to get inode size: %s", file);
-   return ret;
-   }
-   len = real_size;
+   ret = btrfs_size(file, _size);
+   if (ret < 0) {
+   error("Failed to get inode size: %s", file);
+   return ret;
}
+   if (!len)
+   len = real_size;

if (len > real_size - offset)
len = real_size - offset;




signature.asc
Description: OpenPGP digital signature


Re: [BUG] rsa: crash in br_i32_decode() called from rsa_gen_key_prop()

2020-09-07 Thread AKASHI Takahiro
On Mon, Sep 07, 2020 at 05:58:14PM +0200, Heinrich Schuchardt wrote:
> Hello Takahiro,
> 
> on the 32bit Wandboard (with i.mx6 CPU) running the lib_asn1_pkcs7 unit
> test results in a crash due to an unaligned access occurring when
> br_i32_decode() is called by rsa_gen_key_prop().

Some guy has sent me a similar bug report about unaligned access
in rsa-keyprop.c.
I will ask him to post a patch as he seems to have fixed it.

-Takahiro Akashi


> Please, check the alignment assumptions for src when calling
> br_i32_decode(). If src is only 1 byte aligned, you should neither call
> be32_to_cpup() nor be16_to_cpup() which assume 32bit and 16bit alignment.
> 
> 
> Running lib tests
> Running 14 lib tests
> Test: lib_asn1_pkcs7
> data abort
> pc : [<8efb3a8e>]  lr : [<8efb3bbd>]
> reloc pc : [<17845a8e>]lr : [<17845bbd>]
> sp : 8e561330  ip : 0001 fp : 8efd9d66
> r10: 8e58f040  r9 : 8e56dec0 r8 : 8e588748
> r7 : 0001  r6 : 8e58f350 r5 : 8e58f350  r4 : 8e58f350
> r3 : 00fc  r2 : 0100 r1 : 8e58ee49  r0 : 8e58f350
> Flags: nzCv  IRQs off  FIQs off  Mode SVC_32 (T)
> Code: ea43 4302 e7a2 3b04 (58c8) ba00
> Resetting CPU ...
> 
> resetting ...
> 
> 
> 
> br_i32_decode():
> 
> return be16_to_cpup(src);
> 17845a84:   b29buxthr3, r3
> w = ((uint32_t)buf[0] << 16)
> 17845a86:   ea43 4302   orr.w   r3, r3, r2, lsl #16
> 17845a8a:   e7a2b.n 178459d2 
> u -= 4;
> 17845a8c:   3b04subsr3, #4
> return __arch__swab32p(x);
> 17845a8e:   58c8ldr r0, [r1, r3]  <<
> 17845a90:   ba00rev r0, r0
> x[v ++] = br_dec32be(buf + u);
> 17845a92:   f845 0f04   str.w   r0, [r5, #4]!
> if (u < 4) {
> 17845a96:   e78fb.n 178459b8 
> return y ^ (-ctl & (x ^ y));
> 
> 
> rsa_gen_key_prop():
> 
> /* n0 inverse */
> br_i32_decode(n, _key.n[i], rsa_key.n_sz - i);
> 17845bac:   9910ldr r1, [sp, #64]   ; 0x40
> (*prop)->exp_len = sizeof(uint64_t);
> 17845bae:   615astr r2, [r3, #20]
> br_i32_decode(n, _key.n[i], rsa_key.n_sz - i);
> 17845bb0:   9a18ldr r2, [sp, #96]   ; 0x60
> 17845bb2:   4439add r1, r7
> 17845bb4:   1bd2subsr2, r2, r7
> 17845bb6:   4630mov r0, r6
> 17845bb8:   f7ff fef9   bl  178459ae  <<
> (*prop)->n0inv = br_i32_ninv32(n[1]);
> 17845bbc:   6873ldr r3, [r6, #4]
> 17845bbe:   682aldr r2, [r5, #0]
> y = 2 - x;
> 17845bc0:   f1c3 0102   rsb r1, r3, #2
> 
> 
> 
> Best regards
> 
> Heinrich


Re: [PATCH U-BOOT v3 03/30] fs: btrfs: Crossport btrfs_read_dev_super() from btrfs-progs

2020-09-07 Thread Marek Behun
On Mon, 7 Sep 2020 18:26:04 -0400
Tom Rini  wrote:

> On Wed, Jun 24, 2020 at 06:02:49PM +0200, Marek Behún wrote:
> 
> > From: Qu Wenruo 
> > 
> > This patch uses generic code from btrfs-progs to read one super block
> > from block device.  
> [snip]
> > +/* Provide a compatibility layer to make code syncing easier */
> > +
> > +/* A simple wraper to for error() used in btrfs-progs */
> > +__attribute__((format (__printf__, 1, 2)))
> > +static inline void error(const char *fmt, ...)
> > +{
> > +   printf("BTRFS: ");
> > +   printf(fmt, __builtin_va_arg_pack());
> > +   printf("\n");
> > +}  
> 
> Note that this does not work with LLVM (no __builtin_va_arg_pack()).
> I'm reworking this call pr_err(...) under the hood instead, with "BTRFS: " 
> included in the message.
> 

:( clang does not support it? Even the newest version? That is a pity.

Marek


Re: [PATCH U-BOOT v3 25/30] fs: btrfs: Implement btrfs_file_read()

2020-09-07 Thread Tom Rini
On Wed, Jun 24, 2020 at 06:03:11PM +0200, Marek Behún wrote:

> From: Qu Wenruo 
> 
> This version of btrfs_file_read() has the following new features:
> - Tries all mirrors
> - More handling on unaligned size
> - Better compressed extent handling
>   The old implementation doesn't handle compressed extent with offset
>   properly: we need to read out the whole compressed extent, then
>   decompress the whole extent, and only then copy the requested part.
> 
> Signed-off-by: Qu Wenruo 
> Reviewed-by: Marek Behún 

Note that this introduces a warning with LLVM-10:
fs/btrfs/btrfs.c:246:6: warning: variable 'real_size' is used uninitialized 
whenever 'if' condition is false [-Wsometimes-uninitialized]
if (!len) {
^~~~
fs/btrfs/btrfs.c:255:12: note: uninitialized use occurs here
if (len > real_size - offset)
  ^
fs/btrfs/btrfs.c:246:2: note: remove the 'if' if its condition is always true
if (!len) {
^~
fs/btrfs/btrfs.c:228:18: note: initialize the variable 'real_size' to silence 
this warning
loff_t real_size;
^
 = 0
1 warning generated.

and I have silenced as suggested.  I'm not 100% happy with that, but
leave fixing it here and in upstream btrfs-progs to the btrfs-experts.

-- 
Tom


signature.asc
Description: PGP signature


Re: [PATCH U-BOOT v3 03/30] fs: btrfs: Crossport btrfs_read_dev_super() from btrfs-progs

2020-09-07 Thread Tom Rini
On Wed, Jun 24, 2020 at 06:02:49PM +0200, Marek Behún wrote:

> From: Qu Wenruo 
> 
> This patch uses generic code from btrfs-progs to read one super block
> from block device.
[snip]
> +/* Provide a compatibility layer to make code syncing easier */
> +
> +/* A simple wraper to for error() used in btrfs-progs */
> +__attribute__((format (__printf__, 1, 2)))
> +static inline void error(const char *fmt, ...)
> +{
> + printf("BTRFS: ");
> + printf(fmt, __builtin_va_arg_pack());
> + printf("\n");
> +}

Note that this does not work with LLVM (no __builtin_va_arg_pack()).
I'm reworking this call pr_err(...) under the hood instead, with "BTRFS: " 
included in the message.

-- 
Tom


signature.asc
Description: PGP signature


Re: Please pull u-boot-marvell/remove-config-nr-dram-banks-v9-2020-08-26

2020-09-07 Thread Tom Rini
On Wed, Aug 26, 2020 at 09:31:07AM +0200, Stefan Roese wrote:

> Hi Tom,
> 
> I've prepared a branch for you to pull the "Remove CONFIG_NR_DRAM_BANKS
> option and bi_memstart/memsize from bd_info" patchset, if you care to
> pull from it. I've rebased it on top of latest TOT, which was necessary
> because of a merge conflict in pci-uclass.c. I think it's ready to go
> upstream now.
> 
> Here the Azure build, without any issues:
> 
> https://dev.azure.com/sr0718/u-boot/_build/results?buildId=46=results
> 
> Thanks,
> Stefan
> 
> 
> The following changes since commit 9f9ecd3e4d7839e24c182fb7b24937e19b670f1b:
> 
>Merge https://gitlab.denx.de/u-boot/custodians/u-boot-marvell 
> (2020-08-25 13:38:29 -0400)
> 
> are available in the Git repository at:
> 
>g...@gitlab.denx.de:u-boot/custodians/u-boot-marvell.git 
> remove-config-nr-dram-banks-v9-2020-08-26
> 
> for you to fetch changes up to bac9da46c57511e574aa7e763e17fdd6f55db5bb:
> 
>asm-generic/u-boot.h: Remove bi_memstart & bi_memsize from bd_info 
> (2020-08-26 09:20:05 +0200)
> 

Applied to u-boot/next, thanks!

-- 
Tom


signature.asc
Description: PGP signature


[PATCH v7 1/2] board: kontron: add sl28 support

2020-09-07 Thread Michael Walle
Add basic support for the Kontron SMARC-sAL28 board. This includes just
the bare minimum to be able to bring up the board and boot linux.

For now, the Single and Dual PHY variant is supported. Other variants
will fall back to the basic variant.

In particular, there is no watchdog support for now. This means that you
have to disable the default watchdog, otherwise you'll end up in the
recovery bootloader. See the board README for details.

Signed-off-by: Michael Walle 
---
 arch/arm/Kconfig  |  11 +
 arch/arm/dts/Makefile |   3 +
 .../dts/fsl-ls1028a-kontron-sl28-u-boot.dtsi  | 135 +
 .../fsl-ls1028a-kontron-sl28-var3-u-boot.dtsi |   2 +
 .../arm/dts/fsl-ls1028a-kontron-sl28-var3.dts |  15 ++
 .../fsl-ls1028a-kontron-sl28-var4-u-boot.dtsi |   2 +
 .../arm/dts/fsl-ls1028a-kontron-sl28-var4.dts |  48 +
 arch/arm/dts/fsl-ls1028a-kontron-sl28.dts | 189 ++
 board/kontron/sl28/Kconfig|  18 ++
 board/kontron/sl28/MAINTAINERS|   7 +
 board/kontron/sl28/Makefile   |   8 +
 board/kontron/sl28/common.c   |  10 +
 board/kontron/sl28/ddr.c  |  98 +
 board/kontron/sl28/sl28.c |  68 +++
 board/kontron/sl28/spl.c  |  32 +++
 configs/kontron_sl28_defconfig| 107 ++
 doc/board/index.rst   |   1 +
 doc/board/kontron/index.rst   |   9 +
 doc/board/kontron/sl28.rst| 160 +++
 include/configs/kontron_sl28.h| 108 ++
 20 files changed, 1031 insertions(+)
 create mode 100644 arch/arm/dts/fsl-ls1028a-kontron-sl28-u-boot.dtsi
 create mode 100644 arch/arm/dts/fsl-ls1028a-kontron-sl28-var3-u-boot.dtsi
 create mode 100644 arch/arm/dts/fsl-ls1028a-kontron-sl28-var3.dts
 create mode 100644 arch/arm/dts/fsl-ls1028a-kontron-sl28-var4-u-boot.dtsi
 create mode 100644 arch/arm/dts/fsl-ls1028a-kontron-sl28-var4.dts
 create mode 100644 arch/arm/dts/fsl-ls1028a-kontron-sl28.dts
 create mode 100644 board/kontron/sl28/Kconfig
 create mode 100644 board/kontron/sl28/MAINTAINERS
 create mode 100644 board/kontron/sl28/Makefile
 create mode 100644 board/kontron/sl28/common.c
 create mode 100644 board/kontron/sl28/ddr.c
 create mode 100644 board/kontron/sl28/sl28.c
 create mode 100644 board/kontron/sl28/spl.c
 create mode 100644 configs/kontron_sl28_defconfig
 create mode 100644 doc/board/kontron/index.rst
 create mode 100644 doc/board/kontron/sl28.rst
 create mode 100644 include/configs/kontron_sl28.h

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 80702c23d3..f57d48800d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1615,6 +1615,16 @@ config TARGET_LS1046AFRWY
  development platform that supports the QorIQ LS1046A
  Layerscape Architecture processor.
 
+config TARGET_SL28
+   bool "Support sl28"
+   select ARCH_LS1028A
+   select ARM64
+   select ARMV8_MULTIENTRY
+   select SUPPORT_SPL
+   select BINMAN
+   help
+ Support for Kontron SMARC-sAL28 board.
+
 config TARGET_COLIBRI_PXA270
bool "Support colibri_pxa270"
select CPU_PXA
@@ -1986,6 +1996,7 @@ source "board/hisilicon/hikey/Kconfig"
 source "board/hisilicon/hikey960/Kconfig"
 source "board/hisilicon/poplar/Kconfig"
 source "board/isee/igep003x/Kconfig"
+source "board/kontron/sl28/Kconfig"
 source "board/myir/mys_6ulx/Kconfig"
 source "board/spear/spear300/Kconfig"
 source "board/spear/spear310/Kconfig"
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index f8f529435b..b45eb6a772 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -422,6 +422,9 @@ dtb-$(CONFIG_FSL_LSCH2) += fsl-ls1043a-qds-duart.dtb \
fsl-ls1012a-2g5rdb.dtb \
fsl-ls1012a-frdm.dtb \
fsl-ls1012a-frwy.dtb
+dtb-$(CONFIG_TARGET_SL28) += fsl-ls1028a-kontron-sl28.dtb \
+   fsl-ls1028a-kontron-sl28-var3.dtb \
+   fsl-ls1028a-kontron-sl28-var4.dtb \
 
 dtb-$(CONFIG_TARGET_DRAGONBOARD410C) += dragonboard410c.dtb
 dtb-$(CONFIG_TARGET_DRAGONBOARD820C) += dragonboard820c.dtb
diff --git a/arch/arm/dts/fsl-ls1028a-kontron-sl28-u-boot.dtsi 
b/arch/arm/dts/fsl-ls1028a-kontron-sl28-u-boot.dtsi
new file mode 100644
index 00..2375549c6e
--- /dev/null
+++ b/arch/arm/dts/fsl-ls1028a-kontron-sl28-u-boot.dtsi
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include 
+
+/ {
+   aliases {
+   mmc0 = 
+   mmc1 = 
+   i2c0 = 
+   i2c1 = 
+   i2c2 = 
+   rtc0 = 
+   ethernet0 = 
+   ethernet1 = 
+   ethernet2 = 
+   ethernet3 = 
+   };
+
+   binman {
+   filename = "u-boot.rom";
+   pad-byte = <0xff>;
+
+   u-boot-spl {
+   };
+
+   fit {
+   offset = 

[PATCH v7 2/2] board: sl28: add board specific nvm command

2020-09-07 Thread Michael Walle
The board supports 16 configuration bits which can be manipulated with
this command. See the board's README for a detailed explanation on each
bit.

Signed-off-by: Michael Walle 
---
 board/kontron/sl28/Makefile |   2 +-
 board/kontron/sl28/cmds.c   | 178 
 2 files changed, 179 insertions(+), 1 deletion(-)
 create mode 100644 board/kontron/sl28/cmds.c

diff --git a/board/kontron/sl28/Makefile b/board/kontron/sl28/Makefile
index 0f1866c874..74d8012f0f 100644
--- a/board/kontron/sl28/Makefile
+++ b/board/kontron/sl28/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0+
 
 ifndef CONFIG_SPL_BUILD
-obj-y += sl28.o
+obj-y += sl28.o cmds.o
 endif
 
 obj-y += common.o ddr.o
diff --git a/board/kontron/sl28/cmds.c b/board/kontron/sl28/cmds.c
new file mode 100644
index 00..046d3b4903
--- /dev/null
+++ b/board/kontron/sl28/cmds.c
@@ -0,0 +1,178 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * sl28 extension commands
+ *
+ * Copyright (c) 2020 Kontron Europe GmbH
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#define CPLD_I2C_ADDR 0x4a
+#define REG_UFM_CTRL 0x02
+#define   UFM_CTRL_DCLKBIT(1)
+#define   UFM_CTRL_DIN BIT(2)
+#define   UFM_CTRL_PROGRAM BIT(3)
+#define   UFM_CTRL_ERASE   BIT(4)
+#define   UFM_CTRL_DSHIFT  BIT(5)
+#define   UFM_CTRL_DOUTBIT(6)
+#define   UFM_CTRL_BUSYBIT(7)
+
+static int ufm_shift_data(struct udevice *dev, u16 data_in, u16 *data_out)
+{
+   int i;
+   int ret;
+   u16 data = 0;
+
+   /* latch data */
+   ret = dm_i2c_reg_write(dev, REG_UFM_CTRL, 0);
+   if (ret < 0)
+   return ret;
+   ret = dm_i2c_reg_write(dev, REG_UFM_CTRL, UFM_CTRL_DCLK);
+   if (ret < 0)
+   return ret;
+
+   /* assert drshift */
+   ret = dm_i2c_reg_write(dev, REG_UFM_CTRL,
+  UFM_CTRL_DSHIFT | UFM_CTRL_DCLK);
+   if (ret < 0)
+   return ret;
+
+   /* clock 16 data bits, reverse order */
+   for (i = 15; i >= 0; i--) {
+   u8 din = (data_in & (1 << i)) ? UFM_CTRL_DIN : 0;
+
+   ret = dm_i2c_reg_write(dev, REG_UFM_CTRL, UFM_CTRL_DSHIFT
+   | din);
+   if (ret < 0)
+   return ret;
+   if (data_out) {
+   ret = dm_i2c_reg_read(dev, REG_UFM_CTRL);
+   if (ret < 0)
+   return ret;
+   if (ret & UFM_CTRL_DOUT)
+   data |= (1 << i);
+   }
+   ret = dm_i2c_reg_write(dev, REG_UFM_CTRL,
+  UFM_CTRL_DSHIFT | UFM_CTRL_DCLK | din);
+   if (ret < 0)
+   return ret;
+   }
+
+   /* deassert drshift */
+   ret = dm_i2c_reg_write(dev, REG_UFM_CTRL, UFM_CTRL_DCLK);
+   if (ret < 0)
+   return ret;
+
+   if (data_out)
+   *data_out = data;
+
+   return ret;
+}
+
+static int ufm_erase(struct udevice *dev)
+{
+   int ret;
+
+   /* erase, tEPMX is 500ms */
+   ret = dm_i2c_reg_write(dev, REG_UFM_CTRL,
+  UFM_CTRL_DCLK | UFM_CTRL_ERASE);
+   if (ret < 0)
+   return ret;
+   ret = dm_i2c_reg_write(dev, REG_UFM_CTRL, UFM_CTRL_DCLK);
+   if (ret < 0)
+   return ret;
+   mdelay(500);
+
+   return 0;
+}
+
+static int ufm_program(struct udevice *dev)
+{
+   int ret;
+
+   /* program, tPPMX is 100us */
+   ret = dm_i2c_reg_write(dev, REG_UFM_CTRL,
+  UFM_CTRL_DCLK | UFM_CTRL_PROGRAM);
+   if (ret < 0)
+   return ret;
+   ret = dm_i2c_reg_write(dev, REG_UFM_CTRL, UFM_CTRL_DCLK);
+   if (ret < 0)
+   return ret;
+   udelay(100);
+
+   return 0;
+}
+
+static int ufm_write(struct udevice *dev, u16 data)
+{
+   int ret;
+
+   ret = ufm_shift_data(dev, data, NULL);
+   if (ret < 0)
+   return ret;
+
+   ret = ufm_erase(dev);
+   if (ret < 0)
+   return ret;
+
+   return ufm_program(dev);
+}
+
+static int ufm_read(struct udevice *dev, u16 *data)
+{
+   return ufm_shift_data(dev, 0, data);
+}
+
+static int do_sl28_nvm(struct cmd_tbl *cmdtp, int flag, int argc,
+  char *const argv[])
+{
+   struct udevice *dev;
+   u16 nvm;
+   int ret;
+   char *endp;
+
+   if (i2c_get_chip_for_busnum(0, CPLD_I2C_ADDR, 1, ))
+   return CMD_RET_FAILURE;
+
+   if (argc > 1) {
+   nvm = simple_strtoul(argv[1], , 16);
+   if (*endp != '\0') {
+   printf("ERROR: argument is not a valid number\n");
+   ret = -EINVAL;
+   goto out;
+   }
+
+   /*
+* We swap all bits, because the a zero bit in hardware means 
the
+* feature is 

[PATCH v7 0/2] Basic Kontron SMARC-sAL28 board support

2020-09-07 Thread Michael Walle
Add basic board support for the Kontron SMARC-sAL28 board. Please note,
that this board doesn't support TF-a (yet). Therefore, the u-boot SPL is
the first code which is run and it has to set up the RAM.

changes since v6:
 - moved README to doc/board/kontron/sl28.rst
 - added device tree files to MAINTAINERS
 - converted preprocessor macros to actual code using IS_ENABLED()
 - fixed sec_init(), use CONFIG_IS_ENABLED() instead of IS_ENABLED()
 - removed unnecessary #ifdef CONFIG_OF_BOARD_SETUP
 - removed CONFIG_SPL_TARGET, because we use binman, this is not needed
   anymore
 - removed unnecessary CONFIG_SYS_MONITOR_BASE macro
 - redefinded memory addresses according to the comment in
   ti_armv7_common.h
 - removed empty BOOTENV for SPL build
 - removed fdt_high and initrd_high
Thanks Tom!

changes since v5:
 - moved CONFIG_ENV_OVERWRITE to defconfig. Thanks Kuldeep!

changes since v4:
 - dropped "armv8: ls1028a: move FSL_LAYERSCAPE to kconfig" as it is
   already upstream
 - new patch "board: sl28: add board specific nvm command"
 - use binman
 - sync device trees with linux
 - use "-u-boot.dtsi" style
 - rebase to lastest master

changes since v3:
 - rebase to latest master
 - use CONFIG_PCI_INIT_R
 - set fdtfile in default environment

changes since v2:
 - add variant 4 support. Since the atheros PHY dt bindings were merged
   into master, we can now use them
 - add environment section in include/configs/kontron_sl28.h
 - add cover letter

changes since v1:
 - fix watchdog device tree reference

Michael Walle (2):
  board: kontron: add sl28 support
  board: sl28: add board specific nvm command

 arch/arm/Kconfig  |  11 +
 arch/arm/dts/Makefile |   3 +
 .../dts/fsl-ls1028a-kontron-sl28-u-boot.dtsi  | 135 +
 .../fsl-ls1028a-kontron-sl28-var3-u-boot.dtsi |   2 +
 .../arm/dts/fsl-ls1028a-kontron-sl28-var3.dts |  15 ++
 .../fsl-ls1028a-kontron-sl28-var4-u-boot.dtsi |   2 +
 .../arm/dts/fsl-ls1028a-kontron-sl28-var4.dts |  48 +
 arch/arm/dts/fsl-ls1028a-kontron-sl28.dts | 189 ++
 board/kontron/sl28/Kconfig|  18 ++
 board/kontron/sl28/MAINTAINERS|   7 +
 board/kontron/sl28/Makefile   |   8 +
 board/kontron/sl28/cmds.c | 178 +
 board/kontron/sl28/common.c   |  10 +
 board/kontron/sl28/ddr.c  |  98 +
 board/kontron/sl28/sl28.c |  68 +++
 board/kontron/sl28/spl.c  |  32 +++
 configs/kontron_sl28_defconfig| 107 ++
 doc/board/index.rst   |   1 +
 doc/board/kontron/index.rst   |   9 +
 doc/board/kontron/sl28.rst| 160 +++
 include/configs/kontron_sl28.h| 109 ++
 21 files changed, 1210 insertions(+)
 create mode 100644 arch/arm/dts/fsl-ls1028a-kontron-sl28-u-boot.dtsi
 create mode 100644 arch/arm/dts/fsl-ls1028a-kontron-sl28-var3-u-boot.dtsi
 create mode 100644 arch/arm/dts/fsl-ls1028a-kontron-sl28-var3.dts
 create mode 100644 arch/arm/dts/fsl-ls1028a-kontron-sl28-var4-u-boot.dtsi
 create mode 100644 arch/arm/dts/fsl-ls1028a-kontron-sl28-var4.dts
 create mode 100644 arch/arm/dts/fsl-ls1028a-kontron-sl28.dts
 create mode 100644 board/kontron/sl28/Kconfig
 create mode 100644 board/kontron/sl28/MAINTAINERS
 create mode 100644 board/kontron/sl28/Makefile
 create mode 100644 board/kontron/sl28/cmds.c
 create mode 100644 board/kontron/sl28/common.c
 create mode 100644 board/kontron/sl28/ddr.c
 create mode 100644 board/kontron/sl28/sl28.c
 create mode 100644 board/kontron/sl28/spl.c
 create mode 100644 configs/kontron_sl28_defconfig
 create mode 100644 doc/board/kontron/index.rst
 create mode 100644 doc/board/kontron/sl28.rst
 create mode 100644 include/configs/kontron_sl28.h

-- 
2.20.1



Re: [RFC 3/4] dtoc: add support for generate stuct udevice_id

2020-09-07 Thread Walter Lozano

Hi Simon,

On 6/9/20 22:44, Simon Glass wrote:

Hi Walter,

On Fri, 7 Aug 2020 at 11:23, Walter Lozano  wrote:

Hi Simon

On 7/8/20 13:23, Simon Glass wrote:

Hi Walter,

On Wed, 29 Jul 2020 at 10:00, Walter Lozano  wrote:

Hi Simon,

On 28/7/20 23:42, Simon Glass wrote:

Hi Walter,

On Sun, 26 Jul 2020 at 20:16, Walter Lozano  wrote:

Hi Simon,

On 26/7/20 11:53, Simon Glass wrote:

Hi Walter,

On Tue, 7 Jul 2020 at 08:08, Walter Lozano  wrote:

Hi Simon

On 6/7/20 16:21, Simon Glass wrote:

Hi Walter,

On Fri, 19 Jun 2020 at 15:12, Walter Lozano  wrote:

Based on several reports there is an increasing concern in the impact
of adding additional features to drivers based on compatible strings.
A good example of this situation is found in [1].

In order to reduce this impact and as an initial step for further
reduction, propose a new way to declare compatible strings, which allows
to only include the useful ones.

What are the useful ones?

The useful ones would be those that are used by the selected DTB by the
current configuration. The idea of this patch is to declare all the
possible compatible strings in a way that dtoc can generate code for
only those which are going to be used, and in this way avoid lots of
#ifdef like the ones shows in

http://patchwork.ozlabs.org/project/uboot/patch/20200525202429.2146-1-ag...@denx.de/



The idea is to define compatible strings in a way to be easily parsed by
dtoc, which will be responsible to build struct udevice_id [] based on
the compatible strings present in the dtb.

Additional features can be easily added, such as define constants
depending on the presence of compatible strings, which allows to enable
code blocks only in such cases without the need of adding additional
configuration options.

[1] 
http://patchwork.ozlabs.org/project/uboot/patch/20200525202429.2146-1-ag...@denx.de/

Signed-off-by: Walter Lozano 
---
  tools/dtoc/dtb_platdata.py | 32 
  1 file changed, 32 insertions(+)

I think dtoc should be able to parse the compatible strings as they
are today - e.g. see the tiny-dm stuff.

Yes, I agree. My idea is that dtoc parses compatible strings as they are
today but also in this new way. The reason for this is to allow dtoc to
generate the code to include the useful compatible strings. Of course,
this only makes sense if the idea of generating the compatible string
associated  code is accepted.

What do you think?

I think this is useful and better than using #ifdef in the source code
for this sort of thing. We need a way to specify the driver_data value
as well, right?

Yes, I agree, it is better than #ifdef and c/ould give us some extra
functionality.

What doe you mean by driver_data value? Are you referring to the data
field? like

static struct esdhc_soc_data usdhc_imx7d_data = {
.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
| ESDHC_FLAG_HS400,
};


Actually I was talking about the .data member in struct udevice_id.

So my example is correct, as usdhc_imx7d_data is the value for .data in
one case as shown bellow.

If that is the case, I was thinking in defining a constant when specific
compatible strings are enabled by dtoc, based in the above case

#ifdef FSL_ESDHC_IMX_V2
static struct esdhc_soc_data usdhc_imx7d_data = {
.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
| ESDHC_FLAG_HS400,
};
#endif

COMPATIBLE(FSL_ESDHC, "fsl,imx7d-usdhc", _imx7d_data, FSL_ESDHC_IMX_V2)

So when dtoc parses COMPATIBLE and determines that compatible
"fsl,imx7d-usdhc" should be added it also defines FSL_ESDHC_IMX_V2.

I think we can put that data in the dt-platdata.c file perhaps.

I thought the same at the beginning, but then I changed my mind, because

1- in order to work dt-platdata.c will need to include several different
.h, in this example, only for fsl_esdhc_imx to work, we will need to
include fsl_esdhc_imx.h where all the flags are defined.

Yes I hit that problem with the tiny-dm experiment and ended up adding
a macro to specify the header.

I haven't seen that. I will check it. Thanks.



Do you need FSL_ESDHC_IMX_V2? Is it just to avoid a warning about
usdhc_imx7d_data not being used? If so, we could use _maybe_unused

Well, it is not that I really need it, but I try to give the possibility
to add some #ifdef or similar based on compatible strings, the
usdhc_imx7d_data was just an example. A more interesting example could
be some code that makes sense only on specific "compatible string" cases
and using #ifdef or if would save some bytes in other cases.


2- it case we use #define to avoid having to include several different
.h probably the errors will be more difficult to catch/debug

Yes we would have to include the real header, not just copy bits out of it.

Yes, for that reason I feel it 

[PATCH v3 19/21] clk: at91: clk-generic: add driver compatible with ccf

2020-09-07 Thread Claudiu Beznea
Add clk-generic driver compatible with common clock framework.

Signed-off-by: Claudiu Beznea 
---
 drivers/clk/at91/Makefile  |   1 +
 drivers/clk/at91/clk-generic.c | 202 +
 drivers/clk/at91/pmc.h |   6 ++
 3 files changed, 209 insertions(+)
 create mode 100644 drivers/clk/at91/clk-generic.c

diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index b5529065b5c4..2cd840af3859 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -6,6 +6,7 @@ ifdef CONFIG_CLK_CCF
 obj-y += pmc.o sckc.o clk-main.o clk-master.o clk-programmable.o clk-system.o
 obj-y += clk-peripheral.o
 
+obj-$(CONFIG_AT91_GENERIC_CLK) += clk-generic.o
 obj-$(CONFIG_AT91_UTMI)+= clk-utmi.o
 obj-$(CONFIG_AT91_SAM9X60_PLL) += clk-sam9x60-pll.o
 else
diff --git a/drivers/clk/at91/clk-generic.c b/drivers/clk/at91/clk-generic.c
new file mode 100644
index ..87738b7b5bff
--- /dev/null
+++ b/drivers/clk/at91/clk-generic.c
@@ -0,0 +1,202 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Generic clock support for AT91 architectures.
+ *
+ * Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Claudiu Beznea 
+ *
+ * Based on drivers/clk/at91/clk-generated.c from Linux.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "pmc.h"
+
+#define UBOOT_DM_CLK_AT91_GCK  "at91-gck-clk"
+
+#define GENERATED_MAX_DIV  255
+
+struct clk_gck {
+   void __iomem *base;
+   const u32 *clk_mux_table;
+   const u32 *mux_table;
+   const struct clk_pcr_layout *layout;
+   struct clk_range range;
+   struct clk clk;
+   u32 num_parents;
+   u32 id;
+};
+
+#define to_clk_gck(_c) container_of(_c, struct clk_gck, clk)
+
+static int clk_gck_enable(struct clk *clk)
+{
+   struct clk_gck *gck = to_clk_gck(clk);
+
+   pmc_write(gck->base, gck->layout->offset,
+ (gck->id & gck->layout->pid_mask));
+   pmc_update_bits(gck->base, gck->layout->offset,
+   gck->layout->cmd | AT91_PMC_PCR_GCKEN,
+   gck->layout->cmd | AT91_PMC_PCR_GCKEN);
+
+   return 0;
+}
+
+static int clk_gck_disable(struct clk *clk)
+{
+   struct clk_gck *gck = to_clk_gck(clk);
+
+   pmc_write(gck->base, gck->layout->offset,
+ (gck->id & gck->layout->pid_mask));
+   pmc_update_bits(gck->base, gck->layout->offset,
+   gck->layout->cmd | AT91_PMC_PCR_GCKEN,
+   gck->layout->cmd);
+
+   return 0;
+}
+
+static int clk_gck_set_parent(struct clk *clk, struct clk *parent)
+{
+   struct clk_gck *gck = to_clk_gck(clk);
+   int index;
+
+   index = at91_clk_mux_val_to_index(gck->clk_mux_table, gck->num_parents,
+ parent->id);
+   if (index < 0)
+   return index;
+
+   index = at91_clk_mux_index_to_val(gck->mux_table, gck->num_parents,
+ index);
+   if (index < 0)
+   return index;
+
+   pmc_write(gck->base, gck->layout->offset,
+ (gck->id & gck->layout->pid_mask));
+   pmc_update_bits(gck->base, gck->layout->offset,
+   gck->layout->gckcss_mask | gck->layout->cmd,
+   (index << (ffs(gck->layout->gckcss_mask) - 1)) |
+   gck->layout->cmd);
+
+   return 0;
+}
+
+static ulong clk_gck_set_rate(struct clk *clk, ulong rate)
+{
+   struct clk_gck *gck = to_clk_gck(clk);
+   ulong parent_rate = clk_get_parent_rate(clk);
+   u32 div;
+
+   if (!rate || !parent_rate)
+   return 0;
+
+   if (gck->range.max && rate > gck->range.max)
+   return 0;
+
+   div = DIV_ROUND_CLOSEST(parent_rate, rate);
+   if (div > GENERATED_MAX_DIV + 1 || !div)
+   return 0;
+
+   pmc_write(gck->base, gck->layout->offset,
+ (gck->id & gck->layout->pid_mask));
+   pmc_update_bits(gck->base, gck->layout->offset,
+   AT91_PMC_PCR_GCKDIV_MASK | gck->layout->cmd,
+   ((div - 1) << (ffs(AT91_PMC_PCR_GCKDIV_MASK) - 1)) |
+   gck->layout->cmd);
+
+   return parent_rate / div;
+}
+
+static ulong clk_gck_get_rate(struct clk *clk)
+{
+   struct clk_gck *gck = to_clk_gck(clk);
+   ulong parent_rate = clk_get_parent_rate(clk);
+   u32 val, div;
+
+   if (!parent_rate)
+   return 0;
+
+   pmc_write(gck->base, gck->layout->offset,
+ (gck->id & gck->layout->pid_mask));
+   pmc_read(gck->base, gck->layout->offset, );
+
+   div = (val & AT91_PMC_PCR_GCKDIV_MASK) >>
+   (ffs(AT91_PMC_PCR_GCKDIV_MASK) - 1);
+
+   return parent_rate / (div + 1);
+}
+
+static const struct clk_ops gck_ops = {
+   .enable = clk_gck_enable,
+   .disable = clk_gck_disable,
+   .set_parent = 

[PATCH v3 20/21] clk: at91: pmc: add generic clock ops

2020-09-07 Thread Claudiu Beznea
Add generic clock ops to be used by every AT91 PMC driver
built on top of CCF.

Signed-off-by: Claudiu Beznea 
---
 drivers/clk/at91/pmc.c | 71 ++
 drivers/clk/at91/pmc.h |  2 ++
 2 files changed, 73 insertions(+)

diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index 29c6452497b7..660e23192149 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -5,8 +5,79 @@
  */
 
 #include 
+#include 
 #include 
 
+#include "pmc.h"
+
+static int at91_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
+{
+   if (args->args_count != 2) {
+   debug("AT91: clk: Invalid args_count: %d\n", args->args_count);
+   return -EINVAL;
+   }
+
+   clk->id = AT91_TO_CLK_ID(args->args[0], args->args[1]);
+
+   return 0;
+}
+
+static ulong at91_clk_get_rate(struct clk *clk)
+{
+   struct clk *c;
+   int ret;
+
+   ret = clk_get_by_id(clk->id, );
+   if (ret)
+   return ret;
+
+   return clk_get_rate(c);
+}
+
+static ulong at91_clk_set_rate(struct clk *clk, ulong rate)
+{
+   struct clk *c;
+   int ret;
+
+   ret = clk_get_by_id(clk->id, );
+   if (ret)
+   return ret;
+
+   return clk_set_rate(c, rate);
+}
+
+static int at91_clk_enable(struct clk *clk)
+{
+   struct clk *c;
+   int ret;
+
+   ret = clk_get_by_id(clk->id, );
+   if (ret)
+   return ret;
+
+   return clk_enable(c);
+}
+
+static int at91_clk_disable(struct clk *clk)
+{
+   struct clk *c;
+   int ret;
+
+   ret = clk_get_by_id(clk->id, );
+   if (ret)
+   return ret;
+
+   return clk_disable(c);
+}
+
+const struct clk_ops at91_clk_ops = {
+   .of_xlate   = at91_clk_of_xlate,
+   .set_rate   = at91_clk_set_rate,
+   .get_rate   = at91_clk_get_rate,
+   .enable = at91_clk_enable,
+   .disable= at91_clk_disable,
+};
+
 /**
  * pmc_read() - read content at address base + off into val
  *
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index 176855e7a0ed..a6a714fd220b 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -75,6 +75,8 @@ extern const struct clk_programmable_layout 
at91rm9200_programmable_layout;
 extern const struct clk_programmable_layout at91sam9g45_programmable_layout;
 extern const struct clk_programmable_layout at91sam9x5_programmable_layout;
 
+extern const struct clk_ops at91_clk_ops;
+
 struct clk *at91_clk_main_rc(void __iomem *reg, const char *name,
const char *parent_name);
 struct clk *at91_clk_main_osc(void __iomem *reg, const char *name,
-- 
2.7.4



[PATCH v3 18/21] clk: at91: clk-peripheral: add driver compatible with ccf

2020-09-07 Thread Claudiu Beznea
Add clk-peripheral compatible with common clock framework.

Signed-off-by: Claudiu Beznea 
---
 drivers/clk/at91/Makefile |   2 +
 drivers/clk/at91/clk-peripheral.c | 254 ++
 drivers/clk/at91/pmc.h|  16 +++
 3 files changed, 272 insertions(+)
 create mode 100644 drivers/clk/at91/clk-peripheral.c

diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index 1d59531e0c42..b5529065b5c4 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -4,6 +4,8 @@
 
 ifdef CONFIG_CLK_CCF
 obj-y += pmc.o sckc.o clk-main.o clk-master.o clk-programmable.o clk-system.o
+obj-y += clk-peripheral.o
+
 obj-$(CONFIG_AT91_UTMI)+= clk-utmi.o
 obj-$(CONFIG_AT91_SAM9X60_PLL) += clk-sam9x60-pll.o
 else
diff --git a/drivers/clk/at91/clk-peripheral.c 
b/drivers/clk/at91/clk-peripheral.c
new file mode 100644
index ..52cbc520cef4
--- /dev/null
+++ b/drivers/clk/at91/clk-peripheral.c
@@ -0,0 +1,254 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Peripheral clock support for AT91 architectures.
+ *
+ * Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Claudiu Beznea 
+ *
+ * Based on drivers/clk/at91/clk-peripheral.c from Linux.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "pmc.h"
+
+#define UBOOT_DM_CLK_AT91_PERIPH   "at91-periph-clk"
+#define UBOOT_DM_CLK_AT91_SAM9X5_PERIPH"at91-sam9x5-periph-clk"
+
+#define PERIPHERAL_ID_MIN  2
+#define PERIPHERAL_ID_MAX  31
+#define PERIPHERAL_MASK(id)(1 << ((id) & PERIPHERAL_ID_MAX))
+
+#define PERIPHERAL_MAX_SHIFT   3
+
+struct clk_peripheral {
+   void __iomem *base;
+   struct clk clk;
+   u32 id;
+};
+
+#define to_clk_peripheral(_c) container_of(_c, struct clk_peripheral, clk)
+
+struct clk_sam9x5_peripheral {
+   const struct clk_pcr_layout *layout;
+   void __iomem *base;
+   struct clk clk;
+   struct clk_range range;
+   u32 id;
+   u32 div;
+   bool auto_div;
+};
+
+#define to_clk_sam9x5_peripheral(_c) \
+   container_of(_c, struct clk_sam9x5_peripheral, clk)
+
+static int clk_peripheral_enable(struct clk *clk)
+{
+   struct clk_peripheral *periph = to_clk_peripheral(clk);
+   int offset = AT91_PMC_PCER;
+   u32 id = periph->id;
+
+   if (id < PERIPHERAL_ID_MIN)
+   return 0;
+   if (id > PERIPHERAL_ID_MAX)
+   offset = AT91_PMC_PCER1;
+   pmc_write(periph->base, offset, PERIPHERAL_MASK(id));
+
+   return 0;
+}
+
+static int clk_peripheral_disable(struct clk *clk)
+{
+   struct clk_peripheral *periph = to_clk_peripheral(clk);
+   int offset = AT91_PMC_PCDR;
+   u32 id = periph->id;
+
+   if (id < PERIPHERAL_ID_MIN)
+   return -EINVAL;
+
+   if (id > PERIPHERAL_ID_MAX)
+   offset = AT91_PMC_PCDR1;
+   pmc_write(periph->base, offset, PERIPHERAL_MASK(id));
+
+   return 0;
+}
+
+static const struct clk_ops peripheral_ops = {
+   .enable = clk_peripheral_enable,
+   .disable = clk_peripheral_disable,
+   .get_rate = clk_generic_get_rate,
+};
+
+struct clk *
+at91_clk_register_peripheral(void __iomem *base, const char *name,
+const char *parent_name, u32 id)
+{
+   struct clk_peripheral *periph;
+   struct clk *clk;
+   int ret;
+
+   if (!base || !name || !parent_name || id > PERIPHERAL_ID_MAX)
+   return ERR_PTR(-EINVAL);
+
+   periph = kzalloc(sizeof(*periph), GFP_KERNEL);
+   if (!periph)
+   return ERR_PTR(-ENOMEM);
+
+   periph->id = id;
+   periph->base = base;
+
+   clk = >clk;
+   clk->flags = CLK_GET_RATE_NOCACHE;
+   ret = clk_register(clk, UBOOT_DM_CLK_AT91_PERIPH, name, parent_name);
+   if (ret) {
+   kfree(periph);
+   clk = ERR_PTR(ret);
+   }
+
+   return clk;
+}
+
+U_BOOT_DRIVER(at91_periph_clk) = {
+   .name = UBOOT_DM_CLK_AT91_PERIPH,
+   .id = UCLASS_CLK,
+   .ops = _ops,
+   .flags = DM_FLAG_PRE_RELOC,
+};
+
+static int clk_sam9x5_peripheral_enable(struct clk *clk)
+{
+   struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(clk);
+
+   if (periph->id < PERIPHERAL_ID_MIN)
+   return 0;
+
+   pmc_write(periph->base, periph->layout->offset,
+ (periph->id & periph->layout->pid_mask));
+   pmc_update_bits(periph->base, periph->layout->offset,
+   periph->layout->cmd | AT91_PMC_PCR_EN,
+   periph->layout->cmd | AT91_PMC_PCR_EN);
+
+   return 0;
+}
+
+static int clk_sam9x5_peripheral_disable(struct clk *clk)
+{
+   struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(clk);
+
+   if (periph->id < PERIPHERAL_ID_MIN)
+   return -EINVAL;
+
+   pmc_write(periph->base, periph->layout->offset,
+ (periph->id & 

[PATCH v3 13/21] clk: at91: clk-master: add support for sama7g5

2020-09-07 Thread Claudiu Beznea
Add master clock (MCK1..MCK4) support for SAMA7G5. SAMA7G5's PMC has
multiple master clocks feeding different subsystems. One of them
feeds image subsystem and is changeable based on image subsystem
needs.

Signed-off-by: Claudiu Beznea 
---
 drivers/clk/at91/clk-master.c | 178 +-
 drivers/clk/at91/pmc.h|   5 ++
 2 files changed, 182 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c
index 1d388b6b2519..759df93697d2 100644
--- a/drivers/clk/at91/clk-master.c
+++ b/drivers/clk/at91/clk-master.c
@@ -19,12 +19,25 @@
 #include "pmc.h"
 
 #define UBOOT_DM_CLK_AT91_MASTER   "at91-master-clk"
+#define UBOOT_DM_CLK_AT91_SAMA7G5_MASTER   "at91-sama7g5-master-clk"
 
 #define MASTER_PRES_MASK   0x7
 #define MASTER_PRES_MAXMASTER_PRES_MASK
 #define MASTER_DIV_SHIFT   8
 #define MASTER_DIV_MASK0x3
 
+#define PMC_MCR0x30
+#define PMC_MCR_ID_MSK GENMASK(3, 0)
+#define PMC_MCR_CMDBIT(7)
+#define PMC_MCR_DIVGENMASK(10, 8)
+#define PMC_MCR_CSSGENMASK(20, 16)
+#define PMC_MCR_CSS_SHIFT  (16)
+#define PMC_MCR_EN BIT(28)
+
+#define PMC_MCR_ID(x)  ((x) & PMC_MCR_ID_MSK)
+
+#define MASTER_MAX_ID  4
+
 struct clk_master {
void __iomem *base;
const struct clk_master_layout *layout;
@@ -40,11 +53,12 @@ struct clk_master {
 
 static inline bool clk_master_ready(struct clk_master *master)
 {
+   unsigned int bit = master->id ? AT91_PMC_MCKXRDY : AT91_PMC_MCKRDY;
unsigned int status;
 
pmc_read(master->base, AT91_PMC_SR, );
 
-   return !!(status & AT91_PMC_MCKRDY);
+   return !!(status & bit);
 }
 
 static int clk_master_enable(struct clk *clk)
@@ -143,6 +157,168 @@ U_BOOT_DRIVER(at91_master_clk) = {
.flags = DM_FLAG_PRE_RELOC,
 };
 
+static int clk_sama7g5_master_set_parent(struct clk *clk, struct clk *parent)
+{
+   struct clk_master *master = to_clk_master(clk);
+   int index;
+
+   index = at91_clk_mux_val_to_index(master->clk_mux_table,
+ master->num_parents, parent->id);
+   if (index < 0)
+   return index;
+
+   index = at91_clk_mux_index_to_val(master->mux_table,
+ master->num_parents, index);
+   if (index < 0)
+   return index;
+
+   pmc_write(master->base, PMC_MCR, PMC_MCR_ID(master->id));
+   pmc_update_bits(master->base, PMC_MCR,
+   PMC_MCR_CSS | PMC_MCR_CMD | PMC_MCR_ID_MSK,
+   (index << PMC_MCR_CSS_SHIFT) | PMC_MCR_CMD |
+   PMC_MCR_ID(master->id));
+   return 0;
+}
+
+static int clk_sama7g5_master_enable(struct clk *clk)
+{
+   struct clk_master *master = to_clk_master(clk);
+
+   pmc_write(master->base, PMC_MCR, PMC_MCR_ID(master->id));
+   pmc_update_bits(master->base, PMC_MCR,
+   PMC_MCR_EN | PMC_MCR_CMD | PMC_MCR_ID_MSK,
+   PMC_MCR_EN | PMC_MCR_CMD | PMC_MCR_ID(master->id));
+
+   return 0;
+}
+
+static int clk_sama7g5_master_disable(struct clk *clk)
+{
+   struct clk_master *master = to_clk_master(clk);
+
+   pmc_write(master->base, PMC_MCR, master->id);
+   pmc_update_bits(master->base, PMC_MCR,
+   PMC_MCR_EN | PMC_MCR_CMD | PMC_MCR_ID_MSK,
+   PMC_MCR_CMD | PMC_MCR_ID(master->id));
+
+   return 0;
+}
+
+static ulong clk_sama7g5_master_set_rate(struct clk *clk, ulong rate)
+{
+   struct clk_master *master = to_clk_master(clk);
+   ulong parent_rate = clk_get_parent_rate(clk);
+   ulong div, rrate;
+
+   if (!parent_rate)
+   return 0;
+
+   div = DIV_ROUND_CLOSEST(parent_rate, rate);
+   if ((div > (1 << (MASTER_PRES_MAX - 1))) || (div & (div - 1))) {
+   return 0;
+   } else if (div == 3) {
+   rrate = DIV_ROUND_CLOSEST(parent_rate, MASTER_PRES_MAX);
+   div = MASTER_PRES_MAX;
+   } else {
+   rrate = DIV_ROUND_CLOSEST(parent_rate, div);
+   div = ffs(div) - 1;
+   }
+
+   pmc_write(master->base, PMC_MCR, master->id);
+   pmc_update_bits(master->base, PMC_MCR,
+   PMC_MCR_DIV | PMC_MCR_CMD | PMC_MCR_ID_MSK,
+   (div << MASTER_DIV_SHIFT) | PMC_MCR_CMD |
+   PMC_MCR_ID(master->id));
+
+   return rrate;
+}
+
+static ulong clk_sama7g5_master_get_rate(struct clk *clk)
+{
+   struct clk_master *master = to_clk_master(clk);
+   ulong parent_rate = clk_get_parent_rate(clk);
+   unsigned int val;
+   ulong div;
+
+   if (!parent_rate)
+   return 0;
+
+   pmc_write(master->base, PMC_MCR, master->id);
+   pmc_read(master->base, PMC_MCR, );
+
+   div = (val >> MASTER_DIV_SHIFT) & 

[PATCH v3 21/21] clk: at91: sama7g5: add clock support

2020-09-07 Thread Claudiu Beznea
Add clock support for SAMA7G5.

Signed-off-by: Claudiu Beznea 
---
 drivers/clk/at91/Makefile  |1 +
 drivers/clk/at91/sama7g5.c | 1401 
 2 files changed, 1402 insertions(+)
 create mode 100644 drivers/clk/at91/sama7g5.c

diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index 2cd840af3859..2453c38af1aa 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -9,6 +9,7 @@ obj-y += clk-peripheral.o
 obj-$(CONFIG_AT91_GENERIC_CLK) += clk-generic.o
 obj-$(CONFIG_AT91_UTMI)+= clk-utmi.o
 obj-$(CONFIG_AT91_SAM9X60_PLL) += clk-sam9x60-pll.o
+obj-$(CONFIG_SAMA7G5)  += sama7g5.o
 else
 obj-y += compat.o
 endif
diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c
new file mode 100644
index ..b96937673bed
--- /dev/null
+++ b/drivers/clk/at91/sama7g5.c
@@ -0,0 +1,1401 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * SAMA7G5 PMC clock support.
+ *
+ * Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Claudiu Beznea 
+ *
+ * Based on drivers/clk/at91/sama7g5.c from Linux.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "pmc.h"
+
+/**
+ * Clock identifiers to be used in conjunction with macros like
+ * AT91_TO_CLK_ID()
+ *
+ * @ID_MD_SLCK:TD slow clock identifier
+ * @ID_TD_SLCK:MD slow clock identifier
+ * @ID_MAIN_XTAL:  Main Xtal clock identifier
+ * @ID_MAIN_RC:Main RC clock identifier
+ * @ID_MAIN_RC_OSC:Main RC Oscillator clock identifier
+ * @ID_MAIN_OSC:   Main Oscillator clock identifier
+ * @ID_MAINCK: MAINCK clock identifier
+ * @ID_PLL_CPU_FRAC:   CPU PLL fractional clock identifier
+ * @ID_PLL_CPU_DIV:CPU PLL divider clock identifier
+ * @ID_PLL_SYS_FRAC:   SYS PLL fractional clock identifier
+ * @ID_PLL_SYS_DIV:SYS PLL divider clock identifier
+ * @ID_PLL_DDR_FRAC:   DDR PLL fractional clock identifier
+ * @ID_PLL_DDR_DIV:DDR PLL divider clock identifier
+ * @ID_PLL_IMG_FRAC:   IMC PLL fractional clock identifier
+ * @ID_PLL_IMG_DIV:IMG PLL divider clock identifier
+ * @ID_PLL_BAUD_FRAC:  Baud PLL fractional clock identifier
+ * @ID_PLL_BAUD_DIV:   Baud PLL divider clock identifier
+ * @ID_PLL_AUDIO_FRAC: Audio PLL fractional clock identifier
+ * @ID_PLL_AUDIO_DIVPMC:   Audio PLL PMC divider clock identifier
+ * @ID_PLL_AUDIO_DIVIO:Audio PLL IO divider clock identifier
+ * @ID_PLL_ETH_FRAC:   Ethernet PLL fractional clock identifier
+ * @ID_PLL_ETH_DIV:Ethernet PLL divider clock identifier
+
+ * @ID_MCK0:   MCK0 clock identifier
+ * @ID_MCK1:   MCK1 clock identifier
+ * @ID_MCK2:   MCK2 clock identifier
+ * @ID_MCK3:   MCK3 clock identifier
+ * @ID_MCK4:   MCK4 clock identifier
+
+ * @ID_UTMI:   UTMI clock identifier
+
+ * @ID_PROG0:  Programmable 0 clock identifier
+ * @ID_PROG1:  Programmable 1 clock identifier
+ * @ID_PROG2:  Programmable 2 clock identifier
+ * @ID_PROG3:  Programmable 3 clock identifier
+ * @ID_PROG4:  Programmable 4 clock identifier
+ * @ID_PROG5:  Programmable 5 clock identifier
+ * @ID_PROG6:  Programmable 6 clock identifier
+ * @ID_PROG7:  Programmable 7 clock identifier
+
+ * @ID_PCK0:   System clock 0 clock identifier
+ * @ID_PCK1:   System clock 1 clock identifier
+ * @ID_PCK2:   System clock 2 clock identifier
+ * @ID_PCK3:   System clock 3 clock identifier
+ * @ID_PCK4:   System clock 4 clock identifier
+ * @ID_PCK5:   System clock 5 clock identifier
+ * @ID_PCK6:   System clock 6 clock identifier
+ * @ID_PCK7:   System clock 7 clock identifier
+ */
+enum pmc_clk_ids {
+   ID_MD_SLCK  = 0,
+   ID_TD_SLCK  = 1,
+   ID_MAIN_XTAL= 2,
+   ID_MAIN_RC  = 3,
+   ID_MAIN_RC_OSC  = 4,
+   ID_MAIN_OSC = 5,
+   ID_MAINCK   = 6,
+
+   ID_PLL_CPU_FRAC = 7,
+   ID_PLL_CPU_DIV  = 8,
+   ID_PLL_SYS_FRAC = 9,
+   ID_PLL_SYS_DIV  = 10,
+   ID_PLL_DDR_FRAC = 11,
+   ID_PLL_DDR_DIV  = 12,
+   ID_PLL_IMG_FRAC = 13,
+   ID_PLL_IMG_DIV  = 14,
+   ID_PLL_BAUD_FRAC= 15,
+   ID_PLL_BAUD_DIV = 16,
+   ID_PLL_AUDIO_FRAC   = 17,
+   ID_PLL_AUDIO_DIVPMC = 18,
+   ID_PLL_AUDIO_DIVIO  = 19,
+   ID_PLL_ETH_FRAC = 20,
+   ID_PLL_ETH_DIV  = 21,

[PATCH v3 16/21] clk: at91: clk-programmable: add driver compatible with ccf

2020-09-07 Thread Claudiu Beznea
Add clk-programmable driver compatible with common clock framework.

Signed-off-by: Claudiu Beznea 
---
 drivers/clk/at91/Makefile   |   2 +-
 drivers/clk/at91/clk-programmable.c | 208 
 drivers/clk/at91/pmc.h  |  17 +++
 3 files changed, 226 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/at91/clk-programmable.c

diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index 9c38bda5e6b7..8951052eb0f3 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -3,7 +3,7 @@
 #
 
 ifdef CONFIG_CLK_CCF
-obj-y += pmc.o sckc.o clk-main.o clk-master.o
+obj-y += pmc.o sckc.o clk-main.o clk-master.o clk-programmable.o
 obj-$(CONFIG_AT91_UTMI)+= clk-utmi.o
 obj-$(CONFIG_AT91_SAM9X60_PLL) += clk-sam9x60-pll.o
 else
diff --git a/drivers/clk/at91/clk-programmable.c 
b/drivers/clk/at91/clk-programmable.c
new file mode 100644
index ..868de4b1774b
--- /dev/null
+++ b/drivers/clk/at91/clk-programmable.c
@@ -0,0 +1,208 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Programmable clock support for AT91 architectures.
+ *
+ * Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Claudiu Beznea 
+ *
+ * Based on drivers/clk/at91/clk-programmable.c from Linux.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "pmc.h"
+
+#define UBOOT_DM_CLK_AT91_PROG "at91-prog-clk"
+
+#define PROG_ID_MAX7
+
+#define PROG_STATUS_MASK(id)   (1 << ((id) + 8))
+#define PROG_PRES(_l, _p)  (((_p) >> (_l)->pres_shift) & (_l)->pres_mask)
+#define PROG_MAX_RM9200_CSS3
+
+struct clk_programmable {
+   void __iomem *base;
+   const u32 *clk_mux_table;
+   const u32 *mux_table;
+   const struct clk_programmable_layout *layout;
+   u32 num_parents;
+   struct clk clk;
+   u8 id;
+};
+
+#define to_clk_programmable(_c) container_of(_c, struct clk_programmable, clk)
+
+static ulong clk_programmable_get_rate(struct clk *clk)
+{
+   struct clk_programmable *prog = to_clk_programmable(clk);
+   const struct clk_programmable_layout *layout = prog->layout;
+   ulong rate, parent_rate = clk_get_parent_rate(clk);
+   unsigned int pckr;
+
+   pmc_read(prog->base, AT91_PMC_PCKR(prog->id), );
+
+   if (layout->is_pres_direct)
+   rate = parent_rate / (PROG_PRES(layout, pckr) + 1);
+   else
+   rate = parent_rate >> PROG_PRES(layout, pckr);
+
+   return rate;
+}
+
+static int clk_programmable_set_parent(struct clk *clk, struct clk *parent)
+{
+   struct clk_programmable *prog = to_clk_programmable(clk);
+   const struct clk_programmable_layout *layout = prog->layout;
+   unsigned int mask = layout->css_mask;
+   int index;
+
+   index = at91_clk_mux_val_to_index(prog->clk_mux_table,
+ prog->num_parents, parent->id);
+   if (index < 0)
+   return index;
+
+   index = at91_clk_mux_index_to_val(prog->mux_table, prog->num_parents,
+ index);
+   if (index < 0)
+   return index;
+
+   if (layout->have_slck_mck)
+   mask |= AT91_PMC_CSSMCK_MCK;
+
+   if (index > layout->css_mask) {
+   if (index > PROG_MAX_RM9200_CSS && !layout->have_slck_mck)
+   return -EINVAL;
+
+   index |= AT91_PMC_CSSMCK_MCK;
+   }
+
+   pmc_update_bits(prog->base, AT91_PMC_PCKR(prog->id), mask, index);
+
+   return 0;
+}
+
+static ulong clk_programmable_set_rate(struct clk *clk, ulong rate)
+{
+   struct clk_programmable *prog = to_clk_programmable(clk);
+   const struct clk_programmable_layout *layout = prog->layout;
+   ulong parent_rate = clk_get_parent_rate(clk);
+   ulong div = parent_rate / rate;
+   int shift = 0;
+
+   if (!parent_rate || !div)
+   return -EINVAL;
+
+   if (layout->is_pres_direct) {
+   shift = div - 1;
+
+   if (shift > layout->pres_mask)
+   return -EINVAL;
+   } else {
+   shift = fls(div) - 1;
+
+   if (div != (1 << shift))
+   return -EINVAL;
+
+   if (shift >= layout->pres_mask)
+   return -EINVAL;
+   }
+
+   pmc_update_bits(prog->base, AT91_PMC_PCKR(prog->id),
+   layout->pres_mask << layout->pres_shift,
+   shift << layout->pres_shift);
+
+   if (layout->is_pres_direct)
+   return (parent_rate / shift + 1);
+
+   return parent_rate >> shift;
+}
+
+static const struct clk_ops programmable_ops = {
+   .get_rate = clk_programmable_get_rate,
+   .set_parent = clk_programmable_set_parent,
+   .set_rate = clk_programmable_set_rate,
+};
+
+struct clk *at91_clk_register_programmable(void __iomem *base, const char 
*name,
+

[PATCH v3 17/21] clk: at91: clk-system: add driver compatible with ccf

2020-09-07 Thread Claudiu Beznea
Add clk-system driver compatible with common clock framework.

Signed-off-by: Claudiu Beznea 
---
 drivers/clk/at91/Makefile |   2 +-
 drivers/clk/at91/clk-system.c | 112 ++
 drivers/clk/at91/pmc.h|   3 ++
 3 files changed, 116 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/at91/clk-system.c

diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index 8951052eb0f3..1d59531e0c42 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -3,7 +3,7 @@
 #
 
 ifdef CONFIG_CLK_CCF
-obj-y += pmc.o sckc.o clk-main.o clk-master.o clk-programmable.o
+obj-y += pmc.o sckc.o clk-main.o clk-master.o clk-programmable.o clk-system.o
 obj-$(CONFIG_AT91_UTMI)+= clk-utmi.o
 obj-$(CONFIG_AT91_SAM9X60_PLL) += clk-sam9x60-pll.o
 else
diff --git a/drivers/clk/at91/clk-system.c b/drivers/clk/at91/clk-system.c
new file mode 100644
index ..82f79e74a190
--- /dev/null
+++ b/drivers/clk/at91/clk-system.c
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * System clock support for AT91 architectures.
+ *
+ * Copyright (C) Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Claudiu Beznea 
+ *
+ * Based on drivers/clk/at91/clk-system.c from Linux.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "pmc.h"
+
+#define UBOOT_DM_CLK_AT91_SYSTEM   "at91-system-clk"
+
+#define SYSTEM_MAX_ID  31
+
+struct clk_system {
+   void __iomem *base;
+   struct clk clk;
+   u8 id;
+};
+
+#define to_clk_system(_c) container_of(_c, struct clk_system, clk)
+
+static inline int is_pck(int id)
+{
+   return (id >= 8) && (id <= 15);
+}
+
+static inline bool clk_system_ready(void __iomem *base, int id)
+{
+   unsigned int status;
+
+   pmc_read(base, AT91_PMC_SR, );
+
+   return !!(status & (1 << id));
+}
+
+static int clk_system_enable(struct clk *clk)
+{
+   struct clk_system *sys = to_clk_system(clk);
+
+   pmc_write(sys->base, AT91_PMC_SCER, 1 << sys->id);
+
+   if (!is_pck(sys->id))
+   return 0;
+
+   while (!clk_system_ready(sys->base, sys->id)) {
+   debug("waiting for pck%u\n", sys->id);
+   cpu_relax();
+   }
+
+   return 0;
+}
+
+static int clk_system_disable(struct clk *clk)
+{
+   struct clk_system *sys = to_clk_system(clk);
+
+   pmc_write(sys->base, AT91_PMC_SCDR, 1 << sys->id);
+
+   return 0;
+}
+
+static const struct clk_ops system_ops = {
+   .enable = clk_system_enable,
+   .disable = clk_system_disable,
+   .get_rate = clk_generic_get_rate,
+};
+
+struct clk *at91_clk_register_system(void __iomem *base, const char *name,
+const char *parent_name, u8 id)
+{
+   struct clk_system *sys;
+   struct clk *clk;
+   int ret;
+
+   if (!base || !name || !parent_name || id > SYSTEM_MAX_ID)
+   return ERR_PTR(-EINVAL);
+
+   sys = kzalloc(sizeof(*sys), GFP_KERNEL);
+   if (!sys)
+   return ERR_PTR(-ENOMEM);
+
+   sys->id = id;
+   sys->base = base;
+
+   clk = >clk;
+   clk->flags = CLK_GET_RATE_NOCACHE;
+   ret = clk_register(clk, UBOOT_DM_CLK_AT91_SYSTEM, name, parent_name);
+   if (ret) {
+   kfree(sys);
+   clk = ERR_PTR(ret);
+   }
+
+   return clk;
+}
+
+U_BOOT_DRIVER(at91_system_clk) = {
+   .name = UBOOT_DM_CLK_AT91_SYSTEM,
+   .id = UCLASS_CLK,
+   .ops = _ops,
+   .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index a443b65257b9..c372f39fc9f6 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -108,6 +108,9 @@ at91_clk_register_programmable(void __iomem *base, const 
char *name,
const char * const *parent_names, u8 num_parents, u8 id,
const struct clk_programmable_layout *layout,
const u32 *clk_mux_table, const u32 *mux_table);
+struct clk *
+at91_clk_register_system(void __iomem *base, const char *name,
+   const char *parent_name, u8 id);
 
 int at91_clk_mux_val_to_index(const u32 *table, u32 num_parents, u32 val);
 int at91_clk_mux_index_to_val(const u32 *table, u32 num_parents, u32 index);
-- 
2.7.4



[PATCH v3 14/21] clk: at91: clk-utmi: add driver compatible with ccf

2020-09-07 Thread Claudiu Beznea
Add clk-utmi driver compatible with common clock framework.

Signed-off-by: Claudiu Beznea 
---
 drivers/clk/at91/Makefile   |   1 +
 drivers/clk/at91/clk-utmi.c | 165 
 drivers/clk/at91/pmc.h  |   3 +
 3 files changed, 169 insertions(+)
 create mode 100644 drivers/clk/at91/clk-utmi.c

diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index a4e397066e1e..9c38bda5e6b7 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -4,6 +4,7 @@
 
 ifdef CONFIG_CLK_CCF
 obj-y += pmc.o sckc.o clk-main.o clk-master.o
+obj-$(CONFIG_AT91_UTMI)+= clk-utmi.o
 obj-$(CONFIG_AT91_SAM9X60_PLL) += clk-sam9x60-pll.o
 else
 obj-y += compat.o
diff --git a/drivers/clk/at91/clk-utmi.c b/drivers/clk/at91/clk-utmi.c
new file mode 100644
index ..b60fd35b6b6a
--- /dev/null
+++ b/drivers/clk/at91/clk-utmi.c
@@ -0,0 +1,165 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * UTMI clock support for AT91 architectures.
+ *
+ * Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Claudiu Beznea 
+ *
+ * Based on drivers/clk/at91/clk-utmi.c from Linux.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "pmc.h"
+
+#define UBOOT_DM_CLK_AT91_UTMI "at91-utmi-clk"
+
+/*
+ * The purpose of this clock is to generate a 480 MHz signal. A different
+ * rate can't be configured.
+ */
+#define UTMI_RATE  48000
+
+struct clk_utmi {
+   void __iomem *base;
+   struct regmap *regmap_sfr;
+   struct clk clk;
+};
+
+#define to_clk_utmi(_clk) container_of(_clk, struct clk_utmi, clk)
+
+static inline bool clk_utmi_ready(struct regmap *regmap)
+{
+   unsigned int status;
+
+   pmc_read(regmap, AT91_PMC_SR, );
+
+   return !!(status & AT91_PMC_LOCKU);
+}
+
+static int clk_utmi_enable(struct clk *clk)
+{
+   struct clk_utmi *utmi = to_clk_utmi(clk);
+   unsigned int uckr = AT91_PMC_UPLLEN | AT91_PMC_UPLLCOUNT |
+   AT91_PMC_BIASEN;
+   unsigned int utmi_ref_clk_freq;
+   ulong parent_rate = clk_get_parent_rate(clk);
+
+   /*
+* If mainck rate is different from 12 MHz, we have to configure the
+* FREQ field of the SFR_UTMICKTRIM register to generate properly
+* the utmi clock.
+*/
+   switch (parent_rate) {
+   case 1200:
+   utmi_ref_clk_freq = 0;
+   break;
+   case 1600:
+   utmi_ref_clk_freq = 1;
+   break;
+   case 2400:
+   utmi_ref_clk_freq = 2;
+   break;
+   /*
+* Not supported on SAMA5D2 but it's not an issue since MAINCK
+* maximum value is 24 MHz.
+*/
+   case 4800:
+   utmi_ref_clk_freq = 3;
+   break;
+   default:
+   debug("UTMICK: unsupported mainck rate\n");
+   return -EINVAL;
+   }
+
+   if (utmi->regmap_sfr) {
+   regmap_update_bits(utmi->regmap_sfr, AT91_SFR_UTMICKTRIM,
+  AT91_UTMICKTRIM_FREQ, utmi_ref_clk_freq);
+   } else if (utmi_ref_clk_freq) {
+   debug("UTMICK: sfr node required\n");
+   return -EINVAL;
+   }
+
+   pmc_update_bits(utmi->base, AT91_CKGR_UCKR, uckr, uckr);
+
+   while (!clk_utmi_ready(utmi->base)) {
+   debug("waiting for utmi...\n");
+   cpu_relax();
+   }
+
+   return 0;
+}
+
+static int clk_utmi_disable(struct clk *clk)
+{
+   struct clk_utmi *utmi = to_clk_utmi(clk);
+
+   pmc_update_bits(utmi->base, AT91_CKGR_UCKR, AT91_PMC_UPLLEN, 0);
+
+   return 0;
+}
+
+static ulong clk_utmi_get_rate(struct clk *clk)
+{
+   /* UTMI clk rate is fixed. */
+   return UTMI_RATE;
+}
+
+static const struct clk_ops utmi_ops = {
+   .enable = clk_utmi_enable,
+   .disable = clk_utmi_disable,
+   .get_rate = clk_utmi_get_rate,
+};
+
+struct clk *at91_clk_register_utmi(void __iomem *base, struct udevice *dev,
+  const char *name, const char *parent_name)
+{
+   struct udevice *syscon;
+   struct clk_utmi *utmi;
+   struct clk *clk;
+   int ret;
+
+   if (!base || !dev || !name || !parent_name)
+   return ERR_PTR(-EINVAL);
+
+   ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev,
+  "regmap-sfr", );
+   if (ret)
+   return ERR_PTR(ret);
+
+   utmi = kzalloc(sizeof(*utmi), GFP_KERNEL);
+   if (!utmi)
+   return ERR_PTR(-ENOMEM);
+
+   utmi->base = base;
+   utmi->regmap_sfr = syscon_get_regmap(syscon);
+   if (!utmi->regmap_sfr) {
+   kfree(utmi);
+   return ERR_PTR(-ENODEV);
+   }
+
+   clk = >clk;
+   clk->flags = CLK_GET_RATE_NOCACHE;
+   ret = clk_register(clk, UBOOT_DM_CLK_AT91_UTMI, name, 

[PATCH v3 11/21] clk: at91: sam9x60-pll: add driver compatible with ccf

2020-09-07 Thread Claudiu Beznea
Add sam9x60-pll driver compatible with common clock framework.

Signed-off-by: Claudiu Beznea 
---
 drivers/clk/at91/Kconfig   |   7 +
 drivers/clk/at91/Makefile  |   1 +
 drivers/clk/at91/clk-sam9x60-pll.c | 442 +
 drivers/clk/at91/pmc.h |  36 +++
 4 files changed, 486 insertions(+)
 create mode 100644 drivers/clk/at91/clk-sam9x60-pll.c

diff --git a/drivers/clk/at91/Kconfig b/drivers/clk/at91/Kconfig
index 8d482a275239..4abc8026b4da 100644
--- a/drivers/clk/at91/Kconfig
+++ b/drivers/clk/at91/Kconfig
@@ -54,3 +54,10 @@ config AT91_GENERIC_CLK
  that may be different from the system clock. This second
  clock is the generic clock (GCLK) and is managed by
  the PMC via PMC_PCR register.
+
+config AT91_SAM9X60_PLL
+   bool "PLL support for SAM9X60 SoCs"
+   depends on CLK_AT91
+   help
+ This option is used to enable the AT91 SAM9X60's PLL clock
+ driver.
diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index 805f67677a9b..338582b88aee 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -4,6 +4,7 @@
 
 ifdef CONFIG_CLK_CCF
 obj-y += pmc.o sckc.o clk-main.o
+obj-$(CONFIG_AT91_SAM9X60_PLL) += clk-sam9x60-pll.o
 else
 obj-y += compat.o
 endif
diff --git a/drivers/clk/at91/clk-sam9x60-pll.c 
b/drivers/clk/at91/clk-sam9x60-pll.c
new file mode 100644
index ..1bfae5fd0165
--- /dev/null
+++ b/drivers/clk/at91/clk-sam9x60-pll.c
@@ -0,0 +1,442 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * SAM9X60's PLL clock support.
+ *
+ * Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Claudiu Beznea 
+ *
+ * Based on drivers/clk/at91/clk-sam9x60-pll.c from Linux.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "pmc.h"
+
+#define UBOOT_DM_CLK_AT91_SAM9X60_DIV_PLL  "at91-sam9x60-div-pll-clk"
+#define UBOOT_DM_CLK_AT91_SAM9X60_FRAC_PLL "at91-sam9x60-frac-pll-clk"
+
+#definePMC_PLL_CTRL0_DIV_MSK   GENMASK(7, 0)
+#definePMC_PLL_CTRL1_MUL_MSK   GENMASK(31, 24)
+#define PMC_PLL_CTRL1_FRACR_MSKGENMASK(21, 0)
+
+#define PLL_DIV_MAX(FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, UINT_MAX) + 1)
+#define UPLL_DIV   2
+#define PLL_MUL_MAX(FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, UINT_MAX) + 1)
+
+#define FCORE_MIN  (6)
+#define FCORE_MAX  (12)
+
+#define PLL_MAX_ID 7
+
+struct sam9x60_pll {
+   void __iomem *base;
+   const struct clk_pll_characteristics *characteristics;
+   const struct clk_pll_layout *layout;
+   struct clk clk;
+   u8 id;
+};
+
+#define to_sam9x60_pll(_clk)   container_of(_clk, struct sam9x60_pll, clk)
+
+static inline bool sam9x60_pll_ready(void __iomem *base, int id)
+{
+   unsigned int status;
+
+   pmc_read(base, AT91_PMC_PLL_ISR0, );
+
+   return !!(status & BIT(id));
+}
+
+static long sam9x60_frac_pll_compute_mul_frac(u32 *mul, u32 *frac, ulong rate,
+ ulong parent_rate)
+{
+   unsigned long tmprate, remainder;
+   unsigned long nmul = 0;
+   unsigned long nfrac = 0;
+
+   if (rate < FCORE_MIN || rate > FCORE_MAX)
+   return -ERANGE;
+
+   /*
+* Calculate the multiplier associated with the current
+* divider that provide the closest rate to the requested one.
+*/
+   nmul = mult_frac(rate, 1, parent_rate);
+   tmprate = mult_frac(parent_rate, nmul, 1);
+   remainder = rate - tmprate;
+
+   if (remainder) {
+   nfrac = DIV_ROUND_CLOSEST_ULL((u64)remainder * (1 << 22),
+ parent_rate);
+
+   tmprate += DIV_ROUND_CLOSEST_ULL((u64)nfrac * parent_rate,
+(1 << 22));
+   }
+
+   /* Check if resulted rate is valid.  */
+   if (tmprate < FCORE_MIN || tmprate > FCORE_MAX)
+   return -ERANGE;
+
+   *mul = nmul - 1;
+   *frac = nfrac;
+
+   return tmprate;
+}
+
+static ulong sam9x60_frac_pll_set_rate(struct clk *clk, ulong rate)
+{
+   struct sam9x60_pll *pll = to_sam9x60_pll(clk);
+   void __iomem *base = pll->base;
+   ulong parent_rate = clk_get_parent_rate(clk);
+   u32 nmul, cmul, nfrac, cfrac, val;
+   bool ready = sam9x60_pll_ready(base, pll->id);
+   long ret;
+
+   if (!parent_rate)
+   return 0;
+
+   ret = sam9x60_frac_pll_compute_mul_frac(, , rate,
+   parent_rate);
+   if (ret < 0)
+   return 0;
+
+   pmc_update_bits(base, AT91_PMC_PLL_UPDT, AT91_PMC_PLL_UPDT_ID_MSK,
+   pll->id);
+   pmc_read(base, AT91_PMC_PLL_CTRL1, );
+   cmul = (val & pll->layout->mul_mask) >> pll->layout->mul_shift;
+   cfrac = (val & 

[PATCH v3 15/21] clk: at91: clk-utmi: add support for sama7g5

2020-09-07 Thread Claudiu Beznea
Add UTMI support for SAMA7G5. SAMA7G5's UTMI control is done via
XTALF register. Values written at bits 2..0 in this register
correspond to the on board crystal oscillator frequency.

Signed-off-by: Claudiu Beznea 
---
 drivers/clk/at91/clk-utmi.c | 71 -
 drivers/clk/at91/pmc.h  |  3 ++
 2 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/at91/clk-utmi.c b/drivers/clk/at91/clk-utmi.c
index b60fd35b6b6a..7c8bcfb51dba 100644
--- a/drivers/clk/at91/clk-utmi.c
+++ b/drivers/clk/at91/clk-utmi.c
@@ -20,7 +20,8 @@
 
 #include "pmc.h"
 
-#define UBOOT_DM_CLK_AT91_UTMI "at91-utmi-clk"
+#define UBOOT_DM_CLK_AT91_UTMI "at91-utmi-clk"
+#define UBOOT_DM_CLK_AT91_SAMA7G5_UTMI "at91-sama7g5-utmi-clk"
 
 /*
  * The purpose of this clock is to generate a 480 MHz signal. A different
@@ -163,3 +164,71 @@ U_BOOT_DRIVER(at91_utmi_clk) = {
.ops = _ops,
.flags = DM_FLAG_PRE_RELOC,
 };
+
+static int clk_utmi_sama7g5_enable(struct clk *clk)
+{
+   struct clk_utmi *utmi = to_clk_utmi(clk);
+   ulong parent_rate = clk_get_parent_rate(clk);
+   unsigned int val;
+
+   switch (parent_rate) {
+   case 1600:
+   val = 0;
+   break;
+   case 2000:
+   val = 2;
+   break;
+   case 2400:
+   val = 3;
+   break;
+   case 3200:
+   val = 5;
+   break;
+   default:
+   debug("UTMICK: unsupported main_xtal rate\n");
+   return -EINVAL;
+   }
+
+   pmc_write(utmi->base, AT91_PMC_XTALF, val);
+
+   return 0;
+}
+
+static const struct clk_ops sama7g5_utmi_ops = {
+   .enable = clk_utmi_sama7g5_enable,
+   .get_rate = clk_utmi_get_rate,
+};
+
+struct clk *at91_clk_sama7g5_register_utmi(void __iomem *base,
+   const char *name, const char *parent_name)
+{
+   struct clk_utmi *utmi;
+   struct clk *clk;
+   int ret;
+
+   if (!base || !name || !parent_name)
+   return ERR_PTR(-EINVAL);
+
+   utmi = kzalloc(sizeof(*utmi), GFP_KERNEL);
+   if (!utmi)
+   return ERR_PTR(-ENOMEM);
+
+   utmi->base = base;
+
+   clk = >clk;
+   ret = clk_register(clk, UBOOT_DM_CLK_AT91_SAMA7G5_UTMI, name,
+  parent_name);
+   if (ret) {
+   kfree(utmi);
+   clk = ERR_PTR(ret);
+   }
+
+   return clk;
+}
+
+U_BOOT_DRIVER(at91_sama7g5_utmi_clk) = {
+   .name = UBOOT_DM_CLK_AT91_SAMA7G5_UTMI,
+   .id = UCLASS_CLK,
+   .ops = _utmi_ops,
+   .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index 264b36c7b4f5..d34005f6986c 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -88,6 +88,9 @@ at91_clk_sama7g5_register_master(void __iomem *base, const 
char *name,
 struct clk *
 at91_clk_register_utmi(void __iomem *base, struct udevice *dev,
const char *name, const char *parent_name);
+struct clk *
+at91_clk_sama7g5_register_utmi(void __iomem *base, const char *name,
+   const char *parent_name);
 
 int at91_clk_mux_val_to_index(const u32 *table, u32 num_parents, u32 val);
 int at91_clk_mux_index_to_val(const u32 *table, u32 num_parents, u32 index);
-- 
2.7.4



[PATCH v3 08/21] clk: at91: move clock code to compat.c

2020-09-07 Thread Claudiu Beznea
Move clock code to compat.c to allow switching to CCF
without mixing CCF code with non CCF code. This prepares the
field for next commits.

Signed-off-by: Claudiu Beznea 
---
 drivers/clk/at91/Makefile |   13 +-
 drivers/clk/at91/clk-generated.c  |  178 ---
 drivers/clk/at91/clk-h32mx.c  |   56 --
 drivers/clk/at91/clk-main.c   |   54 --
 drivers/clk/at91/clk-master.c |   33 --
 drivers/clk/at91/clk-peripheral.c |  113 
 drivers/clk/at91/clk-plla.c   |   54 --
 drivers/clk/at91/clk-plladiv.c|   85 ---
 drivers/clk/at91/clk-slow.c   |   36 --
 drivers/clk/at91/clk-system.c |  111 
 drivers/clk/at91/clk-usb.c|  147 --
 drivers/clk/at91/clk-utmi.c   |  142 -
 drivers/clk/at91/compat.c | 1023 +
 drivers/clk/at91/pmc.c|  116 +
 drivers/clk/at91/pmc.h|   13 +-
 drivers/clk/at91/sckc.c   |   19 -
 16 files changed, 1030 insertions(+), 1163 deletions(-)
 delete mode 100644 drivers/clk/at91/clk-generated.c
 delete mode 100644 drivers/clk/at91/clk-h32mx.c
 delete mode 100644 drivers/clk/at91/clk-main.c
 delete mode 100644 drivers/clk/at91/clk-master.c
 delete mode 100644 drivers/clk/at91/clk-peripheral.c
 delete mode 100644 drivers/clk/at91/clk-plla.c
 delete mode 100644 drivers/clk/at91/clk-plladiv.c
 delete mode 100644 drivers/clk/at91/clk-slow.c
 delete mode 100644 drivers/clk/at91/clk-system.c
 delete mode 100644 drivers/clk/at91/clk-usb.c
 delete mode 100644 drivers/clk/at91/clk-utmi.c
 create mode 100644 drivers/clk/at91/compat.c
 delete mode 100644 drivers/clk/at91/sckc.c

diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index 8c197ff949a8..e2413af40360 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -2,11 +2,8 @@
 # Makefile for at91 specific clk
 #
 
-obj-y += pmc.o sckc.o
-obj-y += clk-slow.o clk-main.o clk-plla.o clk-plladiv.o clk-master.o
-obj-y += clk-system.o clk-peripheral.o
-
-obj-$(CONFIG_AT91_UTMI)+= clk-utmi.o
-obj-$(CONFIG_AT91_USB_CLK) += clk-usb.o
-obj-$(CONFIG_AT91_H32MX)   += clk-h32mx.o
-obj-$(CONFIG_AT91_GENERIC_CLK) += clk-generated.o
+ifdef CONFIG_CLK_CCF
+obj-y += pmc.o
+else
+obj-y += compat.o
+endif
diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c
deleted file mode 100644
index c0610940c3be..
--- a/drivers/clk/at91/clk-generated.c
+++ /dev/null
@@ -1,178 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2016 Atmel Corporation
- *   Wenyou.Yang 
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include "pmc.h"
-
-DECLARE_GLOBAL_DATA_PTR;
-
-#define GENERATED_SOURCE_MAX   6
-#define GENERATED_MAX_DIV  255
-
-/**
- * generated_clk_bind() - for the generated clock driver
- * Recursively bind its children as clk devices.
- *
- * @return: 0 on success, or negative error code on failure
- */
-static int generated_clk_bind(struct udevice *dev)
-{
-   return at91_clk_sub_device_bind(dev, "generic-clk");
-}
-
-static const struct udevice_id generated_clk_match[] = {
-   { .compatible = "atmel,sama5d2-clk-generated" },
-   {}
-};
-
-U_BOOT_DRIVER(generated_clk) = {
-   .name = "generated-clk",
-   .id = UCLASS_MISC,
-   .of_match = generated_clk_match,
-   .bind = generated_clk_bind,
-};
-
-/*-*/
-
-struct generic_clk_priv {
-   u32 num_parents;
-};
-
-static ulong generic_clk_get_rate(struct clk *clk)
-{
-   struct pmc_platdata *plat = dev_get_platdata(clk->dev);
-   struct at91_pmc *pmc = plat->reg_base;
-   struct clk parent;
-   ulong clk_rate;
-   u32 tmp, gckdiv;
-   u8 clock_source, parent_index;
-   int ret;
-
-   writel(clk->id & AT91_PMC_PCR_PID_MASK, >pcr);
-   tmp = readl(>pcr);
-   clock_source = (tmp >> AT91_PMC_PCR_GCKCSS_OFFSET) &
-   AT91_PMC_PCR_GCKCSS_MASK;
-   gckdiv = (tmp >> AT91_PMC_PCR_GCKDIV_OFFSET) & AT91_PMC_PCR_GCKDIV_MASK;
-
-   parent_index = clock_source - 1;
-   ret = clk_get_by_index(dev_get_parent(clk->dev), parent_index, );
-   if (ret)
-   return 0;
-
-   clk_rate = clk_get_rate() / (gckdiv + 1);
-
-   clk_free();
-
-   return clk_rate;
-}
-
-static ulong generic_clk_set_rate(struct clk *clk, ulong rate)
-{
-   struct pmc_platdata *plat = dev_get_platdata(clk->dev);
-   struct at91_pmc *pmc = plat->reg_base;
-   struct generic_clk_priv *priv = dev_get_priv(clk->dev);
-   struct clk parent, best_parent;
-   ulong tmp_rate, best_rate = rate, parent_rate;
-   int tmp_diff, best_diff = -1;
-   u32 div, best_div = 0;
-   u8 best_parent_index, best_clock_source = 0;
-   u8 i;
-   u32 tmp;
-   int ret;
-
-   for (i = 0; i < priv->num_parents; i++) {
-   ret = 

[PATCH v3 10/21] clk: at91: clk-main: add driver compatible with ccf

2020-09-07 Thread Claudiu Beznea
Add clk-main driver compatible with common clock framework.

Signed-off-by: Claudiu Beznea 
---
 drivers/clk/at91/Makefile   |   2 +-
 drivers/clk/at91/clk-main.c | 387 
 drivers/clk/at91/pmc.h  |  10 ++
 3 files changed, 398 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/at91/clk-main.c

diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index 7083ce2890d6..805f67677a9b 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -3,7 +3,7 @@
 #
 
 ifdef CONFIG_CLK_CCF
-obj-y += pmc.o sckc.o
+obj-y += pmc.o sckc.o clk-main.o
 else
 obj-y += compat.o
 endif
diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c
new file mode 100644
index ..b52d926f3390
--- /dev/null
+++ b/drivers/clk/at91/clk-main.c
@@ -0,0 +1,387 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Main clock support for AT91 architectures.
+ *
+ * Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Claudiu Beznea 
+ *
+ * Based on drivers/clk/at91/clk-main.c from Linux.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "pmc.h"
+
+#define UBOOT_DM_CLK_AT91_MAIN_RC  "at91-main-rc-clk"
+#define UBOOT_DM_CLK_AT91_MAIN_OSC "at91-main-osc-clk"
+#define UBOOT_DM_CLK_AT91_RM9200_MAIN  "at91-rm9200-main-clk"
+#define UBOOT_DM_CLK_AT91_SAM9X5_MAIN  "at91-sam9x5-main-clk"
+
+#define MOR_KEY_MASK   GENMASK(23, 16)
+#define USEC_PER_SEC   100UL
+#define SLOW_CLOCK_FREQ32768
+
+#define clk_main_parent_select(s)  (((s) & \
+   (AT91_PMC_MOSCEN | \
+   AT91_PMC_OSCBYPASS)) ? 1 : 0)
+
+struct clk_main_rc {
+   void __iomem*reg;
+   struct clk  clk;
+};
+
+#define to_clk_main_rc(_clk) container_of(_clk, struct clk_main_rc, clk)
+
+struct clk_main_osc {
+   void __iomem*reg;
+   struct clk  clk;
+};
+
+#define to_clk_main_osc(_clk) container_of(_clk, struct clk_main_osc, clk)
+
+struct clk_main {
+   void __iomem*reg;
+   const unsigned int  *clk_mux_table;
+   const char * const  *parent_names;
+   unsigned intnum_parents;
+   int type;
+   struct clk  clk;
+};
+
+#define to_clk_main(_clk) container_of(_clk, struct clk_main, clk)
+
+static int main_rc_enable(struct clk *clk)
+{
+   struct clk_main_rc *main_rc = to_clk_main_rc(clk);
+   void __iomem *reg = main_rc->reg;
+   unsigned int val;
+
+   pmc_read(reg, AT91_CKGR_MOR, );
+
+   if (!(val & AT91_PMC_MOSCRCEN)) {
+   pmc_update_bits(reg, AT91_CKGR_MOR,
+   MOR_KEY_MASK | AT91_PMC_MOSCRCEN,
+   AT91_PMC_KEY | AT91_PMC_MOSCRCEN);
+   }
+
+   pmc_read(reg, AT91_PMC_SR, );
+   while (!(val & AT91_PMC_MOSCRCS)) {
+   pmc_read(reg, AT91_PMC_SR, );
+   debug("waiting for main rc...\n");
+   cpu_relax();
+   }
+
+   return 0;
+}
+
+static int main_rc_disable(struct clk *clk)
+{
+   struct clk_main_rc *main_rc = to_clk_main_rc(clk);
+   struct reg *reg = main_rc->reg;
+   unsigned int val;
+
+   pmc_read(reg, AT91_CKGR_MOR, );
+
+   if (!(val & AT91_PMC_MOSCRCEN))
+   return 0;
+
+   pmc_update_bits(reg, AT91_CKGR_MOR, MOR_KEY_MASK | AT91_PMC_MOSCRCEN,
+   AT91_PMC_KEY);
+
+   return 0;
+}
+
+static const struct clk_ops main_rc_clk_ops = {
+   .enable = main_rc_enable,
+   .disable = main_rc_disable,
+   .get_rate = clk_generic_get_rate,
+};
+
+struct clk *at91_clk_main_rc(void __iomem *reg, const char *name,
+const char *parent_name)
+{
+   struct clk_main_rc *main_rc;
+   struct clk *clk;
+   int ret;
+
+   if (!reg || !name || !parent_name)
+   return ERR_PTR(-EINVAL);
+
+   main_rc = kzalloc(sizeof(*main_rc), GFP_KERNEL);
+   if (!main_rc)
+   return ERR_PTR(-ENOMEM);
+
+   main_rc->reg = reg;
+   clk = _rc->clk;
+
+   ret = clk_register(clk, UBOOT_DM_CLK_AT91_MAIN_RC, name,
+  parent_name);
+   if (ret) {
+   kfree(main_rc);
+   clk = ERR_PTR(ret);
+   }
+
+   return clk;
+}
+
+U_BOOT_DRIVER(at91_main_rc_clk) = {
+   .name = UBOOT_DM_CLK_AT91_MAIN_RC,
+   .id = UCLASS_CLK,
+   .ops = _rc_clk_ops,
+   .flags = DM_FLAG_PRE_RELOC,
+};
+
+static int clk_main_osc_enable(struct clk *clk)
+{
+   struct clk_main_osc *main = to_clk_main_osc(clk);
+   void __iomem *reg = main->reg;
+   unsigned int val;
+
+   pmc_read(reg, AT91_CKGR_MOR, );
+   val &= ~MOR_KEY_MASK;
+
+   if (val & AT91_PMC_OSCBYPASS)
+   return 0;
+
+   if (!(val & 

[PATCH v3 12/21] clk: at91: clk-master: add driver compatible with ccf

2020-09-07 Thread Claudiu Beznea
Add clk-master driver compatible with common clock framework.

Signed-off-by: Claudiu Beznea 
---
 drivers/clk/at91/Makefile |   2 +-
 drivers/clk/at91/clk-master.c | 156 ++
 drivers/clk/at91/pmc.h|  21 ++
 3 files changed, 178 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/at91/clk-master.c

diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index 338582b88aee..a4e397066e1e 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -3,7 +3,7 @@
 #
 
 ifdef CONFIG_CLK_CCF
-obj-y += pmc.o sckc.o clk-main.o
+obj-y += pmc.o sckc.o clk-main.o clk-master.o
 obj-$(CONFIG_AT91_SAM9X60_PLL) += clk-sam9x60-pll.o
 else
 obj-y += compat.o
diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c
new file mode 100644
index ..1d388b6b2519
--- /dev/null
+++ b/drivers/clk/at91/clk-master.c
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Master clock support for AT91 architectures.
+ *
+ * Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Claudiu Beznea 
+ *
+ * Based on drivers/clk/at91/clk-master.c from Linux.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "pmc.h"
+
+#define UBOOT_DM_CLK_AT91_MASTER   "at91-master-clk"
+
+#define MASTER_PRES_MASK   0x7
+#define MASTER_PRES_MAXMASTER_PRES_MASK
+#define MASTER_DIV_SHIFT   8
+#define MASTER_DIV_MASK0x3
+
+struct clk_master {
+   void __iomem *base;
+   const struct clk_master_layout *layout;
+   const struct clk_master_characteristics *characteristics;
+   const u32 *mux_table;
+   const u32 *clk_mux_table;
+   u32 num_parents;
+   struct clk clk;
+   u8 id;
+};
+
+#define to_clk_master(_clk) container_of(_clk, struct clk_master, clk)
+
+static inline bool clk_master_ready(struct clk_master *master)
+{
+   unsigned int status;
+
+   pmc_read(master->base, AT91_PMC_SR, );
+
+   return !!(status & AT91_PMC_MCKRDY);
+}
+
+static int clk_master_enable(struct clk *clk)
+{
+   struct clk_master *master = to_clk_master(clk);
+
+   while (!clk_master_ready(master)) {
+   debug("waiting for mck %d\n", master->id);
+   cpu_relax();
+   }
+
+   return 0;
+}
+
+static ulong clk_master_get_rate(struct clk *clk)
+{
+   struct clk_master *master = to_clk_master(clk);
+   const struct clk_master_layout *layout = master->layout;
+   const struct clk_master_characteristics *characteristics =
+   master->characteristics;
+   ulong rate = clk_get_parent_rate(clk);
+   unsigned int mckr;
+   u8 pres, div;
+
+   if (!rate)
+   return 0;
+
+   pmc_read(master->base, master->layout->offset, );
+   mckr &= layout->mask;
+
+   pres = (mckr >> layout->pres_shift) & MASTER_PRES_MASK;
+   div = (mckr >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK;
+
+   if (characteristics->have_div3_pres && pres == MASTER_PRES_MAX)
+   rate /= 3;
+   else
+   rate >>= pres;
+
+   rate /= characteristics->divisors[div];
+
+   if (rate < characteristics->output.min)
+   pr_warn("master clk is underclocked");
+   else if (rate > characteristics->output.max)
+   pr_warn("master clk is overclocked");
+
+   return rate;
+}
+
+static const struct clk_ops master_ops = {
+   .enable = clk_master_enable,
+   .get_rate = clk_master_get_rate,
+};
+
+struct clk *at91_clk_register_master(void __iomem *base,
+   const char *name, const char * const *parent_names,
+   int num_parents, const struct clk_master_layout *layout,
+   const struct clk_master_characteristics *characteristics,
+   const u32 *mux_table)
+{
+   struct clk_master *master;
+   struct clk *clk;
+   unsigned int val;
+   int ret;
+
+   if (!base || !name || !num_parents || !parent_names ||
+   !layout || !characteristics || !mux_table)
+   return ERR_PTR(-EINVAL);
+
+   master = kzalloc(sizeof(*master), GFP_KERNEL);
+   if (!master)
+   return ERR_PTR(-ENOMEM);
+
+   master->layout = layout;
+   master->characteristics = characteristics;
+   master->base = base;
+   master->num_parents = num_parents;
+   master->mux_table = mux_table;
+
+   pmc_read(master->base, master->layout->offset, );
+   clk = >clk;
+   clk->flags = CLK_GET_RATE_NOCACHE | CLK_IS_CRITICAL;
+   ret = clk_register(clk, UBOOT_DM_CLK_AT91_MASTER, name,
+  parent_names[val & AT91_PMC_CSS]);
+   if (ret) {
+   kfree(master);
+   clk = ERR_PTR(ret);
+   }
+
+   return clk;
+}
+
+U_BOOT_DRIVER(at91_master_clk) = {
+   .name = UBOOT_DM_CLK_AT91_MASTER,
+   .id = UCLASS_CLK,
+

[PATCH v3 07/21] clk: at91: pmc: add helpers for clock drivers

2020-09-07 Thread Claudiu Beznea
Add helper for clock drivers. These will be used by following
commits in the process of switching AT91 clock drivers to CCF.

Signed-off-by: Claudiu Beznea 
---
 drivers/clk/at91/pmc.c | 91 ++
 drivers/clk/at91/pmc.h | 13 
 2 files changed, 104 insertions(+)

diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index ca90abef2d53..e403baea0efd 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -120,3 +120,94 @@ int at91_clk_probe(struct udevice *dev)
 
return 0;
 }
+
+/**
+ * pmc_read() - read content at address base + off into val
+ *
+ * @base: base address
+ * @off: offset to read from
+ * @val: where the content of base + off is stored
+ *
+ * @return: void
+ */
+void pmc_read(void __iomem *base, unsigned int off, unsigned int *val)
+{
+   *val = readl(base + off);
+}
+
+/**
+ * pmc_write() - write content of val at address base + off
+ *
+ * @base: base address
+ * @off: offset to write to
+ * @val: content to be written at base + off
+ *
+ * @return: void
+ */
+void pmc_write(void __iomem *base, unsigned int off, unsigned int val)
+{
+   writel(val, base + off);
+}
+
+/**
+ * pmc_update_bits() - update a set of bits at address base + off
+ *
+ * @base: base address
+ * @off: offset to be updated
+ * @mask: mask of bits to be updated
+ * @bits: the new value to be updated
+ *
+ * @return: void
+ */
+void pmc_update_bits(void __iomem *base, unsigned int off,
+unsigned int mask, unsigned int bits)
+{
+   unsigned int tmp;
+
+   tmp = readl(base + off);
+   tmp &= ~mask;
+   writel(tmp | (bits & mask), base + off);
+}
+
+/**
+ * at91_clk_mux_val_to_index() - get parent index in mux table
+ *
+ * @table: clock mux table
+ * @num_parents: clock number of parents
+ * @val: clock id who's mux index should be retrieved
+ *
+ * @return: clock index in mux table or a negative error number in case of
+ * failure
+ */
+int at91_clk_mux_val_to_index(const u32 *table, u32 num_parents, u32 val)
+{
+   int i;
+
+   if (!table || !num_parents)
+   return -EINVAL;
+
+   for (i = 0; i < num_parents; i++) {
+   if (table[i] == val)
+   return i;
+   }
+
+   return -EINVAL;
+}
+
+/**
+ * at91_clk_mux_index_to_val() - get parent ID corresponding to an entry in
+ * clock's mux table
+ *
+ * @table: clock's mux table
+ * @num_parents: clock's number of parents
+ * @index: index in mux table which clock's ID should be retrieved
+ *
+ * @return: clock ID or a negative error number in case of failure
+ */
+int at91_clk_mux_index_to_val(const u32 *table, u32 num_parents, u32 index)
+{
+   if (!table || !num_parents || index < 0 || index > num_parents)
+   return -EINVAL;
+
+   return table[index];
+}
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index 517ba1d6b452..b1ab0a95c855 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -8,6 +8,12 @@
 #define __AT91_PMC_H__
 
 #include 
+#include 
+#include 
+
+/* Keep a range of 256 available clocks for every clock type. */
+#define AT91_TO_CLK_ID(_t, _i) (((_t) << 8) | ((_i) & 0xff))
+#define AT91_CLK_ID_TO_DID(_i) ((_i) & 0xff)
 
 struct pmc_platdata {
struct at91_pmc *reg_base;
@@ -20,4 +26,11 @@ int at91_clk_sub_device_bind(struct udevice *dev, const char 
*drv_name);
 int at91_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args);
 int at91_clk_probe(struct udevice *dev);
 
+int at91_clk_mux_val_to_index(const u32 *table, u32 num_parents, u32 val);
+int at91_clk_mux_index_to_val(const u32 *table, u32 num_parents, u32 index);
+
+void pmc_read(void __iomem *base, unsigned int off, unsigned int *val);
+void pmc_write(void __iomem *base, unsigned int off, unsigned int val);
+void pmc_update_bits(void __iomem *base, unsigned int off, unsigned int mask,
+   unsigned int bits);
 #endif
-- 
2.7.4



[PATCH v3 09/21] clk: at91: sckc: add driver compatible with ccf

2020-09-07 Thread Claudiu Beznea
Add sckc driver compatible with common clock framework. Driver
implements slow clock support for SAM9X60 compatible IPs (in this
list it is also present SAMA7G5's slow clock IP).

Signed-off-by: Claudiu Beznea 
---
 drivers/clk/at91/Makefile |   2 +-
 drivers/clk/at91/sckc.c   | 172 ++
 2 files changed, 173 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/at91/sckc.c

diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index e2413af40360..7083ce2890d6 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -3,7 +3,7 @@
 #
 
 ifdef CONFIG_CLK_CCF
-obj-y += pmc.o
+obj-y += pmc.o sckc.o
 else
 obj-y += compat.o
 endif
diff --git a/drivers/clk/at91/sckc.c b/drivers/clk/at91/sckc.c
new file mode 100644
index ..dd62dc5510e4
--- /dev/null
+++ b/drivers/clk/at91/sckc.c
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Slow clock support for AT91 architectures.
+ *
+ * Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Claudiu Beznea 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "pmc.h"
+
+#define UBOOT_DM_CLK_AT91_SAM9X60_TD_SLCK  "at91-sam9x60-td-slck"
+#define UBOOT_DM_CLK_AT91_SCKC "at91-sckc"
+
+#define AT91_OSC_SEL   BIT(24)
+#define AT91_OSC_SEL_SHIFT (24)
+
+struct sam9x60_sckc {
+   void __iomem *reg;
+   const char **parent_names;
+   unsigned int num_parents;
+   struct clk clk;
+};
+
+#define to_sam9x60_sckc(c) container_of(c, struct sam9x60_sckc, clk)
+
+static int sam9x60_sckc_of_xlate(struct clk *clk,
+struct ofnode_phandle_args *args)
+{
+   if (args->args_count != 1) {
+   debug("AT91: SCKC: Invalid args_count: %d\n", args->args_count);
+   return -EINVAL;
+   }
+
+   clk->id = AT91_TO_CLK_ID(PMC_TYPE_SLOW, args->args[0]);
+
+   return 0;
+}
+
+static const struct clk_ops sam9x60_sckc_ops = {
+   .of_xlate = sam9x60_sckc_of_xlate,
+   .get_rate = clk_generic_get_rate,
+};
+
+static int sam9x60_td_slck_set_parent(struct clk *clk, struct clk *parent)
+{
+   struct sam9x60_sckc *sckc = to_sam9x60_sckc(clk);
+   u32 i;
+
+   for (i = 0; i < sckc->num_parents; i++) {
+   if (!strcmp(parent->dev->name, sckc->parent_names[i]))
+   break;
+   }
+   if (i == sckc->num_parents)
+   return -EINVAL;
+
+   pmc_update_bits(sckc->reg, 0, AT91_OSC_SEL, (i << AT91_OSC_SEL_SHIFT));
+
+   return 0;
+}
+
+static const struct clk_ops sam9x60_td_slck_ops = {
+   .get_rate = clk_generic_get_rate,
+   .set_parent = sam9x60_td_slck_set_parent,
+};
+
+static struct clk *at91_sam9x60_clk_register_td_slck(struct sam9x60_sckc *sckc,
+   const char *name, const char * const *parent_names,
+   int num_parents)
+{
+   struct clk *clk;
+   int ret = -ENOMEM;
+   u32 val, i;
+
+   if (!sckc || !name || !parent_names || num_parents != 2)
+   return ERR_PTR(-EINVAL);
+
+   sckc->parent_names = kzalloc(sizeof(*sckc->parent_names) * num_parents,
+GFP_KERNEL);
+   if (!sckc->parent_names)
+   return ERR_PTR(ret);
+
+   for (i = 0; i < num_parents; i++) {
+   sckc->parent_names[i] = kmemdup(parent_names[i],
+   strlen(parent_names[i]) + 1, GFP_KERNEL);
+   if (!sckc->parent_names[i])
+   goto free;
+   }
+   sckc->num_parents = num_parents;
+
+   pmc_read(sckc->reg, 0, );
+   val = (val & AT91_OSC_SEL) >> AT91_OSC_SEL_SHIFT;
+
+   clk = >clk;
+   ret = clk_register(clk, UBOOT_DM_CLK_AT91_SAM9X60_TD_SLCK, name,
+  parent_names[val]);
+   if (ret)
+   goto free;
+
+   return clk;
+
+free:
+   for (; i >= 0; i--)
+   kfree(sckc->parent_names[i]);
+   kfree(sckc->parent_names);
+
+   return ERR_PTR(ret);
+}
+
+U_BOOT_DRIVER(at91_sam9x60_td_slck) = {
+   .name = UBOOT_DM_CLK_AT91_SAM9X60_TD_SLCK,
+   .id = UCLASS_CLK,
+   .ops = _td_slck_ops,
+   .flags = DM_FLAG_PRE_RELOC,
+};
+
+static int at91_sam9x60_sckc_probe(struct udevice *dev)
+{
+   struct sam9x60_sckc *sckc = dev_get_priv(dev);
+   void __iomem *base = (void *)devfdt_get_addr(dev);
+   const char *slow_rc_osc, *slow_osc;
+   const char *parents[2];
+   struct clk *clk, c;
+   int ret;
+
+   ret = clk_get_by_index(dev, 0, );
+   if (ret)
+   return ret;
+   slow_rc_osc = clk_hw_get_name();
+
+   ret = clk_get_by_index(dev, 1, );
+   if (ret)
+   return ret;
+   slow_osc = clk_hw_get_name();
+
+   clk = clk_register_fixed_factor(NULL, "md_slck", slow_rc_osc, 0, 1, 1);
+   if (IS_ERR(clk))
+   return PTR_ERR(clk);
+   

[PATCH v3 06/21] clk: at91: add pre-requisite headers for AT91 clock architecture

2020-09-07 Thread Claudiu Beznea
Add pre-requisite headers for AT91 clock architecture. These
are based on already present files on Linux and will be used
by following commits for AT91 CCF clock drivers.

Signed-off-by: Claudiu Beznea 
---
 include/dt-bindings/clk/at91.h |  22 
 include/linux/clk/at91_pmc.h   | 247 +
 2 files changed, 269 insertions(+)
 create mode 100644 include/dt-bindings/clk/at91.h
 create mode 100644 include/linux/clk/at91_pmc.h

diff --git a/include/dt-bindings/clk/at91.h b/include/dt-bindings/clk/at91.h
new file mode 100644
index ..e30756b2804a
--- /dev/null
+++ b/include/dt-bindings/clk/at91.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * This header provides constants for AT91 pmc status.
+ * The constants defined in this header are being used in dts and PMC code.
+ *
+ * Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Claudiu Beznea 
+ *
+ * Based on include/dt-bindings/clock/at91.h on Linux.
+ */
+
+#ifndef _DT_BINDINGS_CLK_AT91_H
+#define _DT_BINDINGS_CLK_AT91_H
+
+#define PMC_TYPE_CORE  1
+#define PMC_TYPE_SYSTEM2
+#define PMC_TYPE_PERIPHERAL3
+#define PMC_TYPE_GCK   4
+#define PMC_TYPE_SLOW  5
+
+#endif
diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h
new file mode 100644
index ..ee39e72e2b39
--- /dev/null
+++ b/include/linux/clk/at91_pmc.h
@@ -0,0 +1,247 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Power Management Controller (PMC) - System peripherals registers.
+ *
+ * Copyright (C) 2005 Ivan Kokshaysky
+ * Copyright (C) SAN People
+ *
+ * Based on AT91RM9200 datasheet revision E.
+ * Based on include/linux/clk/at91_pmc.h on Linux.
+ */
+
+#ifndef AT91_PMC_H_
+#define AT91_PMC_H_
+
+#define AT91_PMC_V1(1) /* PMC version 1 */
+#define AT91_PMC_V2(2) /* PMC version 2 
[SAM9X60] */
+
+#defineAT91_PMC_SCER   0x00/* System Clock 
Enable Register */
+#defineAT91_PMC_SCDR   0x04/* System Clock 
Disable Register */
+
+#defineAT91_PMC_SCSR   0x08/* System Clock 
Status Register */
+#defineAT91_PMC_PCK(1 <<  0)   /* 
Processor Clock */
+#defineAT91RM9200_PMC_UDP  (1 <<  1)   /* USB 
Devcice Port Clock [AT91RM9200 only] */
+#defineAT91RM9200_PMC_MCKUDP   (1 <<  2)   /* USB 
Device Port Master Clock Automatic Disable on Suspend [AT91RM9200 only] */
+#defineAT91RM9200_PMC_UHP  (1 <<  4)   /* USB 
Host Port Clock [AT91RM9200 only] */
+#defineAT91SAM926x_PMC_UHP (1 <<  6)   /* USB 
Host Port Clock [AT91SAM926x only] */
+#defineAT91SAM926x_PMC_UDP (1 <<  7)   /* USB 
Devcice Port Clock [AT91SAM926x only] */
+#defineAT91_PMC_PCK0   (1 <<  8)   /* 
Programmable Clock 0 */
+#defineAT91_PMC_PCK1   (1 <<  9)   /* 
Programmable Clock 1 */
+#defineAT91_PMC_PCK2   (1 << 10)   /* 
Programmable Clock 2 */
+#defineAT91_PMC_PCK3   (1 << 11)   /* 
Programmable Clock 3 */
+#defineAT91_PMC_PCK4   (1 << 12)   /* 
Programmable Clock 4 [AT572D940HF only] */
+#defineAT91_PMC_HCK0   (1 << 16)   /* AHB 
Clock (USB host) [AT91SAM9261 only] */
+#defineAT91_PMC_HCK1   (1 << 17)   /* AHB 
Clock (LCD) [AT91SAM9261 only] */
+
+#define AT91_PMC_PLL_CTRL0 0x0C/* PLL Control Register 
0 [for SAM9X60] */
+#defineAT91_PMC_PLL_CTRL0_ENPLL(1 << 28)   /* 
Enable PLL */
+#defineAT91_PMC_PLL_CTRL0_ENPLLCK  (1 << 29)   /* 
Enable PLL clock for PMC */
+#defineAT91_PMC_PLL_CTRL0_ENLOCK   (1 << 31)   /* 
Enable PLL lock */
+
+#define AT91_PMC_PLL_CTRL1 0x10/* PLL Control Register 
1 [for SAM9X60] */
+
+#defineAT91_PMC_PCER   0x10/* Peripheral 
Clock Enable Register */
+#defineAT91_PMC_PCDR   0x14/* Peripheral 
Clock Disable Register */
+#defineAT91_PMC_PCSR   0x18/* Peripheral 
Clock Status Register */
+
+#define AT91_PMC_PLL_ACR   0x18/* PLL Analog Control 
Register [for SAM9X60] */
+#defineAT91_PMC_PLL_ACR_DEFAULT_UPLL   0x12020010UL/* 
Default PLL ACR value for UPLL */
+#defineAT91_PMC_PLL_ACR_DEFAULT_PLLA   0x00020010UL/* 
Default PLL ACR value for PLLA */
+#defineAT91_PMC_PLL_ACR_UTMIVR (1 << 12)   /* UPLL 
Voltage 

[PATCH v3 00/21] clk: at91: add sama7g5 support

2020-09-07 Thread Claudiu Beznea
The purpose of this series is to add clock support for SAMA7G5.
Along with this, clock drivers were switched to CCF and aligned
with their corresponding versions present in Linux.
Some changes were done for CCF, patches 1, 3, 4, 5 (I don't know
if they were as is by intention of a fixes tag is needed in there).

Also patch 3/21 has been added to support clock re-reparenting (this
is minimal support and hope it doesn't break anything if used).

Thank you,
Claudiu Beznea

Changes in v3:
- collected remaining Reviewed-by tags
- rebase on top of latest master branch:
  e5df264e7aac ("Merge https://gitlab.denx.de/u-boot/custodians/u-boot-marvell;)
  to adapt patch 8/21 at changes from commit
  702e57e113d8 ("treewide: convert devfdt_get_addr_ptr() to 
dev_read_addr_ptr()")

Changes in v2:
- use assert() in patch 1/21
- drop patch 2/22 from previous series
- add sandbox tests for clock reparenting, device reparenting and
  critical clocks
- adapt review comments
- collected Reviewed-by tags

Claudiu Beznea (21):
  clk: check hw and hw->dev before dereference it
  dm: core: add support for device re-parenting
  clk: bind clk to new parent device
  clk: do not disable clock if it is critical
  clk: get clock pointer before proceeding
  clk: at91: add pre-requisite headers for AT91 clock architecture
  clk: at91: pmc: add helpers for clock drivers
  clk: at91: move clock code to compat.c
  clk: at91: sckc: add driver compatible with ccf
  clk: at91: clk-main: add driver compatible with ccf
  clk: at91: sam9x60-pll: add driver compatible with ccf
  clk: at91: clk-master: add driver compatible with ccf
  clk: at91: clk-master: add support for sama7g5
  clk: at91: clk-utmi: add driver compatible with ccf
  clk: at91: clk-utmi: add support for sama7g5
  clk: at91: clk-programmable: add driver compatible with ccf
  clk: at91: clk-system: add driver compatible with ccf
  clk: at91: clk-peripheral: add driver compatible with ccf
  clk: at91: clk-generic: add driver compatible with ccf
  clk: at91: pmc: add generic clock ops
  clk: at91: sama7g5: add clock support

 drivers/clk/at91/Kconfig|7 +
 drivers/clk/at91/Makefile   |   15 +-
 drivers/clk/at91/clk-generated.c|  178 -
 drivers/clk/at91/clk-generic.c  |  202 +
 drivers/clk/at91/clk-h32mx.c|   56 --
 drivers/clk/at91/clk-main.c |  381 +-
 drivers/clk/at91/clk-master.c   |  331 -
 drivers/clk/at91/clk-peripheral.c   |  291 ++--
 drivers/clk/at91/clk-plla.c |   54 --
 drivers/clk/at91/clk-plladiv.c  |   85 ---
 drivers/clk/at91/clk-programmable.c |  208 ++
 drivers/clk/at91/clk-sam9x60-pll.c  |  442 +++
 drivers/clk/at91/clk-slow.c |   36 -
 drivers/clk/at91/clk-system.c   |  143 ++--
 drivers/clk/at91/clk-usb.c  |  147 
 drivers/clk/at91/clk-utmi.c |  234 --
 drivers/clk/at91/compat.c   | 1023 +
 drivers/clk/at91/pmc.c  |  218 +++---
 drivers/clk/at91/pmc.h  |  140 +++-
 drivers/clk/at91/sama7g5.c  | 1401 +++
 drivers/clk/at91/sckc.c |  169 -
 drivers/clk/clk-uclass.c|   51 +-
 drivers/clk/clk.c   |3 +
 drivers/core/device.c   |   22 +
 include/dm/device-internal.h|9 +
 include/dt-bindings/clk/at91.h  |   22 +
 include/linux/clk/at91_pmc.h|  247 ++
 test/dm/clk_ccf.c   |   57 ++
 test/dm/core.c  |  160 
 29 files changed, 5407 insertions(+), 925 deletions(-)
 delete mode 100644 drivers/clk/at91/clk-generated.c
 create mode 100644 drivers/clk/at91/clk-generic.c
 delete mode 100644 drivers/clk/at91/clk-h32mx.c
 delete mode 100644 drivers/clk/at91/clk-plla.c
 delete mode 100644 drivers/clk/at91/clk-plladiv.c
 create mode 100644 drivers/clk/at91/clk-programmable.c
 create mode 100644 drivers/clk/at91/clk-sam9x60-pll.c
 delete mode 100644 drivers/clk/at91/clk-slow.c
 delete mode 100644 drivers/clk/at91/clk-usb.c
 create mode 100644 drivers/clk/at91/compat.c
 create mode 100644 drivers/clk/at91/sama7g5.c
 create mode 100644 include/dt-bindings/clk/at91.h
 create mode 100644 include/linux/clk/at91_pmc.h

-- 
2.7.4



[PATCH v3 04/21] clk: do not disable clock if it is critical

2020-09-07 Thread Claudiu Beznea
Do not disable clock if it is a critical one.

Signed-off-by: Claudiu Beznea 
Reviewed-by: Simon Glass 
---
 drivers/clk/clk-uclass.c |  3 +++
 test/dm/clk_ccf.c| 32 +++-
 2 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index 5e0c8419d65b..b8538f342a0c 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -606,6 +606,9 @@ int clk_disable(struct clk *clk)
 
if (CONFIG_IS_ENABLED(CLK_CCF)) {
if (clk->id && !clk_get_by_id(clk->id, )) {
+   if (clkp->flags & CLK_IS_CRITICAL)
+   return 0;
+
if (clkp->enable_count == 0) {
printf("clk %s already disabled\n",
   clkp->dev->name);
diff --git a/test/dm/clk_ccf.c b/test/dm/clk_ccf.c
index 1ce28d747dbe..e4ebb93cdad4 100644
--- a/test/dm/clk_ccf.c
+++ b/test/dm/clk_ccf.c
@@ -24,7 +24,7 @@ static int dm_test_clk_ccf(struct unit_test_state *uts)
int ret;
 #if CONFIG_IS_ENABLED(CLK_CCF)
const char *clkname;
-   int clkid;
+   int clkid, i;
 #endif
 
/* Get the device using the clk device */
@@ -157,6 +157,36 @@ static int dm_test_clk_ccf(struct unit_test_state *uts)
pclk = clk_get_parent(clk);
ut_assertok_ptr(pclk);
ut_asserteq_str(clkname, pclk->dev->name);
+
+   /* Test disabling critical clock. */
+   ret = clk_get_by_id(SANDBOX_CLK_I2C_ROOT, );
+   ut_assertok(ret);
+   ut_asserteq_str("i2c_root", clk->dev->name);
+
+   /* Disable it, if any. */
+   ret = sandbox_clk_enable_count(clk);
+   for (i = 0; i < ret; i++) {
+   ret = clk_disable(clk);
+   ut_assertok(ret);
+   }
+
+   ret = sandbox_clk_enable_count(clk);
+   ut_asserteq(ret, 0);
+
+   clk->flags = CLK_IS_CRITICAL;
+   ret = clk_enable(clk);
+   ut_assertok(ret);
+
+   ret = clk_disable(clk);
+   ut_assertok(ret);
+   ret = sandbox_clk_enable_count(clk);
+   ut_asserteq(ret, 1);
+   clk->flags &= ~CLK_IS_CRITICAL;
+
+   ret = clk_disable(clk);
+   ut_assertok(ret);
+   ret = sandbox_clk_enable_count(clk);
+   ut_asserteq(ret, 0);
 #endif
 
return 1;
-- 
2.7.4



[PATCH v3 03/21] clk: bind clk to new parent device

2020-09-07 Thread Claudiu Beznea
Clock re-parenting is not binding the clock's device to its new
parent device, it only calls the clock's ops->set_parent() API. The
changes in this commit re-parent the clock device to its new parent
so that subsequent operations like clk_get_parent() to point to the
proper parent.

Signed-off-by: Claudiu Beznea 
Reviewed-by: Simon Glass 
---
 drivers/clk/clk-uclass.c | 11 ++-
 test/dm/clk_ccf.c| 27 +++
 2 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index 934cd5787a5c..5e0c8419d65b 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -512,6 +513,7 @@ ulong clk_set_rate(struct clk *clk, ulong rate)
 int clk_set_parent(struct clk *clk, struct clk *parent)
 {
const struct clk_ops *ops;
+   int ret;
 
debug("%s(clk=%p, parent=%p)\n", __func__, clk, parent);
if (!clk_valid(clk))
@@ -521,7 +523,14 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
if (!ops->set_parent)
return -ENOSYS;
 
-   return ops->set_parent(clk, parent);
+   ret = ops->set_parent(clk, parent);
+   if (ret)
+   return ret;
+
+   if (CONFIG_IS_ENABLED(CLK_CCF))
+   ret = device_reparent(clk->dev, parent->dev);
+
+   return ret;
 }
 
 int clk_enable(struct clk *clk)
diff --git a/test/dm/clk_ccf.c b/test/dm/clk_ccf.c
index 32bc4d2b8a0c..1ce28d747dbe 100644
--- a/test/dm/clk_ccf.c
+++ b/test/dm/clk_ccf.c
@@ -22,6 +22,10 @@ static int dm_test_clk_ccf(struct unit_test_state *uts)
struct udevice *dev;
long long rate;
int ret;
+#if CONFIG_IS_ENABLED(CLK_CCF)
+   const char *clkname;
+   int clkid;
+#endif
 
/* Get the device using the clk device */
ut_assertok(uclass_get_device_by_name(UCLASS_CLK, "clk-ccf", ));
@@ -130,6 +134,29 @@ static int dm_test_clk_ccf(struct unit_test_state *uts)
 
ret = sandbox_clk_enable_count(pclk);
ut_asserteq(ret, 0);
+
+   /* Test clock re-parenting. */
+   ret = clk_get_by_id(SANDBOX_CLK_USDHC1_SEL, );
+   ut_assertok(ret);
+   ut_asserteq_str("usdhc1_sel", clk->dev->name);
+
+   pclk = clk_get_parent(clk);
+   ut_assertok_ptr(pclk);
+   if (!strcmp(pclk->dev->name, "pll3_60m")) {
+   clkname = "pll3_80m";
+   clkid = SANDBOX_CLK_PLL3_80M;
+   } else {
+   clkname = "pll3_60m";
+   clkid = SANDBOX_CLK_PLL3_60M;
+   }
+
+   ret = clk_get_by_id(clkid, );
+   ut_assertok(ret);
+   ret = clk_set_parent(clk, pclk);
+   ut_assertok(ret);
+   pclk = clk_get_parent(clk);
+   ut_assertok_ptr(pclk);
+   ut_asserteq_str(clkname, pclk->dev->name);
 #endif
 
return 1;
-- 
2.7.4



[PATCH v3 05/21] clk: get clock pointer before proceeding

2020-09-07 Thread Claudiu Beznea
clk_get_by_indexed_prop() retrieves a clock with dev member being set
with the pointer to the udevice for the clock controller driver. But
in case of CCF each clock driver has set in dev member the reference
to its parent (the root of the clock tree is a fixed clock, every
node in clock tree is a clock registered with clk_register()). In this
case the subsequent operations like dev_get_clk_ptr() on clocks
retrieved by clk_get_by_indexed_prop() will fail. For this, get the
pointer to the proper clock registered (with clk_register()) using
clk_get_by_id() before proceeding.

Fixes: 1d7993d1d0ef ("clk: Port Linux common clock framework [CCF] for imx6q to 
U-boot (tag: v5.1.12)")
Signed-off-by: Claudiu Beznea 
Reviewed-by: Simon Glass 
---
 drivers/clk/clk-uclass.c | 37 +
 1 file changed, 33 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index b8538f342a0c..4076535271b1 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -188,9 +188,26 @@ bulk_get_err:
return ret;
 }
 
+static struct clk *clk_set_default_get_by_id(struct clk *clk)
+{
+   struct clk *c = clk;
+
+   if (CONFIG_IS_ENABLED(CLK_CCF)) {
+   int ret = clk_get_by_id(clk->id, );
+
+   if (ret) {
+   debug("%s(): could not get parent clock pointer, id 
%lu\n",
+ __func__, clk->id);
+   ERR_PTR(ret);
+   }
+   }
+
+   return c;
+}
+
 static int clk_set_default_parents(struct udevice *dev, int stage)
 {
-   struct clk clk, parent_clk;
+   struct clk clk, parent_clk, *c, *p;
int index;
int num_parents;
int ret;
@@ -216,6 +233,10 @@ static int clk_set_default_parents(struct udevice *dev, 
int stage)
return ret;
}
 
+   p = clk_set_default_get_by_id(_clk);
+   if (IS_ERR(p))
+   return PTR_ERR(p);
+
ret = clk_get_by_indexed_prop(dev, "assigned-clocks",
  index, );
if (ret) {
@@ -235,7 +256,11 @@ static int clk_set_default_parents(struct udevice *dev, 
int stage)
/* do not setup twice the parent clocks */
continue;
 
-   ret = clk_set_parent(, _clk);
+   c = clk_set_default_get_by_id();
+   if (IS_ERR(c))
+   return PTR_ERR(c);
+
+   ret = clk_set_parent(c, p);
/*
 * Not all drivers may support clock-reparenting (as of now).
 * Ignore errors due to this.
@@ -255,7 +280,7 @@ static int clk_set_default_parents(struct udevice *dev, int 
stage)
 
 static int clk_set_default_rates(struct udevice *dev, int stage)
 {
-   struct clk clk;
+   struct clk clk, *c;
int index;
int num_rates;
int size;
@@ -299,7 +324,11 @@ static int clk_set_default_rates(struct udevice *dev, int 
stage)
/* do not setup twice the parent clocks */
continue;
 
-   ret = clk_set_rate(, rates[index]);
+   c = clk_set_default_get_by_id();
+   if (IS_ERR(c))
+   return PTR_ERR(c);
+
+   ret = clk_set_rate(c, rates[index]);
 
if (ret < 0) {
debug("%s: failed to set rate on clock index %d (%ld) 
for %s\n",
-- 
2.7.4



[PATCH v3 01/21] clk: check hw and hw->dev before dereference it

2020-09-07 Thread Claudiu Beznea
Check hw and hw->dev before dereference it.

Signed-off-by: Claudiu Beznea 
Reviewed-by: Simon Glass 
---
 drivers/clk/clk.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 786f4e887e7a..319808d433f5 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -57,6 +57,9 @@ ulong clk_generic_get_rate(struct clk *clk)
 
 const char *clk_hw_get_name(const struct clk *hw)
 {
+   assert(hw);
+   assert(hw->dev);
+
return hw->dev->name;
 }
 
-- 
2.7.4



[PATCH v3 02/21] dm: core: add support for device re-parenting

2020-09-07 Thread Claudiu Beznea
In common clock framework the relation b/w parent and child clocks is
determined based on the udevice parent/child information. A clock
parent could be changed based on devices needs. In case this is happen
the functionalities for clock who's parent is changed are broken. Add
a function that reparent a device. This will be used in clk-uclass.c
to reparent a clock device.

Signed-off-by: Claudiu Beznea 
Reviewed-by: Simon Glass 
---
 drivers/core/device.c|  22 ++
 include/dm/device-internal.h |   9 +++
 test/dm/core.c   | 160 +++
 3 files changed, 191 insertions(+)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index 355dbd147a9e..e90d70101c20 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -276,6 +276,28 @@ int device_bind_by_name(struct udevice *parent, bool 
pre_reloc_only,
return ret;
 }
 
+int device_reparent(struct udevice *dev, struct udevice *new_parent)
+{
+   struct udevice *pos, *n;
+
+   assert(dev);
+   assert(new_parent);
+
+   list_for_each_entry_safe(pos, n, >parent->child_head,
+sibling_node) {
+   if (pos->driver != dev->driver)
+   continue;
+
+   list_del(>sibling_node);
+   list_add_tail(>sibling_node, _parent->child_head);
+   dev->parent = new_parent;
+
+   break;
+   }
+
+   return 0;
+}
+
 static void *alloc_priv(int size, uint flags)
 {
void *priv;
diff --git a/include/dm/device-internal.h b/include/dm/device-internal.h
index 5145fb4e1459..1dcc22f68915 100644
--- a/include/dm/device-internal.h
+++ b/include/dm/device-internal.h
@@ -84,6 +84,15 @@ int device_bind_by_name(struct udevice *parent, bool 
pre_reloc_only,
struct driver_info *info, struct udevice **devp);
 
 /**
+ * device_reparent: reparent the device to a new parent
+ *
+ * @dev: pointer to device to be reparented
+ * @new_parent: pointer to new parent device
+ * @return 0 if OK, -ve on error
+ */
+int device_reparent(struct udevice *dev, struct udevice *new_parent);
+
+/**
  * device_ofdata_to_platdata() - Read platform data for a device
  *
  * Read platform data for a device (typically from the device tree) so that
diff --git a/test/dm/core.c b/test/dm/core.c
index 8ed5bf73705b..6f380a574cf2 100644
--- a/test/dm/core.c
+++ b/test/dm/core.c
@@ -643,6 +643,166 @@ static int dm_test_children(struct unit_test_state *uts)
 }
 DM_TEST(dm_test_children, 0);
 
+static int dm_test_device_reparent(struct unit_test_state *uts)
+{
+   struct dm_test_state *dms = uts->priv;
+   struct udevice *top[NODE_COUNT];
+   struct udevice *child[NODE_COUNT];
+   struct udevice *grandchild[NODE_COUNT];
+   struct udevice *dev;
+   int total;
+   int ret;
+   int i;
+
+   /* We don't care about the numbering for this test */
+   dms->skip_post_probe = 1;
+
+   ut_assert(NODE_COUNT > 5);
+
+   /* First create 10 top-level children */
+   ut_assertok(create_children(uts, dms->root, NODE_COUNT, 0, top));
+
+   /* Now a few have their own children */
+   ut_assertok(create_children(uts, top[2], NODE_COUNT, 2, NULL));
+   ut_assertok(create_children(uts, top[5], NODE_COUNT, 5, child));
+
+   /* And grandchildren */
+   for (i = 0; i < NODE_COUNT; i++)
+   ut_assertok(create_children(uts, child[i], NODE_COUNT, 50 * i,
+   i == 2 ? grandchild : NULL));
+
+   /* Check total number of devices */
+   total = NODE_COUNT * (3 + NODE_COUNT);
+   ut_asserteq(total, dm_testdrv_op_count[DM_TEST_OP_BIND]);
+
+   /* Probe everything */
+   for (i = 0; i < total; i++)
+   ut_assertok(uclass_get_device(UCLASS_TEST, i, ));
+
+   /* Re-parent top-level children with no grandchildren. */
+   ut_assertok(device_reparent(top[3], top[0]));
+   /* try to get devices */
+   for (ret = uclass_find_first_device(UCLASS_TEST, );
+dev;
+ret = uclass_find_next_device()) {
+   ut_assert(!ret);
+   ut_assertnonnull(dev);
+   }
+
+   ut_assertok(device_reparent(top[4], top[0]));
+   /* try to get devices */
+   for (ret = uclass_find_first_device(UCLASS_TEST, );
+dev;
+ret = uclass_find_next_device()) {
+   ut_assert(!ret);
+   ut_assertnonnull(dev);
+   }
+
+   /* Re-parent top-level children with grandchildren. */
+   ut_assertok(device_reparent(top[2], top[0]));
+   /* try to get devices */
+   for (ret = uclass_find_first_device(UCLASS_TEST, );
+dev;
+ret = uclass_find_next_device()) {
+   ut_assert(!ret);
+   ut_assertnonnull(dev);
+   }
+
+   ut_assertok(device_reparent(top[5], top[2]));
+   /* try to get devices */
+   for (ret = 

[PATCH] timer: Return count from timer_ops.get_count

2020-09-07 Thread Sean Anderson
No timer drivers return an error from get_count. Instead of possibly
returning an error, just return the count directly.

Signed-off-by: Sean Anderson 
---
Passing CI (but not otherwise tested):
https://dev.azure.com/seanga2/u-boot/_build/results?buildId=25=results

This patch depends on
https://patchwork.ozlabs.org/project/uboot/list/?series=198797

 arch/riscv/lib/andes_plmt.c   |  6 ++
 arch/riscv/lib/sifive_clint.c |  6 ++
 drivers/timer/ag101p_timer.c  |  5 ++---
 drivers/timer/altera_timer.c  |  6 ++
 drivers/timer/arc_timer.c |  6 ++
 drivers/timer/ast_timer.c |  6 ++
 drivers/timer/atcpit100_timer.c   |  5 ++---
 drivers/timer/atmel_pit_timer.c   |  6 ++
 drivers/timer/cadence-ttc.c   |  6 ++
 drivers/timer/dw-apb-timer.c  |  6 ++
 drivers/timer/mpc83xx_timer.c |  6 ++
 drivers/timer/mtk_timer.c |  6 ++
 drivers/timer/nomadik-mtu-timer.c |  6 ++
 drivers/timer/omap-timer.c|  6 ++
 drivers/timer/ostm_timer.c|  6 ++
 drivers/timer/riscv_timer.c   | 21 +
 drivers/timer/rockchip_timer.c|  5 ++---
 drivers/timer/sandbox_timer.c |  6 ++
 drivers/timer/sti-timer.c |  6 ++
 drivers/timer/stm32_timer.c   |  6 ++
 drivers/timer/timer-uclass.c  |  3 ++-
 drivers/timer/tsc_timer.c |  6 ++
 include/timer.h   |  5 ++---
 23 files changed, 53 insertions(+), 93 deletions(-)

diff --git a/arch/riscv/lib/andes_plmt.c b/arch/riscv/lib/andes_plmt.c
index b0245d0b52..82b9e99fa8 100644
--- a/arch/riscv/lib/andes_plmt.c
+++ b/arch/riscv/lib/andes_plmt.c
@@ -17,11 +17,9 @@
 /* mtime register */
 #define MTIME_REG(base)((ulong)(base))
 
-static int andes_plmt_get_count(struct udevice *dev, u64 *count)
+static u64 andes_plmt_get_count(struct udevice *dev)
 {
-   *count = readq((void __iomem *)MTIME_REG(dev->priv));
-
-   return 0;
+   return readq((void __iomem *)MTIME_REG(dev->priv));
 }
 
 static const struct timer_ops andes_plmt_ops = {
diff --git a/arch/riscv/lib/sifive_clint.c b/arch/riscv/lib/sifive_clint.c
index 3345a17ad2..9a14b02e50 100644
--- a/arch/riscv/lib/sifive_clint.c
+++ b/arch/riscv/lib/sifive_clint.c
@@ -62,11 +62,9 @@ int riscv_get_ipi(int hart, int *pending)
return 0;
 }
 
-static int sifive_clint_get_count(struct udevice *dev, u64 *count)
+static u64 sifive_clint_get_count(struct udevice *dev)
 {
-   *count = readq((void __iomem *)MTIME_REG(dev->priv));
-
-   return 0;
+   return readq((void __iomem *)MTIME_REG(dev->priv));
 }
 
 static const struct timer_ops sifive_clint_ops = {
diff --git a/drivers/timer/ag101p_timer.c b/drivers/timer/ag101p_timer.c
index c011906b93..23ad5b2b67 100644
--- a/drivers/timer/ag101p_timer.c
+++ b/drivers/timer/ag101p_timer.c
@@ -62,14 +62,13 @@ struct atftmr_timer_platdata {
struct atftmr_timer_regs *regs;
 };
 
-static int atftmr_timer_get_count(struct udevice *dev, u64 *count)
+static u64 atftmr_timer_get_count(struct udevice *dev)
 {
struct atftmr_timer_platdata *plat = dev->platdata;
struct atftmr_timer_regs *const regs = plat->regs;
u32 val;
val = readl(>t3_counter);
-   *count = timer_conv_64(val);
-   return 0;
+   return timer_conv_64(val);
 }
 
 static int atftmr_timer_probe(struct udevice *dev)
diff --git a/drivers/timer/altera_timer.c b/drivers/timer/altera_timer.c
index 6cb2923e0b..ccc164ee17 100644
--- a/drivers/timer/altera_timer.c
+++ b/drivers/timer/altera_timer.c
@@ -32,7 +32,7 @@ struct altera_timer_platdata {
struct altera_timer_regs *regs;
 };
 
-static int altera_timer_get_count(struct udevice *dev, u64 *count)
+static u64 altera_timer_get_count(struct udevice *dev)
 {
struct altera_timer_platdata *plat = dev->platdata;
struct altera_timer_regs *const regs = plat->regs;
@@ -44,9 +44,7 @@ static int altera_timer_get_count(struct udevice *dev, u64 
*count)
/* Read timer value */
val = readl(>snapl) & 0x;
val |= (readl(>snaph) & 0x) << 16;
-   *count = timer_conv_64(~val);
-
-   return 0;
+   return timer_conv_64(~val);
 }
 
 static int altera_timer_probe(struct udevice *dev)
diff --git a/drivers/timer/arc_timer.c b/drivers/timer/arc_timer.c
index 8c574ec5af..2dea9f40cb 100644
--- a/drivers/timer/arc_timer.c
+++ b/drivers/timer/arc_timer.c
@@ -26,7 +26,7 @@ struct arc_timer_priv {
uint timer_id;
 };
 
-static int arc_timer_get_count(struct udevice *dev, u64 *count)
+static u64 arc_timer_get_count(struct udevice *dev)
 {
u32 val = 0;
struct arc_timer_priv *priv = dev_get_priv(dev);
@@ -39,9 +39,7 @@ static int arc_timer_get_count(struct udevice *dev, u64 
*count)
val = read_aux_reg(ARC_AUX_TIMER1_CNT);
break;
}
-   *count = timer_conv_64(val);
-
-   return 0;
+   return timer_conv_64(val);
 }
 
 

[ANN] U-Boot v2020.10-rc4 released

2020-09-07 Thread Tom Rini
Hey all,

It's release day and I'm getting this one out on schedule again.  With
this release, I'm also opening up -next and will start by testing the
NR_DRAM_BANKS PR and go from there on other series that are in my TODO
list.

Once again, for a changelog, 
git log --merges v2020.10-rc3..v2020.10-rc4
and as always, I ask for more details in the PRs people send me so I can
put them in the merge commit.

I'm going to continue with every-other-week RCs on Mondays and
release on October 5th.  Thanks all!

-- 
Tom


signature.asc
Description: PGP signature


[PATCH 6/7] riscv: Ensure gp is NULL or points to valid data

2020-09-07 Thread Sean Anderson
This allows code to use a construct like `if (gd & gd->...) { ... }` when
accessing the global data pointer. Without this change, it was possible for
a very early trap to cause _exit_trap to read arbitrary memory. This could
cause a second trap, preventing show_regs from being printed.

Fixes: 7c6ca03eaed0035ca6676e9bc7f5f1dfcaae7e8f
Signed-off-by: Sean Anderson 
---

 arch/riscv/cpu/start.S  | 20 +---
 arch/riscv/lib/interrupts.c |  3 ++-
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S
index ad18e746b6..59d3d7bbf4 100644
--- a/arch/riscv/cpu/start.S
+++ b/arch/riscv/cpu/start.S
@@ -47,6 +47,13 @@ _start:
mv  tp, a0
mv  s1, a1
 
+   /*
+* Set the global data pointer to a known value in case we get a very
+* early trap. The global data pointer will be set its actual value only
+* after it has been initialized.
+*/
+   mv  gp, zero
+
la  t0, trap_entry
csrwMODE_PREFIX(tvec), t0
 
@@ -85,10 +92,10 @@ call_board_init_f_0:
jal board_init_f_alloc_reserve
 
/*
-* Set global data pointer here for all harts, uninitialized at this
-* point.
+* Save global data pointer for later. We don't set it here because it
+* is not initialized yet.
 */
-   mv  gp, a0
+   mv  s0, a0
 
/* setup stack */
 #if CONFIG_IS_ENABLED(SMP)
@@ -135,6 +142,13 @@ wait_for_gd_init:
fence   r, rw
bnezt1, 1b
 
+   /*
+* Set the global data pointer only when gd_t has been initialized.
+* This was already set by arch_setup_gd on the boot hart, but all other
+* harts' global data pointers gets set here.
+*/
+   mv  gp, s0
+
/* register available harts in the available_harts mask */
li  t1, 1
sll t1, t1, tp
diff --git a/arch/riscv/lib/interrupts.c b/arch/riscv/lib/interrupts.c
index cd47e64487..ad870e98d8 100644
--- a/arch/riscv/lib/interrupts.c
+++ b/arch/riscv/lib/interrupts.c
@@ -78,7 +78,8 @@ static void _exit_trap(ulong code, ulong epc, ulong tval, 
struct pt_regs *regs)
 
printf("EPC: " REG_FMT " RA: " REG_FMT " TVAL: " REG_FMT "\n",
   epc, regs->ra, tval);
-   if (gd->flags & GD_FLG_RELOC)
+   /* Print relocation adjustments, but only if gd is initialized */
+   if (gd && gd->flags & GD_FLG_RELOC)
printf("EPC: " REG_FMT " RA: " REG_FMT " reloc adjusted\n\n",
   epc - gd->reloc_off, regs->ra - gd->reloc_off);
 
-- 
2.28.0



[PATCH 5/7] riscv: Add fence to available_harts_lock

2020-09-07 Thread Sean Anderson
Without these fences, it is perfectly valid for an out-of-order core to
re-order memory accesses to outside of the available_harts_lock critical
section.

Signed-off-by: Sean Anderson 
---

 arch/riscv/cpu/start.S | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S
index e3222b1ea7..ad18e746b6 100644
--- a/arch/riscv/cpu/start.S
+++ b/arch/riscv/cpu/start.S
@@ -126,12 +126,12 @@ call_board_init_f_0:
 #ifndef CONFIG_XIP
la  t0, available_harts_lock
fence   rw, w
-   amoswap.w zero, zero, 0(t0)
+   amoswap.w.rl zero, zero, 0(t0)
 
 wait_for_gd_init:
la  t0, available_harts_lock
li  t1, 1
-1: amoswap.w t1, t1, 0(t0)
+1: amoswap.w.aq t1, t1, 0(t0)
fence   r, rw
bnezt1, 1b
 
@@ -143,7 +143,7 @@ wait_for_gd_init:
SREGt2, GD_AVAILABLE_HARTS(gp)
 
fence   rw, w
-   amoswap.w zero, zero, 0(t0)
+   amoswap.w.rl zero, zero, 0(t0)
 
/*
 * Continue on hart lottery winner, others branch to
-- 
2.28.0



[PATCH 7/7] riscv: Add some comments to start.S

2020-09-07 Thread Sean Anderson
This adds comments regarding the ordering and purpose of certain
instructions as I understand them.

Signed-off-by: Sean Anderson 
---

 arch/riscv/cpu/start.S | 19 +--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S
index 59d3d7bbf4..c659c6df53 100644
--- a/arch/riscv/cpu/start.S
+++ b/arch/riscv/cpu/start.S
@@ -43,7 +43,10 @@ _start:
csrra0, CSR_MHARTID
 #endif
 
-   /* save hart id and dtb pointer */
+   /*
+* Save hart id and dtb pointer. The thread pointer register is not
+* modified by C code, and may be used in trap handlers.
+*/
mv  tp, a0
mv  s1, a1
 
@@ -54,10 +57,18 @@ _start:
 */
mv  gp, zero
 
+   /*
+* Set the trap handler. This must happen after initializing tp and gp
+* because the handler may use these registers.
+*/
la  t0, trap_entry
csrwMODE_PREFIX(tvec), t0
 
-   /* mask all interrupts */
+   /*
+* Mask all interrupts. Interrupts are disabled globally (in m/sstatus)
+* for U-Boot, but we will need to read m/sip to determine if we get an
+* IPI
+*/
csrwMODE_PREFIX(ie), zero
 
 #if CONFIG_IS_ENABLED(SMP)
@@ -407,6 +418,10 @@ secondary_hart_relocate:
mv  gp, a2
 #endif
 
+/*
+ * Interrupts are disabled globally, but they can still be read from m/sip. The
+ * wfi function will wake us up if we get an IPI, even if we do not trap.
+ */
 secondary_hart_loop:
wfi
 
-- 
2.28.0



[PATCH 4/7] riscv: Clear pending IPIs on initialization

2020-09-07 Thread Sean Anderson
Even though we no longer call smp_function if an IPI was not sent by
U-Boot, we still need to clear any IPIs which were pending from the
execution environment. Otherwise, secondary harts will busy-wait in
secondary_hart_loop, instead of relaxing.

Signed-off-by: Sean Anderson 
---

 arch/riscv/cpu/cpu.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c
index bfa2d4a426..ad94744c0f 100644
--- a/arch/riscv/cpu/cpu.c
+++ b/arch/riscv/cpu/cpu.c
@@ -72,6 +72,15 @@ static int riscv_cpu_probe(void)
return 0;
 }
 
+/*
+ * This is called on secondary harts just after the IPI is init'd. Currently
+ * there's nothing to do, since we just need to clear any existing IPIs, and
+ * that is handled by the sending of an ipi itself.
+ */
+void riscv_ipi_init_secondary_hart(ulong hart, ulong arg0, ulong arg1)
+{
+}
+
 int arch_cpu_init_dm(void)
 {
int ret;
@@ -111,6 +120,15 @@ int arch_cpu_init_dm(void)
ret = riscv_init_ipi();
if (ret)
return ret;
+
+   /*
+* Clear all pending IPIs on secondary harts. We don't do anything on
+* the boot hart, since we never send an IPI to ourselves, and no
+* interrupts are enabled
+*/
+   ret = smp_call_function((ulong)riscv_ipi_init_secondary_hart, 0, 0, 0);
+   if (ret)
+   return ret;
 #endif
 
return 0;
-- 
2.28.0



[PATCH 1/7] Revert "riscv: Clear pending interrupts before enabling IPIs"

2020-09-07 Thread Sean Anderson
Clearing MIP doesn't do anything. Whoops. The following commits should
tackle this problem in a more robust manner.

This reverts commit 9472630337e7c4ac442066b5a752aaa8c3b4d4a6.

Signed-off-by: Sean Anderson 
---

 arch/riscv/cpu/start.S | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S
index bf9fdf369b..e3222b1ea7 100644
--- a/arch/riscv/cpu/start.S
+++ b/arch/riscv/cpu/start.S
@@ -65,8 +65,6 @@ _start:
 #else
li  t0, SIE_SSIE
 #endif
-   /* Clear any pending IPIs */
-   csrcMODE_PREFIX(ip), t0
csrsMODE_PREFIX(ie), t0
 #endif
 
-- 
2.28.0



[PATCH 3/7] riscv: Use NULL as a sentinel value for smp_call_function

2020-09-07 Thread Sean Anderson
Some IPIs may already be pending when U-Boot is started. This could be a
problem if a secondary hart tries to handle an IPI before the boot hart has
initialized the IPI device.

This commit uses NULL as a sentinel for secondary harts so they know when
the IPI is initialized, and it is safe to use the IPI API. The smp addr
parameter is initialized to NULL by board_init_f_init_reserve. Before this,
secondary harts wait in wait_for_gd_init.

This imposes a minor restriction because harts may no longer jump to NULL.
However, given that the RISC-V debug device is likely to be located at
0x400, it is unlikely for any RISC-V implementation to have usable ram
located at 0x0.

Signed-off-by: Sean Anderson 
---

 arch/riscv/lib/smp.c | 26 ++
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/arch/riscv/lib/smp.c b/arch/riscv/lib/smp.c
index ab6d8bd7fa..8c25755330 100644
--- a/arch/riscv/lib/smp.c
+++ b/arch/riscv/lib/smp.c
@@ -18,6 +18,12 @@ static int send_ipi_many(struct ipi_data *ipi, int wait)
u32 reg;
int ret, pending;
 
+   /* NULL is used as a sentinel value */
+   if (!ipi->addr) {
+   pr_err("smp_function cannot be set to 0x0\n");
+   return -EINVAL;
+   }
+
cpus = ofnode_path("/cpus");
if (!ofnode_valid(cpus)) {
pr_err("Can't find cpus node!\n");
@@ -50,11 +56,16 @@ static int send_ipi_many(struct ipi_data *ipi, int wait)
continue;
 #endif
 
-   gd->arch.ipi[reg].addr = ipi->addr;
gd->arch.ipi[reg].arg0 = ipi->arg0;
gd->arch.ipi[reg].arg1 = ipi->arg1;
 
-   __smp_mb();
+   /*
+* Ensure addr only becomes non-NULL when arg0 and arg1 are
+* valid. An IPI may already be pending on other harts, so we
+* need a way to signal that the IPI device has been
+* initialized, and that it is ok to call the function.
+*/
+   __smp_store_release(>arch.ipi[reg].addr, ipi->addr);
 
ret = riscv_send_ipi(reg);
if (ret) {
@@ -83,9 +94,16 @@ void handle_ipi(ulong hart)
if (hart >= CONFIG_NR_CPUS)
return;
 
-   __smp_mb();
+   smp_function = (void (*)(ulong, ulong, ulong))
+   __smp_load_acquire(>arch.ipi[hart].addr);
+   /*
+* If the function is NULL, then U-Boot has not requested the IPI. The
+* IPI device may not be initialized, so all we can do is wait for
+* U-Boot to initialize it and send an IPI
+*/
+   if (!smp_function)
+   return;
 
-   smp_function = (void (*)(ulong, ulong, ulong))gd->arch.ipi[hart].addr;
invalidate_icache_all();
 
/*
-- 
2.28.0



[PATCH 0/7] riscv: Correctly handle IPIs already pending upon boot

2020-09-07 Thread Sean Anderson
On the K210, the prior stage bootloader does not clear IPIs. This presents
a problem, because U-Boot up until this point assumes (with one exception)
that IPIs are cleared when it starts. This series attempts to fix this in a
robust manner, and fix several concurrency bugs I noticed while fixing
these other areas. Heinrich previously submitted a patch addressing part of
this problem in [1].

[1] 
https://patchwork.ozlabs.org/project/uboot/patch/20200811035648.3284-1-xypron.g...@gmx.de/


Sean Anderson (7):
  Revert "riscv: Clear pending interrupts before enabling IPIs"
  riscv: Match memory barriers between send_ipi_many and handle_ipi
  riscv: Use NULL as a sentinel value for smp_call_function
  riscv: Clear pending IPIs on initialization
  riscv: Add fence to available_harts_lock
  riscv: Ensure gp is NULL or points to valid data
  riscv: Add some comments to start.S

 arch/riscv/cpu/cpu.c| 18 ++
 arch/riscv/cpu/start.S  | 47 +
 arch/riscv/lib/interrupts.c |  3 ++-
 arch/riscv/lib/smp.c| 26 +---
 4 files changed, 80 insertions(+), 14 deletions(-)

-- 
2.28.0



[PATCH 2/7] riscv: Match memory barriers between send_ipi_many and handle_ipi

2020-09-07 Thread Sean Anderson
Without a matching barrier on the write side, the barrier in handle_ipi
does nothing. It was entirely possible for the boot hart to write to addr,
arg0, and arg1 *after* sending the IPI, because there was no barrier on the
sending side.

Fixes: 90ae28143700bae4edd23930a7772899ad259058
Signed-off-by: Sean Anderson 
---

 arch/riscv/lib/smp.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/riscv/lib/smp.c b/arch/riscv/lib/smp.c
index ac22136314..ab6d8bd7fa 100644
--- a/arch/riscv/lib/smp.c
+++ b/arch/riscv/lib/smp.c
@@ -54,6 +54,8 @@ static int send_ipi_many(struct ipi_data *ipi, int wait)
gd->arch.ipi[reg].arg0 = ipi->arg0;
gd->arch.ipi[reg].arg1 = ipi->arg1;
 
+   __smp_mb();
+
ret = riscv_send_ipi(reg);
if (ret) {
pr_err("Cannot send IPI to hart %d\n", reg);
-- 
2.28.0



[RFC] [PATCH] rockchip: Pinebook Pro: fix mmc boot ordering

2020-09-07 Thread lindsey . stanpoor
From: Cameron Nemo 

On the Pinebook Pro, and perhaps some other boards, the mmc indices are
opposite from what is implied by the comment in
include/configs/rockchip-common.h.

This commit fixes the boot ordering to prioritize the SD card over eMMC.

I am not sure if this appropriate for the Pinebook Pro alone (only board
I can test with atm), or other boards as well (rk3399 or otherwise).

Most distributions of U-Boot that actually target rk3399 boards apply a
similar patch, such as Manjaro (shipped by default on PBP) and armbian.

https://gitlab.manjaro.org/manjaro-arm/packages/core/uboot-pinebookpro/-/blob/60ed56b9bf8809309ec6252bfc45bca38c2b858a/0002-Correct-boot-order-to-be-USB-SD-eMMC.patch
https://github.com/armbian/build/blob/5a2b2c360b9c26ca4bd0d309af7cd3994fd08b7d/patch/u-boot/u-boot-rockchip64-mainline/general-prioritize-sd.patch

Signed-off-by: Cameron Nemo 
---
 include/configs/pinebook-pro-rk3399.h | 8 
 1 file changed, 8 insertions(+)

diff --git a/include/configs/pinebook-pro-rk3399.h 
b/include/configs/pinebook-pro-rk3399.h
index d478b19917..59780bfb0b 100644
--- a/include/configs/pinebook-pro-rk3399.h
+++ b/include/configs/pinebook-pro-rk3399.h
@@ -14,6 +14,14 @@
 
 #include 
 
+/* On Pinebook Pro, mmc1 is SD and mmc0 is eMMC */
+#if CONFIG_IS_ENABLED(CMD_MMC)
+   #undef BOOT_TARGET_MMC
+   #define BOOT_TARGET_MMC(func) \
+   func(MMC, mmc, 1) \
+   func(MMC, mmc, 0)
+#endif
+
 #define SDRAM_BANK_SIZE(2UL << 30)
 
 #define CONFIG_USB_OHCI_NEW
-- 
2.28.0



[RFC] FPGA configuration as MTD using Device Tree

2020-09-07 Thread Ulf Samuelsson

Hi,
The FPGA support in u-boot looks a bit old-fashioned to me.
I would like to have device-tree support and would
like comments on my approach.



BACKGROUND
Need to support loading 2 x Cyclone-10 LP FPGAs using Passive Serial.
Raw binary files (RBF) are stored in boot flash, and
u-boot will load both FPGAs before booting the OS.
The OS should be able to update the FPGAs as well.
The FPGAs must be independently configurable.

Hardwarewise, I have an SPI bus with 4 chip selects.
SPI MOSI, SCK, CS2 and CS3 are connected to the synchronous serial bus 
of the FPGA (DATA0, DCLK, the FPGA1.nCS0 and the FPGA2.nCS0)


Intel normally connect FPGA nCS0 to ground but I connect this to the SPI 
CS. The advantage is that I can have several FPGAs which are programmed 
independent to each other.


The FPGAs require three other signals (nCONFIG, nSTATUS and CONF_DONE).
Each FPGA have their own set of those signals.


I have not found device-tree support for FPGAs in u-boot.
Since the FPGAs are connected to the SPI, I thought adding them as MTD 
devices would result in a nice interface.



Example Device tree connected to a bit-bang SPI driver supporting 
multiple chip select.


The MTD configuration supplies
* Name of the FPGA (fpga property)
* The size of the configuration data
* Sideband signals for starting and checking configuration.

_mcspi {
compatible = "mcspi-gpio";
pinctrl-names = "default";
pinctrl-0 = <_mcspi1_pins>;
status = "okay";
gpio-sck  = < 7 GPIO_ACTIVE_LOW>;
gpio-miso = < 8 GPIO_ACTIVE_HIGH>;
gpio-mosi = < 9 GPIO_ACTIVE_HIGH>;
cs-gpios =
   < 12 GPIO_ACTIVE_LOW>,
   < 13 GPIO_ACTIVE_LOW>,
   < 17 GPIO_ACTIVE_LOW>,
   < 16 GPIO_ACTIVE_LOW>;
num-chipselects = <4>;
#address-cells = <1>;
#size-cells = <0>;
...
sspy-fpga-cfg@3 {   /* Intel Cyclone 10, 10CL025 */
#address-cells = <1>;
#size-cells = <1>;
compatible = "intel,cyclone10";
reg = <3>; /* Chip select 0 */
spi-max-frequency = <100>;
fpga = "spyf";
config-size = <718569>;
gpio-nconfig= < 21 GPIO_ACTIVE_HIGH>;
gpio-nstatus= < 17 GPIO_ACTIVE_HIGH>;
gpio-conf_done  = < 18 GPIO_ACTIVE_HIGH>;
gpio-crc_error  = < 18 GPIO_ACTIVE_HIGH>;
};
};


With a Cyclone 10 MTD driver, is would appear in the "mtd list" command
and configuring the fpga would be done using

$ mtd write.raw spyf 

The driver would have to implement dummy read and erase commands.

An alternative would be to add flags which would be tested by the mtd
command which would block the read and erase if the mtd device is an 
FPGA or simply test for that in the mtd command.


What would be best?


The MTD driver would start configuration by toggling gpio-nconfig low
and then wait for gpio-nstatus to go high.

If OK, it would call the spi_xfer routine for the parent spi slave 
(soft-mcspi)


When the spi write returns, the FPGA MTD driver would await the 
CONF_DONE signal before returning.




What do you guys think of such an approach?

BR
Ulf Samuelsson





Re: [PATCH] arm: mvebu: Espressobin: Set environment variable fdtfile

2020-09-07 Thread Andre Heider

On 07/09/2020 10:52, Pali Rohár wrote:

On Monday 07 September 2020 10:46:37 Andre Heider wrote:

Hi Pali,

On 07/09/2020 09:58, Pali Rohár wrote:

On Sunday 06 September 2020 20:44:50 Andre Heider wrote:

On 06/09/2020 11:32, Pali Rohár wrote:

On Saturday 05 September 2020 14:07:44 Andre Heider wrote:

+
+   emmc = of_machine_is_compatible("globalscale,espressobin-emmc");
+
+   if (ddr4 && emmc)
+   env_set("fdtfile", 
"marvell/armada-3720-espressobin-v7-emmc.dtb");
+   else if (ddr4)
+   env_set("fdtfile", "marvell/armada-3720-espressobin-v7.dtb");
+   else if (emmc)
+   env_set("fdtfile", "marvell/armada-3720-espressobin-emmc.dtb");
+   else
+   env_set("fdtfile", "marvell/armada-3720-espressobin.dtb");


This code would overwrite user's value of fdtfile variable. And any
change done by saveenv for fdtfile would be lost. I do not think this is
correct way as it would break booting other distributions/forks (e.g.
Marvell one) which DTB file has different name.

Also user would not be able to adjust usage of its own DTB file if this
code would overwrite it at every boot.


Indeed, it shouldn't wipe a saved $fdtfile. Fixed locally with adding this
hunk to the start of the function:
+   if (env_get("fdtfile"))
+   return 0;


This has still one issue: 'env default -a' does not restore original
value. I would expect that 'env default -a' resets these values to
correct default.


there doesn't seem to be a way to archive that programmatically?
The default argument needs to be known at compile time.


So what about fixing it instead of adding new hacks?


Right, so for the occasional u-boot hacker like me it's not obvious how 
to solve a certain problem. Usually I check how other boards solve it. 
By your definition of hack other boards are full of it.



Currently default env needs to be known at compile time due to
assignment to static const storage. But this can be changed and e.g.
board could could provide weak function which returns additional
variables/value which uboot main code can use for default settings.


Sounds like you have an idea how to solve it nicely, so please go ahead.


Regards,
Andre




Re: [PATCH v4 1/2] arch: arm: use dt and UCLASS_IRQ to get gic details

2020-09-07 Thread Rayagonda Kokatanur
Hi Stefan,


On Thu, Aug 27, 2020 at 5:01 PM Stefan Roese  wrote:
>
> Hi Rayagonda,
>
> On 26.07.20 19:07, Rayagonda Kokatanur wrote:
> > Use device tree and UCLASS_IRQ driver to get following
> > Generic Interrupt Controller (GIC) details,
> >
> > -GIC Distributor interface (GICD) base address and
> > -GIC Redistributors (GICR) base address.
> >
> > Signed-off-by: Rayagonda Kokatanur 
> > Reviewed-by: Simon Glass 
>
> How is this supposed to work on an ARM platform? I'm currently testing
> TOT on an NXP LX2160 platform and it fails with this bootup message:
>
> Error binding driver 'gic-v3': -96
> Some drivers failed to bind
>
> Debugging revealed that UCLASS_IRQ is missing for this platform. The
> driver "irq-uclass.c" is only selectable for X86 & SANDBOX:
>
> config IRQ
> bool "Intel Interrupt controller"
> depends on X86 || SANDBOX
> help
>   This enables support for Intel interrupt controllers, including 
> ITSS.
>   Some devices have extra features, such as Apollo Lake. The
>   device has its own uclass since there are several operations
>   involved.
>
> This Kconfig help is also not correct any more, as the UCLASS_IRQ
> driver is not Intel specific (any more).
>
> FWICT, it would be best to make CONFIG_IRQ selectable for all platforms
> and select it in the "config GIC_V3_ITS" definition, similar to how it
> done with REGMAP & SYSCON. And change the "config IRQ" help text above.
>
> What do you think?

Sorry I missed your mail.

I am okay with your approach.

Also adding the following code at the end of
"arch/arm/lib/gic-v3-its.c" file, will solve the issue.
I found that this piece of code is not required for the latest uboot
hence I didn't add this as part of my patch.

UCLASS_DRIVER(irq) = {
.id = UCLASS_IRQ,
.name = "irq",
};

Best regards,
Rayagonda

>
> Thanks,
> Stefan
>
> > ---
> > Changes from v3:
> >   -Address review comments from Simon,
> >Correct the data type of variables
> >
> > Changes from v1:
> >   -Address review comments from Tom Rini,
> >Fix build warning messages.
> >
> >   arch/arm/lib/gic-v3-its.c | 73 +++
> >   1 file changed, 66 insertions(+), 7 deletions(-)
> >
> > diff --git a/arch/arm/lib/gic-v3-its.c b/arch/arm/lib/gic-v3-its.c
> > index 90f37a123c..5f88643245 100644
> > --- a/arch/arm/lib/gic-v3-its.c
> > +++ b/arch/arm/lib/gic-v3-its.c
> > @@ -3,6 +3,7 @@
> >* Copyright 2019 Broadcom.
> >*/
> >   #include 
> > +#include 
> >   #include 
> >   #include 
> >   #include 
> > @@ -15,6 +16,48 @@ static u32 lpi_id_bits;
> >   #define LPI_PROPBASE_SZ ALIGN(BIT(LPI_NRBITS), SZ_64K)
> >   #define LPI_PENDBASE_SZ ALIGN(BIT(LPI_NRBITS) / 8, SZ_64K)
> >
> > +/*
> > + * gic_v3_its_priv - gic details
> > + *
> > + * @gicd_base: gicd base address
> > + * @gicr_base: gicr base address
> > + */
> > +struct gic_v3_its_priv {
> > + ulong gicd_base;
> > + ulong gicr_base;
> > +};
> > +
> > +static int gic_v3_its_get_gic_addr(struct gic_v3_its_priv *priv)
> > +{
> > + struct udevice *dev;
> > + fdt_addr_t addr;
> > + int ret;
> > +
> > + ret = uclass_get_device_by_driver(UCLASS_IRQ,
> > +   DM_GET_DRIVER(arm_gic_v3_its), 
> > );
> > + if (ret) {
> > + pr_err("%s: failed to get %s irq device\n", __func__,
> > +DM_GET_DRIVER(arm_gic_v3_its)->name);
> > + return ret;
> > + }
> > +
> > + addr = dev_read_addr_index(dev, 0);
> > + if (addr == FDT_ADDR_T_NONE) {
> > + pr_err("%s: failed to get GICD address\n", __func__);
> > + return -EINVAL;
> > + }
> > + priv->gicd_base = addr;
> > +
> > + addr = dev_read_addr_index(dev, 1);
> > + if (addr == FDT_ADDR_T_NONE) {
> > + pr_err("%s: failed to get GICR address\n", __func__);
> > + return -EINVAL;
> > + }
> > + priv->gicr_base = addr;
> > +
> > + return 0;
> > +}
> > +
> >   /*
> >* Program the GIC LPI configuration tables for all
> >* the re-distributors and enable the LPI table
> > @@ -23,15 +66,18 @@ static u32 lpi_id_bits;
> >*/
> >   int gic_lpi_tables_init(u64 base, u32 num_redist)
> >   {
> > + struct gic_v3_its_priv priv;
> >   u32 gicd_typer;
> >   u64 val;
> >   u64 tmp;
> >   int i;
> >   u64 redist_lpi_base;
> > - u64 pend_base = GICR_BASE + GICR_PENDBASER;
> > + u64 pend_base;
> >
> > - gicd_typer = readl(GICD_BASE + GICD_TYPER);
> > + if (gic_v3_its_get_gic_addr())
> > + return -EINVAL;
> >
> > + gicd_typer = readl((uintptr_t)(priv.gicd_base + GICD_TYPER));
> >   /* GIC support for Locality specific peripheral interrupts (LPI's) */
> >   if (!(gicd_typer & GICD_TYPER_LPIS)) {
> >   pr_err("GIC implementation does not support LPI's\n");
> > @@ -46,7 +92,7 @@ int gic_lpi_tables_init(u64 base, u32 num_redist)
> >   for (i = 

[PATCH] ARM: zynq: Add Z-turn board V5

2020-09-07 Thread agriveaux
From: Alexandre GRIVEAUX 

Adding Z-turn board V5 to resolve the change between:

"Z-TURNBOARD_schematic.pdf" schematics state version 1 to 4 has Atheros AR8035
"Z-Turn_Board_sch_V15_20160303.pdf" schematics state version 5 has Micrel 
KSZ9031

At this time the S25FL128SAGNFI003 doesn't work because of bug:

*** Warning - spi_flash_probe_bus_cs() failed, using default environment

Signed-off-by: Alexandre GRIVEAUX 
---
 arch/arm/dts/Makefile |   1 +
 arch/arm/dts/zynq-zturn-v5.dts| 121 
 .../xilinx/zynq/zynq-zturn-v5/ps7_init_gpl.c  | 273 ++
 configs/xilinx_zynq_virt_defconfig|   4 +-
 4 files changed, 398 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/dts/zynq-zturn-v5.dts
 create mode 100644 board/xilinx/zynq/zynq-zturn-v5/ps7_init_gpl.c

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index f8f529435b..0f8973b1c8 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -277,6 +277,7 @@ dtb-$(CONFIG_ARCH_ZYNQ) += \
zynq-zc770-xm013.dtb \
zynq-zed.dtb \
zynq-zturn.dtb \
+   zynq-zturn-v5.dtb \
zynq-zybo.dtb \
zynq-zybo-z7.dtb
 dtb-$(CONFIG_ARCH_ZYNQMP) += \
diff --git a/arch/arm/dts/zynq-zturn-v5.dts b/arch/arm/dts/zynq-zturn-v5.dts
new file mode 100644
index 00..eebeec800f
--- /dev/null
+++ b/arch/arm/dts/zynq-zturn-v5.dts
@@ -0,0 +1,121 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *  Copyright (C) 2020 Alexandre Griveaux 
+ *
+ *  Based on zynq-zturn.dts which is:
+ *  Copyright (C) 2015 Andrea Merello 
+ *  Copyright (C) 2017 Alexander Graf 
+ *
+ */
+
+/dts-v1/;
+/include/ "zynq-7000.dtsi"
+
+/ {
+   model = "Zynq Z-Turn MYIR Board V5";
+   compatible = "myir,zynq-zturn", "xlnx,zynq-7000";
+
+   aliases {
+   ethernet0 = 
+   serial0 = 
+   serial1 = 
+   mmc0 = 
+   };
+
+   memory@0 {
+   device_type = "memory";
+   reg = <0x0 0x4000>;
+   };
+
+   chosen {
+   stdout-path = "serial0:115200n8";
+   };
+
+   gpio-leds {
+   compatible = "gpio-leds";
+   usr-led1 {
+   label = "usr-led1";
+   gpios = < 0x0 0x1>;
+   default-state = "off";
+   };
+
+   usr-led2 {
+   label = "usr-led2";
+   gpios = < 0x9 0x1>;
+   default-state = "off";
+   };
+   };
+
+   gpio-keys {
+   compatible = "gpio-keys";
+   autorepeat;
+   K1 {
+   label = "K1";
+   gpios = < 0x32 0x1>;
+   linux,code = <0x66>;
+   wakeup-source;
+   autorepeat;
+   };
+   };
+};
+
+ {
+   ps-clk-frequency = <>;
+};
+
+ {
+   u-boot,dm-pre-reloc;
+   status = "okay";
+};
+
+ {
+   status = "okay";
+   phy-mode = "rgmii-id";
+   phy-handle = <_phy>;
+
+   ethernet_phy: ethernet-phy@0 {
+   reg = <0x3>;
+   };
+};
+
+ {
+   u-boot,dm-pre-reloc;
+   status = "okay";
+};
+
+ {
+   u-boot,dm-pre-reloc;
+   status = "okay";
+};
+
+ {
+   u-boot,dm-pre-reloc;
+   status = "okay";
+};
+
+ {
+   status = "okay";
+   dr_mode = "host";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+   clock-frequency = <40>;
+
+   stlm75@49 {
+   status = "okay";
+   compatible = "lm75";
+   reg = <0x49>;
+   };
+
+   accelerometer@53 {
+   compatible = "adi,adxl345", "adxl345", "adi,adxl34x", "adxl34x";
+   reg = <0x53>;
+   interrupt-parent = <>;
+   interrupts = <0x0 0x1e 0x4>;
+   };
+};
diff --git a/board/xilinx/zynq/zynq-zturn-v5/ps7_init_gpl.c 
b/board/xilinx/zynq/zynq-zturn-v5/ps7_init_gpl.c
new file mode 100644
index 00..5d573868cb
--- /dev/null
+++ b/board/xilinx/zynq/zynq-zturn-v5/ps7_init_gpl.c
@@ -0,0 +1,273 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) Xilinx, Inc.
+ */
+
+#include 
+
+static unsigned long ps7_pll_init_data[] = {
+   EMIT_WRITE(0xF808, 0xDF0DU),
+   EMIT_MASKWRITE(0xF8000110, 0x0030U, 0x000FA220U),
+   EMIT_MASKWRITE(0xF8000100, 0x0007F000U, 0x00028000U),
+   EMIT_MASKWRITE(0xF8000100, 0x0010U, 0x0010U),
+   EMIT_MASKWRITE(0xF8000100, 0x0001U, 0x0001U),
+   EMIT_MASKWRITE(0xF8000100, 0x0001U, 0xU),
+   EMIT_MASKPOLL(0xF800010C, 0x0001U),
+   EMIT_MASKWRITE(0xF8000100, 0x0010U, 0xU),
+   EMIT_MASKWRITE(0xF8000120, 0x1F003F30U, 0x1F000200U),
+   EMIT_MASKWRITE(0xF8000114, 0x0030U, 0x0012C220U),
+   EMIT_MASKWRITE(0xF8000104, 0x0007F000U, 0x0002U),
+   EMIT_MASKWRITE(0xF8000104, 

Re: Pull request for UEFI sub-system for efi-2020-10-rc4

2020-09-07 Thread Tom Rini
On Mon, Sep 07, 2020 at 12:10:49PM +0200, Heinrich Schuchardt wrote:

> The following changes since commit e5df264e7aaca0d94428586837a1f70a23479d16:
> 
>   Merge https://gitlab.denx.de/u-boot/custodians/u-boot-marvell
> (2020-09-04 10:09:14 -0400)
> 
> are available in the Git repository at:
> 
>   https://gitlab.denx.de/u-boot/custodians/u-boot-efi.git
> tags/efi-2020-10-rc4
> 
> for you to fetch changes up to d2a885720be6eb66595a26754d075cfd5e868420:
> 
>   efi_selftest: simplify Makefile (2020-09-06 21:21:41 +0200)
> 
> Gitlab CI and Travis CI showed no problems:
> 
> https://gitlab.denx.de/u-boot/custodians/u-boot-efi/-/pipelines/4598
> https://travis-ci.org/github/xypron2/u-boot/builds/724704027
> 

Applied to u-boot/master, thanks!

-- 
Tom


signature.asc
Description: PGP signature


[BUG] rsa: crash in br_i32_decode() called from rsa_gen_key_prop()

2020-09-07 Thread Heinrich Schuchardt
Hello Takahiro,

on the 32bit Wandboard (with i.mx6 CPU) running the lib_asn1_pkcs7 unit
test results in a crash due to an unaligned access occurring when
br_i32_decode() is called by rsa_gen_key_prop().

Please, check the alignment assumptions for src when calling
br_i32_decode(). If src is only 1 byte aligned, you should neither call
be32_to_cpup() nor be16_to_cpup() which assume 32bit and 16bit alignment.


Running lib tests
Running 14 lib tests
Test: lib_asn1_pkcs7
data abort
pc : [<8efb3a8e>]  lr : [<8efb3bbd>]
reloc pc : [<17845a8e>]lr : [<17845bbd>]
sp : 8e561330  ip : 0001 fp : 8efd9d66
r10: 8e58f040  r9 : 8e56dec0 r8 : 8e588748
r7 : 0001  r6 : 8e58f350 r5 : 8e58f350  r4 : 8e58f350
r3 : 00fc  r2 : 0100 r1 : 8e58ee49  r0 : 8e58f350
Flags: nzCv  IRQs off  FIQs off  Mode SVC_32 (T)
Code: ea43 4302 e7a2 3b04 (58c8) ba00
Resetting CPU ...

resetting ...



br_i32_decode():

return be16_to_cpup(src);
17845a84:   b29buxthr3, r3
w = ((uint32_t)buf[0] << 16)
17845a86:   ea43 4302   orr.w   r3, r3, r2, lsl #16
17845a8a:   e7a2b.n 178459d2 
u -= 4;
17845a8c:   3b04subsr3, #4
return __arch__swab32p(x);
17845a8e:   58c8ldr r0, [r1, r3]  <<
17845a90:   ba00rev r0, r0
x[v ++] = br_dec32be(buf + u);
17845a92:   f845 0f04   str.w   r0, [r5, #4]!
if (u < 4) {
17845a96:   e78fb.n 178459b8 
return y ^ (-ctl & (x ^ y));


rsa_gen_key_prop():

/* n0 inverse */
br_i32_decode(n, _key.n[i], rsa_key.n_sz - i);
17845bac:   9910ldr r1, [sp, #64]   ; 0x40
(*prop)->exp_len = sizeof(uint64_t);
17845bae:   615astr r2, [r3, #20]
br_i32_decode(n, _key.n[i], rsa_key.n_sz - i);
17845bb0:   9a18ldr r2, [sp, #96]   ; 0x60
17845bb2:   4439add r1, r7
17845bb4:   1bd2subsr2, r2, r7
17845bb6:   4630mov r0, r6
17845bb8:   f7ff fef9   bl  178459ae  <<
(*prop)->n0inv = br_i32_ninv32(n[1]);
17845bbc:   6873ldr r3, [r6, #4]
17845bbe:   682aldr r2, [r5, #0]
y = 2 - x;
17845bc0:   f1c3 0102   rsb r1, r3, #2



Best regards

Heinrich


Re: [PATCH] time: Fix get_ticks being non-monotonic

2020-09-07 Thread Sean Anderson
On 9/7/20 9:57 AM, Simon Glass wrote:
> Hi Sean,
> 
> On Sun, 6 Sep 2020 at 20:02, Sean Anderson  wrote:
>>
>> On 9/6/20 9:43 PM, Simon Glass wrote:
>>> Hi Sean,
>>>
>>> On Tue, 1 Sep 2020 at 13:56, Sean Anderson  wrote:

 get_ticks does not always succeed. Sometimes it can be called before the
 timer has been initialized. If it does, it returns a negative errno.
 This causes the timer to appear non-monotonic, because the value will
 become much smaller after the timer is initialized.

 No users of get_ticks which I checked handle errors of this kind. Further,
 functions like tick_to_time mangle the result of get_ticks, making it very
 unlikely that one could check for an error without suggesting a patch such
 as this one.

 This patch changes get_ticks to always return 0 when there is an error.
 0 is the least unsigned integer, ensuring get_ticks appears monotonic. This
 has the side effect of time apparently not passing until the timer is
 initialized. However, without this patch, time does not pass anyway,
 because the error value is likely to be the same.

 Fixes: c8a7ba9e6a5
 Signed-off-by: Sean Anderson 
 ---

  lib/time.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)
>>>
>>> Would it be better to panic so people can fix the bug?
>>
>> I thought this was expected behavior. It's only a bug if you do
>> something like udelay before any timers are created. We just can't
>> report errors through get_ticks, because its users assume that it always
>> returns a time of some kind.
> 
> I think it indicates a bug. If you use a device before it is ready you
> don't really know what it will do. I worry that this patch is just
> going to cause confusion, since the behaviour depends on when you call
> it. If we panic, people can figure out why the timer is being inited
> too late, or being used too early.

Hm, maybe. I don't think it's as clear cut as "us[ing] a device before
it is ready," because get_ticks tries to initialize the timer if it
isn't already initialized. Unless someone else does it first, the first
call to get_ticks will always be before the timer is initialized.

The specific problem I ran into was that after relocation, the watchdog
may be initialized before the timer. This occurs on RISC-V because
without [1] a timer only exists after arch_early_init_r. So, for the
first few calls to watchdog_reset there is no timer.
 
The second return could probably be turned into a panic. I checked, and
all current timer drivers always succeed in getting the time (except for
the RISC-V timer, which is fixed in [1]), so the only way for
timer_get_count to fail is if timer_ops.get_count doesn't exist. That is
almost certainly an error on the driver author's part, so I think
panicking there is the only reasonable option.

(Does get_count even need to have a return value? I think it's
reasonable to always expect the timer to return a value.)

--Sean

[1] https://patchwork.ozlabs.org/project/uboot/list/?series=198797


Re: [PATCH 0/5] edison: Support for writing an xFSTK image

2020-09-07 Thread Andy Shevchenko
On Mon, Sep 07, 2020 at 08:15:13AM -0600, Simon Glass wrote:
> On Mon, 7 Sep 2020 at 08:12, Tom Rini  wrote:
> > On Mon, Sep 07, 2020 at 07:57:12AM -0600, Simon Glass wrote:

...

> > On a tangent, when it comes to lab stuff I picked up
> > https://www.yepkit.com/products/ykush a while back precisely for "device
> > can be USB powered on purpose/accident" in order to have
> > software-controlled USB ports I can bring up/down.
> 
> Actually that's very relevant. I did try that with Edison and it
> definitely does power off the board now. I keep thinking with just a
> bit more messing around I can nut it out. My first board turned out to
> have a problem with the slider switch which could have been part of
> the issue.

Btw, seems you are using Edison/Arduino one. It has more (electrical) issues
that slider switch and so. I would recommend rather to buy another base board
for it, like SparkFun or DFRobot (I recently bought the latter one, i.e. IO
Expander for Intel Edison, and it works nicely, but I didn't check xFSTK
extensively, only DFU).

-- 
With Best Regards,
Andy Shevchenko




Re: [RFC PATCH 0/7]

2020-09-07 Thread Etienne Carriere
On Fri, 4 Sep 2020 at 14:25, Ard Biesheuvel  wrote:
>
> On Fri, 4 Sep 2020 at 13:51, Patrick Delaunay  wrote:
> >
> > arm: cache: cp15: don't map reserved region with no-map property
> >
> > Hi,
> >
> > On STM32MP15x platform we can use OP-TEE, loaded in DDR in a region 
> > protected
> > by a firewall. This region is reserved in device with "no-map" property.
> >
> > But sometime the platform boot failed in U-boot on a Cortex A7 access to 
> > this
> > region (depending of the binary and the issue can change with compiler 
> > version or
> > with code alignment), then the firewall raise a error, for example:
> >
> > E/TC:0   tzc_it_handler:19 TZC permission failure
> > E/TC:0   dump_fail_filter:420 Permission violation on filter 0
> > E/TC:0   dump_fail_filter:425 Violation @0xde5c6bf0, non-secure privileged 
> > read, AXI ID 5c0
> > E/TC:0   Panic
> >
> > After investigation, the forbidden access is a speculative request 
> > performed by
> > the Cortex A7 because all the DDR is mapped as MEMORY with CACHEABLE 
> > property.
> >
> > The issue is solved only when the region reserved by OP-TEE is no more 
> > mapped
> > in U-Boot (mapped as DEVICE/NON-CACHEABLE wasn't enough) as it is already 
> > done
> > in Linux kernel.
> >
>
> The only speculative accesses to such regions permitted by the
> architecture are instruction fetches, which is why setting the nx
> attribute is required on v7 for device mappings.
>
> Does uboot currently honour this requirement?

I think current U-Boot honours the speculative side by using a IO memory
default mapping strategy. If the reserved memory is used by a driver
with a specific
mapping, u-boot cannot ensure the mapping won't conflict with default mapping.
For example OP-TEE defines a portion of this memory as non-secure
cached shared memory.
With Arm, we cannot map an area both as cached memory and as IO memory
(Device/StronglyOrdered).
So here, using a not-mapped strategy for "no-map" property looks better.

Regards,
Etienne

>
>
> > I think that can be a general issue for ARM architecture: the no-map tag in
> > device should be respected by U-boot, so I propose a  generic solution in
> > arm/lib/cache-cp15.c:dram_bank_mmu_setup().
> >
> > This RFC serie is composed by 7 patches
> > - 1..4/7: preliminary steps to support flags in library in lmb
> >   (as it is done in memblock.c in Linux)
> > - 5/7: unitary test on the added feature in lmb lib
> > - 6/7: save the no-map flags in lmb when the device tree is parsed
> > - 7/7: update the generic behavior for "no-map" region in
> >arm/lib/cache-cp15.c::dram_bank_mmu_setup()
> >
> > I can change this last patch if it is required by other ARM architecture;
> > it is a weak function so I can avoid to map the region with "no-map"
> > property in device tree only for STM32MP architecture
> > (in arch/arm/mach-stm32mp/cpu.c).
> >
> > See also [1] which handle same speculative access on armv8 for area
> > with Executable attribute.
> >
> > [1] 
> > http://patchwork.ozlabs.org/project/uboot/patch/20200903000106.5016-1-marek.bykow...@gmail.com/
> >
> > Regards
> > Patrick
> >
> >
> > Patrick Delaunay (7):
> >   lmb: Add support of flags for no-map properties
> >   lmb: add lmb_is_reserved_flags
> >   lmb: remove lmb_region.size
> >   lmb: add lmb_dump_region() function
> >   test: lmb: add test for lmb_reserve_flags
> >   image-fdt: save no-map parameter of reserve-memory
> >   arm: cache: cp15: don't map the reserved region with no-map property
> >
> >  arch/arm/include/asm/system.h |   3 +
> >  arch/arm/lib/cache-cp15.c |  17 +-
> >  common/image-fdt.c|  23 +---
> >  include/lmb.h |  22 +++-
> >  lib/lmb.c | 100 +++---
> >  test/lib/lmb.c|  89 ++
> >  6 files changed, 210 insertions(+), 44 deletions(-)
> >
> > --
> > 2.17.1
> >


[PATCH v3 5/8] clk: add clock driver for SCMI agents

2020-09-07 Thread Etienne Carriere
This change introduces a clock driver for SCMI agent devices. When
SCMI agent and SCMI clock drivers are enabled, SCMI agent binds a
clock device for each SCMI clock protocol devices enabled in the FDT.

SCMI clock driver is embedded upon CONFIG_CLK_SCMI=y. If enabled,
CONFIG_SCMI_AGENT is also enabled.

SCMI Clock protocol is defined in the SCMI specification [1].

Links: [1] 
https://developer.arm.com/architectures/system-architectures/software-standards/scmi
Signed-off-by: Etienne Carriere 
Cc: Lukasz Majewski 
Cc: Simon Glass 
Cc: Peng Fan 
Cc: Sudeep Holla 
---

Changes in v3:

Changes in v2:
- CONFIG_CLK_SCMI depends on CONFIG_SCMI_FIRMWARE instead of
  selecting CONFIG_SCMI_FIRMWARE.
- Add inline comment description for structures and moves them to
  source file top. Add/fixup some functions inline description comments.
- Replace rc with ret as return value local variable label.
- Fix scmi_clk_get_rate() return value to propagate error number.
- Fix scmi_clk_set_rate() to request synchronous rate set operation:
  drop flag SCMI_CLK_RATE_ASYNC_NORESP in the SCMI message payload.
- Fix scmi_clk_set_rate() return value to return clock effective rate
  on success.
---
 drivers/clk/Kconfig   |  8 ++
 drivers/clk/Makefile  |  1 +
 drivers/clk/clk_scmi.c| 99 +++
 drivers/firmware/scmi/scmi_agent-uclass.c |  3 +
 include/scmi_protocols.h  | 78 ++
 5 files changed, 189 insertions(+)
 create mode 100644 drivers/clk/clk_scmi.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 6003e140b5..4dfbad7986 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -159,6 +159,14 @@ config CLK_CDCE9XX
   Enable the clock synthesizer driver for CDCE913/925/937/949
   series of chips.
 
+config CLK_SCMI
+   bool "Enable SCMI clock driver"
+   depends on SCMI_FIRMWARE
+   help
+ Enable this option if you want to support clock devices exposed
+ by a SCMI agent based on SCMI clock protocol communication
+ with a SCMI server.
+
 source "drivers/clk/analogbits/Kconfig"
 source "drivers/clk/at91/Kconfig"
 source "drivers/clk/exynos/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index cda4b4b605..d1e295ac7c 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_CLK_MPC83XX) += mpc83xx_clk.o
 obj-$(CONFIG_CLK_OCTEON) += clk_octeon.o
 obj-$(CONFIG_CLK_OWL) += owl/
 obj-$(CONFIG_CLK_RENESAS) += renesas/
+obj-$(CONFIG_CLK_SCMI) += clk_scmi.o
 obj-$(CONFIG_CLK_SIFIVE) += sifive/
 obj-$(CONFIG_ARCH_SUNXI) += sunxi/
 obj-$(CONFIG_CLK_STM32F) += clk_stm32f.o
diff --git a/drivers/clk/clk_scmi.c b/drivers/clk/clk_scmi.c
new file mode 100644
index 00..93a4819501
--- /dev/null
+++ b/drivers/clk/clk_scmi.c
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019-2020 Linaro Limited
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static int scmi_clk_gate(struct clk *clk, int enable)
+{
+   struct scmi_clk_state_in in = {
+   .clock_id = clk->id,
+   .attributes = enable,
+   };
+   struct scmi_clk_state_out out;
+   struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK,
+ SCMI_CLOCK_CONFIG_SET,
+ in, out);
+   int ret;
+
+   ret = devm_scmi_process_msg(clk->dev->parent, );
+   if (ret)
+   return ret;
+
+   return scmi_to_linux_errno(out.status);
+}
+
+static int scmi_clk_enable(struct clk *clk)
+{
+   return scmi_clk_gate(clk, 1);
+}
+
+static int scmi_clk_disable(struct clk *clk)
+{
+   return scmi_clk_gate(clk, 0);
+}
+
+static ulong scmi_clk_get_rate(struct clk *clk)
+{
+   struct scmi_clk_rate_get_in in = {
+   .clock_id = clk->id,
+   };
+   struct scmi_clk_rate_get_out out;
+   struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK,
+ SCMI_CLOCK_RATE_GET,
+ in, out);
+   int ret;
+
+   ret = devm_scmi_process_msg(clk->dev->parent, );
+   if (ret < 0)
+   return ret;
+
+   ret = scmi_to_linux_errno(out.status);
+   if (ret < 0)
+   return ret;
+
+   return (ulong)(((u64)out.rate_msb << 32) | out.rate_lsb);
+}
+
+static ulong scmi_clk_set_rate(struct clk *clk, ulong rate)
+{
+   struct scmi_clk_rate_set_in in = {
+   .clock_id = clk->id,
+   .flags = SCMI_CLK_RATE_ROUND_CLOSEST,
+   .rate_lsb = (u32)rate,
+   .rate_msb = (u32)((u64)rate >> 32),
+   };
+   struct scmi_clk_rate_set_out out;
+   struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK,
+ SCMI_CLOCK_RATE_SET,
+ in, out);
+   int 

[PATCH v3 6/8] firmware: scmi: sandbox test for SCMI clocks

2020-09-07 Thread Etienne Carriere
Add tests for SCMI clocks. A test device driver sandbox-scmi_devices.c
is used to get clock resources, allowing further clock manipulation.

Change sandbox-smci_agent to emulate 3 clocks exposed through 2 agents.
Add DM test scmi_clocks to test these 3 clocks.
Update DM test sandbox_scmi_agent with load/remove test sequences
factorized by {load|remove}_sandbox_scmi_test_devices() helper functions.

Signed-off-by: Etienne Carriere 
Cc: Simon Glass 
Cc: Peng Fan 
Cc: Sudeep Holla 
---

Changes in v3:
- New commit in the series, addresses review comments on test support.
  ut_dm_scmi_clocks test SCMI are found and behave as expected for the
  implemented clk uclass methods.
---
 arch/sandbox/dts/test.dts|  15 ++
 arch/sandbox/include/asm/scmi_test.h |  37 
 configs/sandbox_defconfig|   1 +
 drivers/firmware/scmi/Makefile   |   2 +-
 drivers/firmware/scmi/sandbox-scmi_agent.c   | 169 ++-
 drivers/firmware/scmi/sandbox-scmi_devices.c |  86 ++
 test/dm/scmi.c   | 139 ++-
 7 files changed, 438 insertions(+), 11 deletions(-)
 create mode 100644 drivers/firmware/scmi/sandbox-scmi_devices.c

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index dd3b43885e..61acd8d79f 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -361,6 +361,11 @@
compatible = "sandbox,scmi-agent";
#address-cells = <1>;
#size-cells = <0>;
+
+   clk_scmi0: protocol@14 {
+   reg = <0x14>;
+   #clock-cells = <1>;
+   };
};
 
sandbox-scmi-agent@1 {
@@ -368,6 +373,11 @@
#address-cells = <1>;
#size-cells = <0>;
 
+   clk_scmi1: protocol@14 {
+   reg = <0x14>;
+   #clock-cells = <1>;
+   };
+
protocol@10 {
reg = <0x10>;
};
@@ -1052,6 +1062,11 @@
compatible = "sandbox,virtio2";
};
 
+   sandbox_scmi {
+   compatible = "sandbox,scmi-devices";
+   clocks = <_scmi0 7>, <_scmi0 3>, <_scmi1 1>;
+   };
+
pinctrl {
compatible = "sandbox,pinctrl";
 
diff --git a/arch/sandbox/include/asm/scmi_test.h 
b/arch/sandbox/include/asm/scmi_test.h
index a811fe19c3..4e09957bc7 100644
--- a/arch/sandbox/include/asm/scmi_test.h
+++ b/arch/sandbox/include/asm/scmi_test.h
@@ -10,12 +10,28 @@ struct udevice;
 struct sandbox_scmi_agent;
 struct sandbox_scmi_service;
 
+/**
+ * struct sandbox_scmi_clk - Simulated clock exposed by SCMI
+ * @id:Identifier of the clock used in the SCMI protocol
+ * @enabled:   Clock state: true if enabled, false if disabled
+ * @rate:  Clock rate in Hertz
+ */
+struct sandbox_scmi_clk {
+   uint id;
+   bool enabled;
+   ulong rate;
+};
+
 /**
  * struct sandbox_scmi_agent - Simulated SCMI service seen by SCMI agent
  * @idx:   Identifier for the SCMI agent, its index
+ * @clk:   Simulated clocks
+ * @clk_count: Simulated clocks array size
  */
 struct sandbox_scmi_agent {
uint idx;
+   struct sandbox_scmi_clk *clk;
+   size_t clk_count;
 };
 
 /**
@@ -28,16 +44,37 @@ struct sandbox_scmi_service {
size_t agent_count;
 };
 
+/**
+ * struct sandbox_scmi_devices - Reference to devices probed through SCMI
+ * @clk:   Array the clock devices
+ * @clk_count: Number of clock devices probed
+ */
+struct sandbox_scmi_devices {
+   struct clk *clk;
+   size_t clk_count;
+};
+
 #ifdef CONFIG_SCMI_FIRMWARE
 /**
  * sandbox_scmi_service_context - Get the simulated SCMI services context
  * @return:Reference to backend simulated resources state
  */
 struct sandbox_scmi_service *sandbox_scmi_service_ctx(void);
+
+/**
+ * sandbox_scmi_devices_get_ref - Get references to devices accessed through 
SCMI
+ * @return:Reference to the devices probed by the SCMI test
+ */
+struct sandbox_scmi_devices *sandbox_scmi_devices_ctx(void);
 #else
 static inline struct sandbox_scmi_service *sandbox_scmi_service_ctx(void)
 {
return NULL;
 }
+
+static inline struct sandbox_scmi_devices *sandbox_scmi_devices_ctx(void)
+{
+   return NULL;
+}
 #endif /* CONFIG_SCMI_FIRMWARE */
 #endif /* __SANDBOX_SCMI_TEST_H */
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 2c130c01f0..7d71c805dc 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -122,6 +122,7 @@ CONFIG_BUTTON=y
 CONFIG_BUTTON_GPIO=y
 CONFIG_CLK=y
 CONFIG_CLK_COMPOSITE_CCF=y
+CONFIG_CLK_SCMI=y
 CONFIG_SANDBOX_CLK_CCF=y
 CONFIG_CPU=y
 CONFIG_DM_DEMO=y
diff --git a/drivers/firmware/scmi/Makefile 

[PATCH v3 7/8] reset: add reset controller driver for SCMI agents

2020-09-07 Thread Etienne Carriere
This change introduces a reset controller driver for SCMI agent devices.
When SCMI agent and SCMI reset domain drivers are enabled, SCMI agent
binds a reset controller device for each SCMI reset domain protocol
devices enabled in the FDT.

SCMI reset driver is embedded upon CONFIG_RESET_SCMI=y. If enabled,
CONFIG_SCMI_AGENT is also enabled.

SCMI Reset Domain protocol is defined in the SCMI specification [1].

Links: [1] 
https://developer.arm.com/architectures/system-architectures/software-standards/scmi
Signed-off-by: Etienne Carriere 
Cc: Simon Glass 
Cc: Peng Fan 
Cc: Sudeep Holla 
---

Changes in v3:
- Upgrade to rename into devm_scmi_process_msg() and scmi.h split
  into scmi_*.h.
- Fix message ID used in scmi_reset_request().

Changes in v2:
- Change reset request() method to at least check the reset domain
  exists by sending a SCMI RESET_DOMAIN_ATTRIBUTE message.
- Add inline description for the several structures.
- Patch v1 R-b tag not applied since the above changes in this v2.

BACKPORTED FROM v2020.10-rc2 to V2020.04
---
 drivers/firmware/scmi/scmi_agent-uclass.c |  3 +
 drivers/reset/Kconfig |  8 +++
 drivers/reset/Makefile|  1 +
 drivers/reset/reset-scmi.c| 81 +++
 include/scmi_protocols.h  | 60 +
 5 files changed, 153 insertions(+)
 create mode 100644 drivers/reset/reset-scmi.c

diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c 
b/drivers/firmware/scmi/scmi_agent-uclass.c
index e1694eff3d..54f798318f 100644
--- a/drivers/firmware/scmi/scmi_agent-uclass.c
+++ b/drivers/firmware/scmi/scmi_agent-uclass.c
@@ -73,6 +73,9 @@ static int scmi_bind_protocols(struct udevice *dev)
case SCMI_PROTOCOL_ID_CLOCK:
drv = DM_GET_DRIVER(scmi_clock);
break;
+   case SCMI_PROTOCOL_ID_RESET_DOMAIN:
+   drv = DM_GET_DRIVER(scmi_reset_domain);
+   break;
default:
dev_info(dev, "Ignore unsupported SCMI protocol %#x\n",
 protocol_id);
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 253902ff57..ee5be0bc2f 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -173,4 +173,12 @@ config RESET_RASPBERRYPI
  relevant. This driver provides a reset controller capable of
  interfacing with RPi4's co-processor and model these firmware
  initialization routines as reset lines.
+
+config RESET_SCMI
+   bool "Enable SCMI reset domain driver"
+   select SCMI_FIRMWARE
+   help
+ Enable this option if you want to support reset controller
+ devices exposed by a SCMI agent based on SCMI reset domain
+ protocol communication with a SCMI server.
 endmenu
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 3c7f066ae3..625ec7168e 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -26,3 +26,4 @@ obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
 obj-$(CONFIG_RESET_SIFIVE) += reset-sifive.o
 obj-$(CONFIG_RESET_SYSCON) += reset-syscon.o
 obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o
+obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
diff --git a/drivers/reset/reset-scmi.c b/drivers/reset/reset-scmi.c
new file mode 100644
index 00..1bff8075ee
--- /dev/null
+++ b/drivers/reset/reset-scmi.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019-2020 Linaro Limited
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static int scmi_reset_set_level(struct reset_ctl *rst, bool 
assert_not_deassert)
+{
+   struct scmi_rd_reset_in in = {
+   .domain_id = rst->id,
+   .flags = assert_not_deassert ? SCMI_RD_RESET_FLAG_ASSERT : 0,
+   .reset_state = 0,
+   };
+   struct scmi_rd_reset_out out;
+   struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_RESET_DOMAIN,
+ SCMI_RESET_DOMAIN_RESET,
+ in, out);
+   int ret;
+
+   ret = devm_scmi_process_msg(rst->dev->parent, );
+   if (ret)
+   return ret;
+
+   return scmi_to_linux_errno(out.status);
+}
+
+static int scmi_reset_assert(struct reset_ctl *rst)
+{
+   return scmi_reset_set_level(rst, true);
+}
+
+static int scmi_reset_deassert(struct reset_ctl *rst)
+{
+   return scmi_reset_set_level(rst, false);
+}
+
+static int scmi_reset_request(struct reset_ctl *rst)
+{
+   struct scmi_rd_attr_in in = {
+   .domain_id = rst->id,
+   };
+   struct scmi_rd_attr_out out;
+   struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_RESET_DOMAIN,
+ SCMI_RESET_DOMAIN_ATTRIBUTES,
+ in, out);
+   int ret;
+
+   /*
+* We don't really care about the attribute, just 

[PATCH v3 8/8] firmware: smci: sandbox test for SCMI reset controllers

2020-09-07 Thread Etienne Carriere
Add tests for SCMI reset controllers. A test device driver
sandbox-scmi_devices.c is used to get reset resources, allowing further
resets manipulation.

Change sandbox-smci_agent to emulate 1 reset controller exposed through
an agent. Add DM test scmi_resets to test this reset controller.

Signed-off-by: Etienne Carriere 
Cc: Simon Glass 
Cc: Peng Fan 
Cc: Sudeep Holla 
---

Changes in v3:
- New commit in the series, addresses review comments on test support.
  ut_dm_scmi_resets() tests SCMI resources are found and behave as
  expected for the implemented reset uclass methods.
---
 arch/sandbox/dts/test.dts|   6 +
 arch/sandbox/include/asm/scmi_test.h |  17 +++
 configs/sandbox_defconfig|   1 +
 drivers/firmware/scmi/sandbox-scmi_agent.c   | 117 ++-
 drivers/firmware/scmi/sandbox-scmi_devices.c |  30 -
 test/dm/scmi.c   |  35 ++
 6 files changed, 200 insertions(+), 6 deletions(-)

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 61acd8d79f..7023f33a67 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -366,6 +366,11 @@
reg = <0x14>;
#clock-cells = <1>;
};
+
+   reset_scmi0: protocol@16 {
+   reg = <0x16>;
+   #reset-cells = <1>;
+   };
};
 
sandbox-scmi-agent@1 {
@@ -1065,6 +1070,7 @@
sandbox_scmi {
compatible = "sandbox,scmi-devices";
clocks = <_scmi0 7>, <_scmi0 3>, <_scmi1 1>;
+   resets = <_scmi0 3>;
};
 
pinctrl {
diff --git a/arch/sandbox/include/asm/scmi_test.h 
b/arch/sandbox/include/asm/scmi_test.h
index 4e09957bc7..de3b2bbcc2 100644
--- a/arch/sandbox/include/asm/scmi_test.h
+++ b/arch/sandbox/include/asm/scmi_test.h
@@ -22,16 +22,29 @@ struct sandbox_scmi_clk {
ulong rate;
 };
 
+/**
+ * struct sandbox_scmi_reset - Simulated reset controller exposed by SCMI
+ * @asserted:  Reset control state: true if asserted, false if desasserted
+ */
+struct sandbox_scmi_reset {
+   uint id;
+   bool asserted;
+};
+
 /**
  * struct sandbox_scmi_agent - Simulated SCMI service seen by SCMI agent
  * @idx:   Identifier for the SCMI agent, its index
  * @clk:   Simulated clocks
  * @clk_count: Simulated clocks array size
+ * @clk:   Simulated reset domains
+ * @clk_count: Simulated reset domains array size
  */
 struct sandbox_scmi_agent {
uint idx;
struct sandbox_scmi_clk *clk;
size_t clk_count;
+   struct sandbox_scmi_reset *reset;
+   size_t reset_count;
 };
 
 /**
@@ -48,10 +61,14 @@ struct sandbox_scmi_service {
  * struct sandbox_scmi_devices - Reference to devices probed through SCMI
  * @clk:   Array the clock devices
  * @clk_count: Number of clock devices probed
+ * @reset: Array the reset controller devices
+ * @reset_count:   Number of reset controller devices probed
  */
 struct sandbox_scmi_devices {
struct clk *clk;
size_t clk_count;
+   struct reset_ctl *reset;
+   size_t reset_count;
 };
 
 #ifdef CONFIG_SCMI_FIRMWARE
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 7d71c805dc..a2ebb3c971 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -220,6 +220,7 @@ CONFIG_REMOTEPROC_SANDBOX=y
 CONFIG_DM_RESET=y
 CONFIG_SANDBOX_RESET=y
 CONFIG_RESET_SYSCON=y
+CONFIG_RESET_SCMI=y
 CONFIG_DM_RNG=y
 CONFIG_DM_RTC=y
 CONFIG_RTC_RV8803=y
diff --git a/drivers/firmware/scmi/sandbox-scmi_agent.c 
b/drivers/firmware/scmi/sandbox-scmi_agent.c
index 262efbd12c..01843a9827 100644
--- a/drivers/firmware/scmi/sandbox-scmi_agent.c
+++ b/drivers/firmware/scmi/sandbox-scmi_agent.c
@@ -18,19 +18,20 @@
  * processing. It simulates few of the SCMI services for some of the
  * SCMI protocols embedded in U-Boot. Currently:
  * - SCMI clock protocol: emulate 2 agents each exposing few clocks
+ * - SCMI reset protocol: emulate 1 agents each exposing a reset
  *
- * Agent #0 simulates 2 clocks.
- * See IDs in scmi0_clk[] and "sandbox-scmi-agent@0" in test.dts.
+ * Agent #0 simulates 2 clocks and 1 reset domain.
+ * See IDs in scmi0_clk[]/scmi0_reset[] and "sandbox-scmi-agent@0" in test.dts.
  *
  * Agent #1 simulates 1 clock.
  * See IDs in scmi1_clk[] and "sandbox-scmi-agent@1" in test.dts.
  *
- * All clocks are default disabled.
+ * All clocks are default disabled and reset levels down.
  *
  * This Driver exports sandbox_scmi_service_ct() for the test sequence to
  * get the state of the simulated services (clock state, rate, ...) and
  * check back-end device state reflects the request send through the
- * various uclass devices, currently only clock controllers.
+ * various uclass devices, as clocks and reset controllers.
  */
 
 #define 

[PATCH v3 3/8] firmware: scmi: support Arm SMCCC transport

2020-09-07 Thread Etienne Carriere
This change implements a SMCCC transport for SCMI exchanges. This
implementation follows the Linux kernel as references implementation
for SCMI message processing, using the SMT format for communication
channel meta-data.

Use of SMCCC transport in SCMI FDT bindings are defined in the Linux
kernel DT bindings since v5.8. SMCCC with SMT is implemented in OP-TEE
from tag 3.9.0 [2].

Links: [2] https://github.com/OP-TEE/optee_os/commit/a58c4d706d23
Signed-off-by: Etienne Carriere 
Cc: Simon Glass 
Cc: Peng Fan 
Cc: Sudeep Holla 
---

Changes in v3:
- This is a followup of the SCMI agent patches posted in
  https://patchwork.ozlabs.org/project/uboot/list/?series=196253
  The v3 splits commits and introduces a new uclass as requested.
- This patch implements the same Arm SMCCC SCMI agent as presented
  in v2 but in its own source file smccc_agent.c, and based in smt.h.
---
 drivers/firmware/scmi/Kconfig   |  4 +-
 drivers/firmware/scmi/Makefile  |  1 +
 drivers/firmware/scmi/smccc_agent.c | 95 +
 3 files changed, 98 insertions(+), 2 deletions(-)
 create mode 100644 drivers/firmware/scmi/smccc_agent.c

diff --git a/drivers/firmware/scmi/Kconfig b/drivers/firmware/scmi/Kconfig
index c501bf4943..335d09c821 100644
--- a/drivers/firmware/scmi/Kconfig
+++ b/drivers/firmware/scmi/Kconfig
@@ -15,5 +15,5 @@ config SCMI_FIRMWARE
 
  Communications between agent (client) and the SCMI server are
  based on message exchange. Messages can be exchange over tranport
- channels as a mailbox device with some piece of identified shared
- memory.
+ channels as a mailbox device or an Arm SMCCC service with some
+ piece of identified shared memory.
diff --git a/drivers/firmware/scmi/Makefile b/drivers/firmware/scmi/Makefile
index d22f53efe7..2f782bbd55 100644
--- a/drivers/firmware/scmi/Makefile
+++ b/drivers/firmware/scmi/Makefile
@@ -1,4 +1,5 @@
 obj-y  += scmi_agent-uclass.o
 obj-y  += smt.o
+obj-$(CONFIG_ARM_SMCCC)+= smccc_agent.o
 obj-$(CONFIG_DM_MAILBOX)   += mailbox_agent.o
 obj-$(CONFIG_SANDBOX)  += sandbox-scmi_agent.o
diff --git a/drivers/firmware/scmi/smccc_agent.c 
b/drivers/firmware/scmi/smccc_agent.c
new file mode 100644
index 00..90707710e2
--- /dev/null
+++ b/drivers/firmware/scmi/smccc_agent.c
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Linaro Limited.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include "smt.h"
+
+#define SMCCC_RET_NOT_SUPPORTED ((unsigned long)-1)
+
+/**
+ * struct scmi_smccc_channel - Description of an SCMI SMCCC transport
+ * @func_id:   SMCCC function ID used by the SCMI transport
+ * @smt:   Shared memory buffer
+ */
+struct scmi_smccc_channel {
+   ulong func_id;
+   struct scmi_smt smt;
+};
+
+static struct scmi_smccc_channel *scmi_smccc_get_priv(struct udevice *dev)
+{
+   return (struct scmi_smccc_channel *)dev_get_priv(dev);
+}
+
+static int scmi_smccc_process_msg(struct udevice *dev, struct scmi_msg *msg)
+{
+   struct scmi_smccc_channel *chan = scmi_smccc_get_priv(dev);
+   struct arm_smccc_res res;
+   int ret;
+
+   ret = scmi_write_msg_to_smt(dev, >smt, msg);
+   if (ret)
+   return ret;
+
+   arm_smccc_smc(chan->func_id, 0, 0, 0, 0, 0, 0, 0, );
+   if (res.a0 == SMCCC_RET_NOT_SUPPORTED)
+   ret = -ENXIO;
+   else
+   ret = scmi_read_resp_from_smt(dev, >smt, msg);
+
+   scmi_clear_smt_channel(>smt);
+
+   return ret;
+}
+
+static int scmi_smccc_probe(struct udevice *dev)
+{
+   struct scmi_smccc_channel *chan = scmi_smccc_get_priv(dev);
+   u32 func_id;
+   int ret;
+
+   if (dev_read_u32(dev, "arm,smc-id", _id)) {
+   dev_err(dev, "Missing property func-id\n");
+   return -EINVAL;
+   }
+
+   chan->func_id = func_id;
+
+   ret = scmi_dt_get_smt_buffer(dev, >smt);
+   if (ret) {
+   dev_err(dev, "Failed to get smt resources: %d\n", ret);
+   return ret;
+   }
+
+   return 0;
+}
+
+static const struct udevice_id scmi_smccc_ids[] = {
+   { .compatible = "arm,scmi-smc" },
+   { }
+};
+
+static const struct scmi_agent_ops scmi_smccc_ops = {
+   .process_msg = scmi_smccc_process_msg,
+};
+
+U_BOOT_DRIVER(scmi_smccc) = {
+   .name   = "scmi-over-smccc",
+   .id = UCLASS_SCMI_AGENT,
+   .of_match   = scmi_smccc_ids,
+   .priv_auto_alloc_size = sizeof(struct scmi_smccc_channel),
+   .probe  = scmi_smccc_probe,
+   .ops= _smccc_ops,
+};
-- 
2.17.1



[PATCH v3 4/8] dt-bindings: arm: SCMI bindings documentation

2020-09-07 Thread Etienne Carriere
Dump SCMI DT bindings documentation from Linux kernel source
tree v5.8-rc1.

Signed-off-by: Etienne Carriere 
Reviewed-by: Simon Glass 
---
No change in v3.

Changes in v2:
- No change but added R-b tag.
- Yet a question: do we need to add this binding doc in U-Boot
  since already existing in Linux DT bindings docs? Related to review
  comment https://www.mail-archive.com/u-boot@lists.denx.de/msg377725.html
---
 doc/device-tree-bindings/arm/arm,scmi.txt | 197 ++
 1 file changed, 197 insertions(+)
 create mode 100644 doc/device-tree-bindings/arm/arm,scmi.txt

diff --git a/doc/device-tree-bindings/arm/arm,scmi.txt 
b/doc/device-tree-bindings/arm/arm,scmi.txt
new file mode 100644
index 00..1f293ea24c
--- /dev/null
+++ b/doc/device-tree-bindings/arm/arm,scmi.txt
@@ -0,0 +1,197 @@
+System Control and Management Interface (SCMI) Message Protocol
+--
+
+The SCMI is intended to allow agents such as OSPM to manage various functions
+that are provided by the hardware platform it is running on, including power
+and performance functions.
+
+This binding is intended to define the interface the firmware implementing
+the SCMI as described in ARM document number ARM DEN 0056A ("ARM System Control
+and Management Interface Platform Design Document")[0] provide for OSPM in
+the device tree.
+
+Required properties:
+
+The scmi node with the following properties shall be under the /firmware/ node.
+
+- compatible : shall be "arm,scmi" or "arm,scmi-smc" for smc/hvc transports
+- mboxes: List of phandle and mailbox channel specifiers. It should contain
+ exactly one or two mailboxes, one for transmitting messages("tx")
+ and another optional for receiving the notifications("rx") if
+ supported.
+- shmem : List of phandle pointing to the shared memory(SHM) area as per
+ generic mailbox client binding.
+- #address-cells : should be '1' if the device has sub-nodes, maps to
+ protocol identifier for a given sub-node.
+- #size-cells : should be '0' as 'reg' property doesn't have any size
+ associated with it.
+- arm,smc-id : SMC id required when using smc or hvc transports
+
+Optional properties:
+
+- mbox-names: shall be "tx" or "rx" depending on mboxes entries.
+
+See Documentation/devicetree/bindings/mailbox/mailbox.txt for more details
+about the generic mailbox controller and client driver bindings.
+
+The mailbox is the only permitted method of calling the SCMI firmware.
+Mailbox doorbell is used as a mechanism to alert the presence of a
+messages and/or notification.
+
+Each protocol supported shall have a sub-node with corresponding compatible
+as described in the following sections. If the platform supports dedicated
+communication channel for a particular protocol, the 3 properties namely:
+mboxes, mbox-names and shmem shall be present in the sub-node corresponding
+to that protocol.
+
+Clock/Performance bindings for the clocks/OPPs based on SCMI Message Protocol
+
+
+This binding uses the common clock binding[1].
+
+Required properties:
+- #clock-cells : Should be 1. Contains the Clock ID value used by SCMI 
commands.
+
+Power domain bindings for the power domains based on SCMI Message Protocol
+
+
+This binding for the SCMI power domain providers uses the generic power
+domain binding[2].
+
+Required properties:
+ - #power-domain-cells : Should be 1. Contains the device or the power
+domain ID value used by SCMI commands.
+
+Sensor bindings for the sensors based on SCMI Message Protocol
+--
+SCMI provides an API to access the various sensors on the SoC.
+
+Required properties:
+- #thermal-sensor-cells: should be set to 1. This property follows the
+thermal device tree bindings[3].
+
+Valid cell values are raw identifiers (Sensor ID)
+as used by the firmware. Refer to  platform details
+for your implementation for the IDs to use.
+
+Reset signal bindings for the reset domains based on SCMI Message Protocol
+
+
+This binding for the SCMI reset domain providers uses the generic reset
+signal binding[5].
+
+Required properties:
+ - #reset-cells : Should be 1. Contains the reset domain ID value used
+ by SCMI commands.
+
+SRAM and Shared Memory for SCMI
+---
+
+A small area of SRAM is reserved for SCMI communication between application
+processors and SCP.
+
+The properties should follow the generic mmio-sram description found in [4]
+
+Each sub-node represents the reserved area for SCMI.
+
+Required sub-node properties:
+- reg : The base offset and size of the reserved area with the SRAM
+- 

[PATCH v3 1/8] firmware: add SCMI agent uclass

2020-09-07 Thread Etienne Carriere
This change introduces SCMI agent uclass to interact with a firmware
using the SCMI protocols [1].

SCMI agent uclass currently supports a single method to request
processing of the SCMI message by an identified server. A SCMI message
is made of a byte payload associated to a protocol ID and a message ID,
all defined by the SCMI specification [1]. On return from process_msg()
method, the caller gets the service response.

SCMI agent uclass defines a post bind generic sequence for all devices.
The sequence binds all the SCMI protocols listed in the FDT for that
SCMI agent device. Currently none, but later change will introduce
protocols.

This change implements a simple sandbox device for the SCMI agent uclass.
The sandbox nicely answers SCMI_NOT_SUPPORTED to SCMI messages.
To prepare for further test support, the sandbox exposes a architecture
function for test application to read the sandbox emulated devices state.
Currently supports 2 SCMI agents, identified by an ID in the FDT device
name. The simplistic DM test does nothing yet.

SCMI agent uclass is designed for platforms that embed a SCMI server in
a firmware hosted somewhere, for example in a companion co-processor or
in the secure world of the executing processor. SCMI protocols allow an
SCMI agent to discover and access external resources as clock, reset
controllers and more. SCMI agent and server communicate following the
SCMI specification [1]. This SCMI agent implementation complies with
the DT bindings defined in the Linux kernel source tree regarding
SCMI agent description since v5.8.

Links: [1] 
https://developer.arm.com/architectures/system-architectures/software-standards/scmi
Signed-off-by: Etienne Carriere 
Cc: Simon Glass 
Cc: Peng Fan 
Cc: Sudeep Holla 
---

Changes in v3:
- Address comments about adding a new uclass and some sandbox test from
  v2 in https://patchwork.ozlabs.org/project/uboot/list/?series=196253
- New directory drivers/firmware/scmi/. The path mimics Linux kernel
  source tree for the equivalent driver.
- Split scmi.h (patch v2) into scmi_protocols.h, scmi_agent.h and
  scmi_agent-uclass.h.
- Create new uclass UCLASS_SCMI_AGENT.
- Introduce a simple sandbox on that agent. Mailbox and smccc agents are
  moved to specific commits in the series.

Changes in v2:
- Fix CONFIG_SCMI_FIRMWARE description with explicit SCMI reference.
- Move struct, enum and macro definitions at source file top and
  add inline comment description for the structures and local functions.
- Replace rc with ret as return value local variable label.
- Use explicit return 0 on successful return paths.
- Replace EINVAL with more accurate error numbers.
- Use dev_read_u32() instead of ofnode_read_u32(dev_ofnode(), ...).
- Use memcpy_toio()/memcpy_fromio() when copying message payload
  to/from IO memory.
- Embed mailbox transport resources upon CONFIG_DM_MAILBOX and
  SMCCC transport resources upon CONFIG_ARM_SMCCC.

Note: review comments on defining a uclass and sandbox for SCMI
transport drivers are NOT addressed in this v2. Main issue is that
there is no driver/device defined for SCMI transport layer as well as
and no defined compatible ID in the SCMI DT bindings documentation.
---
 arch/sandbox/dts/test.dts  |  16 +++
 arch/sandbox/include/asm/scmi_test.h   |  43 ++
 configs/sandbox_defconfig  |   2 +
 drivers/firmware/Kconfig   |   2 +
 drivers/firmware/Makefile  |   1 +
 drivers/firmware/scmi/Kconfig  |  17 +++
 drivers/firmware/scmi/Makefile |   2 +
 drivers/firmware/scmi/sandbox-scmi_agent.c | 147 +
 drivers/firmware/scmi/scmi_agent-uclass.c  | 107 +++
 include/dm/uclass-id.h |   1 +
 include/scmi_agent-uclass.h|  24 
 include/scmi_agent.h   |  68 ++
 include/scmi_protocols.h   |  41 ++
 test/dm/Makefile   |   1 +
 test/dm/scmi.c |  38 ++
 15 files changed, 510 insertions(+)
 create mode 100644 arch/sandbox/include/asm/scmi_test.h
 create mode 100644 drivers/firmware/scmi/Kconfig
 create mode 100644 drivers/firmware/scmi/Makefile
 create mode 100644 drivers/firmware/scmi/sandbox-scmi_agent.c
 create mode 100644 drivers/firmware/scmi/scmi_agent-uclass.c
 create mode 100644 include/scmi_agent-uclass.h
 create mode 100644 include/scmi_agent.h
 create mode 100644 include/scmi_protocols.h
 create mode 100644 test/dm/scmi.c

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 9f45c48e4e..dd3b43885e 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -356,6 +356,22 @@
sandbox_firmware: sandbox-firmware {
compatible = "sandbox,firmware";
};
+
+   sandbox-scmi-agent@0 {
+   compatible = "sandbox,scmi-agent";
+   #address-cells = <1>;

[PATCH v3 2/8] firmware: scmi: mailbox/smt agent device

2020-09-07 Thread Etienne Carriere
This change implements a mailbox transport using SMT format for SCMI
exchanges. This implementation follows the Linux kernel and
SCP-firmware [1] as references implementation for SCMI message
processing using SMT format for communication channel meta-data.

Use of mailboxes in SCMI FDT bindings are defined in the Linux kernel
DT bindings since v4.17.

Links: [1] https://github.com/ARM-software/SCP-firmware
Signed-off-by: Etienne Carriere 
Cc: Simon Glass 
Cc: Peng Fan 
Cc: Sudeep Holla 
---

Changes in v3:
- This is a followup of the SCMI agent patches posted in
  https://patchwork.ozlabs.org/project/uboot/list/?series=196253
  The v3 splits commits and introduces a new uclass as requested.
- This patch implements the same mailbox SCMI agent proposed in v2
  but split over few source files.
---
 drivers/firmware/scmi/Kconfig |   6 +-
 drivers/firmware/scmi/Makefile|   2 +
 drivers/firmware/scmi/mailbox_agent.c | 107 
 drivers/firmware/scmi/smt.c   | 139 ++
 drivers/firmware/scmi/smt.h   |  86 
 5 files changed, 338 insertions(+), 2 deletions(-)
 create mode 100644 drivers/firmware/scmi/mailbox_agent.c
 create mode 100644 drivers/firmware/scmi/smt.c
 create mode 100644 drivers/firmware/scmi/smt.h

diff --git a/drivers/firmware/scmi/Kconfig b/drivers/firmware/scmi/Kconfig
index 57e2ebbe42..c501bf4943 100644
--- a/drivers/firmware/scmi/Kconfig
+++ b/drivers/firmware/scmi/Kconfig
@@ -2,7 +2,7 @@ config SCMI_FIRMWARE
bool "Enable SCMI support"
select FIRMWARE
select OF_TRANSLATE
-   depends on SANDBOX
+   depends on SANDBOX || DM_MAILBOX
help
  System Control and Management Interface (SCMI) is a communication
  protocol that defines standard interfaces for power, performance
@@ -14,4 +14,6 @@ config SCMI_FIRMWARE
  or a companion host in the CPU system.
 
  Communications between agent (client) and the SCMI server are
- based on message exchange.
+ based on message exchange. Messages can be exchange over tranport
+ channels as a mailbox device with some piece of identified shared
+ memory.
diff --git a/drivers/firmware/scmi/Makefile b/drivers/firmware/scmi/Makefile
index 336ea1f2a3..d22f53efe7 100644
--- a/drivers/firmware/scmi/Makefile
+++ b/drivers/firmware/scmi/Makefile
@@ -1,2 +1,4 @@
 obj-y  += scmi_agent-uclass.o
+obj-y  += smt.o
+obj-$(CONFIG_DM_MAILBOX)   += mailbox_agent.o
 obj-$(CONFIG_SANDBOX)  += sandbox-scmi_agent.o
diff --git a/drivers/firmware/scmi/mailbox_agent.c 
b/drivers/firmware/scmi/mailbox_agent.c
new file mode 100644
index 00..9a7b0a5858
--- /dev/null
+++ b/drivers/firmware/scmi/mailbox_agent.c
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Linaro Limited.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "smt.h"
+
+#define TIMEOUT_US_10MS1
+
+/**
+ * struct scmi_mbox_channel - Description of an SCMI mailbox transport
+ * @smt:   Shared memory buffer
+ * @mbox:  Mailbox channel description
+ * @timeout_us:Timeout in microseconds for the mailbox transfer
+ */
+struct scmi_mbox_channel {
+   struct scmi_smt smt;
+   struct mbox_chan mbox;
+   ulong timeout_us;
+};
+
+static struct scmi_mbox_channel *scmi_mbox_get_priv(struct udevice *dev)
+{
+   return (struct scmi_mbox_channel *)dev_get_priv(dev);
+}
+
+static int scmi_mbox_process_msg(struct udevice *dev, struct scmi_msg *msg)
+{
+   struct scmi_mbox_channel *chan = scmi_mbox_get_priv(dev);
+   int ret;
+
+   ret = scmi_write_msg_to_smt(dev, >smt, msg);
+   if (ret)
+   return ret;
+
+   /* Give shm addr to mbox in case it is meaningful */
+   ret = mbox_send(>mbox, chan->smt.buf);
+   if (ret) {
+   dev_err(dev, "Message send failed: %d\n", ret);
+   goto out;
+   }
+
+   /* Receive the response */
+   ret = mbox_recv(>mbox, chan->smt.buf, chan->timeout_us);
+   if (ret) {
+   dev_err(dev, "Response failed: %d, abort\n", ret);
+   goto out;
+   }
+
+   ret = scmi_read_resp_from_smt(dev, >smt, msg);
+
+out:
+   scmi_clear_smt_channel(>smt);
+
+   return ret;
+}
+
+int scmi_mbox_probe(struct udevice *dev)
+{
+   struct scmi_mbox_channel *chan = scmi_mbox_get_priv(dev);
+   int ret;
+
+   chan->timeout_us = TIMEOUT_US_10MS;
+
+   ret = mbox_get_by_index(dev, 0, >mbox);
+   if (ret) {
+   dev_err(dev, "Failed to find mailbox: %d\n", ret);
+   goto out;
+   }
+
+   ret = scmi_dt_get_smt_buffer(dev, >smt);
+   if (ret)
+   dev_err(dev, "Failed to get shm resources: %d\n", ret);
+
+out:
+   if (ret)
+   devm_kfree(dev, chan);
+
+   return ret;
+}
+
+static const struct 

Re: RPi4 U-Boot freeze

2020-09-07 Thread Peter Robinson
> Any thoughts on this issue?

Any reason why you're using 2020.01 and not at least 2020.07, or at
least seeing if it's reproducible on 2020.10-rc3? The RPi4 support has
changed quite a bit since then I suspect.

> Just to be sure, I did some memory testing on the 2GB module, but no
> issues found.
>
> I still somehow suspected that something else might be wrong with my
> hardware, so I bought a new RPi4 (this time with 4GB of RAM) but the
> very same with that:
>
> U-Boot 2020.01 (Aug 23 2020 - 22:02:31 +)
>
> DRAM:  3.9 GiB
> 
>
> I still think there is something wrong with caching. From what I
> understand caches are enabled by the RPi (4) firmware. Is it safe to run
> 32-bit ARM U-Boot with enabled caches?
>
> --
> Stefan
>
> On 2020-08-23 19:06, Stefan Agner wrote:
> > Hi,
> >
> > I noticed a quite common freeze when running 32-bit U-Boot 2020.01
> > (rpi_4_32b_defconfig) on a 2GB RPi4 model:
> >
> > U-Boot 2020.01 (Aug 07 2020 - 13:00:23 +)
> >
> > DRAM:  1.9 GiB
> > 
> >
> > This happens fairly often, I would say 4 out of 5 boot tries. However,
> > if it boots, everything seems to run fine.
> >
> > The issue seems to go away when using 2020.04 or any newer release,
> > however, when trying to find the actual patch fixing the issue using git
> > bisect I ended up with a MMC merge request which really seems unrelated
> > (36bdcf7f3b). It seems that the problem is quite evasive and disappears
> > if certain structure are aligned differently etc.
> >
> > Enabling initcall debugging showed that U-Boot crashes right after
> > relocation:
> >
> > ...
> > initcall: 00016f2c
> >
> > RAM Configuration:
> > Bank #0: 0 948 MiB
> > Bank #1: 4000 1 GiB
> > Bank #2: 0 0 Bytes
> > Bank #3: 0 0 Bytes
> >
> > DRAM:  1.9 GiB
> > initcall: 00016bb8
> > New Stack Pointer is: 3af6d9e0
> > initcall: 00016da4
> > initcall: 00016ef0
> > initcall: 00016ef8
> > initcall: 00016d38
> > Relocation Offset is: 3b375000
> > Relocating to 3b37d000, new gd at 3af78ec0, sp at 3af6d9e0
> > initcall: 00016ec8 [clear_bss]
> > initcall: 0004465c [display_options?? only appears sometimes]
> > 
> >
> > I realized when using CONFIG_SYS_(I|D)CACHE_OFF=y the problem seems to
> > disappear. But to be 100% certain that it is cache related, I used my
> > original configuration (which is known to "reliably" freeze), and
> > replaced 00016ec8 with 8688 manually in the binary, essentially
> > swapping out function pointers in "init_sequence_f" [8688 is
> > cleanup_before_linux, which flushes and disables I-cache/D-cache]. And
> > indeed, that hacked up binary does boot reliably every time:
> >
> > ...
> > initcall: 00016f2c
> >
> > RAM Configuration:
> > Bank #0: 0 948 MiB
> > Bank #1: 4000 1 GiB
> > Bank #2: 0 0 Bytes
> > Bank #3: 0 0 Bytes
> >
> > DRAM:  1.9 GiB
> > initcall: 00016bb8
> > New Stack Pointer is: 3af6d9e0
> > initcall: 00016da4
> > initcall: 00016ef0
> > initcall: 00016ef8
> > initcall: 00016d38
> > Relocation Offset is: 3b375000
> > Relocating to 3b37d000, new gd at 3af78ec0, sp at 3af6d9e0
> > initcall: 8688
> > initcall: 3b38c10c
> > initcall: 3b38c114
> > initcall: 000172e0 (relocated to 3b38c2e0)
> > initcall: 0001712c (relocated to 3b38c12c)
> > ...
> >
> > From what I understand on RPi4 caches are enabled when entering U-Boot.
> > I was wondering if the relocation code really can handle that?
> >
> > --
> > Stefan


Re: [PATCH 0/5] edison: Support for writing an xFSTK image

2020-09-07 Thread Simon Glass
Hi Tom,

On Mon, 7 Sep 2020 at 08:12, Tom Rini  wrote:
>
> On Mon, Sep 07, 2020 at 07:57:12AM -0600, Simon Glass wrote:
> > Hi Andy,
> >
> > On Mon, 7 Sep 2020 at 02:04, Andy Shevchenko  
> > wrote:
> > >
> > > On Sat, Sep 5, 2020 at 6:23 AM Simon Glass  wrote:
> > > > On Fri, 4 Sep 2020 at 03:46, Andy Shevchenko
> > > >  wrote:
> > > > > On Thu, Sep 03, 2020 at 07:28:51PM -0600, Simon Glass wrote:
> > >
> > > > I do have a question though. How does the board decide whether to wait
> > > > for the xFSTK tool to connect? Sometimes when I reset it it, it does.
> > > > Sometimes it goes straight into receiving application. I am not
> > > > pressing any button other than reset. Once it makes it mind up, it
> > > > seems to stick to it until the power is removed? But it is powered by
> > > > USB too, so removing power is not so easy.
> > >
> > > It's a good question. I don't know the answer unfortunately. I think
> > > the parties that are involved here are PMIC and thus its firmware (I
> > > don't have access to it and even if ask will not get), DnX protocol,
> > > USB implementation on IFWI level (no access to me either). And I truly
> > > believe there are bugs in all of them, though I dunno if they are
> > > related to the above behaviour.
> > > Btw, pressing the reset button helps?
> >
> > Pressing reset either boots quickly or waits 10 seconds for xFSTK to
> > connect. It's like cracking a code and I haven't cracked it yet. I'll
> > have another go at some point, and maybe finally get this board into
> > my lab.
>
> On a tangent, when it comes to lab stuff I picked up
> https://www.yepkit.com/products/ykush a while back precisely for "device
> can be USB powered on purpose/accident" in order to have
> software-controlled USB ports I can bring up/down.

Actually that's very relevant. I did try that with Edison and it
definitely does power off the board now. I keep thinking with just a
bit more messing around I can nut it out. My first board turned out to
have a problem with the slider switch which could have been part of
the issue.

Regards,
Simon


Re: [PATCH 0/5] edison: Support for writing an xFSTK image

2020-09-07 Thread Tom Rini
On Mon, Sep 07, 2020 at 07:57:12AM -0600, Simon Glass wrote:
> Hi Andy,
> 
> On Mon, 7 Sep 2020 at 02:04, Andy Shevchenko  
> wrote:
> >
> > On Sat, Sep 5, 2020 at 6:23 AM Simon Glass  wrote:
> > > On Fri, 4 Sep 2020 at 03:46, Andy Shevchenko
> > >  wrote:
> > > > On Thu, Sep 03, 2020 at 07:28:51PM -0600, Simon Glass wrote:
> >
> > > I do have a question though. How does the board decide whether to wait
> > > for the xFSTK tool to connect? Sometimes when I reset it it, it does.
> > > Sometimes it goes straight into receiving application. I am not
> > > pressing any button other than reset. Once it makes it mind up, it
> > > seems to stick to it until the power is removed? But it is powered by
> > > USB too, so removing power is not so easy.
> >
> > It's a good question. I don't know the answer unfortunately. I think
> > the parties that are involved here are PMIC and thus its firmware (I
> > don't have access to it and even if ask will not get), DnX protocol,
> > USB implementation on IFWI level (no access to me either). And I truly
> > believe there are bugs in all of them, though I dunno if they are
> > related to the above behaviour.
> > Btw, pressing the reset button helps?
> 
> Pressing reset either boots quickly or waits 10 seconds for xFSTK to
> connect. It's like cracking a code and I haven't cracked it yet. I'll
> have another go at some point, and maybe finally get this board into
> my lab.

On a tangent, when it comes to lab stuff I picked up
https://www.yepkit.com/products/ykush a while back precisely for "device
can be USB powered on purpose/accident" in order to have
software-controlled USB ports I can bring up/down.

-- 
Tom


signature.asc
Description: PGP signature


Re: [PATCH 0/5] edison: Support for writing an xFSTK image

2020-09-07 Thread Simon Glass
Hi Andy,

On Mon, 7 Sep 2020 at 02:04, Andy Shevchenko  wrote:
>
> On Sat, Sep 5, 2020 at 6:23 AM Simon Glass  wrote:
> > On Fri, 4 Sep 2020 at 03:46, Andy Shevchenko
> >  wrote:
> > > On Thu, Sep 03, 2020 at 07:28:51PM -0600, Simon Glass wrote:
>
> > I do have a question though. How does the board decide whether to wait
> > for the xFSTK tool to connect? Sometimes when I reset it it, it does.
> > Sometimes it goes straight into receiving application. I am not
> > pressing any button other than reset. Once it makes it mind up, it
> > seems to stick to it until the power is removed? But it is powered by
> > USB too, so removing power is not so easy.
>
> It's a good question. I don't know the answer unfortunately. I think
> the parties that are involved here are PMIC and thus its firmware (I
> don't have access to it and even if ask will not get), DnX protocol,
> USB implementation on IFWI level (no access to me either). And I truly
> believe there are bugs in all of them, though I dunno if they are
> related to the above behaviour.
> Btw, pressing the reset button helps?

Pressing reset either boots quickly or waits 10 seconds for xFSTK to
connect. It's like cracking a code and I haven't cracked it yet. I'll
have another go at some point, and maybe finally get this board into
my lab.

Regards,
Simon


Re: [PATCH v4 0/3] binman: Further updates for FIT support

2020-09-07 Thread Simon Glass
Hi Michal,

On Mon, 7 Sep 2020 at 02:44, Michal Simek  wrote:
>
> Hi Simon,
>
> On 06. 09. 20 18:39, Simon Glass wrote:
> > This series adds support for help messages when binary blobs are missing,
> > as well as selecting the default FIT configuration.
> >
> > It includes the v3 patches from the earlier series that were not applied.
> >
> > Note: This series is available at u-boot-dm/binman-working and is based
> > on u-boot-dm/next
> >
> > Changes in v4:
> > - Add more documentation for DEFAULT-SEQ
> > - Drop patches previous applied to u-boot-dm/next
> >
> > Changes in v3:
> > - Add a way to show help messages for missing blobs
> > - Rebase on top of earlier binman series
> >
> > Changes in v2:
> > - Add new patch to allow selecting default FIT configuration
> >
> > Simon Glass (3):
> >   binman: Allow selecting default FIT configuration
> >   binman: Support help messages for missing blobs
> >   binman: sunxi: Add help message for missing sunxi ATF BL31
> >
> >  Makefile  |  2 +
> >  arch/arm/dts/sunxi-u-boot.dtsi|  1 +
> >  tools/binman/README   |  6 ++
> >  tools/binman/README.entries   |  4 ++
> >  tools/binman/control.py   | 69 ++-
> >  tools/binman/entry.py |  9 +++
> >  tools/binman/etype/fit.py | 26 +++
> >  tools/binman/ftest.py | 59 ++--
> >  tools/binman/missing-blob-help| 15 
> >  tools/binman/test/168_fit_missing_blob.dts|  9 ++-
> >  .../test/{170_fit_fdt.dts => 172_fit_fdt.dts} |  2 +-
> >  11 files changed, 195 insertions(+), 7 deletions(-)
> >  create mode 100644 tools/binman/missing-blob-help
> >  rename tools/binman/test/{170_fit_fdt.dts => 172_fit_fdt.dts} (95%)
> >
>
> I just spot one thing and will be good to clearify it.
>
> In sunxi this description is used.
> +   firmware = "uboot";
> +   loadables = "atf";
>
> But is this right way how this should be described?
> I personally use firmware which points to ATF and loadables which points
> to uboot. Not sure what sunxi is doing but also in spl_fit.c there is a
> comment about it.
> /*
>  * Find the U-Boot image using the following search order:
>  *   - start at 'firmware' (e.g. an ARM Trusted Firmware)
>  *   - fall back 'kernel' (e.g. a Falcon-mode OS boot
>  *   - fall back to using the first 'loadables' entry
>  */

It would be better if this could be made deterministic. I don't really
know which is right, but we should not need fallbacks, etc. We know
when we are in Falcon mode, at least, and we should be able to settle
on which one to use for U-Boot.

Regards,
Simon


Re: [PATCH] time: Fix get_ticks being non-monotonic

2020-09-07 Thread Simon Glass
Hi Sean,

On Sun, 6 Sep 2020 at 20:02, Sean Anderson  wrote:
>
> On 9/6/20 9:43 PM, Simon Glass wrote:
> > Hi Sean,
> >
> > On Tue, 1 Sep 2020 at 13:56, Sean Anderson  wrote:
> >>
> >> get_ticks does not always succeed. Sometimes it can be called before the
> >> timer has been initialized. If it does, it returns a negative errno.
> >> This causes the timer to appear non-monotonic, because the value will
> >> become much smaller after the timer is initialized.
> >>
> >> No users of get_ticks which I checked handle errors of this kind. Further,
> >> functions like tick_to_time mangle the result of get_ticks, making it very
> >> unlikely that one could check for an error without suggesting a patch such
> >> as this one.
> >>
> >> This patch changes get_ticks to always return 0 when there is an error.
> >> 0 is the least unsigned integer, ensuring get_ticks appears monotonic. This
> >> has the side effect of time apparently not passing until the timer is
> >> initialized. However, without this patch, time does not pass anyway,
> >> because the error value is likely to be the same.
> >>
> >> Fixes: c8a7ba9e6a5
> >> Signed-off-by: Sean Anderson 
> >> ---
> >>
> >>  lib/time.c | 4 ++--
> >>  1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > Would it be better to panic so people can fix the bug?
>
> I thought this was expected behavior. It's only a bug if you do
> something like udelay before any timers are created. We just can't
> report errors through get_ticks, because its users assume that it always
> returns a time of some kind.

I think it indicates a bug. If you use a device before it is ready you
don't really know what it will do. I worry that this patch is just
going to cause confusion, since the behaviour depends on when you call
it. If we panic, people can figure out why the timer is being inited
too late, or being used too early.

Regards,
Simon


Re: [PATCH v3 01/12] binman: Allow entry args to be required

2020-09-07 Thread Simon Glass
Hi Michal,

On Mon, 7 Sep 2020 at 00:31, Michal Simek  wrote:
>
> Hi Simon,
>
> On 05. 09. 20 23:10, Simon Glass wrote:
> > If an entry argument is needed by an entry but the entry argument is not
> > present, then a strange error can occur when trying to read the file.
> >
> > Fix this by allowing arguments to be required. Select this option for the
> > cros-ec-rw entry. If a filename is provided in the node, allow that to be
> > used.
> >
> > Also tidy up a few related tests to make the error string easier to find,
> > and fully ignore unused return values.
> >
> > Signed-off-by: Simon Glass 
> > ---
> >
> > (no changes since v1)
> >
> >  tools/binman/README.entries |  7 ++-
> >  tools/binman/etype/blob_named_by_arg.py | 10 ++
> >  tools/binman/etype/cros_ec_rw.py|  3 +--
> >  tools/binman/ftest.py   | 15 +++
> >  4 files changed, 24 insertions(+), 11 deletions(-)
> >
> > Applied to u-boot-dm/next, thanks!
>
> Did you start to use patman for sending this?
> Just curios because I am missing indentation in origin message.

No that is done with a gmail script.  It would be interesting to use
patman though. I am using patman to collect review tags from
patchwork, so using it to send out the 'applied' emails would help
complete the circle.

Regards,
Simon


Re: [PATCH 1/2] spl: Use standard FIT entries

2020-09-07 Thread Simon Glass
Hi Michal,

On Mon, 7 Sep 2020 at 02:27, Michal Simek  wrote:
>
> Hi Simon,
>
> On 07. 09. 20 3:43, Simon Glass wrote:
> > Hi Michal,
> >
> > On Thu, 3 Sep 2020 at 05:03, Michal Simek  wrote:
> >>
> >> SPL is creating fit-images DT node when loadables are recorded in selected
> >> configuration. Entries which are created are using entry-point and
> >> load-addr property names. But there shouldn't be a need to use non standard
> >> properties because entry/load are standard FIT properties. But using
> >> standard FIT properties enables option to use generic FIT functions to
> >> descrease SPL size. Here is result for ZynqMP virt configuration:
> >> xilinx_zynqmp_virt: spl/u-boot-spl:all -82 spl/u-boot-spl:rodata -22 
> >> spl/u-boot-spl:text -60
> >>
> >> The patch causes change in run time fit image record.
> >> Before:
> >> fit-images {
> >> uboot {
> >> os = "u-boot";
> >> type = "firmware";
> >> size = <0xfd520>;
> >> entry-point = <0x800>;
> >> load-addr = <0x800>;
> >> };
> >> };
> >>
> >> After:
> >> fit-images {
> >> uboot {
> >> os = "u-boot";
> >> type = "firmware";
> >> size = <0xfd520>;
> >> entry = <0x800>;
> >> load = <0x800>;
> >> };
> >> };
> >>
> >> Replacing calling fdt_getprop_u32() by fit_image_get_entry/load() also
> >> enables support for reading entry/load properties recorded in 64bit format.
> >>
> >> Signed-off-by: Michal Simek 
> >> ---
> >
> > Reviewed-by: Simon Glass 
> >
> > Isn't there a test that could be updated here?
>
> Are we testing SPL flow?
>
> >
> >>
> >> Would be good to know history of fit-images and it's property names but
> >> there shouldn't be a need to use non standard names where we have
> >> FIT_*_PROP recorded as macros in include/image.h.
> >
> > I agree.
> >
> >> Concern regarding backward compatibility is definitely valid but not sure
> >> how many systems can be affected by this change.
> >
> > Me neither. Probably a good idea to fix it.
>
> Fix means keep existing code with warning and add new one next to it.

No, I mean use your code as here and document with a test, etc. If it
breaks anything, it can be fixed.

Regards,
SImon


Re: [PATCH 2/5] binman: Show an error when a file is missing

2020-09-07 Thread Simon Glass
Hi Andy,

On Mon, 7 Sep 2020 at 03:08, Andy Shevchenko
 wrote:
>
> On Sun, Sep 06, 2020 at 07:43:39PM -0600, Simon Glass wrote:
> > On Fri, 4 Sep 2020 at 03:33, Andy Shevchenko
> >  wrote:
> > > On Thu, Sep 03, 2020 at 07:28:53PM -0600, Simon Glass wrote:
>
> > > > -self._pathname = tools.GetInputFilename(self._filename,
> > > > -
> > > > self.section.GetAllowMissing())
> > > > +self._pathname = tools.GetInputFilename(
> > > > +self._filename, self.external and 
> > > > self.section.GetAllowMissing())
> > >
> > > I hope you know that 'and' has a bit different semantics in Python than 
> > > in C for example.
> >
> > I think I understand it, in the sense that 'x and y' returns y if x is
> > true. Is that what you mean?
>
> There is no boolean object involved!
>
> "Note that neither and nor or restrict the value and type they return to False
> and True, but rather return the last evaluated argument."
>
> If x is last evaluated argument (false), it will be returned. Means that there
> are possibilities to get None, False, empty container, etc as returned value 
> of
> 'and'.

Yes I think that matches with my understanding. It's more like
'if...else' in this case. Anyway, both x and y are booleans in the
code above.

Regards,
Simon


Re: [PATCH 0/2] Add support for loading images above 4GB

2020-09-07 Thread Simon Glass
Hi Michal,

On Mon, 7 Sep 2020 at 03:01, Michal Simek  wrote:
>
> Hi Simon,
>
> On 07. 09. 20 3:43, Simon Glass wrote:
> > Hi Michal,
> >
> > On Thu, 3 Sep 2020 at 06:30, Michal Simek  wrote:
> >>
> >> Hi,
> >>
> >> On 03. 09. 20 13:16, Heinrich Schuchardt wrote:
> >>> On 9/3/20 1:03 PM, Michal Simek wrote:
>  Hi,
> 
>  We have several use cases where customers want to partition memory by
>  putting NS images above 4GB. On Xilinx arm 64bit SOC 0-2GB can be used 
>  for
>  others CPU in the systems (like R5) or for secure sw.
>  Currently there is limitation in SPL to record load/entry addresses in
>  64bit format because they are recorded in 32bit only.
>  This series add support for it.
>  Patches have been tested on Xilinx ZynqMP zcu102 board in SD bootmode 
>  with
>  images generated by binman. Because u-boot is using
>  CONFIG_POSITION_INDEPENDENT it can be put to others 4k aligned addresses
>  and there is no real need to build it to certain offset.
> 
>  Thanks,
>  Michal
> >>>
> >>> Hello Michal,
> >>>
> >>> does this series require changes to doc/uImage.FIT/source_file_format.txt?
> >>
> >> I am not changing fit format. I am just changing how SPL records
> >> loadables in DT fit-images node. And also series is using FIT functions
> >> for reading these properties (at least in this version).
> >
> > Well I think there should be some mention of the 32/64 bit issue added
> > to the FIT docs. How about adding an example with 64-bit addresses?
>
> git grep "fit-images" doc/
> and output is 0. It means we really don't have any documentation for
> fit-images embed node.
> It means we should create one.
>
> /fit-images are related to loadables property that's why I think make
> sense to document them together.
>
> What about doc/uImage.FIT/howto.txt?

Sounds good.

Regards,
Simon


Re: [PATCH v3 08/12] sunxi: Convert 64-bit boards to use binman

2020-09-07 Thread Simon Glass
Hi Michal,

On Mon, 7 Sep 2020 at 07:02, Michal Simek  wrote:
>
> Hi,
>
> On 06. 09. 20 2:18, Simon Glass wrote:
> > Hi Samuel,
> >
> > On Sat, 5 Sep 2020 at 17:10, Samuel Holland  wrote:
> >>
> >> On 9/1/20 6:14 AM, Simon Glass wrote:
> >>> At present 64-bit sunxi boards use the Makefile to create a FIT, using
> >>> USE_SPL_FIT_GENERATOR. This is deprecated.
> >>>
> >>> Update sunxi to use binman instead.
> >>>
> >>> Signed-off-by: Simon Glass 
> >>> ---
> >>>
> >>> (no changes since v2)
> >>>
> >>> Changes in v2:
> >>> - Add a 'fit-fdt-list' property
> >>> - Fix 'board' typo in commit message
> >>>
> >>>  Kconfig|  3 +-
> >>>  Makefile   | 18 ++
> >>>  arch/arm/dts/sunxi-u-boot.dtsi | 61 +-
> >>>  3 files changed, 63 insertions(+), 19 deletions(-)
> >>>
> >>> diff --git a/Kconfig b/Kconfig
> >>> index 883e3f71d01..837b2f517ae 100644
> >>> --- a/Kconfig
> >>> +++ b/Kconfig
> >>> @@ -659,12 +659,11 @@ config SPL_FIT_SOURCE
> >>>
> >>>  config USE_SPL_FIT_GENERATOR
> >>>   bool "Use a script to generate the .its script"
> >>> - default y if SPL_FIT
> >>> + default y if SPL_FIT && !ARCH_SUNXI
> >>
> >> Now `make u-boot.itb` doesn't work.
> >>
> >> u-boot.itb is helpful to have because, with CONFIG_OF_LIST, it can be 
> >> shared
> >> across all boards of a platform. Only SPL is board-specific (on arm64 
> >> sunxi, at
> >> least).
> >
> > It is generated, just with a different filename.
> >
> >>
> >> Is there a way to make binman also write the FIT without the SPL? Would 
> >> that
> >> require duplicating the whole binman node?
> >
> > Yes it would. We could get more complicated and allow an image to
> > build on another perhaps. I'm not sure what is easiest here.
> >
> >>
> >>>  config SPL_FIT_GENERATOR
> >>>   string ".its file generator script for U-Boot FIT image"
> >>>   depends on USE_SPL_FIT_GENERATOR
> >>> - default "board/sunxi/mksunxi_fit_atf.sh" if SPL_LOAD_FIT && 
> >>> ARCH_SUNXI
> >>>   default "arch/arm/mach-rockchip/make_fit_atf.py" if SPL_LOAD_FIT && 
> >>> ARCH_ROCKCHIP
> >>>   default "arch/arm/mach-zynqmp/mkimage_fit_atf.sh" if SPL_LOAD_FIT 
> >>> && ARCH_ZYNQMP
> >>>   default "arch/riscv/lib/mkimage_fit_opensbi.sh" if SPL_LOAD_FIT && 
> >>> RISCV
> >>> diff --git a/Makefile b/Makefile
> >>> index 5b4e60496d6..65024c74089 100644
> >>> --- a/Makefile
> >>> +++ b/Makefile
> >>> @@ -923,11 +923,6 @@ INPUTS-$(CONFIG_REMAKE_ELF) += u-boot.elf
> >>>  INPUTS-$(CONFIG_EFI_APP) += u-boot-app.efi
> >>>  INPUTS-$(CONFIG_EFI_STUB) += u-boot-payload.efi
> >>>
> >>> -# Build a combined spl + u-boot image for sunxi
> >>> -ifeq ($(CONFIG_ARCH_SUNXI)$(CONFIG_ARM64)$(CONFIG_SPL),yyy)
> >>> -INPUTS-y += u-boot-sunxi-with-spl.bin
> >>> -endif
> >>> -
> >>>  # Generate this input file for binman
> >>>  ifeq ($(CONFIG_SPL),)
> >>>  INPUTS-$(CONFIG_ARCH_MEDIATEK) += u-boot-mtk.bin
> >>> @@ -1024,13 +1019,9 @@ PHONY += inputs
> >>>  inputs: $(INPUTS-y)
> >>>
> >>>  all: .binman_stamp inputs
> >>> -# Hack for sunxi which doesn't have a proper binman definition for
> >>> -# 64-bit boards
> >>> -ifneq ($(CONFIG_ARCH_SUNXI)$(CONFIG_ARM64),yy)
> >>>  ifeq ($(CONFIG_BINMAN),y)
> >>>   $(call if_changed,binman)
> >>>  endif
> >>> -endif
> >>>
> >>>  # Timestamp file to make sure that binman always runs
> >>>  .binman_stamp: FORCE
> >>> @@ -1336,6 +1327,8 @@ cmd_binman = $(srctree)/tools/binman/binman $(if 
> >>> $(BINMAN_DEBUG),-D) \
> >>>   $(if $(BINMAN_VERBOSE),-v$(BINMAN_VERBOSE)) \
> >>>   build -u -d u-boot.dtb -O . -m --allow-missing \
> >>>   -I . -I $(srctree) -I $(srctree)/board/$(BOARDDIR) \
> >>> + -I arch/$(ARCH)/dts -a of-list=$(CONFIG_OF_LIST) \
> >>> + -a atf-bl31-path=${BL31} \
> >>>   $(BINMAN_$(@F))
> >>>
> >>>  OBJCOPYFLAGS_u-boot.ldr.hex := -I binary -O ihex
> >>> @@ -1625,13 +1618,6 @@ u-boot-x86-reset16.bin: u-boot FORCE
> >>>
> >>>  endif # CONFIG_X86
> >>>
> >>> -ifneq ($(CONFIG_ARCH_SUNXI),)
> >>> -ifeq ($(CONFIG_ARM64),y)
> >>> -u-boot-sunxi-with-spl.bin: spl/sunxi-spl.bin u-boot.itb FORCE
> >>> - $(call if_changed,cat)
> >>> -endif
> >>> -endif
> >>> -
> >>
> >> Now `make u-boot-sunxi-with-spl.bin` doesn't work.
> >>
> >> This is less of an issue, but still probably breaks some scripts. It breaks
> >> mine, at least.
> >
> > Why do you specify a target? Doesn't it build the file without the target?
> >
> > One problem with buildman is that there is no definitely of what files
> > it will produce when run, or at least there is, but it is in the
> > binman description itself.
> >
> > This means that 'make clean' doesn't work fully, for example. I can
> > think of a few ways to implement this. One would be to put a list of
> > target files into a text file and have 'make clean' use that. We could
> > also have an option to tell binman to produce a list of files it would
> > generate if run. Then 

Re: [PATCH 2/2] spl: fdt: Record load/entry fit-images entries in 64bit format

2020-09-07 Thread Simon Glass
Hi Michal,

On Mon, 7 Sep 2020 at 02:29, Michal Simek  wrote:
>
>
>
> On 07. 09. 20 3:43, Simon Glass wrote:
> > Hi Michal,
> >
> > On Thu, 3 Sep 2020 at 05:03, Michal Simek  wrote:
> >>
> >> The commit 9f45aeb93727 ("spl: fit: implement fdt_record_loadable") which
> >> introduced fdt_record_loadable() state there spl_fit.c is not 64bit safe.
> >> Based on my tests on Xilinx ZynqMP zcu102 platform there shouldn't be a
> >> problem to record these addresses in 64bit format.
> >> The patch adds support for systems which need to load images above 4GB.
> >
> > But what about 32-bit systems who read this as a 32-bit number?
> > Perhaps we should write 32-bit if !CONFIG_PHYS_64BIT?
>
> The code for reading doesn't really care if value is 32bit or 64bit.
> The fit_image_get_entry() and fit_image_get_load() read number of cells
> used and based on that read 32 or 64 bit values.

Sorry I wrote that before looking at the function. The functions
should have header-file comments that indicate what they do.

Regards,
Simon


[PATCH] am335x, guardian: update the maintainer list

2020-09-07 Thread Moses Christopher
I am leaving Bosch, so replacing myself with Gireesh

Signed-off-by: Moses Christopher 
---
 board/bosch/guardian/MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/board/bosch/guardian/MAINTAINERS b/board/bosch/guardian/MAINTAINERS
index 2f674d7f83..fd216a96ca 100644
--- a/board/bosch/guardian/MAINTAINERS
+++ b/board/bosch/guardian/MAINTAINERS
@@ -1,7 +1,7 @@
 Guardian BOARD
 M: Sjoerd Simons 
 M: Govindaraji Sivanantham 
-M: Moses Christopher Bollavarapu 

+M: Hiremath Gireesh 
 S: Maintained
 F: board/bosch/guardian/
 F: include/configs/am335x_guardian.h
-- 
2.20.1



Re: [PATCH v2 4/6] mmc: atmel-sdhci: do not check clk_set_rate return value

2020-09-07 Thread Eugen.Hristev
On 28.08.2020 08:37, Peng Fan wrote:
>> Subject: [PATCH v2 4/6] mmc: atmel-sdhci: do not check clk_set_rate return
>> value
>>
>> clk_set_rate will return rate in case of success and zero in case of error,
>> however it can also return -ev, but it's an ulong function.
>> To avoid any issues, disregard the return value of this call.
>> In case this call actually fails, nothing much we can do anyway, but we can 
>> at
>> least try with the previous values (or DT assigned-clocks)
>>
>> Signed-off-by: Eugen Hristev 
>> ---
>>   drivers/mmc/atmel_sdhci.c | 4 +---
>>   1 file changed, 1 insertion(+), 3 deletions(-)
>>
>> diff --git a/drivers/mmc/atmel_sdhci.c b/drivers/mmc/atmel_sdhci.c index
>> f03c0457e1..54b660c34a 100644
>> --- a/drivers/mmc/atmel_sdhci.c
>> +++ b/drivers/mmc/atmel_sdhci.c
>> @@ -79,9 +79,7 @@ static int atmel_sdhci_probe(struct udevice *dev)
>>if (ret)
>>return ret;
>>
>> - ret = clk_set_rate(, ATMEL_SDHC_GCK_RATE);
>> - if (ret)
>> - return ret;
>> + clk_set_rate(, ATMEL_SDHC_GCK_RATE);
>>
>>max_clk = clk_get_rate();
>>if (!max_clk)
> 
> Since clk_set_rate will return the new rate or 0, is there
> a need to use clk_get_rate following there?
> 
> Regards,
> Peng.

Hi Peng,

Yes. The clk_set_rate will return failure(0) if the clock was not 
changed, due to maybe an incorrect rate was set. However, this does not 
mean that we need to bail out.
The clock can be preconfigured from DT property assigned-clocks.
When calling clk_get_rate, we get the currently assigned rate.

Here is an example:

sama7g5 SoC supports clock at maximum 200 Mhz. Thus we assign 200 Mhz 
from assigned-clocks property.

The driver will call set_rate with 240 Mhz (predefined in driver). It 
will fail, return code 0.
However, the clock works at 200 Mhz and already configured.
When requesting the rate, we get the 200 Mhz from the clock subsystem.
We can move forward, and have host->max_clk = max_clk, as done below in 
the driver.

Does this look good to you ?

Thanks,
Eugen
> 
> 
>> --
>> 2.25.1
> 



Re: [PATCH v2 2/3] arm64: Bail out PIE builds early if load address is not 4K aligned

2020-09-07 Thread Edgar E. Iglesias
On Mon, Sep 07, 2020 at 08:57:39AM -0400, Tom Rini wrote:
> On Mon, Sep 07, 2020 at 11:52:35AM +0200, Edgar E. Iglesias wrote:
> > On Fri, Sep 04, 2020 at 12:43:57PM -0600, Stephen Warren wrote:
> > > On 9/4/20 3:07 AM, Edgar E. Iglesias wrote:
> > > > From: "Edgar E. Iglesias" 
> > > > 
> > > > PIE requires a 4K aligned load address. If this is not met, trap
> > > > the startup sequence in a WFI loop rather than running into obscure
> > > > failures.
> > > 
> > > > diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S
> > > >  #if CONFIG_POSITION_INDEPENDENT
> > > > +   /* Verify that we're 4K aligned.  */
> > > 
> > > Similar to the comment on the previous patch: I believe the code that
> > > implements this check should be outside the #if check, since it's always
> > > needed.
> > 
> > But a check for non-PIE would have to be stricter, wouldn't it?
> > I.e the load address needs to exactly match the link-time address.
> > 
> > Perhaps we should add the non-PIE check in a separate patch (if at all)?
> 
> If we can catch a bad configuration at link time in the non-PIE case (as
> said in another part of this thread I believe) then we should, yes,
> thanks!

The non-PIE configuration is expected to be loaded at a specific address.
The actual load address cannot be checked at link-time (since it's up to
the user at run-time) but given the assumption of a specific load-address,
4K alignment can be enforced at link-time.

It really comes down to adding reasonable run-time checks for errors that
users may reasonably struggle with.

For PIE, checking for 4K aligment is reasonable because it's an easy
enough misstake to make (since you've got a binary that's was supposed to
handle relocation).

For non-PIE, checking for the exact address at run-time is a little bit more
border-line IMO but I guess also somewhat reasonable.

There are still plenty of cases we can't catch though (loaded at odd addreses,
non-RAM address-ranges etc etc).

Cheers,
Edgar






Re: [PATCH v2 08/21] clk: at91: move clock code to compat.c

2020-09-07 Thread Eugen.Hristev
On 05.08.2020 18:11, Claudiu Beznea wrote:
> Move clock code to compat.c to allow switching to CCF
> without mixing CCF code with non CCF code. This prepares the
> field for next commits.
> 
> Signed-off-by: Claudiu Beznea 
> ---


Hi Claudiu,

I want to apply these, but meanwhile, there are some changes in 
driver/clk/at91/compat.c

To avoid any issues I might introduce when applying/moving code to 
another file, would you mind rebasing your series on top of latest 
u-boot/master ?
This commit from master adds a conflict in rebasing :

702e57e113 ("treewide: convert devfdt_get_addr_ptr() to 
dev_read_addr_ptr()")

It may be needed that new code is also checked against this conversion

Thanks!
Eugen


snip [...]


Re: [PATCH v3 2/2] armv8: lx2162aqds: Add support for LX2162AQDS platform

2020-09-07 Thread Tom Rini
On Mon, Sep 07, 2020 at 03:42:07PM +0530, meenakshi.aggar...@nxp.com wrote:

> From: Meenakshi Aggarwal 
> 
> This patch add base support for LX2162AQDS board.
> LX2162AQDS board supports LX2162A family SoCs.
> This patch add basic support of platform.
> 
> Signed-off-by: Ioana Ciornei 
> Signed-off-by: Zhao Qiang 
> Signed-off-by: hui.song 
> Signed-off-by: Manish Tomar 
> Signed-off-by: Vikas Singh 
> Signed-off-by: Meenakshi Aggarwal 
> ---
>  arch/arm/Kconfig   |  12 +
>  arch/arm/dts/Makefile  |   6 +-
>  arch/arm/dts/fsl-lx2160a-qds.dts   |   3 -
>  arch/arm/dts/fsl-lx2160a-qds.dtsi  |  22 +-
>  arch/arm/dts/fsl-lx2162a-qds-17-x.dts  |  17 +
>  arch/arm/dts/fsl-lx2162a-qds-18-x.dts  |  17 +
>  arch/arm/dts/fsl-lx2162a-qds-20-x.dts  |  17 +
>  arch/arm/dts/fsl-lx2162a-qds-sd1-17.dtsi   |  58 ++
>  arch/arm/dts/fsl-lx2162a-qds-sd1-18.dtsi   |  61 ++
>  arch/arm/dts/fsl-lx2162a-qds-sd1-20.dtsi   |  26 +
>  arch/arm/dts/fsl-lx2162a-qds.dts   |  34 +

Most of these new dts* files are not added to MAINTAINERS entries and it
would be good to do so.

>  board/freescale/common/vid.c   |   3 +-
>  board/freescale/lx2160a/Kconfig|  16 +
>  board/freescale/lx2160a/MAINTAINERS|  10 +
>  board/freescale/lx2160a/Makefile   |   1 +
>  board/freescale/lx2160a/README | 132 

This README also should get updated to rST and moved.

[snip]
> +/*
> + * Need to override existing (lx2160a) with lx2162aqds so set_board_info will
> + * use proper prefix when creating full board_name (SYS_BOARD + type)
> + */
> +#undef CONFIG_SYS_BOARD
> +#define CONFIG_SYS_BOARD"lx2162aqds"

SYS_BOARD is under Kconfig, please just fix it there.

> +
> +#undef CONFIG_SYS_NXP_SRDS_3
> +
> +/* Qixis */
> +#define QIXIS_XMAP_MASK  0x07

This is the start of adding tons of non-CONFIG information to the config
header.  Don't do this, it's going to make full migration to Kconfig
harder.  Please audit the whole file and anything that's not CONFIG_xxx
needs to be somewhere else really.  Thanks.

-- 
Tom


signature.asc
Description: PGP signature


Re: [PATCH v3 1/2] armv8: lx2162a: Add Soc changes to support LX2162A

2020-09-07 Thread Tom Rini
On Mon, Sep 07, 2020 at 03:42:06PM +0530, meenakshi.aggar...@nxp.com wrote:

> From: Meenakshi Aggarwal 
> 
> LX2162 is LX2160 based SoC, it has same die as of LX2160
> with different packaging.
> 
> LX2162A support 64-bit 2.9GT/s DDR4 memory, i2c, micro-click module,
> microSD card, eMMC support, serial console, qspi nor flash, qsgmii,
> sgmii, 25g, 40g, 50g network interface, one usb 3.0 and serdes
> interface to support three PCIe gen3 interface.
> 
> Signed-off-by: Meenakshi Aggarwal 
> ---
>  arch/arm/cpu/armv8/Kconfig |  2 +-
>  arch/arm/cpu/armv8/fsl-layerscape/Kconfig  | 39 +--
>  arch/arm/cpu/armv8/fsl-layerscape/Makefile |  5 ++
>  arch/arm/cpu/armv8/fsl-layerscape/cpu.c|  9 ++--
>  arch/arm/cpu/armv8/fsl-layerscape/doc/README.soc   | 58 
> ++

I just want to make sure it's on the TODO list somewhere to convert this
README.soc file to rST and move it under doc/board/ or similar, thanks!

-- 
Tom


signature.asc
Description: PGP signature


Re: Change in gic_lpi_tables_init() function

2020-09-07 Thread Rayagonda Kokatanur
Hi Priyanka,

On Mon, Sep 7, 2020 at 2:26 PM Priyanka Jain  wrote:

> Hello Rayagonda,
>
>
>
> With today top of upstream u-boot tree, I am still getting the error in
> booting lx216ardb
>
>
>
> U-Boot 2020.10-rc3-00086-ge5df264e7a (Sep 07 2020 - 14:13:57 +0530)
>
> 
>
> “Error binding driver 'gic-v3': -96
>
> Some drivers failed to bind
>
> initcall sequence fbdcf368 failed at call 8201b5e4
> (err=-96)
>
> ### ERROR ### Please RESET the board ###
>
>
>
> But if apply the changes suggested by you, it is booting fine. Can you
> please help to send the pull-request for this soon , so that proper fixes
> are integrated in u-boot code before U-boot v2020.10 release.
>

It was working for me long back without this patch.
Could you please send this patch as you can reproduce it and test it.
Please let me know.

Best regards,
Rayagonda


>
>
> Thanks
>
> Priyanka
>
>
>
> *From:* Rayagonda Kokatanur 
> *Sent:* Friday, September 4, 2020 10:50 PM
> *To:* Priyanka Jain 
> *Cc:* Z.q. Hou ; Wasim Khan ;
> Bharat Gooty ; Manish Tomar <
> manish.to...@nxp.com>; Xiaobo Xie ; Jiafei Pan <
> jiafei@nxp.com>; Meenakshi Aggarwal 
> *Subject:* Re: Change in gic_lpi_tables_init() function
>
>
>
> Hi Priyanka,
>
>
>
> Please add the following code at the end of "arch/arm/lib/gic-v3-its.c"
> file,
> This is not required for the latest uboot hence its not part of the patch.
>
> UCLASS_DRIVER(irq) = {
> .id = UCLASS_IRQ,
> .name = "irq",
> };
>
>
>
> Best regards,
>
> Rayagonda
>
>
>
>
>
> On Fri, Sep 4, 2020 at 9:38 PM Priyanka Jain 
> wrote:
>
> Hello Rayagonda,
>
>
>
> I am getting below error with top of tree upstream on lx2160ardb. Any
> pointer here.
>
>
>
> U-Boot 2020.10-rc3-00082-g9bfb567e5f (Sep 04 2020 - 21:27:29 +0530)
>
>
>
> SoC:  LX2160ACE Rev2.0 (0x87360020)
>
> Clock Configuration:
>
>CPU0(A72):1900 MHz  CPU1(A72):1900 MHz  CPU2(A72):1900 MHz
>
>CPU3(A72):1900 MHz  CPU4(A72):1900 MHz  CPU5(A72):1900 MHz
>
>CPU6(A72):1900 MHz  CPU7(A72):1900 MHz  CPU8(A72):1900 MHz
>
>CPU9(A72):1900 MHz  CPU10(A72):1900 MHz  CPU11(A72):1900 MHz
>
>CPU12(A72):1900 MHz  CPU13(A72):1900 MHz  CPU14(A72):1900 MHz
>
>CPU15(A72):1900 MHz
>
>Bus:  600  MHz  DDR:  2600 MT/s
>
> Reset Configuration Word (RCW):
>
>: 4c6b6b30 204c004c  
>
>0010:  0c01  
>
>0020: 02e001a0 2580  0096
>
>0030:    
>
>0040:    
>
>0050:    
>
>0060:   00027000 
>
>0070: 08b30010 00150020
>
> Model: NXP Layerscape LX2160ARDB Board
>
> Board: LX2160ACE Rev2.0-RDB, Board version: B, boot from FlexSPI DEV#1
>
> FPGA: v5.0
>
> SERDES1 Reference: Clock1 = 161.13MHz Clock2 = 161.13MHz
>
> SERDES2 Reference: Clock1 = 100MHz Clock2 = 100MHz
>
> SERDES3 Reference: Clock1 = 100MHz Clock2 = 100MHz
>
> VID: Core voltage after adjustment is at 851 mV
>
> DRAM:  31.9 GiB
>
> DDR31.9 GiB (DDR4, 64-bit, CL=19, ECC on)
>
>DDR Controller Interleaving Mode: 256B
>
>DDR Chip-Select Interleaving Mode: CS0+CS1
>
> Error binding driver 'gic-v3': -96
>
> Some drivers failed to bind
>
> initcall sequence fbdcf368 failed at call 8201b5e4
> (err=-96)
>
> ### ERROR ### Please RESET the board ###
>
>
>
> Regards
>
> Priyanka
>
>


Re: [PATCH v3 08/12] sunxi: Convert 64-bit boards to use binman

2020-09-07 Thread Michal Simek
Hi,

On 06. 09. 20 2:18, Simon Glass wrote:
> Hi Samuel,
> 
> On Sat, 5 Sep 2020 at 17:10, Samuel Holland  wrote:
>>
>> On 9/1/20 6:14 AM, Simon Glass wrote:
>>> At present 64-bit sunxi boards use the Makefile to create a FIT, using
>>> USE_SPL_FIT_GENERATOR. This is deprecated.
>>>
>>> Update sunxi to use binman instead.
>>>
>>> Signed-off-by: Simon Glass 
>>> ---
>>>
>>> (no changes since v2)
>>>
>>> Changes in v2:
>>> - Add a 'fit-fdt-list' property
>>> - Fix 'board' typo in commit message
>>>
>>>  Kconfig|  3 +-
>>>  Makefile   | 18 ++
>>>  arch/arm/dts/sunxi-u-boot.dtsi | 61 +-
>>>  3 files changed, 63 insertions(+), 19 deletions(-)
>>>
>>> diff --git a/Kconfig b/Kconfig
>>> index 883e3f71d01..837b2f517ae 100644
>>> --- a/Kconfig
>>> +++ b/Kconfig
>>> @@ -659,12 +659,11 @@ config SPL_FIT_SOURCE
>>>
>>>  config USE_SPL_FIT_GENERATOR
>>>   bool "Use a script to generate the .its script"
>>> - default y if SPL_FIT
>>> + default y if SPL_FIT && !ARCH_SUNXI
>>
>> Now `make u-boot.itb` doesn't work.
>>
>> u-boot.itb is helpful to have because, with CONFIG_OF_LIST, it can be shared
>> across all boards of a platform. Only SPL is board-specific (on arm64 sunxi, 
>> at
>> least).
> 
> It is generated, just with a different filename.
> 
>>
>> Is there a way to make binman also write the FIT without the SPL? Would that
>> require duplicating the whole binman node?
> 
> Yes it would. We could get more complicated and allow an image to
> build on another perhaps. I'm not sure what is easiest here.
> 
>>
>>>  config SPL_FIT_GENERATOR
>>>   string ".its file generator script for U-Boot FIT image"
>>>   depends on USE_SPL_FIT_GENERATOR
>>> - default "board/sunxi/mksunxi_fit_atf.sh" if SPL_LOAD_FIT && ARCH_SUNXI
>>>   default "arch/arm/mach-rockchip/make_fit_atf.py" if SPL_LOAD_FIT && 
>>> ARCH_ROCKCHIP
>>>   default "arch/arm/mach-zynqmp/mkimage_fit_atf.sh" if SPL_LOAD_FIT && 
>>> ARCH_ZYNQMP
>>>   default "arch/riscv/lib/mkimage_fit_opensbi.sh" if SPL_LOAD_FIT && 
>>> RISCV
>>> diff --git a/Makefile b/Makefile
>>> index 5b4e60496d6..65024c74089 100644
>>> --- a/Makefile
>>> +++ b/Makefile
>>> @@ -923,11 +923,6 @@ INPUTS-$(CONFIG_REMAKE_ELF) += u-boot.elf
>>>  INPUTS-$(CONFIG_EFI_APP) += u-boot-app.efi
>>>  INPUTS-$(CONFIG_EFI_STUB) += u-boot-payload.efi
>>>
>>> -# Build a combined spl + u-boot image for sunxi
>>> -ifeq ($(CONFIG_ARCH_SUNXI)$(CONFIG_ARM64)$(CONFIG_SPL),yyy)
>>> -INPUTS-y += u-boot-sunxi-with-spl.bin
>>> -endif
>>> -
>>>  # Generate this input file for binman
>>>  ifeq ($(CONFIG_SPL),)
>>>  INPUTS-$(CONFIG_ARCH_MEDIATEK) += u-boot-mtk.bin
>>> @@ -1024,13 +1019,9 @@ PHONY += inputs
>>>  inputs: $(INPUTS-y)
>>>
>>>  all: .binman_stamp inputs
>>> -# Hack for sunxi which doesn't have a proper binman definition for
>>> -# 64-bit boards
>>> -ifneq ($(CONFIG_ARCH_SUNXI)$(CONFIG_ARM64),yy)
>>>  ifeq ($(CONFIG_BINMAN),y)
>>>   $(call if_changed,binman)
>>>  endif
>>> -endif
>>>
>>>  # Timestamp file to make sure that binman always runs
>>>  .binman_stamp: FORCE
>>> @@ -1336,6 +1327,8 @@ cmd_binman = $(srctree)/tools/binman/binman $(if 
>>> $(BINMAN_DEBUG),-D) \
>>>   $(if $(BINMAN_VERBOSE),-v$(BINMAN_VERBOSE)) \
>>>   build -u -d u-boot.dtb -O . -m --allow-missing \
>>>   -I . -I $(srctree) -I $(srctree)/board/$(BOARDDIR) \
>>> + -I arch/$(ARCH)/dts -a of-list=$(CONFIG_OF_LIST) \
>>> + -a atf-bl31-path=${BL31} \
>>>   $(BINMAN_$(@F))
>>>
>>>  OBJCOPYFLAGS_u-boot.ldr.hex := -I binary -O ihex
>>> @@ -1625,13 +1618,6 @@ u-boot-x86-reset16.bin: u-boot FORCE
>>>
>>>  endif # CONFIG_X86
>>>
>>> -ifneq ($(CONFIG_ARCH_SUNXI),)
>>> -ifeq ($(CONFIG_ARM64),y)
>>> -u-boot-sunxi-with-spl.bin: spl/sunxi-spl.bin u-boot.itb FORCE
>>> - $(call if_changed,cat)
>>> -endif
>>> -endif
>>> -
>>
>> Now `make u-boot-sunxi-with-spl.bin` doesn't work.
>>
>> This is less of an issue, but still probably breaks some scripts. It breaks
>> mine, at least.
> 
> Why do you specify a target? Doesn't it build the file without the target?
> 
> One problem with buildman is that there is no definitely of what files
> it will produce when run, or at least there is, but it is in the
> binman description itself.
> 
> This means that 'make clean' doesn't work fully, for example. I can
> think of a few ways to implement this. One would be to put a list of
> target files into a text file and have 'make clean' use that. We could
> also have an option to tell binman to produce a list of files it would
> generate if run. Then we might be able to tell binman to generate a
> particular file.

Why not just to generate all binman images to specific folder?

Thanks,
Michal



Re: [PATCH v2 2/3] arm64: Bail out PIE builds early if load address is not 4K aligned

2020-09-07 Thread Tom Rini
On Mon, Sep 07, 2020 at 11:52:35AM +0200, Edgar E. Iglesias wrote:
> On Fri, Sep 04, 2020 at 12:43:57PM -0600, Stephen Warren wrote:
> > On 9/4/20 3:07 AM, Edgar E. Iglesias wrote:
> > > From: "Edgar E. Iglesias" 
> > > 
> > > PIE requires a 4K aligned load address. If this is not met, trap
> > > the startup sequence in a WFI loop rather than running into obscure
> > > failures.
> > 
> > > diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S
> > >  #if CONFIG_POSITION_INDEPENDENT
> > > + /* Verify that we're 4K aligned.  */
> > 
> > Similar to the comment on the previous patch: I believe the code that
> > implements this check should be outside the #if check, since it's always
> > needed.
> 
> But a check for non-PIE would have to be stricter, wouldn't it?
> I.e the load address needs to exactly match the link-time address.
> 
> Perhaps we should add the non-PIE check in a separate patch (if at all)?

If we can catch a bad configuration at link time in the non-PIE case (as
said in another part of this thread I believe) then we should, yes,
thanks!

-- 
Tom


signature.asc
Description: PGP signature


Re: [PATCH v6 1/2] board: kontron: add sl28 support

2020-09-07 Thread Michael Walle

Hi Tom,

thanks for the review!

Am 2020-08-31 18:08, schrieb Tom Rini:

On Sun, Aug 30, 2020 at 10:03:00PM +0200, Michael Walle wrote:

Add basic support for the Kontron SMARC-sAL28 board. This includes 
just

the bare minimum to be able to bring up the board and boot linux.

For now, the Single and Dual PHY variant is supported. Other variants
will fall back to the basic variant.

In particular, there is no watchdog support for now. This means that 
you

have to disable the default watchdog, otherwise you'll end up in the
recovery bootloader. See the board README for details.

Signed-off-by: Michael Walle 


..

diff --git a/include/configs/kontron_sl28.h 
b/include/configs/kontron_sl28.h

new file mode 100644
index 00..a5e3219560
--- /dev/null
+++ b/include/configs/kontron_sl28.h
@@ -0,0 +1,122 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef __SL28_H
+#define __SL28_H
+
+#include 
+#include 
+#include 


Do we need these in here?


They are included in the ls1028a_common.h, but I cannot include this 
common

file because its is really just a "common across freescale development
boards" file. Therefore, I had to duplicate it here. Removing these 
includes
results in build errors, eg. DCFG_BASE is undefined etc. I really don't 
want
to go down that rabbit hole and fixing all the layerscape/freescale 
stuff.



+#ifdef CONFIG_SPL_BUILD
+#define CONFIG_SYS_MONITOR_BASECONFIG_SPL_TEXT_BASE
+#else
+#define CONFIG_SYS_MONITOR_BASECONFIG_SYS_TEXT_BASE
+#endif


I don't like this, but I see it's copied from other layerscapes.  Is it
really needed?


I don't think so. I'll remove it.


+
+#define CONFIG_SYS_LOAD_ADDR		(CONFIG_SYS_DDR_SDRAM_BASE + 
0x1000)

+
+/* environment */
+#define CONFIG_LOADADDR 0x8100
+#define ENV_MEM_LAYOUT_SETTINGS \
+   "scriptaddr=0x9000\0" \
+   "pxefile_addr_r=0x9010\0" \
+   "kernel_addr_r=" __stringify(CONFIG_LOADADDR) "\0" \
+   "fdt_addr_r=0x8300\0" \
+   "ramdisk_addr_r=0x8310\0" \
+   "fdtfile=freescale/fsl-ls1028a-kontron-sl28.dtb\0"


These are too small of a range of kernel/device tree/ramdisk addresses,
and there will be overlap/overwrites at some point.  I've been pointing
people at the big block comment in include/configs/ti_armv7_common.h as
it's still correct for minimum sizes for aarch64 as well.


thanks for pointing that out.


+#ifndef CONFIG_SPL_BUILD
+#define BOOT_TARGET_DEVICES(func) \
+   func(MMC, mmc, 1) \
+   func(MMC, mmc, 0) \
+   func(NVME, nvme, 0) \
+   func(USB, usb, 0) \
+   func(DHCP, dhcp, 0) \
+   func(PXE, pxe, 0)
+#include 
+#else
+#define BOOTENV
+#endif


Is env in SPL enabled?  This is another case that I don't really like 
to

see done.


No it's not and it seems to build without the else case. IIRC it wasn't
building a year ago when I did the original port.

I'll post a new version with your suggested changes, soon.

-michael


Re: [PATCH 5/5] arm: mach-omap2: am33xx: Add device structure for spi

2020-09-07 Thread Vignesh Raghavendra
Hi,

On 9/7/20 4:02 PM, Faiz Abbas wrote:
> Hi Vignesh,
> 
> On 07/09/20 1:48 pm, Vignesh Raghavendra wrote:
>>
>>
>> On 9/7/20 12:36 PM, Faiz Abbas wrote:
>>> Hi Lokesh,
>>>
>>> On 07/09/20 12:08 pm, Lokesh Vutla wrote:

[...]
>  struct omap3_spi_priv {
>   struct mcspi *regs;
>   unsigned int cs;
> diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h
> index 9c4ef369c5..db1a89ad30 100644
> --- a/include/configs/am335x_evm.h
> +++ b/include/configs/am335x_evm.h
> @@ -281,6 +281,10 @@
>  #endif
>  
>  /* SPI flash. */
> +#if CONFIG_IS_ENABLED(DM_SPI)
> +#define AM33XX_SPI_BASE  0x4803
>>
>> Could this be more specific? AM33XX_SPI_BASE?
> 
> Isn't there only one McSPI instance in am335x?
> 

No, there are 2 SPI ports on AM335x (see arch/arm/dts/am33xx.dtsi).

>>
> +#define AM33XX_SPI_OFFSET(AM33XX_SPI_BASE + 
> OMAP4_MCSPI_REG_OFFSET)

 Can we get the SPI base from DT?

>>>
>>> We are doing that in U-boot (see the ofdata_to_platdata() callback in patch 
>>> 4).
>>> We need hardcoded static platdata for SPL. Was this not clear from the 
>>> commit
>>> message?
>>>
>>
>> Then why not move these defines to arch/arm/mach-omap2/am33xx/board.c as
>> well?
> 
> All the other base addresses used in arch/arm/mach-omap2/am33xx/board.c are 
> included
> from here. For example see UART platdata (struct ns16550_platdata 
> am33xx_serial[]).
> 

UART is bad example as those #defines were added in 2012 which predate
platdata introduction...

Besides what happens when derivative of AM335x (see
include/configs/am335x_*.h) want to enable SPI boot? Would each such
files need to duplicate this snippet?


Re: [PATCH 4/5] spi: omap3_spi: Read platform data in ofdata_to_platdata()

2020-09-07 Thread Vignesh Raghavendra



On 9/2/20 4:48 PM, Faiz Abbas wrote:
> Add an ofdata_to_platdata() callback to access dts in U-boot and
> access all platform data in it. This prepares the driver for supporting
> both device tree as well as static platform data structures in SPL.
> 
> Signed-off-by: Faiz Abbas 
> ---
>  drivers/spi/omap3_spi.c | 37 ++---
>  1 file changed, 26 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/spi/omap3_spi.c b/drivers/spi/omap3_spi.c
> index fbf9575851..08daacf6f0 100644
> --- a/drivers/spi/omap3_spi.c
> +++ b/drivers/spi/omap3_spi.c
> @@ -482,17 +482,10 @@ static int omap3_spi_set_wordlen(struct udevice *dev, 
> unsigned int wordlen)
>  static int omap3_spi_probe(struct udevice *dev)
>  {
>   struct omap3_spi_priv *priv = dev_get_priv(dev);
> - const void *blob = gd->fdt_blob;
> - int node = dev_of_offset(dev);
> + struct omap3_spi_plat *plat = dev_get_platdata(dev);
>  

Definition of struct omap3_spi_plat is unavailable till 5/5.. Should
this patch come after 5/5?

Regards
Vignesh

> - struct omap2_mcspi_platform_config* data =
> - (struct omap2_mcspi_platform_config*)dev_get_driver_data(dev);
> -
> - priv->regs = (struct mcspi *)(dev_read_addr(dev) + data->regs_offset);
> - if (fdtdec_get_bool(blob, node, "ti,pindir-d0-out-d1-in"))
> - priv->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN;
> - else
> - priv->pin_dir = MCSPI_PINDIR_D0_IN_D1_OUT;
> + priv->regs = plat->regs;
> + priv->pin_dir = plat->pin_dir;
>   priv->wordlen = SPI_DEFAULT_WORDLEN;
>  
>   spi_reset(priv->regs);
> @@ -544,6 +537,7 @@ static const struct dm_spi_ops omap3_spi_ops = {
>*/
>  };
>  
> +#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
>  static struct omap2_mcspi_platform_config omap2_pdata = {
>   .regs_offset = 0,
>  };
> @@ -552,16 +546,37 @@ static struct omap2_mcspi_platform_config omap4_pdata = 
> {
>   .regs_offset = OMAP4_MCSPI_REG_OFFSET,
>  };
>  
> +static int omap3_spi_ofdata_to_platdata(struct udevice *dev)
> +{
> + struct omap2_mcspi_platform_config *data =
> + (struct omap2_mcspi_platform_config *)dev_get_driver_data(dev);
> + struct omap3_spi_plat *plat = dev_get_platdata(dev);
> +
> + plat->regs = (struct mcspi *)(dev_read_addr(dev) + data->regs_offset);
> +
> + if (dev_read_bool(dev, "ti,pindir-d0-out-d1-in"))
> + plat->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN;
> + else
> + plat->pin_dir = MCSPI_PINDIR_D0_IN_D1_OUT;
> +
> + return 0;
> +}
> +
>  static const struct udevice_id omap3_spi_ids[] = {
>   { .compatible = "ti,omap2-mcspi", .data = (ulong)_pdata },
>   { .compatible = "ti,omap4-mcspi", .data = (ulong)_pdata },
>   { }
>  };
> -
> +#endif
>  U_BOOT_DRIVER(omap3_spi) = {
>   .name   = "omap3_spi",
>   .id = UCLASS_SPI,
> + .flags  = DM_FLAG_PRE_RELOC,
> +#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
>   .of_match = omap3_spi_ids,
> + .ofdata_to_platdata = omap3_spi_ofdata_to_platdata,
> + .platdata_auto_alloc_size = sizeof(struct omap3_spi_plat),
> +#endif
>   .probe = omap3_spi_probe,
>   .ops= _spi_ops,
>   .priv_auto_alloc_size = sizeof(struct omap3_spi_priv),
> 


Re: [PATCH 4/5] spi: omap3_spi: Read platform data in ofdata_to_platdata()

2020-09-07 Thread Vignesh Raghavendra



On 9/2/20 4:48 PM, Faiz Abbas wrote:
> Add an ofdata_to_platdata() callback to access dts in U-boot and
> access all platform data in it. This prepares the driver for supporting
> both device tree as well as static platform data structures in SPL.
> 
> Signed-off-by: Faiz Abbas 
> ---
>  drivers/spi/omap3_spi.c | 37 ++---
>  1 file changed, 26 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/spi/omap3_spi.c b/drivers/spi/omap3_spi.c
> index fbf9575851..08daacf6f0 100644
> --- a/drivers/spi/omap3_spi.c
> +++ b/drivers/spi/omap3_spi.c
> @@ -482,17 +482,10 @@ static int omap3_spi_set_wordlen(struct udevice *dev, 
> unsigned int wordlen)
>  static int omap3_spi_probe(struct udevice *dev)
>  {
>   struct omap3_spi_priv *priv = dev_get_priv(dev);
> - const void *blob = gd->fdt_blob;
> - int node = dev_of_offset(dev);
> + struct omap3_spi_plat *plat = dev_get_platdata(dev);
>  

Definition of struct omap3_spi_plat is available till 5/5.. Should this
patch come after 5/5?

Regards
Vignesh

> - struct omap2_mcspi_platform_config* data =
> - (struct omap2_mcspi_platform_config*)dev_get_driver_data(dev);
> -
> - priv->regs = (struct mcspi *)(dev_read_addr(dev) + data->regs_offset);
> - if (fdtdec_get_bool(blob, node, "ti,pindir-d0-out-d1-in"))
> - priv->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN;
> - else
> - priv->pin_dir = MCSPI_PINDIR_D0_IN_D1_OUT;
> + priv->regs = plat->regs;
> + priv->pin_dir = plat->pin_dir;
>   priv->wordlen = SPI_DEFAULT_WORDLEN;
>  
>   spi_reset(priv->regs);
> @@ -544,6 +537,7 @@ static const struct dm_spi_ops omap3_spi_ops = {
>*/
>  };
>  
> +#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
>  static struct omap2_mcspi_platform_config omap2_pdata = {
>   .regs_offset = 0,
>  };
> @@ -552,16 +546,37 @@ static struct omap2_mcspi_platform_config omap4_pdata = 
> {
>   .regs_offset = OMAP4_MCSPI_REG_OFFSET,
>  };
>  
> +static int omap3_spi_ofdata_to_platdata(struct udevice *dev)
> +{
> + struct omap2_mcspi_platform_config *data =
> + (struct omap2_mcspi_platform_config *)dev_get_driver_data(dev);
> + struct omap3_spi_plat *plat = dev_get_platdata(dev);
> +
> + plat->regs = (struct mcspi *)(dev_read_addr(dev) + data->regs_offset);
> +
> + if (dev_read_bool(dev, "ti,pindir-d0-out-d1-in"))
> + plat->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN;
> + else
> + plat->pin_dir = MCSPI_PINDIR_D0_IN_D1_OUT;
> +
> + return 0;
> +}
> +
>  static const struct udevice_id omap3_spi_ids[] = {
>   { .compatible = "ti,omap2-mcspi", .data = (ulong)_pdata },
>   { .compatible = "ti,omap4-mcspi", .data = (ulong)_pdata },
>   { }
>  };
> -
> +#endif
>  U_BOOT_DRIVER(omap3_spi) = {
>   .name   = "omap3_spi",
>   .id = UCLASS_SPI,
> + .flags  = DM_FLAG_PRE_RELOC,
> +#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
>   .of_match = omap3_spi_ids,
> + .ofdata_to_platdata = omap3_spi_ofdata_to_platdata,
> + .platdata_auto_alloc_size = sizeof(struct omap3_spi_plat),
> +#endif
>   .probe = omap3_spi_probe,
>   .ops= _spi_ops,
>   .priv_auto_alloc_size = sizeof(struct omap3_spi_priv),
> 


Re: [PATCH v2 2/3] arm64: Bail out PIE builds early if load address is not 4K aligned

2020-09-07 Thread Edgar E. Iglesias
On Fri, Sep 04, 2020 at 12:43:57PM -0600, Stephen Warren wrote:
> On 9/4/20 3:07 AM, Edgar E. Iglesias wrote:
> > From: "Edgar E. Iglesias" 
> > 
> > PIE requires a 4K aligned load address. If this is not met, trap
> > the startup sequence in a WFI loop rather than running into obscure
> > failures.
> 
> > diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S
> >  #if CONFIG_POSITION_INDEPENDENT
> > +   /* Verify that we're 4K aligned.  */
> 
> Similar to the comment on the previous patch: I believe the code that
> implements this check should be outside the #if check, since it's always
> needed.

But a check for non-PIE would have to be stricter, wouldn't it?
I.e the load address needs to exactly match the link-time address.

Perhaps we should add the non-PIE check in a separate patch (if at all)?

Cheers,
Edgar


  1   2   >