DPDK patches and discussions
 help / color / mirror / Atom feed
From: "Huang, Wei" <wei.huang@intel.com>
To: "Zhang, Tianfei" <tianfei.zhang@intel.com>,
	"dev@dpdk.org" <dev@dpdk.org>,
	 "thomas@monjalon.net" <thomas@monjalon.net>,
	"nipun.gupta@nxp.com" <nipun.gupta@nxp.com>,
	"hemant.agrawal@nxp.com" <hemant.agrawal@nxp.com>
Cc: "stable@dpdk.org" <stable@dpdk.org>,
	"Xu, Rosen" <rosen.xu@intel.com>,
	"Zhang, Qi Z" <qi.z.zhang@intel.com>
Subject: RE: [PATCH v2 1/2] raw/ifpga/base: add pmci driver
Date: Mon, 13 Jun 2022 07:29:22 +0000	[thread overview]
Message-ID: <DM6PR11MB353083E315577E7E9AC6E9A9EFAB9@DM6PR11MB3530.namprd11.prod.outlook.com> (raw)
In-Reply-To: <BN9PR11MB5483F360E3DEC5BA33FAD554E3AB9@BN9PR11MB5483.namprd11.prod.outlook.com>



> -----Original Message-----
> From: Zhang, Tianfei <tianfei.zhang@intel.com>
> Sent: Monday, June 13, 2022 15:01
> To: Huang, Wei <wei.huang@intel.com>; dev@dpdk.org;
> thomas@monjalon.net; nipun.gupta@nxp.com; hemant.agrawal@nxp.com
> Cc: stable@dpdk.org; Xu, Rosen <rosen.xu@intel.com>; Zhang, Qi Z
> <qi.z.zhang@intel.com>
> Subject: RE: [PATCH v2 1/2] raw/ifpga/base: add pmci driver
> 
> 
> 
> > -----Original Message-----
> > From: Huang, Wei <wei.huang@intel.com>
> > Sent: Friday, June 10, 2022 10:25 AM
> > To: dev@dpdk.org; thomas@monjalon.net; nipun.gupta@nxp.com;
> > hemant.agrawal@nxp.com
> > Cc: stable@dpdk.org; Xu, Rosen <rosen.xu@intel.com>; Zhang, Tianfei
> > <tianfei.zhang@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>; Huang,
> Wei
> > <wei.huang@intel.com>
> > Subject: [PATCH v2 1/2] raw/ifpga/base: add pmci driver
> >
> > 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>
> > ---
> >  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(-)
> 
> This patch is very huge. I thinks this patch can slit into 3 patches: base PMCI
> driver, flash support and sensor support.
> 
Agree, let me split it into three patches.
> >
> > 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;
> 
> This is a potential concurrency issue, one thread reading the flash content
> while other thread writing the flash.
> There is a hardware lock mechanism in flash controller, when one thread
> write the flash, it got the hardware lock
> in flash controller. And at the same time, the read thread will return fail on
> pmci_set_flash_host_mux(). So in this case,
> it should goto fail label to release the mutex lock.
> 
> > +
> > +	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)
> > --
> > 1.8.3.1


  reply	other threads:[~2022-06-13  7:29 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-25  1:51 [PATCH v1 0/2] Update rsu implementation Wei Huang
2022-05-25  1:51 ` [PATCH v1 1/2] raw/ifpga/base: add pmci driver Wei Huang
2022-05-25  1:51 ` [PATCH v1 2/2] raw/ifpga: update secure rsu Wei Huang
2022-06-10  2:24 ` [PATCH v2 0/2] update rsu implementation Wei Huang
2022-06-10  2:24   ` [PATCH v2 1/2] raw/ifpga/base: add pmci driver Wei Huang
2022-06-13  7:01     ` Zhang, Tianfei
2022-06-13  7:29       ` Huang, Wei [this message]
2022-06-10  2:25   ` [PATCH v2 2/2] raw/ifpga: update secure rsu Wei Huang
2022-06-17  7:19   ` [PATCH v3 0/4] introduce PMCI driver Wei Huang
2022-06-17  7:19     ` [PATCH v3 1/4] raw/ifpga/base: add PMCI base driver Wei Huang
2022-06-17  8:57       ` Zhang, Tianfei
2022-06-17 14:41       ` Xu, Rosen
2022-06-17  7:19     ` [PATCH v3 2/4] raw/ifpga/base: update board information Wei Huang
2022-06-17  8:57       ` Zhang, Tianfei
2022-06-17 14:42       ` Xu, Rosen
2022-06-17  7:19     ` [PATCH v3 3/4] raw/ifpga/base: update flash operation interface Wei Huang
2022-06-17  8:58       ` Zhang, Tianfei
2022-06-17 14:42       ` Xu, Rosen
2022-06-17  7:19     ` [PATCH v3 4/4] raw/ifpga/base: add PMCI sensor driver Wei Huang
2022-06-17  8:58       ` Zhang, Tianfei
2022-06-17 14:43       ` Xu, Rosen
2022-06-20 15:35     ` [PATCH v3 0/4] introduce PMCI driver Thomas Monjalon
2023-09-29 15:31   ` [PATCH v2 0/2] update rsu implementation David Marchand

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=DM6PR11MB353083E315577E7E9AC6E9A9EFAB9@DM6PR11MB3530.namprd11.prod.outlook.com \
    --to=wei.huang@intel.com \
    --cc=dev@dpdk.org \
    --cc=hemant.agrawal@nxp.com \
    --cc=nipun.gupta@nxp.com \
    --cc=qi.z.zhang@intel.com \
    --cc=rosen.xu@intel.com \
    --cc=stable@dpdk.org \
    --cc=thomas@monjalon.net \
    --cc=tianfei.zhang@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).