From patchwork Fri Feb 28 18:07:41 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Khoronzhuk X-Patchwork-Id: 3743771 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 420AE9F35F for ; Fri, 28 Feb 2014 18:11:03 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 3FAD6202DD for ; Fri, 28 Feb 2014 18:11:02 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 1EEB9202AE for ; Fri, 28 Feb 2014 18:11:01 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WJRtD-0004GB-Ij; Fri, 28 Feb 2014 18:10:27 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1WJRt0-0000Dw-7l; Fri, 28 Feb 2014 18:10:14 +0000 Received: from arroyo.ext.ti.com ([192.94.94.40]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WJRsv-0000BY-QI for linux-arm-kernel@lists.infradead.org; Fri, 28 Feb 2014 18:10:11 +0000 Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by arroyo.ext.ti.com (8.13.7/8.13.7) with ESMTP id s1SI9Agx004587; Fri, 28 Feb 2014 12:09:10 -0600 Received: from DLEE71.ent.ti.com (dlee71.ent.ti.com [157.170.170.114]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id s1SI9Avc020433; Fri, 28 Feb 2014 12:09:10 -0600 Received: from dflp32.itg.ti.com (10.64.6.15) by DLEE71.ent.ti.com (157.170.170.114) with Microsoft SMTP Server id 14.3.174.1; Fri, 28 Feb 2014 12:09:10 -0600 Received: from khorivan.synapse.com (incasgf5a_e1_2.itg.ti.com [10.167.216.36]) by dflp32.itg.ti.com (8.14.3/8.13.8) with ESMTP id s1SI8t4o003787; Fri, 28 Feb 2014 12:09:04 -0600 From: Ivan Khoronzhuk To: Subject: [PATCH 1/5] Power: reset: keystone-reset: introduce keystone reset driver Date: Fri, 28 Feb 2014 20:07:41 +0200 Message-ID: <1393610865-23630-2-git-send-email-ivan.khoronzhuk@ti.com> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1393610865-23630-1-git-send-email-ivan.khoronzhuk@ti.com> References: <1393610865-23630-1-git-send-email-ivan.khoronzhuk@ti.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140228_131010_033085_E4A0456B X-CRM114-Status: GOOD ( 20.08 ) X-Spam-Score: -3.8 (---) Cc: fkan@apm.com, grygorii.strashko@ti.com, linux-doc@vger.kernel.org, devicetree@vger.kernel.org, w-kwok2@ti.com, catalin.marinas@arm.com, anton@enomsg.org, sboyd@codeaurora.org, linux-kernel@vger.kernel.org, Rob Herring , Dmitry Eremin-Solenikov , ldewangan@nvidia.com, lho@apm.com, abhimany@codeaurora.org, olof@lixom.net, Ivan Khoronzhuk , ksankaran@apm.com, David Woodhouse , linux-arm-kernel@lists.infradead.org, Grant Likely X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-1.1 required=5.0 tests=BAYES_00,KHOP_BIG_TO_CC, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=no version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The keystone SoC can be rebooted in several ways. By external reset pin, by soft and by watchdogs. To allow keystone SoC reset if watchdog is triggered we have to enable it in reset mux configuration register regarding of watchdog configuration. Also we need to set soft/hard reset we are going to use. So add keystone reset driver to handle all this stuff. Signed-off-by: Ivan Khoronzhuk --- CC: Dmitry Eremin-Solenikov CC: David Woodhouse CC: Grant Likely CC: Rob Herring drivers/power/reset/Kconfig | 7 ++ drivers/power/reset/Makefile | 1 + drivers/power/reset/keystone-reset.c | 171 +++++++++++++++++++++++++++++++++++ 3 files changed, 179 insertions(+) create mode 100644 drivers/power/reset/keystone-reset.c diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig index 6d452a7..9082a72 100644 --- a/drivers/power/reset/Kconfig +++ b/drivers/power/reset/Kconfig @@ -57,3 +57,10 @@ config POWER_RESET_XGENE depends on POWER_RESET help Reboot support for the APM SoC X-Gene Eval boards. + +config POWER_RESET_KEYSTONE + bool "Keystone reset driver" + depends on ARCH_KEYSTONE + help + Reboot support for the KEYSTONE SoCs. + diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile index a5b4a77..802a420 100644 --- a/drivers/power/reset/Makefile +++ b/drivers/power/reset/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o obj-$(CONFIG_POWER_RESET_VEXPRESS) += vexpress-poweroff.o obj-$(CONFIG_POWER_RESET_XGENE) += xgene-reboot.o +obj-$(CONFIG_POWER_RESET_KEYSTONE) += keystone-reset.o diff --git a/drivers/power/reset/keystone-reset.c b/drivers/power/reset/keystone-reset.c new file mode 100644 index 0000000..73f6e7a --- /dev/null +++ b/drivers/power/reset/keystone-reset.c @@ -0,0 +1,171 @@ +/* + * TI keystone reboot driver + * + * Copyright (C) 2014 Texas Instruments Incorporated. http://www.ti.com/ + * + * Author: Ivan Khoronzhuk + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#define RSCTRL_KEY_MASK 0xffff0000 +#define RSCTRL_KEY 0x5a69 +#define RSCTRL_RESET BIT(16) + +#define RSCFG_RSTYPE_SOFT 0x300f +#define RSCFG_RSTYPE_HARD 0x0 + +#define RSTYPE_RG 0x0 +#define RSCTRL_RG 0x4 +#define RSCFG_RG 0x8 +#define RSISO_RG 0xc + +#define RSMUX_OMODE_MASK 0xe +#define RSMUX_OMODE_RESET_SOC 0xa +#define RSMUX_OMODE_RESET_OFF 0x0 +#define RSMUX_LOCK_MASK 0x1 +#define RSMUX_LOCK_SET 0x1 + +#define WDT_MUX_NUMBER 0x4 + +static void __iomem *rspll_base; + +/** + * rsctrl_enable_rspll_write - enable access to RSCTRL, RSCFG + * To be able to access to RSCTRL, RSCFG registers + * we has to write a key before + */ +static void rsctrl_enable_rspll_write(void) +{ + void __iomem *rstctrl_rg; + u32 val; + + rstctrl_rg = rspll_base + RSCTRL_RG; + val = readl(rstctrl_rg); + val &= RSCTRL_KEY_MASK; + val |= RSCTRL_KEY; + writel(val, rstctrl_rg); +} + +static void rsctrl_restart(enum reboot_mode mode, const char *cmd) +{ + u32 val; + void __iomem *rstctrl; + + /* enable write access to RSTCTRL */ + rsctrl_enable_rspll_write(); + + /* reset the SOC */ + rstctrl = rspll_base + RSCTRL_RG; + val = readl(rstctrl); + val &= ~RSCTRL_RESET; + writel(val, rstctrl); +} + +static struct of_device_id rsctrl_of_match[] = { + {.compatible = "ti,keystone-reset", }, + {}, +}; + +static int rsctrl_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + void __iomem *rsmux_base; + void __iomem *rg; + struct resource *res; + u32 val; + int ret; + int i; + + if (!np) + return -ENODEV; + + i = of_property_match_string(np, "reg-names", "pllregs"); + res = platform_get_resource(pdev, IORESOURCE_MEM, i); + rspll_base = devm_ioremap_resource(dev, res); + if (IS_ERR(rspll_base)) + return PTR_ERR(rspll_base); + + i = of_property_match_string(np, "reg-names", "muxregs"); + res = platform_get_resource(pdev, IORESOURCE_MEM, i); + rsmux_base = devm_ioremap_resource(dev, res); + if (IS_ERR(rsmux_base)) + return PTR_ERR(rsmux_base); + + /* set soft/hard reset */ + val = of_property_read_bool(np, "ti,soft-reset"); + val = val ? RSCFG_RSTYPE_SOFT : RSCFG_RSTYPE_HARD; + + rsctrl_enable_rspll_write(); + writel(val, rspll_base + RSCFG_RG); + + arm_pm_restart = rsctrl_restart; + + /* disable reset isolation for all module clocks */ + writel(0, rspll_base + RSISO_RG); + + /* enable reset for watchdogs from list */ + for (i = 0; i < WDT_MUX_NUMBER; i++) { + ret = of_property_read_u32_index(np, "ti,wdt_list", i, &val); + if (ret == -EOVERFLOW && !i) { + dev_err(dev, "ti,wdt_list property has to contain at" + "least one entry\n"); + return -EINVAL; + } else if (ret) { + break; + } + + if (val >= WDT_MUX_NUMBER) { + dev_err(dev, "ti,wdt_list property can contain" + "only numbers < 4\n"); + return -EINVAL; + } + + rg = rsmux_base + val*4; + + val = readl_relaxed(rg); + val &= ~RSMUX_OMODE_MASK; + val |= RSMUX_OMODE_RESET_SOC | RSMUX_LOCK_SET; + writel(val, rg); + } + + /* disable reset for watchdogs from not list */ + for (i = 0; i < WDT_MUX_NUMBER; i++) { + rg = rsmux_base + i*4; + + val = readl_relaxed(rg); + if (!(val & RSMUX_LOCK_MASK)) { + val &= ~RSMUX_OMODE_MASK; + val |= RSMUX_OMODE_RESET_OFF | RSMUX_LOCK_SET; + writel(val, rg); + } + } + + devm_iounmap(dev, rsmux_base); + return 0; +} + +static struct platform_driver rsctrl_driver = { + .probe = rsctrl_probe, + .driver = { + .owner = THIS_MODULE, + .name = KBUILD_MODNAME, + .of_match_table = rsctrl_of_match, + }, +}; +module_platform_driver(rsctrl_driver); + +MODULE_AUTHOR("Ivan Khoronzhuk "); +MODULE_DESCRIPTION("Texas Instruments keystone reset driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" KBUILD_MODNAME);