From: Tianfei zhang <tianfei.zh...@intel.com>

Add secure max10 device support.

Signed-off-by: Tianfei zhang <tianfei.zh...@intel.com>
Signed-off-by: Andy Pei <andy....@intel.com>
---
 drivers/raw/ifpga/base/ifpga_defines.h    |   2 +
 drivers/raw/ifpga/base/ifpga_fme.c        |  26 ++++--
 drivers/raw/ifpga/base/opae_intel_max10.c | 137 +++++++++++++++++++++++++-----
 drivers/raw/ifpga/base/opae_intel_max10.h |  80 ++++++++++++-----
 4 files changed, 198 insertions(+), 47 deletions(-)

diff --git a/drivers/raw/ifpga/base/ifpga_defines.h 
b/drivers/raw/ifpga/base/ifpga_defines.h
index 8993cc6..1e84b15 100644
--- a/drivers/raw/ifpga/base/ifpga_defines.h
+++ b/drivers/raw/ifpga/base/ifpga_defines.h
@@ -1698,6 +1698,8 @@ struct ifpga_fme_board_info {
        u32 patch_version;
        u32 minor_version;
        u32 major_version;
+       u32 max10_version;
+       u32 nios_fw_version;
        u32 nums_of_retimer;
        u32 ports_per_retimer;
        u32 nums_of_fvl;
diff --git a/drivers/raw/ifpga/base/ifpga_fme.c 
b/drivers/raw/ifpga/base/ifpga_fme.c
index 794ca09..87fa596 100644
--- a/drivers/raw/ifpga/base/ifpga_fme.c
+++ b/drivers/raw/ifpga/base/ifpga_fme.c
@@ -825,6 +825,7 @@ static int board_type_to_info(u32 type,
 static int fme_get_board_interface(struct ifpga_fme_hw *fme)
 {
        struct fme_bitstream_id id;
+       u32 val;
 
        if (fme_hdr_get_bitstream_id(fme, &id.id))
                return -EINVAL;
@@ -850,6 +851,18 @@ static int fme_get_board_interface(struct ifpga_fme_hw 
*fme)
                        fme->board_info.nums_of_fvl,
                        fme->board_info.ports_per_fvl);
 
+       if (max10_sys_read(MAX10_BUILD_VER, &val))
+               return -EINVAL;
+       fme->board_info.max10_version = val & 0xffffff;
+
+       if (max10_sys_read(NIOS2_FW_VERSION, &val))
+               return -EINVAL;
+       fme->board_info.nios_fw_version = val & 0xffffff;
+
+       dev_info(fme, "max10 version 0x%x, nios fw version 0x%x\n",
+               fme->board_info.max10_version,
+               fme->board_info.nios_fw_version);
+
        return 0;
 }
 
@@ -858,16 +871,11 @@ static int spi_self_checking(void)
        u32 val;
        int ret;
 
-       ret = max10_reg_read(0x30043c, &val);
+       ret = max10_sys_read(MAX10_TEST_REG, &val);
        if (ret)
                return -EIO;
 
-       if (val != 0x87654321) {
-               dev_err(NULL, "Read MAX10 test register fail: 0x%x\n", val);
-               return -EIO;
-       }
-
-       dev_info(NULL, "Read MAX10 test register success, SPI self-test 
done\n");
+       dev_info(NULL, "Read MAX10 test register 0x%x\n", val);
 
        return 0;
 }
@@ -1283,7 +1291,7 @@ int fme_mgr_get_retimer_status(struct ifpga_fme_hw *fme,
        if (!dev)
                return -ENODEV;
 
-       if (max10_reg_read(PKVL_LINK_STATUS, &val)) {
+       if (max10_sys_read(PKVL_LINK_STATUS, &val)) {
                dev_err(dev, "%s: read pkvl status fail\n", __func__);
                return -EINVAL;
        }
@@ -1311,7 +1319,7 @@ int fme_mgr_get_sensor_value(struct ifpga_fme_hw *fme,
        if (!dev)
                return -ENODEV;
 
-       if (max10_reg_read(sensor->value_reg, value)) {
+       if (max10_sys_read(sensor->value_reg, value)) {
                dev_err(dev, "%s: read sensor value register 0x%x fail\n",
                                __func__, sensor->value_reg);
                return -EINVAL;
diff --git a/drivers/raw/ifpga/base/opae_intel_max10.c 
b/drivers/raw/ifpga/base/opae_intel_max10.c
index ae7a8df..748ab56 100644
--- a/drivers/raw/ifpga/base/opae_intel_max10.c
+++ b/drivers/raw/ifpga/base/opae_intel_max10.c
@@ -30,6 +30,22 @@ int max10_reg_write(unsigned int reg, unsigned int val)
                        reg, 4, (unsigned char *)&tmp);
 }
 
+int max10_sys_read(unsigned int offset, unsigned int *val)
+{
+       if (!g_max10)
+               return -ENODEV;
+
+       return max10_reg_read(g_max10->base + offset, val);
+}
+
+int max10_sys_write(unsigned int offset, unsigned int val)
+{
+       if (!g_max10)
+               return -ENODEV;
+
+       return max10_reg_write(g_max10->base + offset, val);
+}
+
 static struct max10_compatible_id max10_id_table[] = {
        {.compatible = MAX10_PAC,},
        {.compatible = MAX10_PAC_N3000,},
@@ -66,7 +82,8 @@ static void max10_check_capability(struct intel_max10_device 
*max10)
                max10->flags |= MAX10_FLAGS_NO_I2C2 |
                                MAX10_FLAGS_NO_BMCIMG_FLASH;
                dev_info(max10, "found %s card\n", max10->id->compatible);
-       }
+       } else
+               max10->flags |= MAX10_FLAGS_MAC_CACHE;
 }
 
 static int altera_nor_flash_read(u32 offset,
@@ -100,7 +117,7 @@ static int enable_nor_flash(bool on)
        unsigned int val = 0;
        int ret;
 
-       ret = max10_reg_read(RSU_REG_OFF, &val);
+       ret = max10_sys_read(RSU_REG, &val);
        if (ret) {
                dev_err(NULL "enabling flash error\n");
                return ret;
@@ -111,7 +128,7 @@ static int enable_nor_flash(bool on)
        else
                val &= ~RSU_ENABLE;
 
-       return max10_reg_write(RSU_REG_OFF, val);
+       return max10_sys_write(RSU_REG, val);
 }
 
 static int init_max10_device_table(struct intel_max10_device *max10)
@@ -123,7 +140,7 @@ static int init_max10_device_table(struct 
intel_max10_device *max10)
        u32 dt_size, dt_addr, val;
        int ret;
 
-       ret = max10_reg_read(DT_AVAIL_REG_OFF, &val);
+       ret = max10_sys_read(DT_AVAIL_REG, &val);
        if (ret) {
                dev_err(max10 "cannot read DT_AVAIL_REG\n");
                return ret;
@@ -134,7 +151,7 @@ static int init_max10_device_table(struct 
intel_max10_device *max10)
                return -EINVAL;
        }
 
-       ret = max10_reg_read(DT_BASE_ADDR_REG_OFF, &dt_addr);
+       ret = max10_sys_read(DT_BASE_ADDR_REG, &dt_addr);
        if (ret) {
                dev_info(max10 "cannot get base addr of device table\n");
                return ret;
@@ -315,7 +332,7 @@ static int max10_add_sensor(struct raw_sensor_info *info,
                if (!sensor_reg_valid(&info->regs[i]))
                        continue;
 
-               ret = max10_reg_read(info->regs[i].regoff, &val);
+               ret = max10_sys_read(info->regs[i].regoff, &val);
                if (ret)
                        break;
 
@@ -355,7 +372,8 @@ static int max10_add_sensor(struct raw_sensor_info *info,
        return ret;
 }
 
-static int max10_sensor_init(struct intel_max10_device *dev)
+static int
+max10_sensor_init(struct intel_max10_device *dev, int parent)
 {
        int i, ret = 0, offset = 0;
        const fdt32_t *num;
@@ -370,7 +388,7 @@ static int max10_sensor_init(struct intel_max10_device *dev)
                return 0;
        }
 
-       fdt_for_each_subnode(offset, fdt_root, 0) {
+       fdt_for_each_subnode(offset, fdt_root, parent) {
                ptr = fdt_get_name(fdt_root, offset, NULL);
                if (!ptr) {
                        dev_err(dev, "failed to fdt get name\n");
@@ -417,7 +435,16 @@ static int max10_sensor_init(struct intel_max10_device 
*dev)
                                continue;
                        }
 
-                       raw->regs[i].regoff = start;
+                       /* This is a hack to compatible with non-secure
+                        * solution. If sensors are included in root node,
+                        * then it's non-secure dtb, which use absolute addr
+                        * of non-secure solution.
+                        */
+                       if (parent)
+                               raw->regs[i].regoff = start;
+                       else
+                               raw->regs[i].regoff = start -
+                                       MAX10_BASE_ADDR;
                        raw->regs[i].size = size;
                }
 
@@ -469,6 +496,63 @@ static int max10_sensor_init(struct intel_max10_device 
*dev)
        return ret;
 }
 
+static int check_max10_version(struct intel_max10_device *dev)
+{
+       unsigned int v;
+
+       if (!max10_reg_read(MAX10_SEC_BASE_ADDR + MAX10_BUILD_VER,
+                               &v)) {
+               if (v != 0xffffffff) {
+                       dev_info(dev, "secure MAX10 detected\n");
+                       dev->base = MAX10_SEC_BASE_ADDR;
+                       dev->flags |= MAX10_FLAGS_SECURE;
+               } else {
+                       dev_info(dev, "non-secure MAX10 detected\n");
+                       dev->base = MAX10_BASE_ADDR;
+               }
+               return 0;
+       }
+
+       return -ENODEV;
+}
+
+static int
+max10_secure_hw_init(struct intel_max10_device *dev)
+{
+       int offset, sysmgr_offset = 0;
+       char *fdt_root;
+
+       fdt_root = dev->fdt_root;
+       if (!fdt_root) {
+               dev_debug(dev, "skip init as not find Device Tree\n");
+               return 0;
+       }
+
+       fdt_for_each_subnode(offset, fdt_root, 0) {
+               if (!fdt_node_check_compatible(fdt_root, offset,
+                                       "intel-max10,system-manager")) {
+                       sysmgr_offset = offset;
+                       break;
+               }
+       }
+
+       max10_check_capability(dev);
+
+       max10_sensor_init(dev, sysmgr_offset);
+
+       return 0;
+}
+
+static int
+max10_non_secure_hw_init(struct intel_max10_device *dev)
+{
+       max10_check_capability(dev);
+
+       max10_sensor_init(dev, 0);
+
+       return 0;
+}
+
 struct intel_max10_device *
 intel_max10_device_probe(struct altera_spi_device *spi,
                int chipselect)
@@ -492,32 +576,47 @@ struct intel_max10_device *
        /* set the max10 device firstly */
        g_max10 = dev;
 
-       /* init the MAX10 device table */
+       /* check the max10 version */
+       ret = check_max10_version(dev);
+       if (ret) {
+               dev_err(dev, "Failed to find max10 hardware!\n");
+               goto free_dev;
+       }
+
+       /* load the MAX10 device table */
        ret = init_max10_device_table(dev);
        if (ret) {
-               dev_err(dev, "init max10 device table fail\n");
+               dev_err(dev, "Init max10 device table fail\n");
                goto free_dev;
        }
 
-       max10_check_capability(dev);
+       /* init max10 devices, like sensor*/
+       if (dev->flags & MAX10_FLAGS_SECURE)
+               ret = max10_secure_hw_init(dev);
+       else
+               ret = max10_non_secure_hw_init(dev);
+       if (ret) {
+               dev_err(dev, "Failed to init max10 hardware!\n");
+               goto free_dtb;
+       }
 
        /* read FPGA loading information */
-       ret = max10_reg_read(FPGA_PAGE_INFO_OFF, &val);
+       ret = max10_sys_read(FPGA_PAGE_INFO, &val);
        if (ret) {
                dev_err(dev, "fail to get FPGA loading info\n");
-               goto spi_tran_fail;
+               goto release_max10_hw;
        }
        dev_info(dev, "FPGA loaded from %s Image\n", val ? "User" : "Factory");
 
-
-       max10_sensor_init(dev);
-
        return dev;
 
-spi_tran_fail:
+release_max10_hw:
+       max10_sensor_uinit();
+free_dtb:
        if (dev->fdt_root)
                opae_free(dev->fdt_root);
-       spi_transaction_remove(dev->spi_tran_dev);
+       if (dev->spi_tran_dev)
+               spi_transaction_remove(dev->spi_tran_dev);
 free_dev:
        g_max10 = NULL;
        opae_free(dev);
diff --git a/drivers/raw/ifpga/base/opae_intel_max10.h 
b/drivers/raw/ifpga/base/opae_intel_max10.h
index 90bf098..e632941 100644
--- a/drivers/raw/ifpga/base/opae_intel_max10.h
+++ b/drivers/raw/ifpga/base/opae_intel_max10.h
@@ -23,6 +23,8 @@ struct max10_compatible_id {
 #define MAX10_FLAGS_SPI                 BIT(3)
 #define MAX10_FLGAS_NIOS_SPI            BIT(4)
 #define MAX10_FLAGS_PKVL                BIT(5)
+#define MAX10_FLAGS_SECURE             BIT(6)
+#define MAX10_FLAGS_MAC_CACHE          BIT(7)
 
 struct intel_max10_device {
        unsigned int flags; /*max10 hardware capability*/
@@ -30,6 +32,7 @@ struct intel_max10_device {
        struct spi_transaction_dev *spi_tran_dev;
        struct max10_compatible_id *id; /*max10 compatible*/
        char *fdt_root;
+       unsigned int base; /* max10 base address */
 };
 
 /* retimer speed */
@@ -74,30 +77,69 @@ struct opae_retimer_status {
 #define FLASH_BASE 0x10000000
 #define FLASH_OPTION_BITS 0x10000
 
-#define NIOS2_FW_VERSION_OFF   0x300400
-#define RSU_REG_OFF            0x30042c
-#define FPGA_RP_LOAD           BIT(3)
-#define NIOS2_PRERESET         BIT(4)
-#define NIOS2_HANG             BIT(5)
-#define RSU_ENABLE             BIT(6)
-#define NIOS2_RESET            BIT(7)
-#define NIOS2_I2C2_POLL_STOP   BIT(13)
-#define FPGA_RECONF_REG_OFF    0x300430
-#define COUNTDOWN_START                BIT(18)
-#define MAX10_BUILD_VER_OFF    0x300468
-#define PCB_INFO               GENMASK(31, 24)
-#define MAX10_BUILD_VERION     GENMASK(23, 0)
-#define FPGA_PAGE_INFO_OFF     0x30046c
-#define DT_AVAIL_REG_OFF       0x300490
-#define DT_AVAIL               BIT(0)
-#define DT_BASE_ADDR_REG_OFF   0x300494
-#define PKVL_POLLING_CTRL       0x300480
-#define PKVL_LINK_STATUS        0x300564
+/* System Registers */
+#define MAX10_BASE_ADDR                0x300400
+#define MAX10_SEC_BASE_ADDR    0x300800
+/* Register offset of system registers */
+#define NIOS2_FW_VERSION       0x0
+#define MAX10_MACADDR1         0x10
+#define   MAX10_MAC_BYTE4      GENMASK(7, 0)
+#define   MAX10_MAC_BYTE3      GENMASK(15, 8)
+#define   MAX10_MAC_BYTE2      GENMASK(23, 16)
+#define   MAX10_MAC_BYTE1      GENMASK(31, 24)
+#define MAX10_MACADDR2         0x14
+#define   MAX10_MAC_BYTE6      GENMASK(7, 0)
+#define   MAX10_MAC_BYTE5      GENMASK(15, 8)
+#define   MAX10_MAC_COUNT      GENMASK(23, 16)
+#define RSU_REG                        0x2c
+#define   FPGA_RECONF_PAGE     GENMASK(2, 0)
+#define   FPGA_RP_LOAD         BIT(3)
+#define   NIOS2_PRERESET       BIT(4)
+#define   NIOS2_HANG           BIT(5)
+#define   RSU_ENABLE           BIT(6)
+#define   NIOS2_RESET          BIT(7)
+#define   NIOS2_I2C2_POLL_STOP BIT(13)
+#define   PKVL_EEPROM_LOAD     BIT(31)
+#define FPGA_RECONF_REG                0x30
+#define MAX10_TEST_REG         0x3c
+#define   COUNTDOWN_START      BIT(18)
+#define MAX10_BUILD_VER                0x68
+#define   MAX10_VERSION_MAJOR  GENMASK(23, 16)
+#define   PCB_INFO             GENMASK(31, 24)
+#define FPGA_PAGE_INFO         0x6c
+#define DT_AVAIL_REG           0x90
+#define   DT_AVAIL             BIT(0)
+#define DT_BASE_ADDR_REG       0x94
+#define MAX10_DOORBELL         0x400
+#define   RSU_REQUEST          BIT(0)
+#define   SEC_PROGRESS         GENMASK(7, 4)
+#define   HOST_STATUS          GENMASK(11, 8)
+#define   SEC_STATUS           GENMASK(23, 16)
+
+/* PKVL related registers, in system register region */
+#define PKVL_POLLING_CTRL              0x80
+#define   POLLING_MODE                 GENMASK(15, 0)
+#define   PKVL_A_PRELOAD               BIT(16)
+#define   PKVL_A_PRELOAD_TIMEOUT       BIT(17)
+#define   PKVL_A_DATA_TOO_BIG          BIT(18)
+#define   PKVL_A_HDR_CHECKSUM          BIT(20)
+#define   PKVL_B_PRELOAD               BIT(24)
+#define   PKVL_B_PRELOAD_TIMEOUT       BIT(25)
+#define   PKVL_B_DATA_TOO_BIG          BIT(26)
+#define   PKVL_B_HDR_CHECKSUM          BIT(28)
+#define   PKVL_EEPROM_UPG_STATUS       GENMASK(31, 16)
+#define PKVL_LINK_STATUS               0x164
+#define PKVL_A_VERSION                 0x254
+#define PKVL_B_VERSION                 0x258
+#define   SERDES_VERSION               GENMASK(15, 0)
+#define   SBUS_VERSION                 GENMASK(31, 16)
 
 #define DFT_MAX_SIZE           0x7e0000
 
 int max10_reg_read(unsigned int reg, unsigned int *val);
 int max10_reg_write(unsigned int reg, unsigned int val);
+int max10_sys_read(unsigned int offset, unsigned int *val);
+int max10_sys_write(unsigned int offset, unsigned int val);
 struct intel_max10_device *
 intel_max10_device_probe(struct altera_spi_device *spi,
                int chipselect);
-- 
1.8.3.1

Reply via email to