* [PATCH v2 02/11] coresight: etm4x: Fix input validation for sysfs.
From: Mike Leach @ 2019-08-29 21:33 UTC (permalink / raw)
To: mike.leach, mathieu.poirier, linux-arm-kernel, coresight,
linux-doc
Cc: gregkh, corbet, suzuki.poulose
In-Reply-To: <20190829213321.4092-1-mike.leach@linaro.org>
A number of issues are fixed relating to sysfs input validation:-
1) bb_ctrl_store() - incorrect compare of bit select field to absolute
value. Reworked per ETMv4 specification.
2) seq_event_store() - incorrect mask value - register has two
event values.
3) cyc_threshold_store() - must mask with max before checking min
otherwise wrapped values can set illegal value below min.
4) res_ctrl_store() - update to mask off all res0 bits.
Reviewed-by: Leo Yan <leo.yan@linaro.org>
Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Mike Leach <mike.leach@linaro.org>
---
.../coresight/coresight-etm4x-sysfs.c | 21 ++++++++++++-------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
index b6984be0c515..cc8156318018 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
@@ -652,10 +652,13 @@ static ssize_t cyc_threshold_store(struct device *dev,
if (kstrtoul(buf, 16, &val))
return -EINVAL;
+
+ /* mask off max threshold before checking min value */
+ val &= ETM_CYC_THRESHOLD_MASK;
if (val < drvdata->ccitmin)
return -EINVAL;
- config->ccctlr = val & ETM_CYC_THRESHOLD_MASK;
+ config->ccctlr = val;
return size;
}
static DEVICE_ATTR_RW(cyc_threshold);
@@ -686,14 +689,16 @@ static ssize_t bb_ctrl_store(struct device *dev,
return -EINVAL;
if (!drvdata->nr_addr_cmp)
return -EINVAL;
+
/*
- * Bit[7:0] selects which address range comparator is used for
- * branch broadcast control.
+ * Bit[8] controls include(1) / exclude(0), bits[0-7] select
+ * individual range comparators. If include then at least 1
+ * range must be selected.
*/
- if (BMVAL(val, 0, 7) > drvdata->nr_addr_cmp)
+ if ((val & BIT(8)) && (BMVAL(val, 0, 7) == 0))
return -EINVAL;
- config->bb_ctrl = val;
+ config->bb_ctrl = val & GENMASK(8, 0);
return size;
}
static DEVICE_ATTR_RW(bb_ctrl);
@@ -1324,8 +1329,8 @@ static ssize_t seq_event_store(struct device *dev,
spin_lock(&drvdata->spinlock);
idx = config->seq_idx;
- /* RST, bits[7:0] */
- config->seq_ctrl[idx] = val & 0xFF;
+ /* Seq control has two masks B[15:8] F[7:0] */
+ config->seq_ctrl[idx] = val & 0xFFFF;
spin_unlock(&drvdata->spinlock);
return size;
}
@@ -1580,7 +1585,7 @@ static ssize_t res_ctrl_store(struct device *dev,
if (idx % 2 != 0)
/* PAIRINV, bit[21] */
val &= ~BIT(21);
- config->res_ctrl[idx] = val;
+ config->res_ctrl[idx] = val & GENMASK(21, 0);
spin_unlock(&drvdata->spinlock);
return size;
}
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2 03/11] coresight: etm4x: Add missing API to set EL match on address filters
From: Mike Leach @ 2019-08-29 21:33 UTC (permalink / raw)
To: mike.leach, mathieu.poirier, linux-arm-kernel, coresight,
linux-doc
Cc: gregkh, corbet, suzuki.poulose
In-Reply-To: <20190829213321.4092-1-mike.leach@linaro.org>
TRCACATRn registers have match bits for secure and non-secure exception
levels which are not accessible by the sysfs API.
This adds a new sysfs parameter to enable this - addr_exlevel_s_ns.
Signed-off-by: Mike Leach <mike.leach@linaro.org>
---
.../coresight/coresight-etm4x-sysfs.c | 42 +++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
index cc8156318018..b520f3c1521f 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
@@ -1233,6 +1233,47 @@ static ssize_t addr_context_store(struct device *dev,
}
static DEVICE_ATTR_RW(addr_context);
+static ssize_t addr_exlevel_s_ns_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ u8 idx;
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ struct etmv4_config *config = &drvdata->config;
+
+ spin_lock(&drvdata->spinlock);
+ idx = config->addr_idx;
+ val = BMVAL(config->addr_acc[idx], 14, 8);
+ spin_unlock(&drvdata->spinlock);
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t addr_exlevel_s_ns_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ u8 idx;
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ struct etmv4_config *config = &drvdata->config;
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+
+ if (val & ~0x7F)
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ idx = config->addr_idx;
+ /* clear Exlevel_ns & Exlevel_s bits[14:12, 11:8] */
+ config->addr_acc[idx] &= ~(GENMASK(14, 8));
+ config->addr_acc[idx] |= (val << 8);
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(addr_exlevel_s_ns);
+
static ssize_t seq_idx_show(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -2038,6 +2079,7 @@ static struct attribute *coresight_etmv4_attrs[] = {
&dev_attr_addr_stop.attr,
&dev_attr_addr_ctxtype.attr,
&dev_attr_addr_context.attr,
+ &dev_attr_addr_exlevel_s_ns.attr,
&dev_attr_seq_idx.attr,
&dev_attr_seq_state.attr,
&dev_attr_seq_event.attr,
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2 04/11] coresight: etm4x: Fix issues with start-stop logic.
From: Mike Leach @ 2019-08-29 21:33 UTC (permalink / raw)
To: mike.leach, mathieu.poirier, linux-arm-kernel, coresight,
linux-doc
Cc: gregkh, corbet, suzuki.poulose
In-Reply-To: <20190829213321.4092-1-mike.leach@linaro.org>
Fixes the following issues when using the ETMv4 start-stop logic.
1) Setting a start or a stop address should not automatically set the
start-stop status to 'on'. The value set by the user in 'mode' must
be respected or start instances could be missed.
2) Missing API for controlling TRCVIPCSSCTLR - start stop control by
PE comparators.
3) Default ETM configuration sets a trace all range, and correctly sets
the start-stop status bit. This was not being correctly reflected in
the 'mode' parameter.
Signed-off-by: Mike Leach <mike.leach@linaro.org>
---
.../coresight/coresight-etm4x-sysfs.c | 39 +++++++++++++++++--
drivers/hwtracing/coresight/coresight-etm4x.c | 1 +
2 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
index b520f3c1521f..11730a194951 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
@@ -217,6 +217,7 @@ static ssize_t reset_store(struct device *dev,
/* No start-stop filtering for ViewInst */
config->vissctlr = 0x0;
+ config->vipcssctlr = 0x0;
/* Disable seq events */
for (i = 0; i < drvdata->nrseqstate-1; i++)
@@ -1059,8 +1060,6 @@ static ssize_t addr_start_store(struct device *dev,
config->addr_val[idx] = (u64)val;
config->addr_type[idx] = ETM_ADDR_TYPE_START;
config->vissctlr |= BIT(idx);
- /* SSSTATUS, bit[9] - turn on start/stop logic */
- config->vinst_ctrl |= BIT(9);
spin_unlock(&drvdata->spinlock);
return size;
}
@@ -1116,8 +1115,6 @@ static ssize_t addr_stop_store(struct device *dev,
config->addr_val[idx] = (u64)val;
config->addr_type[idx] = ETM_ADDR_TYPE_STOP;
config->vissctlr |= BIT(idx + 16);
- /* SSSTATUS, bit[9] - turn on start/stop logic */
- config->vinst_ctrl |= BIT(9);
spin_unlock(&drvdata->spinlock);
return size;
}
@@ -1274,6 +1271,39 @@ static ssize_t addr_exlevel_s_ns_store(struct device *dev,
}
static DEVICE_ATTR_RW(addr_exlevel_s_ns);
+static ssize_t vinst_pe_cmp_start_stop_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ struct etmv4_config *config = &drvdata->config;
+
+ if (!drvdata->nr_pe_cmp)
+ return -EINVAL;
+ val = config->vipcssctlr;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+static ssize_t vinst_pe_cmp_start_stop_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ struct etmv4_config *config = &drvdata->config;
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+ if (!drvdata->nr_pe_cmp)
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ config->vipcssctlr = val;
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(vinst_pe_cmp_start_stop);
+
static ssize_t seq_idx_show(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -2080,6 +2110,7 @@ static struct attribute *coresight_etmv4_attrs[] = {
&dev_attr_addr_ctxtype.attr,
&dev_attr_addr_context.attr,
&dev_attr_addr_exlevel_s_ns.attr,
+ &dev_attr_vinst_pe_cmp_start_stop.attr,
&dev_attr_seq_idx.attr,
&dev_attr_seq_state.attr,
&dev_attr_seq_event.attr,
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
index 52b8876de157..d8b078d0cc7f 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -868,6 +868,7 @@ static void etm4_set_default_filter(struct etmv4_config *config)
* in the started state
*/
config->vinst_ctrl |= BIT(9);
+ config->mode |= ETM_MODE_VIEWINST_STARTSTOP;
/* No start-stop filtering for ViewInst */
config->vissctlr = 0x0;
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2 05/11] coresight: etm4x: Improve usability of sysfs - include/exclude addr.
From: Mike Leach @ 2019-08-29 21:33 UTC (permalink / raw)
To: mike.leach, mathieu.poirier, linux-arm-kernel, coresight,
linux-doc
Cc: gregkh, corbet, suzuki.poulose
In-Reply-To: <20190829213321.4092-1-mike.leach@linaro.org>
Setting include / exclude on a range had to be done by setting
the bit in 'mode' before setting the range. However, setting this
bit also had the effect of altering the current range as well.
Changed to only set include / exclude setting of a range at the point of
setting that range. Either use a 3rd input parameter as the include exclude
value, or if not present use the current value of 'mode'. Do not change
current range when 'mode' changes.
Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Mike Leach <mike.leach@linaro.org>
---
.../hwtracing/coresight/coresight-etm4x-sysfs.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
index 11730a194951..e4a9ce76ed33 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
@@ -297,8 +297,6 @@ static ssize_t mode_store(struct device *dev,
spin_lock(&drvdata->spinlock);
config->mode = val & ETMv4_MODE_ALL;
- etm4_set_mode_exclude(drvdata,
- config->mode & ETM_MODE_EXCLUDE ? true : false);
if (drvdata->instrp0 == true) {
/* start by clearing instruction P0 field */
@@ -972,8 +970,12 @@ static ssize_t addr_range_store(struct device *dev,
unsigned long val1, val2;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
struct etmv4_config *config = &drvdata->config;
+ int elements, exclude;
- if (sscanf(buf, "%lx %lx", &val1, &val2) != 2)
+ elements = sscanf(buf, "%lx %lx %x", &val1, &val2, &exclude);
+
+ /* exclude is optional, but need at least two parameter */
+ if (elements < 2)
return -EINVAL;
/* lower address comparator cannot have a higher address value */
if (val1 > val2)
@@ -1001,9 +1003,11 @@ static ssize_t addr_range_store(struct device *dev,
/*
* Program include or exclude control bits for vinst or vdata
* whenever we change addr comparators to ETM_ADDR_TYPE_RANGE
+ * use supplied value, or default to bit set in 'mode'
*/
- etm4_set_mode_exclude(drvdata,
- config->mode & ETM_MODE_EXCLUDE ? true : false);
+ if (elements != 3)
+ exclude = config->mode & ETM_MODE_EXCLUDE;
+ etm4_set_mode_exclude(drvdata, exclude ? true : false);
spin_unlock(&drvdata->spinlock);
return size;
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2 06/11] coresight: etm4x: Improve usability of sysfs - CID and VMID masks.
From: Mike Leach @ 2019-08-29 21:33 UTC (permalink / raw)
To: mike.leach, mathieu.poirier, linux-arm-kernel, coresight,
linux-doc
Cc: gregkh, corbet, suzuki.poulose
In-Reply-To: <20190829213321.4092-1-mike.leach@linaro.org>
Context ID and VM ID masks required 2 value inputs, even when the
second value is ignored as insufficient CID / VMID comparators are
implemented.
Permit a single value to be used if that is sufficient to cover all
implemented comparators.
Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Mike Leach <mike.leach@linaro.org>
---
drivers/hwtracing/coresight/coresight-etm4x-sysfs.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
index e4a9ce76ed33..171d3c580968 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
@@ -1794,6 +1794,7 @@ static ssize_t ctxid_masks_store(struct device *dev,
unsigned long val1, val2, mask;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
struct etmv4_config *config = &drvdata->config;
+ int nr_inputs;
/*
* Don't use contextID tracing if coming from a PID namespace. See
@@ -1809,7 +1810,9 @@ static ssize_t ctxid_masks_store(struct device *dev,
*/
if (!drvdata->ctxid_size || !drvdata->numcidc)
return -EINVAL;
- if (sscanf(buf, "%lx %lx", &val1, &val2) != 2)
+ /* one mask if <= 4 comparators, two for up to 8 */
+ nr_inputs = sscanf(buf, "%lx %lx", &val1, &val2);
+ if ((drvdata->numcidc > 4) && (nr_inputs != 2))
return -EINVAL;
spin_lock(&drvdata->spinlock);
@@ -1983,6 +1986,7 @@ static ssize_t vmid_masks_store(struct device *dev,
unsigned long val1, val2, mask;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
struct etmv4_config *config = &drvdata->config;
+ int nr_inputs;
/*
* only implemented when vmid tracing is enabled, i.e. at least one
@@ -1990,7 +1994,9 @@ static ssize_t vmid_masks_store(struct device *dev,
*/
if (!drvdata->vmid_size || !drvdata->numvmidc)
return -EINVAL;
- if (sscanf(buf, "%lx %lx", &val1, &val2) != 2)
+ /* one mask if <= 4 comparators, two for up to 8 */
+ nr_inputs = sscanf(buf, "%lx %lx", &val1, &val2);
+ if ((drvdata->numvmidc > 4) && (nr_inputs != 2))
return -EINVAL;
spin_lock(&drvdata->spinlock);
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2 07/11] coresight: etm4x: Add view comparator settings API to sysfs.
From: Mike Leach @ 2019-08-29 21:33 UTC (permalink / raw)
To: mike.leach, mathieu.poirier, linux-arm-kernel, coresight,
linux-doc
Cc: gregkh, corbet, suzuki.poulose
In-Reply-To: <20190829213321.4092-1-mike.leach@linaro.org>
Currently it is not possible to view the current settings of a given
address comparator without knowing what type it is set to. For example, if
a comparator is set as an addr_start comparator, attempting to read
addr_stop for the same index will result in an error.
addr_cmp_view is added to allow the user to see the current settings of
the indexed address comparator without resorting to trial and error when
the set type is not known.
Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Reviewed-by: Leo Yan <leo.yan@linaro.org>
Signed-off-by: Mike Leach <mike.leach@linaro.org>
---
.../coresight/coresight-etm4x-sysfs.c | 52 +++++++++++++++++++
1 file changed, 52 insertions(+)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
index 171d3c580968..a8c9eadfe56f 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
@@ -1275,6 +1275,57 @@ static ssize_t addr_exlevel_s_ns_store(struct device *dev,
}
static DEVICE_ATTR_RW(addr_exlevel_s_ns);
+static const char * const addr_type_names[] = {
+ "unused",
+ "single",
+ "range",
+ "start",
+ "stop"
+};
+
+static ssize_t addr_cmp_view_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ u8 idx, addr_type;
+ unsigned long addr_v, addr_v2, addr_ctrl;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ struct etmv4_config *config = &drvdata->config;
+ int size = 0;
+ bool exclude = false;
+
+ spin_lock(&drvdata->spinlock);
+ idx = config->addr_idx;
+ addr_v = config->addr_val[idx];
+ addr_ctrl = config->addr_acc[idx];
+ addr_type = config->addr_type[idx];
+ if (addr_type == ETM_ADDR_TYPE_RANGE) {
+ if (idx & 0x1) {
+ idx -= 1;
+ addr_v2 = addr_v;
+ addr_v = config->addr_val[idx];
+ } else {
+ addr_v2 = config->addr_val[idx + 1];
+ }
+ exclude = config->viiectlr & BIT(idx / 2 + 16);
+ }
+ spin_unlock(&drvdata->spinlock);
+ if (addr_type) {
+ size = scnprintf(buf, PAGE_SIZE, "addr_cmp[%i] %s %#lx", idx,
+ addr_type_names[addr_type], addr_v);
+ if (addr_type == ETM_ADDR_TYPE_RANGE) {
+ size += scnprintf(buf + size, PAGE_SIZE - size,
+ " %#lx %s", addr_v2,
+ exclude ? "exclude" : "include");
+ }
+ size += scnprintf(buf + size, PAGE_SIZE - size,
+ " ctrl(%#lx)\n", addr_ctrl);
+ } else {
+ size = scnprintf(buf, PAGE_SIZE, "addr_cmp[%i] unused\n", idx);
+ }
+ return size;
+}
+static DEVICE_ATTR_RO(addr_cmp_view);
+
static ssize_t vinst_pe_cmp_start_stop_show(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -2120,6 +2171,7 @@ static struct attribute *coresight_etmv4_attrs[] = {
&dev_attr_addr_ctxtype.attr,
&dev_attr_addr_context.attr,
&dev_attr_addr_exlevel_s_ns.attr,
+ &dev_attr_addr_cmp_view.attr,
&dev_attr_vinst_pe_cmp_start_stop.attr,
&dev_attr_seq_idx.attr,
&dev_attr_seq_state.attr,
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2 08/11] coresight: etm4x: Add missing single-shot control API to sysfs
From: Mike Leach @ 2019-08-29 21:33 UTC (permalink / raw)
To: mike.leach, mathieu.poirier, linux-arm-kernel, coresight,
linux-doc
Cc: gregkh, corbet, suzuki.poulose
In-Reply-To: <20190829213321.4092-1-mike.leach@linaro.org>
An API to control single-shot comparator operation was missing from sysfs.
This adds the parameters to sysfs to allow programming of this feature.
Signed-off-by: Mike Leach <mike.leach@linaro.org>
---
.../coresight/coresight-etm4x-sysfs.c | 122 ++++++++++++++++++
drivers/hwtracing/coresight/coresight-etm4x.c | 26 +++-
drivers/hwtracing/coresight/coresight-etm4x.h | 3 +
3 files changed, 150 insertions(+), 1 deletion(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
index a8c9eadfe56f..14be3274f8d9 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
@@ -239,6 +239,7 @@ static ssize_t reset_store(struct device *dev,
for (i = 0; i < drvdata->nr_resource; i++)
config->res_ctrl[i] = 0x0;
+ config->ss_idx = 0x0;
for (i = 0; i < drvdata->nr_ss_cmp; i++) {
config->ss_ctrl[i] = 0x0;
config->ss_pe_cmp[i] = 0x0;
@@ -1717,6 +1718,123 @@ static ssize_t res_ctrl_store(struct device *dev,
}
static DEVICE_ATTR_RW(res_ctrl);
+static ssize_t sshot_idx_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ struct etmv4_config *config = &drvdata->config;
+
+ val = config->ss_idx;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t sshot_idx_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ struct etmv4_config *config = &drvdata->config;
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+ if (val >= drvdata->nr_ss_cmp)
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ config->ss_idx = val;
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(sshot_idx);
+
+static ssize_t sshot_ctrl_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ struct etmv4_config *config = &drvdata->config;
+
+ spin_lock(&drvdata->spinlock);
+ val = config->ss_ctrl[config->ss_idx];
+ spin_unlock(&drvdata->spinlock);
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t sshot_ctrl_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ u8 idx;
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ struct etmv4_config *config = &drvdata->config;
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ idx = config->ss_idx;
+ config->ss_ctrl[idx] = val & GENMASK(24, 0);
+ /* must clear bit 31 in related status register on programming */
+ config->ss_status[idx] &= ~BIT(31);
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(sshot_ctrl);
+
+static ssize_t sshot_status_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ struct etmv4_config *config = &drvdata->config;
+
+ spin_lock(&drvdata->spinlock);
+ val = config->ss_status[config->ss_idx];
+ spin_unlock(&drvdata->spinlock);
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+static DEVICE_ATTR_RO(sshot_status);
+
+static ssize_t sshot_pe_ctrl_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ struct etmv4_config *config = &drvdata->config;
+
+ spin_lock(&drvdata->spinlock);
+ val = config->ss_pe_cmp[config->ss_idx];
+ spin_unlock(&drvdata->spinlock);
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t sshot_pe_ctrl_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ u8 idx;
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ struct etmv4_config *config = &drvdata->config;
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ idx = config->ss_idx;
+ config->ss_pe_cmp[idx] = val & GENMASK(7, 0);
+ /* must clear bit 31 in related status register on programming */
+ config->ss_status[idx] &= ~BIT(31);
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(sshot_pe_ctrl);
+
static ssize_t ctxid_idx_show(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -2173,6 +2291,10 @@ static struct attribute *coresight_etmv4_attrs[] = {
&dev_attr_addr_exlevel_s_ns.attr,
&dev_attr_addr_cmp_view.attr,
&dev_attr_vinst_pe_cmp_start_stop.attr,
+ &dev_attr_sshot_idx.attr,
+ &dev_attr_sshot_ctrl.attr,
+ &dev_attr_sshot_pe_ctrl.attr,
+ &dev_attr_sshot_status.attr,
&dev_attr_seq_idx.attr,
&dev_attr_seq_state.attr,
&dev_attr_seq_event.attr,
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
index d8b078d0cc7f..fb7083218410 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -149,6 +149,9 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
drvdata->base + TRCRSCTLRn(i));
for (i = 0; i < drvdata->nr_ss_cmp; i++) {
+ /* always clear status bit on restart if using single-shot */
+ if (config->ss_ctrl[i] || config->ss_pe_cmp[i])
+ config->ss_status[i] &= ~BIT(31);
writel_relaxed(config->ss_ctrl[i],
drvdata->base + TRCSSCCRn(i));
writel_relaxed(config->ss_status[i],
@@ -448,6 +451,9 @@ static void etm4_disable_hw(void *info)
{
u32 control;
struct etmv4_drvdata *drvdata = info;
+ struct etmv4_config *config = &drvdata->config;
+ struct device *etm_dev = &drvdata->csdev->dev;
+ int i;
CS_UNLOCK(drvdata->base);
@@ -470,6 +476,18 @@ static void etm4_disable_hw(void *info)
isb();
writel_relaxed(control, drvdata->base + TRCPRGCTLR);
+ /* wait for TRCSTATR.PMSTABLE to go to '1' */
+ if (coresight_timeout(drvdata->base, TRCSTATR,
+ TRCSTATR_PMSTABLE_BIT, 1))
+ dev_err(etm_dev,
+ "timeout while waiting for PM stable Trace Status\n");
+
+ /* read the status of the single shot comparators */
+ for (i = 0; i < drvdata->nr_ss_cmp; i++) {
+ config->ss_status[i] =
+ readl_relaxed(drvdata->base + TRCSSCSRn(i));
+ }
+
coresight_disclaim_device_unlocked(drvdata->base);
CS_LOCK(drvdata->base);
@@ -576,6 +594,7 @@ static void etm4_init_arch_data(void *info)
u32 etmidr4;
u32 etmidr5;
struct etmv4_drvdata *drvdata = info;
+ int i;
/* Make sure all registers are accessible */
etm4_os_unlock(drvdata);
@@ -699,9 +718,14 @@ static void etm4_init_arch_data(void *info)
drvdata->nr_resource = BMVAL(etmidr4, 16, 19) + 1;
/*
* NUMSSCC, bits[23:20] the number of single-shot
- * comparator control for tracing
+ * comparator control for tracing. Read any status regs as these
+ * also contain RO capability data.
*/
drvdata->nr_ss_cmp = BMVAL(etmidr4, 20, 23);
+ for (i = 0; i < drvdata->nr_ss_cmp; i++) {
+ drvdata->config.ss_status[i] =
+ readl_relaxed(drvdata->base + TRCSSCSRn(i));
+ }
/* NUMCIDC, bits[27:24] number of Context ID comparators for tracing */
drvdata->numcidc = BMVAL(etmidr4, 24, 27);
/* NUMVMIDC, bits[31:28] number of VMID comparators for tracing */
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
index 60bc2fb5159b..be8b32ea1654 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.h
+++ b/drivers/hwtracing/coresight/coresight-etm4x.h
@@ -175,6 +175,7 @@
ETM_MODE_EXCL_USER)
#define TRCSTATR_IDLE_BIT 0
+#define TRCSTATR_PMSTABLE_BIT 1
#define ETM_DEFAULT_ADDR_COMP 0
/* PowerDown Control Register bits */
@@ -226,6 +227,7 @@
* @cntr_val: Sets or returns the value for a counter.
* @res_idx: Resource index selector.
* @res_ctrl: Controls the selection of the resources in the trace unit.
+ * @ss_idx: Single-shot index selector.
* @ss_ctrl: Controls the corresponding single-shot comparator resource.
* @ss_status: The status of the corresponding single-shot comparator.
* @ss_pe_cmp: Selects the PE comparator inputs for Single-shot control.
@@ -269,6 +271,7 @@ struct etmv4_config {
u32 cntr_val[ETMv4_MAX_CNTR];
u8 res_idx;
u32 res_ctrl[ETM_MAX_RES_SEL];
+ u8 ss_idx;
u32 ss_ctrl[ETM_MAX_SS_CMP];
u32 ss_status[ETM_MAX_SS_CMP];
u32 ss_pe_cmp[ETM_MAX_SS_CMP];
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2 10/11] coresight: docs: Create common sub-directory for coresight trace.
From: Mike Leach @ 2019-08-29 21:33 UTC (permalink / raw)
To: mike.leach, mathieu.poirier, linux-arm-kernel, coresight,
linux-doc
Cc: gregkh, corbet, suzuki.poulose
In-Reply-To: <20190829213321.4092-1-mike.leach@linaro.org>
There are two files in the Documentation/trace directory relating to
coresight, with more to follow, so create a Documentation/trace/coresight
directory and move existing files there. Update MAINTAINERS to reference
this sub-directory rather than the individual files.
Signed-off-by: Mike Leach <mike.leach@linaro.org>
---
Documentation/trace/{ => coresight}/coresight-cpu-debug.txt | 0
Documentation/trace/{ => coresight}/coresight.txt | 0
MAINTAINERS | 3 +--
3 files changed, 1 insertion(+), 2 deletions(-)
rename Documentation/trace/{ => coresight}/coresight-cpu-debug.txt (100%)
rename Documentation/trace/{ => coresight}/coresight.txt (100%)
diff --git a/Documentation/trace/coresight-cpu-debug.txt b/Documentation/trace/coresight/coresight-cpu-debug.txt
similarity index 100%
rename from Documentation/trace/coresight-cpu-debug.txt
rename to Documentation/trace/coresight/coresight-cpu-debug.txt
diff --git a/Documentation/trace/coresight.txt b/Documentation/trace/coresight/coresight.txt
similarity index 100%
rename from Documentation/trace/coresight.txt
rename to Documentation/trace/coresight/coresight.txt
diff --git a/MAINTAINERS b/MAINTAINERS
index 783569e3c4b4..777b77fde29b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1582,8 +1582,7 @@ R: Suzuki K Poulose <suzuki.poulose@arm.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: drivers/hwtracing/coresight/*
-F: Documentation/trace/coresight.txt
-F: Documentation/trace/coresight-cpu-debug.txt
+F: Documentation/trace/coresight/*
F: Documentation/devicetree/bindings/arm/coresight.txt
F: Documentation/devicetree/bindings/arm/coresight-cpu-debug.txt
F: Documentation/ABI/testing/sysfs-bus-coresight-devices-*
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2 09/11] coresight: etm4x: docs: Update ABI doc for sysfs features added.
From: Mike Leach @ 2019-08-29 21:33 UTC (permalink / raw)
To: mike.leach, mathieu.poirier, linux-arm-kernel, coresight,
linux-doc
Cc: gregkh, corbet, suzuki.poulose
In-Reply-To: <20190829213321.4092-1-mike.leach@linaro.org>
Update document to include the new sysfs features added during this
patchset.
Updated to reflect the new sysfs component nameing schema.
Signed-off-by: Mike Leach <mike.leach@linaro.org>
---
.../testing/sysfs-bus-coresight-devices-etm4x | 183 +++++++++++-------
1 file changed, 115 insertions(+), 68 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
index 36258bc1b473..112c50ae9986 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
@@ -1,4 +1,4 @@
-What: /sys/bus/coresight/devices/<memory_map>.etm/enable_source
+What: /sys/bus/coresight/devices/etm<N>/enable_source
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
@@ -8,82 +8,82 @@ Description: (RW) Enable/disable tracing on this specific trace entiry.
of coresight components linking the source to the sink is
configured and managed automatically by the coresight framework.
-What: /sys/bus/coresight/devices/<memory_map>.etm/cpu
+What: /sys/bus/coresight/devices/etm<N>/cpu
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) The CPU this tracing entity is associated with.
-What: /sys/bus/coresight/devices/<memory_map>.etm/nr_pe_cmp
+What: /sys/bus/coresight/devices/etm<N>/nr_pe_cmp
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Indicates the number of PE comparator inputs that are
available for tracing.
-What: /sys/bus/coresight/devices/<memory_map>.etm/nr_addr_cmp
+What: /sys/bus/coresight/devices/etm<N>/nr_addr_cmp
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Indicates the number of address comparator pairs that are
available for tracing.
-What: /sys/bus/coresight/devices/<memory_map>.etm/nr_cntr
+What: /sys/bus/coresight/devices/etm<N>/nr_cntr
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Indicates the number of counters that are available for
tracing.
-What: /sys/bus/coresight/devices/<memory_map>.etm/nr_ext_inp
+What: /sys/bus/coresight/devices/etm<N>/nr_ext_inp
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Indicates how many external inputs are implemented.
-What: /sys/bus/coresight/devices/<memory_map>.etm/numcidc
+What: /sys/bus/coresight/devices/etm<N>/numcidc
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Indicates the number of Context ID comparators that are
available for tracing.
-What: /sys/bus/coresight/devices/<memory_map>.etm/numvmidc
+What: /sys/bus/coresight/devices/etm<N>/numvmidc
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Indicates the number of VMID comparators that are available
for tracing.
-What: /sys/bus/coresight/devices/<memory_map>.etm/nrseqstate
+What: /sys/bus/coresight/devices/etm<N>/nrseqstate
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Indicates the number of sequencer states that are
implemented.
-What: /sys/bus/coresight/devices/<memory_map>.etm/nr_resource
+What: /sys/bus/coresight/devices/etm<N>/nr_resource
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Indicates the number of resource selection pairs that are
available for tracing.
-What: /sys/bus/coresight/devices/<memory_map>.etm/nr_ss_cmp
+What: /sys/bus/coresight/devices/etm<N>/nr_ss_cmp
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Indicates the number of single-shot comparator controls that
are available for tracing.
-What: /sys/bus/coresight/devices/<memory_map>.etm/reset
+What: /sys/bus/coresight/devices/etm<N>/reset
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (W) Cancels all configuration on a trace unit and set it back
to its boot configuration.
-What: /sys/bus/coresight/devices/<memory_map>.etm/mode
+What: /sys/bus/coresight/devices/etm<N>/mode
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
@@ -91,302 +91,349 @@ Description: (RW) Controls various modes supported by this ETM, for example
P0 instruction tracing, branch broadcast, cycle counting and
context ID tracing.
-What: /sys/bus/coresight/devices/<memory_map>.etm/pe
+What: /sys/bus/coresight/devices/etm<N>/pe
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Controls which PE to trace.
-What: /sys/bus/coresight/devices/<memory_map>.etm/event
+What: /sys/bus/coresight/devices/etm<N>/event
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Controls the tracing of arbitrary events from bank 0 to 3.
-What: /sys/bus/coresight/devices/<memory_map>.etm/event_instren
+What: /sys/bus/coresight/devices/etm<N>/event_instren
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Controls the behavior of the events in bank 0 to 3.
-What: /sys/bus/coresight/devices/<memory_map>.etm/event_ts
+What: /sys/bus/coresight/devices/etm<N>/event_ts
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Controls the insertion of global timestamps in the trace
streams.
-What: /sys/bus/coresight/devices/<memory_map>.etm/syncfreq
+What: /sys/bus/coresight/devices/etm<N>/syncfreq
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Controls how often trace synchronization requests occur.
-What: /sys/bus/coresight/devices/<memory_map>.etm/cyc_threshold
+What: /sys/bus/coresight/devices/etm<N>/cyc_threshold
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Sets the threshold value for cycle counting.
-What: /sys/bus/coresight/devices/<memory_map>.etm/bb_ctrl
+What: /sys/bus/coresight/devices/etm<N>/bb_ctrl
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Controls which regions in the memory map are enabled to
use branch broadcasting.
-What: /sys/bus/coresight/devices/<memory_map>.etm/event_vinst
+What: /sys/bus/coresight/devices/etm<N>/event_vinst
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Controls instruction trace filtering.
-What: /sys/bus/coresight/devices/<memory_map>.etm/s_exlevel_vinst
+What: /sys/bus/coresight/devices/etm<N>/s_exlevel_vinst
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) In Secure state, each bit controls whether instruction
tracing is enabled for the corresponding exception level.
-What: /sys/bus/coresight/devices/<memory_map>.etm/ns_exlevel_vinst
+What: /sys/bus/coresight/devices/etm<N>/ns_exlevel_vinst
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) In non-secure state, each bit controls whether instruction
tracing is enabled for the corresponding exception level.
-What: /sys/bus/coresight/devices/<memory_map>.etm/addr_idx
+What: /sys/bus/coresight/devices/etm<N>/addr_idx
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Select which address comparator or pair (of comparators) to
work with.
-What: /sys/bus/coresight/devices/<memory_map>.etm/addr_instdatatype
+What: /sys/bus/coresight/devices/etm<N>/addr_instdatatype
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Controls what type of comparison the trace unit performs.
-What: /sys/bus/coresight/devices/<memory_map>.etm/addr_single
+What: /sys/bus/coresight/devices/etm<N>/addr_single
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Used to setup single address comparator values.
-What: /sys/bus/coresight/devices/<memory_map>.etm/addr_range
+What: /sys/bus/coresight/devices/etm<N>/addr_range
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Used to setup address range comparator values.
-What: /sys/bus/coresight/devices/<memory_map>.etm/seq_idx
+What: /sys/bus/coresight/devices/etm<N>/seq_idx
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Select which sequensor.
-What: /sys/bus/coresight/devices/<memory_map>.etm/seq_state
+What: /sys/bus/coresight/devices/etm<N>/seq_state
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Use this to set, or read, the sequencer state.
-What: /sys/bus/coresight/devices/<memory_map>.etm/seq_event
+What: /sys/bus/coresight/devices/etm<N>/seq_event
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Moves the sequencer state to a specific state.
-What: /sys/bus/coresight/devices/<memory_map>.etm/seq_reset_event
+What: /sys/bus/coresight/devices/etm<N>/seq_reset_event
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Moves the sequencer to state 0 when a programmed event
occurs.
-What: /sys/bus/coresight/devices/<memory_map>.etm/cntr_idx
+What: /sys/bus/coresight/devices/etm<N>/cntr_idx
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Select which counter unit to work with.
-What: /sys/bus/coresight/devices/<memory_map>.etm/cntrldvr
+What: /sys/bus/coresight/devices/etm<N>/cntrldvr
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) This sets or returns the reload count value of the
specific counter.
-What: /sys/bus/coresight/devices/<memory_map>.etm/cntr_val
+What: /sys/bus/coresight/devices/etm<N>/cntr_val
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) This sets or returns the current count value of the
specific counter.
-What: /sys/bus/coresight/devices/<memory_map>.etm/cntr_ctrl
+What: /sys/bus/coresight/devices/etm<N>/cntr_ctrl
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Controls the operation of the selected counter.
-What: /sys/bus/coresight/devices/<memory_map>.etm/res_idx
+What: /sys/bus/coresight/devices/etm<N>/res_idx
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Select which resource selection unit to work with.
-What: /sys/bus/coresight/devices/<memory_map>.etm/res_ctrl
+What: /sys/bus/coresight/devices/etm<N>/res_ctrl
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Controls the selection of the resources in the trace unit.
-What: /sys/bus/coresight/devices/<memory_map>.etm/ctxid_idx
+What: /sys/bus/coresight/devices/etm<N>/ctxid_idx
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Select which context ID comparator to work with.
-What: /sys/bus/coresight/devices/<memory_map>.etm/ctxid_pid
+What: /sys/bus/coresight/devices/etm<N>/ctxid_pid
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Get/Set the context ID comparator value to trigger on.
-What: /sys/bus/coresight/devices/<memory_map>.etm/ctxid_masks
+What: /sys/bus/coresight/devices/etm<N>/ctxid_masks
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Mask for all 8 context ID comparator value
registers (if implemented).
-What: /sys/bus/coresight/devices/<memory_map>.etm/vmid_idx
+What: /sys/bus/coresight/devices/etm<N>/vmid_idx
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Select which virtual machine ID comparator to work with.
-What: /sys/bus/coresight/devices/<memory_map>.etm/vmid_val
+What: /sys/bus/coresight/devices/etm<N>/vmid_val
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Get/Set the virtual machine ID comparator value to
trigger on.
-What: /sys/bus/coresight/devices/<memory_map>.etm/vmid_masks
+What: /sys/bus/coresight/devices/etm<N>/vmid_masks
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Mask for all 8 virtual machine ID comparator value
registers (if implemented).
-What: /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcoslsr
+What: /sys/bus/coresight/devices/etm<N>/addr_exlevel_s_ns
+Date: August 2019
+KernelVersion: 5.4
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) Set the Exception Level matching bits for secure and
+ non-secure exception levels.
+
+What: /sys/bus/coresight/devices/etm<N>/vinst_pe_cmp_start_stop
+Date: August 2019
+KernelVersion: 5.4
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) Access the start stop control register for PE input
+ comparators.
+
+What: /sys/bus/coresight/devices/etm<N>/addr_cmp_view
+Date: August 2019
+KernelVersion: 5.4
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (R) Print the current settings for the selected address
+ comparator.
+
+What: /sys/bus/coresight/devices/etm<N>/sshot_idx
+Date: August 2019
+KernelVersion: 5.4
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) Select the single shot control register to access.
+
+What: /sys/bus/coresight/devices/etm<N>/sshot_ctrl
+Date: August 2019
+KernelVersion: 5.4
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) Access the selected single shot control register.
+
+What: /sys/bus/coresight/devices/etm<N>/sshot_status
+Date: August 2019
+KernelVersion: 5.4
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (R) Print the current value of the selected single shot
+ status register.
+
+What: /sys/bus/coresight/devices/etm<N>/sshot_pe_ctrl
+Date: August 2019
+KernelVersion: 5.4
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) Access the selected single show PE comparator control
+ register.
+
+What: /sys/bus/coresight/devices/etm<N>/mgmt/trcoslsr
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Print the content of the OS Lock Status Register (0x304).
The value it taken directly from the HW.
-What: /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcpdcr
+What: /sys/bus/coresight/devices/etm<N>/mgmt/trcpdcr
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Print the content of the Power Down Control Register
(0x310). The value is taken directly from the HW.
-What: /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcpdsr
+What: /sys/bus/coresight/devices/etm<N>/mgmt/trcpdsr
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Print the content of the Power Down Status Register
(0x314). The value is taken directly from the HW.
-What: /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trclsr
+What: /sys/bus/coresight/devices/etm<N>/mgmt/trclsr
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Print the content of the SW Lock Status Register
(0xFB4). The value is taken directly from the HW.
-What: /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcauthstatus
+What: /sys/bus/coresight/devices/etm<N>/mgmt/trcauthstatus
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Print the content of the Authentication Status Register
(0xFB8). The value is taken directly from the HW.
-What: /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcdevid
+What: /sys/bus/coresight/devices/etm<N>/mgmt/trcdevid
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Print the content of the Device ID Register
(0xFC8). The value is taken directly from the HW.
-What: /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcdevtype
+What: /sys/bus/coresight/devices/etm<N>/mgmt/trcdevtype
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Print the content of the Device Type Register
(0xFCC). The value is taken directly from the HW.
-What: /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcpidr0
+What: /sys/bus/coresight/devices/etm<N>/mgmt/trcpidr0
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Print the content of the Peripheral ID0 Register
(0xFE0). The value is taken directly from the HW.
-What: /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcpidr1
+What: /sys/bus/coresight/devices/etm<N>/mgmt/trcpidr1
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Print the content of the Peripheral ID1 Register
(0xFE4). The value is taken directly from the HW.
-What: /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcpidr2
+What: /sys/bus/coresight/devices/etm<N>/mgmt/trcpidr2
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Print the content of the Peripheral ID2 Register
(0xFE8). The value is taken directly from the HW.
-What: /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcpidr3
+What: /sys/bus/coresight/devices/etm<N>/mgmt/trcpidr3
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Print the content of the Peripheral ID3 Register
(0xFEC). The value is taken directly from the HW.
-What: /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcconfig
+What: /sys/bus/coresight/devices/etm<N>/mgmt/trcconfig
Date: February 2016
KernelVersion: 4.07
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Print the content of the trace configuration register
(0x010) as currently set by SW.
-What: /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trctraceid
+What: /sys/bus/coresight/devices/etm<N>/mgmt/trctraceid
Date: February 2016
KernelVersion: 4.07
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Print the content of the trace ID register (0x040).
-What: /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr0
+What: /sys/bus/coresight/devices/etm<N>/trcidr/trcidr0
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Returns the tracing capabilities of the trace unit (0x1E0).
The value is taken directly from the HW.
-What: /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr1
+What: /sys/bus/coresight/devices/etm<N>/trcidr/trcidr1
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Returns the tracing capabilities of the trace unit (0x1E4).
The value is taken directly from the HW.
-What: /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr2
+What: /sys/bus/coresight/devices/etm<N>/trcidr/trcidr2
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
@@ -394,7 +441,7 @@ Description: (R) Returns the maximum size of the data value, data address,
VMID, context ID and instuction address in the trace unit
(0x1E8). The value is taken directly from the HW.
-What: /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr3
+What: /sys/bus/coresight/devices/etm<N>/trcidr/trcidr3
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
@@ -403,42 +450,42 @@ Description: (R) Returns the value associated with various resources
architecture specification for more details (0x1E8).
The value is taken directly from the HW.
-What: /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr4
+What: /sys/bus/coresight/devices/etm<N>/trcidr/trcidr4
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Returns how many resources the trace unit supports (0x1F0).
The value is taken directly from the HW.
-What: /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr5
+What: /sys/bus/coresight/devices/etm<N>/trcidr/trcidr5
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Returns how many resources the trace unit supports (0x1F4).
The value is taken directly from the HW.
-What: /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr8
+What: /sys/bus/coresight/devices/etm<N>/trcidr/trcidr8
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Returns the maximum speculation depth of the instruction
trace stream. (0x180). The value is taken directly from the HW.
-What: /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr9
+What: /sys/bus/coresight/devices/etm<N>/trcidr/trcidr9
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Returns the number of P0 right-hand keys that the trace unit
can use (0x184). The value is taken directly from the HW.
-What: /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr10
+What: /sys/bus/coresight/devices/etm<N>/trcidr/trcidr10
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Returns the number of P1 right-hand keys that the trace unit
can use (0x188). The value is taken directly from the HW.
-What: /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr11
+What: /sys/bus/coresight/devices/etm<N>/trcidr/trcidr11
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
@@ -446,7 +493,7 @@ Description: (R) Returns the number of special P1 right-hand keys that the
trace unit can use (0x18C). The value is taken directly from
the HW.
-What: /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr12
+What: /sys/bus/coresight/devices/etm<N>/trcidr/trcidr12
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
@@ -454,7 +501,7 @@ Description: (R) Returns the number of conditional P1 right-hand keys that
the trace unit can use (0x190). The value is taken directly
from the HW.
-What: /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr13
+What: /sys/bus/coresight/devices/etm<N>/trcidr/trcidr13
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2 11/11] coresight: etm4x: docs: Adds detailed document for programming etm4x.
From: Mike Leach @ 2019-08-29 21:33 UTC (permalink / raw)
To: mike.leach, mathieu.poirier, linux-arm-kernel, coresight,
linux-doc
Cc: gregkh, corbet, suzuki.poulose
In-Reply-To: <20190829213321.4092-1-mike.leach@linaro.org>
Add in detailed programmers reference for users wanting to program the
CoreSight ETM 4.x driver using sysfs.
Signed-off-by: Mike Leach <mike.leach@linaro.org>
---
.../coresight/coresight-etm4x-reference.txt | 458 ++++++++++++++++++
1 file changed, 458 insertions(+)
create mode 100644 Documentation/trace/coresight/coresight-etm4x-reference.txt
diff --git a/Documentation/trace/coresight/coresight-etm4x-reference.txt b/Documentation/trace/coresight/coresight-etm4x-reference.txt
new file mode 100644
index 000000000000..f0c370870992
--- /dev/null
+++ b/Documentation/trace/coresight/coresight-etm4x-reference.txt
@@ -0,0 +1,458 @@
+ETMv4 sysfs linux driver programming reference - v2.
+====================================================
+
+Supplement to existing ETMv4 driver documentation.
+
+Sysfs files and directories
+---------------------------
+
+Root: /sys/bus/coresight/devices/etm<N>
+
+
+The following paragraphs explain the association between sysfs files and the
+ETMv4 registers that they effect. Note the register names are given without
+the ‘TRC’ prefix.
+
+File : mode (rw)
+Trace Registers : {CONFIGR + others}
+Notes : Bit select trace features. See ‘mode’ section below. Bits
+ in this will cause equivalent programming of trace config and
+ other registers to enable the features requested.
+Syntax & eg : 'echo bitfield > mode'
+ bitfield up to 32 bits setting trace features.
+Example : $> echo 0x > mode
+
+File : reset (wo)
+Trace Registers : All
+Notes : Reset all programming to trace nothing / no logic programmed.
+Syntax : 'echo 1 > reset'
+
+File : enable_source (wo)
+Trace Registers : PRGCTLR, All hardware regs.
+Notes : >0: Programs up the hardware with the current values held in
+ the driver and enables trace.
+ 0: disable trace hardware.
+Syntax : 'echo 1 > enable_source'
+
+File : cpu (ro)
+Trace Registers : None.
+Notes : CPU ID that this ETM is attached to.
+Example :$> cat cpu
+ $> 0
+
+File : addr_idx (rw)
+Trace Registers : None.
+Notes : Virtual register to index address comparator and range
+ features. Set index for first of the pair in a range.
+Syntax : 'echo idx > addr_idx'
+ Where idx < nr_addr_cmp x 2
+
+File : addr_range (rw)
+Trace Registers : ACVR[idx, idx+1], VIIECTLR
+Notes : Pair of addresses for a range selected by addr_idx. Include
+ / exclude according to the optional parameter, or if omitted
+ uses the current ‘mode’ setting. Select comparator range in
+ control register. Error if index is odd value.
+Depends : mode, addr_idx
+Syntax : 'echo addr1 addr2 [exclude] > addr_range'
+ Where addr1 and addr2 define the range and addr1 < addr2.
+ Optional exclude value - 0 for include, 1 for exclude.
+Example : $> echo 0x0000 0x2000 0 > addr_range
+
+File : addr_single (rw)
+Trace Registers : ACVR[idx]
+Notes : Set a single address comparator according to addr_idx. This
+ is used if the address comparator is used as part of event
+ generation logic etc.
+Depends : addr_idx
+Syntax : 'echo addr1 > addr_single'
+
+File : addr_start (rw)
+Trace Registers : ACVR[idx], VISSCTLR
+Notes : Set a trace start address comparator according to addr_idx.
+ Select comparator in control register.
+Depends : addr_idx
+Syntax : 'echo addr1 > addr_start'
+
+File : addr_stop (rw)
+Trace Registers : ACVR[idx], VISSCTLR
+Notes : Set a trace stop address comparator according to addr_idx.
+ Select comparator in control register.
+Depends : addr_idx
+Syntax : 'echo addr1 > addr_stop'
+
+File : addr_context (rw)
+Trace Registers : ACATR[idx,{6:4}]
+Notes : Link context ID comparator to address comparator addr_idx
+Depends : addr_idx.
+Syntax : 'echo ctxt_idx > addr_context'
+ Where ctxt_idx is the index of the linked context id / vmid
+ comparator.
+
+File : addr_ctxtype (rw)
+Trace Registers : ACATR[idx,{3:2}]
+Notes : Input value string. Set type for linked context ID comparator
+Depends : addr_idx
+Syntax : 'echo type > addr_ctxtype'
+ Type one of {all, vmid, ctxid, none}
+Example : $> echo ctxid > addr_ctxtype
+
+File : addr_exlevel_s_ns (rw)
+Trace Registers : ACATR[idx,{14:8}]
+Notes : Set the ELx secure and non-secure matching bits for the
+ selected address comparator
+Depends : addr_idx
+Syntax : 'echo val > addr_exlevel_s_ns'
+ val is a 7 bit value for exception levels to exclude. Input
+ value shifted to correct bits in register.
+Example : $> echo 0x4F > addr_exlevel_s_ns
+
+File : addr_instdatatype (rw)
+Trace Registers : ACATR[idx,{1:0}]
+Notes : Set the comparator address type for matching. Driver only
+ supports setting instruction address type.
+Depends : addr_idx
+
+File : addr_cmp_view (ro)
+Trace Registers : ACVR[idx, idx+1], ACATR[idx], VIIECTLR
+Notes : Read the currently selected address comparator. If part of
+ address range then display both addresses.
+Depends : addr_idx
+Syntax : 'cat addr_cmp_view'
+Example : $> cat addr_cmp_view
+ addr_cmp[0] range 0x0 0xffffffffffffffff include ctrl(0x4b00)
+
+File : nr_addr_cmp (ro)
+Trace Registers : From IDR4
+Notes : Number of address comparator pairs
+
+File : sshot_idx (rw)
+Trace Registers : None
+Notes : Select single shot register set.
+
+File : sshot_ctrl (rw)
+Trace Registers : SSCCR[idx]
+Notes : Access a single shot comparator control register.
+Depends : sshot_idx
+Syntax : 'echo val > sshot_ctrl'
+ Writes val into the selected control register.
+
+File : sshot_status (ro)
+Trace Registers : SSCSR[idx]
+Notes : Read a single shot comparator status register
+Depends : sshot_idx
+Syntax : 'cat sshot_status'
+ Read status.
+Example : $> cat sshot_status
+ 0x1
+
+File : sshot_pe_ctrl (rw)
+Trace Registers : SSPCICR[idx]
+Notes : Access a single shot PE comparator input control register.
+Depends : sshot_idx
+Syntax : echo val > sshot_pe_ctrl
+ Writes val into the selected control register.
+
+File : ns_exlevel_vinst (rw)
+Trace Registers : VICTLR{23:20}
+Notes : Program non-secure exception level filters. Set / clear NS
+ exception filter bits. Setting ‘1’ excludes trace from the
+ exception level.
+Syntax : 'echo bitfield > ns_exlevel_viinst'
+ Where bitfield contains bits to set clear for EL0 to EL2
+Example : %> echo 0x4 > ns_exlevel_viinst
+ ; Exclude EL2 NS trace.
+
+File : vinst_pe_cmp_start_stop (rw)
+Trace Registers : VIPCSSCTLR
+Notes : Access PE start stop comparator input control registers
+
+File : bb_ctrl (rw)
+Trace Registers : BBCTLR
+Notes : Define ranges that Branch Broadcast will operate in.
+ Default (0x0) is all addresses.
+Depends : BB enabled.
+
+File : cyc_threshold (rw)
+Trace Registers : CCCTLR
+Notes : Set the threshold for which cycle counts will be emitted.
+ Error if attempt to set below minimum defined in IDR3, masked
+ to width of valid bits.
+Depends : CC enabled.
+
+File : syncfreq (rw)
+Trace Registers : SYNCPR
+Notes : Set trace synchronisation period. Power of 2 value, 0 (off)
+ or 8-20. Driver defaults to 12 (every 4096 bytes).
+
+File : cntr_idx (rw)
+Trace Registers : none
+Notes : Select the counter to access
+Syntax : 'echo idx > cntr_idx'
+ Where idx < nr_cntr
+
+File : cntr_ctrl (rw)
+Trace Registers : CNTCTLR[idx]
+Notes : Set counter control value
+Depends : cntr_idx
+Syntax : 'echo val > cntr_ctrl'
+ Where val is per ETMv4 spec.
+
+File : cntrldvr (rw)
+Trace Registers : CNTRLDVR[idx]
+Notes : Set counter reload value
+Depends : cntr_idx
+Syntax : 'echo val > cntrldvr'
+ Where val is per ETMv4 spec.
+
+File : nr_cntr (ro)
+Trace Registers : From IDR5
+Notes : Number of counters implemented.
+
+File : ctxid_idx (rw)
+Trace Registers : None
+Notes : Select the context ID comparator to access
+Syntax : 'echo idx > ctxid_idx'
+ Where idx < numcidc
+
+File : ctxid_pid (rw)
+Trace Registers : CIDCVR[idx]
+Notes : Set the context ID comparator value
+Depends : ctxid_idx
+
+File : ctxid_masks (rw)
+Trace Registers : CIDCCTLR0, CIDCCTLR1, CIDCVR<0-7>
+Notes : Pair of values to set the byte masks for 1-8 context ID
+ comparators. Automatically clears masked bytes to 0 in CID
+ value registers.
+Syntax : 'echo m3m2m1m0 [m7m6m5m4] > ctxid_masks'
+ 32 bit values made up of mask bytes, where mN represents a
+ byte mask value for Ctxt ID comparator N.
+ Second value not required on systems that have fewer than 4
+ context ID comparators
+
+File : numcidc (ro)
+Trace Registers : From IDR4
+Notes : Number of Context ID comparators
+
+File : vmid_idx (rw)
+Trace Registers : None
+Notes : Select the VM ID comparator to access.
+Syntax : 'echo idx > vmid_idx'
+ Where idx < numvmidc
+
+File : vmid_val (rw)
+Trace Registers : VMIDCVR[idx]
+Notes : Set the VM ID comparator value
+Depends : vmid_idx
+
+File : vmid_masks (rw)
+Trace Registers : VMIDCCTLR0, VMIDCCTLR1, VMIDCVR<0-7>
+Notes : Pair of values to set the byte masks for 1-8 VM ID
+ comparators. Automatically clears masked bytes to 0 in VMID
+ value registers.
+Syntax : 'echo m3m2m1m0 [m7m6m5m4] > vmid_masks'
+ Where mN represents a byte mask value for VMID comparator N.
+ Second value not required on systems that have fewer than
+ 4 VMID comparators.
+
+File : numvmidc (ro)
+Trace Registers : From IDR4
+Notes : Number of VMID comparators
+
+File : res_idx (rw)
+Trace Registers : None.
+Notes : Select the resource selector control to access. Must be 2 or
+ higher as selectors 0 and 1 are hardwired.
+Syntax : 'echo idx > res_idx'
+ Where 2 <= idx < nr_resource x 2
+
+File : res_ctrl (rw)
+Trace Registers : RSCTLR[idx]
+Notes : Set resource selector control value. Value per ETMv4 spec.
+Depends : res_idx
+Syntax : 'echo val > res_cntr'
+ Where val is per ETMv4 spec.
+
+File : nr_resource (ro)
+Trace Registers : From IDR4
+Notes : Number of resource selector pairs
+
+File : event (rw)
+Trace Registers : EVENTCTRL0R
+Notes : Set up to 4 implemented event fields.
+Syntax : 'echo ev3ev2ev1ev0 > event'
+ Where evN is an 8 bit event field. Up to 4 event fields make up
+ the 32bit input value. Number of valid fields implementation
+ dependent defined in IDR0.
+
+File : event_instren (rw)
+Trace Registers : EVENTCTRL1R
+Notes : Choose events which insert event packets into trace stream.
+Depends : EVENTCTRL0R
+Syntax : 'echo bitfield > event_instren'
+ Where bitfield is up to 4 bits according to number of event
+ fields.
+
+File : event_ts (rw)
+Trace Registers : TSCTLR
+Notes : Set the event that will generate timestamp requests.
+Depends : TS activated
+Syntax : 'echo evfield > event_ts'
+ Where evfield is an 8 bit event selector.
+
+File : seq_idx (rw)
+Trace Registers : None
+Notes : Sequencer event register select - 0 to 2
+
+
+File : seq_state (rw)
+Trace Registers : SEQSTR
+Notes : Sequencer current state - 0 to 3.
+
+File : seq_event (rw)
+Trace Registers : SEQEVR[idx]
+Notes : State transition event registers
+Depends : seq_idx
+Syntax : 'echo evBevF > seq_event'
+ Where evBevF is a 16 bit value made up of two event selectors,
+ evB - back, evF - forwards.
+
+File : seq_reset_event (rw)
+Trace Registers : SEQRSTEVR
+Notes : Sequencer reset event
+Syntax : 'echo evfield > seq_reset_event'
+ Where evfield is an 8 bit event selector.
+
+File : nrseqstate (ro)
+Trace Registers : From IDR5
+Notes : Number of sequencer states (0 or 4)
+
+File : nr_pe_cmp (ro)
+Trace Registers : From IDR4
+Notes : Number of PE comparator inputs
+
+File : nr_ext_inp (ro)
+Trace Registers : From IDR5
+Notes : Number of external inputs
+
+File : nr_ss_cmp (ro)
+Trace Registers : From IDR4
+Notes : Number of Single Shot control registers
+
+Note: When programming any address comparator the driver will tag the
+comparator with a type used - i.e. RANGE, SINGLE, START, STOP. Once this tag
+is set, then only the values can be changed using the same sysfs file / type
+used to program it.
+
+Thus:-
+% echo 0 > addr_idx ; select address comparator 0
+% echo 0x1000 0x5000 0 > addr_range ; set address range on comparators 0 and 1.
+% echo 0x2000 > addr_start ; this will error as comparator 0 is a
+ ; range comparator
+% echo 2 > addr_idx ; select address comparator 2
+% echo 0x2000 > addr_start ; this is OK as comparator 2 is unused,
+% echo 0x3000 > addr_stop ; this will error as comparator 2 a start
+ ; address comparator
+% echo 2 > addr_idx ; select address comparator 3
+% echo 0x3000 > addr_stop ; this is OK
+
+To remove programming on all the comparators (and all the other hardware) use
+the reset parameter:
+
+% echo 1 > reset
+
+The ‘mode’ sysfs parameter.
+---------------------------
+
+This is a bitfield selection parameter that sets the overall trace mode for the
+ETM. The table below describes the bits, using the defines from the driver
+source file, along with a description of the feature these represent. Many
+features are optional and therefore dependent on implementation in the
+hardware.
+
+Bit assignements shown below:-
+
+bit (0) : #define ETM_MODE_EXCLUDE
+description : This is the default value for the include / exclude function when
+ setting address ranges. Set 1 for exclude range. When the mode
+ parameter is set this value is applied to the currently indexed
+ address range.
+
+bit (4) : #define ETM_MODE_BB
+description : Set to enable branch broadcast if supported in hardware [IDR0].
+
+bit (5) : #define ETMv4_MODE_CYCACC
+description : Set to enable cycle accurate trace if supported [IDR0].
+
+bit (6) : ETMv4_MODE_CTXID
+description : Set to enable context ID tracing if supported in hardware [IDR2].
+
+bit (7) : ETM_MODE_VMID
+description : Set to enable virtual machine ID tracing if supported [IDR2].
+
+bit (11) : ETMv4_MODE_TIMESTAMP
+description : Set to enable timestamp generation if supported [IDR0].
+
+bit (12) : ETM_MODE_RETURNSTACK
+description : Set to enable trace return stack use if supported [IDR0].
+
+bit (13-14) : ETM_MODE_QELEM(val)
+description : ‘val’ determines level of Q element support enabled if
+ implemented by the ETM [IDR0]
+
+bit (19) : ETM_MODE_ATB_TRIGGER
+description : Set to enable the ATBTRIGGER bit in the event control register
+ [EVENTCTLR1] if supported [IDR5].
+
+bit (20) : ETM_MODE_LPOVERRIDE
+description : Set to enable the LPOVERRIDE bit in the event control register
+ [EVENTCTLR1], if supported [IDR5].
+
+bit (21) : ETM_MODE_ISTALL_EN
+description : Set to enable the ISTALL bit in the stall control register
+ [STALLCTLR]
+
+bit (23) : ETM_MODE_INSTPRIO
+description : Set to enable the INSTPRIORITY bit in the stall control register
+ [STALLCTLR] , if supported [IDR0].
+
+bit (24) : ETM_MODE_NOOVERFLOW
+description : Set to enable the NOOVERFLOW bit in the stall control register
+ [STALLCTLR], if supported [IDR3].
+
+bit (25) : ETM_MODE_TRACE_RESET
+description : Set to enable the TRCRESET bit in the viewinst control register
+ [VICTLR] , if supported [IDR3].
+
+bit (26) : ETM_MODE_TRACE_ERR
+description : Set to enable the TRCCTRL bit in the viewinst control register
+ [VICTLR].
+
+bit (27) : ETM_MODE_VIEWINST_STARTSTOP
+description : Set the initial state value of the ViewInst start / stop logic
+ in the viewinst control register [VICTLR]
+
+bit (30) : ETM_MODE_EXCL_KERN
+description : Set default trace setup to exclude kernel mode trace (see note a)
+
+bit (31) : ETM_MODE_EXCL_USER
+description : Set default trace setup to exclude user space trace (see note a)
+
+Note a) On startup the ETM is programmed to trace the complete address space
+using address range comparator 0. ‘mode’ bits 30 / 31 modify this setting to
+set EL exclude bits for NS state in either user space (EL0) or kernel space
+(EL1) in the address range comparator. (the default setting excludes all
+secure EL, and NS EL2)
+
+Once the reset parameter has been used, and/or custom programming has been
+implemented - using these bits will result in the EL bits for address
+comparator 0 being set in the same way.
+
+Note b) Bits 2-3, 8-10, 15-16, 18, 22, control features that only work with
+data trace. As A profile data trace is architecturally prohibited in ETMv4,
+these have been omitted here. Possible uses could be where a kernel has
+support for control of R or M profile infrastructure as part of a heterogeneous
+system.
+
+Bits 17, 28-29 are unused.
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH v3] scsi: ufs: fix broken hba->outstanding_tasks
From: Martin K. Petersen @ 2019-08-29 21:50 UTC (permalink / raw)
To: Stanley Chu
Cc: linux-scsi, martin.petersen, marc.w.gonzalez, andy.teng,
chun-hung.wu, kuohong.wang, evgreen, avri.altman, linux-mediatek,
peter.wang, alim.akhtar, matthias.bgg, pedrom.sousa,
linux-arm-kernel, beanhuo
In-Reply-To: <1566222208-19890-1-git-send-email-stanley.chu@mediatek.com>
Stanley,
> Currently bits in hba->outstanding_tasks are cleared only after their
> corresponding task management commands are successfully done by
> __ufshcd_issue_tm_cmd().
Applied to 5.4/scsi-queue. Thank you!
--
Martin K. Petersen Oracle Linux Engineering
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v5 10/10] arm64: atomics: Use K constraint when toolchain appears to support it
From: Will Deacon @ 2019-08-29 21:53 UTC (permalink / raw)
To: Nick Desaulniers
Cc: Mark Rutland, Peter Zijlstra, Catalin Marinas, Ard.Biesheuvel,
andrew.murray, Nathan Chancellor, Robin Murphy, Linux ARM
In-Reply-To: <CAKwvOdkaCTQ92hUe823Y14xo_Gft4vsRGgimHc8QPUBCbbAOrQ@mail.gmail.com>
On Thu, Aug 29, 2019 at 10:45:57AM -0700, Nick Desaulniers wrote:
> On Thu, Aug 29, 2019 at 9:55 AM Will Deacon <will@kernel.org> wrote:
> >
> > On Thu, Aug 29, 2019 at 04:48:34PM +0100, Will Deacon wrote:
> > > diff --git a/arch/arm64/include/asm/atomic_ll_sc.h b/arch/arm64/include/asm/atomic_ll_sc.h
> > > index 95091f72228b..7fa042f5444e 100644
> > > --- a/arch/arm64/include/asm/atomic_ll_sc.h
> > > +++ b/arch/arm64/include/asm/atomic_ll_sc.h
> > > @@ -23,6 +23,10 @@ asm_ops "\n" \
> > > #define __LL_SC_FALLBACK(asm_ops) asm_ops
> > > #endif
> > >
> > > +#ifndef CONFIG_CC_HAS_K_CONSTRAINT
> > > +#define K
> > > +#endif
> >
> > Bah, I need to use something like __stringify when the constraint is used
> > in order for this to get expanded properly. Updated diff below.
> >
> > Will
>
> Hi Will, thanks for cc'ing me on the patch set. I'd be happy to help
> test w/ Clang. Would you mind pushing this set with the below diff to
> a publicly available tree+branch I can pull from? (I haven't yet
> figured out how to download multiple diff's from gmail rather than 1
> by 1, and TBH I'd rather just use git).
Sorry, of course. I should've mentioned this in the cover letter:
https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/log/?h=for-next/atomics
FWIW, I did test (defconfig + boot) with clang, but this does mean that LSE
atomics are disabled for that configuration when asm goto is not supported.
Will
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v5 05/10] arm64: atomics: Remove atomic_ll_sc compilation unit
From: Will Deacon @ 2019-08-29 21:54 UTC (permalink / raw)
To: Tri Vo
Cc: Mark Rutland, Peter Zijlstra, Catalin Marinas, Nick Desaulniers,
Ard.Biesheuvel, andrew.murray, Nathan Chancellor, Robin Murphy,
Linux ARM
In-Reply-To: <CANA+-vA8CcSKPU-0Pyaxd5YOprTzqAq9KAZ2Ta1pf-zNdNB3BA@mail.gmail.com>
On Thu, Aug 29, 2019 at 01:07:04PM -0700, Tri Vo wrote:
> On Thu, Aug 29, 2019 at 10:47 AM Nick Desaulniers
> <ndesaulniers@google.com> wrote:
> >
> > On Thu, Aug 29, 2019 at 8:48 AM Will Deacon <will@kernel.org> wrote:
> > >
> > > From: Andrew Murray <andrew.murray@arm.com>
> > >
> > > We no longer fall back to out-of-line atomics on systems with
> > > CONFIG_ARM64_LSE_ATOMICS where ARM64_HAS_LSE_ATOMICS is not set.
> > >
> > > Remove the unused compilation unit which provided these symbols.
> > >
> > > Signed-off-by: Andrew Murray <andrew.murray@arm.com>
> > > Signed-off-by: Will Deacon <will@kernel.org>
> > > ---
> > > arch/arm64/lib/Makefile | 19 -------------------
> > > arch/arm64/lib/atomic_ll_sc.c | 3 ---
> > > 2 files changed, 22 deletions(-)
> > > delete mode 100644 arch/arm64/lib/atomic_ll_sc.c
> > >
> > > diff --git a/arch/arm64/lib/Makefile b/arch/arm64/lib/Makefile
> > > index 33c2a4abda04..f10809ef1690 100644
> > > --- a/arch/arm64/lib/Makefile
> > > +++ b/arch/arm64/lib/Makefile
> > > @@ -11,25 +11,6 @@ CFLAGS_REMOVE_xor-neon.o += -mgeneral-regs-only
> > > CFLAGS_xor-neon.o += -ffreestanding
> > > endif
> > >
> > > -# Tell the compiler to treat all general purpose registers (with the
> > > -# exception of the IP registers, which are already handled by the caller
> > > -# in case of a PLT) as callee-saved, which allows for efficient runtime
> > > -# patching of the bl instruction in the caller with an atomic instruction
> > > -# when supported by the CPU. Result and argument registers are handled
> > > -# correctly, based on the function prototype.
> > > -lib-$(CONFIG_ARM64_LSE_ATOMICS) += atomic_ll_sc.o
> > > -CFLAGS_atomic_ll_sc.o := -ffixed-x1 -ffixed-x2 \
> > > - -ffixed-x3 -ffixed-x4 -ffixed-x5 -ffixed-x6 \
> > > - -ffixed-x7 -fcall-saved-x8 -fcall-saved-x9 \
> > > - -fcall-saved-x10 -fcall-saved-x11 -fcall-saved-x12 \
> > > - -fcall-saved-x13 -fcall-saved-x14 -fcall-saved-x15 \
> > > - -fcall-saved-x18 -fomit-frame-pointer
> >
> > + Tri (who implemented support for -fcall-saved-x*, -ffixed-x* in
> > Clang). I won't be sad to see the use of these flags go.
>
> Nice! IMO these flags made the code hard to read.
Well, we didn't do it like that because it looked pretty ;)
Will
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] drm: dw-hdmi-i2s: enable audio clock in audio_startup
From: Doug Anderson @ 2019-08-29 22:16 UTC (permalink / raw)
To: Cheng-Yi Chiang
Cc: ALSA Development Mailing List, tzungbi, 郑兴,
kuninori.morimoto.gx, Andrzej Hajda, David Airlie,
陈渐飞, LKML, dri-devel,
蔡艺伟, Neil Armstrong,
open list:ARM/Rockchip SoC..., Eddie Cai, Laurent Pinchart,
Daniel Vetter, Enric Balletbo i Serra, Dylan Reid, Sam Ravnborg,
Linux ARM, Jerome Brunet
In-Reply-To: <20190829042957.150929-1-cychiang@chromium.org>
Hi,
On Wed, Aug 28, 2019 at 9:30 PM Cheng-Yi Chiang <cychiang@chromium.org> wrote:
>
> In the designware databook, the sequence of enabling audio clock and
> setting format is not clearly specified.
> Currently, audio clock is enabled in the end of hw_param ops after
> setting format.
>
> On some monitors, there is a possibility that audio does not come out.
> Fix this by enabling audio clock in audio_startup ops
> before hw_param ops setting format.
>
> Signed-off-by: Cheng-Yi Chiang <cychiang@chromium.org>
> ---
> drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
> index 5cbb71a866d5..08b4adbb1ddc 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
> @@ -69,6 +69,14 @@ static int dw_hdmi_i2s_hw_params(struct device *dev, void *data,
> hdmi_write(audio, conf0, HDMI_AUD_CONF0);
> hdmi_write(audio, conf1, HDMI_AUD_CONF1);
>
> + return 0;
> +}
> +
> +static int dw_hdmi_i2s_audio_startup(struct device *dev, void *data)
> +{
> + struct dw_hdmi_i2s_audio_data *audio = data;
> + struct dw_hdmi *hdmi = audio->hdmi;
> +
> dw_hdmi_audio_enable(hdmi);
>
> return 0;
> @@ -105,6 +113,7 @@ static int dw_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
> }
>
> static struct hdmi_codec_ops dw_hdmi_i2s_ops = {
> + .audio_startup = dw_hdmi_i2s_audio_startup,
> .hw_params = dw_hdmi_i2s_hw_params,
> .audio_shutdown = dw_hdmi_i2s_audio_shutdown,
> .get_dai_id = dw_hdmi_i2s_get_dai_id,
> --
I am no expert on audio stuff, but this seems sane to me. If you
happened to spin it for another reason, it might seem slightly nicer
to put the setting of ".audio_startup" adjacent to the setting of
".audio_shutdown" in the struct.
I have tested your patch on Chrome OS 4.19 and it definitely fixes the
problems I saw. Chrome OS 4.19 is a little different than upstream
and I'm not setup to test HDMI audio directly on upstream, but I did
at least confirm that my problem _wasn't_ magically fixed by any of
these patches that I found upstream (I picked them into my tree and
still saw the problem):
fc1ca6e01d0a drm/bridge: dw-hdmi-i2s: add .get_eld support
43e88f670a5e drm/bridge: dw-hdmi-i2s: enable only the required i2s lanes
46cecde310bb drm/bridge: dw-hdmi-i2s: reset audio fifo before applying
new params
0c6098859176 drm/bridge: dw-hdmi-i2s: set the channel allocation
17a1e555b608 drm/bridge: dw-hdmi-i2s: enable lpcm multi channels
da5f5bc92f49 drm/bridge: dw-hdmi: set channel count in the infoframes
2a2a3d2ff799 drm/bridge: dw-hdmi: move audio channel setup out of ahb
8067f62bccaf drm/bridge: dw-hdmi-i2s: support more i2s format
Thus:
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Tested-by: Douglas Anderson <dianders@chromium.org>
-Doug
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH 0/7] Replace Tegra FUSE API by nvmem API
From: Thierry Reding @ 2019-08-29 22:19 UTC (permalink / raw)
To: Thierry Reding
Cc: linux-tegra, Nagarjuna Kristam, linux-arm-kernel, Jon Hunter
From: Thierry Reding <treding@nvidia.com>
The nvmem API provides a generic API to retrieve the kind of information
currently retrieved using the custom Tegra FUSE API. Convert the Tegra
FUSE driver to be an nvmem provider and export cells used by existing
drivers.
The three non-SoC drivers included in this series are meant to serve as
examples for how to use this. I'm not Cc'ing them to the subsystem
maintainers because the idea is to first merge the soc/tegra patches and
after that convert the consumers. Once the first patches are applied, I
will send out the consumers conversion patches to the respective
subsystems.
What's not included in this series is a cleanup patch that finally
removes the custom Tegra FUSE API. I'll follow up with that once these
patches have been applied.
Thierry
Thierry Reding (7):
soc/tegra: fuse: Restore base on sysfs failure
soc/tegra: fuse: Implement nvmem device
soc/tegra: fuse: Add cell information
soc/tegra: fuse: Register cell lookups for compatibility
drm/nouveau: tegra: Use nvmem API
phy: tegra: xusb: Use nvmem API
thermal: tegra: Use nvmem API
.../gpu/drm/nouveau/nvkm/subdev/clk/gm20b.c | 12 +-
drivers/phy/tegra/xusb-tegra124.c | 10 +-
drivers/phy/tegra/xusb-tegra186.c | 7 +-
drivers/phy/tegra/xusb-tegra210.c | 10 +-
drivers/soc/tegra/fuse/fuse-tegra.c | 193 +++++++++++++-----
drivers/soc/tegra/fuse/fuse-tegra30.c | 154 ++++++++++++++
drivers/soc/tegra/fuse/fuse.h | 8 +
drivers/thermal/tegra/soctherm-fuse.c | 19 +-
drivers/thermal/tegra/soctherm.c | 4 +-
drivers/thermal/tegra/soctherm.h | 9 +-
drivers/thermal/tegra/tegra124-soctherm.c | 8 -
drivers/thermal/tegra/tegra132-soctherm.c | 8 -
drivers/thermal/tegra/tegra210-soctherm.c | 8 -
13 files changed, 344 insertions(+), 106 deletions(-)
--
2.22.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH 1/7] soc/tegra: fuse: Restore base on sysfs failure
From: Thierry Reding @ 2019-08-29 22:19 UTC (permalink / raw)
To: Thierry Reding
Cc: linux-tegra, Nagarjuna Kristam, linux-arm-kernel, Jon Hunter
In-Reply-To: <20190829221911.24876-1-thierry.reding@gmail.com>
From: Thierry Reding <treding@nvidia.com>
Make sure to also restore the register base address on sysfs
registration failure.
Signed-off-by: Thierry Reding <treding@nvidia.com>
---
drivers/soc/tegra/fuse/fuse-tegra.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c
index 3eb44e65b326..6617a4bd11bb 100644
--- a/drivers/soc/tegra/fuse/fuse-tegra.c
+++ b/drivers/soc/tegra/fuse/fuse-tegra.c
@@ -146,20 +146,24 @@ static int tegra_fuse_probe(struct platform_device *pdev)
if (fuse->soc->probe) {
err = fuse->soc->probe(fuse);
- if (err < 0) {
- fuse->base = base;
- return err;
- }
+ if (err < 0)
+ goto restore;
}
if (tegra_fuse_create_sysfs(&pdev->dev, fuse->soc->info->size,
- fuse->soc->info))
- return -ENODEV;
+ fuse->soc->info)) {
+ err = -ENODEV;
+ goto restore;
+ }
/* release the early I/O memory mapping */
iounmap(base);
return 0;
+
+restore:
+ fuse->base = base;
+ return err;
}
static struct platform_driver tegra_fuse_driver = {
--
2.22.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 2/7] soc/tegra: fuse: Implement nvmem device
From: Thierry Reding @ 2019-08-29 22:19 UTC (permalink / raw)
To: Thierry Reding
Cc: linux-tegra, Nagarjuna Kristam, linux-arm-kernel, Jon Hunter
In-Reply-To: <20190829221911.24876-1-thierry.reding@gmail.com>
From: Thierry Reding <treding@nvidia.com>
The nvmem framework provides a generic infrastructure and API to access
the type of information stored in fuses such as the Tegra FUSE block.
Implement an nvmem device that can be used to access the information in
a more generic way to decouple consumers from the custom Tegra API and
to add a more formal way of creating the dependency between the FUSE
device and the consumers.
Signed-off-by: Thierry Reding <treding@nvidia.com>
---
drivers/soc/tegra/fuse/fuse-tegra.c | 82 ++++++++++++-----------------
drivers/soc/tegra/fuse/fuse.h | 3 ++
2 files changed, 38 insertions(+), 47 deletions(-)
diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c
index 6617a4bd11bb..3ce2138b278b 100644
--- a/drivers/soc/tegra/fuse/fuse-tegra.c
+++ b/drivers/soc/tegra/fuse/fuse-tegra.c
@@ -8,6 +8,8 @@
#include <linux/kobject.h>
#include <linux/init.h>
#include <linux/io.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/nvmem-provider.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
@@ -31,50 +33,6 @@ static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {
[TEGRA_REVISION_A04] = "A04",
};
-static u8 fuse_readb(struct tegra_fuse *fuse, unsigned int offset)
-{
- u32 val;
-
- val = fuse->read(fuse, round_down(offset, 4));
- val >>= (offset % 4) * 8;
- val &= 0xff;
-
- return val;
-}
-
-static ssize_t fuse_read(struct file *fd, struct kobject *kobj,
- struct bin_attribute *attr, char *buf,
- loff_t pos, size_t size)
-{
- struct device *dev = kobj_to_dev(kobj);
- struct tegra_fuse *fuse = dev_get_drvdata(dev);
- int i;
-
- if (pos < 0 || pos >= attr->size)
- return 0;
-
- if (size > attr->size - pos)
- size = attr->size - pos;
-
- for (i = 0; i < size; i++)
- buf[i] = fuse_readb(fuse, pos + i);
-
- return i;
-}
-
-static struct bin_attribute fuse_bin_attr = {
- .attr = { .name = "fuse", .mode = S_IRUGO, },
- .read = fuse_read,
-};
-
-static int tegra_fuse_create_sysfs(struct device *dev, unsigned int size,
- const struct tegra_fuse_info *info)
-{
- fuse_bin_attr.size = size;
-
- return device_create_bin_file(dev, &fuse_bin_attr);
-}
-
static const struct of_device_id car_match[] __initconst = {
{ .compatible = "nvidia,tegra20-car", },
{ .compatible = "nvidia,tegra30-car", },
@@ -115,9 +73,23 @@ static const struct of_device_id tegra_fuse_match[] = {
{ /* sentinel */ }
};
+static int tegra_fuse_read(void *priv, unsigned int offset, void *value,
+ size_t bytes)
+{
+ unsigned int count = bytes / 4, i;
+ struct tegra_fuse *fuse = priv;
+ u32 *buffer = value;
+
+ for (i = 0; i < count; i++)
+ buffer[i] = fuse->read(fuse, offset + i * 4);
+
+ return 0;
+}
+
static int tegra_fuse_probe(struct platform_device *pdev)
{
void __iomem *base = fuse->base;
+ struct nvmem_config nvmem;
struct resource *res;
int err;
@@ -150,9 +122,25 @@ static int tegra_fuse_probe(struct platform_device *pdev)
goto restore;
}
- if (tegra_fuse_create_sysfs(&pdev->dev, fuse->soc->info->size,
- fuse->soc->info)) {
- err = -ENODEV;
+ memset(&nvmem, 0, sizeof(nvmem));
+ nvmem.dev = &pdev->dev;
+ nvmem.name = "fuse";
+ nvmem.id = -1;
+ nvmem.owner = THIS_MODULE;
+ nvmem.type = NVMEM_TYPE_OTP;
+ nvmem.read_only = true;
+ nvmem.root_only = true;
+ nvmem.reg_read = tegra_fuse_read;
+ nvmem.size = fuse->soc->info->size;
+ nvmem.word_size = 4;
+ nvmem.stride = 4;
+ nvmem.priv = fuse;
+
+ fuse->nvmem = devm_nvmem_register(&pdev->dev, &nvmem);
+ if (IS_ERR(fuse->nvmem)) {
+ err = PTR_ERR(fuse->nvmem);
+ dev_err(&pdev->dev, "failed to register NVMEM device: %d\n",
+ err);
goto restore;
}
diff --git a/drivers/soc/tegra/fuse/fuse.h b/drivers/soc/tegra/fuse/fuse.h
index 7230cb330503..32bf6c070ae7 100644
--- a/drivers/soc/tegra/fuse/fuse.h
+++ b/drivers/soc/tegra/fuse/fuse.h
@@ -13,6 +13,7 @@
#include <linux/dmaengine.h>
#include <linux/types.h>
+struct nvmem_device;
struct tegra_fuse;
struct tegra_fuse_info {
@@ -48,6 +49,8 @@ struct tegra_fuse {
dma_addr_t phys;
u32 *virt;
} apbdma;
+
+ struct nvmem_device *nvmem;
};
void tegra_init_revision(void);
--
2.22.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 3/7] soc/tegra: fuse: Add cell information
From: Thierry Reding @ 2019-08-29 22:19 UTC (permalink / raw)
To: Thierry Reding
Cc: linux-tegra, Nagarjuna Kristam, linux-arm-kernel, Jon Hunter
In-Reply-To: <20190829221911.24876-1-thierry.reding@gmail.com>
From: Thierry Reding <treding@nvidia.com>
Create nvmem cells for all the fuses currently used by consumers.
Signed-off-by: Thierry Reding <treding@nvidia.com>
---
drivers/soc/tegra/fuse/fuse-tegra.c | 90 +++++++++++++++++++++++++++++
1 file changed, 90 insertions(+)
diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c
index 3ce2138b278b..c6c6a7746046 100644
--- a/drivers/soc/tegra/fuse/fuse-tegra.c
+++ b/drivers/soc/tegra/fuse/fuse-tegra.c
@@ -86,6 +86,94 @@ static int tegra_fuse_read(void *priv, unsigned int offset, void *value,
return 0;
}
+static const struct nvmem_cell_info tegra_fuse_cells[] = {
+ {
+ .name = "tsensor-cpu1",
+ .offset = 0x084,
+ .bytes = 4,
+ .bit_offset = 0,
+ .nbits = 32,
+ }, {
+ .name = "tsensor-cpu2",
+ .offset = 0x088,
+ .bytes = 4,
+ .bit_offset = 0,
+ .nbits = 32,
+ }, {
+ .name = "tsensor-cpu0",
+ .offset = 0x098,
+ .bytes = 4,
+ .bit_offset = 0,
+ .nbits = 32,
+ }, {
+ .name = "xusb-pad-calibration",
+ .offset = 0x0f0,
+ .bytes = 4,
+ .bit_offset = 0,
+ .nbits = 32,
+ }, {
+ .name = "tsensor-cpu3",
+ .offset = 0x12c,
+ .bytes = 4,
+ .bit_offset = 0,
+ .nbits = 32,
+ }, {
+ .name = "sata-calibration",
+ .offset = 0x124,
+ .bytes = 1,
+ .bit_offset = 0,
+ .nbits = 2,
+ }, {
+ .name = "tsensor-gpu",
+ .offset = 0x154,
+ .bytes = 4,
+ .bit_offset = 0,
+ .nbits = 32,
+ }, {
+ .name = "tsensor-mem0",
+ .offset = 0x158,
+ .bytes = 4,
+ .bit_offset = 0,
+ .nbits = 32,
+ }, {
+ .name = "tsensor-mem1",
+ .offset = 0x15c,
+ .bytes = 4,
+ .bit_offset = 0,
+ .nbits = 32,
+ }, {
+ .name = "tsensor-pllx",
+ .offset = 0x160,
+ .bytes = 4,
+ .bit_offset = 0,
+ .nbits = 32,
+ }, {
+ .name = "tsensor-common",
+ .offset = 0x180,
+ .bytes = 4,
+ .bit_offset = 0,
+ .nbits = 32,
+ }, {
+ .name = "tsensor-realignment",
+ .offset = 0x1fc,
+ .bytes = 4,
+ .bit_offset = 0,
+ .nbits = 32,
+ }, {
+ .name = "gpu-calibration",
+ .offset = 0x204,
+ .bytes = 4,
+ .bit_offset = 0,
+ .nbits = 32,
+ }, {
+ .name = "xusb-pad-calibration-ext",
+ .offset = 0x250,
+ .bytes = 4,
+ .bit_offset = 0,
+ .nbits = 32,
+ },
+};
+
static int tegra_fuse_probe(struct platform_device *pdev)
{
void __iomem *base = fuse->base;
@@ -127,6 +215,8 @@ static int tegra_fuse_probe(struct platform_device *pdev)
nvmem.name = "fuse";
nvmem.id = -1;
nvmem.owner = THIS_MODULE;
+ nvmem.cells = tegra_fuse_cells;
+ nvmem.ncells = ARRAY_SIZE(tegra_fuse_cells);
nvmem.type = NVMEM_TYPE_OTP;
nvmem.read_only = true;
nvmem.root_only = true;
--
2.22.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 4/7] soc/tegra: fuse: Register cell lookups for compatibility
From: Thierry Reding @ 2019-08-29 22:19 UTC (permalink / raw)
To: Thierry Reding
Cc: linux-tegra, Nagarjuna Kristam, linux-arm-kernel, Jon Hunter
In-Reply-To: <20190829221911.24876-1-thierry.reding@gmail.com>
From: Thierry Reding <treding@nvidia.com>
Typically nvmem cells would be stored in device tree. However, for
compatibility with device trees that don't contain nvmem cell
definitions, register lookups for cells currently used by consumers.
This allows the consumers to use the same API to query cells from the
device tree or using the legacy mechanism.
Signed-off-by: Thierry Reding <treding@nvidia.com>
---
drivers/soc/tegra/fuse/fuse-tegra.c | 9 ++
drivers/soc/tegra/fuse/fuse-tegra30.c | 154 ++++++++++++++++++++++++++
drivers/soc/tegra/fuse/fuse.h | 5 +
3 files changed, 168 insertions(+)
diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c
index c6c6a7746046..6a0e25103e1c 100644
--- a/drivers/soc/tegra/fuse/fuse-tegra.c
+++ b/drivers/soc/tegra/fuse/fuse-tegra.c
@@ -420,6 +420,15 @@ static int __init tegra_init_fuse(void)
pr_debug("Tegra CPU Speedo ID %d, SoC Speedo ID %d\n",
tegra_sku_info.cpu_speedo_id, tegra_sku_info.soc_speedo_id);
+ if (fuse->soc->lookups) {
+ size_t size = sizeof(*fuse->lookups) * fuse->soc->num_lookups;
+
+ fuse->lookups = kmemdup(fuse->soc->lookups, size, GFP_KERNEL);
+ if (!fuse->lookups)
+ return -ENOMEM;
+
+ nvmem_add_cell_lookups(fuse->lookups, fuse->soc->num_lookups);
+ }
return 0;
}
diff --git a/drivers/soc/tegra/fuse/fuse-tegra30.c b/drivers/soc/tegra/fuse/fuse-tegra30.c
index be9424a87173..b8daaf5b7291 100644
--- a/drivers/soc/tegra/fuse/fuse-tegra30.c
+++ b/drivers/soc/tegra/fuse/fuse-tegra30.c
@@ -8,6 +8,7 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/kernel.h>
+#include <linux/nvmem-consumer.h>
#include <linux/of_device.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
@@ -127,6 +128,70 @@ const struct tegra_fuse_soc tegra114_fuse_soc = {
#endif
#if defined(CONFIG_ARCH_TEGRA_124_SOC) || defined(CONFIG_ARCH_TEGRA_132_SOC)
+static const struct nvmem_cell_lookup tegra124_fuse_lookups[] = {
+ {
+ .nvmem_name = "fuse",
+ .cell_name = "xusb-pad-calibration",
+ .dev_id = "7009f000.padctl",
+ .con_id = "calibration",
+ }, {
+ .nvmem_name = "fuse",
+ .cell_name = "sata-calibration",
+ .dev_id = "70020000.sata",
+ .con_id = "calibration",
+ }, {
+ .nvmem_name = "fuse",
+ .cell_name = "tsensor-common",
+ .dev_id = "700e2000.thermal-sensor",
+ .con_id = "common",
+ }, {
+ .nvmem_name = "fuse",
+ .cell_name = "tsensor-realignment",
+ .dev_id = "700e2000.thermal-sensor",
+ .con_id = "realignment",
+ }, {
+ .nvmem_name = "fuse",
+ .cell_name = "tsensor-cpu0",
+ .dev_id = "700e2000.thermal-sensor",
+ .con_id = "cpu0",
+ }, {
+ .nvmem_name = "fuse",
+ .cell_name = "tsensor-cpu1",
+ .dev_id = "700e2000.thermal-sensor",
+ .con_id = "cpu1",
+ }, {
+ .nvmem_name = "fuse",
+ .cell_name = "tsensor-cpu2",
+ .dev_id = "700e2000.thermal-sensor",
+ .con_id = "cpu2",
+ }, {
+ .nvmem_name = "fuse",
+ .cell_name = "tsensor-cpu3",
+ .dev_id = "700e2000.thermal-sensor",
+ .con_id = "cpu3",
+ }, {
+ .nvmem_name = "fuse",
+ .cell_name = "tsensor-mem0",
+ .dev_id = "700e2000.thermal-sensor",
+ .con_id = "mem0",
+ }, {
+ .nvmem_name = "fuse",
+ .cell_name = "tsensor-mem1",
+ .dev_id = "700e2000.thermal-sensor",
+ .con_id = "mem1",
+ }, {
+ .nvmem_name = "fuse",
+ .cell_name = "tsensor-gpu",
+ .dev_id = "700e2000.thermal-sensor",
+ .con_id = "gpu",
+ }, {
+ .nvmem_name = "fuse",
+ .cell_name = "tsensor-pllx",
+ .dev_id = "700e2000.thermal-sensor",
+ .con_id = "pllx",
+ },
+};
+
static const struct tegra_fuse_info tegra124_fuse_info = {
.read = tegra30_fuse_read,
.size = 0x300,
@@ -137,10 +202,81 @@ const struct tegra_fuse_soc tegra124_fuse_soc = {
.init = tegra30_fuse_init,
.speedo_init = tegra124_init_speedo_data,
.info = &tegra124_fuse_info,
+ .lookups = tegra124_fuse_lookups,
+ .num_lookups = ARRAY_SIZE(tegra124_fuse_lookups),
};
#endif
#if defined(CONFIG_ARCH_TEGRA_210_SOC)
+static const struct nvmem_cell_lookup tegra210_fuse_lookups[] = {
+ {
+ .nvmem_name = "fuse",
+ .cell_name = "tsensor-cpu1",
+ .dev_id = "700e2000.thermal-sensor",
+ .con_id = "cpu1",
+ }, {
+ .nvmem_name = "fuse",
+ .cell_name = "tsensor-cpu2",
+ .dev_id = "700e2000.thermal-sensor",
+ .con_id = "cpu2",
+ }, {
+ .nvmem_name = "fuse",
+ .cell_name = "tsensor-cpu0",
+ .dev_id = "700e2000.thermal-sensor",
+ .con_id = "cpu0",
+ }, {
+ .nvmem_name = "fuse",
+ .cell_name = "xusb-pad-calibration",
+ .dev_id = "7009f000.padctl",
+ .con_id = "calibration",
+ }, {
+ .nvmem_name = "fuse",
+ .cell_name = "tsensor-cpu3",
+ .dev_id = "700e2000.thermal-sensor",
+ .con_id = "cpu3",
+ }, {
+ .nvmem_name = "fuse",
+ .cell_name = "sata-calibration",
+ .dev_id = "70020000.sata",
+ .con_id = "calibration",
+ }, {
+ .nvmem_name = "fuse",
+ .cell_name = "tsensor-gpu",
+ .dev_id = "700e2000.thermal-sensor",
+ .con_id = "gpu",
+ }, {
+ .nvmem_name = "fuse",
+ .cell_name = "tsensor-mem0",
+ .dev_id = "700e2000.thermal-sensor",
+ .con_id = "mem0",
+ }, {
+ .nvmem_name = "fuse",
+ .cell_name = "tsensor-mem1",
+ .dev_id = "700e2000.thermal-sensor",
+ .con_id = "mem1",
+ }, {
+ .nvmem_name = "fuse",
+ .cell_name = "tsensor-pllx",
+ .dev_id = "700e2000.thermal-sensor",
+ .con_id = "pllx",
+ }, {
+ .nvmem_name = "fuse",
+ .cell_name = "tsensor-common",
+ .dev_id = "700e2000.thermal-sensor",
+ .con_id = "common",
+ }, {
+ .nvmem_name = "fuse",
+ .cell_name = "gpu-calibration",
+ .dev_id = "57000000.gpu",
+ .con_id = "calibration",
+ }, {
+ .nvmem_name = "fuse",
+ .cell_name = "xusb-pad-calibration-ext",
+ .dev_id = "7009f000.padctl",
+ .con_id = "calibration-ext",
+ },
+};
+
static const struct tegra_fuse_info tegra210_fuse_info = {
.read = tegra30_fuse_read,
.size = 0x300,
@@ -151,10 +287,26 @@ const struct tegra_fuse_soc tegra210_fuse_soc = {
.init = tegra30_fuse_init,
.speedo_init = tegra210_init_speedo_data,
.info = &tegra210_fuse_info,
+ .lookups = tegra210_fuse_lookups,
+ .num_lookups = ARRAY_SIZE(tegra210_fuse_lookups),
};
#endif
#if defined(CONFIG_ARCH_TEGRA_186_SOC)
+static const struct nvmem_cell_lookup tegra186_fuse_lookups[] = {
+ {
+ .nvmem_name = "fuse",
+ .cell_name = "xusb-pad-calibration",
+ .dev_id = "3520000.padctl",
+ .con_id = "calibration",
+ }, {
+ .nvmem_name = "fuse",
+ .cell_name = "xusb-pad-calibration-ext",
+ .dev_id = "3520000.padctl",
+ .con_id = "calibration-ext",
+ },
+};
+
static const struct tegra_fuse_info tegra186_fuse_info = {
.read = tegra30_fuse_read,
.size = 0x300,
@@ -164,5 +316,7 @@ static const struct tegra_fuse_info tegra186_fuse_info = {
const struct tegra_fuse_soc tegra186_fuse_soc = {
.init = tegra30_fuse_init,
.info = &tegra186_fuse_info,
+ .lookups = tegra186_fuse_lookups,
+ .num_lookups = ARRAY_SIZE(tegra186_fuse_lookups),
};
#endif
diff --git a/drivers/soc/tegra/fuse/fuse.h b/drivers/soc/tegra/fuse/fuse.h
index 32bf6c070ae7..0f74c2c34af0 100644
--- a/drivers/soc/tegra/fuse/fuse.h
+++ b/drivers/soc/tegra/fuse/fuse.h
@@ -13,6 +13,7 @@
#include <linux/dmaengine.h>
#include <linux/types.h>
+struct nvmem_cell_lookup;
struct nvmem_device;
struct tegra_fuse;
@@ -28,6 +29,9 @@ struct tegra_fuse_soc {
int (*probe)(struct tegra_fuse *fuse);
const struct tegra_fuse_info *info;
+
+ const struct nvmem_cell_lookup *lookups;
+ unsigned int num_lookups;
};
struct tegra_fuse {
@@ -51,6 +55,7 @@ struct tegra_fuse {
} apbdma;
struct nvmem_device *nvmem;
+ struct nvmem_cell_lookup *lookups;
};
void tegra_init_revision(void);
--
2.22.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 5/7] drm/nouveau: tegra: Use nvmem API
From: Thierry Reding @ 2019-08-29 22:19 UTC (permalink / raw)
To: Thierry Reding
Cc: linux-tegra, Nagarjuna Kristam, linux-arm-kernel, Jon Hunter
In-Reply-To: <20190829221911.24876-1-thierry.reding@gmail.com>
From: Thierry Reding <treding@nvidia.com>
Instead of using the custom Tegra FUSE API to read the calibration fuse
for the clock on GM20B, use the nvmem API. This makes the dependency
between the two devices more explicit and decouples the driver from one
another.
Signed-off-by: Thierry Reding <treding@nvidia.com>
---
drivers/gpu/drm/nouveau/nvkm/subdev/clk/gm20b.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gm20b.c
index b284e949f732..096a8b4b9bb5 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gm20b.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gm20b.c
@@ -20,6 +20,8 @@
* DEALINGS IN THE SOFTWARE.
*/
+#include <linux/nvmem-consumer.h>
+
#include <subdev/clk.h>
#include <subdev/volt.h>
#include <subdev/timer.h>
@@ -929,7 +931,6 @@ gm20b_clk_new_speedo0(struct nvkm_device *device, int index,
}
/* FUSE register */
-#define FUSE_RESERVED_CALIB0 0x204
#define FUSE_RESERVED_CALIB0_INTERCEPT_FRAC_SHIFT 0
#define FUSE_RESERVED_CALIB0_INTERCEPT_FRAC_WIDTH 4
#define FUSE_RESERVED_CALIB0_INTERCEPT_INT_SHIFT 4
@@ -945,14 +946,17 @@ static int
gm20b_clk_init_fused_params(struct gm20b_clk *clk)
{
struct nvkm_subdev *subdev = &clk->base.base.subdev;
+ struct nvkm_device *device = subdev->device;
u32 val = 0;
u32 rev = 0;
+ int ret;
+
+ ret = nvmem_cell_read_u32(device->dev, "calibration", &val);
+ if (ret < 0)
+ return ret;
-#if IS_ENABLED(CONFIG_ARCH_TEGRA)
- tegra_fuse_readl(FUSE_RESERVED_CALIB0, &val);
rev = (val >> FUSE_RESERVED_CALIB0_FUSE_REV_SHIFT) &
MASK(FUSE_RESERVED_CALIB0_FUSE_REV_WIDTH);
-#endif
/* No fused parameters, we will calibrate later */
if (rev == 0)
--
2.22.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 6/7] phy: tegra: xusb: Use nvmem API
From: Thierry Reding @ 2019-08-29 22:19 UTC (permalink / raw)
To: Thierry Reding
Cc: linux-tegra, Nagarjuna Kristam, linux-arm-kernel, Jon Hunter
In-Reply-To: <20190829221911.24876-1-thierry.reding@gmail.com>
From: Thierry Reding <treding@nvidia.com>
Instead of using the custom Tegra FUSE API to read the calibration fuses
for the UPHY, use the nvmem API. This makes the dependency between the
two devices more explicit and decouples the drivers from one another.
Signed-off-by: Thierry Reding <treding@nvidia.com>
---
drivers/phy/tegra/xusb-tegra124.c | 10 +++++-----
drivers/phy/tegra/xusb-tegra186.c | 7 +++----
drivers/phy/tegra/xusb-tegra210.c | 10 ++++++----
3 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/drivers/phy/tegra/xusb-tegra124.c b/drivers/phy/tegra/xusb-tegra124.c
index 98d84920c676..f62905ea4ca5 100644
--- a/drivers/phy/tegra/xusb-tegra124.c
+++ b/drivers/phy/tegra/xusb-tegra124.c
@@ -7,6 +7,7 @@
#include <linux/io.h>
#include <linux/mailbox_client.h>
#include <linux/module.h>
+#include <linux/nvmem-consumer.h>
#include <linux/of.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
@@ -14,8 +15,6 @@
#include <linux/reset.h>
#include <linux/slab.h>
-#include <soc/tegra/fuse.h>
-
#include "xusb.h"
#define FUSE_SKU_CALIB_HS_CURR_LEVEL_PADX_SHIFT(x) ((x) ? 15 : 0)
@@ -1653,13 +1652,14 @@ static const struct tegra_xusb_port_ops tegra124_usb3_port_ops = {
};
static int
-tegra124_xusb_read_fuse_calibration(struct tegra124_xusb_fuse_calibration *fuse)
+tegra124_xusb_read_fuse_calibration(struct tegra124_xusb_padctl *padctl)
{
+ struct tegra124_xusb_fuse_calibration *fuse = &padctl->fuse;
unsigned int i;
int err;
u32 value;
- err = tegra_fuse_readl(TEGRA_FUSE_SKU_CALIB_0, &value);
+ err = nvmem_cell_read_u32(padctl->base.dev, "calibration", &value);
if (err < 0)
return err;
@@ -1695,7 +1695,7 @@ tegra124_xusb_padctl_probe(struct device *dev,
padctl->base.dev = dev;
padctl->base.soc = soc;
- err = tegra124_xusb_read_fuse_calibration(&padctl->fuse);
+ err = tegra124_xusb_read_fuse_calibration(padctl);
if (err < 0)
return ERR_PTR(err);
diff --git a/drivers/phy/tegra/xusb-tegra186.c b/drivers/phy/tegra/xusb-tegra186.c
index 6f3afaf9398f..0663ed00d748 100644
--- a/drivers/phy/tegra/xusb-tegra186.c
+++ b/drivers/phy/tegra/xusb-tegra186.c
@@ -6,6 +6,7 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/module.h>
+#include <linux/nvmem-consumer.h>
#include <linux/of.h>
#include <linux/phy/phy.h>
#include <linux/regulator/consumer.h>
@@ -13,8 +14,6 @@
#include <linux/clk.h>
#include <linux/slab.h>
-#include <soc/tegra/fuse.h>
-
#include "xusb.h"
/* FUSE USB_CALIB registers */
@@ -800,7 +799,7 @@ tegra186_xusb_read_fuse_calibration(struct tegra186_xusb_padctl *padctl)
if (!level)
return -ENOMEM;
- err = tegra_fuse_readl(TEGRA_FUSE_SKU_CALIB_0, &value);
+ err = nvmem_cell_read_u32(dev, "calibration", &value);
if (err) {
dev_err(dev, "failed to read calibration fuse: %d\n", err);
return err;
@@ -819,7 +818,7 @@ tegra186_xusb_read_fuse_calibration(struct tegra186_xusb_padctl *padctl)
padctl->calib.hs_term_range_adj = (value >> HS_TERM_RANGE_ADJ_SHIFT) &
HS_TERM_RANGE_ADJ_MASK;
- err = tegra_fuse_readl(TEGRA_FUSE_USB_CALIB_EXT_0, &value);
+ err = nvmem_cell_read_u32(dev, "calibration-ext", &value);
if (err) {
dev_err(dev, "failed to read calibration fuse: %d\n", err);
return err;
diff --git a/drivers/phy/tegra/xusb-tegra210.c b/drivers/phy/tegra/xusb-tegra210.c
index 0c0df6897a3b..659b62867012 100644
--- a/drivers/phy/tegra/xusb-tegra210.c
+++ b/drivers/phy/tegra/xusb-tegra210.c
@@ -10,6 +10,7 @@
#include <linux/io.h>
#include <linux/mailbox_client.h>
#include <linux/module.h>
+#include <linux/nvmem-consumer.h>
#include <linux/of.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
@@ -1946,13 +1947,14 @@ static const struct tegra_xusb_port_ops tegra210_usb3_port_ops = {
};
static int
-tegra210_xusb_read_fuse_calibration(struct tegra210_xusb_fuse_calibration *fuse)
+tegra210_xusb_read_fuse_calibration(struct tegra210_xusb_padctl *padctl)
{
+ struct tegra210_xusb_fuse_calibration *fuse = &padctl->fuse;
unsigned int i;
u32 value;
int err;
- err = tegra_fuse_readl(TEGRA_FUSE_SKU_CALIB_0, &value);
+ err = nvmem_cell_read_u32(padctl->base.dev, "calibration", &value);
if (err < 0)
return err;
@@ -1966,7 +1968,7 @@ tegra210_xusb_read_fuse_calibration(struct tegra210_xusb_fuse_calibration *fuse)
(value >> FUSE_SKU_CALIB_HS_TERM_RANGE_ADJ_SHIFT) &
FUSE_SKU_CALIB_HS_TERM_RANGE_ADJ_MASK;
- err = tegra_fuse_readl(TEGRA_FUSE_USB_CALIB_EXT_0, &value);
+ err = nvmem_cell_read_u32(padctl->base.dev, "calibration-ext", &value);
if (err < 0)
return err;
@@ -1991,7 +1993,7 @@ tegra210_xusb_padctl_probe(struct device *dev,
padctl->base.dev = dev;
padctl->base.soc = soc;
- err = tegra210_xusb_read_fuse_calibration(&padctl->fuse);
+ err = tegra210_xusb_read_fuse_calibration(padctl);
if (err < 0)
return ERR_PTR(err);
--
2.22.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 7/7] thermal: tegra: Use nvmem API
From: Thierry Reding @ 2019-08-29 22:19 UTC (permalink / raw)
To: Thierry Reding
Cc: linux-tegra, Nagarjuna Kristam, linux-arm-kernel, Jon Hunter
In-Reply-To: <20190829221911.24876-1-thierry.reding@gmail.com>
From: Thierry Reding <treding@nvidia.com>
Instead of using the custom Tegra FUSE API to read the fuses for TSENSOR
configuration, use the nvmem API. This makes the dependency between the
two devices more explicit and decouples the driver from one another.
Signed-off-by: Thierry Reding <treding@nvidia.com>
---
drivers/thermal/tegra/soctherm-fuse.c | 19 ++++++++++---------
drivers/thermal/tegra/soctherm.c | 4 ++--
drivers/thermal/tegra/soctherm.h | 9 ++++++---
drivers/thermal/tegra/tegra124-soctherm.c | 8 --------
drivers/thermal/tegra/tegra132-soctherm.c | 8 --------
drivers/thermal/tegra/tegra210-soctherm.c | 8 --------
6 files changed, 18 insertions(+), 38 deletions(-)
diff --git a/drivers/thermal/tegra/soctherm-fuse.c b/drivers/thermal/tegra/soctherm-fuse.c
index 190f95280e0b..c63bef809004 100644
--- a/drivers/thermal/tegra/soctherm-fuse.c
+++ b/drivers/thermal/tegra/soctherm-fuse.c
@@ -4,6 +4,7 @@
*/
#include <linux/module.h>
+#include <linux/nvmem-consumer.h>
#include <linux/platform_device.h>
#include <soc/tegra/fuse.h>
@@ -70,14 +71,15 @@ static s64 div64_s64_precise(s64 a, s32 b)
return r >> 16;
}
-int tegra_calc_shared_calib(const struct tegra_soctherm_fuse *tfuse,
+int tegra_calc_shared_calib(struct device *dev,
+ const struct tegra_soctherm_fuse *tfuse,
struct tsensor_shared_calib *shared)
{
u32 val;
s32 shifted_cp, shifted_ft;
int err;
- err = tegra_fuse_readl(FUSE_TSENSOR_COMMON, &val);
+ err = nvmem_cell_read_u32(dev, "common", &val);
if (err)
return err;
@@ -90,11 +92,9 @@ int tegra_calc_shared_calib(const struct tegra_soctherm_fuse *tfuse,
tfuse->fuse_shift_ft_shift;
shifted_ft = sign_extend32(shifted_ft, 4);
- if (tfuse->fuse_spare_realignment) {
- err = tegra_fuse_readl(tfuse->fuse_spare_realignment, &val);
- if (err)
- return err;
- }
+ err = nvmem_cell_read_u32(dev, "realignment", &val);
+ if (err != -ENOENT)
+ return err;
shifted_cp = sign_extend32(val, 5);
@@ -104,7 +104,8 @@ int tegra_calc_shared_calib(const struct tegra_soctherm_fuse *tfuse,
return 0;
}
-int tegra_calc_tsensor_calib(const struct tegra_tsensor *sensor,
+int tegra_calc_tsensor_calib(struct device *dev,
+ const struct tegra_tsensor *sensor,
const struct tsensor_shared_calib *shared,
u32 *calibration)
{
@@ -119,7 +120,7 @@ int tegra_calc_tsensor_calib(const struct tegra_tsensor *sensor,
sensor_group = sensor->group;
- err = tegra_fuse_readl(sensor->calib_fuse_offset, &val);
+ err = nvmem_cell_read_u32(dev, sensor->name, &val);
if (err)
return err;
diff --git a/drivers/thermal/tegra/soctherm.c b/drivers/thermal/tegra/soctherm.c
index 43941eb734eb..e632888ff1ae 100644
--- a/drivers/thermal/tegra/soctherm.c
+++ b/drivers/thermal/tegra/soctherm.c
@@ -2180,13 +2180,13 @@ static int tegra_soctherm_probe(struct platform_device *pdev)
return -ENOMEM;
/* calculate shared calibration data */
- err = tegra_calc_shared_calib(soc->tfuse, &shared_calib);
+ err = tegra_calc_shared_calib(&pdev->dev, soc->tfuse, &shared_calib);
if (err)
return err;
/* calculate tsensor calibaration data */
for (i = 0; i < soc->num_tsensors; ++i) {
- err = tegra_calc_tsensor_calib(&soc->tsensors[i],
+ err = tegra_calc_tsensor_calib(&pdev->dev, &soc->tsensors[i],
&shared_calib,
&tegra->calib[i]);
if (err)
diff --git a/drivers/thermal/tegra/soctherm.h b/drivers/thermal/tegra/soctherm.h
index 70501e73d586..715b4f06e162 100644
--- a/drivers/thermal/tegra/soctherm.h
+++ b/drivers/thermal/tegra/soctherm.h
@@ -93,7 +93,6 @@ struct tegra_tsensor {
const char *name;
const u32 base;
const struct tegra_tsensor_configuration *config;
- const u32 calib_fuse_offset;
/*
* Correction values used to modify values read from
* calibration fuses
@@ -131,9 +130,13 @@ struct tegra_soctherm_soc {
struct tsensor_group_thermtrips *thermtrips;
};
-int tegra_calc_shared_calib(const struct tegra_soctherm_fuse *tfuse,
+struct tegra_soctherm;
+
+int tegra_calc_shared_calib(struct device *dev,
+ const struct tegra_soctherm_fuse *tfuse,
struct tsensor_shared_calib *shared);
-int tegra_calc_tsensor_calib(const struct tegra_tsensor *sensor,
+int tegra_calc_tsensor_calib(struct device *dev,
+ const struct tegra_tsensor *sensor,
const struct tsensor_shared_calib *shared,
u32 *calib);
diff --git a/drivers/thermal/tegra/tegra124-soctherm.c b/drivers/thermal/tegra/tegra124-soctherm.c
index 20ad27f4d1a1..e5bd080e3632 100644
--- a/drivers/thermal/tegra/tegra124-soctherm.c
+++ b/drivers/thermal/tegra/tegra124-soctherm.c
@@ -129,7 +129,6 @@ static const struct tegra_tsensor tegra124_tsensors[] = {
.name = "cpu0",
.base = 0xc0,
.config = &tegra124_tsensor_config,
- .calib_fuse_offset = 0x098,
.fuse_corr_alpha = 1135400,
.fuse_corr_beta = -6266900,
.group = &tegra124_tsensor_group_cpu,
@@ -137,7 +136,6 @@ static const struct tegra_tsensor tegra124_tsensors[] = {
.name = "cpu1",
.base = 0xe0,
.config = &tegra124_tsensor_config,
- .calib_fuse_offset = 0x084,
.fuse_corr_alpha = 1122220,
.fuse_corr_beta = -5700700,
.group = &tegra124_tsensor_group_cpu,
@@ -145,7 +143,6 @@ static const struct tegra_tsensor tegra124_tsensors[] = {
.name = "cpu2",
.base = 0x100,
.config = &tegra124_tsensor_config,
- .calib_fuse_offset = 0x088,
.fuse_corr_alpha = 1127000,
.fuse_corr_beta = -6768200,
.group = &tegra124_tsensor_group_cpu,
@@ -153,7 +150,6 @@ static const struct tegra_tsensor tegra124_tsensors[] = {
.name = "cpu3",
.base = 0x120,
.config = &tegra124_tsensor_config,
- .calib_fuse_offset = 0x12c,
.fuse_corr_alpha = 1110900,
.fuse_corr_beta = -6232000,
.group = &tegra124_tsensor_group_cpu,
@@ -161,7 +157,6 @@ static const struct tegra_tsensor tegra124_tsensors[] = {
.name = "mem0",
.base = 0x140,
.config = &tegra124_tsensor_config,
- .calib_fuse_offset = 0x158,
.fuse_corr_alpha = 1122300,
.fuse_corr_beta = -5936400,
.group = &tegra124_tsensor_group_mem,
@@ -169,7 +164,6 @@ static const struct tegra_tsensor tegra124_tsensors[] = {
.name = "mem1",
.base = 0x160,
.config = &tegra124_tsensor_config,
- .calib_fuse_offset = 0x15c,
.fuse_corr_alpha = 1145700,
.fuse_corr_beta = -7124600,
.group = &tegra124_tsensor_group_mem,
@@ -177,7 +171,6 @@ static const struct tegra_tsensor tegra124_tsensors[] = {
.name = "gpu",
.base = 0x180,
.config = &tegra124_tsensor_config,
- .calib_fuse_offset = 0x154,
.fuse_corr_alpha = 1120100,
.fuse_corr_beta = -6000500,
.group = &tegra124_tsensor_group_gpu,
@@ -185,7 +178,6 @@ static const struct tegra_tsensor tegra124_tsensors[] = {
.name = "pllx",
.base = 0x1a0,
.config = &tegra124_tsensor_config,
- .calib_fuse_offset = 0x160,
.fuse_corr_alpha = 1106500,
.fuse_corr_beta = -6729300,
.group = &tegra124_tsensor_group_pll,
diff --git a/drivers/thermal/tegra/tegra132-soctherm.c b/drivers/thermal/tegra/tegra132-soctherm.c
index b76308fdad9e..2f211ae4d6e8 100644
--- a/drivers/thermal/tegra/tegra132-soctherm.c
+++ b/drivers/thermal/tegra/tegra132-soctherm.c
@@ -129,7 +129,6 @@ static struct tegra_tsensor tegra132_tsensors[] = {
.name = "cpu0",
.base = 0xc0,
.config = &tegra132_tsensor_config,
- .calib_fuse_offset = 0x098,
.fuse_corr_alpha = 1126600,
.fuse_corr_beta = -9433500,
.group = &tegra132_tsensor_group_cpu,
@@ -137,7 +136,6 @@ static struct tegra_tsensor tegra132_tsensors[] = {
.name = "cpu1",
.base = 0xe0,
.config = &tegra132_tsensor_config,
- .calib_fuse_offset = 0x084,
.fuse_corr_alpha = 1110800,
.fuse_corr_beta = -7383000,
.group = &tegra132_tsensor_group_cpu,
@@ -145,7 +143,6 @@ static struct tegra_tsensor tegra132_tsensors[] = {
.name = "cpu2",
.base = 0x100,
.config = &tegra132_tsensor_config,
- .calib_fuse_offset = 0x088,
.fuse_corr_alpha = 1113800,
.fuse_corr_beta = -6215200,
.group = &tegra132_tsensor_group_cpu,
@@ -153,7 +150,6 @@ static struct tegra_tsensor tegra132_tsensors[] = {
.name = "cpu3",
.base = 0x120,
.config = &tegra132_tsensor_config,
- .calib_fuse_offset = 0x12c,
.fuse_corr_alpha = 1129600,
.fuse_corr_beta = -8196100,
.group = &tegra132_tsensor_group_cpu,
@@ -161,7 +157,6 @@ static struct tegra_tsensor tegra132_tsensors[] = {
.name = "mem0",
.base = 0x140,
.config = &tegra132_tsensor_config,
- .calib_fuse_offset = 0x158,
.fuse_corr_alpha = 1132900,
.fuse_corr_beta = -6755300,
.group = &tegra132_tsensor_group_mem,
@@ -169,7 +164,6 @@ static struct tegra_tsensor tegra132_tsensors[] = {
.name = "mem1",
.base = 0x160,
.config = &tegra132_tsensor_config,
- .calib_fuse_offset = 0x15c,
.fuse_corr_alpha = 1142300,
.fuse_corr_beta = -7374200,
.group = &tegra132_tsensor_group_mem,
@@ -177,7 +171,6 @@ static struct tegra_tsensor tegra132_tsensors[] = {
.name = "gpu",
.base = 0x180,
.config = &tegra132_tsensor_config,
- .calib_fuse_offset = 0x154,
.fuse_corr_alpha = 1125100,
.fuse_corr_beta = -6350400,
.group = &tegra132_tsensor_group_gpu,
@@ -185,7 +178,6 @@ static struct tegra_tsensor tegra132_tsensors[] = {
.name = "pllx",
.base = 0x1a0,
.config = &tegra132_tsensor_config,
- .calib_fuse_offset = 0x160,
.fuse_corr_alpha = 1118100,
.fuse_corr_beta = -8208800,
.group = &tegra132_tsensor_group_pll,
diff --git a/drivers/thermal/tegra/tegra210-soctherm.c b/drivers/thermal/tegra/tegra210-soctherm.c
index d0ff793f18c5..b2f3c775c1bb 100644
--- a/drivers/thermal/tegra/tegra210-soctherm.c
+++ b/drivers/thermal/tegra/tegra210-soctherm.c
@@ -130,7 +130,6 @@ static const struct tegra_tsensor tegra210_tsensors[] = {
.name = "cpu0",
.base = 0xc0,
.config = &tegra210_tsensor_config,
- .calib_fuse_offset = 0x098,
.fuse_corr_alpha = 1085000,
.fuse_corr_beta = 3244200,
.group = &tegra210_tsensor_group_cpu,
@@ -138,7 +137,6 @@ static const struct tegra_tsensor tegra210_tsensors[] = {
.name = "cpu1",
.base = 0xe0,
.config = &tegra210_tsensor_config,
- .calib_fuse_offset = 0x084,
.fuse_corr_alpha = 1126200,
.fuse_corr_beta = -67500,
.group = &tegra210_tsensor_group_cpu,
@@ -146,7 +144,6 @@ static const struct tegra_tsensor tegra210_tsensors[] = {
.name = "cpu2",
.base = 0x100,
.config = &tegra210_tsensor_config,
- .calib_fuse_offset = 0x088,
.fuse_corr_alpha = 1098400,
.fuse_corr_beta = 2251100,
.group = &tegra210_tsensor_group_cpu,
@@ -154,7 +151,6 @@ static const struct tegra_tsensor tegra210_tsensors[] = {
.name = "cpu3",
.base = 0x120,
.config = &tegra210_tsensor_config,
- .calib_fuse_offset = 0x12c,
.fuse_corr_alpha = 1108000,
.fuse_corr_beta = 602700,
.group = &tegra210_tsensor_group_cpu,
@@ -162,7 +158,6 @@ static const struct tegra_tsensor tegra210_tsensors[] = {
.name = "mem0",
.base = 0x140,
.config = &tegra210_tsensor_config,
- .calib_fuse_offset = 0x158,
.fuse_corr_alpha = 1069200,
.fuse_corr_beta = 3549900,
.group = &tegra210_tsensor_group_mem,
@@ -170,7 +165,6 @@ static const struct tegra_tsensor tegra210_tsensors[] = {
.name = "mem1",
.base = 0x160,
.config = &tegra210_tsensor_config,
- .calib_fuse_offset = 0x15c,
.fuse_corr_alpha = 1173700,
.fuse_corr_beta = -6263600,
.group = &tegra210_tsensor_group_mem,
@@ -178,7 +172,6 @@ static const struct tegra_tsensor tegra210_tsensors[] = {
.name = "gpu",
.base = 0x180,
.config = &tegra210_tsensor_config,
- .calib_fuse_offset = 0x154,
.fuse_corr_alpha = 1074300,
.fuse_corr_beta = 2734900,
.group = &tegra210_tsensor_group_gpu,
@@ -186,7 +179,6 @@ static const struct tegra_tsensor tegra210_tsensors[] = {
.name = "pllx",
.base = 0x1a0,
.config = &tegra210_tsensor_config,
- .calib_fuse_offset = 0x160,
.fuse_corr_alpha = 1039700,
.fuse_corr_beta = 6829100,
.group = &tegra210_tsensor_group_pll,
--
2.22.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH 01/11] xen/arm: use dma-noncoherent.h calls for xen-swiotlb cache maintainance
From: Stefano Stabellini @ 2019-08-29 22:41 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Stefano Stabellini, Konrad Rzeszutek Wilk, x86, linux-kernel,
iommu, xen-devel, linux-arm-kernel
In-Reply-To: <20190826121944.515-2-hch@lst.de>
On Mon, 26 Aug 2019, Christoph Hellwig wrote:
> Reuse the arm64 code that uses the dma-direct/swiotlb helpers for DMA
> non-coherent devices.
This patch does a bunch of things not listed in the commit message, such
as moving the static inline functions to include/xen/arm/page-coherent.h
and removing xen_swiotlb_dma_mmap and xen_swiotlb_get_sgtable because
unnecessary.
I would prefer if they were separate patches (for bisectability). It's
OK if you want to keep it all in one patch but please list all changes
the commit message.
In any case, I looked at the patch in details and it does all the right
things -- it's correct.
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> arch/arm/include/asm/device.h | 3 -
> arch/arm/include/asm/xen/page-coherent.h | 93 ----------------------
> arch/arm/mm/dma-mapping.c | 8 +-
> arch/arm64/include/asm/xen/page-coherent.h | 75 -----------------
> drivers/xen/swiotlb-xen.c | 49 +-----------
> include/xen/arm/page-coherent.h | 80 +++++++++++++++++++
> 6 files changed, 83 insertions(+), 225 deletions(-)
>
> diff --git a/arch/arm/include/asm/device.h b/arch/arm/include/asm/device.h
> index f6955b55c544..c675bc0d5aa8 100644
> --- a/arch/arm/include/asm/device.h
> +++ b/arch/arm/include/asm/device.h
> @@ -14,9 +14,6 @@ struct dev_archdata {
> #endif
> #ifdef CONFIG_ARM_DMA_USE_IOMMU
> struct dma_iommu_mapping *mapping;
> -#endif
> -#ifdef CONFIG_XEN
> - const struct dma_map_ops *dev_dma_ops;
> #endif
> unsigned int dma_coherent:1;
> unsigned int dma_ops_setup:1;
> diff --git a/arch/arm/include/asm/xen/page-coherent.h b/arch/arm/include/asm/xen/page-coherent.h
> index 2c403e7c782d..27e984977402 100644
> --- a/arch/arm/include/asm/xen/page-coherent.h
> +++ b/arch/arm/include/asm/xen/page-coherent.h
> @@ -1,95 +1,2 @@
> /* SPDX-License-Identifier: GPL-2.0 */
> -#ifndef _ASM_ARM_XEN_PAGE_COHERENT_H
> -#define _ASM_ARM_XEN_PAGE_COHERENT_H
> -
> -#include <linux/dma-mapping.h>
> -#include <asm/page.h>
> #include <xen/arm/page-coherent.h>
> -
> -static inline const struct dma_map_ops *xen_get_dma_ops(struct device *dev)
> -{
> - if (dev && dev->archdata.dev_dma_ops)
> - return dev->archdata.dev_dma_ops;
> - return get_arch_dma_ops(NULL);
> -}
> -
> -static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
> - dma_addr_t *dma_handle, gfp_t flags, unsigned long attrs)
> -{
> - return xen_get_dma_ops(hwdev)->alloc(hwdev, size, dma_handle, flags, attrs);
> -}
> -
> -static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
> - void *cpu_addr, dma_addr_t dma_handle, unsigned long attrs)
> -{
> - xen_get_dma_ops(hwdev)->free(hwdev, size, cpu_addr, dma_handle, attrs);
> -}
> -
> -static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
> - dma_addr_t dev_addr, unsigned long offset, size_t size,
> - enum dma_data_direction dir, unsigned long attrs)
> -{
> - unsigned long page_pfn = page_to_xen_pfn(page);
> - unsigned long dev_pfn = XEN_PFN_DOWN(dev_addr);
> - unsigned long compound_pages =
> - (1<<compound_order(page)) * XEN_PFN_PER_PAGE;
> - bool local = (page_pfn <= dev_pfn) &&
> - (dev_pfn - page_pfn < compound_pages);
> -
> - /*
> - * Dom0 is mapped 1:1, while the Linux page can span across
> - * multiple Xen pages, it's not possible for it to contain a
> - * mix of local and foreign Xen pages. So if the first xen_pfn
> - * == mfn the page is local otherwise it's a foreign page
> - * grant-mapped in dom0. If the page is local we can safely
> - * call the native dma_ops function, otherwise we call the xen
> - * specific function.
> - */
> - if (local)
> - xen_get_dma_ops(hwdev)->map_page(hwdev, page, offset, size, dir, attrs);
> - else
> - __xen_dma_map_page(hwdev, page, dev_addr, offset, size, dir, attrs);
> -}
> -
> -static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
> - size_t size, enum dma_data_direction dir, unsigned long attrs)
> -{
> - unsigned long pfn = PFN_DOWN(handle);
> - /*
> - * Dom0 is mapped 1:1, while the Linux page can be spanned accross
> - * multiple Xen page, it's not possible to have a mix of local and
> - * foreign Xen page. Dom0 is mapped 1:1, so calling pfn_valid on a
> - * foreign mfn will always return false. If the page is local we can
> - * safely call the native dma_ops function, otherwise we call the xen
> - * specific function.
> - */
> - if (pfn_valid(pfn)) {
> - if (xen_get_dma_ops(hwdev)->unmap_page)
> - xen_get_dma_ops(hwdev)->unmap_page(hwdev, handle, size, dir, attrs);
> - } else
> - __xen_dma_unmap_page(hwdev, handle, size, dir, attrs);
> -}
> -
> -static inline void xen_dma_sync_single_for_cpu(struct device *hwdev,
> - dma_addr_t handle, size_t size, enum dma_data_direction dir)
> -{
> - unsigned long pfn = PFN_DOWN(handle);
> - if (pfn_valid(pfn)) {
> - if (xen_get_dma_ops(hwdev)->sync_single_for_cpu)
> - xen_get_dma_ops(hwdev)->sync_single_for_cpu(hwdev, handle, size, dir);
> - } else
> - __xen_dma_sync_single_for_cpu(hwdev, handle, size, dir);
> -}
> -
> -static inline void xen_dma_sync_single_for_device(struct device *hwdev,
> - dma_addr_t handle, size_t size, enum dma_data_direction dir)
> -{
> - unsigned long pfn = PFN_DOWN(handle);
> - if (pfn_valid(pfn)) {
> - if (xen_get_dma_ops(hwdev)->sync_single_for_device)
> - xen_get_dma_ops(hwdev)->sync_single_for_device(hwdev, handle, size, dir);
> - } else
> - __xen_dma_sync_single_for_device(hwdev, handle, size, dir);
> -}
> -
> -#endif /* _ASM_ARM_XEN_PAGE_COHERENT_H */
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index d42557ee69c2..738097396445 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -1132,10 +1132,6 @@ static const struct dma_map_ops *arm_get_dma_map_ops(bool coherent)
> * 32-bit DMA.
> * Use the generic dma-direct / swiotlb ops code in that case, as that
> * handles bounce buffering for us.
> - *
> - * Note: this checks CONFIG_ARM_LPAE instead of CONFIG_SWIOTLB as the
> - * latter is also selected by the Xen code, but that code for now relies
> - * on non-NULL dev_dma_ops. To be cleaned up later.
> */
> if (IS_ENABLED(CONFIG_ARM_LPAE))
> return NULL;
> @@ -2363,10 +2359,8 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> set_dma_ops(dev, dma_ops);
>
> #ifdef CONFIG_XEN
> - if (xen_initial_domain()) {
> - dev->archdata.dev_dma_ops = dev->dma_ops;
> + if (xen_initial_domain())
> dev->dma_ops = xen_dma_ops;
> - }
> #endif
> dev->archdata.dma_ops_setup = true;
> }
> diff --git a/arch/arm64/include/asm/xen/page-coherent.h b/arch/arm64/include/asm/xen/page-coherent.h
> index d88e56b90b93..27e984977402 100644
> --- a/arch/arm64/include/asm/xen/page-coherent.h
> +++ b/arch/arm64/include/asm/xen/page-coherent.h
> @@ -1,77 +1,2 @@
> /* SPDX-License-Identifier: GPL-2.0 */
> -#ifndef _ASM_ARM64_XEN_PAGE_COHERENT_H
> -#define _ASM_ARM64_XEN_PAGE_COHERENT_H
> -
> -#include <linux/dma-mapping.h>
> -#include <asm/page.h>
> #include <xen/arm/page-coherent.h>
> -
> -static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
> - dma_addr_t *dma_handle, gfp_t flags, unsigned long attrs)
> -{
> - return dma_direct_alloc(hwdev, size, dma_handle, flags, attrs);
> -}
> -
> -static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
> - void *cpu_addr, dma_addr_t dma_handle, unsigned long attrs)
> -{
> - dma_direct_free(hwdev, size, cpu_addr, dma_handle, attrs);
> -}
> -
> -static inline void xen_dma_sync_single_for_cpu(struct device *hwdev,
> - dma_addr_t handle, size_t size, enum dma_data_direction dir)
> -{
> - unsigned long pfn = PFN_DOWN(handle);
> -
> - if (pfn_valid(pfn))
> - dma_direct_sync_single_for_cpu(hwdev, handle, size, dir);
> - else
> - __xen_dma_sync_single_for_cpu(hwdev, handle, size, dir);
> -}
> -
> -static inline void xen_dma_sync_single_for_device(struct device *hwdev,
> - dma_addr_t handle, size_t size, enum dma_data_direction dir)
> -{
> - unsigned long pfn = PFN_DOWN(handle);
> - if (pfn_valid(pfn))
> - dma_direct_sync_single_for_device(hwdev, handle, size, dir);
> - else
> - __xen_dma_sync_single_for_device(hwdev, handle, size, dir);
> -}
> -
> -static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
> - dma_addr_t dev_addr, unsigned long offset, size_t size,
> - enum dma_data_direction dir, unsigned long attrs)
> -{
> - unsigned long page_pfn = page_to_xen_pfn(page);
> - unsigned long dev_pfn = XEN_PFN_DOWN(dev_addr);
> - unsigned long compound_pages =
> - (1<<compound_order(page)) * XEN_PFN_PER_PAGE;
> - bool local = (page_pfn <= dev_pfn) &&
> - (dev_pfn - page_pfn < compound_pages);
> -
> - if (local)
> - dma_direct_map_page(hwdev, page, offset, size, dir, attrs);
> - else
> - __xen_dma_map_page(hwdev, page, dev_addr, offset, size, dir, attrs);
> -}
> -
> -static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
> - size_t size, enum dma_data_direction dir, unsigned long attrs)
> -{
> - unsigned long pfn = PFN_DOWN(handle);
> - /*
> - * Dom0 is mapped 1:1, while the Linux page can be spanned accross
> - * multiple Xen page, it's not possible to have a mix of local and
> - * foreign Xen page. Dom0 is mapped 1:1, so calling pfn_valid on a
> - * foreign mfn will always return false. If the page is local we can
> - * safely call the native dma_ops function, otherwise we call the xen
> - * specific function.
> - */
> - if (pfn_valid(pfn))
> - dma_direct_unmap_page(hwdev, handle, size, dir, attrs);
> - else
> - __xen_dma_unmap_page(hwdev, handle, size, dir, attrs);
> -}
> -
> -#endif /* _ASM_ARM64_XEN_PAGE_COHERENT_H */
> diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
> index ae1df496bf38..b8808677ae1d 100644
> --- a/drivers/xen/swiotlb-xen.c
> +++ b/drivers/xen/swiotlb-xen.c
> @@ -547,51 +547,6 @@ xen_swiotlb_dma_supported(struct device *hwdev, u64 mask)
> return xen_virt_to_bus(xen_io_tlb_end - 1) <= mask;
> }
>
> -/*
> - * Create userspace mapping for the DMA-coherent memory.
> - * This function should be called with the pages from the current domain only,
> - * passing pages mapped from other domains would lead to memory corruption.
> - */
> -static int
> -xen_swiotlb_dma_mmap(struct device *dev, struct vm_area_struct *vma,
> - void *cpu_addr, dma_addr_t dma_addr, size_t size,
> - unsigned long attrs)
> -{
> -#ifdef CONFIG_ARM
> - if (xen_get_dma_ops(dev)->mmap)
> - return xen_get_dma_ops(dev)->mmap(dev, vma, cpu_addr,
> - dma_addr, size, attrs);
> -#endif
> - return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
> -}
> -
> -/*
> - * This function should be called with the pages from the current domain only,
> - * passing pages mapped from other domains would lead to memory corruption.
> - */
> -static int
> -xen_swiotlb_get_sgtable(struct device *dev, struct sg_table *sgt,
> - void *cpu_addr, dma_addr_t handle, size_t size,
> - unsigned long attrs)
> -{
> -#ifdef CONFIG_ARM
> - if (xen_get_dma_ops(dev)->get_sgtable) {
> -#if 0
> - /*
> - * This check verifies that the page belongs to the current domain and
> - * is not one mapped from another domain.
> - * This check is for debug only, and should not go to production build
> - */
> - unsigned long bfn = PHYS_PFN(dma_to_phys(dev, handle));
> - BUG_ON (!page_is_ram(bfn));
> -#endif
> - return xen_get_dma_ops(dev)->get_sgtable(dev, sgt, cpu_addr,
> - handle, size, attrs);
> - }
> -#endif
> - return dma_common_get_sgtable(dev, sgt, cpu_addr, handle, size, attrs);
> -}
> -
> const struct dma_map_ops xen_swiotlb_dma_ops = {
> .alloc = xen_swiotlb_alloc_coherent,
> .free = xen_swiotlb_free_coherent,
> @@ -604,6 +559,6 @@ const struct dma_map_ops xen_swiotlb_dma_ops = {
> .map_page = xen_swiotlb_map_page,
> .unmap_page = xen_swiotlb_unmap_page,
> .dma_supported = xen_swiotlb_dma_supported,
> - .mmap = xen_swiotlb_dma_mmap,
> - .get_sgtable = xen_swiotlb_get_sgtable,
> + .mmap = dma_common_mmap,
> + .get_sgtable = dma_common_get_sgtable,
> };
> diff --git a/include/xen/arm/page-coherent.h b/include/xen/arm/page-coherent.h
> index 2ca9164a79bf..a840d6949a87 100644
> --- a/include/xen/arm/page-coherent.h
> +++ b/include/xen/arm/page-coherent.h
> @@ -2,6 +2,9 @@
> #ifndef _XEN_ARM_PAGE_COHERENT_H
> #define _XEN_ARM_PAGE_COHERENT_H
>
> +#include <linux/dma-mapping.h>
> +#include <asm/page.h>
> +
> void __xen_dma_map_page(struct device *hwdev, struct page *page,
> dma_addr_t dev_addr, unsigned long offset, size_t size,
> enum dma_data_direction dir, unsigned long attrs);
> @@ -13,4 +16,81 @@ void __xen_dma_sync_single_for_cpu(struct device *hwdev,
> void __xen_dma_sync_single_for_device(struct device *hwdev,
> dma_addr_t handle, size_t size, enum dma_data_direction dir);
>
> +static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
> + dma_addr_t *dma_handle, gfp_t flags, unsigned long attrs)
> +{
> + return dma_direct_alloc(hwdev, size, dma_handle, flags, attrs);
> +}
> +
> +static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
> + void *cpu_addr, dma_addr_t dma_handle, unsigned long attrs)
> +{
> + dma_direct_free(hwdev, size, cpu_addr, dma_handle, attrs);
> +}
> +
> +static inline void xen_dma_sync_single_for_cpu(struct device *hwdev,
> + dma_addr_t handle, size_t size, enum dma_data_direction dir)
> +{
> + unsigned long pfn = PFN_DOWN(handle);
> +
> + if (pfn_valid(pfn))
> + dma_direct_sync_single_for_cpu(hwdev, handle, size, dir);
> + else
> + __xen_dma_sync_single_for_cpu(hwdev, handle, size, dir);
> +}
> +
> +static inline void xen_dma_sync_single_for_device(struct device *hwdev,
> + dma_addr_t handle, size_t size, enum dma_data_direction dir)
> +{
> + unsigned long pfn = PFN_DOWN(handle);
> + if (pfn_valid(pfn))
> + dma_direct_sync_single_for_device(hwdev, handle, size, dir);
> + else
> + __xen_dma_sync_single_for_device(hwdev, handle, size, dir);
> +}
> +
> +static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
> + dma_addr_t dev_addr, unsigned long offset, size_t size,
> + enum dma_data_direction dir, unsigned long attrs)
> +{
> + unsigned long page_pfn = page_to_xen_pfn(page);
> + unsigned long dev_pfn = XEN_PFN_DOWN(dev_addr);
> + unsigned long compound_pages =
> + (1<<compound_order(page)) * XEN_PFN_PER_PAGE;
> + bool local = (page_pfn <= dev_pfn) &&
> + (dev_pfn - page_pfn < compound_pages);
> +
> + /*
> + * Dom0 is mapped 1:1, while the Linux page can span across
> + * multiple Xen pages, it's not possible for it to contain a
> + * mix of local and foreign Xen pages. So if the first xen_pfn
> + * == mfn the page is local otherwise it's a foreign page
> + * grant-mapped in dom0. If the page is local we can safely
> + * call the native dma_ops function, otherwise we call the xen
> + * specific function.
> + */
> + if (local)
> + dma_direct_map_page(hwdev, page, offset, size, dir, attrs);
> + else
> + __xen_dma_map_page(hwdev, page, dev_addr, offset, size, dir, attrs);
> +}
> +
> +static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
> + size_t size, enum dma_data_direction dir, unsigned long attrs)
> +{
> + unsigned long pfn = PFN_DOWN(handle);
> + /*
> + * Dom0 is mapped 1:1, while the Linux page can be spanned accross
> + * multiple Xen page, it's not possible to have a mix of local and
> + * foreign Xen page. Dom0 is mapped 1:1, so calling pfn_valid on a
> + * foreign mfn will always return false. If the page is local we can
> + * safely call the native dma_ops function, otherwise we call the xen
> + * specific function.
> + */
> + if (pfn_valid(pfn))
> + dma_direct_unmap_page(hwdev, handle, size, dir, attrs);
> + else
> + __xen_dma_unmap_page(hwdev, handle, size, dir, attrs);
> +}
> +
> #endif /* _XEN_ARM_PAGE_COHERENT_H */
> --
> 2.20.1
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 02/11] xen/arm: use dev_is_dma_coherent
From: Stefano Stabellini @ 2019-08-29 22:41 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Julien Grall, Stefano Stabellini, Konrad Rzeszutek Wilk, x86,
linux-kernel, iommu, xen-devel, linux-arm-kernel
In-Reply-To: <20190826121944.515-3-hch@lst.de>
On Mon, 26 Aug 2019, Christoph Hellwig wrote:
> Use the dma-noncoherent dev_is_dma_coherent helper instead of the home
> grown variant. Note that both are always initialized to the same
> value in arch_setup_dma_ops.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
> ---
> arch/arm/include/asm/dma-mapping.h | 6 ------
> arch/arm/xen/mm.c | 12 ++++++------
> arch/arm64/include/asm/dma-mapping.h | 9 ---------
> 3 files changed, 6 insertions(+), 21 deletions(-)
>
> diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
> index dba9355e2484..bdd80ddbca34 100644
> --- a/arch/arm/include/asm/dma-mapping.h
> +++ b/arch/arm/include/asm/dma-mapping.h
> @@ -91,12 +91,6 @@ static inline dma_addr_t virt_to_dma(struct device *dev, void *addr)
> }
> #endif
>
> -/* do not use this function in a driver */
> -static inline bool is_device_dma_coherent(struct device *dev)
> -{
> - return dev->archdata.dma_coherent;
> -}
> -
> /**
> * arm_dma_alloc - allocate consistent memory for DMA
> * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
> diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
> index d33b77e9add3..90574d89d0d4 100644
> --- a/arch/arm/xen/mm.c
> +++ b/arch/arm/xen/mm.c
> @@ -1,6 +1,6 @@
> // SPDX-License-Identifier: GPL-2.0-only
> #include <linux/cpu.h>
> -#include <linux/dma-mapping.h>
> +#include <linux/dma-noncoherent.h>
> #include <linux/gfp.h>
> #include <linux/highmem.h>
> #include <linux/export.h>
> @@ -99,7 +99,7 @@ void __xen_dma_map_page(struct device *hwdev, struct page *page,
> dma_addr_t dev_addr, unsigned long offset, size_t size,
> enum dma_data_direction dir, unsigned long attrs)
> {
> - if (is_device_dma_coherent(hwdev))
> + if (dev_is_dma_coherent(hwdev))
> return;
> if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
> return;
> @@ -112,7 +112,7 @@ void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
> unsigned long attrs)
>
> {
> - if (is_device_dma_coherent(hwdev))
> + if (dev_is_dma_coherent(hwdev))
> return;
> if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
> return;
> @@ -123,7 +123,7 @@ void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
> void __xen_dma_sync_single_for_cpu(struct device *hwdev,
> dma_addr_t handle, size_t size, enum dma_data_direction dir)
> {
> - if (is_device_dma_coherent(hwdev))
> + if (dev_is_dma_coherent(hwdev))
> return;
> __xen_dma_page_dev_to_cpu(hwdev, handle, size, dir);
> }
> @@ -131,7 +131,7 @@ void __xen_dma_sync_single_for_cpu(struct device *hwdev,
> void __xen_dma_sync_single_for_device(struct device *hwdev,
> dma_addr_t handle, size_t size, enum dma_data_direction dir)
> {
> - if (is_device_dma_coherent(hwdev))
> + if (dev_is_dma_coherent(hwdev))
> return;
> __xen_dma_page_cpu_to_dev(hwdev, handle, size, dir);
> }
> @@ -159,7 +159,7 @@ bool xen_arch_need_swiotlb(struct device *dev,
> * memory and we are not able to flush the cache.
> */
> return (!hypercall_cflush && (xen_pfn != bfn) &&
> - !is_device_dma_coherent(dev));
> + !dev_is_dma_coherent(dev));
> }
>
> int xen_create_contiguous_region(phys_addr_t pstart, unsigned int order,
> diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h
> index bdcb0922a40c..67243255a858 100644
> --- a/arch/arm64/include/asm/dma-mapping.h
> +++ b/arch/arm64/include/asm/dma-mapping.h
> @@ -18,14 +18,5 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
> return NULL;
> }
>
> -/*
> - * Do not use this function in a driver, it is only provided for
> - * arch/arm/mm/xen.c, which is used by arm64 as well.
> - */
> -static inline bool is_device_dma_coherent(struct device *dev)
> -{
> - return dev->dma_coherent;
> -}
> -
> #endif /* __KERNEL__ */
> #endif /* __ASM_DMA_MAPPING_H */
> --
> 2.20.1
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 03/11] xen/arm: simplify dma_cache_maint
From: Stefano Stabellini @ 2019-08-29 22:41 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Stefano Stabellini, Konrad Rzeszutek Wilk, x86, linux-kernel,
iommu, xen-devel, linux-arm-kernel
In-Reply-To: <20190826121944.515-4-hch@lst.de>
On Mon, 26 Aug 2019, Christoph Hellwig wrote:
> Calculate the required operation in the caller, and pass it directly
> instead of recalculating it for each page, and use simple arithmetics
> to get from the physical address to Xen page size aligned chunks.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> arch/arm/xen/mm.c | 62 +++++++++++++++++------------------------------
> 1 file changed, 22 insertions(+), 40 deletions(-)
>
> diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
> index 90574d89d0d4..14210ebdea1a 100644
> --- a/arch/arm/xen/mm.c
> +++ b/arch/arm/xen/mm.c
> @@ -35,64 +35,46 @@ unsigned long xen_get_swiotlb_free_pages(unsigned int order)
> return __get_free_pages(flags, order);
> }
>
> -enum dma_cache_op {
> - DMA_UNMAP,
> - DMA_MAP,
> -};
> static bool hypercall_cflush = false;
>
> -/* functions called by SWIOTLB */
> -
> -static void dma_cache_maint(dma_addr_t handle, unsigned long offset,
> - size_t size, enum dma_data_direction dir, enum dma_cache_op op)
> +/* buffers in highmem or foreign pages cannot cross page boundaries */
> +static void dma_cache_maint(dma_addr_t handle, size_t size, u32 op)
> {
> struct gnttab_cache_flush cflush;
> - unsigned long xen_pfn;
> - size_t left = size;
>
> - xen_pfn = (handle >> XEN_PAGE_SHIFT) + offset / XEN_PAGE_SIZE;
> - offset %= XEN_PAGE_SIZE;
> + cflush.a.dev_bus_addr = handle & XEN_PAGE_MASK;
> + cflush.offset = xen_offset_in_page(handle);
> + cflush.op = op;
>
> do {
> - size_t len = left;
> -
> - /* buffers in highmem or foreign pages cannot cross page
> - * boundaries */
> - if (len + offset > XEN_PAGE_SIZE)
> - len = XEN_PAGE_SIZE - offset;
> -
> - cflush.op = 0;
> - cflush.a.dev_bus_addr = xen_pfn << XEN_PAGE_SHIFT;
> - cflush.offset = offset;
> - cflush.length = len;
> -
> - if (op == DMA_UNMAP && dir != DMA_TO_DEVICE)
> - cflush.op = GNTTAB_CACHE_INVAL;
> - if (op == DMA_MAP) {
> - if (dir == DMA_FROM_DEVICE)
> - cflush.op = GNTTAB_CACHE_INVAL;
> - else
> - cflush.op = GNTTAB_CACHE_CLEAN;
> - }
> - if (cflush.op)
> - HYPERVISOR_grant_table_op(GNTTABOP_cache_flush, &cflush, 1);
> + if (size + cflush.offset > XEN_PAGE_SIZE)
> + cflush.length = XEN_PAGE_SIZE - cflush.offset;
> + else
> + cflush.length = size;
isn't it missing a:
cflush.a.dev_bus_addr = handle & XEN_PAGE_MASK;
here?
> + HYPERVISOR_grant_table_op(GNTTABOP_cache_flush, &cflush, 1);
> +
> + handle += cflush.length;
> + size -= cflush.length;
>
> - offset = 0;
> - xen_pfn++;
> - left -= len;
> - } while (left);
> + cflush.offset = 0;
> + } while (size);
> }
>
> static void __xen_dma_page_dev_to_cpu(struct device *hwdev, dma_addr_t handle,
> size_t size, enum dma_data_direction dir)
> {
> - dma_cache_maint(handle & PAGE_MASK, handle & ~PAGE_MASK, size, dir, DMA_UNMAP);
> + if (dir != DMA_TO_DEVICE)
> + dma_cache_maint(handle, size, GNTTAB_CACHE_INVAL);
> }
>
> static void __xen_dma_page_cpu_to_dev(struct device *hwdev, dma_addr_t handle,
> size_t size, enum dma_data_direction dir)
> {
> - dma_cache_maint(handle & PAGE_MASK, handle & ~PAGE_MASK, size, dir, DMA_MAP);
> + if (dir == DMA_FROM_DEVICE)
> + dma_cache_maint(handle, size, GNTTAB_CACHE_INVAL);
> + else
> + dma_cache_maint(handle, size, GNTTAB_CACHE_CLEAN);
> }
>
> void __xen_dma_map_page(struct device *hwdev, struct page *page,
> --
> 2.20.1
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox