From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by dpdk.org (Postfix) with ESMTP id E2EE15398 for ; Fri, 29 Mar 2019 17:00:34 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 29 Mar 2019 09:00:34 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.60,284,1549958400"; d="scan'208";a="156993188" Received: from dpdkx8602.sh.intel.com ([10.67.110.200]) by fmsmga004.fm.intel.com with ESMTP; 29 Mar 2019 09:00:32 -0700 From: Rosen Xu To: dev@dpdk.org Cc: ferruh.yigit@intel.com, tianfei.zhang@intel.com, dan.wei@intel.com, rosen.xu@intel.com, andy.pei@intel.com, qiming.yang@intel.com, haiyue.wang@intel.com, santos.chen@intel.com, zhang.zhang@intel.com Date: Fri, 29 Mar 2019 23:58:16 +0800 Message-Id: <1553875099-166351-13-git-send-email-rosen.xu@intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1553875099-166351-1-git-send-email-rosen.xu@intel.com> References: <1551338000-120348-1-git-send-email-rosen.xu@intel.com> <1553875099-166351-1-git-send-email-rosen.xu@intel.com> Subject: [dpdk-dev] [PATCH v2 12/15] raw/ifpga/base: add device tree support X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 29 Mar 2019 16:00:36 -0000 From: "Zhang, Tianfei" In PAC N3000 card, there is using device tree to descript the board info and sensor device info. Add device tree support by using libfdt library in Linux distribution. The end-user should pre-install the libfdt and libfdt-devel package. Signed-off-by: Zhang, Tianfei --- drivers/raw/ifpga_rawdev/base/Makefile | 2 + drivers/raw/ifpga_rawdev/base/opae_intel_max10.c | 183 +++++++++++++++++++++++ drivers/raw/ifpga_rawdev/base/opae_intel_max10.h | 10 ++ 3 files changed, 195 insertions(+) diff --git a/drivers/raw/ifpga_rawdev/base/Makefile b/drivers/raw/ifpga_rawdev/base/Makefile index c5bbcbd..86815b4 100644 --- a/drivers/raw/ifpga_rawdev/base/Makefile +++ b/drivers/raw/ifpga_rawdev/base/Makefile @@ -8,6 +8,7 @@ OSDEP := osdep_raw endif CFLAGS += -I$(RTE_SDK)/drivers/raw/ifpga_rawdev/base/$(OSDEP) +CFLAGS += -I libfdt SRCS-y += ifpga_api.c SRCS-y += ifpga_enumerate.c @@ -30,3 +31,4 @@ SRCS-y += opae_at24_eeprom.c SRCS-y += opae_eth_group.c SRCS-y += $(wildcard $(SRCDIR)/base/$(OSDEP)/*.c) +LDLIBS += -lfdt diff --git a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c index f354ee4..6b624aa 100644 --- a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c +++ b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c @@ -3,6 +3,7 @@ */ #include "opae_intel_max10.h" +#include static struct intel_max10_device *g_max10; @@ -24,6 +25,174 @@ int max10_reg_write(unsigned int reg, unsigned int val) reg, 4, (unsigned char *)&val); } +static struct max10_compatible_id max10_id_table[] = { + {.compatible = MAX10_PAC,}, + {.compatible = MAX10_PAC_N3000,}, + {.compatible = MAX10_PAC_END,} +}; + +static struct max10_compatible_id *max10_match_compatible(const char *fdt_root) +{ + struct max10_compatible_id *id = max10_id_table; + + for (; strcmp(id->compatible, MAX10_PAC_END); id++) { + if (fdt_node_check_compatible(fdt_root, 0, id->compatible)) + continue; + + return id; + } + + return NULL; +} + +static inline bool +is_max10_pac_n3000(struct intel_max10_device *max10) +{ + return max10->id && !strcmp(max10->id->compatible, + MAX10_PAC_N3000); +} + +static void max10_check_capability(struct intel_max10_device *max10) +{ + if (!max10->fdt_root) + return; + + if (is_max10_pac_n3000(max10)) { + max10->flags |= MAX10_FLAGS_NO_I2C2 | + MAX10_FLAGS_NO_BMCIMG_FLASH; + dev_info(max10, "found %s card\n", max10->id->compatible); + } +} + +static int altera_nor_flash_read(u32 offset, + void *buffer, u32 len) +{ + int word_len; + int i; + unsigned int *buf = (unsigned int *)buffer; + unsigned int value; + int ret; + + if (!buffer || len <= 0) + return -ENODEV; + + word_len = len/4; + + for (i = 0; i < word_len; i++) { + ret = max10_reg_read(FLASH_BASE + offset + i*4, + &value); + if (ret) + return -EBUSY; + + *buf++ = value; + } + + return 0; +} + +static int enable_nor_flash(bool on) +{ + unsigned int val = 0; + int ret; + + ret = max10_reg_read(RSU_REG_OFF, &val); + if (ret) { + dev_err(NULL "enabling flash error\n"); + return ret; + } + + if (on) + val |= RSU_ENABLE; + else + val &= ~RSU_ENABLE; + + return max10_reg_write(RSU_REG_OFF, val); +} + +static int init_max10_device_table(struct intel_max10_device *max10) +{ + struct max10_compatible_id *id; + struct fdt_header hdr; + char *fdt_root = NULL; + + u32 dt_size, dt_addr, val; + int ret; + + ret = max10_reg_read(DT_AVAIL_REG_OFF, &val); + if (ret) { + dev_err(max10 "cannot read DT_AVAIL_REG\n"); + return ret; + } + + if (!(val & DT_AVAIL)) { + dev_err(max10 "DT not available\n"); + return -EINVAL; + } + + ret = max10_reg_read(DT_BASE_ADDR_REG_OFF, &dt_addr); + if (ret) { + dev_info(max10 "cannot get base addr of device table\n"); + return ret; + } + + ret = enable_nor_flash(true); + if (ret) { + dev_err(max10 "fail to enable flash\n"); + return ret; + } + + ret = altera_nor_flash_read(dt_addr, &hdr, sizeof(hdr)); + if (ret) { + dev_err(max10 "read fdt header fail\n"); + goto done; + } + + ret = fdt_check_header(&hdr); + if (ret) { + dev_err(max10 "check fdt header fail\n"); + goto done; + } + + dt_size = fdt_totalsize(&hdr); + if (dt_size > DFT_MAX_SIZE) { + dev_err(max10 "invalid device table size\n"); + ret = -EINVAL; + goto done; + } + + fdt_root = opae_malloc(dt_size); + if (!fdt_root) { + ret = -ENOMEM; + goto done; + } + + ret = altera_nor_flash_read(dt_addr, fdt_root, dt_size); + if (ret) { + dev_err(max10 "cannot read device table\n"); + goto done; + } + + id = max10_match_compatible(fdt_root); + if (!id) { + dev_err(max10 "max10 compatible not found\n"); + ret = -ENODEV; + goto done; + } + + max10->flags |= MAX10_FLAGS_DEVICE_TABLE; + + max10->id = id; + max10->fdt_root = fdt_root; + +done: + ret = enable_nor_flash(false); + + if (ret && fdt_root) + opae_free(fdt_root); + + return ret; +} + struct intel_max10_device * intel_max10_device_probe(struct altera_spi_device *spi, int chipselect) @@ -47,6 +216,15 @@ struct intel_max10_device * /* set the max10 device firstly */ g_max10 = dev; + /* init the MAX10 device table */ + ret = init_max10_device_table(dev); + if (ret) { + dev_err(dev, "init max10 device table fail\n"); + goto free_dev; + } + + max10_check_capability(dev); + /* read FPGA loading information */ ret = max10_reg_read(FPGA_PAGE_INFO_OFF, &val); if (ret) { @@ -65,6 +243,8 @@ struct intel_max10_device * return dev; spi_tran_fail: + if (dev->fdt_root) + opae_free(dev->fdt_root); spi_transaction_remove(dev->spi_tran_dev); free_dev: g_max10 = NULL; @@ -81,6 +261,9 @@ int intel_max10_device_remove(struct intel_max10_device *dev) if (dev->spi_tran_dev) spi_transaction_remove(dev->spi_tran_dev); + if (dev->fdt_root) + opae_free(dev->fdt_root); + g_max10 = NULL; opae_free(dev); diff --git a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h index 08b387e..a52b63e 100644 --- a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h +++ b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h @@ -8,6 +8,14 @@ #include "opae_osdep.h" #include "opae_spi.h" +struct max10_compatible_id { + char compatible[128]; +}; + +#define MAX10_PAC "intel,max10" +#define MAX10_PAC_N3000 "intel,max10-pac-n3000" +#define MAX10_PAC_END "intel,end" + /* max10 capability flags */ #define MAX10_FLAGS_NO_I2C2 BIT(0) #define MAX10_FLAGS_NO_BMCIMG_FLASH BIT(1) @@ -20,6 +28,8 @@ struct intel_max10_device { unsigned int flags; /*max10 hardware capability*/ struct altera_spi_device *spi_master; struct spi_transaction_dev *spi_tran_dev; + struct max10_compatible_id *id; /*max10 compatible*/ + char *fdt_root; }; /* retimer speed */ -- 1.8.3.1 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by dpdk.space (Postfix) with ESMTP id 22D21A05D3 for ; Fri, 29 Mar 2019 17:02:47 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id D215B5A6E; Fri, 29 Mar 2019 17:00:49 +0100 (CET) Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by dpdk.org (Postfix) with ESMTP id E2EE15398 for ; Fri, 29 Mar 2019 17:00:34 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 29 Mar 2019 09:00:34 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.60,284,1549958400"; d="scan'208";a="156993188" Received: from dpdkx8602.sh.intel.com ([10.67.110.200]) by fmsmga004.fm.intel.com with ESMTP; 29 Mar 2019 09:00:32 -0700 From: Rosen Xu To: dev@dpdk.org Cc: ferruh.yigit@intel.com, tianfei.zhang@intel.com, dan.wei@intel.com, rosen.xu@intel.com, andy.pei@intel.com, qiming.yang@intel.com, haiyue.wang@intel.com, santos.chen@intel.com, zhang.zhang@intel.com Date: Fri, 29 Mar 2019 23:58:16 +0800 Message-Id: <1553875099-166351-13-git-send-email-rosen.xu@intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1553875099-166351-1-git-send-email-rosen.xu@intel.com> References: <1551338000-120348-1-git-send-email-rosen.xu@intel.com> <1553875099-166351-1-git-send-email-rosen.xu@intel.com> Subject: [dpdk-dev] [PATCH v2 12/15] raw/ifpga/base: add device tree support X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Content-Type: text/plain; charset="UTF-8" Message-ID: <20190329155816.htlDPXe_JPSrugE4or1TaTgqzHb8khu9pzuNA7LiWuw@z> From: "Zhang, Tianfei" In PAC N3000 card, there is using device tree to descript the board info and sensor device info. Add device tree support by using libfdt library in Linux distribution. The end-user should pre-install the libfdt and libfdt-devel package. Signed-off-by: Zhang, Tianfei --- drivers/raw/ifpga_rawdev/base/Makefile | 2 + drivers/raw/ifpga_rawdev/base/opae_intel_max10.c | 183 +++++++++++++++++++++++ drivers/raw/ifpga_rawdev/base/opae_intel_max10.h | 10 ++ 3 files changed, 195 insertions(+) diff --git a/drivers/raw/ifpga_rawdev/base/Makefile b/drivers/raw/ifpga_rawdev/base/Makefile index c5bbcbd..86815b4 100644 --- a/drivers/raw/ifpga_rawdev/base/Makefile +++ b/drivers/raw/ifpga_rawdev/base/Makefile @@ -8,6 +8,7 @@ OSDEP := osdep_raw endif CFLAGS += -I$(RTE_SDK)/drivers/raw/ifpga_rawdev/base/$(OSDEP) +CFLAGS += -I libfdt SRCS-y += ifpga_api.c SRCS-y += ifpga_enumerate.c @@ -30,3 +31,4 @@ SRCS-y += opae_at24_eeprom.c SRCS-y += opae_eth_group.c SRCS-y += $(wildcard $(SRCDIR)/base/$(OSDEP)/*.c) +LDLIBS += -lfdt diff --git a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c index f354ee4..6b624aa 100644 --- a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c +++ b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c @@ -3,6 +3,7 @@ */ #include "opae_intel_max10.h" +#include static struct intel_max10_device *g_max10; @@ -24,6 +25,174 @@ int max10_reg_write(unsigned int reg, unsigned int val) reg, 4, (unsigned char *)&val); } +static struct max10_compatible_id max10_id_table[] = { + {.compatible = MAX10_PAC,}, + {.compatible = MAX10_PAC_N3000,}, + {.compatible = MAX10_PAC_END,} +}; + +static struct max10_compatible_id *max10_match_compatible(const char *fdt_root) +{ + struct max10_compatible_id *id = max10_id_table; + + for (; strcmp(id->compatible, MAX10_PAC_END); id++) { + if (fdt_node_check_compatible(fdt_root, 0, id->compatible)) + continue; + + return id; + } + + return NULL; +} + +static inline bool +is_max10_pac_n3000(struct intel_max10_device *max10) +{ + return max10->id && !strcmp(max10->id->compatible, + MAX10_PAC_N3000); +} + +static void max10_check_capability(struct intel_max10_device *max10) +{ + if (!max10->fdt_root) + return; + + if (is_max10_pac_n3000(max10)) { + max10->flags |= MAX10_FLAGS_NO_I2C2 | + MAX10_FLAGS_NO_BMCIMG_FLASH; + dev_info(max10, "found %s card\n", max10->id->compatible); + } +} + +static int altera_nor_flash_read(u32 offset, + void *buffer, u32 len) +{ + int word_len; + int i; + unsigned int *buf = (unsigned int *)buffer; + unsigned int value; + int ret; + + if (!buffer || len <= 0) + return -ENODEV; + + word_len = len/4; + + for (i = 0; i < word_len; i++) { + ret = max10_reg_read(FLASH_BASE + offset + i*4, + &value); + if (ret) + return -EBUSY; + + *buf++ = value; + } + + return 0; +} + +static int enable_nor_flash(bool on) +{ + unsigned int val = 0; + int ret; + + ret = max10_reg_read(RSU_REG_OFF, &val); + if (ret) { + dev_err(NULL "enabling flash error\n"); + return ret; + } + + if (on) + val |= RSU_ENABLE; + else + val &= ~RSU_ENABLE; + + return max10_reg_write(RSU_REG_OFF, val); +} + +static int init_max10_device_table(struct intel_max10_device *max10) +{ + struct max10_compatible_id *id; + struct fdt_header hdr; + char *fdt_root = NULL; + + u32 dt_size, dt_addr, val; + int ret; + + ret = max10_reg_read(DT_AVAIL_REG_OFF, &val); + if (ret) { + dev_err(max10 "cannot read DT_AVAIL_REG\n"); + return ret; + } + + if (!(val & DT_AVAIL)) { + dev_err(max10 "DT not available\n"); + return -EINVAL; + } + + ret = max10_reg_read(DT_BASE_ADDR_REG_OFF, &dt_addr); + if (ret) { + dev_info(max10 "cannot get base addr of device table\n"); + return ret; + } + + ret = enable_nor_flash(true); + if (ret) { + dev_err(max10 "fail to enable flash\n"); + return ret; + } + + ret = altera_nor_flash_read(dt_addr, &hdr, sizeof(hdr)); + if (ret) { + dev_err(max10 "read fdt header fail\n"); + goto done; + } + + ret = fdt_check_header(&hdr); + if (ret) { + dev_err(max10 "check fdt header fail\n"); + goto done; + } + + dt_size = fdt_totalsize(&hdr); + if (dt_size > DFT_MAX_SIZE) { + dev_err(max10 "invalid device table size\n"); + ret = -EINVAL; + goto done; + } + + fdt_root = opae_malloc(dt_size); + if (!fdt_root) { + ret = -ENOMEM; + goto done; + } + + ret = altera_nor_flash_read(dt_addr, fdt_root, dt_size); + if (ret) { + dev_err(max10 "cannot read device table\n"); + goto done; + } + + id = max10_match_compatible(fdt_root); + if (!id) { + dev_err(max10 "max10 compatible not found\n"); + ret = -ENODEV; + goto done; + } + + max10->flags |= MAX10_FLAGS_DEVICE_TABLE; + + max10->id = id; + max10->fdt_root = fdt_root; + +done: + ret = enable_nor_flash(false); + + if (ret && fdt_root) + opae_free(fdt_root); + + return ret; +} + struct intel_max10_device * intel_max10_device_probe(struct altera_spi_device *spi, int chipselect) @@ -47,6 +216,15 @@ struct intel_max10_device * /* set the max10 device firstly */ g_max10 = dev; + /* init the MAX10 device table */ + ret = init_max10_device_table(dev); + if (ret) { + dev_err(dev, "init max10 device table fail\n"); + goto free_dev; + } + + max10_check_capability(dev); + /* read FPGA loading information */ ret = max10_reg_read(FPGA_PAGE_INFO_OFF, &val); if (ret) { @@ -65,6 +243,8 @@ struct intel_max10_device * return dev; spi_tran_fail: + if (dev->fdt_root) + opae_free(dev->fdt_root); spi_transaction_remove(dev->spi_tran_dev); free_dev: g_max10 = NULL; @@ -81,6 +261,9 @@ int intel_max10_device_remove(struct intel_max10_device *dev) if (dev->spi_tran_dev) spi_transaction_remove(dev->spi_tran_dev); + if (dev->fdt_root) + opae_free(dev->fdt_root); + g_max10 = NULL; opae_free(dev); diff --git a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h index 08b387e..a52b63e 100644 --- a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h +++ b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h @@ -8,6 +8,14 @@ #include "opae_osdep.h" #include "opae_spi.h" +struct max10_compatible_id { + char compatible[128]; +}; + +#define MAX10_PAC "intel,max10" +#define MAX10_PAC_N3000 "intel,max10-pac-n3000" +#define MAX10_PAC_END "intel,end" + /* max10 capability flags */ #define MAX10_FLAGS_NO_I2C2 BIT(0) #define MAX10_FLAGS_NO_BMCIMG_FLASH BIT(1) @@ -20,6 +28,8 @@ struct intel_max10_device { unsigned int flags; /*max10 hardware capability*/ struct altera_spi_device *spi_master; struct spi_transaction_dev *spi_tran_dev; + struct max10_compatible_id *id; /*max10 compatible*/ + char *fdt_root; }; /* retimer speed */ -- 1.8.3.1