get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/1415017/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 1415017,
    "url": "http://patchwork.ozlabs.org/api/patches/1415017/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/uboot/patch/20201211160612.1498780-49-sr@denx.de/",
    "project": {
        "id": 18,
        "url": "http://patchwork.ozlabs.org/api/projects/18/?format=api",
        "name": "U-Boot",
        "link_name": "uboot",
        "list_id": "u-boot.lists.denx.de",
        "list_email": "u-boot@lists.denx.de",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20201211160612.1498780-49-sr@denx.de>",
    "list_archive_url": null,
    "date": "2020-12-11T16:06:10",
    "name": "[v1,48/50] mips: octeon: octeon_ebb7304: Add board specific QLM init code",
    "commit_ref": "6a453e50c36f99ed5b8488eb07e82ece375805df",
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "11f4c145604f5f4674c655839e0a42867a47bfa3",
    "submitter": {
        "id": 13,
        "url": "http://patchwork.ozlabs.org/api/people/13/?format=api",
        "name": "Stefan Roese",
        "email": "sr@denx.de"
    },
    "delegate": {
        "id": 4307,
        "url": "http://patchwork.ozlabs.org/api/users/4307/?format=api",
        "username": "danielschwierzeck",
        "first_name": "Daniel",
        "last_name": "Schwierzeck",
        "email": "daniel.schwierzeck@googlemail.com"
    },
    "mbox": "http://patchwork.ozlabs.org/project/uboot/patch/20201211160612.1498780-49-sr@denx.de/mbox/",
    "series": [
        {
            "id": 220054,
            "url": "http://patchwork.ozlabs.org/api/series/220054/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/uboot/list/?series=220054",
            "date": "2020-12-11T16:05:23",
            "name": "mips: octeon: Add serdes and device helper support incl. DM PCIe driver",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/220054/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/1415017/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/1415017/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<u-boot-bounces@lists.denx.de>",
        "X-Original-To": "incoming@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming@bilbo.ozlabs.org",
        "Authentication-Results": [
            "ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de\n (client-ip=85.214.62.61; helo=phobos.denx.de;\n envelope-from=u-boot-bounces@lists.denx.de; receiver=<UNKNOWN>)",
            "ozlabs.org;\n dmarc=none (p=none dis=none) header.from=denx.de",
            "ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=denx.de header.i=@denx.de header.a=rsa-sha256\n header.s=phobos-20191101 header.b=gmRtLXks;\n\tdkim-atps=neutral",
            "phobos.denx.de;\n dmarc=none (p=none dis=none) header.from=denx.de",
            "phobos.denx.de;\n spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de",
            "phobos.denx.de;\n dmarc=none (p=none dis=none) header.from=denx.de",
            "phobos.denx.de; spf=none smtp.mailfrom=sr@denx.de"
        ],
        "Received": [
            "from phobos.denx.de (phobos.denx.de [85.214.62.61])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange X25519 server-signature RSA-PSS (4096 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 4Cswpt5RvSz9sSs\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 12 Dec 2020 03:14:46 +1100 (AEDT)",
            "from h2850616.stratoserver.net (localhost [IPv6:::1])\n\tby phobos.denx.de (Postfix) with ESMTP id BE0BF827B6;\n\tFri, 11 Dec 2020 17:09:24 +0100 (CET)",
            "by phobos.denx.de (Postfix, from userid 109)\n id A2865827BC; Fri, 11 Dec 2020 17:08:41 +0100 (CET)",
            "from mx2.mailbox.org (mx2.mailbox.org [80.241.60.215])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))\n (No client certificate requested)\n by phobos.denx.de (Postfix) with ESMTPS id D6DD182774\n for <u-boot@lists.denx.de>; Fri, 11 Dec 2020 17:06:31 +0100 (CET)",
            "from smtp1.mailbox.org (smtp1.mailbox.org\n [IPv6:2001:67c:2050:105:465:1:1:0])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest\n SHA256) (No client certificate requested)\n by mx2.mailbox.org (Postfix) with ESMTPS id 73B3DA0E1F;\n Fri, 11 Dec 2020 17:06:31 +0100 (CET)",
            "from smtp1.mailbox.org ([80.241.60.240])\n by spamfilter05.heinlein-hosting.de (spamfilter05.heinlein-hosting.de\n [80.241.56.123]) (amavisd-new, port 10030)\n with ESMTP id 42qCErRh585A; Fri, 11 Dec 2020 17:06:27 +0100 (CET)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=denx.de;\n\ts=phobos-20191101; t=1607702965;\n\tbh=FgQltuCvdai3ra3olipyRd39EH6+3fKZQivciqjuL7g=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:List-Id:\n\t List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe:\n\t From;\n\tb=gmRtLXksJyEIMHHpETQSt7ECHB5sLti/KHZZNuh0EJ1mlj37CtIZ+AMUSF3dizxux\n\t gzOLHZjkXzrUf3eDpJl3alLTSk2kSjcx1JwkkNG7iADYPhKt/eMIzcMwMGEvR3lsqp\n\t 6MkWVJrP/RqnxQnKvU44d3AT1YyQ2cDmwf4yPEgv5JYpRkRoDXi7WXQJ2zWyBXLnMx\n\t bL1CdQ+NvOyz6cdMrSBWsbhdHgWg4yRVfLlNpoQiO1vbZgBp65JZy2DbeJlg1k99nt\n\t rD/1wJLnBYTCEk6CYHmzZzhHWkfqjYokjUc9s17dvzE7zYSpadueJGIun1feDEWul9\n\t VpR6M7v+TYBSA==",
        "X-Spam-Checker-Version": "SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de",
        "X-Spam-Level": "",
        "X-Spam-Status": "No, score=-2.6 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_LOW,\n SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2",
        "From": "Stefan Roese <sr@denx.de>",
        "To": "u-boot@lists.denx.de",
        "Cc": "daniel.schwierzeck@gmail.com, awilliams@marvell.com, cchavva@marvell.com",
        "Subject": "[PATCH v1 48/50] mips: octeon: octeon_ebb7304: Add board specific QLM\n init code",
        "Date": "Fri, 11 Dec 2020 17:06:10 +0100",
        "Message-Id": "<20201211160612.1498780-49-sr@denx.de>",
        "In-Reply-To": "<20201211160612.1498780-1-sr@denx.de>",
        "References": "<20201211160612.1498780-1-sr@denx.de>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "X-MBO-SPAM-Probability": "",
        "X-Rspamd-Score": "-0.76 / 15.00 / 15.00",
        "X-Rspamd-Queue-Id": "6A6E81868",
        "X-Rspamd-UID": "7e37a2",
        "X-BeenThere": "u-boot@lists.denx.de",
        "X-Mailman-Version": "2.1.34",
        "Precedence": "list",
        "List-Id": "U-Boot discussion <u-boot.lists.denx.de>",
        "List-Unsubscribe": "<https://lists.denx.de/options/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=unsubscribe>",
        "List-Archive": "<https://lists.denx.de/pipermail/u-boot/>",
        "List-Post": "<mailto:u-boot@lists.denx.de>",
        "List-Help": "<mailto:u-boot-request@lists.denx.de?subject=help>",
        "List-Subscribe": "<https://lists.denx.de/listinfo/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=subscribe>",
        "Errors-To": "u-boot-bounces@lists.denx.de",
        "Sender": "\"U-Boot\" <u-boot-bounces@lists.denx.de>",
        "X-Virus-Scanned": "clamav-milter 0.102.3 at phobos.denx.de",
        "X-Virus-Status": "Clean"
    },
    "content": "From: Aaron Williams <awilliams@marvell.com>\n\nThis patch adds the board specific QLM/DLM init code to the Octeon 3\nEBB7304 board. The configuration of each port is read from the\nenvironment exactly as done in the 2013 U-Boot version to keep the\nboard and it's configuration compatible.\n\nSigned-off-by: Aaron Williams <awilliams@marvell.com>\nSigned-off-by: Stefan Roese <sr@denx.de>\n---\n\n board/Marvell/octeon_ebb7304/board.c | 732 ++++++++++++++++++++++++++-\n 1 file changed, 730 insertions(+), 2 deletions(-)",
    "diff": "diff --git a/board/Marvell/octeon_ebb7304/board.c b/board/Marvell/octeon_ebb7304/board.c\nindex 611b18fa6a..9aac5f0b09 100644\n--- a/board/Marvell/octeon_ebb7304/board.c\n+++ b/board/Marvell/octeon_ebb7304/board.c\n@@ -3,20 +3,32 @@\n  * Copyright (C) 2020 Stefan Roese <sr@denx.de>\n  */\n \n-#include <common.h>\n #include <dm.h>\n+#include <fdt_support.h>\n #include <ram.h>\n+#include <asm/gpio.h>\n \n #include <mach/octeon_ddr.h>\n+#include <mach/cvmx-qlm.h>\n+#include <mach/octeon_qlm.h>\n+#include <mach/octeon_fdt.h>\n+#include <mach/cvmx-helper.h>\n+#include <mach/cvmx-helper-cfg.h>\n+#include <mach/cvmx-helper-util.h>\n+#include <mach/cvmx-bgxx-defs.h>\n \n #include \"board_ddr.h\"\n \n+#define MAX_MIX_ENV_VARS\t4\n+\n #define EBB7304_DEF_DRAM_FREQ\t800\n \n static struct ddr_conf board_ddr_conf[] = {\n-\t OCTEON_EBB7304_DDR_CONFIGURATION\n+\tOCTEON_EBB7304_DDR_CONFIGURATION\n };\n \n+static int no_phy[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };\n+\n struct ddr_conf *octeon_ddr_conf_table_get(int *count, int *def_ddr_freq)\n {\n \t*count = ARRAY_SIZE(board_ddr_conf);\n@@ -24,3 +36,719 @@ struct ddr_conf *octeon_ddr_conf_table_get(int *count, int *def_ddr_freq)\n \n \treturn board_ddr_conf;\n }\n+\n+/*\n+ * parse_env_var:\tParse the environment variable (\"bgx_for_mix%d\") to\n+ *\t\t\textract the lmac it is set to.\n+ *\n+ *  index:\t\tIndex of environment variable to parse.\n+ *\t\t\tenvironment variable.\n+ *  env_bgx:\t\tUpdated with the bgx of the lmac in the environment\n+ *\t\t\tvariable.\n+ *  env_lmac:\t\tUpdated with the index of lmac in the environment\n+ *\t\t\tvariable.\n+ *\n+ *  returns:\t\tZero on success, error otherwise.\n+ */\n+static int parse_env_var(int index, int *env_bgx, int *env_lmac)\n+{\n+\tchar env_var[20];\n+\tulong xipd_port;\n+\n+\tsprintf(env_var, \"bgx_for_mix%d\", index);\n+\txipd_port = env_get_ulong(env_var, 0, 0xffff);\n+\tif (xipd_port != 0xffff) {\n+\t\tint xiface;\n+\t\tstruct cvmx_xiface xi;\n+\t\tstruct cvmx_xport xp;\n+\n+\t\t/*\n+\t\t * The environemt variable is set to the xipd port. Convert the\n+\t\t * xipd port to numa node, bgx, and lmac.\n+\t\t */\n+\t\txiface = cvmx_helper_get_interface_num(xipd_port);\n+\t\txi = cvmx_helper_xiface_to_node_interface(xiface);\n+\t\txp = cvmx_helper_ipd_port_to_xport(xipd_port);\n+\t\t*env_bgx = xi.interface;\n+\t\t*env_lmac = cvmx_helper_get_interface_index_num(xp.port);\n+\t\treturn 0;\n+\t}\n+\n+\treturn -1;\n+}\n+\n+/*\n+ * get_lmac_fdt_node:\tSearch the device tree for the node corresponding to\n+ *\t\t\ta given bgx lmac.\n+ *\n+ *  fdt:\t\tPointer to flat device tree\n+ *  search_node:\tNuma node of the lmac to search for.\n+ *  search_bgx:\t\tBgx of the lmac to search for.\n+ *  search_lmac:\tLmac index to search for.\n+ *  compat:\t\tCompatible string to search for.\n+\n+ *  returns:\t\tThe device tree node of the lmac if found,\n+ *\t\t\tor -1 otherwise.\n+ */\n+static int get_lmac_fdt_node(const void *fdt, int search_node, int search_bgx, int search_lmac,\n+\t\t\t     const char *compat)\n+{\n+\tint node;\n+\tconst fdt32_t *reg;\n+\tu64 addr;\n+\tint fdt_node = -1;\n+\tint fdt_bgx = -1;\n+\tint fdt_lmac = -1;\n+\tint len;\n+\tint parent;\n+\n+\t/* Iterate through all bgx ports */\n+\tnode = -1;\n+\twhile ((node = fdt_node_offset_by_compatible((void *)fdt, node,\n+\t\t\t\t\t\t     compat)) >= 0) {\n+\t\t/* Get the node and bgx from the physical address */\n+\t\tparent = fdt_parent_offset(fdt, node);\n+\t\treg = fdt_getprop(fdt, parent, \"reg\", &len);\n+\t\tif (parent < 0 || !reg)\n+\t\t\tcontinue;\n+\n+\t\taddr = fdt_translate_address((void *)fdt, parent, reg);\n+\t\tfdt_node = (addr >> 36) & 0x7;\n+\t\tfdt_bgx = (addr >> 24) & 0xf;\n+\n+\t\t/* Get the lmac index from the reg property */\n+\t\treg = fdt_getprop(fdt, node, \"reg\", &len);\n+\t\tif (reg)\n+\t\t\tfdt_lmac = *reg;\n+\n+\t\t/* Check for a match */\n+\t\tif (search_node == fdt_node && search_bgx == fdt_bgx &&\n+\t\t    search_lmac == fdt_lmac)\n+\t\t\treturn node;\n+\t}\n+\n+\treturn -1;\n+}\n+\n+/*\n+ * get_mix_fdt_node:\tSearch the device tree for the node corresponding to\n+ *\t\t\ta given mix.\n+ *\n+ *  fdt:\t\tPointer to flat device tree\n+ *  search_node:\tMix numa node to search for.\n+ *  search_index:\tMix index to search for.\n+ *\n+ *  returns:\t\tThe device tree node of the lmac if found,\n+ *\t\t\tor -1 otherwise.\n+ */\n+static int get_mix_fdt_node(const void *fdt, int search_node, int search_index)\n+{\n+\tint node;\n+\n+\t/* Iterate through all the mix fdt nodes */\n+\tnode = -1;\n+\twhile ((node = fdt_node_offset_by_compatible((void *)fdt, node,\n+\t\t\t\t\t\t     \"cavium,octeon-7890-mix\")) >= 0) {\n+\t\tint parent;\n+\t\tint len;\n+\t\tconst char *name;\n+\t\tint mix_numa_node;\n+\t\tconst fdt32_t *reg;\n+\t\tint mix_index = -1;\n+\t\tu64 addr;\n+\n+\t\t/* Get the numa node of the mix from the parent node name */\n+\t\tparent = fdt_parent_offset(fdt, node);\n+\t\tif (parent < 0 ||\n+\t\t    ((name = fdt_get_name(fdt, parent, &len)) == NULL) ||\n+\t\t    ((name = strchr(name, '@')) == NULL))\n+\t\t\tcontinue;\n+\n+\t\tname++;\n+\t\tmix_numa_node = simple_strtol(name, NULL, 0) ? 1 : 0;\n+\n+\t\t/* Get the mix index from the reg property */\n+\t\treg = fdt_getprop(fdt, node, \"reg\", &len);\n+\t\tif (reg) {\n+\t\t\taddr = fdt_translate_address((void *)fdt, parent, reg);\n+\t\t\tmix_index = (addr >> 11) & 1;\n+\t\t}\n+\n+\t\t/* Check for a match */\n+\t\tif (mix_numa_node == search_node && mix_index == search_index)\n+\t\t\treturn node;\n+\t}\n+\n+\treturn -1;\n+}\n+\n+/*\n+ * fdt_fix_mix:\t\tFix the mix nodes in the device tree. Only the mix nodes\n+ *\t\t\tconfigured by the user will be preserved. All other mix\n+ *\t\t\tnodes will be trimmed.\n+ *\n+ *  fdt:\t\tPointer to flat device tree\n+ *\n+ *  returns:\t\tZero on success, error otherwise.\n+ */\n+static int fdt_fix_mix(const void *fdt)\n+{\n+\tint node;\n+\tint next_node;\n+\tint len;\n+\tint i;\n+\n+\t/* Parse all the mix port environment variables */\n+\tfor (i = 0; i < MAX_MIX_ENV_VARS; i++) {\n+\t\tint env_node = 0;\n+\t\tint env_bgx = -1;\n+\t\tint env_lmac = -1;\n+\t\tint lmac_fdt_node = -1;\n+\t\tint mix_fdt_node = -1;\n+\t\tint lmac_phandle;\n+\t\tchar *compat;\n+\n+\t\t/* Get the lmac for this environment variable */\n+\t\tif (parse_env_var(i, &env_bgx, &env_lmac))\n+\t\t\tcontinue;\n+\n+\t\t/* Get the fdt node for this lmac and add a phandle to it */\n+\t\tcompat = \"cavium,octeon-7890-bgx-port\";\n+\t\tlmac_fdt_node = get_lmac_fdt_node(fdt, env_node, env_bgx,\n+\t\t\t\t\t\t  env_lmac, compat);\n+\t\tif (lmac_fdt_node < 0) {\n+\t\t\t/* Must check for the xcv compatible string too */\n+\t\t\tcompat = \"cavium,octeon-7360-xcv\";\n+\t\t\tlmac_fdt_node = get_lmac_fdt_node(fdt, env_node,\n+\t\t\t\t\t\t\t  env_bgx, env_lmac,\n+\t\t\t\t\t\t\t  compat);\n+\t\t\tif (lmac_fdt_node < 0) {\n+\t\t\t\tprintf(\"WARNING: Failed to get lmac fdt node for %d%d%d\\n\",\n+\t\t\t\t       env_node, env_bgx, env_lmac);\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\t\t}\n+\n+\t\tlmac_phandle = fdt_alloc_phandle((void *)fdt);\n+\t\tfdt_set_phandle((void *)fdt, lmac_fdt_node, lmac_phandle);\n+\n+\t\t/* Get the fdt mix node corresponding to this lmac */\n+\t\tmix_fdt_node = get_mix_fdt_node(fdt, env_node, env_lmac);\n+\t\tif (mix_fdt_node < 0)\n+\t\t\tcontinue;\n+\n+\t\t/* Point the mix to the lmac */\n+\t\tfdt_getprop(fdt, mix_fdt_node, \"cavium,mac-handle\", &len);\n+\t\tfdt_setprop_inplace((void *)fdt, mix_fdt_node,\n+\t\t\t\t    \"cavium,mac-handle\", &lmac_phandle, len);\n+\t}\n+\n+\t/* Trim unused mix'es from the device tree */\n+\tfor (node = fdt_next_node(fdt, -1, NULL); node >= 0; node = next_node) {\n+\t\tconst char *compat;\n+\t\tconst fdt32_t *reg;\n+\n+\t\tnext_node = fdt_next_node(fdt, node, NULL);\n+\n+\t\tcompat = fdt_getprop(fdt, node, \"compatible\", &len);\n+\t\tif (compat) {\n+\t\t\tif (strcmp(compat, \"cavium,octeon-7890-mix\"))\n+\t\t\t\tcontinue;\n+\n+\t\t\treg = fdt_getprop(fdt, node, \"cavium,mac-handle\", &len);\n+\t\t\tif (reg) {\n+\t\t\t\tif (*reg == 0xffff)\n+\t\t\t\t\tfdt_nop_node((void *)fdt, node);\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static void kill_fdt_phy(void *fdt, int offset, void *arg)\n+{\n+\tint len, phy_offset;\n+\tconst fdt32_t *php;\n+\tu32 phandle;\n+\n+\tphp = fdt_getprop(fdt, offset, \"phy-handle\", &len);\n+\tif (php && len == sizeof(*php)) {\n+\t\tphandle = fdt32_to_cpu(*php);\n+\t\tfdt_nop_property(fdt, offset, \"phy-handle\");\n+\t\tphy_offset = fdt_node_offset_by_phandle(fdt, phandle);\n+\t\tif (phy_offset > 0)\n+\t\t\tfdt_nop_node(fdt, phy_offset);\n+\t}\n+}\n+\n+void __fixup_xcv(void)\n+{\n+\tunsigned long bgx = env_get_ulong(\"bgx_for_rgmii\", 10,\n+\t\t\t\t\t  (unsigned long)-1);\n+\tchar fdt_key[16];\n+\tint i;\n+\n+\tdebug(\"%s: BGX %d\\n\", __func__, (int)bgx);\n+\n+\tfor (i = 0; i < 3; i++) {\n+\t\tsnprintf(fdt_key, sizeof(fdt_key),\n+\t\t\t bgx == i ? \"%d,xcv\" : \"%d,not-xcv\", i);\n+\t\tdebug(\"%s: trimming bgx %lu with key %s\\n\",\n+\t\t      __func__, bgx, fdt_key);\n+\n+\t\tocteon_fdt_patch_rename((void *)gd->fdt_blob, fdt_key,\n+\t\t\t\t\t\"cavium,xcv-trim\", true, NULL, NULL);\n+\t}\n+}\n+\n+/* QLM0 - QLM6 */\n+void __fixup_fdt(void)\n+{\n+\tint qlm;\n+\tint speed = 0;\n+\n+\tfor (qlm = 0; qlm < 7; qlm++) {\n+\t\tenum cvmx_qlm_mode mode;\n+\t\tchar fdt_key[16];\n+\t\tconst char *type_str = \"none\";\n+\n+\t\tmode = cvmx_qlm_get_mode(qlm);\n+\t\tswitch (mode) {\n+\t\tcase CVMX_QLM_MODE_SGMII:\n+\t\tcase CVMX_QLM_MODE_RGMII_SGMII:\n+\t\tcase CVMX_QLM_MODE_RGMII_SGMII_1X1:\n+\t\t\ttype_str = \"sgmii\";\n+\t\t\tbreak;\n+\t\tcase CVMX_QLM_MODE_XAUI:\n+\t\tcase CVMX_QLM_MODE_RGMII_XAUI:\n+\t\t\tspeed = (cvmx_qlm_get_gbaud_mhz(qlm) * 8 / 10) * 4;\n+\t\t\tif (speed == 10000)\n+\t\t\t\ttype_str = \"xaui\";\n+\t\t\telse\n+\t\t\t\ttype_str = \"dxaui\";\n+\t\t\tbreak;\n+\t\tcase CVMX_QLM_MODE_RXAUI:\n+\t\tcase CVMX_QLM_MODE_RGMII_RXAUI:\n+\t\t\ttype_str = \"rxaui\";\n+\t\t\tbreak;\n+\t\tcase CVMX_QLM_MODE_XLAUI:\n+\t\tcase CVMX_QLM_MODE_RGMII_XLAUI:\n+\t\t\ttype_str = \"xlaui\";\n+\t\t\tbreak;\n+\t\tcase CVMX_QLM_MODE_XFI:\n+\t\tcase CVMX_QLM_MODE_RGMII_XFI:\n+\t\tcase CVMX_QLM_MODE_RGMII_XFI_1X1:\n+\t\t\ttype_str = \"xfi\";\n+\t\t\tbreak;\n+\t\tcase CVMX_QLM_MODE_10G_KR:\n+\t\tcase CVMX_QLM_MODE_RGMII_10G_KR:\n+\t\t\ttype_str = \"10G_KR\";\n+\t\t\tbreak;\n+\t\tcase CVMX_QLM_MODE_40G_KR4:\n+\t\tcase CVMX_QLM_MODE_RGMII_40G_KR4:\n+\t\t\ttype_str = \"40G_KR4\";\n+\t\t\tbreak;\n+\t\tcase CVMX_QLM_MODE_SATA_2X1:\n+\t\t\ttype_str = \"sata\";\n+\t\t\tbreak;\n+\t\tcase CVMX_QLM_MODE_SGMII_2X1:\n+\t\tcase CVMX_QLM_MODE_XFI_1X2:\n+\t\tcase CVMX_QLM_MODE_10G_KR_1X2:\n+\t\tcase CVMX_QLM_MODE_RXAUI_1X2:\n+\t\tcase CVMX_QLM_MODE_MIXED: // special for DLM5 & DLM6\n+\t\t{\n+\t\t\tcvmx_bgxx_cmrx_config_t cmr_config;\n+\t\t\tcvmx_bgxx_spux_br_pmd_control_t pmd_control;\n+\t\t\tint mux = cvmx_qlm_mux_interface(2);\n+\n+\t\t\tif (mux == 2) { // only dlm6\n+\t\t\t\tcmr_config.u64 = csr_rd(CVMX_BGXX_CMRX_CONFIG(2, 2));\n+\t\t\t\tpmd_control.u64 =\n+\t\t\t\t\tcsr_rd(CVMX_BGXX_SPUX_BR_PMD_CONTROL(2, 2));\n+\t\t\t} else {\n+\t\t\t\tif (qlm == 5) {\n+\t\t\t\t\tcmr_config.u64 =\n+\t\t\t\t\t\tcsr_rd(CVMX_BGXX_CMRX_CONFIG(0, 2));\n+\t\t\t\t\tpmd_control.u64 =\n+\t\t\t\t\t\tcsr_rd(CVMX_BGXX_SPUX_BR_PMD_CONTROL(0, 2));\n+\t\t\t\t} else {\n+\t\t\t\t\tcmr_config.u64 =\n+\t\t\t\t\t\tcsr_rd(CVMX_BGXX_CMRX_CONFIG(2, 2));\n+\t\t\t\t\tpmd_control.u64 =\n+\t\t\t\t\t\tcsr_rd(CVMX_BGXX_SPUX_BR_PMD_CONTROL(2, 2));\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tswitch (cmr_config.s.lmac_type) {\n+\t\t\tcase 0:\n+\t\t\t\ttype_str = \"sgmii\";\n+\t\t\t\tbreak;\n+\t\t\tcase 1:\n+\t\t\t\ttype_str = \"xaui\";\n+\t\t\t\tbreak;\n+\t\t\tcase 2:\n+\t\t\t\ttype_str = \"rxaui\";\n+\t\t\t\tbreak;\n+\t\t\tcase 3:\n+\t\t\t\tif (pmd_control.s.train_en)\n+\t\t\t\t\ttype_str = \"10G_KR\";\n+\t\t\t\telse\n+\t\t\t\t\ttype_str = \"xfi\";\n+\t\t\t\tbreak;\n+\t\t\tcase 4:\n+\t\t\t\tif (pmd_control.s.train_en)\n+\t\t\t\t\ttype_str = \"40G_KR4\";\n+\t\t\t\telse\n+\t\t\t\t\ttype_str = \"xlaui\";\n+\t\t\t\tbreak;\n+\t\t\tdefault:\n+\t\t\t\ttype_str = \"none\";\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tbreak;\n+\t\t}\n+\t\tdefault:\n+\t\t\ttype_str = \"none\";\n+\t\t\tbreak;\n+\t\t}\n+\t\tsprintf(fdt_key, \"%d,%s\", qlm, type_str);\n+\t\tdebug(\"Patching qlm %d for %s for mode %d%s\\n\", qlm, fdt_key, mode,\n+\t\t      no_phy[qlm] ? \", removing PHY\" : \"\");\n+\t\tocteon_fdt_patch_rename((void *)gd->fdt_blob, fdt_key, NULL, true,\n+\t\t\t\t\tno_phy[qlm] ? kill_fdt_phy : NULL, NULL);\n+\t}\n+}\n+\n+int board_fix_fdt(void)\n+{\n+\t__fixup_fdt();\n+\t__fixup_xcv();\n+\n+\t/* Fix the mix ports */\n+\tfdt_fix_mix(gd->fdt_blob);\n+\n+\treturn 0;\n+}\n+\n+/*\n+ * Here is the description of the parameters that are passed to QLM\n+ * configuration:\n+ *\n+ *\tparam0 : The QLM to configure\n+ *\tparam1 : Speed to configure the QLM at\n+ *\tparam2 : Mode the QLM to configure\n+ *\tparam3 : 1 = RC, 0 = EP\n+ *\tparam4 : 0 = GEN1, 1 = GEN2, 2 = GEN3\n+ *\tparam5 : ref clock select, 0 = 100Mhz, 1 = 125MHz, 2 = 156MHz\n+ *\tparam6 : ref clock input to use:\n+ *\t\t 0 - external reference (QLMx_REF_CLK)\n+ *\t\t 1 = common clock 0 (QLMC_REF_CLK0)\n+ *\t\t 2 = common_clock 1 (QLMC_REF_CLK1)\n+ */\n+static void board_configure_qlms(void)\n+{\n+\tint speed[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };\n+\tint mode[8] = { -1, -1, -1, -1, -1, -1, -1, -1 };\n+\tint pcie_rc[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };\n+\tint pcie_gen[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };\n+\tint ref_clock_sel[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };\n+\tint ref_clock_input[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };\n+\tstruct gpio_desc desc;\n+\tint rbgx, rqlm;\n+\tchar env_var[16];\n+\tint qlm;\n+\tint ret;\n+\n+\t/* RGMII PHY reset GPIO */\n+\tret = dm_gpio_lookup_name(\"gpio-controllerA27\", &desc);\n+\tif (ret)\n+\t\tdebug(\"gpio ret=%d\\n\", ret);\n+\tret = dm_gpio_request(&desc, \"rgmii_phy_reset\");\n+\tif (ret)\n+\t\tdebug(\"gpio_request ret=%d\\n\", ret);\n+\tret = dm_gpio_set_dir_flags(&desc, GPIOD_IS_OUT);\n+\tif (ret)\n+\t\tdebug(\"gpio dir ret=%d\\n\", ret);\n+\n+\t/* Put RGMII PHY in reset */\n+\tdm_gpio_set_value(&desc, 0);\n+\n+\tocteon_init_qlm(0);\n+\n+\trbgx = env_get_ulong(\"bgx_for_rgmii\", 10, (unsigned long)-1);\n+\tswitch (rbgx) {\n+\tcase 0:\n+\t\trqlm = 2;\n+\t\tbreak;\n+\tcase 1:\n+\t\trqlm = 3;\n+\t\tbreak;\n+\tcase 2:\n+\t\trqlm = 5;\n+\t\tbreak;\n+\tdefault:\n+\t\trqlm = -1;\n+\t\tbreak;\n+\t}\n+\n+\tfor (qlm = 0; qlm < 7; qlm++) {\n+\t\tconst char *mode_str;\n+\t\tchar spd_env[16];\n+\n+\t\tmode[qlm] = CVMX_QLM_MODE_DISABLED;\n+\t\tsprintf(env_var, \"qlm%d_mode\", qlm);\n+\t\tmode_str = env_get(env_var);\n+\t\tif (!mode_str)\n+\t\t\tcontinue;\n+\n+\t\tif (qlm == 4 && mode[4] != -1 &&\n+\t\t    mode[4] != CVMX_QLM_MODE_SATA_2X1) {\n+\t\t\tprintf(\"Error: DLM 4 can only be configured for SATA\\n\");\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tif (strstr(mode_str, \",no_phy\"))\n+\t\t\tno_phy[qlm] = 1;\n+\n+\t\tif (!strncmp(mode_str, \"sgmii\", 5)) {\n+\t\t\tbool rgmii = false;\n+\n+\t\t\tspeed[qlm] = 1250;\n+\t\t\tif (rqlm == qlm && qlm < 5) {\n+\t\t\t\tmode[qlm] = CVMX_QLM_MODE_RGMII_SGMII;\n+\t\t\t\trgmii = true;\n+\t\t\t} else if (qlm == 6 || qlm == 5) {\n+\t\t\t\tif (rqlm == qlm && qlm == 5) {\n+\t\t\t\t\tmode[qlm] = CVMX_QLM_MODE_RGMII_SGMII_1X1;\n+\t\t\t\t\trgmii = true;\n+\t\t\t\t} else if (rqlm == 5 && qlm == 6 &&\n+\t\t\t\t\t   mode[5] != CVMX_QLM_MODE_RGMII_SGMII_1X1) {\n+\t\t\t\t\tmode[qlm] = CVMX_QLM_MODE_RGMII_SGMII_2X1;\n+\t\t\t\t\trgmii = true;\n+\t\t\t\t} else {\n+\t\t\t\t\tmode[qlm] = CVMX_QLM_MODE_SGMII_2X1;\n+\t\t\t\t}\n+\t\t\t} else {\n+\t\t\t\tmode[qlm] = CVMX_QLM_MODE_SGMII;\n+\t\t\t}\n+\t\t\tref_clock_sel[qlm] = 2;\n+\n+\t\t\tif (qlm == 5 || qlm == 6)\n+\t\t\t\tref_clock_input[qlm] = 2; // use QLMC_REF_CLK1\n+\n+\t\t\tif (no_phy[qlm]) {\n+\t\t\t\tint i;\n+\t\t\t\tint start = 0, stop = 2;\n+\n+\t\t\t\trbgx = 0;\n+\t\t\t\tswitch (qlm) {\n+\t\t\t\tcase 3:\n+\t\t\t\t\trbgx = 1;\n+\t\t\t\tcase 2:\n+\t\t\t\t\tfor (i = 0; i < 4; i++) {\n+\t\t\t\t\t\tprintf(\"Ignoring PHY for interface: %d, port: %d\\n\",\n+\t\t\t\t\t\t       rbgx, i);\n+\t\t\t\t\t\tcvmx_helper_set_port_force_link_up(rbgx, i, true);\n+\t\t\t\t\t}\n+\t\t\t\t\tbreak;\n+\t\t\t\tcase 6:\n+\t\t\t\t\tstart = 2;\n+\t\t\t\t\tstop = 4;\n+\t\t\t\tcase 5:\n+\t\t\t\t\tfor (i = start; i < stop; i++) {\n+\t\t\t\t\t\tprintf(\"Ignoring PHY for interface: %d, port: %d\\n\",\n+\t\t\t\t\t\t       2, i);\n+\t\t\t\t\t\tcvmx_helper_set_port_force_link_up(2, i, true);\n+\t\t\t\t\t}\n+\t\t\t\t\tbreak;\n+\t\t\t\tdefault:\n+\t\t\t\t\tprintf(\"SGMII not supported for QLM/DLM %d\\n\",\n+\t\t\t\t\t       qlm);\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tprintf(\"QLM %d: SGMII%s\\n\",\n+\t\t\t       qlm, rgmii ? \", RGMII\" : \"\");\n+\t\t} else if (!strncmp(mode_str, \"xaui\", 4)) {\n+\t\t\tspeed[qlm] = 3125;\n+\t\t\tmode[qlm] = CVMX_QLM_MODE_XAUI;\n+\t\t\tref_clock_sel[qlm] = 2;\n+\t\t\tif (qlm == 5 || qlm == 6)\n+\t\t\t\tref_clock_input[qlm] = 2; // use QLMC_REF_CLK1\n+\t\t\tprintf(\"QLM %d: XAUI\\n\", qlm);\n+\t\t} else if (!strncmp(mode_str, \"dxaui\", 5)) {\n+\t\t\tspeed[qlm] = 6250;\n+\t\t\tmode[qlm] = CVMX_QLM_MODE_XAUI;\n+\t\t\tref_clock_sel[qlm] = 2;\n+\t\t\tif (qlm == 5 || qlm == 6)\n+\t\t\t\tref_clock_input[qlm] = 2; // use QLMC_REF_CLK1\n+\t\t\tprintf(\"QLM %d: DXAUI\\n\", qlm);\n+\t\t} else if (!strncmp(mode_str, \"rxaui\", 5)) {\n+\t\t\tbool rgmii = false;\n+\n+\t\t\tspeed[qlm] = 6250;\n+\t\t\tif (qlm == 5 || qlm == 6) {\n+\t\t\t\tif (rqlm == qlm && qlm == 5) {\n+\t\t\t\t\tmode[qlm] = CVMX_QLM_MODE_RGMII_RXAUI;\n+\t\t\t\t\trgmii = true;\n+\t\t\t\t} else {\n+\t\t\t\t\tmode[qlm] = CVMX_QLM_MODE_RXAUI_1X2;\n+\t\t\t\t}\n+\t\t\t} else {\n+\t\t\t\tmode[qlm] = CVMX_QLM_MODE_RXAUI;\n+\t\t\t}\n+\t\t\tref_clock_sel[qlm] = 2;\n+\t\t\tif (qlm == 5 || qlm == 6)\n+\t\t\t\tref_clock_input[qlm] = 2; // use QLMC_REF_CLK1\n+\t\t\tprintf(\"QLM %d: RXAUI%s\\n\",\n+\t\t\t       qlm, rgmii ? \", rgmii\" : \"\");\n+\t\t} else if (!strncmp(mode_str, \"xlaui\", 5)) {\n+\t\t\tspeed[qlm] = 103125;\n+\t\t\tmode[qlm] = CVMX_QLM_MODE_XLAUI;\n+\t\t\tref_clock_sel[qlm] = 2;\n+\t\t\tif (qlm == 5 || qlm == 6)\n+\t\t\t\tref_clock_input[qlm] = 2; // use QLMC_REF_CLK1\n+\t\t\tsprintf(spd_env, \"qlm%d_speed\", qlm);\n+\t\t\tif (env_get(spd_env)) {\n+\t\t\t\tint spd = env_get_ulong(spd_env, 0, 8);\n+\n+\t\t\t\tif (spd)\n+\t\t\t\t\tspeed[qlm] = spd;\n+\t\t\t\telse\n+\t\t\t\t\tspeed[qlm] = 103125;\n+\t\t\t}\n+\t\t\tprintf(\"QLM %d: XLAUI\\n\", qlm);\n+\t\t} else if (!strncmp(mode_str, \"xfi\", 3)) {\n+\t\t\tbool rgmii = false;\n+\n+\t\t\tspeed[qlm] = 103125;\n+\t\t\tif (rqlm == qlm) {\n+\t\t\t\tmode[qlm] = CVMX_QLM_MODE_RGMII_XFI;\n+\t\t\t\trgmii = true;\n+\t\t\t} else if (qlm == 5 || qlm == 6) {\n+\t\t\t\tmode[qlm] = CVMX_QLM_MODE_XFI_1X2;\n+\t\t\t} else {\n+\t\t\t\tmode[qlm] = CVMX_QLM_MODE_XFI;\n+\t\t\t}\n+\t\t\tref_clock_sel[qlm] = 2;\n+\t\t\tif (qlm == 5 || qlm == 6)\n+\t\t\t\tref_clock_input[qlm] = 2; // use QLMC_REF_CLK1\n+\t\t\tprintf(\"QLM %d: XFI%s\\n\", qlm, rgmii ? \", RGMII\" : \"\");\n+\t\t} else if (!strncmp(mode_str, \"10G_KR\", 6)) {\n+\t\t\tspeed[qlm] = 103125;\n+\t\t\tif (rqlm == qlm && qlm == 5)\n+\t\t\t\tmode[qlm] = CVMX_QLM_MODE_RGMII_10G_KR;\n+\t\t\telse if (qlm == 5 || qlm == 6)\n+\t\t\t\tmode[qlm] = CVMX_QLM_MODE_10G_KR_1X2;\n+\t\t\telse\n+\t\t\t\tmode[qlm] = CVMX_QLM_MODE_10G_KR;\n+\t\t\tref_clock_sel[qlm] = 2;\n+\t\t\tif (qlm == 5 || qlm == 6)\n+\t\t\t\tref_clock_input[qlm] = 2; // use QLMC_REF_CLK1\n+\t\t\tprintf(\"QLM %d: 10G_KR\\n\", qlm);\n+\t\t} else if (!strncmp(mode_str, \"40G_KR4\", 7)) {\n+\t\t\tspeed[qlm] = 103125;\n+\t\t\tmode[qlm] = CVMX_QLM_MODE_40G_KR4;\n+\t\t\tref_clock_sel[qlm] = 2;\n+\t\t\tif (qlm == 5 || qlm == 6)\n+\t\t\t\tref_clock_input[qlm] = 2; // use QLMC_REF_CLK1\n+\t\t\tprintf(\"QLM %d: 40G_KR4\\n\", qlm);\n+\t\t} else if (!strcmp(mode_str, \"pcie\")) {\n+\t\t\tchar *pmode;\n+\t\t\tint lanes = 0;\n+\n+\t\t\tsprintf(env_var, \"pcie%d_mode\", qlm);\n+\t\t\tpmode = env_get(env_var);\n+\t\t\tif (pmode && !strcmp(pmode, \"ep\"))\n+\t\t\t\tpcie_rc[qlm] = 0;\n+\t\t\telse\n+\t\t\t\tpcie_rc[qlm] = 1;\n+\t\t\tsprintf(env_var, \"pcie%d_gen\", qlm);\n+\t\t\tpcie_gen[qlm] = env_get_ulong(env_var, 0, 3);\n+\t\t\tsprintf(env_var, \"pcie%d_lanes\", qlm);\n+\t\t\tlanes = env_get_ulong(env_var, 0, 8);\n+\t\t\tif (lanes == 8) {\n+\t\t\t\tmode[qlm] = CVMX_QLM_MODE_PCIE_1X8;\n+\t\t\t} else if (qlm == 5 || qlm == 6) {\n+\t\t\t\tif (lanes != 2) {\n+\t\t\t\t\tprintf(\"QLM%d: Invalid lanes selected, defaulting to 2 lanes\\n\",\n+\t\t\t\t\t       qlm);\n+\t\t\t\t}\n+\t\t\t\tmode[qlm] = CVMX_QLM_MODE_PCIE_1X2;\n+\t\t\t\tref_clock_input[qlm] = 1; // use QLMC_REF_CLK0\n+\t\t\t} else {\n+\t\t\t\tmode[qlm] = CVMX_QLM_MODE_PCIE;\n+\t\t\t}\n+\t\t\tref_clock_sel[qlm] = 0;\n+\t\t\tprintf(\"QLM %d: PCIe gen%d %s, x%d lanes\\n\",\n+\t\t\t       qlm, pcie_gen[qlm] + 1,\n+\t\t\t       pcie_rc[qlm] ? \"root complex\" : \"endpoint\",\n+\t\t\t       lanes);\n+\t\t} else if (!strcmp(mode_str, \"sata\")) {\n+\t\t\tmode[qlm] = CVMX_QLM_MODE_SATA_2X1;\n+\t\t\tref_clock_sel[qlm] = 0;\n+\t\t\tref_clock_input[qlm] = 1;\n+\t\t\tsprintf(spd_env, \"qlm%d_speed\", qlm);\n+\t\t\tif (env_get(spd_env)) {\n+\t\t\t\tint spd = env_get_ulong(spd_env, 0, 8);\n+\n+\t\t\t\tif (spd == 1500 || spd == 3000 || spd == 3000)\n+\t\t\t\t\tspeed[qlm] = spd;\n+\t\t\t\telse\n+\t\t\t\t\tspeed[qlm] = 6000;\n+\t\t\t} else {\n+\t\t\t\tspeed[qlm] = 6000;\n+\t\t\t}\n+\t\t} else {\n+\t\t\tprintf(\"QLM %d: disabled\\n\", qlm);\n+\t\t}\n+\t}\n+\n+\tfor (qlm = 0; qlm < 7; qlm++) {\n+\t\tint rc;\n+\n+\t\tif (mode[qlm] == -1)\n+\t\t\tcontinue;\n+\n+\t\tdebug(\"Configuring qlm%d with speed(%d), mode(%d), RC(%d), Gen(%d), REF_CLK(%d), CLK_SOURCE(%d)\\n\",\n+\t\t      qlm, speed[qlm], mode[qlm], pcie_rc[qlm],\n+\t\t      pcie_gen[qlm] + 1,\n+\t\t      ref_clock_sel[qlm], ref_clock_input[qlm]);\n+\t\trc = octeon_configure_qlm(qlm, speed[qlm], mode[qlm],\n+\t\t\t\t\t  pcie_rc[qlm], pcie_gen[qlm],\n+\t\t\t\t\t  ref_clock_sel[qlm],\n+\t\t\t\t\t  ref_clock_input[qlm]);\n+\n+\t\tif (speed[qlm] == 6250) {\n+\t\t\tif (mode[qlm] == CVMX_QLM_MODE_RXAUI) {\n+\t\t\t\tocteon_qlm_tune_v3(0, qlm, speed[qlm], 0x12,\n+\t\t\t\t\t\t   0xa0, -1, -1);\n+\t\t\t} else {\n+\t\t\t\tocteon_qlm_tune_v3(0, qlm, speed[qlm], 0xa,\n+\t\t\t\t\t\t   0xa0, -1, -1);\n+\t\t\t}\n+\t\t} else if (speed[qlm] == 103125) {\n+\t\t\tocteon_qlm_tune_v3(0, qlm, speed[qlm], 0xd, 0xd0,\n+\t\t\t\t\t   -1, -1);\n+\t\t}\n+\n+\t\tif (qlm == 4 && rc != 0)\n+\t\t\t/*\n+\t\t\t * There is a bug with SATA with 73xx.  Until it's\n+\t\t\t * fixed we need to strip it from the device tree.\n+\t\t\t */\n+\t\t\tocteon_fdt_patch_rename((void *)gd->fdt_blob, \"4,none\",\n+\t\t\t\t\t\tNULL, true, NULL, NULL);\n+\t}\n+\n+\tdm_gpio_set_value(&desc, 0); /* Put RGMII PHY in reset */\n+\tmdelay(10);\n+\tdm_gpio_set_value(&desc, 1); /* Take RGMII PHY out of reset */\n+}\n+\n+int board_late_init(void)\n+{\n+\tboard_configure_qlms();\n+\n+\treturn 0;\n+}\n",
    "prefixes": [
        "v1",
        "48/50"
    ]
}