From: Jon Hunter <jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
To: "Stephen Warren"
<swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>,
"Thierry Reding"
<thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
"Alexandre Courbot"
<gnurou-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
"Philipp Zabel" <p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>,
"Peter De Schrijver"
<pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>,
"Prashant Gaikwad"
<pgaikwad-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>,
"Terje Bergström"
<tbergstrom-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>,
"Hans de Goede"
<hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>,
"Tejun Heo" <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: Vince Hsu <vinceh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>,
"Rafael J. Wysocki" <rjw-LthD3rsA81gm4RdzfppkhA@public.gmane.org>,
Kevin Hilman <khilman-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
Ulf Hansson <ulf.hansson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>,
linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
linux-pm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Jon Hunter <jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Subject: [PATCH V3 02/19] memory: tegra: Add MC flush support
Date: Mon, 13 Jul 2015 13:39:40 +0100 [thread overview]
Message-ID: <1436791197-32358-3-git-send-email-jonathanh@nvidia.com> (raw)
In-Reply-To: <1436791197-32358-1-git-send-email-jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
The Tegra memory controller implements a flush feature to flush pending
accesses and prevent further accesses from occurring. This feature is
used when powering down IP blocks to ensure the IP block is in a good
state. The flushes are organised by software groups and IP blocks are
assigned in hardware to the different software groups. Add helper
functions for requesting a handle to an MC flush for a given
software group and enabling/disabling the MC flush itself.
This is based upon a change by Vince Hsu <vinceh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>.
Signed-off-by: Jon Hunter <jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
drivers/memory/tegra/mc.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++
drivers/memory/tegra/mc.h | 2 +
include/soc/tegra/mc.h | 34 ++++++++++++++
3 files changed, 146 insertions(+)
diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
index c71ede67e6c8..fb8da3d4caf4 100644
--- a/drivers/memory/tegra/mc.c
+++ b/drivers/memory/tegra/mc.c
@@ -7,6 +7,7 @@
*/
#include <linux/clk.h>
+#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
@@ -71,6 +72,107 @@ static const struct of_device_id tegra_mc_of_match[] = {
};
MODULE_DEVICE_TABLE(of, tegra_mc_of_match);
+const struct tegra_mc_flush *tegra_mc_flush_get(struct tegra_mc *mc,
+ unsigned int swgroup)
+{
+ const struct tegra_mc_flush *flush = NULL;
+ int i;
+
+ mutex_lock(&mc->lock);
+
+ for (i = 0; i < mc->soc->num_flushes; i++) {
+ if (mc->soc->flushes[i].swgroup == swgroup) {
+ if (mc->flush_reserved[i] == false) {
+ mc->flush_reserved[i] = true;
+ flush = &mc->soc->flushes[i];
+ }
+ break;
+ }
+ }
+
+ mutex_unlock(&mc->lock);
+
+ return flush;
+}
+EXPORT_SYMBOL(tegra_mc_flush_get);
+
+static bool tegra_mc_flush_done(struct tegra_mc *mc,
+ const struct tegra_mc_flush *flush)
+{
+ unsigned long timeout = jiffies + msecs_to_jiffies(100);
+ int i;
+ u32 val;
+
+ while (time_before(jiffies, timeout)) {
+ val = mc_readl(mc, flush->status);
+
+ /*
+ * If the flush bit is still set it
+ * is not done and so wait then retry.
+ */
+ if (val & BIT(flush->bit))
+ goto retry;
+
+ /*
+ * Depending on the tegra SoC, it may be necessary to read
+ * the status register multiple times to ensure the value
+ * read is correct. Some tegra devices have a HW issue where
+ * reading the status register shortly after writing the
+ * control register (on the order of 5 cycles) may return
+ * an incorrect value.
+ */
+ for (i = 0; i < mc->soc->metastable_flush_reads; i++) {
+ if (mc_readl(mc, flush->status) != val)
+ goto retry;
+ }
+
+ /*
+ * The flush is complete and so return.
+ */
+ return 0;
+retry:
+ udelay(10);
+ }
+
+ return -ETIMEDOUT;
+}
+
+int tegra_mc_flush(struct tegra_mc *mc, const struct tegra_mc_flush *flush,
+ bool enable)
+{
+ int ret = 0;
+ u32 val;
+
+ if (!mc || !flush)
+ return -EINVAL;
+
+ mutex_lock(&mc->lock);
+
+ val = mc_readl(mc, flush->ctrl);
+
+ if (enable)
+ val |= BIT(flush->bit);
+ else
+ val &= ~BIT(flush->bit);
+
+ mc_writel(mc, val, flush->ctrl);
+ mc_readl(mc, flush->ctrl);
+
+ /*
+ * If activating the flush, poll the
+ * status register until the flush is done.
+ */
+ if (enable)
+ ret = tegra_mc_flush_done(mc, flush);
+
+ mutex_unlock(&mc->lock);
+
+ dev_dbg(mc->dev, "%s bit %d\n", __func__, flush->bit);
+
+ return ret;
+}
+EXPORT_SYMBOL(tegra_mc_flush);
+
static int tegra_mc_setup_latency_allowance(struct tegra_mc *mc)
{
unsigned long long tick;
@@ -359,6 +461,12 @@ static int tegra_mc_probe(struct platform_device *pdev)
mc->soc = match->data;
mc->dev = &pdev->dev;
+ mc->flush_reserved = devm_kcalloc(&pdev->dev, mc->soc->num_flushes,
+ sizeof(mc->flush_reserved),
+ GFP_KERNEL);
+ if (!mc->flush_reserved)
+ return -ENOMEM;
+
/* length of MC tick in nanoseconds */
mc->tick = 30;
@@ -410,6 +518,8 @@ static int tegra_mc_probe(struct platform_device *pdev)
return err;
}
+ mutex_init(&mc->lock);
+
value = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE |
MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM;
diff --git a/drivers/memory/tegra/mc.h b/drivers/memory/tegra/mc.h
index b7361b0a6696..0f59d49b735b 100644
--- a/drivers/memory/tegra/mc.h
+++ b/drivers/memory/tegra/mc.h
@@ -14,6 +14,8 @@
#include <soc/tegra/mc.h>
+#define MC_FLUSH_METASTABLE_READS 5
+
static inline u32 mc_readl(struct tegra_mc *mc, unsigned long offset)
{
return readl(mc->regs + offset);
diff --git a/include/soc/tegra/mc.h b/include/soc/tegra/mc.h
index 1ab2813273cd..b634c6df79eb 100644
--- a/include/soc/tegra/mc.h
+++ b/include/soc/tegra/mc.h
@@ -45,6 +45,13 @@ struct tegra_mc_client {
struct tegra_mc_la la;
};
+struct tegra_mc_flush {
+ unsigned int swgroup;
+ unsigned int ctrl;
+ unsigned int status;
+ unsigned int bit;
+};
+
struct tegra_smmu_swgroup {
const char *name;
unsigned int swgroup;
@@ -96,6 +103,10 @@ struct tegra_mc_soc {
const struct tegra_mc_client *clients;
unsigned int num_clients;
+ const struct tegra_mc_flush *flushes;
+ unsigned int num_flushes;
+ unsigned int metastable_flush_reads;
+
const unsigned long *emem_regs;
unsigned int num_emem_regs;
@@ -117,9 +128,32 @@ struct tegra_mc {
struct tegra_mc_timing *timings;
unsigned int num_timings;
+
+ bool *flush_reserved;
+
+ struct mutex lock;
};
void tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate);
unsigned int tegra_mc_get_emem_device_count(struct tegra_mc *mc);
+#ifdef CONFIG_TEGRA_MC
+const struct tegra_mc_flush *tegra_mc_flush_get(struct tegra_mc *mc,
+ unsigned int swgroup);
+int tegra_mc_flush(struct tegra_mc *mc, const struct tegra_mc_flush *s,
+ bool enable);
+#else
+const struct tegra_mc_flush *tegra_mc_flush_get(struct tegra_mc *mc,
+ unsigned int swgroup)
+{
+ return NULL;
+}
+
+int tegra_mc_flush(struct tegra_mc *mc, const struct tegra_mc_flush *s,
+ bool enable)
+{
+ return -ENOTSUPP;
+}
+#endif
+
#endif /* __SOC_TEGRA_MC_H__ */
--
2.1.4
next prev parent reply other threads:[~2015-07-13 12:39 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-13 12:39 [PATCH V3 00/19] Add generic PM domain support for Tegra SoCs Jon Hunter
[not found] ` <1436791197-32358-1-git-send-email-jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2015-07-13 12:39 ` [PATCH V3 01/19] reset: add of_reset_control_get_by_index() Jon Hunter
[not found] ` <1436791197-32358-2-git-send-email-jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2015-07-17 12:08 ` Philipp Zabel
2015-07-13 12:39 ` Jon Hunter [this message]
2015-07-17 9:57 ` [PATCH V3 02/19] memory: tegra: Add MC flush support Thierry Reding
2015-07-17 10:20 ` Peter De Schrijver
[not found] ` <20150717102049.GQ6287-Rysk9IDjsxmJz7etNGeUX8VPkgjIgRvpAL8bYrjMMd8@public.gmane.org>
2015-07-17 11:31 ` Thierry Reding
2015-07-20 8:46 ` Jon Hunter
2015-07-20 9:17 ` Thierry Reding
2015-07-20 9:59 ` Peter De Schrijver
[not found] ` <20150720095941.GZ6287-Rysk9IDjsxmJz7etNGeUX8VPkgjIgRvpAL8bYrjMMd8@public.gmane.org>
2015-07-20 13:14 ` Thierry Reding
2015-07-21 10:57 ` Peter De Schrijver
2015-07-13 12:39 ` [PATCH V3 03/19] memory: tegra: add flush operation for Tegra30 memory clients Jon Hunter
[not found] ` <1436791197-32358-4-git-send-email-jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2015-07-17 10:03 ` Thierry Reding
2015-07-21 8:54 ` Jon Hunter
2015-07-13 12:39 ` [PATCH V3 04/19] memory: tegra: add flush operation for Tegra114 " Jon Hunter
[not found] ` <1436791197-32358-5-git-send-email-jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2015-07-17 10:05 ` Thierry Reding
2015-07-13 12:39 ` [PATCH V3 05/19] memory: tegra: add flush operation for Tegra124 " Jon Hunter
2015-07-17 10:05 ` Thierry Reding
2015-07-13 12:39 ` [PATCH V3 07/19] soc: tegra: pmc: Wait for powergate state to change Jon Hunter
[not found] ` <1436791197-32358-8-git-send-email-jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2015-07-17 10:17 ` Thierry Reding
2015-07-21 9:34 ` Jon Hunter
2015-07-13 12:39 ` [PATCH V3 08/19] soc: tegra: pmc: Clean-up PMC helper functions Jon Hunter
2015-07-17 10:25 ` Thierry Reding
2015-07-21 9:38 ` Jon Hunter
2015-07-13 12:39 ` [PATCH V3 14/19] Documentation: DT: bindings: Add power domain info for NVIDIA PMC Jon Hunter
[not found] ` <1436791197-32358-15-git-send-email-jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2015-07-17 9:38 ` Thierry Reding
2015-07-13 12:39 ` [PATCH V3 15/19] soc: tegra: pmc: Add generic PM domain support Jon Hunter
[not found] ` <1436791197-32358-16-git-send-email-jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2015-07-17 11:29 ` Thierry Reding
2015-07-13 12:39 ` [PATCH V3 16/19] soc: tegra: pmc: Remove the deprecated powergate APIs Jon Hunter
2015-07-13 12:39 ` [PATCH V3 18/19] ARM: tegra: add GPU power supply to Jetson TK1 DT Jon Hunter
[not found] ` <1436791197-32358-19-git-send-email-jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2015-07-17 9:28 ` Thierry Reding
2015-07-13 12:39 ` [PATCH V3 19/19] ARM: tegra: select PM_GENERIC_DOMAINS Jon Hunter
2015-07-13 13:50 ` Peter De Schrijver
[not found] ` <20150713135047.GR6287-Rysk9IDjsxmJz7etNGeUX8VPkgjIgRvpAL8bYrjMMd8@public.gmane.org>
2015-07-13 14:03 ` Jon Hunter
2015-07-14 11:59 ` Jon Hunter
[not found] ` <55A4F9B6.1070904-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2015-07-15 8:17 ` Peter De Schrijver
2015-07-13 12:39 ` [PATCH V3 06/19] clk: tegra: remove TEGRA_PLL_USE_LOCK for PLLD/PLLD2 Jon Hunter
[not found] ` <1436791197-32358-7-git-send-email-jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2015-07-13 13:41 ` Peter De Schrijver
2015-07-13 14:02 ` Jon Hunter
[not found] ` <55A3C50E.7060706-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2015-07-14 11:59 ` Jon Hunter
[not found] ` <55A4F985.7010503-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2015-07-15 8:16 ` Peter De Schrijver
2015-07-13 12:39 ` [PATCH V3 09/19] soc: tegra: pmc: Prepare for migrating to generic PM domains Jon Hunter
2015-07-13 12:39 ` [PATCH V3 10/19] drm/tegra: dc: Prepare for " Jon Hunter
[not found] ` <1436791197-32358-11-git-send-email-jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2015-07-17 10:41 ` Thierry Reding
2015-07-28 8:30 ` Jon Hunter
[not found] ` <55B73D8C.103-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2015-07-28 11:20 ` Thierry Reding
[not found] ` <20150728112030.GA10949-AwZRO8vwLAwmlAP/+Wk3EA@public.gmane.org>
2015-07-28 15:30 ` Jon Hunter
2015-07-13 12:39 ` [PATCH V3 11/19] PCI: tegra: Add support " Jon Hunter
2015-07-17 10:45 ` Thierry Reding
2015-07-28 8:35 ` Jon Hunter
2015-07-13 12:39 ` [PATCH V3 12/19] ata: ahci_tegra: " Jon Hunter
2015-07-13 12:39 ` [PATCH V3 13/19] drm/tegra: gr3d: " Jon Hunter
2015-07-13 12:39 ` [PATCH V3 17/19] ARM: tegra: Add PM domain device nodes to Tegra124 DT Jon Hunter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1436791197-32358-3-git-send-email-jonathanh@nvidia.com \
--to=jonathanh-ddmlm1+adcrqt0dzr+alfa@public.gmane.org \
--cc=devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=gnurou-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
--cc=hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
--cc=khilman-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
--cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
--cc=linux-pm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org \
--cc=pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org \
--cc=pgaikwad-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org \
--cc=rjw-LthD3rsA81gm4RdzfppkhA@public.gmane.org \
--cc=swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org \
--cc=tbergstrom-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org \
--cc=thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
--cc=tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
--cc=ulf.hansson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
--cc=vinceh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).