get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 52180,
    "url": "http://patches.dpdk.org/api/patches/52180/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1554292065-186702-10-git-send-email-rosen.xu@intel.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1554292065-186702-10-git-send-email-rosen.xu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1554292065-186702-10-git-send-email-rosen.xu@intel.com",
    "date": "2019-04-03T11:47:40",
    "name": "[v5,09/14] raw/ifpga/base: add SPI and MAX10 device driver",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "7ba3dc14f18c718b6c4bbc328ea7e6f703435959",
    "submitter": {
        "id": 946,
        "url": "http://patches.dpdk.org/api/people/946/?format=api",
        "name": "Xu, Rosen",
        "email": "rosen.xu@intel.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1554292065-186702-10-git-send-email-rosen.xu@intel.com/mbox/",
    "series": [
        {
            "id": 4084,
            "url": "http://patches.dpdk.org/api/series/4084/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=4084",
            "date": "2019-04-03T11:47:31",
            "name": "Add patch set for IPN3KE",
            "version": 5,
            "mbox": "http://patches.dpdk.org/series/4084/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/52180/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/52180/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 126C11B3BA;\n\tWed,  3 Apr 2019 13:47:19 +0200 (CEST)",
            "from mga11.intel.com (mga11.intel.com [192.55.52.93])\n\tby dpdk.org (Postfix) with ESMTP id 845951B39B\n\tfor <dev@dpdk.org>; Wed,  3 Apr 2019 13:47:14 +0200 (CEST)",
            "from fmsmga005.fm.intel.com ([10.253.24.32])\n\tby fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t03 Apr 2019 04:47:11 -0700",
            "from dpdkx8602.sh.intel.com ([10.67.110.200])\n\tby fmsmga005.fm.intel.com with ESMTP; 03 Apr 2019 04:47:09 -0700"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.60,304,1549958400\"; d=\"scan'208\";a=\"334606326\"",
        "From": "Rosen Xu <rosen.xu@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "ferruh.yigit@intel.com, tianfei.zhang@intel.com, dan.wei@intel.com,\n\trosen.xu@intel.com, andy.pei@intel.com, qiming.yang@intel.com,\n\thaiyue.wang@intel.com, santos.chen@intel.com, zhang.zhang@intel.com, \n\tdavid.lomartire@intel.com",
        "Date": "Wed,  3 Apr 2019 19:47:40 +0800",
        "Message-Id": "<1554292065-186702-10-git-send-email-rosen.xu@intel.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1554292065-186702-1-git-send-email-rosen.xu@intel.com>",
        "References": "<1551338000-120348-1-git-send-email-rosen.xu@intel.com>\n\t<1554292065-186702-1-git-send-email-rosen.xu@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v5 09/14] raw/ifpga/base: add SPI and MAX10\n\tdevice driver",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: \"Zhang, Tianfei\" <tianfei.zhang@intel.com>\n\nThere is a SPI bus link between A10 FPGA and MAX10 FPGA.\nMAX10 is in charge of board management, like power management,\nsensors, flash devices.\n\nSigned-off-by: Zhang, Tianfei <tianfei.zhang@intel.com>\n---\n drivers/raw/ifpga_rawdev/base/Makefile             |   3 +\n drivers/raw/ifpga_rawdev/base/ifpga_defines.h      |   5 +\n drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c  |   4 +\n drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h  |   2 +\n drivers/raw/ifpga_rawdev/base/ifpga_fme.c          | 196 +++++++++\n drivers/raw/ifpga_rawdev/base/ifpga_hw.h           |   2 +\n drivers/raw/ifpga_rawdev/base/meson.build          |   5 +-\n drivers/raw/ifpga_rawdev/base/opae_hw_api.h        |   1 +\n drivers/raw/ifpga_rawdev/base/opae_intel_max10.c   |  88 +++++\n drivers/raw/ifpga_rawdev/base/opae_intel_max10.h   |  60 +++\n drivers/raw/ifpga_rawdev/base/opae_osdep.h         |   4 +\n drivers/raw/ifpga_rawdev/base/opae_spi.c           | 304 ++++++++++++++\n drivers/raw/ifpga_rawdev/base/opae_spi.h           | 160 ++++++++\n .../raw/ifpga_rawdev/base/opae_spi_transaction.c   | 438 +++++++++++++++++++++\n .../ifpga_rawdev/base/osdep_rte/osdep_generic.h    |  14 +\n 15 files changed, 1285 insertions(+), 1 deletion(-)\n create mode 100644 drivers/raw/ifpga_rawdev/base/opae_intel_max10.c\n create mode 100644 drivers/raw/ifpga_rawdev/base/opae_intel_max10.h\n create mode 100644 drivers/raw/ifpga_rawdev/base/opae_spi.c\n create mode 100644 drivers/raw/ifpga_rawdev/base/opae_spi.h\n create mode 100644 drivers/raw/ifpga_rawdev/base/opae_spi_transaction.c",
    "diff": "diff --git a/drivers/raw/ifpga_rawdev/base/Makefile b/drivers/raw/ifpga_rawdev/base/Makefile\nindex d79da72..c6f51a8 100644\n--- a/drivers/raw/ifpga_rawdev/base/Makefile\n+++ b/drivers/raw/ifpga_rawdev/base/Makefile\n@@ -22,5 +22,8 @@ SRCS-y += opae_hw_api.c\n SRCS-y += opae_ifpga_hw_api.c\n SRCS-y += opae_debug.c\n SRCS-y += ifpga_fme_pr.c\n+SRCS-y += opae_spi.c\n+SRCS-y += opae_spi_transaction.c\n+SRCS-y += opae_intel_max10.c\n \n SRCS-y += $(wildcard $(SRCDIR)/base/$(OSDEP)/*.c)\ndiff --git a/drivers/raw/ifpga_rawdev/base/ifpga_defines.h b/drivers/raw/ifpga_rawdev/base/ifpga_defines.h\nindex 217d0b1..f5e22ae 100644\n--- a/drivers/raw/ifpga_rawdev/base/ifpga_defines.h\n+++ b/drivers/raw/ifpga_rawdev/base/ifpga_defines.h\n@@ -19,6 +19,8 @@\n #define FME_FEATURE_HSSI_ETH        \"fme_hssi\"\n #define FME_FEATURE_GLOBAL_DPERF    \"fme_dperf\"\n #define FME_FEATURE_QSPI_FLASH\t    \"fme_qspi_flash\"\n+#define FME_FEATURE_MAX10_SPI       \"fme_max10_spi\"\n+#define FME_FEATURE_NIOS_SPI        \"fme_nios_spi\"\n \n #define PORT_FEATURE_HEADER         \"port_hdr\"\n #define PORT_FEATURE_UAFU           \"port_uafu\"\n@@ -43,6 +45,7 @@\n #define FME_HSSI_ETH_REVISION\t\t0\n #define FME_GLOBAL_DPERF_REVISION\t0\n #define FME_QSPI_REVISION\t\t0\n+#define FME_MAX10_SPI                   0\n \n #define PORT_HEADER_REVISION\t\t0\n /* UAFU's header info depends on the downloaded GBS */\n@@ -80,6 +83,8 @@ enum fpga_id_type {\n #define FME_FEATURE_ID_GLOBAL_DPERF 0x7\n #define FME_FEATURE_ID_QSPI_FLASH 0x8\n #define FME_FEATURE_ID_EMIF_MGMT  0x9\n+#define FME_FEATURE_ID_MAX10_SPI  0xe\n+#define FME_FEATURE_ID_NIOS_SPI 0xd\n \n #define PORT_FEATURE_ID_HEADER FEATURE_ID_FIU_HEADER\n #define PORT_FEATURE_ID_ERROR 0x10\ndiff --git a/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c b/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c\nindex d82a890..2a35c06 100644\n--- a/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c\n+++ b/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c\n@@ -197,6 +197,10 @@ int port_clear_error(struct ifpga_port_hw *port)\n \t&fme_hssi_eth_ops),},\n \t{FEATURE_DRV(FME_FEATURE_ID_EMIF_MGMT, FME_FEATURE_EMIF_MGMT,\n \t&fme_emif_ops),},\n+\t{FEATURE_DRV(FME_FEATURE_ID_MAX10_SPI, FME_FEATURE_MAX10_SPI,\n+\t&fme_spi_master_ops),},\n+\t{FEATURE_DRV(FME_FEATURE_ID_NIOS_SPI, FME_FEATURE_NIOS_SPI,\n+\t&fme_nios_spi_master_ops),},\n \t{0, NULL, NULL}, /* end of arrary */\n };\n \ndiff --git a/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h b/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h\nindex 1d80f1d..72352ee 100644\n--- a/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h\n+++ b/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h\n@@ -171,6 +171,8 @@ int do_pr(struct ifpga_hw *hw, u32 port_id, void *buffer, u32 size,\n extern struct feature_ops fme_global_dperf_ops;\n extern struct feature_ops fme_hssi_eth_ops;\n extern struct feature_ops fme_emif_ops;\n+extern struct feature_ops fme_spi_master_ops;\n+extern struct feature_ops fme_nios_spi_master_ops;\n \n int port_get_prop(struct ifpga_port_hw *port, struct feature_prop *prop);\n int port_set_prop(struct ifpga_port_hw *port, struct feature_prop *prop);\ndiff --git a/drivers/raw/ifpga_rawdev/base/ifpga_fme.c b/drivers/raw/ifpga_rawdev/base/ifpga_fme.c\nindex 9451086..28226f0 100644\n--- a/drivers/raw/ifpga_rawdev/base/ifpga_fme.c\n+++ b/drivers/raw/ifpga_rawdev/base/ifpga_fme.c\n@@ -3,6 +3,8 @@\n  */\n \n #include \"ifpga_feature_dev.h\"\n+#include \"opae_spi.h\"\n+#include \"opae_intel_max10.h\"\n \n #define PWR_THRESHOLD_MAX       0x7F\n \n@@ -764,3 +766,197 @@ struct feature_ops fme_emif_ops = {\n \t.init = fme_emif_init,\n \t.uinit = fme_emif_uinit,\n };\n+\n+static int spi_self_checking(void)\n+{\n+\tu32 val;\n+\tint ret;\n+\n+\tret = max10_reg_read(0x30043c, &val);\n+\tif (ret)\n+\t\treturn -EIO;\n+\n+\tif (val != 0x87654321) {\n+\t\tdev_err(NULL, \"Read MAX10 test register fail: 0x%x\\n\", val);\n+\t\treturn -EIO;\n+\t}\n+\n+\tdev_info(NULL, \"Read MAX10 test register success, SPI self-test done\\n\");\n+\n+\treturn 0;\n+}\n+\n+static int fme_spi_init(struct feature *feature)\n+{\n+\tstruct ifpga_fme_hw *fme = (struct ifpga_fme_hw *)feature->parent;\n+\tstruct altera_spi_device *spi_master;\n+\tstruct intel_max10_device *max10;\n+\tint ret = 0;\n+\n+\tdev_info(fme, \"FME SPI Master (Max10) Init.\\n\");\n+\tdev_debug(fme, \"FME SPI base addr %p.\\n\",\n+\t\t\tfeature->addr);\n+\tdev_debug(fme, \"spi param=0x%llx\\n\",\n+\t\t\t(unsigned long long)opae_readq(feature->addr + 0x8));\n+\n+\tspi_master = altera_spi_alloc(feature->addr, TYPE_SPI);\n+\tif (!spi_master)\n+\t\treturn -ENODEV;\n+\n+\taltera_spi_init(spi_master);\n+\n+\tmax10 = intel_max10_device_probe(spi_master, 0);\n+\tif (!max10) {\n+\t\tret = -ENODEV;\n+\t\tdev_err(fme, \"max10 init fail\\n\");\n+\t\tgoto spi_fail;\n+\t}\n+\n+\tfme->max10_dev = max10;\n+\n+\t/* SPI self test */\n+\tif (spi_self_checking()) {\n+\t\tret = -EIO;\n+\t\tgoto max10_fail;\n+\t}\n+\n+\treturn ret;\n+\n+max10_fail:\n+\tintel_max10_device_remove(fme->max10_dev);\n+spi_fail:\n+\taltera_spi_release(spi_master);\n+\treturn ret;\n+}\n+\n+static void fme_spi_uinit(struct feature *feature)\n+{\n+\tstruct ifpga_fme_hw *fme = (struct ifpga_fme_hw *)feature->parent;\n+\n+\tif (fme->max10_dev)\n+\t\tintel_max10_device_remove(fme->max10_dev);\n+}\n+\n+struct feature_ops fme_spi_master_ops = {\n+\t.init = fme_spi_init,\n+\t.uinit = fme_spi_uinit,\n+};\n+\n+static int nios_spi_wait_init_done(struct altera_spi_device *dev)\n+{\n+\tu32 val = 0;\n+\tunsigned long timeout = msecs_to_timer_cycles(10000);\n+\tunsigned long ticks;\n+\n+\tdo {\n+\t\tif (spi_reg_read(dev, NIOS_SPI_INIT_DONE, &val))\n+\t\t\treturn -EIO;\n+\t\tif (val)\n+\t\t\tbreak;\n+\n+\t\tticks = rte_get_timer_cycles();\n+\t\tif (time_after(ticks, timeout))\n+\t\t\treturn -ETIMEDOUT;\n+\t\tmsleep(100);\n+\t} while (!val);\n+\n+\treturn 0;\n+}\n+\n+static int nios_spi_check_error(struct altera_spi_device *dev)\n+{\n+\tu32 value = 0;\n+\n+\tif (spi_reg_read(dev, NIOS_SPI_INIT_STS0, &value))\n+\t\treturn -EIO;\n+\n+\tdev_debug(dev, \"SPI init status0 0x%x\\n\", value);\n+\n+\t/* Error code: 0xFFF0 to 0xFFFC */\n+\tif (value >= 0xFFF0 && value <= 0xFFFC)\n+\t\treturn -EINVAL;\n+\n+\tvalue = 0;\n+\tif (spi_reg_read(dev, NIOS_SPI_INIT_STS1, &value))\n+\t\treturn -EIO;\n+\n+\tdev_debug(dev, \"SPI init status1 0x%x\\n\", value);\n+\n+\t/* Error code: 0xFFF0 to 0xFFFC */\n+\tif (value >= 0xFFF0 && value <= 0xFFFC)\n+\t\treturn -EINVAL;\n+\n+\treturn 0;\n+}\n+\n+static int fme_nios_spi_init(struct feature *feature)\n+{\n+\tstruct ifpga_fme_hw *fme = (struct ifpga_fme_hw *)feature->parent;\n+\tstruct altera_spi_device *spi_master;\n+\tstruct intel_max10_device *max10;\n+\tint ret = 0;\n+\n+\tdev_info(fme, \"FME SPI Master (NIOS) Init.\\n\");\n+\tdev_debug(fme, \"FME SPI base addr %p.\\n\",\n+\t\t\tfeature->addr);\n+\tdev_debug(fme, \"spi param=0x%llx\\n\",\n+\t\t\t(unsigned long long)opae_readq(feature->addr + 0x8));\n+\n+\tspi_master = altera_spi_alloc(feature->addr, TYPE_NIOS_SPI);\n+\tif (!spi_master)\n+\t\treturn -ENODEV;\n+\n+\t/**\n+\t * 1. wait A10 NIOS initial finished and\n+\t * release the SPI master to Host\n+\t */\n+\tret = nios_spi_wait_init_done(spi_master);\n+\tif (ret != 0) {\n+\t\tdev_err(fme, \"FME NIOS_SPI init fail\\n\");\n+\t\tgoto release_dev;\n+\t}\n+\n+\tdev_info(fme, \"FME NIOS_SPI initial done\\n\");\n+\n+\t/* 2. check if error occur? */\n+\tif (nios_spi_check_error(spi_master))\n+\t\tdev_info(fme, \"NIOS_SPI INIT done, but found some error\\n\");\n+\n+\t/* 3. init the spi master*/\n+\taltera_spi_init(spi_master);\n+\n+\t/* init the max10 device */\n+\tmax10 = intel_max10_device_probe(spi_master, 0);\n+\tif (!max10) {\n+\t\tret = -ENODEV;\n+\t\tdev_err(fme, \"max10 init fail\\n\");\n+\t\tgoto release_dev;\n+\t}\n+\n+\tfme->max10_dev = max10;\n+\n+\t/* SPI self test */\n+\tif (spi_self_checking())\n+\t\tgoto spi_fail;\n+\n+\treturn ret;\n+\n+spi_fail:\n+\tintel_max10_device_remove(fme->max10_dev);\n+release_dev:\n+\taltera_spi_release(spi_master);\n+\treturn -ENODEV;\n+}\n+\n+static void fme_nios_spi_uinit(struct feature *feature)\n+{\n+\tstruct ifpga_fme_hw *fme = (struct ifpga_fme_hw *)feature->parent;\n+\n+\tif (fme->max10_dev)\n+\t\tintel_max10_device_remove(fme->max10_dev);\n+}\n+\n+struct feature_ops fme_nios_spi_master_ops = {\n+\t.init = fme_nios_spi_init,\n+\t.uinit = fme_nios_spi_uinit,\n+};\ndiff --git a/drivers/raw/ifpga_rawdev/base/ifpga_hw.h b/drivers/raw/ifpga_rawdev/base/ifpga_hw.h\nindex 8aaa056..a2f4776 100644\n--- a/drivers/raw/ifpga_rawdev/base/ifpga_hw.h\n+++ b/drivers/raw/ifpga_rawdev/base/ifpga_hw.h\n@@ -79,6 +79,8 @@ struct ifpga_fme_hw {\n \tu32 cache_size;\n \n \tu32 capability;\n+\n+\tvoid *max10_dev; /* MAX10 device */\n };\n \n enum ifpga_port_state {\ndiff --git a/drivers/raw/ifpga_rawdev/base/meson.build b/drivers/raw/ifpga_rawdev/base/meson.build\nindex 03f5112..6bc762f 100644\n--- a/drivers/raw/ifpga_rawdev/base/meson.build\n+++ b/drivers/raw/ifpga_rawdev/base/meson.build\n@@ -14,7 +14,10 @@ sources = [\n \t'ifpga_fme_pr.c',\n \t'opae_hw_api.c',\n \t'opae_ifpga_hw_api.c',\n-\t'opae_debug.c'\n+\t'opae_debug.c',\n+\t'opae_spi.c',\n+\t'opae_spi_transaction.c',\n+\t'opae_intel_max10.c',\n ]\n \n error_cflags = ['-Wno-sign-compare', '-Wno-unused-value',\ndiff --git a/drivers/raw/ifpga_rawdev/base/opae_hw_api.h b/drivers/raw/ifpga_rawdev/base/opae_hw_api.h\nindex 332e0f3..76224b4 100644\n--- a/drivers/raw/ifpga_rawdev/base/opae_hw_api.h\n+++ b/drivers/raw/ifpga_rawdev/base/opae_hw_api.h\n@@ -11,6 +11,7 @@\n #include <sys/queue.h>\n \n #include \"opae_osdep.h\"\n+#include \"opae_intel_max10.h\"\n \n #ifndef PCI_MAX_RESOURCE\n #define PCI_MAX_RESOURCE 6\ndiff --git a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c\nnew file mode 100644\nindex 0000000..f354ee4\n--- /dev/null\n+++ b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c\n@@ -0,0 +1,88 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2010-2019 Intel Corporation\n+ */\n+\n+#include \"opae_intel_max10.h\"\n+\n+static struct intel_max10_device *g_max10;\n+\n+int max10_reg_read(unsigned int reg, unsigned int *val)\n+{\n+\tif (!g_max10)\n+\t\treturn -ENODEV;\n+\n+\treturn spi_transaction_read(g_max10->spi_tran_dev,\n+\t\t\treg, 4, (unsigned char *)val);\n+}\n+\n+int max10_reg_write(unsigned int reg, unsigned int val)\n+{\n+\tif (!g_max10)\n+\t\treturn -ENODEV;\n+\n+\treturn spi_transaction_write(g_max10->spi_tran_dev,\n+\t\t\treg, 4, (unsigned char *)&val);\n+}\n+\n+struct intel_max10_device *\n+intel_max10_device_probe(struct altera_spi_device *spi,\n+\t\tint chipselect)\n+{\n+\tstruct intel_max10_device *dev;\n+\tint ret;\n+\tunsigned int val;\n+\n+\tdev = opae_malloc(sizeof(*dev));\n+\tif (!dev)\n+\t\treturn NULL;\n+\n+\tdev->spi_master = spi;\n+\n+\tdev->spi_tran_dev = spi_transaction_init(spi, chipselect);\n+\tif (!dev->spi_tran_dev) {\n+\t\tdev_err(dev, \"%s spi tran init fail\\n\", __func__);\n+\t\tgoto free_dev;\n+\t}\n+\n+\t/* set the max10 device firstly */\n+\tg_max10 = dev;\n+\n+\t/* read FPGA loading information */\n+\tret = max10_reg_read(FPGA_PAGE_INFO_OFF, &val);\n+\tif (ret) {\n+\t\tdev_err(dev, \"fail to get FPGA loading info\\n\");\n+\t\tgoto spi_tran_fail;\n+\t}\n+\tdev_info(dev, \"FPGA loaded from %s Image\\n\", val ? \"User\" : \"Factory\");\n+\n+\t/* set PKVL Polling manually in BBS */\n+\tret = max10_reg_write(PKVL_POLLING_CTRL, 0x3);\n+\tif (ret) {\n+\t\tdev_err(dev, \"%s set PKVL polling fail\\n\", __func__);\n+\t\tgoto spi_tran_fail;\n+\t}\n+\n+\treturn dev;\n+\n+spi_tran_fail:\n+\tspi_transaction_remove(dev->spi_tran_dev);\n+free_dev:\n+\tg_max10 = NULL;\n+\topae_free(dev);\n+\n+\treturn NULL;\n+}\n+\n+int intel_max10_device_remove(struct intel_max10_device *dev)\n+{\n+\tif (!dev)\n+\t\treturn 0;\n+\n+\tif (dev->spi_tran_dev)\n+\t\tspi_transaction_remove(dev->spi_tran_dev);\n+\n+\tg_max10 = NULL;\n+\topae_free(dev);\n+\n+\treturn 0;\n+}\ndiff --git a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h\nnew file mode 100644\nindex 0000000..91a188d\n--- /dev/null\n+++ b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h\n@@ -0,0 +1,60 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2019 Intel Corporation\n+ */\n+\n+#ifndef _OPAE_INTEL_MAX10_H_\n+#define _OPAE_INTEL_MAX10_H_\n+\n+#include \"opae_osdep.h\"\n+#include \"opae_spi.h\"\n+\n+#define INTEL_MAX10_MAX_MDIO_DEVS 2\n+#define PKVL_NUMBER_PORTS  4\n+\n+/* max10 capability flags */\n+#define MAX10_FLAGS_NO_I2C2\t\tBIT(0)\n+#define MAX10_FLAGS_NO_BMCIMG_FLASH\tBIT(1)\n+#define MAX10_FLAGS_DEVICE_TABLE        BIT(2)\n+#define MAX10_FLAGS_SPI                 BIT(3)\n+#define MAX10_FLGAS_NIOS_SPI            BIT(4)\n+#define MAX10_FLAGS_PKVL                BIT(5)\n+\n+struct intel_max10_device {\n+\tunsigned int flags; /*max10 hardware capability*/\n+\tstruct altera_spi_device *spi_master;\n+\tstruct spi_transaction_dev *spi_tran_dev;\n+};\n+\n+#define FLASH_BASE 0x10000000\n+#define FLASH_OPTION_BITS 0x10000\n+\n+#define NIOS2_FW_VERSION_OFF   0x300400\n+#define RSU_REG_OFF            0x30042c\n+#define FPGA_RP_LOAD\t\tBIT(3)\n+#define NIOS2_PRERESET\t\tBIT(4)\n+#define NIOS2_HANG\t\tBIT(5)\n+#define RSU_ENABLE\t\tBIT(6)\n+#define NIOS2_RESET\t\tBIT(7)\n+#define NIOS2_I2C2_POLL_STOP\tBIT(13)\n+#define FPGA_RECONF_REG_OFF\t0x300430\n+#define COUNTDOWN_START\t\tBIT(18)\n+#define MAX10_BUILD_VER_OFF\t0x300468\n+#define PCB_INFO\t\tGENMASK(31, 24)\n+#define MAX10_BUILD_VERION\tGENMASK(23, 0)\n+#define FPGA_PAGE_INFO_OFF\t0x30046c\n+#define DT_AVAIL_REG_OFF\t0x300490\n+#define DT_AVAIL\t\tBIT(0)\n+#define DT_BASE_ADDR_REG_OFF\t0x300494\n+#define PKVL_POLLING_CTRL       0x300480\n+#define PKVL_LINK_STATUS        0x300564\n+\n+#define DFT_MAX_SIZE\t\t0x7e0000\n+\n+int max10_reg_read(unsigned int reg, unsigned int *val);\n+int max10_reg_write(unsigned int reg, unsigned int val);\n+struct intel_max10_device *\n+intel_max10_device_probe(struct altera_spi_device *spi,\n+\t\tint chipselect);\n+int intel_max10_device_remove(struct intel_max10_device *dev);\n+\n+#endif\ndiff --git a/drivers/raw/ifpga_rawdev/base/opae_osdep.h b/drivers/raw/ifpga_rawdev/base/opae_osdep.h\nindex 78fec50..d710ec0 100644\n--- a/drivers/raw/ifpga_rawdev/base/opae_osdep.h\n+++ b/drivers/raw/ifpga_rawdev/base/opae_osdep.h\n@@ -35,6 +35,7 @@ struct uuid {\n #ifndef BIT\n #define BIT(a) (1UL << (a))\n #endif /* BIT */\n+#define U64_C(x) x ## ULL\n #ifndef BIT_ULL\n #define BIT_ULL(a) (1ULL << (a))\n #endif /* BIT_ULL */\n@@ -76,5 +77,8 @@ struct uuid {\n #define msleep(x) opae_udelay(1000 * (x))\n #define usleep_range(min, max) msleep(DIV_ROUND_UP(min, 1000))\n \n+#define time_after(a, b)\t((long)((b) - (a)) < 0)\n+#define time_before(a, b)\ttime_after(b, a)\n #define opae_memset(a, b, c)    memset((a), (b), (c))\n+\n #endif\ndiff --git a/drivers/raw/ifpga_rawdev/base/opae_spi.c b/drivers/raw/ifpga_rawdev/base/opae_spi.c\nnew file mode 100644\nindex 0000000..cc52782\n--- /dev/null\n+++ b/drivers/raw/ifpga_rawdev/base/opae_spi.c\n@@ -0,0 +1,304 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2010-2019 Intel Corporation\n+ */\n+\n+#include \"opae_osdep.h\"\n+#include \"opae_spi.h\"\n+\n+static int nios_spi_indirect_read(struct altera_spi_device *dev, u32 reg,\n+\t\tu32 *val)\n+{\n+\tu64 ctrl = 0;\n+\tu64 stat = 0;\n+\tint loops = SPI_MAX_RETRY;\n+\n+\tctrl = NIOS_SPI_RD | ((u64)reg << 32);\n+\topae_writeq(ctrl, dev->regs + NIOS_SPI_CTRL);\n+\n+\tstat = opae_readq(dev->regs + NIOS_SPI_STAT);\n+\twhile (!(stat & NIOS_SPI_VALID) && --loops)\n+\t\tstat = opae_readq(dev->regs + NIOS_SPI_STAT);\n+\n+\t*val = stat & NIOS_SPI_READ_DATA;\n+\n+\treturn loops ? 0 : -ETIMEDOUT;\n+}\n+\n+static int nios_spi_indirect_write(struct altera_spi_device *dev, u32 reg,\n+\t\tu32 value)\n+{\n+\n+\tu64 ctrl = 0;\n+\tu64 stat = 0;\n+\tint loops = SPI_MAX_RETRY;\n+\n+\tctrl |= NIOS_SPI_WR | (u64)reg << 32;\n+\tctrl |= value & NIOS_SPI_WRITE_DATA;\n+\n+\topae_writeq(ctrl, dev->regs + NIOS_SPI_CTRL);\n+\n+\tstat = opae_readq(dev->regs + NIOS_SPI_STAT);\n+\twhile (!(stat & NIOS_SPI_VALID) && --loops)\n+\t\tstat = opae_readq(dev->regs + NIOS_SPI_STAT);\n+\n+\treturn loops ? 0 : -ETIMEDOUT;\n+}\n+\n+static int spi_indirect_write(struct altera_spi_device *dev, u32 reg,\n+\t\tu32 value)\n+{\n+\tu64 ctrl;\n+\n+\topae_writeq(value & WRITE_DATA_MASK, dev->regs + SPI_WRITE);\n+\n+\tctrl = CTRL_W | (reg >> 2);\n+\topae_writeq(ctrl, dev->regs + SPI_CTRL);\n+\n+\treturn 0;\n+}\n+\n+static int spi_indirect_read(struct altera_spi_device *dev, u32 reg,\n+\t\tu32 *val)\n+{\n+\tu64 tmp;\n+\tu64 ctrl;\n+\n+\tctrl = CTRL_R | (reg >> 2);\n+\topae_writeq(ctrl, dev->regs + SPI_CTRL);\n+\n+\t/**\n+\t *  FIXME: Read one more time to avoid HW timing issue. This is\n+\t *  a short term workaround solution, and must be removed once\n+\t *  hardware fixing is done.\n+\t */\n+\ttmp = opae_readq(dev->regs + SPI_READ);\n+\n+\t*val = (u32)tmp;\n+\n+\treturn 0;\n+}\n+\n+int spi_reg_write(struct altera_spi_device *dev, u32 reg,\n+\t\tu32 value)\n+{\n+\treturn dev->reg_write(dev, reg, value);\n+}\n+\n+int spi_reg_read(struct altera_spi_device *dev, u32 reg,\n+\t\tu32 *val)\n+{\n+\treturn dev->reg_read(dev, reg, val);\n+}\n+\n+void spi_cs_activate(struct altera_spi_device *dev, unsigned int chip_select)\n+{\n+\tspi_reg_write(dev, ALTERA_SPI_SLAVE_SEL, 1 << chip_select);\n+\tspi_reg_write(dev, ALTERA_SPI_CONTROL, ALTERA_SPI_CONTROL_SSO_MSK);\n+}\n+\n+void spi_cs_deactivate(struct altera_spi_device *dev)\n+{\n+\tspi_reg_write(dev, ALTERA_SPI_CONTROL, 0);\n+}\n+\n+static int spi_flush_rx(struct altera_spi_device *dev)\n+{\n+\tu32 val = 0;\n+\tint ret;\n+\n+\tret = spi_reg_read(dev, ALTERA_SPI_STATUS, &val);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tif (val & ALTERA_SPI_STATUS_RRDY_MSK) {\n+\t\tret = spi_reg_read(dev, ALTERA_SPI_RXDATA, &val);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static unsigned int spi_write_bytes(struct altera_spi_device *dev, int count)\n+{\n+\tunsigned int val = 0;\n+\tu16 *p16;\n+\tu32 *p32;\n+\n+\tif (dev->txbuf) {\n+\t\tswitch (dev->data_width) {\n+\t\tcase 1:\n+\t\t\tval = dev->txbuf[count];\n+\t\t\tbreak;\n+\t\tcase 2:\n+\t\t\tp16 = (u16 *)(dev->txbuf + 2*count);\n+\t\t\tval = *p16;\n+\t\t\tif (dev->endian == SPI_BIG_ENDIAN)\n+\t\t\t\tval = cpu_to_be16(val);\n+\t\t\tbreak;\n+\t\tcase 4:\n+\t\t\tp32 = (u32 *)(dev->txbuf + 4*count);\n+\t\t\tval = *p32;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\treturn val;\n+}\n+\n+static void spi_fill_readbuffer(struct altera_spi_device *dev,\n+\t\tunsigned int value, int count)\n+{\n+\tu16 *p16;\n+\tu32 *p32;\n+\n+\tif (dev->rxbuf) {\n+\t\tswitch (dev->data_width) {\n+\t\tcase 1:\n+\t\t\tdev->rxbuf[count] = value;\n+\t\t\tbreak;\n+\t\tcase 2:\n+\t\t\tp16 = (u16 *)(dev->rxbuf + 2*count);\n+\t\t\tif (dev->endian == SPI_BIG_ENDIAN)\n+\t\t\t\t*p16 = cpu_to_be16((u16)value);\n+\t\t\telse\n+\t\t\t\t*p16 = (u16)value;\n+\t\t\tbreak;\n+\t\tcase 4:\n+\t\t\tp32 = (u32 *)(dev->rxbuf + 4*count);\n+\t\t\tif (dev->endian == SPI_BIG_ENDIAN)\n+\t\t\t\t*p32 = cpu_to_be32(value);\n+\t\t\telse\n+\t\t\t\t*p32 = value;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+}\n+\n+static int spi_txrx(struct altera_spi_device *dev)\n+{\n+\tunsigned int count = 0;\n+\tu32 rxd;\n+\tunsigned int tx_data;\n+\tu32 status;\n+\tint retry = 0;\n+\tint ret;\n+\n+\twhile (count < dev->len) {\n+\t\ttx_data = spi_write_bytes(dev, count);\n+\t\tspi_reg_write(dev, ALTERA_SPI_TXDATA, tx_data);\n+\n+\t\twhile (1) {\n+\t\t\tret = spi_reg_read(dev, ALTERA_SPI_STATUS, &status);\n+\t\t\tif (ret)\n+\t\t\t\treturn -EIO;\n+\t\t\tif (status & ALTERA_SPI_STATUS_RRDY_MSK)\n+\t\t\t\tbreak;\n+\t\t\tif (retry++ > SPI_MAX_RETRY) {\n+\t\t\t\tdev_err(dev, \"%s, read timeout\\n\", __func__);\n+\t\t\t\treturn -EBUSY;\n+\t\t\t}\n+\t\t}\n+\n+\t\tret = spi_reg_read(dev, ALTERA_SPI_RXDATA, &rxd);\n+\t\tif (ret)\n+\t\t\treturn -EIO;\n+\n+\t\tspi_fill_readbuffer(dev, rxd, count);\n+\n+\t\tcount++;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int spi_command(struct altera_spi_device *dev, unsigned int chip_select,\n+\t\tunsigned int wlen, void *wdata,\n+\t\tunsigned int rlen, void *rdata)\n+{\n+\tif (((wlen > 0) && !wdata) || ((rlen > 0) && !rdata)) {\n+\t\tdev_err(dev, \"error on spi command checking\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\twlen = wlen / dev->data_width;\n+\trlen = rlen / dev->data_width;\n+\n+\t/* flush rx buffer */\n+\tspi_flush_rx(dev);\n+\n+\tspi_cs_activate(dev, chip_select);\n+\tif (wlen) {\n+\t\tdev->txbuf = wdata;\n+\t\tdev->rxbuf = rdata;\n+\t\tdev->len = wlen;\n+\t\tspi_txrx(dev);\n+\t}\n+\tif (rlen) {\n+\t\tdev->rxbuf = rdata;\n+\t\tdev->txbuf = NULL;\n+\t\tdev->len = rlen;\n+\t\tspi_txrx(dev);\n+\t}\n+\tspi_cs_deactivate(dev);\n+\treturn 0;\n+}\n+\n+struct altera_spi_device *altera_spi_alloc(void *base, int type)\n+{\n+\tstruct altera_spi_device *spi_dev =\n+\t\topae_malloc(sizeof(struct altera_spi_device));\n+\n+\tif (!spi_dev)\n+\t\treturn NULL;\n+\n+\tspi_dev->regs = base;\n+\n+\tswitch (type) {\n+\tcase TYPE_SPI:\n+\t\tspi_dev->reg_read = spi_indirect_read;\n+\t\tspi_dev->reg_write = spi_indirect_write;\n+\t\tbreak;\n+\tcase TYPE_NIOS_SPI:\n+\t\tspi_dev->reg_read = nios_spi_indirect_read;\n+\t\tspi_dev->reg_write = nios_spi_indirect_write;\n+\t\tbreak;\n+\tdefault:\n+\t\tdev_err(dev, \"%s: invalid SPI type\\n\", __func__);\n+\t\tgoto error;\n+\t}\n+\n+\treturn spi_dev;\n+\n+error:\n+\taltera_spi_release(spi_dev);\n+\treturn NULL;\n+}\n+\n+void altera_spi_init(struct altera_spi_device *spi_dev)\n+{\n+\tspi_dev->spi_param.info = opae_readq(spi_dev->regs + SPI_CORE_PARAM);\n+\n+\tspi_dev->data_width = spi_dev->spi_param.data_width / 8;\n+\tspi_dev->endian = spi_dev->spi_param.endian;\n+\tspi_dev->num_chipselect = spi_dev->spi_param.num_chipselect;\n+\tdev_info(spi_dev, \"spi param: type=%d, data width:%d, endian:%d, clock_polarity=%d, clock=%dMHz, chips=%d, cpha=%d\\n\",\n+\t\t\tspi_dev->spi_param.type,\n+\t\t\tspi_dev->data_width, spi_dev->endian,\n+\t\t\tspi_dev->spi_param.clock_polarity,\n+\t\t\tspi_dev->spi_param.clock,\n+\t\t\tspi_dev->num_chipselect,\n+\t\t\tspi_dev->spi_param.clock_phase);\n+\n+\t/* clear */\n+\tspi_reg_write(spi_dev, ALTERA_SPI_CONTROL, 0);\n+\tspi_reg_write(spi_dev, ALTERA_SPI_STATUS, 0);\n+\t/* flush rxdata */\n+\tspi_flush_rx(spi_dev);\n+}\n+\n+void altera_spi_release(struct altera_spi_device *dev)\n+{\n+\tif (dev)\n+\t\topae_free(dev);\n+}\ndiff --git a/drivers/raw/ifpga_rawdev/base/opae_spi.h b/drivers/raw/ifpga_rawdev/base/opae_spi.h\nnew file mode 100644\nindex 0000000..ab66e1f\n--- /dev/null\n+++ b/drivers/raw/ifpga_rawdev/base/opae_spi.h\n@@ -0,0 +1,160 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2010-2019 Intel Corporation\n+ */\n+\n+#ifndef _OPAE_SPI_H\n+#define _OPAE_SPI_H\n+\n+#include \"opae_osdep.h\"\n+\n+#define ALTERA_SPI_RXDATA\t0\n+#define ALTERA_SPI_TXDATA\t4\n+#define ALTERA_SPI_STATUS\t8\n+#define ALTERA_SPI_CONTROL\t12\n+#define ALTERA_SPI_SLAVE_SEL\t20\n+\n+#define ALTERA_SPI_STATUS_ROE_MSK\t0x8\n+#define ALTERA_SPI_STATUS_TOE_MSK\t0x10\n+#define ALTERA_SPI_STATUS_TMT_MSK\t0x20\n+#define ALTERA_SPI_STATUS_TRDY_MSK\t0x40\n+#define ALTERA_SPI_STATUS_RRDY_MSK\t0x80\n+#define ALTERA_SPI_STATUS_E_MSK\t\t0x100\n+\n+#define ALTERA_SPI_CONTROL_IROE_MSK\t0x8\n+#define ALTERA_SPI_CONTROL_ITOE_MSK\t0x10\n+#define ALTERA_SPI_CONTROL_ITRDY_MSK\t0x40\n+#define ALTERA_SPI_CONTROL_IRRDY_MSK\t0x80\n+#define ALTERA_SPI_CONTROL_IE_MSK\t0x100\n+#define ALTERA_SPI_CONTROL_SSO_MSK\t0x400\n+\n+#define SPI_CORE_PARAM 0x8\n+#define SPI_CTRL 0x10\n+#define CTRL_R    BIT_ULL(9)\n+#define CTRL_W    BIT_ULL(8)\n+#define CTRL_ADDR_MASK GENMASK_ULL(2, 0)\n+#define SPI_READ 0x18\n+#define READ_DATA_VALID BIT_ULL(32)\n+#define READ_DATA_MASK GENMASK_ULL(31, 0)\n+#define SPI_WRITE 0x20\n+#define WRITE_DATA_MASK GENMASK_ULL(31, 0)\n+\n+#define SPI_MAX_RETRY 100000\n+\n+#define TYPE_SPI 0\n+#define TYPE_NIOS_SPI 1\n+\n+struct spi_core_param {\n+\tunion {\n+\t\tu64 info;\n+\t\tstruct {\n+\t\t\tu8 type:1;\n+\t\t\tu8 endian:1;\n+\t\t\tu8 data_width:6;\n+\t\t\tu8 num_chipselect:6;\n+\t\t\tu8 clock_polarity:1;\n+\t\t\tu8 clock_phase:1;\n+\t\t\tu8 stages:2;\n+\t\t\tu8 resvd:4;\n+\t\t\tu16 clock:10;\n+\t\t\tu16 peripheral_id:16;\n+\t\t\tu8 controller_type:1;\n+\t\t\tu16 resvd1:15;\n+\t\t};\n+\t};\n+};\n+\n+struct altera_spi_device {\n+\tu8 *regs;\n+\tstruct spi_core_param spi_param;\n+\tint data_width; /* how many bytes for data width */\n+\tint endian;\n+\t#define SPI_BIG_ENDIAN  0\n+\t#define SPI_LITTLE_ENDIAN 1\n+\tint num_chipselect;\n+\tunsigned char *rxbuf;\n+\tunsigned char *txbuf;\n+\tunsigned int len;\n+\tint (*reg_read)(struct altera_spi_device *dev, u32 reg, u32 *val);\n+\tint (*reg_write)(struct altera_spi_device *dev, u32 reg,\n+\t\t\tu32 value);\n+};\n+\n+#define HEADER_LEN 8\n+#define RESPONSE_LEN 4\n+#define SPI_TRANSACTION_MAX_LEN 1024\n+#define TRAN_SEND_MAX_LEN (SPI_TRANSACTION_MAX_LEN + HEADER_LEN)\n+#define TRAN_RESP_MAX_LEN SPI_TRANSACTION_MAX_LEN\n+#define PACKET_SEND_MAX_LEN (2*TRAN_SEND_MAX_LEN + 4)\n+#define PACKET_RESP_MAX_LEN (2*TRAN_RESP_MAX_LEN + 4)\n+#define BYTES_SEND_MAX_LEN  (2*PACKET_SEND_MAX_LEN)\n+#define BYTES_RESP_MAX_LEN (2*PACKET_RESP_MAX_LEN)\n+\n+struct spi_tran_buffer {\n+\tunsigned char tran_send[TRAN_SEND_MAX_LEN];\n+\tunsigned char tran_resp[TRAN_RESP_MAX_LEN];\n+\tunsigned char packet_send[PACKET_SEND_MAX_LEN];\n+\tunsigned char packet_resp[PACKET_RESP_MAX_LEN];\n+\tunsigned char bytes_send[BYTES_SEND_MAX_LEN];\n+\tunsigned char bytes_resp[2*BYTES_RESP_MAX_LEN];\n+};\n+\n+struct spi_transaction_dev {\n+\tstruct altera_spi_device *dev;\n+\tint chipselect;\n+\tstruct spi_tran_buffer *buffer;\n+};\n+\n+struct spi_tran_header {\n+\tu8 trans_type;\n+\tu8 reserve;\n+\tu16 size;\n+\tu32 addr;\n+};\n+\n+int spi_command(struct altera_spi_device *dev, unsigned int chip_select,\n+\t\tunsigned int wlen, void *wdata, unsigned int rlen, void *rdata);\n+void spi_cs_deactivate(struct altera_spi_device *dev);\n+void spi_cs_activate(struct altera_spi_device *dev, unsigned int chip_select);\n+struct altera_spi_device *altera_spi_alloc(void *base, int type);\n+void altera_spi_init(struct altera_spi_device *dev);\n+void altera_spi_release(struct altera_spi_device *dev);\n+int spi_transaction_read(struct spi_transaction_dev *dev, unsigned int addr,\n+\t\tunsigned int size, unsigned char *data);\n+int spi_transaction_write(struct spi_transaction_dev *dev, unsigned int addr,\n+\t\tunsigned int size, unsigned char *data);\n+struct spi_transaction_dev *spi_transaction_init(struct altera_spi_device *dev,\n+\t\tint chipselect);\n+void spi_transaction_remove(struct spi_transaction_dev *dev);\n+int spi_reg_write(struct altera_spi_device *dev, u32 reg,\n+\t\tu32 value);\n+int spi_reg_read(struct altera_spi_device *dev, u32 reg, u32 *val);\n+\n+#define NIOS_SPI_PARAM 0x8\n+#define CONTROL_TYPE BIT_ULL(48)\n+#define PERI_ID GENMASK_ULL(47, 32)\n+#define SPI_CLK GENMASK_ULL(31, 22)\n+#define SYNC_STAGES GENMASK_ULL(17, 16)\n+#define CLOCK_PHASE BIT_ULL(15)\n+#define CLOCK_POLARITY BIT_ULL(14)\n+#define NUM_SELECT  GENMASK_ULL(13, 8)\n+#define DATA_WIDTH GENMASK_ULL(7, 2)\n+#define SHIFT_DIRECTION BIT_ULL(1)\n+#define SPI_TYPE  BIT_ULL(0)\n+#define NIOS_SPI_CTRL 0x10\n+#define NIOS_SPI_RD (0x1ULL << 62)\n+#define NIOS_SPI_WR (0x2ULL << 62)\n+#define NIOS_SPI_COMMAND GENMASK_ULL(63, 62)\n+#define NIOS_SPI_ADDR  GENMASK_ULL(44, 32)\n+#define NIOS_SPI_WRITE_DATA  GENMASK_ULL(31, 0)\n+#define NIOS_SPI_STAT 0x18\n+#define NIOS_SPI_VALID BIT_ULL(32)\n+#define NIOS_SPI_READ_DATA GENMASK_ULL(31, 0)\n+#define NIOS_SPI_INIT_DONE 0x1000\n+\n+#define NIOS_SPI_INIT_DONE 0x1000\n+#define NIOS_SPI_INIT_STS0 0x1020\n+#define NIOS_SPI_INIT_STS1 0x1024\n+#define PKVL_STATUS_RESET  0\n+#define PKVL_10G_MODE      1\n+#define PKVL_25G_MODE      2\n+#endif\ndiff --git a/drivers/raw/ifpga_rawdev/base/opae_spi_transaction.c b/drivers/raw/ifpga_rawdev/base/opae_spi_transaction.c\nnew file mode 100644\nindex 0000000..17ec3c1\n--- /dev/null\n+++ b/drivers/raw/ifpga_rawdev/base/opae_spi_transaction.c\n@@ -0,0 +1,438 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2010-2019 Intel Corporation\n+ */\n+\n+#include \"opae_spi.h\"\n+#include \"ifpga_compat.h\"\n+\n+/*transaction opcodes*/\n+#define SPI_TRAN_SEQ_WRITE 0x04 /* SPI transaction sequential write */\n+#define SPI_TRAN_SEQ_READ  0x14 /* SPI transaction sequential read */\n+#define SPI_TRAN_NON_SEQ_WRITE 0x00 /* SPI transaction non-sequential write */\n+#define SPI_TRAN_NON_SEQ_READ  0x10 /* SPI transaction non-sequential read*/\n+\n+/*specail packet characters*/\n+#define SPI_PACKET_SOP     0x7a\n+#define SPI_PACKET_EOP     0x7b\n+#define SPI_PACKET_CHANNEL 0x7c\n+#define SPI_PACKET_ESC     0x7d\n+\n+/*special byte characters*/\n+#define SPI_BYTE_IDLE 0x4a\n+#define SPI_BYTE_ESC  0x4d\n+\n+#define SPI_REG_BYTES 4\n+\n+#define INIT_SPI_TRAN_HEADER(trans_type, size, address) \\\n+({ \\\n+\theader.trans_type = trans_type; \\\n+\theader.reserve = 0; \\\n+\theader.size = cpu_to_be16(size); \\\n+\theader.addr = cpu_to_be32(addr); \\\n+})\n+\n+#ifdef OPAE_SPI_DEBUG\n+static void print_buffer(const char *string, void *buffer, int len)\n+{\n+\tint i;\n+\tunsigned char *p = buffer;\n+\n+\tprintf(\"%s print buffer, len=%d\\n\", string, len);\n+\n+\tfor (i = 0; i < len; i++)\n+\t\tprintf(\"%x \", *(p+i));\n+\tprintf(\"\\n\");\n+}\n+#else\n+static void print_buffer(const char *string, void *buffer, int len)\n+{\n+\tUNUSED(string);\n+\tUNUSED(buffer);\n+\tUNUSED(len);\n+}\n+#endif\n+\n+static unsigned char xor_20(unsigned char val)\n+{\n+\treturn val^0x20;\n+}\n+\n+static void reorder_phy_data(u8 bits_per_word,\n+\t\tvoid *buf, unsigned int len)\n+{\n+\tunsigned int count = len / (bits_per_word/8);\n+\tu32 *p;\n+\n+\tif (bits_per_word == 32) {\n+\t\tp = (u32 *)buf;\n+\t\twhile (count--) {\n+\t\t\t*p = cpu_to_be32(*p);\n+\t\t\tp++;\n+\t\t}\n+\t}\n+}\n+\n+enum {\n+\tSPI_FOUND_SOP,\n+\tSPI_FOUND_EOP,\n+\tSPI_NOT_FOUND,\n+};\n+\n+static int resp_find_sop_eop(unsigned char *resp, unsigned int len,\n+\t\tint flags)\n+{\n+\tint ret = SPI_NOT_FOUND;\n+\n+\tunsigned char *b = resp;\n+\n+\t/* find SOP */\n+\tif (flags != SPI_FOUND_SOP) {\n+\t\twhile (b < resp + len && *b != SPI_PACKET_SOP)\n+\t\t\tb++;\n+\n+\t\tif (*b != SPI_PACKET_SOP)\n+\t\t\tgoto done;\n+\n+\t\tret = SPI_FOUND_SOP;\n+\t}\n+\n+\t/* find EOP */\n+\twhile (b < resp + len && *b != SPI_PACKET_EOP)\n+\t\tb++;\n+\n+\tif (*b != SPI_PACKET_EOP)\n+\t\tgoto done;\n+\n+\tret = SPI_FOUND_EOP;\n+\n+done:\n+\treturn ret;\n+}\n+\n+static int byte_to_core_convert(struct spi_transaction_dev *dev,\n+\t\tunsigned int send_len, unsigned char *send_data,\n+\t\tunsigned int resp_len, unsigned char *resp_data,\n+\t\tunsigned int *valid_resp_len)\n+{\n+\tunsigned int i;\n+\tint ret = 0;\n+\tunsigned char *send_packet = dev->buffer->bytes_send;\n+\tunsigned char *resp_packet = dev->buffer->bytes_resp;\n+\tunsigned char *p;\n+\tunsigned char current_byte;\n+\tunsigned char *tx_buffer;\n+\tunsigned int tx_len = 0;\n+\tunsigned char *rx_buffer;\n+\tunsigned int rx_len = 0;\n+\tint retry = 0;\n+\tint spi_flags;\n+\tunsigned int resp_max_len = 2 * resp_len;\n+\n+\tprint_buffer(\"before bytes:\", send_data, send_len);\n+\n+\tp = send_packet;\n+\n+\tfor (i = 0; i < send_len; i++) {\n+\t\tcurrent_byte = send_data[i];\n+\t\tswitch (current_byte) {\n+\t\tcase SPI_BYTE_IDLE:\n+\t\t\t*p++ = SPI_BYTE_IDLE;\n+\t\t\t*p++ = xor_20(current_byte);\n+\t\t\tbreak;\n+\t\tcase SPI_BYTE_ESC:\n+\t\t\t*p++ = SPI_BYTE_ESC;\n+\t\t\t*p++ = xor_20(current_byte);\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\t*p++ = current_byte;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\tprint_buffer(\"before spi:\", send_packet, p-send_packet);\n+\n+\treorder_phy_data(32, send_packet, p - send_packet);\n+\n+\tprint_buffer(\"after order to spi:\", send_packet, p-send_packet);\n+\n+\t/* call spi */\n+\ttx_buffer = send_packet;\n+\ttx_len = p - send_packet;\n+\trx_buffer = resp_packet;\n+\trx_len = resp_max_len;\n+\tspi_flags = SPI_NOT_FOUND;\n+\n+read_again:\n+\tret = spi_command(dev->dev, dev->chipselect, tx_len, tx_buffer,\n+\t\t\trx_len, rx_buffer);\n+\tif (ret)\n+\t\treturn -EBUSY;\n+\n+\tprint_buffer(\"read from spi:\", rx_buffer, rx_len);\n+\n+\t/* look for SOP firstly*/\n+\tret = resp_find_sop_eop(rx_buffer, rx_len - 1, spi_flags);\n+\tif (ret != SPI_FOUND_EOP) {\n+\t\ttx_buffer = NULL;\n+\t\ttx_len = 0;\n+\t\tif (retry++ > 10) {\n+\t\t\tdev_err(NULL, \"cannot found valid data from SPI\\n\");\n+\t\t\treturn -EBUSY;\n+\t\t}\n+\n+\t\tif (ret == SPI_FOUND_SOP) {\n+\t\t\trx_buffer += rx_len;\n+\t\t\tresp_max_len += rx_len;\n+\t\t}\n+\n+\t\tspi_flags = ret;\n+\t\tgoto read_again;\n+\t}\n+\n+\tprint_buffer(\"found valid data:\", resp_packet, resp_max_len);\n+\n+\t/* analyze response packet */\n+\ti = 0;\n+\tp = resp_data;\n+\twhile (i < resp_max_len) {\n+\t\tcurrent_byte = resp_packet[i];\n+\t\tswitch (current_byte) {\n+\t\tcase SPI_BYTE_IDLE:\n+\t\t\ti++;\n+\t\t\tbreak;\n+\t\tcase SPI_BYTE_ESC:\n+\t\t\ti++;\n+\t\t\tcurrent_byte = resp_packet[i];\n+\t\t\t*p++ = xor_20(current_byte);\n+\t\t\ti++;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\t*p++ = current_byte;\n+\t\t\ti++;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\t/* receive \"4a\" means the SPI is idle, not valid data */\n+\t*valid_resp_len = p - resp_data;\n+\tif (*valid_resp_len == 0) {\n+\t\tdev_err(NULL, \"error: repond package without valid data\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int packet_to_byte_conver(struct spi_transaction_dev *dev,\n+\t\tunsigned int send_len, unsigned char *send_buf,\n+\t\tunsigned int resp_len, unsigned char *resp_buf,\n+\t\tunsigned int *valid)\n+{\n+\tint ret = 0;\n+\tunsigned int i;\n+\tunsigned char current_byte;\n+\tunsigned int resp_max_len;\n+\tunsigned char *send_packet = dev->buffer->packet_send;\n+\tunsigned char *resp_packet = dev->buffer->packet_resp;\n+\tunsigned char *p;\n+\tunsigned int valid_resp_len = 0;\n+\n+\tprint_buffer(\"before packet:\", send_buf, send_len);\n+\n+\tresp_max_len = 2 * resp_len + 4;\n+\n+\tp = send_packet;\n+\n+\t/* SOP header */\n+\t*p++ = SPI_PACKET_SOP;\n+\n+\t*p++ = SPI_PACKET_CHANNEL;\n+\t*p++ = 0;\n+\n+\t/* append the data into a packet */\n+\tfor (i = 0; i < send_len; i++) {\n+\t\tcurrent_byte = send_buf[i];\n+\n+\t\t/* EOP for last byte */\n+\t\tif (i == send_len - 1)\n+\t\t\t*p++ = SPI_PACKET_EOP;\n+\n+\t\tswitch (current_byte) {\n+\t\tcase SPI_PACKET_SOP:\n+\t\tcase SPI_PACKET_EOP:\n+\t\tcase SPI_PACKET_CHANNEL:\n+\t\tcase SPI_PACKET_ESC:\n+\t\t\t*p++ = SPI_PACKET_ESC;\n+\t\t\t*p++ = xor_20(current_byte);\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\t*p++ = current_byte;\n+\t\t}\n+\t}\n+\n+\tret = byte_to_core_convert(dev, p - send_packet,\n+\t\t\tsend_packet, resp_max_len, resp_packet,\n+\t\t\t&valid_resp_len);\n+\tif (ret)\n+\t\treturn -EBUSY;\n+\n+\tprint_buffer(\"after byte conver:\", resp_packet, valid_resp_len);\n+\n+\t/* analyze the response packet */\n+\tp = resp_buf;\n+\n+\t/* look for SOP */\n+\tfor (i = 0; i < valid_resp_len; i++) {\n+\t\tif (resp_packet[i] == SPI_PACKET_SOP)\n+\t\t\tbreak;\n+\t}\n+\n+\tif (i == valid_resp_len) {\n+\t\tdev_err(NULL, \"error on analyze response packet 0x%x\\n\",\n+\t\t\t\tresp_packet[i]);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\ti++;\n+\n+\t/* continue parsing data after SOP */\n+\twhile (i < valid_resp_len) {\n+\t\tcurrent_byte = resp_packet[i];\n+\n+\t\tswitch (current_byte) {\n+\t\tcase SPI_PACKET_ESC:\n+\t\tcase SPI_PACKET_CHANNEL:\n+\t\tcase SPI_PACKET_SOP:\n+\t\t\ti++;\n+\t\t\tcurrent_byte = resp_packet[i];\n+\t\t\t*p++ = xor_20(current_byte);\n+\t\t\ti++;\n+\t\t\tbreak;\n+\t\tcase SPI_PACKET_EOP:\n+\t\t\ti++;\n+\t\t\tcurrent_byte = resp_packet[i];\n+\t\t\tif (current_byte == SPI_PACKET_ESC ||\n+\t\t\t\t\tcurrent_byte == SPI_PACKET_CHANNEL ||\n+\t\t\t\t\tcurrent_byte == SPI_PACKET_SOP) {\n+\t\t\t\ti++;\n+\t\t\t\tcurrent_byte = resp_packet[i];\n+\t\t\t\t*p++ = xor_20(current_byte);\n+\t\t\t} else\n+\t\t\t\t*p++ = current_byte;\n+\t\t\ti = valid_resp_len;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\t*p++ = current_byte;\n+\t\t\ti++;\n+\t\t}\n+\n+\t}\n+\n+\t*valid = p - resp_buf;\n+\n+\tprint_buffer(\"after packet:\", resp_buf, *valid);\n+\n+\treturn ret;\n+}\n+\n+static int do_transaction(struct spi_transaction_dev *dev, unsigned int addr,\n+\t\tunsigned int size, unsigned char *data,\n+\t\tunsigned int trans_type)\n+{\n+\n+\tstruct spi_tran_header header;\n+\tunsigned char *transaction = dev->buffer->tran_send;\n+\tunsigned char *response = dev->buffer->tran_resp;\n+\tunsigned char *p;\n+\tint ret = 0;\n+\tunsigned int i;\n+\tunsigned int valid_len = 0;\n+\n+\t/* make transacation header */\n+\tINIT_SPI_TRAN_HEADER(trans_type, size, addr);\n+\n+\t/* fill the header */\n+\tp = transaction;\n+\topae_memcpy(p, &header, sizeof(struct spi_tran_header));\n+\tp = p + sizeof(struct spi_tran_header);\n+\n+\tswitch (trans_type) {\n+\tcase SPI_TRAN_SEQ_WRITE:\n+\tcase SPI_TRAN_NON_SEQ_WRITE:\n+\t\tfor (i = 0; i < size; i++)\n+\t\t\t*p++ = *data++;\n+\n+\t\tret = packet_to_byte_conver(dev, size + HEADER_LEN,\n+\t\t\t\ttransaction, RESPONSE_LEN, response,\n+\t\t\t\t&valid_len);\n+\t\tif (ret)\n+\t\t\treturn -EBUSY;\n+\n+\t\t/* check the result */\n+\t\tif (size != ((unsigned int)(response[2] & 0xff) << 8 |\n+\t\t\t(unsigned int)(response[3] & 0xff)))\n+\t\t\tret = -EBUSY;\n+\n+\t\tbreak;\n+\tcase SPI_TRAN_SEQ_READ:\n+\tcase SPI_TRAN_NON_SEQ_READ:\n+\t\tret = packet_to_byte_conver(dev, HEADER_LEN,\n+\t\t\t\ttransaction, size, response,\n+\t\t\t\t&valid_len);\n+\t\tif (ret || valid_len != size)\n+\t\t\treturn -EBUSY;\n+\n+\t\tfor (i = 0; i < size; i++)\n+\t\t\t*data++ = *response++;\n+\n+\t\tret = 0;\n+\t\tbreak;\n+\t}\n+\n+\treturn ret;\n+}\n+\n+int spi_transaction_read(struct spi_transaction_dev *dev, unsigned int addr,\n+\t\tunsigned int size, unsigned char *data)\n+{\n+\treturn do_transaction(dev, addr, size, data,\n+\t\t\t(size > SPI_REG_BYTES) ?\n+\t\t\tSPI_TRAN_SEQ_READ : SPI_TRAN_NON_SEQ_READ);\n+}\n+\n+int spi_transaction_write(struct spi_transaction_dev *dev, unsigned int addr,\n+\t\tunsigned int size, unsigned char *data)\n+{\n+\treturn do_transaction(dev, addr, size, data,\n+\t\t\t(size > SPI_REG_BYTES) ?\n+\t\t\tSPI_TRAN_SEQ_WRITE : SPI_TRAN_NON_SEQ_WRITE);\n+}\n+\n+struct spi_transaction_dev *spi_transaction_init(struct altera_spi_device *dev,\n+\t\tint chipselect)\n+{\n+\tstruct spi_transaction_dev *spi_tran_dev;\n+\n+\tspi_tran_dev = opae_malloc(sizeof(struct spi_transaction_dev));\n+\tif (!spi_tran_dev)\n+\t\treturn NULL;\n+\n+\tspi_tran_dev->dev = dev;\n+\tspi_tran_dev->chipselect = chipselect;\n+\n+\tspi_tran_dev->buffer = opae_malloc(sizeof(struct spi_tran_buffer));\n+\tif (!spi_tran_dev->buffer) {\n+\t\topae_free(spi_tran_dev);\n+\t\treturn NULL;\n+\t}\n+\n+\treturn spi_tran_dev;\n+}\n+\n+void spi_transaction_remove(struct spi_transaction_dev *dev)\n+{\n+\tif (dev && dev->buffer)\n+\t\topae_free(dev->buffer);\n+\tif (dev)\n+\t\topae_free(dev);\n+}\ndiff --git a/drivers/raw/ifpga_rawdev/base/osdep_rte/osdep_generic.h b/drivers/raw/ifpga_rawdev/base/osdep_rte/osdep_generic.h\nindex 3d9a0ca..3ff49a8 100644\n--- a/drivers/raw/ifpga_rawdev/base/osdep_rte/osdep_generic.h\n+++ b/drivers/raw/ifpga_rawdev/base/osdep_rte/osdep_generic.h\n@@ -11,6 +11,7 @@\n #include <rte_log.h>\n #include <rte_io.h>\n #include <rte_malloc.h>\n+#include <rte_byteorder.h>\n #include <rte_memcpy.h>\n \n #define dev_printf(level, fmt, args...) \\\n@@ -43,5 +44,18 @@\n #define spinlock_lock(x) rte_spinlock_lock(x)\n #define spinlock_unlock(x) rte_spinlock_unlock(x)\n \n+#define cpu_to_be16(o) rte_cpu_to_be_16(o)\n+#define cpu_to_be32(o) rte_cpu_to_be_32(o)\n+#define cpu_to_be64(o) rte_cpu_to_be_64(o)\n+#define cpu_to_le16(o) rte_cpu_to_le_16(o)\n+#define cpu_to_le32(o) rte_cpu_to_le_32(o)\n+#define cpu_to_le64(o) rte_cpu_to_le_64(o)\n+\n #define opae_memcpy(a, b, c) rte_memcpy((a), (b), (c))\n+\n+static inline unsigned long msecs_to_timer_cycles(unsigned int m)\n+{\n+\treturn rte_get_timer_hz() * (m / 1000);\n+}\n+\n #endif\n",
    "prefixes": [
        "v5",
        "09/14"
    ]
}