On 17.08.2018 12:58, Marek Behún wrote:
Patch Linux's device tree according to which Mox modules are connected.
Linux's device tree is supposed to have some nodes already
preprogrammed. If user wants to use different device tree, they should
disable CONFIG_OF_BOARD_SETUP in U-Boot's config, so that the boot
command does not fail.

Signed-off-by: Marek Behun <marek.be...@nic.cz>
---
  board/CZ.NIC/turris_mox/turris_mox.c | 222 +++++++++++++++++++++++++++++++++++
  configs/turris_mox_defconfig         |   1 +
  2 files changed, 223 insertions(+)

diff --git a/board/CZ.NIC/turris_mox/turris_mox.c 
b/board/CZ.NIC/turris_mox/turris_mox.c
index 21a3e63864..3361579d7c 100644
--- a/board/CZ.NIC/turris_mox/turris_mox.c
+++ b/board/CZ.NIC/turris_mox/turris_mox.c
@@ -3,6 +3,7 @@
   * Copyright (C) 2018 Marek Behun <marek.be...@nic.cz>
   */
+#include <stdarg.h>
  #include <common.h>
  #include <asm/gpio.h>
  #include <asm/io.h>
@@ -34,7 +35,11 @@
  #define ARMADA_37XX_SPI_DOUT  0xd0010608
  #define ARMADA_37XX_SPI_DIN   0xd001060c
+#define ETH1_PATH "/soc/internal-regs@d0000000/ethernet@40000"
+#define MDIO_PATH      "/soc/internal-regs@d0000000/mdio@32004"
+#define MOXTET_SFP_PATH        
"/soc/internal-regs@d0000000/spi@10600/moxtet@1/moxtet-sfp@0"
  #define PCIE_PATH     "/soc/pcie@d0070000"
+#define SFP_PATH       "/sfp"
typedef enum {
        MOX_UNKNOWN,
@@ -530,3 +535,220 @@ int last_stage_init(void)
return 0;
  }
