From mboxrd@z Thu Jan 1 00:00:00 1970 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 847B5C433F5 for ; Sun, 14 Nov 2021 11:20:01 +0000 (UTC) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 541A561073 for ; Sun, 14 Nov 2021 11:20:00 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 541A561073 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=openbsd.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=lists.denx.de Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id B59058344C; Sun, 14 Nov 2021 12:19:57 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=openbsd.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id 6A03383473; Sun, 14 Nov 2021 12:19:55 +0100 (CET) Received: from lb3-smtp-cloud8.xs4all.net (lb3-smtp-cloud8.xs4all.net [194.109.24.29]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id B5C7A8344C for ; Sun, 14 Nov 2021 12:19:51 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=openbsd.org Authentication-Results: phobos.denx.de; spf=fail smtp.mailfrom=kettenis@openbsd.org Received: from cust-df1d398c ([IPv6:fc0c:c1f5:9ac0:c45f:1583:5c5b:91fa:2436]) by smtp-cloud8.xs4all.net with ESMTPA id mDY4mB4VX8wPvmDY7mjMev; Sun, 14 Nov 2021 12:19:51 +0100 From: Mark Kettenis To: u-boot@lists.denx.de Cc: sjg@chromium.org, sven@svenpeter.dev, Mark Kettenis Subject: [PATCH 1/3] watchdog: Add a driver for the Apple watchdog Date: Sun, 14 Nov 2021 12:19:40 +0100 Message-Id: <20211114111942.96151-2-kettenis@openbsd.org> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211114111942.96151-1-kettenis@openbsd.org> References: <20211114111942.96151-1-kettenis@openbsd.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CMAE-Envelope: MS4xfKqcmaGzlsldV4KRj2wFySf+GcVW0+Dq0lXe4HhpJ92wEWHbV/E57TVZNbpsePD/4OVBvxwgIzubk74mAP5uz+CElV4tB/b6Mcx7exIymKde8W3edysI B6TTOoDxloT5MOsYFj/+LSIWMCTF9/+oP8ElKbcz6ss7hQ5W/KiO3S9HXCFZ0s7IlIqJgq5kQsrJesiJJ1Dg81nMFp7NosJF9FApBqH7w2k/O4e+BFIpX30V IDkgHUdI2v5hq1vlJ2eiOiVzqHBf6rfVeQDkXW5uctCg+Vad2bKNqL3r/BeLhYch X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.35 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.2 at phobos.denx.de X-Virus-Status: Clean This driver supports the watchdog timer found on Apple's M1 SoC. On systems that use these SoC, the watchdog timer is the primary way to reboot the system. Signed-off-by: Mark Kettenis --- MAINTAINERS | 1 + drivers/watchdog/Kconfig | 9 +++ drivers/watchdog/Makefile | 1 + drivers/watchdog/apple_wdt.c | 111 +++++++++++++++++++++++++++++++++++ 4 files changed, 122 insertions(+) create mode 100644 drivers/watchdog/apple_wdt.c diff --git a/MAINTAINERS b/MAINTAINERS index 00ff572d4d..fe56ffed60 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -115,6 +115,7 @@ F: arch/arm/include/asm/arch-m1/ F: arch/arm/mach-apple/ F: configs/apple_m1_defconfig F: drivers/iommu/apple_dart.c +F: drivers/watchdog/apple_wdt.c F: include/configs/apple.h ARM diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 1177f17fd8..cabac29053 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -81,6 +81,15 @@ config WDT What exactly happens when the timer expires is up to a particular device/driver. +config WDT_APPLE + bool "Apple watchdog timer support" + depends on WDT + default y if ARCH_APPLE + help + Enable support for the watchdog timer on Apple SoCs. + The watchdog will perform a full SoC reset resulting in a + reboot of the entire system. + config WDT_ARMADA_37XX bool "Marvell Armada 37xx watchdog timer support" depends on WDT && ARMADA_3700 diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index fa7ce583ce..6d2b3822c0 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_DESIGNWARE_WATCHDOG) += designware_wdt.o obj-$(CONFIG_ULP_WATCHDOG) += ulp_wdog.o obj-$(CONFIG_$(SPL_TPL_)WDT) += wdt-uclass.o obj-$(CONFIG_WDT_SANDBOX) += sandbox_wdt.o +obj-$(CONFIG_WDT_APPLE) += apple_wdt.o obj-$(CONFIG_WDT_ARMADA_37XX) += armada-37xx-wdt.o obj-$(CONFIG_WDT_ASPEED) += ast_wdt.o obj-$(CONFIG_WDT_AST2600) += ast2600_wdt.o diff --git a/drivers/watchdog/apple_wdt.c b/drivers/watchdog/apple_wdt.c new file mode 100644 index 0000000000..08eefcdaf9 --- /dev/null +++ b/drivers/watchdog/apple_wdt.c @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021 Mark Kettenis + */ + +#include +#include +#include +#include +#include + +#define APPLE_WDT_CUR_TIME 0x10 +#define APPLE_WDT_BARK_TIME 0x14 +#define APPLE_WDT_CTRL 0x1c +#define APPLE_WDT_CTRL_RESET_EN BIT(2) + +struct apple_wdt_priv { + void *base; + ulong clk_rate; +}; + +static int apple_wdt_reset(struct udevice *dev) +{ + struct apple_wdt_priv *priv = dev_get_priv(dev); + + writel(0, priv->base + APPLE_WDT_CUR_TIME); + + return 0; +} + +static int apple_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags) +{ + struct apple_wdt_priv *priv = dev_get_priv(dev); + u64 timeout; + + timeout = (timeout_ms * priv->clk_rate) / 1000; + if (timeout > U32_MAX) + return -EINVAL; + + writel(0, priv->base + APPLE_WDT_CUR_TIME); + writel(timeout, priv->base + APPLE_WDT_BARK_TIME); + writel(APPLE_WDT_CTRL_RESET_EN, priv->base + APPLE_WDT_CTRL); + + return 0; +} + +static int apple_wdt_stop(struct udevice *dev) +{ + struct apple_wdt_priv *priv = dev_get_priv(dev); + + writel(0, priv->base + APPLE_WDT_CTRL); + + return 0; +} + +static int apple_wdt_expire_now(struct udevice *dev, ulong flags) +{ + int ret; + + ret = apple_wdt_start(dev, 0, flags); + if (ret) + return ret; + + mdelay(150); + + return 0; +} + +static const struct wdt_ops apple_wdt_ops = { + .reset = apple_wdt_reset, + .start = apple_wdt_start, + .stop = apple_wdt_stop, + .expire_now = apple_wdt_expire_now, +}; + +static const struct udevice_id apple_wdt_ids[] = { + { .compatible = "apple,wdt" }, + { /* sentinel */ } +}; + +static int apple_wdt_probe(struct udevice *dev) +{ + struct apple_wdt_priv *priv = dev_get_priv(dev); + struct clk clk; + int ret; + + priv->base = dev_read_addr_ptr(dev); + if (!priv->base) + return -EINVAL; + + ret = clk_get_by_index(dev, 0, &clk); + if (ret) + return ret; + + ret = clk_enable(&clk); + if (ret) + return ret; + + priv->clk_rate = clk_get_rate(&clk); + + return 0; +} + +U_BOOT_DRIVER(apple_wdt) = { + .name = "apple_wdt", + .id = UCLASS_WDT, + .of_match = apple_wdt_ids, + .priv_auto = sizeof(struct apple_wdt_priv), + .probe = apple_wdt_probe, + .ops = &apple_wdt_ops, +}; -- 2.33.1