Received: by 2002:a6b:500f:0:0:0:0:0 with SMTP id e15csp4595363iob; Sun, 8 May 2022 18:37:14 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz93yR7DvZV3uUoL2/tjDsyqvN1RyWvGGVxxBhCVxNJnpQNCXINsWEV4CE2l6wC/hC/mC55 X-Received: by 2002:a17:90b:1c04:b0:1dc:4dfd:5a43 with SMTP id oc4-20020a17090b1c0400b001dc4dfd5a43mr24376849pjb.160.1652060234468; Sun, 08 May 2022 18:37:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1652060234; cv=none; d=google.com; s=arc-20160816; b=Im3emOQH/QjJ/bDtc95gtfNtF6QT5YyBk4VbkicdYKcAt39X9SoCNOffCyGGHv4pnL hh/9NzH0rI8suhkHmtN+Y72F99gViqD9vdEdq3uPtAGtvEQkPIIEe4fn/0WM3tMjvlTK 7WCm3fuCk4aKhp9WwhxSG1TCNncHUgrlaseJDZbszIcnrmUzmQAgp/BAZ+5t/CeJXFeh r22sTVuKewgPuWKNw/dHEjcLiXsIxp603yyJh9MQlckpcXoNLa2UiGkdTjHwdeRz36q1 UkNePt6JO2k6rTvTTEWi6mvt+FhMxJJDivFAyqdhxYy/WSknPnrXhVZ/aNSfCul77KAy nfkQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:references:in-reply-to:message-id:date:subject :cc:to:from:dkim-signature; bh=wPeo9gKUsXGDcf2AwG47xYAu+t7EEJRVwgZ5m0pNUlc=; b=q5QMQjqduVin9nUVc08ZpzdWl8szV4QlmbAnQO6NUopg2LIS2tPAdV+nVd+NtilxbA iK2icqvSdghlrozin+/8kuaV+Ebd/WP2ygkcNdTVYtjlchGuOKH0JeaOYuyVCDYDzHwu aUxJJjIvG6HUU05G1PTrSOzk1gEAsYZ8w6WJ56vnBgqiroGJ7+hdORahA9BbaF9/oTyY YDbxaUyOhTe1JmpBI3Zb2g7jFtkttswWadLxy93N8Nv3I8RbH2Bdcj5+btEYdG4dl+uZ 80D1kJEBrW+xhxpLwqAk8IOQ5zpWAxLKH2nhCVxAIVOuoTp3wsXs7xGqOY4yWETb3+/M KwWA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=me41Slqk; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [23.128.96.19]) by mx.google.com with ESMTPS id z3-20020a631903000000b003c66b60b375si7665817pgl.712.2022.05.08.18.37.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 May 2022 18:37:14 -0700 (PDT) Received-SPF: softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) client-ip=23.128.96.19; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=me41Slqk; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 4D9C63524C; Sun, 8 May 2022 18:36:52 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348398AbiEFACo (ORCPT + 99 others); Thu, 5 May 2022 20:02:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35218 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1387116AbiEFABr (ORCPT ); Thu, 5 May 2022 20:01:47 -0400 Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 851BD612A4 for ; Thu, 5 May 2022 16:57:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1651795073; x=1683331073; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=TyPidIU9s9JbwJNwvFvgLrTu4E+Y5y97BFEdQg2cUk8=; b=me41SlqkT0DwRfIzvo/ciQAoCLD1qsyy+SULhWMBbDYPBkr6IZBCGILz uIBBkZP4/VYX7Ffh8bgJA8nLbrhIbPTBA2xAc+WtH8pbKY1H7yx4tz8uq ck7ONI9SE6ZKZ7wXCYnavlaJ3ogLfekAiQBLloYruWD/sz6cu3NzM2ReF bwGOb053f/Rbuc44c5xkws0eciOSfLdaYQhqIyc8VViJ9s+gw663F4dPV PlJ1Kd4Jb3u9vsIFkfKHMmRreHCTv3+2LxNqywYCsWgJJHEiT3/oNxi5i jY5rcNx6HdPYnoYWaPxmbP9kVjV2p7ka0JfPewu+Nu7FXmgFQlHdpjPFo w==; X-IronPort-AV: E=McAfee;i="6400,9594,10338"; a="250283639" X-IronPort-AV: E=Sophos;i="5.91,203,1647327600"; d="scan'208";a="250283639" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 May 2022 16:57:50 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.91,203,1647327600"; d="scan'208";a="694914380" Received: from ranerica-svr.sc.intel.com ([172.25.110.23]) by orsmga004.jf.intel.com with ESMTP; 05 May 2022 16:57:50 -0700 From: Ricardo Neri To: Thomas Gleixner , x86@kernel.org Cc: Tony Luck , Andi Kleen , Stephane Eranian , Andrew Morton , Joerg Roedel , Suravee Suthikulpanit , David Woodhouse , Lu Baolu , Nicholas Piggin , "Ravi V. Shankar" , Ricardo Neri , iommu@lists.linux-foundation.org, linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, Ricardo Neri Subject: [PATCH v6 15/29] x86/hpet: Add helper function hpet_set_comparator_periodic() Date: Thu, 5 May 2022 16:59:54 -0700 Message-Id: <20220506000008.30892-16-ricardo.neri-calderon@linux.intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220506000008.30892-1-ricardo.neri-calderon@linux.intel.com> References: <20220506000008.30892-1-ricardo.neri-calderon@linux.intel.com> X-Spam-Status: No, score=-2.5 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RDNS_NONE,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Programming an HPET channel as periodic requires setting the HPET_TN_SETVAL bit in the channel configuration. Plus, the comparator register must be written twice (once for the comparator value and once for the periodic value). Since this programming might be needed in several places (e.g., the HPET clocksource and the HPET-based hardlockup detector), add a helper function for this purpose. A helper function hpet_set_comparator_oneshot() could also be implemented. However, such function would only program the comparator register and the function would be quite small. Hence, it is better to not bloat the code with such an obvious function. Cc: Andi Kleen Cc: Tony Luck Cc: Stephane Eranian Cc: "Ravi V. Shankar" Cc: iommu@lists.linux-foundation.org Cc: linuxppc-dev@lists.ozlabs.org Cc: x86@kernel.org Originally-by: Suravee Suthikulpanit Reviewed-by: Tony Luck Signed-off-by: Ricardo Neri --- When programming the HPET channel in periodic mode, a udelay(1) between the two successive writes to HPET_Tn_CMP was introduced in commit e9e2cdb41241 ("[PATCH] clockevents: i386 drivers"). The commit message does not give any reason for such delay. The hardware specification does not seem to require it. The refactoring in this patch simply carries such delay. --- Changes since v5: * None Changes since v4: * Implement function only for periodic mode. This removed extra logic to to use a non-zero period value as a proxy for periodic mode programming. (Thomas) * Added a comment on the history of the udelay() when programming the channel in periodic mode. (Ashok) Changes since v3: * Added back a missing hpet_writel() for time configuration. Changes since v2: * Introduced this patch. Changes since v1: * N/A --- arch/x86/include/asm/hpet.h | 2 ++ arch/x86/kernel/hpet.c | 49 ++++++++++++++++++++++++++++--------- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/arch/x86/include/asm/hpet.h b/arch/x86/include/asm/hpet.h index be9848f0883f..486e001413c7 100644 --- a/arch/x86/include/asm/hpet.h +++ b/arch/x86/include/asm/hpet.h @@ -74,6 +74,8 @@ extern void hpet_disable(void); extern unsigned int hpet_readl(unsigned int a); extern void hpet_writel(unsigned int d, unsigned int a); extern void force_hpet_resume(void); +extern void hpet_set_comparator_periodic(int channel, unsigned int cmp, + unsigned int period); #ifdef CONFIG_HPET_EMULATE_RTC diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index 47678e7927ff..2c6713b40921 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -294,6 +294,39 @@ static void hpet_enable_legacy_int(void) hpet_legacy_int_enabled = true; } +/** + * hpet_set_comparator_periodic() - Helper function to set periodic channel + * @channel: The HPET channel + * @cmp: The value to be written to the comparator/accumulator + * @period: Number of ticks per period + * + * Helper function for updating comparator, accumulator and period values. + * + * In periodic mode, HPET needs HPET_TN_SETVAL to be set before writing + * to the Tn_CMP to update the accumulator. Then, HPET needs a second + * write (with HPET_TN_SETVAL cleared) to Tn_CMP to set the period. + * The HPET_TN_SETVAL bit is automatically cleared after the first write. + * + * This function takes a 1 microsecond delay. However, this function is supposed + * to be called only once (or when reprogramming the timer) as it deals with a + * periodic timer channel. + * + * See the following documents: + * - Intel IA-PC HPET (High Precision Event Timers) Specification + * - AMD-8111 HyperTransport I/O Hub Data Sheet, Publication # 24674 + */ +void hpet_set_comparator_periodic(int channel, unsigned int cmp, unsigned int period) +{ + unsigned int v = hpet_readl(HPET_Tn_CFG(channel)); + + hpet_writel(v | HPET_TN_SETVAL, HPET_Tn_CFG(channel)); + + hpet_writel(cmp, HPET_Tn_CMP(channel)); + + udelay(1); + hpet_writel(period, HPET_Tn_CMP(channel)); +} + static int hpet_clkevt_set_state_periodic(struct clock_event_device *evt) { unsigned int channel = clockevent_to_channel(evt)->num; @@ -306,19 +339,11 @@ static int hpet_clkevt_set_state_periodic(struct clock_event_device *evt) now = hpet_readl(HPET_COUNTER); cmp = now + (unsigned int)delta; cfg = hpet_readl(HPET_Tn_CFG(channel)); - cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL | - HPET_TN_32BIT; + cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_32BIT; hpet_writel(cfg, HPET_Tn_CFG(channel)); - hpet_writel(cmp, HPET_Tn_CMP(channel)); - udelay(1); - /* - * HPET on AMD 81xx needs a second write (with HPET_TN_SETVAL - * cleared) to T0_CMP to set the period. The HPET_TN_SETVAL - * bit is automatically cleared after the first write. - * (See AMD-8111 HyperTransport I/O Hub Data Sheet, - * Publication # 24674) - */ - hpet_writel((unsigned int)delta, HPET_Tn_CMP(channel)); + + hpet_set_comparator_periodic(channel, cmp, (unsigned int)delta); + hpet_start_counter(); hpet_print_config(); -- 2.17.1