[PATCH] ARM: uniphier: Move uniphier_mem_map_init() call into dram_init()

2024-04-05 Thread Kunihiko Hayashi
The function uniphier_mem_map_init() is to change global variable
'mem_map', which is referenced to get_page_table_size() to calculate
the size of page table.

However, uniphier_mem_map_init() is called after get_page_table_size(),
so the size of page table and 'mem_map' become inconsist each other.
After all, U-Boot fails to boot on chip with memory map different from
default map,

uniphier_mem_map_init() should be moved to dram_init(), which is
called before get_page_table_size().

Signed-off-by: Kunihiko Hayashi 
---
 arch/arm/mach-uniphier/dram_init.c | 16 +++-
 1 file changed, 3 insertions(+), 13 deletions(-)

diff --git a/arch/arm/mach-uniphier/dram_init.c 
b/arch/arm/mach-uniphier/dram_init.c
index 7f2753190c23..e6f1286e71fd 100644
--- a/arch/arm/mach-uniphier/dram_init.c
+++ b/arch/arm/mach-uniphier/dram_init.c
@@ -265,14 +265,15 @@ int dram_init(void)
if (uniphier_get_soc_id() == UNIPHIER_LD20_ID)
gd->ram_size -= 64;
 
+   /* map all the DRAM regions */
+   uniphier_mem_map_init(gd->ram_base, prev_top - gd->ram_base);
+
return 0;
 }
 
 int dram_init_banksize(void)
 {
struct uniphier_dram_map dram_map[3] = {};
-   unsigned long base, top;
-   bool valid_bank_found = false;
int ret, i;
 
ret = uniphier_dram_map_get(dram_map);
@@ -287,18 +288,7 @@ int dram_init_banksize(void)
 
if (!dram_map[i].size)
continue;
-
-   if (!valid_bank_found)
-   base = dram_map[i].base;
-   top = dram_map[i].base + dram_map[i].size;
-   valid_bank_found = true;
}
 
-   if (!valid_bank_found)
-   return -EINVAL;
-
-   /* map all the DRAM regions */
-   uniphier_mem_map_init(base, top - base);
-
return 0;
 }
-- 
2.25.1



Re: [PATCH] spi: dw: Use controller clock rate as maximum frequency

2024-04-04 Thread Kunihiko Hayashi

Hi Jagan,

On 2023/12/18 20:40, Jagan Teki wrote:

On Wed, Oct 25, 2023 at 1:20 PM Kunihiko Hayashi
 wrote:


Currently the controller driver has maximum frequency in plat->frequency
that is specified by "spi-max-frequency" DT property in the controller
node. This is special to U-Boot and doesn't exist to Linux.

 spi {
 spi-max-frequency = ;
 };

Usually the frequency should be specified by "spi-max-frequency" at the
slave device node.

 spi {
 slave {
 spi-max-frequency = ;
 };
 };

The final maximum frequency is set to the smaller value of the controller
node (A) and the slave device node (B).

Currently, if the property in the controller node is omitted, the default
frequency is fixed at 500kHz. Even if the controller and the slave device
allow the higher frequency than 500kHz, the maximum frequency can't exceed
500kHz.

The upper limit of the maximum frequency should be determined by the clock
rate of the controller clock. And this patch determines the maximum
frequency based on the clock rate if the controller node property isn't
specified.

Signed-off-by: Kunihiko Hayashi 
---


Applied to u-boot-spi/master


Sorry for the old response,
I couldn't see this patch in the current master branch.
Could you please apply this if it is missing?

Thank you,

---
Best Regards
Kunihiko Hayashi


[PATCH] spi: dw: Use controller clock rate as maximum frequency

2023-10-25 Thread Kunihiko Hayashi
Currently the controller driver has maximum frequency in plat->frequency
that is specified by "spi-max-frequency" DT property in the controller
node. This is special to U-Boot and doesn't exist to Linux.

spi {
spi-max-frequency = ;
};

Usually the frequency should be specified by "spi-max-frequency" at the
slave device node.

spi {
slave {
spi-max-frequency = ;
};
};

The final maximum frequency is set to the smaller value of the controller
node (A) and the slave device node (B).

Currently, if the property in the controller node is omitted, the default
frequency is fixed at 500kHz. Even if the controller and the slave device
allow the higher frequency than 500kHz, the maximum frequency can't exceed
500kHz.

The upper limit of the maximum frequency should be determined by the clock
rate of the controller clock. And this patch determines the maximum
frequency based on the clock rate if the controller node property isn't
specified.

Signed-off-by: Kunihiko Hayashi 
---
 drivers/spi/designware_spi.c | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/spi/designware_spi.c b/drivers/spi/designware_spi.c
index 1c7d0ca310b6..637ea57eba24 100644
--- a/drivers/spi/designware_spi.c
+++ b/drivers/spi/designware_spi.c
@@ -250,15 +250,13 @@ static int dw_spi_of_to_plat(struct udevice *bus)
if (!plat->regs)
return -EINVAL;
 
-   /* Use 500KHz as a suitable default */
+   /* Specify fixed max-frequency as default */
plat->frequency = dev_read_u32_default(bus, "spi-max-frequency",
-  50);
+  0);
 
if (dev_read_bool(bus, "spi-slave"))
return -EINVAL;
 
-   dev_info(bus, "max-frequency=%d\n", plat->frequency);
-
return request_gpio_cs(bus);
 }
 
@@ -362,12 +360,17 @@ static int dw_spi_probe(struct udevice *bus)
u32 version;
 
priv->regs = plat->regs;
-   priv->freq = plat->frequency;
 
ret = dw_spi_get_clk(bus, >bus_clk_rate);
if (ret)
return ret;
 
+   if (!plat->frequency)
+   plat->frequency = priv->bus_clk_rate;
+
+   dev_info(bus, "max-frequency=%d\n", plat->frequency);
+   priv->freq = plat->frequency;
+
ret = dw_spi_reset(bus);
if (ret)
return ret;
-- 
2.25.1



[PATCH] MAINTAINERS: Step up as maintainers of UniPhier SoC platform

2023-09-22 Thread Kunihiko Hayashi
Update maintainers for UniPhier SoC platform.

Signed-off-by: Kunihiko Hayashi 
---
 MAINTAINERS | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 0a10a436bcec..281a3f81f73a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -723,7 +723,10 @@ F: drivers/usb/musb-new/ux500.c
 F: drivers/video/mcde_simple.c
 
 ARM UNIPHIER
-S: Orphan (Since 2020-09)
+M: Kunihiko Hayashi 
+R: Dai Okamura 
+S: Maintained
+F: arch/arm/dts/uniphier-*
 F: arch/arm/mach-uniphier/
 F: configs/uniphier_*_defconfig
 N: uniphier
-- 
2.25.1



[PATCH v2] board_f: Relocate fdt even if GD_FLG_SKIP_RELOC is set

2023-06-20 Thread Kunihiko Hayashi
In case of OF_SEPARATE (!OF_EMBED), the devicetree blob is placed
after _end, and fdt_find_separate() always returns _end. There is
a .bss section after _end and the section is cleared before relocation.

When GD_FLG_SKIP_RELOC is set, relocation is skipped, so the blob is
still in .bss section, but will be cleared. As a result, the devicetree
become invalid.

To avoid this issue, should relocate it regardless of GD_FLG_SKIP_RELOC
in reloc_fdt().

Signed-off-by: Kunihiko Hayashi 
---
 common/board_f.c | 2 --
 1 file changed, 2 deletions(-)

Changes since v1:
- Remove condition for skipping fdt relocation (always relocate)

