From patchwork Tue Oct 27 10:44:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joakim Zhang X-Patchwork-Id: 11859897 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=-12.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,MSGID_FROM_MTA_HEADER,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham 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 02383C4363A for ; Tue, 27 Oct 2020 10:45:15 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (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 6FF5520878 for ; Tue, 27 Oct 2020 10:45:14 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="b3qe+Flm"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=nxp.com header.i=@nxp.com header.b="YLTFJnP6" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6FF5520878 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=nxp.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=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:To:From: Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender :Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Owner; bh=z7j02fqVceArlPgzlaXUNMLTGk9fZkf0uHlPYRwLY00=; b=b3qe+FlmxAvI9KvUYd0t3/lSZg o3eKoyyXD/SB3/fxgBCaL1Uf/6rlh8my/neuy7RPhuTxfONBB79613uSwhTY4jEeZuzCOO9fAn8ab voW7L8JiGRR3nhwsC4UvGJ1ibd9fU5TgnWfwoSblLrs5MHK4P7YxXH0yTmKso+DHFWMUangR5q6lg 9pxh2TqP+ndPQoKlJKBmoweXpjYSP7FMagjkTO9xVDd4vRJlspyq6WRpdkTVRLf6pefklu8OOqstB GIVLs4JKzE4dOX16Sxw09Otevqkm6v4CE48Ba5Lv7GfGXc83WHW02kgBrGU/yRM9ssNpOwkDq5iWA hXJvwmCw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kXMT2-0002UV-62; Tue, 27 Oct 2020 10:44:40 +0000 Received: from mail-vi1eur05on2055.outbound.protection.outlook.com ([40.107.21.55] helo=EUR05-VI1-obe.outbound.protection.outlook.com) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kXMSo-0002OU-0v for linux-arm-kernel@lists.infradead.org; Tue, 27 Oct 2020 10:44:29 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=SwEfYqA9Ske36rVHjwk1ieFfiyZh9DnDA9vsF+g0qT6a+P6aCmPMPWcr9IeUrSuRDlw/Q23PBIpAT101ElfCD+4YQ6wEIVyqKAwyPVUBX4FW9xW/BypSila32HtUhqraqO1WiOlra8+x195rsIASWu6ERY6nHyPC/SF8phfeIwcfE1hPN7HSxTaVrc8TLyrO1JWJ/U8FWp5m97XCbShIjmslrz2rmIiQgJ7sBDx7TqAcWOk+w39vemWrXTy6qLQxMRMovim7KibLUu4GvkBywzRfgUdlq5Dlhz+gdHQgchcWlqiZwqhVTVz3lig6L8oRjLEFwW0qfCvJt+KMi1RbTA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=5ykp0o4ZrEEUUnAqhLDDXJF8mNALcKZIrMgB++tWkzo=; b=NKU2G9uq7Wmc/nLngs1A6DKclERg7gtg7dsie4jRKVOrrzyYFYYrKNZMzobr1Fc5tmZjAvqudA1QzGi7sDS+SrY3wD3Jhi4dOk9KmBG4o683P45weU4og8+pRlBn+vBQrdDvcuWFCQUH24D2TpSaF2VDgnyddts7TnyEhFPfP1jSgUU0ZMjy49vZVsd3o1NQX8eEUpSpWC/JgcoxKCwjgVVHHcmt31Kw+uLSCO1ZAqnSu7Xj1GTaUyjpT+cm6ZXu6OuGNjYJJcnsRQuJnpx82n2pJmXAYPie4p0bqWAJkJoVFiJSbIykqOmq6cVY/uKJA/n1hXFUIHixR6YodDDRSQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nxp.com; dmarc=pass action=none header.from=nxp.com; dkim=pass header.d=nxp.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=5ykp0o4ZrEEUUnAqhLDDXJF8mNALcKZIrMgB++tWkzo=; b=YLTFJnP6k6kGqlpPNdihgov6L/8c34KGQvXUejQFtoQSu/LrpsIUgbykS0ZKUzguoWeYqabN5U8Zeh2TW3/kTSp45tHtyuo3retKvZWMfv1PxseCEIOr1okI/jMNLeSKOBor4z8ZqYOGATp4g+drZ8HDy4n5+G8ENHAA08f8xbY= Authentication-Results: kernel.org; dkim=none (message not signed) header.d=none;kernel.org; dmarc=none action=none header.from=nxp.com; Received: from DB8PR04MB6795.eurprd04.prod.outlook.com (2603:10a6:10:fa::15) by DB8PR04MB6969.eurprd04.prod.outlook.com (2603:10a6:10:11b::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3455.24; Tue, 27 Oct 2020 10:44:21 +0000 Received: from DB8PR04MB6795.eurprd04.prod.outlook.com ([fe80::3c3a:58b9:a1cc:cbcc]) by DB8PR04MB6795.eurprd04.prod.outlook.com ([fe80::3c3a:58b9:a1cc:cbcc%9]) with mapi id 15.20.3477.028; Tue, 27 Oct 2020 10:44:21 +0000 From: Joakim Zhang To: will@kernel.org Subject: [PATCH V3] perf/imx_ddr: Add stop event counters support for i.MX8MP Date: Tue, 27 Oct 2020 18:44:51 +0800 Message-Id: <20201027104451.15434-1-qiangqing.zhang@nxp.com> X-Mailer: git-send-email 2.17.1 X-Originating-IP: [119.31.174.71] X-ClientProxiedBy: SG2PR06CA0246.apcprd06.prod.outlook.com (2603:1096:4:ac::30) To DB8PR04MB6795.eurprd04.prod.outlook.com (2603:10a6:10:fa::15) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from localhost.localdomain (119.31.174.71) by SG2PR06CA0246.apcprd06.prod.outlook.com (2603:1096:4:ac::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3499.18 via Frontend Transport; Tue, 27 Oct 2020 10:44:19 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: 54032273-89c7-41f9-8fcd-08d87a65433d X-MS-TrafficTypeDiagnostic: DB8PR04MB6969: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:8882; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 4FplwWMe08Y0xkHfg9pTJZ7Kpa2kNpUbEjfvA9uf2BUgsl56Tufude4dZf5kLrB5/C2uJv1h8ql+7LUywJMB6msAqmA1goi+moCJAj50y3jUw61e6GqMAskIMy355cEMnT5K64l+skK4r66n/OJ9c7u2tPwKopgAlmhxkDYfWIH5Y3K9sdRsMb2OhBVXC+5Xpxd4UidQRdudfnwWSk9U0sRnY8ZpNmuWxHZzgibqoOGL242YAslAxip9R5F/kF+lgw7rl5wKH8tSyPtNkHA9IpT75eEjji7NpKWoxaRiw+iVCsmcYtlomg1W2ConoAJU3Ft9CBzb+BAswb0niQb2th1BmakmcXna0EaaOiWfc9jqwctBvG4D+vHLfGhvVMNM X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:DB8PR04MB6795.eurprd04.prod.outlook.com; PTR:; CAT:NONE; SFS:(4636009)(396003)(376002)(39860400002)(346002)(366004)(136003)(316002)(26005)(52116002)(16526019)(66946007)(66476007)(478600001)(956004)(66556008)(6506007)(83380400001)(69590400008)(1076003)(186003)(2616005)(6666004)(5660300002)(86362001)(36756003)(8936002)(6916009)(6486002)(4326008)(8676002)(2906002)(6512007); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData: 6tAm1OQ3/v4cenROXNZwGV8/xSb3YWS/S7PU7wRPTNFH2621s5RMgvfvFnVlpi/TMYuOF/1XJTmZStXBxzVKL1qK/Z5giJKtwLvudUXVaimuDEgxYcdL/jokTqOpoUBBOFuzdeC3YNJCDlL8tSicJar5UL0MGnPoekret4OpgwuJoI9yvsCAKGtf7H2+xKsUmx91jnVTbZApE7S/T+098fJ5HmZg5md6HMtcc3XJ35LBwGMkDIerJPVWEj+ZvKgsMCSZhqmmTWgQDrjoQ+wwTvdMxscwPJwukG7LiL61B6zWuaFcpi6g3NJw9HxZHX6TAnvF3BIYi7Hyzf6CdK6KK+J9CQwjzROTQNkkXzbhxhYKNGej2BPdetprzPygQI+G8MPvEUkNzHbthRasYQ95cJ32/+k32oaUvFXcmMjBGYrB/yr3+WT1INOoT2pqJCy0Z9QpgdqP2ivbeS2Nm5YeC43kydM/O4iFzusfvtI6K2ECTL7/LP8tN2omjV2ps86njvTHQrTKm73OFU5M7eI8Mh2t92TCOT+kq5hkYvbAkMNcC+vrdmxlg1/u/ZnKJN9MJVd5lMACC6cp3k3c/JPMHOXn0dbshWzd+yY+u27U7GUDfInS9bp3YdHfJ59cm2yoTFGQx6+uJ0s7XnFemYmPxQ== X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 54032273-89c7-41f9-8fcd-08d87a65433d X-MS-Exchange-CrossTenant-AuthSource: DB8PR04MB6795.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Oct 2020 10:44:21.3807 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 9PLLOXOa3iO/qxHy8sE3ehSu9LzlgUD4lRvqv6mKAupDQk9KE9YGcJBmbIrWgsnRoYV/Scy6aqXdb+AsBnZMtA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB8PR04MB6969 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201027_064426_403182_00EB0733 X-CRM114-Status: GOOD ( 22.81 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, robin.murphy@arm.com, linux-imx@nxp.com, linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DDR Perf driver only supports free-running event counters(counter1/2/3) now, this patch adds support for stop event counters. Legacy SoCs: Cycle counter(counter0) is a special counter, only count cycles. When cycle counter overflow, it will lock all counters and generate an interrupt. In ddr_perf_irq_handler, disable cycle counter then all counters would stop at the same time, update all counters' count, then enable cycle counter that all counters count again. During this process, only clear cycle counter, no need to clear event counters since they are free-running counters. They would continue counting after overflow and do/while loop from ddr_perf_event_update can handle event counters overflow case. i.MX8MP: Almost all is the same as legacy SoCs, the only difference is that, event counters are not free-running any more. Like cycle counter, when event counters overflow, they would stop counting unless clear the counter, and no interrupt generate for event counters. So we should clear event counters that let them re-count when cycle counter overflow, which ensure event counters will not lose data. This patch adds stop event counters support which would be compatible to free-running event counters. We use the cycle counter to stop overflow of the event counters. Signed-off-by: Joakim Zhang --- ChangeLogs: V2->V3: * return val & CNTL_OVER ? true : false; -> return val & CNTL_OVER; * dev_warn() -> dev_warn_ratelimited() * treat cycle counter and event counter as the same way in update function. * add ddr_perf_counter_clear() V1->V2: * clear event counters in update function, instead of irq handler, so remove spinlock. --- drivers/perf/fsl_imx8_ddr_perf.c | 80 +++++++++++++++++++++----------- 1 file changed, 54 insertions(+), 26 deletions(-) diff --git a/drivers/perf/fsl_imx8_ddr_perf.c b/drivers/perf/fsl_imx8_ddr_perf.c index 90884d14f95f..98aec58f1559 100644 --- a/drivers/perf/fsl_imx8_ddr_perf.c +++ b/drivers/perf/fsl_imx8_ddr_perf.c @@ -361,25 +361,6 @@ static int ddr_perf_event_init(struct perf_event *event) return 0; } - -static void ddr_perf_event_update(struct perf_event *event) -{ - struct ddr_pmu *pmu = to_ddr_pmu(event->pmu); - struct hw_perf_event *hwc = &event->hw; - u64 delta, prev_raw_count, new_raw_count; - int counter = hwc->idx; - - do { - prev_raw_count = local64_read(&hwc->prev_count); - new_raw_count = ddr_perf_read_counter(pmu, counter); - } while (local64_cmpxchg(&hwc->prev_count, prev_raw_count, - new_raw_count) != prev_raw_count); - - delta = (new_raw_count - prev_raw_count) & 0xFFFFFFFF; - - local64_add(delta, &event->count); -} - static void ddr_perf_counter_enable(struct ddr_pmu *pmu, int config, int counter, bool enable) { @@ -404,6 +385,56 @@ static void ddr_perf_counter_enable(struct ddr_pmu *pmu, int config, } } +static bool ddr_perf_counter_overflow(struct ddr_pmu *pmu, int counter) +{ + int val; + + val = readl_relaxed(pmu->base + counter * 4 + COUNTER_CNTL); + + return val & CNTL_OVER; +} + +static void ddr_perf_counter_clear(struct ddr_pmu *pmu, int counter) +{ + u8 reg = counter * 4 + COUNTER_CNTL; + int val; + + val = readl_relaxed(pmu->base + reg); + val &= ~CNTL_CLEAR; + writel(val, pmu->base + reg); + + val |= CNTL_CLEAR; + writel(val, pmu->base + reg); +} + +static void ddr_perf_event_update(struct perf_event *event) +{ + struct ddr_pmu *pmu = to_ddr_pmu(event->pmu); + struct hw_perf_event *hwc = &event->hw; + u64 new_raw_count; + int counter = hwc->idx; + int ret; + + new_raw_count = ddr_perf_read_counter(pmu, counter); + local64_add(new_raw_count, &event->count); + + /* + * For legacy SoCs: event counter continue counting when overflow, + * no need to clear the counter. + * For new SoCs: event counter stop counting when overflow, need + * clear counter to let it count again. + */ + if (counter != EVENT_CYCLES_COUNTER) { + ret = ddr_perf_counter_overflow(pmu, counter); + if (ret) + dev_warn_ratelimited(pmu->dev, "events lost due to counter overflow (config 0x%llx)\n", + event->attr.config); + } + + /* clear counter every time for both cycle counter and event counter */ + ddr_perf_counter_clear(pmu, counter); +} + static void ddr_perf_event_start(struct perf_event *event, int flags) { struct ddr_pmu *pmu = to_ddr_pmu(event->pmu); @@ -536,7 +567,7 @@ static irqreturn_t ddr_perf_irq_handler(int irq, void *p) { int i; struct ddr_pmu *pmu = (struct ddr_pmu *) p; - struct perf_event *event, *cycle_event = NULL; + struct perf_event *event; /* all counter will stop if cycle counter disabled */ ddr_perf_counter_enable(pmu, @@ -546,7 +577,9 @@ static irqreturn_t ddr_perf_irq_handler(int irq, void *p) /* * When the cycle counter overflows, all counters are stopped, * and an IRQ is raised. If any other counter overflows, it - * continues counting, and no IRQ is raised. + * continues counting, and no IRQ is raised. But for new SoCs, + * such as i.MX8MP, event counter would stop when overflow, so + * we need use cycle counter to stop overflow of event counter. * * Cycles occur at least 4 times as often as other events, so we * can update all events on a cycle counter overflow and not @@ -561,17 +594,12 @@ static irqreturn_t ddr_perf_irq_handler(int irq, void *p) event = pmu->events[i]; ddr_perf_event_update(event); - - if (event->hw.idx == EVENT_CYCLES_COUNTER) - cycle_event = event; } ddr_perf_counter_enable(pmu, EVENT_CYCLES_ID, EVENT_CYCLES_COUNTER, true); - if (cycle_event) - ddr_perf_event_update(cycle_event); return IRQ_HANDLED; }