[PATCH v7 28/28] board: ti: am335x-ice: get CDCE913 clock device

2020-12-23 Thread Dario Binacchi
With support for other clock drivers, the potentially supported CDCE913
device can no longer be probed without specifying its DT node name.

Signed-off-by: Dario Binacchi 

---

(no changes since v1)

 board/ti/am335x/board.c | 2 +-
 board/ti/am43xx/board.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/board/ti/am335x/board.c b/board/ti/am335x/board.c
index 984cc5e3ba..e1f64859cf 100644
--- a/board/ti/am335x/board.c
+++ b/board/ti/am335x/board.c
@@ -879,7 +879,7 @@ int board_late_init(void)
}
 
/* Just probe the potentially supported cdce913 device */
-   uclass_get_device(UCLASS_CLK, 0, );
+   uclass_get_device_by_name(UCLASS_CLK, "cdce913@65", );
 
return 0;
 }
diff --git a/board/ti/am43xx/board.c b/board/ti/am43xx/board.c
index de49590031..62ed37cb48 100644
--- a/board/ti/am43xx/board.c
+++ b/board/ti/am43xx/board.c
@@ -744,7 +744,7 @@ int board_late_init(void)
 #endif
 
/* Just probe the potentially supported cdce913 device */
-   uclass_get_device(UCLASS_CLK, 0, );
+   uclass_get_device_by_name(UCLASS_CLK, "cdce913@65", );
 
return 0;
 }
-- 
2.17.1



[PATCH v7 26/28] video: omap: split the legacy code from the DM code

2020-12-23 Thread Dario Binacchi
The schedule for deprecating the features of the pre-driver-model puts
2019.17 as the deadline for the video subsystem. Furthermore, the latest
patches applied to the am335x-fb.c module have decreased the amount of
code shared with the pre-driver-model implementation. Splitting the two
implementations into two modules improves the readability of the code
and will make it easier to drop the pre-driver-model code.
I have not created a header file with the data structures and the
constants for accessing the LCD controller registers, but I preferred to
keep them inside the two c modules. This is a code replication until the
pre-driver-model version is dropped.

Signed-off-by: Dario Binacchi 

---

Changes in v7:
- Add linux/err.h header in am335x-fb.c to fix building errors for
  brxre1_defconfig.

Changes in v4:
- Include device_compat.h header for dev_xxx macros.

 drivers/video/Makefile   |   5 +-
 drivers/video/am335x-fb.c| 335 ---
 drivers/video/am335x-fb.h|  35 ---
 drivers/video/tilcdc-panel.c |   2 +-
 drivers/video/tilcdc-panel.h |   2 +-
 drivers/video/tilcdc.c   | 425 +++
 drivers/video/tilcdc.h   |  38 
 7 files changed, 468 insertions(+), 374 deletions(-)
 create mode 100644 drivers/video/tilcdc.c
 create mode 100644 drivers/video/tilcdc.h

diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 132a63ecea..29f3434f7c 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -16,7 +16,9 @@ obj-$(CONFIG_DM_VIDEO) += video-uclass.o vidconsole-uclass.o
 obj-$(CONFIG_DM_VIDEO) += video_bmp.o
 obj-$(CONFIG_PANEL) += panel-uclass.o
 obj-$(CONFIG_SIMPLE_PANEL) += simple_panel.o
-obj-$(CONFIG_AM335X_LCD) += tilcdc-panel.o
+obj-$(CONFIG_AM335X_LCD) += tilcdc.o tilcdc-panel.o
+else
+obj-$(CONFIG_AM335X_LCD) += am335x-fb.o
 endif
 
 obj-${CONFIG_EXYNOS_FB} += exynos/
@@ -24,7 +26,6 @@ obj-${CONFIG_VIDEO_ROCKCHIP} += rockchip/
 obj-${CONFIG_VIDEO_STM32} += stm32/
 obj-${CONFIG_VIDEO_TEGRA124} += tegra124/
 
-obj-$(CONFIG_AM335X_LCD) += am335x-fb.o
 obj-$(CONFIG_ATI_RADEON_FB) += ati_radeon_fb.o videomodes.o
 obj-$(CONFIG_ATMEL_HLCD) += atmel_hlcdfb.o
 obj-$(CONFIG_ATMEL_LCD) += atmel_lcdfb.o
diff --git a/drivers/video/am335x-fb.c b/drivers/video/am335x-fb.c
index a0a635cc29..5fa6f794ec 100644
--- a/drivers/video/am335x-fb.c
+++ b/drivers/video/am335x-fb.c
@@ -12,22 +12,16 @@
  * - starts output DMA from gd->fb_base buffer
  */
 #include 
-#include 
-#include 
 #include 
 #include 
-#include 
-#include 
 #include 
 #include 
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include "am335x-fb.h"
-#include "tilcdc-panel.h"
 
 #define LCDC_FMAX  2
 
@@ -115,8 +109,6 @@ struct am335x_lcdhw {
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#if !CONFIG_IS_ENABLED(DM_VIDEO)
-
 #if !defined(LCD_CNTL_BASE)
 #error "hw-base address of LCD-Controller (LCD_CNTL_BASE) not defined!"
 #endif
@@ -323,330 +315,3 @@ int am335xfb_init(struct am335x_lcdpanel *panel)
 
return 0;
 }
