Re: imx6ull: NAND boot fails when block 0x00000000 is bad

2022-05-13 Thread Thierry Bultel

Hi Michael,
I am using version 2022.04


|Colibri iMX6ULL # nand erase.chip NAND erase.chip: device 0 whole chip 
Skipping bad block at 0x Skipping bad block at 0x1ff8|


Thierry

Le 13/05/2022 à 20:00, Michael Nazzareno Trimarchi a écrit :

Hi Thierry

Il ven 13 mag 2022, 19:56 Fabio Estevam  ha scritto:

[Adding some more folks]

On Fri, May 13, 2022 at 2:41 PM Thierry Bultel
 wrote:
>
> Hi,
>
> I have a imx6ull module from Toradex, with NAND flash. U-boot
does not
> have SPL.
> I does not boot from NAND flash anymore, I was able to flash it
several
> times with tezi, as well as with
> nandbcb (that I discovered more recently).
>
> There are error messages complaining about some bad blocks,
including
> block 0x.
>
> Toradex say that the module cannot be recovered, but this seems in
> contradiction with what we can read
> from the iMX6 reference manual, where the boot process description
> mentions that the ROM can attempt to
> seek for FCB several times.
>
> I attempted to use nandbcb to write the FCB at next block, ie
0x2
> (attempting a lower value
> makes nandbcb complain that I am not writing to an aligned
location),
> with no better success.
>
> What is your mind about that ? Sounds that the answer could be in
> mis-configured fuses,
> else I consider that having block 0x causes a bricked
board, as
> a weakness for production,
> in other words, an unreliable product.


What U-Boot version are you using? Anyway block 0 is always guarantee 
by nand manufacturer, so having that bad look strange


Michael

>
> Best regards
> Thierry
>
>
> --
> Re: test
> www.linatsea.fr  http://www.linatsea.fr>>
> --
> www.linatsea.fr 



--
Re: test
www.linatsea.fr 
--
www.linatsea.fr

Re: [PATCH v2] sunxi: psci: Fix sunxi_power_switch on sun8i-r40 platform

2022-05-13 Thread qianfan




在 2022/5/14 11:52, Chen-Yu Tsai 写道:

Hi,

On Sat, May 14, 2022 at 11:19 AM  wrote:

From: qianfan Zhao 

linux system will die if we offline one of the cpu on R40 based board:
eg: echo 0 > /sys/devices/system/cpu/cpu3/online

Fixed sunxi_power_switch based on allwinner lichee 3.10 kernel driver.

Signed-off-by: qianfan Zhao 

Please add a Fixes tag.


---
v2 changes: Fix the commit message, the source code doesn't change.

  arch/arm/cpu/armv7/sunxi/psci.c | 24 +++-
  1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c
index 1ac50f558a..63186a9388 100644
--- a/arch/arm/cpu/armv7/sunxi/psci.c
+++ b/arch/arm/cpu/armv7/sunxi/psci.c
@@ -79,8 +79,7 @@ static void __secure __mdelay(u32 ms)
  static void __secure clamp_release(u32 __maybe_unused *clamp)
  {
  #if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN7I) || \
-   defined(CONFIG_MACH_SUN8I_H3) || \
-   defined(CONFIG_MACH_SUN8I_R40)
+   defined(CONFIG_MACH_SUN8I_H3)
 u32 tmp = 0x1ff;
 do {
 tmp >>= 1;
@@ -88,15 +87,30 @@ static void __secure clamp_release(u32 __maybe_unused 
*clamp)
 } while (tmp);

 __mdelay(10);
+#elif defined(CONFIG_MACH_SUN8I_R40)
+   u8 i, tmp = 0xfe;
+
+   for (i = 0; i < 5; i++) { /* 0xfe, 0xf8, 0xe0, 0x80, 0x00 */
+   writel(tmp, clamp);
+   tmp <<= 2;
+   }
+
+   while (0x00 != readl(clamp)) {
+   ;
+   }
  #endif
  }

  static void __secure clamp_set(u32 __maybe_unused *clamp)
  {
  #if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN7I) || \
-   defined(CONFIG_MACH_SUN8I_H3) || \
-   defined(CONFIG_MACH_SUN8I_R40)
+   defined(CONFIG_MACH_SUN8I_H3)
 writel(0xff, clamp);
+#elif defined(CONFIG_MACH_SUN8I_R40)
+   writel(0xff, clamp);
+   while (0xff != readl(clamp)) {
+   ;
+   }
  #endif
  }

@@ -153,7 +167,7 @@ static void __secure sunxi_cpu_set_power(int cpu, bool on)

 sunxi_power_switch((void *)cpucfg + SUN8I_R40_PWR_CLAMP(cpu),
(void *)cpucfg + SUN8I_R40_PWROFF,
-  on, 0);
+  on, cpu);

I think this is the only change that is needed. Looking again at the
R40 user manual, the original code turned off core 0 regardless of
which core was being brought down.

Could you give that a try? The power clamp stuff shouldn't change
much, as the end result is the same. The readback might make a
difference, but if it does, it should be applied to all SoCs.

Just change the last params of sunxi_power_switch can also work fine.

diff --git a/arch/arm/cpu/armv7/sunxi/psci.c 
b/arch/arm/cpu/armv7/sunxi/psci.c

index 1ac50f558a..ae21879e69 100644
--- a/arch/arm/cpu/armv7/sunxi/psci.c
+++ b/arch/arm/cpu/armv7/sunxi/psci.c
@@ -153,7 +153,7 @@ static void __secure sunxi_cpu_set_power(int cpu, 
bool on)


    sunxi_power_switch((void *)cpucfg + SUN8I_R40_PWR_CLAMP(cpu),
   (void *)cpucfg + SUN8I_R40_PWROFF,
-  on, 0);
+  on, cpu);
 }
 #else /* ! CONFIG_MACH_SUN7I && ! CONFIG_MACH_SUN8I_R40 */
 static void __secure sunxi_cpu_set_power(int cpu, bool on)

The readback might as same as __mdelay.

But I can't make sure the 0xfe, 0x80 ... 0x00 sequence number when 
clame_release.



Regards
ChenYu


  }
  #else /* ! CONFIG_MACH_SUN7I && ! CONFIG_MACH_SUN8I_R40 */
  static void __secure sunxi_cpu_set_power(int cpu, bool on)
--
2.25.1





Re: [PATCH v2] sunxi: psci: Fix sunxi_power_switch on sun8i-r40 platform

2022-05-13 Thread Chen-Yu Tsai
Hi,

On Sat, May 14, 2022 at 11:19 AM  wrote:
>
> From: qianfan Zhao 
>
> linux system will die if we offline one of the cpu on R40 based board:
> eg: echo 0 > /sys/devices/system/cpu/cpu3/online
>
> Fixed sunxi_power_switch based on allwinner lichee 3.10 kernel driver.
>
> Signed-off-by: qianfan Zhao 

Please add a Fixes tag.

> ---
> v2 changes: Fix the commit message, the source code doesn't change.
>
>  arch/arm/cpu/armv7/sunxi/psci.c | 24 +++-
>  1 file changed, 19 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c
> index 1ac50f558a..63186a9388 100644
> --- a/arch/arm/cpu/armv7/sunxi/psci.c
> +++ b/arch/arm/cpu/armv7/sunxi/psci.c
> @@ -79,8 +79,7 @@ static void __secure __mdelay(u32 ms)
>  static void __secure clamp_release(u32 __maybe_unused *clamp)
>  {
>  #if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN7I) || \
> -   defined(CONFIG_MACH_SUN8I_H3) || \
> -   defined(CONFIG_MACH_SUN8I_R40)
> +   defined(CONFIG_MACH_SUN8I_H3)
> u32 tmp = 0x1ff;
> do {
> tmp >>= 1;
> @@ -88,15 +87,30 @@ static void __secure clamp_release(u32 __maybe_unused 
> *clamp)
> } while (tmp);
>
> __mdelay(10);
> +#elif defined(CONFIG_MACH_SUN8I_R40)
> +   u8 i, tmp = 0xfe;
> +
> +   for (i = 0; i < 5; i++) { /* 0xfe, 0xf8, 0xe0, 0x80, 0x00 */
> +   writel(tmp, clamp);
> +   tmp <<= 2;
> +   }
> +
> +   while (0x00 != readl(clamp)) {
> +   ;
> +   }
>  #endif
>  }
>
>  static void __secure clamp_set(u32 __maybe_unused *clamp)
>  {
>  #if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN7I) || \
> -   defined(CONFIG_MACH_SUN8I_H3) || \
> -   defined(CONFIG_MACH_SUN8I_R40)
> +   defined(CONFIG_MACH_SUN8I_H3)
> writel(0xff, clamp);
> +#elif defined(CONFIG_MACH_SUN8I_R40)
> +   writel(0xff, clamp);
> +   while (0xff != readl(clamp)) {
> +   ;
> +   }
>  #endif
>  }
>
> @@ -153,7 +167,7 @@ static void __secure sunxi_cpu_set_power(int cpu, bool on)
>
> sunxi_power_switch((void *)cpucfg + SUN8I_R40_PWR_CLAMP(cpu),
>(void *)cpucfg + SUN8I_R40_PWROFF,
> -  on, 0);
> +  on, cpu);

I think this is the only change that is needed. Looking again at the
R40 user manual, the original code turned off core 0 regardless of
which core was being brought down.

Could you give that a try? The power clamp stuff shouldn't change
much, as the end result is the same. The readback might make a
difference, but if it does, it should be applied to all SoCs.


Regards
ChenYu

>  }
>  #else /* ! CONFIG_MACH_SUN7I && ! CONFIG_MACH_SUN8I_R40 */
>  static void __secure sunxi_cpu_set_power(int cpu, bool on)
> --
> 2.25.1
>


[PATCH v2] sunxi: psci: Fix sunxi_power_switch on sun8i-r40 platform

2022-05-13 Thread qianfanguijin
From: qianfan Zhao 

linux system will die if we offline one of the cpu on R40 based board:
eg: echo 0 > /sys/devices/system/cpu/cpu3/online

Fixed sunxi_power_switch based on allwinner lichee 3.10 kernel driver.

Signed-off-by: qianfan Zhao 
---
v2 changes: Fix the commit message, the source code doesn't change.

 arch/arm/cpu/armv7/sunxi/psci.c | 24 +++-
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c
index 1ac50f558a..63186a9388 100644
--- a/arch/arm/cpu/armv7/sunxi/psci.c
+++ b/arch/arm/cpu/armv7/sunxi/psci.c
@@ -79,8 +79,7 @@ static void __secure __mdelay(u32 ms)
 static void __secure clamp_release(u32 __maybe_unused *clamp)
 {
 #if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN7I) || \
-   defined(CONFIG_MACH_SUN8I_H3) || \
-   defined(CONFIG_MACH_SUN8I_R40)
+   defined(CONFIG_MACH_SUN8I_H3)
u32 tmp = 0x1ff;
do {
tmp >>= 1;
@@ -88,15 +87,30 @@ static void __secure clamp_release(u32 __maybe_unused 
*clamp)
} while (tmp);
 
__mdelay(10);
+#elif defined(CONFIG_MACH_SUN8I_R40)
+   u8 i, tmp = 0xfe;
+
+   for (i = 0; i < 5; i++) { /* 0xfe, 0xf8, 0xe0, 0x80, 0x00 */
+   writel(tmp, clamp);
+   tmp <<= 2;
+   }
+
+   while (0x00 != readl(clamp)) {
+   ;
+   }
 #endif
 }
 
 static void __secure clamp_set(u32 __maybe_unused *clamp)
 {
 #if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN7I) || \
-   defined(CONFIG_MACH_SUN8I_H3) || \
-   defined(CONFIG_MACH_SUN8I_R40)
+   defined(CONFIG_MACH_SUN8I_H3)
writel(0xff, clamp);
+#elif defined(CONFIG_MACH_SUN8I_R40)
+   writel(0xff, clamp);
+   while (0xff != readl(clamp)) {
+   ;
+   }
 #endif
 }
 
@@ -153,7 +167,7 @@ static void __secure sunxi_cpu_set_power(int cpu, bool on)
 
sunxi_power_switch((void *)cpucfg + SUN8I_R40_PWR_CLAMP(cpu),
   (void *)cpucfg + SUN8I_R40_PWROFF,
-  on, 0);
+  on, cpu);
 }
 #else /* ! CONFIG_MACH_SUN7I && ! CONFIG_MACH_SUN8I_R40 */
 static void __secure sunxi_cpu_set_power(int cpu, bool on)
-- 
2.25.1



Broken support for 4GB DDR on 32-bit platforms

2022-05-13 Thread Pali Rohár
Hello! I tried to enable support for 2GB+ of DDR memory (with 4GB DDR3)
on powerpc P2020 board in 32-bit addressing mode and U-Boot crashed
during startup.

I figured out that issue is not powerpc specific, but rather generic to
all 32-bit platforms. U-Boot stores memory size into phys_size_t type
(gd->ram_size) and last mapped memory address increased by one byte into
phys_addr_t type (gd->ram_top).

Despite size 4GB fits into 32-bit addressing mode, it does not fit into
above two variables, and it overflows to zero. U-Boot then see zero RAM
size and crashes.

I tried to workaround this issue by changing both phys_size_t and
phys_addr_t types to 64-bit. But it did not helped because U-Boot on
many places cast gd->ram_size or gd->ram_top to ulong type, which is
32-bit on 32-bit platforms.

Next I changed ulong parameters of board_get_usable_ram_top() function
to u64.

This still was not enough because config value CONFIG_MAX_MEM_MAPPED is
ignored on one important place -- in function get_effective_memsize().
This config value takes effect only when also CONFIG_VERY_BIG_RAM is
set.

Finally With this change I was able to start U-Boot with more than 2GB
of DDR memory inserted in SODIMM slot on P2020.

How to fix issues with gd->ram_size and gd->ram_top? That +1 byte is
really stupid limitation. Changing phys_size_t and phys_addr_t types
unconditionally to 64-bit? Or something else?

And what is the purpose of CONFIG_VERY_BIG_RAM config option? Why is
CONFIG_MAX_MEM_MAPPED check skipped in get_effective_memsize() function,
but is not skipped on many more places?


[PATCH] mtd: mtdpart: Change size type from fdt_addr_t to fdt_size_t

2022-05-13 Thread Pali Rohár
Set correct type for 3rd argument of ofnode_get_addr_size_index_notrans()
function. It expects fdt_size_t * and not fdt_addr_t *.

When these two types do not have same size then U-Boot throw compile
warning:

drivers/mtd/mtdpart.c: In function ‘add_mtd_partitions_of’:
drivers/mtd/mtdpart.c:906:57: warning: passing argument 3 of 
‘ofnode_get_addr_size_index_notrans’ from incompatible pointer type 
[-Wincompatible-pointer-types]
   offset = ofnode_get_addr_size_index_notrans(child, 0, );
 ^
In file included from include/dm/device.h:13,
 from include/linux/mtd/mtd.h:26,
 from include/ubi_uboot.h:28,
 from drivers/mtd/mtdpart.c:27:
include/dm/ofnode.h:530:25: note: expected ‘fdt_size_t *’ {aka ‘long long 
unsigned int *’} but argument is of type ‘fdt_addr_t *’ {aka ‘long unsigned int 
*’}
 fdt_size_t *size);
 ^~~~

Signed-off-by: Pali Rohár 
---
 drivers/mtd/mtdpart.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 4119ea4ff6b0..adc0515730d5 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -898,7 +898,8 @@ int add_mtd_partitions_of(struct mtd_info *master)
ofnode_for_each_subnode(child, parts) {
struct mtd_partition part = { 0 };
struct mtd_info *slave;
-   fdt_addr_t offset, size;
+   fdt_addr_t offset;
+   fdt_size_t size;
 
if (!ofnode_is_available(child))
continue;
-- 
2.20.1



[PATCH 2/2] tpm: add support for TPMv2.x I2C chips

2022-05-13 Thread Eddie James
Add the tpm2_tis_i2c driver that should support any TPMv2 compliant
I2C chips, such as the NPCT75X chip.

Signed-off-by: Eddie James 
---
 drivers/tpm/Kconfig|   9 ++
 drivers/tpm/Makefile   |   1 +
 drivers/tpm/tpm2_tis_i2c.c | 171 +
 3 files changed, 181 insertions(+)
 create mode 100644 drivers/tpm/tpm2_tis_i2c.c

diff --git a/drivers/tpm/Kconfig b/drivers/tpm/Kconfig
index eceff27d5f..d59102d9a6 100644
--- a/drivers/tpm/Kconfig
+++ b/drivers/tpm/Kconfig
@@ -185,6 +185,15 @@ config TPM2_TIS_SPI
  to the device using the standard TPM Interface Specification (TIS)
  protocol.
 
+config TPM2_TIS_I2C
+   bool "Enable support for TPMv2.x I2C chips"
+   depends on TPM_V2 && DM_I2C
+   help
+ This driver supports TPMv2.x devices connected on the I2C bus.
+ The usual TPM operations and the 'tpm' command can be used to talk
+ to the device using the standard TPM Interface Specification (TIS)
+ protocol.
+
 config TPM2_FTPM_TEE
bool "TEE based fTPM Interface"
depends on TEE && OPTEE && TPM_V2
diff --git a/drivers/tpm/Makefile b/drivers/tpm/Makefile
index 51725230c7..9540fd7fe7 100644
--- a/drivers/tpm/Makefile
+++ b/drivers/tpm/Makefile
@@ -13,5 +13,6 @@ obj-$(CONFIG_TPM_ST33ZP24_SPI) += tpm_tis_st33zp24_spi.o
 obj-$(CONFIG_$(SPL_TPL_)TPM2_CR50_I2C) += cr50_i2c.o
 obj-$(CONFIG_TPM2_TIS_SANDBOX) += tpm2_tis_sandbox.o sandbox_common.o
 obj-$(CONFIG_TPM2_TIS_SPI) += tpm2_tis_core.o tpm2_tis_spi.o
+obj-$(CONFIG_TPM2_TIS_I2C) += tpm2_tis_core.o tpm2_tis_i2c.o
 obj-$(CONFIG_TPM2_FTPM_TEE) += tpm2_ftpm_tee.o
 obj-$(CONFIG_TPM2_MMIO) += tpm2_tis_core.o tpm2_tis_mmio.o
diff --git a/drivers/tpm/tpm2_tis_i2c.c b/drivers/tpm/tpm2_tis_i2c.c
new file mode 100644
index 00..33cd5bb84b
--- /dev/null
+++ b/drivers/tpm/tpm2_tis_i2c.c
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2022 IBM Corp.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "tpm_tis.h"
+#include "tpm_internal.h"
+
+struct tpm_tis_chip_data {
+   unsigned int pcr_count;
+   unsigned int pcr_select_min;
+};
+
+static uint tpm_tis_i2c_address_to_register(u32 addr)
+{
+   addr &= 0xFFF;
+
+   /*
+* Adapt register addresses that have changed compared to older TIS
+* version.
+*/
+   switch (addr) {
+   case TPM_ACCESS(0):
+   return 0x04;
+   case TPM_DID_VID(0):
+   return 0x48;
+   case TPM_RID(0):
+   return 0x4C;
+   default:
+   return addr;
+   }
+}
+
+static int tpm_tis_i2c_read(struct udevice *dev, u32 addr, u16 len, u8 *in)
+{
+   int rc;
+   int count = 0;
+   uint reg = tpm_tis_i2c_address_to_register(addr);
+
+   do {
+   rc = dm_i2c_read(dev, reg, in, len);
+   udelay(SLEEP_DURATION_US);
+   } while (rc && count++ < MAX_COUNT);
+
+   return rc;
+}
+
+static int tpm_tis_i2c_write(struct udevice *dev, u32 addr, u16 len,
+const u8 *out)
+{
+   int rc;
+   int count = 0;
+   uint reg = tpm_tis_i2c_address_to_register(addr);
+
+   do {
+   rc = dm_i2c_write(dev, reg, out, len);
+   udelay(SLEEP_DURATION_US);
+   } while (rc && count++ < MAX_COUNT);
+
+   return rc;
+}
+
+static int tpm_tis_i2c_read32(struct udevice *dev, u32 addr, u32 *result)
+{
+   __le32 result_le;
+   int rc;
+
+   rc = tpm_tis_i2c_read(dev, addr, sizeof(u32), (u8 *)_le);
+   if (!rc)
+   *result = le32_to_cpu(result_le);
+
+   return rc;
+}
+
+static int tpm_tis_i2c_write32(struct udevice *dev, u32 addr, u32 value)
+{
+   __le32 value_le = cpu_to_le32(value);
+
+   return tpm_tis_i2c_write(dev, addr, sizeof(value), (u8 *)_le);
+}
+
+static struct tpm_tis_phy_ops phy_ops = {
+   .read_bytes = tpm_tis_i2c_read,
+   .write_bytes = tpm_tis_i2c_write,
+   .read32 = tpm_tis_i2c_read32,
+   .write32 = tpm_tis_i2c_write32,
+};
+
+static int tpm_tis_i2c_probe(struct udevice *udev)
+{
+   struct tpm_tis_chip_data *drv_data = (void *)dev_get_driver_data(udev);
+   struct tpm_chip_priv *priv = dev_get_uclass_priv(udev);
+   int rc;
+   u8 loc = 0;
+
+   tpm_tis_ops_register(udev, _ops);
+
+   /*
+* Force locality 0. The core driver doesn't actually write the
+* locality register and instead just reads/writes various access
+* bits of the selected locality.
+*/
+   rc = dm_i2c_write(udev, 0, , 1);
+   if (rc)
+   return rc;
+
+   rc = tpm_tis_init(udev);
+   if (rc)
+   return rc;
+
+   priv->pcr_count = drv_data->pcr_count;
+   priv->pcr_select_min = drv_data->pcr_select_min;
+   priv->version = TPM_V2;
+
+   return 0;
+}
+
+static int 

[PATCH 1/2] tpm: core: Set timeouts before requesting locality

2022-05-13 Thread Eddie James
Requesting the locality uses the timeout values, so they need
to be set beforehand.

Signed-off-by: Eddie James 
---
 drivers/tpm/tpm2_tis_core.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/tpm/tpm2_tis_core.c b/drivers/tpm/tpm2_tis_core.c
index 51392c4584..985a816219 100644
--- a/drivers/tpm/tpm2_tis_core.c
+++ b/drivers/tpm/tpm2_tis_core.c
@@ -433,15 +433,16 @@ int tpm_tis_init(struct udevice *dev)
log_err("Driver bug. No bus ops defined\n");
return -1;
}
-   ret = tpm_tis_request_locality(dev, 0);
-   if (ret)
-   return ret;
 
chip->timeout_a = TIS_SHORT_TIMEOUT_MS;
chip->timeout_b = TIS_LONG_TIMEOUT_MS;
chip->timeout_c = TIS_SHORT_TIMEOUT_MS;
chip->timeout_d = TIS_SHORT_TIMEOUT_MS;
 
+   ret = tpm_tis_request_locality(dev, 0);
+   if (ret)
+   return ret;
+
/* Disable interrupts */
phy_ops->read32(dev, TPM_INT_ENABLE(chip->locality), );
tmp |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT |
-- 
2.27.0



[PATCH 0/2] tpm: Add support for TPMv2.x I2C chips

2022-05-13 Thread Eddie James
Add a tpm driver that should support any TPMv2 compliant I2C chips,
such as the NPCT75X chip. In my testing I also noticed that the timeouts
weren't set before requesting the locality so I have included a fix.

Eddie James (2):
  tpm: core: Set timeouts before requesting locality
  tpm: add support for TPMv2.x I2C chips

 drivers/tpm/Kconfig |   9 ++
 drivers/tpm/Makefile|   1 +
 drivers/tpm/tpm2_tis_core.c |   7 +-
 drivers/tpm/tpm2_tis_i2c.c  | 171 
 4 files changed, 185 insertions(+), 3 deletions(-)
 create mode 100644 drivers/tpm/tpm2_tis_i2c.c

-- 
2.27.0



Re: imx6ull: NAND boot fails when block 0x00000000 is bad

2022-05-13 Thread Michael Nazzareno Trimarchi
Hi Thierry

Il ven 13 mag 2022, 19:56 Fabio Estevam  ha scritto:

> [Adding some more folks]
>
> On Fri, May 13, 2022 at 2:41 PM Thierry Bultel
>  wrote:
> >
> > Hi,
> >
> > I have a imx6ull module from Toradex, with NAND flash. U-boot does not
> > have SPL.
> > I does not boot from NAND flash anymore, I was able to flash it several
> > times with tezi, as well as with
> > nandbcb (that I discovered more recently).
> >
> > There are error messages complaining about some bad blocks, including
> > block 0x.
> >
> > Toradex say that the module cannot be recovered, but this seems in
> > contradiction with what we can read
> > from the iMX6 reference manual, where the boot process description
> > mentions that the ROM can attempt to
> > seek for FCB several times.
> >
> > I attempted to use nandbcb to write the FCB at next block, ie 0x2
> > (attempting a lower value
> > makes nandbcb complain that I am not writing to an aligned location),
> > with no better success.
> >
> > What is your mind about that ? Sounds that the answer could be in
> > mis-configured fuses,
> > else I consider that having block 0x causes a bricked board, as
> > a weakness for production,
> > in other words, an unreliable product.
>

What U-Boot version are you using? Anyway block 0 is always guarantee by
nand manufacturer, so having that bad look strange

Michael

> >
> > Best regards
> > Thierry
> >
> >
> > --
> > Re: test
> > www.linatsea.fr 
> > --
> > www.linatsea.fr
>


Re: imx6ull: NAND boot fails when block 0x00000000 is bad

2022-05-13 Thread Fabio Estevam
[Adding some more folks]

On Fri, May 13, 2022 at 2:41 PM Thierry Bultel
 wrote:
>
> Hi,
>
> I have a imx6ull module from Toradex, with NAND flash. U-boot does not
> have SPL.
> I does not boot from NAND flash anymore, I was able to flash it several
> times with tezi, as well as with
> nandbcb (that I discovered more recently).
>
> There are error messages complaining about some bad blocks, including
> block 0x.
>
> Toradex say that the module cannot be recovered, but this seems in
> contradiction with what we can read
> from the iMX6 reference manual, where the boot process description
> mentions that the ROM can attempt to
> seek for FCB several times.
>
> I attempted to use nandbcb to write the FCB at next block, ie 0x2
> (attempting a lower value
> makes nandbcb complain that I am not writing to an aligned location),
> with no better success.
>
> What is your mind about that ? Sounds that the answer could be in
> mis-configured fuses,
> else I consider that having block 0x causes a bricked board, as
> a weakness for production,
> in other words, an unreliable product.
>
> Best regards
> Thierry
>
>
> --
> Re: test
> www.linatsea.fr 
> --
> www.linatsea.fr


imx6ull: NAND boot fails when block 0x00000000 is bad

2022-05-13 Thread Thierry Bultel

Hi,

I have a imx6ull module from Toradex, with NAND flash. U-boot does not 
have SPL.
I does not boot from NAND flash anymore, I was able to flash it several 
times with tezi, as well as with

nandbcb (that I discovered more recently).

There are error messages complaining about some bad blocks, including 
block 0x.


Toradex say that the module cannot be recovered, but this seems in 
contradiction with what we can read
from the iMX6 reference manual, where the boot process description 
mentions that the ROM can attempt to

seek for FCB several times.

I attempted to use nandbcb to write the FCB at next block, ie 0x2 
(attempting a lower value
makes nandbcb complain that I am not writing to an aligned location), 
with no better success.


What is your mind about that ? Sounds that the answer could be in 
mis-configured fuses,
else I consider that having block 0x causes a bricked board, as 
a weakness for production,

in other words, an unreliable product.

Best regards
Thierry


--
Re: test
www.linatsea.fr 
--
www.linatsea.fr

Re: [PATCH v2 1/6] arm_ffa: introduce Arm FF-A low-level driver

2022-05-13 Thread Jens Wiklander
On Fri, Apr 15, 2022 at 01:27:58PM +0100, abdellatif.elkhl...@arm.com wrote:
> From: Abdellatif El Khlifi 
> 
> Add the driver implementing Arm Firmware Framework for Armv8-A v1.0
> 
> The Firmware Framework for Arm A-profile processors (FF-A)
> describes interfaces (ABIs) that standardize communication
> between the Secure World and Normal World leveraging TrustZone
> technology. This driver uses SMC32 calling convention.

How come only the SMC32 calling convention is used? What if you need
64-bit pointers for some reason (RXTX_MAP comes to mind) ? Doing the
64-bit calling convention at the same time can't be much more work.

> 
> In u-boot FF-A design, FF-A is considered as a discoverable bus.
> The Secure World is considered as one entity to communicate with
> using the FF-A bus. FF-A communication is handled by one device and
> one instance (the bus). This FF-A driver takes care of all the
> interactions between Normal world and Secure World.
> 
> The driver provides helper FF-A interfaces for user layers.
> These helper functions allow clients to pass data and select the
> FF-A function to use for the communication with secure world.
> 
> Signed-off-by: Abdellatif El Khlifi 
> ---
>  MAINTAINERS  |8 +
>  arch/arm/cpu/armv8/smccc-call.S  |   27 +
>  arch/arm/lib/asm-offsets.c   |6 +
>  common/board_r.c |7 +
>  drivers/Kconfig  |2 +
>  drivers/Makefile |1 +
>  drivers/arm-ffa/Kconfig  |   27 +
>  drivers/arm-ffa/Makefile |6 +
>  drivers/arm-ffa/arm-ffa-uclass.c |   64 ++
>  drivers/arm-ffa/arm_ffa_prv.h|  193 +
>  drivers/arm-ffa/core.c   | 1349 ++
>  include/arm_ffa.h|  190 +
>  include/arm_ffa_helper.h |   45 +
>  include/dm/uclass-id.h   |1 +
>  include/linux/arm-smccc.h|   28 +-
>  lib/Kconfig  |1 +
>  lib/Makefile |1 +
>  lib/arm-ffa/Kconfig  |6 +
>  lib/arm-ffa/Makefile |8 +
>  lib/arm-ffa/arm_ffa_helper.c |  188 +
>  lib/efi_loader/efi_boottime.c|   17 +
>  21 files changed, 2174 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/arm-ffa/Kconfig
>  create mode 100644 drivers/arm-ffa/Makefile
>  create mode 100644 drivers/arm-ffa/arm-ffa-uclass.c
>  create mode 100644 drivers/arm-ffa/arm_ffa_prv.h
>  create mode 100644 drivers/arm-ffa/core.c
>  create mode 100644 include/arm_ffa.h
>  create mode 100644 include/arm_ffa_helper.h
>  create mode 100644 lib/arm-ffa/Kconfig
>  create mode 100644 lib/arm-ffa/Makefile
>  create mode 100644 lib/arm-ffa/arm_ffa_helper.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index aca97cd2a3..efa17206b8 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -232,6 +232,14 @@ F:   board/CZ.NIC/
>  F:   configs/turris_*_defconfig
>  F:   include/configs/turris_*.h
>  
> +ARM FF-A
> +M:   Abdellatif El Khlifi 
> +S:   Maintained
> +F:   drivers/arm-ffa/
> +F:   include/arm_ffa.h
> +F:   include/arm_ffa_helper.h
> +F:   lib/arm-ffa/
> +
>  ARM FREESCALE IMX
>  M:   Stefano Babic 
>  M:   Fabio Estevam 
> diff --git a/arch/arm/cpu/armv8/smccc-call.S b/arch/arm/cpu/armv8/smccc-call.S
> index dc92b28777..9a6aebf194 100644
> --- a/arch/arm/cpu/armv8/smccc-call.S
> +++ b/arch/arm/cpu/armv8/smccc-call.S
> @@ -1,6 +1,8 @@
>  /* SPDX-License-Identifier: GPL-2.0 */
>  /*
>   * Copyright (c) 2015, Linaro Limited
> + * (C) Copyright 2022 ARM Limited
> + * Abdellatif El Khlifi 
>   */
>  #include 
>  #include 
> @@ -45,3 +47,28 @@ ENDPROC(__arm_smccc_smc)
>  ENTRY(__arm_smccc_hvc)
>   SMCCC   hvc
>  ENDPROC(__arm_smccc_hvc)
> +
> +#if (IS_ENABLED(CONFIG_ARM_FFA_TRANSPORT))
> +
> + .macro FFASMCCC instr
> + .cfi_startproc
> + \instr  #0
> + ldr x9, [sp]
> + stp x0, x1, [x9, #ARM_SMCCC_RES_X0_OFFS]
> + stp x2, x3, [x9, #ARM_SMCCC_RES_X2_OFFS]
> + stp x4, x5, [x9, #ARM_SMCCC_RES_X4_OFFS]
> + stp x6, x7, [x9, #ARM_SMCCC_RES_X6_OFFS]
> + ret
> + .cfi_endproc
> + .endm
> +
> +/*
> + * void arm_ffa_smccc_smc(unsigned long a0, unsigned long a1, unsigned long 
> a2,
> + * unsigned long a3, unsigned long a4, unsigned long a5,
> + * unsigned long a6, unsigned long a7, struct arm_smccc_res *res)
> + */
> +ENTRY(__arm_ffa_smccc_smc)
> + FFASMCCCsmc
> +ENDPROC(__arm_ffa_smccc_smc)
> +
> +#endif
> diff --git a/arch/arm/lib/asm-offsets.c b/arch/arm/lib/asm-offsets.c
> index 22fd541f9a..02a4a42fe6 100644
> --- a/arch/arm/lib/asm-offsets.c
> +++ b/arch/arm/lib/asm-offsets.c
> @@ -9,6 +9,8 @@
>   * generate asm statements containing #defines,
>   * compile this file to assembler, and then extract the
>   * #defines from the assembly-language output.
> + *
> + * (C) Copyright 2022 ARM Limited
>   */
>  
>  #include 
> @@ -115,6 +117,10 @@ int main(void)
>  #ifdef CONFIG_ARM_SMCCC
>   

Re: [PATCH v2 1/6] arm_ffa: introduce Arm FF-A low-level driver

2022-05-13 Thread Ilias Apalodimas
Hi Abdellatif
On Fri, Apr 15, 2022 at 01:27:58PM +0100, abdellatif.elkhl...@arm.com wrote:
> From: Abdellatif El Khlifi 
> 
> Add the driver implementing Arm Firmware Framework for Armv8-A v1.0
> 
> The Firmware Framework for Arm A-profile processors (FF-A)
> describes interfaces (ABIs) that standardize communication
> between the Secure World and Normal World leveraging TrustZone
> technology. This driver uses SMC32 calling convention.
> 
> In u-boot FF-A design, FF-A is considered as a discoverable bus.
> The Secure World is considered as one entity to communicate with
> using the FF-A bus. FF-A communication is handled by one device and
> one instance (the bus). This FF-A driver takes care of all the
> interactions between Normal world and Secure World.
> 
> The driver provides helper FF-A interfaces for user layers.
> These helper functions allow clients to pass data and select the
> FF-A function to use for the communication with secure world.
> 
> Signed-off-by: Abdellatif El Khlifi 
> +++ b/arch/arm/cpu/armv8/smccc-call.S
> @@ -1,6 +1,8 @@
>  /* SPDX-License-Identifier: GPL-2.0 */
>  /*
>   * Copyright (c) 2015, Linaro Limited
> + * (C) Copyright 2022 ARM Limited
> + * Abdellatif El Khlifi 
>   */
>  #include 
>  #include 
> @@ -45,3 +47,28 @@ ENDPROC(__arm_smccc_smc)
>  ENTRY(__arm_smccc_hvc)
>   SMCCC   hvc
>  ENDPROC(__arm_smccc_hvc)
> +
> +#if (IS_ENABLED(CONFIG_ARM_FFA_TRANSPORT))
> +
> + .macro FFASMCCC instr
> + .cfi_startproc
> + \instr  #0
> + ldr x9, [sp]
> + stp x0, x1, [x9, #ARM_SMCCC_RES_X0_OFFS]
> + stp x2, x3, [x9, #ARM_SMCCC_RES_X2_OFFS]
> + stp x4, x5, [x9, #ARM_SMCCC_RES_X4_OFFS]
> + stp x6, x7, [x9, #ARM_SMCCC_RES_X6_OFFS]
> + ret
> + .cfi_endproc
> + .endm
> +
> +/*
> + * void arm_ffa_smccc_smc(unsigned long a0, unsigned long a1, unsigned long 
> a2,
> + * unsigned long a3, unsigned long a4, unsigned long a5,
> + * unsigned long a6, unsigned long a7, struct arm_smccc_res *res)
> + */
> +ENTRY(__arm_ffa_smccc_smc)
> + FFASMCCCsmc
> +ENDPROC(__arm_ffa_smccc_smc)
> +
> +#endif
> diff --git a/arch/arm/lib/asm-offsets.c b/arch/arm/lib/asm-offsets.c
> index 22fd541f9a..02a4a42fe6 100644
> --- a/arch/arm/lib/asm-offsets.c
> +++ b/arch/arm/lib/asm-offsets.c
> @@ -9,6 +9,8 @@
>   * generate asm statements containing #defines,
>   * compile this file to assembler, and then extract the
>   * #defines from the assembly-language output.
> + *
> + * (C) Copyright 2022 ARM Limited
>   */
>  
>  #include 
> @@ -115,6 +117,10 @@ int main(void)
>  #ifdef CONFIG_ARM_SMCCC
>   DEFINE(ARM_SMCCC_RES_X0_OFFS, offsetof(struct arm_smccc_res, a0));
>   DEFINE(ARM_SMCCC_RES_X2_OFFS, offsetof(struct arm_smccc_res, a2));
> +#if (IS_ENABLED(CONFIG_ARM_FFA_TRANSPORT))
> + DEFINE(ARM_SMCCC_RES_X4_OFFS, offsetof(struct arm_smccc_res, a4));
> + DEFINE(ARM_SMCCC_RES_X6_OFFS, offsetof(struct arm_smccc_res, a6));
> +#endif
>   DEFINE(ARM_SMCCC_QUIRK_ID_OFFS, offsetof(struct arm_smccc_quirk, id));
>   DEFINE(ARM_SMCCC_QUIRK_STATE_OFFS, offsetof(struct arm_smccc_quirk, 
> state));
>  #endif
> diff --git a/common/board_r.c b/common/board_r.c
> index b92c1bb0be..bb5f1d0aa6 100644
> --- a/common/board_r.c
> +++ b/common/board_r.c
> @@ -62,6 +62,10 @@
>  #include 
>  #include 
>  
> +#ifdef CONFIG_ARM_FFA_TRANSPORT
> +#include 
> +#endif
> +
>  DECLARE_GLOBAL_DATA_PTR;
>  
>  ulong monitor_flash_len;
> @@ -771,6 +775,9 @@ static init_fnc_t init_sequence_r[] = {
>   INIT_FUNC_WATCHDOG_RESET
>   initr_net,
>  #endif
> +#ifdef CONFIG_ARM_FFA_TRANSPORT
> + ffa_helper_bus_discover,
> +#endif
>  #ifdef CONFIG_POST
>   initr_post,
>  #endif
> diff --git a/drivers/Kconfig b/drivers/Kconfig
> index b26ca8cf70..e83c23789d 100644
> --- a/drivers/Kconfig
> +++ b/drivers/Kconfig
> @@ -6,6 +6,8 @@ source "drivers/core/Kconfig"
>  
>  source "drivers/adc/Kconfig"
>  
> +source "drivers/arm-ffa/Kconfig"
> +
>  source "drivers/ata/Kconfig"
>  
>  source "drivers/axi/Kconfig"
> diff --git a/drivers/Makefile b/drivers/Makefile
> index 4e7cf28440..6671d2a604 100644
> --- a/drivers/Makefile
> +++ b/drivers/Makefile
> @@ -107,6 +107,7 @@ obj-y += iommu/
>  obj-y += smem/
>  obj-y += thermal/
>  obj-$(CONFIG_TEE) += tee/
> +obj-$(CONFIG_ARM_FFA_TRANSPORT) += arm-ffa/
>  obj-y += axi/
>  obj-y += ufs/
>  obj-$(CONFIG_W1) += w1/
> diff --git a/drivers/arm-ffa/Kconfig b/drivers/arm-ffa/Kconfig
> new file mode 100644
> index 00..23815534c4
> --- /dev/null
> +++ b/drivers/arm-ffa/Kconfig
> @@ -0,0 +1,27 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +config ARM_FFA_TRANSPORT
> + bool "Enable Arm Firmware Framework for Armv8-A driver"
> + depends on DM && ARM64
> + select ARM_SMCCC if ARM64
> + select LIB_UUID
> + select ARM_FFA_TRANSPORT_HELPERS
> + help
> +   The Firmware Framework for Arm A-profile processors (FF-A)
> +   describes interfaces (ABIs) that standardize 

Re: [PATCH] RockPi4: Add UEFI capsule update support

2022-05-13 Thread Jerome Forissier



On 5/13/22 08:50, Sughosh Ganu wrote:
> Add support for updating the idbloader and u-boot images through the
> UEFI capsule update functionality. Enable the modules required for
> supporting the functionality.
> 
> The implementation is for the updatable images placed on a GPT
> partitioned storage device. With the GPT partition devices, the
> partition information can be obtained at runtime, and hence the
> dfu_alt_info variable needed for the updates is being populated at
> runtime.
> 
> This requires the partitions containing the idbloader and u-boot
> images to be created with the PartitionTypeGUID values set to the
> corresponding image type GUID values defined in the platform's config
> header(ROCKPI_4{B,C}_IDBLOADER_IMAGE_GUID and
> ROCKPI_4{B,C}_UBOOT_IMAGE_GUID).
> 
> Signed-off-by: Sughosh Ganu 
> ---
>  arch/arm/mach-rockchip/Kconfig |   1 +
>  board/rockchip/evb_rk3399/evb-rk3399.c | 190 -
>  configs/rock-pi-4-rk3399_defconfig |   4 +
>  configs/rock-pi-4c-rk3399_defconfig|   4 +
>  include/configs/rk3399_common.h|  16 +++
>  5 files changed, 214 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
> index 18aff5480b..6d13e7b92e 100644
> --- a/arch/arm/mach-rockchip/Kconfig
> +++ b/arch/arm/mach-rockchip/Kconfig
> @@ -246,6 +246,7 @@ config ROCKCHIP_RK3399
>   select DM_PMIC
>   select DM_REGULATOR_FIXED
>   select BOARD_LATE_INIT
> + imply PARTITION_TYPE_GUID
>   imply PRE_CONSOLE_BUFFER
>   imply ROCKCHIP_COMMON_BOARD
>   imply ROCKCHIP_SDRAM_COMMON
> diff --git a/board/rockchip/evb_rk3399/evb-rk3399.c 
> b/board/rockchip/evb_rk3399/evb-rk3399.c
> index abb76585cf..cc976d9471 100644
> --- a/board/rockchip/evb_rk3399/evb-rk3399.c
> +++ b/board/rockchip/evb_rk3399/evb-rk3399.c
> @@ -5,11 +5,27 @@
>  
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
> +#include 
> +#include 
> +#include 
>  #include 
>  #include 
>  
> +#define ROCKPI4_UPDATABLE_IMAGES 2
> +
> +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT)
> +struct efi_fw_image fw_images[ROCKPI4_UPDATABLE_IMAGES] = {0};
> +
> +struct efi_capsule_update_info update_info = {
> + .images = fw_images,
> +};
> +
> +u8 num_image_type_guids = ARRAY_SIZE(fw_images);
> +#endif
> +
>  #ifndef CONFIG_SPL_BUILD
>  int board_early_init_f(void)
>  {
> @@ -29,4 +45,176 @@ int board_early_init_f(void)
>  out:
>   return 0;
>  }
> -#endif
> +
> +#if defined(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) && defined(CONFIG_EFI_PARTITION)
> +
> +#define DFU_ALT_BUF_LEN SZ_1K
> +
> +static bool board_is_rockpi_4b(void)
> +{
> + return CONFIG_IS_ENABLED(TARGET_EVB_RK3399) &&
> + of_machine_is_compatible("radxa,rockpi4b");
> +}
> +
> +static bool board_is_rockpi_4c(void)
> +{
> + return CONFIG_IS_ENABLED(TARGET_EVB_RK3399) &&
> + of_machine_is_compatible("radxa,rockpi4c");
> +}
> +
> +static bool updatable_image(struct disk_partition *info)
> +{
> + int i;
> + bool ret = false;
> + efi_guid_t image_type_guid;
> +
> + uuid_str_to_bin(info->type_guid, image_type_guid.b,
> + UUID_STR_FORMAT_GUID);
> +
> + for (i = 0; i < ROCKPI4_UPDATABLE_IMAGES; i++) {
> + if (!guidcmp(_images[i].image_type_id, _type_guid)) {
> + ret = true;
> + break;
> + }
> + }
> +
> + return ret;
> +}
> +
> +static void set_image_index(struct disk_partition *info, int index)
> +{
> + int i;
> + efi_guid_t image_type_guid;
> +
> + uuid_str_to_bin(info->type_guid, image_type_guid.b,
> + UUID_STR_FORMAT_GUID);
> +
> + for (i = 0; i < ROCKPI4_UPDATABLE_IMAGES; i++) {
> + if (!guidcmp(_images[i].image_type_id, _type_guid)) {
> + fw_images[i].image_index = index;
> + break;
> + }
> + }
> +}
> +
> +static int get_mmc_desc(struct blk_desc **desc)
> +{
> + int ret;
> + struct mmc *mmc;
> + struct udevice *dev;
> +
> + /*
> +  * For now the firmware images are assumed to
> +  * be on the SD card
> +  */
> + ret = uclass_get_device(UCLASS_MMC, 1, );
> + if (ret)
> + return -1;
> +
> + mmc = mmc_get_mmc_dev(dev);
> + if (!mmc)
> + return -1;
> +
> + if (mmc_init(mmc))
> + return -1;
> +
> + *desc = mmc_get_blk_desc(mmc);
> + if (!*desc)
> + return -1;
> +
> + return 0;
> +}
> +
> +void set_dfu_alt_info(char *interface, char *devstr)
> +{
> + const char *name;
> + bool first = true;
> + int p, len, devnum, ret;
> + char buf[DFU_ALT_BUF_LEN];
> + struct disk_partition info;
> + struct blk_desc *desc = NULL;
> +
> + ret = get_mmc_desc();
> + if (ret)
> + return;
> +
> + memset(buf, 0, sizeof(buf));
> + name = blk_get_if_type_name(desc->if_type);
> + devnum = 

[PATCH v2] arm: socfpga: soc64: To notify SDM when U-Boot pass control to Linux

2022-05-13 Thread dinesh . maniyam
From: Dinesh Maniyam 

Prior U-Boot pass control to Linux, U-Boot will send a mailbox command
"HPS_STAGE_NOTIFY" to notify Secure Device Manager (SDM) on HPS SW
transition.

Signed-off-by: Dinesh Maniyam 

---

v1->v2
Add space in title
---
 arch/arm/mach-socfpga/misc_soc64.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/mach-socfpga/misc_soc64.c 
b/arch/arm/mach-socfpga/misc_soc64.c
index 2acdfad07b..3148eb46a5 100644
--- a/arch/arm/mach-socfpga/misc_soc64.c
+++ b/arch/arm/mach-socfpga/misc_soc64.c
@@ -89,3 +89,8 @@ void do_bridge_reset(int enable, unsigned int mask)

socfpga_bridges_reset(enable);
 }
+
+void arch_preboot_os(void)
+{
+   mbox_hps_stage_notify(HPS_EXECUTION_STATE_OS);
+}
\ No newline at end of file
--
2.26.2



[PATCH v2] ddr: altera: soc64: Integer fix overflow that caused DDR size mismatched

2022-05-13 Thread dinesh . maniyam
From: Dinesh Maniyam 

Convert the constant integer to 'phys_size_t' to avoid overflow
when calculating the SDRAM size.

Signed-off-by: Dinesh Maniyam 

---

v1->v2
- Add space in title
---
 drivers/ddr/altera/sdram_soc64.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/ddr/altera/sdram_soc64.c b/drivers/ddr/altera/sdram_soc64.c
index d6baac2410..1f479c514d 100644
--- a/drivers/ddr/altera/sdram_soc64.c
+++ b/drivers/ddr/altera/sdram_soc64.c
@@ -239,7 +239,8 @@ phys_size_t sdram_calculate_size(struct altera_sdram_plat 
*plat)
 {
u32 dramaddrw = hmc_readl(plat, DRAMADDRW);

-   phys_size_t size = 1 << (DRAMADDRW_CFG_CS_ADDR_WIDTH(dramaddrw) +
+   phys_size_t size = (phys_size_t)1 <<
+   (DRAMADDRW_CFG_CS_ADDR_WIDTH(dramaddrw) +
 DRAMADDRW_CFG_BANK_GRP_ADDR_WIDTH(dramaddrw) +
 DRAMADDRW_CFG_BANK_ADDR_WIDTH(dramaddrw) +
 DRAMADDRW_CFG_ROW_ADDR_WIDTH(dramaddrw) +
--
2.26.2



Re: [PATCH v1] sunxi: psci: Fix sunxi_power_switch on sun8i-r40 platform

2022-05-13 Thread Peter Robinson
On Fri, May 13, 2022 at 10:25 AM  wrote:
>
> From: qianfan Zhao 
>
> linux system will dead if we offline one of the cpu on R40 based board:

Minor nit this should read "will die" not "will dead"

> eg: echo 0 > /sys/devices/system/cpu/cpu3/online
>
> Fixed sunxi_power_switch based on allwinner lichee 3.10 kernel driver.
>
> Signed-off-by: qianfan Zhao 
> ---
>  arch/arm/cpu/armv7/sunxi/psci.c | 24 +++-
>  1 file changed, 19 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c
> index 1ac50f558a..63186a9388 100644
> --- a/arch/arm/cpu/armv7/sunxi/psci.c
> +++ b/arch/arm/cpu/armv7/sunxi/psci.c
> @@ -79,8 +79,7 @@ static void __secure __mdelay(u32 ms)
>  static void __secure clamp_release(u32 __maybe_unused *clamp)
>  {
>  #if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN7I) || \
> -   defined(CONFIG_MACH_SUN8I_H3) || \
> -   defined(CONFIG_MACH_SUN8I_R40)
> +   defined(CONFIG_MACH_SUN8I_H3)
> u32 tmp = 0x1ff;
> do {
> tmp >>= 1;
> @@ -88,15 +87,30 @@ static void __secure clamp_release(u32 __maybe_unused 
> *clamp)
> } while (tmp);
>
> __mdelay(10);
> +#elif defined(CONFIG_MACH_SUN8I_R40)
> +   u8 i, tmp = 0xfe;
> +
> +   for (i = 0; i < 5; i++) { /* 0xfe, 0xf8, 0xe0, 0x80, 0x00 */
> +   writel(tmp, clamp);
> +   tmp <<= 2;
> +   }
> +
> +   while (0x00 != readl(clamp)) {
> +   ;
> +   }
>  #endif
>  }
>
>  static void __secure clamp_set(u32 __maybe_unused *clamp)
>  {
>  #if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN7I) || \
> -   defined(CONFIG_MACH_SUN8I_H3) || \
> -   defined(CONFIG_MACH_SUN8I_R40)
> +   defined(CONFIG_MACH_SUN8I_H3)
> writel(0xff, clamp);
> +#elif defined(CONFIG_MACH_SUN8I_R40)
> +   writel(0xff, clamp);
> +   while (0xff != readl(clamp)) {
> +   ;
> +   }
>  #endif
>  }
>
> @@ -153,7 +167,7 @@ static void __secure sunxi_cpu_set_power(int cpu, bool on)
>
> sunxi_power_switch((void *)cpucfg + SUN8I_R40_PWR_CLAMP(cpu),
>(void *)cpucfg + SUN8I_R40_PWROFF,
> -  on, 0);
> +  on, cpu);
>  }
>  #else /* ! CONFIG_MACH_SUN7I && ! CONFIG_MACH_SUN8I_R40 */
>  static void __secure sunxi_cpu_set_power(int cpu, bool on)
> --
> 2.25.1
>


[PATCH v1] sunxi: psci: Fix sunxi_power_switch on sun8i-r40 platform

2022-05-13 Thread qianfanguijin
From: qianfan Zhao 

linux system will dead if we offline one of the cpu on R40 based board:
eg: echo 0 > /sys/devices/system/cpu/cpu3/online

Fixed sunxi_power_switch based on allwinner lichee 3.10 kernel driver.

Signed-off-by: qianfan Zhao 
---
 arch/arm/cpu/armv7/sunxi/psci.c | 24 +++-
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c
index 1ac50f558a..63186a9388 100644
--- a/arch/arm/cpu/armv7/sunxi/psci.c
+++ b/arch/arm/cpu/armv7/sunxi/psci.c
@@ -79,8 +79,7 @@ static void __secure __mdelay(u32 ms)
 static void __secure clamp_release(u32 __maybe_unused *clamp)
 {
 #if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN7I) || \
-   defined(CONFIG_MACH_SUN8I_H3) || \
-   defined(CONFIG_MACH_SUN8I_R40)
+   defined(CONFIG_MACH_SUN8I_H3)
u32 tmp = 0x1ff;
do {
tmp >>= 1;
@@ -88,15 +87,30 @@ static void __secure clamp_release(u32 __maybe_unused 
*clamp)
} while (tmp);
 
__mdelay(10);
+#elif defined(CONFIG_MACH_SUN8I_R40)
+   u8 i, tmp = 0xfe;
+
+   for (i = 0; i < 5; i++) { /* 0xfe, 0xf8, 0xe0, 0x80, 0x00 */
+   writel(tmp, clamp);
+   tmp <<= 2;
+   }
+
+   while (0x00 != readl(clamp)) {
+   ;
+   }
 #endif
 }
 
 static void __secure clamp_set(u32 __maybe_unused *clamp)
 {
 #if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN7I) || \
-   defined(CONFIG_MACH_SUN8I_H3) || \
-   defined(CONFIG_MACH_SUN8I_R40)
+   defined(CONFIG_MACH_SUN8I_H3)
writel(0xff, clamp);
+#elif defined(CONFIG_MACH_SUN8I_R40)
+   writel(0xff, clamp);
+   while (0xff != readl(clamp)) {
+   ;
+   }
 #endif
 }
 
@@ -153,7 +167,7 @@ static void __secure sunxi_cpu_set_power(int cpu, bool on)
 
sunxi_power_switch((void *)cpucfg + SUN8I_R40_PWR_CLAMP(cpu),
   (void *)cpucfg + SUN8I_R40_PWROFF,
-  on, 0);
+  on, cpu);
 }
 #else /* ! CONFIG_MACH_SUN7I && ! CONFIG_MACH_SUN8I_R40 */
 static void __secure sunxi_cpu_set_power(int cpu, bool on)
-- 
2.25.1



[PATCH 1/1] config: ls2088ardb: Add config CONFIG_SYS_FLASH_CFI_WIDTH

2022-05-13 Thread Priyanka Singh
Add config CONFIG_SYS_FLASH_CFI_WIDTH as FLASH_CFI_16BIT to
fix flash writing issue on ls2088ardb platform introduced by the
commit '53879b1738'
(cfi_flash: Fix detection of 8-bit bus flash devices via address shift)

Signed-off-by: Priyanka Singh 
---
 include/configs/ls2080ardb.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/configs/ls2080ardb.h b/include/configs/ls2080ardb.h
index 60d99a0b37..6445193272 100644
--- a/include/configs/ls2080ardb.h
+++ b/include/configs/ls2080ardb.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0+ */
 /*
- * Copyright 2017, 2019-2021 NXP
+ * Copyright 2017, 2019-2022 NXP
  * Copyright 2015 Freescale Semiconductor
  */
 
@@ -77,6 +77,8 @@
 #define CONFIG_SYS_NOR_FTIM3   0x0400
 #define CONFIG_SYS_IFC_CCR 0x0100
 
+#define CONFIG_SYS_FLASH_CFI_WIDTH  FLASH_CFI_16BIT
+
 #ifdef CONFIG_MTD_NOR_FLASH
 #define CONFIG_SYS_FLASH_QUIET_TEST
 #define CONFIG_FLASH_SHOW_PROGRESS 45 /* count down from 45/5: 9..1 */
-- 
2.17.1



[PATCH] RockPi4: Add UEFI capsule update support

2022-05-13 Thread Sughosh Ganu
Add support for updating the idbloader and u-boot images through the
UEFI capsule update functionality. Enable the modules required for
supporting the functionality.

The implementation is for the updatable images placed on a GPT
partitioned storage device. With the GPT partition devices, the
partition information can be obtained at runtime, and hence the
dfu_alt_info variable needed for the updates is being populated at
runtime.

This requires the partitions containing the idbloader and u-boot
images to be created with the PartitionTypeGUID values set to the
corresponding image type GUID values defined in the platform's config
header(ROCKPI_4{B,C}_IDBLOADER_IMAGE_GUID and
ROCKPI_4{B,C}_UBOOT_IMAGE_GUID).

Signed-off-by: Sughosh Ganu 
---
 arch/arm/mach-rockchip/Kconfig |   1 +
 board/rockchip/evb_rk3399/evb-rk3399.c | 190 -
 configs/rock-pi-4-rk3399_defconfig |   4 +
 configs/rock-pi-4c-rk3399_defconfig|   4 +
 include/configs/rk3399_common.h|  16 +++
 5 files changed, 214 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index 18aff5480b..6d13e7b92e 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -246,6 +246,7 @@ config ROCKCHIP_RK3399
select DM_PMIC
select DM_REGULATOR_FIXED
select BOARD_LATE_INIT
+   imply PARTITION_TYPE_GUID
imply PRE_CONSOLE_BUFFER
imply ROCKCHIP_COMMON_BOARD
imply ROCKCHIP_SDRAM_COMMON
diff --git a/board/rockchip/evb_rk3399/evb-rk3399.c 
b/board/rockchip/evb_rk3399/evb-rk3399.c
index abb76585cf..cc976d9471 100644
--- a/board/rockchip/evb_rk3399/evb-rk3399.c
+++ b/board/rockchip/evb_rk3399/evb-rk3399.c
@@ -5,11 +5,27 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
 
+#define ROCKPI4_UPDATABLE_IMAGES   2
+
+#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT)
+struct efi_fw_image fw_images[ROCKPI4_UPDATABLE_IMAGES] = {0};
+
+struct efi_capsule_update_info update_info = {
+   .images = fw_images,
+};
+
+u8 num_image_type_guids = ARRAY_SIZE(fw_images);
+#endif
+
 #ifndef CONFIG_SPL_BUILD
 int board_early_init_f(void)
 {
@@ -29,4 +45,176 @@ int board_early_init_f(void)
 out:
return 0;
 }
-#endif
+
+#if defined(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) && defined(CONFIG_EFI_PARTITION)
+
+#define DFU_ALT_BUF_LEN SZ_1K
+
+static bool board_is_rockpi_4b(void)
+{
+   return CONFIG_IS_ENABLED(TARGET_EVB_RK3399) &&
+   of_machine_is_compatible("radxa,rockpi4b");
+}
+
+static bool board_is_rockpi_4c(void)
+{
+   return CONFIG_IS_ENABLED(TARGET_EVB_RK3399) &&
+   of_machine_is_compatible("radxa,rockpi4c");
+}
+
+static bool updatable_image(struct disk_partition *info)
+{
+   int i;
+   bool ret = false;
+   efi_guid_t image_type_guid;
+
+   uuid_str_to_bin(info->type_guid, image_type_guid.b,
+   UUID_STR_FORMAT_GUID);
+
+   for (i = 0; i < ROCKPI4_UPDATABLE_IMAGES; i++) {
+   if (!guidcmp(_images[i].image_type_id, _type_guid)) {
+   ret = true;
+   break;
+   }
+   }
+
+   return ret;
+}
+
+static void set_image_index(struct disk_partition *info, int index)
+{
+   int i;
+   efi_guid_t image_type_guid;
+
+   uuid_str_to_bin(info->type_guid, image_type_guid.b,
+   UUID_STR_FORMAT_GUID);
+
+   for (i = 0; i < ROCKPI4_UPDATABLE_IMAGES; i++) {
+   if (!guidcmp(_images[i].image_type_id, _type_guid)) {
+   fw_images[i].image_index = index;
+   break;
+   }
+   }
+}
+
+static int get_mmc_desc(struct blk_desc **desc)
+{
+   int ret;
+   struct mmc *mmc;
+   struct udevice *dev;
+
+   /*
+* For now the firmware images are assumed to
+* be on the SD card
+*/
+   ret = uclass_get_device(UCLASS_MMC, 1, );
+   if (ret)
+   return -1;
+
+   mmc = mmc_get_mmc_dev(dev);
+   if (!mmc)
+   return -1;
+
+   if (mmc_init(mmc))
+   return -1;
+
+   *desc = mmc_get_blk_desc(mmc);
+   if (!*desc)
+   return -1;
+
+   return 0;
+}
+
+void set_dfu_alt_info(char *interface, char *devstr)
+{
+   const char *name;
+   bool first = true;
+   int p, len, devnum, ret;
+   char buf[DFU_ALT_BUF_LEN];
+   struct disk_partition info;
+   struct blk_desc *desc = NULL;
+
+   ret = get_mmc_desc();
+   if (ret)
+   return;
+
+   memset(buf, 0, sizeof(buf));
+   name = blk_get_if_type_name(desc->if_type);
+   devnum = desc->devnum;
+   len = strlen(buf);
+
+   len += snprintf(buf + len, DFU_ALT_BUF_LEN - len,
+"%s %d=", name, devnum);
+
+   for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) {
+   if (part_get_info(desc, 

[PATCH 12/14] power: regulator: scmi: support SCMI multi-channel

2022-05-13 Thread Etienne Carriere
Update SCMI regulator controller driver to get its assigned SCMI channel
during initialization. This change allows SCMI voltage domain protocol
to use a dedicated channel when defined in the DT. The reference is
saved in SCMI regulator controller driver private data.

Cc: Jaehoon Chung 
Signed-off-by: Etienne Carriere 
---
 drivers/power/regulator/scmi_regulator.c | 20 +++-
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/power/regulator/scmi_regulator.c 
b/drivers/power/regulator/scmi_regulator.c
index 3325ddaf23b..e0343e913f4 100644
--- a/drivers/power/regulator/scmi_regulator.c
+++ b/drivers/power/regulator/scmi_regulator.c
@@ -27,6 +27,7 @@ struct scmi_regulator_platdata {
 
 static int scmi_voltd_set_enable(struct udevice *dev, bool enable)
 {
+   struct scmi_channel **scmi_channel_ref = dev_get_priv(dev);
struct scmi_regulator_platdata *pdata = dev_get_plat(dev);
struct scmi_voltd_config_set_in in = {
.domain_id = pdata->domain_id,
@@ -38,7 +39,7 @@ static int scmi_voltd_set_enable(struct udevice *dev, bool 
enable)
  in, out);
int ret;
 
-   ret = devm_scmi_process_msg(dev, NULL, );
+   ret = devm_scmi_process_msg(dev, *scmi_channel_ref, );
if (ret)
return ret;
 
@@ -51,6 +52,7 @@ static int scmi_voltd_set_enable(struct udevice *dev, bool 
enable)
 
 static int scmi_voltd_get_enable(struct udevice *dev)
 {
+   struct scmi_channel **scmi_channel_ref = dev_get_priv(dev);
struct scmi_regulator_platdata *pdata = dev_get_plat(dev);
struct scmi_voltd_config_get_in in = {
.domain_id = pdata->domain_id,
@@ -61,7 +63,7 @@ static int scmi_voltd_get_enable(struct udevice *dev)
  in, out);
int ret;
 
-   ret = devm_scmi_process_msg(dev, NULL, );
+   ret = devm_scmi_process_msg(dev, *scmi_channel_ref, );
if (ret < 0)
return ret;
 
@@ -74,6 +76,7 @@ static int scmi_voltd_get_enable(struct udevice *dev)
 
 static int scmi_voltd_set_voltage_level(struct udevice *dev, int uV)
 {
+   struct scmi_channel **scmi_channel_ref = dev_get_priv(dev);
struct scmi_regulator_platdata *pdata = dev_get_plat(dev);
struct scmi_voltd_level_set_in in = {
.domain_id = pdata->domain_id,
@@ -85,7 +88,7 @@ static int scmi_voltd_set_voltage_level(struct udevice *dev, 
int uV)
  in, out);
int ret;
 
-   ret = devm_scmi_process_msg(dev, NULL, );
+   ret = devm_scmi_process_msg(dev, *scmi_channel_ref, );
if (ret < 0)
return ret;
 
@@ -94,6 +97,7 @@ static int scmi_voltd_set_voltage_level(struct udevice *dev, 
int uV)
 
 static int scmi_voltd_get_voltage_level(struct udevice *dev)
 {
+   struct scmi_channel **scmi_channel_ref = dev_get_priv(dev);
struct scmi_regulator_platdata *pdata = dev_get_plat(dev);
struct scmi_voltd_level_get_in in = {
.domain_id = pdata->domain_id,
@@ -104,7 +108,7 @@ static int scmi_voltd_get_voltage_level(struct udevice *dev)
  in, out);
int ret;
 
-   ret = devm_scmi_process_msg(dev, NULL, );
+   ret = devm_scmi_process_msg(dev, *scmi_channel_ref, );
if (ret < 0)
return ret;
 
@@ -131,6 +135,7 @@ static int scmi_regulator_of_to_plat(struct udevice *dev)
 
 static int scmi_regulator_probe(struct udevice *dev)
 {
+   struct scmi_channel **scmi_channel_ref = dev_get_priv(dev);
struct scmi_regulator_platdata *pdata = dev_get_plat(dev);
struct scmi_voltd_attr_in in = { 0 };
struct scmi_voltd_attr_out out = { 0 };
@@ -144,10 +149,14 @@ static int scmi_regulator_probe(struct udevice *dev)
};
int ret;
 
+   ret = devm_scmi_of_get_channel(dev->parent, scmi_channel_ref);
+   if (ret)
+   return ret;
+
/* Check voltage domain is known from SCMI server */
in.domain_id = pdata->domain_id;
 
-   ret = devm_scmi_process_msg(dev, NULL, _msg);
+   ret = devm_scmi_process_msg(dev, *scmi_channel_ref, _msg);
if (ret) {
dev_err(dev, "Failed to query voltage domain %u: %d\n",
pdata->domain_id, ret);
@@ -171,6 +180,7 @@ U_BOOT_DRIVER(scmi_regulator) = {
.probe = scmi_regulator_probe,
.of_to_plat = scmi_regulator_of_to_plat,
.plat_auto = sizeof(struct scmi_regulator_platdata),
+   .priv_auto = sizeof(struct scmi_channel *),
 };
 
 static int scmi_regulator_bind(struct udevice *dev)
-- 
2.25.1



[PATCH 14/14] firmware: scmi: use multi channel in mailbox, optee and smccc agents

2022-05-13 Thread Etienne Carriere
Updates .process_msg operators of the SCMI transport drivers that
supports multi-channel to use it now that drivers do provide
the reference through channel argument. These are the mailbox
agent, the optee agent and the smccc agent.

Signed-off-by: Etienne Carriere 
---
 drivers/firmware/scmi/mailbox_agent.c | 6 +-
 drivers/firmware/scmi/optee_agent.c   | 5 +
 drivers/firmware/scmi/smccc_agent.c   | 6 +-
 3 files changed, 3 insertions(+), 14 deletions(-)

diff --git a/drivers/firmware/scmi/mailbox_agent.c 
b/drivers/firmware/scmi/mailbox_agent.c
index e63b67c5ee8..3efdab9e723 100644
--- a/drivers/firmware/scmi/mailbox_agent.c
+++ b/drivers/firmware/scmi/mailbox_agent.c
@@ -43,13 +43,9 @@ static int scmi_mbox_process_msg(struct udevice *dev,
 struct scmi_channel *channel,
 struct scmi_msg *msg)
 {
-   struct scmi_mbox_channel *chan = dev_get_plat(dev);
+   struct scmi_mbox_channel *chan = >ref;
int ret;
 
-   /* Support SCMI drivers upgraded to of_get_channel operator */
-   if (channel)
-   chan = >ref;
-
ret = scmi_write_msg_to_smt(dev, >smt, msg);
if (ret)
return ret;
diff --git a/drivers/firmware/scmi/optee_agent.c 
b/drivers/firmware/scmi/optee_agent.c
index da5c2ec9754..2b2b8c1670a 100644
--- a/drivers/firmware/scmi/optee_agent.c
+++ b/drivers/firmware/scmi/optee_agent.c
@@ -278,13 +278,10 @@ static int scmi_optee_process_msg(struct udevice *dev,
  struct scmi_channel *channel,
  struct scmi_msg *msg)
 {
+   struct scmi_optee_channel *chan = >ref;
struct channel_session sess = { };
int ret;
 
-   /* Support SCMI drivers upgraded to of_get_channel operator */
-   if (channel)
-   chan = >ref;
-
ret = open_channel(dev, chan, );
if (ret)
return ret;
diff --git a/drivers/firmware/scmi/smccc_agent.c 
b/drivers/firmware/scmi/smccc_agent.c
index 73a7e0a844a..bc2eb67335b 100644
--- a/drivers/firmware/scmi/smccc_agent.c
+++ b/drivers/firmware/scmi/smccc_agent.c
@@ -42,14 +42,10 @@ static int scmi_smccc_process_msg(struct udevice *dev,
  struct scmi_channel *channel,
  struct scmi_msg *msg)
 {
-   struct scmi_smccc_channel *chan = dev_get_plat(dev);
+   struct scmi_smccc_channel *chan = >ref;
struct arm_smccc_res res;
int ret;
 
-   /* Support SCMI drivers upgraded to of_get_channel operator */
-   if (channel)
-   chan = >ref;
-
ret = scmi_write_msg_to_smt(dev, >smt, msg);
if (ret)
return ret;
-- 
2.25.1



[PATCH 13/14] power: regulator: scmi: simplify scmi_voltd_set_enable()

2022-05-13 Thread Etienne Carriere
Simplify scmi_voltd_set_enable() exit sequence.

Cc: Jaehoon Chung 
Signed-off-by: Etienne Carriere 
---
 drivers/power/regulator/scmi_regulator.c | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/power/regulator/scmi_regulator.c 
b/drivers/power/regulator/scmi_regulator.c
index e0343e913f4..6affa457991 100644
--- a/drivers/power/regulator/scmi_regulator.c
+++ b/drivers/power/regulator/scmi_regulator.c
@@ -43,11 +43,7 @@ static int scmi_voltd_set_enable(struct udevice *dev, bool 
enable)
if (ret)
return ret;
 
-   ret = scmi_to_linux_errno(out.status);
-   if (ret)
-   return ret;
-
-   return ret;
+   return scmi_to_linux_errno(out.status);
 }
 
 static int scmi_voltd_get_enable(struct udevice *dev)
-- 
2.25.1



[PATCH 11/14] reset: scmi: support SCMI multi-channel

2022-05-13 Thread Etienne Carriere
Update SCMI reset controller driver to get its assigned SCMI channel
during initialization. This change allows SCMI reset domain protocol
to use a dedicated channel when defined in the DT. The reference is
saved in SCMI reset controller driver private data.

Signed-off-by: Etienne Carriere 
---
 drivers/reset/reset-scmi.c | 15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/reset/reset-scmi.c b/drivers/reset/reset-scmi.c
index 30b26ec9d31..6101bd2a1e8 100644
--- a/drivers/reset/reset-scmi.c
+++ b/drivers/reset/reset-scmi.c
@@ -15,6 +15,7 @@
 
 static int scmi_reset_set_level(struct reset_ctl *rst, bool 
assert_not_deassert)
 {
+   struct scmi_channel **scmi_channel_ref = dev_get_priv(rst->dev);
struct scmi_rd_reset_in in = {
.domain_id = rst->id,
.flags = assert_not_deassert ? SCMI_RD_RESET_FLAG_ASSERT : 0,
@@ -26,7 +27,7 @@ static int scmi_reset_set_level(struct reset_ctl *rst, bool 
assert_not_deassert)
  in, out);
int ret;
 
-   ret = devm_scmi_process_msg(rst->dev, NULL, );
+   ret = devm_scmi_process_msg(rst->dev, *scmi_channel_ref, );
if (ret)
return ret;
 
@@ -45,6 +46,7 @@ static int scmi_reset_deassert(struct reset_ctl *rst)
 
 static int scmi_reset_request(struct reset_ctl *rst)
 {
+   struct scmi_channel **scmi_channel_ref = dev_get_priv(rst->dev);
struct scmi_rd_attr_in in = {
.domain_id = rst->id,
};
@@ -58,7 +60,7 @@ static int scmi_reset_request(struct reset_ctl *rst)
 * We don't really care about the attribute, just check
 * the reset domain exists.
 */
-   ret = devm_scmi_process_msg(rst->dev, NULL, );
+   ret = devm_scmi_process_msg(rst->dev, *scmi_channel_ref, );
if (ret)
return ret;
 
@@ -71,8 +73,17 @@ static const struct reset_ops scmi_reset_domain_ops = {
.rst_deassert   = scmi_reset_deassert,
 };
 
+static int scmi_reset_probe(struct udevice *dev)
+{
+   struct scmi_channel **scmi_channel_ref = dev_get_priv(dev);
+
+   return devm_scmi_of_get_channel(dev, scmi_channel_ref);
+}
+
 U_BOOT_DRIVER(scmi_reset_domain) = {
.name = "scmi_reset_domain",
.id = UCLASS_RESET,
.ops = _reset_domain_ops,
+   .probe = scmi_reset_probe,
+   .priv_auto = sizeof(struct scmi_channel *),
 };
-- 
2.25.1



[PATCH 10/14] clk: scmi: support SCMI multi-channel

2022-05-13 Thread Etienne Carriere
Update SCMI clock driver to get its assigned SCMI channel during
initialization. This change allows SCMI clock protocol to use a
dedicated channel when defined in the DT. The reference is saved
in SCMI clock driver private data.

Cc: Lukasz Majewski 
Cc: Sean Anderson 
Signed-off-by: Etienne Carriere 
---
 drivers/clk/clk_scmi.c | 23 +--
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/clk_scmi.c b/drivers/clk/clk_scmi.c
index 0d0bb72eaf7..5cf7bd73df5 100644
--- a/drivers/clk/clk_scmi.c
+++ b/drivers/clk/clk_scmi.c
@@ -15,6 +15,7 @@
 
 static int scmi_clk_get_num_clock(struct udevice *dev, size_t *num_clocks)
 {
+   struct scmi_channel **scmi_channel_ref = dev_get_priv(dev);
struct scmi_clk_protocol_attr_out out;
struct scmi_msg msg = {
.protocol_id = SCMI_PROTOCOL_ID_CLOCK,
@@ -24,7 +25,7 @@ static int scmi_clk_get_num_clock(struct udevice *dev, size_t 
*num_clocks)
};
int ret;
 
-   ret = devm_scmi_process_msg(dev, NULL, );
+   ret = devm_scmi_process_msg(dev, *scmi_channel_ref, );
if (ret)
return ret;
 
@@ -35,6 +36,7 @@ static int scmi_clk_get_num_clock(struct udevice *dev, size_t 
*num_clocks)
 
 static int scmi_clk_get_attibute(struct udevice *dev, int clkid, char **name)
 {
+   struct scmi_channel **scmi_channel_ref = dev_get_priv(dev);
struct scmi_clk_attribute_in in = {
.clock_id = clkid,
};
@@ -49,7 +51,7 @@ static int scmi_clk_get_attibute(struct udevice *dev, int 
clkid, char **name)
};
int ret;
 
-   ret = devm_scmi_process_msg(dev, NULL, );
+   ret = devm_scmi_process_msg(dev, *scmi_channel_ref, );
if (ret)
return ret;
 
@@ -60,6 +62,7 @@ static int scmi_clk_get_attibute(struct udevice *dev, int 
clkid, char **name)
 
 static int scmi_clk_gate(struct clk *clk, int enable)
 {
+   struct scmi_channel **scmi_channel_ref = dev_get_priv(clk->dev);
struct scmi_clk_state_in in = {
.clock_id = clk->id,
.attributes = enable,
@@ -70,7 +73,7 @@ static int scmi_clk_gate(struct clk *clk, int enable)
  in, out);
int ret;
 
-   ret = devm_scmi_process_msg(clk->dev, NULL, );
+   ret = devm_scmi_process_msg(clk->dev, *scmi_channel_ref, );
if (ret)
return ret;
 
@@ -89,6 +92,7 @@ static int scmi_clk_disable(struct clk *clk)
 
 static ulong scmi_clk_get_rate(struct clk *clk)
 {
+   struct scmi_channel **scmi_channel_ref = dev_get_priv(clk->dev);
struct scmi_clk_rate_get_in in = {
.clock_id = clk->id,
};
@@ -98,7 +102,7 @@ static ulong scmi_clk_get_rate(struct clk *clk)
  in, out);
int ret;
 
-   ret = devm_scmi_process_msg(clk->dev, NULL, );
+   ret = devm_scmi_process_msg(clk->dev, *scmi_channel_ref, );
if (ret < 0)
return ret;
 
@@ -111,6 +115,7 @@ static ulong scmi_clk_get_rate(struct clk *clk)
 
 static ulong scmi_clk_set_rate(struct clk *clk, ulong rate)
 {
+   struct scmi_channel **scmi_channel_ref = dev_get_priv(clk->dev);
struct scmi_clk_rate_set_in in = {
.clock_id = clk->id,
.flags = SCMI_CLK_RATE_ROUND_CLOSEST,
@@ -123,7 +128,7 @@ static ulong scmi_clk_set_rate(struct clk *clk, ulong rate)
  in, out);
int ret;
 
-   ret = devm_scmi_process_msg(clk->dev, NULL, );
+   ret = devm_scmi_process_msg(clk->dev, *scmi_channel_ref, );
if (ret < 0)
return ret;
 
@@ -136,10 +141,15 @@ static ulong scmi_clk_set_rate(struct clk *clk, ulong 
rate)
 
 static int scmi_clk_probe(struct udevice *dev)
 {
+   struct scmi_channel **scmi_channel_ref = dev_get_priv(dev);
struct clk *clk;
size_t num_clocks, i;
int ret;
 
+   ret = devm_scmi_of_get_channel(dev, scmi_channel_ref);
+   if (ret)
+   return ret;
+
if (!CONFIG_IS_ENABLED(CLK_CCF))
return 0;
 
@@ -186,5 +196,6 @@ U_BOOT_DRIVER(scmi_clock) = {
.name = "scmi_clk",
.id = UCLASS_CLK,
.ops = _clk_ops,
-   .probe = _clk_probe,
+   .probe = scmi_clk_probe,
+   .priv_auto = sizeof(struct scmi_channel *),
 };
-- 
2.25.1



[PATCH 08/14] firmware: scmi: smccc transport: implement multi-channel

2022-05-13 Thread Etienne Carriere
Updates SCMI SMCCC transport driver to get SCMI channel reference
at initialization and use when posting SCMI messages.

Signed-off-by: Etienne Carriere 
---
 drivers/firmware/scmi/smccc_agent.c | 54 +++--
 1 file changed, 52 insertions(+), 2 deletions(-)

diff --git a/drivers/firmware/scmi/smccc_agent.c 
b/drivers/firmware/scmi/smccc_agent.c
index b7a930b24df..73a7e0a844a 100644
--- a/drivers/firmware/scmi/smccc_agent.c
+++ b/drivers/firmware/scmi/smccc_agent.c
@@ -30,6 +30,14 @@ struct scmi_smccc_channel {
struct scmi_smt smt;
 };
 
+/**
+ * struct scmi_channel - Channel instance referenced in SCMI drivers
+ * @ref: Reference to local channel instance
+ **/
+struct scmi_channel {
+   struct scmi_smccc_channel ref;
+};
+
 static int scmi_smccc_process_msg(struct udevice *dev,
  struct scmi_channel *channel,
  struct scmi_msg *msg)
@@ -38,6 +46,10 @@ static int scmi_smccc_process_msg(struct udevice *dev,
struct arm_smccc_res res;
int ret;
 
+   /* Support SCMI drivers upgraded to of_get_channel operator */
+   if (channel)
+   chan = >ref;
+
ret = scmi_write_msg_to_smt(dev, >smt, msg);
if (ret)
return ret;
@@ -53,9 +65,8 @@ static int scmi_smccc_process_msg(struct udevice *dev,
return ret;
 }
 
-static int scmi_smccc_of_to_plat(struct udevice *dev)
+static int setup_channel(struct udevice *dev, struct scmi_smccc_channel *chan)
 {
-   struct scmi_smccc_channel *chan = dev_get_plat(dev);
u32 func_id;
int ret;
 
@@ -73,12 +84,51 @@ static int scmi_smccc_of_to_plat(struct udevice *dev)
return ret;
 }
 
+static int scmi_smccc_get_channel(struct udevice *dev,
+ struct scmi_channel **channel)
+{
+   struct scmi_smccc_channel *base_chan = dev_get_plat(dev->parent);
+   struct scmi_smccc_channel *chan;
+   u32 func_id;
+   int ret;
+
+   if (dev_read_u32(dev, "arm,smc-id", _id)) {
+   /* Uses agent base channel */
+   *channel = container_of(base_chan, struct scmi_channel, ref);
+
+   return 0;
+   }
+
+   /* Setup a dedicated channel */
+   chan = calloc(1, sizeof(*chan));
+   if (!chan)
+   return -ENOMEM;
+
+   ret = setup_channel(dev, chan);
+   if (ret) {
+   free(chan);
+   return ret;
+   }
+
+   *channel = container_of(chan, struct scmi_channel, ref);
+
+   return 0;
+}
+
+static int scmi_smccc_of_to_plat(struct udevice *dev)
+{
+   struct scmi_smccc_channel *chan = dev_get_plat(dev);
+
+   return setup_channel(dev, chan);
+}
+
 static const struct udevice_id scmi_smccc_ids[] = {
{ .compatible = "arm,scmi-smc" },
{ }
 };
 
 static const struct scmi_agent_ops scmi_smccc_ops = {
+   .of_get_channel = scmi_smccc_get_channel,
.process_msg = scmi_smccc_process_msg,
 };
 
-- 
2.25.1



[PATCH 09/14] firmware: scmi: optee transport: implement multi-channel

2022-05-13 Thread Etienne Carriere
Implements multi SCMI channel support in OP-TEE SCMI transport. An
SCMI protocol may use a dedicated channel, specified by the DT.

Signed-off-by: Etienne Carriere 
---
 drivers/firmware/scmi/optee_agent.c | 76 -
 1 file changed, 63 insertions(+), 13 deletions(-)

diff --git a/drivers/firmware/scmi/optee_agent.c 
b/drivers/firmware/scmi/optee_agent.c
index 771fa25e989..da5c2ec9754 100644
--- a/drivers/firmware/scmi/optee_agent.c
+++ b/drivers/firmware/scmi/optee_agent.c
@@ -35,6 +35,14 @@ struct scmi_optee_channel {
bool dyn_shm;
 };
 
+/**
+ * struct scmi_channel - Channel instance referenced in SCMI drivers
+ * @ref: Reference to local channel instance
+ **/
+struct scmi_channel {
+   struct scmi_optee_channel ref;
+};
+
 /**
  * struct channel_session - Aggreates SCMI service session context references
  * @tee:   OP-TEE device to invoke
@@ -132,10 +140,10 @@ enum optee_smci_pta_cmd {
 #define PTA_SCMI_CAPS_MASK (PTA_SCMI_CAPS_SMT_HEADER | \
 PTA_SCMI_CAPS_MSG_HEADER)
 
-static int open_channel(struct udevice *dev, struct channel_session *sess)
+static int open_channel(struct udevice *dev, struct scmi_optee_channel *chan,
+   struct channel_session *sess)
 {
const struct tee_optee_ta_uuid uuid = TA_SCMI_UUID;
-   struct scmi_optee_channel *chan = dev_get_plat(dev);
struct tee_open_session_arg sess_arg = { };
struct tee_invoke_arg cmd_arg = { };
struct tee_param param[1] = { };
@@ -187,10 +195,9 @@ static void close_channel(struct channel_session *sess)
tee_close_session(sess->tee, sess->tee_session);
 }
 
-static int invoke_cmd(struct udevice *dev, struct channel_session *sess,
- struct scmi_msg *msg)
+static int invoke_cmd(struct udevice *dev, struct scmi_optee_channel *chan,
+ struct channel_session *sess, struct scmi_msg *msg)
 {
-   struct scmi_optee_channel *chan = dev_get_plat(dev);
struct tee_invoke_arg arg = { };
struct tee_param param[3] = { };
int ret;
@@ -237,9 +244,9 @@ static int invoke_cmd(struct udevice *dev, struct 
channel_session *sess,
return ret;
 }
 
-static int prepare_shm(struct udevice *dev, struct channel_session *sess)
+static int prepare_shm(struct udevice *dev, struct scmi_optee_channel *chan,
+  struct channel_session *sess)
 {
-   struct scmi_optee_channel *chan = dev_get_plat(dev);
int ret;
 
/* Static shm is already prepared by the firmware: nothing to do */
@@ -274,15 +281,19 @@ static int scmi_optee_process_msg(struct udevice *dev,
struct channel_session sess = { };
int ret;
 
-   ret = open_channel(dev, );
+   /* Support SCMI drivers upgraded to of_get_channel operator */
+   if (channel)
+   chan = >ref;
+
+   ret = open_channel(dev, chan, );
if (ret)
return ret;
 
-   ret = prepare_shm(dev, );
+   ret = prepare_shm(dev, chan, );
if (ret)
goto out;
 
-   ret = invoke_cmd(dev, , msg);
+   ret = invoke_cmd(dev, chan, , msg);
 
release_shm(dev, );
 
@@ -292,9 +303,8 @@ out:
return ret;
 }
 
-static int scmi_optee_of_to_plat(struct udevice *dev)
+static int setup_channel(struct udevice *dev, struct scmi_optee_channel *chan)
 {
-   struct scmi_optee_channel *chan = dev_get_plat(dev);
int ret;
 
if (dev_read_u32(dev, "linaro,optee-channel-id", >channel_id)) {
@@ -316,13 +326,52 @@ static int scmi_optee_of_to_plat(struct udevice *dev)
return 0;
 }
 
+static int scmi_optee_get_channel(struct udevice *dev,
+ struct scmi_channel **channel)
+{
+   struct scmi_optee_channel *base_chan = dev_get_plat(dev->parent);
+   struct scmi_optee_channel *chan;
+   u32 channel_id;
+   int ret;
+
+   if (dev_read_u32(dev, "linaro,optee-channel-id", _id)) {
+   /* Uses agent base channel */
+   *channel = container_of(base_chan, struct scmi_channel, ref);
+
+   return 0;
+   }
+
+   /* Setup a dedicated channel */
+   chan = calloc(1, sizeof(*chan));
+   if (!chan)
+   return -ENOMEM;
+
+   ret = setup_channel(dev, chan);
+   if (ret) {
+   free(chan);
+   return ret;
+   }
+
+   *channel = container_of(chan, struct scmi_channel, ref);
+
+   return 0;
+}
+
+static int scmi_optee_of_to_plat(struct udevice *dev)
+{
+   struct scmi_optee_channel *chan = dev_get_plat(dev);
+
+   return setup_channel(dev, chan);
+}
+
 static int scmi_optee_probe(struct udevice *dev)
 {
+   struct scmi_optee_channel *chan = dev_get_plat(dev);
struct channel_session sess;
int ret;
 
/* Check OP-TEE service acknowledges the SCMI channel */
-   ret = open_channel(dev, );
+   ret = 

[PATCH 06/14] firmware: scmi: add multi-channel support

2022-05-13 Thread Etienne Carriere
Adds resources for SCMI protocols to possibly use a dedicated SCMI
channel instead of the default channel allocated by the SCMI agent
during initialization. As per DT binding documentation, some SCMI
transports can define a specific SCMI communication channel for
given SCMI protocols. It allows SCMI protocols to pass messages
concurrently each other.

This change introduces new scmi agent uclass API function
devm_scmi_of_get_channel() for SCMI drivers probe sequences to get
a reference to the SCMI channel assigned to its related SCMI protocol.
The function queries the channel reference to its SCMI transport driver
through new scmi agent uclass operator .of_get_channel that uses Device
Tree information from related SCMI agent node.

Operator .of_get_channel returns a reference to the SCMI channel
assigned to SCMI protocol used by the caller device. SCMI transport
drivers that do not support multi-channel are not mandated to register
this operator. When so, API function devm_scmi_of_get_channel() returns
NULL and SCMI transport driver are expected to retrieve by their own
means the reference to the unique SCMI channel, for example using
platform data as these drivers currently do in U-Boot source tree.

Signed-off-by: Etienne Carriere 
---
 drivers/firmware/scmi/scmi_agent-uclass.c | 19 ++-
 include/scmi_agent-uclass.h   |  9 +
 include/scmi_agent.h  |  9 +
 3 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c 
b/drivers/firmware/scmi/scmi_agent-uclass.c
index f7fa5df214c..2b6211c4e6a 100644
--- a/drivers/firmware/scmi/scmi_agent-uclass.c
+++ b/drivers/firmware/scmi/scmi_agent-uclass.c
@@ -128,6 +128,23 @@ static const struct scmi_agent_ops 
*transport_dev_ops(struct udevice *dev)
return (const struct scmi_agent_ops *)dev->driver->ops;
 }
 
+int devm_scmi_of_get_channel(struct udevice *dev, struct scmi_channel 
**channel)
+{
+   struct udevice *parent;
+
+   parent = find_scmi_transport_device(dev);
+   if (!parent)
+   return -ENODEV;
+
+   if (transport_dev_ops(parent)->of_get_channel)
+   return transport_dev_ops(parent)->of_get_channel(dev, channel);
+
+   /* Drivers without a get_channel operator don't need a channel ref */
+   *channel = NULL;
+
+   return 0;
+}
+
 int devm_scmi_process_msg(struct udevice *dev, struct scmi_channel *channel,
  struct scmi_msg *msg)
 {
@@ -141,7 +158,7 @@ int devm_scmi_process_msg(struct udevice *dev, struct 
scmi_channel *channel,
ops = transport_dev_ops(parent);
 
if (ops->process_msg)
-   return ops->process_msg(parent, NULL, msg);
+   return ops->process_msg(parent, channel, msg);
 
return -EPROTONOSUPPORT;
 }
diff --git a/include/scmi_agent-uclass.h b/include/scmi_agent-uclass.h
index 562a4cc99af..b1c93532c0e 100644
--- a/include/scmi_agent-uclass.h
+++ b/include/scmi_agent-uclass.h
@@ -13,6 +13,15 @@ struct scmi_channel;
  * struct scmi_transport_ops - The functions that a SCMI transport layer must 
implement.
  */
 struct scmi_agent_ops {
+   /*
+* of_get_channel - Get SCMI channel from SCMI agent device tree node
+*
+* @dev:SCMI protocol device using the transport
+* @channel:Output reference to SCMI channel upon success
+* Return 0 upon success and a negative errno on failure
+*/
+   int (*of_get_channel)(struct udevice *dev, struct scmi_channel 
**channel);
+
/*
 * process_msg - Request transport to get the SCMI message processed
 *
diff --git a/include/scmi_agent.h b/include/scmi_agent.h
index f4d85cae773..ee6286366df 100644
--- a/include/scmi_agent.h
+++ b/include/scmi_agent.h
@@ -45,6 +45,15 @@ struct scmi_msg {
.out_msg_sz = sizeof(_out_array),   \
}
 
+/**
+ * devm_scmi_of_get_channel() - Get SCMI channel handle from SCMI agent DT node
+ *
+ * @dev:   Device requesting a channel
+ * @channel:   Output reference to the SCMI channel upon success
+ * @return 0 on success and a negative errno on failure
+ */
+int devm_scmi_of_get_channel(struct udevice *dev, struct scmi_channel 
**channel);
+
 /**
  * devm_scmi_process_msg() - Send and process an SCMI message
  *
-- 
2.25.1



[PATCH 07/14] firmware: scmi: mailbox transport: implement multi-channel

2022-05-13 Thread Etienne Carriere
Updates SCMI mailbox transport driver to get SCMI channel reference
at initialization and use when posting SCMI messages.

Signed-off-by: Etienne Carriere 
---
 drivers/firmware/scmi/mailbox_agent.c | 63 ---
 1 file changed, 57 insertions(+), 6 deletions(-)

diff --git a/drivers/firmware/scmi/mailbox_agent.c 
b/drivers/firmware/scmi/mailbox_agent.c
index aa4929aafae..e63b67c5ee8 100644
--- a/drivers/firmware/scmi/mailbox_agent.c
+++ b/drivers/firmware/scmi/mailbox_agent.c
@@ -31,6 +31,14 @@ struct scmi_mbox_channel {
ulong timeout_us;
 };
 
+/**
+ * struct scmi_channel - Channel instance referenced in SCMI drivers
+ * @ref: Reference to local channel instance
+ **/
+struct scmi_channel {
+   struct scmi_mbox_channel ref;
+};
+
 static int scmi_mbox_process_msg(struct udevice *dev,
 struct scmi_channel *channel,
 struct scmi_msg *msg)
@@ -38,6 +46,10 @@ static int scmi_mbox_process_msg(struct udevice *dev,
struct scmi_mbox_channel *chan = dev_get_plat(dev);
int ret;
 
+   /* Support SCMI drivers upgraded to of_get_channel operator */
+   if (channel)
+   chan = >ref;
+
ret = scmi_write_msg_to_smt(dev, >smt, msg);
if (ret)
return ret;
@@ -64,13 +76,10 @@ out:
return ret;
 }
 
-int scmi_mbox_of_to_plat(struct udevice *dev)
+static int setup_channel(struct udevice *dev, struct scmi_mbox_channel *chan)
 {
-   struct scmi_mbox_channel *chan = dev_get_plat(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);
@@ -78,10 +87,51 @@ int scmi_mbox_of_to_plat(struct udevice *dev)
}
 
ret = scmi_dt_get_smt_buffer(dev, >smt);
-   if (ret)
+   if (ret) {
dev_err(dev, "Failed to get shm resources: %d\n", ret);
+   return ret;
+   }
 
-   return ret;
+   chan->timeout_us = TIMEOUT_US_10MS;
+
+   return 0;
+}
+
+static int scmi_mbox_get_channel(struct udevice *dev,
+struct scmi_channel **channel)
+{
+   struct scmi_mbox_channel *base_chan = dev_get_plat(dev->parent);
+   struct scmi_mbox_channel *chan;
+   int ret;
+
+   if (!dev_read_prop(dev, "shmem", NULL)) {
+   /* Uses agent base channel */
+   *channel = container_of(base_chan, struct scmi_channel, ref);
+
+   return 0;
+   }
+
+   chan = calloc(1, sizeof(*chan));
+   if (!chan)
+   return -ENOMEM;
+
+   /* Setup a dedicated channel for the protocol */
+   ret = setup_channel(dev, chan);
+   if (ret) {
+   free(chan);
+   return ret;
+   }
+
+   *channel = (void *)chan;
+
+   return 0;
+}
+
+int scmi_mbox_of_to_plat(struct udevice *dev)
+{
+   struct scmi_mbox_channel *chan = dev_get_plat(dev);
+
+   return setup_channel(dev, chan);
 }
 
 static const struct udevice_id scmi_mbox_ids[] = {
@@ -90,6 +140,7 @@ static const struct udevice_id scmi_mbox_ids[] = {
 };
 
 static const struct scmi_agent_ops scmi_mbox_ops = {
+   .of_get_channel = scmi_mbox_get_channel,
.process_msg = scmi_mbox_process_msg,
 };
 
-- 
2.25.1



[PATCH 04/14] firmware: scmi: prepare uclass to pass channel reference

2022-05-13 Thread Etienne Carriere
Changes SCMI transport operator ::process_msg to pass the SCMI channel
reference provided by caller SCMI protocol device.

Signed-off-by: Etienne Carriere 
---
 drivers/firmware/scmi/mailbox_agent.c  | 4 +++-
 drivers/firmware/scmi/optee_agent.c| 4 +++-
 drivers/firmware/scmi/sandbox-scmi_agent.c | 1 +
 drivers/firmware/scmi/scmi_agent-uclass.c  | 2 +-
 drivers/firmware/scmi/smccc_agent.c| 4 +++-
 include/scmi_agent-uclass.h| 4 +++-
 6 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/firmware/scmi/mailbox_agent.c 
b/drivers/firmware/scmi/mailbox_agent.c
index 8e4af0c8faf..aa4929aafae 100644
--- a/drivers/firmware/scmi/mailbox_agent.c
+++ b/drivers/firmware/scmi/mailbox_agent.c
@@ -31,7 +31,9 @@ struct scmi_mbox_channel {
ulong timeout_us;
 };
 
-static int scmi_mbox_process_msg(struct udevice *dev, struct scmi_msg *msg)
+static int scmi_mbox_process_msg(struct udevice *dev,
+struct scmi_channel *channel,
+struct scmi_msg *msg)
 {
struct scmi_mbox_channel *chan = dev_get_plat(dev);
int ret;
diff --git a/drivers/firmware/scmi/optee_agent.c 
b/drivers/firmware/scmi/optee_agent.c
index bf0647bafd1..771fa25e989 100644
--- a/drivers/firmware/scmi/optee_agent.c
+++ b/drivers/firmware/scmi/optee_agent.c
@@ -267,7 +267,9 @@ static void release_shm(struct udevice *dev, struct 
channel_session *sess)
tee_shm_free(sess->tee_shm);
 }
 
-static int scmi_optee_process_msg(struct udevice *dev, struct scmi_msg *msg)
+static int scmi_optee_process_msg(struct udevice *dev,
+ struct scmi_channel *channel,
+ struct scmi_msg *msg)
 {
struct channel_session sess = { };
int ret;
diff --git a/drivers/firmware/scmi/sandbox-scmi_agent.c 
b/drivers/firmware/scmi/sandbox-scmi_agent.c
index c555164d196..031882998df 100644
--- a/drivers/firmware/scmi/sandbox-scmi_agent.c
+++ b/drivers/firmware/scmi/sandbox-scmi_agent.c
@@ -471,6 +471,7 @@ static int sandbox_scmi_voltd_level_get(struct udevice *dev,
 }
 
 static int sandbox_scmi_test_process_msg(struct udevice *dev,
+struct scmi_channel *channel,
 struct scmi_msg *msg)
 {
switch (msg->protocol_id) {
diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c 
b/drivers/firmware/scmi/scmi_agent-uclass.c
index 93cfc9c395b..c9c9c00384a 100644
--- a/drivers/firmware/scmi/scmi_agent-uclass.c
+++ b/drivers/firmware/scmi/scmi_agent-uclass.c
@@ -133,7 +133,7 @@ int devm_scmi_process_msg(struct udevice *dev, struct 
scmi_channel *channel,
ops = transport_dev_ops(parent);
 
if (ops->process_msg)
-   return ops->process_msg(parent, msg);
+   return ops->process_msg(parent, NULL, msg);
 
return -EPROTONOSUPPORT;
 }
diff --git a/drivers/firmware/scmi/smccc_agent.c 
b/drivers/firmware/scmi/smccc_agent.c
index 5e166ca93ee..b7a930b24df 100644
--- a/drivers/firmware/scmi/smccc_agent.c
+++ b/drivers/firmware/scmi/smccc_agent.c
@@ -30,7 +30,9 @@ struct scmi_smccc_channel {
struct scmi_smt smt;
 };
 
-static int scmi_smccc_process_msg(struct udevice *dev, struct scmi_msg *msg)
+static int scmi_smccc_process_msg(struct udevice *dev,
+ struct scmi_channel *channel,
+ struct scmi_msg *msg)
 {
struct scmi_smccc_channel *chan = dev_get_plat(dev);
struct arm_smccc_res res;
diff --git a/include/scmi_agent-uclass.h b/include/scmi_agent-uclass.h
index 861ac6d1100..562a4cc99af 100644
--- a/include/scmi_agent-uclass.h
+++ b/include/scmi_agent-uclass.h
@@ -7,6 +7,7 @@
 
 struct udevice;
 struct scmi_msg;
+struct scmi_channel;
 
 /**
  * struct scmi_transport_ops - The functions that a SCMI transport layer must 
implement.
@@ -18,7 +19,8 @@ struct scmi_agent_ops {
 * @dev:SCMI protocol device using the transport
 * @msg:SCMI message to be transmitted
 */
-   int (*process_msg)(struct udevice *dev, struct scmi_msg *msg);
+   int (*process_msg)(struct udevice *dev, struct scmi_channel *channel,
+  struct scmi_msg *msg);
 };
 
 #endif /* _SCMI_TRANSPORT_UCLASS_H */
-- 
2.25.1



[PATCH 05/14] firmware: scmi: factorize scmi transport look up

2022-05-13 Thread Etienne Carriere
Defines local helper function find_scmi_transport_device() with the
instructions to find the SCMI transport device from a SCMI protocol
device.

Cc: Patrick Delaunay 
Signed-off-by: Etienne Carriere 
---
 drivers/firmware/scmi/scmi_agent-uclass.c | 26 +++
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c 
b/drivers/firmware/scmi/scmi_agent-uclass.c
index c9c9c00384a..f7fa5df214c 100644
--- a/drivers/firmware/scmi/scmi_agent-uclass.c
+++ b/drivers/firmware/scmi/scmi_agent-uclass.c
@@ -109,6 +109,20 @@ static int scmi_bind_protocols(struct udevice *dev)
return ret;
 }
 
+static struct udevice *find_scmi_transport_device(struct udevice *dev)
+{
+   struct udevice *parent = dev;
+
+   do {
+   parent = dev_get_parent(parent);
+   } while (parent && device_get_uclass_id(parent) != UCLASS_SCMI_AGENT);
+
+   if (!parent)
+   dev_err(dev, "Invalid SCMI device, agent not found\n");
+
+   return parent;
+}
+
 static const struct scmi_agent_ops *transport_dev_ops(struct udevice *dev)
 {
return (const struct scmi_agent_ops *)dev->driver->ops;
@@ -118,17 +132,11 @@ int devm_scmi_process_msg(struct udevice *dev, struct 
scmi_channel *channel,
  struct scmi_msg *msg)
 {
const struct scmi_agent_ops *ops;
-   struct udevice *parent = dev;
+   struct udevice *parent;
 
-   /* Find related SCMI agent device */
-   do {
-   parent = dev_get_parent(parent);
-   } while (parent && device_get_uclass_id(parent) != UCLASS_SCMI_AGENT);
-
-   if (!parent) {
-   dev_err(dev, "Invalid SCMI device, agent not found\n");
+   parent = find_scmi_transport_device(dev);
+   if (!parent)
return -ENODEV;
-   }
 
ops = transport_dev_ops(parent);
 
-- 
2.25.1



[PATCH 03/14] firmware: scmi: prepare scmi uclass API to multi-channel

2022-05-13 Thread Etienne Carriere
Changes SCMI driver API function devm_scmi_process_msg() to add
an SCMI channel reference argument for when SCMI agent supports
SCMI protocol specific channels. First argument of devm_scmi_process_msg()
is also change to point to the caller SCMI protocol device rather
than its parent device (the SCMI agent device).

The argument is a pointer to opaque struct scmi_channel known from
the SCMI transport drivers. It is currently unused and caller a pass
NULL value. A later change will enable such support once SCMI protocol
drivers have means to get the channel reference during initialization.

Cc: Lukasz Majewski 
Cc: Sean Anderson 
Cc: Jaehoon Chung 
Signed-off-by: Etienne Carriere 
---
 drivers/clk/clk_scmi.c| 10 +-
 drivers/firmware/scmi/scmi_agent-uclass.c |  3 ++-
 drivers/power/regulator/scmi_regulator.c  | 10 +-
 drivers/reset/reset-scmi.c|  4 ++--
 include/scmi_agent-uclass.h   |  2 +-
 include/scmi_agent.h  |  5 -
 6 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/drivers/clk/clk_scmi.c b/drivers/clk/clk_scmi.c
index 5aaabcf0b44..0d0bb72eaf7 100644
--- a/drivers/clk/clk_scmi.c
+++ b/drivers/clk/clk_scmi.c
@@ -24,7 +24,7 @@ static int scmi_clk_get_num_clock(struct udevice *dev, size_t 
*num_clocks)
};
int ret;
 
-   ret = devm_scmi_process_msg(dev, );
+   ret = devm_scmi_process_msg(dev, NULL, );
if (ret)
return ret;
 
@@ -49,7 +49,7 @@ static int scmi_clk_get_attibute(struct udevice *dev, int 
clkid, char **name)
};
int ret;
 
-   ret = devm_scmi_process_msg(dev, );
+   ret = devm_scmi_process_msg(dev, NULL, );
if (ret)
return ret;
 
@@ -70,7 +70,7 @@ static int scmi_clk_gate(struct clk *clk, int enable)
  in, out);
int ret;
 
-   ret = devm_scmi_process_msg(clk->dev, );
+   ret = devm_scmi_process_msg(clk->dev, NULL, );
if (ret)
return ret;
 
@@ -98,7 +98,7 @@ static ulong scmi_clk_get_rate(struct clk *clk)
  in, out);
int ret;
 
-   ret = devm_scmi_process_msg(clk->dev, );
+   ret = devm_scmi_process_msg(clk->dev, NULL, );
if (ret < 0)
return ret;
 
@@ -123,7 +123,7 @@ static ulong scmi_clk_set_rate(struct clk *clk, ulong rate)
  in, out);
int ret;
 
-   ret = devm_scmi_process_msg(clk->dev, );
+   ret = devm_scmi_process_msg(clk->dev, NULL, );
if (ret < 0)
return ret;
 
diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c 
b/drivers/firmware/scmi/scmi_agent-uclass.c
index 3819f2fa993..93cfc9c395b 100644
--- a/drivers/firmware/scmi/scmi_agent-uclass.c
+++ b/drivers/firmware/scmi/scmi_agent-uclass.c
@@ -114,7 +114,8 @@ static const struct scmi_agent_ops 
*transport_dev_ops(struct udevice *dev)
return (const struct scmi_agent_ops *)dev->driver->ops;
 }
 
-int devm_scmi_process_msg(struct udevice *dev, struct scmi_msg *msg)
+int devm_scmi_process_msg(struct udevice *dev, struct scmi_channel *channel,
+ struct scmi_msg *msg)
 {
const struct scmi_agent_ops *ops;
struct udevice *parent = dev;
diff --git a/drivers/power/regulator/scmi_regulator.c 
b/drivers/power/regulator/scmi_regulator.c
index 2966bdcf830..3325ddaf23b 100644
--- a/drivers/power/regulator/scmi_regulator.c
+++ b/drivers/power/regulator/scmi_regulator.c
@@ -38,7 +38,7 @@ static int scmi_voltd_set_enable(struct udevice *dev, bool 
enable)
  in, out);
int ret;
 
-   ret = devm_scmi_process_msg(dev, );
+   ret = devm_scmi_process_msg(dev, NULL, );
if (ret)
return ret;
 
@@ -61,7 +61,7 @@ static int scmi_voltd_get_enable(struct udevice *dev)
  in, out);
int ret;
 
-   ret = devm_scmi_process_msg(dev, );
+   ret = devm_scmi_process_msg(dev, NULL, );
if (ret < 0)
return ret;
 
@@ -85,7 +85,7 @@ static int scmi_voltd_set_voltage_level(struct udevice *dev, 
int uV)
  in, out);
int ret;
 
-   ret = devm_scmi_process_msg(dev, );
+   ret = devm_scmi_process_msg(dev, NULL, );
if (ret < 0)
return ret;
 
@@ -104,7 +104,7 @@ static int scmi_voltd_get_voltage_level(struct udevice *dev)
  in, out);
int ret;
 
-   ret = devm_scmi_process_msg(dev, );
+   ret = devm_scmi_process_msg(dev, NULL, );
if (ret < 0)
return ret;
 
@@ -147,7 +147,7 @@ static int scmi_regulator_probe(struct udevice *dev)
/* Check voltage domain is known from SCMI server */
in.domain_id = pdata->domain_id;
 
-   ret = devm_scmi_process_msg(dev, _msg);
+   ret = 

[PATCH 01/14] firmware: scmi: optee: use TEE shared memory for SCMI messages

2022-05-13 Thread Etienne Carriere
Changes implementation when using TEE dynamically allocated shared
memory to synchronize with the Linux implementation where the legacy
SMT protocol cannot be used with such memory since it is expected from
device mapped memory whereas OP-TEE shared memory is cached and
hence should not be accessed using memcpy_toio()/memcpy_fromio().

This change implements the MSG shared memory protocol introduced
in Linux [1]. The protocol uses a simplified SMT header of 32bit
named MSG_SMT to carry SCMI protocol information and uses side channel
means to carry exchanged buffer size information, as TEE invocation API
parameters when used in the SCMI OP-TEE transport.

Link: [1] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f301bba0ca7392d16a6ea4f1d264a91f1fadea1a
Signed-off-by: Etienne Carriere 
---
 drivers/firmware/scmi/optee_agent.c | 68 ++---
 drivers/firmware/scmi/smt.c | 53 +-
 drivers/firmware/scmi/smt.h | 45 ++-
 3 files changed, 149 insertions(+), 17 deletions(-)

diff --git a/drivers/firmware/scmi/optee_agent.c 
b/drivers/firmware/scmi/optee_agent.c
index 1f265922343..e76f738bbaf 100644
--- a/drivers/firmware/scmi/optee_agent.c
+++ b/drivers/firmware/scmi/optee_agent.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * Copyright (C) 2020-2021 Linaro Limited.
+ * Copyright (C) 2020-2022 Linaro Limited.
  */
 
 #define LOG_CATEGORY UCLASS_SCMI_AGENT
@@ -98,6 +98,22 @@ enum optee_smci_pta_cmd {
 * [in] value[0].b: Requested capabilities mask (enum pta_scmi_caps)
 */
PTA_SCMI_CMD_GET_CHANNEL = 3,
+
+   /*
+* PTA_SCMI_CMD_PROCESS_MSG_CHANNEL - Process SCMI message in MSG
+* buffers pointed by memref parameters
+*
+* [in] value[0].a: Channel handle
+* [in] memref[1]: Message buffer (MSG header and SCMI payload)
+* [out]memref[2]: Response buffer (MSG header and SCMI payload)
+*
+* Shared memories used for SCMI message/response are MSG buffers
+* referenced by param[1] and param[2]. MSG transport protocol
+* uses a 32bit header to carry SCMI meta-data (protocol ID and
+* protocol message ID) followed by the effective SCMI message
+* payload.
+*/
+   PTA_SCMI_CMD_PROCESS_MSG_CHANNEL = 4,
 };
 
 /*
@@ -106,9 +122,17 @@ enum optee_smci_pta_cmd {
  * PTA_SCMI_CAPS_SMT_HEADER
  * When set, OP-TEE supports command using SMT header protocol (SCMI shmem) in
  * shared memory buffers to carry SCMI protocol synchronisation information.
+ *
+ * PTA_SCMI_CAPS_MSG_HEADER
+ * When set, OP-TEE supports command using MSG header protocol in an OP-TEE
+ * shared memory to carry SCMI protocol synchronisation information and SCMI
+ * message payload.
  */
 #define PTA_SCMI_CAPS_NONE 0
 #define PTA_SCMI_CAPS_SMT_HEADER   BIT(0)
+#define PTA_SCMI_CAPS_MSG_HEADER   BIT(1)
+#define PTA_SCMI_CAPS_MASK (PTA_SCMI_CAPS_SMT_HEADER | \
+PTA_SCMI_CAPS_MSG_HEADER)
 
 static int open_channel(struct udevice *dev, struct channel_session *sess)
 {
@@ -139,7 +163,10 @@ static int open_channel(struct udevice *dev, struct 
channel_session *sess)
 
param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INOUT;
param[0].u.value.a = chan->channel_id;
-   param[0].u.value.b = PTA_SCMI_CAPS_SMT_HEADER;
+   if (chan->dyn_shm)
+   param[0].u.value.b = PTA_SCMI_CAPS_MSG_HEADER;
+   else
+   param[0].u.value.b = PTA_SCMI_CAPS_SMT_HEADER;
 
ret = tee_invoke_func(sess->tee, _arg, ARRAY_SIZE(param), param);
if (ret || cmd_arg.ret) {
@@ -167,34 +194,48 @@ static int invoke_cmd(struct udevice *dev, struct 
channel_session *sess,
 {
struct scmi_optee_channel *chan = dev_get_plat(dev);
struct tee_invoke_arg arg = { };
-   struct tee_param param[2] = { };
+   struct tee_param param[3] = { };
int ret;
 
-   scmi_write_msg_to_smt(dev, >smt, msg);
-
arg.session = sess->tee_session;
param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT;
param[0].u.value.a = sess->channel_hdl;
 
-   if (chan->dyn_shm) {
-   arg.func = PTA_SCMI_CMD_PROCESS_SMT_CHANNEL_MESSAGE;
-   param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INOUT;
+   if (sess->tee_shm) {
+   size_t in_size;
+
+   ret = scmi_msg_to_smt_msg(dev, >smt, msg, _size);
+   if (ret < 0)
+   return ret;
+
+   arg.func = PTA_SCMI_CMD_PROCESS_MSG_CHANNEL;
+   param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INPUT;
param[1].u.memref.shm = sess->tee_shm;
-   param[1].u.memref.size = SCMI_SHM_SIZE;
+   param[1].u.memref.size = in_size;
+   param[2].attr = TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT;
+   param[2].u.memref.shm = 

[PATCH 02/14] firmware: scmi: optee: fix inline description of PTA_SCMI_CMD_GET_CHANNEL

2022-05-13 Thread Etienne Carriere
Removes inaccurate inline description of OP-TEE SCMI PTA command
PTA_SCMI_CMD_GET_CHANNEL.

Signed-off-by: Etienne Carriere 
---
 drivers/firmware/scmi/optee_agent.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/firmware/scmi/optee_agent.c 
b/drivers/firmware/scmi/optee_agent.c
index e76f738bbaf..bf0647bafd1 100644
--- a/drivers/firmware/scmi/optee_agent.c
+++ b/drivers/firmware/scmi/optee_agent.c
@@ -91,8 +91,6 @@ enum optee_smci_pta_cmd {
/*
 * PTA_SCMI_CMD_GET_CHANNEL - Get channel handle
 *
-* SCMI shm information are 0 if agent expects to use OP-TEE regular SHM
-*
 * [in] value[0].a: Channel identifier
 * [out]value[0].a: Returned channel handle
 * [in] value[0].b: Requested capabilities mask (enum pta_scmi_caps)
-- 
2.25.1



[PATCH 00/14] SCMI multi-channel and optee shm

2022-05-13 Thread Etienne Carriere
Dear all,

This series implements 2 features in driver/firmware/scmi.

First, a single change adds support for SCMI OP-TEE transport to
use OP-TEE native shared memory. See the 1st patch in this series:
"firmware: scmi: optee: use TEE shared memory for SCMI messages".

Then come changes for supporting multi-channel in the SCMI drivers.
I've split the implementation in 11 several small incremental changes
in the hope it helps the review. Few minor fixup commits are also
inserted in the series. 

Regards,
Etienne

Etienne Carriere (14):
  firmware: scmi: optee: use TEE shared memory for SCMI messages
  firmware: scmi: optee: fix inline description of
PTA_SCMI_CMD_GET_CHANNEL
  firmware: scmi: prepare scmi uclass API to multi-channel
  firmware: scmi: prepare uclass to pass channel reference
  firmware: scmi: factorize scmi transport look up
  firmware: scmi: add multi-channel support
  firmware: scmi: mailbox transport: implement multi-channel
  firmware: scmi: smccc transport: implement multi-channel
  firmware: scmi: optee transport: implement multi-channel
  clk: scmi: support SCMI multi-channel
  reset: scmi: support SCMI multi-channel
  power: regulator: scmi: support SCMI multi-channel
  power: regulator: scmi: simplify scmi_voltd_set_enable()
  firmware: scmi: use multi channel in mailbox, optee and smccc agents

 drivers/clk/clk_scmi.c |  23 +++-
 drivers/firmware/scmi/mailbox_agent.c  |  65 +++--
 drivers/firmware/scmi/optee_agent.c| 147 -
 drivers/firmware/scmi/sandbox-scmi_agent.c |   1 +
 drivers/firmware/scmi/scmi_agent-uclass.c  |  48 +--
 drivers/firmware/scmi/smccc_agent.c|  56 +++-
 drivers/firmware/scmi/smt.c|  53 +++-
 drivers/firmware/scmi/smt.h|  45 ++-
 drivers/power/regulator/scmi_regulator.c   |  26 ++--
 drivers/reset/reset-scmi.c |  15 ++-
 include/scmi_agent-uclass.h|  15 ++-
 include/scmi_agent.h   |  14 +-
 12 files changed, 431 insertions(+), 77 deletions(-)

-- 
2.25.1