Skip to content

Commit 611d9ca

Browse files
author
Jiri Kosina
committed
Merge branch 'for-6.10/intel-ish' into for-linus
- Implement loading firmware from host in intel-ish driver, needed to support Lunar Lake and later (Zhang Lixu)
2 parents c216843 + 25247cf commit 611d9ca

File tree

10 files changed

+740
-97
lines changed

10 files changed

+740
-97
lines changed

Documentation/hid/intel-ish-hid.rst

Lines changed: 101 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ These ISH also comply to HID sensor specification, but the difference is the
1818
transport protocol used for communication. The current external sensor hubs
1919
mainly use HID over I2C or USB. But ISH doesn't use either I2C or USB.
2020

21-
1. Overview
22-
===========
21+
Overview
22+
========
2323

2424
Using a analogy with a usbhid implementation, the ISH follows a similar model
2525
for a very high speed communication::
@@ -58,8 +58,8 @@ implemented as a bus. Each client application executing in the ISH processor
5858
is registered as a device on this bus. The driver, which binds each device
5959
(ISH HID driver) identifies the device type and registers with the HID core.
6060

61-
2. ISH Implementation: Block Diagram
62-
====================================
61+
ISH Implementation: Block Diagram
62+
=================================
6363

6464
::
6565

@@ -96,27 +96,27 @@ is registered as a device on this bus. The driver, which binds each device
9696
| ISH Hardware/Firmware(FW) |
9797
----------------------------
9898

99-
3. High level processing in above blocks
100-
========================================
99+
High level processing in above blocks
100+
=====================================
101101

102-
3.1 Hardware Interface
103-
----------------------
102+
Hardware Interface
103+
------------------
104104

105105
The ISH is exposed as "Non-VGA unclassified PCI device" to the host. The PCI
106106
product and vendor IDs are changed from different generations of processors. So
107107
the source code which enumerates drivers needs to update from generation to
108108
generation.
109109

110-
3.2 Inter Processor Communication (IPC) driver
111-
----------------------------------------------
110+
Inter Processor Communication (IPC) driver
111+
------------------------------------------
112112

113113
Location: drivers/hid/intel-ish-hid/ipc
114114

115115
The IPC message uses memory mapped I/O. The registers are defined in
116116
hw-ish-regs.h.
117117

118-
3.2.1 IPC/FW message types
119-
^^^^^^^^^^^^^^^^^^^^^^^^^^
118+
IPC/FW message types
119+
^^^^^^^^^^^^^^^^^^^^
120120

121121
There are two types of messages, one for management of link and another for
122122
messages to and from transport layers.
@@ -142,20 +142,20 @@ register has the following format::
142142
Bit 31: doorbell trigger (signal H/W interrupt to the other side)
143143
Other bits are reserved, should be 0.
144144

145-
3.2.2 Transport layer interface
146-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
145+
Transport layer interface
146+
^^^^^^^^^^^^^^^^^^^^^^^^^
147147

148148
To abstract HW level IPC communication, a set of callbacks is registered.
149149
The transport layer uses them to send and receive messages.
150150
Refer to struct ishtp_hw_ops for callbacks.
151151

152-
3.3 ISH Transport layer
153-
-----------------------
152+
ISH Transport layer
153+
-------------------
154154

155155
Location: drivers/hid/intel-ish-hid/ishtp/
156156

157-
3.3.1 A Generic Transport Layer
158-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
157+
A Generic Transport Layer
158+
^^^^^^^^^^^^^^^^^^^^^^^^^
159159

160160
The transport layer is a bi-directional protocol, which defines:
161161
- Set of commands to start, stop, connect, disconnect and flow control
@@ -166,8 +166,8 @@ This protocol resembles bus messages described in the following document:
166166
http://www.intel.com/content/dam/www/public/us/en/documents/technical-\
167167
specifications/dcmi-hi-1-0-spec.pdf "Chapter 7: Bus Message Layer"
168168

169-
3.3.2 Connection and Flow Control Mechanism
170-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
169+
Connection and Flow Control Mechanism
170+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
171171

172172
Each FW client and a protocol is identified by a UUID. In order to communicate
173173
to a FW client, a connection must be established using connect request and
@@ -181,8 +181,8 @@ before receiving the next flow control credit.
181181
Either side can send disconnect request bus message to end communication. Also
182182
the link will be dropped if major FW reset occurs.
183183

184-
3.3.3 Peer to Peer data transfer
185-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
184+
Peer to Peer data transfer
185+
^^^^^^^^^^^^^^^^^^^^^^^^^^
186186

