1579a267eSZhang Lixu /* SPDX-License-Identifier: GPL-2.0-only */ 2579a267eSZhang Lixu /* 3579a267eSZhang Lixu * ISHTP firmware loader header 4579a267eSZhang Lixu * 5579a267eSZhang Lixu * Copyright (c) 2024, Intel Corporation. 6579a267eSZhang Lixu */ 7579a267eSZhang Lixu 8579a267eSZhang Lixu #ifndef _ISHTP_LOADER_H_ 9579a267eSZhang Lixu #define _ISHTP_LOADER_H_ 10579a267eSZhang Lixu 11579a267eSZhang Lixu #include <linux/bits.h> 12579a267eSZhang Lixu #include <linux/jiffies.h> 13579a267eSZhang Lixu #include <linux/types.h> 14579a267eSZhang Lixu 15579a267eSZhang Lixu #include "ishtp-dev.h" 16579a267eSZhang Lixu 17579a267eSZhang Lixu struct work_struct; 18579a267eSZhang Lixu 19579a267eSZhang Lixu #define LOADER_MSG_SIZE \ 20579a267eSZhang Lixu (IPC_PAYLOAD_SIZE - sizeof(struct ishtp_msg_hdr)) 21579a267eSZhang Lixu 22579a267eSZhang Lixu /* 23579a267eSZhang Lixu * ISHTP firmware loader protocol definition 24579a267eSZhang Lixu */ 25579a267eSZhang Lixu #define LOADER_CMD_XFER_QUERY 0 /* SW -> FW */ 26579a267eSZhang Lixu #define LOADER_CMD_XFER_FRAGMENT 1 /* SW -> FW */ 27579a267eSZhang Lixu #define LOADER_CMD_START 2 /* SW -> FW */ 28579a267eSZhang Lixu 29579a267eSZhang Lixu /* Only support DMA mode */ 30579a267eSZhang Lixu #define LOADER_XFER_MODE_DMA BIT(0) 31579a267eSZhang Lixu 32579a267eSZhang Lixu /** 33*9e438fe3SArnd Bergmann * union loader_msg_header - ISHTP firmware loader message header 34579a267eSZhang Lixu * @command: Command type 35579a267eSZhang Lixu * @is_response: Indicates if the message is a response 36579a267eSZhang Lixu * @has_next: Indicates if there is a next message 37579a267eSZhang Lixu * @reserved: Reserved for future use 38579a267eSZhang Lixu * @status: Status of the message 39*9e438fe3SArnd Bergmann * @val32: entire header as a 32-bit value 40579a267eSZhang Lixu */ 41*9e438fe3SArnd Bergmann union loader_msg_header { 42*9e438fe3SArnd Bergmann struct { 43*9e438fe3SArnd Bergmann __u32 command:7; 44*9e438fe3SArnd Bergmann __u32 is_response:1; 45*9e438fe3SArnd Bergmann __u32 has_next:1; 46*9e438fe3SArnd Bergmann __u32 reserved:15; 47*9e438fe3SArnd Bergmann __u32 status:8; 48*9e438fe3SArnd Bergmann }; 49*9e438fe3SArnd Bergmann __u32 val32; 50579a267eSZhang Lixu }; 51579a267eSZhang Lixu 52579a267eSZhang Lixu /** 53579a267eSZhang Lixu * struct loader_xfer_query - ISHTP firmware loader transfer query packet 54579a267eSZhang Lixu * @header: Header of the message 55579a267eSZhang Lixu * @image_size: Size of the image 56579a267eSZhang Lixu */ 57579a267eSZhang Lixu struct loader_xfer_query { 58*9e438fe3SArnd Bergmann __le32 header; 59579a267eSZhang Lixu __le32 image_size; 60579a267eSZhang Lixu }; 61579a267eSZhang Lixu 62579a267eSZhang Lixu /** 63579a267eSZhang Lixu * struct loader_version - ISHTP firmware loader version 64579a267eSZhang Lixu * @value: Value of the version 65579a267eSZhang Lixu * @major: Major version 66579a267eSZhang Lixu * @minor: Minor version 67579a267eSZhang Lixu * @hotfix: Hotfix version 68579a267eSZhang Lixu * @build: Build version 69579a267eSZhang Lixu */ 70579a267eSZhang Lixu struct loader_version { 71579a267eSZhang Lixu union { 72579a267eSZhang Lixu __le32 value; 73579a267eSZhang Lixu struct { 74579a267eSZhang Lixu __u8 major; 75579a267eSZhang Lixu __u8 minor; 76579a267eSZhang Lixu __u8 hotfix; 77579a267eSZhang Lixu __u8 build; 78579a267eSZhang Lixu }; 79579a267eSZhang Lixu }; 80579a267eSZhang Lixu }; 81579a267eSZhang Lixu 82579a267eSZhang Lixu /** 83579a267eSZhang Lixu * struct loader_capability - ISHTP firmware loader capability 84579a267eSZhang Lixu * @max_fw_image_size: Maximum firmware image size 85579a267eSZhang Lixu * @support_mode: Support mode 86579a267eSZhang Lixu * @reserved: Reserved for future use 87579a267eSZhang Lixu * @platform: Platform 88579a267eSZhang Lixu * @max_dma_buf_size: Maximum DMA buffer size, multiples of 4096 89579a267eSZhang Lixu */ 90579a267eSZhang Lixu struct loader_capability { 91579a267eSZhang Lixu __le32 max_fw_image_size; 92579a267eSZhang Lixu __le16 support_mode; 93579a267eSZhang Lixu __u8 reserved; 94579a267eSZhang Lixu __u8 platform; 95579a267eSZhang Lixu __le32 max_dma_buf_size; 96579a267eSZhang Lixu }; 97579a267eSZhang Lixu 98579a267eSZhang Lixu /** 99579a267eSZhang Lixu * struct loader_xfer_query_ack - ISHTP firmware loader transfer query acknowledgment 100579a267eSZhang Lixu * @header: Header of the message 101579a267eSZhang Lixu * @version_major: ISH Major version 102579a267eSZhang Lixu * @version_minor: ISH Minor version 103579a267eSZhang Lixu * @version_hotfix: ISH Hotfix version 104579a267eSZhang Lixu * @version_build: ISH Build version 105579a267eSZhang Lixu * @protocol_version: Protocol version 106579a267eSZhang Lixu * @loader_version: Loader version 107579a267eSZhang Lixu * @capability: Loader capability 108579a267eSZhang Lixu */ 109579a267eSZhang Lixu struct loader_xfer_query_ack { 110*9e438fe3SArnd Bergmann __le32 header; 111579a267eSZhang Lixu __le16 version_major; 112579a267eSZhang Lixu __le16 version_minor; 113579a267eSZhang Lixu __le16 version_hotfix; 114579a267eSZhang Lixu __le16 version_build; 115579a267eSZhang Lixu __le32 protocol_version; 116579a267eSZhang Lixu struct loader_version loader_version; 117579a267eSZhang Lixu struct loader_capability capability; 118579a267eSZhang Lixu }; 119579a267eSZhang Lixu 120579a267eSZhang Lixu /** 121579a267eSZhang Lixu * struct loader_xfer_fragment - ISHTP firmware loader transfer fragment 122579a267eSZhang Lixu * @header: Header of the message 123579a267eSZhang Lixu * @xfer_mode: Transfer mode 124579a267eSZhang Lixu * @offset: Offset 125579a267eSZhang Lixu * @size: Size 126579a267eSZhang Lixu * @is_last: Is last 127579a267eSZhang Lixu */ 128579a267eSZhang Lixu struct loader_xfer_fragment { 129*9e438fe3SArnd Bergmann __le32 header; 130579a267eSZhang Lixu __le32 xfer_mode; 131579a267eSZhang Lixu __le32 offset; 132579a267eSZhang Lixu __le32 size; 133579a267eSZhang Lixu __le32 is_last; 134579a267eSZhang Lixu }; 135579a267eSZhang Lixu 136579a267eSZhang Lixu /** 137579a267eSZhang Lixu * struct loader_xfer_fragment_ack - ISHTP firmware loader transfer fragment acknowledgment 138579a267eSZhang Lixu * @header: Header of the message 139579a267eSZhang Lixu */ 140579a267eSZhang Lixu struct loader_xfer_fragment_ack { 141*9e438fe3SArnd Bergmann __le32 header; 142579a267eSZhang Lixu }; 143579a267eSZhang Lixu 144579a267eSZhang Lixu /** 145579a267eSZhang Lixu * struct fragment_dscrpt - ISHTP firmware loader fragment descriptor 146579a267eSZhang Lixu * @ddr_adrs: The address in host DDR 147579a267eSZhang Lixu * @fw_off: The offset of the fragment in the fw image 148579a267eSZhang Lixu * @length: The length of the fragment 149579a267eSZhang Lixu */ 150579a267eSZhang Lixu struct fragment_dscrpt { 151579a267eSZhang Lixu __le64 ddr_adrs; 152579a267eSZhang Lixu __le32 fw_off; 153579a267eSZhang Lixu __le32 length; 154579a267eSZhang Lixu }; 155579a267eSZhang Lixu 156579a267eSZhang Lixu #define FRAGMENT_MAX_NUM \ 157579a267eSZhang Lixu ((LOADER_MSG_SIZE - sizeof(struct loader_xfer_dma_fragment)) / \ 158579a267eSZhang Lixu sizeof(struct fragment_dscrpt)) 159579a267eSZhang Lixu 160579a267eSZhang Lixu /** 161579a267eSZhang Lixu * struct loader_xfer_dma_fragment - ISHTP firmware loader transfer DMA fragment 162579a267eSZhang Lixu * @fragment: Fragment 163579a267eSZhang Lixu * @fragment_cnt: How many descriptors in the fragment_tbl 164579a267eSZhang Lixu * @fragment_tbl: Fragment table 165579a267eSZhang Lixu */ 166579a267eSZhang Lixu struct loader_xfer_dma_fragment { 167579a267eSZhang Lixu struct loader_xfer_fragment fragment; 168579a267eSZhang Lixu __le32 fragment_cnt; 169579a267eSZhang Lixu struct fragment_dscrpt fragment_tbl[] __counted_by(fragment_cnt); 170579a267eSZhang Lixu }; 171579a267eSZhang Lixu 172579a267eSZhang Lixu /** 173579a267eSZhang Lixu * struct loader_start - ISHTP firmware loader start 174579a267eSZhang Lixu * @header: Header of the message 175579a267eSZhang Lixu */ 176579a267eSZhang Lixu struct loader_start { 177*9e438fe3SArnd Bergmann __le32 header; 178579a267eSZhang Lixu }; 179579a267eSZhang Lixu 180579a267eSZhang Lixu /** 181579a267eSZhang Lixu * struct loader_start_ack - ISHTP firmware loader start acknowledgment 182579a267eSZhang Lixu * @header: Header of the message 183579a267eSZhang Lixu */ 184579a267eSZhang Lixu struct loader_start_ack { 185*9e438fe3SArnd Bergmann __le32 header; 186579a267eSZhang Lixu }; 187579a267eSZhang Lixu 188579a267eSZhang Lixu union loader_recv_message { 189*9e438fe3SArnd Bergmann __le32 header; 190579a267eSZhang Lixu struct loader_xfer_query_ack query_ack; 191579a267eSZhang Lixu struct loader_xfer_fragment_ack fragment_ack; 192579a267eSZhang Lixu struct loader_start_ack start_ack; 193579a267eSZhang Lixu __u8 raw_data[LOADER_MSG_SIZE]; 194579a267eSZhang Lixu }; 195579a267eSZhang Lixu 196579a267eSZhang Lixu /* 197579a267eSZhang Lixu * ISHTP firmware loader internal use 198579a267eSZhang Lixu */ 199579a267eSZhang Lixu /* ISHTP firmware loader command timeout */ 200579a267eSZhang Lixu #define ISHTP_LOADER_TIMEOUT msecs_to_jiffies(100) 201579a267eSZhang Lixu 202579a267eSZhang Lixu /* ISHTP firmware loader retry times */ 203579a267eSZhang Lixu #define ISHTP_LOADER_RETRY_TIMES 3 204579a267eSZhang Lixu 205579a267eSZhang Lixu /** 206579a267eSZhang Lixu * struct ish_firmware_variant - ISH firmware variant 207579a267eSZhang Lixu * @device: PCI Device ID 208579a267eSZhang Lixu * @filename: The firmware file name 209579a267eSZhang Lixu */ 210579a267eSZhang Lixu struct ish_firmware_variant { 211579a267eSZhang Lixu unsigned short device; 212579a267eSZhang Lixu const char *filename; 213579a267eSZhang Lixu }; 214579a267eSZhang Lixu 215579a267eSZhang Lixu /* 216579a267eSZhang Lixu * ISHTP firmware loader API for ISHTP hbm 217579a267eSZhang Lixu */ 218579a267eSZhang Lixu 219579a267eSZhang Lixu /* ISHTP capability bit for firmware loader */ 220579a267eSZhang Lixu #define ISHTP_SUPPORT_CAP_LOADER BIT(4) 221579a267eSZhang Lixu 222579a267eSZhang Lixu /* Firmware loader address */ 223579a267eSZhang Lixu #define ISHTP_LOADER_CLIENT_ADDR 16 224579a267eSZhang Lixu 225579a267eSZhang Lixu /** 226579a267eSZhang Lixu * ishtp_loader_work - The work function to start the firmware loading process 227579a267eSZhang Lixu * @work: The work structure 228579a267eSZhang Lixu */ 229579a267eSZhang Lixu void ishtp_loader_work(struct work_struct *work); 230579a267eSZhang Lixu 231579a267eSZhang Lixu #endif /* _ISHTP_LOADER_H_ */ 232