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