cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rmi_f34v7.c (33948B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (c) 2016, Zodiac Inflight Innovations
      4 * Copyright (c) 2007-2016, Synaptics Incorporated
      5 * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
      6 * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
      7 */
      8
      9#include <linux/bitops.h>
     10#include <linux/kernel.h>
     11#include <linux/rmi.h>
     12#include <linux/firmware.h>
     13#include <linux/delay.h>
     14#include <linux/slab.h>
     15#include <linux/jiffies.h>
     16#include <asm/unaligned.h>
     17
     18#include "rmi_driver.h"
     19#include "rmi_f34.h"
     20
     21static int rmi_f34v7_read_flash_status(struct f34_data *f34)
     22{
     23	u8 status;
     24	u8 command;
     25	int ret;
     26
     27	ret = rmi_read_block(f34->fn->rmi_dev,
     28			f34->fn->fd.data_base_addr + f34->v7.off.flash_status,
     29			&status,
     30			sizeof(status));
     31	if (ret < 0) {
     32		rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
     33			"%s: Error %d reading flash status\n", __func__, ret);
     34		return ret;
     35	}
     36
     37	f34->v7.in_bl_mode = status >> 7;
     38	f34->v7.flash_status = status & 0x1f;
     39
     40	if (f34->v7.flash_status != 0x00) {
     41		dev_err(&f34->fn->dev, "%s: status=%d, command=0x%02x\n",
     42			__func__, f34->v7.flash_status, f34->v7.command);
     43	}
     44
     45	ret = rmi_read_block(f34->fn->rmi_dev,
     46			f34->fn->fd.data_base_addr + f34->v7.off.flash_cmd,
     47			&command,
     48			sizeof(command));
     49	if (ret < 0) {
     50		dev_err(&f34->fn->dev, "%s: Failed to read flash command\n",
     51			__func__);
     52		return ret;
     53	}
     54
     55	f34->v7.command = command;
     56
     57	return 0;
     58}
     59
     60static int rmi_f34v7_wait_for_idle(struct f34_data *f34, int timeout_ms)
     61{
     62	unsigned long timeout;
     63
     64	timeout = msecs_to_jiffies(timeout_ms);
     65
     66	if (!wait_for_completion_timeout(&f34->v7.cmd_done, timeout)) {
     67		dev_warn(&f34->fn->dev, "%s: Timed out waiting for idle status\n",
     68			 __func__);
     69		return -ETIMEDOUT;
     70	}
     71
     72	return 0;
     73}
     74
     75static int rmi_f34v7_write_command_single_transaction(struct f34_data *f34,
     76						      u8 cmd)
     77{
     78	int ret;
     79	u8 base;
     80	struct f34v7_data_1_5 data_1_5;
     81
     82	base = f34->fn->fd.data_base_addr;
     83
     84	memset(&data_1_5, 0, sizeof(data_1_5));
     85
     86	switch (cmd) {
     87	case v7_CMD_ERASE_ALL:
     88		data_1_5.partition_id = CORE_CODE_PARTITION;
     89		data_1_5.command = CMD_V7_ERASE_AP;
     90		break;
     91	case v7_CMD_ERASE_UI_FIRMWARE:
     92		data_1_5.partition_id = CORE_CODE_PARTITION;
     93		data_1_5.command = CMD_V7_ERASE;
     94		break;
     95	case v7_CMD_ERASE_BL_CONFIG:
     96		data_1_5.partition_id = GLOBAL_PARAMETERS_PARTITION;
     97		data_1_5.command = CMD_V7_ERASE;
     98		break;
     99	case v7_CMD_ERASE_UI_CONFIG:
    100		data_1_5.partition_id = CORE_CONFIG_PARTITION;
    101		data_1_5.command = CMD_V7_ERASE;
    102		break;
    103	case v7_CMD_ERASE_DISP_CONFIG:
    104		data_1_5.partition_id = DISPLAY_CONFIG_PARTITION;
    105		data_1_5.command = CMD_V7_ERASE;
    106		break;
    107	case v7_CMD_ERASE_FLASH_CONFIG:
    108		data_1_5.partition_id = FLASH_CONFIG_PARTITION;
    109		data_1_5.command = CMD_V7_ERASE;
    110		break;
    111	case v7_CMD_ERASE_GUEST_CODE:
    112		data_1_5.partition_id = GUEST_CODE_PARTITION;
    113		data_1_5.command = CMD_V7_ERASE;
    114		break;
    115	case v7_CMD_ENABLE_FLASH_PROG:
    116		data_1_5.partition_id = BOOTLOADER_PARTITION;
    117		data_1_5.command = CMD_V7_ENTER_BL;
    118		break;
    119	}
    120
    121	data_1_5.payload[0] = f34->bootloader_id[0];
    122	data_1_5.payload[1] = f34->bootloader_id[1];
    123
    124	ret = rmi_write_block(f34->fn->rmi_dev,
    125			base + f34->v7.off.partition_id,
    126			&data_1_5, sizeof(data_1_5));
    127	if (ret < 0) {
    128		dev_err(&f34->fn->dev,
    129			"%s: Failed to write single transaction command\n",
    130			__func__);
    131		return ret;
    132	}
    133
    134	return 0;
    135}
    136
    137static int rmi_f34v7_write_command(struct f34_data *f34, u8 cmd)
    138{
    139	int ret;
    140	u8 base;
    141	u8 command;
    142
    143	base = f34->fn->fd.data_base_addr;
    144
    145	switch (cmd) {
    146	case v7_CMD_WRITE_FW:
    147	case v7_CMD_WRITE_CONFIG:
    148	case v7_CMD_WRITE_GUEST_CODE:
    149		command = CMD_V7_WRITE;
    150		break;
    151	case v7_CMD_READ_CONFIG:
    152		command = CMD_V7_READ;
    153		break;
    154	case v7_CMD_ERASE_ALL:
    155		command = CMD_V7_ERASE_AP;
    156		break;
    157	case v7_CMD_ERASE_UI_FIRMWARE:
    158	case v7_CMD_ERASE_BL_CONFIG:
    159	case v7_CMD_ERASE_UI_CONFIG:
    160	case v7_CMD_ERASE_DISP_CONFIG:
    161	case v7_CMD_ERASE_FLASH_CONFIG:
    162	case v7_CMD_ERASE_GUEST_CODE:
    163		command = CMD_V7_ERASE;
    164		break;
    165	case v7_CMD_ENABLE_FLASH_PROG:
    166		command = CMD_V7_ENTER_BL;
    167		break;
    168	default:
    169		dev_err(&f34->fn->dev, "%s: Invalid command 0x%02x\n",
    170			__func__, cmd);
    171		return -EINVAL;
    172	}
    173
    174	f34->v7.command = command;
    175
    176	switch (cmd) {
    177	case v7_CMD_ERASE_ALL:
    178	case v7_CMD_ERASE_UI_FIRMWARE:
    179	case v7_CMD_ERASE_BL_CONFIG:
    180	case v7_CMD_ERASE_UI_CONFIG:
    181	case v7_CMD_ERASE_DISP_CONFIG:
    182	case v7_CMD_ERASE_FLASH_CONFIG:
    183	case v7_CMD_ERASE_GUEST_CODE:
    184	case v7_CMD_ENABLE_FLASH_PROG:
    185		ret = rmi_f34v7_write_command_single_transaction(f34, cmd);
    186		if (ret < 0)
    187			return ret;
    188		else
    189			return 0;
    190	default:
    191		break;
    192	}
    193
    194	rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, "%s: writing cmd %02X\n",
    195		__func__, command);
    196
    197	ret = rmi_write_block(f34->fn->rmi_dev,
    198			base + f34->v7.off.flash_cmd,
    199			&command, sizeof(command));
    200	if (ret < 0) {
    201		dev_err(&f34->fn->dev, "%s: Failed to write flash command\n",
    202			__func__);
    203		return ret;
    204	}
    205
    206	return 0;
    207}
    208
    209static int rmi_f34v7_write_partition_id(struct f34_data *f34, u8 cmd)
    210{
    211	int ret;
    212	u8 base;
    213	u8 partition;
    214
    215	base = f34->fn->fd.data_base_addr;
    216
    217	switch (cmd) {
    218	case v7_CMD_WRITE_FW:
    219		partition = CORE_CODE_PARTITION;
    220		break;
    221	case v7_CMD_WRITE_CONFIG:
    222	case v7_CMD_READ_CONFIG:
    223		if (f34->v7.config_area == v7_UI_CONFIG_AREA)
    224			partition = CORE_CONFIG_PARTITION;
    225		else if (f34->v7.config_area == v7_DP_CONFIG_AREA)
    226			partition = DISPLAY_CONFIG_PARTITION;
    227		else if (f34->v7.config_area == v7_PM_CONFIG_AREA)
    228			partition = GUEST_SERIALIZATION_PARTITION;
    229		else if (f34->v7.config_area == v7_BL_CONFIG_AREA)
    230			partition = GLOBAL_PARAMETERS_PARTITION;
    231		else if (f34->v7.config_area == v7_FLASH_CONFIG_AREA)
    232			partition = FLASH_CONFIG_PARTITION;
    233		break;
    234	case v7_CMD_WRITE_GUEST_CODE:
    235		partition = GUEST_CODE_PARTITION;
    236		break;
    237	case v7_CMD_ERASE_ALL:
    238		partition = CORE_CODE_PARTITION;
    239		break;
    240	case v7_CMD_ERASE_BL_CONFIG:
    241		partition = GLOBAL_PARAMETERS_PARTITION;
    242		break;
    243	case v7_CMD_ERASE_UI_CONFIG:
    244		partition = CORE_CONFIG_PARTITION;
    245		break;
    246	case v7_CMD_ERASE_DISP_CONFIG:
    247		partition = DISPLAY_CONFIG_PARTITION;
    248		break;
    249	case v7_CMD_ERASE_FLASH_CONFIG:
    250		partition = FLASH_CONFIG_PARTITION;
    251		break;
    252	case v7_CMD_ERASE_GUEST_CODE:
    253		partition = GUEST_CODE_PARTITION;
    254		break;
    255	case v7_CMD_ENABLE_FLASH_PROG:
    256		partition = BOOTLOADER_PARTITION;
    257		break;
    258	default:
    259		dev_err(&f34->fn->dev, "%s: Invalid command 0x%02x\n",
    260			__func__, cmd);
    261		return -EINVAL;
    262	}
    263
    264	ret = rmi_write_block(f34->fn->rmi_dev,
    265			base + f34->v7.off.partition_id,
    266			&partition, sizeof(partition));
    267	if (ret < 0) {
    268		dev_err(&f34->fn->dev, "%s: Failed to write partition ID\n",
    269			__func__);
    270		return ret;
    271	}
    272
    273	return 0;
    274}
    275
    276static int rmi_f34v7_read_partition_table(struct f34_data *f34)
    277{
    278	int ret;
    279	unsigned long timeout;
    280	u8 base;
    281	__le16 length;
    282	u16 block_number = 0;
    283
    284	base = f34->fn->fd.data_base_addr;
    285
    286	f34->v7.config_area = v7_FLASH_CONFIG_AREA;
    287
    288	ret = rmi_f34v7_write_partition_id(f34, v7_CMD_READ_CONFIG);
    289	if (ret < 0)
    290		return ret;
    291
    292	ret = rmi_write_block(f34->fn->rmi_dev,
    293			base + f34->v7.off.block_number,
    294			&block_number, sizeof(block_number));
    295	if (ret < 0) {
    296		dev_err(&f34->fn->dev, "%s: Failed to write block number\n",
    297			__func__);
    298		return ret;
    299	}
    300
    301	put_unaligned_le16(f34->v7.flash_config_length, &length);
    302
    303	ret = rmi_write_block(f34->fn->rmi_dev,
    304			base + f34->v7.off.transfer_length,
    305			&length, sizeof(length));
    306	if (ret < 0) {
    307		dev_err(&f34->fn->dev, "%s: Failed to write transfer length\n",
    308			__func__);
    309		return ret;
    310	}
    311
    312	init_completion(&f34->v7.cmd_done);
    313
    314	ret = rmi_f34v7_write_command(f34, v7_CMD_READ_CONFIG);
    315	if (ret < 0) {
    316		dev_err(&f34->fn->dev, "%s: Failed to write command\n",
    317			__func__);
    318		return ret;
    319	}
    320
    321	timeout = msecs_to_jiffies(F34_WRITE_WAIT_MS);
    322	while (time_before(jiffies, timeout)) {
    323		usleep_range(5000, 6000);
    324		rmi_f34v7_read_flash_status(f34);
    325
    326		if (f34->v7.command == v7_CMD_IDLE &&
    327		    f34->v7.flash_status == 0x00) {
    328			break;
    329		}
    330	}
    331
    332	ret = rmi_read_block(f34->fn->rmi_dev,
    333			base + f34->v7.off.payload,
    334			f34->v7.read_config_buf,
    335			f34->v7.partition_table_bytes);
    336	if (ret < 0) {
    337		dev_err(&f34->fn->dev, "%s: Failed to read block data\n",
    338			__func__);
    339		return ret;
    340	}
    341
    342	return 0;
    343}
    344
    345static void rmi_f34v7_parse_partition_table(struct f34_data *f34,
    346					    const void *partition_table,
    347					    struct block_count *blkcount,
    348					    struct physical_address *phyaddr)
    349{
    350	int i;
    351	int index;
    352	u16 partition_length;
    353	u16 physical_address;
    354	const struct partition_table *ptable;
    355
    356	for (i = 0; i < f34->v7.partitions; i++) {
    357		index = i * 8 + 2;
    358		ptable = partition_table + index;
    359		partition_length = le16_to_cpu(ptable->partition_length);
    360		physical_address = le16_to_cpu(ptable->start_physical_address);
    361		rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
    362			"%s: Partition entry %d: %*ph\n",
    363			__func__, i, sizeof(struct partition_table), ptable);
    364		switch (ptable->partition_id & 0x1f) {
    365		case CORE_CODE_PARTITION:
    366			blkcount->ui_firmware = partition_length;
    367			phyaddr->ui_firmware = physical_address;
    368			rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
    369				"%s: Core code block count: %d\n",
    370				__func__, blkcount->ui_firmware);
    371			break;
    372		case CORE_CONFIG_PARTITION:
    373			blkcount->ui_config = partition_length;
    374			phyaddr->ui_config = physical_address;
    375			rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
    376				"%s: Core config block count: %d\n",
    377				__func__, blkcount->ui_config);
    378			break;
    379		case DISPLAY_CONFIG_PARTITION:
    380			blkcount->dp_config = partition_length;
    381			phyaddr->dp_config = physical_address;
    382			rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
    383				"%s: Display config block count: %d\n",
    384				__func__, blkcount->dp_config);
    385			break;
    386		case FLASH_CONFIG_PARTITION:
    387			blkcount->fl_config = partition_length;
    388			rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
    389				"%s: Flash config block count: %d\n",
    390				__func__, blkcount->fl_config);
    391			break;
    392		case GUEST_CODE_PARTITION:
    393			blkcount->guest_code = partition_length;
    394			phyaddr->guest_code = physical_address;
    395			rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
    396				"%s: Guest code block count: %d\n",
    397				__func__, blkcount->guest_code);
    398			break;
    399		case GUEST_SERIALIZATION_PARTITION:
    400			blkcount->pm_config = partition_length;
    401			rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
    402				"%s: Guest serialization block count: %d\n",
    403				__func__, blkcount->pm_config);
    404			break;
    405		case GLOBAL_PARAMETERS_PARTITION:
    406			blkcount->bl_config = partition_length;
    407			rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
    408				"%s: Global parameters block count: %d\n",
    409				__func__, blkcount->bl_config);
    410			break;
    411		case DEVICE_CONFIG_PARTITION:
    412			blkcount->lockdown = partition_length;
    413			rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
    414				"%s: Device config block count: %d\n",
    415				__func__, blkcount->lockdown);
    416			break;
    417		}
    418	}
    419}
    420
    421static int rmi_f34v7_read_queries_bl_version(struct f34_data *f34)
    422{
    423	int ret;
    424	u8 base;
    425	int offset;
    426	u8 query_0;
    427	struct f34v7_query_1_7 query_1_7;
    428
    429	base = f34->fn->fd.query_base_addr;
    430
    431	ret = rmi_read_block(f34->fn->rmi_dev,
    432			base,
    433			&query_0,
    434			sizeof(query_0));
    435	if (ret < 0) {
    436		dev_err(&f34->fn->dev,
    437			"%s: Failed to read query 0\n", __func__);
    438		return ret;
    439	}
    440
    441	offset = (query_0 & 0x7) + 1;
    442
    443	ret = rmi_read_block(f34->fn->rmi_dev,
    444			base + offset,
    445			&query_1_7,
    446			sizeof(query_1_7));
    447	if (ret < 0) {
    448		dev_err(&f34->fn->dev, "%s: Failed to read queries 1 to 7\n",
    449			__func__);
    450		return ret;
    451	}
    452
    453	f34->bootloader_id[0] = query_1_7.bl_minor_revision;
    454	f34->bootloader_id[1] = query_1_7.bl_major_revision;
    455
    456	rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, "Bootloader V%d.%d\n",
    457		f34->bootloader_id[1], f34->bootloader_id[0]);
    458
    459	return 0;
    460}
    461
    462static int rmi_f34v7_read_queries(struct f34_data *f34)
    463{
    464	int ret;
    465	int i;
    466	u8 base;
    467	int offset;
    468	u8 *ptable;
    469	u8 query_0;
    470	struct f34v7_query_1_7 query_1_7;
    471
    472	base = f34->fn->fd.query_base_addr;
    473
    474	ret = rmi_read_block(f34->fn->rmi_dev,
    475			base,
    476			&query_0,
    477			sizeof(query_0));
    478	if (ret < 0) {
    479		dev_err(&f34->fn->dev,
    480			"%s: Failed to read query 0\n", __func__);
    481		return ret;
    482	}
    483
    484	offset = (query_0 & 0x07) + 1;
    485
    486	ret = rmi_read_block(f34->fn->rmi_dev,
    487			base + offset,
    488			&query_1_7,
    489			sizeof(query_1_7));
    490	if (ret < 0) {
    491		dev_err(&f34->fn->dev, "%s: Failed to read queries 1 to 7\n",
    492			__func__);
    493		return ret;
    494	}
    495
    496	f34->bootloader_id[0] = query_1_7.bl_minor_revision;
    497	f34->bootloader_id[1] = query_1_7.bl_major_revision;
    498
    499	f34->v7.block_size = le16_to_cpu(query_1_7.block_size);
    500	f34->v7.flash_config_length =
    501			le16_to_cpu(query_1_7.flash_config_length);
    502	f34->v7.payload_length = le16_to_cpu(query_1_7.payload_length);
    503
    504	rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, "%s: f34->v7.block_size = %d\n",
    505		 __func__, f34->v7.block_size);
    506
    507	f34->v7.off.flash_status = V7_FLASH_STATUS_OFFSET;
    508	f34->v7.off.partition_id = V7_PARTITION_ID_OFFSET;
    509	f34->v7.off.block_number = V7_BLOCK_NUMBER_OFFSET;
    510	f34->v7.off.transfer_length = V7_TRANSFER_LENGTH_OFFSET;
    511	f34->v7.off.flash_cmd = V7_COMMAND_OFFSET;
    512	f34->v7.off.payload = V7_PAYLOAD_OFFSET;
    513
    514	f34->v7.has_display_cfg = query_1_7.partition_support[1] & HAS_DISP_CFG;
    515	f34->v7.has_guest_code =
    516			query_1_7.partition_support[1] & HAS_GUEST_CODE;
    517
    518	if (query_0 & HAS_CONFIG_ID) {
    519		u8 f34_ctrl[CONFIG_ID_SIZE];
    520
    521		ret = rmi_read_block(f34->fn->rmi_dev,
    522				f34->fn->fd.control_base_addr,
    523				f34_ctrl,
    524				sizeof(f34_ctrl));
    525		if (ret)
    526			return ret;
    527
    528		/* Eat leading zeros */
    529		for (i = 0; i < sizeof(f34_ctrl) - 1 && !f34_ctrl[i]; i++)
    530			/* Empty */;
    531
    532		snprintf(f34->configuration_id, sizeof(f34->configuration_id),
    533			 "%*phN", (int)sizeof(f34_ctrl) - i, f34_ctrl + i);
    534
    535		rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, "Configuration ID: %s\n",
    536			f34->configuration_id);
    537	}
    538
    539	f34->v7.partitions = 0;
    540	for (i = 0; i < sizeof(query_1_7.partition_support); i++)
    541		f34->v7.partitions += hweight8(query_1_7.partition_support[i]);
    542
    543	rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, "%s: Supported partitions: %*ph\n",
    544		__func__, sizeof(query_1_7.partition_support),
    545		query_1_7.partition_support);
    546
    547
    548	f34->v7.partition_table_bytes = f34->v7.partitions * 8 + 2;
    549
    550	f34->v7.read_config_buf = devm_kzalloc(&f34->fn->dev,
    551			f34->v7.partition_table_bytes,
    552			GFP_KERNEL);
    553	if (!f34->v7.read_config_buf) {
    554		f34->v7.read_config_buf_size = 0;
    555		return -ENOMEM;
    556	}
    557
    558	f34->v7.read_config_buf_size = f34->v7.partition_table_bytes;
    559	ptable = f34->v7.read_config_buf;
    560
    561	ret = rmi_f34v7_read_partition_table(f34);
    562	if (ret < 0) {
    563		dev_err(&f34->fn->dev, "%s: Failed to read partition table\n",
    564				__func__);
    565		return ret;
    566	}
    567
    568	rmi_f34v7_parse_partition_table(f34, ptable,
    569					&f34->v7.blkcount, &f34->v7.phyaddr);
    570
    571	return 0;
    572}
    573
    574static int rmi_f34v7_check_ui_firmware_size(struct f34_data *f34)
    575{
    576	u16 block_count;
    577
    578	block_count = f34->v7.img.ui_firmware.size / f34->v7.block_size;
    579	f34->update_size += block_count;
    580
    581	if (block_count != f34->v7.blkcount.ui_firmware) {
    582		dev_err(&f34->fn->dev,
    583			"UI firmware size mismatch: %d != %d\n",
    584			block_count, f34->v7.blkcount.ui_firmware);
    585		return -EINVAL;
    586	}
    587
    588	return 0;
    589}
    590
    591static int rmi_f34v7_check_ui_config_size(struct f34_data *f34)
    592{
    593	u16 block_count;
    594
    595	block_count = f34->v7.img.ui_config.size / f34->v7.block_size;
    596	f34->update_size += block_count;
    597
    598	if (block_count != f34->v7.blkcount.ui_config) {
    599		dev_err(&f34->fn->dev, "UI config size mismatch\n");
    600		return -EINVAL;
    601	}
    602
    603	return 0;
    604}
    605
    606static int rmi_f34v7_check_dp_config_size(struct f34_data *f34)
    607{
    608	u16 block_count;
    609
    610	block_count = f34->v7.img.dp_config.size / f34->v7.block_size;
    611	f34->update_size += block_count;
    612
    613	if (block_count != f34->v7.blkcount.dp_config) {
    614		dev_err(&f34->fn->dev, "Display config size mismatch\n");
    615		return -EINVAL;
    616	}
    617
    618	return 0;
    619}
    620
    621static int rmi_f34v7_check_guest_code_size(struct f34_data *f34)
    622{
    623	u16 block_count;
    624
    625	block_count = f34->v7.img.guest_code.size / f34->v7.block_size;
    626	f34->update_size += block_count;
    627
    628	if (block_count != f34->v7.blkcount.guest_code) {
    629		dev_err(&f34->fn->dev, "Guest code size mismatch\n");
    630		return -EINVAL;
    631	}
    632
    633	return 0;
    634}
    635
    636static int rmi_f34v7_check_bl_config_size(struct f34_data *f34)
    637{
    638	u16 block_count;
    639
    640	block_count = f34->v7.img.bl_config.size / f34->v7.block_size;
    641	f34->update_size += block_count;
    642
    643	if (block_count != f34->v7.blkcount.bl_config) {
    644		dev_err(&f34->fn->dev, "Bootloader config size mismatch\n");
    645		return -EINVAL;
    646	}
    647
    648	return 0;
    649}
    650
    651static int rmi_f34v7_erase_config(struct f34_data *f34)
    652{
    653	int ret;
    654
    655	dev_info(&f34->fn->dev, "Erasing config...\n");
    656
    657	init_completion(&f34->v7.cmd_done);
    658
    659	switch (f34->v7.config_area) {
    660	case v7_UI_CONFIG_AREA:
    661		ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_UI_CONFIG);
    662		if (ret < 0)
    663			return ret;
    664		break;
    665	case v7_DP_CONFIG_AREA:
    666		ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_DISP_CONFIG);
    667		if (ret < 0)
    668			return ret;
    669		break;
    670	case v7_BL_CONFIG_AREA:
    671		ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_BL_CONFIG);
    672		if (ret < 0)
    673			return ret;
    674		break;
    675	}
    676
    677	ret = rmi_f34v7_wait_for_idle(f34, F34_ERASE_WAIT_MS);
    678	if (ret < 0)
    679		return ret;
    680
    681	return 0;
    682}
    683
    684static int rmi_f34v7_erase_guest_code(struct f34_data *f34)
    685{
    686	int ret;
    687
    688	dev_info(&f34->fn->dev, "Erasing guest code...\n");
    689
    690	init_completion(&f34->v7.cmd_done);
    691
    692	ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_GUEST_CODE);
    693	if (ret < 0)
    694		return ret;
    695
    696	ret = rmi_f34v7_wait_for_idle(f34, F34_ERASE_WAIT_MS);
    697	if (ret < 0)
    698		return ret;
    699
    700	return 0;
    701}
    702
    703static int rmi_f34v7_erase_all(struct f34_data *f34)
    704{
    705	int ret;
    706
    707	dev_info(&f34->fn->dev, "Erasing firmware...\n");
    708
    709	init_completion(&f34->v7.cmd_done);
    710
    711	ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_UI_FIRMWARE);
    712	if (ret < 0)
    713		return ret;
    714
    715	ret = rmi_f34v7_wait_for_idle(f34, F34_ERASE_WAIT_MS);
    716	if (ret < 0)
    717		return ret;
    718
    719	f34->v7.config_area = v7_UI_CONFIG_AREA;
    720	ret = rmi_f34v7_erase_config(f34);
    721	if (ret < 0)
    722		return ret;
    723
    724	if (f34->v7.has_display_cfg) {
    725		f34->v7.config_area = v7_DP_CONFIG_AREA;
    726		ret = rmi_f34v7_erase_config(f34);
    727		if (ret < 0)
    728			return ret;
    729	}
    730
    731	if (f34->v7.new_partition_table && f34->v7.has_guest_code) {
    732		ret = rmi_f34v7_erase_guest_code(f34);
    733		if (ret < 0)
    734			return ret;
    735	}
    736
    737	return 0;
    738}
    739
    740static int rmi_f34v7_read_blocks(struct f34_data *f34,
    741				 u16 block_cnt, u8 command)
    742{
    743	int ret;
    744	u8 base;
    745	__le16 length;
    746	u16 transfer;
    747	u16 max_transfer;
    748	u16 remaining = block_cnt;
    749	u16 block_number = 0;
    750	u16 index = 0;
    751
    752	base = f34->fn->fd.data_base_addr;
    753
    754	ret = rmi_f34v7_write_partition_id(f34, command);
    755	if (ret < 0)
    756		return ret;
    757
    758	ret = rmi_write_block(f34->fn->rmi_dev,
    759			base + f34->v7.off.block_number,
    760			&block_number, sizeof(block_number));
    761	if (ret < 0) {
    762		dev_err(&f34->fn->dev, "%s: Failed to write block number\n",
    763			__func__);
    764		return ret;
    765	}
    766
    767	max_transfer = min(f34->v7.payload_length,
    768			   (u16)(PAGE_SIZE / f34->v7.block_size));
    769
    770	do {
    771		transfer = min(remaining, max_transfer);
    772		put_unaligned_le16(transfer, &length);
    773
    774		ret = rmi_write_block(f34->fn->rmi_dev,
    775				base + f34->v7.off.transfer_length,
    776				&length, sizeof(length));
    777		if (ret < 0) {
    778			dev_err(&f34->fn->dev,
    779				"%s: Write transfer length fail (%d remaining)\n",
    780				__func__, remaining);
    781			return ret;
    782		}
    783
    784		init_completion(&f34->v7.cmd_done);
    785
    786		ret = rmi_f34v7_write_command(f34, command);
    787		if (ret < 0)
    788			return ret;
    789
    790		ret = rmi_f34v7_wait_for_idle(f34, F34_ENABLE_WAIT_MS);
    791		if (ret < 0)
    792			return ret;
    793
    794		ret = rmi_read_block(f34->fn->rmi_dev,
    795				base + f34->v7.off.payload,
    796				&f34->v7.read_config_buf[index],
    797				transfer * f34->v7.block_size);
    798		if (ret < 0) {
    799			dev_err(&f34->fn->dev,
    800				"%s: Read block failed (%d blks remaining)\n",
    801				__func__, remaining);
    802			return ret;
    803		}
    804
    805		index += (transfer * f34->v7.block_size);
    806		remaining -= transfer;
    807	} while (remaining);
    808
    809	return 0;
    810}
    811
    812static int rmi_f34v7_write_f34v7_blocks(struct f34_data *f34,
    813					const void *block_ptr, u16 block_cnt,
    814					u8 command)
    815{
    816	int ret;
    817	u8 base;
    818	__le16 length;
    819	u16 transfer;
    820	u16 max_transfer;
    821	u16 remaining = block_cnt;
    822	u16 block_number = 0;
    823
    824	base = f34->fn->fd.data_base_addr;
    825
    826	ret = rmi_f34v7_write_partition_id(f34, command);
    827	if (ret < 0)
    828		return ret;
    829
    830	ret = rmi_write_block(f34->fn->rmi_dev,
    831			base + f34->v7.off.block_number,
    832			&block_number, sizeof(block_number));
    833	if (ret < 0) {
    834		dev_err(&f34->fn->dev, "%s: Failed to write block number\n",
    835			__func__);
    836		return ret;
    837	}
    838
    839	if (f34->v7.payload_length > (PAGE_SIZE / f34->v7.block_size))
    840		max_transfer = PAGE_SIZE / f34->v7.block_size;
    841	else
    842		max_transfer = f34->v7.payload_length;
    843
    844	do {
    845		transfer = min(remaining, max_transfer);
    846		put_unaligned_le16(transfer, &length);
    847
    848		init_completion(&f34->v7.cmd_done);
    849
    850		ret = rmi_write_block(f34->fn->rmi_dev,
    851				base + f34->v7.off.transfer_length,
    852				&length, sizeof(length));
    853		if (ret < 0) {
    854			dev_err(&f34->fn->dev,
    855				"%s: Write transfer length fail (%d remaining)\n",
    856				__func__, remaining);
    857			return ret;
    858		}
    859
    860		ret = rmi_f34v7_write_command(f34, command);
    861		if (ret < 0)
    862			return ret;
    863
    864		ret = rmi_write_block(f34->fn->rmi_dev,
    865				base + f34->v7.off.payload,
    866				block_ptr, transfer * f34->v7.block_size);
    867		if (ret < 0) {
    868			dev_err(&f34->fn->dev,
    869				"%s: Failed writing data (%d blks remaining)\n",
    870				__func__, remaining);
    871			return ret;
    872		}
    873
    874		ret = rmi_f34v7_wait_for_idle(f34, F34_ENABLE_WAIT_MS);
    875		if (ret < 0)
    876			return ret;
    877
    878		block_ptr += (transfer * f34->v7.block_size);
    879		remaining -= transfer;
    880		f34->update_progress += transfer;
    881		f34->update_status = (f34->update_progress * 100) /
    882				     f34->update_size;
    883	} while (remaining);
    884
    885	return 0;
    886}
    887
    888static int rmi_f34v7_write_config(struct f34_data *f34)
    889{
    890	return rmi_f34v7_write_f34v7_blocks(f34, f34->v7.config_data,
    891					    f34->v7.config_block_count,
    892					    v7_CMD_WRITE_CONFIG);
    893}
    894
    895static int rmi_f34v7_write_ui_config(struct f34_data *f34)
    896{
    897	f34->v7.config_area = v7_UI_CONFIG_AREA;
    898	f34->v7.config_data = f34->v7.img.ui_config.data;
    899	f34->v7.config_size = f34->v7.img.ui_config.size;
    900	f34->v7.config_block_count = f34->v7.config_size / f34->v7.block_size;
    901
    902	return rmi_f34v7_write_config(f34);
    903}
    904
    905static int rmi_f34v7_write_dp_config(struct f34_data *f34)
    906{
    907	f34->v7.config_area = v7_DP_CONFIG_AREA;
    908	f34->v7.config_data = f34->v7.img.dp_config.data;
    909	f34->v7.config_size = f34->v7.img.dp_config.size;
    910	f34->v7.config_block_count = f34->v7.config_size / f34->v7.block_size;
    911
    912	return rmi_f34v7_write_config(f34);
    913}
    914
    915static int rmi_f34v7_write_guest_code(struct f34_data *f34)
    916{
    917	return rmi_f34v7_write_f34v7_blocks(f34, f34->v7.img.guest_code.data,
    918					    f34->v7.img.guest_code.size /
    919							f34->v7.block_size,
    920					    v7_CMD_WRITE_GUEST_CODE);
    921}
    922
    923static int rmi_f34v7_write_flash_config(struct f34_data *f34)
    924{
    925	int ret;
    926
    927	f34->v7.config_area = v7_FLASH_CONFIG_AREA;
    928	f34->v7.config_data = f34->v7.img.fl_config.data;
    929	f34->v7.config_size = f34->v7.img.fl_config.size;
    930	f34->v7.config_block_count = f34->v7.config_size / f34->v7.block_size;
    931
    932	if (f34->v7.config_block_count != f34->v7.blkcount.fl_config) {
    933		dev_err(&f34->fn->dev, "%s: Flash config size mismatch\n",
    934			__func__);
    935		return -EINVAL;
    936	}
    937
    938	init_completion(&f34->v7.cmd_done);
    939
    940	ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_FLASH_CONFIG);
    941	if (ret < 0)
    942		return ret;
    943
    944	rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
    945		"%s: Erase flash config command written\n", __func__);
    946
    947	ret = rmi_f34v7_wait_for_idle(f34, F34_WRITE_WAIT_MS);
    948	if (ret < 0)
    949		return ret;
    950
    951	ret = rmi_f34v7_write_config(f34);
    952	if (ret < 0)
    953		return ret;
    954
    955	return 0;
    956}
    957
    958static int rmi_f34v7_write_partition_table(struct f34_data *f34)
    959{
    960	u16 block_count;
    961	int ret;
    962
    963	block_count = f34->v7.blkcount.bl_config;
    964	f34->v7.config_area = v7_BL_CONFIG_AREA;
    965	f34->v7.config_size = f34->v7.block_size * block_count;
    966	devm_kfree(&f34->fn->dev, f34->v7.read_config_buf);
    967	f34->v7.read_config_buf = devm_kzalloc(&f34->fn->dev,
    968					       f34->v7.config_size, GFP_KERNEL);
    969	if (!f34->v7.read_config_buf) {
    970		f34->v7.read_config_buf_size = 0;
    971		return -ENOMEM;
    972	}
    973
    974	f34->v7.read_config_buf_size = f34->v7.config_size;
    975
    976	ret = rmi_f34v7_read_blocks(f34, block_count, v7_CMD_READ_CONFIG);
    977	if (ret < 0)
    978		return ret;
    979
    980	ret = rmi_f34v7_erase_config(f34);
    981	if (ret < 0)
    982		return ret;
    983
    984	ret = rmi_f34v7_write_flash_config(f34);
    985	if (ret < 0)
    986		return ret;
    987
    988	f34->v7.config_area = v7_BL_CONFIG_AREA;
    989	f34->v7.config_data = f34->v7.read_config_buf;
    990	f34->v7.config_size = f34->v7.img.bl_config.size;
    991	f34->v7.config_block_count = f34->v7.config_size / f34->v7.block_size;
    992
    993	ret = rmi_f34v7_write_config(f34);
    994	if (ret < 0)
    995		return ret;
    996
    997	return 0;
    998}
    999
   1000static int rmi_f34v7_write_firmware(struct f34_data *f34)
   1001{
   1002	u16 blk_count;
   1003
   1004	blk_count = f34->v7.img.ui_firmware.size / f34->v7.block_size;
   1005
   1006	return rmi_f34v7_write_f34v7_blocks(f34, f34->v7.img.ui_firmware.data,
   1007					    blk_count, v7_CMD_WRITE_FW);
   1008}
   1009
   1010static void rmi_f34v7_compare_partition_tables(struct f34_data *f34)
   1011{
   1012	if (f34->v7.phyaddr.ui_firmware != f34->v7.img.phyaddr.ui_firmware) {
   1013		f34->v7.new_partition_table = true;
   1014		return;
   1015	}
   1016
   1017	if (f34->v7.phyaddr.ui_config != f34->v7.img.phyaddr.ui_config) {
   1018		f34->v7.new_partition_table = true;
   1019		return;
   1020	}
   1021
   1022	if (f34->v7.has_display_cfg &&
   1023	    f34->v7.phyaddr.dp_config != f34->v7.img.phyaddr.dp_config) {
   1024		f34->v7.new_partition_table = true;
   1025		return;
   1026	}
   1027
   1028	if (f34->v7.has_guest_code &&
   1029	    f34->v7.phyaddr.guest_code != f34->v7.img.phyaddr.guest_code) {
   1030		f34->v7.new_partition_table = true;
   1031		return;
   1032	}
   1033
   1034	f34->v7.new_partition_table = false;
   1035}
   1036
   1037static void rmi_f34v7_parse_img_header_10_bl_container(struct f34_data *f34,
   1038						       const void *image)
   1039{
   1040	int i;
   1041	int num_of_containers;
   1042	unsigned int addr;
   1043	unsigned int container_id;
   1044	unsigned int length;
   1045	const void *content;
   1046	const struct container_descriptor *descriptor;
   1047
   1048	num_of_containers = f34->v7.img.bootloader.size / 4 - 1;
   1049
   1050	for (i = 1; i <= num_of_containers; i++) {
   1051		addr = get_unaligned_le32(f34->v7.img.bootloader.data + i * 4);
   1052		descriptor = image + addr;
   1053		container_id = le16_to_cpu(descriptor->container_id);
   1054		content = image + le32_to_cpu(descriptor->content_address);
   1055		length = le32_to_cpu(descriptor->content_length);
   1056		switch (container_id) {
   1057		case BL_CONFIG_CONTAINER:
   1058		case GLOBAL_PARAMETERS_CONTAINER:
   1059			f34->v7.img.bl_config.data = content;
   1060			f34->v7.img.bl_config.size = length;
   1061			break;
   1062		case BL_LOCKDOWN_INFO_CONTAINER:
   1063		case DEVICE_CONFIG_CONTAINER:
   1064			f34->v7.img.lockdown.data = content;
   1065			f34->v7.img.lockdown.size = length;
   1066			break;
   1067		default:
   1068			break;
   1069		}
   1070	}
   1071}
   1072
   1073static void rmi_f34v7_parse_image_header_10(struct f34_data *f34)
   1074{
   1075	unsigned int i;
   1076	unsigned int num_of_containers;
   1077	unsigned int addr;
   1078	unsigned int offset;
   1079	unsigned int container_id;
   1080	unsigned int length;
   1081	const void *image = f34->v7.image;
   1082	const u8 *content;
   1083	const struct container_descriptor *descriptor;
   1084	const struct image_header_10 *header = image;
   1085
   1086	f34->v7.img.checksum = le32_to_cpu(header->checksum);
   1087
   1088	rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, "%s: f34->v7.img.checksum=%X\n",
   1089		__func__, f34->v7.img.checksum);
   1090
   1091	/* address of top level container */
   1092	offset = le32_to_cpu(header->top_level_container_start_addr);
   1093	descriptor = image + offset;
   1094
   1095	/* address of top level container content */
   1096	offset = le32_to_cpu(descriptor->content_address);
   1097	num_of_containers = le32_to_cpu(descriptor->content_length) / 4;
   1098
   1099	for (i = 0; i < num_of_containers; i++) {
   1100		addr = get_unaligned_le32(image + offset);
   1101		offset += 4;
   1102		descriptor = image + addr;
   1103		container_id = le16_to_cpu(descriptor->container_id);
   1104		content = image + le32_to_cpu(descriptor->content_address);
   1105		length = le32_to_cpu(descriptor->content_length);
   1106
   1107		rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
   1108			"%s: container_id=%d, length=%d\n", __func__,
   1109			container_id, length);
   1110
   1111		switch (container_id) {
   1112		case UI_CONTAINER:
   1113		case CORE_CODE_CONTAINER:
   1114			f34->v7.img.ui_firmware.data = content;
   1115			f34->v7.img.ui_firmware.size = length;
   1116			break;
   1117		case UI_CONFIG_CONTAINER:
   1118		case CORE_CONFIG_CONTAINER:
   1119			f34->v7.img.ui_config.data = content;
   1120			f34->v7.img.ui_config.size = length;
   1121			break;
   1122		case BL_CONTAINER:
   1123			f34->v7.img.bl_version = *content;
   1124			f34->v7.img.bootloader.data = content;
   1125			f34->v7.img.bootloader.size = length;
   1126			rmi_f34v7_parse_img_header_10_bl_container(f34, image);
   1127			break;
   1128		case GUEST_CODE_CONTAINER:
   1129			f34->v7.img.contains_guest_code = true;
   1130			f34->v7.img.guest_code.data = content;
   1131			f34->v7.img.guest_code.size = length;
   1132			break;
   1133		case DISPLAY_CONFIG_CONTAINER:
   1134			f34->v7.img.contains_display_cfg = true;
   1135			f34->v7.img.dp_config.data = content;
   1136			f34->v7.img.dp_config.size = length;
   1137			break;
   1138		case FLASH_CONFIG_CONTAINER:
   1139			f34->v7.img.contains_flash_config = true;
   1140			f34->v7.img.fl_config.data = content;
   1141			f34->v7.img.fl_config.size = length;
   1142			break;
   1143		case GENERAL_INFORMATION_CONTAINER:
   1144			f34->v7.img.contains_firmware_id = true;
   1145			f34->v7.img.firmware_id =
   1146				get_unaligned_le32(content + 4);
   1147			break;
   1148		default:
   1149			break;
   1150		}
   1151	}
   1152}
   1153
   1154static int rmi_f34v7_parse_image_info(struct f34_data *f34)
   1155{
   1156	const struct image_header_10 *header = f34->v7.image;
   1157
   1158	memset(&f34->v7.img, 0x00, sizeof(f34->v7.img));
   1159
   1160	rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
   1161		"%s: header->major_header_version = %d\n",
   1162		__func__, header->major_header_version);
   1163
   1164	switch (header->major_header_version) {
   1165	case IMAGE_HEADER_VERSION_10:
   1166		rmi_f34v7_parse_image_header_10(f34);
   1167		break;
   1168	default:
   1169		dev_err(&f34->fn->dev, "Unsupported image file format %02X\n",
   1170			header->major_header_version);
   1171		return -EINVAL;
   1172	}
   1173
   1174	if (!f34->v7.img.contains_flash_config) {
   1175		dev_err(&f34->fn->dev, "%s: No flash config in fw image\n",
   1176			__func__);
   1177		return -EINVAL;
   1178	}
   1179
   1180	rmi_f34v7_parse_partition_table(f34, f34->v7.img.fl_config.data,
   1181			&f34->v7.img.blkcount, &f34->v7.img.phyaddr);
   1182
   1183	rmi_f34v7_compare_partition_tables(f34);
   1184
   1185	return 0;
   1186}
   1187
   1188int rmi_f34v7_do_reflash(struct f34_data *f34, const struct firmware *fw)
   1189{
   1190	int ret;
   1191
   1192	f34->fn->rmi_dev->driver->set_irq_bits(f34->fn->rmi_dev,
   1193					       f34->fn->irq_mask);
   1194
   1195	rmi_f34v7_read_queries_bl_version(f34);
   1196
   1197	f34->v7.image = fw->data;
   1198	f34->update_progress = 0;
   1199	f34->update_size = 0;
   1200
   1201	ret = rmi_f34v7_parse_image_info(f34);
   1202	if (ret < 0)
   1203		goto fail;
   1204
   1205	if (!f34->v7.new_partition_table) {
   1206		ret = rmi_f34v7_check_ui_firmware_size(f34);
   1207		if (ret < 0)
   1208			goto fail;
   1209
   1210		ret = rmi_f34v7_check_ui_config_size(f34);
   1211		if (ret < 0)
   1212			goto fail;
   1213
   1214		if (f34->v7.has_display_cfg &&
   1215		    f34->v7.img.contains_display_cfg) {
   1216			ret = rmi_f34v7_check_dp_config_size(f34);
   1217			if (ret < 0)
   1218				goto fail;
   1219		}
   1220
   1221		if (f34->v7.has_guest_code && f34->v7.img.contains_guest_code) {
   1222			ret = rmi_f34v7_check_guest_code_size(f34);
   1223			if (ret < 0)
   1224				goto fail;
   1225		}
   1226	} else {
   1227		ret = rmi_f34v7_check_bl_config_size(f34);
   1228		if (ret < 0)
   1229			goto fail;
   1230	}
   1231
   1232	ret = rmi_f34v7_erase_all(f34);
   1233	if (ret < 0)
   1234		goto fail;
   1235
   1236	if (f34->v7.new_partition_table) {
   1237		ret = rmi_f34v7_write_partition_table(f34);
   1238		if (ret < 0)
   1239			goto fail;
   1240		dev_info(&f34->fn->dev, "%s: Partition table programmed\n",
   1241			 __func__);
   1242	}
   1243
   1244	dev_info(&f34->fn->dev, "Writing firmware (%d bytes)...\n",
   1245		 f34->v7.img.ui_firmware.size);
   1246
   1247	ret = rmi_f34v7_write_firmware(f34);
   1248	if (ret < 0)
   1249		goto fail;
   1250
   1251	dev_info(&f34->fn->dev, "Writing config (%d bytes)...\n",
   1252		 f34->v7.img.ui_config.size);
   1253
   1254	f34->v7.config_area = v7_UI_CONFIG_AREA;
   1255	ret = rmi_f34v7_write_ui_config(f34);
   1256	if (ret < 0)
   1257		goto fail;
   1258
   1259	if (f34->v7.has_display_cfg && f34->v7.img.contains_display_cfg) {
   1260		dev_info(&f34->fn->dev, "Writing display config...\n");
   1261
   1262		ret = rmi_f34v7_write_dp_config(f34);
   1263		if (ret < 0)
   1264			goto fail;
   1265	}
   1266
   1267	if (f34->v7.new_partition_table) {
   1268		if (f34->v7.has_guest_code && f34->v7.img.contains_guest_code) {
   1269			dev_info(&f34->fn->dev, "Writing guest code...\n");
   1270
   1271			ret = rmi_f34v7_write_guest_code(f34);
   1272			if (ret < 0)
   1273				goto fail;
   1274		}
   1275	}
   1276
   1277fail:
   1278	return ret;
   1279}
   1280
   1281static int rmi_f34v7_enter_flash_prog(struct f34_data *f34)
   1282{
   1283	int ret;
   1284
   1285	f34->fn->rmi_dev->driver->set_irq_bits(f34->fn->rmi_dev, f34->fn->irq_mask);
   1286
   1287	ret = rmi_f34v7_read_flash_status(f34);
   1288	if (ret < 0)
   1289		return ret;
   1290
   1291	if (f34->v7.in_bl_mode)
   1292		return 0;
   1293
   1294	init_completion(&f34->v7.cmd_done);
   1295
   1296	ret = rmi_f34v7_write_command(f34, v7_CMD_ENABLE_FLASH_PROG);
   1297	if (ret < 0)
   1298		return ret;
   1299
   1300	ret = rmi_f34v7_wait_for_idle(f34, F34_ENABLE_WAIT_MS);
   1301	if (ret < 0)
   1302		return ret;
   1303
   1304	return 0;
   1305}
   1306
   1307int rmi_f34v7_start_reflash(struct f34_data *f34, const struct firmware *fw)
   1308{
   1309	int ret = 0;
   1310
   1311	f34->fn->rmi_dev->driver->set_irq_bits(f34->fn->rmi_dev, f34->fn->irq_mask);
   1312
   1313	f34->v7.config_area = v7_UI_CONFIG_AREA;
   1314	f34->v7.image = fw->data;
   1315
   1316	ret = rmi_f34v7_parse_image_info(f34);
   1317	if (ret < 0)
   1318		goto exit;
   1319
   1320	if (!f34->v7.force_update && f34->v7.new_partition_table) {
   1321		dev_err(&f34->fn->dev, "%s: Partition table mismatch\n",
   1322				__func__);
   1323		ret = -EINVAL;
   1324		goto exit;
   1325	}
   1326
   1327	dev_info(&f34->fn->dev, "Firmware image OK\n");
   1328
   1329	ret = rmi_f34v7_read_flash_status(f34);
   1330	if (ret < 0)
   1331		goto exit;
   1332
   1333	if (f34->v7.in_bl_mode) {
   1334		dev_info(&f34->fn->dev, "%s: Device in bootloader mode\n",
   1335				__func__);
   1336	}
   1337
   1338	rmi_f34v7_enter_flash_prog(f34);
   1339
   1340	return 0;
   1341
   1342exit:
   1343	return ret;
   1344}
   1345
   1346int rmi_f34v7_probe(struct f34_data *f34)
   1347{
   1348	int ret;
   1349
   1350	/* Read bootloader version */
   1351	ret = rmi_read_block(f34->fn->rmi_dev,
   1352			f34->fn->fd.query_base_addr + V7_BOOTLOADER_ID_OFFSET,
   1353			f34->bootloader_id,
   1354			sizeof(f34->bootloader_id));
   1355	if (ret < 0) {
   1356		dev_err(&f34->fn->dev, "%s: Failed to read bootloader ID\n",
   1357			__func__);
   1358		return ret;
   1359	}
   1360
   1361	if (f34->bootloader_id[1] == '5') {
   1362		f34->bl_version = 5;
   1363	} else if (f34->bootloader_id[1] == '6') {
   1364		f34->bl_version = 6;
   1365	} else if (f34->bootloader_id[1] == 7) {
   1366		f34->bl_version = 7;
   1367	} else if (f34->bootloader_id[1] == 8) {
   1368		f34->bl_version = 8;
   1369	} else {
   1370		dev_err(&f34->fn->dev,
   1371			"%s: Unrecognized bootloader version: %d (%c) %d (%c)\n",
   1372			__func__,
   1373			f34->bootloader_id[0], f34->bootloader_id[0],
   1374			f34->bootloader_id[1], f34->bootloader_id[1]);
   1375		return -EINVAL;
   1376	}
   1377
   1378	memset(&f34->v7.blkcount, 0x00, sizeof(f34->v7.blkcount));
   1379	memset(&f34->v7.phyaddr, 0x00, sizeof(f34->v7.phyaddr));
   1380
   1381	init_completion(&f34->v7.cmd_done);
   1382
   1383	ret = rmi_f34v7_read_queries(f34);
   1384	if (ret < 0)
   1385		return ret;
   1386
   1387	f34->v7.force_update = true;
   1388	return 0;
   1389}