187187
Peer to Peer data transfer can happen with or without using DMA. Depending on
188188
the sensor bandwidth requirement DMA can be enabled by using module parameter
@@ -217,8 +217,8 @@ In principle, multiple DMA_XFER and DMA_XFER_ACK messages may be sent at once
217217
Currently, ISH FW decides to send over DMA if ISHTP message is more than 3 IPC
218218
fragments and via IPC otherwise.
219219

220-
3.3.4 Ring Buffers
221-
^^^^^^^^^^^^^^^^^^
220+
Ring Buffers
221+
^^^^^^^^^^^^
222222

223223
When a client initiates a connection, a ring of RX and TX buffers is allocated.
224224
The size of ring can be specified by the client. HID client sets 16 and 32 for
@@ -228,8 +228,8 @@ bus message protocol. These buffers are required because the FW may have not
228228
have processed the last message and may not have enough flow control credits
229229
to send. Same thing holds true on receive side and flow control is required.
230230

231-
3.3.5 Host Enumeration
232-
^^^^^^^^^^^^^^^^^^^^^^
231+
Host Enumeration
232+
^^^^^^^^^^^^^^^^
233233

234234
The host enumeration bus command allows discovery of clients present in the FW.
235235
There can be multiple sensor clients and clients for calibration function.
@@ -252,8 +252,8 @@ Enumeration sequence of messages:
252252
- Once host received properties for that last discovered client, it considers
253253
ISHTP device fully functional (and allocates DMA buffers)
254254

255-
3.4 HID over ISH Client
256-
-----------------------
255+
HID over ISH Client
256+
-------------------
257257

258258
Location: drivers/hid/intel-ish-hid
259259

@@ -265,16 +265,16 @@ The ISHTP client driver is responsible for:
265265
- Process Get/Set feature request
266266
- Get input reports
267267

268-
3.5 HID Sensor Hub MFD and IIO sensor drivers
269-
---------------------------------------------
268+
HID Sensor Hub MFD and IIO sensor drivers
269+
-----------------------------------------
270270

271271
The functionality in these drivers is the same as an external sensor hub.
272272
Refer to
273273
Documentation/hid/hid-sensor.rst for HID sensor
274274
Documentation/ABI/testing/sysfs-bus-iio for IIO ABIs to user space.
275275

276-
3.6 End to End HID transport Sequence Diagram
277-
---------------------------------------------
276+
End to End HID transport Sequence Diagram
277+
-----------------------------------------
278278

279279
::
280280

@@ -339,16 +339,81 @@ Documentation/ABI/testing/sysfs-bus-iio for IIO ABIs to user space.
339339
| | | |
340340

341341

342-
3.7 ISH Debugging
343-
-----------------
342+
ISH Firmware Loading from Host Flow
343+
-----------------------------------
344+
345+
Starting from the Lunar Lake generation, the ISH firmware has been divided into two components for better space optimization and increased flexibility. These components include a bootloader that is integrated into the BIOS, and a main firmware that is stored within the operating system's file system.
346+
347+
The process works as follows:
348+
349+
- Initially, the ISHTP driver sends a command, HOST_START_REQ_CMD, to the ISH bootloader. In response, the bootloader sends back a HOST_START_RES_CMD. This response includes the ISHTP_SUPPORT_CAP_LOADER bit. Subsequently, the ISHTP driver checks if this bit is set. If it is, the firmware loading process from the host begins.
350+
351+
- During this process, the ISHTP driver first invokes the request_firmware() function, followed by sending a LOADER_CMD_XFER_QUERY command. Upon receiving a response from the bootloader, the ISHTP driver sends a LOADER_CMD_XFER_FRAGMENT command. After receiving another response, the ISHTP driver sends a LOADER_CMD_START command. The bootloader responds and then proceeds to the Main Firmware.
352+
353+
- After the process concludes, the ISHTP driver calls the release_firmware() function.
354+
355+
For more detailed information, please refer to the flow descriptions provided below:
356+
357+
::
358+
359+
+---------------+ +-----------------+
360+
| ISHTP Driver | | ISH Bootloader |
361+
+---------------+ +-----------------+
362+
| |
363+
|~~~Send HOST_START_REQ_CMD~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|
364+
| |
365+
|<--Send HOST_START_RES_CMD(Includes ISHTP_SUPPORT_CAP_LOADER bit)----|
366+
| |
367+
****************************************************************************************
368+
* if ISHTP_SUPPORT_CAP_LOADER bit is set *
369+
****************************************************************************************
370+
| |
371+
|~~~start loading firmware from host process~~~+ |
372+
| | |
373+
|<---------------------------------------------+ |
374+
| |
375+
--------------------------- |
376+
| Call request_firmware() | |
377+
--------------------------- |
378+
| |
379+
|~~~Send LOADER_CMD_XFER_QUERY~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|
380+
| |
381+
|<--Send response-----------------------------------------------------|
382+
| |
383+
|~~~Send LOADER_CMD_XFER_FRAGMENT~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|
384+
| |
385+
|<--Send response-----------------------------------------------------|
386+
| |
387+
|~~~Send LOADER_CMD_START~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|
388+
| |
389+
|<--Send response-----------------------------------------------------|
390+
| |
391+
| |~~~Jump to Main Firmware~~~+
392+
| | |
393+
| |<--------------------------+
394+
| |
395+
--------------------------- |
396+
| Call release_firmware() | |
397+
--------------------------- |
398+
| |
399+
****************************************************************************************
400+
* end if *
401+
****************************************************************************************
402+
| |
403+
+---------------+ +-----------------+
404+
| ISHTP Driver | | ISH Bootloader |
405+
+---------------+ +-----------------+
406+
407+
ISH Debugging
408+
-------------
344409

345410
To debug ISH, event tracing mechanism is used. To enable debug logs::
346411

347412
echo 1 > /sys/kernel/tracing/events/intel_ish/enable
348413
cat /sys/kernel/tracing/trace
349414

350-
3.8 ISH IIO sysfs Example on Lenovo thinkpad Yoga 260
351-
-----------------------------------------------------
415+
ISH IIO sysfs Example on Lenovo thinkpad Yoga 260
416+
-------------------------------------------------
352417

353418
::
354419

drivers/hid/intel-ish-hid/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ intel-ishtp-objs += ishtp/client.o
1111
intel-ishtp-objs += ishtp/bus.o
1212
intel-ishtp-objs += ishtp/dma-if.o
1313
intel-ishtp-objs += ishtp/client-buffers.o
14+
intel-ishtp-objs += ishtp/loader.o
1415

1516
obj-$(CONFIG_INTEL_ISH_HID) += intel-ish-ipc.o
1617
intel-ish-ipc-objs := ipc/ipc.o

drivers/hid/intel-ish-hid/ipc/hw-ish.h

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,28 +13,29 @@
1313
#include "hw-ish-regs.h"
1414
#include "ishtp-dev.h"
1515

16-
#define CHV_DEVICE_ID 0x22D8
17-
#define BXT_Ax_DEVICE_ID 0x0AA2
18-
#define BXT_Bx_DEVICE_ID 0x1AA2
19-
#define APL_Ax_DEVICE_ID 0x5AA2
20-
#define SPT_Ax_DEVICE_ID 0x9D35
21-
#define CNL_Ax_DEVICE_ID 0x9DFC
22-
#define GLK_Ax_DEVICE_ID 0x31A2
23-
#define CNL_H_DEVICE_ID 0xA37C
24-
#define ICL_MOBILE_DEVICE_ID 0x34FC
25-
#define SPT_H_DEVICE_ID 0xA135
26-
#define CML_LP_DEVICE_ID 0x02FC
27-
#define CMP_H_DEVICE_ID 0x06FC
28-
#define EHL_Ax_DEVICE_ID 0x4BB3
29-
#define TGL_LP_DEVICE_ID 0xA0FC
30-
#define TGL_H_DEVICE_ID 0x43FC
31-
#define ADL_S_DEVICE_ID 0x7AF8
32-
#define ADL_P_DEVICE_ID 0x51FC
33-
#define ADL_N_DEVICE_ID 0x54FC
34-
#define RPL_S_DEVICE_ID 0x7A78
35-
#define MTL_P_DEVICE_ID 0x7E45
36-
#define ARL_H_DEVICE_ID 0x7745
37-
#define ARL_S_DEVICE_ID 0x7F78
16+
#define PCI_DEVICE_ID_INTEL_ISH_CHV 0x22D8
17+
#define PCI_DEVICE_ID_INTEL_ISH_BXT_Ax 0x0AA2
18+
#define PCI_DEVICE_ID_INTEL_ISH_BXT_Bx 0x1AA2
19+
#define PCI_DEVICE_ID_INTEL_ISH_APL_Ax 0x5AA2
20+
#define PCI_DEVICE_ID_INTEL_ISH_SPT_Ax 0x9D35
21+
#define PCI_DEVICE_ID_INTEL_ISH_CNL_Ax 0x9DFC
22+
#define PCI_DEVICE_ID_INTEL_ISH_GLK_Ax 0x31A2
23+
#define PCI_DEVICE_ID_INTEL_ISH_CNL_H 0xA37C
24+
#define PCI_DEVICE_ID_INTEL_ISH_ICL_MOBILE 0x34FC
25+
#define PCI_DEVICE_ID_INTEL_ISH_SPT_H 0xA135
26+
#define PCI_DEVICE_ID_INTEL_ISH_CML_LP 0x02FC
27+
#define PCI_DEVICE_ID_INTEL_ISH_CMP_H 0x06FC
28+
#define PCI_DEVICE_ID_INTEL_ISH_EHL_Ax 0x4BB3
29+
#define PCI_DEVICE_ID_INTEL_ISH_TGL_LP 0xA0FC
30+
#define PCI_DEVICE_ID_INTEL_ISH_TGL_H 0x43FC
31+
#define PCI_DEVICE_ID_INTEL_ISH_ADL_S 0x7AF8
32+
#define PCI_DEVICE_ID_INTEL_ISH_ADL_P 0x51FC
33+
#define PCI_DEVICE_ID_INTEL_ISH_ADL_N 0x54FC
34+
#define PCI_DEVICE_ID_INTEL_ISH_RPL_S 0x7A78
35+
#define PCI_DEVICE_ID_INTEL_ISH_MTL_P 0x7E45
36+
#define PCI_DEVICE_ID_INTEL_ISH_ARL_H 0x7745
37+
#define PCI_DEVICE_ID_INTEL_ISH_ARL_S 0x7F78
38+
#define PCI_DEVICE_ID_INTEL_ISH_LNL_M 0xA845
3839