-
-#else /* CONFIG_DM_VIDEO */
-
-#define FBSIZE(t, p)   (((t).hactive.typ * (t).vactive.typ * (p).bpp) >> 3)
-
-enum {
-   LCD_MAX_WIDTH   = 2048,
-   LCD_MAX_HEIGHT  = 2048,
-   LCD_MAX_LOG2_BPP= VIDEO_BPP32,
-};
-
-struct am335x_fb_priv {
-   struct am335x_lcdhw *regs;
-   struct clk gclk;
-   struct clk dpll_m2_clk;
-};
-
-static ulong tilcdc_set_pixel_clk_rate(struct udevice *dev, ulong rate)
-{
-   struct am335x_fb_priv *priv = dev_get_priv(dev);
-   struct am335x_lcdhw *regs = priv->regs;
-   ulong mult_rate, mult_round_rate, best_err, err;
-   u32 v;
-   int div, i;
-
-   best_err = rate;
-   div = 0;
-   for (i = 2; i <= 255; i++) {
-   mult_rate = rate * i;
-   mult_round_rate = clk_round_rate(>gclk, mult_rate);
-   if (IS_ERR_VALUE(mult_round_rate))
-   return mult_round_rate;
-
-   err = mult_rate - mult_round_rate;
-   if (err < best_err) {
-   best_err = err;
-   div = i;
-   if (err == 0)
-   break;
-   }
-   }
-
-   if (div == 0) {
-   dev_err(dev, "failed to find a divisor\n");
-   return -EFAULT;
-   }
-
-   mult_rate = clk_set_rate(>gclk, rate * div);
-   v = readl(>ctrl) & ~LCDC_CTRL_CLK_DIVISOR_MASK;
-   v |= LCDC_CTRL_CLK_DIVISOR(div);
-   writel(v, >ctrl);
-   rate = mult_rate / div;
-   dev_dbg(dev, "rate=%ld, div=%d, err=%ld\n", rate, div, err);
-   return rate;
-}
-
-static int am335x_fb_remove(struct udevice *dev)
-{
-   struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
-   struct am335x_fb_priv *priv = dev_get_priv(dev);
-
-   uc_plat->base -= 0x20;
-   uc_plat->size += 0x20;
-   clk_release_all(>gclk, 1);
-   

[PATCH v7 23/28] video: omap: add panel driver

2020-12-23 Thread Dario Binacchi
The previous version of am335x-fb.c contained the functionalities of two
drivers that this patch has split. It was a video type driver that used
the same registration compatible string that now registers a panel type
driver. The proof of this is that two compatible strings were referred
to within the same driver.
There are now two drivers, each with its own compatible string,
functions and API.
Furthermore, the panel driver, in addition to decoding the display
timings, is now also able to manage the backlight.

Signed-off-by: Dario Binacchi 
Reviewed-by: Simon Glass 

---

(no changes since v4)

Changes in v4:
- Include device_compat.h header for dev_xxx macros.
- Add Simon Glass review.

Changes in v3:
- Update the DTS lcdc node of the am335x boards because of the
  am33xx.dtsi resynced with Linux 5.9-rc7.

 arch/arm/dts/am335x-brppt1-mmc.dts   |  17 +-
 arch/arm/dts/am335x-brppt1-nand.dts  |  17 +-
 arch/arm/dts/am335x-brppt1-spi.dts   |  17 +-
 arch/arm/dts/am335x-brsmarc1.dts |  20 +-
 arch/arm/dts/am335x-brxre1.dts   |  21 +-
 arch/arm/dts/am335x-evm-u-boot.dtsi  |  15 +-
 arch/arm/dts/am335x-evmsk-u-boot.dtsi|  14 +-
 arch/arm/dts/am335x-guardian-u-boot.dtsi |  18 +-
 arch/arm/dts/am335x-pdu001-u-boot.dtsi   |  18 +-
 arch/arm/dts/am335x-pxm50-u-boot.dtsi|  14 +-
 arch/arm/dts/am335x-rut-u-boot.dtsi  |  14 +-
 arch/arm/dts/da850-evm-u-boot.dtsi   |  18 +-
 drivers/video/Makefile   |   1 +
 drivers/video/am335x-fb.c| 255 ++-
 drivers/video/am335x-fb.h|  31 +++
 drivers/video/tilcdc-panel.c | 172 +++
 drivers/video/tilcdc-panel.h |  14 ++
 17 files changed, 478 insertions(+), 198 deletions(-)
 create mode 100644 drivers/video/tilcdc-panel.c
 create mode 100644 drivers/video/tilcdc-panel.h

diff --git a/arch/arm/dts/am335x-brppt1-mmc.dts 
b/arch/arm/dts/am335x-brppt1-mmc.dts
index 6f919711f0..bd2f6c2e3e 100644
--- a/arch/arm/dts/am335x-brppt1-mmc.dts
+++ b/arch/arm/dts/am335x-brppt1-mmc.dts
@@ -53,8 +53,6 @@
bkl-pwm = <>;
bkl-tps = <_bl>;
 
-   u-boot,dm-pre-reloc;
-
panel-info {
ac-bias = <255>;
ac-bias-intrpt  = <0>;
@@ -238,8 +236,19 @@
status = "okay";
 };
 
- {
-   status = "disabled";
+_per {
+
+   segment@30 {
+
+   target-module@e000 {
+   u-boot,dm-pre-reloc;
+
+   lcdc: lcdc@0 {
+   u-boot,dm-pre-reloc;
+   status = "disabled";
+   };
+   };
+   };
 };
 
  {
diff --git a/arch/arm/dts/am335x-brppt1-nand.dts 
b/arch/arm/dts/am335x-brppt1-nand.dts
index 9d4340f591..67c609739f 100644
--- a/arch/arm/dts/am335x-brppt1-nand.dts
+++ b/arch/arm/dts/am335x-brppt1-nand.dts
@@ -53,8 +53,6 @@
bkl-pwm = <>;
bkl-tps = <_bl>;
 
-   u-boot,dm-pre-reloc;
-
panel-info {
ac-bias = <255>;
ac-bias-intrpt  = <0>;
@@ -228,8 +226,19 @@
status = "disabled";
 };
 
- {
-   status = "disabled";
+_per {
+
+   segment@30 {
+
+   target-module@e000 {
+   u-boot,dm-pre-reloc;
+
+   lcdc: lcdc@0 {
+   u-boot,dm-pre-reloc;
+   status = "disabled";
+   };
+   };
+   };
 };
 
  {
diff --git a/arch/arm/dts/am335x-brppt1-spi.dts 
b/arch/arm/dts/am335x-brppt1-spi.dts
index c078af8fba..ce3dce204d 100644
--- a/arch/arm/dts/am335x-brppt1-spi.dts
+++ b/arch/arm/dts/am335x-brppt1-spi.dts
@@ -54,8 +54,6 @@
bkl-pwm = <>;
bkl-tps = <_bl>;
 
-   u-boot,dm-pre-reloc;
-
panel-info {
ac-bias = <255>;
ac-bias-intrpt  = <0>;
@@ -259,8 +257,19 @@
status = "okay";
 };
 
- {
-   status = "disabled";
+_per {
+
+   segment@30 {
+
+   target-module@e000 {
+   u-boot,dm-pre-reloc;
+
+   lcdc: lcdc@0 {
+   u-boot,dm-pre-reloc;
+   status = "disabled";
+   };
+   };
+   };
 };
 
  {
diff --git a/arch/arm/dts/am335x-brsmarc1.dts b/arch/arm/dts/am335x-brsmarc1.dts
index 7e9516e8f8..25cdb11164 100644
--- a/arch/arm/dts/am335x-brsmarc1.dts
+++ b/arch/arm/dts/am335x-brsmarc1.dts
@@ -59,7 +59,6 @@
/*backlight = <_bl>; */
compatible = "ti,tilcdc,panel";
status = "okay";
-   u-boot,dm-pre-reloc;
 
panel-info {
ac-bias = <255>;
@@ -298,10 +297,21 @@
status = "okay";
 };
 
- {

[PATCH v7 27/28] video: omap: move drivers to 'ti' directory

2020-12-23 Thread Dario Binacchi
Add drivers/video/ti/ folder and move all TI's code in this folder for
better maintenance.

Signed-off-by: Dario Binacchi 

---

Changes in v7:
- Fix building errors for:
   brppt1_mmc_defconfig
   brppt1_nand_defconfig
   brppt1_spi_defconfig
   brxre1_defconfig
   brsmarc1_defconfig

 board/BuR/common/bur_common.h |  2 +-
 board/BuR/common/common.c |  2 +-
 drivers/video/Kconfig |  5 +
 drivers/video/Makefile|  4 +---
 drivers/video/ti/Kconfig  |  8 
 drivers/video/ti/Makefile | 10 ++
 drivers/video/{ => ti}/am335x-fb.c|  0
 drivers/video/{ => ti}/am335x-fb.h|  0
 drivers/video/{ => ti}/tilcdc-panel.c |  0
 drivers/video/{ => ti}/tilcdc-panel.h |  0
 drivers/video/{ => ti}/tilcdc.c   |  0
 drivers/video/{ => ti}/tilcdc.h   |  0
 12 files changed, 22 insertions(+), 9 deletions(-)
 create mode 100644 drivers/video/ti/Kconfig
 create mode 100644 drivers/video/ti/Makefile
 rename drivers/video/{ => ti}/am335x-fb.c (100%)
 rename drivers/video/{ => ti}/am335x-fb.h (100%)
 rename drivers/video/{ => ti}/tilcdc-panel.c (100%)
 rename drivers/video/{ => ti}/tilcdc-panel.h (100%)
 rename drivers/video/{ => ti}/tilcdc.c (100%)
 rename drivers/video/{ => ti}/tilcdc.h (100%)

diff --git a/board/BuR/common/bur_common.h b/board/BuR/common/bur_common.h
index c64ebe93b0..79c9af1466 100644
--- a/board/BuR/common/bur_common.h
+++ b/board/BuR/common/bur_common.h
@@ -12,7 +12,7 @@
 #define _BUR_COMMON_H_
 
 #if !CONFIG_IS_ENABLED(DM_VIDEO)
-#include <../../../drivers/video/am335x-fb.h>
+#include <../../../drivers/video/ti/am335x-fb.h>
 
 int load_lcdtiming(struct am335x_lcdpanel *panel);
 #endif
diff --git a/board/BuR/common/common.c b/board/BuR/common/common.c
index 0a5104a48f..f676d7baa6 100644
--- a/board/BuR/common/common.c
+++ b/board/BuR/common/common.c
@@ -27,7 +27,7 @@ DECLARE_GLOBAL_DATA_PTR;
 #include 
 #include 
 #include 
-#include "../../../drivers/video/am335x-fb.h"
+#include "../../../drivers/video/ti/am335x-fb.h"
 
 void lcdbacklight(int on)
 {
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 998271b9b6..758aab37e0 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -546,10 +546,7 @@ config ATMEL_HLCD
help
   HLCDC supports video output to an attached LCD panel.
 
-config AM335X_LCD
-   bool "Enable AM335x video support"
-   help
-  Supports video output to an attached LCD panel.
+source "drivers/video/ti/Kconfig"
 
 config LOGICORE_DP_TX
bool "Enable Logicore DP TX driver"
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 29f3434f7c..51b545ed83 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -16,15 +16,13 @@ obj-$(CONFIG_DM_VIDEO) += video-uclass.o vidconsole-uclass.o
 obj-$(CONFIG_DM_VIDEO) += video_bmp.o
 obj-$(CONFIG_PANEL) += panel-uclass.o
 obj-$(CONFIG_SIMPLE_PANEL) += simple_panel.o
-obj-$(CONFIG_AM335X_LCD) += tilcdc.o tilcdc-panel.o
-else
-obj-$(CONFIG_AM335X_LCD) += am335x-fb.o
 endif
 
 obj-${CONFIG_EXYNOS_FB} += exynos/
 obj-${CONFIG_VIDEO_ROCKCHIP} += rockchip/
 obj-${CONFIG_VIDEO_STM32} += stm32/
 obj-${CONFIG_VIDEO_TEGRA124} += tegra124/
+obj-y += ti/
 
 obj-$(CONFIG_ATI_RADEON_FB) += ati_radeon_fb.o videomodes.o
 obj-$(CONFIG_ATMEL_HLCD) += atmel_hlcdfb.o
diff --git a/drivers/video/ti/Kconfig b/drivers/video/ti/Kconfig
new file mode 100644
index 00..3081e9e8c0
--- /dev/null
+++ b/drivers/video/ti/Kconfig
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2020 Dario Binacchi 
+#
+config AM335X_LCD
+   bool "Enable AM335x video support"
+   help
+  Supports video output to an attached LCD panel.
diff --git a/drivers/video/ti/Makefile b/drivers/video/ti/Makefile
new file mode 100644
index 00..d59216
--- /dev/null
+++ b/drivers/video/ti/Makefile
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2020 Dario Binacchi 
+#
+
+ifdef CONFIG_DM_VIDEO
+obj-$(CONFIG_AM335X_LCD) += tilcdc.o tilcdc-panel.o
+else
+obj-$(CONFIG_AM335X_LCD) += am335x-fb.o
+endif
diff --git a/drivers/video/am335x-fb.c b/drivers/video/ti/am335x-fb.c
similarity index 100%
rename from drivers/video/am335x-fb.c
rename to drivers/video/ti/am335x-fb.c
diff --git a/drivers/video/am335x-fb.h b/drivers/video/ti/am335x-fb.h
similarity index 100%
rename from drivers/video/am335x-fb.h
rename to drivers/video/ti/am335x-fb.h
diff --git a/drivers/video/tilcdc-panel.c b/drivers/video/ti/tilcdc-panel.c
similarity index 100%
rename from drivers/video/tilcdc-panel.c
rename to drivers/video/ti/tilcdc-panel.c
diff --git a/drivers/video/tilcdc-panel.h b/drivers/video/ti/tilcdc-panel.h
similarity index 100%
rename from drivers/video/tilcdc-panel.h
rename to drivers/video/ti/tilcdc-panel.h
diff --git a/drivers/video/tilcdc.c b/drivers/video/ti/tilcdc.c
similarity index 100%
rename from drivers/video/tilcdc.c
rename to drivers/video/ti/tilcdc.c
diff --git 

[PATCH v7 25/28] video: omap: set LCD clock rate through DM API

2020-12-23 Thread Dario Binacchi
The patch configures the display DPLL using the functions provided by
the driver model API for the clock. The device tree contains everything
needed to get the DPLL clock. The round rate function developed for
calculating the DPLL multiplier and divisor and the platform routines
for accessing the DPLL registers are removed from the LCD driver code
because they are implemented inside the DPLL clock driver.

Signed-off-by: Dario Binacchi 

---

(no changes since v3)

Changes in v3:
- Add clk.h header.
- Fix an error code returned by the probe function.

 drivers/video/am335x-fb.c | 129 ++
 1 file changed, 103 insertions(+), 26 deletions(-)

diff --git a/drivers/video/am335x-fb.c b/drivers/video/am335x-fb.c
index dc959baa27..a0a635cc29 100644
--- a/drivers/video/am335x-fb.c
+++ b/drivers/video/am335x-fb.c
@@ -12,6 +12,7 @@
  * - starts output DMA from gd->fb_base buffer
  */
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -112,6 +113,27 @@ struct am335x_lcdhw {
unsigned intclkc_reset; /* 0x70 */
 };
 
+DECLARE_GLOBAL_DATA_PTR;
+
+#if !CONFIG_IS_ENABLED(DM_VIDEO)
+
+#if !defined(LCD_CNTL_BASE)
+#error "hw-base address of LCD-Controller (LCD_CNTL_BASE) not defined!"
+#endif
+
+/* Macro definitions */
+#define FBSIZE(x)  (((x)->hactive * (x)->vactive * (x)->bpp) >> 3)
+
+#define LCDC_RASTER_TIMING_2_INVMASK(x)((x) & GENMASK(25, 20))
+
+static struct am335x_lcdhw *lcdhw = (void *)LCD_CNTL_BASE;
+
+int lcd_get_size(int *line_length)
+{
+   *line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8;
+   return *line_length * panel_info.vl_row + 0x20;
+}
+
 struct dpll_data {
unsigned long rounded_rate;
u16 rounded_m;
@@ -119,8 +141,6 @@ struct dpll_data {
u8 rounded_div;
 };
 
-DECLARE_GLOBAL_DATA_PTR;
-
 /**
  * am335x_dpll_round_rate() - Round a target rate for an OMAP DPLL
  *
@@ -199,25 +219,6 @@ static ulong am335x_fb_set_pixel_clk_rate(struct 
am335x_lcdhw *regs, ulong rate)
return round_rate;
 }
 
-#if !CONFIG_IS_ENABLED(DM_VIDEO)
-
-#if !defined(LCD_CNTL_BASE)
-#error "hw-base address of LCD-Controller (LCD_CNTL_BASE) not defined!"
-#endif
-
-/* Macro definitions */
-#define FBSIZE(x)  (((x)->hactive * (x)->vactive * (x)->bpp) >> 3)
-
-#define LCDC_RASTER_TIMING_2_INVMASK(x)((x) & GENMASK(25, 20))
-
-static struct am335x_lcdhw *lcdhw = (void *)LCD_CNTL_BASE;
-
-int lcd_get_size(int *line_length)
-{
-   *line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8;
-   return *line_length * panel_info.vl_row + 0x20;
-}
-
 int am335xfb_init(struct am335x_lcdpanel *panel)
 {
u32 raster_ctrl = 0;
@@ -335,14 +336,58 @@ enum {
 
 struct am335x_fb_priv {
struct am335x_lcdhw *regs;
+   struct clk gclk;
+   struct clk dpll_m2_clk;
 };
 
+static ulong tilcdc_set_pixel_clk_rate(struct udevice *dev, ulong rate)
+{
+   struct am335x_fb_priv *priv = dev_get_priv(dev);
+   struct am335x_lcdhw *regs = priv->regs;
+   ulong mult_rate, mult_round_rate, best_err, err;
+   u32 v;
+   int div, i;
+
+   best_err = rate;
+   div = 0;
+   for (i = 2; i <= 255; i++) {
+   mult_rate = rate * i;
+   mult_round_rate = clk_round_rate(>gclk, mult_rate);
+   if (IS_ERR_VALUE(mult_round_rate))
+   return mult_round_rate;
+
+   err = mult_rate - mult_round_rate;
+   if (err < best_err) {
+   best_err = err;
+   div = i;
+   if (err == 0)
+   break;
+   }
+   }
+
+   if (div == 0) {
+   dev_err(dev, "failed to find a divisor\n");
+   return -EFAULT;
+   }
+
+   mult_rate = clk_set_rate(>gclk, rate * div);
+   v = readl(>ctrl) & ~LCDC_CTRL_CLK_DIVISOR_MASK;
+   v |= LCDC_CTRL_CLK_DIVISOR(div);
+   writel(v, >ctrl);
+   rate = mult_rate / div;
+   dev_dbg(dev, "rate=%ld, div=%d, err=%ld\n", rate, div, err);
+   return rate;
+}
+
 static int am335x_fb_remove(struct udevice *dev)
 {
struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
+   struct am335x_fb_priv *priv = dev_get_priv(dev);
 
uc_plat->base -= 0x20;
uc_plat->size += 0x20;
+   clk_release_all(>gclk, 1);
+   clk_release_all(>dpll_m2_clk, 1);
return 0;
 }
 
@@ -352,10 +397,10 @@ static int am335x_fb_probe(struct udevice *dev)
struct video_priv *uc_priv = dev_get_uclass_priv(dev);
struct am335x_fb_priv *priv = dev_get_priv(dev);
struct am335x_lcdhw *regs = priv->regs;
-   struct udevice *panel;
+   struct udevice *panel, *clk_dev;
struct tilcdc_panel_info info;
struct display_timing timing;
-   struct cm_dpll *const cmdpll = (struct cm_dpll *)CM_DPLL;
+   ulong rate;
u32 reg;
int err;
 
@@ 

[PATCH v7 22/28] dm: core: add a function to decode display timings

2020-12-23 Thread Dario Binacchi
The patch adds a function to get display timings from the device tree
node attached to the device.

Signed-off-by: Dario Binacchi 
Reviewed-by: Simon Glass 
---

(no changes since v1)

 arch/sandbox/dts/test.dts | 46 ++
 drivers/core/read.c   |  6 +++
 include/dm/read.h | 24 
 test/dm/test-fdt.c| 80 +++
 4 files changed, 156 insertions(+)

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 637d79caf7..6e095de180 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -141,6 +141,52 @@
   <>;
mux-control-names = "mux0", "mux1", "mux2", "mux3", "mux4";
mux-syscon = <>;
+   display-timings {
+   timing0: 240x320 {
+   clock-frequency = <650>;
+   hactive = <240>;
+   vactive = <320>;
+   hfront-porch = <6>;
+   hback-porch = <7>;
+   hsync-len = <1>;
+   vback-porch = <5>;
+   vfront-porch = <8>;
+   vsync-len = <2>;
+   hsync-active = <1>;
+   vsync-active = <0>;
+   de-active = <1>;
+   pixelclk-active = <1>;
+   interlaced;
+   doublescan;
+   doubleclk;
+   };
+   timing1: 480x800 {
+   clock-frequency = <900>;
+   hactive = <480>;
+   vactive = <800>;
+   hfront-porch = <10>;
+   hback-porch = <59>;
+   hsync-len = <12>;
+   vback-porch = <15>;
+   vfront-porch = <17>;
+   vsync-len = <16>;
+   hsync-active = <0>;
+   vsync-active = <1>;
+   de-active = <0>;
+   pixelclk-active = <0>;
+   };
+   timing2: 800x480 {
+   clock-frequency = <3350>;
+   hactive = <800>;
+   vactive = <480>;
+   hback-porch = <89>;
+   hfront-porch = <164>;
+   vback-porch = <23>;
+   vfront-porch = <10>;
+   hsync-len = <11>;
+   vsync-len = <13>;
+   };
+   };
};
 
junk {
diff --git a/drivers/core/read.c b/drivers/core/read.c
index 076125824c..7925c09f60 100644
--- a/drivers/core/read.c
+++ b/drivers/core/read.c
@@ -377,3 +377,9 @@ int dev_read_pci_bus_range(const struct udevice *dev,
 
return 0;
 }
+
+int dev_decode_display_timing(const struct udevice *dev, int index,
+ struct display_timing *config)
+{
+   return ofnode_decode_display_timing(dev_ofnode(dev), index, config);
+}
diff --git a/include/dm/read.h b/include/dm/read.h
index 0585eb1228..0ac26d9f1d 100644
--- a/include/dm/read.h
+++ b/include/dm/read.h
@@ -694,6 +694,23 @@ int dev_get_child_count(const struct udevice *dev);
  */
 int dev_read_pci_bus_range(const struct udevice *dev, struct resource *res);
 
+/**
+ * dev_decode_display_timing() - decode display timings
+ *
+ * Decode display timings from the supplied 'display-timings' node.
+ * See doc/device-tree-bindings/video/display-timing.txt for binding
+ * information.
+ *
+ * @dev: device to read DT display timings from. The node linked to the device
+ *   contains a child node called 'display-timings' which in turn contains
+ *   one or more display timing nodes.
+ * @index: index number to read (0=first timing subnode)
+ * @config: place to put timings
+ * @return 0 if OK, -FDT_ERR_NOTFOUND if not found
+ */
+int dev_decode_display_timing(const struct udevice *dev, int index,
+ struct display_timing *config);
+
 #else /* CONFIG_DM_DEV_READ_INLINE is enabled */
 
 static inline int dev_read_u32(const struct udevice *dev,
@@ -1016,6 +1033,13 @@ static inline int dev_get_child_count(const struct 
udevice *dev)
return ofnode_get_child_count(dev_ofnode(dev));
 }
 
+static inline int dev_decode_display_timing(const struct udevice *dev,
+   int index,
+   struct display_timing *config)
+{
+   return ofnode_decode_display_timing(dev_ofnode(dev), index, 

[PATCH v7 24/28] video: omap: drop domain clock enabling by SOC api

2020-12-23 Thread Dario Binacchi
Enabling the domain clock is performed by the sysc interconnect target
module driver during the video device probing.

Signed-off-by: Dario Binacchi 

---

(no changes since v3)

Changes in v3:
- Remove clock domain enabling/disabling.
- Update the commit message.

 arch/arm/mach-omap2/am33xx/clock_am33xx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/am33xx/clock_am33xx.c 
b/arch/arm/mach-omap2/am33xx/clock_am33xx.c
index 2427933c8b..cf71192360 100644
--- a/arch/arm/mach-omap2/am33xx/clock_am33xx.c
+++ b/arch/arm/mach-omap2/am33xx/clock_am33xx.c
@@ -226,7 +226,7 @@ void enable_basic_clocks(void)
>usb0clkctrl,
>emiffwclkctrl,
>emifclkctrl,
-#if CONFIG_IS_ENABLED(AM335X_LCD)
+#if CONFIG_IS_ENABLED(AM335X_LCD) && !CONFIG_IS_ENABLED(DM_VIDEO)
>lcdclkctrl,
>lcdcclkstctrl,
 #endif
-- 
2.17.1



[PATCH v7 21/28] bus: ti: am33xx: add pwm subsystem driver

2020-12-23 Thread Dario Binacchi
The TI PWMSS driver is a simple bus driver for providing clock and power
management for the PWM peripherals on TI AM33xx SoCs, namely eCAP,
eHRPWM and eQEP.

For DT binding details see Linux doc:
- Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt

Signed-off-by: Dario Binacchi 

---

(no changes since v3)

Changes in v3:
- Move Kconfig symbol from drivers/pwm to drivers/bus.
- Remove the domain clock reference from the pwmss nodes of the device
  tree in am33xx.dtsi. The resync of am33xx.dtsi with Linux 5.9-rc7
  already contains such references.
- Remove domain clock enabling/disabling. Enabling the domain clock is
  performed by the sysc interconnect target module driver during the pwm
  device probing.
- Remove doc/device-tree-bindings/pwm/ti,pwmss.txt.
- Add to commit message the references to linux kernel dt binding
  documentation.

 drivers/bus/Kconfig|  6 ++
 drivers/bus/Makefile   |  1 +
 drivers/bus/ti-pwmss.c | 21 +
 3 files changed, 28 insertions(+)
 create mode 100644 drivers/bus/ti-pwmss.c

diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index 733bec5a56..d742ed333b 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -5,6 +5,12 @@
 
 menu "Bus devices"
 
+config TI_PWMSS
+   bool
+   default y if ARCH_OMAP2PLUS && PWM_TI_EHRPWM
+   help
+ PWM Subsystem driver support for AM33xx SOC.
+
 config TI_SYSC
bool "TI sysc interconnect target module driver"
depends on ARCH_OMAP2PLUS
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 875bb4ed42..a2e71c7b3b 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -3,5 +3,6 @@
 # Makefile for the bus drivers.
 #
 
+obj-$(CONFIG_TI_PWMSS) += ti-pwmss.o
 obj-$(CONFIG_TI_SYSC)  += ti-sysc.o
 obj-$(CONFIG_UNIPHIER_SYSTEM_BUS) += uniphier-system-bus.o
diff --git a/drivers/bus/ti-pwmss.c b/drivers/bus/ti-pwmss.c
new file mode 100644
index 00..265b4cf83b
--- /dev/null
+++ b/drivers/bus/ti-pwmss.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Pulse-Width Modulation Subsystem (pwmss)
+ *
+ * Copyright (C) 2020 Dario Binacchi 
+ */
+
+#include 
+#include 
+
+static const struct udevice_id ti_pwmss_ids[] = {
+   {.compatible = "ti,am33xx-pwmss"},
+   {}
+};
+
+U_BOOT_DRIVER(ti_pwmss) = {
+   .name = "ti_pwmss",
+   .id = UCLASS_SIMPLE_BUS,
+   .of_match = ti_pwmss_ids,
+   .bind = dm_scan_fdt_dev,
+};
-- 
2.17.1



[PATCH v7 16/28] clk: move clk-ti-sci driver to 'ti' directory

2020-12-23 Thread Dario Binacchi
The patch moves the clk-ti-sci.c file to the 'ti' directory along with
all the other TI's drivers, and renames it clk-sci.c.

Signed-off-by: Dario Binacchi 
---

(no changes since v1)

 drivers/clk/Kconfig| 8 
 drivers/clk/Makefile   | 1 -
 drivers/clk/ti/Kconfig | 8 
 drivers/clk/ti/Makefile| 1 +
 drivers/clk/{clk-ti-sci.c => ti/clk-sci.c} | 0
 5 files changed, 9 insertions(+), 9 deletions(-)
 rename drivers/clk/{clk-ti-sci.c => ti/clk-sci.c} (100%)

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 9e54929039..db06f276ec 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -98,14 +98,6 @@ config CLK_STM32F
  This clock driver adds support for RCC clock management
  for STM32F4 and STM32F7 SoCs.
 
-config CLK_TI_SCI
-   bool "TI System Control Interface (TI SCI) clock driver"
-   depends on CLK && TI_SCI_PROTOCOL && OF_CONTROL
-   help
- This enables the clock driver support over TI System Control Interface
- available on some new TI's SoCs. If you wish to use clock resources
- managed by the TI System Controller, say Y here. Otherwise, say N.
-
 config CLK_HSDK
bool "Enable cgu clock driver for HSDK boards"
depends on CLK && TARGET_HSDK
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 2581fe0a19..f8383e523d 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -48,6 +48,5 @@ obj-$(CONFIG_SANDBOX) += clk_sandbox.o
 obj-$(CONFIG_SANDBOX) += clk_sandbox_test.o
 obj-$(CONFIG_SANDBOX_CLK_CCF) += clk_sandbox_ccf.o
 obj-$(CONFIG_STM32H7) += clk_stm32h7.o
-obj-$(CONFIG_CLK_TI_SCI) += clk-ti-sci.o
 obj-$(CONFIG_CLK_VERSAL) += clk_versal.o
 obj-$(CONFIG_CLK_CDCE9XX) += clk-cdce9xx.o
diff --git a/drivers/clk/ti/Kconfig b/drivers/clk/ti/Kconfig
index 9e257a2eb7..2dc86d44a9 100644
--- a/drivers/clk/ti/Kconfig
+++ b/drivers/clk/ti/Kconfig
@@ -33,3 +33,11 @@ config CLK_TI_MUX
depends on CLK && OF_CONTROL && CLK_CCF
help
  This enables the mux clock driver support on TI's SoCs.
+
+config CLK_TI_SCI
+   bool "TI System Control Interface (TI SCI) clock driver"
+   depends on CLK && TI_SCI_PROTOCOL && OF_CONTROL
+   help
+ This enables the clock driver support over TI System Control Interface
+ available on some new TI's SoCs. If you wish to use clock resources
+ managed by the TI System Controller, say Y here. Otherwise, say N.
diff --git a/drivers/clk/ti/Makefile b/drivers/clk/ti/Makefile
index dbd343069c..9f56b47736 100644
--- a/drivers/clk/ti/Makefile
+++ b/drivers/clk/ti/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_CLK_TI_CTRL) += clk-ctrl.o
 obj-$(CONFIG_CLK_TI_DIVIDER) += clk-divider.o
 obj-$(CONFIG_CLK_TI_GATE) += clk-gate.o
 obj-$(CONFIG_CLK_TI_MUX) += clk-mux.o
+obj-$(CONFIG_CLK_TI_SCI) += clk-sci.o
diff --git a/drivers/clk/clk-ti-sci.c b/drivers/clk/ti/clk-sci.c
similarity index 100%
rename from drivers/clk/clk-ti-sci.c
rename to drivers/clk/ti/clk-sci.c
-- 
2.17.1



[PATCH v7 17/28] fdt: translate address if #size-cells = <0>

2020-12-23 Thread Dario Binacchi
The __of_translate_address routine translates an address from the
device tree into a CPU physical address. A note in the description of
the routine explains that the crossing of any level with
#size-cells = <0> is to be considered an error not by specification but
since inherited from IBM. This does not happen for Texas Instruments, or
at least for the beaglebone device tree. Without this patch, in fact,
the translation into physical addresses of the registers contained in the
am33xx-clocks.dtsi nodes would not be possible. They all have a parent
with #size-cells = <0>.

The CONFIG_OF_TRANSLATE_ZERO_SIZE_CELLS symbol makes translation
possible even in the case of crossing levels with #size-cells = <0>.

The patch acts conservatively on address translation, except for
removing a check within the of_translate_one function in the
drivers/core/of_addr.c file:

+
ranges = of_get_property(parent, rprop, );
-   if (ranges == NULL && !of_empty_ranges_quirk(parent)) {
-   debug("no ranges; cannot translate\n");
-   return 1;
-   }
if (ranges == NULL || rlen == 0) {
offset = of_read_number(addr, na);
memset(addr, 0, pna * 4);
debug("empty ranges; 1:1 translation\n");

There are two reasons:
1 The function of_empty_ranges_quirk always returns false, invalidating
  the following if statement in case of null ranges. Therefore one of
  the two checks is useless.

2 The implementation of the of_translate_one function found in the
  common/fdt_support.c file has removed this check while keeping the one
  about the 1:1 translation.

The patch adds a test and modifies a check for the correctness of an
address in the case of enabling translation also for zero size cells.
The added test checks translations of addresses generated by nodes of
a device tree similar to those you can find in the files am33xx.dtsi
and am33xx-clocks.dtsi for which the patch was created.

The patch was also tested on a beaglebone black board. The addresses
generated for the registers of the loaded drivers are those specified
by the AM335x reference manual.

Signed-off-by: Dario Binacchi 
Tested-by: Dario Binacchi 
Reviewed-by: Simon Glass 

---

Changes in v7:
- Add gd_size_cells_0 macro to fix building errors for boards that do
  not use CONFIG_DM.

Changes in v4:
- Add Sphinx documentation for dm_flags.
- Convert GD_DM_FLG_* to enum.
- Include device_compat.h header in test/dm/test-fdt.c for dev_xxx macros.

Changes in v3:
- Comment dm_flags field in the global_data structure.

Changes in v2:
- Fix a missing line in the commit message.
- Add dm_flags to global_data structure and GD_DM_FLG_SIZE_CELLS_0 macro
  to test without recompiling.
- Update the OF_CHECK_COUNTS macro in order to have just one
  #define by bringing the GD_DM_FLG_SIZE_CELLS_0 into the expression.
- Lower-case the 0xC019 hex number.

 arch/sandbox/dts/test.dts | 21 ++
 common/fdt_support.c  |  6 ++-
 drivers/core/Kconfig  | 12 ++
 drivers/core/fdtaddr.c|  2 +-
 drivers/core/of_addr.c| 13 ++
 drivers/core/ofnode.c |  7 +++-
 drivers/core/root.c   |  3 ++
 include/asm-generic/global_data.h | 24 +++
 test/dm/test-fdt.c| 69 ++-
 9 files changed, 141 insertions(+), 16 deletions(-)

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index f3b766271d..637d79caf7 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -41,6 +41,7 @@
fdt-dummy1 = "/translation-test@8000/dev@1,100";
fdt-dummy2 = "/translation-test@8000/dev@2,200";
fdt-dummy3 = "/translation-test@8000/noxlatebus@3,300/dev@42";
+   fdt-dummy4 = 
"/translation-test@8000/xlatebus@4,400/devs/dev@19";
usb0 = _0;
usb1 = _1;
usb2 = _2;
@@ -1061,6 +1062,7 @@
  1 0x100 0x9000 0x1000
  2 0x200 0xA000 0x1000
  3 0x300 0xB000 0x1000
+ 4 0x400 0xC000 0x1000
 >;
 
dma-ranges = <0 0x000 0x1000 0x1000
@@ -1097,6 +1099,25 @@
reg = <0x42>;
};
};
+
+   xlatebus@4,400 {
+   compatible = "sandbox,zero-size-cells-bus";
+   reg = <4 0x400 0x1000>;
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges = <0 4 0x400 0x1000>;
+
+   devs {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   dev@19 {
+   compatible = "denx,u-boot-fdt-dummy";
+   reg = <0x19>;
+  

[PATCH v7 20/28] pwm: ti: am33xx: add enhanced pwm driver

2020-12-23 Thread Dario Binacchi
Enhanced high resolution PWM module (EHRPWM) hardware can be used to
generate PWM output over 2 channels. This commit adds PWM driver support
for EHRPWM device present on AM33XX SOC.

The code is based on the drivers/pwm/pwm-tiehrpwm.c driver of the Linux
kernel version 5.9-rc7.
For DT binding details see:
- Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt

Signed-off-by: Dario Binacchi 

---

(no changes since v4)

Changes in v4:
- Include device_compat.h header for dev_xxx macros.

Changes in v3:
- Adds PWM_TI_EHRPWM dependency on ARCH_OMAP2PLUS in Kconfig.
- Add error message in case of invalid address.
- Remove doc/device-tree-bindings/pwm/ti,ehrpwm.txt.
- Add to commit message the references to linux kernel dt binding
  documentation.

 drivers/pwm/Kconfig |   7 +
 drivers/pwm/Makefile|   1 +
 drivers/pwm/pwm-ti-ehrpwm.c | 468 
 3 files changed, 476 insertions(+)
 create mode 100644 drivers/pwm/pwm-ti-ehrpwm.c

diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index b3bd5c6bb7..ccf81abbe9 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -75,3 +75,10 @@ config PWM_SUNXI
help
  This PWM is found on H3, A64 and other Allwinner SoCs. It supports a
  programmable period and duty cycle. A 16-bit counter is used.
+
+config PWM_TI_EHRPWM
+   bool "Enable support for EHRPWM PWM"
+   depends on DM_PWM && ARCH_OMAP2PLUS
+   default y
+   help
+ PWM driver support for the EHRPWM controller found on TI SOCs.
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index f21ae7d76e..0b9d2698a3 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -19,3 +19,4 @@ obj-$(CONFIG_PWM_SANDBOX) += sandbox_pwm.o
 obj-$(CONFIG_PWM_SIFIVE)   += pwm-sifive.o
 obj-$(CONFIG_PWM_TEGRA)+= tegra_pwm.o
 obj-$(CONFIG_PWM_SUNXI)+= sunxi_pwm.o
+obj-$(CONFIG_PWM_TI_EHRPWM)+= pwm-ti-ehrpwm.o
diff --git a/drivers/pwm/pwm-ti-ehrpwm.c b/drivers/pwm/pwm-ti-ehrpwm.c
new file mode 100644
index 00..df995c8865
--- /dev/null
+++ b/drivers/pwm/pwm-ti-ehrpwm.c
@@ -0,0 +1,468 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * EHRPWM PWM driver
+ *
+ * Copyright (C) 2020 Dario Binacchi 
+ *
+ * Based on Linux kernel drivers/pwm/pwm-tiehrpwm.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define NSEC_PER_SEC   10L
+
+/* Time base module registers */
+#define TI_EHRPWM_TBCTL0x00
+#define TI_EHRPWM_TBPRD0x0A
+
+#define TI_EHRPWM_TBCTL_PRDLD_MASK BIT(3)
+#define TI_EHRPWM_TBCTL_PRDLD_SHDW 0
+#define TI_EHRPWM_TBCTL_PRDLD_IMDT BIT(3)
+#define TI_EHRPWM_TBCTL_CLKDIV_MASKGENMASK(12, 7)
+#define TI_EHRPWM_TBCTL_CTRMODE_MASK   GENMASK(1, 0)
+#define TI_EHRPWM_TBCTL_CTRMODE_UP 0
+#define TI_EHRPWM_TBCTL_CTRMODE_DOWN   BIT(0)
+#define TI_EHRPWM_TBCTL_CTRMODE_UPDOWN BIT(1)
+#define TI_EHRPWM_TBCTL_CTRMODE_FREEZE GENMASK(1, 0)
+
+#define TI_EHRPWM_TBCTL_HSPCLKDIV_SHIFT7
+#define TI_EHRPWM_TBCTL_CLKDIV_SHIFT   10
+
+#define TI_EHRPWM_CLKDIV_MAX   7
+#define TI_EHRPWM_HSPCLKDIV_MAX7
+#define TI_EHRPWM_PERIOD_MAX   0x
+
+/* Counter compare module registers */
+#define TI_EHRPWM_CMPA 0x12
+#define TI_EHRPWM_CMPB 0x14
+
+/* Action qualifier module registers */
+#define TI_EHRPWM_AQCTLA   0x16
+#define TI_EHRPWM_AQCTLB   0x18
+#define TI_EHRPWM_AQSFRC   0x1A
+#define TI_EHRPWM_AQCSFRC  0x1C
+
+#define TI_EHRPWM_AQCTL_CBU_MASK   GENMASK(9, 8)
+#define TI_EHRPWM_AQCTL_CBU_FRCLOW BIT(8)
+#define TI_EHRPWM_AQCTL_CBU_FRCHIGHBIT(9)
+#define TI_EHRPWM_AQCTL_CBU_FRCTOGGLE  GENMASK(9, 8)
+#define TI_EHRPWM_AQCTL_CAU_MASK   GENMASK(5, 4)
+#define TI_EHRPWM_AQCTL_CAU_FRCLOW BIT(4)
+#define TI_EHRPWM_AQCTL_CAU_FRCHIGHBIT(5)
+#define TI_EHRPWM_AQCTL_CAU_FRCTOGGLE  GENMASK(5, 4)
+#define TI_EHRPWM_AQCTL_PRD_MASK   GENMASK(3, 2)
+#define TI_EHRPWM_AQCTL_PRD_FRCLOW BIT(2)
+#define TI_EHRPWM_AQCTL_PRD_FRCHIGHBIT(3)
+#define TI_EHRPWM_AQCTL_PRD_FRCTOGGLE  GENMASK(3, 2)
+#define TI_EHRPWM_AQCTL_ZRO_MASK   GENMASK(1, 0)
+#define TI_EHRPWM_AQCTL_ZRO_FRCLOW BIT(0)
+#define TI_EHRPWM_AQCTL_ZRO_FRCHIGHBIT(1)
+#define TI_EHRPWM_AQCTL_ZRO_FRCTOGGLE  GENMASK(1, 0)
+
+#define TI_EHRPWM_AQCTL_CHANA_POLNORMAL
(TI_EHRPWM_AQCTL_CAU_FRCLOW | \
+TI_EHRPWM_AQCTL_PRD_FRCHIGH | \
+

[PATCH v7 18/28] omap: timer: fix the rate setting

2020-12-23 Thread Dario Binacchi
The prescaler (PTV) setting must be taken into account even when the
timer input clock frequency has been set.

Signed-off-by: Dario Binacchi 
---

(no changes since v1)

 drivers/timer/omap-timer.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/timer/omap-timer.c b/drivers/timer/omap-timer.c
index 4eecb3e64d..c08cb5ad2e 100644
--- a/drivers/timer/omap-timer.c
+++ b/drivers/timer/omap-timer.c
@@ -19,8 +19,6 @@
 #define TCLR_PRE_ENBIT(5)  /* Pre-scaler enable */
 #define TCLR_PTV_SHIFT (2) /* Pre-scaler shift value */
 
-#define TIMER_CLOCK (V_SCLK / (2 << CONFIG_SYS_PTV))
-
 struct omap_gptimer_regs {
unsigned int tidr;  /* offset 0x00 */
unsigned char res1[12];
@@ -61,7 +59,9 @@ static int omap_timer_probe(struct udevice *dev)
struct omap_timer_priv *priv = dev_get_priv(dev);
 
if (!uc_priv->clock_rate)
-   uc_priv->clock_rate = TIMER_CLOCK;
+   uc_priv->clock_rate = V_SCLK;
+
+   uc_priv->clock_rate /= (2 << CONFIG_SYS_PTV);
 
/* start the counter ticking up, reload value on overflow */
writel(0, >regs->tldr);
-- 
2.17.1



[PATCH v7 19/28] arm: dts: am335x: enable scm_clocks auto binding

2020-12-23 Thread Dario Binacchi
Adding the 'simple-bus' compatible string to the scm_clocks node will
allow its automatic binding.

Signed-off-by: Dario Binacchi 


---

Changes in v7:
- Add dm8168-evm-u-boot.dtsi to fix building errors for
  ti816x_evm_defconfig.

Changes in v6:
- Remove the 'am3-scm' driver.
- Add the 'simple-bus' compatible string to the scm_clocks node.

Changes in v4:
- Include device_compat.h header for dev_xxx macros.

Changes in v3:
- Remove doc/device-tree-bindings/arm/omap,ctrl.txt.
- Remove doc/device-tree-bindings/pinctrl/pinctrl-single.txt.
- Add to commit message the references to linux kernel dt binding
  documentation.

Changes in v2:
- Remove the 'ti_am3_scm_clocks' driver. Handle 'scm_clocks' node in
  the 'ti_am3_scm' driver.
- Update the commit message.

 arch/arm/dts/am33xx-u-boot.dtsi |  4 
 arch/arm/dts/dm8168-evm-u-boot.dtsi | 12 
 2 files changed, 16 insertions(+)
 create mode 100644 arch/arm/dts/dm8168-evm-u-boot.dtsi

diff --git a/arch/arm/dts/am33xx-u-boot.dtsi b/arch/arm/dts/am33xx-u-boot.dtsi
index 2426ece680..61d10b841b 100644
--- a/arch/arm/dts/am33xx-u-boot.dtsi
+++ b/arch/arm/dts/am33xx-u-boot.dtsi
@@ -13,3 +13,7 @@
 _clocks {
compatible = "simple-bus";
 };
+
+_clocks {
+   compatible = "simple-bus";
+};
diff --git a/arch/arm/dts/dm8168-evm-u-boot.dtsi 
b/arch/arm/dts/dm8168-evm-u-boot.dtsi
new file mode 100644
index 00..de0bb9bc81
--- /dev/null
+++ b/arch/arm/dts/dm8168-evm-u-boot.dtsi
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * dm8168-evm U-Boot Additions
+ *
+ * Copyright (C) 2020 Dario Binacchi 
+ */
+
+/ {
+   ocp {
+   u-boot,dm-pre-reloc;
+   };
+};
-- 
2.17.1



[PATCH v7 15/28] arm: dts: am335x: enable prcm_clocks auto binding

2020-12-23 Thread Dario Binacchi
Adding the 'simple-bus' compatible string to the prcm_clocks node will
allow its automatic binding.

Signed-off-by: Dario Binacchi 


---

(no changes since v6)

Changes in v6:
- Remove the 'am3-prcm' driver.
- Add the 'simple-bus' compatible string to the prcm_clocks node.

Changes in v4:
- Include device_compat.h header for dev_xxx macros.

Changes in v3:
- Add to commit message the references to linux kernel dt binding
  documentation.

Changes in v2:
- Remove the 'ti_am3_prcm_clocks' driver. Handle 'prcm_clocks' node in
  the 'ti_am3_prcm' driver.
- Update the commit message.

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

diff --git a/arch/arm/dts/am33xx-u-boot.dtsi b/arch/arm/dts/am33xx-u-boot.dtsi
index 78f5e2c4d3..2426ece680 100644
--- a/arch/arm/dts/am33xx-u-boot.dtsi
+++ b/arch/arm/dts/am33xx-u-boot.dtsi
@@ -9,3 +9,7 @@
u-boot,dm-pre-reloc;
};
 };
+
+_clocks {
+   compatible = "simple-bus";
+};
-- 
2.17.1



[PATCH v7 14/28] clk: ti: omap4: add clock manager driver

2020-12-23 Thread Dario Binacchi
This minimal driver is only used to bind child devices.

For DT binding details see Linux doc:
- Documentation/devicetree/bindings/arm/omap/prcm.txt

Signed-off-by: Dario Binacchi 

---

(no changes since v3)

Changes in v3:
- doc/device-tree-bindings/arm/omap,prcm.txt.
- Add to commit message the references to linux kernel dt binding
  documentation.

 drivers/clk/ti/Makefile   |  2 +-
 drivers/clk/ti/omap4-cm.c | 22 ++
 2 files changed, 23 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/ti/omap4-cm.c

diff --git a/drivers/clk/ti/Makefile b/drivers/clk/ti/Makefile
index ed45f18311..dbd343069c 100644
--- a/drivers/clk/ti/Makefile
+++ b/drivers/clk/ti/Makefile
@@ -3,7 +3,7 @@
 # Copyright (C) 2020 Dario Binacchi 
 #
 
-obj-$(CONFIG_ARCH_OMAP2PLUS) += clk.o
+obj-$(CONFIG_ARCH_OMAP2PLUS) += clk.o omap4-cm.o
 
 obj-$(CONFIG_CLK_TI_AM3_DPLL) += clk-am3-dpll.o clk-am3-dpll-x2.o
 obj-$(CONFIG_CLK_TI_CTRL) += clk-ctrl.o
diff --git a/drivers/clk/ti/omap4-cm.c b/drivers/clk/ti/omap4-cm.c
new file mode 100644
index 00..3cdc9b2888
--- /dev/null
+++ b/drivers/clk/ti/omap4-cm.c
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * OMAP4 clock manager (cm)
+ *
+ * Copyright (C) 2020 Dario Binacchi 
+ */
+
+#include 
+#include 
+#include 
+
+static const struct udevice_id ti_omap4_cm_ids[] = {
+   {.compatible = "ti,omap4-cm"},
+   {}
+};
+
+U_BOOT_DRIVER(ti_omap4_cm) = {
+   .name = "ti_omap4_cm",
+   .id = UCLASS_SIMPLE_BUS,
+   .of_match = ti_omap4_cm_ids,
+   .bind = dm_scan_fdt_dev,
+};
-- 
2.17.1



[PATCH v7 04/28] arm: dts: sync am33xx with Linux 5.9-rc7

2020-12-23 Thread Dario Binacchi
There have been several changes to the am33xx.dtsi, so this patch
re-syncs it with Linux.

Let's add proper interconnect hierarchy for l4 interconnect instances
with the related ti-sysc interconnect module data as documented in
Documentation/devicetree/bindings/bus/ti-sysc.txt of the Linux kernel.
With l4 interconnect hierarchy and ti-sysc interconnect target module
data in place, we can simply move all the related child devices to their
proper location and enable probing using ti-sysc.

The am33xx-clock.dtsi file is the same as that of the Linux kernel,
except for the reg property of the node l4-wkup-clkctrl@0.
As for the am33xx.dtsi file, all the devices with drivers not yet
implemented and those I was able to test with this patch have been moved
to am33xx-l4.dtsi. In case of any regressions, problem devices can be
reverted by moving them back and removing the related interconnect
target module node.

Signed-off-by: Dario Binacchi 

---

(no changes since v4)

Changes in v4:
- Remove a blank line at end of file arch/arm/dts/am33xx-l4.dtsi.

 arch/arm/dts/am335x-draco.dtsi   |   11 +-
 arch/arm/dts/am335x-evm.dts  |2 +-
 arch/arm/dts/am335x-evmsk.dts|2 +-
 arch/arm/dts/am335x-guardian-u-boot.dtsi |5 -
 arch/arm/dts/am335x-pxm2.dtsi|2 +-
 arch/arm/dts/am335x-rut.dts  |2 +-
 arch/arm/dts/am335x-shc.dts  |2 +-
 arch/arm/dts/am33xx-clocks.dtsi  |  106 +-
 arch/arm/dts/am33xx-l4.dtsi  | 1962 ++
 arch/arm/dts/am33xx.dtsi |  721 +++-
 10 files changed, 2273 insertions(+), 542 deletions(-)
 create mode 100644 arch/arm/dts/am33xx-l4.dtsi

diff --git a/arch/arm/dts/am335x-draco.dtsi b/arch/arm/dts/am335x-draco.dtsi
index b38ff55e1d..2c125fcec9 100644
--- a/arch/arm/dts/am335x-draco.dtsi
+++ b/arch/arm/dts/am335x-draco.dtsi
@@ -20,11 +20,6 @@
};
 
ocp {
-   uart0: serial@44e09000 {
-   pinctrl-names = "default";
-   pinctrl-0 = <_pins>;
-   status = "okay";
-   };
 
i2c0: i2c@44e0b000 {
pinctrl-names = "default";
@@ -112,6 +107,12 @@
status = "disabled";
 };
 
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   status = "okay";
+};
+
  {
status = "disabled";
 };
diff --git a/arch/arm/dts/am335x-evm.dts b/arch/arm/dts/am335x-evm.dts
index 0bda4d4429..07288fb188 100644
--- a/arch/arm/dts/am335x-evm.dts
+++ b/arch/arm/dts/am335x-evm.dts
@@ -486,7 +486,7 @@
  {
status = "okay";
 
-   ecap0: ecap@48300100 {
+   ecap0: ecap@100 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <_pins>;
diff --git a/arch/arm/dts/am335x-evmsk.dts b/arch/arm/dts/am335x-evmsk.dts
index 5762967cf7..c94c33b595 100644
--- a/arch/arm/dts/am335x-evmsk.dts
+++ b/arch/arm/dts/am335x-evmsk.dts
@@ -531,7 +531,7 @@
  {
status = "okay";
 
-   ecap2: ecap@48304100 {
+   ecap2: ecap@100 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <_pins>;
diff --git a/arch/arm/dts/am335x-guardian-u-boot.dtsi 
b/arch/arm/dts/am335x-guardian-u-boot.dtsi
index 705ef335bf..eae027c541 100644
--- a/arch/arm/dts/am335x-guardian-u-boot.dtsi
+++ b/arch/arm/dts/am335x-guardian-u-boot.dtsi
@@ -26,11 +26,6 @@
u-boot,dm-pre-reloc;
 };
 
- {
-   clocks = <_per_clkctrl AM3_CLKDIV32K_CLKCTRL 0>;
-   clock-names = "int-clk";
-};
-
  {
u-boot,dm-pre-reloc;
 };
diff --git a/arch/arm/dts/am335x-pxm2.dtsi b/arch/arm/dts/am335x-pxm2.dtsi
index 19bd7e2420..645d221507 100644
--- a/arch/arm/dts/am335x-pxm2.dtsi
+++ b/arch/arm/dts/am335x-pxm2.dtsi
@@ -148,7 +148,7 @@
  {
status = "okay";
 
-   ecap0: ecap@48300100 {
+   ecap0: ecap@100 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <_pins>;
diff --git a/arch/arm/dts/am335x-rut.dts b/arch/arm/dts/am335x-rut.dts
index 145247344f..cc06f5d23a 100644
--- a/arch/arm/dts/am335x-rut.dts
+++ b/arch/arm/dts/am335x-rut.dts
@@ -174,7 +174,7 @@
  {
status = "okay";
 
-   ecap0: ecap@48300100 {
+   ecap0: ecap@100 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <_pins>;
diff --git a/arch/arm/dts/am335x-shc.dts b/arch/arm/dts/am335x-shc.dts
index 8e35c439e5..a41a0606b1 100644
--- a/arch/arm/dts/am335x-shc.dts
+++ b/arch/arm/dts/am335x-shc.dts
@@ -136,7 +136,7 @@
  {
status = "okay";
 
-   ehrpwm1: pwm@48302200 {
+   ehrpwm1: pwm@200 {
pinctrl-names = "default";
pinctrl-0 = <_pins>;
status = "okay";
diff --git a/arch/arm/dts/am33xx-clocks.dtsi b/arch/arm/dts/am33xx-clocks.dtsi
index 95d5c9d136..87c4410ee2 100644
--- a/arch/arm/dts/am33xx-clocks.dtsi
+++ 

[PATCH v7 10/28] clk: ti: add gate clock driver

2020-12-23 Thread Dario Binacchi
The patch adds support for TI gate clock binding. The code is based on
the drivers/clk/ti/gate.c driver of the Linux kernel version 5.9-rc7.
For DT binding details see:
- Documentation/devicetree/bindings/clock/ti/gate.txt

Signed-off-by: Dario Binacchi 

---

(no changes since v5)

Changes in v5:
- Move the clk-ti-gate.c file to drivers/clk/ti with the name
  clk-gate.c.

Changes in v4:
- Include device_compat.h header for dev_xxx macros.

Changes in v3:
- Remove doc/device-tree-bindings/clock/gpio-gate-clock.txt.
- Remove doc/device-tree-bindings/clock/ti,clockdomain.txt.
- Remove doc/device-tree-bindings/clock/ti,gate.txt.
- Add to commit message the references to linux kernel dt binding
  documentation.

 drivers/clk/ti/Kconfig|  6 +++
 drivers/clk/ti/Makefile   |  1 +
 drivers/clk/ti/clk-gate.c | 93 +++
 3 files changed, 100 insertions(+)
 create mode 100644 drivers/clk/ti/clk-gate.c

diff --git a/drivers/clk/ti/Kconfig b/drivers/clk/ti/Kconfig
index 87eea86c6f..30959a316a 100644
--- a/drivers/clk/ti/Kconfig
+++ b/drivers/clk/ti/Kconfig
@@ -16,6 +16,12 @@ config CLK_TI_DIVIDER
help
  This enables the divider clock driver support on TI's SoCs.
 
+config CLK_TI_GATE
+   bool "TI gate clock driver"
+   depends on CLK && OF_CONTROL
+   help
+ This enables the gate clock driver support on TI's SoCs.
+
 config CLK_TI_MUX
bool "TI mux clock driver"
depends on CLK && OF_CONTROL && CLK_CCF
diff --git a/drivers/clk/ti/Makefile b/drivers/clk/ti/Makefile
index fd7094cff0..f8aa735c83 100644
--- a/drivers/clk/ti/Makefile
+++ b/drivers/clk/ti/Makefile
@@ -7,4 +7,5 @@ obj-$(CONFIG_ARCH_OMAP2PLUS) += clk.o
 
 obj-$(CONFIG_CLK_TI_AM3_DPLL) += clk-am3-dpll.o clk-am3-dpll-x2.o
 obj-$(CONFIG_CLK_TI_DIVIDER) += clk-divider.o
+obj-$(CONFIG_CLK_TI_GATE) += clk-gate.o
 obj-$(CONFIG_CLK_TI_MUX) += clk-mux.o
diff --git a/drivers/clk/ti/clk-gate.c b/drivers/clk/ti/clk-gate.c
new file mode 100644
index 00..6c5432c823
--- /dev/null
+++ b/drivers/clk/ti/clk-gate.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * TI gate clock support
+ *
+ * Copyright (C) 2020 Dario Binacchi 
+ *
+ * Loosely based on Linux kernel drivers/clk/ti/gate.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct clk_ti_gate_priv {
+   fdt_addr_t reg;
+   u8 enable_bit;
+   u32 flags;
+   bool invert_enable;
+};
+
+static int clk_ti_gate_disable(struct clk *clk)
+{
+   struct clk_ti_gate_priv *priv = dev_get_priv(clk->dev);
+   u32 v;
+
+   v = readl(priv->reg);
+   if (priv->invert_enable)
+   v |= (1 << priv->enable_bit);
+   else
+   v &= ~(1 << priv->enable_bit);
+
+   writel(v, priv->reg);
+   /* No OCP barrier needed here since it is a disable operation */
+   return 0;
+}
+
+static int clk_ti_gate_enable(struct clk *clk)
+{
+   struct clk_ti_gate_priv *priv = dev_get_priv(clk->dev);
+   u32 v;
+
+   v = readl(priv->reg);
+   if (priv->invert_enable)
+   v &= ~(1 << priv->enable_bit);
+   else
+   v |= (1 << priv->enable_bit);
+
+   writel(v, priv->reg);
+   /* OCP barrier */
+   v = readl(priv->reg);
+   return 0;
+}
+
+static int clk_ti_gate_ofdata_to_platdata(struct udevice *dev)
+{
+   struct clk_ti_gate_priv *priv = dev_get_priv(dev);
+
+   priv->reg = dev_read_addr(dev);
+   if (priv->reg == FDT_ADDR_T_NONE) {
+   dev_err(dev, "failed to get control register\n");
+   return -EINVAL;
+   }
+
+   dev_dbg(dev, "reg=0x%08lx\n", priv->reg);
+   priv->enable_bit = dev_read_u32_default(dev, "ti,bit-shift", 0);
+   if (dev_read_bool(dev, "ti,set-rate-parent"))
+   priv->flags |= CLK_SET_RATE_PARENT;
+
+   priv->invert_enable = dev_read_bool(dev, "ti,set-bit-to-disable");
+   return 0;
+}
+
+static struct clk_ops clk_ti_gate_ops = {
+   .enable = clk_ti_gate_enable,
+   .disable = clk_ti_gate_disable,
+};
+
+static const struct udevice_id clk_ti_gate_of_match[] = {
+   { .compatible = "ti,gate-clock" },
+   { },
+};
+
+U_BOOT_DRIVER(clk_ti_gate) = {
+   .name = "ti_gate_clock",
+   .id = UCLASS_CLK,
+   .of_match = clk_ti_gate_of_match,
+   .ofdata_to_platdata = clk_ti_gate_ofdata_to_platdata,
+   .priv_auto_alloc_size = sizeof(struct clk_ti_gate_priv),
+   .ops = _ti_gate_ops,
+};
-- 
2.17.1



[PATCH v7 13/28] clk: ti: add support for clkctrl clocks

2020-12-23 Thread Dario Binacchi
Until now the clkctrl clocks have been enabled/disabled through platform
routines. Thanks to this patch they can be enabled and configured directly
by the probed devices that need to use them.

For DT binding details see Linux doc:
- Documentation/devicetree/bindings/clock/ti-clkctrl.txt

Signed-off-by: Dario Binacchi 

---

(no changes since v5)

Changes in v5:
- Move the clk-ti-ctrl.c file to drivers/clk/ti with the name
  clk-ctrl.c.

Changes in v4:
- Include device_compat.h header for dev_xxx macros.
- Fix compilation errors on the dev parameter of the dev_xx macros.

Changes in v3:
- Fix access to registers listed by device tree following resync of
  am33xx-clock.dtsi with Linux 5.9-rc7.
- Remove doc/device-tree-bindings/clock/ti,clkctrl.txt.
- Add to commit message the references to linux kernel dt binding
  documentation.

 drivers/clk/ti/Kconfig|   6 ++
 drivers/clk/ti/Makefile   |   1 +
 drivers/clk/ti/clk-ctrl.c | 154 ++
 3 files changed, 161 insertions(+)
 create mode 100644 drivers/clk/ti/clk-ctrl.c

diff --git a/drivers/clk/ti/Kconfig b/drivers/clk/ti/Kconfig
index 30959a316a..9e257a2eb7 100644
--- a/drivers/clk/ti/Kconfig
+++ b/drivers/clk/ti/Kconfig
@@ -10,6 +10,12 @@ config CLK_TI_AM3_DPLL
  This enables the DPLL clock drivers support on AM33XX SoCs. The DPLL
  provides all interface clocks and functional clocks to the processor.
 
+config CLK_TI_CTRL
+   bool "TI OMAP4 clock controller"
+   depends on CLK && OF_CONTROL
+   help
+ This enables the clock controller driver support on TI's SoCs.
+
 config CLK_TI_DIVIDER
bool "TI divider clock driver"
depends on CLK && OF_CONTROL && CLK_CCF
diff --git a/drivers/clk/ti/Makefile b/drivers/clk/ti/Makefile
index f8aa735c83..ed45f18311 100644
--- a/drivers/clk/ti/Makefile
+++ b/drivers/clk/ti/Makefile
@@ -6,6 +6,7 @@
 obj-$(CONFIG_ARCH_OMAP2PLUS) += clk.o
 
 obj-$(CONFIG_CLK_TI_AM3_DPLL) += clk-am3-dpll.o clk-am3-dpll-x2.o
+obj-$(CONFIG_CLK_TI_CTRL) += clk-ctrl.o
 obj-$(CONFIG_CLK_TI_DIVIDER) += clk-divider.o
 obj-$(CONFIG_CLK_TI_GATE) += clk-gate.o
 obj-$(CONFIG_CLK_TI_MUX) += clk-mux.o
diff --git a/drivers/clk/ti/clk-ctrl.c b/drivers/clk/ti/clk-ctrl.c
new file mode 100644
index 00..74271aaf56
--- /dev/null
+++ b/drivers/clk/ti/clk-ctrl.c
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * OMAP clock controller support
+ *
+ * Copyright (C) 2020 Dario Binacchi 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct clk_ti_ctrl_offs {
+   fdt_addr_t start;
+   fdt_size_t end;
+};
+
+struct clk_ti_ctrl_priv {
+   int offs_num;
+   struct clk_ti_ctrl_offs *offs;
+};
+
+static int clk_ti_ctrl_check_offs(struct clk *clk, fdt_addr_t offs)
+{
+   struct clk_ti_ctrl_priv *priv = dev_get_priv(clk->dev);
+   int i;
+
+   for (i = 0; i < priv->offs_num; i++) {
+   if (offs >= priv->offs[i].start && offs <= priv->offs[i].end)
+   return 0;
+   }
+
+   return -EFAULT;
+}
+
+static int clk_ti_ctrl_disable(struct clk *clk)
+{
+   struct clk_ti_ctrl_priv *priv = dev_get_priv(clk->dev);
+   u32 *clk_modules[2] = { };
+   fdt_addr_t offs;
+   int err;
+
+   offs = priv->offs[0].start + clk->id;
+   err = clk_ti_ctrl_check_offs(clk, offs);
+   if (err) {
+   dev_err(clk->dev, "invalid offset: 0x%lx\n", offs);
+   return err;
+   }
+
+   clk_modules[0] = (u32 *)(offs);
+   dev_dbg(clk->dev, "module address=%p\n", clk_modules[0]);
+   do_disable_clocks(NULL, clk_modules, 1);
+   return 0;
+}
+
+static int clk_ti_ctrl_enable(struct clk *clk)
+{
+   struct clk_ti_ctrl_priv *priv = dev_get_priv(clk->dev);
+   u32 *clk_modules[2] = { };
+   fdt_addr_t offs;
+   int err;
+
+   offs = priv->offs[0].start + clk->id;
+   err = clk_ti_ctrl_check_offs(clk, offs);
+   if (err) {
+   dev_err(clk->dev, "invalid offset: 0x%lx\n", offs);
+   return err;
+   }
+
+   clk_modules[0] = (u32 *)(offs);
+   dev_dbg(clk->dev, "module address=%p\n", clk_modules[0]);
+   do_enable_clocks(NULL, clk_modules, 1);
+   return 0;
+}
+
+static ulong clk_ti_ctrl_get_rate(struct clk *clk)
+{
+   return 0;
+}
+
+static int clk_ti_ctrl_of_xlate(struct clk *clk,
+   struct ofnode_phandle_args *args)
+{
+   if (args->args_count != 2) {
+   dev_err(clk->dev, "invaild args_count: %d\n", args->args_count);
+   return -EINVAL;
+   }
+
+   if (args->args_count)
+   clk->id = args->args[0];
+   else
+   clk->id = 0;
+
+   dev_dbg(clk->dev, "name=%s, id=%ld\n", clk->dev->name, clk->id);
+   return 0;
+}
+
+static int clk_ti_ctrl_ofdata_to_platdata(struct udevice *dev)
+{
+   struct clk_ti_ctrl_priv *priv = dev_get_priv(dev);
+   fdt_size_t fdt_size;
+   int i, 

[PATCH v7 09/28] clk: ti: add divider clock driver

2020-12-23 Thread Dario Binacchi
The patch adds support for TI divider clock binding. The driver uses
routines provided by the common clock framework (ccf).

The code is based on the drivers/clk/ti/divider.c driver of the Linux
kernel version 5.9-rc7.
For DT binding details see:
- Documentation/devicetree/bindings/clock/ti/divider.txt

Signed-off-by: Dario Binacchi 

---

(no changes since v5)

Changes in v5:
- Move the clk-ti.c file to drivers/clk/ti with the name clk.c.
- Move the clk-ti.h file to drivers/clk/ti with the name clk.h.
- Move the clk-ti-divider.c file to drivers/clk/ti with the name
  clk-divider.c.

Changes in v4:
- Include device_compat.h header for dev_xxx macros.
- Fix compilation errors on the dev parameter of the dev_xx macros.

Changes in v3:
- Remove doc/device-tree-bindings/clock/ti,autoidle.txt.
- Remove doc/device-tree-bindings/clock/ti,divider.txt.
- Add to commit message the references to linux kernel dt binding
  documentation.

Changes in v2:
- Merged to patch [09/31] clk: ti: refactor mux and divider clock
  drivers.

 drivers/clk/ti/Kconfig   |   6 +
 drivers/clk/ti/Makefile  |   3 +
 drivers/clk/ti/clk-divider.c | 381 +++
 drivers/clk/ti/clk-mux.c |  27 +--
 drivers/clk/ti/clk.c |  34 
 drivers/clk/ti/clk.h |  13 ++
 6 files changed, 439 insertions(+), 25 deletions(-)
 create mode 100644 drivers/clk/ti/clk-divider.c
 create mode 100644 drivers/clk/ti/clk.c
 create mode 100644 drivers/clk/ti/clk.h

diff --git a/drivers/clk/ti/Kconfig b/drivers/clk/ti/Kconfig
index c430dd9b8a..87eea86c6f 100644
--- a/drivers/clk/ti/Kconfig
+++ b/drivers/clk/ti/Kconfig
@@ -10,6 +10,12 @@ config CLK_TI_AM3_DPLL
  This enables the DPLL clock drivers support on AM33XX SoCs. The DPLL
  provides all interface clocks and functional clocks to the processor.
 
+config CLK_TI_DIVIDER
+   bool "TI divider clock driver"
+   depends on CLK && OF_CONTROL && CLK_CCF
+   help
+ This enables the divider clock driver support on TI's SoCs.
+
 config CLK_TI_MUX
bool "TI mux clock driver"
depends on CLK && OF_CONTROL && CLK_CCF
diff --git a/drivers/clk/ti/Makefile b/drivers/clk/ti/Makefile
index 9e14b83cfe..fd7094cff0 100644
--- a/drivers/clk/ti/Makefile
+++ b/drivers/clk/ti/Makefile
@@ -3,5 +3,8 @@
 # Copyright (C) 2020 Dario Binacchi 
 #
 
+obj-$(CONFIG_ARCH_OMAP2PLUS) += clk.o
+
 obj-$(CONFIG_CLK_TI_AM3_DPLL) += clk-am3-dpll.o clk-am3-dpll-x2.o
+obj-$(CONFIG_CLK_TI_DIVIDER) += clk-divider.o
 obj-$(CONFIG_CLK_TI_MUX) += clk-mux.o
diff --git a/drivers/clk/ti/clk-divider.c b/drivers/clk/ti/clk-divider.c
new file mode 100644
index 00..d448197b1f
--- /dev/null
+++ b/drivers/clk/ti/clk-divider.c
@@ -0,0 +1,381 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * TI divider clock support
+ *
+ * Copyright (C) 2020 Dario Binacchi 
+ *
+ * Loosely based on Linux kernel drivers/clk/ti/divider.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "clk.h"
+
+/*
+ * The reverse of DIV_ROUND_UP: The maximum number which
+ * divided by m is r
+ */
+#define MULT_ROUND_UP(r, m) ((r) * (m) + (m) - 1)
+
+struct clk_ti_divider_priv {
+   struct clk parent;
+   fdt_addr_t reg;
+   const struct clk_div_table *table;
+   u8 shift;
+   u8 flags;
+   u8 div_flags;
+   s8 latch;
+   u16 min;
+   u16 max;
+   u16 mask;
+};
+
+static unsigned int _get_div(const struct clk_div_table *table, ulong flags,
+unsigned int val)
+{
+   if (flags & CLK_DIVIDER_ONE_BASED)
+   return val;
+
+   if (flags & CLK_DIVIDER_POWER_OF_TWO)
+   return 1 << val;
+
+   if (table)
+   return clk_divider_get_table_div(table, val);
+
+   return val + 1;
+}
+
+static unsigned int _get_val(const struct clk_div_table *table, ulong flags,
+unsigned int div)
+{
+   if (flags & CLK_DIVIDER_ONE_BASED)
+   return div;
+
+   if (flags & CLK_DIVIDER_POWER_OF_TWO)
+   return __ffs(div);
+
+   if (table)
+   return clk_divider_get_table_val(table, div);
+
+   return div - 1;
+}
+
+static int _div_round_up(const struct clk_div_table *table, ulong parent_rate,
+ulong rate)
+{
+   const struct clk_div_table *clkt;
+   int up = INT_MAX;
+   int div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
+
+   for (clkt = table; clkt->div; clkt++) {
+   if (clkt->div == div)
+   return clkt->div;
+   else if (clkt->div < div)
+   continue;
+
+   if ((clkt->div - div) < (up - div))
+   up = clkt->div;
+   }
+
+   return up;
+}
+
+static int _div_round(const struct clk_div_table *table, ulong parent_rate,
+ ulong rate)
+{
+   if (table)
+   return 

[PATCH v7 11/28] arm: dts: am335x: include am33xx-u-boot.dtsi

2020-12-23 Thread Dario Binacchi
Include the SoC U-boot DTS in each am335x--u-boot.dtsi.

Signed-off-by: Dario Binacchi 

---

(no changes since v1)

 arch/arm/dts/am335x-chiliboard-u-boot.dtsi | 2 ++
 arch/arm/dts/am335x-evm-u-boot.dtsi| 2 ++
 arch/arm/dts/am335x-evmsk-u-boot.dtsi  | 2 ++
 arch/arm/dts/am335x-guardian-u-boot.dtsi   | 2 ++
 arch/arm/dts/am335x-icev2-u-boot.dtsi  | 3 +++
 arch/arm/dts/am335x-pdu001-u-boot.dtsi | 2 ++
 arch/arm/dts/am335x-pxm50-u-boot.dtsi  | 2 ++
 arch/arm/dts/am335x-regor-rdk-u-boot.dtsi  | 2 ++
 arch/arm/dts/am335x-rut-u-boot.dtsi| 2 ++
 arch/arm/dts/am335x-shc-u-boot.dtsi| 2 ++
 arch/arm/dts/am335x-wega-rdk-u-boot.dtsi   | 2 ++
 11 files changed, 23 insertions(+)

diff --git a/arch/arm/dts/am335x-chiliboard-u-boot.dtsi 
b/arch/arm/dts/am335x-chiliboard-u-boot.dtsi
index 4f9d308039..06a13872ee 100644
--- a/arch/arm/dts/am335x-chiliboard-u-boot.dtsi
+++ b/arch/arm/dts/am335x-chiliboard-u-boot.dtsi
@@ -4,6 +4,8 @@
  * Author: Marcin Niestroj 
  */
 
+#include "am33xx-u-boot.dtsi"
+
 / {
chosen {
stdout-path = 
diff --git a/arch/arm/dts/am335x-evm-u-boot.dtsi 
b/arch/arm/dts/am335x-evm-u-boot.dtsi
index d7b049ef20..400a1d2cec 100644
--- a/arch/arm/dts/am335x-evm-u-boot.dtsi
+++ b/arch/arm/dts/am335x-evm-u-boot.dtsi
@@ -3,6 +3,8 @@
  * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/
  */
 
+#include "am33xx-u-boot.dtsi"
+
 / {
panel {
u-boot,dm-pre-reloc;
diff --git a/arch/arm/dts/am335x-evmsk-u-boot.dtsi 
b/arch/arm/dts/am335x-evmsk-u-boot.dtsi
index 599fb377e6..96798330b1 100644
--- a/arch/arm/dts/am335x-evmsk-u-boot.dtsi
+++ b/arch/arm/dts/am335x-evmsk-u-boot.dtsi
@@ -5,6 +5,8 @@
  * Copyright (C) 2020 Dario Binacchi 
  */
 
+#include "am33xx-u-boot.dtsi"
+
 / {
panel {
u-boot,dm-pre-reloc;
diff --git a/arch/arm/dts/am335x-guardian-u-boot.dtsi 
b/arch/arm/dts/am335x-guardian-u-boot.dtsi
index eae027c541..c866ce83f3 100644
--- a/arch/arm/dts/am335x-guardian-u-boot.dtsi
+++ b/arch/arm/dts/am335x-guardian-u-boot.dtsi
@@ -4,6 +4,8 @@
  * Copyright (C) 2018 Robert Bosch Power Tools GmbH
  */
 
+#include "am33xx-u-boot.dtsi"
+
 / {
ocp {
u-boot,dm-pre-reloc;
diff --git a/arch/arm/dts/am335x-icev2-u-boot.dtsi 
b/arch/arm/dts/am335x-icev2-u-boot.dtsi
index cc9569af03..67bfac916e 100644
--- a/arch/arm/dts/am335x-icev2-u-boot.dtsi
+++ b/arch/arm/dts/am335x-icev2-u-boot.dtsi
@@ -2,6 +2,9 @@
 /*
  * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
  */
+
+#include "am33xx-u-boot.dtsi"
+
 / {
xtal25mhz: xtal25mhz {
compatible = "fixed-clock";
diff --git a/arch/arm/dts/am335x-pdu001-u-boot.dtsi 
b/arch/arm/dts/am335x-pdu001-u-boot.dtsi
index a799fe9bc3..4f4fc411f9 100644
--- a/arch/arm/dts/am335x-pdu001-u-boot.dtsi
+++ b/arch/arm/dts/am335x-pdu001-u-boot.dtsi
@@ -3,6 +3,8 @@
  * Copyright (C) 2018 EETS GmbH - https://www.eets.ch/
  */
 
+#include "am33xx-u-boot.dtsi"
+
 / {
ocp {
u-boot,dm-pre-reloc;
diff --git a/arch/arm/dts/am335x-pxm50-u-boot.dtsi 
b/arch/arm/dts/am335x-pxm50-u-boot.dtsi
index 77dfe6e262..65ed948c58 100644
--- a/arch/arm/dts/am335x-pxm50-u-boot.dtsi
+++ b/arch/arm/dts/am335x-pxm50-u-boot.dtsi
@@ -5,6 +5,8 @@
  * Copyright (C) 2020 Dario Binacchi 
  */
 
+#include "am33xx-u-boot.dtsi"
+
 / {
panel {
u-boot,dm-pre-reloc;
diff --git a/arch/arm/dts/am335x-regor-rdk-u-boot.dtsi 
b/arch/arm/dts/am335x-regor-rdk-u-boot.dtsi
index 1ddd715875..4052d0ee21 100644
--- a/arch/arm/dts/am335x-regor-rdk-u-boot.dtsi
+++ b/arch/arm/dts/am335x-regor-rdk-u-boot.dtsi
@@ -3,6 +3,8 @@
  * Copyright (C) 2020 Linumiz
  */
 
+#include "am33xx-u-boot.dtsi"
+
 / {
chosen {
#address-cells = <1>;
diff --git a/arch/arm/dts/am335x-rut-u-boot.dtsi 
b/arch/arm/dts/am335x-rut-u-boot.dtsi
index b2b4aa596a..b16f75a764 100644
--- a/arch/arm/dts/am335x-rut-u-boot.dtsi
+++ b/arch/arm/dts/am335x-rut-u-boot.dtsi
@@ -5,6 +5,8 @@
  * Copyright (C) 2020 Dario Binacchi 
  */
 
+#include "am33xx-u-boot.dtsi"
+
 / {
panel {
u-boot,dm-pre-reloc;
diff --git a/arch/arm/dts/am335x-shc-u-boot.dtsi 
b/arch/arm/dts/am335x-shc-u-boot.dtsi
index 2975839ea7..359ae05209 100644
--- a/arch/arm/dts/am335x-shc-u-boot.dtsi
+++ b/arch/arm/dts/am335x-shc-u-boot.dtsi
@@ -3,6 +3,8 @@
  * Copyright (C) 2019 Heiko Schocher 
  */
 
+#include "am33xx-u-boot.dtsi"
+
 / {
ocp {
u-boot,dm-pre-reloc;
diff --git a/arch/arm/dts/am335x-wega-rdk-u-boot.dtsi 
b/arch/arm/dts/am335x-wega-rdk-u-boot.dtsi
index 634f1b0712..28fd62e231 100644
--- a/arch/arm/dts/am335x-wega-rdk-u-boot.dtsi
+++ b/arch/arm/dts/am335x-wega-rdk-u-boot.dtsi
@@ -3,6 +3,8 @@
  * Copyright (C) 2019 DENX Software Engineering GmbH
  */
 
+#include "am33xx-u-boot.dtsi"
+
 / {
chosen {
#address-cells = <1>;
-- 
2.17.1



[PATCH v7 12/28] ti: am33xx: fix do_enable_clocks() to accept NULL parameters

2020-12-23 Thread Dario Binacchi
Up till this commit passing NULL as input parameter was allowed, but not
handled properly. When a NULL parameter was passed to the function a data
abort was raised.

Signed-off-by: Dario Binacchi 
Reviewed-by: Simon Glass 
---

(no changes since v1)

 arch/arm/mach-omap2/am33xx/clock.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-omap2/am33xx/clock.c 
b/arch/arm/mach-omap2/am33xx/clock.c
index 8819062aaa..130ee6c6e3 100644
--- a/arch/arm/mach-omap2/am33xx/clock.c
+++ b/arch/arm/mach-omap2/am33xx/clock.c
@@ -194,13 +194,14 @@ void do_enable_clocks(u32 *const *clk_domains,
u32 i, max = 100;
 
/* Put the clock domains in SW_WKUP mode */
-   for (i = 0; (i < max) && clk_domains[i]; i++) {
+   for (i = 0; (i < max) && clk_domains && clk_domains[i]; i++) {
enable_clock_domain(clk_domains[i],
CD_CLKCTRL_CLKTRCTRL_SW_WKUP);
}
 
/* Clock modules that need to be put in SW_EXPLICIT_EN mode */
-   for (i = 0; (i < max) && clk_modules_explicit_en[i]; i++) {
+   for (i = 0; (i < max) && clk_modules_explicit_en &&
+clk_modules_explicit_en[i]; i++) {
enable_clock_module(clk_modules_explicit_en[i],
MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN,
wait_for_enable);
@@ -215,12 +216,13 @@ void do_disable_clocks(u32 *const *clk_domains,
 
 
/* Clock modules that need to be put in SW_DISABLE */
-   for (i = 0; (i < max) && clk_modules_disable[i]; i++)
+   for (i = 0; (i < max) && clk_modules_disable && clk_modules_disable[i];
+i++)
disable_clock_module(clk_modules_disable[i],
 wait_for_disable);
 
/* Put the clock domains in SW_SLEEP mode */
-   for (i = 0; (i < max) && clk_domains[i]; i++)
+   for (i = 0; (i < max) && clk_domains && clk_domains[i]; i++)
disable_clock_domain(clk_domains[i]);
 }
 
-- 
2.17.1



[PATCH v7 08/28] clk: ti: am33xx: add DPLL clock drivers

2020-12-23 Thread Dario Binacchi
The digital phase-locked loop (DPLL) provides all interface clocks and
functional clocks to the processor of the AM33xx device. The AM33xx
device integrates five different DPLLs:
 * Core DPLL
 * Per DPLL
 * LCD DPLL
 * DDR DPLL
 * MPU DPLL

The patch adds support for the compatible strings:
 * "ti,am3-dpll-core-clock"
 * "ti,am3-dpll-no-gate-clock"
 * "ti,am3-dpll-no-gate-j-type-clock"
 * "ti,am3-dpll-x2-clock"

The code is loosely based on the drivers/clk/ti/dpll.c drivers of the
Linux kernel version 5.9-rc7.
For DT binding details see:
- Documentation/devicetree/bindings/clock/ti/dpll.txt

Signed-off-by: Dario Binacchi 

---

(no changes since v5)

Changes in v5:
- Move the clk-ti-am3-dpll.c file to drivers/clk/ti with the name
  clk-am3-dpll.c.
- Move the clk-ti-am3-dpll-x2.c file to drivers/clk/ti with the name
  clk-am3-dpll-x2.c.

Changes in v4:
- Include device_compat.h header for dev_xxx macros.
- Fix compilation errors on the dev parameter of the dev_xx macros.

Changes in v3:
- Remove doc/device-tree-bindings/clock/ti,dpll.txt.
- Add to commit message the references to linux kernel dt binding
  documentation.

 drivers/clk/ti/Kconfig   |   7 +
 drivers/clk/ti/Makefile  |   1 +
 drivers/clk/ti/clk-am3-dpll-x2.c |  79 +
 drivers/clk/ti/clk-am3-dpll.c| 268 +++
 4 files changed, 355 insertions(+)
 create mode 100644 drivers/clk/ti/clk-am3-dpll-x2.c
 create mode 100644 drivers/clk/ti/clk-am3-dpll.c

diff --git a/drivers/clk/ti/Kconfig b/drivers/clk/ti/Kconfig
index be4f26817f..c430dd9b8a 100644
--- a/drivers/clk/ti/Kconfig
+++ b/drivers/clk/ti/Kconfig
@@ -3,6 +3,13 @@
 # Copyright (C) 2020 Dario Binacchi 
 #
 
+config CLK_TI_AM3_DPLL
+   bool "TI AM33XX Digital Phase-Locked Loop (DPLL) clock drivers"
+   depends on CLK && OF_CONTROL
+   help
+ This enables the DPLL clock drivers support on AM33XX SoCs. The DPLL
+ provides all interface clocks and functional clocks to the processor.
+
 config CLK_TI_MUX
bool "TI mux clock driver"
depends on CLK && OF_CONTROL && CLK_CCF
diff --git a/drivers/clk/ti/Makefile b/drivers/clk/ti/Makefile
index 5faf68d30e..9e14b83cfe 100644
--- a/drivers/clk/ti/Makefile
+++ b/drivers/clk/ti/Makefile
@@ -3,4 +3,5 @@
 # Copyright (C) 2020 Dario Binacchi 
 #
 
+obj-$(CONFIG_CLK_TI_AM3_DPLL) += clk-am3-dpll.o clk-am3-dpll-x2.o
 obj-$(CONFIG_CLK_TI_MUX) += clk-mux.o
diff --git a/drivers/clk/ti/clk-am3-dpll-x2.c b/drivers/clk/ti/clk-am3-dpll-x2.c
new file mode 100644
index 00..3aa35f0e6c
--- /dev/null
+++ b/drivers/clk/ti/clk-am3-dpll-x2.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * TI DPLL x2 clock support
+ *
+ * Copyright (C) 2020 Dario Binacchi 
+ *
+ * Loosely based on Linux kernel drivers/clk/ti/dpll.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct clk_ti_am3_dpll_x2_priv {
+   struct clk parent;
+};
+
+static ulong clk_ti_am3_dpll_x2_get_rate(struct clk *clk)
+{
+   struct clk_ti_am3_dpll_x2_priv *priv = dev_get_priv(clk->dev);
+   unsigned long rate;
+
+   rate = clk_get_rate(>parent);
+   if (IS_ERR_VALUE(rate))
+   return rate;
+
+   rate *= 2;
+   dev_dbg(clk->dev, "rate=%ld\n", rate);
+   return rate;
+}
+
+const struct clk_ops clk_ti_am3_dpll_x2_ops = {
+   .get_rate = clk_ti_am3_dpll_x2_get_rate,
+};
+
+static int clk_ti_am3_dpll_x2_remove(struct udevice *dev)
+{
+   struct clk_ti_am3_dpll_x2_priv *priv = dev_get_priv(dev);
+   int err;
+
+   err = clk_release_all(>parent, 1);
+   if (err) {
+   dev_err(dev, "failed to release parent clock\n");
+   return err;
+   }
+
+   return 0;
+}
+
+static int clk_ti_am3_dpll_x2_probe(struct udevice *dev)
+{
+   struct clk_ti_am3_dpll_x2_priv *priv = dev_get_priv(dev);
+   int err;
+
+   err = clk_get_by_index(dev, 0, >parent);
+   if (err) {
+   dev_err(dev, "%s: failed to get parent clock\n", __func__);
+   return err;
+   }
+
+   return 0;
+}
+
+static const struct udevice_id clk_ti_am3_dpll_x2_of_match[] = {
+   {.compatible = "ti,am3-dpll-x2-clock"},
+   {}
+};
+
+U_BOOT_DRIVER(clk_ti_am3_dpll_x2) = {
+   .name = "ti_am3_dpll_x2_clock",
+   .id = UCLASS_CLK,
+   .of_match = clk_ti_am3_dpll_x2_of_match,
+   .probe = clk_ti_am3_dpll_x2_probe,
+   .remove = clk_ti_am3_dpll_x2_remove,
+   .priv_auto_alloc_size = sizeof(struct clk_ti_am3_dpll_x2_priv),
+   .ops = _ti_am3_dpll_x2_ops,
+};
diff --git a/drivers/clk/ti/clk-am3-dpll.c b/drivers/clk/ti/clk-am3-dpll.c
new file mode 100644
index 00..d50660aae2
--- /dev/null
+++ b/drivers/clk/ti/clk-am3-dpll.c
@@ -0,0 +1,268 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * TI DPLL clock support
+ *
+ * Copyright (C) 2020 Dario Binacchi 
+ *
+ * Loosely based on Linux kernel drivers/clk/ti/dpll.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 

[PATCH v7 06/28] clk: ti: add mux clock driver

2020-12-23 Thread Dario Binacchi
The driver manages a register-mapped multiplexer with multiple input
clock signals or parents, one of which can be selected as output. It
uses routines provided by the common clock framework (ccf).

The code is based on the drivers/clk/ti/mux.c driver of the Linux
kernel version 5.9-rc7.
For DT binding details see:
- Documentation/devicetree/bindings/clock/ti/mux.txt

Signed-off-by: Dario Binacchi 

---

(no changes since v5)

Changes in v5:
- Create drivers/clk/ti directory.
- Move the clk-ti-mux.c file to drivers/clk/ti and rename it clk-mux.c

Changes in v4:
- Include device_compat.h header for dev_xxx macros.

Changes in v3:
- Remove doc/device-tree-bindings/clock/clock-bindings.txt.
- Remove doc/device-tree-bindings/clock/ti,mux.txt.
- Add to commit message the references to linux kernel dt binding
  documentation.

 drivers/clk/Kconfig  |   1 +
 drivers/clk/Makefile |   1 +
 drivers/clk/ti/Kconfig   |  10 ++
 drivers/clk/ti/Makefile  |   6 +
 drivers/clk/ti/clk-mux.c | 276 +++
 5 files changed, 294 insertions(+)
 create mode 100644 drivers/clk/ti/Kconfig
 create mode 100644 drivers/clk/ti/Makefile
 create mode 100644 drivers/clk/ti/clk-mux.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 4dfbad7986..9e54929039 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -179,6 +179,7 @@ source "drivers/clk/renesas/Kconfig"
 source "drivers/clk/sunxi/Kconfig"
 source "drivers/clk/sifive/Kconfig"
 source "drivers/clk/tegra/Kconfig"
+source "drivers/clk/ti/Kconfig"
 source "drivers/clk/uniphier/Kconfig"
 
 config ICS8N3QV01
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index d1e295ac7c..2581fe0a19 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_$(SPL_TPL_)CLK_COMPOSITE_CCF) += clk-composite.o
 obj-y += analogbits/
 obj-y += imx/
 obj-y += tegra/
+obj-y += ti/
 obj-$(CONFIG_ARCH_ASPEED) += aspeed/
 obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
 obj-$(CONFIG_ARCH_MTMIPS) += mtmips/
diff --git a/drivers/clk/ti/Kconfig b/drivers/clk/ti/Kconfig
new file mode 100644
index 00..be4f26817f
--- /dev/null
+++ b/drivers/clk/ti/Kconfig
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2020 Dario Binacchi 
+#
+
+config CLK_TI_MUX
+   bool "TI mux clock driver"
+   depends on CLK && OF_CONTROL && CLK_CCF
+   help
+ This enables the mux clock driver support on TI's SoCs.
diff --git a/drivers/clk/ti/Makefile b/drivers/clk/ti/Makefile
new file mode 100644
index 00..5faf68d30e
--- /dev/null
+++ b/drivers/clk/ti/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2020 Dario Binacchi 
+#
+
+obj-$(CONFIG_CLK_TI_MUX) += clk-mux.o
diff --git a/drivers/clk/ti/clk-mux.c b/drivers/clk/ti/clk-mux.c
new file mode 100644
index 00..9720c84513
--- /dev/null
+++ b/drivers/clk/ti/clk-mux.c
@@ -0,0 +1,276 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * TI multiplexer clock support
+ *
+ * Copyright (C) 2020 Dario Binacchi 
+ *
+ * Based on Linux kernel drivers/clk/ti/mux.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct clk_ti_mux_priv {
+   struct clk_bulk parents;
+   fdt_addr_t reg;
+   u32 flags;
+   u32 mux_flags;
+   u32 mask;
+   u32 shift;
+   s32 latch;
+};
+
+static void clk_ti_mux_rmw(u32 val, u32 mask, fdt_addr_t reg)
+{
+   u32 v;
+
+   v = readl(reg);
+   v &= ~mask;
+   v |= val;
+   writel(v, reg);
+}
+
+static void clk_ti_mux_latch(fdt_addr_t reg, s8 shift)
+{
+   u32 latch;
+
+   if (shift < 0)
+   return;
+
+   latch = 1 << shift;
+
+   clk_ti_mux_rmw(latch, latch, reg);
+   clk_ti_mux_rmw(0, latch, reg);
+   readl(reg); /* OCP barrier */
+}
+
+static struct clk *clk_ti_mux_get_parent_by_index(struct clk_bulk *parents,
+ int index)
+{
+   if (index < 0 || !parents)
+   return ERR_PTR(-EINVAL);
+
+   if (index >= parents->count)
+   return ERR_PTR(-ENODEV);
+
+   return >clks[index];
+}
+
+static int clk_ti_mux_get_parent_index(struct clk_bulk *parents,
+  struct clk *parent)
+{
+   int i;
+
+   if (!parents || !parent)
+   return -EINVAL;
+
+   for (i = 0; i < parents->count; i++) {
+   if (parents->clks[i].dev == parent->dev)
+   return i;
+   }
+
+   return -ENODEV;
+}
+
+static int clk_ti_mux_get_index(struct clk *clk)
+{
+   struct clk_ti_mux_priv *priv = dev_get_priv(clk->dev);
+   u32 val;
+
+   val = readl(priv->reg);
+   val >>= priv->shift;
+   val &= priv->mask;
+
+   if (val && (priv->flags & CLK_MUX_INDEX_BIT))
+   val = ffs(val) - 1;
+
+   if (val && (priv->flags & CLK_MUX_INDEX_ONE))
+   val--;
+
+   if (val >= priv->parents.count)
+   

[PATCH v7 03/28] bus: ti: add minimal sysc interconnect target driver

2020-12-23 Thread Dario Binacchi
We can handle the sysc interconnect target module in a generic way for
many TI SoCs. Initially let's just enable domain clocks before the
children are probed.

The code is loosely based on the drivers/bus/ti-sysc.c of the Linux
kernel version 5.9-rc7.
For DT binding details see:
- Documentation/devicetree/bindings/bus/ti-sysc.txt

Signed-off-by: Dario Binacchi 

---

Changes in v7:
- Not all OMAP2 platform need CONFIG_TI_SYSC.
  Set CONFIG_TI_SYSC as imply and disable it to fix building errors in:
   nokia_rx51_defconfig
   cm_t335_defconfig

Changes in v4:
- Include device_compat.h header for dev_xxx macros.

 arch/arm/Kconfig |   1 +
 configs/cm_t335_defconfig|   1 +
 configs/nokia_rx51_defconfig |   1 +
 drivers/bus/Kconfig  |   7 ++
 drivers/bus/Makefile |   1 +
 drivers/bus/ti-sysc.c| 166 +++
 6 files changed, 177 insertions(+)
 create mode 100644 drivers/bus/ti-sysc.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index fbe90875ae..6f039f7909 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -799,6 +799,7 @@ config ARCH_OMAP2PLUS
select SPL_BOARD_INIT if SPL
select SPL_STACK_R if SPL
select SUPPORT_SPL
+   imply TI_SYSC
imply FIT
 
 config ARCH_MESON
diff --git a/configs/cm_t335_defconfig b/configs/cm_t335_defconfig
index 3112915dc1..c4fd56b673 100644
--- a/configs/cm_t335_defconfig
+++ b/configs/cm_t335_defconfig
@@ -1,6 +1,7 @@
 CONFIG_ARM=y
 CONFIG_ARCH_CPU_INIT=y
 CONFIG_ARCH_OMAP2PLUS=y
+# CONFIG_TI_SYSC is not set
 CONFIG_SPL_GPIO_SUPPORT=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
diff --git a/configs/nokia_rx51_defconfig b/configs/nokia_rx51_defconfig
index d0c8929525..30a02e2bc3 100644
--- a/configs/nokia_rx51_defconfig
+++ b/configs/nokia_rx51_defconfig
@@ -4,6 +4,7 @@ CONFIG_ARCH_OMAP2PLUS=y
 CONFIG_SYS_TEXT_BASE=0x80008000
 CONFIG_NR_DRAM_BANKS=2
 CONFIG_TARGET_NOKIA_RX51=y
+# CONFIG_TI_SYSC is not set
 # CONFIG_FIT is not set
 CONFIG_BOOTDELAY=30
 CONFIG_AUTOBOOT_KEYED=y
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index 07a33c6287..733bec5a56 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -5,6 +5,13 @@
 
 menu "Bus devices"
 
+config TI_SYSC
+   bool "TI sysc interconnect target module driver"
+   depends on ARCH_OMAP2PLUS
+   help
+ Generic driver for Texas Instruments interconnect target module
+ found on many TI SoCs.
+
 config UNIPHIER_SYSTEM_BUS
bool "UniPhier System Bus driver"
depends on ARCH_UNIPHIER
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 0b97fc1f8b..875bb4ed42 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -3,4 +3,5 @@
 # Makefile for the bus drivers.
 #
 
+obj-$(CONFIG_TI_SYSC)  += ti-sysc.o
 obj-$(CONFIG_UNIPHIER_SYSTEM_BUS) += uniphier-system-bus.o
diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
new file mode 100644
index 00..65974a70a6
--- /dev/null
+++ b/drivers/bus/ti-sysc.c
@@ -0,0 +1,166 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Texas Instruments sysc interconnect target driver
+ *
+ * Copyright (C) 2020 Dario Binacchi 
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+enum ti_sysc_clocks {
+   TI_SYSC_FCK,
+   TI_SYSC_ICK,
+   TI_SYSC_MAX_CLOCKS,
+};
+
+static const char *const clock_names[] = {"fck", "ick"};
+
+struct ti_sysc_priv {
+   int clocks_count;
+   struct clk clocks[TI_SYSC_MAX_CLOCKS];
+};
+
+static const struct udevice_id ti_sysc_ids[] = {
+   {.compatible = "ti,sysc-omap2"},
+   {.compatible = "ti,sysc-omap4"},
+   {.compatible = "ti,sysc-omap4-simple"},
+   {.compatible = "ti,sysc-omap3430-sr"},
+   {.compatible = "ti,sysc-omap3630-sr"},
+   {.compatible = "ti,sysc-omap4-sr"},
+   {.compatible = "ti,sysc-omap3-sham"},
+   {.compatible = "ti,sysc-omap-aes"},
+   {.compatible = "ti,sysc-mcasp"},
+   {.compatible = "ti,sysc-usb-host-fs"},
+   {}
+};
+
+static int ti_sysc_get_one_clock(struct udevice *dev, enum ti_sysc_clocks 
index)
+{
+   struct ti_sysc_priv *priv = dev_get_priv(dev);
+   const char *name;
+   int err;
+
+   switch (index) {
+   case TI_SYSC_FCK:
+   break;
+   case TI_SYSC_ICK:
+   break;
+   default:
+   return -EINVAL;
+   }
+
+   name = clock_names[index];
+
+   err = clk_get_by_name(dev, name, >clocks[index]);
+   if (err) {
+   if (err == -ENODATA)
+   return 0;
+
+   dev_err(dev, "failed to get %s clock\n", name);
+   return err;
+   }
+
+   return 0;
+}
+
+static int ti_sysc_put_clocks(struct udevice *dev)
+{
+   struct ti_sysc_priv *priv = dev_get_priv(dev);
+   int err;
+
+   err = clk_release_all(priv->clocks, priv->clocks_count);
+   if (err)
+   dev_err(dev, "failed to release all clocks\n");
+
+   return err;
+}
+

[PATCH v7 05/28] clk: add clk_round_rate()

2020-12-23 Thread Dario Binacchi
It returns the rate which will be set if you ask clk_set_rate() to set
that rate. It provides a way to query exactly what rate you'll get if
you call clk_set_rate() with that same argument.
So essentially, clk_round_rate() and clk_set_rate() are equivalent
except the former does not modify the clock hardware in any way.

Signed-off-by: Dario Binacchi 
Reviewed-by: Simon Glass 
Reviewed-by: Sean Anderson 

---

(no changes since v4)

Changes in v4:
- Update clk_round_rate description.
- Add Sean Anderson review.

 arch/sandbox/include/asm/clk.h |  9 +
 drivers/clk/clk-uclass.c   | 15 +++
 drivers/clk/clk_sandbox.c  | 17 +
 drivers/clk/clk_sandbox_test.c | 10 ++
 include/clk-uclass.h   |  8 
 include/clk.h  | 28 
 test/dm/clk.c  | 22 ++
 7 files changed, 109 insertions(+)

diff --git a/arch/sandbox/include/asm/clk.h b/arch/sandbox/include/asm/clk.h
index c184c4bffc..0294baee27 100644
--- a/arch/sandbox/include/asm/clk.h
+++ b/arch/sandbox/include/asm/clk.h
@@ -105,6 +105,15 @@ int sandbox_clk_test_get_bulk(struct udevice *dev);
  * @return:The rate of the clock.
  */
 ulong sandbox_clk_test_get_rate(struct udevice *dev, int id);
+/**
+ * sandbox_clk_test_round_rate - Ask the sandbox clock test device to round a
+ * clock's rate.
+ *
+ * @dev:   The sandbox clock test (client) device.
+ * @id:The test device's clock ID to configure.
+ * @return:The rounded rate of the clock.
+ */
+ulong sandbox_clk_test_round_rate(struct udevice *dev, int id, ulong rate);
 /**
  * sandbox_clk_test_set_rate - Ask the sandbox clock test device to set a
  * clock's rate.
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index ac954a34d2..3b8e27e4a5 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -523,6 +523,21 @@ long long clk_get_parent_rate(struct clk *clk)
return pclk->rate;
 }
 
+ulong clk_round_rate(struct clk *clk, ulong rate)
+{
+   const struct clk_ops *ops;
+
+   debug("%s(clk=%p, rate=%lu)\n", __func__, clk, rate);
+   if (!clk_valid(clk))
+   return 0;
+
+   ops = clk_dev_ops(clk->dev);
+   if (!ops->round_rate)
+   return -ENOSYS;
+
+   return ops->round_rate(clk, rate);
+}
+
 ulong clk_set_rate(struct clk *clk, ulong rate)
 {
const struct clk_ops *ops;
diff --git a/drivers/clk/clk_sandbox.c b/drivers/clk/clk_sandbox.c
index 0ff1b49633..0751e923e7 100644
--- a/drivers/clk/clk_sandbox.c
+++ b/drivers/clk/clk_sandbox.c
@@ -30,6 +30,22 @@ static ulong sandbox_clk_get_rate(struct clk *clk)
return priv->rate[clk->id];
 }
 
+static ulong sandbox_clk_round_rate(struct clk *clk, ulong rate)
+{
+   struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
+
+   if (!priv->probed)
+   return -ENODEV;
+
+   if (clk->id >= SANDBOX_CLK_ID_COUNT)
+   return -EINVAL;
+
+   if (!rate)
+   return -EINVAL;
+
+   return rate;
+}
+
 static ulong sandbox_clk_set_rate(struct clk *clk, ulong rate)
 {
struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
@@ -103,6 +119,7 @@ static int sandbox_clk_free(struct clk *clk)
 }
 
 static struct clk_ops sandbox_clk_ops = {
+   .round_rate = sandbox_clk_round_rate,
.get_rate   = sandbox_clk_get_rate,
.set_rate   = sandbox_clk_set_rate,
.enable = sandbox_clk_enable,
diff --git a/drivers/clk/clk_sandbox_test.c b/drivers/clk/clk_sandbox_test.c
index 873383856f..f7b77aa674 100644
--- a/drivers/clk/clk_sandbox_test.c
+++ b/drivers/clk/clk_sandbox_test.c
@@ -86,6 +86,16 @@ ulong sandbox_clk_test_get_rate(struct udevice *dev, int id)
return clk_get_rate(sbct->clkps[id]);
 }
 
+ulong sandbox_clk_test_round_rate(struct udevice *dev, int id, ulong rate)
+{
+   struct sandbox_clk_test *sbct = dev_get_priv(dev);
+
+   if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT)
+   return -EINVAL;
+
+   return clk_round_rate(sbct->clkps[id], rate);
+}
+
 ulong sandbox_clk_test_set_rate(struct udevice *dev, int id, ulong rate)
 {
struct sandbox_clk_test *sbct = dev_get_priv(dev);
diff --git a/include/clk-uclass.h b/include/clk-uclass.h
index dac42dab36..50e8681b55 100644
--- a/include/clk-uclass.h
+++ b/include/clk-uclass.h
@@ -61,6 +61,14 @@ struct clk_ops {
 * @return 0 if OK, or a negative error code.
 */
int (*rfree)(struct clk *clock);
+   /**
+* round_rate() - Adjust a rate to the exact rate a clock can provide.
+*
+* @clk:The clock to manipulate.
+* @rate:   Desidered clock rate in Hz.
+* @return rounded rate in Hz, or -ve error code.
+*/
+   ulong (*round_rate)(struct clk *clk, ulong rate);
/**
 * get_rate() - Get current clock rate.
 *
diff --git a/include/clk.h 

[PATCH v7 07/28] arm: ti: am33xx: add DPLL_EN_FAST_RELOCK_BYPASS macro

2020-12-23 Thread Dario Binacchi
Add missing DPLL_EN_FAST_RELOCK_BYPASS macro. Used to put the DPLL in
idle bypass fast relock mode.

Signed-off-by: Dario Binacchi 
---

(no changes since v1)

 arch/arm/include/asm/arch-am33xx/clock.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/include/asm/arch-am33xx/clock.h 
b/arch/arm/include/asm/arch-am33xx/clock.h
index dc7a9b188d..5d775902bb 100644
--- a/arch/arm/include/asm/arch-am33xx/clock.h
+++ b/arch/arm/include/asm/arch-am33xx/clock.h
@@ -66,6 +66,7 @@
 #define DPLL_EN_STOP   1
 #define DPLL_EN_MN_BYPASS  4
 #define DPLL_EN_LOW_POWER_BYPASS   5
+#define DPLL_EN_FAST_RELOCK_BYPASS 6
 #define DPLL_EN_LOCK   7
 
 /* CM_IDLEST_DPLL fields */
-- 
2.17.1



[PATCH v7 02/28] dt-bindings: bus: ti-sysc: resync with Linux 5.9-rc7

2020-12-23 Thread Dario Binacchi
Add support for PRUSS SYSC type:
The PRUSS module has a SYSCFG which is unique. The SYSCFG has two
additional unique fields called STANDBY_INIT and SUB_MWAIT in addition
to regular IDLE_MODE and STANDBY_MODE fields. Add the bindings for this
new sysc type.

Add support for MCAN on dra76x:
The dra76x MCAN generic interconnect module has a its own format for the
bits in the control registers.

Signed-off-by: Dario Binacchi 
---

(no changes since v1)

 include/dt-bindings/bus/ti-sysc.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/include/dt-bindings/bus/ti-sysc.h 
b/include/dt-bindings/bus/ti-sysc.h
index 2c005376ac..eae4274543 100644
--- a/include/dt-bindings/bus/ti-sysc.h
+++ b/include/dt-bindings/bus/ti-sysc.h
@@ -15,6 +15,12 @@
 /* SmartReflex sysc found on 36xx and later */
 #define SYSC_OMAP3_SR_ENAWAKEUP(1 << 26)
 
+#define SYSC_DRA7_MCAN_ENAWAKEUP   (1 << 4)
+
+/* PRUSS sysc found on AM33xx/AM43xx/AM57xx */
+#define SYSC_PRUSS_SUB_MWAIT   (1 << 5)
+#define SYSC_PRUSS_STANDBY_INIT(1 << 4)
+
 /* SYSCONFIG STANDBYMODE/MIDLEMODE/SIDLEMODE supported by hardware */
 #define SYSC_IDLE_FORCE0
 #define SYSC_IDLE_NO   1
-- 
2.17.1



[PATCH v7 01/28] clk: export generic routines

2020-12-23 Thread Dario Binacchi
Export routines that can be used by other drivers avoiding duplicating
code.

Signed-off-by: Dario Binacchi 
Reviewed-by: Simon Glass 

---

(no changes since v2)

Changes in v2:
- Add the clk_ prefix to the divider functions.
- Add kernel-doc comments to the exported functions.

 drivers/clk/clk-divider.c| 24 +++
 include/linux/clk-provider.h | 57 
 2 files changed, 69 insertions(+), 12 deletions(-)

diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index 8f59d7fb72..9df50a5e72 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -28,8 +28,8 @@
 
 #define UBOOT_DM_CLK_CCF_DIVIDER "ccf_clk_divider"
 
-static unsigned int _get_table_div(const struct clk_div_table *table,
-  unsigned int val)
+unsigned int clk_divider_get_table_div(const struct clk_div_table *table,
+  unsigned int val)
 {
const struct clk_div_table *clkt;
 
@@ -49,7 +49,7 @@ static unsigned int _get_div(const struct clk_div_table 
*table,
if (flags & CLK_DIVIDER_MAX_AT_ZERO)
return val ? val : clk_div_mask(width) + 1;
if (table)
-   return _get_table_div(table, val);
+   return clk_divider_get_table_div(table, val);
return val + 1;
 }
 
@@ -89,8 +89,8 @@ static ulong clk_divider_recalc_rate(struct clk *clk)
   divider->flags, divider->width);
 }
 
-static bool _is_valid_table_div(const struct clk_div_table *table,
-   unsigned int div)
+bool clk_divider_is_valid_table_div(const struct clk_div_table *table,
+   unsigned int div)
 {
const struct clk_div_table *clkt;
 
@@ -100,18 +100,18 @@ static bool _is_valid_table_div(const struct 
clk_div_table *table,
return false;
 }
 
-static bool _is_valid_div(const struct clk_div_table *table, unsigned int div,
- unsigned long flags)
+bool clk_divider_is_valid_div(const struct clk_div_table *table,
+ unsigned int div, unsigned long flags)
 {
if (flags & CLK_DIVIDER_POWER_OF_TWO)
return is_power_of_2(div);
if (table)
-   return _is_valid_table_div(table, div);
+   return clk_divider_is_valid_table_div(table, div);
return true;
 }
 
-static unsigned int _get_table_val(const struct clk_div_table *table,
-  unsigned int div)
+unsigned int clk_divider_get_table_val(const struct clk_div_table *table,
+  unsigned int div)
 {
const struct clk_div_table *clkt;
 
@@ -131,7 +131,7 @@ static unsigned int _get_val(const struct clk_div_table 
*table,
if (flags & CLK_DIVIDER_MAX_AT_ZERO)
return (div == clk_div_mask(width) + 1) ? 0 : div;
if (table)
-   return  _get_table_val(table, div);
+   return clk_divider_get_table_val(table, div);
return div - 1;
 }
 int divider_get_val(unsigned long rate, unsigned long parent_rate,
@@ -142,7 +142,7 @@ int divider_get_val(unsigned long rate, unsigned long 
parent_rate,
 
div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
 
-   if (!_is_valid_div(table, div, flags))
+   if (!clk_divider_is_valid_div(table, div, flags))
return -EINVAL;
 
value = _get_val(table, div, flags, width);
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 79dce8f0ad..a94539037a 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -76,6 +76,19 @@ struct clk_mux {
 extern const struct clk_ops clk_mux_ops;
 u8 clk_mux_get_parent(struct clk *clk);
 
+/**
+ * clk_mux_index_to_val() - Convert the parent index to the register value
+ *
+ * It returns the value to write in the hardware register to output the 
selected
+ * input clock parent.
+ *
+ * @table: array of register values corresponding to the parent index 
(optional)
+ * @flags: hardware-specific flags
+ * @index: parent clock index
+ * @return the register value
+ */
+unsigned int clk_mux_index_to_val(u32 *table, unsigned int flags, u8 index);
+
 struct clk_gate {
struct clk  clk;
void __iomem*reg;
@@ -125,6 +138,50 @@ struct clk_divider {
 #define CLK_DIVIDER_READ_ONLY  BIT(5)
 #define CLK_DIVIDER_MAX_AT_ZEROBIT(6)
 extern const struct clk_ops clk_divider_ops;
+
+/**
+ * clk_divider_get_table_div() - convert the register value to the divider
+ *
+ * @table:  array of register values corresponding to valid dividers
+ * @val: value to convert
+ * @return the divider
+ */
+unsigned int clk_divider_get_table_div(const struct clk_div_table *table,
+  unsigned int val);
+
+/**
+ * clk_divider_get_table_val() - convert the divider to the register value
+ *
+ * It returns the value to write in the 

RE: [v6 10/18] net: designware: socfpga: Add ATF support for MAC driver

2020-12-23 Thread Tan, Ley Foon



> -Original Message-
> From: Lim, Elly Siew Chin 
> Sent: Wednesday, December 23, 2020 10:56 PM
> To: u-boot@lists.denx.de
> Cc: Marek Vasut ; Tan, Ley Foon
> ; See, Chin Liang ;
> Simon Goldschmidt ; Chee, Tien Fong
> ; Westergreen, Dalon
> ; Simon Glass ; Gan,
> Yau Wai ; Ang, Chee Hong
> ; Lim, Elly Siew Chin
> 
> Subject: [v6 10/18] net: designware: socfpga: Add ATF support for MAC
> driver
> 
> From: Chee Hong Ang 
> 
> In non-secure mode (EL2), MAC driver calls the SMC/PSCI services provided
> by ATF to setup the PHY interface.
> 
> Signed-off-by: Chee Hong Ang 
> Signed-off-by: Siew Chin Lim 
> 
> ---
> v5
> ---
> Call secure register access helper function to write the secure register.
> Return error if fail to write the PHY related secure register.
> 
> ---
> v6
> ---
> Clean up the code and use socfpga_secure_reg_update32 to update PHY
> related secure registers.

Reviewed-by: Ley Foon Tan 



RE: [v6 07/18] arm: socfpga: Add secure register access helper functions for SoC 64bits

2020-12-23 Thread Tan, Ley Foon



> -Original Message-
> From: Lim, Elly Siew Chin 
> Sent: Wednesday, December 23, 2020 10:56 PM
> To: u-boot@lists.denx.de
> Cc: Marek Vasut ; Tan, Ley Foon
> ; See, Chin Liang ;
> Simon Goldschmidt ; Chee, Tien Fong
> ; Westergreen, Dalon
> ; Simon Glass ; Gan,
> Yau Wai ; Lim, Elly Siew Chin
> 
> Subject: [v6 07/18] arm: socfpga: Add secure register access helper functions
> for SoC 64bits
> 
> These secure register access functions allow U-Boot proper running at EL2
> (non-secure) to access System Manager's secure registers by calling the ATF's
> PSCI runtime services (EL3/secure).
> 
> Signed-off-by: Siew Chin Lim 
> 
> ---
> v5
> ---
> Return error code instead of hang the system if fail to access the secure
> register.
> 
> ---
> v6
> ---
> Directly return 'ret' after SMC call in write and update function.
> ---
>  arch/arm/mach-socfpga/Makefile |  1 +
>  .../mach-socfpga/include/mach/secure_reg_helper.h  | 19 +
>  arch/arm/mach-socfpga/secure_reg_helper.c  | 91
> ++
>  3 files changed, 111 insertions(+)
>  create mode 100644 arch/arm/mach-
> socfpga/include/mach/secure_reg_helper.h
>  create mode 100644 arch/arm/mach-socfpga/secure_reg_helper.c
> 
> diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-
> socfpga/Makefile index 0b05283a7a..82b681d870 100644
> --- a/arch/arm/mach-socfpga/Makefile
> +++ b/arch/arm/mach-socfpga/Makefile
> @@ -73,6 +73,7 @@ obj-y   += firewall.o
>  obj-y+= spl_agilex.o
>  endif
>  else
> +obj-$(CONFIG_SPL_ATF) += secure_reg_helper.o
>  obj-$(CONFIG_SPL_ATF) += smc_api.o
>  endif
> 
> diff --git a/arch/arm/mach-socfpga/include/mach/secure_reg_helper.h
> b/arch/arm/mach-socfpga/include/mach/secure_reg_helper.h
> new file mode 100644
> index 00..d5a11122c7
> --- /dev/null
> +++ b/arch/arm/mach-socfpga/include/mach/secure_reg_helper.h
> @@ -0,0 +1,19 @@
> +/* SPDX-License-Identifier: GPL-2.0
> + *
> + * Copyright (C) 2020 Intel Corporation 
> + *
> + */
> +
> +#ifndef  _SECURE_REG_HELPER_H_
> +#define  _SECURE_REG_HELPER_H_
> +
> +#define SOCFPGA_SECURE_REG_SYSMGR_SOC64_SDMMC 1 #define
> +SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC0 2 #define
> +SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC1 3 #define
> +SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC2 4
> +
> +int socfpga_secure_reg_read32(u32 id, u32 *val); int
> +socfpga_secure_reg_write32(u32 id, u32 val); int
> +socfpga_secure_reg_update32(u32 id, u32 mask, u32 val);
> +
> +#endif /* _SECURE_REG_HELPER_H_ */
> diff --git a/arch/arm/mach-socfpga/secure_reg_helper.c b/arch/arm/mach-
> socfpga/secure_reg_helper.c
> new file mode 100644
> index 00..816006cb5a
> --- /dev/null
> +++ b/arch/arm/mach-socfpga/secure_reg_helper.c
> @@ -0,0 +1,91 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2020 Intel Corporation 
> + *
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include  #include 
> +#include  #include  #include
> +
> +
> +int socfpga_secure_convert_reg_id_to_addr(u32 id, phys_addr_t
> +*reg_addr) {
> + switch (id) {
> + case SOCFPGA_SECURE_REG_SYSMGR_SOC64_SDMMC:
> + *reg_addr = socfpga_get_sysmgr_addr() +
> SYSMGR_SOC64_SDMMC;
> + break;
> + case SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC0:
> + *reg_addr = socfpga_get_sysmgr_addr() +
> SYSMGR_SOC64_EMAC0;
> + break;
> + case SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC1:
> + *reg_addr = socfpga_get_sysmgr_addr() +
> SYSMGR_SOC64_EMAC1;
> + break;
> + case SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC2:
> + *reg_addr = socfpga_get_sysmgr_addr() +
> SYSMGR_SOC64_EMAC2;
> + break;
> + default:
> + return -EADDRNOTAVAIL;
> + }
> + return 0;
> +}
> +
> +int socfpga_secure_reg_read32(u32 id, u32 *val) {
> + int ret;
> + u64 ret_arg;
> + u64 args[1];
> +
> + phys_addr_t reg_addr;
> + ret = socfpga_secure_convert_reg_id_to_addr(id, _addr);
> + if (ret)
> + return ret;
> +
> + args[0] = (u64)reg_addr;
> + ret = invoke_smc(INTEL_SIP_SMC_REG_READ, args, 1, _arg, 1);
> + if (ret)
> + return ret;
> +
> + *val = (u32)ret_arg;
> +
> + return 0;
> +}
> +
> +int socfpga_secure_reg_write32(u32 id, u32 val) {
> + int ret;
> + u64 args[2];
> +
> + phys_addr_t reg_addr;
> + ret = socfpga_secure_convert_reg_id_to_addr(id, _addr);
> + if (ret)
> + return ret;
> +
> + args[0] = (u64)reg_addr;
> + args[1] = val;
> + ret = invoke_smc(INTEL_SIP_SMC_REG_WRITE, args, 2, NULL, 0);
> + return ret;
Can simplify code to:

return invoke_smc(INTEL_SIP_SMC_REG_WRITE, args, 2, NULL, 0);
> +
> +int socfpga_secure_reg_update32(u32 id, u32 mask, u32 val) {
> + int ret;
> + u64 args[3];
> +
> + phys_addr_t reg_addr;
> + ret = socfpga_secure_convert_reg_id_to_addr(id, _addr);
> + if (ret)
> + return ret;
> +
> + 

Re: Please pull u-boot-x86

2020-12-23 Thread Tom Rini
On Tue, Dec 22, 2020 at 03:27:49PM +0800, Bin Meng wrote:

> Hi Tom,
> 
> This PR includes the following changes for v2021.01 release:
> 
> - Update Intel Edison doc information about xFSTK
> - Move and rename fsp_types.h file to signatures.h
> 
> Azure results: PASS
> https://dev.azure.com/bmeng/GitHub/_build/results?buildId=304=results
> 
> The following changes since commit c15f44acf9d473f4682bfdc63b8aebd313492b15:
> 
>   Prepare v2021.01-rc4 (2020-12-21 15:03:24 -0500)
> 
> are available in the git repository at:
> 
>   https://gitlab.denx.de/u-boot/custodians/u-boot-x86
> 
> for you to fetch changes up to 6ef1b7508740dfce9b30f172839b385361e8bd50:
> 
>   fsp: Move and rename fsp_types.h file (2020-12-22 10:19:40 +0800)
> 

Applied to u-boot/master, thanks!

-- 
Tom


signature.asc
Description: PGP signature


[PATCH] cmd: mmc: add mmcboot command

2020-12-23 Thread Ravik Hasija
Similar to usbboot, add command line to boot from raw mmc partition
using common_diskboot(), which supports legacy or FIT images.

Usage:
mmcboot loadAaddr dev:part

Where  defaults to CONFIG_SYS_LOAD_ADDR, and 
defaults to ${bootdevice}.

Also fixing config macro usage for CONFIG_SUPPORT_EMMC_BOOT (suggested
by checkpatch.pl).

Signed-off-by: Ravik Hasija 
Signed-off-by: Dhananjay Phadke 
---
 cmd/mmc.c | 22 +++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/cmd/mmc.c b/cmd/mmc.c
index 1529a3e05d..4d134e35a1 100644
--- a/cmd/mmc.c
+++ b/cmd/mmc.c
@@ -711,7 +711,7 @@ static int do_mmc_hwpartition(struct cmd_tbl *cmdtp, int 
flag,
 }
 #endif
 
-#ifdef CONFIG_SUPPORT_EMMC_BOOT
+#if CONFIG_IS_ENABLED(SUPPORT_EMMC_BOOT)
 static int do_mmc_bootbus(struct cmd_tbl *cmdtp, int flag,
  int argc, char *const argv[])
 {
@@ -950,7 +950,7 @@ static struct cmd_tbl cmd_mmc[] = {
 #if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
U_BOOT_CMD_MKENT(hwpartition, 28, 0, do_mmc_hwpartition, "", ""),
 #endif
-#ifdef CONFIG_SUPPORT_EMMC_BOOT
+#if CONFIG_IS_ENABLED(SUPPORT_EMMC_BOOT)
U_BOOT_CMD_MKENT(bootbus, 5, 0, do_mmc_bootbus, "", ""),
U_BOOT_CMD_MKENT(bootpart-resize, 4, 0, do_mmc_boot_resize, "", ""),
U_BOOT_CMD_MKENT(partconf, 5, 0, do_mmc_partconf, "", ""),
@@ -992,6 +992,14 @@ static int do_mmcops(struct cmd_tbl *cmdtp, int flag, int 
argc,
return cp->cmd(cmdtp, flag, argc, argv);
 }
 
+#if CONFIG_IS_ENABLED(SUPPORT_EMMC_BOOT)
+static int do_mmcboot(cmd_tbl_t *cmdtp, int flag, int argc,
+   char *const argv[])
+{
+   return common_diskboot(cmdtp, "mmc", argc, argv);
+}
+#endif
+
 U_BOOT_CMD(
mmc, 29, 1, do_mmcops,
"MMC sub system",
@@ -1016,7 +1024,7 @@ U_BOOT_CMD(
"  WARNING: Partitioning is a write-once setting once it is set to 
complete.\n"
"  Power cycling is required to initialize partitions after set to 
complete.\n"
 #endif
-#ifdef CONFIG_SUPPORT_EMMC_BOOT
+#if CONFIG_IS_ENABLED(SUPPORT_EMMC_BOOT)
"mmc bootbus dev boot_bus_width reset_boot_bus_width boot_mode\n"
" - Set the BOOT_BUS_WIDTH field of the specified device\n"
"mmc bootpart-resize   \n"
@@ -1046,3 +1054,11 @@ U_BOOT_CMD(
"display MMC info",
"- display info of the current MMC device"
 );
+
+#if CONFIG_IS_ENABLED(SUPPORT_EMMC_BOOT)
+U_BOOT_CMD(
+   mmcboot, 3, 1, do_mmcboot,
+   "boot from eMMC",
+   "loadAddr dev:part"
+);
+#endif
-- 
2.17.1



Please pull u-boot-dm/next into -next

2020-12-23 Thread Simon Glass
Hi Tom,

This is for the -next branch,

Build here:

https://gitlab.denx.de/u-boot/custodians/u-boot-dm/-/pipelines/5664


The following changes since commit 8351a29d2df18c92d8e365cfa848218c3859f3d2:

  Merge tag 'dm-pull-14dec20' of git://git.denx.de/u-boot-dm into next
(2020-12-14 18:57:57 -0500)

are available in the Git repository at:

  git://git.denx.de/u-boot-dm.git tags/dm-next-23dec20

for you to fetch changes up to ec1add1e51affd4aacc308dc37439ea13dc1b70e:

  dm: core: Inline a few ofnode functions in SPL (2020-12-22 20:39:26 -0700)


dm: New sequence number implementation
SPI handling of bus with different-speed devices
patman supression of sign-offs


Aswath Govindraju (1):
  fdt: Use phandle to distinguish DT nodes with same name

Heinrich Schuchardt (2):
  sandbox: implement runtime system reset
  sandbox: implement invalidate_icache_all()

Hongwei Zhang (1):
  Common:fdt: Check for error return value

Niel Fourie (1):
  dm: spi: Fix spi_free_slave() freed memory write

Ovidiu Panait (6):
  sandbox: spi: Drop unused sandbox_spi_parse_spec function
  sandbox: test: Add a second SPI slave on sandbox_spi bus
  spi: sandbox_spi: Implement speed/mode setup
  test: spi: Add sandbox_spi_get_{speed, mode} interface
  spi: spi-uclass: Fix spi_claim_bus() speed/mode setup logic
  test: dm: spi: Add testcase for spi_claim_bus()

Patrick Delaunay (1):
  configs: sandbox: activate DEBUG_UART

Philipp Tomsich (2):
  patman: Add --no-signoff to suppress adding signoffs
  patman: Add project-default for 'gcc'

Simon Glass (30):
  linker_lists: Fix alignment issue
  dm: Avoid accessing seq directly
  dm: core: Update uclass_find_next_free_req_seq() args
  dm: core: Add a new sequence number for devices
  dm: test: Check all devices have a sequence numbers
  dm: core: Switch binding to use new sequence numbers
  dm: Fix return value in dev_read_alias_seq()
  dm: test: Drop assumptions of no sequence numbers
  octeon: Don't attempt to set the sequence number
  i2c: Update for new sequence numbers
  net: Update to use new sequence numbers
  dm: core: Allow manual sequence numbering
  pci: Update to use new sequence numbers
  spi: Update for new sequence numbers
  usb: ehci-mx6: Drop assignment of sequence number
  usb: Update for new sequence numbers
  x86: Drop unnecessary mp_init logic
  x86: Simplify acpi_device_infer_name()
  gpio: Update for new sequence numbers
  pinctrl: Update for new sequence numbers
  dm: Switch over to use new sequence number for dev_seq()
  dm: test: Add a test for DM_UC_FLAG_NO_AUTO_SEQ
  dm: Drop uclass_resolve_seq()
  dm: Drop the unused arg in uclass_find_device_by_seq()
  dm: core: Update uclass_find_next_free_req_seq() for new scheme
  cmd: Drop use of old sequence numbers in commands
  dm: core: Drop seq and req_seq
  dm: Update documentation for new sequence numbers
  buildman: Remove output binaries before building
  dm: core: Inline a few ofnode functions in SPL

 arch/Kconfig |  11 +++
 arch/arm/include/asm/mach-imx/mxc_i2c.h  |   2 +-
 arch/arm/mach-k3/am6_init.c  |   2 +-
 arch/arm/mach-k3/j721e_init.c|   2 +-
 arch/arm/mach-k3/sysfw-loader.c  |   2 +-
 arch/sandbox/cpu/Makefile|   2 +-
 arch/sandbox/cpu/cache.c |  23 ++
 arch/sandbox/cpu/start.c |  10 +++
 arch/sandbox/dts/test.dts|  25 +-
 arch/sandbox/include/asm/spi.h   |  10 ---
 arch/sandbox/include/asm/test.h  |  16 
 arch/x86/cpu/apollolake/cpu.c|   2 +-
 arch/x86/cpu/broadwell/cpu_full.c|   2 +-
 arch/x86/cpu/ivybridge/model_206ax.c |   2 +-
 arch/x86/cpu/mp_init.c   |  23 ++
 arch/x86/include/asm/mp.h|   2 +-
 board/sandbox/sandbox.c  |   4 -
 board/xilinx/versal/board.c  |  12 +--
 board/xilinx/zynqmp/zynqmp.c |  12 +--
 cmd/axi.c|   6 +-
 cmd/cpu.c|   2 +-
 cmd/i2c.c|   6 +-
 cmd/misc.c   |   2 +-
 cmd/osd.c|   6 +-
 cmd/pci.c|   7 +-
 cmd/pmic.c   |   4 +-
 cmd/remoteproc.c |   2 +-
 cmd/w1.c |   4 +-
 common/image-fdt.c   |   3 +
 configs/sandbox64_defconfig  |   1 +
 configs/sandbox_flattree_defconfig   |   1 +
 configs/sandbox_spl_defconfig|   1 +
 doc/api/linker_lists.rst |  59 +++
 doc/driver-model/design.rst

[PATCH v5 12/13] configs: rpi4: Enable DM_DMA across all RPi4 configurations

2020-12-23 Thread Nicolas Saenz Julienne
The DM_DMA option is needed in order to translate physical address into
bus addresses on a per-device basis.

Signed-off-by: Nicolas Saenz Julienne 
Reviewed-by: Simon Glass 
---
 configs/rpi_4_32b_defconfig | 1 +
 configs/rpi_4_defconfig | 1 +
 configs/rpi_arm64_defconfig | 1 +
 3 files changed, 3 insertions(+)

diff --git a/configs/rpi_4_32b_defconfig b/configs/rpi_4_32b_defconfig
index 5ddd838fd5..0a5d3ff8cd 100644
--- a/configs/rpi_4_32b_defconfig
+++ b/configs/rpi_4_32b_defconfig
@@ -22,6 +22,7 @@ CONFIG_OF_BOARD=y
 CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_DM_DMA=y
 CONFIG_DFU_MMC=y
 CONFIG_DM_KEYBOARD=y
 CONFIG_DM_MMC=y
diff --git a/configs/rpi_4_defconfig b/configs/rpi_4_defconfig
index 2590d0a696..b61cdc05f1 100644
--- a/configs/rpi_4_defconfig
+++ b/configs/rpi_4_defconfig
@@ -22,6 +22,7 @@ CONFIG_OF_BOARD=y
 CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_DM_DMA=y
 CONFIG_DFU_MMC=y
 CONFIG_DM_KEYBOARD=y
 CONFIG_DM_MMC=y
diff --git a/configs/rpi_arm64_defconfig b/configs/rpi_arm64_defconfig
index 2639219a1a..4125a1feba 100644
--- a/configs/rpi_arm64_defconfig
+++ b/configs/rpi_arm64_defconfig
@@ -20,6 +20,7 @@ CONFIG_CMD_FS_UUID=y
 CONFIG_OF_BOARD=y
 CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_DM_DMA=y
 CONFIG_DM_KEYBOARD=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_SDHCI=y
-- 
2.29.2



[PATCH v5 13/13] video: arm: rpi: Add brcm,bcm2711-hdmi0 compatible

2020-12-23 Thread Nicolas Saenz Julienne
The 'brcm,bcm2711-hdmi0' compatible string is used on RPi4 instead of
'brcm,bcm2835-hdmi' since the IP core was upgraded (now called VC6
instead of VC4). This has no functional change as far as u-boot driver
is concerned. So simply add the compatible string.

Signed-off-by: Nicolas Saenz Julienne 

---
Changes since v3:
 - Add this patch

 drivers/video/bcm2835.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/video/bcm2835.c b/drivers/video/bcm2835.c
index 0888cb0019..51941c4f53 100644
--- a/drivers/video/bcm2835.c
+++ b/drivers/video/bcm2835.c
@@ -52,6 +52,7 @@ 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" },
{ }
 };
-- 
2.29.2



[PATCH v5 11/13] mmc: Introduce mmc_phys_to_bus()/mmc_bus_to_phys()

2020-12-23 Thread Nicolas Saenz Julienne
This will allow us to use DM variants of phys_to_bus()/bus_to_phys()
when relevant.

Signed-off-by: Nicolas Saenz Julienne 
Reviewed-by: Simon Glass 

---
Changes since v4:
 - Introduce mmc->dev access macros to avoid ifdefs
 - No need to create mmc_phys_to_bus()

Changes since v3:
 - Don't call phys_to_bus()/bus_to_phys(), we only support DM

 drivers/mmc/sdhci.c | 12 +++-
 include/mmc.h   |  6 ++
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 0628934312..62e4f53b8b 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -14,12 +14,12 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
-#include 
 
 static void sdhci_reset(struct sdhci_host *host, u8 mask)
 {
@@ -73,6 +73,7 @@ static void sdhci_transfer_pio(struct sdhci_host *host, 
struct mmc_data *data)
 static void sdhci_prepare_dma(struct sdhci_host *host, struct mmc_data *data,
  int *is_aligned, int trans_bytes)
 {
+   dma_addr_t dma_addr;
unsigned char ctrl;
void *buf;
 
@@ -103,8 +104,8 @@ static void sdhci_prepare_dma(struct sdhci_host *host, 
struct mmc_data *data,
  mmc_get_dma_dir(data));
 
if (host->flags & USE_SDMA) {
-   sdhci_writel(host, phys_to_bus((ulong)host->start_addr),
-   SDHCI_DMA_ADDRESS);
+   dma_addr = dev_phys_to_bus(mmc_to_dev(host->mmc), 
host->start_addr);
+   sdhci_writel(host, dma_addr, SDHCI_DMA_ADDRESS);
}
 #if CONFIG_IS_ENABLED(MMC_SDHCI_ADMA)
else if (host->flags & (USE_ADMA | USE_ADMA64)) {
@@ -162,8 +163,9 @@ static int sdhci_transfer_data(struct sdhci_host *host, 
struct mmc_data *data)
start_addr &=
~(SDHCI_DEFAULT_BOUNDARY_SIZE - 1);
start_addr += SDHCI_DEFAULT_BOUNDARY_SIZE;
-   sdhci_writel(host, 
phys_to_bus((ulong)start_addr),
-SDHCI_DMA_ADDRESS);
+   start_addr = 
dev_phys_to_bus(mmc_to_dev(host->mmc),
+start_addr);
+   sdhci_writel(host, start_addr, 
SDHCI_DMA_ADDRESS);
}
}
if (timeout-- > 0)
diff --git a/include/mmc.h b/include/mmc.h
index 1d377e0281..c12c7a0b5c 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -736,6 +736,12 @@ struct mmc {
u8 hs400_tuning;
 };
 
+#if CONFIG_IS_ENABLED(DM_MMC)
+#define mmc_to_dev(_mmc)   _mmc->dev
+#else
+#define mmc_to_dev(_mmc)   NULL
+#endif
+
 struct mmc_hwpart_conf {
struct {
uint enh_start; /* in 512-byte sectors */
-- 
2.29.2



[PATCH v5 10/13] xhci: translate virtual addresses into the bus's address space

2020-12-23 Thread Nicolas Saenz Julienne
So far we've been content with passing physical addresses when
configuring memory addresses into XHCI controllers, but not all
platforms have buses with transparent mappings. Specifically the
Raspberry Pi 4 might introduce an offset to memory accesses incoming
from its PCIe port.

Introduce xhci_virt_to_bus() and xhci_bus_to_virt() to cater with these
limitations, and make sure we don't break non DM users.

Signed-off-by: Nicolas Saenz Julienne 
Reviewed-by: Simon Glass 
Reviewed-by: Stefan Roese 

---
Changes since v4:
 - Introduce macro to access ctrl->dev
 - No need to make code conditional on DM_DMA with new macros

Changes since v3:
 - Don't call phys_to_bus()/bus_to_phys(), we only support DM

 drivers/usb/host/xhci-mem.c  | 45 +++-
 drivers/usb/host/xhci-ring.c | 11 +
 drivers/usb/host/xhci.c  |  4 ++--
 include/usb/xhci.h   | 20 +++-
 4 files changed, 52 insertions(+), 28 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index b002d6f166..83147d51b5 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -110,7 +110,7 @@ static void xhci_scratchpad_free(struct xhci_ctrl *ctrl)
 
ctrl->dcbaa->dev_context_ptrs[0] = 0;
 
-   free((void *)(uintptr_t)le64_to_cpu(ctrl->scratchpad->sp_array[0]));
+   free(xhci_bus_to_virt(ctrl, 
le64_to_cpu(ctrl->scratchpad->sp_array[0])));
free(ctrl->scratchpad->sp_array);
free(ctrl->scratchpad);
ctrl->scratchpad = NULL;
@@ -216,8 +216,8 @@ static void *xhci_malloc(unsigned int size)
  * @param link_trbsflag to indicate whether to link the trbs or NOT
  * @return none
  */
-static void xhci_link_segments(struct xhci_segment *prev,
-   struct xhci_segment *next, bool link_trbs)
+static void xhci_link_segments(struct xhci_ctrl *ctrl, struct xhci_segment 
*prev,
+  struct xhci_segment *next, bool link_trbs)
 {
u32 val;
u64 val_64 = 0;
@@ -226,7 +226,7 @@ static void xhci_link_segments(struct xhci_segment *prev,
return;
prev->next = next;
if (link_trbs) {
-   val_64 = virt_to_phys(next->trbs);
+   val_64 = xhci_virt_to_bus(ctrl, next->trbs);
prev->trbs[TRBS_PER_SEGMENT-1].link.segment_ptr =
cpu_to_le64(val_64);
 
@@ -304,7 +304,8 @@ static struct xhci_segment *xhci_segment_alloc(void)
  * @param link_trbsflag to indicate whether to link the trbs or NOT
  * @return pointer to the newly created RING
  */
-struct xhci_ring *xhci_ring_alloc(unsigned int num_segs, bool link_trbs)
+struct xhci_ring *xhci_ring_alloc(struct xhci_ctrl *ctrl, unsigned int 
num_segs,
+ bool link_trbs)
 {
struct xhci_ring *ring;
struct xhci_segment *prev;
@@ -327,12 +328,12 @@ struct xhci_ring *xhci_ring_alloc(unsigned int num_segs, 
bool link_trbs)
next = xhci_segment_alloc();
BUG_ON(!next);
 
-   xhci_link_segments(prev, next, link_trbs);
+   xhci_link_segments(ctrl, prev, next, link_trbs);
 
prev = next;
num_segs--;
}
-   xhci_link_segments(prev, ring->first_seg, link_trbs);
+   xhci_link_segments(ctrl, prev, ring->first_seg, link_trbs);
if (link_trbs) {
/* See section 4.9.2.1 and 6.4.4.1 */
prev->trbs[TRBS_PER_SEGMENT-1].link.control |=
@@ -354,6 +355,7 @@ static int xhci_scratchpad_alloc(struct xhci_ctrl *ctrl)
struct xhci_hccr *hccr = ctrl->hccr;
struct xhci_hcor *hcor = ctrl->hcor;
struct xhci_scratchpad *scratchpad;
+   uint64_t val_64;
int num_sp;
uint32_t page_size;
void *buf;
@@ -371,8 +373,9 @@ static int xhci_scratchpad_alloc(struct xhci_ctrl *ctrl)
scratchpad->sp_array = xhci_malloc(num_sp * sizeof(u64));
if (!scratchpad->sp_array)
goto fail_sp2;
-   ctrl->dcbaa->dev_context_ptrs[0] =
-   cpu_to_le64((uintptr_t)scratchpad->sp_array);
+
+   val_64 = xhci_virt_to_bus(ctrl, scratchpad->sp_array);
+   ctrl->dcbaa->dev_context_ptrs[0] = cpu_to_le64(val_64);
 
xhci_flush_cache((uintptr_t)>dcbaa->dev_context_ptrs[0],
sizeof(ctrl->dcbaa->dev_context_ptrs[0]));
@@ -393,8 +396,8 @@ static int xhci_scratchpad_alloc(struct xhci_ctrl *ctrl)
xhci_flush_cache((uintptr_t)buf, num_sp * page_size);
 
for (i = 0; i < num_sp; i++) {
-   uintptr_t ptr = (uintptr_t)buf + i * page_size;
-   scratchpad->sp_array[i] = cpu_to_le64(ptr);
+   val_64 = xhci_virt_to_bus(ctrl, buf + i * page_size);
+   scratchpad->sp_array[i] = cpu_to_le64(val_64);
}
 
xhci_flush_cache((uintptr_t)scratchpad->sp_array,
@@ -484,9 +487,9 @@ int xhci_alloc_virt_device(struct xhci_ctrl *ctrl, unsigned 
int 

[PATCH v5 09/13] dm: test: Add test case for dev_phys_to_bus()/dev_bus_to_phys()

2020-12-23 Thread Nicolas Saenz Julienne
By reusing DT nodes already available in sandbox's test DT introduce a
test to validate dev_phys_to_bus()/dev_bus_to_phys().

Signed-off-by: Nicolas Saenz Julienne 
Reviewed-by: Simon Glass 

---
Changes since v3:
 - Use ut_assertok() instead of ut_assert(!func())
 - Use ut_assert_addr()

 test/dm/Makefile   |  1 +
 test/dm/phys2bus.c | 37 +
 2 files changed, 38 insertions(+)
 create mode 100644 test/dm/phys2bus.c

diff --git a/test/dm/Makefile b/test/dm/Makefile
index 5c52d8b6ea..ac86abaa88 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_UT_DM) += test-uclass.o
 
 obj-$(CONFIG_UT_DM) += core.o
 obj-$(CONFIG_UT_DM) += read.o
+obj-$(CONFIG_UT_DM) += phys2bus.o
 ifneq ($(CONFIG_SANDBOX),)
 obj-$(CONFIG_ACPIGEN) += acpi.o
 obj-$(CONFIG_ACPIGEN) += acpigen.o
diff --git a/test/dm/phys2bus.c b/test/dm/phys2bus.c
new file mode 100644
index 00..342f2fa8eb
--- /dev/null
+++ b/test/dm/phys2bus.c
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2020 Nicolas Saenz Julienne 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static int dm_test_phys_to_bus(struct unit_test_state *uts)
+{
+   struct udevice *dev;
+   ofnode node;
+
+   node = ofnode_path("/mmio-bus@0");
+   ut_assert(ofnode_valid(node));
+   ut_assertok(uclass_get_device_by_ofnode(UCLASS_TEST_BUS, node, ));
+   /* In this case it should be transparent, no dma-ranges in parent bus */
+   ut_asserteq_addr((void*)0xfULL, (void*)dev_phys_to_bus(dev, 
0xf));
+   ut_asserteq_addr((void*)0xfULL, (void*)(ulong)dev_bus_to_phys(dev, 
0xf));
+
+   node = ofnode_path("/mmio-bus@0/subnode@0");
+   ut_assert(ofnode_valid(node));
+   ut_assertok(uclass_get_device_by_ofnode(UCLASS_TEST_FDT, node, ));
+   ut_asserteq_addr((void*)0x100fULL, (void*)dev_phys_to_bus(dev, 
0xf));
+   ut_asserteq_addr((void*)0xfULL, (void*)(ulong)dev_bus_to_phys(dev, 
0x100f));
+
+   return 0;
+}
+DM_TEST(dm_test_phys_to_bus, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
-- 
2.29.2



[PATCH v5 07/13] dm: test: Add test case for dev->dma_offset

2020-12-23 Thread Nicolas Saenz Julienne
Add test to validate dev->dma_offset is properly set on devices.

Signed-off-by: Nicolas Saenz Julienne 
Reviewed-by: Simon Glass 

---
Changes since v3:
 - Use ut_assertok() instead of ut_assert(!func())

 arch/sandbox/dts/test.dts  |  4 
 configs/sandbox64_defconfig|  1 +
 configs/sandbox_defconfig  |  1 +
 configs/sandbox_flattree_defconfig |  1 +
 configs/sandbox_spl_defconfig  |  1 +
 test/dm/core.c | 30 ++
 6 files changed, 38 insertions(+)

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 3a3b51f83b..78f0100282 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -307,6 +307,10 @@
#address-cells = <1>;
#size-cells = <1>;
compatible = "denx,u-boot-test-bus";
+
+   subnode@0 {
+   compatible = "denx,u-boot-fdt-test";
+   };
};
 
acpi_test1: acpi-test {
diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig
index 5fbbfd7236..2c189a8a00 100644
--- a/configs/sandbox64_defconfig
+++ b/configs/sandbox64_defconfig
@@ -94,6 +94,7 @@ CONFIG_ENV_EXT4_DEVICE_AND_PART="0:0"
 CONFIG_BOOTP_SEND_HOSTNAME=y
 CONFIG_NETCONSOLE=y
 CONFIG_IP_DEFRAG=y
+CONFIG_DM_DMA=y
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
 CONFIG_DEVRES=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index f1ec701a9f..ac97c16cef 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -108,6 +108,7 @@ CONFIG_ENV_EXT4_DEVICE_AND_PART="0:0"
 CONFIG_BOOTP_SEND_HOSTNAME=y
 CONFIG_NETCONSOLE=y
 CONFIG_IP_DEFRAG=y
+CONFIG_DM_DMA=y
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
 CONFIG_DEVRES=y
diff --git a/configs/sandbox_flattree_defconfig 
b/configs/sandbox_flattree_defconfig
index edca7f1808..f5923bf713 100644
--- a/configs/sandbox_flattree_defconfig
+++ b/configs/sandbox_flattree_defconfig
@@ -75,6 +75,7 @@ CONFIG_ENV_EXT4_DEVICE_AND_PART="0:0"
 CONFIG_BOOTP_SEND_HOSTNAME=y
 CONFIG_NETCONSOLE=y
 CONFIG_IP_DEFRAG=y
+CONFIG_DM_DMA=y
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
 CONFIG_DEVRES=y
diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig
index 479f0226e3..0a4815770c 100644
--- a/configs/sandbox_spl_defconfig
+++ b/configs/sandbox_spl_defconfig
@@ -94,6 +94,7 @@ CONFIG_BOOTP_SEND_HOSTNAME=y
 CONFIG_NETCONSOLE=y
 CONFIG_IP_DEFRAG=y
 CONFIG_SPL_DM=y
+CONFIG_DM_DMA=y
 CONFIG_REGMAP=y
 CONFIG_SPL_REGMAP=y
 CONFIG_SYSCON=y
diff --git a/test/dm/core.c b/test/dm/core.c
index 6f380a574c..8ca49d09ee 100644
--- a/test/dm/core.c
+++ b/test/dm/core.c
@@ -1066,3 +1066,33 @@ static int dm_test_inactive_child(struct unit_test_state 
*uts)
return 0;
 }
 DM_TEST(dm_test_inactive_child, UT_TESTF_SCAN_PDATA);
+
+static int dm_test_dma_offset(struct unit_test_state *uts)
+{
+   struct udevice *dev;
+   ofnode node;
+
+   /* Make sure the bus's dma-ranges aren't taken into account here */
+   node = ofnode_path("/mmio-bus@0");
+   ut_assert(ofnode_valid(node));
+   ut_assertok(uclass_get_device_by_ofnode(UCLASS_TEST_BUS, node, ));
+   ut_asserteq_64(0, dev->dma_offset);
+
+   /* Device behind a bus with dma-ranges */
+   node = ofnode_path("/mmio-bus@0/subnode@0");
+   ut_assert(ofnode_valid(node));
+   ut_assertok(uclass_get_device_by_ofnode(UCLASS_TEST_FDT, node, ));
+   ut_asserteq_64(-0x1000ULL, dev->dma_offset);
+
+   /* This one has no dma-ranges */
+   node = ofnode_path("/mmio-bus@1");
+   ut_assert(ofnode_valid(node));
+   ut_assertok(uclass_get_device_by_ofnode(UCLASS_TEST_BUS, node, ));
+   node = ofnode_path("/mmio-bus@1/subnode@0");
+   ut_assert(ofnode_valid(node));
+   ut_assertok(uclass_get_device_by_ofnode(UCLASS_TEST_FDT, node, ));
+   ut_asserteq_64(0, dev->dma_offset);
+
+   return 0;
+}
+DM_TEST(dm_test_dma_offset, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
-- 
2.29.2



[PATCH v5 08/13] dm: Introduce dev_phys_to_bus()/dev_bus_to_phys()

2020-12-23 Thread Nicolas Saenz Julienne
These functions, instead of relying on hard-coded platform-specific
address translations, make use of the DMA constraints provided by the DM
core. This allows for per-device translations.

We can't yet get rid of the legacy phys_to_bus()/bus_to_phys()
implementations as some of its users are not integrated into the
device model.

Signed-off-by: Nicolas Saenz Julienne 
Reviewed-by: Simon Glass 
Reviewed-by: Stefan Roese 

---
Changes since v4:
 - Introduce macros for !DM case to make API usage cleaner

Changes since v2:
 - Use CONFIG_DM_DMA

 include/phys2bus.h | 17 +
 1 file changed, 17 insertions(+)

diff --git a/include/phys2bus.h b/include/phys2bus.h
index dc9b8e5a25..866b8b51a8 100644
--- a/include/phys2bus.h
+++ b/include/phys2bus.h
@@ -21,4 +21,21 @@ static inline unsigned long bus_to_phys(unsigned long bus)
 }
 #endif
 
+#if CONFIG_IS_ENABLED(DM)
+#include 
+
+static inline dma_addr_t dev_phys_to_bus(struct udevice *dev, phys_addr_t phys)
+{
+   return phys - dev_get_dma_offset(dev);
+}
+
+static inline phys_addr_t dev_bus_to_phys(struct udevice *dev, dma_addr_t bus)
+{
+   return bus + dev_get_dma_offset(dev);
+}
+#else
+#define dev_phys_to_bus(_, _addr)  _addr
+#define dev_bus_to_phys(_, _addr)  _addr
+#endif
+
 #endif
-- 
2.29.2



[PATCH v5 04/13] dm: Introduce xxx_get_dma_range()

2020-12-23 Thread Nicolas Saenz Julienne
Add the following functions to get a specific device's DMA ranges:
 - dev_get_dma_range()
 - ofnode_get_dma_range()
 - of_get_dma_range()
 - fdt_get_dma_range()
They are specially useful in oder to be able validate a physical address
space range into a bus's and to convert addresses from and to address
spaces.

Signed-off-by: Nicolas Saenz Julienne 
Reviewed-by: Simon Glass 

---
Changes since v2:
 - Return ENOENT instead of ENODEV
 - Refcount of nodes

Changes since v1:
 - Fix wrong arguments in of_get_dma_range()'s call to 
of_translate_dma_address()
 - Fix build in SPL/TPL and no LIBFDT supprt
 - Add missing declaration in 'core/read.c'
 - Address Matthias' comments

 common/fdt_support.c   | 73 +++
 drivers/core/of_addr.c | 78 ++
 drivers/core/ofnode.c  |  9 +
 drivers/core/read.c|  6 
 include/dm/of_addr.h   | 17 +
 include/dm/ofnode.h| 16 +
 include/dm/read.h  | 21 
 include/fdt_support.h  | 14 
 8 files changed, 234 insertions(+)

diff --git a/common/fdt_support.c b/common/fdt_support.c
index 5ae75df3c6..bf855d26c8 100644
--- a/common/fdt_support.c
+++ b/common/fdt_support.c
@@ -1342,6 +1342,79 @@ u64 fdt_translate_dma_address(const void *blob, int 
node_offset,
return __of_translate_address(blob, node_offset, in_addr, "dma-ranges");
 }
 
+int fdt_get_dma_range(const void *blob, int node, phys_addr_t *cpu,
+ dma_addr_t *bus, u64 *size)
+{
+   bool found_dma_ranges = false;
+   struct of_bus *bus_node;
+   const fdt32_t *ranges;
+   int na, ns, pna, pns;
+   int parent = node;
+   int ret = 0;
+   int len;
+
+   /* Find the closest dma-ranges property */
+   while (parent >= 0) {
+   ranges = fdt_getprop(blob, parent, "dma-ranges", );
+
+   /* Ignore empty ranges, they imply no translation required */
+   if (ranges && len > 0)
+   break;
+
+   /* Once we find 'dma-ranges', then a missing one is an error */
+   if (found_dma_ranges && !ranges) {
+   ret = -EINVAL;
+   goto out;
+   }
+
+   if (ranges)
+   found_dma_ranges = true;
+
+   parent = fdt_parent_offset(blob, parent);
+   }
+
+   if (!ranges || parent < 0) {
+   debug("no dma-ranges found for node %s\n",
+ fdt_get_name(blob, node, NULL));
+   ret = -ENOENT;
+   goto out;
+   }
+
+   /* switch to that node */
+   node = parent;
+   parent = fdt_parent_offset(blob, node);
+   if (parent < 0) {
+   printf("Found dma-ranges in root node, shoudln't happen\n");
+   ret = -EINVAL;
+   goto out;
+   }
+
+   /* Get the address sizes both for the bus and its parent */
+   bus_node = of_match_bus(blob, node);
+   bus_node->count_cells(blob, node, , );
+   if (!OF_CHECK_COUNTS(na, ns)) {
+   printf("%s: Bad cell count for %s\n", __FUNCTION__,
+  fdt_get_name(blob, node, NULL));
+   return -EINVAL;
+   goto out;
+   }
+
+   bus_node = of_match_bus(blob, parent);
+   bus_node->count_cells(blob, parent, , );
+   if (!OF_CHECK_COUNTS(pna, pns)) {
+   printf("%s: Bad cell count for %s\n", __FUNCTION__,
+  fdt_get_name(blob, parent, NULL));
+   return -EINVAL;
+   goto out;
+   }
+
+   *bus = fdt_read_number(ranges, na);
+   *cpu = fdt_translate_dma_address(blob, node, ranges + na);
+   *size = fdt_read_number(ranges + na + pna, ns);
+out:
+   return ret;
+}
+
 /**
  * fdt_node_offset_by_compat_reg: Find a node that matches compatiable and
  * who's reg property matches a physical cpu address
diff --git a/drivers/core/of_addr.c b/drivers/core/of_addr.c
index ca34d84922..703bc3e3f5 100644
--- a/drivers/core/of_addr.c
+++ b/drivers/core/of_addr.c
@@ -325,6 +325,84 @@ u64 of_translate_dma_address(const struct device_node 
*dev, const __be32 *in_add
return __of_translate_address(dev, in_addr, "dma-ranges");
 }
 
+int of_get_dma_range(const struct device_node *dev, phys_addr_t *cpu,
+dma_addr_t *bus, u64 *size)
+{
+   bool found_dma_ranges = false;
+   struct device_node *parent;
+   struct of_bus *bus_node;
+   int na, ns, pna, pns;
+   const __be32 *ranges;
+   int ret = 0;
+   int len;
+
+   /* Find the closest dma-ranges property */
+   dev = of_node_get(dev);
+   while (dev) {
+   ranges = of_get_property(dev, "dma-ranges", );
+
+   /* Ignore empty ranges, they imply no translation required */
+   if (ranges && len > 0)
+   break;
+
+   /* Once we find 'dma-ranges', then a 

[PATCH v5 06/13] dm: Introduce DMA constraints into the core device model

2020-12-23 Thread Nicolas Saenz Julienne
Calculating the DMA offset between a bus address space and CPU's every
time we call phys_to_bus() and bus_to_phys() isn't ideal performance
wise, as it implies traversing the device tree from the device's node up
to the root. Since this information is static and available before the
device's initialization, parse it before the probe call an provide the
DMA offset in 'struct udevice' for the address translation code to use
it.

Signed-off-by: Nicolas Saenz Julienne 
Reviewed-by: Simon Glass 

---
Changes since v4:
 - Use macros to access dma_offset

Changes since v3:
 - Comment functions and struct variables
 - Correct typos

Changes since v2:
 - Return/Fail on error
 - Add config option
 - use ulong instead for u64 for dev->dma_offset

Changes since v1:
 - Update commit message so as to explain better the reasoning behind
   this

 drivers/core/Kconfig  | 10 ++
 drivers/core/device.c | 41 +
 include/dm/device.h   | 13 +
 3 files changed, 64 insertions(+)

diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig
index ffae6f9795..295cf2dd00 100644
--- a/drivers/core/Kconfig
+++ b/drivers/core/Kconfig
@@ -113,6 +113,16 @@ config SPL_DM_SEQ_ALIAS
  numbered devices (e.g. serial0 = ). This feature can be
  disabled if it is not required, to save code space in SPL.
 
+config DM_DMA
+   bool "Support per-device DMA constraints"
+   depends on DM
+   default n
+   help
+ Enable this to extract per-device DMA constraints, only supported on
+ device-tree systems for now. This is needed in order translate
+ addresses on systems where different buses have different views of
+ the physical address space.
+
 config REGMAP
bool "Support register maps"
depends on DM
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 4b3dcb3b37..047032a1dd 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -421,6 +421,43 @@ fail:
return ret;
 }
 
+/**
+ * device_get_dma_constraints() - Populate device's DMA constraints
+ *
+ * Gets a device's DMA constraints from firmware. This information is later
+ * used by drivers to translate physcal addresses to the device's bus address
+ * space. For now only device-tree is supported.
+ *
+ * @dev: Pointer to target device
+ * Return: 0 if OK or if no DMA constraints were found, error otherwise
+ */
+static int device_get_dma_constraints(struct udevice *dev)
+{
+   struct udevice *parent = dev->parent;
+   phys_addr_t cpu = 0;
+   dma_addr_t bus = 0;
+   u64 size = 0;
+   int ret;
+
+   if (!CONFIG_IS_ENABLED(DM_DMA) || !parent || !dev_of_valid(parent))
+   return 0;
+
+   /*
+* We start parsing for dma-ranges from the device's bus node. This is
+* specially important on nested buses.
+*/
+   ret = dev_get_dma_range(parent, , , );
+   /* Don't return an error if no 'dma-ranges' were found */
+   if (ret && ret != -ENOENT) {
+   dm_warn("%s: failed to get DMA range, %d\n", dev->name, ret);
+   return ret;
+   }
+
+   dev_set_dma_offset(dev, cpu - bus);
+
+   return 0;
+}
+
 int device_probe(struct udevice *dev)
 {
const struct driver *drv;
@@ -482,6 +519,10 @@ int device_probe(struct udevice *dev)
goto fail;
}
 
+   ret = device_get_dma_constraints(dev);
+   if (ret)
+   goto fail;
+
ret = uclass_pre_probe_device(dev);
if (ret)
goto fail;
diff --git a/include/dm/device.h b/include/dm/device.h
index 5bef484247..b27889af01 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -138,6 +138,8 @@ enum {
  * When CONFIG_DEVRES is enabled, devm_kmalloc() and friends will
  * add to this list. Memory so-allocated will be freed
  * automatically when the device is removed / unbound
+ * @dma_offset: Offset between the physical address space (CPU's) and the
+ * device's bus address space
  */
 struct udevice {
const struct driver *driver;
@@ -161,6 +163,9 @@ struct udevice {
 #ifdef CONFIG_DEVRES
struct list_head devres_head;
 #endif
+#if CONFIG_IS_ENABLED(DM_DMA)
+   ulong dma_offset;
+#endif
 };
 
 /* Maximum sequence number supported */
@@ -172,6 +177,14 @@ struct udevice {
 /* Returns non-zero if the device is active (probed and not removed) */
 #define device_active(dev) ((dev)->flags & DM_FLAG_ACTIVATED)
 
+#if CONFIG_IS_ENABLED(DM_DMA)
+#define dev_set_dma_offset(_dev, _offset)  _dev->dma_offset = _offset
+#define dev_get_dma_offset(_dev)   _dev->dma_offset
+#else
+#define dev_set_dma_offset(_dev, _offset)
+#define dev_get_dma_offset(_dev)   0
+#endif
+
 static inline int dev_of_offset(const struct udevice *dev)
 {
return ofnode_to_offset(dev->node);
-- 
2.29.2



[PATCH v5 05/13] dm: test: Add test case for dev_get_dma_ranges()

2020-12-23 Thread Nicolas Saenz Julienne
Introduce some new nodes in sandbox's test device-tree and dm tests in
order to validate dev_get_dma_range().

Signed-off-by: Nicolas Saenz Julienne 
Reviewed-by: Simon Glass 

---
Changes since v3:
 - Use ut_assertok() instead of ut_assert(!func())

 arch/sandbox/dts/test.dts | 17 ++
 test/dm/Makefile  |  1 +
 test/dm/read.c| 49 +++
 3 files changed, 67 insertions(+)
 create mode 100644 test/dm/read.c

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index f3b766271d..3a3b51f83b 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -292,6 +292,23 @@
test5-gpios = <_a 19>;
};
 
+   mmio-bus@0 {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   compatible = "denx,u-boot-test-bus";
+   dma-ranges = <0x1000 0x 0x0004>;
+
+   subnode@0 {
+   compatible = "denx,u-boot-fdt-test";
+   };
+   };
+
+   mmio-bus@1 {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   compatible = "denx,u-boot-test-bus";
+   };
+
acpi_test1: acpi-test {
compatible = "denx,u-boot-acpi-test";
acpi-ssdt-test-data = "ab";
diff --git a/test/dm/Makefile b/test/dm/Makefile
index 46e076ed09..5c52d8b6ea 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_UT_DM) += test-fdt.o
 obj-$(CONFIG_UT_DM) += test-uclass.o
 
 obj-$(CONFIG_UT_DM) += core.o
+obj-$(CONFIG_UT_DM) += read.o
 ifneq ($(CONFIG_SANDBOX),)
 obj-$(CONFIG_ACPIGEN) += acpi.o
 obj-$(CONFIG_ACPIGEN) += acpigen.o
diff --git a/test/dm/read.c b/test/dm/read.c
new file mode 100644
index 00..7768aa2968
--- /dev/null
+++ b/test/dm/read.c
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2020 Nicolas Saenz Julienne 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static int dm_test_dma_ranges(struct unit_test_state *uts)
+{
+   struct udevice *dev;
+   phys_addr_t cpu;
+   dma_addr_t bus;
+   ofnode node;
+   u64 size;
+
+   /* dma-ranges are on the device's node */
+   node = ofnode_path("/mmio-bus@0");
+   ut_assert(ofnode_valid(node));
+   ut_assertok(uclass_get_device_by_ofnode(UCLASS_TEST_BUS, node, ));
+   ut_assertok(dev_get_dma_range(dev, , , ));
+   ut_asserteq_64(0x4, size);
+   ut_asserteq_64(0x0, cpu);
+   ut_asserteq_64(0x1000, bus);
+
+   /* dma-ranges are on the bus' node */
+   node = ofnode_path("/mmio-bus@0/subnode@0");
+   ut_assert(ofnode_valid(node));
+   ut_assertok(uclass_get_device_by_ofnode(UCLASS_TEST_FDT, node, ));
+   ut_assertok(dev_get_dma_range(dev, , , ));
+   ut_asserteq_64(0x4, size);
+   ut_asserteq_64(0x0, cpu);
+   ut_asserteq_64(0x1000, bus);
+
+   /* No dma-ranges available */
+   node = ofnode_path("/mmio-bus@1");
+   ut_assert(ofnode_valid(node));
+   ut_assertok(uclass_get_device_by_ofnode(UCLASS_TEST_BUS, node, ));
+   ut_asserteq(-ENOENT, dev_get_dma_range(dev, , , ));
+
+   return 0;
+}
+DM_TEST(dm_test_dma_ranges, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
-- 
2.29.2



[PATCH v5 03/13] pci: pcie-brcmstb: Fix inbound window configurations

2020-12-23 Thread Nicolas Saenz Julienne
So far we've assumed a fixed configuration for inbound windows as we had
a single user for this controller. But the controller's DMA constraints
were improved starting with BCM2711's B1 revision of the SoC, notably
available in CM4 and Pi400. They allow for wider inbound windows. We can
now cover the whole address space, whereas before we where limited to
the lower 3GB.

This information is passed to us through DT's 'dma-ranges' property and
it's specially important for us to honor it since some interactions with
the board's co-processor assume we're doing so (specifically the XHCI
firmware load operation, which is handled by the co-processor after
u-boot has correctly configured the PCIe controller).

Signed-off-by: Nicolas Saenz Julienne 
---
 drivers/pci/pcie_brcmstb.c | 12 +---
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/pci/pcie_brcmstb.c b/drivers/pci/pcie_brcmstb.c
index dade79e9c8..f6e8ad0d0a 100644
--- a/drivers/pci/pcie_brcmstb.c
+++ b/drivers/pci/pcie_brcmstb.c
@@ -432,6 +432,7 @@ static int brcm_pcie_probe(struct udevice *dev)
struct pci_controller *hose = dev_get_uclass_priv(ctlr);
struct brcm_pcie *pcie = dev_get_priv(dev);
void __iomem *base = pcie->base;
+   struct pci_region region;
bool ssc_good = false;
int num_out_wins = 0;
u64 rc_bar2_offset, rc_bar2_size;
@@ -468,13 +469,10 @@ static int brcm_pcie_probe(struct udevice *dev)
MISC_CTRL_SCB_ACCESS_EN_MASK |
MISC_CTRL_CFG_READ_UR_MODE_MASK |
MISC_CTRL_MAX_BURST_SIZE_128);
-   /*
-* TODO: When support for other SoCs than BCM2711 is added we may
-* need to use the base address and size(s) provided in the dma-ranges
-* property.
-*/
-   rc_bar2_offset = 0;
-   rc_bar2_size = 0xc000;
+
+   pci_get_dma_regions(dev, , 0);
+   rc_bar2_offset = region.bus_start - region.phys_start;
+   rc_bar2_size = 1ULL << fls64(region.size - 1);
 
tmp = lower_32_bits(rc_bar2_offset);
u32p_replace_bits(, brcm_pcie_encode_ibar_size(rc_bar2_size),
-- 
2.29.2



[PATCH v5 02/13] rpi: Add identifier for the new CM4

2020-12-23 Thread Nicolas Saenz Julienne
The Raspberry Pi Foundation released the new Compute Module 4 which we
want to detect, so we can enable Ethernet on it and know the correct
device tree file name.

Note that this sets the Ethernet option to true since the official CM4
IO board has an Ethernet port. But that might not be the case when using
custom ones.

Signed-off-by: Nicolas Saenz Julienne 
---
 board/raspberrypi/rpi/rpi.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c
index b66698e4a9..abcf41a5a8 100644
--- a/board/raspberrypi/rpi/rpi.c
+++ b/board/raspberrypi/rpi/rpi.c
@@ -162,6 +162,11 @@ static const struct rpi_model rpi_models_new_scheme[] = {
DTB_DIR "bcm2711-rpi-400.dtb",
true,
},
+   [0x14] = {
+   "Compute Module 4",
+   DTB_DIR "bcm2711-rpi-cm4.dtb",
+   true,
+   },
 };
 
 static const struct rpi_model rpi_models_old_scheme[] = {
-- 
2.29.2



[PATCH v5 00/13] Raspberry Pi 400/Compute Module 4 support

2020-12-23 Thread Nicolas Saenz Julienne
This series could be split into at least two or even three parts, but I
kept it as is for now as it contains all the changes needed in order to
have u-boot working on the new Raspberry Pi 400 and Raspberry Pi Compute
Module 4.

There are core changes, specifically with regard to cpu to bus address
space translations. So far we had relied on hard-coded values but RPi
needs per device translations as it has at least three distinct bus
address spaces with different offsets. So it's a good opportunity to
implement bus translations the right way by parsing DT's dma-ranges.

Here's a more concrete example of what we're dealing with:

 - On a RPi4, SoC version BCM2711C0 with 8GB of memory

[0x0 0x2]   [0x2 0x4]  [0xc000 0x1] 
 [0x 0x1]
 phys/cpu address   PCIe bus address   Legacy peripheral
   emmc2 address
 space   space   address space  
  space

 - On a RPi4, SoC version BCM2711C0 with 4GB of memory

[0x0 0x1]   [0x1 0x2]  [0xc000 0x1] 
 [0x 0x1]
  phys/cpu address  PCIe bus address  Legacy peripheral 
   emmc2 address
space  spaceaddress space   
 space

- On a RPi4, SoC version BCM2711B0 with 8GB of memory (bus can only access the
  lower 3GB of memory because of a SoC routing bug)

[0x0 0x2]   [0x 0xC000]   [0xc000 0x1]
 phys/cpu address  PCIe bus address  Legacy peripheral
space  space   address space

---

Changes since v4:
 - Get rid of #ifs all over the place

Changes since v3:
 - Add commit "video: arm: rpi: Add brcm,bcm2711-hdmi0 compatible", it's
   pretty harmless
 - Get rid of non-device based phys2bus call in xhci & mmc
 - Simon's review changes in tests
 - Comment some of the APIs

Changes since v2:
 - Test builds not broken with buildman
 - Add tests to all DM changes
 - Make code conditional with config option
 - Correct OF refcount
 - Add config changes
 - Address small changes as per reviews

Changes since v1:
 - Fix some issues in 'dm: Introduce xxx_get_dma_range()'
 - Fix some typos in commit messages
 - Change DTB file name for RPi400
 - Address Matthias' comments

Nicolas Saenz Julienne (13):
  rpi: Add identifier for the new RPi400
  rpi: Add identifier for the new CM4
  pci: pcie-brcmstb: Fix inbound window configurations
  dm: Introduce xxx_get_dma_range()
  dm: test: Add test case for dev_get_dma_ranges()
  dm: Introduce DMA constraints into the core device model
  dm: test: Add test case for dev->dma_offset
  dm: Introduce dev_phys_to_bus()/dev_bus_to_phys()
  dm: test: Add test case for dev_phys_to_bus()/dev_bus_to_phys()
  xhci: translate virtual addresses into the bus's address space
  mmc: Introduce mmc_phys_to_bus()/mmc_bus_to_phys()
  configs: rpi4: Enable DM_DMA across all RPi4 configurations
  video: arm: rpi: Add brcm,bcm2711-hdmi0 compatible

 arch/sandbox/dts/test.dts  | 21 
 board/raspberrypi/rpi/rpi.c| 10 
 common/fdt_support.c   | 73 
 configs/rpi_4_32b_defconfig|  1 +
 configs/rpi_4_defconfig|  1 +
 configs/rpi_arm64_defconfig|  1 +
 configs/sandbox64_defconfig|  1 +
 configs/sandbox_defconfig  |  1 +
 configs/sandbox_flattree_defconfig |  1 +
 configs/sandbox_spl_defconfig  |  1 +
 drivers/core/Kconfig   | 10 
 drivers/core/device.c  | 41 
 drivers/core/of_addr.c | 78 ++
 drivers/core/ofnode.c  |  9 
 drivers/core/read.c|  6 +++
 drivers/mmc/sdhci.c| 12 +++--
 drivers/pci/pcie_brcmstb.c | 12 ++---
 drivers/usb/host/xhci-mem.c| 45 +
 drivers/usb/host/xhci-ring.c   | 11 +++--
 drivers/usb/host/xhci.c|  4 +-
 drivers/video/bcm2835.c|  1 +
 include/dm/device.h| 13 +
 include/dm/of_addr.h   | 17 +++
 include/dm/ofnode.h| 16 ++
 include/dm/read.h  | 21 
 include/fdt_support.h  | 14 ++
 include/mmc.h  |  6 +++
 include/phys2bus.h | 17 +++
 include/usb/xhci.h | 20 +++-
 test/dm/Makefile   |  2 +
 test/dm/core.c | 30 
 test/dm/phys2bus.c | 37 ++
 test/dm/read.c | 49 +++
 33 files changed, 542 insertions(+), 40 deletions(-)
 create mode 100644 test/dm/phys2bus.c
 create mode 100644 test/dm/read.c

-- 
2.29.2



[PATCH v5 01/13] rpi: Add identifier for the new RPi400

2020-12-23 Thread Nicolas Saenz Julienne
The Raspberry Pi Foundation released the new RPi400 which we want to
detect, so we can enable Ethernet on it and know the correct device tree
file name.

Signed-off-by: Nicolas Saenz Julienne 

---

Changes since v1:
 - The RPi Foundation introduced a RPi400 specific device tree, so use
   that file name instead of the fallback (RPi4b).

 board/raspberrypi/rpi/rpi.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c
index 6b1fa5fc14..b66698e4a9 100644
--- a/board/raspberrypi/rpi/rpi.c
+++ b/board/raspberrypi/rpi/rpi.c
@@ -157,6 +157,11 @@ static const struct rpi_model rpi_models_new_scheme[] = {
DTB_DIR "bcm2711-rpi-4-b.dtb",
true,
},
+   [0x13] = {
+   "400",
+   DTB_DIR "bcm2711-rpi-400.dtb",
+   true,
+   },
 };
 
 static const struct rpi_model rpi_models_old_scheme[] = {
-- 
2.29.2



Re: [u-boot,v2019.04-aspeed, v1 1/1] Common:fdt: Check for error return value

2020-12-23 Thread Simon Glass
On Sat, 12 Dec 2020 at 08:35, Simon Glass  wrote:
>
> On Wed, 2 Dec 2020 at 12:48, Hongwei Zhang  wrote:
> >
> > Check for negative return value of fdt_noffset from calling
> > boot_get_fdt_fit().
> >
> > Signed-off-by: Hongwei Zhang 
> > ---
> >  common/image-fdt.c | 3 +++
> >  1 file changed, 3 insertions(+)
> >
>
> Reviewed-by: Simon Glass 

Applied to u-boot-dm/next, thanks!


Re: [PATCH v2 4/6] test: spi: Add sandbox_spi_get_{speed, mode} interface

2020-12-23 Thread Simon Glass
On Mon, 14 Dec 2020 at 10:08, Ovidiu Panait  wrote:
>
> Introduce sandbox_spi_get_{speed, mode} public interface to retrieve the
> sandbox spi bus internal state. They are meant to be used in sandbox spi
> testcases.
>
> Signed-off-by: Ovidiu Panait 
> Reviewed-by: Simon Glass 
> ---
>
> Changes in v2:
> - add reviewed-by tag
>
>  arch/sandbox/include/asm/test.h | 16 
>  drivers/spi/sandbox_spi.c   | 14 ++
>  2 files changed, 30 insertions(+)

Applied to u-boot-dm/next, thanks!


Re: [PATCH 1/1] sandbox: implement runtime system reset

2020-12-23 Thread Simon Glass
On Wed, 2 Dec 2020 at 08:22, Heinrich Schuchardt  wrote:
>
> Implement a reset function that we can call after ExitBootServices(),
> when all driver model devices are gone.
>
> Signed-off-by: Heinrich Schuchardt 
> ---
>  arch/sandbox/cpu/start.c | 10 ++
>  lib/efi_loader/Kconfig   |  3 ++-
>  2 files changed, 12 insertions(+), 1 deletion(-)

Reviewed-by: Simon Glass 

Applied to u-boot-dm/next, thanks!


Re: [PATCH 1/2] configs: sandbox: activate DEBUG_UART

2020-12-23 Thread Simon Glass
On Fri, 27 Nov 2020 at 03:49, Patrick Delaunay  wrote:
>
> Add CONFIG_DEBUG_UART=y for all sandbox defconfig
> as it is already done in sandbox_defconfig.
>
> Signed-off-by: Patrick Delaunay 
> ---
>
>  configs/sandbox64_defconfig| 1 +
>  configs/sandbox_flattree_defconfig | 1 +
>  configs/sandbox_spl_defconfig  | 1 +
>  3 files changed, 3 insertions(+)

Reviewed-by: Simon Glass 

Applied to u-boot-dm/next, thanks!


Re: [PATCH 1/3] patman: Add --no-signoff to suppress adding signoffs

2020-12-23 Thread Simon Glass
On Tue, 24 Nov 2020 at 10:15, Philipp Tomsich  wrote:
>
> To enable use of patman with FSF/GNU projects, such as GCC or
> Binutils, no Signed-off-by may be added.  This adds a command
> line flag '--no-signoff' to suppress adding signoffs in patman
> when processing commits.
>
> Signed-off-by: Philipp Tomsich 
> ---
>
>  tools/patman/control.py | 6 +++---
>  tools/patman/gitutil.py | 6 --
>  tools/patman/main.py| 2 ++
>  3 files changed, 9 insertions(+), 5 deletions(-)

Reviewed-by: Simon Glass 

Applied to u-boot-dm/next, thanks!


Re: [PATCH v3] fdt: Use phandle to distinguish DT nodes with same name

2020-12-23 Thread Simon Glass
On Wed, 2 Dec 2020 at 22:26, Aswath Govindraju  wrote:
>
> While assigning the sequence number to subsystem instances by reading the
> aliases property, only DT nodes names are compared and not the complete
> path. This causes a problem when there are two DT nodes with same name but
> have different paths.
>
> In arch/arm/dts/k3-am65-main.dtsi there are two USB controllers with the
> same device tree node name but different path. When aliases are defined for
> these USB controllers then fdtdec_get_alias_seq() fails to pick the correct
> instance for a given index.
>
> fdt_path_offset() function is slow and this would effect the U-Boot
> startup. To avert the time penalty on all boards, apply this extra check
> only when required by using a config option.
>
> Fix it by comparing the phandles of DT nodes after the node names match,
> under a config option.
>
> Signed-off-by: Aswath Govindraju 
> ---
>
> Changes since v2:
>  - changed #ifdef to if(IS_ENABLED())
>  - corrected errors in commit description
>
> Changes since v1:
>  - Added a config option as fdt_path_offset() slows down the u-boot start
>up and would be better to be enabled only when required
>  - Added an example case in commit message where the following fix is
>required.
>
>  lib/Kconfig  |  8 
>  lib/fdtdec.c | 11 +++
>  2 files changed, 19 insertions(+)
>

Reviewed-by: Simon Glass 

Applied to u-boot-dm/next, thanks!


Re: [PATCH 2/3] patman: Add project-default for 'gcc'

2020-12-23 Thread Simon Glass
On Tue, 24 Nov 2020 at 10:15, Philipp Tomsich  wrote:
>
> Add defaults for FSF/GNU projects, such as gcc, that provide sensible
> settings for those projects.
>
> Signed-off-by: Philipp Tomsich 
> ---
>
>  tools/patman/settings.py | 7 ++-
>  1 file changed, 6 insertions(+), 1 deletion(-)

Reviewed-by: Simon Glass 

Applied to u-boot-dm/next, thanks!


Re: [PATCH v2 1/6] sandbox: spi: Drop unused sandbox_spi_parse_spec function

2020-12-23 Thread Simon Glass
Commit 1289e96797bf ("sandbox: spi: Drop command-line SPI option") dropped
support for specifying SPI devices on the command line, removing the only
user of sandbox_spi_parse_spec(). Remove the function too.

Fixes: 1289e96797bf ("sandbox: spi: Drop command-line SPI option")
Signed-off-by: Ovidiu Panait 
Reviewed-by: Simon Glass 
---

Changes in v2:
- add reviewed-by tag

 arch/sandbox/include/asm/spi.h | 10 --
 drivers/spi/sandbox_spi.c  | 16 
 2 files changed, 26 deletions(-)

Applied to u-boot-dm/next, thanks!


Re: [PATCH v2 2/6] sandbox: test: Add a second SPI slave on sandbox_spi bus

2020-12-23 Thread Simon Glass
Place a second spi slave on the sandbox_spi bus, to be used by the
spi_claim_bus() testcase we are about to introduce. We need to make sure
that jumping between slaves calling spi_claim_bus() sets the bus speed and
mode appropriately. Use different max-hz and mode properties for this new
slave.

Also, update sandbox_spi cs_info call to allow activity on CS0/CS1 and
adapt dm_test_spi_find() testcase for this new setup.

Signed-off-by: Ovidiu Panait 
Reviewed-by: Simon Glass 
---

Changes in v2:
- add reviewed-by tag

 arch/sandbox/dts/test.dts | 10 +-
 drivers/spi/sandbox_spi.c |  4 ++--
 test/dm/spi.c |  2 +-
 3 files changed, 12 insertions(+), 4 deletions(-)

Applied to u-boot-dm/next, thanks!


Re: [PATCH v2 5/6] spi: spi-uclass: Fix spi_claim_bus() speed/mode setup logic

2020-12-23 Thread Simon Glass
Currently, when different spi slaves claim the bus consecutively using
spi_claim_bus(), spi_set_speed_mode() will only be executed on the first
two calls, leaving the bus in a bad state starting with the third call.

This patch drops spi_slave->speed member and adds caching of bus
speed/mode in dm_spi_bus struct. It also updates spi_claim_bus() to call
spi_set_speed_mode() if either speed or mode is different from what the
bus is currently configured for. Current behavior is to only take into
account the speed, but not the mode, which seems wrong.

Fixes: 60e2809a848 ("dm: spi: Avoid setting the speed with every transfer")
Reviewed-by: Simon Glass 
Reported-by: Rasmus Villemoes 
Reported-by: Moshe, Yaniv 
Signed-off-by: Ovidiu Panait 
---

Changes in v2:
- add reviewed-by tag

 drivers/mmc/mmc_spi.c|  1 -
 drivers/spi/spi-uclass.c | 17 -
 include/spi.h| 18 ++
 3 files changed, 26 insertions(+), 10 deletions(-)

Applied to u-boot-dm/next, thanks!


Re: [PATCH v2 3/6] spi: sandbox_spi: Implement speed/mode setup

2020-12-23 Thread Simon Glass
Implement sandbox_spi_set_{speed, mode} routines, to be able to keep track
of the current bus speed/mode. This will help determine whether the values
passed from dm_spi_claim_bus() are valid.

Signed-off-by: Ovidiu Panait 
---

Changes in v2:
- none

 drivers/spi/sandbox_spi.c | 26 ++
 1 file changed, 26 insertions(+)

Applied to u-boot-dm/next, thanks!


Re: [PATCH] dm: spi: Fix spi_free_slave() freed memory write

2020-12-23 Thread Simon Glass
On Wed, 16 Dec 2020 at 04:12, Niel Fourie  wrote:
>
> Remove setting slave->dev to NULL after the device_remove() call.
>
> The slave pointer points to dev->parent_priv, which has already
> been freed by device_free(), called from device_remove() in the
> preceding line. Writing to slave->dev may cause corruption of the
> dlmalloc free chunk forward pointer of the previously freed chunk.
>
> Signed-off-by: Niel Fourie 
> Cc: Simon Glass 
> ---
>  drivers/spi/spi-uclass.c | 1 -
>  1 file changed, 1 deletion(-)

Reviewed-by: Simon Glass 

Applied to u-boot-dm/next, thanks!


Re: [PATCH v2 6/6] test: dm: spi: Add testcase for spi_claim_bus()

2020-12-23 Thread Simon Glass
Add testcase for spi_claim_bus(), which checks that sandbox spi bus
speed/mode settings are updated correctly when multiple slaves use
the bus consecutively. The following configurations are used for the
two spi slaves involved:
  * different max_hz / different modes
  * different max_hz / same modes
  * different modes / same max_hz

asm/test.h header is added in order to be able to retrieve the current
speed/mode of the sandbox spi bus, via sandbox_spi_get_{speed, mode}.

Signed-off-by: Ovidiu Panait 
Reviewed-by: Simon Glass 
---

Changes in v2:
- add reviewed-by tag
- properly restore slave_a->mode from platdata:
  
  -   slave_a->mode = slave_plat->max_hz;
  +   slave_a->mode = slave_plat->mode;

 test/dm/spi.c | 82 +++
 1 file changed, 82 insertions(+)

Applied to u-boot-dm/next, thanks!


Re: [PATCH] buildman: Remove output binaries before building

2020-12-23 Thread Simon Glass
Buildman reuses build directories from previous builds to avoid the cost
of 'make mrproper' for every build. If the previous build produced an SPL
image but the current one does not, the SPL image will remain and buildman
will think it is a result of building the current board.

Remove these files before building, to avoid this problem.

Signed-off-by: Simon Glass 
---

 tools/buildman/builderthread.py | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

Applied to u-boot-dm/next, thanks!


Re: [PATCH] dm: core: Inline a few ofnode functions in SPL

2020-12-23 Thread Simon Glass
A recent change to unify the flattree/livetree code introduced a small
size increase in SPL on some boards. For example SPL code size for
px30-core-ctouch2-px30 increased by 40 bytes.

To address this we can take advantage of the fact that some of the ofnode
functions are only called a few times in SPL, so it is worth inlining
them.

Add new Kconfig options to control this. These functions are not inlined
for U-Boot proper, since this increases code size.

Fixes: 2ebea5eaebf ("dm: core: Combine the flattree and livetree binding code")
Signed-off-by: Simon Glass 
---
This series mostly improves code size:

04: dm: core: Inline a few ofnode functions in SPL
   arm: brppt1_spi brsmarc1
   aarch64: (for 267/267 boards) spl/u-boot-spl:all -8.9
spl/u-boot-spl:text -8.9
   arm: (for 693/693 boards) all +65.1 bss +0.2 data +64.9 rodata
+0.0 spl/u-boot-spl:all -6.6 spl/u-boot-spl:text -6.6 text -0.0
microblaze: (for 1/1 boards) spl/u-boot-spl:all -132.0
spl/u-boot-spl:text -132.0
  mips: (for 44/44 boards) spl/u-boot-spl:all -9.0 spl/u-boot-spl:text -9.0
 riscv: (for 18/18 boards) spl/u-boot-spl:all +17.3
spl/u-boot-spl:text +17.3
   x86: (for 28/28 boards) spl/u-boot-spl:all -6.1
spl/u-boot-spl:text -6.1 tpl/u-boot-tpl:all -1.5 tpl/u-boot-tpl:text
-1.5

For the particular board mentioned with the problem
(px30-core-ctouch2-px30) it erases the size 40-byte increase:
04: dm: core: Inline a few ofnode functions in SPL
   aarch64: (for 1/1 boards) spl/u-boot-spl:all -84.0 spl/u-boot-spl:text -84.0

 drivers/core/Kconfig  | 16 +
 drivers/core/ofnode.c |  2 ++
 include/dm/ofnode.h   | 56 ++-
 3 files changed, 63 insertions(+), 11 deletions(-)

Applied to u-boot-dm/next, thanks!


[PATCH] cosmetic: fix typo in drivers/usb/Kconfig

2020-12-23 Thread ferlandm
From: Marc Ferland 

This commit fixes a simple typo: sPL --> SPL.

Signed-off-by: Marc Ferland 
---
 drivers/usb/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index fedc0134f5..6e291198ab 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -60,7 +60,7 @@ config DM_USB_GADGET
  mode)
 
 config SPL_DM_USB_GADGET
-   bool "Enable driver model for USB Gadget in sPL"
+   bool "Enable driver model for USB Gadget in SPL"
depends on SPL_DM_USB
help
  Enable driver model for USB Gadget in SPL
-- 
2.25.1



Re: [PATCH v2] riscv: Add support for SPI on Kendryte K210

2020-12-23 Thread Christopher Obbard
Hi Sean,

everything looks good!

On Tue, 22 Dec 2020 at 23:58, Sean Anderson  wrote:
>
> This enables configs necessary for using SPI. The environment is saved to
> the very end of SPI flash. This is unlikely to be overwritten unless the
> entire flash is reprogrammed.
>
> This also supplies a default bootcommand. It loads an image and device tree
> from the first partition of the MMC. This is a minimal/least effort
> bootcmd, so suggestions (especially in the form of patches) are welcome. I
> didn't set up distro boot because I think it is unlikely that any
> general-purpose linux distros will ever be ported to this board.
>
> Signed-off-by: Sean Anderson 

Tested-by: Chrstopher Obbard 

> ---
> Sorry for the late follow-up Jagen.
>
> This patch was previously part of
> https://patchwork.ozlabs.org/project/uboot/list/?series=208443
>
> Changes in v2:
> - Add CONFIG_HUSH_PARSER to run the bootcmd
>   (In my haste I forgot to commit my changes)
>
>  board/sipeed/maix/Kconfig  |  16 ++
>  configs/sipeed_maix_bitm_defconfig |  11 +
>  doc/board/sipeed/maix.rst  | 319 -
>  include/configs/sipeed-maix.h  |   7 +-
>  4 files changed, 301 insertions(+), 52 deletions(-)
>
> diff --git a/board/sipeed/maix/Kconfig b/board/sipeed/maix/Kconfig
> index 4c42dd2087..2cdea8ea81 100644
> --- a/board/sipeed/maix/Kconfig
> +++ b/board/sipeed/maix/Kconfig
> @@ -53,4 +53,20 @@ config BOARD_SPECIFIC_OPTIONS
> imply CMD_GPIO
> imply LED
> imply LED_GPIO
> +   imply SPI
> +   imply DESIGNWARE_SPI
> +   imply SPI_FLASH_GIGADEVICE
> +   imply SPI_FLASH_WINBOND
> +   imply DM_MTD
> +   imply SPI_FLASH_MTD
> +   imply CMD_MTD
> +   imply ENV_IS_IN_SPI_FLASH
> +   imply MMC
> +   imply MMC_BROKEN_CD
> +   imply MMC_SPI
> +   imply CMD_MMC
> +   imply DOS_PARTITION
> +   imply EFI_PARTITION
> +   imply CMD_PART
> +   imply CMD_FS_GENERIC
>  endif
> diff --git a/configs/sipeed_maix_bitm_defconfig 
> b/configs/sipeed_maix_bitm_defconfig
> index 459bf0d530..210848cccf 100644
> --- a/configs/sipeed_maix_bitm_defconfig
> +++ b/configs/sipeed_maix_bitm_defconfig
> @@ -1,8 +1,19 @@
>  CONFIG_RISCV=y
> +CONFIG_ENV_SIZE=0x1000
> +CONFIG_ENV_OFFSET=0xfff000
> +CONFIG_ENV_SECT_SIZE=0x1000
>  CONFIG_TARGET_SIPEED_MAIX=y
>  CONFIG_ARCH_RV64I=y
>  CONFIG_STACK_SIZE=0x10
> +CONFIG_USE_BOOTCOMMAND=y
> +CONFIG_BOOTCOMMAND="run k210_bootcmd"
> +CONFIG_HUSH_PARSER=y
> +CONFIG_MTDIDS_DEFAULT="nor0=spi3:0"
> +CONFIG_MTDPARTS_DEFAULT="nor0:1M(u-boot),0x1000@0xfff000(env)"
>  # CONFIG_NET is not set
>  # CONFIG_INPUT is not set
> +CONFIG_SF_DEFAULT_BUS=3
>  # CONFIG_DM_ETH is not set
> +CONFIG_FS_EXT4=y
> +CONFIG_FS_FAT=y
>  # CONFIG_EFI_LOADER is not set
> diff --git a/doc/board/sipeed/maix.rst b/doc/board/sipeed/maix.rst
> index 92f2d112a9..bf945b3458 100644
> --- a/doc/board/sipeed/maix.rst
> +++ b/doc/board/sipeed/maix.rst
> @@ -70,6 +70,7 @@ console shall be opened immediately. Boot output should 
> look like the following:
>  U-Boot 2020.04-rc2-00087-g2221cc09c1-dirty (Feb 28 2020 - 13:53:09 -0500)
>
>  DRAM:  8 MiB
> +MMC:   spi@5300:slot@0: 0
>  In:serial@3800
>  Out:   serial@3800
>  Err:   serial@3800
> @@ -118,14 +119,115 @@ The value of FW_PAYLOAD_OFFSET must match 
> CONFIG_SYS_TEXT_BASE - 0x8000.
>
>  The file to flash is build/platform/kendryte/k210/firmware/fw_payload.bin.
>
> -Loading Images
> -^^
> +Booting
> +^^^
>
> -To load a kernel, transfer it over serial.
> +The default boot process is to load and boot the files ``/uImage`` and
> +``/k210.dtb`` off of the first partition of the MMC. For Linux, this will 
> result
> +in an output like
>
>  .. code-block:: none
>
> -=> loady 8000 150
> +U-Boot 2020.10-00691-gd1d651d988-dirty (Oct 16 2020 - 17:05:24 -0400)
> +
> +DRAM:  8 MiB
> +MMC:   spi@5300:slot@0: 0
> +Loading Environment from SPIFlash... SF: Detected w25q128fw with page 
> size 256 Bytes, erase size 4 KiB, total 16 MiB
> +OK
> +In:serial@3800
> +Out:   serial@3800
> +Err:   serial@3800
> +Hit any key to stop autoboot:  0
> +1827380 bytes read in 1044 ms (1.7 MiB/s)
> +13428 bytes read in 10 ms (1.3 MiB/s)
> +## Booting kernel from Legacy Image at 8006 ...
> +   Image Name:   linux
> +   Image Type:   RISC-V Linux Kernel Image (uncompressed)
> +   Data Size:1827316 Bytes = 1.7 MiB
> +   Load Address: 8000
> +   Entry Point:  8000
> +   Verifying Checksum ... OK
> +## Flattened Device Tree blob at 8040
> +   Booting using the fdt blob at 0x8040
> +   Loading Kernel Image
> +   Loading Device Tree to 803f9000, end 803ff473 ... OK
> +
> +Starting kernel ...
> +
> +[0.00] Linux version 5.9.0-00021-g6dcc2f0814c6-dirty 
> (sean@godwin) (riscv64-linux-gnu-gcc (GCC) 

[PATCH v2 16/18] dm: Use access methods for dev/uclass private data

2020-12-23 Thread Simon Glass
Most drivers use these access methods but a few do not. Update them.

In some cases the access is not permitted, so mark those with a FIXME tag
for the maintainer to check.

Signed-off-by: Simon Glass 
Acked-by: Andy Shevchenko 
Acked-by: Pratyush Yadav 
---

(no changes since v1)

 arch/arm/cpu/armv7/ls102xa/fdt.c  |  4 ++
 arch/arm/mach-stm32mp/pwr_regulator.c |  3 +-
 arch/x86/cpu/apollolake/uart.c|  3 +-
 arch/x86/cpu/slimbootloader/serial.c  |  2 +-
 drivers/clk/clk.c |  4 +-
 drivers/clk/clk_fixed_rate.c  |  4 +-
 drivers/clk/rockchip/clk_px30.c   |  3 +-
 drivers/clk/rockchip/clk_rk3036.c |  3 +-
 drivers/clk/rockchip/clk_rk3128.c |  3 +-
 drivers/clk/rockchip/clk_rk3188.c |  2 +-
 drivers/clk/rockchip/clk_rk322x.c |  3 +-
 drivers/clk/rockchip/clk_rk3288.c |  2 +-
 drivers/clk/rockchip/clk_rk3308.c |  3 +-
 drivers/clk/rockchip/clk_rk3328.c |  3 +-
 drivers/clk/rockchip/clk_rk3368.c |  3 +-
 drivers/clk/rockchip/clk_rk3399.c |  3 +-
 drivers/clk/rockchip/clk_rv1108.c |  3 +-
 drivers/core/device-remove.c  | 16 
 drivers/ddr/altera/sdram_agilex.c |  2 +-
 drivers/ddr/altera/sdram_gen5.c   |  4 +-
 drivers/ddr/altera/sdram_s10.c|  2 +-
 drivers/ddr/altera/sdram_soc64.c  |  2 +-
 drivers/gpio/dwapb_gpio.c |  2 +-
 drivers/gpio/gpio-uclass.c|  2 +-
 drivers/gpio/hi6220_gpio.c|  2 +-
 drivers/gpio/imx_rgpio2p.c|  5 ++-
 drivers/gpio/lpc32xx_gpio.c   |  2 +-
 drivers/gpio/mt7621_gpio.c|  2 +-
 drivers/gpio/mxs_gpio.c   |  2 +-
 drivers/gpio/omap_gpio.c  |  3 +-
 drivers/gpio/s5p_gpio.c   |  6 +--
 drivers/gpio/sandbox.c|  6 ++-
 drivers/gpio/sunxi_gpio.c |  2 +-
 drivers/gpio/tegra186_gpio.c  |  6 +--
 drivers/gpio/tegra_gpio.c |  6 +--
 drivers/misc/altera_sysid.c   |  2 +-
 drivers/misc/cros_ec_sandbox.c|  4 +-
 drivers/misc/fs_loader.c  |  6 +--
 drivers/misc/vexpress_config.c|  2 +-
 drivers/mmc/arm_pl180_mmci.c  |  6 +--
 drivers/mmc/mxsmmc.c  |  2 +-
 drivers/mmc/octeontx_hsmmc.c  | 17 ++---
 drivers/mux/mmio.c|  3 +-
 drivers/net/eth-phy-uclass.c  |  4 +-
 drivers/net/fm/eth.c  | 22 +--
 drivers/net/fsl_mcdmafec.c| 10 ++---
 drivers/net/mcffec.c  | 12 +++---
 drivers/net/mcfmii.c  |  8 
 drivers/net/pfe_eth/pfe_eth.c |  2 +-
 drivers/net/sunxi_emac.c  |  2 +-
 drivers/net/tsec.c| 46 +--
 drivers/net/xilinx_emaclite.c |  2 +-
 drivers/pci/pci-emul-uclass.c |  4 +-
 drivers/pci/pci-uclass.c  |  8 ++--
 drivers/pinctrl/pinctrl-qe-io.c   |  4 +-
 drivers/pinctrl/pinctrl-single.c  |  6 +--
 drivers/power/regulator/da9063.c  | 24 ++--
 drivers/power/regulator/pbias_regulator.c |  3 +-
 drivers/remoteproc/rproc-uclass.c |  4 +-
 drivers/reset/reset-mediatek.c|  3 +-
 drivers/reset/reset-rockchip.c|  3 +-
 drivers/reset/reset-sifive.c  |  3 +-
 drivers/reset/reset-sunxi.c   |  3 +-
 drivers/serial/altera_jtag_uart.c |  8 ++--
 drivers/serial/altera_uart.c  |  8 ++--
 drivers/serial/atmel_usart.c  |  2 +-
 drivers/serial/ns16550.c  |  4 +-
 drivers/serial/sandbox.c  |  6 +--
 drivers/serial/serial_arc.c   |  8 ++--
 drivers/serial/serial_linflexuart.c   |  2 +-
 drivers/serial/serial_lpuart.c| 10 ++---
 drivers/serial/serial_mcf.c   | 10 ++---
 drivers/serial/serial_meson.c | 12 +++---
 drivers/serial/serial_mxc.c   | 12 +++---
 drivers/serial/serial_omap.c  |  2 +-
 drivers/serial/serial_pxa.c   | 10 ++---
 drivers/serial/serial_rockchip.c  |  3 +-
 drivers/serial/serial_s5p.c   | 12 +++---
 drivers/spi/cadence_qspi.c| 12 +++---
 drivers/spi/cf_spi.c  |  2 +-
 drivers/spi/davinci_spi.c |  4 +-
 drivers/spi/designware_spi.c  |  4 +-
 drivers/spi/exynos_spi.c  |  4 +-
 drivers/spi/fsl_dspi.c|  4 +-
 drivers/spi/fsl_espi.c|  2 +-
 drivers/spi/fsl_qspi.c|  2 +-
 drivers/spi/mxs_spi.c |  2 +-
 drivers/spi/pl022_spi.c   |  2 +-
 drivers/spi/rk_spi.c  |  6 +--
 drivers/spi/soft_spi.c|  4 +-
 

Re: [PATCH v2 5/6] mmc: actions: add MMC driver for Actions OWL S700

2020-12-23 Thread André Przywara
On 23/12/2020 12:29, Amit Tomar wrote:
> Hi,
> 
> Thanks again for the detailed review
> 
> +
> 
> >  3 files changed, 407 insertions(+)
> >  create mode 100644 drivers/mmc/owl_mmc.c
> >
> > diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
> > index 14d7913..61f9c67 100644
> > --- a/drivers/mmc/Kconfig
> > +++ b/drivers/mmc/Kconfig
> > @@ -289,6 +289,13 @@ config MMC_MXC
> > 
> >         If unsure, say N.
> > 
> > +config MMC_OWL
> > +     bool "Actions OWL Multimedia Card Interface support"
> > +     depends on ARCH_OWL && DM_MMC && BLK
> > +     help
> > +       This selects the OWL SD/MMC host controller found on board
> > +       based on Actions S700 SoC.
> 
> And S900 as well?
> 
> But as you aware S900 has different DMA requirements, would it be
> okay to claim that this works for S900 as well ?

Well, you tell me! At the moment I don't see much preventing people from
enabling it on the S900, and your compatible string listing in the
driver includes the S900 one.

What are the different DMA requirements? Aren't the controllers the same
as far as we are concerned, for the purpose of MMC?
And even if not, how much would it take to adapt the code?

Cheers,
Andre

> 
> > +
> >  config MMC_MXS
> >       bool "Freescale MXS Multimedia Card Interface support"
> >       depends on MX23 || MX28 || MX6 || MX7
> > diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
> > index 1c849cb..f270f6c 100644
> > --- a/drivers/mmc/Makefile
> > +++ b/drivers/mmc/Makefile
> > @@ -38,6 +38,7 @@ obj-$(CONFIG_MMC_OMAP_HS)           += omap_hsmmc.o
> >  obj-$(CONFIG_MMC_MXC)                        += mxcmmc.o
> >  obj-$(CONFIG_MMC_MXS)                        += mxsmmc.o
> >  obj-$(CONFIG_MMC_OCTEONTX)           += octeontx_hsmmc.o
> > +obj-$(CONFIG_MMC_OWL)                        += owl_mmc.o
> >  obj-$(CONFIG_MMC_PCI)                        += pci_mmc.o
> >  obj-$(CONFIG_PXA_MMC_GENERIC) += pxa_mmc_gen.o
> >  obj-$(CONFIG_$(SPL_TPL_)SUPPORT_EMMC_RPMB) += rpmb.o
> > diff --git a/drivers/mmc/owl_mmc.c b/drivers/mmc/owl_mmc.c
> > new file mode 100644
> > index 000..5c48307
> > --- /dev/null
> > +++ b/drivers/mmc/owl_mmc.c
> > @@ -0,0 +1,399 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Copyright (C) 2020 Amit Singh Tomar  >
> > + *
> > + * Driver for SD/MMC controller present on Actions Semi S700 SoC,
> based
> > + * on Linux Driver "drivers/mmc/host/owl-mmc.c".
> > + *
> > + * Though, there is a bit (BSEL, BUS or DMA Special Channel
> Selection) that
> > + * controls the data transfer from SDx_DAT register either using
> CPU AHB Bus
> > + * or DMA channel, but seems like, it only works correctly using
> external DMA
> > + * channel, and those special bits used in this driver is picked
> from vendor
> > + * source exclusively for MMC/SD.
> > + */
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +/*
> > + * SDC registers
> > + */
> > +#define OWL_REG_SD_EN                   0x
> > +#define OWL_REG_SD_CTL                  0x0004
> > +#define OWL_REG_SD_STATE                0x0008
> > +#define OWL_REG_SD_CMD                  0x000c
> > +#define OWL_REG_SD_ARG                  0x0010
> > +#define OWL_REG_SD_RSPBUF0              0x0014
> > +#define OWL_REG_SD_RSPBUF1              0x0018
> > +#define OWL_REG_SD_RSPBUF2              0x001c
> > +#define OWL_REG_SD_RSPBUF3              0x0020
> > +#define OWL_REG_SD_RSPBUF4              0x0024
> > +#define OWL_REG_SD_DAT                  0x0028
> > +#define OWL_REG_SD_BLK_SIZE             0x002c
> > +#define OWL_REG_SD_BLK_NUM              0x0030
> > +#define OWL_REG_SD_BUF_SIZE             0x0034
> > +
> > +/* SD_EN Bits */
> > +#define OWL_SD_EN_RANE                  BIT(31)
> > +#define OWL_SD_EN_RESE                  BIT(10)
> > +#define OWL_SD_ENABLE                   BIT(7)
> > +#define OWL_SD_EN_BSEL                  BIT(6)
> > +#define OWL_SD_EN_DATAWID(x)            (((x) & 0x3) << 0)
> > +#define OWL_SD_EN_DATAWID_MASK               0x03
> > +
> > +/* SD_CTL Bits */
> > +#define OWL_SD_CTL_TOUTEN               BIT(31)
> > +#define OWL_SD_CTL_DELAY_MSK            GENMASK(23, 16)
> > +#define OWL_SD_CTL_RDELAY(x)            (((x) & 0xf) << 20)
> > +#define OWL_SD_CTL_WDELAY(x)            (((x) & 0xf) << 16)
> > +#define OWL_SD_CTL_TS                   BIT(7)
> > +#define OWL_SD_CTL_LBE                  BIT(6)
> > 

[PATCH v2 20/21] x86: tpl: Remove unwanted devicetree string

2020-12-23 Thread Simon Glass
Update this driver to use of_match_ptr().

This reduces the TPL binary size by about 32 bytes.

Signed-off-by: Simon Glass 
---

(no changes since v1)

 arch/x86/lib/tpl.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/x86/lib/tpl.c b/arch/x86/lib/tpl.c
index 15b0212d190..04ff32277fd 100644
--- a/arch/x86/lib/tpl.c
+++ b/arch/x86/lib/tpl.c
@@ -133,14 +133,16 @@ void spl_board_init(void)
  * for devices, so the TPL BARs continue to be used. Once U-Boot starts it does
  * the auto allocation (after relocation).
  */
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
 static const struct udevice_id tpl_fake_pci_ids[] = {
{ .compatible = "pci-x86" },
{ }
 };
+#endif
 
 U_BOOT_DRIVER(pci_x86) = {
.name   = "pci_x86",
.id = UCLASS_SIMPLE_BUS,
-   .of_match = tpl_fake_pci_ids,
+   .of_match = of_match_ptr(tpl_fake_pci_ids),
 };
 #endif
-- 
2.29.2.729.g45daf8777d-goog



[PATCH v2 18/21] x86: apl: Reduce size for TPL

2020-12-23 Thread Simon Glass
Update various drivers to use of_match_ptr() and to avoid including debug
strings in TPL. Omit the WiFi driver entirely, since it is not used in
TPL.

This reduces the TPL binary size by about 608 bytes.

Signed-off-by: Simon Glass 
---

(no changes since v1)

 arch/x86/cpu/apollolake/lpc.c| 13 -
 arch/x86/cpu/apollolake/pch.c|  4 +++-
 arch/x86/cpu/apollolake/pmc.c|  4 +++-
 arch/x86/cpu/apollolake/uart.c   |  4 +++-
 arch/x86/cpu/intel_common/Makefile   |  2 +-
 arch/x86/cpu/intel_common/itss.c |  4 +++-
 arch/x86/cpu/intel_common/p2sb.c |  4 +++-
 arch/x86/cpu/turbo.c |  5 +
 board/google/chromebook_coral/coral.c|  4 +++-
 drivers/gpio/intel_gpio.c|  4 +++-
 drivers/pinctrl/intel/pinctrl_apl.c  |  4 +++-
 drivers/power/acpi_pmc/acpi-pmc-uclass.c |  4 +++-
 drivers/timer/tsc_timer.c|  4 +++-
 13 files changed, 44 insertions(+), 16 deletions(-)

diff --git a/arch/x86/cpu/apollolake/lpc.c b/arch/x86/cpu/apollolake/lpc.c
index d8e05f6a8f4..e085890d638 100644
--- a/arch/x86/cpu/apollolake/lpc.c
+++ b/arch/x86/cpu/apollolake/lpc.c
@@ -81,10 +81,11 @@ int lpc_open_pmio_window(uint base, uint size)
 
lgir_reg_num = find_unused_pmio_window();
if (lgir_reg_num < 0) {
-   log_err("LPC: Cannot open IO window: %lx size %lx\n",
-   bridge_base, size - bridged_size);
-   log_err("No more IO windows\n");
-
+   if (spl_phase() > PHASE_TPL) {
+   log_err("LPC: Cannot open IO window: %lx size 
%lx\n",
+   bridge_base, size - bridged_size);
+   log_err("No more IO windows\n");
+   }
return -ENOSPC;
}
lgir_reg_offset = LPC_GENERIC_IO_RANGE(lgir_reg_num);
@@ -127,15 +128,17 @@ struct acpi_ops apl_lpc_acpi_ops = {
.inject_dsdt= southbridge_inject_dsdt,
 };
 
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
 static const struct udevice_id apl_lpc_ids[] = {
{ .compatible = "intel,apl-lpc" },
{ }
 };
+#endif
 
 /* All pads are LPC already configured by the hostbridge, so no probing here */
 U_BOOT_DRIVER(intel_apl_lpc) = {
.name   = "intel_apl_lpc",
.id = UCLASS_LPC,
-   .of_match   = apl_lpc_ids,
+   .of_match   = of_match_ptr(apl_lpc_ids),
ACPI_OPS_PTR(_lpc_acpi_ops)
 };
diff --git a/arch/x86/cpu/apollolake/pch.c b/arch/x86/cpu/apollolake/pch.c
index d9832ff2496..39d6ad5ed49 100644
--- a/arch/x86/cpu/apollolake/pch.c
+++ b/arch/x86/cpu/apollolake/pch.c
@@ -23,14 +23,16 @@ static const struct pch_ops apl_pch_ops = {
.set_spi_protect = apl_set_spi_protect,
 };
 
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
 static const struct udevice_id apl_pch_ids[] = {
{ .compatible = "intel,apl-pch" },
{ }
 };
+#endif
 
 U_BOOT_DRIVER(intel_apl_pch) = {
.name   = "intel_apl_pch",
.id = UCLASS_PCH,
-   .of_match   = apl_pch_ids,
+   .of_match   = of_match_ptr(apl_pch_ids),
.ops= _pch_ops,
 };
diff --git a/arch/x86/cpu/apollolake/pmc.c b/arch/x86/cpu/apollolake/pmc.c
index c40065ab8cf..e033baf1205 100644
--- a/arch/x86/cpu/apollolake/pmc.c
+++ b/arch/x86/cpu/apollolake/pmc.c
@@ -212,15 +212,17 @@ static const struct acpi_pmc_ops apl_pmc_ops = {
.global_reset_set_enable = apl_global_reset_set_enable,
 };
 
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
 static const struct udevice_id apl_pmc_ids[] = {
{ .compatible = "intel,apl-pmc" },
{ }
 };
+#endif
 
 U_BOOT_DRIVER(intel_apl_pmc) = {
.name   = "intel_apl_pmc",
.id = UCLASS_ACPI_PMC,
-   .of_match   = apl_pmc_ids,
+   .of_match   = of_match_ptr(apl_pmc_ids),
.of_to_plat = apl_pmc_ofdata_to_uc_plat,
.probe  = apl_pmc_probe,
.ops= _pmc_ops,
diff --git a/arch/x86/cpu/apollolake/uart.c b/arch/x86/cpu/apollolake/uart.c
index e523d85b1b4..69e5899235b 100644
--- a/arch/x86/cpu/apollolake/uart.c
+++ b/arch/x86/cpu/apollolake/uart.c
@@ -118,15 +118,17 @@ static int apl_ns16550_of_to_plat(struct udevice *dev)
return 0;
 }
 
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
 static const struct udevice_id apl_ns16550_serial_ids[] = {
{ .compatible = "intel,apl-ns16550" },
{ },
 };
+#endif
 
 U_BOOT_DRIVER(intel_apl_ns16550) = {
.name   = "intel_apl_ns16550",
.id = UCLASS_SERIAL,
-   .of_match = apl_ns16550_serial_ids,
+   .of_match = of_match_ptr(apl_ns16550_serial_ids),
.plat_auto  = sizeof(struct ns16550_plat),
.priv_auto  = sizeof(struct ns16550),
.ops= _serial_ops,
diff --git a/arch/x86/cpu/intel_common/Makefile 

[PATCH v2 06/21] test: Move some test drivers into their own file

2020-12-23 Thread Simon Glass
At present several test drivers are part of the test file itself. Some of
these are useful for of-platdata tests. Separate them out so we can use
them for other things also.

A few adjustments are needed so this driver can build for sandbox_spl as
well.

Signed-off-by: Simon Glass 
---

(no changes since v1)

 drivers/misc/Kconfig|   9 ++
 drivers/misc/Makefile   |   1 +
 drivers/misc/test_drv.c | 230 
 include/dm/test.h   |  18 
 include/test/test.h |   9 ++
 test/dm/bus.c   | 105 +-
 test/dm/test-fdt.c  | 120 -
 7 files changed, 271 insertions(+), 221 deletions(-)
 create mode 100644 drivers/misc/test_drv.c

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 29432ae7eb4..7d2a2997797 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -343,6 +343,15 @@ config TEGRA186_BPMP
  can make requests to the BPMP. This driver is similar to an MFD
  driver in the Linux kernel.
 
+config TEST_DRV
+   bool "Enable support for test drivers"
+   default y if SANDBOX
+   help
+ This enables drivers and uclasses that provides a way of testing the
+ operations of memory allocation and driver/uclass methods in driver
+ model. This should only be enabled for testing as it is not useful for
+ anything else.
+
 config TWL4030_LED
bool "Enable TWL4030 LED controller"
help
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 947bd3a647f..d7372037045 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -67,6 +67,7 @@ obj-$(CONFIG_STM32_RCC) += stm32_rcc.o
 obj-$(CONFIG_SYS_DPAA_QBMAN) += fsl_portals.o
 obj-$(CONFIG_TEGRA186_BPMP) += tegra186_bpmp.o
 obj-$(CONFIG_TEGRA_CAR) += tegra_car.o
+obj-$(CONFIG_TEST_DRV) += test_drv.o
 obj-$(CONFIG_TWL4030_LED) += twl4030_led.o
 obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress_config.o
 obj-$(CONFIG_WINBOND_W83627) += winbond_w83627.o
diff --git a/drivers/misc/test_drv.c b/drivers/misc/test_drv.c
new file mode 100644
index 000..a163312b108
--- /dev/null
+++ b/drivers/misc/test_drv.c
@@ -0,0 +1,230 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2014 Google, Inc
+ */
+
+#include 
+#include 
+#include 
+
+/* Records the last testbus device that was removed */
+static struct udevice *testbus_removed;
+
+struct udevice *testbus_get_clear_removed(void)
+{
+   struct udevice *removed = testbus_removed;
+
+   testbus_removed = NULL;
+
+   return removed;
+}
+
+static int testbus_drv_probe(struct udevice *dev)
+{
+   if (!CONFIG_IS_ENABLED(OF_PLATDATA)) {
+   int ret;
+
+   ret = dm_scan_fdt_dev(dev);
+   if (ret)
+   return ret;
+   }
+
+   return 0;
+}
+
+static int testbus_child_post_bind(struct udevice *dev)
+{
+   struct dm_test_parent_plat *plat;
+
+   plat = dev_get_parent_plat(dev);
+   plat->bind_flag = 1;
+   plat->uclass_bind_flag = 2;
+
+   return 0;
+}
+
+static int testbus_child_pre_probe(struct udevice *dev)
+{
+   struct dm_test_parent_data *parent_data = dev_get_parent_priv(dev);
+
+   parent_data->flag += TEST_FLAG_CHILD_PROBED;
+
+   return 0;
+}
+
+static int testbus_child_pre_probe_uclass(struct udevice *dev)
+{
+   struct dm_test_priv *priv = dev_get_priv(dev);
+
+   priv->uclass_flag++;
+
+   return 0;
+}
+
+static int testbus_child_post_probe_uclass(struct udevice *dev)
+{
+   struct dm_test_priv *priv = dev_get_priv(dev);
+
+   priv->uclass_postp++;
+
+   return 0;
+}
+
+static int testbus_child_post_remove(struct udevice *dev)
+{
+   struct dm_test_parent_data *parent_data = dev_get_parent_priv(dev);
+
+   parent_data->flag += TEST_FLAG_CHILD_REMOVED;
+   testbus_removed = dev;
+
+   return 0;
+}
+
+static const struct udevice_id testbus_ids[] = {
+   {
+   .compatible = "denx,u-boot-test-bus",
+   .data = DM_TEST_TYPE_FIRST },
+   { }
+};
+
+U_BOOT_DRIVER(testbus_drv) = {
+   .name   = "testbus_drv",
+   .of_match   = testbus_ids,
+   .id = UCLASS_TEST_BUS,
+   .probe  = testbus_drv_probe,
+   .child_post_bind = testbus_child_post_bind,
+   .priv_auto  = sizeof(struct dm_test_priv),
+   .plat_auto  = sizeof(struct dm_test_pdata),
+   .per_child_auto = sizeof(struct dm_test_parent_data),
+   .per_child_plat_auto= sizeof(struct dm_test_parent_plat),
+   .child_pre_probe = testbus_child_pre_probe,
+   .child_post_remove = testbus_child_post_remove,
+};
+
+UCLASS_DRIVER(testbus) = {
+   .name   = "testbus",
+   .id = UCLASS_TEST_BUS,
+   .flags  = DM_UC_FLAG_SEQ_ALIAS,
+   .child_pre_probe = testbus_child_pre_probe_uclass,
+   .child_post_probe = testbus_child_post_probe_uclass,
+};
+
+static int testfdt_drv_ping(struct udevice *dev, int 

[PATCH v2 21/21] x86: Fix header guard in asm/pmu.h

2020-12-23 Thread Simon Glass
This has the wrong name. Fix it.

Signed-off-by: Simon Glass 
---

(no changes since v1)

 arch/x86/include/asm/pmu.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/pmu.h b/arch/x86/include/asm/pmu.h
index b76bdf64a30..818e80881ec 100644
--- a/arch/x86/include/asm/pmu.h
+++ b/arch/x86/include/asm/pmu.h
@@ -2,9 +2,9 @@
 /*
  * Copyright (c) 2017 Intel Corporation
  */
-#ifndef _X86_ASM_PMU_IPC_H_
-#define _X86_ASM_PMU_IPC_H_
+#ifndef _X86_ASM_PMU_H_
+#define _X86_ASM_PMU_H_
 
 int pmu_turn_power(unsigned int lss, bool on);
 
-#endif /* _X86_ASM_PMU_IPC_H_ */
+#endif /* _X86_ASM_PMU_H_ */
-- 
2.29.2.729.g45daf8777d-goog



[PATCH v2 19/21] x86: pinctrl: Drop unlikely error messages from TPL

2020-12-23 Thread Simon Glass
These errors are only really for development purposes. Drop them to reduce
the size of TPL. The error numbers are still reported.

This reduces the TPL binary size on coral by about 160 bytes.

Signed-off-by: Simon Glass 
---

(no changes since v1)

 drivers/pinctrl/intel/pinctrl.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/pinctrl/intel/pinctrl.c b/drivers/pinctrl/intel/pinctrl.c
index 9f96505dd5a..987a56b715e 100644
--- a/drivers/pinctrl/intel/pinctrl.c
+++ b/drivers/pinctrl/intel/pinctrl.c
@@ -274,7 +274,9 @@ static int pinctrl_configure_itss(struct udevice *dev,
irq = pcr_read32(dev, PAD_CFG1_OFFSET(pad_cfg_offset));
irq &= PAD_CFG1_IRQ_MASK;
if (!irq) {
-   log_err("GPIO %u doesn't support APIC routing\n", cfg->pad);
+   if (spl_phase() > PHASE_TPL)
+   log_err("GPIO %u doesn't support APIC routing\n",
+   cfg->pad);
 
return -EPROTONOSUPPORT;
}
@@ -314,7 +316,8 @@ static int pinctrl_pad_reset_config_override(const struct 
pad_community *comm,
return config_value;
}
}
-   log_err("Logical-to-Chipset mapping not found\n");
+   if (spl_phase() > PHASE_TPL)
+   log_err("Logical-to-Chipset mapping not found\n");
 
return -ENOENT;
 }
@@ -620,7 +623,9 @@ int intel_pinctrl_of_to_plat(struct udevice *dev,
struct intel_pinctrl_priv *priv = dev_get_priv(dev);
 
if (!comm) {
-   log_err("Cannot find community for pid %d\n", pplat->pid);
+   if (spl_phase() > PHASE_TPL)
+   log_err("Cannot find community for pid %d\n",
+   pplat->pid);
return -EDOM;
}
priv->comm = comm;
-- 
2.29.2.729.g45daf8777d-goog



[PATCH v2 16/21] x86: coral: Move fsp-m settings to a subnode

2020-12-23 Thread Simon Glass
At present these settings are in the node for host-bridge and so are
visible in TPL as well as SPL. But they are only used for SPL.

Move them to a subnode so that TPL does not included them.

Signed-off-by: Simon Glass 
---

(no changes since v1)

 arch/x86/cpu/apollolake/fsp_m.c   | 5 -
 arch/x86/dts/chromebook_coral.dts | 5 +
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/x86/cpu/apollolake/fsp_m.c b/arch/x86/cpu/apollolake/fsp_m.c
index cef937573b0..c6be707e4ea 100644
--- a/arch/x86/cpu/apollolake/fsp_m.c
+++ b/arch/x86/cpu/apollolake/fsp_m.c
@@ -32,7 +32,10 @@ int fspm_update_config(struct udevice *dev, struct fspm_upd 
*upd)
 
node = dev_ofnode(dev);
if (!ofnode_valid(node))
-   return log_msg_ret("fsp-m settings", -ENOENT);
+   return log_msg_ret("node", -ENOENT);
+   node = ofnode_find_subnode(node, "fsp-m");
+   if (!ofnode_valid(node))
+   return log_msg_ret("fspm", -ENOENT);
 
ret = fsp_m_update_config_from_dtb(node, cfg);
if (ret)
diff --git a/arch/x86/dts/chromebook_coral.dts 
b/arch/x86/dts/chromebook_coral.dts
index d66e128ae62..3c8fdf23809 100644
--- a/arch/x86/dts/chromebook_coral.dts
+++ b/arch/x86/dts/chromebook_coral.dts
@@ -174,6 +174,9 @@
 */
fsp_s: fsp-s {
};
+   fsp_m: fsp-m {
+   u-boot,dm-spl;
+   };
 
nhlt {
intel,dmic-channels = <4>;
@@ -650,7 +653,9 @@
PAD_CFG_NF(LPC_CLKRUNB, UP_20K, DEEP, NF1) /* LPC_CLKRUN_N */
PAD_CFG_NF(LPC_FRAMEB, NATIVE, DEEP, NF1) /* LPC_FRAME_N */
>;
+};
 
+_m {
fspm,package = ;
fspm,profile = ;
fspm,memory-down = ;
-- 
2.29.2.729.g45daf8777d-goog



[PATCH v2 17/21] x86: apl: Update hostbridge to remove unwanted TPL code

2020-12-23 Thread Simon Glass
At present several strings from this file appear in the TPL binary. Add
preprocessor checks to drop them.

This reduces the TPL binary size by about 128 bytes.

Signed-off-by: Simon Glass 
---

(no changes since v1)

 arch/x86/cpu/apollolake/hostbridge.c | 14 +-
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/arch/x86/cpu/apollolake/hostbridge.c 
b/arch/x86/cpu/apollolake/hostbridge.c
index e4674f3788a..9ec2309d086 100644
--- a/arch/x86/cpu/apollolake/hostbridge.c
+++ b/arch/x86/cpu/apollolake/hostbridge.c
@@ -60,6 +60,7 @@ struct apl_hostbridge_plat {
pci_dev_t bdf;
 };
 
+#if CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE)
 static const struct nhlt_format_config dmic_1ch_formats[] = {
/* 48 KHz 16-bits per sample. */
{
@@ -155,6 +156,7 @@ static const struct nhlt_endp_descriptor 
dmic_4ch_descriptors[] = {
.num_formats = ARRAY_SIZE(dmic_4ch_formats),
},
 };
+#endif
 
 static int apl_hostbridge_early_init_pinctrl(struct udevice *dev)
 {
@@ -283,7 +285,7 @@ static int apl_acpi_hb_get_name(const struct udevice *dev, 
char *out_name)
return acpi_copy_name(out_name, "RHUB");
 }
 
-#ifdef CONFIG_GENERATE_ACPI_TABLE
+#if CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE)
 static int apl_acpi_hb_write_tables(const struct udevice *dev,
struct acpi_ctx *ctx)
 {
@@ -322,7 +324,6 @@ static int apl_acpi_hb_write_tables(const struct udevice 
*dev,
 
return 0;
 }
-#endif
 
 static int apl_acpi_setup_nhlt(const struct udevice *dev, struct acpi_ctx *ctx)
 {
@@ -347,6 +348,7 @@ static int apl_acpi_setup_nhlt(const struct udevice *dev, 
struct acpi_ctx *ctx)
 
return log_msg_ret("channels", -EINVAL);
 }
+#endif
 
 static int apl_hostbridge_remove(struct udevice *dev)
 {
@@ -385,21 +387,23 @@ ulong sa_get_tseg_base(struct udevice *dev)
 
 struct acpi_ops apl_hostbridge_acpi_ops = {
.get_name   = apl_acpi_hb_get_name,
-#ifdef CONFIG_GENERATE_ACPI_TABLE
+#if CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE)
.write_tables   = apl_acpi_hb_write_tables,
-#endif
.setup_nhlt = apl_acpi_setup_nhlt,
+#endif
 };
 
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
 static const struct udevice_id apl_hostbridge_ids[] = {
{ .compatible = "intel,apl-hostbridge" },
{ }
 };
+#endif
 
 U_BOOT_DRIVER(intel_apl_hostbridge) = {
.name   = "intel_apl_hostbridge",
.id = UCLASS_NORTHBRIDGE,
-   .of_match   = apl_hostbridge_ids,
+   .of_match   = of_match_ptr(apl_hostbridge_ids),
.of_to_plat = apl_hostbridge_of_to_plat,
.probe  = apl_hostbridge_probe,
.remove = apl_hostbridge_remove,
-- 
2.29.2.729.g45daf8777d-goog



[PATCH v2 12/21] dtoc: Scan drivers for available information

2020-12-23 Thread Simon Glass
At present we simply record the name of a driver parsed from its
implementation file. We also need to get the uclass and a few other
things so we can instantiate devices at build time. Add support for
collecting this information. This requires parsing each driver file.

Signed-off-by: Simon Glass 
---

(no changes since v1)

 tools/dtoc/dtb_platdata.py | 171 ++---
 tools/dtoc/test_dtoc.py| 101 +-
 2 files changed, 258 insertions(+), 14 deletions(-)

diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index 5b1bb7e5fd9..51c4d1cae00 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -69,15 +69,26 @@ class Driver:
 
 Attributes:
 name: Name of driver. For U_BOOT_DRIVER(x) this is 'x'
+uclass_id: Name of uclass (e.g. 'UCLASS_I2C')
+compat: Driver data for each compatible string:
+key: Compatible string, e.g. 'rockchip,rk3288-grf'
+value: Driver data, e,g, 'ROCKCHIP_SYSCON_GRF', or None
 """
-def __init__(self, name):
+def __init__(self, name, uclass_id, compat):
 self.name = name
+self.uclass_id = uclass_id
+self.compat = compat
+self.priv_size = 0
 
 def __eq__(self, other):
-return self.name == other.name
+return (self.name == other.name and
+self.uclass_id == other.uclass_id and
+self.compat == other.compat and
+self.priv_size == other.priv_size)
 
 def __repr__(self):
-return "Driver(name='%s')" % self.name
+return ("Driver(name='%s', uclass_id='%s', compat=%s, priv_size=%s)" %
+(self.name, self.uclass_id, self.compat, self.priv_size))
 
 
 def conv_name_to_c(name):
@@ -180,6 +191,12 @@ class DtbPlatdata():
 U_BOOT_DRIVER_ALIAS(driver_alias, driver_name)
 value: Driver name declared with U_BOOT_DRIVER(driver_name)
 _drivers_additional: List of additional drivers to use during scanning
+_of_match: Dict holding information about compatible strings
+key: Name of struct udevice_id variable
+value: Dict of compatible info in that variable:
+   key: Compatible string, e.g. 'rockchip,rk3288-grf'
+   value: Driver data, e,g, 'ROCKCHIP_SYSCON_GRF', or None
+_compat_to_driver: Maps compatible strings to Driver
 """
 def __init__(self, dtb_fname, include_disabled, warning_disabled,
  drivers_additional=None):
@@ -193,6 +210,8 @@ class DtbPlatdata():
 self._drivers = {}
 self._driver_aliases = {}
 self._drivers_additional = drivers_additional or []
+self._of_match = {}
+self._compat_to_driver = {}
 
 def get_normalized_compat_name(self, node):
 """Get a node's normalized compat name
@@ -331,10 +350,144 @@ class DtbPlatdata():
 return PhandleInfo(max_args, args)
 return None
 
+def _parse_driver(self, fname, buff):
+"""Parse a C file to extract driver information contained within
+
+This parses U_BOOT_DRIVER() structs to obtain various pieces of useful
+information.
+
+It updates the following members:
+_drivers - updated with new Driver records for each driver found
+in the file
+_of_match - updated with each compatible string found in the file
+_compat_to_driver - Maps compatible string to Driver
+
+Args:
+fname (str): Filename being parsed (used for warnings)
+buff (str): Contents of file
+
+Raises:
+ValueError: Compatible variable is mentioned in .of_match in
+U_BOOT_DRIVER() but not found in the file
+"""
+# Dict holding information about compatible strings collected in this
+# function so far
+#key: Name of struct udevice_id variable
+#value: Dict of compatible info in that variable:
+#   key: Compatible string, e.g. 'rockchip,rk3288-grf'
+#   value: Driver data, e,g, 'ROCKCHIP_SYSCON_GRF', or None
+of_match = {}
+
+# Dict holding driver information collected in this function so far
+#key: Driver name (C name as in U_BOOT_DRIVER(xxx))
+#value: Driver
+drivers = {}
+
+# Collect the driver name (None means not found yet)
+driver_name = None
+re_driver = re.compile(r'U_BOOT_DRIVER\((.*)\)')
+
+# Collect the uclass ID, e.g. 'UCLASS_SPI'
+uclass_id = None
+re_id = re.compile(r'\s*\.id\s*=\s*(UCLASS_[A-Z0-9_]+)')
+
+# Collect the compatible string, e.g. 'rockchip,rk3288-grf'
+compat = None
+re_compat = re.compile(r'{\s*.compatible\s*=\s*"(.*)"\s*'
+   r'(,\s*.data\s*=\s*(.*))?\s*},')
+
+# This is a dict of compatible strings that were found:
+#

[PATCH v2 15/21] x86: Move call64 into its own section

2020-12-23 Thread Simon Glass
When this code is not used (e.g. by TPL) we want it to be excluded from
the image. Put it in its own section so that this happens.

Signed-off-by: Simon Glass 
---

(no changes since v1)

 arch/x86/cpu/i386/call64.S | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/x86/cpu/i386/call64.S b/arch/x86/cpu/i386/call64.S
index 275063c4af8..0ffc1006bbf 100644
--- a/arch/x86/cpu/i386/call64.S
+++ b/arch/x86/cpu/i386/call64.S
@@ -11,6 +11,7 @@
 #include 
 
 .code32
+.section .text_call64
 .globl cpu_call64
 cpu_call64:
/*
-- 
2.29.2.729.g45daf8777d-goog



[PATCH v2 14/21] x86: apl: Use const for driver operations

2020-12-23 Thread Simon Glass
Update these declarations to const to ensure that the data ends up in the
rodata section.

Signed-off-by: Simon Glass 
---

(no changes since v1)

 arch/x86/cpu/apollolake/pmc.c| 2 +-
 arch/x86/cpu/intel_common/p2sb.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/cpu/apollolake/pmc.c b/arch/x86/cpu/apollolake/pmc.c
index 290b2cb3e71..c40065ab8cf 100644
--- a/arch/x86/cpu/apollolake/pmc.c
+++ b/arch/x86/cpu/apollolake/pmc.c
@@ -205,7 +205,7 @@ static int apl_pmc_probe(struct udevice *dev)
return 0;
 }
 
-static struct acpi_pmc_ops apl_pmc_ops = {
+static const struct acpi_pmc_ops apl_pmc_ops = {
.init   = apl_pmc_fill_power_state,
.prev_sleep_state   = apl_prev_sleep_state,
.disable_tco= apl_disable_tco,
diff --git a/arch/x86/cpu/intel_common/p2sb.c b/arch/x86/cpu/intel_common/p2sb.c
index e6edab0b056..3765eeeab0d 100644
--- a/arch/x86/cpu/intel_common/p2sb.c
+++ b/arch/x86/cpu/intel_common/p2sb.c
@@ -180,7 +180,7 @@ static int p2sb_child_post_bind(struct udevice *dev)
return 0;
 }
 
-struct p2sb_ops p2sb_ops = {
+static const struct p2sb_ops p2sb_ops = {
.set_hide   = intel_p2sb_set_hide,
 };
 
-- 
2.29.2.729.g45daf8777d-goog



[PATCH v2 13/21] dtoc: Allow use of the of_match_ptr() macro

2020-12-23 Thread Simon Glass
Update the regex for the of_match member to allow of_match_ptr() so it
matches both:

.of_match   = apl_hostbridge_ids,
and
.of_match   = of_match_ptr(apl_hostbridge_ids),

Without this, dtoc emits warnings and cannot find the drivers.

Signed-off-by: Simon Glass 
---

(no changes since v1)

 tools/dtoc/dtb_platdata.py |  5 +++--
 tools/dtoc/test_dtoc.py| 20 
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index 51c4d1cae00..9c2bd18f5a4 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -408,7 +408,8 @@ class DtbPlatdata():
 re_ids = re.compile(r'struct udevice_id (.*)\[\]\s*=')
 
 # Matches the references to the udevice_id list
-re_of_match = re.compile(r'\.of_match\s*=\s*([a-z0-9_]+),')
+re_of_match = re.compile(
+r'\.of_match\s*=\s*(of_match_ptr\()?([a-z0-9_]+)(\))?,')
 
 # Matches the header/size information for priv
 re_priv = re.compile(r'^\s*DM_PRIV\((.*)\)$')
@@ -431,7 +432,7 @@ class DtbPlatdata():
 if id_m:
 uclass_id = id_m.group(1)
 elif id_of_match:
-compat = id_of_match.group(1)
+compat = id_of_match.group(2)
 elif '};' in line:
 if uclass_id and compat:
 if compat not in of_match:
diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py
index 89192797781..1fd981f51e1 100755
--- a/tools/dtoc/test_dtoc.py
+++ b/tools/dtoc/test_dtoc.py
@@ -1009,3 +1009,23 @@ U_BOOT_DRIVER(i2c_tegra) = {
 self.assertIn(
 "file.c: Unknown compatible var 'tegra_i2c_ids' (found: 
tegra_i2c_ids2)",
 str(e.exception))
+
+def testOfmatch(self):
+"""Test detection of of_match_ptr() member"""
+buff = '''
+static const struct udevice_id tegra_i2c_ids[] = {
+   { .compatible = "nvidia,tegra114-i2c", .data = TYPE_114 },
+   { }
+};
+
+U_BOOT_DRIVER(i2c_tegra) = {
+   .name   = "i2c_tegra",
+   .id = UCLASS_I2C,
+   .of_match = of_match_ptr(tegra_i2c_ids),
+};
+'''
+dpd = dtb_platdata.DtbPlatdata(None, False, False)
+dpd._parse_driver('file.c', buff)
+self.assertIn('i2c_tegra', dpd._drivers)
+drv = dpd._drivers['i2c_tegra']
+self.assertEqual('i2c_tegra', drv.name)
-- 
2.29.2.729.g45daf8777d-goog



[PATCH v2 11/21] dtoc: Convert _drivers to a dict

2020-12-23 Thread Simon Glass
At present this member holds a simple list of driver names. Update it to
be a dict of DriverInfo, with the name being the key. This will allow more
information to be added about each driver, in future patches.

Signed-off-by: Simon Glass 
---

Changes in v2:
- Rename DriverInfo to Driver
- Add a test for the new code and a comment for Driver

 tools/dtoc/dtb_platdata.py | 26 ++
 tools/dtoc/test_dtoc.py| 10 ++
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index 1d89f77a00b..5b1bb7e5fd9 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -64,6 +64,22 @@ PhandleInfo = collections.namedtuple('PhandleInfo', 
['max_args', 'args'])
 PhandleLink = collections.namedtuple('PhandleLink', ['var_node', 'dev_name'])
 
 
+class Driver:
+"""Information about a driver in U-Boot
+
+Attributes:
+name: Name of driver. For U_BOOT_DRIVER(x) this is 'x'
+"""
+def __init__(self, name):
+self.name = name
+
+def __eq__(self, other):
+return self.name == other.name
+
+def __repr__(self):
+return "Driver(name='%s')" % self.name
+
+
 def conv_name_to_c(name):
 """Convert a device-tree name to a C identifier
 
@@ -156,7 +172,9 @@ class DtbPlatdata():
 _outfile: The current output file (sys.stdout or a real file)
 _warning_disabled: true to disable warnings about driver names not 
found
 _lines: Stashed list of output lines for outputting in the future
-_drivers: List of valid driver names found in drivers/
+_drivers: Dict of valid driver names found in drivers/
+key: Driver name
+value: Driver for that driver
 _driver_aliases: Dict that holds aliases for driver names
 key: Driver alias declared with
 U_BOOT_DRIVER_ALIAS(driver_alias, driver_name)
@@ -172,7 +190,7 @@ class DtbPlatdata():
 self._outfile = None
 self._warning_disabled = warning_disabled
 self._lines = []
-self._drivers = []
+self._drivers = {}
 self._driver_aliases = {}
 self._drivers_additional = drivers_additional or []
 
@@ -196,7 +214,7 @@ class DtbPlatdata():
 compat_list_c = get_compat_name(node)
 
 for compat_c in compat_list_c:
-if not compat_c in self._drivers:
+if not compat_c in self._drivers.keys():
 compat_c = self._driver_aliases.get(compat_c)
 if not compat_c:
 continue
@@ -334,7 +352,7 @@ class DtbPlatdata():
 drivers = re.findall(r'U_BOOT_DRIVER\((.*)\)', buff)
 
 for driver in drivers:
-self._drivers.append(driver)
+self._drivers[driver] = Driver(driver)
 
 # The following re will search for driver aliases declared as
 # U_BOOT_DRIVER_ALIAS(alias, driver_name)
diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py
index 49ab75b85da..c76942c9e2d 100755
--- a/tools/dtoc/test_dtoc.py
+++ b/tools/dtoc/test_dtoc.py
@@ -906,3 +906,13 @@ U_BOOT_DEVICE(spl_test2) = {
 with test_util.capture_sys_output() as (stdout, stderr):
 dtb_platdata.run_steps(['struct'], dtb_file, False, output, True,
[driver_fn])
+
+def testDriver(self):
+"""Test the Driver class"""
+drv1 = dtb_platdata.Driver('fred')
+drv2 = dtb_platdata.Driver('mary')
+drv3 = dtb_platdata.Driver('fred')
+self.assertEqual("Driver(name='fred')", str(drv1))
+self.assertEqual(drv1, drv3)
+self.assertNotEqual(drv1, drv2)
+self.assertNotEqual(drv2, drv3)
-- 
2.29.2.729.g45daf8777d-goog



[PATCH v2 10/21] dtoc: Output the struct values in a separate function

2020-12-23 Thread Simon Glass
Reduce the length of output_node() futher by moving the struct-output
functionality into a two separate functions.

Signed-off-by: Simon Glass 
---

(no changes since v1)

 tools/dtoc/dtb_platdata.py | 50 ++
 1 file changed, 34 insertions(+), 16 deletions(-)

diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index 2d701ac24da..1d89f77a00b 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -652,6 +652,39 @@ class DtbPlatdata():
 self.buf('};\n')
 self.buf('\n')
 
+def _output_prop(self, node, prop):
+"""Output a line containing the value of a struct member
+
+Args:
+node (Node): Node being output
+prop (Prop): Prop object to output
+"""
+if prop.name in PROP_IGNORE_LIST or prop.name[0] == '#':
+return
+member_name = conv_name_to_c(prop.name)
+self.buf('\t%s= ' % tab_to(3, '.' + member_name))
+
+# Special handling for lists
+if isinstance(prop.value, list):
+self._output_list(node, prop)
+else:
+self.buf(get_value(prop.type, prop.value))
+self.buf(',\n')
+
+def _output_values(self, var_name, struct_name, node):
+"""Output the definition of a device's struct values
+
+Args:
+var_name (str): C name for the node
+struct_name (str): Name for the dt struct associated with the node
+node (Node): Node being output
+"""
+self.buf('static struct %s%s %s%s = {\n' %
+ (STRUCT_PREFIX, struct_name, VAL_PREFIX, var_name))
+for pname in sorted(node.props):
+self._output_prop(node, node.props[pname])
+self.buf('};\n')
+
 def output_node(self, node):
 """Output the C code for a node
 
@@ -661,23 +694,8 @@ class DtbPlatdata():
 struct_name, _ = self.get_normalized_compat_name(node)
 var_name = conv_name_to_c(node.name)
 self.buf('/* Node %s index %d */\n' % (node.path, node.idx))
-self.buf('static struct %s%s %s%s = {\n' %
- (STRUCT_PREFIX, struct_name, VAL_PREFIX, var_name))
-for pname in sorted(node.props):
-prop = node.props[pname]
-if pname in PROP_IGNORE_LIST or pname[0] == '#':
-continue
-member_name = conv_name_to_c(prop.name)
-self.buf('\t%s= ' % tab_to(3, '.' + member_name))
-
-# Special handling for lists
-if isinstance(prop.value, list):
-self._output_list(node, prop)
-else:
-self.buf(get_value(prop.type, prop.value))
-self.buf(',\n')
-self.buf('};\n')
 
+self._output_values(var_name, struct_name, node)
 self._declare_device(var_name, struct_name, node.parent)
 
 self.out(''.join(self.get_buf()))
-- 
2.29.2.729.g45daf8777d-goog



[PATCH v2 07/21] dtoc: Fix a few pylint warnings in dtb_platdata

2020-12-23 Thread Simon Glass
These have crept in again. Update the file to fix all but these ones:

   dtb_platdata.py:143:0: R0902: Too many instance attributes (10/7)
  (too-many-instance-attributes)
   dtb_platdata.py:713:0: R0913: Too many arguments (6/5)
  (too-many-arguments)

Signed-off-by: Simon Glass 
---

(no changes since v1)

 tools/dtoc/dtb_platdata.py | 31 ---
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index 82671138a9a..cc3e58a1cd6 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -112,18 +112,19 @@ def get_value(ftype, value):
 str: String representation of the value
 """
 if ftype == fdt.Type.INT:
-return '%#x' % fdt_util.fdt32_to_cpu(value)
+val = '%#x' % fdt_util.fdt32_to_cpu(value)
 elif ftype == fdt.Type.BYTE:
 char = value[0]
-return '%#x' % (ord(char) if isinstance(char, str) else char)
+val = '%#x' % (ord(char) if isinstance(char, str) else char)
 elif ftype == fdt.Type.STRING:
 # Handle evil ACPI backslashes by adding another backslash before them.
 # So "\\_SB.GPO0" in the device tree effectively stays like that in C
-return '"%s"' % value.replace('\\', '')
+val = '"%s"' % value.replace('\\', '')
 elif ftype == fdt.Type.BOOL:
-return 'true'
+val = 'true'
 else:  # ftype == fdt.Type.INT64:
-return '%#x' % value
+val = '%#x' % value
+return val
 
 def get_compat_name(node):
 """Get the node's list of compatible string as a C identifiers
@@ -131,7 +132,7 @@ def get_compat_name(node):
 Args:
 node (fdt.Node): Node object to check
 Return:
-List of C identifiers for all the compatible strings
+list of str: List of C identifiers for all the compatible strings
 """
 compat = node.props['compatible'].value
 if not isinstance(compat, list):
@@ -139,7 +140,7 @@ def get_compat_name(node):
 return [conv_name_to_c(c) for c in compat]
 
 
-class DtbPlatdata(object):
+class DtbPlatdata():
 """Provide a means to convert device tree binary data to platform data
 
 The output of this process is C structures which can be used in space-
@@ -183,7 +184,7 @@ class DtbPlatdata(object):
 and a lookup in driver_aliases printing a warning in case of failure.
 
 Args:
-node: Node object to check
+node (Node): Node object to check
 Return:
 Tuple:
 Driver name associated with the first compatible string
@@ -330,7 +331,7 @@ class DtbPlatdata(object):
 
 # The following re will search for driver names declared as
 # U_BOOT_DRIVER(driver_name)
-drivers = re.findall('U_BOOT_DRIVER\((.*)\)', buff)
+drivers = re.findall(r'U_BOOT_DRIVER\((.*)\)', buff)
 
 for driver in drivers:
 self._drivers.append(driver)
@@ -338,7 +339,7 @@ class DtbPlatdata(object):
 # The following re will search for driver aliases declared as
 # U_BOOT_DRIVER_ALIAS(alias, driver_name)
 driver_aliases = re.findall(
-'U_BOOT_DRIVER_ALIAS\(\s*(\w+)\s*,\s*(\w+)\s*\)',
+r'U_BOOT_DRIVER_ALIAS\(\s*(\w+)\s*,\s*(\w+)\s*\)',
 buff)
 
 for alias in driver_aliases: # pragma: no cover
@@ -383,8 +384,8 @@ class DtbPlatdata(object):
 This adds each node to self._valid_nodes.
 
 Args:
-root: Root node for scan
-valid_nodes: List of Node objects to add to
+root (Node): Root node for scan
+valid_nodes (list of Node): List of Node objects to add to
 """
 for node in root.subnodes:
 if 'compatible' in node.props:
@@ -484,7 +485,7 @@ class DtbPlatdata(object):
 updated to match that width.
 
 Returns:
-dict containing structures:
+dict of dict: dict containing structures:
 key (str): Node name, as a C identifier
 value: dict containing structure fields:
 key (str): Field name
@@ -559,7 +560,7 @@ class DtbPlatdata(object):
 doc/driver-model/of-plat.rst for more information.
 
 Args:
-structs: dict containing structures:
+structs (dict): dict containing structures:
 key (str): Node name, as a C identifier
 value: dict containing structure fields:
 key (str): Field name
@@ -720,7 +721,7 @@ def run_steps(args, dtb_file, include_disabled, output, 
warning_disabled=False,
 output (str): Name of output file
 warning_disabled (bool): True to avoid showing warnings about missing
 drivers
-   _drivers_additional (list): List of additional drivers to use during
+drivers_additional (list): List of additional 

[PATCH v2 08/21] dtoc: Make _output_list a top-level function

2020-12-23 Thread Simon Glass
It is annoying to have this function inside its parent since it makes the
parent longer and hard to read. Move it to the top level.

Signed-off-by: Simon Glass 
---

(no changes since v1)

 tools/dtoc/dtb_platdata.py | 80 +++---
 1 file changed, 40 insertions(+), 40 deletions(-)

diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index cc3e58a1cd6..372f756037e 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -592,51 +592,51 @@ class DtbPlatdata():
 self.out(';\n')
 self.out('};\n')
 
+def _output_list(self, node, prop):
+"""Output the C code for a devicetree property that holds a list
+
+Args:
+node (fdt.Node): Node to output
+prop (fdt.Prop): Prop to output
+"""
+self.buf('{')
+vals = []
+# For phandles, output a reference to the platform data
+# of the target node.
+info = self.get_phandle_argc(prop, node.name)
+if info:
+# Process the list as pairs of (phandle, id)
+pos = 0
+for args in info.args:
+phandle_cell = prop.value[pos]
+phandle = fdt_util.fdt32_to_cpu(phandle_cell)
+target_node = self._fdt.phandle_to_node[phandle]
+arg_values = []
+for i in range(args):
+arg_values.append(
+str(fdt_util.fdt32_to_cpu(prop.value[pos + 1 + i])))
+pos += 1 + args
+vals.append('\t{%d, {%s}}' % (target_node.idx,
+  ', '.join(arg_values)))
+for val in vals:
+self.buf('\n\t\t%s,' % val)
+else:
+for val in prop.value:
+vals.append(get_value(prop.type, val))
+
+# Put 8 values per line to avoid very long lines.
+for i in range(0, len(vals), 8):
+if i:
+self.buf(',\n\t\t')
+self.buf(', '.join(vals[i:i + 8]))
+self.buf('}')
+
 def output_node(self, node):
 """Output the C code for a node
 
 Args:
 node (fdt.Node): node to output
 """
-def _output_list(node, prop):
-"""Output the C code for a devicetree property that holds a list
-
-Args:
-node (fdt.Node): Node to output
-prop (fdt.Prop): Prop to output
-"""
-self.buf('{')
-vals = []
-# For phandles, output a reference to the platform data
-# of the target node.
-info = self.get_phandle_argc(prop, node.name)
-if info:
-# Process the list as pairs of (phandle, id)
-pos = 0
-for args in info.args:
-phandle_cell = prop.value[pos]
-phandle = fdt_util.fdt32_to_cpu(phandle_cell)
-target_node = self._fdt.phandle_to_node[phandle]
-arg_values = []
-for i in range(args):
-arg_values.append(
-str(fdt_util.fdt32_to_cpu(prop.value[pos + 1 + 
i])))
-pos += 1 + args
-vals.append('\t{%d, {%s}}' % (target_node.idx,
-  ', '.join(arg_values)))
-for val in vals:
-self.buf('\n\t\t%s,' % val)
-else:
-for val in prop.value:
-vals.append(get_value(prop.type, val))
-
-# Put 8 values per line to avoid very long lines.
-for i in range(0, len(vals), 8):
-if i:
-self.buf(',\n\t\t')
-self.buf(', '.join(vals[i:i + 8]))
-self.buf('}')
-
 struct_name, _ = self.get_normalized_compat_name(node)
 var_name = conv_name_to_c(node.name)
 self.buf('/* Node %s index %d */\n' % (node.path, node.idx))
@@ -651,7 +651,7 @@ class DtbPlatdata():
 
 # Special handling for lists
 if isinstance(prop.value, list):
-_output_list(node, prop)
+self._output_list(node, prop)
 else:
 self.buf(get_value(prop.type, prop.value))
 self.buf(',\n')
-- 
2.29.2.729.g45daf8777d-goog



[PATCH v2 09/21] dtoc: Output the device in a separate function

2020-12-23 Thread Simon Glass
Reduce the length of output_node() by moving the device-output
functionality into a separate function.

Signed-off-by: Simon Glass 
---

(no changes since v1)

 tools/dtoc/dtb_platdata.py | 33 ++---
 1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index 372f756037e..2d701ac24da 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -631,6 +631,27 @@ class DtbPlatdata():
 self.buf(', '.join(vals[i:i + 8]))
 self.buf('}')
 
+def _declare_device(self, var_name, struct_name, node_parent):
+"""Add a device declaration to the output
+
+This declares a U_BOOT_DEVICE() for the device being processed
+
+Args:
+var_name (str): C name for the node
+struct_name (str): Name for the dt struct associated with the node
+node_parent (Node): Parent of the node (or None if none)
+"""
+self.buf('U_BOOT_DEVICE(%s) = {\n' % var_name)
+self.buf('\t.name\t\t= "%s",\n' % struct_name)
+self.buf('\t.plat\t= &%s%s,\n' % (VAL_PREFIX, var_name))
+self.buf('\t.plat_size\t= sizeof(%s%s),\n' % (VAL_PREFIX, var_name))
+idx = -1
+if node_parent and node_parent in self._valid_nodes:
+idx = node_parent.idx
+self.buf('\t.parent_idx\t= %d,\n' % idx)
+self.buf('};\n')
+self.buf('\n')
+
 def output_node(self, node):
 """Output the C code for a node
 
@@ -657,17 +678,7 @@ class DtbPlatdata():
 self.buf(',\n')
 self.buf('};\n')
 
-# Add a device declaration
-self.buf('U_BOOT_DEVICE(%s) = {\n' % var_name)
-self.buf('\t.name\t\t= "%s",\n' % struct_name)
-self.buf('\t.plat\t= &%s%s,\n' % (VAL_PREFIX, var_name))
-self.buf('\t.plat_size\t= sizeof(%s%s),\n' % (VAL_PREFIX, var_name))
-idx = -1
-if node.parent and node.parent in self._valid_nodes:
-idx = node.parent.idx
-self.buf('\t.parent_idx\t= %d,\n' % idx)
-self.buf('};\n')
-self.buf('\n')
+self._declare_device(var_name, struct_name, node.parent)
 
 self.out(''.join(self.get_buf()))
 
-- 
2.29.2.729.g45daf8777d-goog



[PATCH v2 05/21] test: Use a simple variable to record removed device

2020-12-23 Thread Simon Glass
At present the entire test state is effective passed into a test driver
just to record which device was removed. This is unnecessary and makes it
harder to track what is going on.

Use a simple boolean instead.

Also drop the unused 'removed' member while we are here.

Signed-off-by: Simon Glass 
---

(no changes since v1)

 include/dm/test.h |  2 --
 test/dm/bus.c | 14 ++
 2 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/include/dm/test.h b/include/dm/test.h
index b2adce730ad..cbe1b57d95f 100644
--- a/include/dm/test.h
+++ b/include/dm/test.h
@@ -134,14 +134,12 @@ extern struct unit_test_state global_dm_test_state;
  * @testdev: Test device
  * @force_fail_alloc: Force all memory allocs to fail
  * @skip_post_probe: Skip uclass post-probe processing
- * @removed: Used to keep track of a device that was removed
  */
 struct dm_test_state {
struct udevice *root;
struct udevice *testdev;
int force_fail_alloc;
int skip_post_probe;
-   struct udevice *removed;
 };
 
 /* Declare a new driver model test */
diff --git a/test/dm/bus.c b/test/dm/bus.c
index 60ddb1d6b14..b95c106f5f0 100644
--- a/test/dm/bus.c
+++ b/test/dm/bus.c
@@ -30,7 +30,8 @@ enum {
FLAG_CHILD_REMOVED  = -7,
 };
 
-static struct dm_test_state *test_state;
+/* Records the last testbus device that was removed */
+static struct udevice *testbus_removed;
 
 static int testbus_drv_probe(struct udevice *dev)
 {
@@ -78,11 +79,9 @@ static int testbus_child_post_probe_uclass(struct udevice 
*dev)
 static int testbus_child_post_remove(struct udevice *dev)
 {
struct dm_test_parent_data *parent_data = dev_get_parent_priv(dev);
-   struct dm_test_state *dms = test_state;
 
parent_data->flag += FLAG_CHILD_REMOVED;
-   if (dms)
-   dms->removed = dev;
+   testbus_removed = dev;
 
return 0;
 }
@@ -335,11 +334,10 @@ DM_TEST(dm_test_bus_parent_data_uclass,
 static int dm_test_bus_parent_ops(struct unit_test_state *uts)
 {
struct dm_test_parent_data *parent_data;
-   struct dm_test_state *dms = uts->priv;
struct udevice *bus, *dev;
struct uclass *uc;
 
-   test_state = dms;
+   testbus_removed = NULL;
ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, ));
ut_assertok(uclass_get(UCLASS_TEST_FDT, ));
 
@@ -362,9 +360,9 @@ static int dm_test_bus_parent_ops(struct unit_test_state 
*uts)
ut_asserteq(FLAG_CHILD_PROBED, parent_data->flag);
ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
-   ut_asserteq_ptr(dms->removed, dev);
+   ut_asserteq_ptr(testbus_removed, dev);
}
-   test_state = NULL;
+   testbus_removed = NULL;
 
return 0;
 }
-- 
2.29.2.729.g45daf8777d-goog



[PATCH v2 04/21] timer: Use a shorter error in TPL

2020-12-23 Thread Simon Glass
This error should not happen in normal use. Reduce the length of it to
save space in the image.

Add an empty spl.h file to sh since it appears to lack this.

Signed-off-by: Simon Glass 
---

(no changes since v1)

 lib/time.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/lib/time.c b/lib/time.c
index 88bc50405ff..cc6944ec345 100644
--- a/lib/time.c
+++ b/lib/time.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -96,8 +97,13 @@ uint64_t notrace get_ticks(void)
}
 
ret = timer_get_count(gd->timer, );
-   if (ret)
-   panic("Could not read count from timer (err %d)\n", ret);
+   if (ret) {
+   if (spl_phase() > PHASE_TPL)
+   panic("Could not read count from timer (err %d)\n",
+ ret);
+   else
+   panic("no timer (err %d)\n", ret);
+   }
 
return count;
 }
-- 
2.29.2.729.g45daf8777d-goog



[PATCH v2 03/21] arc: m68k: nds32: nios2: sh: xtensa: Add empty spl.h header

2020-12-23 Thread Simon Glass
At present it is not possible to include spl.h in on these architectures
since the asm/spl.h file is not present. We want to be able to use the
spl_phase() function, so add empty headers to make things build.

Signed-off-by: Simon Glass 
---

(no changes since v1)

 arch/arc/include/asm/spl.h| 0
 arch/m68k/include/asm/spl.h   | 0
 arch/nds32/include/asm/spl.h  | 0
 arch/nios2/include/asm/spl.h  | 0
 arch/sh/include/asm/spl.h | 0
 arch/xtensa/include/asm/spl.h | 0
 6 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 arch/arc/include/asm/spl.h
 create mode 100644 arch/m68k/include/asm/spl.h
 create mode 100644 arch/nds32/include/asm/spl.h
 create mode 100644 arch/nios2/include/asm/spl.h
 create mode 100644 arch/sh/include/asm/spl.h
 create mode 100644 arch/xtensa/include/asm/spl.h

diff --git a/arch/arc/include/asm/spl.h b/arch/arc/include/asm/spl.h
new file mode 100644
index 000..e69de29bb2d
diff --git a/arch/m68k/include/asm/spl.h b/arch/m68k/include/asm/spl.h
new file mode 100644
index 000..e69de29bb2d
diff --git a/arch/nds32/include/asm/spl.h b/arch/nds32/include/asm/spl.h
new file mode 100644
index 000..e69de29bb2d
diff --git a/arch/nios2/include/asm/spl.h b/arch/nios2/include/asm/spl.h
new file mode 100644
index 000..e69de29bb2d
diff --git a/arch/sh/include/asm/spl.h b/arch/sh/include/asm/spl.h
new file mode 100644
index 000..e69de29bb2d
diff --git a/arch/xtensa/include/asm/spl.h b/arch/xtensa/include/asm/spl.h
new file mode 100644
index 000..e69de29bb2d
-- 
2.29.2.729.g45daf8777d-goog



[PATCH v2 02/21] sysreset: Use a shorter error with SPL

2020-12-23 Thread Simon Glass
Use a minimal error message to save space. Sort the header files while we
are here.

Signed-off-by: Simon Glass 
---

(no changes since v1)

 drivers/sysreset/sysreset-uclass.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/sysreset/sysreset-uclass.c 
b/drivers/sysreset/sysreset-uclass.c
index 3f5414ed1f8..e69fb2255b6 100644
--- a/drivers/sysreset/sysreset-uclass.c
+++ b/drivers/sysreset/sysreset-uclass.c
@@ -9,12 +9,13 @@
 #include 
 #include 
 #include 
-#include 
-#include 
-#include 
 #include 
 #include 
+#include 
+#include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -101,7 +102,10 @@ void sysreset_walk_halt(enum sysreset_t type)
mdelay(100);
 
/* Still no reset? Give up */
-   log_err("System reset not supported on this platform\n");
+   if (spl_phase() <= PHASE_SPL)
+   log_err("no sysreset\n");
+   else
+   log_err("System reset not supported on this platform\n");
hang();
 }
 
-- 
2.29.2.729.g45daf8777d-goog



[PATCH v2 01/21] pinctrl: Drop post_bind() method when not needed

2020-12-23 Thread Simon Glass
This is not used with of-platdata, so remove it in that case.

Signed-off-by: Simon Glass 
---

(no changes since v1)

 drivers/pinctrl/pinctrl-uclass.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/pinctrl-uclass.c b/drivers/pinctrl/pinctrl-uclass.c
index aba88104747..4e474cbff73 100644
--- a/drivers/pinctrl/pinctrl-uclass.c
+++ b/drivers/pinctrl/pinctrl-uclass.c
@@ -305,7 +305,7 @@ int pinctrl_select_state(struct udevice *dev, const char 
*statename)
 * Some device which is logical like mmc.blk, do not have
 * a valid ofnode.
 */
-   if (!ofnode_valid(dev->node))
+   if (!dev_has_of_node(dev))
return 0;
/*
 * Try full-implemented pinctrl first.
@@ -416,7 +416,9 @@ static int __maybe_unused pinctrl_post_bind(struct udevice 
*dev)
 
 UCLASS_DRIVER(pinctrl) = {
.id = UCLASS_PINCTRL,
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
.post_bind = pinctrl_post_bind,
+#endif
.flags = DM_UC_FLAG_SEQ_ALIAS,
.name = "pinctrl",
 };
-- 
2.29.2.729.g45daf8777d-goog



[PATCH v2 00/21] dm: Preparation for enhanced of-platdata (part B)

2020-12-23 Thread Simon Glass
This series includes some refactoring of the dtoc tool and some changes
to a few drivers (particularly on x86) to reduce TPL size.

It is available at u-boot-dm/prep-working

Changes in v2:
- Rename DriverInfo to Driver
- Add a test for the new code and a comment for Driver

Simon Glass (21):
  pinctrl: Drop post_bind() method when not needed
  sysreset: Use a shorter error with SPL
  arc: m68k: nds32: nios2: sh: xtensa: Add empty spl.h header
  timer: Use a shorter error in TPL
  test: Use a simple variable to record removed device
  test: Move some test drivers into their own file
  dtoc: Fix a few pylint warnings in dtb_platdata
  dtoc: Make _output_list a top-level function
  dtoc: Output the device in a separate function
  dtoc: Output the struct values in a separate function
  dtoc: Convert _drivers to a dict
  dtoc: Scan drivers for available information
  dtoc: Allow use of the of_match_ptr() macro
  x86: apl: Use const for driver operations
  x86: Move call64 into its own section
  x86: coral: Move fsp-m settings to a subnode
  x86: apl: Update hostbridge to remove unwanted TPL code
  x86: apl: Reduce size for TPL
  x86: pinctrl: Drop unlikely error messages from TPL
  x86: tpl: Remove unwanted devicetree string
  x86: Fix header guard in asm/pmu.h

 arch/arc/include/asm/spl.h   |   0
 arch/m68k/include/asm/spl.h  |   0
 arch/nds32/include/asm/spl.h |   0
 arch/nios2/include/asm/spl.h |   0
 arch/sh/include/asm/spl.h|   0
 arch/x86/cpu/apollolake/fsp_m.c  |   5 +-
 arch/x86/cpu/apollolake/hostbridge.c |  14 +-
 arch/x86/cpu/apollolake/lpc.c|  13 +-
 arch/x86/cpu/apollolake/pch.c|   4 +-
 arch/x86/cpu/apollolake/pmc.c|   6 +-
 arch/x86/cpu/apollolake/uart.c   |   4 +-
 arch/x86/cpu/i386/call64.S   |   1 +
 arch/x86/cpu/intel_common/Makefile   |   2 +-
 arch/x86/cpu/intel_common/itss.c |   4 +-
 arch/x86/cpu/intel_common/p2sb.c |   6 +-
 arch/x86/cpu/turbo.c |   5 +
 arch/x86/dts/chromebook_coral.dts|   5 +
 arch/x86/include/asm/pmu.h   |   6 +-
 arch/x86/lib/tpl.c   |   4 +-
 arch/xtensa/include/asm/spl.h|   0
 board/google/chromebook_coral/coral.c|   4 +-
 drivers/gpio/intel_gpio.c|   4 +-
 drivers/misc/Kconfig |   9 +
 drivers/misc/Makefile|   1 +
 drivers/misc/test_drv.c  | 230 ++
 drivers/pinctrl/intel/pinctrl.c  |  11 +-
 drivers/pinctrl/intel/pinctrl_apl.c  |   4 +-
 drivers/pinctrl/pinctrl-uclass.c |   4 +-
 drivers/power/acpi_pmc/acpi-pmc-uclass.c |   4 +-
 drivers/sysreset/sysreset-uclass.c   |  12 +-
 drivers/timer/tsc_timer.c|   4 +-
 include/dm/test.h|  20 +-
 include/test/test.h  |   9 +
 lib/time.c   |  10 +-
 test/dm/bus.c| 107 +--
 test/dm/test-fdt.c   | 120 
 tools/dtoc/dtb_platdata.py   | 370 +--
 tools/dtoc/test_dtoc.py  | 123 
 38 files changed, 777 insertions(+), 348 deletions(-)
 create mode 100644 arch/arc/include/asm/spl.h
 create mode 100644 arch/m68k/include/asm/spl.h
 create mode 100644 arch/nds32/include/asm/spl.h
 create mode 100644 arch/nios2/include/asm/spl.h
 create mode 100644 arch/sh/include/asm/spl.h
 create mode 100644 arch/xtensa/include/asm/spl.h
 create mode 100644 drivers/misc/test_drv.c

-- 
2.29.2.729.g45daf8777d-goog



[PATCH] Revert "arm64: a37xx: pci: Assert PERST# signal when unloading driver"

2020-12-23 Thread Pali Rohár
This reverts commit 828d32621686aec593076d16445d39b9b8d49c05.

This change revers code which asserting PERST# signal when unloading
driver. Driver's remove callback is still there as it is used for other
functionality.

Asserting PERST# signal prior booting kernel is causing that A3720 boards
(Turris MOX and Espressobin) with stable Linux kernel versions 4.14 and
4.19 are not able to detect some PCIe cards (e.g. Compex WLE200 and WLE900)
and anymore. When PERST# signal is not asserted these cards are detected
correctly. As this is regression for existing stable Linux kernel versions
revert this problematic change in U-Boot.

To make cards working with OpenWRT 4.14 kernel it is needed to disable link
training prior booting kernel, which is already done in driver's remove
callback.

Described issue is in Linux kernel pci aardvark driver which is (hopefully)
fixed in latest upstream versions. Latest upstream versions should be able
to initialize PCIe bus and detects cards independently of the link training
and PERST# signal state.

So with this change, U-Boot on A3720 boards should be able to boot OpenWRT
4.14 kernel, stable 4.14 and 4.19 kernels and also latest mainline kernels.

Signed-off-by: Pali Rohár 
---
Stefan, please include this patch for U-Boot 2020.01 release. It fixes
using PCIe cards on Espressobin with OpenWRT which Gérald reported to
me and I was reproduced it.

Gérald, if you have a time please this patch if it fixes this issue.

I have tested this patch with OpenWRT 4.14 kernel, stable 4.19 kernel
and mainline 5.10 on Espressobin. And with OpenWRT TurrisOS 4.14 kernel
and mainline 5.10 on Turris MOX. Both after cold boot and reboot with
Compex WLE900 and WLE200 cards.

I hope that there would not be any new regression.
---
 drivers/pci/pci-aardvark.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/pci/pci-aardvark.c b/drivers/pci/pci-aardvark.c
index babb84ca93..5c6e30e667 100644
--- a/drivers/pci/pci-aardvark.c
+++ b/drivers/pci/pci-aardvark.c
@@ -649,9 +649,6 @@ static int pcie_advk_remove(struct udevice *dev)
struct pcie_advk *pcie = dev_get_priv(dev);
u32 reg;
 
-   if (dm_gpio_is_valid(>reset_gpio))
-   dm_gpio_set_value(>reset_gpio, 1);
-
reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG);
reg &= ~LINK_TRAINING_EN;
advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG);
-- 
2.20.1



[v6 18/18] configs: socfpga: Add defconfig for Agilex and Stratix 10 with ATF support

2020-12-23 Thread Siew Chin Lim
From: Chee Hong Ang 

Booting Agilex and Stratix 10 with ATF support.

SPL now loads ATF (BL31), U-Boot proper and DTB from FIT
image. The new boot flow with ATF support is as follow:

SPL -> ATF (BL31) -> U-Boot proper -> OS (Linux)

U-Boot proper now starts at 0x20 (CONFIG_SYS_TEXT_BASE).
ATF will occupy the address range starting from 0x1000.

Signed-off-by: Chee Hong Ang 
Signed-off-by: Siew Chin Lim 
---
 ...ilex_defconfig => socfpga_agilex_atf_defconfig} | 22 
 ...0_defconfig => socfpga_stratix10_atf_defconfig} | 24 +-
 2 files changed, 28 insertions(+), 18 deletions(-)
 copy configs/{socfpga_agilex_defconfig => socfpga_agilex_atf_defconfig} (80%)
 copy configs/{socfpga_stratix10_defconfig => socfpga_stratix10_atf_defconfig} 
(80%)

diff --git a/configs/socfpga_agilex_defconfig 
b/configs/socfpga_agilex_atf_defconfig
similarity index 80%
copy from configs/socfpga_agilex_defconfig
copy to configs/socfpga_agilex_atf_defconfig
index 230d3c2ce5..ad87a8098f 100644
--- a/configs/socfpga_agilex_defconfig
+++ b/configs/socfpga_agilex_atf_defconfig
@@ -1,25 +1,29 @@
 CONFIG_ARM=y
+CONFIG_ARM_SMCCC=y
+CONFIG_SPL_LDSCRIPT="arch/arm/mach-socfpga/u-boot-spl-soc64.lds"
 CONFIG_ARCH_SOCFPGA=y
-CONFIG_SYS_TEXT_BASE=0x1000
+CONFIG_SYS_TEXT_BASE=0x20
 CONFIG_SYS_MALLOC_F_LEN=0x2000
-CONFIG_NR_DRAM_BANKS=2
-CONFIG_SYS_MEMTEST_START=0x
-CONFIG_SYS_MEMTEST_END=0x3fe0
 CONFIG_ENV_SIZE=0x1000
 CONFIG_ENV_OFFSET=0x200
-CONFIG_SYS_SPI_U_BOOT_OFFS=0x3c0
 CONFIG_DM_GPIO=y
-CONFIG_SPL_TEXT_BASE=0xFFE0
+CONFIG_NR_DRAM_BANKS=2
 CONFIG_TARGET_SOCFPGA_AGILEX_SOCDK=y
 CONFIG_IDENT_STRING="socfpga_agilex"
 CONFIG_SPL_FS_FAT=y
-# CONFIG_PSCI_RESET is not set
-CONFIG_DEFAULT_DEVICE_TREE="socfpga_agilex_socdk"
+CONFIG_SPL_TEXT_BASE=0xFFE0
+CONFIG_FIT=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_SPL_LOAD_FIT_ADDRESS=0x0200
+# CONFIG_USE_SPL_FIT_GENERATOR is not set
 CONFIG_BOOTDELAY=5
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="earlycon"
 CONFIG_SPL_CACHE=y
 CONFIG_SPL_SPI_LOAD=y
+CONFIG_SYS_SPI_U_BOOT_OFFS=0x0200
+CONFIG_SPL_ATF=y
+CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="SOCFPGA_AGILEX # "
 CONFIG_CMD_MEMTEST=y
@@ -35,6 +39,7 @@ CONFIG_CMD_CACHE=y
 CONFIG_CMD_EXT4=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
+CONFIG_DEFAULT_DEVICE_TREE="socfpga_agilex_socdk"
 CONFIG_ENV_IS_IN_MMC=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
@@ -44,6 +49,7 @@ CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_DW=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_DW=y
+CONFIG_MTD=y
 CONFIG_SF_DEFAULT_MODE=0x2003
 CONFIG_SPI_FLASH_SPANSION=y
 CONFIG_SPI_FLASH_STMICRO=y
diff --git a/configs/socfpga_stratix10_defconfig 
b/configs/socfpga_stratix10_atf_defconfig
similarity index 80%
copy from configs/socfpga_stratix10_defconfig
copy to configs/socfpga_stratix10_atf_defconfig
index 3df44bb88d..1005ba979e 100644
--- a/configs/socfpga_stratix10_defconfig
+++ b/configs/socfpga_stratix10_atf_defconfig
@@ -1,26 +1,28 @@
 CONFIG_ARM=y
+CONFIG_ARM_SMCCC=y
+CONFIG_SPL_LDSCRIPT="arch/arm/mach-socfpga/u-boot-spl-soc64.lds"
 CONFIG_ARCH_SOCFPGA=y
-CONFIG_SYS_TEXT_BASE=0x1000
+CONFIG_SYS_TEXT_BASE=0x20
 CONFIG_SYS_MALLOC_F_LEN=0x2000
-CONFIG_NR_DRAM_BANKS=2
-CONFIG_SYS_MEMTEST_START=0x
-CONFIG_SYS_MEMTEST_END=0x3fe0
 CONFIG_ENV_SIZE=0x1000
 CONFIG_ENV_OFFSET=0x200
-CONFIG_SYS_SPI_U_BOOT_OFFS=0x3C0
 CONFIG_DM_GPIO=y
-CONFIG_SPL_TEXT_BASE=0xFFE0
+CONFIG_NR_DRAM_BANKS=2
 CONFIG_TARGET_SOCFPGA_STRATIX10_SOCDK=y
 CONFIG_IDENT_STRING="socfpga_stratix10"
 CONFIG_SPL_FS_FAT=y
-# CONFIG_PSCI_RESET is not set
-CONFIG_DEFAULT_DEVICE_TREE="socfpga_stratix10_socdk"
-CONFIG_OPTIMIZE_INLINING=y
-CONFIG_SPL_OPTIMIZE_INLINING=y
+CONFIG_SPL_TEXT_BASE=0xFFE0
+CONFIG_FIT=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_SPL_LOAD_FIT_ADDRESS=0x0200
+# CONFIG_USE_SPL_FIT_GENERATOR is not set
 CONFIG_BOOTDELAY=5
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="earlycon"
 CONFIG_SPL_SPI_LOAD=y
+CONFIG_SYS_SPI_U_BOOT_OFFS=0x0200
+CONFIG_SPL_ATF=y
+CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="SOCFPGA_STRATIX10 # "
 CONFIG_CMD_MEMTEST=y
@@ -37,11 +39,13 @@ CONFIG_CMD_CACHE=y
 CONFIG_CMD_EXT4=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
+CONFIG_DEFAULT_DEVICE_TREE="socfpga_stratix10_socdk"
 CONFIG_ENV_IS_IN_MMC=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_SPL_ALTERA_SDRAM=y
+CONFIG_FPGA_INTEL_PR=y
 CONFIG_DWAPB_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_DW=y
-- 
2.13.0



[v6 17/18] arm: socfpga: soc64: Enable FIT image generation using binman

2020-12-23 Thread Siew Chin Lim
Enable BINMAN when using Arm-Trusted-Firmware (ATF) to
generate FIT images.

Signed-off-by: Siew Chin Lim 

---
v4
---
Adjust BINMAN sequence in code, sorted by alphabetical order.

v5
---
Revert all changes in Makefile for BINMAN:
(1) Remove target "fit-itb", directly use binman command to generate fit
(2) Do not skip binman for ARCH_SOCFPGA in default Makefile flow.
Use "blob-ext" entry instead of "blob" in binman node in device tree,
binman will report warning instead of error in default Makefile flow.
So, it wouldn't fail the default compilation process.
---
 arch/arm/mach-socfpga/Kconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig
index 01f5a1fc41..4d4ff16337 100644
--- a/arch/arm/mach-socfpga/Kconfig
+++ b/arch/arm/mach-socfpga/Kconfig
@@ -33,6 +33,7 @@ config TARGET_SOCFPGA_AGILEX
bool
select ARMV8_MULTIENTRY
select ARMV8_SET_SMPEN
+   select BINMAN if SPL_ATF
select CLK
select FPGA_INTEL_SDM_MAILBOX
select NCORE_CACHE
@@ -78,6 +79,7 @@ config TARGET_SOCFPGA_STRATIX10
bool
select ARMV8_MULTIENTRY
select ARMV8_SET_SMPEN
+   select BINMAN if SPL_ATF
select FPGA_INTEL_SDM_MAILBOX
 
 choice
-- 
2.13.0



[v6 16/18] arm: socfpga: dts: soc64: Add binman node of FIT image with ATF support

2020-12-23 Thread Siew Chin Lim
Add binman node to device tree to generate the FIT image for u-boot
(u-boot.itb) and OS kernel (kernel.itb).

u-boot.itb contains arm trusted firmware (ATF), u-boot proper and
u-boot device tree for ATF u-boot flow.

kernel.itb contains Linux Image and Linux device tree.

Signed-off-by: Siew Chin Lim 

---
v5
---
Change 'blob' to 'blob-ext' entry in binman dts node for all input files.
The input files (u-boot proper, Linux image files) that required to
build FIT images may not yet ready during u-boot compilation.
By using 'blob-ext', binman will report warning instead of error
during u-boot compilation when the input files doesn't exist.
It wouldn't fail the u-boot compilation. Then, user can prepare the
input files later, and use binman command to generate the FIT images.
---
 arch/arm/dts/socfpga_agilex-u-boot.dtsi  |   4 +-
 arch/arm/dts/socfpga_soc64_fit-u-boot.dtsi   | 120 +++
 arch/arm/dts/socfpga_stratix10-u-boot.dtsi   |   8 ++
 arch/arm/dts/socfpga_stratix10_socdk-u-boot.dtsi |   4 +-
 4 files changed, 134 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/dts/socfpga_soc64_fit-u-boot.dtsi
 create mode 100644 arch/arm/dts/socfpga_stratix10-u-boot.dtsi

diff --git a/arch/arm/dts/socfpga_agilex-u-boot.dtsi 
b/arch/arm/dts/socfpga_agilex-u-boot.dtsi
index f0528a9ad9..08f7cf7f7a 100644
--- a/arch/arm/dts/socfpga_agilex-u-boot.dtsi
+++ b/arch/arm/dts/socfpga_agilex-u-boot.dtsi
@@ -2,9 +2,11 @@
 /*
  * U-Boot additions
  *
- * Copyright (C) 2019 Intel Corporation 
+ * Copyright (C) 2019-2020 Intel Corporation 
  */
 
+#include "socfpga_soc64_fit-u-boot.dtsi"
+
 /{
memory {
#address-cells = <2>;
diff --git a/arch/arm/dts/socfpga_soc64_fit-u-boot.dtsi 
b/arch/arm/dts/socfpga_soc64_fit-u-boot.dtsi
new file mode 100644
index 00..cf365590a8
--- /dev/null
+++ b/arch/arm/dts/socfpga_soc64_fit-u-boot.dtsi
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * U-Boot additions
+ *
+ * Copyright (C) 2020 Intel Corporation 
+ */
+
+#if defined(CONFIG_FIT)
+
+/ {
+   binman: binman {
+   multiple-images;
+   };
+};
+
+ {
+   u-boot {
+   filename = "u-boot.itb";
+   fit {
+   fit,external-offset = ;
+   description = "FIT with firmware and bootloader";
+   #address-cells = <1>;
+
+   images {
+   uboot {
+   description = "U-Boot SoC64";
+   type = "standalone";
+   os = "U-Boot";
+   arch = "arm64";
+   compression = "none";
+   load = <0x0020>;
+
+   uboot_blob: blob-ext {
+   filename = "u-boot-nodtb.bin";
+   };
+   };
+
+   atf {
+   description = "ARM Trusted Firmware";
+   type = "firmware";
+   os = "arm-trusted-firmware";
+   arch = "arm64";
+   compression = "none";
+   load = <0x1000>;
+   entry = <0x1000>;
+
+   atf_blob: blob-ext {
+   filename = "bl31.bin";
+   };
+   };
+
+   fdt {
+   description = "U-Boot SoC64 flat 
device-tree";
+   type = "flat_dt";
+   compression = "none";
+
+   uboot_fdt_blob: blob-ext {
+   filename = "u-boot.dtb";
+   };
+   };
+   };
+
+   configurations {
+   default = "conf";
+   conf {
+   description = "Intel SoC64 FPGA";
+   firmware = "atf";
+   loadables = "uboot";
+   fdt = "fdt";
+   };
+   };
+   };
+   };
+
+   kernel {
+   filename = "kernel.itb";
+   fit {
+   description = "FIT with Linux kernel image and FDT 
blob";
+   #address-cells = <1>;
+
+   images {
+ 

[v6 15/18] arm: socfpga: soc64: Skip handoff data access in SSBL

2020-12-23 Thread Siew Chin Lim
From: Chee Hong Ang 

SPL already setup the Clock Manager with the handoff data
from OCRAM. When the Clock Manager's driver get probed again
in SSBL, it shall skip the handoff data access in OCRAM.

Signed-off-by: Chee Hong Ang 
---
 arch/arm/mach-socfpga/wrap_pll_config_s10.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-socfpga/wrap_pll_config_s10.c 
b/arch/arm/mach-socfpga/wrap_pll_config_s10.c
index 3da85791a1..049c5711a8 100644
--- a/arch/arm/mach-socfpga/wrap_pll_config_s10.c
+++ b/arch/arm/mach-socfpga/wrap_pll_config_s10.c
@@ -12,6 +12,7 @@
 
 const struct cm_config * const cm_get_default_config(void)
 {
+#ifdef CONFIG_SPL_BUILD
struct cm_config *cm_handoff_cfg = (struct cm_config *)
(S10_HANDOFF_CLOCK + S10_HANDOFF_OFFSET_DATA);
u32 *conversion = (u32 *)cm_handoff_cfg;
@@ -26,7 +27,7 @@ const struct cm_config * const cm_get_default_config(void)
} else if (handoff_clk == S10_HANDOFF_MAGIC_CLOCK) {
return cm_handoff_cfg;
}
-
+#endif
return NULL;
 }
 
-- 
2.13.0



[v6 14/18] arm: socfpga: soc64: SSBL shall not setup stack on OCRAM

2020-12-23 Thread Siew Chin Lim
From: Chee Hong Ang 

Since SSBL is running in DRAM, it shall setup the stack in DRAM
instead of OCRAM which is occupied by SPL and handoff data.

Signed-off-by: Chee Hong Ang 
---
 include/configs/socfpga_soc64_common.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/include/configs/socfpga_soc64_common.h 
b/include/configs/socfpga_soc64_common.h
index 990f879b07..fdcd7d3e9a 100644
--- a/include/configs/socfpga_soc64_common.h
+++ b/include/configs/socfpga_soc64_common.h
@@ -40,9 +40,14 @@
  */
 #define CONFIG_SYS_INIT_RAM_ADDR   0xFFE0
 #define CONFIG_SYS_INIT_RAM_SIZE   0x4
+#ifdef CONFIG_SPL_BUILD
 #define CONFIG_SYS_INIT_SP_ADDR(CONFIG_SYS_INIT_RAM_ADDR  \
+ CONFIG_SYS_INIT_RAM_SIZE \
- S10_HANDOFF_SIZE)
+#else
+#define CONFIG_SYS_INIT_SP_ADDR(CONFIG_SYS_TEXT_BASE \
+   + 0x10)
+#endif
 #define CONFIG_SYS_INIT_SP_OFFSET  (CONFIG_SYS_INIT_SP_ADDR)
 #define CONFIG_SYS_MALLOC_LEN  (5 * 1024 * 1024)
 
-- 
2.13.0



[v6 13/18] arm: socfpga: mailbox: Add 'SYSTEM_RESET' PSCI support to mbox_reset_cold()

2020-12-23 Thread Siew Chin Lim
From: Chee Hong Ang 

mbox_reset_cold() will invoke ATF's PSCI service when running in
non-secure mode (EL2).

Signed-off-by: Chee Hong Ang 
---
 arch/arm/mach-socfpga/mailbox_s10.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/mach-socfpga/mailbox_s10.c 
b/arch/arm/mach-socfpga/mailbox_s10.c
index 18d44924e6..429444f069 100644
--- a/arch/arm/mach-socfpga/mailbox_s10.c
+++ b/arch/arm/mach-socfpga/mailbox_s10.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -398,6 +399,9 @@ error:
 
 int mbox_reset_cold(void)
 {
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF)
+   psci_system_reset();
+#else
int ret;
 
ret = mbox_send_cmd(MBOX_ID_UBOOT, MBOX_REBOOT_HPS, MBOX_CMD_DIRECT,
@@ -406,6 +410,7 @@ int mbox_reset_cold(void)
/* mailbox sent failure, wait for watchdog to kick in */
hang();
}
+#endif
return 0;
 }
 
-- 
2.13.0



[v6 12/18] arm: socfpga: soc64: Add ATF support for FPGA reconfig driver

2020-12-23 Thread Siew Chin Lim
From: Chee Hong Ang 

In non-secure mode (EL2), FPGA reconfiguration driver calls the
SMC/PSCI services provided by ATF to configure the FPGA.

Signed-off-by: Chee Hong Ang 
---
 drivers/fpga/intel_sdm_mb.c | 139 
 1 file changed, 139 insertions(+)

diff --git a/drivers/fpga/intel_sdm_mb.c b/drivers/fpga/intel_sdm_mb.c
index 9a1dc2c0c8..f5fd9a14c2 100644
--- a/drivers/fpga/intel_sdm_mb.c
+++ b/drivers/fpga/intel_sdm_mb.c
@@ -8,11 +8,149 @@
 #include 
 #include 
 #include 
+#include 
 #include 
+#include 
 
 #define RECONFIG_STATUS_POLL_RESP_TIMEOUT_MS   6
 #define RECONFIG_STATUS_INTERVAL_DELAY_US  100
 
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF)
+
+#define BITSTREAM_CHUNK_SIZE   0x0
+#define RECONFIG_STATUS_POLL_RETRY_MAX 100
+
+/*
+ * Polling the FPGA configuration status.
+ * Return 0 for success, non-zero for error.
+ */
+static int reconfig_status_polling_resp(void)
+{
+   int ret;
+   unsigned long start = get_timer(0);
+
+   while (1) {
+   ret = invoke_smc(INTEL_SIP_SMC_FPGA_CONFIG_ISDONE, NULL, 0,
+NULL, 0);
+
+   if (!ret)
+   return 0;   /* configuration success */
+
+   if (ret != INTEL_SIP_SMC_STATUS_BUSY)
+   return ret;
+
+   if (get_timer(start) > RECONFIG_STATUS_POLL_RESP_TIMEOUT_MS)
+   return -ETIMEDOUT;  /* time out */
+
+   puts(".");
+   udelay(RECONFIG_STATUS_INTERVAL_DELAY_US);
+   WATCHDOG_RESET();
+   }
+
+   return -ETIMEDOUT;
+}
+
+static int send_bitstream(const void *rbf_data, size_t rbf_size)
+{
+   int i;
+   u64 res_buf[3];
+   u64 args[2];
+   u32 xfer_count = 0;
+   int ret, wr_ret = 0, retry = 0;
+   size_t buf_size = (rbf_size > BITSTREAM_CHUNK_SIZE) ?
+   BITSTREAM_CHUNK_SIZE : rbf_size;
+
+   while (rbf_size || xfer_count) {
+   if (!wr_ret && rbf_size) {
+   args[0] = (u64)rbf_data;
+   args[1] = buf_size;
+   wr_ret = invoke_smc(INTEL_SIP_SMC_FPGA_CONFIG_WRITE,
+   args, 2, NULL, 0);
+
+   debug("wr_ret = %d, rbf_data = %p, buf_size = %08lx\n",
+ wr_ret, rbf_data, buf_size);
+
+   if (wr_ret)
+   continue;
+
+   rbf_size -= buf_size;
+   rbf_data += buf_size;
+
+   if (buf_size >= rbf_size)
+   buf_size = rbf_size;
+
+   xfer_count++;
+   puts(".");
+   } else {
+   ret = invoke_smc(
+   INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE,
+   NULL, 0, res_buf, ARRAY_SIZE(res_buf));
+   if (!ret) {
+   for (i = 0; i < ARRAY_SIZE(res_buf); i++) {
+   if (!res_buf[i])
+   break;
+   xfer_count--;
+   wr_ret = 0;
+   retry = 0;
+   }
+   } else if (ret !=
+  INTEL_SIP_SMC_STATUS_BUSY)
+   return ret;
+   else if (!xfer_count)
+   return INTEL_SIP_SMC_STATUS_ERROR;
+
+   if (++retry >= RECONFIG_STATUS_POLL_RETRY_MAX)
+   return -ETIMEDOUT;
+
+   udelay(2);
+   }
+   WATCHDOG_RESET();
+   }
+
+   return 0;
+}
+
+/*
+ * This is the interface used by FPGA driver.
+ * Return 0 for success, non-zero for error.
+ */
+int intel_sdm_mb_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size)
+{
+   int ret;
+   u64 arg = 1;
+
+   debug("Invoking FPGA_CONFIG_START...\n");
+
+   ret = invoke_smc(INTEL_SIP_SMC_FPGA_CONFIG_START, , 1, NULL, 0);
+
+   if (ret) {
+   puts("Failure in RECONFIG mailbox command!\n");
+   return ret;
+   }
+
+   ret = send_bitstream(rbf_data, rbf_size);
+   if (ret) {
+   puts("Error sending bitstream!\n");
+   return ret;
+   }
+
+   /* Make sure we don't send MBOX_RECONFIG_STATUS too fast */
+   udelay(RECONFIG_STATUS_INTERVAL_DELAY_US);
+
+   debug("Polling with MBOX_RECONFIG_STATUS...\n");
+   ret = reconfig_status_polling_resp();
+   if (ret) {
+   puts("FPGA reconfiguration failed!");
+   return ret;
+   }
+
+   puts("FPGA 

[v6 11/18] arm: socfpga: soc64: Add ATF support for Reset Manager driver

2020-12-23 Thread Siew Chin Lim
From: Chee Hong Ang 

In non-secure mode (EL2), Reset Manager driver calls the
SMC/PSCI service provided by ATF to enable/disable the
SOCFPGA bridges.

Signed-off-by: Chee Hong Ang 
Signed-off-by: Siew Chin Lim 
---
 arch/arm/mach-socfpga/reset_manager_s10.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/arch/arm/mach-socfpga/reset_manager_s10.c 
b/arch/arm/mach-socfpga/reset_manager_s10.c
index 3746e6a60c..af8f2c0873 100644
--- a/arch/arm/mach-socfpga/reset_manager_s10.c
+++ b/arch/arm/mach-socfpga/reset_manager_s10.c
@@ -5,11 +5,14 @@
  */
 
 #include 
+#include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
+#include 
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -55,6 +58,15 @@ void socfpga_per_reset_all(void)
 
 void socfpga_bridges_reset(int enable)
 {
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF)
+   u64 arg = enable;
+
+   int ret = invoke_smc(INTEL_SIP_SMC_HPS_SET_BRIDGES, , 1, NULL, 0);
+   if (ret) {
+   printf("SMC call failed with error %d in %s.\n", ret, __func__);
+   return;
+   }
+#else
u32 reg;
 
if (enable) {
@@ -101,6 +113,7 @@ void socfpga_bridges_reset(int enable)
/* Disable NOC timeout */
writel(0, socfpga_get_sysmgr_addr() + SYSMGR_SOC64_NOC_TIMEOUT);
}
+#endif
 }
 
 /*
-- 
2.13.0



[v6 10/18] net: designware: socfpga: Add ATF support for MAC driver

2020-12-23 Thread Siew Chin Lim
From: Chee Hong Ang 

In non-secure mode (EL2), MAC driver calls the SMC/PSCI services
provided by ATF to setup the PHY interface.

Signed-off-by: Chee Hong Ang 
Signed-off-by: Siew Chin Lim 

---
v5
---
Call secure register access helper function to write the secure register.
Return error if fail to write the PHY related secure register.

---
v6
---
Clean up the code and use socfpga_secure_reg_update32 to update
PHY related secure registers.
---
 drivers/net/dwmac_socfpga.c | 37 +++--
 1 file changed, 31 insertions(+), 6 deletions(-)

diff --git a/drivers/net/dwmac_socfpga.c b/drivers/net/dwmac_socfpga.c
index e93561dffa..26f647c778 100644
--- a/drivers/net/dwmac_socfpga.c
+++ b/drivers/net/dwmac_socfpga.c
@@ -6,6 +6,8 @@
  */
 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -17,8 +19,6 @@
 #include 
 #include 
 
-#include 
-
 struct dwmac_socfpga_platdata {
struct dw_eth_pdata dw_eth_pdata;
void*phy_intf;
@@ -64,6 +64,32 @@ static int dwmac_socfpga_ofdata_to_platdata(struct udevice 
*dev)
return designware_eth_ofdata_to_platdata(dev);
 }
 
+static int dwmac_socfpga_do_setphy(struct udevice *dev, u32 modereg)
+{
+   struct dwmac_socfpga_platdata *pdata = dev_get_platdata(dev);
+   u32 modemask = SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << pdata->reg_shift;
+
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF)
+   u32 index = ((u64)pdata->phy_intf - socfpga_get_sysmgr_addr() -
+SYSMGR_SOC64_EMAC0) >> 2;
+
+   u32 id = SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC0 + index;
+
+   int ret = socfpga_secure_reg_update32(id,
+modemask,
+modereg << pdata->reg_shift);
+   if (ret) {
+   dev_err(dev, "Failed to set PHY register via SMC call\n");
+   return ret;
+   }
+#else
+   clrsetbits_le32(pdata->phy_intf, modemask,
+   modereg << pdata->reg_shift);
+#endif
+
+   return 0;
+}
+
 static int dwmac_socfpga_probe(struct udevice *dev)
 {
struct dwmac_socfpga_platdata *pdata = dev_get_platdata(dev);
@@ -71,7 +97,6 @@ static int dwmac_socfpga_probe(struct udevice *dev)
struct reset_ctl_bulk reset_bulk;
int ret;
u32 modereg;
-   u32 modemask;
 
switch (edata->phy_interface) {
case PHY_INTERFACE_MODE_MII:
@@ -97,9 +122,9 @@ static int dwmac_socfpga_probe(struct udevice *dev)
 
reset_assert_bulk(_bulk);
 
-   modemask = SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << pdata->reg_shift;
-   clrsetbits_le32(pdata->phy_intf, modemask,
-   modereg << pdata->reg_shift);
+   ret = dwmac_socfpga_do_setphy(dev, modereg);
+   if (ret)
+   return ret;
 
reset_release_bulk(_bulk);
 
-- 
2.13.0



[v6 09/18] mmc: dwmmc: socfpga: Add ATF support for MMC driver

2020-12-23 Thread Siew Chin Lim
From: Chee Hong Ang 

In non-secure mode (EL2), MMC driver calls the SMC/PSCI services
provided by ATF to set SDMMC's DRVSEL and SMPLSEL.

Signed-off-by: Chee Hong Ang 
Signed-off-by: Siew Chin Lim 

---
v5
---
Call secure register access helper function to write the secure register.
Return error if fail to write the secure register.
---
 drivers/mmc/socfpga_dw_mmc.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/mmc/socfpga_dw_mmc.c b/drivers/mmc/socfpga_dw_mmc.c
index 0a2845bcc2..7a485b492d 100644
--- a/drivers/mmc/socfpga_dw_mmc.c
+++ b/drivers/mmc/socfpga_dw_mmc.c
@@ -6,6 +6,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -13,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -58,10 +60,22 @@ static int socfpga_dwmci_clksel(struct dwmci_host *host)
 
debug("%s: drvsel %d smplsel %d\n", __func__,
  priv->drvsel, priv->smplsel);
+
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF)
+   int ret;
+
+   ret = socfpga_secure_reg_write32(SOCFPGA_SECURE_REG_SYSMGR_SOC64_SDMMC,
+sdmmc_mask);
+   if (ret) {
+   printf("DWMMC: Failed to set clksel via SMC call");
+   return ret;
+   }
+#else
writel(sdmmc_mask, socfpga_get_sysmgr_addr() + SYSMGR_SDMMC);
 
debug("%s: SYSMGR_SDMMCGRP_CTRL_REG = 0x%x\n", __func__,
readl(socfpga_get_sysmgr_addr() + SYSMGR_SDMMC));
+#endif
 
/* Enable SDMMC clock */
setbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_PERPLL_EN,
-- 
2.13.0



[v6 08/18] mmc: dwmmc: Change designware MMC 'clksel' callback function to return status

2020-12-23 Thread Siew Chin Lim
Change 'clksel' callback function to allow the code to return a
status.

This patch is a preparation for enabling Arm-Trusted-Firmware (ATF)
in Intel SoC FPGA. This patch does not change functionality.

When using Arm-Trusted-Firmware (ATF) in Intel SoC FPGA, the MMC clock
related register is secure register which is required to be written
via SMC/PCSI call. It is possible that U-Boot fail to write the
register if there is unexpected error between U-Boot and ATF.
As a result, there maybe signal integrity on MMC connection due to
clock. So, the code should reports error to user when 'clksel' fail.

Signed-off-by: Siew Chin Lim 
---
 drivers/mmc/ca_dw_mmc.c  | 4 +++-
 drivers/mmc/dw_mmc.c | 9 +++--
 drivers/mmc/exynos_dw_mmc.c  | 4 +++-
 drivers/mmc/nexell_dw_mmc.c  | 4 +++-
 drivers/mmc/socfpga_dw_mmc.c | 4 +++-
 include/dwmmc.h  | 2 +-
 6 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/drivers/mmc/ca_dw_mmc.c b/drivers/mmc/ca_dw_mmc.c
index 198c41f451..d0cf1b7248 100644
--- a/drivers/mmc/ca_dw_mmc.c
+++ b/drivers/mmc/ca_dw_mmc.c
@@ -40,7 +40,7 @@ struct ca_dwmmc_priv_data {
u8 ds;
 };
 
-static void ca_dwmci_clksel(struct dwmci_host *host)
+static int ca_dwmci_clksel(struct dwmci_host *host)
 {
struct ca_dwmmc_priv_data *priv = host->priv;
u32 val = readl(priv->sd_dll_reg);
@@ -52,6 +52,8 @@ static void ca_dwmci_clksel(struct dwmci_host *host)
val |= SD_CLK_SEL_100MHZ;
 
writel(val, priv->sd_dll_reg);
+
+   return 0;
 }
 
 static void ca_dwmci_board_init(struct dwmci_host *host)
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 7702f4be3f..7c8a312fa7 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -496,8 +496,13 @@ static int dwmci_set_ios(struct mmc *mmc)
 
dwmci_writel(host, DWMCI_UHS_REG, regs);
 
-   if (host->clksel)
-   host->clksel(host);
+   if (host->clksel) {
+   int ret;
+
+   ret = host->clksel(host);
+   if (ret)
+   return ret;
+   }
 
 #if CONFIG_IS_ENABLED(DM_REGULATOR)
if (mmc->vqmmc_supply) {
diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c
index 435ccac594..7a25dac841 100644
--- a/drivers/mmc/exynos_dw_mmc.c
+++ b/drivers/mmc/exynos_dw_mmc.c
@@ -44,7 +44,7 @@ struct dwmci_exynos_priv_data {
  * Function used as callback function to initialise the
  * CLKSEL register for every mmc channel.
  */
-static void exynos_dwmci_clksel(struct dwmci_host *host)
+static int exynos_dwmci_clksel(struct dwmci_host *host)
 {
 #ifdef CONFIG_DM_MMC
struct dwmci_exynos_priv_data *priv =
@@ -53,6 +53,8 @@ static void exynos_dwmci_clksel(struct dwmci_host *host)
struct dwmci_exynos_priv_data *priv = host->priv;
 #endif
dwmci_writel(host, DWMCI_CLKSEL, priv->sdr_timing);
+
+   return 0;
 }
 
 unsigned int exynos_dwmci_get_clk(struct dwmci_host *host, uint freq)
diff --git a/drivers/mmc/nexell_dw_mmc.c b/drivers/mmc/nexell_dw_mmc.c
index 0462759444..fe00189fe1 100644
--- a/drivers/mmc/nexell_dw_mmc.c
+++ b/drivers/mmc/nexell_dw_mmc.c
@@ -51,7 +51,7 @@ struct nexell_dwmmc_priv {
 
 struct clk *clk_get(const char *id);
 
-static void nx_dw_mmc_clksel(struct dwmci_host *host)
+static int nx_dw_mmc_clksel(struct dwmci_host *host)
 {
/* host->priv is pointer to "struct udevice" */
struct nexell_dwmmc_priv *priv = dev_get_priv(host->priv);
@@ -65,6 +65,8 @@ static void nx_dw_mmc_clksel(struct dwmci_host *host)
  DWMCI_SET_DRV_CLK(DWMCI_SHIFT_0) | DWMCI_SET_DIV_RATIO(3);
 
dwmci_writel(host, DWMCI_CLKSEL, val);
+
+   return 0;
 }
 
 static void nx_dw_mmc_reset(int ch)
diff --git a/drivers/mmc/socfpga_dw_mmc.c b/drivers/mmc/socfpga_dw_mmc.c
index 0022f943bd..0a2845bcc2 100644
--- a/drivers/mmc/socfpga_dw_mmc.c
+++ b/drivers/mmc/socfpga_dw_mmc.c
@@ -46,7 +46,7 @@ static void socfpga_dwmci_reset(struct udevice *dev)
reset_deassert_bulk(_bulk);
 }
 
-static void socfpga_dwmci_clksel(struct dwmci_host *host)
+static int socfpga_dwmci_clksel(struct dwmci_host *host)
 {
struct dwmci_socfpga_priv_data *priv = host->priv;
u32 sdmmc_mask = ((priv->smplsel & 0x7) << SYSMGR_SDMMC_SMPLSEL_SHIFT) |
@@ -66,6 +66,8 @@ static void socfpga_dwmci_clksel(struct dwmci_host *host)
/* Enable SDMMC clock */
setbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_PERPLL_EN,
 CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK);
+
+   return 0;
 }
 
 static int socfpga_dwmmc_get_clk_rate(struct udevice *dev)
diff --git a/include/dwmmc.h b/include/dwmmc.h
index d8a8355a0a..f8aeda7697 100644
--- a/include/dwmmc.h
+++ b/include/dwmmc.h
@@ -174,7 +174,7 @@ struct dwmci_host {
struct mmc *mmc;
void *priv;
 
-   void (*clksel)(struct dwmci_host *host);
+   int (*clksel)(struct dwmci_host *host);
void (*board_init)(struct dwmci_host *host);
 
/**
-- 
2.13.0



  1   2   >