示例#1
0
static int fw_erase_stm(struct spi_device *spi)
{
	struct stm32fwu_spi_cmd cmd;
	struct stm32fwu_spi_cmd dummy_cmd;
	int ret;
	char buff[EXT_ER_DATA_LEN] = {0xff, 0xff, 0x00};
	ssp_dbgf();
	cmd.cmd = EXT_ER_COMMAND;
	cmd.xor_cmd = XOR_EXT_ER_COMMAND;
	cmd.timeout = DEF_ACKCMD_NUMBER;
	cmd.ack_pad = BL_DUMMY;

	ret = stm32fwu_spi_send_cmd(spi, &cmd);

	if (ret != BL_ACK) {
		ssp_err("fw_erase failed - %d", ret);
		return ret;
	}

	ret = stm32fwu_spi_write(spi, buff, EXT_ER_DATA_LEN);
	if (ret < EXT_ER_DATA_LEN) {
		ssp_err("fw_erase write failed");
		return 0;
	}

	dummy_cmd.timeout = DEF_ACK_ERASE_NUMBER;

	ret = stm32fwu_spi_wait_for_ack(spi, &dummy_cmd, BL_ACK);
	if (ret == BL_ACK)
		return 0;
	else if (ret == BL_NACK)
		return -EPROTO;
	else
		return -ETIME;
}
示例#2
0
static int update_mcu_bin(struct ssp_data *data, int iBinType)
{
	int retry = BLMODE_RETRYCOUNT;
	int iRet = SUCCESS;
	struct stm32fwu_spi_cmd cmd;

	cmd.cmd = GO_COMMAND;
	cmd.xor_cmd = XOR_GO_COMMAND;
	cmd.timeout = 1000;
	cmd.ack_pad = (u8)((STM_APP_ADDR >> 24) & 0xFF);

    // 1. Start system boot mode
	do {
		iRet = change_to_bootmode(data);
		pr_info("[ssp] bootmode %d retry: %d\n", iRet, 3 - retry);
	} while (retry-- > 0 && iRet != BL_ACK );

	if(iRet != BL_ACK) {
		pr_err("[SSP]: %s - change_to_bootmode %d\n",
			__func__, iRet);
		return iRet;
	}

    // 2. Flash erase all
	iRet = fw_erase_stm(data->spi);
	if (iRet < 0) {
		pr_err("[SSP]: %s - fw_erase_stm %d\n",
			__func__, iRet);
		return iRet;
	}

	switch (iBinType) {
	case KERNEL_BINARY:
	 /* HW request: I2C line is reversed */
#if defined(CONFIG_SEC_KSPORTS_PROJECT)
		iRet = load_kernel_fw_bootmode(data->spi, BL_FW_NAME_TASMAN);
#else
		iRet = load_kernel_fw_bootmode(data->spi, BL_FW_NAME);
#endif
		break;
	case KERNEL_CRASHED_BINARY:
		iRet = load_kernel_fw_bootmode(data->spi, BL_CRASHED_FW_NAME);
		break;
	case UMS_BINARY:
		iRet = load_ums_fw_bootmode(data->spi, BL_UMS_FW_NAME);
		break;
	default:
		pr_err("[SSP] binary type error!!\n");
	}
/* STM : GO USER ADDR */
	stm32fwu_spi_send_cmd(data->spi, &cmd);
	send_addr(data->spi, STM_APP_ADDR, 0);

	data->spi->mode = SPI_MODE_1;
	if (spi_setup(data->spi))
		pr_err("failed to setup spi mode for app\n");
	usleep_range(1000, 1100);

	return iRet;
}
示例#3
0
static int update_mcu_bin(struct ssp_data *data, int iBinType)
{
	int retry = BLMODE_RETRYCOUNT;
	int iRet = SUCCESS;
	struct stm32fwu_spi_cmd cmd;

	cmd.cmd = GO_COMMAND;
	cmd.xor_cmd = XOR_GO_COMMAND;
	cmd.timeout = 1000;
	cmd.ack_pad = (u8)((STM_APP_ADDR >> 24) & 0xFF);

	do {
		iRet = change_to_bootmode(data);
		pr_info("[ssp] bootmode %d retry: %d\n", iRet, 3 - retry);
	} while (retry-- > 0 && iRet != BL_ACK );

	if(iRet != BL_ACK) {
		pr_err("[SSP]: %s - change_to_bootmode %d\n",
			__func__, iRet);
		return iRet;
	}

	iRet = fw_erase_stm(data->spi);
	if (iRet < 0) {
		pr_err("[SSP]: %s - fw_erase_stm %d\n",
			__func__, iRet);
		return iRet;
	}

	switch (iBinType) {
	case KERNEL_BINARY:
	 /* HW request: I2C line is reversed */
	iRet = load_kernel_fw_bootmode(data->spi,
		BL_FW_NAME);
		break;
	case KERNEL_CRASHED_BINARY:
		iRet = load_kernel_fw_bootmode(data->spi,
		BL_CRASHED_FW_NAME);
	break;
	case UMS_BINARY:
		iRet = load_ums_fw_bootmode(data->spi,
			BL_UMS_FW_NAME);
		break;

	default:
		pr_err("[SSP] binary type error!!\n");
	}
/* STM : GO USER ADDR */
	stm32fwu_spi_send_cmd(data->spi, &cmd);
	if (cmd.ack_loops > 0)
		send_addr(data->spi, STM_APP_ADDR, 1);
	else
		send_addr(data->spi, STM_APP_ADDR, 0);

	msleep(SSP_SW_RESET_TIME);

	return iRet;
}
static int update_mcu_bin(struct ssp_data *data, int iBinType)
{
	int retry = BLMODE_RETRYCOUNT;
	int iRet = SUCCESS;
	struct stm32fwu_spi_cmd cmd;

	cmd.cmd = GO_COMMAND;
	cmd.xor_cmd = XOR_GO_COMMAND;
	cmd.timeout = 1000;
	cmd.ack_pad = (u8)((STM_APP_ADDR >> 24) & 0xFF);

	pr_info("[SSP] update_mcu_bin\n");
	
    // 1. Start system boot mode
	do {
		iRet = change_to_bootmode(data);
		pr_info("[SSP] bootmode %d, retry = %d\n", iRet, 3 - retry);
	} while (retry-- > 0 && iRet != BL_ACK);

	if(iRet != BL_ACK) {
		pr_err("[SSP] %s, change_to_bootmode failed %d\n", __func__, iRet);
		return iRet;
	}
    // 2. Flash erase all
	iRet = fw_erase_stm(data->spi);
	if (iRet < 0) {
		pr_err("[SSP] %s, fw_erase_stm failed %d\n", __func__, iRet);
		return iRet;
	}
	pr_info("======[SSP] SCHEDULE!!!!!\n");
	schedule(); /*Defence for cpu schedule blocking watchdog*/
	msleep(3);
	
	switch (iBinType) {
	case KERNEL_BINARY:
	 /* HW request: I2C line is reversed */
		iRet = load_kernel_fw_bootmode(data->spi, BL_FW_NAME);
		break;
	case KERNEL_CRASHED_BINARY:
		iRet = load_kernel_fw_bootmode(data->spi, BL_CRASHED_FW_NAME);
		break;
	case UMS_BINARY:
		iRet = load_ums_fw_bootmode(data->spi, BL_UMS_FW_NAME);
		break;
	default:
		pr_err("[SSP] binary type error!!\n");
	}
	pr_info("======[SSP] SCHEDULE!!!!!\n");
	schedule(); /*Defence for cpu schedule blocking watchdog*/
	msleep(3);

/* STM : GO USER ADDR */
	stm32fwu_spi_send_cmd(data->spi, &cmd);
	send_addr(data->spi, STM_APP_ADDR, 0);

	return iRet;
}
示例#5
0
static int update_mcu_bin(struct ssp_data *data, int iBinType)
{
	int retry = BLMODE_RETRYCOUNT;
	int iRet = SUCCESS;
	struct stm32fwu_spi_cmd cmd;

	cmd.cmd = GO_COMMAND;
	cmd.xor_cmd = XOR_GO_COMMAND;
	cmd.timeout = 1000;
	cmd.ack_pad = (u8)((STM_APP_ADDR >> 24) & 0xFF);

	/* 1. Start system boot mode */
	do {
		iRet = change_to_bootmode(data);
		ssp_info("bootmode %d retry: %d", iRet, 3 - retry);
	} while (retry-- > 0 && iRet != BL_ACK);

	if (iRet != BL_ACK) {
		ssp_errf("change_to_bootmode %d", iRet);
		return iRet;
	}

	/* 2. Flash erase all */
	iRet = fw_erase_stm(data->spi);
	if (iRet < 0) {
		ssp_errf("fw_erase_stm %d", iRet);
		return iRet;
	}

	switch (iBinType) {
	case KERNEL_BINARY:
	/* HW request: I2C line is reversed */
		iRet = load_kernel_fw_bootmode(data->spi, BL_FW_NAME);
		break;
	case KERNEL_CRASHED_BINARY:
		iRet = load_kernel_fw_bootmode(data->spi, BL_CRASHED_FW_NAME);
		break;
	case UMS_BINARY:
		iRet = load_ums_fw_bootmode(data->spi, BL_UMS_FW_NAME);
		break;
	default:
		ssp_err("binary type error!!");
	}

	/* STM : GO USER ADDR */
	stm32fwu_spi_send_cmd(data->spi, &cmd);
	send_addr(data->spi, STM_APP_ADDR, 0);

	data->spi->mode = SPI_MODE_1;
	if (spi_setup(data->spi))
		ssp_err("failed to setup spi mode for app");
	usleep_range(1000, 1100);

	return iRet;
}
static int fw_read_stm(struct spi_device *spi, u32 fw_addr,
	int len, const u8 *buffer)
{
	int res;
	struct stm32fwu_spi_cmd cmd;
	struct stm32fwu_spi_cmd dummy_cmd;
	int i;
	u8 xor = 0;
	u8 send_buff[STM_MAX_BUFFER_SIZE] = {0,};

	cmd.cmd = WMEM_COMMAND;
	cmd.xor_cmd = XOR_RMEM_COMMAND;
	cmd.timeout = DEF_ACKCMD_NUMBER;
	cmd.ack_pad = (u8)((fw_addr >> 24) & 0xFF);

	res = stm32fwu_spi_send_cmd(spi, &cmd);

	if (res != BL_ACK) {
		pr_err("[SSP] Error %d sending read_mem cmd\n", res);
		return res;
	}

	res = send_addr(spi, fw_addr, 0);

	if (res != 0) {
		pr_err("[SSP] Error %d sending read_mem Address\n", res);
		return res;
	}

	res = send_byte_count(spi, len, 1);

	if (res != 0) {
		return -EPROTO;
	}

    // Add Read Syc
    stm32fwu_spi_send_ack(spi, BL_DUMMY);

	res = stm32fwu_spi_read(spi, buffer, len);

	if (res < len) {
		return -EIO;
	}

	return len;
}
static int fw_erase_stm(struct spi_device *spi)
{
	struct stm32fwu_spi_cmd cmd;
	struct stm32fwu_spi_cmd dummy_cmd;
	int ret;
	char buff[EXT_ER_DATA_LEN] = {0xff, 0xff, 0x00};
	pr_debug("[SSP]%s\n", __func__);
	cmd.cmd = EXT_ER_COMMAND;
	cmd.xor_cmd = XOR_EXT_ER_COMMAND;
	cmd.timeout = DEF_ACKCMD_NUMBER;
	cmd.ack_pad = BL_DUMMY;

	ret = stm32fwu_spi_send_cmd(spi, &cmd);
	if (ret < 0 || ret != BL_ACK) {
		pr_err("[SSP] fw_erase failed\n");
		return ret;
	}

	ret = stm32fwu_spi_write(spi, buff, EXT_ER_DATA_LEN);

	if( ret < EXT_ER_DATA_LEN )
	{
		pr_err("[SSP] fw_erase write failed\n");
		return 0;
	}

	dummy_cmd.timeout = DEF_ACK_ERASE_NUMBER;

	ret = stm32fwu_spi_wait_for_ack(spi, &dummy_cmd, BL_ACK);

#if SSP_STM_DEBUG
	pr_info("[SSP] %s: stm32fwu_spi_wait_for_ack returned %d (0x%x)\n",
		__func__, ret, ret);
#endif

	if (ret == BL_ACK)
		return 0;
	else if (ret == BL_NACK)
		return -EPROTO;
	else
		return -ETIME;

}
示例#8
0
static int fw_erase_stm(struct spi_device *spi)
{
	struct stm32fwu_spi_cmd cmd;
	struct stm32fwu_spi_cmd dummy_cmd;
	int ret;
	char buff[EXT_ER_DATA_LEN] = {0xff, 0xff, 0x00};

	cmd.cmd = EXT_ER_COMMAND;
	cmd.xor_cmd = XOR_EXT_ER_COMMAND;
	cmd.timeout = DEF_ACKCMD_NUMBER;
	cmd.ack_pad = 0xFF;

	ret = stm32fwu_spi_send_cmd(spi, &cmd);

	if (ret < 0 || ret != BL_ACK) {
		pr_err("[SSP] fw_erase failed\n");
		return ret;
	}
	if (cmd.ack_loops == 0)
		ret = stm32fwu_spi_write(spi, buff, EXT_ER_DATA_LEN);
	else
		ret = stm32fwu_spi_write(spi, buff, EXT_ER_DATA_LEN-1);

	if (ret < (EXT_ER_DATA_LEN - cmd.ack_loops)) {
		return -EPROTO;
	}
	dummy_cmd.timeout = DEF_ACK_ERASE_NUMBER;
	ret = stm32fwu_spi_wait_for_ack(spi, &dummy_cmd, BL_ACK);


	if (ret == BL_ACK)
		return 0;
	else if (ret == BL_NACK)
		return -EPROTO;
	else
		return -ETIME;

}
static int fw_write_stm(struct spi_device *spi, u32 fw_addr,
	int len, const u8 *buffer)
{
	int res;
	struct stm32fwu_spi_cmd cmd;
	struct stm32fwu_spi_cmd dummy_cmd;
	int i;
	u8 xor = 0;
	u8 send_buff[STM_MAX_BUFFER_SIZE] = {0,};

	cmd.cmd = WMEM_COMMAND;
	cmd.xor_cmd = XOR_WMEM_COMMAND;
	cmd.timeout = DEF_ACKCMD_NUMBER;
	cmd.ack_pad = (u8)((fw_addr >> 24) & 0xFF);
	pr_debug("[SSP]%s\n", __func__);
#if SSP_STM_DEBUG
	pr_info("[SSP] sending WMEM_COMMAND\n");
#endif

	if (len > STM_MAX_XFER_SIZE) {
		pr_err("[SSP] Can't send more than 256 bytes per transaction\n");
		return -EINVAL;
	}

	send_buff[0] = len - 1;
	memcpy(&send_buff[1], buffer, len);
	for (i = 0; i < (len + 1); i++)
		xor ^= send_buff[i];

	send_buff[len + 1] = xor;

	res = stm32fwu_spi_send_cmd(spi, &cmd);
	if (res != BL_ACK) {
		pr_err("[SSP] Error %d sending read_mem cmd\n", res);
		return res;
	}

	res = send_addr(spi, fw_addr, 0);

	if (res != 0) {
		pr_err("[SSP] Error %d sending write_mem Address\n", res);
		return res;
	}

	res = stm32fwu_spi_write(spi, send_buff, len + 2);
	if (res < len) {
		pr_err("[SSP] Error writing to flash. res = %d\n", res);
		return ((res > 0) ? -EIO : res);
	}
	pr_debug("[SSP]%s 2\n", __func__);

	dummy_cmd.timeout = DEF_ACKROOF_NUMBER;
	usleep_range(100, 150); /* Samsung added */
	res = stm32fwu_spi_wait_for_ack(spi, &dummy_cmd, BL_ACK);
	if (res == BL_ACK) {
		return len;
	}

	if (res == BL_NACK) {
		pr_err("[SSP] Got NAK waiting for WRITE_MEM to complete\n");
		return -EPROTO;
	}
	pr_err("[SSP] timeout waiting for ACK for WRITE_MEM command\n");
	return -ETIME;
}