From patchwork Sat Apr 17 10:17:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yicong Yang X-Patchwork-Id: 12209641 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7A9C8C433ED for ; Sat, 17 Apr 2021 10:24:33 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E4F776113D for ; Sat, 17 Apr 2021 10:24:32 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E4F776113D Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=hisilicon.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id: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=GEPP9FQY0quYNn2omCslPGFekdcZx0gELts96yHmBro=; b=cuabuf0AqSLGsHIOMNlp5YHk1 hkz9VTh7IAYXH9dDnUdv7LyFBdbtEcHxfL8XQ9Ev2pHhIcCCb8cnMkgTz16PFHdC17gqYr7X8GVko QBa7BQE0NAM2KHXCQk/rmSYJeFUOS/OQe3TCh063RzmGs/oSJ3pOKdzz0Z0XSwfMOar/tWCbYxjAY P9hrkr8Ddfu7gMu1SaLQz5nQ3q9G5vm7L3Hme2qpZoPI6OkAO00L1WgIss3TUh08FADaPmPk64r2b hDfgPJW5M+8rihoXJzh4ky1m2y1GG3I+1WkFCPf2RJ5XBfg+bUfEfGUY6/PQXwhDX96q6INN5EYOm OHVJpLWTw==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lXi68-004ytF-0x; Sat, 17 Apr 2021 10:22:44 +0000 Received: from bombadil.infradead.org ([2607:7c80:54:e::133]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lXi5f-004ymg-TS for linux-arm-kernel@desiato.infradead.org; Sat, 17 Apr 2021 10:22:16 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Type:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:CC:To:From:Sender:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=kG01Fyqeu6BKun7zaYAp16xTLhuzuvSZCvEX+MxN31E=; b=ZVU8YGhbL6wcLLPYMzkDisKVQp zCfj1/D+NlJpr6e5ljvMNfv+MD3Y6yE4EyAdTI0MmjkajjfM+0miVTIooUZc031FIrdryItdLHVvE C8Bwi8DQA0UPbVJBqOZ48Tbm/yjcOjdcmM79M5hqK2jZAiajJ3KSrCOOVVuT/wxh8V658NXmu3SCN Zfv8eQm+dUi+NC/WSrJgCyPWhUewXzQ0WGto34fReIDaZHfZBc72AHn2htF41i2XQ7hTWad7XrJmq WHW1obhu3/nuwA9acNrwlJTrTJsfaMNtGIzSrWBclum3x6r94uLMSeGrBTCUnhQ91q/RwW7SRDgMx 8gODK8Cg==; Received: from szxga07-in.huawei.com ([45.249.212.35]) by bombadil.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lXi5c-009yRm-2Q for linux-arm-kernel@lists.infradead.org; Sat, 17 Apr 2021 10:22:14 +0000 Received: from DGGEMS408-HUB.china.huawei.com (unknown [172.30.72.58]) by szxga07-in.huawei.com (SkyGuard) with ESMTP id 4FMptC5JsXz7vcS; Sat, 17 Apr 2021 18:17:39 +0800 (CST) Received: from localhost.localdomain (10.67.165.24) by DGGEMS408-HUB.china.huawei.com (10.3.19.208) with Microsoft SMTP Server id 14.3.498.0; Sat, 17 Apr 2021 18:19:50 +0800 From: Yicong Yang To: , , , CC: , , , , , , , , , , , , , , , , , Subject: [PATCH RESEND 2/4] hwtracing: Add tune function support for HiSilicon PCIe Tune and Trace device Date: Sat, 17 Apr 2021 18:17:09 +0800 Message-ID: <1618654631-42454-3-git-send-email-yangyicong@hisilicon.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1618654631-42454-1-git-send-email-yangyicong@hisilicon.com> References: <1618654631-42454-1-git-send-email-yangyicong@hisilicon.com> MIME-Version: 1.0 X-Originating-IP: [10.67.165.24] X-CFilter-Loop: Reflected X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210417_032212_454153_2997917F X-CRM114-Status: GOOD ( 15.27 ) 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 Add tune function for the HiSilicon Tune and Trace device. The interface of tune is also exposed through debugfs. Signed-off-by: Yicong Yang --- drivers/hwtracing/hisilicon/hisi_ptt.c | 187 +++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) diff --git a/drivers/hwtracing/hisilicon/hisi_ptt.c b/drivers/hwtracing/hisilicon/hisi_ptt.c index a1feece..2e3631b 100644 --- a/drivers/hwtracing/hisilicon/hisi_ptt.c +++ b/drivers/hwtracing/hisilicon/hisi_ptt.c @@ -72,6 +72,7 @@ struct hisi_ptt_debugfs_file_desc { struct hisi_ptt *hisi_ptt; const char *name; const struct file_operations *fops; + struct hisi_ptt_tune_event_desc *private; }; #define PTT_FILE_INIT(__name, __fops) \ @@ -85,6 +86,15 @@ struct hisi_ptt_trace_event_desc { #define PTT_TRACE_EVENT_INIT(__name, __event_code) \ { .name = __name, .event_code = __event_code } +struct hisi_ptt_tune_event_desc { + const char *name; + u32 event_code; + int (*set)(struct hisi_ptt *hisi_ptt, void *data); + int (*get)(struct hisi_ptt *hisi_ptt, void *data); +}; +#define PTT_TUNE_EVENT_INIT(__name, __event_code, __set, __get) \ + { .name = __name, .event_code = __event_code, .set = __set, .get = __get } + enum hisi_ptt_trace_rxtx { HISI_PTT_TRACE_RX = 0, HISI_PTT_TRACE_TX, @@ -217,6 +227,8 @@ struct hisi_ptt { bool is_port; u16 val; } cur_filter; + + u32 tune_event; }; static int hisi_ptt_write_to_buffer(void *buf, size_t len, loff_t *pos, @@ -234,6 +246,131 @@ static int hisi_ptt_write_to_buffer(void *buf, size_t len, loff_t *pos, return 0; } +static int hisi_ptt_wait_tuning_finish(struct hisi_ptt *hisi_ptt) +{ + u32 val; + + return readl_poll_timeout(hisi_ptt->iobase + HISI_PTT_TUNING_INT_STAT, + val, !(val & HISI_PTT_TUNING_INT_STAT_MASK), + HISI_PTT_WAIT_POLL_INTERVAL_US, + HISI_PTT_WAIT_TIMEOUT_US); +} + +static int hisi_ptt_tune_data_get(struct hisi_ptt *hisi_ptt, void *data) +{ + u32 *val = data, reg; + + reg = readl(hisi_ptt->iobase + HISI_PTT_TUNING_CTRL); + reg &= ~(HISI_PTT_TUNING_CTRL_CODE | HISI_PTT_TUNING_CTRL_SUB); + reg |= FIELD_PREP(HISI_PTT_TUNING_CTRL_CODE | HISI_PTT_TUNING_CTRL_SUB, + hisi_ptt->tune_event); + writel(reg, hisi_ptt->iobase + HISI_PTT_TUNING_CTRL); + /* Write all 1 to indicates it's the read process */ + writel(HISI_PTT_TUNING_DATA_VAL_MASK, + hisi_ptt->iobase + HISI_PTT_TUNING_DATA); + + if (hisi_ptt_wait_tuning_finish(hisi_ptt)) { + pci_err(hisi_ptt->pdev, "failed to read tune data, device timeout.\n"); + return -ETIMEDOUT; + } + + *val = readl(hisi_ptt->iobase + HISI_PTT_TUNING_DATA); + *val &= HISI_PTT_TUNING_DATA_VAL_MASK; + + return 0; +} + +static int hisi_ptt_tune_data_set(struct hisi_ptt *hisi_ptt, void *data) +{ + u32 *val = data, reg; + + reg = readl(hisi_ptt->iobase + HISI_PTT_TUNING_CTRL); + reg &= ~(HISI_PTT_TUNING_CTRL_CODE | HISI_PTT_TUNING_CTRL_SUB); + reg |= FIELD_PREP(HISI_PTT_TUNING_CTRL_CODE | HISI_PTT_TUNING_CTRL_SUB, + hisi_ptt->tune_event); + writel(reg, hisi_ptt->iobase + HISI_PTT_TUNING_CTRL); + *val &= HISI_PTT_TUNING_DATA_VAL_MASK; + writel(*val, hisi_ptt->iobase + HISI_PTT_TUNING_DATA); + + if (hisi_ptt_wait_tuning_finish(hisi_ptt)) { + pci_err(hisi_ptt->pdev, "failed to write tune data, device timeout.\n"); + return -ETIMEDOUT; + } + + return 0; +} + +static ssize_t hisi_ptt_tune_common_read(struct file *filp, char __user *buf, + size_t count, loff_t *pos) +{ + struct hisi_ptt_debugfs_file_desc *desc = filp->private_data; + struct hisi_ptt *hisi_ptt = desc->hisi_ptt; + struct hisi_ptt_tune_event_desc *e_desc = desc->private; + char tbuf[HISI_PTT_CTRL_STR_LEN]; + int len, ret; + u32 val; + + if (!mutex_trylock(&hisi_ptt->mutex)) + return -EBUSY; + + hisi_ptt->tune_event = e_desc->event_code; + ret = e_desc->get(hisi_ptt, &val); + mutex_unlock(&hisi_ptt->mutex); + if (ret) + return ret; + + len = snprintf(tbuf, HISI_PTT_CTRL_STR_LEN, "%d\n", val); + + return simple_read_from_buffer(buf, count, pos, tbuf, len); +} + +static ssize_t hisi_ptt_tune_common_write(struct file *filp, + const char __user *buf, + size_t count, loff_t *pos) +{ + struct hisi_ptt_debugfs_file_desc *desc = filp->private_data; + struct hisi_ptt *hisi_ptt = desc->hisi_ptt; + struct hisi_ptt_tune_event_desc *e_desc = desc->private; + char tbuf[HISI_PTT_CTRL_STR_LEN]; + int ret; + u16 val; + + if (hisi_ptt_write_to_buffer(tbuf, HISI_PTT_CTRL_STR_LEN - 1, + pos, buf, count)) + return -EINVAL; + + if (kstrtou16(tbuf, 0, &val)) + return -EINVAL; + + if (!mutex_trylock(&hisi_ptt->mutex)) + return -EBUSY; + + hisi_ptt->tune_event = e_desc->event_code; + ret = e_desc->set(hisi_ptt, &val); + + mutex_unlock(&hisi_ptt->mutex); + return ret ? ret : count; +} + +static const struct file_operations tune_common_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = hisi_ptt_tune_common_read, + .write = hisi_ptt_tune_common_write, + .llseek = no_llseek, +}; + +#define PTT_SIMPLE_TUNE_EVENTS(__name, __event_code) \ + PTT_TUNE_EVENT_INIT(__name, __event_code, hisi_ptt_tune_data_set, hisi_ptt_tune_data_get) + +static struct hisi_ptt_tune_event_desc tune_events[] = { + PTT_SIMPLE_TUNE_EVENTS("qos_tx_cpl", (0x4 | (3 << 16))), + PTT_SIMPLE_TUNE_EVENTS("qos_tx_np", (0x4 | (4 << 16))), + PTT_SIMPLE_TUNE_EVENTS("qos_tx_p", (0x4 | (5 << 16))), + PTT_SIMPLE_TUNE_EVENTS("tx_path_rx_req_alloc_buf_level", (0x5 | (6 << 16))), + PTT_SIMPLE_TUNE_EVENTS("tx_path_tx_req_alloc_buf_level", (0x5 | (7 << 16))), +}; + static u16 hisi_ptt_get_filter_val(struct pci_dev *pdev) { if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT) @@ -1241,6 +1378,49 @@ static void hisi_ptt_init_ctrls(struct hisi_ptt *hisi_ptt) hisi_ptt->trace_ctrl.tr_event = HISI_PTT_TRACE_DEFAULT_EVENT.event_code; } +static int hisi_ptt_create_tune_entries(struct hisi_ptt *hisi_ptt) +{ + struct hisi_ptt_debugfs_file_desc *tune_files; + struct dentry *dir; + int i, ret = 0; + + dir = debugfs_create_dir("tune", hisi_ptt->debugfs_dir); + if (IS_ERR(dir)) + return PTR_ERR(dir); + + tune_files = devm_kcalloc(&hisi_ptt->pdev->dev, ARRAY_SIZE(tune_events), + sizeof(struct hisi_ptt_debugfs_file_desc), + GFP_KERNEL); + if (IS_ERR(tune_files)) { + ret = PTR_ERR(tune_files); + goto err; + } + + for (i = 0; i < ARRAY_SIZE(tune_events); ++i) { + struct dentry *file; + + tune_files[i].hisi_ptt = hisi_ptt; + + /* We use tune event string as control file name. */ + tune_files[i].name = tune_events[i].name; + tune_files[i].fops = &tune_common_fops; + tune_files[i].private = &tune_events[i]; + file = debugfs_create_file(tune_files[i].name, 0600, + dir, &tune_files[i], + &tune_common_fops); + if (IS_ERR(file)) { + ret = PTR_ERR(file); + goto err; + } + } + + return 0; + +err: + debugfs_remove_recursive(dir); + return ret; +} + static int hisi_ptt_create_trace_entries(struct hisi_ptt *hisi_ptt) { struct hisi_ptt_debugfs_file_desc *trace_files; @@ -1294,6 +1474,13 @@ static int hisi_ptt_create_debugfs_entries(struct hisi_ptt *hisi_ptt) return ret; } + ret = hisi_ptt_create_tune_entries(hisi_ptt); + if (ret) { + pci_err(hisi_ptt->pdev, "failed to create tune entries.\n"); + debugfs_remove_recursive(hisi_ptt->debugfs_dir); + return ret; + } + return 0; }