@@ -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)
@@ -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 */
};
@@ -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);
@@ -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,
+};
@@ -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)
@@ -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);
@@ -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;
}
@@ -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);
@@ -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
*
@@ -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,
@@ -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;
}
@@ -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
@@ -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
@@ -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)