From nobody Sat Oct 4 12:47:30 2025 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 8F1B3279794 for ; Mon, 18 Aug 2025 06:56:13 +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=1755500175; cv=none; b=ZMzZxVhWpm4X/+DLfl2eNBqQ+O8N3IVs4uHgwh5NdG/wUDJkSqvxsSLw6lsUkjhUKXjRUU9wypBMnY311HE41NRR6veOelAmdnG2fTBYoQ4vm4EKZEUyOUgSxF12kJP3gDHbUbTUP/3bNYwQli7/0/+8iv4ogG+4capI1CabdYQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755500175; c=relaxed/simple; bh=Vtq+LqyHwabRSuVT5MMuwrzUmQB0qL0gtNzL53SbFic=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=IFH6ZKgPVe7lMDFajsjWXmnDiUFzL8hMMIMC64og4HoCc/IYntORsAallEcfSssZtMPA/rY7BBaJ1cyWrGG0SAWb4xHU45RpCToFE2/S9VUBNJEknQ990D+y09PTzKDord60icRaL5r9ZvkrLvgQyq89VEVpXXD6+0IWlZF2eME= 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=Z514PpE9; 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="Z514PpE9" Received: from pps.filterd (m0279862.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 57HNwMU1018545 for ; Mon, 18 Aug 2025 06:56:12 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= Q7Hct/taILfKpdTRmUfYnuJgK15nNJqQFrPMWbLaR9Q=; b=Z514PpE9CAMsdNu+ nARB143KOo4lF5/LLGV1dFYVjmGEryOkHtOpSNMmUxYksaxoXPIHPaezNdDLPXk6 QSPG5fgseH5Z8+us4HWJlaAAka3RH3El5QUxrfp2y1XRJtONN3eyfBlK52FZCCLG ZljYwtS2XjI9m/UdPbKVL7C1LGmpJEVwOKEFqmwIo7j2k8QKeug8NrtObTZQO+dB 6SdXs8Aavek3OUdPZg/WkHSMvUTH+vxYKt+nS19ki78EjtNTgBE74kBNpckMgkoz 88R1T8ca3nvuXhWkKG10Zc1AKWQr6wf39C90t0N2s7zfnki+0Jvjad5DNpqlnAVl vlItDw== Received: from mail-pg1-f198.google.com (mail-pg1-f198.google.com [209.85.215.198]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 48jjrfuhrg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Mon, 18 Aug 2025 06:56:12 +0000 (GMT) Received: by mail-pg1-f198.google.com with SMTP id 41be03b00d2f7-b471737e673so7464293a12.1 for ; Sun, 17 Aug 2025 23:56:12 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755500171; x=1756104971; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Q7Hct/taILfKpdTRmUfYnuJgK15nNJqQFrPMWbLaR9Q=; b=mdQDuRRhnSu19I6EEj7U9bJHqzkq0CHid0ePIWVAgdNq4QriPMpaW5IIcDb+EdA/Tz dkLFv4fVaCbppGt2R3vhMPPqSPPV7PRSGkSb4g02P4627+uGd+CpLukXHpFtdrqBz2DZ WsfibGKvh7/ecDRsU4hgXyZMHaLvB5ek307m17QxtnO5/X0F+dvZudrs6eBTxJ25PgFO ObZJvI4YGSuGueUJLjOJkbHeRWegrzAkpw5KeOkwdR4LwKFTITYgW1qlZ2ad+Dt2tP2K KBonIMS5l7UDNIOJLqQ/Yot3EllC4nljWRkL4oiFGBVsZJSmLHSWHQk6psIMboPSlHjP yPTA== X-Forwarded-Encrypted: i=1; AJvYcCWybkFDvjYSB5k/gqWxVYgMaBpIPbRtPCzmXwPjPXK+CWogaNxOW5nCUyX85r04rGdBFKmJYZD5ms5A19o=@vger.kernel.org X-Gm-Message-State: AOJu0YyBf0kNHGivOJI+sTUcPGxwotHS+pfIum8oBp0OYO9fzJAyuf8B O3WOQ6hpyhRH6MOEoVhUULbjfJntgEXY6XCEKoO8wihpcBoO4CjgUJpbWEPmEMBg9FaicRzHksk teHAiJ7477AKVVqqMozSSTH9qOs0uiFR45t8biQ4pAY4ws4tF2sP5gfdgBDPbSwWocqw= X-Gm-Gg: ASbGncuJYFZLDK7t0yRb1q54EC2bElSKeU46fbLdpY94U3jnZYNVOLsuGx7kqxsH9D7 otSCv6t5L/+7RCmdlN4W3wGm2ilYk6k/uHD/1FkijTx2DIx/rGs14+9+AbIFJwfz6iTwNl7yH5C Uu5rtEIcEW1e8eT92e2KziVBXTC4uW7UEQB7nDfHBbyNlkSLhjHYJzIIFMUDaIfMwcwxTe5zy2L yaND3FFiB3c7LARgDxMH7hOrQLynC0Y8EbjMX/Mj9ptfoFFSQEfeM3HY0wgrNiCHspK3E6KSluZ Lbh6jnimvBbh/rid/V6ktdc44p8TTKfQBmHtPlcQetxhGkpR4GxzTrod8aACtVUTaF6t12YZVA0 = X-Received: by 2002:a17:903:1107:b0:240:48f4:40d5 with SMTP id d9443c01a7336-2446d8bc395mr199357065ad.39.1755500170833; Sun, 17 Aug 2025 23:56:10 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFm00coYUmrKJrf8oBX7qk5XondVTD7nuk4SBWcSqcmNI9kSTJQX11L4conpVEGYpJxs+Wcyg== X-Received: by 2002:a17:903:1107:b0:240:48f4:40d5 with SMTP id d9443c01a7336-2446d8bc395mr199356745ad.39.1755500170330; Sun, 17 Aug 2025 23:56:10 -0700 (PDT) Received: from hu-krichai-hyd.qualcomm.com ([202.46.23.25]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2446d50f664sm70240105ad.75.2025.08.17.23.56.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 17 Aug 2025 23:56:10 -0700 (PDT) From: Krishna Chaitanya Chundru Date: Mon, 18 Aug 2025 12:25:46 +0530 Subject: [PATCH 1/5] bus: mhi: host: Add support for non-posted TSC timesync feature 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: <20250818-tsc_time_sync-v1-1-2747710693ba@oss.qualcomm.com> References: <20250818-tsc_time_sync-v1-0-2747710693ba@oss.qualcomm.com> In-Reply-To: <20250818-tsc_time_sync-v1-0-2747710693ba@oss.qualcomm.com> To: Manivannan Sadhasivam , Richard Cochran Cc: mhi@lists.linux.dev, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, taniya.das@oss.qualcomm.com, imran.shaik@oss.qualcomm.com, quic_vbadigan@quicinc.com, quic_mrana@quicinc.com, Krishna Chaitanya Chundru , Vivek Pernamitta X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1755500162; l=8702; i=krishna.chundru@oss.qualcomm.com; s=20230907; h=from:subject:message-id; bh=e8/ku6lMOX/7dfksgna+jLyXTGndYgqBNn5EzeuwPa4=; b=bFTgC9gnjTuDnHGgcj5Hxbjh0jbXrId/75gtSEqawLCqdiCBxldVVKzAENfPY38bDoyFYbAPX RGiOj+Njge5CHJwnlarCkmTMYxYEKEFbhwqCgP7DmxUpxoPF6EOMQ4x X-Developer-Key: i=krishna.chundru@oss.qualcomm.com; a=ed25519; pk=10CL2pdAKFyzyOHbfSWHCD0X0my7CXxj8gJScmn1FAg= X-Proofpoint-GUID: Bz-eHZv3RCKVw6MespqDM8qnhPbJKnks X-Authority-Analysis: v=2.4 cv=YrsPR5YX c=1 sm=1 tr=0 ts=68a2ce8c cx=c_pps a=Qgeoaf8Lrialg5Z894R3/Q==:117 a=ZePRamnt/+rB5gQjfz0u9A==:17 a=IkcTkHD0fZMA:10 a=2OwXVqhp2XgA:10 a=COk6AnOGAAAA:8 a=EUspDBNiAAAA:8 a=DQPGbgbYSupBwqSZGUIA:9 a=QEXdDO2ut3YA:10 a=x9snwWr2DeNwDh03kgHS:22 a=TjNXssC_j7lpFel5tvFf:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwODE2MDAzOSBTYWx0ZWRfX0dk2HK8JRuiC ME8xZwkUO1HkmfT+Z36i9yz4Zw9BNVlkfQdefaT7dhmpzGMyDlcl09b0RJ+kXkk/OZkYPX4NjHO Ndgc4hPbyKwNzwpJg4zTdIDevv0Up7kgvu4HghzeWdBJV9Cl4TCnKHxDEf2BFpwA852u0AKla45 GuasERMfEj3PVSstXgrc+QJAHBOYuJU2zVCXNuFeqwusmk+CYJ5+W/Usn5Cdp7a3SyK3cO+LXBf nENU4YZrKT/tP2QRwzzbxLyx6BA6OAJfKRmlrNAyX8UT+DcYmheFUHEOY6ZfBSjzAVtPiZ/qE+L OB4I+/vudvV165S1fL4dMllH7KiyFIocDMr/AEj6fJsaBMsGRQ4Ejr5u4D/Lf90VRhvWtGYgX09 FhyAkfUD X-Proofpoint-ORIG-GUID: Bz-eHZv3RCKVw6MespqDM8qnhPbJKnks X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.1.9,FMLib:17.12.80.40 definitions=2025-08-18_03,2025-08-14_01,2025-03-28_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 suspectscore=0 spamscore=0 priorityscore=1501 phishscore=0 adultscore=0 bulkscore=0 clxscore=1015 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.19.0-2507300000 definitions=main-2508160039 From: Vivek Pernamitta Implement non-posted time synchronization as described in section 5.1.1 of the MHI v1.2 specification. The host disables low-power link states to minimize latency, reads the local time, issues a MMIO read to the device's TIME register. Add support for initializing this feature and export a function to be used by the drivers which does the time synchronization. MHI reads the device time registers in the MMIO address space pointed to by the capability register after disabling all low power modes and keeping MHI in M0. Before and after MHI reads, the local time is captured and shared for processing. Signed-off-by: Vivek Pernamitta Signed-off-by: Krishna Chaitanya Chundru --- drivers/bus/mhi/common.h | 4 +++ drivers/bus/mhi/host/init.c | 28 ++++++++++++++++ drivers/bus/mhi/host/internal.h | 9 +++++ drivers/bus/mhi/host/main.c | 74 +++++++++++++++++++++++++++++++++++++= ++++ include/linux/mhi.h | 37 +++++++++++++++++++++ 5 files changed, 152 insertions(+) diff --git a/drivers/bus/mhi/common.h b/drivers/bus/mhi/common.h index 58f27c6ba63e3e6fa28ca48d6d1065684ed6e1dd..70319ffa62155f8f450944a08d4= cd524094d01de 100644 --- a/drivers/bus/mhi/common.h +++ b/drivers/bus/mhi/common.h @@ -118,6 +118,10 @@ #define CAP_CAPID_MASK GENMASK(31, 24) #define CAP_NEXT_CAP_MASK GENMASK(23, 12) =20 +/* MHI TSC Timesync */ +#define TSC_TIMESYNC_TIME_LOW_OFFSET (0x8) +#define TSC_TIMESYNC_TIME_HIGH_OFFSET (0xC) + /* Command Ring Element macros */ /* No operation command */ #define MHI_TRE_CMD_NOOP_PTR 0 diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c index b5f23336eb6afe249c07932bc4182fafdf1f2a19..83b92d8beef12797941140a314b= 4c7878e89e525 100644 --- a/drivers/bus/mhi/host/init.c +++ b/drivers/bus/mhi/host/init.c @@ -499,6 +499,30 @@ static int mhi_find_capability(struct mhi_controller *= mhi_cntrl, u32 capability, return -ENXIO; } =20 +static int mhi_init_tsc_timesync(struct mhi_controller *mhi_cntrl) +{ + struct device *dev =3D &mhi_cntrl->mhi_dev->dev; + struct mhi_timesync *mhi_tsc_tsync; + u32 time_offset; + int ret; + + ret =3D mhi_find_capability(mhi_cntrl, MHI_CAP_ID_TSC_TIME_SYNC, &time_of= fset); + if (ret) + return ret; + + mhi_tsc_tsync =3D devm_kzalloc(dev, sizeof(*mhi_tsc_tsync), GFP_KERNEL); + if (!mhi_tsc_tsync) + return -ENOMEM; + + mhi_cntrl->tsc_timesync =3D mhi_tsc_tsync; + mutex_init(&mhi_tsc_tsync->ts_mutex); + + /* save time_offset for obtaining time via MMIO register reads */ + mhi_tsc_tsync->time_reg =3D mhi_cntrl->regs + time_offset; + + return 0; +} + int mhi_init_mmio(struct mhi_controller *mhi_cntrl) { u32 val; @@ -636,6 +660,10 @@ int mhi_init_mmio(struct mhi_controller *mhi_cntrl) return ret; } =20 + ret =3D mhi_init_tsc_timesync(mhi_cntrl); + if (ret) + dev_dbg(dev, "TSC Time synchronization init failure\n"); + return 0; } =20 diff --git a/drivers/bus/mhi/host/internal.h b/drivers/bus/mhi/host/interna= l.h index 034be33565b78eff9bdefd93faa4f3ce93825bad..0909c33568ba1b8c736b8c41a56= 96da524691529 100644 --- a/drivers/bus/mhi/host/internal.h +++ b/drivers/bus/mhi/host/internal.h @@ -15,6 +15,15 @@ extern const struct bus_type mhi_bus_type; #define MHI_SOC_RESET_REQ_OFFSET 0xb0 #define MHI_SOC_RESET_REQ BIT(0) =20 +/* + * With ASPM enabled, the link may enter a low power state, requiring + * a wake-up sequence. Use a short burst of back-to-back reads to + * transition the link to the active state. Based on testing, + * 4 iterations are necessary to ensure reliable wake-up without + * excess latency. + */ +#define MHI_NUM_BACK_TO_BACK_READS 4 + struct mhi_ctxt { struct mhi_event_ctxt *er_ctxt; struct mhi_chan_ctxt *chan_ctxt; diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c index 52bef663e182de157e50f64c1764a52545c70865..070b58a5ea75f121d4495d9dfd5= 32f33cace274d 100644 --- a/drivers/bus/mhi/host/main.c +++ b/drivers/bus/mhi/host/main.c @@ -1702,3 +1702,77 @@ int mhi_get_channel_doorbell_offset(struct mhi_contr= oller *mhi_cntrl, u32 *chdb_ return 0; } EXPORT_SYMBOL_GPL(mhi_get_channel_doorbell_offset); + +static int mhi_get_remote_time(struct mhi_controller *mhi_cntrl, struct mh= i_timesync *mhi_tsync, + struct mhi_timesync_info *time) +{ + struct device *dev =3D &mhi_cntrl->mhi_dev->dev; + int ret, i; + + if (!mhi_tsync && !mhi_tsync->time_reg) { + dev_err(dev, "Time sync is not supported\n"); + return -EINVAL; + } + + if (unlikely(MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state))) { + dev_err(dev, "MHI is not in active state, pm_state:%s\n", + to_mhi_pm_state_str(mhi_cntrl->pm_state)); + return -EIO; + } + + /* bring to M0 state */ + ret =3D mhi_device_get_sync(mhi_cntrl->mhi_dev); + if (ret) + return ret; + + guard(mutex)(&mhi_tsync->ts_mutex); + mhi_cntrl->runtime_get(mhi_cntrl); + + /* + * time critical code to fetch device time, delay between these two steps + * should be deterministic as possible. + */ + preempt_disable(); + local_irq_disable(); + + time->t_host_pre =3D ktime_get_real(); + + /* + * To ensure the PCIe link is in L0 when ASPM is enabled, perform series + * of back-to-back reads. This is necessary because the link may be in a + * low-power state (e.g., L1 or L1ss), and need to be forced it to + * transition to L0. + */ + for (i =3D 0; i < MHI_NUM_BACK_TO_BACK_READS; i++) { + ret =3D mhi_read_reg(mhi_cntrl, mhi_tsync->time_reg, + TSC_TIMESYNC_TIME_LOW_OFFSET, &time->t_dev_lo); + + ret =3D mhi_read_reg(mhi_cntrl, mhi_tsync->time_reg, + TSC_TIMESYNC_TIME_HIGH_OFFSET, &time->t_dev_hi); + } + + time->t_host_post =3D ktime_get_real(); + + local_irq_enable(); + preempt_enable(); + + mhi_cntrl->runtime_put(mhi_cntrl); + + mhi_device_put(mhi_cntrl->mhi_dev); + + return 0; +} + +int mhi_get_remote_tsc_time_sync(struct mhi_device *mhi_dev, struct mhi_ti= mesync_info *time) +{ + struct mhi_controller *mhi_cntrl =3D mhi_dev->mhi_cntrl; + struct mhi_timesync *mhi_tsc_tsync =3D mhi_cntrl->tsc_timesync; + int ret; + + ret =3D mhi_get_remote_time(mhi_cntrl, mhi_tsc_tsync, time); + if (ret) + dev_err(&mhi_dev->dev, "Failed to get TSC Time Sync value:%d\n", ret); + + return ret; +} +EXPORT_SYMBOL_GPL(mhi_get_remote_tsc_time_sync); diff --git a/include/linux/mhi.h b/include/linux/mhi.h index dd372b0123a6da5107b807ff8fe940c567eb2030..770d51e9bfac7434ff4b4013ad0= 45c041c26adeb 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -288,6 +288,30 @@ struct mhi_controller_config { bool m2_no_db; }; =20 +/** + * struct mhi_timesync - MHI time synchronization structure + * @time_reg: Points to address of Timesync register + * @ts_mutex: Mutex for synchronization + */ +struct mhi_timesync { + void __iomem *time_reg; + struct mutex ts_mutex; +}; + +/** + * struct mhi_timesync_info - MHI time sync info structure + * @t_host_pre: Pre host soc time + * @t_host_post: Post host soc time + * @t_dev_lo: Mhi device time of lower dword + * @t_dev_hi: Mhi device time of higher dword + */ +struct mhi_timesync_info { + ktime_t t_host_pre; + ktime_t t_host_post; + u32 t_dev_lo; + u32 t_dev_hi; +}; + /** * struct mhi_controller - Master MHI controller structure * @name: Device name of the MHI controller @@ -325,6 +349,7 @@ struct mhi_controller_config { * @mhi_event: MHI event ring configurations table * @mhi_cmd: MHI command ring configurations table * @mhi_ctxt: MHI device context, shared memory between host and device + * @tsc_timesync: MHI TSC timesync * @pm_mutex: Mutex for suspend/resume operation * @pm_lock: Lock for protecting MHI power management state * @timeout_ms: Timeout in ms for state transitions @@ -403,6 +428,8 @@ struct mhi_controller { struct mhi_cmd *mhi_cmd; struct mhi_ctxt *mhi_ctxt; =20 + struct mhi_timesync *tsc_timesync; + struct mutex pm_mutex; rwlock_t pm_lock; u32 timeout_ms; @@ -809,4 +836,14 @@ bool mhi_queue_is_full(struct mhi_device *mhi_dev, enu= m dma_data_direction dir); */ int mhi_get_channel_doorbell_offset(struct mhi_controller *mhi_cntrl, u32 = *chdb_offset); =20 +/** + * mhi_get_remote_tsc_time_sync - get external soc time relative to local = soc + * time pre and post using MMIO method. + * @mhi_dev: Device associated with the channels + * @time: mhi_timesync_info to get device time details + * + * Returns: + * 0 for success, error code for failure + */ +int mhi_get_remote_tsc_time_sync(struct mhi_device *mhi_dev, struct mhi_ti= mesync_info *time); #endif /* _MHI_H_ */ --=20 2.34.1