* [PATCH V2 1/2] clk: rockchip: add ids for camera
From: Eddie Cai @ 2017-04-25 6:41 UTC (permalink / raw)
To: robh+dt, mark.rutland, heiko, zhengxing, mturquette, sboyd
Cc: devicetree, linux-kernel, linux-clk, linux-arm-kernel,
linux-rockchip, Eddie Cai
In-Reply-To: <1493102470-22965-1-git-send-email-eddie.cai.linux@gmail.com>
we use SCLK_TESTCLKOUT1 and SCLK_TESTCLKOUT2 for camera, so add those ids.
Signed-off-by: Eddie Cai <eddie.cai.linux@gmail.com>
---
include/dt-bindings/clock/rk3399-cru.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/dt-bindings/clock/rk3399-cru.h b/include/dt-bindings/clock/rk3399-cru.h
index 220a60f..22cb1df 100644
--- a/include/dt-bindings/clock/rk3399-cru.h
+++ b/include/dt-bindings/clock/rk3399-cru.h
@@ -132,6 +132,8 @@
#define SCLK_RMII_SRC 166
#define SCLK_PCIEPHY_REF100M 167
#define SCLK_DDRC 168
+#define SCLK_TESTCLKOUT1 169
+#define SCLK_TESTCLKOUT2 170
#define DCLK_VOP0 180
#define DCLK_VOP1 181
--
1.9.1
^ permalink raw reply related
* [PATCH V2 0/2] correct ids for clk_testout
From: Eddie Cai @ 2017-04-25 6:41 UTC (permalink / raw)
To: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
heiko-4mtYJXux2i+zQB+pC5nmwQ, zhengxing-TNX95d0MmH7DzftRWevZcw,
mturquette-rdvid1DuHRBWk0Htik3J/w, sboyd-sgV2jX0FEOL9JmXXK+q4OQ
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-clk-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Eddie Cai
we use clk_testout1 and clk_testout2 for camera. e.g. mipi 24M mclk. the ids of
clk_testout1 and clk_testout2 is wrong. it's time to correct it.
Eddie Cai (2):
clk: rockchip: add ids for camera
clk: rockchip: fix the incorrect ids
drivers/clk/rockchip/clk-rk3399.c | 4 ++--
include/dt-bindings/clock/rk3399-cru.h | 2 ++
2 files changed, 4 insertions(+), 2 deletions(-)
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] ARM: dts: Add devicetree for the Raspberry Pi 3, for arm32 (v5)
From: Stefan Wahren @ 2017-04-25 6:22 UTC (permalink / raw)
To: Eric Anholt, Lee Jones, Florian Fainelli, Olof Johansson,
Rob Herring, Mark Rutland, devicetree
Cc: linux-rpi-kernel, bcm-kernel-feedback-list, linux-kernel,
linux-arm-kernel, Gerd Hoffmann
In-Reply-To: <20170424200037.25615-1-eric@anholt.net>
Am 24.04.2017 um 22:00 schrieb Eric Anholt:
> Raspbian and Fedora have decided to support the Pi3 in 32-bit mode for
> now, so it's useful to be able to test that mode on an upstream
> kernel. It's also been useful for me to use the same board for 32-bit
> and 64-bit development.
>
> Signed-off-by: Eric Anholt <eric@anholt.net>
> ---
> arch/arm/boot/dts/Makefile | 1 +
> arch/arm/boot/dts/bcm2837-rpi-3.b.dts | 1 +
> 2 files changed, 2 insertions(+)
> create mode 100644 arch/arm/boot/dts/bcm2837-rpi-3.b.dts
>
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 011808490fed..eded842d9978 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -72,6 +72,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \
> bcm2835-rpi-b-plus.dtb \
> bcm2835-rpi-a-plus.dtb \
> bcm2836-rpi-2-b.dtb \
> + bcm2837-rpi-3-b.dtb \
> bcm2835-rpi-zero.dtb
> dtb-$(CONFIG_ARCH_BCM_5301X) += \
> bcm4708-asus-rt-ac56u.dtb \
> diff --git a/arch/arm/boot/dts/bcm2837-rpi-3.b.dts b/arch/arm/boot/dts/bcm2837-rpi-3.b.dts
> new file mode 100644
> index 000000000000..8c8aa4d1e9b3
> --- /dev/null
> +++ b/arch/arm/boot/dts/bcm2837-rpi-3.b.dts
> @@ -0,0 +1 @@
> +#include "arm64/broadcom/bcm2837-rpi-3.b.dts"
Looks like a typo in the dts filename and in the include ( dot instead
of dash ).
^ permalink raw reply
* [PATCH v2 4/4] of: detect invalid phandle in overlay
From: frowand.list-Re5JQEeQqe8AvxtiuMwx3w @ 2017-04-25 6:20 UTC (permalink / raw)
To: Rob Herring, stephen.boyd-QSEj5FYQhm4dnm+yROfE0A
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1493101210-11745-1-git-send-email-frowand.list-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
From: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
Overlays are not allowed to modify phandle values of previously existing
nodes because there is no information available to allow fixup up
properties that use the previously existing phandle.
Signed-off-by: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
---
drivers/of/overlay.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index ca0b85f5deb1..20ab49d2f7a4 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -130,6 +130,10 @@ static int of_overlay_apply_single_device_node(struct of_overlay *ov,
/* NOTE: Multiple mods of created nodes not supported */
tchild = of_get_child_by_name(target, cname);
if (tchild != NULL) {
+ /* new overlay phandle value conflicts with existing value */
+ if (child->phandle)
+ return -EINVAL;
+
/* apply overlay recursively */
ret = of_overlay_apply_one(ov, tchild, child);
of_node_put(tchild);
--
Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 3/4] of: be consistent in form of file mode
From: frowand.list @ 2017-04-25 6:20 UTC (permalink / raw)
To: Rob Herring, stephen.boyd; +Cc: devicetree, linux-kernel
In-Reply-To: <1493101210-11745-1-git-send-email-frowand.list@gmail.com>
From: Frank Rowand <frank.rowand@sony.com>
checkpatch whined about using S_IRUGO instead of octal equivalent
when adding phandle sysfs code, so used octal in that patch.
Change other instances of the S_* constants in the same file to
the octal form.
Signed-off-by: Frank Rowand <frank.rowand@sony.com>
---
drivers/of/base.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 9e70d283cdc5..865e54355733 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -168,7 +168,7 @@ int __of_add_property_sysfs(struct device_node *np, struct property *pp)
sysfs_bin_attr_init(&pp->attr);
pp->attr.attr.name = safe_name(&np->kobj, pp->name);
- pp->attr.attr.mode = secure ? S_IRUSR : S_IRUGO;
+ pp->attr.attr.mode = secure ? 0400 : 0444;
pp->attr.size = secure ? 0 : pp->length;
pp->attr.read = of_node_property_read;
--
Frank Rowand <frank.rowand@sony.com>
^ permalink raw reply related
* [PATCH v2 2/4] of: make __of_attach_node() static
From: frowand.list-Re5JQEeQqe8AvxtiuMwx3w @ 2017-04-25 6:20 UTC (permalink / raw)
To: Rob Herring, stephen.boyd-QSEj5FYQhm4dnm+yROfE0A
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1493101210-11745-1-git-send-email-frowand.list-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
From: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
__of_attach_node() is not used outside of drivers/of/dynamic.c. Make
it static and remove it from drivers/of/of_private.h.
Signed-off-by: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
---
drivers/of/dynamic.c | 2 +-
drivers/of/of_private.h | 1 -
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
index 59545b8fbf46..0b9cf6d5914c 100644
--- a/drivers/of/dynamic.c
+++ b/drivers/of/dynamic.c
@@ -216,7 +216,7 @@ int of_property_notify(int action, struct device_node *np,
return of_reconfig_notify(action, &pr);
}
-void __of_attach_node(struct device_node *np)
+static void __of_attach_node(struct device_node *np)
{
np->child = NULL;
np->sibling = np->parent->child;
diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
index 33f11a5384f3..b1ff70e1fdda 100644
--- a/drivers/of/of_private.h
+++ b/drivers/of/of_private.h
@@ -79,7 +79,6 @@ extern int __of_update_property(struct device_node *np,
extern void __of_update_property_sysfs(struct device_node *np,
struct property *newprop, struct property *oldprop);
-extern void __of_attach_node(struct device_node *np);
extern int __of_attach_node_sysfs(struct device_node *np);
extern void __of_detach_node(struct device_node *np);
extern void __of_detach_node_sysfs(struct device_node *np);
--
Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 1/4] of: remove *phandle properties from expanded device tree
From: frowand.list-Re5JQEeQqe8AvxtiuMwx3w @ 2017-04-25 6:20 UTC (permalink / raw)
To: Rob Herring, stephen.boyd-QSEj5FYQhm4dnm+yROfE0A
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1493101210-11745-1-git-send-email-frowand.list-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
From: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
Remove "phandle", "linux,phandle", and "ibm,phandle" properties from
the internal device tree. The phandle will still be in the struct
device_node phandle field.
This is to resolve the issue found by Stephen Boyd [1] when he changed
the type of struct property.value from void * to const void *. As
a result of the type change, the overlay code had compile errors
where the resolver updates phandle values.
[1] http://lkml.iu.edu/hypermail/linux/kernel/1702.1/04160.html
- Add sysfs infrastructure to report np->phandle, as if it was a property.
- Do not create "phandle" "ibm,phandle", and "linux,phandle" properties
in the expanded device tree.
- Remove phandle properties in of_attach_node(), for nodes dynamically
attached to the live tree. Add the phandle sysfs entry for these nodes.
- When creating an overlay changeset, duplicate the node phandle in
__of_node_dup().
- Remove no longer needed checks to exclude "phandle" and "linux,phandle"
properties in several locations.
- A side effect of these changes is that the obsolete "linux,phandle" and
"ibm,phandle" properties will no longer appear in /proc/device-tree (they
will appear as "phandle").
Signed-off-by: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
---
drivers/of/base.c | 51 +++++++++++++++++++++++++++++++++++++++++++---
drivers/of/dynamic.c | 54 +++++++++++++++++++++++++++++++++++++------------
drivers/of/fdt.c | 40 +++++++++++++++++++++---------------
drivers/of/of_private.h | 1 +
drivers/of/overlay.c | 4 +---
drivers/of/resolver.c | 23 +--------------------
include/linux/of.h | 1 +
7 files changed, 117 insertions(+), 57 deletions(-)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index d7c4629a3a2d..9e70d283cdc5 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -116,6 +116,19 @@ static ssize_t of_node_property_read(struct file *filp, struct kobject *kobj,
return memory_read_from_buffer(buf, count, &offset, pp->value, pp->length);
}
+static ssize_t of_node_phandle_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf,
+ loff_t offset, size_t count)
+{
+ phandle phandle;
+ struct device_node *np;
+
+ np = container_of(bin_attr, struct device_node, attr_phandle);
+ phandle = cpu_to_be32(np->phandle);
+ return memory_read_from_buffer(buf, count, &offset, &phandle,
+ sizeof(phandle));
+}
+
/* always return newly allocated name, caller must free after use */
static const char *safe_name(struct kobject *kobj, const char *orig_name)
{
@@ -164,6 +177,38 @@ int __of_add_property_sysfs(struct device_node *np, struct property *pp)
return rc;
}
+/*
+ * In the imported device tree (fdt), phandle is a property. In the
+ * internal data structure it is instead stored in the struct device_node.
+ * Make phandle visible in sysfs as if it was a property.
+ */
+int __of_add_phandle_sysfs(struct device_node *np)
+{
+ int rc;
+
+ if (IS_ENABLED(CONFIG_PPC_PSERIES))
+ return 0;
+
+ if (!IS_ENABLED(CONFIG_SYSFS))
+ return 0;
+
+ if (!of_kset || !of_node_is_attached(np))
+ return 0;
+
+ if (!np->phandle || np->phandle == 0xffffffff)
+ return 0;
+
+ sysfs_bin_attr_init(&pp->attr);
+ np->attr_phandle.attr.name = "phandle";
+ np->attr_phandle.attr.mode = 0444;
+ np->attr_phandle.size = sizeof(np->phandle);
+ np->attr_phandle.read = of_node_phandle_read;
+
+ rc = sysfs_create_bin_file(&np->kobj, &np->attr_phandle);
+ WARN(rc, "error adding attribute phandle to node %s\n", np->full_name);
+ return rc;
+}
+
int __of_attach_node_sysfs(struct device_node *np)
{
const char *name;
@@ -193,6 +238,8 @@ int __of_attach_node_sysfs(struct device_node *np)
if (rc)
return rc;
+ __of_add_phandle_sysfs(np);
+
for_each_property_of_node(np, pp)
__of_add_property_sysfs(np, pp);
@@ -2097,9 +2144,7 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
int id, len;
/* Skip those we do not want to proceed */
- if (!strcmp(pp->name, "name") ||
- !strcmp(pp->name, "phandle") ||
- !strcmp(pp->name, "linux,phandle"))
+ if (!strcmp(pp->name, "name"))
continue;
np = of_find_node_by_path(pp->value);
diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
index 888fdbc09992..59545b8fbf46 100644
--- a/drivers/of/dynamic.c
+++ b/drivers/of/dynamic.c
@@ -218,19 +218,6 @@ int of_property_notify(int action, struct device_node *np,
void __of_attach_node(struct device_node *np)
{
- const __be32 *phandle;
- int sz;
-
- np->name = __of_get_property(np, "name", NULL) ? : "<NULL>";
- np->type = __of_get_property(np, "device_type", NULL) ? : "<NULL>";
-
- phandle = __of_get_property(np, "phandle", &sz);
- if (!phandle)
- phandle = __of_get_property(np, "linux,phandle", &sz);
- if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle)
- phandle = __of_get_property(np, "ibm,phandle", &sz);
- np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0;
-
np->child = NULL;
np->sibling = np->parent->child;
np->parent->child = np;
@@ -243,11 +230,47 @@ void __of_attach_node(struct device_node *np)
int of_attach_node(struct device_node *np)
{
struct of_reconfig_data rd;
+ struct property *prev;
+ struct property *prop;
+ struct property *save_next;
unsigned long flags;
+ const __be32 *phandle;
+ int sz;
memset(&rd, 0, sizeof(rd));
rd.dn = np;
+ np->name = __of_get_property(np, "name", NULL) ? : "<NULL>";
+ np->type = __of_get_property(np, "device_type", NULL) ? : "<NULL>";
+
+ phandle = __of_get_property(np, "phandle", &sz);
+ if (!phandle)
+ phandle = __of_get_property(np, "linux,phandle", &sz);
+ if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle)
+ phandle = __of_get_property(np, "ibm,phandle", &sz);
+ np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0;
+
+ /* remove phandle properties from node */
+ prev = NULL;
+ for (prop = np->properties; prop != NULL; ) {
+ save_next = prop->next;
+ if (!strcmp(prop->name, "phandle") ||
+ !strcmp(prop->name, "ibm,phandle") ||
+ !strcmp(prop->name, "linux,phandle")) {
+ if (prev)
+ prev->next = prop->next;
+ else
+ np->properties = prop->next;
+ prop->next = np->deadprops;
+ np->deadprops = prop;
+ } else {
+ prev = prop;
+ }
+ prop = save_next;
+ }
+
+ __of_add_phandle_sysfs(np);
+
mutex_lock(&of_mutex);
raw_spin_lock_irqsave(&devtree_lock, flags);
__of_attach_node(np);
@@ -429,6 +452,7 @@ struct device_node *__of_node_dup(const struct device_node *np, const char *fmt,
/* Iterate over and duplicate all properties */
if (np) {
struct property *pp, *new_pp;
+ node->phandle = np->phandle;
for_each_property_of_node(np, pp) {
new_pp = __of_prop_dup(pp, GFP_KERNEL);
if (!new_pp)
@@ -441,6 +465,10 @@ struct device_node *__of_node_dup(const struct device_node *np, const char *fmt,
}
}
}
+
+ node->name = __of_get_property(node, "name", NULL) ? : "<NULL>";
+ node->type = __of_get_property(node, "device_type", NULL) ? : "<NULL>";
+
return node;
err_prop:
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index e5ce4b59e162..270f31b0c259 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -181,6 +181,8 @@ static void populate_properties(const void *blob,
const __be32 *val;
const char *pname;
u32 sz;
+ int prop_is_phandle = 0;
+ int prop_is_ibm_phandle = 0;
val = fdt_getprop_by_offset(blob, cur, &pname, &sz);
if (!val) {
@@ -196,11 +198,6 @@ static void populate_properties(const void *blob,
if (!strcmp(pname, "name"))
has_name = true;
- pp = unflatten_dt_alloc(mem, sizeof(struct property),
- __alignof__(struct property));
- if (dryrun)
- continue;
-
/* We accept flattened tree phandles either in
* ePAPR-style "phandle" properties, or the
* legacy "linux,phandle" properties. If both
@@ -208,23 +205,34 @@ static void populate_properties(const void *blob,
* will get weird. Don't do that.
*/
if (!strcmp(pname, "phandle") ||
- !strcmp(pname, "linux,phandle")) {
- if (!np->phandle)
- np->phandle = be32_to_cpup(val);
- }
+ !strcmp(pname, "linux,phandle"))
+ prop_is_phandle = 1;
/* And we process the "ibm,phandle" property
* used in pSeries dynamic device tree
* stuff
*/
- if (!strcmp(pname, "ibm,phandle"))
- np->phandle = be32_to_cpup(val);
+ if (!strcmp(pname, "ibm,phandle")) {
+ prop_is_phandle = 1;
+ prop_is_ibm_phandle = 1;
+ }
+
+ if (!prop_is_phandle)
+ pp = unflatten_dt_alloc(mem, sizeof(struct property),
+ __alignof__(struct property));
- pp->name = (char *)pname;
- pp->length = sz;
- pp->value = (__be32 *)val;
- *pprev = pp;
- pprev = &pp->next;
+ if (dryrun)
+ continue;
+
+ if (!prop_is_phandle) {
+ pp->name = (char *)pname;
+ pp->length = sz;
+ pp->value = (__be32 *)val;
+ *pprev = pp;
+ pprev = &pp->next;
+ } else if (prop_is_ibm_phandle || !np->phandle) {
+ np->phandle = be32_to_cpup(val);
+ }
}
/* With version 0x10 we may not have the name property,
diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
index 18bbb4517e25..33f11a5384f3 100644
--- a/drivers/of/of_private.h
+++ b/drivers/of/of_private.h
@@ -47,6 +47,7 @@ extern int of_property_notify(int action, struct device_node *np,
extern void of_node_release(struct kobject *kobj);
extern int __of_changeset_apply(struct of_changeset *ocs);
extern int __of_changeset_revert(struct of_changeset *ocs);
+extern int __of_add_phandle_sysfs(struct device_node *np);
#else /* CONFIG_OF_DYNAMIC */
static inline int of_property_notify(int action, struct device_node *np,
struct property *prop, struct property *old_prop)
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index 7827786718d8..ca0b85f5deb1 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -101,9 +101,7 @@ static int of_overlay_apply_single_property(struct of_overlay *ov,
tprop = of_find_property(target, prop->name, NULL);
/* special properties are not meant to be updated (silent NOP) */
- if (of_prop_cmp(prop->name, "name") == 0 ||
- of_prop_cmp(prop->name, "phandle") == 0 ||
- of_prop_cmp(prop->name, "linux,phandle") == 0)
+ if (!of_prop_cmp(prop->name, "name"))
return 0;
propn = __of_prop_dup(prop, GFP_KERNEL);
diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c
index 7ae9863cb0a4..624cbaeae0a4 100644
--- a/drivers/of/resolver.c
+++ b/drivers/of/resolver.c
@@ -71,30 +71,11 @@ static void adjust_overlay_phandles(struct device_node *overlay,
int phandle_delta)
{
struct device_node *child;
- struct property *prop;
- phandle phandle;
/* adjust node's phandle in node */
if (overlay->phandle != 0 && overlay->phandle != OF_PHANDLE_ILLEGAL)
overlay->phandle += phandle_delta;
- /* copy adjusted phandle into *phandle properties */
- for_each_property_of_node(overlay, prop) {
-
- if (of_prop_cmp(prop->name, "phandle") &&
- of_prop_cmp(prop->name, "linux,phandle"))
- continue;
-
- if (prop->length < 4)
- continue;
-
- phandle = be32_to_cpup(prop->value);
- if (phandle == OF_PHANDLE_ILLEGAL)
- continue;
-
- *(uint32_t *)prop->value = cpu_to_be32(overlay->phandle);
- }
-
for_each_child_of_node(overlay, child)
adjust_overlay_phandles(child, phandle_delta);
}
@@ -197,9 +178,7 @@ static int adjust_local_phandle_references(struct device_node *local_fixups,
for_each_property_of_node(local_fixups, prop_fix) {
/* skip properties added automatically */
- if (!of_prop_cmp(prop_fix->name, "name") ||
- !of_prop_cmp(prop_fix->name, "phandle") ||
- !of_prop_cmp(prop_fix->name, "linux,phandle"))
+ if (!of_prop_cmp(prop_fix->name, "name"))
continue;
if ((prop_fix->length % 4) != 0 || prop_fix->length == 0)
diff --git a/include/linux/of.h b/include/linux/of.h
index 21e6323de0f3..4e86e05853f3 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -61,6 +61,7 @@ struct device_node {
struct kobject kobj;
unsigned long _flags;
void *data;
+ struct bin_attribute attr_phandle;
#if defined(CONFIG_SPARC)
const char *path_component_name;
unsigned int unique_id;
--
Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 0/4] of: remove *phandle properties from expanded device tree
From: frowand.list @ 2017-04-25 6:20 UTC (permalink / raw)
To: Rob Herring, stephen.boyd; +Cc: devicetree, linux-kernel
From: Frank Rowand <frank.rowand@sony.com>
Remove "phandle" and "linux,phandle" properties from the internal
device tree. The phandle will still be in the struct device_node
phandle field.
This is to resolve the issue found by Stephen Boyd [1] when he changed
the type of struct property.value from void * to const void *. As
a result of the type change, the overlay code had compile errors
where the resolver updates phandle values.
[1] http://lkml.iu.edu/hypermail/linux/kernel/1702.1/04160.html
Patch 1 is the phandle related changes.
Patches 2 - 4 are minor fixups for issues that became visible
while implementing patch 1.
Changes from v1:
- Remove phandle properties in of_attach_node(), before attaching
the node to the live tree.
- Add the phandle sysfs entry for the node in of_attach_node().
- When creating an overlay changeset, duplicate the node phandle in
__of_node_dup().
Frank Rowand (4):
of: remove *phandle properties from expanded device tree
of: make __of_attach_node() static
of: be consistent in form of file mode
of: detect invalid phandle in overlay
drivers/of/base.c | 53 ++++++++++++++++++++++++++++++++++++++++++----
drivers/of/dynamic.c | 56 ++++++++++++++++++++++++++++++++++++-------------
drivers/of/fdt.c | 40 +++++++++++++++++++++--------------
drivers/of/of_private.h | 2 +-
drivers/of/overlay.c | 8 ++++---
drivers/of/resolver.c | 23 +-------------------
include/linux/of.h | 1 +
7 files changed, 123 insertions(+), 60 deletions(-)
--
Frank Rowand <frank.rowand@sony.com>
^ permalink raw reply
* Re: [PATCH v4 07/10] mfd: axp20x: add axp20x-regulator cell for AXP803
From: icenowy-h8G6r0blFSE @ 2017-04-25 5:47 UTC (permalink / raw)
To: Chen-Yu Tsai
Cc: Thomas Gleixner, Rob Herring, Maxime Ripard, Lee Jones,
Liam Girdwood, linux-kernel, devicetree, linux-arm-kernel,
linux-sunxi
In-Reply-To: <CAGb2v673CL6TaZxkNR9SZDiG5G3cMqU1-=XeMj5gyDbQq4YzVA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
在 2017-04-25 10:17,Chen-Yu Tsai 写道:
> On Tue, Apr 25, 2017 at 12:01 AM, Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
> wrote:
>> As axp20x-regulator now supports AXP803, add a cell for it.
>>
>> Signed-off-by: Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
>> Acked-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
>> ---
>> Changes in v4:
>> - Added a trailing comma for new cell, for easier further cell
>> addition.
>> Changes in v3:
>> - Make the new cell one-liner.
>>
>> drivers/mfd/axp20x.c | 3 ++-
>> drivers/regulator/axp20x-regulator.c | 6 +++---
>
> Squashed in wrong patch?
Oh seems so...
>
> ChenYu
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
^ permalink raw reply
* Re: [PATCH] ARM: dts: Add devicetree for the Raspberry Pi 3, for arm32 (v5)
From: Florian Fainelli @ 2017-04-25 4:14 UTC (permalink / raw)
To: Eric Anholt, Lee Jones, Florian Fainelli, Olof Johansson,
Rob Herring, Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA
Cc: linux-rpi-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Stefan Wahren,
bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w, Gerd Hoffmann
In-Reply-To: <20170424200037.25615-1-eric-WhKQ6XTQaPysTnJN9+BGXg@public.gmane.org>
On 04/24/2017 01:00 PM, Eric Anholt wrote:
> Raspbian and Fedora have decided to support the Pi3 in 32-bit mode for
> now, so it's useful to be able to test that mode on an upstream
> kernel. It's also been useful for me to use the same board for 32-bit
> and 64-bit development.
>
> Signed-off-by: Eric Anholt <eric-WhKQ6XTQaPysTnJN9+BGXg@public.gmane.org>
> ---
> arch/arm/boot/dts/Makefile | 1 +
> arch/arm/boot/dts/bcm2837-rpi-3.b.dts | 1 +
> 2 files changed, 2 insertions(+)
> create mode 100644 arch/arm/boot/dts/bcm2837-rpi-3.b.dts
>
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 011808490fed..eded842d9978 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -72,6 +72,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \
> bcm2835-rpi-b-plus.dtb \
> bcm2835-rpi-a-plus.dtb \
> bcm2836-rpi-2-b.dtb \
> + bcm2837-rpi-3-b.dtb \
> bcm2835-rpi-zero.dtb
> dtb-$(CONFIG_ARCH_BCM_5301X) += \
> bcm4708-asus-rt-ac56u.dtb \
> diff --git a/arch/arm/boot/dts/bcm2837-rpi-3.b.dts b/arch/arm/boot/dts/bcm2837-rpi-3.b.dts
> new file mode 100644
> index 000000000000..8c8aa4d1e9b3
> --- /dev/null
> +++ b/arch/arm/boot/dts/bcm2837-rpi-3.b.dts
> @@ -0,0 +1 @@
> +#include "arm64/broadcom/bcm2837-rpi-3.b.dts"
Sounds like this should be
../arm64/boot/dts/broadcom/bcm2837-rpi-3.b.dts are reported by the
kbuild test robot?
--
Florian
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] ARM: dts: Add devicetree for the Raspberry Pi 3, for arm32 (v5)
From: kbuild test robot @ 2017-04-25 3:56 UTC (permalink / raw)
Cc: kbuild-all-JC7UmRfGjtg, Lee Jones, Florian Fainelli,
Olof Johansson, Rob Herring, Mark Rutland,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-rpi-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Stefan Wahren,
bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w, Gerd Hoffmann,
Eric Anholt
In-Reply-To: <20170424200037.25615-1-eric-WhKQ6XTQaPysTnJN9+BGXg@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 1321 bytes --]
Hi Eric,
[auto build test ERROR on robh/for-next]
[also build test ERROR on v4.11-rc8 next-20170424]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Eric-Anholt/ARM-dts-Add-devicetree-for-the-Raspberry-Pi-3-for-arm32-v5/20170425-063618
base: https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: arm-at91_dt_defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=arm
All errors (new ones prefixed by >>):
>> arch/arm/boot/dts/bcm2837-rpi-3.b.dts:1:46: fatal error: arm64/broadcom/bcm2837-rpi-3.b.dts: No such file or directory
#include "arm64/broadcom/bcm2837-rpi-3.b.dts"
^
compilation terminated.
vim +1 arch/arm/boot/dts/bcm2837-rpi-3.b.dts
> 1 #include "arm64/broadcom/bcm2837-rpi-3.b.dts"
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 22403 bytes --]
^ permalink raw reply
* Re: [PATCH v3 2/2] Input: add support for the STMicroelectronics FingerTip touchscreen
From: Andi Shyti @ 2017-04-25 2:31 UTC (permalink / raw)
To: Dmitry Torokhov, Rob Herring
Cc: Javier Martinez Canillas, Andrzej Hajda, Chanwoo Choi,
linux-input-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Andi Shyti
In-Reply-To: <20170327130743.27783-3-andi.shyti-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Hi Dmitry,
again, kindly ping. This patch has been posted on March 27th and
this is the third time I ask you a feedback about it.
Please let me know,
Andi
On Mon, Mar 27, 2017 at 10:07:43PM +0900, Andi Shyti wrote:
> The stmfts (ST-Microelectronics FingerTip S) touchscreen device
> is a capacitive multi-touch controller mainly for mobile use.
>
> It's connected through i2c bus at the address 0x49 and it
> interfaces with userspace through input event interface.
>
> At the current state it provides a touchscreen multitouch
> functionality up to 10 fingers. Each finger is enumerated with a
> distinctive id (from 0 to 9).
>
> If enabled the device can support single "touch" hovering, by
> providing three coordinates, x, y and distance.
>
> It is possible to select the touchkey functionality which
> provides a basic two keys interface for "home" and "back" menu,
> typical in mobile phones.
>
> Signed-off-by: Andi Shyti <andi.shyti-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> ---
> drivers/input/touchscreen/Kconfig | 12 +
> drivers/input/touchscreen/Makefile | 1 +
> drivers/input/touchscreen/stmfts.c | 805 +++++++++++++++++++++++++++++++++++++
> 3 files changed, 818 insertions(+)
> create mode 100644 drivers/input/touchscreen/stmfts.c
>
> diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
> index 33c62e5de4fa..f8631c64290d 100644
> --- a/drivers/input/touchscreen/Kconfig
> +++ b/drivers/input/touchscreen/Kconfig
> @@ -1114,6 +1114,18 @@ config TOUCHSCREEN_ST1232
> To compile this driver as a module, choose M here: the
> module will be called st1232_ts.
>
> +config TOUCHSCREEN_STMFTS
> + tristate "STMicroelectronics STMFTS touchscreen"
> + depends on I2C
> + depends on INPUT
> + depends on LEDS_CLASS
> + help
> + Say Y here if you want support for STMicroelectronics
> + STMFTS touchscreen.
> +
> + To compile this driver as a module, choose M here: the
> + module will be called stmfts.
> +
> config TOUCHSCREEN_STMPE
> tristate "STMicroelectronics STMPE touchscreens"
> depends on MFD_STMPE
> diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
> index 18e476948e44..6badce87037b 100644
> --- a/drivers/input/touchscreen/Makefile
> +++ b/drivers/input/touchscreen/Makefile
> @@ -67,6 +67,7 @@ obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o
> obj-$(CONFIG_TOUCHSCREEN_SILEAD) += silead.o
> obj-$(CONFIG_TOUCHSCREEN_SIS_I2C) += sis_i2c.o
> obj-$(CONFIG_TOUCHSCREEN_ST1232) += st1232.o
> +obj-$(CONFIG_TOUCHSCREEN_STMFTS) += stmfts.o
> obj-$(CONFIG_TOUCHSCREEN_STMPE) += stmpe-ts.o
> obj-$(CONFIG_TOUCHSCREEN_SUN4I) += sun4i-ts.o
> obj-$(CONFIG_TOUCHSCREEN_SUR40) += sur40.o
> diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
> new file mode 100644
> index 000000000000..2e18b1456f42
> --- /dev/null
> +++ b/drivers/input/touchscreen/stmfts.c
> @@ -0,0 +1,805 @@
> +/*
> + * Copyright (c) 2017 Samsung Electronics Co., Ltd.
> + * Author: Andi Shyti <andi.shyti-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> + *
> + * 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.
> + *
> + * STMicroelectronics FTS Touchscreen device driver
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/i2c.h>
> +#include <linux/input/mt.h>
> +#include <linux/input/touchscreen.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/leds.h>
> +#include <linux/module.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/regulator/consumer.h>
> +
> +/* I2C commands */
> +#define STMFTS_READ_INFO 0x80
> +#define STMFTS_READ_STATUS 0x84
> +#define STMFTS_READ_ONE_EVENT 0x85
> +#define STMFTS_READ_ALL_EVENT 0x86
> +#define STMFTS_LATEST_EVENT 0x87
> +#define STMFTS_SLEEP_IN 0x90
> +#define STMFTS_SLEEP_OUT 0x91
> +#define STMFTS_MS_MT_SENSE_OFF 0x92
> +#define STMFTS_MS_MT_SENSE_ON 0x93
> +#define STMFTS_SS_HOVER_SENSE_OFF 0x94
> +#define STMFTS_SS_HOVER_SENSE_ON 0x95
> +#define STMFTS_MS_KEY_SENSE_OFF 0x9a
> +#define STMFTS_MS_KEY_SENSE_ON 0x9b
> +#define STMFTS_SYSTEM_RESET 0xa0
> +#define STMFTS_CLEAR_EVENT_STACK 0xa1
> +#define STMFTS_FULL_FORCE_CALIBRATION 0xa2
> +#define STMFTS_MS_CX_TUNING 0xa3
> +#define STMFTS_SS_CX_TUNING 0xa4
> +
> +/* events */
> +#define STMFTS_EV_NO_EVENT 0x00
> +#define STMFTS_EV_MULTI_TOUCH_DETECTED 0x02
> +#define STMFTS_EV_MULTI_TOUCH_ENTER 0x03
> +#define STMFTS_EV_MULTI_TOUCH_LEAVE 0x04
> +#define STMFTS_EV_MULTI_TOUCH_MOTION 0x05
> +#define STMFTS_EV_HOVER_ENTER 0x07
> +#define STMFTS_EV_HOVER_LEAVE 0x08
> +#define STMFTS_EV_HOVER_MOTION 0x09
> +#define STMFTS_EV_KEY_STATUS 0x0e
> +#define STMFTS_EV_ERROR 0x0f
> +#define STMFTS_EV_CONTROLLER_READY 0x10
> +#define STMFTS_EV_SLEEP_OUT_CONTROLLER_READY 0x11
> +#define STMFTS_EV_STATUS 0x16
> +#define STMFTS_EV_DEBUG 0xdb
> +
> +/* multi touch related event masks */
> +#define STMFTS_MASK_EVENT_ID 0x0f
> +#define STMFTS_MASK_TOUCH_ID 0xf0
> +#define STMFTS_MASK_LEFT_EVENT 0x0f
> +#define STMFTS_MASK_X_MSB 0x0f
> +#define STMFTS_MASK_Y_LSB 0xf0
> +
> +/* key related event masks */
> +#define STMFTS_MASK_KEY_NO_TOUCH 0x00
> +#define STMFTS_MASK_KEY_MENU 0x01
> +#define STMFTS_MASK_KEY_BACK 0x02
> +
> +#define STMFTS_EVENT_SIZE 8
> +#define STMFTS_STACK_DEPTH 32
> +#define STMFTS_DATA_MAX_SIZE (STMFTS_EVENT_SIZE * STMFTS_STACK_DEPTH)
> +#define STMFTS_MAX_FINGERS 10
> +#define STMFTS_DEV_NAME "stmfts"
> +
> +enum stmfts_regulators {
> + STMFTS_REGULATOR_VDD,
> + STMFTS_REGULATOR_AVDD,
> +};
> +
> +struct stmfts_data {
> + struct i2c_client *client;
> + struct input_dev *input;
> + struct led_classdev led_cdev;
> + struct mutex mutex;
> +
> + struct touchscreen_properties prop;
> +
> + struct regulator_bulk_data regulators[2];
> +
> + /* ledvdd will be used also to check
> + * whether the LED is supported
> + */
> + struct regulator *ledvdd;
> +
> + u16 chip_id;
> + u8 chip_ver;
> + u16 fw_ver;
> + u8 config_id;
> + u8 config_ver;
> +
> + u8 data[STMFTS_DATA_MAX_SIZE];
> +
> + struct completion signal;
> +
> + bool use_key;
> + bool led_status;
> + bool hover_enabled;
> + bool running;
> +};
> +
> +static int stmfts_read_i2c_block_data(struct stmfts_data *sdata)
> +{
> + struct i2c_msg msgs[2];
> + u8 cmd = STMFTS_READ_ALL_EVENT;
> +
> + msgs[0].addr = sdata->client->addr;
> + msgs[0].flags = 0;
> + msgs[0].len = 1;
> + msgs[0].buf = &cmd;
> +
> + msgs[1].addr = sdata->client->addr;
> + msgs[1].flags = I2C_M_RD;
> + msgs[1].len = STMFTS_DATA_MAX_SIZE - STMFTS_EVENT_SIZE;
> + msgs[1].buf = sdata->data + STMFTS_EVENT_SIZE;
> +
> + return i2c_transfer(sdata->client->adapter, msgs, ARRAY_SIZE(msgs));
> +}
> +
> +static void stmfts_brightness_set(struct led_classdev *led_cdev,
> + enum led_brightness value)
> +{
> + struct stmfts_data *sdata = container_of(led_cdev,
> + struct stmfts_data, led_cdev);
> +
> + if (value == sdata->led_status || !sdata->ledvdd)
> + return;
> +
> + if (!value) {
> + regulator_disable(sdata->ledvdd);
> + } else {
> + int err = regulator_enable(sdata->ledvdd);
> +
> + if (err)
> + dev_warn(&sdata->client->dev,
> + "failed to disable ledvdd regulator\n");
> + }
> +
> + sdata->led_status = value;
> +}
> +
> +static enum led_brightness stmfts_brightness_get(struct led_classdev *led_cdev)
> +{
> + struct stmfts_data *sdata = container_of(led_cdev,
> + struct stmfts_data, led_cdev);
> +
> + return !!regulator_is_enabled(sdata->ledvdd);
> +}
> +
> +static void stmfts_parse_event(struct stmfts_data *sdata)
> +{
> + u8 id, t_id;
> + u16 x, y, z, maj, min, orientation, area;
> + u8 *event;
> + int i;
> +
> + for (i = 0; i < STMFTS_STACK_DEPTH; i++) {
> + event = &sdata->data[i*STMFTS_EVENT_SIZE];
> +
> + id = event[0] & STMFTS_MASK_EVENT_ID;
> + t_id = (event[0] & STMFTS_MASK_TOUCH_ID) >> 4;
> +
> + switch (id) {
> + case STMFTS_EV_NO_EVENT:
> + return;
> +
> + case STMFTS_EV_MULTI_TOUCH_ENTER:
> + case STMFTS_EV_MULTI_TOUCH_LEAVE:
> + case STMFTS_EV_MULTI_TOUCH_MOTION:
> + if (id == STMFTS_EV_MULTI_TOUCH_ENTER)
> + input_mt_report_slot_state(sdata->input,
> + MT_TOOL_FINGER, true);
> + else if (id == STMFTS_EV_MULTI_TOUCH_LEAVE)
> + input_mt_report_slot_state(sdata->input,
> + MT_TOOL_FINGER, false);
> +
> + x = event[1] | ((event[2] & STMFTS_MASK_X_MSB) << 8);
> + y = (event[2] >> 4) | (event[3] << 4);
> +
> + maj = event[4];
> + min = event[5];
> + orientation = event[6];
> + area = event[7];
> +
> + input_mt_slot(sdata->input, t_id);
> + input_report_abs(sdata->input, ABS_MT_POSITION_X, x);
> + input_report_abs(sdata->input, ABS_MT_POSITION_Y, y);
> + input_report_abs(sdata->input, ABS_MT_TOUCH_MAJOR, maj);
> + input_report_abs(sdata->input, ABS_MT_TOUCH_MINOR, min);
> + input_report_abs(sdata->input, ABS_MT_PRESSURE, area);
> + input_report_abs(sdata->input, ABS_MT_ORIENTATION,
> + orientation);
> + input_sync(sdata->input);
> +
> + break;
> +
> + case STMFTS_EV_HOVER_ENTER:
> + case STMFTS_EV_HOVER_LEAVE:
> + case STMFTS_EV_HOVER_MOTION:
> + x = (event[2] << 4) | (event[4] >> 4);
> + y = (event[3] << 4) | (event[4] & STMFTS_MASK_Y_LSB);
> + z = event[5];
> + orientation = event[6] & STMFTS_MASK_Y_LSB;
> +
> + input_report_abs(sdata->input, ABS_X, x);
> + input_report_abs(sdata->input, ABS_Y, y);
> + input_report_abs(sdata->input, ABS_DISTANCE, z);
> + input_sync(sdata->input);
> +
> + break;
> +
> + case STMFTS_EV_KEY_STATUS:
> + switch (event[2]) {
> + case 0:
> + input_report_key(sdata->input, KEY_BACK, 0);
> + input_report_key(sdata->input, KEY_MENU, 0);
> + break;
> +
> + case STMFTS_MASK_KEY_BACK:
> + input_report_key(sdata->input, KEY_BACK, 1);
> + break;
> +
> + case STMFTS_MASK_KEY_MENU:
> + input_report_key(sdata->input, KEY_MENU, 1);
> + break;
> +
> + default:
> + dev_warn(&sdata->client->dev,
> + "unknown key event\n");
> + }
> +
> + input_sync(sdata->input);
> + break;
> +
> + case STMFTS_EV_ERROR:
> + dev_warn(&sdata->client->dev,
> + "error code: 0x%x%x%x%x%x%x",
> + event[6], event[5], event[4],
> + event[3], event[2], event[1]);
> + break;
> +
> + default:
> + dev_err(&sdata->client->dev,
> + "unknown event 0x%x\n", event[0]);
> + }
> + }
> +}
> +
> +static irqreturn_t stmfts_irq_handler(int irq, void *dev)
> +{
> + struct stmfts_data *sdata = dev;
> + int ret;
> +
> + mutex_lock(&sdata->mutex);
> + ret = i2c_smbus_read_i2c_block_data(sdata->client,
> + STMFTS_READ_ONE_EVENT,
> + STMFTS_EVENT_SIZE, sdata->data);
> +
> + if (ret < 0 || ret != STMFTS_EVENT_SIZE)
> + goto exit;
> +
> + switch (sdata->data[0]) {
> + case STMFTS_EV_CONTROLLER_READY:
> + case STMFTS_EV_SLEEP_OUT_CONTROLLER_READY:
> + case STMFTS_EV_STATUS:
> + complete(&sdata->signal);
> + case STMFTS_EV_NO_EVENT:
> + case STMFTS_EV_DEBUG:
> + break;
> +
> + default:
> + if (unlikely(!sdata->input))
> + goto exit;
> +
> + ret = stmfts_read_i2c_block_data(sdata);
> + if (ret < 0)
> + goto exit;
> +
> + stmfts_parse_event(sdata);
> + }
> +
> +exit:
> + mutex_unlock(&sdata->mutex);
> + return IRQ_HANDLED;
> +}
> +
> +static int stmfts_write_and_wait(struct stmfts_data *sdata, const u8 cmd)
> +{
> + int err;
> +
> + err = i2c_smbus_write_byte(sdata->client, cmd);
> + if (err)
> + return err;
> +
> + err = wait_for_completion_timeout(&sdata->signal,
> + msecs_to_jiffies(1000));
> +
> + return !err ? -ETIMEDOUT : 0;
> +}
> +
> +static int stmfts_input_open(struct input_dev *dev)
> +{
> + int ret;
> + struct stmfts_data *sdata = input_get_drvdata(dev);
> +
> + ret = pm_runtime_get_sync(&sdata->client->dev);
> + if (ret < 0)
> + return ret;
> +
> + ret = i2c_smbus_write_byte(sdata->client, STMFTS_MS_MT_SENSE_ON);
> + if (ret)
> + return ret;
> +
> + mutex_lock(&sdata->mutex);
> + sdata->running = true;
> +
> + if (sdata->hover_enabled) {
> + ret = i2c_smbus_write_byte(sdata->client,
> + STMFTS_SS_HOVER_SENSE_ON);
> + if (ret)
> + dev_warn(&sdata->client->dev,
> + "failed to enable hover\n");
> + }
> + mutex_unlock(&sdata->mutex);
> +
> + if (sdata->use_key) {
> + ret = i2c_smbus_write_byte(sdata->client,
> + STMFTS_MS_KEY_SENSE_ON);
> + if (ret)
> + /* I can still use only the touch screen */
> + dev_warn(&sdata->client->dev,
> + "failed to enable touchkey\n");
> + }
> +
> + return 0;
> +}
> +
> +static void stmfts_input_close(struct input_dev *dev)
> +{
> + int ret;
> + struct stmfts_data *sdata = input_get_drvdata(dev);
> +
> + ret = i2c_smbus_write_byte(sdata->client, STMFTS_MS_MT_SENSE_OFF);
> + if (ret)
> + dev_warn(&sdata->client->dev,
> + "failed to disable touchscreen\n");
> +
> + mutex_lock(&sdata->mutex);
> + sdata->running = false;
> +
> + if (sdata->hover_enabled) {
> + ret = i2c_smbus_write_byte(sdata->client,
> + STMFTS_SS_HOVER_SENSE_OFF);
> + if (ret)
> + dev_warn(&sdata->client->dev,
> + "failed to disable hover\n");
> + }
> + mutex_unlock(&sdata->mutex);
> +
> + if (sdata->use_key) {
> + i2c_smbus_write_byte(sdata->client, STMFTS_MS_KEY_SENSE_OFF);
> + if (ret)
> + dev_warn(&sdata->client->dev,
> + "failed to disable touchkey\n");
> + }
> +
> + pm_runtime_put_sync(&sdata->client->dev);
> +}
> +
> +static ssize_t stmfts_sysfs_chip_id(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + struct stmfts_data *sdata = dev_get_drvdata(dev);
> +
> + return sprintf(buf, "0x%x\n", sdata->chip_id);
> +}
> +
> +static ssize_t stmfts_sysfs_chip_version(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + struct stmfts_data *sdata = dev_get_drvdata(dev);
> +
> + return sprintf(buf, "%u\n", sdata->chip_ver);
> +}
> +
> +static ssize_t stmfts_sysfs_fw_ver(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + struct stmfts_data *sdata = dev_get_drvdata(dev);
> +
> + return sprintf(buf, "%u\n", sdata->fw_ver);
> +}
> +
> +static ssize_t stmfts_sysfs_config_id(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + struct stmfts_data *sdata = dev_get_drvdata(dev);
> +
> + return sprintf(buf, "0x%x\n", sdata->config_id);
> +}
> +
> +static ssize_t stmfts_sysfs_config_version(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + struct stmfts_data *sdata = dev_get_drvdata(dev);
> +
> + return sprintf(buf, "%u\n", sdata->config_ver);
> +}
> +
> +static ssize_t stmfts_sysfs_read_status(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + struct stmfts_data *sdata = dev_get_drvdata(dev);
> + u8 status[4];
> + int ret;
> +
> + ret = i2c_smbus_read_i2c_block_data(sdata->client,
> + STMFTS_READ_STATUS, 4, status);
> +
> + return sprintf(buf, "0x%x\n", status[0]);
> +}
> +
> +static ssize_t stmfts_sysfs_hover_enable_read(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + struct stmfts_data *sdata = dev_get_drvdata(dev);
> +
> + return sprintf(buf, "%u\n", sdata->hover_enabled);
> +}
> +
> +static ssize_t stmfts_sysfs_hover_enable_write(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf, size_t len)
> +{
> + unsigned long value;
> + int err;
> + struct stmfts_data *sdata = dev_get_drvdata(dev);
> +
> + if (kstrtoul(buf, 0, &value))
> + return -EINVAL;
> +
> + mutex_lock(&sdata->mutex);
> +
> + if (value & sdata->hover_enabled)
> + goto out;
> +
> + if (!sdata->running) {
> + sdata->hover_enabled = !!value;
> + goto out;
> + }
> +
> + if (value) {
> + err = i2c_smbus_write_byte(sdata->client,
> + STMFTS_SS_HOVER_SENSE_ON);
> + sdata->hover_enabled = !err;
> + } else {
> + err = i2c_smbus_write_byte(sdata->client,
> + STMFTS_SS_HOVER_SENSE_OFF);
> + sdata->hover_enabled = !!err;
> + }
> +
> + if (err)
> + dev_warn(&sdata->client->dev, "failed to %s hover\n",
> + value ? "enable" : "disable");
> +out:
> + mutex_unlock(&sdata->mutex);
> +
> + return len;
> +}
> +
> +static DEVICE_ATTR(chip_id, 0444, stmfts_sysfs_chip_id, NULL);
> +static DEVICE_ATTR(chip_version, 0444, stmfts_sysfs_chip_version, NULL);
> +static DEVICE_ATTR(fw_ver, 0444, stmfts_sysfs_fw_ver, NULL);
> +static DEVICE_ATTR(config_id, 0444, stmfts_sysfs_config_id, NULL);
> +static DEVICE_ATTR(config_version, 0444, stmfts_sysfs_config_version, NULL);
> +static DEVICE_ATTR(status, 0444, stmfts_sysfs_read_status, NULL);
> +static DEVICE_ATTR(hover_enable, 0644, stmfts_sysfs_hover_enable_read,
> + stmfts_sysfs_hover_enable_write);
> +
> +static struct attribute *stmfts_sysfs_attrs[] = {
> + &dev_attr_chip_id.attr,
> + &dev_attr_chip_version.attr,
> + &dev_attr_fw_ver.attr,
> + &dev_attr_config_id.attr,
> + &dev_attr_config_version.attr,
> + &dev_attr_status.attr,
> + &dev_attr_hover_enable.attr,
> + NULL
> +};
> +
> +static struct attribute_group stmfts_attribute_group = {
> + .attrs = stmfts_sysfs_attrs
> +};
> +
> +static int stmfts_power_on(struct stmfts_data *sdata)
> +{
> + int err;
> + u8 reg[8];
> +
> + err = regulator_bulk_enable(ARRAY_SIZE(sdata->regulators),
> + sdata->regulators);
> + if (err)
> + return err;
> +
> + /*
> + * the datasheet does not specify the power on time, but considering
> + * that the reset time is < 10ms, I sleep 20ms to be sure
> + */
> + msleep(20);
> +
> + err = i2c_smbus_read_i2c_block_data(sdata->client,
> + STMFTS_READ_INFO, 8, reg);
> + if (err < 0)
> + return err;
> + if (err != 8)
> + return -EIO;
> +
> + sdata->chip_id = (reg[6] << 8) | reg[7];
> + sdata->chip_ver = reg[0];
> + sdata->fw_ver = (reg[2] << 8) | reg[3];
> + sdata->config_id = reg[4];
> + sdata->config_ver = reg[5];
> +
> + reinit_completion(&sdata->signal);
> +
> + enable_irq(sdata->client->irq);
> + err = stmfts_write_and_wait(sdata, STMFTS_SYSTEM_RESET);
> + if (err)
> + return err;
> +
> + err = stmfts_write_and_wait(sdata, STMFTS_SLEEP_OUT);
> + if (err)
> + return err;
> +
> + /* optional tuning */
> + err = stmfts_write_and_wait(sdata, STMFTS_MS_CX_TUNING);
> + if (err)
> + dev_warn(&sdata->client->dev, "failed to perform mutual auto tune\n");
> +
> + /* optional tuning */
> + err = stmfts_write_and_wait(sdata, STMFTS_SS_CX_TUNING);
> + if (err)
> + dev_warn(&sdata->client->dev, "failed to perform self auto tune\n");
> +
> + err = stmfts_write_and_wait(sdata, STMFTS_FULL_FORCE_CALIBRATION);
> + if (err)
> + return err;
> +
> + /* at this point no one is using the touchscreen
> + * and I don't really care about the return value
> + */
> + i2c_smbus_write_byte(sdata->client, STMFTS_SLEEP_IN);
> +
> + return 0;
> +}
> +
> +static void stmfts_power_off(void *data)
> +{
> + struct stmfts_data *sdata = data;
> +
> + disable_irq(sdata->client->irq);
> + regulator_bulk_disable(ARRAY_SIZE(sdata->regulators),
> + sdata->regulators);
> +}
> +
> +/* This function is void because I don't want to prevent using the touch key
> + * only because the LEDs don't get registered
> + */
> +static int stmfts_enable_led(struct stmfts_data *sdata)
> +{
> + int err;
> +
> + /* get the regulator for powering the leds on */
> + sdata->ledvdd = devm_regulator_get(&sdata->client->dev, "ledvdd");
> + if (IS_ERR(sdata->ledvdd))
> + return PTR_ERR(sdata->ledvdd);
> +
> + sdata->led_cdev.name = STMFTS_DEV_NAME;
> + sdata->led_cdev.max_brightness = LED_ON;
> + sdata->led_cdev.brightness = LED_OFF;
> + sdata->led_cdev.brightness_set = stmfts_brightness_set;
> + sdata->led_cdev.brightness_get = stmfts_brightness_get;
> +
> + err = devm_led_classdev_register(&sdata->client->dev, &sdata->led_cdev);
> + if (err) {
> + devm_regulator_put(sdata->ledvdd);
> + return err;
> + }
> +
> + return 0;
> +}
> +
> +static int stmfts_probe(struct i2c_client *client,
> + const struct i2c_device_id *id)
> +{
> + int err;
> + struct stmfts_data *sdata;
> +
> + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
> + I2C_FUNC_SMBUS_BYTE_DATA |
> + I2C_FUNC_SMBUS_I2C_BLOCK))
> + return -ENODEV;
> +
> + if (!client->dev.of_node)
> + return -ENOENT;
> +
> + sdata = devm_kzalloc(&client->dev, sizeof(*sdata), GFP_KERNEL);
> + if (!sdata)
> + return -ENOMEM;
> +
> + i2c_set_clientdata(client, sdata);
> +
> + mutex_init(&sdata->mutex);
> +
> + sdata->regulators[STMFTS_REGULATOR_VDD].supply = "vdd";
> + sdata->regulators[STMFTS_REGULATOR_AVDD].supply = "avdd";
> + err = devm_regulator_bulk_get(&client->dev,
> + ARRAY_SIZE(sdata->regulators), sdata->regulators);
> + if (err)
> + return err;
> +
> + err = devm_add_action_or_reset(&client->dev, stmfts_power_off, sdata);
> + if (err)
> + return err;
> +
> + sdata->client = client;
> +
> + init_completion(&sdata->signal);
> +
> + /*
> + * Do not enable interrupts by default.
> + * One possible case when an IRQ can be already rased is e.g. if the
> + * regulator is set as always on and the stmfts device sends an IRQ as
> + * soon as it gets powered, de-synchronizing the power on sequence.
> + * During power on, the device will be reset and all the initialization
> + * IRQ will be resent.
> + */
> + irq_set_status_flags(client->irq, IRQ_NOAUTOEN);
> + err = devm_request_threaded_irq(&client->dev, client->irq,
> + NULL, stmfts_irq_handler,
> + IRQF_ONESHOT | IRQF_TRIGGER_LOW,
> + "stmfts_irq", sdata);
> + if (err)
> + return err;
> +
> + dev_info(&client->dev, "initializing ST-Microelectronics FTS...\n");
> + err = stmfts_power_on(sdata);
> + if (err)
> + return err;
> +
> + sdata->use_key = of_property_read_bool(client->dev.of_node,
> + "touch-key-connected");
> +
> + sdata->input = devm_input_allocate_device(&client->dev);
> + if (!sdata->input)
> + return -ENOMEM;
> +
> + sdata->input->name = STMFTS_DEV_NAME;
> + sdata->input->id.bustype = BUS_I2C;
> + sdata->input->open = stmfts_input_open;
> + sdata->input->close = stmfts_input_close;
> +
> + touchscreen_parse_properties(sdata->input, true, &sdata->prop);
> +
> + input_set_abs_params(sdata->input, ABS_MT_POSITION_X, 0,
> + sdata->prop.max_x, 0, 0);
> + input_set_abs_params(sdata->input, ABS_MT_POSITION_Y, 0,
> + sdata->prop.max_y, 0, 0);
> + input_set_abs_params(sdata->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
> + input_set_abs_params(sdata->input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0);
> + input_set_abs_params(sdata->input, ABS_MT_ORIENTATION, 0, 255, 0, 0);
> + input_set_abs_params(sdata->input, ABS_MT_PRESSURE, 0, 255, 0, 0);
> + input_set_abs_params(sdata->input, ABS_DISTANCE, 0, 255, 0, 0);
> +
> + if (sdata->use_key) {
> + input_set_capability(sdata->input, EV_KEY, KEY_MENU);
> + input_set_capability(sdata->input, EV_KEY, KEY_BACK);
> + }
> +
> + err = input_mt_init_slots(sdata->input,
> + STMFTS_MAX_FINGERS, INPUT_MT_DIRECT);
> + if (err)
> + return err;
> +
> + input_set_drvdata(sdata->input, sdata);
> + err = input_register_device(sdata->input);
> + if (err)
> + return err;
> +
> + if (sdata->use_key) {
> + err = stmfts_enable_led(sdata);
> + if (err) {
> + /* even if the LEDs have failed to be initialized and
> + * used in the driver, I can still use the device even
> + * without LEDs. The ledvdd regulator pointer will be
> + * used as a flag.
> + */
> + dev_warn(&client->dev,
> + "unable to use touchkey leds\n");
> + sdata->ledvdd = NULL;
> + }
> + }
> +
> + err = sysfs_create_group(&sdata->client->dev.kobj,
> + &stmfts_attribute_group);
> + if (err)
> + return err;
> +
> + pm_runtime_enable(&client->dev);
> +
> + return 0;
> +}
> +
> +static int stmfts_remove(struct i2c_client *client)
> +{
> + pm_runtime_disable(&client->dev);
> + sysfs_remove_group(&client->dev.kobj, &stmfts_attribute_group);
> +
> + return 0;
> +}
> +
> +static int stmfts_runtime_suspend(struct device *dev)
> +{
> + int ret;
> + struct stmfts_data *sdata = dev_get_drvdata(dev);
> +
> + ret = i2c_smbus_write_byte(sdata->client, STMFTS_SLEEP_IN);
> + if (ret)
> + dev_warn(dev, "failed to suspend device\n");
> +
> + return ret;
> +}
> +
> +static int stmfts_runtime_resume(struct device *dev)
> +{
> + int ret;
> + struct stmfts_data *sdata = dev_get_drvdata(dev);
> +
> + ret = i2c_smbus_write_byte(sdata->client, STMFTS_SLEEP_OUT);
> + if (ret)
> + dev_err(dev, "failed to resume device\n");
> +
> + return ret;
> +}
> +
> +static int __maybe_unused stmfts_suspend(struct device *dev)
> +{
> + struct stmfts_data *sdata = dev_get_drvdata(dev);
> +
> + stmfts_power_off(sdata);
> +
> + return 0;
> +}
> +
> +static int __maybe_unused stmfts_resume(struct device *dev)
> +{
> + struct stmfts_data *sdata = dev_get_drvdata(dev);
> +
> + return stmfts_power_on(sdata);
> +}
> +
> +static const struct dev_pm_ops stmfts_pm_ops = {
> + SET_SYSTEM_SLEEP_PM_OPS(stmfts_suspend, stmfts_resume)
> + SET_RUNTIME_PM_OPS(stmfts_runtime_suspend, stmfts_runtime_resume, NULL)
> +};
> +
> +static const struct of_device_id stmfts_of_match[] = {
> + { .compatible = "st,stmfts", },
> + { },
> +};
> +MODULE_DEVICE_TABLE(of, stmfts_of_match);
> +
> +static const struct i2c_device_id stmfts_id[] = {
> + { "stmfts", 0 },
> + { },
> +};
> +MODULE_DEVICE_TABLE(i2c, stmfts_id);
> +
> +static struct i2c_driver stmfts_driver = {
> + .driver = {
> + .name = STMFTS_DEV_NAME,
> + .of_match_table = of_match_ptr(stmfts_of_match),
> + .pm = &stmfts_pm_ops,
> + },
> + .probe = stmfts_probe,
> + .remove = stmfts_remove,
> + .id_table = stmfts_id,
> +};
> +
> +module_i2c_driver(stmfts_driver);
> +
> +MODULE_AUTHOR("Andi Shyti <andi.shyti-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>");
> +MODULE_DESCRIPTION("STMicroelectronics FTS Touch Screen");
> +MODULE_LICENSE("GPL v2");
> --
> 2.11.0
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v7 4/5] i2c: aspeed: added driver for Aspeed I2C
From: Benjamin Herrenschmidt @ 2017-04-25 2:21 UTC (permalink / raw)
To: Brendan Higgins, wsa, robh+dt, mark.rutland, tglx, jason,
marc.zyngier, joel, vz, mouse, clg
Cc: linux-i2c, devicetree, linux-kernel, openbmc
In-Reply-To: <20170424181818.2754-5-brendanhiggins@google.com>
On Mon, 2017-04-24 at 11:18 -0700, Brendan Higgins wrote:
> +static int __aspeed_i2c_init_clk(struct aspeed_i2c_bus *bus,
> + struct platform_device *pdev)
> +{
Minor nit ... I'm really not fan of those underscores.
We use __ functions in some cases in the kernel for low level
helpers, usually when it's a low level variant of an existing
function or an "unlocked" variant, but I don't think generalizing
it to pretty much everything in the driver is worthwhile here.
If you want to be explicit about locking, I would suggest you
use a comment in front of the function explaining if it
expects to be called with the lock held.
We tend to only do that when *both* functions exist and one is
implemented in term of the other.
Cheers,
Ben.
^ permalink raw reply
* Re: [PATCH v6 4/5] i2c: aspeed: added driver for Aspeed I2C
From: Benjamin Herrenschmidt @ 2017-04-25 2:19 UTC (permalink / raw)
To: Brendan Higgins
Cc: Wolfram Sang, Rob Herring, Mark Rutland, Thomas Gleixner,
Jason Cooper, Marc Zyngier, Joel Stanley, Vladimir Zapolskiy,
Kachalov Anton, Cédric Le Goater, linux-i2c, devicetree,
Linux Kernel Mailing List, OpenBMC Maillist
In-Reply-To: <CAFd5g45DQZz99y59AY-4465qnM+tRv6+bDdGQqS6VYHEfRfjDg@mail.gmail.com>
On Mon, 2017-04-24 at 11:56 -0700, Brendan Higgins wrote:
> > > +struct aspeed_i2c_bus {
> > > + struct i2c_adapter adap;
> > > + struct device *dev;
> > > + void __iomem *base;
> > > + /* Synchronizes I/O mem access to base. */
> > > + spinlock_t lock;
> >
> > I am not entirely convinced we need that lock. The i2c core will
> > take a mutex protecting all operations on the bus. So we only need
> > to synchronize between our "xfer" code and our interrupt handler.
>
> You are right if both having slave and master active at the same time
> was not possible; however, it is.
Right, I somewhat forgot about the slave case.
...
> > Some of those error states probably also warrant a reset of the
> > controller,
> > I think aspeed does that in the SDK.
>
> For timeout and cmd_err, I do not see any argument against it; it
> sounds like we are in a very messed up, very unknown state, so full
> reset is probably the best last resort.
Yup.
> For SDA staying pulled down, I
> think we can say with reasonable confidence that some device on our
> bus is behaving very badly and I am not convinced that resetting the
> controller is likely to do anything to help;
Right. Hammering with STOPs and pray ...
> that being said, I really
> do not have any good ideas to address that. So maybe praying and
> resetting the controller is *the most reasonable thing to do.* I
> would like to know what you think we should do in that case.
Well, there's a (small ?) chance that it's a controller bug asserting
the line so ... but there's little we can do if not.
> While I was thinking about this I also realized that the SDA line
> check after recovery happens in the else branch, but SCL line check
> does not happen after we attempt to STOP if SCL is hung. If we decide
> to make special note SDA being hung by a device that won't let go, we
> might want to make a special note that SCL is hung by a device that
> won't let go. Just a thought.
Maybe. Or just "unrecoverable error"... hopefully these don't happen
too often ... We had cases of a TPM misbehaving like that.
> > > +out:
>
> ...
> > What about I2C_M_NOSTART ?
> >
> > Not that I've ever seen it used... ;-)
>
> Right now I am not doing any of the protocol mangling options, but I
> can add them in if you think it is important for initial support.
No, not important, we can add that later if it ever becomes useful.
...
> > In general, you always ACK all interrupts first. Then you handle
> > the bits you have harvested.
> >
>
> The documentation says to ACK the interrupt after handling in the RX
> case:
>
> <<<
> S/W needs to clear this status bit to allow next data receiving.
> > > >
>
> I will double check with Ryan to make sure TX works the same way.
>
> > > + if (irq_status & ASPEED_I2CD_INTR_ERROR ||
> > > + (!bus->msgs && bus->master_state !=
> > > ASPEED_I2C_MASTER_STOP)) {
>
> ...
> >
> > I would set master_state to "RECOVERY" (new state ?) and ensure
> > those things are caught if they happen outside of a recovery.
I replied privately ... as long as we ack before we start a new command
we should be ok but we shouldn't ack after.
Your latest patch still does that. It will do things like start a STOP
command *then* ack the status bits. I'm pretty sure that's bogus.
That way it's a lot simpler to simply move the
writel(irq_status, bus->base + ASPEED_I2C_INTR_STS_REG);
To either right after the readl of the status reg at the beginning of
aspeed_i2c_master_irq().
I would be very surprised if that didn't work properly and wasn't much
safer than what you are currently doing.
> Let me know if you still think we need a "RECOVERY" state.
The way you just switch to stop state and store the error for later
should work I think.
> >
> > > + if (bus->master_state == ASPEED_I2C_MASTER_START) {
>
> ...
> >
> > > + dev_dbg(bus->dev,
> > > + "no slave present at %02x", msg-
> > > >addr);
> > > + status_ack |= ASPEED_I2CD_INTR_TX_NAK;
> > > + bus->cmd_err = -EIO;
> > > + do_stop(bus);
> > > + goto out_no_complete;
> > > + } else {
> > > + status_ack |= ASPEED_I2CD_INTR_TX_ACK;
> > > + if (msg->flags & I2C_M_RD)
> > > + bus->master_state =
> > > ASPEED_I2C_MASTER_RX;
> > > + else
> > > + bus->master_state =
> > > ASPEED_I2C_MASTER_TX_FIRST;
> >
> > What about the SMBUS_QUICK case ? (0-len transfer). Do we need
> > to handle this here ? A quick look at the TX_FIRST case makes
> > me think we are ok there but I'm not sure about the RX case.
>
> I did not think that there is an SMBUS_QUICK RX. Could you point me
> to an example?
Not so much an RX, it's more like you are sending a 1-bit data in
the place of the Rd/Wr bit. So you have a read with a lenght of 0,
I don't think in that case you should set ASPEED_I2CD_M_RX_CMD in
__aspeed_i2c_do_start
> > I'm not sure the RX case is tight also. What completion does the
> > HW give you for the address cycle ? Won't you get that before it
> > has received the first character ? IE. You fall through to
> > the read case of the state machine with the read potentially
> > not complete yet no ?
>
> ...
> > > + case ASPEED_I2C_MASTER_RX:
> > > + if (!(irq_status & ASPEED_I2CD_INTR_RX_DONE)) {
> > > + dev_err(bus->dev, "master failed to RX");
> > > + goto out_complete;
> > > + }
> >
> > See my comment above for a bog standard i2c_read. Aren't you
> > getting
> > the completion for the address before the read is even started ?
>
> In practice no, but it is probably best to be safe :-)
Yup :)
> >
> > > + status_ack |= ASPEED_I2CD_INTR_RX_DONE;
> > > +
> > > + recv_byte = aspeed_i2c_read(bus,
> > > ASPEED_I2C_BYTE_BUF_REG) >> 8;
> > > + msg->buf[bus->buf_index++] = recv_byte;
> > > +
> > > + if (msg->flags & I2C_M_RECV_LEN &&
> > > + recv_byte <= I2C_SMBUS_BLOCK_MAX) {
> > > + msg->len = recv_byte +
> > > + ((msg->flags &
> > > I2C_CLIENT_PEC) ? 2 : 1);
>
> ...
> > > + return ((clk_high << ASPEED_I2CD_TIME_SCL_HIGH_SHIFT)
> > > + & ASPEED_I2CD_TIME_SCL_HIGH_MASK)
> > > + | ((clk_low <<
> > > ASPEED_I2CD_TIME_SCL_LOW_SHIFT)
> > > + & ASPEED_I2CD_TIME_SCL_LOW_MASK)
> > > + | (base_clk &
> > > ASPEED_I2CD_TIME_BASE_DIVISOR_MASK);
> > > +}
> >
> > As I think I mentioned earlier, the AST2500 has a slightly
> > different
> > register layout which support larger values for high and low, thus
> > allowing a finer granularity.
>
> I am developing against the 2500.
Yes but we'd like the driver to work with both :-)
> > BTW. In case you haven't, I would suggest you copy/paste the above
> > in
> > a userspace app and run it for all frequency divisors and see if
> > your
> > results match the aspeed table :)
>
> Good call.
If you end up doing that, can you shoot it my way ? I can take care
of making sure it's all good for the 2400.
> > > +static int aspeed_i2c_init_clk(struct aspeed_i2c_bus *bus,
> > > + struct platform_device *pdev)
> > > +{
> > > + u32 clk_freq, divisor;
> > > + struct clk *pclk;
> > > + int ret;
> > > +
> > > + pclk = devm_clk_get(&pdev->dev, NULL);
> > > + if (IS_ERR(pclk)) {
> > > + dev_err(&pdev->dev, "clk_get failed\n");
> > > + return PTR_ERR(pclk);
> > > + }
> > > + ret = of_property_read_u32(pdev->dev.of_node,
> > > + "clock-frequency", &clk_freq);
> >
> > See my previous comment about calling that 'bus-frequency' rather
> > than 'clock-frequency'.
> >
> > > + if (ret < 0) {
> > > + dev_err(&pdev->dev,
> > > + "Could not read clock-frequency
> > > property\n");
> > > + clk_freq = 100000;
> > > + }
> > > + divisor = clk_get_rate(pclk) / clk_freq;
> > > + /* We just need the clock rate, we don't actually use the
> > > clk object. */
> > > + devm_clk_put(&pdev->dev, pclk);
> > > +
> > > + /* Set AC Timing */
> > > + if (clk_freq / 1000 > 1000) {
> > > + aspeed_i2c_write(bus, aspeed_i2c_read(bus,
> > > + ASPEED_I2C_FU
> > > N_CTRL_REG) |
> > > + ASPEED_I2CD_M_HIGH_SPEED_EN |
> > > + ASPEED_I2CD_M_SDA_DRIVE_1T_EN |
> > > + ASPEED_I2CD_SDA_DRIVE_1T_EN,
> > > + ASPEED_I2C_FUN_CTRL_REG);
> > > +
> > > + aspeed_i2c_write(bus, 0x3,
> > > ASPEED_I2C_AC_TIMING_REG2);
> > > + aspeed_i2c_write(bus,
> > > aspeed_i2c_get_clk_reg_val(divisor),
> > > + ASPEED_I2C_AC_TIMING_REG1);
> >
> > I already discussed by doubts about the above. I can try to scope
> > it with the EVB if you don't get to it. For now I'd rather take the
> > code out.
> >
> > We should ask aspeed from what frequency the "1T" stuff is useful.
>
> Will do, I will try to rope Ryan in on the next review; it will be
> good for him to get used to working with upstream anyway.
Yup. However, for the sake of getting something upstream (and in
OpenBMC 4.10 kernel) asap, I would suggest just dropping support
for those fast speeds for now, we can add them back later.
> >
> > > + } else {
> > > + aspeed_i2c_write(bus,
> > > aspeed_i2c_get_clk_reg_val(divisor),
> > > + ASPEED_I2C_AC_TIMING_REG1);
> > > + aspeed_i2c_write(bus, ASPEED_NO_TIMEOUT_CTRL,
> > > + ASPEED_I2C_AC_TIMING_REG2);
> > > + }
>
> ...
> > > + spin_lock_init(&bus->lock);
> > > + init_completion(&bus->cmd_complete);
> > > + bus->adap.owner = THIS_MODULE;
> > > + bus->adap.retries = 0;
> > > + bus->adap.timeout = 5 * HZ;
> > > + bus->adap.algo = &aspeed_i2c_algo;
> > > + bus->adap.algo_data = bus;
> > > + bus->adap.dev.parent = &pdev->dev;
> > > + bus->adap.dev.of_node = pdev->dev.of_node;
> > > + snprintf(bus->adap.name, sizeof(bus->adap.name), "Aspeed
> > > i2c");
> >
> > Another trivial one, should we put some kind of bus number
> > in that string ?
>
> Whoops, looks like I missed this one; I will get to it in the next
> revision.
Ok. I noticed you missed that in v7, so I assume you mean v8 :-)
> >
> > > + bus->dev = &pdev->dev;
> > > +
> > > + /* reset device: disable master & slave functions */
> > > + aspeed_i2c_write(bus, 0, ASPEED_I2C_FUN_CTRL_REG);
>
> ...
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree"
> in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v4 07/10] mfd: axp20x: add axp20x-regulator cell for AXP803
From: Chen-Yu Tsai @ 2017-04-25 2:17 UTC (permalink / raw)
To: Icenowy Zheng
Cc: Thomas Gleixner, Rob Herring, Maxime Ripard, Chen-Yu Tsai,
Lee Jones, Liam Girdwood, linux-kernel, devicetree,
linux-arm-kernel, linux-sunxi
In-Reply-To: <20170424160103.9447-8-icenowy-h8G6r0blFSE@public.gmane.org>
On Tue, Apr 25, 2017 at 12:01 AM, Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org> wrote:
> As axp20x-regulator now supports AXP803, add a cell for it.
>
> Signed-off-by: Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
> Acked-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
> ---
> Changes in v4:
> - Added a trailing comma for new cell, for easier further cell addition.
> Changes in v3:
> - Make the new cell one-liner.
>
> drivers/mfd/axp20x.c | 3 ++-
> drivers/regulator/axp20x-regulator.c | 6 +++---
Squashed in wrong patch?
ChenYu
^ permalink raw reply
* Re: Re: [PATCH 1/2] PCI: mediatek: Add Mediatek PCIe host controller support
From: Ryder Lee @ 2017-04-25 2:14 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Arnd Bergmann,
linux-pci-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Rob Herring,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Bjorn Helgaas,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20170424220218.GA18659-1RhO1Y9PlrlHTL0Zs8A6p5iNqAH0jzoTYJqu5kTmcBRl57MIdRCFDg@public.gmane.org>
Hi,
On Mon, 2017-04-24 at 17:02 -0500, Bjorn Helgaas wrote:
> Hi Ryder,
>
> Looks good, but I have a few questions below.
>
> On Sun, Apr 23, 2017 at 04:19:02PM +0800, Ryder Lee wrote:
> > Add support for the Mediatek PCIe controller which can be found
> > on MT7623A/N, MT2701 and MT8521p platforms.
> >
> > Signed-off-by: Ryder Lee <ryder.lee-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> > ---
> > drivers/pci/host/Kconfig | 11 +
> > drivers/pci/host/Makefile | 1 +
> > drivers/pci/host/pcie-mediatek.c | 611 +++++++++++++++++++++++++++++++++++++++
> > 3 files changed, 623 insertions(+)
> > create mode 100644 drivers/pci/host/pcie-mediatek.c
> >
> > diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
> > index f7c1d4d..cf13b5d 100644
> > --- a/drivers/pci/host/Kconfig
> > +++ b/drivers/pci/host/Kconfig
> > @@ -174,6 +174,17 @@ config PCIE_ROCKCHIP
> > There is 1 internal PCIe port available to support GEN2 with
> > 4 slots.
> >
> > +config PCIE_MEDIATEK
> > + bool "Mediatek PCIe Controller for MT7623 SoCs families"
> > + depends on (ARM && ARCH_MEDIATEK) || COMPILE_TEST
> > + depends on OF
> > + depends on PCI
> > + select PCIEPORTBUS
> > + help
> > + Say Y here if you want to enable PCIe controller support on MT7623 A/N
> > + series SoCs. There is a one root complex with 3 root ports available.
> > + Each port supports Gen2 lane x1.
> > +
> > config VMD
> > depends on PCI_MSI && X86_64 && SRCU
> > tristate "Intel Volume Management Device Driver"
> > diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
> > index 4d36866..265adff 100644
> > --- a/drivers/pci/host/Makefile
> > +++ b/drivers/pci/host/Makefile
> > @@ -17,6 +17,7 @@ obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o
> > obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o
> > obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o
> > obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o
> > +obj-$(CONFIG_PCIE_MEDIATEK) += pcie-mediatek.o
> > obj-$(CONFIG_VMD) += vmd.o
> >
> > # The following drivers are for devices that use the generic ACPI
> > diff --git a/drivers/pci/host/pcie-mediatek.c b/drivers/pci/host/pcie-mediatek.c
> > new file mode 100644
> > index 0000000..98e84d9
> > --- /dev/null
> > +++ b/drivers/pci/host/pcie-mediatek.c
> > @@ -0,0 +1,611 @@
> > +/*
> > + * PCIe host controller driver for Mediatek MT7623 SoCs families
> > + *
> > + * Copyright (c) 2017 MediaTek Inc.
> > + * Author: Ryder Lee <ryder.lee-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> > + *
> > + * 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.
> > + *
> > + * This program 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.
> > + */
> > +
> > +#include <linux/clk.h>
> > +#include <linux/delay.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/of_address.h>
> > +#include <linux/of_pci.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/pci.h>
> > +#include <linux/phy/phy.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/pm_runtime.h>
> > +#include <linux/reset.h>
> > +
> > +/* PCIe shared registers */
> > +#define PCIE_SYS_CFG 0x00
> > +#define PCIE_INT_ENABLE 0x0c
> > +#define PCIE_CFG_ADDR 0x20
> > +#define PCIE_CFG_DATA 0x24
> > +
> > +/* PCIe per port registers */
> > +#define PCIE_BAR0_SETUP 0x10
> > +#define PCIE_BAR1_SETUP 0x14
> > +#define PCIE_BAR0_MEM_BASE 0x18
> > +#define PCIE_CLASS 0x34
> > +#define PCIE_LINK_STATUS 0x50
> > +
> > +#define PCIE_PORT_INT_EN(x) BIT(20 + (x))
> > +#define PCIE_PORT_PERST(x) BIT(1 + (x))
> > +#define PCIE_PORT_LINKUP BIT(0)
> > +#define PCIE_BAR_MAP_MAX GENMASK(31, 16)
> > +
> > +#define PCIE_BAR_ENABLE BIT(0)
> > +#define PCIE_REVISION_ID BIT(0)
> > +#define PCIE_CLASS_CODE (0x60400 << 8)
> > +#define PCIE_CONF_REG(regn) (((regn) & GENMASK(7, 2)) | \
> > + ((((regn) >> 8) & GENMASK(3, 0)) << 24))
> > +#define PCIE_CONF_FUN(fun) (((fun) << 8) & GENMASK(10, 8))
> > +#define PCIE_CONF_DEV(dev) (((dev) << 11) & GENMASK(15, 11))
> > +#define PCIE_CONF_BUS(bus) (((bus) << 16) & GENMASK(23, 16))
> > +#define PCIE_CONF_ADDR(regn, fun, dev, bus) \
> > + (PCIE_CONF_REG(regn) | PCIE_CONF_FUN(fun) | \
> > + PCIE_CONF_DEV(dev) | PCIE_CONF_BUS(bus))
> > +
> > +/* Mediatek specific configuration registers */
> > +#define PCIE_FTS_NUM 0x70c
> > +#define PCIE_FTS_NUM_MASK GENMASK(15, 8)
> > +#define PCIE_FTS_NUM_L0(x) ((x) & 0xff << 8)
> > +
> > +#define PCIE_FC_CREDIT 0x73c
> > +#define PCIE_FC_CREDIT_MASK (GENMASK(31, 31) | GENMASK(28, 16))
> > +#define PCIE_FC_CREDIT_VAL(x) ((x) << 16)
> > +
> > +/**
> > + * struct mtk_pcie_port - PCIe port information
> > + * @dev: pointer to root port device
> > + * @base: IO mapped register base
> > + * @list: port list
> > + * @pcie: pointer to PCIe host info
> > + * @reset: pointer to RC reset control
> > + * @regs: port memory region
> > + * @sys_ck: root port clock
> > + * @phy: pointer to phy control block
> > + * @irq: IRQ number
> > + * @lane: lane count
> > + * @index: port index
> > + */
> > +struct mtk_pcie_port {
> > + struct device *dev;
> > + void __iomem *base;
> > + struct list_head list;
> > + struct mtk_pcie *pcie;
> > + struct reset_control *reset;
> > + struct resource regs;
> > + struct clk *sys_ck;
> > + struct phy *phy;
> > + int irq;
> > + u32 lane;
> > + u32 index;
> > +};
> > +
> > +/**
> > + * struct mtk_pcie - PCIe host information
> > + * @dev: pointer to PCIe device
> > + * @base: IO mapped register Base
> > + * @free_ck: free-run reference clock
> > + * @resources: bus resources
> > + * @ports: pointer to PCIe port information
> > + */
> > +struct mtk_pcie {
> > + struct device *dev;
> > + void __iomem *base;
> > + struct clk *free_ck;
> > + struct list_head resources;
> > + struct list_head ports;
> > +};
> > +
> > +static inline bool mtk_pcie_link_is_up(struct mtk_pcie_port *port)
> > +{
> > + return !!(readl_relaxed(port->base + PCIE_LINK_STATUS) &
> > + PCIE_PORT_LINKUP);
> > +}
> > +
> > +static bool mtk_pcie_valid_device(struct mtk_pcie *pcie,
> > + struct pci_bus *bus, int devfn)
> > +{
> > + struct mtk_pcie_port *port;
> > + struct pci_dev *dev;
> > + struct pci_bus *pbus;
> > +
> > + /* if there is no link, then there is no device */
> > + list_for_each_entry(port, &pcie->ports, list) {
> > + if (bus->number == 0 && port->index == PCI_SLOT(devfn) &&
> > + mtk_pcie_link_is_up(port)) {
> > + return true;
> > + } else if (bus->number != 0) {
> > + pbus = bus;
> > + do {
> > + dev = pbus->self;
> > + if (port->index == PCI_SLOT(dev->devfn) &&
> > + mtk_pcie_link_is_up(port)) {
> > + return true;
> > + }
> > + pbus = dev->bus;
> > + } while (dev->bus->number != 0);
> > + }
> > + }
> > +
> > + return false;
> > +}
> > +
> > +static void mtk_pcie_port_free(struct mtk_pcie_port *port)
> > +{
> > + struct mtk_pcie *pcie = port->pcie;
> > + struct device *dev = pcie->dev;
> > +
> > + devm_iounmap(dev, port->base);
> > + devm_release_mem_region(dev, port->regs.start,
> > + resource_size(&port->regs));
> > + list_del(&port->list);
> > + devm_kfree(dev, port);
> > +}
> > +
> > +static int mtk_pcie_hw_rd_cfg(struct mtk_pcie *pcie, u32 bus, u32 devfn,
> > + int where, int size, u32 *val)
> > +{
> > + writel(PCIE_CONF_ADDR(where, PCI_FUNC(devfn), PCI_SLOT(devfn), bus),
> > + pcie->base + PCIE_CFG_ADDR);
> > +
> > + *val = 0;
> > +
> > + switch (size) {
> > + case 1:
> > + *val = readb(pcie->base + PCIE_CFG_DATA + (where & 3));
> > + break;
> > + case 2:
> > + *val = readw(pcie->base + PCIE_CFG_DATA + (where & 2));
> > + break;
> > + case 4:
> > + *val = readl(pcie->base + PCIE_CFG_DATA);
> > + break;
> > + }
> > +
> > + return PCIBIOS_SUCCESSFUL;
> > +}
> > +
> > +static int mtk_pcie_hw_wr_cfg(struct mtk_pcie *pcie, u32 bus, u32 devfn,
> > + int where, int size, u32 val)
> > +
> > +{
> > + writel(PCIE_CONF_ADDR(where, PCI_FUNC(devfn), PCI_SLOT(devfn), bus),
> > + pcie->base + PCIE_CFG_ADDR);
> > +
> > + switch (size) {
> > + case 1:
> > + writeb(val, pcie->base + PCIE_CFG_DATA + (where & 3));
> > + break;
> > + case 2:
> > + writew(val, pcie->base + PCIE_CFG_DATA + (where & 2));
> > + break;
> > + case 4:
> > + writel(val, pcie->base + PCIE_CFG_DATA);
> > + break;
> > + }
> > +
> > + return PCIBIOS_SUCCESSFUL;
> > +}
> > +
> > +static int mtk_pcie_read_config(struct pci_bus *bus, u32 devfn,
> > + int where, int size, u32 *val)
> > +{
> > + struct mtk_pcie *pcie = bus->sysdata;
> > + u32 bn = bus->number;
> > +
> > + if (!mtk_pcie_valid_device(pcie, bus, devfn)) {
> > + *val = 0xffffffff;
> > + return PCIBIOS_DEVICE_NOT_FOUND;
> > + }
>
> I know there are some other drivers with the *_valid_device() pattern
> in their config accessors, but I don't like it because it's racy.
> It's possible for the link to be up for the test above, then go down
> before the actual config access below.
>
> Your hardware *should* do something sensible if we try to read config
> space when the link is down, and ideally that would be enough that we
> don't need this "valid_device()" check.
>
Yup,it's unnecessary, will remove it.
> > + return mtk_pcie_hw_rd_cfg(pcie, bn, devfn, where, size, val);
> > +}
> > +
> > +static int mtk_pcie_write_config(struct pci_bus *bus, u32 devfn,
> > + int where, int size, u32 val)
> > +{
> > + struct mtk_pcie *pcie = bus->sysdata;
> > + u32 bn = bus->number;
> > +
> > + if (!mtk_pcie_valid_device(pcie, bus, devfn))
> > + return PCIBIOS_DEVICE_NOT_FOUND;
> > +
> > + return mtk_pcie_hw_wr_cfg(pcie, bn, devfn, where, size, val);
> > +}
> > +
> > +static struct pci_ops mtk_pcie_ops = {
> > + .read = mtk_pcie_read_config,
> > + .write = mtk_pcie_write_config,
> > +};
> > +
> > +static void mtk_pcie_configure_rc(struct mtk_pcie_port *port)
> > +{
> > + struct mtk_pcie *pcie = port->pcie;
> > + u32 val;
> > +
> > + /* enable interrupt */
> > + val = readl(pcie->base + PCIE_INT_ENABLE);
> > + val |= PCIE_PORT_INT_EN(port->index);
> > + writel(val, pcie->base + PCIE_INT_ENABLE);
> > +
> > + /* map to all DDR region. We need to set it before cfg operation. */
> > + writel(PCIE_BAR_MAP_MAX | PCIE_BAR_ENABLE,
> > + port->base + PCIE_BAR0_SETUP);
> > +
> > + /* configure class Code and revision ID */
> > + writel(PCIE_CLASS_CODE | PCIE_REVISION_ID,
> > + port->base + PCIE_CLASS);
> > +
> > + /* configure FC credit */
> > + mtk_pcie_hw_rd_cfg(pcie, 0, (port->index << 3),
> > + PCIE_FC_CREDIT, 4, &val);
> > + val &= ~PCIE_FC_CREDIT_MASK;
> > + val |= PCIE_FC_CREDIT_VAL(0x806c);
> > + mtk_pcie_hw_wr_cfg(pcie, 0, (port->index << 3),
> > + PCIE_FC_CREDIT, 4, val);
> > +
> > + /* configure RC FTS number to 250 when it leaves L0s */
> > + mtk_pcie_hw_rd_cfg(pcie, 0, (port->index << 3),
> > + PCIE_FTS_NUM, 4, &val);
> > + val &= ~PCIE_FTS_NUM_MASK;
> > + val |= PCIE_FTS_NUM_L0(0x50);
> > + mtk_pcie_hw_wr_cfg(pcie, 0, (port->index << 3),
> > + PCIE_FTS_NUM, 4, val);
> > +}
> > +
> > +static void mtk_pcie_assert_ports(struct mtk_pcie_port *port)
> > +{
> > + struct mtk_pcie *pcie = port->pcie;
> > + u32 val;
> > +
> > + /* assert port PERST_N */
> > + val = readl(pcie->base + PCIE_SYS_CFG);
> > + val |= PCIE_PORT_PERST(port->index);
> > + writel(val, pcie->base + PCIE_SYS_CFG);
> > +
> > + /* de-assert port PERST_N */
> > + val = readl(pcie->base + PCIE_SYS_CFG);
> > + val &= ~PCIE_PORT_PERST(port->index);
> > + writel(val, pcie->base + PCIE_SYS_CFG);
> > +
> > + /*
> > + * at least 100ms delay because PCIe v2.0 need more time to
> > + * train from Gen1 to Gen2
> > + */
> > + msleep(100);
> > +}
> > +
> > +static int mtk_pcie_enable_ports(struct mtk_pcie *pcie)
> > +{
> > + struct device *dev = pcie->dev;
> > + struct mtk_pcie_port *port, *tmp;
> > + int err, linkup = 0;
> > +
> > + list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
> > + err = clk_prepare_enable(port->sys_ck);
> > + if (err) {
> > + dev_err(dev, "failed to enable port%d clock\n",
> > + port->index);
> > + continue;
> > + }
> > +
> > + /* assert RC */
> > + reset_control_assert(port->reset);
> > + /* de-assert RC */
> > + reset_control_deassert(port->reset);
> > +
> > + /* power on PHY */
> > + err = phy_power_on(port->phy);
> > + if (err) {
> > + dev_err(dev, "failed to power on port%d phy\n",
> > + port->index);
> > + goto err_phy_on;
> > + }
> > +
> > + mtk_pcie_assert_ports(port);
> > +
> > + /* if link up, then setup root port configuration space */
> > + if (mtk_pcie_link_is_up(port)) {
> > + mtk_pcie_configure_rc(port);
> > + linkup++;
> > + continue;
> > + }
> > +
> > + dev_info(dev, "Port%d link down\n", port->index);
> > +
> > + phy_power_off(port->phy);
> > +err_phy_on:
> > + clk_disable_unprepare(port->sys_ck);
> > + mtk_pcie_port_free(port);
> > + }
> > +
> > + return linkup;
> > +}
> > +
> > +static int mtk_pcie_get_port_resource(struct mtk_pcie_port *port,
> > + struct device_node *node)
> > +{
> > + struct device *dev = port->pcie->dev;
> > + struct platform_device *pdev = to_platform_device(dev);
> > + struct platform_device *plat_dev;
> > + char name[10];
> > + int err;
> > +
> > + err = of_address_to_resource(node, 0, &port->regs);
> > + if (err) {
> > + dev_err(dev, "failed to parse address: %d\n", err);
> > + return err;
> > + }
> > +
> > + port->base = devm_ioremap_resource(dev, &port->regs);
> > + if (IS_ERR(port->base)) {
> > + dev_err(dev, "failed to map port%d base\n", port->index);
> > + return PTR_ERR(port->base);
> > + }
> > +
> > + plat_dev = of_find_device_by_node(node);
> > + if (!plat_dev) {
> > + plat_dev = of_platform_device_create(
> > + node, NULL,
> > + platform_bus_type.dev_root);
> > + if (!plat_dev)
> > + return -EPROBE_DEFER;
> > + }
> > +
> > + port->dev = &plat_dev->dev;
> > +
> > + port->irq = platform_get_irq(pdev, port->index);
> > + if (!port->irq) {
> > + dev_err(dev, "failed to get irq\n");
> > + return -ENODEV;
> > + }
> > +
> > + port->sys_ck = devm_clk_get(port->dev, "sys_ck");
> > + if (IS_ERR(port->sys_ck)) {
> > + dev_err(port->dev, "failed to get port%d clock\n", port->index);
> > + return PTR_ERR(port->sys_ck);
> > + }
> > +
> > + port->reset = devm_reset_control_get(port->dev, "pcie-reset");
> > + if (IS_ERR(port->reset)) {
> > + dev_err(port->dev, "failed to get port%d reset control\n",
> > + port->index);
> > + return PTR_ERR(port->reset);
> > + }
> > +
> > + snprintf(name, sizeof(name), "pcie-phy%d", port->index);
> > + port->phy = devm_of_phy_get(port->dev, node, name);
> > + if (IS_ERR(port->phy)) {
> > + dev_err(port->dev, "failed to get port%d phy\n", port->index);
> > + return PTR_ERR(port->phy);
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int mtk_pcie_parse_and_add_res(struct mtk_pcie *pcie)
> > +{
> > + struct device *dev = pcie->dev;
> > + struct platform_device *pdev = to_platform_device(dev);
> > + struct device_node *node = dev->of_node, *child;
> > + struct resource_entry *win, *tmp;
> > + struct resource *regs;
> > + resource_size_t iobase;
> > + int err;
> > +
> > + /* parse shared resources */
> > + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > + pcie->base = devm_ioremap_resource(dev, regs);
> > + if (IS_ERR(pcie->base)) {
> > + dev_err(dev, "failed to get PCIe base\n");
> > + return PTR_ERR(pcie->base);
> > + }
> > +
> > + pcie->free_ck = devm_clk_get(dev, "free_ck");
> > + if (IS_ERR(pcie->free_ck)) {
> > + dev_err(dev, "failed to get free_ck\n");
> > + return PTR_ERR(pcie->free_ck);
> > + }
> > +
> > + err = of_pci_get_host_bridge_resources(node, 0, 0xff, &pcie->resources,
> > + &iobase);
> > + if (err)
> > + return err;
> > +
> > + err = devm_request_pci_bus_resources(dev, &pcie->resources);
> > + if (err)
> > + return err;
> > +
> > + resource_list_for_each_entry_safe(win, tmp, &pcie->resources) {
> > + struct resource *res = win->res;
> > +
> > + switch (resource_type(res)) {
> > + case IORESOURCE_IO:
> > + err = pci_remap_iospace(res, iobase);
> > + if (err) {
> > + dev_warn(dev, "failed to map resource %pR\n",
> > + res);
> > + resource_list_destroy_entry(win);
> > + }
> > + break;
> > + }
> > + }
> > +
> > + /* parse port resources */
> > + for_each_child_of_node(node, child) {
> > + struct mtk_pcie_port *port;
> > + int index;
> > +
> > + err = of_pci_get_devfn(child);
> > + if (err < 0) {
> > + dev_err(pcie->dev, "failed to parse devfn: %d\n", err);
>
> dev_err(dev, ...)
OK.
> > + return err;
> > + }
> > +
> > + index = PCI_SLOT(err);
> > + if (index < 1) {
> > + dev_err(dev, "invalid port number: %d\n", index);
> > + return -EINVAL;
> > + }
> > +
> > + index--;
> > +
> > + if (!of_device_is_available(child))
> > + continue;
> > +
> > + port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
> > + if (!port)
> > + return -ENOMEM;
> > +
> > + err = of_property_read_u32(child, "num-lanes", &port->lane);
> > + if (err) {
> > + dev_err(dev, "missing num-lanes property\n");
> > + return err;
> > + }
> > +
> > + port->index = index;
> > + port->pcie = pcie;
> > +
> > + err = mtk_pcie_get_port_resource(port, child);
> > + if (err)
> > + return err;
> > +
> > + INIT_LIST_HEAD(&port->list);
> > + list_add_tail(&port->list, &pcie->ports);
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +/*
> > + * This IP lacks interrupt status register to check or map INTx from
> > + * different devices at the same time.
> > + */
> > +static int __init mtk_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
> > +{
> > + struct mtk_pcie *pcie = dev->bus->sysdata;
> > + struct mtk_pcie_port *port;
> > +
> > + list_for_each_entry(port, &pcie->ports, list)
> > + if (port->index == slot)
> > + return port->irq;
> > +
> > + return -1;
> > +}
> > +
> > +static int mtk_pcie_register_ports(struct mtk_pcie *pcie)
> > +{
> > + struct pci_bus *bus, *child;
> > +
> > + bus = pci_scan_root_bus(pcie->dev, 0, &mtk_pcie_ops, pcie,
> > + &pcie->resources);
> > + if (!bus) {
> > + dev_err(pcie->dev, "failed to create root bus\n");
> > + return -ENOMEM;
> > + }
> > +
> > + if (!pci_has_flag(PCI_PROBE_ONLY)) {
> > + pci_fixup_irqs(pci_common_swizzle, mtk_pcie_map_irq);
> > + pci_bus_size_bridges(bus);
> > + pci_bus_assign_resources(bus);
> > +
> > + list_for_each_entry(child, &bus->children, node)
> > + pcie_bus_configure_settings(child);
>
> Do you actually need the functionality of PCI_PROBE_ONLY? We're
> trying to get rid of this, so if you don't need it, please omit it.
>
> If you *do* need it, can you include a note about why?
>
> If you do need it, I don't think PCI_PROBE_ONLY should control
> pci_fixup_irqs() or pcie_bus_configure_settings(). I know there is
> some other similar code that does this, but I think PCI_PROBE_ONLY
> should only influence resource assignment, i.e., BARs and bridge
> windows. I don't want it to influence IRQs or the MPS/MRRS settings
> done by pcie_bus_configure_settings() if we can avoid it.
I will remove it, thanks.
> > + }
> > +
> > + pci_bus_add_devices(bus);
> > +
> > + return 0;
> > +}
> > +
> > +static int mtk_pcie_probe(struct platform_device *pdev)
> > +{
> > + struct mtk_pcie *pcie;
> > + int err;
> > +
> > + pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
> > + if (!pcie)
> > + return -ENOMEM;
> > +
> > + pcie->dev = &pdev->dev;
> > + platform_set_drvdata(pdev, pcie);
> > +
> > + /*
> > + * parse PCI ranges, configuration bus range and
> > + * request their resources
> > + */
> > + INIT_LIST_HEAD(&pcie->ports);
> > + INIT_LIST_HEAD(&pcie->resources);
> > +
> > + err = mtk_pcie_parse_and_add_res(pcie);
> > + if (err)
> > + goto err_parse;
> > +
> > + pm_runtime_enable(pcie->dev);
> > + err = pm_runtime_get_sync(pcie->dev);
> > + if (err)
> > + goto err_pm;
> > +
> > + err = clk_prepare_enable(pcie->free_ck);
> > + if (err) {
> > + dev_err(pcie->dev, "failed to enable free_ck\n");
> > + goto err_free_ck;
> > + }
> > +
> > + /* power on PCIe ports */
> > + err = mtk_pcie_enable_ports(pcie);
> > + if (!err)
> > + goto err_enable;
> > +
> > + /* register PCIe ports */
> > + err = mtk_pcie_register_ports(pcie);
> > + if (err)
> > + goto err_enable;
> > +
> > + return 0;
> > +
> > +err_enable:
> > + clk_disable_unprepare(pcie->free_ck);
> > +err_free_ck:
> > + pm_runtime_put_sync(pcie->dev);
> > +err_pm:
> > + pm_runtime_disable(pcie->dev);
> > +err_parse:
> > + pci_free_resource_list(&pcie->resources);
> > +
> > + return err;
> > +}
> > +
> > +static const struct of_device_id mtk_pcie_ids[] = {
> > + { .compatible = "mediatek,mt7623-pcie"},
> > + { .compatible = "mediatek,mt2701-pcie"},
> > + {},
> > +};
> > +MODULE_DEVICE_TABLE(of, mtk_pcie_ids);
> > +
> > +static struct platform_driver mtk_pcie_driver = {
> > + .probe = mtk_pcie_probe,
> > + .driver = {
> > + .name = "mtk-pcie",
> > + .of_match_table = mtk_pcie_ids,
>
> Per [1], I think you should have ".suppress_bind_attrs = true," here.
> Without it, apparently you can easily crash the system by unbinding
> the driver, as in [2].
>
> [1] https://git.kernel.org/cgit/linux/kernel/git/helgaas/pci.git/commit/?id=65e0527b933a
> [2] https://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git/commit/?id=073d3dbe9a7c
OK!
> > + },
> > +};
> > +
> > +builtin_platform_driver(mtk_pcie_driver);
> > +
> > +MODULE_DESCRIPTION("Mediatek PCIe host driver for MT7623 SoCs families");
> > +MODULE_LICENSE("GPL v2");
> > --
> > 1.9.1
> >
Thanks for your review!
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCHv2 3/3] ARM: socfpga: drm driver updates in socfpga_defconfig
From: hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w @ 2017-04-25 2:06 UTC (permalink / raw)
To: daniel.vetter-ral2JQCrhuEAvxtiuMwx3w,
dinguyen-DgEjT+Ai2ygdnm+yROfE0A, robh+dt-DgEjT+Ai2ygdnm+yROfE0A
Cc: tien.hock.loh-ral2JQCrhuEAvxtiuMwx3w,
hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w,
devicetree-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
Ong-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1493086006-4392-1-git-send-email-hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
From: "Ong, Hean Loong" <hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Intel FPGA Video and Image Processing Suite Frame Buffer II
driver config for Arria 10 devkit and its variants
Signed-off-by: Ong, Hean Loong <hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
v2:
* Added drm frame bufferr II module support for Arria10
---
arch/arm/configs/socfpga_defconfig | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm/configs/socfpga_defconfig b/arch/arm/configs/socfpga_defconfig
index 030264c..49ae269 100644
--- a/arch/arm/configs/socfpga_defconfig
+++ b/arch/arm/configs/socfpga_defconfig
@@ -110,6 +110,10 @@ CONFIG_MFD_ALTERA_A10SR=y
CONFIG_MFD_STMPE=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_DRM=m
+CONFIG_DRM_IVIP=m
+CONFIG_DRM_IVIP_OF=m
+CONFIG_FB=y
CONFIG_USB=y
CONFIG_USB_STORAGE=y
CONFIG_USB_DWC2=y
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCHv2 2/3] ARM: drm: Intel FPGA VIP Frame Buffer II drm driver
From: hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w @ 2017-04-25 2:06 UTC (permalink / raw)
To: daniel.vetter-ral2JQCrhuEAvxtiuMwx3w,
dinguyen-DgEjT+Ai2ygdnm+yROfE0A, robh+dt-DgEjT+Ai2ygdnm+yROfE0A
Cc: tien.hock.loh-ral2JQCrhuEAvxtiuMwx3w,
hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w,
devicetree-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
Ong-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1493086006-4392-1-git-send-email-hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
From: "Ong, Hean Loong" <hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Driver for Intel FPGA Video and Image Processing
Suite Frame Buffer II. The driver only supports the Intel
Arria10 devkit and its variants. This driver can be either
loaded staticlly or in modules. The OF device tree binding
is located at:
Documentation/devicetree/bindings/display/altr,vip-fb2.txt
Signed-off-by: Ong, Hean Loong <hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
v2:
* Simplify the driver by using drm_simple_display_pipe_init.
* Cleaned up some unused codes with no-ops
* Clean up Kconfig to use only DRM_IVIP
* Use DRM_GEM_CMA_FOPS for file operations
* Removed the use of fb_info to populate DT information
---
drivers/gpu/drm/Kconfig | 2 +
drivers/gpu/drm/Makefile | 1 +
drivers/gpu/drm/ivip/Kconfig | 13 +++
drivers/gpu/drm/ivip/Makefile | 9 ++
drivers/gpu/drm/ivip/intel_vip_conn.c | 96 +++++++++++++++++
drivers/gpu/drm/ivip/intel_vip_core.c | 171 +++++++++++++++++++++++++++++
drivers/gpu/drm/ivip/intel_vip_drv.h | 55 ++++++++++
drivers/gpu/drm/ivip/intel_vip_of.c | 195 ++++++++++++++++++++++++++++++++++
8 files changed, 542 insertions(+)
create mode 100644 drivers/gpu/drm/ivip/Kconfig
create mode 100644 drivers/gpu/drm/ivip/Makefile
create mode 100644 drivers/gpu/drm/ivip/intel_vip_conn.c
create mode 100644 drivers/gpu/drm/ivip/intel_vip_core.c
create mode 100644 drivers/gpu/drm/ivip/intel_vip_drv.h
create mode 100644 drivers/gpu/drm/ivip/intel_vip_of.c
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 78d7fc0..bc03c938 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -195,6 +195,8 @@ source "drivers/gpu/drm/nouveau/Kconfig"
source "drivers/gpu/drm/i915/Kconfig"
+source "drivers/gpu/drm/ivip/Kconfig"
+
config DRM_VGEM
tristate "Virtual GEM provider"
depends on DRM
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 59f0f9b..7cfe899 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_DRM_AMDGPU)+= amd/amdgpu/
obj-$(CONFIG_DRM_MGA) += mga/
obj-$(CONFIG_DRM_I810) += i810/
obj-$(CONFIG_DRM_I915) += i915/
+obj-$(CONFIG_DRM_IVIP) += ivip/
obj-$(CONFIG_DRM_MGAG200) += mgag200/
obj-$(CONFIG_DRM_VC4) += vc4/
obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus/
diff --git a/drivers/gpu/drm/ivip/Kconfig b/drivers/gpu/drm/ivip/Kconfig
new file mode 100644
index 0000000..9a8c5ce
--- /dev/null
+++ b/drivers/gpu/drm/ivip/Kconfig
@@ -0,0 +1,13 @@
+config DRM_IVIP
+ tristate "Intel FGPA Video and Image Processing"
+ depends on DRM && OF
+ select DRM_GEM_CMA_HELPER
+ select DRM_KMS_HELPER
+ select DRM_KMS_FB_HELPER
+ select DRM_KMS_CMA_HELPER
+ help
+ Choose this option if you have a Intel FPGA Arria 10 system
+ and above with a Display Port IP. This does not support legacy
+ Intel FPGA Cyclone V display port. Currently only single frame
+ buffer is supported. Note that ACPI and X_86 architecture is yet
+ to be supported.If M is selected the module would be called ivip.
diff --git a/drivers/gpu/drm/ivip/Makefile b/drivers/gpu/drm/ivip/Makefile
new file mode 100644
index 0000000..95291c6
--- /dev/null
+++ b/drivers/gpu/drm/ivip/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for the drm device driver. This driver provides support for the
+# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
+
+ccflags-y := -Iinclude/drm
+
+obj-$(CONFIG_DRM_IVIP) += ivip.o
+ivip-objs := intel_vip_of.o intel_vip_core.o \
+intel_vip_conn.o
diff --git a/drivers/gpu/drm/ivip/intel_vip_conn.c b/drivers/gpu/drm/ivip/intel_vip_conn.c
new file mode 100644
index 0000000..499d3b4
--- /dev/null
+++ b/drivers/gpu/drm/ivip/intel_vip_conn.c
@@ -0,0 +1,96 @@
+/*
+ * intel_vip_conn.c -- Intel Video and Image Processing(VIP)
+ * Frame Buffer II driver
+ *
+ * This driver supports the Intel VIP Frame Reader component.
+ * More info on the hardware can be found in the Intel Video
+ * and Image Processing Suite User Guide at this address
+ * http://www.altera.com/literature/ug/ug_vip.pdf.
+ *
+ * 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.
+ *
+ * Authors:
+ * Ong, Hean-Loong <hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_encoder_slave.h>
+#include <drm/drm_plane_helper.h>
+
+static enum drm_connector_status
+intelvipfb_drm_connector_detect(struct drm_connector *connector, bool force)
+{
+ return connector_status_connected;
+}
+
+static void intelvipfb_drm_connector_destroy(struct drm_connector *connector)
+{
+ drm_connector_unregister(connector);
+ drm_connector_cleanup(connector);
+}
+
+static const struct drm_connector_funcs intelvipfb_drm_connector_funcs = {
+ .dpms = drm_helper_connector_dpms,
+ .reset = drm_atomic_helper_connector_reset,
+ .detect = intelvipfb_drm_connector_detect,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .destroy = intelvipfb_drm_connector_destroy,
+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static int intelvipfb_drm_connector_get_modes(struct drm_connector *connector)
+{
+ struct drm_device *drm = connector->dev;
+ int count;
+
+ count = drm_add_modes_noedid(connector, drm->mode_config.max_width,
+ drm->mode_config.max_height);
+ drm_set_preferred_mode(connector, drm->mode_config.max_width,
+ drm->mode_config.max_height);
+ return count;
+}
+
+static const struct drm_connector_helper_funcs
+intelvipfb_drm_connector_helper_funcs = {
+ .get_modes = intelvipfb_drm_connector_get_modes,
+};
+
+struct drm_connector *
+intelvipfb_conn_setup(struct drm_device *drm)
+{
+ struct drm_connector *conn;
+ int ret;
+
+ conn = devm_kzalloc(drm->dev, sizeof(*conn), GFP_KERNEL);
+ if (IS_ERR(conn))
+ return NULL;
+
+ ret = drm_connector_init(drm, conn, &intelvipfb_drm_connector_funcs,
+ DRM_MODE_CONNECTOR_DisplayPort);
+ if (ret < 0) {
+ dev_err(drm->dev, "failed to initialize drm connector\n");
+ ret = -ENOMEM;
+ goto error_connector_cleanup;
+ }
+
+ drm_connector_helper_add(conn, &intelvipfb_drm_connector_helper_funcs);
+
+ return conn;
+
+error_connector_cleanup:
+ drm_connector_cleanup(conn);
+
+ return NULL;
+}
diff --git a/drivers/gpu/drm/ivip/intel_vip_core.c b/drivers/gpu/drm/ivip/intel_vip_core.c
new file mode 100644
index 0000000..4e83343
--- /dev/null
+++ b/drivers/gpu/drm/ivip/intel_vip_core.c
@@ -0,0 +1,171 @@
+/*
+ * intel_vip_core.c -- Intel Video and Image Processing(VIP)
+ * Frame Buffer II driver
+ *
+ * This driver supports the Intel VIP Frame Reader component.
+ * More info on the hardware can be found in the Intel Video
+ * and Image Processing Suite User Guide at this address
+ * http://www.altera.com/literature/ug/ug_vip.pdf.
+ *
+ * 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.
+ *
+ * Authors:
+ * Ong, Hean-Loong <hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_plane_helper.h>
+#include <drm/drm_simple_kms_helper.h>
+
+#include "intel_vip_drv.h"
+
+static const u32 fbpriv_formats[] = {
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_RGB565
+};
+
+static void intelvipfb_start_hw(void __iomem *base, resource_size_t addr)
+{
+ /*
+ * The frameinfo variable has to correspond to the size of the VIP Suite
+ * Frame Reader register 7 which will determine the maximum size used
+ * in this frameinfo
+ */
+
+ u32 frameinfo;
+
+ frameinfo =
+ readl(base + INTELVIPFB_FRAME_READER) & 0x00ffffff;
+ writel(frameinfo, base + INTELVIPFB_FRAME_INFO);
+ writel(addr, base + INTELVIPFB_FRAME_START);
+ /* Finally set the control register to 1 to start streaming */
+ writel(1, base + INTELVIPFB_CONTROL);
+}
+
+static void intelvipfb_disable_hw(void __iomem *base)
+{
+ /* set the control register to 0 to stop streaming */
+ writel(0, base + INTELVIPFB_CONTROL);
+}
+
+static const struct drm_mode_config_funcs intelvipfb_mode_config_funcs = {
+ .fb_create = drm_fb_cma_create,
+ .atomic_check = drm_atomic_helper_check,
+ .atomic_commit = drm_atomic_helper_commit,
+};
+
+static struct drm_mode_config_helper_funcs intelvipfb_mode_config_helpers = {
+ .atomic_commit_tail = drm_atomic_helper_commit_tail,
+};
+
+static void intelvipfb_setup_mode_config(struct drm_device *drm)
+{
+ drm_mode_config_init(drm);
+ drm->mode_config.funcs = &intelvipfb_mode_config_funcs;
+ drm->mode_config.helper_private = &intelvipfb_mode_config_helpers;
+}
+
+static int intelvipfb_pipe_prepare_fb(struct drm_simple_display_pipe *pipe,
+ struct drm_plane_state *plane_state)
+{
+ return drm_fb_cma_prepare_fb(&pipe->plane, plane_state);
+}
+
+static struct drm_simple_display_pipe_funcs fbpriv_funcs = {
+ .prepare_fb = intelvipfb_pipe_prepare_fb,
+};
+
+int intelvipfb_probe(struct device *dev, void __iomem *base)
+{
+ int retval;
+ struct drm_device *drm;
+ struct intelvipfb_priv *fbpriv = dev_get_drvdata(dev);
+ struct drm_connector *connector;
+
+ dev_set_drvdata(dev, fbpriv);
+
+ drm = fbpriv->drm;
+
+ intelvipfb_setup_mode_config(drm);
+
+ connector = intelvipfb_conn_setup(drm);
+ if (!connector) {
+ dev_err(drm->dev, "Connector setup failed\n");
+ goto err_mode_config;
+ }
+
+ retval = drm_simple_display_pipe_init(drm, &fbpriv->pipe,
+ &fbpriv_funcs,
+ fbpriv_formats,
+ ARRAY_SIZE(fbpriv_formats),
+ connector);
+ if (retval < 0) {
+ dev_err(drm->dev, "Cannot setup simple display pipe\n");
+ goto err_mode_config;
+ }
+
+ fbpriv->fbcma = drm_fbdev_cma_init(drm, PREF_BPP,
+ drm->mode_config.num_connector);
+ if (!fbpriv->fbcma) {
+ fbpriv->fbcma = NULL;
+ dev_err(drm->dev, "Failed to init FB CMA area\n");
+ goto err_mode_config;
+ }
+
+ drm_mode_config_reset(drm);
+
+ intelvipfb_start_hw(base, drm->mode_config.fb_base);
+
+ drm_dev_register(drm, 0);
+
+ return retval;
+
+err_mode_config:
+
+ drm_mode_config_cleanup(drm);
+ return -ENODEV;
+}
+EXPORT_SYMBOL_GPL(intelvipfb_probe);
+
+int intelvipfb_remove(struct device *dev)
+{
+ struct intelvipfb_priv *fbpriv = dev_get_drvdata(dev);
+ struct drm_device *drm = fbpriv->drm;
+
+ drm_dev_unregister(drm);
+
+ if (fbpriv->fbcma)
+ drm_fbdev_cma_fini(fbpriv->fbcma);
+
+ intelvipfb_disable_hw(fbpriv->base);
+ drm_mode_config_cleanup(drm);
+
+ drm_dev_unref(drm);
+
+ devm_kfree(dev, fbpriv);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(intelvipfb_remove);
+
+MODULE_AUTHOR("Ong, Hean-Loong <hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>");
+MODULE_DESCRIPTION("Intel VIP Frame Buffer II driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/ivip/intel_vip_drv.h b/drivers/gpu/drm/ivip/intel_vip_drv.h
new file mode 100644
index 0000000..8ef83f59
--- /dev/null
+++ b/drivers/gpu/drm/ivip/intel_vip_drv.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2017 Intel Corporation.
+ *
+ * Intel Video and Image Processing(VIP) Frame Buffer II driver.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Ong, Hean-Loong <hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
+ *
+ */
+#ifndef _INTEL_VIP_DRV_H
+#define _INTEL_VIP_DRV_H
+#include <linux/io.h>
+#include <linux/fb.h>
+
+#define DRIVER_NAME "intelvipfb"
+#define BYTES_PER_PIXEL 4
+#define PREF_BPP 32
+#define CRTC_NUM 1
+#define CONN_NUM 1
+
+/* control registers */
+#define INTELVIPFB_CONTROL 0
+#define INTELVIPFB_STATUS 0x4
+#define INTELVIPFB_INTERRUPT 0x8
+#define INTELVIPFB_FRAME_COUNTER 0xC
+#define INTELVIPFB_FRAME_DROP 0x10
+#define INTELVIPFB_FRAME_INFO 0x14
+#define INTELVIPFB_FRAME_START 0x18
+#define INTELVIPFB_FRAME_READER 0x1C
+
+int intelvipfb_probe(struct device *dev, void __iomem *base);
+int intelvipfb_remove(struct device *dev);
+int intelvipfb_setup_crtc(struct drm_device *drm);
+struct drm_connector *intelvipfb_conn_setup(struct drm_device *drm);
+
+struct intelvipfb_priv {
+ struct drm_simple_display_pipe pipe;
+ struct drm_fbdev_cma *fbcma;
+ struct drm_device *drm;
+ void __iomem *base;
+};
+
+#endif
diff --git a/drivers/gpu/drm/ivip/intel_vip_of.c b/drivers/gpu/drm/ivip/intel_vip_of.c
new file mode 100644
index 0000000..7e3dc39
--- /dev/null
+++ b/drivers/gpu/drm/ivip/intel_vip_of.c
@@ -0,0 +1,195 @@
+/*
+ * intel_vip_of.c -- Intel Video and Image Processing(VIP)
+ * Frame Buffer II driver
+ *
+ * This driver supports the Intel VIP Frame Reader component.
+ * More info on the hardware can be found in the Intel Video
+ * and Image Processing Suite User Guide at this address
+ * http://www.altera.com/literature/ug/ug_vip.pdf.
+ *
+ * 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.
+ *
+ * Authors:
+ * Ong, Hean-Loong <hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
+ *
+ */
+
+#include <linux/component.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_of.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_simple_kms_helper.h>
+
+#include "intel_vip_drv.h"
+
+DEFINE_DRM_GEM_CMA_FOPS(fops);
+
+static struct drm_driver intelvipfb_drm = {
+ .driver_features =
+ DRIVER_GEM | DRIVER_PRIME |
+ DRIVER_RENDER | DRIVER_MODESET | DRIVER_ATOMIC,
+ .gem_free_object_unlocked = drm_gem_cma_free_object,
+ .gem_vm_ops = &drm_gem_cma_vm_ops,
+ .dumb_create = drm_gem_cma_dumb_create,
+ .dumb_map_offset = drm_gem_cma_dumb_map_offset,
+ .dumb_destroy = drm_gem_dumb_destroy,
+ .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
+ .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
+ .gem_prime_export = drm_gem_prime_export,
+ .gem_prime_import = drm_gem_prime_import,
+ .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table,
+ .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
+ .gem_prime_vmap = drm_gem_cma_prime_vmap,
+ .gem_prime_vunmap = drm_gem_cma_prime_vunmap,
+ .gem_prime_mmap = drm_gem_cma_prime_mmap,
+ .name = DRIVER_NAME,
+ .date = "20170329",
+ .desc = "Intel FPGA VIP SUITE",
+ .major = 1,
+ .minor = 0,
+ .patchlevel = 0,
+ .fops = &fops,
+};
+
+/*
+ * Setting up information derived from OF Device Tree Nodes
+ * max-width, max-height, bits per pixel, memory port width
+ */
+
+static int intelvipfb_drm_setup(struct device *dev,
+ struct intelvipfb_priv *fbpriv)
+{
+ struct drm_device *drm = fbpriv->drm;
+ struct device_node *np = dev->of_node;
+ int mem_word_width;
+ int max_h, max_w;
+ int bpp;
+ int ret;
+
+ ret = of_property_read_u32(np, "altr,max-width", &max_w);
+ if (ret) {
+ dev_err(dev,
+ "Missing required parameter 'altr,max-width'");
+ return ret;
+ }
+
+ ret = of_property_read_u32(np, "altr,max-height", &max_h);
+ if (ret) {
+ dev_err(dev,
+ "Missing required parameter 'altr,max-height'");
+ return ret;
+ }
+
+ ret = of_property_read_u32(np, "altr,bits-per-symbol", &bpp);
+ if (ret) {
+ dev_err(dev,
+ "Missing required parameter 'altr,bits-per-symbol'");
+ return ret;
+ }
+
+ ret = of_property_read_u32(np, "altr,mem-port-width", &mem_word_width);
+ if (ret) {
+ dev_err(dev, "Missing required parameter 'altr,mem-port-width '");
+ return ret;
+ }
+
+ if (!(mem_word_width >= 32 && mem_word_width % 32 == 0)) {
+ dev_err(dev,
+ "mem-word-width is set to %i. must be >= 32 and multiple of 32.",
+ mem_word_width);
+ return -ENODEV;
+ }
+
+ drm->mode_config.min_width = 640;
+ drm->mode_config.min_height = 480;
+ drm->mode_config.max_width = max_w;
+ drm->mode_config.max_height = max_h;
+ drm->mode_config.preferred_depth = bpp * BYTES_PER_PIXEL;
+
+ return 0;
+}
+
+static int intelvipfb_of_probe(struct platform_device *pdev)
+{
+ int retval;
+ struct resource *reg_res;
+ struct intelvipfb_priv *fbpriv;
+ struct device *dev = &pdev->dev;
+ struct drm_device *drm;
+
+ fbpriv = devm_kzalloc(dev, sizeof(*fbpriv), GFP_KERNEL);
+ if (!fbpriv)
+ return -ENOMEM;
+
+ /*setup DRM */
+ drm = drm_dev_alloc(&intelvipfb_drm, dev);
+ if (IS_ERR(drm))
+ return PTR_ERR(drm);
+
+ retval = dma_set_mask_and_coherent(drm->dev, DMA_BIT_MASK(32));
+ if (retval)
+ return -ENODEV;
+
+ fbpriv->drm = drm;
+
+ reg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!reg_res)
+ return -ENOMEM;
+
+ fbpriv->base = devm_ioremap_resource(dev, reg_res);
+
+ if (IS_ERR(fbpriv->base)) {
+ dev_err(dev, "devm_ioremap_resource failed\n");
+ retval = PTR_ERR(fbpriv->base);
+ return -ENOMEM;
+ }
+
+ intelvipfb_drm_setup(dev, fbpriv);
+
+ dev_set_drvdata(dev, fbpriv);
+
+ return intelvipfb_probe(dev, fbpriv->base);
+}
+
+static int intelvipfb_of_remove(struct platform_device *pdev)
+{
+ return intelvipfb_remove(&pdev->dev);
+}
+
+/*
+ * The name vip-frame-buffer-2.0 is derived from
+ * http://www.altera.com/literature/ug/ug_vip.pdf
+ * frame buffer IP cores section 14
+ */
+
+static const struct of_device_id intelvipfb_of_match[] = {
+ { .compatible = "altr,vip-frame-buffer-2.0" },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, intelvipfb_of_match);
+
+static struct platform_driver intelvipfb_driver = {
+ .probe = intelvipfb_of_probe,
+ .remove = intelvipfb_of_remove,
+ .driver = {
+ .name = DRIVER_NAME,
+ .of_match_table = intelvipfb_of_match,
+ },
+};
+
+module_platform_driver(intelvipfb_driver);
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCHv2 1/3] dt-bindings: display: Intel FPGA VIP drm driver Devicetree bindings
From: hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w @ 2017-04-25 2:06 UTC (permalink / raw)
To: daniel.vetter-ral2JQCrhuEAvxtiuMwx3w,
dinguyen-DgEjT+Ai2ygdnm+yROfE0A, robh+dt-DgEjT+Ai2ygdnm+yROfE0A
Cc: tien.hock.loh-ral2JQCrhuEAvxtiuMwx3w,
hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w,
devicetree-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
Ong-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1493086006-4392-1-git-send-email-hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
From: "Ong, Hean Loong" <hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Device tree binding for Intel FPGA Video and Image
Processing Suite. The binding involved would be generated
from the Altera (Intel) Qsys system. The bindings would
set the max width, max height, buts per pixel and memory
port width. The device tree binding only supports the Intel
Arria10 devkit and its variants. Vendor name retained as
altr.
Signed-off-by: Ong, Hean Loong <hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
v2:
* Moved Device Tree bindings to Documentation/devicetree/bindings/display/
* Added vendor name altr, to description
---
.../devicetree/bindings/display/altr,vip-fb2.txt | 30 ++++++++++++++++++++++
1 file changed, 30 insertions(+)
create mode 100644 Documentation/devicetree/bindings/display/altr,vip-fb2.txt
diff --git a/Documentation/devicetree/bindings/display/altr,vip-fb2.txt b/Documentation/devicetree/bindings/display/altr,vip-fb2.txt
new file mode 100644
index 0000000..bdffefb
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/altr,vip-fb2.txt
@@ -0,0 +1,30 @@
+Intel Video and Image Processing(VIP) Frame Buffer II bindings
+
+Supported hardware: Arria 10 and above with display port IP
+
+The drm driver for the Arria 10 devkit would require the display resolution
+and pixel information to be included as these values are generated based
+on the FPGA design that drives the video connector attached to the drm driver
+Information the FPGA video IP component can be acquired from
+https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/ug/ug_vip.pdf
+
+Required properties:
+
+- compatible: "altr,vip-frame-buffer-2.0"
+- reg: Physical base address and length of the framebuffer controller's
+ registers.
+- altr,max-width: The width of the framebuffer in pixels.
+- altr,max-height: The height of the framebuffer in pixels.
+- altr,bits-per-symbol: only "8" is currently supported
+- altr,mem-port-width = the bus width of the avalon master port on the frame reader
+
+Example:
+
+ dp_0_frame_buf: vip@100000280 {
+ compatible = "altr,vip-frame-buffer-2.0";
+ reg = <0x00000001 0x00000280 0x00000040>;
+ altr,max-width = <1280>;
+ altr,max-height = <720>;
+ altr,bits-per-symbol = <8>;
+ altr,mem-port-width = <128>;
+ };
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCHv2 0/3] Intel FPGA VIP Frame Buffer II DRM Driver
From: hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w @ 2017-04-25 2:06 UTC (permalink / raw)
To: daniel.vetter-ral2JQCrhuEAvxtiuMwx3w,
dinguyen-DgEjT+Ai2ygdnm+yROfE0A, robh+dt-DgEjT+Ai2ygdnm+yROfE0A
Cc: tien.hock.loh-ral2JQCrhuEAvxtiuMwx3w,
hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w,
devicetree-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
From: Ong Hean Loong <hean.loong.ong-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Hi,
The new Intel Arria10 SOC FPGA devkit has a Display Port IP component
which requires a new driver. This is a virtual driver in which the
FGPA hardware would enable the Display Port based on the information
and data provided from the DRM frame buffer from the OS. Basically all
all information with reagrds to resolution and bits per pixel are
pre-configured on the FPGA design and these information are fed to
the driver via the device tree information as part of the hardware
information.
Further information can be obtained from
https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/ug/ug_vip.pdf
Ong, Hean Loong (3):
dt-bindings: display: Intel FPGA VIP drm driver Devicetree bindings
ARM: drm: Intel FPGA VIP Frame Buffer II drm driver
ARM: socfpga: drm driver updates in socfpga_defconfig
.../devicetree/bindings/display/altr,vip-fb2.txt | 30 ++++
arch/arm/configs/socfpga_defconfig | 4 +
drivers/gpu/drm/Kconfig | 2 +
drivers/gpu/drm/Makefile | 1 +
drivers/gpu/drm/ivip/Kconfig | 13 ++
drivers/gpu/drm/ivip/Makefile | 9 +
drivers/gpu/drm/ivip/intel_vip_conn.c | 96 ++++++++++
drivers/gpu/drm/ivip/intel_vip_core.c | 171 ++++++++++++++++++
drivers/gpu/drm/ivip/intel_vip_drv.h | 55 ++++++
drivers/gpu/drm/ivip/intel_vip_of.c | 195 +++++++++++++++++++++
10 files changed, 576 insertions(+)
create mode 100644 Documentation/devicetree/bindings/display/altr,vip-fb2.txt
create mode 100644 drivers/gpu/drm/ivip/Kconfig
create mode 100644 drivers/gpu/drm/ivip/Makefile
create mode 100644 drivers/gpu/drm/ivip/intel_vip_conn.c
create mode 100644 drivers/gpu/drm/ivip/intel_vip_core.c
create mode 100644 drivers/gpu/drm/ivip/intel_vip_drv.h
create mode 100644 drivers/gpu/drm/ivip/intel_vip_of.c
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH] arm64: dts: exynos: Remove the te-gpios property in the TM2 boards
From: Hoegeun Kwon @ 2017-04-25 1:54 UTC (permalink / raw)
To: robh+dt, mark.rutland, catalin.marinas, will.deacon, kgene, krzk
Cc: javier, devicetree, linux-arm-kernel, linux-samsung-soc,
linux-kernel, a.hajda, Hoegeun Kwon
In-Reply-To: <CGME20170425015437epcas5p43549d47e69519f43d89ba2de496ba451@epcas5p4.samsung.com>
The decon uses HW-TRIGGER, so TE interrupt is not necessary.
Therefore, remove the te-gpios property in the TM2 dts.
Signed-off-by: Hoegeun Kwon <hoegeun.kwon@samsung.com>
---
arch/arm64/boot/dts/exynos/exynos5433-tm2.dts | 1 -
1 file changed, 1 deletion(-)
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
index 3ff9527..23191eb 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
@@ -60,7 +60,6 @@
vci-supply = <&ldo28_reg>;
reset-gpios = <&gpg0 0 GPIO_ACTIVE_LOW>;
enable-gpios = <&gpf1 5 GPIO_ACTIVE_HIGH>;
- te-gpios = <&gpf1 3 GPIO_ACTIVE_HIGH>;
};
};
--
1.9.1
^ permalink raw reply related
* Re: [PATCH v3 1/3] mtd: nand: Cleanup/rework the atmel_nand driver
From: Brian Norris @ 2017-04-25 1:09 UTC (permalink / raw)
To: Boris Brezillon
Cc: Richard Weinberger, linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
Nicolas Ferre, Alexandre Belloni, Haavard Skinnemoen,
Hans-Christian Egtvedt, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
Wenyou Yang, Josh Wu, David Woodhouse, Marek Vasut,
Cyrille Pitchen,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
devicetree-u79uwXL29TY76Z2rM5mHXA, Masahiro Yamada
In-Reply-To: <1489651362-17077-2-git-send-email-boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
On Thu, Mar 16, 2017 at 09:02:40AM +0100, Boris Brezillon wrote:
> diff --git a/drivers/mtd/nand/atmel/nand-controller.c b/drivers/mtd/nand/atmel/nand-controller.c
> new file mode 100644
> index 000000000000..f71b9e5d7d9d
> --- /dev/null
> +++ b/drivers/mtd/nand/atmel/nand-controller.c
> @@ -0,0 +1,2198 @@
[...]
> +static int
> +atmel_hsmc_nand_controller_legacy_init(struct atmel_hsmc_nand_controller *nc)
> +{
> + struct regmap_config regmap_conf = {
> + .reg_bits = 32,
> + .val_bits = 32,
> + .reg_stride = 4,
> + .val_bits = 32,
You assigned val_bits twice. Is that just a harmless mistake, or did you
mean to set something else?
(sparse and other tools complain about this)
> + };
Brian
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v3 0/7] NFC: trf7970a: Fixups & convert to desc-based GPIO
From: Mark Greer @ 2017-04-25 0:19 UTC (permalink / raw)
To: Samuel Ortiz
Cc: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw,
devicetree-u79uwXL29TY76Z2rM5mHXA, Mark Greer,
linux-wireless-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170120191745.29255-1-mgreer-luAo+O/VEmrlveNOaEYElw@public.gmane.org>
[-CC: Lauro Ramos Venancio <lauro.venancio-430g2QfJUUCGglJvpFV4uA@public.gmane.org> and
Aloisio Almeida Jr <aloisio.almeida-430g2QfJUUCGglJvpFV4uA@public.gmane.org>]
[+CC: linux-wireless]
On Fri, Jan 20, 2017 at 12:17:38PM -0700, Mark Greer wrote:
> These trf7970a driver patches do the following things:
> - a couple minor fixups
> - allow EN2 to not be managed by the driver (e.g., when its tied low by
> hardware
> - convert the driver to use the descriptor-based GPIO interface
> - remove support for 'vin-voltage-override' DT property
> - change the DTS example to indicate that EN and EN2 are active high GPIOs
> - add Mark Greer as the maintainer of the trf7970a driver
>
> Based on k.o. 44b4b46 (Merge tag 'armsoc-fixes' of
> git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc)
>
> v2->v3:
> - Removed "[PATCH v2 5/7] NFC: trf7970a: Clean up coding style issues"
> because it will make merging patches from Geoff Lansberry and others
> hard to apply. I will resubmit once those patches have been merged
> or rejected.
> - Added a patch to remove 'vin-voltage-override' DT property support as
> proper DT regulator set up makes it unnecessary.
>
> v1->v2:
> - Commit description fixups only; no functional changes.
>
> Mark Greer (7):
> NFC: trf7970a: Don't de-assert EN2 unless it was asserted
> NFC: trf7970a: Don't manage EN2 when not specified in DT
> NFC: trf7970a: Convert to descriptor based GPIO interface
> NFC: trf7970a: Remove useless comment
> NFC: trf7970a: Remove support for 'vin-voltage-override' DT property
> NFC: trf7970a: Enable pins are active high not active low
> MAINTAINERS: NFC: trf7970a: Add Mark Greer as maintainer
>
> .../devicetree/bindings/net/nfc/trf7970a.txt | 6 +-
> MAINTAINERS | 7 ++
> drivers/nfc/Kconfig | 2 +-
> drivers/nfc/trf7970a.c | 75 +++++++++-------------
> 4 files changed, 40 insertions(+), 50 deletions(-)
I've already mentioned this to Samuel privately but for everyone's sake,
I will respin this series because some patches that cause conflicts have
been accepted. I will also add some patches that I have made in the
interim. I apologize for the churn.
Mark
--
^ permalink raw reply
* Re: [PATCH 2/2] ARM: dts: Add the ethernet and ethernet PHY to the cygnus core DT.
From: Eric Anholt @ 2017-04-25 0:02 UTC (permalink / raw)
To: Florian Fainelli, Vivien Didelot, Andrew Lunn,
netdev-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Mark Rutland,
devicetree-u79uwXL29TY76Z2rM5mHXA
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w, Ray Jui,
Scott Branden, Jon Mason
In-Reply-To: <1759fb29-0678-0ec5-5398-16c4a3ba9660-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 613 bytes --]
Florian Fainelli <f.fainelli-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> writes:
> On 04/24/2017 02:50 PM, Eric Anholt wrote:
>> Cygnus has a single amac controller connected to the B53 switch with 2
>> PHYs. On the BCM911360_EP platform, those two PHYs are connected to
>> the external ethernet jacks.
>>
>> Signed-off-by: Eric Anholt <eric-WhKQ6XTQaPysTnJN9+BGXg@public.gmane.org>
>
> This looks fine, just a few nits on the label names:
Thanks. I've applied all of these (and Andrew's and Scott's
suggestions), and I'll send out a new version once the DT maintainers
have had a chance to look.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
^ permalink raw reply
* Re: [PATCH 2/2] ARM: dts: Add the ethernet and ethernet PHY to the cygnus core DT.
From: Eric Anholt @ 2017-04-25 0:00 UTC (permalink / raw)
To: Andrew Lunn
Cc: Florian Fainelli, Vivien Didelot, netdev, Rob Herring,
Mark Rutland, devicetree, linux-arm-kernel, linux-kernel,
bcm-kernel-feedback-list, Ray Jui, Scott Branden, Jon Mason
In-Reply-To: <20170424220842.GA26241@lunn.ch>
[-- Attachment #1: Type: text/plain, Size: 568 bytes --]
Andrew Lunn <andrew@lunn.ch> writes:
>> + mdio: mdio@18002000 {
>> + compatible = "brcm,iproc-mdio";
>> + reg = <0x18002000 0x8>;
>> + #size-cells = <1>;
>> + #address-cells = <0>;
>> +
>> + gphy0: eth-gphy@0 {
>> + reg = <0>;
>> + max-speed = <1000>;
>> + };
>> +
>> + gphy1: eth-gphy@1 {
>> + reg = <1>;
>> + max-speed = <1000>;
>> + };
>> + };
>
> Hi Eric
>
> Do these max-speed properties do anything useful? Is the PHY capable
> of > 1Gbps?
Not sure where I had those copy-and-pasted from, but they don't seem
necessary. Dropped.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox