mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
mfd: intel-m10-bmc: Support multiple CSR register layouts
There are different addresses for the MAX10 CSR registers. Introducing a new data structure m10bmc_csr_map for the register definition of MAX10 CSR. Provide the csr_map for SPI. Co-developed-by: Tianfei zhang <tianfei.zhang@intel.com> Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com> Reviewed-by: Russ Weight <russell.h.weight@intel.com> Reviewed-by: Xu Yilun <yilun.xu@intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Lee Jones <lee@kernel.org> Link: https://lore.kernel.org/r/20230116100845.6153-6-ilpo.jarvinen@linux.intel.com
This commit is contained in:
parent
603aed8ffd
commit
6052a005ca
@ -73,16 +73,24 @@ show_root_entry_hash(struct device *dev, u32 exp_magic,
|
||||
return cnt;
|
||||
}
|
||||
|
||||
#define DEVICE_ATTR_SEC_REH_RO(_name, _magic, _prog_addr, _reh_addr) \
|
||||
#define DEVICE_ATTR_SEC_REH_RO(_name) \
|
||||
static ssize_t _name##_root_entry_hash_show(struct device *dev, \
|
||||
struct device_attribute *attr, \
|
||||
char *buf) \
|
||||
{ return show_root_entry_hash(dev, _magic, _prog_addr, _reh_addr, buf); } \
|
||||
{ \
|
||||
struct m10bmc_sec *sec = dev_get_drvdata(dev); \
|
||||
const struct m10bmc_csr_map *csr_map = sec->m10bmc->info->csr_map; \
|
||||
\
|
||||
return show_root_entry_hash(dev, csr_map->_name##_magic, \
|
||||
csr_map->_name##_prog_addr, \
|
||||
csr_map->_name##_reh_addr, \
|
||||
buf); \
|
||||
} \
|
||||
static DEVICE_ATTR_RO(_name##_root_entry_hash)
|
||||
|
||||
DEVICE_ATTR_SEC_REH_RO(bmc, BMC_PROG_MAGIC, BMC_PROG_ADDR, BMC_REH_ADDR);
|
||||
DEVICE_ATTR_SEC_REH_RO(sr, SR_PROG_MAGIC, SR_PROG_ADDR, SR_REH_ADDR);
|
||||
DEVICE_ATTR_SEC_REH_RO(pr, PR_PROG_MAGIC, PR_PROG_ADDR, PR_REH_ADDR);
|
||||
DEVICE_ATTR_SEC_REH_RO(bmc);
|
||||
DEVICE_ATTR_SEC_REH_RO(sr);
|
||||
DEVICE_ATTR_SEC_REH_RO(pr);
|
||||
|
||||
#define CSK_BIT_LEN 128U
|
||||
#define CSK_32ARRAY_SIZE DIV_ROUND_UP(CSK_BIT_LEN, 32)
|
||||
@ -122,18 +130,25 @@ show_canceled_csk(struct device *dev, u32 addr, char *buf)
|
||||
return bitmap_print_to_pagebuf(1, buf, csk_map, CSK_BIT_LEN);
|
||||
}
|
||||
|
||||
#define DEVICE_ATTR_SEC_CSK_RO(_name, _addr) \
|
||||
#define DEVICE_ATTR_SEC_CSK_RO(_name) \
|
||||
static ssize_t _name##_canceled_csks_show(struct device *dev, \
|
||||
struct device_attribute *attr, \
|
||||
char *buf) \
|
||||
{ return show_canceled_csk(dev, _addr, buf); } \
|
||||
{ \
|
||||
struct m10bmc_sec *sec = dev_get_drvdata(dev); \
|
||||
const struct m10bmc_csr_map *csr_map = sec->m10bmc->info->csr_map; \
|
||||
\
|
||||
return show_canceled_csk(dev, \
|
||||
csr_map->_name##_prog_addr + CSK_VEC_OFFSET, \
|
||||
buf); \
|
||||
} \
|
||||
static DEVICE_ATTR_RO(_name##_canceled_csks)
|
||||
|
||||
#define CSK_VEC_OFFSET 0x34
|
||||
|
||||
DEVICE_ATTR_SEC_CSK_RO(bmc, BMC_PROG_ADDR + CSK_VEC_OFFSET);
|
||||
DEVICE_ATTR_SEC_CSK_RO(sr, SR_PROG_ADDR + CSK_VEC_OFFSET);
|
||||
DEVICE_ATTR_SEC_CSK_RO(pr, PR_PROG_ADDR + CSK_VEC_OFFSET);
|
||||
DEVICE_ATTR_SEC_CSK_RO(bmc);
|
||||
DEVICE_ATTR_SEC_CSK_RO(sr);
|
||||
DEVICE_ATTR_SEC_CSK_RO(pr);
|
||||
|
||||
#define FLASH_COUNT_SIZE 4096 /* count stored as inverted bit vector */
|
||||
|
||||
@ -141,6 +156,7 @@ static ssize_t flash_count_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct m10bmc_sec *sec = dev_get_drvdata(dev);
|
||||
const struct m10bmc_csr_map *csr_map = sec->m10bmc->info->csr_map;
|
||||
unsigned int stride, num_bits;
|
||||
u8 *flash_buf;
|
||||
int cnt, ret;
|
||||
@ -160,12 +176,12 @@ static ssize_t flash_count_show(struct device *dev,
|
||||
if (!flash_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = regmap_bulk_read(sec->m10bmc->regmap, STAGING_FLASH_COUNT,
|
||||
ret = regmap_bulk_read(sec->m10bmc->regmap, csr_map->rsu_update_counter,
|
||||
flash_buf, FLASH_COUNT_SIZE / stride);
|
||||
if (ret) {
|
||||
dev_err(sec->dev,
|
||||
"failed to read flash count: %x cnt %x: %d\n",
|
||||
STAGING_FLASH_COUNT, FLASH_COUNT_SIZE / stride, ret);
|
||||
csr_map->rsu_update_counter, FLASH_COUNT_SIZE / stride, ret);
|
||||
goto exit_free;
|
||||
}
|
||||
cnt = num_bits - bitmap_weight((unsigned long *)flash_buf, num_bits);
|
||||
@ -200,20 +216,22 @@ static const struct attribute_group *m10bmc_sec_attr_groups[] = {
|
||||
|
||||
static void log_error_regs(struct m10bmc_sec *sec, u32 doorbell)
|
||||
{
|
||||
const struct m10bmc_csr_map *csr_map = sec->m10bmc->info->csr_map;
|
||||
u32 auth_result;
|
||||
|
||||
dev_err(sec->dev, "RSU error status: 0x%08x\n", doorbell);
|
||||
|
||||
if (!m10bmc_sys_read(sec->m10bmc, M10BMC_AUTH_RESULT, &auth_result))
|
||||
if (!m10bmc_sys_read(sec->m10bmc, csr_map->auth_result, &auth_result))
|
||||
dev_err(sec->dev, "RSU auth result: 0x%08x\n", auth_result);
|
||||
}
|
||||
|
||||
static enum fw_upload_err rsu_check_idle(struct m10bmc_sec *sec)
|
||||
{
|
||||
const struct m10bmc_csr_map *csr_map = sec->m10bmc->info->csr_map;
|
||||
u32 doorbell;
|
||||
int ret;
|
||||
|
||||
ret = m10bmc_sys_read(sec->m10bmc, M10BMC_DOORBELL, &doorbell);
|
||||
ret = m10bmc_sys_read(sec->m10bmc, csr_map->doorbell, &doorbell);
|
||||
if (ret)
|
||||
return FW_UPLOAD_ERR_RW_ERROR;
|
||||
|
||||
@ -246,11 +264,12 @@ static inline bool rsu_start_done(u32 doorbell)
|
||||
|
||||
static enum fw_upload_err rsu_update_init(struct m10bmc_sec *sec)
|
||||
{
|
||||
const struct m10bmc_csr_map *csr_map = sec->m10bmc->info->csr_map;
|
||||
u32 doorbell, status;
|
||||
int ret;
|
||||
|
||||
ret = regmap_update_bits(sec->m10bmc->regmap,
|
||||
M10BMC_SYS_BASE + M10BMC_DOORBELL,
|
||||
csr_map->base + csr_map->doorbell,
|
||||
DRBL_RSU_REQUEST | DRBL_HOST_STATUS,
|
||||
DRBL_RSU_REQUEST |
|
||||
FIELD_PREP(DRBL_HOST_STATUS,
|
||||
@ -259,7 +278,7 @@ static enum fw_upload_err rsu_update_init(struct m10bmc_sec *sec)
|
||||
return FW_UPLOAD_ERR_RW_ERROR;
|
||||
|
||||
ret = regmap_read_poll_timeout(sec->m10bmc->regmap,
|
||||
M10BMC_SYS_BASE + M10BMC_DOORBELL,
|
||||
csr_map->base + csr_map->doorbell,
|
||||
doorbell,
|
||||
rsu_start_done(doorbell),
|
||||
NIOS_HANDSHAKE_INTERVAL_US,
|
||||
@ -286,11 +305,12 @@ static enum fw_upload_err rsu_update_init(struct m10bmc_sec *sec)
|
||||
|
||||
static enum fw_upload_err rsu_prog_ready(struct m10bmc_sec *sec)
|
||||
{
|
||||
const struct m10bmc_csr_map *csr_map = sec->m10bmc->info->csr_map;
|
||||
unsigned long poll_timeout;
|
||||
u32 doorbell, progress;
|
||||
int ret;
|
||||
|
||||
ret = m10bmc_sys_read(sec->m10bmc, M10BMC_DOORBELL, &doorbell);
|
||||
ret = m10bmc_sys_read(sec->m10bmc, csr_map->doorbell, &doorbell);
|
||||
if (ret)
|
||||
return FW_UPLOAD_ERR_RW_ERROR;
|
||||
|
||||
@ -300,7 +320,7 @@ static enum fw_upload_err rsu_prog_ready(struct m10bmc_sec *sec)
|
||||
if (time_after(jiffies, poll_timeout))
|
||||
break;
|
||||
|
||||
ret = m10bmc_sys_read(sec->m10bmc, M10BMC_DOORBELL, &doorbell);
|
||||
ret = m10bmc_sys_read(sec->m10bmc, csr_map->doorbell, &doorbell);
|
||||
if (ret)
|
||||
return FW_UPLOAD_ERR_RW_ERROR;
|
||||
}
|
||||
@ -319,11 +339,12 @@ static enum fw_upload_err rsu_prog_ready(struct m10bmc_sec *sec)
|
||||
|
||||
static enum fw_upload_err rsu_send_data(struct m10bmc_sec *sec)
|
||||
{
|
||||
const struct m10bmc_csr_map *csr_map = sec->m10bmc->info->csr_map;
|
||||
u32 doorbell;
|
||||
int ret;
|
||||
|
||||
ret = regmap_update_bits(sec->m10bmc->regmap,
|
||||
M10BMC_SYS_BASE + M10BMC_DOORBELL,
|
||||
csr_map->base + csr_map->doorbell,
|
||||
DRBL_HOST_STATUS,
|
||||
FIELD_PREP(DRBL_HOST_STATUS,
|
||||
HOST_STATUS_WRITE_DONE));
|
||||
@ -331,7 +352,7 @@ static enum fw_upload_err rsu_send_data(struct m10bmc_sec *sec)
|
||||
return FW_UPLOAD_ERR_RW_ERROR;
|
||||
|
||||
ret = regmap_read_poll_timeout(sec->m10bmc->regmap,
|
||||
M10BMC_SYS_BASE + M10BMC_DOORBELL,
|
||||
csr_map->base + csr_map->doorbell,
|
||||
doorbell,
|
||||
rsu_prog(doorbell) != RSU_PROG_READY,
|
||||
NIOS_HANDSHAKE_INTERVAL_US,
|
||||
@ -360,7 +381,9 @@ static enum fw_upload_err rsu_send_data(struct m10bmc_sec *sec)
|
||||
|
||||
static int rsu_check_complete(struct m10bmc_sec *sec, u32 *doorbell)
|
||||
{
|
||||
if (m10bmc_sys_read(sec->m10bmc, M10BMC_DOORBELL, doorbell))
|
||||
const struct m10bmc_csr_map *csr_map = sec->m10bmc->info->csr_map;
|
||||
|
||||
if (m10bmc_sys_read(sec->m10bmc, csr_map->doorbell, doorbell))
|
||||
return -EIO;
|
||||
|
||||
switch (rsu_stat(*doorbell)) {
|
||||
@ -389,10 +412,11 @@ static int rsu_check_complete(struct m10bmc_sec *sec, u32 *doorbell)
|
||||
|
||||
static enum fw_upload_err rsu_cancel(struct m10bmc_sec *sec)
|
||||
{
|
||||
const struct m10bmc_csr_map *csr_map = sec->m10bmc->info->csr_map;
|
||||
u32 doorbell;
|
||||
int ret;
|
||||
|
||||
ret = m10bmc_sys_read(sec->m10bmc, M10BMC_DOORBELL, &doorbell);
|
||||
ret = m10bmc_sys_read(sec->m10bmc, csr_map->doorbell, &doorbell);
|
||||
if (ret)
|
||||
return FW_UPLOAD_ERR_RW_ERROR;
|
||||
|
||||
@ -400,7 +424,7 @@ static enum fw_upload_err rsu_cancel(struct m10bmc_sec *sec)
|
||||
return FW_UPLOAD_ERR_BUSY;
|
||||
|
||||
ret = regmap_update_bits(sec->m10bmc->regmap,
|
||||
M10BMC_SYS_BASE + M10BMC_DOORBELL,
|
||||
csr_map->base + csr_map->doorbell,
|
||||
DRBL_HOST_STATUS,
|
||||
FIELD_PREP(DRBL_HOST_STATUS,
|
||||
HOST_STATUS_ABORT_RSU));
|
||||
@ -445,6 +469,7 @@ static enum fw_upload_err m10bmc_sec_write(struct fw_upload *fwl, const u8 *data
|
||||
u32 offset, u32 size, u32 *written)
|
||||
{
|
||||
struct m10bmc_sec *sec = fwl->dd_handle;
|
||||
const struct m10bmc_csr_map *csr_map = sec->m10bmc->info->csr_map;
|
||||
u32 blk_size, doorbell, extra_offset;
|
||||
unsigned int stride, extra = 0;
|
||||
int ret;
|
||||
@ -453,7 +478,7 @@ static enum fw_upload_err m10bmc_sec_write(struct fw_upload *fwl, const u8 *data
|
||||
if (sec->cancel_request)
|
||||
return rsu_cancel(sec);
|
||||
|
||||
ret = m10bmc_sys_read(sec->m10bmc, M10BMC_DOORBELL, &doorbell);
|
||||
ret = m10bmc_sys_read(sec->m10bmc, csr_map->doorbell, &doorbell);
|
||||
if (ret) {
|
||||
return FW_UPLOAD_ERR_RW_ERROR;
|
||||
} else if (rsu_prog(doorbell) != RSU_PROG_READY) {
|
||||
|
@ -19,7 +19,7 @@ static ssize_t bmc_version_show(struct device *dev,
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
ret = m10bmc_sys_read(ddata, M10BMC_BUILD_VER, &val);
|
||||
ret = m10bmc_sys_read(ddata, ddata->info->csr_map->build_version, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -34,7 +34,7 @@ static ssize_t bmcfw_version_show(struct device *dev,
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
ret = m10bmc_sys_read(ddata, NIOS2_FW_VERSION, &val);
|
||||
ret = m10bmc_sys_read(ddata, ddata->info->csr_map->fw_version, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -49,11 +49,11 @@ static ssize_t mac_address_show(struct device *dev,
|
||||
unsigned int macaddr_low, macaddr_high;
|
||||
int ret;
|
||||
|
||||
ret = m10bmc_sys_read(ddata, M10BMC_MAC_LOW, &macaddr_low);
|
||||
ret = m10bmc_sys_read(ddata, ddata->info->csr_map->mac_low, &macaddr_low);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = m10bmc_sys_read(ddata, M10BMC_MAC_HIGH, &macaddr_high);
|
||||
ret = m10bmc_sys_read(ddata, ddata->info->csr_map->mac_high, &macaddr_high);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -74,7 +74,7 @@ static ssize_t mac_count_show(struct device *dev,
|
||||
unsigned int macaddr_high;
|
||||
int ret;
|
||||
|
||||
ret = m10bmc_sys_read(ddata, M10BMC_MAC_HIGH, &macaddr_high);
|
||||
ret = m10bmc_sys_read(ddata, ddata->info->csr_map->mac_high, &macaddr_high);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -91,6 +91,26 @@ static int intel_m10_bmc_spi_probe(struct spi_device *spi)
|
||||
return m10bmc_dev_init(ddata, info);
|
||||
}
|
||||
|
||||
static const struct m10bmc_csr_map m10bmc_n3000_csr_map = {
|
||||
.base = M10BMC_SYS_BASE,
|
||||
.build_version = M10BMC_BUILD_VER,
|
||||
.fw_version = NIOS2_FW_VERSION,
|
||||
.mac_low = M10BMC_MAC_LOW,
|
||||
.mac_high = M10BMC_MAC_HIGH,
|
||||
.doorbell = M10BMC_DOORBELL,
|
||||
.auth_result = M10BMC_AUTH_RESULT,
|
||||
.bmc_prog_addr = BMC_PROG_ADDR,
|
||||
.bmc_reh_addr = BMC_REH_ADDR,
|
||||
.bmc_magic = BMC_PROG_MAGIC,
|
||||
.sr_prog_addr = SR_PROG_ADDR,
|
||||
.sr_reh_addr = SR_REH_ADDR,
|
||||
.sr_magic = SR_PROG_MAGIC,
|
||||
.pr_prog_addr = PR_PROG_ADDR,
|
||||
.pr_reh_addr = PR_REH_ADDR,
|
||||
.pr_magic = PR_PROG_MAGIC,
|
||||
.rsu_update_counter = STAGING_FLASH_COUNT,
|
||||
};
|
||||
|
||||
static struct mfd_cell m10bmc_d5005_subdevs[] = {
|
||||
{ .name = "d5005bmc-hwmon" },
|
||||
{ .name = "d5005bmc-sec-update" },
|
||||
@ -109,16 +129,19 @@ static struct mfd_cell m10bmc_n5010_subdevs[] = {
|
||||
static const struct intel_m10bmc_platform_info m10bmc_spi_n3000 = {
|
||||
.cells = m10bmc_pacn3000_subdevs,
|
||||
.n_cells = ARRAY_SIZE(m10bmc_pacn3000_subdevs),
|
||||
.csr_map = &m10bmc_n3000_csr_map,
|
||||
};
|
||||
|
||||
static const struct intel_m10bmc_platform_info m10bmc_spi_d5005 = {
|
||||
.cells = m10bmc_d5005_subdevs,
|
||||
.n_cells = ARRAY_SIZE(m10bmc_d5005_subdevs),
|
||||
.csr_map = &m10bmc_n3000_csr_map,
|
||||
};
|
||||
|
||||
static const struct intel_m10bmc_platform_info m10bmc_spi_n5010 = {
|
||||
.cells = m10bmc_n5010_subdevs,
|
||||
.n_cells = ARRAY_SIZE(m10bmc_n5010_subdevs),
|
||||
.csr_map = &m10bmc_n3000_csr_map,
|
||||
};
|
||||
|
||||
static const struct spi_device_id m10bmc_spi_id[] = {
|
||||
|
@ -121,14 +121,39 @@
|
||||
/* Address of 4KB inverted bit vector containing staging area FLASH count */
|
||||
#define STAGING_FLASH_COUNT 0x17ffb000
|
||||
|
||||
/**
|
||||
* struct m10bmc_csr_map - Intel MAX 10 BMC CSR register map
|
||||
*/
|
||||
struct m10bmc_csr_map {
|
||||
unsigned int base;
|
||||
unsigned int build_version;
|
||||
unsigned int fw_version;
|
||||
unsigned int mac_low;
|
||||
unsigned int mac_high;
|
||||
unsigned int doorbell;
|
||||
unsigned int auth_result;
|
||||
unsigned int bmc_prog_addr;
|
||||
unsigned int bmc_reh_addr;
|
||||
unsigned int bmc_magic;
|
||||
unsigned int sr_prog_addr;
|
||||
unsigned int sr_reh_addr;
|
||||
unsigned int sr_magic;
|
||||
unsigned int pr_prog_addr;
|
||||
unsigned int pr_reh_addr;
|
||||
unsigned int pr_magic;
|
||||
unsigned int rsu_update_counter;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct intel_m10bmc_platform_info - Intel MAX 10 BMC platform specific information
|
||||
* @cells: MFD cells
|
||||
* @n_cells: MFD cells ARRAY_SIZE()
|
||||
* @csr_map: the mappings for register definition of MAX10 BMC
|
||||
*/
|
||||
struct intel_m10bmc_platform_info {
|
||||
struct mfd_cell *cells;
|
||||
int n_cells;
|
||||
const struct m10bmc_csr_map *csr_map;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -167,12 +192,17 @@ m10bmc_raw_read(struct intel_m10bmc *m10bmc, unsigned int addr,
|
||||
* The base of the system registers could be configured by HW developers, and
|
||||
* in HW SPEC, the base is not added to the addresses of the system registers.
|
||||
*
|
||||
* This macro helps to simplify the accessing of the system registers. And if
|
||||
* This function helps to simplify the accessing of the system registers. And if
|
||||
* the base is reconfigured in HW, SW developers could simply change the
|
||||
* M10BMC_SYS_BASE accordingly.
|
||||
* csr_map's base accordingly.
|
||||
*/
|
||||
#define m10bmc_sys_read(m10bmc, offset, val) \
|
||||
m10bmc_raw_read(m10bmc, M10BMC_SYS_BASE + (offset), val)
|
||||
static inline int m10bmc_sys_read(struct intel_m10bmc *m10bmc, unsigned int offset,
|
||||
unsigned int *val)
|
||||
{
|
||||
const struct m10bmc_csr_map *csr_map = m10bmc->info->csr_map;
|
||||
|
||||
return m10bmc_raw_read(m10bmc, csr_map->base + offset, val);
|
||||
}
|
||||
|
||||
/*
|
||||
* MAX10 BMC Core support
|
||||
|
Loading…
Reference in New Issue
Block a user