3940
#define REVISION_ID_CHT_A0 0x6
4041
#define REVISION_ID_CHT_Ax_SI 0x0

drivers/hid/intel-ish-hid/ipc/ipc.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ static bool check_generated_interrupt(struct ishtp_device *dev)
7878
bool interrupt_generated = true;
7979
uint32_t pisr_val = 0;
8080

81-
if (dev->pdev->device == CHV_DEVICE_ID) {
81+
if (dev->pdev->device == PCI_DEVICE_ID_INTEL_ISH_CHV) {
8282
pisr_val = ish_reg_read(dev, IPC_REG_PISR_CHV_AB);
8383
interrupt_generated =
8484
IPC_INT_FROM_ISH_TO_HOST_CHV_AB(pisr_val);
@@ -117,7 +117,7 @@ static bool ish_is_input_ready(struct ishtp_device *dev)
117117
*/
118118
static void set_host_ready(struct ishtp_device *dev)
119119
{
120-
if (dev->pdev->device == CHV_DEVICE_ID) {
120+
if (dev->pdev->device == PCI_DEVICE_ID_INTEL_ISH_CHV) {
121121
if (dev->pdev->revision == REVISION_ID_CHT_A0 ||
122122
(dev->pdev->revision & REVISION_ID_SI_MASK) ==
123123
REVISION_ID_CHT_Ax_SI)
@@ -546,11 +546,11 @@ static int ish_fw_reset_handler(struct ishtp_device *dev)
546546

547547
/**
548548
* fw_reset_work_fn() - FW reset worker function
549-
* @unused: not used
549+
* @work: Work item
550550
*
551551
* Call ish_fw_reset_handler to complete FW reset
552552
*/
553-
static void fw_reset_work_fn(struct work_struct *unused)
553+
static void fw_reset_work_fn(struct work_struct *work)
554554
{
555555
int rv;
556556

@@ -562,7 +562,8 @@ static void fw_reset_work_fn(struct work_struct *unused)
562562
wake_up_interruptible(&ishtp_dev->wait_hw_ready);
563563

564564
/* ISHTP notification in IPC_RESET sequence completion */
565-
ishtp_reset_compl_handler(ishtp_dev);
565+
if (!work_pending(work))
566+
ishtp_reset_compl_handler(ishtp_dev);
566567
} else
567568
dev_err(ishtp_dev->devc, "[ishtp-ish]: FW reset failed (%d)\n",
568569
rv);
@@ -909,11 +910,11 @@ static uint32_t ish_ipc_get_header(struct ishtp_device *dev, int length,
909910
*/
910911
static bool _dma_no_cache_snooping(struct ishtp_device *dev)
911912
{
912-
return (dev->pdev->device == EHL_Ax_DEVICE_ID ||
913-
dev->pdev->device == TGL_LP_DEVICE_ID ||
914-
dev->pdev->device == TGL_H_DEVICE_ID ||
915-
dev->pdev->device == ADL_S_DEVICE_ID ||
916-
dev->pdev->device == ADL_P_DEVICE_ID);
913+
return (dev->pdev->device == PCI_DEVICE_ID_INTEL_ISH_EHL_Ax ||
914+
dev->pdev->device == PCI_DEVICE_ID_INTEL_ISH_TGL_LP ||
915+
dev->pdev->device == PCI_DEVICE_ID_INTEL_ISH_TGL_H ||
916+
dev->pdev->device == PCI_DEVICE_ID_INTEL_ISH_ADL_S ||
917+
dev->pdev->device == PCI_DEVICE_ID_INTEL_ISH_ADL_P);
917918
}
918919

919920
static const struct ishtp_hw_ops ish_hw_ops = {

0 commit comments

Comments
 (0)