xref: /linux/drivers/hid/intel-ish-hid/ishtp/loader.h (revision 001821b0e79716c4e17c71d8e053a23599a7a508)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * ISHTP firmware loader header
4  *
5  * Copyright (c) 2024, Intel Corporation.
6  */
7 
8 #ifndef _ISHTP_LOADER_H_
9 #define _ISHTP_LOADER_H_
10 
11 #include <linux/bits.h>
12 #include <linux/jiffies.h>
13 #include <linux/types.h>
14 
15 #include "ishtp-dev.h"
16 
17 struct work_struct;
18 
19 #define LOADER_MSG_SIZE \
20 	(IPC_PAYLOAD_SIZE - sizeof(struct ishtp_msg_hdr))
21 
22 /*
23  * ISHTP firmware loader protocol definition
24  */
25 #define LOADER_CMD_XFER_QUERY		0	/* SW -> FW */
26 #define LOADER_CMD_XFER_FRAGMENT	1	/* SW -> FW */
27 #define LOADER_CMD_START		2	/* SW -> FW */
28 
29 /* Only support DMA mode */
30 #define LOADER_XFER_MODE_DMA BIT(0)
31 
32 /**
33  * struct loader_msg_header - ISHTP firmware loader message header
34  * @command: Command type
35  * @is_response: Indicates if the message is a response
36  * @has_next: Indicates if there is a next message
37  * @reserved: Reserved for future use
38  * @status: Status of the message
39  */
40 struct loader_msg_header {
41 	__le32 command:7;
42 	__le32 is_response:1;
43 	__le32 has_next:1;
44 	__le32 reserved:15;
45 	__le32 status:8;
46 };
47 
48 /**
49  * struct loader_xfer_query - ISHTP firmware loader transfer query packet
50  * @header: Header of the message
51  * @image_size: Size of the image
52  */
53 struct loader_xfer_query {
54 	struct loader_msg_header header;
55 	__le32 image_size;
56 };
57 
58 /**
59  * struct loader_version - ISHTP firmware loader version
60  * @value: Value of the version
61  * @major: Major version
62  * @minor: Minor version
63  * @hotfix: Hotfix version
64  * @build: Build version
65  */
66 struct loader_version {
67 	union {
68 		__le32 value;
69 		struct {
70 			__u8 major;
71 			__u8 minor;
72 			__u8 hotfix;
73 			__u8 build;
74 		};
75 	};
76 };
77 
78 /**
79  * struct loader_capability - ISHTP firmware loader capability
80  * @max_fw_image_size: Maximum firmware image size
81  * @support_mode: Support mode
82  * @reserved: Reserved for future use
83  * @platform: Platform
84  * @max_dma_buf_size: Maximum DMA buffer size, multiples of 4096
85  */
86 struct loader_capability {
87 	__le32 max_fw_image_size;
88 	__le16 support_mode;
89 	__u8 reserved;
90 	__u8 platform;
91 	__le32 max_dma_buf_size;
92 };
93 
94 /**
95  * struct loader_xfer_query_ack - ISHTP firmware loader transfer query acknowledgment
96  * @header: Header of the message
97  * @version_major: ISH Major version
98  * @version_minor: ISH Minor version
99  * @version_hotfix: ISH Hotfix version
100  * @version_build: ISH Build version
101  * @protocol_version: Protocol version
102  * @loader_version: Loader version
103  * @capability: Loader capability
104  */
105 struct loader_xfer_query_ack {
106 	struct loader_msg_header header;
107 	__le16 version_major;
108 	__le16 version_minor;
109 	__le16 version_hotfix;
110 	__le16 version_build;
111 	__le32 protocol_version;
112 	struct loader_version loader_version;
113 	struct loader_capability capability;
114 };
115 
116 /**
117  * struct loader_xfer_fragment - ISHTP firmware loader transfer fragment
118  * @header: Header of the message
119  * @xfer_mode: Transfer mode
120  * @offset: Offset
121  * @size: Size
122  * @is_last: Is last
123  */
124 struct loader_xfer_fragment {
125 	struct loader_msg_header header;
126 	__le32 xfer_mode;
127 	__le32 offset;
128 	__le32 size;
129 	__le32 is_last;
130 };
131 
132 /**
133  * struct loader_xfer_fragment_ack - ISHTP firmware loader transfer fragment acknowledgment
134  * @header: Header of the message
135  */
136 struct loader_xfer_fragment_ack {
137 	struct loader_msg_header header;
138 };
139 
140 /**
141  * struct fragment_dscrpt - ISHTP firmware loader fragment descriptor
142  * @ddr_adrs: The address in host DDR
143  * @fw_off: The offset of the fragment in the fw image
144  * @length: The length of the fragment
145  */
146 struct fragment_dscrpt {
147 	__le64 ddr_adrs;
148 	__le32 fw_off;
149 	__le32 length;
150 };
151 
152 #define FRAGMENT_MAX_NUM \
153 	((LOADER_MSG_SIZE - sizeof(struct loader_xfer_dma_fragment)) / \
154 	 sizeof(struct fragment_dscrpt))
155 
156 /**
157  * struct loader_xfer_dma_fragment - ISHTP firmware loader transfer DMA fragment
158  * @fragment: Fragment
159  * @fragment_cnt: How many descriptors in the fragment_tbl
160  * @fragment_tbl: Fragment table
161  */
162 struct loader_xfer_dma_fragment {
163 	struct loader_xfer_fragment fragment;
164 	__le32 fragment_cnt;
165 	struct fragment_dscrpt fragment_tbl[] __counted_by(fragment_cnt);
166 };
167 
168 /**
169  * struct loader_start - ISHTP firmware loader start
170  * @header: Header of the message
171  */
172 struct loader_start {
173 	struct loader_msg_header header;
174 };
175 
176 /**
177  * struct loader_start_ack - ISHTP firmware loader start acknowledgment
178  * @header: Header of the message
179  */
180 struct loader_start_ack {
181 	struct loader_msg_header header;
182 };
183 
184 union loader_recv_message {
185 	struct loader_xfer_query_ack query_ack;
186 	struct loader_xfer_fragment_ack fragment_ack;
187 	struct loader_start_ack start_ack;
188 	__u8 raw_data[LOADER_MSG_SIZE];
189 };
190 
191 /*
192  * ISHTP firmware loader internal use
193  */
194 /* ISHTP firmware loader command timeout */
195 #define ISHTP_LOADER_TIMEOUT msecs_to_jiffies(100)
196 
197 /* ISHTP firmware loader retry times */
198 #define ISHTP_LOADER_RETRY_TIMES 3
199 
200 /**
201  * struct ish_firmware_variant - ISH firmware variant
202  * @device: PCI Device ID
203  * @filename: The firmware file name
204  */
205 struct ish_firmware_variant {
206 	unsigned short device;
207 	const char *filename;
208 };
209 
210 /*
211  * ISHTP firmware loader API for ISHTP hbm
212  */
213 
214 /* ISHTP capability bit for firmware loader */
215 #define ISHTP_SUPPORT_CAP_LOADER BIT(4)
216 
217 /* Firmware loader address */
218 #define ISHTP_LOADER_CLIENT_ADDR 16
219 
220 /**
221  * ishtp_loader_work - The work function to start the firmware loading process
222  * @work: The work structure
223  */
224 void ishtp_loader_work(struct work_struct *work);
225 
226 #endif /* _ISHTP_LOADER_H_ */
227