From patchwork Thu Nov 22 11:39:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roger Quadros X-Patchwork-Id: 151754 Delivered-To: patch@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp628043ljp; Thu, 22 Nov 2018 03:39:42 -0800 (PST) X-Google-Smtp-Source: AFSGD/VhigWY754jRPlxHyB769cJQ0Jf5BR1jhsBhcdIOozdlAIz9aXDENRwTKoKUtaRYrn4ZeE8 X-Received: by 2002:a63:1904:: with SMTP id z4mr9449855pgl.135.1542886782783; Thu, 22 Nov 2018 03:39:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1542886782; cv=none; d=google.com; s=arc-20160816; b=JxafqCelCi3RrmvQTD5E+wM8ToiEUJ++8FPwQnOAk3SrW9VlakUEATL6XKLYnoU7+l MvzfEFARBYDKveEEFHqXFEwGpMAnr5xMAqpW7j5bjYY/4KMwAgvuWMlNAHq7gdKDYr8P u+uGh3Gj1huSuLuqIZ+J3+jC4J3H53vUWwPOyZ1XKcanF03pBrJGFT3g23l9NVbQRTJe Ue7UsNqaJxzPJcizGIfkpWOh8s8xsZfkyPsNDdKfM4+75QV2WqKhWzkqOORdxVwpk440 HJBOCK4jU+Uwx8PXpU7tbVeDFgNqXS2EUdc5iMF+tYAIO9QiNHCYyXyWIOpnbbWB2m4G zr9g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=wid2SPnwYAS8OrDuPNeFfDxOtgHDrKisgze3uUQ/47A=; b=eoO1hbubHYWItOTGNV24stACgwvU0xceT+LoLU7YY/NriJNNKsGmqj+Fw082rymHSN uZxJDVr/ddG5ZqwVTdEOTIxi4T7p7/sMi2RGus+NLE6cQdvmJ+3n1XZ8JiPus97crycV MH4UaMvjxauiCL1LwerahALZPPqRbs2umKS+LyzfW0njzcqAmf213QKsaN2W10m6gxnh z3hrBmcgEcTM9sm9f+4DB+d7m02VkwEisvZ6JX9gdRT85RVbrX2q9KQ0cwM5myK01n+/ lWetwvPyMy1364uaSdYJ5/p5gSeLN7BvTjscxmuYKp5VsNZVG8H6hYkF7iUo+WkGbR6E g3EA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=oP5igHjv; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v5si36542340ply.74.2018.11.22.03.39.42; Thu, 22 Nov 2018 03:39:42 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=oP5igHjv; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2436487AbeKVWSl (ORCPT + 32 others); Thu, 22 Nov 2018 17:18:41 -0500 Received: from lelv0143.ext.ti.com ([198.47.23.248]:41972 "EHLO lelv0143.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2405572AbeKVWSk (ORCPT ); Thu, 22 Nov 2018 17:18:40 -0500 Received: from fllv0035.itg.ti.com ([10.64.41.0]) by lelv0143.ext.ti.com (8.15.2/8.15.2) with ESMTP id wAMBdb9F022534; Thu, 22 Nov 2018 05:39:37 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1542886777; bh=wid2SPnwYAS8OrDuPNeFfDxOtgHDrKisgze3uUQ/47A=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=oP5igHjvdpz6N+rdhOf4a0gDZNlRzmFMOXngvZGz7sFwQpeIDPRjp5dEEsnhr9W2r sl0if1ofabNQnS+O0lSLhxxm98dNKWUWyrZ2gcbTPKH55q9EqzLhBwdFiRq9Ssqnvs gJvzHFJv6MYNv4y3N1ROb+17Lu9VZdiu78tm+bqI= Received: from DFLE105.ent.ti.com (dfle105.ent.ti.com [10.64.6.26]) by fllv0035.itg.ti.com (8.15.2/8.15.2) with ESMTPS id wAMBdb4q106946 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 22 Nov 2018 05:39:37 -0600 Received: from DFLE111.ent.ti.com (10.64.6.32) by DFLE105.ent.ti.com (10.64.6.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1591.10; Thu, 22 Nov 2018 05:39:34 -0600 Received: from dflp32.itg.ti.com (10.64.6.15) by DFLE111.ent.ti.com (10.64.6.32) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1591.10 via Frontend Transport; Thu, 22 Nov 2018 05:39:34 -0600 Received: from dlelxv97.itg.ti.com (dlelxv97.itg.ti.com [172.17.2.193]) by dflp32.itg.ti.com (8.14.3/8.13.8) with ESMTP id wAMBdYq9017630; Thu, 22 Nov 2018 05:39:34 -0600 Received: from localhost.localdomain (vboxa0400828d.dhcp.ti.com [172.22.239.63]) by dlelxv97.itg.ti.com (8.14.3/8.13.8) with ESMTP id wAMBdDf3013203; Thu, 22 Nov 2018 05:39:30 -0600 From: Roger Quadros To: CC: , , , , , , , , , , , , , , , , Subject: [PATCH 04/17] soc: ti: pruss: Fix system suspend/MStandby config issues Date: Thu, 22 Nov 2018 13:39:00 +0200 Message-ID: <1542886753-17625-5-git-send-email-rogerq@ti.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1542886753-17625-1-git-send-email-rogerq@ti.com> References: <1542886753-17625-1-git-send-email-rogerq@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Suman Anna The PRU-ICSS subsystem has a separate PRUSS_CFG module that contains various configuration registers. This includes a control bit STANDBY_INIT in PRUSS_CFG register to initiate a Standby sequence (when set) and trigger a MStandby request to the SoC's PRCM module. This same bit is also used to enable the OCP master ports (when cleared). The system suspend/resume functionality on AM33xx/AM437x/AM57xx SoCs requires all initiators to assert their MStandby signal properly inorder to successfully enter suspend, and resume on a wakeup event. Certain firmwares can enable the OCP master ports through the STANDBY_INIT programming on the firmware side in order to access peripherals or memories external to the PRUSS. This causes a hang in the resume sequence on AM33xx/AM437x boards and requires a board reset to come out of the hang. This patch adds the preliminary System PM callbacks in the PRUSS SoC bus driver, and fixes this system resume hang by setting the STANDBY_INIT in the PM system suspend callback and resetting it back in the PM system resume callback, if so configured. The clearing of the STANDBY_INIT during resume requires an acknowledgment from PRCM and is done through the monitoring of the PRUSS_SYSCFG.SUB_MWAIT bit. NOTE: 1. This patch only adds the PM callbacks with code to fix the System Suspend/Resume hang issue on AM33xx/AM437x SoCs, but does not implement the full context save and restore required for the PRUSS drivers to work across system suspend/resume when the power domain is switched off (L4PER domain is switched OFF on AM335x/AM437x during system suspend/resume, so PRUSS modules do lose context). 2. The PRUSS driver functionality on AM57xx SoCs is not affected that much because the PER power domain to which the PRUSS IPs belong is not switched OFF during suspend/resume. Signed-off-by: Suman Anna Signed-off-by: Roger Quadros --- drivers/soc/ti/pruss_soc_bus.c | 85 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki diff --git a/drivers/soc/ti/pruss_soc_bus.c b/drivers/soc/ti/pruss_soc_bus.c index 16b4802..d4da55d2 100644 --- a/drivers/soc/ti/pruss_soc_bus.c +++ b/drivers/soc/ti/pruss_soc_bus.c @@ -7,6 +7,7 @@ * Keerthy */ +#include #include #include #include @@ -16,13 +17,18 @@ #include +#define SYSCFG_STANDBY_INIT BIT(4) +#define SYSCFG_SUB_MWAIT_READY BIT(5) + /** * struct pruss_soc_bus - PRUSS SoC bus structure * @syscfg: kernel mapped address for SYSCFG register + * @in_standby: flag for storing standby status * @has_reset: cached variable for storing global module reset flag */ struct pruss_soc_bus { void __iomem *syscfg; + bool in_standby; bool has_reset; }; @@ -34,6 +40,81 @@ struct pruss_soc_bus_match_data { bool has_reset; }; +static inline void pruss_soc_bus_rmw(void __iomem *reg, u32 mask, u32 set) +{ + u32 val; + + val = readl_relaxed(reg); + val &= ~mask; + val |= (set & mask); + writel_relaxed(val, reg); +} + +/* + * This function programs the PRUSS_SYSCFG.STANDBY_INIT bit to achieve dual + * functionalities - one is to deassert the MStandby signal to the device + * PRCM, and the other is to enable OCP master ports to allow accesses + * outside of the PRU-ICSS. The function has to wait for the PRCM to + * acknowledge through the monitoring of the PRUSS_SYSCFG.SUB_MWAIT bit. + */ +static +int __maybe_unused pruss_soc_bus_enable_ocp_master_ports(struct device *dev) +{ + struct pruss_soc_bus *psoc_bus = dev_get_drvdata(dev); + u32 syscfg_val, i; + bool ready = false; + + pruss_soc_bus_rmw(psoc_bus->syscfg, SYSCFG_STANDBY_INIT, 0); + + /* wait till we are ready for transactions - delay is arbitrary */ + for (i = 0; i < 10; i++) { + syscfg_val = readl_relaxed(psoc_bus->syscfg); + ready = !(syscfg_val & SYSCFG_SUB_MWAIT_READY); + if (ready) + break; + udelay(5); + } + + if (!ready) { + dev_err(dev, "timeout waiting for SUB_MWAIT_READY\n"); + return -ETIMEDOUT; + } + + return 0; +} + +static int __maybe_unused pruss_soc_bus_suspend(struct device *dev) +{ + struct pruss_soc_bus *psoc_bus = dev_get_drvdata(dev); + u32 syscfg_val; + + syscfg_val = readl_relaxed(psoc_bus->syscfg); + psoc_bus->in_standby = syscfg_val & SYSCFG_STANDBY_INIT; + + /* initiate MStandby, undo the MStandby config in probe */ + if (!psoc_bus->in_standby) { + pruss_soc_bus_rmw(psoc_bus->syscfg, SYSCFG_STANDBY_INIT, + SYSCFG_STANDBY_INIT); + } + + return 0; +} + +static int __maybe_unused pruss_soc_bus_resume(struct device *dev) +{ + struct pruss_soc_bus *psoc_bus = dev_get_drvdata(dev); + int ret = 0; + + /* re-enable OCP master ports/disable MStandby */ + if (!psoc_bus->in_standby) { + ret = pruss_soc_bus_enable_ocp_master_ports(dev); + if (ret) + dev_err(dev, "%s failed\n", __func__); + } + + return ret; +} + static int pruss_soc_bus_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -126,9 +207,13 @@ static const struct of_device_id pruss_soc_bus_of_match[] = { }; MODULE_DEVICE_TABLE(of, pruss_soc_bus_of_match); +static SIMPLE_DEV_PM_OPS(pruss_soc_bus_pm_ops, + pruss_soc_bus_suspend, pruss_soc_bus_resume); + static struct platform_driver pruss_soc_bus_driver = { .driver = { .name = "pruss-soc-bus", + .pm = &pruss_soc_bus_pm_ops, .of_match_table = pruss_soc_bus_of_match, }, .probe = pruss_soc_bus_probe,