+
+#if defined(CONFIG_OF_BOARD_SETUP)
+
+static int vnode_by_path(void *blob, const char *fmt, va_list ap)
+{
+       char path[128];
+
+       vsprintf(path, fmt, ap);
+       return fdt_path_offset(blob, path);
+}
+
+static int node_by_path(void *blob, const char *fmt, ...)
+{
+       va_list ap;
+       int res;
+
+       va_start(ap, fmt);
+       res = vnode_by_path(blob, fmt, ap);
+       va_end(ap);
+
+       return res;
+}
+
+static int phandle_by_path(void *blob, const char *fmt, ...)
+{
+       va_list ap;
+       int node, phandle, res;
+
+       va_start(ap, fmt);
+       node = vnode_by_path(blob, fmt, ap);
+       va_end(ap);
+
+       if (node < 0)
+               return node;
+
+       phandle = fdt_get_phandle(blob, node);
+       if (phandle > 0)
+               return phandle;
+
+       phandle = fdt_get_max_phandle(blob);
+       if (phandle < 0)
+               return phandle;
+
+       phandle += 1;
+
+       res = fdt_setprop_u32(blob, node, "linux,phandle", phandle);
+       if (res < 0)
+               return res;
+
+       res = fdt_setprop_u32(blob, node, "phandle", phandle);
+       if (res < 0)
+               return res;
+
+       return phandle;
+}
+
+static int enable_by_path(void *blob, const char *fmt, ...)
+{
+       va_list ap;
+       int node;
+
+       va_start(ap, fmt);
+       node = vnode_by_path(blob, fmt, ap);
+       va_end(ap);
+
+       if (node < 0)
+               return node;
+
+       return fdt_setprop_string(blob, node, "status", "okay");
+}
+
+static bool is_topaz(int id)
+{
+       return topaz && id == peridot + topaz - 1;
+}
+
+static int switch_addr(int id)
+{
+       return is_topaz(id) ? 0x2 : 0x10 + id;
+}
+
+static int setup_switch(void *blob, int id)
+{
+       int res, addr, i, node, phandle;
+
+       addr = switch_addr(id);
+
+       /* first enable the switch by setting status = "okay" */
+       res = enable_by_path(blob, MDIO_PATH "/switch%i@%x", id, addr);
+       if (res < 0)
+               return res;
+
+       /*
+        * now if there are more switches or a SFP module coming after,
+        * enable corresponding ports
+        */
+       if (id < peridot + topaz - 1)
+               res = enable_by_path(blob,
+                                    MDIO_PATH "/switch%i@%x/ports/port@a",
+                                    id, addr);
+       else if (id == peridot - 1 && !topaz && sfp)
+               res = enable_by_path(blob,
+                                    MDIO_PATH "/switch%i@%x/ports/port-sfp@a",
+                                    id, addr);
+       else
+               res = 0;
+       if (res < 0)
+               return res;
+
+       if (id >= peridot + topaz - 1)
+               return 0;
+
+       /* finally change link property if needed */
+       node = node_by_path(blob, MDIO_PATH "/switch%i@%x/ports/port@a", id,
+                           addr);
+       if (node < 0)
+               return node;
+
+       for (i = id + 1; i < peridot + topaz; ++i) {
+               phandle = phandle_by_path(blob,
+                                         MDIO_PATH 
"/switch%i@%x/ports/port@%x",
+                                         i, switch_addr(i),
+                                         is_topaz(i) ? 5 : 9);
+               if (phandle < 0)
+                       return phandle;
+
+               if (i == id + 1)
+                       res = fdt_setprop_u32(blob, node, "link", phandle);
+               else
+                       res = fdt_appendprop_u32(blob, node, "link", phandle);
+               if (res < 0)
+                       return res;
+       }
+
+       return 0;
+}
+
+int ft_board_setup(void *blob, bd_t *bd)
+{
+       int node, phandle, res;
+
+       if (pci || usb) {
+               node = fdt_path_offset(blob, PCIE_PATH);
+               if (node < 0)
+                       return node;
+
+               res = fdt_setprop_string(blob, node, "status", "okay");
+               if (res < 0)
+                       return res;
+       }
+
+       if (peridot || topaz) {
+               int i;
+
+               res = enable_by_path(blob, ETH1_PATH);
+               if (res < 0)
+                       return res;
+
+               for (i = 0; i < peridot + topaz; ++i) {
+                       res = setup_switch(blob, i);
+                       if (res < 0)
+                               return res;
+               }
+       }
+
+       if (sfp) {
+               res = enable_by_path(blob, SFP_PATH);
+               if (res < 0)
+                       return res;
+
+               if (!peridot) {
+                       phandle = phandle_by_path(blob, SFP_PATH);
+                       if (phandle < 0)
+                               return res;
+
+                       node = node_by_path(blob, ETH1_PATH);
+                       if (node < 0)
+                               return node;
+
+                       res = fdt_setprop_u32(blob, node, "sfp", phandle);
+                       if (res < 0)
+                               return res;
+
+                       res = fdt_setprop_string(blob, node, "phy-mode",
+                                                "sgmii");
+                       if (res < 0)
+                               return res;
+               }
+
+               res = enable_by_path(blob, MOXTET_SFP_PATH);
+               if (res < 0)
+                       return res;
+
+               if (sfp_pos) {
+                       char newname[16];
+
+                       /* moxtet-sfp is on non-zero position, change default */
+                       node = node_by_path(blob, MOXTET_SFP_PATH);
+                       if (node < 0)
+                               return node;
+
+                       res = fdt_setprop_u32(blob, node, "reg", sfp_pos);
+                       if (res < 0)
+                               return res;
+
+                       sprintf(newname, "moxtet-sfp@%x", sfp_pos);
+
+                       res = fdt_set_name(blob, node, newname);
+                       if (res < 0)
+                               return res;
+               }
+       }
+
+       return 0;
+}
+
+#endif
diff --git a/configs/turris_mox_defconfig b/configs/turris_mox_defconfig
index 1dd6826dbc..fb4192df56 100644
--- a/configs/turris_mox_defconfig
+++ b/configs/turris_mox_defconfig
@@ -14,6 +14,7 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y
  # CONFIG_DISPLAY_BOARDINFO is not set
  CONFIG_ARCH_EARLY_INIT_R=y
  CONFIG_OF_BOARD_FIXUP=y
+CONFIG_OF_BOARD_SETUP=y
  CONFIG_CMD_CLK=y
  # CONFIG_CMD_FLASH is not set
  CONFIG_CMD_I2C=y


This patch does not apply currently. I'm skipping it from this
series for now. I'm currently pushing my Marvell branch upstream
and would like to get the first batch of patches accepted. After
Tom has pulled these patches, please rebase on top of this new
master.

Thanks,
Stefan
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to