From patchwork Thu Feb 27 09:26:35 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: songchai X-Patchwork-Id: 13994016 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2114DC19F2E for ; Thu, 27 Feb 2025 09:41:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type: Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date :Subject:CC:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=2vLLCr0C7CBSwFASgTef7yr9Y3K8NM+33PnWJy0v1hs=; b=uCQMd2nJCBXFh01VdYSAFfxhJo KY9fqg2BIOLehncTyQC9e6anJHoeby9HEy874eOnEdzznapG7itMUrgGj6DNHfMAKNvEX7pT2VAe3 nnIofW3LhSlSdeQH+TxNRLviUgKKvK0hX9DvEOVVwQnirmL+Ao/QVvjGwTLsAggoiTXr0CQhI1T/2 S4cLEIHPT9a1JgYColyych/HgYXmng9N0+qo2FTaYNMbhAMN/QKcwyI5JQxmvAH8OY5nzZkS3Jp2W 01HvnnvaKD85UQOCyZdBHawacYZIn8iwmaQyANKQJCtzikrfgsfDaI72Tex9s5ZOCTx7fBCp3NGE2 /ZTiPS5w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tnaOj-00000006tUl-34tU; Thu, 27 Feb 2025 09:41:41 +0000 Received: from mx0b-0031df01.pphosted.com ([205.220.180.131]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tnaAp-00000006rGs-1Lvr for linux-arm-kernel@lists.infradead.org; Thu, 27 Feb 2025 09:27:21 +0000 Received: from pps.filterd (m0279871.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 51R9N7sJ017602; Thu, 27 Feb 2025 09:27:12 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= 2vLLCr0C7CBSwFASgTef7yr9Y3K8NM+33PnWJy0v1hs=; b=patfxaJplo+FWvdM nNXGlD7mUXIAhkyQc2hj7o9FJgxbOVBsb9YRWUVGLbZ8acM0HMx8zak+JLRSRuac QA/CDtu8/UMInqOo9pNGf3RXyJxl29hP6KDOhkW/H+YA2FoKi/utW3kgAHNhqg3i 3sEAjDYNz++5e4T/1rnMPO2ImXTuwlTkpHVsoVO7pg1epmHvgHGbdWXgOqJnj9Ol TpgFRz1lLnSRI0Lxm3ID9e7tPZjAN5Kc2WVljn50UnCsg9Q+AAFKr/mypSub/DUe VTAnc5ra3bJRWSmyR+M1rCZ/ahZvx36PzheWj/xF9Jh1BRSr0X5unM1QJMPnxRhL 3wQeBw== Received: from nasanppmta03.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 451prn531t-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 27 Feb 2025 09:27:11 +0000 (GMT) Received: from nasanex01b.na.qualcomm.com (nasanex01b.na.qualcomm.com [10.46.141.250]) by NASANPPMTA03.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 51R9RAQT021082 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 27 Feb 2025 09:27:10 GMT Received: from ap-cloud-sh02-lnx.qualcomm.com (10.80.80.8) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Thu, 27 Feb 2025 01:27:06 -0800 From: songchai To: Suzuki K Poulose , Mike Leach , James Clark , "Alexander Shishkin" , Andy Gross , Bjorn Andersson , Rob Herring , Krzysztof Kozlowski , Conor Dooley CC: Songwei Chai , , , , , Subject: [PATCH v3 2/7] coresight: Add coresight TGU driver Date: Thu, 27 Feb 2025 17:26:35 +0800 Message-ID: <20250227092640.2666894-3-quic_songchai@quicinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20250227092640.2666894-1-quic_songchai@quicinc.com> References: <20250227092640.2666894-1-quic_songchai@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nasanex01b.na.qualcomm.com (10.46.141.250) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: CtncMPrbBI6HXtCjMTSGvqBtuYS7kFAx X-Proofpoint-GUID: CtncMPrbBI6HXtCjMTSGvqBtuYS7kFAx X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34 definitions=2025-02-27_04,2025-02-26_01,2024-11-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 spamscore=0 clxscore=1011 mlxscore=0 adultscore=0 mlxlogscore=999 suspectscore=0 phishscore=0 bulkscore=0 malwarescore=0 lowpriorityscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2502100000 definitions=main-2502270071 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250227_012719_490528_D3BB3E96 X-CRM114-Status: GOOD ( 30.15 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Songwei Chai Add driver to support Coresight device TGU (Trigger Generation Unit). TGU is a Data Engine which can be utilized to sense a plurality of signals and create a trigger into the CTI or generate interrupts to processors. Add probe/enable/disable functions for tgu. Signed-off-by: Songwei Chai Signed-off-by: songchai --- .../testing/sysfs-bus-coresight-devices-tgu | 9 + drivers/hwtracing/coresight/Kconfig | 11 + drivers/hwtracing/coresight/Makefile | 1 + drivers/hwtracing/coresight/coresight-tgu.c | 218 ++++++++++++++++++ drivers/hwtracing/coresight/coresight-tgu.h | 36 +++ 5 files changed, 275 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-coresight-devices-tgu create mode 100644 drivers/hwtracing/coresight/coresight-tgu.c create mode 100644 drivers/hwtracing/coresight/coresight-tgu.h diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tgu b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tgu new file mode 100644 index 000000000000..741bc9fd9df5 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tgu @@ -0,0 +1,9 @@ +What: /sys/bus/coresight/devices//enable_tgu +Date: February 2025 +KernelVersion 6.15 +Contact: Jinlong Mao (QUIC) , Sam Chai (QUIC) +Description: + (RW) Set/Get the enable/disable status of TGU + Accepts only one of the 2 values - 0 or 1. + 0 : disable TGU. + 1 : enable TGU. diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig index 06f0a7594169..3fe59c745dd4 100644 --- a/drivers/hwtracing/coresight/Kconfig +++ b/drivers/hwtracing/coresight/Kconfig @@ -247,4 +247,15 @@ config CORESIGHT_DUMMY To compile this driver as a module, choose M here: the module will be called coresight-dummy. + +config CORESIGHT_TGU + tristate "CoreSight Trigger Generation Unit driver" + help + This driver provides support for Trigger Generation Unit that is + used to detect patterns or sequences on a given set of signals. + TGU is used to monitor a particular bus within a given region to + detect illegal transaction sequences or slave responses. It is also + used to monitor a data stream to detect protocol violations and to + provide a trigger point for centering data around a specific event + within the trace data buffer. endif diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile index 4ba478211b31..7c2b9e9cf1cd 100644 --- a/drivers/hwtracing/coresight/Makefile +++ b/drivers/hwtracing/coresight/Makefile @@ -51,3 +51,4 @@ coresight-cti-y := coresight-cti-core.o coresight-cti-platform.o \ coresight-cti-sysfs.o obj-$(CONFIG_ULTRASOC_SMB) += ultrasoc-smb.o obj-$(CONFIG_CORESIGHT_DUMMY) += coresight-dummy.o +obj-$(CONFIG_CORESIGHT_TGU) += coresight-tgu.o diff --git a/drivers/hwtracing/coresight/coresight-tgu.c b/drivers/hwtracing/coresight/coresight-tgu.c new file mode 100644 index 000000000000..da4c04ac1097 --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-tgu.c @@ -0,0 +1,218 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "coresight-priv.h" +#include "coresight-tgu.h" + +DEFINE_CORESIGHT_DEVLIST(tgu_devs, "tgu"); + +static void tgu_write_all_hw_regs(struct tgu_drvdata *drvdata) +{ + CS_UNLOCK(drvdata->base); + /* Enable TGU to program the triggers */ + tgu_writel(drvdata, 1, TGU_CONTROL); + CS_LOCK(drvdata->base); +} + +static int tgu_enable(struct coresight_device *csdev, enum cs_mode mode, + void *data) +{ + struct tgu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + + spin_lock(&drvdata->spinlock); + + if (drvdata->enable) { + spin_unlock(&drvdata->spinlock); + return -EBUSY; + } + tgu_write_all_hw_regs(drvdata); + drvdata->enable = true; + + spin_unlock(&drvdata->spinlock); + return 0; +} + +static int tgu_disable(struct coresight_device *csdev, void *data) +{ + struct tgu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + + spin_lock(&drvdata->spinlock); + + if (!drvdata->enable) { + spin_unlock(&drvdata->spinlock); + return 0; + } + + CS_UNLOCK(drvdata->base); + tgu_writel(drvdata, 0, TGU_CONTROL); + CS_LOCK(drvdata->base); + + drvdata->enable = false; + spin_unlock(&drvdata->spinlock); + return 0; +} + +static ssize_t enable_tgu_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + bool enabled; + + struct tgu_drvdata *drvdata = dev_get_drvdata(dev->parent); + + spin_lock(&drvdata->spinlock); + enabled = drvdata->enable; + spin_unlock(&drvdata->spinlock); + + return sprintf(buf, "%d\n", enabled); +} + +/* enable_tgu_store - Configure Trace and Gating Unit (TGU) triggers. */ +static ssize_t enable_tgu_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t size) +{ + int ret = 0; + unsigned long val; + struct tgu_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 0, &val); + if (ret) + return ret; + + if (val) { + ret = pm_runtime_resume_and_get(dev->parent); + if (ret) + return ret; + ret = tgu_enable(drvdata->csdev, CS_MODE_SYSFS, NULL); + if (ret) + pm_runtime_put(dev->parent); + } else { + ret = tgu_disable(drvdata->csdev, NULL); + if (!ret) + pm_runtime_put(dev->parent); + } + + if (ret) + return ret; + return size; +} +static DEVICE_ATTR_RW(enable_tgu); + +static const struct coresight_ops_helper tgu_helper_ops = { + .enable = tgu_enable, + .disable = tgu_disable, +}; + +static const struct coresight_ops tgu_ops = { + .helper_ops = &tgu_helper_ops, +}; + +static struct attribute *tgu_common_attrs[] = { + &dev_attr_enable_tgu.attr, + NULL, +}; + +static const struct attribute_group tgu_common_grp = { + .attrs = tgu_common_attrs, + NULL, +}; + +static const struct attribute_group *tgu_attr_groups[] = { + &tgu_common_grp, + NULL, +}; + +static int tgu_probe(struct amba_device *adev, const struct amba_id *id) +{ + int ret = 0; + struct device *dev = &adev->dev; + struct coresight_desc desc = { 0 }; + struct coresight_platform_data *pdata; + struct tgu_drvdata *drvdata; + + desc.name = coresight_alloc_device_name(&tgu_devs, dev); + if (!desc.name) + return -ENOMEM; + + pdata = coresight_get_platform_data(dev); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + + adev->dev.platform_data = pdata; + + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + + drvdata->dev = &adev->dev; + dev_set_drvdata(dev, drvdata); + + drvdata->base = devm_ioremap_resource(dev, &adev->res); + if (!drvdata->base) + return -ENOMEM; + + spin_lock_init(&drvdata->spinlock); + + drvdata->enable = false; + desc.type = CORESIGHT_DEV_TYPE_HELPER; + desc.pdata = adev->dev.platform_data; + desc.dev = &adev->dev; + desc.ops = &tgu_ops; + desc.groups = tgu_attr_groups; + + drvdata->csdev = coresight_register(&desc); + if (IS_ERR(drvdata->csdev)) { + ret = PTR_ERR(drvdata->csdev); + goto err; + } + + pm_runtime_put(&adev->dev); + return 0; +err: + pm_runtime_put(&adev->dev); + return ret; +} + +static void tgu_remove(struct amba_device *adev) +{ + struct tgu_drvdata *drvdata = dev_get_drvdata(&adev->dev); + + coresight_unregister(drvdata->csdev); +} + +static const struct amba_id tgu_ids[] = { + { + .id = 0x000f0e00, + .mask = 0x000fffff, + .data = "TGU", + }, + { 0, 0, NULL }, +}; + +MODULE_DEVICE_TABLE(amba, tgu_ids); + +static struct amba_driver tgu_driver = { + .drv = { + .name = "coresight-tgu", + .suppress_bind_attrs = true, + }, + .probe = tgu_probe, + .remove = tgu_remove, + .id_table = tgu_ids, +}; + +module_amba_driver(tgu_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("CoreSight TGU driver"); diff --git a/drivers/hwtracing/coresight/coresight-tgu.h b/drivers/hwtracing/coresight/coresight-tgu.h new file mode 100644 index 000000000000..380686f94130 --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-tgu.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _CORESIGHT_TGU_H +#define _CORESIGHT_TGU_H + +/* Register addresses */ +#define TGU_CONTROL 0x0000 + +/* Register read/write */ +#define tgu_writel(drvdata, val, off) __raw_writel((val), drvdata->base + off) +#define tgu_readl(drvdata, off) __raw_readl(drvdata->base + off) + +/** + * struct tgu_drvdata - Data structure for a TGU (Trigger Generator Unit) device + * @base: Memory-mapped base address of the TGU device + * @dev: Pointer to the associated device structure + * @csdev: Pointer to the associated coresight device + * @spinlock: Spinlock for handling concurrent access + * @enable: Flag indicating whether the TGU device is enabled + * + * This structure defines the data associated with a TGU device, including its base + * address, device pointers, clock, spinlock for synchronization, trigger data pointers, + * maximum limits for various trigger-related parameters, and enable status. + */ +struct tgu_drvdata { + void __iomem *base; + struct device *dev; + struct coresight_device *csdev; + spinlock_t spinlock; + bool enable; +}; + +#endif