diff --git a/common/board_f.c b/common/board_f.c
index 1688e27071fc..334d04af197b 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -633,8 +633,6 @@ static int init_post(void)
 static int reloc_fdt(void)
 {
if (!IS_ENABLED(CONFIG_OF_EMBED)) {
-   if (gd->flags & GD_FLG_SKIP_RELOC)
-   return 0;
if (gd->new_fdt) {
memcpy(gd->new_fdt, gd->fdt_blob,
   fdt_totalsize(gd->fdt_blob));
-- 
2.25.1



Re: [PATCH] board_f: Relocate fdt if SKIP_RELOC and fdt is in bss

2023-06-20 Thread Kunihiko Hayashi

Hi Simon,

On 2023/06/19 21:36, Simon Glass wrote:

Hi Kunihiko,

On Fri, 16 Jun 2023 at 00:59, Kunihiko Hayashi
 wrote:


Hi Simon,

Thank you for your comment.

On 2023/06/13 6:17, Simon Glass wrote:

Hi Kunihiko,

On Thu, 8 Jun 2023 at 07:53, Kunihiko Hayashi
 wrote:


There are cases that the devicetree blob is placed after _end, such as
fdt_find_separate() returns _end. This is in bss area cleared before
relocation.

When GD_FLG_SKIP_RELOC is set, the blob is still in bss, but will be
cleared. As a result, the devicetree become invalid.

To avoid this issue, should relocate it to the new fdt area using the
latter condition in reloc_fdt().

Signed-off-by: Kunihiko Hayashi 
---
   common/board_f.c | 3 ++-
   1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/common/board_f.c b/common/board_f.c
index 51d2f3c365e9..9a245872d190 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -622,7 +622,8 @@ static int init_post(void)
   static int reloc_fdt(void)
   {
  if (!IS_ENABLED(CONFIG_OF_EMBED)) {
-   if (gd->flags & GD_FLG_SKIP_RELOC)
+   if (gd->flags & GD_FLG_SKIP_RELOC &&
+   gd->fdt_blob != &_end)


!IS_ENABLED(CONFIG_OF_EMBED)  == IS_ENABLED(CONFIG_OF_SEPARATE)

reloc_fdt() is only called by U-Boot (not SP)

So the FDT was found by fdt_find_separate() and gd->fdt_blob == &_end

So, is there any case where:

gd->flags & GD_FLG_SKIP_RELO is true
gd->fdt_blob != &_end is true

?


Yes. But in fact,
if (gd->flags & GD_FLG_SKIP_RELOC is true) and (gd->fdt_blob overlaps .bss
section),
the fdt should be relocated because clear_bss() will clear the fdt after
that.


I misstated my point. I am wondering if  gd(->fdt_blob != &_end) is
ever false? If not, then we can always relocate.


When CONFIG_OF_SEPARATE is true, it seems that (gd->fdt_blob != &_end) is
always false because the fdt file is concatinated to the end of the image file
in Makefile.




I can't think of one.

If that is the case, then you could add a comment to this effect and
unconditionally relocate if !CONFIG_OF_EMBED.


I'm not sure if it is possible to unconditionally relocate the fdt,
I think we need to know if the fdt overlaps .bss section.


What is the down-side of always relocating, and when would the fdt not
overlap the .bss section?


The fdt always overlaps the .bss section, so it should be relocated
even if (gd->flags & GL_FLG_SKIP_RELOC) is true.


Note that OF_EMBED is not to be used in production boards. That is
violated by a few things at present, but IMO always relocating should
be safe.


Yes, I undestand.
I delete the condition in v2, and change to always relocate the fdt
in case of !OF_EMBED.

Thank you,

---
Best Regards
Kunihiko Hayashi


Re: [PATCH] board_f: Relocate fdt if SKIP_RELOC and fdt is in bss

2023-06-15 Thread Kunihiko Hayashi

Hi Simon,

Thank you for your comment.

On 2023/06/13 6:17, Simon Glass wrote:

Hi Kunihiko,

On Thu, 8 Jun 2023 at 07:53, Kunihiko Hayashi
 wrote:


There are cases that the devicetree blob is placed after _end, such as
fdt_find_separate() returns _end. This is in bss area cleared before
relocation.

When GD_FLG_SKIP_RELOC is set, the blob is still in bss, but will be
cleared. As a result, the devicetree become invalid.

To avoid this issue, should relocate it to the new fdt area using the
latter condition in reloc_fdt().

Signed-off-by: Kunihiko Hayashi 
---
  common/board_f.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/common/board_f.c b/common/board_f.c
index 51d2f3c365e9..9a245872d190 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -622,7 +622,8 @@ static int init_post(void)
  static int reloc_fdt(void)
  {
 if (!IS_ENABLED(CONFIG_OF_EMBED)) {
-   if (gd->flags & GD_FLG_SKIP_RELOC)
+   if (gd->flags & GD_FLG_SKIP_RELOC &&
+   gd->fdt_blob != &_end)


!IS_ENABLED(CONFIG_OF_EMBED)  == IS_ENABLED(CONFIG_OF_SEPARATE)

reloc_fdt() is only called by U-Boot (not SP)

So the FDT was found by fdt_find_separate() and gd->fdt_blob == &_end

So, is there any case where:

gd->flags & GD_FLG_SKIP_RELO is true
gd->fdt_blob != &_end is true

?


Yes. But in fact,
if (gd->flags & GD_FLG_SKIP_RELOC is true) and (gd->fdt_blob overlaps .bss 
section),
the fdt should be relocated because clear_bss() will clear the fdt after that.


I can't think of one.

If that is the case, then you could add a comment to this effect and
unconditionally relocate if !CONFIG_OF_EMBED.


I'm not sure if it is possible to unconditionally relocate the fdt,
I think we need to know if the fdt overlaps .bss section.


Of course the down size is that you would probably rather relocate it
to just after BSS (rather than to the top of memory) but it doesn't
much matter, I suspect.

Thank you,

---
Best Regards
Kunihiko Hayashi


[PATCH] board_f: Relocate fdt if SKIP_RELOC and fdt is in bss

2023-06-08 Thread Kunihiko Hayashi
There are cases that the devicetree blob is placed after _end, such as
fdt_find_separate() returns _end. This is in bss area cleared before
relocation.

When GD_FLG_SKIP_RELOC is set, the blob is still in bss, but will be
cleared. As a result, the devicetree become invalid.

To avoid this issue, should relocate it to the new fdt area using the
latter condition in reloc_fdt().

Signed-off-by: Kunihiko Hayashi 
---
 common/board_f.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/common/board_f.c b/common/board_f.c
index 51d2f3c365e9..9a245872d190 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -622,7 +622,8 @@ static int init_post(void)
 static int reloc_fdt(void)
 {
if (!IS_ENABLED(CONFIG_OF_EMBED)) {
-   if (gd->flags & GD_FLG_SKIP_RELOC)
+   if (gd->flags & GD_FLG_SKIP_RELOC &&
+   gd->fdt_blob != &_end)
return 0;
if (gd->new_fdt) {
memcpy(gd->new_fdt, gd->fdt_blob,
-- 
2.25.1



Re: [PATCH v2 5/8] usb: dwc3: Add dwc3 glue driver for am62

2023-04-23 Thread Kunihiko Hayashi
e_bits(syscon, args.args[0],
PHY_PLL_REFCLK_MASK, rate_code);
+   if (ret) {
+   dev_err(dev, "failed to set phy pll reference clock
rate\n");
+   return;
+   }
+
+   /* VBUS divider select */
+   reg = readl(usbss + USBSS_PHY_CONFIG);
+   vbus_divider = dev_read_bool(dev, "ti,vbus-divider");
+   if (vbus_divider)
+   reg |= 1 << USBSS_PHY_VBUS_SEL_SHIFT;
+
+   writel(reg, usbss + USBSS_PHY_CONFIG);
+
+   /* Set mode valid */
+   reg = readl(usbss + USBSS_MODE_CONTROL);
+   reg |= USBSS_MODE_VALID;
+   writel(reg, usbss + USBSS_MODE_CONTROL);
+}
+
+struct dwc3_glue_ops ti_am62_ops = {
+   .glue_configure = dwc3_ti_am62_glue_configure,
+};
+
+static const struct udevice_id dwc3_am62_match[] = {
+   { .compatible = "ti,am62-usb", .data = (ulong)_am62_ops },
+   { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(dwc3_am62_wrapper) = {
+   .name   = "dwc3-am62",
+   .id = UCLASS_SIMPLE_BUS,
+   .of_match = dwc3_am62_match,
+   .bind = dwc3_glue_bind,
+   .probe = dwc3_glue_probe,
+   .remove = dwc3_glue_remove,
+   .plat_auto  = sizeof(struct dwc3_glue_data),
+


The pointless blank line.


+};


Thank you,

---
Best Regards
Kunihiko Hayashi


[PATCH] spi: f-ospi: Add missing spi_mem_default_supports_op() helper

2023-03-26 Thread Kunihiko Hayashi
The .supports_op() callback function returns true by default after
performing driver-specific checks. Therefore the driver cannot apply
the buswidth in devicetree.

Call spi_mem_default_supports_op() helper to handle the buswidth
in devicetree.

Fixes: 358f803ae21c ("spi: Add Socionext F_OSPI SPI flash controller driver")
Signed-off-by: Kunihiko Hayashi 
---
 drivers/spi/spi-sn-f-ospi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/spi/spi-sn-f-ospi.c b/drivers/spi/spi-sn-f-ospi.c
index ebf2903d3e..e3633a5260 100644
--- a/drivers/spi/spi-sn-f-ospi.c
+++ b/drivers/spi/spi-sn-f-ospi.c
@@ -556,7 +556,7 @@ static bool f_ospi_supports_op(struct spi_slave *slave,
if (!f_ospi_supports_op_width(op))
return false;
 
-   return true;
+   return spi_mem_default_supports_op(slave, op);
 }
 
 static int f_ospi_adjust_op_size(struct spi_slave *slave, struct spi_mem_op 
*op)
-- 
2.25.1



[PATCH 2/2] ARM: dts: uniphier: Sync DT with Linux v6.2

2023-02-27 Thread Kunihiko Hayashi
Synchronize devicetree sources with Linux v6.2.

- Use GIC interrupt definitions
- Add reg properties in USB-glue and SoC-glue node
- Fix node names to follow the generic names list in DT specification
- Add L2 cache and AHCI nodes
- Update nand and pcie nodes
- And some trivial fixes

Signed-off-by: Kunihiko Hayashi 
---
 arch/arm/dts/uniphier-ld11-global.dts |   4 +
 arch/arm/dts/uniphier-ld11-ref.dts|   6 +-
 arch/arm/dts/uniphier-ld11.dtsi   |  94 ++--
 arch/arm/dts/uniphier-ld20.dtsi   | 129 +---
 arch/arm/dts/uniphier-ld4-ref.dts |  10 +-
 arch/arm/dts/uniphier-ld4.dtsi|  76 ++
 arch/arm/dts/uniphier-pro4-ace.dts|   8 +
 arch/arm/dts/uniphier-pro4-ref.dts|  18 ++-
 arch/arm/dts/uniphier-pro4-sanji.dts  |   6 +-
 arch/arm/dts/uniphier-pro4.dtsi   | 205 +++--
 arch/arm/dts/uniphier-pro5.dtsi   | 101 +++--
 arch/arm/dts/uniphier-pxs2-gentil.dts |   4 +
 arch/arm/dts/uniphier-pxs2.dtsi   | 155 ---
 arch/arm/dts/uniphier-pxs3-ref.dts|  18 ++-
 arch/arm/dts/uniphier-pxs3.dtsi   | 206 +++---
 arch/arm/dts/uniphier-sld8-ref.dts|  10 +-
 arch/arm/dts/uniphier-sld8.dtsi   |  77 ++
 17 files changed, 754 insertions(+), 373 deletions(-)

diff --git a/arch/arm/dts/uniphier-ld11-global.dts 
b/arch/arm/dts/uniphier-ld11-global.dts
index 644ffb9707..da44a15a8a 100644
--- a/arch/arm/dts/uniphier-ld11-global.dts
+++ b/arch/arm/dts/uniphier-ld11-global.dts
@@ -164,4 +164,8 @@
 
  {
status = "okay";
+
+   nand@0 {
+   reg = <0>;
+   };
 };
diff --git a/arch/arm/dts/uniphier-ld11-ref.dts 
b/arch/arm/dts/uniphier-ld11-ref.dts
index 617d2b1e9b..414aeb99e6 100644
--- a/arch/arm/dts/uniphier-ld11-ref.dts
+++ b/arch/arm/dts/uniphier-ld11-ref.dts
@@ -39,11 +39,11 @@
 };
 
  {
-   interrupts = <0 8>;
+   interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
 };
 
  {
-   interrupts = <0 8>;
+   interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
 };
 
  {
@@ -51,7 +51,7 @@
 };
 
  {
-   xirq0 {
+   xirq0-hog {
gpio-hog;
gpios = ;
input;
diff --git a/arch/arm/dts/uniphier-ld11.dtsi b/arch/arm/dts/uniphier-ld11.dtsi
index 104d56d625..7bb36b0714 100644
--- a/arch/arm/dts/uniphier-ld11.dtsi
+++ b/arch/arm/dts/uniphier-ld11.dtsi
@@ -7,6 +7,7 @@
 
 #include 
 #include 
+#include 
 
 / {
compatible = "socionext,uniphier-ld11";
@@ -35,6 +36,7 @@
reg = <0 0x000>;
clocks = <_clk 33>;
enable-method = "psci";
+   next-level-cache = <>;
operating-points-v2 = <_opp>;
};
 
@@ -44,8 +46,13 @@
reg = <0 0x001>;
clocks = <_clk 33>;
enable-method = "psci";
+   next-level-cache = <>;
operating-points-v2 = <_opp>;
};
+
+   l2: l2-cache {
+   compatible = "cache";
+   };
};
 
cluster0_opp: opp-table {
@@ -102,10 +109,10 @@
 
timer {
compatible = "arm,armv8-timer";
-   interrupts = <1 13 4>,
-<1 14 4>,
-<1 11 4>,
-<1 10 4>;
+   interrupts = ,
+,
+,
+;
};
 
reserved-memory {
@@ -131,7 +138,7 @@
reg = <0x54006000 0x100>;
#address-cells = <1>;
#size-cells = <0>;
-   interrupts = <0 39 4>;
+   interrupts = ;
pinctrl-names = "default";
pinctrl-0 = <_spi0>;
clocks = <_clk 11>;
@@ -144,7 +151,7 @@
reg = <0x54006100 0x100>;
#address-cells = <1>;
#size-cells = <0>;
-   interrupts = <0 216 4>;
+   interrupts = ;
pinctrl-names = "default";
pinctrl-0 = <_spi1>;
clocks = <_clk 12>;
@@ -155,7 +162,7 @@
compatible = "socionext,uniphier-uart";
status = "disabled";
reg = <0x54006800 0x40>;
-   interrupts = <0 33 4>;
+   interrupts = ;
pinctrl-names = "default";
   

[PATCH 1/2] ARM: dts: uniphier: Switch USB node to the original

2023-02-27 Thread Kunihiko Hayashi
UniPhier DT applies its own USB node for U-Boot due to the USB driver
constrains. After solving this issue, u-boot allows the original USB node.

After switching USB node, synchronization of USB node with Linux becomes
possible.

Signed-off-by: Kunihiko Hayashi 
---
 arch/arm/dts/uniphier-ld20.dtsi | 21 +
 arch/arm/dts/uniphier-pro4.dtsi | 42 ++---
 arch/arm/dts/uniphier-pxs2.dtsi | 42 ++---
 arch/arm/dts/uniphier-pxs3.dtsi | 42 ++---
 4 files changed, 7 insertions(+), 140 deletions(-)

diff --git a/arch/arm/dts/uniphier-ld20.dtsi b/arch/arm/dts/uniphier-ld20.dtsi
index 4549935c42..1aad4cff5b 100644
--- a/arch/arm/dts/uniphier-ld20.dtsi
+++ b/arch/arm/dts/uniphier-ld20.dtsi
@@ -744,7 +744,7 @@
};
};
 
-   _usb: usb@65a0 {
+   usb: usb@65a0 {
compatible = "socionext,uniphier-dwc3", "snps,dwc3";
status = "disabled";
reg = <0x65a0 0xcd00>;
@@ -894,25 +894,6 @@
};
};
 
-   /* FIXME: U-Boot own node */
-   usb: usb@65b0 {
-   compatible = "socionext,uniphier-ld20-dwc3";
-   reg = <0x65b0 0x1000>;
-   #address-cells = <1>;
-   #size-cells = <1>;
-   ranges;
-   pinctrl-names = "default";
-   pinctrl-0 = <_usb0>, <_usb1>,
-   <_usb2>, <_usb3>;
-   dwc3@65a0 {
-   compatible = "snps,dwc3";
-   reg = <0x65a0 0x1>;
-   interrupts = <0 134 4>;
-   dr_mode = "host";
-   tx-fifo-resize;
-   };
-   };
-
pcie: pcie@6600 {
compatible = "socionext,uniphier-pcie", "snps,dw-pcie";
status = "disabled";
diff --git a/arch/arm/dts/uniphier-pro4.dtsi b/arch/arm/dts/uniphier-pro4.dtsi
index 9dae4e9b23..cd706f485e 100644
--- a/arch/arm/dts/uniphier-pro4.dtsi
+++ b/arch/arm/dts/uniphier-pro4.dtsi
@@ -503,7 +503,7 @@
};
};
 
-   _usb0: usb@65a0 {
+   usb0: usb@65a0 {
compatible = "socionext,uniphier-dwc3", "snps,dwc3";
status = "disabled";
reg = <0x65a0 0xcd00>;
@@ -556,26 +556,7 @@
};
};
 
-   /* FIXME: U-Boot own node */
-   usb0: usb@65b0 {
-   compatible = "socionext,uniphier-pro4-dwc3";
-   status = "disabled";
-   reg = <0x65b0 0x1000>;
-   #address-cells = <1>;
-   #size-cells = <1>;
-   ranges;
-   pinctrl-names = "default";
-   pinctrl-0 = <_usb0>;
-   dwc3@65a0 {
-   compatible = "snps,dwc3";
-   reg = <0x65a0 0x1>;
-   interrupts = <0 134 4>;
-   dr_mode = "host";
-   tx-fifo-resize;
-   };
-   };
-
-   _usb1: usb@65c0 {
+   usb1: usb@65c0 {
compatible = "socionext,uniphier-dwc3", "snps,dwc3";
status = "disabled";
reg = <0x65c0 0xcd00>;
@@ -617,25 +598,6 @@
};
};
 
-   /* FIXME: U-Boot own node */
-   usb1: usb@65d0 {
-   compatible = "socionext,uniphier-pro4-dwc3";
-   status = "disabled";
-   reg = <0x65d0 0x1000>;
-   #address-cells = <1>;
-   #size-cells = <1>;
-   ranges;
-   pinctrl-names = "default";
-   pinctrl-0 = <_usb1>;
-   dwc3@65c0 {
-   compatible = "snps,dwc3";
-   reg = <0x65c0 0x1>;
-   interrupts = <0 137 4>;
-   dr_

[PATCH 0/2] Update UniPhier devicetree

2023-02-27 Thread Kunihiko Hayashi
Migrate the USB node to the original node after updating dwc3-generic and
dwc3-uniphier.
https://lists.denx.de/pipermail/u-boot/2023-February/509635.html

And synchronize UniPhier devicetree with Linux v6.2.

Kunihiko Hayashi (2):
  ARM: dts: uniphier: Switch USB node to the original
  ARM: dts: uniphier: Sync DT with Linux v6.2

 arch/arm/dts/uniphier-ld11-global.dts |   4 +
 arch/arm/dts/uniphier-ld11-ref.dts|   6 +-
 arch/arm/dts/uniphier-ld11.dtsi   |  94 +-
 arch/arm/dts/uniphier-ld20.dtsi   | 150 
 arch/arm/dts/uniphier-ld4-ref.dts |  10 +-
 arch/arm/dts/uniphier-ld4.dtsi|  76 
 arch/arm/dts/uniphier-pro4-ace.dts|   8 +
 arch/arm/dts/uniphier-pro4-ref.dts|  18 +-
 arch/arm/dts/uniphier-pro4-sanji.dts  |   6 +-
 arch/arm/dts/uniphier-pro4.dtsi   | 247 -
 arch/arm/dts/uniphier-pro5.dtsi   | 101 ++-
 arch/arm/dts/uniphier-pxs2-gentil.dts |   4 +
 arch/arm/dts/uniphier-pxs2.dtsi   | 197 ++--
 arch/arm/dts/uniphier-pxs3-ref.dts|  18 +-
 arch/arm/dts/uniphier-pxs3.dtsi   | 248 --
 arch/arm/dts/uniphier-sld8-ref.dts|  10 +-
 arch/arm/dts/uniphier-sld8.dtsi   |  77 
 17 files changed, 761 insertions(+), 513 deletions(-)

-- 
2.25.1



Re: [PATCH v4 00/10] usb: dwc3: Refactor dwc3-generic and apply to dwc3-uniphier

2023-02-21 Thread Kunihiko Hayashi

Hi Marek,

On 2023/02/21 0:53, Marek Vasut wrote:

On 2/20/23 06:50, Kunihiko Hayashi wrote:

This series achieves refactoring of dwc3-generic.

First, dwc3-generic allows DT controller nodes to be children of glue
nodes,
but outside of glue nodes.

To achieve this goal, define a glue-specific function to get controller
node,
look up more reference clocks in the controller node, and initialize
clocks
in children of glue node before access to the controller,

Next, this series exports the structures and functions from the driver
source
to the header, and replaces dwc3-uniphier driver as one implementation
using
them. This expects dwc3-generic to prevent more SoC-dependent codes.

The dwc3-uniphier has original USB node, however, tentatively added its
own
node dedicated to U-Boot. After this refactoring, the driver needs to add
clock entries and PHY driver to enable them corresponding to the
properties
in the original node.

PATCH 1 has been provided below.

https://patchwork.ozlabs.org/project/uboot/patch/20221215223822.137739-1-ma...@denx.de/

PATCH 2 is based on the suggested patch from Marek.

PATCH 4-5 and 9-10 have been already reviewed in the previous v1.
https://lists.denx.de/pipermail/u-boot/2023-January/505689.html

I think this series is good to go. Do you want to pull this through the
uniphier git tree and send PR to Tom that way , or shall I pick it all
via usb git tree ? I think the former option is better.


Currently I don't have the public uniphier git tree and
the maintainership, so I'd like to choose the latter at the moment.
Colud you please pick it now?

Thank you,

---
Best Regards
Kunihiko Hayashi


[PATCH v4 08/10] phy: socionext: Add UniPhier USB3 PHY driver

2023-02-19 Thread Kunihiko Hayashi
Add USB3 PHY driver support to control clocks and resets needed to enable
PHY. The phy_ops->init() and exit() control PHY clocks and resets only,
and clocks and resets for the controller and the parent logic are enabled
in advance.

Signed-off-by: Kunihiko Hayashi 
---
 drivers/phy/socionext/Kconfig |   8 ++
 drivers/phy/socionext/Makefile|   1 +
 drivers/phy/socionext/phy-uniphier-usb3.c | 168 ++
 3 files changed, 177 insertions(+)
 create mode 100644 drivers/phy/socionext/phy-uniphier-usb3.c

diff --git a/drivers/phy/socionext/Kconfig b/drivers/phy/socionext/Kconfig
index bcd579e98e..de87d5b010 100644
--- a/drivers/phy/socionext/Kconfig
+++ b/drivers/phy/socionext/Kconfig
@@ -10,3 +10,11 @@ config PHY_UNIPHIER_PCIE
help
  Enable this to support PHY implemented in PCIe controller
  on UniPhier SoCs.
+
+config PHY_UNIPHIER_USB3
+   bool "UniPhier USB3 PHY driver"
+   depends on PHY && ARCH_UNIPHIER
+   imply REGMAP
+   help
+ Enable this to support PHY implemented in USB3 controller
+ on UniPhier SoCs.
diff --git a/drivers/phy/socionext/Makefile b/drivers/phy/socionext/Makefile
index 5484360b70..94d3aa68cf 100644
--- a/drivers/phy/socionext/Makefile
+++ b/drivers/phy/socionext/Makefile
@@ -4,3 +4,4 @@
 #
 
 obj-$(CONFIG_PHY_UNIPHIER_PCIE)+= phy-uniphier-pcie.o
+obj-$(CONFIG_PHY_UNIPHIER_USB3)+= phy-uniphier-usb3.o
diff --git a/drivers/phy/socionext/phy-uniphier-usb3.c 
b/drivers/phy/socionext/phy-uniphier-usb3.c
new file mode 100644
index 00..1d65b0b08f
--- /dev/null
+++ b/drivers/phy/socionext/phy-uniphier-usb3.c
@@ -0,0 +1,168 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * phy_uniphier_usb3.c - Socionext UniPhier Usb3 PHY driver
+ * Copyright 2019-2023 Socionext, Inc.
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+struct uniphier_usb3phy_priv {
+   struct clk *clk_link, *clk_phy, *clk_parent, *clk_phyext;
+   struct reset_ctl *rst_link, *rst_phy, *rst_parent;
+};
+
+static int uniphier_usb3phy_init(struct phy *phy)
+{
+   struct uniphier_usb3phy_priv *priv = dev_get_priv(phy->dev);
+   int ret;
+
+   ret = clk_enable(priv->clk_phy);
+   if (ret)
+   return ret;
+
+   ret = reset_deassert(priv->rst_phy);
+   if (ret)
+   goto out_clk;
+
+   if (priv->clk_phyext) {
+   ret = clk_enable(priv->clk_phyext);
+   if (ret)
+   goto out_rst;
+   }
+
+   return 0;
+
+out_rst:
+   reset_assert(priv->rst_phy);
+out_clk:
+   clk_disable(priv->clk_phy);
+
+   return ret;
+}
+
+static int uniphier_usb3phy_exit(struct phy *phy)
+{
+   struct uniphier_usb3phy_priv *priv = dev_get_priv(phy->dev);
+
+   if (priv->clk_phyext)
+   clk_disable(priv->clk_phyext);
+
+   reset_assert(priv->rst_phy);
+   clk_disable(priv->clk_phy);
+
+   return 0;
+}
+
+static int uniphier_usb3phy_probe(struct udevice *dev)
+{
+   struct uniphier_usb3phy_priv *priv = dev_get_priv(dev);
+   int ret;
+
+   priv->clk_link = devm_clk_get(dev, "link");
+   if (IS_ERR(priv->clk_link)) {
+   printf("Failed to get link clock\n");
+   return PTR_ERR(priv->clk_link);
+   }
+
+   priv->clk_phy = devm_clk_get(dev, "phy");
+   if (IS_ERR(priv->clk_link)) {
+   printf("Failed to get phy clock\n");
+   return PTR_ERR(priv->clk_link);
+   }
+
+   priv->clk_parent = devm_clk_get_optional(dev, "gio");
+   if (IS_ERR(priv->clk_parent)) {
+   printf("Failed to get parent clock\n");
+   return PTR_ERR(priv->clk_parent);
+   }
+
+   priv->clk_phyext = devm_clk_get_optional(dev, "phy-ext");
+   if (IS_ERR(priv->clk_phyext)) {
+   printf("Failed to get external phy clock\n");
+   return PTR_ERR(priv->clk_phyext);
+   }
+
+   priv->rst_link = devm_reset_control_get(dev, "link");
+   if (IS_ERR(priv->rst_link)) {
+   printf("Failed to get link reset\n");
+   return PTR_ERR(priv->rst_link);
+   }
+
+   priv->rst_phy = devm_reset_control_get(dev, "phy");
+   if (IS_ERR(priv->rst_phy)) {
+   printf("Failed to get phy reset\n");
+   return PTR_ERR(priv->rst_phy);
+   }
+
+   priv->rst_parent = devm_reset_control_get_optional(dev, "gio");
+   if (IS_ERR(priv->rst_parent)) {
+   printf("Failed to get parent reset\n");
+   return PTR_ERR(priv->rst_parent);
+   }
+
+   if (priv->clk_parent) {
+   ret = clk_enable(priv->clk_parent);
+ 

[PATCH v4 09/10] usb: dwc3-uniphier: Use dwc3-generic instead of xhci-dwc3

2023-02-19 Thread Kunihiko Hayashi
dwc3-uniphier depends on xhci-dwc3 framework, however, it is preferable
to use dwc3-generic.

This driver calls the exported dwc3-generic functions and redefine
the SoC-dependent operations to fit dwc3-generic.

Signed-off-by: Kunihiko Hayashi 
Reviewed-by: Marek Vasut 
---
 drivers/usb/dwc3/Kconfig |   4 +-
 drivers/usb/dwc3/dwc3-uniphier.c | 116 ---
 2 files changed, 78 insertions(+), 42 deletions(-)

diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index f010291d02..7ddfa94e51 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -55,7 +55,9 @@ config USB_DWC3_MESON_GXL
 
 config USB_DWC3_UNIPHIER
bool "DesignWare USB3 Host Support on UniPhier Platforms"
-   depends on ARCH_UNIPHIER && USB_XHCI_DWC3
+   depends on ARCH_UNIPHIER && USB_DWC3
+   select USB_DWC3_GENERIC
+   select PHY_UNIPHIER_USB3
help
  Support of USB2/3 functionality in Socionext UniPhier platforms.
  Say 'Y' here if you have one such device.
diff --git a/drivers/usb/dwc3/dwc3-uniphier.c b/drivers/usb/dwc3/dwc3-uniphier.c
index 54b52dcd66..ab85428a70 100644
--- a/drivers/usb/dwc3/dwc3-uniphier.c
+++ b/drivers/usb/dwc3/dwc3-uniphier.c
@@ -4,14 +4,17 @@
  *
  * Copyright (C) 2016-2017 Socionext Inc.
  *   Author: Masahiro Yamada 
+ *   Author: Kunihiko Hayashi 
  */
 
 #include 
-#include 
+#include 
 #include 
-#include 
-#include 
-#include 
+#include 
+
+#include "core.h"
+#include "gadget.h"
+#include "dwc3-generic.h"
 
 #define UNIPHIER_PRO4_DWC3_RESET   0x40
 #define   UNIPHIER_PRO4_DWC3_RESET_XIOMMU  BIT(5)
@@ -27,8 +30,11 @@
 #define UNIPHIER_PXS2_DWC3_RESET   0x00
 #define   UNIPHIER_PXS2_DWC3_RESET_XLINK   BIT(15)
 
-static int uniphier_pro4_dwc3_init(void __iomem *regs)
+static void uniphier_pro4_dwc3_init(struct udevice *dev, int index,
+   enum usb_dr_mode mode)
 {
+   struct dwc3_glue_data *glue = dev_get_plat(dev);
+   void *regs = map_physmem(glue->regs, glue->size, MAP_NOCACHE);
u32 tmp;
 
tmp = readl(regs + UNIPHIER_PRO4_DWC3_RESET);
@@ -36,11 +42,14 @@ static int uniphier_pro4_dwc3_init(void __iomem *regs)
tmp |= UNIPHIER_PRO4_DWC3_RESET_XIOMMU | UNIPHIER_PRO4_DWC3_RESET_XLINK;
writel(tmp, regs + UNIPHIER_PRO4_DWC3_RESET);
 
-   return 0;
+   unmap_physmem(regs, MAP_NOCACHE);
 }
 
-static int uniphier_pro5_dwc3_init(void __iomem *regs)
+static void uniphier_pro5_dwc3_init(struct udevice *dev, int index,
+   enum usb_dr_mode mode)
 {
+   struct dwc3_glue_data *glue = dev_get_plat(dev);
+   void *regs = map_physmem(glue->regs, glue->size, MAP_NOCACHE);
u32 tmp;
 
tmp = readl(regs + UNIPHIER_PRO5_DWC3_RESET);
@@ -49,72 +58,97 @@ static int uniphier_pro5_dwc3_init(void __iomem *regs)
tmp |= UNIPHIER_PRO5_DWC3_RESET_XLINK | UNIPHIER_PRO5_DWC3_RESET_XIOMMU;
writel(tmp, regs + UNIPHIER_PRO5_DWC3_RESET);
 
-   return 0;
+   unmap_physmem(regs, MAP_NOCACHE);
 }
 
-static int uniphier_pxs2_dwc3_init(void __iomem *regs)
+static void uniphier_pxs2_dwc3_init(struct udevice *dev, int index,
+   enum usb_dr_mode mode)
 {
+   struct dwc3_glue_data *glue = dev_get_plat(dev);
+   void *regs = map_physmem(glue->regs, glue->size, MAP_NOCACHE);
u32 tmp;
 
tmp = readl(regs + UNIPHIER_PXS2_DWC3_RESET);
tmp |= UNIPHIER_PXS2_DWC3_RESET_XLINK;
writel(tmp, regs + UNIPHIER_PXS2_DWC3_RESET);
 
-   return 0;
+   unmap_physmem(regs, MAP_NOCACHE);
 }
 
-static int uniphier_dwc3_probe(struct udevice *dev)
+static int dwc3_uniphier_glue_get_ctrl_dev(struct udevice *dev, ofnode *node)
 {
-   fdt_addr_t base;
-   void __iomem *regs;
-   int (*init)(void __iomem *regs);
-   int ret;
+   struct udevice *child;
+   const char *name;
+   ofnode subnode;
+
+   /*
+* "controller reset" belongs to glue logic, and it should be
+* accessible in .glue_configure() before access to the controller
+* begins.
+*/
+   ofnode_for_each_subnode(subnode, dev_ofnode(dev)) {
+   name = ofnode_get_name(subnode);
+   if (!strncmp(name, "reset", 5))
+   device_bind_driver_to_node(dev, "uniphier-reset",
+  name, subnode, );
+   }
+
+   /* Get controller node that is placed separately from the glue node */
+   *node = ofnode_by_compatible(dev_ofnode(dev->parent),
+"socionext,uniphier-dwc3");
 
-   base = dev_read_addr(dev);
-   if (base == FDT_ADDR_T_NONE)
-   return -EINVAL;
-
-   regs = ioremap(base, SZ_32K);
-   if (!regs)
-   return -ENOMEM;
+ 

[PATCH v4 10/10] uniphier_defconfig: Disable USB_XHCI_DWC3

2023-02-19 Thread Kunihiko Hayashi
Replacing with dwc3-generic, no need USB_XHCI_DWC3 anymore.

Signed-off-by: Kunihiko Hayashi 
Reviewed-by: Marek Vasut 
---
 configs/uniphier_v7_defconfig | 1 -
 configs/uniphier_v8_defconfig | 1 -
 2 files changed, 2 deletions(-)

diff --git a/configs/uniphier_v7_defconfig b/configs/uniphier_v7_defconfig
index d626968c76..03feb04b93 100644
--- a/configs/uniphier_v7_defconfig
+++ b/configs/uniphier_v7_defconfig
@@ -82,7 +82,6 @@ CONFIG_DM_SPI=y
 CONFIG_UNIPHIER_SPI=y
 CONFIG_USB=y
 CONFIG_USB_XHCI_HCD=y
-CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_GENERIC=y
 CONFIG_USB_DWC3=y
diff --git a/configs/uniphier_v8_defconfig b/configs/uniphier_v8_defconfig
index 6a0e2666cf..ed58b5746e 100644
--- a/configs/uniphier_v8_defconfig
+++ b/configs/uniphier_v8_defconfig
@@ -71,7 +71,6 @@ CONFIG_SYSRESET=y
 CONFIG_SYSRESET_PSCI=y
 CONFIG_USB=y
 CONFIG_USB_XHCI_HCD=y
-CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_GENERIC=y
 CONFIG_USB_DWC3=y
-- 
2.25.1



[PATCH v4 05/10] usb: dwc3-generic: Add the size of regs property to glue structure

2023-02-19 Thread Kunihiko Hayashi
Add the size of regs property to the glue structure to correctly
specify the register region to map.

Signed-off-by: Kunihiko Hayashi 
Reviewed-by: Marek Vasut 
---
 drivers/usb/dwc3/dwc3-generic.c | 2 +-
 drivers/usb/dwc3/dwc3-generic.h | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
index 4576390ec7..acbf7acb19 100644
--- a/drivers/usb/dwc3/dwc3-generic.c
+++ b/drivers/usb/dwc3/dwc3-generic.c
@@ -542,7 +542,7 @@ int dwc3_glue_probe(struct udevice *dev)
phy.dev = NULL;
}
 
-   glue->regs = dev_read_addr(dev);
+   glue->regs = dev_read_addr_size_index(dev, 0, >size);
 
ret = dwc3_glue_clk_init(dev, glue);
if (ret)
diff --git a/drivers/usb/dwc3/dwc3-generic.h b/drivers/usb/dwc3/dwc3-generic.h
index 824f678841..40902c8923 100644
--- a/drivers/usb/dwc3/dwc3-generic.h
+++ b/drivers/usb/dwc3/dwc3-generic.h
@@ -17,6 +17,7 @@ struct dwc3_glue_data {
struct clk_bulk clks;
struct reset_ctl_bulk   resets;
fdt_addr_t regs;
+   fdt_size_t size;
 };
 
 struct dwc3_glue_ops {
-- 
2.25.1



[PATCH v4 03/10] usb: dwc3-generic: Add clock initialization in child DT node

2023-02-19 Thread Kunihiko Hayashi
Same as the reset cotnrol, should add a clock initialization in child DT
node, if the glue node doesn't have any clocks.

Signed-off-by: Kunihiko Hayashi 
Reviewed-by: Marek Vasut 
---
 drivers/usb/dwc3/dwc3-generic.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
index e32003d68e..8fa56e1ac1 100644
--- a/drivers/usb/dwc3/dwc3-generic.c
+++ b/drivers/usb/dwc3/dwc3-generic.c
@@ -572,6 +572,12 @@ static int dwc3_glue_probe(struct udevice *dev)
if (ret)
return ret;
 
+   if (glue->clks.count == 0) {
+   ret = dwc3_glue_clk_init(child, glue);
+   if (ret)
+   return ret;
+   }
+
if (glue->resets.count == 0) {
ret = dwc3_glue_reset_init(child, glue);
if (ret)
-- 
2.25.1



[PATCH v4 02/10] usb: dwc3-generic: Allow different controller DT node pattern

2023-02-19 Thread Kunihiko Hayashi
The most of devicetree has the following USB node structure.
The controller node is placed as a child node of the glue node.
Current dwc3-generic driver works on this premise.

glue {
/* glue node */
usb {
/* controller node */
};
};

However, UniPhier original devicetree has the following USB node structure.
The controller node is separately placed from the glue node.

usb {
/* controller node */
};
glue {
/* glue node */
};

In dwc_glue_bind(), this patch provides .glue_get_ctrl_dev() callback to
get such a controller node and binds the driver related to the node.

If this callback isn't defined, dwc_glue_bind() looks for the controller
nodes from the child nodes, as before.

Suggested-by: Marek Vasut 
Signed-off-by: Kunihiko Hayashi 
Reviewed-by: Marek Vasut 
---
 drivers/usb/dwc3/dwc3-generic.c | 93 -
 1 file changed, 57 insertions(+), 36 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
index 42e92478f2..e32003d68e 100644
--- a/drivers/usb/dwc3/dwc3-generic.c
+++ b/drivers/usb/dwc3/dwc3-generic.c
@@ -276,6 +276,7 @@ U_BOOT_DRIVER(dwc3_generic_host) = {
 #endif
 
 struct dwc3_glue_ops {
+   int (*glue_get_ctrl_dev)(struct udevice *parent, ofnode *node);
void (*glue_configure)(struct udevice *dev, int index,
   enum usb_dr_mode mode);
 };
@@ -415,54 +416,74 @@ struct dwc3_glue_ops ti_ops = {
.glue_configure = dwc3_ti_glue_configure,
 };
 
-static int dwc3_glue_bind(struct udevice *parent)
+static int dwc3_glue_bind_common(struct udevice *parent, ofnode node)
 {
-   ofnode node;
-   int ret;
+   const char *name = ofnode_get_name(node);
+   const char *driver = NULL;
enum usb_dr_mode dr_mode;
+   struct udevice *dev;
+   int ret;
 
-   dr_mode = usb_get_dr_mode(dev_ofnode(parent));
-
-   ofnode_for_each_subnode(node, dev_ofnode(parent)) {
-   const char *name = ofnode_get_name(node);
-   struct udevice *dev;
-   const char *driver = NULL;
-
-   debug("%s: subnode name: %s\n", __func__, name);
+   debug("%s: subnode name: %s\n", __func__, name);
 
-   /* if the parent node doesn't have a mode check the leaf */
-   if (!dr_mode)
-   dr_mode = usb_get_dr_mode(node);
+   /* if the parent node doesn't have a mode check the leaf */
+   dr_mode = usb_get_dr_mode(dev_ofnode(parent));
+   if (!dr_mode)
+   dr_mode = usb_get_dr_mode(node);
 
-   switch (dr_mode) {
-   case USB_DR_MODE_PERIPHERAL:
-   case USB_DR_MODE_OTG:
+   switch (dr_mode) {
+   case USB_DR_MODE_PERIPHERAL:
+   case USB_DR_MODE_OTG:
 #if CONFIG_IS_ENABLED(DM_USB_GADGET)
-   debug("%s: dr_mode: OTG or Peripheral\n", __func__);
-   driver = "dwc3-generic-peripheral";
+   debug("%s: dr_mode: OTG or Peripheral\n", __func__);
+   driver = "dwc3-generic-peripheral";
 #endif
-   break;
+   break;
 #if defined(CONFIG_SPL_USB_HOST) || !defined(CONFIG_SPL_BUILD)
-   case USB_DR_MODE_HOST:
-   debug("%s: dr_mode: HOST\n", __func__);
-   driver = "dwc3-generic-host";
-   break;
+   case USB_DR_MODE_HOST:
+   debug("%s: dr_mode: HOST\n", __func__);
+   driver = "dwc3-generic-host";
+   break;
 #endif
-   default:
-   debug("%s: unsupported dr_mode\n", __func__);
-   return -ENODEV;
-   };
+   default:
+   debug("%s: unsupported dr_mode\n", __func__);
+   return -ENODEV;
+   };
 
-   if (!driver)
-   continue;
+   if (!driver)
+   return -ENXIO;
+
+   ret = device_bind_driver_to_node(parent, driver, name,
+node, );
+   if (ret) {
+   debug("%s: not able to bind usb device mode\n",
+ __func__);
+   return ret;
+   }
+
+   return 0;
+}
+
+static int dwc3_glue_bind(struct udevice *parent)
+{
+   struct dwc3_glue_ops *ops = (struct dwc3_glue_ops 
*)dev_get_driver_data(parent);
+   ofnode node;
+   int ret;
 
-   ret = device_bind_driver_to_node(parent, driver, name,
-node, );
-   if (ret) {
-   debug("%s: not able to bind usb device mode\n",
- __func__);
+   if (ops && ops->glue_get_ctrl_dev) {
+   ret = ops

[PATCH v4 07/10] clk: uniphier: Add missing USB SS-PHY clocks

2023-02-19 Thread Kunihiko Hayashi
The USB SS-PHY needs its own clock, however, some clocks don't have
clock gates. Define missing clock entries for the PHY as reference
clock.

Signed-off-by: Kunihiko Hayashi 
---
 drivers/clk/uniphier/clk-uniphier-sys.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/clk/uniphier/clk-uniphier-sys.c 
b/drivers/clk/uniphier/clk-uniphier-sys.c
index ff5d364f59..3b8595fe61 100644
--- a/drivers/clk/uniphier/clk-uniphier-sys.c
+++ b/drivers/clk/uniphier/clk-uniphier-sys.c
@@ -28,7 +28,10 @@ const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[] 
= {
UNIPHIER_CLK_GATE_SIMPLE(14, 0x2104, 16),   /* usb30 (Pro4, Pro5, 
PXs2) */
UNIPHIER_CLK_GATE_SIMPLE(15, 0x2104, 17),   /* usb31 (Pro4, Pro5, 
PXs2) */
UNIPHIER_CLK_GATE_SIMPLE(16, 0x2104, 19),   /* usb30-phy (PXs2) */
+   UNIPHIER_CLK_RATE(17, 2500),/* usb30-phy2 (PXs2) */
+   UNIPHIER_CLK_RATE(18, 2500),/* usb30-phy3 (PXs2) */
UNIPHIER_CLK_GATE_SIMPLE(20, 0x2104, 20),   /* usb31-phy (PXs2) */
+   UNIPHIER_CLK_RATE(21, 2500),/* usb31-phy2 (PXs2) */
UNIPHIER_CLK_GATE_SIMPLE(24, 0x2108, 2),/* pcie (Pro5) */
{ /* sentinel */ }
 #endif
@@ -44,6 +47,8 @@ const struct uniphier_clk_data uniphier_ld20_sys_clk_data[] = 
{
UNIPHIER_CLK_GATE_SIMPLE(14, 0x210c, 14),   /* usb30 (LD20) */
UNIPHIER_CLK_GATE_SIMPLE(16, 0x210c, 12),   /* usb30-phy0 (LD20) */
UNIPHIER_CLK_GATE_SIMPLE(17, 0x210c, 13),   /* usb30-phy1 (LD20) */
+   UNIPHIER_CLK_RATE(18, 2500),/* usb30-phy2 (LD20) */
+   UNIPHIER_CLK_RATE(19, 2500),/* usb30-phy3 (LD20) */
UNIPHIER_CLK_GATE_SIMPLE(24, 0x210c, 4),/* pcie */
{ /* sentinel */ }
 #endif
-- 
2.25.1



[PATCH v4 06/10] reset: uniphier: Add USB glue reset support

2023-02-19 Thread Kunihiko Hayashi
Add reset control support in USB glue logic. This needs to control
the external clocks and resets for the logic before accessing the
glue logic.

The USB dm tree when using dwc3-generic is the following:

   USB glue
 +-- controller   (need controller-reset)
 +-- controller-reset (need syscon-reset)
 +-- phy

The controller needs to deassert "controller-reset" in USB glue before
the controller registers are accessed. The glue needs to deassert
"syscon-reset" before the glue registers are accessed.

The glue itself doesn't have "syscon-reset", so the controller-reset
controls "syscon-reset" instead.

Signed-off-by: Kunihiko Hayashi 
Reviewed-by: Marek Vasut 
---
 drivers/reset/reset-uniphier.c | 78 +-
 1 file changed, 77 insertions(+), 1 deletion(-)

diff --git a/drivers/reset/reset-uniphier.c b/drivers/reset/reset-uniphier.c
index 7adae51873..35e3ccebd7 100644
--- a/drivers/reset/reset-uniphier.c
+++ b/drivers/reset/reset-uniphier.c
@@ -2,6 +2,7 @@
 /*
  * Copyright (C) 2016 Socionext Inc.
  *   Author: Masahiro Yamada 
+ *   Author: Kunihiko Hayashi 
  */
 
 #include 
@@ -9,6 +10,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -178,10 +181,17 @@ static const struct uniphier_reset_data 
uniphier_pro4_peri_reset_data[] = {
UNIPHIER_RESET_END,
 };
 
+/* Glue reset data */
+static const struct uniphier_reset_data uniphier_pro4_usb3_reset_data[] = {
+   UNIPHIER_RESETX(15, 0, 15)
+};
+
 /* core implementaton */
 struct uniphier_reset_priv {
void __iomem *base;
const struct uniphier_reset_data *data;
+   struct clk_bulk clks;
+   struct reset_ctl_bulk   rsts;
 };
 
 static int uniphier_reset_update(struct reset_ctl *reset_ctl, int assert)
@@ -233,10 +243,47 @@ static const struct reset_ops uniphier_reset_ops = {
.rst_deassert = uniphier_reset_deassert,
 };
 
+static int uniphier_reset_rst_init(struct udevice *dev)
+{
+   struct uniphier_reset_priv *priv = dev_get_priv(dev);
+   int ret;
+
+   ret = reset_get_bulk(dev, >rsts);
+   if (ret == -ENOSYS || ret == -ENOENT)
+   return 0;
+   else if (ret)
+   return ret;
+
+   ret = reset_deassert_bulk(>rsts);
+   if (ret)
+   reset_release_bulk(>rsts);
+
+   return ret;
+}
+
+static int uniphier_reset_clk_init(struct udevice *dev)
+{
+   struct uniphier_reset_priv *priv = dev_get_priv(dev);
+   int ret;
+
+   ret = clk_get_bulk(dev, >clks);
+   if (ret == -ENOSYS || ret == -ENOENT)
+   return 0;
+   if (ret)
+   return ret;
+
+   ret = clk_enable_bulk(>clks);
+   if (ret)
+   clk_release_bulk(>clks);
+
+   return ret;
+}
+
 static int uniphier_reset_probe(struct udevice *dev)
 {
struct uniphier_reset_priv *priv = dev_get_priv(dev);
fdt_addr_t addr;
+   int ret;
 
addr = dev_read_addr(dev->parent);
if (addr == FDT_ADDR_T_NONE)
@@ -248,7 +295,11 @@ static int uniphier_reset_probe(struct udevice *dev)
 
priv->data = (void *)dev_get_driver_data(dev);
 
-   return 0;
+   ret = uniphier_reset_clk_init(dev);
+   if (ret)
+   return ret;
+
+   return uniphier_reset_rst_init(dev);
 }
 
 static const struct udevice_id uniphier_reset_match[] = {
@@ -355,6 +406,31 @@ static const struct udevice_id uniphier_reset_match[] = {
.compatible = "socionext,uniphier-pxs3-peri-reset",
.data = (ulong)uniphier_pro4_peri_reset_data,
},
+   /* USB glue reset */
+   {
+   .compatible = "socionext,uniphier-pro4-usb3-reset",
+   .data = (ulong)uniphier_pro4_usb3_reset_data,
+   },
+   {
+   .compatible = "socionext,uniphier-pro5-usb3-reset",
+   .data = (ulong)uniphier_pro4_usb3_reset_data,
+   },
+   {
+   .compatible = "socionext,uniphier-pxs2-usb3-reset",
+   .data = (ulong)uniphier_pro4_usb3_reset_data,
+   },
+   {
+   .compatible = "socionext,uniphier-ld20-usb3-reset",
+   .data = (ulong)uniphier_pro4_usb3_reset_data,
+   },
+   {
+   .compatible = "socionext,uniphier-pxs3-usb3-reset",
+   .data = (ulong)uniphier_pro4_usb3_reset_data,
+   },
+   {
+   .compatible = "socionext,uniphier-nx1-usb3-reset",
+   .data = (ulong)uniphier_pro4_usb3_reset_data,
+   },
{ /* sentinel */ }
 };
 
-- 
2.25.1



[PATCH v4 01/10] usb: dwc3: Look up reference clock DT phandle in both controller DT nodes

2023-02-19 Thread Kunihiko Hayashi
From: Marek Vasut 

There are currently four disparate placement possibilities of DWC3
reference clock phandle in SoC DTs:
- in top level glue node, with generic subnode without clock (ZynqMP)
- in top level generic node, with no subnode (i.MX8MQ)
- in generic subnode, with other clock in top level node (i.MX8MP)
- in both top level node and generic subnode (Rockchip)

Cover all the possibilities here by looking into both nodes, start
with the top level node as that seems to be used in majority of DTs
to reference the clock.

Signed-off-by: Marek Vasut 
Acked-by: Kunihiko Hayashi 
---
 drivers/usb/dwc3/dwc3-generic.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
index 78966718d0..42e92478f2 100644
--- a/drivers/usb/dwc3/dwc3-generic.c
+++ b/drivers/usb/dwc3/dwc3-generic.c
@@ -68,10 +68,27 @@ static int dwc3_generic_probe(struct udevice *dev,
 #if CONFIG_IS_ENABLED(OF_CONTROL)
dwc3_of_parse(dwc3);
 
+   /*
+* There are currently four disparate placement possibilities of DWC3
+* reference clock phandle in SoC DTs:
+* - in top level glue node, with generic subnode without clock (ZynqMP)
+* - in top level generic node, with no subnode (i.MX8MQ)
+* - in generic subnode, with other clock in top level node (i.MX8MP)
+* - in both top level node and generic subnode (Rockchip)
+* Cover all the possibilities here by looking into both nodes, start
+* with the top level node as that seems to be used in majority of DTs
+* to reference the clock.
+*/
node = dev_ofnode(dev->parent);
index = ofnode_stringlist_search(node, "clock-names", "ref");
if (index < 0)
index = ofnode_stringlist_search(node, "clock-names", 
"ref_clk");
+   if (index < 0) {
+   node = dev_ofnode(dev);
+   index = ofnode_stringlist_search(node, "clock-names", "ref");
+   if (index < 0)
+   index = ofnode_stringlist_search(node, "clock-names", 
"ref_clk");
+   }
if (index >= 0)
dwc3->ref_clk = >clks.clks[index];
 #endif
-- 
2.25.1



[PATCH v4 04/10] usb: dwc3-generic: Export glue structures and functions

2023-02-19 Thread Kunihiko Hayashi
In order to allow external SoC-dependent glue drivers to use dwc3-generic
functions, push the glue structures and export the functions to a header
file.

The exported structures and functions are:

- struct dwc3_glue_data
- struct dwc3_glue_ops
- dwc3_glue_bind()
- dwc3_glue_probe()
- dwc3_glue_remove()

The SoC-dependent glue drivers can only define their own wrapper driver
and specify these functions. The drivers can also add their own compatible
strings and configure functions.

Signed-off-by: Kunihiko Hayashi 
Reviewed-by: Marek Vasut 
---
 drivers/usb/dwc3/dwc3-generic.c | 18 --
 drivers/usb/dwc3/dwc3-generic.h | 32 
 2 files changed, 36 insertions(+), 14 deletions(-)
 create mode 100644 drivers/usb/dwc3/dwc3-generic.h

diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
index 8fa56e1ac1..4576390ec7 100644
--- a/drivers/usb/dwc3/dwc3-generic.c
+++ b/drivers/usb/dwc3/dwc3-generic.c
@@ -28,11 +28,7 @@
 #include 
 #include 
 
-struct dwc3_glue_data {
-   struct clk_bulk clks;
-   struct reset_ctl_bulk   resets;
-   fdt_addr_t regs;
-};
+#include "dwc3-generic.h"
 
 struct dwc3_generic_plat {
fdt_addr_t base;
@@ -275,12 +271,6 @@ U_BOOT_DRIVER(dwc3_generic_host) = {
 };
 #endif
 
-struct dwc3_glue_ops {
-   int (*glue_get_ctrl_dev)(struct udevice *parent, ofnode *node);
-   void (*glue_configure)(struct udevice *dev, int index,
-  enum usb_dr_mode mode);
-};
-
 void dwc3_imx8mp_glue_configure(struct udevice *dev, int index,
enum usb_dr_mode mode)
 {
@@ -464,7 +454,7 @@ static int dwc3_glue_bind_common(struct udevice *parent, 
ofnode node)
return 0;
 }
 
-static int dwc3_glue_bind(struct udevice *parent)
+int dwc3_glue_bind(struct udevice *parent)
 {
struct dwc3_glue_ops *ops = (struct dwc3_glue_ops 
*)dev_get_driver_data(parent);
ofnode node;
@@ -531,7 +521,7 @@ static int dwc3_glue_clk_init(struct udevice *dev,
return 0;
 }
 
-static int dwc3_glue_probe(struct udevice *dev)
+int dwc3_glue_probe(struct udevice *dev)
 {
struct dwc3_glue_ops *ops = (struct dwc3_glue_ops 
*)dev_get_driver_data(dev);
struct dwc3_glue_data *glue = dev_get_plat(dev);
@@ -597,7 +587,7 @@ static int dwc3_glue_probe(struct udevice *dev)
return 0;
 }
 
-static int dwc3_glue_remove(struct udevice *dev)
+int dwc3_glue_remove(struct udevice *dev)
 {
struct dwc3_glue_data *glue = dev_get_plat(dev);
 
diff --git a/drivers/usb/dwc3/dwc3-generic.h b/drivers/usb/dwc3/dwc3-generic.h
new file mode 100644
index 00..824f678841
--- /dev/null
+++ b/drivers/usb/dwc3/dwc3-generic.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * dwc3-generic.h - Generic DWC3 Glue layer header
+ *
+ * Copyright (C) 2016 - 2018 Xilinx, Inc.
+ * Copyright (C) 2023 Socionext Inc.
+ */
+
+#ifndef __DRIVERS_USB_DWC3_GENERIC_H
+#define __DRIVERS_USB_DWC3_GENERIC_H
+
+#include 
+#include 
+#include 
+
+struct dwc3_glue_data {
+   struct clk_bulk clks;
+   struct reset_ctl_bulk   resets;
+   fdt_addr_t regs;
+};
+
+struct dwc3_glue_ops {
+   int (*glue_get_ctrl_dev)(struct udevice *parent, ofnode *node);
+   void (*glue_configure)(struct udevice *dev, int index,
+  enum usb_dr_mode mode);
+};
+
+int dwc3_glue_bind(struct udevice *parent);
+int dwc3_glue_probe(struct udevice *dev);
+int dwc3_glue_remove(struct udevice *dev);
+
+#endif
-- 
2.25.1



[PATCH v4 00/10] usb: dwc3: Refactor dwc3-generic and apply to dwc3-uniphier

2023-02-19 Thread Kunihiko Hayashi
This series achieves refactoring of dwc3-generic.

First, dwc3-generic allows DT controller nodes to be children of glue nodes,
but outside of glue nodes.

To achieve this goal, define a glue-specific function to get controller node,
look up more reference clocks in the controller node, and initialize clocks
in children of glue node before access to the controller,

Next, this series exports the structures and functions from the driver source
to the header, and replaces dwc3-uniphier driver as one implementation using
them. This expects dwc3-generic to prevent more SoC-dependent codes.

The dwc3-uniphier has original USB node, however, tentatively added its own
node dedicated to U-Boot. After this refactoring, the driver needs to add
clock entries and PHY driver to enable them corresponding to the properties
in the original node.

PATCH 1 has been provided below.
  
https://patchwork.ozlabs.org/project/uboot/patch/20221215223822.137739-1-ma...@denx.de/

PATCH 2 is based on the suggested patch from Marek.

PATCH 4-5 and 9-10 have been already reviewed in the previous v1.
  https://lists.denx.de/pipermail/u-boot/2023-January/505689.html

Changes since v3:
- Control the controller clock/reset and phy clock/reset separately

Changes since v2:
- Add Reviewed-by: tags
- Add more details to reset-uniphier patch log
- Add error release for clock/reset initializer in phy-uniphier-usb3 patch
- Fix release year in in phy-uniphier-usb3 patch
- Enable PHY_UNIPHIER_USB3 with DWC3_UNIPHIER
- Separate devicetree patches

Changes since v1:
- Add a patch to refer to the clock in top level generic node
- Add a patch to allow controller DT node outside of glue node
- Add a patch to initialize clocks in children of glue node
- Update dwc3_glue_ops to add the function to get controller device
- Add a patch to support USB glue reset
- Add a patch to add missing PHY clocks
- Add a patch to enable the driver to enable PHY clocks and resets
- Add a patch to fix node names and missing properties
- Add a patch to switch to the original USB node in DT

Kunihiko Hayashi (9):
  usb: dwc3-generic: Allow different controller DT node pattern
  usb: dwc3-generic: Add clock initialization in child DT node
  usb: dwc3-generic: Export glue structures and functions
  usb: dwc3-generic: Add the size of regs property to glue structure
  reset: uniphier: Add USB glue reset support
  clk: uniphier: Add missing USB SS-PHY clocks
  phy: socionext: Add UniPhier USB3 PHY driver
  usb: dwc3-uniphier: Use dwc3-generic instead of xhci-dwc3
  uniphier_defconfig: Disable USB_XHCI_DWC3

Marek Vasut (1):
  usb: dwc3: Look up reference clock DT phandle in both controller DT
nodes

 configs/uniphier_v7_defconfig |   1 -
 configs/uniphier_v8_defconfig |   1 -
 drivers/clk/uniphier/clk-uniphier-sys.c   |   5 +
 drivers/phy/socionext/Kconfig |   8 ++
 drivers/phy/socionext/Makefile|   1 +
 drivers/phy/socionext/phy-uniphier-usb3.c | 168 ++
 drivers/reset/reset-uniphier.c|  78 +-
 drivers/usb/dwc3/Kconfig  |   4 +-
 drivers/usb/dwc3/dwc3-generic.c   | 132 ++---
 drivers/usb/dwc3/dwc3-generic.h   |  33 +
 drivers/usb/dwc3/dwc3-uniphier.c  | 116 +--
 11 files changed, 453 insertions(+), 94 deletions(-)
 create mode 100644 drivers/phy/socionext/phy-uniphier-usb3.c
 create mode 100644 drivers/usb/dwc3/dwc3-generic.h

-- 
2.25.1



Re: [PATCH v3 08/10] phy: socionext: Add UniPhier USB3 PHY driver

2023-02-19 Thread Kunihiko Hayashi

Hi Marek,

On 2023/02/18 4:58, Marek Vasut wrote:

On 2/16/23 17:14, Kunihiko Hayashi wrote:

Hi Marek,


Hello Hayashi-san,


Sorry for late reply.

On 2023/02/14 6:06, Marek Vasut wrote:

On 2/13/23 04:08, Kunihiko Hayashi wrote:

Hi Marek,


Hello Hayashi-san,



[...]


I think so, however, when I added .exit() and executed "usb stop;usb
start",
unfortunately the command got stuck.

Currently uniphier clk doesn't support CLK_CCF and can't be nested.
I think more changes are needed.


Do you know where exactly the system hangs ?


Yes.

The controller-reset driver controls the clock/reset for the glue
in probe(). The phy driver controls the clock/reset for the glue and
the phy in init(). There is an inconsistency.

When submitting "usb stop", the phy driver disables all the clock/reset
in exit().

When submitting "usb start" again, the controller-reset driver accesses
the glue register without enabling the clock/reset, and the system hangs.


Shouldn't the PHY enable its own set of clock, while the controller
should only enable its own (different) set of clock ?


PHY has this own clock/reset, however, PHY is in the glue logic.
So accessing to PHY also needs to enable the glue clock
(same as the controller clock).


If it is the same clock and there is no refcounting, then maybe what you
should do for now is enable/disable all the clock in the controller
driver only, and deal with the PHY once CCF with refcounting is in place ?


PHY needs the glue(controller) clock and the phy clock.
After all, it's wrong to control all the clocks/resets at the same time.

In this time, I don't event think about CCF (sorry to confuse you).


Do you expect to add the CCF support ?


Yes, first I thought the clock needed the CCF support to count the clock
function calls, but there is no support to count the reset function calls.
I need another solution.

Currently the phy driver controls all the clock/reset in init() and
exit(),
however, it should control the phy clock/reset only.


If that's possible on this hardware, that would be good, let controller
control its clock and PHY control its (different) clock.


Yes. I'll separate these controls.


If so, then add at least a FIXME code comment that the exit callback
must be implemented, so that this is not forgotten once CCF is in place.
I don't want this series to grow much further into some "rework
everything at once" thing.


As above, I should put the glue clock/reset into probe(),
and the phy clock/reset into init() without using bulk function.


OK


Thank you,

---
Best Regards
Kunihiko Hayashi


Re: [PATCH v3 08/10] phy: socionext: Add UniPhier USB3 PHY driver

2023-02-16 Thread Kunihiko Hayashi

Hi Marek,

Sorry for late reply.

On 2023/02/14 6:06, Marek Vasut wrote:

On 2/13/23 04:08, Kunihiko Hayashi wrote:

Hi Marek,


Hello Hayashi-san,



[...]


I think so, however, when I added .exit() and executed "usb stop;usb
start",
unfortunately the command got stuck.

Currently uniphier clk doesn't support CLK_CCF and can't be nested.
I think more changes are needed.


Do you know where exactly the system hangs ?


Yes.

The controller-reset driver controls the clock/reset for the glue
in probe(). The phy driver controls the clock/reset for the glue and
the phy in init(). There is an inconsistency.

When submitting "usb stop", the phy driver disables all the clock/reset
in exit().

When submitting "usb start" again, the controller-reset driver accesses
the glue register without enabling the clock/reset, and the system hangs.


Do you expect to add the CCF support ?


Yes, first I thought the clock needed the CCF support to count the clock
function calls, but there is no support to count the reset function calls.
I need another solution.

Currently the phy driver controls all the clock/reset in init() and exit(),
however, it should control the phy clock/reset only.


If so, then add at least a FIXME code comment that the exit callback
must be implemented, so that this is not forgotten once CCF is in place.
I don't want this series to grow much further into some "rework
everything at once" thing.


As above, I should put the glue clock/reset into probe(),
and the phy clock/reset into init() without using bulk function.

Thank you,

---
Best Regards
Kunihiko Hayashi


Re: [PATCH v3 08/10] phy: socionext: Add UniPhier USB3 PHY driver

2023-02-12 Thread Kunihiko Hayashi

Hi Marek,

On 2023/02/10 23:09, Marek Vasut wrote:

On 2/8/23 10:15, Kunihiko Hayashi wrote:

[...]


+static int uniphier_usb3phy_init(struct phy *phy)
+{
+   struct uniphier_usb3phy_priv *priv = dev_get_priv(phy->dev);
+   int ret;
+
+   ret = clk_enable_bulk(>clks);
+   if (ret)
+   goto out_clk;


This should be just 'return ret;'


+   ret = reset_deassert_bulk(>rsts);
+   if (ret)
+   goto out_rst;


This should be goto out_rst, however ...


+   return 0;
+
+out_rst:
+   reset_release_bulk(>rsts);
+out_clk:
+   clk_release_bulk(>clks);


... the out_rst: should only do:

out_rst:
clk_disable_bulk();
return ret

out_clk part can be removed.


I see. These operations are unpaired.
I'll fix them.


+   return ret;
+}
+
+static int uniphier_usb3phy_probe(struct udevice *dev)
+{
+   struct uniphier_usb3phy_priv *priv = dev_get_priv(dev);
+   int ret;
+
+   ret = clk_get_bulk(dev, >clks);
+   if (ret) {
+   if (ret != -ENOSYS && ret != -ENOENT) {


This can be single line:

if (ret && ret != -ENOSYS && ret != -ENOENT)
return ret;


OK, This will be fixed.


+   printf("Failed to get clocks\n");
+   return ret;
+   }
+   }
+
+   ret = reset_get_bulk(dev, >rsts);
+   if (ret) {
+   if (ret != -ENOSYS && ret != -ENOENT) {


Same here.


+   printf("Failed to get resets\n");
+   clk_release_bulk(>clks);


Better use goto out_clk fail path.


+   return ret;
+   }
+   }
+
+   return 0;
+}
+
+static struct phy_ops uniphier_usb3phy_ops = {
+   .init = uniphier_usb3phy_init,


You should implement .exit callback too, that one should do these two steps:

reset_assert_bulk()
clk_disable_bulk()


I think so, however, when I added .exit() and executed "usb stop;usb start",
unfortunately the command got stuck.

Currently uniphier clk doesn't support CLK_CCF and can't be nested.
I think more changes are needed.

Thank you,

---
Best Regards
Kunihiko Hayashi


[PATCH v3 08/10] phy: socionext: Add UniPhier USB3 PHY driver

2023-02-08 Thread Kunihiko Hayashi
Add USB3 PHY driver support to control clocks and resets for the phy.

Signed-off-by: Kunihiko Hayashi 
---
 drivers/phy/socionext/Kconfig |  8 ++
 drivers/phy/socionext/Makefile|  1 +
 drivers/phy/socionext/phy-uniphier-usb3.c | 93 +++
 3 files changed, 102 insertions(+)
 create mode 100644 drivers/phy/socionext/phy-uniphier-usb3.c

diff --git a/drivers/phy/socionext/Kconfig b/drivers/phy/socionext/Kconfig
index bcd579e98ec1..de87d5b0109b 100644
--- a/drivers/phy/socionext/Kconfig
+++ b/drivers/phy/socionext/Kconfig
@@ -10,3 +10,11 @@ config PHY_UNIPHIER_PCIE
help
  Enable this to support PHY implemented in PCIe controller
  on UniPhier SoCs.
+
+config PHY_UNIPHIER_USB3
+   bool "UniPhier USB3 PHY driver"
+   depends on PHY && ARCH_UNIPHIER
+   imply REGMAP
+   help
+ Enable this to support PHY implemented in USB3 controller
+ on UniPhier SoCs.
diff --git a/drivers/phy/socionext/Makefile b/drivers/phy/socionext/Makefile
index 5484360b70ff..94d3aa68cfac 100644
--- a/drivers/phy/socionext/Makefile
+++ b/drivers/phy/socionext/Makefile
@@ -4,3 +4,4 @@
 #
 
 obj-$(CONFIG_PHY_UNIPHIER_PCIE)+= phy-uniphier-pcie.o
+obj-$(CONFIG_PHY_UNIPHIER_USB3)+= phy-uniphier-usb3.o
diff --git a/drivers/phy/socionext/phy-uniphier-usb3.c 
b/drivers/phy/socionext/phy-uniphier-usb3.c
new file mode 100644
index ..ec3774569287
--- /dev/null
+++ b/drivers/phy/socionext/phy-uniphier-usb3.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * phy_uniphier_usb3.c - Socionext UniPhier Usb3 PHY driver
+ * Copyright 2019-2023 Socionext, Inc.
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+struct uniphier_usb3phy_priv {
+   struct clk_bulk clks;
+   struct reset_ctl_bulk rsts;
+};
+
+static int uniphier_usb3phy_init(struct phy *phy)
+{
+   struct uniphier_usb3phy_priv *priv = dev_get_priv(phy->dev);
+   int ret;
+
+   ret = clk_enable_bulk(>clks);
+   if (ret)
+   goto out_clk;
+
+   ret = reset_deassert_bulk(>rsts);
+   if (ret)
+   goto out_rst;
+
+   return 0;
+
+out_rst:
+   reset_release_bulk(>rsts);
+out_clk:
+   clk_release_bulk(>clks);
+
+   return ret;
+}
+
+static int uniphier_usb3phy_probe(struct udevice *dev)
+{
+   struct uniphier_usb3phy_priv *priv = dev_get_priv(dev);
+   int ret;
+
+   ret = clk_get_bulk(dev, >clks);
+   if (ret) {
+   if (ret != -ENOSYS && ret != -ENOENT) {
+   printf("Failed to get clocks\n");
+   return ret;
+   }
+   }
+
+   ret = reset_get_bulk(dev, >rsts);
+   if (ret) {
+   if (ret != -ENOSYS && ret != -ENOENT) {
+   printf("Failed to get resets\n");
+   clk_release_bulk(>clks);
+   return ret;
+   }
+   }
+
+   return 0;
+}
+
+static struct phy_ops uniphier_usb3phy_ops = {
+   .init = uniphier_usb3phy_init,
+};
+
+static const struct udevice_id uniphier_usb3phy_ids[] = {
+   { .compatible = "socionext,uniphier-pro4-usb3-ssphy" },
+   { .compatible = "socionext,uniphier-pro5-usb3-hsphy" },
+   { .compatible = "socionext,uniphier-pro5-usb3-ssphy" },
+   { .compatible = "socionext,uniphier-pxs2-usb3-hsphy" },
+   { .compatible = "socionext,uniphier-pxs2-usb3-ssphy" },
+   { .compatible = "socionext,uniphier-ld20-usb3-hsphy" },
+   { .compatible = "socionext,uniphier-ld20-usb3-ssphy" },
+   { .compatible = "socionext,uniphier-pxs3-usb3-hsphy" },
+   { .compatible = "socionext,uniphier-pxs3-usb3-ssphy" },
+   { .compatible = "socionext,uniphier-nx1-usb3-hsphy" },
+   { .compatible = "socionext,uniphier-nx1-usb3-ssphy" },
+   { }
+};
+
+U_BOOT_DRIVER(uniphier_usb3_phy) = {
+   .name   = "uniphier-usb3-phy",
+   .id = UCLASS_PHY,
+   .of_match   = uniphier_usb3phy_ids,
+   .ops= _usb3phy_ops,
+   .probe  = uniphier_usb3phy_probe,
+   .priv_auto  = sizeof(struct uniphier_usb3phy_priv),
+};
-- 
2.25.1



[PATCH v3 10/10] uniphier_defconfig: Disable USB_XHCI_DWC3

2023-02-08 Thread Kunihiko Hayashi
Replacing with dwc3-generic, no need USB_XHCI_DWC3 anymore.

Signed-off-by: Kunihiko Hayashi 
Reviewed-by: Marek Vasut 
---
 configs/uniphier_v7_defconfig | 1 -
 configs/uniphier_v8_defconfig | 1 -
 2 files changed, 2 deletions(-)

diff --git a/configs/uniphier_v7_defconfig b/configs/uniphier_v7_defconfig
index d626968c76d4..03feb04b9378 100644
--- a/configs/uniphier_v7_defconfig
+++ b/configs/uniphier_v7_defconfig
@@ -82,7 +82,6 @@ CONFIG_DM_SPI=y
 CONFIG_UNIPHIER_SPI=y
 CONFIG_USB=y
 CONFIG_USB_XHCI_HCD=y
-CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_GENERIC=y
 CONFIG_USB_DWC3=y
diff --git a/configs/uniphier_v8_defconfig b/configs/uniphier_v8_defconfig
index 6a0e2666cf18..ed58b5746e72 100644
--- a/configs/uniphier_v8_defconfig
+++ b/configs/uniphier_v8_defconfig
@@ -71,7 +71,6 @@ CONFIG_SYSRESET=y
 CONFIG_SYSRESET_PSCI=y
 CONFIG_USB=y
 CONFIG_USB_XHCI_HCD=y
-CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_GENERIC=y
 CONFIG_USB_DWC3=y
-- 
2.25.1



[PATCH v3 05/10] usb: dwc3-generic: Add the size of regs property to glue structure

2023-02-08 Thread Kunihiko Hayashi
Add the size of regs property to the glue structure to correctly
specify the register region to map.

Signed-off-by: Kunihiko Hayashi 
Reviewed-by: Marek Vasut 
---
 drivers/usb/dwc3/dwc3-generic.c | 2 +-
 drivers/usb/dwc3/dwc3-generic.h | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
index 4576390ec7cd..acbf7acb1918 100644
--- a/drivers/usb/dwc3/dwc3-generic.c
+++ b/drivers/usb/dwc3/dwc3-generic.c
@@ -542,7 +542,7 @@ int dwc3_glue_probe(struct udevice *dev)
phy.dev = NULL;
}
 
-   glue->regs = dev_read_addr(dev);
+   glue->regs = dev_read_addr_size_index(dev, 0, >size);
 
ret = dwc3_glue_clk_init(dev, glue);
if (ret)
diff --git a/drivers/usb/dwc3/dwc3-generic.h b/drivers/usb/dwc3/dwc3-generic.h
index 824f678841a8..40902c8923f5 100644
--- a/drivers/usb/dwc3/dwc3-generic.h
+++ b/drivers/usb/dwc3/dwc3-generic.h
@@ -17,6 +17,7 @@ struct dwc3_glue_data {
struct clk_bulk clks;
struct reset_ctl_bulk   resets;
fdt_addr_t regs;
+   fdt_size_t size;
 };
 
 struct dwc3_glue_ops {
-- 
2.25.1



[PATCH v3 09/10] usb: dwc3-uniphier: Use dwc3-generic instead of xhci-dwc3

2023-02-08 Thread Kunihiko Hayashi
dwc3-uniphier depends on xhci-dwc3 framework, however, it is preferable
to use dwc3-generic.

This driver calls the exported dwc3-generic functions and redefine
the SoC-dependent operations to fit dwc3-generic.

Signed-off-by: Kunihiko Hayashi 
Reviewed-by: Marek Vasut 
---
 drivers/usb/dwc3/Kconfig |   4 +-
 drivers/usb/dwc3/dwc3-uniphier.c | 116 ---
 2 files changed, 78 insertions(+), 42 deletions(-)

diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index f010291d0223..7ddfa94e518d 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -55,7 +55,9 @@ config USB_DWC3_MESON_GXL
 
 config USB_DWC3_UNIPHIER
bool "DesignWare USB3 Host Support on UniPhier Platforms"
-   depends on ARCH_UNIPHIER && USB_XHCI_DWC3
+   depends on ARCH_UNIPHIER && USB_DWC3
+   select USB_DWC3_GENERIC
+   select PHY_UNIPHIER_USB3
help
  Support of USB2/3 functionality in Socionext UniPhier platforms.
  Say 'Y' here if you have one such device.
diff --git a/drivers/usb/dwc3/dwc3-uniphier.c b/drivers/usb/dwc3/dwc3-uniphier.c
index 54b52dcd66a9..ab85428a7003 100644
--- a/drivers/usb/dwc3/dwc3-uniphier.c
+++ b/drivers/usb/dwc3/dwc3-uniphier.c
@@ -4,14 +4,17 @@
  *
  * Copyright (C) 2016-2017 Socionext Inc.
  *   Author: Masahiro Yamada 
+ *   Author: Kunihiko Hayashi 
  */
 
 #include 
-#include 
+#include 
 #include 
-#include 
-#include 
-#include 
+#include 
+
+#include "core.h"
+#include "gadget.h"
+#include "dwc3-generic.h"
 
 #define UNIPHIER_PRO4_DWC3_RESET   0x40
 #define   UNIPHIER_PRO4_DWC3_RESET_XIOMMU  BIT(5)
@@ -27,8 +30,11 @@
 #define UNIPHIER_PXS2_DWC3_RESET   0x00
 #define   UNIPHIER_PXS2_DWC3_RESET_XLINK   BIT(15)
 
-static int uniphier_pro4_dwc3_init(void __iomem *regs)
+static void uniphier_pro4_dwc3_init(struct udevice *dev, int index,
+   enum usb_dr_mode mode)
 {
+   struct dwc3_glue_data *glue = dev_get_plat(dev);
+   void *regs = map_physmem(glue->regs, glue->size, MAP_NOCACHE);
u32 tmp;
 
tmp = readl(regs + UNIPHIER_PRO4_DWC3_RESET);
@@ -36,11 +42,14 @@ static int uniphier_pro4_dwc3_init(void __iomem *regs)
tmp |= UNIPHIER_PRO4_DWC3_RESET_XIOMMU | UNIPHIER_PRO4_DWC3_RESET_XLINK;
writel(tmp, regs + UNIPHIER_PRO4_DWC3_RESET);
 
-   return 0;
+   unmap_physmem(regs, MAP_NOCACHE);
 }
 
-static int uniphier_pro5_dwc3_init(void __iomem *regs)
+static void uniphier_pro5_dwc3_init(struct udevice *dev, int index,
+   enum usb_dr_mode mode)
 {
+   struct dwc3_glue_data *glue = dev_get_plat(dev);
+   void *regs = map_physmem(glue->regs, glue->size, MAP_NOCACHE);
u32 tmp;
 
tmp = readl(regs + UNIPHIER_PRO5_DWC3_RESET);
@@ -49,72 +58,97 @@ static int uniphier_pro5_dwc3_init(void __iomem *regs)
tmp |= UNIPHIER_PRO5_DWC3_RESET_XLINK | UNIPHIER_PRO5_DWC3_RESET_XIOMMU;
writel(tmp, regs + UNIPHIER_PRO5_DWC3_RESET);
 
-   return 0;
+   unmap_physmem(regs, MAP_NOCACHE);
 }
 
-static int uniphier_pxs2_dwc3_init(void __iomem *regs)
+static void uniphier_pxs2_dwc3_init(struct udevice *dev, int index,
+   enum usb_dr_mode mode)
 {
+   struct dwc3_glue_data *glue = dev_get_plat(dev);
+   void *regs = map_physmem(glue->regs, glue->size, MAP_NOCACHE);
u32 tmp;
 
tmp = readl(regs + UNIPHIER_PXS2_DWC3_RESET);
tmp |= UNIPHIER_PXS2_DWC3_RESET_XLINK;
writel(tmp, regs + UNIPHIER_PXS2_DWC3_RESET);
 
-   return 0;
+   unmap_physmem(regs, MAP_NOCACHE);
 }
 
-static int uniphier_dwc3_probe(struct udevice *dev)
+static int dwc3_uniphier_glue_get_ctrl_dev(struct udevice *dev, ofnode *node)
 {
-   fdt_addr_t base;
-   void __iomem *regs;
-   int (*init)(void __iomem *regs);
-   int ret;
+   struct udevice *child;
+   const char *name;
+   ofnode subnode;
+
+   /*
+* "controller reset" belongs to glue logic, and it should be
+* accessible in .glue_configure() before access to the controller
+* begins.
+*/
+   ofnode_for_each_subnode(subnode, dev_ofnode(dev)) {
+   name = ofnode_get_name(subnode);
+   if (!strncmp(name, "reset", 5))
+   device_bind_driver_to_node(dev, "uniphier-reset",
+  name, subnode, );
+   }
+
+   /* Get controller node that is placed separately from the glue node */
+   *node = ofnode_by_compatible(dev_ofnode(dev->parent),
+"socionext,uniphier-dwc3");
 
-   base = dev_read_addr(dev);
-   if (base == FDT_ADDR_T_NONE)
-   return -EINVAL;
-
-   regs = ioremap(base, SZ_32K);
-   if (!regs)
-   

[PATCH v3 04/10] usb: dwc3-generic: Export glue structures and functions

2023-02-08 Thread Kunihiko Hayashi
In order to allow external SoC-dependent glue drivers to use dwc3-generic
functions, push the glue structures and export the functions to a header
file.

The exported structures and functions are:

- struct dwc3_glue_data
- struct dwc3_glue_ops
- dwc3_glue_bind()
- dwc3_glue_probe()
- dwc3_glue_remove()

The SoC-dependent glue drivers can only define their own wrapper driver
and specify these functions. The drivers can also add their own compatible
strings and configure functions.

Signed-off-by: Kunihiko Hayashi 
Reviewed-by: Marek Vasut 
---
 drivers/usb/dwc3/dwc3-generic.c | 18 --
 drivers/usb/dwc3/dwc3-generic.h | 32 
 2 files changed, 36 insertions(+), 14 deletions(-)
 create mode 100644 drivers/usb/dwc3/dwc3-generic.h

diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
index 8fa56e1ac173..4576390ec7cd 100644
--- a/drivers/usb/dwc3/dwc3-generic.c
+++ b/drivers/usb/dwc3/dwc3-generic.c
@@ -28,11 +28,7 @@
 #include 
 #include 
 
-struct dwc3_glue_data {
-   struct clk_bulk clks;
-   struct reset_ctl_bulk   resets;
-   fdt_addr_t regs;
-};
+#include "dwc3-generic.h"
 
 struct dwc3_generic_plat {
fdt_addr_t base;
@@ -275,12 +271,6 @@ U_BOOT_DRIVER(dwc3_generic_host) = {
 };
 #endif
 
-struct dwc3_glue_ops {
-   int (*glue_get_ctrl_dev)(struct udevice *parent, ofnode *node);
-   void (*glue_configure)(struct udevice *dev, int index,
-  enum usb_dr_mode mode);
-};
-
 void dwc3_imx8mp_glue_configure(struct udevice *dev, int index,
enum usb_dr_mode mode)
 {
@@ -464,7 +454,7 @@ static int dwc3_glue_bind_common(struct udevice *parent, 
ofnode node)
return 0;
 }
 
-static int dwc3_glue_bind(struct udevice *parent)
+int dwc3_glue_bind(struct udevice *parent)
 {
struct dwc3_glue_ops *ops = (struct dwc3_glue_ops 
*)dev_get_driver_data(parent);
ofnode node;
@@ -531,7 +521,7 @@ static int dwc3_glue_clk_init(struct udevice *dev,
return 0;
 }
 
-static int dwc3_glue_probe(struct udevice *dev)
+int dwc3_glue_probe(struct udevice *dev)
 {
struct dwc3_glue_ops *ops = (struct dwc3_glue_ops 
*)dev_get_driver_data(dev);
struct dwc3_glue_data *glue = dev_get_plat(dev);
@@ -597,7 +587,7 @@ static int dwc3_glue_probe(struct udevice *dev)
return 0;
 }
 
-static int dwc3_glue_remove(struct udevice *dev)
+int dwc3_glue_remove(struct udevice *dev)
 {
struct dwc3_glue_data *glue = dev_get_plat(dev);
 
diff --git a/drivers/usb/dwc3/dwc3-generic.h b/drivers/usb/dwc3/dwc3-generic.h
new file mode 100644
index ..824f678841a8
--- /dev/null
+++ b/drivers/usb/dwc3/dwc3-generic.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * dwc3-generic.h - Generic DWC3 Glue layer header
+ *
+ * Copyright (C) 2016 - 2018 Xilinx, Inc.
+ * Copyright (C) 2023 Socionext Inc.
+ */
+
+#ifndef __DRIVERS_USB_DWC3_GENERIC_H
+#define __DRIVERS_USB_DWC3_GENERIC_H
+
+#include 
+#include 
+#include 
+
+struct dwc3_glue_data {
+   struct clk_bulk clks;
+   struct reset_ctl_bulk   resets;
+   fdt_addr_t regs;
+};
+
+struct dwc3_glue_ops {
+   int (*glue_get_ctrl_dev)(struct udevice *parent, ofnode *node);
+   void (*glue_configure)(struct udevice *dev, int index,
+  enum usb_dr_mode mode);
+};
+
+int dwc3_glue_bind(struct udevice *parent);
+int dwc3_glue_probe(struct udevice *dev);
+int dwc3_glue_remove(struct udevice *dev);
+
+#endif
-- 
2.25.1



[PATCH v3 06/10] reset: uniphier: Add USB glue reset support

2023-02-08 Thread Kunihiko Hayashi
Add reset control support in USB glue logic. This needs to control
the external clocks and resets for the logic before accessing the
glue logic.

The USB dm tree when using dwc3-generic is the following:

   USB glue
 +-- controller   (need controller-reset)
 +-- controller-reset (need syscon-reset)
 +-- phy

The controller needs to deassert "controller-reset" in USB glue before
the controller registers are accessed. The glue needs to deassert
"syscon-reset" before the glue registers are accessed.

The glue itself doesn't have "syscon-reset", so the controller-reset
controls "syscon-reset" instead.

Signed-off-by: Kunihiko Hayashi 
Reviewed-by: Marek Vasut 
---
 drivers/reset/reset-uniphier.c | 78 +-
 1 file changed, 77 insertions(+), 1 deletion(-)

diff --git a/drivers/reset/reset-uniphier.c b/drivers/reset/reset-uniphier.c
index 7adae51873f3..35e3ccebd72e 100644
--- a/drivers/reset/reset-uniphier.c
+++ b/drivers/reset/reset-uniphier.c
@@ -2,6 +2,7 @@
 /*
  * Copyright (C) 2016 Socionext Inc.
  *   Author: Masahiro Yamada 
+ *   Author: Kunihiko Hayashi 
  */
 
 #include 
@@ -9,6 +10,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -178,10 +181,17 @@ static const struct uniphier_reset_data 
uniphier_pro4_peri_reset_data[] = {
UNIPHIER_RESET_END,
 };
 
+/* Glue reset data */
+static const struct uniphier_reset_data uniphier_pro4_usb3_reset_data[] = {
+   UNIPHIER_RESETX(15, 0, 15)
+};
+
 /* core implementaton */
 struct uniphier_reset_priv {
void __iomem *base;
const struct uniphier_reset_data *data;
+   struct clk_bulk clks;
+   struct reset_ctl_bulk   rsts;
 };
 
 static int uniphier_reset_update(struct reset_ctl *reset_ctl, int assert)
@@ -233,10 +243,47 @@ static const struct reset_ops uniphier_reset_ops = {
.rst_deassert = uniphier_reset_deassert,
 };
 
+static int uniphier_reset_rst_init(struct udevice *dev)
+{
+   struct uniphier_reset_priv *priv = dev_get_priv(dev);
+   int ret;
+
+   ret = reset_get_bulk(dev, >rsts);
+   if (ret == -ENOSYS || ret == -ENOENT)
+   return 0;
+   else if (ret)
+   return ret;
+
+   ret = reset_deassert_bulk(>rsts);
+   if (ret)
+   reset_release_bulk(>rsts);
+
+   return ret;
+}
+
+static int uniphier_reset_clk_init(struct udevice *dev)
+{
+   struct uniphier_reset_priv *priv = dev_get_priv(dev);
+   int ret;
+
+   ret = clk_get_bulk(dev, >clks);
+   if (ret == -ENOSYS || ret == -ENOENT)
+   return 0;
+   if (ret)
+   return ret;
+
+   ret = clk_enable_bulk(>clks);
+   if (ret)
+   clk_release_bulk(>clks);
+
+   return ret;
+}
+
 static int uniphier_reset_probe(struct udevice *dev)
 {
struct uniphier_reset_priv *priv = dev_get_priv(dev);
fdt_addr_t addr;
+   int ret;
 
addr = dev_read_addr(dev->parent);
if (addr == FDT_ADDR_T_NONE)
@@ -248,7 +295,11 @@ static int uniphier_reset_probe(struct udevice *dev)
 
priv->data = (void *)dev_get_driver_data(dev);
 
-   return 0;
+   ret = uniphier_reset_clk_init(dev);
+   if (ret)
+   return ret;
+
+   return uniphier_reset_rst_init(dev);
 }
 
 static const struct udevice_id uniphier_reset_match[] = {
@@ -355,6 +406,31 @@ static const struct udevice_id uniphier_reset_match[] = {
.compatible = "socionext,uniphier-pxs3-peri-reset",
.data = (ulong)uniphier_pro4_peri_reset_data,
},
+   /* USB glue reset */
+   {
+   .compatible = "socionext,uniphier-pro4-usb3-reset",
+   .data = (ulong)uniphier_pro4_usb3_reset_data,
+   },
+   {
+   .compatible = "socionext,uniphier-pro5-usb3-reset",
+   .data = (ulong)uniphier_pro4_usb3_reset_data,
+   },
+   {
+   .compatible = "socionext,uniphier-pxs2-usb3-reset",
+   .data = (ulong)uniphier_pro4_usb3_reset_data,
+   },
+   {
+   .compatible = "socionext,uniphier-ld20-usb3-reset",
+   .data = (ulong)uniphier_pro4_usb3_reset_data,
+   },
+   {
+   .compatible = "socionext,uniphier-pxs3-usb3-reset",
+   .data = (ulong)uniphier_pro4_usb3_reset_data,
+   },
+   {
+   .compatible = "socionext,uniphier-nx1-usb3-reset",
+   .data = (ulong)uniphier_pro4_usb3_reset_data,
+   },
{ /* sentinel */ }
 };
 
-- 
2.25.1



[PATCH v3 07/10] clk: uniphier: Add missing USB SS-PHY clocks

2023-02-08 Thread Kunihiko Hayashi
The USB SS-PHY needs its own clock, however, some clocks don't have
clock gates. Define missing clock entries for the PHY as reference
clock.

Signed-off-by: Kunihiko Hayashi 
---
 drivers/clk/uniphier/clk-uniphier-sys.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/clk/uniphier/clk-uniphier-sys.c 
b/drivers/clk/uniphier/clk-uniphier-sys.c
index ff5d364f5978..3b8595fe610a 100644
--- a/drivers/clk/uniphier/clk-uniphier-sys.c
+++ b/drivers/clk/uniphier/clk-uniphier-sys.c
@@ -28,7 +28,10 @@ const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[] 
= {
UNIPHIER_CLK_GATE_SIMPLE(14, 0x2104, 16),   /* usb30 (Pro4, Pro5, 
PXs2) */
UNIPHIER_CLK_GATE_SIMPLE(15, 0x2104, 17),   /* usb31 (Pro4, Pro5, 
PXs2) */
UNIPHIER_CLK_GATE_SIMPLE(16, 0x2104, 19),   /* usb30-phy (PXs2) */
+   UNIPHIER_CLK_RATE(17, 2500),/* usb30-phy2 (PXs2) */
+   UNIPHIER_CLK_RATE(18, 2500),/* usb30-phy3 (PXs2) */
UNIPHIER_CLK_GATE_SIMPLE(20, 0x2104, 20),   /* usb31-phy (PXs2) */
+   UNIPHIER_CLK_RATE(21, 2500),/* usb31-phy2 (PXs2) */
UNIPHIER_CLK_GATE_SIMPLE(24, 0x2108, 2),/* pcie (Pro5) */
{ /* sentinel */ }
 #endif
@@ -44,6 +47,8 @@ const struct uniphier_clk_data uniphier_ld20_sys_clk_data[] = 
{
UNIPHIER_CLK_GATE_SIMPLE(14, 0x210c, 14),   /* usb30 (LD20) */
UNIPHIER_CLK_GATE_SIMPLE(16, 0x210c, 12),   /* usb30-phy0 (LD20) */
UNIPHIER_CLK_GATE_SIMPLE(17, 0x210c, 13),   /* usb30-phy1 (LD20) */
+   UNIPHIER_CLK_RATE(18, 2500),/* usb30-phy2 (LD20) */
+   UNIPHIER_CLK_RATE(19, 2500),/* usb30-phy3 (LD20) */
UNIPHIER_CLK_GATE_SIMPLE(24, 0x210c, 4),/* pcie */
{ /* sentinel */ }
 #endif
-- 
2.25.1



[PATCH v3 03/10] usb: dwc3-generic: Add clock initialization in child DT node

2023-02-08 Thread Kunihiko Hayashi
Same as the reset cotnrol, should add a clock initialization in child DT
node, if the glue node doesn't have any clocks.

Signed-off-by: Kunihiko Hayashi 
Reviewed-by: Marek Vasut 
---
 drivers/usb/dwc3/dwc3-generic.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
index e32003d68e01..8fa56e1ac173 100644
--- a/drivers/usb/dwc3/dwc3-generic.c
+++ b/drivers/usb/dwc3/dwc3-generic.c
@@ -572,6 +572,12 @@ static int dwc3_glue_probe(struct udevice *dev)
if (ret)
return ret;
 
+   if (glue->clks.count == 0) {
+   ret = dwc3_glue_clk_init(child, glue);
+   if (ret)
+   return ret;
+   }
+
if (glue->resets.count == 0) {
ret = dwc3_glue_reset_init(child, glue);
if (ret)
-- 
2.25.1



[PATCH v3 01/10] usb: dwc3: Look up reference clock DT phandle in both controller DT nodes

2023-02-08 Thread Kunihiko Hayashi
From: Marek Vasut 

There are currently four disparate placement possibilities of DWC3
reference clock phandle in SoC DTs:
- in top level glue node, with generic subnode without clock (ZynqMP)
- in top level generic node, with no subnode (i.MX8MQ)
- in generic subnode, with other clock in top level node (i.MX8MP)
- in both top level node and generic subnode (Rockchip)

Cover all the possibilities here by looking into both nodes, start
with the top level node as that seems to be used in majority of DTs
to reference the clock.

Signed-off-by: Marek Vasut 
Acked-by: Kunihiko Hayashi 
---
 drivers/usb/dwc3/dwc3-generic.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
index 78966718d01d..42e92478f25a 100644
--- a/drivers/usb/dwc3/dwc3-generic.c
+++ b/drivers/usb/dwc3/dwc3-generic.c
@@ -68,10 +68,27 @@ static int dwc3_generic_probe(struct udevice *dev,
 #if CONFIG_IS_ENABLED(OF_CONTROL)
dwc3_of_parse(dwc3);
 
+   /*
+* There are currently four disparate placement possibilities of DWC3
+* reference clock phandle in SoC DTs:
+* - in top level glue node, with generic subnode without clock (ZynqMP)
+* - in top level generic node, with no subnode (i.MX8MQ)
+* - in generic subnode, with other clock in top level node (i.MX8MP)
+* - in both top level node and generic subnode (Rockchip)
+* Cover all the possibilities here by looking into both nodes, start
+* with the top level node as that seems to be used in majority of DTs
+* to reference the clock.
+*/
node = dev_ofnode(dev->parent);
index = ofnode_stringlist_search(node, "clock-names", "ref");
if (index < 0)
index = ofnode_stringlist_search(node, "clock-names", 
"ref_clk");
+   if (index < 0) {
+   node = dev_ofnode(dev);
+   index = ofnode_stringlist_search(node, "clock-names", "ref");
+   if (index < 0)
+   index = ofnode_stringlist_search(node, "clock-names", 
"ref_clk");
+   }
if (index >= 0)
dwc3->ref_clk = >clks.clks[index];
 #endif
-- 
2.25.1



[PATCH v3 02/10] usb: dwc3-generic: Allow different controller DT node pattern

2023-02-08 Thread Kunihiko Hayashi
The most of devicetree has the following USB node structure.
The controller node is placed as a child node of the glue node.
Current dwc3-generic driver works on this premise.

glue {
/* glue node */
usb {
/* controller node */
};
};

However, UniPhier original devicetree has the following USB node structure.
The controller node is separately placed from the glue node.

usb {
/* controller node */
};
glue {
/* glue node */
};

In dwc_glue_bind(), this patch provides .glue_get_ctrl_dev() callback to
get such a controller node and binds the driver related to the node.

If this callback isn't defined, dwc_glue_bind() looks for the controller
nodes from the child nodes, as before.

Suggested-by: Marek Vasut 
Signed-off-by: Kunihiko Hayashi 
Reviewed-by: Marek Vasut 
---
 drivers/usb/dwc3/dwc3-generic.c | 93 -
 1 file changed, 57 insertions(+), 36 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
index 42e92478f25a..e32003d68e01 100644
--- a/drivers/usb/dwc3/dwc3-generic.c
+++ b/drivers/usb/dwc3/dwc3-generic.c
@@ -276,6 +276,7 @@ U_BOOT_DRIVER(dwc3_generic_host) = {
 #endif
 
 struct dwc3_glue_ops {
+   int (*glue_get_ctrl_dev)(struct udevice *parent, ofnode *node);
void (*glue_configure)(struct udevice *dev, int index,
   enum usb_dr_mode mode);
 };
@@ -415,54 +416,74 @@ struct dwc3_glue_ops ti_ops = {
.glue_configure = dwc3_ti_glue_configure,
 };
 
-static int dwc3_glue_bind(struct udevice *parent)
+static int dwc3_glue_bind_common(struct udevice *parent, ofnode node)
 {
-   ofnode node;
-   int ret;
+   const char *name = ofnode_get_name(node);
+   const char *driver = NULL;
enum usb_dr_mode dr_mode;
+   struct udevice *dev;
+   int ret;
 
-   dr_mode = usb_get_dr_mode(dev_ofnode(parent));
-
-   ofnode_for_each_subnode(node, dev_ofnode(parent)) {
-   const char *name = ofnode_get_name(node);
-   struct udevice *dev;
-   const char *driver = NULL;
-
-   debug("%s: subnode name: %s\n", __func__, name);
+   debug("%s: subnode name: %s\n", __func__, name);
 
-   /* if the parent node doesn't have a mode check the leaf */
-   if (!dr_mode)
-   dr_mode = usb_get_dr_mode(node);
+   /* if the parent node doesn't have a mode check the leaf */
+   dr_mode = usb_get_dr_mode(dev_ofnode(parent));
+   if (!dr_mode)
+   dr_mode = usb_get_dr_mode(node);
 
-   switch (dr_mode) {
-   case USB_DR_MODE_PERIPHERAL:
-   case USB_DR_MODE_OTG:
+   switch (dr_mode) {
+   case USB_DR_MODE_PERIPHERAL:
+   case USB_DR_MODE_OTG:
 #if CONFIG_IS_ENABLED(DM_USB_GADGET)
-   debug("%s: dr_mode: OTG or Peripheral\n", __func__);
-   driver = "dwc3-generic-peripheral";
+   debug("%s: dr_mode: OTG or Peripheral\n", __func__);
+   driver = "dwc3-generic-peripheral";
 #endif
-   break;
+   break;
 #if defined(CONFIG_SPL_USB_HOST) || !defined(CONFIG_SPL_BUILD)
-   case USB_DR_MODE_HOST:
-   debug("%s: dr_mode: HOST\n", __func__);
-   driver = "dwc3-generic-host";
-   break;
+   case USB_DR_MODE_HOST:
+   debug("%s: dr_mode: HOST\n", __func__);
+   driver = "dwc3-generic-host";
+   break;
 #endif
-   default:
-   debug("%s: unsupported dr_mode\n", __func__);
-   return -ENODEV;
-   };
+   default:
+   debug("%s: unsupported dr_mode\n", __func__);
+   return -ENODEV;
+   };
 
-   if (!driver)
-   continue;
+   if (!driver)
+   return -ENXIO;
+
+   ret = device_bind_driver_to_node(parent, driver, name,
+node, );
+   if (ret) {
+   debug("%s: not able to bind usb device mode\n",
+ __func__);
+   return ret;
+   }
+
+   return 0;
+}
+
+static int dwc3_glue_bind(struct udevice *parent)
+{
+   struct dwc3_glue_ops *ops = (struct dwc3_glue_ops 
*)dev_get_driver_data(parent);
+   ofnode node;
+   int ret;
 
-   ret = device_bind_driver_to_node(parent, driver, name,
-node, );
-   if (ret) {
-   debug("%s: not able to bind usb device mode\n",
- __func__);
+   if (ops && ops->glue_get_ctrl_dev) {
+   ret = ops

[PATCH v3 00/10] usb: dwc3: Refactor dwc3-generic and apply to dwc3-uniphier

2023-02-08 Thread Kunihiko Hayashi
This series achieves refactoring of dwc3-generic.

First, dwc3-generic allows DT controller nodes to be children of glue nodes,
but outside of glue nodes.

To achieve this goal, define a glue-specific function to get controller node,
look up more reference clocks in the controller node, and initialize clocks
in children of glue node before access to the controller,

Next, this series exports the structures and functions from the driver source
to the header, and replaces dwc3-uniphier driver as one implementation using
them. This expects dwc3-generic to prevent more SoC-dependent codes.

The dwc3-uniphier has original USB node, however, tentatively added its own
node dedicated to U-Boot. After this refactoring, the driver needs to add
clock entries and PHY driver to enable them corresponding to the properties
in the original node.

PATCH 1 has been provided below.
  
https://patchwork.ozlabs.org/project/uboot/patch/20221215223822.137739-1-ma...@denx.de/

PATCH 2 is based on the suggested patch from Marek.

PATCH 4-5 and 9-10 have been already reviewed in the previous v1.
  https://lists.denx.de/pipermail/u-boot/2023-January/505689.html

Changes since v2:
- Add Reviewed-by: tags
- Add more details to reset-uniphier patch log
- Add error release for clock/reset initializer in phy-uniphier-usb3 patch
- Fix release year in in phy-uniphier-usb3 patch
- Enable PHY_UNIPHIER_USB3 with DWC3_UNIPHIER
- Separate devicetree patches

Changes since v1:
- Add a patch to refer to the clock in top level generic node
- Add a patch to allow controller DT node outside of glue node
- Add a patch to initialize clocks in children of glue node
- Update dwc3_glue_ops to add the function to get controller device
- Add a patch to support USB glue reset
- Add a patch to add missing PHY clocks
- Add a patch to enable the driver to enable PHY clocks and resets
- Add a patch to fix node names and missing properties
- Add a patch to switch to the original USB node in DT

Kunihiko Hayashi (9):
  usb: dwc3-generic: Allow different controller DT node pattern
  usb: dwc3-generic: Add clock initialization in child DT node
  usb: dwc3-generic: Export glue structures and functions
  usb: dwc3-generic: Add the size of regs property to glue structure
  reset: uniphier: Add USB glue reset support
  clk: uniphier: Add missing USB SS-PHY clocks
  phy: socionext: Add UniPhier USB3 PHY driver
  usb: dwc3-uniphier: Use dwc3-generic instead of xhci-dwc3
  uniphier_defconfig: Disable USB_XHCI_DWC3

Marek Vasut (1):
  usb: dwc3: Look up reference clock DT phandle in both controller DT
nodes

 configs/uniphier_v7_defconfig |   1 -
 configs/uniphier_v8_defconfig |   1 -
 drivers/clk/uniphier/clk-uniphier-sys.c   |   5 +
 drivers/phy/socionext/Kconfig |   8 ++
 drivers/phy/socionext/Makefile|   1 +
 drivers/phy/socionext/phy-uniphier-usb3.c |  93 +++
 drivers/reset/reset-uniphier.c|  78 -
 drivers/usb/dwc3/Kconfig  |   4 +-
 drivers/usb/dwc3/dwc3-generic.c   | 132 ++
 drivers/usb/dwc3/dwc3-generic.h   |  33 ++
 drivers/usb/dwc3/dwc3-uniphier.c  | 116 ---
 11 files changed, 378 insertions(+), 94 deletions(-)
 create mode 100644 drivers/phy/socionext/phy-uniphier-usb3.c
 create mode 100644 drivers/usb/dwc3/dwc3-generic.h

-- 
2.25.1



Re: [PATCH v2 07/12] reset: uniphier: Add USB glue reset support

2023-02-01 Thread Kunihiko Hayashi

Hi Marek,

On 2023/02/02 6:51, Marek Vasut wrote:

On 2/1/23 02:13, Kunihiko Hayashi wrote:

Add reset control support in USB glue logic. This needs to control
the external clocks and resets for the logic before accessing the
glue logic.

Signed-off-by: Kunihiko Hayashi 


With the very little knowledge I have of this platform:
Reviewed-by: Marek Vasut 


I see. I should make some explanation.

The dm tree for usb is the following.

  glue
+-- controller   (need controller-reset)
+-- controller-reset (need syscon-reset)
+-- phy

The controller needs to deassert "controller-reset" in the glue.
The glue needs to deassert "syscon-reset".

The glue node itself doesn't have "resets" property, so
the controller-reset controls "syscon-reset" instead.

This patch adds the reset control for "controller-reset".

Thank you,

---
Best Regards
Kunihiko Hayashi


Re: [PATCH v2 10/12] ARM: dts: uniphier: Fix node names and missing reg property in USB glue node

2023-02-01 Thread Kunihiko Hayashi

Hi Marek,

On 2023/02/02 6:55, Marek Vasut wrote:

On 2/1/23 02:13, Kunihiko Hayashi wrote:

The node name should follow the generic name list in DT specification.
This moves "reset" to "reset-controller", "hs-phy" and "ss-phy" to "phy"
in the USB glue node.

And the node should have reg property to define the register region.

Signed-off-by: Kunihiko Hayashi 
---
   arch/arm/dts/uniphier-ld20.dtsi | 15 ---
   arch/arm/dts/uniphier-pro4.dtsi |  7 ---
   arch/arm/dts/uniphier-pro5.dtsi | 15 ---
   arch/arm/dts/uniphier-pxs2.dtsi | 20 +++-
   arch/arm/dts/uniphier-pxs3.dtsi | 20 +++-
   5 files changed, 42 insertions(+), 35 deletions(-)


I don't mind this patch, but would it make sense to later, in a separate
patch, synchronize the .dtsi with Linux kernel fully ?


I see.

I also think I should to synchronize the devicetree with Linux, so
I'll separate this patch from this series in the next.

Thank you,

---
Best Regards
Kunihiko Hayashi


Re: [PATCH v2 09/12] phy: socionext: Add UniPhier USB3 PHY driver

2023-02-01 Thread Kunihiko Hayashi

Hi Marek,

Thank you for reviewing.

On 2023/02/02 6:54, Marek Vasut wrote:

On 2/1/23 02:13, Kunihiko Hayashi wrote:

Add USB3 PHY driver support to control clocks and resets for the phy.

Signed-off-by: Kunihiko Hayashi 
---
   configs/uniphier_v8_defconfig |  1 +
   drivers/phy/socionext/Kconfig |  7 ++
   drivers/phy/socionext/Makefile|  1 +
   drivers/phy/socionext/phy-uniphier-usb3.c | 89 +++
   4 files changed, 98 insertions(+)
   create mode 100644 drivers/phy/socionext/phy-uniphier-usb3.c

diff --git a/configs/uniphier_v8_defconfig b/configs/uniphier_v8_defconfig
index 6a0e2666cf..5cfa9fc01d 100644
--- a/configs/uniphier_v8_defconfig
+++ b/configs/uniphier_v8_defconfig
@@ -78,3 +78,4 @@ CONFIG_USB_DWC3=y
   CONFIG_USB_DWC3_UNIPHIER=y
   CONFIG_PANIC_HANG=y
   CONFIG_FDT_FIXUP_PARTITIONS=y
+CONFIG_PHY_UNIPHIER_USB3=y


This should be in 12/12 patch, right ?


Yes, this should be.


diff --git a/drivers/phy/socionext/Kconfig b/drivers/phy/socionext/Kconfig
index bcd579e98e..fc63f4c042 100644
--- a/drivers/phy/socionext/Kconfig
+++ b/drivers/phy/socionext/Kconfig
@@ -10,3 +10,10 @@ config PHY_UNIPHIER_PCIE
help
  Enable this to support PHY implemented in PCIe controller
  on UniPhier SoCs.
+
+config PHY_UNIPHIER_USB3
+   bool "UniPhier USB3 PHY driver"
+   depends on PHY && ARCH_UNIPHIER


Maybe 'default y if SOMETHING' here, so you won't need to adjust defconfig ?


OK. this phy is mandatory for the controller.


+   help
+ Enable this to support PHY implemented in USB3 controller
+ on UniPhier SoCs.
diff --git a/drivers/phy/socionext/Makefile
b/drivers/phy/socionext/Makefile
index 5484360b70..94d3aa68cf 100644
--- a/drivers/phy/socionext/Makefile
+++ b/drivers/phy/socionext/Makefile
@@ -4,3 +4,4 @@
   #

   obj-$(CONFIG_PHY_UNIPHIER_PCIE)  += phy-uniphier-pcie.o
+obj-$(CONFIG_PHY_UNIPHIER_USB3)+= phy-uniphier-usb3.o
diff --git a/drivers/phy/socionext/phy-uniphier-usb3.c
b/drivers/phy/socionext/phy-uniphier-usb3.c
new file mode 100644
index 00..a2e44a52c1
--- /dev/null
+++ b/drivers/phy/socionext/phy-uniphier-usb3.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * phy_uniphier_usb3.c - Socionext UniPhier Usb3 PHY driver
+ * Copyright 2019-2021 Socionext, Inc.


2023 instead of 2021 .


I'll fix it.


+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+struct uniphier_usb3phy_priv {
+   struct clk_bulk clks;
+   struct reset_ctl_bulk rsts;
+};
+
+static int uniphier_usb3phy_init(struct phy *phy)
+{
+   struct uniphier_usb3phy_priv *priv = dev_get_priv(phy->dev);
+   int ret;
+
+   ret = clk_enable_bulk(>clks);
+   if (ret) {
+   clk_release_bulk(>clks);
+   return ret;
+   }
+
+   ret = reset_deassert_bulk(>rsts);
+   if (ret) {
+   reset_release_bulk(>rsts);


You have to disable clock here too.


Yes. I'll add it.


+   return ret;
+   }
+
+   return 0;
+}
+
+static int uniphier_usb3phy_probe(struct udevice *dev)
+{
+   struct uniphier_usb3phy_priv *priv = dev_get_priv(dev);
+   int ret;
+
+   ret = clk_get_bulk(dev, >clks);
+   if (ret) {
+   if (ret != -ENOSYS && ret != -ENOENT) {
+   printf("Failed to get clocks\n");
+   return ret;
+   }
+   }
+
+   ret = reset_get_bulk(dev, >rsts);
+   if (ret) {
+   if (ret != -ENOSYS && ret != -ENOENT) {
+   printf("Failed to get resets\n");


You have to release resets here too (use fail path, i.e. goto err_clock).


I see. I'll consider adding release or using "devm" function.

Thank you,

---
Best Regards
Kunihiko Hayashi


[PATCH v2 11/12] ARM: dts: uniphier: Switch USB node to the original

2023-01-31 Thread Kunihiko Hayashi
UniPhier DT applies its own USB node for U-Boot due to the USB driver
constrains. After solving this issue, u-boot allows the original USB node.

After switching USB node, synchronization of USB node with Linux becomes
possible.

Signed-off-by: Kunihiko Hayashi 
---
 arch/arm/dts/uniphier-ld20.dtsi | 21 +
 arch/arm/dts/uniphier-pro4.dtsi | 42 ++---
 arch/arm/dts/uniphier-pxs2.dtsi | 42 ++---
 arch/arm/dts/uniphier-pxs3.dtsi | 42 ++---
 4 files changed, 7 insertions(+), 140 deletions(-)

diff --git a/arch/arm/dts/uniphier-ld20.dtsi b/arch/arm/dts/uniphier-ld20.dtsi
index 21a431ab7f..9155b39dfa 100644
--- a/arch/arm/dts/uniphier-ld20.dtsi
+++ b/arch/arm/dts/uniphier-ld20.dtsi
@@ -744,7 +744,7 @@
};
};
 
-   _usb: usb@65a0 {
+   usb: usb@65a0 {
compatible = "socionext,uniphier-dwc3", "snps,dwc3";
status = "disabled";
reg = <0x65a0 0xcd00>;
@@ -895,25 +895,6 @@
};
};
 
-   /* FIXME: U-Boot own node */
-   usb: usb@65b0 {
-   compatible = "socionext,uniphier-ld20-dwc3";
-   reg = <0x65b0 0x1000>;
-   #address-cells = <1>;
-   #size-cells = <1>;
-   ranges;
-   pinctrl-names = "default";
-   pinctrl-0 = <_usb0>, <_usb1>,
-   <_usb2>, <_usb3>;
-   dwc3@65a0 {
-   compatible = "snps,dwc3";
-   reg = <0x65a0 0x1>;
-   interrupts = <0 134 4>;
-   dr_mode = "host";
-   tx-fifo-resize;
-   };
-   };
-
pcie: pcie@6600 {
compatible = "socionext,uniphier-pcie", "snps,dw-pcie";
status = "disabled";
diff --git a/arch/arm/dts/uniphier-pro4.dtsi b/arch/arm/dts/uniphier-pro4.dtsi
index 0e0a30ab40..3412c800e3 100644
--- a/arch/arm/dts/uniphier-pro4.dtsi
+++ b/arch/arm/dts/uniphier-pro4.dtsi
@@ -503,7 +503,7 @@
};
};
 
-   _usb0: usb@65a0 {
+   usb0: usb@65a0 {
compatible = "socionext,uniphier-dwc3", "snps,dwc3";
status = "disabled";
reg = <0x65a0 0xcd00>;
@@ -557,26 +557,7 @@
};
};
 
-   /* FIXME: U-Boot own node */
-   usb0: usb@65b0 {
-   compatible = "socionext,uniphier-pro4-dwc3";
-   status = "disabled";
-   reg = <0x65b0 0x1000>;
-   #address-cells = <1>;
-   #size-cells = <1>;
-   ranges;
-   pinctrl-names = "default";
-   pinctrl-0 = <_usb0>;
-   dwc3@65a0 {
-   compatible = "snps,dwc3";
-   reg = <0x65a0 0x1>;
-   interrupts = <0 134 4>;
-   dr_mode = "host";
-   tx-fifo-resize;
-   };
-   };
-
-   _usb1: usb@65c0 {
+   usb1: usb@65c0 {
compatible = "socionext,uniphier-dwc3", "snps,dwc3";
status = "disabled";
reg = <0x65c0 0xcd00>;
@@ -618,25 +599,6 @@
};
};
 
-   /* FIXME: U-Boot own node */
-   usb1: usb@65d0 {
-   compatible = "socionext,uniphier-pro4-dwc3";
-   status = "disabled";
-   reg = <0x65d0 0x1000>;
-   #address-cells = <1>;
-   #size-cells = <1>;
-   ranges;
-   pinctrl-names = "default";
-   pinctrl-0 = <_usb1>;
-   dwc3@65c0 {
-   compatible = "snps,dwc3";
-   reg = <0x65c0 0x1>;
-   interrupts = <0 137 4>;
-   dr_

[PATCH v2 04/12] usb: dwc3-generic: Export glue structures and functions

2023-01-31 Thread Kunihiko Hayashi
In order to allow external SoC-dependent glue drivers to use dwc3-generic
functions, push the glue structures and export the functions to a header
file.

The exported structures and functions are:

- struct dwc3_glue_data
- struct dwc3_glue_ops
- dwc3_glue_bind()
- dwc3_glue_probe()
- dwc3_glue_remove()

The SoC-dependent glue drivers can only define their own wrapper driver
and specify these functions. The drivers can also add their own compatible
strings and configure functions.

Signed-off-by: Kunihiko Hayashi 
Reviewed-by: Marek Vasut 
---
 drivers/usb/dwc3/dwc3-generic.c | 18 --
 drivers/usb/dwc3/dwc3-generic.h | 32 
 2 files changed, 36 insertions(+), 14 deletions(-)
 create mode 100644 drivers/usb/dwc3/dwc3-generic.h

diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
index 8fa56e1ac1..4576390ec7 100644
--- a/drivers/usb/dwc3/dwc3-generic.c
+++ b/drivers/usb/dwc3/dwc3-generic.c
@@ -28,11 +28,7 @@
 #include 
 #include 
 
-struct dwc3_glue_data {
-   struct clk_bulk clks;
-   struct reset_ctl_bulk   resets;
-   fdt_addr_t regs;
-};
+#include "dwc3-generic.h"
 
 struct dwc3_generic_plat {
fdt_addr_t base;
@@ -275,12 +271,6 @@ U_BOOT_DRIVER(dwc3_generic_host) = {
 };
 #endif
 
-struct dwc3_glue_ops {
-   int (*glue_get_ctrl_dev)(struct udevice *parent, ofnode *node);
-   void (*glue_configure)(struct udevice *dev, int index,
-  enum usb_dr_mode mode);
-};
-
 void dwc3_imx8mp_glue_configure(struct udevice *dev, int index,
enum usb_dr_mode mode)
 {
@@ -464,7 +454,7 @@ static int dwc3_glue_bind_common(struct udevice *parent, 
ofnode node)
return 0;
 }
 
-static int dwc3_glue_bind(struct udevice *parent)
+int dwc3_glue_bind(struct udevice *parent)
 {
struct dwc3_glue_ops *ops = (struct dwc3_glue_ops 
*)dev_get_driver_data(parent);
ofnode node;
@@ -531,7 +521,7 @@ static int dwc3_glue_clk_init(struct udevice *dev,
return 0;
 }
 
-static int dwc3_glue_probe(struct udevice *dev)
+int dwc3_glue_probe(struct udevice *dev)
 {
struct dwc3_glue_ops *ops = (struct dwc3_glue_ops 
*)dev_get_driver_data(dev);
struct dwc3_glue_data *glue = dev_get_plat(dev);
@@ -597,7 +587,7 @@ static int dwc3_glue_probe(struct udevice *dev)
return 0;
 }
 
-static int dwc3_glue_remove(struct udevice *dev)
+int dwc3_glue_remove(struct udevice *dev)
 {
struct dwc3_glue_data *glue = dev_get_plat(dev);
 
diff --git a/drivers/usb/dwc3/dwc3-generic.h b/drivers/usb/dwc3/dwc3-generic.h
new file mode 100644
index 00..824f678841
--- /dev/null
+++ b/drivers/usb/dwc3/dwc3-generic.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * dwc3-generic.h - Generic DWC3 Glue layer header
+ *
+ * Copyright (C) 2016 - 2018 Xilinx, Inc.
+ * Copyright (C) 2023 Socionext Inc.
+ */
+
+#ifndef __DRIVERS_USB_DWC3_GENERIC_H
+#define __DRIVERS_USB_DWC3_GENERIC_H
+
+#include 
+#include 
+#include 
+
+struct dwc3_glue_data {
+   struct clk_bulk clks;
+   struct reset_ctl_bulk   resets;
+   fdt_addr_t regs;
+};
+
+struct dwc3_glue_ops {
+   int (*glue_get_ctrl_dev)(struct udevice *parent, ofnode *node);
+   void (*glue_configure)(struct udevice *dev, int index,
+  enum usb_dr_mode mode);
+};
+
+int dwc3_glue_bind(struct udevice *parent);
+int dwc3_glue_probe(struct udevice *dev);
+int dwc3_glue_remove(struct udevice *dev);
+
+#endif
-- 
2.25.1



[PATCH v2 10/12] ARM: dts: uniphier: Fix node names and missing reg property in USB glue node

2023-01-31 Thread Kunihiko Hayashi
The node name should follow the generic name list in DT specification.
This moves "reset" to "reset-controller", "hs-phy" and "ss-phy" to "phy"
in the USB glue node.

And the node should have reg property to define the register region.

Signed-off-by: Kunihiko Hayashi 
---
 arch/arm/dts/uniphier-ld20.dtsi | 15 ---
 arch/arm/dts/uniphier-pro4.dtsi |  7 ---
 arch/arm/dts/uniphier-pro5.dtsi | 15 ---
 arch/arm/dts/uniphier-pxs2.dtsi | 20 +++-
 arch/arm/dts/uniphier-pxs3.dtsi | 20 +++-
 5 files changed, 42 insertions(+), 35 deletions(-)

diff --git a/arch/arm/dts/uniphier-ld20.dtsi b/arch/arm/dts/uniphier-ld20.dtsi
index 4549935c42..21a431ab7f 100644
--- a/arch/arm/dts/uniphier-ld20.dtsi
+++ b/arch/arm/dts/uniphier-ld20.dtsi
@@ -765,11 +765,12 @@
usb-glue@65b0 {
compatible = "socionext,uniphier-ld20-dwc3-glue",
 "simple-mfd";
+   reg = <0x65b0 0x4000>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x65b0 0x400>;
 
-   usb_rst: reset@0 {
+   usb_rst: reset-controller@0 {
compatible = 
"socionext,uniphier-ld20-usb3-reset";
reg = <0x0 0x4>;
#reset-cells = <1>;
@@ -815,7 +816,7 @@
resets = <_rst 14>;
};
 
-   usb_hsphy0: hs-phy@200 {
+   usb_hsphy0: phy@200 {
compatible = 
"socionext,uniphier-ld20-usb3-hsphy";
reg = <0x200 0x10>;
#phy-cells = <0>;
@@ -829,7 +830,7 @@
  <_hs_i0>;
};
 
-   usb_hsphy1: hs-phy@210 {
+   usb_hsphy1: phy@210 {
compatible = 
"socionext,uniphier-ld20-usb3-hsphy";
reg = <0x210 0x10>;
#phy-cells = <0>;
@@ -843,7 +844,7 @@
  <_hs_i0>;
};
 
-   usb_hsphy2: hs-phy@220 {
+   usb_hsphy2: phy@220 {
compatible = 
"socionext,uniphier-ld20-usb3-hsphy";
reg = <0x220 0x10>;
#phy-cells = <0>;
@@ -857,7 +858,7 @@
  <_hs_i2>;
};
 
-   usb_hsphy3: hs-phy@230 {
+   usb_hsphy3: phy@230 {
compatible = 
"socionext,uniphier-ld20-usb3-hsphy";
reg = <0x230 0x10>;
#phy-cells = <0>;
@@ -871,7 +872,7 @@
  <_hs_i2>;
};
 
-   usb_ssphy0: ss-phy@300 {
+   usb_ssphy0: phy@300 {
compatible = 
"socionext,uniphier-ld20-usb3-ssphy";
reg = <0x300 0x10>;
#phy-cells = <0>;
@@ -882,7 +883,7 @@
vbus-supply = <_vbus0>;
};
 
-   usb_ssphy1: ss-phy@310 {
+   usb_ssphy1: phy@310 {
compatible = 
"socionext,uniphier-ld20-usb3-ssphy";
reg = <0x310 0x10>;
#phy-cells = <0>;
diff --git a/arch/arm/dts/uniphier-pro4.dtsi b/arch/arm/dts/uniphier-pro4.dtsi
index 9dae4e9b23..0e0a30ab40 100644
--- a/arch/arm/dts/uniphier-pro4.dtsi
+++ b/arch/arm/dts/uniphier-pro4.dtsi
@@ -521,6 +521,7 @@
usb-glue@65b0 {
compatible = "socionext,uniphier-pro4-dwc3-glue",
 "simple-mfd";
+   reg = <0x65b0 0x100>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x65b0 0x100>;
@@ -534,7 +535,7 @@
resets = <_rst 12>, <_rst 14>;
};
 
-   usb0_ssphy: ss-phy@10 {
+   usb0_ssphy: phy@10 {
compatible = 
"socionext,uniphier-pro4-usb3-ssphy";
  

[PATCH v2 09/12] phy: socionext: Add UniPhier USB3 PHY driver

2023-01-31 Thread Kunihiko Hayashi
Add USB3 PHY driver support to control clocks and resets for the phy.

Signed-off-by: Kunihiko Hayashi 
---
 configs/uniphier_v8_defconfig |  1 +
 drivers/phy/socionext/Kconfig |  7 ++
 drivers/phy/socionext/Makefile|  1 +
 drivers/phy/socionext/phy-uniphier-usb3.c | 89 +++
 4 files changed, 98 insertions(+)
 create mode 100644 drivers/phy/socionext/phy-uniphier-usb3.c

diff --git a/configs/uniphier_v8_defconfig b/configs/uniphier_v8_defconfig
index 6a0e2666cf..5cfa9fc01d 100644
--- a/configs/uniphier_v8_defconfig
+++ b/configs/uniphier_v8_defconfig
@@ -78,3 +78,4 @@ CONFIG_USB_DWC3=y
 CONFIG_USB_DWC3_UNIPHIER=y
 CONFIG_PANIC_HANG=y
 CONFIG_FDT_FIXUP_PARTITIONS=y
+CONFIG_PHY_UNIPHIER_USB3=y
diff --git a/drivers/phy/socionext/Kconfig b/drivers/phy/socionext/Kconfig
index bcd579e98e..fc63f4c042 100644
--- a/drivers/phy/socionext/Kconfig
+++ b/drivers/phy/socionext/Kconfig
@@ -10,3 +10,10 @@ config PHY_UNIPHIER_PCIE
help
  Enable this to support PHY implemented in PCIe controller
  on UniPhier SoCs.
+
+config PHY_UNIPHIER_USB3
+   bool "UniPhier USB3 PHY driver"
+   depends on PHY && ARCH_UNIPHIER
+   help
+ Enable this to support PHY implemented in USB3 controller
+ on UniPhier SoCs.
diff --git a/drivers/phy/socionext/Makefile b/drivers/phy/socionext/Makefile
index 5484360b70..94d3aa68cf 100644
--- a/drivers/phy/socionext/Makefile
+++ b/drivers/phy/socionext/Makefile
@@ -4,3 +4,4 @@
 #
 
 obj-$(CONFIG_PHY_UNIPHIER_PCIE)+= phy-uniphier-pcie.o
+obj-$(CONFIG_PHY_UNIPHIER_USB3)+= phy-uniphier-usb3.o
diff --git a/drivers/phy/socionext/phy-uniphier-usb3.c 
b/drivers/phy/socionext/phy-uniphier-usb3.c
new file mode 100644
index 00..a2e44a52c1
--- /dev/null
+++ b/drivers/phy/socionext/phy-uniphier-usb3.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * phy_uniphier_usb3.c - Socionext UniPhier Usb3 PHY driver
+ * Copyright 2019-2021 Socionext, Inc.
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+struct uniphier_usb3phy_priv {
+   struct clk_bulk clks;
+   struct reset_ctl_bulk rsts;
+};
+
+static int uniphier_usb3phy_init(struct phy *phy)
+{
+   struct uniphier_usb3phy_priv *priv = dev_get_priv(phy->dev);
+   int ret;
+
+   ret = clk_enable_bulk(>clks);
+   if (ret) {
+   clk_release_bulk(>clks);
+   return ret;
+   }
+
+   ret = reset_deassert_bulk(>rsts);
+   if (ret) {
+   reset_release_bulk(>rsts);
+   return ret;
+   }
+
+   return 0;
+}
+
+static int uniphier_usb3phy_probe(struct udevice *dev)
+{
+   struct uniphier_usb3phy_priv *priv = dev_get_priv(dev);
+   int ret;
+
+   ret = clk_get_bulk(dev, >clks);
+   if (ret) {
+   if (ret != -ENOSYS && ret != -ENOENT) {
+   printf("Failed to get clocks\n");
+   return ret;
+   }
+   }
+
+   ret = reset_get_bulk(dev, >rsts);
+   if (ret) {
+   if (ret != -ENOSYS && ret != -ENOENT) {
+   printf("Failed to get resets\n");
+   return ret;
+   }
+   }
+
+   return 0;
+}
+
+static struct phy_ops uniphier_usb3phy_ops = {
+   .init = uniphier_usb3phy_init,
+};
+
+static const struct udevice_id uniphier_usb3phy_ids[] = {
+   { .compatible = "socionext,uniphier-pro4-usb3-ssphy" },
+   { .compatible = "socionext,uniphier-pro5-usb3-hsphy" },
+   { .compatible = "socionext,uniphier-pro5-usb3-ssphy" },
+   { .compatible = "socionext,uniphier-pxs2-usb3-hsphy" },
+   { .compatible = "socionext,uniphier-pxs2-usb3-ssphy" },
+   { .compatible = "socionext,uniphier-ld20-usb3-hsphy" },
+   { .compatible = "socionext,uniphier-ld20-usb3-ssphy" },
+   { .compatible = "socionext,uniphier-pxs3-usb3-hsphy" },
+   { .compatible = "socionext,uniphier-pxs3-usb3-ssphy" },
+   { .compatible = "socionext,uniphier-nx1-usb3-hsphy" },
+   { .compatible = "socionext,uniphier-nx1-usb3-ssphy" },
+   { }
+};
+
+U_BOOT_DRIVER(uniphier_usb3_phy) = {
+   .name   = "uniphier-usb3-phy",
+   .id = UCLASS_PHY,
+   .of_match   = uniphier_usb3phy_ids,
+   .ops= _usb3phy_ops,
+   .probe  = uniphier_usb3phy_probe,
+   .priv_auto  = sizeof(struct uniphier_usb3phy_priv),
+};
-- 
2.25.1



[PATCH v2 12/12] uniphier_defconfig: Disable USB_XHCI_DWC3

2023-01-31 Thread Kunihiko Hayashi
Replacing with dwc3-generic, no need USB_XHCI_DWC3 anymore.

Signed-off-by: Kunihiko Hayashi 
Reviewed-by: Marek Vasut 
---
 configs/uniphier_v7_defconfig | 1 -
 configs/uniphier_v8_defconfig | 1 -
 2 files changed, 2 deletions(-)

diff --git a/configs/uniphier_v7_defconfig b/configs/uniphier_v7_defconfig
index d626968c76..03feb04b93 100644
--- a/configs/uniphier_v7_defconfig
+++ b/configs/uniphier_v7_defconfig
@@ -82,7 +82,6 @@ CONFIG_DM_SPI=y
 CONFIG_UNIPHIER_SPI=y
 CONFIG_USB=y
 CONFIG_USB_XHCI_HCD=y
-CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_GENERIC=y
 CONFIG_USB_DWC3=y
diff --git a/configs/uniphier_v8_defconfig b/configs/uniphier_v8_defconfig
index 5cfa9fc01d..93520e01a1 100644
--- a/configs/uniphier_v8_defconfig
+++ b/configs/uniphier_v8_defconfig
@@ -71,7 +71,6 @@ CONFIG_SYSRESET=y
 CONFIG_SYSRESET_PSCI=y
 CONFIG_USB=y
 CONFIG_USB_XHCI_HCD=y
-CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_GENERIC=y
 CONFIG_USB_DWC3=y
-- 
2.25.1



[PATCH v2 06/12] usb: dwc3-uniphier: Use dwc3-generic instead of xhci-dwc3

2023-01-31 Thread Kunihiko Hayashi
dwc3-uniphier depends on xhci-dwc3 framework, however, it is preferable
to use dwc3-generic.

This driver calls the exported dwc3-generic functions and redefine
the SoC-dependent operations to fit dwc3-generic.

Signed-off-by: Kunihiko Hayashi 
Reviewed-by: Marek Vasut 
---
 drivers/usb/dwc3/Kconfig |   3 +-
 drivers/usb/dwc3/dwc3-uniphier.c | 116 ---
 2 files changed, 77 insertions(+), 42 deletions(-)

diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index f010291d02..69801eeb81 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -55,7 +55,8 @@ config USB_DWC3_MESON_GXL
 
 config USB_DWC3_UNIPHIER
bool "DesignWare USB3 Host Support on UniPhier Platforms"
-   depends on ARCH_UNIPHIER && USB_XHCI_DWC3
+   depends on ARCH_UNIPHIER && USB_DWC3
+   select USB_DWC3_GENERIC
help
  Support of USB2/3 functionality in Socionext UniPhier platforms.
  Say 'Y' here if you have one such device.
diff --git a/drivers/usb/dwc3/dwc3-uniphier.c b/drivers/usb/dwc3/dwc3-uniphier.c
index 54b52dcd66..ab85428a70 100644
--- a/drivers/usb/dwc3/dwc3-uniphier.c
+++ b/drivers/usb/dwc3/dwc3-uniphier.c
@@ -4,14 +4,17 @@
  *
  * Copyright (C) 2016-2017 Socionext Inc.
  *   Author: Masahiro Yamada 
+ *   Author: Kunihiko Hayashi 
  */
 
 #include 
-#include 
+#include 
 #include 
-#include 
-#include 
-#include 
+#include 
+
+#include "core.h"
+#include "gadget.h"
+#include "dwc3-generic.h"
 
 #define UNIPHIER_PRO4_DWC3_RESET   0x40
 #define   UNIPHIER_PRO4_DWC3_RESET_XIOMMU  BIT(5)
@@ -27,8 +30,11 @@
 #define UNIPHIER_PXS2_DWC3_RESET   0x00
 #define   UNIPHIER_PXS2_DWC3_RESET_XLINK   BIT(15)
 
-static int uniphier_pro4_dwc3_init(void __iomem *regs)
+static void uniphier_pro4_dwc3_init(struct udevice *dev, int index,
+   enum usb_dr_mode mode)
 {
+   struct dwc3_glue_data *glue = dev_get_plat(dev);
+   void *regs = map_physmem(glue->regs, glue->size, MAP_NOCACHE);
u32 tmp;
 
tmp = readl(regs + UNIPHIER_PRO4_DWC3_RESET);
@@ -36,11 +42,14 @@ static int uniphier_pro4_dwc3_init(void __iomem *regs)
tmp |= UNIPHIER_PRO4_DWC3_RESET_XIOMMU | UNIPHIER_PRO4_DWC3_RESET_XLINK;
writel(tmp, regs + UNIPHIER_PRO4_DWC3_RESET);
 
-   return 0;
+   unmap_physmem(regs, MAP_NOCACHE);
 }
 
-static int uniphier_pro5_dwc3_init(void __iomem *regs)
+static void uniphier_pro5_dwc3_init(struct udevice *dev, int index,
+   enum usb_dr_mode mode)
 {
+   struct dwc3_glue_data *glue = dev_get_plat(dev);
+   void *regs = map_physmem(glue->regs, glue->size, MAP_NOCACHE);
u32 tmp;
 
tmp = readl(regs + UNIPHIER_PRO5_DWC3_RESET);
@@ -49,72 +58,97 @@ static int uniphier_pro5_dwc3_init(void __iomem *regs)
tmp |= UNIPHIER_PRO5_DWC3_RESET_XLINK | UNIPHIER_PRO5_DWC3_RESET_XIOMMU;
writel(tmp, regs + UNIPHIER_PRO5_DWC3_RESET);
 
-   return 0;
+   unmap_physmem(regs, MAP_NOCACHE);
 }
 
-static int uniphier_pxs2_dwc3_init(void __iomem *regs)
+static void uniphier_pxs2_dwc3_init(struct udevice *dev, int index,
+   enum usb_dr_mode mode)
 {
+   struct dwc3_glue_data *glue = dev_get_plat(dev);
+   void *regs = map_physmem(glue->regs, glue->size, MAP_NOCACHE);
u32 tmp;
 
tmp = readl(regs + UNIPHIER_PXS2_DWC3_RESET);
tmp |= UNIPHIER_PXS2_DWC3_RESET_XLINK;
writel(tmp, regs + UNIPHIER_PXS2_DWC3_RESET);
 
-   return 0;
+   unmap_physmem(regs, MAP_NOCACHE);
 }
 
-static int uniphier_dwc3_probe(struct udevice *dev)
+static int dwc3_uniphier_glue_get_ctrl_dev(struct udevice *dev, ofnode *node)
 {
-   fdt_addr_t base;
-   void __iomem *regs;
-   int (*init)(void __iomem *regs);
-   int ret;
+   struct udevice *child;
+   const char *name;
+   ofnode subnode;
+
+   /*
+* "controller reset" belongs to glue logic, and it should be
+* accessible in .glue_configure() before access to the controller
+* begins.
+*/
+   ofnode_for_each_subnode(subnode, dev_ofnode(dev)) {
+   name = ofnode_get_name(subnode);
+   if (!strncmp(name, "reset", 5))
+   device_bind_driver_to_node(dev, "uniphier-reset",
+  name, subnode, );
+   }
+
+   /* Get controller node that is placed separately from the glue node */
+   *node = ofnode_by_compatible(dev_ofnode(dev->parent),
+"socionext,uniphier-dwc3");
 
-   base = dev_read_addr(dev);
-   if (base == FDT_ADDR_T_NONE)
-   return -EINVAL;
-
-   regs = ioremap(base, SZ_32K);
-   if (!regs)
-   return -ENOMEM;
+   return 0;
+}
 
-   init = (t

[PATCH v2 08/12] clk: uniphier: Add missing USB SS-PHY clocks

2023-01-31 Thread Kunihiko Hayashi
The USB SS-PHY needs its own clock, however, some clocks don't have
clock gates. Define missing clock entries for the PHY as reference
clock.

Signed-off-by: Kunihiko Hayashi 
---
 drivers/clk/uniphier/clk-uniphier-sys.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/clk/uniphier/clk-uniphier-sys.c 
b/drivers/clk/uniphier/clk-uniphier-sys.c
index ff5d364f59..3b8595fe61 100644
--- a/drivers/clk/uniphier/clk-uniphier-sys.c
+++ b/drivers/clk/uniphier/clk-uniphier-sys.c
@@ -28,7 +28,10 @@ const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[] 
= {
UNIPHIER_CLK_GATE_SIMPLE(14, 0x2104, 16),   /* usb30 (Pro4, Pro5, 
PXs2) */
UNIPHIER_CLK_GATE_SIMPLE(15, 0x2104, 17),   /* usb31 (Pro4, Pro5, 
PXs2) */
UNIPHIER_CLK_GATE_SIMPLE(16, 0x2104, 19),   /* usb30-phy (PXs2) */
+   UNIPHIER_CLK_RATE(17, 2500),/* usb30-phy2 (PXs2) */
+   UNIPHIER_CLK_RATE(18, 2500),/* usb30-phy3 (PXs2) */
UNIPHIER_CLK_GATE_SIMPLE(20, 0x2104, 20),   /* usb31-phy (PXs2) */
+   UNIPHIER_CLK_RATE(21, 2500),/* usb31-phy2 (PXs2) */
UNIPHIER_CLK_GATE_SIMPLE(24, 0x2108, 2),/* pcie (Pro5) */
{ /* sentinel */ }
 #endif
@@ -44,6 +47,8 @@ const struct uniphier_clk_data uniphier_ld20_sys_clk_data[] = 
{
UNIPHIER_CLK_GATE_SIMPLE(14, 0x210c, 14),   /* usb30 (LD20) */
UNIPHIER_CLK_GATE_SIMPLE(16, 0x210c, 12),   /* usb30-phy0 (LD20) */
UNIPHIER_CLK_GATE_SIMPLE(17, 0x210c, 13),   /* usb30-phy1 (LD20) */
+   UNIPHIER_CLK_RATE(18, 2500),/* usb30-phy2 (LD20) */
+   UNIPHIER_CLK_RATE(19, 2500),/* usb30-phy3 (LD20) */
UNIPHIER_CLK_GATE_SIMPLE(24, 0x210c, 4),/* pcie */
{ /* sentinel */ }
 #endif
-- 
2.25.1



[PATCH v2 05/12] usb: dwc3-generic: Add the size of regs property to glue structure

2023-01-31 Thread Kunihiko Hayashi
Add the size of regs property to the glue structure to correctly
specify the register region to map.

Signed-off-by: Kunihiko Hayashi 
Reviewed-by: Marek Vasut 
---
 drivers/usb/dwc3/dwc3-generic.c | 2 +-
 drivers/usb/dwc3/dwc3-generic.h | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
index 4576390ec7..acbf7acb19 100644
--- a/drivers/usb/dwc3/dwc3-generic.c
+++ b/drivers/usb/dwc3/dwc3-generic.c
@@ -542,7 +542,7 @@ int dwc3_glue_probe(struct udevice *dev)
phy.dev = NULL;
}
 
-   glue->regs = dev_read_addr(dev);
+   glue->regs = dev_read_addr_size_index(dev, 0, >size);
 
ret = dwc3_glue_clk_init(dev, glue);
if (ret)
diff --git a/drivers/usb/dwc3/dwc3-generic.h b/drivers/usb/dwc3/dwc3-generic.h
index 824f678841..40902c8923 100644
--- a/drivers/usb/dwc3/dwc3-generic.h
+++ b/drivers/usb/dwc3/dwc3-generic.h
@@ -17,6 +17,7 @@ struct dwc3_glue_data {
struct clk_bulk clks;
struct reset_ctl_bulk   resets;
fdt_addr_t regs;
+   fdt_size_t size;
 };
 
 struct dwc3_glue_ops {
-- 
2.25.1



[PATCH v2 03/12] usb: dwc3-generic: Add clock initialization in child DT node

2023-01-31 Thread Kunihiko Hayashi
Same as the reset cotnrol, should add a clock initialization in child DT
node, if the glue node doesn't have any clocks.

Signed-off-by: Kunihiko Hayashi 
---
 drivers/usb/dwc3/dwc3-generic.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
index e32003d68e..8fa56e1ac1 100644
--- a/drivers/usb/dwc3/dwc3-generic.c
+++ b/drivers/usb/dwc3/dwc3-generic.c
@@ -572,6 +572,12 @@ static int dwc3_glue_probe(struct udevice *dev)
if (ret)
return ret;
 
+   if (glue->clks.count == 0) {
+   ret = dwc3_glue_clk_init(child, glue);
+   if (ret)
+   return ret;
+   }
+
if (glue->resets.count == 0) {
ret = dwc3_glue_reset_init(child, glue);
if (ret)
-- 
2.25.1



[PATCH v2 07/12] reset: uniphier: Add USB glue reset support

2023-01-31 Thread Kunihiko Hayashi
Add reset control support in USB glue logic. This needs to control
the external clocks and resets for the logic before accessing the
glue logic.

Signed-off-by: Kunihiko Hayashi 
---
 drivers/reset/reset-uniphier.c | 78 +-
 1 file changed, 77 insertions(+), 1 deletion(-)

diff --git a/drivers/reset/reset-uniphier.c b/drivers/reset/reset-uniphier.c
index 7adae51873..35e3ccebd7 100644
--- a/drivers/reset/reset-uniphier.c
+++ b/drivers/reset/reset-uniphier.c
@@ -2,6 +2,7 @@
 /*
  * Copyright (C) 2016 Socionext Inc.
  *   Author: Masahiro Yamada 
+ *   Author: Kunihiko Hayashi 
  */
 
 #include 
@@ -9,6 +10,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -178,10 +181,17 @@ static const struct uniphier_reset_data 
uniphier_pro4_peri_reset_data[] = {
UNIPHIER_RESET_END,
 };
 
+/* Glue reset data */
+static const struct uniphier_reset_data uniphier_pro4_usb3_reset_data[] = {
+   UNIPHIER_RESETX(15, 0, 15)
+};
+
 /* core implementaton */
 struct uniphier_reset_priv {
void __iomem *base;
const struct uniphier_reset_data *data;
+   struct clk_bulk clks;
+   struct reset_ctl_bulk   rsts;
 };
 
 static int uniphier_reset_update(struct reset_ctl *reset_ctl, int assert)
@@ -233,10 +243,47 @@ static const struct reset_ops uniphier_reset_ops = {
.rst_deassert = uniphier_reset_deassert,
 };
 
+static int uniphier_reset_rst_init(struct udevice *dev)
+{
+   struct uniphier_reset_priv *priv = dev_get_priv(dev);
+   int ret;
+
+   ret = reset_get_bulk(dev, >rsts);
+   if (ret == -ENOSYS || ret == -ENOENT)
+   return 0;
+   else if (ret)
+   return ret;
+
+   ret = reset_deassert_bulk(>rsts);
+   if (ret)
+   reset_release_bulk(>rsts);
+
+   return ret;
+}
+
+static int uniphier_reset_clk_init(struct udevice *dev)
+{
+   struct uniphier_reset_priv *priv = dev_get_priv(dev);
+   int ret;
+
+   ret = clk_get_bulk(dev, >clks);
+   if (ret == -ENOSYS || ret == -ENOENT)
+   return 0;
+   if (ret)
+   return ret;
+
+   ret = clk_enable_bulk(>clks);
+   if (ret)
+   clk_release_bulk(>clks);
+
+   return ret;
+}
+
 static int uniphier_reset_probe(struct udevice *dev)
 {
struct uniphier_reset_priv *priv = dev_get_priv(dev);
fdt_addr_t addr;
+   int ret;
 
addr = dev_read_addr(dev->parent);
if (addr == FDT_ADDR_T_NONE)
@@ -248,7 +295,11 @@ static int uniphier_reset_probe(struct udevice *dev)
 
priv->data = (void *)dev_get_driver_data(dev);
 
-   return 0;
+   ret = uniphier_reset_clk_init(dev);
+   if (ret)
+   return ret;
+
+   return uniphier_reset_rst_init(dev);
 }
 
 static const struct udevice_id uniphier_reset_match[] = {
@@ -355,6 +406,31 @@ static const struct udevice_id uniphier_reset_match[] = {
.compatible = "socionext,uniphier-pxs3-peri-reset",
.data = (ulong)uniphier_pro4_peri_reset_data,
},
+   /* USB glue reset */
+   {
+   .compatible = "socionext,uniphier-pro4-usb3-reset",
+   .data = (ulong)uniphier_pro4_usb3_reset_data,
+   },
+   {
+   .compatible = "socionext,uniphier-pro5-usb3-reset",
+   .data = (ulong)uniphier_pro4_usb3_reset_data,
+   },
+   {
+   .compatible = "socionext,uniphier-pxs2-usb3-reset",
+   .data = (ulong)uniphier_pro4_usb3_reset_data,
+   },
+   {
+   .compatible = "socionext,uniphier-ld20-usb3-reset",
+   .data = (ulong)uniphier_pro4_usb3_reset_data,
+   },
+   {
+   .compatible = "socionext,uniphier-pxs3-usb3-reset",
+   .data = (ulong)uniphier_pro4_usb3_reset_data,
+   },
+   {
+   .compatible = "socionext,uniphier-nx1-usb3-reset",
+   .data = (ulong)uniphier_pro4_usb3_reset_data,
+   },
{ /* sentinel */ }
 };
 
-- 
2.25.1



[PATCH v2 02/12] usb: dwc3-generic: Allow different controller DT node pattern

2023-01-31 Thread Kunihiko Hayashi
The most of devicetree has the following USB node structure.
The controller node is placed as a child node of the glue node.
Current dwc3-generic driver works on this premise.

glue {
/* glue node */
usb {
/* controller node */
};
};

However, UniPhier original devicetree has the following USB node structure.
The controller node is separately placed from the glue node.

usb {
/* controller node */
};
glue {
/* glue node */
};

In dwc_glue_bind(), this patch provides .glue_get_ctrl_dev() callback to
get such a controller node and binds the driver related to the node.

If this callback isn't defined, dwc_glue_bind() looks for the controller
nodes from the child nodes, as before.

Suggested-by: Marek Vasut 
Signed-off-by: Kunihiko Hayashi 
---
 drivers/usb/dwc3/dwc3-generic.c | 93 -
 1 file changed, 57 insertions(+), 36 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
index 42e92478f2..e32003d68e 100644
--- a/drivers/usb/dwc3/dwc3-generic.c
+++ b/drivers/usb/dwc3/dwc3-generic.c
@@ -276,6 +276,7 @@ U_BOOT_DRIVER(dwc3_generic_host) = {
 #endif
 
 struct dwc3_glue_ops {
+   int (*glue_get_ctrl_dev)(struct udevice *parent, ofnode *node);
void (*glue_configure)(struct udevice *dev, int index,
   enum usb_dr_mode mode);
 };
@@ -415,54 +416,74 @@ struct dwc3_glue_ops ti_ops = {
.glue_configure = dwc3_ti_glue_configure,
 };
 
-static int dwc3_glue_bind(struct udevice *parent)
+static int dwc3_glue_bind_common(struct udevice *parent, ofnode node)
 {
-   ofnode node;
-   int ret;
+   const char *name = ofnode_get_name(node);
+   const char *driver = NULL;
enum usb_dr_mode dr_mode;
+   struct udevice *dev;
+   int ret;
 
-   dr_mode = usb_get_dr_mode(dev_ofnode(parent));
-
-   ofnode_for_each_subnode(node, dev_ofnode(parent)) {
-   const char *name = ofnode_get_name(node);
-   struct udevice *dev;
-   const char *driver = NULL;
-
-   debug("%s: subnode name: %s\n", __func__, name);
+   debug("%s: subnode name: %s\n", __func__, name);
 
-   /* if the parent node doesn't have a mode check the leaf */
-   if (!dr_mode)
-   dr_mode = usb_get_dr_mode(node);
+   /* if the parent node doesn't have a mode check the leaf */
+   dr_mode = usb_get_dr_mode(dev_ofnode(parent));
+   if (!dr_mode)
+   dr_mode = usb_get_dr_mode(node);
 
-   switch (dr_mode) {
-   case USB_DR_MODE_PERIPHERAL:
-   case USB_DR_MODE_OTG:
+   switch (dr_mode) {
+   case USB_DR_MODE_PERIPHERAL:
+   case USB_DR_MODE_OTG:
 #if CONFIG_IS_ENABLED(DM_USB_GADGET)
-   debug("%s: dr_mode: OTG or Peripheral\n", __func__);
-   driver = "dwc3-generic-peripheral";
+   debug("%s: dr_mode: OTG or Peripheral\n", __func__);
+   driver = "dwc3-generic-peripheral";
 #endif
-   break;
+   break;
 #if defined(CONFIG_SPL_USB_HOST) || !defined(CONFIG_SPL_BUILD)
-   case USB_DR_MODE_HOST:
-   debug("%s: dr_mode: HOST\n", __func__);
-   driver = "dwc3-generic-host";
-   break;
+   case USB_DR_MODE_HOST:
+   debug("%s: dr_mode: HOST\n", __func__);
+   driver = "dwc3-generic-host";
+   break;
 #endif
-   default:
-   debug("%s: unsupported dr_mode\n", __func__);
-   return -ENODEV;
-   };
+   default:
+   debug("%s: unsupported dr_mode\n", __func__);
+   return -ENODEV;
+   };
 
-   if (!driver)
-   continue;
+   if (!driver)
+   return -ENXIO;
+
+   ret = device_bind_driver_to_node(parent, driver, name,
+node, );
+   if (ret) {
+   debug("%s: not able to bind usb device mode\n",
+ __func__);
+   return ret;
+   }
+
+   return 0;
+}
+
+static int dwc3_glue_bind(struct udevice *parent)
+{
+   struct dwc3_glue_ops *ops = (struct dwc3_glue_ops 
*)dev_get_driver_data(parent);
+   ofnode node;
+   int ret;
 
-   ret = device_bind_driver_to_node(parent, driver, name,
-node, );
-   if (ret) {
-   debug("%s: not able to bind usb device mode\n",
- __func__);
+   if (ops && ops->glue_get_ctrl_dev) {
+   ret = ops

[PATCH v2 00/12] usb: dwc3: Refactor dwc3-generic and apply to dwc3-uniphier

2023-01-31 Thread Kunihiko Hayashi
This series achieves refactoring of dwc3-generic.

First, dwc3-generic allows DT controller nodes to be children of glue nodes,
but outside of glue nodes.

To achieve this goal, define a glue-specific function to get controller node,
look up more reference clocks in the controller node, and initialize clocks
in children of glue node before access to the controller,

Next, this series exports the structures and functions from the driver source
to the header, and replaces dwc3-uniphier driver as one implementation using
them. This expects dwc3-generic to prevent more SoC-dependent codes.

The dwc3-uniphier has original USB node, however, tentatively added its own
node dedicated to U-Boot. After this refactoring, the driver needs to add
clock entries and PHY driver to enable them corresponding to the properties
in the original node.

PATCH 1 has been provided below.
  
https://patchwork.ozlabs.org/project/uboot/patch/20221215223822.137739-1-ma...@denx.de/

PATCH 2 is based on the suggested patch from Marek.

PATCH 4-6 and 12 have been already reviewed in the previous v1.
  https://lists.denx.de/pipermail/u-boot/2023-January/505689.html

Changes since v1:
- Add PATCH 1 to refer to the clock in top level generic node
- Add PATCH 2 to allow controller DT node outside of glue node
- Add PATCH 3 to initialize clocks in children of glue node
- Update dwc3_glue_ops to add the function to get controller device
- Add PATCH 7 to support USB glue reset
- Add PATCH 8 to add missing PHY clocks
- Add PATCH 9 to enable the driver to enable PHY clocks and resets
- Add PATCH 10 to fix node names and missing properties
- Add PATCH 11 to switch to the original USB node in DT

Kunihiko Hayashi (11):
  usb: dwc3-generic: Allow different controller DT node pattern
  usb: dwc3-generic: Add clock initialization in child DT node
  usb: dwc3-generic: Export glue structures and functions
  usb: dwc3-generic: Add the size of regs property to glue structure
  usb: dwc3-uniphier: Use dwc3-generic instead of xhci-dwc3
  reset: uniphier: Add USB glue reset support
  clk: uniphier: Add missing USB SS-PHY clocks
  phy: socionext: Add UniPhier USB3 PHY driver
  ARM: dts: uniphier: Fix node names and missing reg property in USB
glue node
  ARM: dts: uniphier: Switch USB node to the original
  uniphier_defconfig: Disable USB_XHCI_DWC3

Marek Vasut (1):
  usb: dwc3: Look up reference clock DT phandle in both controller DT
nodes

 arch/arm/dts/uniphier-ld20.dtsi   |  36 ++
 arch/arm/dts/uniphier-pro4.dtsi   |  49 +---
 arch/arm/dts/uniphier-pro5.dtsi   |  15 +--
 arch/arm/dts/uniphier-pxs2.dtsi   |  62 +++---
 arch/arm/dts/uniphier-pxs3.dtsi   |  62 +++---
 configs/uniphier_v7_defconfig |   1 -
 configs/uniphier_v8_defconfig |   2 +-
 drivers/clk/uniphier/clk-uniphier-sys.c   |   5 +
 drivers/phy/socionext/Kconfig |   7 ++
 drivers/phy/socionext/Makefile|   1 +
 drivers/phy/socionext/phy-uniphier-usb3.c |  89 +++
 drivers/reset/reset-uniphier.c|  78 -
 drivers/usb/dwc3/Kconfig  |   3 +-
 drivers/usb/dwc3/dwc3-generic.c   | 132 ++
 drivers/usb/dwc3/dwc3-generic.h   |  33 ++
 drivers/usb/dwc3/dwc3-uniphier.c  | 116 ---
 16 files changed, 422 insertions(+), 269 deletions(-)
 create mode 100644 drivers/phy/socionext/phy-uniphier-usb3.c
 create mode 100644 drivers/usb/dwc3/dwc3-generic.h

-- 
2.25.1



[PATCH v2 01/12] usb: dwc3: Look up reference clock DT phandle in both controller DT nodes

2023-01-31 Thread Kunihiko Hayashi
From: Marek Vasut 

There are currently four disparate placement possibilities of DWC3
reference clock phandle in SoC DTs:
- in top level glue node, with generic subnode without clock (ZynqMP)
- in top level generic node, with no subnode (i.MX8MQ)
- in generic subnode, with other clock in top level node (i.MX8MP)
- in both top level node and generic subnode (Rockchip)

Cover all the possibilities here by looking into both nodes, start
with the top level node as that seems to be used in majority of DTs
to reference the clock.

Signed-off-by: Marek Vasut 
Acked-by: Kunihiko Hayashi 
---
 drivers/usb/dwc3/dwc3-generic.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
index 78966718d0..42e92478f2 100644
--- a/drivers/usb/dwc3/dwc3-generic.c
+++ b/drivers/usb/dwc3/dwc3-generic.c
@@ -68,10 +68,27 @@ static int dwc3_generic_probe(struct udevice *dev,
 #if CONFIG_IS_ENABLED(OF_CONTROL)
dwc3_of_parse(dwc3);
 
+   /*
+* There are currently four disparate placement possibilities of DWC3
+* reference clock phandle in SoC DTs:
+* - in top level glue node, with generic subnode without clock (ZynqMP)
+* - in top level generic node, with no subnode (i.MX8MQ)
+* - in generic subnode, with other clock in top level node (i.MX8MP)
+* - in both top level node and generic subnode (Rockchip)
+* Cover all the possibilities here by looking into both nodes, start
+* with the top level node as that seems to be used in majority of DTs
+* to reference the clock.
+*/
node = dev_ofnode(dev->parent);
index = ofnode_stringlist_search(node, "clock-names", "ref");
if (index < 0)
index = ofnode_stringlist_search(node, "clock-names", 
"ref_clk");
+   if (index < 0) {
+   node = dev_ofnode(dev);
+   index = ofnode_stringlist_search(node, "clock-names", "ref");
+   if (index < 0)
+   index = ofnode_stringlist_search(node, "clock-names", 
"ref_clk");
+   }
if (index >= 0)
dwc3->ref_clk = >clks.clks[index];
 #endif
-- 
2.25.1



Re: [PATCH 3/5] usb: dwc3-generic: Add dependency on SIMPLE_BUS

2023-01-30 Thread Kunihiko Hayashi

Hi Marek,

On 2023/01/31 7:50, Marek Vasut wrote:

On 1/30/23 06:52, Kunihiko Hayashi wrote:

Hi Marek,


Hello Hayashi-san,


Sorry for late reply.
I was stuck in some pitfalls.


No worries, the MW closed today, but rc2 should be still OK to land
these patches.


Thank you for caring.


[...]


I've successfully enabled the regular usb node using your suggested
patch [1] and your earlier submitted patch [2].

[1]
https://source.denx.de/u-boot/custodians/u-boot-usb/-/commit/028ad9536e501986f4e19d27f462f81a9ea70bad
- Change 2nd argument type from "udevice *" to "ofnode"
  because glue_get_ctrl_dev() can give only "ofnode" structure from
  the device node.
- Move soc-dependent stuffs to dwc3-uniphier.c.


Please integrate this patch into your series, feel free to change it as
needed too.


OK, I'll make the commit log.
You're the original author of this patch, what about your tag?


[2]
https://patchwork.ozlabs.org/project/uboot/patch/20221215223822.137739-1-ma...@denx.de/
- correspond to "for top level generic node with no subnode"


Could you provide AB/RB on this one if this looks OK? Then I would apply
it to usb tree .


This looks good to me. The dwc3-uniphier uses this for the reference clock in 
the
top level generic node. I'll provide my tag.


However, the uniphier usb3 glue node has more child nodes (not for
the controller), so I need to add more patches to enable more clocks
that the child nodes have.

I should send new patches as v2 series, though, how do you treat
your patches [1] and [2]?


Yes please, send V2. Regarding [1] and [2], see above.


OK, I'll clean up and make the series soon.

Thank you,

---
Best Regards
Kunihiko Hayashi


Re: [PATCH 3/5] usb: dwc3-generic: Add dependency on SIMPLE_BUS

2023-01-29 Thread Kunihiko Hayashi

Hi Marek,

Sorry for late reply.
I was stuck in some pitfalls.

On 2023/01/25 22:03, Marek Vasut wrote:

On 1/25/23 09:40, Kunihiko Hayashi wrote:

Hi Marek,


Hello Hayashi-san,

[...]


The idea is that the dwc3-generic.c (or dwc3-uniphier.c , placement does
not really matter) binds to "socionext,uniphier-pxs3-dwc3-glue"
compatible first.

Then, the dwc3_glue_ops is extended with a new callback
glue_get_ctrl_dev, which returns the pointer to controller DT node (the
node compatible with "socionext,uniphier-dwc3"). This is used in
dwc3_glue_bind(), which either uses the current implementation with a
loop over all subnodes and tries to find the controller subnode, OR,
calls the glue_get_ctrl_dev callback, obtains controller device node
pointer that way, and runs the inner loop of dwc3_glue_bind() (now
dwc3_glue_bind_common()) only on that pointer.


I understand your patch adds trying to call "glue_get_ctrl_dev" to get
controller device node before finding subnode,


Yes. Feel free to adjust the patch so it fits uniphier better of course.


In either case, the dwc3-generic driver is bound to the controller. You
might need to re-use this trick in dwc3_glue_probe() too.

This should allow you to get rid of the custom DT node too.

Does this work ?


I'll try this soon.


Thank you !


I've successfully enabled the regular usb node using your suggested
patch [1] and your earlier submitted patch [2].

[1] 
https://source.denx.de/u-boot/custodians/u-boot-usb/-/commit/028ad9536e501986f4e19d27f462f81a9ea70bad

  - Change 2nd argument type from "udevice *" to "ofnode"
because glue_get_ctrl_dev() can give only "ofnode" structure from
the device node.
  - Move soc-dependent stuffs to dwc3-uniphier.c.

[2] 
https://patchwork.ozlabs.org/project/uboot/patch/20221215223822.137739-1-ma...@denx.de/
  - correspond to "for top level generic node with no subnode"

However, the uniphier usb3 glue node has more child nodes (not for
the controller), so I need to add more patches to enable more clocks
that the child nodes have.

I should send new patches as v2 series, though, how do you treat
your patches [1] and [2]?

Thank you,

---
Best Regards
Kunihiko Hayashi


Re: [PATCH 3/5] usb: dwc3-generic: Add dependency on SIMPLE_BUS

2023-01-25 Thread Kunihiko Hayashi

Hi Marek,

On 2023/01/25 10:38, Marek Vasut wrote:

On 1/24/23 03:53, Kunihiko Hayashi wrote:

Hi Marek,


Hello Hayashi-san,


On 2023/01/24 0:49, Marek Vasut wrote:

On 1/23/23 06:01, Kunihiko Hayashi wrote:

Hi Marek,


Hello Hayashi-san,

[...]


On the other hand, the PXS2 controller for example is not a bus:

arch/arm/dts/uniphier-pxs2.dtsi:
596 _usb0: usb@65a0 {
597 compatible = "socionext,uniphier-dwc3", "snps,dwc3";
598 status = "disabled";
599 reg = <0x65a0 0xcd00>;
...
610 };


I understand. However, this node isn't used in u-boot.
(see below for details)


Is this needed for socionext dwc3 variant to handle the simple-mfd in
e.g. arch/arm/dts/uniphier-pxs3.dtsi :

614 usb-glue@65b0 {
615 compatible = "socionext,uniphier-pxs3-dwc3-glue",
616  "simple-mfd";

?


In case of U-Boot, the glue driver is probed by:

/* FIXME: U-Boot own node */
usb@65b0 {
compatible = "socionext,uniphier-pxs3-dwc3";

And dwc3-uniphier is also declared as UCLASS_SIMPLE_BUS.
Even if using "simple-mfd", this is included in
drivers/core/simple-bus.c
which is declared as UCLASS_SIMPLE_BUS.


If I understand this correctly, node compatible with
"socionext,uniphier-pxs3-dwc3-glue" is not used at all , right ?


Yes.
Original uniphier devicetree has the following usb nodes.

   usb@65a0 {
   compatible = "snps,dwc3";
   };
   usb-glue@65b0 {
   compatible = "socionext,uniphier-pxs3-dwc3-glue",
"simple-mfd";
   };

However, U-Boot dwc3-generic needs to put dwc3 node under the glue node.


Have a look at arch/arm/dts/imx8mq.dtsi which does not use any glue
node, the snps,dwc3 compatible node is directly placed on the soc@0 bus:

1417
1418 usb_dwc3_0: usb@3810 {
1419 compatible = "fsl,imx8mq-dwc3", "snps,dwc3";
1420 reg = <0x3810 0x1>;
1421 clocks = < IMX8MQ_CLK_USB1_CTRL_ROOT>,


Due to this restriction, there is another usb node dedicated to u-boot.

   /* FIXME: U-Boot own node */
   usb@65b0 { /* glue */
   compatible = "socionext,uniphier-pxs3-dwc3";

   dwc3@65a0 {
   compatible = "snps,dwc3";
   };
   };

So instead of "socionext,uniphier-pxs3-dwc3-glue", the glue driver
uses "socionext,uniphier-pxs3-dwc3" in U-Boot.


Can we use the same method as imx8mq.dtsi uses, to avoid this special
node workaround ?


Umm, it's curious. It seems imx8mq doesn't have any glue registers and
defines
dwc3 core registers directly.

On the other hand, "fsl,imx8mq-dwc3" is included in dwc3-generic.c,
though,
dwc3_glue_bind() calls the driver that the child node shows.

  ofnode_for_each_subnode(node, dev_ofnode(parent)) {
  ...
  device_bind_driver_to_node(parent, driver, name,
 node, );
  ...
  }

Maybe the child node expects the driver that "snps,dwc3" indicates.

If we use the same method as imx8mq.dtsi, I think there is no way to probe
the driver for "snps,dwc3" in dwc3-generic.c.

BTW, xchi-dwc3.c can handle "snps,dwc3", but it seems this doesn't use
usb/dwc3/ functions (so I'm confusing it).


Let's try the following, please have a look at this change:

https://source.denx.de/u-boot/custodians/u-boot-usb/-/commit/028ad9536e501986f4e19d27f462f81a9ea70bad

The change is difficult to read, use 'git show -w' to ignore space
changes, that might help.


Thanks a lot for your work!


The idea is that the dwc3-generic.c (or dwc3-uniphier.c , placement does
not really matter) binds to "socionext,uniphier-pxs3-dwc3-glue"
compatible first.

Then, the dwc3_glue_ops is extended with a new callback
glue_get_ctrl_dev, which returns the pointer to controller DT node (the
node compatible with "socionext,uniphier-dwc3"). This is used in
dwc3_glue_bind(), which either uses the current implementation with a
loop over all subnodes and tries to find the controller subnode, OR,
calls the glue_get_ctrl_dev callback, obtains controller device node
pointer that way, and runs the inner loop of dwc3_glue_bind() (now
dwc3_glue_bind_common()) only on that pointer.


I understand your patch adds trying to call "glue_get_ctrl_dev" to get
controller device node before finding subnode,


In either case, the dwc3-generic driver is bound to the controller. You
might need to re-use this trick in dwc3_glue_probe() too.

This should allow you to get rid of the custom DT node too.

Does this work ?


I'll try this soon.

Thank you,

---
Best Regards
Kunihiko Hayashi


Re: [PATCH 3/5] usb: dwc3-generic: Add dependency on SIMPLE_BUS

2023-01-23 Thread Kunihiko Hayashi

Hi Marek,

On 2023/01/24 0:49, Marek Vasut wrote:

On 1/23/23 06:01, Kunihiko Hayashi wrote:

Hi Marek,


Hello Hayashi-san,

[...]


On the other hand, the PXS2 controller for example is not a bus:

arch/arm/dts/uniphier-pxs2.dtsi:
596 _usb0: usb@65a0 {
597 compatible = "socionext,uniphier-dwc3", "snps,dwc3";
598 status = "disabled";
599 reg = <0x65a0 0xcd00>;
...
610 };


I understand. However, this node isn't used in u-boot.
(see below for details)


Is this needed for socionext dwc3 variant to handle the simple-mfd in
e.g. arch/arm/dts/uniphier-pxs3.dtsi :

614 usb-glue@65b0 {
615 compatible = "socionext,uniphier-pxs3-dwc3-glue",
616  "simple-mfd";

?


In case of U-Boot, the glue driver is probed by:

   /* FIXME: U-Boot own node */
   usb@65b0 {
   compatible = "socionext,uniphier-pxs3-dwc3";

And dwc3-uniphier is also declared as UCLASS_SIMPLE_BUS.
Even if using "simple-mfd", this is included in
drivers/core/simple-bus.c
which is declared as UCLASS_SIMPLE_BUS.


If I understand this correctly, node compatible with
"socionext,uniphier-pxs3-dwc3-glue" is not used at all , right ?


Yes.
Original uniphier devicetree has the following usb nodes.

  usb@65a0 {
  compatible = "snps,dwc3";
  };
  usb-glue@65b0 {
  compatible = "socionext,uniphier-pxs3-dwc3-glue", "simple-mfd";
  };

However, U-Boot dwc3-generic needs to put dwc3 node under the glue node.


Have a look at arch/arm/dts/imx8mq.dtsi which does not use any glue
node, the snps,dwc3 compatible node is directly placed on the soc@0 bus:

1417
1418 usb_dwc3_0: usb@3810 {
1419 compatible = "fsl,imx8mq-dwc3", "snps,dwc3";
1420 reg = <0x3810 0x1>;
1421 clocks = < IMX8MQ_CLK_USB1_CTRL_ROOT>,


Due to this restriction, there is another usb node dedicated to u-boot.

  /* FIXME: U-Boot own node */
  usb@65b0 { /* glue */
  compatible = "socionext,uniphier-pxs3-dwc3";

  dwc3@65a0 {
  compatible = "snps,dwc3";
  };
  };

So instead of "socionext,uniphier-pxs3-dwc3-glue", the glue driver
uses "socionext,uniphier-pxs3-dwc3" in U-Boot.


Can we use the same method as imx8mq.dtsi uses, to avoid this special
node workaround ?


Umm, it's curious. It seems imx8mq doesn't have any glue registers and defines
dwc3 core registers directly.

On the other hand, "fsl,imx8mq-dwc3" is included in dwc3-generic.c, though,
dwc3_glue_bind() calls the driver that the child node shows.

ofnode_for_each_subnode(node, dev_ofnode(parent)) {
...
device_bind_driver_to_node(parent, driver, name,
   node, );
...
}

Maybe the child node expects the driver that "snps,dwc3" indicates.

If we use the same method as imx8mq.dtsi, I think there is no way to probe
the driver for "snps,dwc3" in dwc3-generic.c.

BTW, xchi-dwc3.c can handle "snps,dwc3", but it seems this doesn't use
usb/dwc3/ functions (so I'm confusing it).


The generic driver binds to node compatible with
"socionext,uniphier-dwc3" , right ?


No, the generic driver binds "socionext,uniphier-pxs3-dwc3".


That means, there is nothing which would be a bus, and so the
dwc3-uniphier.c can be switched from UCLASS_SIMPLE_BUS to UCLASS_NOP ,
is that correct ?


There is still the issue of different usb node between Original and
u-boot,
however, the glue driver can be switched to UCLASS_NOP.


Understood, thank you for the clarification.


Thank you,

---
Best Regards
Kunihiko Hayashi


Re: [PATCH 3/5] usb: dwc3-generic: Add dependency on SIMPLE_BUS

2023-01-22 Thread Kunihiko Hayashi

Hi Marek,

On 2023/01/23 12:37, Marek Vasut wrote:

On 1/23/23 04:08, Kunihiko Hayashi wrote:

Hello Hayashi-san,


diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index f010291d02..dadaa083e7 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -25,14 +25,14 @@ config USB_DWC3_OMAP
config USB_DWC3_GENERIC
bool "Generic implementation of a DWC3 wrapper (aka dwc3 glue)"
-depends on DM_USB && USB_DWC3 && MISC
+depends on DM_USB && USB_DWC3 && (MISC || SIMPLE_BUS)


I'm afraid I don't understand why this change is needed for all variants
of DWC3.


Although dwc3-generic is declared as UCLASS_NOP, the similar glue driver
dwc3-meson-glx is declared as UCLASS_SIMPLE_BUS.


I think here it makes sense, because "amlogic,meson-axg-usb-ctrl"
behaves like a bus with subnodes:

arch/arm/dts/meson-axg.dtsi:
   227 usb: usb@ffe09080 {
   228 compatible = "amlogic,meson-axg-usb-ctrl";
   229 reg = <0x0 0xffe09080 0x0 0x20>;
...
   244 dwc2: usb@ff40 {
   245 compatible = "amlogic,meson-g12a-usb", "snps,dwc2";
   246 reg = <0x0 0xff40 0x0 0x4>;
...
   255 };
   256
   257 dwc3: usb@ff50 {
   258 compatible = "snps,dwc3";
   259 reg = <0x0 0xff50 0x0 0x10>;
...
   264 };
   265 };

arch/arm/dts/meson-gxl.dtsi
   17 usb: usb@d0078080 {
   18 compatible = "amlogic,meson-gxl-usb-ctrl";
   19 reg = <0x0 0xd0078080 0x0 0x20>;
...
   34 dwc2: usb@c910 {
   35 compatible = "amlogic,meson-g12a-usb", "snps,dwc2";
   36 reg = <0x0 0xc910 0x0 0x4>;
...
   45 };
   46
   47 dwc3: usb@c900 {
   48 compatible = "snps,dwc3";
   49 reg = <0x0 0xc900 0x0 0x10>;
...
   54 };
   55 };

On the other hand, the PXS2 controller for example is not a bus:

arch/arm/dts/uniphier-pxs2.dtsi:
596 _usb0: usb@65a0 {
597 compatible = "socionext,uniphier-dwc3", "snps,dwc3";
598 status = "disabled";
599 reg = <0x65a0 0xcd00>;
...
610 };


I understand. However, this node isn't used in u-boot.
(see below for details)


Is this needed for socionext dwc3 variant to handle the simple-mfd in
e.g. arch/arm/dts/uniphier-pxs3.dtsi :

614 usb-glue@65b0 {
615 compatible = "socionext,uniphier-pxs3-dwc3-glue",
616  "simple-mfd";

?


In case of U-Boot, the glue driver is probed by:

  /* FIXME: U-Boot own node */
  usb@65b0 {
  compatible = "socionext,uniphier-pxs3-dwc3";

And dwc3-uniphier is also declared as UCLASS_SIMPLE_BUS.
Even if using "simple-mfd", this is included in drivers/core/simple-bus.c
which is declared as UCLASS_SIMPLE_BUS.


If I understand this correctly, node compatible with
"socionext,uniphier-pxs3-dwc3-glue" is not used at all , right ?


Yes.
Original uniphier devicetree has the following usb nodes.

usb@65a0 {
compatible = "snps,dwc3";
};
usb-glue@65b0 {
compatible = "socionext,uniphier-pxs3-dwc3-glue", "simple-mfd";
};

However, U-Boot dwc3-generic needs to put dwc3 node under the glue node.
Due to this restriction, there is another usb node dedicated to u-boot.

/* FIXME: U-Boot own node */
usb@65b0 { /* glue */
compatible = "socionext,uniphier-pxs3-dwc3";

dwc3@65a0 {
compatible = "snps,dwc3";
};
};

So instead of "socionext,uniphier-pxs3-dwc3-glue", the glue driver
uses "socionext,uniphier-pxs3-dwc3" in U-Boot.


The generic driver binds to node compatible with
"socionext,uniphier-dwc3" , right ?


No, the generic driver binds "socionext,uniphier-pxs3-dwc3".


That means, there is nothing which would be a bus, and so the
dwc3-uniphier.c can be switched from UCLASS_SIMPLE_BUS to UCLASS_NOP ,
is that correct ?


There is still the issue of different usb node between Original and u-boot,
however, the glue driver can be switched to UCLASS_NOP.

Thank you,

---
Best Regards
Kunihiko Hayashi


Re: [PATCH 3/5] usb: dwc3-generic: Add dependency on SIMPLE_BUS

2023-01-22 Thread Kunihiko Hayashi

Hi Marek,

Thank you for reviewing.

On 2023/01/23 10:42, Marek Vasut wrote:

On 1/23/23 01:47, Kunihiko Hayashi wrote:

The glue driver doesn't do or offer actively anything, SIMPLE_BUS is
more preferable to represent the driver.

Signed-off-by: Kunihiko Hayashi 
---
   drivers/usb/dwc3/Kconfig | 4 ++--
   1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index f010291d02..dadaa083e7 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -25,14 +25,14 @@ config USB_DWC3_OMAP
   
   config USB_DWC3_GENERIC

bool "Generic implementation of a DWC3 wrapper (aka dwc3 glue)"
-   depends on DM_USB && USB_DWC3 && MISC
+   depends on DM_USB && USB_DWC3 && (MISC || SIMPLE_BUS)


I'm afraid I don't understand why this change is needed for all variants
of DWC3.


Although dwc3-generic is declared as UCLASS_NOP, the similar glue driver
dwc3-meson-glx is declared as UCLASS_SIMPLE_BUS.


Is this needed for socionext dwc3 variant to handle the simple-mfd in
e.g. arch/arm/dts/uniphier-pxs3.dtsi :

614 usb-glue@65b0 {
615 compatible = "socionext,uniphier-pxs3-dwc3-glue",
616  "simple-mfd";

?


In case of U-Boot, the glue driver is probed by:

/* FIXME: U-Boot own node */
usb@65b0 {
compatible = "socionext,uniphier-pxs3-dwc3";

And dwc3-uniphier is also declared as UCLASS_SIMPLE_BUS.
Even if using "simple-mfd", this is included in drivers/core/simple-bus.c
which is declared as UCLASS_SIMPLE_BUS.

Thank you,

---
Best Regards
Kunihiko Hayashi


[PATCH 4/5] usb: dwc3-uniphier: Use dwc3-generic instead of xhci-dwc3

2023-01-22 Thread Kunihiko Hayashi
dwc3-uniphier depends on xhci-dwc3 framework, however, it is preferable
to use dwc3-generic.

This driver calls the exported dwc3-generic functions and redefine
the SoC-dependent operations to fit dwc3-generic.

Signed-off-by: Kunihiko Hayashi 
---
 drivers/usb/dwc3/Kconfig |  3 +-
 drivers/usb/dwc3/dwc3-uniphier.c | 79 
 2 files changed, 42 insertions(+), 40 deletions(-)

diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index dadaa083e7..dbd14b1e90 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -55,7 +55,8 @@ config USB_DWC3_MESON_GXL
 
 config USB_DWC3_UNIPHIER
bool "DesignWare USB3 Host Support on UniPhier Platforms"
-   depends on ARCH_UNIPHIER && USB_XHCI_DWC3
+   depends on ARCH_UNIPHIER && USB_DWC3
+   select USB_DWC3_GENERIC
help
  Support of USB2/3 functionality in Socionext UniPhier platforms.
  Say 'Y' here if you have one such device.
diff --git a/drivers/usb/dwc3/dwc3-uniphier.c b/drivers/usb/dwc3/dwc3-uniphier.c
index 54b52dcd66..175a97c5e4 100644
--- a/drivers/usb/dwc3/dwc3-uniphier.c
+++ b/drivers/usb/dwc3/dwc3-uniphier.c
@@ -4,14 +4,16 @@
  *
  * Copyright (C) 2016-2017 Socionext Inc.
  *   Author: Masahiro Yamada 
+ *   Author: Kunihiko Hayashi 
  */
 
 #include 
-#include 
 #include 
-#include 
-#include 
-#include 
+#include 
+
+#include "core.h"
+#include "gadget.h"
+#include "dwc3-generic.h"
 
 #define UNIPHIER_PRO4_DWC3_RESET   0x40
 #define   UNIPHIER_PRO4_DWC3_RESET_XIOMMU  BIT(5)
@@ -27,8 +29,11 @@
 #define UNIPHIER_PXS2_DWC3_RESET   0x00
 #define   UNIPHIER_PXS2_DWC3_RESET_XLINK   BIT(15)
 
-static int uniphier_pro4_dwc3_init(void __iomem *regs)
+static void uniphier_pro4_dwc3_init(struct udevice *dev, int index,
+   enum usb_dr_mode mode)
 {
+   struct dwc3_glue_data *glue = dev_get_plat(dev);
+   void *regs = map_physmem(glue->regs, glue->size, MAP_NOCACHE);
u32 tmp;
 
tmp = readl(regs + UNIPHIER_PRO4_DWC3_RESET);
@@ -36,11 +41,14 @@ static int uniphier_pro4_dwc3_init(void __iomem *regs)
tmp |= UNIPHIER_PRO4_DWC3_RESET_XIOMMU | UNIPHIER_PRO4_DWC3_RESET_XLINK;
writel(tmp, regs + UNIPHIER_PRO4_DWC3_RESET);
 
-   return 0;
+   unmap_physmem(regs, MAP_NOCACHE);
 }
 
-static int uniphier_pro5_dwc3_init(void __iomem *regs)
+static void uniphier_pro5_dwc3_init(struct udevice *dev, int index,
+   enum usb_dr_mode mode)
 {
+   struct dwc3_glue_data *glue = dev_get_plat(dev);
+   void *regs = map_physmem(glue->regs, glue->size, MAP_NOCACHE);
u32 tmp;
 
tmp = readl(regs + UNIPHIER_PRO5_DWC3_RESET);
@@ -49,72 +57,65 @@ static int uniphier_pro5_dwc3_init(void __iomem *regs)
tmp |= UNIPHIER_PRO5_DWC3_RESET_XLINK | UNIPHIER_PRO5_DWC3_RESET_XIOMMU;
writel(tmp, regs + UNIPHIER_PRO5_DWC3_RESET);
 
-   return 0;
+   unmap_physmem(regs, MAP_NOCACHE);
 }
 
-static int uniphier_pxs2_dwc3_init(void __iomem *regs)
+static void uniphier_pxs2_dwc3_init(struct udevice *dev, int index,
+   enum usb_dr_mode mode)
 {
+   struct dwc3_glue_data *glue = dev_get_plat(dev);
+   void *regs = map_physmem(glue->regs, glue->size, MAP_NOCACHE);
u32 tmp;
 
tmp = readl(regs + UNIPHIER_PXS2_DWC3_RESET);
tmp |= UNIPHIER_PXS2_DWC3_RESET_XLINK;
writel(tmp, regs + UNIPHIER_PXS2_DWC3_RESET);
 
-   return 0;
+   unmap_physmem(regs, MAP_NOCACHE);
 }
 
-static int uniphier_dwc3_probe(struct udevice *dev)
-{
-   fdt_addr_t base;
-   void __iomem *regs;
-   int (*init)(void __iomem *regs);
-   int ret;
-
-   base = dev_read_addr(dev);
-   if (base == FDT_ADDR_T_NONE)
-   return -EINVAL;
-
-   regs = ioremap(base, SZ_32K);
-   if (!regs)
-   return -ENOMEM;
-
-   init = (typeof(init))dev_get_driver_data(dev);
-   ret = init(regs);
-   if (ret)
-   dev_err(dev, "failed to init glue layer\n");
+struct dwc3_glue_ops uniphier_pro4_dwc3_ops = {
+   .glue_configure = uniphier_pro4_dwc3_init,
+};
 
-   iounmap(regs);
+struct dwc3_glue_ops uniphier_pro5_dwc3_ops = {
+   .glue_configure = uniphier_pro5_dwc3_init,
+};
 
-   return ret;
-}
+struct dwc3_glue_ops uniphier_pxs2_dwc3_ops = {
+   .glue_configure = uniphier_pxs2_dwc3_init,
+};
 
 static const struct udevice_id uniphier_dwc3_match[] = {
{
.compatible = "socionext,uniphier-pro4-dwc3",
-   .data = (ulong)uniphier_pro4_dwc3_init,
+   .data = (ulong)_pro4_dwc3_ops,
},
{
.compatible = "socionext,uniphier-pro5-dwc3",
-   .data = (ulong)uniphier_pro5_dwc3_init,
+   .data = (ulong)_pro5_dwc3_ops,
}

[PATCH 5/5] uniphier_defconfig: Disable USB_XHCI_DWC3

2023-01-22 Thread Kunihiko Hayashi
Replacing with dwc3-generic, no need USB_XHCI_DWC3 anymore.

Signed-off-by: Kunihiko Hayashi 
---
 configs/uniphier_v7_defconfig | 1 -
 configs/uniphier_v8_defconfig | 1 -
 2 files changed, 2 deletions(-)

diff --git a/configs/uniphier_v7_defconfig b/configs/uniphier_v7_defconfig
index d626968c76..03feb04b93 100644
--- a/configs/uniphier_v7_defconfig
+++ b/configs/uniphier_v7_defconfig
@@ -82,7 +82,6 @@ CONFIG_DM_SPI=y
 CONFIG_UNIPHIER_SPI=y
 CONFIG_USB=y
 CONFIG_USB_XHCI_HCD=y
-CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_GENERIC=y
 CONFIG_USB_DWC3=y
diff --git a/configs/uniphier_v8_defconfig b/configs/uniphier_v8_defconfig
index 6a0e2666cf..ed58b5746e 100644
--- a/configs/uniphier_v8_defconfig
+++ b/configs/uniphier_v8_defconfig
@@ -71,7 +71,6 @@ CONFIG_SYSRESET=y
 CONFIG_SYSRESET_PSCI=y
 CONFIG_USB=y
 CONFIG_USB_XHCI_HCD=y
-CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_GENERIC=y
 CONFIG_USB_DWC3=y
-- 
2.25.1



[PATCH 2/5] usb: dwc3-generic: Add the size of regs property to glue structure

2023-01-22 Thread Kunihiko Hayashi
Add the size of regs property to the glue structure to correctly
specify the register region to map.

Signed-off-by: Kunihiko Hayashi 
---
 drivers/usb/dwc3/dwc3-generic.c | 2 +-
 drivers/usb/dwc3/dwc3-generic.h | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
index 1708ea14bb..7ad26c454d 100644
--- a/drivers/usb/dwc3/dwc3-generic.c
+++ b/drivers/usb/dwc3/dwc3-generic.c
@@ -505,7 +505,7 @@ int dwc3_glue_probe(struct udevice *dev)
phy.dev = NULL;
}
 
-   glue->regs = dev_read_addr(dev);
+   glue->regs = dev_read_addr_size_index(dev, 0, >size);
 
ret = dwc3_glue_clk_init(dev, glue);
if (ret)
diff --git a/drivers/usb/dwc3/dwc3-generic.h b/drivers/usb/dwc3/dwc3-generic.h
index c7925ce4ae..f1823a01f4 100644
--- a/drivers/usb/dwc3/dwc3-generic.h
+++ b/drivers/usb/dwc3/dwc3-generic.h
@@ -17,6 +17,7 @@ struct dwc3_glue_data {
struct clk_bulk clks;
struct reset_ctl_bulk   resets;
fdt_addr_t regs;
+   fdt_size_t size;
 };
 
 struct dwc3_glue_ops {
-- 
2.25.1



[PATCH 1/5] usb: dwc3-generic: Export glue structures and functions

2023-01-22 Thread Kunihiko Hayashi
In order to allow external SoC-dependent glue drivers to use dwc3-generic
functions, push the glue structures and export the functions to a header
file.

The exported structures and functions are:

- struct dwc3_glue_data
- struct dwc3_glue_ops
- dwc3_glue_bind()
- dwc3_glue_probe()
- dwc3_glue_remove()

The SoC-dependent glue drivers can only define their own wrapper driver
and specify these functions. The drivers can also add their own compatible
strings and configure functions.

Signed-off-by: Kunihiko Hayashi 
---
 drivers/usb/dwc3/dwc3-generic.c | 17 -
 drivers/usb/dwc3/dwc3-generic.h | 31 +++
 2 files changed, 35 insertions(+), 13 deletions(-)
 create mode 100644 drivers/usb/dwc3/dwc3-generic.h

diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
index 78966718d0..1708ea14bb 100644
--- a/drivers/usb/dwc3/dwc3-generic.c
+++ b/drivers/usb/dwc3/dwc3-generic.c
@@ -28,11 +28,7 @@
 #include 
 #include 
 
-struct dwc3_glue_data {
-   struct clk_bulk clks;
-   struct reset_ctl_bulk   resets;
-   fdt_addr_t regs;
-};
+#include "dwc3-generic.h"
 
 struct dwc3_generic_plat {
fdt_addr_t base;
@@ -258,11 +254,6 @@ U_BOOT_DRIVER(dwc3_generic_host) = {
 };
 #endif
 
-struct dwc3_glue_ops {
-   void (*glue_configure)(struct udevice *dev, int index,
-  enum usb_dr_mode mode);
-};
-
 void dwc3_imx8mp_glue_configure(struct udevice *dev, int index,
enum usb_dr_mode mode)
 {
@@ -398,7 +389,7 @@ struct dwc3_glue_ops ti_ops = {
.glue_configure = dwc3_ti_glue_configure,
 };
 
-static int dwc3_glue_bind(struct udevice *parent)
+int dwc3_glue_bind(struct udevice *parent)
 {
ofnode node;
int ret;
@@ -493,7 +484,7 @@ static int dwc3_glue_clk_init(struct udevice *dev,
return 0;
 }
 
-static int dwc3_glue_probe(struct udevice *dev)
+int dwc3_glue_probe(struct udevice *dev)
 {
struct dwc3_glue_ops *ops = (struct dwc3_glue_ops 
*)dev_get_driver_data(dev);
struct dwc3_glue_data *glue = dev_get_plat(dev);
@@ -553,7 +544,7 @@ static int dwc3_glue_probe(struct udevice *dev)
return 0;
 }
 
-static int dwc3_glue_remove(struct udevice *dev)
+int dwc3_glue_remove(struct udevice *dev)
 {
struct dwc3_glue_data *glue = dev_get_plat(dev);
 
diff --git a/drivers/usb/dwc3/dwc3-generic.h b/drivers/usb/dwc3/dwc3-generic.h
new file mode 100644
index 00..c7925ce4ae
--- /dev/null
+++ b/drivers/usb/dwc3/dwc3-generic.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/**
+ * dwc3-generic.h - Generic DWC3 Glue layer header
+ *
+ * Copyright (C) 2016 - 2018 Xilinx, Inc.
+ * Copyright (C) 2023 Socionext Inc.
+ */
+
+#ifndef __DRIVERS_USB_DWC3_GENERIC_H
+#define __DRIVERS_USB_DWC3_GENERIC_H
+
+#include 
+#include 
+#include 
+
+struct dwc3_glue_data {
+   struct clk_bulk clks;
+   struct reset_ctl_bulk   resets;
+   fdt_addr_t regs;
+};
+
+struct dwc3_glue_ops {
+   void (*glue_configure)(struct udevice *dev, int index,
+  enum usb_dr_mode mode);
+};
+
+int dwc3_glue_bind(struct udevice *parent);
+int dwc3_glue_probe(struct udevice *dev);
+int dwc3_glue_remove(struct udevice *dev);
+
+#endif
-- 
2.25.1



[PATCH 3/5] usb: dwc3-generic: Add dependency on SIMPLE_BUS

2023-01-22 Thread Kunihiko Hayashi
The glue driver doesn't do or offer actively anything, SIMPLE_BUS is
more preferable to represent the driver.

Signed-off-by: Kunihiko Hayashi 
---
 drivers/usb/dwc3/Kconfig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index f010291d02..dadaa083e7 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -25,14 +25,14 @@ config USB_DWC3_OMAP
 
 config USB_DWC3_GENERIC
bool "Generic implementation of a DWC3 wrapper (aka dwc3 glue)"
-   depends on DM_USB && USB_DWC3 && MISC
+   depends on DM_USB && USB_DWC3 && (MISC || SIMPLE_BUS)
help
  Select this for Xilinx ZynqMP and similar Platforms.
  This wrapper supports Host and Peripheral operation modes.
 
 config SPL_USB_DWC3_GENERIC
bool "Generic implementation of a DWC3 wrapper (aka dwc3 glue) for the 
SPL"
-   depends on SPL_DM_USB && USB_DWC3 && SPL_MISC
+   depends on SPL_DM_USB && USB_DWC3 && (SPL_MISC || SPL_SIMPLE_BUS)
help
  Select this for Xilinx ZynqMP and similar Platforms.
  This wrapper supports Host and Peripheral operation modes.
-- 
2.25.1



[PATCH 0/5] usb: dwc3-uniphier: Replace the driver to use dwc3-generic

2023-01-22 Thread Kunihiko Hayashi
This series exports the structures and functions from the driver source
to the header, and replaces dwc3-uniphier driver to use them.

This expects dwc3-generic to prevent more SoC-dependent codes.

Kunihiko Hayashi (5):
  usb: dwc3-generic: Export glue structures and functions
  usb: dwc3-generic: Add the size of regs property to glue structure
  usb: dwc3-generic: Add dependency on SIMPLE_BUS
  usb: dwc3-uniphier: Use dwc3-generic instead of xhci-dwc3
  uniphier_defconfig: Disable USB_XHCI_DWC3

 configs/uniphier_v7_defconfig|  1 -
 configs/uniphier_v8_defconfig|  1 -
 drivers/usb/dwc3/Kconfig |  7 +--
 drivers/usb/dwc3/dwc3-generic.c  | 19 ++--
 drivers/usb/dwc3/dwc3-generic.h  | 32 +
 drivers/usb/dwc3/dwc3-uniphier.c | 79 
 6 files changed, 81 insertions(+), 58 deletions(-)
 create mode 100644 drivers/usb/dwc3/dwc3-generic.h

-- 
2.25.1



Re: [PATCH] i2c: uniphier-f: correct error recovery

2022-12-25 Thread Kunihiko Hayashi

On 2022/12/09 20:38, Dai Okamura wrote:

The uniphier i2c block can recognize some handshake errors.
But driver handles all error detections as no error if no timeout.
So this makes unrecoverable state.

This replaces the return values with the right ones to tell the i2c
framework the errors:
- EDEADLK for arbitration lost error
- ENODATA for no answer error

Signed-off-by: Dai Okamura 
---
  drivers/i2c/i2c-uniphier-f.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/i2c-uniphier-f.c b/drivers/i2c/i2c-uniphier-f.c
index 9d6f1688cb..3dcd382469 100644
--- a/drivers/i2c/i2c-uniphier-f.c
+++ b/drivers/i2c/i2c-uniphier-f.c
@@ -130,12 +130,12 @@ static int wait_for_irq(struct uniphier_fi2c_priv
*priv, u32 flags,
if (irq & I2C_INT_AL) {
dev_dbg(priv->dev, "error: arbitration lost\n");
*stop = false;
-   return ret;
+   return -EDEADLK;
}
  
  	if (irq & I2C_INT_NA) {

dev_dbg(priv->dev, "error: no answer\n");
-   return ret;
+   return -ENODATA;
}
  
  	return 0;


I understand this "ret" comes from readl_poll_timeout() and is zero,
so the error can't be detected. It should be fixed.

Fixes: 238bd0b8ce52 ("i2c: UniPhier: add driver for UniPhier FIFO-builtin i2c 
controller")

and,

Acked-by: Kunihiko Hayashi 

Thank you,

---
Best Regards
Kunihiko Hayashi


[PATCH] spi: Add Socionext F_OSPI SPI flash controller driver

2022-11-28 Thread Kunihiko Hayashi
Introduce Socionext F_OSPI controller driver. This controller is used to
communicate with slave devices such as SPI flash memories. It supports
4 slave devices and up to 8-bit wide bus, but supports master mode only.

This driver uses spi-mem framework for SPI flash memory access, and
can only operate indirect access mode and single data rate mode.

Signed-off-by: Kunihiko Hayashi 
---
 drivers/spi/Kconfig |   8 +
 drivers/spi/Makefile|   1 +
 drivers/spi/spi-sn-f-ospi.c | 686 
 3 files changed, 695 insertions(+)
 create mode 100644 drivers/spi/spi-sn-f-ospi.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index c6900f449d5f..ff68ffbc0e06 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -451,6 +451,14 @@ config SOFT_SPI
 Enable Soft SPI driver. This driver is to use GPIO simulate
 the SPI protocol.
 
+config SPI_SN_F_OSPI
+   tristate "Socionext F_OSPI SPI flash controller"
+   depends on SPI_MEM
+   help
+ This enables support for the Socionext F_OSPI controller
+ for connecting an SPI flash memory over up to 8-bit wide bus.
+ It supports indirect access mode only.
+
 config SPI_SUNXI
bool "Allwinner SoC SPI controllers"
default ARCH_SUNXI
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 674d81caae3b..95dba9ac4559 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -67,6 +67,7 @@ obj-$(CONFIG_ROCKCHIP_SFC) += rockchip_sfc.o
 obj-$(CONFIG_ROCKCHIP_SPI) += rk_spi.o
 obj-$(CONFIG_SANDBOX_SPI) += sandbox_spi.o
 obj-$(CONFIG_SPI_SIFIVE) += spi-sifive.o
+obj-$(CONFIG_SPI_SN_F_OSPI) += spi-sn-f-ospi.o
 obj-$(CONFIG_SPI_SUNXI) += spi-sunxi.o
 obj-$(CONFIG_SH_QSPI) += sh_qspi.o
 obj-$(CONFIG_STM32_QSPI) += stm32_qspi.o
diff --git a/drivers/spi/spi-sn-f-ospi.c b/drivers/spi/spi-sn-f-ospi.c
new file mode 100644
index ..ebf2903d3ea7
--- /dev/null
+++ b/drivers/spi/spi-sn-f-ospi.c
@@ -0,0 +1,686 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Socionext SPI flash controller F_OSPI driver
+ * Copyright (C) 2021 Socionext Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Registers */
+#define OSPI_PROT_CTL_INDIR0x00
+#define   OSPI_PROT_MODE_DATA_MASK GENMASK(31, 30)
+#define   OSPI_PROT_MODE_ALT_MASK  GENMASK(29, 28)
+#define   OSPI_PROT_MODE_ADDR_MASK GENMASK(27, 26)
+#define   OSPI_PROT_MODE_CODE_MASK GENMASK(25, 24)
+#define OSPI_PROT_MODE_SINGLE  0
+#define OSPI_PROT_MODE_DUAL1
+#define OSPI_PROT_MODE_QUAD2
+#define OSPI_PROT_MODE_OCTAL   3
+#define   OSPI_PROT_DATA_RATE_DATA BIT(23)
+#define   OSPI_PROT_DATA_RATE_ALT  BIT(22)
+#define   OSPI_PROT_DATA_RATE_ADDR BIT(21)
+#define   OSPI_PROT_DATA_RATE_CODE BIT(20)
+#define OSPI_PROT_SDR  0
+#define OSPI_PROT_DDR  1
+#define   OSPI_PROT_BIT_POS_DATA   BIT(19)
+#define   OSPI_PROT_BIT_POS_ALTBIT(18)
+#define   OSPI_PROT_BIT_POS_ADDR   BIT(17)
+#define   OSPI_PROT_BIT_POS_CODE   BIT(16)
+#define   OSPI_PROT_SAMP_EDGE  BIT(12)
+#define   OSPI_PROT_DATA_UNIT_MASK GENMASK(11, 10)
+#define OSPI_PROT_DATA_UNIT_1B 0
+#define OSPI_PROT_DATA_UNIT_2B 1
+#define OSPI_PROT_DATA_UNIT_4B 3
+#define   OSPI_PROT_TRANS_DIR_WRITEBIT(9)
+#define   OSPI_PROT_DATA_ENBIT(8)
+#define   OSPI_PROT_ALT_SIZE_MASK  GENMASK(7, 5)
+#define   OSPI_PROT_ADDR_SIZE_MASK GENMASK(4, 2)
+#define   OSPI_PROT_CODE_SIZE_MASK GENMASK(1, 0)
+
+#define OSPI_CLK_CTL   0x10
+#define   OSPI_CLK_CTL_BOOT_INT_CLK_EN BIT(16)
+#define   OSPI_CLK_CTL_PHA BIT(12)
+#define OSPI_CLK_CTL_PHA_180   0
+#define OSPI_CLK_CTL_PHA_901
+#define   OSPI_CLK_CTL_DIV GENMASK(9, 8)
+#define OSPI_CLK_CTL_DIV_1 0
+#define OSPI_CLK_CTL_DIV_2 1
+#define OSPI_CLK_CTL_DIV_4 2
+#define OSPI_CLK_CTL_DIV_8 3
+#define   OSPI_CLK_CTL_INT_CLK_EN  BIT(0)
+
+#define OSPI_CS_CTL1   0x14
+#define OSPI_CS_CTL2   0x18
+#define OSPI_SSEL  0x20
+#define OSPI_CMD_IDX_INDIR 0x40
+#define OSPI_ADDR  0x50
+#define OSPI_ALT_INDIR 0x60
+#define OSPI_DMY_INDIR 0x70
+#define OSPI_DAT   0x80
+#define OSPI_DAT_SWP_INDIR

[PATCH v2 1/2] mmc: sdhci: Add new quirks for SUPPORT_SINGLE

2022-09-09 Thread Kunihiko Hayashi
This patch defines a quirk to disable the block count
for single block transactions.

This is similar to Linux kernel commit d3fc5d71ac4d
("mmc: sdhci: add a quirk for single block transactions").

Signed-off-by: Kunihiko Hayashi 
Reviewed-by: Jaehoon Chung 
---
 drivers/mmc/sdhci.c | 8 +---
 include/sdhci.h | 1 +
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index bf989a594f7e..a80ad8329a38 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -211,7 +211,7 @@ static int sdhci_send_command(struct mmc *mmc, struct 
mmc_cmd *cmd,
unsigned int stat = 0;
int ret = 0;
int trans_bytes = 0, is_aligned = 1;
-   u32 mask, flags, mode;
+   u32 mask, flags, mode = 0;
unsigned int time = 0;
int mmc_dev = mmc_get_blk_desc(mmc)->devnum;
ulong start = get_timer(0);
@@ -273,10 +273,12 @@ static int sdhci_send_command(struct mmc *mmc, struct 
mmc_cmd *cmd,
/* Set Transfer mode regarding to data flag */
if (data) {
sdhci_writeb(host, 0xe, SDHCI_TIMEOUT_CONTROL);
-   mode = SDHCI_TRNS_BLK_CNT_EN;
+
+   if (!(host->quirks & SDHCI_QUIRK_SUPPORT_SINGLE))
+   mode = SDHCI_TRNS_BLK_CNT_EN;
trans_bytes = data->blocks * data->blocksize;
if (data->blocks > 1)
-   mode |= SDHCI_TRNS_MULTI;
+   mode |= SDHCI_TRNS_MULTI | SDHCI_TRNS_BLK_CNT_EN;
 
if (data->flags == MMC_DATA_READ)
mode |= SDHCI_TRNS_READ;
diff --git a/include/sdhci.h b/include/sdhci.h
index 88f1917480b6..24b4599b857d 100644
--- a/include/sdhci.h
+++ b/include/sdhci.h
@@ -247,6 +247,7 @@
 #define SDHCI_QUIRK_WAIT_SEND_CMD  (1 << 6)
 #define SDHCI_QUIRK_USE_WIDE8  (1 << 8)
 #define SDHCI_QUIRK_NO_1_8_V   (1 << 9)
+#define SDHCI_QUIRK_SUPPORT_SINGLE (1 << 10)
 
 /* to make gcc happy */
 struct sdhci_host;
-- 
2.17.1



[PATCH v2 2/2] mmc: f_sdh30: Add support for F_SDH30_E51

2022-09-09 Thread Kunihiko Hayashi
Add Socionext F_SDH30_E51 IP support. The features of this IP includes
CMD/DAT line delay and force card insertion mode for non-removable cards.
And the IP needs to add some quirks.

Signed-off-by: Kunihiko Hayashi 
---
 drivers/mmc/Kconfig   |  4 +--
 drivers/mmc/f_sdh30.c | 66 +--
 2 files changed, 66 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 0dcec8adcee8..c30f20cba5f2 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -577,12 +577,12 @@ config MMC_SDHCI_IPROC
  If unsure, say N.
 
 config MMC_SDHCI_F_SDH30
-   bool "SDHCI support for Fujitsu Semiconductor F_SDH30"
+   bool "SDHCI support for Fujitsu Semiconductor/Socionext F_SDH30"
depends on BLK && DM_MMC
depends on MMC_SDHCI
help
  This selects the Secure Digital Host Controller Interface (SDHCI)
- Needed by some Fujitsu SoC for MMC / SD / SDIO support.
+ Needed by some Fujitsu/Socionext SoC for MMC / SD / SDIO support.
  If you have a controller with this interface, say Y or M here.
  If unsure, say N.
 
diff --git a/drivers/mmc/f_sdh30.c b/drivers/mmc/f_sdh30.c
index 3a85d9e348ab..3d587a464d50 100644
--- a/drivers/mmc/f_sdh30.c
+++ b/drivers/mmc/f_sdh30.c
@@ -11,13 +11,48 @@
 #include 
 #include 
 
+#define F_SDH30_ESD_CONTROL0x124
+#define F_SDH30_CMD_DAT_DELAY  BIT(9)
+
+#define F_SDH30_TEST   0x158
+#define F_SDH30_FORCE_CARD_INSERT  BIT(6)
+
+struct f_sdh30_data {
+   void (*init)(struct udevice *dev);
+   u32 quirks;
+};
+
 struct f_sdh30_plat {
struct mmc_config cfg;
struct mmc mmc;
+
+   bool enable_cmd_dat_delay;
+   const struct f_sdh30_data *data;
 };
 
 DECLARE_GLOBAL_DATA_PTR;
 
+static void f_sdh30_e51_init(struct udevice *dev)
+{
+   struct f_sdh30_plat *plat = dev_get_plat(dev);
+   struct sdhci_host *host = dev_get_priv(dev);
+   u32 val;
+
+   val = sdhci_readl(host, F_SDH30_ESD_CONTROL);
+   if (plat->enable_cmd_dat_delay)
+   val |= F_SDH30_CMD_DAT_DELAY;
+   else
+   val &= ~F_SDH30_CMD_DAT_DELAY;
+   sdhci_writel(host, val, F_SDH30_ESD_CONTROL);
+
+   val = sdhci_readl(host, F_SDH30_TEST);
+   if (plat->cfg.host_caps & MMC_CAP_NONREMOVABLE)
+   val |= F_SDH30_FORCE_CARD_INSERT;
+   else
+   val &= ~F_SDH30_FORCE_CARD_INSERT;
+   sdhci_writel(host, val, F_SDH30_TEST);
+}
+
 static int f_sdh30_sdhci_probe(struct udevice *dev)
 {
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
@@ -25,6 +60,8 @@ static int f_sdh30_sdhci_probe(struct udevice *dev)
struct sdhci_host *host = dev_get_priv(dev);
int ret;
 
+   plat->data = (const struct f_sdh30_data *)dev_get_driver_data(dev);
+
ret = mmc_of_parse(dev, >cfg);
if (ret)
return ret;
@@ -33,6 +70,9 @@ static int f_sdh30_sdhci_probe(struct udevice *dev)
host->mmc->dev = dev;
host->mmc->priv = host;
 
+   if (plat->data && plat->data->quirks)
+   host->quirks = plat->data->quirks;
+
ret = sdhci_setup_cfg(>cfg, host, 2, 40);
if (ret)
return ret;
@@ -41,18 +81,29 @@ static int f_sdh30_sdhci_probe(struct udevice *dev)
 
mmc_set_clock(host->mmc, host->mmc->cfg->f_min, MMC_CLK_ENABLE);
 
-   return sdhci_probe(dev);
+   ret = sdhci_probe(dev);
+   if (ret)
+   return ret;
+
+   if (plat->data && plat->data->init)
+   plat->data->init(dev);
+
+   return 0;
 }
 
 static int f_sdh30_of_to_plat(struct udevice *dev)
 {
struct sdhci_host *host = dev_get_priv(dev);
+   struct f_sdh30_plat *plat = dev_get_plat(dev);
 
host->name = strdup(dev->name);
host->ioaddr = dev_read_addr_ptr(dev);
host->bus_width = dev_read_u32_default(dev, "bus-width", 4);
host->index = dev_read_u32_default(dev, "index", 0);
 
+   plat->enable_cmd_dat_delay =
+   dev_read_bool(dev, "socionext,enable-cmd-dat-delay");
+
return 0;
 }
 
@@ -63,8 +114,19 @@ static int f_sdh30_bind(struct udevice *dev)
return sdhci_bind(dev, >mmc, >cfg);
 }
 
+static const struct f_sdh30_data f_sdh30_e51_data = {
+   .init = f_sdh30_e51_init,
+   .quirks = SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_SUPPORT_SINGLE,
+};
+
 static const struct udevice_id f_sdh30_mmc_ids[] = {
-   { .compatible = "fujitsu,mb86s70-sdhci-3.0" },
+   {
+   .compatible = "fujitsu,mb86s70-sdhci-3.0",
+   },
+   {
+   .compatible = "socionext,f-sdh30-e51-mmc",
+   .data = (ulong)_sdh30_e51_data,
+   },
{ }
 };
 
-- 
2.17.1



[PATCH v2 0/2] mmc: Add support for F_SDH30_E51

2022-09-09 Thread Kunihiko Hayashi
This series adds a new quirk "SUPPORT_SINGLE" for single transaction to
sdhci framework and Socionext F_SDH30_E51 IP support to f_sdh30 driver.

Changes since v1:
- Fix register settings for false case in f_sdh30_e51_init()
- Remove "|" operator for quirks initialization
- Add Reviewed-by tag

Kunihiko Hayashi (2):
  mmc: sdhci: Add new quirks for SUPPORT_SINGLE
  mmc: f_sdh30: Add support for F_SDH30_E51

 drivers/mmc/Kconfig   |  4 +--
 drivers/mmc/f_sdh30.c | 66 +--
 drivers/mmc/sdhci.c   |  8 --
 include/sdhci.h   |  1 +
 4 files changed, 72 insertions(+), 7 deletions(-)

-- 
2.17.1



Re: [PATCH 2/2] mmc: f_sdh30: Add support for F_SDH30_E51

2022-09-09 Thread Kunihiko Hayashi

Hi Jaehoon,
Thank you for checking.

On 2022/09/08 20:35, Jaehoon Chung wrote:



On 9/6/22 09:39, Kunihiko Hayashi wrote:

Add Socionext F_SDH30_E51 IP support. The features of this IP includes
CMD/DAT line delay and force card insertion mode for non-removable cards.
And the IP needs to add some quirks.

Signed-off-by: Kunihiko Hayashi 
---
  drivers/mmc/Kconfig   |  4 +--
  drivers/mmc/f_sdh30.c | 64 +--
  2 files changed, 64 insertions(+), 4 deletions(-)


(snip)


+static void f_sdh30_e51_init(struct udevice *dev)
+{
+   struct f_sdh30_plat *plat = dev_get_plat(dev);
+   struct sdhci_host *host = dev_get_priv(dev);
+   u32 val;
+
+   if (plat->enable_cmd_dat_delay) {
+   val = sdhci_readl(host, F_SDH30_ESD_CONTROL);
+   val |= F_SDH30_CMD_DAT_DELAY;


Is there a case to set its regardless of enable_cmd_dat_delay?

how about below?

if (plat->enable_cmd_dat_delay)
val |= F_SDH30_CMD_DAT_DELAY;
else
val &= ~F_SDH30_CMD_DAT_DELAY;


Yes, I forgot the false case. Need to add it.


+   sdhci_writel(host, val, F_SDH30_ESD_CONTROL);
+   }
+
+   if (plat->cfg.host_caps & MMC_CAP_NONREMOVABLE) {
+   val = sdhci_readl(host, F_SDH30_TEST);
+   val |= F_SDH30_FORCE_CARD_INSERT;


Ditto.


I'll fix it too.


+   sdhci_writel(host, val, F_SDH30_TEST);
+   }
+}
+
  static int f_sdh30_sdhci_probe(struct udevice *dev)
  {
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
@@ -25,6 +58,8 @@ static int f_sdh30_sdhci_probe(struct udevice *dev)
struct sdhci_host *host = dev_get_priv(dev);
int ret;
  
+	plat->data = (const struct f_sdh30_data *)dev_get_driver_data(dev);

+
ret = mmc_of_parse(dev, >cfg);
if (ret)
return ret;
@@ -33,6 +68,9 @@ static int f_sdh30_sdhci_probe(struct udevice *dev)
host->mmc->dev = dev;
host->mmc->priv = host;
  
+	if (plat->data && plat->data->quirks)

+   host->quirks |= plat->data->quirks;


Doesn't need to use "|" ?


I thought there was some premise in "host", however, this is a private
structure allocated by calloc() before probing the driver.
I can remove "|".

Thank you,

---
Best Regards
Kunihiko Hayashi


[PATCH 2/2] mmc: f_sdh30: Add support for F_SDH30_E51

2022-09-05 Thread Kunihiko Hayashi
Add Socionext F_SDH30_E51 IP support. The features of this IP includes
CMD/DAT line delay and force card insertion mode for non-removable cards.
And the IP needs to add some quirks.

Signed-off-by: Kunihiko Hayashi 
---
 drivers/mmc/Kconfig   |  4 +--
 drivers/mmc/f_sdh30.c | 64 +--
 2 files changed, 64 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 0dcec8adcee8..c30f20cba5f2 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -577,12 +577,12 @@ config MMC_SDHCI_IPROC
  If unsure, say N.
 
 config MMC_SDHCI_F_SDH30
-   bool "SDHCI support for Fujitsu Semiconductor F_SDH30"
+   bool "SDHCI support for Fujitsu Semiconductor/Socionext F_SDH30"
depends on BLK && DM_MMC
depends on MMC_SDHCI
help
  This selects the Secure Digital Host Controller Interface (SDHCI)
- Needed by some Fujitsu SoC for MMC / SD / SDIO support.
+ Needed by some Fujitsu/Socionext SoC for MMC / SD / SDIO support.
  If you have a controller with this interface, say Y or M here.
  If unsure, say N.
 
diff --git a/drivers/mmc/f_sdh30.c b/drivers/mmc/f_sdh30.c
index 3a85d9e348ab..6b950edab74e 100644
--- a/drivers/mmc/f_sdh30.c
+++ b/drivers/mmc/f_sdh30.c
@@ -11,13 +11,46 @@
 #include 
 #include 
 
+#define F_SDH30_ESD_CONTROL0x124
+#define F_SDH30_CMD_DAT_DELAY  BIT(9)
+
+#define F_SDH30_TEST   0x158
+#define F_SDH30_FORCE_CARD_INSERT  BIT(6)
+
+struct f_sdh30_data {
+   void (*init)(struct udevice *dev);
+   u32 quirks;
+};
+
 struct f_sdh30_plat {
struct mmc_config cfg;
struct mmc mmc;
+
+   bool enable_cmd_dat_delay;
+   const struct f_sdh30_data *data;
 };
 
 DECLARE_GLOBAL_DATA_PTR;
 
+static void f_sdh30_e51_init(struct udevice *dev)
+{
+   struct f_sdh30_plat *plat = dev_get_plat(dev);
+   struct sdhci_host *host = dev_get_priv(dev);
+   u32 val;
+
+   if (plat->enable_cmd_dat_delay) {
+   val = sdhci_readl(host, F_SDH30_ESD_CONTROL);
+   val |= F_SDH30_CMD_DAT_DELAY;
+   sdhci_writel(host, val, F_SDH30_ESD_CONTROL);
+   }
+
+   if (plat->cfg.host_caps & MMC_CAP_NONREMOVABLE) {
+   val = sdhci_readl(host, F_SDH30_TEST);
+   val |= F_SDH30_FORCE_CARD_INSERT;
+   sdhci_writel(host, val, F_SDH30_TEST);
+   }
+}
+
 static int f_sdh30_sdhci_probe(struct udevice *dev)
 {
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
@@ -25,6 +58,8 @@ static int f_sdh30_sdhci_probe(struct udevice *dev)
struct sdhci_host *host = dev_get_priv(dev);
int ret;
 
+   plat->data = (const struct f_sdh30_data *)dev_get_driver_data(dev);
+
ret = mmc_of_parse(dev, >cfg);
if (ret)
return ret;
@@ -33,6 +68,9 @@ static int f_sdh30_sdhci_probe(struct udevice *dev)
host->mmc->dev = dev;
host->mmc->priv = host;
 
+   if (plat->data && plat->data->quirks)
+   host->quirks |= plat->data->quirks;
+
ret = sdhci_setup_cfg(>cfg, host, 2, 40);
if (ret)
return ret;
@@ -41,18 +79,29 @@ static int f_sdh30_sdhci_probe(struct udevice *dev)
 
mmc_set_clock(host->mmc, host->mmc->cfg->f_min, MMC_CLK_ENABLE);
 
-   return sdhci_probe(dev);
+   ret = sdhci_probe(dev);
+   if (ret)
+   return ret;
+
+   if (plat->data && plat->data->init)
+   plat->data->init(dev);
+
+   return 0;
 }
 
 static int f_sdh30_of_to_plat(struct udevice *dev)
 {
struct sdhci_host *host = dev_get_priv(dev);
+   struct f_sdh30_plat *plat = dev_get_plat(dev);
 
host->name = strdup(dev->name);
host->ioaddr = dev_read_addr_ptr(dev);
host->bus_width = dev_read_u32_default(dev, "bus-width", 4);
host->index = dev_read_u32_default(dev, "index", 0);
 
+   plat->enable_cmd_dat_delay =
+   dev_read_bool(dev, "socionext,enable-cmd-dat-delay");
+
return 0;
 }
 
@@ -63,8 +112,19 @@ static int f_sdh30_bind(struct udevice *dev)
return sdhci_bind(dev, >mmc, >cfg);
 }
 
+static const struct f_sdh30_data f_sdh30_e51_data = {
+   .init = f_sdh30_e51_init,
+   .quirks = SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_SUPPORT_SINGLE,
+};
+
 static const struct udevice_id f_sdh30_mmc_ids[] = {
-   { .compatible = "fujitsu,mb86s70-sdhci-3.0" },
+   {
+   .compatible = "fujitsu,mb86s70-sdhci-3.0",
+   },
+   {
+   .compatible = "socionext,f-sdh30-e51-mmc",
+   .data = (ulong)_sdh30_e51_data,
+   },
{ }
 };
 
-- 
2.17.1



[PATCH 1/2] mmc: sdhci: Add new quirks for SUPPORT_SINGLE

2022-09-05 Thread Kunihiko Hayashi
This patch defines a quirk to disable the block count
for single block transactions.

This is similar to Linux kernel commit d3fc5d71ac4d
("mmc: sdhci: add a quirk for single block transactions").

Signed-off-by: Kunihiko Hayashi 
---
 drivers/mmc/sdhci.c | 8 +---
 include/sdhci.h | 1 +
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index bf989a594f7e..a80ad8329a38 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -211,7 +211,7 @@ static int sdhci_send_command(struct mmc *mmc, struct 
mmc_cmd *cmd,
unsigned int stat = 0;
int ret = 0;
int trans_bytes = 0, is_aligned = 1;
-   u32 mask, flags, mode;
+   u32 mask, flags, mode = 0;
unsigned int time = 0;
int mmc_dev = mmc_get_blk_desc(mmc)->devnum;
ulong start = get_timer(0);
@@ -273,10 +273,12 @@ static int sdhci_send_command(struct mmc *mmc, struct 
mmc_cmd *cmd,
/* Set Transfer mode regarding to data flag */
if (data) {
sdhci_writeb(host, 0xe, SDHCI_TIMEOUT_CONTROL);
-   mode = SDHCI_TRNS_BLK_CNT_EN;
+
+   if (!(host->quirks & SDHCI_QUIRK_SUPPORT_SINGLE))
+   mode = SDHCI_TRNS_BLK_CNT_EN;
trans_bytes = data->blocks * data->blocksize;
if (data->blocks > 1)
-   mode |= SDHCI_TRNS_MULTI;
+   mode |= SDHCI_TRNS_MULTI | SDHCI_TRNS_BLK_CNT_EN;
 
if (data->flags == MMC_DATA_READ)
mode |= SDHCI_TRNS_READ;
diff --git a/include/sdhci.h b/include/sdhci.h
index 88f1917480b6..24b4599b857d 100644
--- a/include/sdhci.h
+++ b/include/sdhci.h
@@ -247,6 +247,7 @@
 #define SDHCI_QUIRK_WAIT_SEND_CMD  (1 << 6)
 #define SDHCI_QUIRK_USE_WIDE8  (1 << 8)
 #define SDHCI_QUIRK_NO_1_8_V   (1 << 9)
+#define SDHCI_QUIRK_SUPPORT_SINGLE (1 << 10)
 
 /* to make gcc happy */
 struct sdhci_host;
-- 
2.17.1



[PATCH 0/2] mmc: Add support for F_SDH30_E51

2022-09-05 Thread Kunihiko Hayashi
This series adds a new quirk "SUPPORT_SINGLE" for single transaction to
sdhci framework and Socionext F_SDH30_E51 IP support to f_sdh30 driver.

Kunihiko Hayashi (2):
  mmc: sdhci: Add new quirks for SUPPORT_SINGLE
  mmc: f_sdh30: Add support for F_SDH30_E51

 drivers/mmc/Kconfig   |  4 +--
 drivers/mmc/f_sdh30.c | 64 +--
 drivers/mmc/sdhci.c   |  8 --
 include/sdhci.h   |  1 +
 4 files changed, 70 insertions(+), 7 deletions(-)

-- 
2.17.1



Re: [PATCH] serial: zynq: Use DIV_ROUND_CLOSEST() to calcurate divider value

2022-07-16 Thread Kunihiko Hayashi

Hi Michal,

On 2022/07/15 19:48, Michal Simek wrote:



On 7/13/22 03:38, Kunihiko Hayashi wrote:

Since the calulation of "bgen" is rounded down, using a higher
baudrate will result in a larger difference from the actual
baudrate. Should use DIV_ROUND_CLOSEST() like the Linux driver.

Signed-off-by: Kunihiko Hayashi 
---
   drivers/serial/serial_zynq.c | 2 +-
   1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/serial/serial_zynq.c b/drivers/serial/serial_zynq.c
index 83adfb5fb98a..857c570c5836 100644
--- a/drivers/serial/serial_zynq.c
+++ b/drivers/serial/serial_zynq.c
@@ -75,7 +75,7 @@ static void _uart_zynq_serial_setbrg(struct uart_zynq
*regs,
 * Find acceptable values for baud generation.
 */
for (bdiv = 4; bdiv < 255; bdiv++) {
-   bgen = clock / (baud * (bdiv + 1));
+   bgen = DIV_ROUND_CLOSEST(clock, (baud * (bdiv + 1)));


Applied but I have removed one level of () in second parameter which is not
needed.

Sorry I forgot to remove it.
Thanks for pointing out.

---
Best Regards
Kunihiko Hayashi


[PATCH 2/2] ARM: dts: uniphier: Change phy-mode to RGMII-ID to enable delay pins

2022-07-12 Thread Kunihiko Hayashi
UniPhier LD20, PXs2 and PXs3 boards have ethernet phy that has RX/TX delays
of RGMII interface using pull-ups on the RXDLY and TXDLY pins.

So should set the phy-mode to "rgmii-id" to show that RX/TX delays are
enabled.

Signed-off-by: Kunihiko Hayashi 
---
 arch/arm/dts/uniphier-ld20.dtsi | 2 +-
 arch/arm/dts/uniphier-pxs2.dtsi | 2 +-
 arch/arm/dts/uniphier-pxs3.dtsi | 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/dts/uniphier-ld20.dtsi b/arch/arm/dts/uniphier-ld20.dtsi
index 5e7143ed012f..4549935c421b 100644
--- a/arch/arm/dts/uniphier-ld20.dtsi
+++ b/arch/arm/dts/uniphier-ld20.dtsi
@@ -734,7 +734,7 @@
clocks = <_clk 6>;
reset-names = "ether";
resets = <_rst 6>;
-   phy-mode = "rgmii";
+   phy-mode = "rgmii-id";
local-mac-address = [00 00 00 00 00 00];
socionext,syscon-phy-mode = <_glue 0>;
 
diff --git a/arch/arm/dts/uniphier-pxs2.dtsi b/arch/arm/dts/uniphier-pxs2.dtsi
index 899ff379c9b8..7a8b6c10f4dc 100644
--- a/arch/arm/dts/uniphier-pxs2.dtsi
+++ b/arch/arm/dts/uniphier-pxs2.dtsi
@@ -583,7 +583,7 @@
clocks = <_clk 6>;
reset-names = "ether";
resets = <_rst 6>;
-   phy-mode = "rgmii";
+   phy-mode = "rgmii-id";
local-mac-address = [00 00 00 00 00 00];
socionext,syscon-phy-mode = <_glue 0>;
 
diff --git a/arch/arm/dts/uniphier-pxs3.dtsi b/arch/arm/dts/uniphier-pxs3.dtsi
index c4344926d95d..004656c992b7 100644
--- a/arch/arm/dts/uniphier-pxs3.dtsi
+++ b/arch/arm/dts/uniphier-pxs3.dtsi
@@ -564,7 +564,7 @@
clocks = <_clk 6>;
reset-names = "ether";
resets = <_rst 6>;
-   phy-mode = "rgmii";
+   phy-mode = "rgmii-id";
local-mac-address = [00 00 00 00 00 00];
socionext,syscon-phy-mode = <_glue 0>;
 
@@ -585,7 +585,7 @@
clocks = <_clk 7>;
reset-names = "ether";
resets = <_rst 7>;
-   phy-mode = "rgmii";
+   phy-mode = "rgmii-id";
local-mac-address = [00 00 00 00 00 00];
socionext,syscon-phy-mode = <_glue 1>;
 
-- 
2.7.4



[PATCH 1/2] net: ave: Add capability of rgmii-id mode

2022-07-12 Thread Kunihiko Hayashi
This allows you to specify the type of rgmii-id that will enable phy
internal delay in ethernet phy-mode.

This adds all RGMII cases to all of get_pinmode() except LD11, because LD11
SoC doesn't support RGMII due to the constraint of the hardware. When RGMII
phy mode is specified in the devicetree for LD11, the driver will abort
with an error.

Signed-off-by: Kunihiko Hayashi 
---
 drivers/net/sni_ave.c | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/net/sni_ave.c b/drivers/net/sni_ave.c
index 58276a40c774..014b070d9e52 100644
--- a/drivers/net/sni_ave.c
+++ b/drivers/net/sni_ave.c
@@ -483,7 +483,10 @@ static int ave_start(struct udevice *dev)
priv->rx_siz = (PKTSIZE_ALIGN - priv->rx_off);
 
val = 0;
-   if (priv->phy_mode != PHY_INTERFACE_MODE_RGMII)
+   if (priv->phy_mode != PHY_INTERFACE_MODE_RGMII &&
+   priv->phy_mode != PHY_INTERFACE_MODE_RGMII_ID &&
+   priv->phy_mode != PHY_INTERFACE_MODE_RGMII_RXID &&
+   priv->phy_mode != PHY_INTERFACE_MODE_RGMII_TXID)
val |= AVE_CFGR_MII;
writel(val, priv->iobase + AVE_CFGR);
 
@@ -639,6 +642,9 @@ static int ave_pro4_get_pinmode(struct ave_private *priv)
break;
case PHY_INTERFACE_MODE_MII:
case PHY_INTERFACE_MODE_RGMII:
+   case PHY_INTERFACE_MODE_RGMII_ID:
+   case PHY_INTERFACE_MODE_RGMII_RXID:
+   case PHY_INTERFACE_MODE_RGMII_TXID:
break;
default:
return -EINVAL;
@@ -693,6 +699,9 @@ static int ave_ld20_get_pinmode(struct ave_private *priv)
val  = SG_ETPINMODE_RMII(0);
break;
case PHY_INTERFACE_MODE_RGMII:
+   case PHY_INTERFACE_MODE_RGMII_ID:
+   case PHY_INTERFACE_MODE_RGMII_RXID:
+   case PHY_INTERFACE_MODE_RGMII_TXID:
break;
default:
return -EINVAL;
@@ -720,6 +729,9 @@ static int ave_pxs3_get_pinmode(struct ave_private *priv)
val = SG_ETPINMODE_RMII(priv->regmap_arg);
break;
case PHY_INTERFACE_MODE_RGMII:
+   case PHY_INTERFACE_MODE_RGMII_ID:
+   case PHY_INTERFACE_MODE_RGMII_RXID:
+   case PHY_INTERFACE_MODE_RGMII_TXID:
break;
default:
return -EINVAL;
-- 
2.7.4



[PATCH 0/2] Add RGMII-ID phy-mode support for AVE ethernet controller

2022-07-12 Thread Kunihiko Hayashi
This series adds support for RGMII-ID phy-mode for the SoCs that implement
AVE ethernet controller. Some SoCs need to enable delay pins as default.

Kunihiko Hayashi (2):
  net: ave: Add capability of rgmii-id mode
  ARM: dts: uniphier: Change phy-mode to RGMII-ID to enable delay pins

 arch/arm/dts/uniphier-ld20.dtsi |  2 +-
 arch/arm/dts/uniphier-pxs2.dtsi |  2 +-
 arch/arm/dts/uniphier-pxs3.dtsi |  4 ++--
 drivers/net/sni_ave.c   | 14 +-
 4 files changed, 17 insertions(+), 5 deletions(-)

-- 
2.7.4



[PATCH] serial: zynq: Use DIV_ROUND_CLOSEST() to calcurate divider value

2022-07-12 Thread Kunihiko Hayashi
Since the calulation of "bgen" is rounded down, using a higher
baudrate will result in a larger difference from the actual
baudrate. Should use DIV_ROUND_CLOSEST() like the Linux driver.

Signed-off-by: Kunihiko Hayashi 
---
 drivers/serial/serial_zynq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/serial/serial_zynq.c b/drivers/serial/serial_zynq.c
index 83adfb5fb98a..857c570c5836 100644
--- a/drivers/serial/serial_zynq.c
+++ b/drivers/serial/serial_zynq.c
@@ -75,7 +75,7 @@ static void _uart_zynq_serial_setbrg(struct uart_zynq *regs,
 * Find acceptable values for baud generation.
 */
for (bdiv = 4; bdiv < 255; bdiv++) {
-   bgen = clock / (baud * (bdiv + 1));
+   bgen = DIV_ROUND_CLOSEST(clock, (baud * (bdiv + 1)));
if (bgen < 2 || bgen > 65535)
continue;
 
-- 
2.7.4



[PATCH 6/6] ARM: dts: uniphier: Add support for Akebi96

2021-07-06 Thread Kunihiko Hayashi
Add the device tree for Akebi96. Akebi96 is a 96boards certified
development board based on UniPhier LD20.
( https://www.96boards.org/product/akebi96/ )

Signed-off-by: Masami Hiramatsu 
Signed-off-by: Kunihiko Hayashi 
---
 arch/arm/dts/Makefile  |   1 +
 arch/arm/dts/uniphier-ld20-akebi96.dts | 189 +
 2 files changed, 190 insertions(+)
 create mode 100644 arch/arm/dts/uniphier-ld20-akebi96.dts

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 9fb3868..ff50727 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -250,6 +250,7 @@ dtb-$(CONFIG_ARCH_UNIPHIER_LD11) += \
uniphier-ld11-global.dtb \
uniphier-ld11-ref.dtb
 dtb-$(CONFIG_ARCH_UNIPHIER_LD20) += \
+   uniphier-ld20-akebi96.dtb \
uniphier-ld20-global.dtb \
uniphier-ld20-ref.dtb
 dtb-$(CONFIG_ARCH_UNIPHIER_LD4) += \
diff --git a/arch/arm/dts/uniphier-ld20-akebi96.dts 
b/arch/arm/dts/uniphier-ld20-akebi96.dts
new file mode 100644
index 000..aa159a1
--- /dev/null
+++ b/arch/arm/dts/uniphier-ld20-akebi96.dts
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+//
+// Device Tree Source for Akebi96 Development Board
+//
+// Derived from uniphier-ld20-global.dts.
+//
+// Copyright (C) 2015-2017 Socionext Inc.
+// Copyright (C) 2019-2020 Linaro Ltd.
+
+/dts-v1/;
+#include 
+#include "uniphier-ld20.dtsi"
+
+/ {
+   model = "Akebi96";
+   compatible = "socionext,uniphier-ld20-akebi96",
+"socionext,uniphier-ld20";
+
+   chosen {
+   stdout-path = "serial0:115200n8";
+   };
+
+   aliases {
+   serial0 = 
+   serial1 = 
+   serial2 = 
+   serial3 = 
+   i2c0 = 
+   i2c1 = 
+   i2c2 = 
+   i2c3 = 
+   i2c4 = 
+   i2c5 = 
+   spi0 = 
+   spi1 = 
+   spi2 = 
+   spi3 = 
+   ethernet0 = 
+   };
+
+   memory@8000 {
+   device_type = "memory";
+   reg = <0 0x8000 0 0xc000>;
+   };
+
+   framebuffer@c000 {
+   compatible = "simple-framebuffer";
+   reg = <0 0xc000 0 0x0200>;
+   width = <1920>;
+   height = <1080>;
+   stride = <7680>;
+   format = "a8r8g8b8";
+   };
+
+   reserved-memory {
+   #address-cells = <2>;
+   #size-cells = <2>;
+   ranges;
+
+   memory@c000 {
+   reg = <0 0xc000 0 0x0200>;
+   no-map;
+   };
+   };
+
+   sound {
+   compatible = "audio-graph-card";
+   label = "UniPhier LD20";
+   dais = <_port0
+   _spdif_port0>;
+   };
+
+   spdif-out {
+   compatible = "linux,spdif-dit";
+   #sound-dai-cells = <0>;
+
+   port@0 {
+   spdif_tx: endpoint {
+   remote-endpoint = <_hiecout1>;
+   };
+   };
+   };
+
+   comp-spdif-out {
+   compatible = "linux,spdif-dit";
+   #sound-dai-cells = <0>;
+
+   port@0 {
+   comp_spdif_tx: endpoint {
+   remote-endpoint = <_spdif_hiecout1>;
+   };
+   };
+   };
+
+   firmware {
+   optee {
+   compatible = "linaro,optee-tz";
+   method = "smc";
+   };
+   };
+};
+
+ {
+   status = "okay";
+   #address-cells = <1>;
+   #size-cells = <0>;
+   usb-over-spi@0 {
+   compatible = "maxim,max3421-udc";
+   reg = <0>;
+   spi-max-frequency = <1250>;
+   interrupt-parent = <>;
+   interrupt-names = "udc";
+   interrupts = <0 2>;
+   };
+};
+
+ {
+   /* Onboard USB-UART */
+   status = "okay";
+};
+
+ {
+   /* LS connector UART1 */
+   status = "okay";
+};
+
+ {
+   /* LS connector UART0 */
+   status = "okay";
+};
+
+_hiecout1 {
+   remote-endpoint = <_tx>;
+};
+
+_spdif_hiecout1 {
+   remote-endpoint = <_spdif_tx>;
+};
+
+ {
+   /* LS connector I2C0 */
+   status = "okay";
+};
+
+ {
+   /* LS connector I2C1 */
+   status = "okay";
+};
+
+ {
+   status = "okay";
+   phy-handle = <>;
+};
+
+ {
+   ethphy: ethernet-phy@0 {
+

[PATCH 4/6] pci: uniphier: Add UniPhier PCIe controller driver

2021-07-06 Thread Kunihiko Hayashi
Add PCIe driver for UniPhier SoCs. This PCIe controller is based on
Synopsys DesignWare Core IP.

This version doesn't apply common DW functions because supported
controller doesn't have unroll version of iATU.

Signed-off-by: Kunihiko Hayashi 
---
 drivers/pci/Kconfig |  10 ++
 drivers/pci/Makefile|   1 +
 drivers/pci/pcie_uniphier.c | 424 
 3 files changed, 435 insertions(+)
 create mode 100644 drivers/pci/pcie_uniphier.c

diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index b2b7b25..6b35455 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -328,4 +328,14 @@ config PCI_BRCMSTB
  on Broadcom set-top-box (STB) SoCs.
  This driver currently supports only BCM2711 SoC and RC mode
  of the controller.
+
+config PCIE_UNIPHIER
+   bool "Socionext UniPhier PCIe driver"
+   depends on DM_PCI
+   depends on ARCH_UNIPHIER
+   select PHY_UNIPHIER_PCIE
+   help
+ Say Y here if you want to enable PCIe controller support on
+ UniPhier SoCs.
+
 endif
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index c742bb2..73dee64 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -55,3 +55,4 @@ obj-$(CONFIG_PCI_BRCMSTB) += pcie_brcmstb.o
 obj-$(CONFIG_PCI_OCTEONTX) += pci_octeontx.o
 obj-$(CONFIG_PCIE_OCTEON) += pcie_octeon.o
 obj-$(CONFIG_PCIE_DW_SIFIVE) += pcie_dw_sifive.o
+obj-$(CONFIG_PCIE_UNIPHIER) += pcie_uniphier.o
diff --git a/drivers/pci/pcie_uniphier.c b/drivers/pci/pcie_uniphier.c
new file mode 100644
index 000..f2edea9
--- /dev/null
+++ b/drivers/pci/pcie_uniphier.c
@@ -0,0 +1,424 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * pcie_uniphier.c - Socionext UniPhier PCIe driver
+ * Copyright 2019-2021 Socionext, Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* DBI registers */
+#define PCIE_LINK_STATUS_REG   0x0080
+#define PCIE_LINK_STATUS_WIDTH_MASKGENMASK(25, 20)
+#define PCIE_LINK_STATUS_SPEED_MASKGENMASK(19, 16)
+
+#define PCIE_MISC_CONTROL_1_OFF0x08BC
+#define PCIE_DBI_RO_WR_EN  BIT(0)
+
+/* DBI iATU registers */
+#define PCIE_ATU_VIEWPORT  0x0900
+#define PCIE_ATU_REGION_INBOUNDBIT(31)
+#define PCIE_ATU_REGION_OUTBOUND   0
+#define PCIE_ATU_REGION_INDEX_MASK GENMASK(3, 0)
+
+#define PCIE_ATU_CR1   0x0904
+#define PCIE_ATU_TYPE_MEM  0
+#define PCIE_ATU_TYPE_IO   2
+#define PCIE_ATU_TYPE_CFG0 4
+#define PCIE_ATU_TYPE_CFG1 5
+
+#define PCIE_ATU_CR2   0x0908
+#define PCIE_ATU_ENABLEBIT(31)
+#define PCIE_ATU_MATCH_MODEBIT(30)
+#define PCIE_ATU_BAR_NUM_MASK  GENMASK(10, 8)
+
+#define PCIE_ATU_LOWER_BASE0x090C
+#define PCIE_ATU_UPPER_BASE0x0910
+#define PCIE_ATU_LIMIT 0x0914
+#define PCIE_ATU_LOWER_TARGET  0x0918
+#define PCIE_ATU_BUS(x)FIELD_PREP(GENMASK(31, 24), x)
+#define PCIE_ATU_DEV(x)FIELD_PREP(GENMASK(23, 19), x)
+#define PCIE_ATU_FUNC(x)   FIELD_PREP(GENMASK(18, 16), x)
+#define PCIE_ATU_UPPER_TARGET  0x091C
+
+/* Link Glue registers */
+#define PCL_PINCTRL0   0x002c
+#define PCL_PERST_PLDN_REGEN   BIT(12)
+#define PCL_PERST_NOE_REGENBIT(11)
+#define PCL_PERST_OUT_REGENBIT(8)
+#define PCL_PERST_PLDN_REGVAL  BIT(4)
+#define PCL_PERST_NOE_REGVAL   BIT(3)
+#define PCL_PERST_OUT_REGVAL   BIT(0)
+
+#define PCL_MODE   0x8000
+#define PCL_MODE_REGEN BIT(8)
+#define PCL_MODE_REGVALBIT(0)
+
+#define PCL_APP_READY_CTRL 0x8008
+#define PCL_APP_LTSSM_ENABLE   BIT(0)
+
+#define PCL_APP_PM00x8078
+#define PCL_SYS_AUX_PWR_DETBIT(8)
+
+#define PCL_STATUS_LINK0x8140
+#define PCL_RDLH_LINK_UP   BIT(1)
+#define PCL_XMLH_LINK_UP   BIT(0)
+
+#define LINK_UP_TIMEOUT_MS 100
+
+struct uniphier_pcie_priv {
+   void *base;
+   void *dbi_base;
+   void *cfg_base;
+   fdt_size_t cfg_size;
+   struct fdt_resource link_res;
+   struct fdt_resource dbi_res;
+   struct fdt_resource cfg_res;
+
+   struct clk clk;
+   struct reset_ctl rst;
+   struct phy phy;
+
+   struct pci_region io;
+   struct pci_region mem;
+};
+
+static int pcie_dw_get_link_speed(struct uniphier_pcie_priv *priv)
+{
+   u32 val = readl(priv->dbi_base + PCIE_LINK_STATUS_REG);
+
+   return FIELD_GET(PCIE_LINK_STATUS_SPEED_MASK, val);
+}
+
+static int pcie_dw_get_link_width(struct uniphier_pcie_priv *priv)
+{
+   u32 val = readl(priv->dbi_base + PCIE

[PATCH 5/6] configs: uniphier: Enable CONFIG_SYS_PCI_64BIT

2021-07-06 Thread Kunihiko Hayashi
Enable CONFIG_SYS_PCI_64BIT to allow 64bit access to PCI space.

Signed-off-by: Kunihiko Hayashi 
---
 include/configs/uniphier.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h
index bad4e41..12028e5 100644
--- a/include/configs/uniphier.h
+++ b/include/configs/uniphier.h
@@ -210,4 +210,6 @@
 
 #define CONFIG_SPL_PAD_TO  0x2
 
+#define CONFIG_SYS_PCI_64BIT
+
 #endif /* __CONFIG_UNIPHIER_H__ */
-- 
2.7.4



[PATCH 3/6] phy: socionext: Add UniPhier PCIe PHY driver

2021-07-06 Thread Kunihiko Hayashi
Add PCIe PHY driver support for Pro5, LD20 and PXs3 SoCs.

Signed-off-by: Kunihiko Hayashi 
---
 drivers/Kconfig   |  2 ++
 drivers/Makefile  |  1 +
 drivers/phy/socionext/Kconfig | 12 +++
 drivers/phy/socionext/Makefile|  6 
 drivers/phy/socionext/phy-uniphier-pcie.c | 59 +++
 5 files changed, 80 insertions(+)
 create mode 100644 drivers/phy/socionext/Kconfig
 create mode 100644 drivers/phy/socionext/Makefile
 create mode 100644 drivers/phy/socionext/phy-uniphier-pcie.c

diff --git a/drivers/Kconfig b/drivers/Kconfig
index b1ada1c..c9c812b 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -80,6 +80,8 @@ source "drivers/phy/allwinner/Kconfig"
 
 source "drivers/phy/marvell/Kconfig"
 
+source "drivers/phy/socionext/Kconfig"
+
 source "drivers/pinctrl/Kconfig"
 
 source "drivers/power/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 3510dab..4081289 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -96,6 +96,7 @@ obj-$(CONFIG_PCH) += pch/
 obj-y += phy/allwinner/
 obj-y += phy/marvell/
 obj-y += phy/rockchip/
+obj-y += phy/socionext/
 obj-y += rtc/
 obj-y += scsi/
 obj-y += sound/
diff --git a/drivers/phy/socionext/Kconfig b/drivers/phy/socionext/Kconfig
new file mode 100644
index 000..bcd579e
--- /dev/null
+++ b/drivers/phy/socionext/Kconfig
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# PHY drivers for Socionext platforms.
+#
+
+config PHY_UNIPHIER_PCIE
+   bool "UniPhier PCIe PHY driver"
+   depends on PHY && ARCH_UNIPHIER
+   imply REGMAP
+   help
+ Enable this to support PHY implemented in PCIe controller
+ on UniPhier SoCs.
diff --git a/drivers/phy/socionext/Makefile b/drivers/phy/socionext/Makefile
new file mode 100644
index 000..5484360
--- /dev/null
+++ b/drivers/phy/socionext/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the phy drivers.
+#
+
+obj-$(CONFIG_PHY_UNIPHIER_PCIE)+= phy-uniphier-pcie.o
diff --git a/drivers/phy/socionext/phy-uniphier-pcie.c 
b/drivers/phy/socionext/phy-uniphier-pcie.c
new file mode 100644
index 000..d352c4c
--- /dev/null
+++ b/drivers/phy/socionext/phy-uniphier-pcie.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * phy_uniphier_pcie.c - Socionext UniPhier PCIe PHY driver
+ * Copyright 2019-2021 Socionext, Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* SG */
+#define SG_USBPCIESEL  0x590
+#define SG_USBPCIESEL_PCIE BIT(0)
+
+struct uniphier_pciephy_priv {
+   int dummy;
+};
+
+static int uniphier_pciephy_init(struct phy *phy)
+{
+   return 0;
+}
+
+static int uniphier_pciephy_probe(struct udevice *dev)
+{
+   struct regmap *regmap;
+
+   regmap = syscon_regmap_lookup_by_phandle(dev,
+"socionext,syscon");
+   if (!IS_ERR(regmap))
+   regmap_update_bits(regmap, SG_USBPCIESEL,
+  SG_USBPCIESEL_PCIE, SG_USBPCIESEL_PCIE);
+
+   return 0;
+}
+
+static struct phy_ops uniphier_pciephy_ops = {
+   .init = uniphier_pciephy_init,
+};
+
+static const struct udevice_id uniphier_pciephy_ids[] = {
+   { .compatible = "socionext,uniphier-pro5-pcie-phy" },
+   { .compatible = "socionext,uniphier-ld20-pcie-phy" },
+   { .compatible = "socionext,uniphier-pxs3-pcie-phy" },
+   { }
+};
+
+U_BOOT_DRIVER(uniphier_pcie_phy) = {
+   .name   = "uniphier-pcie-phy",
+   .id = UCLASS_PHY,
+   .of_match   = uniphier_pciephy_ids,
+   .ops= _pciephy_ops,
+   .probe  = uniphier_pciephy_probe,
+   .priv_auto  = sizeof(struct uniphier_pciephy_priv),
+};
-- 
2.7.4



[PATCH 2/6] reset: uniphier: Add PCIe reset entry

2021-07-06 Thread Kunihiko Hayashi
Add reset control for PCIe controller on each SoC.

Signed-off-by: Kunihiko Hayashi 
---
 drivers/reset/reset-uniphier.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/reset/reset-uniphier.c b/drivers/reset/reset-uniphier.c
index 2694d13..c5af995 100644
--- a/drivers/reset/reset-uniphier.c
+++ b/drivers/reset/reset-uniphier.c
@@ -50,6 +50,7 @@ static const struct uniphier_reset_data 
uniphier_pro4_sys_reset_data[] = {
UNIPHIER_RESETX(12, 0x2000, 6), /* GIO */
UNIPHIER_RESETX(14, 0x2000, 17),/* USB30 */
UNIPHIER_RESETX(15, 0x2004, 17),/* USB31 */
+   UNIPHIER_RESETX(24, 0x2008, 2), /* PCIE */
UNIPHIER_RESET_END,
 };
 
@@ -79,6 +80,7 @@ static const struct uniphier_reset_data 
uniphier_ld20_sys_reset_data[] = {
UNIPHIER_RESETX(17, 0x200c, 13),/* USB30-PHY1 */
UNIPHIER_RESETX(18, 0x200c, 14),/* USB30-PHY2 */
UNIPHIER_RESETX(19, 0x200c, 15),/* USB30-PHY3 */
+   UNIPHIER_RESETX(24, 0x200c, 4), /* PCIE */
UNIPHIER_RESET_END,
 };
 
@@ -95,6 +97,7 @@ static const struct uniphier_reset_data 
uniphier_pxs3_sys_reset_data[] = {
UNIPHIER_RESETX(18, 0x200c, 20),/* USB30-PHY2 */
UNIPHIER_RESETX(20, 0x200c, 17),/* USB31-PHY0 */
UNIPHIER_RESETX(21, 0x200c, 19),/* USB31-PHY1 */
+   UNIPHIER_RESETX(24, 0x200c, 3), /* PCIE */
UNIPHIER_RESET_END,
 };
 
-- 
2.7.4



[PATCH 1/6] clk: uniphier: Add PCIe clock entry

2021-07-06 Thread Kunihiko Hayashi
Add clock control for PCIe controller on each SoC.

Signed-off-by: Kunihiko Hayashi 
---
 drivers/clk/uniphier/clk-uniphier-sys.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/clk/uniphier/clk-uniphier-sys.c 
b/drivers/clk/uniphier/clk-uniphier-sys.c
index c627a4b..ff5d364 100644
--- a/drivers/clk/uniphier/clk-uniphier-sys.c
+++ b/drivers/clk/uniphier/clk-uniphier-sys.c
@@ -29,6 +29,7 @@ const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[] = 
{
UNIPHIER_CLK_GATE_SIMPLE(15, 0x2104, 17),   /* usb31 (Pro4, Pro5, 
PXs2) */
UNIPHIER_CLK_GATE_SIMPLE(16, 0x2104, 19),   /* usb30-phy (PXs2) */
UNIPHIER_CLK_GATE_SIMPLE(20, 0x2104, 20),   /* usb31-phy (PXs2) */
+   UNIPHIER_CLK_GATE_SIMPLE(24, 0x2108, 2),/* pcie (Pro5) */
{ /* sentinel */ }
 #endif
 };
@@ -43,6 +44,7 @@ const struct uniphier_clk_data uniphier_ld20_sys_clk_data[] = 
{
UNIPHIER_CLK_GATE_SIMPLE(14, 0x210c, 14),   /* usb30 (LD20) */
UNIPHIER_CLK_GATE_SIMPLE(16, 0x210c, 12),   /* usb30-phy0 (LD20) */
UNIPHIER_CLK_GATE_SIMPLE(17, 0x210c, 13),   /* usb30-phy1 (LD20) */
+   UNIPHIER_CLK_GATE_SIMPLE(24, 0x210c, 4),/* pcie */
{ /* sentinel */ }
 #endif
 };
@@ -62,6 +64,7 @@ const struct uniphier_clk_data uniphier_pxs3_sys_clk_data[] = 
{
UNIPHIER_CLK_GATE_SIMPLE(18, 0x210c, 20),   /* usb30-phy2 */
UNIPHIER_CLK_GATE_SIMPLE(20, 0x210c, 17),   /* usb31-phy0 */
UNIPHIER_CLK_GATE_SIMPLE(21, 0x210c, 19),   /* usb31-phy1 */
+   UNIPHIER_CLK_GATE_SIMPLE(24, 0x210c, 3),/* pcie */
{ /* sentinel */ }
 #endif
 };
-- 
2.7.4



[PATCH 0/6] uniphier: Add PCIe host controller and Akebi96 board support

2021-07-06 Thread Kunihiko Hayashi
This series adds PCI-express host controller support for UniPhier SoCs.
This also adds clock, reset, and phy support to enable the controller.

The controller is based on DW PCIe IP, however, the controller doesn't
have unroll version of iATU, so this series doesn't apply common DW
functions yet.

And this series includes Akebi96 board (96boards) support that has
UniPhier LD20 SoC and PCIe interface. The controller is available for
LD20 and PXs3 SoCs, and the devicetree already supports it.

Kunihiko Hayashi (6):
  clk: uniphier: Add PCIe clock entry
  reset: uniphier: Add PCIe reset entry
  phy: socionext: Add UniPhier PCIe PHY driver
  pci: uniphier: Add UniPhier PCIe controller driver
  configs: uniphier: Enable CONFIG_SYS_PCI_64BIT
  ARM: dts: uniphier: Add support for Akebi96

 arch/arm/dts/Makefile |   1 +
 arch/arm/dts/uniphier-ld20-akebi96.dts| 189 +
 drivers/Kconfig   |   2 +
 drivers/Makefile  |   1 +
 drivers/clk/uniphier/clk-uniphier-sys.c   |   3 +
 drivers/pci/Kconfig   |  10 +
 drivers/pci/Makefile  |   1 +
 drivers/pci/pcie_uniphier.c   | 424 ++
 drivers/phy/socionext/Kconfig |  12 +
 drivers/phy/socionext/Makefile|   6 +
 drivers/phy/socionext/phy-uniphier-pcie.c |  59 +
 drivers/reset/reset-uniphier.c|   3 +
 include/configs/uniphier.h|   2 +
 13 files changed, 713 insertions(+)
 create mode 100644 arch/arm/dts/uniphier-ld20-akebi96.dts
 create mode 100644 drivers/pci/pcie_uniphier.c
 create mode 100644 drivers/phy/socionext/Kconfig
 create mode 100644 drivers/phy/socionext/Makefile
 create mode 100644 drivers/phy/socionext/phy-uniphier-pcie.c

-- 
2.7.4



[PATCH v2] serial: zynq: Add support for serial parameters

2021-06-25 Thread Kunihiko Hayashi
This adds serial parameters that include stop bit mode, parity mode,
and character length. Mark parity and space parity modes are not
supported.

At the moment, the only path to call setconfig directly is DM testing,
however, this affects the size of SPL for DM testing, so it doesn't
apply to SPL.

Signed-off-by: Kunihiko Hayashi 
---
 drivers/serial/serial_zynq.c | 68 
 1 file changed, 68 insertions(+)

diff --git a/drivers/serial/serial_zynq.c b/drivers/serial/serial_zynq.c
index 799d524..2f49f59 100644
--- a/drivers/serial/serial_zynq.c
+++ b/drivers/serial/serial_zynq.c
@@ -28,7 +28,17 @@
 #define ZYNQ_UART_CR_TXRST BIT(1) /* TX logic reset */
 #define ZYNQ_UART_CR_RXRST BIT(0) /* RX logic reset */
 
+#define ZYNQ_UART_MR_STOPMODE_2_BIT0x0080  /* 2 stop bits */
+#define ZYNQ_UART_MR_STOPMODE_1_5_BIT  0x0040  /* 1.5 stop bits */
+#define ZYNQ_UART_MR_STOPMODE_1_BIT0x  /* 1 stop bit */
+
 #define ZYNQ_UART_MR_PARITY_NONE   0x0020  /* No parity mode */
+#define ZYNQ_UART_MR_PARITY_ODD0x0008  /* Odd parity mode 
*/
+#define ZYNQ_UART_MR_PARITY_EVEN   0x  /* Even parity mode */
+
+#define ZYNQ_UART_MR_CHARLEN_6_BIT 0x0006  /* 6 bits data */
+#define ZYNQ_UART_MR_CHARLEN_7_BIT 0x0004  /* 7 bits data */
+#define ZYNQ_UART_MR_CHARLEN_8_BIT 0x  /* 8 bits data */
 
 struct uart_zynq {
u32 control; /* 0x0 - Control Register [8:0] */
@@ -137,6 +147,63 @@ static int zynq_serial_setbrg(struct udevice *dev, int 
baudrate)
return 0;
 }
 
+#if !defined(CONFIG_SPL_BUILD)
+static int zynq_serial_setconfig(struct udevice *dev, uint serial_config)
+{
+   struct zynq_uart_plat *plat = dev_get_plat(dev);
+   struct uart_zynq *regs = plat->regs;
+   u32 val = 0;
+
+   switch (SERIAL_GET_BITS(serial_config)) {
+   case SERIAL_6_BITS:
+   val |= ZYNQ_UART_MR_CHARLEN_6_BIT;
+   break;
+   case SERIAL_7_BITS:
+   val |= ZYNQ_UART_MR_CHARLEN_7_BIT;
+   break;
+   case SERIAL_8_BITS:
+   val |= ZYNQ_UART_MR_CHARLEN_8_BIT;
+   break;
+   default:
+   return -ENOTSUPP; /* not supported in driver */
+   }
+
+   switch (SERIAL_GET_STOP(serial_config)) {
+   case SERIAL_ONE_STOP:
+   val |= ZYNQ_UART_MR_STOPMODE_1_BIT;
+   break;
+   case SERIAL_ONE_HALF_STOP:
+   val |= ZYNQ_UART_MR_STOPMODE_1_5_BIT;
+   break;
+   case SERIAL_TWO_STOP:
+   val |= ZYNQ_UART_MR_STOPMODE_2_BIT;
+   break;
+   default:
+   return -ENOTSUPP; /* not supported in driver */
+   }
+
+   switch (SERIAL_GET_PARITY(serial_config)) {
+   case SERIAL_PAR_NONE:
+   val |= ZYNQ_UART_MR_PARITY_NONE;
+   break;
+   case SERIAL_PAR_ODD:
+   val |= ZYNQ_UART_MR_PARITY_ODD;
+   break;
+   case SERIAL_PAR_EVEN:
+   val |= ZYNQ_UART_MR_PARITY_EVEN;
+   break;
+   default:
+   return -ENOTSUPP; /* not supported in driver */
+   }
+
+   writel(val, >mode);
+
+   return 0;
+}
+#else
+#define zynq_serial_setconfig NULL
+#endif
+
 static int zynq_serial_probe(struct udevice *dev)
 {
struct zynq_uart_plat *plat = dev_get_plat(dev);
@@ -198,6 +265,7 @@ static const struct dm_serial_ops zynq_serial_ops = {
.pending = zynq_serial_pending,
.getc = zynq_serial_getc,
.setbrg = zynq_serial_setbrg,
+   .setconfig = zynq_serial_setconfig,
 };
 
 static const struct udevice_id zynq_serial_ids[] = {
-- 
2.7.4



Re: [PATCH] serial: zynq: Add support for serial parameters

2021-06-24 Thread Kunihiko Hayashi

Hi Michal,

On 2021/06/23 20:15, Michal Simek wrote:

Hi Kunihiko,

On 6/23/21 12:52 PM, Kunihiko Hayashi wrote:

Hi Michal,

On 2021/06/22 21:44, Michal Simek wrote:

Hi,

On 6/22/21 6:24 AM, Kunihiko Hayashi wrote:

This adds serial parameters that include stop bit mode, parity mode,
and character length. Mark parity and space parity modes are not
supported.

Signed-off-by: Kunihiko Hayashi 
---
   drivers/serial/serial_zynq.c | 64

   1 file changed, 64 insertions(+)


[snip]


I am just curious how you have tested it because only hook is in
test/dm/serial.c and I can't see no way how to change this setting via
u-boot command line.


I was misunderstanding.

Surely there is no way to execute .setconfig function, and
neither command line nor devicetree actually affects the serial mode.
The mode just inherits that of the previous firmware.


That being said I see that this change adds 184 bytes which is quite a
lot especially for SPL on zynqmp. That's why would like to know how this
feature should be used. If make sense for example to limit it to only
full U-Boot.


I see. I didn't think enough about the size limit of SPL.
Anyway, I withdraw this patch.


Up2you. Maybe someone will add any support for calling these functions.
For me it is fine to add it to full U-Boot but not to SPL for DM testing.


Ok, I expect to such support.
I'll modify it to add the function when CONFIG_SPL_BUILD isn't defined
if there is no concern, and resend it.

Thank you,

---
Best Regards
Kunihiko Hayashi


Re: [PATCH] serial: zynq: Add support for serial parameters

2021-06-23 Thread Kunihiko Hayashi

Hi Michal,

On 2021/06/22 21:44, Michal Simek wrote:

Hi,

On 6/22/21 6:24 AM, Kunihiko Hayashi wrote:

This adds serial parameters that include stop bit mode, parity mode,
and character length. Mark parity and space parity modes are not
supported.

Signed-off-by: Kunihiko Hayashi 
---
  drivers/serial/serial_zynq.c | 64 
  1 file changed, 64 insertions(+)


[snip]


I am just curious how you have tested it because only hook is in
test/dm/serial.c and I can't see no way how to change this setting via
u-boot command line.


I was misunderstanding.

Surely there is no way to execute .setconfig function, and
neither command line nor devicetree actually affects the serial mode.
The mode just inherits that of the previous firmware.


That being said I see that this change adds 184 bytes which is quite a
lot especially for SPL on zynqmp. That's why would like to know how this
feature should be used. If make sense for example to limit it to only
full U-Boot.


I see. I didn't think enough about the size limit of SPL.
Anyway, I withdraw this patch.

Thank you,

---
Best Regards
Kunihiko Hayashi


[PATCH] serial: zynq: Add support for serial parameters

2021-06-21 Thread Kunihiko Hayashi
This adds serial parameters that include stop bit mode, parity mode,
and character length. Mark parity and space parity modes are not
supported.

Signed-off-by: Kunihiko Hayashi 
---
 drivers/serial/serial_zynq.c | 64 
 1 file changed, 64 insertions(+)

diff --git a/drivers/serial/serial_zynq.c b/drivers/serial/serial_zynq.c
index 799d524..a644e78 100644
--- a/drivers/serial/serial_zynq.c
+++ b/drivers/serial/serial_zynq.c
@@ -28,7 +28,17 @@
 #define ZYNQ_UART_CR_TXRST BIT(1) /* TX logic reset */
 #define ZYNQ_UART_CR_RXRST BIT(0) /* RX logic reset */
 
+#define ZYNQ_UART_MR_STOPMODE_2_BIT0x0080  /* 2 stop bits */
+#define ZYNQ_UART_MR_STOPMODE_1_5_BIT  0x0040  /* 1.5 stop bits */
+#define ZYNQ_UART_MR_STOPMODE_1_BIT0x  /* 1 stop bit */
+
 #define ZYNQ_UART_MR_PARITY_NONE   0x0020  /* No parity mode */
+#define ZYNQ_UART_MR_PARITY_ODD0x0008  /* Odd parity mode 
*/
+#define ZYNQ_UART_MR_PARITY_EVEN   0x  /* Even parity mode */
+
+#define ZYNQ_UART_MR_CHARLEN_6_BIT 0x0006  /* 6 bits data */
+#define ZYNQ_UART_MR_CHARLEN_7_BIT 0x0004  /* 7 bits data */
+#define ZYNQ_UART_MR_CHARLEN_8_BIT 0x  /* 8 bits data */
 
 struct uart_zynq {
u32 control; /* 0x0 - Control Register [8:0] */
@@ -137,6 +147,59 @@ static int zynq_serial_setbrg(struct udevice *dev, int 
baudrate)
return 0;
 }
 
+static int zynq_serial_setconfig(struct udevice *dev, uint serial_config)
+{
+   struct zynq_uart_plat *plat = dev_get_plat(dev);
+   struct uart_zynq *regs = plat->regs;
+   u32 val = 0;
+
+   switch (SERIAL_GET_BITS(serial_config)) {
+   case SERIAL_6_BITS:
+   val |= ZYNQ_UART_MR_CHARLEN_6_BIT;
+   break;
+   case SERIAL_7_BITS:
+   val |= ZYNQ_UART_MR_CHARLEN_7_BIT;
+   break;
+   case SERIAL_8_BITS:
+   val |= ZYNQ_UART_MR_CHARLEN_8_BIT;
+   break;
+   default:
+   return -ENOTSUPP; /* not supported in driver */
+   }
+
+   switch (SERIAL_GET_STOP(serial_config)) {
+   case SERIAL_ONE_STOP:
+   val |= ZYNQ_UART_MR_STOPMODE_1_BIT;
+   break;
+   case SERIAL_ONE_HALF_STOP:
+   val |= ZYNQ_UART_MR_STOPMODE_1_5_BIT;
+   break;
+   case SERIAL_TWO_STOP:
+   val |= ZYNQ_UART_MR_STOPMODE_2_BIT;
+   break;
+   default:
+   return -ENOTSUPP; /* not supported in driver */
+   }
+
+   switch (SERIAL_GET_PARITY(serial_config)) {
+   case SERIAL_PAR_NONE:
+   val |= ZYNQ_UART_MR_PARITY_NONE;
+   break;
+   case SERIAL_PAR_ODD:
+   val |= ZYNQ_UART_MR_PARITY_ODD;
+   break;
+   case SERIAL_PAR_EVEN:
+   val |= ZYNQ_UART_MR_PARITY_EVEN;
+   break;
+   default:
+   return -ENOTSUPP; /* not supported in driver */
+   }
+
+   writel(val, >mode);
+
+   return 0;
+}
+
 static int zynq_serial_probe(struct udevice *dev)
 {
struct zynq_uart_plat *plat = dev_get_plat(dev);
@@ -198,6 +261,7 @@ static const struct dm_serial_ops zynq_serial_ops = {
.pending = zynq_serial_pending,
.getc = zynq_serial_getc,
.setbrg = zynq_serial_setbrg,
+   .setconfig = zynq_serial_setconfig,
 };
 
 static const struct udevice_id zynq_serial_ids[] = {
-- 
2.7.4



[PATCH] arm64: Fix relocation of env_addr if POSITION_INDEPENDENT=y

2021-06-15 Thread Kunihiko Hayashi
If both POSITION_INDEPENDENT and SYS_RELOC_GD_ENV_ADDR are enabled,
wherever original env is placed anywhere, it should be relocated to
the right address.

Relocation offset gd->reloc_off is calculated with SYS_TEXT_BASE in
setup_reloc() and env address gd->env_addr is relocated by the offset in
initr_reloc_global_data().

gd->env_addr
  = (orig env) + gd->reloc_off
  = (orig env) + (gd->relocaddr - SYS_TEXT_BASE)

However, SYS_TEXT_BASE isn't always runtime base address when
POSITION_INDEPENDENT is enabled. So the relocated env_addr might point to
wrong address. For example, if SYS_TEXT_BASE is zero, gd->env_addr is
out of memory location and memory exception will occur.

There is a difference between linked address such as SYS_TEXT_BASE and
runtime base address. In _main, the difference is calculated as
"run-vs-link" offset. The env_addr should also be added to the offset
to fix the address.

gd->env_addr
  = (orig env) + ("run-vs-link" offset)   + gd->reloc_off
  = (orig env) + (SYS_TEXT_BASE - _start) + (gd->relocaddr - SYS_TEXT_BASE)
  = (orig env) + (gd->relocaddr - _start)

Cc: Marek Vasut 
Signed-off-by: Kunihiko Hayashi 
---
 arch/arm/lib/crt0_64.S | 5 +
 lib/asm-offsets.c  | 2 ++
 2 files changed, 7 insertions(+)

This patch is based on the previous topic:
"env: Leave invalid env for nowhere location"
https://patchwork.ozlabs.org/project/uboot/patch/1620828554-24013-1-git-send-email-hayashi.kunih...@socionext.com/

diff --git a/arch/arm/lib/crt0_64.S b/arch/arm/lib/crt0_64.S
index 9d2319c..680e674 100644
--- a/arch/arm/lib/crt0_64.S
+++ b/arch/arm/lib/crt0_64.S
@@ -112,6 +112,11 @@ ENTRY(_main)
ldr x9, _TEXT_BASE  /* x9 <- Linked value of _start */
sub x9, x9, x0  /* x9 <- Run-vs-link offset */
add lr, lr, x9
+#if defined(CONFIG_SYS_RELOC_GD_ENV_ADDR)
+   ldr x0, [x18, #GD_ENV_ADDR] /* x0 <- gd->env_addr */
+   add x0, x0, x9
+   str x0, [x18, #GD_ENV_ADDR]
+#endif
 #endif
/* Add in link-vs-relocation offset */
ldr x9, [x18, #GD_RELOC_OFF]/* x9 <- gd->reloc_off */
diff --git a/lib/asm-offsets.c b/lib/asm-offsets.c
index ee592cf..c691066 100644
--- a/lib/asm-offsets.c
+++ b/lib/asm-offsets.c
@@ -41,5 +41,7 @@ int main(void)
 
DEFINE(GD_NEW_GD, offsetof(struct global_data, new_gd));
 
+   DEFINE(GD_ENV_ADDR, offsetof(struct global_data, env_addr));
+
return 0;
 }
-- 
2.7.4



Re: [PATCH] env: Leave invalid env for nowhere location

2021-06-10 Thread Kunihiko Hayashi

Hi Marek,

On 2021/06/10 10:07, Marek Vasut wrote:

On 6/8/21 9:54 AM, Kunihiko Hayashi wrote:

Hi,

[...]


I would expect that after relocation, if all you have is env_nowhere
driver, the env_nowhere_init() is called again from the first for() loop
of env_init() [1], which would set gd->env_valid to ENV_INVALID [1], and
that for() loop would exit with ret = -ENOENT [2], so then the last part
of env_init() would check for ret == -ENOENT and update gd->env_addr to
relocated default_environment [3].

324  int env_init(void)
325  {
326    struct env_driver *drv;
327    int ret = -ENOENT;
328    int prio;
329
330    for (prio = 0; (drv = env_driver_lookup(ENVOP_INIT, prio)); prio++) {
   /* Part [1] */
331  if (!drv->init || !(ret = drv->init()))
332    env_set_inited(drv->location);
333  if (ret == -ENOENT)
334    env_set_inited(drv->location);
335
336  debug("%s: Environment %s init done (ret=%d)\n", __func__,
337    drv->name, ret);
338
   /* Part [2] */
339  if (gd->env_valid == ENV_INVALID)
340    ret = -ENOENT;
341    }
342
343    if (!prio)
344  return -ENODEV;
345
 /* Part [3] */
346    if (ret == -ENOENT) {
   /* This should be relocated default_environment address */
347  gd->env_addr = (ulong)_environment[0];
348  gd->env_valid = ENV_VALID;
349
350  return 0;
351    }
352
353    return ret;
354  }

Or am I missing something obvious ?


These are called before relocation, and update gd->env_addr to non-relocated
default_environment by [3].

After that, gd->env_addr is relocated in initr_reloc_global_data()
if CONFIG_SYS_RELOC_GD_ENV_ADDR is defined.

| #ifdef CONFIG_SYS_RELOC_GD_ENV_ADDR
| /*
|  * Relocate the early env_addr pointer unless we know it is not inside
|  * the binary. Some systems need this and for the rest, it doesn't hurt.
|  */
| gd->env_addr += gd->reloc_off;
| #endif



Shouldn't the post-relocation env update happen in env_relocate() ?


Usually env_relocate() calls env_load() that uses relocated gd->env_addr.
It's no problem.

If CONFIG_SYS_TEXT_BASE is zero, gd->reloc_off becomes illegal.
CONFIG_SYS_RELOC_GD_ENV_ADDR should be disabled in that case.


Sorry this isn't wrong.

But then, if CONFIG_SYS_TEXT_BASE is zero, the env shouldn't be relocated or how should it 
behave ?


I think the env should be relocated if CONFIG_SYS_RELOC_GD_ENV_ADDR=y
regardless of CONFIG_SYS_TEXT_BASE.

If CONFIG_POSITION_INDEPENDENT=y and CONFIG_SYS_TEXT_BASE is zero,
there is something wrong with the calculation of the relocation address about 
env.


Ah, got it.


gd->reloc_off is relocated address offset from zero, however,
gd->env_addr has still non-relocated address.

 >>>> | gd->env_addr += gd->reloc_off;

I think the env should be relocated if CONFIG_SYS_RELOC_GD_ENV_ADDR=y.
But this code sets gd->env_addr incorrectly.

In that case, there is a non-relocated  address instead of
CONFIG_SYS_TEXT_BASE.

This should be "gd->env_addr = (gd->env_addr - ) + gd->reloc_off",
However, I'm not sure how we get non-relocated  address.


Maybe what you need to do is store current $pc register when you enter U-Boot very early on, in 
_start function, and then use it here ? Although, I am not entirely sure whether this is still 
possible on arm64.


Exactly. I guess it's reasonable to fix gd->env_addr when POSITION_INDEPENDENT=y
before relocation. I'll try it.

Thank you,

---
Best Regards
Kunihiko Hayashi


Re: [PATCH] env: Leave invalid env for nowhere location

2021-06-08 Thread Kunihiko Hayashi

Hi Marek,

On 2021/06/08 2:33, Marek Vasut wrote:

On 6/7/21 9:54 AM, Kunihiko Hayashi wrote:

Hi,

[...]


I would expect that after relocation, if all you have is env_nowhere
driver, the env_nowhere_init() is called again from the first for() loop
of env_init() [1], which would set gd->env_valid to ENV_INVALID [1], and
that for() loop would exit with ret = -ENOENT [2], so then the last part
of env_init() would check for ret == -ENOENT and update gd->env_addr to
relocated default_environment [3].

324  int env_init(void)
325  {
326    struct env_driver *drv;
327    int ret = -ENOENT;
328    int prio;
329
330    for (prio = 0; (drv = env_driver_lookup(ENVOP_INIT, prio)); prio++) {
   /* Part [1] */
331  if (!drv->init || !(ret = drv->init()))
332    env_set_inited(drv->location);
333  if (ret == -ENOENT)
334    env_set_inited(drv->location);
335
336  debug("%s: Environment %s init done (ret=%d)\n", __func__,
337    drv->name, ret);
338
   /* Part [2] */
339  if (gd->env_valid == ENV_INVALID)
340    ret = -ENOENT;
341    }
342
343    if (!prio)
344  return -ENODEV;
345
 /* Part [3] */
346    if (ret == -ENOENT) {
   /* This should be relocated default_environment address */
347  gd->env_addr = (ulong)_environment[0];
348  gd->env_valid = ENV_VALID;
349
350  return 0;
351    }
352
353    return ret;
354  }

Or am I missing something obvious ?


These are called before relocation, and update gd->env_addr to non-relocated
default_environment by [3].

After that, gd->env_addr is relocated in initr_reloc_global_data()
if CONFIG_SYS_RELOC_GD_ENV_ADDR is defined.

| #ifdef CONFIG_SYS_RELOC_GD_ENV_ADDR
| /*
|  * Relocate the early env_addr pointer unless we know it is not inside
|  * the binary. Some systems need this and for the rest, it doesn't hurt.
|  */
| gd->env_addr += gd->reloc_off;
| #endif



Shouldn't the post-relocation env update happen in env_relocate() ?


Usually env_relocate() calls env_load() that uses relocated gd->env_addr.
It's no problem.

If CONFIG_SYS_TEXT_BASE is zero, gd->reloc_off becomes illegal.
CONFIG_SYS_RELOC_GD_ENV_ADDR should be disabled in that case.


Sorry this isn't wrong.


But then, if CONFIG_SYS_TEXT_BASE is zero, the env shouldn't be relocated or 
how should it behave ?


I think the env should be relocated if CONFIG_SYS_RELOC_GD_ENV_ADDR=y
regardless of CONFIG_SYS_TEXT_BASE.

If CONFIG_POSITION_INDEPENDENT=y and CONFIG_SYS_TEXT_BASE is zero,
there is something wrong with the calculation of the relocation address about 
env.

gd->reloc_off is relocated address offset from zero, however,
gd->env_addr has still non-relocated address.

>>>> | gd->env_addr += gd->reloc_off;

I think the env should be relocated if CONFIG_SYS_RELOC_GD_ENV_ADDR=y.
But this code sets gd->env_addr incorrectly.

In that case, there is a non-relocated  address instead of
CONFIG_SYS_TEXT_BASE.

This should be "gd->env_addr = (gd->env_addr - ) + gd->reloc_off",
However, I'm not sure how we get non-relocated  address.

Thank you,

---
Best Regards
Kunihiko Hayashi


Re: [PATCH] env: Leave invalid env for nowhere location

2021-06-07 Thread Kunihiko Hayashi

Hi Marek,

On 2021/06/07 3:08, Marek Vasut wrote:

On 6/3/21 6:15 PM, Kunihiko Hayashi wrote:

Hi Marek,


Hi,


Sorry for rate reply.


No worries, same here.


On 2021/05/25 16:35, Marek Vasut wrote:

On 5/12/21 4:09 PM, Kunihiko Hayashi wrote:

When CONFIG_ENV_IS_NOWHERE is enabled, env_nowhere_init() sets ENV_INVALID
to gd->env_valid, and sets default_environment before relocation to
gd->env_addr. After that, env_init() switches gd->env_valid to ENV_VALID
by the previous fix.

If gd->env_valid is ENV_INVALID, env_get_char() returns relocated
default_environment, however, env_get_char() returns gd->env_addr before
relocation since gd->env_valid is ENV_VALID, and access to gd->env_addr
will cause a fault.

This leaves gd->env_valid as ENV_INVALID for "nowhere" location.


So do I understand this correctly that _after_ relocation, env_init() is
called and env_init() does not update gd->env_addr to the relocated one?


In my understandings, env_init() belongs to init_sequence_f[]
and env_init() is called before relocation.


You're right.

So the env update after relocation should then be done in env_relocate().


Yes. I understand that the relocated gd->env_addr is used in env_relocate().


I would expect that after relocation, if all you have is env_nowhere
driver, the env_nowhere_init() is called again from the first for() loop
of env_init() [1], which would set gd->env_valid to ENV_INVALID [1], and
that for() loop would exit with ret = -ENOENT [2], so then the last part
of env_init() would check for ret == -ENOENT and update gd->env_addr to
relocated default_environment [3].

324  int env_init(void)
325  {
326    struct env_driver *drv;
327    int ret = -ENOENT;
328    int prio;
329
330    for (prio = 0; (drv = env_driver_lookup(ENVOP_INIT, prio)); prio++) {
   /* Part [1] */
331  if (!drv->init || !(ret = drv->init()))
332    env_set_inited(drv->location);
333  if (ret == -ENOENT)
334    env_set_inited(drv->location);
335
336  debug("%s: Environment %s init done (ret=%d)\n", __func__,
337    drv->name, ret);
338
   /* Part [2] */
339  if (gd->env_valid == ENV_INVALID)
340    ret = -ENOENT;
341    }
342
343    if (!prio)
344  return -ENODEV;
345
 /* Part [3] */
346    if (ret == -ENOENT) {
   /* This should be relocated default_environment address */
347  gd->env_addr = (ulong)_environment[0];
348  gd->env_valid = ENV_VALID;
349
350  return 0;
351    }
352
353    return ret;
354  }

Or am I missing something obvious ?


These are called before relocation, and update gd->env_addr to non-relocated
default_environment by [3].

After that, gd->env_addr is relocated in initr_reloc_global_data()
if CONFIG_SYS_RELOC_GD_ENV_ADDR is defined.

| #ifdef CONFIG_SYS_RELOC_GD_ENV_ADDR
| /*
|  * Relocate the early env_addr pointer unless we know it is not inside
|  * the binary. Some systems need this and for the rest, it doesn't hurt.
|  */
| gd->env_addr += gd->reloc_off;
| #endif



Shouldn't the post-relocation env update happen in env_relocate() ?


Usually env_relocate() calls env_load() that uses relocated gd->env_addr.
It's no problem.

If CONFIG_SYS_TEXT_BASE is zero, gd->reloc_off becomes illegal.
CONFIG_SYS_RELOC_GD_ENV_ADDR should be disabled in that case.

>

However, I misunderstood my situation.
gd->reloc_off doesn't have the proper value because CONFIG_SYS_TEXT_BASE
is zero due to CONFIG_POSITION_INDENENDENT=y.

gd->reloc_off is calculated with CONFIG_SYS_TEXT_BASE in setup_reloc().

| gd->reloc_off = gd->relocaddr - CONFIG_SYS_TEXT_BASE;

gd->env_addr is added with gd->reloc_off (== gd->relocaddr - 0),
as a result, gd->env_addr has wrong address.

In this case, I think the proper solution is to undefine
CONFIG_SYS_RELOC_GD_ENV_ADDR.

My patch isn't necessary no longer and your patch also works with
"nowhere".

OK


Thank you,

---
Best Regards
Kunihiko Hayashi


Re: [PATCH] env: Leave invalid env for nowhere location

2021-06-03 Thread Kunihiko Hayashi

Hi Marek,
Sorry for rate reply.

On 2021/05/25 16:35, Marek Vasut wrote:

On 5/12/21 4:09 PM, Kunihiko Hayashi wrote:

When CONFIG_ENV_IS_NOWHERE is enabled, env_nowhere_init() sets ENV_INVALID
to gd->env_valid, and sets default_environment before relocation to
gd->env_addr. After that, env_init() switches gd->env_valid to ENV_VALID
by the previous fix.

If gd->env_valid is ENV_INVALID, env_get_char() returns relocated
default_environment, however, env_get_char() returns gd->env_addr before
relocation since gd->env_valid is ENV_VALID, and access to gd->env_addr
will cause a fault.

This leaves gd->env_valid as ENV_INVALID for "nowhere" location.


So do I understand this correctly that _after_ relocation, env_init() is
called and env_init() does not update gd->env_addr to the relocated one?


In my understandings, env_init() belongs to init_sequence_f[]
and env_init() is called before relocation.


I would expect that after relocation, if all you have is env_nowhere
driver, the env_nowhere_init() is called again from the first for() loop
of env_init() [1], which would set gd->env_valid to ENV_INVALID [1], and
that for() loop would exit with ret = -ENOENT [2], so then the last part
of env_init() would check for ret == -ENOENT and update gd->env_addr to
relocated default_environment [3].

324  int env_init(void)
325  {
326struct env_driver *drv;
327int ret = -ENOENT;
328int prio;
329
330for (prio = 0; (drv = env_driver_lookup(ENVOP_INIT, prio)); prio++) {
   /* Part [1] */
331  if (!drv->init || !(ret = drv->init()))
332env_set_inited(drv->location);
333  if (ret == -ENOENT)
334env_set_inited(drv->location);
335
336  debug("%s: Environment %s init done (ret=%d)\n", __func__,
337drv->name, ret);
338
   /* Part [2] */
339  if (gd->env_valid == ENV_INVALID)
340ret = -ENOENT;
341}
342
343if (!prio)
344  return -ENODEV;
345
 /* Part [3] */
346if (ret == -ENOENT) {
   /* This should be relocated default_environment address */
347  gd->env_addr = (ulong)_environment[0];
348  gd->env_valid = ENV_VALID;
349
350  return 0;
351}
352
353return ret;
354  }

Or am I missing something obvious ?


These are called before relocation, and update gd->env_addr to non-relocated
default_environment by [3].

After that, gd->env_addr is relocated in initr_reloc_global_data()
if CONFIG_SYS_RELOC_GD_ENV_ADDR is defined.

| #ifdef CONFIG_SYS_RELOC_GD_ENV_ADDR
|   /*
|* Relocate the early env_addr pointer unless we know it is not inside
|* the binary. Some systems need this and for the rest, it doesn't hurt.
|*/
|   gd->env_addr += gd->reloc_off;
| #endif


However, I misunderstood my situation.
gd->reloc_off doesn't have the proper value because CONFIG_SYS_TEXT_BASE
is zero due to CONFIG_POSITION_INDENENDENT=y.

gd->reloc_off is calculated with CONFIG_SYS_TEXT_BASE in setup_reloc().

|   gd->reloc_off = gd->relocaddr - CONFIG_SYS_TEXT_BASE;

gd->env_addr is added with gd->reloc_off (== gd->relocaddr - 0),
as a result, gd->env_addr has wrong address.

In this case, I think the proper solution is to undefine
CONFIG_SYS_RELOC_GD_ENV_ADDR.

My patch isn't necessary no longer and your patch also works with
"nowhere".

Thank you,

---
Best Regards
Kunihiko Hayashi


Re: [PATCH] env: Leave invalid env for nowhere location

2021-05-25 Thread Kunihiko Hayashi

Hi Tim,

How about this fix?

You already tested Marek's patch, and I'd like to hear your comment
about this patch, or know whether it occurs the issue with
CONFIG_ENV_IS_NOWHERE if possible.

Thank you,

On 2021/05/17 2:19, Marek Vasut wrote:

On 5/12/21 4:09 PM, Kunihiko Hayashi wrote:

When CONFIG_ENV_IS_NOWHERE is enabled, env_nowhere_init() sets ENV_INVALID
to gd->env_valid, and sets default_environment before relocation to
gd->env_addr. After that, env_init() switches gd->env_valid to ENV_VALID
by the previous fix.

If gd->env_valid is ENV_INVALID, env_get_char() returns relocated
default_environment, however, env_get_char() returns gd->env_addr before
relocation since gd->env_valid is ENV_VALID, and access to gd->env_addr
will cause a fault.

This leaves gd->env_valid as ENV_INVALID for "nowhere" location.

Cc: Marek Vasut 
Fixes: 5557eec01cbf ("env: Fix invalid env handling in env_init()")
Signed-off-by: Kunihiko Hayashi 
---
   env/env.c | 3 ++-
   1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/env/env.c b/env/env.c
index e534008..3233172 100644
--- a/env/env.c
+++ b/env/env.c
@@ -336,7 +336,8 @@ int env_init(void)
debug("%s: Environment %s init done (ret=%d)\n", __func__,
  drv->name, ret);
   
-		if (gd->env_valid == ENV_INVALID)

+   if (gd->env_valid == ENV_INVALID
+   && drv->location != ENVL_NOWHERE)
ret = -ENOENT;
}


I'm CCing Tim, it would be good to get a TB from him.



---
Best Regards
Kunihiko Hayashi


[PATCH] usb: dwc3-generic: Disable host driver definition if gadget only

2021-05-12 Thread Kunihiko Hayashi
Even if only USB gadget is defined, dwc3 generic driver enables
a definition and probe/remove functions for host driver.

This enables the definition if USB_HOST is enabled only.

Signed-off-by: Kunihiko Hayashi 
---
 drivers/usb/dwc3/dwc3-generic.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
index 30f835e..c8bf4ae 100644
--- a/drivers/usb/dwc3/dwc3-generic.c
+++ b/drivers/usb/dwc3/dwc3-generic.c
@@ -163,7 +163,8 @@ U_BOOT_DRIVER(dwc3_generic_peripheral) = {
 };
 #endif
 
-#if defined(CONFIG_SPL_USB_HOST_SUPPORT) || !defined(CONFIG_SPL_BUILD)
+#if defined(CONFIG_SPL_USB_HOST_SUPPORT) || \
+   !defined(CONFIG_SPL_BUILD) && defined(CONFIG_USB_HOST)
 static int dwc3_generic_host_probe(struct udevice *dev)
 {
struct xhci_hcor *hcor;
-- 
2.7.4



[PATCH] env: Leave invalid env for nowhere location

2021-05-12 Thread Kunihiko Hayashi
When CONFIG_ENV_IS_NOWHERE is enabled, env_nowhere_init() sets ENV_INVALID
to gd->env_valid, and sets default_environment before relocation to
gd->env_addr. After that, env_init() switches gd->env_valid to ENV_VALID
by the previous fix.

If gd->env_valid is ENV_INVALID, env_get_char() returns relocated
default_environment, however, env_get_char() returns gd->env_addr before
relocation since gd->env_valid is ENV_VALID, and access to gd->env_addr
will cause a fault.

This leaves gd->env_valid as ENV_INVALID for "nowhere" location.

Cc: Marek Vasut 
Fixes: 5557eec01cbf ("env: Fix invalid env handling in env_init()")
Signed-off-by: Kunihiko Hayashi 
---
 env/env.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/env/env.c b/env/env.c
index e534008..3233172 100644
--- a/env/env.c
+++ b/env/env.c
@@ -336,7 +336,8 @@ int env_init(void)
debug("%s: Environment %s init done (ret=%d)\n", __func__,
  drv->name, ret);
 
-   if (gd->env_valid == ENV_INVALID)
+   if (gd->env_valid == ENV_INVALID
+   && drv->location != ENVL_NOWHERE)
ret = -ENOENT;
}
 
-- 
2.7.4



  1   2   >