From patchwork Wed Feb 1 08:53:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Svyatoslav Ryhel X-Patchwork-Id: 1735395 X-Patchwork-Delegate: twarren@nvidia.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=jvWa4Tau; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4P6G234RBMz23gY for ; Wed, 1 Feb 2023 19:54:35 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id ED2A585C41; Wed, 1 Feb 2023 09:54:06 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="jvWa4Tau"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 004D685C37; Wed, 1 Feb 2023 09:53:44 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-wr1-x434.google.com (mail-wr1-x434.google.com [IPv6:2a00:1450:4864:20::434]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 74AEA85C43 for ; Wed, 1 Feb 2023 09:53:32 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=clamor95@gmail.com Received: by mail-wr1-x434.google.com with SMTP id a3so9865371wrt.6 for ; Wed, 01 Feb 2023 00:53:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=eBROmD5cHsHJVdtinFdgegYJLkh5CuEKLJ4gge6F/4I=; b=jvWa4TauLO0bQSZTFdMauj+MOWVnSpddnycbUykpMA0XC9orCb3kD1N9RBIYiZqunP TJfX9iSYPwGMw5F2H6B74dUM/LMd/gB10ARy5YO9YkuZ6fx8zifl3SCmQt0hHRMIVYFw MFF7y+CEQp/sh8l9AUc5Vo8XJqhj4QdggeGtzj+HrxYo3khpR65EH/u3FKu3o+KbXu/c EpHzifrHbhp5txOwQs+DgS2ThPWDi5HqOOKL14VmphDJyDjyBTlw1cWvkYjliD8WDP6x Y/ejIO0AlQi3n4OL1yTjBdf6/Fpn1wteo5Y+THbaBHgWrE3bsbv2EIHqA7nUV2aAxEc3 6XFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=eBROmD5cHsHJVdtinFdgegYJLkh5CuEKLJ4gge6F/4I=; b=qZCqTd9fHTRSW6wg00ltlCOWry+15ZZN1JCyxzuVAa6lBl9ywR6y+yEUXntiMSnGCn sGQUQyDk+3RNCZk3vbF5GjjWdjx+DfmLXe0zv4Hhtc6YLluPzjAT9ie21Ri2jh3eScaO RkhuR6xaMDmKiH4WvyD4pqyv5Hv2JKrZIKe2LHPLx6dPoUeuujOP6uP8Ez03nTEYY22N 5nqXAPMNWeZkLsZRCN0VQykOeZ0/y30j4lkUrpyrEFhq+DumL+5WSxNmrLeKOBieyxn9 eSWeC6WQRyXhnpUeJwt4H+I5amSh+vTtxkczjtD55pnPaumGmc2b8l76crM5F5WanZZZ 57Jw== X-Gm-Message-State: AO0yUKVkNrCstDgMPWBtnC5rgyY30OHpNCWmfaTqaB5TzIftlOHr23+3 KMF7S2DqAu4H98TBkZigfLM= X-Google-Smtp-Source: AK7set8NJf0XnJ5mjSODydcycxCZz017ekfD48sVv307mdh95CTWJgbvbNejuRme2GzgmfCSXt7Lnw== X-Received: by 2002:a5d:584f:0:b0:2be:1ea0:f794 with SMTP id i15-20020a5d584f000000b002be1ea0f794mr6385884wrf.52.1675241611598; Wed, 01 Feb 2023 00:53:31 -0800 (PST) Received: from xeon.. ([188.163.112.54]) by smtp.gmail.com with ESMTPSA id r6-20020adff106000000b002bfe05bf6dcsm11704871wro.88.2023.02.01.00.53.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 01 Feb 2023 00:53:31 -0800 (PST) From: Svyatoslav Ryhel To: Tom Warren , Thierry Reding , Marek Vasut , Svyatoslav Ryhel , Maxim Schwalm , Dmitry Osipenko , =?utf-8?q?Jonas_Schw=C3=B6bel?= , Agneli , Heinrich Schuchardt , Michal Simek , Stefan Roese , Eugen Hristev , Michael Walle , Simon Glass , Jim Liu , William Zhang , Rick Chen , Stefan Herbrechtsmeier , Andre Przywara , Jaehoon Chung Cc: u-boot@lists.denx.de Subject: [PATCH v8 2/3] drivers: timer: add driver for ARMv7 based Tegra devices and T210 Date: Wed, 1 Feb 2023 10:53:02 +0200 Message-Id: <20230201085303.6653-3-clamor95@gmail.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20230201085303.6653-1-clamor95@gmail.com> References: <20230201085303.6653-1-clamor95@gmail.com> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.6 at phobos.denx.de X-Virus-Status: Clean Add timer support for T20/T30/T114/T124 and T210 based devices. Driver is based on DM, has device tree support and can be used on SPL and early boot stage. Arm64 Tegra (apart T210) according to comment in tegra-common.h use architected timer. Tested-by: Andreas Westman Dorcsak # ASUS TF600T T30 Tested-by: Jonas Schwöbel # Surface RT T30 Tested-by: Robert Eckelmann # ASUS TF101 T20 Tested-by: Agneli # Toshiba AC100 T20 Tested-by: Svyatoslav Ryhel # LG P895 T30 Co-developed-by: Jonas Schwöbel Signed-off-by: Jonas Schwöbel Signed-off-by: Svyatoslav Ryhel Reviewed-by: Simon Glass --- drivers/timer/Kconfig | 8 +++ drivers/timer/Makefile | 1 + drivers/timer/tegra-timer.c | 130 ++++++++++++++++++++++++++++++++++++ 3 files changed, 139 insertions(+) create mode 100644 drivers/timer/tegra-timer.c diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig index 6d6665005c..f32bd16227 100644 --- a/drivers/timer/Kconfig +++ b/drivers/timer/Kconfig @@ -252,6 +252,14 @@ config STM32_TIMER Select this to enable support for the timer found on STM32 devices. +config TEGRA_TIMER + bool "Tegra timer support" + depends on TIMER + select TIMER_EARLY + help + Select this to enable support for the timer found on + Tegra devices. + config X86_TSC_TIMER bool "x86 Time-Stamp Counter (TSC) timer support" depends on TIMER && X86 diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile index 6470fd5426..3c92113fc6 100644 --- a/drivers/timer/Makefile +++ b/drivers/timer/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_SP804_TIMER) += sp804_timer.o obj-$(CONFIG_$(SPL_)SIFIVE_CLINT) += sifive_clint_timer.o obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o obj-$(CONFIG_STM32_TIMER) += stm32_timer.o +obj-$(CONFIG_TEGRA_TIMER) += tegra-timer.o obj-$(CONFIG_X86_TSC_TIMER) += tsc_timer.o obj-$(CONFIG_MTK_TIMER) += mtk_timer.o obj-$(CONFIG_MCHP_PIT64B_TIMER) += mchp-pit64b-timer.o diff --git a/drivers/timer/tegra-timer.c b/drivers/timer/tegra-timer.c new file mode 100644 index 0000000000..a867c649c3 --- /dev/null +++ b/drivers/timer/tegra-timer.c @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 Svyatoslav Ryhel + */ + +#include +#include +#include +#include + +#include +#include +#include + +#define TEGRA_OSC_CLK_ENB_L_SET (NV_PA_CLK_RST_BASE + 0x320) +#define TEGRA_OSC_SET_CLK_ENB_TMR BIT(5) + +#define TEGRA_TIMER_USEC_CNTR (NV_PA_TMRUS_BASE + 0) +#define TEGRA_TIMER_USEC_CFG (NV_PA_TMRUS_BASE + 4) + +#define TEGRA_TIMER_RATE 1000000 /* 1 MHz */ + +/* + * On pre-DM stage timer should be left configured by + * previous bootloader for correct 1MHz clock. + * In the case of reset default value is set to 1/13 of + * CLK_M which should be decent enough to safely + * get to DM stage. + */ +u64 notrace timer_early_get_count(void) +{ + /* At this stage raw timer is used */ + return readl(TEGRA_TIMER_USEC_CNTR); +} + +unsigned long notrace timer_early_get_rate(void) +{ + return TEGRA_TIMER_RATE; +} + +ulong timer_get_boot_us(void) +{ + return timer_early_get_count(); +} + +/* + * At moment of calling get_count, timer driver is already + * probed and is configured to have precise 1MHz clock. + * Tegra timer has a step of 1 microsecond which removes + * need of using adjusments involving uc_priv->clock_rate. + */ +static notrace u64 tegra_timer_get_count(struct udevice *dev) +{ + u32 val = timer_early_get_count(); + return timer_conv_64(val); +} + +static int tegra_timer_probe(struct udevice *dev) +{ + struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); + u32 usec_config, value; + + /* Timer rate has to be set unconditionally */ + uc_priv->clock_rate = TEGRA_TIMER_RATE; + + /* + * Configure microsecond timers to have 1MHz clock + * Config register is 0xqqww, where qq is "dividend", ww is "divisor" + * Uses n+1 scheme + */ + switch (clock_get_rate(CLOCK_ID_CLK_M)) { + case 12000000: + usec_config = 0x000b; /* (11+1)/(0+1) */ + break; + case 12800000: + usec_config = 0x043f; /* (63+1)/(4+1) */ + break; + case 13000000: + usec_config = 0x000c; /* (12+1)/(0+1) */ + break; + case 16800000: + usec_config = 0x0453; /* (83+1)/(4+1) */ + break; + case 19200000: + usec_config = 0x045f; /* (95+1)/(4+1) */ + break; + case 26000000: + usec_config = 0x0019; /* (25+1)/(0+1) */ + break; + case 38400000: + usec_config = 0x04bf; /* (191+1)/(4+1) */ + break; + case 48000000: + usec_config = 0x002f; /* (47+1)/(0+1) */ + break; + default: + return -EINVAL; + } + + /* Enable clock to timer hardware */ + value = readl_relaxed(TEGRA_OSC_CLK_ENB_L_SET); + writel_relaxed(value | TEGRA_OSC_SET_CLK_ENB_TMR, + TEGRA_OSC_CLK_ENB_L_SET); + + writel_relaxed(usec_config, TEGRA_TIMER_USEC_CFG); + + return 0; +} + +static const struct timer_ops tegra_timer_ops = { + .get_count = tegra_timer_get_count, +}; + +static const struct udevice_id tegra_timer_ids[] = { + { .compatible = "nvidia,tegra20-timer" }, + { .compatible = "nvidia,tegra30-timer" }, + { .compatible = "nvidia,tegra114-timer" }, + { .compatible = "nvidia,tegra124-timer" }, + { .compatible = "nvidia,tegra210-timer" }, + { } +}; + +U_BOOT_DRIVER(tegra_timer) = { + .name = "tegra_timer", + .id = UCLASS_TIMER, + .of_match = tegra_timer_ids, + .probe = tegra_timer_probe, + .ops = &tegra_timer_ops, + .flags = DM_FLAG_PRE_RELOC, +};