From patchwork Wed Mar 25 20:18:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suman Anna X-Patchwork-Id: 11458585 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AF67B92A for ; Wed, 25 Mar 2020 20:19:48 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8D95E20740 for ; Wed, 25 Mar 2020 20:19:48 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="n2ttB2Vs"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=ti.com header.i=@ti.com header.b="A372TIB2" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8D95E20740 Authentication-Results: mail.kernel.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=pz7+XnqNff1DKZUnksvYbpnf8/4fYKp9IcoDNYiF3fc=; b=n2ttB2VsLjw/6m qFaMWvDMoaX0l2mnDDP4KJlVf128O/NoUua5m8I8YdtaLwxp/QPWNzbr3p2+ndVAMIOMnUMTnR5lk BhUqvoms6hj2KgXDqaAwyoDR1Xhi1GdW56l3ys/YCs0n71VWNKbMAjZWPYRH0Ve8OqtrjI7kByV66 6GzV1LjsP9e5zFSy8gkyug8C+boIWkh16WBQPUsHfQdgalXkHsUT/9I+VWRB/qha7rg8QvblSNERd 5hMQwO9uque5YuoOrUUiQtgmSZxex9LPc399Q1P4Z/vYJtgdXzNyzv4LO347EaebOU85WWBwm4NZt BVpv68Uqw9VxB0M9BcEg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1jHCV5-0000oO-0n; Wed, 25 Mar 2020 20:19:43 +0000 Received: from fllv0015.ext.ti.com ([198.47.19.141]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1jHCUI-0008WT-AB for linux-arm-kernel@lists.infradead.org; Wed, 25 Mar 2020 20:18:57 +0000 Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 02PKInxn053430; Wed, 25 Mar 2020 15:18:49 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1585167529; bh=h6Y7kKyK0HpFuOURmmpiDpmaMkeTeq/m6EYhOH7YPZc=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=A372TIB2G5ZkXvyo7xBTZU1Zk7HYMLTJN1K7MEMmVnYkGCtZpoalqEfv6b4+2L6Ak /KCkZQe3iHabYULf9HIUIn7Vh9oqQZD8Iqk+Iy9lno8fEy+X3qYHI3WsgIA5CfFD74 AaXtmPIFfkkhG2GqOPki9cKxNQPy4R8L16rlP8MY= Received: from DFLE109.ent.ti.com (dfle109.ent.ti.com [10.64.6.30]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 02PKIndn010823 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 25 Mar 2020 15:18:49 -0500 Received: from DFLE101.ent.ti.com (10.64.6.22) by DFLE109.ent.ti.com (10.64.6.30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1847.3; Wed, 25 Mar 2020 15:18:49 -0500 Received: from fllv0039.itg.ti.com (10.64.41.19) by DFLE101.ent.ti.com (10.64.6.22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1847.3 via Frontend Transport; Wed, 25 Mar 2020 15:18:48 -0500 Received: from fllv0103.dal.design.ti.com (fllv0103.dal.design.ti.com [10.247.120.73]) by fllv0039.itg.ti.com (8.15.2/8.15.2) with ESMTP id 02PKInIi064382; Wed, 25 Mar 2020 15:18:49 -0500 Received: from localhost ([10.250.35.147]) by fllv0103.dal.design.ti.com (8.14.7/8.14.7) with ESMTP id 02PKInUQ090870; Wed, 25 Mar 2020 15:18:49 -0500 From: Suman Anna To: Bjorn Andersson , Rob Herring , Mathieu Poirier Subject: [PATCH 3/3] remoteproc/k3-dsp: Add support for L2RAM loading on C66x DSPs Date: Wed, 25 Mar 2020 15:18:39 -0500 Message-ID: <20200325201839.15896-4-s-anna@ti.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20200325201839.15896-1-s-anna@ti.com> References: <20200325201839.15896-1-s-anna@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200325_131854_434484_9DE35977 X-CRM114-Status: GOOD ( 23.35 ) X-Spam-Score: -2.5 (--) X-Spam-Report: SpamAssassin version 3.4.4 on bombadil.infradead.org summary: Content analysis details: (-2.5 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [198.47.19.141 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, Lokesh Vutla , linux-remoteproc@vger.kernel.org, linux-kernel@vger.kernel.org, Suman Anna , linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org The resets for the DSP processors on K3 SoCs are managed through the Power and Sleep Controller (PSC) module. Each DSP typically has two resets - a global module reset for powering on the device, and a local reset that affects only the CPU while allowing access to the other sub-modules within the DSP processor sub-systems. The C66x DSPs have two levels of internal RAMs that can be used to boot from, and the firmware loading into these RAMs require the local reset to be asserted with the device powered on/enabled using the module reset. Enhance the K3 DSP remoteproc driver to add support for loading into the internal RAMs. The local reset is deasserted on SoC power-on-reset, so logic has to be added in probe in remoteproc mode to balance the remoteproc state-machine. Note that the local resets are a no-op on C71x cores, and the hardware does not supporting loading into its internal RAMs. Signed-off-by: Suman Anna --- drivers/remoteproc/ti_k3_dsp_remoteproc.c | 82 +++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c b/drivers/remoteproc/ti_k3_dsp_remoteproc.c index fd0d84f46f90..7b712ef74611 100644 --- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c +++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c @@ -175,6 +175,9 @@ static int k3_dsp_rproc_reset(struct k3_dsp_rproc *kproc) return ret; } + if (kproc->data->uses_lreset) + return ret; + ret = kproc->ti_sci->ops.dev_ops.put_device(kproc->ti_sci, kproc->ti_sci_id); if (ret) { @@ -192,6 +195,9 @@ static int k3_dsp_rproc_release(struct k3_dsp_rproc *kproc) struct device *dev = kproc->dev; int ret; + if (kproc->data->uses_lreset) + goto lreset; + ret = kproc->ti_sci->ops.dev_ops.get_device(kproc->ti_sci, kproc->ti_sci_id); if (ret) { @@ -199,6 +205,7 @@ static int k3_dsp_rproc_release(struct k3_dsp_rproc *kproc) return ret; } +lreset: ret = reset_control_deassert(kproc->reset); if (ret) { dev_err(dev, "local-reset deassert failed, ret = %d\n", ret); @@ -210,6 +217,63 @@ static int k3_dsp_rproc_release(struct k3_dsp_rproc *kproc) return ret; } +/* + * The C66x DSP cores have a local reset that affects only the CPU, and a + * generic module reset that powers on the device and allows the DSP internal + * memories to be accessed while the local reset is asserted. This function is + * used to release the global reset on C66x DSPs to allow loading into the DSP + * internal RAMs. The .prepare() ops is invoked by remoteproc core before any + * firmware loading, and is followed by the .start() ops after loading to + * actually let the C66x DSP cores run. The local reset on C71x cores is a + * no-op and the global reset cannot be released on C71x cores until after + * the firmware images are loaded, so this function does nothing for C71x cores. + */ +static int k3_dsp_rproc_prepare(struct rproc *rproc) +{ + struct k3_dsp_rproc *kproc = rproc->priv; + struct device *dev = kproc->dev; + int ret; + + /* local reset is no-op on C71x processors */ + if (!kproc->data->uses_lreset) + return 0; + + ret = kproc->ti_sci->ops.dev_ops.get_device(kproc->ti_sci, + kproc->ti_sci_id); + if (ret) + dev_err(dev, "module-reset deassert failed, cannot enable internal RAM loading, ret = %d\n", + ret); + + return ret; +} + +/* + * This function implements the .unprepare() ops and performs the complimentary + * operations to that of the .prepare() ops. The function is used to assert the + * global reset on applicable C66x cores. This completes the second portion of + * powering down the C66x DSP cores. The cores themselves are only halted in the + * .stop() callback through the local reset, and the .unprepare() ops is invoked + * by the remoteproc core after the remoteproc is stopped to balance the global + * reset. + */ +static int k3_dsp_rproc_unprepare(struct rproc *rproc) +{ + struct k3_dsp_rproc *kproc = rproc->priv; + struct device *dev = kproc->dev; + int ret; + + /* local reset is no-op on C71x processors */ + if (!kproc->data->uses_lreset) + return 0; + + ret = kproc->ti_sci->ops.dev_ops.put_device(kproc->ti_sci, + kproc->ti_sci_id); + if (ret) + dev_err(dev, "module-reset assert failed, ret = %d\n", ret); + + return ret; +} + /* * Power up the DSP remote processor. * @@ -353,6 +417,8 @@ static void *k3_dsp_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len) } static const struct rproc_ops k3_dsp_rproc_ops = { + .prepare = k3_dsp_rproc_prepare, + .unprepare = k3_dsp_rproc_unprepare, .start = k3_dsp_rproc_start, .stop = k3_dsp_rproc_stop, .kick = k3_dsp_rproc_kick, @@ -644,6 +710,22 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev) goto disable_clk; } + /* + * ensure the DSP local reset is asserted to ensure the DSP doesn't + * execute bogus code in .prepare() when the module reset is released. + */ + if (data->uses_lreset) { + ret = reset_control_status(kproc->reset); + if (ret < 0) { + dev_err(dev, "failed to get reset status, status = %d\n", + ret); + goto release_mem; + } else if (ret == 0) { + dev_warn(dev, "local reset is deasserted for device\n"); + k3_dsp_rproc_reset(kproc); + } + } + ret = rproc_add(rproc); if (ret) { dev_err(dev, "failed to add register device with remoteproc core, status = %d\n",