From patchwork Mon May 6 01:30:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhang Lixu X-Patchwork-Id: 13654820 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.14]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E23AC381AA for ; Mon, 6 May 2024 01:30:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.14 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714959046; cv=none; b=tWSXsaRPkBuevq8oRpFb2DSve/owahMAMDmd9zqcjXzmPok36RxhyMVP5osTQvCmvHb4nGB0jO4EfGD/3j1R7xXlu6EKp2ibL8x5MyA5A93hxQ+DI7Yo1ymDc5ryt6je8Ma22ZZR8N4aogy9bXmKFhalS3/RMUc0BlFlR5ayoc4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714959046; c=relaxed/simple; bh=GbPFKax1AUFm5v+Qmxx1wgB9gElrx2gO051/IbYxByM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=KmzpcMDVBPULldEGKGbjqncofLVRzXjqC3cvDZLqKW9kDxpVJB1DLQVjP+Vz+7LiGlth+CC2M1iPkWGstsKIYekDenFWfxCBsYn6+esGwjZHnNFbZsrkveUJntMDkPxkJeMhYmr9Fzuy3KlvMXwWAx63w9TB7DdaU+E5kj2JHMs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=Gr0H0xHT; arc=none smtp.client-ip=198.175.65.14 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="Gr0H0xHT" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1714959045; x=1746495045; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=GbPFKax1AUFm5v+Qmxx1wgB9gElrx2gO051/IbYxByM=; b=Gr0H0xHTEbQBwkho+5k6IXqScfdOs7jYgoUEJOBaG8b4xZ/c+jVQR42Q Ci6dyr/Y1fLu6G1kbGA7s3TNiVUSfA5PZ33pDKwxKEfsjavMRColLx2Lc P2fxu5dZmWLk8LumibacTHc5JOzYVgJ9G5Tlm/bOsMt2IsgnNZkzuQux5 L+wskxn9zXPeZG/ZYofDDdODixp8D91g1tGyRmkSXzTCNN2VtDKobBZFp lxb7tewC6OPXPmhAQWIxeHhi1c9N8KVMNgDOCyQKd6hvqucGqGd6w69Ku Phi98WuSj/Hh91b/WcCzrIIOxAA4V0URhGW1q2x7VZPXGAi95PfgL+Bld g==; X-CSE-ConnectionGUID: fyaRlECVRJq04THT+GsjFg== X-CSE-MsgGUID: rQsjLEmESBWG4PguvtEy2A== X-IronPort-AV: E=McAfee;i="6600,9927,11064"; a="14503854" X-IronPort-AV: E=Sophos;i="6.07,257,1708416000"; d="scan'208";a="14503854" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 May 2024 18:30:44 -0700 X-CSE-ConnectionGUID: lF7u3f9gSPOoKx9GiKFWfA== X-CSE-MsgGUID: TLJzi5igQuy1RkJPBGkwvA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,257,1708416000"; d="scan'208";a="28092901" Received: from unknown (HELO ipg-l-lixuzha.sh.intel.com) ([10.239.153.157]) by fmviesa010.fm.intel.com with ESMTP; 05 May 2024 18:30:43 -0700 From: Zhang Lixu To: linux-input@vger.kernel.org, srinivas.pandruvada@linux.intel.com, jikos@kernel.org, benjamin.tissoires@redhat.com Cc: lixu.zhang@intel.com Subject: [PATCH 1/5] Documentation: hid: intel-ish-hid: remove section numbering Date: Mon, 6 May 2024 09:30:36 +0800 Message-Id: <20240506013040.10700-2-lixu.zhang@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240506013040.10700-1-lixu.zhang@intel.com> References: <20240506013040.10700-1-lixu.zhang@intel.com> Precedence: bulk X-Mailing-List: linux-input@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Qianru Huang Remove section numbering from the Intel Integrated Sensor Hub (ISH) documentation to simplify the structure, making it easier to maintain and update in the future. Suggested-by: Andy Shevchenko Signed-off-by: Qianru Huang Signed-off-by: Zhang Lixu Reviewed-by: Andy Shevchenko Acked-by: Srinivas Pandruvada --- Documentation/hid/intel-ish-hid.rst | 72 ++++++++++++++--------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/Documentation/hid/intel-ish-hid.rst b/Documentation/hid/intel-ish-hid.rst index 42dc77b7b10f..12613cb2be43 100644 --- a/Documentation/hid/intel-ish-hid.rst +++ b/Documentation/hid/intel-ish-hid.rst @@ -18,8 +18,8 @@ These ISH also comply to HID sensor specification, but the difference is the transport protocol used for communication. The current external sensor hubs mainly use HID over I2C or USB. But ISH doesn't use either I2C or USB. -1. Overview -=========== +Overview +======== Using a analogy with a usbhid implementation, the ISH follows a similar model for a very high speed communication:: @@ -58,8 +58,8 @@ implemented as a bus. Each client application executing in the ISH processor is registered as a device on this bus. The driver, which binds each device (ISH HID driver) identifies the device type and registers with the HID core. -2. ISH Implementation: Block Diagram -==================================== +ISH Implementation: Block Diagram +================================= :: @@ -96,27 +96,27 @@ is registered as a device on this bus. The driver, which binds each device | ISH Hardware/Firmware(FW) | ---------------------------- -3. High level processing in above blocks -======================================== +High level processing in above blocks +===================================== -3.1 Hardware Interface ----------------------- +Hardware Interface +------------------ The ISH is exposed as "Non-VGA unclassified PCI device" to the host. The PCI product and vendor IDs are changed from different generations of processors. So the source code which enumerates drivers needs to update from generation to generation. -3.2 Inter Processor Communication (IPC) driver ----------------------------------------------- +Inter Processor Communication (IPC) driver +------------------------------------------ Location: drivers/hid/intel-ish-hid/ipc The IPC message uses memory mapped I/O. The registers are defined in hw-ish-regs.h. -3.2.1 IPC/FW message types -^^^^^^^^^^^^^^^^^^^^^^^^^^ +IPC/FW message types +^^^^^^^^^^^^^^^^^^^^ There are two types of messages, one for management of link and another for messages to and from transport layers. @@ -142,20 +142,20 @@ register has the following format:: Bit 31: doorbell trigger (signal H/W interrupt to the other side) Other bits are reserved, should be 0. -3.2.2 Transport layer interface -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Transport layer interface +^^^^^^^^^^^^^^^^^^^^^^^^^ To abstract HW level IPC communication, a set of callbacks is registered. The transport layer uses them to send and receive messages. Refer to struct ishtp_hw_ops for callbacks. -3.3 ISH Transport layer ------------------------ +ISH Transport layer +------------------- Location: drivers/hid/intel-ish-hid/ishtp/ -3.3.1 A Generic Transport Layer -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +A Generic Transport Layer +^^^^^^^^^^^^^^^^^^^^^^^^^ The transport layer is a bi-directional protocol, which defines: - 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: http://www.intel.com/content/dam/www/public/us/en/documents/technical-\ specifications/dcmi-hi-1-0-spec.pdf "Chapter 7: Bus Message Layer" -3.3.2 Connection and Flow Control Mechanism -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Connection and Flow Control Mechanism +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Each FW client and a protocol is identified by a UUID. In order to communicate to a FW client, a connection must be established using connect request and @@ -181,8 +181,8 @@ before receiving the next flow control credit. Either side can send disconnect request bus message to end communication. Also the link will be dropped if major FW reset occurs. -3.3.3 Peer to Peer data transfer -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Peer to Peer data transfer +^^^^^^^^^^^^^^^^^^^^^^^^^^ Peer to Peer data transfer can happen with or without using DMA. Depending on 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 Currently, ISH FW decides to send over DMA if ISHTP message is more than 3 IPC fragments and via IPC otherwise. -3.3.4 Ring Buffers -^^^^^^^^^^^^^^^^^^ +Ring Buffers +^^^^^^^^^^^^ When a client initiates a connection, a ring of RX and TX buffers is allocated. 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 have processed the last message and may not have enough flow control credits to send. Same thing holds true on receive side and flow control is required. -3.3.5 Host Enumeration -^^^^^^^^^^^^^^^^^^^^^^ +Host Enumeration +^^^^^^^^^^^^^^^^ The host enumeration bus command allows discovery of clients present in the FW. There can be multiple sensor clients and clients for calibration function. @@ -252,8 +252,8 @@ Enumeration sequence of messages: - Once host received properties for that last discovered client, it considers ISHTP device fully functional (and allocates DMA buffers) -3.4 HID over ISH Client ------------------------ +HID over ISH Client +------------------- Location: drivers/hid/intel-ish-hid @@ -265,16 +265,16 @@ The ISHTP client driver is responsible for: - Process Get/Set feature request - Get input reports -3.5 HID Sensor Hub MFD and IIO sensor drivers ---------------------------------------------- +HID Sensor Hub MFD and IIO sensor drivers +----------------------------------------- The functionality in these drivers is the same as an external sensor hub. Refer to Documentation/hid/hid-sensor.rst for HID sensor Documentation/ABI/testing/sysfs-bus-iio for IIO ABIs to user space. -3.6 End to End HID transport Sequence Diagram ---------------------------------------------- +End to End HID transport Sequence Diagram +----------------------------------------- :: @@ -339,16 +339,16 @@ Documentation/ABI/testing/sysfs-bus-iio for IIO ABIs to user space. | | | | -3.7 ISH Debugging ------------------ +ISH Debugging +------------- To debug ISH, event tracing mechanism is used. To enable debug logs:: echo 1 > /sys/kernel/tracing/events/intel_ish/enable cat /sys/kernel/tracing/trace -3.8 ISH IIO sysfs Example on Lenovo thinkpad Yoga 260 ------------------------------------------------------ +ISH IIO sysfs Example on Lenovo thinkpad Yoga 260 +------------------------------------------------- :: From patchwork Mon May 6 01:30:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhang Lixu X-Patchwork-Id: 13654821 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.14]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 59FF62FB6 for ; Mon, 6 May 2024 01:30:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.14 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714959047; cv=none; b=lVDI48ixmnHK4c6nI3PHKABqI28uNMaBwkF8ia5/UHlyf/rDox60+4rR/HKeKXpmSlHhJ4klJrlgRhMsG9/xX2nANnMH19wYUm8Gzax3NoZWvzmk51vVDvU9LsLkwK0l26Kv3lxQgyQGmXHtgH+l+oRlq1uSg1tW1QogABy9swc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714959047; c=relaxed/simple; bh=pc+H5eCwZlQwuCX/gPKOACHfdZm6g/vpcGzGq78Td/c=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=pKOwAj3zoF/OHZ1biOygysTyeVu3J/JGbdmdsrCsZq76vGB/Y73frx/hU37/qWyc2cWfmjrKK1F3uq8l20Fz5BPNam6KGJps5dzIQijMSL0sRvkvAvABFn6eqxSMlTEbqn6NtiMt8VeUdMVjkUff/JSW7CvIviW7aoyUt3a/aJQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=f4kURGQi; arc=none smtp.client-ip=198.175.65.14 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="f4kURGQi" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1714959046; x=1746495046; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=pc+H5eCwZlQwuCX/gPKOACHfdZm6g/vpcGzGq78Td/c=; b=f4kURGQibifb1r7JNZeYe0fKoAqeeiboqAE0Qnzaa8IrhIOJWmFC64tC imAAfJC/9fTuwJ9M8rnqGRWGZ46VBTiaU21Halpvx8Mi0p1KXY4qcZzgc OuN4FEEHEIZoSbEE/k3LuJq3ly8ogAXa+9w6MBSXfrWbyZxe0SuJZvqwf 6AZVHwnCm78d8CES4EdBNtRxW2lGoRO9wzbJ4/zYKuRclau1s9emoLuv7 lajS7j35Deqa+5prPXA7uHNvWOf46lBG322uc85IpfiLGbvRxBqJzl+cF Seyo+QJ9cWYXk4hWXr06efftGUqZ0L3EoCp5g0HDuu6r+EUIBFKPMJpsb A==; X-CSE-ConnectionGUID: /NDSq8f5QkKkL46whvaULw== X-CSE-MsgGUID: udYOVs3PQ2yJWr+KE4/nNA== X-IronPort-AV: E=McAfee;i="6600,9927,11064"; a="14503858" X-IronPort-AV: E=Sophos;i="6.07,257,1708416000"; d="scan'208";a="14503858" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 May 2024 18:30:46 -0700 X-CSE-ConnectionGUID: EF37PLDqQJuaAOLPCFFuLQ== X-CSE-MsgGUID: yGbuqNatTCaOQhWcZRg3MQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,257,1708416000"; d="scan'208";a="28092908" Received: from unknown (HELO ipg-l-lixuzha.sh.intel.com) ([10.239.153.157]) by fmviesa010.fm.intel.com with ESMTP; 05 May 2024 18:30:44 -0700 From: Zhang Lixu To: linux-input@vger.kernel.org, srinivas.pandruvada@linux.intel.com, jikos@kernel.org, benjamin.tissoires@redhat.com Cc: lixu.zhang@intel.com Subject: [PATCH 2/5] Documentation: hid: intel-ish-hid: add section for firmware loading Date: Mon, 6 May 2024 09:30:37 +0800 Message-Id: <20240506013040.10700-3-lixu.zhang@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240506013040.10700-1-lixu.zhang@intel.com> References: <20240506013040.10700-1-lixu.zhang@intel.com> Precedence: bulk X-Mailing-List: linux-input@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Qianru Huang Add a section to describe the ISH firmware loading process for Lunar Lake and later generations. Signed-off-by: Qianru Huang Signed-off-by: Zhang Lixu Acked-by: Srinivas Pandruvada --- Documentation/hid/intel-ish-hid.rst | 65 +++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/Documentation/hid/intel-ish-hid.rst b/Documentation/hid/intel-ish-hid.rst index 12613cb2be43..55cbaa719a79 100644 --- a/Documentation/hid/intel-ish-hid.rst +++ b/Documentation/hid/intel-ish-hid.rst @@ -339,6 +339,71 @@ End to End HID transport Sequence Diagram | | | | +ISH Firmware Loading from Host Flow +----------------------------------- + +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. + +The process works as follows: + +- 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. + +- 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. + +- After the process concludes, the ISHTP driver calls the release_firmware() function. + +For more detailed information, please refer to the flow descriptions provided below: + +:: + + +---------------+ +-----------------+ + | ISHTP Driver | | ISH Bootloader | + +---------------+ +-----------------+ + | | + |~~~Send HOST_START_REQ_CMD~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>| + | | + |<--Send HOST_START_RES_CMD(Includes ISHTP_SUPPORT_CAP_LOADER bit)----| + | | + **************************************************************************************** + * if ISHTP_SUPPORT_CAP_LOADER bit is set * + **************************************************************************************** + | | + |~~~start loading firmware from host process~~~+ | + | | | + |<---------------------------------------------+ | + | | + --------------------------- | + | Call request_firmware() | | + --------------------------- | + | | + |~~~Send LOADER_CMD_XFER_QUERY~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>| + | | + |<--Send response-----------------------------------------------------| + | | + |~~~Send LOADER_CMD_XFER_FRAGMENT~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>| + | | + |<--Send response-----------------------------------------------------| + | | + |~~~Send LOADER_CMD_START~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>| + | | + |<--Send response-----------------------------------------------------| + | | + | |~~~Jump to Main Firmware~~~+ + | | | + | |<--------------------------+ + | | + --------------------------- | + | Call release_firmware() | | + --------------------------- | + | | + **************************************************************************************** + * end if * + **************************************************************************************** + | | + +---------------+ +-----------------+ + | ISHTP Driver | | ISH Bootloader | + +---------------+ +-----------------+ + ISH Debugging ------------- From patchwork Mon May 6 01:30:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhang Lixu X-Patchwork-Id: 13654822 X-Patchwork-Delegate: jikos@jikos.cz Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.14]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E3F2B381AA for ; Mon, 6 May 2024 01:30:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.14 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714959049; cv=none; b=S6C9f/GrOa4zDkDSBoYLAp1fwr5Gm5B7yIs5f6VgsfDtxLnilZJCL8wSBA8Hrih1R4iYCobKVckYR5EltxJG6xVb0h+yfw/i4b4xCROz9iUkvQdUJqTI78q14GcryK0k+M3Xc6jPwO5D/5N3hn2xqk34cTGaPP+Jh1+TNzVWHVs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714959049; c=relaxed/simple; bh=EyJAlViozMA94Ttsq4HfOHgRMN2VJ6zTyHW2xv6rIwc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=JwrpQgmgv8/KvytxyAquMop1b2l5JhBXusp+KmdndQ864dPVFn4hXyMWaW/1ekTgTPNNk1HsoRDNIek/CdBXWZCzPdZZ7lFmRDUS5RxMeyctJZ7wmhuDHsvuX1A2B6bzkBCzs0bc2Kjjh3w1/iiw0rOcq03meZQLGS2SALZETW8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=jhPBC1XN; arc=none smtp.client-ip=198.175.65.14 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="jhPBC1XN" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1714959048; x=1746495048; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=EyJAlViozMA94Ttsq4HfOHgRMN2VJ6zTyHW2xv6rIwc=; b=jhPBC1XNcU5pVVHopz6kktMm8v+6ULsV20wRNHERVWyYyLdyAlfyZh8J OhaLOeN/JRi0Aq2tw0emTSH2LkjhL2BOMqTxSNVe+ongIgAAy7HQVOLzo 8+nN9pWUXESV/m8XabXZVrSG01lqno2HBlLbaYUxTvPBHfT0KqVg2VxpP YHohoi+Zoykcm+FBT+i2qT3WjlqSx0NnVH64FMP2K+KtQF+JqygbZzYqc Eewt+2OHWTrvYWGNIdW+LR61nPMy+b6V4X0JDFsoSOKucO68oU5/I0w08 gggSaeirU3CD6LzugAToTOIpJrFusq+6V4+Wv6GSV9XPSJX337vRfzrwh Q==; X-CSE-ConnectionGUID: kGksXvg6RAqLIVBPo2/MjQ== X-CSE-MsgGUID: TBLbwPWOQaO/SRpZBX2dRQ== X-IronPort-AV: E=McAfee;i="6600,9927,11064"; a="14503867" X-IronPort-AV: E=Sophos;i="6.07,257,1708416000"; d="scan'208";a="14503867" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 May 2024 18:30:48 -0700 X-CSE-ConnectionGUID: fCtp+2E7QxmKBr2hm1JjyA== X-CSE-MsgGUID: jwbBn9gpTtWU2QY5sCSsRQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,257,1708416000"; d="scan'208";a="28092913" Received: from unknown (HELO ipg-l-lixuzha.sh.intel.com) ([10.239.153.157]) by fmviesa010.fm.intel.com with ESMTP; 05 May 2024 18:30:46 -0700 From: Zhang Lixu To: linux-input@vger.kernel.org, srinivas.pandruvada@linux.intel.com, jikos@kernel.org, benjamin.tissoires@redhat.com Cc: lixu.zhang@intel.com Subject: [PATCH 3/5] HID: intel-ish-hid: Add driver_data for specifying the firmware filename Date: Mon, 6 May 2024 09:30:38 +0800 Message-Id: <20240506013040.10700-4-lixu.zhang@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240506013040.10700-1-lixu.zhang@intel.com> References: <20240506013040.10700-1-lixu.zhang@intel.com> Precedence: bulk X-Mailing-List: linux-input@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Introduces a new structure, ishtp_driver_data, to hold driver-specific data, including the firmware filename for different hardware variants of the Intel Integrated Sensor Hub (ISH). Signed-off-by: Zhang Lixu Acked-by: Srinivas Pandruvada --- drivers/hid/intel-ish-hid/ipc/pci-ish.c | 18 +++++++++++++++++- drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h | 17 +++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/drivers/hid/intel-ish-hid/ipc/pci-ish.c b/drivers/hid/intel-ish-hid/ipc/pci-ish.c index e79d72f7db2a..d487227085b2 100644 --- a/drivers/hid/intel-ish-hid/ipc/pci-ish.c +++ b/drivers/hid/intel-ish-hid/ipc/pci-ish.c @@ -23,6 +23,19 @@ #include "ishtp-dev.h" #include "hw-ish.h" +enum ishtp_driver_data_index { + ISHTP_DRIVER_DATA_NONE, + ISHTP_DRIVER_DATA_LNL_M, +}; + +#define ISH_FW_FILENAME_LNL_M "intel/ish/ish_lnlm.bin" + +static struct ishtp_driver_data ishtp_driver_data[] = { + [ISHTP_DRIVER_DATA_LNL_M] = { + .fw_filename = ISH_FW_FILENAME_LNL_M, + }, +}; + static const struct pci_device_id ish_pci_tbl[] = { {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ISH_CHV)}, {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ISH_BXT_Ax)}, @@ -46,7 +59,7 @@ static const struct pci_device_id ish_pci_tbl[] = { {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ISH_MTL_P)}, {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ISH_ARL_H)}, {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ISH_ARL_S)}, - {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ISH_LNL_M)}, + {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ISH_LNL_M), .driver_data = ISHTP_DRIVER_DATA_LNL_M}, {} }; MODULE_DEVICE_TABLE(pci, ish_pci_tbl); @@ -167,6 +180,7 @@ static int ish_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } hw = to_ish_hw(ishtp); ishtp->print_log = ish_event_tracer; + ishtp->driver_data = &ishtp_driver_data[ent->driver_data]; /* mapping IO device memory */ hw->mem_addr = pcim_iomap_table(pdev)[0]; @@ -377,3 +391,5 @@ MODULE_AUTHOR("Srinivas Pandruvada "); MODULE_DESCRIPTION("Intel(R) Integrated Sensor Hub PCI Device Driver"); MODULE_LICENSE("GPL"); + +MODULE_FIRMWARE(ISH_FW_FILENAME_LNL_M); diff --git a/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h b/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h index 32142c7d9a04..ed294bf0bc8f 100644 --- a/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h +++ b/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h @@ -122,12 +122,29 @@ struct ishtp_hw_ops { bool (*dma_no_cache_snooping)(struct ishtp_device *dev); }; +/** + * struct ishtp_driver_data - Driver-specific data for ISHTP devices + * + * This structure holds driver-specific data that can be associated with each + * ISHTP device instance. It allows for the storage of data that is unique to + * a particular driver or hardware variant. + * + * @fw_filename: The firmware filename associated with a specific hardware + * variant of the Intel Integrated Sensor Hub (ISH). This allows + * the driver to load the correct firmware based on the device's + * hardware variant. + */ +struct ishtp_driver_data { + char *fw_filename; +}; + /** * struct ishtp_device - ISHTP private device struct */ struct ishtp_device { struct device *devc; /* pointer to lowest device */ struct pci_dev *pdev; /* PCI device to get device ids */ + struct ishtp_driver_data *driver_data; /* pointer to driver-specific data */ /* waitq for waiting for suspend response */ wait_queue_head_t suspend_wait; From patchwork Mon May 6 01:30:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhang Lixu X-Patchwork-Id: 13654823 X-Patchwork-Delegate: jikos@jikos.cz Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.14]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 75623381AA for ; Mon, 6 May 2024 01:30:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.14 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714959052; cv=none; b=mBMrfflE6DKQL1KOZA4fA2CUGrJcUGTwCLLyg7RMq2NLRKUa5N7zCL3HbjVfsR5BgrE6mQwoBTiS5U6+td9g8cRyemzAYAg2ApIEor/1BwI3bkTCrNx2O2WwMm5zZ4gCdbMdOq1zect9OQszl+3VHeZj8vSHAOGMd2JWWW9qXQs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714959052; c=relaxed/simple; bh=gm+qttAIcoj00DzmsYcdM5NLisYQaT12lf3t/9TN4Qs=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=B2nssqya+kDOzIOJGJB2PRYy1sI969qESlv72EAqfKc6Sw6CwX5jmGVqalhTG8py0ZeZE1cxelNCvzPRl6UDB7cxQZqENgoBRMBKHF2HC78DJ+pJMUiD5Ggd+lH9tLwLOJFOiqOQsaMy9/gD3lNh/7GtwSQCWmFJPbwEOnnIQjw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=cYZvsvs2; arc=none smtp.client-ip=198.175.65.14 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="cYZvsvs2" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1714959051; x=1746495051; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=gm+qttAIcoj00DzmsYcdM5NLisYQaT12lf3t/9TN4Qs=; b=cYZvsvs2MIE/BsTwiethNyBwnk9u/CLOQlv8E2XRDQMlGUS5q4S5zGSm 4AghFmLRs/XhRBHFzwgQ4dUvFCfJvWLvOByn1D5AJn7uBkwTcxgFJAMUA Jr4SmuFOGuG8NrGJo8KFftfJ0rn59JjEwFxjNWmIVrmXQk6YW+FIvSPv2 pZpbEeXF7zcoB+lPAEj9hG0UYiiXbrG8u2FEJqbRUD5P0QqQE+fkU7FPB m9FIluaceKoVkOBIC/ssZf97fq2kMDGBxMfWR5bDviUUR2JSomJeyOuYY OUJMLDzApP1TLvN4ka6ZGHJT1XTTPFwWbTLhBLSk0rXuaSmL4k4obuyN5 Q==; X-CSE-ConnectionGUID: vgiRmBAlQIeyDJOdEK9cGQ== X-CSE-MsgGUID: WQt5d//aRh+7bQUz1m+RUA== X-IronPort-AV: E=McAfee;i="6600,9927,11064"; a="14503871" X-IronPort-AV: E=Sophos;i="6.07,257,1708416000"; d="scan'208";a="14503871" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 May 2024 18:30:50 -0700 X-CSE-ConnectionGUID: 6HqODHdcSTysL/XHKFvFkg== X-CSE-MsgGUID: mSyx6M/TTNeKNZ4tFtbigg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,257,1708416000"; d="scan'208";a="28092923" Received: from unknown (HELO ipg-l-lixuzha.sh.intel.com) ([10.239.153.157]) by fmviesa010.fm.intel.com with ESMTP; 05 May 2024 18:30:48 -0700 From: Zhang Lixu To: linux-input@vger.kernel.org, srinivas.pandruvada@linux.intel.com, jikos@kernel.org, benjamin.tissoires@redhat.com Cc: lixu.zhang@intel.com Subject: [PATCH 4/5] HID: intel-ish-hid: Implement loading firmware from host feature Date: Mon, 6 May 2024 09:30:39 +0800 Message-Id: <20240506013040.10700-5-lixu.zhang@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240506013040.10700-1-lixu.zhang@intel.com> References: <20240506013040.10700-1-lixu.zhang@intel.com> Precedence: bulk X-Mailing-List: linux-input@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 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. Introduce support for loading ISH main firmware from host. This feature is applicable for Lunar Lake and later generation. Current intel-ishtp-loader, is designed for Chrome OS based systems which uses core boot and has different firmware loading method. For non chrome systems the ISH firmware loading uses different method. Key differences include: 1. The new method utilizes ISHTP capability/fixed client to enumerate the firmware loader function. It does not require a connection or flow control, unlike the method used in Chrome OS, which is enumerated as an ISHTP dynamic client driver, necessitating connect/disconnect operations and flow control. 2. The new method employs a table to describe firmware fragments, which are sent to ISH in a single operation. Conversely, the Chrome OS method sends firmware fragments in multiple operations within a loop, sending only one fragment at a time. Additionally, address potential error scenarios to ensure graceful failure handling. - Firmware Not Found: Triggers if request_firmware() fails, leaving ISH in a waiting state. Recovery: Re-insmod the ISH drivers to retry. - DMA Buffer Allocation Failure: Occurs during prepare_dma_bufs(), leading to ISH waiting state. Allocated resources are released. Recovery: Re-insmod the ISH drivers to retry. - Incorrect Firmware Image: Causes ISH to refuse loading after three failed attempts. Recovery: A platform reset is required. Please refer to the [Documentation](Documentation/hid/intel-ish-hid.rst) for the details on flows. Signed-off-by: Zhang Lixu Acked-by: Srinivas Pandruvada --- drivers/hid/intel-ish-hid/Makefile | 1 + drivers/hid/intel-ish-hid/ishtp/hbm.c | 21 ++ drivers/hid/intel-ish-hid/ishtp/init.c | 8 + drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h | 11 + drivers/hid/intel-ish-hid/ishtp/loader.c | 275 ++++++++++++++++++++ drivers/hid/intel-ish-hid/ishtp/loader.h | 226 ++++++++++++++++ 6 files changed, 542 insertions(+) create mode 100644 drivers/hid/intel-ish-hid/ishtp/loader.c create mode 100644 drivers/hid/intel-ish-hid/ishtp/loader.h diff --git a/drivers/hid/intel-ish-hid/Makefile b/drivers/hid/intel-ish-hid/Makefile index f0a82b1c7cb9..a927b224cd44 100644 --- a/drivers/hid/intel-ish-hid/Makefile +++ b/drivers/hid/intel-ish-hid/Makefile @@ -11,6 +11,7 @@ intel-ishtp-objs += ishtp/client.o intel-ishtp-objs += ishtp/bus.o intel-ishtp-objs += ishtp/dma-if.o intel-ishtp-objs += ishtp/client-buffers.o +intel-ishtp-objs += ishtp/loader.o obj-$(CONFIG_INTEL_ISH_HID) += intel-ish-ipc.o intel-ish-ipc-objs := ipc/ipc.o diff --git a/drivers/hid/intel-ish-hid/ishtp/hbm.c b/drivers/hid/intel-ish-hid/ishtp/hbm.c index 9c031a06e4c4..8ee5467127d8 100644 --- a/drivers/hid/intel-ish-hid/ishtp/hbm.c +++ b/drivers/hid/intel-ish-hid/ishtp/hbm.c @@ -13,6 +13,7 @@ #include "ishtp-dev.h" #include "hbm.h" #include "client.h" +#include "loader.h" /** * ishtp_hbm_fw_cl_allocate() - Allocate FW clients @@ -570,6 +571,10 @@ void ishtp_hbm_dispatch(struct ishtp_device *dev, return; } + /* Start firmware loading process if it has loader capability */ + if (version_res->host_version_supported & ISHTP_SUPPORT_CAP_LOADER) + schedule_work(&dev->work_fw_loader); + dev->version.major_version = HBM_MAJOR_VERSION; dev->version.minor_version = HBM_MINOR_VERSION; if (dev->dev_state == ISHTP_DEV_INIT_CLIENTS && @@ -864,6 +869,20 @@ void recv_hbm(struct ishtp_device *dev, struct ishtp_msg_hdr *ishtp_hdr) return; } +/** + * ishtp_loader_recv_msg() - Receive a message from the ISHTP device + * @dev: The ISHTP device + * @buf: The buffer containing the message + */ +static void ishtp_loader_recv_msg(struct ishtp_device *dev, void *buf) +{ + if (dev->fw_loader_rx_buf) + memcpy(dev->fw_loader_rx_buf, buf, dev->fw_loader_rx_size); + + dev->fw_loader_received = true; + wake_up_interruptible(&dev->wait_loader_recvd_msg); +} + /** * recv_fixed_cl_msg() - Receive fixed client message * @dev: ISHTP device instance @@ -890,6 +909,8 @@ void recv_fixed_cl_msg(struct ishtp_device *dev, else dev_err(dev->devc, "unknown fixed client msg [%02X]\n", msg_hdr->cmd); + } else if (ishtp_hdr->fw_addr == ISHTP_LOADER_CLIENT_ADDR) { + ishtp_loader_recv_msg(dev, rd_msg_buf); } } diff --git a/drivers/hid/intel-ish-hid/ishtp/init.c b/drivers/hid/intel-ish-hid/ishtp/init.c index 02a00cc2dd11..07fdd52e4c5e 100644 --- a/drivers/hid/intel-ish-hid/ishtp/init.c +++ b/drivers/hid/intel-ish-hid/ishtp/init.c @@ -5,12 +5,14 @@ * Copyright (c) 2003-2016, Intel Corporation. */ +#include #include #include #include #include "ishtp-dev.h" #include "hbm.h" #include "client.h" +#include "loader.h" /** * ishtp_dev_state_str() -Convert to string format @@ -51,6 +53,8 @@ const char *ishtp_dev_state_str(int state) */ void ishtp_device_init(struct ishtp_device *dev) { + int ret; + dev->dev_state = ISHTP_DEV_INITIALIZING; INIT_LIST_HEAD(&dev->cl_list); INIT_LIST_HEAD(&dev->device_list); @@ -59,6 +63,7 @@ void ishtp_device_init(struct ishtp_device *dev) spin_lock_init(&dev->rd_msg_spinlock); init_waitqueue_head(&dev->wait_hbm_recvd_msg); + init_waitqueue_head(&dev->wait_loader_recvd_msg); spin_lock_init(&dev->read_list_spinlock); spin_lock_init(&dev->device_lock); spin_lock_init(&dev->device_list_lock); @@ -76,6 +81,9 @@ void ishtp_device_init(struct ishtp_device *dev) INIT_LIST_HEAD(&dev->read_list.list); + ret = devm_work_autocancel(dev->devc, &dev->work_fw_loader, ishtp_loader_work); + if (ret) + dev_err_probe(dev->devc, ret, "Failed to initialise FW loader work\n"); } EXPORT_SYMBOL(ishtp_device_init); diff --git a/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h b/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h index ed294bf0bc8f..181838c3d7ac 100644 --- a/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h +++ b/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h @@ -164,6 +164,17 @@ struct ishtp_device { struct hbm_version version; int transfer_path; /* Choice of transfer path: IPC or DMA */ + /* work structure for scheduling firmware loading tasks */ + struct work_struct work_fw_loader; + /* waitq for waiting for command response from the firmware loader */ + wait_queue_head_t wait_loader_recvd_msg; + /* indicating whether a message from the firmware loader has been received */ + bool fw_loader_received; + /* pointer to a buffer for receiving messages from the firmware loader */ + void *fw_loader_rx_buf; + /* size of the buffer pointed to by fw_loader_rx_buf */ + int fw_loader_rx_size; + /* ishtp device states */ enum ishtp_dev_state dev_state; enum ishtp_hbm_state hbm_state; diff --git a/drivers/hid/intel-ish-hid/ishtp/loader.c b/drivers/hid/intel-ish-hid/ishtp/loader.c new file mode 100644 index 000000000000..993f8b390e57 --- /dev/null +++ b/drivers/hid/intel-ish-hid/ishtp/loader.c @@ -0,0 +1,275 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * ISHTP firmware loader function + * + * Copyright (c) 2024, Intel Corporation. + * + * This module implements the functionality to load the main ISH firmware from the host, starting + * with the Lunar Lake generation. It leverages a new method that enhances space optimization and + * flexibility by dividing the ISH firmware into a bootloader and main firmware. + * + * Please refer to the [Documentation](Documentation/hid/intel-ish-hid.rst) for the details on + * flows. + * + * Additionally, address potential error scenarios to ensure graceful failure handling. + * - Firmware Image Not Found: + * Occurs when `request_firmware()` cannot locate the firmware image. The ISH firmware will + * remain in a state awaiting firmware loading from the host, with no further action from + * the ISHTP driver. + * Recovery: Re-insmod the ISH drivers allows for a retry of the firmware loading from the host. + * + * - DMA Buffer Allocation Failure: + * This happens if allocating a DMA buffer during `prepare_dma_bufs()` fails. The ISH firmware + * will stay in a waiting state, and the ISHTP driver will release any allocated DMA buffers and + * firmware without further actions. + * Recovery: Re-insmod the ISH drivers allows for a retry of the firmware loading from the host. + * + * - Incorrect Firmware Image: + * Using an incorrect firmware image will initiate the firmware loading process but will + * eventually be refused by the ISH firmware after three unsuccessful attempts, indicated by + * returning an error code. The ISHTP driver will stop attempting after three tries. + * Recovery: A platform reset is required to retry firmware loading from the host. + */ + +#define dev_fmt(fmt) "ISH loader: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hbm.h" +#include "loader.h" + +/** + * loader_write_message() - Write a message to the ISHTP device + * @dev: The ISHTP device + * @buf: The buffer containing the message + * @len: The length of the message + * + * Return: 0 on success, negative error code on failure + */ +static int loader_write_message(struct ishtp_device *dev, void *buf, int len) +{ + struct ishtp_msg_hdr ishtp_hdr = { + .fw_addr = ISHTP_LOADER_CLIENT_ADDR, + .length = len, + .msg_complete = 1, + }; + + dev->fw_loader_received = false; + + return ishtp_write_message(dev, &ishtp_hdr, buf); +} + +/** + * loader_xfer_cmd() - Transfer a command to the ISHTP device + * @dev: The ISHTP device + * @req: The request buffer + * @req_len: The length of the request + * @resp: The response buffer + * @resp_len: The length of the response + * + * Return: 0 on success, negative error code on failure + */ +static int loader_xfer_cmd(struct ishtp_device *dev, void *req, int req_len, + void *resp, int resp_len) +{ + struct loader_msg_header *req_hdr = req; + struct loader_msg_header *resp_hdr = resp; + struct device *devc = dev->devc; + int rv; + + dev->fw_loader_rx_buf = resp; + dev->fw_loader_rx_size = resp_len; + + rv = loader_write_message(dev, req, req_len); + if (rv < 0) { + dev_err(devc, "write cmd %u failed:%d\n", req_hdr->command, rv); + return rv; + } + + /* Wait the ACK */ + wait_event_interruptible_timeout(dev->wait_loader_recvd_msg, dev->fw_loader_received, + ISHTP_LOADER_TIMEOUT); + dev->fw_loader_rx_size = 0; + dev->fw_loader_rx_buf = NULL; + if (!dev->fw_loader_received) { + dev_err(devc, "wait response of cmd %u timeout\n", req_hdr->command); + return -ETIMEDOUT; + } + + if (!resp_hdr->is_response) { + dev_err(devc, "not a response for %u\n", req_hdr->command); + return -EBADMSG; + } + + if (req_hdr->command != resp_hdr->command) { + dev_err(devc, "unexpected cmd response %u:%u\n", req_hdr->command, + resp_hdr->command); + return -EBADMSG; + } + + if (resp_hdr->status) { + dev_err(devc, "cmd %u failed %u\n", req_hdr->command, resp_hdr->status); + return -EIO; + } + + return 0; +} + +/** + * release_dma_bufs() - Release the DMA buffer for transferring firmware fragments + * @dev: The ISHTP device + * @fragment: The ISHTP firmware fragment descriptor + * @dma_bufs: The array of DMA fragment buffers + * @fragment_size: The size of a single DMA fragment + */ +static void release_dma_bufs(struct ishtp_device *dev, + struct loader_xfer_dma_fragment *fragment, + void **dma_bufs, u32 fragment_size) +{ + int i; + + for (i = 0; i < FRAGMENT_MAX_NUM; i++) { + if (dma_bufs[i]) { + dma_free_coherent(dev->devc, fragment_size, dma_bufs[i], + fragment->fragment_tbl[i].ddr_adrs); + dma_bufs[i] = NULL; + } + } +} + +/** + * prepare_dma_bufs() - Prepare the DMA buffer for transferring firmware fragments + * @dev: The ISHTP device + * @ish_fw: The ISH firmware + * @fragment: The ISHTP firmware fragment descriptor + * @dma_bufs: The array of DMA fragment buffers + * @fragment_size: The size of a single DMA fragment + * + * Return: 0 on success, negative error code on failure + */ +static int prepare_dma_bufs(struct ishtp_device *dev, + const struct firmware *ish_fw, + struct loader_xfer_dma_fragment *fragment, + void **dma_bufs, u32 fragment_size) +{ + u32 offset = 0; + int i; + + for (i = 0; i < fragment->fragment_cnt && offset < ish_fw->size; i++) { + dma_bufs[i] = dma_alloc_coherent(dev->devc, fragment_size, + &fragment->fragment_tbl[i].ddr_adrs, GFP_KERNEL); + if (!dma_bufs[i]) + return -ENOMEM; + + fragment->fragment_tbl[i].length = clamp(ish_fw->size - offset, 0, fragment_size); + fragment->fragment_tbl[i].fw_off = offset; + memcpy(dma_bufs[i], ish_fw->data + offset, fragment->fragment_tbl[i].length); + clflush_cache_range(dma_bufs[i], fragment_size); + + offset += fragment->fragment_tbl[i].length; + } + + return 0; +} + +/** + * ishtp_loader_work() - Load the ISHTP firmware + * @work: The work structure + * + * The ISH Loader attempts to load firmware by sending a series of commands + * to the ISH device. If a command fails to be acknowledged by the ISH device, + * the loader will retry sending the command, up to a maximum of + * ISHTP_LOADER_RETRY_TIMES. + * + * After the maximum number of retries has been reached without success, the + * ISH bootloader will return an error status code and will no longer respond + * to the driver's commands. This behavior indicates that the ISH Loader has + * encountered a critical error during the firmware loading process. + * + * In such a case, where the ISH bootloader is unresponsive after all retries + * have been exhausted, a platform reset is required to restore communication + * with the ISH device and to recover from this error state. + */ +void ishtp_loader_work(struct work_struct *work) +{ + DEFINE_RAW_FLEX(struct loader_xfer_dma_fragment, fragment, fragment_tbl, FRAGMENT_MAX_NUM); + struct ishtp_device *dev = container_of(work, struct ishtp_device, work_fw_loader); + struct loader_xfer_query query = { + .header.command = LOADER_CMD_XFER_QUERY, + }; + struct loader_start start = { + .header.command = LOADER_CMD_START, + }; + union loader_recv_message recv_msg; + char *filename = dev->driver_data->fw_filename; + const struct firmware *ish_fw; + void *dma_bufs[FRAGMENT_MAX_NUM] = {}; + u32 fragment_size; + int retry = ISHTP_LOADER_RETRY_TIMES; + int rv; + + rv = request_firmware(&ish_fw, filename, dev->devc); + if (rv < 0) { + dev_err(dev->devc, "request firmware %s failed:%d\n", filename, rv); + return; + } + + fragment->fragment.header.command = LOADER_CMD_XFER_FRAGMENT; + fragment->fragment.xfer_mode = LOADER_XFER_MODE_DMA; + fragment->fragment.is_last = 1; + fragment->fragment.size = ish_fw->size; + /* Calculate the size of a single DMA fragment */ + fragment_size = PFN_ALIGN(DIV_ROUND_UP(ish_fw->size, FRAGMENT_MAX_NUM)); + /* Calculate the count of DMA fragments */ + fragment->fragment_cnt = DIV_ROUND_UP(ish_fw->size, fragment_size); + + rv = prepare_dma_bufs(dev, ish_fw, fragment, dma_bufs, fragment_size); + if (rv) { + dev_err(dev->devc, "prepare DMA buffer failed.\n"); + goto out; + } + + do { + query.image_size = ish_fw->size; + rv = loader_xfer_cmd(dev, &query, sizeof(query), recv_msg.raw_data, + sizeof(struct loader_xfer_query_ack)); + if (rv) + continue; /* try again if failed */ + + dev_dbg(dev->devc, "ISH Version %u.%u.%u.%u\n", + recv_msg.query_ack.version_major, + recv_msg.query_ack.version_minor, + recv_msg.query_ack.version_hotfix, + recv_msg.query_ack.version_build); + + rv = loader_xfer_cmd(dev, fragment, + struct_size(fragment, fragment_tbl, fragment->fragment_cnt), + recv_msg.raw_data, sizeof(struct loader_xfer_fragment_ack)); + if (rv) + continue; /* try again if failed */ + + rv = loader_xfer_cmd(dev, &start, sizeof(start), recv_msg.raw_data, + sizeof(struct loader_start_ack)); + if (rv) + continue; /* try again if failed */ + + dev_info(dev->devc, "firmware loaded. size:%zu\n", ish_fw->size); + break; + } while (--retry); + +out: + release_dma_bufs(dev, fragment, dma_bufs, fragment_size); + release_firmware(ish_fw); +} diff --git a/drivers/hid/intel-ish-hid/ishtp/loader.h b/drivers/hid/intel-ish-hid/ishtp/loader.h new file mode 100644 index 000000000000..7aa45ebc3f7b --- /dev/null +++ b/drivers/hid/intel-ish-hid/ishtp/loader.h @@ -0,0 +1,226 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * ISHTP firmware loader header + * + * Copyright (c) 2024, Intel Corporation. + */ + +#ifndef _ISHTP_LOADER_H_ +#define _ISHTP_LOADER_H_ + +#include +#include +#include + +#include "ishtp-dev.h" + +struct work_struct; + +#define LOADER_MSG_SIZE \ + (IPC_PAYLOAD_SIZE - sizeof(struct ishtp_msg_hdr)) + +/* + * ISHTP firmware loader protocol definition + */ +#define LOADER_CMD_XFER_QUERY 0 /* SW -> FW */ +#define LOADER_CMD_XFER_FRAGMENT 1 /* SW -> FW */ +#define LOADER_CMD_START 2 /* SW -> FW */ + +/* Only support DMA mode */ +#define LOADER_XFER_MODE_DMA BIT(0) + +/** + * struct loader_msg_header - ISHTP firmware loader message header + * @command: Command type + * @is_response: Indicates if the message is a response + * @has_next: Indicates if there is a next message + * @reserved: Reserved for future use + * @status: Status of the message + */ +struct loader_msg_header { + __le32 command:7; + __le32 is_response:1; + __le32 has_next:1; + __le32 reserved:15; + __le32 status:8; +}; + +/** + * struct loader_xfer_query - ISHTP firmware loader transfer query packet + * @header: Header of the message + * @image_size: Size of the image + */ +struct loader_xfer_query { + struct loader_msg_header header; + __le32 image_size; +}; + +/** + * struct loader_version - ISHTP firmware loader version + * @value: Value of the version + * @major: Major version + * @minor: Minor version + * @hotfix: Hotfix version + * @build: Build version + */ +struct loader_version { + union { + __le32 value; + struct { + __u8 major; + __u8 minor; + __u8 hotfix; + __u8 build; + }; + }; +}; + +/** + * struct loader_capability - ISHTP firmware loader capability + * @max_fw_image_size: Maximum firmware image size + * @support_mode: Support mode + * @reserved: Reserved for future use + * @platform: Platform + * @max_dma_buf_size: Maximum DMA buffer size, multiples of 4096 + */ +struct loader_capability { + __le32 max_fw_image_size; + __le16 support_mode; + __u8 reserved; + __u8 platform; + __le32 max_dma_buf_size; +}; + +/** + * struct loader_xfer_query_ack - ISHTP firmware loader transfer query acknowledgment + * @header: Header of the message + * @version_major: ISH Major version + * @version_minor: ISH Minor version + * @version_hotfix: ISH Hotfix version + * @version_build: ISH Build version + * @protocol_version: Protocol version + * @loader_version: Loader version + * @capability: Loader capability + */ +struct loader_xfer_query_ack { + struct loader_msg_header header; + __le16 version_major; + __le16 version_minor; + __le16 version_hotfix; + __le16 version_build; + __le32 protocol_version; + struct loader_version loader_version; + struct loader_capability capability; +}; + +/** + * struct loader_xfer_fragment - ISHTP firmware loader transfer fragment + * @header: Header of the message + * @xfer_mode: Transfer mode + * @offset: Offset + * @size: Size + * @is_last: Is last + */ +struct loader_xfer_fragment { + struct loader_msg_header header; + __le32 xfer_mode; + __le32 offset; + __le32 size; + __le32 is_last; +}; + +/** + * struct loader_xfer_fragment_ack - ISHTP firmware loader transfer fragment acknowledgment + * @header: Header of the message + */ +struct loader_xfer_fragment_ack { + struct loader_msg_header header; +}; + +/** + * struct fragment_dscrpt - ISHTP firmware loader fragment descriptor + * @ddr_adrs: The address in host DDR + * @fw_off: The offset of the fragment in the fw image + * @length: The length of the fragment + */ +struct fragment_dscrpt { + __le64 ddr_adrs; + __le32 fw_off; + __le32 length; +}; + +#define FRAGMENT_MAX_NUM \ + ((LOADER_MSG_SIZE - sizeof(struct loader_xfer_dma_fragment)) / \ + sizeof(struct fragment_dscrpt)) + +/** + * struct loader_xfer_dma_fragment - ISHTP firmware loader transfer DMA fragment + * @fragment: Fragment + * @fragment_cnt: How many descriptors in the fragment_tbl + * @fragment_tbl: Fragment table + */ +struct loader_xfer_dma_fragment { + struct loader_xfer_fragment fragment; + __le32 fragment_cnt; + struct fragment_dscrpt fragment_tbl[] __counted_by(fragment_cnt); +}; + +/** + * struct loader_start - ISHTP firmware loader start + * @header: Header of the message + */ +struct loader_start { + struct loader_msg_header header; +}; + +/** + * struct loader_start_ack - ISHTP firmware loader start acknowledgment + * @header: Header of the message + */ +struct loader_start_ack { + struct loader_msg_header header; +}; + +union loader_recv_message { + struct loader_xfer_query_ack query_ack; + struct loader_xfer_fragment_ack fragment_ack; + struct loader_start_ack start_ack; + __u8 raw_data[LOADER_MSG_SIZE]; +}; + +/* + * ISHTP firmware loader internal use + */ +/* ISHTP firmware loader command timeout */ +#define ISHTP_LOADER_TIMEOUT msecs_to_jiffies(100) + +/* ISHTP firmware loader retry times */ +#define ISHTP_LOADER_RETRY_TIMES 3 + +/** + * struct ish_firmware_variant - ISH firmware variant + * @device: PCI Device ID + * @filename: The firmware file name + */ +struct ish_firmware_variant { + unsigned short device; + const char *filename; +}; + +/* + * ISHTP firmware loader API for ISHTP hbm + */ + +/* ISHTP capability bit for firmware loader */ +#define ISHTP_SUPPORT_CAP_LOADER BIT(4) + +/* Firmware loader address */ +#define ISHTP_LOADER_CLIENT_ADDR 16 + +/** + * ishtp_loader_work - The work function to start the firmware loading process + * @work: The work structure + */ +void ishtp_loader_work(struct work_struct *work); + +#endif /* _ISHTP_LOADER_H_ */ From patchwork Mon May 6 01:30:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhang Lixu X-Patchwork-Id: 13654825 X-Patchwork-Delegate: jikos@jikos.cz Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.14]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D05AA3BBFF for ; Mon, 6 May 2024 01:30:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.14 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714959055; cv=none; b=UwrEA40w5pOKAvLANeAAZ++w0nLgYWVjPAZcVdmhiERUKcreqK+Dr0DHUS19aB2HhNNBIO7KQH5vhZv2mxGjQtpDiPECMXoaIyvxgMyJxUiFfUisngTQGGTm7LhCg/fHHmdaUvEcr8rE01BgPtjCV5G3w+zbWbaGiLTX5WcbOEg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714959055; c=relaxed/simple; bh=FiM+puNJNqGWXVrLxkZrBbWhRMgcc8dtVC2049Q8vHY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=F3sWX/wW4D9jVOHx//4A/7twpDqe27zbn5AzIuRhHIgd7i1DBFKOtOjQRmvf7HsQ2lIdVddp/dQciqrdopl1/Oh3vPTw9+KLPxb8Yi596/3ECJAn+SfJ8ViqDDAX5uHqfFGn4kKOEUk7OVWsII6Up2TrizCaplG6v7B6/Lz8AJ4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=iMOytEP/; arc=none smtp.client-ip=198.175.65.14 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="iMOytEP/" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1714959052; x=1746495052; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=FiM+puNJNqGWXVrLxkZrBbWhRMgcc8dtVC2049Q8vHY=; b=iMOytEP/nXCY/PvYX5weHonhvnSkByqyP8Ok1vgQsIytx/c2sZcCmHRt RE9/hpIPI0l4Yk6w0eRgdtFUseOtK7ZUYVzi1s6wDrM5Y8mGqhLlnM1ZK mEg/82XAV7TGbpkdSBRh+2MdhCQJgMLjrYduBODIXhPiV/1uuumBAtZjv ld9G5e0kIwGFByUwXItWv2hGkXOCvGO4X6vq4bKlyOpIh8FWPCpPyNAoV aDoxvhx5ocRvri536ZLcGFrF/9tSlGtBvobj+GnXfLVy72bGjbxaBOVNE j1IUTVi6Md09/rLsAMbFlfjDRfOp+us1ElyoEaZAIDCuDv41vewH3dbRf g==; X-CSE-ConnectionGUID: 31d8EabCT/qSalS6PPNe3w== X-CSE-MsgGUID: uXSW3RcFQPiloMvwpuJ6dA== X-IronPort-AV: E=McAfee;i="6600,9927,11064"; a="14503874" X-IronPort-AV: E=Sophos;i="6.07,257,1708416000"; d="scan'208";a="14503874" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 May 2024 18:30:52 -0700 X-CSE-ConnectionGUID: egAbinSJRRW8qYH2VyfaOg== X-CSE-MsgGUID: ABQfRw0bQCu6nRQWpLiV6Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,257,1708416000"; d="scan'208";a="28092929" Received: from unknown (HELO ipg-l-lixuzha.sh.intel.com) ([10.239.153.157]) by fmviesa010.fm.intel.com with ESMTP; 05 May 2024 18:30:50 -0700 From: Zhang Lixu To: linux-input@vger.kernel.org, srinivas.pandruvada@linux.intel.com, jikos@kernel.org, benjamin.tissoires@redhat.com Cc: lixu.zhang@intel.com Subject: [PATCH 5/5] HID: intel-ish-hid: handler multiple MNG_RESET_NOTIFY messages Date: Mon, 6 May 2024 09:30:40 +0800 Message-Id: <20240506013040.10700-6-lixu.zhang@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240506013040.10700-1-lixu.zhang@intel.com> References: <20240506013040.10700-1-lixu.zhang@intel.com> Precedence: bulk X-Mailing-List: linux-input@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This patch enhances the firmware reset handler in the Intel Integrated Sensor Hub (ISH) driver. Previously, the ISH firmware would send a MNG_RESET_NOTIFY message in response to an empty IPC message from the ish_wakeup function. With the introduction of the feature to load ISH firmware from the host on the LunarLake platform, the ISH bootloader now involves the IPC function. This results in an additional MNG_RESET_NOTIFY message being sent by ISH bootloader after power on. Consequently, the driver receives two MNG_RESET_NOTIFY messages during system boot up. This can disrupt the dev->dev_state during the first reset flow due to the subsequent reset notify message. To address this, the patch modifies the fw_reset_work_fn function to skip the execution of ishtp_reset_compl_handler during the first reset flow if a reset is pending. The ishtp_reset_compl_handler will then be executed during the second reset flow, ensuring the dev->dev_state is not disrupted. Signed-off-by: Zhang Lixu Acked-by: Srinivas Pandruvada --- drivers/hid/intel-ish-hid/ipc/ipc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/hid/intel-ish-hid/ipc/ipc.c b/drivers/hid/intel-ish-hid/ipc/ipc.c index adce30f8ebff..3cd53fc80634 100644 --- a/drivers/hid/intel-ish-hid/ipc/ipc.c +++ b/drivers/hid/intel-ish-hid/ipc/ipc.c @@ -546,11 +546,11 @@ static int ish_fw_reset_handler(struct ishtp_device *dev) /** * fw_reset_work_fn() - FW reset worker function - * @unused: not used + * @work: Work item * * Call ish_fw_reset_handler to complete FW reset */ -static void fw_reset_work_fn(struct work_struct *unused) +static void fw_reset_work_fn(struct work_struct *work) { int rv; @@ -562,7 +562,8 @@ static void fw_reset_work_fn(struct work_struct *unused) wake_up_interruptible(&ishtp_dev->wait_hw_ready); /* ISHTP notification in IPC_RESET sequence completion */ - ishtp_reset_compl_handler(ishtp_dev); + if (!work_pending(work)) + ishtp_reset_compl_handler(ishtp_dev); } else dev_err(ishtp_dev->devc, "[ishtp-ish]: FW reset failed (%d)\n", rv);