From patchwork Tue Jun 18 15:52:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Hancock X-Patchwork-Id: 1118412 X-Patchwork-Delegate: sbabic@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=sedsystems.ca Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 45T78S3BQjz9s7h for ; Wed, 19 Jun 2019 11:46:16 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 18244C2204C; Wed, 19 Jun 2019 01:42:32 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 1B2EBC22064; Wed, 19 Jun 2019 01:40:53 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id AFF1BC21F38; Tue, 18 Jun 2019 15:52:40 +0000 (UTC) Received: from sed198n136.sedsystems.ca (sed198n136.SEDSystems.ca [198.169.180.136]) by lists.denx.de (Postfix) with ESMTPS id 23E56C21F37 for ; Tue, 18 Jun 2019 15:52:40 +0000 (UTC) Received: from barney.sedsystems.ca (barney [198.169.180.121]) by sed198n136.sedsystems.ca with ESMTP id x5IFqcQM031052 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Tue, 18 Jun 2019 09:52:38 -0600 (CST) Received: from SED.RFC1918.192.168.sedsystems.ca (eng1n65.eng.sedsystems.ca [172.21.1.65]) by barney.sedsystems.ca (8.14.7/8.14.4) with ESMTP id x5IFqc0M021440 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Tue, 18 Jun 2019 09:52:38 -0600 From: Robert Hancock To: u-boot@lists.denx.de Date: Tue, 18 Jun 2019 09:52:35 -0600 Message-Id: <1560873155-21570-1-git-send-email-hancock@sedsystems.ca> X-Mailer: git-send-email 1.8.3.1 X-Scanned-By: MIMEDefang 2.64 on 198.169.180.136 X-Mailman-Approved-At: Wed, 19 Jun 2019 01:40:48 +0000 Subject: [U-Boot] [PATCH] driver: watchdog: Add new iMX/LSCH2 WDT driver X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" This is a new watchdog timer driver for iMX and LSCH2 using the WDT framework and driver model. This allows ensuring that U-Boot uses the same watchdog timer instance and same settings (ex: internal or external reset) specified in the device tree. This driver can be used in preference to the old imx_watchdog driver for boards which have been converted to use the driver model. Signed-off-by: Robert Hancock --- drivers/watchdog/Kconfig | 14 ++++-- drivers/watchdog/Makefile | 3 ++ drivers/watchdog/imx_wdt.c | 112 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 126 insertions(+), 3 deletions(-) create mode 100644 drivers/watchdog/imx_wdt.c diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index dbafb74..0e8c8e5 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -27,11 +27,11 @@ config BCM2835_WDT hardware, with a max timeout of ~15secs. config IMX_WATCHDOG - bool "Enable Watchdog Timer support for IMX and LSCH2 of NXP" + bool "Enable legacy Watchdog Timer support for IMX and LSCH2 of NXP" select HW_WATCHDOG help - Select this to enable the IMX and LSCH2 of Layerscape watchdog - driver. + Select this to enable the IMX and LSCH2 of Layerscape legacy watchdog + driver (not using driver model). config OMAP_WATCHDOG bool "TI OMAP watchdog driver" @@ -109,6 +109,14 @@ config WDT_CDNS Select this to enable Cadence watchdog timer, which can be found on some Xilinx Microzed Platform. +config WDT_IMX + bool "iMX/LSCH2 watchdog timer support" + depends on WDT && (ARCH_MX25 || ARCH_MX31 || ARCH_MX35 || ARCH_MX5 || ARCH_MX6 || ARCH_MX7 || ARCH_VF610) + imply WATCHDOG + help + Select this to enable the IMX and LSCH2 of Layerscape watchdog + driver using driver model. + config WDT_MPC8xx bool "MPC8xx watchdog timer support" depends on WDT && MPC8xx diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index e3f4fdb..49dd457 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -5,11 +5,13 @@ obj-$(CONFIG_WDT_AT91) += at91sam9_wdt.o obj-$(CONFIG_FTWDT010_WATCHDOG) += ftwdt010_wdt.o +ifndef CONFIG_WDT_IMX ifneq (,$(filter $(SOC), mx25 mx31 mx35 mx5 mx6 mx7 vf610)) obj-y += imx_watchdog.o else obj-$(CONFIG_IMX_WATCHDOG) += imx_watchdog.o endif +endif obj-$(CONFIG_S5P) += s5p_wdt.o obj-$(CONFIG_XILINX_TB_WATCHDOG) += xilinx_tb_wdt.o obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o @@ -24,6 +26,7 @@ obj-$(CONFIG_WDT_BCM6345) += bcm6345_wdt.o obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o obj-$(CONFIG_WDT_ORION) += orion_wdt.o obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o +obj-$(CONFIG_WDT_IMX) += imx_wdt.o obj-$(CONFIG_WDT_MPC8xx) += mpc8xx_wdt.o obj-$(CONFIG_WDT_MT7621) += mt7621_wdt.o obj-$(CONFIG_WDT_MTK) += mtk_wdt.o diff --git a/drivers/watchdog/imx_wdt.c b/drivers/watchdog/imx_wdt.c new file mode 100644 index 0000000..1b4a5e6 --- /dev/null +++ b/drivers/watchdog/imx_wdt.c @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * imx_wdt.c - WDT driver for Freescale/NXP i.MX on-chip watchdog + * Copyright (c) 2019 SED Systems, a division of Calian Ltd. + * + * Based on Linux 4.19 drivers/watchdog/imx2_wdt.c which is: + * Copyright (C) 2010 Wolfram Sang, Pengutronix e.K. + * Copyright (C) 2014 Freescale Semiconductor, Inc. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +struct imx_wdt_priv { + struct watchdog_regs *regs; + bool ext_reset; +}; + +static int imx_wdt_start(struct udevice *dev, u64 timeout, ulong flags) +{ + struct imx_wdt_priv *priv = dev_get_priv(dev); + u16 timeout_reg = (timeout / 500) - 1; + u16 wcr = WCR_WDZST | WCR_WDBG | WCR_WDE | WCR_SRS | + WCR_WDA | SET_WCR_WT(timeout_reg); + + if (priv->ext_reset) + wcr |= WCR_WDT; + + debug("%s timeout %llu, wcr %04hX\n", __func__, timeout, wcr); + + writew(wcr, &priv->regs->wcr); + + return 0; +} + +static int imx_wdt_reset(struct udevice *dev) +{ + struct imx_wdt_priv *priv = dev_get_priv(dev); + + writew(0x5555, &priv->regs->wsr); + writew(0xaaaa, &priv->regs->wsr); + return 0; +} + +static int imx_wdt_expire_now(struct udevice *dev, ulong flags) +{ + struct imx_wdt_priv *priv = dev_get_priv(dev); + u16 wcr = WCR_WDE; + + if (priv->ext_reset) + wcr |= WCR_SRS; /* do not assert internal reset */ + else + wcr |= WCR_WDA; /* do not assert external reset */ + + debug("%s wcr %04hX\n", __func__, wcr); + + /* Write 3 times to ensure it works, due to IMX6Q errata ERR004346 */ + writew(wcr, &priv->regs->wcr); + writew(wcr, &priv->regs->wcr); + writew(wcr, &priv->regs->wcr); + + return 0; +} + +static int imx_wdt_ofdata_to_platdata(struct udevice *dev) +{ + struct imx_wdt_priv *priv = dev_get_priv(dev); + + priv->regs = devfdt_get_addr_ptr(dev); + if (IS_ERR(priv->regs)) + return PTR_ERR(priv->regs); + + priv->ext_reset = dev_read_bool(dev, "fsl,ext-reset-output"); + + debug("%s: ext_reset %d\n", __func__, (int)priv->ext_reset); + return 0; +} + +static const struct wdt_ops imx_wdt_ops = { + .start = imx_wdt_start, + .reset = imx_wdt_reset, + .expire_now = imx_wdt_expire_now, +}; + +static const struct udevice_id imx_wdt_ids[] = { + { .compatible = "fsl,imx21-wdt", }, + {} +}; + +static int imx_wdt_probe(struct udevice *dev) +{ + debug("%s() wdt%u\n", __func__, dev->seq); + + return 0; +} + +U_BOOT_DRIVER(imx_wdt) = { + .name = "imx_wdt", + .id = UCLASS_WDT, + .of_match = imx_wdt_ids, + .probe = imx_wdt_probe, + .priv_auto_alloc_size = sizeof(struct imx_wdt_priv), + .ofdata_to_platdata = imx_wdt_ofdata_to_platdata, + .ops = &imx_wdt_ops, + .flags = DM_FLAG_PRE_RELOC, +};