All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Hackmann <ghackmann@google.com>
To: dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org
Cc: konkers@google.com
Subject: [RFC 3/4] video: adf: add display core helper
Date: Wed, 28 Aug 2013 18:51:20 -0700	[thread overview]
Message-ID: <1377741081-30189-4-git-send-email-ghackmann@google.com> (raw)
In-Reply-To: <1377741081-30189-1-git-send-email-ghackmann@google.com>

Optional helper which implements some ADF interface ops for displays
using the Display Core framework

Signed-off-by: Greg Hackmann <ghackmann@google.com>
---
 drivers/video/adf/Kconfig       |   5 ++
 drivers/video/adf/Makefile      |   2 +
 drivers/video/adf/adf.c         |  28 ++++++++-
 drivers/video/adf/adf.h         |   1 +
 drivers/video/adf/adf_display.c | 123 ++++++++++++++++++++++++++++++++++++++++
 include/video/adf_display.h     |  31 ++++++++++
 6 files changed, 189 insertions(+), 1 deletion(-)
 create mode 100644 drivers/video/adf/adf_display.c
 create mode 100644 include/video/adf_display.h

diff --git a/drivers/video/adf/Kconfig b/drivers/video/adf/Kconfig
index 0b64408..30b0611 100644
--- a/drivers/video/adf/Kconfig
+++ b/drivers/video/adf/Kconfig
@@ -3,3 +3,8 @@ menuconfig ADF
 	depends on SW_SYNC
 	depends on DMA_SHARED_BUFFER
 	tristate "Atomic Display Framework"
+
+menuconfig ADF_DISPLAY_CORE
+	depends on ADF
+	depends on DISPLAY_CORE
+	tristate "Helper for implementing ADF interface ops with Display Core devices"
diff --git a/drivers/video/adf/Makefile b/drivers/video/adf/Makefile
index 2af5f79..30164ee 100644
--- a/drivers/video/adf/Makefile
+++ b/drivers/video/adf/Makefile
@@ -8,3 +8,5 @@ obj-$(CONFIG_ADF) += adf.o \
 	adf_sysfs.o
 
 obj-$(CONFIG_COMPAT) += adf_fops32.o
+
+obj-$(CONFIG_ADF_DISPLAY_CORE) += adf_display.o
diff --git a/drivers/video/adf/adf.c b/drivers/video/adf/adf.c
index 5dc04af..b3b57dd 100644
--- a/drivers/video/adf/adf.c
+++ b/drivers/video/adf/adf.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2013 Google, Inc.
- * adf_modeinfo_set_name modified from drm_mode_set_name in
+ * adf_modeinfo_{set_name,set_vrefresh} modified from
  * drivers/gpu/drm/drm_modes.c
  *
  * This software is licensed under the terms of the GNU General Public
@@ -966,6 +966,32 @@ void adf_modeinfo_set_name(struct drm_mode_modeinfo *mode)
 		 interlaced ? "i" : "");
 }
 
