From: fengsheng fengsheng5@huawei.com
driver inclusion category: feature bugzilla: NA CVE: NA
1. add interface: sysctl_pmbus_write_common 2. add interface: sysctl_pmbus_read_common
Signed-off-by: fengsheng fengsheng5@huawei.com Reviewed-by: wuyang wuyang7@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/soc/hisilicon/sysctl/sysctl_drv.c | 2 +- drivers/soc/hisilicon/sysctl/sysctl_pmbus.c | 113 ++++++++++++++++++++++------ drivers/soc/hisilicon/sysctl/sysctl_pmbus.h | 16 ++++ 3 files changed, 108 insertions(+), 23 deletions(-)
diff --git a/drivers/soc/hisilicon/sysctl/sysctl_drv.c b/drivers/soc/hisilicon/sysctl/sysctl_drv.c index 3899fac..c4cb157 100644 --- a/drivers/soc/hisilicon/sysctl/sysctl_drv.c +++ b/drivers/soc/hisilicon/sysctl/sysctl_drv.c @@ -48,7 +48,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define DEBUG
-#define SYSCTL_DRIVER_VERSION "1.9.39.1" +#define SYSCTL_DRIVER_VERSION "1.9.60.0"
unsigned int g_sysctrl_debug;
diff --git a/drivers/soc/hisilicon/sysctl/sysctl_pmbus.c b/drivers/soc/hisilicon/sysctl/sysctl_pmbus.c index 74d06a8..92eeba6 100644 --- a/drivers/soc/hisilicon/sysctl/sysctl_pmbus.c +++ b/drivers/soc/hisilicon/sysctl/sysctl_pmbus.c @@ -190,6 +190,9 @@ int InitPmbus(u8 chip_id) his_sysctrl_reg_wr(base, I2C_SS_SCL_HCNT_OFFSET, I2C_SS_SCLHCNT); /* ulSclLow > 1.5us */ his_sysctrl_reg_wr(base, I2C_SS_SCL_LCNT_OFFSET, I2C_SS_SCLLCNT); + /* set sda_hold_fs 1us > 250ns */ + his_sysctrl_reg_wr(base, I2C_SDA_HOLD_OFFSET, I2C_SS_SDA_HOLD_FS); + his_sysctrl_reg_wr(base, I2C_ENABLE_OFFSET, 0x1);
debug_sysctrl_print("Initialize Pmbus end\n"); @@ -233,35 +236,36 @@ int sysctl_pmbus_cfg(u8 chip_id, u8 addr, u8 page, u32 slave_addr) return 0; }
-int sysctl_pmbus_write(u8 chip_id, u8 addr, u32 slave_addr, u32 data_len, u32 buf) +int sysctl_pmbus_write_common(u8 chip_id, u32 slave_addr, u32 data_len, u8 *buf) { u32 i = 0; u32 temp = 0; u32 loop = 0x1000; - u32 temp_data = addr; + u32 temp_data; void __iomem *base = NULL;
if ((chip_id >= CHIP_ID_NUM_MAX) || - (data_len > DATA_NUM_MAX) || - (slave_addr >= SLAVE_ADDR_MAX)) { + (slave_addr >= SLAVE_ADDR_MAX) || + (!data_len) || (data_len > PMBUS_WRITE_LEN_MAX) || + (!buf)) { pr_err("[sysctl pmbus] write param err,chipid=0x%x,data_len=0x%x,slave_addr=0x%x!\n", chip_id, data_len, slave_addr); return SYSCTL_ERR_PARAM; }
+ /* clear all interrupt */ base = g_sysctl_pmbus_base[chip_id]; - his_sysctrl_reg_wr(base, I2C_INTR_RAW_OFFSET, 0x3ffff);
+ /* send: slave_addr[7bit] + write[1bit] */ his_sysctrl_reg_wr(base, I2C_DATA_CMD_OFFSET, (0x2 << 0x8) | slave_addr); - if (data_len != 0) { - his_sysctrl_reg_wr(base, I2C_DATA_CMD_OFFSET, addr);
- for (i = 0; i < data_len - 1; i++) - his_sysctrl_reg_wr(base, I2C_DATA_CMD_OFFSET, 0xff & (buf >> (i * 0x8))); + /* write data */ + for (i = 0; i < data_len - 1; i++) + his_sysctrl_reg_wr(base, I2C_DATA_CMD_OFFSET, buf[i]);
- temp_data = (0xff & (buf >> (i * 0x8))); - } + /* last data should send stop */ + temp_data = buf[i]; his_sysctrl_reg_wr(base, I2C_DATA_CMD_OFFSET, (0x4 << 0x8) | temp_data);
/* poll until send done */ @@ -273,14 +277,15 @@ int sysctl_pmbus_write(u8 chip_id, u8 addr, u32 slave_addr, u32 data_len, u32 bu /* send data failed */ if (temp & I2C_TX_ABRT) { his_sysctrl_reg_rd(base, I2C_TX_ABRT_SRC_REG, &temp); - pr_err("[sysctl pmbus]write data fail, chip_id:0x%x,slave_addr:0x%x, addr:0x%x!\r\n", - chip_id, slave_addr, addr); + pr_err("[sysctl pmbus]write data fail, chip_id:0x%x,slave_addr:0x%x\r\n", + chip_id, slave_addr);
his_sysctrl_reg_rd(base, I2C_CLR_TX_ABRT_REG, &temp); return SYSCTL_ERR_FAILED; }
his_sysctrl_reg_rd(base, I2C_STATUS_REG, &temp); + /* send done */ if (temp & I2C_TX_FIFO_EMPTY) { his_sysctrl_reg_rd(base, I2C_TX_FIFO_DATA_NUM_REG, &temp); if (temp == 0) @@ -289,8 +294,8 @@ int sysctl_pmbus_write(u8 chip_id, u8 addr, u32 slave_addr, u32 data_len, u32 bu
loop--; if (loop == 0) { - pr_err("[sysctl pmbus]write data retry fail, chip_id:0x%x,slave_addr:0x%x, addr:0x%x!\r\n", - chip_id, slave_addr, addr); + pr_err("[sysctl pmbus]write data retry fail, chip_id:0x%x,slave_addr:0x%x\r\n", + chip_id, slave_addr); return SYSCTL_ERR_FAILED; } } @@ -298,7 +303,25 @@ int sysctl_pmbus_write(u8 chip_id, u8 addr, u32 slave_addr, u32 data_len, u32 bu return SYSCTL_ERR_OK; }
-static int sysctl_pmbus_read_pre(void __iomem *base, u8 addr, u32 slave_addr, u32 data_len) +int sysctl_pmbus_write(u8 chip_id, u8 addr, u32 slave_addr, u32 data_len, u32 buf) +{ +#define TMP_LEN_MAX 5 + u8 i; + u8 tmp[TMP_LEN_MAX] = {0}; + + if (data_len > DATA_NUM_MAX) { + pr_err("[sysctl pmbus] write param err,data_len=0x%x!\n", data_len); + return SYSCTL_ERR_PARAM; + } + + tmp[0] = addr; + for (i = 0; i < data_len; i++) + tmp[i + 1] = (buf >> (i * 0x8)) & 0xff; + + return sysctl_pmbus_write_common(chip_id, slave_addr, data_len + sizeof(addr), &tmp[0]); +} + +static int sysctl_pmbus_read_pre(void __iomem *base, u32 cmd_len, u8 *cmd, u32 slave_addr, u32 data_len) { u32 i = 0; u32 fifo_num = 0; @@ -309,22 +332,29 @@ static int sysctl_pmbus_read_pre(void __iomem *base, u8 addr, u32 slave_addr, u3 return SYSCTL_ERR_PARAM; }
+ /* clear all interrupt */ his_sysctrl_reg_wr(base, I2C_INTR_RAW_OFFSET, 0x3ffff); + /* clear rx fifo */ his_sysctrl_reg_rd(base, I2C_RXFLR_OFFSET, &fifo_num); - debug_sysctrl_print("[sysctl_pmbus_read_byte]read pmbus , read empty rx fifo num:%d\r\n", fifo_num); for (i = 0; i < fifo_num; i++) his_sysctrl_reg_rd(base, I2C_DATA_CMD_OFFSET, &temp_byte);
- his_sysctrl_reg_wr(base, I2C_DATA_CMD_OFFSET, (0x2 << 0x8) | slave_addr); - his_sysctrl_reg_wr(base, I2C_DATA_CMD_OFFSET, addr); - his_sysctrl_reg_wr(base, I2C_DATA_CMD_OFFSET, (0x3 << 0x8) | slave_addr); + /* send cmd */ + if (cmd_len) { + his_sysctrl_reg_wr(base, I2C_DATA_CMD_OFFSET, (0x2 << 0x8) | slave_addr); + for (i = 0; i < cmd_len; i++) + his_sysctrl_reg_wr(base, I2C_DATA_CMD_OFFSET, cmd[i]); + }
+ /* read data */ + his_sysctrl_reg_wr(base, I2C_DATA_CMD_OFFSET, (0x3 << 0x8) | slave_addr); i = data_len; while ((i - 1) > 0) { his_sysctrl_reg_wr(base, I2C_DATA_CMD_OFFSET, 0x100); i--; }
+ /* last data should send stop */ his_sysctrl_reg_wr(base, I2C_DATA_CMD_OFFSET, 0x500);
return 0; @@ -366,6 +396,43 @@ static int sysctl_pmbus_wait_data(void __iomem *base, u32 data_len) return SYSCTL_ERR_OK; }
+int sysctl_pmbus_read_common(u8 chip_id, struct pmbus_read_op *op) +{ + u32 ret; + u32 i = 0; + u32 temp_byte = 0; + void __iomem *base = NULL; + + if ((chip_id >= CHIP_ID_NUM_MAX) || (!op)) { + pr_err("[sysctl pmbus]read param err,chipid=0x%x!\n", chip_id); + return SYSCTL_ERR_PARAM; + } + + if ((op->slave_addr >= SLAVE_ADDR_MAX) || + (!op->data_len) || ((op->cmd_len + op->data_len) > PMBUS_READ_LEN_MAX) || + (!op->data) || ((op->cmd_len) && (!op->cmd))) { + pr_err("[sysctl pmbus]read param err,data_len=0x%x,cmd_len=0x%x,slave_addr=0x%x\n", + op->data_len, op->cmd_len, op->slave_addr); + return SYSCTL_ERR_PARAM; + } + + base = g_sysctl_pmbus_base[chip_id]; + ret = sysctl_pmbus_read_pre(base, op->cmd_len, op->cmd, op->slave_addr, op->data_len); + if (ret != SYSCTL_ERR_OK) + return ret; + + ret = sysctl_pmbus_wait_data(base, op->data_len); + if (ret != SYSCTL_ERR_OK) + return ret; + + for (i = 0; i < op->data_len; i++) { + his_sysctrl_reg_rd(base, I2C_DATA_CMD_OFFSET, &temp_byte); + op->data[i] = temp_byte & 0xff; + } + + return SYSCTL_ERR_OK; +} + int sysctl_pmbus_read(u8 chip_id, u8 addr, u32 slave_addr, u32 data_len, u32 *buf) { u32 ret; @@ -385,7 +452,7 @@ int sysctl_pmbus_read(u8 chip_id, u8 addr, u32 slave_addr, u32 data_len, u32 *bu
base = g_sysctl_pmbus_base[chip_id];
- ret = sysctl_pmbus_read_pre(base, addr, slave_addr, data_len); + ret = sysctl_pmbus_read_pre(base, sizeof(addr), &addr, slave_addr, data_len); if (ret != SYSCTL_ERR_OK) return ret;
@@ -566,7 +633,7 @@ static int sysctl_cpu_convert_vol_to_vid(u32 vid_table, u32 value, u32 *vid) return SYSCTL_ERR_OK; }
-int sysctl_cpu_voltage_adjust (u8 chip_id, u8 loop, u32 slave_addr, u32 value) +int sysctl_cpu_voltage_adjust(u8 chip_id, u8 loop, u32 slave_addr, u32 value) { u32 ret; u32 vid; @@ -647,5 +714,7 @@ void hip_sysctl_pmbus_exit(void) EXPORT_SYMBOL(sysctl_cpu_voltage_adjust); EXPORT_SYMBOL(sysctl_pmbus_write); EXPORT_SYMBOL(sysctl_pmbus_read); +EXPORT_SYMBOL(sysctl_pmbus_write_common); +EXPORT_SYMBOL(sysctl_pmbus_read_common); EXPORT_SYMBOL(InitPmbus); EXPORT_SYMBOL(DeInitPmbus); diff --git a/drivers/soc/hisilicon/sysctl/sysctl_pmbus.h b/drivers/soc/hisilicon/sysctl/sysctl_pmbus.h index e1a4742..ce1d83d 100644 --- a/drivers/soc/hisilicon/sysctl/sysctl_pmbus.h +++ b/drivers/soc/hisilicon/sysctl/sysctl_pmbus.h @@ -20,6 +20,13 @@ #define PAGE_NUM_MAX (0x6f) #define DATA_NUM_MAX (0x4)
+#define I2C_FIFO_DEPTH (256) + +/* slave_addr use 1 fifo */ +#define PMBUS_READ_LEN_MAX (I2C_FIFO_DEPTH - 1) +/* slave_addr use 2 fifo */ +#define PMBUS_WRITE_LEN_MAX (I2C_FIFO_DEPTH - 2) + #define I2C_TX_ABRT (0x040) #define I2C_TX_ABRT_SRC_REG (0x0880) #define I2C_CLR_TX_ABRT_REG (0x0854) @@ -29,6 +36,7 @@
#define I2C_SS_SCLHCNT 0x3db #define I2C_SS_SCLLCNT 0x3e6 +#define I2C_SS_SDA_HOLD_FS 0xfa
/* AVS_REG_GEN */ #define AVS_WR_OPEN_OFFSET 0x0004 @@ -77,6 +85,14 @@ #define STATUS_RPT_OFFSET 0x0AA4 #define STATUS_ERR_RPT_OFFSET 0x0AA8
+struct pmbus_read_op { + u32 slave_addr; + u32 cmd_len; + u32 data_len; + u8 *cmd; + u8 *data; +}; + /* Define the union pmbus_vout_mode */ typedef union { /* Define the struct bits */
From: fengsheng fengsheng5@huawei.com
driver inclusion category: bugfix bugzilla: NA CVE: NA
Signed-off-by: fengsheng fengsheng5@huawei.com Reviewed-by: wuyang wuyang7@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/mtd/hisilicon/sfc/hrd_sfc_driver.c | 2 +- drivers/mtd/hisilicon/sfc/hrd_sflash_core.h | 1 + drivers/mtd/hisilicon/sfc/hrd_sflash_hal.c | 27 ++++++++++++++++++++++----- 3 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/drivers/mtd/hisilicon/sfc/hrd_sfc_driver.c b/drivers/mtd/hisilicon/sfc/hrd_sfc_driver.c index 8935263..23254e3 100644 --- a/drivers/mtd/hisilicon/sfc/hrd_sfc_driver.c +++ b/drivers/mtd/hisilicon/sfc/hrd_sfc_driver.c @@ -26,7 +26,7 @@ #include "hrd_common.h" #include "hrd_sflash_driver.h"
-#define SFC_DRIVER_VERSION "1.9.39.0" +#define SFC_DRIVER_VERSION "1.9.60.0"
static const char *g_sflashMtdList[] = {"sflash", NULL};
diff --git a/drivers/mtd/hisilicon/sfc/hrd_sflash_core.h b/drivers/mtd/hisilicon/sfc/hrd_sflash_core.h index 56c4417..ccf1d48 100644 --- a/drivers/mtd/hisilicon/sfc/hrd_sflash_core.h +++ b/drivers/mtd/hisilicon/sfc/hrd_sflash_core.h @@ -20,6 +20,7 @@ #include "hrd_sflash_driver.h"
#define SFC_HARD_BUF_LEN (256) +#define SPI_FLASH_PAGE_SIZE (256)
#define SPI_CMD_SR_WIP 1 /* Write in Progress bit in status register position */ #define SPI_CMD_RDSR 0x05 /* Read Status Register */ diff --git a/drivers/mtd/hisilicon/sfc/hrd_sflash_hal.c b/drivers/mtd/hisilicon/sfc/hrd_sflash_hal.c index ec9887a7..81fed47 100644 --- a/drivers/mtd/hisilicon/sfc/hrd_sflash_hal.c +++ b/drivers/mtd/hisilicon/sfc/hrd_sflash_hal.c @@ -731,7 +731,7 @@ static s32 _SFC_RegModeWrite(struct SFC_SFLASH_INFO *sflash, pr_err("[SFC] [%s %d]: SFC_RegWordAlignWrite fail\n", __func__, __LINE__); return slRet; } - i += ulRemain&(~0x3); + i += ulRemain & (~0x3); }
for (; i < ulWriteLen; i++) { @@ -749,6 +749,9 @@ s32 SFC_RegModeWrite(struct SFC_SFLASH_INFO *sflash, u32 offset, const u8 *pucSrc, u32 ulWriteLen) { s32 slRet; + u32 ulPageRemain; + u32 offsetTmp = offset; + u8 *pucSrcTmp = (u8 *)pucSrc;
if (!pucSrc) { pr_err("[SFC] [%s %d]: Pointer is null\n", __func__, __LINE__); @@ -762,9 +765,23 @@ s32 SFC_RegModeWrite(struct SFC_SFLASH_INFO *sflash,
SFC_CheckErr(sflash);
- slRet = _SFC_RegModeWrite(sflash, offset, pucSrc, ulWriteLen); - if (slRet != HRD_OK) - return slRet; + /* the size of data remaining on the first page */ + ulPageRemain = SPI_FLASH_PAGE_SIZE - (offset % SPI_FLASH_PAGE_SIZE); + if (ulWriteLen >= ulPageRemain) { + slRet = _SFC_RegModeWrite(sflash, offsetTmp, pucSrcTmp, ulPageRemain); + if (slRet != HRD_OK) + return slRet; + + offsetTmp += ulPageRemain; + pucSrcTmp += ulPageRemain; + ulWriteLen -= ulPageRemain; + } + + if (ulWriteLen) { + slRet = _SFC_RegModeWrite(sflash, offsetTmp, pucSrcTmp, ulWriteLen); + if (slRet != HRD_OK) + return slRet; + }
if (SFC_IsOpErr(sflash->sfc_reg_base)) return HRD_ERR; @@ -809,7 +826,7 @@ s32 SFC_RegModeRead(struct SFC_SFLASH_INFO *sflash, pr_err("[SFC] [%s %d]: SFC_RegWordAlignRead fail\n", __func__, __LINE__); return ret; } - i += ulRemain&(~0x3); + i += ulRemain & (~0x3); }
for (; i < ulReadLen; i++) {