@@ -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;
@@ -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;
@@ -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);
@@ -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);