From patchwork Fri Apr 19 08:32:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jagan Teki X-Patchwork-Id: 245 Return-Path: X-Original-To: linux-amarula@patchwork.amarulasolutions.com Delivered-To: linux-amarula@patchwork.amarulasolutions.com Received: from mail-pg1-f199.google.com (mail-pg1-f199.google.com [209.85.215.199]) by ganimede.amarulasolutions.com (Postfix) with ESMTPS id 226A13F063 for ; Fri, 19 Apr 2019 10:32:19 +0200 (CEST) Received: by mail-pg1-f199.google.com with SMTP id d1sf3007734pgk.21 for ; Fri, 19 Apr 2019 01:32:19 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1555662736; cv=pass; d=google.com; s=arc-20160816; b=FSp9aKKO3DqPEK5j6RQdx5IhQhT+H5GPW60OQ9gLLSp/3ycHJDAR/iymKfZ45XJPiI i0f8K9HDSWGJvrFHHXLK2zHmXKv7fu7Pq35RlTZ/c9cFylXb/09hLACqjOJSoVeFWk7k etuRqF618uSXvxtgKEERwNzT5riLyXC0K1pR+cf2BKwVBBurAV657dZGokufAy+cUt9L +vUYSfNK0TrBL55wwEoK258afNampsU4rfmaybp31lZXnj0vjOL4riiomTO4ilOJlLNI siIPkv6oqRPxiC6kyDfHQMM+vq5Y3aPa1015NH1l+0L9ogoepWKztN3m2Y5qsg8kleiU DRVg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-archive:list-help:list-post:list-id :mailing-list:precedence:mime-version:message-id:date:subject:cc:to :from:dkim-signature; bh=i9K/vicHk/RKIvjL+lOXzbSVSMtnUL6yqBJAoDAGKH8=; b=IDBSvpNSSWl026pwSeOGgLyj81io5774H7RQW+S/J/jnghEFvW1CGIolt2iVeSJJNN IGQt2fpfG0boCaOzEBP/axZMVvh5ejbRZ77+KG3GuljkNVFr1jd+1ogr8anftNg7UojU iPmDeDb4wezw7UkL3jW/sN+YC9i4eu6LMp8yBd4oNMVwAlNJCijAWC3e0OT9DyTvUXCz Eo28f+mZT/t49lDhspXdqe7HA6Q04D3Nb/YnUPVsMQx+/k0+7a8rb3tMeGnhRGFkdVDy PZyumYLwRzoyNLNadsaUPPduKcbLSag3uHP6G65jr/VZLduj5A0aF1msojF4rHq+pZUH 8gvA== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=OKU9Q8Rp; spf=pass (google.com: domain of jagan@amarulasolutions.com designates 209.85.220.65 as permitted sender) smtp.mailfrom=jagan@amarulasolutions.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amarulasolutions.com; s=google; h=from:to:cc:subject:date:message-id:mime-version:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=i9K/vicHk/RKIvjL+lOXzbSVSMtnUL6yqBJAoDAGKH8=; b=NOg/wNH3HhqeCoZaCz+3WX7UJGxOPAsNLFGrzXfDV9rvM4SC28N0xA9HporykhofuS CLeneumr3H3VIX/XtNHh6Em4Eo/eEbCKXhRjCSR5MEER+/Ku71q/iMkcUcUhV7TAxGb9 Ut49GwAf9zHkj2RTI3/DYwXyqnVYhMTvqu73U= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :x-original-sender:x-original-authentication-results:precedence :mailing-list:list-id:x-spam-checked-in-group:list-post:list-help :list-archive:list-unsubscribe; bh=i9K/vicHk/RKIvjL+lOXzbSVSMtnUL6yqBJAoDAGKH8=; b=szFuGw9FwVaLPX55UIqufhzNYsa4UpaNwJuEHpKgNu7d0boqFFJoTdH+9fwgNZONzz VTW+ceP+7fYYn8FKqKpbWBF4rd1G3CHVeQom33bRjoW4En2DzhIvvOim62BNsUUojqPJ nLj1qScc5h2LY2XATWL6fAZHyJR5XOLhwp59P07Yffnvk0CKGfUi+iE3ZZ/FWfqEqYVY /q4Jl2JZHGezDQKNZ+zE6dvxad3s2u/amzbRpWouZasoS6rB+XkZNXIuaiKH6GlXb1rY CfP8mXs35FNtuWeOkbfOQb35TciVkk5pbLXWbp0VNjSHbwBhkDBDLUeIzVbaJvv8pvrR eUpA== X-Gm-Message-State: APjAAAWjdCPnVDza5qwqpa0J+dqlvM/YQLNOJQYNVXCU6XggQxl+Elfy lq+zqsKCfxuX6flXCD8NMsj345ZW X-Google-Smtp-Source: APXvYqz3uF5YWsu/jWDlUBnoECf5jkSdjvXYpw/PGrtAH5p5UaLxw5+3xfMu6I/1UN368PAF1O+QLg== X-Received: by 2002:a17:902:70c6:: with SMTP id l6mr2421755plt.95.1555662734417; Fri, 19 Apr 2019 01:32:14 -0700 (PDT) X-BeenThere: linux-amarula@amarulasolutions.com Received: by 2002:a63:ff54:: with SMTP id s20ls1226437pgk.14.gmail; Fri, 19 Apr 2019 01:32:13 -0700 (PDT) X-Received: by 2002:a65:50c2:: with SMTP id s2mr2731270pgp.112.1555662733319; Fri, 19 Apr 2019 01:32:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1555662733; cv=none; d=google.com; s=arc-20160816; b=00ZeHpQAqHwUtbf8nfaWI0XLIqKJ819aelp4nfLtgOWr+TrTHDBTjnW+RrSKUrrpbx r563rsaU0VK1ZLnptwoxmixTD4GQ+Gpia3kDYHaoMQsgV05ukwHMNdHXnpMaDqmdwcim gu1KsqbNijQXwrP10WWs0F54d5XVIye5wGIBLkLJ0RJBmrruatRB2nOaDmmHH0YtSXo1 x39ZJHs8/NkfEDkKz8bebfS6icEmJoAoQKicso0q7NuBNjfp1DfJ6CA7vhboMFh6nCvw UE8N7sUL1ZkNu3yA7/EAnLB6UlU2Zo+xlseXJ9vb7kjmF8yIkpJcs5QAAyGkrDMWr5jT 3fjA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:dkim-signature; bh=y5EPeRkTA/ZllV+nbuROVj03j7jkDQ/2u9lLQfmqgb8=; b=lKPF+CkjfiQyscCNYUuTzmig36r7l0vjQc8QpwVzUup80LWatOLRSfcP0MoWlEIKbo Exk0DQK+pU9gcN6NdJGQXr6Nb7sNGL/egoeovjkZ9rBETqv+S/lRajSMXdSb1iGlj9cF 27sDTzUj+VWwlKuBSHk4+PTgKWuX+dvvKV018g6Yr87MJjyY+bpm3/utFICqg9alHsnE GNV8ZLrxBgVT0ZrUZULS/YzUG+ndWOCAC4/sFcvezaIR+JZqxuHuJRUOdn3FLa4whn0a JBu1g3BFflA+Z5zJ96rpLAZ7zyZz66uK04Lk7E/cP9+1jlPTf0gvkD/4rfk8W1umw5q/ NFig== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=OKU9Q8Rp; spf=pass (google.com: domain of jagan@amarulasolutions.com designates 209.85.220.65 as permitted sender) smtp.mailfrom=jagan@amarulasolutions.com Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id o9sor5167011plk.32.2019.04.19.01.32.13 for (Google Transport Security); Fri, 19 Apr 2019 01:32:13 -0700 (PDT) Received-SPF: pass (google.com: domain of jagan@amarulasolutions.com designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; X-Received: by 2002:a17:902:da4:: with SMTP id 33mr620182plv.20.1555662732892; Fri, 19 Apr 2019 01:32:12 -0700 (PDT) Received: from localhost.localdomain ([115.97.185.144]) by smtp.gmail.com with ESMTPSA id e7sm7333911pfc.132.2019.04.19.01.32.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 19 Apr 2019 01:32:12 -0700 (PDT) From: Jagan Teki To: u-boot@lists.denx.de Cc: Maxime Ripard , =?utf-8?b?Q2zDqW1lbnQgUMOp?= =?utf-8?q?ron?= , linux-sunxi , linux-amarula@amarulasolutions.com, Jagan Teki , Chris Blake Subject: [PATCH RFC] watchdog: Add Allwinner watchdog driver Date: Fri, 19 Apr 2019 14:02:01 +0530 Message-Id: <20190419083201.20468-1-jagan@amarulasolutions.com> X-Mailer: git-send-email 2.18.0.321.gffc6fa0e3 MIME-Version: 1.0 X-Original-Sender: jagan@amarulasolutions.com X-Original-Authentication-Results: mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=OKU9Q8Rp; spf=pass (google.com: domain of jagan@amarulasolutions.com designates 209.85.220.65 as permitted sender) smtp.mailfrom=jagan@amarulasolutions.com Content-Type: text/plain; charset="UTF-8" Precedence: list Mailing-list: list linux-amarula@amarulasolutions.com; contact linux-amarula+owners@amarulasolutions.com List-ID: X-Spam-Checked-In-Group: linux-amarula@amarulasolutions.com X-Google-Group-Id: 476853432473 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , This patch add watchdog driver for Allwinner SoCs. Initial non-dm driver has send by 'Chris Blake' So I keep his author on the driver itself. Signed-off-by: Chris Blake Signed-off-by: Jagan Teki --- drivers/watchdog/Kconfig | 7 ++ drivers/watchdog/Makefile | 1 + drivers/watchdog/sunxi_wdt.c | 207 +++++++++++++++++++++++++++++++++++ 3 files changed, 215 insertions(+) create mode 100644 drivers/watchdog/sunxi_wdt.c diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 115fc4551f..79fd58048e 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -117,6 +117,13 @@ config WDT_MTK The watchdog timer is stopped when initialized. It performs full SoC reset. +config WDT_SUNXI + bool "Allwinner SoC watchdog support" + depends on WDT + default y if ARCH_SUNXI + help + Select this to enable watchdog timer for Allwinner SoCs. + config XILINX_TB_WATCHDOG bool "Xilinx Axi watchdog timer support" depends on WDT diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index d901240ad1..16003a8fc6 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -27,3 +27,4 @@ obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o obj-$(CONFIG_MPC8xx_WATCHDOG) += mpc8xx_wdt.o obj-$(CONFIG_WDT_MT7621) += mt7621_wdt.o obj-$(CONFIG_WDT_MTK) += mtk_wdt.o +obj-$(CONFIG_WDT_SUNXI) += sunxi_wdt.o diff --git a/drivers/watchdog/sunxi_wdt.c b/drivers/watchdog/sunxi_wdt.c new file mode 100644 index 0000000000..2e7364b7bb --- /dev/null +++ b/drivers/watchdog/sunxi_wdt.c @@ -0,0 +1,207 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Watchdog driver for Allwinner SoCs + * + * Copyright (C) 2019 Chris Blake + * Copyright (C) 2019 Jagan Teki + * + * Based on the linux/drivers/watchdog/sunxi_wdt.c + */ + +#include +#include +#include +#include + +#define WDT_TIMEOUT_MASK 0x0F +#define WDT_CTRL_RELOAD ((1 << 0) | (0x0a57 << 1)) +#define WDT_MODE_EN BIT(0) + +/* + * This structure stores the register offsets for different variants + * of Allwinner's watchdog hardware. + */ +struct sunxi_wdt_reg { + u8 wdt_ctrl; + u8 wdt_cfg; + u8 wdt_mode; + u8 wdt_timeout_shift; + u8 wdt_reset_mask; + u8 wdt_reset_val; +}; + +struct sunxi_wdt_priv { + void __iomem *base; + const struct sunxi_wdt_reg *wdt_regs; +}; + +/* + * wdt_timeout_map maps the watchdog timer interval value in seconds to + * the value of the register WDT_MODE at bits .wdt_timeout_shift ~ +3 + * + * [timeout seconds] = register value + * + */ +static const int wdt_timeout_map[] = { + [1] = 0x1, /* 1s */ + [2] = 0x2, /* 2s */ + [3] = 0x3, /* 3s */ + [4] = 0x4, /* 4s */ + [5] = 0x5, /* 5s */ + [6] = 0x6, /* 6s */ + [8] = 0x7, /* 8s */ + [10] = 0x8, /* 10s */ + [12] = 0x9, /* 12s */ + [14] = 0xA, /* 14s */ + [16] = 0xB, /* 16s */ +}; + +static int sunxi_wdt_reset(struct udevice *dev) +{ + struct sunxi_wdt_priv *priv = dev_get_priv(dev); + + writel(WDT_CTRL_RELOAD, priv->base + priv->wdt_regs->wdt_ctrl); + + return 0; +} + +static int sunxi_wdt_stop(struct udevice *dev) +{ + struct sunxi_wdt_priv *priv = dev_get_priv(dev); + + writel(0, priv->base + priv->wdt_regs->wdt_mode); + + return 0; +} + +static int sunxi_wdt_expire_now(struct udevice *dev, ulong flags) +{ + struct sunxi_wdt_priv *priv = dev_get_priv(dev); + u32 val; + + /* Set system reset function */ + val = readl(priv->base + priv->wdt_regs->wdt_cfg); + val &= ~(priv->wdt_regs->wdt_reset_mask); + val |= priv->wdt_regs->wdt_reset_val; + writel(val, priv->base + priv->wdt_regs->wdt_cfg); + + /* Set lowest timeout and enable watchdog */ + val = readl(priv->base + priv->wdt_regs->wdt_mode); + val &= (WDT_TIMEOUT_MASK << priv->wdt_regs->wdt_timeout_shift); + val |= WDT_MODE_EN; + writel(val, priv->base + priv->wdt_regs->wdt_mode); + + /* + * Restart the watchdog. The default (and lowest) interval + * value for the watchdog is 0.5s. + */ + writel(WDT_CTRL_RELOAD, priv->base + priv->wdt_regs->wdt_ctrl); + + while (1) { + mdelay(5); + val = readl(priv->base + priv->wdt_regs->wdt_mode); + val |= WDT_MODE_EN; + writel(val, priv->base + priv->wdt_regs->wdt_mode); + } + + return 0; +} + +static void sunxi_wdt_set_timeout(struct udevice *dev, unsigned int timeout) +{ + struct sunxi_wdt_priv *priv = dev_get_priv(dev); + u32 reg; + + if (wdt_timeout_map[timeout] == 0) + timeout++; + + reg = readl(priv->base + priv->wdt_regs->wdt_mode); + reg &= (WDT_TIMEOUT_MASK << priv->wdt_regs->wdt_timeout_shift); + reg |= wdt_timeout_map[timeout] << priv->wdt_regs->wdt_timeout_shift; + writel(reg, priv->base + priv->wdt_regs->wdt_mode); + + sunxi_wdt_reset(dev); +} + +static int sunxi_wdt_start(struct udevice *dev, u64 timeout, ulong flags) +{ + struct sunxi_wdt_priv *priv = dev_get_priv(dev); + u32 reg; + + sunxi_wdt_set_timeout(dev, timeout); + + /* Set system reset function */ + reg = readl(priv->base + priv->wdt_regs->wdt_cfg); + reg &= ~(priv->wdt_regs->wdt_reset_mask); + reg |= priv->wdt_regs->wdt_reset_val; + writel(reg, priv->base + priv->wdt_regs->wdt_cfg); + + /* Enable watchdog */ + reg = readl(priv->base + priv->wdt_regs->wdt_mode); + reg |= WDT_MODE_EN; + writel(reg, priv->base + priv->wdt_regs->wdt_mode); + + return 0; +} + +static int sunxi_wdt_probe(struct udevice *dev) +{ + struct sunxi_wdt_priv *priv = dev_get_priv(dev); + + priv->base = dev_read_addr_ptr(dev); + if (!priv->base) + return -ENOENT; + + priv->wdt_regs = (const struct sunxi_wdt_reg *)dev_get_driver_data(dev); + if (!priv->wdt_regs) + return -EINVAL; + + return sunxi_wdt_stop(dev); +} + +static const struct wdt_ops sunxi_wdt_ops = { + .start = sunxi_wdt_start, + .reset = sunxi_wdt_reset, + .stop = sunxi_wdt_stop, + .expire_now = sunxi_wdt_expire_now, +}; + +static const struct sunxi_wdt_reg sun4i_wdt_reg = { + .wdt_ctrl = 0x00, + .wdt_cfg = 0x04, + .wdt_mode = 0x04, + .wdt_timeout_shift = 3, + .wdt_reset_mask = 0x02, + .wdt_reset_val = 0x02, +}; + +static const struct sunxi_wdt_reg sun6i_wdt_reg = { + .wdt_ctrl = 0x10, + .wdt_cfg = 0x14, + .wdt_mode = 0x18, + .wdt_timeout_shift = 4, + .wdt_reset_mask = 0x03, + .wdt_reset_val = 0x01, +}; + +static const struct udevice_id sunxi_wdt_ids[] = { + { + .compatible = "allwinner,sun4i-a10-wdt", + .data = (ulong)&sun4i_wdt_reg + }, + { + .compatible = "allwinner,sun6i-a31-wdt", + .data = (ulong)&sun6i_wdt_reg + }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(sunxi_wdt) = { + .name = "sunxi_wdt", + .id = UCLASS_WDT, + .of_match = sunxi_wdt_ids, + .priv_auto_alloc_size = sizeof(struct sunxi_wdt_priv), + .probe = sunxi_wdt_probe, + .ops = &sunxi_wdt_ops, + .flags = DM_FLAG_PRE_RELOC, +};