+void adf_modeinfo_set_vrefresh(struct drm_mode_modeinfo *mode)
+{
+	int refresh = 0;
+	unsigned int calc_val;
+
+	if (mode->vrefresh > 0)
+		return;
+	else if (mode->htotal > 0 && mode->vtotal > 0) {
+		int vtotal;
+		vtotal = mode->vtotal;
+		/* work out vrefresh the value will be x1000 */
+		calc_val = (mode->clock * 1000);
+		calc_val /= mode->htotal;
+		refresh = (calc_val + vtotal / 2) / vtotal;
+
+		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+			refresh *= 2;
+		if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
+			refresh /= 2;
+		if (mode->vscan > 1)
+			refresh /= mode->vscan;
+
+		mode->vrefresh = refresh;
+	}
+}
+
 static void __exit adf_exit(void);
 static int __init adf_init(void)
 {
diff --git a/drivers/video/adf/adf.h b/drivers/video/adf/adf.h
index acad631..5f7260d 100644
--- a/drivers/video/adf/adf.h
+++ b/drivers/video/adf/adf.h
@@ -44,5 +44,6 @@ struct adf_event_refcount *adf_obj_find_refcount(struct adf_obj *obj,
 		enum adf_event_type type);
 
 void adf_modeinfo_set_name(struct drm_mode_modeinfo *mode);
+void adf_modeinfo_set_vrefresh(struct drm_mode_modeinfo *mode);
 
 #endif /* __ADF_H */
diff --git a/drivers/video/adf/adf_display.c b/drivers/video/adf/adf_display.c
new file mode 100644
index 0000000..c87f6a5
--- /dev/null
+++ b/drivers/video/adf/adf_display.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2013 Google, Inc.
+ * adf_modeinfo_from_videomode modified from drm_display_mode_from_videomode in
+ * drivers/gpu/drm/drm_modes.c
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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/slab.h>
+#include <video/adf.h>
+#include <video/adf_display.h>
+
+#include "adf.h"
+
+/**
+ * adf_display_entity_screen_size - handle the screen_size interface op
+ * by querying a display core entity
+ */
+int adf_display_entity_screen_size(struct display_entity *display,
+		u16 *width_mm, u16 *height_mm)
+{
+	unsigned int cdf_width, cdf_height;
+	int ret;
+
+	ret = display_entity_get_size(display, &cdf_width, &cdf_height);
+	if (!ret) {
+		*width_mm = cdf_width;
+		*height_mm = cdf_height;
+	}
+	return ret;
+}
+EXPORT_SYMBOL(adf_display_entity_screen_size);
+
+/**
+ * adf_display_entity_notify_connected - notify ADF of a display core entity
+ * being connected to an interface
+ *
+ * @intf: the interface
+ * @display: the display
+ *
+ * adf_display_entity_notify_connected() wraps adf_hotplug_notify_connected()
+ * but does not require a hardware modelist.  @display is queried to
+ * automatically populate the modelist.
+ *
+ * Returns 0 on success or error code (<0) on failure.
+ */
+int adf_display_entity_notify_connected(struct adf_interface *intf,
+		struct display_entity *display)
+{
+	const struct videomode *vmodes;
+	struct drm_mode_modeinfo *dmodes = NULL;
+	int ret;
+	size_t i, n_modes;
+
+	ret = display_entity_get_modes(display, &vmodes);
+	if (ret < 0)
+		return ret;
+
+	n_modes = ret;
+	if (n_modes) {
+		dmodes = kzalloc(n_modes * sizeof(dmodes[0]), GFP_KERNEL);
+		if (!dmodes)
+			return -ENOMEM;
+	}
+
+	for (i = 0; i < n_modes; i++)
+		adf_modeinfo_from_videomode(&vmodes[i], &dmodes[i]);
+
+	ret = adf_hotplug_notify_connected(intf, dmodes, n_modes);
+	kfree(dmodes);
+	return ret;
+}
+EXPORT_SYMBOL(adf_display_entity_notify_connected);
+
+/**
+ * adf_modeinfo_from_videomode - copy a display core videomode into
+ * an equivalent &struct drm_mode_modeinfo
+ *
+ * @vm: the input display core videomode
+ * @dmode: the output DRM/ADF modeinfo
+ */
+void adf_modeinfo_from_videomode(const struct videomode *vm,
+		struct drm_mode_modeinfo *dmode)
+{
+	memset(dmode, 0, sizeof(*dmode));
+
+	dmode->hdisplay = vm->hactive;
+	dmode->hsync_start = dmode->hdisplay + vm->hfront_porch;
+	dmode->hsync_end = dmode->hsync_start + vm->hsync_len;
+	dmode->htotal = dmode->hsync_end + vm->hback_porch;
+
+	dmode->vdisplay = vm->vactive;
+	dmode->vsync_start = dmode->vdisplay + vm->vfront_porch;
+	dmode->vsync_end = dmode->vsync_start + vm->vsync_len;
+	dmode->vtotal = dmode->vsync_end + vm->vback_porch;
+
+	dmode->clock = vm->pixelclock / 1000;
+
+	if (vm->flags & DISPLAY_FLAGS_HSYNC_HIGH)
+		dmode->flags |= DRM_MODE_FLAG_PHSYNC;
+	else if (vm->flags & DISPLAY_FLAGS_HSYNC_LOW)
+		dmode->flags |= DRM_MODE_FLAG_NHSYNC;
+	if (vm->flags & DISPLAY_FLAGS_VSYNC_HIGH)
+		dmode->flags |= DRM_MODE_FLAG_PVSYNC;
+	else if (vm->flags & DISPLAY_FLAGS_VSYNC_LOW)
+		dmode->flags |= DRM_MODE_FLAG_NVSYNC;
+	if (vm->flags & DISPLAY_FLAGS_INTERLACED)
+		dmode->flags |= DRM_MODE_FLAG_INTERLACE;
+	if (vm->flags & DISPLAY_FLAGS_DOUBLESCAN)
+		dmode->flags |= DRM_MODE_FLAG_DBLSCAN;
+
+	adf_modeinfo_set_name(dmode);
+	adf_modeinfo_set_vrefresh(dmode);
+}
+EXPORT_SYMBOL_GPL(adf_modeinfo_from_videomode);
diff --git a/include/video/adf_display.h b/include/video/adf_display.h
new file mode 100644
index 0000000..af8cb6b
--- /dev/null
+++ b/include/video/adf_display.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2013 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#ifndef _VIDEO_ADF_DISPLAY_H
+#define _VIDEO_ADF_DISPLAY_H
+
+#include <video/adf.h>
+#include <video/display.h>
+#include <video/videomode.h>
+
+int adf_display_entity_screen_size(struct display_entity *display,
+		u16 *width_mm, u16 *height_mm);
+
+int adf_display_entity_notify_connected(struct adf_interface *intf,
+		struct display_entity *display);
+
+void adf_modeinfo_from_videomode(const struct videomode *vm,
+		struct drm_mode_modeinfo *dmode);
+
+#endif /* _VIDEO_ADF_DISPLAY_H */
-- 
1.8.0

  parent reply	other threads:[~2013-08-29  1:51 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-08-29  1:51 [RFC 0/4] Atomic Display Framework Greg Hackmann
2013-08-29  1:51 ` [RFC 1/4] video: Add generic display entity core Greg Hackmann
2013-08-29  1:51 ` [RFC 2/4] video: add atomic display framework Greg Hackmann
2013-08-29  1:51 ` Greg Hackmann [this message]
2013-08-29  1:51 ` [RFC 4/4] video: adf: add memblock helper Greg Hackmann
2013-08-29  3:51 ` [RFC 0/4] Atomic Display Framework Rob Clark
2013-08-29  7:01   ` [Linaro-mm-sig] " Daniel Vetter
2013-08-29  7:58     ` Ville Syrjälä
2013-08-29  8:52       ` Damien Lespiau
2013-08-29 12:59       ` Rob Clark
2013-08-29 12:25     ` Rob Clark
2013-08-29  7:36   ` Ville Syrjälä
2013-08-29 12:54     ` Rob Clark
2013-08-29 23:34       ` Greg Hackmann
2013-08-30 14:00         ` Rob Clark
2013-08-30 14:11           ` Ville Syrjälä
2013-09-02  7:39           ` Daniel Vetter
2013-09-02 13:19             ` Rob Clark
2013-09-02 15:26               ` Alex Deucher
2013-08-29 23:26     ` Greg Hackmann
2013-08-30 13:55       ` Rob Clark
2013-08-30 14:01       ` Ville Syrjälä

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=1377741081-30189-4-git-send-email-ghackmann@google.com \
    --to=ghackmann@google.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=konkers@google.com \
    --cc=linaro-mm-sig@lists.linaro.org \
    /path/to/YOUR_REPLY

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

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is 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.