I'm adding support [1] for another zynq-based board (MYIR Zturn [2]).

This board has one peculiarity that I have to deal with: it has a shared reset
signal that hits both the USB PHY and the Ethernet PHY, and this is routed to
a GPIO that must be shaken down and up before using those two pheripherals
(especially USB) in order to make things working.

This must be done before the two ethernet and USB drivers probes, so I couldn't
delegate this to any of the twos..

Right now I added a top-level node "board" to my DT containing the GPIO property
and I handle this in the board initialization code.

        board {
                phys-reset-gpio = <&gpio0 51 GPIO_ACTIVE_LOW>;
        };

RFC: is this a good/clean way to handle this thing? Ideally I would like to
put this mechanism out of the Zynq-specific board file, so that it could be
available for any kind of board..

(once a clean way to handle this thing have been agreed I'll rebase and I'll
post a patch serie for adding support for that board).

[1] https://github.com/andreamerello/u-boot-zynq
[2] http://www.myirtech.com/list.asp?id=502

Signed-off-by: Andrea Merello <andrea.mere...@gmail.com>
Cc: Michal Simek <mon...@monstr.eu>

diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c
index 183f642..f72b219 100644
--- a/board/xilinx/zynq/board.c
+++ b/board/xilinx/zynq/board.c
@@ -11,6 +11,7 @@
 #include <zynqpl.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/sys_proto.h>
+#include <asm/gpio.h>

 DECLARE_GLOBAL_DATA_PTR;

@@ -70,8 +71,43 @@ int board_init(void)
        return 0;
 }

+int phys_reset(void)
+{
+       struct gpio_desc reset_gpio;
+       int nodeoffset;
+       const void *blob = gd->fdt_blob;
+
+       nodeoffset = fdt_path_offset(blob, "/board");
+       if (nodeoffset == -FDT_ERR_NOTFOUND)
+               return 0;
+       if (nodeoffset < 0)
+               return nodeoffset;
+
+       gpio_request_by_name_nodev(blob, nodeoffset, "phys-reset-gpio", 0,
+                                  &reset_gpio, 0);
+
+       if (dm_gpio_is_valid(&reset_gpio)) {
+               /* reset PHYs (ethernet and USB) before any driver comes up */
+               dm_gpio_set_dir_flags(&reset_gpio, reset_gpio.flags |
+                               GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
+
+               mdelay(100);
+               dm_gpio_set_dir_flags(&reset_gpio, (reset_gpio.flags |
+                               GPIOD_IS_OUT) & ~GPIOD_IS_OUT_ACTIVE);
+
+               /* wait for PHYs to come up before going on */
+               mdelay(100);
+
+               printf("PHYs reset OK\n");
+       }
+
+       return 0;
+}
+
 int board_late_init(void)
 {
+       phys_reset();
+
        switch ((zynq_slcr_get_boot_mode()) & ZYNQ_BM_MASK) {
        case ZYNQ_BM_NOR:
                setenv("modeboot", "norboot");
--
2.1.4
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to