Re: [PATCH v3 4/6] usb: typec: ucsi: add cmd used for fw flashing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Feb 01, 2019 at 05:05:08PM -0800, Ajay Gupta wrote:
> From: Ajay Gupta <ajayg@xxxxxxxxxx>
> 
> Adding support for below commands which will be used
> during firmware flashing.
> 	- ENTER_FLASHING
> 	- RESET
> 	- PDPORT_ENABLE
> 	- JUMP_TO_BOOT
> 	- FLASH_ROW_RW
> 	- VALIDATE_FW
> I command specific mutex lock is also added to sync
> between driver and user threads.
> 
> Signed-off-by: Ajay Gupta <ajayg@xxxxxxxxxx>
> ---
> Changes from v2 to v3
> 	- None
> 
>  drivers/usb/typec/ucsi/ucsi_ccg.c | 216 ++++++++++++++++++++++++++++++
>  1 file changed, 216 insertions(+)
> 
> diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c b/drivers/usb/typec/ucsi/ucsi_ccg.c
> index 63b07b7d17f2..b9bbe90bdf57 100644
> --- a/drivers/usb/typec/ucsi/ucsi_ccg.c
> +++ b/drivers/usb/typec/ucsi/ucsi_ccg.c
> @@ -30,13 +30,34 @@ enum enum_fw_mode {
>  #define  PORT0_INT				BIT(1)
>  #define  PORT1_INT				BIT(2)
>  #define  UCSI_READ_INT				BIT(7)
> +#define CCGX_RAB_JUMP_TO_BOOT			0x0007
> +#define  TO_BOOT				'J'
> +#define  TO_ALT_FW				'A'
> +#define CCGX_RAB_RESET_REQ			0x0008
> +#define  RESET_SIG				'R'
> +#define  CMD_RESET_I2C				0x0
> +#define  CMD_RESET_DEV				0x1
> +#define CCGX_RAB_ENTER_FLASHING			0x000A
> +#define  FLASH_ENTER_SIG			'P'
> +#define CCGX_RAB_VALIDATE_FW			0x000B
> +#define CCGX_RAB_FLASH_ROW_RW			0x000C
> +#define  FLASH_SIG				'F'
> +#define  FLASH_RD_CMD				0x0
> +#define  FLASH_WR_CMD				0x1
> +#define  FLASH_FWCT1_WR_CMD			0x2
> +#define  FLASH_FWCT2_WR_CMD			0x3
> +#define  FLASH_FWCT_SIG_WR_CMD			0x4
>  #define CCGX_RAB_READ_ALL_VER			0x0010
>  #define CCGX_RAB_READ_FW2_VER			0x0020
>  #define CCGX_RAB_UCSI_CONTROL			0x0039
>  #define CCGX_RAB_UCSI_CONTROL_START		BIT(0)
>  #define CCGX_RAB_UCSI_CONTROL_STOP		BIT(1)
>  #define CCGX_RAB_UCSI_DATA_BLOCK(offset)	(0xf000 | ((offset) & 0xff))
> +#define REG_FLASH_RW_MEM        0x0200
>  #define DEV_REG_IDX				CCGX_RAB_DEVICE_MODE
> +#define CCGX_RAB_PDPORT_ENABLE			0x002C
> +#define  PDPORT_1		BIT(0)
> +#define  PDPORT_2		BIT(1)
>  #define CCGX_RAB_RESPONSE			0x007E
>  #define  ASYNC_EVENT				BIT(7)
>  
> @@ -47,6 +68,13 @@ enum enum_fw_mode {
>  #define PORT_DISCONNECT_DET	0x85
>  #define ROLE_SWAP_COMPELETE	0x87
>  
> +/* ccg firmware */
> +#define CYACD_LINE_SIZE         527
> +#define CCG4_ROW_SIZE           256
> +#define FW1_METADATA_ROW        0x1FF
> +#define FW2_METADATA_ROW        0x1FE
> +#define FW_CFG_TABLE_SIG_SIZE	256
> +
>  struct ccg_dev_info {
>  #define CCG_DEVINFO_FWMODE_SHIFT (0)
>  #define CCG_DEVINFO_FWMODE_MASK (0x3 << CCG_DEVINFO_FWMODE_SHIFT)
> @@ -118,6 +146,7 @@ struct ucsi_ccg {
>  	struct ccg_resp dev_resp;
>  	u8 cmd_resp;
>  	int port_num;
> +	struct mutex lock; /* to sync between user and driver thread */
>  };
>  
>  static int ccg_read(struct ucsi_ccg *uc, u16 rab, u8 *data, u32 len)
> @@ -431,6 +460,193 @@ static int ccg_send_command(struct ucsi_ccg *uc, struct ccg_cmd *cmd)
>  	return uc->cmd_resp;
>  }
>  
> +static int ccg_cmd_enter_flashing(struct ucsi_ccg *uc)
> +{
> +	struct ccg_cmd cmd;
> +	int ret;
> +
> +	cmd.reg = CCGX_RAB_ENTER_FLASHING;
> +	cmd.data = FLASH_ENTER_SIG;
> +	cmd.len = 1;
> +	cmd.delay = 50;
> +
> +	mutex_lock(&uc->lock);
> +
> +	ret = ccg_send_command(uc, &cmd);
> +
> +	mutex_unlock(&uc->lock);
> +
> +	if (ret != CMD_SUCCESS) {
> +		dev_err(uc->dev, "enter flashing failed ret=%d\n", ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int ccg_cmd_reset(struct ucsi_ccg *uc, bool extra_delay)
> +{
> +	struct ccg_cmd cmd;
> +	u8 *p;
> +	int ret;
> +
> +	p = (u8 *)&cmd.data;
> +	cmd.reg = CCGX_RAB_RESET_REQ;
> +	p[0] = RESET_SIG;
> +	p[1] = CMD_RESET_DEV;
> +	cmd.len = 2;
> +	cmd.delay = 2000 + (extra_delay ? 3000 : 0);
> +
> +	mutex_lock(&uc->lock);
> +
> +	set_bit(RESET_PENDING, &uc->flags);
> +
> +	ret = ccg_send_command(uc, &cmd);
> +	if (ret != RESET_COMPLETE)
> +		goto err_clear_flag;
> +
> +	ret = 0;
> +
> +err_clear_flag:
> +	clear_bit(RESET_PENDING, &uc->flags);
> +
> +	mutex_unlock(&uc->lock);
> +
> +	return ret;
> +}
> +
> +static int ccg_cmd_port_control(struct ucsi_ccg *uc, bool enable)
> +{
> +	struct ccg_cmd cmd;
> +	int ret;
> +
> +	cmd.reg = CCGX_RAB_PDPORT_ENABLE;
> +	if (enable)
> +		cmd.data = (uc->port_num == 1) ?
> +			    PDPORT_1 : (PDPORT_1 | PDPORT_2);
> +	else
> +		cmd.data = 0x0;
> +	cmd.len = 1;
> +	cmd.delay = 10;
> +
> +	mutex_lock(&uc->lock);
> +
> +	ret = ccg_send_command(uc, &cmd);
> +
> +	mutex_unlock(&uc->lock);
> +
> +	if (ret != CMD_SUCCESS) {
> +		dev_err(uc->dev, "port control failed ret=%d\n", ret);
> +		return ret;
> +	}
> +	return 0;
> +}
> +
> +static int ccg_cmd_jump_boot_mode(struct ucsi_ccg *uc, int bl_mode)
> +{
> +	struct ccg_cmd cmd;
> +	int ret;
> +
> +	cmd.reg = CCGX_RAB_JUMP_TO_BOOT;
> +
> +	if (bl_mode)
> +		cmd.data = TO_BOOT;
> +	else
> +		cmd.data = TO_ALT_FW;
> +
> +	cmd.len = 1;
> +	cmd.delay = 100;
> +
> +	mutex_lock(&uc->lock);
> +
> +	set_bit(RESET_PENDING, &uc->flags);
> +
> +	ret = ccg_send_command(uc, &cmd);
> +	if (ret != RESET_COMPLETE)
> +		goto err_clear_flag;
> +
> +	ret = 0;
> +
> +err_clear_flag:
> +	clear_bit(RESET_PENDING, &uc->flags);
> +
> +	mutex_unlock(&uc->lock);
> +
> +	return ret;
> +}
> +
> +static int
> +ccg_cmd_write_flash_row(struct ucsi_ccg *uc, u16 row,
> +			const void *data, u8 fcmd)
> +{
> +	struct i2c_client *client = uc->client;
> +	struct ccg_cmd cmd;
> +	u8 buf[CCG4_ROW_SIZE + 2];
> +	u8 *p;
> +	int ret;
> +
> +	/* Copy the data into the flash read/write memory. */
> +	buf[0] = REG_FLASH_RW_MEM & 0xFF;
> +	buf[1] = REG_FLASH_RW_MEM >> 8;
> +
> +	memcpy(buf + 2, data, CCG4_ROW_SIZE);
> +
> +	mutex_lock(&uc->lock);
> +
> +	ret = i2c_master_send(client, buf, CCG4_ROW_SIZE + 2);
> +	if (ret != CCG4_ROW_SIZE + 2) {
> +		dev_err(uc->dev, "REG_FLASH_RW_MEM write fail %d\n", ret);
> +		return ret < 0 ? ret : -EIO;
> +	}
> +
> +	/* Use the FLASH_ROW_READ_WRITE register to trigger */
> +	/* writing of data to the desired flash row */
> +	p = (u8 *)&cmd.data;
> +	cmd.reg = CCGX_RAB_FLASH_ROW_RW;
> +	p[0] = FLASH_SIG;
> +	p[1] = fcmd;
> +	p[2] = row & 0xFF;
> +	p[3] = row >> 8;
> +	cmd.len = 4;
> +	cmd.delay = 50;
> +	if (fcmd == FLASH_FWCT_SIG_WR_CMD)
> +		cmd.delay += 400;
> +	if (row == 510)
> +		cmd.delay += 220;
> +	ret = ccg_send_command(uc, &cmd);
> +
> +	mutex_unlock(&uc->lock);
> +
> +	if (ret != CMD_SUCCESS) {
> +		dev_err(uc->dev, "write flash row failed ret=%d\n", ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int ccg_cmd_validate_fw(struct ucsi_ccg *uc, unsigned int fwid)
> +{
> +	struct ccg_cmd cmd;
> +	int ret;
> +
> +	cmd.reg = CCGX_RAB_VALIDATE_FW;
> +	cmd.data = fwid;
> +	cmd.len = 1;
> +	cmd.delay = 500;
> +
> +	mutex_lock(&uc->lock);
> +
> +	ret = ccg_send_command(uc, &cmd);
> +
> +	mutex_unlock(&uc->lock);
> +
> +	if (ret != CMD_SUCCESS)
> +		return ret;
> +
> +	return 0;
> +}

Here you finally call ccg_send_command(), but now you introduce new
functions that are not yet used, causing compiler warnings.

I think these patches need to be reorganized.

thanks,

-- 
heikki



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux