[v1,1/2] raw/ifpga/base: add pmci driver

Message ID 1653443483-30971-2-git-send-email-wei.huang@intel.com (mailing list archive)
State New
Delegated to: Thomas Monjalon
Headers
Series Update rsu implementation |

Checks

Context Check Description
ci/checkpatch warning coding style issues
ci/iol-testing warning apply patch failure

Commit Message

Wei Huang May 25, 2022, 1:51 a.m. UTC
  PMCI (Platform Management Control Interface) is a new module in FPGA,
which is designed to cooperate with BMC chip to fulfill board management
functions.
This driver provide interfaces to access registers of BMC chip and
external flash of FPGA.

Signed-off-by: Wei Huang <wei.huang@intel.com>
Acked-by: Tianfei Zhang <tianfei.zhang@intel.com>
---
 drivers/raw/ifpga/base/ifpga_defines.h           | 103 ++-
 drivers/raw/ifpga/base/ifpga_feature_dev.c       |   2 +
 drivers/raw/ifpga/base/ifpga_feature_dev.h       |   1 +
 drivers/raw/ifpga/base/ifpga_fme.c               | 265 +++++--
 drivers/raw/ifpga/base/ifpga_fme_error.c         |   2 +
 drivers/raw/ifpga/base/ifpga_port_error.c        |   2 +-
 drivers/raw/ifpga/base/ifpga_sec_mgr.c           |   9 +-
 drivers/raw/ifpga/base/ifpga_sec_mgr.h           |   9 +-
 drivers/raw/ifpga/base/opae_hw_api.c             |  29 +
 drivers/raw/ifpga/base/opae_hw_api.h             |   1 +
 drivers/raw/ifpga/base/opae_intel_max10.c        | 938 ++++++++++++++++++++---
 drivers/raw/ifpga/base/opae_intel_max10.h        | 313 +++++++-
 drivers/raw/ifpga/base/opae_osdep.h              |  43 +-
 drivers/raw/ifpga/base/osdep_rte/osdep_generic.h |  10 +
 14 files changed, 1524 insertions(+), 203 deletions(-)
  

Patch

diff --git a/drivers/raw/ifpga/base/ifpga_defines.h b/drivers/raw/ifpga/base/ifpga_defines.h
index 9a280eb..7c8fa89 100644
--- a/drivers/raw/ifpga/base/ifpga_defines.h
+++ b/drivers/raw/ifpga/base/ifpga_defines.h
@@ -23,6 +23,7 @@ 
 #define FME_FEATURE_NIOS_SPI        "fme_nios_spi"
 #define FME_FEATURE_I2C_MASTER      "fme_i2c_master"
 #define FME_FEATURE_ETH_GROUP       "fme_eth_group"
+#define FME_FEATURE_PMCI            "fme_pmci"
 
 #define PORT_FEATURE_HEADER         "port_hdr"
 #define PORT_FEATURE_UAFU           "port_uafu"
@@ -91,6 +92,7 @@  enum fpga_id_type {
 #define FME_FEATURE_ID_NIOS_SPI 0xd
 #define FME_FEATURE_ID_I2C_MASTER  0xf
 #define FME_FEATURE_ID_ETH_GROUP 0x10
+#define FME_FEATURE_ID_PMCI      0x12
 
 #define PORT_FEATURE_ID_HEADER FEATURE_ID_FIU_HEADER
 #define PORT_FEATURE_ID_ERROR 0x10
@@ -266,6 +268,24 @@  struct feature_fme_bitstream_id {
 	union {
 		u64 csr;
 		struct {
+			u8 build_patch:8;
+			u8 build_minor:8;
+			u8 build_major:8;
+			u8 fvl_bypass:1;
+			u8 mac_lightweight:1;
+			u8 disagregate:1;
+			u8 lightweiht:1;
+			u8 seu:1;
+			u8 ptp:1;
+			u8 reserve:2;
+			u8 interface:4;
+			u32 afu_revision:12;
+			u8 patch:4;
+			u8 minor:4;
+			u8 major:4;
+			u8 reserved:4;
+		} v1;
+		struct {
 			u32 gitrepo_hash:32;	/* GIT repository hash */
 			/*
 			 * HSSI configuration identifier:
@@ -274,7 +294,8 @@  struct feature_fme_bitstream_id {
 			 * 2 - Ethernet
 			 */
 			u8  hssi_id:4;
-			u16 rsvd1:12;		/* Reserved */
+			u8  rsvd1:4;
+			u8  fim_type:8;
 			/* Bitstream version patch number */
 			u8  bs_verpatch:4;
 			/* Bitstream version minor number */
@@ -283,7 +304,7 @@  struct feature_fme_bitstream_id {
 			u8  bs_vermajor:4;
 			/* Bitstream version debug number */
 			u8  bs_verdebug:4;
-		};
+		} v2;
 	};
 };
 
@@ -1670,31 +1691,6 @@  struct bts_header {
 
 #define check_support(n) (n == 1 ? "support" : "no")
 
-/* bitstream id definition */
-struct fme_bitstream_id {
-	union {
-		u64 id;
-		struct {
-			u8 build_patch:8;
-			u8 build_minor:8;
-			u8 build_major:8;
-			u8 fvl_bypass:1;
-			u8 mac_lightweight:1;
-			u8 disagregate:1;
-			u8 lightweiht:1;
-			u8 seu:1;
-			u8 ptp:1;
-			u8 reserve:2;
-			u8 interface:4;
-			u32 afu_revision:12;
-			u8 patch:4;
-			u8 minor:4;
-			u8 major:4;
-			u8 reserved:4;
-		};
-	};
-};
-
 enum board_interface {
 	VC_8_10G = 0,
 	VC_4_25G = 1,
@@ -1703,10 +1699,30 @@  enum board_interface {
 	VC_2_2_25G = 4,
 };
 
+enum fim_type {
+	BASE_ADP = 0,
+	BASE_FDK,
+	BASE_X16_ADP,
+	BASE_X16_FDK,
+	FIMA_10G_ADP,
+	FIMA_25G_ADP,
+	FIMA_100G_ADP,
+	FIMB_ADP,
+	FIMC_ADP
+};
+
+enum hssi_id {
+	NO_HSSI = 0,
+	PCIE_RP,
+	ETHER_NET
+};
+
 enum pac_major {
 	VISTA_CREEK = 0,
 	RUSH_CREEK = 1,
 	DARBY_CREEK = 2,
+	LIGHTNING_CREEK = 3,
+	ARROW_CREEK = 5,
 };
 
 enum pac_minor {
@@ -1718,23 +1734,30 @@  enum pac_minor {
 struct opae_board_info {
 	enum pac_major major;
 	enum pac_minor minor;
-	enum board_interface type;
-
-	/* PAC features */
-	u8 fvl_bypass;
-	u8 mac_lightweight;
-	u8 disaggregate;
-	u8 lightweight;
-	u8 seu;
-	u8 ptp;
 
 	u32 boot_page;
 	u32 max10_version;
 	u32 nios_fw_version;
-	u32 nums_of_retimer;
-	u32 ports_per_retimer;
-	u32 nums_of_fvl;
-	u32 ports_per_fvl;
+
+	union {
+		struct {  /* N3000 specific */
+			enum board_interface type;
+			u8 fvl_bypass;
+			u8 mac_lightweight;
+			u8 disaggregate;
+			u8 lightweight;
+			u8 seu;
+			u8 ptp;
+			u32 nums_of_retimer;
+			u32 ports_per_retimer;
+			u32 nums_of_fvl;
+			u32 ports_per_fvl;
+		};
+		struct {
+			enum fim_type n6000_fim_type;
+			enum hssi_id n6000_hssi_id;
+		};
+	};
 };
 
 #pragma pack(pop)
diff --git a/drivers/raw/ifpga/base/ifpga_feature_dev.c b/drivers/raw/ifpga/base/ifpga_feature_dev.c
index dbecc7b..0a00af1 100644
--- a/drivers/raw/ifpga/base/ifpga_feature_dev.c
+++ b/drivers/raw/ifpga/base/ifpga_feature_dev.c
@@ -227,6 +227,8 @@  int port_clear_error(struct ifpga_port_hw *port)
 	&fme_i2c_master_ops),},
 	{FEATURE_DRV(FME_FEATURE_ID_ETH_GROUP, FME_FEATURE_ETH_GROUP,
 	&fme_eth_group_ops),},
+	{FEATURE_DRV(FME_FEATURE_ID_PMCI, FME_FEATURE_PMCI,
+	&fme_pmci_ops),},
 	{0, NULL, NULL}, /* end of arrary */
 };
 
diff --git a/drivers/raw/ifpga/base/ifpga_feature_dev.h b/drivers/raw/ifpga/base/ifpga_feature_dev.h
index b355d22..a637eb5 100644
--- a/drivers/raw/ifpga/base/ifpga_feature_dev.h
+++ b/drivers/raw/ifpga/base/ifpga_feature_dev.h
@@ -178,6 +178,7 @@  int do_pr(struct ifpga_hw *hw, u32 port_id, const char *buffer, u32 size,
 extern struct ifpga_feature_ops fme_i2c_master_ops;
 extern struct ifpga_feature_ops fme_eth_group_ops;
 extern struct ifpga_feature_ops fme_nios_spi_master_ops;
+extern struct ifpga_feature_ops fme_pmci_ops;
 
 int port_get_prop(struct ifpga_port_hw *port, struct feature_prop *prop);
 int port_set_prop(struct ifpga_port_hw *port, struct feature_prop *prop);
diff --git a/drivers/raw/ifpga/base/ifpga_fme.c b/drivers/raw/ifpga/base/ifpga_fme.c
index 43c7b9c..1b9a922 100644
--- a/drivers/raw/ifpga/base/ifpga_fme.c
+++ b/drivers/raw/ifpga/base/ifpga_fme.c
@@ -790,19 +790,32 @@  struct ifpga_feature_ops fme_emif_ops = {
 	.uinit = fme_emif_uinit,
 };
 
-static const char *board_type_to_string(u32 type)
-{
-	switch (type) {
-	case VC_8_10G:
-		return "VC_8x10G";
-	case VC_4_25G:
-		return "VC_4x25G";
-	case VC_2_1_25:
-		return "VC_2x1x25G";
-	case VC_4_25G_2_25G:
-		return "VC_4x25G+2x25G";
-	case VC_2_2_25G:
-		return "VC_2x2x25G";
+static const char *board_type_to_string(u32 board, u32 type)
+{
+	if (board == VISTA_CREEK) {
+		switch (type) {
+		case VC_8_10G:
+			return "8x10G";
+		case VC_4_25G:
+			return "4x25G";
+		case VC_2_1_25:
+			return "2x1x25G";
+		case VC_4_25G_2_25G:
+			return "4x25G+2x25G";
+		case VC_2_2_25G:
+			return "2x2x25G";
+		break;
+		}
+	} else {
+		switch (type) {
+		case FIMA_10G_ADP:
+			return "2x4x10G";
+		case FIMA_25G_ADP:
+			return "2x2x25G";
+		case FIMA_100G_ADP:
+			return "2x100G";
+		break;
+		}
 	}
 
 	return "unknown";
@@ -817,6 +830,12 @@  static const char *board_major_to_string(u32 major)
 		return "RUSH_CREEK";
 	case DARBY_CREEK:
 		return "DARBY_CREEK";
+	case LIGHTNING_CREEK:
+		return "LIGHTNING_CREEK";
+	case ARROW_CREEK:
+		return "ARROW_CREEK";
+	default:
+		break;
 	}
 
 	return "unknown";
@@ -859,35 +878,56 @@  static int board_type_to_info(u32 type,
 
 static int fme_get_board_interface(struct ifpga_fme_hw *fme)
 {
-	struct fme_bitstream_id id;
+	struct feature_fme_bitstream_id id;
 	struct ifpga_hw *hw;
 	u32 val;
+	const char *type = NULL;
+	int ret;
 
 	hw = fme->parent;
 	if (!hw)
 		return -ENODEV;
 
-	if (fme_hdr_get_bitstream_id(fme, &id.id))
+	if (fme_hdr_get_bitstream_id(fme, &id.csr))
 		return -EINVAL;
 
-	fme->board_info.major = id.major;
-	fme->board_info.minor = id.minor;
-	fme->board_info.type = id.interface;
-	fme->board_info.fvl_bypass = id.fvl_bypass;
-	fme->board_info.mac_lightweight = id.mac_lightweight;
-	fme->board_info.lightweight = id.lightweiht;
-	fme->board_info.disaggregate = id.disagregate;
-	fme->board_info.seu = id.seu;
-	fme->board_info.ptp = id.ptp;
+	if (id.v1.major == ARROW_CREEK) {
+		fme->board_info.major = id.v2.bs_vermajor;
+		fme->board_info.minor = id.v2.bs_verminor;
+		fme->board_info.n6000_fim_type = id.v2.fim_type;
+		fme->board_info.n6000_hssi_id = id.v2.hssi_id;
+		type = board_type_to_string(fme->board_info.major,
+				fme->board_info.n6000_fim_type);
+	} else {
+		fme->board_info.major = id.v1.major;
+		fme->board_info.minor = id.v1.minor;
+		fme->board_info.type = id.v1.interface;
+		fme->board_info.fvl_bypass = id.v1.fvl_bypass;
+		fme->board_info.mac_lightweight = id.v1.mac_lightweight;
+		fme->board_info.lightweight = id.v1.lightweiht;
+		fme->board_info.disaggregate = id.v1.disagregate;
+		fme->board_info.seu = id.v1.seu;
+		fme->board_info.ptp = id.v1.ptp;
+		type = board_type_to_string(fme->board_info.major,
+				fme->board_info.type);
+	}
 
 	dev_info(fme, "found: PCI dev: %02x:%02x:%x board: %s type: %s\n",
 			hw->pci_data->bus,
 			hw->pci_data->devid,
 			hw->pci_data->function,
 			board_major_to_string(fme->board_info.major),
-			board_type_to_string(fme->board_info.type));
+			type);
 
-	dev_info(fme, "support feature:\n"
+	ret = max10_get_fpga_load_info(fme->max10_dev, &val);
+	if (ret)
+		return ret;
+	fme->board_info.boot_page = val;
+
+	if (fme->board_info.major == VISTA_CREEK) {
+		dev_info(dev, "FPGA loaded from %s Image\n",
+			val ? "User" : "Factory");
+		dev_info(fme, "support feature:\n"
 			"fvl_bypass:%s\n"
 			"mac_lightweight:%s\n"
 			"lightweight:%s\n"
@@ -901,26 +941,29 @@  static int fme_get_board_interface(struct ifpga_fme_hw *fme)
 			check_support(fme->board_info.seu),
 			check_support(fme->board_info.ptp));
 
+		if (board_type_to_info(fme->board_info.type, &fme->board_info))
+			return -EINVAL;
 
-	if (board_type_to_info(fme->board_info.type, &fme->board_info))
-		return -EINVAL;
-
-	dev_info(fme, "get board info: nums_retimers %d ports_per_retimer %d nums_fvl %d ports_per_fvl %d\n",
+		dev_info(fme, "get board info: nums_retimers %d "
+			"ports_per_retimer %d nums_fvl %d "
+			"ports_per_fvl %d\n",
 			fme->board_info.nums_of_retimer,
 			fme->board_info.ports_per_retimer,
 			fme->board_info.nums_of_fvl,
 			fme->board_info.ports_per_fvl);
+	} else {
+		dev_info(dev, "FPGA loaded from %s Image\n",
+			val ? (val == 1 ? "User1" : "User2") : "Factory");
+	}
 
-	if (max10_sys_read(fme->max10_dev, FPGA_PAGE_INFO, &val))
-		return -EINVAL;
-	fme->board_info.boot_page = val & 0x7;
-
-	if (max10_sys_read(fme->max10_dev, MAX10_BUILD_VER, &val))
-		return -EINVAL;
+	ret = max10_get_bmc_version(fme->max10_dev, &val);
+	if (ret)
+		return ret;
 	fme->board_info.max10_version = val;
 
-	if (max10_sys_read(fme->max10_dev, NIOS2_FW_VERSION, &val))
-		return -EINVAL;
+	ret = max10_get_bmcfw_version(fme->max10_dev, &val);
+	if (ret)
+		return ret;
 	fme->board_info.nios_fw_version = val;
 
 	dev_info(fme, "max10 version 0x%x, nios fw version 0x%x\n",
@@ -983,11 +1026,25 @@  static int fme_spi_init(struct ifpga_feature *feature)
 
 	altera_spi_init(spi_master);
 
-	max10 = intel_max10_device_probe(spi_master, 0);
-	if (!max10) {
+	max10 = opae_zmalloc(sizeof(*max10));
+	if (!max10)
+		goto release_dev;
+
+	max10->spi_master = spi_master;
+	max10->type = M10_N3000;
+
+	max10->spi_tran_dev = spi_transaction_init(spi_master, 0);
+	if (!max10->spi_tran_dev) {
+		dev_err(fme, "%s spi tran init fail\n", __func__);
+		goto free_max10;
+	}
+
+	/* init the max10 device */
+	ret = intel_max10_device_init(max10);
+	if (ret) {
 		ret = -ENODEV;
 		dev_err(fme, "max10 init fail\n");
-		goto spi_fail;
+		goto release_spi_tran_dev;
 	}
 
 	fme->max10_dev = max10;
@@ -1002,17 +1059,24 @@  static int fme_spi_init(struct ifpga_feature *feature)
 
 max10_fail:
 	intel_max10_device_remove(fme->max10_dev);
-spi_fail:
+release_spi_tran_dev:
+	if (max10->spi_tran_dev)
+		spi_transaction_remove(max10->spi_tran_dev);
+free_max10:
+	opae_free(max10);
+release_dev:
 	altera_spi_release(spi_master);
-	return ret;
+	return -ENODEV;
 }
 
 static void fme_spi_uinit(struct ifpga_feature *feature)
 {
 	struct ifpga_fme_hw *fme = (struct ifpga_fme_hw *)feature->parent;
 
-	if (fme->max10_dev)
+	if (fme->max10_dev) {
 		intel_max10_device_remove(fme->max10_dev);
+		opae_free(fme->max10_dev);
+	}
 }
 
 struct ifpga_feature_ops fme_spi_master_ops = {
@@ -1157,27 +1221,37 @@  static int fme_nios_spi_init(struct ifpga_feature *feature)
 	/* 3. init the spi master*/
 	altera_spi_init(spi_master);
 
+	max10 = opae_zmalloc(sizeof(*max10));
+	if (!max10)
+		goto release_dev;
+
+	max10->spi_master = spi_master;
+	max10->type = M10_N3000;
+
+	max10->spi_tran_dev = spi_transaction_init(spi_master, 0);
+	if (!max10->spi_tran_dev) {
+		dev_err(fme, "%s spi tran init fail\n", __func__);
+		goto free_max10;
+	}
+
 	/* init the max10 device */
-	max10 = intel_max10_device_probe(spi_master, 0);
-	if (!max10) {
+	ret = intel_max10_device_init(max10);
+	if (ret) {
 		ret = -ENODEV;
 		dev_err(fme, "max10 init fail\n");
-		goto release_dev;
+		goto release_spi_tran_dev;
 	}
 
 	fme->max10_dev = max10;
-
 	max10->bus = hw->pci_data->bus;
-
 	fme_get_board_interface(fme);
-
 	mgr->sensor_list = &max10->opae_sensor_list;
 
 	/* SPI self test */
 	if (spi_self_checking(max10))
 		goto spi_fail;
 
-	ret = init_sec_mgr(fme);
+	ret = init_sec_mgr(fme, N3000BMC_SEC);
 	if (ret) {
 		dev_err(fme, "security manager init fail\n");
 		goto spi_fail;
@@ -1187,6 +1261,11 @@  static int fme_nios_spi_init(struct ifpga_feature *feature)
 
 spi_fail:
 	intel_max10_device_remove(fme->max10_dev);
+release_spi_tran_dev:
+	if (max10->spi_tran_dev)
+		spi_transaction_remove(max10->spi_tran_dev);
+free_max10:
+	opae_free(max10);
 release_dev:
 	altera_spi_release(spi_master);
 	return -ENODEV;
@@ -1197,8 +1276,10 @@  static void fme_nios_spi_uinit(struct ifpga_feature *feature)
 	struct ifpga_fme_hw *fme = (struct ifpga_fme_hw *)feature->parent;
 
 	release_sec_mgr(fme);
-	if (fme->max10_dev)
+	if (fme->max10_dev) {
 		intel_max10_device_remove(fme->max10_dev);
+		opae_free(fme->max10_dev);
+	}
 }
 
 struct ifpga_feature_ops fme_nios_spi_master_ops = {
@@ -1230,7 +1311,7 @@  static int i2c_mac_rom_test(struct altera_i2c_dev *dev)
 	}
 
 	if (memcmp(buf, read_buf, strlen(string))) {
-		dev_err(NULL, "%s test fail!\n", __func__);
+		dev_info(NULL, "%s test fail!\n", __func__);
 		return -EFAULT;
 	}
 
@@ -1499,3 +1580,81 @@  int fme_mgr_get_sensor_value(struct ifpga_fme_hw *fme,
 
 	return 0;
 }
+
+static int fme_pmci_init(struct ifpga_feature *feature)
+{
+	struct ifpga_fme_hw *fme = (struct ifpga_fme_hw *)feature->parent;
+	struct intel_max10_device *max10;
+	struct ifpga_hw *hw;
+	struct opae_manager *mgr;
+	opae_share_data *sd = NULL;
+	int ret = 0;
+
+	hw = fme->parent;
+	if (!hw)
+		return -ENODEV;
+
+	mgr = hw->adapter->mgr;
+	if (!mgr)
+		return -ENODEV;
+
+	dev_info(fme, "FME PMCI Init.\n");
+	dev_debug(fme, "FME PMCI base addr %p.\n",
+			feature->addr);
+
+	max10 = opae_zmalloc(sizeof(*max10));
+	if (!max10)
+		return -ENOMEM;
+
+	max10->type = M10_N6000;
+	max10->mmio = feature->addr;
+	if (hw->adapter && hw->adapter->shm.ptr) {
+		sd = (opae_share_data *)hw->adapter->shm.ptr;
+		max10->bmc_ops.mutex = &sd->spi_mutex;
+	} else {
+		max10->bmc_ops.mutex = NULL;
+	}
+
+	/* init the max10 device */
+	ret = intel_max10_device_init(max10);
+	if (ret) {
+		dev_err(fme, "max10 init fail\n");
+		goto free_max10;
+	}
+
+	fme->max10_dev = max10;
+	max10->bus = hw->pci_data->bus;
+	fme_get_board_interface(fme);
+	mgr->sensor_list = &max10->opae_sensor_list;
+
+	ret = init_sec_mgr(fme, N6000BMC_SEC);
+	if (ret) {
+		dev_err(fme, "security manager init fail\n");
+		goto release_max10;
+	}
+
+	return ret;
+
+release_max10:
+	intel_max10_device_remove(max10);
+free_max10:
+	opae_free(max10);
+
+	return ret;
+}
+
+static void fme_pmci_uinit(struct ifpga_feature *feature)
+{
+	struct ifpga_fme_hw *fme = (struct ifpga_fme_hw *)feature->parent;
+
+	release_sec_mgr(fme);
+	if (fme->max10_dev) {
+		intel_max10_device_remove(fme->max10_dev);
+		opae_free(fme->max10_dev);
+	}
+}
+
+struct ifpga_feature_ops fme_pmci_ops = {
+	.init = fme_pmci_init,
+	.uinit = fme_pmci_uinit,
+};
diff --git a/drivers/raw/ifpga/base/ifpga_fme_error.c b/drivers/raw/ifpga/base/ifpga_fme_error.c
index 5905eac..c5bed28 100644
--- a/drivers/raw/ifpga/base/ifpga_fme_error.c
+++ b/drivers/raw/ifpga/base/ifpga_fme_error.c
@@ -224,6 +224,8 @@  static int fme_global_error_init(struct ifpga_feature *feature)
 {
 	struct ifpga_fme_hw *fme = feature->parent;
 
+	dev_info(NULL, "FME error_module Init.\n");
+
 	fme_error_enable(fme);
 
 	if (feature->ctx_num)
diff --git a/drivers/raw/ifpga/base/ifpga_port_error.c b/drivers/raw/ifpga/base/ifpga_port_error.c
index 189f762..6c8a7d7 100644
--- a/drivers/raw/ifpga/base/ifpga_port_error.c
+++ b/drivers/raw/ifpga/base/ifpga_port_error.c
@@ -88,7 +88,7 @@  static int port_error_init(struct ifpga_feature *feature)
 {
 	struct ifpga_port_hw *port = feature->parent;
 
-	dev_info(NULL, "port error Init.\n");
+	dev_info(NULL, "port error_module Init.\n");
 
 	spinlock_lock(&port->lock);
 	port_err_mask(port, false);
diff --git a/drivers/raw/ifpga/base/ifpga_sec_mgr.c b/drivers/raw/ifpga/base/ifpga_sec_mgr.c
index 15fb5b6..557c4e3 100644
--- a/drivers/raw/ifpga/base/ifpga_sec_mgr.c
+++ b/drivers/raw/ifpga/base/ifpga_sec_mgr.c
@@ -227,7 +227,7 @@  static int n3000_bulk_write(struct intel_max10_device *dev, uint32_t addr,
 	for (i = 0; i < n; i++) {
 		p = i << 2;
 		v = *(uint32_t *)(buf + p);
-		ret = max10_reg_write(dev, addr + p, v);
+		ret = max10_sys_raw_write(dev, addr + p, v);
 		if (ret < 0) {
 			dev_err(dev,
 				"Failed to write to staging area 0x%08x [e:%d]\n",
@@ -490,7 +490,7 @@  static int n3000_reload_bmc(struct intel_max10_device *dev, int page)
 			CONFIG_SEL_S(page) | REBOOT_REQ);
 	} else {
 		val = (page == 0) ? 0x1 : 0x3;
-		ret = max10_reg_write(dev, IFPGA_DUAL_CFG_CTRL1, val);
+		ret = max10_sys_raw_write(dev, IFPGA_DUAL_CFG_CTRL1, val);
 		if (ret < 0) {
 			dev_err(dev,
 				"Failed to write to dual config1 register [e:%d]\n",
@@ -498,7 +498,7 @@  static int n3000_reload_bmc(struct intel_max10_device *dev, int page)
 			goto end;
 		}
 
-		ret = max10_reg_write(dev, IFPGA_DUAL_CFG_CTRL0, 0x1);
+		ret = max10_sys_raw_write(dev, IFPGA_DUAL_CFG_CTRL0, 0x1);
 		if (ret < 0) {
 			if (ret == -EIO) {
 				ret = 0;
@@ -584,7 +584,7 @@  static uint64_t n3000_get_hw_errinfo(struct ifpga_sec_mgr *smgr)
 	.get_hw_errinfo = n3000_get_hw_errinfo,
 };
 
-int init_sec_mgr(struct ifpga_fme_hw *fme)
+int init_sec_mgr(struct ifpga_fme_hw *fme, enum fpga_sec_type type)
 {
 	struct ifpga_hw *hw = NULL;
 	opae_share_data *sd = NULL;
@@ -621,6 +621,7 @@  int init_sec_mgr(struct ifpga_fme_hw *fme)
 
 	smgr->fme = fme;
 	smgr->max10_dev = fme->max10_dev;
+	smgr->type = type;
 
 	return 0;
 }
diff --git a/drivers/raw/ifpga/base/ifpga_sec_mgr.h b/drivers/raw/ifpga/base/ifpga_sec_mgr.h
index fbeba56..09cc038 100644
--- a/drivers/raw/ifpga/base/ifpga_sec_mgr.h
+++ b/drivers/raw/ifpga/base/ifpga_sec_mgr.h
@@ -55,6 +55,12 @@ 
 #define IFPGA_RSU_ERR_WEAROUT		-7
 #define IFPGA_RSU_ERR_FILE_READ		-8
 
+/* Supported fpga secure manager types */
+enum fpga_sec_type {
+	N3000BMC_SEC,
+	N6000BMC_SEC
+};
+
 struct ifpga_sec_mgr;
 
 struct ifpga_sec_ops {
@@ -80,9 +86,10 @@  struct ifpga_sec_mgr {
 	unsigned int *rsu_control;
 	unsigned int *rsu_status;
 	const struct ifpga_sec_ops *ops;
+	enum fpga_sec_type type;
 };
 
-int init_sec_mgr(struct ifpga_fme_hw *fme);
+int init_sec_mgr(struct ifpga_fme_hw *fme, enum fpga_sec_type type);
 void release_sec_mgr(struct ifpga_fme_hw *fme);
 int fpga_update_flash(struct ifpga_fme_hw *fme, const char *image,
 	uint64_t *status);
diff --git a/drivers/raw/ifpga/base/opae_hw_api.c b/drivers/raw/ifpga/base/opae_hw_api.c
index 87256fc..6b78094 100644
--- a/drivers/raw/ifpga/base/opae_hw_api.c
+++ b/drivers/raw/ifpga/base/opae_hw_api.c
@@ -831,6 +831,35 @@  int opae_manager_get_retimer_status(struct opae_manager *mgr,
 }
 
 /**
+ * opae_manager_get_sensor_list - get sensor name list
+ * @mgr: opae_manager of sensors
+ * @buf: buffer to accommodate name list separated by semicolon
+ * @size: size of buffer
+ *
+ * Return: the pointer of the opae_sensor_info
+ */
+int
+opae_mgr_get_sensor_list(struct opae_manager *mgr, char *buf, size_t size)
+{
+	struct opae_sensor_info *sensor;
+	uint32_t offset = 0;
+
+	opae_mgr_for_each_sensor(mgr, sensor) {
+		if (sensor->name) {
+			if (buf && (offset < size))
+				snprintf(buf + offset, size - offset, "%s;",
+					sensor->name);
+			offset += strlen(sensor->name) + 1;
+		}
+	}
+
+	if (buf && (offset > 0) && (offset <= size))
+		buf[offset-1] = 0;
+
+	return offset;
+}
+
+/**
  * opae_manager_get_sensor_by_id - get sensor device
  * @id: the id of the sensor
  *
diff --git a/drivers/raw/ifpga/base/opae_hw_api.h b/drivers/raw/ifpga/base/opae_hw_api.h
index fd40e09..8aead4d 100644
--- a/drivers/raw/ifpga/base/opae_hw_api.h
+++ b/drivers/raw/ifpga/base/opae_hw_api.h
@@ -93,6 +93,7 @@  int opae_manager_flash(struct opae_manager *mgr, int acc_id, const char *buf,
 		       u32 size, u64 *status);
 int opae_manager_get_eth_group_region_info(struct opae_manager *mgr,
 		u8 group_id, struct opae_eth_group_region_info *info);
+int opae_mgr_get_sensor_list(struct opae_manager *mgr, char *buf, size_t size);
 struct opae_sensor_info *opae_mgr_get_sensor_by_name(struct opae_manager *mgr,
 		const char *name);
 struct opae_sensor_info *opae_mgr_get_sensor_by_id(struct opae_manager *mgr,
diff --git a/drivers/raw/ifpga/base/opae_intel_max10.c b/drivers/raw/ifpga/base/opae_intel_max10.c
index 9d82fb0..465494a 100644
--- a/drivers/raw/ifpga/base/opae_intel_max10.c
+++ b/drivers/raw/ifpga/base/opae_intel_max10.c
@@ -4,51 +4,42 @@ 
 
 #include "opae_intel_max10.h"
 #include <libfdt.h>
+#include "opae_osdep.h"
 
-int max10_reg_read(struct intel_max10_device *dev,
-	unsigned int reg, unsigned int *val)
+int max10_sys_read(struct intel_max10_device *dev,
+	unsigned int offset, unsigned int *val)
 {
-	if (!dev)
+	if (!dev || !dev->ops->reg_read)
 		return -ENODEV;
 
-	dev_debug(dev, "%s: bus:0x%x, reg:0x%x\n", __func__, dev->bus, reg);
-
-	return spi_transaction_read(dev->spi_tran_dev,
-			reg, 4, (unsigned char *)val);
+	return dev->ops->reg_read(dev, dev->csr->base + offset, val);
 }
 
-int max10_reg_write(struct intel_max10_device *dev,
-	unsigned int reg, unsigned int val)
+int max10_sys_write(struct intel_max10_device *dev,
+	unsigned int offset, unsigned int val)
 {
-	unsigned int tmp = val;
-
-	if (!dev)
+	if (!dev || !dev->ops->reg_write)
 		return -ENODEV;
 
-	dev_debug(dev, "%s: bus:0x%x, reg:0x%x, val:0x%x\n", __func__,
-			dev->bus, reg, val);
-
-	return spi_transaction_write(dev->spi_tran_dev,
-			reg, 4, (unsigned char *)&tmp);
+	return dev->ops->reg_write(dev, dev->csr->base + offset, val);
 }
 
-int max10_sys_read(struct intel_max10_device *dev,
+int max10_sys_raw_read(struct intel_max10_device *dev,
 	unsigned int offset, unsigned int *val)
 {
-	if (!dev)
+	if (!dev || !dev->ops->reg_read)
 		return -ENODEV;
 
-
-	return max10_reg_read(dev, dev->base + offset, val);
+	return dev->ops->reg_read(dev, offset, val);
 }
 
-int max10_sys_write(struct intel_max10_device *dev,
+int max10_sys_raw_write(struct intel_max10_device *dev,
 	unsigned int offset, unsigned int val)
 {
-	if (!dev)
+	if (!dev || !dev->ops->reg_write)
 		return -ENODEV;
 
-	return max10_reg_write(dev, dev->base + offset, val);
+	return dev->ops->reg_write(dev, offset, val);
 }
 
 int max10_sys_update_bits(struct intel_max10_device *dev, unsigned int offset,
@@ -67,6 +58,402 @@  int max10_sys_update_bits(struct intel_max10_device *dev, unsigned int offset,
 	return max10_sys_write(dev, offset, temp);
 }
 
+static int n3000_bulk_raw_write(struct intel_max10_device *dev, uint32_t addr,
+	void *buf, uint32_t len)
+{
+	uint32_t v = 0;
+	uint32_t i = 0;
+	char *p = buf;
+	int ret = 0;
+
+	len = IFPGA_ALIGN(len, 4);
+
+	for (i = 0; i < len; i += 4) {
+		v = *(uint32_t *)(p + i);
+		ret = max10_sys_raw_write(dev, addr + i, v);
+		if (ret < 0) {
+			dev_err(dev,
+				"Failed to write to staging area 0x%08x [e:%d]\n",
+				addr + i, ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int n3000_bulk_raw_read(struct intel_max10_device *dev,
+		uint32_t addr, void *buf, uint32_t len)
+{
+	u32 v, i;
+	char *p = buf;
+	int ret;
+
+	len = IFPGA_ALIGN(len, 4);
+
+	for (i = 0; i < len; i += 4) {
+		ret = max10_sys_raw_read(dev, addr + i, &v);
+		if (ret < 0) {
+			dev_err(dev,
+				"Failed to write to staging area 0x%08x [e:%d]\n",
+				addr + i, ret);
+			return ret;
+		}
+		*(u32 *)(p + i) = v;
+	}
+
+	return 0;
+}
+
+static int n3000_flash_read(struct intel_max10_device *dev,
+		u32 addr, void *buf, u32 size)
+{
+	if (!dev->raw_blk_ops.read_blk)
+		return -ENODEV;
+
+	return dev->raw_blk_ops.read_blk(dev, addr, buf, size);
+}
+
+static int n3000_flash_write(struct intel_max10_device *dev,
+		u32 addr, void *buf, u32 size)
+{
+	if (!dev->raw_blk_ops.write_blk)
+		return -ENODEV;
+
+	return dev->raw_blk_ops.write_blk(dev, addr, buf, size);
+}
+
+static u32
+pmci_get_write_space(struct intel_max10_device *dev, u32 size)
+{
+	u32 count, val;
+	int ret;
+
+	ret = opae_readl_poll_timeout(dev->mmio + PMCI_FLASH_CTRL, val,
+				GET_FIELD(PMCI_FLASH_FIFO_SPACE, val) ==
+				PMCI_FIFO_MAX_WORDS,
+				PMCI_FLASH_INT_US, PMCI_FLASH_TIMEOUT_US);
+	if (ret == -ETIMEDOUT)
+		return 0;
+
+	count = GET_FIELD(PMCI_FLASH_FIFO_SPACE, val) * 4;
+
+	return (size > count) ? count : size;
+}
+
+static void pmci_write_fifo(void __iomem *base, char *buf, size_t count)
+{
+	size_t i;
+	u32 val;
+
+	for (i = 0; i < count/4 ; i++) {
+		val = *(u32 *)(buf + i * 4);
+		writel(val, base);
+	}
+}
+
+static void pmci_read_fifo(void __iomem *base, char *buf, size_t count)
+{
+	size_t i;
+	u32 val;
+
+	for (i = 0; i < count/4; i++) {
+		val = readl(base);
+		*(u32 *)(buf + i * 4) = val;
+	}
+}
+
+static int
+__pmci_flash_bulk_write(struct intel_max10_device *dev, u32 addr,
+		void *buf, u32 size)
+{
+	UNUSED(addr);
+	u32 blk_size, n_offset = 0;
+
+	while (size) {
+		blk_size = pmci_get_write_space(dev, size);
+		if (blk_size == 0) {
+			dev_err(pmci->dev, "get FIFO available size fail\n");
+			return -EIO;
+		}
+		size -= blk_size;
+		pmci_write_fifo(dev->mmio + PMCI_FLASH_FIFO, (char *)buf + n_offset,
+				blk_size);
+		n_offset += blk_size;
+	}
+
+	return 0;
+}
+
+static int
+pmci_flash_bulk_write(struct intel_max10_device *dev, u32 addr,
+		void *buf, u32 size)
+{
+	int ret;
+
+	pthread_mutex_lock(dev->bmc_ops.mutex);
+
+	ret = __pmci_flash_bulk_write(dev, addr, buf, size);
+
+	pthread_mutex_unlock(dev->bmc_ops.mutex);
+	return ret;
+}
+
+static int
+pmci_set_flash_host_mux(struct intel_max10_device *dev, bool request)
+{
+	u32 ctrl;
+	int ret;
+
+	ret = max10_sys_update_bits(dev,
+			m10bmc_base(dev) + M10BMC_PMCI_FLASH_CTRL,
+			FLASH_HOST_REQUEST,
+			SET_FIELD(FLASH_HOST_REQUEST, request));
+	if (ret)
+		return ret;
+
+	return opae_max10_read_poll_timeout(dev, m10bmc_base(dev) + M10BMC_PMCI_FLASH_CTRL,
+			ctrl, request ? (get_flash_mux(ctrl) == FLASH_MUX_HOST) :
+			(get_flash_mux(ctrl) != FLASH_MUX_HOST),
+			PMCI_FLASH_INT_US, PMCI_FLASH_TIMEOUT_US);
+}
+
+static int
+pmci_get_mux(struct intel_max10_device *dev)
+{
+	pthread_mutex_lock(dev->bmc_ops.mutex);
+	return pmci_set_flash_host_mux(dev, true);
+}
+
+static int
+pmci_put_mux(struct intel_max10_device *dev)
+{
+	int ret;
+
+	ret = pmci_set_flash_host_mux(dev, false);
+	pthread_mutex_unlock(dev->bmc_ops.mutex);
+	return ret;
+}
+
+static int
+__pmci_flash_bulk_read(struct intel_max10_device *dev, u32 addr,
+		     void *buf, u32 size)
+{
+	u32 blk_size, offset = 0, val;
+	int ret;
+
+	while (size) {
+		blk_size = min_t(u32, size, PMCI_READ_BLOCK_SIZE);
+
+		opae_writel(addr + offset, dev->mmio + PMCI_FLASH_ADDR);
+
+		opae_writel(SET_FIELD(PMCI_FLASH_READ_COUNT, blk_size / 4)
+				| PMCI_FLASH_RD_MODE,
+			dev->mmio + PMCI_FLASH_CTRL);
+
+		ret = opae_readl_poll_timeout((dev->mmio + PMCI_FLASH_CTRL),
+				val, !(val & PMCI_FLASH_BUSY),
+				PMCI_FLASH_INT_US,
+				PMCI_FLASH_TIMEOUT_US);
+		if (ret) {
+			dev_err(dev, "%s timed out on reading flash 0x%xn",
+				__func__, val);
+			return ret;
+		}
+
+		pmci_read_fifo(dev->mmio + PMCI_FLASH_FIFO, (char *)buf + offset,
+				blk_size);
+
+		size -= blk_size;
+		offset += blk_size;
+
+		opae_writel(0, dev->mmio + PMCI_FLASH_CTRL);
+	}
+
+	return 0;
+}
+
+static int
+pmci_flash_bulk_read(struct intel_max10_device *dev, u32 addr,
+		     void *buf, u32 size)
+{
+	int ret;
+
+	ret = pmci_get_mux(dev);
+	if (ret)
+		return ret;
+
+	ret = __pmci_flash_bulk_read(dev, addr, buf, size);
+	if (ret)
+		goto fail;
+
+	return pmci_put_mux(dev);
+
+fail:
+	pmci_put_mux(dev);
+	return ret;
+}
+
+static int pmci_check_flash_address(u32 start, u32 end)
+{
+	if (start < PMCI_FLASH_START || end > PMCI_FLASH_END)
+		return -EINVAL;
+
+	return 0;
+}
+
+int opae_read_flash(struct intel_max10_device *dev, u32 addr,
+		u32 size, void *buf)
+{
+	int ret;
+
+	if (!dev->bmc_ops.check_flash_range ||
+			!dev->bmc_ops.flash_read)
+		return -ENODEV;
+
+	if (!buf)
+		return -EINVAL;
+
+	ret = dev->bmc_ops.check_flash_range(addr, addr + size);
+	if (ret)
+		return ret;
+
+	ret = dev->bmc_ops.flash_read(dev, addr, buf, size);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int max10_spi_read(struct intel_max10_device *dev,
+	unsigned int addr, unsigned int *val)
+{
+	if (!dev)
+		return -ENODEV;
+
+	dev_debug(dev, "%s: bus:0x%x, addr:0x%x\n", __func__, dev->bus, addr);
+
+	return spi_transaction_read(dev->spi_tran_dev,
+			addr, 4, (unsigned char *)val);
+}
+
+static int max10_spi_write(struct intel_max10_device *dev,
+	unsigned int addr, unsigned int val)
+{
+	unsigned int tmp = val;
+
+	if (!dev)
+		return -ENODEV;
+
+	dev_debug(dev, "%s: bus:0x%x, reg:0x%x, val:0x%x\n", __func__,
+			dev->bus, addr, val);
+
+	return spi_transaction_write(dev->spi_tran_dev,
+			addr, 4, (unsigned char *)&tmp);
+}
+
+static int indirect_bus_clr_cmd(struct intel_max10_device *dev)
+{
+	unsigned int cmd;
+	int ret;
+
+	opae_writel(0, dev->mmio + INDIRECT_CMD_OFF);
+
+	ret = opae_readl_poll_timeout((dev->mmio + INDIRECT_CMD_OFF), cmd,
+				 (!cmd), INDIRECT_INT_US, INDIRECT_TIMEOUT_US);
+
+	if (ret)
+		dev_err(dev, "%s timed out on clearing cmd 0x%x\n",
+				__func__, cmd);
+
+	return ret;
+}
+
+static int max10_indirect_reg_read(struct intel_max10_device *dev,
+	unsigned int addr, unsigned int *val)
+{
+	unsigned int cmd;
+	int ret;
+
+	if (!dev)
+		return -ENODEV;
+
+	pthread_mutex_lock(dev->bmc_ops.mutex);
+
+	cmd = opae_readl(dev->mmio + INDIRECT_CMD_OFF);
+	if (cmd)
+		dev_warn(dev, "%s non-zero cmd 0x%x\n", __func__, cmd);
+
+	opae_writel(addr, dev->mmio + INDIRECT_ADDR_OFF);
+
+	opae_writel(INDIRECT_CMD_RD, dev->mmio + INDIRECT_CMD_OFF);
+
+	ret = opae_readl_poll_timeout((dev->mmio + INDIRECT_CMD_OFF), cmd,
+				 (cmd & INDIRECT_CMD_ACK), INDIRECT_INT_US,
+				 INDIRECT_TIMEOUT_US);
+
+	*val = opae_readl(dev->mmio + INDIRECT_RD_OFF);
+
+	if (ret)
+		dev_err(dev, "%s timed out on reg 0x%x cmd 0x%x\n",
+				__func__, addr, cmd);
+
+	if (indirect_bus_clr_cmd(dev))
+		ret = -ETIME;
+
+	pthread_mutex_unlock(dev->bmc_ops.mutex);
+
+	return ret;
+}
+
+static int max10_indirect_reg_write(struct intel_max10_device *dev,
+	unsigned int addr, unsigned int val)
+{
+	unsigned int cmd;
+	int ret;
+
+	if (!dev)
+		return -ENODEV;
+
+	pthread_mutex_lock(dev->bmc_ops.mutex);
+
+	cmd = readl(dev->mmio + INDIRECT_CMD_OFF);
+
+	if (cmd)
+		dev_warn(dev, "%s non-zero cmd 0x%x\n", __func__, cmd);
+
+	opae_writel(val, dev->mmio + INDIRECT_WR_OFF);
+
+	opae_writel(addr, dev->mmio + INDIRECT_ADDR_OFF);
+
+	writel(INDIRECT_CMD_WR, dev->mmio + INDIRECT_CMD_OFF);
+
+	ret = opae_readl_poll_timeout((dev->mmio + INDIRECT_CMD_OFF), cmd,
+				 (cmd & INDIRECT_CMD_ACK), INDIRECT_INT_US,
+				 INDIRECT_TIMEOUT_US);
+
+	if (ret)
+		dev_err(dev, "%s timed out on reg 0x%x cmd 0x%x\n",
+				__func__, addr, cmd);
+
+	if (indirect_bus_clr_cmd(dev))
+		ret = -ETIME;
+
+	pthread_mutex_unlock(dev->bmc_ops.mutex);
+
+	return ret;
+}
+
+const struct m10bmc_regmap m10bmc_pmci_regmap = {
+	.reg_write = max10_indirect_reg_write,
+	.reg_read = max10_indirect_reg_read,
+};
+
+const struct m10bmc_regmap m10bmc_n3000_regmap = {
+	.reg_write = max10_spi_write,
+	.reg_read = max10_spi_read,
+};
+
 static struct max10_compatible_id max10_id_table[] = {
 	{.compatible = MAX10_PAC,},
 	{.compatible = MAX10_PAC_N3000,},
@@ -122,7 +509,7 @@  static int altera_nor_flash_read(struct intel_max10_device *dev,
 	word_len = len/4;
 
 	for (i = 0; i < word_len; i++) {
-		ret = max10_reg_read(dev, offset + i*4,
+		ret = max10_sys_raw_read(dev, offset + i*4,
 				&value);
 		if (ret)
 			return -EBUSY;
@@ -557,15 +944,13 @@  static int check_max10_version(struct intel_max10_device *dev)
 {
 	unsigned int v;
 
-	if (!max10_reg_read(dev, MAX10_SEC_BASE_ADDR + MAX10_BUILD_VER,
+	if (!max10_sys_raw_read(dev, 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;
 	}
@@ -648,73 +1033,455 @@  static int max10_staging_area_init(struct intel_max10_device *dev)
 	return 0;
 }
 
-struct intel_max10_device *
-intel_max10_device_probe(struct altera_spi_device *spi,
-		int chipselect)
+int max10_get_fpga_load_info(struct intel_max10_device *dev, unsigned int *val)
 {
-	struct intel_max10_device *dev;
 	int ret;
-	unsigned int val;
+	unsigned int value;
 
-	dev = opae_malloc(sizeof(*dev));
-	if (!dev)
-		return NULL;
+	/* read FPGA loading information */
+	ret = max10_sys_read(dev, dev->csr->fpga_page_info, &value);
+	if (ret) {
+		dev_err(dev, "fail to get FPGA loading info\n");
+		return ret;
+	}
 
-	TAILQ_INIT(&dev->opae_sensor_list);
+	if (dev->type == M10_N3000)
+		*val = value & 0x7;
+	else if (dev->type == M10_N6000) {
+		if (!GET_FIELD(PMCI_FPGA_CONFIGED, value))
+			return -EINVAL;
+		*val = GET_FIELD(PMCI_FPGA_BOOT_PAGE, value);
+	}
 
-	dev->spi_master = spi;
+	return 0;
+}
 
-	dev->spi_tran_dev = spi_transaction_init(spi, chipselect);
-	if (!dev->spi_tran_dev) {
-		dev_err(dev, "%s spi tran init fail\n", __func__);
-		goto free_dev;
-	}
+int max10_get_bmc_version(struct intel_max10_device *dev, unsigned int *val)
+{
+	int ret;
 
-	/* check the max10 version */
-	ret = check_max10_version(dev);
-	if (ret) {
-		dev_err(dev, "Failed to find max10 hardware!\n");
-		goto free_dev;
-	}
+	ret = max10_sys_read(dev, dev->csr->build_version, val);
+	if (ret)
+		return ret;
 
-	/* load the MAX10 device table */
-	ret = init_max10_device_table(dev);
-	if (ret) {
-		dev_err(dev, "Init max10 device table fail\n");
-		goto free_dev;
-	}
+	return 0;
+}
 
-	/* 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;
+int max10_get_bmcfw_version(struct intel_max10_device *dev, unsigned int *val)
+{
+	int ret;
+
+	ret = max10_sys_read(dev, dev->csr->fw_version, val);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static const struct m10bmc_csr m10bmc_spi_csr = {
+	.base = MAX10_SEC_BASE_ADDR,
+	.build_version = MAX10_BUILD_VER,
+	.fw_version = NIOS2_FW_VERSION,
+	.fpga_page_info = FPGA_PAGE_INFO,
+	.doorbell = MAX10_DOORBELL,
+	.auth_result = MAX10_AUTH_RESULT,
+};
+
+static const struct m10bmc_csr m10bmc_pmci_csr = {
+	.base = M10BMC_PMCI_SYS_BASE,
+	.build_version = M10BMC_PMCI_BUILD_VER,
+	.fw_version = NIOS2_PMCI_FW_VERSION,
+	.fpga_page_info = M10BMC_PMCI_FPGA_CONF_STS,
+	.doorbell = M10BMC_PMCI_DOORBELL,
+	.auth_result = M10BMC_PMCI_AUTH_RESULT,
+};
+
+static const struct max10_sensor_raw_data n6010bmc_temp_tbl[] = {
+	{ 0x444, 0x448, 0x44c, 0x0, 0x0, 500,
+		"FPGA E-TILE Temperature #1" },
+	{ 0x450, 0x454, 0x458, 0x0, 0x0, 500,
+		"FPGA E-TILE Temperature #2" },
+	{ 0x45c, 0x460, 0x464, 0x0, 0x0, 500,
+		"FPGA E-TILE Temperature #3" },
+	{ 0x468, 0x46c, 0x470, 0x0, 0x0, 500,
+		"FPGA E-TILE Temperature #4" },
+	{ 0x474, 0x478, 0x47c, 0x0, 0x0, 500,
+		"FPGA P-TILE Temperature" },
+	{ 0x484, 0x488, 0x48c, 0x0, 0x0, 500,
+		"FPGA FABRIC Digital Temperature#1" },
+	{ 0x490, 0x494, 0x498, 0x0, 0x0, 500,
+		"FPGA FABRIC Digital Temperature#2" },
+	{ 0x49c, 0x4a0, 0x4a4, 0x0, 0x0, 500,
+		"FPGA FABRIC Digital Temperature#3" },
+	{ 0x4a8, 0x4ac, 0x4b0, 0x0, 0x0, 500,
+		"FPGA FABRIC Digital Temperature#4" },
+	{ 0x4b4, 0x4b8, 0x4bc, 0x0, 0x0, 500,
+		"FPGA FABRIC Digital Temperature#5" },
+	{ 0x4c0, 0x4c4, 0x4c8, 0x0, 0x0, 500,
+		"FPGA FABRIC Remote Digital Temperature#1" },
+	{ 0x4cc, 0x4d0, 0x4d4, 0x0, 0x0, 500,
+		"FPGA FABRIC Remote Digital Temperature#2" },
+	{ 0x4d8, 0x4dc, 0x4e0, 0x0, 0x0, 500,
+		"FPGA FABRIC Remote Digital Temperature#3" },
+	{ 0x4e4, 0x4e8, 0x4ec, 0x0, 0x0, 500,
+		"FPGA FABRIC Remote Digital Temperature#4" },
+	{ 0x4f0, 0x4f4, 0x4f8, 0x0, 0x0, 500,
+		"Board Top Near FPGA Temperature" },
+	{ 0x4fc, 0x500, 0x504, 0x52c, 0x0, 500,
+		"Board Bottom Near CVL Temperature" },
+	{ 0x508, 0x50c, 0x510, 0x52c, 0x0, 500,
+		"Board Top East Near VRs Temperature" },
+	{ 0x514, 0x518, 0x51c, 0x52c, 0x0, 500,
+		"Columbiaville Die Temperature" },
+	{ 0x520, 0x524, 0x528, 0x52c, 0x0, 500,
+		"Board Rear Side Temperature" },
+	{ 0x530, 0x534, 0x538, 0x52c, 0x0, 500,
+		"Board Front Side Temperature" },
+	{ 0x53c, 0x540, 0x544, 0x0, 0x0, 500,
+		"QSFP1 Temperature" },
+	{ 0x548, 0x54c, 0x550, 0x0, 0x0, 500,
+		"QSFP2 Temperature" },
+	{ 0x554, 0x0, 0x0, 0x0, 0x0, 500,
+		"FPGA Core Voltage Phase 0 VR Temperature" },
+	{ 0x560, 0x0, 0x0, 0x0, 0x0, 500,
+		"FPGA Core Voltage Phase 1 VR Temperature" },
+	{ 0x56c, 0x0, 0x0, 0x0, 0x0, 500,
+		"FPGA Core Voltage Phase 2 VR Temperature" },
+	{ 0x578, 0x0, 0x0, 0x0, 0x0, 500,
+		"FPGA Core Voltage VR Controller Temperature" },
+	{ 0x584, 0x0, 0x0, 0x0, 0x0, 500,
+		"FPGA VCCH VR Temperature" },
+	{ 0x590, 0x0, 0x0, 0x0, 0x0, 500,
+		"FPGA VCC_1V2 VR Temperature" },
+	{ 0x59c, 0x0, 0x0, 0x0, 0x0, 500,
+		"FPGA VCCH, VCC_1V2 VR Controller Temperature" },
+	{ 0x5a8, 0x0, 0x0, 0x0, 0x0, 500,
+		"3V3 VR Temperature" },
+	{ 0x5b4, 0x5b8, 0x5bc, 0x0, 0x0, 500,
+		"CVL Core Voltage VR Temperature" },
+	{ 0x5c4, 0x5c8, 0x5cc, 0x5c0, 0x0, 500,
+		"FPGA P-Tile Temperature [Remote]" },
+	{ 0x5d0, 0x5d4, 0x5d8, 0x5c0, 0x0, 500,
+		"FPGA E-Tile Temperature [Remote]" },
+	{ 0x5dc, 0x5e0, 0x5e4, 0x5c0, 0x0, 500,
+		"FPGA SDM Temperature [Remote]" },
+	{ 0x5e8, 0x5ec, 0x5f0, 0x5c0, 0x0, 500,
+		"FPGA Corner Temperature [Remote]" },
+};
+
+static const struct max10_sensor_data n6010bmc_tmp_data = {
+	.type = SENSOR_TMP_NAME,
+	.number = ARRAY_SIZE(n6010bmc_temp_tbl),
+	.table = n6010bmc_temp_tbl,
+};
+
+static const struct max10_sensor_raw_data n6010bmc_in_tbl[] = {
+	{ 0x5f4, 0x0, 0x0, 0x0, 0x0, 1,
+		"Inlet 12V PCIe Rail Voltage" },
+	{ 0x60c, 0x0, 0x0, 0x0, 0x0, 1,
+		"Inlet 12V Aux Rail Voltage" },
+	{ 0x624, 0x0, 0x0, 0x0, 0x0, 1,
+		"Inlet 3V3 PCIe Rail Voltage" },
+	{ 0x63c, 0x0, 0x0, 0x0, 0x0, 1,
+		"FPGA Core Voltage Rail Voltage" },
+	{ 0x644, 0x0, 0x0, 0x0, 0x0, 1,
+		"FPGA VCCH Rail Voltage" },
+	{ 0x64c, 0x0, 0x0, 0x0, 0x0, 1,
+		"FPGA VCC_1V2 Rail Voltage" },
+	{ 0x654, 0x0, 0x0, 0x0, 0x0, 1,
+		"FPGA VCCH_GXER_1V1, VCCA_1V8 Voltage" },
+	{ 0x664, 0x0, 0x0, 0x0, 0x0, 1,
+		"FPGA VCCIO_1V2 Voltage" },
+	{ 0x674, 0x0, 0x0, 0x0, 0x0, 1,
+		"CVL Non Core Rails Inlet Voltage" },
+	{ 0x684, 0x0, 0x0, 0x0, 0x0, 1,
+		"MAX10 & Board CLK PWR 3V3 Inlet Voltage" },
+	{ 0x694, 0x0, 0x0, 0x0, 0x0, 1,
+		"CVL Core Voltage Rail Voltage" },
+	{ 0x6ac, 0x0, 0x0, 0x0, 0x0, 1,
+		"Board 3V3 VR Voltage" },
+	{ 0x6b4, 0x0, 0x0, 0x0, 0x0, 1,
+		"QSFP 3V3 Rail Voltage" },
+	{ 0x6c4, 0x0, 0x0, 0x0, 0x0, 1,
+		"QSFP (Primary) Supply Rail Voltage" },
+	{ 0x6c8, 0x0, 0x0, 0x0, 0x0, 1,
+		"QSFP (Secondary) Supply Rail Voltage" },
+	{ 0x6cc, 0x0, 0x0, 0x0, 0x0, 1,
+		"VCCCLK_GXER_2V5 Voltage" },
+	{ 0x6d0, 0x0, 0x0, 0x0, 0x0, 1,
+		"AVDDH_1V1_CVL Voltage" },
+	{ 0x6d4, 0x0, 0x0, 0x0, 0x0, 1,
+		"VDDH_1V8_CVL Voltage" },
+	{ 0x6d8, 0x0, 0x0, 0x0, 0x0, 1,
+		"VCCA_PLL Voltage" },
+	{ 0x6e0, 0x0, 0x0, 0x0, 0x0, 1,
+		"VCCRT_GXER_0V9 Voltage" },
+	{ 0x6e8, 0x0, 0x0, 0x0, 0x0, 1,
+		"VCCRT_GXEL_0V9 Voltage" },
+	{ 0x6f0, 0x0, 0x0, 0x0, 0x0, 1,
+		"VCCH_GXPL_1V8 Voltage" },
+	{ 0x6f4, 0x0, 0x0, 0x0, 0x0, 1,
+		"VCCPT_1V8 Voltage" },
+	{ 0x6fc, 0x0, 0x0, 0x0, 0x0, 1,
+		"VCC_3V3_M10 Voltage" },
+	{ 0x700, 0x0, 0x0, 0x0, 0x0, 1,
+		"VCC_1V8_M10 Voltage" },
+	{ 0x704, 0x0, 0x0, 0x0, 0x0, 1,
+		"VCC_1V2_EMIF1_2_3 Voltage" },
+	{ 0x70c, 0x0, 0x0, 0x0, 0x0, 1,
+		"VCC_1V2_EMIF4_5 Voltage" },
+	{ 0x714, 0x0, 0x0, 0x0, 0x0, 1,
+		"VCCA_1V8 Voltage" },
+	{ 0x718, 0x0, 0x0, 0x0, 0x0, 1,
+		"VCCH_GXER_1V1 Voltage" },
+	{ 0x71c, 0x0, 0x0, 0x0, 0x0, 1,
+		"AVDD_ETH_0V9_CVL Voltage" },
+	{ 0x720, 0x0, 0x0, 0x0, 0x0, 1,
+		"AVDD_PCIE_0V9_CVL Voltage" },
+};
+
+static const struct max10_sensor_data n6010bmc_in_data = {
+	.type = SENSOR_IN_NAME,
+	.number = ARRAY_SIZE(n6010bmc_in_tbl),
+	.table = n6010bmc_in_tbl,
+};
+
+static const struct max10_sensor_raw_data n6010bmc_curr_tbl[] = {
+	{ 0x600, 0x604, 0x608, 0x0, 0x0, 1,
+		"Inlet 12V PCIe Rail Current" },
+	{ 0x618, 0x61c, 0x620, 0x0, 0x0, 1,
+		"Inlet 12V Aux Rail Current" },
+	{ 0x630, 0x634, 0x638, 0x0, 0x0, 1,
+		"Inlet 3V3 PCIe Rail Current" },
+	{ 0x640, 0x0, 0x0, 0x0, 0x0, 1,
+		"FPGA Core Voltage Rail Current" },
+	{ 0x648, 0x0, 0x0, 0x0, 0x0, 1,
+		"FPGA VCCH Rail Current" },
+	{ 0x650, 0x0, 0x0, 0x0, 0x0, 1,
+		"FPGA VCC_1V2 Rail Current" },
+	{ 0x658, 0x65c, 0x660, 0x0, 0x0, 1,
+		"FPGA VCCH_GXER_1V1, VCCA_1V8 Current" },
+	{ 0x668, 0x66c, 0x670, 0x0, 0x0, 1,
+		"FPGA VCCIO_1V2 Current" },
+	{ 0x678, 0x67c, 0x680, 0x0, 0x0, 1,
+		"CVL Non Core Rails Inlet Current" },
+	{ 0x688, 0x68c, 0x680, 0x0, 0x0, 1,
+		"MAX10 & Board CLK PWR 3V3 Inlet Current" },
+	{ 0x690, 0x0, 0x0, 0x0, 0x0, 1,
+		"CVL Core Voltage Rail Current" },
+	{ 0x6b0, 0x0, 0x0, 0x0, 0x0, 1,
+		"Board 3V3 VR Current" },
+	{ 0x6b8, 0x6bc, 0x670, 0x0, 0x0, 1,
+		"QSFP 3V3 Rail Current" },
+};
+
+static const struct max10_sensor_data n6010bmc_curr_data = {
+	.type = SENSOR_CURR_NAME,
+	.number = ARRAY_SIZE(n6010bmc_curr_tbl),
+	.table = n6010bmc_curr_tbl,
+};
+
+static const struct max10_sensor_raw_data n6010bmc_power_tbl[] = {
+	{ 0x724, 0x0, 0x0, 0x0, 0x0, 1000, "Board Power" },
+};
+
+static const struct max10_sensor_data n6010bmc_power_data = {
+	.type = SENSOR_POWER_NAME,
+	.number = ARRAY_SIZE(n6010bmc_power_tbl),
+	.table = n6010bmc_power_tbl,
+};
+
+static const struct max10_sensor_board_data n6010bmc_sensor_board_data = {
+	.tables = {
+		[sensor_temp] = &n6010bmc_tmp_data,
+		[sensor_in] = &n6010bmc_in_data,
+		[sensor_curr] = &n6010bmc_curr_data,
+		[sensor_power] = &n6010bmc_power_data,
+	},
+};
+
+static int get_sensor_data(struct intel_max10_device *dev,
+		struct opae_sensor_info *sensor,
+		unsigned int *value,
+		unsigned int reg,
+		unsigned int flags)
+{
+	int ret;
+	unsigned int data;
+
+	if (!reg)
+		return 0;
+
+	ret = max10_sys_read(dev, reg, &data);
+	if (ret)
+		return ret;
+
+	if (data == SENSOR_INVALID) {
+		dev_debug(dev, "%s: sensor:%s invalid 0x%x at:%d\n",
+				__func__, sensor->name, data, reg);
+		return ret;
 	}
 
-	/* read FPGA loading information */
-	ret = max10_sys_read(dev, FPGA_PAGE_INFO, &val);
-	if (ret) {
-		dev_err(dev, "fail to get FPGA loading info\n");
-		goto release_max10_hw;
+	*value = data * sensor->multiplier;
+	sensor->flags |= flags;
+
+	return 0;
+}
+
+static int max10_parse_sensor_data(struct intel_max10_device *dev,
+		const struct max10_sensor_data *sdata)
+{
+	struct opae_sensor_info *sensor;
+	const struct max10_sensor_raw_data *raw;
+	const struct max10_sensor_raw_data *table =
+		(const struct max10_sensor_raw_data *)sdata->table;
+	unsigned int i;
+	static unsigned int sensor_id;
+	int ret = 0;
+
+	for (i = 0; i < sdata->number; i++) {
+		raw = &table[i];
+
+		sensor = opae_zmalloc(sizeof(*sensor));
+		if (!sensor) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		sensor->type = sdata->type;
+		sensor->id = sensor_id++;
+
+		if (!raw->reg_input)
+			continue;
+
+		sensor->value_reg = raw->reg_input;
+		sensor->multiplier = raw->multiplier;
+		sensor->name = raw->label;
+
+		ret = get_sensor_data(dev, sensor,
+				&sensor->high_warn,
+				raw->reg_high_warn,
+				OPAE_SENSOR_HIGH_WARN_VALID);
+		if (ret)
+			break;
+
+		ret = get_sensor_data(dev, sensor,
+				&sensor->high_fatal,
+				raw->reg_high_fatal,
+				OPAE_SENSOR_HIGH_FATAL_VALID);
+		if (ret)
+			break;
+
+		ret = get_sensor_data(dev, sensor,
+				&sensor->hysteresis,
+				raw->reg_hyst,
+				OPAE_SENSOR_HYSTERESIS_VALID);
+		if (ret)
+			break;
+
+		ret = get_sensor_data(dev, sensor,
+				&sensor->low_warn,
+				raw->reg_low_warn,
+				OPAE_SENSOR_LOW_WARN_VALID);
+		if (ret)
+			break;
+
+		sensor->flags |= OPAE_SENSOR_VALID;
+
+		TAILQ_INSERT_TAIL(&dev->opae_sensor_list, sensor, node);
+		dev_info(dev, "found valid sensor: %s\n", sensor->name);
 	}
-	dev_info(dev, "FPGA loaded from %s Image\n", val ? "User" : "Factory");
 
-	return dev;
+	return ret;
 
-release_max10_hw:
+free_sensor:
 	max10_sensor_uinit(dev);
-free_dtb:
-	if (dev->fdt_root)
-		opae_free(dev->fdt_root);
-	if (dev->spi_tran_dev)
-		spi_transaction_remove(dev->spi_tran_dev);
-free_dev:
-	opae_free(dev);
+	return ret;
+}
 
-	return NULL;
+static int max10_sensor_init_table(struct intel_max10_device *dev,
+		const struct max10_sensor_board_data *data)
+{
+	int ret = 0;
+	unsigned int i;
+	const struct max10_sensor_data *sdata;
+
+	for (i = 0; i < ARRAY_SIZE(data->tables); i++) {
+		sdata = data->tables[i];
+		if (!sdata)
+			continue;
+		ret = max10_parse_sensor_data(dev, sdata);
+		if (ret)
+			break;
+	}
+
+	return ret;
+}
+
+int
+intel_max10_device_init(struct intel_max10_device *dev)
+{
+	int ret = 0;
+
+	TAILQ_INIT(&dev->opae_sensor_list);
+
+
+	if (dev->type == M10_N3000) {
+		dev->ops = &m10bmc_n3000_regmap;
+		dev->csr = &m10bmc_spi_csr;
+
+		dev->raw_blk_ops.write_blk = n3000_bulk_raw_write;
+		dev->raw_blk_ops.read_blk = n3000_bulk_raw_read;
+		dev->bmc_ops.flash_read = n3000_flash_read;
+		dev->bmc_ops.flash_write = n3000_flash_write;
+
+		/* check the max10 version */
+		ret = check_max10_version(dev);
+		if (ret) {
+			dev_err(dev, "Failed to find max10 hardware!\n");
+			return ret;
+		}
+
+		/* load the MAX10 device table */
+		ret = init_max10_device_table(dev);
+		if (ret) {
+			dev_err(dev, "Init max10 device table fail\n");
+			return ret;
+		}
+
+		/* 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");
+			opae_free(dev->fdt_root);
+			return ret;
+		}
+	} else if (dev->type == M10_N6000) {
+		dev->ops = &m10bmc_pmci_regmap;
+		dev->csr = &m10bmc_pmci_csr;
+		dev->staging_area_size = MAX_STAGING_AREA_SIZE;
+		dev->flags |= MAX10_FLAGS_SECURE;
+
+		dev->bmc_ops.flash_read = pmci_flash_bulk_read;
+		dev->bmc_ops.flash_write = pmci_flash_bulk_write;
+		dev->bmc_ops.check_flash_range = pmci_check_flash_address;
+
+		ret = max10_sensor_init_table(dev, &n6010bmc_sensor_board_data);
+		if (ret)
+			return ret;
+
+		ret = pthread_mutex_init(&dev->bmc_ops.lock, NULL);
+		if (ret)
+			return ret;
+
+		if (!dev->bmc_ops.mutex)
+			dev->bmc_ops.mutex = &dev->bmc_ops.lock;
+	}
+
+	return ret;
 }
 
 int intel_max10_device_remove(struct intel_max10_device *dev)
@@ -722,15 +1489,14 @@  int intel_max10_device_remove(struct intel_max10_device *dev)
 	if (!dev)
 		return 0;
 
-	max10_sensor_uinit(dev);
+	pthread_mutex_destroy(&dev->bmc_ops.lock);
 
-	if (dev->spi_tran_dev)
-		spi_transaction_remove(dev->spi_tran_dev);
+	if (dev->type == M10_N3000) {
+		max10_sensor_uinit(dev);
 
-	if (dev->fdt_root)
-		opae_free(dev->fdt_root);
-
-	opae_free(dev);
+		if (dev->fdt_root)
+			opae_free(dev->fdt_root);
+	}
 
 	return 0;
 }
diff --git a/drivers/raw/ifpga/base/opae_intel_max10.h b/drivers/raw/ifpga/base/opae_intel_max10.h
index e761d7e..ead48ea 100644
--- a/drivers/raw/ifpga/base/opae_intel_max10.h
+++ b/drivers/raw/ifpga/base/opae_intel_max10.h
@@ -7,6 +7,9 @@ 
 
 #include "opae_osdep.h"
 #include "opae_spi.h"
+#include "ifpga_compat.h"
+
+struct intel_max10_device;
 
 struct max10_compatible_id {
 	char compatible[128];
@@ -29,6 +32,64 @@  struct max10_compatible_id {
 /** List of opae sensors */
 TAILQ_HEAD(opae_sensor_list, opae_sensor_info);
 
+/* Supported MAX10 BMC types */
+enum m10bmc_type {
+	M10_N3000,
+	M10_N6000
+};
+
+struct regmap_range {
+	unsigned int min;
+	unsigned int max;
+};
+
+struct m10bmc_regmap {
+	int (*reg_write)(struct intel_max10_device *dev,
+			unsigned int reg, unsigned int val);
+	int (*reg_read)(struct intel_max10_device *dev,
+			unsigned int reg, unsigned int *val);
+	const struct regmap_range *range;
+	int num_ranges;
+};
+
+struct m10bmc_csr {
+	unsigned int base;
+	unsigned int build_version;
+	unsigned int fw_version;
+	unsigned int fpga_page_info;
+	unsigned int doorbell;
+	unsigned int auth_result;
+};
+
+/**
+ * struct flash_raw_blk_ops - device specific operations for flash R/W
+ * @write_blk: write a block of data to flash
+ * @read_blk: read a block of data from flash
+ */
+struct flash_raw_blk_ops {
+	int (*write_blk)(struct intel_max10_device *dev, uint32_t addr,
+			void *buf, uint32_t size);
+	int (*read_blk)(struct intel_max10_device *dev, uint32_t addr,
+			void *buf, uint32_t size);
+};
+
+/**
+ * struct m10bmc_ops - device specific operations
+ * @lock: prevent concurrent flash read/write
+ * @mutex: prevent concurrent bmc read/write
+ * @flash_read: read a block of data from flash
+ * @flash_write: write a block of data to flash
+ */
+struct m10bmc_ops {
+	pthread_mutex_t lock;
+	pthread_mutex_t *mutex;
+	int (*check_flash_range)(u32 start, u32 end);
+	int (*flash_read)(struct intel_max10_device *dev, u32 addr,
+			void *buf, u32 size);
+	int (*flash_write)(struct intel_max10_device *dev, u32 addr,
+			void *buf, u32 size);
+};
+
 struct intel_max10_device {
 	unsigned int flags; /*max10 hardware capability*/
 	struct altera_spi_device *spi_master;
@@ -40,6 +101,12 @@  struct intel_max10_device {
 	struct opae_sensor_list opae_sensor_list;
 	u32 staging_area_base;
 	u32 staging_area_size;
+	enum m10bmc_type type;
+	const struct m10bmc_regmap *ops;
+	const struct m10bmc_csr *csr;
+	struct flash_raw_blk_ops raw_blk_ops;
+	struct m10bmc_ops bmc_ops;
+	u8 *mmio; /* mmio address for PMCI */
 };
 
 /* retimer speed */
@@ -87,6 +154,7 @@  struct opae_retimer_status {
 /* 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
@@ -151,6 +219,32 @@  struct opae_retimer_status {
 #define   SEC_STATUS_NON_INC		0x6
 #define   SEC_STATUS_ERASE_FAIL		0x7
 #define   SEC_STATUS_WEAROUT		0x8
+#define   SEC_STATUS_PMCI_SS_FAIL           0x9
+#define   SEC_STATUS_FLASH_CMD              0xa
+#define   SEC_STATUS_FACTORY_UNVERITY       0xb
+#define   SEC_STATUS_FACTORY_ACTIVE         0xc
+#define   SEC_STATUS_POWER_DOWN             0xd
+#define   SEC_STATUS_CANCELLATION           0xe
+#define   SEC_STATUS_HASH                   0xf
+#define   SEC_STATUS_FLASH_ACCESS           0x10
+#define   SEC_STATUS_SDM_PR_CERT            0x20
+#define   SEC_STATUS_SDM_PR_NIOS_BUSY       0x21
+#define   SEC_STATUS_SDM_PR_TIMEOUT         0x22
+#define   SEC_STATUS_SDM_PR_FAILED          0x23
+#define   SEC_STATUS_SDM_PR_MISMATCH        0x24
+#define   SEC_STATUS_SDM_PR_FLUSH           0x25
+#define   SEC_STATUS_SDM_SR_CERT            0x30
+#define   SEC_STATUS_SDM_SR_NIOS_BUSY       0x31
+#define   SEC_STATUS_SDM_SR_TIMEOUT         0x32
+#define   SEC_STATUS_SDM_SR_FAILED          0x33
+#define   SEC_STATUS_SDM_SR_MISMATCH        0x34
+#define   SEC_STATUS_SDM_SR_FLUSH           0x35
+#define   SEC_STATUS_SDM_KEY_CERT           0x40
+#define   SEC_STATUS_SDM_KEY_NIOS_BUSY      0x41
+#define   SEC_STATUS_SDM_KEY_TIMEOUT        0x42
+#define   SEC_STATUS_SDM_KEY_FAILED         0x43
+#define   SEC_STATUS_SDM_KEY_MISMATCH       0x44
+#define   SEC_STATUS_SDM_KEY_FLUSH          0x45
 #define   SEC_STATUS_NIOS_OK		0x80
 #define   SEC_STATUS_USER_OK		0x81
 #define   SEC_STATUS_FACTORY_OK		0x82
@@ -158,9 +252,65 @@  struct opae_retimer_status {
 #define   SEC_STATUS_FACTORY_FAIL	0x84
 #define   SEC_STATUS_NIOS_FLASH_ERR	0x85
 #define   SEC_STATUS_FPGA_FLASH_ERR	0x86
+#define   SEC_STATUS_MAX   SEC_STATUS_FPGA_FLASH_ERR
+
+/* Authentication status */
+#define SEC_AUTH_G(v)	((v) & 0xff)
+#define AUTH_STAT_PASS    0x0
+#define AUTH_STAT_B0_MAGIC   0x1
+#define AUTH_STAT_CONLEN  0x2
+#define AUTH_STAT_CONTYPE 0x3
+#define AUTH_STAT_B1_MAGIC 0x4
+#define AUTH_STAT_ROOT_MAGIC 0x5
+#define AUTH_STAT_CURVE_MAGIC 0x6
+#define AUTH_STAT_PERMISSION 0x7
+#define AUTH_STAT_KEY_ID    0x8
+#define AUTH_STAT_CSK_MAGIC 0x9
+#define AUTH_STAT_CSK_CURVE 0xa
+#define AUTH_STAT_CSK_PERMISSION 0xb
+#define AUTH_STAT_CSK_ID    0xc
+#define AUTH_STAT_CSK_SM 0xd
+#define AUTH_STAT_B0_E_MAGIC 0xe
+#define AUTH_STAT_B0_E_SIGN 0xf
+#define AUTH_STAT_RK_P      0x10
+#define AUTH_STAT_RE_SHA    0x11
+#define AUTH_STAT_CSK_SHA   0x12
+#define AUTH_STAT_B0_SHA    0x13
+#define AUTH_STAT_KEY_INV   0x14
+#define AUTH_STAT_KEY_CAN   0x15
+#define AUTH_STAT_UP_SHA    0x16
+#define AUTH_STAT_CAN_SHA   0x17
+#define AUTH_STAT_HASH      0x18
+#define AUTH_STAT_INV_ID    0x19
+#define AUTH_STAT_KEY_PROG  0x1a
+#define AUTH_STAT_INV_BC    0x1b
+#define AUTH_STAT_INV_SLOT  0x1c
+#define AUTH_STAT_IN_OP     0x1d
+#define AUTH_STAT_TIME_OUT  0X1e
+#define AUTH_STAT_SHA_TO    0x1f
+#define AUTH_STAT_CSK_TO    0x20
+#define AUTH_STAT_B0_TO     0x21
+#define AUTH_STAT_UP_TO     0x22
+#define AUTH_STAT_CAN_TO    0x23
+#define AUTH_STAT_HASH_TO   0x24
+#define AUTH_STAT_AUTH_IDLE 0xfe
+#define AUTH_STAT_GA_FAIL   0xff
+#define AUTH_STAT_S_ERR     0x8000
+#define AUTH_STAT_S_MN      0x8001
+#define AUTH_STAT_SH_CRC     0x8002
+#define AUTH_STAT_SD_CRC    0x8003
+#define AUTH_STAT_SD_LEN    0x8004
+#define AUTH_STAT_S_ID      0x8005
+#define AUTH_STAT_S_THR    0x8006
+#define AUTH_STAT_S_TO      0x8007
+#define AUTH_STAT_S_EN     0x8008
+#define AUTH_STAT_SF       0x8009
+#define AUTH_STAT_MAX    AUTH_STAT_SF
+
 #define   CONFIG_SEL		BIT(28)
 #define   CONFIG_SEL_S(v)	(((v) & 0x1) << 28)
 #define   REBOOT_REQ		BIT(29)
+#define   REBOOT_DISABLED	BIT(30)
 #define MAX10_AUTH_RESULT	0x404
 
 /* PKVL related registers, in system register region */
@@ -185,22 +335,26 @@  struct opae_retimer_status {
 #define MAX_STAGING_AREA_BASE	0xffffffff
 #define MAX_STAGING_AREA_SIZE	0x3800000
 
-int max10_reg_read(struct intel_max10_device *dev,
-	unsigned int reg, unsigned int *val);
-int max10_reg_write(struct intel_max10_device *dev,
-	unsigned int reg, unsigned int val);
+#define m10bmc_base(max10) ((max10)->csr->base)
+#define doorbell_reg(max10) ((max10)->csr->doorbell)
+#define auth_result_reg(max10) ((max10)->csr->auth_result)
+
 int max10_sys_read(struct intel_max10_device *dev,
 	unsigned int offset, unsigned int *val);
 int max10_sys_write(struct intel_max10_device *dev,
 	unsigned int offset, unsigned int val);
+int max10_sys_raw_read(struct intel_max10_device *dev,
+	unsigned int offset, unsigned int *val);
+int max10_sys_raw_write(struct intel_max10_device *dev,
+	unsigned int offset, unsigned int val);
 int max10_sys_update_bits(struct intel_max10_device *dev,
 	unsigned int offset, unsigned int msk, unsigned int val);
-struct intel_max10_device *
-intel_max10_device_probe(struct altera_spi_device *spi,
-		int chipselect);
+int max10_get_bmcfw_version(struct intel_max10_device *dev, unsigned int *val);
+int max10_get_bmc_version(struct intel_max10_device *dev, unsigned int *val);
+int max10_get_fpga_load_info(struct intel_max10_device *dev, unsigned int *val);
+int intel_max10_device_init(struct intel_max10_device *dev);
 int intel_max10_device_remove(struct intel_max10_device *dev);
 
-
 #define SENSOR_REG_VALUE 0x0
 #define SENSOR_REG_HIGH_WARN 0x1
 #define SENSOR_REG_HIGH_FATAL 0x2
@@ -254,4 +408,147 @@  struct opae_sensor_info {
 	unsigned int value_reg;
 };
 
+#define SENSOR_INVALID 0xdeadbeef
+
+struct max10_sensor_raw_data {
+	unsigned int reg_input;
+	unsigned int reg_high_warn;
+	unsigned int reg_high_fatal;
+	unsigned int reg_hyst;
+	unsigned int reg_low_warn;
+	unsigned int multiplier;
+	const char *label;
+};
+
+struct max10_sensor_data {
+	const char *type;
+	unsigned int number;
+	const struct max10_sensor_raw_data *table;
+};
+
+enum max10_sensor_types {
+	sensor_temp,
+	sensor_in,
+	sensor_curr,
+	sensor_power,
+	sensor_max,
+};
+
+#define SENSOR_TMP_NAME "Temperature"
+#define SENSOR_IN_NAME "Voltage"
+#define SENSOR_CURR_NAME "Current"
+#define SENSOR_POWER_NAME "Power"
+
+struct max10_sensor_board_data {
+	const struct max10_sensor_data *tables[sensor_max];
+};
+
+/* indirect access for PMCI */
+#define PMCI_INDIRECT_BASE 0x400
+#define INDIRECT_CMD_OFF   (PMCI_INDIRECT_BASE + 0x0)
+#define INDIRECT_CMD_RD	BIT(0)
+#define INDIRECT_CMD_WR	BIT(1)
+#define INDIRECT_CMD_ACK	BIT(2)
+
+#define INDIRECT_ADDR_OFF	 (PMCI_INDIRECT_BASE + 0x4)
+#define INDIRECT_RD_OFF	         (PMCI_INDIRECT_BASE + 0x8)
+#define INDIRECT_WR_OFF	 (PMCI_INDIRECT_BASE + 0xc)
+
+#define INDIRECT_INT_US	1
+#define INDIRECT_TIMEOUT_US	10000
+
+#define M10BMC_PMCI_SYS_BASE 0x0
+#define M10BMC_PMCI_SYS_END  0xfff
+
+#define M10BMC_PMCI_BUILD_VER   0x0
+#define NIOS2_PMCI_FW_VERSION   0x4
+
+#define M10BMC_PMCI_PWR_STATE 0xb4
+#define PMCI_PRIMARY_IMAGE_PAGE GENMASK(10, 8)
+
+#define M10BMC_PMCI_DOORBELL 0x1c0
+#define PMCI_DRBL_REBOOT_DISABLED BIT(1)
+#define M10BMC_PMCI_AUTH_RESULT 0x1c4
+
+#define M10BMC_PMCI_MAX10_RECONF 0xfc
+#define PMCI_MAX10_REBOOT_REQ BIT(0)
+#define PMCI_MAX10_REBOOT_PAGE BIT(1)
+
+#define M10BMC_PMCI_FPGA_RECONF 0xb8
+#define PMCI_FPGA_RECONF_PAGE  GENMASK(22, 20)
+#define PMCI_FPGA_RP_LOAD      BIT(23)
+
+#define PMCI_FLASH_CTRL 0x40
+#define PMCI_FLASH_WR_MODE BIT(0)
+#define PMCI_FLASH_RD_MODE BIT(1)
+#define PMCI_FLASH_BUSY    BIT(2)
+#define PMCI_FLASH_FIFO_SPACE GENMASK(13, 4)
+#define PMCI_FLASH_READ_COUNT GENMASK(25, 16)
+
+#define PMCI_FLASH_INT_US       1
+#define PMCI_FLASH_TIMEOUT_US   10000
+
+#define PMCI_FLASH_ADDR 0x44
+#define PMCI_FLASH_FIFO 0x800
+#define PMCI_READ_BLOCK_SIZE 0x800
+#define PMCI_FIFO_MAX_BYTES 0x800
+#define PMCI_FIFO_MAX_WORDS (PMCI_FIFO_MAX_BYTES / 4)
+
+#define M10BMC_PMCI_FPGA_POC	0xb0
+#define PMCI_FPGA_POC		BIT(0)
+#define PMCI_NIOS_REQ_CLEAR	BIT(1)
+#define PMCI_NIOS_STATUS	GENMASK(5, 4)
+#define NIOS_STATUS_IDLE	0
+#define NIOS_STATUS_SUCCESS	1
+#define NIOS_STATUS_FAIL	2
+#define PMCI_USER_IMAGE_PAGE	GENMASK(10, 8)
+#define POC_USER_IMAGE_1	1
+#define POC_USER_IMAGE_2	2
+#define PMCI_FACTORY_IMAGE_SEL	BIT(31)
+
+#define M10BMC_PMCI_FPGA_CONF_STS 0xa0
+#define PMCI_FPGA_BOOT_PAGE  GENMASK(2, 0)
+#define PMCI_FPGA_CONFIGED   BIT(3)
+
+#define M10BMC_PMCI_FLASH_CTRL 0x1d0
+#define FLASH_MUX_SELECTION GENMASK(2, 0)
+#define FLASH_MUX_IDLE 0
+#define FLASH_MUX_NIOS 1
+#define FLASH_MUX_HOST 2
+#define FLASH_MUX_PFL  4
+#define get_flash_mux(mux)  GET_FIELD(FLASH_MUX_SELECTION, mux)
+#define FLASH_NIOS_REQUEST BIT(4)
+#define FLASH_HOST_REQUEST BIT(5)
+
+#define M10BMC_PMCI_SDM_CTRL_STS 0x230
+#define PMCI_SDM_IMG_REQ	BIT(0)
+#define PMCI_SDM_STAT GENMASK(23, 16)
+
+#define SDM_STAT_DONE    0x0
+#define SDM_STAT_PROV    0x1
+#define SDM_STAT_BUSY    0x2
+#define SDM_STAT_INV     0x3
+#define SDM_STAT_FAIL    0x4
+#define SDM_STAT_BMC_BUSY 0x5
+#define SDM_STAT_TO      0x6
+#define SDM_STAT_DB      0x7
+#define SDM_STAT_CON_R    0x8
+#define SDM_STAT_CON_E    0x9
+#define SDM_STAT_WAIT     0xa
+#define SDM_STAT_RTO      0xb
+#define SDM_STAT_SB       0xc
+#define SDM_STAT_RE       0xd
+#define SDM_STAT_PDD     0xe
+#define SDM_STAT_ISC     0xf
+#define SDM_STAT_SIC     0x10
+#define SDM_STAT_NO_PROV  0x11
+#define SDM_STAT_CS_MIS   0x12
+#define SDM_STAT_PR_MIS   0x13
+#define SDM_STAT_MAX SDM_STAT_PR_MIS
+
+#define PMCI_FLASH_START 0x10000
+#define PMCI_FLASH_END 0xC7FFFFF
+
+int opae_read_flash(struct intel_max10_device *dev, u32 addr,
+		u32 size, void *buf);
 #endif
diff --git a/drivers/raw/ifpga/base/opae_osdep.h b/drivers/raw/ifpga/base/opae_osdep.h
index 18e6a11..033b7e0 100644
--- a/drivers/raw/ifpga/base/opae_osdep.h
+++ b/drivers/raw/ifpga/base/opae_osdep.h
@@ -79,15 +79,38 @@  struct uuid {
 #define time_before(a, b)	time_after(b, a)
 #define opae_memset(a, b, c)    memset((a), (b), (c))
 
-#define opae_readq_poll_timeout(addr, val, cond, invl, timeout)\
-({									     \
-	int wait = 0;							     \
-	for (; wait <= timeout; wait += invl) {			     \
-		(val) = opae_readq(addr);				     \
-		if (cond)                  \
-			break;						     \
-		udelay(invl);						     \
-	}								     \
-	(cond) ? 0 : -ETIMEDOUT;	  \
+#define readx_poll_timeout(op, val, cond, invl, timeout, args...) \
+({                                                                \
+	unsigned long __wait = 0;                                     \
+	unsigned long __invl = (invl);                                \
+	unsigned long __timeout = (timeout);                          \
+	for (; __wait <= __timeout; __wait += __invl) {               \
+		(val) = op(args);                                         \
+		if (cond)                                                 \
+			break;                                                \
+		udelay(__invl);                                           \
+	}                                                             \
+	(cond) ? 0 : -ETIMEDOUT;                                      \
 })
+
+#define opae_readq_poll_timeout(addr, val, cond, invl, timeout) \
+	readx_poll_timeout(opae_readq, val, cond, invl, timeout, addr)
+
+#define opae_readl_poll_timeout(addr, val, cond, invl, timeout) \
+	readx_poll_timeout(opae_readl, val, cond, invl, timeout, addr)
+
+#define opae_readw_poll_timeout(addr, val, cond, invl, timeout) \
+	readx_poll_timeout(opae_readw, val, cond, invl, timeout, addr)
+
+#define opae_readb_poll_timeout(addr, val, cond, invl, timeout) \
+	readx_poll_timeout(opae_readb, val, cond, invl, timeout, addr)
+
+#define opae_max10_read_poll_timeout(dev, addr, value, cond, invl, timeout) \
+({ \
+	int __ret, __tmp; \
+	__tmp = readx_poll_timeout(max10_sys_read, __ret, __ret || (cond), \
+			invl, timeout, (dev), (addr), &(value)); \
+	__ret?:__tmp; \
+})
+
 #endif
diff --git a/drivers/raw/ifpga/base/osdep_rte/osdep_generic.h b/drivers/raw/ifpga/base/osdep_rte/osdep_generic.h
index 3ff49a8..68499e6 100644
--- a/drivers/raw/ifpga/base/osdep_rte/osdep_generic.h
+++ b/drivers/raw/ifpga/base/osdep_rte/osdep_generic.h
@@ -39,6 +39,16 @@ 
 #define min(a, b) RTE_MIN(a, b)
 #define max(a, b) RTE_MAX(a, b)
 
+#define min_t(type, x, y) ({                    \
+	type __min1 = (x);                      \
+	type __min2 = (y);                      \
+	__min1 < __min2 ? __min1 : __min2; })
+
+#define max_t(type, x, y) ({                    \
+	type __max1 = (x);                      \
+	type __max2 = (y);                      \
+	__max1 > __max2 ? __max1 : __max2; })
+
 #define spinlock_t rte_spinlock_t
 #define spinlock_init(x) rte_spinlock_init(x)
 #define spinlock_lock(x) rte_spinlock_lock(x)