1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Copyright (c) 2007-2016, Synaptics Incorporated 4*4882a593Smuzhiyun * Copyright (C) 2016 Zodiac Inflight Innovations 5*4882a593Smuzhiyun */ 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun #ifndef _RMI_F34_H 8*4882a593Smuzhiyun #define _RMI_F34_H 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun /* F34 image file offsets. */ 11*4882a593Smuzhiyun #define F34_FW_IMAGE_OFFSET 0x100 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun /* F34 register offsets. */ 14*4882a593Smuzhiyun #define F34_BLOCK_DATA_OFFSET 2 15*4882a593Smuzhiyun 16*4882a593Smuzhiyun /* F34 commands */ 17*4882a593Smuzhiyun #define F34_WRITE_FW_BLOCK 0x2 18*4882a593Smuzhiyun #define F34_ERASE_ALL 0x3 19*4882a593Smuzhiyun #define F34_READ_CONFIG_BLOCK 0x5 20*4882a593Smuzhiyun #define F34_WRITE_CONFIG_BLOCK 0x6 21*4882a593Smuzhiyun #define F34_ERASE_CONFIG 0x7 22*4882a593Smuzhiyun #define F34_ENABLE_FLASH_PROG 0xf 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun #define F34_STATUS_IN_PROGRESS 0xff 25*4882a593Smuzhiyun #define F34_STATUS_IDLE 0x80 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun #define F34_IDLE_WAIT_MS 500 28*4882a593Smuzhiyun #define F34_ENABLE_WAIT_MS 300 29*4882a593Smuzhiyun #define F34_ERASE_WAIT_MS 5000 30*4882a593Smuzhiyun #define F34_WRITE_WAIT_MS 3000 31*4882a593Smuzhiyun 32*4882a593Smuzhiyun #define F34_BOOTLOADER_ID_LEN 2 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun /* F34 V7 defines */ 35*4882a593Smuzhiyun #define V7_FLASH_STATUS_OFFSET 0 36*4882a593Smuzhiyun #define V7_PARTITION_ID_OFFSET 1 37*4882a593Smuzhiyun #define V7_BLOCK_NUMBER_OFFSET 2 38*4882a593Smuzhiyun #define V7_TRANSFER_LENGTH_OFFSET 3 39*4882a593Smuzhiyun #define V7_COMMAND_OFFSET 4 40*4882a593Smuzhiyun #define V7_PAYLOAD_OFFSET 5 41*4882a593Smuzhiyun #define V7_BOOTLOADER_ID_OFFSET 1 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun #define IMAGE_HEADER_VERSION_10 0x10 44*4882a593Smuzhiyun 45*4882a593Smuzhiyun #define CONFIG_ID_SIZE 32 46*4882a593Smuzhiyun #define PRODUCT_ID_SIZE 10 47*4882a593Smuzhiyun 48*4882a593Smuzhiyun 49*4882a593Smuzhiyun #define HAS_BSR BIT(5) 50*4882a593Smuzhiyun #define HAS_CONFIG_ID BIT(3) 51*4882a593Smuzhiyun #define HAS_GUEST_CODE BIT(6) 52*4882a593Smuzhiyun #define HAS_DISP_CFG BIT(5) 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun /* F34 V7 commands */ 55*4882a593Smuzhiyun #define CMD_V7_IDLE 0 56*4882a593Smuzhiyun #define CMD_V7_ENTER_BL 1 57*4882a593Smuzhiyun #define CMD_V7_READ 2 58*4882a593Smuzhiyun #define CMD_V7_WRITE 3 59*4882a593Smuzhiyun #define CMD_V7_ERASE 4 60*4882a593Smuzhiyun #define CMD_V7_ERASE_AP 5 61*4882a593Smuzhiyun #define CMD_V7_SENSOR_ID 6 62*4882a593Smuzhiyun 63*4882a593Smuzhiyun #define v7_CMD_IDLE 0 64*4882a593Smuzhiyun #define v7_CMD_WRITE_FW 1 65*4882a593Smuzhiyun #define v7_CMD_WRITE_CONFIG 2 66*4882a593Smuzhiyun #define v7_CMD_WRITE_LOCKDOWN 3 67*4882a593Smuzhiyun #define v7_CMD_WRITE_GUEST_CODE 4 68*4882a593Smuzhiyun #define v7_CMD_READ_CONFIG 5 69*4882a593Smuzhiyun #define v7_CMD_ERASE_ALL 6 70*4882a593Smuzhiyun #define v7_CMD_ERASE_UI_FIRMWARE 7 71*4882a593Smuzhiyun #define v7_CMD_ERASE_UI_CONFIG 8 72*4882a593Smuzhiyun #define v7_CMD_ERASE_BL_CONFIG 9 73*4882a593Smuzhiyun #define v7_CMD_ERASE_DISP_CONFIG 10 74*4882a593Smuzhiyun #define v7_CMD_ERASE_FLASH_CONFIG 11 75*4882a593Smuzhiyun #define v7_CMD_ERASE_GUEST_CODE 12 76*4882a593Smuzhiyun #define v7_CMD_ENABLE_FLASH_PROG 13 77*4882a593Smuzhiyun 78*4882a593Smuzhiyun #define v7_UI_CONFIG_AREA 0 79*4882a593Smuzhiyun #define v7_PM_CONFIG_AREA 1 80*4882a593Smuzhiyun #define v7_BL_CONFIG_AREA 2 81*4882a593Smuzhiyun #define v7_DP_CONFIG_AREA 3 82*4882a593Smuzhiyun #define v7_FLASH_CONFIG_AREA 4 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun /* F34 V7 partition IDs */ 85*4882a593Smuzhiyun #define BOOTLOADER_PARTITION 1 86*4882a593Smuzhiyun #define DEVICE_CONFIG_PARTITION 2 87*4882a593Smuzhiyun #define FLASH_CONFIG_PARTITION 3 88*4882a593Smuzhiyun #define MANUFACTURING_BLOCK_PARTITION 4 89*4882a593Smuzhiyun #define GUEST_SERIALIZATION_PARTITION 5 90*4882a593Smuzhiyun #define GLOBAL_PARAMETERS_PARTITION 6 91*4882a593Smuzhiyun #define CORE_CODE_PARTITION 7 92*4882a593Smuzhiyun #define CORE_CONFIG_PARTITION 8 93*4882a593Smuzhiyun #define GUEST_CODE_PARTITION 9 94*4882a593Smuzhiyun #define DISPLAY_CONFIG_PARTITION 10 95*4882a593Smuzhiyun 96*4882a593Smuzhiyun /* F34 V7 container IDs */ 97*4882a593Smuzhiyun #define TOP_LEVEL_CONTAINER 0 98*4882a593Smuzhiyun #define UI_CONTAINER 1 99*4882a593Smuzhiyun #define UI_CONFIG_CONTAINER 2 100*4882a593Smuzhiyun #define BL_CONTAINER 3 101*4882a593Smuzhiyun #define BL_IMAGE_CONTAINER 4 102*4882a593Smuzhiyun #define BL_CONFIG_CONTAINER 5 103*4882a593Smuzhiyun #define BL_LOCKDOWN_INFO_CONTAINER 6 104*4882a593Smuzhiyun #define PERMANENT_CONFIG_CONTAINER 7 105*4882a593Smuzhiyun #define GUEST_CODE_CONTAINER 8 106*4882a593Smuzhiyun #define BL_PROTOCOL_DESCRIPTOR_CONTAINER 9 107*4882a593Smuzhiyun #define UI_PROTOCOL_DESCRIPTOR_CONTAINER 10 108*4882a593Smuzhiyun #define RMI_SELF_DISCOVERY_CONTAINER 11 109*4882a593Smuzhiyun #define RMI_PAGE_CONTENT_CONTAINER 12 110*4882a593Smuzhiyun #define GENERAL_INFORMATION_CONTAINER 13 111*4882a593Smuzhiyun #define DEVICE_CONFIG_CONTAINER 14 112*4882a593Smuzhiyun #define FLASH_CONFIG_CONTAINER 15 113*4882a593Smuzhiyun #define GUEST_SERIALIZATION_CONTAINER 16 114*4882a593Smuzhiyun #define GLOBAL_PARAMETERS_CONTAINER 17 115*4882a593Smuzhiyun #define CORE_CODE_CONTAINER 18 116*4882a593Smuzhiyun #define CORE_CONFIG_CONTAINER 19 117*4882a593Smuzhiyun #define DISPLAY_CONFIG_CONTAINER 20 118*4882a593Smuzhiyun 119*4882a593Smuzhiyun struct f34v7_query_1_7 { 120*4882a593Smuzhiyun u8 bl_minor_revision; /* query 1 */ 121*4882a593Smuzhiyun u8 bl_major_revision; 122*4882a593Smuzhiyun __le32 bl_fw_id; /* query 2 */ 123*4882a593Smuzhiyun u8 minimum_write_size; /* query 3 */ 124*4882a593Smuzhiyun __le16 block_size; 125*4882a593Smuzhiyun __le16 flash_page_size; 126*4882a593Smuzhiyun __le16 adjustable_partition_area_size; /* query 4 */ 127*4882a593Smuzhiyun __le16 flash_config_length; /* query 5 */ 128*4882a593Smuzhiyun __le16 payload_length; /* query 6 */ 129*4882a593Smuzhiyun u8 partition_support[4]; /* query 7 */ 130*4882a593Smuzhiyun } __packed; 131*4882a593Smuzhiyun 132*4882a593Smuzhiyun struct f34v7_data_1_5 { 133*4882a593Smuzhiyun u8 partition_id; 134*4882a593Smuzhiyun __le16 block_offset; 135*4882a593Smuzhiyun __le16 transfer_length; 136*4882a593Smuzhiyun u8 command; 137*4882a593Smuzhiyun u8 payload[2]; 138*4882a593Smuzhiyun } __packed; 139*4882a593Smuzhiyun 140*4882a593Smuzhiyun struct block_data { 141*4882a593Smuzhiyun const void *data; 142*4882a593Smuzhiyun int size; 143*4882a593Smuzhiyun }; 144*4882a593Smuzhiyun 145*4882a593Smuzhiyun struct partition_table { 146*4882a593Smuzhiyun u8 partition_id; 147*4882a593Smuzhiyun u8 byte_1_reserved; 148*4882a593Smuzhiyun __le16 partition_length; 149*4882a593Smuzhiyun __le16 start_physical_address; 150*4882a593Smuzhiyun __le16 partition_properties; 151*4882a593Smuzhiyun } __packed; 152*4882a593Smuzhiyun 153*4882a593Smuzhiyun struct physical_address { 154*4882a593Smuzhiyun u16 ui_firmware; 155*4882a593Smuzhiyun u16 ui_config; 156*4882a593Smuzhiyun u16 dp_config; 157*4882a593Smuzhiyun u16 guest_code; 158*4882a593Smuzhiyun }; 159*4882a593Smuzhiyun 160*4882a593Smuzhiyun struct container_descriptor { 161*4882a593Smuzhiyun __le32 content_checksum; 162*4882a593Smuzhiyun __le16 container_id; 163*4882a593Smuzhiyun u8 minor_version; 164*4882a593Smuzhiyun u8 major_version; 165*4882a593Smuzhiyun u8 reserved_08; 166*4882a593Smuzhiyun u8 reserved_09; 167*4882a593Smuzhiyun u8 reserved_0a; 168*4882a593Smuzhiyun u8 reserved_0b; 169*4882a593Smuzhiyun u8 container_option_flags[4]; 170*4882a593Smuzhiyun __le32 content_options_length; 171*4882a593Smuzhiyun __le32 content_options_address; 172*4882a593Smuzhiyun __le32 content_length; 173*4882a593Smuzhiyun __le32 content_address; 174*4882a593Smuzhiyun } __packed; 175*4882a593Smuzhiyun 176*4882a593Smuzhiyun struct block_count { 177*4882a593Smuzhiyun u16 ui_firmware; 178*4882a593Smuzhiyun u16 ui_config; 179*4882a593Smuzhiyun u16 dp_config; 180*4882a593Smuzhiyun u16 fl_config; 181*4882a593Smuzhiyun u16 pm_config; 182*4882a593Smuzhiyun u16 bl_config; 183*4882a593Smuzhiyun u16 lockdown; 184*4882a593Smuzhiyun u16 guest_code; 185*4882a593Smuzhiyun }; 186*4882a593Smuzhiyun 187*4882a593Smuzhiyun struct image_header_10 { 188*4882a593Smuzhiyun __le32 checksum; 189*4882a593Smuzhiyun u8 reserved_04; 190*4882a593Smuzhiyun u8 reserved_05; 191*4882a593Smuzhiyun u8 minor_header_version; 192*4882a593Smuzhiyun u8 major_header_version; 193*4882a593Smuzhiyun u8 reserved_08; 194*4882a593Smuzhiyun u8 reserved_09; 195*4882a593Smuzhiyun u8 reserved_0a; 196*4882a593Smuzhiyun u8 reserved_0b; 197*4882a593Smuzhiyun __le32 top_level_container_start_addr; 198*4882a593Smuzhiyun }; 199*4882a593Smuzhiyun 200*4882a593Smuzhiyun struct image_metadata { 201*4882a593Smuzhiyun bool contains_firmware_id; 202*4882a593Smuzhiyun bool contains_bootloader; 203*4882a593Smuzhiyun bool contains_display_cfg; 204*4882a593Smuzhiyun bool contains_guest_code; 205*4882a593Smuzhiyun bool contains_flash_config; 206*4882a593Smuzhiyun unsigned int firmware_id; 207*4882a593Smuzhiyun unsigned int checksum; 208*4882a593Smuzhiyun unsigned int bootloader_size; 209*4882a593Smuzhiyun unsigned int display_cfg_offset; 210*4882a593Smuzhiyun unsigned char bl_version; 211*4882a593Smuzhiyun unsigned char product_id[PRODUCT_ID_SIZE + 1]; 212*4882a593Smuzhiyun unsigned char cstmr_product_id[PRODUCT_ID_SIZE + 1]; 213*4882a593Smuzhiyun struct block_data bootloader; 214*4882a593Smuzhiyun struct block_data ui_firmware; 215*4882a593Smuzhiyun struct block_data ui_config; 216*4882a593Smuzhiyun struct block_data dp_config; 217*4882a593Smuzhiyun struct block_data fl_config; 218*4882a593Smuzhiyun struct block_data bl_config; 219*4882a593Smuzhiyun struct block_data guest_code; 220*4882a593Smuzhiyun struct block_data lockdown; 221*4882a593Smuzhiyun struct block_count blkcount; 222*4882a593Smuzhiyun struct physical_address phyaddr; 223*4882a593Smuzhiyun }; 224*4882a593Smuzhiyun 225*4882a593Smuzhiyun struct register_offset { 226*4882a593Smuzhiyun u8 properties; 227*4882a593Smuzhiyun u8 properties_2; 228*4882a593Smuzhiyun u8 block_size; 229*4882a593Smuzhiyun u8 block_count; 230*4882a593Smuzhiyun u8 gc_block_count; 231*4882a593Smuzhiyun u8 flash_status; 232*4882a593Smuzhiyun u8 partition_id; 233*4882a593Smuzhiyun u8 block_number; 234*4882a593Smuzhiyun u8 transfer_length; 235*4882a593Smuzhiyun u8 flash_cmd; 236*4882a593Smuzhiyun u8 payload; 237*4882a593Smuzhiyun }; 238*4882a593Smuzhiyun 239*4882a593Smuzhiyun struct rmi_f34_firmware { 240*4882a593Smuzhiyun __le32 checksum; 241*4882a593Smuzhiyun u8 pad1[3]; 242*4882a593Smuzhiyun u8 bootloader_version; 243*4882a593Smuzhiyun __le32 image_size; 244*4882a593Smuzhiyun __le32 config_size; 245*4882a593Smuzhiyun u8 product_id[10]; 246*4882a593Smuzhiyun u8 product_info[2]; 247*4882a593Smuzhiyun u8 pad2[228]; 248*4882a593Smuzhiyun u8 data[]; 249*4882a593Smuzhiyun }; 250*4882a593Smuzhiyun 251*4882a593Smuzhiyun struct f34v5_data { 252*4882a593Smuzhiyun u16 block_size; 253*4882a593Smuzhiyun u16 fw_blocks; 254*4882a593Smuzhiyun u16 config_blocks; 255*4882a593Smuzhiyun u16 ctrl_address; 256*4882a593Smuzhiyun u8 status; 257*4882a593Smuzhiyun 258*4882a593Smuzhiyun struct completion cmd_done; 259*4882a593Smuzhiyun struct mutex flash_mutex; 260*4882a593Smuzhiyun }; 261*4882a593Smuzhiyun 262*4882a593Smuzhiyun struct f34v7_data { 263*4882a593Smuzhiyun bool has_display_cfg; 264*4882a593Smuzhiyun bool has_guest_code; 265*4882a593Smuzhiyun bool force_update; 266*4882a593Smuzhiyun bool in_bl_mode; 267*4882a593Smuzhiyun u8 *read_config_buf; 268*4882a593Smuzhiyun size_t read_config_buf_size; 269*4882a593Smuzhiyun u8 command; 270*4882a593Smuzhiyun u8 flash_status; 271*4882a593Smuzhiyun u16 block_size; 272*4882a593Smuzhiyun u16 config_block_count; 273*4882a593Smuzhiyun u16 config_size; 274*4882a593Smuzhiyun u16 config_area; 275*4882a593Smuzhiyun u16 flash_config_length; 276*4882a593Smuzhiyun u16 payload_length; 277*4882a593Smuzhiyun u8 partitions; 278*4882a593Smuzhiyun u16 partition_table_bytes; 279*4882a593Smuzhiyun bool new_partition_table; 280*4882a593Smuzhiyun 281*4882a593Smuzhiyun struct register_offset off; 282*4882a593Smuzhiyun struct block_count blkcount; 283*4882a593Smuzhiyun struct physical_address phyaddr; 284*4882a593Smuzhiyun struct image_metadata img; 285*4882a593Smuzhiyun 286*4882a593Smuzhiyun const void *config_data; 287*4882a593Smuzhiyun const void *image; 288*4882a593Smuzhiyun struct completion cmd_done; 289*4882a593Smuzhiyun }; 290*4882a593Smuzhiyun 291*4882a593Smuzhiyun struct f34_data { 292*4882a593Smuzhiyun struct rmi_function *fn; 293*4882a593Smuzhiyun 294*4882a593Smuzhiyun u8 bl_version; 295*4882a593Smuzhiyun unsigned char bootloader_id[5]; 296*4882a593Smuzhiyun unsigned char configuration_id[CONFIG_ID_SIZE*2 + 1]; 297*4882a593Smuzhiyun 298*4882a593Smuzhiyun int update_status; 299*4882a593Smuzhiyun int update_progress; 300*4882a593Smuzhiyun int update_size; 301*4882a593Smuzhiyun 302*4882a593Smuzhiyun union { 303*4882a593Smuzhiyun struct f34v5_data v5; 304*4882a593Smuzhiyun struct f34v7_data v7; 305*4882a593Smuzhiyun }; 306*4882a593Smuzhiyun }; 307*4882a593Smuzhiyun 308*4882a593Smuzhiyun int rmi_f34v7_start_reflash(struct f34_data *f34, const struct firmware *fw); 309*4882a593Smuzhiyun int rmi_f34v7_do_reflash(struct f34_data *f34, const struct firmware *fw); 310*4882a593Smuzhiyun int rmi_f34v7_probe(struct f34_data *f34); 311*4882a593Smuzhiyun 312*4882a593Smuzhiyun #endif /* _RMI_F34_H */ 313