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
next prev 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox