All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Noralf Trønnes" <noralf@tronnes.org>
To: dri-devel@lists.freedesktop.org
Cc: thomas.petazzoni@free-electrons.com
Subject: [RFC 2/5] drm/tinydrm: Add lcd register abstraction
Date: Wed, 16 Mar 2016 14:34:16 +0100	[thread overview]
Message-ID: <1458135259-31050-3-git-send-email-noralf@tronnes.org> (raw)
In-Reply-To: <1458135259-31050-1-git-send-email-noralf@tronnes.org>

Add LCD register abstraction for MIPI DBI/DCS like controllers.
This hides LCD controller interface implementation details.
When built with debugfs, the register is available to userspace.

Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
---
 drivers/gpu/drm/tinydrm/Kconfig                 |   2 +
 drivers/gpu/drm/tinydrm/Makefile                |   1 +
 drivers/gpu/drm/tinydrm/lcdreg/Kconfig          |   3 +
 drivers/gpu/drm/tinydrm/lcdreg/Makefile         |   3 +
 drivers/gpu/drm/tinydrm/lcdreg/internal.h       |   8 +
 drivers/gpu/drm/tinydrm/lcdreg/lcdreg-core.c    | 190 ++++++++++++++++
 drivers/gpu/drm/tinydrm/lcdreg/lcdreg-debugfs.c | 281 ++++++++++++++++++++++++
 include/drm/tinydrm/lcdreg.h                    | 126 +++++++++++
 8 files changed, 614 insertions(+)
 create mode 100644 drivers/gpu/drm/tinydrm/lcdreg/Kconfig
 create mode 100644 drivers/gpu/drm/tinydrm/lcdreg/Makefile
 create mode 100644 drivers/gpu/drm/tinydrm/lcdreg/internal.h
 create mode 100644 drivers/gpu/drm/tinydrm/lcdreg/lcdreg-core.c
 create mode 100644 drivers/gpu/drm/tinydrm/lcdreg/lcdreg-debugfs.c
 create mode 100644 include/drm/tinydrm/lcdreg.h

diff --git a/drivers/gpu/drm/tinydrm/Kconfig b/drivers/gpu/drm/tinydrm/Kconfig
index f290045..671239f 100644
--- a/drivers/gpu/drm/tinydrm/Kconfig
+++ b/drivers/gpu/drm/tinydrm/Kconfig
@@ -9,3 +9,5 @@ menuconfig DRM_TINYDRM
 	help
 	  Choose this option if you have a tinydrm supported display.
 	  If M is selected the module will be called tinydrm.
