Re: [PATCH 4/4] nvmem: layouts: add U-Boot env layout

2023-12-18 Thread Miquel Raynal
Hi Rafał,

zaj...@gmail.com wrote on Mon, 18 Dec 2023 23:10:20 +0100:

> On 18.12.2023 15:21, Miquel Raynal wrote:
> > Hi Rafał,
> > 
> > zaj...@gmail.com wrote on Mon, 18 Dec 2023 14:37:22 +0100:
> >   
> >> From: Rafał Miłecki 
> >>
> >> This patch moves all generic (NVMEM devices independent) code from NVMEM
> >> device driver to NVMEM layout driver. Then it adds a simple NVMEM layout
> >> code on top of it.
> >>
> >> Thanks to proper layout it's possible to support U-Boot env data stored
> >> on any kind of NVMEM device.
> >>
> >> For backward compatibility with old DT bindings we need to keep old
> >> NVMEM device driver functional. To avoid code duplication a parsing
> >> function is exported and reused in it.
> >>
> >> Signed-off-by: Rafał Miłecki 
> >> ---  
> > 
> > I have a couple of comments about the original driver which gets
> > copy-pasted in the new layout driver, maybe you could clean these
> > (the memory leak should be fixed before the migration so it can be
> > backported easily, the others are just style so it can be done after, I
> > don't mind).
> > 
> > ...
> >   
> >> +int u_boot_env_parse(struct device *dev, struct nvmem_device *nvmem,
> >> +   enum u_boot_env_format format)
> >> +{
> >> +  size_t crc32_data_offset;
> >> +  size_t crc32_data_len;
> >> +  size_t crc32_offset;
> >> +  size_t data_offset;
> >> +  size_t data_len;
> >> +  size_t dev_size;
> >> +  uint32_t crc32;
> >> +  uint32_t calc;
> >> +  uint8_t *buf;
> >> +  int bytes;
> >> +  int err;
> >> +
> >> +  dev_size = nvmem_dev_size(nvmem);
> >> +
> >> +  buf = kcalloc(1, dev_size, GFP_KERNEL);  
> > 
> > Out of curiosity, why kcalloc(1,...) rather than kzalloc() ?  
> 
> I used kcalloc() initially as I didn't need buffer to be zeroed.

I think kcalloc() initializes the memory to zero.
https://elixir.bootlin.com/linux/latest/source/include/linux/slab.h#L659

If you don't need it you can switch to kmalloc() instead, I don't mind,
but kcalloc() is meant to be used with arrays, I don't see the point of
using kcalloc() in this case.

> 
> I see that memory-allocation.rst however says:
>  > And, to be on the safe side it's best to use routines that set memory to 
> zero, like kzalloc().  
> 
> It's probably close to zero cost to zero that buffer so it could be kzalloc().
> 
> 
> >> +  if (!buf) {
> >> +  err = -ENOMEM;
> >> +  goto err_out;  
> > 
> > We could directly return ENOMEM here I guess.
> >   
> >> +  }
> >> +
> >> +  bytes = nvmem_device_read(nvmem, 0, dev_size, buf);
> >> +  if (bytes < 0)
> >> +  return bytes;
> >> +  else if (bytes != dev_size)
> >> +  return -EIO;  
> > 
> > Don't we need to free buf in the above cases?
> >   
> >> +  switch (format) {
> >> +  case U_BOOT_FORMAT_SINGLE:
> >> +  crc32_offset = offsetof(struct u_boot_env_image_single, crc32);
> >> +  crc32_data_offset = offsetof(struct u_boot_env_image_single, 
> >> data);
> >> +  data_offset = offsetof(struct u_boot_env_image_single, data);
> >> +  break;
> >> +  case U_BOOT_FORMAT_REDUNDANT:
> >> +  crc32_offset = offsetof(struct u_boot_env_image_redundant, 
> >> crc32);
> >> +  crc32_data_offset = offsetof(struct u_boot_env_image_redundant, 
> >> data);
> >> +  data_offset = offsetof(struct u_boot_env_image_redundant, data);
> >> +  break;
> >> +  case U_BOOT_FORMAT_BROADCOM:
> >> +  crc32_offset = offsetof(struct u_boot_env_image_broadcom, 
> >> crc32);
> >> +  crc32_data_offset = offsetof(struct u_boot_env_image_broadcom, 
> >> data);
> >> +  data_offset = offsetof(struct u_boot_env_image_broadcom, data);
> >> +  break;
> >> +  }
> >> +  crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset));  
> > 
> > Looks a bit convoluted, any chances we can use intermediate variables
> > to help decipher this?
> >   
> >> +  crc32_data_len = dev_size - crc32_data_offset;
> >> +  data_len = dev_size - data_offset;
> >> +
> >> +  calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L;
> >> +  if (calc != crc32) {
> >> +  dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 
> >> 0x%08x)\n", calc, crc32);
> >> +  err = -EINVAL;
> >> +  goto err_kfree;
> >> +  }
> >> +
> >> +  buf[dev_size - 1] = '\0';
> >> +  err = u_boot_env_parse_cells(dev, nvmem, buf, data_offset, data_len);
> >> +  if (err)
> >> +  dev_err(dev, "Failed to add cells: %d\n", err);  
> > 
> > Please drop this error message, the only reason for which the function
> > call would fail is apparently an ENOMEM case.
> >   
> >> +
> >> +err_kfree:
> >> +  kfree(buf);
> >> +err_out:
> >> +  return err;
> >> +}
> >> +EXPORT_SYMBOL_GPL(u_boot_env_parse);
> >> +
> >> +static int u_boot_env_add_cells(struct device *dev, struct nvmem_device 
> >> *nvmem)
> >> +{
> >> +  const struct of_device_id *match;
> >> +  struct device_node *layout_np;
> >> +  enum u_boot_env_format format;
> >> +
> >> +  layout_np = of_nvmem_la

Re: [PATCH v2 13/17] video: rockchip: Add rk3328 vop support

2023-12-18 Thread Jagan Teki
Hi Andy,

On Tue, Dec 19, 2023 at 6:50 AM Andy Yan  wrote:
>
>
> Hi Jaqan:
>
> At 2023-12-19 03:11:10, "Jagan Teki"  wrote:
> >From: Jagan Teki 
> >
> >Add support for Rockchip RK3328 VOP.
> >
> >Require VOP cleanup before handoff to Linux by writing reset values to
> >WIN registers. Without this Linux VOP trigger page fault as below
> >[0.752016] Loading compiled-in X.509 certificates
> >[0.787796] inno_hdmi_phy_rk3328_clk_recalc_rate: parent 2400
> >[0.788391] inno-hdmi-phy ff43.phy: 
> >inno_hdmi_phy_rk3328_clk_recalc_rate rate 14850 vco 14850
> >[0.798353] rockchip-drm display-subsystem: bound ff37.vop (ops 
> >vop_component_ops)
> >[0.799403] dwhdmi-rockchip ff3c.hdmi: supply avdd-0v9 not found, 
> >using dummy regulator
> >[0.800288] rk_iommu ff373f00.iommu: Enable stall request timed out, 
> >status: 0x4b
> >[0.801131] dwhdmi-rockchip ff3c.hdmi: supply avdd-1v8 not found, 
> >using dummy regulator
> >[0.802056] rk_iommu ff373f00.iommu: Disable paging request timed out, 
> >status: 0x4b
> >[0.803233] dwhdmi-rockchip ff3c.hdmi: Detected HDMI TX controller 
> >v2.11a with HDCP (inno_dw_hdmi_phy2)
> >[0.805355] dwhdmi-rockchip ff3c.hdmi: registered DesignWare HDMI I2C 
> >bus driver
> >[0.808769] rockchip-drm display-subsystem: bound ff3c.hdmi (ops 
> >dw_hdmi_rockchip_ops)
> >[0.810869] [drm] Initialized rockchip 1.0.0 20140818 for 
> >display-subsystem on minor 0
> >
> >Signed-off-by: Jagan Teki 
> >---
> >Changes for v2:
> >- Add VOP cleanup
> >- Update commit
> >
> > drivers/video/rockchip/Makefile |  1 +
> > drivers/video/rockchip/rk3328_vop.c | 83 +
> > 2 files changed, 84 insertions(+)
> > create mode 100644 drivers/video/rockchip/rk3328_vop.c
> >
> >diff --git a/drivers/video/rockchip/Makefile 
> >b/drivers/video/rockchip/Makefile
> >index 4991303c73..f55beceebf 100644
> >--- a/drivers/video/rockchip/Makefile
> >+++ b/drivers/video/rockchip/Makefile
> >@@ -6,6 +6,7 @@
> > ifdef CONFIG_VIDEO_ROCKCHIP
> > obj-y += rk_vop.o
> > obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288_vop.o
> >+obj-$(CONFIG_ROCKCHIP_RK3328) += rk3328_vop.o
> > obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399_vop.o
> > obj-$(CONFIG_DISPLAY_ROCKCHIP_EDP) += rk_edp.o
> > obj-$(CONFIG_DISPLAY_ROCKCHIP_LVDS) += rk_lvds.o
> >diff --git a/drivers/video/rockchip/rk3328_vop.c 
> >b/drivers/video/rockchip/rk3328_vop.c
> >new file mode 100644
> >index 00..a4da3a91e8
> >--- /dev/null
> >+++ b/drivers/video/rockchip/rk3328_vop.c
> >@@ -0,0 +1,83 @@
> >+// SPDX-License-Identifier: GPL-2.0+
> >+/*
> >+ * Copyright (c) 2023 Edgeble AI Technologies Pvt. Ltd.
> >+ */
> >+
> >+#include 
> >+#include 
> >+#include 
> >+#include "rk_vop.h"
> >+
> >+DECLARE_GLOBAL_DATA_PTR;
> >+
> >+static void rk3328_set_pin_polarity(struct udevice *dev,
> >+  enum vop_modes mode, u32 polarity)
> >+{
> >+  struct rk_vop_priv *priv = dev_get_priv(dev);
> >+  struct rk3288_vop *regs = priv->regs;
> >+
> >+  switch (mode) {
> >+  case VOP_MODE_HDMI:
> >+  clrsetbits_le32(®s->dsp_ctrl1,
> >+  M_RK3399_DSP_HDMI_POL,
> >+  V_RK3399_DSP_HDMI_POL(polarity));
> >+  break;
> >+  default:
> >+  debug("%s: unsupported output mode %x\n", __func__, mode);
> >+  }
> >+}
> >+
> >+static int rk3328_vop_probe(struct udevice *dev)
> >+{
> >+  /* Before relocation we don't need to do anything */
> >+  if (!(gd->flags & GD_FLG_RELOC))
> >+  return 0;
> >+
> >+  return rk_vop_probe(dev);
> >+}
> >+
> >+static int rk3328_vop_remove(struct udevice *dev)
> >+{
> >+  struct rk_vop_priv *priv = dev_get_priv(dev);
> >+  struct rk3288_vop *regs = priv->regs;
> >+  struct rk3288_vop *win_regs = priv->regs + priv->win_offset;
> >+
> >+  /* write reset values */
> >+  writel(0xef013f, &win_regs->win0_act_info);
> >+  writel(0xef013f, &win_regs->win0_dsp_info);
> >+  writel(0xa000a, &win_regs->win0_dsp_st);
> >+  writel(0x0, &win_regs->win0_yrgb_mst);
> >+  writel(0x01, ®s->reg_cfg_done);
> >+
> >+  return 0;
> >+}
>
> I think this just workaround Linux iommu page fault by luck。
> The reset value(what you called it is)your write just let win0 read a
> 320x240 rectangular from address 0 and display it at next frame(maybe 16ms 
> later if your
> current display is run at 60HZ)。
>
> 1. we don't know what content is at address 0, so you will see something 
> strange on your monitor.
> 2. there is no guarantee that address 0 is really readable(maybe a security 
> memory space, or maybe
> it is not a valid address), this may cause another issue that not easy to 
> detect。

Okay. Can you suggest any proper way to clean up VOP? All these reset
values are referred to as per the TRM and read before enabling the
video.

Thanks,
Jagan.


RE: [PATCH] clk: altera: n5x: Fix MEMCLKMGR_EXTCNTRST_C0CNTRST to bit(0)

2023-12-18 Thread Chee, Tien Fong
Hi,

> -Original Message-
> From: Maniyam, Dinesh 
> Sent: Friday, December 15, 2023 3:15 PM
> To: u-boot@lists.denx.de
> Cc: Marek ; Simon ;
> Lukasz Majewski ; Sean Anderson ;
> Chee, Tien Fong ; Hea, Kok Kiang
> ; Maniyam, Dinesh
> ; Ng, Boon Khai ;
> Yuslaimi, Alif Zakuan ; Chong, Teik Heng
> ; Zamri, Muhammad Hazim Izzat
> ; Lim, Jit Loon
> ; Tang, Sieu Mun 
> Subject: [PATCH] clk: altera: n5x: Fix MEMCLKMGR_EXTCNTRST_C0CNTRST to
> bit(0)
> 
> From: Dinesh Maniyam 
> 
> MEMCLKMGR_EXTCNTRST_C0CNTRST register defined as BIT[0] in
> documentation but it is wrongly defined as BIT[7] in u-boot code. This
> register is used to hold associated pingpong counter in reset while PLL and
> 5:1 mux configuration is changed.
> 
> Signed-off-by: Dinesh Maniyam 
> ---
>  drivers/clk/altera/clk-mem-n5x.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/clk/altera/clk-mem-n5x.h b/drivers/clk/altera/clk-mem-
> n5x.h
> index 7b687012e8..c6bc44bb34 100644
> --- a/drivers/clk/altera/clk-mem-n5x.h
> +++ b/drivers/clk/altera/clk-mem-n5x.h
> @@ -1,6 +1,6 @@
>  /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
>  /*
> - * Copyright (C) 2020-2022 Intel Corporation 
> + * Copyright (C) 2020-2023 Intel Corporation 
>   */
> 
>  #ifndef  _CLK_MEM_N5X_
> @@ -77,7 +77,7 @@
>  #define MEMCLKMGR_PLLOUTDIV_C0CNT_MASK
>   GENMASK(4, 0)
>  #define MEMCLKMGR_PLLOUTDIV_C0CNT_OFFSET 0
> 
> -#define MEMCLKMGR_EXTCNTRST_C0CNTRST BIT(7)
> +#define MEMCLKMGR_EXTCNTRST_C0CNTRST BIT(0)
>  #define MEMCLKMGR_EXTCNTRST_ALLCNTRST\
>   (MEMCLKMGR_EXTCNTRST_C0CNTRST)
> 
> --
> 2.26.2

Reviewed-by: Tien Fong Chee 

Regards
Tien Fong



RE: [PATCH] arm: dts: agilex: Increase reserved memory size to 32MB

2023-12-18 Thread Chee, Tien Fong
Hi,

> -Original Message-
> From: Maniyam, Dinesh 
> Sent: Friday, December 15, 2023 3:22 PM
> To: u-boot@lists.denx.de
> Cc: Marek ; Simon ;
> Chee, Tien Fong ; Hea, Kok Kiang
> ; Maniyam, Dinesh
> ; Ng, Boon Khai ;
> Yuslaimi, Alif Zakuan ; Chong, Teik Heng
> ; Zamri, Muhammad Hazim Izzat
> ; Lim, Jit Loon
> ; Tang, Sieu Mun 
> Subject: [PATCH] arm: dts: agilex: Increase reserved memory size to 32MB
> 
> From: Dinesh Maniyam 
> 
> The reserved space is extended to 32MB in Linux kernel because additional
> space is needed for authorization execution of JIC/RBF file.
> U-Boot required to align with Linux.
> 
> Signed-off-by: Dinesh Maniyam 
> ---
>  arch/arm/dts/socfpga_agilex.dtsi | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/dts/socfpga_agilex.dtsi
> b/arch/arm/dts/socfpga_agilex.dtsi
> index c3ead2d72b..712304d07a 100644
> --- a/arch/arm/dts/socfpga_agilex.dtsi
> +++ b/arch/arm/dts/socfpga_agilex.dtsi
> @@ -1,6 +1,6 @@
>  // SPDX-License-Identifier: GPL-2.0
>  /*
> - * Copyright (C) 2019, Intel Corporation
> + * Copyright (C) 2019-2023 Intel Corporation 
>   */
> 
>  /dts-v1/;
> @@ -20,7 +20,7 @@
> 
>   service_reserved: svcbuffer@0 {
>   compatible = "shared-dma-pool";
> - reg = <0x0 0x0 0x0 0x100>;
> + reg = <0x0 0x0 0x0 0x200>;
>   alignment = <0x1000>;
>   no-map;
>   };
> --
> 2.26.2

Reviewed-by: Tien Fong Chee 

Regards
Tien Fong



RE: [PATCH v1 1/1] drivers: misc: Add socfpga_dtreg driver for Intel SoCFPGA

2023-12-18 Thread Chee, Tien Fong
Hi,

> -Original Message-
> From: Lau, Wan Yee 
> Sent: Friday, December 8, 2023 4:37 PM
> To: u-boot@lists.denx.de
> Cc: Simon Glass ; Kever Yang  chips.com>; Bin Meng ; Jonas Karlman
> ; Jean-Marie Lemetayer ; Peng
> Fan ; Vladimir Zapolskiy
> ; Konrad Dybcio ;
> Marek Vasut ; Simon Goldschmidt
> ; Chee, Tien Fong
> ; Hea, Kok Kiang ;
> Maniyam, Dinesh ; Ng, Boon Khai
> ; Yuslaimi, Alif Zakuan
> ; Chong, Teik Heng
> ; Zamri, Muhammad Hazim Izzat
> ; Lim, Jit Loon
> ; Tang, Sieu Mun 
> Subject: [PATCH v1 1/1] drivers: misc: Add socfpga_dtreg driver for Intel
> SoCFPGA
> 
> From: Wan Yee Lau 
> 
> This driver can be used to provide user a clean interface and all register
> settings are centralized in one place, device tree without need for
> hardcoding in the source code.
> 
> Signed-off-by: Wan Yee Lau 
> ---
>  .../misc/socfpga_dtreg.txt|  66 ++
>  drivers/misc/Kconfig  |   7 ++
>  drivers/misc/Makefile |   1 +
>  drivers/misc/socfpga_dtreg.c  | 117 ++
>  4 files changed, 191 insertions(+)
>  create mode 100644 doc/device-tree-bindings/misc/socfpga_dtreg.txt
>  create mode 100644 drivers/misc/socfpga_dtreg.c
> 
> diff --git a/doc/device-tree-bindings/misc/socfpga_dtreg.txt b/doc/device-
> tree-bindings/misc/socfpga_dtreg.txt
> new file mode 100644
> index 00..5458103f88
> --- /dev/null
> +++ b/doc/device-tree-bindings/misc/socfpga_dtreg.txt
> @@ -0,0 +1,66 @@
> +* Firewall and privilege register settings in device tree
> +
> +Required properties:
> +
> +
> +- compatible: should contain "intel,socfpga-dtreg"
> +- reg: Physical base address and size of block register.
> +- intel,offset-settings: 32-bit offset address of block register,
> +  followed by 32-bit value settings and
> +  the masking bits, only masking bit
> +  set to 1 allows modification.
> +
> +This driver can be used to provide user a clean interface and all
> +register settings are centralized in one place, device tree without
> +need for hardcoding in the source code.
> +
> +General setup would be to set the memory address used by the register,
> +followed by the offset-settings containing the 32-bit offset address of
> +the block register, then the 32-bit value settings and lastly the
> +masking bits.
> +
> +Example:
> +
> +
> +Configuration for multiple dtreg node support in device tree:
> +
> + socfpga_mainfirewall: socfpga-mainfirewall {
> + compatible = "intel,socfpga-dtreg";
> + #address-cells = <1>;
> +#size-cells = <1>;
> + bootph-all;
> +
> +coh_cpu0_bypass_OC_Firewall_main_Firewall@f7100200 {
> + reg = <0xf7100200 0x0014>;
> +intel,offset-settings =
> + /* Disable ocram security at CCU for 
> non secure
> access */
> +<0x004 0x8000 0xe007>,
> +<0x008 0x8000 0xe007>,
> +<0x00c 0x8000 0xe007>,
> +<0x010 0x8000 0xe007>;
> +bootph-all;
> +};
> +};
> +
> + socfpga_mpfefirewall: socfpga-mpfefirewall {
> + compatible = "intel,socfpga-dtreg";
> + #address-cells = <1>;
> +#size-cells = <1>;
> + bootph-all;
> +
> +soc_noc_fw_mpfe_csr_inst_0_mpfe_scr@f802 {
> +reg = <0xf802 0x001c>;
> +intel,offset-settings =
> +/* Disable MPFE firewall for SMMU */
> +<0x 0x00010101 0x00010101>,
> +/* Disable MPFE firewall for HMC 
> adapter */
> +<0x0004 0x0001 0x00010101>;
> + bootph-all;
> +};
> +};
> +
> +To call the nodes use:
> +
> + ret = uclass_get_device_by_name(UCLASS_NOP, "socfpga-
> mainfirewall", &dev);
> + ret = uclass_get_device_by_name(UCLASS_NOP, "socfpga-
> mpfefirewall",
> +&dev);
> +
> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index
> fccd9b89b8..c423905ba2 100644
> --- a/drivers/misc/Kconfig
> +++ b/drivers/misc/Kconfig
> @@ -683,4 +683,11 @@ config SL28CPLD
> the base driver which provides common access methods for the
> sub-drivers.
> 
> +config SPL_SOCFPGA_DT_REG
> + bool "Enable register setting from device tree in SPL"
> + depends on SPL
> + help
> +   Enable register setting fro

Re: [PATCH 0/7] Add SE HMBSC board support

2023-12-18 Thread Sumit Garg
Hi Simon,

On Mon, 18 Dec 2023 at 20:32, Simon Glass  wrote:
>
> Hi Sumit,
>
> On Mon, 18 Dec 2023 at 00:24, Sumit Garg  wrote:
> >
> > SE HMIBSC board is based on Qcom APQ8016 SoC. One of the major
>
> Could you please add a doc/ file for this board and explain how to
> build it and how to run U-Boot on it?

Ah I forgot to add that since the build/boot instructions are quite
similar to db410c. BTW, I will add that in the next spin.

-Sumit

>
> > difference from db410c is serial port where HMIBSC board uses UART1 as
> > the debug console with an RS232 port, patch #1 - #3 adds corresponding
> > driver support.
> >
> > Patch #4 adds main HMIBSC board specific bits, features:
> > - Qualcomm Snapdragon 410C SoC - APQ8016 (4xCortex A53, Adreno 306)
> > - 2GiB RAM
> > - 64GiB eMMC, SD slot
> > - WiFi and Bluetooth
> > - 2x Host, 1x Device USB port
> > - HDMI
> > - Discrete TPM2 chip over SPI
> >
> > Patch #5 - #7 enables specific board features like RAUC support,
> > environment protection and USB networking support.
> >
> > This patch series is based on top of Qcom maintainer tree [1] + the latest
> > PMIC patch-set [2]. Feedback is very much welcome.
> >
> > [1] 
> > https://source.denx.de/u-boot/custodians/u-boot-snapdragon/-/commits/u-boot-qcom-next?ref_type=heads
> > [2] https://patchwork.ozlabs.org/project/uboot/list/?series=385322
> >
> > Sumit Garg (7):
> >   clk: apq8016: Add support for UART1 clocks
> >   serial_msm: Add support for RS232 GPIOs
> >   serial_msm: Enable RS232 flow control
> >   board: Add SE HMIBSC board support
> >   hmibsc: Enable RAUC support
> >   hmibsc: enable U-Boot Environment variables protection
> >   hmibsc: Enable LAN75XX USB ethernet driver
> >
> >  arch/arm/dts/Makefile  |   1 +
> >  arch/arm/dts/hmibsc-uboot.dtsi |  43 +++
> >  arch/arm/dts/hmibsc.dts| 188 +
> >  arch/arm/mach-snapdragon/Kconfig   |  18 +++
> >  arch/arm/mach-snapdragon/Makefile  |   1 +
> >  board/schneider/hmibsc/Kconfig |  15 +++
> >  board/schneider/hmibsc/MAINTAINERS |   6 +
> >  board/schneider/hmibsc/Makefile|   5 +
> >  board/schneider/hmibsc/hmibsc.c| 179 +++
> >  board/schneider/hmibsc/hmibsc.env  |  11 ++
> >  configs/hmibsc_defconfig   |  79 
> >  drivers/clk/qcom/clock-apq8016.c   |  44 ++-
> >  drivers/serial/serial_msm.c|  23 +++-
> >  drivers/usb/host/Kconfig   |   1 +
> >  include/configs/hmibsc.h   |  59 +
> >  15 files changed, 665 insertions(+), 8 deletions(-)
> >  create mode 100644 arch/arm/dts/hmibsc-uboot.dtsi
> >  create mode 100644 arch/arm/dts/hmibsc.dts
> >  create mode 100644 board/schneider/hmibsc/Kconfig
> >  create mode 100644 board/schneider/hmibsc/MAINTAINERS
> >  create mode 100644 board/schneider/hmibsc/Makefile
> >  create mode 100644 board/schneider/hmibsc/hmibsc.c
> >  create mode 100644 board/schneider/hmibsc/hmibsc.env
> >  create mode 100644 configs/hmibsc_defconfig
> >  create mode 100644 include/configs/hmibsc.h
> >
> > --
> > 2.34.1
> >
>
> Regards,
> Simon


[PATCH v7 6/6] spi: zynq_qspi: Add parallel memories support in QSPI driver

2023-12-18 Thread Venkatesh Yadav Abbarapu
Add support for parallel memories in zynq_qspi.c driver. In case of
parallel memories STRIPE bit is set and sent to the qspi ip, which will
send data bits to both the flashes in parallel. However for few commands
we should not use stripe, instead send same data to both the flashes.
Those commands are exclueded by using zynqmp_qspi_update_stripe().

Also update copyright info for this file.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/spi/zynq_qspi.c | 113 
 1 file changed, 102 insertions(+), 11 deletions(-)

diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c
index bc82acd0b6..41f7ae2ab2 100644
--- a/drivers/spi/zynq_qspi.c
+++ b/drivers/spi/zynq_qspi.c
@@ -1,7 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * (C) Copyright 2013 Xilinx, Inc.
+ * (C) Copyright 2013 - 2022, Xilinx, Inc.
  * (C) Copyright 2015 Jagan Teki 
+ * (C) Copyright 2023, Advanced Micro Devices, Inc.
  *
  * Xilinx Zynq Quad-SPI(QSPI) controller driver (master mode only)
  */
@@ -13,10 +14,12 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include "../mtd/spi/sf_internal.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -42,6 +45,21 @@ DECLARE_GLOBAL_DATA_PTR;
 #define ZYNQ_QSPI_TXD_00_01_OFFSET 0x80/* Transmit 1-byte inst */
 #define ZYNQ_QSPI_TXD_00_10_OFFSET 0x84/* Transmit 2-byte inst */
 #define ZYNQ_QSPI_TXD_00_11_OFFSET 0x88/* Transmit 3-byte inst */
+#define ZYNQ_QSPI_FR_QOUT_CODE 0x6B/* read instruction code */
+
+#define QSPI_SELECT_LOWER_CSBIT(0)
+#define QSPI_SELECT_UPPER_CSBIT(1)
+
+/*
+ * QSPI Linear Configuration Register
+ *
+ * It is named Linear Configuration but it controls other modes when not in
+ * linear mode also.
+ */
+#define ZYNQ_QSPI_LCFG_TWO_MEM_MASK 0x4000 /* QSPI Enable Bit Mask */
+#define ZYNQ_QSPI_LCFG_SEP_BUS_MASK 0x2000 /* QSPI Enable Bit Mask */
+#define ZYNQ_QSPI_LCFG_U_PAGE   0x1000 /* QSPI Upper memory set */
+#define ZYNQ_QSPI_LCFG_DUMMY_SHIFT  8
 
 #define ZYNQ_QSPI_TXFIFO_THRESHOLD 1   /* Tx FIFO threshold level*/
 #define ZYNQ_QSPI_RXFIFO_THRESHOLD 32  /* Rx FIFO threshold level */
@@ -101,7 +119,11 @@ struct zynq_qspi_priv {
int bytes_to_transfer;
int bytes_to_receive;
unsigned int is_inst;
+   unsigned int is_parallel;
+   unsigned int is_stacked;
+   unsigned int u_page;
unsigned cs_change:1;
+   unsigned is_strip:1;
 };
 
 static int zynq_qspi_of_to_plat(struct udevice *bus)
@@ -112,7 +134,6 @@ static int zynq_qspi_of_to_plat(struct udevice *bus)
 
plat->regs = (struct zynq_qspi_regs *)fdtdec_get_addr(blob,
  node, "reg");
-
return 0;
 }
 
@@ -147,6 +168,9 @@ static void zynq_qspi_init_hw(struct zynq_qspi_priv *priv)
/* Disable Interrupts */
writel(ZYNQ_QSPI_IXR_ALL_MASK, ®s->idr);
 
+   /* Disable linear mode as the boot loader may have used it */
+   writel(0x0, ®s->lqspicfg);
+
/* Clear the TX and RX threshold reg */
writel(ZYNQ_QSPI_TXFIFO_THRESHOLD, ®s->txftr);
writel(ZYNQ_QSPI_RXFIFO_THRESHOLD, ®s->rxftr);
@@ -164,12 +188,11 @@ static void zynq_qspi_init_hw(struct zynq_qspi_priv *priv)
confr |= ZYNQ_QSPI_CR_IFMODE_MASK | ZYNQ_QSPI_CR_MCS_MASK |
ZYNQ_QSPI_CR_PCS_MASK | ZYNQ_QSPI_CR_FW_MASK |
ZYNQ_QSPI_CR_MSTREN_MASK;
-   writel(confr, ®s->cr);
 
-   /* Disable the LQSPI feature */
-   confr = readl(®s->lqspicfg);
-   confr &= ~ZYNQ_QSPI_LQSPICFG_LQMODE_MASK;
-   writel(confr, ®s->lqspicfg);
+   if (priv->is_stacked)
+   confr |= 0x10;
+
+   writel(confr, ®s->cr);
 
/* Enable SPI */
writel(ZYNQ_QSPI_ENR_SPI_EN_MASK, ®s->enr);
@@ -181,6 +204,7 @@ static int zynq_qspi_child_pre_probe(struct udevice *bus)
struct zynq_qspi_priv *priv = dev_get_priv(bus->parent);
 
priv->max_hz = slave->max_hz;
+   slave->multi_cs_cap = true;
 
return 0;
 }
@@ -363,8 +387,8 @@ static void zynq_qspi_fill_tx_fifo(struct zynq_qspi_priv 
*priv, u32 size)
unsigned len, offset;
struct zynq_qspi_regs *regs = priv->regs;
static const unsigned offsets[4] = {
-   ZYNQ_QSPI_TXD_00_00_OFFSET, ZYNQ_QSPI_TXD_00_01_OFFSET,
-   ZYNQ_QSPI_TXD_00_10_OFFSET, ZYNQ_QSPI_TXD_00_11_OFFSET };
+   ZYNQ_QSPI_TXD_00_01_OFFSET, ZYNQ_QSPI_TXD_00_10_OFFSET,
+   ZYNQ_QSPI_TXD_00_11_OFFSET, ZYNQ_QSPI_TXD_00_00_OFFSET };
 
while ((fifocount < size) &&
(priv->bytes_to_transfer > 0)) {
@@ -386,7 +410,11 @@ static void zynq_qspi_fill_tx_fifo(struct zynq_qspi_priv 
*priv, u32 size)
return;
len = priv->bytes_to_transfer;
zynq_qspi_write_dat

[PATCH v7 4/6] spi: spi-uclass: Read chipselect and restrict capabilities

2023-12-18 Thread Venkatesh Yadav Abbarapu
From: Ashok Reddy Soma 

Read chipselect properties from DT which are populated using 'reg'
property and save it in plat->cs[] array for later use.

Also read multi chipselect capability which is used for
parallel-memories and return errors if they are passed on using DT but
driver is not capable of handling it.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/sandbox.c|  2 +-
 drivers/spi/altera_spi.c |  4 ++--
 drivers/spi/atcspi200_spi.c  |  2 +-
 drivers/spi/ath79_spi.c  |  2 +-
 drivers/spi/atmel_spi.c  |  6 +++---
 drivers/spi/bcm63xx_hsspi.c  | 42 ++--
 drivers/spi/bcm63xx_spi.c|  6 +++---
 drivers/spi/bcmbca_hsspi.c   | 34 ++---
 drivers/spi/cf_spi.c |  6 +++---
 drivers/spi/davinci_spi.c|  8 +++
 drivers/spi/fsl_dspi.c   | 18 
 drivers/spi/fsl_espi.c   |  4 ++--
 drivers/spi/fsl_qspi.c   |  4 ++--
 drivers/spi/gxp_spi.c|  2 +-
 drivers/spi/mpc8xx_spi.c |  4 ++--
 drivers/spi/mpc8xxx_spi.c| 10 -
 drivers/spi/mscc_bb_spi.c|  4 ++--
 drivers/spi/mxc_spi.c|  6 +++---
 drivers/spi/npcm_fiu_spi.c   | 14 ++--
 drivers/spi/nxp_fspi.c   |  2 +-
 drivers/spi/octeon_spi.c |  2 +-
 drivers/spi/omap3_spi.c  |  4 ++--
 drivers/spi/pic32_spi.c  |  2 +-
 drivers/spi/rk_spi.c |  4 ++--
 drivers/spi/rockchip_sfc.c   |  2 +-
 drivers/spi/spi-aspeed-smc.c | 28 
 drivers/spi/spi-mxic.c   |  6 +++---
 drivers/spi/spi-qup.c|  4 ++--
 drivers/spi/spi-sifive.c |  6 +++---
 drivers/spi/spi-sn-f-ospi.c  |  2 +-
 drivers/spi/spi-sunxi.c  |  6 +++---
 drivers/spi/spi-synquacer.c  |  4 ++--
 drivers/spi/spi-uclass.c | 33 +++-
 drivers/spi/stm32_qspi.c |  2 +-
 drivers/spi/stm32_spi.c  |  4 ++--
 drivers/spi/ti_qspi.c| 14 ++--
 drivers/spi/xilinx_spi.c |  4 ++--
 drivers/spi/zynq_qspi.c  |  6 +++---
 drivers/spi/zynq_spi.c   |  6 +++---
 include/spi.h|  8 ++-
 lib/acpi/acpi_device.c   |  2 +-
 41 files changed, 179 insertions(+), 150 deletions(-)

diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c
index 4fe547171a..72036d5a88 100644
--- a/drivers/mtd/spi/sandbox.c
+++ b/drivers/mtd/spi/sandbox.c
@@ -139,7 +139,7 @@ static int sandbox_sf_probe(struct udevice *dev)
return ret;
}
slave_plat = dev_get_parent_plat(dev);
-   cs = slave_plat->cs;
+   cs = slave_plat->cs[0];
debug("found at cs %d\n", cs);
 
if (!pdata->filename) {
diff --git a/drivers/spi/altera_spi.c b/drivers/spi/altera_spi.c
index 989679e881..48782f81c1 100644
--- a/drivers/spi/altera_spi.c
+++ b/drivers/spi/altera_spi.c
@@ -96,7 +96,7 @@ static int altera_spi_xfer(struct udevice *dev, unsigned int 
bitlen,
uint32_t reg, data, start;
 
debug("%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", __func__,
- dev_seq(bus), slave_plat->cs, bitlen, bytes, flags);
+ dev_seq(bus), slave_plat->cs[0], bitlen, bytes, flags);
 
if (bitlen == 0)
goto done;
@@ -111,7 +111,7 @@ static int altera_spi_xfer(struct udevice *dev, unsigned 
int bitlen,
readl(®s->rxdata);
 
if (flags & SPI_XFER_BEGIN)
-   spi_cs_activate(dev, slave_plat->cs);
+   spi_cs_activate(dev, slave_plat->cs[0]);
 
while (bytes--) {
if (txp)
diff --git a/drivers/spi/atcspi200_spi.c b/drivers/spi/atcspi200_spi.c
index de9c14837c..acee743653 100644
--- a/drivers/spi/atcspi200_spi.c
+++ b/drivers/spi/atcspi200_spi.c
@@ -321,7 +321,7 @@ static int atcspi200_spi_claim_bus(struct udevice *dev)
struct udevice *bus = dev->parent;
struct nds_spi_slave *ns = dev_get_priv(bus);
 
-   if (slave_plat->cs >= ns->num_cs) {
+   if (slave_plat->cs[0] >= ns->num_cs) {
printf("Invalid SPI chipselect\n");
return -EINVAL;
}
diff --git a/drivers/spi/ath79_spi.c b/drivers/spi/ath79_spi.c
index 205567ef54..ad10cec2a6 100644
--- a/drivers/spi/ath79_spi.c
+++ b/drivers/spi/ath79_spi.c
@@ -74,7 +74,7 @@ static int ath79_spi_xfer(struct udevice *dev, unsigned int 
bitlen,
if (restbits)
bytes++;
 
-   out = AR71XX_SPI_IOC_CS_ALL & ~(AR71XX_SPI_IOC_CS(slave->cs));
+   out = AR71XX_SPI_IOC_CS_ALL & ~(AR71XX_SPI_IOC_CS(slave->cs[0]));
while (bytes > 0) {
bytes--;
curbyte = 0;
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index aec6f4eca9..e2de39d1ef 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -126,7 +126,7 @@ static int atmel_spi_claim_bus(struct udevice *dev)
struct atmel_spi_priv *priv = dev_get_priv(bus);
struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
struct at91_

[PATCH v7 5/6] spi: zynqmp_gqspi: Add parallel memories support in GQSPI driver

2023-12-18 Thread Venkatesh Yadav Abbarapu
Add support for parallel memories in zynqmp_gqspi.c driver. In case of
parallel memories STRIPE bit is set and sent to the qspi ip, which will
send data bits to both the flashes in parallel. However for few commands
we should not use stripe, instead send same data to both the flashes.
Those commands are exclueded by using zynqmp_qspi_update_stripe().

Also update copyright info for this file.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/spi/zynqmp_gqspi.c | 141 -
 include/spi.h  |   4 ++
 2 files changed, 129 insertions(+), 16 deletions(-)

diff --git a/drivers/spi/zynqmp_gqspi.c b/drivers/spi/zynqmp_gqspi.c
index a323994fb2..dedf8270a8 100644
--- a/drivers/spi/zynqmp_gqspi.c
+++ b/drivers/spi/zynqmp_gqspi.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * (C) Copyright 2018 Xilinx
- *
+ * (C) Copyright 2013 - 2022, Xilinx, Inc.
+ * (C) Copyright 2023, Advanced Micro Devices, Inc.
  * Xilinx ZynqMP Generic Quad-SPI(QSPI) controller driver(master mode only)
  */
 
@@ -25,6 +25,8 @@
 #include 
 #include 
 #include 
+#include 
+#include "../mtd/spi/sf_internal.h"
 #include 
 
 #define GQSPI_GFIFO_STRT_MODE_MASK BIT(29)
@@ -88,6 +90,9 @@
 #define SPI_XFER_ON_LOWER  1
 #define SPI_XFER_ON_UPPER  2
 
+#define GQSPI_SELECT_LOWER_CS  BIT(0)
+#define GQSPI_SELECT_UPPER_CS  BIT(1)
+
 #define GQSPI_DMA_ALIGN0x4
 #define GQSPI_MAX_BAUD_RATE_VAL7
 #define GQSPI_DFLT_BAUD_RATE_VAL   2
@@ -183,13 +188,14 @@ struct zynqmp_qspi_priv {
int bytes_to_transfer;
int bytes_to_receive;
const struct spi_mem_op *op;
+   unsigned int is_parallel;
+   unsigned int u_page;
+   unsigned int bus;
+   unsigned int stripe;
+   unsigned int flags;
+   u32 max_hz;
 };
 
-__weak int zynqmp_mmio_write(const u32 address, const u32 mask, const u32 
value)
-{
-   return 0;
-}
-
 static int zynqmp_qspi_of_to_plat(struct udevice *bus)
 {
struct zynqmp_qspi_plat *plat = dev_get_plat(bus);
@@ -234,8 +240,30 @@ static u32 zynqmp_qspi_bus_select(struct zynqmp_qspi_priv 
*priv)
 {
u32 gqspi_fifo_reg = 0;
 
-   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
-GQSPI_GFIFO_CS_LOWER;
+   if (priv->is_parallel) {
+   if (priv->bus == SPI_XFER_ON_BOTH)
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
+GQSPI_GFIFO_UP_BUS |
+GQSPI_GFIFO_CS_UPPER |
+GQSPI_GFIFO_CS_LOWER;
+   else if (priv->bus == SPI_XFER_ON_LOWER)
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
+GQSPI_GFIFO_CS_UPPER |
+GQSPI_GFIFO_CS_LOWER;
+   else if (priv->bus == SPI_XFER_ON_UPPER)
+   gqspi_fifo_reg = GQSPI_GFIFO_UP_BUS |
+GQSPI_GFIFO_CS_LOWER |
+GQSPI_GFIFO_CS_UPPER;
+   else
+   debug("Wrong Bus selection:0x%x\n", priv->bus);
+   } else {
+   if (priv->u_page)
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
+GQSPI_GFIFO_CS_UPPER;
+   else
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
+GQSPI_GFIFO_CS_LOWER;
+   }
 
return gqspi_fifo_reg;
 }
@@ -295,8 +323,15 @@ static void zynqmp_qspi_chipselect(struct zynqmp_qspi_priv 
*priv, int is_on)
gqspi_fifo_reg |= GQSPI_SPI_MODE_SPI |
  GQSPI_IMD_DATA_CS_ASSERT;
} else {
-   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS;
-   gqspi_fifo_reg |= GQSPI_IMD_DATA_CS_DEASSERT;
+   if (priv->is_parallel) {
+   gqspi_fifo_reg = GQSPI_GFIFO_UP_BUS |
+GQSPI_GFIFO_LOW_BUS;
+   } else if (priv->u_page) {
+   gqspi_fifo_reg = GQSPI_GFIFO_UP_BUS;
+   } else {
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS;
+   gqspi_fifo_reg |= GQSPI_IMD_DATA_CS_DEASSERT;
+   }
}
 
zynqmp_qspi_fill_gen_fifo(priv, gqspi_fifo_reg);
@@ -366,12 +401,13 @@ static int zynqmp_qspi_set_speed(struct udevice *bus, 
uint speed)
 
log_debug("%s, Speed: %d, Max: %d\n", __func__, speed, plat->frequency);
 
-   if (speed > plat->frequency)
-   speed = plat->frequency;
+   /*
+* If speed == 0 or speed > max freq, then set speed to highest
+*/
+   if (!speed || speed > priv->max_hz)
+   speed = priv->max_hz;
 
if (plat->speed_hz != speed) {
-   /* Set the c

[PATCH v7 3/6] mtd: spi-nor: Add parallel and stacked memories support in read_bar and write_bar

2023-12-18 Thread Venkatesh Yadav Abbarapu
From: Ashok Reddy Soma 

Add support for parallel memories and stacked memories configuration
in read_bar and write_bar functions.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/spi-nor-core.c | 55 +-
 1 file changed, 47 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 3112f93af0..410f7320a8 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -885,12 +885,32 @@ static int clean_bar(struct spi_nor *nor)
 
 static int write_bar(struct spi_nor *nor, u32 offset)
 {
-   u8 cmd, bank_sel;
+   u8 cmd, bank_sel, upage_curr;
int ret;
+   struct mtd_info *mtd = &nor->mtd;
+
+   /* Wait until previous write command is finished */
+   if (spi_nor_wait_till_ready(nor))
+   return 1;
+
+   if (nor->flags & (SNOR_F_HAS_PARALLEL | SNOR_F_HAS_STACKED) &&
+   mtd->size <= SZ_32M)
+   return 0;
+
+   if (mtd->size <= SZ_16M)
+   return 0;
+
+   offset = offset % (u32)mtd->size;
+   bank_sel = offset >> 24;
 
-   bank_sel = offset / SZ_16M;
-   if (bank_sel == nor->bank_curr)
-   goto bar_end;
+   upage_curr = nor->spi->flags & SPI_XFER_U_PAGE;
+
+   if (!(nor->flags & SNOR_F_HAS_STACKED) && bank_sel == nor->bank_curr)
+   return 0;
+   else if (upage_curr == nor->upage_prev && bank_sel == nor->bank_curr)
+   return 0;
+
+   nor->upage_prev = upage_curr;
 
cmd = nor->bank_write_cmd;
write_enable(nor);
@@ -900,15 +920,19 @@ static int write_bar(struct spi_nor *nor, u32 offset)
return ret;
}
 
-bar_end:
nor->bank_curr = bank_sel;
-   return nor->bank_curr;
+
+   return write_disable(nor);
 }
 
 static int read_bar(struct spi_nor *nor, const struct flash_info *info)
 {
u8 curr_bank = 0;
int ret;
+   struct mtd_info *mtd = &nor->mtd;
+
+   if (mtd->size <= SZ_16M)
+   return 0;
 
switch (JEDEC_MFR(info)) {
case SNOR_MFR_SPANSION:
@@ -920,15 +944,30 @@ static int read_bar(struct spi_nor *nor, const struct 
flash_info *info)
nor->bank_write_cmd = SPINOR_OP_WREAR;
}
 
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   nor->spi->flags |= SPI_XFER_LOWER;
+
ret = nor->read_reg(nor, nor->bank_read_cmd,
-   &curr_bank, 1);
+   &curr_bank, 1);
if (ret) {
debug("SF: fail to read bank addr register\n");
return ret;
}
nor->bank_curr = curr_bank;
 
-   return 0;
+   // Make sure both chips use the same BAR
+   if (nor->flags & SNOR_F_HAS_PARALLEL) {
+   write_enable(nor);
+   ret = nor->write_reg(nor, nor->bank_write_cmd, &curr_bank, 1);
+   if (ret)
+   return ret;
+
+   ret = write_disable(nor);
+   if (ret)
+   return ret;
+   }
+
+   return ret;
 }
 #endif
 
-- 
2.25.1



[PATCH v7 2/6] mtd: spi-nor: Add parallel memories support for read_sr and read_fsr

2023-12-18 Thread Venkatesh Yadav Abbarapu
From: Ashok Reddy Soma 

Add support for parallel memories flash configuration in read status
register and read flag status register functions.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/spi-nor-core.c | 50 --
 1 file changed, 36 insertions(+), 14 deletions(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 08319a881d..3112f93af0 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -438,8 +438,9 @@ static ssize_t spi_nor_write_data(struct spi_nor *nor, 
loff_t to, size_t len,
 }
 
 /*
- * Read the status register, returning its value in the location
- * Return the status register value.
+ * Return the status register value. If the chip is parallel, then the
+ * read will be striped, so we should read 2 bytes to get the sr
+ * register value from both of the parallel chips.
  * Returns negative if error occurred.
  */
 static int read_sr(struct spi_nor *nor)
@@ -471,18 +472,29 @@ static int read_sr(struct spi_nor *nor)
if (spi_nor_protocol_is_dtr(nor->reg_proto))
op.data.nbytes = 2;
 
-   ret = spi_nor_read_write_reg(nor, &op, val);
-   if (ret < 0) {
-   pr_debug("error %d reading SR\n", (int)ret);
-   return ret;
+   if (nor->flags & SNOR_F_HAS_PARALLEL) {
+   op.data.nbytes = 2;
+   ret = spi_nor_read_write_reg(nor, &op, &val[0]);
+   if (ret < 0) {
+   pr_debug("error %d reading SR\n", (int)ret);
+   return ret;
+   }
+   val[0] |= val[1];
+   } else {
+   ret = spi_nor_read_write_reg(nor, &op, &val[0]);
+   if (ret < 0) {
+   pr_debug("error %d reading SR\n", (int)ret);
+   return ret;
+   }
}
 
-   return *val;
+   return val[0];
 }
 
 /*
- * Read the flag status register, returning its value in the location
- * Return the status register value.
+ * Return the flag status register value. If the chip is parallel, then
+ * the read will be striped, so we should read 2 bytes to get the fsr
+ * register value from both of the parallel chips.
  * Returns negative if error occurred.
  */
 static int read_fsr(struct spi_nor *nor)
@@ -514,13 +526,23 @@ static int read_fsr(struct spi_nor *nor)
if (spi_nor_protocol_is_dtr(nor->reg_proto))
op.data.nbytes = 2;
 
-   ret = spi_nor_read_write_reg(nor, &op, val);
-   if (ret < 0) {
-   pr_debug("error %d reading FSR\n", ret);
-   return ret;
+   if (nor->flags & SNOR_F_HAS_PARALLEL) {
+   op.data.nbytes = 2;
+   ret = spi_nor_read_write_reg(nor, &op, &val[0]);
+   if (ret < 0) {
+   pr_debug("error %d reading SR\n", (int)ret);
+   return ret;
+   }
+   val[0] &= val[1];
+   } else {
+   ret = spi_nor_read_write_reg(nor, &op, &val[0]);
+   if (ret < 0) {
+   pr_debug("error %d reading FSR\n", ret);
+   return ret;
+   }
}
 
-   return *val;
+   return val[0];
 }
 
 /*
-- 
2.25.1



[PATCH v7 1/6] mtd: spi-nor: Add parallel and stacked memories support

2023-12-18 Thread Venkatesh Yadav Abbarapu
From: Ashok Reddy Soma 

In parallel mode, the current implementation assumes that a maximum of
two flashes are connected. The QSPI controller splits the data evenly
between both the flashes so, both the flashes that are connected in
parallel mode should be identical.
During each operation SPI-NOR sets 0th bit for CS0 & 1st bit for CS1 in
nor->flags.

In stacked mode the current implementation assumes that a maximum of two
flashes are connected and both the flashes are of same make but can
differ in sizes. So, except the sizes all other flash parameters of both
the flashes are identical

Spi-nor will pass on the appropriate flash select flag to low level
driver, and it will select pass all the data to that particular flash.

Write operation in parallel mode are performed in page size * 2 chunks as
each write operation results in writing both the flashes. For doubling
the address space each operation is performed at addr/2 flash offset,
where addr is the address specified by the user.

Similarly for read and erase operations it will read from both flashes,
so size and offset are divided by 2 and send to flash.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/spi-nor-core.c | 293 +
 include/linux/mtd/spi-nor.h|  12 ++
 include/spi.h  |  11 ++
 3 files changed, 288 insertions(+), 28 deletions(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 9a1801ba93..08319a881d 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -639,12 +639,17 @@ static u8 spi_nor_convert_3to4_erase(u8 opcode)
 static void spi_nor_set_4byte_opcodes(struct spi_nor *nor,
  const struct flash_info *info)
 {
+   bool shift = 0;
+
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   shift = 1;
+
/* Do some manufacturer fixups first */
switch (JEDEC_MFR(info)) {
case SNOR_MFR_SPANSION:
/* No small sector erase for 4-byte command set */
nor->erase_opcode = SPINOR_OP_SE;
-   nor->mtd.erasesize = info->sector_size;
+   nor->mtd.erasesize = info->sector_size << shift;
break;
 
default:
@@ -965,8 +970,8 @@ static int spi_nor_erase_sector(struct spi_nor *nor, u32 
addr)
 static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
struct spi_nor *nor = mtd_to_spi_nor(mtd);
+   u32 addr, len, rem, offset;
bool addr_known = false;
-   u32 addr, len, rem;
int ret, err;
 
dev_dbg(nor->dev, "at 0x%llx, len %lld\n", (long long)instr->addr,
@@ -991,6 +996,19 @@ static int spi_nor_erase(struct mtd_info *mtd, struct 
erase_info *instr)
ret = -EINTR;
goto erase_err;
}
+
+   offset = addr;
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   offset /= 2;
+
+   if (nor->flags & SNOR_F_HAS_STACKED) {
+   if (offset >= (mtd->size / 2)) {
+   offset = offset - (mtd->size / 2);
+   nor->spi->flags |= SPI_XFER_U_PAGE;
+   } else {
+   nor->spi->flags &= ~SPI_XFER_U_PAGE;
+   }
+   }
 #ifdef CONFIG_SPI_FLASH_BAR
ret = write_bar(nor, addr);
if (ret < 0)
@@ -1396,6 +1414,9 @@ static const struct flash_info *spi_nor_read_id(struct 
spi_nor *nor)
u8  id[SPI_NOR_MAX_ID_LEN];
const struct flash_info *info;
 
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   nor->spi->flags |= SPI_XFER_LOWER;
+
tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN);
if (tmp < 0) {
dev_dbg(nor->dev, "error %d reading JEDEC ID\n", tmp);
@@ -1420,28 +1441,66 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t 
from, size_t len,
 {
struct spi_nor *nor = mtd_to_spi_nor(mtd);
int ret;
+   u32 offset = from;
+   u32 stack_shift = 0;
+   u32 read_len = 0;
+   u32 rem_bank_len = 0;
+   u8 bank;
+   u8 is_ofst_odd = 0;
 
dev_dbg(nor->dev, "from 0x%08x, len %zd\n", (u32)from, len);
 
+   if ((nor->flags & SNOR_F_HAS_PARALLEL) && (offset & 1)) {
+   /* We can hit this case when we use file system like ubifs */
+   from = (loff_t)(from - 1);
+   len = (size_t)(len + 1);
+   is_ofst_odd = 1;
+   }
+
while (len) {
-   loff_t addr = from;
-   size_t read_len = len;
+   if (nor->addr_width == 3) {
+   if (nor->flags & SNOR_F_HAS_PARALLEL) {
+   bank = (u32)from / (SZ_16M << 0x01);
+   rem_bank_len = ((SZ_16M << 0x01) *
+

[PATCH v7 0/6] spi-nor: Add parallel and stacked memories support

2023-12-18 Thread Venkatesh Yadav Abbarapu
This series adds support for Xilinx qspi parallel and stacked memeories.

In parallel mode, the current implementation assumes that a maximum of two 
flashes are connected. The QSPI controller splits the data evenly between both 
the flashes so, both the flashes that are connected in parallel mode should be 
identical.
During each operation SPI-NOR sets 0th bit for CS0 & 1st bit for CS1 in
nor->flags.

In stacked mode the current implementation assumes that a maximum of two 
flashes are connected and both the flashes are of same make but can differ in 
sizes. So, except the sizes all other flash parameters of both the flashes are 
identical.

Spi-nor will pass on the appropriate flash select flag to low level driver, and 
it will select pass all the data to that particular flash.

Write operation in parallel mode are performed in page size * 2 chunks as each 
write operation results in writing both the flashes. For doubling the address 
space each operation is performed at addr/2 flash offset, where addr is the 
address specified by the user.

Similarly for read and erase operations it will read from both flashes, so size 
and offset are divided by 2 and send to flash.

Changes in v2:
- Fixed the compilation issues.
Changes in v3:
- Fixed the CI issues.
Changes in v4:
- Removed the dio,dummy_bytes variables from zynq_qspi driver.
- Fix the compilation issue by including the DM_SPI config.
Changes in v5:
- Fixed the issue reported by buildman.
Changes in v6:
- Fixed the issues reported while running the sandbox test cases.
Changes in v7:
- Fixed the issues reported while running these da850evm_defconfig,
  imx28_xea_defconfig configs.
- Fixed the issue when DM_SPI config is disabled.
- Fixed the issue while running the sandbox_noinst_defconfig with spl
  ./spl/u-boot-spl -d arch/sandbox/dts/test.dtb
   jedec_spi_nor spi.bin@0: has no valid 'reg' property (-12)
   jedec_spi_nor spi.bin@1: has no valid 'reg' property (-12)
   ### ERROR ### Please RESET the board ###

Ashok Reddy Soma (4):
  mtd: spi-nor: Add parallel and stacked memories support
  mtd: spi-nor: Add parallel memories support for read_sr and read_fsr
  mtd: spi-nor: Add parallel and stacked memories support in read_bar
and write_bar
  spi: spi-uclass: Read chipselect and restrict capabilities

Venkatesh Yadav Abbarapu (2):
  spi: zynqmp_gqspi: Add parallel memories support in GQSPI driver
  spi: zynq_qspi: Add parallel memories support in QSPI driver

 drivers/mtd/spi/sandbox.c  |   2 +-
 drivers/mtd/spi/spi-nor-core.c | 398 -
 drivers/spi/altera_spi.c   |   4 +-
 drivers/spi/atcspi200_spi.c|   2 +-
 drivers/spi/ath79_spi.c|   2 +-
 drivers/spi/atmel_spi.c|   6 +-
 drivers/spi/bcm63xx_hsspi.c|  42 ++--
 drivers/spi/bcm63xx_spi.c  |   6 +-
 drivers/spi/bcmbca_hsspi.c |  34 +--
 drivers/spi/cf_spi.c   |   6 +-
 drivers/spi/davinci_spi.c  |   8 +-
 drivers/spi/fsl_dspi.c |  18 +-
 drivers/spi/fsl_espi.c |   4 +-
 drivers/spi/fsl_qspi.c |   4 +-
 drivers/spi/gxp_spi.c  |   2 +-
 drivers/spi/mpc8xx_spi.c   |   4 +-
 drivers/spi/mpc8xxx_spi.c  |  10 +-
 drivers/spi/mscc_bb_spi.c  |   4 +-
 drivers/spi/mxc_spi.c  |   6 +-
 drivers/spi/npcm_fiu_spi.c |  14 +-
 drivers/spi/nxp_fspi.c |   2 +-
 drivers/spi/octeon_spi.c   |   2 +-
 drivers/spi/omap3_spi.c|   4 +-
 drivers/spi/pic32_spi.c|   2 +-
 drivers/spi/rk_spi.c   |   4 +-
 drivers/spi/rockchip_sfc.c |   2 +-
 drivers/spi/spi-aspeed-smc.c   |  28 +--
 drivers/spi/spi-mxic.c |   6 +-
 drivers/spi/spi-qup.c  |   4 +-
 drivers/spi/spi-sifive.c   |   6 +-
 drivers/spi/spi-sn-f-ospi.c|   2 +-
 drivers/spi/spi-sunxi.c|   6 +-
 drivers/spi/spi-synquacer.c|   4 +-
 drivers/spi/spi-uclass.c   |  33 ++-
 drivers/spi/stm32_qspi.c   |   2 +-
 drivers/spi/stm32_spi.c|   4 +-
 drivers/spi/ti_qspi.c  |  14 +-
 drivers/spi/xilinx_spi.c   |   4 +-
 drivers/spi/zynq_qspi.c| 119 --
 drivers/spi/zynq_spi.c |   6 +-
 drivers/spi/zynqmp_gqspi.c | 141 ++--
 include/linux/mtd/spi-nor.h|  12 +
 include/spi.h  |  23 +-
 lib/acpi/acpi_device.c |   2 +-
 44 files changed, 781 insertions(+), 227 deletions(-)

-- 
2.25.1



Re: Proposal: U-Boot memory management

2023-12-18 Thread Heinrich Schuchardt



Am 19. Dezember 2023 02:26:00 MEZ schrieb Tom Rini :
>On Tue, Dec 19, 2023 at 01:01:51AM +0100, Heinrich Schuchardt wrote:
>> 
>> 
>> Am 19. Dezember 2023 00:31:30 MEZ schrieb Tom Rini :
>> >On Tue, Dec 19, 2023 at 12:29:19AM +0100, Heinrich Schuchardt wrote:
>> >> 
>> >> 
>> >> Am 19. Dezember 2023 00:16:40 MEZ schrieb Tom Rini :
>> >> >On Tue, Dec 19, 2023 at 12:08:31AM +0100, Heinrich Schuchardt wrote:
>> >> >> 
>> >> >> 
>> >> >> Am 18. Dezember 2023 23:41:08 MEZ schrieb Tom Rini 
>> >> >> :
>> >> >> >On Mon, Dec 18, 2023 at 11:34:16PM +0100, Heinrich Schuchardt wrote:
>> >> >> >
>> >> >> >[snip]
>> >> >> >> Or take:
>> >> >> >> 
>> >> >> >> load host 0:1 $c kernel.efi
>> >> >> >> load host 0:1 $d initrd.img
>> >> >> >> 
>> >> >> >> How could we ensure that initrd.img is not overwriting a part of 
>> >> >> >> kernel.efi without memory allocation?
>> >> >> >
>> >> >> >Today, invalid checksum as part of some part of the kernel fails. But
>> >> >> >how do we do this tomorrow, are you suggesting that "load" perform
>> >> >> >malloc() in some predefined size? If $c is below $d and $c + 
>> >> >> >kernel.efi
>> >> >> >is now above $d we can throw an error before trying to load, yes. But
>> >> >> >what about:
>> >> >> >load host 0:1 $d initrd.img
>> >> >> >load host 0:1 $c kernel.efi
>> >> >> >
>> >> >> >In that case (which is only marginally contrived, the more real case 
>> >> >> >is
>> >> >> >loading device tree in to unexpectedly large ramdisk because someone
>> >> >> >didn't understand the general advice on why device tree is lower than
>> >> >> >ramdisk address) I'm fine with an error that amounts to "you just
>> >> >> >corrupted another allocation" and then "fail, reset the board" or so.
>> >> >> >
>> >> >> 
>> >> >> Our current malloc library cannot manage the complete memory. We need 
>> >> >> a library like lmb which should also cover the memory management that 
>> >> >> we currently have in lib/efi/efi_memory.c. This must include a memory 
>> >> >> type attribute for usage in the GetMemoryMap() service. A management 
>> >> >> on page level seems sufficient.
>> >> >> 
>> >> >> The load command should permanently allocate memory in that lmb+ 
>> >> >> library.
>> >> >> 
>> >> >> We need an unload command to free the memory if we want to reuse the 
>> >> >> memory or we might let the load comand free the memory if exactly the 
>> >> >> same start address is reused.
>> >> >
>> >> >Our current way of loading things in to memory does not handle the case
>> >> >I described, yes. How would what you're proposing handle it?
>> >> 
>> >> If the load command has to allocate memory for the image and that 
>> >> allocation is kept, any attempt to allocate overlapping memory would fail.
>> >
>> >So you're saying that the load command has to pre-allocate memory? Or as
>> >it goes? If the latter, in what size chunks? This starts to get at what
>> >Simon was talking about with respect to memory fragmentation. Which to
>> >be clear is a problem we have today, we just let things overlap and hope
>> >something later catches an incorrect checksum.
>> >
>> 
>> I don't want to replace the malloc library which handles large numbets of 
>> allocations.
>
>I'm confused. The normal malloc library is not involved with current
>image loading, it's direct to memory (with some attempts at sanity
>checking by lmb).  Are you proposing a different allocator with
>malloc/free like behavior? If so, please outline how it will determine
>pool size, and how we'll use it to load thing to memory.

All memory below the stack needs to be managed. Malloc uses a small memory area 
(a few MiB) above the stack.

>
>> Closing the eyes when the user loads multiple files does not solve the 
>> fragmentation problem.
>
>Yes. I'm only noting that today we just ignore the problem and sometimes
>catch it via checksums.
>
>> Fragmentation only happens if we have many concurrent allocations.  In EFI 
>> we are allocating top down. The number of concurrent allocations is low. 
>> Typically a few dozen at most. After terminating an application these should 
>> be freed again.
>
>OK, so are you saying that we would no longer be loading _to_ a location
>in memory and instead just be saying "load this thing" and picking where
>dynamically?

Both preassigned and allocator assigned adresses are compatible with memory 
management.

Architectures and binaries have different requirements. On riscv64 you can load 
Linux kernel, initrd, fdt anywhere. We don't need predefined addresses there. 
Other architectures have restrictions.

>
>> When loading a file from a file system we know the filesize beforehand. So 
>> allocation is trivial.
>> 
>> The loady command currently does not use the  offered size information but 
>> could do so.
>
>We should be using that information to make sure we don't overwrite
>U-Boot itself, but I don't recall how exactly we handle it today
>off-hand.

If the user issues multiple load commands, he can overwrite previous files.

During 

Re: Proposal: U-Boot memory management

2023-12-18 Thread Tom Rini
On Tue, Dec 19, 2023 at 01:01:51AM +0100, Heinrich Schuchardt wrote:
> 
> 
> Am 19. Dezember 2023 00:31:30 MEZ schrieb Tom Rini :
> >On Tue, Dec 19, 2023 at 12:29:19AM +0100, Heinrich Schuchardt wrote:
> >> 
> >> 
> >> Am 19. Dezember 2023 00:16:40 MEZ schrieb Tom Rini :
> >> >On Tue, Dec 19, 2023 at 12:08:31AM +0100, Heinrich Schuchardt wrote:
> >> >> 
> >> >> 
> >> >> Am 18. Dezember 2023 23:41:08 MEZ schrieb Tom Rini :
> >> >> >On Mon, Dec 18, 2023 at 11:34:16PM +0100, Heinrich Schuchardt wrote:
> >> >> >
> >> >> >[snip]
> >> >> >> Or take:
> >> >> >> 
> >> >> >> load host 0:1 $c kernel.efi
> >> >> >> load host 0:1 $d initrd.img
> >> >> >> 
> >> >> >> How could we ensure that initrd.img is not overwriting a part of 
> >> >> >> kernel.efi without memory allocation?
> >> >> >
> >> >> >Today, invalid checksum as part of some part of the kernel fails. But
> >> >> >how do we do this tomorrow, are you suggesting that "load" perform
> >> >> >malloc() in some predefined size? If $c is below $d and $c + kernel.efi
> >> >> >is now above $d we can throw an error before trying to load, yes. But
> >> >> >what about:
> >> >> >load host 0:1 $d initrd.img
> >> >> >load host 0:1 $c kernel.efi
> >> >> >
> >> >> >In that case (which is only marginally contrived, the more real case is
> >> >> >loading device tree in to unexpectedly large ramdisk because someone
> >> >> >didn't understand the general advice on why device tree is lower than
> >> >> >ramdisk address) I'm fine with an error that amounts to "you just
> >> >> >corrupted another allocation" and then "fail, reset the board" or so.
> >> >> >
> >> >> 
> >> >> Our current malloc library cannot manage the complete memory. We need a 
> >> >> library like lmb which should also cover the memory management that we 
> >> >> currently have in lib/efi/efi_memory.c. This must include a memory type 
> >> >> attribute for usage in the GetMemoryMap() service. A management on page 
> >> >> level seems sufficient.
> >> >> 
> >> >> The load command should permanently allocate memory in that lmb+ 
> >> >> library.
> >> >> 
> >> >> We need an unload command to free the memory if we want to reuse the 
> >> >> memory or we might let the load comand free the memory if exactly the 
> >> >> same start address is reused.
> >> >
> >> >Our current way of loading things in to memory does not handle the case
> >> >I described, yes. How would what you're proposing handle it?
> >> 
> >> If the load command has to allocate memory for the image and that 
> >> allocation is kept, any attempt to allocate overlapping memory would fail.
> >
> >So you're saying that the load command has to pre-allocate memory? Or as
> >it goes? If the latter, in what size chunks? This starts to get at what
> >Simon was talking about with respect to memory fragmentation. Which to
> >be clear is a problem we have today, we just let things overlap and hope
> >something later catches an incorrect checksum.
> >
> 
> I don't want to replace the malloc library which handles large numbets of 
> allocations.

I'm confused. The normal malloc library is not involved with current
image loading, it's direct to memory (with some attempts at sanity
checking by lmb).  Are you proposing a different allocator with
malloc/free like behavior? If so, please outline how it will determine
pool size, and how we'll use it to load thing to memory.

> Closing the eyes when the user loads multiple files does not solve the 
> fragmentation problem.

Yes. I'm only noting that today we just ignore the problem and sometimes
catch it via checksums.

> Fragmentation only happens if we have many concurrent allocations.  In EFI we 
> are allocating top down. The number of concurrent allocations is low. 
> Typically a few dozen at most. After terminating an application these should 
> be freed again.

OK, so are you saying that we would no longer be loading _to_ a location
in memory and instead just be saying "load this thing" and picking where
dynamically?

> When loading a file from a file system we know the filesize beforehand. So 
> allocation is trivial.
> 
> The loady command currently does not use the  offered size information but 
> could do so.

We should be using that information to make sure we don't overwrite
U-Boot itself, but I don't recall how exactly we handle it today
off-hand.

> TFTP is problematic because it does not transfer the filesize. We would 
> probably try to allocate a large chunk of memory and then downsize the 
> allocation after reading the whole file.

Reading from non-filesystem flash also has this problem, but we at least
specify the amount to read too. But yes, it gets back to what I was
asking about on how you're proposing to handle network load cases.

-- 
Tom


signature.asc
Description: PGP signature


Re:[PATCH v2 13/17] video: rockchip: Add rk3328 vop support

2023-12-18 Thread Andy Yan

Hi Jaqan:

At 2023-12-19 03:11:10, "Jagan Teki"  wrote:
>From: Jagan Teki 
>
>Add support for Rockchip RK3328 VOP.
>
>Require VOP cleanup before handoff to Linux by writing reset values to
>WIN registers. Without this Linux VOP trigger page fault as below
>[0.752016] Loading compiled-in X.509 certificates
>[0.787796] inno_hdmi_phy_rk3328_clk_recalc_rate: parent 2400
>[0.788391] inno-hdmi-phy ff43.phy: 
>inno_hdmi_phy_rk3328_clk_recalc_rate rate 14850 vco 14850
>[0.798353] rockchip-drm display-subsystem: bound ff37.vop (ops 
>vop_component_ops)
>[0.799403] dwhdmi-rockchip ff3c.hdmi: supply avdd-0v9 not found, using 
>dummy regulator
>[0.800288] rk_iommu ff373f00.iommu: Enable stall request timed out, 
>status: 0x4b
>[0.801131] dwhdmi-rockchip ff3c.hdmi: supply avdd-1v8 not found, using 
>dummy regulator
>[0.802056] rk_iommu ff373f00.iommu: Disable paging request timed out, 
>status: 0x4b
>[0.803233] dwhdmi-rockchip ff3c.hdmi: Detected HDMI TX controller 
>v2.11a with HDCP (inno_dw_hdmi_phy2)
>[0.805355] dwhdmi-rockchip ff3c.hdmi: registered DesignWare HDMI I2C 
>bus driver
>[0.808769] rockchip-drm display-subsystem: bound ff3c.hdmi (ops 
>dw_hdmi_rockchip_ops)
>[0.810869] [drm] Initialized rockchip 1.0.0 20140818 for display-subsystem 
>on minor 0
>
>Signed-off-by: Jagan Teki 
>---
>Changes for v2:
>- Add VOP cleanup
>- Update commit
>
> drivers/video/rockchip/Makefile |  1 +
> drivers/video/rockchip/rk3328_vop.c | 83 +
> 2 files changed, 84 insertions(+)
> create mode 100644 drivers/video/rockchip/rk3328_vop.c
>
>diff --git a/drivers/video/rockchip/Makefile b/drivers/video/rockchip/Makefile
>index 4991303c73..f55beceebf 100644
>--- a/drivers/video/rockchip/Makefile
>+++ b/drivers/video/rockchip/Makefile
>@@ -6,6 +6,7 @@
> ifdef CONFIG_VIDEO_ROCKCHIP
> obj-y += rk_vop.o
> obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288_vop.o
>+obj-$(CONFIG_ROCKCHIP_RK3328) += rk3328_vop.o
> obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399_vop.o
> obj-$(CONFIG_DISPLAY_ROCKCHIP_EDP) += rk_edp.o
> obj-$(CONFIG_DISPLAY_ROCKCHIP_LVDS) += rk_lvds.o
>diff --git a/drivers/video/rockchip/rk3328_vop.c 
>b/drivers/video/rockchip/rk3328_vop.c
>new file mode 100644
>index 00..a4da3a91e8
>--- /dev/null
>+++ b/drivers/video/rockchip/rk3328_vop.c
>@@ -0,0 +1,83 @@
>+// SPDX-License-Identifier: GPL-2.0+
>+/*
>+ * Copyright (c) 2023 Edgeble AI Technologies Pvt. Ltd.
>+ */
>+
>+#include 
>+#include 
>+#include 
>+#include "rk_vop.h"
>+
>+DECLARE_GLOBAL_DATA_PTR;
>+
>+static void rk3328_set_pin_polarity(struct udevice *dev,
>+  enum vop_modes mode, u32 polarity)
>+{
>+  struct rk_vop_priv *priv = dev_get_priv(dev);
>+  struct rk3288_vop *regs = priv->regs;
>+
>+  switch (mode) {
>+  case VOP_MODE_HDMI:
>+  clrsetbits_le32(®s->dsp_ctrl1,
>+  M_RK3399_DSP_HDMI_POL,
>+  V_RK3399_DSP_HDMI_POL(polarity));
>+  break;
>+  default:
>+  debug("%s: unsupported output mode %x\n", __func__, mode);
>+  }
>+}
>+
>+static int rk3328_vop_probe(struct udevice *dev)
>+{
>+  /* Before relocation we don't need to do anything */
>+  if (!(gd->flags & GD_FLG_RELOC))
>+  return 0;
>+
>+  return rk_vop_probe(dev);
>+}
>+
>+static int rk3328_vop_remove(struct udevice *dev)
>+{
>+  struct rk_vop_priv *priv = dev_get_priv(dev);
>+  struct rk3288_vop *regs = priv->regs;
>+  struct rk3288_vop *win_regs = priv->regs + priv->win_offset;
>+
>+  /* write reset values */
>+  writel(0xef013f, &win_regs->win0_act_info);
>+  writel(0xef013f, &win_regs->win0_dsp_info);
>+  writel(0xa000a, &win_regs->win0_dsp_st);
>+  writel(0x0, &win_regs->win0_yrgb_mst);
>+  writel(0x01, ®s->reg_cfg_done);
>+
>+  return 0;
>+}

I think this just workaround Linux iommu page fault by luck。
The reset value(what you called it is)your write just let win0 read a
320x240 rectangular from address 0 and display it at next frame(maybe 16ms 
later if your
current display is run at 60HZ)。

1. we don't know what content is at address 0, so you will see something 
strange on your monitor.
2. there is no guarantee that address 0 is really readable(maybe a security 
memory space, or maybe
it is not a valid address), this may cause another issue that not easy to 
detect。

>+
>+struct rkvop_driverdata rk3328_driverdata = {
>+  .dsp_offset = 0x490,
>+  .win_offset = 0xd0,
>+  .features = VOP_FEATURE_OUTPUT_10BIT,
>+  .set_pin_polarity = rk3328_set_pin_polarity,
>+};
>+
>+static const struct udevice_id rk3328_vop_ids[] = {
>+  {
>+  .compatible = "rockchip,rk3328-vop",
>+  .data = (ulong)&rk3328_driverdata
>+  },
>+  { /* sentile */ }
>+};
>+
>+static const struct video_ops rk3328_vop_ops = {
>+};
>+
>+U_BOOT_DRIVER(rk3328_vop) = {
>+ 

Re: [PATCH v3 1/4] efi_loader: split unrelated code from efi_bootmgr.c

2023-12-18 Thread AKASHI Takahiro
On Mon, Dec 18, 2023 at 08:01:51AM -0700, Simon Glass wrote:
> Hi AKASHI,
> 
> On Sun, 17 Dec 2023 at 19:39, AKASHI Takahiro
>  wrote:
> >
> > Some code moved from cmd/bootefi.c is actually necessary only for "bootefi
> > " command (starting an image manually loaded by a user using U-Boot
> > load commands or other methods (like JTAG debugger).
> >
> > The code will never been opted out as unused code by a compiler which
> > doesn't know how EFI boot manager is implemented. So introduce a new
> > configuration, CONFIG_EFI_BINARY_EXEC, to enforce theem opted out
> > explicitly.
> >
> > Signed-off-by: AKASHI Takahiro 
> > ---
> >  boot/Kconfig |   4 +-
> >  cmd/Kconfig  |   6 +-
> >  include/efi_loader.h |  28 +-
> >  lib/efi_loader/Kconfig   |   9 +
> >  lib/efi_loader/efi_bootmgr.c | 493 --
> >  lib/efi_loader/efi_device_path.c |   3 +-
> >  lib/efi_loader/efi_helper.c  | 499 ++-
> >  7 files changed, 529 insertions(+), 513 deletions(-)
> 
> 'helper' seems a bit vague to me. How about efi_boot.c ?

Although I hesitated to add one more new file as we already have
efi_boottime.c and efi_bootmgr.c, then efi_boot.c?, okay I will do that.

-Takahiro Akashi


> REgards,
> Simon


Re: [PATCH] ARM: dts: imx: Power off display output on Data Modul i.MX8M Mini/Plus eDM SBC

2023-12-18 Thread Fabio Estevam
On Mon, Dec 18, 2023 at 3:02 PM Marek Vasut  wrote:
>
> Turn display connector power off on boot and reboot to prevent any
> bogus start up sequence of any panel potentially attached to the
> display connector.
>
> Signed-off-by: Marek Vasut 

Applied to u-boot-imx/master, thanks.


Re: [PATCH v3 3/4] net: tftp: remove explicit efi configuration dependency

2023-12-18 Thread AKASHI Takahiro
Hi Simon,

On Mon, Dec 18, 2023 at 08:01:46AM -0700, Simon Glass wrote:
> Hi AKASHI,
> 
> On Sun, 17 Dec 2023 at 19:39, AKASHI Takahiro
>  wrote:
> >
> > Now it is clear that the feature actually depends on efi interfaces,
> > not "bootefi" command. efi_set_bootdev() will automatically be nullified
> > if necessary efi component is disabled.
> >
> > Signed-off-by: AKASHI Takahiro 
> > ---
> >  net/tftp.c | 10 --
> >  1 file changed, 4 insertions(+), 6 deletions(-)
> >
> 
> I have the same comment here as the 'fs' patch.
> 
> > diff --git a/net/tftp.c b/net/tftp.c
> > index 88e71e67de35..2e335413492b 100644
> > --- a/net/tftp.c
> > +++ b/net/tftp.c
> > @@ -302,12 +302,10 @@ static void tftp_complete(void)
> > time_start * 1000, "/s");
> > }
> > puts("\ndone\n");
> > -   if (IS_ENABLED(CONFIG_CMD_BOOTEFI)) {
> 
> Shouldn't this depend on your new CONFIG? What happens if EFI_LOADER
> is not enabled?

The trick is in efi_loader.h.
If EFI_LOADER (more specifically CONFIG_EFI_BINARY_EXEC) is not defined,
this function gets voided.  See patch#1 in this version.

I took this approach in order not to make users much worried about
what config be used as they are not familiar with UEFI implementation.

-Takahiro Akashi

> > -   if (!tftp_put_active)
> > -   efi_set_bootdev("Net", "", tftp_filename,
> > -   map_sysmem(tftp_load_addr, 0),
> > -   net_boot_file_size);
> > -   }
> > +   if (!tftp_put_active)
> > +   efi_set_bootdev("Net", "", tftp_filename,
> > +   map_sysmem(tftp_load_addr, 0),
> > +   net_boot_file_size);
> > net_set_state(NETLOOP_SUCCESS);
> >  }
> >
> > --
> > 2.34.1
> >
> 
> Regards,
> Simon


Re: Proposal: U-Boot memory management

2023-12-18 Thread Heinrich Schuchardt



Am 19. Dezember 2023 00:31:30 MEZ schrieb Tom Rini :
>On Tue, Dec 19, 2023 at 12:29:19AM +0100, Heinrich Schuchardt wrote:
>> 
>> 
>> Am 19. Dezember 2023 00:16:40 MEZ schrieb Tom Rini :
>> >On Tue, Dec 19, 2023 at 12:08:31AM +0100, Heinrich Schuchardt wrote:
>> >> 
>> >> 
>> >> Am 18. Dezember 2023 23:41:08 MEZ schrieb Tom Rini :
>> >> >On Mon, Dec 18, 2023 at 11:34:16PM +0100, Heinrich Schuchardt wrote:
>> >> >
>> >> >[snip]
>> >> >> Or take:
>> >> >> 
>> >> >> load host 0:1 $c kernel.efi
>> >> >> load host 0:1 $d initrd.img
>> >> >> 
>> >> >> How could we ensure that initrd.img is not overwriting a part of 
>> >> >> kernel.efi without memory allocation?
>> >> >
>> >> >Today, invalid checksum as part of some part of the kernel fails. But
>> >> >how do we do this tomorrow, are you suggesting that "load" perform
>> >> >malloc() in some predefined size? If $c is below $d and $c + kernel.efi
>> >> >is now above $d we can throw an error before trying to load, yes. But
>> >> >what about:
>> >> >load host 0:1 $d initrd.img
>> >> >load host 0:1 $c kernel.efi
>> >> >
>> >> >In that case (which is only marginally contrived, the more real case is
>> >> >loading device tree in to unexpectedly large ramdisk because someone
>> >> >didn't understand the general advice on why device tree is lower than
>> >> >ramdisk address) I'm fine with an error that amounts to "you just
>> >> >corrupted another allocation" and then "fail, reset the board" or so.
>> >> >
>> >> 
>> >> Our current malloc library cannot manage the complete memory. We need a 
>> >> library like lmb which should also cover the memory management that we 
>> >> currently have in lib/efi/efi_memory.c. This must include a memory type 
>> >> attribute for usage in the GetMemoryMap() service. A management on page 
>> >> level seems sufficient.
>> >> 
>> >> The load command should permanently allocate memory in that lmb+ library.
>> >> 
>> >> We need an unload command to free the memory if we want to reuse the 
>> >> memory or we might let the load comand free the memory if exactly the 
>> >> same start address is reused.
>> >
>> >Our current way of loading things in to memory does not handle the case
>> >I described, yes. How would what you're proposing handle it?
>> 
>> If the load command has to allocate memory for the image and that allocation 
>> is kept, any attempt to allocate overlapping memory would fail.
>
>So you're saying that the load command has to pre-allocate memory? Or as
>it goes? If the latter, in what size chunks? This starts to get at what
>Simon was talking about with respect to memory fragmentation. Which to
>be clear is a problem we have today, we just let things overlap and hope
>something later catches an incorrect checksum.
>

I don't want to replace the malloc library which handles large numbets of 
allocations.

Closing the eyes when the user loads multiple files does not solve the 
fragmentation problem.

Fragmentation only happens if we have many concurrent allocations.  In EFI we 
are allocating top down. The number of concurrent allocations is low. Typically 
a few dozen at most. After terminating an application these should be freed 
again.

When loading a file from a file system we know the filesize beforehand. So 
allocation is trivial.

The loady command currently does not use the  offered size information but 
could do so.

TFTP is problematic because it does not transfer the filesize. We would 
probably try to allocate a large chunk of memory and then downsize the 
allocation after reading the whole file.

We will have to review each file load method individually.

Best regards

Heinrich


Re: Proposal: U-Boot memory management

2023-12-18 Thread Tom Rini
On Tue, Dec 19, 2023 at 12:29:19AM +0100, Heinrich Schuchardt wrote:
> 
> 
> Am 19. Dezember 2023 00:16:40 MEZ schrieb Tom Rini :
> >On Tue, Dec 19, 2023 at 12:08:31AM +0100, Heinrich Schuchardt wrote:
> >> 
> >> 
> >> Am 18. Dezember 2023 23:41:08 MEZ schrieb Tom Rini :
> >> >On Mon, Dec 18, 2023 at 11:34:16PM +0100, Heinrich Schuchardt wrote:
> >> >
> >> >[snip]
> >> >> Or take:
> >> >> 
> >> >> load host 0:1 $c kernel.efi
> >> >> load host 0:1 $d initrd.img
> >> >> 
> >> >> How could we ensure that initrd.img is not overwriting a part of 
> >> >> kernel.efi without memory allocation?
> >> >
> >> >Today, invalid checksum as part of some part of the kernel fails. But
> >> >how do we do this tomorrow, are you suggesting that "load" perform
> >> >malloc() in some predefined size? If $c is below $d and $c + kernel.efi
> >> >is now above $d we can throw an error before trying to load, yes. But
> >> >what about:
> >> >load host 0:1 $d initrd.img
> >> >load host 0:1 $c kernel.efi
> >> >
> >> >In that case (which is only marginally contrived, the more real case is
> >> >loading device tree in to unexpectedly large ramdisk because someone
> >> >didn't understand the general advice on why device tree is lower than
> >> >ramdisk address) I'm fine with an error that amounts to "you just
> >> >corrupted another allocation" and then "fail, reset the board" or so.
> >> >
> >> 
> >> Our current malloc library cannot manage the complete memory. We need a 
> >> library like lmb which should also cover the memory management that we 
> >> currently have in lib/efi/efi_memory.c. This must include a memory type 
> >> attribute for usage in the GetMemoryMap() service. A management on page 
> >> level seems sufficient.
> >> 
> >> The load command should permanently allocate memory in that lmb+ library.
> >> 
> >> We need an unload command to free the memory if we want to reuse the 
> >> memory or we might let the load comand free the memory if exactly the same 
> >> start address is reused.
> >
> >Our current way of loading things in to memory does not handle the case
> >I described, yes. How would what you're proposing handle it?
> 
> If the load command has to allocate memory for the image and that allocation 
> is kept, any attempt to allocate overlapping memory would fail.

So you're saying that the load command has to pre-allocate memory? Or as
it goes? If the latter, in what size chunks? This starts to get at what
Simon was talking about with respect to memory fragmentation. Which to
be clear is a problem we have today, we just let things overlap and hope
something later catches an incorrect checksum.

-- 
Tom


signature.asc
Description: PGP signature


Re: Proposal: U-Boot memory management

2023-12-18 Thread Heinrich Schuchardt



Am 19. Dezember 2023 00:16:40 MEZ schrieb Tom Rini :
>On Tue, Dec 19, 2023 at 12:08:31AM +0100, Heinrich Schuchardt wrote:
>> 
>> 
>> Am 18. Dezember 2023 23:41:08 MEZ schrieb Tom Rini :
>> >On Mon, Dec 18, 2023 at 11:34:16PM +0100, Heinrich Schuchardt wrote:
>> >
>> >[snip]
>> >> Or take:
>> >> 
>> >> load host 0:1 $c kernel.efi
>> >> load host 0:1 $d initrd.img
>> >> 
>> >> How could we ensure that initrd.img is not overwriting a part of 
>> >> kernel.efi without memory allocation?
>> >
>> >Today, invalid checksum as part of some part of the kernel fails. But
>> >how do we do this tomorrow, are you suggesting that "load" perform
>> >malloc() in some predefined size? If $c is below $d and $c + kernel.efi
>> >is now above $d we can throw an error before trying to load, yes. But
>> >what about:
>> >load host 0:1 $d initrd.img
>> >load host 0:1 $c kernel.efi
>> >
>> >In that case (which is only marginally contrived, the more real case is
>> >loading device tree in to unexpectedly large ramdisk because someone
>> >didn't understand the general advice on why device tree is lower than
>> >ramdisk address) I'm fine with an error that amounts to "you just
>> >corrupted another allocation" and then "fail, reset the board" or so.
>> >
>> 
>> Our current malloc library cannot manage the complete memory. We need a 
>> library like lmb which should also cover the memory management that we 
>> currently have in lib/efi/efi_memory.c. This must include a memory type 
>> attribute for usage in the GetMemoryMap() service. A management on page 
>> level seems sufficient.
>> 
>> The load command should permanently allocate memory in that lmb+ library.
>> 
>> We need an unload command to free the memory if we want to reuse the memory 
>> or we might let the load comand free the memory if exactly the same start 
>> address is reused.
>
>Our current way of loading things in to memory does not handle the case
>I described, yes. How would what you're proposing handle it?

If the load command has to allocate memory for the image and that allocation is 
kept, any attempt to allocate overlapping memory would fail.

Furthermore the EFI sub-system would be aware of such memory allocations and 
respect them. This would of course also hold true for allocations for SMBIOS or 
ACPI tables.

Best regards

Heinrich


Re: Proposal: U-Boot memory management

2023-12-18 Thread Tom Rini
On Tue, Dec 19, 2023 at 12:08:31AM +0100, Heinrich Schuchardt wrote:
> 
> 
> Am 18. Dezember 2023 23:41:08 MEZ schrieb Tom Rini :
> >On Mon, Dec 18, 2023 at 11:34:16PM +0100, Heinrich Schuchardt wrote:
> >
> >[snip]
> >> Or take:
> >> 
> >> load host 0:1 $c kernel.efi
> >> load host 0:1 $d initrd.img
> >> 
> >> How could we ensure that initrd.img is not overwriting a part of 
> >> kernel.efi without memory allocation?
> >
> >Today, invalid checksum as part of some part of the kernel fails. But
> >how do we do this tomorrow, are you suggesting that "load" perform
> >malloc() in some predefined size? If $c is below $d and $c + kernel.efi
> >is now above $d we can throw an error before trying to load, yes. But
> >what about:
> >load host 0:1 $d initrd.img
> >load host 0:1 $c kernel.efi
> >
> >In that case (which is only marginally contrived, the more real case is
> >loading device tree in to unexpectedly large ramdisk because someone
> >didn't understand the general advice on why device tree is lower than
> >ramdisk address) I'm fine with an error that amounts to "you just
> >corrupted another allocation" and then "fail, reset the board" or so.
> >
> 
> Our current malloc library cannot manage the complete memory. We need a 
> library like lmb which should also cover the memory management that we 
> currently have in lib/efi/efi_memory.c. This must include a memory type 
> attribute for usage in the GetMemoryMap() service. A management on page level 
> seems sufficient.
> 
> The load command should permanently allocate memory in that lmb+ library.
> 
> We need an unload command to free the memory if we want to reuse the memory 
> or we might let the load comand free the memory if exactly the same start 
> address is reused.

Our current way of loading things in to memory does not handle the case
I described, yes. How would what you're proposing handle it?

-- 
Tom


signature.asc
Description: PGP signature


Re: Proposal: U-Boot memory management

2023-12-18 Thread Heinrich Schuchardt



Am 18. Dezember 2023 23:41:08 MEZ schrieb Tom Rini :
>On Mon, Dec 18, 2023 at 11:34:16PM +0100, Heinrich Schuchardt wrote:
>
>[snip]
>> Or take:
>> 
>> load host 0:1 $c kernel.efi
>> load host 0:1 $d initrd.img
>> 
>> How could we ensure that initrd.img is not overwriting a part of kernel.efi 
>> without memory allocation?
>
>Today, invalid checksum as part of some part of the kernel fails. But
>how do we do this tomorrow, are you suggesting that "load" perform
>malloc() in some predefined size? If $c is below $d and $c + kernel.efi
>is now above $d we can throw an error before trying to load, yes. But
>what about:
>load host 0:1 $d initrd.img
>load host 0:1 $c kernel.efi
>
>In that case (which is only marginally contrived, the more real case is
>loading device tree in to unexpectedly large ramdisk because someone
>didn't understand the general advice on why device tree is lower than
>ramdisk address) I'm fine with an error that amounts to "you just
>corrupted another allocation" and then "fail, reset the board" or so.
>

Our current malloc library cannot manage the complete memory. We need a library 
like lmb which should also cover the memory management that we currently have 
in lib/efi/efi_memory.c. This must include a memory type attribute for usage in 
the GetMemoryMap() service. A management on page level seems sufficient.

The load command should permanently allocate memory in that lmb+ library.

We need an unload command to free the memory if we want to reuse the memory or 
we might let the load comand free the memory if exactly the same start address 
is reused.

Best regards

Heinrich



Re: Proposal: U-Boot memory management

2023-12-18 Thread Tom Rini
On Mon, Dec 18, 2023 at 11:34:16PM +0100, Heinrich Schuchardt wrote:

[snip]
> Or take:
> 
> load host 0:1 $c kernel.efi
> load host 0:1 $d initrd.img
> 
> How could we ensure that initrd.img is not overwriting a part of kernel.efi 
> without memory allocation?

Today, invalid checksum as part of some part of the kernel fails. But
how do we do this tomorrow, are you suggesting that "load" perform
malloc() in some predefined size? If $c is below $d and $c + kernel.efi
is now above $d we can throw an error before trying to load, yes. But
what about:
load host 0:1 $d initrd.img
load host 0:1 $c kernel.efi

In that case (which is only marginally contrived, the more real case is
loading device tree in to unexpectedly large ramdisk because someone
didn't understand the general advice on why device tree is lower than
ramdisk address) I'm fine with an error that amounts to "you just
corrupted another allocation" and then "fail, reset the board" or so.

-- 
Tom


signature.asc
Description: PGP signature


Re: Proposal: U-Boot memory management

2023-12-18 Thread Heinrich Schuchardt



Am 18. Dezember 2023 22:48:43 MEZ schrieb Simon Glass :
>Hi Heinrich,
>
>On Mon, 18 Dec 2023 at 14:37, Heinrich Schuchardt  wrote:
>>
>>
>>
>> Am 18. Dezember 2023 22:03:41 MEZ schrieb Simon Glass :
>> >Hi Heinrich,
>> >
>> >On Mon, 18 Dec 2023 at 13:00, Heinrich Schuchardt  
>> >wrote:
>> >>
>> >>
>> >>
>> >> Am 18. Dezember 2023 19:12:11 MEZ schrieb Simon Glass :
>> >> >Hi Heinrich,
>> >> >
>> >> >On Sat, 16 Dec 2023 at 12:04, Heinrich Schuchardt  
>> >> >wrote:
>> >> >>
>> >> >> On 12/16/23 19:01, Simon Glass wrote:
>> >> >> > Hi,
>> >> >> >
>> >> >> > This records my thoughts after a discussion with Ilias & Heinrich re
>> >> >> > memory allocation in U-Boot.
>> >> >> >
>> >> >> > 1. malloc()
>> >> >> >
>> >> >> > malloc() is used for programmatic memory allocation. It allows memory
>> >> >> > to be freed. It is not designed for very large allocations (e.g. a
>> >> >> > 10MB kernel or 100MB ramdisk).
>> >> >> >
>> >> >> > 2. lmb
>> >> >> >
>> >> >> > lmb is used for large blocks of memory, such as those needed for a
>> >> >> > kernel or ramdisk. Allocation is only transitory, for the purposes of
>> >> >> > loading some images and booting. If the boot fails, then all lmb
>> >> >> > allocations go away.
>> >> >> >
>> >> >> > lmb is set up by getting all available memory and then removing what
>> >> >> > is used by U-Boot (code, data, malloc() space, etc.)
>> >> >> >
>> >> >> > lmb reservations have a few flags so that areas of memory can be
>> >> >> > provided with attributes
>> >> >> >
>> >> >> > There are some corner cases...e.g. loading a file does an lmb
>> >> >> > allocation but only for the purpose of avoiding a file being loaded
>> >> >> > over U-Boot code/data. The allocation is dropped immediately after 
>> >> >> > the
>> >> >> > file is loaded. Within the bootm command, or when using standard 
>> >> >> > boot,
>> >> >> > this would be fairly easy to solve.
>> >> >> >
>> >> >> > Linux has renamed lmb to memblock. We should consider doing the same.
>> >> >> >
>> >> >> > 3. EFI
>> >> >> >
>> >> >> > EFI has its own memory-allocation tables.
>> >> >> >
>> >> >> > Like lmb, EFI is able to deal with large allocations. But via a 
>> >> >> > 'pool'
>> >> >> > function it can also do smaller allocations similar to malloc(),
>> >> >> > although each one uses at least 4KB at present.
>> >> >> >
>> >> >> > EFI allocations do not go away when a boot fails.
>> >> >> >
>> >> >> > With EFI it is possible to add allocations post facto, in which case
>> >> >> > they are added to the allocation table just as if the memory was
>> >> >> > allocated with EFI to begin with.
>> >> >> >
>> >> >> > The EFI allocations and the lmb allocations use the same memory, so 
>> >> >> > in
>> >> >> > principle could conflict.
>> >> >> >
>> >> >> > EFI allocations are sometimes used to allocate internal U-Boot data 
>> >> >> > as
>> >> >> > well, if needed by the EFI app. For example, while efi_image_parse()
>> >> >> > uses malloc(), efi_var_mem.c uses EFI allocations since the code runs
>> >> >> > in the app context and may need to access the memory after U-Boot has
>> >> >> > exited. Also efi_smbios.c uses allocate_pages() and then adds a new
>> >> >> > mapping as well.
>> >> >> >
>> >> >> > EFI memory has attributes, including what the memory is used for (to
>> >> >> > some degree of granularity). See enum efi_memory_type and struct
>> >> >> > efi_mem_desc. In the latter there are also attribute flags - whether
>> >> >> > memory is cacheable, etc.
>> >> >> >
>> >> >> > EFI also has the x86 idea of 'conventional' memory, meaning (I
>> >> >> > believe) that below 4GB that isn't reserved for the hardware/system.
>> >> >> > This is meaningless, or at least confusing, on ARM systems.
>> >> >> >
>> >> >> > 4. reservations
>> >> >> >
>> >> >> > It is perhaps worth mentioning a fourth method of memory management,
>> >> >> > where U-Boot reserves chunks of memory before relocation (in
>> >> >> > board_init_f.c), e.g. for the framebuffer, U-Boot code, the malloc()
>> >> >> > region, etc.
>> >> >> >
>> >> >> >
>> >> >> > Problems
>> >> >> > —---
>> >> >> >
>> >> >> > There are no urgent problems, but here are some things that could be 
>> >> >> > improved:
>> >> >> >
>> >> >> > 1. EFI should attach most of its data structures to driver model. 
>> >> >> > This
>> >> >> > work has started, with the partition support, but more effort would
>> >> >> > help. This would make it easier to see which memory is related to
>> >> >> > devices and which is separate.
>> >> >> >
>> >> >> > 2. Some drivers do EFI reservations today, whether EFI is used for
>> >> >> > booting or not (e.g. rockchip video rk_vop_probe()).
>> >> >>
>> >> >> Hello Simon,
>> >> >>
>> >> >> thank you for summarizing our discussion.
>> >> >>
>> >> >> Some U-Boot drivers including rockchip video inform the EFI sub-system
>> >> >> that memory is reserved.
>> >> >>
>> >> >> Furthermore drivers like arch/arm/mach-bcm283x/reset.c exist that are
>> >> >> still used after ExitBoo

Re: [PATCH v3 4/7] bcm2835: brcm,bcm2708-fb device is using r5g6b5 format

2023-12-18 Thread Stefan Wahren

Hi Ivan,

Am 18.12.23 um 22:03 schrieb Ivan T. Ivanov:

brcm,bcm2708-fb device provided by firmware on RPi5 uses
16 bits per pixel. Update driver to properly handle this.

Signed-off-by: Ivan T. Ivanov 
---
  drivers/video/bcm2835.c | 10 +-
  1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/video/bcm2835.c b/drivers/video/bcm2835.c
index 14942526f1..245c958b6e 100644
--- a/drivers/video/bcm2835.c
+++ b/drivers/video/bcm2835.c
@@ -43,7 +43,7 @@ static int bcm2835_video_probe(struct udevice *dev)

uc_priv->xsize = w;
uc_priv->ysize = h;
-   uc_priv->bpix = VIDEO_BPP32;
+   uc_priv->bpix = dev_get_driver_data(dev);
plat->base = fb_base;
plat->size = fb_size;

@@ -51,11 +51,11 @@ static int bcm2835_video_probe(struct udevice *dev)
  }

  static const struct udevice_id bcm2835_video_ids[] = {
-   { .compatible = "brcm,bcm2835-hdmi" },
-   { .compatible = "brcm,bcm2711-hdmi0" },
-   { .compatible = "brcm,bcm2708-fb" },
+   { .compatible = "brcm,bcm2835-hdmi",  .data = VIDEO_BPP32},
+   { .compatible = "brcm,bcm2711-hdmi0", .data = VIDEO_BPP32},
+   { .compatible = "brcm,bcm2708-fb",.data = VIDEO_BPP16 },

this change looks wrong to me. Before we used VIDEO_BPP32 for
brcm,bcm2708-fb. I think it's hard to explain why we should downgrade
the other boards. I would expect some brcm,bcm2712 compatible at least
this needs an explanation in the commit message.

  #if !IS_ENABLED(CONFIG_VIDEO_DT_SIMPLEFB)
-   { .compatible = "simple-framebuffer" },
+   { .compatible = "simple-framebuffer", .data = VIDEO_BPP32},
  #endif
{ }
  };




Re: [PATCH v3 1/7] rpi5: add initial memory map for bcm2712

2023-12-18 Thread Stefan Wahren

Hi Ivan,

Am 18.12.23 um 22:03 schrieb Ivan T. Ivanov:

From: Dmitry Malkin 

includes:
* 1GB of RAM (from 4GB or 8GB total)
* VPU memory interface
* AXI ranges (main peripherals)

my experience with U-Boot is little, but i do my best to give you some
feedback.


Signed-off-by: Dmitry Malkin 
Signed-off-by: Ivan T. Ivanov 
---
  arch/arm/mach-bcm283x/init.c | 38 +++-
  1 file changed, 37 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-bcm283x/init.c b/arch/arm/mach-bcm283x/init.c
index 7265faf6ce..af23b9711a 100644
--- a/arch/arm/mach-bcm283x/init.c
+++ b/arch/arm/mach-bcm283x/init.c
@@ -19,7 +19,7 @@
  #ifdef CONFIG_ARM64
  #include 

-#define MEM_MAP_MAX_ENTRIES (4)
+#define MEM_MAP_MAX_ENTRIES (5)

  static struct mm_region bcm283x_mem_map[MEM_MAP_MAX_ENTRIES] = {
{
@@ -68,6 +68,41 @@ static struct mm_region bcm2711_mem_map[MEM_MAP_MAX_ENTRIES] 
= {
}
  };

+static struct mm_region bcm2712_mem_map[MEM_MAP_MAX_ENTRIES] = {
+   {

in comparison to mach-imx/imx9/soc.c most of the memory maps doesn't
have a describing comment.

+   .virt = 0xUL,
+   .phys = 0xUL,
+   .size = 0x3f80UL,
+   .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+PTE_BLOCK_INNER_SHARE
+   }, {
+   .virt = 0x3f80UL,
+   .phys = 0x3f80UL,
+   .size = 0x0080UL,
+   .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+PTE_BLOCK_NON_SHARE |
+PTE_BLOCK_PXN | PTE_BLOCK_UXN
+   }, {
+   /* Beginning of AXI bus where uSD controller lives */
+   .virt = 0x10UL,
+   .phys = 0x10UL,
+   .size = 0x000200UL,
+   .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+PTE_BLOCK_NON_SHARE |
+PTE_BLOCK_PXN | PTE_BLOCK_UXN
+   }, {
+   .virt = 0x107c00UL,
+   .phys = 0x107c00UL,
+   .size = 0x000400UL,
+   .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+PTE_BLOCK_NON_SHARE |
+PTE_BLOCK_PXN | PTE_BLOCK_UXN
+   }, {
+   /* List terminator */
+   0,
+   }
+};
+
  struct mm_region *mem_map = bcm283x_mem_map;

  /*
@@ -78,6 +113,7 @@ static const struct udevice_id board_ids[] = {
{ .compatible = "brcm,bcm2837", .data = (ulong)&bcm283x_mem_map},
{ .compatible = "brcm,bcm2838", .data = (ulong)&bcm2711_mem_map},
{ .compatible = "brcm,bcm2711", .data = (ulong)&bcm2711_mem_map},
+   { .compatible = "brcm,bcm2712", .data = (ulong)&bcm2712_mem_map},
{ },
  };


Looking at the complete file, i saw the function print_cpuinfo().
Personally i think it's wrong to print BCM283x in case of a RPI 4 or 5.


Re: [PATCH v3 4/4] fs: remove explicit efi configuration dependency

2023-12-18 Thread Heinrich Schuchardt



Am 18. Dezember 2023 16:01:40 MEZ schrieb Simon Glass :
>Hi AKASHI,
>
>On Sun, 17 Dec 2023 at 19:39, AKASHI Takahiro
> wrote:
>>
>> Now it is clear that the feature actually depends on efi interfaces,
>> not "bootefi" command. efi_set_bootdev() will automatically be nullified
>> if necessary efi component is disabled.
>>
>> Signed-off-by: AKASHI Takahiro 
>> ---
>>  fs/fs.c | 7 +++
>>  1 file changed, 3 insertions(+), 4 deletions(-)
>>
>> diff --git a/fs/fs.c b/fs/fs.c
>> index f33b85f92b61..82ee03b160e9 100644
>> --- a/fs/fs.c
>> +++ b/fs/fs.c
>> @@ -791,10 +791,9 @@ int do_load(struct cmd_tbl *cmdtp, int flag, int argc, 
>> char *const argv[],
>> return 1;
>> }
>>
>> -   if (IS_ENABLED(CONFIG_CMD_BOOTEFI))
>> -   efi_set_bootdev(argv[1], (argc > 2) ? argv[2] : "",
>> -   (argc > 4) ? argv[4] : "", map_sysmem(addr, 
>> 0),
>> -   len_read);
>> +   efi_set_bootdev(argv[1], (argc > 2) ? argv[2] : "",
>> +   (argc > 4) ? argv[4] : "", map_sysmem(addr, 0),
>> +   len_read);
>
>As I understand it, this is setting the boot device so that (if it
>happens to be an efi application) it will know which device it came
>from. But this is a hack. For bootstd, the device is known as it loads
>the kernel.

Please, consider what happens when the user interactively executes the load and 
bootefi command from the console.

>
>Also it does not deal with memory allocation (nor can it).
>
>Where are we using the 'load' command to load a kernel? The distro
>scripts are deprecated.

Some users use boot.scr scripts 


>
>At some point this code should be removed. Is it too early for that?

Yes, as long as we allow users to invoke the bootefi command with an address 
pointer.

Best regards

Heinrich

>
>>
>> printf("%llu bytes read in %lu ms", len_read, time);
>> if (time > 0) {
>> --
>> 2.34.1
>>
>
>Regards,
>Simon


Re: [PATCH 1/4] dt-bindings: nvmem: layouts: add U-Boot environment variables layout

2023-12-18 Thread Rafał Miłecki

On 18.12.2023 15:48, Rob Herring wrote:


On Mon, 18 Dec 2023 14:37:19 +0100, Rafał Miłecki wrote:

From: Rafał Miłecki 

U-Boot env data is a way of storing firmware variables. It's a format
that can be used of top of various storage devices. Its binding should
be an NVMEM layout instead of a standalone device.

This patch adds layout binding which allows using it on top of MTD NVMEM
device as well as any other. At the same time it deprecates the old
combined binding.

Signed-off-by: Rafał Miłecki 
---
  .../bindings/nvmem/layouts/u-boot,env.yaml| 55 +++
  .../devicetree/bindings/nvmem/u-boot,env.yaml |  6 ++
  2 files changed, 61 insertions(+)
  create mode 100644 
Documentation/devicetree/bindings/nvmem/layouts/u-boot,env.yaml



My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/nvmem/u-boot,env.example.dtb:
 partition@4: 'ethaddr', 'reg' do not match any of the regexes: 
'pinctrl-[0-9]+'
from schema $id: 
http://devicetree.org/schemas/nvmem/layouts/u-boot,env.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/nvmem/u-boot,env.example.dtb:
 partition-u-boot-env: 'ethaddr' does not match any of the regexes: 
'pinctrl-[0-9]+'
from schema $id: 
http://devicetree.org/schemas/nvmem/layouts/u-boot,env.yaml#


I checked my binding independently using using dt_binding_check and
missed that. I'm not aware of any way of limiting possibility of
applying binding to specific cases (like "nvmem-layout" node) so I
guess I'll just have to avoid duplicated "u-boot,env" compatible
string.



doc reference errors (make refcheckdocs):

See 
https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20231218133722.16150-1-zaj...@gmail.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.





Re: [PATCH 4/4] nvmem: layouts: add U-Boot env layout

2023-12-18 Thread Rafał Miłecki

On 18.12.2023 15:21, Miquel Raynal wrote:

Hi Rafał,

zaj...@gmail.com wrote on Mon, 18 Dec 2023 14:37:22 +0100:


From: Rafał Miłecki 

This patch moves all generic (NVMEM devices independent) code from NVMEM
device driver to NVMEM layout driver. Then it adds a simple NVMEM layout
code on top of it.

Thanks to proper layout it's possible to support U-Boot env data stored
on any kind of NVMEM device.

For backward compatibility with old DT bindings we need to keep old
NVMEM device driver functional. To avoid code duplication a parsing
function is exported and reused in it.

Signed-off-by: Rafał Miłecki 
---


I have a couple of comments about the original driver which gets
copy-pasted in the new layout driver, maybe you could clean these
(the memory leak should be fixed before the migration so it can be
backported easily, the others are just style so it can be done after, I
don't mind).

...


+int u_boot_env_parse(struct device *dev, struct nvmem_device *nvmem,
+enum u_boot_env_format format)
+{
+   size_t crc32_data_offset;
+   size_t crc32_data_len;
+   size_t crc32_offset;
+   size_t data_offset;
+   size_t data_len;
+   size_t dev_size;
+   uint32_t crc32;
+   uint32_t calc;
+   uint8_t *buf;
+   int bytes;
+   int err;
+
+   dev_size = nvmem_dev_size(nvmem);
+
+   buf = kcalloc(1, dev_size, GFP_KERNEL);


Out of curiosity, why kcalloc(1,...) rather than kzalloc() ?


I used kcalloc() initially as I didn't need buffer to be zeroed.

I see that memory-allocation.rst however says:
> And, to be on the safe side it's best to use routines that set memory to 
zero, like kzalloc().

It's probably close to zero cost to zero that buffer so it could be kzalloc().



+   if (!buf) {
+   err = -ENOMEM;
+   goto err_out;


We could directly return ENOMEM here I guess.


+   }
+
+   bytes = nvmem_device_read(nvmem, 0, dev_size, buf);
+   if (bytes < 0)
+   return bytes;
+   else if (bytes != dev_size)
+   return -EIO;


Don't we need to free buf in the above cases?


+   switch (format) {
+   case U_BOOT_FORMAT_SINGLE:
+   crc32_offset = offsetof(struct u_boot_env_image_single, crc32);
+   crc32_data_offset = offsetof(struct u_boot_env_image_single, 
data);
+   data_offset = offsetof(struct u_boot_env_image_single, data);
+   break;
+   case U_BOOT_FORMAT_REDUNDANT:
+   crc32_offset = offsetof(struct u_boot_env_image_redundant, 
crc32);
+   crc32_data_offset = offsetof(struct u_boot_env_image_redundant, 
data);
+   data_offset = offsetof(struct u_boot_env_image_redundant, data);
+   break;
+   case U_BOOT_FORMAT_BROADCOM:
+   crc32_offset = offsetof(struct u_boot_env_image_broadcom, 
crc32);
+   crc32_data_offset = offsetof(struct u_boot_env_image_broadcom, 
data);
+   data_offset = offsetof(struct u_boot_env_image_broadcom, data);
+   break;
+   }
+   crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset));


Looks a bit convoluted, any chances we can use intermediate variables
to help decipher this?


+   crc32_data_len = dev_size - crc32_data_offset;
+   data_len = dev_size - data_offset;
+
+   calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L;
+   if (calc != crc32) {
+   dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 
0x%08x)\n", calc, crc32);
+   err = -EINVAL;
+   goto err_kfree;
+   }
+
+   buf[dev_size - 1] = '\0';
+   err = u_boot_env_parse_cells(dev, nvmem, buf, data_offset, data_len);
+   if (err)
+   dev_err(dev, "Failed to add cells: %d\n", err);


Please drop this error message, the only reason for which the function
call would fail is apparently an ENOMEM case.


+
+err_kfree:
+   kfree(buf);
+err_out:
+   return err;
+}
+EXPORT_SYMBOL_GPL(u_boot_env_parse);
+
+static int u_boot_env_add_cells(struct device *dev, struct nvmem_device *nvmem)
+{
+   const struct of_device_id *match;
+   struct device_node *layout_np;
+   enum u_boot_env_format format;
+
+   layout_np = of_nvmem_layout_get_container(nvmem);
+   if (!layout_np)
+   return -ENOENT;
+
+   match = of_match_node(u_boot_env_of_match_table, layout_np);
+   if (!match)
+   return -ENOENT;
+
+   format = (uintptr_t)match->data;


In the core there is currently an unused helper called
nvmem_layout_get_match_data() which does that. I think the original
intent of this function was to be used in this driver, so depending on
your preference, can you please either use it or remove it?


The problem is that nvmem_layout_get_match_data() uses:
layout->dev.driver

It doesn't work with layouts driver (since refactoring?) as driver is
NULL. That results in NULL pointer dereference when tryi

Re: [PATCH RFC] dt-bindings: nvmem: u-boot, env: add any-name MAC cells compatible

2023-12-18 Thread Rafał Miłecki

On 14.12.2023 22:27, Simon Glass wrote:

On Thu, 14 Dec 2023 at 08:36, Rafał Miłecki  wrote:


From: Rafał Miłecki 

So far we had a property for "ethaddr" NVMEM cell containing base
Ethernet MAC address. The problem is vendors often pick non-standard
names for storing MAC(s) (other than "ethaddr"). A few names were
noticed over years:
1. "wanaddr" (Edimax, ELECOM, EnGenius, I-O DATA, Sitecom)
2. "et1macaddr" (ASUS)
3. "eth1addr" (Buffalo)
4. "athaddr" (EnGenius)
5. "baseMAC" (Netgear)
6. "mac" (Netgear)
7. "mac_addr" (Moxa)
and more ("HW_LAN_MAC", "HW_WAN_MAC", "INIC_MAC_ADDR", "LAN_MAC_ADDR",
"RADIOADDR0", "RADIOADDR1", "WAN_MAC_ADDR", "lan1_mac_addr", "wanmac",
"wmac1", "wmac2").

It doesn't make sense to add property for every possible MAC cell name.
Instead allow specifying cells with "mac" compatible.

Signed-off-by: Rafał Miłecki 
---
List of devices and their U-Boot MAC variables:
alphanetworks,asl56026) wanmac
asus,rt-ac65p) et1macaddr
asus,rt-ac85p) et1macaddr
belkin,f9k1109v1) HW_WAN_MAC + HW_LAN_MAC
buffalo,ls220de) eth1addr
buffalo,ls421de) eth1addr
checkpoint,l-50) lan1_mac_addr
dovado,tiny-ac) INIC_MAC_ADDR
dovado,tiny-ac) LAN_MAC_ADDR + WAN_MAC_ADDR
edimax,ra21s) wanaddr
edimax,rg21s) wanaddr
elecom,wrc-2533ghbk-i) wanaddr
elecom,wrc-2533ghbk2-t) wanaddr
engenius,ecb1200) athaddr
engenius,ecb1750) athaddr
engenius,epg5000) wanaddr
engenius,epg600) wanaddr
engenius,esr1200) wanaddr
engenius,esr1750) wanaddr
engenius,esr600) wanaddr
engenius,esr600h) wanaddr
engenius,esr900) wanaddr
enterasys,ws-ap3705i) RADIOADDR0 + RADIOADDR1
iodata,wn-ac1167dgr) wanaddr
iodata,wn-ac1167gr) wanaddr
iodata,wn-ac1600dgr) wanaddr
iodata,wn-ac1600dgr2) wanaddr
iodata,wn-ac733gr3) wanaddr
iodata,wn-ag300dgr) wanaddr
iodata,wnpr2600g) wanaddr
moxa,awk-1137c) mac_addr
netgear,wax220) mac
netgear,wndap620) baseMAC
netgear,wndap660) baseMAC
ocedo,panda) wmac1 + wmac2
sitecom,wlr-7100) wanaddr
sitecom,wlr-8100) wanaddr

  .../devicetree/bindings/nvmem/u-boot,env.yaml | 33 +++
  1 file changed, 33 insertions(+)



Are these upstream U-Boots, or just vendor forks?


I guess most of those devices don't have upstream U-Boot support. Please
note that while upstreaming vendors changes would be great in most cases
it doesn't happen. Most vendors sadly don't care and most end users
don't have enough time for that. In practice we often stick with vendor
provided bootloader to flash and boot self build Linux system (like
OpenWrt).

I'm not sure if/how does it help with this PATCH but please note that
upstream U-Boot code also supports few extra variables.

There is generic eth_env_get_enetaddr_by_index() that supports variables
like "<%s><%d>addr" and "<%s>addr". Right now it's used only for
"eth<%d>addr" and "ethaddr" so that mostly limits us to "ethaddr",
"eth1addr", "eth2addr" and "eth3addr".

From some rare cases: there are also "usbnet_devaddr" and "wolpassword".

So given that U-Boot oficially supports at least 6 env variables for
MAC and there are many used with custom U-Boots and firmwares this
binding would help a lot.


Re: Proposal: U-Boot memory management

2023-12-18 Thread Tom Rini
On Mon, Dec 18, 2023 at 02:48:43PM -0700, Simon Glass wrote:
> Hi Heinrich,
> 
> On Mon, 18 Dec 2023 at 14:37, Heinrich Schuchardt  wrote:
> >
> >
> >
> > Am 18. Dezember 2023 22:03:41 MEZ schrieb Simon Glass :
> > >Hi Heinrich,
> > >
> > >On Mon, 18 Dec 2023 at 13:00, Heinrich Schuchardt  
> > >wrote:
> > >>
> > >>
> > >>
> > >> Am 18. Dezember 2023 19:12:11 MEZ schrieb Simon Glass 
> > >> :
> > >> >Hi Heinrich,
> > >> >
> > >> >On Sat, 16 Dec 2023 at 12:04, Heinrich Schuchardt  
> > >> >wrote:
> > >> >>
> > >> >> On 12/16/23 19:01, Simon Glass wrote:
> > >> >> > Hi,
> > >> >> >
> > >> >> > This records my thoughts after a discussion with Ilias & Heinrich re
> > >> >> > memory allocation in U-Boot.
> > >> >> >
> > >> >> > 1. malloc()
> > >> >> >
> > >> >> > malloc() is used for programmatic memory allocation. It allows 
> > >> >> > memory
> > >> >> > to be freed. It is not designed for very large allocations (e.g. a
> > >> >> > 10MB kernel or 100MB ramdisk).
> > >> >> >
> > >> >> > 2. lmb
> > >> >> >
> > >> >> > lmb is used for large blocks of memory, such as those needed for a
> > >> >> > kernel or ramdisk. Allocation is only transitory, for the purposes 
> > >> >> > of
> > >> >> > loading some images and booting. If the boot fails, then all lmb
> > >> >> > allocations go away.
> > >> >> >
> > >> >> > lmb is set up by getting all available memory and then removing what
> > >> >> > is used by U-Boot (code, data, malloc() space, etc.)
> > >> >> >
> > >> >> > lmb reservations have a few flags so that areas of memory can be
> > >> >> > provided with attributes
> > >> >> >
> > >> >> > There are some corner cases...e.g. loading a file does an lmb
> > >> >> > allocation but only for the purpose of avoiding a file being loaded
> > >> >> > over U-Boot code/data. The allocation is dropped immediately after 
> > >> >> > the
> > >> >> > file is loaded. Within the bootm command, or when using standard 
> > >> >> > boot,
> > >> >> > this would be fairly easy to solve.
> > >> >> >
> > >> >> > Linux has renamed lmb to memblock. We should consider doing the 
> > >> >> > same.
> > >> >> >
> > >> >> > 3. EFI
> > >> >> >
> > >> >> > EFI has its own memory-allocation tables.
> > >> >> >
> > >> >> > Like lmb, EFI is able to deal with large allocations. But via a 
> > >> >> > 'pool'
> > >> >> > function it can also do smaller allocations similar to malloc(),
> > >> >> > although each one uses at least 4KB at present.
> > >> >> >
> > >> >> > EFI allocations do not go away when a boot fails.
> > >> >> >
> > >> >> > With EFI it is possible to add allocations post facto, in which case
> > >> >> > they are added to the allocation table just as if the memory was
> > >> >> > allocated with EFI to begin with.
> > >> >> >
> > >> >> > The EFI allocations and the lmb allocations use the same memory, so 
> > >> >> > in
> > >> >> > principle could conflict.
> > >> >> >
> > >> >> > EFI allocations are sometimes used to allocate internal U-Boot data 
> > >> >> > as
> > >> >> > well, if needed by the EFI app. For example, while efi_image_parse()
> > >> >> > uses malloc(), efi_var_mem.c uses EFI allocations since the code 
> > >> >> > runs
> > >> >> > in the app context and may need to access the memory after U-Boot 
> > >> >> > has
> > >> >> > exited. Also efi_smbios.c uses allocate_pages() and then adds a new
> > >> >> > mapping as well.
> > >> >> >
> > >> >> > EFI memory has attributes, including what the memory is used for (to
> > >> >> > some degree of granularity). See enum efi_memory_type and struct
> > >> >> > efi_mem_desc. In the latter there are also attribute flags - whether
> > >> >> > memory is cacheable, etc.
> > >> >> >
> > >> >> > EFI also has the x86 idea of 'conventional' memory, meaning (I
> > >> >> > believe) that below 4GB that isn't reserved for the hardware/system.
> > >> >> > This is meaningless, or at least confusing, on ARM systems.
> > >> >> >
> > >> >> > 4. reservations
> > >> >> >
> > >> >> > It is perhaps worth mentioning a fourth method of memory management,
> > >> >> > where U-Boot reserves chunks of memory before relocation (in
> > >> >> > board_init_f.c), e.g. for the framebuffer, U-Boot code, the malloc()
> > >> >> > region, etc.
> > >> >> >
> > >> >> >
> > >> >> > Problems
> > >> >> > —---
> > >> >> >
> > >> >> > There are no urgent problems, but here are some things that could 
> > >> >> > be improved:
> > >> >> >
> > >> >> > 1. EFI should attach most of its data structures to driver model. 
> > >> >> > This
> > >> >> > work has started, with the partition support, but more effort would
> > >> >> > help. This would make it easier to see which memory is related to
> > >> >> > devices and which is separate.
> > >> >> >
> > >> >> > 2. Some drivers do EFI reservations today, whether EFI is used for
> > >> >> > booting or not (e.g. rockchip video rk_vop_probe()).
> > >> >>
> > >> >> Hello Simon,
> > >> >>
> > >> >> thank you for summarizing our discussion.
> > >> >>
> > >> >> Some U-Boot drivers including ro

Re: Proposal: U-Boot memory management

2023-12-18 Thread Simon Glass
Hi Heinrich,

On Mon, 18 Dec 2023 at 14:37, Heinrich Schuchardt  wrote:
>
>
>
> Am 18. Dezember 2023 22:03:41 MEZ schrieb Simon Glass :
> >Hi Heinrich,
> >
> >On Mon, 18 Dec 2023 at 13:00, Heinrich Schuchardt  wrote:
> >>
> >>
> >>
> >> Am 18. Dezember 2023 19:12:11 MEZ schrieb Simon Glass :
> >> >Hi Heinrich,
> >> >
> >> >On Sat, 16 Dec 2023 at 12:04, Heinrich Schuchardt  
> >> >wrote:
> >> >>
> >> >> On 12/16/23 19:01, Simon Glass wrote:
> >> >> > Hi,
> >> >> >
> >> >> > This records my thoughts after a discussion with Ilias & Heinrich re
> >> >> > memory allocation in U-Boot.
> >> >> >
> >> >> > 1. malloc()
> >> >> >
> >> >> > malloc() is used for programmatic memory allocation. It allows memory
> >> >> > to be freed. It is not designed for very large allocations (e.g. a
> >> >> > 10MB kernel or 100MB ramdisk).
> >> >> >
> >> >> > 2. lmb
> >> >> >
> >> >> > lmb is used for large blocks of memory, such as those needed for a
> >> >> > kernel or ramdisk. Allocation is only transitory, for the purposes of
> >> >> > loading some images and booting. If the boot fails, then all lmb
> >> >> > allocations go away.
> >> >> >
> >> >> > lmb is set up by getting all available memory and then removing what
> >> >> > is used by U-Boot (code, data, malloc() space, etc.)
> >> >> >
> >> >> > lmb reservations have a few flags so that areas of memory can be
> >> >> > provided with attributes
> >> >> >
> >> >> > There are some corner cases...e.g. loading a file does an lmb
> >> >> > allocation but only for the purpose of avoiding a file being loaded
> >> >> > over U-Boot code/data. The allocation is dropped immediately after the
> >> >> > file is loaded. Within the bootm command, or when using standard boot,
> >> >> > this would be fairly easy to solve.
> >> >> >
> >> >> > Linux has renamed lmb to memblock. We should consider doing the same.
> >> >> >
> >> >> > 3. EFI
> >> >> >
> >> >> > EFI has its own memory-allocation tables.
> >> >> >
> >> >> > Like lmb, EFI is able to deal with large allocations. But via a 'pool'
> >> >> > function it can also do smaller allocations similar to malloc(),
> >> >> > although each one uses at least 4KB at present.
> >> >> >
> >> >> > EFI allocations do not go away when a boot fails.
> >> >> >
> >> >> > With EFI it is possible to add allocations post facto, in which case
> >> >> > they are added to the allocation table just as if the memory was
> >> >> > allocated with EFI to begin with.
> >> >> >
> >> >> > The EFI allocations and the lmb allocations use the same memory, so in
> >> >> > principle could conflict.
> >> >> >
> >> >> > EFI allocations are sometimes used to allocate internal U-Boot data as
> >> >> > well, if needed by the EFI app. For example, while efi_image_parse()
> >> >> > uses malloc(), efi_var_mem.c uses EFI allocations since the code runs
> >> >> > in the app context and may need to access the memory after U-Boot has
> >> >> > exited. Also efi_smbios.c uses allocate_pages() and then adds a new
> >> >> > mapping as well.
> >> >> >
> >> >> > EFI memory has attributes, including what the memory is used for (to
> >> >> > some degree of granularity). See enum efi_memory_type and struct
> >> >> > efi_mem_desc. In the latter there are also attribute flags - whether
> >> >> > memory is cacheable, etc.
> >> >> >
> >> >> > EFI also has the x86 idea of 'conventional' memory, meaning (I
> >> >> > believe) that below 4GB that isn't reserved for the hardware/system.
> >> >> > This is meaningless, or at least confusing, on ARM systems.
> >> >> >
> >> >> > 4. reservations
> >> >> >
> >> >> > It is perhaps worth mentioning a fourth method of memory management,
> >> >> > where U-Boot reserves chunks of memory before relocation (in
> >> >> > board_init_f.c), e.g. for the framebuffer, U-Boot code, the malloc()
> >> >> > region, etc.
> >> >> >
> >> >> >
> >> >> > Problems
> >> >> > —---
> >> >> >
> >> >> > There are no urgent problems, but here are some things that could be 
> >> >> > improved:
> >> >> >
> >> >> > 1. EFI should attach most of its data structures to driver model. This
> >> >> > work has started, with the partition support, but more effort would
> >> >> > help. This would make it easier to see which memory is related to
> >> >> > devices and which is separate.
> >> >> >
> >> >> > 2. Some drivers do EFI reservations today, whether EFI is used for
> >> >> > booting or not (e.g. rockchip video rk_vop_probe()).
> >> >>
> >> >> Hello Simon,
> >> >>
> >> >> thank you for summarizing our discussion.
> >> >>
> >> >> Some U-Boot drivers including rockchip video inform the EFI sub-system
> >> >> that memory is reserved.
> >> >>
> >> >> Furthermore drivers like arch/arm/mach-bcm283x/reset.c exist that are
> >> >> still used after ExitBootServices. mmio addresses have to be updated
> >> >> when Linux creates its virtual memory map. Currently this is done via
> >> >> efi_add_runtime_mmio(). A more UEFI style method would be to register an
> >> >> event handler for ExitBootServices() and

Re: Proposal: U-Boot memory management

2023-12-18 Thread Tom Rini
On Mon, Dec 18, 2023 at 02:03:41PM -0700, Simon Glass wrote:
> Hi Heinrich,
> 
> On Mon, 18 Dec 2023 at 13:00, Heinrich Schuchardt  wrote:
> >
> >
> >
> > Am 18. Dezember 2023 19:12:11 MEZ schrieb Simon Glass :
> > >Hi Heinrich,
> > >
> > >On Sat, 16 Dec 2023 at 12:04, Heinrich Schuchardt  
> > >wrote:
> > >>
> > >> On 12/16/23 19:01, Simon Glass wrote:
> > >> > Hi,
> > >> >
> > >> > This records my thoughts after a discussion with Ilias & Heinrich re
> > >> > memory allocation in U-Boot.
> > >> >
> > >> > 1. malloc()
> > >> >
> > >> > malloc() is used for programmatic memory allocation. It allows memory
> > >> > to be freed. It is not designed for very large allocations (e.g. a
> > >> > 10MB kernel or 100MB ramdisk).
> > >> >
> > >> > 2. lmb
> > >> >
> > >> > lmb is used for large blocks of memory, such as those needed for a
> > >> > kernel or ramdisk. Allocation is only transitory, for the purposes of
> > >> > loading some images and booting. If the boot fails, then all lmb
> > >> > allocations go away.
> > >> >
> > >> > lmb is set up by getting all available memory and then removing what
> > >> > is used by U-Boot (code, data, malloc() space, etc.)
> > >> >
> > >> > lmb reservations have a few flags so that areas of memory can be
> > >> > provided with attributes
> > >> >
> > >> > There are some corner cases...e.g. loading a file does an lmb
> > >> > allocation but only for the purpose of avoiding a file being loaded
> > >> > over U-Boot code/data. The allocation is dropped immediately after the
> > >> > file is loaded. Within the bootm command, or when using standard boot,
> > >> > this would be fairly easy to solve.
> > >> >
> > >> > Linux has renamed lmb to memblock. We should consider doing the same.
> > >> >
> > >> > 3. EFI
> > >> >
> > >> > EFI has its own memory-allocation tables.
> > >> >
> > >> > Like lmb, EFI is able to deal with large allocations. But via a 'pool'
> > >> > function it can also do smaller allocations similar to malloc(),
> > >> > although each one uses at least 4KB at present.
> > >> >
> > >> > EFI allocations do not go away when a boot fails.
> > >> >
> > >> > With EFI it is possible to add allocations post facto, in which case
> > >> > they are added to the allocation table just as if the memory was
> > >> > allocated with EFI to begin with.
> > >> >
> > >> > The EFI allocations and the lmb allocations use the same memory, so in
> > >> > principle could conflict.
> > >> >
> > >> > EFI allocations are sometimes used to allocate internal U-Boot data as
> > >> > well, if needed by the EFI app. For example, while efi_image_parse()
> > >> > uses malloc(), efi_var_mem.c uses EFI allocations since the code runs
> > >> > in the app context and may need to access the memory after U-Boot has
> > >> > exited. Also efi_smbios.c uses allocate_pages() and then adds a new
> > >> > mapping as well.
> > >> >
> > >> > EFI memory has attributes, including what the memory is used for (to
> > >> > some degree of granularity). See enum efi_memory_type and struct
> > >> > efi_mem_desc. In the latter there are also attribute flags - whether
> > >> > memory is cacheable, etc.
> > >> >
> > >> > EFI also has the x86 idea of 'conventional' memory, meaning (I
> > >> > believe) that below 4GB that isn't reserved for the hardware/system.
> > >> > This is meaningless, or at least confusing, on ARM systems.
> > >> >
> > >> > 4. reservations
> > >> >
> > >> > It is perhaps worth mentioning a fourth method of memory management,
> > >> > where U-Boot reserves chunks of memory before relocation (in
> > >> > board_init_f.c), e.g. for the framebuffer, U-Boot code, the malloc()
> > >> > region, etc.
> > >> >
> > >> >
> > >> > Problems
> > >> > —---
> > >> >
> > >> > There are no urgent problems, but here are some things that could be 
> > >> > improved:
> > >> >
> > >> > 1. EFI should attach most of its data structures to driver model. This
> > >> > work has started, with the partition support, but more effort would
> > >> > help. This would make it easier to see which memory is related to
> > >> > devices and which is separate.
> > >> >
> > >> > 2. Some drivers do EFI reservations today, whether EFI is used for
> > >> > booting or not (e.g. rockchip video rk_vop_probe()).
> > >>
> > >> Hello Simon,
> > >>
> > >> thank you for summarizing our discussion.
> > >>
> > >> Some U-Boot drivers including rockchip video inform the EFI sub-system
> > >> that memory is reserved.
> > >>
> > >> Furthermore drivers like arch/arm/mach-bcm283x/reset.c exist that are
> > >> still used after ExitBootServices. mmio addresses have to be updated
> > >> when Linux creates its virtual memory map. Currently this is done via
> > >> efi_add_runtime_mmio(). A more UEFI style method would be to register an
> > >> event handler for ExitBootServices() and use ConvertPointer() in the
> > >> event handler.
> > >>
> > >> >
> > >> > 3. U-Boot doesn't really map arch-specific memory attributes (e.g.
> > >> > armv8's struct mm_region) to EFI on

Re: Proposal: U-Boot memory management

2023-12-18 Thread Heinrich Schuchardt



Am 18. Dezember 2023 22:03:41 MEZ schrieb Simon Glass :
>Hi Heinrich,
>
>On Mon, 18 Dec 2023 at 13:00, Heinrich Schuchardt  wrote:
>>
>>
>>
>> Am 18. Dezember 2023 19:12:11 MEZ schrieb Simon Glass :
>> >Hi Heinrich,
>> >
>> >On Sat, 16 Dec 2023 at 12:04, Heinrich Schuchardt  
>> >wrote:
>> >>
>> >> On 12/16/23 19:01, Simon Glass wrote:
>> >> > Hi,
>> >> >
>> >> > This records my thoughts after a discussion with Ilias & Heinrich re
>> >> > memory allocation in U-Boot.
>> >> >
>> >> > 1. malloc()
>> >> >
>> >> > malloc() is used for programmatic memory allocation. It allows memory
>> >> > to be freed. It is not designed for very large allocations (e.g. a
>> >> > 10MB kernel or 100MB ramdisk).
>> >> >
>> >> > 2. lmb
>> >> >
>> >> > lmb is used for large blocks of memory, such as those needed for a
>> >> > kernel or ramdisk. Allocation is only transitory, for the purposes of
>> >> > loading some images and booting. If the boot fails, then all lmb
>> >> > allocations go away.
>> >> >
>> >> > lmb is set up by getting all available memory and then removing what
>> >> > is used by U-Boot (code, data, malloc() space, etc.)
>> >> >
>> >> > lmb reservations have a few flags so that areas of memory can be
>> >> > provided with attributes
>> >> >
>> >> > There are some corner cases...e.g. loading a file does an lmb
>> >> > allocation but only for the purpose of avoiding a file being loaded
>> >> > over U-Boot code/data. The allocation is dropped immediately after the
>> >> > file is loaded. Within the bootm command, or when using standard boot,
>> >> > this would be fairly easy to solve.
>> >> >
>> >> > Linux has renamed lmb to memblock. We should consider doing the same.
>> >> >
>> >> > 3. EFI
>> >> >
>> >> > EFI has its own memory-allocation tables.
>> >> >
>> >> > Like lmb, EFI is able to deal with large allocations. But via a 'pool'
>> >> > function it can also do smaller allocations similar to malloc(),
>> >> > although each one uses at least 4KB at present.
>> >> >
>> >> > EFI allocations do not go away when a boot fails.
>> >> >
>> >> > With EFI it is possible to add allocations post facto, in which case
>> >> > they are added to the allocation table just as if the memory was
>> >> > allocated with EFI to begin with.
>> >> >
>> >> > The EFI allocations and the lmb allocations use the same memory, so in
>> >> > principle could conflict.
>> >> >
>> >> > EFI allocations are sometimes used to allocate internal U-Boot data as
>> >> > well, if needed by the EFI app. For example, while efi_image_parse()
>> >> > uses malloc(), efi_var_mem.c uses EFI allocations since the code runs
>> >> > in the app context and may need to access the memory after U-Boot has
>> >> > exited. Also efi_smbios.c uses allocate_pages() and then adds a new
>> >> > mapping as well.
>> >> >
>> >> > EFI memory has attributes, including what the memory is used for (to
>> >> > some degree of granularity). See enum efi_memory_type and struct
>> >> > efi_mem_desc. In the latter there are also attribute flags - whether
>> >> > memory is cacheable, etc.
>> >> >
>> >> > EFI also has the x86 idea of 'conventional' memory, meaning (I
>> >> > believe) that below 4GB that isn't reserved for the hardware/system.
>> >> > This is meaningless, or at least confusing, on ARM systems.
>> >> >
>> >> > 4. reservations
>> >> >
>> >> > It is perhaps worth mentioning a fourth method of memory management,
>> >> > where U-Boot reserves chunks of memory before relocation (in
>> >> > board_init_f.c), e.g. for the framebuffer, U-Boot code, the malloc()
>> >> > region, etc.
>> >> >
>> >> >
>> >> > Problems
>> >> > —---
>> >> >
>> >> > There are no urgent problems, but here are some things that could be 
>> >> > improved:
>> >> >
>> >> > 1. EFI should attach most of its data structures to driver model. This
>> >> > work has started, with the partition support, but more effort would
>> >> > help. This would make it easier to see which memory is related to
>> >> > devices and which is separate.
>> >> >
>> >> > 2. Some drivers do EFI reservations today, whether EFI is used for
>> >> > booting or not (e.g. rockchip video rk_vop_probe()).
>> >>
>> >> Hello Simon,
>> >>
>> >> thank you for summarizing our discussion.
>> >>
>> >> Some U-Boot drivers including rockchip video inform the EFI sub-system
>> >> that memory is reserved.
>> >>
>> >> Furthermore drivers like arch/arm/mach-bcm283x/reset.c exist that are
>> >> still used after ExitBootServices. mmio addresses have to be updated
>> >> when Linux creates its virtual memory map. Currently this is done via
>> >> efi_add_runtime_mmio(). A more UEFI style method would be to register an
>> >> event handler for ExitBootServices() and use ConvertPointer() in the
>> >> event handler.
>> >>
>> >> >
>> >> > 3. U-Boot doesn't really map arch-specific memory attributes (e.g.
>> >> > armv8's struct mm_region) to EFI ones.
>> >>
>> >> U-Boot fails to set up RWX properties. E.g. the region where a FIT image
>> >> is loaded should not be 

Re: [PATCH 2/2 v3] smbios: Fallback to the default DT if sysinfo nodes are missing

2023-12-18 Thread Simon Glass
Hi Neil,

On Mon, 18 Dec 2023 at 08:37,  wrote:
>
> Hi,
>
> On 18/12/2023 16:01, Simon Glass wrote:
> > Hi Neil,
> >
> > On Mon, 18 Dec 2023 at 02:54,  wrote:
> >>
> >> On 17/12/2023 19:41, Tom Rini wrote:
> >>> On Sat, Dec 16, 2023 at 11:46:18AM -0700, Simon Glass wrote:
>  Hi Tom,
> 
>  On Thu, 14 Dec 2023 at 06:11, Tom Rini  wrote:
> >
> > [..]
> >
> >>> And my point with the above is that other SoC maintainers (Neil, for
> >>> amlogic) have said (paraphrasing) he does not want to do N smbios node
> >>> patches. Which is why Ilias' patch is if not 1000% correct, it's Good
> >>> Enough and will, if it's really a problem to have all lower case
> >>> information displayed, spur people to see providing that information as
> >>> a real problem that needs to be solved. Or it will be seen as good
> >>> enough.
> >>>
> >>
> >> If some platforms requires a more "correct" smbios dataset, then they're
> >> welcome adding the required smbios node, and it's perfectly understandable,
> >> but for the other community-maintained platforms we need some valid 
> >> fallback
> >> data otherwise they'll be de facto excluded from some tools for no valid 
> >> reasons.
> >
> > Do you know which tools require SMBIOS tables? I found sos and another
> > Redhat one.
>
> SMBIOS data is translated into dmi informations in Linux, and a little
> lookup in GitHub gives 6.4K files using something from 
> /sys/devices/virtual/dmi/id/,
> and by very commonly used tools like lshw and probably fwupd.

lshw also uses devicetree, so should not also need SMBIOS.

fwupd uses UUIDs to indicate the device. So far as I know (and I wrote
a plugin for it, so at least know something), it does not rely on
SMBIOS tables.

Here is my main question: is SMBIOS:

1) just informational, not affecting the operation of the device
2) important and needed for the device to function

If it is (1), then I don't mind what is in the tables - we could
perhaps add a '?' at the start of each string to indicate it is
provisional?
If it is (2), then I want to avoid adding information that might be
wrong / might change over the life of the device

In either case, putting these workarounds behind a Kconfig seems
reasonable to me. What do you think?

Regards,
Simon


Re: Proposal: U-Boot memory management

2023-12-18 Thread Simon Glass
Hi Heinrich,

On Mon, 18 Dec 2023 at 13:00, Heinrich Schuchardt  wrote:
>
>
>
> Am 18. Dezember 2023 19:12:11 MEZ schrieb Simon Glass :
> >Hi Heinrich,
> >
> >On Sat, 16 Dec 2023 at 12:04, Heinrich Schuchardt  wrote:
> >>
> >> On 12/16/23 19:01, Simon Glass wrote:
> >> > Hi,
> >> >
> >> > This records my thoughts after a discussion with Ilias & Heinrich re
> >> > memory allocation in U-Boot.
> >> >
> >> > 1. malloc()
> >> >
> >> > malloc() is used for programmatic memory allocation. It allows memory
> >> > to be freed. It is not designed for very large allocations (e.g. a
> >> > 10MB kernel or 100MB ramdisk).
> >> >
> >> > 2. lmb
> >> >
> >> > lmb is used for large blocks of memory, such as those needed for a
> >> > kernel or ramdisk. Allocation is only transitory, for the purposes of
> >> > loading some images and booting. If the boot fails, then all lmb
> >> > allocations go away.
> >> >
> >> > lmb is set up by getting all available memory and then removing what
> >> > is used by U-Boot (code, data, malloc() space, etc.)
> >> >
> >> > lmb reservations have a few flags so that areas of memory can be
> >> > provided with attributes
> >> >
> >> > There are some corner cases...e.g. loading a file does an lmb
> >> > allocation but only for the purpose of avoiding a file being loaded
> >> > over U-Boot code/data. The allocation is dropped immediately after the
> >> > file is loaded. Within the bootm command, or when using standard boot,
> >> > this would be fairly easy to solve.
> >> >
> >> > Linux has renamed lmb to memblock. We should consider doing the same.
> >> >
> >> > 3. EFI
> >> >
> >> > EFI has its own memory-allocation tables.
> >> >
> >> > Like lmb, EFI is able to deal with large allocations. But via a 'pool'
> >> > function it can also do smaller allocations similar to malloc(),
> >> > although each one uses at least 4KB at present.
> >> >
> >> > EFI allocations do not go away when a boot fails.
> >> >
> >> > With EFI it is possible to add allocations post facto, in which case
> >> > they are added to the allocation table just as if the memory was
> >> > allocated with EFI to begin with.
> >> >
> >> > The EFI allocations and the lmb allocations use the same memory, so in
> >> > principle could conflict.
> >> >
> >> > EFI allocations are sometimes used to allocate internal U-Boot data as
> >> > well, if needed by the EFI app. For example, while efi_image_parse()
> >> > uses malloc(), efi_var_mem.c uses EFI allocations since the code runs
> >> > in the app context and may need to access the memory after U-Boot has
> >> > exited. Also efi_smbios.c uses allocate_pages() and then adds a new
> >> > mapping as well.
> >> >
> >> > EFI memory has attributes, including what the memory is used for (to
> >> > some degree of granularity). See enum efi_memory_type and struct
> >> > efi_mem_desc. In the latter there are also attribute flags - whether
> >> > memory is cacheable, etc.
> >> >
> >> > EFI also has the x86 idea of 'conventional' memory, meaning (I
> >> > believe) that below 4GB that isn't reserved for the hardware/system.
> >> > This is meaningless, or at least confusing, on ARM systems.
> >> >
> >> > 4. reservations
> >> >
> >> > It is perhaps worth mentioning a fourth method of memory management,
> >> > where U-Boot reserves chunks of memory before relocation (in
> >> > board_init_f.c), e.g. for the framebuffer, U-Boot code, the malloc()
> >> > region, etc.
> >> >
> >> >
> >> > Problems
> >> > —---
> >> >
> >> > There are no urgent problems, but here are some things that could be 
> >> > improved:
> >> >
> >> > 1. EFI should attach most of its data structures to driver model. This
> >> > work has started, with the partition support, but more effort would
> >> > help. This would make it easier to see which memory is related to
> >> > devices and which is separate.
> >> >
> >> > 2. Some drivers do EFI reservations today, whether EFI is used for
> >> > booting or not (e.g. rockchip video rk_vop_probe()).
> >>
> >> Hello Simon,
> >>
> >> thank you for summarizing our discussion.
> >>
> >> Some U-Boot drivers including rockchip video inform the EFI sub-system
> >> that memory is reserved.
> >>
> >> Furthermore drivers like arch/arm/mach-bcm283x/reset.c exist that are
> >> still used after ExitBootServices. mmio addresses have to be updated
> >> when Linux creates its virtual memory map. Currently this is done via
> >> efi_add_runtime_mmio(). A more UEFI style method would be to register an
> >> event handler for ExitBootServices() and use ConvertPointer() in the
> >> event handler.
> >>
> >> >
> >> > 3. U-Boot doesn't really map arch-specific memory attributes (e.g.
> >> > armv8's struct mm_region) to EFI ones.
> >>
> >> U-Boot fails to set up RWX properties. E.g. the region where a FIT image
> >> is loaded should not be executable.
> >>
> >> >
> >> > 4. EFI duplicates some code from bootm, some of which relates to
> >> > memory allocation (e.g. FDT fixup).
> >>
> >> Fixup code is not duplicated but i

[PATCH v3 7/7] pci: pcie-brcmstb: Add bcm2712 PCIe controller support

2023-12-18 Thread Ivan T. Ivanov
PCIe controller have minor register map difference compared
to bcm2711 variant. Handle this using device specific register
offset.

Signed-off-by: Ivan T. Ivanov 
---
 drivers/pci/pcie_brcmstb.c | 23 +++
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/pcie_brcmstb.c b/drivers/pci/pcie_brcmstb.c
index cd45f0bee9..d63e715b2e 100644
--- a/drivers/pci/pcie_brcmstb.c
+++ b/drivers/pci/pcie_brcmstb.c
@@ -90,7 +90,6 @@
 #define PCIE_MEM_WIN0_LIMIT_HI(win)\
 PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI + ((win) * 8)
 
-#define PCIE_MISC_HARD_PCIE_HARD_DEBUG 0x4204
 #define  PCIE_HARD_DEBUG_SERDES_IDDQ_MASK  0x0800
 
 #define PCIE_MSI_INTR2_CLR 0x4508
@@ -131,6 +130,10 @@
 #define SSC_STATUS_PLL_LOCK_MASK   0x800
 #define SSC_STATUS_PLL_LOCK_SHIFT  11
 
+struct pcie_cfg_data {
+   unsigned long hard_debug_offs;
+};
+
 /**
  * struct brcm_pcie - the PCIe controller state
  * @base: Base address of memory mapped IO registers of the controller
@@ -141,6 +144,7 @@
 struct brcm_pcie {
void __iomem*base;
 
+   struct pcie_cfg_data*cfg;
int gen;
boolssc;
 };
@@ -458,7 +462,7 @@ static int brcm_pcie_probe(struct udevice *dev)
/* Take the bridge out of reset */
clrbits_le32(base + PCIE_RGR1_SW_INIT_1, RGR1_SW_INIT_1_INIT_MASK);
 
-   clrbits_le32(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG,
+   clrbits_le32(base + pcie->cfg->hard_debug_offs,
 PCIE_HARD_DEBUG_SERDES_IDDQ_MASK);
 
/* Wait for SerDes to be stable */
@@ -599,7 +603,7 @@ static int brcm_pcie_remove(struct udevice *dev)
setbits_le32(base + PCIE_RGR1_SW_INIT_1, RGR1_SW_INIT_1_PERST_MASK);
 
/* Turn off SerDes */
-   setbits_le32(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG,
+   setbits_le32(base + pcie->cfg->hard_debug_offs,
 PCIE_HARD_DEBUG_SERDES_IDDQ_MASK);
 
/* Shutdown bridge */
@@ -620,6 +624,8 @@ static int brcm_pcie_of_to_plat(struct udevice *dev)
if (!pcie->base)
return -EINVAL;
 
+   pcie->cfg = (struct pcie_cfg_data *)dev_get_driver_data(dev);
+
pcie->ssc = ofnode_read_bool(dn, "brcm,enable-ssc");
 
ret = ofnode_read_u32(dn, "max-link-speed", &max_link_speed);
@@ -636,8 +642,17 @@ static const struct dm_pci_ops brcm_pcie_ops = {
.write_config   = brcm_pcie_write_config,
 };
 
+static const struct pcie_cfg_data bcm2711_cfg = {
+   .hard_debug_offs= 0x4204
+};
+
+static const struct pcie_cfg_data bcm2712_cfg = {
+   .hard_debug_offs= 0x4304
+};
+
 static const struct udevice_id brcm_pcie_ids[] = {
-   { .compatible = "brcm,bcm2711-pcie" },
+   { .compatible = "brcm,bcm2711-pcie", .data = (ulong)&bcm2711_cfg },
+   { .compatible = "brcm,bcm2712-pcie", .data = (ulong)&bcm2712_cfg },
{ }
 };
 
-- 
2.35.3



[PATCH v3 6/7] configs: rpi_arm64: enable SDHCI BCMSTB driver

2023-12-18 Thread Ivan T. Ivanov
RPi5 have "brcm,bcm2712-sdhci" controller which is
handled by "sdhci-bcmstb" driver, so enable it.

Signed-off-by: Ivan T. Ivanov 
---
 configs/rpi_arm64_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configs/rpi_arm64_defconfig b/configs/rpi_arm64_defconfig
index f9dade18f6..1107fd11de 100644
--- a/configs/rpi_arm64_defconfig
+++ b/configs/rpi_arm64_defconfig
@@ -33,6 +33,7 @@ CONFIG_BCM2835_GPIO=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_BCM2835=y
+CONFIG_MMC_SDHCI_BCMSTB=y
 CONFIG_BCMGENET=y
 CONFIG_PCI_BRCMSTB=y
 CONFIG_PINCTRL=y
-- 
2.35.3



[PATCH v3 5/7] mmc: bcmstb: Add support for bcm2712 SD controller

2023-12-18 Thread Ivan T. Ivanov
Borrow SD quirks from vendor Linux driver.

"BCM2712 unfortunately carries with it a perennial bug with the SD
controller register interface present on previous chips (2711/2709/2708).
Accesses must be dword-sized and a read-modify-write cycle to the 32-bit
registers containing the COMMAND, TRANSFER_MODE, BLOCK_SIZE and
BLOCK_COUNT registers tramples the upper/lower 16 bits of data written.
BCM2712 does not seem to need the extreme delay between each write as on
previous chips, just the serialisation of writes to these registers in a
single 32-bit operation."

Signed-off-by: Ivan T. Ivanov 
---
 drivers/mmc/bcmstb_sdhci.c | 173 -
 1 file changed, 172 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/bcmstb_sdhci.c b/drivers/mmc/bcmstb_sdhci.c
index dc96818cff..21489e66c0 100644
--- a/drivers/mmc/bcmstb_sdhci.c
+++ b/drivers/mmc/bcmstb_sdhci.c
@@ -38,6 +38,16 @@
  */
 #define BCMSTB_SDHCI_MINIMUM_CLOCK_FREQUENCY   40
 
+#define SDIO_CFG_CTRL  0x0
+#define  SDIO_CFG_CTRL_SDCD_N_TEST_EN  BIT(31)
+#define  SDIO_CFG_CTRL_SDCD_N_TEST_LEV BIT(30)
+
+#define SDIO_CFG_SD_PIN_SEL0x44
+#define  SDIO_CFG_SD_PIN_SEL_MASK  0x3
+#define  SDIO_CFG_SD_PIN_SEL_CARD  BIT(1)
+
+#define REG_OFFSET_IN_BITS(reg) ((reg) << 3 & 0x18)
+
 /*
  * This driver has only been tested with eMMC devices; SD devices may
  * not work.
@@ -47,6 +57,53 @@ struct sdhci_bcmstb_plat {
struct mmc mmc;
 };
 
+struct sdhci_bcmstb_host {
+   struct sdhci_host host;
+   u32 shadow_cmd;
+   u32 shadow_blk;
+   bool is_cmd_shadowed;
+   bool is_blk_shadowed;
+};
+
+struct sdhci_brcmstb_dev_priv {
+   int (*init)(struct udevice *dev);
+   struct sdhci_ops *ops;
+};
+
+static inline struct sdhci_bcmstb_host *to_bcmstb_host(struct sdhci_host *host)
+{
+   return container_of(host, struct sdhci_bcmstb_host, host);
+}
+
+static int sdhci_brcmstb_init_2712(struct udevice *dev)
+{
+   struct sdhci_host *host = dev_get_priv(dev);
+   void *cfg_regs;
+   u32 reg;
+
+   /* Map in the non-standard CFG registers */
+   cfg_regs = dev_remap_addr_name(dev, "cfg");
+   if (!cfg_regs)
+   return -ENOENT;
+
+   if ((host->mmc->host_caps & MMC_CAP_NONREMOVABLE) ||
+   (host->mmc->host_caps & MMC_CAP_NEEDS_POLL)) {
+   /* Force presence */
+   reg = readl(cfg_regs + SDIO_CFG_CTRL);
+   reg &= ~SDIO_CFG_CTRL_SDCD_N_TEST_LEV;
+   reg |= SDIO_CFG_CTRL_SDCD_N_TEST_EN;
+   writel(reg, cfg_regs + SDIO_CFG_CTRL);
+   } else {
+   /* Enable card detection line */
+   reg = readl(cfg_regs + SDIO_CFG_SD_PIN_SEL);
+   reg &= ~SDIO_CFG_SD_PIN_SEL_MASK;
+   reg |= SDIO_CFG_SD_PIN_SEL_CARD;
+   writel(reg, cfg_regs + SDIO_CFG_SD_PIN_SEL);
+   }
+
+   return 0;
+}
+
 static int sdhci_bcmstb_bind(struct udevice *dev)
 {
struct sdhci_bcmstb_plat *plat = dev_get_plat(dev);
@@ -58,10 +115,14 @@ static int sdhci_bcmstb_probe(struct udevice *dev)
 {
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
struct sdhci_bcmstb_plat *plat = dev_get_plat(dev);
-   struct sdhci_host *host = dev_get_priv(dev);
+   struct sdhci_bcmstb_host *bcmstb = dev_get_priv(dev);
+   struct sdhci_host *host = &bcmstb->host;
+   struct sdhci_brcmstb_dev_priv *dev_priv;
fdt_addr_t base;
int ret;
 
+   dev_priv = (struct sdhci_brcmstb_dev_priv *)dev_get_driver_data(dev);
+
base = dev_read_addr(dev);
if (base == FDT_ADDR_T_NONE)
return -EINVAL;
@@ -75,6 +136,10 @@ static int sdhci_bcmstb_probe(struct udevice *dev)
 
host->mmc = &plat->mmc;
host->mmc->dev = dev;
+
+   if (dev_priv && dev_priv->ops)
+   host->ops = dev_priv->ops;
+
ret = sdhci_setup_cfg(&plat->cfg, host,
  BCMSTB_SDHCI_MAXIMUM_CLOCK_FREQUENCY,
  BCMSTB_SDHCI_MINIMUM_CLOCK_FREQUENCY);
@@ -84,10 +149,116 @@ static int sdhci_bcmstb_probe(struct udevice *dev)
upriv->mmc = &plat->mmc;
host->mmc->priv = host;
 
+   if (dev_priv && dev_priv->init) {
+   ret = dev_priv->init(dev);
+   if (ret)
+   return ret;
+   }
+
return sdhci_probe(dev);
 }
 
+static u16 sdhci_brcmstb_32bits_readw(struct sdhci_host *host, int reg)
+{
+   struct sdhci_bcmstb_host *bcmstb = to_bcmstb_host(host);
+   u16 word;
+   u32 val;
+
+   if (reg == SDHCI_TRANSFER_MODE && bcmstb->is_cmd_shadowed) {
+   /* Get the saved transfer mode */
+   val = bcmstb->shadow_cmd;
+   } else if ((reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) &&
+  bcmstb->is_blk_shadowed) {
+   /* Get the saved block info */
+   

[PATCH v3 3/7] rpi5: Use devicetree to retrieve board revision

2023-12-18 Thread Ivan T. Ivanov
Firmware on RPi5 return error on board revision query
through firmware interface, but on the other hand it fills
"linux,revision" in "system" node, so use it to detect board
revision.

system {
linux,revision = <0xc04170>;
linux,serial = <0x6cf44e80 0x3c533ede>;
};

Signed-off-by: Ivan T. Ivanov 
---
 board/raspberrypi/rpi/rpi.c | 22 +++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c
index cd823ad746..2851ebc985 100644
--- a/board/raspberrypi/rpi/rpi.c
+++ b/board/raspberrypi/rpi/rpi.c
@@ -171,6 +171,11 @@ static const struct rpi_model rpi_models_new_scheme[] = {
DTB_DIR "bcm2711-rpi-cm4.dtb",
true,
},
+   [0x17] = {
+   "5 Model B",
+   DTB_DIR "bcm2712-rpi-5-b.dtb",
+   true,
+   },
 };
 
 static const struct rpi_model rpi_models_old_scheme[] = {
@@ -429,15 +434,27 @@ static void get_board_revision(void)
int ret;
const struct rpi_model *models;
uint32_t models_count;
+   ofnode node;
 
BCM2835_MBOX_INIT_HDR(msg);
BCM2835_MBOX_INIT_TAG(&msg->get_board_rev, GET_BOARD_REV);
 
ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg->hdr);
if (ret) {
-   printf("bcm2835: Could not query board revision\n");
/* Ignore error; not critical */
-   return;
+   node = ofnode_path("/system");
+   if (!ofnode_valid(node)) {
+   printf("bcm2835: Could not find /system node\n");
+   return;
+   }
+
+   ret = ofnode_read_u32(node, "linux,revision", &revision);
+   if (ret) {
+   printf("bcm2835: Could not find linux,revision\n");
+   return;
+   }
+   } else {
+   revision = msg->get_board_rev.body.resp.rev;
}
 
/*
@@ -451,7 +468,6 @@ static void get_board_revision(void)
 * 
http://www.raspberrypi.org/forums/viewtopic.php?f=63&t=98367&start=250
 * http://www.raspberrypi.org/forums/viewtopic.php?f=31&t=20594
 */
-   revision = msg->get_board_rev.body.resp.rev;
if (revision & 0x80) {
rev_scheme = 1;
rev_type = (revision >> 4) & 0xff;
-- 
2.35.3



[PATCH v3 4/7] bcm2835: brcm, bcm2708-fb device is using r5g6b5 format

2023-12-18 Thread Ivan T. Ivanov
brcm,bcm2708-fb device provided by firmware on RPi5 uses
16 bits per pixel. Update driver to properly handle this.

Signed-off-by: Ivan T. Ivanov 
---
 drivers/video/bcm2835.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/video/bcm2835.c b/drivers/video/bcm2835.c
index 14942526f1..245c958b6e 100644
--- a/drivers/video/bcm2835.c
+++ b/drivers/video/bcm2835.c
@@ -43,7 +43,7 @@ static int bcm2835_video_probe(struct udevice *dev)
 
uc_priv->xsize = w;
uc_priv->ysize = h;
-   uc_priv->bpix = VIDEO_BPP32;
+   uc_priv->bpix = dev_get_driver_data(dev);
plat->base = fb_base;
plat->size = fb_size;
 
@@ -51,11 +51,11 @@ static int bcm2835_video_probe(struct udevice *dev)
 }
 
 static const struct udevice_id bcm2835_video_ids[] = {
-   { .compatible = "brcm,bcm2835-hdmi" },
-   { .compatible = "brcm,bcm2711-hdmi0" },
-   { .compatible = "brcm,bcm2708-fb" },
+   { .compatible = "brcm,bcm2835-hdmi",  .data = VIDEO_BPP32},
+   { .compatible = "brcm,bcm2711-hdmi0", .data = VIDEO_BPP32},
+   { .compatible = "brcm,bcm2708-fb",.data = VIDEO_BPP16 },
 #if !IS_ENABLED(CONFIG_VIDEO_DT_SIMPLEFB)
-   { .compatible = "simple-framebuffer" },
+   { .compatible = "simple-framebuffer", .data = VIDEO_BPP32},
 #endif
{ }
 };
-- 
2.35.3



[PATCH v3 2/7] rpi5: Use devicetree as alternative way to read IO base addresses

2023-12-18 Thread Ivan T. Ivanov
From: Dmitry Malkin 

MBOX and Watchdog on RPi5/bcm2712 has a different base IO offsets.
Find them via devicetree blob passed by bootloader.

Signed-off-by: Dmitry Malkin 
Signed-off-by: Ivan T. Ivanov 
---
 arch/arm/mach-bcm283x/include/mach/base.h  |  5 ++-
 arch/arm/mach-bcm283x/include/mach/mbox.h  |  3 +-
 arch/arm/mach-bcm283x/include/mach/sdhci.h |  3 +-
 arch/arm/mach-bcm283x/include/mach/timer.h |  3 +-
 arch/arm/mach-bcm283x/include/mach/wdog.h  |  3 +-
 arch/arm/mach-bcm283x/init.c   | 43 ++
 6 files changed, 43 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-bcm283x/include/mach/base.h 
b/arch/arm/mach-bcm283x/include/mach/base.h
index 4ccaf69693..6de99e7ea1 100644
--- a/arch/arm/mach-bcm283x/include/mach/base.h
+++ b/arch/arm/mach-bcm283x/include/mach/base.h
@@ -6,7 +6,10 @@
 #ifndef _BCM283x_BASE_H_
 #define _BCM283x_BASE_H_
 
-extern unsigned long rpi_bcm283x_base;
+extern unsigned long rpi_mbox_base;
+extern unsigned long rpi_timer_base;
+extern unsigned long rpi_sdhci_base;
+extern unsigned long rpi_wdog_base;
 
 #ifdef CONFIG_ARMV7_LPAE
 #ifdef CONFIG_TARGET_RPI_4_32B
diff --git a/arch/arm/mach-bcm283x/include/mach/mbox.h 
b/arch/arm/mach-bcm283x/include/mach/mbox.h
index 490664f878..35d4e2f075 100644
--- a/arch/arm/mach-bcm283x/include/mach/mbox.h
+++ b/arch/arm/mach-bcm283x/include/mach/mbox.h
@@ -38,8 +38,7 @@
 
 /* Raw mailbox HW */
 
-#define BCM2835_MBOX_PHYSADDR ({ BUG_ON(!rpi_bcm283x_base); \
-rpi_bcm283x_base + 0xb880; })
+#define BCM2835_MBOX_PHYSADDR  rpi_mbox_base
 
 struct bcm2835_mbox_regs {
u32 read;
diff --git a/arch/arm/mach-bcm283x/include/mach/sdhci.h 
b/arch/arm/mach-bcm283x/include/mach/sdhci.h
index 7323690687..e837c679c4 100644
--- a/arch/arm/mach-bcm283x/include/mach/sdhci.h
+++ b/arch/arm/mach-bcm283x/include/mach/sdhci.h
@@ -8,8 +8,7 @@
 
 #include 
 
-#define BCM2835_SDHCI_PHYSADDR ({ BUG_ON(!rpi_bcm283x_base); \
- rpi_bcm283x_base + 0x0030; })
+#define BCM2835_SDHCI_PHYSADDR rpi_sdhci_base
 
 int bcm2835_sdhci_init(u32 regbase, u32 emmc_freq);
 
diff --git a/arch/arm/mach-bcm283x/include/mach/timer.h 
b/arch/arm/mach-bcm283x/include/mach/timer.h
index 5567dbd7f3..60500a256d 100644
--- a/arch/arm/mach-bcm283x/include/mach/timer.h
+++ b/arch/arm/mach-bcm283x/include/mach/timer.h
@@ -11,8 +11,7 @@
 #include 
 #endif
 
-#define BCM2835_TIMER_PHYSADDR ({ BUG_ON(!rpi_bcm283x_base); \
- rpi_bcm283x_base + 0x3000; })
+#define BCM2835_TIMER_PHYSADDR rpi_timer_base
 
 #define BCM2835_TIMER_CS_M3(1 << 3)
 #define BCM2835_TIMER_CS_M2(1 << 2)
diff --git a/arch/arm/mach-bcm283x/include/mach/wdog.h 
b/arch/arm/mach-bcm283x/include/mach/wdog.h
index 9942666720..b950560674 100644
--- a/arch/arm/mach-bcm283x/include/mach/wdog.h
+++ b/arch/arm/mach-bcm283x/include/mach/wdog.h
@@ -8,8 +8,7 @@
 
 #include 
 
-#define BCM2835_WDOG_PHYSADDR ({ BUG_ON(!rpi_bcm283x_base); \
-rpi_bcm283x_base + 0x0010; })
+#define BCM2835_WDOG_PHYSADDR  rpi_wdog_base
 
 struct bcm2835_wdog_regs {
u32 unknown0[7];
diff --git a/arch/arm/mach-bcm283x/init.c b/arch/arm/mach-bcm283x/init.c
index af23b9711a..1c5c748484 100644
--- a/arch/arm/mach-bcm283x/init.c
+++ b/arch/arm/mach-bcm283x/init.c
@@ -151,7 +151,11 @@ static void rpi_update_mem_map(void)
 static void rpi_update_mem_map(void) {}
 #endif
 
-unsigned long rpi_bcm283x_base = 0x3f00;
+/* Default bcm283x devices addresses */
+unsigned long rpi_mbox_base  = 0x3f00b880;
+unsigned long rpi_sdhci_base = 0x3f30;
+unsigned long rpi_wdog_base  = 0x3f10;
+unsigned long rpi_timer_base = 0x3f003000;
 
 int arch_cpu_init(void)
 {
@@ -162,22 +166,45 @@ int arch_cpu_init(void)
 
 int mach_cpu_init(void)
 {
-   int ret, soc_offset;
+   int ret, soc, offset;
u64 io_base, size;
 
rpi_update_mem_map();
 
/* Get IO base from device tree */
-   soc_offset = fdt_path_offset(gd->fdt_blob, "/soc");
-   if (soc_offset < 0)
-   return soc_offset;
+   soc = fdt_path_offset(gd->fdt_blob, "/soc");
+   if (soc < 0)
+   return soc;
 
-   ret = fdt_read_range((void *)gd->fdt_blob, soc_offset, 0, NULL,
-   &io_base, &size);
+   ret = fdt_read_range((void *)gd->fdt_blob, soc, 0, NULL,
+&io_base, &size);
if (ret)
return ret;
 
-   rpi_bcm283x_base = io_base;
+   rpi_mbox_base  = io_base + 0x00b880;
+   rpi_sdhci_base = io_base + 0x30;
+   rpi_wdog_base  = io_base + 0x10;
+   rpi_timer_base = io_base + 0x003000;
+
+   offset = fdt_node_offset_by_compatible(gd->fdt_blob, soc,
+  "brcm,bcm2835-mbox");
+   if (offset > soc)
+   rpi_mbox_base = fdt_get_base_address(gd->fdt_blob, offset);
+
+   offset = fdt_node_offset_

[PATCH v3 1/7] rpi5: add initial memory map for bcm2712

2023-12-18 Thread Ivan T. Ivanov
From: Dmitry Malkin 

includes:
* 1GB of RAM (from 4GB or 8GB total)
* VPU memory interface
* AXI ranges (main peripherals)

Signed-off-by: Dmitry Malkin 
Signed-off-by: Ivan T. Ivanov 
---
 arch/arm/mach-bcm283x/init.c | 38 +++-
 1 file changed, 37 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-bcm283x/init.c b/arch/arm/mach-bcm283x/init.c
index 7265faf6ce..af23b9711a 100644
--- a/arch/arm/mach-bcm283x/init.c
+++ b/arch/arm/mach-bcm283x/init.c
@@ -19,7 +19,7 @@
 #ifdef CONFIG_ARM64
 #include 
 
-#define MEM_MAP_MAX_ENTRIES (4)
+#define MEM_MAP_MAX_ENTRIES (5)
 
 static struct mm_region bcm283x_mem_map[MEM_MAP_MAX_ENTRIES] = {
{
@@ -68,6 +68,41 @@ static struct mm_region bcm2711_mem_map[MEM_MAP_MAX_ENTRIES] 
= {
}
 };
 
+static struct mm_region bcm2712_mem_map[MEM_MAP_MAX_ENTRIES] = {
+   {
+   .virt = 0xUL,
+   .phys = 0xUL,
+   .size = 0x3f80UL,
+   .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+PTE_BLOCK_INNER_SHARE
+   }, {
+   .virt = 0x3f80UL,
+   .phys = 0x3f80UL,
+   .size = 0x0080UL,
+   .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+PTE_BLOCK_NON_SHARE |
+PTE_BLOCK_PXN | PTE_BLOCK_UXN
+   }, {
+   /* Beginning of AXI bus where uSD controller lives */
+   .virt = 0x10UL,
+   .phys = 0x10UL,
+   .size = 0x000200UL,
+   .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+PTE_BLOCK_NON_SHARE |
+PTE_BLOCK_PXN | PTE_BLOCK_UXN
+   }, {
+   .virt = 0x107c00UL,
+   .phys = 0x107c00UL,
+   .size = 0x000400UL,
+   .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+PTE_BLOCK_NON_SHARE |
+PTE_BLOCK_PXN | PTE_BLOCK_UXN
+   }, {
+   /* List terminator */
+   0,
+   }
+};
+
 struct mm_region *mem_map = bcm283x_mem_map;
 
 /*
@@ -78,6 +113,7 @@ static const struct udevice_id board_ids[] = {
{ .compatible = "brcm,bcm2837", .data = (ulong)&bcm283x_mem_map},
{ .compatible = "brcm,bcm2838", .data = (ulong)&bcm2711_mem_map},
{ .compatible = "brcm,bcm2711", .data = (ulong)&bcm2711_mem_map},
+   { .compatible = "brcm,bcm2712", .data = (ulong)&bcm2712_mem_map},
{ },
 };
 
-- 
2.35.3



[PATCH v3 0/7] rpi5: initial support

2023-12-18 Thread Ivan T. Ivanov
Hi,

These patches are adding basic support for RPi5.
They are based on v2 series from Dmitry Malkin[1].

With them I am able to _start_ current openSUSE
Tumbleweed without modification. They are still
a lot of things to be added to the upstream Linux
before it runs flawlessly on this device, but at
least in U-Booot SD controller used for uSD card
and Frameboffer and HDMI0 devices are working fine
now. It seems that PCIe controller is working fine
too, but I have not tested it too much.

Serial console and reset are also functional.

Hopefully this will help others add missing pieces
more easily.

Happy hacking!

Regards,
Ivan

[1] 
https://lore.kernel.org/all/CAKRNjQ0dsWozGo4n8g58m4cCEk3n=qx1r+l24wbgpo-ip1y...@mail.gmail.com/

Dmitry Malkin (2):
  rpi5: add initial memory map for bcm2712
  rpi5: Use devicetree as alternative way to read IO base addresses

Ivan T. Ivanov (5):
  rpi5: Use devicetree to retrieve board revision
  bcm2835: brcm,bcm2708-fb device is using r5g6b5 format
  mmc: bcmstb: Add support for bcm2712 SD controller
  configs: rpi_arm64: enable SDHCI BCMSTB driver
  pci: pcie-brcmstb: Add bcm2712 PCIe controller support

 arch/arm/mach-bcm283x/include/mach/base.h  |   5 +-
 arch/arm/mach-bcm283x/include/mach/mbox.h  |   3 +-
 arch/arm/mach-bcm283x/include/mach/sdhci.h |   3 +-
 arch/arm/mach-bcm283x/include/mach/timer.h |   3 +-
 arch/arm/mach-bcm283x/include/mach/wdog.h  |   3 +-
 arch/arm/mach-bcm283x/init.c   |  81 --
 board/raspberrypi/rpi/rpi.c|  22 ++-
 configs/rpi_arm64_defconfig|   1 +
 drivers/mmc/bcmstb_sdhci.c | 173 -
 drivers/pci/pcie_brcmstb.c |  23 ++-
 drivers/video/bcm2835.c|  10 +-
 11 files changed, 296 insertions(+), 31 deletions(-)

-- 
2.35.3



Re: Adding EFI runtime support to the Arm's FF-A bus

2023-12-18 Thread Heinrich Schuchardt



Am 18. Dezember 2023 16:01:44 MEZ schrieb Simon Glass :
>Hi,
>
>On Thu, 14 Dec 2023 at 12:47, Ilias Apalodimas
> wrote:
>>
>> Hi Mark, Abdellatif
>>
>> On Thu, 14 Dec 2023 at 18:47, Mark Kettenis  wrote:
>> >
>> > > Date: Thu, 14 Dec 2023 15:53:46 +
>> > > From: Abdellatif El Khlifi 
>> >
>> > Hi Abdellatif,
>> >
>> > > Hi guys,
>> > >
>> > > I'd like to ask for advice regarding adding EFI RT support to the Arm's 
>> > > FF-A bus
>> > > in U-Boot.
>> > >
>> > > The objective is to enable the FF-A messaging APIs in EFI RT to be
>> > > used for comms with the secure world. This will help getting/setting
>> > > EFI variables through FF-A.
>> > >
>> > > The existing FF-A APIs in U-Boot call the DM APIs (which are not 
>> > > available at RT).
>> > >
>> > > Two possible solutions:
>> > >
>> > > 1/ having the entire U-Boot in RT space (as Simon stated in this 
>> > > discussion[1])
>> >
>> > I don't think this is a terribly good idea.  With this approach orders
>> > of magnitude more code will be present in kernel address space one the
>> > OS kernel is running and calling into the EFI runtime.  Including code
>> > that may access hardware devices that are now under OS control.  It
>> > will be nigh impossible to audit all that code and make sure that only
>> > a safe subset of it gets called.  So...
>>
>> +100
>> I think we should draw a line here. I mentioned it on another thread,
>> but I did a shot BoF in Plumbers discussing issues like this,
>> problems, and potential solutions [0] [1]. Since that talk patches for
>> the kernel that 'solve' the problem for RPMBs got pulled into
>> linux-next [2].
>> The TL;DR of that talk is that if the kernel ends up being in control
>> of the hardware that stores the EFI variables, we need to find elegant
>> ways to teach the kernel how to store those directly. The EFI
>> requirement of an isolated flash is something that mostly came from
>> the x86 world and is not a reality on the majority of embedded boards.
>> I also think we should give up on Authenticated EFI variables in that
>> case. We get zero guarantees unless the medium has similar properties
>> to an RPMB.
>> If a vendor cares about proper UEFI secure boot he can implement
>> proper hardware.
>
>Just to copy in my thoughts as they are lost at this point:
>
>> We would need to publish a runtime interface with access to the driver
>> API. I did ask for this when the EFI runtime support was added, but it
>> wasn't done.
>
>> It would be possible to create a new 'runtime' phase of U-Boot (RPL?),
>> separate from the others. That will be much easier once we get the XPL
>> stuff sorted out., since adding new [hase would be fairly trivial  CPL
>> died as another contributor had a series which went in first...then I
>> never got back to it.
>
>> So for now having the entire U-Boot in runtime space seems reasonable to me.
>
>> I'll also mention that it would be nice to have s new-style API
>> (replacing the old API U-Boot currently has) which uses more of a
>> module approach. E.g. we could declare that uclass_first_device() is
>> exported and can be called from outside U-Boot.
>
>>
>> >
>> > >
>> > > 2/ Create an RT variant for the FF-A APIs needed.
>> > >   These RT variant don't call the DM APIs
>> > >   (e.g: ffa_mm_communicate_runtime, ffa_sync_send_receive_runtime, 
>> > > ...)
>> > >
>> > > What do you recommend please ?
>> >
>> > ...this is what I would recommend.  Preferably in a way that refactors
>> > the code such that the low-level functionality is shared between the
>> > DM and non-DM APIs.
>>
>> Yes. The only thing you need to keep alive is the machinery to talk to
>> the secure world. The bus, flash driver etc should all be running
>> isolated in there. In that case you can implement SetVariableRT as
>> described the the EFI spec.
>
>The current approach is pretty brittle, since it relies on putting
>some of the U-Boot code into a separate area. There is no good way to
>know which U-Boot code should be in that area, since we don't create a
>separate build. If a function calls one that has not been specially
>marked, or accesses data that is not in the area, then it will crash
>or hang.
>
>So, as I said, I think we need a new build, if we want to avoid all of
>U-Boot in there. Anything else is hard to maintain.

The EFI runtime is the most security exposed part of U-Boot. We should strive 
to keep the attack surface small. No matter how we define the runtime (by 
section assignment as today or by a dedicated build) I would not want to have 
the driver model in the runtime.

The only drivers that are required by the EBBR are for resetting the system. 
ARM has PSCI as reset handler, RISC-V has SBI. These are invoked by simple 
ecalls.

Any runtime device drivers for variable storage should not be in the U-Boot 
runtime but live in the secure world (e.g. OP-TEE). FF-A is the new  ARM 
protocol for talking to the secure world and hence fits into the picture.

@Abdellatif 

Does an OP-TEE modu

Re: Proposal: U-Boot memory management

2023-12-18 Thread Heinrich Schuchardt



Am 18. Dezember 2023 19:12:11 MEZ schrieb Simon Glass :
>Hi Heinrich,
>
>On Sat, 16 Dec 2023 at 12:04, Heinrich Schuchardt  wrote:
>>
>> On 12/16/23 19:01, Simon Glass wrote:
>> > Hi,
>> >
>> > This records my thoughts after a discussion with Ilias & Heinrich re
>> > memory allocation in U-Boot.
>> >
>> > 1. malloc()
>> >
>> > malloc() is used for programmatic memory allocation. It allows memory
>> > to be freed. It is not designed for very large allocations (e.g. a
>> > 10MB kernel or 100MB ramdisk).
>> >
>> > 2. lmb
>> >
>> > lmb is used for large blocks of memory, such as those needed for a
>> > kernel or ramdisk. Allocation is only transitory, for the purposes of
>> > loading some images and booting. If the boot fails, then all lmb
>> > allocations go away.
>> >
>> > lmb is set up by getting all available memory and then removing what
>> > is used by U-Boot (code, data, malloc() space, etc.)
>> >
>> > lmb reservations have a few flags so that areas of memory can be
>> > provided with attributes
>> >
>> > There are some corner cases...e.g. loading a file does an lmb
>> > allocation but only for the purpose of avoiding a file being loaded
>> > over U-Boot code/data. The allocation is dropped immediately after the
>> > file is loaded. Within the bootm command, or when using standard boot,
>> > this would be fairly easy to solve.
>> >
>> > Linux has renamed lmb to memblock. We should consider doing the same.
>> >
>> > 3. EFI
>> >
>> > EFI has its own memory-allocation tables.
>> >
>> > Like lmb, EFI is able to deal with large allocations. But via a 'pool'
>> > function it can also do smaller allocations similar to malloc(),
>> > although each one uses at least 4KB at present.
>> >
>> > EFI allocations do not go away when a boot fails.
>> >
>> > With EFI it is possible to add allocations post facto, in which case
>> > they are added to the allocation table just as if the memory was
>> > allocated with EFI to begin with.
>> >
>> > The EFI allocations and the lmb allocations use the same memory, so in
>> > principle could conflict.
>> >
>> > EFI allocations are sometimes used to allocate internal U-Boot data as
>> > well, if needed by the EFI app. For example, while efi_image_parse()
>> > uses malloc(), efi_var_mem.c uses EFI allocations since the code runs
>> > in the app context and may need to access the memory after U-Boot has
>> > exited. Also efi_smbios.c uses allocate_pages() and then adds a new
>> > mapping as well.
>> >
>> > EFI memory has attributes, including what the memory is used for (to
>> > some degree of granularity). See enum efi_memory_type and struct
>> > efi_mem_desc. In the latter there are also attribute flags - whether
>> > memory is cacheable, etc.
>> >
>> > EFI also has the x86 idea of 'conventional' memory, meaning (I
>> > believe) that below 4GB that isn't reserved for the hardware/system.
>> > This is meaningless, or at least confusing, on ARM systems.
>> >
>> > 4. reservations
>> >
>> > It is perhaps worth mentioning a fourth method of memory management,
>> > where U-Boot reserves chunks of memory before relocation (in
>> > board_init_f.c), e.g. for the framebuffer, U-Boot code, the malloc()
>> > region, etc.
>> >
>> >
>> > Problems
>> > —---
>> >
>> > There are no urgent problems, but here are some things that could be 
>> > improved:
>> >
>> > 1. EFI should attach most of its data structures to driver model. This
>> > work has started, with the partition support, but more effort would
>> > help. This would make it easier to see which memory is related to
>> > devices and which is separate.
>> >
>> > 2. Some drivers do EFI reservations today, whether EFI is used for
>> > booting or not (e.g. rockchip video rk_vop_probe()).
>>
>> Hello Simon,
>>
>> thank you for summarizing our discussion.
>>
>> Some U-Boot drivers including rockchip video inform the EFI sub-system
>> that memory is reserved.
>>
>> Furthermore drivers like arch/arm/mach-bcm283x/reset.c exist that are
>> still used after ExitBootServices. mmio addresses have to be updated
>> when Linux creates its virtual memory map. Currently this is done via
>> efi_add_runtime_mmio(). A more UEFI style method would be to register an
>> event handler for ExitBootServices() and use ConvertPointer() in the
>> event handler.
>>
>> >
>> > 3. U-Boot doesn't really map arch-specific memory attributes (e.g.
>> > armv8's struct mm_region) to EFI ones.
>>
>> U-Boot fails to set up RWX properties. E.g. the region where a FIT image
>> is loaded should not be executable.
>>
>> >
>> > 4. EFI duplicates some code from bootm, some of which relates to
>> > memory allocation (e.g. FDT fixup).
>>
>> Fixup code is not duplicated but invoked via image_setup_libfdt().
>>
>> >
>> > 5. EFI code is used even if EFI is never used to boot
>>
>>
>> * Only a minimum initialization of the EFI sub-system happens in
>> efi_init_early().
>> * Some EFI code is called when probing block devices because we wanted
>> the EFI and the dm part to be integrated.

[PATCH v2 17/17] configs: Enable HDMI Out for ROC-RK3328-CC

2023-12-18 Thread Jagan Teki
U-Boot 2024.01-rc4-00053-gb9f7cafdd9-dirty (Dec 11 2023 - 13:18:15 +0530)

Model: Firefly roc-rk3328-cc
DRAM:  1 GiB (effective 1022 MiB)
PMIC:  RK8050 (on=0x40, off=0x00)
Core:  236 devices, 26 uclasses, devicetree: separate
MMC:   mmc@ff50: 1, mmc@ff52: 0
Loading Environment from MMC... *** Warning - bad CRC, using default environment

tmdsclock = 14850; chipversion = 1
In:serial
Out:   vidconsole
Err:   vidconsole
Model: Firefly roc-rk3328-cc
Net:   eth0: ethernet@ff54
Hit any key to stop autoboot:  0
=> dm tree
 Class Index  Probed  DriverName
---
 root  0  [ + ]   root_driver   root_driver
 firmware  0  [   ]   psci  |-- psci
 clk   0  [ + ]   fixed_clock   |-- xin24m
 syscon0  [ + ]   rockchip_rk3328_grf   |-- syscon@ff10
 serial0  [ + ]   ns16550_serial|-- serial@ff13
 i2c   0  [ + ]   rockchip_rk3066_i2c   |-- i2c@ff16
 pmic  0  [ + ]   rockchip_rk805|   `-- pmic@18
 sysreset  0  [   ]   rk8xx_sysreset|   |-- rk8xx_sysreset
 regulator 0  [ + ]   rk8xx_buck|   |-- DCDC_REG1
 regulator 1  [ + ]   rk8xx_buck|   |-- DCDC_REG2
 regulator 2  [ + ]   rk8xx_buck|   |-- DCDC_REG3
 regulator 3  [ + ]   rk8xx_buck|   |-- DCDC_REG4
 regulator 4  [ + ]   rk8xx_ldo |   |-- LDO_REG1
 regulator 5  [ + ]   rk8xx_ldo |   |-- LDO_REG2
 regulator 6  [ + ]   rk8xx_ldo |   `-- LDO_REG3
 video 0  [ + ]   rk3328_vop|-- vop@ff37
 vidconsole0  [ + ]   vidconsole0   |   `-- vop@ff37.vidconsole0
 display   0  [ + ]   rk3328_hdmi_rockchip  |-- hdmi@ff3c
 phy   0  [ + ]   inno_hdmi_phy |-- phy@ff43
 clk   1  [ + ]   rockchip_rk3328_cru   |-- clock-controller@ff44
 sysreset  1  [   ]   rockchip_sysreset |   |-- sysreset
 reset 0  [ + ]   rockchip_reset|   `-- reset

Signed-off-by: Jagan Teki 
---
Changes for v2:
- none

 configs/roc-cc-rk3328_defconfig | 5 +
 1 file changed, 5 insertions(+)

diff --git a/configs/roc-cc-rk3328_defconfig b/configs/roc-cc-rk3328_defconfig
index 4ac3c9403b..4eef9016dc 100644
--- a/configs/roc-cc-rk3328_defconfig
+++ b/configs/roc-cc-rk3328_defconfig
@@ -79,6 +79,7 @@ CONFIG_PHY_REALTEK=y
 CONFIG_PHY_GIGE=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_GMAC_ROCKCHIP=y
+CONFIG_PHY_ROCKCHIP_INNO_HDMI=y
 CONFIG_PHY_ROCKCHIP_INNO_USB2=y
 CONFIG_PINCTRL=y
 CONFIG_SPL_PINCTRL=y
@@ -114,6 +115,10 @@ CONFIG_USB_DWC3=y
 CONFIG_USB_DWC3_GENERIC=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_DWC2_OTG=y
+CONFIG_VIDEO=y
+CONFIG_DISPLAY=y
+CONFIG_VIDEO_ROCKCHIP=y
+CONFIG_DISPLAY_ROCKCHIP_HDMI=y
 CONFIG_SPL_TINY_MEMSET=y
 CONFIG_TPL_TINY_MEMSET=y
 CONFIG_ERRNO_STR=y
-- 
2.25.1



[PATCH v2 16/17] configs: evb-rk3328: Enable vidconsole for rk3328

2023-12-18 Thread Jagan Teki
Enable video console for Rockchip RK3328.

Signed-off-by: Jagan Teki 
---
Changes for v2:
- none

 include/configs/evb_rk3328.h| 5 +
 include/configs/rk3328_common.h | 1 +
 2 files changed, 6 insertions(+)

diff --git a/include/configs/evb_rk3328.h b/include/configs/evb_rk3328.h
index d10e5b1d2e..c985080f7b 100644
--- a/include/configs/evb_rk3328.h
+++ b/include/configs/evb_rk3328.h
@@ -6,6 +6,11 @@
 #ifndef __EVB_RK3328_H
 #define __EVB_RK3328_H
 
+#define ROCKCHIP_DEVICE_SETTINGS \
+   "stdin=serial,usbkbd\0" \
+   "stdout=serial,vidconsole\0" \
+   "stderr=serial,vidconsole\0"
+
 #include 
 
 #endif
diff --git a/include/configs/rk3328_common.h b/include/configs/rk3328_common.h
index e920ec7e5d..2c40674b22 100644
--- a/include/configs/rk3328_common.h
+++ b/include/configs/rk3328_common.h
@@ -26,6 +26,7 @@
ENV_MEM_LAYOUT_SETTINGS \
"fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \
"partitions=" PARTS_DEFAULT \
+   ROCKCHIP_DEVICE_SETTINGS \
"boot_targets=" BOOT_TARGETS "\0"
 
 #endif
-- 
2.25.1



[PATCH v2 15/17] rockchip: Enable preconsole for rk3328

2023-12-18 Thread Jagan Teki
Enable and set the start address of pre-console buffer for RK3328.

Signed-off-by: Jagan Teki 
---
Changes for v2:
- none

 arch/arm/mach-rockchip/Kconfig | 1 +
 common/Kconfig | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index b577a911e7..60f403fe74 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -179,6 +179,7 @@ config ROCKCHIP_RK3328
select SUPPORT_TPL
select TPL
select TPL_NEEDS_SEPARATE_STACK if TPL
+   imply PRE_CONSOLE_BUFFER
imply ROCKCHIP_COMMON_BOARD
imply ROCKCHIP_SDRAM_COMMON
imply SPL_ROCKCHIP_COMMON_BOARD
diff --git a/common/Kconfig b/common/Kconfig
index 0f54819519..093ebfbd1e 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -208,7 +208,7 @@ config PRE_CON_BUF_ADDR
default 0x2f00 if ARCH_SUNXI && MACH_SUN9I
default 0x4f00 if ARCH_SUNXI && !MACH_SUN9I
default 0x0f00 if ROCKCHIP_RK3288
-   default 0x0f20 if ROCKCHIP_RK3399
+   default 0x0f20 if ROCKCHIP_RK3399 || ROCKCHIP_RK3328
help
  This sets the start address of the pre-console buffer. This must
  be in available memory and is accessed before relocation and
-- 
2.25.1



[PATCH v2 14/17] ARM: dts: rk3328: Enable VOP for bootph-all

2023-12-18 Thread Jagan Teki
Model: Firefly roc-rk3328-cc
DRAM: 1 GiB (effective 1022 MiB)
Video device 'vop@ff37' cannot allocate frame buffer memory -ensure the 
device is set up before relocation
Error binding driver 'rockchip_rk3328_vop': -28
Some drivers failed to bind
initcall sequence 3ffcd5e8 failed at call 0021a5c4 (err=-28)
 ### ERROR ### Please RESET the board ###

Signed-off-by: Jagan Teki 
---
Changes for v2:
- none

 arch/arm/dts/rk3328-u-boot.dtsi | 4 
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/dts/rk3328-u-boot.dtsi b/arch/arm/dts/rk3328-u-boot.dtsi
index a9f2536de2..5258fec566 100644
--- a/arch/arm/dts/rk3328-u-boot.dtsi
+++ b/arch/arm/dts/rk3328-u-boot.dtsi
@@ -68,3 +68,7 @@
 &spi0 {
bootph-all;
 };
+
+&vop {
+   bootph-all;
+};
-- 
2.25.1



[PATCH v2 13/17] video: rockchip: Add rk3328 vop support

2023-12-18 Thread Jagan Teki
From: Jagan Teki 

Add support for Rockchip RK3328 VOP.

Require VOP cleanup before handoff to Linux by writing reset values to
WIN registers. Without this Linux VOP trigger page fault as below
[0.752016] Loading compiled-in X.509 certificates
[0.787796] inno_hdmi_phy_rk3328_clk_recalc_rate: parent 2400
[0.788391] inno-hdmi-phy ff43.phy: inno_hdmi_phy_rk3328_clk_recalc_rate 
rate 14850 vco 14850
[0.798353] rockchip-drm display-subsystem: bound ff37.vop (ops 
vop_component_ops)
[0.799403] dwhdmi-rockchip ff3c.hdmi: supply avdd-0v9 not found, using 
dummy regulator
[0.800288] rk_iommu ff373f00.iommu: Enable stall request timed out, status: 
0x4b
[0.801131] dwhdmi-rockchip ff3c.hdmi: supply avdd-1v8 not found, using 
dummy regulator
[0.802056] rk_iommu ff373f00.iommu: Disable paging request timed out, 
status: 0x4b
[0.803233] dwhdmi-rockchip ff3c.hdmi: Detected HDMI TX controller 
v2.11a with HDCP (inno_dw_hdmi_phy2)
[0.805355] dwhdmi-rockchip ff3c.hdmi: registered DesignWare HDMI I2C 
bus driver
[0.808769] rockchip-drm display-subsystem: bound ff3c.hdmi (ops 
dw_hdmi_rockchip_ops)
[0.810869] [drm] Initialized rockchip 1.0.0 20140818 for display-subsystem 
on minor 0

Signed-off-by: Jagan Teki 
---
Changes for v2:
- Add VOP cleanup
- Update commit

 drivers/video/rockchip/Makefile |  1 +
 drivers/video/rockchip/rk3328_vop.c | 83 +
 2 files changed, 84 insertions(+)
 create mode 100644 drivers/video/rockchip/rk3328_vop.c

diff --git a/drivers/video/rockchip/Makefile b/drivers/video/rockchip/Makefile
index 4991303c73..f55beceebf 100644
--- a/drivers/video/rockchip/Makefile
+++ b/drivers/video/rockchip/Makefile
@@ -6,6 +6,7 @@
 ifdef CONFIG_VIDEO_ROCKCHIP
 obj-y += rk_vop.o
 obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288_vop.o
+obj-$(CONFIG_ROCKCHIP_RK3328) += rk3328_vop.o
 obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399_vop.o
 obj-$(CONFIG_DISPLAY_ROCKCHIP_EDP) += rk_edp.o
 obj-$(CONFIG_DISPLAY_ROCKCHIP_LVDS) += rk_lvds.o
diff --git a/drivers/video/rockchip/rk3328_vop.c 
b/drivers/video/rockchip/rk3328_vop.c
new file mode 100644
index 00..a4da3a91e8
--- /dev/null
+++ b/drivers/video/rockchip/rk3328_vop.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2023 Edgeble AI Technologies Pvt. Ltd.
+ */
+
+#include 
+#include 
+#include 
+#include "rk_vop.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void rk3328_set_pin_polarity(struct udevice *dev,
+   enum vop_modes mode, u32 polarity)
+{
+   struct rk_vop_priv *priv = dev_get_priv(dev);
+   struct rk3288_vop *regs = priv->regs;
+
+   switch (mode) {
+   case VOP_MODE_HDMI:
+   clrsetbits_le32(®s->dsp_ctrl1,
+   M_RK3399_DSP_HDMI_POL,
+   V_RK3399_DSP_HDMI_POL(polarity));
+   break;
+   default:
+   debug("%s: unsupported output mode %x\n", __func__, mode);
+   }
+}
+
+static int rk3328_vop_probe(struct udevice *dev)
+{
+   /* Before relocation we don't need to do anything */
+   if (!(gd->flags & GD_FLG_RELOC))
+   return 0;
+
+   return rk_vop_probe(dev);
+}
+
+static int rk3328_vop_remove(struct udevice *dev)
+{
+   struct rk_vop_priv *priv = dev_get_priv(dev);
+   struct rk3288_vop *regs = priv->regs;
+   struct rk3288_vop *win_regs = priv->regs + priv->win_offset;
+
+   /* write reset values */
+   writel(0xef013f, &win_regs->win0_act_info);
+   writel(0xef013f, &win_regs->win0_dsp_info);
+   writel(0xa000a, &win_regs->win0_dsp_st);
+   writel(0x0, &win_regs->win0_yrgb_mst);
+   writel(0x01, ®s->reg_cfg_done);
+
+   return 0;
+}
+
+struct rkvop_driverdata rk3328_driverdata = {
+   .dsp_offset = 0x490,
+   .win_offset = 0xd0,
+   .features = VOP_FEATURE_OUTPUT_10BIT,
+   .set_pin_polarity = rk3328_set_pin_polarity,
+};
+
+static const struct udevice_id rk3328_vop_ids[] = {
+   {
+   .compatible = "rockchip,rk3328-vop",
+   .data = (ulong)&rk3328_driverdata
+   },
+   { /* sentile */ }
+};
+
+static const struct video_ops rk3328_vop_ops = {
+};
+
+U_BOOT_DRIVER(rk3328_vop) = {
+   .name   = "rk3328_vop",
+   .id = UCLASS_VIDEO,
+   .of_match = rk3328_vop_ids,
+   .ops= &rk3328_vop_ops,
+   .bind   = rk_vop_bind,
+   .probe  = rk3328_vop_probe,
+   .remove = rk3328_vop_remove,
+   .priv_auto  = sizeof(struct rk_vop_priv),
+   .flags  = DM_FLAG_PRE_RELOC | DM_FLAG_OS_PREPARE,
+};
-- 
2.25.1



[PATCH v2 12/17] video: rockchip: Add rk3328 hdmi support

2023-12-18 Thread Jagan Teki
From: Jagan Teki 

Add Rockchip RK3328 HDMI Out driver.

Signed-off-by: Jagan Teki 
---
Changes for v2:
- none

 drivers/video/rockchip/Makefile  |   1 +
 drivers/video/rockchip/rk3328_hdmi.c | 131 +++
 drivers/video/rockchip/rk_hdmi.h |   3 +
 3 files changed, 135 insertions(+)
 create mode 100644 drivers/video/rockchip/rk3328_hdmi.c

diff --git a/drivers/video/rockchip/Makefile b/drivers/video/rockchip/Makefile
index 8128289cc8..4991303c73 100644
--- a/drivers/video/rockchip/Makefile
+++ b/drivers/video/rockchip/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399_vop.o
 obj-$(CONFIG_DISPLAY_ROCKCHIP_EDP) += rk_edp.o
 obj-$(CONFIG_DISPLAY_ROCKCHIP_LVDS) += rk_lvds.o
 obj-hdmi-$(CONFIG_ROCKCHIP_RK3288) += rk3288_hdmi.o
+obj-hdmi-$(CONFIG_ROCKCHIP_RK3328) += rk3328_hdmi.o
 obj-hdmi-$(CONFIG_ROCKCHIP_RK3399) += rk3399_hdmi.o
 obj-$(CONFIG_DISPLAY_ROCKCHIP_HDMI) += rk_hdmi.o $(obj-hdmi-y)
 obj-mipi-$(CONFIG_ROCKCHIP_RK3288) += rk3288_mipi.o
diff --git a/drivers/video/rockchip/rk3328_hdmi.c 
b/drivers/video/rockchip/rk3328_hdmi.c
new file mode 100644
index 00..23624699ba
--- /dev/null
+++ b/drivers/video/rockchip/rk3328_hdmi.c
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2023 Edgeble AI Technologies Pvt. Ltd.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "rk_hdmi.h"
+
+#define RK3328_IO_3V_DOMAIN  (7 << (9 + 16))
+#define RK3328_IO_5V_DOMAIN  ((7 << 9) | (3 << (9 + 16)))
+#define RK3328_IO_DDC_IN_MSK ((3 << 10) | (3 << (10 + 16)))
+#define RK3328_IO_CTRL_BY_HDMI   ((1 << 13) | (1 << (13 + 16)))
+
+static int rk3328_hdmi_enable(struct udevice *dev, int panel_bpp,
+ const struct display_timing *edid)
+{
+   struct rk_hdmi_priv *priv = dev_get_priv(dev);
+
+   return dw_hdmi_enable(&priv->hdmi, edid);
+}
+
+static int rk3328_dw_hdmi_phy_cfg(struct dw_hdmi *hdmi, uint pixclock)
+{
+   struct rk_hdmi_priv *priv = container_of(hdmi, struct rk_hdmi_priv, 
hdmi);
+   int ret;
+
+   ret = generic_phy_init(&priv->phy);
+   if (ret) {
+   printf("failed to init phy (ret=%d)\n", ret);
+   return ret;
+   }
+
+   ret = generic_phy_power_on(&priv->phy);
+   if (ret) {
+   printf("failed to power on phy (ret=%d)\n", ret);
+   return ret;
+   }
+
+   return 0;
+}
+
+static void rk3328_dw_hdmi_setup_hpd(struct dw_hdmi *hdmi)
+{
+   struct rk_hdmi_priv *priv = container_of(hdmi, struct rk_hdmi_priv, 
hdmi);
+   struct rk3328_grf_regs *grf = priv->grf;
+
+   writel(RK3328_IO_DDC_IN_MSK, &grf->soc_con[2]);
+   writel(RK3328_IO_CTRL_BY_HDMI, &grf->soc_con[3]);
+}
+
+static void rk3328_dw_hdmi_read_hpd(struct dw_hdmi *hdmi, bool hpd_status)
+{
+   struct rk_hdmi_priv *priv = container_of(hdmi, struct rk_hdmi_priv, 
hdmi);
+   struct rk3328_grf_regs *grf = priv->grf;
+
+   if (hpd_status)
+   writel(RK3328_IO_5V_DOMAIN, &grf->soc_con[4]);
+   else
+   writel(RK3328_IO_3V_DOMAIN, &grf->soc_con[4]);
+}
+
+static const struct dw_hdmi_phy_ops dw_hdmi_rk3328_phy_ops = {
+   .phy_set = rk3328_dw_hdmi_phy_cfg,
+   .setup_hpd = rk3328_dw_hdmi_setup_hpd,
+   .read_hpd = rk3328_dw_hdmi_read_hpd,
+};
+
+static const struct dw_hdmi_plat_data dw_hdmi_rk3328_plat_data = {
+   .phy_force_vendor = true,
+   .phy_ops = &dw_hdmi_rk3328_phy_ops,
+};
+
+static int rk3328_hdmi_of_to_plat(struct udevice *dev)
+{
+   struct rk_hdmi_priv *priv = dev_get_priv(dev);
+   struct dw_hdmi *hdmi = &priv->hdmi;
+
+   hdmi->i2c_clk_high = 0x71;
+   hdmi->i2c_clk_low = 0x76;
+
+   rk_hdmi_of_to_plat(dev);
+
+   hdmi->data = &dw_hdmi_rk3328_plat_data;
+
+   return 0;
+}
+
+static int rk3328_hdmi_probe(struct udevice *dev)
+{
+   struct rk_hdmi_priv *priv = dev_get_priv(dev);
+   int ret;
+
+   ret = generic_phy_get_by_name(dev, "hdmi", &priv->phy);
+   if (ret) {
+   printf("failed to get hdmi phy\n");
+   return ret;
+   };
+
+   ret = rk_hdmi_probe(dev);
+   if (ret) {
+   printf("failed to probe rk hdmi\n");
+   return ret;
+   }
+
+   return 0;
+}
+
+static const struct dm_display_ops rk3328_hdmi_ops = {
+   .read_edid = rk_hdmi_read_edid,
+   .enable = rk3328_hdmi_enable,
+};
+
+static const struct udevice_id rk3328_hdmi_ids[] = {
+   { .compatible = "rockchip,rk3328-dw-hdmi" },
+   { }
+};
+
+U_BOOT_DRIVER(rk3328_hdmi_rockchip) = {
+   .name = "rk3328_hdmi_rockchip",
+   .id = UCLASS_DISPLAY,
+   .of_match = rk3328_hdmi_ids,
+   .ops = &rk3328_hdmi_ops,
+   .of_to_plat = rk3328_hdmi_of_to_plat,
+   .probe = rk3328_hdmi_probe,
+   .priv_auto  = sizeof(struct rk_hdmi_priv),
+};
diff --git a/drivers/video/rockchip/rk_hdmi.h b/drivers/video/rockchip/

[PATCH v2 11/17] phy: rockchip: Add Rockchip INNO HDMI PHY driver

2023-12-18 Thread Jagan Teki
From: Jagan Teki 

Add Rockchip INNO HDMI PHY driver for RK3328.

Reference from linux-next phy-rockchip-inno-hdmi driver.

Signed-off-by: Jagan Teki 
---
Changes for v2:
- none

 drivers/phy/rockchip/Kconfig  |   7 +
 drivers/phy/rockchip/Makefile |   1 +
 drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 885 ++
 3 files changed, 893 insertions(+)
 create mode 100644 drivers/phy/rockchip/phy-rockchip-inno-hdmi.c

diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
index 0247d93ab4..80128335d5 100644
--- a/drivers/phy/rockchip/Kconfig
+++ b/drivers/phy/rockchip/Kconfig
@@ -12,6 +12,13 @@ config PHY_ROCKCHIP_INNO_DSIDPHY
help
  Support for Rockchip MIPI DPHY with Innosilicon IP block.
 
+config PHY_ROCKCHIP_INNO_HDMI
+   bool "Rockchip INNO HDMI PHY Driver"
+   depends on ARCH_ROCKCHIP
+   select PHY
+   help
+ Enable this to support the Rockchip Innosilicon HDMI PHY.
+
 config PHY_ROCKCHIP_INNO_USB2
bool "Rockchip INNO USB2PHY Driver"
depends on ARCH_ROCKCHIP
diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile
index 7fdbd10797..0420017425 100644
--- a/drivers/phy/rockchip/Makefile
+++ b/drivers/phy/rockchip/Makefile
@@ -3,6 +3,7 @@
 # Copyright (C) 2020 Amarula Solutions(India)
 #
 
+obj-$(CONFIG_PHY_ROCKCHIP_INNO_HDMI)   += phy-rockchip-inno-hdmi.o
 obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2)   += phy-rockchip-inno-usb2.o
 obj-$(CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY) += phy-rockchip-naneng-combphy.o
 obj-$(CONFIG_PHY_ROCKCHIP_PCIE)+= phy-rockchip-pcie.o
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c 
b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
new file mode 100644
index 00..3bb1a254ff
--- /dev/null
+++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
@@ -0,0 +1,885 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Rockchip Innosilicon HDMI PHY
+ *
+ * Copyright (c) 2023 Edgeble AI Technologies Pvt. Ltd.
+ * Copyright (c) 2017 Rockchip Electronics Co. Ltd.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define UPDATE(x, h, l)(((x) << (l)) & GENMASK((h), (l)))
+
+/* REG: 0x01 */
+#define RK3328_BYPASS_RXSENSE_EN   BIT(2)
+#define RK3328_BYPASS_POWERON_EN   BIT(1)
+#define RK3328_BYPASS_PLLPD_EN BIT(0)
+/* REG: 0x02 */
+#define RK3328_INT_POL_HIGHBIT(7)
+#define RK3328_BYPASS_PDATA_EN BIT(4)
+#define RK3328_PDATA_ENBIT(0)
+/* REG:0x05 */
+#define RK3328_INT_TMDS_CLK(x) UPDATE(x, 7, 4)
+#define RK3328_INT_TMDS_D2(x)  UPDATE(x, 3, 0)
+/* REG:0x07 */
+#define RK3328_INT_TMDS_D1(x)  UPDATE(x, 7, 4)
+#define RK3328_INT_TMDS_D0(x)  UPDATE(x, 3, 0)
+/* for all RK3328_INT_TMDS_*, ESD_DET as defined in 0xc8-0xcb */
+#define RK3328_INT_AGND_LOW_PULSE_LOCKED   BIT(3)
+#define RK3328_INT_RXSENSE_LOW_PULSE_LOCKEDBIT(2)
+#define RK3328_INT_VSS_AGND_ESD_DETBIT(1)
+#define RK3328_INT_AGND_VSS_ESD_DETBIT(0)
+/* REG: 0xa0 */
+#define RK3328_PCLK_VCO_DIV_5_MASK BIT(1)
+#define RK3328_PCLK_VCO_DIV_5(x)   UPDATE(x, 1, 1)
+#define RK3328_PRE_PLL_POWER_DOWN  BIT(0)
+/* REG: 0xa1 */
+#define RK3328_PRE_PLL_PRE_DIV_MASKGENMASK(5, 0)
+#define RK3328_PRE_PLL_PRE_DIV(x)  UPDATE(x, 5, 0)
+/* REG: 0xa2 */
+/* unset means center spread */
+#define RK3328_SPREAD_SPECTRUM_MOD_DOWNBIT(7)
+#define RK3328_SPREAD_SPECTRUM_MOD_DISABLE BIT(6)
+#define RK3328_PRE_PLL_FRAC_DIV_DISABLEUPDATE(3, 5, 4)
+#define RK3328_PRE_PLL_FB_DIV_11_8_MASKGENMASK(3, 0)
+#define RK3328_PRE_PLL_FB_DIV_11_8(x)  UPDATE((x) >> 8, 3, 0)
+/* REG: 0xa3 */
+#define RK3328_PRE_PLL_FB_DIV_7_0(x)   UPDATE(x, 7, 0)
+/* REG: 0xa4*/
+#define RK3328_PRE_PLL_TMDSCLK_DIV_C_MASK  GENMASK(1, 0)
+#define RK3328_PRE_PLL_TMDSCLK_DIV_C(x)UPDATE(x, 1, 0)
+#define RK3328_PRE_PLL_TMDSCLK_DIV_B_MASK  GENMASK(3, 2)
+#define RK3328_PRE_PLL_TMDSCLK_DIV_B(x)UPDATE(x, 3, 2)
+#define RK3328_PRE_PLL_TMDSCLK_DIV_A_MASK  GENMASK(5, 4)
+#define RK3328_PRE_PLL_TMDSCLK_DIV_A(x)UPDATE(x, 5, 4)
+/* REG: 0xa5 */
+#define RK3328_PRE_PLL_PCLK_DIV_B_SHIFT5
+#define RK3328_PRE_PLL_PCLK_DIV_B_MASK GENMASK(6, 5)
+#define RK3328_PRE_PLL_PCLK_DIV_B(x)   UPDATE(x, 6, 5)
+#define RK3328_PRE_PLL_PCLK_DIV_A_MASK GENMASK(4, 0)
+#define RK3328_PRE_PLL_PCLK_DIV_A(x

[PATCH v2 10/17] clk: rk3328: Add get hdmiphy clock

2023-12-18 Thread Jagan Teki
From: Jagan Teki 

Add support to get the hdmiphy clock for RK3328 PCLK_HDMIPHY.

Signed-off-by: Jagan Teki 
---
Changes for v2:
- none

 drivers/clk/rockchip/clk_rk3328.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/drivers/clk/rockchip/clk_rk3328.c 
b/drivers/clk/rockchip/clk_rk3328.c
index ee7edb9d10..5bb9238abb 100644
--- a/drivers/clk/rockchip/clk_rk3328.c
+++ b/drivers/clk/rockchip/clk_rk3328.c
@@ -179,6 +179,10 @@ enum {
CLK_I2C3_DIV_CON_SHIFT  = 8,
CLK_I2C2_PLL_SEL_SHIFT  = 7,
CLK_I2C2_DIV_CON_SHIFT  = 0,
+
+   /* CLKSEL_CON40 */
+   CLK_HDMIPHY_DIV_CON_SHIFT   = 3,
+   CLK_HDMIPHY_DIV_CON_MASK= 0x7 << CLK_HDMIPHY_DIV_CON_SHIFT,
 };
 
 #define VCO_MAX_KHZ(3200 * (MHz / KHz))
@@ -661,6 +665,16 @@ static ulong rk3328_vop_set_clk(struct rk3328_clk_priv 
*priv,
 }
 #endif
 
+static ulong rk3328_hdmiphy_get_clk(struct rk3328_cru *cru)
+{
+   u32 div, con;
+
+   con = readl(&cru->clksel_con[40]);
+   div = (con & CLK_HDMIPHY_DIV_CON_MASK) >> CLK_HDMIPHY_DIV_CON_SHIFT;
+
+   return DIV_TO_RATE(GPLL_HZ, div);
+}
+
 static ulong rk3328_clk_get_rate(struct clk *clk)
 {
struct rk3328_clk_priv *priv = dev_get_priv(clk->dev);
@@ -690,6 +704,9 @@ static ulong rk3328_clk_get_rate(struct clk *clk)
case SCLK_SPI:
rate = rk3328_spi_get_clk(priv->cru);
break;
+   case PCLK_HDMIPHY:
+   rate = rk3328_hdmiphy_get_clk(priv->cru);
+   break;
default:
return -ENOENT;
}
-- 
2.25.1



[PATCH v2 09/17] clk: rockchip: rk3328: Add VOP clk support

2023-12-18 Thread Jagan Teki
From: Jagan Teki 

VOP get and set clock would needed for VOP drivers.

Add support for it.

Signed-off-by: Jagan Teki 
---
Changes for v2:
- Add DCLK get rate

 .../include/asm/arch-rockchip/cru_rk3328.h| 34 +++
 drivers/clk/rockchip/clk_rk3328.c | 88 ++-
 2 files changed, 120 insertions(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3328.h 
b/arch/arm/include/asm/arch-rockchip/cru_rk3328.h
index 226744d67d..4ad1d33e05 100644
--- a/arch/arm/include/asm/arch-rockchip/cru_rk3328.h
+++ b/arch/arm/include/asm/arch-rockchip/cru_rk3328.h
@@ -62,6 +62,40 @@ check_member(rk3328_cru, sdmmc_ext_con[1], 0x39c);
 enum apll_frequencies {
APLL_816_MHZ,
APLL_600_MHZ,
+
+   /* CRU_CLK_SEL37_CON */
+   ACLK_VIO_PLL_SEL_CPLL   = 0,
+   ACLK_VIO_PLL_SEL_GPLL   = 1,
+   ACLK_VIO_PLL_SEL_HDMIPHY= 2,
+   ACLK_VIO_PLL_SEL_USB480M= 3,
+   ACLK_VIO_PLL_SEL_SHIFT  = 6,
+   ACLK_VIO_PLL_SEL_MASK   = 3 << ACLK_VIO_PLL_SEL_SHIFT,
+   ACLK_VIO_DIV_CON_SHIFT  = 0,
+   ACLK_VIO_DIV_CON_MASK   = 0x1f << ACLK_VIO_DIV_CON_SHIFT,
+   HCLK_VIO_DIV_CON_SHIFT  = 8,
+   HCLK_VIO_DIV_CON_MASK   = 0x1f << HCLK_VIO_DIV_CON_SHIFT,
+
+   /* CRU_CLK_SEL39_CON */
+   ACLK_VOP_PLL_SEL_CPLL   = 0,
+   ACLK_VOP_PLL_SEL_GPLL   = 1,
+   ACLK_VOP_PLL_SEL_HDMIPHY= 2,
+   ACLK_VOP_PLL_SEL_USB480M= 3,
+   ACLK_VOP_PLL_SEL_SHIFT  = 6,
+   ACLK_VOP_PLL_SEL_MASK   = 3 << ACLK_VOP_PLL_SEL_SHIFT,
+   ACLK_VOP_DIV_CON_SHIFT  = 0,
+   ACLK_VOP_DIV_CON_MASK   = 0x1f << ACLK_VOP_DIV_CON_SHIFT,
+
+   /* CRU_CLK_SEL40_CON */
+   DCLK_LCDC_PLL_SEL_GPLL  = 0,
+   DCLK_LCDC_PLL_SEL_CPLL  = 1,
+   DCLK_LCDC_PLL_SEL_SHIFT = 0,
+   DCLK_LCDC_PLL_SEL_MASK  = 1 << DCLK_LCDC_PLL_SEL_SHIFT,
+   DCLK_LCDC_SEL_HDMIPHY   = 0,
+   DCLK_LCDC_SEL_PLL   = 1,
+   DCLK_LCDC_SEL_SHIFT = 1,
+   DCLK_LCDC_SEL_MASK  = 1 << DCLK_LCDC_SEL_SHIFT,
+   DCLK_LCDC_DIV_CON_SHIFT = 8,
+   DCLK_LCDC_DIV_CON_MASK  = 0xFf << DCLK_LCDC_DIV_CON_SHIFT,
 };
 
 void rk3328_configure_cpu(struct rk3328_cru *cru,
diff --git a/drivers/clk/rockchip/clk_rk3328.c 
b/drivers/clk/rockchip/clk_rk3328.c
index ef97381f0e..ee7edb9d10 100644
--- a/drivers/clk/rockchip/clk_rk3328.c
+++ b/drivers/clk/rockchip/clk_rk3328.c
@@ -581,6 +581,86 @@ static ulong rk3328_spi_set_clk(struct rk3328_cru *cru, 
uint hz)
return rk3328_spi_get_clk(cru);
 }
 
+#ifndef CONFIG_SPL_BUILD
+static ulong rk3328_vop_get_clk(struct rk3328_clk_priv *priv, ulong clk_id)
+{
+   struct rk3328_cru *cru = priv->cru;
+   u32 div, con, parent;
+
+   switch (clk_id) {
+   case ACLK_VOP_PRE:
+   con = readl(&cru->clksel_con[39]);
+   div = (con & ACLK_VOP_DIV_CON_MASK) >> ACLK_VOP_DIV_CON_SHIFT;
+   parent = GPLL_HZ;
+   break;
+   case ACLK_VIO_PRE:
+   con = readl(&cru->clksel_con[37]);
+   div = (con & ACLK_VIO_DIV_CON_MASK) >> ACLK_VIO_DIV_CON_SHIFT;
+   parent = GPLL_HZ;
+   break;
+   case DCLK_LCDC:
+   con = readl(&cru->clksel_con[40]);
+   div = (con & DCLK_LCDC_DIV_CON_MASK) >> DCLK_LCDC_DIV_CON_SHIFT;
+   parent = GPLL_HZ;
+   break;
+   default:
+   printf("%s: Unsupported vop get clk#%ld\n", __func__, clk_id);
+   return -ENOENT;
+   }
+
+   return DIV_TO_RATE(parent, div);
+}
+
+static ulong rk3328_vop_set_clk(struct rk3328_clk_priv *priv,
+   ulong clk_id, uint hz)
+{
+   struct rk3328_cru *cru = priv->cru;
+   int src_clk_div;
+   u32 con, parent;
+
+   src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz);
+   assert(src_clk_div - 1 < 31);
+
+   switch (clk_id) {
+   case ACLK_VOP_PRE:
+   rk_clrsetreg(&cru->clksel_con[39],
+ACLK_VOP_PLL_SEL_MASK | ACLK_VOP_DIV_CON_MASK,
+ACLK_VOP_PLL_SEL_CPLL << ACLK_VOP_PLL_SEL_SHIFT |
+(src_clk_div - 1) << ACLK_VOP_DIV_CON_SHIFT);
+   break;
+   case ACLK_VIO_PRE:
+   rk_clrsetreg(&cru->clksel_con[37],
+ACLK_VIO_PLL_SEL_MASK | ACLK_VIO_DIV_CON_MASK,
+ACLK_VIO_PLL_SEL_CPLL << ACLK_VIO_PLL_SEL_SHIFT |
+(src_clk_div - 1) << ACLK_VIO_DIV_CON_SHIFT);
+   break;
+   case DCLK_LCDC:
+   con = readl(&cru->clksel_con[40]);
+   con = (con & DCLK_LCDC_SEL_MASK) >> DCLK_LCDC_SEL_SHIFT;
+   if (con) {
+   parent = readl(&cru->clksel_con[40]);
+ 

[PATCH v2 08/17] video: rockchip: vop: Add dsp offset support

2023-12-18 Thread Jagan Teki
From: Jagan Teki 

Unlike RK3399, RK3288 the Newer Rockchip SoC's like RK3328 have
different offsets for dsp registers.

Group the dsp register set via dsp_regs pointers so that dsp_offset
would point the dsp_regs to access for any changes in the offset value.

Signed-off-by: Jagan Teki 
---
Changes for v2:
- none

 drivers/video/rockchip/rk_vop.c | 14 --
 drivers/video/rockchip/rk_vop.h |  2 ++
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/video/rockchip/rk_vop.c b/drivers/video/rockchip/rk_vop.c
index b719a4e4ea..acc02e5d7c 100644
--- a/drivers/video/rockchip/rk_vop.c
+++ b/drivers/video/rockchip/rk_vop.c
@@ -165,6 +165,7 @@ static void rkvop_mode_set(struct udevice *dev,
 {
struct rk_vop_priv *priv = dev_get_priv(dev);
struct rk3288_vop *regs = priv->regs;
+   struct rk3288_vop *dsp_regs = priv->regs + priv->dsp_offset;
struct rkvop_driverdata *data =
(struct rkvop_driverdata *)dev_get_driver_data(dev);
 
@@ -198,27 +199,27 @@ static void rkvop_mode_set(struct udevice *dev,
 
writel(V_HSYNC(hsync_len) |
   V_HORPRD(hsync_len + hback_porch + hactive + hfront_porch),
-   ®s->dsp_htotal_hs_end);
+   &dsp_regs->dsp_htotal_hs_end);
 
writel(V_HEAP(hsync_len + hback_porch + hactive) |
   V_HASP(hsync_len + hback_porch),
-  ®s->dsp_hact_st_end);
+  &dsp_regs->dsp_hact_st_end);
 
writel(V_VSYNC(vsync_len) |
   V_VERPRD(vsync_len + vback_porch + vactive + vfront_porch),
-  ®s->dsp_vtotal_vs_end);
+  &dsp_regs->dsp_vtotal_vs_end);
 
writel(V_VAEP(vsync_len + vback_porch + vactive)|
   V_VASP(vsync_len + vback_porch),
-  ®s->dsp_vact_st_end);
+  &dsp_regs->dsp_vact_st_end);
 
writel(V_HEAP(hsync_len + hback_porch + hactive) |
   V_HASP(hsync_len + hback_porch),
-  ®s->post_dsp_hact_info);
+  &dsp_regs->post_dsp_hact_info);
 
writel(V_VAEP(vsync_len + vback_porch + vactive)|
   V_VASP(vsync_len + vback_porch),
-  ®s->post_dsp_vact_info);
+  &dsp_regs->post_dsp_vact_info);
 
writel(0x01, ®s->reg_cfg_done); /* enable reg config */
 }
@@ -452,6 +453,7 @@ int rk_vop_probe(struct udevice *dev)
 
priv->regs = dev_read_addr_ptr(dev);
priv->win_offset = ops->win_offset;
+   priv->dsp_offset = ops->dsp_offset;
 
/*
 * Try all the ports until we find one that works. In practice this
diff --git a/drivers/video/rockchip/rk_vop.h b/drivers/video/rockchip/rk_vop.h
index 909f5602e5..eba68d87c4 100644
--- a/drivers/video/rockchip/rk_vop.h
+++ b/drivers/video/rockchip/rk_vop.h
@@ -12,6 +12,7 @@ struct rk_vop_priv {
void *grf;
void *regs;
int win_offset;
+   int dsp_offset;
 };
 
 enum vop_features {
@@ -20,6 +21,7 @@ enum vop_features {
 
 struct rkvop_driverdata {
int win_offset;
+   int dsp_offset;
/* configuration */
u32 features;
/* block-specific setters/getters */
-- 
2.25.1



[PATCH v2 07/17] video: rockchip: vop: Add win offset support

2023-12-18 Thread Jagan Teki
From: Jagan Teki 

Unlike RK3399, RK3288 the Newer Rockchip SoC's like RK3328 have
different offsets for win registers.

Group the win register set via win_regs pointers so that win_offset
would point the win_regs to access for any changes in the offset value.

Signed-off-by: Jagan Teki 
---
Changes for v2:
- none

 drivers/video/rockchip/rk_vop.c | 22 +-
 drivers/video/rockchip/rk_vop.h |  2 ++
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/video/rockchip/rk_vop.c b/drivers/video/rockchip/rk_vop.c
index 158ba7cbf6..b719a4e4ea 100644
--- a/drivers/video/rockchip/rk_vop.c
+++ b/drivers/video/rockchip/rk_vop.c
@@ -46,6 +46,7 @@ static void rkvop_enable(struct udevice *dev, ulong fbbase,
 {
struct rk_vop_priv *priv = dev_get_priv(dev);
struct rk3288_vop *regs = priv->regs;
+   struct rk3288_vop *win_regs = priv->regs + priv->win_offset;
u32 lb_mode;
u32 rgb_mode;
u32 hactive = edid->hactive.typ;
@@ -53,32 +54,32 @@ static void rkvop_enable(struct udevice *dev, ulong fbbase,
int ret;
 
writel(V_ACT_WIDTH(hactive - 1) | V_ACT_HEIGHT(vactive - 1),
-  ®s->win0_act_info);
+  &win_regs->win0_act_info);
 
writel(V_DSP_XST(edid->hsync_len.typ + edid->hback_porch.typ) |
   V_DSP_YST(edid->vsync_len.typ + edid->vback_porch.typ),
-  ®s->win0_dsp_st);
+  &win_regs->win0_dsp_st);
 
writel(V_DSP_WIDTH(hactive - 1) |
V_DSP_HEIGHT(vactive - 1),
-   ®s->win0_dsp_info);
+   &win_regs->win0_dsp_info);
 
-   clrsetbits_le32(®s->win0_color_key, M_WIN0_KEY_EN | M_WIN0_KEY_COLOR,
+   clrsetbits_le32(&win_regs->win0_color_key, M_WIN0_KEY_EN | 
M_WIN0_KEY_COLOR,
V_WIN0_KEY_EN(0) | V_WIN0_KEY_COLOR(0));
 
switch (fb_bits_per_pixel) {
case 16:
rgb_mode = RGB565;
-   writel(V_RGB565_VIRWIDTH(hactive), ®s->win0_vir);
+   writel(V_RGB565_VIRWIDTH(hactive), &win_regs->win0_vir);
break;
case 24:
rgb_mode = RGB888;
-   writel(V_RGB888_VIRWIDTH(hactive), ®s->win0_vir);
+   writel(V_RGB888_VIRWIDTH(hactive), &win_regs->win0_vir);
break;
case 32:
default:
rgb_mode = ARGB;
-   writel(V_ARGB888_VIRWIDTH(hactive), ®s->win0_vir);
+   writel(V_ARGB888_VIRWIDTH(hactive), &win_regs->win0_vir);
break;
}
 
@@ -91,12 +92,12 @@ static void rkvop_enable(struct udevice *dev, ulong fbbase,
else
lb_mode = LB_RGB_1280X8;
 
-   clrsetbits_le32(®s->win0_ctrl0,
+   clrsetbits_le32(&win_regs->win0_ctrl0,
M_WIN0_LB_MODE | M_WIN0_DATA_FMT | M_WIN0_EN,
V_WIN0_LB_MODE(lb_mode) | V_WIN0_DATA_FMT(rgb_mode) |
V_WIN0_EN(1));
 
-   writel(fbbase, ®s->win0_yrgb_mst);
+   writel(fbbase, &win_regs->win0_yrgb_mst);
writel(0x01, ®s->reg_cfg_done); /* enable reg config */
 
ret = reset_assert(dclk_rst);
@@ -415,6 +416,8 @@ int rk_vop_probe(struct udevice *dev)
 {
struct video_uc_plat *plat = dev_get_uclass_plat(dev);
struct rk_vop_priv *priv = dev_get_priv(dev);
+   struct rkvop_driverdata *ops =
+   (struct rkvop_driverdata *)dev_get_driver_data(dev);
int ret = 0;
ofnode port, node;
struct reset_ctl ahb_rst;
@@ -448,6 +451,7 @@ int rk_vop_probe(struct udevice *dev)
 #endif
 
priv->regs = dev_read_addr_ptr(dev);
+   priv->win_offset = ops->win_offset;
 
/*
 * Try all the ports until we find one that works. In practice this
diff --git a/drivers/video/rockchip/rk_vop.h b/drivers/video/rockchip/rk_vop.h
index 0528fb23f5..909f5602e5 100644
--- a/drivers/video/rockchip/rk_vop.h
+++ b/drivers/video/rockchip/rk_vop.h
@@ -11,6 +11,7 @@
 struct rk_vop_priv {
void *grf;
void *regs;
+   int win_offset;
 };
 
 enum vop_features {
@@ -18,6 +19,7 @@ enum vop_features {
 };
 
 struct rkvop_driverdata {
+   int win_offset;
/* configuration */
u32 features;
/* block-specific setters/getters */
-- 
2.25.1



[PATCH v2 06/17] video: rockchip: vop: Simplify rkvop_enable

2023-12-18 Thread Jagan Teki
From: Jagan Teki 

Get the regs from priv pointer instead of passing it an argument.

This would simplify the code and better readability.

Signed-off-by: Jagan Teki 
---
Changes for v2:
- none

 drivers/video/rockchip/rk_vop.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/video/rockchip/rk_vop.c b/drivers/video/rockchip/rk_vop.c
index c514e2a0e4..158ba7cbf6 100644
--- a/drivers/video/rockchip/rk_vop.c
+++ b/drivers/video/rockchip/rk_vop.c
@@ -39,11 +39,13 @@ enum vop_pol {
DCLK_INVERT= 3
 };
 
-static void rkvop_enable(struct udevice *dev, struct rk3288_vop *regs, ulong 
fbbase,
+static void rkvop_enable(struct udevice *dev, ulong fbbase,
 int fb_bits_per_pixel,
 const struct display_timing *edid,
 struct reset_ctl *dclk_rst)
 {
+   struct rk_vop_priv *priv = dev_get_priv(dev);
+   struct rk3288_vop *regs = priv->regs;
u32 lb_mode;
u32 rgb_mode;
u32 hactive = edid->hactive.typ;
@@ -243,9 +245,7 @@ static void rkvop_mode_set(struct udevice *dev,
 static int rk_display_init(struct udevice *dev, ulong fbbase, ofnode ep_node)
 {
struct video_priv *uc_priv = dev_get_uclass_priv(dev);
-   struct rk_vop_priv *priv = dev_get_priv(dev);
int vop_id, remote_vop_id;
-   struct rk3288_vop *regs = priv->regs;
struct display_timing timing;
struct udevice *disp;
int ret;
@@ -380,7 +380,7 @@ static int rk_display_init(struct udevice *dev, ulong 
fbbase, ofnode ep_node)
return ret;
}
 
-   rkvop_enable(dev, regs, fbbase, 1 << l2bpp, &timing, &dclk_rst);
+   rkvop_enable(dev, fbbase, 1 << l2bpp, &timing, &dclk_rst);
 
ret = display_enable(disp, 1 << l2bpp, &timing);
if (ret)
-- 
2.25.1



[PATCH v2 05/17] video: dw_hdmi: Add setup_hpd hook

2023-12-18 Thread Jagan Teki
From: Jagan Teki 

Add support for DW HDMI Setup HPD status.

Signed-off-by: Jagan Teki 
---
Changes for v2:
- none

 drivers/video/dw_hdmi.c | 3 +++
 include/dw_hdmi.h   | 1 +
 2 files changed, 4 insertions(+)

diff --git a/drivers/video/dw_hdmi.c b/drivers/video/dw_hdmi.c
index 172e6b45a6..3e0e20e59b 100644
--- a/drivers/video/dw_hdmi.c
+++ b/drivers/video/dw_hdmi.c
@@ -1080,4 +1080,7 @@ void dw_hdmi_init(struct dw_hdmi *hdmi)
 
/* enable i2c client nack % arbitration error irq */
hdmi_write(hdmi, ~0x44, HDMI_I2CM_CTLINT);
+
+   if (hdmi->ops->setup_hpd)
+   hdmi->ops->setup_hpd(hdmi);
 }
diff --git a/include/dw_hdmi.h b/include/dw_hdmi.h
index d6de472cee..9a44b9e90c 100644
--- a/include/dw_hdmi.h
+++ b/include/dw_hdmi.h
@@ -539,6 +539,7 @@ struct dw_hdmi;
 struct dw_hdmi_phy_ops {
int (*phy_set)(struct dw_hdmi *hdmi, uint mpixelclock);
void (*read_hpd)(struct dw_hdmi *hdmi, bool hdp_status);
+   void (*setup_hpd)(struct dw_hdmi *hdmi);
 };
 
 struct dw_hdmi_plat_data {
-- 
2.25.1



[PATCH v2 04/17] video: dw_hdmi: Add read_hpd hook

2023-12-18 Thread Jagan Teki
From: Jagan Teki 

Add support for DW HDMI Read HPD status.

Signed-off-by: Jagan Teki 
---
Changes for v2:
- none

 drivers/video/dw_hdmi.c | 3 +++
 include/dw_hdmi.h   | 1 +
 2 files changed, 4 insertions(+)

diff --git a/drivers/video/dw_hdmi.c b/drivers/video/dw_hdmi.c
index 0a597206f0..172e6b45a6 100644
--- a/drivers/video/dw_hdmi.c
+++ b/drivers/video/dw_hdmi.c
@@ -946,6 +946,9 @@ int dw_hdmi_detect_hpd(struct dw_hdmi *hdmi)
return -ENODEV;
}
 
+   if (hdmi->ops->read_hpd)
+   hdmi->ops->read_hpd(hdmi, true);
+
return 0;
 }
 
diff --git a/include/dw_hdmi.h b/include/dw_hdmi.h
index 756560e092..d6de472cee 100644
--- a/include/dw_hdmi.h
+++ b/include/dw_hdmi.h
@@ -538,6 +538,7 @@ struct dw_hdmi;
 
 struct dw_hdmi_phy_ops {
int (*phy_set)(struct dw_hdmi *hdmi, uint mpixelclock);
+   void (*read_hpd)(struct dw_hdmi *hdmi, bool hdp_status);
 };
 
 struct dw_hdmi_plat_data {
-- 
2.25.1



[PATCH v2 03/17] video: dw_hdmi: Extend the HPD detection

2023-12-18 Thread Jagan Teki
From: Jagan Teki 

HPD detection on some DW HDMIdesigned SoC's would need to read and
setup the HPD status explicitly.

So, extend the HPD detection code by adding the dw_hdmi_detect_hpd
function and move the default detection code caller there.

The new read and setup hdp will integrate the same function in
later patches.

Signed-off-by: Jagan Teki 
---
Changes for v2:
- none

 drivers/video/dw_hdmi.c | 13 +
 drivers/video/rockchip/rk_hdmi.c|  8 +++-
 drivers/video/sunxi/sunxi_dw_hdmi.c |  8 +++-
 include/dw_hdmi.h   |  1 +
 4 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/drivers/video/dw_hdmi.c b/drivers/video/dw_hdmi.c
index ea12a09407..0a597206f0 100644
--- a/drivers/video/dw_hdmi.c
+++ b/drivers/video/dw_hdmi.c
@@ -936,6 +936,19 @@ int dw_hdmi_phy_wait_for_hpd(struct dw_hdmi *hdmi)
return -1;
 }
 
+int dw_hdmi_detect_hpd(struct dw_hdmi *hdmi)
+{
+   int ret;
+
+   ret = dw_hdmi_phy_wait_for_hpd(hdmi);
+   if (ret < 0) {
+   debug("hdmi can not get hpd signal\n");
+   return -ENODEV;
+   }
+
+   return 0;
+}
+
 void dw_hdmi_phy_init(struct dw_hdmi *hdmi)
 {
/* enable phy i2cm done irq */
diff --git a/drivers/video/rockchip/rk_hdmi.c b/drivers/video/rockchip/rk_hdmi.c
index e34f532cd6..8a65f2440e 100644
--- a/drivers/video/rockchip/rk_hdmi.c
+++ b/drivers/video/rockchip/rk_hdmi.c
@@ -115,11 +115,9 @@ int rk_hdmi_probe(struct udevice *dev)
dw_hdmi_init(hdmi);
dw_hdmi_phy_init(hdmi);
 
-   ret = dw_hdmi_phy_wait_for_hpd(hdmi);
-   if (ret < 0) {
-   debug("hdmi can not get hpd signal\n");
-   return -1;
-   }
+   ret = dw_hdmi_detect_hpd(hdmi);
+   if (ret < 0)
+   return ret;
 
return 0;
 }
diff --git a/drivers/video/sunxi/sunxi_dw_hdmi.c 
b/drivers/video/sunxi/sunxi_dw_hdmi.c
index 4b67a1614e..513276d812 100644
--- a/drivers/video/sunxi/sunxi_dw_hdmi.c
+++ b/drivers/video/sunxi/sunxi_dw_hdmi.c
@@ -358,11 +358,9 @@ static int sunxi_dw_hdmi_probe(struct udevice *dev)
 
sunxi_dw_hdmi_phy_init(&priv->hdmi);
 
-   ret = dw_hdmi_phy_wait_for_hpd(&priv->hdmi);
-   if (ret < 0) {
-   debug("hdmi can not get hpd signal\n");
-   return -1;
-   }
+   ret = dw_hdmi_detect_hpd(&priv->hdmi);
+   if (ret < 0)
+   return ret;
 
dw_hdmi_init(&priv->hdmi);
 
diff --git a/include/dw_hdmi.h b/include/dw_hdmi.h
index 4ad8b39f84..756560e092 100644
--- a/include/dw_hdmi.h
+++ b/include/dw_hdmi.h
@@ -568,5 +568,6 @@ void dw_hdmi_phy_init(struct dw_hdmi *hdmi);
 int dw_hdmi_enable(struct dw_hdmi *hdmi, const struct display_timing *edid);
 int dw_hdmi_read_edid(struct dw_hdmi *hdmi, u8 *buf, int buf_size);
 void dw_hdmi_init(struct dw_hdmi *hdmi);
+int dw_hdmi_detect_hpd(struct dw_hdmi *hdmi);
 
 #endif
-- 
2.25.1



[PATCH v2 02/17] video: dw_hdmi: Add Vendor PHY handling

2023-12-18 Thread Jagan Teki
From: Jagan Teki 

DW HDMI support Vendor PHY like Rockchip RK3328 Inno HDMI PHY.

Extend the vendor phy handling by adding platform phy hooks.

Signed-off-by: Jagan Teki 
---
Changes for v2:
- fix meson cfg

 drivers/video/dw_hdmi.c  | 29 +++-
 drivers/video/meson/meson_dw_hdmi.c  | 11 ++-
 drivers/video/rockchip/rk3399_hdmi.c |  8 +++-
 drivers/video/rockchip/rk_hdmi.c |  2 +-
 drivers/video/sunxi/sunxi_dw_hdmi.c  | 11 ++-
 include/dw_hdmi.h| 14 +-
 6 files changed, 69 insertions(+), 6 deletions(-)

diff --git a/drivers/video/dw_hdmi.c b/drivers/video/dw_hdmi.c
index c4fbb18294..ea12a09407 100644
--- a/drivers/video/dw_hdmi.c
+++ b/drivers/video/dw_hdmi.c
@@ -988,7 +988,7 @@ int dw_hdmi_enable(struct dw_hdmi *hdmi, const struct 
display_timing *edid)
 
hdmi_av_composer(hdmi, edid);
 
-   ret = hdmi->phy_set(hdmi, edid->pixelclock.typ);
+   ret = hdmi->ops->phy_set(hdmi, edid->pixelclock.typ);
if (ret)
return ret;
 
@@ -1009,10 +1009,37 @@ int dw_hdmi_enable(struct dw_hdmi *hdmi, const struct 
display_timing *edid)
return 0;
 }
 
+static const struct dw_hdmi_phy_ops dw_hdmi_synopsys_phy_ops = {
+   .phy_set = dw_hdmi_phy_cfg,
+};
+
+static void dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
+{
+   if (!hdmi->data)
+   return;
+
+   /* hook Synopsys PHYs ops */
+   if (!hdmi->data->phy_force_vendor) {
+   hdmi->ops = &dw_hdmi_synopsys_phy_ops;
+   return;
+   }
+
+   /* Vendor HDMI PHYs must assign phy_ops in plat_data */
+   if (!hdmi->data->phy_ops) {
+   printf("Unsupported Vendor HDMI phy_ops\n");
+   return;
+   }
+
+   /* hook Vendor HDMI PHYs ops */
+   hdmi->ops = hdmi->data->phy_ops;
+}
+
 void dw_hdmi_init(struct dw_hdmi *hdmi)
 {
uint ih_mute;
 
+   dw_hdmi_detect_phy(hdmi);
+
/*
 * boot up defaults are:
 * hdmi_ih_mute   = 0x03 (disabled)
diff --git a/drivers/video/meson/meson_dw_hdmi.c 
b/drivers/video/meson/meson_dw_hdmi.c
index 5db01904b5..d0d878b6af 100644
--- a/drivers/video/meson/meson_dw_hdmi.c
+++ b/drivers/video/meson/meson_dw_hdmi.c
@@ -375,6 +375,15 @@ static int meson_dw_hdmi_wait_hpd(struct dw_hdmi *hdmi)
return -ETIMEDOUT;
 }
 
+static const struct dw_hdmi_phy_ops dw_hdmi_meson_phy_ops = {
+   .phy_set = meson_dw_hdmi_phy_init,
+};
+
+static const struct dw_hdmi_plat_data dw_hdmi_meson_plat_data = {
+   .phy_force_vendor = true,
+   .phy_ops = &dw_hdmi_meson_phy_ops,
+};
+
 static int meson_dw_hdmi_probe(struct udevice *dev)
 {
struct meson_dw_hdmi *priv = dev_get_priv(dev);
@@ -397,7 +406,7 @@ static int meson_dw_hdmi_probe(struct udevice *dev)
 
priv->hdmi.hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
priv->hdmi.hdmi_data.enc_in_bus_format = MEDIA_BUS_FMT_YUV8_1X24;
-   priv->hdmi.phy_set = meson_dw_hdmi_phy_init;
+   priv->hdmi.data = &dw_hdmi_meson_plat_data;
if (meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_G12A))
priv->hdmi.reg_io_width = 1;
else {
diff --git a/drivers/video/rockchip/rk3399_hdmi.c 
b/drivers/video/rockchip/rk3399_hdmi.c
index 3041360c6e..b32139a8a6 100644
--- a/drivers/video/rockchip/rk3399_hdmi.c
+++ b/drivers/video/rockchip/rk3399_hdmi.c
@@ -64,8 +64,14 @@ static const struct dm_display_ops rk3399_hdmi_ops = {
.enable = rk3399_hdmi_enable,
 };
 
+static const struct dw_hdmi_plat_data rk3399_hdmi_drv_data = {
+};
+
 static const struct udevice_id rk3399_hdmi_ids[] = {
-   { .compatible = "rockchip,rk3399-dw-hdmi" },
+   {
+   .compatible = "rockchip,rk3399-dw-hdmi",
+   .data = (ulong)&rk3399_hdmi_drv_data
+   },
{ }
 };
 
diff --git a/drivers/video/rockchip/rk_hdmi.c b/drivers/video/rockchip/rk_hdmi.c
index b75a174489..e34f532cd6 100644
--- a/drivers/video/rockchip/rk_hdmi.c
+++ b/drivers/video/rockchip/rk_hdmi.c
@@ -83,6 +83,7 @@ int rk_hdmi_of_to_plat(struct udevice *dev)
struct rk_hdmi_priv *priv = dev_get_priv(dev);
struct dw_hdmi *hdmi = &priv->hdmi;
 
+   hdmi->data = (const struct dw_hdmi_plat_data *)dev_get_driver_data(dev);
hdmi->ioaddr = (ulong)dev_read_addr(dev);
hdmi->mpll_cfg = rockchip_mpll_cfg;
hdmi->phy_cfg = rockchip_phy_config;
@@ -90,7 +91,6 @@ int rk_hdmi_of_to_plat(struct udevice *dev)
/* hdmi->i2c_clk_{high,low} are set up by the SoC driver */
 
hdmi->reg_io_width = 4;
-   hdmi->phy_set = dw_hdmi_phy_cfg;
 
priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
 
diff --git a/drivers/video/sunxi/sunxi_dw_hdmi.c 
b/drivers/video/sunxi/sunxi_dw_hdmi.c
index 0324a050d0..4b67a1614e 100644
--- a/drivers/video/sunxi/sunxi_dw_hdmi.c
+++ b/drivers/video/sunxi/sunxi_dw_hdmi.c
@@ -369,6 +369,15 @@ static int sunxi_dw_hdmi_probe(struct udevice *dev)
retu

[PATCH v2 01/17] video: rockchip: hdmi: Detect hpd after controller init

2023-12-18 Thread Jagan Teki
From: Jagan Teki 

HDP is a hardware connector event, so detect the same once the
controller and attached PHY initialization are done.

Signed-off-by: Jagan Teki 
---
Changes for v2:
- none

 drivers/video/rockchip/rk_hdmi.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/video/rockchip/rk_hdmi.c b/drivers/video/rockchip/rk_hdmi.c
index 8dcd4d5964..b75a174489 100644
--- a/drivers/video/rockchip/rk_hdmi.c
+++ b/drivers/video/rockchip/rk_hdmi.c
@@ -112,14 +112,14 @@ int rk_hdmi_probe(struct udevice *dev)
struct dw_hdmi *hdmi = &priv->hdmi;
int ret;
 
+   dw_hdmi_init(hdmi);
+   dw_hdmi_phy_init(hdmi);
+
ret = dw_hdmi_phy_wait_for_hpd(hdmi);
if (ret < 0) {
debug("hdmi can not get hpd signal\n");
return -1;
}
 
-   dw_hdmi_init(hdmi);
-   dw_hdmi_phy_init(hdmi);
-
return 0;
 }
-- 
2.25.1



[PATCH v2 00/17] video: dw_hdmi: Support Vendor PHY

2023-12-18 Thread Jagan Teki
From: Jagan Teki 

Unlike RK3399, Sunxi/Meson DW HDMI the new Rockchip SoC Rk3328 would
support external vendor PHY with DW HDMI chip.

Support this vendor PHY by adding new platform PHY ops via DW HDMI
driver and call the respective generic phy from platform driver code.

This series tested in RK3328 with 1080p (1920x1080) resolution.

Patch 0001/0005: Support Vendor PHY
Patch 0006/0008: VOP extension for win, dsp offsets
Patch 0009/0010: RK3328 VOP, HDMI clocks
Patch 0011:  Rockchip Inno HDMI PHY
Patch 0012:  RK3328 HDMI driver
Patch 0013:  RK3328 VOP driver
Patch 0014/0017: Enable HDMI Out for RK3328

Changes for v2:
- Use proper cfg function for meson
- Add VOP cleanup code.
- Add DCLK get rate

Linux VOP/HDMI out issues seems resolved with explicit VOP cleanup.

V1:
https://patchwork.ozlabs.org/project/uboot/cover/20231211085939.5478-1-ja...@amarulasolutions.com/

Any inputs?
Jagan.

Jagan Teki (17):
  video: rockchip: hdmi: Detect hpd after controller init
  video: dw_hdmi: Add Vendor PHY handling
  video: dw_hdmi: Extend the HPD detection
  video: dw_hdmi: Add read_hpd hook
  video: dw_hdmi: Add setup_hpd hook
  video: rockchip: vop: Simplify rkvop_enable
  video: rockchip: vop: Add win offset support
  video: rockchip: vop: Add dsp offset support
  clk: rockchip: rk3328: Add VOP clk support
  clk: rk3328: Add get hdmiphy clock
  phy: rockchip: Add Rockchip INNO HDMI PHY driver
  video: rockchip: Add rk3328 hdmi support
  video: rockchip: Add rk3328 vop support
  ARM: dts: rk3328: Enable VOP for bootph-all
  rockchip: Enable preconsole for rk3328
  configs: evb-rk3328: Enable vidconsole for rk3328
  configs: Enable HDMI Out for ROC-RK3328-CC

 arch/arm/dts/rk3328-u-boot.dtsi   |   4 +
 .../include/asm/arch-rockchip/cru_rk3328.h|  34 +
 arch/arm/mach-rockchip/Kconfig|   1 +
 common/Kconfig|   2 +-
 configs/roc-cc-rk3328_defconfig   |   5 +
 drivers/clk/rockchip/clk_rk3328.c | 105 ++-
 drivers/phy/rockchip/Kconfig  |   7 +
 drivers/phy/rockchip/Makefile |   1 +
 drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 885 ++
 drivers/video/dw_hdmi.c   |  48 +-
 drivers/video/meson/meson_dw_hdmi.c   |  11 +-
 drivers/video/rockchip/Makefile   |   2 +
 drivers/video/rockchip/rk3328_hdmi.c  | 131 +++
 drivers/video/rockchip/rk3328_vop.c   |  83 ++
 drivers/video/rockchip/rk3399_hdmi.c  |   8 +-
 drivers/video/rockchip/rk_hdmi.c  |  12 +-
 drivers/video/rockchip/rk_hdmi.h  |   3 +
 drivers/video/rockchip/rk_vop.c   |  44 +-
 drivers/video/rockchip/rk_vop.h   |   4 +
 drivers/video/sunxi/sunxi_dw_hdmi.c   |  19 +-
 include/configs/evb_rk3328.h  |   5 +
 include/configs/rk3328_common.h   |   1 +
 include/dw_hdmi.h |  17 +-
 23 files changed, 1393 insertions(+), 39 deletions(-)
 create mode 100644 drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
 create mode 100644 drivers/video/rockchip/rk3328_hdmi.c
 create mode 100644 drivers/video/rockchip/rk3328_vop.c

-- 
2.25.1



Re: [PATCH 00/17] video: dw_hdmi: Support Vendor PHY

2023-12-18 Thread Jagan Teki
On Mon, Dec 18, 2023 at 7:23 PM Robin Murphy  wrote:
>
> On 2023-12-15 7:13 am, Kever Yang wrote:
> > Hi Jagan,
> >
> > On 2023/12/15 14:36, Jagan Teki wrote:
> >> Hi Heiko/Kerver/Anatoloj,
> >>
> >> On Mon, Dec 11, 2023 at 2:30 PM Jagan Teki
> >>  wrote:
> >>> Unlike RK3399, Sunxi/Meson DW HDMI the new Rockchip SoC Rk3328 would
> >>> support external vendor PHY with DW HDMI chip.
> >>>
> >>> Support this vendor PHY by adding new platform PHY ops via DW HDMI
> >>> driver and call the respective generic phy from platform driver code.
> >>>
> >>> This series tested in RK3328 with 1080p (1920x1080) resolution.
> >>>
> >>> Patch 0001/0005: Support Vendor PHY
> >>> Patch 0006/0008: VOP extension for win, dsp offsets
> >>> Patch 0009/0010: RK3328 VOP, HDMI clocks
> >>> Patch 0011:  Rockchip Inno HDMI PHY
> >>> Patch 0012:  RK3328 HDMI driver
> >>> Patch 0013:  RK3328 VOP driver
> >>> Patch 0014/0017: Enable HDMI Out for RK3328
> >>>
> >>> Importent:
> >>> One pontential issues is that Linux HDMI out on RK3328 has effected by
> >>> this patchset as I wouldn't find any relation or clue.
> >>>
> >>> [0.752016] Loading compiled-in X.509 certificates
> >>> [0.787796] inno_hdmi_phy_rk3328_clk_recalc_rate: parent 2400
> >>> [0.788391] inno-hdmi-phy ff43.phy:
> >>> inno_hdmi_phy_rk3328_clk_recalc_rate rate 14850 vco 14850
> >>> [0.798353] rockchip-drm display-subsystem: bound ff37.vop
> >>> (ops vop_component_ops)
> >>> [0.799403] dwhdmi-rockchip ff3c.hdmi: supply avdd-0v9 not
> >>> found, using dummy regulator
> >>> [0.800288] rk_iommu ff373f00.iommu: Enable stall request timed
> >>> out, status: 0x4b
> >>> [0.801131] dwhdmi-rockchip ff3c.hdmi: supply avdd-1v8 not
> >>> found, using dummy regulator
> >>> [0.802056] rk_iommu ff373f00.iommu: Disable paging request timed
> >>> out, status: 0x4b
> >>> [0.803233] dwhdmi-rockchip ff3c.hdmi: Detected HDMI TX
> >>> controller v2.11a with HDCP (inno_dw_hdmi_phy2)
> >>> [0.805355] dwhdmi-rockchip ff3c.hdmi: registered DesignWare
> >>> HDMI I2C bus driver
> >>> [0.808769] rockchip-drm display-subsystem: bound ff3c.hdmi
> >>> (ops dw_hdmi_rockchip_ops)
> >>> [0.810869] [drm] Initialized rockchip 1.0.0 20140818 for
> >>> display-subsystem on minor 0
> >>>
> >>> The only way I can use Linux HDMI by disabling IOMMU or support
> >>> disable-iommu link for RK3328 via DT [1].
> >>>
> >>> [1] https://www.spinics.net/lists/devicetree/msg605124.html
> >> Is anyone aware of this issue? I did post the patches for Linux IOMMU
> >> but seems not a proper solution. Any suggestions?
> >
> > I'm not expert in HDMI/VOP, so I can't provide a suitable solution in
> > the kernel,
> >
> > but here is the reason why we need patch to workaround the issue in the
> > kernel:
> >
> > - The VOP driver working in U-Boot is non-IOMMU mode, and the VOP access
> > DDR by physical address;
> >
> > - The VOP driver working in kernel with IOMMU enabled(by default), the
> > VOP access DDR with virtual address(by IOMMU);
> >
> > - The VOP is keep working in kernel before kernel VOP driver is enabled,
> > and the IOMMU driver will be enabled by
> >
> > the Linux PM framework, since the IOMMU is not correctly configured
> > at this point, the VOP will access unknown
> >
> >  space(the original physical address in U-Boot) convert by IOMMU;
> >
> > So we need to disable the IOMMU temporary in kernel startup before VOP
> > driver is enabled.
>
> If U-Boot isn't handing off an active framebuffer, then it should be
> U-Boot's responsibility to stop the VOP before it exits; if on the other
> hand it is, then it can now use the "iommu-addresses" DT property (see
> the reserved-memory schema) on the framebuffer region, and we should
> just need a bit of work in the IOMMU driver to ensure that is respected
> during the period between the IOMMU initialising and the Linux VOP
> driver subsequently taking over (i.e. so it won't get stuck on an
> unexpected page fault as seems to be happening above). The IOMMU aspect
> of that ought to be fairly straightforward; the trickier part might be
> the runtime PM aspect to ensure the IOMMU doesn't let itself go idle and
> actually turn anything off during that period. I also still think that
> doing the full rk_iommu_disable() upon runtime suspend is wrong, but
> that's more of a thing which confounds the underlying issue here, rather
> than being the problem in itself.

Thanks for your comments. Okay, keeping the Linux IOMMU issue aside I
think whatever change that u-boot makes on VOP has to clear it before
handoff to Linux - so clearing the VOP registers during handoff seems
working. I only wonder why it happens only on RK3328 (RK3399 and
RK3288 seem fine).

I will post the next version with VOP clear during handoff.

Thanks,
Jagan.


[PATCH v3 14/14] bloblist: Align bloblist used_size and total_size to spec

2023-12-18 Thread Raymond Mao
Align used_size and total_size of the bloblist header to the definition
of the FW Handoff spec v0.9.
Update the related bloblist APIs and UT testcases.

Signed-off-by: Raymond Mao 
---
Changes in v2
- New patch file created for v2.
Changes in v3
- Keep the flag and spare values to align to FW handoff spec up to commit 
3592349.

 common/bloblist.c  | 86 +++---
 include/bloblist.h | 25 +-
 test/bloblist.c| 35 ++-
 3 files changed, 84 insertions(+), 62 deletions(-)

diff --git a/common/bloblist.c b/common/bloblist.c
index 6d079c58f7..625e480f6b 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -80,7 +80,7 @@ const char *bloblist_tag_name(enum bloblist_tag_t tag)
 
 static struct bloblist_rec *bloblist_first_blob(struct bloblist_hdr *hdr)
 {
-   if (hdr->alloced <= hdr->hdr_size)
+   if (hdr->used_size <= hdr->hdr_size)
return NULL;
return (struct bloblist_rec *)((void *)hdr + hdr->hdr_size);
 }
@@ -119,7 +119,7 @@ static struct bloblist_rec *bloblist_next_blob(struct 
bloblist_hdr *hdr,
 {
ulong offset = bloblist_blob_end_ofs(hdr, rec);
 
-   if (offset >= hdr->alloced)
+   if (offset >= hdr->used_size)
return NULL;
return (struct bloblist_rec *)((void *)hdr + offset);
 }
@@ -156,9 +156,9 @@ static int bloblist_addrec(uint tag, int size, int 
align_log2,
align_log2 = BLOBLIST_BLOB_ALIGN_LOG2;
 
/* Figure out where the new data will start */
-   data_start = map_to_sysmem(hdr) + hdr->alloced + sizeof(*rec);
+   data_start = map_to_sysmem(hdr) + hdr->used_size + sizeof(*rec);
 
-   /* Align the address and then calculate the offset from ->alloced */
+   /* Align the address and then calculate the offset from used size */
aligned_start = ALIGN(data_start, 1U << align_log2) - data_start;
 
/* If we need to create a dummy record, create it */
@@ -172,19 +172,20 @@ static int bloblist_addrec(uint tag, int size, int 
align_log2,
return log_msg_ret("void", ret);
 
/* start the record after that */
-   data_start = map_to_sysmem(hdr) + hdr->alloced + sizeof(*vrec);
+   data_start = map_to_sysmem(hdr) + hdr->used_size + 
sizeof(*vrec);
}
 
/* Calculate the new allocated total */
new_alloced = data_start - map_to_sysmem(hdr) +
ALIGN(size, 1U << align_log2);
 
-   if (new_alloced > hdr->size) {
-   log_err("Failed to allocate %x bytes size=%x, need size=%x\n",
-   size, hdr->size, new_alloced);
+   if (new_alloced > hdr->total_size) {
+   log_err("Failed to allocate %x bytes\n", size);
+   log_err("Used size=%x, total size=%x\n",
+   hdr->used_size, hdr->total_size);
return log_msg_ret("bloblist add", -ENOSPC);
}
-   rec = (void *)hdr + hdr->alloced;
+   rec = (void *)hdr + hdr->used_size;
 
rec->tag_and_hdr_size = tag | sizeof(*rec) << BLOBLISTR_HDR_SIZE_SHIFT;
rec->size = size;
@@ -192,7 +193,7 @@ static int bloblist_addrec(uint tag, int size, int 
align_log2,
/* Zero the record data */
memset((void *)rec + rec_hdr_size(rec), '\0', rec->size);
 
-   hdr->alloced = new_alloced;
+   hdr->used_size = new_alloced;
*recp = rec;
 
return 0;
@@ -287,29 +288,30 @@ static int bloblist_resize_rec(struct bloblist_hdr *hdr,
   int new_size)
 {
int expand_by;  /* Number of bytes to expand by (-ve to contract) */
-   int new_alloced;/* New value for @hdr->alloced */
+   int new_alloced;
ulong next_ofs; /* Offset of the record after @rec */
 
expand_by = ALIGN(new_size - rec->size, BLOBLIST_BLOB_ALIGN);
-   new_alloced = ALIGN(hdr->alloced + expand_by, BLOBLIST_BLOB_ALIGN);
+   new_alloced = ALIGN(hdr->used_size + expand_by, BLOBLIST_BLOB_ALIGN);
if (new_size < 0) {
log_debug("Attempt to shrink blob size below 0 (%x)\n",
  new_size);
return log_msg_ret("size", -EINVAL);
}
-   if (new_alloced > hdr->size) {
-   log_err("Failed to allocate %x bytes size=%x, need size=%x\n",
-   new_size, hdr->size, new_alloced);
+   if (new_alloced > hdr->total_size) {
+   log_err("Failed to allocate %x bytes\n", new_size);
+   log_err("Used size=%x, total size=%x\n",
+   hdr->used_size, hdr->total_size);
return log_msg_ret("alloc", -ENOSPC);
}
 
/* Move the following blobs up or down, if this is not the last */
next_ofs = bloblist_blob_end_ofs(hdr, rec);
-   if (next_ofs != hdr->alloced) {
+   if (next_ofs != hdr->used_size) {
memmove((void *)hdr + next_ofs + expand_by,
   

[PATCH v3 13/14] bloblist: Update documentation and header comment

2023-12-18 Thread Raymond Mao
From: Simon Glass 

Align the documentation with the v0.9 spec.

Signed-off-by: Simon Glass 
Signed-off-by: Raymond Mao 
---
 doc/develop/bloblist.rst | 4 +++-
 include/bloblist.h   | 1 +
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/doc/develop/bloblist.rst b/doc/develop/bloblist.rst
index 81643c7674..28431039ad 100644
--- a/doc/develop/bloblist.rst
+++ b/doc/develop/bloblist.rst
@@ -14,6 +14,8 @@ structure defined by the code that owns it.
 For the design goals of bloblist, please see the comments at the top of the
 `bloblist.h` header file.
 
+Bloblist is an implementation with the `Firmware Handoff`_ protocol.
+
 Passing state through the boot process
 --
 
@@ -99,7 +101,7 @@ API documentation
 -
 
 .. kernel-doc:: include/bloblist.h
-
+.. _`Firmware Handoff`: https://github.com/FirmwareHandoff/firmware_handoff
 
 Simon Glass
 s...@chromium.org
diff --git a/include/bloblist.h b/include/bloblist.h
index 8f0286fda7..e3c86808b4 100644
--- a/include/bloblist.h
+++ b/include/bloblist.h
@@ -66,6 +66,7 @@
  *
  * Copyright 2018 Google, Inc
  * Written by Simon Glass 
+ * Adjusted July 2023 to match Firmware handoff specification, Release 0.9
  */
 
 #ifndef __BLOBLIST_H
-- 
2.25.1



[PATCH v3 12/14] bloblist: Add alignment to bloblist_new()

2023-12-18 Thread Raymond Mao
From: Simon Glass 

Allow the alignment to be specified when creating a bloblist.

Signed-off-by: Simon Glass 
Co-developed-by: Raymond Mao 
Signed-off-by: Raymond Mao 
---
Changes in v3
- Keep the flag argument to align to FW handoff spec up to commit 3592349.

 common/bloblist.c  |  5 +++--
 include/bloblist.h |  3 ++-
 test/bloblist.c| 40 ++--
 3 files changed, 27 insertions(+), 21 deletions(-)

diff --git a/common/bloblist.c b/common/bloblist.c
index 1c97d61e4a..6d079c58f7 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -349,7 +349,7 @@ static u32 bloblist_calc_chksum(struct bloblist_hdr *hdr)
return chksum;
 }
 
-int bloblist_new(ulong addr, uint size, uint flags)
+int bloblist_new(ulong addr, uint size, uint flags, uint align_log2)
 {
struct bloblist_hdr *hdr;
 
@@ -365,6 +365,7 @@ int bloblist_new(ulong addr, uint size, uint flags)
hdr->magic = BLOBLIST_MAGIC;
hdr->size = size;
hdr->alloced = hdr->hdr_size;
+   hdr->align_log2 = align_log2 ?: BLOBLIST_BLOB_ALIGN_LOG2;
hdr->chksum = 0;
gd->bloblist = hdr;
 
@@ -508,7 +509,7 @@ int bloblist_init(void)
}
log_debug("Creating new bloblist size %lx at %lx\n", size,
  addr);
-   ret = bloblist_new(addr, size, 0);
+   ret = bloblist_new(addr, size, 0, 0);
} else {
log_debug("Found existing bloblist size %lx at %lx\n", size,
  addr);
diff --git a/include/bloblist.h b/include/bloblist.h
index 5dba630adb..8f0286fda7 100644
--- a/include/bloblist.h
+++ b/include/bloblist.h
@@ -330,10 +330,11 @@ int bloblist_resize(uint tag, int new_size);
  * @addr: Address of bloblist
  * @size: Initial size for bloblist
  * @flags: Flags to use for bloblist
+ * @align_log2: Log base 2 of maximum alignment provided by this bloblist
  * Return: 0 if OK, -EFAULT if addr is not aligned correctly, -ENOSPC is the
  * area is not large enough
  */
-int bloblist_new(ulong addr, uint size, uint flags);
+int bloblist_new(ulong addr, uint size, uint flags, uint align_log2);
 
 /**
  * bloblist_check() - Check if a bloblist exists
diff --git a/test/bloblist.c b/test/bloblist.c
index a083259d0c..29abd46862 100644
--- a/test/bloblist.c
+++ b/test/bloblist.c
@@ -72,15 +72,15 @@ static int bloblist_test_init(struct unit_test_state *uts)
hdr = clear_bloblist();
ut_asserteq(-ENOENT, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
ut_asserteq_ptr(NULL, bloblist_check_magic(TEST_ADDR));
-   ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
+   ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0));
ut_asserteq_ptr(hdr, bloblist_check_magic(TEST_ADDR));
hdr->version++;
ut_asserteq(-EPROTONOSUPPORT, bloblist_check(TEST_ADDR,
 TEST_BLOBLIST_SIZE));
 
-   ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0xc, 0));
-   ut_asserteq(-EFAULT, bloblist_new(1, TEST_BLOBLIST_SIZE, 0));
-   ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
+   ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0xc, 0, 0));
+   ut_asserteq(-EFAULT, bloblist_new(1, TEST_BLOBLIST_SIZE, 0, 0));
+   ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0));
 
ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
ut_assertok(bloblist_finish());
@@ -106,7 +106,7 @@ static int bloblist_test_blob(struct unit_test_state *uts)
/* At the start there should be no records */
hdr = clear_bloblist();
ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE));
-   ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
+   ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0));
ut_asserteq(TEST_BLOBLIST_SIZE, bloblist_get_size());
ut_asserteq(TEST_ADDR, bloblist_get_base());
ut_asserteq(map_to_sysmem(hdr), TEST_ADDR);
@@ -144,7 +144,7 @@ static int bloblist_test_blob_ensure(struct unit_test_state 
*uts)
 
/* At the start there should be no records */
clear_bloblist();
-   ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
+   ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0));
 
/* Test with an empty bloblist */
size = TEST_SIZE;
@@ -176,7 +176,7 @@ static int bloblist_test_bad_blob(struct unit_test_state 
*uts)
void *data;
 
hdr = clear_bloblist();
-   ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
+   ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0));
data = hdr + 1;
data += sizeof(struct bloblist_rec);
ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
@@ -192,7 +192,7 @@ static int bloblist_test_checksum(struct unit_test_state 
*uts)
char *data, *data2;
 
hdr = clear_bloblist();
-   ut_asse

[PATCH v3 11/14] bloblist: Adjust the bloblist header

2023-12-18 Thread Raymond Mao
From: Simon Glass 

The v0.9 spec provides for a 24-byte header. Update
the implementation to match this.

This also adds an alignment field.

Signed-off-by: Simon Glass 
Co-developed-by: Raymond Mao 
Signed-off-by: Raymond Mao 
---
Changes in v3
- Update the bloblist header to align to FW handoff spec up to commit 3592349.
- Update the related testcases.

 include/bloblist.h | 29 +++--
 test/bloblist.c|  6 +++---
 2 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/include/bloblist.h b/include/bloblist.h
index 7024d7bf9e..5dba630adb 100644
--- a/include/bloblist.h
+++ b/include/bloblist.h
@@ -166,32 +166,33 @@ enum bloblist_tag_t {
  * from the last.
  *
  * @magic: BLOBLIST_MAGIC
+ * @chksum: checksum for the entire bloblist allocated area. Since any of the
+ * blobs can be altered after being created, this checksum is only valid
+ * when the bloblist is finalized before jumping to the next stage of boot.
+ * This is the value needed to make all checksummed bytes sum to 0
  * @version: BLOBLIST_VERSION
  * @hdr_size: Size of this header, normally sizeof(struct bloblist_hdr). The
  * first bloblist_rec starts at this offset from the start of the header
- * @flags: Space for BLOBLISTF... flags (none yet)
- * @size: Total size of the bloblist (non-zero if valid) including this header.
- * The bloblist extends for this many bytes from the start of this header.
- * When adding new records, the bloblist can grow up to this size.
+ * @align_log2: Power of two of the maximum alignment required by this list
  * @alloced: Total size allocated so far for this bloblist. This starts out as
  * sizeof(bloblist_hdr) since we need at least that much space to store a
  * valid bloblist
+ * @size: Total size of the bloblist (non-zero if valid) including this header.
+ * The bloblist extends for this many bytes from the start of this header.
+ * When adding new records, the bloblist can grow up to this size.
+ * @flags: Space for BLOBLISTF... flags (none yet)
  * @spare: Spare space (for future use)
- * @chksum: checksum for the entire bloblist allocated area. Since any of the
- * blobs can be altered after being created, this checksum is only valid
- * when the bloblist is finalised before jumping to the next stage of boot.
- * This is the value needed to make all checksummed bytes sum to 0
  */
 struct bloblist_hdr {
u32 magic;
-   u32 version;
-   u32 hdr_size;
-   u32 flags;
-
-   u32 size;
+   u8 chksum;
+   u8 version;
+   u8 hdr_size;
+   u8 align_log2;
u32 alloced;
+   u32 size;
+   u32 flags;
u32 spare;
-   u32 chksum;
 };
 
 /**
diff --git a/test/bloblist.c b/test/bloblist.c
index e6070041d3..a083259d0c 100644
--- a/test/bloblist.c
+++ b/test/bloblist.c
@@ -78,7 +78,7 @@ static int bloblist_test_init(struct unit_test_state *uts)
ut_asserteq(-EPROTONOSUPPORT, bloblist_check(TEST_ADDR,
 TEST_BLOBLIST_SIZE));
 
-   ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0x10, 0));
+   ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0xc, 0));
ut_asserteq(-EFAULT, bloblist_new(1, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
 
@@ -272,8 +272,8 @@ static int bloblist_test_cmd_info(struct unit_test_state 
*uts)
run_command("bloblist info", 0);
ut_assert_nextline("base: %lx", (ulong)map_to_sysmem(hdr));
ut_assert_nextline("size: 4001 KiB");
-   ut_assert_nextline("alloced:  58 88 Bytes");
-   ut_assert_nextline("free: 3a8936 Bytes");
+   ut_assert_nextline("alloced:  50 80 Bytes");
+   ut_assert_nextline("free: 3b0944 Bytes");
ut_assert_console_end();
ut_unsilence_console(uts);
 
-- 
2.25.1



[PATCH v3 10/14] bloblist: Reduce blob-header size

2023-12-18 Thread Raymond Mao
From: Simon Glass 

The v0.9 spec provides for an 8-byte header for each blob, with fewer
fields.
The blob data start address should be aligned to the alignment specified
by the bloblist header.
Update the implementation to match this.

Signed-off-by: Simon Glass 
Co-developed-by: Raymond Mao 
Signed-off-by: Raymond Mao 
---
Changes in v2
- Update the blob start address to align to the alignment required by
  the bloblist header.
- Define the macros of bloblist header size and bloblist record header
  size as the size of their structures.  
Changes in v3
- Update the calculation of the bloblist record offset to make sure
  that each bloblist record data section start address fulfills the
  alignment requirement.
- Update commit message.

 common/bloblist.c  | 23 +++
 include/bloblist.h | 33 ++---
 test/bloblist.c| 16 
 3 files changed, 45 insertions(+), 27 deletions(-)

diff --git a/common/bloblist.c b/common/bloblist.c
index 73dbbc01c0..1c97d61e4a 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -87,12 +87,14 @@ static struct bloblist_rec *bloblist_first_blob(struct 
bloblist_hdr *hdr)
 
 static inline uint rec_hdr_size(struct bloblist_rec *rec)
 {
-   return rec->hdr_size;
+   return (rec->tag_and_hdr_size & BLOBLISTR_HDR_SIZE_MASK) >>
+   BLOBLISTR_HDR_SIZE_SHIFT;
 }
 
 static inline uint rec_tag(struct bloblist_rec *rec)
 {
-   return rec->tag;
+   return (rec->tag_and_hdr_size & BLOBLISTR_TAG_MASK) >>
+   BLOBLISTR_TAG_SHIFT;
 }
 
 static ulong bloblist_blob_end_ofs(struct bloblist_hdr *hdr,
@@ -101,7 +103,13 @@ static ulong bloblist_blob_end_ofs(struct bloblist_hdr 
*hdr,
ulong offset;
 
offset = (void *)rec - (void *)hdr;
-   offset += rec_hdr_size(rec) + ALIGN(rec->size, BLOBLIST_ALIGN);
+   /*
+* The data section of next TE should start from an address aligned
+* to 1 << hdr->align_log2.
+*/
+   offset += rec_hdr_size(rec) + rec->size;
+   offset = round_up(offset + rec_hdr_size(rec), 1 << hdr->align_log2);
+   offset -= rec_hdr_size(rec);
 
return offset;
 }
@@ -145,7 +153,7 @@ static int bloblist_addrec(uint tag, int size, int 
align_log2,
int data_start, aligned_start, new_alloced;
 
if (!align_log2)
-   align_log2 = BLOBLIST_ALIGN_LOG2;
+   align_log2 = BLOBLIST_BLOB_ALIGN_LOG2;
 
/* Figure out where the new data will start */
data_start = map_to_sysmem(hdr) + hdr->alloced + sizeof(*rec);
@@ -178,8 +186,7 @@ static int bloblist_addrec(uint tag, int size, int 
align_log2,
}
rec = (void *)hdr + hdr->alloced;
 
-   rec->tag = tag;
-   rec->hdr_size = sizeof(struct bloblist_rec);
+   rec->tag_and_hdr_size = tag | sizeof(*rec) << BLOBLISTR_HDR_SIZE_SHIFT;
rec->size = size;
 
/* Zero the record data */
@@ -283,8 +290,8 @@ static int bloblist_resize_rec(struct bloblist_hdr *hdr,
int new_alloced;/* New value for @hdr->alloced */
ulong next_ofs; /* Offset of the record after @rec */
 
-   expand_by = ALIGN(new_size - rec->size, BLOBLIST_ALIGN);
-   new_alloced = ALIGN(hdr->alloced + expand_by, BLOBLIST_ALIGN);
+   expand_by = ALIGN(new_size - rec->size, BLOBLIST_BLOB_ALIGN);
+   new_alloced = ALIGN(hdr->alloced + expand_by, BLOBLIST_BLOB_ALIGN);
if (new_size < 0) {
log_debug("Attempt to shrink blob size below 0 (%x)\n",
  new_size);
diff --git a/include/bloblist.h b/include/bloblist.h
index d2dcad69a1..7024d7bf9e 100644
--- a/include/bloblist.h
+++ b/include/bloblist.h
@@ -24,11 +24,11 @@
  * which would add to code size. For Thumb-2 the code size needed in SPL is
  * approximately 940 bytes (e.g. for chromebook_bob).
  *
- * 5. Bloblist uses 16-byte alignment internally and is designed to start on a
- * 16-byte boundary. Its headers are multiples of 16 bytes. This makes it 
easier
- * to deal with data structures which need this level of alignment, such as 
ACPI
- * tables. For use in SPL and TPL the alignment can be relaxed, since it can be
- * relocated to an aligned address in U-Boot proper.
+ * 5. Bloblist uses 8-byte alignment internally and is designed to start on a
+ * 8-byte boundary. Its headers are 8 bytes long. It is possible to achieve
+ * larger alignment (e.g. 16 bytes) by adding a dummy header, For use in SPL 
and
+ * TPL the alignment can be relaxed, since it can be relocated to an aligned
+ * address in U-Boot proper.
  *
  * 6. Bloblist is designed to be passed to Linux as reserved memory. While 
linux
  * doesn't understand the bloblist header, it can be passed the indivdual 
blobs.
@@ -77,6 +77,9 @@ enum {
BLOBLIST_VERSION= 1,
BLOBLIST_MAGIC  = 0x4a0fb10b,
 
+   BLOBLIST_BLOB_ALIGN_LOG2 = 3,
+   BLOBLIST_BLOB_ALIGN  = 1 << BLOBLIST_BLOB_ALIGN_LOG2,
+
BLOBLIST_ALIGN

[PATCH v3 09/14] bloblist: Handle alignment with a void entry

2023-12-18 Thread Raymond Mao
From: Simon Glass 

Rather than setting the alignment using the header size, add an entirely
new entry to cover the gap left by the alignment.

Signed-off-by: Simon Glass 
Co-developed-by: Raymond Mao 
Signed-off-by: Raymond Mao 
Reviewed-by: Simon Glass 
---
 common/bloblist.c | 23 +++
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/common/bloblist.c b/common/bloblist.c
index 705d9c6ae9..73dbbc01c0 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -142,7 +142,7 @@ static int bloblist_addrec(uint tag, int size, int 
align_log2,
 {
struct bloblist_hdr *hdr = gd->bloblist;
struct bloblist_rec *rec;
-   int data_start, new_alloced;
+   int data_start, aligned_start, new_alloced;
 
if (!align_log2)
align_log2 = BLOBLIST_ALIGN_LOG2;
@@ -151,10 +151,25 @@ static int bloblist_addrec(uint tag, int size, int 
align_log2,
data_start = map_to_sysmem(hdr) + hdr->alloced + sizeof(*rec);
 
/* Align the address and then calculate the offset from ->alloced */
-   data_start = ALIGN(data_start, 1U << align_log2) - map_to_sysmem(hdr);
+   aligned_start = ALIGN(data_start, 1U << align_log2) - data_start;
+
+   /* If we need to create a dummy record, create it */
+   if (aligned_start) {
+   int void_size = aligned_start - sizeof(*rec);
+   struct bloblist_rec *vrec;
+   int ret;
+
+   ret = bloblist_addrec(BLOBLISTT_VOID, void_size, 0, &vrec);
+   if (ret)
+   return log_msg_ret("void", ret);
+
+   /* start the record after that */
+   data_start = map_to_sysmem(hdr) + hdr->alloced + sizeof(*vrec);
+   }
 
/* Calculate the new allocated total */
-   new_alloced = data_start + ALIGN(size, 1U << align_log2);
+   new_alloced = data_start - map_to_sysmem(hdr) +
+   ALIGN(size, 1U << align_log2);
 
if (new_alloced > hdr->size) {
log_err("Failed to allocate %x bytes size=%x, need size=%x\n",
@@ -164,7 +179,7 @@ static int bloblist_addrec(uint tag, int size, int 
align_log2,
rec = (void *)hdr + hdr->alloced;
 
rec->tag = tag;
-   rec->hdr_size = data_start - hdr->alloced;
+   rec->hdr_size = sizeof(struct bloblist_rec);
rec->size = size;
 
/* Zero the record data */
-- 
2.25.1



[PATCH v3 08/14] bloblist: Checksum the entire bloblist

2023-12-18 Thread Raymond Mao
From: Simon Glass 

Spec v0.9 specifies that the entire bloblist area is checksummed,
including unused portions. Update the code to follow this.

Signed-off-by: Simon Glass 
Co-developed-by: Raymond Mao 
Signed-off-by: Raymond Mao 
Reviewed-by: Simon Glass 
---
 common/bloblist.c |  9 +
 test/bloblist.c   | 10 --
 2 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/common/bloblist.c b/common/bloblist.c
index 32692d8319..705d9c6ae9 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -319,17 +319,10 @@ int bloblist_resize(uint tag, int new_size)
 
 static u32 bloblist_calc_chksum(struct bloblist_hdr *hdr)
 {
-   struct bloblist_rec *rec;
u8 chksum;
 
-   chksum = table_compute_checksum(hdr, hdr->hdr_size);
+   chksum = table_compute_checksum(hdr, hdr->alloced);
chksum += hdr->chksum;
-   foreach_rec(rec, hdr) {
-   chksum -= table_compute_checksum((void *)rec,
-rec_hdr_size(rec));
-   chksum -= table_compute_checksum((void *)rec +
-rec_hdr_size(rec), rec->size);
-   }
 
return chksum;
 }
diff --git a/test/bloblist.c b/test/bloblist.c
index 8b435e27ca..49ac4b92ae 100644
--- a/test/bloblist.c
+++ b/test/bloblist.c
@@ -237,12 +237,18 @@ static int bloblist_test_checksum(struct unit_test_state 
*uts)
*data2 -= 1;
 
/*
-* Changing data outside the range of valid data should not affect
-* the checksum.
+* Changing data outside the range of valid data should affect the
+* checksum.
 */
ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
data[TEST_SIZE]++;
+   ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
+   data[TEST_SIZE]--;
+   ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
+
data2[TEST_SIZE2]++;
+   ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
+   data[TEST_SIZE]--;
ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
 
return 0;
-- 
2.25.1



[PATCH v3 07/14] bloblist: Change the checksum algorithm

2023-12-18 Thread Raymond Mao
From: Simon Glass 

Use a sinple 8-bit checksum for bloblist, as specified by the spec
version 0.9

Signed-off-by: Simon Glass 
Co-developed-by: Raymond Mao 
Signed-off-by: Raymond Mao 
Reviewed-by: Simon Glass 
---
 common/bloblist.c  | 14 --
 include/bloblist.h |  5 ++---
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/common/bloblist.c b/common/bloblist.c
index 88e2a0f5c0..32692d8319 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -13,6 +13,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -319,14 +320,15 @@ int bloblist_resize(uint tag, int new_size)
 static u32 bloblist_calc_chksum(struct bloblist_hdr *hdr)
 {
struct bloblist_rec *rec;
-   u32 chksum;
+   u8 chksum;
 
-   chksum = crc32(0, (unsigned char *)hdr,
-  offsetof(struct bloblist_hdr, chksum));
+   chksum = table_compute_checksum(hdr, hdr->hdr_size);
+   chksum += hdr->chksum;
foreach_rec(rec, hdr) {
-   chksum = crc32(chksum, (void *)rec, rec_hdr_size(rec));
-   chksum = crc32(chksum, (void *)rec + rec_hdr_size(rec),
-  rec->size);
+   chksum -= table_compute_checksum((void *)rec,
+rec_hdr_size(rec));
+   chksum -= table_compute_checksum((void *)rec +
+rec_hdr_size(rec), rec->size);
}
 
return chksum;
diff --git a/include/bloblist.h b/include/bloblist.h
index 68f97395b7..d2dcad69a1 100644
--- a/include/bloblist.h
+++ b/include/bloblist.h
@@ -174,11 +174,10 @@ enum bloblist_tag_t {
  * sizeof(bloblist_hdr) since we need at least that much space to store a
  * valid bloblist
  * @spare: Spare space (for future use)
- * @chksum: CRC32 for the entire bloblist allocated area. Since any of the
+ * @chksum: checksum for the entire bloblist allocated area. Since any of the
  * blobs can be altered after being created, this checksum is only valid
  * when the bloblist is finalised before jumping to the next stage of boot.
- * Note that chksum is last to make it easier to exclude it from the
- * checksum calculation.
+ * This is the value needed to make all checksummed bytes sum to 0
  */
 struct bloblist_hdr {
u32 magic;
-- 
2.25.1



[PATCH v3 06/14] bloblist: Drop spare value from bloblist record

2023-12-18 Thread Raymond Mao
From: Simon Glass 

Drop spare value from bloblist record header.

For now it is still present in the header, with an underscore, so that
tests continue to pass.

Signed-off-by: Simon Glass 
Co-developed-by: Raymond Mao 
Signed-off-by: Raymond Mao 
---
Changes in v3
- Keep the spare value in the bloblist header to align to FW handoff spec up to 
commit 3592349.

 common/bloblist.c  | 1 -
 include/bloblist.h | 3 +--
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/common/bloblist.c b/common/bloblist.c
index 168993e0a7..88e2a0f5c0 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -165,7 +165,6 @@ static int bloblist_addrec(uint tag, int size, int 
align_log2,
rec->tag = tag;
rec->hdr_size = data_start - hdr->alloced;
rec->size = size;
-   rec->spare = 0;
 
/* Zero the record data */
memset((void *)rec + rec_hdr_size(rec), '\0', rec->size);
diff --git a/include/bloblist.h b/include/bloblist.h
index 7eff709ec8..68f97395b7 100644
--- a/include/bloblist.h
+++ b/include/bloblist.h
@@ -205,13 +205,12 @@ struct bloblist_hdr {
  * record's data starts at this offset from the start of the record
  * @size: Size of record in bytes, excluding the header size. This does not
  * need to be aligned (e.g. 3 is OK).
- * @spare: Spare space for other things
  */
 struct bloblist_rec {
u32 tag;
u32 hdr_size;
u32 size;
-   u32 spare;
+   u32 _spare;
 };
 
 /**
-- 
2.25.1



[PATCH v3 05/14] bloblist: Access record hdr_size and tag via a function

2023-12-18 Thread Raymond Mao
From: Simon Glass 

Convert accesses to tag and hdr_size via function for grouping tag and
hdr_size together later.

Signed-off-by: Simon Glass 
Co-developed-by: Raymond Mao 
Signed-off-by: Raymond Mao 
---
Changes in v3
- Update commit message.

 common/bloblist.c | 38 +-
 1 file changed, 25 insertions(+), 13 deletions(-)

diff --git a/common/bloblist.c b/common/bloblist.c
index 1e78a3d4b3..168993e0a7 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -84,13 +84,23 @@ static struct bloblist_rec *bloblist_first_blob(struct 
bloblist_hdr *hdr)
return (struct bloblist_rec *)((void *)hdr + hdr->hdr_size);
 }
 
+static inline uint rec_hdr_size(struct bloblist_rec *rec)
+{
+   return rec->hdr_size;
+}
+
+static inline uint rec_tag(struct bloblist_rec *rec)
+{
+   return rec->tag;
+}
+
 static ulong bloblist_blob_end_ofs(struct bloblist_hdr *hdr,
   struct bloblist_rec *rec)
 {
ulong offset;
 
offset = (void *)rec - (void *)hdr;
-   offset += rec->hdr_size + ALIGN(rec->size, BLOBLIST_ALIGN);
+   offset += rec_hdr_size(rec) + ALIGN(rec->size, BLOBLIST_ALIGN);
 
return offset;
 }
@@ -119,7 +129,7 @@ static struct bloblist_rec *bloblist_findrec(uint tag)
return NULL;
 
foreach_rec(rec, hdr) {
-   if (rec->tag == tag)
+   if (rec_tag(rec) == tag)
return rec;
}
 
@@ -158,7 +168,7 @@ static int bloblist_addrec(uint tag, int size, int 
align_log2,
rec->spare = 0;
 
/* Zero the record data */
-   memset((void *)rec + rec->hdr_size, '\0', rec->size);
+   memset((void *)rec + rec_hdr_size(rec), '\0', rec->size);
 
hdr->alloced = new_alloced;
*recp = rec;
@@ -199,7 +209,7 @@ void *bloblist_find(uint tag, int size)
if (size && size != rec->size)
return NULL;
 
-   return (void *)rec + rec->hdr_size;
+   return (void *)rec + rec_hdr_size(rec);
 }
 
 void *bloblist_add(uint tag, int size, int align_log2)
@@ -209,7 +219,7 @@ void *bloblist_add(uint tag, int size, int align_log2)
if (bloblist_addrec(tag, size, align_log2, &rec))
return NULL;
 
-   return (void *)rec + rec->hdr_size;
+   return (void *)rec + rec_hdr_size(rec);
 }
 
 int bloblist_ensure_size(uint tag, int size, int align_log2, void **blobp)
@@ -220,7 +230,7 @@ int bloblist_ensure_size(uint tag, int size, int 
align_log2, void **blobp)
ret = bloblist_ensurerec(tag, &rec, size, align_log2);
if (ret)
return ret;
-   *blobp = (void *)rec + rec->hdr_size;
+   *blobp = (void *)rec + rec_hdr_size(rec);
 
return 0;
 }
@@ -232,7 +242,7 @@ void *bloblist_ensure(uint tag, int size)
if (bloblist_ensurerec(tag, &rec, size, 0))
return NULL;
 
-   return (void *)rec + rec->hdr_size;
+   return (void *)rec + rec_hdr_size(rec);
 }
 
 int bloblist_ensure_size_ret(uint tag, int *sizep, void **blobp)
@@ -245,7 +255,7 @@ int bloblist_ensure_size_ret(uint tag, int *sizep, void 
**blobp)
*sizep = rec->size;
else if (ret)
return ret;
-   *blobp = (void *)rec + rec->hdr_size;
+   *blobp = (void *)rec + rec_hdr_size(rec);
 
return 0;
 }
@@ -281,7 +291,7 @@ static int bloblist_resize_rec(struct bloblist_hdr *hdr,
 
/* Zero the new part of the blob */
if (expand_by > 0) {
-   memset((void *)rec + rec->hdr_size + rec->size, '\0',
+   memset((void *)rec + rec_hdr_size(rec) + rec->size, '\0',
   new_size - rec->size);
}
 
@@ -315,8 +325,9 @@ static u32 bloblist_calc_chksum(struct bloblist_hdr *hdr)
chksum = crc32(0, (unsigned char *)hdr,
   offsetof(struct bloblist_hdr, chksum));
foreach_rec(rec, hdr) {
-   chksum = crc32(chksum, (void *)rec, rec->hdr_size);
-   chksum = crc32(chksum, (void *)rec + rec->hdr_size, rec->size);
+   chksum = crc32(chksum, (void *)rec, rec_hdr_size(rec));
+   chksum = crc32(chksum, (void *)rec + rec_hdr_size(rec),
+  rec->size);
}
 
return chksum;
@@ -424,8 +435,9 @@ void bloblist_show_list(void)
for (rec = bloblist_first_blob(hdr); rec;
 rec = bloblist_next_blob(hdr, rec)) {
printf("%08lx  %8x  %4x %s\n",
-  (ulong)map_to_sysmem((void *)rec + rec->hdr_size),
-  rec->size, rec->tag, bloblist_tag_name(rec->tag));
+  (ulong)map_to_sysmem((void *)rec + rec_hdr_size(rec)),
+  rec->size, rec_tag(rec),
+  bloblist_tag_name(rec_tag(rec)));
}
 }
 
-- 
2.25.1



[PATCH v3 04/14] bloblist: Set version to 1

2023-12-18 Thread Raymond Mao
From: Simon Glass 

The new bloblist for v0.9 has version 1 so update this value.

Signed-off-by: Simon Glass 
Co-developed-by: Raymond Mao 
Signed-off-by: Raymond Mao 
Reviewed-by: Ilias Apalodimas 
Reviewed-by: Simon Glass 
---
 include/bloblist.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/bloblist.h b/include/bloblist.h
index 72c785411d..7eff709ec8 100644
--- a/include/bloblist.h
+++ b/include/bloblist.h
@@ -74,7 +74,7 @@
 #include 
 
 enum {
-   BLOBLIST_VERSION= 0,
+   BLOBLIST_VERSION= 1,
BLOBLIST_MAGIC  = 0x4a0fb10b,
 
BLOBLIST_ALIGN_LOG2 = 3,
-- 
2.25.1



[PATCH v3 03/14] bloblist: Change the magic value

2023-12-18 Thread Raymond Mao
From: Simon Glass 

This uses a new value with spec v0.9 so change it.

Signed-off-by: Simon Glass 
Co-developed-by: Raymond Mao 
Signed-off-by: Raymond Mao 
---
Changes in v2
- Update the bloblist magic to align to FW handoff spec v0.9.
Changes in v3
- Update the bloblist magic to align to FW handoff spec up to commit 3592349.

 include/bloblist.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/bloblist.h b/include/bloblist.h
index 5ad1337d1f..72c785411d 100644
--- a/include/bloblist.h
+++ b/include/bloblist.h
@@ -75,7 +75,7 @@
 
 enum {
BLOBLIST_VERSION= 0,
-   BLOBLIST_MAGIC  = 0xb00757a3,
+   BLOBLIST_MAGIC  = 0x4a0fb10b,
 
BLOBLIST_ALIGN_LOG2 = 3,
BLOBLIST_ALIGN  = 1 << BLOBLIST_ALIGN_LOG2,
-- 
2.25.1



[PATCH v3 02/14] bloblist: Adjust API to align in powers of 2

2023-12-18 Thread Raymond Mao
From: Simon Glass 

The updated bloblist structure stores the alignment as a power-of-two
value in its structures. Adjust the API to use this, to avoid needing to
calling ilog2().

Drop a stale comment while we are here.

Signed-off-by: Simon Glass 
Co-developed-by: Raymond Mao 
Signed-off-by: Raymond Mao 
Reviewed-by: Simon Glass 
---
Changes in v2
- Update the bloblist alignment to align to FW handoff spec v0.9.

 arch/x86/lib/tables.c |  3 ++-
 common/bloblist.c | 24 +++-
 include/bloblist.h| 12 +++-
 test/bloblist.c   |  4 ++--
 4 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/arch/x86/lib/tables.c b/arch/x86/lib/tables.c
index 5b5070f7ca..d43e77d373 100644
--- a/arch/x86/lib/tables.c
+++ b/arch/x86/lib/tables.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -104,7 +105,7 @@ int write_tables(void)
if (!gd->arch.table_end)
gd->arch.table_end = rom_addr;
rom_addr = (ulong)bloblist_add(table->tag, size,
-  table->align);
+  ilog2(table->align));
if (!rom_addr)
return log_msg_ret("bloblist", -ENOBUFS);
 
diff --git a/common/bloblist.c b/common/bloblist.c
index 5606487f5b..1e78a3d4b3 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -26,8 +26,6 @@
  * start address of the data in each blob is aligned as required. Note that
  * each blob's *data* is aligned to BLOBLIST_ALIGN regardless of the alignment
  * of the bloblist itself or the blob header.
- *
- * So far, only BLOBLIST_ALIGN alignment is supported.
  */
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -128,24 +126,24 @@ static struct bloblist_rec *bloblist_findrec(uint tag)
return NULL;
 }
 
-static int bloblist_addrec(uint tag, int size, int align,
+static int bloblist_addrec(uint tag, int size, int align_log2,
   struct bloblist_rec **recp)
 {
struct bloblist_hdr *hdr = gd->bloblist;
struct bloblist_rec *rec;
int data_start, new_alloced;
 
-   if (!align)
-   align = BLOBLIST_ALIGN;
+   if (!align_log2)
+   align_log2 = BLOBLIST_ALIGN_LOG2;
 
/* Figure out where the new data will start */
data_start = map_to_sysmem(hdr) + hdr->alloced + sizeof(*rec);
 
/* Align the address and then calculate the offset from ->alloced */
-   data_start = ALIGN(data_start, align) - map_to_sysmem(hdr);
+   data_start = ALIGN(data_start, 1U << align_log2) - map_to_sysmem(hdr);
 
/* Calculate the new allocated total */
-   new_alloced = data_start + ALIGN(size, align);
+   new_alloced = data_start + ALIGN(size, 1U << align_log2);
 
if (new_alloced > hdr->size) {
log_err("Failed to allocate %x bytes size=%x, need size=%x\n",
@@ -169,7 +167,7 @@ static int bloblist_addrec(uint tag, int size, int align,
 }
 
 static int bloblist_ensurerec(uint tag, struct bloblist_rec **recp, int size,
- int align)
+ int align_log2)
 {
struct bloblist_rec *rec;
 
@@ -182,7 +180,7 @@ static int bloblist_ensurerec(uint tag, struct bloblist_rec 
**recp, int size,
} else {
int ret;
 
-   ret = bloblist_addrec(tag, size, align, &rec);
+   ret = bloblist_addrec(tag, size, align_log2, &rec);
if (ret)
return ret;
}
@@ -204,22 +202,22 @@ void *bloblist_find(uint tag, int size)
return (void *)rec + rec->hdr_size;
 }
 
-void *bloblist_add(uint tag, int size, int align)
+void *bloblist_add(uint tag, int size, int align_log2)
 {
struct bloblist_rec *rec;
 
-   if (bloblist_addrec(tag, size, align, &rec))
+   if (bloblist_addrec(tag, size, align_log2, &rec))
return NULL;
 
return (void *)rec + rec->hdr_size;
 }
 
-int bloblist_ensure_size(uint tag, int size, int align, void **blobp)
+int bloblist_ensure_size(uint tag, int size, int align_log2, void **blobp)
 {
struct bloblist_rec *rec;
int ret;
 
-   ret = bloblist_ensurerec(tag, &rec, size, align);
+   ret = bloblist_ensurerec(tag, &rec, size, align_log2);
if (ret)
return ret;
*blobp = (void *)rec + rec->hdr_size;
diff --git a/include/bloblist.h b/include/bloblist.h
index 92dbfda21b..5ad1337d1f 100644
--- a/include/bloblist.h
+++ b/include/bloblist.h
@@ -76,7 +76,9 @@
 enum {
BLOBLIST_VERSION= 0,
BLOBLIST_MAGIC  = 0xb00757a3,
-   BLOBLIST_ALIGN  = 16,
+
+   BLOBLIST_ALIGN_LOG2 = 3,
+   BLOBLIST_ALIGN  = 1 << BLOBLIST_ALIGN_LOG2,
 };
 
 /* Supported tags - add new ones to tag_name in bloblist.c */
@@ -254,11 +256,11 @@ void *bloblist_find(uint ta

[PATCH v3 01/14] bloblist: Update the tag numbering

2023-12-18 Thread Raymond Mao
From: Simon Glass 

Align bloblist tags with the FW handoff spec v0.9.
The most common ones are from 0.
TF related ones are from 0x100.
All non-standard ones from 0xfff000.

Added new defined tags:
BLOBLISTT_OPTEE_PAGABLE_PART for TF.
BLOBLISTT_TPM_EVLOG and BLOBLISTT_TPM_CRB_BASE for TPM.

Signed-off-by: Simon Glass 
Co-developed-by: Raymond Mao 
Signed-off-by: Raymond Mao 
---
Changes in v2
- Align bloblist tags to FW handoff spec v0.9.
Changes in v3
- Add TPM related tags

 common/bloblist.c  | 18 ++---
 include/bloblist.h | 67 +-
 test/bloblist.c|  4 +--
 3 files changed, 52 insertions(+), 37 deletions(-)

diff --git a/common/bloblist.c b/common/bloblist.c
index a22f6c12b0..5606487f5b 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -36,16 +36,26 @@ static struct tag_name {
enum bloblist_tag_t tag;
const char *name;
 } tag_name[] = {
-   { BLOBLISTT_NONE, "(none)" },
+   { BLOBLISTT_VOID, "(void)" },
 
/* BLOBLISTT_AREA_FIRMWARE_TOP */
+   { BLOBLISTT_CONTROL_FDT, "Control FDT" },
+   { BLOBLISTT_HOB_BLOCK, "HOB block" },
+   { BLOBLISTT_HOB_LIST, "HOB list" },
+   { BLOBLISTT_ACPI_TABLES, "ACPI tables for x86" },
+   { BLOBLISTT_TPM_EVLOG, "TPM event log defined by TCG EFI" },
+   { BLOBLISTT_TPM_CRB_BASE, "TPM Command Response Buffer address" },
 
/* BLOBLISTT_AREA_FIRMWARE */
-   { BLOBLISTT_ACPI_GNVS, "ACPI GNVS" },
-   { BLOBLISTT_INTEL_VBT, "Intel Video-BIOS table" },
{ BLOBLISTT_TPM2_TCG_LOG, "TPM v2 log space" },
{ BLOBLISTT_TCPA_LOG, "TPM log space" },
-   { BLOBLISTT_ACPI_TABLES, "ACPI tables for x86" },
+   { BLOBLISTT_ACPI_GNVS, "ACPI GNVS" },
+
+   /* BLOBLISTT_AREA_TF */
+   { BLOBLISTT_OPTEE_PAGABLE_PART, "OP-TEE pagable part" },
+
+   /* BLOBLISTT_AREA_OTHER */
+   { BLOBLISTT_INTEL_VBT, "Intel Video-BIOS table" },
{ BLOBLISTT_SMBIOS_TABLES, "SMBIOS tables for x86" },
{ BLOBLISTT_VBOOT_CTX, "Chrome OS vboot context" },
 
diff --git a/include/bloblist.h b/include/bloblist.h
index 080cc46a12..92dbfda21b 100644
--- a/include/bloblist.h
+++ b/include/bloblist.h
@@ -81,7 +81,7 @@ enum {
 
 /* Supported tags - add new ones to tag_name in bloblist.c */
 enum bloblist_tag_t {
-   BLOBLISTT_NONE = 0,
+   BLOBLISTT_VOID = 0,
 
/*
 * Standard area to allocate blobs used across firmware components, for
@@ -89,42 +89,36 @@ enum bloblist_tag_t {
 * projects.
 */
BLOBLISTT_AREA_FIRMWARE_TOP = 0x1,
+   /*
+* Devicetree for use by firmware. On some platforms this is passed to
+* the OS also
+*/
+   BLOBLISTT_CONTROL_FDT = 1,
+   BLOBLISTT_HOB_BLOCK = 2,
+   BLOBLISTT_HOB_LIST = 3,
+   BLOBLISTT_ACPI_TABLES = 4,
+   BLOBLISTT_TPM_EVLOG = 5,
+   BLOBLISTT_TPM_CRB_BASE = 6,
 
/* Standard area to allocate blobs used across firmware components */
-   BLOBLISTT_AREA_FIRMWARE = 0x100,
+   BLOBLISTT_AREA_FIRMWARE = 0x10,
+   BLOBLISTT_TPM2_TCG_LOG = 0x10,  /* TPM v2 log space */
+   BLOBLISTT_TCPA_LOG = 0x11,  /* TPM log space */
/*
 * Advanced Configuration and Power Interface Global Non-Volatile
 * Sleeping table. This forms part of the ACPI tables passed to Linux.
 */
-   BLOBLISTT_ACPI_GNVS = 0x100,
-   BLOBLISTT_INTEL_VBT = 0x101,/* Intel Video-BIOS table */
-   BLOBLISTT_TPM2_TCG_LOG = 0x102, /* TPM v2 log space */
-   BLOBLISTT_TCPA_LOG = 0x103, /* TPM log space */
-   BLOBLISTT_ACPI_TABLES = 0x104,  /* ACPI tables for x86 */
-   BLOBLISTT_SMBIOS_TABLES = 0x105, /* SMBIOS tables for x86 */
-   BLOBLISTT_VBOOT_CTX = 0x106,/* Chromium OS verified boot context */
+   BLOBLISTT_ACPI_GNVS = 0x12,
 
-   /*
-* Project-specific tags are permitted here. Projects can be open source
-* or not, but the format of the data must be fuily documented in an
-* open source project, including all fields, bits, etc. Naming should
-* be: BLOBLISTT__
-*/
-   BLOBLISTT_PROJECT_AREA = 0x8000,
-   BLOBLISTT_U_BOOT_SPL_HANDOFF = 0x8000, /* Hand-off info from SPL */
-   BLOBLISTT_VBE   = 0x8001,   /* VBE per-phase state */
-   BLOBLISTT_U_BOOT_VIDEO = 0x8002, /* Video information from SPL */
-
-   /*
-* Vendor-specific tags are permitted here. Projects can be open source
-* or not, but the format of the data must be fuily documented in an
-* open source project, including all fields, bits, etc. Naming should
-* be BLOBLISTT__
-*/
-   BLOBLISTT_VENDOR_AREA = 0xc000,
+   /* Standard area to allocate blobs used for Trusted Firmware */
+   BLOBLISTT_AREA_TF = 0x100,
+   BLOBLISTT_OPTEE_PAGABLE_PART = 0x100,
 
-   /* Tags after this are not allocated for now */
-   BLOBLISTT_EXPANSION = 0x1,
+   /* Oth

[PATCH v3 00/14] Support Firmware Handoff spec via bloblist

2023-12-18 Thread Raymond Mao
Major changes:

Update bloblist to align to Firmware Handoff spec v0.9 (up to commit #3592349 
of the spec)
(https://github.com/FirmwareHandoff/firmware_handoff).

Includes:
- Align bloblist tags with the FW handoff spec
- Add an explicit alignment field in the header
- Update bloblist magic and version
- Use a packed format for blob record header
- Change the checksum alorigthm
- Use a void entry to handle the alignment
- Adjust the headers of bloblist and blob record
- Align the bloblist record data section start address

In v3, the implementation from boot arguments to bloblist and how to load the
FDT from the bloblist are moved to a forthcoming patch serie.

Raymond Mao (1):
  bloblist: Align bloblist used_size and total_size to spec

Simon Glass (13):
  bloblist: Update the tag numbering
  bloblist: Adjust API to align in powers of 2
  bloblist: Change the magic value
  bloblist: Set version to 1
  bloblist: Access record hdr_size and tag via a function
  bloblist: Drop spare value from bloblist record
  bloblist: Change the checksum algorithm
  bloblist: Checksum the entire bloblist
  bloblist: Handle alignment with a void entry
  bloblist: Reduce blob-header size
  bloblist: Adjust the bloblist header
  bloblist: Add alignment to bloblist_new()
  bloblist: Update documentation and header comment

 arch/x86/lib/tables.c|   3 +-
 common/bloblist.c| 205 ---
 doc/develop/bloblist.rst |   4 +-
 include/bloblist.h   | 166 ++-
 test/bloblist.c  | 105 +++-
 5 files changed, 287 insertions(+), 196 deletions(-)

-- 
2.25.1



Re: Proposal: U-Boot memory management

2023-12-18 Thread Simon Glass
Hi Heinrich,

On Sat, 16 Dec 2023 at 12:04, Heinrich Schuchardt  wrote:
>
> On 12/16/23 19:01, Simon Glass wrote:
> > Hi,
> >
> > This records my thoughts after a discussion with Ilias & Heinrich re
> > memory allocation in U-Boot.
> >
> > 1. malloc()
> >
> > malloc() is used for programmatic memory allocation. It allows memory
> > to be freed. It is not designed for very large allocations (e.g. a
> > 10MB kernel or 100MB ramdisk).
> >
> > 2. lmb
> >
> > lmb is used for large blocks of memory, such as those needed for a
> > kernel or ramdisk. Allocation is only transitory, for the purposes of
> > loading some images and booting. If the boot fails, then all lmb
> > allocations go away.
> >
> > lmb is set up by getting all available memory and then removing what
> > is used by U-Boot (code, data, malloc() space, etc.)
> >
> > lmb reservations have a few flags so that areas of memory can be
> > provided with attributes
> >
> > There are some corner cases...e.g. loading a file does an lmb
> > allocation but only for the purpose of avoiding a file being loaded
> > over U-Boot code/data. The allocation is dropped immediately after the
> > file is loaded. Within the bootm command, or when using standard boot,
> > this would be fairly easy to solve.
> >
> > Linux has renamed lmb to memblock. We should consider doing the same.
> >
> > 3. EFI
> >
> > EFI has its own memory-allocation tables.
> >
> > Like lmb, EFI is able to deal with large allocations. But via a 'pool'
> > function it can also do smaller allocations similar to malloc(),
> > although each one uses at least 4KB at present.
> >
> > EFI allocations do not go away when a boot fails.
> >
> > With EFI it is possible to add allocations post facto, in which case
> > they are added to the allocation table just as if the memory was
> > allocated with EFI to begin with.
> >
> > The EFI allocations and the lmb allocations use the same memory, so in
> > principle could conflict.
> >
> > EFI allocations are sometimes used to allocate internal U-Boot data as
> > well, if needed by the EFI app. For example, while efi_image_parse()
> > uses malloc(), efi_var_mem.c uses EFI allocations since the code runs
> > in the app context and may need to access the memory after U-Boot has
> > exited. Also efi_smbios.c uses allocate_pages() and then adds a new
> > mapping as well.
> >
> > EFI memory has attributes, including what the memory is used for (to
> > some degree of granularity). See enum efi_memory_type and struct
> > efi_mem_desc. In the latter there are also attribute flags - whether
> > memory is cacheable, etc.
> >
> > EFI also has the x86 idea of 'conventional' memory, meaning (I
> > believe) that below 4GB that isn't reserved for the hardware/system.
> > This is meaningless, or at least confusing, on ARM systems.
> >
> > 4. reservations
> >
> > It is perhaps worth mentioning a fourth method of memory management,
> > where U-Boot reserves chunks of memory before relocation (in
> > board_init_f.c), e.g. for the framebuffer, U-Boot code, the malloc()
> > region, etc.
> >
> >
> > Problems
> > —---
> >
> > There are no urgent problems, but here are some things that could be 
> > improved:
> >
> > 1. EFI should attach most of its data structures to driver model. This
> > work has started, with the partition support, but more effort would
> > help. This would make it easier to see which memory is related to
> > devices and which is separate.
> >
> > 2. Some drivers do EFI reservations today, whether EFI is used for
> > booting or not (e.g. rockchip video rk_vop_probe()).
>
> Hello Simon,
>
> thank you for summarizing our discussion.
>
> Some U-Boot drivers including rockchip video inform the EFI sub-system
> that memory is reserved.
>
> Furthermore drivers like arch/arm/mach-bcm283x/reset.c exist that are
> still used after ExitBootServices. mmio addresses have to be updated
> when Linux creates its virtual memory map. Currently this is done via
> efi_add_runtime_mmio(). A more UEFI style method would be to register an
> event handler for ExitBootServices() and use ConvertPointer() in the
> event handler.
>
> >
> > 3. U-Boot doesn't really map arch-specific memory attributes (e.g.
> > armv8's struct mm_region) to EFI ones.
>
> U-Boot fails to set up RWX properties. E.g. the region where a FIT image
> is loaded should not be executable.
>
> >
> > 4. EFI duplicates some code from bootm, some of which relates to
> > memory allocation (e.g. FDT fixup).
>
> Fixup code is not duplicated but invoked via image_setup_libfdt().
>
> >
> > 5. EFI code is used even if EFI is never used to boot
>
>
> * Only a minimum initialization of the EFI sub-system happens in
> efi_init_early().
> * Some EFI code is called when probing block devices because we wanted
> the EFI and the dm part to be integrated.
> * The rest of the initialization in efi_init_obj_list() is only invoked
> if an EFI command is invoked.
>
> >
> > 6. EFI allocations can result in the same memory being used as has
> 

[PATCH] ARM: dts: imx: Power off display output on Data Modul i.MX8M Mini/Plus eDM SBC

2023-12-18 Thread Marek Vasut
Turn display connector power off on boot and reboot to prevent any
bogus start up sequence of any panel potentially attached to the
display connector.

Signed-off-by: Marek Vasut 
---
Cc: Fabio Estevam 
Cc: Peng Fan 
Cc: Stefano Babic 
---
 .../dts/imx8mm-data-modul-edm-sbc-u-boot.dtsi | 49 +++
 .../dts/imx8mp-data-modul-edm-sbc-u-boot.dtsi | 48 ++
 2 files changed, 97 insertions(+)

diff --git a/arch/arm/dts/imx8mm-data-modul-edm-sbc-u-boot.dtsi 
b/arch/arm/dts/imx8mm-data-modul-edm-sbc-u-boot.dtsi
index 144c42b2103..a235e088fa4 100644
--- a/arch/arm/dts/imx8mm-data-modul-edm-sbc-u-boot.dtsi
+++ b/arch/arm/dts/imx8mm-data-modul-edm-sbc-u-boot.dtsi
@@ -77,10 +77,59 @@
 
 &gpio2 {
bootph-pre-ram;
+
+   dsi-reset-hog {
+   bootph-pre-ram;
+   gpio-hog;
+   output-high;
+   gpios = <2 GPIO_ACTIVE_LOW>;
+   line-name = "DSI_RESET_1V8#";
+   };
+
+
+   dsi-irq-hog {
+   bootph-pre-ram;
+   gpio-hog;
+   input;
+   gpios = <3 GPIO_ACTIVE_LOW>;
+   line-name = "DSI_IRQ_1V8#";
+   };
+
+   graphics-prsnt-hog {
+   bootph-pre-ram;
+   gpio-hog;
+   input;
+   gpios = <7 GPIO_ACTIVE_LOW>;
+   line-name = "GRAPHICS_PRSNT_1V8#";
+   };
 };
 
 &gpio3 {
bootph-pre-ram;
+
+   bl-enable-hog {
+   bootph-pre-ram;
+   gpio-hog;
+   output-low;
+   gpios = <0 GPIO_ACTIVE_HIGH>;
+   line-name = "BL_ENABLE_1V8";
+   };
+
+   tft-enable-hog {
+   bootph-pre-ram;
+   gpio-hog;
+   output-low;
+   gpios = <6 GPIO_ACTIVE_HIGH>;
+   line-name = "TFT_ENABLE_1V8";
+   };
+
+   graphics-gpio0-hog {
+   bootph-pre-ram;
+   gpio-hog;
+   input;
+   gpios = <7 GPIO_ACTIVE_HIGH>;
+   line-name = "GRAPHICS_GPIO0_1V8";
+   };
 };
 
 &gpio4 {
diff --git a/arch/arm/dts/imx8mp-data-modul-edm-sbc-u-boot.dtsi 
b/arch/arm/dts/imx8mp-data-modul-edm-sbc-u-boot.dtsi
index eafe9b9308c..a2b5976b6bd 100644
--- a/arch/arm/dts/imx8mp-data-modul-edm-sbc-u-boot.dtsi
+++ b/arch/arm/dts/imx8mp-data-modul-edm-sbc-u-boot.dtsi
@@ -67,10 +67,58 @@
 
 &gpio3 {
bootph-pre-ram;
+
+   bl-enable-hog {
+   bootph-pre-ram;
+   gpio-hog;
+   output-low;
+   gpios = <0 GPIO_ACTIVE_HIGH>;
+   line-name = "BL_ENABLE_1V8";
+   };
+
+   tft-enable-hog {
+   bootph-pre-ram;
+   gpio-hog;
+   output-low;
+   gpios = <6 GPIO_ACTIVE_HIGH>;
+   line-name = "TFT_ENABLE_1V8";
+   };
+
+   graphics-gpio0-hog {
+   bootph-pre-ram;
+   gpio-hog;
+   input;
+   gpios = <7 GPIO_ACTIVE_HIGH>;
+   line-name = "GRAPHICS_GPIO0_1V8";
+   };
 };
 
 &gpio4 {
bootph-pre-ram;
+
+   dsi-reset-hog {
+   bootph-pre-ram;
+   gpio-hog;
+   output-high;
+   gpios = <0 GPIO_ACTIVE_LOW>;
+   line-name = "DSI_RESET_1V8#";
+   };
+
+   graphics-prsnt-hog {
+   bootph-pre-ram;
+   gpio-hog;
+   input;
+   gpios = <18 GPIO_ACTIVE_LOW>;
+   line-name = "GRAPHICS_PRSNT_1V8#";
+   };
+
+   dsi-irq-hog {
+   bootph-pre-ram;
+   gpio-hog;
+   input;
+   gpios = <19 GPIO_ACTIVE_LOW>;
+   line-name = "DSI_IRQ_1V8#";
+   };
 };
 
 &gpio5 {
-- 
2.43.0



Re: [PATCH v1] spi: dw: add check for Rx FIFO overflow

2023-12-18 Thread Maxim Kiselev
Hello Jagan,

пн, 18 дек. 2023 г. в 14:28, Jagan Teki :
>
> On Tue, Oct 17, 2023 at 12:35 PM Maksim Kiselev  wrote:
> >
> > If even one byte is lost due to Rx FIFO overflow then we will never
> > exit the read loop. Because the (priv->rx != priv->rx_end) condition will
> > be always true.
> >
> > Let's check if Rx FIFO overflow occurred and exit the read loop
> > in this case.
> >
> > Signed-off-by: Maksim Kiselev 
> > ---
> >  drivers/spi/designware_spi.c | 24 +---
> >  1 file changed, 21 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/spi/designware_spi.c b/drivers/spi/designware_spi.c
> > index 1c7d0ca310..0f443bff8e 100644
> > --- a/drivers/spi/designware_spi.c
> > +++ b/drivers/spi/designware_spi.c
> > @@ -111,6 +111,15 @@
> >  #define SR_TX_ERR  BIT(5)
> >  #define SR_DCOLBIT(6)
> >
> > +/* Bit fields in ISR, IMR, RISR, 7 bits */
> > +#define DW_SPI_INT_MASKGENMASK(5, 0)
> > +#define DW_SPI_INT_TXEIBIT(0)
> > +#define DW_SPI_INT_TXOIBIT(1)
> > +#define DW_SPI_INT_RXUIBIT(2)
> > +#define DW_SPI_INT_RXOIBIT(3)
> > +#define DW_SPI_INT_RXFIBIT(4)
> > +#define DW_SPI_INT_MSTIBIT(5)
>
> Why do we need unused macros?

Actually DW_SPI_INT_RXOI is used. As for the other bits in DW_SPI_RISR,
I decided to add them all to match a Linux driver.

We already have a lot of unused macro in this driver (ex. definitions
for bits in CTRLR0_FRF,
CTRLR0_MODE regs and so on).

So, what's a problem with adding the DW_SPI_RISR bits?

Cheers,
Maksim

>
> Jagan.


Re: Adding EFI runtime support to the Arm's FF-A bus

2023-12-18 Thread Abdellatif El Khlifi
Hi Mark,

On Thu, Dec 14, 2023 at 05:47:42PM +0100, Mark Kettenis wrote:
> > Date: Thu, 14 Dec 2023 15:53:46 +
> > From: Abdellatif El Khlifi 
> 
> Hi Abdellatif,
> 
> > Hi guys,
> > 
> > I'd like to ask for advice regarding adding EFI RT support to the Arm's 
> > FF-A bus
> > in U-Boot.
> > 
> > The objective is to enable the FF-A messaging APIs in EFI RT to be
> > used for comms with the secure world. This will help getting/setting
> > EFI variables through FF-A.
> > 
> > The existing FF-A APIs in U-Boot call the DM APIs (which are not available 
> > at RT).
> > 
> > Two possible solutions:
> > 
> > 1/ having the entire U-Boot in RT space (as Simon stated in this 
> > discussion[1])
> 
> I don't think this is a terribly good idea.  With this approach orders
> of magnitude more code will be present in kernel address space one the
> OS kernel is running and calling into the EFI runtime.  Including code
> that may access hardware devices that are now under OS control.  It
> will be nigh impossible to audit all that code and make sure that only
> a safe subset of it gets called.  So...
> 
> > 
> > 2/ Create an RT variant for the FF-A APIs needed.
> >   These RT variant don't call the DM APIs
> >   (e.g: ffa_mm_communicate_runtime, ffa_sync_send_receive_runtime, ...)
> > 
> > What do you recommend please ?
> 
> ...this is what I would recommend.  Preferably in a way that refactors
> the code such that the low-level functionality is shared between the
> DM and non-DM APIs.

That's my preferred solution, thanks.

Cheers,
Abdellatif


Re: [GIT PULL] u-boot-riscv/next

2023-12-18 Thread Tom Rini
On Mon, Dec 18, 2023 at 07:44:15PM +0800, Leo Liang wrote:

> Hi Tom,
> 
> The following changes since commit fdefb4e194c65777fa11479119adaa71651f41d4:
> 
>   Merge tag 'efi-next-20231217' of 
> https://source.denx.de/u-boot/custodians/u-boot-efi into next (2023-12-17 
> 09:11:06 -0500)
> 
> are available in the Git repository at:
> 
>   https://source.denx.de/u-boot/custodians/u-boot-riscv.git next
> 
> for you to fetch changes up to 44a792c99498f5a9d3526019779d66585978c491:
> 
>   riscv: sifive: unmatched: migrate to text environment (2023-12-18 11:09:01 
> +0800)
> 
> CI result shows no issue: 
> https://source.denx.de/u-boot/custodians/u-boot-riscv/-/pipelines/18996

Applied to u-boot/next, thanks!

-- 
Tom


signature.asc
Description: PGP signature


Re: Adding EFI runtime support to the Arm's FF-A bus

2023-12-18 Thread Abdellatif El Khlifi
Hi Ilias

On Thu, Dec 14, 2023 at 09:47:13PM +0200, Ilias Apalodimas wrote:
> Hi Mark, Abdellatif
> 
> On Thu, 14 Dec 2023 at 18:47, Mark Kettenis  wrote:
> >
> > > Date: Thu, 14 Dec 2023 15:53:46 +
> > > From: Abdellatif El Khlifi 
> >
> > Hi Abdellatif,
> >
> > > Hi guys,
> > >
> > > I'd like to ask for advice regarding adding EFI RT support to the Arm's 
> > > FF-A bus
> > > in U-Boot.
> > >
> > > The objective is to enable the FF-A messaging APIs in EFI RT to be
> > > used for comms with the secure world. This will help getting/setting
> > > EFI variables through FF-A.
> > >
> > > The existing FF-A APIs in U-Boot call the DM APIs (which are not 
> > > available at RT).
> > >
> > > Two possible solutions:
> > >
> > > 1/ having the entire U-Boot in RT space (as Simon stated in this 
> > > discussion[1])
> >
> > I don't think this is a terribly good idea.  With this approach orders
> > of magnitude more code will be present in kernel address space one the
> > OS kernel is running and calling into the EFI runtime.  Including code
> > that may access hardware devices that are now under OS control.  It
> > will be nigh impossible to audit all that code and make sure that only
> > a safe subset of it gets called.  So...
> 
> +100
> I think we should draw a line here. I mentioned it on another thread,
> but I did a shot BoF in Plumbers discussing issues like this,
> problems, and potential solutions [0] [1]. Since that talk patches for
> the kernel that 'solve' the problem for RPMBs got pulled into
> linux-next [2].

I watched your talk. Great work, thanks :)

> The TL;DR of that talk is that if the kernel ends up being in control
> of the hardware that stores the EFI variables, we need to find elegant
> ways to teach the kernel how to store those directly. The EFI
> requirement of an isolated flash is something that mostly came from
> the x86 world and is not a reality on the majority of embedded boards.
> I also think we should give up on Authenticated EFI variables in that
> case. We get zero guarantees unless the medium has similar properties
> to an RPMB.
> If a vendor cares about proper UEFI secure boot he can implement
> proper hardware.
> 
> >
> > >
> > > 2/ Create an RT variant for the FF-A APIs needed.
> > >   These RT variant don't call the DM APIs
> > >   (e.g: ffa_mm_communicate_runtime, ffa_sync_send_receive_runtime, 
> > > ...)
> > >
> > > What do you recommend please ?
> >
> > ...this is what I would recommend.  Preferably in a way that refactors
> > the code such that the low-level functionality is shared between the
> > DM and non-DM APIs.
> 
> Yes. The only thing you need to keep alive is the machinery to talk to
> the secure world. The bus, flash driver etc should all be running
> isolated in there. In that case you can implement SetVariableRT as
> described the the EFI spec.

Cool, thanks. That's my preferred solution too.

mm_communicate() should be able to detect runtime mode so it calls 
ffa_mm_communicate_runtime().

Is there a way to check whether we are in EFI runtime or not ?

Suggested changes (pseudo-code):

__efi_runtime mm_communicate () {
#if CONFIG_IS_ENABLED(ARM_FFA_TRANSPORT)
if (RT) { /* NEW */
        ret = ffa_mm_communicate_runtime(comm_buf, dsize); /* NEW */
} else {
    mm_comms = get_mm_comms();
    if (mm_comms == MM_COMMS_FFA)
        ret = ffa_mm_communicate(comm_buf, dsize);
    else
        ret = optee_mm_communicate(comm_buf, dsize);
}
#else
...
#endif

Existing code:  
https://github.com/u-boot/u-boot/blob/master/lib/efi_loader/efi_variable_tee.c#L417

Cheers,
Abdellatif


Re: Pull request: u-boot-spi/master [for-next]

2023-12-18 Thread Tom Rini
On Mon, Dec 18, 2023 at 03:56:25PM +0530, Jagan Teki wrote:

> Hi Tom,
> 
> Please pull this PR for next.
> 
> Summary:
> - spi_nor_read_sfdp_dma_unsafe (Vaishnav)
> - w25q01/02 (Jim)
> 
> CI:
> https://source.denx.de/u-boot/custodians/u-boot-spi/-/pipelines/18995
> 
> thanks,
> Jagan.
> 
> The following changes since commit 2f0282922b2c458eea7f85c500a948a587437b63:
> 
>   Prepare v2024.01-rc4 (2023-12-04 13:46:56 -0500)
> 
> are available in the Git repository at:
> 
>   https://source.denx.de/u-boot/custodians/u-boot-spi master
> 
> for you to fetch changes up to 959a4a0838acf7ef733e000d1304cea6711b8945:
> 
>   spi: cadence-quadspi: Fix error message on stuck busy state (2023-12-14 
> 23:56:19 +0530)
> 

Applied to u-boot/next, thanks!

-- 
Tom


signature.asc
Description: PGP signature


[tom.r...@gmail.com: Fwd: New Defects reported by Coverity Scan for Das U-Boot]

2023-12-18 Thread Tom Rini
Here's the latest report.

-- Forwarded message -
From: 
Date: Mon, Dec 18, 2023 at 8:42 AM
Subject: New Defects reported by Coverity Scan for Das U-Boot
To: 


Hi,

Please find the latest report on new defect(s) introduced to Das
U-Boot found with Coverity Scan.

1 new defect(s) introduced to Das U-Boot found with Coverity Scan.


New defect(s) Reported-by: Coverity Scan
Showing 1 of 1 defect(s)


** CID 470930:  Uninitialized variables  (UNINIT)
/boot/bootmeth_efi.c: 465 in distro_efi_boot()



*** CID 470930:  Uninitialized variables  (UNINIT)
/boot/bootmeth_efi.c: 465 in distro_efi_boot()
459  */
460 if (bflow->flags & BOOTFLOWF_USE_BUILTIN_FDT) {
461 log_debug("Booting with built-in fdt\n");
462 snprintf(cmd, sizeof(cmd), "bootefi %lx", kernel);
463 } else {
464 log_debug("Booting with external fdt\n");
>>> CID 470930:  Uninitialized variables  (UNINIT)
>>> Using uninitialized value "fdt" when calling "snprintf". [Note: The 
>>> source code implementation of the function has been overridden by a builtin 
>>> model.]
465 snprintf(cmd, sizeof(cmd), "bootefi %lx %lx",
kernel, fdt);
466 }
467
468 if (run_command(cmd, 0))
469 return log_msg_ret("run", -EINVAL);
470


-- 
Tom


signature.asc
Description: PGP signature


Re: Booting fails on the sandbox

2023-12-18 Thread Heinrich Schuchardt



Am 18. Dezember 2023 16:01:36 MEZ schrieb Simon Glass :
>Hi Heinrich,
>
>On Sat, 16 Dec 2023 at 14:08, Heinrich Schuchardt  wrote:
>>
>> On 12/16/23 19:45, Simon Glass wrote:
>> > Hi Heinrich,
>> >
>> > On Sat, 16 Dec 2023 at 07:50, Heinrich Schuchardt  
>> > wrote:
>> >>
>> >> Hello Simon,
>> >>
>> >> I have built sandbox_defconfig with PREBOOT='host bind 0 ../sct.img'
>> >>
>> >> On the image I have an ESP with file EFI/BOOT/BOOTX64.EFI.
>> >>
>> >> I would expect the sandbox to boot from the ESP.
>> >>
>> >> But when starting the sandbox is does not boot. Instead it shows a menu
>> >> with some Fedora related entry:
>> >>
>> >> Fedora-Workstation-armhfp-31-1.9 Boot Options.
>> >> 1:  Fedora-Workstation-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl)
>> >>
>> >> This makes absolutely no sense on an x86_64 system. Could you, please,
>> >> fix sandbox_defconfig to boot according to distroboot.
>> >
>> > What sort of 'fix' are you thinking of? You should be able to discover
>> > all the options with 'bootflow scan' and then use 'bootflow select' or
>> > 'bootflow menu' to choose which one you want.
>> >
>> > The Fedora thing is used for testing and development.
>>
>> I want to autoboot the sandbox without manual intervention. This
>> requires a sane state.
>
>Well, stop doing that :-)
>
>Really, sandbox is for development and CI testing. It is not designed
>to boot anything automatically.

It is the fastest way to run the UEFI SCT. But that requires an EFI compliant 
dandbox.

How do you want to test the EFI bootflow on the sandbox  when wrecking it?

>
>>
>> If that Fedora thingy is only needed in CI, can't we put it into a
>> config segment that only used by the CI scripts and have the sandbox in
>> a generally usable state? Or can we let the Python tests add the
>> otherwise not needed bootflow?
>
>Yes, we could. We have some extra mmc devices which are manually
>enabled in tests.
>
>But it is handy to be able to try out a distro without doing anything
>special. I suppose we could add a sandbox command to enable an mmc
>device in test.dts
>
>If you have ideas / patches that is fine...it's just that I do want to
>be able to use sandbox for basic development and trying things out.
>
>Regards,
>Simon


Re: [PATCH v2] net: mv88e6xxx: fix missing SMI address initialization

2023-12-18 Thread Marek Behún
On Wed, 6 Dec 2023 15:35:56 +0100
Marek Mojík  wrote:

> The mv88e6xxx driver does not currently initialize the smi_addr field, but
> instead keeps the default zero value. This leads to driver being unusable
> on devices where the switch is not on address zero of the mdio bus. Fix
> this problem by reading the SMI address from device tree.
> 
> Signed-off-by: Marek Mojík 
> ---
>  drivers/net/mv88e6xxx.c | 8 
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/net/mv88e6xxx.c b/drivers/net/mv88e6xxx.c
> index c073f81e72..8fbbc1cacc 100644
> --- a/drivers/net/mv88e6xxx.c
> +++ b/drivers/net/mv88e6xxx.c
> @@ -745,6 +745,7 @@ static int mv88e6xxx_probe(struct udevice *dev)
>  {
>   struct dsa_pdata *dsa_pdata = dev_get_uclass_plat(dev);
>   struct mv88e6xxx_priv *priv = dev_get_priv(dev);
> + fdt_addr_t smi_addr;
>   int val, ret;
>  
>   if (ofnode_valid(dev_ofnode(dev)) &&
> @@ -753,6 +754,13 @@ static int mv88e6xxx_probe(struct udevice *dev)
>   return -ENODEV;
>   }
>  
> + smi_addr = dev_read_addr(dev);
> + if (smi_addr == FDT_ADDR_T_NONE) {
> + dev_err(dev, "Missing SMI address\n");
> + return -EINVAL;
> + }
> + priv->smi_addr = smi_addr;
> +
>   /* probe internal mdio bus */
>   ret = mv88e6xxx_probe_mdio(dev);
>   if (ret)

Reviewed-by: Marek Behún 


Re: [PATCH 2/2 v3] smbios: Fallback to the default DT if sysinfo nodes are missing

2023-12-18 Thread neil . armstrong

Hi,

On 18/12/2023 16:01, Simon Glass wrote:

Hi Neil,

On Mon, 18 Dec 2023 at 02:54,  wrote:


On 17/12/2023 19:41, Tom Rini wrote:

On Sat, Dec 16, 2023 at 11:46:18AM -0700, Simon Glass wrote:

Hi Tom,

On Thu, 14 Dec 2023 at 06:11, Tom Rini  wrote:



[..]


And my point with the above is that other SoC maintainers (Neil, for
amlogic) have said (paraphrasing) he does not want to do N smbios node
patches. Which is why Ilias' patch is if not 1000% correct, it's Good
Enough and will, if it's really a problem to have all lower case
information displayed, spur people to see providing that information as
a real problem that needs to be solved. Or it will be seen as good
enough.



If some platforms requires a more "correct" smbios dataset, then they're
welcome adding the required smbios node, and it's perfectly understandable,
but for the other community-maintained platforms we need some valid fallback
data otherwise they'll be de facto excluded from some tools for no valid 
reasons.


Do you know which tools require SMBIOS tables? I found sos and another
Redhat one.


SMBIOS data is translated into dmi informations in Linux, and a little
lookup in GitHub gives 6.4K files using something from 
/sys/devices/virtual/dmi/id/,
and by very commonly used tools like lshw and probably fwupd.

Neil



Regards,
Simon




Re: [PATCH 00/13] arm: exynos: Add E850-96 board

2023-12-18 Thread Sam Protsenko
On Tue, Dec 12, 2023 at 9:16 PM Sam Protsenko
 wrote:
>
> NOTE: This patch series depends on "pinctrl: exynos: Prepare for other
> SoCs support" series [1]. It should be applied first.
>
> Add Exynos850 SoC and WinLink's E850-96 board support. A short overview
> of series additions and modifications:
>   * USI driver: configures UART block
>   * PMU driver: connects AP UART lines to uart1 pins)
>   * Exynos850 clock driver: generates UART clocks
>   * Exynos850 pinctrl driver: mux UART pins
>   * serial_s5p: UART driver
>   * Exynos850 SoC: dtsi files and MMU maps
>   * E850-96 board: dts files, defconfig, board file and doc
>
> Most of the code was borrowed from mainline Linux kernel (where this
> board is already enabled) and adapted for U-Boot. Preliminary
> preparation for this series includes next patches / series (already
> merged):
>
>   * commit 585a2aaac2ac ("arm: exynos: Include missing CPU header in
>   soc.c")
>   * commit c9ab9f30c8e4 ("arm: exynos: Include missing CPU header in
>   gpio.h")
>   * commit 11bd2787deff ("watchdog: s5p_wdt: Include missing CPU
>   header")
>   * commit 08cfa971a717 ("exynos: Avoid duplicate reset_cpu with
>   SYSRESET enabled")
>   * commit f655090901dc ("clk: exynos: Add header guard for clk-pll.h")
>   * commit 2227f4c0afed ("serial: s5p: Fix clk_get_by_index() error code
>   check")
>   * commit a0615ffc99a5 ("serial: s5p: Remove common.h inclusion")
>   * commit 5ad21de6bae0 ("serial: s5p: Use livetree API to get "id"
>   property")
>   * commit e79f630dbf67 ("serial: s5p: Use named constants for register
>   values")
>   * commit a627f2802a71 ("serial: s5p: Improve coding style")
>   * commit 33e7ca5a9b6a ("serial: s5p: Use dev_read_addr_ptr() to get
>   base address")
>   * commit 6219b47c4d91 ("board: samsung: Fix SYS_CONFIG_NAME configs in
>   axy17lte Kconfig")
>   * commit 470682ace1e0 ("configs: Remove unneeded SYS_CONFIG_NAME from
>   a*y17lte defconfigs")
>
> and series [1] (dependency) is still pending.
>
> For more detailed description please see the board documentation (added
> in PATCH #12) and corresponding commit messages.
>
> [1] https://lists.denx.de/pipermail/u-boot/2023-November/539033.html
>
> Sam Protsenko (13):
>   dt-bindings: soc: samsung: Add Exynos USI
>   dt-bindings: soc: samsung: Add Exynos PMU
>   dt-bindings: clock: Add Exynos850 clock controller
>   soc: samsung: Add Exynos USI driver
>   soc: samsung: Add Exynos PMU driver
>   clk: exynos: Move pll code into clk-exynos7420
>   clk: exynos: Add Samsung clock framework
>   clk: exynos: Add Exynos850 clock driver
>   pinctrl: exynos: Add pinctrl support for Exynos850
>   serial: s5p: Add Exynos850 compatible
>   arm: exynos: Add Exynos850 SoC support
>   board: samsung: Add support for E850-96 board
>   MAINTAINERS: Add new Samsung subsystems
>
>  MAINTAINERS   |   25 +
>  arch/arm/dts/Makefile |1 +
>  arch/arm/dts/exynos-pinctrl.h |   79 +
>  arch/arm/dts/exynos850-e850-96-u-boot.dtsi|   37 +
>  arch/arm/dts/exynos850-e850-96.dts|  273 
>  arch/arm/dts/exynos850-pinctrl.dtsi   |  663 +
>  arch/arm/dts/exynos850.dtsi   |  809 +++
>  arch/arm/mach-exynos/Kconfig  |   28 +-
>  arch/arm/mach-exynos/mmu-arm64.c  |   34 +
>  board/samsung/e850-96/Kconfig |   16 +
>  board/samsung/e850-96/MAINTAINERS |9 +
>  board/samsung/e850-96/Makefile|6 +
>  board/samsung/e850-96/e850-96.c   |   22 +
>  configs/e850-96_defconfig |   21 +
>  doc/board/samsung/e850-96.rst |   87 ++
>  .../img/exynos850-boot-architecture.svg   | 1283 +
>  doc/board/samsung/index.rst   |1 +
>  .../clock/samsung,exynos850-clock.yaml|  307 
>  .../soc/samsung/exynos-pmu.yaml   |   85 ++
>  .../soc/samsung/exynos-usi.yaml   |  162 +++
>  drivers/clk/exynos/Kconfig|7 +
>  drivers/clk/exynos/Makefile   |   11 +-
>  drivers/clk/exynos/clk-exynos7420.c   |   25 +-
>  drivers/clk/exynos/clk-exynos850.c|  189 +++
>  drivers/clk/exynos/clk-pll.c  |  167 ++-
>  drivers/clk/exynos/clk-pll.h  |   16 +-
>  drivers/clk/exynos/clk.c  |  121 ++
>  drivers/clk/exynos/clk.h  |  228 +++
>  drivers/pinctrl/exynos/Kconfig|8 +
>  drivers/pinctrl/exynos/Makefile   |1 +
>  drivers/pinctrl/exynos/pinctrl-exynos850.c|  125 ++
>  drivers/serial/serial_s5p.c   |1 +
>  drivers/soc/Kconfig   

Re: [PATCH v2 8/9] configs: qemu: add config fragment for ACPI

2023-12-18 Thread Tom Rini
On Mon, Dec 18, 2023 at 08:01:34AM -0700, Simon Glass wrote:
> Hi Heinrich,
> 
> On Sat, 16 Dec 2023 at 12:27, Heinrich Schuchardt
>  wrote:
> >
> > On 12/16/23 19:46, Simon Glass wrote:
> > > On Fri, 15 Dec 2023 at 06:33, Heinrich Schuchardt
> > >  wrote:
> > >>
> > >> Provide a configuration fragment to enable ACPI on QEMU.
> > >>
> > >> Signed-off-by: Heinrich Schuchardt 
> > >> Acked-by: Ilias Apalodimas 
> > >> ---
> > >> v2:
> > >>  no change
> > >> ---
> > >>   MAINTAINERS |  1 +
> > >>   board/emulation/configs/acpi.config |  3 +++
> > >>   doc/board/emulation/acpi.rst| 23 +++
> > >>   doc/board/emulation/index.rst   |  1 +
> > >>   4 files changed, 28 insertions(+)
> > >>   create mode 100644 board/emulation/configs/acpi.config
> > >>   create mode 100644 doc/board/emulation/acpi.rst
> > >>
> > >
> > > Reviewed-by: Simon Glass 
> >
> > Are you planning to enable binman to build configurations with config
> > fragments? This would be needed for testing in CI.
> 
> We still have not decided on a mechanism to name things which are made
> up of a base config and a fragment. The current proposal is [1] which
> I think is probably OK, but I have not tried to look at this in
> buildman yet.
> 
> Regards,
> Simon
> 
> [1] https://patchwork.ozlabs.org/user/todo/uboot/?series=380278

Patchwork a little frustrating about links sometimes, this should be:
https://patchwork.ozlabs.org/project/uboot/list/?series=380278&state=*

Which _I_ don't think we need, but I'm also in the minority here so I'm
not nak'ing it.

-- 
Tom


signature.asc
Description: PGP signature


Re: [PATHv1 0/9] net fixes prior lwip

2023-12-18 Thread Tom Rini
On Mon, Dec 18, 2023 at 09:03:47PM +0600, Maxim Uvarov wrote:
> Hi,
> 
> Do I need to resend this patchset with small comment message correction or
> it can be done on the apply?

Yes, please v2 that patch and perhaps re-read all of the commits and see
if all of the commit messages could be improved / expanded upon a
little more, thanks.

-- 
Tom


signature.asc
Description: PGP signature


Re: [PATHv1 0/9] net fixes prior lwip

2023-12-18 Thread Maxim Uvarov
Hi,

Do I need to resend this patchset with small comment message correction or
it can be done on the apply?

Thank you,
Maxim.

On Mon, 4 Dec 2023 at 18:06, Maxim Uvarov  wrote:

> Add small net fixes prior lwip patch.
>
> CI for this patch set:
>
> https://dev.azure.com/u-boot/u-boot/_build/results?buildId=7460&view=results
>
> Maxim Uvarov (9):
>   test_net: print out net list
>   net: sandbox: fix NULL pointer derefences
>   net/smc911x: fix return from smc911x_send
>   sandbox: eth-raw-os: successful return code is 0
>   driver/net/rtl8139: remove debug print
>   mach-socfpga: do not overlap defines with lwip
>   bcm_ns3: fix overlap define with lwip
>   omap3: rename mem_init
>   Makefile: add dtbs to clean
>
>  Makefile   | 3 ++-
>  arch/arm/include/asm/arch-omap3/mem.h  | 2 +-
>  arch/arm/mach-omap2/omap3/board.c  | 2 +-
>  arch/arm/mach-omap2/omap3/emif4.c  | 4 ++--
>  arch/arm/mach-omap2/omap3/sdrc.c   | 6 +++---
>  arch/arm/mach-socfpga/include/mach/handoff_soc64.h | 6 --
>  arch/arm/mach-socfpga/wrap_handoff_soc64.c | 9 +
>  arch/sandbox/cpu/eth-raw-os.c  | 2 +-
>  drivers/net/rtl8139.c  | 2 +-
>  drivers/net/sandbox.c  | 3 +++
>  drivers/net/smc911x.c  | 2 +-
>  include/configs/bcm_ns3.h  | 6 +++---
>  test/py/tests/test_net.py  | 2 ++
>  13 files changed, 29 insertions(+), 20 deletions(-)
>
> --
> 2.30.2
>
>


Re: [PATCH 2/2 v2] smbios: Fallback to the default DT if sysinfo nodes are missing

2023-12-18 Thread Simon Glass
Hi Mark,

On Wed, 13 Dec 2023 at 14:00, Mark Kettenis  wrote:
>
> > From: Simon Glass 
> > Date: Wed, 13 Dec 2023 13:41:05 -0700
> >
> > Hi Tom,
> >
> > On Wed, 13 Dec 2023 at 13:19, Tom Rini  wrote:
> > >
> > > On Wed, Dec 13, 2023 at 12:50:03PM -0700, Simon Glass wrote:
> > > > Hi Ilias,
> > > >
> > > > On Mon, 11 Dec 2023 at 00:49, Ilias Apalodimas
> > > >  wrote:
> > > > >
> > > > > Hi Tom,
> > > > >
> > > > > On Sat, 9 Dec 2023 at 20:49, Tom Rini  wrote:
> > > > > >
> > > > > > On Wed, Dec 06, 2023 at 06:03:14PM +0200, Ilias Apalodimas wrote:
> > > > > > > Hi Simon,
> > > > > > >
> > > > > > > On Sat, 2 Dec 2023 at 20:28, Simon Glass  
> > > > > > > wrote:
> > > > > > > >
> > > > > > > > Hi Ilias,
> > > > > > > >
> > > > > > > > On Wed, 29 Nov 2023 at 23:50, Ilias Apalodimas
> > > > > > > >  wrote:
> > > > > > > > >
> > > > > > > > > Hi Simon,
> > > > > > > > >
> > > > > > > > > [...]
> > > > > > > > >
> > > > > > > > >> > Changes since v1:
> > > > > > > > >> > - Tokenize the DT node entry and use the appropriate value 
> > > > > > > > >> > instead of
> > > > > > > > >> >   the entire string
> > > > > > > > >> > - Removed Peters tested/reviewed-by tags due to the above
> > > > > > > > >> >  lib/smbios.c | 94 
> > > > > > > > >> > +---
> > > > > > > > >> >  1 file changed, 90 insertions(+), 4 deletions(-)
> > > > > > > > >> >
> > > > > > > > >>
> > > > > > > > >> Can this be put behind a Kconfig? It adds quite a bit of 
> > > > > > > > >> code which
> > > > > > > > >> punishes those boards which do the right thing.
> > > > > > > > >
> > > > > > > > >
> > > > > > > > > Sure but OTOH the code increase should be really minimal. But 
> > > > > > > > > I don't mind I can add a Kconfig
> > > > > > > > >
> > > > > > > > >>
> > > > > > > > >> > +
> > > > > > > > >> > +   dt_str = ofnode_read_string(ofnode_root(), 
> > > > > > > > >> > nprop->dt_str);
> > > > > > > > >>
> > > > > > > > >> Could this use ofnode_read_string_index() ?
> > > > > > > > >
> > > > > > > > >
> > > > > > > > > Maybe, I'll have a look and change it if that works
> > > > > > >
> > > > > > > Unless I am missing something this doesn't work.
> > > > > > > This is designed to return a string index from a DT property 
> > > > > > > that's defined as
> > > > > > > foo_property = "value1", "value2" isn't it?
> > > > > > >
> > > > > > > The code above is trying to read an existing property (e.g 
> > > > > > > compatible)
> > > > > > > and get the string after the comma delimiter.
> > > > > > > Perhaps I should add this in drivers/core/ofnode.c instead?
> > > > > > >
> > > > > > > > >
> > > > > > > > > [...]
> > > > > > > > >
> > > > > > > > >>
> > > > > > > > >> Any chance of a test for this code?
> > > > > > > > >
> > > > > > > > >
> > > > > > > > > Sure, but any suggestions on where to add the test?
> > > > > > > > > SMBIOS tables are populated on OS booting, do we have a test 
> > > > > > > > > somewhere that boots an OS?
> > > > > > > >
> > > > > > > > They are written on startup, right? They should certainly be in 
> > > > > > > > place
> > > > > > > > before U-Boot enters the command line.
> > > > > > >
> > > > > > > Not always.  I am not sure if x86 does that, but on the rest of 
> > > > > > > the
> > > > > > > architectures, they are only initialized when the efi smbios code
> > > > > > > runs. Wasn't this something you were trying to change?
> > > > > >
> > > > > > One of those things I keep repeating is that we don't know for sure 
> > > > > > what
> > > > > > the right values here are until we load the DT the OS _will_ use. 
> > > > > > It's
> > > > > > quite valid to start U-Boot and pass it a generic "good enough" DT 
> > > > > > at
> > > > > > run time until U-Boot can see (GPIOs, EEPROM, whatever) what it's 
> > > > > > on and
> > > > > > what the real DT to load before passing to the OS is. Since U-Boot
> > > > > > doesn't need SMBIOS tables itself, we should make these "late" not
> > > > > > "early".
> > > > >
> > > > > Fair enough, we can defer the init and testing of those late, just
> > > > > before we are about to boot. But this is irrelevant to what this patch
> > > > > does, can we get the fallback mechanism in first, assuming everyone is
> > > > > ok with the patch now?
> > > > >
> > > >
> > > > I would like this behind a Kconfig. Making it the default means people
> > > > are going to start relying on (in user space) and then discover later
> > > > that it is wrong.
> > >
> > > What do you mean wrong, exactly?
> >
> > "raspberrypi" instead of "Raspberry Pi", for example, or "friendlyarm"
> > instead of "FriendlyElec"
>
> Heh, well, even in the x86 world vendors can't even spell their own
> name consistently.
>
> > I just wonder what this information is actually used for. If it is
> > just for fun, that is fine, but I believe some tools do use dmidecode,
> > at which point it needs to be accurate and should not change later,
> > e.g. when someone decides to actually add t

Re: [PATCH 1/2 v2] smbios: Simplify reporting of unknown values

2023-12-18 Thread Simon Glass
Hi Ilias,

On Wed, 6 Dec 2023 at 04:36, Ilias Apalodimas
 wrote:
>
> [...]
>
> >
> >>
> >> > str = "Unknown";
> >> >
> >> > for (;;) {
> >> > @@ -151,8 +151,7 @@ static int smbios_add_prop_si(struct smbios_ctx 
> >> > *ctx, const char *prop,
> >> > const char *str;
> >> >
> >> > str = ofnode_read_string(ctx->node, prop);
> >> > -   if (str)
> >> > -   return smbios_add_string(ctx, str);
> >> > +   return smbios_add_string(ctx, str);
> >> > }
> >> >
> >> > return 0;
> >> > @@ -231,7 +230,7 @@ static int smbios_write_type0(ulong *current, int 
> >> > handle,
> >> > t->vendor = smbios_add_string(ctx, "U-Boot");
> >> >
> >> > t->bios_ver = smbios_add_prop(ctx, "version");
> >> > -   if (!t->bios_ver)
> >> > +   if (!strcmp(ctx->last_str, "Unknown"))
> >>
> >> That is really ugly...checking the ctx value looking for a side effect.
> >>
> >> Can you not have smbios_add_prop() continue to return NULL in this case?
> >
> >
> > Hmm I don't know, but I wonder why I am not just checking t->bios_ver for 
> > Unknown.
> > I'll have a look and change it
>
> Ok, this can't be changed as easily.  smbios_add_prop() will not
> return NULL in any case. It returns an integer. With the cleanup, it
> will always writes 'Uknown' and not return 0 anymore.
> I can add that default value you suggested but the ctx->last_str is
> still used on the next line anyway.

Would you mind if I tried to create a version of the patch which does
the same thing but with less code, and perhaps a test? It might be
easier to discuss it then. I can't claim to understand all the
different code paths at this point.

My main concern is that with so many code paths it will be hard even
to refactor the code in the future, since it will become
'load-bearing' and anyone might turn up and say it breaks their board
because different information is provided.

Overall, so long as the information isn't used for anything important
in userspace, and we find a way to report SMBIOS to Linux without EFI,
it is OK to enable this feature (with a new Kconfig so it can be
disabled). But there is already authoritative info in the DT, so this
transformation into SMBIOS really should just be used for user
display, etc., not for anything which affects operation of the device.
Do you agree? If you do, how to ensure that? Perhaps a special string
in the table like 'GENERATED'?

Regards,
Simon


Re: [PATCH v3 1/4] efi_loader: split unrelated code from efi_bootmgr.c

2023-12-18 Thread Simon Glass
Hi AKASHI,

On Sun, 17 Dec 2023 at 19:39, AKASHI Takahiro
 wrote:
>
> Some code moved from cmd/bootefi.c is actually necessary only for "bootefi
> " command (starting an image manually loaded by a user using U-Boot
> load commands or other methods (like JTAG debugger).
>
> The code will never been opted out as unused code by a compiler which
> doesn't know how EFI boot manager is implemented. So introduce a new
> configuration, CONFIG_EFI_BINARY_EXEC, to enforce theem opted out
> explicitly.
>
> Signed-off-by: AKASHI Takahiro 
> ---
>  boot/Kconfig |   4 +-
>  cmd/Kconfig  |   6 +-
>  include/efi_loader.h |  28 +-
>  lib/efi_loader/Kconfig   |   9 +
>  lib/efi_loader/efi_bootmgr.c | 493 --
>  lib/efi_loader/efi_device_path.c |   3 +-
>  lib/efi_loader/efi_helper.c  | 499 ++-
>  7 files changed, 529 insertions(+), 513 deletions(-)

'helper' seems a bit vague to me. How about efi_boot.c ?

REgards,
Simon


  1   2   >