From nobody Tue Jun 16 05:19:42 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (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 5F38937BE7D for ; Thu, 16 Apr 2026 14:10:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776348610; cv=none; b=NqTQoTu4AYl3F72lrFPsR3+HgEuaqQi9jQBhVfvc1CiYDJF38KuVBRRaihIZhRjZyq5oOAxo0g9tTGa/piFst72mlPd9SnZWlFNov03+DYX9vq9aH+6PxoV7NXNgyanVCRp/oDfRU+IyRYJMJVbVz4B6EJh9Wib6pq3ZThqkoXQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776348610; c=relaxed/simple; bh=KJI7ZVP46GsvQBICzMva6qA6JZ1rp835Edcq69Cmckk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=pLnJfqsjVzYlCSmb6M5qXAq3oOLo9baeqAzVJ8edS2zmnfbq3IIt9wlI4K6KCXJ+R267vfEHbPhH4Hwn+9jXzY1qcnv+FNaloirpbNPcF5RHPctGewaFl/MSbkao4/Lhh2x2XikFgbq5asHviJFzuKt8LhLnuIi/hxRc/l9lvBQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=llXpGCjV; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=J1jU8v3K; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="llXpGCjV"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="J1jU8v3K" Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 63GDqciI2596135 for ; Thu, 16 Apr 2026 14:10:06 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= oDNxIf2aOeOAEs1uuuhsACboB5Z3XGXOKAwTkkNVu4w=; b=llXpGCjVbIAynPSm e1NZEJgzWJAHJajSiN6qxihrmhB/uF3wTo72vZ/WVTfndxHJ6CTymmL+wcP318dM LY8KKlaBLN0f5N3UOsYAN5NZH65EySawQtEzI+uQUcpTpOvTKRbBxxNm/L4fpmcJ XG9LiRbtR/z+GfrIVzYi4UkrW3Jv2f93hf1lw90gSRk8zmI9+dRmKsUmfroM2rHJ CNt4xX+/yPkQA7FlnaTnMB/pyNckivONCJsxUyP0FEkKCIwYPQRkOrcdUJ0weUZk Y+aXyWRQC+Sj7ZfakT/6WCNrHxpHt2DrHopBJEtRaEbkX0ExsUwT8ePG9vMMY2dp 2bSASA== Received: from mail-yx1-f69.google.com (mail-yx1-f69.google.com [74.125.224.69]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4dk11r822q-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 16 Apr 2026 14:10:06 +0000 (GMT) Received: by mail-yx1-f69.google.com with SMTP id 956f58d0204a3-6501528b1caso6167624d50.2 for ; Thu, 16 Apr 2026 07:10:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1776348605; x=1776953405; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=oDNxIf2aOeOAEs1uuuhsACboB5Z3XGXOKAwTkkNVu4w=; b=J1jU8v3K9lUJ5qpGLH10u4WsgJ34ZGoUfNFlcIpbz6rvOtK9VRnvHNjnaXEui8YXEu o4dblPX2WccZymW+arCV9dLgQutPEphUOGDVY6fhsnsr7ckeHvEWmSToLeDAGf9EUuQU /NXyRIyBGzjX6lsF5YH3q/oBkw9IR9jYnkly9/xw41353D0qCoWHnXUrpNi6+jN3vYFp 31AEJuWE5SS60lcUBT2+Ah/RPTFEEBmp846mMlvFDhcVEK09R7EZlIhMRQlWyNnlvFKd 4WmJGokd3CUFjwsqzQOqQIIi/tsQBUzAV6K3JUbxAvK1WMric4PmGEhDNN1Z0hwId+lS RImg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776348605; x=1776953405; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=oDNxIf2aOeOAEs1uuuhsACboB5Z3XGXOKAwTkkNVu4w=; b=L93aNioWKNAjImCkerSOixYLUD+bAFzFH6bz/wE08hxOSzeJsq2sKArNs5qnKMMWSC Sl0Klovhfl933wwYtqpArot2rXK5OdMSdnUW3W3Ga0L6BlQQvOsN00jH227o8Aev/Zy4 927vNkcq7/ZvHbQGRKXARhbKujZbsOMDIXg5RcfZKZ3Z2Jf/Oxdr8Hpyk/HcvZ1h3JI0 SRBVBmB6ZkDotYeWhPKOTIvXaWJb6Cabjvtq+cbcOjeyXR0wyWt9I8XI6ncFPevJlaBz SbJlYc62O3EHMqMrBwe0t0C1j5gl7tV6nYOMvXfMW6Plehsrw6GVY8mGHS59knB+g3p2 DeUA== X-Forwarded-Encrypted: i=1; AFNElJ9cA2SrIXEmxAWD/SnSvO6vRPgvppJzhfUcZjeZ8PjIQULWbnIALwWWmtKmkX/XWnRnhNcte0wFMsZYdyE=@vger.kernel.org X-Gm-Message-State: AOJu0Yyq+ZtK3+OCKRwQBVNFr3lLuuVUwsmZQbJE3lKv3zn0w+EQa+ro 2pRraXnuk0iZ8nqjoZSMyrdxJoAFwMCDeyI0tHIHn1dKQMyFoxbhAETmPQGE2rTNuI3UztJ1j6y yOeiOtXP2CWeZxJ5UgNTkwHTAaGbSI6qG0KLFuydgL0CzVNFGSZh7jWFMlWhi68phku0= X-Gm-Gg: AeBDietTf/jGhyy6mHL3PWmeuoObVoHl/Vpe5w0nGNuir7SxdkNQnemQU7jzf7sxEXB TRmH+AUtQt3DV8Ymj/1CeOhZPMGKqSuYVC4tm5CRiU+lWIhYW9xD7GNHxTd9xRQqj7Fq58sUdeb 1IggePGsVt9nxugyCwV3qzOOHPCnqfXIm71cWbWZC11nwO/0ZnWmx6k7ea08ike2hd7qsMt+Kvc 1nTXxYDqzrS1skriZpSQzmA39vy26SWvjPSJBgL+JCM/BosQbO8PZLY/Zk5xfA7gin7rsvDoRHU EaxuVbHcu2HQQhCClZNWTNJ+Msj0aUik5Ro914gwjxMiMj7gPNMI3LHDQKZW+5GYmbDJGsQTIC+ GVrjTG+buCRjVvzmJ/AEtkgEzrZdSlzRm7LJw6jO/jNtq9DTU6s4= X-Received: by 2002:a05:690e:13cb:b0:651:bcb6:8894 with SMTP id 956f58d0204a3-651bcb68b04mr18461442d50.12.1776348603654; Thu, 16 Apr 2026 07:10:03 -0700 (PDT) X-Received: by 2002:a05:690e:13cb:b0:651:bcb6:8894 with SMTP id 956f58d0204a3-651bcb68b04mr18461343d50.12.1776348602312; Thu, 16 Apr 2026 07:10:02 -0700 (PDT) Received: from hu-batta-hyd.qualcomm.com ([202.46.23.25]) by smtp.gmail.com with ESMTPSA id 956f58d0204a3-652e47ba4a3sm2084691d50.17.2026.04.16.07.09.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Apr 2026 07:10:01 -0700 (PDT) From: Kishore Batta Date: Thu, 16 Apr 2026 19:39:42 +0530 Subject: [PATCH v5 1/7] Add documentation for Sahara protocol Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260416-sahara_protocol_new_v2-v5-1-6aebf005e4ba@oss.qualcomm.com> References: <20260416-sahara_protocol_new_v2-v5-0-6aebf005e4ba@oss.qualcomm.com> In-Reply-To: <20260416-sahara_protocol_new_v2-v5-0-6aebf005e4ba@oss.qualcomm.com> To: Jonathan Corbet , Shuah Khan , Jeff Hugo , Carl Vanderlip , Oded Gabbay , Manivannan Sadhasivam Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, mhi@lists.linux.dev, Kishore Batta X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1776348592; l=70392; i=kishore.batta@oss.qualcomm.com; s=20260206; h=from:subject:message-id; bh=KJI7ZVP46GsvQBICzMva6qA6JZ1rp835Edcq69Cmckk=; b=IqNYu/AIXCQjKBkk8WMpOYCaJYZNKb3EgP4K7nugw2LYkxyZ78gHDh2dB5//AhktEAh5RBY0P ubd/uAMOpmNCkkuSDiOzYqQ15Z5TZpwgqttu8N61KymBWF4zWZNTZHQ X-Developer-Key: i=kishore.batta@oss.qualcomm.com; a=ed25519; pk=vJo8RvTf+HZpRLK2oOIljmbn9l3zFkibCGh+blaqZCw= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNDE2MDEzNiBTYWx0ZWRfX/eoytZemNWPJ x7Qtz1bGDaQR+kSyEX4ycDV5icLEXDdu9G3+DrLkB/2OZvMUKS1R6Bhs4nqauyarZpSn1ckfcFr Ml7Uc33tqZs85vuNrX0R0cU3IhqAP/hpQCI2AJbZ7vPBl1tzXpj+9hXsbjXCEEoHXymlHASxQdv cjhIPI2E2HfGiX09/UxhU42NNTQ4lqZZkAgjq47j9Yo12Q7x6Za1eiyfzl4wXE5/W3uVM0TmcPl xkjwPBjznpxbYExsqGuBTAlYsUUiY2Ri/QTXoQEQOBPkXgjMmF8GnE1jcvcyOagfWjnl1lPVeh9 zv0kUiRJ9q5FA5dkkTFO9BTZKxjnvtHv1Bq2heTXi443PqF3BDEWRfEgdpkJzFZDk0GreAOZO82 ce3cJfTB+q6C/Z0jsXgP/mYAgjhQ7absG+Q1Oiz+wCACzBQce2VJCvDVFWBatVn3d8Z+flrdBVU A1yfA/cIaVg0eBj8fUg== X-Authority-Analysis: v=2.4 cv=ZPznX37b c=1 sm=1 tr=0 ts=69e0edbe cx=c_pps a=J+5FMm3BkXb42VdG8aMU9w==:117 a=ZePRamnt/+rB5gQjfz0u9A==:17 a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=eoimf2acIAo5FJnRuUoq:22 a=EUspDBNiAAAA:8 a=MMUwo3wwYuTaqRZ-dQsA:9 a=t_MdwZQk9VBQcGG5:21 a=QEXdDO2ut3YA:10 a=Epx66wHExT0cjJnnR-oj:22 X-Proofpoint-ORIG-GUID: 7NksRFk6UtdEJ8tJuw2JRafTWAfcHt93 X-Proofpoint-GUID: 7NksRFk6UtdEJ8tJuw2JRafTWAfcHt93 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-04-16_03,2026-04-16_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 priorityscore=1501 suspectscore=0 lowpriorityscore=0 spamscore=0 adultscore=0 bulkscore=0 malwarescore=0 clxscore=1015 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604070000 definitions=main-2604160136 Introduce documentation for the Sahara protocol, describing its operational modes and their respective functions. The image transfer mode enables firmware transfer from host to device. The memory debug mode allows extraction of device memory contents to host. The command mode facilitates retrieval of DDR training data from the device and also to restore the training data back to device in subsequent boot of device to save boot time. Signed-off-by: Kishore Batta --- Documentation/mhi/index.rst | 1 + Documentation/mhi/sahara_protocol.rst | 1241 +++++++++++++++++++++++++++++= ++++ 2 files changed, 1242 insertions(+) diff --git a/Documentation/mhi/index.rst b/Documentation/mhi/index.rst index 0aa00482aa2e2d7ec4941154a8c6947dc0a0ac40..39a38978398b81727514ec95dee= 4e060a1063b34 100644 --- a/Documentation/mhi/index.rst +++ b/Documentation/mhi/index.rst @@ -9,3 +9,4 @@ MHI =20 mhi topology + sahara_protocol diff --git a/Documentation/mhi/sahara_protocol.rst b/Documentation/mhi/saha= ra_protocol.rst new file mode 100644 index 0000000000000000000000000000000000000000..bea72a98b9529ee7d5ce875b00d= da5665237830a --- /dev/null +++ b/Documentation/mhi/sahara_protocol.rst @@ -0,0 +1,1241 @@ +.. SPDX-License-Identifier: GPL-2.0-only + + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D +Sahara protocol Specification +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D + +The Qualcomm Sahara protocol driver is primarily designed for transferring +software images from a host device to a target device using a simplified d= ata +transfer mechanism over a link. However, the Sahara protocol does not supp= ort +any authentication/validation of the data sent between devices. Such a mec= hanism +is beyond the scope of the protocol. + +The Sahara protocol defines two types of packets - Command packet and Data +packet. + +Command packet +-------------- + These packets are sent between the host and the target to setup transfer= s of + data packets. The command packets contain a command ID and packet length. + Depending on the command, the packet may contain additional command spec= ific + field. + ++-------------+---------------+----------------+----------------+ +| Command ID | Packet length | Optional field | Optional field | ++-------------+---------------+----------------+----------------+ + +Data packet +----------- + The data packets contain RAW data as shown below. + ++---------------------------------------------------------+ +| RAW Data (arbitrary number of bytes) | ++---------------------------------------------------------+ + +Command packet optional fields +------------------------------ + ++---------+---------------+---------+-------------------------------------= ----+ +| ID val | Field | Sent by | Description = | ++---------+---------------+---------+-------------------------------------= ----+ +| 0x0 | - | - | Invalid = | ++---------+---------------+---------+-------------------------------------= ----+ +| 0x1 | Hello packet | Target | Initializes connection and protocol = | ++---------+---------------+---------+-------------------------------------= ----+ +| 0x2 | Hello response| Host | Acknowledges connection and protocol= | +| | | | sent by target. Also used to set mod= e of| +| | | | operation for target to execute. = | ++---------+---------------+---------+-------------------------------------= ----+ +| 0x3 | Read data | Target | Reads specified number of bytes from= | +| | | | host for a given image. = | ++---------+---------------+---------+-------------------------------------= ----+ +| 0x4 | End of image | Target | Indicates host that the single image= tx | +| | transfer | | is complete. Also used to indicate a= | +| | | | target failure during an image trans= fer | ++---------+---------------+---------+-------------------------------------= ----+ +| 0x5 | Done packet | Host | Sends acknowledgment from host that = a | +| | | | single image transfer is complete. = | ++---------+---------------+---------+-------------------------------------= ----+ +| 0x6 | Done response | Target | Provides the following information t= o | +| | | | host. = | +| | | | 1. Target is exiting protocol = | +| | | | 2. Whether the target expects to = | +| | | | re-enter protocol to transfer anothe= r | +| | | | image. = | ++---------+---------------+---------+-------------------------------------= ----+ +| 0x7 | Reset packet | Host | Instructs target to perform a reset.= | ++---------+---------------+---------+-------------------------------------= ----+ +| 0x8 | Reset response| Target | Indicates host that target is about = to | +| | | | reset. = | ++---------+---------------+---------+-------------------------------------= ----+ +| 0x9 | Memory debug | Target | Indicates host that target has enter= ed | +| | packet | | a debug mode where it is ready to = | +| | | | transfer its system memory contents = | ++---------+---------------+---------+-------------------------------------= ----+ +| 0xA | Memory read | Host | Reads specified number of bytes from= | +| | packet | | target's system memory, starting fro= m a | +| | | | specified address. = | ++---------+---------------+---------+-------------------------------------= ----+ +| 0xB | Command ready | Target | Indicates host that target is ready = to | +| | packet | | receive client commands. = | ++---------+---------------+---------+-------------------------------------= ----+ +| 0xC | Command switch| Host | Indicates target to switch modes. = | +| | mode packet | | 1. Image transfer pending mode. = | +| | | | 2. Image transfer complete mode. = | +| | | | 3. Memory debug mode. = | +| | | | 4. Command mode. = | ++---------+---------------+---------+-------------------------------------= ----+ +| 0xD | Command | Host | Indicates target to execute a given = | +| | execute packet| | client command. = | ++---------+---------------+---------+-------------------------------------= ----+ +| 0xE | Command | Target | Indicates host that target has execu= ted | +| | execute | | client command. Also used to indicat= e | +| | response | | status of executed command. = | +| | packet | | = | ++---------+---------------+---------+-------------------------------------= ----+ +| 0xF | Command | Host | Indicates target that host is ready = to | +| | execute | | receive data resulting from executin= g | +| | data | | previous client command. = | +| | packet | | = | ++---------+---------------+---------+-------------------------------------= ----+ +| 0x10 | 64 bit Memory | Target | Indicates host that target has enter= ed | +| | debug packet | | a debug mode where it is ready to = | +| | | | transfer its 64 bit system memory = | +| | | | contents. = | ++---------+---------------+---------+-------------------------------------= ----+ +| 0x11 | 64 bit Memory | Host | Reads specified number of bytes from= | +| | read packet | | target's system memory, starting fro= m a | +| | | | 64 bit specified address. = | ++---------+---------------+---------+-------------------------------------= ----+ +| 0x12 | 64 bit Read | Target | Reads specified number of bytes from= | +| | data | | host for a given 64 bit image. = | ++---------+---------------+---------+-------------------------------------= ----+ +| 0x13 | Reset Sahara | Host | Resets Sahara state machine and ente= rs | +| | sate machine | | Sahara entry without target reset = | +| | packet | | = | ++---------+---------------+---------+-------------------------------------= ----+ +| 0x14 | Write data | Target | Writes specified number of bytes to = host| +| | packet | | for a given image = | ++---------+---------------+---------+-------------------------------------= ----+ +| Others | - | - | Invalid = | ++---------+---------------+---------+-------------------------------------= ----+ + + +Hello Packet +------------ + +The hello packet is the first packet that the target sends to the host. If= the +host receives any other packet, it sends a reset command to the target. Wh= en the +host receives a valid hello packet, it first verifies that the protocol ru= nning +on the target is compatible with the protocol running on the host. If the +protocol mismatch, the host sends a reset command to the target. The targe= t uses +the following format while sending a hello packet. + ++-----------+-------------+--------------------------------------+ +| Field | Length | Description | +| | (bytes) | | ++-----------+-------------+--------------------------------------+ +| Command | 4 | Command identifier code | ++-----------+-------------+--------------------------------------+ +| Length | 4 | Length of the packet(in bytes) | ++-----------+-------------+--------------------------------------+ +| Version | 4 | Version number of this protocol | ++-----------+-------------+--------------------------------------+ +| Version | 4 | Lowest Compatible version | +| Compatible| | | ++-----------+-------------+--------------------------------------+ +| Command | 4 | Maximum command packet length | +| packet | | (in bytes) the protocol supports. | +| length | | | ++-----------+-------------+--------------------------------------+ +| Mode | 4 | Expected mode of target operation | ++-----------+-------------+--------------------------------------+ +| Reserved | 4 | Reserved for future use. | ++-----------+-------------+--------------------------------------+ +| Reserved | 4 | Reserved for future use. | ++-----------+-------------+--------------------------------------+ +| Reserved | 4 | Reserved for future use. | ++-----------+-------------+--------------------------------------+ +| Reserved | 4 | Reserved for future use. | ++-----------+-------------+--------------------------------------+ +| Reserved | 4 | Reserved for future use. | ++-----------+-------------+--------------------------------------+ +| Reserved | 4 | Reserved for future use. | ++-----------+-------------+--------------------------------------+ + +The target also sends the following information: + 1. Maximum length of the command packet that it supports. The host uses = this + information to avoid sending more bytes than the target can support i= n the + receiving command buffer. + 2. Mode of operation it expects to enter, based on the boot up sequence.= The + supported modes of operation for the target are as follows: + ++-----------------------------+---------+---------------------------------= ---+ +| Mode | Mode ID | Description = | ++-----------------------------+---------+---------------------------------= ---+ +| SAHARA_MODE_IMAGE_TX_PENDING| 0x0 | Image transfer is in the pending= | +| | | mode. Transfer image from the ho= st.| +| | | After completion, the host shoul= d | +| | | expect another image transfer = | +| | | request. = | ++-----------------------------+---------+---------------------------------= ---+ +|SAHARA_MODE_IMAGE_TX_COMPLETE| 0x1 | Image transfer is in the complet= e | +| | | mode. Transfer image from the ho= st.| +| | | After completion, the host shoul= d | +| | | not expect another image transfe= r | +| | | request. = | ++-----------------------------+---------+---------------------------------= ---+ +| SAHARA_MODE_MEMORY_DBEUG | 0x2 | Memory debug mode. The host shou= ld | +| | | prepare to receive a memory dump= | +| | | from the target. = | ++-----------------------------+---------+---------------------------------= ---+ +| SAHARA_MODE_COMMAND | 0x3 | Command mode. The host executes = | +| | | operations on the target by send= ing| +| | | the appropriate client command t= o | +| | | the Sahara client running on the= | +| | | target. The Sahar client interpr= ets| +| | | the client command and the respo= nse| +| | | is sent after execution of the = | +| | | given command. = | ++-----------------------------+---------+---------------------------------= ---+ + +Hello response packet +--------------------- + +After the host validates the protocol running on the target, it sends a re= sponse +to the target. The response contains the following information. +1. The protocol version that is running. +2. The minimum protocol version that it supports. +3. The mode of operation. + +The host sets the packet status field to success if no errors occur on the= host +side. After the target receives this packet, it can proceed with data tran= sfer +requests or memory debug. The host uses the following format while sending= a +hello response packet. + ++-----------+-------------+--------------------------------------+ +| Field | Length | Description | +| | (bytes) | | ++=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+ +| Command | 4 | Command identifier code | ++-----------+-------------+--------------------------------------+ +| Length | 4 | Length of the packet (in bytes) | ++-----------+-------------+--------------------------------------+ +| Version | 4 | Version number of this protocol | ++-----------+-------------+--------------------------------------+ +| Compatible| 4 | Lowest Compatible version | ++-----------+-------------+--------------------------------------+ +| Status | 4 | Success or error code | ++-----------+-------------+--------------------------------------+ +| Mode | 4 | Mode of operation for target to | +| | | execute | ++-----------+-------------+--------------------------------------+ +| Reserved | 4 | Reserved for future use | ++-----------+-------------+--------------------------------------+ +| Reserved | 4 | Reserved for future use | ++-----------+-------------+--------------------------------------+ +| Reserved | 4 | Reserved for future use | ++-----------+-------------+--------------------------------------+ +| Reserved | 4 | Reserved for future use | ++-----------+-------------+--------------------------------------+ +| Reserved | 4 | Reserved for future use | ++-----------+-------------+--------------------------------------+ +| Reserved | 4 | Reserved for future use | ++-----------+-------------+--------------------------------------+ + + +Read data packet / 64 bit read data packet +------------------------------------------ + +The read data packet serves as a generic data transfer packet when any ima= ge +data is to be transferred from the host to the target. This packet allows +flexibility in the way that the image is transferred from the host to the +target. As the target controls which data gets transferred, the target can +determine what parts of the image get transferred and in what order. The h= ost +need not be familiar about the structure of the image. It must open the fi= le and +start transferring the data to the target based on the parameters specifie= d in +the packet. + +This gives the target complete control over how the images are transferred= and +processed. To initiate an image transfer, the target fills the read data p= acket +with the image ID corresponding to the image that it wants to receive. The +target also sends the offset into the image file and the length of the dat= a(in +bytes) it wants to read from the image. After the host receives this packe= t, the +host responds with a data packet, which contains image data with the length +specified in the read data packet. The host uses the following format while +transferring the read data packet and 64-bit read data packet. + + +Read data packet format +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + ++-----------+-------------+--------------------------------------+ +| Field | Length | Description | +| | (bytes) | | ++-----------+-------------+--------------------------------------+ +| Command | 4 | Command identifier code | ++-----------+-------------+--------------------------------------+ +| Length | 4 | Length of the packet(in bytes) | ++-----------+-------------+--------------------------------------+ +| Image ID | 4 | ID of the image to be transferred. | ++-----------+-------------+--------------------------------------+ +| Data | 4 | Offset into the image file to start | +| offset | | transferring data. | ++-----------+-------------+--------------------------------------+ +| Data | 4 | Number of bytes target wants to | +| Length | | transfer from the image. | ++-----------+-------------+--------------------------------------+ + + +64-bit read data packet format +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D + ++-----------+-------------+--------------------------------------+ +| Field | Length | Description | +| | (bytes) | | ++-----------+-------------+--------------------------------------+ +| Command | 4 | Command identifier code | ++-----------+-------------+--------------------------------------+ +| Length | 4 | Length of the packet(in bytes) | ++-----------+-------------+--------------------------------------+ +| Image ID | 8 | ID of the image to be transferred. | ++-----------+-------------+--------------------------------------+ +| Data | 8 | Offset into the image file to start | +| offset | | transferring data. | ++-----------+-------------+--------------------------------------+ +| Data | 8 | Number of bytes target wants to | +| Length | | transfer from the image. | ++-----------+-------------+--------------------------------------+ + +If any of the preceding fields are invalid, or if any other error occurs o= n the +host, the host sends a data packet with length that does not match with wh= at the +target was expecting. The resulting error forces the target to send an end= of +image transfer packet with an error code in the status field and enables b= oth +the target and the host to enter an error handling state. + +End of Image transfer packet +---------------------------- + +If an image transfer is successfully completed, the target sends the host = an end +of image transfer packet with a success status. The target then waits for = the +host to send a done packet. If any error occurs during the transfer or +processing of the image data, the status is set to the corresponding error= code, +and the target waits for a different command packet. + +The host uses the following format while transferring end of image transfer +packet: + ++-----------+-------------+--------------------------------------+ +| Field | Length | Description | +| | (bytes) | | ++-----------+-------------+--------------------------------------+ +| Command | 4 | Command identifier code | ++-----------+-------------+--------------------------------------+ +| Length | 4 | Length of the packet(in bytes) | ++-----------+-------------+--------------------------------------+ +| Image ID | 4 | ID of the image that was being | +| | | transferred. | ++-----------+-------------+--------------------------------------+ +| Status | 4 | Success or error code | ++-----------+-------------+--------------------------------------+ + +Done packet +----------- + +If the host receives an end of image transfer packet with a success status= , the +host sends a done packet to indicate the target that it can exit the proto= col +and continue execution of code. The host uses the following format while s= ending +the done packet: + ++-----------+-------------+--------------------------------------+ +| Field | Length | Description | +| | (bytes) | | ++-----------+-------------+--------------------------------------+ +| Command | 4 | Command identifier code | ++-----------+-------------+--------------------------------------+ +| Length | 4 | Length of the packet(in bytes) | ++-----------+-------------+--------------------------------------+ + +To transfer another image from the host, the target must re-initiate the +protocol by starting with another hello packet. + +Done Response packet +-------------------- + +If the target receives a done packet, it responds with a done response pac= ket +containing the image transfer status. The target uses the following format= while +sending the done response packet: + ++-----------+-------------+--------------------------------------+ +| Field | Length | Description | +| | (bytes) | | ++-----------+-------------+--------------------------------------+ +| Command | 4 | Command identifier code | ++-----------+-------------+--------------------------------------+ +| Length | 4 | Length of the packet(in bytes) | ++-----------+-------------+--------------------------------------+ +| Image Tx | 4 | Indicates whether target is | +| Status | | expecting to receive another image | +| | | or not. | ++-----------+-------------+--------------------------------------+ + +If all the images are transferred, the target sends a complete status to e= nable +the host to exit the protocol. If all the images are not transferred, the = target +sends a pending status and waits for another hello packet to arrive. + +Reset Packet +------------ + +The host sends a reset packet to reset the target. The target services a r= eset +request only if its in a state where reset requests are valid. If the targ= et +receives an invalid reset request, the target sends an error in an end of = image +transfer packet. The format of reset packet is as follows: + ++-----------+-------------+--------------------------------------+ +| Field | Length | Description | +| | (bytes) | | ++-----------+-------------+--------------------------------------+ +| Command | 4 | Command identifier code | ++-----------+-------------+--------------------------------------+ +| Length | 4 | Length of the packet(in bytes) | ++-----------+-------------+--------------------------------------+ + + +Reset response packet +--------------------- + +If the target receives a valid reset request, it sends a reset response pa= cket +just before it resets. The purpose of this response is to acknowledge the = host +that the target received the reset request. The format of reset response p= acket +is as follows: + ++-----------+-------------+--------------------------------------+ +| Field | Length | Description | +| | (bytes) | | ++-----------+-------------+--------------------------------------+ +| Command | 4 | Command identifier code | ++-----------+-------------+--------------------------------------+ +| Length | 4 | Length of the packet(in bytes) | ++-----------+-------------+--------------------------------------+ + + +Memory debug packet +------------------- + +The target initiates a memory dump by sending the host a memory debug pack= et. +This packet contains the address and length of the memory debug table. The +memory debug table is a listing of memory locations that can be accessed a= nd +dumped to the host. The target uses the following format while sending the +memory debug packet: + ++-----------+-------------+--------------------------------------+ +| Field | Length | Description | +| | (bytes) | | ++-----------+-------------+--------------------------------------+ +| Command | 4 | Command identifier code | ++-----------+-------------+--------------------------------------+ +| Length | 4 | Length of the packet(in bytes) | ++-----------+-------------+--------------------------------------+ +| Memory | 4 | Target sets this field to the address| +| table | | in memory that stores the memory | +| Address | | debug table. | ++-----------+-------------+--------------------------------------+ +| Memory | 4 | Length in bytes of memory debug | +| table | | table. | +| Length | | | ++-----------+-------------+--------------------------------------+ + +Given the memory table address and length, the host issues a memory read to +retrieve the table. After the host receives the memory table information, = it can +decode each entry and issue memory read requests to dump each memory locat= ion. + +Memory read packet / 64-bit memory read packet +---------------------------------------------- + +The host issues memory read commands for each section of memory that it du= mps. +The host uses the following format while sending the memory read packet an= d 64 +bit memory read packet: + +Memory read packet format +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D + ++-----------+-------------+--------------------------------------+ +| Field | Length | Description | +| | (bytes) | | ++-----------+-------------+--------------------------------------+ +| Command | 4 | Command identifier code | ++-----------+-------------+--------------------------------------+ +| Length | 4 | Length of the packet(in bytes) | ++-----------+-------------+--------------------------------------+ +| Memory | 4 | Memory location to read. | +| Address | | | ++-----------+-------------+--------------------------------------+ +| Memory | 4 | Length in bytes of memory to read | +| Length | | | ++-----------+-------------+--------------------------------------+ + +64 bit memory read packet format +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D + ++-----------+-------------+--------------------------------------+ +| Field | Length | Description | +| | (bytes) | | ++-----------+-------------+--------------------------------------+ +| Command | 4 | Command identifier code | ++-----------+-------------+--------------------------------------+ +| Length | 4 | Length of the packet(in bytes) | ++-----------+-------------+--------------------------------------+ +| Memory | 8 | Memory location to read. | +| Address | | | ++-----------+-------------+--------------------------------------+ +| Memory | 8 | Length in bytes of memory to read | +| Length | | | ++-----------+-------------+--------------------------------------+ + +The accessible regions are defined in the memory debug table. For each mem= ory +read command received, the target verifies that the specified memory(addre= ss and +length) is accessible and responds with a raw data packet. The content and +length of the raw data packet is the memory dump starting from the memory +address and length specified in the memory read packet. The memory debug t= able +can also be read using a memory read command by setting the address and le= ngth +to the values specified in the memory debug packet. + +If any error occurs on the target, an end of image transfer packet is sent= with +the corresponding error code and the host recognizes whether it is actual = memory +data or an end of image transfer packet. The host issues a reset command on +completion of a successful memory dump. However, the protocol does not for= ce +this implementation. + +Command ready packet +-------------------- + +The target sends this packet to the host to indicate that the target is re= ady to +execute client commands. The target uses the following format while sendin= g the +command ready packet: + ++-----------+-------------+--------------------------------------+ +| Field | Length | Description | +| | (bytes) | | ++-----------+-------------+--------------------------------------+ +| Command | 4 | Command identifier code | ++-----------+-------------+--------------------------------------+ +| Length | 4 | Length of the packet(in bytes) | ++-----------+-------------+--------------------------------------+ + + +Command switch mode packet +-------------------------- + +The host sends the command switch mode packet to the target so that the ta= rget +can switch to another mode. The host uses the following format while sendi= ng the +command switch mode packet: + ++-----------+-------------+--------------------------------------+ +| Field | Length | Description | +| | (bytes) | | ++-----------+-------------+--------------------------------------+ +| Command | 4 | Command identifier code | ++-----------+-------------+--------------------------------------+ +| Length | 4 | Length of the packet(in bytes) | ++-----------+-------------+--------------------------------------+ +| Mode | 4 | Mode of operation for target | +| | | to execute. | ++-----------+-------------+--------------------------------------+ + +Command execute packet +---------------------- + +The host sends this packet to execute the given client command on the targ= et. If +the client command successfully executes, the target sends a command execu= te +response packet. If an error occurs, the target sends an end of image tran= sfer +packet with the corresponding error code. The host uses the following form= at +while sending command execute packet: + ++-----------+-------------+--------------------------------------+ +| Field | Length | Description | +| | (bytes) | | ++-----------+-------------+--------------------------------------+ +| Command | 4 | Command identifier code | ++-----------+-------------+--------------------------------------+ +| Length | 4 | Length of the packet(in bytes) | ++-----------+-------------+--------------------------------------+ +| Client | 4 | Client Command to be executed. | +| Command | | | ++-----------+-------------+--------------------------------------+ + + +Client commands +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + ++------------+-------------+--------------------------------------+ +| Client ID | Length | Description | ++------------+-------------+--------------------------------------+ +| 0x8 | 4 | Get Command ID list. | ++------------+-------------+--------------------------------------+ +| 0x9 | 4 | Get DDR training data. | ++------------+-------------+--------------------------------------+ + +Command execute Response packet +------------------------------- + +The target sends this packet if it successfully executes the client comman= d. The +target uses the following format while sending the command execute response +packet. + ++-----------+-------------+--------------------------------------+ +| Field | Length | Description | +| | (bytes) | | ++-----------+-------------+--------------------------------------+ +| Command | 4 | Command identifier code | ++-----------+-------------+--------------------------------------+ +| Length | 4 | Length of the packet(in bytes) | ++-----------+-------------+--------------------------------------+ +| Client | 4 | Client Command to be executed. | +| Command | | | ++-----------+-------------+--------------------------------------+ +| Response | 4 | Number of bytes for response data. | +| Length | | | ++-----------+-------------+--------------------------------------+ + +Command execute data packet +--------------------------- + +The host sends this packet if the response length received in the command +execute response packet is greater than 0. The host uses the following for= mat +while sending command execute data packet: + ++-----------+-------------+--------------------------------------+ +| Field | Length | Description | +| | (bytes) | | ++-----------+-------------+--------------------------------------+ +| Command | 4 | Command identifier code | ++-----------+-------------+--------------------------------------+ +| Length | 4 | Length of the packet(in bytes) | ++-----------+-------------+--------------------------------------+ +| Client | 4 | Client Command executed. | +| Command | | | ++-----------+-------------+--------------------------------------+ + +The packet indicates the target to send the response data in a raw data pa= cket. +The target sends the response data upon receiving this packet. + +64-bit memory debug packet +-------------------------- + +The target sends this packet to the host to initiate a memory dump. The pa= cket +contains 64-bit address and length of the memory table. The target uses the +following format while sending 64-bit memory debug packet: + ++-----------+-------------+--------------------------------------+ +| Field | Length | Description | +| | (bytes) | | ++-----------+-------------+--------------------------------------+ +| Command | 4 | Command identifier code | ++-----------+-------------+--------------------------------------+ +| Length | 4 | Length of the packet(in bytes) | ++-----------+-------------+--------------------------------------+ +| Memory | 8 | Target sets this field to the 64-bit | +| table | | address in memory that stores the | +| Address | | memory debug table. | ++-----------+-------------+--------------------------------------+ +| Memory | 8 | Length in bytes of memory debug | +| table | | table. | +| Length | | | ++-----------+-------------+--------------------------------------+ + +Reset Sahara state machine packet +--------------------------------- + +The host sends a reset Sahara state machine packet whenever it wants to re= set +Sahara state machine. When the target receives a reset Sahara state machine +request, it reinitializes Sahara protocol and sends the hello packet to the +host. The Sahara protocol is restarted without a target reset. The host us= es the +following format while sending the reset Sahara state machine packet: + ++-----------+-------------+--------------------------------------+ +| Field | Length | Description | +| | (bytes) | | ++-----------+-------------+--------------------------------------+ +| Command | 4 | Command identifier code | ++-----------+-------------+--------------------------------------+ +| Length | 4 | Length of the packet(in bytes) | ++-----------+-------------+--------------------------------------+ + +Write data packet +----------------- + +Write data packet serves as a generic data transfer packet when any data is +transferred from the target to the host. This packet allows flexible data +transfer from the target to the host. + +As the target controls what data gets transferred, target can determine wh= at +parts of the data get transferred and in what order. The host does not nee= d to +know anything about the structure of the data. It only needs to open the f= ile +and start accepting the data to the host based on the parameters specified= in +the packet. + +To initiate a write data transfer, the target fills the write data packet = with +the image ID corresponding to the image data that it wants to send. The ta= rget +also sends the offset into the output file and the length of the data(in b= ytes) +it wants to write from the target. As soon as the host receives the packet= , the +host opens an output file and waits to receive the data packets. After the +packet is received, the content from the data pcket is written to the outp= ut +file, The format of the write data packet is as follows: + ++-----------+-------------+--------------------------------------+ +| Field | Length | Description | +| | (bytes) | | ++-----------+-------------+--------------------------------------+ +| Command | 4 | Command identifier code | ++-----------+-------------+--------------------------------------+ +| Length | 4 | Length of the packet(in bytes) | ++-----------+-------------+--------------------------------------+ +| Data | 8 | Offset into the image file to start | +| offset | | writing the data to host. | ++-----------+-------------+--------------------------------------+ +| Image ID | 4 | ID of the image to be transferred. | ++-----------+-------------+--------------------------------------+ +| Data | 4 | Number of bytes target wants to | +| Length | | transfer the data to the host. | ++-----------+-------------+--------------------------------------+ + + +Command packet flow between host and target +------------------------------------------- + +Packet flow is a process of exchange of information as packets between the= host +and the target in a specific way using command packets. The Sahara protocol +allows packet processing for the following scenarios: + +1. Transferring an image from the host to the target. +2. Dumping memory from the target to the host. +3. Loading DDR calibration data on flashless target. + +Packet flow for Image transfer +------------------------------ + +The packet flow is performed between the host and target for a successful = image +transfer. + +.. code-block:: text + + Host Target + | HELLO | + | (mode =3D image transfer) | + |<--------------------------| + | | + | HELLO RESP | + | (mode =3D image transfer) | + |-------------------------->| + | | + | READ_DATA | + | (img ID, 0, offset, | + | size of image header) | + |<--------------------------| + | | + | RAW_DATA | + | (size of image header) | + |-------------------------->| + | | + | READ_DATA | + | (img ID, segment 0 offset,| + | size of segment 0) | + |<--------------------------| + | RAW_DATA | + | (size of segment 0) | + |-------------------------->| + | | + | READ_DATA | + | (img ID, segment 1 offset,| + | size of segment 1) | + |<--------------------------| + | | + | | + | RAW_DATA | + | (size of segment 1) | + |-------------------------->| + | ... | + | ... | + | ... | + | ... | + | | + | | + | READ_DATA | + | (img ID, segment N offset,| + | size of segment N) | + |<--------------------------| + | | + | | + | | + | RAW_DATA | + | (size of segment N) | + |-------------------------->| + | | + | | + | END_IMAGE_TX | + |<--------------------------| + | | + | | + | DONE | + |-------------------------->| + | | + | | + | DONE_RESP | + |<--------------------------| + | | + +The packet flow sequence for image transfer is as follows: + +1. A hello packet is sent from the target to the host to initiate the prot= ocol + with the mode set to either image transfer pending or image transfer + complete (depending on the target's boot sequence). + +2. The host sends a hello response packet with a success status and sets t= he + mode to the mode received in the hello packet. After it receives the he= llo + packet and validates the protocol version running on the target. + +3. After the target receives the hello response, the target initiates the + image transfer request by sending read data packets. Each read data pac= ket + specifies the image that the target wishes to receive and what part of = the + image is to be transferred. + +4. During normal operation, the target first requests image header informa= tion. + + a. The image header information specifies image size and location of the + image data that is to be transferred. + + b. The image header information (which is sent as a read data request) + allows the target to know the format of the image to be transferred. + The protocol does not require the host to know anything about the + image formats and allows the host to read and transfer data from the + image as requested by the target. + + c. If the image is a standalone binary image without any data segmentat= ion + (which means the data is entirely contiguous when stored as well as + transferred to the target system memory), then the target requests f= or + entire image data to be sent in one transfer. + + d. If the image data is segmented and requires scattering of the data + segments to noncontiguous system memory locations, the target issues + multiple read data requests to enable each data segment to be + transferred directly to the respective destination address. This + scattered information resides in the image header and is parsed by t= he + target before issuing the read data requests. + +5. After receiving a read data request, the host parses the image ID, data + offset, and data length to transfer data from the corresponding image f= ile. + The host sends the requested data without any packet header. + +6. The target directly transfers the data to the destination address witho= ut + any software processing or temporarily buffering of the data in system + memory by transferring the image header to the targert and setting the + receive buffer for the data as the destination address in system memory. + +7. After the target successfully receives all segments for an image, the + target sends an end of image transfer packet with the image ID of the + corresponding image, and a success status. The host stops reading and + closes the image file after receiving the success status. + +8. The host sends a done packet to allow the target to exit the protocol a= fter + it receives a successgul end of image transfer packet. + +9. After the target receives the done packet, the target sends a done resp= onse + packet to the host. This packet indicates if the target expects another + image to be transferred and if the host can continue to run the protoco= l. + +Packet flow for memory debug +---------------------------- + +The packet flow is performed between the host and the target for the succe= ssful +memory debug. + +.. code-block:: text + + Host Target + | HELLO | + | (mode =3D memory debug) | + |<--------------------------| + | | + | HELLO RESP | + | (mode =3D memory debug) | + |-------------------------->| + | | + | MEMORY_DEBUG | + | (location of mem table, | + | size of memory table) | + |<--------------------------| + | | + | MEMORY_READ | + | (Address from region 0 ,| + | size of region 0) | + |-------------------------->| + | RAW_DATA | + | (size of region 0) | + |<--------------------------| + | | + | MEMORY_READ | + | (Address from region 1 ,| + | size of region 1) | + |-------------------------->| + | RAW_DATA | + | (size of region 1) | + |<--------------------------| + | MEMORY_READ | + | (Address from region 2 ,| + | size of region 0) | + |-------------------------->| + | RAW_DATA | + | (size of region 2) | + |<--------------------------| + | ... | + | ... | + | ... | + | ... | + | | + | MEMORY_READ | + | (Address from region N ,| + | size of region N) | + |-------------------------->| + | RAW_DATA | + | (size of region N) | + |<--------------------------| + | | + | RESET | + |-------------------------->| + | | + | | + | RESET_RESP | + |<--------------------------| + | | + +The packet flow sequence for image transfer is as follows: + +1. A hello packet is sent from the target to the host to initiate the prot= ocol + with mode set to memory debug. + +2. The host sends a hello response packet with a success status and sets t= he + mode to memory debug after it receives the hello packet and validates t= he + protocol version running on the target. + +3. After the target receives the hello response, the target initiates the + memory dump by sending a memory debug packet with the location and size= of + the memory debug table. The memory debug table specifies accessible mem= ory + regions. + +4. The host then initiates a memory read packet to read the memory debug + table and receives the table in a raw data packet after it receives the + memory debug packet. + +5. The host then decodes the table and issues memory reads for each access= ible + region. The data for each region is sent in a raw data packet. + +6. Upon completion, the host issues a reset to the target. The target send= s a + reset response and resets the target. + +7. The host can alternatively send a command switch mode packet to allow t= he + target to switch modes and avoid a reset. + + +Packet flow to load DDR calibration data on target +-------------------------------------------------- + +The packet flow is performed between the host and the target to load DDR +calibration data on flashless target. This packet flow is initiated when t= he +device boots up for the first time and needs DDR calibration. This packet = flow +is also initiated in other scenarios, such as build update or any reason f= or +which DDR calibration data gets corrupted. + +First boot scenario or invalid calibration data in filesystem. +-------------------------------------------------------------- + +.. code-block:: text + + Host Target + | HELLO | + | (mode =3D image transfer) | + |<--------------------------| + | | + | HELLO RESP | + | (mode =3D image transfer) | + |-------------------------->| + | | + | READ_DATA | + | (img ID:34, 0, offset, | + | size of DDR training data)| + |<--------------------------| + | | + | RAW_DATA | + |(size of DDR training data)| + |-------------------------->| + | | + | | + | END_IMAGE_TX | + |<--------------------------| + | | + | | + | DONE | + |-------------------------->| + | | + | | + | DONE_RESP | + | (mode =3D IMAGE_TX_PENDING) | + |<--------------------------| + |1. First boot scenario. | + | DDR driver performs | + | calibration and returns | + | to SBL. | + |2. Next: Push DDR | + | Calibration data to host | + | | + | | + | HELLO | + | (mode =3D COMMAND mode) | + |<--------------------------| + | | + | HELLO RESP | + | (mode =3D COMMAND mode ) | + |-------------------------->| + | | + | CMD_READY | + |<--------------------------| + | | + | CMD_EXEC | + |(cmd id =3D 8, Get command | + | ID to be executed) | + |-------------------------->| + | | + | CMD_EXEC_RESP | + |(cmd id: 8, resp len =3D 4) | + |<--------------------------| + | | + | CMD_EXEC_GET_DATA | + | (ID =3D 0x8) | + |-------------------------->| + | | + | RAW_DATA | + | (0x00000009) | + |<--------------------------| + | | + | CMD_EXEC | + | (cmd id: 9, resp len > 0) | + |-------------------------->| + | | + | | + | CMD_EXEC_RESP | + |(cmd id: 9, resp len > 0) | + |<--------------------------| + | | + | CMD_EXEC_GET_DATA | + | (ID =3D 0x9) | + |-------------------------->| + | | + | RAW_DATA | + | (valid training data) | + |<--------------------------| + | | + |3. Host sends switch to | + |image tx mode to continue | + |booting. | + | | + | | + | CMD_SWITCH_MODE | + | (mode =3D IMAGE_TX_PENDING) | + |-------------------------->| + | | + | | + | HELLO | + | (mode =3D IMAGE_TX_PENDING) | + |<--------------------------| + | | + | HELLO RESP | + | (mode =3D IMAGE_TX_PENDING) | + |-------------------------->| + | | + |4. Boot/Load rest of the | + | images.... | + | | + | END_IMAGE_TX | + |<--------------------------| + | | + | | + | DONE | + |-------------------------->| + | | + | | + | DONE_RESP | + |(mode =3D IMAGE_TX_COMPLETE) | + |<--------------------------| + | | + +The packet flow sequence is as follows : + +1. The target sends the hello packet to the host to initiate the protocol + with the mode set to image transfer pending. + +2. The host sends a hello response packet with a success status and sets t= he + mode to image transfer pending after it receives the hello packet and + validates the protocol version running on the target. + +3. After the target receives the hello response, it initiates the data + transfer by requesting the size of DDR training/calibration data. + +4. The host sends back the DDR training/calibration data to the target. + +5. The target decodes the training data and does not find valid DDR + calibration data, target sends END_IMAGE_TX to interrupt the transfer. + +6. The host sends DONE after receives END_IMAGE_TX. + +7. The target sends DONE_RESP with mode =3D IMAGE_TX_PENDING because it has + not received all images. + +8. The target executes DDR training process to generate valid DDR calibrat= ion + data and prepares to push back to host. + +9. The target initiates protocol by sending a hello packet with COMMAND_MO= DE + to the host. + +10. The host sends a hello response packet with a success status and sets = the + mode to COMMAND_MODE. + +11. The target sends CMD_READY to the host. + +12. The host receives CMD_READY and starts to get command IDs to be execut= ed. + +13. The target sends CMD_ID =3D 9 to push DDR calibration data to host. + +14. The host executes CMD_ID =3D 9 to get DDR calibration data from the ta= rget. + +15. The target sends RAW_DATA with the payload which contains DDR calibrat= ion + data to host. + +16. The host saves training data in the kernel buffer and exposes to users= pace + via the sysfs entry. The host sends CMD_SWITCH_MODE with the mode set = to + IMAGE_TX_PENDING to continue booting. + +17. After the target receives the CMD_SWITCH_MODE command, it sends HELLO = to + the host with the mode set to IMAGE_TX_PENDING. The target and the host + repeat the packet flow for image transfer to get all booting-required + images. + +18. Upon successful transfer of all images, the target sends an END_IMAGE_= TX + packet with a success status to the host. + +19. The host sends DONE after it receives END_IMAGE_TX. + +20. The target sends DONE_RESP with the mode set to IMAGE_TX_COMPLETE beca= use + it has received all images. The process has been completed after the h= ost + receives DONE_RESP with the mode set to IMAGE_TX_COMPLETE. + +Subsequent boot scenario with valid DDR calibration data +-------------------------------------------------------- + +The below firgure shows the subsequent boot scenario with valid DDR calibr= ation +data process being loaded from host to target. + +.. code-block:: text + + Host Target + | HELLO | + | (mode =3D image transfer) | + |<--------------------------| + | | + | HELLO RESP | + | (mode =3D image transfer) | + |-------------------------->| + | | + | READ_DATA | + | (img ID:34, 0, offset, | + | size of DDR training data)| + |<--------------------------| + | | + | RAW_DATA | + |(size of DDR training data)| + |-------------------------->| + | | + | | + | END_IMAGE_TX | + |<--------------------------| + | | + | | + | DONE | + |-------------------------->| + | | + | | + | DONE_RESP | + | (mode =3D IMAGE_TX_PENDING) | + |<--------------------------| + | | + | Subsequent boot scenario | + | (valid calibration data) | + | DDR driver configures DDR | + | using valid calibration | + | data | + | | + | | + | HELLO | + | (mode =3D IMAGE_TX_PENDING) | + |<--------------------------| + | | + | HELLO RESP | + | (mode =3D IMAGE_TX_PENDING) | + |-------------------------->| + | | + | Boot/Load rest of the | + | images.... | + | | + | END_IMAGE_TX | + |<--------------------------| + | | + | | + | DONE | + |-------------------------->| + | | + | | + | DONE_RESP | + |(mode =3D IMAGE_TX_COMPLETE) | + |<--------------------------| + | | + +The packet flow is as follows : + +1. The target sends the hello packet to the host to initiate the protocol + with the mode set to image transfer pending. + +2. The host sends a hello response packet with a success status and sets t= he + mode to image transfer pending after it receives the hello packet and + validates the protocol version running on the target. + +3. After the target receives the hello response, it initiates the images + transfer by requesting the training/calibration data from the host. + +4. The host sends back the DDR training/calibration data to the target. + +5. The target decodes the DDR training/calibration data and finds valid DDR + calibration data. + +6. The host sends RAW_DATA with the size of the DDR calibration data to the + target. + +7. Upon successful transfer of DDR calibration data, the target sends an + END_IMAGE_TX packet with a success status. + +8. The host sends DONE after it receives END_IMAGE_TX. + +9. The target sends DONE_RESP with mode =3D IMAGE_TX_PENDING because it ha= s not + received all images. + +10. The target continues booting with valid DDR calibration data. + +11. The target and the host repeat the packet flow for image transfer to g= et + all booting-required images. + +12. After successful transfer of all images, the target sends an END_IMAGE= _TX + packet with a success status to the host. + +13. The host sends DONE after it receives END_IMAGE_TX. + +14. The target sends DONE_RESP with the mode set to IMAGE_TX_COMPLETE beca= use + it has received all images. The process has been completed after the h= ost + receives DONE_RESP with the mode set to IMAGE_TX_COMPLETE. --=20 2.34.1 From nobody Tue Jun 16 05:19:42 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 24F7D3DE441 for ; Thu, 16 Apr 2026 14:10:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776348613; cv=none; b=VmJeTzD9G8Gw6fImgZSoBwT0r2m+fBMGeWdoH5IGhLVuST1ADZtH5YgtazXuAIfWkB46vSUDq5TgWGp3LTUFs5bt5IqoGqyc/JoL2MGuenUk835oH4yElLflvdG+z3Q+vU/rNdAdRAOQ/2mEtxeIAwaPWsAnYL53gHIdDRS1rDg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776348613; c=relaxed/simple; bh=wxmxFNTxmH1BxvnW9OL8EFs3pxurc8AKng1CYfcu7cA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=taycrQgDaoWz0DA7xG8Z2riZG+Fw4lLmqv5jk15SwaAduCfrQM1hXt4l/yTi/LGoaGmug+dMP82e+cuz1OcM71yNMIh5HDfMb9S5h81nQJNmpfCqBXElvyr7aZR0+sTtL7KlMsi5h/oDNXud2a1hRye30+FjCBRTnql24bLf6t0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=Wi5LYv24; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=S1sFHRaf; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="Wi5LYv24"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="S1sFHRaf" Received: from pps.filterd (m0279872.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 63G8QTlM862166 for ; Thu, 16 Apr 2026 14:10:10 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= 9CGLii7+KdkxqW5GSTDgBYsnFCYt35AgEJQIXwVb6iw=; b=Wi5LYv24L2Ke16ql qrqz8yStjLRrhnlnod+4GLrSyMDWKgi0/zShk5LR92dtCtH/KLO0vGpByB5rl3eR cX0KgVAx2vCc/XVGJ32H+fwVmpy6LnjEaWeX8A/7W6/L0yPhQ1VB6X4+0geH0G8w v3Mq2a2RgXLf3nwu7P5Vs8qAP1wPOpaCdOe8Tj919JpROUqzHEbq4s7q6sa2xzQl 0qspG3BJBLj1oxVE1RLUriKhpIE17cB5xvqOGcNm38nZD4Vdqbs5S8FxMgOSkQgv /D3JTtflcx5ezuP7t27rOmlJsX7IPX5gFL3JQmvblLzbRkaINGSimM3g1rykBivO xlOstg== Received: from mail-yx1-f70.google.com (mail-yx1-f70.google.com [74.125.224.70]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4djd0ec6dt-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 16 Apr 2026 14:10:09 +0000 (GMT) Received: by mail-yx1-f70.google.com with SMTP id 956f58d0204a3-65079af1ee9so16064997d50.1 for ; Thu, 16 Apr 2026 07:10:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1776348608; x=1776953408; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=9CGLii7+KdkxqW5GSTDgBYsnFCYt35AgEJQIXwVb6iw=; b=S1sFHRafdA54KWVafaKCTbPTx55N+wL7h1J+Q8C25Wie1hatZMFtp+2iogSIbmzeZO nMzFhUxIJ5gbg774/+sJ4C5h0RiTCLSo2M7HFHpEuatKwmUY1yblntzon1ApUrdHLHX8 HFzX2Cb0TD31lAALJ3RGyAfL2XIPWL+PpCnZsZo4eXzkLTWuwKG1FxZo+BvX+arG09tU xIJ30p3+bZbFMMNvo0wJQUB98nplJ40il/8SgKk1+tLjFVqhWT9xAcMA0LhNhH7TfD34 m/EOcOW5gcydwKWPyRBuKmujGQXLVCQ3K2UbcmjvLUrER6+FBhd3pwBaas3cYuINeOc4 usxw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776348608; x=1776953408; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=9CGLii7+KdkxqW5GSTDgBYsnFCYt35AgEJQIXwVb6iw=; b=WsIxZ36Ox9V5VWnPJLtMC6hXpw6lDfZzOwZgtWQ+cbnVcCIn6mL6jys65P533fg8gO N09hjItv9dWX7dUbKgFgp+FRbVxCbBVVnLO7oK3v9drnkAiBHISq77kfss6aWjlXi5eW y7l6ykf+3gPhlHWAMnHo/wMS9rdqZK5qy0eMY83oXH6S/uk7cFOJA0LNZIoUQe9J56We TbojYa+3K6NiS2EVfEJRXtCHYOJCDFSdVQQjkq0QaBCu7N1KBUb6awyXMVV578/7STDi s2ZcCieBnZ/Pb4DA8l3tSrg52YUdhrVjILBYEWNm1ce9woembpZBUzKsKzHEfRiplBXg WOfw== X-Forwarded-Encrypted: i=1; AFNElJ+uJhgeocaoJ3GyHeCiyH+8de01iwqcghtTu1S+TmEsbhizZgTW0soZUOuYguD4G1dRlAcsMC9vOIVGpvQ=@vger.kernel.org X-Gm-Message-State: AOJu0Ywr3Qfer/U5L9AQC7DV+q37FGugsHB2jfOQ5UVlQ6sdmchxuJP0 hcltSm8Mbah0OMWflZGnt5nLrBO7KLKS1Eq/N2NY2TRcD1Fmhx1aQgV715p3IKiwEEeHWUI6+vA OO7aWYdtkYmrQdVVbIA2TD4c9VprMwrYduy4ETdFMWMTXoObKLh+AaZ7T1ctPmsA7804= X-Gm-Gg: AeBDiev5eyN8YQev0JPhIRuUt5EuR8SSrwugjvM40SMQE3x4tPcDZMgMQ2I7oTzqGYz PpD1+ckVDeVVREwNQO7m61No05Ya54i0T6et+7dHQcw6vJ32pE5ujxxaXOWmkjcgjsH3wjzOR0i 97WVv9AXV3jG8nh2F8zmGSXGHgs9P5ZonYBJ4RPQDLXlgcJ5+zhkJfK+Y4QJExbcmwF0sxDptDf vU6tAm2EefEC7omFpsReRqsrQGXD/xHGocqRu0dgXEL6E8/gDdpDqwlIRZRwGVrxFgzHcaTgX3D zNkv05tJ5cbl8mNm/RIco2t4zv7rTGLP37Hg/KvweC3qXBRaR9Sb9maT/s4uvCy9DOMIg7GUb7F T15pT/gh2d0kVvEoUsOgoCwJQU9KEUbLJFcsEhdTM4rpPzygo+7M= X-Received: by 2002:a05:690e:ec4:b0:650:7b5b:ed00 with SMTP id 956f58d0204a3-65198a82f55mr19690045d50.23.1776348607825; Thu, 16 Apr 2026 07:10:07 -0700 (PDT) X-Received: by 2002:a05:690e:ec4:b0:650:7b5b:ed00 with SMTP id 956f58d0204a3-65198a82f55mr19689991d50.23.1776348607308; Thu, 16 Apr 2026 07:10:07 -0700 (PDT) Received: from hu-batta-hyd.qualcomm.com ([202.46.23.25]) by smtp.gmail.com with ESMTPSA id 956f58d0204a3-652e47ba4a3sm2084691d50.17.2026.04.16.07.10.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Apr 2026 07:10:06 -0700 (PDT) From: Kishore Batta Date: Thu, 16 Apr 2026 19:39:43 +0530 Subject: [PATCH v5 2/7] bus: mhi: Move Sahara protocol driver under MHI host client drivers Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260416-sahara_protocol_new_v2-v5-2-6aebf005e4ba@oss.qualcomm.com> References: <20260416-sahara_protocol_new_v2-v5-0-6aebf005e4ba@oss.qualcomm.com> In-Reply-To: <20260416-sahara_protocol_new_v2-v5-0-6aebf005e4ba@oss.qualcomm.com> To: Jonathan Corbet , Shuah Khan , Jeff Hugo , Carl Vanderlip , Oded Gabbay , Manivannan Sadhasivam Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, mhi@lists.linux.dev, Kishore Batta X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1776348592; l=8314; i=kishore.batta@oss.qualcomm.com; s=20260206; h=from:subject:message-id; bh=wxmxFNTxmH1BxvnW9OL8EFs3pxurc8AKng1CYfcu7cA=; b=67FcuWucSZqFHCHyX67DHEpx9YKqUBfr8Q2ACSNXqo4VdYY55XSzvWRev3aQYf+FHm/PjYUEr feCqZxI8m0jDJ2ZoB8rfJ8dOmxAagkFDqOs4yTk871cWCvpiLIZ5R9q X-Developer-Key: i=kishore.batta@oss.qualcomm.com; a=ed25519; pk=vJo8RvTf+HZpRLK2oOIljmbn9l3zFkibCGh+blaqZCw= X-Proofpoint-GUID: aI2U3WoMGoUVQr71-JRg9SwRXhj8T0RJ X-Proofpoint-ORIG-GUID: aI2U3WoMGoUVQr71-JRg9SwRXhj8T0RJ X-Authority-Analysis: v=2.4 cv=GP441ONK c=1 sm=1 tr=0 ts=69e0edc1 cx=c_pps a=S/uc88zpIJVNbziUnJ6G4Q==:117 a=ZePRamnt/+rB5gQjfz0u9A==:17 a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=yx91gb_oNiZeI1HMLzn7:22 a=EUspDBNiAAAA:8 a=h4jUYMdnt1ASHzOZM6YA:9 a=QEXdDO2ut3YA:10 a=nd2WpGr1bMy9NW-iytEl:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNDE2MDEzNSBTYWx0ZWRfXxBHKMTPiKlf2 tfQ6no2h9xbVSWkW1wk3IThE1jQMzzdfO311HpqN1ZFFhfjI7vDUXH6JqtUZpHhI7y49M3l86Tn JMEIP9islJUlo78zAqKgYCCqtRAYMpR8u2icLU3meFZ1fMgLJcy4UJupPs0y+FySVlIn46dxVFv OAYPnpzBgBxjmV89SN8/c/BMqIRXpBPmvr/rT6X2Bi3OOd2kznphE+dJS7WzqMauHVYhudKaYPH QPObZlvwEt/kIcy0LW5/1MVjbn0KgkRA/n8RUDQci8hnIKG5gNNvNwqutAWAYziWzgAzSfoQo5s 4RvtV8LeuaYovmPPdFYClrHN745P8zYe2wXSZkguZplPZdxpjU62g3py79z19zRJlMGzu0i6YZc t5dNoK5d5sN4Abji8SdT4mUJzKjGl56ScXYhLwaUsN4L3wQXNJ484WeqCDi6viM0QyBHViqWZlk kjio06UPmqkycX9Z6vA== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-04-16_03,2026-04-16_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 spamscore=0 clxscore=1015 adultscore=0 phishscore=0 lowpriorityscore=0 bulkscore=0 suspectscore=0 priorityscore=1501 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604070000 definitions=main-2604160135 The Sahara protocol driver currently lives under the QAIC accelerator subsystem even though the protocol is transported over MHI and is used by multiple Qualcomm flashless devices. This makes Sahara appear QAIC specific and complicates reuse by other MHI based devices. Move the Sahara protocol driver under drivers/bus/mhi as a host client driver and build it as an independent MHI protocol driver. This keeps the QAIC driver focused on the accelerator device while allowing other MHI users to enable Sahara without depending on QAIC. As part of the move, add a dedicated Kconfig/Makefile hierarchy under the MHI host client drivers and convert the driver to use module_mhi_driver() instead of register/unregister hooks. Signed-off-by: Kishore Batta --- drivers/accel/qaic/Kconfig | 1 + drivers/accel/qaic/Makefile | 3 +-- drivers/accel/qaic/qaic_drv.c | 9 --------- drivers/accel/qaic/sahara.h | 10 ---------- drivers/bus/mhi/Kconfig | 1 + drivers/bus/mhi/host/Makefile | 1 + drivers/bus/mhi/host/clients/Kconfig | 5 +++++ drivers/bus/mhi/host/clients/Makefile | 1 + drivers/bus/mhi/host/clients/sahara/Kconfig | 15 +++++++++++++++ drivers/bus/mhi/host/clients/sahara/Makefile | 2 ++ .../qaic =3D> bus/mhi/host/clients/sahara}/sahara.c | 20 +++++++-------= ------ 11 files changed, 34 insertions(+), 34 deletions(-) diff --git a/drivers/accel/qaic/Kconfig b/drivers/accel/qaic/Kconfig index 116e42d152ca885b8c59e33c7a87519a0abc6bb3..af90fdfcf77eeb6dd5ad309b33d= 793d4fdc91b1e 100644 --- a/drivers/accel/qaic/Kconfig +++ b/drivers/accel/qaic/Kconfig @@ -8,6 +8,7 @@ config DRM_ACCEL_QAIC depends on DRM_ACCEL depends on PCI && HAS_IOMEM depends on MHI_BUS + depends on MHI_SAHARA select CRC32 select WANT_DEV_COREDUMP help diff --git a/drivers/accel/qaic/Makefile b/drivers/accel/qaic/Makefile index 71f727b74da3bb4478324689f02a7cea24a05c2d..e7b8458800072aa627f7f36c325= 7883aa56f4ce4 100644 --- a/drivers/accel/qaic/Makefile +++ b/drivers/accel/qaic/Makefile @@ -13,7 +13,6 @@ qaic-y :=3D \ qaic_ras.o \ qaic_ssr.o \ qaic_sysfs.o \ - qaic_timesync.o \ - sahara.o + qaic_timesync.o =20 qaic-$(CONFIG_DEBUG_FS) +=3D qaic_debugfs.o diff --git a/drivers/accel/qaic/qaic_drv.c b/drivers/accel/qaic/qaic_drv.c index 63fb8c7b4abcbe4f1b76c32106f4e8b9ea5e2c8e..3907b13e426064f4fa069e803cc= 44462feea4063 100644 --- a/drivers/accel/qaic/qaic_drv.c +++ b/drivers/accel/qaic/qaic_drv.c @@ -32,7 +32,6 @@ #include "qaic_ras.h" #include "qaic_ssr.h" #include "qaic_timesync.h" -#include "sahara.h" =20 MODULE_IMPORT_NS("DMA_BUF"); =20 @@ -791,12 +790,6 @@ static int __init qaic_init(void) goto free_pci; } =20 - ret =3D sahara_register(); - if (ret) { - pr_debug("qaic: sahara_register failed %d\n", ret); - goto free_mhi; - } - ret =3D qaic_timesync_init(); if (ret) pr_debug("qaic: qaic_timesync_init failed %d\n", ret); @@ -818,7 +811,6 @@ static int __init qaic_init(void) =20 free_bootlog: qaic_bootlog_unregister(); -free_mhi: mhi_driver_unregister(&qaic_mhi_driver); free_pci: pci_unregister_driver(&qaic_pci_driver); @@ -847,7 +839,6 @@ static void __exit qaic_exit(void) qaic_ras_unregister(); qaic_bootlog_unregister(); qaic_timesync_deinit(); - sahara_unregister(); mhi_driver_unregister(&qaic_mhi_driver); pci_unregister_driver(&qaic_pci_driver); } diff --git a/drivers/accel/qaic/sahara.h b/drivers/accel/qaic/sahara.h deleted file mode 100644 index 640208acc0d13d423bd9220e6861b7c141af74ff..000000000000000000000000000= 0000000000000 --- a/drivers/accel/qaic/sahara.h +++ /dev/null @@ -1,10 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -/* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved= . */ - -#ifndef __SAHARA_H__ -#define __SAHARA_H__ - -int sahara_register(void); -void sahara_unregister(void); -#endif /* __SAHARA_H__ */ diff --git a/drivers/bus/mhi/Kconfig b/drivers/bus/mhi/Kconfig index b39a11e6c624ba00349cca22d74bd876020590ab..720115218c2401c99b29f79bbd4= 113cd877503ac 100644 --- a/drivers/bus/mhi/Kconfig +++ b/drivers/bus/mhi/Kconfig @@ -7,3 +7,4 @@ =20 source "drivers/bus/mhi/host/Kconfig" source "drivers/bus/mhi/ep/Kconfig" +source "drivers/bus/mhi/host/clients/Kconfig" diff --git a/drivers/bus/mhi/host/Makefile b/drivers/bus/mhi/host/Makefile index 859c2f38451c669b3d3014c374b2b957c99a1cfe..2e8949f1a2fe6f3f3b2e1dc541f= 97d2c393d6a0f 100644 --- a/drivers/bus/mhi/host/Makefile +++ b/drivers/bus/mhi/host/Makefile @@ -4,3 +4,4 @@ mhi-$(CONFIG_MHI_BUS_DEBUG) +=3D debugfs.o =20 obj-$(CONFIG_MHI_BUS_PCI_GENERIC) +=3D mhi_pci_generic.o mhi_pci_generic-y +=3D pci_generic.o +obj-$(CONFIG_MHI_BUS) +=3D clients/ diff --git a/drivers/bus/mhi/host/clients/Kconfig b/drivers/bus/mhi/host/cl= ients/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..a4f2a3c1d20c887cc474646ea91= 532d775a13f57 --- /dev/null +++ b/drivers/bus/mhi/host/clients/Kconfig @@ -0,0 +1,5 @@ +menu "MHI host client drivers" + +source "drivers/bus/mhi/host/clients/sahara/Kconfig" + +endmenu diff --git a/drivers/bus/mhi/host/clients/Makefile b/drivers/bus/mhi/host/c= lients/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..62e2fa161565225be7f6a23d3cd= f4f2f169cb7ce --- /dev/null +++ b/drivers/bus/mhi/host/clients/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_MHI_SAHARA) +=3D sahara/ diff --git a/drivers/bus/mhi/host/clients/sahara/Kconfig b/drivers/bus/mhi/= host/clients/sahara/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..f1fc7013a2dee0be645c50f3230= 5659e591de7e7 --- /dev/null +++ b/drivers/bus/mhi/host/clients/sahara/Kconfig @@ -0,0 +1,15 @@ +config MHI_SAHARA + tristate "Sahara protocol driver" + depends on MHI_BUS + help + Enable support for the Sahara protocol transported over the MHI bus. + + The Sahara protocol is used to transfer firmware images, retrieve + memory dumps and exchange command mode DDR calibration data between + host and device. This driver is not tied to a specific SoC and may be + used by multiple MHI based devices. + + If unsure, say N. + + To compile this driver as a module, choose M here: the module will be + called mhi_sahara. diff --git a/drivers/bus/mhi/host/clients/sahara/Makefile b/drivers/bus/mhi= /host/clients/sahara/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..fc02a25935011cbd7138ea8f24b= 88cf5b032a4ce --- /dev/null +++ b/drivers/bus/mhi/host/clients/sahara/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_MHI_SAHARA) +=3D mhi_sahara.o +mhi_sahara-y :=3D sahara.o diff --git a/drivers/accel/qaic/sahara.c b/drivers/bus/mhi/host/clients/sah= ara/sahara.c similarity index 99% rename from drivers/accel/qaic/sahara.c rename to drivers/bus/mhi/host/clients/sahara/sahara.c index fd3c3b2d1fd3bb698809e6ca669128e2dce06613..858dc5bc39c1ad42922cabef3b1= abcd43bc4f0f4 100644 --- a/drivers/accel/qaic/sahara.c +++ b/drivers/bus/mhi/host/clients/sahara/sahara.c @@ -1,6 +1,8 @@ // SPDX-License-Identifier: GPL-2.0-only - -/* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved= . */ +/* + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. + * + */ =20 #include #include @@ -13,8 +15,6 @@ #include #include =20 -#include "sahara.h" - #define SAHARA_HELLO_CMD 0x1 /* Min protocol version 1.0 */ #define SAHARA_HELLO_RESP_CMD 0x2 /* Min protocol version 1.0 */ #define SAHARA_READ_DATA_CMD 0x3 /* Min protocol version 1.0 */ @@ -923,13 +923,7 @@ static struct mhi_driver sahara_mhi_driver =3D { .name =3D "sahara", }, }; +module_mhi_driver(sahara_mhi_driver); =20 -int sahara_register(void) -{ - return mhi_driver_register(&sahara_mhi_driver); -} - -void sahara_unregister(void) -{ - mhi_driver_unregister(&sahara_mhi_driver); -} +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Qualcomm Sahara MHI protocol driver"); --=20 2.34.1 From nobody Tue Jun 16 05:19:42 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (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 50D703DF013 for ; Thu, 16 Apr 2026 14:10:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776348623; cv=none; b=kkZs/Zi8NhDjU+P08ZaIJH0JiZpGFvsSmxvxJMdSD3ucdqG6PHYUqY6Roy/5lBUtwf+q95qgAcoqUjSVjQtX9dM9G1z9FGqnTGsEz46lSw5cvSvNH31w0+lsmBBhTJVEZbyQJWXbsGEiIM2qLB6zEmWnnHJC00TxaziPwahS9Xg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776348623; c=relaxed/simple; bh=28E7Vcxz/zL/tJvNl4R7cGAC0IOtuHloTBJjNXp+ts8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Ghd3OtzE9u60YamACioA5Um5E2g6qfS4kWw8O+BphFmHCCR8F0FTOHPEM6FikynYAESPJlLTjwhsxspH7o1CR8xraCWnXnfGAi8uZ75w9bsOBIIuJHWhYN+2Um2fwBu3E+SWMkySTWJyW/1FcJ3B0WQsiVh0qQwQVH9ypFvkhTY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=LSYpZNPn; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=BSTyB1M2; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="LSYpZNPn"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="BSTyB1M2" Received: from pps.filterd (m0279866.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 63GAY48U1245288 for ; Thu, 16 Apr 2026 14:10:18 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= W899JKnFZJ6i4LZoCOiJODPDV7JFYUGw4LZ0YibnRaI=; b=LSYpZNPnRr96YJZW wKqC8e5FjmGdIngL4CGU1WSka5g66sFuP02bJzXT1NL0swaaspCBUNdufQP5r73i oyIqIc2FX21mWzm8lNo5eDKG7bJI66b1BP9mR0dyYthkaJ23QVtZoU36otjx4Utd xjt3rLyX2iYLV7Hj8NIIG1p3di9p8MODiWiQB+et4HDpv/27qO17HtetoCW8duka vXL7Cmp8i9BUxRqNdgVQ7FMQFNrbw7VNKLwl4GthGvma+dP7O9aUIan8At/HoQSg MFhBNGjICFmfTPKA9x+agRR+nQaC5eIa1fC2/mANtqTj0m31+PdMm/k77fHKjyXs RaFcnA== Received: from mail-yx1-f71.google.com (mail-yx1-f71.google.com [74.125.224.71]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4djx4k8nrr-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 16 Apr 2026 14:10:14 +0000 (GMT) Received: by mail-yx1-f71.google.com with SMTP id 956f58d0204a3-651c0aae418so5688691d50.2 for ; Thu, 16 Apr 2026 07:10:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1776348613; x=1776953413; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=W899JKnFZJ6i4LZoCOiJODPDV7JFYUGw4LZ0YibnRaI=; b=BSTyB1M2vUJJXqK0MKIyKbm+B43vpZh6DqOTzKw66l5tn81yLFwPwlCfMxiez92vLc NRQJqpseZGjbAvzWYOnWYRC3NEBO17IMElxI/+Tvvq9Pt1jG0mYpgDJbosogUc0kKRNN cgXibYA6PnF6vQoJJNWUo7AqsNn2+J97/pUQ+TRRgdMFswKJzcZshz2sDlowxwPQO5d3 g/Hw1T6dbHh40OaXRMyKiMi71kbJ/9i8AIu9a95Ae3b2pPTP2moiAr/8aQzkJbojXnis Y8QSJa8L7mHCzm5M/61dUZ6vfviIH2mtBplP0meGXS6Zbs82l3sRIfdMQE46tneaWyye G5kA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776348613; x=1776953413; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=W899JKnFZJ6i4LZoCOiJODPDV7JFYUGw4LZ0YibnRaI=; b=OK4vQoFypZ/Fi1kV25ORQ6RL7Pxq5qF5g2iiMxU2HQXZFRu4p4pawUvhwkWvO/UOhq 0ZDW7y8SV4SpW0pf+2QzMRVqRfsORdnxICg6Wc232N7c600Sroi3fM6gOJr/bREkOh5y H+OCm9OxESNs7M55KxYvCoedH6zBB4kcUvHCA0QY9yseDRoR/Ek7/61VXXoRJCVMcUqS SHwJK90xUEolBG9Srs40JduGpMbHuNje2Mxz5NJF7LMamvf5NqX53a1oQQB/zAGyLMK8 9GGmyKjQDQ3742vPYEx6Pze1aIO0NcqtYILdJNC+3WI/Id3GmSanN5rC45+t9Ma+OPqZ GFCA== X-Forwarded-Encrypted: i=1; AFNElJ+upIl357p1AVYyBCUFAQTfKgA2QtIqzR7XKQil1yZ0DviYYc4nfawxz8xbJlRImoUEDyszEBWX0ST0OJE=@vger.kernel.org X-Gm-Message-State: AOJu0Yzf3My0bSR3v7ykDFM2GXignVMPZKBUn+bWmemPUeo9jwe0rHrt LUMYDQJu8FdvKqS4aU5xgiLrUYzC26U9fzNLBK7Vj+84HEqM3D3uG6AJJhG2P2g604YGvno8ZNJ m9wrQF9YPW6Ga6JhVRBNdte1+7pILs24gk7Ef2PdRy2zWA2IEVoQXiNsESmxwYwv/s1A= X-Gm-Gg: AeBDietAonlHEAL4jpeb8Gjthi8SM+le5HzZw3ZoFvYyJnPu8fC0fpZY2kdgekoq+qf HX9M+RvAitq8cyLMM4Dj4cqiMo+nYGt9HFhmJm+AiwXMq8qaoek1IwhAXaxN6R3TdY28jZO9rG9 iGL4L8OpVrpOrP7qughaJlTbRVraRYBmuATbocPjI5JvsDEBQeX3qWz8WmYBKlOzTWIH7DK47gG 3bEsjvmY5HdFEBDwWjvTfCvJUouXsMiTe5irTrqKH1H01wkx74VpYvT/1KzMirjM6gxtIT+CJk7 q/A43+1XQvUA5ciug3tYBXQm76kA8/ZG0S38ScCOUebwxsXqkocNDic77LXcjfqdLrLEC1LaftC ViGvhdIFR1Iqgyasn8gRqWMLP9TlKcGn2eYLinb6hRJUTY2EiLAM= X-Received: by 2002:a05:690e:1504:b0:652:cacb:ba15 with SMTP id 956f58d0204a3-652cacbc0fbmr8016157d50.64.1776348612950; Thu, 16 Apr 2026 07:10:12 -0700 (PDT) X-Received: by 2002:a05:690e:1504:b0:652:cacb:ba15 with SMTP id 956f58d0204a3-652cacbc0fbmr8016067d50.64.1776348612014; Thu, 16 Apr 2026 07:10:12 -0700 (PDT) Received: from hu-batta-hyd.qualcomm.com ([202.46.23.25]) by smtp.gmail.com with ESMTPSA id 956f58d0204a3-652e47ba4a3sm2084691d50.17.2026.04.16.07.10.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Apr 2026 07:10:11 -0700 (PDT) From: Kishore Batta Date: Thu, 16 Apr 2026 19:39:44 +0530 Subject: [PATCH v5 3/7] bus: mhi: Centralize Sahara firmware image table selection at probe time Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260416-sahara_protocol_new_v2-v5-3-6aebf005e4ba@oss.qualcomm.com> References: <20260416-sahara_protocol_new_v2-v5-0-6aebf005e4ba@oss.qualcomm.com> In-Reply-To: <20260416-sahara_protocol_new_v2-v5-0-6aebf005e4ba@oss.qualcomm.com> To: Jonathan Corbet , Shuah Khan , Jeff Hugo , Carl Vanderlip , Oded Gabbay , Manivannan Sadhasivam Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, mhi@lists.linux.dev, Kishore Batta X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1776348592; l=8668; i=kishore.batta@oss.qualcomm.com; s=20260206; h=from:subject:message-id; bh=28E7Vcxz/zL/tJvNl4R7cGAC0IOtuHloTBJjNXp+ts8=; b=XWpmcV6fJDjnetWvTknnLHmt0XMO7To/AjsDMb5xTAMK2v+MLMHinXZ9VcPKAm/ohA24eT7g0 9unbhhGtOixD4XZmUvYq6YQxFEfklQ2Q3NrNgfrLGJb3Ah8FT6CnqVP X-Developer-Key: i=kishore.batta@oss.qualcomm.com; a=ed25519; pk=vJo8RvTf+HZpRLK2oOIljmbn9l3zFkibCGh+blaqZCw= X-Proofpoint-GUID: dS2NPN3HatkjvnywLfizufU-qvAHajrI X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNDE2MDEzNSBTYWx0ZWRfX7TBF+1G28/Hi 0PkG5zrQkdsCLswaf5oVKQUux1S97/Hi4E8UDiwINPrE4Ii1kG+GXe3o7YkuAoHqjvSiPRhrHrD NAxueG508zeS0Klr91V/0NUujIIOSDmfUCmAm4GIO4i3+ftlGXU7AVdm1BVzwgROetd65i+wHaa 9JjO4jgToJyuCuNk4FaIegDvkcOTA2cKzKTPn1MS+cIOTxWCVoxrjcQ4kxUwxE+S3DTSeUtzKGm pMecf05mFj9a8BnNECLKUz5L5MmWqPnoqQndQinyScuh6AoTCb5g496mm7A530BWxF/WHWjISEQ w20TknGFWnQ7dQ0BjnfMf0M1jTk3YQWrV5Eya0YjwWdQGNgrt9PUI5jRpVpE1f3XWmcQAbvouHJ B3kdUGKlNEXmjuRqOWlktnih4vVyDA== X-Authority-Analysis: v=2.4 cv=H47rBeYi c=1 sm=1 tr=0 ts=69e0edc6 cx=c_pps a=ngMg22mHWrP7m7pwYf9JkA==:117 a=ZePRamnt/+rB5gQjfz0u9A==:17 a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=YMgV9FUhrdKAYTUUvYB2:22 a=EUspDBNiAAAA:8 a=FaWmrOfgj8M-bvBoqZ0A:9 a=QEXdDO2ut3YA:10 a=yHXA93iunegOHmWoMUFd:22 X-Proofpoint-ORIG-GUID: dS2NPN3HatkjvnywLfizufU-qvAHajrI X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-04-16_03,2026-04-16_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 lowpriorityscore=0 bulkscore=0 phishscore=0 adultscore=0 spamscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604070000 definitions=main-2604160135 The Sahara driver currently selects firmware image tables using scattered, device specific conditionals in the probe path. This makes the logic harder to follow, harder to extend for new devices, and spreads device knowledge across multiple code paths. Refactor firmware image table selection into a single, explicit probe time mechanism by introducing a controller provided firmware mapping table that captures device matching, Sahara image tables, firmware folder names, and streaming behaviour in one place. This centralizes device specific decisions in the controller driver, simplifies the Sahara probe logic, and removes ad-hoc conditionals while preserving existing behavior for all supported AIC devices. This is in preparation for adding QDU100 support. Signed-off-by: Kishore Batta --- drivers/accel/qaic/mhi_controller.c | 61 ++++++++++++++++++++++++= ++++ drivers/bus/mhi/host/clients/sahara/sahara.c | 60 +++++-------------------= --- include/linux/mhi.h | 17 ++++++++ 3 files changed, 88 insertions(+), 50 deletions(-) diff --git a/drivers/accel/qaic/mhi_controller.c b/drivers/accel/qaic/mhi_c= ontroller.c index 4d787f77ce419fcd2b250f9cabaec9c26f2da8dc..1f9ef871421b976c35cfad59aed= 715da96c1813b 100644 --- a/drivers/accel/qaic/mhi_controller.c +++ b/drivers/accel/qaic/mhi_controller.c @@ -20,6 +20,62 @@ static unsigned int mhi_timeout_ms =3D 2000; /* 2 sec de= fault */ module_param(mhi_timeout_ms, uint, 0600); MODULE_PARM_DESC(mhi_timeout_ms, "MHI controller timeout value"); =20 +static const char * const aic100_image_table[] =3D { + [1] =3D "qcom/aic100/fw1.bin", + [2] =3D "qcom/aic100/fw2.bin", + [4] =3D "qcom/aic100/fw4.bin", + [5] =3D "qcom/aic100/fw5.bin", + [6] =3D "qcom/aic100/fw6.bin", + [8] =3D "qcom/aic100/fw8.bin", + [9] =3D "qcom/aic100/fw9.bin", + [10] =3D "qcom/aic100/fw10.bin", +}; + +static const char * const aic200_image_table[] =3D { + [5] =3D "qcom/aic200/uefi.elf", + [12] =3D "qcom/aic200/aic200-nsp.bin", + [23] =3D "qcom/aic200/aop.mbn", + [32] =3D "qcom/aic200/tz.mbn", + [33] =3D "qcom/aic200/hypvm.mbn", + [38] =3D "qcom/aic200/xbl_config.elf", + [39] =3D "qcom/aic200/aic200_abl.elf", + [40] =3D "qcom/aic200/apdp.mbn", + [41] =3D "qcom/aic200/devcfg.mbn", + [42] =3D "qcom/aic200/sec.elf", + [43] =3D "qcom/aic200/aic200-hlos.elf", + [49] =3D "qcom/aic200/shrm.elf", + [50] =3D "qcom/aic200/cpucp.elf", + [51] =3D "qcom/aic200/aop_devcfg.mbn", + [54] =3D "qcom/aic200/qupv3fw.elf", + [57] =3D "qcom/aic200/cpucp_dtbs.elf", + [62] =3D "qcom/aic200/uefi_dtbs.elf", + [63] =3D "qcom/aic200/xbl_ac_config.mbn", + [64] =3D "qcom/aic200/tz_ac_config.mbn", + [65] =3D "qcom/aic200/hyp_ac_config.mbn", + [66] =3D "qcom/aic200/pdp.elf", + [67] =3D "qcom/aic200/pdp_cdb.elf", + [68] =3D "qcom/aic200/sdi.mbn", + [69] =3D "qcom/aic200/dcd.mbn", + [73] =3D "qcom/aic200/gearvm.mbn", + [74] =3D "qcom/aic200/sti.bin", + [76] =3D "qcom/aic200/tz_qti_config.mbn", + [78] =3D "qcom/aic200/pvs.bin", +}; + +static const struct mhi_sahara_fw_table aic100_sahara_fw =3D { + .image_table =3D aic100_image_table, + .table_size =3D ARRAY_SIZE(aic100_image_table), + .fw_folder =3D "aic100", + .non_streaming =3D true, +}; + +static const struct mhi_sahara_fw_table aic200_sahara_fw =3D { + .image_table =3D aic200_image_table, + .table_size =3D ARRAY_SIZE(aic200_image_table), + .fw_folder =3D "aic200", + .non_streaming =3D false, +}; + static const char *fw_image_paths[FAMILY_MAX] =3D { [FAMILY_AIC100] =3D "qcom/aic100/sbl.bin", [FAMILY_AIC200] =3D "qcom/aic200/sbl.bin", @@ -871,6 +927,11 @@ struct mhi_controller *qaic_mhi_register_controller(st= ruct pci_dev *pci_dev, voi mhi_cntrl->name =3D "AIC100"; } =20 + if (mhi_cntrl->name && !strcmp(mhi_cntrl->name, "AIC100")) + mhi_cntrl->sahara_fw =3D &aic100_sahara_fw; + else if (mhi_cntrl->name && !strcmp(mhi_cntrl->name, "AIC200")) + mhi_cntrl->sahara_fw =3D &aic200_sahara_fw; + /* use latest configured timeout */ mhi_config.timeout_ms =3D mhi_timeout_ms; ret =3D mhi_register_controller(mhi_cntrl, &mhi_config); diff --git a/drivers/bus/mhi/host/clients/sahara/sahara.c b/drivers/bus/mhi= /host/clients/sahara/sahara.c index 858dc5bc39c1ad42922cabef3b1abcd43bc4f0f4..e339c67e236af271645ca81cc51= 7efd9eead87e4 100644 --- a/drivers/bus/mhi/host/clients/sahara/sahara.c +++ b/drivers/bus/mhi/host/clients/sahara/sahara.c @@ -179,48 +179,7 @@ struct sahara_context { u32 read_data_length; bool is_mem_dump_mode; bool non_streaming; -}; - -static const char * const aic100_image_table[] =3D { - [1] =3D "qcom/aic100/fw1.bin", - [2] =3D "qcom/aic100/fw2.bin", - [4] =3D "qcom/aic100/fw4.bin", - [5] =3D "qcom/aic100/fw5.bin", - [6] =3D "qcom/aic100/fw6.bin", - [8] =3D "qcom/aic100/fw8.bin", - [9] =3D "qcom/aic100/fw9.bin", - [10] =3D "qcom/aic100/fw10.bin", -}; - -static const char * const aic200_image_table[] =3D { - [5] =3D "qcom/aic200/uefi.elf", - [12] =3D "qcom/aic200/aic200-nsp.bin", - [23] =3D "qcom/aic200/aop.mbn", - [32] =3D "qcom/aic200/tz.mbn", - [33] =3D "qcom/aic200/hypvm.mbn", - [38] =3D "qcom/aic200/xbl_config.elf", - [39] =3D "qcom/aic200/aic200_abl.elf", - [40] =3D "qcom/aic200/apdp.mbn", - [41] =3D "qcom/aic200/devcfg.mbn", - [42] =3D "qcom/aic200/sec.elf", - [43] =3D "qcom/aic200/aic200-hlos.elf", - [49] =3D "qcom/aic200/shrm.elf", - [50] =3D "qcom/aic200/cpucp.elf", - [51] =3D "qcom/aic200/aop_devcfg.mbn", - [54] =3D "qcom/aic200/qupv3fw.elf", - [57] =3D "qcom/aic200/cpucp_dtbs.elf", - [62] =3D "qcom/aic200/uefi_dtbs.elf", - [63] =3D "qcom/aic200/xbl_ac_config.mbn", - [64] =3D "qcom/aic200/tz_ac_config.mbn", - [65] =3D "qcom/aic200/hyp_ac_config.mbn", - [66] =3D "qcom/aic200/pdp.elf", - [67] =3D "qcom/aic200/pdp_cdb.elf", - [68] =3D "qcom/aic200/sdi.mbn", - [69] =3D "qcom/aic200/dcd.mbn", - [73] =3D "qcom/aic200/gearvm.mbn", - [74] =3D "qcom/aic200/sti.bin", - [76] =3D "qcom/aic200/tz_qti_config.mbn", - [78] =3D "qcom/aic200/pvs.bin", + const char *fw_folder; }; =20 static bool is_streaming(struct sahara_context *context) @@ -796,6 +755,7 @@ static void sahara_read_data_processing(struct work_str= uct *work) =20 static int sahara_mhi_probe(struct mhi_device *mhi_dev, const struct mhi_d= evice_id *id) { + const struct mhi_sahara_fw_table *sahara_fw; struct sahara_context *context; int ret; int i; @@ -808,14 +768,14 @@ static int sahara_mhi_probe(struct mhi_device *mhi_de= v, const struct mhi_device_ if (!context->rx) return -ENOMEM; =20 - if (!strcmp(mhi_dev->mhi_cntrl->name, "AIC200")) { - context->image_table =3D aic200_image_table; - context->table_size =3D ARRAY_SIZE(aic200_image_table); - } else { - context->image_table =3D aic100_image_table; - context->table_size =3D ARRAY_SIZE(aic100_image_table); - context->non_streaming =3D true; - } + sahara_fw =3D mhi_dev->mhi_cntrl->sahara_fw; + if (!sahara_fw || !sahara_fw->image_table || !sahara_fw->table_size) + return -ENODEV; + + context->image_table =3D sahara_fw->image_table; + context->table_size =3D sahara_fw->table_size; + context->non_streaming =3D sahara_fw->non_streaming; + context->fw_folder =3D sahara_fw->fw_folder; =20 /* * There are two firmware implementations for READ_DATA handling. diff --git a/include/linux/mhi.h b/include/linux/mhi.h index 88ccb3e14f481d6b85c2a314eb74ba960c2d4c81..060dafffac67c5c920adc1562a6= 1a7233e8d583f 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -234,6 +234,21 @@ struct mhi_channel_config { bool wake_capable; }; =20 +/** + * struct mhi_sahara_fw_table - Controller provided sahara firmware mapping + * @image_table: Sparse array indexed by Sahara image ID + * @table_size: Size of @image_table + * @fw_folder: Firmware folder name. + * @non_streaming: Streaming feature support (optional) + * + */ +struct mhi_sahara_fw_table { + const char *const *image_table; + u32 table_size; + const char *fw_folder; + bool non_streaming; +}; + /** * struct mhi_event_config - Event ring configuration structure for contro= ller * @num_elements: The number of elements that can be queued to this ring @@ -360,6 +375,7 @@ struct mhi_controller_config { * @wake_set: Device wakeup set flag * @irq_flags: irq flags passed to request_irq (optional) * @mru: the default MRU for the MHI device + * @sahara_fw: Sahara firmware mapping * * Fields marked as (required) need to be populated by the controller driv= er * before calling mhi_register_controller(). For the fields marked as (opt= ional) @@ -445,6 +461,7 @@ struct mhi_controller { bool wake_set; unsigned long irq_flags; u32 mru; + const struct mhi_sahara_fw_table *sahara_fw; }; =20 /** --=20 2.34.1 From nobody Tue Jun 16 05:19:42 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (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 537763D565F for ; Thu, 16 Apr 2026 14:10:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776348624; cv=none; b=uE6YX9s9pxSYmE09VGyGFCxynyatN3yL6MgGQFQK6QBDVjcPf1/ZTnw8X3DnqV/zJedr1kUcySF+guXNmr5gL08C5+SdAMYjo2i6V2iIq325WacjvjNYBuA5roWW3LqgE2GMgFizaqsikvbK6ilHOGIcVaaf9qd2pdUM6Rxn/kU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776348624; c=relaxed/simple; bh=y9g67LoOAK1zIYhgVoqMtpnLtPZtPHG+SZ4nbuUAoiw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GlxdIaaVRNml+cdkG9ItwxYG+Nor2URHwTPGkh5SAZArJkac12YQhzYltJYeYjBpToSW37v65eAi2ynmQuTOD1t/dGZEa2xoolhF47YPdTJWkBv4Y9kGM1ITK6FiFRu2OMLEzpSLJ8ycrJglJ+RgJFCGUL/IR7yStzMP9mXhnUs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=hpm0hb/b; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=KLH3+2Bz; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="hpm0hb/b"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="KLH3+2Bz" Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 63GDqcpH2596141 for ; Thu, 16 Apr 2026 14:10:20 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= eWnkB32rC8c/c1FmukfGJLAkXTQ/yzUwW5QZTJ1tuHA=; b=hpm0hb/bFNhRlhQm 0sLAALK9V93qPCce9b7ucLX45C1dmbYi2MfOxGGbKdeMgk3bRnhiLISNPQVYGE8n bHXIbaoGh1O1bNQGXY6+pSU9PzeHuxb0BGwoiYG/8aZdmeYLbrVUMIPQAM4qP0kd 24cTtIKc/8Rn9rbjW35pL37BsP+PbwRJmbpt+7Kkow+9z3nd+ZXLi+D993MvUGIQ soIQm3mXVTq+2n8ZqQbfGR+E0v9NoWG4E5FF9MwW0Ipb2iF63ZQQbx0NaTE4RpaS 7awyScIBfjNsPSgM9EAVqmxrjztZ6B3xELGfZ9LwM12ZS5V4QdMJnF1mEib1+3fS 66BY1A== Received: from mail-yw1-f197.google.com (mail-yw1-f197.google.com [209.85.128.197]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4dk11r823g-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 16 Apr 2026 14:10:18 +0000 (GMT) Received: by mail-yw1-f197.google.com with SMTP id 00721157ae682-799003e8a77so259030627b3.2 for ; Thu, 16 Apr 2026 07:10:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1776348617; x=1776953417; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=eWnkB32rC8c/c1FmukfGJLAkXTQ/yzUwW5QZTJ1tuHA=; b=KLH3+2BzW+Pr4AiV8yf/YS0ZdJSSuwSYIeF33V/w5QmErH1zn3YfLaqktmru0INXVv KFUSVFBwx59xwkgmk94pib1jiW9KljHXxkg9eRWsZfYF+l6HhRqdE9MRJ5MsXHX9NWaw wo8l/c0wbxlFaRq3EwIEVWyuC1vRilk1GVZTzQngBtNbrlqXMV9yZ5jdMtF3lTUQ2MdH LjBGOVYXrdTjSNAwAX+hVtgDkmk1V5uc+6rz1NXGsDgpddaffMDhFzgYFCc1Ln6RVTBO c4XeQsIqIpcE0sVy6tk/3ikEaqN8K6AGk+c/Vcqxzs1zJ6SlA/AtVE6o5sM9BoEbE93m XoSw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776348617; x=1776953417; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=eWnkB32rC8c/c1FmukfGJLAkXTQ/yzUwW5QZTJ1tuHA=; b=pP7y2a3Qcr1r6PMTf9NN7IrEB3m7iQsatF3k+6A+JMTXBO8AnxSDJJ1AL6akuIJ2z9 rmvbtCI5uqDhhEm19nnc1YWCV72WuhzlQFPn8t2/tM+MEE5q1HcgjCv6DsuKL3qPxv9g b7P/AkZT/vgvS/aYKD9dlfxLNyDLMQnQyruur9TsXfXBCaNQm95QQbNW4ErR5/k7hfWf 6VqF+GWIcssen0Qhv36PcZ7tXlq3R6ksQrXNHYoOFZsLbhixS1u46Ea7YemQ3HSLqOj9 9IMbYPEjOSiWfCY/2qxPC/HFxbe4xjtuBXfFXM/1luC6AbQXvJkWfwGU+0hK/qGUcCO/ lyZg== X-Forwarded-Encrypted: i=1; AFNElJ8hskBDDlzRUcsy1gY9RqbVExllBq8DWWeEoHdA2h+S1R5Qb9y8/LMSYJnrftf2fIayJJzk9Cj+9LCVUxQ=@vger.kernel.org X-Gm-Message-State: AOJu0YzbBca4UeqGhZGdD48Azk92GUejFyeA4Y8EZD8zfFTk5qwwEjNq JNrVq5SPegqFLoTf/NRMTS+qcqCcHLiIkn1/8w+9BMeYvB0ZmVpM0AhWy9e4qfOBv7PQhL51pUx K6MJWviABJcNHTFGA/Ne9PU+B9U+XKawL7fyuFfwLaenflklCjSOjbSbwhQiCOGfy4gc= X-Gm-Gg: AeBDiev6xFVc/DOL2T0/KKe1mgQ4m89Y3k4oVh7GlvfuDXha/3Cl2kH73MosPh4WIYd kNAbQucXtM6QaT0QAP/uEbd4cE8EnlqzKhSUe7hxecXsC1AbWS+rpJ7ljC6UIxFcJ8E0rDUaAfy eMtLEKJuSYZdYG+WD7dyLV14OZU4JdXSUpfKqTnyeV3R5DODAyrOlA/R5f0vw8QSIWr4lo3VaE6 SEeUwwrjxgtFP5svP/B0/IHoapcyz2mDlCPYHz0dSySszBpq7ZlgC4d0VF5p8sA+EBw+CrD0Lir MF4ik1VyBxB3Wq1rDmOHIIKJTUxPCCLEiv7Tt3A90BHi8g1HlYZmBfcAU2K+lOGt4+jGEqFU6fl J3lM5PjQL7lJRO2SpPsWxU7/S8L95pw/g1BOeInodaeq/VMc0RKg= X-Received: by 2002:a05:690e:4093:b0:652:b4cf:5f4a with SMTP id 956f58d0204a3-652b4cf6489mr9471021d50.37.1776348617281; Thu, 16 Apr 2026 07:10:17 -0700 (PDT) X-Received: by 2002:a05:690e:4093:b0:652:b4cf:5f4a with SMTP id 956f58d0204a3-652b4cf6489mr9470976d50.37.1776348616813; Thu, 16 Apr 2026 07:10:16 -0700 (PDT) Received: from hu-batta-hyd.qualcomm.com ([202.46.23.25]) by smtp.gmail.com with ESMTPSA id 956f58d0204a3-652e47ba4a3sm2084691d50.17.2026.04.16.07.10.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Apr 2026 07:10:16 -0700 (PDT) From: Kishore Batta Date: Thu, 16 Apr 2026 19:39:45 +0530 Subject: [PATCH v5 4/7] bus: mhi: Add QDU100 Sahara variant and firmware fallback Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260416-sahara_protocol_new_v2-v5-4-6aebf005e4ba@oss.qualcomm.com> References: <20260416-sahara_protocol_new_v2-v5-0-6aebf005e4ba@oss.qualcomm.com> In-Reply-To: <20260416-sahara_protocol_new_v2-v5-0-6aebf005e4ba@oss.qualcomm.com> To: Jonathan Corbet , Shuah Khan , Jeff Hugo , Carl Vanderlip , Oded Gabbay , Manivannan Sadhasivam Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, mhi@lists.linux.dev, Kishore Batta X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1776348592; l=5296; i=kishore.batta@oss.qualcomm.com; s=20260206; h=from:subject:message-id; bh=y9g67LoOAK1zIYhgVoqMtpnLtPZtPHG+SZ4nbuUAoiw=; b=moq8nUJ0iUz8BQ2TQ8GG3ft1cyqL1DFfDQ3UYv2eS/Qyql41eeEq9JnLpiDH0cxJMFU/XU1RY QA9H7PAlju6BGFBKd2Mucqmhx7mTeCTRhGPO2W6QwUfnz1rrBJEfDSM X-Developer-Key: i=kishore.batta@oss.qualcomm.com; a=ed25519; pk=vJo8RvTf+HZpRLK2oOIljmbn9l3zFkibCGh+blaqZCw= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNDE2MDEzNiBTYWx0ZWRfXy+GygIFEmlcM Uh4FoLtUoW3iMjRId2pgAyJ+jK35WJBcmpgn+xWERaaFBCLx2rcTIQblKhc+rqZQrUNP/vEqQES xanveqx2+vkn88a9N0lldIJ9ExWpdejXQnrCbsqRoF9FgBfFj53X6aW+ib1PiDYFwTkvriV3uXd CzEeRJuldRZMF4tD9XErHiz1NCB2fhie1F7gv7EjllbWBJoFkD+sQ2OZ/g2DjlWg79ZPVP/D5zF Shncjh+iTfNsRMR7ArPjYcybbuag8ilXhwe101/rcn1AHy6Q9PJNH8Zwauv2PfSqdF6WcXKY/0t 1Z35OL2UDC3q96G16fVfdkXywCYYKV1KF3BDQboU8Q0gHvXoVQcnAsDUSRYBC6odmXwlmA8Axjj sqqS/J2GKALBRabVwbTTvLePEHFwqtwd+6yYLJcFbBFRAAa//HBpGzPaRkCrurnpJ2BhdGnk9rk 5pTfrewSAceg7obb6Vw== X-Authority-Analysis: v=2.4 cv=ZPznX37b c=1 sm=1 tr=0 ts=69e0edca cx=c_pps a=0mLRTIufkjop4KoA/9S1MA==:117 a=ZePRamnt/+rB5gQjfz0u9A==:17 a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=eoimf2acIAo5FJnRuUoq:22 a=EUspDBNiAAAA:8 a=3TBL8zyTcm-CCHetwZgA:9 a=QEXdDO2ut3YA:10 a=WgItmB6HBUc_1uVUp3mg:22 X-Proofpoint-ORIG-GUID: Xw2NDVdzDCESngLe8NKvKXqAtO5p0P7p X-Proofpoint-GUID: Xw2NDVdzDCESngLe8NKvKXqAtO5p0P7p X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-04-16_03,2026-04-16_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 priorityscore=1501 suspectscore=0 lowpriorityscore=0 spamscore=0 adultscore=0 bulkscore=0 malwarescore=0 clxscore=1015 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604070000 definitions=main-2604160136 The Sahara driver currently selects a firmware image table based on the attached device, but it does not recognize QDU100 devices that expose the protocol on the SAHARA MHI channel. As a result, the host cannot associate QDU100 devices with the correct firmware namespace during image transfer. Extend the probe time variant selection to match the SAHARA MHI channel and associate it with the QDU100 firmware folder. Add a firmware lookup fallback for cases where an image does not have an explicit entry in the device's firmware table. This allows required images to be provisioned by the platform. This change only affects devices matched on the SAHARA MHI channel and does not change behavior for existing AIC100 and AIC200 devices. Signed-off-by: Kishore Batta --- drivers/bus/mhi/host/clients/sahara/sahara.c | 27 +++++++++++++++-- drivers/bus/mhi/host/pci_generic.c | 45 ++++++++++++++++++++++++= ++++ 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/drivers/bus/mhi/host/clients/sahara/sahara.c b/drivers/bus/mhi= /host/clients/sahara/sahara.c index e339c67e236af271645ca81cc517efd9eead87e4..9adbd84859073d8024ba2a5fcfa= 33897439d6759 100644 --- a/drivers/bus/mhi/host/clients/sahara/sahara.c +++ b/drivers/bus/mhi/host/clients/sahara/sahara.c @@ -189,6 +189,7 @@ static bool is_streaming(struct sahara_context *context) =20 static int sahara_find_image(struct sahara_context *context, u32 image_id) { + char *fw_path; int ret; =20 if (image_id =3D=3D context->active_image_id) @@ -201,8 +202,28 @@ static int sahara_find_image(struct sahara_context *co= ntext, u32 image_id) } =20 if (image_id >=3D context->table_size || !context->image_table[image_id])= { - dev_err(&context->mhi_dev->dev, "request for unknown image: %d\n", image= _id); - return -EINVAL; + if (!context->fw_folder) { + dev_err(&context->mhi_dev->dev, + "Request for unknown image: %u (no fw folder)\n", image_id); + return -EINVAL; + } + + fw_path =3D kasprintf(GFP_KERNEL, "qcom/%s/%u", + context->fw_folder, image_id); + if (!fw_path) + return -ENOMEM; + + ret =3D firmware_request_nowarn(&context->firmware, + fw_path, + &context->mhi_dev->dev); + kfree(fw_path); + if (ret) { + dev_err(&context->mhi_dev->dev, + "request for unknown image: %d\n", image_id); + return -EINVAL; + } + context->active_image_id =3D image_id; + return 0; } =20 /* @@ -870,8 +891,10 @@ static void sahara_mhi_dl_xfer_cb(struct mhi_device *m= hi_dev, struct mhi_result =20 static const struct mhi_device_id sahara_mhi_match_table[] =3D { { .chan =3D "QAIC_SAHARA", }, + { .chan =3D "SAHARA"}, {}, }; +MODULE_DEVICE_TABLE(mhi, sahara_mhi_match_table); =20 static struct mhi_driver sahara_mhi_driver =3D { .id_table =3D sahara_mhi_match_table, diff --git a/drivers/bus/mhi/host/pci_generic.c b/drivers/bus/mhi/host/pci_= generic.c index 391ab146f501c6ce1c81f6138f7c491a49c2f264..82e41632afc555a53dec3d83955= 58ae039b33bbd 100644 --- a/drivers/bus/mhi/host/pci_generic.c +++ b/drivers/bus/mhi/host/pci_generic.c @@ -300,6 +300,43 @@ static const struct mhi_pci_dev_info mhi_qcom_qdu100_i= nfo =3D { .reset_on_remove =3D true, }; =20 +static const char * const qdu100_image_table[] =3D { + [5] =3D "qcom/qdu100/uefi.elf", + [8] =3D "qcom/qdu100/qdsp6sw.mbn", + [16] =3D "qcom/qdu100/efs1.bin", + [17] =3D "qcom/qdu100/efs2.bin", + [20] =3D "qcom/qdu100/efs3.bin", + [23] =3D "qcom/qdu100/aop.mbn", + [25] =3D "qcom/qdu100/tz.mbn", + [29] =3D "qcom/qdu100/zeros_1sector.bin", + [33] =3D "qcom/qdu100/hypvm.mbn", + [34] =3D "qcom/qdu100/mdmddr.mbn", + [36] =3D "qcom/qdu100/multi_image_qti.mbn", + [37] =3D "qcom/qdu100/multi_image.mbn", + [38] =3D "qcom/qdu100/xbl_config.elf", + [39] =3D "qcom/qdu100/abl_userdebug.elf", + [40] =3D "qcom/qdu100/zeros_1sector.bin", + [41] =3D "qcom/qdu100/devcfg.mbn", + [42] =3D "qcom/qdu100/zeros_1sector.bin", + [45] =3D "qcom/qdu100/tools_l.elf", + [46] =3D "qcom/qdu100/Quantum.elf", + [47] =3D "qcom/qdu100/quest.elf", + [48] =3D "qcom/qdu100/xbl_ramdump.elf", + [49] =3D "qcom/qdu100/shrm.elf", + [50] =3D "qcom/qdu100/cpucp.elf", + [51] =3D "qcom/qdu100/aop_devcfg.mbn", + [52] =3D "qcom/qdu100/fw_csm_gsi_3.0.elf", + [53] =3D "qcom/qdu100/qdsp6sw_dtbs.elf", + [54] =3D "qcom/qdu100/qupv3fw.elf", +}; + +static const struct mhi_sahara_fw_table qdu100_sahara_fw =3D { + .image_table =3D qdu100_image_table, + .table_size =3D ARRAY_SIZE(qdu100_image_table), + .fw_folder =3D "qdu100", + .non_streaming =3D false, +}; + static const struct mhi_channel_config mhi_qcom_sa8775p_channels[] =3D { MHI_CHANNEL_CONFIG_UL(46, "IP_SW0", 2048, 1), MHI_CHANNEL_CONFIG_DL(47, "IP_SW0", 2048, 2), @@ -1399,6 +1436,14 @@ static int mhi_pci_probe(struct pci_dev *pdev, const= struct pci_device_id *id) =20 pci_set_drvdata(pdev, mhi_pdev); =20 + /* + * Provide Sahara firmware mapping. Sahara consumes it via + * mhi_dev->mhi_cntrl->sahara_fw at probe time. + */ + if (info =3D=3D &mhi_qcom_qdu100_info || + (info->name && !strcmp(info->name, "qcom-qdu100"))) + mhi_cntrl->sahara_fw =3D &qdu100_sahara_fw; + /* Have stored pci confspace at hand for restore in sudden PCI error. * cache the state locally and discard the PCI core one. */ --=20 2.34.1 From nobody Tue Jun 16 05:19:42 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (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 B84793DEADE for ; Thu, 16 Apr 2026 14:10:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776348627; cv=none; b=LR6PCyLpU54x7PecLWXRSIR6twyO/QDstf+iqXu+j4ljY4BA5Dpodyco1L5MxRXEspT+R/jcA+oADkKPzqS75sLNpIGtkdYKuMIq9oH9T76IJgkDa5mLEBJyN/1oj0OZf2MVlMlGtZxVjkbwo0UhahQIHJLqNqMBIPIivCOpq4A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776348627; c=relaxed/simple; bh=Ai7Oj6HYo2DVpdnuStjVjQuKPI6ELc1HNULGnu45Dq0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=vFYMrUrg3FbHqnlS8hXgCLN0PznYDM6qEhzB6MJXaUitx7ti4BtXcv8YWXagqSLKH4CCYyqCvtIGeAWnmC5S8r5u2Txvp5G+TBEfqC7f2Qmwua14zFAlYEZjg5sES+gubVnj6LSL/XWIEXMDXIAmxz2wTSgGGnbsboSYn0knBbg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=NXJghhS5; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=hSKPdgPi; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="NXJghhS5"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="hSKPdgPi" Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 63G9JkKX1553312 for ; Thu, 16 Apr 2026 14:10:25 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= ILMb+mV5AdAqlIxF1QaEkI31w6HYyIF9XcVFgHuAyCo=; b=NXJghhS5Y94uTiXh vlaoOzTtkgnGrV/O/geMhThLlUVMw8E1bxPcKsZvAgXcoJPChVCz3IMqMo0wbfE0 EySpjaAInNHKjpobrxamxOBMsbIdPCRSMh9oBk+C9LG0vhofKInNpjITY+Qz1Bay FreF+ohwj+wyWwe407n7DgHPNivediP6JqFGifIDQKMkeSBXKSqQF9a2nTgBbuGt IcqjyXefR6/DkUFclSaMwi963/nxTlVxtzidNvIrc6xVBozHmQ15fbmh6guJaUs1 aIBR/WSgiF7tWlYcfW88XNVmR3grySvdTGisYgZmZTcydd71Lu1yVf9FzgX8GAdM kUtt6A== Received: from mail-yx1-f72.google.com (mail-yx1-f72.google.com [74.125.224.72]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4djrsn9ygm-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 16 Apr 2026 14:10:24 +0000 (GMT) Received: by mail-yx1-f72.google.com with SMTP id 956f58d0204a3-651bd2131f0so10805635d50.3 for ; Thu, 16 Apr 2026 07:10:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1776348624; x=1776953424; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=ILMb+mV5AdAqlIxF1QaEkI31w6HYyIF9XcVFgHuAyCo=; b=hSKPdgPibvf1A2iTHGKhtbTEdTfJGZHA+nRHaWmeaA/3PYUVW4rbSilyDepK6HsU9K d21xGGo2LwoNC87QbykozP5ljlEv06bw6ymfzylkNE9yUH4HEEtbONNzgt5qM5L7v4yn jrT2B8oEzENmhsxyyLUUTb8qxWQ7ZvUXaGn9JXFDKFsoppUgsWBvL2hOI5HjJYRX4oh9 SswQrsBnV6sSClsDu0WH+BqZ5GAVqa/SBYFJ6j0hNfIwASJzQ+VC0+6VkZi0xyxVnaQl b6c8AV9byAkXUO91fciKmRCtrh9WAiwrj+ngi9oYIXRVV0nkW99ABnSM3abi1YxYyCR4 r2rQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776348624; x=1776953424; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=ILMb+mV5AdAqlIxF1QaEkI31w6HYyIF9XcVFgHuAyCo=; b=Yl67cJ/LDgDKG2Mi9rDwgtwUXXZeJf9a8iQPxbfeBPT52InTo2kb+7ce59NEDiUKKh lYC9aeRFfTtSyd55hvelliwq+Dr3x3EKUTC1rVvNukruLHb3i+dQaHuO0k7uzmByjtXQ BAOOWpLQkAWAhxlaPnSvrNoXlpf6m0zArucDrYJ+kLvzTIQb5UEPwcQtQT0krKnZ/QTK BaWuxaBP0DCDRuxTPcWklguH1eKKLSEQ2yb7eorZgq220izmHRpfzKL3oxE7FqH0VW4W XNU5XxISecXZvKAdEyqNEIIB5Pw+ZOLaLjr5hgnH92/0Gb92pQ3ynpe48zhj4Ysnwf8g zGew== X-Forwarded-Encrypted: i=1; AFNElJ+3krSagk5Q0f4OANPFtIXlj6LY6yEssHUvBifhcAsbzz5IFfxy9cj8UBlFqEfoL/NHv5ktWIEVT2psWH4=@vger.kernel.org X-Gm-Message-State: AOJu0Yz8zvk1UdDwCeNhyo/9zp26HvNtnTPOpyowLKeNWeuQSaVEDP8N YZ2KqwtUX2NzihxkvRtkjmMpQ5B+M9Tg1JS/CZa1RomiH6DuulqPaIT9ATk4+hmk4cCdQDA2Ub7 UWGvq9+9baT+lBWGQLntAwttb8vZs45YBKgY1jcZRWMWWP/o7jdAp3ukGowraCFy4D5w= X-Gm-Gg: AeBDieuXEu0TxIH2XK0VGBavF4J9YnnQUmtsCA4Os1vacgUWxE8Dr2h3uwpvj8DV+Jg wBvOCNuoL1NGnzLjvLvMPEByCulMwGrTxh7eAhXnMvsfw3QvuNxZ+2DmWY+WH4uuHwSppCXPEc4 Z1ADSm8wxMCm5I0Y6ZMzSeGwbwKOFbd4oHJACZpirDTGQwTeXkBVSts6OjufvSsuz+JfPynY9WV TGbFcAZinnPZQAHi/mmYPN38Y03c85uBRYm1UoF2gsxdiSTq68IHwaDBxx+CmLpYdulJq94GZz7 IjE6haw85Oi8F5Zt/t8Go+aDWmDyfViEQUvB+d5qWfqxKmIihKpkxwmEdROoaX0G2R/Vkm7Qaha m5TTiQQ5XyTEMUBQz+fyLV/gL5qKc7NqzNLsGISB7vjzNmqHeRys= X-Received: by 2002:a53:b6ce:0:b0:650:7846:f326 with SMTP id 956f58d0204a3-65198bb5341mr17653929d50.51.1776348623063; Thu, 16 Apr 2026 07:10:23 -0700 (PDT) X-Received: by 2002:a53:b6ce:0:b0:650:7846:f326 with SMTP id 956f58d0204a3-65198bb5341mr17653845d50.51.1776348621719; Thu, 16 Apr 2026 07:10:21 -0700 (PDT) Received: from hu-batta-hyd.qualcomm.com ([202.46.23.25]) by smtp.gmail.com with ESMTPSA id 956f58d0204a3-652e47ba4a3sm2084691d50.17.2026.04.16.07.10.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Apr 2026 07:10:21 -0700 (PDT) From: Kishore Batta Date: Thu, 16 Apr 2026 19:39:46 +0530 Subject: [PATCH v5 5/7] bus: mhi: Load DDR training data using device serial number Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260416-sahara_protocol_new_v2-v5-5-6aebf005e4ba@oss.qualcomm.com> References: <20260416-sahara_protocol_new_v2-v5-0-6aebf005e4ba@oss.qualcomm.com> In-Reply-To: <20260416-sahara_protocol_new_v2-v5-0-6aebf005e4ba@oss.qualcomm.com> To: Jonathan Corbet , Shuah Khan , Jeff Hugo , Carl Vanderlip , Oded Gabbay , Manivannan Sadhasivam Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, mhi@lists.linux.dev, Kishore Batta X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1776348592; l=2770; i=kishore.batta@oss.qualcomm.com; s=20260206; h=from:subject:message-id; bh=Ai7Oj6HYo2DVpdnuStjVjQuKPI6ELc1HNULGnu45Dq0=; b=WWlNVMISE32YzOacAObQV7dNIdXlO1BGZ6LObollUK2JIrhEPezGqcUbkpsBTUSpn3s2vLrDp UNhQYOZM7PhB+Q1nzHDwRgrwZHLL44tf02jQlSCFTctKmH9zRJSHFeq X-Developer-Key: i=kishore.batta@oss.qualcomm.com; a=ed25519; pk=vJo8RvTf+HZpRLK2oOIljmbn9l3zFkibCGh+blaqZCw= X-Proofpoint-ORIG-GUID: o3MgLIF4U1pG_zD3v7ipnf2Z3kbUDdgQ X-Proofpoint-GUID: o3MgLIF4U1pG_zD3v7ipnf2Z3kbUDdgQ X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNDE2MDEzNiBTYWx0ZWRfXzQ4C3YAgaikq CmssxGEyyuh+y3YuJuQ0gKGpGn+cY/TzZzECgIZGNVuny7IpxLIAktR4E+6yg8IS4DOYFM1zESO TNB5nMASIXVJNIz2zASjW9aYVxxgdzX9LAsurbWROT8VY3sNE/245Liz8zC10jeCI9Hvzce2Bpn tm2MampuijxofwZ7TRbQwH2Q4fYQj74mV0uvoUtG8nIpbTo5x5CZDHP1JaypLsDw+7gt/lAEBmF pPcxE3qe9sSW0gJ/S+Zu+diYUHqSsmv8AS+pmTWQMF7jQ1KO/NaVXOL5B+RnmKEKS78HeXwVKm0 DHuYnwrxOXHLoliPyeIsIO67PygGQ3lCDXaEdsojf/bWP9B3cY35b6oYmxdaotzPO9dj+x8GV8e +Ogyet0Tdrc6RDfSlArgunn5/kzoY98XHsuj6YiRoeqKYg/7n9NhEpqae7PsWRNzLU2GPbYF4H3 yeu7+BbHhsBmr0ccP+w== X-Authority-Analysis: v=2.4 cv=EojiaycA c=1 sm=1 tr=0 ts=69e0edd0 cx=c_pps a=VEzVgl358Dq0xwHDEbsOzA==:117 a=ZePRamnt/+rB5gQjfz0u9A==:17 a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=yOCtJkima9RkubShWh1s:22 a=EUspDBNiAAAA:8 a=ICgrKnnyuXbdZ-Zkjz4A:9 a=QEXdDO2ut3YA:10 a=uujmmnXaIg8lM0-o0HFK:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-04-16_03,2026-04-16_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 bulkscore=0 adultscore=0 spamscore=0 phishscore=0 impostorscore=0 suspectscore=0 lowpriorityscore=0 malwarescore=0 clxscore=1015 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604070000 definitions=main-2604160136 Devices may provide device specific DDR training data that can be reused across boot to avoid retraining and reduce boot time. The Sahara driver currently always falls back to the default DDR training image, even when serial specific training data is available. Extend the firmware loading logic for the DDR training image to first attempt loading a per-device image dervied from the device serial number. If the serial-specific image is not present, fall back to the existing default image, preserving current behavior. This allows reuse of previously generated DDR training data when available, while keeping the existing training flow unchanged for devices without saved data or for all other firmware images. Signed-off-by: Kishore Batta --- drivers/bus/mhi/host/clients/sahara/sahara.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/bus/mhi/host/clients/sahara/sahara.c b/drivers/bus/mhi= /host/clients/sahara/sahara.c index 9adbd84859073d8024ba2a5fcfa33897439d6759..b5ca6353540dc3815db6539e742= 4afdb749fd3f6 100644 --- a/drivers/bus/mhi/host/clients/sahara/sahara.c +++ b/drivers/bus/mhi/host/clients/sahara/sahara.c @@ -59,6 +59,7 @@ #define SAHARA_RESET_LENGTH 0x8 #define SAHARA_MEM_DEBUG64_LENGTH 0x18 #define SAHARA_MEM_READ64_LENGTH 0x18 +#define SAHARA_DDR_TRAINING_IMG_ID 34 =20 struct sahara_packet { __le32 cmd; @@ -226,6 +227,27 @@ static int sahara_find_image(struct sahara_context *co= ntext, u32 image_id) return 0; } =20 + /* DDR training special case: Try per-serial number file first */ + if (image_id =3D=3D SAHARA_DDR_TRAINING_IMG_ID && context->fw_folder) { + u32 serial_num =3D context->mhi_dev->mhi_cntrl->serial_number; + + fw_path =3D kasprintf(GFP_KERNEL, + "qcom/%s/mdmddr_0x%x.mbn", + context->fw_folder, serial_num); + if (!fw_path) + return -ENOMEM; + + ret =3D firmware_request_nowarn(&context->firmware, + fw_path, + &context->mhi_dev->dev); + kfree(fw_path); + + if (!ret) { + context->active_image_id =3D image_id; + return 0; + } + } + /* * This image might be optional. The device may continue without it. * Only the device knows. Suppress error messages that could suggest an @@ -235,7 +257,8 @@ static int sahara_find_image(struct sahara_context *con= text, u32 image_id) context->image_table[image_id], &context->mhi_dev->dev); if (ret) { - dev_dbg(&context->mhi_dev->dev, "request for image id %d / file %s faile= d %d\n", + dev_dbg(&context->mhi_dev->dev, + "request for image id %d / file %s failed %d\n", image_id, context->image_table[image_id], ret); return ret; } --=20 2.34.1 From nobody Tue Jun 16 05:19:42 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (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 974D23DFC84 for ; Thu, 16 Apr 2026 14:10:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776348632; cv=none; b=aiBfr7fKoufKlvYOoxAPS+ceHHJVYEelMTXnccOJTbHsqYqnOvJzXobyrrjLdcgYdNScprwyo3qfx9E2Upn+u9vzpvsVnYLvVO72cM6pRxTxskuC8GAUGo266hcZXugzwQyuKv/5upykDntZR1US/rdlOIrTUfH3bvmc9lvOMM0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776348632; c=relaxed/simple; bh=jLSelPvlya5PlSF3BSCeXWNO38xxNT62OMTcs59kxy8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=R0u2JedLQvtmOE3Aeg+0/eL6FcRKWVRF2ZohaolU7eDgLIZnwkNokP1ByVc39dVoUmjHeeu63WTecqpv7mW2VdlnvsW5D6wTLUClhEUayHdu0yD5idpePY/dKInAUOTosFuAdKRSrDttcOcD8nx4PRY1meZdSTOCs6EfBuL/db0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=Hk3qdE8o; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=bRLkCOYv; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="Hk3qdE8o"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="bRLkCOYv" Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 63GDqcpK2596141 for ; Thu, 16 Apr 2026 14:10:29 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= 2DrLFZCgjnzYRSDXk/anHPMrlL9toedQJxC2wRf4GXo=; b=Hk3qdE8on/oG8s8b 0D00Os0ghR3Mrh0lnYIbAIQN62zskGYamAlwcSyCOFGQKQeGvAdfV5hjY4H6eJbb KzrWwigx/wZo78OAA5cx9Ojd5h+NIAWQbp3nlDrSfVLJBVN2HIL0qHk/vigDL71y CftZAxKRxzp1XZF3DmDaAYYpYnGqqYSUWFAp2FsGljRRaEHBbP/M4Ta5fVgdxHor QmpyZ/xexbW3n5vunVMxLGnBU68G019XoDHDVruLzTmYJt7j3oqcsP0hQv36cyMn Efi0OooU/rLCAz649K5Lr0LRiXG3y45TKtyrYyVQfNnfH2AMOjp8dTQEjxIQDSdM F+0M3Q== Received: from mail-yx1-f71.google.com (mail-yx1-f71.google.com [74.125.224.71]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4dk11r824a-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 16 Apr 2026 14:10:28 +0000 (GMT) Received: by mail-yx1-f71.google.com with SMTP id 956f58d0204a3-65036e62f9bso6796786d50.3 for ; Thu, 16 Apr 2026 07:10:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1776348628; x=1776953428; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=2DrLFZCgjnzYRSDXk/anHPMrlL9toedQJxC2wRf4GXo=; b=bRLkCOYvsc4brzye//urwoAvnEPizsso6uBMlia3A+Rqd7F1FtnFA2XB8ubhBaFgb4 EAVcy+Xq1xxFE0bkZGkHnZXwAUGTp75keE2U/Ic5UmVbVSBg4m8shay/XycsojHDFqT5 a5xoQU9zBhUDT1ECMHyjP4jr2Yx2B6I/tfe2uVfLJsdHDwTDp6ann84Du31PB83gmDHn o0YKfY8VlVTdGLSgJLEO2SRsyqCm3k8vlEUOpfQ/QfmAfG0a0Wzp6Ecxkle5OXA5d94T SouBb0CE1+4mZnRL72xD6Y7xdibPefDLN6bd9SygfT6THXZ9tGdyegBPOLd2ju78WEj5 pNnw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776348628; x=1776953428; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=2DrLFZCgjnzYRSDXk/anHPMrlL9toedQJxC2wRf4GXo=; b=GZPzJjuiBKrfzWfPVEs8S2PEvG/XXINMrBQ08Pp8Ou4nDYBiEmUGZ7U5CewmLo+hkO E9kTmBLtxAojX3rX3EJ17YGk2GbdjYeVuI8LM2EFD5yO1skUy+m2EkL4nyNI9sBoO+9H 3z5tIy6mVOlwak47Cbhu+UGTh0KifbZC1vnjmlMENhMDvMjkDLe4L927dEdAoUcMK4WB VD9jcVG3pdkO9XV+9KDF4aWKvWqmXn+9ibSRilOdBM93npYo4hsOWjJuoXMkBUDw7lQb L02m34CbIbbTCuK/Epen3FE5OQKRk/6y1TyLMFkLaDu9GLRpn2MkdceEhwp2o4XCQxIZ SXrw== X-Forwarded-Encrypted: i=1; AFNElJ+dcKAwvd1WDVaERmE5whlP0A68u2QV+wDe9DyyUkQBTtfbIKvBk5p2geZd2O/do4cO1Jmp4FK7ugoUPgg=@vger.kernel.org X-Gm-Message-State: AOJu0YzvLrpqxnFZ8ZP9b3HCSRcXtx2TVm1AXnzGlDZ5LsYyFv8+IqPX rws4D1CzmigW8xk2FwAEpXbVaHkKRqo5XBDhmpupMrDtXB/uFytUU1PE5ug8NmqJagw1hM/jq1j TcqHM5EL/KM2K3muqtobNjN6W5pKUBuNmcT7xjTmxMbThh9nsEQx68mKeXUIUU4NCvAk= X-Gm-Gg: AeBDievy8LKtwl7/j8GiQpkAn7MCKwiCTNoPp7wohmRxiyBI6kCMEQHJKZbz/kL7Wf5 S8x4QsMGk0KhDyrbvndyYV8oPuIdc9RIY0Ix03BxDd+aystR+ULPyQYB7nipCOc9pEs6gAjO2JF kFGFTotTOKFuPXnAp+7ERsrCqIgju8EYA9BSzbDNJd2BwxvWZ/c39HxEALYvQjK3B1UqvgWKxKe DiCVhd2xVBL1zGyLCeBiF1v3GQCHOhNv8toRxcRSQZCVRnpEN4Hlpn5aBEByQIIlyYxkelUqY4U wsk6/pkgJD9IfnOU1EZvxCE180FfZcPXzDtIFpG9BIEz0lycVmFCWAPgHcCoLE5qdFsdVy0C/2q LciGgxxb0pIghRiNxk5yVPpTLpM0TehRIPOaMiRvdiZHYCmnf0xo= X-Received: by 2002:a53:c842:0:b0:650:18e3:d917 with SMTP id 956f58d0204a3-65198b4713dmr19780506d50.41.1776348627432; Thu, 16 Apr 2026 07:10:27 -0700 (PDT) X-Received: by 2002:a53:c842:0:b0:650:18e3:d917 with SMTP id 956f58d0204a3-65198b4713dmr19780453d50.41.1776348626819; Thu, 16 Apr 2026 07:10:26 -0700 (PDT) Received: from hu-batta-hyd.qualcomm.com ([202.46.23.25]) by smtp.gmail.com with ESMTPSA id 956f58d0204a3-652e47ba4a3sm2084691d50.17.2026.04.16.07.10.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Apr 2026 07:10:26 -0700 (PDT) From: Kishore Batta Date: Thu, 16 Apr 2026 19:39:47 +0530 Subject: [PATCH v5 6/7] bus: mhi: Capture DDR training data via command mode Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260416-sahara_protocol_new_v2-v5-6-6aebf005e4ba@oss.qualcomm.com> References: <20260416-sahara_protocol_new_v2-v5-0-6aebf005e4ba@oss.qualcomm.com> In-Reply-To: <20260416-sahara_protocol_new_v2-v5-0-6aebf005e4ba@oss.qualcomm.com> To: Jonathan Corbet , Shuah Khan , Jeff Hugo , Carl Vanderlip , Oded Gabbay , Manivannan Sadhasivam Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, mhi@lists.linux.dev, Kishore Batta X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1776348592; l=15044; i=kishore.batta@oss.qualcomm.com; s=20260206; h=from:subject:message-id; bh=jLSelPvlya5PlSF3BSCeXWNO38xxNT62OMTcs59kxy8=; b=OmZoFh3+FaTmElb9qLRJXQ7+wQSSQZTd1Q1s/IgNbSTlxk9SUqr/wNbMMy6JYKbQ+4M9KUtFX TjplyASHAr7BsJqqLq9+59ytaxermotsLhrikmvgHCyMUDNZXEnop2U X-Developer-Key: i=kishore.batta@oss.qualcomm.com; a=ed25519; pk=vJo8RvTf+HZpRLK2oOIljmbn9l3zFkibCGh+blaqZCw= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNDE2MDEzNiBTYWx0ZWRfX6SghxnHvH8To IJiX36+J2aVzQN24UCvakRn+tk3Uv/YHjWzuKUizIZqIEyrk+l1Yj5Ordn4zcFKt3LY3zh9VbEV /PUnUE1KHrAEzJCHfJRxMTE8xXIWmjaHVzOYtotAv+UqICADCbN5QIozkfj7DUYta62UAem9duO NpTIDmiQOk9E13ubZIy06RWSsWl0fDV6UcKiv9z3brq6U9wtbBHs/NbC1Pm0VpKgRmFQOwihWRM SsVEmn2j2ynD6VpI+teJQZw4Qw0A4z/rQu6XAsIRPoRRN8B6DSFAASwVQDL5uRfHxJFX8ichZsF habILAhJebxE/eRUo7fmq8qkhwSk9B17ceRHxK+nM4U4KuBMcGA6A+tWTxVFlj8DBVCCrWKfcJv PBBGkc0Z/vFeu5VwB8iH0Y1jB4LdcL5U/F8zYQ490p8uusIqY5NAgpBZwx/DNTvg67WMk5e6mss +GdHEZAKQxHataKIsZg== X-Authority-Analysis: v=2.4 cv=ZPznX37b c=1 sm=1 tr=0 ts=69e0edd4 cx=c_pps a=ngMg22mHWrP7m7pwYf9JkA==:117 a=ZePRamnt/+rB5gQjfz0u9A==:17 a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=eoimf2acIAo5FJnRuUoq:22 a=EUspDBNiAAAA:8 a=_u4x-iUupSARUiuVX_kA:9 a=QEXdDO2ut3YA:10 a=yHXA93iunegOHmWoMUFd:22 X-Proofpoint-ORIG-GUID: u8YHaP4liyxGpRMk2REsBhfhsACZvTw4 X-Proofpoint-GUID: u8YHaP4liyxGpRMk2REsBhfhsACZvTw4 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-04-16_03,2026-04-16_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 priorityscore=1501 suspectscore=0 lowpriorityscore=0 spamscore=0 adultscore=0 bulkscore=0 malwarescore=0 clxscore=1015 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604070000 definitions=main-2604160136 During early boot, devices may perform DDR training and produce training data that can be reused on subsequent boots to reduce initialization time. The Sahara protocol provides a command mode flow to transfer this training data to the host, but the driver currently does not handle command mode and drops the training payload. Add Sahara command mode support to retrieve DDR training data from the device. When the device enters command mode and sends CMD_READY, query the support command list(ID 8) and request DDR training data(ID 9) using EXECUTE and EXECUTE_DATA as defined by protocol. Allocate receive buffers based on the reported response size and copy the raw payload directly from the MHI DL completion callback. Store the captured training data in controller-scoped memory using devres, so it remains available after Sahara channel teardown. Also distinguish raw payload completion from control packets in the DL callback, avoiding misinterpretation of training data as protocol messages, and requeue the RX buffer after switching back to IMAGE_TX_PENDING to allow the boot flow to continue. Signed-off-by: Kishore Batta --- drivers/bus/mhi/host/clients/sahara/sahara.c | 326 +++++++++++++++++++++++= +++- 1 file changed, 319 insertions(+), 7 deletions(-) diff --git a/drivers/bus/mhi/host/clients/sahara/sahara.c b/drivers/bus/mhi= /host/clients/sahara/sahara.c index b5ca6353540dc3815db6539e7424afdb749fd3f6..07bc743aa061dd2fa85638067d4= 94562152474e3 100644 --- a/drivers/bus/mhi/host/clients/sahara/sahara.c +++ b/drivers/bus/mhi/host/clients/sahara/sahara.c @@ -5,11 +5,14 @@ */ =20 #include +#include +#include #include #include #include #include #include +#include #include #include #include @@ -59,7 +62,15 @@ #define SAHARA_RESET_LENGTH 0x8 #define SAHARA_MEM_DEBUG64_LENGTH 0x18 #define SAHARA_MEM_READ64_LENGTH 0x18 +#define SAHARA_COMMAND_READY_LENGTH 0x8 +#define SAHARA_COMMAND_EXEC_RESP_LENGTH 0x10 +#define SAHARA_COMMAND_EXECUTE_LENGTH 0xc +#define SAHARA_COMMAND_EXEC_DATA_LENGTH 0xc +#define SAHARA_SWITCH_MODE_LENGTH 0xc +#define SAHARA_EXEC_CMD_GET_COMMAND_ID_LIST 0x8 +#define SAHARA_EXEC_CMD_GET_TRAINING_DATA 0x9 #define SAHARA_DDR_TRAINING_IMG_ID 34 +#define SAHARA_NUM_CMD_BUF SAHARA_NUM_TX_BUF =20 struct sahara_packet { __le32 cmd; @@ -95,6 +106,19 @@ struct sahara_packet { __le64 memory_address; __le64 memory_length; } memory_read64; + struct { + __le32 client_command; + } command_execute; + struct { + __le32 client_command; + __le32 response_length; + } command_execute_resp; + struct { + __le32 client_command; + } command_exec_data; + struct { + __le32 mode; + } mode_switch; }; }; =20 @@ -161,6 +185,7 @@ struct sahara_context { struct work_struct fw_work; struct work_struct dump_work; struct work_struct read_data_work; + struct work_struct cmd_work; struct mhi_device *mhi_dev; const char * const *image_table; u32 table_size; @@ -181,6 +206,24 @@ struct sahara_context { bool is_mem_dump_mode; bool non_streaming; const char *fw_folder; + bool is_cmd_mode; + bool receiving_training_data; + size_t training_size; + size_t training_rcvd; + u32 training_nbuf; + char *cmd_buff[SAHARA_NUM_CMD_BUF]; +}; + +/* + * Controller-scoped training data store (per MHI controller device). + * Stored as devres resource on mhi_dev->mhi_cntrl->mhi_dev->dev. + */ +struct sahara_cntrl_training_data { + struct mutex lock; /* Protects data, size, copied and receiving */ + void *data; + size_t size; + size_t copied; + bool receiving; }; =20 static bool is_streaming(struct sahara_context *context) @@ -188,6 +231,48 @@ static bool is_streaming(struct sahara_context *contex= t) return !context->non_streaming; } =20 +static void sahara_cntrl_training_release(struct device *dev, void *res) +{ + struct sahara_cntrl_training_data *ct =3D res; + + mutex_lock(&ct->lock); + kfree(ct->data); + ct->data =3D NULL; + ct->size =3D 0; + ct->copied =3D 0; + ct->receiving =3D false; + mutex_unlock(&ct->lock); +} + +static int sahara_cntrl_training_match(struct device *dev, void *res, void= *match_data) +{ + /* Exactly one instance per controller */ + return 1; +} + +static struct sahara_cntrl_training_data *sahara_cntrl_training_get(struct= device *dev) +{ + struct sahara_cntrl_training_data *ct; + + ct =3D devres_find(dev, sahara_cntrl_training_release, + sahara_cntrl_training_match, NULL); + if (ct) + return ct; + + ct =3D devres_alloc(sahara_cntrl_training_release, sizeof(*ct), GFP_KERNE= L); + if (!ct) + return NULL; + + mutex_init(&ct->lock); + ct->data =3D NULL; + ct->size =3D 0; + ct->copied =3D 0; + ct->receiving =3D false; + + devres_add(dev, ct); + return ct; +} + static int sahara_find_image(struct sahara_context *context, u32 image_id) { char *fw_path; @@ -282,6 +367,11 @@ static void sahara_send_reset(struct sahara_context *c= ontext) context->is_mem_dump_mode =3D false; context->read_data_offset =3D 0; context->read_data_length =3D 0; + context->is_cmd_mode =3D false; + context->receiving_training_data =3D false; + context->training_size =3D 0; + context->training_rcvd =3D 0; + context->training_nbuf =3D 0; =20 context->tx[0]->cmd =3D cpu_to_le32(SAHARA_RESET_CMD); context->tx[0]->length =3D cpu_to_le32(SAHARA_RESET_LENGTH); @@ -317,7 +407,8 @@ static void sahara_hello(struct sahara_context *context) =20 if (le32_to_cpu(context->rx->hello.mode) !=3D SAHARA_MODE_IMAGE_TX_PENDIN= G && le32_to_cpu(context->rx->hello.mode) !=3D SAHARA_MODE_IMAGE_TX_COMPLE= TE && - le32_to_cpu(context->rx->hello.mode) !=3D SAHARA_MODE_MEMORY_DEBUG) { + le32_to_cpu(context->rx->hello.mode) !=3D SAHARA_MODE_MEMORY_DEBUG && + le32_to_cpu(context->rx->hello.mode) !=3D SAHARA_MODE_COMMAND) { dev_err(&context->mhi_dev->dev, "Unsupported hello packet - mode %d\n", le32_to_cpu(context->rx->hello.mode)); return; @@ -336,6 +427,153 @@ static void sahara_hello(struct sahara_context *conte= xt) dev_err(&context->mhi_dev->dev, "Unable to send hello response %d\n", re= t); } =20 +static void sahara_switch_mode_to_img_tx(struct sahara_context *context) +{ + int ret; + + context->tx[0]->cmd =3D cpu_to_le32(SAHARA_SWITCH_MODE_CMD); + context->tx[0]->length =3D cpu_to_le32(SAHARA_SWITCH_MODE_LENGTH); + context->tx[0]->mode_switch.mode =3D cpu_to_le32(SAHARA_MODE_IMAGE_TX_PEN= DING); + + ret =3D mhi_queue_buf(context->mhi_dev, DMA_TO_DEVICE, context->tx[0], + SAHARA_SWITCH_MODE_LENGTH, MHI_EOT); + + if (ret) + dev_err(&context->mhi_dev->dev, "Unable to send mode switch %d\n", ret); +} + +static void sahara_command_execute(struct sahara_context *context, u32 cli= ent_command) +{ + int ret; + + context->tx[0]->cmd =3D cpu_to_le32(SAHARA_EXECUTE_CMD); + context->tx[0]->length =3D cpu_to_le32(SAHARA_COMMAND_EXECUTE_LENGTH); + context->tx[0]->command_execute.client_command =3D cpu_to_le32(client_com= mand); + + ret =3D mhi_queue_buf(context->mhi_dev, DMA_TO_DEVICE, context->tx[0], + SAHARA_COMMAND_EXECUTE_LENGTH, MHI_EOT); + if (ret) + dev_err(&context->mhi_dev->dev, "Unable to send command execute %d\n", r= et); +} + +static void sahara_command_execute_data(struct sahara_context *context, u3= 2 client_command) +{ + int ret; + + context->tx[0]->cmd =3D cpu_to_le32(SAHARA_EXECUTE_DATA_CMD); + context->tx[0]->length =3D cpu_to_le32(SAHARA_COMMAND_EXEC_DATA_LENGTH); + context->tx[0]->command_exec_data.client_command =3D cpu_to_le32(client_c= ommand); + + ret =3D mhi_queue_buf(context->mhi_dev, DMA_TO_DEVICE, context->tx[0], + SAHARA_COMMAND_EXEC_DATA_LENGTH, MHI_EOT); + if (ret) + dev_err(&context->mhi_dev->dev, "Unable to send execute data %d\n", ret); +} + +static void sahara_command_ready(struct sahara_context *context) +{ + if (le32_to_cpu(context->rx->length) !=3D SAHARA_COMMAND_READY_LENGTH) { + dev_err(&context->mhi_dev->dev, + "Malformed command ready packet - length %u\n", + le32_to_cpu(context->rx->length)); + return; + } + + context->is_cmd_mode =3D true; + context->receiving_training_data =3D false; + + sahara_command_execute(context, SAHARA_EXEC_CMD_GET_COMMAND_ID_LIST); +} + +static void sahara_command_execute_resp(struct sahara_context *context) +{ + struct device *dev =3D &context->mhi_dev->mhi_cntrl->mhi_dev->dev; + struct sahara_cntrl_training_data *ct; + u32 client_cmd, resp_len; + int ret; + u64 remaining; + u32 i; + + if (le32_to_cpu(context->rx->length) !=3D SAHARA_COMMAND_EXEC_RESP_LENGTH= || + le32_to_cpu(context->rx->command_execute_resp.response_length) < 0) { + dev_err(&context->mhi_dev->dev, + "Malformed command execute resp packet - length %d\n", + le32_to_cpu(context->rx->length)); + return; + } + + client_cmd =3D le32_to_cpu(context->rx->command_execute_resp.client_comma= nd); + resp_len =3D le32_to_cpu(context->rx->command_execute_resp.response_lengt= h); + + sahara_command_execute_data(context, client_cmd); + + if (client_cmd =3D=3D SAHARA_EXEC_CMD_GET_COMMAND_ID_LIST) { + sahara_command_execute(context, SAHARA_EXEC_CMD_GET_TRAINING_DATA); + return; + } + + if (client_cmd !=3D SAHARA_EXEC_CMD_GET_TRAINING_DATA) + return; + + ct =3D sahara_cntrl_training_get(dev); + if (!ct) { + context->is_cmd_mode =3D false; + sahara_switch_mode_to_img_tx(context); + return; + } + + mutex_lock(&ct->lock); + kfree(ct->data); + ct->data =3D kzalloc(resp_len, GFP_KERNEL); + ct->size =3D resp_len; + ct->copied =3D 0; + ct->receiving =3D true; + mutex_unlock(&ct->lock); + + if (!ct->data) { + context->is_cmd_mode =3D false; + sahara_switch_mode_to_img_tx(context); + return; + } + + context->training_size =3D resp_len; + context->training_rcvd =3D 0; + context->receiving_training_data =3D true; + + remaining =3D resp_len; + for (i =3D 0; i < SAHARA_NUM_CMD_BUF && remaining; i++) { + size_t pkt =3D min_t(size_t, remaining, SAHARA_PACKET_MAX_SIZE); + + ret =3D mhi_queue_buf(context->mhi_dev, DMA_FROM_DEVICE, + context->cmd_buff[i], pkt, + (remaining <=3D pkt) ? MHI_EOT : MHI_CHAIN); + if (ret) + break; + + remaining -=3D pkt; + } + + context->training_nbuf =3D i; +} + +static void sahara_command_processing(struct work_struct *work) +{ + struct sahara_context *context =3D container_of(work, struct sahara_conte= xt, cmd_work); + int ret; + + if (le32_to_cpu(context->rx->cmd) =3D=3D SAHARA_EXECUTE_RESP_CMD) + sahara_command_execute_resp(context); + + if (!context->receiving_training_data) { + ret =3D mhi_queue_buf(context->mhi_dev, DMA_FROM_DEVICE, + context->rx, SAHARA_PACKET_MAX_SIZE, MHI_EOT); + + if (ret) + dev_err(&context->mhi_dev->dev, + "Unable to requeue rx buf %d\n", ret); + } +} + static int read_data_helper(struct sahara_context *context, int buf_index) { enum mhi_flags mhi_flag; @@ -562,6 +800,9 @@ static void sahara_processing(struct work_struct *work) case SAHARA_MEM_DEBUG64_CMD: sahara_memory_debug64(context); break; + case SAHARA_CMD_READY_CMD: + sahara_command_ready(context); + break; default: dev_err(&context->mhi_dev->dev, "Unknown command %d\n", le32_to_cpu(context->rx->cmd)); @@ -862,6 +1103,20 @@ static int sahara_mhi_probe(struct mhi_device *mhi_de= v, const struct mhi_device_ INIT_WORK(&context->fw_work, sahara_processing); INIT_WORK(&context->dump_work, sahara_dump_processing); INIT_WORK(&context->read_data_work, sahara_read_data_processing); + INIT_WORK(&context->cmd_work, sahara_command_processing); + + for (i =3D 0; i < SAHARA_NUM_CMD_BUF; i++) { + context->cmd_buff[i] =3D devm_kzalloc(&mhi_dev->dev, + SAHARA_PACKET_MAX_SIZE, GFP_KERNEL); + if (!context->cmd_buff[i]) + return -ENOMEM; + } + + context->is_cmd_mode =3D false; + context->receiving_training_data =3D false; + context->training_size =3D 0; + context->training_rcvd =3D 0; + context->training_nbuf =3D 0; =20 context->active_image_id =3D SAHARA_IMAGE_ID_NONE; dev_set_drvdata(&mhi_dev->dev, context); @@ -885,6 +1140,7 @@ static void sahara_mhi_remove(struct mhi_device *mhi_d= ev) =20 cancel_work_sync(&context->fw_work); cancel_work_sync(&context->dump_work); + cancel_work_sync(&context->cmd_work); vfree(context->mem_dump); sahara_release_image(context); mhi_unprepare_from_transfer(mhi_dev); @@ -901,15 +1157,71 @@ static void sahara_mhi_ul_xfer_cb(struct mhi_device = *mhi_dev, struct mhi_result static void sahara_mhi_dl_xfer_cb(struct mhi_device *mhi_dev, struct mhi_r= esult *mhi_result) { struct sahara_context *context =3D dev_get_drvdata(&mhi_dev->dev); + struct sahara_cntrl_training_data *ct; + struct device *dev; + size_t copy; + int ret; + u32 i; + + if (mhi_result->transaction_status) + return; + + /* + * Raw training payload completions arrive for cmd_buff[] buffers. + * Do not schedule cmd_work for those. + */ + if (context->is_cmd_mode && context->receiving_training_data && + mhi_result->buf_addr !=3D context->rx) { + dev =3D &context->mhi_dev->mhi_cntrl->mhi_dev->dev; + ct =3D sahara_cntrl_training_get(dev); + if (!ct) + return; =20 - if (!mhi_result->transaction_status) { - context->rx_size =3D mhi_result->bytes_xferd; - if (context->is_mem_dump_mode) - schedule_work(&context->dump_work); - else - schedule_work(&context->fw_work); + for (i =3D 0; i < context->training_nbuf; i++) { + if (mhi_result->buf_addr =3D=3D context->cmd_buff[i]) { + mutex_lock(&ct->lock); + copy =3D min_t(size_t, mhi_result->bytes_xferd, + ct->size - ct->copied); + memcpy((u8 *)ct->data + ct->copied, + mhi_result->buf_addr, copy); + ct->copied +=3D copy; + mutex_unlock(&ct->lock); + + context->training_rcvd +=3D copy; + + if (context->training_rcvd >=3D context->training_size) { + mutex_lock(&ct->lock); + ct->receiving =3D false; + mutex_unlock(&ct->lock); + + context->receiving_training_data =3D false; + context->is_cmd_mode =3D false; + + sahara_switch_mode_to_img_tx(context); + ret =3D mhi_queue_buf(context->mhi_dev, + DMA_FROM_DEVICE, + context->rx, + SAHARA_PACKET_MAX_SIZE, + MHI_EOT); + if (ret) + dev_err(&context->mhi_dev->dev, + "Unable to requeue rx buf %d\n", ret); + } + return; + } + } + return; } =20 + /* Normal Rx completion */ + context->rx_size =3D mhi_result->bytes_xferd; + if (context->is_mem_dump_mode) + schedule_work(&context->dump_work); + else if (context->is_cmd_mode) + schedule_work(&context->cmd_work); + else + schedule_work(&context->fw_work); + } =20 static const struct mhi_device_id sahara_mhi_match_table[] =3D { --=20 2.34.1 From nobody Tue Jun 16 05:19:42 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 A17B23DE43F for ; Thu, 16 Apr 2026 14:10:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776348636; cv=none; b=rJlHDPgQ2ycrzY1BLujer4fPpvuK1yxNACbgTdNIB50vVHUHmF2Hr6zzS7NkUnYp1P48f+mMNv4xUwf/SvuZZkMFS0zXeX/Pp2cAo7G74z2jNOyR4xxqAecLbohgfHi6+lM4/lTJGDQdsmR5R5BbxznOphqnr3f4DYi9Ea2sjV0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776348636; c=relaxed/simple; bh=ED34D8b+KIsBJGlgWYmYp+bxz9nF9W6dhG3Lu+L8T+Y=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=kpXQhewDzlY09CChTXc62P/i3AAi5CletomFB4txCjCJWb/dfDFPy3C2VQ34fxnp/Bf2zq9tgqXtPbJs40fIPtxU/PVdcc0KfRJ356ADutqrQzPBSjMn76I5AzDnAOOT7P9/+1eyzQ/6iqs153OlcbtbN0LH6j+TvACJ1xn/7Y0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=XqjGIXZd; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=DJZzALKm; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="XqjGIXZd"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="DJZzALKm" Received: from pps.filterd (m0279873.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 63GCPiue1668112 for ; Thu, 16 Apr 2026 14:10:33 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= olONKICAQIN5WecCXZoB05Va0xoXxi3BtToDJt2JvlU=; b=XqjGIXZdw6NKQMIj hSdPAXMczheOQYqH98Bq4weVCFDDFn4Zl9dpgUgwEA0k6WsX6U5CdxHcdpikXQ7I osU9HlveeflD3qM1vNr9ljKCejtLeubry2wpPTOPiclUymeC3eF06EVlH6SlR4jV 1Uh5MPrhLPMk0lQIwaNs1LdmIlInNKAYvidiw08ZmneMzSWnRoroYB9Yg7kyLU3D 0XeKNpgw4tok3ZAlx3r6RONqmRy3Rdn4RycrT99ZTnszi2EZVnOawonyeWfylSV5 HCyH90Yqe4uIR75M6mt0P2Rk+k9EmjsU7XGSzRifJSks8W0s1UqK5vMDGjGdWEl2 8ThZ0Q== Received: from mail-yx1-f70.google.com (mail-yx1-f70.google.com [74.125.224.70]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4djtd91ms9-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 16 Apr 2026 14:10:33 +0000 (GMT) Received: by mail-yx1-f70.google.com with SMTP id 956f58d0204a3-644548b1dcfso12668890d50.3 for ; Thu, 16 Apr 2026 07:10:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1776348632; x=1776953432; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=olONKICAQIN5WecCXZoB05Va0xoXxi3BtToDJt2JvlU=; b=DJZzALKmhPmWQs4MEBjB2vZ0ouRqz1mqpwsnQT3miKMQVFJ7JR60k8Q17RbETP3djF lgWEtiN+hJVX/W1qxgqNiFNGvw61eA5IOUoxSc4zNytEdf05A7h918oA6QX9SqCNZ4A2 DHc51z1qVQP+r5pXXd78bkn1oxB39+F/0xJnAC0aIJo2fJz8b1dq/kVYtkZPorLepcLB 9UhsSnd+Z3o/czRivMh1hbRafx+GwwE2l6ktEPT205MTI1fyAJ2ySSTFXGAb1OL5lfeL VpZiJsiZtBmsy1m8oKajnJg2u7cnI5LZtCBZ817RZqPd0YFq1WGwshvaK12GGk9Kdhd+ QLJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776348632; x=1776953432; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=olONKICAQIN5WecCXZoB05Va0xoXxi3BtToDJt2JvlU=; b=DoGZPrJV146ZHZXDVS8YSvdtL7Z4V6LQKvzFAp69/0aqxD/rtwVqOcmuVb4ekJDfr1 Tye6pTthQk8XUmqAxoqAclyZ566JmFgVrtPQOoVwNKpSxi26IdPLNXK2dYyRKx/2f9d0 Aulhxk75ycW0kzZCHa7kccBj2oKNmwMNBzFcdQSt+EZ9d09NtjhEKQD1wbuzM/J7nSS8 y1b9f9RMSN+CYlyxsQHadLQtXjX0hpJk+2bVfMC+6616RgfPCcZxImZKBl2BJ5RBrzjn CzqCPZYlIllBZrjTPwgVlfEo8tUt3wb6etC311tnlU4HqmwAjhar7Y6xAE5EecKTVcN3 yVBw== X-Forwarded-Encrypted: i=1; AFNElJ/1i7/0RDdDJRPXN7OpF0WLiI8pJXoJR8lGGOeAgT5Db1AS6aJNfNjYidgpGjZsjy2Vfj5SrAbEhiuAuCM=@vger.kernel.org X-Gm-Message-State: AOJu0YzvVxEGvGHReuh5qvYF8Obtue4xNSaEtYNiN/6ebR2xG6EgIe8v 0GuTwpRv9d7ob474PYJRQD5Ls/4SkFN6Vkb8hEtTNnrhgIrf9AMIgehU6ynW61iht6ZjZXSiufu zWcvKMY1qi8qAd1/lhD3jG90Kmsb6Ld2FpokazVrPDxpym+4WzY38BxNMjgG6aAQ2H98= X-Gm-Gg: AeBDieu1jmAd/KuBi+8r22kW4SQrkPhKOldQQt6i6UASc50DoAdf9rBjMWnAJeBTeJE RVZdrJD5E1Or9AxMwip8h/0zVfb/Eo4xyo7Nw8/wQZmBINDnYHXaEc+dfYJF+ElQNADvH9MWxHR WPCtdUA0OG4ZTNRORH1OISBnfZ7ZtciB8962kw9ohB7sUlv+KgTB1f0eoehnF2aFizXf+2A/fg4 mzrP/q3fpVqrOJaMRO0wydcnX5bCGM8duTZ08JQv/sOYAZg/82Y1sf247LYUtw8koIrqeqkC3cR twCAGJTBgdx0leTAj4Yiv9vxACGHoQUaYPqr3helBxIuYh3OJPxaB+qjFBjZytGtrzpuRcqZV7B x3dIhjUWHHAYElY/qnma3qjzp95fPrCrwf7W3rqDw2gwL0YI+ocU= X-Received: by 2002:a53:cf05:0:b0:650:4aec:29fa with SMTP id 956f58d0204a3-65198b734cbmr16936300d50.38.1776348632107; Thu, 16 Apr 2026 07:10:32 -0700 (PDT) X-Received: by 2002:a53:cf05:0:b0:650:4aec:29fa with SMTP id 956f58d0204a3-65198b734cbmr16936245d50.38.1776348631578; Thu, 16 Apr 2026 07:10:31 -0700 (PDT) Received: from hu-batta-hyd.qualcomm.com ([202.46.23.25]) by smtp.gmail.com with ESMTPSA id 956f58d0204a3-652e47ba4a3sm2084691d50.17.2026.04.16.07.10.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Apr 2026 07:10:31 -0700 (PDT) From: Kishore Batta Date: Thu, 16 Apr 2026 19:39:48 +0530 Subject: [PATCH v5 7/7] bus: mhi: Expose DDR training data via controller sysfs Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260416-sahara_protocol_new_v2-v5-7-6aebf005e4ba@oss.qualcomm.com> References: <20260416-sahara_protocol_new_v2-v5-0-6aebf005e4ba@oss.qualcomm.com> In-Reply-To: <20260416-sahara_protocol_new_v2-v5-0-6aebf005e4ba@oss.qualcomm.com> To: Jonathan Corbet , Shuah Khan , Jeff Hugo , Carl Vanderlip , Oded Gabbay , Manivannan Sadhasivam Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, mhi@lists.linux.dev, Kishore Batta X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1776348592; l=5329; i=kishore.batta@oss.qualcomm.com; s=20260206; h=from:subject:message-id; bh=ED34D8b+KIsBJGlgWYmYp+bxz9nF9W6dhG3Lu+L8T+Y=; b=wr3vSGs78JSxGrL9+BaCDjQaV430OdwRmfmRxGfEA18NdKlc7cPBYHUMyREr7q9wjEQydgh2n fowGZKpD2eLBYkBvWD8gp2LTGudSo2ECATeMbqaMDKsHQlDphB0Yaf9 X-Developer-Key: i=kishore.batta@oss.qualcomm.com; a=ed25519; pk=vJo8RvTf+HZpRLK2oOIljmbn9l3zFkibCGh+blaqZCw= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNDE2MDEzNiBTYWx0ZWRfXzv8DfJgbSPkN PJb6jHtTICR60NkcL/9eBjS3kFt7VZXN6+XZ5XH6plHPcIF7UZb1z01GM5oidEn2LgrlzBzY0kE VDTT5U2a0cx6IyLaKQvi4ELtVu9IwJOb3otblu6ruW9GLo+rE9I7WWFcXYnqAk+O1lSV4838aI3 w8lAT2q8I+28vZU9/AOM2e+cfj0QKFC+8EYOLx0QaqhcIJJqi0VDtP9aeHXBMvF1AKKngVVjCR/ DBXi7RKlkksxSSizRCKAMbiEEmVLE68AJEVhJNva1LBDCkCRYF++2D43tRqEiA19mI5s4LGwx2x ligEtuD6a6H/003qe9HLYuX3/46AxkrAHToLjhIfLOL8Wqh84GAC4kvS61NJnr+3eOf2EyjXQvF snCZoay8eidh5O+/rRLcvdIm5w3lYT1xp08uTIHTZnmaXIRVXPhzauX199qJzwT1k4FN3+J0tm2 LTuioe0E6c/P5PSSoWA== X-Authority-Analysis: v=2.4 cv=avuCzyZV c=1 sm=1 tr=0 ts=69e0edd9 cx=c_pps a=S/uc88zpIJVNbziUnJ6G4Q==:117 a=ZePRamnt/+rB5gQjfz0u9A==:17 a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=rJkE3RaqiGZ5pbrm-msn:22 a=EUspDBNiAAAA:8 a=6t33SRJ6vQwVIDTtI9kA:9 a=QEXdDO2ut3YA:10 a=nd2WpGr1bMy9NW-iytEl:22 X-Proofpoint-GUID: tvoxMOy76Zgox7dnfR8oqVFPgl2B_30U X-Proofpoint-ORIG-GUID: tvoxMOy76Zgox7dnfR8oqVFPgl2B_30U X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-04-16_03,2026-04-16_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 phishscore=0 spamscore=0 bulkscore=0 priorityscore=1501 adultscore=0 suspectscore=0 clxscore=1015 lowpriorityscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604070000 definitions=main-2604160136 DDR training data captured during Sahara command mode needs to be accessible to userspace so it can be persisted and reused on subsequent boots. Currently, the training data is stored internally in the driver but has no external visibility once the Sahara channel is torn down. Expose the captured DDR training data via a read-only binary sysfs attribute on the MHI controller device: /sys/bus/mhi/devices//ddr_training_data The sysfs read callback serves data directly from controller scoped storage and protects access with the controller training data lock. The attribute lifetime is tied to the controller device via devres, allowing the data to remain readable after Sahara channel teardown and ensuring automatic cleanup when controller device is removed. Userspace flow: 1. For each controller device, userspace reads the ddr_training_data sysfs attribute. 2. If the read returns non-zero data, userspace persists it using a serial specific filename (for example, mdmddr_0x.mbn). 3. On subsequent boots, the Sahara driver attempts to load this serial specific DDR training image before falling back to the default training image, restoring DDR calibration data and avoiding retraining. Add ABI documentation for the DDR training data sysfs attribute exposed by Sahara MHI driver. Signed-off-by: Kishore Batta --- .../ABI/testing/sysfs-bus-mhi-ddr_training_data | 19 ++++++ drivers/bus/mhi/host/clients/sahara/sahara.c | 69 ++++++++++++++++++= ++++ 2 files changed, 88 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-mhi-ddr_training_data b/Do= cumentation/ABI/testing/sysfs-bus-mhi-ddr_training_data new file mode 100644 index 0000000000000000000000000000000000000000..810b487b5a5fdba133d81255f98= 79844e3938a10 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-mhi-ddr_training_data @@ -0,0 +1,19 @@ +What: /sys/bus/mhi/devices//ddr_training_data + +Date: March 2026 + +Contact: Kishore Batta + +Description: Contains the DDR training data for the Qualcomm de= vice + connected. MHI driver populates different controll= er + nodes for each device. The DDR training data is ex= posed + to userspace to read and save the training data fi= le to + the filesystem. In the subsequent boot up of the d= evice, + the training data is restored from host to device + optimizing the boot up time of the device. + +Usage: Example for reading DDR training data: + cat /sys/bus/mhi/devices/mhi0/ddr_training_data + +Permissions: The file permissions are set to 0444 allowing read + access. diff --git a/drivers/bus/mhi/host/clients/sahara/sahara.c b/drivers/bus/mhi= /host/clients/sahara/sahara.c index 07bc743aa061dd2fa85638067d494562152474e3..fef5dc1d8884133397d204f2336= 1584fd1d9b075 100644 --- a/drivers/bus/mhi/host/clients/sahara/sahara.c +++ b/drivers/bus/mhi/host/clients/sahara/sahara.c @@ -273,6 +273,73 @@ static struct sahara_cntrl_training_data *sahara_cntrl= _training_get(struct devic return ct; } =20 +static ssize_t ddr_training_data_read(struct file *filp, struct kobject *k= obj, + const struct bin_attribute *attr, char *buf, + loff_t offset, size_t count) +{ + struct device *dev =3D kobj_to_dev(kobj); + struct sahara_cntrl_training_data *ct; + size_t available; + + ct =3D sahara_cntrl_training_get(dev); + if (!ct) + return -ENODEV; + + mutex_lock(&ct->lock); + + /* No data yet or offset past end */ + if (!ct->data || offset >=3D ct->size) { + mutex_unlock(&ct->lock); + return 0; + } + + available =3D ct->size - offset; + count =3D min(count, available); + memcpy(buf, (u8 *)ct->data + offset, count); + + mutex_unlock(&ct->lock); + + return count; +} + +static const struct bin_attribute ddr_training_data_attr =3D { + .attr =3D { + .name =3D "ddr_training_data", + .mode =3D 0444, + }, + .read =3D ddr_training_data_read, +}; + +static void sahara_sysfs_devres_release(struct device *dev, void *res) +{ + device_remove_bin_file(dev, &ddr_training_data_attr); +} + +static void sahara_sysfs_create(struct mhi_device *mhi_dev) +{ + struct device *dev =3D &mhi_dev->mhi_cntrl->mhi_dev->dev; + void *cookie; + int ret; + + if (devres_find(dev, sahara_sysfs_devres_release, NULL, NULL)) + return; + + ret =3D device_create_bin_file(dev, &ddr_training_data_attr); + if (ret) { + dev_warn(&mhi_dev->dev, + "Failed to create DDR training sysfs node (%d)\n", ret); + return; + } + + cookie =3D devres_alloc(sahara_sysfs_devres_release, 1, GFP_KERNEL); + if (!cookie) { + device_remove_bin_file(dev, &ddr_training_data_attr); + return; + } + + devres_add(dev, cookie); +} + static int sahara_find_image(struct sahara_context *context, u32 image_id) { char *fw_path; @@ -1131,6 +1198,8 @@ static int sahara_mhi_probe(struct mhi_device *mhi_de= v, const struct mhi_device_ return ret; } =20 + sahara_sysfs_create(mhi_dev); + return 0; } =20 --=20 2.34.1