+
+source "drivers/gpu/drm/tinydrm/lcdreg/Kconfig"
diff --git a/drivers/gpu/drm/tinydrm/Makefile b/drivers/gpu/drm/tinydrm/Makefile
index 7476ed1..f4a92d9 100644
--- a/drivers/gpu/drm/tinydrm/Makefile
+++ b/drivers/gpu/drm/tinydrm/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_DRM_TINYDRM)		+= core/
+obj-$(CONFIG_LCDREG)			+= lcdreg/
diff --git a/drivers/gpu/drm/tinydrm/lcdreg/Kconfig b/drivers/gpu/drm/tinydrm/lcdreg/Kconfig
new file mode 100644
index 0000000..41383b1
--- /dev/null
+++ b/drivers/gpu/drm/tinydrm/lcdreg/Kconfig
@@ -0,0 +1,3 @@
+config LCDREG
+	tristate
+	depends on GPIOLIB || COMPILE_TEST
diff --git a/drivers/gpu/drm/tinydrm/lcdreg/Makefile b/drivers/gpu/drm/tinydrm/lcdreg/Makefile
new file mode 100644
index 0000000..c9ea774
--- /dev/null
+++ b/drivers/gpu/drm/tinydrm/lcdreg/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_LCDREG)                   += lcdreg.o
+lcdreg-y                               += lcdreg-core.o
+lcdreg-$(CONFIG_DEBUG_FS)              += lcdreg-debugfs.o
diff --git a/drivers/gpu/drm/tinydrm/lcdreg/internal.h b/drivers/gpu/drm/tinydrm/lcdreg/internal.h
new file mode 100644
index 0000000..140fcfd
--- /dev/null
+++ b/drivers/gpu/drm/tinydrm/lcdreg/internal.h
@@ -0,0 +1,8 @@
+
+#ifdef CONFIG_DEBUG_FS
+void lcdreg_debugfs_init(struct lcdreg *reg);
+void lcdreg_debugfs_exit(struct lcdreg *reg);
+#else
+static inline void lcdreg_debugfs_init(struct lcdreg *reg) { }
+static inline void lcdreg_debugfs_exit(struct lcdreg *reg) { }
+#endif
diff --git a/drivers/gpu/drm/tinydrm/lcdreg/lcdreg-core.c b/drivers/gpu/drm/tinydrm/lcdreg/lcdreg-core.c
new file mode 100644
index 0000000..bda848c
--- /dev/null
+++ b/drivers/gpu/drm/tinydrm/lcdreg/lcdreg-core.c
@@ -0,0 +1,190 @@
+//#define DEBUG
+/*
+ * Copyright (C) 2016 Noralf Trønnes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <drm/tinydrm/lcdreg.h>
+#include <linux/device.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include "internal.h"
+
+/**
+ * Write to LCD register
+ *
+ * @reg: LCD register
+ * @regnr: Register number
+ * @transfer: Transfer to write
+ */
+int lcdreg_write(struct lcdreg *reg, unsigned regnr,
+		 struct lcdreg_transfer *transfer)
+{
+	if (WARN_ON_ONCE(!reg || !reg->write || !transfer))
+		return -EINVAL;
+
+	if (!transfer->width)
+		transfer->width = reg->def_width;
+
+	dev_dbg(reg->dev,
+		"lcdreg_write: regnr=0x%02x, index=%u, count=%u, width=%u\n",
+		regnr, transfer->index, transfer->count, transfer->width);
+	lcdreg_dbg_transfer_buf(transfer);
+
+	return reg->write(reg, regnr, transfer);
+}
+EXPORT_SYMBOL(lcdreg_write);
+
+/**
+ * Write 32-bit wide buffer to LCD register
+ * @reg: lcdreg
+ * @regnr: Register number
+ * @buf: Buffer to write
+ * @count: Number of words to write
+ */
+int lcdreg_write_buf32(struct lcdreg *reg, unsigned regnr, const u32 *buf,
+		       unsigned count)
+{
+	struct lcdreg_transfer tr = {
+		.index = 1,
+		.width = reg->def_width,
+		.count = count,
+	};
+	int i, ret;
+
+	if (!buf)
+		return -EINVAL;
+
+	tr.buf = kmalloc_array(count, sizeof(*buf), GFP_KERNEL);
+	if (!tr.buf)
+		return -ENOMEM;
+
+	if (reg->def_width <= 8)
+		for (i = 0; i < tr.count; i++)
+			((u8 *)tr.buf)[i] = buf[i];
+	else
+		for (i = 0; i < tr.count; i++)
+			((u16 *)tr.buf)[i] = buf[i];
+	ret = lcdreg_write(reg, regnr, &tr);
+	kfree(tr.buf);
+
+	return ret;
+}
+EXPORT_SYMBOL(lcdreg_write_buf32);
+
+/**
+ * Read from LCD register
+ *
+ * @reg: LCD register
+ * @regnr: Register number
+ * @transfer: Transfer to read into
+ */
+int lcdreg_read(struct lcdreg *reg, unsigned regnr,
+		struct lcdreg_transfer *transfer)
+{
+	int ret;
+
+	if (WARN_ON_ONCE(!reg || !transfer))
+		return -EINVAL;
+
+	if (!reg->read)
+		return -EOPNOTSUPP;
+
+	if (!transfer->width)
+		transfer->width = reg->def_width;
+
+	dev_dbg(reg->dev,
+		"lcdreg_read: regnr=0x%02x, index=%u, count=%u, width=%u\n",
+		regnr, transfer->index, transfer->count, transfer->width);
+
+	ret = reg->read(reg, regnr, transfer);
+
+	lcdreg_dbg_transfer_buf(transfer);
+
+	return ret;
+}
+EXPORT_SYMBOL(lcdreg_read);
+
+/**
+ * Read from LCD register into 32-bit wide buffer
+ * @reg: LCD register
+ * @regnr: Register number
+ * @buf: Buffer to read into
+ * @count: Number of words to read
+ */
+int lcdreg_readreg_buf32(struct lcdreg *reg, unsigned regnr, u32 *buf,
+			 unsigned count)
+{
+	struct lcdreg_transfer tr = {
+		.index = 1,
+		.count = count,
+	};
+	int i, ret;
+
+	if (!buf || !count)
+		return -EINVAL;
+
+	tr.buf = kmalloc_array(count, sizeof(*buf), GFP_KERNEL);
+	if (!tr.buf)
+		return -ENOMEM;
+
+	ret = lcdreg_read(reg, regnr, &tr);
+	if (ret) {
+		kfree(tr.buf);
+		return ret;
+	}
+
+	if (reg->def_width <= 8)
+		for (i = 0; i < count; i++)
+			buf[i] = ((u8 *)tr.buf)[i];
+	else
+		for (i = 0; i < count; i++)
+			buf[i] = ((u16 *)tr.buf)[i];
+	kfree(tr.buf);
+
+	return ret;
+}
+EXPORT_SYMBOL(lcdreg_readreg_buf32);
+
+static void devm_lcdreg_release(struct device *dev, void *res)
+{
+	struct lcdreg *reg = *(struct lcdreg **)res;
+
+	lcdreg_debugfs_exit(reg);
+	mutex_destroy(&reg->lock);
+}
+
+/**
+ * Device managed lcdreg initialization
+ *
+ * @dev: Device backing the LCD register
+ * @reg: LCD register
+ */
+struct lcdreg *devm_lcdreg_init(struct device *dev, struct lcdreg *reg)
+{
+	struct lcdreg **ptr;
+
+	if (!dev || !reg)
+		return ERR_PTR(-EINVAL);
+
+	ptr = devres_alloc(devm_lcdreg_release, sizeof(*ptr), GFP_KERNEL);
+	if (!ptr)
+		return ERR_PTR(-ENOMEM);
+
+	*ptr = reg;
+	devres_add(dev, ptr);
+	reg->dev = dev;
+	mutex_init(&reg->lock);
+	lcdreg_debugfs_init(reg);
+
+	return reg;
+}
+EXPORT_SYMBOL(devm_lcdreg_init);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/tinydrm/lcdreg/lcdreg-debugfs.c b/drivers/gpu/drm/tinydrm/lcdreg/lcdreg-debugfs.c
new file mode 100644
index 0000000..9fcc13d
--- /dev/null
+++ b/drivers/gpu/drm/tinydrm/lcdreg/lcdreg-debugfs.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2016 Noralf Trønnes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <drm/tinydrm/lcdreg.h>
+#include <linux/debugfs.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+
+#define READ_RESULT_SIZE 16
+
+static struct dentry *lcdreg_debugfs_root;
+
+static int lcdreg_userbuf_to_u32(const char __user *user_buf, size_t count,
+				 u32 *dest, size_t dest_size)
+{
+	char *buf, *start;
+	int ret = -EINVAL;
+	int i;
+
+	buf = kmalloc(count, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	if (copy_from_user(buf, user_buf, count)) {
+		kfree(buf);
+		return -EFAULT;
+	}
+
+	/* turn whitespace into end-of-string for number parsing */
+	for (i = 0; i < count; i++)
+		if (buf[i] == ' ' || buf[i] == '\n' || buf[i] == '\t')
+			buf[i] = '\0';
+
+	i = 0;
+	start = buf;
+	while (start < buf + count) {
+		/* skip "whitespace" */
+		if (*start == '\0') {
+			start++;
+			continue;
+		}
+
+		if (i == dest_size) {
+			ret = -EFBIG;
+			break;
+		}
+
+		ret = kstrtou32(start, 0, &dest[i++]);
+		if (ret)
+			break;
+
+		/* move past this number */
+		while (*start != '\0')
+			start++;
+	};
+
+	kfree(buf);
+
+	return ret ? : i;
+}
+
+static ssize_t lcdreg_debugfs_write_file(struct file *file,
+					 const char __user *user_buf,
+					 size_t count, loff_t *ppos)
+{
+	struct lcdreg *reg = file->private_data;
+	int ret;
+	u32 txbuf[128];
+
+	ret = lcdreg_userbuf_to_u32(user_buf, count, txbuf, ARRAY_SIZE(txbuf));
+	if (ret < 0)
+		return ret;
+
+	mutex_lock(&reg->lock);
+	ret = lcdreg_write_buf32(reg, txbuf[0], txbuf + 1, ret - 1);
+	mutex_unlock(&reg->lock);
+
+	return ret ? : count;
+}
+
+static const struct file_operations lcdreg_debugfs_write_fops = {
+	.open = simple_open,
+	.write = lcdreg_debugfs_write_file,
+	.llseek = default_llseek,
+};
+
+static ssize_t lcdreg_debugfs_read_wr(struct file *file,
+				      const char __user *user_buf,
+				      size_t count, loff_t *ppos)
+{
+	struct lcdreg *reg = file->private_data;
+	int ret;
+
+	ret = lcdreg_userbuf_to_u32(user_buf, count,
+				    &reg->debugfs_read_reg, 1);
+
+	return ret < 0 ? ret : count;
+}
+
+
+static int lcdreg_debugfs_readreg(struct lcdreg *reg)
+{
+	struct lcdreg_transfer tr = {
+		.index = 1,
+		.width = reg->debugfs_read_width,
+		.count = 1,
+	};
+	char *buf = reg->debugfs_read_result;
+	int ret;
+
+	tr.buf = kmalloc(lcdreg_bytes_per_word(tr.width), GFP_KERNEL);
+	if (!tr.buf)
+		return -ENOMEM;
+
+	mutex_lock(&reg->lock);
+	ret = lcdreg_read(reg, reg->debugfs_read_reg, &tr);
+	mutex_unlock(&reg->lock);
+	if (ret)
+		goto error_out;
+
+	switch (tr.width) {
+	case 8:
+		snprintf(buf, READ_RESULT_SIZE, "0x%02x\n", *(u8 *)tr.buf);
+		break;
+	case 16:
+		snprintf(buf, READ_RESULT_SIZE, "0x%04x\n", *(u16 *)tr.buf);
+		break;
+	case 24:
+	case 32:
+		snprintf(buf, READ_RESULT_SIZE, "0x%08x\n", *(u32 *)tr.buf);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+error_out:
+	kfree(tr.buf);
+
+	return ret;
+}
+
+static ssize_t lcdreg_debugfs_read_rd(struct file *file,
+				      char __user *user_buf,
+				      size_t count, loff_t *ppos)
+{
+	struct lcdreg *reg = file->private_data;
+	int ret;
+
+	if (*ppos < 0 || !count)
+		return -EINVAL;
+
+	if (*reg->debugfs_read_result == '\0') {
+		ret = lcdreg_debugfs_readreg(reg);
+		if (ret)
+			return ret;
+	}
+
+	if (*ppos >= strlen(reg->debugfs_read_result)) {
+		*reg->debugfs_read_result = '\0';
+		return 0;
+	}
+
+	return simple_read_from_buffer(user_buf, count, ppos,
+				       reg->debugfs_read_result,
+				       strlen(reg->debugfs_read_result));
+}
+
+static const struct file_operations lcdreg_debugfs_read_fops = {
+	.open = simple_open,
+	.read = lcdreg_debugfs_read_rd,
+	.write = lcdreg_debugfs_read_wr,
+	.llseek = default_llseek,
+};
+
+static ssize_t lcdreg_debugfs_reset_wr(struct file *file,
+				       const char __user *user_buf,
+				       size_t count, loff_t *ppos)
+{
+	struct lcdreg *reg = file->private_data;
+
+	lcdreg_reset(reg);
+
+	return count;
+}
+
+static const struct file_operations lcdreg_debugfs_reset_fops = {
+	.open = simple_open,
+	.write = lcdreg_debugfs_reset_wr,
+	.llseek = default_llseek,
+};
+
+static int lcdreg_debugfs_readwidth_set(void *data, u64 val)
+{
+	struct lcdreg *reg = data;
+
+	reg->debugfs_read_width = val;
+
+	return 0;
+}
+
+static int lcdreg_debugfs_readwidth_get(void *data, u64 *val)
+{
+	struct lcdreg *reg = data;
+
+	/*
+	* def_width is not set when lcdreg_debugfs_init() is run, it's
+	* set later by the controller init code. Hence the need for this
+	* late assignment.
+	*/
+	if (!reg->debugfs_read_width)
+		reg->debugfs_read_width = reg->def_width;
+
+	*val = reg->debugfs_read_width;
+
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(lcdreg_debugfs_readwidth_fops,
+			lcdreg_debugfs_readwidth_get,
+			lcdreg_debugfs_readwidth_set, "%llu\n");
+
+void lcdreg_debugfs_init(struct lcdreg *reg)
+{
+	if (IS_ERR_OR_NULL(lcdreg_debugfs_root))
+		return;
+
+	reg->debugfs_read_result = devm_kzalloc(reg->dev, READ_RESULT_SIZE,
+						GFP_KERNEL);
+	if (!reg->debugfs_read_result)
+		return;
+
+	reg->debugfs = debugfs_create_dir(dev_name(reg->dev),
+					  lcdreg_debugfs_root);
+	if (!reg->debugfs) {
+		dev_warn(reg->dev, "Failed to create debugfs directory\n");
+		return;
+	}
+
+	debugfs_create_file("write", 0220, reg->debugfs, reg,
+			    &lcdreg_debugfs_write_fops);
+	if (reg->read) {
+		debugfs_create_file("read_width", 0660, reg->debugfs, reg,
+				    &lcdreg_debugfs_readwidth_fops);
+		debugfs_create_file("read", 0660, reg->debugfs, reg,
+				    &lcdreg_debugfs_read_fops);
+	}
+	if (reg->reset) {
+		debugfs_create_file("reset", 0220, reg->debugfs, reg,
+				    &lcdreg_debugfs_reset_fops);
+	}
+}
+
+void lcdreg_debugfs_exit(struct lcdreg *reg)
+{
+	debugfs_remove_recursive(reg->debugfs);
+}
+
+static int lcdreg_debugfs_module_init(void)
+{
+	lcdreg_debugfs_root = debugfs_create_dir("lcdreg", NULL);
+	if (!lcdreg_debugfs_root)
+		pr_warn("lcdreg: Failed to create debugfs root\n");
+
+	return 0;
+}
+module_init(lcdreg_debugfs_module_init);
+
+static void lcdreg_debugfs_module_exit(void)
+{
+	debugfs_remove_recursive(lcdreg_debugfs_root);
+}
+module_exit(lcdreg_debugfs_module_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/include/drm/tinydrm/lcdreg.h b/include/drm/tinydrm/lcdreg.h
new file mode 100644
index 0000000..74e5e50
--- /dev/null
+++ b/include/drm/tinydrm/lcdreg.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2016 Noralf Trønnes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __LINUX_LCDREG_H
+#define __LINUX_LCDREG_H
+
+#include <linux/device.h>
+#include <linux/mutex.h>
+
+/**
+ * struct lcdreg_transfer - LCD register transfer
+ * @index: register index (address)
+ *         Known under the following names:
+ *         D/C (command=0, data=1)
+ *         RS (register selection: index=0, data=1)
+ *         D/I (data/index: index=0, data=1)
+ * @buf: data array to transfer
+ * @count: number of items in array
+ * @width: override default regwidth
+ */
+struct lcdreg_transfer {
+	unsigned index;
+	void *buf;
+	unsigned count;
+	unsigned width;
+};
+
+/**
+ * struct lcdreg - interface to LCD register
+ * @dev: device interface
+ * @lock: mutex for register access locking
+ * @def_width: default register width
+ * @bits_per_word_mask: Bitmask of bits per word supported by the hardware.
+ *                      The driver can emulate more word widths.
+ * @readable: register is readable
+ * @little_endian: register has little endian byte order
+ * @write: write to register
+ * @read: read from register (optional)
+ * @reset: reset controller (optional)
+ */
+struct lcdreg {
+	struct device *dev;
+	struct mutex lock;
+	unsigned def_width;
+	bool readable;
+	bool little_endian;
+	u32 bits_per_word_mask;
+#define LCDREG_BPW_MASK(bits) BIT((bits) - 1)
+
+	int (*write)(struct lcdreg *reg, unsigned regnr,
+		     struct lcdreg_transfer *transfer);
+	int (*read)(struct lcdreg *reg, unsigned regnr,
+		    struct lcdreg_transfer *transfer);
+	void (*reset)(struct lcdreg *reg);
+
+#ifdef CONFIG_DEBUG_FS
+	struct dentry *debugfs;
+	u32 debugfs_read_width;
+	u32 debugfs_read_reg;
+	char *debugfs_read_result;
+#endif
+};
+
+struct lcdreg *devm_lcdreg_init(struct device *dev, struct lcdreg *reg);
+int lcdreg_write(struct lcdreg *reg, unsigned regnr,
+		 struct lcdreg_transfer *transfer);
+int lcdreg_write_buf32(struct lcdreg *reg, unsigned regnr, const u32 *data,
+		       unsigned count);
+
+#define lcdreg_writereg(lcdreg, regnr, seq...) \
+({\
+	u32 d[] = { seq };\
+	lcdreg_write_buf32(lcdreg, regnr, d, ARRAY_SIZE(d));\
+})
+
+int lcdreg_read(struct lcdreg *reg, unsigned regnr,
+		struct lcdreg_transfer *transfer);
+int lcdreg_readreg_buf32(struct lcdreg *reg, unsigned regnr, u32 *buf,
+			 unsigned count);
+
+static inline void lcdreg_reset(struct lcdreg *reg)
+{
+	if (reg->reset)
+		reg->reset(reg);
+}
+
+static inline bool lcdreg_is_readable(struct lcdreg *reg)
+{
+	return reg->readable;
+}
+
+static inline unsigned lcdreg_bytes_per_word(unsigned bits_per_word)
+{
+	if (bits_per_word <= 8)
+		return 1;
+	else if (bits_per_word <= 16)
+		return 2;
+	else /* bits_per_word <= 32 */
+		return 4;
+}
+
+static inline bool lcdreg_bpw_supported(struct lcdreg *reg, unsigned bpw)
+{
+	return LCDREG_BPW_MASK(bpw) & reg->bits_per_word_mask;
+}
+
+#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
+static inline void lcdreg_dbg_transfer_buf(struct lcdreg_transfer *tr)
+{
+	int groupsize = lcdreg_bytes_per_word(tr->width);
+	size_t len = min_t(size_t, 32, tr->count * groupsize);
+
+	print_hex_dump_debug("    buf=", DUMP_PREFIX_NONE, 32, groupsize,
+			     tr->buf, len, false);
+}
+#else
+static inline void lcdreg_dbg_transfer_buf(struct lcdreg_transfer *tr) { }
+#endif /* DEBUG || CONFIG_DYNAMIC_DEBUG */
+
+#endif /* __LINUX_LCDREG_H */
-- 
2.2.2

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  parent reply	other threads:[~2016-03-16 13:40 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-16 13:34 [RFC 0/5] drm: Add support for tiny LCD displays Noralf Trønnes
2016-03-16 13:34 ` [RFC 1/5] drm: Add DRM " Noralf Trønnes
2016-03-16 15:11   ` Daniel Vetter
2016-03-17 21:51     ` Noralf Trønnes
2016-03-18 17:47       ` Daniel Vetter
2016-03-23 17:07         ` Noralf Trønnes
2016-03-23 17:28           ` Daniel Vetter
2016-03-25 10:41             ` Noralf Trønnes
2016-03-29  7:27               ` Daniel Vetter
2016-04-01 19:15                 ` Noralf Trønnes
2016-04-12 10:40                   ` Daniel Vetter
2016-03-23 17:37   ` David Herrmann
2016-03-25 19:39     ` Noralf Trønnes
2016-03-16 13:34 ` Noralf Trønnes [this message]
2016-03-16 13:34 ` [RFC 3/5] drm/tinydrm/lcdreg: Add SPI support Noralf Trønnes
2016-03-16 13:34 ` [RFC 4/5] drm/tinydrm: Add mipi-dbi support Noralf Trønnes
2016-03-16 13:34 ` [RFC 5/5] drm/tinydrm: Add support for several Adafruit TFT displays Noralf Trønnes
2016-03-16 14:50 ` [RFC 0/5] drm: Add support for tiny LCD displays Daniel Vetter
2016-03-16 18:26 ` Eric Anholt
2016-03-17 22:00   ` Noralf Trønnes
2016-03-18 17:48     ` Daniel Vetter
2016-03-26 19:11       ` Noralf Trønnes
2016-03-29  7:29         ` Daniel Vetter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1458135259-31050-3-git-send-email-noralf@tronnes.org \
    --to=noralf@tronnes.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=thomas.petazzoni@free-electrons.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.