* [PATCH V9 5/6] stm dummy: Mark dummy_stm_packet() with notrace
From: Chunyan Zhang @ 2016-11-21 7:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479715043-6534-1-git-send-email-zhang.chunyan@linaro.org>
If CONFIG_STM_SOURCE_FTRACE is selected, Function trace data can be
writen to sink via STM, all functions that related to writing data
packets to STM should be marked 'notrace' to avoid being traced by
Ftrace, otherwise the program would stall into an endless loop.
Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
Acked-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
drivers/hwtracing/stm/dummy_stm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hwtracing/stm/dummy_stm.c b/drivers/hwtracing/stm/dummy_stm.c
index a86612d..c5f94ca 100644
--- a/drivers/hwtracing/stm/dummy_stm.c
+++ b/drivers/hwtracing/stm/dummy_stm.c
@@ -21,7 +21,7 @@
#include <linux/slab.h>
#include <linux/stm.h>
-static ssize_t
+static ssize_t notrace
dummy_stm_packet(struct stm_data *stm_data, unsigned int master,
unsigned int channel, unsigned int packet, unsigned int flags,
unsigned int size, const unsigned char *payload)
--
2.7.4
^ permalink raw reply related
* [PATCH V9 4/6] intel_th: Mark sth_stm_packet() with notrace
From: Chunyan Zhang @ 2016-11-21 7:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479715043-6534-1-git-send-email-zhang.chunyan@linaro.org>
If CONFIG_STM_SOURCE_FTRACE is selected, Function trace data can be
writen to sink via STM, all functions that related to writing data
packets to STM should be marked 'notrace' to avoid being traced by
Ftrace, otherwise the program would stall into an endless loop.
Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
Acked-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
drivers/hwtracing/intel_th/sth.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/hwtracing/intel_th/sth.c b/drivers/hwtracing/intel_th/sth.c
index e1aee61..b034446 100644
--- a/drivers/hwtracing/intel_th/sth.c
+++ b/drivers/hwtracing/intel_th/sth.c
@@ -67,10 +67,13 @@ static void sth_iowrite(void __iomem *dest, const unsigned char *payload,
}
}
-static ssize_t sth_stm_packet(struct stm_data *stm_data, unsigned int master,
- unsigned int channel, unsigned int packet,
- unsigned int flags, unsigned int size,
- const unsigned char *payload)
+static ssize_t notrace sth_stm_packet(struct stm_data *stm_data,
+ unsigned int master,
+ unsigned int channel,
+ unsigned int packet,
+ unsigned int flags,
+ unsigned int size,
+ const unsigned char *payload)
{
struct sth_device *sth = container_of(stm_data, struct sth_device, stm);
struct intel_th_channel __iomem *out =
--
2.7.4
^ permalink raw reply related
* [PATCH V9 3/6] coresight: Mark stm_generic_packet() with notrace
From: Chunyan Zhang @ 2016-11-21 7:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479715043-6534-1-git-send-email-zhang.chunyan@linaro.org>
If CONFIG_STM_SOURCE_FTRACE is selected, Function trace data can be
writen to sink via STM, all functions that related to writing data
packets to STM should be marked 'notrace' to avoid being traced by
Ftrace, otherwise the program would stall into an endless loop.
Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
Acked-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
drivers/hwtracing/coresight/coresight-stm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
index 49e0f1b..b7543bd 100644
--- a/drivers/hwtracing/coresight/coresight-stm.c
+++ b/drivers/hwtracing/coresight/coresight-stm.c
@@ -406,7 +406,7 @@ static long stm_generic_set_options(struct stm_data *stm_data,
return 0;
}
-static ssize_t stm_generic_packet(struct stm_data *stm_data,
+static ssize_t notrace stm_generic_packet(struct stm_data *stm_data,
unsigned int master,
unsigned int channel,
unsigned int packet,
--
2.7.4
^ permalink raw reply related
* [PATCH V9 2/6] stm class: ftrace: Add ftrace-export-over-stm driver
From: Chunyan Zhang @ 2016-11-21 7:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479715043-6534-1-git-send-email-zhang.chunyan@linaro.org>
This patch adds a driver that models itself as an stm_source called
stm_ftrace. Once the stm device and stm_ftrace have been linked via
sysfs, the driver registers itself as a trace_export and everything
passed to the interface from Ftrace subsystem will end up in the STM
trace engine.
Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
Acked-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
drivers/hwtracing/stm/Kconfig | 11 ++++++
drivers/hwtracing/stm/Makefile | 2 +
drivers/hwtracing/stm/ftrace.c | 87 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 100 insertions(+)
create mode 100644 drivers/hwtracing/stm/ftrace.c
diff --git a/drivers/hwtracing/stm/Kconfig b/drivers/hwtracing/stm/Kconfig
index 847a39b..723e2d9 100644
--- a/drivers/hwtracing/stm/Kconfig
+++ b/drivers/hwtracing/stm/Kconfig
@@ -39,4 +39,15 @@ config STM_SOURCE_HEARTBEAT
If you want to send heartbeat messages over STM devices,
say Y.
+config STM_SOURCE_FTRACE
+ tristate "Copy the output from kernel Ftrace to STM engine"
+ depends on FUNCTION_TRACER
+ help
+ This option can be used to copy the output from kernel Ftrace
+ to STM engine. Enabling this option will introduce a slight
+ timing effect.
+
+ If you want to send kernel Ftrace messages over STM devices,
+ say Y.
+
endif
diff --git a/drivers/hwtracing/stm/Makefile b/drivers/hwtracing/stm/Makefile
index a9ce3d4..3abd84c 100644
--- a/drivers/hwtracing/stm/Makefile
+++ b/drivers/hwtracing/stm/Makefile
@@ -6,6 +6,8 @@ obj-$(CONFIG_STM_DUMMY) += dummy_stm.o
obj-$(CONFIG_STM_SOURCE_CONSOLE) += stm_console.o
obj-$(CONFIG_STM_SOURCE_HEARTBEAT) += stm_heartbeat.o
+obj-$(CONFIG_STM_SOURCE_FTRACE) += stm_ftrace.o
stm_console-y := console.o
stm_heartbeat-y := heartbeat.o
+stm_ftrace-y := ftrace.o
diff --git a/drivers/hwtracing/stm/ftrace.c b/drivers/hwtracing/stm/ftrace.c
new file mode 100644
index 0000000..bd126a7
--- /dev/null
+++ b/drivers/hwtracing/stm/ftrace.c
@@ -0,0 +1,87 @@
+/*
+ * Simple kernel driver to link kernel Ftrace and an STM device
+ * Copyright (c) 2016, Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * STM Ftrace will be registered as a trace_export.
+ */
+
+#include <linux/module.h>
+#include <linux/stm.h>
+#include <linux/trace.h>
+
+#define STM_FTRACE_NR_CHANNELS 1
+#define STM_FTRACE_CHAN 0
+
+static int stm_ftrace_link(struct stm_source_data *data);
+static void stm_ftrace_unlink(struct stm_source_data *data);
+
+static struct stm_ftrace {
+ struct stm_source_data data;
+ struct trace_export ftrace;
+} stm_ftrace = {
+ .data = {
+ .name = "ftrace",
+ .nr_chans = STM_FTRACE_NR_CHANNELS,
+ .link = stm_ftrace_link,
+ .unlink = stm_ftrace_unlink,
+ },
+};
+
+/**
+ * stm_ftrace_write() - write data to STM via 'stm_ftrace' source
+ * @buf: buffer containing the data packet
+ * @len: length of the data packet
+ */
+static void notrace
+stm_ftrace_write(const void *buf, unsigned int len)
+{
+ stm_source_write(&stm_ftrace.data, STM_FTRACE_CHAN, buf, len);
+}
+
+static int stm_ftrace_link(struct stm_source_data *data)
+{
+ struct stm_ftrace *sf = container_of(data, struct stm_ftrace, data);
+
+ sf->ftrace.write = stm_ftrace_write;
+
+ return register_ftrace_export(&sf->ftrace);
+}
+
+static void stm_ftrace_unlink(struct stm_source_data *data)
+{
+ struct stm_ftrace *sf = container_of(data, struct stm_ftrace, data);
+
+ unregister_ftrace_export(&sf->ftrace);
+}
+
+static int __init stm_ftrace_init(void)
+{
+ int ret;
+
+ ret = stm_source_register_device(NULL, &stm_ftrace.data);
+ if (ret)
+ pr_err("Failed to register stm_source - ftrace.\n");
+
+ return ret;
+}
+
+static void __exit stm_ftrace_exit(void)
+{
+ stm_source_unregister_device(&stm_ftrace.data);
+}
+
+module_init(stm_ftrace_init);
+module_exit(stm_ftrace_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("stm_ftrace driver");
+MODULE_AUTHOR("Chunyan Zhang <zhang.chunyan@linaro.org>");
--
2.7.4
^ permalink raw reply related
* [PATCH V9 1/6] tracing: add a possibility of exporting function trace to other places instead of ring buffer only
From: Chunyan Zhang @ 2016-11-21 7:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479715043-6534-1-git-send-email-zhang.chunyan@linaro.org>
Currently Function traces can be only exported to ring buffer, this
patch added trace_export concept which can process traces and export
them to a registered destination as an addition to the current only
one output of Ftrace - i.e. ring buffer.
In this way, if we want Function traces to be sent to other destination
rather than ring buffer only, we just need to register a new trace_export
and implement its own .write() function for writing traces to storage.
With this patch, only Function trace (trace type is TRACE_FN)
is supported.
Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
---
include/linux/trace.h | 28 +++++++++++
kernel/trace/trace.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 156 insertions(+), 1 deletion(-)
create mode 100644 include/linux/trace.h
diff --git a/include/linux/trace.h b/include/linux/trace.h
new file mode 100644
index 0000000..9330a58
--- /dev/null
+++ b/include/linux/trace.h
@@ -0,0 +1,28 @@
+#ifndef _LINUX_TRACE_H
+#define _LINUX_TRACE_H
+
+#ifdef CONFIG_TRACING
+/*
+ * The trace export - an export of Ftrace output. The trace_export
+ * can process traces and export them to a registered destination as
+ * an addition to the current only output of Ftrace - i.e. ring buffer.
+ *
+ * If you want traces to be sent to some other place rather than ring
+ * buffer only, just need to register a new trace_export and implement
+ * its own .write() function for writing traces to the storage.
+ *
+ * next - pointer to the next trace_export
+ * write - copy traces which have been delt with ->commit() to
+ * the destination
+ */
+struct trace_export {
+ struct trace_export __rcu *next;
+ void (*write)(const void *, unsigned int);
+};
+
+int register_ftrace_export(struct trace_export *export);
+int unregister_ftrace_export(struct trace_export *export);
+
+#endif /* CONFIG_TRACING */
+
+#endif /* _LINUX_TRACE_H */
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 8696ce6..038291d 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -40,6 +40,7 @@
#include <linux/poll.h>
#include <linux/nmi.h>
#include <linux/fs.h>
+#include <linux/trace.h>
#include <linux/sched/rt.h>
#include "trace.h"
@@ -2128,6 +2129,129 @@ void trace_buffer_unlock_commit_regs(struct trace_array *tr,
ftrace_trace_userstack(buffer, flags, pc);
}
+static void
+trace_process_export(struct trace_export *export,
+ struct ring_buffer_event *event)
+{
+ struct trace_entry *entry;
+ unsigned int size = 0;
+
+ entry = ring_buffer_event_data(event);
+ size = ring_buffer_event_length(event);
+ export->write(entry, size);
+}
+
+static DEFINE_MUTEX(ftrace_export_lock);
+
+static struct trace_export __rcu *ftrace_exports_list __read_mostly;
+
+static DEFINE_STATIC_KEY_FALSE(ftrace_exports_enabled);
+
+static inline void ftrace_exports_enable(void)
+{
+ static_branch_enable(&ftrace_exports_enabled);
+}
+
+static inline void ftrace_exports_disable(void)
+{
+ static_branch_disable(&ftrace_exports_enabled);
+}
+
+void ftrace_exports(struct ring_buffer_event *event)
+{
+ struct trace_export *export;
+
+ preempt_disable_notrace();
+
+ export = rcu_dereference_raw_notrace(ftrace_exports_list);
+ while (export) {
+ trace_process_export(export, event);
+ export = rcu_dereference_raw_notrace(export->next);
+ }
+
+ preempt_enable_notrace();
+}
+
+static inline void
+add_trace_export(struct trace_export **list, struct trace_export *export)
+{
+ rcu_assign_pointer(export->next, *list);
+ /*
+ * We are entering export into the list but another
+ * CPU might be walking that list. We need to make sure
+ * the export->next pointer is valid before another CPU sees
+ * the export pointer included into the list.
+ */
+ rcu_assign_pointer(*list, export);
+}
+
+static inline int
+rm_trace_export(struct trace_export **list, struct trace_export *export)
+{
+ struct trace_export **p;
+
+ for (p = list; *p != NULL; p = &(*p)->next)
+ if (*p == export)
+ break;
+
+ if (*p != export)
+ return -1;
+
+ rcu_assign_pointer(*p, (*p)->next);
+
+ return 0;
+}
+
+static inline void
+add_ftrace_export(struct trace_export **list, struct trace_export *export)
+{
+ if (*list == NULL)
+ ftrace_exports_enable();
+
+ add_trace_export(list, export);
+}
+
+static inline int
+rm_ftrace_export(struct trace_export **list, struct trace_export *export)
+{
+ int ret;
+
+ ret = rm_trace_export(list, export);
+ if (*list == NULL)
+ ftrace_exports_disable();
+
+ return ret;
+}
+
+int register_ftrace_export(struct trace_export *export)
+{
+ if (WARN_ON_ONCE(!export->write))
+ return -1;
+
+ mutex_lock(&ftrace_export_lock);
+
+ add_ftrace_export(&ftrace_exports_list, export);
+
+ mutex_unlock(&ftrace_export_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(register_ftrace_export);
+
+int unregister_ftrace_export(struct trace_export *export)
+{
+ int ret;
+
+ mutex_lock(&ftrace_export_lock);
+
+ ret = rm_ftrace_export(&ftrace_exports_list, export);
+
+ mutex_unlock(&ftrace_export_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(unregister_ftrace_export);
+
void
trace_function(struct trace_array *tr,
unsigned long ip, unsigned long parent_ip, unsigned long flags,
@@ -2146,8 +2270,11 @@ trace_function(struct trace_array *tr,
entry->ip = ip;
entry->parent_ip = parent_ip;
- if (!call_filter_check_discard(call, entry, buffer, event))
+ if (!call_filter_check_discard(call, entry, buffer, event)) {
+ if (static_branch_unlikely(&ftrace_exports_enabled))
+ ftrace_exports(event);
__buffer_unlock_commit(buffer, event);
+ }
}
#ifdef CONFIG_STACKTRACE
--
2.7.4
^ permalink raw reply related
* [PATCH V9 0/6] Integration of function trace with System Trace IP blocks
From: Chunyan Zhang @ 2016-11-21 7:57 UTC (permalink / raw)
To: linux-arm-kernel
IP blocks allowing a variety of trace sources to log debugging
information to a pre-defined area have been introduced on a couple of
architecture [1][2]. These system trace blocks (also known as STM)
typically follow the MIPI STPv2 protocol [3] and provide a system wide
logging facility to any device, running a kernel or not, with access
to the block's log entry port(s). Since each trace message has a
timestamp, it is possible to correlate events happening in the entire
system rather than being confined to the logging facility of a single
entity.
This patchset is trying to use STM IP blocks to store function tracing
information produced by Ftrace and I'm taking the Function trace
(trace type is TRACE_FN) as the example in this patchset, but other
types of traces also can be supported.
Logging information generated by the Ftrace subsystem to STM and gathered
in the sink device can be used in conjunction with trace data from other
board components, also collected in the same trace sink.
This example is using ARM coresight STM but the same would apply to any
other architecture wishing to do the same.
[1]. https://lwn.net/Articles/674746/
[2]. http://lxr.free-electrons.com/source/drivers/hwtracing/intel_th/
[3]. http://mipi.org/specifications/debug#STP
Changes from v8:
* Split the last patch into 4 according to the suggestion from Alexander Shishkin;
* Add Alexander Shishkin's Acked-by.
Changes from v7:
* Addressed comments from Steven Rostedt:
- Removed unnessecery code;
- Shrinked the dependence of 'STM_SOURCE_FTRACE' from 'TRACING' to 'FUNCTION_TRACER';
- Changed the parameter type from char* to void*, that makes more sense.
Changes from v6:
* Rebased on v4.9-rc1;
* Removed unused the declaration and header file including from trace.h
which was added in patch 1 of this series;
* Revised a bit the comments in trace.h .
Changes from v5:
* Addressed comments from Steven Rostedt:
- Removed .commit() from trace_export;
- Changed to directly call trace_process_export() instead of trace_export::commit();
- Used 'ring_buffer_event_length(event)' instead to get the trace size;
- Removed trace_export pointer from trace_array structure.
* Revised commit message a little to make the description more accurate.
Changes from v4:
* Addressed comments from Steven Rostedt:
- Removed 'inline' annotations from the function which is called via function pointer;
- Removed useless components from structure trace_export;
- Added '__rcu' annotation to the RCU variables;
- Used 'rcu_assign_pointer' to do every RCU assignment;
- Added WARN_ON_ONCE() when the .write() is not assigned;
- In order to reduce the overhead caused by adding this feature, this revision used an
global array instead of a big "if statement" to get the size of trace entry according
to the trace type.
- In order to keep the current logic unchanged, made ftrace_exports() only being called if
there's something have been added, i.e. if trace_export to stm_ftrace has been added in
this patchset.
Changes from v3:
* Addressed comments from Steven Rostedt:
- Added comments for the element 'name' and 'next' of trace_export;
- Changed to use RCU functions instead of mutex in function callback;
- Moved the check for name to register trace_export function;
* Renamed 'trace_function_exports' to 'trace_exports' since its
implementation is not only for function_trace; The similar changes on
'add_trace_export' and 'rm_trace_export'.
Changes from v2:
* Rebased on v4.8-rc1.
* Added trace_export class, and make traces can be exported to not only
ring buffer but also other area such as STM.
* Made stm_ftrace as an trace_export.
* More detailed changes are described in change log of each patch.
Changes from v1:
* Addressed comments from Alexander Shishkin:
- Modified some ambiguous change logs.
- Decoupled stm_ftrace and trace_output interface to STM.
- Changed the file name from stm_ftrace.c to stm/ftrace.c.
- Implemented link/unlink hooks for stm_ftrace.
* Removed useless header file include from stm/ftrace.c
* Added Acked-by from Steven Rostedt on 4/4.
Chunyan Zhang (6):
tracing: add a possibility of exporting function trace to other places
instead of ring buffer only
stm class: ftrace: Add ftrace-export-over-stm driver
coresight: Mark stm_generic_packet() with notrace
intel_th: Mark sth_stm_packet() with notrace
stm dummy: Mark dummy_stm_packet() with notrace
stm: Mark the functions of writing STM with notrace
drivers/hwtracing/coresight/coresight-stm.c | 2 +-
drivers/hwtracing/intel_th/sth.c | 11 ++-
drivers/hwtracing/stm/Kconfig | 11 +++
drivers/hwtracing/stm/Makefile | 2 +
drivers/hwtracing/stm/core.c | 7 +-
drivers/hwtracing/stm/dummy_stm.c | 2 +-
drivers/hwtracing/stm/ftrace.c | 87 +++++++++++++++++++
include/linux/stm.h | 4 +-
include/linux/trace.h | 28 ++++++
kernel/trace/trace.c | 129 +++++++++++++++++++++++++++-
10 files changed, 271 insertions(+), 12 deletions(-)
create mode 100644 drivers/hwtracing/stm/ftrace.c
create mode 100644 include/linux/trace.h
--
2.7.4
^ permalink raw reply
* [PATCH 2/5] drm/modes: Support modes names on the command line
From: Maxime Ripard @ 2016-11-21 7:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAOw6vb+bpf_JoPR8To0Q5Sfidxs=FTif0d3gpgCtFTOKnGCqfA@mail.gmail.com>
Hi Sean,
On Wed, Nov 16, 2016 at 12:21:42PM -0500, Sean Paul wrote:
> On Tue, Oct 18, 2016 at 4:29 AM, Maxime Ripard
> <maxime.ripard@free-electrons.com> wrote:
> > The drm subsystem also uses the video= kernel parameter, and in the
> > documentation refers to the fbdev documentation for that parameter.
> >
> > However, that documentation also says that instead of giving the mode using
> > its resolution we can also give a name. However, DRM doesn't handle that
> > case at the moment. Even though in most case it shouldn't make any
> > difference, it might be useful for analog modes, where different standards
> > might have the same resolution, but still have a few different parameters
> > that are not encoded in the modes (NTSC vs NTSC-J vs PAL-M for example).
> >
> > Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> > ---
> > drivers/gpu/drm/drm_connector.c | 3 +-
> > drivers/gpu/drm/drm_fb_helper.c | 4 +++-
> > drivers/gpu/drm/drm_modes.c | 49 +++++++++++++++++++++++-----------
> > include/drm/drm_connector.h | 1 +-
> > 4 files changed, 41 insertions(+), 16 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> > index 2db7fb510b6c..27a8a511257c 100644
> > --- a/drivers/gpu/drm/drm_connector.c
> > +++ b/drivers/gpu/drm/drm_connector.c
> > @@ -147,8 +147,9 @@ static void drm_connector_get_cmdline_mode(struct drm_connector *connector)
> > connector->force = mode->force;
> > }
> >
> > - DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n",
> > + DRM_DEBUG_KMS("cmdline mode for connector %s %s %dx%d@%dHz%s%s%s\n",
> > connector->name,
> > + mode->name ? mode->name : "",
> > mode->xres, mode->yres,
> > mode->refresh_specified ? mode->refresh : 60,
> > mode->rb ? " reduced blanking" : "",
> > diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
> > index 03414bde1f15..20a68305fb45 100644
> > --- a/drivers/gpu/drm/drm_fb_helper.c
> > +++ b/drivers/gpu/drm/drm_fb_helper.c
> > @@ -1748,6 +1748,10 @@ struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_connector *f
> > prefer_non_interlace = !cmdline_mode->interlace;
> > again:
> > list_for_each_entry(mode, &fb_helper_conn->connector->modes, head) {
> > + /* Check (optional) mode name first */
> > + if (!strcmp(mode->name, cmdline_mode->name))
> > + return mode;
> > +
> > /* check width/height */
> > if (mode->hdisplay != cmdline_mode->xres ||
> > mode->vdisplay != cmdline_mode->yres)
> > diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
> > index 7d5bdca276f2..fdbf541a5978 100644
> > --- a/drivers/gpu/drm/drm_modes.c
> > +++ b/drivers/gpu/drm/drm_modes.c
> > @@ -1413,7 +1413,7 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
> > struct drm_cmdline_mode *mode)
> > {
> > const char *name;
> > - bool parse_extras = false;
> > + bool named_mode = false, parse_extras = false;
> > unsigned int bpp_off = 0, refresh_off = 0;
> > unsigned int mode_end = 0;
> > char *bpp_ptr = NULL, *refresh_ptr = NULL, *extra_ptr = NULL;
> > @@ -1432,8 +1432,14 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
> >
> > name = mode_option;
> >
> > + /*
> > + * If the first character is not a digit, then it means that
> > + * we have a named mode.
> > + */
> > if (!isdigit(name[0]))
> > - return false;
> > + named_mode = true;
> > + else
> > + named_mode = false;
>
> named_mode = isalpha(name[0]); might be more succinct (and covers
> special characters).
>
> >
> > /* Try to locate the bpp and refresh specifiers, if any */
> > bpp_ptr = strchr(name, '-');
> > @@ -1460,12 +1466,16 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
> > parse_extras = true;
> > }
> >
> > - ret = drm_mode_parse_cmdline_res_mode(name, mode_end,
> > - parse_extras,
> > - connector,
> > - mode);
> > - if (ret)
> > - return false;
> > + if (named_mode) {
> > + strncpy(mode->name, name, mode_end);
> > + } else {
> > + ret = drm_mode_parse_cmdline_res_mode(name, mode_end,
> > + parse_extras,
> > + connector,
> > + mode);
> > + if (ret)
> > + return false;
> > + }
> > mode->specified = true;
> >
> > if (bpp_ptr) {
> > @@ -1493,14 +1503,23 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
> > extra_ptr = refresh_end_ptr;
> >
> > if (extra_ptr) {
> > - int remaining = strlen(name) - (extra_ptr - name);
> > + if (!named_mode) {
> > + int len = strlen(name) - (extra_ptr - name);
> >
> > - /*
> > - * We still have characters to process, while
> > - * we shouldn't have any
> > - */
> > - if (remaining > 0)
> > - return false;
> > + ret = drm_mode_parse_cmdline_extra(extra_ptr, len,
> > + connector, mode);
> > + if (ret)
> > + return false;
> > + } else {
> > + int remaining = strlen(name) - (extra_ptr - name);
> > +
> > + /*
> > + * We still have characters to process, while
> > + * we shouldn't have any
> > + */
> > + if (remaining > 0)
> > + return false;
>
> Correct me if I'm wrong, but this shouldn't ever happen. AFAICT, the
> only way it could would be if we parsed bpp or refresh in the named
> mode (since those are the only cases where we don't copy the whole
> string over). Shouldn't that be invalid anyways?
It's supposed to be supported by the video
string. Documentation/fb/modedb.txt defines:
Valid mode specifiers (mode_option argument):
<xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m][eDd]
<name>[-<bpp>][@<refresh>]
So we can't just copy the string over, and we need to parse it :/
Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161121/e27ca461/attachment.sig>
^ permalink raw reply
* [PATCH 1/5] drm/modes: Rewrite the command line parser
From: Maxime Ripard @ 2016-11-21 7:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAOw6vbKf3B2DYJA-kpmxa7vLzRcv5LhyVtToPyB2d6-thdt4Ng@mail.gmail.com>
Hi Sean,
Thanks for taking the time to review this.
On Wed, Nov 16, 2016 at 12:12:53PM -0500, Sean Paul wrote:
> On Tue, Oct 18, 2016 at 4:29 AM, Maxime Ripard
> <maxime.ripard@free-electrons.com> wrote:
> > Rewrite the command line parser in order to get away from the state machine
> > parsing the video mode lines.
> >
> > Hopefully, this will allow to extend it more easily to support named modes
> > and / or properties set directly on the command line.
> >
> > Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> > ---
> > drivers/gpu/drm/drm_modes.c | 305 +++++++++++++++++++++++--------------
> > 1 file changed, 190 insertions(+), 115 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
> > index 53f07ac7c174..7d5bdca276f2 100644
> > --- a/drivers/gpu/drm/drm_modes.c
> > +++ b/drivers/gpu/drm/drm_modes.c
> > @@ -30,6 +30,7 @@
> > * authorization from the copyright holder(s) and author(s).
> > */
> >
> > +#include <linux/ctype.h>
> > #include <linux/list.h>
> > #include <linux/list_sort.h>
> > #include <linux/export.h>
> > @@ -1261,6 +1262,131 @@ void drm_mode_connector_list_update(struct drm_connector *connector)
> > }
> > EXPORT_SYMBOL(drm_mode_connector_list_update);
> >
> > +static int drm_mode_parse_cmdline_bpp(const char *str, char **end_ptr,
> > + struct drm_cmdline_mode *mode)
> > +{
> > + if (str[0] != '-')
> > + return -EINVAL;
> > +
> > + mode->bpp = simple_strtol(str + 1, end_ptr, 10);
> > + mode->bpp_specified = true;
> > +
> > + return 0;
> > +}
> > +
> > +static int drm_mode_parse_cmdline_refresh(const char *str, char **end_ptr,
> > + struct drm_cmdline_mode *mode)
> > +{
> > + if (str[0] != '@')
> > + return -EINVAL;
> > +
> > + mode->refresh = simple_strtol(str + 1, end_ptr, 10);
> > + mode->refresh_specified = true;
> > +
> > + return 0;
> > +}
> > +
> > +static int drm_mode_parse_cmdline_extra(const char *str, int length,
> > + struct drm_connector *connector,
> > + struct drm_cmdline_mode *mode)
> > +{
> > + int i;
> > +
> > + for (i = 0; i < length; i++) {
> > + switch (str[i]) {
> > + case 'i':
> > + mode->interlace = true;
> > + break;
> > + case 'm':
> > + mode->margins = true;
> > + break;
> > + case 'D':
> > + if (mode->force != DRM_FORCE_UNSPECIFIED)
> > + return -EINVAL;
> > +
> > + if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) &&
> > + (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB))
> > + mode->force = DRM_FORCE_ON;
> > + else
> > + mode->force = DRM_FORCE_ON_DIGITAL;
> > + break;
> > + case 'd':
> > + if (mode->force != DRM_FORCE_UNSPECIFIED)
> > + return -EINVAL;
> > +
> > + mode->force = DRM_FORCE_OFF;
> > + break;
> > + case 'e':
> > + if (mode->force != DRM_FORCE_UNSPECIFIED)
> > + return -EINVAL;
> > +
> > + mode->force = DRM_FORCE_ON;
> > + break;
> > + default:
> > + return -EINVAL;
> > + }
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int drm_mode_parse_cmdline_res_mode(const char *str, unsigned int length,
> > + bool extras,
> > + struct drm_connector *connector,
> > + struct drm_cmdline_mode *mode)
> > +{
> > + bool rb = false, cvt = false;
> > + int xres = 0, yres = 0;
> > + int remaining, i;
> > + char *end_ptr;
> > +
> > + xres = simple_strtol(str, &end_ptr, 10);
> > +
>
> checkpatch is telling me to use kstrtol instead, as simple_strtol is deprecated
>
> > + if (end_ptr[0] != 'x')
>
> check that end_ptr != NULL? you should probably also check that xres
> isn't an error (ie: -ERANGE or -EINVAL)
>
> > + return -EINVAL;
> > + end_ptr++;
> > +
> > + yres = simple_strtol(end_ptr, &end_ptr, 10);
>
> check end_ptr != NULL and yres sane
>
> > +
> > + remaining = length - (end_ptr - str);
> > + if (remaining < 0)
>
> right, so if end_ptr is NULL here, we'll end up with a huge positive
> value for remaining :)
>
> > + return -EINVAL;
> > +
> > + for (i = 0; i < remaining; i++) {
> > + switch (end_ptr[i]) {
> > + case 'M':
> > + cvt = true;
>
> the previous code ensured proper ordering as well as parsing, whereas
> yours will take these in any order (and accepts duplicates). i don't
> think this should cause any issues, but perhaps something to verify.
Yes, I definitely overlooked the order of the parameters (and now I
get why the switch was so convoluted...)
I'll come up with a second version fixing that (and the other comments
you had).
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161121/2a06cc04/attachment.sig>
^ permalink raw reply
* [PATCH v16 05/15] clocksource/drivers/arm_arch_timer: fix a bug in arch_timer_register about arch_timer_uses_ppi
From: Fu Wei @ 2016-11-21 7:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161118185252.GI1197@leverpostej>
Hi Mark,
On 19 November 2016 at 02:52, Mark Rutland <mark.rutland@arm.com> wrote:
> On Wed, Nov 16, 2016 at 09:48:58PM +0800, fu.wei at linaro.org wrote:
>> From: Fu Wei <fu.wei@linaro.org>
>>
>> The patch fix a potential bug about arch_timer_uses_ppi in
>> arch_timer_register.
>> On ARM64, we don't use ARCH_TIMER_PHYS_SECURE_PPI in Linux, so we will
>> just igorne it in init code.
>
> That's not currently the case. I assume you mean we will in later
> patches? If so, please make that clear in the commit message.
>
>> If arch_timer_uses_ppi is ARCH_TIMER_PHYS_NONSECURE_PPI, the orignal
>> code of arch_timer_uses_ppi may go wrong.
>
> How? What specifically happens?
>
> We don't currently assign ARCH_TIMER_PHYS_NONSECURE_PPI to
> arch_timer_uses_ppi, so I assume a later patch changes this. This change
> should be folded into said patch; it doesn't make sense in isolation.
yes, this patch is a preparation for the next which may set
arch_timer_use_ppi as ARCH_TIMER_PHYS_NONSECURE_PPI.
So you are right, I will merge this into the next and mention this
change in the commit message.
Great thanks
>
> Thanks,
> Mark.
>
>> Signed-off-by: Fu Wei <fu.wei@linaro.org>
>> ---
>> drivers/clocksource/arm_arch_timer.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
>> index dd1040d..6de164f 100644
>> --- a/drivers/clocksource/arm_arch_timer.c
>> +++ b/drivers/clocksource/arm_arch_timer.c
>> @@ -699,7 +699,7 @@ static int __init arch_timer_register(void)
>> case ARCH_TIMER_PHYS_NONSECURE_PPI:
>> err = request_percpu_irq(ppi, arch_timer_handler_phys,
>> "arch_timer", arch_timer_evt);
>> - if (!err && arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]) {
>> + if (!err && arch_timer_has_nonsecure_ppi()) {
>> ppi = arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI];
>> err = request_percpu_irq(ppi, arch_timer_handler_phys,
>> "arch_timer", arch_timer_evt);
>> --
>> 2.7.4
>>
--
Best regards,
Fu Wei
Software Engineer
Red Hat
^ permalink raw reply
* [PATCH 5/5] drm/sun4i: Add support for the overscan profiles
From: Maxime Ripard @ 2016-11-21 7:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161111091755.tfqizju5voazjrmm@phenom.ffwll.local>
On Fri, Nov 11, 2016 at 10:17:55AM +0100, Daniel Vetter wrote:
> On Thu, Nov 10, 2016 at 03:56:30PM +0100, Maxime Ripard wrote:
> > Hi Daniel,
> >
> > On Tue, Nov 08, 2016 at 09:59:27AM +0100, Daniel Vetter wrote:
> > > On Tue, Oct 18, 2016 at 10:29:38AM +0200, Maxime Ripard wrote:
> > > > Create overscan profiles reducing the displayed zone.
> > > >
> > > > For each TV standard (PAL and NTSC so far), we create 4 more reduced modes
> > > > by steps of 5% that the user will be able to select.
> > > >
> > > > Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> > >
> > > tbh I think if we agree to do this (and that still seems an open question)
> > > I think there should be a generic helper to add these overscan modes with
> > > increased porches. Anything that only depends upon the sink (and
> > > overscanning is something the sink does) should imo be put into a suitable
> > > helper library for everyone to share.
> > >
> > > Or maybe even stash it into the probe helpers and call it for all TV
> > > connectors. Definitely not a driver-private thing.
> >
> > Last time we discussed it, my recollection was that you didn't want to
> > have generic code for it, but I'd be happy to implement it.
> >
> > I'll come up with something like that.
>
> Well I can flip-flop around with the nonsense I'm sometimes emitting ;-)
> Since you called me out, feel free to do whatever you want ...
I also found the generic solution to be a much better solution, so
I'll definitely implement it :)
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161121/7da26be6/attachment-0001.sig>
^ permalink raw reply
* [GIT PULL] Allwinner arm64 DT changes for 4.9
From: Maxime Ripard @ 2016-11-21 7:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161119003930.GC15902@localhost>
On Fri, Nov 18, 2016 at 04:39:30PM -0800, Olof Johansson wrote:
> On Tue, Nov 15, 2016 at 10:13:33PM +0100, Maxime Ripard wrote:
> > Hi Arnd, Olof,
> >
> > Here are our changes for arm64 DT for the next merge window.
> >
> > Thanks!
> > Maxime
> >
> > The following changes since commit 1001354ca34179f3db924eb66672442a173147dc:
> >
> > Linux 4.9-rc1 (2016-10-15 12:17:50 -0700)
> >
> > are available in the git repository at:
> >
> > https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux.git tags/sunxi-dt64-for-4.10
> >
> > for you to fetch changes up to 4e3886081848b7ea16452a92c4324acaab644d49:
> >
> > arm64: dts: add Pine64 support (2016-11-03 09:08:24 +0100)
> >
> > ----------------------------------------------------------------
> > Allwinner arm64 DT changes for 4.10
> >
> > Support for the Allwinner A64, their first armv8 SoC.
> >
> > ----------------------------------------------------------------
> > Andre Przywara (3):
> > arm64: dts: add Allwinner A64 SoC .dtsi
> > Documentation: devicetree: add vendor prefix for Pine64
> > arm64: dts: add Pine64 support
>
> Hi,
>
> Merged the branch, but please use "arm64: dts: allwinner: <..>" as patch
> prefix in the future. Thanks!
Ack.
Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161121/34f9fa8f/attachment.sig>
^ permalink raw reply
* [PATCH v3 6/9] mtd: spi-nor: Support R/W for S25FS-S family flash
From: Krzeminski, Marcin (Nokia - PL/Wroclaw) @ 2016-11-21 7:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <DB6PR0401MB24070BB49A1F5152A915AE3289B50@DB6PR0401MB2407.eurprd04.prod.outlook.com>
> -----Original Message-----
> From: Yao Yuan [mailto:yao.yuan at nxp.com]
> Sent: Monday, November 21, 2016 7:28 AM
> To: Krzeminski, Marcin (Nokia - PL/Wroclaw)
> <marcin.krzeminski@nokia.com>; Han Xu <xhnjupt@gmail.com>
> Cc: David Woodhouse <dwmw2@infradead.org>; linux-
> kernel at vger.kernel.org; linux-mtd at lists.infradead.org;
> han.xu at freescale.com; Brian Norris <computersforpeace@gmail.com>;
> jagannadh.teki at gmail.com; linux-arm-kernel at lists.infradead.org; Cyrille
> Pitchen <cyrille.pitchen@atmel.com>
> Subject: RE: [PATCH v3 6/9] mtd: spi-nor: Support R/W for S25FS-S family
> flash
>
> On Thu, Nov 18, 2016 at 07:00 PM +0000, Krzeminski, Marcin (Nokia -
> PL/Wroclaw) wrote:
> > > -----Original Message-----
> > > From: Yao Yuan [mailto:yao.yuan at nxp.com]
> > > Sent: Friday, November 18, 2016 5:20 AM
> > > To: Krzeminski, Marcin (Nokia - PL/Wroclaw)
> > > <marcin.krzeminski@nokia.com>; Han Xu <xhnjupt@gmail.com>
> > > Cc: David Woodhouse <dwmw2@infradead.org>; linux-
> > > kernel at vger.kernel.org; linux-mtd at lists.infradead.org;
> > > han.xu at freescale.com; Brian Norris <computersforpeace@gmail.com>;
> > > jagannadh.teki at gmail.com; linux-arm-kernel at lists.infradead.org
> > > Subject: RE: [PATCH v3 6/9] mtd: spi-nor: Support R/W for S25FS-S
> > > family flash
> > >
> > > On Thu, Nov 17, 2016 at 10:14:55AM +0000, Krzeminski, Marcin (Nokia
> > > -
> > > PL/Wroclaw) wrote:
> > > > > On Thu, Nov 17, 2016 at 06:50:55AM +0000, Krzeminski, Marcin
> > > > > (Nokia
> > > > > -
> > > > > PL/Wroclaw) wrote:
> > > > > > > > > On Thu, Aug 18, 2016 at 2:38 AM, Yunhui Cui
> > > > > > > > > <B56489@freescale.com>
> > > > > > > > > wrote:
> > > > > > > > > > From: Yunhui Cui <yunhui.cui@nxp.com>
> > > > > > > > > >
> > > > > > > > > > With the physical sectors combination, S25FS-S family
> > > > > > > > > > flash requires some special operations for read/write
> functions.
> > > > > > > > > >
> > > > > > > > > > Signed-off-by: Yunhui Cui <yunhui.cui@nxp.com>
> > > > > > > > > > ---
> > > > > > > > > > drivers/mtd/spi-nor/spi-nor.c | 56
> > > > > > > > > > +++++++++++++++++++++++++++++++++++++++++++
> > > > > > > > > > 1 file changed, 56 insertions(+)
> > > > > > > > > >
> > > > > > > > > > diff --git a/drivers/mtd/spi-nor/spi-nor.c
> > > > > > > > > > b/drivers/mtd/spi-nor/spi-nor.c index d0fc165..495d0bb
> > > > > > > > > > 100644
> > > > > > > > > > --- a/drivers/mtd/spi-nor/spi-nor.c
> > > > > > > > > > +++ b/drivers/mtd/spi-nor/spi-nor.c
> > > > > > > > > > @@ -39,6 +39,10 @@
> > > > > > > > > >
> > > > > > > > > > #define SPI_NOR_MAX_ID_LEN 6
> > > > > > > > > > #define SPI_NOR_MAX_ADDR_WIDTH 4
> > > > > > > > > > +/* Added for S25FS-S family flash */
> > > > > > > > > > +#define SPINOR_CONFIG_REG3_OFFSET 0x800004
> > > > > > > > > > +#define CR3V_4KB_ERASE_UNABLE 0x8 #define
> > > > > > > > > > +SPINOR_S25FS_FAMILY_EXT_JEDEC 0x81
> > > > > > > > > >
> > > > > > > > > > struct flash_info {
> > > > > > > > > > char *name;
> > > > > > > > > > @@ -78,6 +82,7 @@ struct flash_info { };
> > > > > > > > > >
> > > > > > > > > > #define JEDEC_MFR(info) ((info)->id[0])
> > > > > > > > > > +#define EXT_JEDEC(info) ((info)->id[5])
> > > > > > > > > >
> > > > > > > > > > static const struct flash_info
> > > > > > > > > > *spi_nor_match_id(const char *name);
> > > > > > > > > >
> > > > > > > > > > @@ -899,6 +904,7 @@ static const struct flash_info
> > > spi_nor_ids[] = {
> > > > > > > > > > */
> > > > > > > > > > { "s25sl032p", INFO(0x010215, 0x4d00, 64 *
> > > > > > > > > > 1024, 64,
> > > > > > > > > SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> > > > > > > > > > { "s25sl064p", INFO(0x010216, 0x4d00, 64 *
> > > > > > > > > > 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
> },
> > > > > > > > > > + { "s25fs256s1", INFO6(0x010219, 0x4d0181, 64 *
> > > > > > > > > > + 1024, 512, 0)},
> > > > > > > > > > { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128,
> 0) },
> > > > > > > > > > { "s25fl256s1", INFO(0x010219, 0x4d01, 64 *
> > > > > > > > > > 1024, 512,
> > > > > > > > > SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> > > > > > > > > > { "s25fl512s", INFO(0x010220, 0x4d00, 256 *
> > > > > > > > > > 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
> },
> > @@
> > > > > > > > > > -
> > > 1036,6
> > > > > > > +1042,50
> > > > > > > > > @@ static const struct flash_info
> > > > > > > > > *spi_nor_read_id(struct spi_nor
> > > > > > > > > *nor)
> > > > > > > > > > return ERR_PTR(-ENODEV); }
> > > > > > > > > >
> > > > > > > > > > +/*
> > > > > > > > > > + * The S25FS-S family physical sectors may be
> > > > > > > > > > +configured as a
> > > > > > > > > > + * hybrid combination of eight 4-kB parameter sectors
> > > > > > > > > > + * at the top or bottom of the address space with all
> > > > > > > > > > + * but one of the remaining sectors being uniform size.
> > > > > > > > > > + * The Parameter Sector Erase commands (20h or 21h)
> > > > > > > > > > +must
> > > > > > > > > > + * be used to erase the 4-kB parameter sectors individually.
> > > > > > > > > > + * The Sector (uniform sector) Erase commands (D8h or
> > > > > > > > > > +DCh)
> > > > > > > > > > + * must be used to erase any of the remaining
> > > > > > > > > > + * sectors, including the portion of highest or
> > > > > > > > > > +lowest address
> > > > > > > > > > + * sector that is not overlaid by the parameter sectors.
> > > > > > > > > > + * The uniform sector erase command has no effect on
> > > > > > > > > > +parameter
> > > > > > > > > sectors.
> > > > > > > > > > + */
> > > > > > > > > > +static int spansion_s25fs_disable_4kb_erase(struct
> > > > > > > > > > +spi_nor
> > > *nor) {
> > > > > > > > > > + u32 cr3v_addr = SPINOR_CONFIG_REG3_OFFSET;
> > > > > > > > > > + u8 cr3v = 0x0;
> > > > > > > > > > + int ret = 0x0;
> > > > > > > > > > +
> > > > > > > > > > + nor->cmd_buf[2] = cr3v_addr >> 16;
> > > > > > > > > > + nor->cmd_buf[1] = cr3v_addr >> 8;
> > > > > > > > > > + nor->cmd_buf[0] = cr3v_addr >> 0;
> > > > > > > > > > +
> > > > > > > > > > + ret = nor->read_reg(nor,
> > > > > > > > > > + SPINOR_OP_SPANSION_RDAR,
> > > > > &cr3v, 1);
> > > > > > > > > > + if (ret)
> > > > > > > > > > + return ret;
> > > > > > > > > > + if (cr3v & CR3V_4KB_ERASE_UNABLE)
> > > > > > > > > > + return 0;
> > > > > > > > > > + ret = nor->write_reg(nor, SPINOR_OP_WREN, NULL, 0);
> > > > > > > > > > + if (ret)
> > > > > > > > > > + return ret;
> > > > > > > > > > + cr3v = CR3V_4KB_ERASE_UNABLE;
> > > > > > > > > > + nor->program_opcode =
> SPINOR_OP_SPANSION_WRAR;
> > > > > > > > > > + nor->write(nor, cr3v_addr, 1, &cr3v);
> > > > > > > > > > +
> > > > > > > > > > + ret = nor->read_reg(nor,
> > > > > > > > > > + SPINOR_OP_SPANSION_RDAR,
> > > > > &cr3v, 1);
> > > > > > > > > > + if (ret)
> > > > > > > > > > + return ret;
> > > > > > > > > > + if (!(cr3v & CR3V_4KB_ERASE_UNABLE))
> > > > > > > > > > + return -EPERM;
> > > > > > > > > > +
> > > > > > > > > > + return 0;
> > > > > > > > > > +}
> > > > > > > > > > +
> > > > > > > > > > static int spi_nor_read(struct mtd_info *mtd, loff_t
> > > > > > > > > > from, size_t
> > > > > len,
> > > > > > > > > > size_t *retlen, u_char *buf)
> > > > > > > > > > { @@
> > > > > > > > > > -1361,6
> > > > > > > > > > +1411,12 @@ int spi_nor_scan(struct spi_nor *nor,
> > > > > > > > > > +const char *name,
> > > > > > > > > enum read_mode mode)
> > > > > > > > > > spi_nor_wait_till_ready(nor);
> > > > > > > > > > }
> > > > > > > > > >
> > > > > > > > > > + if (EXT_JEDEC(info) ==
> > > > > > > > > > + SPINOR_S25FS_FAMILY_EXT_JEDEC)
> > > {
> > > > > > > > > > + ret = spansion_s25fs_disable_4kb_erase(nor);
> > > > > > > > > > + if (ret)
> > > > > > > > > > + return ret;
> > > > > > > > > > + }
> > > > > > > > > > +
> > > > > > > > > > if (!mtd->name)
> > > > > > > > > > mtd->name = dev_name(dev);
> > > > > > > > > > mtd->priv = nor;
> > > > > > > > > > --
> > > > > > > > > > 2.1.0.27.g96db324
> > > > > > > > > >
> > > > > > > > > >
> > > > > > > > > Hi Brian, I will ack this change but still feel it's kind of hacking
> code.
> > > > > > > > >
> > > > > > > > > Acked-by: Han xu <han.xu@nxp.com>
> > > > > > > >
> > > > > > > > I am new on the list so I am not sure if this topic has been
> discussed.
> > > > > > > > Generally our product functionality relay on those 4KiB sectors.
> > > > > > > > I know that this hack is already in u-boot, but if you
> > > > > > > > mainstream this you will force users of those 4KiB sectors
> > > > > > > > to do hack the
> > > > hack...
> > > > > > > > I believe the proper solution here is to use erase regions
> > > > > > > > functionality, I send and RFS about that some time ago.
> > > > > > >
> > > > > > > Do you mind to send me a link for reference?
> > > > > > >
> > > > > > Han,
> > > > > >
> > > > > > Sorry, It seem I have not posted erase region changes (only
> > > > > > those regarding DUAL/QUAD I/O).
> > > > > > Generally, in this flash you need to create 3 erase regions
> > > > > > (because in FS-S family support only 4KiB erase on parameters
> > > > > > sector -
> > > eg.
> > > > > > 1.2.2.4 in
> > > > > S25FS512S).
> > > > > > In my case regions are:
> > > > > > 1. 0-32KiB (8*4KiB) - 4K_ERASE (0x20/0x21) 2. 32 - 256 -
> > > > > > SE_CMD
> > > > > (0xd8/0xdc) 3.
> > > > > > Rest of the flash SE_CMD (0xd8/0xdc)
> > > > > >
> > > > > > To erase whole flash you can also use CHIP_ERASE_CMD
> > > > > > (0x60/0xC7) command, you just need to add one more mtd
> > > > > > partition that will cover
> > > > > whole flash.
> > > > > >
> > > > >
> > > > > Hi Krzeminski,
> > > > >
> > > > > Do you think is there any great advantages for enable 4KB?
> > > > > Because for NXP(Freescale) QSPI controller, there is only
> > > > > support max to 16 groups command.
> > > > >
> > > > > So It's hard to give 3 groups command just for erase (0x21,0xdc and
> 0xc7).
> > > > > So we have to disable the 4kb erase and only use 256kbytes in this
> patch.
> > > > >
> > > > Yes, if you disable parameters sector in spi-nor framework you
> > > > will disable it for all spi-nor clients not only for NXP QSPI controller.
> > > > There are users (at least me) that relay on parameters sector
> functionality.
> > > This patch will brake it.
> > > >
> > > > Thanks,
> > >
> > > Hi Krzeminski,
> > >
> > > Get it.
> > > So do you think how about that I add a flag in dts to select it?
> > > The user want's disable 4kb, he can add the flag.
> > >
> > > In spi-nor.c:
> > > if (of_property_read_bool(np, "spi-nor, disable-4kb")) {
> > > spansion_s25fs_disable_4kb_erase();
> > > }
> > > else
> > > ...
> > >
> > > In dts:
> > >
> > > &qspi {
> > > num-cs = <2>;
> > > bus-num = <0>;
> > > status = "okay";
> > >
> > > qflash0: s25fs512s at 0 {
> > > compatible = "spansion, s25fs512s";
> > > spi-nor, disable-4kb
> > > #address-cells = <1>;
> > > #size-cells = <1>;
> > > spi-max-frequency = <20000000>;
> > > reg = <0>;
> > > };
> > >
> > > I think it should be a better way.
> > >
> > > How about your think?
> >
> > This looks much better - at least for me.
> > There are some parameters in JESD216 standard regarding parameters
> > sector, but unfortunately I have not investigated that. You can take a
> > look at Cyrille series, that adds support for JESD216 standard.
> >
>
> Ok, I will resend v4 for add this.
>
> BTW, the 4-kytes block for S25FS is just only the first 8 blocks, the other block
> is 256kytes.
> Do out SPI-NOR support erase those specific combination?
>
> If not, do you have any plan for add it?
> It seems I can't fine the support in spi-nor.
>
Those erase regions are solution for such flash, current upstream version does not
have this. My solution is not universal, so probably I will not add it.
Regards,
Marcin
> Thanks.
^ permalink raw reply
* [PATCH v3 6/9] mtd: spi-nor: Support R/W for S25FS-S family flash
From: Yao Yuan @ 2016-11-21 6:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CA+EcR20gNsuWG7pXimCmXmMy1wFFOv+zocMXTQoFhysGQ+wEFA@mail.gmail.com>
On Thu, Nov 18, 2016 at 12:31 PM, Han Xu wrote:
> On Thu, Nov 17, 2016 at 3:14 AM, Yao Yuan <yao.yuan@nxp.com> wrote:
> > On Thu, Nov 17, 2016 at 06:50:55AM +0000, Krzeminski, Marcin (Nokia -
> PL/Wroclaw) wrote:
> >> > > > On Thu, Aug 18, 2016 at 2:38 AM, Yunhui Cui
> >> > > > <B56489@freescale.com>
> >> > > > wrote:
> >> > > > > From: Yunhui Cui <yunhui.cui@nxp.com>
> >> > > > >
> >> > > > > With the physical sectors combination, S25FS-S family flash
> >> > > > > requires some special operations for read/write functions.
> >> > > > >
> >> > > > > Signed-off-by: Yunhui Cui <yunhui.cui@nxp.com>
> >> > > > > ---
> >> > > > > drivers/mtd/spi-nor/spi-nor.c | 56
> >> > > > > +++++++++++++++++++++++++++++++++++++++++++
> >> > > > > 1 file changed, 56 insertions(+)
> >> > > > >
> >> > > > > diff --git a/drivers/mtd/spi-nor/spi-nor.c
> >> > > > > b/drivers/mtd/spi-nor/spi-nor.c index d0fc165..495d0bb 100644
> >> > > > > --- a/drivers/mtd/spi-nor/spi-nor.c
> >> > > > > +++ b/drivers/mtd/spi-nor/spi-nor.c
> >> > > > > @@ -39,6 +39,10 @@
> >> > > > >
> >> > > > > #define SPI_NOR_MAX_ID_LEN 6
> >> > > > > #define SPI_NOR_MAX_ADDR_WIDTH 4
> >> > > > > +/* Added for S25FS-S family flash */
> >> > > > > +#define SPINOR_CONFIG_REG3_OFFSET 0x800004
> >> > > > > +#define CR3V_4KB_ERASE_UNABLE 0x8 #define
> >> > > > > +SPINOR_S25FS_FAMILY_EXT_JEDEC 0x81
> >> > > > >
> >> > > > > struct flash_info {
> >> > > > > char *name;
> >> > > > > @@ -78,6 +82,7 @@ struct flash_info { };
> >> > > > >
> >> > > > > #define JEDEC_MFR(info) ((info)->id[0])
> >> > > > > +#define EXT_JEDEC(info) ((info)->id[5])
> >> > > > >
> >> > > > > static const struct flash_info *spi_nor_match_id(const char
> >> > > > > *name);
> >> > > > >
> >> > > > > @@ -899,6 +904,7 @@ static const struct flash_info spi_nor_ids[] = {
> >> > > > > */
> >> > > > > { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024,
> >> > > > > 64,
> >> > > > SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> >> > > > > { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024,
> >> > > > > 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> >> > > > > + { "s25fs256s1", INFO6(0x010219, 0x4d0181, 64 * 1024,
> >> > > > > + 512, 0)},
> >> > > > > { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
> >> > > > > { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024,
> >> > > > > 512,
> >> > > > SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> >> > > > > { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024,
> >> > > > > 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, @@ -1036,6
> >> > +1042,50
> >> > > > @@ static const struct flash_info *spi_nor_read_id(struct
> >> > > > spi_nor
> >> > > > *nor)
> >> > > > > return ERR_PTR(-ENODEV); }
> >> > > > >
> >> > > > > +/*
> >> > > > > + * The S25FS-S family physical sectors may be configured as
> >> > > > > +a
> >> > > > > + * hybrid combination of eight 4-kB parameter sectors
> >> > > > > + * at the top or bottom of the address space with all
> >> > > > > + * but one of the remaining sectors being uniform size.
> >> > > > > + * The Parameter Sector Erase commands (20h or 21h) must
> >> > > > > + * be used to erase the 4-kB parameter sectors individually.
> >> > > > > + * The Sector (uniform sector) Erase commands (D8h or DCh)
> >> > > > > + * must be used to erase any of the remaining
> >> > > > > + * sectors, including the portion of highest or lowest
> >> > > > > +address
> >> > > > > + * sector that is not overlaid by the parameter sectors.
> >> > > > > + * The uniform sector erase command has no effect on
> >> > > > > +parameter
> >> > > > sectors.
> >> > > > > + */
> >> > > > > +static int spansion_s25fs_disable_4kb_erase(struct spi_nor *nor) {
> >> > > > > + u32 cr3v_addr = SPINOR_CONFIG_REG3_OFFSET;
> >> > > > > + u8 cr3v = 0x0;
> >> > > > > + int ret = 0x0;
> >> > > > > +
> >> > > > > + nor->cmd_buf[2] = cr3v_addr >> 16;
> >> > > > > + nor->cmd_buf[1] = cr3v_addr >> 8;
> >> > > > > + nor->cmd_buf[0] = cr3v_addr >> 0;
> >> > > > > +
> >> > > > > + ret = nor->read_reg(nor, SPINOR_OP_SPANSION_RDAR, &cr3v,
> 1);
> >> > > > > + if (ret)
> >> > > > > + return ret;
> >> > > > > + if (cr3v & CR3V_4KB_ERASE_UNABLE)
> >> > > > > + return 0;
> >> > > > > + ret = nor->write_reg(nor, SPINOR_OP_WREN, NULL, 0);
> >> > > > > + if (ret)
> >> > > > > + return ret;
> >> > > > > + cr3v = CR3V_4KB_ERASE_UNABLE;
> >> > > > > + nor->program_opcode = SPINOR_OP_SPANSION_WRAR;
> >> > > > > + nor->write(nor, cr3v_addr, 1, &cr3v);
> >> > > > > +
> >> > > > > + ret = nor->read_reg(nor, SPINOR_OP_SPANSION_RDAR, &cr3v,
> 1);
> >> > > > > + if (ret)
> >> > > > > + return ret;
> >> > > > > + if (!(cr3v & CR3V_4KB_ERASE_UNABLE))
> >> > > > > + return -EPERM;
> >> > > > > +
> >> > > > > + return 0;
> >> > > > > +}
> >> > > > > +
> >> > > > > static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
> >> > > > > size_t *retlen, u_char *buf) { @@
> >> > > > > -1361,6
> >> > > > > +1411,12 @@ int spi_nor_scan(struct spi_nor *nor, const char
> >> > > > > +*name,
> >> > > > enum read_mode mode)
> >> > > > > spi_nor_wait_till_ready(nor);
> >> > > > > }
> >> > > > >
> >> > > > > + if (EXT_JEDEC(info) == SPINOR_S25FS_FAMILY_EXT_JEDEC) {
> >> > > > > + ret = spansion_s25fs_disable_4kb_erase(nor);
> >> > > > > + if (ret)
> >> > > > > + return ret;
> >> > > > > + }
> >> > > > > +
> >> > > > > if (!mtd->name)
> >> > > > > mtd->name = dev_name(dev);
> >> > > > > mtd->priv = nor;
> >> > > > > --
> >> > > > > 2.1.0.27.g96db324
> >> > > > >
> >> > > > >
> >> > > > Hi Brian, I will ack this change but still feel it's kind of hacking code.
> >> > > >
> >> > > > Acked-by: Han xu <han.xu@nxp.com>
> >> > >
> >> > > I am new on the list so I am not sure if this topic has been discussed.
> >> > > Generally our product functionality relay on those 4KiB sectors.
> >> > > I know that this hack is already in u-boot, but if you mainstream
> >> > > this you will force users of those 4KiB sectors to do hack the hack...
> >> > > I believe the proper solution here is to use erase regions
> >> > > functionality, I send and RFS about that some time ago.
> >> >
> >> > Do you mind to send me a link for reference?
> >> >
> >> Han,
> >>
> >> Sorry, It seem I have not posted erase region changes (only those
> >> regarding DUAL/QUAD I/O).
> >> Generally, in this flash you need to create 3 erase regions (because
> >> in FS-S family support only 4KiB erase on parameters sector - eg. 1.2.2.4 in
> S25FS512S).
> >> In my case regions are:
> >> 1. 0-32KiB (8*4KiB) - 4K_ERASE (0x20/0x21) 2. 32 - 256 - SE_CMD (0xd8/0xdc)
> 3.
> >> Rest of the flash SE_CMD (0xd8/0xdc)
> >>
> >> To erase whole flash you can also use CHIP_ERASE_CMD (0x60/0xC7)
> >> command, you just need to add one more mtd partition that will cover
> whole flash.
> >>
> >
> > Hi Krzeminski,
> >
> > Do you think is there any great advantages for enable 4KB?
> > Because for NXP(Freescale) QSPI controller, there is only support max to 16
> groups command.
>
> If it's really necessary to support all command groups, you can try apply my
> dynamic lut patch first.
> https://patchwork.ozlabs.org/patch/676791/
>
I think it will be helpful, I will test and check it.
Thanks,
^ permalink raw reply
* [PATCH v3 6/9] mtd: spi-nor: Support R/W for S25FS-S family flash
From: Yao Yuan @ 2016-11-21 6:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AM4PR0701MB21302592BE1B712D6E74C569FEB00@AM4PR0701MB2130.eurprd07.prod.outlook.com>
On Thu, Nov 18, 2016 at 07:00 PM +0000, Krzeminski, Marcin (Nokia - PL/Wroclaw) wrote:
> > -----Original Message-----
> > From: Yao Yuan [mailto:yao.yuan at nxp.com]
> > Sent: Friday, November 18, 2016 5:20 AM
> > To: Krzeminski, Marcin (Nokia - PL/Wroclaw)
> > <marcin.krzeminski@nokia.com>; Han Xu <xhnjupt@gmail.com>
> > Cc: David Woodhouse <dwmw2@infradead.org>; linux-
> > kernel at vger.kernel.org; linux-mtd at lists.infradead.org;
> > han.xu at freescale.com; Brian Norris <computersforpeace@gmail.com>;
> > jagannadh.teki at gmail.com; linux-arm-kernel at lists.infradead.org
> > Subject: RE: [PATCH v3 6/9] mtd: spi-nor: Support R/W for S25FS-S
> > family flash
> >
> > On Thu, Nov 17, 2016 at 10:14:55AM +0000, Krzeminski, Marcin (Nokia -
> > PL/Wroclaw) wrote:
> > > > On Thu, Nov 17, 2016 at 06:50:55AM +0000, Krzeminski, Marcin
> > > > (Nokia
> > > > -
> > > > PL/Wroclaw) wrote:
> > > > > > > > On Thu, Aug 18, 2016 at 2:38 AM, Yunhui Cui
> > > > > > > > <B56489@freescale.com>
> > > > > > > > wrote:
> > > > > > > > > From: Yunhui Cui <yunhui.cui@nxp.com>
> > > > > > > > >
> > > > > > > > > With the physical sectors combination, S25FS-S family
> > > > > > > > > flash requires some special operations for read/write functions.
> > > > > > > > >
> > > > > > > > > Signed-off-by: Yunhui Cui <yunhui.cui@nxp.com>
> > > > > > > > > ---
> > > > > > > > > drivers/mtd/spi-nor/spi-nor.c | 56
> > > > > > > > > +++++++++++++++++++++++++++++++++++++++++++
> > > > > > > > > 1 file changed, 56 insertions(+)
> > > > > > > > >
> > > > > > > > > diff --git a/drivers/mtd/spi-nor/spi-nor.c
> > > > > > > > > b/drivers/mtd/spi-nor/spi-nor.c index d0fc165..495d0bb
> > > > > > > > > 100644
> > > > > > > > > --- a/drivers/mtd/spi-nor/spi-nor.c
> > > > > > > > > +++ b/drivers/mtd/spi-nor/spi-nor.c
> > > > > > > > > @@ -39,6 +39,10 @@
> > > > > > > > >
> > > > > > > > > #define SPI_NOR_MAX_ID_LEN 6
> > > > > > > > > #define SPI_NOR_MAX_ADDR_WIDTH 4
> > > > > > > > > +/* Added for S25FS-S family flash */
> > > > > > > > > +#define SPINOR_CONFIG_REG3_OFFSET 0x800004
> > > > > > > > > +#define CR3V_4KB_ERASE_UNABLE 0x8 #define
> > > > > > > > > +SPINOR_S25FS_FAMILY_EXT_JEDEC 0x81
> > > > > > > > >
> > > > > > > > > struct flash_info {
> > > > > > > > > char *name;
> > > > > > > > > @@ -78,6 +82,7 @@ struct flash_info { };
> > > > > > > > >
> > > > > > > > > #define JEDEC_MFR(info) ((info)->id[0])
> > > > > > > > > +#define EXT_JEDEC(info) ((info)->id[5])
> > > > > > > > >
> > > > > > > > > static const struct flash_info *spi_nor_match_id(const
> > > > > > > > > char *name);
> > > > > > > > >
> > > > > > > > > @@ -899,6 +904,7 @@ static const struct flash_info
> > spi_nor_ids[] = {
> > > > > > > > > */
> > > > > > > > > { "s25sl032p", INFO(0x010215, 0x4d00, 64 *
> > > > > > > > > 1024, 64,
> > > > > > > > SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> > > > > > > > > { "s25sl064p", INFO(0x010216, 0x4d00, 64 *
> > > > > > > > > 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> > > > > > > > > + { "s25fs256s1", INFO6(0x010219, 0x4d0181, 64 *
> > > > > > > > > + 1024, 512, 0)},
> > > > > > > > > { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
> > > > > > > > > { "s25fl256s1", INFO(0x010219, 0x4d01, 64 *
> > > > > > > > > 1024, 512,
> > > > > > > > SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> > > > > > > > > { "s25fl512s", INFO(0x010220, 0x4d00, 256 *
> > > > > > > > > 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> @@
> > > > > > > > > -
> > 1036,6
> > > > > > +1042,50
> > > > > > > > @@ static const struct flash_info *spi_nor_read_id(struct
> > > > > > > > spi_nor
> > > > > > > > *nor)
> > > > > > > > > return ERR_PTR(-ENODEV); }
> > > > > > > > >
> > > > > > > > > +/*
> > > > > > > > > + * The S25FS-S family physical sectors may be
> > > > > > > > > +configured as a
> > > > > > > > > + * hybrid combination of eight 4-kB parameter sectors
> > > > > > > > > + * at the top or bottom of the address space with all
> > > > > > > > > + * but one of the remaining sectors being uniform size.
> > > > > > > > > + * The Parameter Sector Erase commands (20h or 21h)
> > > > > > > > > +must
> > > > > > > > > + * be used to erase the 4-kB parameter sectors individually.
> > > > > > > > > + * The Sector (uniform sector) Erase commands (D8h or
> > > > > > > > > +DCh)
> > > > > > > > > + * must be used to erase any of the remaining
> > > > > > > > > + * sectors, including the portion of highest or lowest
> > > > > > > > > +address
> > > > > > > > > + * sector that is not overlaid by the parameter sectors.
> > > > > > > > > + * The uniform sector erase command has no effect on
> > > > > > > > > +parameter
> > > > > > > > sectors.
> > > > > > > > > + */
> > > > > > > > > +static int spansion_s25fs_disable_4kb_erase(struct
> > > > > > > > > +spi_nor
> > *nor) {
> > > > > > > > > + u32 cr3v_addr = SPINOR_CONFIG_REG3_OFFSET;
> > > > > > > > > + u8 cr3v = 0x0;
> > > > > > > > > + int ret = 0x0;
> > > > > > > > > +
> > > > > > > > > + nor->cmd_buf[2] = cr3v_addr >> 16;
> > > > > > > > > + nor->cmd_buf[1] = cr3v_addr >> 8;
> > > > > > > > > + nor->cmd_buf[0] = cr3v_addr >> 0;
> > > > > > > > > +
> > > > > > > > > + ret = nor->read_reg(nor,
> > > > > > > > > + SPINOR_OP_SPANSION_RDAR,
> > > > &cr3v, 1);
> > > > > > > > > + if (ret)
> > > > > > > > > + return ret;
> > > > > > > > > + if (cr3v & CR3V_4KB_ERASE_UNABLE)
> > > > > > > > > + return 0;
> > > > > > > > > + ret = nor->write_reg(nor, SPINOR_OP_WREN, NULL, 0);
> > > > > > > > > + if (ret)
> > > > > > > > > + return ret;
> > > > > > > > > + cr3v = CR3V_4KB_ERASE_UNABLE;
> > > > > > > > > + nor->program_opcode = SPINOR_OP_SPANSION_WRAR;
> > > > > > > > > + nor->write(nor, cr3v_addr, 1, &cr3v);
> > > > > > > > > +
> > > > > > > > > + ret = nor->read_reg(nor,
> > > > > > > > > + SPINOR_OP_SPANSION_RDAR,
> > > > &cr3v, 1);
> > > > > > > > > + if (ret)
> > > > > > > > > + return ret;
> > > > > > > > > + if (!(cr3v & CR3V_4KB_ERASE_UNABLE))
> > > > > > > > > + return -EPERM;
> > > > > > > > > +
> > > > > > > > > + return 0;
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > > static int spi_nor_read(struct mtd_info *mtd, loff_t
> > > > > > > > > from, size_t
> > > > len,
> > > > > > > > > size_t *retlen, u_char *buf) {
> > > > > > > > > @@
> > > > > > > > > -1361,6
> > > > > > > > > +1411,12 @@ int spi_nor_scan(struct spi_nor *nor, const
> > > > > > > > > +char *name,
> > > > > > > > enum read_mode mode)
> > > > > > > > > spi_nor_wait_till_ready(nor);
> > > > > > > > > }
> > > > > > > > >
> > > > > > > > > + if (EXT_JEDEC(info) ==
> > > > > > > > > + SPINOR_S25FS_FAMILY_EXT_JEDEC)
> > {
> > > > > > > > > + ret = spansion_s25fs_disable_4kb_erase(nor);
> > > > > > > > > + if (ret)
> > > > > > > > > + return ret;
> > > > > > > > > + }
> > > > > > > > > +
> > > > > > > > > if (!mtd->name)
> > > > > > > > > mtd->name = dev_name(dev);
> > > > > > > > > mtd->priv = nor;
> > > > > > > > > --
> > > > > > > > > 2.1.0.27.g96db324
> > > > > > > > >
> > > > > > > > >
> > > > > > > > Hi Brian, I will ack this change but still feel it's kind of hacking code.
> > > > > > > >
> > > > > > > > Acked-by: Han xu <han.xu@nxp.com>
> > > > > > >
> > > > > > > I am new on the list so I am not sure if this topic has been discussed.
> > > > > > > Generally our product functionality relay on those 4KiB sectors.
> > > > > > > I know that this hack is already in u-boot, but if you
> > > > > > > mainstream this you will force users of those 4KiB sectors
> > > > > > > to do hack the
> > > hack...
> > > > > > > I believe the proper solution here is to use erase regions
> > > > > > > functionality, I send and RFS about that some time ago.
> > > > > >
> > > > > > Do you mind to send me a link for reference?
> > > > > >
> > > > > Han,
> > > > >
> > > > > Sorry, It seem I have not posted erase region changes (only
> > > > > those regarding DUAL/QUAD I/O).
> > > > > Generally, in this flash you need to create 3 erase regions
> > > > > (because in FS-S family support only 4KiB erase on parameters
> > > > > sector -
> > eg.
> > > > > 1.2.2.4 in
> > > > S25FS512S).
> > > > > In my case regions are:
> > > > > 1. 0-32KiB (8*4KiB) - 4K_ERASE (0x20/0x21) 2. 32 - 256 - SE_CMD
> > > > (0xd8/0xdc) 3.
> > > > > Rest of the flash SE_CMD (0xd8/0xdc)
> > > > >
> > > > > To erase whole flash you can also use CHIP_ERASE_CMD (0x60/0xC7)
> > > > > command, you just need to add one more mtd partition that will
> > > > > cover
> > > > whole flash.
> > > > >
> > > >
> > > > Hi Krzeminski,
> > > >
> > > > Do you think is there any great advantages for enable 4KB?
> > > > Because for NXP(Freescale) QSPI controller, there is only support
> > > > max to 16 groups command.
> > > >
> > > > So It's hard to give 3 groups command just for erase (0x21,0xdc and 0xc7).
> > > > So we have to disable the 4kb erase and only use 256kbytes in this patch.
> > > >
> > > Yes, if you disable parameters sector in spi-nor framework you will
> > > disable it for all spi-nor clients not only for NXP QSPI controller.
> > > There are users (at least me) that relay on parameters sector functionality.
> > This patch will brake it.
> > >
> > > Thanks,
> >
> > Hi Krzeminski,
> >
> > Get it.
> > So do you think how about that I add a flag in dts to select it?
> > The user want's disable 4kb, he can add the flag.
> >
> > In spi-nor.c:
> > if (of_property_read_bool(np, "spi-nor, disable-4kb")) {
> > spansion_s25fs_disable_4kb_erase();
> > }
> > else
> > ...
> >
> > In dts:
> >
> > &qspi {
> > num-cs = <2>;
> > bus-num = <0>;
> > status = "okay";
> >
> > qflash0: s25fs512s at 0 {
> > compatible = "spansion, s25fs512s";
> > spi-nor, disable-4kb
> > #address-cells = <1>;
> > #size-cells = <1>;
> > spi-max-frequency = <20000000>;
> > reg = <0>;
> > };
> >
> > I think it should be a better way.
> >
> > How about your think?
>
> This looks much better - at least for me.
> There are some parameters in JESD216 standard regarding parameters sector,
> but unfortunately I have not investigated that. You can take a look at Cyrille
> series, that adds support for JESD216 standard.
>
Ok, I will resend v4 for add this.
BTW, the 4-kytes block for S25FS is just only the first 8 blocks, the other block is 256kytes.
Do out SPI-NOR support erase those specific combination?
If not, do you have any plan for add it?
It seems I can't fine the support in spi-nor.
Thanks.
^ permalink raw reply
* [PATCH v16 04/15] clocksource/drivers/arm_arch_timer: rename some enums and defines, and some cleanups.
From: Fu Wei @ 2016-11-21 6:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161118184913.GH1197@leverpostej>
Hi Mark,
On 19 November 2016 at 02:49, Mark Rutland <mark.rutland@arm.com> wrote:
> On Wed, Nov 16, 2016 at 09:48:57PM +0800, fu.wei at linaro.org wrote:
>> From: Fu Wei <fu.wei@linaro.org>
>>
>> Rename some enums and defines, to unify the format of enums and defines
>> in arm_arch_timer.h, also update all the users of these enums and defines:
>> drivers/clocksource/arm_arch_timer.c
>> virt/kvm/arm/hyp/timer-sr.c
>
> I'm happy with making definitions use a consistent ARCH_TIMER_ prefix,
> given they're exposed in headers...
>
>> And do some cleanups, according to the suggestion from checkpatch.pl:
>> (1) using BIT(nr) instead of (1 << nr)
>> (2) using 'unsigned int' instead of 'unsigned'
>
> ... but these changes are pointless churn. They make the patch larger,
> hardwer to review, and more painful to merge.
>
> Please leave these as they are unless there is a functional problem. If
> there will be a functional problem unless these are changed, describe
> that in the commit message.
OK, Mark.
I will take these out of patch, thanks :-)
>
> Thanks,
> Mark.
>
>>
>> No functional change.
>>
>> Signed-off-by: Fu Wei <fu.wei@linaro.org>
>> ---
>> drivers/clocksource/arm_arch_timer.c | 111 ++++++++++++++++++-----------------
>> include/clocksource/arm_arch_timer.h | 40 ++++++-------
>> virt/kvm/arm/hyp/timer-sr.c | 6 +-
>> 3 files changed, 81 insertions(+), 76 deletions(-)
>>
>> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
>> index 15341cf..dd1040d 100644
>> --- a/drivers/clocksource/arm_arch_timer.c
>> +++ b/drivers/clocksource/arm_arch_timer.c
>> @@ -66,11 +66,11 @@ struct arch_timer {
>> #define to_arch_timer(e) container_of(e, struct arch_timer, evt)
>>
>> static u32 arch_timer_rate;
>> -static int arch_timer_ppi[MAX_TIMER_PPI];
>> +static int arch_timer_ppi[ARCH_TIMER_MAX_TIMER_PPI];
>>
>> static struct clock_event_device __percpu *arch_timer_evt;
>>
>> -static enum arch_timer_ppi_nr arch_timer_uses_ppi = VIRT_PPI;
>> +static enum arch_timer_ppi_nr arch_timer_uses_ppi = ARCH_TIMER_VIRT_PPI;
>> static bool arch_timer_c3stop;
>> static bool arch_timer_mem_use_virtual;
>>
>> @@ -340,7 +340,7 @@ static void fsl_a008585_set_sne(struct clock_event_device *clk)
>> if (!static_branch_unlikely(&arch_timer_read_ool_enabled))
>> return;
>>
>> - if (arch_timer_uses_ppi == VIRT_PPI)
>> + if (arch_timer_uses_ppi == ARCH_TIMER_VIRT_PPI)
>> clk->set_next_event = fsl_a008585_set_next_event_virt;
>> else
>> clk->set_next_event = fsl_a008585_set_next_event_phys;
>> @@ -352,7 +352,7 @@ static void __arch_timer_setup(unsigned type,
>> {
>> clk->features = CLOCK_EVT_FEAT_ONESHOT;
>>
>> - if (type == ARCH_CP15_TIMER) {
>> + if (type == ARCH_TIMER_TYPE_CP15) {
>> if (arch_timer_c3stop)
>> clk->features |= CLOCK_EVT_FEAT_C3STOP;
>> clk->name = "arch_sys_timer";
>> @@ -360,14 +360,14 @@ static void __arch_timer_setup(unsigned type,
>> clk->cpumask = cpumask_of(smp_processor_id());
>> clk->irq = arch_timer_ppi[arch_timer_uses_ppi];
>> switch (arch_timer_uses_ppi) {
>> - case VIRT_PPI:
>> + case ARCH_TIMER_VIRT_PPI:
>> clk->set_state_shutdown = arch_timer_shutdown_virt;
>> clk->set_state_oneshot_stopped = arch_timer_shutdown_virt;
>> clk->set_next_event = arch_timer_set_next_event_virt;
>> break;
>> - case PHYS_SECURE_PPI:
>> - case PHYS_NONSECURE_PPI:
>> - case HYP_PPI:
>> + case ARCH_TIMER_PHYS_SECURE_PPI:
>> + case ARCH_TIMER_PHYS_NONSECURE_PPI:
>> + case ARCH_TIMER_HYP_PPI:
>> clk->set_state_shutdown = arch_timer_shutdown_phys;
>> clk->set_state_oneshot_stopped = arch_timer_shutdown_phys;
>> clk->set_next_event = arch_timer_set_next_event_phys;
>> @@ -447,8 +447,8 @@ static void arch_counter_set_user_access(void)
>>
>> static bool arch_timer_has_nonsecure_ppi(void)
>> {
>> - return (arch_timer_uses_ppi == PHYS_SECURE_PPI &&
>> - arch_timer_ppi[PHYS_NONSECURE_PPI]);
>> + return (arch_timer_uses_ppi == ARCH_TIMER_PHYS_SECURE_PPI &&
>> + arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]);
>> }
>>
>> static u32 check_ppi_trigger(int irq)
>> @@ -469,14 +469,15 @@ static int arch_timer_starting_cpu(unsigned int cpu)
>> struct clock_event_device *clk = this_cpu_ptr(arch_timer_evt);
>> u32 flags;
>>
>> - __arch_timer_setup(ARCH_CP15_TIMER, clk);
>> + __arch_timer_setup(ARCH_TIMER_TYPE_CP15, clk);
>>
>> flags = check_ppi_trigger(arch_timer_ppi[arch_timer_uses_ppi]);
>> enable_percpu_irq(arch_timer_ppi[arch_timer_uses_ppi], flags);
>>
>> if (arch_timer_has_nonsecure_ppi()) {
>> - flags = check_ppi_trigger(arch_timer_ppi[PHYS_NONSECURE_PPI]);
>> - enable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI], flags);
>> + flags = check_ppi_trigger(arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]);
>> + enable_percpu_irq(arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI],
>> + flags);
>> }
>>
>> arch_counter_set_user_access();
>> @@ -513,16 +514,17 @@ arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np)
>> static void arch_timer_banner(unsigned type)
>> {
>> pr_info("%s%s%s timer(s) running at %lu.%02luMHz (%s%s%s).\n",
>> - type & ARCH_CP15_TIMER ? "cp15" : "",
>> - type == (ARCH_CP15_TIMER | ARCH_MEM_TIMER) ? " and " : "",
>> - type & ARCH_MEM_TIMER ? "mmio" : "",
>> + type & ARCH_TIMER_TYPE_CP15 ? "cp15" : "",
>> + type == (ARCH_TIMER_TYPE_CP15 | ARCH_TIMER_TYPE_MEM) ?
>> + " and " : "",
>> + type & ARCH_TIMER_TYPE_MEM ? "mmio" : "",
>> (unsigned long)arch_timer_rate / 1000000,
>> (unsigned long)(arch_timer_rate / 10000) % 100,
>> - type & ARCH_CP15_TIMER ?
>> - (arch_timer_uses_ppi == VIRT_PPI) ? "virt" : "phys" :
>> + type & ARCH_TIMER_TYPE_CP15 ?
>> + (arch_timer_uses_ppi == ARCH_TIMER_VIRT_PPI) ? "virt" : "phys" :
>> "",
>> - type == (ARCH_CP15_TIMER | ARCH_MEM_TIMER) ? "/" : "",
>> - type & ARCH_MEM_TIMER ?
>> + type == (ARCH_TIMER_TYPE_CP15 | ARCH_TIMER_TYPE_MEM) ? "/" : "",
>> + type & ARCH_TIMER_TYPE_MEM ?
>> arch_timer_mem_use_virtual ? "virt" : "phys" :
>> "");
>> }
>> @@ -588,8 +590,9 @@ static void __init arch_counter_register(unsigned type)
>> u64 start_count;
>>
>> /* Register the CP15 based counter if we have one */
>> - if (type & ARCH_CP15_TIMER) {
>> - if (IS_ENABLED(CONFIG_ARM64) || arch_timer_uses_ppi == VIRT_PPI)
>> + if (type & ARCH_TIMER_TYPE_CP15) {
>> + if (IS_ENABLED(CONFIG_ARM64) ||
>> + arch_timer_uses_ppi == ARCH_TIMER_VIRT_PPI)
>> arch_timer_read_counter = arch_counter_get_cntvct;
>> else
>> arch_timer_read_counter = arch_counter_get_cntpct;
>> @@ -625,7 +628,7 @@ static void arch_timer_stop(struct clock_event_device *clk)
>>
>> disable_percpu_irq(arch_timer_ppi[arch_timer_uses_ppi]);
>> if (arch_timer_has_nonsecure_ppi())
>> - disable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI]);
>> + disable_percpu_irq(arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]);
>>
>> clk->set_state_shutdown(clk);
>> }
>> @@ -688,24 +691,24 @@ static int __init arch_timer_register(void)
>>
>> ppi = arch_timer_ppi[arch_timer_uses_ppi];
>> switch (arch_timer_uses_ppi) {
>> - case VIRT_PPI:
>> + case ARCH_TIMER_VIRT_PPI:
>> err = request_percpu_irq(ppi, arch_timer_handler_virt,
>> "arch_timer", arch_timer_evt);
>> break;
>> - case PHYS_SECURE_PPI:
>> - case PHYS_NONSECURE_PPI:
>> + case ARCH_TIMER_PHYS_SECURE_PPI:
>> + case ARCH_TIMER_PHYS_NONSECURE_PPI:
>> err = request_percpu_irq(ppi, arch_timer_handler_phys,
>> "arch_timer", arch_timer_evt);
>> - if (!err && arch_timer_ppi[PHYS_NONSECURE_PPI]) {
>> - ppi = arch_timer_ppi[PHYS_NONSECURE_PPI];
>> + if (!err && arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]) {
>> + ppi = arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI];
>> err = request_percpu_irq(ppi, arch_timer_handler_phys,
>> "arch_timer", arch_timer_evt);
>> if (err)
>> - free_percpu_irq(arch_timer_ppi[PHYS_SECURE_PPI],
>> + free_percpu_irq(arch_timer_ppi[ARCH_TIMER_PHYS_SECURE_PPI],
>> arch_timer_evt);
>> }
>> break;
>> - case HYP_PPI:
>> + case ARCH_TIMER_HYP_PPI:
>> err = request_percpu_irq(ppi, arch_timer_handler_phys,
>> "arch_timer", arch_timer_evt);
>> break;
>> @@ -737,7 +740,7 @@ static int __init arch_timer_register(void)
>> out_unreg_notify:
>> free_percpu_irq(arch_timer_ppi[arch_timer_uses_ppi], arch_timer_evt);
>> if (arch_timer_has_nonsecure_ppi())
>> - free_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI],
>> + free_percpu_irq(arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI],
>> arch_timer_evt);
>>
>> out_free:
>> @@ -758,7 +761,7 @@ static int __init arch_timer_mem_register(void __iomem *base, unsigned int irq)
>>
>> t->base = base;
>> t->evt.irq = irq;
>> - __arch_timer_setup(ARCH_MEM_TIMER, &t->evt);
>> + __arch_timer_setup(ARCH_TIMER_TYPE_MEM, &t->evt);
>>
>> if (arch_timer_mem_use_virtual)
>> func = arch_timer_handler_virt_mem;
>> @@ -801,13 +804,15 @@ arch_timer_needs_probing(int type, const struct of_device_id *matches)
>>
>> static int __init arch_timer_common_init(void)
>> {
>> - unsigned mask = ARCH_CP15_TIMER | ARCH_MEM_TIMER;
>> + unsigned int mask = ARCH_TIMER_TYPE_CP15 | ARCH_TIMER_TYPE_MEM;
>>
>> /* Wait until both nodes are probed if we have two timers */
>> if ((arch_timers_present & mask) != mask) {
>> - if (arch_timer_needs_probing(ARCH_MEM_TIMER, arch_timer_mem_of_match))
>> + if (arch_timer_needs_probing(ARCH_TIMER_TYPE_MEM,
>> + arch_timer_mem_of_match))
>> return 0;
>> - if (arch_timer_needs_probing(ARCH_CP15_TIMER, arch_timer_of_match))
>> + if (arch_timer_needs_probing(ARCH_TIMER_TYPE_CP15,
>> + arch_timer_of_match))
>> return 0;
>> }
>>
>> @@ -832,16 +837,16 @@ static int __init arch_timer_init(void)
>> * their CNTHP_*_EL2 counterparts, and use a different PPI
>> * number.
>> */
>> - if (is_hyp_mode_available() || !arch_timer_ppi[VIRT_PPI]) {
>> + if (is_hyp_mode_available() || !arch_timer_ppi[ARCH_TIMER_VIRT_PPI]) {
>> bool has_ppi;
>>
>> if (is_kernel_in_hyp_mode()) {
>> - arch_timer_uses_ppi = HYP_PPI;
>> - has_ppi = !!arch_timer_ppi[HYP_PPI];
>> + arch_timer_uses_ppi = ARCH_TIMER_HYP_PPI;
>> + has_ppi = !!arch_timer_ppi[ARCH_TIMER_HYP_PPI];
>> } else {
>> - arch_timer_uses_ppi = PHYS_SECURE_PPI;
>> - has_ppi = (!!arch_timer_ppi[PHYS_SECURE_PPI] ||
>> - !!arch_timer_ppi[PHYS_NONSECURE_PPI]);
>> + arch_timer_uses_ppi = ARCH_TIMER_PHYS_SECURE_PPI;
>> + has_ppi = (!!arch_timer_ppi[ARCH_TIMER_PHYS_SECURE_PPI] ||
>> + !!arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]);
>> }
>>
>> if (!has_ppi) {
>> @@ -858,7 +863,7 @@ static int __init arch_timer_init(void)
>> if (ret)
>> return ret;
>>
>> - arch_timer_kvm_info.virtual_irq = arch_timer_ppi[VIRT_PPI];
>> + arch_timer_kvm_info.virtual_irq = arch_timer_ppi[ARCH_TIMER_VIRT_PPI];
>>
>> return 0;
>> }
>> @@ -867,13 +872,13 @@ static int __init arch_timer_of_init(struct device_node *np)
>> {
>> int i;
>>
>> - if (arch_timers_present & ARCH_CP15_TIMER) {
>> + if (arch_timers_present & ARCH_TIMER_TYPE_CP15) {
>> pr_warn("multiple nodes in dt, skipping\n");
>> return 0;
>> }
>>
>> - arch_timers_present |= ARCH_CP15_TIMER;
>> - for (i = PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++)
>> + arch_timers_present |= ARCH_TIMER_TYPE_CP15;
>> + for (i = ARCH_TIMER_PHYS_SECURE_PPI; i < ARCH_TIMER_MAX_TIMER_PPI; i++)
>> arch_timer_ppi[i] = irq_of_parse_and_map(np, i);
>>
>> arch_timer_detect_rate(NULL, np);
>> @@ -895,7 +900,7 @@ static int __init arch_timer_of_init(struct device_node *np)
>> */
>> if (IS_ENABLED(CONFIG_ARM) &&
>> of_property_read_bool(np, "arm,cpu-registers-not-fw-configured"))
>> - arch_timer_uses_ppi = PHYS_SECURE_PPI;
>> + arch_timer_uses_ppi = ARCH_TIMER_PHYS_SECURE_PPI;
>>
>> return arch_timer_init();
>> }
>> @@ -909,7 +914,7 @@ static int __init arch_timer_mem_init(struct device_node *np)
>> unsigned int irq, ret = -EINVAL;
>> u32 cnttidr;
>>
>> - arch_timers_present |= ARCH_MEM_TIMER;
>> + arch_timers_present |= ARCH_TIMER_TYPE_MEM;
>> cntctlbase = of_iomap(np, 0);
>> if (!cntctlbase) {
>> pr_err("Can't find CNTCTLBase\n");
>> @@ -1008,28 +1013,28 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table)
>> {
>> struct acpi_table_gtdt *gtdt;
>>
>> - if (arch_timers_present & ARCH_CP15_TIMER) {
>> + if (arch_timers_present & ARCH_TIMER_TYPE_CP15) {
>> pr_warn("already initialized, skipping\n");
>> return -EINVAL;
>> }
>>
>> gtdt = container_of(table, struct acpi_table_gtdt, header);
>>
>> - arch_timers_present |= ARCH_CP15_TIMER;
>> + arch_timers_present |= ARCH_TIMER_TYPE_CP15;
>>
>> - arch_timer_ppi[PHYS_SECURE_PPI] =
>> + arch_timer_ppi[ARCH_TIMER_PHYS_SECURE_PPI] =
>> map_generic_timer_interrupt(gtdt->secure_el1_interrupt,
>> gtdt->secure_el1_flags);
>>
>> - arch_timer_ppi[PHYS_NONSECURE_PPI] =
>> + arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI] =
>> map_generic_timer_interrupt(gtdt->non_secure_el1_interrupt,
>> gtdt->non_secure_el1_flags);
>>
>> - arch_timer_ppi[VIRT_PPI] =
>> + arch_timer_ppi[ARCH_TIMER_VIRT_PPI] =
>> map_generic_timer_interrupt(gtdt->virtual_timer_interrupt,
>> gtdt->virtual_timer_flags);
>>
>> - arch_timer_ppi[HYP_PPI] =
>> + arch_timer_ppi[ARCH_TIMER_HYP_PPI] =
>> map_generic_timer_interrupt(gtdt->non_secure_el2_interrupt,
>> gtdt->non_secure_el2_flags);
>>
>> diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h
>> index d23c381..2625ff1 100644
>> --- a/include/clocksource/arm_arch_timer.h
>> +++ b/include/clocksource/arm_arch_timer.h
>> @@ -20,18 +20,18 @@
>> #include <linux/timecounter.h>
>> #include <linux/types.h>
>>
>> -#define ARCH_CP15_TIMER BIT(0)
>> -#define ARCH_MEM_TIMER BIT(1)
>> +#define ARCH_TIMER_TYPE_CP15 BIT(0)
>> +#define ARCH_TIMER_TYPE_MEM BIT(1)
>>
>> -#define ARCH_TIMER_CTRL_ENABLE (1 << 0)
>> -#define ARCH_TIMER_CTRL_IT_MASK (1 << 1)
>> -#define ARCH_TIMER_CTRL_IT_STAT (1 << 2)
>> +#define ARCH_TIMER_CTRL_ENABLE BIT(0)
>> +#define ARCH_TIMER_CTRL_IT_MASK BIT(1)
>> +#define ARCH_TIMER_CTRL_IT_STAT BIT(2)
>>
>> -#define CNTHCTL_EL1PCTEN (1 << 0)
>> -#define CNTHCTL_EL1PCEN (1 << 1)
>> -#define CNTHCTL_EVNTEN (1 << 2)
>> -#define CNTHCTL_EVNTDIR (1 << 3)
>> -#define CNTHCTL_EVNTI (0xF << 4)
>> +#define ARCH_TIMER_CNTHCTL_EL1PCTEN BIT(0)
>> +#define ARCH_TIMER_CNTHCTL_EL1PCEN BIT(1)
>> +#define ARCH_TIMER_CNTHCTL_EVNTEN BIT(2)
>> +#define ARCH_TIMER_CNTHCTL_EVNTDIR BIT(3)
>> +#define ARCH_TIMER_CNTHCTL_EVNTI (0xF << 4)
>>
>> enum arch_timer_reg {
>> ARCH_TIMER_REG_CTRL,
>> @@ -39,11 +39,11 @@ enum arch_timer_reg {
>> };
>>
>> enum arch_timer_ppi_nr {
>> - PHYS_SECURE_PPI,
>> - PHYS_NONSECURE_PPI,
>> - VIRT_PPI,
>> - HYP_PPI,
>> - MAX_TIMER_PPI
>> + ARCH_TIMER_PHYS_SECURE_PPI,
>> + ARCH_TIMER_PHYS_NONSECURE_PPI,
>> + ARCH_TIMER_VIRT_PPI,
>> + ARCH_TIMER_HYP_PPI,
>> + ARCH_TIMER_MAX_TIMER_PPI
>> };
>>
>> enum arch_timer_spi_nr {
>> @@ -57,13 +57,13 @@ enum arch_timer_spi_nr {
>> #define ARCH_TIMER_MEM_PHYS_ACCESS 2
>> #define ARCH_TIMER_MEM_VIRT_ACCESS 3
>>
>> -#define ARCH_TIMER_USR_PCT_ACCESS_EN (1 << 0) /* physical counter */
>> -#define ARCH_TIMER_USR_VCT_ACCESS_EN (1 << 1) /* virtual counter */
>> -#define ARCH_TIMER_VIRT_EVT_EN (1 << 2)
>> +#define ARCH_TIMER_USR_PCT_ACCESS_EN BIT(0) /* physical counter */
>> +#define ARCH_TIMER_USR_VCT_ACCESS_EN BIT(1) /* virtual counter */
>> +#define ARCH_TIMER_VIRT_EVT_EN BIT(2)
>> #define ARCH_TIMER_EVT_TRIGGER_SHIFT (4)
>> #define ARCH_TIMER_EVT_TRIGGER_MASK (0xF << ARCH_TIMER_EVT_TRIGGER_SHIFT)
>> -#define ARCH_TIMER_USR_VT_ACCESS_EN (1 << 8) /* virtual timer registers */
>> -#define ARCH_TIMER_USR_PT_ACCESS_EN (1 << 9) /* physical timer registers */
>> +#define ARCH_TIMER_USR_VT_ACCESS_EN BIT(8) /* virtual timer registers */
>> +#define ARCH_TIMER_USR_PT_ACCESS_EN BIT(9) /* physical timer registers */
>>
>> #define ARCH_TIMER_EVT_STREAM_FREQ 10000 /* 100us */
>>
>> diff --git a/virt/kvm/arm/hyp/timer-sr.c b/virt/kvm/arm/hyp/timer-sr.c
>> index 798866a..695b9d9 100644
>> --- a/virt/kvm/arm/hyp/timer-sr.c
>> +++ b/virt/kvm/arm/hyp/timer-sr.c
>> @@ -37,7 +37,7 @@ void __hyp_text __timer_save_state(struct kvm_vcpu *vcpu)
>>
>> /* Allow physical timer/counter access for the host */
>> val = read_sysreg(cnthctl_el2);
>> - val |= CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN;
>> + val |= ARCH_TIMER_CNTHCTL_EL1PCTEN | ARCH_TIMER_CNTHCTL_EL1PCEN;
>> write_sysreg(val, cnthctl_el2);
>>
>> /* Clear cntvoff for the host */
>> @@ -55,8 +55,8 @@ void __hyp_text __timer_restore_state(struct kvm_vcpu *vcpu)
>> * Physical counter access is allowed
>> */
>> val = read_sysreg(cnthctl_el2);
>> - val &= ~CNTHCTL_EL1PCEN;
>> - val |= CNTHCTL_EL1PCTEN;
>> + val &= ~ARCH_TIMER_CNTHCTL_EL1PCEN;
>> + val |= ARCH_TIMER_CNTHCTL_EL1PCTEN;
>> write_sysreg(val, cnthctl_el2);
>>
>> if (timer->enabled) {
>> --
>> 2.7.4
>>
--
Best regards,
Fu Wei
Software Engineer
Red Hat
^ permalink raw reply
* [PATCH v2] ARM: Drop fixed 200 Hz timer requirement from Samsung platforms
From: Tomasz Figa @ 2016-11-21 6:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <22757093.ejshJp9T7L@wuerfel>
2016-11-18 17:46 GMT+09:00 Arnd Bergmann <arnd@arndb.de>:
> Maybe add a paragraph about the specific problem:
>
> "On s3c24xx, the PWM counter is only 16 bit wide, and with the
> typical 12MHz input clock that overflows every 5.5ms. This works
> with HZ=200 or higher but not with HZ=100 which needs a 10ms
> interval between ticks. On Later chips (S3C64xx, S5P and EXYNOS),
> the counter is 32 bits and does not have this problem.
> The new samsung_pwm_timer driver solves the problem by scaling
> the input clock by a factor of 50 on s3c24xx, which makes it
> less accurate but allows HZ=100 as well as CONFIG_NO_HZ with
> fewer wakeups".
One thing to correct here is that the typical clock is PCLK, which is
derived from one of the PLLs and AFAIR is between 33-66 MHz on
s3c24xx. Technically you can drive the PWM block from an external
clock (12 MHz for some board-file based boards), but for simplicity
this functionality was omitted in the new PWM timer driver used for DT
boards (which worked fine with the PWM driven by PCLK).
Also I'm wondering if the divisor we use right now for 16-bit timers
isn't too small, since it gives us a really short wraparound time,
which means getting more timer interrupts for longer intervals, kind
of defeating the benefit of tickless mode. However, AFAICT it doesn't
affect the HZ problem.
Best regards.
Tomasz
^ permalink raw reply
* [PATCH] ARM: dts: AM571x-IDK Initial Support
From: Lokesh Vutla @ 2016-11-21 5:58 UTC (permalink / raw)
To: linux-arm-kernel
From: Schuyler Patton <spatton@ti.com>
The AM571x-IDK board is a board based on TI's AM5718 SOC
which has a single core 1.5GHz A15 processor. This board is a
development platform for the Industrial market with:
- 1GB of DDR3L
- Dual 1Gbps Ethernet
- HDMI,
- PRU-ICSS
- uSD
- 16GB eMMC
- CAN
- RS-485
- PCIe
- USB3.0
- Video Input Port
- Industrial IO port and expansion connector
The link to the data sheet and TRM can be found here:
http://www.ti.com/product/AM5718
Initial support is only for basic peripherals.
Signed-off-by: Schuyler Patton <spatton@ti.com>
Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
---
Logs: http://pastebin.ubuntu.com/23510390/
.../devicetree/bindings/arm/omap/omap.txt | 3 +
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/am571x-idk.dts | 82 ++++++++++++++++++++++
3 files changed, 86 insertions(+)
create mode 100644 arch/arm/boot/dts/am571x-idk.dts
diff --git a/Documentation/devicetree/bindings/arm/omap/omap.txt b/Documentation/devicetree/bindings/arm/omap/omap.txt
index f53e2ee..647ffd3 100644
--- a/Documentation/devicetree/bindings/arm/omap/omap.txt
+++ b/Documentation/devicetree/bindings/arm/omap/omap.txt
@@ -175,6 +175,9 @@ Boards:
- AM5728 IDK
compatible = "ti,am5728-idk", "ti,am5728", "ti,dra742", "ti,dra74", "ti,dra7"
+- AM5718 IDK
+ compatible = "ti,am5718-idk", "ti,am5728", "ti,dra722", "ti,dra72", "ti,dra7"
+
- DRA742 EVM: Software Development Board for DRA742
compatible = "ti,dra7-evm", "ti,dra742", "ti,dra74", "ti,dra7"
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index befcd26..c298078 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -588,6 +588,7 @@ dtb-$(CONFIG_SOC_DRA7XX) += \
am57xx-cl-som-am57x.dtb \
am57xx-sbc-am57x.dtb \
am572x-idk.dtb \
+ am571x-idk.dtb \
dra7-evm.dtb \
dra72-evm.dtb \
dra72-evm-revc.dtb
diff --git a/arch/arm/boot/dts/am571x-idk.dts b/arch/arm/boot/dts/am571x-idk.dts
new file mode 100644
index 0000000..a6a743e
--- /dev/null
+++ b/arch/arm/boot/dts/am571x-idk.dts
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+#include "dra72x.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "am57xx-idk-common.dtsi"
+
+/ {
+ model = "TI AM5718 IDK";
+ compatible = "ti,am5718-idk", "ti,am5718", "ti,dra722",
+ "ti,dra72", "ti,dra7";
+
+ memory at 0 {
+ device_type = "memory";
+ reg = <0x0 0x80000000 0x0 0x40000000>;
+ };
+
+ status-leds {
+ compatible = "gpio-leds";
+ cpu0-led {
+ label = "status0:red:cpu0";
+ gpios = <&gpio2 25 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ linux,default-trigger = "cpu0";
+ };
+
+ usr0-led {
+ label = "status0:green:usr";
+ gpios = <&gpio2 26 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ heartbeat-led {
+ label = "status0:blue:heartbeat";
+ gpios = <&gpio2 27 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ linux,default-trigger = "heartbeat";
+ };
+
+ usr1-led {
+ label = "status1:red:usr";
+ gpios = <&gpio2 28 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ usr2-led {
+ label = "status1:green:usr";
+ gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ mmc0-led {
+ label = "status1:blue:mmc0";
+ gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ linux,default-trigger = "mmc0";
+ };
+ };
+
+ extcon_usb2: extcon_usb2 {
+ compatible = "linux,extcon-usb-gpio";
+ id-gpio = <&gpio5 7 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&mmc1 {
+ status = "okay";
+ vmmc-supply = <&ldo1_reg>;
+ bus-width = <4>;
+ cd-gpios = <&gpio6 27 0>; /* gpio 219 */
+};
+
+&omap_dwc3_2 {
+ extcon = <&extcon_usb2>;
+};
--
2.10.1
^ permalink raw reply related
* [PATCH v2 4/4] spi: spi-fsl-dspi: Minor code cleanup and error path fixes
From: Sanchayan Maity @ 2016-11-21 5:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1479706671.git.maitysanchayan@gmail.com>
Code cleanup for improving code readability and error path fixes
and cleanup removing use of devm_kfree.
Signed-off-by: Sanchayan Maity <maitysanchayan@gmail.com>
---
drivers/spi/spi-fsl-dspi.c | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 08882f7..2987a16 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -226,8 +226,10 @@ static void dspi_rx_dma_callback(void *arg)
if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) {
for (i = 0; i < dma->curr_xfer_len; i++) {
d = dspi->dma->rx_dma_buf[i];
- rx_word ? (*(u16 *)dspi->rx = d) :
- (*(u8 *)dspi->rx = d);
+ if (rx_word)
+ *(u16 *)dspi->rx = d;
+ else
+ *(u8 *)dspi->rx = d;
dspi->rx += rx_word + 1;
}
}
@@ -247,14 +249,20 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
tx_word = is_double_byte_mode(dspi);
for (i = 0; i < dma->curr_xfer_len - 1; i++) {
- val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
+ if (tx_word)
+ val = *(u16 *) dspi->tx;
+ else
+ val = *(u8 *) dspi->tx;
dspi->dma->tx_dma_buf[i] =
SPI_PUSHR_TXDATA(val) | SPI_PUSHR_PCS(dspi->cs) |
SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
dspi->tx += tx_word + 1;
}
- val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
+ if (tx_word)
+ val = *(u16 *) dspi->tx;
+ else
+ val = *(u8 *) dspi->tx;
dspi->dma->tx_dma_buf[i] = SPI_PUSHR_TXDATA(val) |
SPI_PUSHR_PCS(dspi->cs) |
SPI_PUSHR_CTAS(0);
@@ -430,9 +438,11 @@ static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr)
return 0;
err_slave_config:
- devm_kfree(dev, dma->rx_dma_buf);
+ dma_free_coherent(dev, DSPI_DMA_BUFSIZE,
+ dma->rx_dma_buf, dma->rx_dma_phys);
err_rx_dma_buf:
- devm_kfree(dev, dma->tx_dma_buf);
+ dma_free_coherent(dev, DSPI_DMA_BUFSIZE,
+ dma->tx_dma_buf, dma->tx_dma_phys);
err_tx_dma_buf:
dma_release_channel(dma->chan_tx);
err_tx_channel:
--
2.10.2
^ permalink raw reply related
* [PATCH v2 3/4] spi: spi-fsl-dspi: Fix incorrect DMA setup
From: Sanchayan Maity @ 2016-11-21 5:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1479706671.git.maitysanchayan@gmail.com>
Currently dmaengine_prep_slave_single was being called with length
set to the complete DMA buffer size. This resulted in unwanted bytes
being transferred to the SPI register leading to clock and MOSI lines
having unwanted data even after chip select got deasserted and the
required bytes having been transferred.
While at it also clean up the use of curr_xfer_len which is central
to the DMA setup, from bytes to DMA transfers for every use.
Signed-off-by: Sanchayan Maity <maitysanchayan@gmail.com>
---
drivers/spi/spi-fsl-dspi.c | 35 ++++++++++++++++++-----------------
1 file changed, 18 insertions(+), 17 deletions(-)
diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 41422cd..08882f7 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -151,6 +151,7 @@ static const struct fsl_dspi_devtype_data ls2085a_data = {
};
struct fsl_dspi_dma {
+ /* Length of transfer in words of DSPI_FIFO_SIZE */
u32 curr_xfer_len;
u32 *tx_dma_buf;
@@ -217,15 +218,13 @@ static void dspi_rx_dma_callback(void *arg)
struct fsl_dspi *dspi = arg;
struct fsl_dspi_dma *dma = dspi->dma;
int rx_word;
- int i, len;
+ int i;
u16 d;
rx_word = is_double_byte_mode(dspi);
- len = rx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
-
if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) {
- for (i = 0; i < len; i++) {
+ for (i = 0; i < dma->curr_xfer_len; i++) {
d = dspi->dma->rx_dma_buf[i];
rx_word ? (*(u16 *)dspi->rx = d) :
(*(u8 *)dspi->rx = d);
@@ -242,14 +241,12 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
struct device *dev = &dspi->pdev->dev;
int time_left;
int tx_word;
- int i, len;
+ int i;
u16 val;
tx_word = is_double_byte_mode(dspi);
- len = tx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len;
-
- for (i = 0; i < len - 1; i++) {
+ for (i = 0; i < dma->curr_xfer_len - 1; i++) {
val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
dspi->dma->tx_dma_buf[i] =
SPI_PUSHR_TXDATA(val) | SPI_PUSHR_PCS(dspi->cs) |
@@ -267,7 +264,9 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx,
dma->tx_dma_phys,
- DSPI_DMA_BUFSIZE, DMA_MEM_TO_DEV,
+ dma->curr_xfer_len *
+ DMA_SLAVE_BUSWIDTH_4_BYTES,
+ DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!dma->tx_desc) {
dev_err(dev, "Not able to get desc for DMA xfer\n");
@@ -283,7 +282,9 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
dma->rx_desc = dmaengine_prep_slave_single(dma->chan_rx,
dma->rx_dma_phys,
- DSPI_DMA_BUFSIZE, DMA_DEV_TO_MEM,
+ dma->curr_xfer_len *
+ DMA_SLAVE_BUSWIDTH_4_BYTES,
+ DMA_DEV_TO_MEM,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!dma->rx_desc) {
dev_err(dev, "Not able to get desc for DMA xfer\n");
@@ -330,17 +331,17 @@ static int dspi_dma_xfer(struct fsl_dspi *dspi)
struct device *dev = &dspi->pdev->dev;
int curr_remaining_bytes;
int bytes_per_buffer;
- int tx_word;
+ int word = 1;
int ret = 0;
- tx_word = is_double_byte_mode(dspi);
+ if (is_double_byte_mode(dspi))
+ word = 2;
curr_remaining_bytes = dspi->len;
+ bytes_per_buffer = DSPI_DMA_BUFSIZE / DSPI_FIFO_SIZE;
while (curr_remaining_bytes) {
/* Check if current transfer fits the DMA buffer */
- dma->curr_xfer_len = curr_remaining_bytes;
- bytes_per_buffer = DSPI_DMA_BUFSIZE /
- (DSPI_FIFO_SIZE / (tx_word ? 2 : 1));
- if (curr_remaining_bytes > bytes_per_buffer)
+ dma->curr_xfer_len = curr_remaining_bytes / word;
+ if (dma->curr_xfer_len > bytes_per_buffer)
dma->curr_xfer_len = bytes_per_buffer;
ret = dspi_next_xfer_dma_submit(dspi);
@@ -349,7 +350,7 @@ static int dspi_dma_xfer(struct fsl_dspi *dspi)
goto exit;
} else {
- curr_remaining_bytes -= dma->curr_xfer_len;
+ curr_remaining_bytes -= dma->curr_xfer_len * word;
if (curr_remaining_bytes < 0)
curr_remaining_bytes = 0;
dspi->len = curr_remaining_bytes;
--
2.10.2
^ permalink raw reply related
* [PATCH v2 2/4] spi: spi-fsl-dspi: Fix continuous selection format
From: Sanchayan Maity @ 2016-11-21 5:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1479706671.git.maitysanchayan@gmail.com>
Current DMA implementation was not handling the continuous selection
format viz. SPI chip select would be deasserted even between sequential
serial transfers. Use the cs_change variable and correctly set or
reset the CONT bit accordingly for case where peripherals require
the chip select to be asserted between sequential transfers.
Signed-off-by: Sanchayan Maity <maitysanchayan@gmail.com>
---
drivers/spi/spi-fsl-dspi.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index b1ee1f5..41422cd 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -261,6 +261,8 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
dspi->dma->tx_dma_buf[i] = SPI_PUSHR_TXDATA(val) |
SPI_PUSHR_PCS(dspi->cs) |
SPI_PUSHR_CTAS(0);
+ if (!dspi->cs_change)
+ dspi->dma->tx_dma_buf[i] |= SPI_PUSHR_CONT;
dspi->tx += tx_word + 1;
dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx,
--
2.10.2
^ permalink raw reply related
* [PATCH v2 1/4] spi: spi-fsl-dspi: Fix SPI transfer issue when using multiple SPI_IOC_MESSAGE
From: Sanchayan Maity @ 2016-11-21 5:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1479706671.git.maitysanchayan@gmail.com>
Current DMA implementation had a bug where the DMA transfer would
exit the loop in dspi_transfer_one_message after the completion of
a single transfer. This results in a multi message transfer submitted
with SPI_IOC_MESSAGE to terminate incorrectly without an error.
Signed-off-by: Sanchayan Maity <maitysanchayan@gmail.com>
Reviewed-by: Stefan Agner <stefan@agner.ch>
---
drivers/spi/spi-fsl-dspi.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index bc64700..b1ee1f5 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -714,7 +714,7 @@ static int dspi_transfer_one_message(struct spi_master *master,
SPI_RSER_TFFFE | SPI_RSER_TFFFD |
SPI_RSER_RFDFE | SPI_RSER_RFDFD);
status = dspi_dma_xfer(dspi);
- goto out;
+ break;
default:
dev_err(&dspi->pdev->dev, "unsupported trans_mode %u\n",
trans_mode);
@@ -722,9 +722,13 @@ static int dspi_transfer_one_message(struct spi_master *master,
goto out;
}
- if (wait_event_interruptible(dspi->waitq, dspi->waitflags))
- dev_err(&dspi->pdev->dev, "wait transfer complete fail!\n");
- dspi->waitflags = 0;
+ if (trans_mode != DSPI_DMA_MODE) {
+ if (wait_event_interruptible(dspi->waitq,
+ dspi->waitflags))
+ dev_err(&dspi->pdev->dev,
+ "wait transfer complete fail!\n");
+ dspi->waitflags = 0;
+ }
if (transfer->delay_usecs)
udelay(transfer->delay_usecs);
--
2.10.2
^ permalink raw reply related
* [PATCH v2 0/4] Fixes for Vybrid SPI DMA implementation
From: Sanchayan Maity @ 2016-11-21 5:54 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
The following set of patches have fixes for Vybrid SPI DMA
implementation along with some minor clean ups requested
at time when v3 version of SPI DMA support patch was accepted.
This series of patches is based on top of branch topic/fsl-dspi.
http://git.kernel.org/cgit/linux/kernel/git/broonie/spi.git/log/?h=topic/fsl-dspi
The patches have been tested on a Toradex Colibri Vybrid VF61 module
and now incoporate feedback from Stefan on version 1 of patchset.
Changes since v1:
1. Place the continuous selection format patch second in order and remove
code duplication
2. Improve the use of curr_xfer_len and instead of converting from bytes
to DMA transfers in every use, do it at a single place. Accordingly change
it's use at other places
3. Code cleanup patch has less to clean with change above
v1:
http://www.mail-archive.com/linux-kernel at vger.kernel.org/msg1274632.html
Thanks & Regards,
Sanchayan.
Sanchayan Maity (4):
spi: spi-fsl-dspi: Fix SPI transfer issue when using multiple SPI_IOC_MESSAGE
spi: spi-fsl-dspi: Fix continuous selection format
spi: spi-fsl-dspi: Fix incorrect DMA setup
spi: spi-fsl-dspi: Minor code cleanup and error path fixes
drivers/spi/spi-fsl-dspi.c | 71 ++++++++++++++++++++++++++++------------------
1 file changed, 44 insertions(+), 27 deletions(-)
--
2.10.2
^ permalink raw reply
* [PATCH v3] ARM: at91/dt: add dts file for sama5d36ek CMP board
From: Wenyou Yang @ 2016-11-21 5:14 UTC (permalink / raw)
To: linux-arm-kernel
The sama5d36ek CMP board is the variant of sama5d3xek board.
It is equipped with the low-power DDR2 SDRAM, PMIC ACT8865 and
some power rail. Its main purpose is used to measure the power
consumption.
The difference of the sama5d36ek CMP dts from sama5d36ek dts is
listed as below.
1. The USB host nodes are removed, that is, the USB host is disabled.
2. The gpio_keys node is added to wake up from the sleep.
3. The LCD isn't supported due to the pins for LCD are conflicted
with gpio_keys.
4. The adc0 node support the pinctrl sleep state to fix the over
consumption on VDDANA.
As said in errata, "When the USB host ports are used in high speed
mode (EHCI), it is not possible to suspend the ports if no device is
attached on each port. This leads to increased power consumption even
if the system is in a low power mode." That is why the the USB host
is disabled.
Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
---
Changes in v3:
- Use a dual license scheme for DT files.
- Use the proper model name and the compatible string to reflect
the nature of this new "CMP" board.
- Change name of wakeup property to "wakeup-source".
- Remove unnecessary comments.
- Remove bootargs.
Changes in v2:
- Add the pinctrl sleep state for adc0 node to fix the over
consumption on VDDANA.
- Improve the commit log.
arch/arm/boot/dts/sama5d36ek_cmp.dts | 87 ++++++++++
arch/arm/boot/dts/sama5d3xcm_cmp.dtsi | 201 +++++++++++++++++++++++
arch/arm/boot/dts/sama5d3xmb_cmp.dtsi | 301 ++++++++++++++++++++++++++++++++++
3 files changed, 589 insertions(+)
create mode 100644 arch/arm/boot/dts/sama5d36ek_cmp.dts
create mode 100644 arch/arm/boot/dts/sama5d3xcm_cmp.dtsi
create mode 100644 arch/arm/boot/dts/sama5d3xmb_cmp.dtsi
diff --git a/arch/arm/boot/dts/sama5d36ek_cmp.dts b/arch/arm/boot/dts/sama5d36ek_cmp.dts
new file mode 100644
index 0000000..b632143
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d36ek_cmp.dts
@@ -0,0 +1,87 @@
+/*
+ * sama5d36ek_cmp.dts - Device Tree file for SAMA5D36-EK CMP board
+ *
+ * Copyright (C) 2016 Atmel,
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+/dts-v1/;
+#include "sama5d36.dtsi"
+#include "sama5d3xmb_cmp.dtsi"
+
+/ {
+ model = "Atmel SAMA5D36EK-CMP";
+ compatible = "atmel,sama5d36ek-cmp", "atmel,sama5d3xmb-cmp", "atmel,sama5d3xcm-cmp", "atmel,sama5d36", "atmel,sama5d3", "atmel,sama5";
+
+ ahb {
+ apb {
+ spi0: spi at f0004000 {
+ status = "okay";
+ };
+
+ ssc0: ssc at f0008000 {
+ status = "okay";
+ };
+
+ can0: can at f000c000 {
+ status = "okay";
+ };
+
+ i2c0: i2c at f0014000 {
+ status = "okay";
+ };
+
+ i2c1: i2c at f0018000 {
+ status = "okay";
+ };
+
+ macb0: ethernet at f0028000 {
+ status = "okay";
+ };
+
+ macb1: ethernet at f802c000 {
+ status = "okay";
+ };
+ };
+ };
+
+ sound {
+ status = "okay";
+ };
+};
diff --git a/arch/arm/boot/dts/sama5d3xcm_cmp.dtsi b/arch/arm/boot/dts/sama5d3xcm_cmp.dtsi
new file mode 100644
index 0000000..dc7572b
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d3xcm_cmp.dtsi
@@ -0,0 +1,201 @@
+/*
+ * sama5d3xcm_cmp.dtsi - Device Tree Include file for SAMA5D36 CMP CPU Module
+ *
+ * Copyright (C) 2016 Atmel,
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/ {
+ compatible = "atmel,sama5d3xcm-cmp", "atmel,sama5d3", "atmel,sama5";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ reg = <0x20000000 0x20000000>;
+ };
+
+ clocks {
+ slow_xtal {
+ clock-frequency = <32768>;
+ };
+
+ main_xtal {
+ clock-frequency = <12000000>;
+ };
+ };
+
+ ahb {
+ apb {
+ spi0: spi at f0004000 {
+ cs-gpios = <&pioD 13 0>, <0>, <0>, <0>;
+ };
+
+ macb0: ethernet at f0028000 {
+ phy-mode = "rgmii";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethernet-phy at 1 {
+ reg = <0x1>;
+ interrupt-parent = <&pioB>;
+ interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
+ txen-skew-ps = <800>;
+ txc-skew-ps = <3000>;
+ rxdv-skew-ps = <400>;
+ rxc-skew-ps = <3000>;
+ rxd0-skew-ps = <400>;
+ rxd1-skew-ps = <400>;
+ rxd2-skew-ps = <400>;
+ rxd3-skew-ps = <400>;
+ };
+
+ ethernet-phy at 7 {
+ reg = <0x7>;
+ interrupt-parent = <&pioB>;
+ interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
+ txen-skew-ps = <800>;
+ txc-skew-ps = <3000>;
+ rxdv-skew-ps = <400>;
+ rxc-skew-ps = <3000>;
+ rxd0-skew-ps = <400>;
+ rxd1-skew-ps = <400>;
+ rxd2-skew-ps = <400>;
+ rxd3-skew-ps = <400>;
+ };
+ };
+
+ i2c1: i2c at f0018000 {
+ pmic: act8865 at 5b {
+ compatible = "active-semi,act8865";
+ reg = <0x5b>;
+ status = "disabled";
+
+ regulators {
+ vcc_1v8_reg: DCDC_REG1 {
+ regulator-name = "VCC_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ vcc_1v2_reg: DCDC_REG2 {
+ regulator-name = "VCC_1V2";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ };
+
+ vcc_3v3_reg: DCDC_REG3 {
+ regulator-name = "VCC_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vddana_reg: LDO_REG1 {
+ regulator-name = "VDDANA";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vddfuse_reg: LDO_REG2 {
+ regulator-name = "FUSE_2V5";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ };
+ };
+ };
+ };
+ };
+
+ nand0: nand at 60000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "hw";
+ atmel,has-pmecc;
+ atmel,pmecc-cap = <4>;
+ atmel,pmecc-sector-size = <512>;
+ nand-on-flash-bbt;
+ status = "okay";
+
+ at91bootstrap at 0 {
+ label = "at91bootstrap";
+ reg = <0x0 0x40000>;
+ };
+
+ bootloader at 40000 {
+ label = "bootloader";
+ reg = <0x40000 0x80000>;
+ };
+
+ bootloaderenv at c0000 {
+ label = "bootloader env";
+ reg = <0xc0000 0xc0000>;
+ };
+
+ dtb at 180000 {
+ label = "device tree";
+ reg = <0x180000 0x80000>;
+ };
+
+ kernel at 200000 {
+ label = "kernel";
+ reg = <0x200000 0x600000>;
+ };
+
+ rootfs at 800000 {
+ label = "rootfs";
+ reg = <0x800000 0x0f800000>;
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ d2 {
+ label = "d2";
+ gpios = <&pioE 25 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/sama5d3xmb_cmp.dtsi b/arch/arm/boot/dts/sama5d3xmb_cmp.dtsi
new file mode 100644
index 0000000..252e0d3
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d3xmb_cmp.dtsi
@@ -0,0 +1,301 @@
+/*
+ * sama5d3xmb_cmp.dts - Device Tree file for SAMA5D3x CMP mother board
+ *
+ * Copyright (C) 2016 Atmel,
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "sama5d3xcm_cmp.dtsi"
+
+/ {
+ compatible = "atmel,sama5d3xmb-cmp", "atmel,sama5d3xcm-cmp", "atmel,sama5d3", "atmel,sama5";
+
+ ahb {
+ apb {
+ mmc0: mmc at f0000000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mmc0_clk_cmd_dat0 &pinctrl_mmc0_dat1_3 &pinctrl_mmc0_cd>;
+ status = "okay";
+ slot at 0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioD 17 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ spi0: spi at f0004000 {
+ dmas = <0>, <0>; /* Do not use DMA for spi0 */
+
+ m25p80 at 0 {
+ compatible = "atmel,at25df321a";
+ spi-max-frequency = <50000000>;
+ reg = <0>;
+ };
+ };
+
+ ssc0: ssc at f0008000 {
+ atmel,clk-from-rk-pin;
+ };
+
+ /*
+ * i2c0 conflicts with ISI:
+ * disable it to allow the use of ISI
+ * can not enable audio when i2c0 disabled
+ */
+ i2c0: i2c at f0014000 {
+ wm8904: wm8904 at 1a {
+ compatible = "wlf,wm8904";
+ reg = <0x1a>;
+ clocks = <&pck0>;
+ clock-names = "mclk";
+ };
+ };
+
+ i2c1: i2c at f0018000 {
+ ov2640: camera at 0x30 {
+ compatible = "ovti,ov2640";
+ reg = <0x30>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pck1_as_isi_mck &pinctrl_sensor_power &pinctrl_sensor_reset>;
+ resetb-gpios = <&pioE 24 GPIO_ACTIVE_LOW>;
+ pwdn-gpios = <&pioE 29 GPIO_ACTIVE_HIGH>;
+ /* use pck1 for the master clock of ov2640 */
+ clocks = <&pck1>;
+ clock-names = "xvclk";
+ assigned-clocks = <&pck1>;
+ assigned-clock-rates = <25000000>;
+
+ port {
+ ov2640_0: endpoint {
+ remote-endpoint = <&isi_0>;
+ bus-width = <8>;
+ };
+ };
+ };
+ };
+
+ usart1: serial at f0020000 {
+ dmas = <0>, <0>; /* Do not use DMA for usart1 */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart1 &pinctrl_usart1_rts_cts>;
+ status = "okay";
+ };
+
+ isi: isi at f0034000 {
+ port {
+ isi_0: endpoint {
+ remote-endpoint = <&ov2640_0>;
+ bus-width = <8>;
+ vsync-active = <1>;
+ hsync-active = <1>;
+ };
+ };
+ };
+
+ mmc1: mmc at f8000000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3 &pinctrl_mmc1_cd>;
+ status = "okay";
+ slot at 0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioD 18 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ adc0: adc at f8018000 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <
+ &pinctrl_adc0_adtrg
+ &pinctrl_adc0_ad0
+ &pinctrl_adc0_ad1
+ &pinctrl_adc0_ad2
+ &pinctrl_adc0_ad3
+ &pinctrl_adc0_ad4
+ >;
+ pinctrl-1 = <
+ &pinctrl_adc0_adtrg_sleep
+ &pinctrl_adc0_ad0_sleep
+ &pinctrl_adc0_ad1_sleep
+ &pinctrl_adc0_ad2_sleep
+ &pinctrl_adc0_ad3_sleep
+ &pinctrl_adc0_ad4_sleep
+ >;
+ status = "okay";
+ };
+
+ macb1: ethernet at f802c000 {
+ phy-mode = "rmii";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ phy0: ethernet-phy at 1 {
+ /*interrupt-parent = <&pioE>;*/
+ /*interrupts = <30 IRQ_TYPE_EDGE_FALLING>;*/
+ reg = <1>;
+ };
+ };
+
+ pinctrl at fffff200 {
+ adc0 {
+ pinctrl_adc0_adtrg_sleep: adc0_adtrg_1 {
+ atmel,pins =
+ <AT91_PIOD 19 AT91_PERIPH_GPIO (AT91_PINCTRL_OUTPUT | AT91_PINCTRL_OUTPUT_VAL(0))>;
+ };
+ pinctrl_adc0_ad0_sleep: adc0_ad0_1 {
+ atmel,pins =
+ <AT91_PIOD 20 AT91_PERIPH_GPIO (AT91_PINCTRL_OUTPUT | AT91_PINCTRL_OUTPUT_VAL(0))>;
+ };
+ pinctrl_adc0_ad1_sleep: adc0_ad1_1 {
+ atmel,pins =
+ <AT91_PIOD 21 AT91_PERIPH_GPIO (AT91_PINCTRL_OUTPUT | AT91_PINCTRL_OUTPUT_VAL(0))>;
+ };
+ pinctrl_adc0_ad2_sleep: adc0_ad2_1 {
+ atmel,pins =
+ <AT91_PIOD 22 AT91_PERIPH_GPIO (AT91_PINCTRL_OUTPUT | AT91_PINCTRL_OUTPUT_VAL(0))>;
+ };
+ pinctrl_adc0_ad3_sleep: adc0_ad3_1 {
+ atmel,pins =
+ <AT91_PIOD 23 AT91_PERIPH_GPIO (AT91_PINCTRL_OUTPUT | AT91_PINCTRL_OUTPUT_VAL(0))>;
+ };
+ pinctrl_adc0_ad4_sleep: adc0_ad4_1 {
+ atmel,pins =
+ <AT91_PIOD 24 AT91_PERIPH_GPIO (AT91_PINCTRL_OUTPUT | AT91_PINCTRL_OUTPUT_VAL(0))>;
+ };
+ };
+
+ board {
+ pinctrl_gpio_keys: gpio_keys {
+ atmel,pins =
+ <AT91_PIOE 27 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>;
+ };
+
+ pinctrl_mmc0_cd: mmc0_cd {
+ atmel,pins =
+ <AT91_PIOD 17 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
+ };
+
+ pinctrl_mmc1_cd: mmc1_cd {
+ atmel,pins =
+ <AT91_PIOD 18 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
+ };
+
+ pinctrl_pck0_as_audio_mck: pck0_as_audio_mck {
+ atmel,pins =
+ <AT91_PIOD 30 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_pck1_as_isi_mck: pck1_as_isi_mck-0 {
+ atmel,pins =
+ <AT91_PIOD 31 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_sensor_reset: sensor_reset-0 {
+ atmel,pins =
+ <AT91_PIOE 24 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_sensor_power: sensor_power-0 {
+ atmel,pins =
+ <AT91_PIOE 29 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+ };
+
+ pinctrl_usba_vbus: usba_vbus {
+ atmel,pins =
+ <AT91_PIOD 29 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>;
+ };
+ };
+ };
+
+ dbgu: serial at ffffee00 {
+ dmas = <0>, <0>; /* Do not use DMA for dbgu */
+ status = "okay";
+ };
+
+ watchdog at fffffe40 {
+ status = "okay";
+ };
+ };
+
+ usb0: gadget at 00500000 {
+ atmel,vbus-gpio = <&pioD 29 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usba_vbus>;
+ status = "okay";
+ };
+ };
+
+ sound {
+ compatible = "atmel,asoc-wm8904";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pck0_as_audio_mck>;
+
+ atmel,model = "wm8904 @ SAMA5D3EK";
+ atmel,audio-routing =
+ "Headphone Jack", "HPOUTL",
+ "Headphone Jack", "HPOUTR",
+ "IN2L", "Line In Jack",
+ "IN2R", "Line In Jack",
+ "Mic", "MICBIAS",
+ "IN1L", "Mic";
+
+ atmel,ssc-controller = <&ssc0>;
+ atmel,audio-codec = <&wm8904>;
+
+ status = "disabled";
+ };
+
+ /* Conflict with LCD pins */
+ gpio_keys {
+ compatible = "gpio-keys";
+ status = "okay";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_keys>;
+
+ pb_user1 {
+ label = "pb_user1";
+ gpios = <&pioE 27 GPIO_ACTIVE_HIGH>;
+ linux,code = <0x100>;
+ wakeup-source;
+ };
+ };
+};
--
2.7.4
^ permalink raw reply related
* Summary of LPC guest MSI discussion in Santa Fe
From: Jon Masters @ 2016-11-21 5:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161108024559.GA20591@arm.com>
On 11/07/2016 07:45 PM, Will Deacon wrote:
> I figured this was a reasonable post to piggy-back on for the LPC minutes
> relating to guest MSIs on arm64.
Thanks for this Will. I'm still digging out post-LPC and SC16, but the
summary was much appreciated, and I'm glad the conversation is helping.
> 1. The physical memory map is not standardised (Jon pointed out that
> this is something that was realised late on)
Just to note, we discussed this one about 3-4 years ago. I recall making
a vigorous slideshow at a committee meeting in defense of having a
single memory map for ARMv8 servers and requiring everyone to follow it.
I was weak. I listened to the comments that this was "unreasonable".
Instead, I consider it was unreasonable of me to not get with the other
OS vendors and force things to be done one way. The lack of a "map at
zero" RAM location on ARMv8 has been annoying enough for 32-bit DMA only
devices on 64-bit (behind an SMMU but in passthrough mode it doesn't
help) and other issues beyond fixing the MSI doorbell regions. If I ever
have a time machine, I tried harder.
> Jon pointed out that most people are pretty conservative about hardware
> choices when migrating between them -- that is, they may only migrate
> between different revisions of the same SoC, or they know ahead of time
> all of the memory maps they want to support and this could be communicated
> by way of configuration to libvirt.
I think it's certainly reasonable to assume this in an initial
implementation and fix it later. Currently, we're very conservative
about host CPU passthrough anyway and can't migrate from one microarch
to another revision of the same microarch even. And on x86, nobody
really supports e.g. Intel to AMD and back again. I've always been of
the mind that we should ensure the architecture can handle this, but
then cautiously approach this with a default to not doing it.
> Alex asked if there was a security
> issue with DMA bypassing the SMMU, but there aren't currently any systems
> where that is known to happen. Such a system would surely not be safe for
> passthrough.
There are other potential security issues that came up but don't need to
be noted here (yet). I have wanted to clarify the SBSA for a long time
when it comes to how IOMMUs should be implemented. It's past time that
we went back and had a few conversations about that. I've poked.
> Ben mused that a way to handle conflicts dynamically might be to hotplug
> on the entire host bridge in the guest, passing firmware tables describing
> the new reserved regions as a property of the host bridge. Whilst this
> may well solve the issue, it was largely considered future work due to
> its invasive nature and dependency on firmware tables (and guest support)
> that do not currently exist.
Indeed. It's an elegant solution (thanks Ben) that I gather POWER
already does (good for them). We've obviously got a few things to clean
up after we get the basics in place. Again, I think we can consider it
reasonable that the MSI doorbell regions are predetermined on system A
well ahead of any potential migration (that may or may not then work)
for the moment. Vendors will want to loosen this later, and they can
drive the work to do that, for example by hotplugging a host bridge.
Jon.
^ permalink raw reply
* [PATCH] ARM: davinci: Allocate spare interrupts
From: David Lechner @ 2016-11-21 4:20 UTC (permalink / raw)
To: linux-arm-kernel
This allocates spare interrupts for mach-davinci. These extra interrupts
are need for things like IIO triggers that define software interrupts.
Signed-off-by: David Lechner <david@lechnology.com>
---
arch/arm/mach-davinci/include/mach/irqs.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-davinci/include/mach/irqs.h b/arch/arm/mach-davinci/include/mach/irqs.h
index edb2ca6..2b56bb2 100644
--- a/arch/arm/mach-davinci/include/mach/irqs.h
+++ b/arch/arm/mach-davinci/include/mach/irqs.h
@@ -403,7 +403,9 @@
/* da850 currently has the most gpio pins (144) */
#define DAVINCI_N_GPIO 144
+/* Extra IRQs for things like IIO triggers */
+#define DAVINCI_N_SPARE_IRQ 16
/* da850 currently has the most irqs so use DA850_N_CP_INTC_IRQ */
-#define NR_IRQS (DA850_N_CP_INTC_IRQ + DAVINCI_N_GPIO)
+#define NR_IRQS (DA850_N_CP_INTC_IRQ + DAVINCI_N_GPIO + DAVINCI_N_SPARE_IRQ)
#endif /* __ASM_ARCH_IRQS_H */
--
2.7.4
^ permalink raw reply related
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