* [PATCH 1/2] of: add helper to parse display specs
From: Steffen Trumtrar @ 2012-09-24 15:35 UTC (permalink / raw)
To: devicetree-discuss
Cc: Rob Herring, linux-fbdev, dri-devel, Laurent Pinchart, kernel,
linux-media, Hans Verkuil, Tomi Valkeinen, Steffen Trumtrar
In-Reply-To: <1348500924-8551-1-git-send-email-s.trumtrar@pengutronix.de>
Parse a display-node with timings and hardware-specs from devictree.
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
Documentation/devicetree/bindings/video/display | 208 +++++++++++++++++++++++
drivers/of/Kconfig | 5 +
drivers/of/Makefile | 1 +
drivers/of/of_display.c | 157 +++++++++++++++++
include/linux/display.h | 85 +++++++++
include/linux/of_display.h | 15 ++
6 files changed, 471 insertions(+)
create mode 100644 Documentation/devicetree/bindings/video/display
create mode 100644 drivers/of/of_display.c
create mode 100644 include/linux/display.h
create mode 100644 include/linux/of_display.h
diff --git a/Documentation/devicetree/bindings/video/display b/Documentation/devicetree/bindings/video/display
new file mode 100644
index 0000000..722766a
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/display
@@ -0,0 +1,208 @@
+display bindings
+=========
+
+display-node
+------------
+
+required properties:
+ - none
+
+optional properties:
+ - default-timing: the default timing value
+ - width-mm, height-mm: Display dimensions in mm
+ - hsync-active-high (bool): Hsync pulse is active high
+ - vsync-active-high (bool): Vsync pulse is active high
+ - de-active-high (bool): Data-Enable pulse is active high
+ - pixelclk-inverted (bool): pixelclock is inverted
+ - pixel-per-clk
+ - link-width: number of channels (e.g. LVDS)
+ - bpp: bits-per-pixel
+
+timings-subnode
+---------------
+
+required properties:
+subnodes that specify
+ - hactive, vactive: Display resolution
+ - hfront-porch, hback-porch, hsync-len: Horizontal Display timing parameters
+ in pixels
+ vfront-porch, vback-porch, vsync-len: Vertical display timing parameters in
+ lines
+ - clock: displayclock in Hz
+
+There are different ways of describing a display and its capabilities. The devicetree
+representation corresponds to the one commonly found in datasheets for displays.
+The description of the display and its timing is split in two parts: first the display
+properties like size in mm and (optionally) multiple subnodes with the supported timings.
+If a display supports multiple signal timings, the default-timing can be specified.
+
+Example:
+
+ display@0 {
+ width-mm = <800>;
+ height-mm = <480>;
+ default-timing = <&timing0>;
+ timings {
+ timing0: timing@0 {
+ /* 1920x1080p24 */
+ clock = <52000000>;
+ hactive = <1920>;
+ vactive = <1080>;
+ hfront-porch = <25>;
+ hback-porch = <25>;
+ hsync-len = <25>;
+ vback-porch = <2>;
+ vfront-porch = <2>;
+ vsync-len = <2>;
+ hsync-active-high;
+ };
+ };
+ };
+
+Every property also supports the use of ranges, so the commonly used datasheet
+description with <min typ max>-tuples can be used.
+
+Example:
+
+ timing1: timing@1 {
+ /* 1920x1080p24 */
+ clock = <148500000>;
+ hactive = <1920>;
+ vactive = <1080>;
+ hsync-len = <0 44 60>;
+ hfront-porch = <80 88 95>;
+ hback-porch = <100 148 160>;
+ vfront-porch = <0 4 6>;
+ vback-porch = <0 36 50>;
+ vsync-len = <0 5 6>;
+ };
+
+The "display"-property in a connector-node (e.g. hdmi, ldb,...) is used to connect
+the display to that driver.
+of_display expects a phandle, that specifies the display-node, in that property.
+
+Example:
+
+ hdmi@00120000 {
+ status = "okay";
+ display = <&acme>;
+ };
+
+Usage in backend
+========
+
+A backend driver may choose to use the display directly and convert the timing
+ranges to a suitable mode. Or it may just use the conversion of the display timings
+to the required mode via the generic videomode struct.
+
+ dtb
+ |
+ | of_get_display
+ ↓
+ struct display
+ |
+ | videomode_from_timings
+ ↓
+ --- struct videomode ---
+ | |
+ videomode_to_displaymode | | videomode_to_fb_videomode
+ ↓ ↓
+ drm_display_mode fb_videomode
+
+
+Conversion to videomode
+===========+
+As device drivers normally work with some kind of video mode, the timings can be
+converted (may be just a simple copying of the typical value) to a generic videomode
+structure which then can be converted to the according mode used by the backend.
+
+Supported modes
+=======+
+The generic videomode read in by the driver can be converted to the following
+modes with the following parameters
+
+struct fb_videomode
+=========+
+ +----------+---------------------------------------------+----------+-------+
+ | | ↑ | | |
+ | | |upper_margin | | |
+ | | ↓ | | |
+ +----------###############################################----------+-------+
+ | # ↑ # | |
+ | # | # | |
+ | # | # | |
+ | # | # | |
+ | left # | # right | hsync |
+ | margin # | xres # margin | len |
+ |<-------->#<---------------+--------------------------->#<-------->|<----->|
+ | # | # | |
+ | # | # | |
+ | # | # | |
+ | # |yres # | |
+ | # | # | |
+ | # | # | |
+ | # | # | |
+ | # | # | |
+ | # | # | |
+ | # | # | |
+ | # | # | |
+ | # | # | |
+ | # ↓ # | |
+ +----------###############################################----------+-------+
+ | | ↑ | | |
+ | | |lower_margin | | |
+ | | ↓ | | |
+ +----------+---------------------------------------------+----------+-------+
+ | | ↑ | | |
+ | | |vsync_len | | |
+ | | ↓ | | |
+ +----------+---------------------------------------------+----------+-------+
+
+clock in nanoseconds
+
+struct drm_display_mode
+===========+
+ +----------+---------------------------------------------+----------+-------+
+ | | | | | ↑
+ | | | | | |
+ | | | | | |
+ +----------###############################################----------+-------+ |
+ | # ↑ ↑ ↑ # | | |
+ | # | | | # | | |
+ | # | | | # | | |
+ | # | | | # | | |
+ | # | | | # | | |
+ | # | | | hdisplay # | | |
+ | #<--+--------------------+-------------------># | | |
+ | # | | | # | | |
+ | # |vsync_start | # | | |
+ | # | | | # | | |
+ | # | |vsync_end | # | | |
+ | # | | |vdisplay # | | |
+ | # | | | # | | |
+ | # | | | # | | |
+ | # | | | # | | | vtotal
+ | # | | | # | | |
+ | # | | | hsync_start # | | |
+ | #<--+---------+----------+------------------------------>| | |
+ | # | | | # | | |
+ | # | | | hsync_end # | | |
+ | #<--+---------+----------+-------------------------------------->| |
+ | # | | ↓ # | | |
+ +----------####|#########|################################----------+-------+ |
+ | | | | | | | |
+ | | | | | | | |
+ | | ↓ | | | | |
+ +----------+-------------+-------------------------------+----------+-------+ |
+ | | | | | | |
+ | | | | | | |
+ | | ↓ | | | ↓
+ +----------+---------------------------------------------+----------+-------+
+ htotal
+ <------------------------------------------------------------------------->
+
+clock in kilohertz
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index dfba3e6..a4e3074 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -83,4 +83,9 @@ config OF_MTD
depends on MTD
def_bool y
+config OF_DISPLAY
+ def_bool y
+ help
+ helper to parse displays from the devicetree
+
endmenu # OF
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index e027f44..0756bee 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_OF_MDIO) += of_mdio.o
obj-$(CONFIG_OF_PCI) += of_pci.o
obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o
obj-$(CONFIG_OF_MTD) += of_mtd.o
+obj-$(CONFIG_OF_DISPLAY) += of_display.o
diff --git a/drivers/of/of_display.c b/drivers/of/of_display.c
new file mode 100644
index 0000000..632a351
--- /dev/null
+++ b/drivers/of/of_display.c
@@ -0,0 +1,157 @@
+/*
+ * OF helpers for parsing display timings
+ *
+ * Copyright (c) 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>, Pengutronix
+ *
+ * based on of_videomode.c by Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * This file is released under the GPLv2
+ */
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/display.h>
+#include <linux/of_display.h>
+#include <linux/fb.h>
+
+/* every signal_timing can be specified with either
+ * just the typical value or a range consisting of
+ * min/typ/max.
+ * This function helps handling this
+ */
+static int of_display_parse_property(struct device_node *np, char *name,
+ struct timing_entry *result)
+{
+ struct property *prop;
+ int length;
+ int cells;
+ int ret;
+
+ prop = of_find_property(np, name, &length);
+ if (!prop) {
+ pr_err("%s: could not find property %s\n", __func__,
+ name);
+ return -EINVAL;
+ }
+
+ cells = length / sizeof(u32);
+
+ if (cells = 1)
+ ret = of_property_read_u32_array(np, name, &result->typ, cells);
+ else if (cells = 3)
+ ret = of_property_read_u32_array(np, name, &result->min, cells);
+ else {
+ pr_err("%s: illegal timing specification in %s\n", __func__,
+ name);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+struct display *of_get_display(struct device_node *np)
+{
+ struct device_node *display_np;
+ struct device_node *timing_np;
+ struct device_node *timings;
+ struct display *disp;
+ char *default_timing;
+
+ if (!np) {
+ pr_err("%s: no devicenode given\n", __func__);
+ return NULL;
+ }
+
+ display_np = of_parse_phandle(np, "display", 0);
+
+ if (!display_np) {
+ pr_err("%s: could not find display node\n", __func__);
+ return NULL;
+ }
+
+ disp = kmalloc(sizeof(struct display *), GFP_KERNEL);
+
+ memset(disp, 0, sizeof(struct display *));
+
+ of_property_read_u32(display_np, "width-mm", &disp->width_mm);
+ of_property_read_u32(display_np, "height-mm", &disp->height_mm);
+
+ timing_np = of_parse_phandle(display_np, "default-timing", 0);
+
+ if (!timing_np) {
+ pr_info("%s: no default-timing specified\n", __func__);
+ timing_np = of_find_node_by_name(np, "timing");
+ }
+
+ if (!timing_np) {
+ pr_info("%s: no timing specifications given\n", __func__);
+ return disp;
+ }
+
+ default_timing = (char *)timing_np->full_name;
+
+ timings = of_find_node_by_name(np, "timings");
+
+ disp->num_timings = 0;
+
+ disp->timings = kmalloc(sizeof(struct signal_timing *), GFP_KERNEL);
+
+ for_each_child_of_node(timings, timing_np) {
+ struct signal_timing *st;
+ int ret;
+
+ st = kmalloc(sizeof(struct signal_timing *), GFP_KERNEL);
+ disp->timings[disp->num_timings] = kmalloc(sizeof(struct signal_timing *), GFP_KERNEL);
+
+ ret |= of_display_parse_property(timing_np, "hback-porch", &st->hback_porch);
+ ret |= of_display_parse_property(timing_np, "hfront-porch", &st->hfront_porch);
+ ret |= of_display_parse_property(timing_np, "hactive", &st->hactive);
+ ret |= of_display_parse_property(timing_np, "hsync-len", &st->hsync_len);
+ ret |= of_display_parse_property(timing_np, "vback-porch", &st->vback_porch);
+ ret |= of_display_parse_property(timing_np, "vfront-porch", &st->vfront_porch);
+ ret |= of_display_parse_property(timing_np, "vactive", &st->vactive);
+ ret |= of_display_parse_property(timing_np, "vsync-len", &st->vsync_len);
+ ret |= of_display_parse_property(timing_np, "clock", &st->pixelclock);
+
+ if (strcmp(default_timing, timing_np->full_name) = 0)
+ disp->default_timing = disp->num_timings;
+
+ disp->timings[disp->num_timings] = st;
+ disp->num_timings++;
+ }
+
+ disp->vsync_pol_active_high = of_property_read_bool(display_np, "vsync-active-high");
+ disp->hsync_pol_active_high = of_property_read_bool(display_np, "hsync-active-high");
+ disp->de_pol_active_high = of_property_read_bool(display_np, "de-active-high");
+ disp->pixelclk_pol_inverted = of_property_read_bool(display_np, "pixelclk-inverted");
+ of_property_read_u32(display_np, "pixel-per-clk", &disp->if_pixel_per_clk);
+ of_property_read_u32(display_np, "link-width", &disp->if_link_width);
+ of_property_read_u32(display_np, "bpp", &disp->if_bpp);
+
+
+ pr_info("%s: got %d timings. Using #%d as default\n", __func__, disp->num_timings, disp->default_timing + 1);
+
+ return disp;
+}
+EXPORT_SYMBOL(of_get_display);
+
+int of_display_exists(struct device_node *np)
+{
+ struct device_node *display_np;
+ struct device_node *timing_np;
+
+ if (!np)
+ return -EINVAL;
+
+ display_np = of_parse_phandle(np, "display", 0);
+
+ if (!display_np)
+ return -EINVAL;
+
+ timing_np = of_parse_phandle(np, "default-timing", 0);
+
+ if (timing_np)
+ return 0;
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(of_display_exists);
diff --git a/include/linux/display.h b/include/linux/display.h
new file mode 100644
index 0000000..bb84ed9
--- /dev/null
+++ b/include/linux/display.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ *
+ * Hardware-description of a display
+ *
+ * This file is released under the GPLv2
+ */
+
+#ifndef __LINUX_DISPLAY_H
+#define __LINUX_DISPLAY_H
+
+#include <linux/list.h>
+
+#define OF_DEFAULT_TIMING -1
+
+struct display {
+ u32 width_mm;
+ u32 height_mm;
+ unsigned int num_timings;
+ unsigned int default_timing;
+
+ struct signal_timing **timings;
+
+ bool vsync_pol_active_high;
+ bool hsync_pol_active_high;
+ bool de_pol_active_high;
+ bool pixelclk_pol_inverted;
+
+ u32 if_bpp;
+ u32 if_link_width;
+ u32 if_pixel_per_clk;
+};
+
+struct timing_entry {
+ u32 min;
+ u32 typ;
+ u32 max;
+};
+
+struct signal_timing {
+ struct timing_entry pixelclock;
+
+ struct timing_entry hactive;
+ struct timing_entry hfront_porch;
+ struct timing_entry hback_porch;
+ struct timing_entry hsync_len;
+
+ struct timing_entry vactive;
+ struct timing_entry vfront_porch;
+ struct timing_entry vback_porch;
+ struct timing_entry vsync_len;
+};
+
+/* placeholder function until ranges are really needed */
+static inline u32 signal_timing_get_value(struct timing_entry *te, int index)
+{
+ return te->typ;
+}
+
+static inline void timings_release(struct display *disp)
+{
+ int i;
+ for (i = 0; i < disp->num_timings; i++)
+ kfree(disp->timings[i]);
+}
+
+static inline void display_release(struct display *disp)
+{
+ timings_release(disp);
+ kfree(disp->timings);
+}
+
+static inline struct signal_timing *display_get_timing(struct display *disp, int index)
+{
+ if (disp->num_timings >= index)
+ return disp->timings[index];
+ else
+ return NULL;
+}
+
+
+int of_display_exists(struct device_node *np);
+struct display *of_get_display(struct device_node *np);
+
+#endif /* __LINUX_DISPLAY_H */
diff --git a/include/linux/of_display.h b/include/linux/of_display.h
new file mode 100644
index 0000000..500ff94
--- /dev/null
+++ b/include/linux/of_display.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ *
+ * This file is released under the GPLv2
+ */
+
+#ifndef __LINUX_OF_DISPLAY_H
+#define __LINUX_OF_DISPALY_H
+
+#include <linux/fb.h>
+
+struct display *of_get_display(struct device_node *np);
+int of_display_exists(struct device_node *np);
+
+#endif
--
1.7.10.4
^ permalink raw reply related
* [PATCH 2/2] video: add generic videomode description
From: Steffen Trumtrar @ 2012-09-24 15:35 UTC (permalink / raw)
To: devicetree-discuss
Cc: Rob Herring, linux-fbdev, dri-devel, Laurent Pinchart, kernel,
linux-media, Hans Verkuil, Tomi Valkeinen, Steffen Trumtrar
In-Reply-To: <1348500924-8551-1-git-send-email-s.trumtrar@pengutronix.de>
Backend-independent videomode. At the moment this is not very different
from fb_mode or drm_mode.
It is supposed to be a generic description of videomodes and conversion
step to the desired backend video mode representation.
At the moment, only really makes sense when used with of_display
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
drivers/video/Makefile | 1 +
drivers/video/videomode.c | 146 +++++++++++++++++++++++++++++++++++++++++++++
include/linux/videomode.h | 38 ++++++++++++
3 files changed, 185 insertions(+)
create mode 100644 drivers/video/videomode.c
create mode 100644 include/linux/videomode.h
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index ee8dafb..6a02fe0 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -170,3 +170,4 @@ obj-$(CONFIG_FB_VIRTUAL) += vfb.o
#video output switch sysfs driver
obj-$(CONFIG_VIDEO_OUTPUT_CONTROL) += output.o
+obj-y += videomode.o
diff --git a/drivers/video/videomode.c b/drivers/video/videomode.c
new file mode 100644
index 0000000..b118d00
--- /dev/null
+++ b/drivers/video/videomode.c
@@ -0,0 +1,146 @@
+/*
+ * generic videomode helper
+ *
+ * Copyright (c) 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>, Pengutronix
+ *
+ * This file is released under the GPLv2
+ */
+#include <linux/of.h>
+#include <linux/fb.h>
+#include <linux/slab.h>
+#include <drm/drm_mode.h>
+#include <linux/display.h>
+#include <linux/videomode.h>
+
+struct videomode *videomode_from_display(struct display *disp, int index)
+{
+ struct videomode *vm;
+ struct signal_timing *st;
+
+ vm = kmalloc(sizeof(struct videomode *), GFP_KERNEL);
+
+ if (!vm)
+ return NULL;
+
+ st = display_get_timing(disp, index);
+
+ vm->pixelclock = signal_timing_get_value(&st->pixelclock, 0);
+ vm->hactive = signal_timing_get_value(&st->hactive, 0);
+ vm->hfront_porch = signal_timing_get_value(&st->hfront_porch, 0);
+ vm->hback_porch = signal_timing_get_value(&st->hback_porch, 0);
+ vm->hsync_len = signal_timing_get_value(&st->hsync_len, 0);
+
+ vm->vactive = signal_timing_get_value(&st->vactive, 0);
+ vm->vfront_porch = signal_timing_get_value(&st->vfront_porch, 0);
+ vm->vback_porch = signal_timing_get_value(&st->vback_porch, 0);
+ vm->vsync_len = signal_timing_get_value(&st->vsync_len, 0);
+
+ vm->vah = disp->vsync_pol_active_high;
+ vm->hah = disp->hsync_pol_active_high;
+
+ return vm;
+}
+
+#if defined(CONFIG_DRM)
+int videomode_to_display_mode(struct videomode *vm, struct drm_display_mode *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->vtotal + vm->vback_porch;
+
+ dmode->clock = vm->pixelclock / 1000;
+
+ if (vm->hah)
+ dmode->flags |= DRM_MODE_FLAG_PHSYNC;
+ else
+ dmode->flags |= DRM_MODE_FLAG_NHSYNC;
+ if (vm->vah)
+ dmode->flags |= DRM_MODE_FLAG_PVSYNC;
+ else
+ dmode->flags |= DRM_MODE_FLAG_NVSYNC;
+ if (vm->interlaced)
+ dmode->flags |= DRM_MODE_FLAG_INTERLACE;
+ if (vm->doublescan)
+ dmode->flags |= DRM_MODE_FLAG_DBLSCAN;
+ drm_mode_set_name(dmode);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(videomode_to_display_mode);
+#else
+int videomode_to_displaymode(struct videomode *vm, struct drm_display_mode *dmode)
+{
+ return 0;
+}
+#endif
+
+int videomode_to_fb_videomode(struct videomode *vm, struct fb_videomode *fbmode)
+{
+ memset(fbmode, 0, sizeof(*fbmode));
+
+ fbmode->xres = vm->hactive;
+ fbmode->left_margin = vm->hback_porch;
+ fbmode->right_margin = vm->hfront_porch;
+ fbmode->hsync_len = vm->hsync_len;
+
+ fbmode->yres = vm->vactive;
+ fbmode->upper_margin = vm->vback_porch;
+ fbmode->lower_margin = vm->vfront_porch;
+ fbmode->vsync_len = vm->vsync_len;
+
+ fbmode->pixclock = KHZ2PICOS(vm->pixelclock) / 1000;
+
+ if (vm->hah)
+ fbmode->sync |= FB_SYNC_HOR_HIGH_ACT;
+ if (vm->vah)
+ fbmode->sync |= FB_SYNC_VERT_HIGH_ACT;
+ if (vm->interlaced)
+ fbmode->vmode |= FB_VMODE_INTERLACED;
+ if (vm->doublescan)
+ fbmode->vmode |= FB_VMODE_DOUBLE;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(videomode_to_fb_videomode);
+
+int of_get_display_mode(struct device_node *np, struct drm_display_mode *dmode, int index)
+{
+ struct videomode *vm;
+ struct display *disp;
+
+ disp = of_get_display(np);
+
+ if (!disp) {
+ pr_err("%s: no display specified\n", __func__);
+ return -EINVAL;
+ }
+
+ if (index = OF_DEFAULT_TIMING)
+ index = disp->default_timing;
+
+ vm = videomode_from_display(disp, index);
+
+ if (!vm) {
+ pr_err("%s: could not get videomode %d\n", __func__, index);
+ return -EINVAL;
+ }
+
+ videomode_to_display_mode(vm, dmode);
+
+ pr_info("%s: got %dx%d display mode from %s\n", __func__, vm->hactive, vm->vactive, np->name);
+
+ display_release(disp);
+ kfree(vm);
+
+ return 0;
+
+}
+EXPORT_SYMBOL_GPL(of_get_display_mode);
diff --git a/include/linux/videomode.h b/include/linux/videomode.h
new file mode 100644
index 0000000..100c88b
--- /dev/null
+++ b/include/linux/videomode.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ *
+ * generic videomode description
+ *
+ * This file is released under the GPLv2
+ */
+
+#ifndef __LINUX_VIDEOMODE_H
+#define __LINUX_VIDEOMODE_H
+
+#include <drm/drmP.h>
+
+struct videomode {
+ u32 pixelclock;
+ u32 refreshrate;
+
+ u32 hactive;
+ u32 hfront_porch;
+ u32 hback_porch;
+ u32 hsync_len;
+
+ u32 vactive;
+ u32 vfront_porch;
+ u32 vback_porch;
+ u32 vsync_len;
+
+ bool hah;
+ bool vah;
+ bool interlaced;
+ bool doublescan;
+
+};
+
+int videomode_to_display_mode(struct videomode *vm, struct drm_display_mode *dmode);
+int videomode_to_fb_videomode(struct videomode *vm, struct fb_videomode *fbmode);
+int of_get_display_mode(struct device_node *np, struct drm_display_mode *dmode, int index);
+#endif /* __LINUX_VIDEOMODE_H */
--
1.7.10.4
^ permalink raw reply related
* Re: [PATCH v4] of: Add videomode helper
From: Stephen Warren @ 2012-09-24 15:45 UTC (permalink / raw)
To: Rob Herring
Cc: linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Laurent Pinchart,
kernel-bIcnvbaLZ9MEGnE8C9+IrQ, Steffen Trumtrar, Sascha Hauer
In-Reply-To: <50606334.7030902-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
On 09/24/2012 07:42 AM, Rob Herring wrote:
> On 09/19/2012 03:20 AM, Steffen Trumtrar wrote:
>> This patch adds a helper function for parsing videomodes from the devicetree.
>> The videomode can be either converted to a struct drm_display_mode or a
>> struct fb_videomode.
>> +++ b/Documentation/devicetree/bindings/video/displaymode
>> @@ -0,0 +1,74 @@
>> +videomode bindings
>> +=========
>> +
>> +Required properties:
>> + - hactive, vactive: Display resolution
>> + - hfront-porch, hback-porch, hsync-len: Horizontal Display timing parameters
>> + in pixels
>> + vfront-porch, vback-porch, vsync-len: Vertical display timing parameters in
>> + lines
>> + - clock: displayclock in Hz
>
> A major piece missing is the LCD controller to display interface width
> and component ordering.
I thought this binding was solely defining the timing of the video
signal (hence "video mode"). Any definition of the physical interface to
the LCD/display-connector is something entirely orthogonal, so it seems
entirely reasonable to represent that separately.
>> +Example:
>> +
>> + display@0 {
>
> It would be useful to have a compatible string here. We may not always
> know the panel type or have a fixed panel though. We could define
> "generic-lcd" or something for cases where the panel type is unknown.
>
>> + width-mm = <800>;
>> + height-mm = <480>;
I would hope that everything in the example above this point is just
that - an example, and this binding only covers the display mode
definition - i.e. that part of the example below.
If that's not the intent, as Rob says, there's a /ton/ of stuff missing.
>> + modes {
>> + mode0: mode@0 {
>> + /* 1920x1080p24 */
>> + clock = <52000000>;
>> + hactive = <1920>;
>> + vactive = <1080>;
>> + hfront-porch = <25>;
>> + hback-porch = <25>;
>> + hsync-len = <25>;
>> + vback-porch = <2>;
>> + vfront-porch = <2>;
>> + vsync-len = <2>;
>> + hsync-active-high;
>> + };
>> + };
>> + };
^ permalink raw reply
* Re: [PATCH v4] of: Add videomode helper
From: Rob Herring @ 2012-09-24 18:26 UTC (permalink / raw)
To: Stephen Warren
Cc: linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Laurent Pinchart,
kernel-bIcnvbaLZ9MEGnE8C9+IrQ, Steffen Trumtrar, Sascha Hauer
In-Reply-To: <50608000.6050007-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
On 09/24/2012 10:45 AM, Stephen Warren wrote:
> On 09/24/2012 07:42 AM, Rob Herring wrote:
>> On 09/19/2012 03:20 AM, Steffen Trumtrar wrote:
>>> This patch adds a helper function for parsing videomodes from the devicetree.
>>> The videomode can be either converted to a struct drm_display_mode or a
>>> struct fb_videomode.
>
>>> +++ b/Documentation/devicetree/bindings/video/displaymode
>>> @@ -0,0 +1,74 @@
>>> +videomode bindings
>>> +=========
>>> +
>>> +Required properties:
>>> + - hactive, vactive: Display resolution
>>> + - hfront-porch, hback-porch, hsync-len: Horizontal Display timing parameters
>>> + in pixels
>>> + vfront-porch, vback-porch, vsync-len: Vertical display timing parameters in
>>> + lines
>>> + - clock: displayclock in Hz
>>
>> A major piece missing is the LCD controller to display interface width
>> and component ordering.
>
> I thought this binding was solely defining the timing of the video
> signal (hence "video mode"). Any definition of the physical interface to
> the LCD/display-connector is something entirely orthogonal, so it seems
> entirely reasonable to represent that separately.
It is not orthogonal because in many cases the LCD panel defines the
mode. It is only cases where you just have a connector like hdmi that
you have multiple modes. Ideally, you would use EDID in those cases, but
obviously there are boards where that is missing or broken.
>>> +Example:
>>> +
>>> + display@0 {
>>
>> It would be useful to have a compatible string here. We may not always
>> know the panel type or have a fixed panel though. We could define
>> "generic-lcd" or something for cases where the panel type is unknown.
>>
>>> + width-mm = <800>;
>>> + height-mm = <480>;
>
> I would hope that everything in the example above this point is just
> that - an example, and this binding only covers the display mode
> definition - i.e. that part of the example below.
>
It's fairly clear this binding is being defined based on what Linux
supports vs. what the h/w looks like.
> If that's not the intent, as Rob says, there's a /ton/ of stuff missing.
Assuming not, what all is missing?
Rob
>
>>> + modes {
>>> + mode0: mode@0 {
>>> + /* 1920x1080p24 */
>>> + clock = <52000000>;
>>> + hactive = <1920>;
>>> + vactive = <1080>;
>>> + hfront-porch = <25>;
>>> + hback-porch = <25>;
>>> + hsync-len = <25>;
>>> + vback-porch = <2>;
>>> + vfront-porch = <2>;
>>> + vsync-len = <2>;
>>> + hsync-active-high;
>>> + };
>>> + };
>>> + };
>
^ permalink raw reply
* Re: [PATCH v4] of: Add videomode helper
From: Sascha Hauer @ 2012-09-24 19:16 UTC (permalink / raw)
To: Rob Herring
Cc: linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Laurent Pinchart,
kernel-bIcnvbaLZ9MEGnE8C9+IrQ, Steffen Trumtrar
In-Reply-To: <506079CF.40902-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
On Mon, Sep 24, 2012 at 10:18:39AM -0500, Rob Herring wrote:
> On 09/24/2012 09:12 AM, Sascha Hauer wrote:
> >>
> >> A major piece missing is the LCD controller to display interface width
> >> and component ordering.
> >
> > Psst. We silently skipped this for now...
> >
> > I think having such a videomode helper is useful without having the
> > data order part. We are aware that this should be added later, but
> > I think currently it makes sense to concentrate on the basics.
>
> Evolving bindings is not a good thing. We know this is needed, so we
> should address it now. If Linux had a standard way to describe the
> interface (it didn't a few years ago and I haven't kept up), then I
> would bet it would already be part of this binding. Defining the
> bindings in terms of what an OS uses or not is the wrong way around.
I see your point. I'm just afraid that if we start a discussion about
this now, it will take a long time we get something merged. In the
meantime we will get a lot of ad-hoc bindings like this one
suggested for the exynos:
> + lcd_fimd0: lcd_panel0 {
> + lcd-htiming = <4 4 4 480>;
> + lcd-vtiming = <4 4 4 320>;
> + supports-mipi-panel;
> + };
Or this one for the AMBA LCD controller;
> + panel.mode.refresh = get_val(node, "refresh");
> + panel.mode.xres = get_val(node, "xres");
> + panel.mode.yres = get_val(node, "yres");
> + panel.mode.pixclock = get_val(node, "pixclock");
> + panel.mode.left_margin = get_val(node, "left_margin");
> + panel.mode.right_margin = get_val(node, "right_margin");
> + panel.mode.upper_margin = get_val(node, "upper_margin");
> + panel.mode.lower_margin = get_val(node, "lower_margin");
> + panel.mode.hsync_len = get_val(node, "hsync_len");
> + panel.mode.vsync_len = get_val(node, "vsync_len");
> + panel.mode.sync = get_val(node, "sync");
> + panel.bpp = get_val(node, "bpp");
> + panel.width = (signed short) get_val(node, "width");
> + panel.height = (signed short) get_val(node, "height");
(get_val() is a wrapper around of_property_read_u32)
BTW the SoC-camera guys will need a wire format description for their
cameras aswell.
> >
> > We expect the display nodes being subnodes of a driver (which of course
> > has a compatible), or maybe referred to from a driver using phandles. So
> > I don't see why the display node itself should have a compatible
> > property. The display information is only ever useful in the context of
> > a driver.
>
> A subnode or phandle will describe the h/w connection, but you need a
> name to describe what is at each end of the connection.
>
> Where would the model number of an lcd panel be captured then? The
> timing parameters are a property of a specific panel, so both should be
> described together. You may not have any use for the compatible string
> now, but more information is better than less and adding it would not
> hurt anything. For pretty much any other device sitting on a board, we
> describe the manufacturer and type of device. LCD panels should be no
> different.
You convinced me. Lets add a compatible property, it won't hurt.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* Re: [PATCH v4] of: Add videomode helper
From: Stephen Warren @ 2012-09-24 23:09 UTC (permalink / raw)
To: Rob Herring
Cc: linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Laurent Pinchart,
kernel-bIcnvbaLZ9MEGnE8C9+IrQ, Steffen Trumtrar, Sascha Hauer
In-Reply-To: <5060A5D5.7040908-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
On 09/24/2012 12:26 PM, Rob Herring wrote:
> On 09/24/2012 10:45 AM, Stephen Warren wrote:
>> On 09/24/2012 07:42 AM, Rob Herring wrote:
>>> On 09/19/2012 03:20 AM, Steffen Trumtrar wrote:
>>>> This patch adds a helper function for parsing videomodes from the devicetree.
>>>> The videomode can be either converted to a struct drm_display_mode or a
>>>> struct fb_videomode.
>>
>>>> +++ b/Documentation/devicetree/bindings/video/displaymode
>>>> @@ -0,0 +1,74 @@
>>>> +videomode bindings
>>>> +=========
>>>> +
>>>> +Required properties:
>>>> + - hactive, vactive: Display resolution
>>>> + - hfront-porch, hback-porch, hsync-len: Horizontal Display timing parameters
>>>> + in pixels
>>>> + vfront-porch, vback-porch, vsync-len: Vertical display timing parameters in
>>>> + lines
>>>> + - clock: displayclock in Hz
>>>
>>> A major piece missing is the LCD controller to display interface width
>>> and component ordering.
>>
>> I thought this binding was solely defining the timing of the video
>> signal (hence "video mode"). Any definition of the physical interface to
>> the LCD/display-connector is something entirely orthogonal, so it seems
>> entirely reasonable to represent that separately.
>
> It is not orthogonal because in many cases the LCD panel defines the
> mode.
The LCD panel itself defines both the mode and the physical interface
properties. The mode does not imply anything about the physical
interface, nor does the physical interface imply anything about the
mode. So, they are in fact orthogonal. In other words, just because you
need both sets of information, doesn't make the two pieces of
information correlated.
>>>> +Example:
>>>> +
>>>> + display@0 {
>>>
>>> It would be useful to have a compatible string here. We may not always
>>> know the panel type or have a fixed panel though. We could define
>>> "generic-lcd" or something for cases where the panel type is unknown.
>>>
>>>> + width-mm = <800>;
>>>> + height-mm = <480>;
>>
>> I would hope that everything in the example above this point is just
>> that - an example, and this binding only covers the display mode
>> definition - i.e. that part of the example below.
>>
>
> It's fairly clear this binding is being defined based on what Linux
> supports vs. what the h/w looks like.
>
>> If that's not the intent, as Rob says, there's a /ton/ of stuff missing.
>
> Assuming not, what all is missing?
Everything related to the physical interface:
* For DSI, whatever it needs to be configured.
* For LVDS, e.g. number of lanes of R, G, B.
* Perhaps multi-pumping rates (# of clock signals to send each data
value for, to satisfy any minimum clock rates)
* Built-in displays typically need to be coupled with a backlight and
all the associated control of that.
* Pinctrl interaction.
and probably a bunch of other things I haven't thought about.
^ permalink raw reply
* Re: [PATCH] matroxfb: Convert struct i2c_msg initialization to C99 format
From: Shubhrajyoti Datta @ 2012-09-25 4:06 UTC (permalink / raw)
To: Shubhrajyoti D; +Cc: linux-fbdev, linux-kernel, julia.lawall
In-Reply-To: <1347897325-20684-1-git-send-email-shubhrajyoti@ti.com>
On Mon, Sep 17, 2012 at 9:25 PM, Shubhrajyoti D <shubhrajyoti@ti.com> wrote:
> Convert the struct i2c_msg initialization to C99 format. This makes
> maintaining and editing the code simpler. Also helps once other fields
> like transferred are added in future.
>
> Thanks to Julia Lawall <julia.lawall@lip6.fr> for automating the conversion
ping.
>
> Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
> ---
> the cocci file was posted
> http://www.mail-archive.com/cocci@diku.dk/msg02753.html
>
> drivers/video/matrox/matroxfb_maven.c | 15 +++++++++++++--
> 1 files changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/matrox/matroxfb_maven.c
> index 217678e..fb5c123 100644
> --- a/drivers/video/matrox/matroxfb_maven.c
> +++ b/drivers/video/matrox/matroxfb_maven.c
> @@ -137,8 +137,19 @@ static int* get_ctrl_ptr(struct maven_data* md, int idx) {
>
> static int maven_get_reg(struct i2c_client* c, char reg) {
> char dst;
> - struct i2c_msg msgs[] = {{ c->addr, I2C_M_REV_DIR_ADDR, sizeof(reg), ® },
> - { c->addr, I2C_M_RD | I2C_M_NOSTART, sizeof(dst), &dst }};
> + struct i2c_msg msgs[] = {{
> + .addr = c->addr,
> + .flags = I2C_M_REV_DIR_ADDR,
> + .len = sizeof(reg),
> + .buf = ®
> + },
> + {
> + .addr = c->addr,
> + .flags = I2C_M_RD | I2C_M_NOSTART,
> + .len = sizeof(dst),
> + .buf = &dst
> + }
> + };
> s32 err;
>
> err = i2c_transfer(c->adapter, msgs, 2);
> --
> 1.7.5.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply
* Re: [PATCH 0/9] OMAPDSS: OMAP5 related patches
From: Archit Taneja @ 2012-09-25 5:32 UTC (permalink / raw)
To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev
In-Reply-To: <1348495119-8262-1-git-send-email-tomi.valkeinen@ti.com>
On Monday 24 September 2012 07:28 PM, Tomi Valkeinen wrote:
> Hi,
>
> This series adds basic OMAP5 DSS functionality, mainly related to DSS core, DPI
> and DSI.
Looks good to me.
Archit
>
> Tomi
>
> Archit Taneja (1):
> OMAPDSS: Add basic omap5 features to dss and dispc
>
> Tomi Valkeinen (8):
> OMAPDSS: DSI: improve DSI clock calcs for DISPC
> OMAPDSS: move dss feats to the end of dss.c
> OMAPDSS: Add support for DPI source selection
> OMAPDSS: DSI: Add FEAT_DSI_PLL_SELFREQDCO
> OMAPDSS: DSI: Add FEAT_DSI_PLL_REFSEL
> OMAPDSS: DSI: Add new linebuffer size for OMAP5
> OMAPDSS: DSI: Add code to disable PHY DCC
> OMAPDSS: DSI: make OMAP2_DSS_DSI depend on ARCH_OMAP5
>
> drivers/video/omap2/dss/Kconfig | 2 +-
> drivers/video/omap2/dss/dispc.c | 2 +
> drivers/video/omap2/dss/dpi.c | 5 +
> drivers/video/omap2/dss/dsi.c | 167 +++++++++++++++++++++++++-------
> drivers/video/omap2/dss/dss.c | 121 ++++++++++++++++++-----
> drivers/video/omap2/dss/dss.h | 1 +
> drivers/video/omap2/dss/dss_features.c | 96 ++++++++++++++++++
> drivers/video/omap2/dss/dss_features.h | 3 +
> 8 files changed, 337 insertions(+), 60 deletions(-)
>
^ permalink raw reply
* [PATCH] OMAPDSS: Cleanup DSSDBG with dynamic pr_debug function
From: Chandrabhanu Mahapatra @ 2012-09-25 6:15 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra
The printk in DSSDBG function definition is replaced with dynamic debug enabled
pr_debug(). The use of dynamic debugging provides more flexiblity as each debug
statement can be enabled or disabled dynamically on basis of source filename,
line number, module name etc. by writing to a control file in debugfs
filesystem. For better undertsanding please refer to
Documentation/dynamic-debug-howto.txt.
The DSSDBGF() differs from DSSDBG() by providing function name. However,
function name, line number, module name and thread ID can be printed through
dynamic debug by setting appropiate flags 'f','l','m' and 't' in the debugfs
control file. So, DSSDBGF instances are replaced with DSSDBG.
Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
drivers/video/omap2/dss/apply.c | 8 ++++----
drivers/video/omap2/dss/dsi.c | 12 ++++--------
drivers/video/omap2/dss/dss.h | 34 ++++++++--------------------------
3 files changed, 16 insertions(+), 38 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 6354bb8..cb86d94 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -559,7 +559,7 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)
struct mgr_priv_data *mp;
int r;
- DSSDBGF("%d", ovl->id);
+ DSSDBG("%d", ovl->id);
if (!op->enabled || !op->info_dirty)
return;
@@ -594,7 +594,7 @@ static void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
struct ovl_priv_data *op = get_ovl_priv(ovl);
struct mgr_priv_data *mp;
- DSSDBGF("%d", ovl->id);
+ DSSDBG("%d", ovl->id);
if (!op->extra_info_dirty)
return;
@@ -618,7 +618,7 @@ static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
struct mgr_priv_data *mp = get_mgr_priv(mgr);
struct omap_overlay *ovl;
- DSSDBGF("%d", mgr->id);
+ DSSDBG("%d", mgr->id);
if (!mp->enabled)
return;
@@ -644,7 +644,7 @@ static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr)
{
struct mgr_priv_data *mp = get_mgr_priv(mgr);
- DSSDBGF("%d", mgr->id);
+ DSSDBG("%d", mgr->id);
if (!mp->extra_info_dirty)
return;
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 8d815e3..8304cc6b 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -1525,8 +1525,6 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev,
u8 regn_start, regn_end, regm_start, regm_end;
u8 regm_dispc_start, regm_dispc_end, regm_dsi_start, regm_dsi_end;
- DSSDBGF();
-
dsi->current_cinfo.clkin = cinfo->clkin;
dsi->current_cinfo.fint = cinfo->fint;
dsi->current_cinfo.clkin4ddr = cinfo->clkin4ddr;
@@ -2334,8 +2332,6 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
int r;
u32 l;
- DSSDBGF();
-
r = dss_dsi_enable_pads(dsi->module_id, dsi_get_lane_mask(dssdev));
if (r)
return r;
@@ -2686,7 +2682,7 @@ static void dsi_vc_initial_config(struct platform_device *dsidev, int channel)
{
u32 r;
- DSSDBGF("%d", channel);
+ DSSDBG("%d", channel);
r = dsi_read_reg(dsidev, DSI_VC_CTRL(channel));
@@ -2718,7 +2714,7 @@ static int dsi_vc_config_source(struct platform_device *dsidev, int channel,
if (dsi->vc[channel].source = source)
return 0;
- DSSDBGF("%d", channel);
+ DSSDBG("%d", channel);
dsi_sync_vc(dsidev, channel);
@@ -3475,7 +3471,7 @@ static int dsi_enter_ulps(struct platform_device *dsidev)
int r, i;
unsigned mask;
- DSSDBGF();
+ DSSDBG("");
WARN_ON(!dsi_bus_is_locked(dsidev));
@@ -4184,7 +4180,7 @@ int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev,
unsigned long pck;
int r;
- DSSDBGF("ddr_clk %lu, lp_clk %lu", ddr_clk, lp_clk);
+ DSSDBG("ddr_clk %lu, lp_clk %lu", ddr_clk, lp_clk);
mutex_lock(&dsi->lock);
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 5e9fd769..3a2caab 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -29,38 +29,20 @@
#ifdef DEBUG
extern bool dss_debug;
-#ifdef DSS_SUBSYS_NAME
-#define DSSDBG(format, ...) \
- if (dss_debug) \
- printk(KERN_DEBUG "omapdss " DSS_SUBSYS_NAME ": " format, \
- ## __VA_ARGS__)
-#else
-#define DSSDBG(format, ...) \
- if (dss_debug) \
- printk(KERN_DEBUG "omapdss: " format, ## __VA_ARGS__)
#endif
-#ifdef DSS_SUBSYS_NAME
-#define DSSDBGF(format, ...) \
- if (dss_debug) \
- printk(KERN_DEBUG "omapdss " DSS_SUBSYS_NAME \
- ": %s(" format ")\n", \
- __func__, \
- ## __VA_ARGS__)
-#else
-#define DSSDBGF(format, ...) \
- if (dss_debug) \
- printk(KERN_DEBUG "omapdss: " \
- ": %s(" format ")\n", \
- __func__, \
- ## __VA_ARGS__)
+#ifdef pr_fmt
+#undef pr_fmt
#endif
-#else /* DEBUG */
-#define DSSDBG(format, ...)
-#define DSSDBGF(format, ...)
+#ifdef DSS_SUBSYS_NAME
+#define pr_fmt(fmt) DSS_SUBSYS_NAME ": " fmt
+#else
+#define pr_fmt(fmt) fmt
#endif
+#define DSSDBG(format, ...) \
+ pr_debug(format, ## __VA_ARGS__)
#ifdef DSS_SUBSYS_NAME
#define DSSERR(format, ...) \
--
1.7.10
^ permalink raw reply related
* Re: [PATCH] OMAPDSS: Cleanup DSSDBG with dynamic pr_debug function
From: Tomi Valkeinen @ 2012-09-25 6:24 UTC (permalink / raw)
To: Chandrabhanu Mahapatra; +Cc: linux-omap, linux-fbdev
In-Reply-To: <1348552998-6596-1-git-send-email-cmahapatra@ti.com>
[-- Attachment #1: Type: text/plain, Size: 5314 bytes --]
On Tue, 2012-09-25 at 11:33 +0530, Chandrabhanu Mahapatra wrote:
> The printk in DSSDBG function definition is replaced with dynamic debug enabled
> pr_debug(). The use of dynamic debugging provides more flexiblity as each debug
> statement can be enabled or disabled dynamically on basis of source filename,
> line number, module name etc. by writing to a control file in debugfs
> filesystem. For better undertsanding please refer to
> Documentation/dynamic-debug-howto.txt.
>
> The DSSDBGF() differs from DSSDBG() by providing function name. However,
> function name, line number, module name and thread ID can be printed through
> dynamic debug by setting appropiate flags 'f','l','m' and 't' in the debugfs
> control file. So, DSSDBGF instances are replaced with DSSDBG.
Typos with: flexiblity, undertsanding, appropiate.
> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
> ---
> drivers/video/omap2/dss/apply.c | 8 ++++----
> drivers/video/omap2/dss/dsi.c | 12 ++++--------
> drivers/video/omap2/dss/dss.h | 34 ++++++++--------------------------
> 3 files changed, 16 insertions(+), 38 deletions(-)
>
> diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
> index 6354bb8..cb86d94 100644
> --- a/drivers/video/omap2/dss/apply.c
> +++ b/drivers/video/omap2/dss/apply.c
> @@ -559,7 +559,7 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)
> struct mgr_priv_data *mp;
> int r;
>
> - DSSDBGF("%d", ovl->id);
> + DSSDBG("%d", ovl->id);
I don't think this is good. It's true that dyn-debug can print the
function name, but that's optional. The debug message should be somehow
sensible independently, but in this case only a number is printed which
is totally meaningless.
Either the messages should be modified to give a hint what's going on,
or the DSSDBGF could be kept for now. In the above case the debug
message could be something like "writing ovl %d regs".
However, I think it'd be easier just to keep the DSSDBGF for now, and
remove it gradually.
> if (!op->enabled || !op->info_dirty)
> return;
> @@ -594,7 +594,7 @@ static void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
> struct ovl_priv_data *op = get_ovl_priv(ovl);
> struct mgr_priv_data *mp;
>
> - DSSDBGF("%d", ovl->id);
> + DSSDBG("%d", ovl->id);
>
> if (!op->extra_info_dirty)
> return;
> @@ -618,7 +618,7 @@ static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
> struct mgr_priv_data *mp = get_mgr_priv(mgr);
> struct omap_overlay *ovl;
>
> - DSSDBGF("%d", mgr->id);
> + DSSDBG("%d", mgr->id);
>
> if (!mp->enabled)
> return;
> @@ -644,7 +644,7 @@ static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr)
> {
> struct mgr_priv_data *mp = get_mgr_priv(mgr);
>
> - DSSDBGF("%d", mgr->id);
> + DSSDBG("%d", mgr->id);
>
> if (!mp->extra_info_dirty)
> return;
> diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
> index 8d815e3..8304cc6b 100644
> --- a/drivers/video/omap2/dss/dsi.c
> +++ b/drivers/video/omap2/dss/dsi.c
> @@ -1525,8 +1525,6 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev,
> u8 regn_start, regn_end, regm_start, regm_end;
> u8 regm_dispc_start, regm_dispc_end, regm_dsi_start, regm_dsi_end;
>
> - DSSDBGF();
> -
> dsi->current_cinfo.clkin = cinfo->clkin;
> dsi->current_cinfo.fint = cinfo->fint;
> dsi->current_cinfo.clkin4ddr = cinfo->clkin4ddr;
> @@ -2334,8 +2332,6 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
> int r;
> u32 l;
>
> - DSSDBGF();
> -
> r = dss_dsi_enable_pads(dsi->module_id, dsi_get_lane_mask(dssdev));
> if (r)
> return r;
> @@ -2686,7 +2682,7 @@ static void dsi_vc_initial_config(struct platform_device *dsidev, int channel)
> {
> u32 r;
>
> - DSSDBGF("%d", channel);
> + DSSDBG("%d", channel);
>
> r = dsi_read_reg(dsidev, DSI_VC_CTRL(channel));
>
> @@ -2718,7 +2714,7 @@ static int dsi_vc_config_source(struct platform_device *dsidev, int channel,
> if (dsi->vc[channel].source == source)
> return 0;
>
> - DSSDBGF("%d", channel);
> + DSSDBG("%d", channel);
>
> dsi_sync_vc(dsidev, channel);
>
> @@ -3475,7 +3471,7 @@ static int dsi_enter_ulps(struct platform_device *dsidev)
> int r, i;
> unsigned mask;
>
> - DSSDBGF();
> + DSSDBG("");
This debug message is even less meaningful than the overlay number =).
Again, I think either keep the DSSDBGF, or print something sensible,
like "entering ULPS".
>
> WARN_ON(!dsi_bus_is_locked(dsidev));
>
> @@ -4184,7 +4180,7 @@ int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev,
> unsigned long pck;
> int r;
>
> - DSSDBGF("ddr_clk %lu, lp_clk %lu", ddr_clk, lp_clk);
> + DSSDBG("ddr_clk %lu, lp_clk %lu", ddr_clk, lp_clk);
>
> mutex_lock(&dsi->lock);
>
> diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
> index 5e9fd769..3a2caab 100644
> --- a/drivers/video/omap2/dss/dss.h
> +++ b/drivers/video/omap2/dss/dss.h
> @@ -29,38 +29,20 @@
>
> #ifdef DEBUG
> extern bool dss_debug;
You still left the dss_debug option here, even if it's not used by the
DSSDBG anymore. What's your plan about this?
Tomi
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* [PATCH v2 00/18] OMAPDSS: DISPC changes for writeback pipeline
From: Archit Taneja @ 2012-09-25 6:30 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1347538505-25359-1-git-send-email-archit@ti.com>
This series prepares the low level DISPC driver(dispc.c) to configure writeback
registers. Original series can be seen here:
http://marc.info/?l=linux-fbdev&m\x134753851619354&w=2
Changes since v2:
- Removed patches which rename dispc_ovl_* functions to dispc_plane_*
- Revisited the scaling related code a bit. Removed the usage of 'output rate'
to fit in writeback. Instead, added a new parameter called mem_to_mem, passed
by APPLY. This tells whether we have to consider a display pixel clock for
scaling limitations or not.
- All 'Scalar' references renamed to 'Scaler'.
- Minor cleanups.
Reference branch:
git://gitorious.org/~boddob/linux-omap-dss2/archit-dss2-clone.git 1-writeback-dispc
Archit Taneja (18):
OMAPDSS: DISPC: Constify omap_overlay_info in dispc_ovl_setup()
OMAPDSS: DISPC: Simplify function names for setting pipeline input
and output sizes
OMAPDSS: DISPC: Pass overlay caps as a parameter to dispc plane
functions
OMAPDSS: OVERLAY: Add position and replication as overlay caps
OMAPDSS: DISPC: Make dispc_ovl_setup call dispc_ovl_setup_common
OMAPDSS: DISPC: Don't pass channel out when configuring overlays
OMAPDSS: DIPSC: Relax scaling limitations when in memory to memory
mode
OMAPDSS: DISPC: Allow both upscaling and downscaling of chroma
OMAPDSS: DISPC: Add writeback register offsets and dss features
structs
OMAPDSS: DISPC: Configure input and output sizes for writeback
OMAPDSS: DISPC: Downscale chroma if plane is writeback
OMAPDSS: DISPC: Don't set chroma resampling bit for writeback
OMAPDSS: DISPC: Add function to set channel in for writeback
OMAPDSS: DISPC: Configure overlay-like parameters in dispc_wb_setup
OMAPDSS: DISPC: Configure writeback specific parameters in
dispc_wb_setup()
OMAPDSS: DISPC: Configure writeback FIFOs
OMAPDSS: DISPC: Add manager like functions for writeback
OMAPDSS: DISPC: Configure color conversion coefficients for writeback
drivers/video/omap2/dss/apply.c | 2 +-
drivers/video/omap2/dss/dispc.c | 561 ++++++++++++++++++++++----------
drivers/video/omap2/dss/dispc.h | 33 ++
drivers/video/omap2/dss/dss.h | 25 +-
drivers/video/omap2/dss/dss_features.c | 57 +++-
drivers/video/omap2/dss/dss_features.h | 1 +
include/video/omapdss.h | 15 +
7 files changed, 510 insertions(+), 184 deletions(-)
--
1.7.9.5
^ permalink raw reply
* [PATCH v2 00/18] OMAPDSS: DISPC changes for writeback pipeline
From: Archit Taneja @ 2012-09-25 6:31 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1347538505-25359-1-git-send-email-archit@ti.com>
This series prepares the low level DISPC driver(dispc.c) to configure writeback
registers. Original series can be seen here:
http://marc.info/?l=linux-fbdev&m\x134753851619354&w=2
Changes since v2:
- Removed patches which rename dispc_ovl_* functions to dispc_plane_*
- Revisited the scaling related code a bit. Removed the usage of 'output rate'
to fit in writeback. Instead, added a new parameter called mem_to_mem, passed
by APPLY. This tells whether we have to consider a display pixel clock for
scaling limitations or not.
- All 'Scalar' references renamed to 'Scaler'.
- Minor cleanups.
Reference branch:
git://gitorious.org/~boddob/linux-omap-dss2/archit-dss2-clone.git 1-writeback-dispc
Archit Taneja (18):
OMAPDSS: DISPC: Constify omap_overlay_info in dispc_ovl_setup()
OMAPDSS: DISPC: Simplify function names for setting pipeline input
and output sizes
OMAPDSS: DISPC: Pass overlay caps as a parameter to dispc plane
functions
OMAPDSS: OVERLAY: Add position and replication as overlay caps
OMAPDSS: DISPC: Make dispc_ovl_setup call dispc_ovl_setup_common
OMAPDSS: DISPC: Don't pass channel out when configuring overlays
OMAPDSS: DIPSC: Relax scaling limitations when in memory to memory
mode
OMAPDSS: DISPC: Allow both upscaling and downscaling of chroma
OMAPDSS: DISPC: Add writeback register offsets and dss features
structs
OMAPDSS: DISPC: Configure input and output sizes for writeback
OMAPDSS: DISPC: Downscale chroma if plane is writeback
OMAPDSS: DISPC: Don't set chroma resampling bit for writeback
OMAPDSS: DISPC: Add function to set channel in for writeback
OMAPDSS: DISPC: Configure overlay-like parameters in dispc_wb_setup
OMAPDSS: DISPC: Configure writeback specific parameters in
dispc_wb_setup()
OMAPDSS: DISPC: Configure writeback FIFOs
OMAPDSS: DISPC: Add manager like functions for writeback
OMAPDSS: DISPC: Configure color conversion coefficients for writeback
drivers/video/omap2/dss/apply.c | 2 +-
drivers/video/omap2/dss/dispc.c | 561 ++++++++++++++++++++++----------
drivers/video/omap2/dss/dispc.h | 33 ++
drivers/video/omap2/dss/dss.h | 25 +-
drivers/video/omap2/dss/dss_features.c | 57 +++-
drivers/video/omap2/dss/dss_features.h | 1 +
include/video/omapdss.h | 15 +
7 files changed, 510 insertions(+), 184 deletions(-)
--
1.7.9.5
^ permalink raw reply
* [PATCH v2 01/18] OMAPDSS: DISPC: Constify omap_overlay_info in dispc_ovl_setup()
From: Archit Taneja @ 2012-09-25 6:31 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1348553993-8083-1-git-send-email-archit@ti.com>
The struct omap_overlay_info passed to dispc_ovl_setup() is used to configure
DISPC registers. It shouldn't modify the overlay_info structure. The pos_y field
was being changed in dispc_ovl_setup in the case of interlaced displays. Fix
this and const qualifier to the omap_overlay_info argument.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dispc.c | 9 +++++----
drivers/video/omap2/dss/dss.h | 2 +-
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 33db882..cd3d532 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -2253,7 +2253,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
return 0;
}
-int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
+int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
bool replication, const struct omap_video_timings *mgr_timings)
{
struct omap_overlay *ovl = omap_dss_get_overlay(plane);
@@ -2271,6 +2271,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
enum omap_channel channel;
int x_predecim = 1, y_predecim = 1;
bool ilace = mgr_timings->interlace;
+ u16 pos_y = oi->pos_y;
channel = dispc_ovl_get_channel_out(plane);
@@ -2293,12 +2294,12 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
if (ilace) {
if (fieldmode)
in_height /= 2;
- oi->pos_y /= 2;
+ pos_y /= 2;
out_height /= 2;
DSSDBG("adjusting for ilace: height %d, pos_y %d, "
"out_height %d\n",
- in_height, oi->pos_y, out_height);
+ in_height, pos_y, out_height);
}
if (!dss_feat_color_mode_supported(plane, oi->color_mode))
@@ -2381,7 +2382,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
DSSDBG("%d,%d %dx%d -> %dx%d\n", oi->pos_x, oi->pos_y, in_width,
in_height, out_width, out_height);
- dispc_ovl_set_pos(plane, oi->pos_x, oi->pos_y);
+ dispc_ovl_set_pos(plane, oi->pos_x, pos_y);
dispc_ovl_set_pic_size(plane, in_width, in_height);
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index c2bc092..43210b8 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -440,7 +440,7 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high);
void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
u32 *fifo_low, u32 *fifo_high, bool use_fifomerge,
bool manual_update);
-int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
+int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
bool replication, const struct omap_video_timings *mgr_timings);
int dispc_ovl_enable(enum omap_plane plane, bool enable);
void dispc_ovl_set_channel_out(enum omap_plane plane,
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 02/18] OMAPDSS: DISPC: Simplify function names for setting pipeline input and output sizes
From: Archit Taneja @ 2012-09-25 6:31 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1348553993-8083-1-git-send-email-archit@ti.com>
The DISPC pipeline register names in the TRM for setting the buffer size and
the output size are a bit misleading, for example, there are different register
names for setting the buffer size for VID and GFX pipes. Things get more
confusing when considering writeback pipeline.
Rename the functions so that they tell whether they are configuring the input
to the scalar or the output. These will be extended later to support writeback
registers.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dispc.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index cd3d532..2c01e13 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -705,7 +705,8 @@ static void dispc_ovl_set_pos(enum omap_plane plane, int x, int y)
dispc_write_reg(DISPC_OVL_POSITION(plane), val);
}
-static void dispc_ovl_set_pic_size(enum omap_plane plane, int width, int height)
+static void dispc_ovl_set_input_size(enum omap_plane plane, int width,
+ int height)
{
u32 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
@@ -715,7 +716,8 @@ static void dispc_ovl_set_pic_size(enum omap_plane plane, int width, int height)
dispc_write_reg(DISPC_OVL_PICTURE_SIZE(plane), val);
}
-static void dispc_ovl_set_vid_size(enum omap_plane plane, int width, int height)
+static void dispc_ovl_set_output_size(enum omap_plane plane, int width,
+ int height)
{
u32 val;
@@ -2384,13 +2386,14 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
dispc_ovl_set_pos(plane, oi->pos_x, pos_y);
- dispc_ovl_set_pic_size(plane, in_width, in_height);
+ dispc_ovl_set_input_size(plane, in_width, in_height);
if (ovl->caps & OMAP_DSS_OVL_CAP_SCALE) {
dispc_ovl_set_scaling(plane, in_width, in_height, out_width,
out_height, ilace, five_taps, fieldmode,
oi->color_mode, oi->rotation);
- dispc_ovl_set_vid_size(plane, out_width, out_height);
+
+ dispc_ovl_set_output_size(plane, out_width, out_height);
dispc_ovl_set_vid_color_conv(plane, cconv);
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 03/18] OMAPDSS: DISPC: Pass overlay caps as a parameter to dispc plane functions
From: Archit Taneja @ 2012-09-25 6:31 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1348553993-8083-1-git-send-email-archit@ti.com>
Currently, the functions below take the omap_plane parameter and derive the
overlay caps within them. Pass the overlay caps as a parameter to the function
to allow these to be used by writeback too.
- dispc_ovl_set_zorder()
- dispc_ovl_set_pre_mult_alpha()
- dispc_ovl_setup_global_alpha()
- dispc_ovl_calc_scaling()
- dispc_ovl_setup()
These functions will be used for writeback later, and the caps will help in
deciding if they are to be used for writeback or not. This allows reuse of
overlay caps for writeback.
Using omap_overlay_caps for writeback seems a bit incorrect, but caps is
something already in use by users of OMAPDSS(omapfb/omap_vout), so we use
overlay caps for overlay like features of writeback too.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dispc.c | 41 +++++++++++++++++++--------------------
1 file changed, 20 insertions(+), 21 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 2c01e13..955db56 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -728,11 +728,10 @@ static void dispc_ovl_set_output_size(enum omap_plane plane, int width,
dispc_write_reg(DISPC_OVL_SIZE(plane), val);
}
-static void dispc_ovl_set_zorder(enum omap_plane plane, u8 zorder)
+static void dispc_ovl_set_zorder(enum omap_plane plane,
+ enum omap_overlay_caps caps, u8 zorder)
{
- struct omap_overlay *ovl = omap_dss_get_overlay(plane);
-
- if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) = 0)
+ if ((caps & OMAP_DSS_OVL_CAP_ZORDER) = 0)
return;
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), zorder, 27, 26);
@@ -749,23 +748,22 @@ static void dispc_ovl_enable_zorder_planes(void)
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), 1, 25, 25);
}
-static void dispc_ovl_set_pre_mult_alpha(enum omap_plane plane, bool enable)
+static void dispc_ovl_set_pre_mult_alpha(enum omap_plane plane,
+ enum omap_overlay_caps caps, bool enable)
{
- struct omap_overlay *ovl = omap_dss_get_overlay(plane);
-
- if ((ovl->caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) = 0)
+ if ((caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) = 0)
return;
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 28, 28);
}
-static void dispc_ovl_setup_global_alpha(enum omap_plane plane, u8 global_alpha)
+static void dispc_ovl_setup_global_alpha(enum omap_plane plane,
+ enum omap_overlay_caps caps, u8 global_alpha)
{
static const unsigned shifts[] = { 0, 8, 16, 24, };
int shift;
- struct omap_overlay *ovl = omap_dss_get_overlay(plane);
- if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) = 0)
+ if ((caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) = 0)
return;
shift = shifts[plane];
@@ -2193,13 +2191,12 @@ static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
}
static int dispc_ovl_calc_scaling(enum omap_plane plane,
- enum omap_channel channel,
+ enum omap_overlay_caps caps, enum omap_channel channel,
const struct omap_video_timings *mgr_timings,
u16 width, u16 height, u16 out_width, u16 out_height,
enum omap_color_mode color_mode, bool *five_taps,
int *x_predecim, int *y_predecim, u16 pos_x)
{
- struct omap_overlay *ovl = omap_dss_get_overlay(plane);
const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
const int max_decim_limit = 16;
unsigned long core_clk = 0;
@@ -2208,7 +2205,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
if (width = out_width && height = out_height)
return 0;
- if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) = 0)
+ if ((caps & OMAP_DSS_OVL_CAP_SCALE) = 0)
return -EINVAL;
*x_predecim = max_decim_limit;
@@ -2259,6 +2256,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
bool replication, const struct omap_video_timings *mgr_timings)
{
struct omap_overlay *ovl = omap_dss_get_overlay(plane);
+ enum omap_overlay_caps caps = ovl->caps;
bool five_taps = true;
bool fieldmode = 0;
int r, cconv = 0;
@@ -2307,9 +2305,10 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
if (!dss_feat_color_mode_supported(plane, oi->color_mode))
return -EINVAL;
- r = dispc_ovl_calc_scaling(plane, channel, mgr_timings, in_width,
- in_height, out_width, out_height, oi->color_mode,
- &five_taps, &x_predecim, &y_predecim, oi->pos_x);
+ r = dispc_ovl_calc_scaling(plane, caps, channel, mgr_timings,
+ in_width, in_height, out_width, out_height,
+ oi->color_mode, &five_taps, &x_predecim, &y_predecim,
+ oi->pos_x);
if (r)
return r;
@@ -2388,7 +2387,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
dispc_ovl_set_input_size(plane, in_width, in_height);
- if (ovl->caps & OMAP_DSS_OVL_CAP_SCALE) {
+ if (caps & OMAP_DSS_OVL_CAP_SCALE) {
dispc_ovl_set_scaling(plane, in_width, in_height, out_width,
out_height, ilace, five_taps, fieldmode,
oi->color_mode, oi->rotation);
@@ -2400,9 +2399,9 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
dispc_ovl_set_rotation_attrs(plane, oi->rotation, oi->mirror,
oi->color_mode);
- dispc_ovl_set_zorder(plane, oi->zorder);
- dispc_ovl_set_pre_mult_alpha(plane, oi->pre_mult_alpha);
- dispc_ovl_setup_global_alpha(plane, oi->global_alpha);
+ dispc_ovl_set_zorder(plane, caps, oi->zorder);
+ dispc_ovl_set_pre_mult_alpha(plane, caps, oi->pre_mult_alpha);
+ dispc_ovl_setup_global_alpha(plane, caps, oi->global_alpha);
dispc_ovl_enable_replication(plane, replication);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 04/18] OMAPDSS: OVERLAY: Add position and replication as overlay caps
From: Archit Taneja @ 2012-09-25 6:31 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1348553993-8083-1-git-send-email-archit@ti.com>
Add position and replication as overlay caps, and pass overlay caps as an
argument to the corresponding functions. Adding position and replication to
overlay caps seems a bit unnecessary, but it allows us to use the
corresponding functions for writeback too.
These caps will be set for all overlays, but not for writeback. This is done
so writeback can reuse dispc_ovl_setup() to the maximum.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dispc.c | 20 ++++++++++++-----
drivers/video/omap2/dss/dss_features.c | 38 +++++++++++++++++++++-----------
include/video/omapdss.h | 2 ++
3 files changed, 42 insertions(+), 18 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 955db56..0ff1c07 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -698,9 +698,15 @@ static void dispc_ovl_set_ba1_uv(enum omap_plane plane, u32 paddr)
dispc_write_reg(DISPC_OVL_BA1_UV(plane), paddr);
}
-static void dispc_ovl_set_pos(enum omap_plane plane, int x, int y)
+static void dispc_ovl_set_pos(enum omap_plane plane,
+ enum omap_overlay_caps caps, int x, int y)
{
- u32 val = FLD_VAL(y, 26, 16) | FLD_VAL(x, 10, 0);
+ u32 val;
+
+ if ((caps & OMAP_DSS_OVL_CAP_POS) = 0)
+ return;
+
+ val = FLD_VAL(y, 26, 16) | FLD_VAL(x, 10, 0);
dispc_write_reg(DISPC_OVL_POSITION(plane), val);
}
@@ -1051,11 +1057,15 @@ static void dispc_ovl_set_vid_color_conv(enum omap_plane plane, bool enable)
dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val);
}
-static void dispc_ovl_enable_replication(enum omap_plane plane, bool enable)
+static void dispc_ovl_enable_replication(enum omap_plane plane,
+ enum omap_overlay_caps caps, bool enable)
{
static const unsigned shifts[] = { 5, 10, 10, 10 };
int shift;
+ if ((caps & OMAP_DSS_OVL_CAP_REPLICATION) = 0)
+ return;
+
shift = shifts[plane];
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, shift, shift);
}
@@ -2383,7 +2393,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
DSSDBG("%d,%d %dx%d -> %dx%d\n", oi->pos_x, oi->pos_y, in_width,
in_height, out_width, out_height);
- dispc_ovl_set_pos(plane, oi->pos_x, pos_y);
+ dispc_ovl_set_pos(plane, caps, oi->pos_x, pos_y);
dispc_ovl_set_input_size(plane, in_width, in_height);
@@ -2403,7 +2413,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
dispc_ovl_set_pre_mult_alpha(plane, caps, oi->pre_mult_alpha);
dispc_ovl_setup_global_alpha(plane, caps, oi->global_alpha);
- dispc_ovl_enable_replication(plane, replication);
+ dispc_ovl_enable_replication(plane, caps, replication);
return 0;
}
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 63d109f..8b6c79f 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -269,54 +269,66 @@ static const enum omap_color_mode omap4_dss_supported_color_modes[] = {
static const enum omap_overlay_caps omap2_dss_overlay_caps[] = {
/* OMAP_DSS_GFX */
- 0,
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
/* OMAP_DSS_VIDEO1 */
- OMAP_DSS_OVL_CAP_SCALE,
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
/* OMAP_DSS_VIDEO2 */
- OMAP_DSS_OVL_CAP_SCALE,
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
};
static const enum omap_overlay_caps omap3430_dss_overlay_caps[] = {
/* OMAP_DSS_GFX */
- OMAP_DSS_OVL_CAP_GLOBAL_ALPHA,
+ OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
/* OMAP_DSS_VIDEO1 */
- OMAP_DSS_OVL_CAP_SCALE,
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
/* OMAP_DSS_VIDEO2 */
- OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA,
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
};
static const enum omap_overlay_caps omap3630_dss_overlay_caps[] = {
/* OMAP_DSS_GFX */
- OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA,
+ OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA |
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
/* OMAP_DSS_VIDEO1 */
- OMAP_DSS_OVL_CAP_SCALE,
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
/* OMAP_DSS_VIDEO2 */
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
- OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA,
+ OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
};
static const enum omap_overlay_caps omap4_dss_overlay_caps[] = {
/* OMAP_DSS_GFX */
OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA |
- OMAP_DSS_OVL_CAP_ZORDER,
+ OMAP_DSS_OVL_CAP_ZORDER | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
/* OMAP_DSS_VIDEO1 */
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
- OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER,
+ OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER |
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
/* OMAP_DSS_VIDEO2 */
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
- OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER,
+ OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER |
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
/* OMAP_DSS_VIDEO3 */
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
- OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER,
+ OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER |
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
};
static const char * const omap2_dss_clk_source_names[] = {
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index e65e2e9..46097bd 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -187,6 +187,8 @@ enum omap_overlay_caps {
OMAP_DSS_OVL_CAP_GLOBAL_ALPHA = 1 << 1,
OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA = 1 << 2,
OMAP_DSS_OVL_CAP_ZORDER = 1 << 3,
+ OMAP_DSS_OVL_CAP_POS = 1 << 4,
+ OMAP_DSS_OVL_CAP_REPLICATION = 1 << 5,
};
enum omap_overlay_manager_caps {
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 05/18] OMAPDSS: DISPC: Make dispc_ovl_setup call dispc_ovl_setup_common
From: Archit Taneja @ 2012-09-25 6:31 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1348553993-8083-1-git-send-email-archit@ti.com>
Add a new static function called dispc_ovl_setup_common(). This function is used by
dispc_ovl_setup() to configure the overlay registers. This split is done so that
dispc_wb_setup() can reuse overlay register configuration related code.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dispc.c | 128 ++++++++++++++++++++++-----------------
1 file changed, 71 insertions(+), 57 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 0ff1c07..782de44 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -2262,43 +2262,35 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
return 0;
}
-int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
+static int dispc_ovl_setup_common(enum omap_plane plane,
+ enum omap_channel channel, enum omap_overlay_caps caps,
+ u32 paddr, u32 p_uv_addr, u16 screen_width, int pos_x,
+ int pos_y, u16 width, u16 height, u16 out_width, u16 out_height,
+ enum omap_color_mode color_mode, u8 rotation, bool mirror,
+ u8 zorder, u8 pre_mult_alpha, u8 global_alpha,
+ enum omap_dss_rotation_type rotation_type,
bool replication, const struct omap_video_timings *mgr_timings)
{
- struct omap_overlay *ovl = omap_dss_get_overlay(plane);
- enum omap_overlay_caps caps = ovl->caps;
bool five_taps = true;
bool fieldmode = 0;
int r, cconv = 0;
unsigned offset0, offset1;
s32 row_inc;
s32 pix_inc;
- u16 frame_height = oi->height;
+ u16 frame_height = height;
unsigned int field_offset = 0;
- u16 in_height = oi->height;
- u16 in_width = oi->width;
- u16 out_width, out_height;
- enum omap_channel channel;
+ u16 in_height = height;
+ u16 in_width = width;
int x_predecim = 1, y_predecim = 1;
bool ilace = mgr_timings->interlace;
- u16 pos_y = oi->pos_y;
-
- channel = dispc_ovl_get_channel_out(plane);
-
- DSSDBG("dispc_ovl_setup %d, pa %x, pa_uv %x, sw %d, %d,%d, %dx%d -> "
- "%dx%d, cmode %x, rot %d, mir %d, ilace %d chan %d repl %d\n",
- plane, oi->paddr, oi->p_uv_addr,
- oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height,
- oi->out_width, oi->out_height, oi->color_mode, oi->rotation,
- oi->mirror, ilace, channel, replication);
- if (oi->paddr = 0)
+ if (paddr = 0)
return -EINVAL;
- out_width = oi->out_width = 0 ? oi->width : oi->out_width;
- out_height = oi->out_height = 0 ? oi->height : oi->out_height;
+ out_width = out_width = 0 ? width : out_width;
+ out_height = out_height = 0 ? height : out_height;
- if (ilace && oi->height = out_height)
+ if (ilace && height = out_height)
fieldmode = 1;
if (ilace) {
@@ -2308,26 +2300,26 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
out_height /= 2;
DSSDBG("adjusting for ilace: height %d, pos_y %d, "
- "out_height %d\n",
- in_height, pos_y, out_height);
+ "out_height %d\n", in_height, pos_y,
+ out_height);
}
- if (!dss_feat_color_mode_supported(plane, oi->color_mode))
+ if (!dss_feat_color_mode_supported(plane, color_mode))
return -EINVAL;
r = dispc_ovl_calc_scaling(plane, caps, channel, mgr_timings,
in_width, in_height, out_width, out_height,
- oi->color_mode, &five_taps, &x_predecim, &y_predecim,
- oi->pos_x);
+ color_mode, &five_taps, &x_predecim, &y_predecim,
+ pos_x);
if (r)
return r;
in_width = DIV_ROUND_UP(in_width, x_predecim);
in_height = DIV_ROUND_UP(in_height, y_predecim);
- if (oi->color_mode = OMAP_DSS_COLOR_YUV2 ||
- oi->color_mode = OMAP_DSS_COLOR_UYVY ||
- oi->color_mode = OMAP_DSS_COLOR_NV12)
+ if (color_mode = OMAP_DSS_COLOR_YUV2 ||
+ color_mode = OMAP_DSS_COLOR_UYVY ||
+ color_mode = OMAP_DSS_COLOR_NV12)
cconv = 1;
if (ilace && !fieldmode) {
@@ -2353,71 +2345,93 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
row_inc = 0;
pix_inc = 0;
- if (oi->rotation_type = OMAP_DSS_ROT_TILER)
- calc_tiler_rotation_offset(oi->screen_width, in_width,
- oi->color_mode, fieldmode, field_offset,
+ if (rotation_type = OMAP_DSS_ROT_TILER)
+ calc_tiler_rotation_offset(screen_width, in_width,
+ color_mode, fieldmode, field_offset,
&offset0, &offset1, &row_inc, &pix_inc,
x_predecim, y_predecim);
- else if (oi->rotation_type = OMAP_DSS_ROT_DMA)
- calc_dma_rotation_offset(oi->rotation, oi->mirror,
- oi->screen_width, in_width, frame_height,
- oi->color_mode, fieldmode, field_offset,
+ else if (rotation_type = OMAP_DSS_ROT_DMA)
+ calc_dma_rotation_offset(rotation, mirror,
+ screen_width, in_width, frame_height,
+ color_mode, fieldmode, field_offset,
&offset0, &offset1, &row_inc, &pix_inc,
x_predecim, y_predecim);
else
- calc_vrfb_rotation_offset(oi->rotation, oi->mirror,
- oi->screen_width, in_width, frame_height,
- oi->color_mode, fieldmode, field_offset,
+ calc_vrfb_rotation_offset(rotation, mirror,
+ screen_width, in_width, frame_height,
+ color_mode, fieldmode, field_offset,
&offset0, &offset1, &row_inc, &pix_inc,
x_predecim, y_predecim);
DSSDBG("offset0 %u, offset1 %u, row_inc %d, pix_inc %d\n",
offset0, offset1, row_inc, pix_inc);
- dispc_ovl_set_color_mode(plane, oi->color_mode);
+ dispc_ovl_set_color_mode(plane, color_mode);
- dispc_ovl_configure_burst_type(plane, oi->rotation_type);
+ dispc_ovl_configure_burst_type(plane, rotation_type);
- dispc_ovl_set_ba0(plane, oi->paddr + offset0);
- dispc_ovl_set_ba1(plane, oi->paddr + offset1);
+ dispc_ovl_set_ba0(plane, paddr + offset0);
+ dispc_ovl_set_ba1(plane, paddr + offset1);
- if (OMAP_DSS_COLOR_NV12 = oi->color_mode) {
- dispc_ovl_set_ba0_uv(plane, oi->p_uv_addr + offset0);
- dispc_ovl_set_ba1_uv(plane, oi->p_uv_addr + offset1);
+ if (OMAP_DSS_COLOR_NV12 = color_mode) {
+ dispc_ovl_set_ba0_uv(plane, p_uv_addr + offset0);
+ dispc_ovl_set_ba1_uv(plane, p_uv_addr + offset1);
}
-
dispc_ovl_set_row_inc(plane, row_inc);
dispc_ovl_set_pix_inc(plane, pix_inc);
- DSSDBG("%d,%d %dx%d -> %dx%d\n", oi->pos_x, oi->pos_y, in_width,
+ DSSDBG("%d,%d %dx%d -> %dx%d\n", pos_x, pos_y, in_width,
in_height, out_width, out_height);
- dispc_ovl_set_pos(plane, caps, oi->pos_x, pos_y);
+ dispc_ovl_set_pos(plane, caps, pos_x, pos_y);
dispc_ovl_set_input_size(plane, in_width, in_height);
if (caps & OMAP_DSS_OVL_CAP_SCALE) {
dispc_ovl_set_scaling(plane, in_width, in_height, out_width,
out_height, ilace, five_taps, fieldmode,
- oi->color_mode, oi->rotation);
-
+ color_mode, rotation);
dispc_ovl_set_output_size(plane, out_width, out_height);
dispc_ovl_set_vid_color_conv(plane, cconv);
}
- dispc_ovl_set_rotation_attrs(plane, oi->rotation, oi->mirror,
- oi->color_mode);
+ dispc_ovl_set_rotation_attrs(plane, rotation, mirror, color_mode);
- dispc_ovl_set_zorder(plane, caps, oi->zorder);
- dispc_ovl_set_pre_mult_alpha(plane, caps, oi->pre_mult_alpha);
- dispc_ovl_setup_global_alpha(plane, caps, oi->global_alpha);
+ dispc_ovl_set_zorder(plane, caps, zorder);
+ dispc_ovl_set_pre_mult_alpha(plane, caps, pre_mult_alpha);
+ dispc_ovl_setup_global_alpha(plane, caps, global_alpha);
dispc_ovl_enable_replication(plane, caps, replication);
return 0;
}
+int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
+ bool replication, const struct omap_video_timings *mgr_timings)
+{
+ int r;
+ struct omap_overlay *ovl = omap_dss_get_overlay(plane);
+ enum omap_channel channel;
+
+ channel = dispc_ovl_get_channel_out(plane);
+
+ DSSDBG("dispc_ovl_setup %d, pa %x, pa_uv %x, sw %d, %d,%d, %dx%d -> "
+ "%dx%d, cmode %x, rot %d, mir %d, chan %d repl %d\n",
+ plane, oi->paddr, oi->p_uv_addr, oi->screen_width, oi->pos_x,
+ oi->pos_y, oi->width, oi->height, oi->out_width, oi->out_height,
+ oi->color_mode, oi->rotation, oi->mirror, channel, replication);
+
+ r = dispc_ovl_setup_common(plane, channel, ovl->caps, oi->paddr,
+ oi->p_uv_addr, oi->screen_width, oi->pos_x, oi->pos_y,
+ oi->width, oi->height, oi->out_width, oi->out_height,
+ oi->color_mode, oi->rotation, oi->mirror, oi->zorder,
+ oi->pre_mult_alpha, oi->global_alpha, oi->rotation_type,
+ replication, mgr_timings);
+
+ return r;
+}
+
int dispc_ovl_enable(enum omap_plane plane, bool enable)
{
DSSDBG("dispc_enable_plane %d, %d\n", plane, enable);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 06/18] OMAPDSS: DISPC: Don't pass channel out when configuring overlays
From: Archit Taneja @ 2012-09-25 6:31 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1348553993-8083-1-git-send-email-archit@ti.com>
dispc_ovl_setup_common() is to be used by both overlays and writeback. We pass
channel out to figure out what manager the overlay is connected to, to determine
the pixel clock rate. This is used to decide the scaling limitations for that
overlay.
writeback doesn't have a channel out, it has a channel in field which tells
where writeback gets its input from. These are 2 different fields, and this
prevents us reusing the overlay configuration code for writeback.
To overcome this, we now pass omap_plane to overlay related functions rather
than passing channel out. We create helper functions which can derive pclk/lclk
from the omap_plane id.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dispc.c | 115 ++++++++++++++++++++++-----------------
1 file changed, 66 insertions(+), 49 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 782de44..edb31fd 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -86,13 +86,13 @@ struct dispc_features {
u16 sw_max;
u16 vp_max;
u16 hp_max;
- int (*calc_scaling) (enum omap_channel channel,
+ int (*calc_scaling) (enum omap_plane plane,
const struct omap_video_timings *mgr_timings,
u16 width, u16 height, u16 out_width, u16 out_height,
enum omap_color_mode color_mode, bool *five_taps,
int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
u16 pos_x, unsigned long *core_clk);
- unsigned long (*calc_core_clk) (enum omap_channel channel,
+ unsigned long (*calc_core_clk) (enum omap_plane plane,
u16 width, u16 height, u16 out_width, u16 out_height);
u8 num_fifos;
@@ -236,6 +236,8 @@ static const struct {
};
static void _omap_dispc_set_irqs(void);
+static unsigned long dispc_plane_pclk_rate(enum omap_plane plane);
+static unsigned long dispc_plane_lclk_rate(enum omap_plane plane);
static inline void dispc_write_reg(const u16 idx, u32 val)
{
@@ -1919,22 +1921,19 @@ static void calc_tiler_rotation_offset(u16 screen_width, u16 width,
* This function is used to avoid synclosts in OMAP3, because of some
* undocumented horizontal position and timing related limitations.
*/
-static int check_horiz_timing_omap3(enum omap_channel channel,
+static int check_horiz_timing_omap3(enum omap_plane plane,
const struct omap_video_timings *t, u16 pos_x,
u16 width, u16 height, u16 out_width, u16 out_height)
{
int DS = DIV_ROUND_UP(height, out_height);
- unsigned long nonactive, lclk, pclk;
+ unsigned long nonactive;
static const u8 limits[3] = { 8, 10, 20 };
u64 val, blank;
+ unsigned long pclk = dispc_plane_pclk_rate(plane);
+ unsigned long lclk = dispc_plane_lclk_rate(plane);
int i;
nonactive = t->x_res + t->hfp + t->hsw + t->hbp - out_width;
- pclk = dispc_mgr_pclk_rate(channel);
- if (dss_mgr_is_lcd(channel))
- lclk = dispc_mgr_lclk_rate(channel);
- else
- lclk = dispc_fclk_rate();
i = 0;
if (out_height < height)
@@ -1971,13 +1970,14 @@ static int check_horiz_timing_omap3(enum omap_channel channel,
return 0;
}
-static unsigned long calc_core_clk_five_taps(enum omap_channel channel,
+static unsigned long calc_core_clk_five_taps(enum omap_plane plane,
const struct omap_video_timings *mgr_timings, u16 width,
u16 height, u16 out_width, u16 out_height,
enum omap_color_mode color_mode)
{
u32 core_clk = 0;
- u64 tmp, pclk = dispc_mgr_pclk_rate(channel);
+ u64 tmp;
+ unsigned long pclk = dispc_plane_pclk_rate(plane);
if (height <= out_height && width <= out_width)
return (unsigned long) pclk;
@@ -2011,10 +2011,10 @@ static unsigned long calc_core_clk_five_taps(enum omap_channel channel,
return core_clk;
}
-static unsigned long calc_core_clk_24xx(enum omap_channel channel, u16 width,
+static unsigned long calc_core_clk_24xx(enum omap_plane plane, u16 width,
u16 height, u16 out_width, u16 out_height)
{
- unsigned long pclk = dispc_mgr_pclk_rate(channel);
+ unsigned long pclk = dispc_plane_pclk_rate(plane);
if (height > out_height && width > out_width)
return pclk * 4;
@@ -2022,11 +2022,11 @@ static unsigned long calc_core_clk_24xx(enum omap_channel channel, u16 width,
return pclk * 2;
}
-static unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width,
+static unsigned long calc_core_clk_34xx(enum omap_plane plane, u16 width,
u16 height, u16 out_width, u16 out_height)
{
unsigned int hf, vf;
- unsigned long pclk = dispc_mgr_pclk_rate(channel);
+ unsigned long pclk = dispc_plane_pclk_rate(plane);
/*
* FIXME how to determine the 'A' factor
@@ -2049,10 +2049,10 @@ static unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width,
return pclk * vf * hf;
}
-static unsigned long calc_core_clk_44xx(enum omap_channel channel, u16 width,
+static unsigned long calc_core_clk_44xx(enum omap_plane plane, u16 width,
u16 height, u16 out_width, u16 out_height)
{
- unsigned long pclk = dispc_mgr_pclk_rate(channel);
+ unsigned long pclk = dispc_plane_pclk_rate(plane);
if (width > out_width)
return DIV_ROUND_UP(pclk, out_width) * width;
@@ -2060,7 +2060,7 @@ static unsigned long calc_core_clk_44xx(enum omap_channel channel, u16 width,
return pclk;
}
-static int dispc_ovl_calc_scaling_24xx(enum omap_channel channel,
+static int dispc_ovl_calc_scaling_24xx(enum omap_plane plane,
const struct omap_video_timings *mgr_timings,
u16 width, u16 height, u16 out_width, u16 out_height,
enum omap_color_mode color_mode, bool *five_taps,
@@ -2072,12 +2072,13 @@ static int dispc_ovl_calc_scaling_24xx(enum omap_channel channel,
int min_factor = min(*decim_x, *decim_y);
const int maxsinglelinewidth dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
*five_taps = false;
do {
in_height = DIV_ROUND_UP(height, *decim_y);
in_width = DIV_ROUND_UP(width, *decim_x);
- *core_clk = dispc.feat->calc_core_clk(channel, in_width,
+ *core_clk = dispc.feat->calc_core_clk(plane, in_width,
in_height, out_width, out_height);
error = (in_width > maxsinglelinewidth || !*core_clk ||
*core_clk > dispc_core_clk_rate());
@@ -2100,7 +2101,7 @@ static int dispc_ovl_calc_scaling_24xx(enum omap_channel channel,
return 0;
}
-static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
+static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane,
const struct omap_video_timings *mgr_timings,
u16 width, u16 height, u16 out_width, u16 out_height,
enum omap_color_mode color_mode, bool *five_taps,
@@ -2116,18 +2117,19 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
do {
in_height = DIV_ROUND_UP(height, *decim_y);
in_width = DIV_ROUND_UP(width, *decim_x);
- *core_clk = calc_core_clk_five_taps(channel, mgr_timings,
+ *core_clk = calc_core_clk_five_taps(plane, mgr_timings,
in_width, in_height, out_width, out_height, color_mode);
- error = check_horiz_timing_omap3(channel, mgr_timings, pos_x,
- in_width, in_height, out_width, out_height);
+ error = check_horiz_timing_omap3(plane, mgr_timings,
+ pos_x, in_width, in_height, out_width,
+ out_height);
if (in_width > maxsinglelinewidth)
if (in_height > out_height &&
in_height < out_height * 2)
*five_taps = false;
if (!*five_taps)
- *core_clk = dispc.feat->calc_core_clk(channel, in_width,
+ *core_clk = dispc.feat->calc_core_clk(plane, in_width,
in_height, out_width, out_height);
error = (error || in_width > maxsinglelinewidth * 2 ||
@@ -2145,7 +2147,7 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
}
} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
- if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width, height,
+ if (check_horiz_timing_omap3(plane, mgr_timings, pos_x, width, height,
out_width, out_height)){
DSSERR("horizontal timing too tight\n");
return -EINVAL;
@@ -2164,7 +2166,7 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
return 0;
}
-static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
+static int dispc_ovl_calc_scaling_44xx(enum omap_plane plane,
const struct omap_video_timings *mgr_timings,
u16 width, u16 height, u16 out_width, u16 out_height,
enum omap_color_mode color_mode, bool *five_taps,
@@ -2176,9 +2178,10 @@ static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
u16 in_height = DIV_ROUND_UP(height, *decim_y);
const int maxsinglelinewidth dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+ unsigned long pclk = dispc_plane_pclk_rate(plane);
+
+ in_width_max = dispc_core_clk_rate() / DIV_ROUND_UP(pclk, out_width);
- in_width_max = dispc_core_clk_rate() /
- DIV_ROUND_UP(dispc_mgr_pclk_rate(channel), out_width);
*decim_x = DIV_ROUND_UP(width, in_width_max);
*decim_x = *decim_x > decim_x_min ? *decim_x : decim_x_min;
@@ -2195,13 +2198,13 @@ static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
return -EINVAL;
}
- *core_clk = dispc.feat->calc_core_clk(channel, in_width, in_height,
+ *core_clk = dispc.feat->calc_core_clk(plane, in_width, in_height,
out_width, out_height);
return 0;
}
static int dispc_ovl_calc_scaling(enum omap_plane plane,
- enum omap_overlay_caps caps, enum omap_channel channel,
+ enum omap_overlay_caps caps,
const struct omap_video_timings *mgr_timings,
u16 width, u16 height, u16 out_width, u16 out_height,
enum omap_color_mode color_mode, bool *five_taps,
@@ -2240,9 +2243,9 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
if (decim_y > *y_predecim || out_height > height * 8)
return -EINVAL;
- ret = dispc.feat->calc_scaling(channel, mgr_timings, width, height,
- out_width, out_height, color_mode, five_taps, x_predecim,
- y_predecim, &decim_x, &decim_y, pos_x, &core_clk);
+ ret = dispc.feat->calc_scaling(plane, mgr_timings, width, height,
+ out_width, out_height, color_mode, five_taps,
+ x_predecim, y_predecim, &decim_x, &decim_y, pos_x, &core_clk);
if (ret)
return ret;
@@ -2263,12 +2266,11 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
}
static int dispc_ovl_setup_common(enum omap_plane plane,
- enum omap_channel channel, enum omap_overlay_caps caps,
- u32 paddr, u32 p_uv_addr, u16 screen_width, int pos_x,
- int pos_y, u16 width, u16 height, u16 out_width, u16 out_height,
- enum omap_color_mode color_mode, u8 rotation, bool mirror,
- u8 zorder, u8 pre_mult_alpha, u8 global_alpha,
- enum omap_dss_rotation_type rotation_type,
+ enum omap_overlay_caps caps, u32 paddr, u32 p_uv_addr,
+ u16 screen_width, int pos_x, int pos_y, u16 width, u16 height,
+ u16 out_width, u16 out_height, enum omap_color_mode color_mode,
+ u8 rotation, bool mirror, u8 zorder, u8 pre_mult_alpha,
+ u8 global_alpha, enum omap_dss_rotation_type rotation_type,
bool replication, const struct omap_video_timings *mgr_timings)
{
bool five_taps = true;
@@ -2307,10 +2309,9 @@ static int dispc_ovl_setup_common(enum omap_plane plane,
if (!dss_feat_color_mode_supported(plane, color_mode))
return -EINVAL;
- r = dispc_ovl_calc_scaling(plane, caps, channel, mgr_timings,
- in_width, in_height, out_width, out_height,
- color_mode, &five_taps, &x_predecim, &y_predecim,
- pos_x);
+ r = dispc_ovl_calc_scaling(plane, caps, mgr_timings, in_width,
+ in_height, out_width, out_height, color_mode,
+ &five_taps, &x_predecim, &y_predecim, pos_x);
if (r)
return r;
@@ -2422,12 +2423,11 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
oi->pos_y, oi->width, oi->height, oi->out_width, oi->out_height,
oi->color_mode, oi->rotation, oi->mirror, channel, replication);
- r = dispc_ovl_setup_common(plane, channel, ovl->caps, oi->paddr,
- oi->p_uv_addr, oi->screen_width, oi->pos_x, oi->pos_y,
- oi->width, oi->height, oi->out_width, oi->out_height,
- oi->color_mode, oi->rotation, oi->mirror, oi->zorder,
- oi->pre_mult_alpha, oi->global_alpha, oi->rotation_type,
- replication, mgr_timings);
+ r = dispc_ovl_setup_common(plane, ovl->caps, oi->paddr, oi->p_uv_addr,
+ oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height,
+ oi->out_width, oi->out_height, oi->color_mode, oi->rotation,
+ oi->mirror, oi->zorder, oi->pre_mult_alpha, oi->global_alpha,
+ oi->rotation_type, replication, mgr_timings);
return r;
}
@@ -2987,6 +2987,23 @@ unsigned long dispc_core_clk_rate(void)
return fclk / lcd;
}
+static unsigned long dispc_plane_pclk_rate(enum omap_plane plane)
+{
+ enum omap_channel channel = dispc_ovl_get_channel_out(plane);
+
+ return dispc_mgr_pclk_rate(channel);
+}
+
+static unsigned long dispc_plane_lclk_rate(enum omap_plane plane)
+{
+ enum omap_channel channel = dispc_ovl_get_channel_out(plane);
+
+ if (dss_mgr_is_lcd(channel))
+ return dispc_mgr_lclk_rate(channel);
+ else
+ return dispc_fclk_rate();
+
+}
static void dispc_dump_clocks_channel(struct seq_file *s, enum omap_channel channel)
{
int lcd, pcd;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 07/18] OMAPDSS: DIPSC: Relax scaling limitations when in memory to memory mode
From: Archit Taneja @ 2012-09-25 6:31 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1348553993-8083-1-git-send-email-archit@ti.com>
The scalers of overlays and writeback do not have any constraints on downscale
ratio when operating in memory to memory mode.
This is because in memory to memory mode, we aren't connected to a display which
needs data output at the rate of pixel clock. The scalers can perform as much
downscaling as needed, the rate at which the scaler outputs is adjusted
accordingly.
Relax constraints related to downscaling based on whether the input overlays are
connected to writeback in memory to memory mode. We pass a mem_to_mem boolean
parameter to dispc_ovl_setup() from APPLY. This is currently set to false, this
will later be configured to the correct value based on whether the overlay is
connected to writeback or not. Do the same later for writeback when writeback is
configured.
In the scaling calculation code, we calculate the minimum amount of core clock we
need to achieve the required downscaling. If we are in memory to memory mode, we
set this to a very small value(1 in this case), this value would always be
lesser than the actual DISPC core clock value, and hence the scaling checks
would succeed.
We take care that pixel clock isn't calculated for writeback and the overlays
connected to it when in memory to memory mode. A pixel clock in such cases
doesn't make sense.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/apply.c | 2 +-
drivers/video/omap2/dss/dispc.c | 60 ++++++++++++++++++++++++++-------------
drivers/video/omap2/dss/dss.h | 3 +-
3 files changed, 44 insertions(+), 21 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 2b1fa85..19d66f4 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -584,7 +584,7 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)
replication = dss_ovl_use_replication(mp->lcd_config, oi->color_mode);
- r = dispc_ovl_setup(ovl->id, oi, replication, &mp->timings);
+ r = dispc_ovl_setup(ovl->id, oi, replication, &mp->timings, false);
if (r) {
/*
* We can't do much here, as this function can be called from
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index edb31fd..ba65ebd 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -91,9 +91,10 @@ struct dispc_features {
u16 width, u16 height, u16 out_width, u16 out_height,
enum omap_color_mode color_mode, bool *five_taps,
int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
- u16 pos_x, unsigned long *core_clk);
+ u16 pos_x, unsigned long *core_clk, bool mem_to_mem);
unsigned long (*calc_core_clk) (enum omap_plane plane,
- u16 width, u16 height, u16 out_width, u16 out_height);
+ u16 width, u16 height, u16 out_width, u16 out_height,
+ bool mem_to_mem);
u8 num_fifos;
/* swap GFX & WB fifos */
@@ -2012,7 +2013,7 @@ static unsigned long calc_core_clk_five_taps(enum omap_plane plane,
}
static unsigned long calc_core_clk_24xx(enum omap_plane plane, u16 width,
- u16 height, u16 out_width, u16 out_height)
+ u16 height, u16 out_width, u16 out_height, bool mem_to_mem)
{
unsigned long pclk = dispc_plane_pclk_rate(plane);
@@ -2023,7 +2024,7 @@ static unsigned long calc_core_clk_24xx(enum omap_plane plane, u16 width,
}
static unsigned long calc_core_clk_34xx(enum omap_plane plane, u16 width,
- u16 height, u16 out_width, u16 out_height)
+ u16 height, u16 out_width, u16 out_height, bool mem_to_mem)
{
unsigned int hf, vf;
unsigned long pclk = dispc_plane_pclk_rate(plane);
@@ -2050,9 +2051,20 @@ static unsigned long calc_core_clk_34xx(enum omap_plane plane, u16 width,
}
static unsigned long calc_core_clk_44xx(enum omap_plane plane, u16 width,
- u16 height, u16 out_width, u16 out_height)
+ u16 height, u16 out_width, u16 out_height, bool mem_to_mem)
{
- unsigned long pclk = dispc_plane_pclk_rate(plane);
+ unsigned long pclk;
+
+ /*
+ * If the overlay/writeback is in mem to mem mode, there are no
+ * downscaling limitations with respect to pixel clock, return 1 as
+ * required core clock to represent that we have sufficient enough
+ * core clock to do maximum downscaling
+ */
+ if (mem_to_mem)
+ return 1;
+
+ pclk = dispc_plane_pclk_rate(plane);
if (width > out_width)
return DIV_ROUND_UP(pclk, out_width) * width;
@@ -2065,7 +2077,7 @@ static int dispc_ovl_calc_scaling_24xx(enum omap_plane plane,
u16 width, u16 height, u16 out_width, u16 out_height,
enum omap_color_mode color_mode, bool *five_taps,
int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
- u16 pos_x, unsigned long *core_clk)
+ u16 pos_x, unsigned long *core_clk, bool mem_to_mem)
{
int error;
u16 in_width, in_height;
@@ -2079,7 +2091,7 @@ static int dispc_ovl_calc_scaling_24xx(enum omap_plane plane,
in_height = DIV_ROUND_UP(height, *decim_y);
in_width = DIV_ROUND_UP(width, *decim_x);
*core_clk = dispc.feat->calc_core_clk(plane, in_width,
- in_height, out_width, out_height);
+ in_height, out_width, out_height, mem_to_mem);
error = (in_width > maxsinglelinewidth || !*core_clk ||
*core_clk > dispc_core_clk_rate());
if (error) {
@@ -2106,7 +2118,7 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane,
u16 width, u16 height, u16 out_width, u16 out_height,
enum omap_color_mode color_mode, bool *five_taps,
int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
- u16 pos_x, unsigned long *core_clk)
+ u16 pos_x, unsigned long *core_clk, bool mem_to_mem)
{
int error;
u16 in_width, in_height;
@@ -2130,7 +2142,8 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane,
*five_taps = false;
if (!*five_taps)
*core_clk = dispc.feat->calc_core_clk(plane, in_width,
- in_height, out_width, out_height);
+ in_height, out_width, out_height,
+ mem_to_mem);
error = (error || in_width > maxsinglelinewidth * 2 ||
(in_width > maxsinglelinewidth && *five_taps) ||
@@ -2171,7 +2184,7 @@ static int dispc_ovl_calc_scaling_44xx(enum omap_plane plane,
u16 width, u16 height, u16 out_width, u16 out_height,
enum omap_color_mode color_mode, bool *five_taps,
int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
- u16 pos_x, unsigned long *core_clk)
+ u16 pos_x, unsigned long *core_clk, bool mem_to_mem)
{
u16 in_width, in_width_max;
int decim_x_min = *decim_x;
@@ -2179,8 +2192,13 @@ static int dispc_ovl_calc_scaling_44xx(enum omap_plane plane,
const int maxsinglelinewidth dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
unsigned long pclk = dispc_plane_pclk_rate(plane);
+ const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
- in_width_max = dispc_core_clk_rate() / DIV_ROUND_UP(pclk, out_width);
+ if (mem_to_mem)
+ in_width_max = DIV_ROUND_UP(out_width, maxdownscale);
+ else
+ in_width_max = dispc_core_clk_rate() /
+ DIV_ROUND_UP(pclk, out_width);
*decim_x = DIV_ROUND_UP(width, in_width_max);
@@ -2199,7 +2217,7 @@ static int dispc_ovl_calc_scaling_44xx(enum omap_plane plane,
}
*core_clk = dispc.feat->calc_core_clk(plane, in_width, in_height,
- out_width, out_height);
+ out_width, out_height, mem_to_mem);
return 0;
}
@@ -2208,7 +2226,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
const struct omap_video_timings *mgr_timings,
u16 width, u16 height, u16 out_width, u16 out_height,
enum omap_color_mode color_mode, bool *five_taps,
- int *x_predecim, int *y_predecim, u16 pos_x)
+ int *x_predecim, int *y_predecim, u16 pos_x, bool mem_to_mem)
{
const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
const int max_decim_limit = 16;
@@ -2245,7 +2263,8 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
ret = dispc.feat->calc_scaling(plane, mgr_timings, width, height,
out_width, out_height, color_mode, five_taps,
- x_predecim, y_predecim, &decim_x, &decim_y, pos_x, &core_clk);
+ x_predecim, y_predecim, &decim_x, &decim_y, pos_x, &core_clk,
+ mem_to_mem);
if (ret)
return ret;
@@ -2271,7 +2290,8 @@ static int dispc_ovl_setup_common(enum omap_plane plane,
u16 out_width, u16 out_height, enum omap_color_mode color_mode,
u8 rotation, bool mirror, u8 zorder, u8 pre_mult_alpha,
u8 global_alpha, enum omap_dss_rotation_type rotation_type,
- bool replication, const struct omap_video_timings *mgr_timings)
+ bool replication, const struct omap_video_timings *mgr_timings,
+ bool mem_to_mem)
{
bool five_taps = true;
bool fieldmode = 0;
@@ -2311,7 +2331,8 @@ static int dispc_ovl_setup_common(enum omap_plane plane,
r = dispc_ovl_calc_scaling(plane, caps, mgr_timings, in_width,
in_height, out_width, out_height, color_mode,
- &five_taps, &x_predecim, &y_predecim, pos_x);
+ &five_taps, &x_predecim, &y_predecim, pos_x,
+ mem_to_mem);
if (r)
return r;
@@ -2409,7 +2430,8 @@ static int dispc_ovl_setup_common(enum omap_plane plane,
}
int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
- bool replication, const struct omap_video_timings *mgr_timings)
+ bool replication, const struct omap_video_timings *mgr_timings,
+ bool mem_to_mem)
{
int r;
struct omap_overlay *ovl = omap_dss_get_overlay(plane);
@@ -2427,7 +2449,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height,
oi->out_width, oi->out_height, oi->color_mode, oi->rotation,
oi->mirror, oi->zorder, oi->pre_mult_alpha, oi->global_alpha,
- oi->rotation_type, replication, mgr_timings);
+ oi->rotation_type, replication, mgr_timings, mem_to_mem);
return r;
}
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 43210b8..04a1eda 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -441,7 +441,8 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
u32 *fifo_low, u32 *fifo_high, bool use_fifomerge,
bool manual_update);
int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
- bool replication, const struct omap_video_timings *mgr_timings);
+ bool replication, const struct omap_video_timings *mgr_timings,
+ bool mem_to_mem);
int dispc_ovl_enable(enum omap_plane plane, bool enable);
void dispc_ovl_set_channel_out(enum omap_plane plane,
enum omap_channel channel);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 08/18] OMAPDSS: DISPC: Allow both upscaling and downscaling of chroma
From: Archit Taneja @ 2012-09-25 6:31 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1348553993-8083-1-git-send-email-archit@ti.com>
In the function dispc_plane_set_scaling_uv(), create a parameter which tells if
we want to upscale or downscale the chroma plane.
Downscaling of chroma is required by writeback pipeline for converting the input
YUV444 color format to YUV422 or NV12.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dispc.c | 32 ++++++++++++++++++++++----------
1 file changed, 22 insertions(+), 10 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index ba65ebd..e42e902 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1457,6 +1457,7 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane,
{
int scale_x = out_width != orig_width;
int scale_y = out_height != orig_height;
+ bool chroma_upscale = true;
if (!dss_has_feature(FEAT_HANDLE_UV_SEPARATE))
return;
@@ -1473,23 +1474,34 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane,
switch (color_mode) {
case OMAP_DSS_COLOR_NV12:
- /* UV is subsampled by 2 vertically*/
- orig_height >>= 1;
- /* UV is subsampled by 2 horz.*/
- orig_width >>= 1;
+ if (chroma_upscale) {
+ /* UV is subsampled by 2 horizontally and vertically */
+ orig_height >>= 1;
+ orig_width >>= 1;
+ } else {
+ /* UV is downsampled by 2 horizontally and vertically */
+ orig_height <<= 1;
+ orig_width <<= 1;
+ }
+
break;
case OMAP_DSS_COLOR_YUV2:
case OMAP_DSS_COLOR_UYVY:
- /*For YUV422 with 90/270 rotation,
- *we don't upsample chroma
- */
+ /* For YUV422 with 90/270 rotation, we don't upsample chroma */
if (rotation = OMAP_DSS_ROT_0 ||
- rotation = OMAP_DSS_ROT_180)
- /* UV is subsampled by 2 hrz*/
- orig_width >>= 1;
+ rotation = OMAP_DSS_ROT_180) {
+ if (chroma_upscale)
+ /* UV is subsampled by 2 horizontally */
+ orig_width >>= 1;
+ else
+ /* UV is downsampled by 2 horizontally */
+ orig_width <<= 1;
+ }
+
/* must use FIR for YUV422 if rotated */
if (rotation != OMAP_DSS_ROT_0)
scale_x = scale_y = true;
+
break;
default:
BUG();
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 09/18] OMAPDSS: DISPC: Add writeback register offsets and dss features structs
From: Archit Taneja @ 2012-09-25 6:31 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1348553993-8083-1-git-send-email-archit@ti.com>
Since writeback has many overlay like properties, and most of it's registers are
similar to that of overlays, it's possible to reuse most of the overlay related
DISPC code for writeback when considering it as a plane. Writeback was added as
a plane in the omap_plane field as OMAP_DSS_WB.
Add the writeback register offsets in dispc.h, add minimal WB plane related info
needed in dss_features. Add a function which returns the number of writeback
pipelines an OMAP version has.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dispc.h | 33 ++++++++++++++++++++++++++++++++
drivers/video/omap2/dss/dss_features.c | 19 ++++++++++++++++++
drivers/video/omap2/dss/dss_features.h | 1 +
3 files changed, 53 insertions(+)
diff --git a/drivers/video/omap2/dss/dispc.h b/drivers/video/omap2/dss/dispc.h
index 42e56cc..222363c 100644
--- a/drivers/video/omap2/dss/dispc.h
+++ b/drivers/video/omap2/dss/dispc.h
@@ -373,6 +373,7 @@ static inline u16 DISPC_BA0_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x0000;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0008;
default:
BUG();
@@ -388,6 +389,7 @@ static inline u16 DISPC_BA1_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x0004;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x000C;
default:
BUG();
@@ -407,6 +409,8 @@ static inline u16 DISPC_BA0_UV_OFFSET(enum omap_plane plane)
return 0x04BC;
case OMAP_DSS_VIDEO3:
return 0x0310;
+ case OMAP_DSS_WB:
+ return 0x0118;
default:
BUG();
return 0;
@@ -425,6 +429,8 @@ static inline u16 DISPC_BA1_UV_OFFSET(enum omap_plane plane)
return 0x04C0;
case OMAP_DSS_VIDEO3:
return 0x0314;
+ case OMAP_DSS_WB:
+ return 0x011C;
default:
BUG();
return 0;
@@ -454,6 +460,7 @@ static inline u16 DISPC_SIZE_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x000C;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x00A8;
default:
BUG();
@@ -470,6 +477,7 @@ static inline u16 DISPC_ATTR_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x0010;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0070;
default:
BUG();
@@ -489,6 +497,8 @@ static inline u16 DISPC_ATTR2_OFFSET(enum omap_plane plane)
return 0x04DC;
case OMAP_DSS_VIDEO3:
return 0x032C;
+ case OMAP_DSS_WB:
+ return 0x0310;
default:
BUG();
return 0;
@@ -504,6 +514,7 @@ static inline u16 DISPC_FIFO_THRESH_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x0014;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x008C;
default:
BUG();
@@ -537,6 +548,7 @@ static inline u16 DISPC_ROW_INC_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x001C;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x00A4;
default:
BUG();
@@ -553,6 +565,7 @@ static inline u16 DISPC_PIX_INC_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x0020;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0098;
default:
BUG();
@@ -602,6 +615,7 @@ static inline u16 DISPC_FIR_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x0024;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0090;
default:
BUG();
@@ -621,6 +635,8 @@ static inline u16 DISPC_FIR2_OFFSET(enum omap_plane plane)
return 0x055C;
case OMAP_DSS_VIDEO3:
return 0x0424;
+ case OMAP_DSS_WB:
+ return 0x290;
default:
BUG();
return 0;
@@ -637,6 +653,7 @@ static inline u16 DISPC_PIC_SIZE_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x0028;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0094;
default:
BUG();
@@ -655,6 +672,7 @@ static inline u16 DISPC_ACCU0_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x002C;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0000;
default:
BUG();
@@ -674,6 +692,8 @@ static inline u16 DISPC_ACCU2_0_OFFSET(enum omap_plane plane)
return 0x0560;
case OMAP_DSS_VIDEO3:
return 0x0428;
+ case OMAP_DSS_WB:
+ return 0x0294;
default:
BUG();
return 0;
@@ -690,6 +710,7 @@ static inline u16 DISPC_ACCU1_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x0030;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0004;
default:
BUG();
@@ -709,6 +730,8 @@ static inline u16 DISPC_ACCU2_1_OFFSET(enum omap_plane plane)
return 0x0564;
case OMAP_DSS_VIDEO3:
return 0x042C;
+ case OMAP_DSS_WB:
+ return 0x0298;
default:
BUG();
return 0;
@@ -726,6 +749,7 @@ static inline u16 DISPC_FIR_COEF_H_OFFSET(enum omap_plane plane, u16 i)
case OMAP_DSS_VIDEO2:
return 0x0034 + i * 0x8;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0010 + i * 0x8;
default:
BUG();
@@ -746,6 +770,8 @@ static inline u16 DISPC_FIR_COEF_H2_OFFSET(enum omap_plane plane, u16 i)
return 0x0568 + i * 0x8;
case OMAP_DSS_VIDEO3:
return 0x0430 + i * 0x8;
+ case OMAP_DSS_WB:
+ return 0x02A0 + i * 0x8;
default:
BUG();
return 0;
@@ -763,6 +789,7 @@ static inline u16 DISPC_FIR_COEF_HV_OFFSET(enum omap_plane plane, u16 i)
case OMAP_DSS_VIDEO2:
return 0x0038 + i * 0x8;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0014 + i * 0x8;
default:
BUG();
@@ -783,6 +810,8 @@ static inline u16 DISPC_FIR_COEF_HV2_OFFSET(enum omap_plane plane, u16 i)
return 0x056C + i * 0x8;
case OMAP_DSS_VIDEO3:
return 0x0434 + i * 0x8;
+ case OMAP_DSS_WB:
+ return 0x02A4 + i * 0x8;
default:
BUG();
return 0;
@@ -799,6 +828,7 @@ static inline u16 DISPC_CONV_COEF_OFFSET(enum omap_plane plane, u16 i)
case OMAP_DSS_VIDEO1:
case OMAP_DSS_VIDEO2:
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0074 + i * 0x4;
default:
BUG();
@@ -818,6 +848,7 @@ static inline u16 DISPC_FIR_COEF_V_OFFSET(enum omap_plane plane, u16 i)
case OMAP_DSS_VIDEO2:
return 0x00B4 + i * 0x4;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0050 + i * 0x4;
default:
BUG();
@@ -838,6 +869,8 @@ static inline u16 DISPC_FIR_COEF_V2_OFFSET(enum omap_plane plane, u16 i)
return 0x05A8 + i * 0x4;
case OMAP_DSS_VIDEO3:
return 0x0470 + i * 0x4;
+ case OMAP_DSS_WB:
+ return 0x02E0 + i * 0x4;
default:
BUG();
return 0;
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 8b6c79f..5968fd8 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -46,6 +46,7 @@ struct omap_dss_features {
const int num_mgrs;
const int num_ovls;
+ const int num_wbs;
const enum omap_display_type *supported_displays;
const enum omap_dss_output_id *supported_outputs;
const enum omap_color_mode *supported_color_modes;
@@ -265,6 +266,16 @@ static const enum omap_color_mode omap4_dss_supported_color_modes[] = {
OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 |
OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 |
OMAP_DSS_COLOR_RGBX32,
+
+ /* OMAP_DSS_WB */
+ OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB12U |
+ OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_ARGB16_1555 |
+ OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_NV12 |
+ OMAP_DSS_COLOR_RGBA16 | OMAP_DSS_COLOR_RGB24U |
+ OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_UYVY |
+ OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 |
+ OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 |
+ OMAP_DSS_COLOR_RGBX32,
};
static const enum omap_overlay_caps omap2_dss_overlay_caps[] = {
@@ -576,6 +587,7 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = {
.num_mgrs = 3,
.num_ovls = 4,
+ .num_wbs = 1,
.supported_displays = omap4_dss_supported_displays,
.supported_outputs = omap4_dss_supported_outputs,
.supported_color_modes = omap4_dss_supported_color_modes,
@@ -597,6 +609,7 @@ static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = {
.num_mgrs = 3,
.num_ovls = 4,
+ .num_wbs = 1,
.supported_displays = omap4_dss_supported_displays,
.supported_outputs = omap4_dss_supported_outputs,
.supported_color_modes = omap4_dss_supported_color_modes,
@@ -618,6 +631,7 @@ static const struct omap_dss_features omap4_dss_features = {
.num_mgrs = 3,
.num_ovls = 4,
+ .num_wbs = 1,
.supported_displays = omap4_dss_supported_displays,
.supported_outputs = omap4_dss_supported_outputs,
.supported_color_modes = omap4_dss_supported_color_modes,
@@ -674,6 +688,11 @@ int dss_feat_get_num_ovls(void)
return omap_current_dss_features->num_ovls;
}
+int dss_feat_get_num_wbs(void)
+{
+ return omap_current_dss_features->num_wbs;
+}
+
unsigned long dss_feat_get_param_min(enum dss_range_param param)
{
return omap_current_dss_features->dss_params[param].min;
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index fb8ed59..66fd9f7 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -102,6 +102,7 @@ enum dss_range_param {
/* DSS Feature Functions */
int dss_feat_get_num_mgrs(void);
int dss_feat_get_num_ovls(void);
+int dss_feat_get_num_wbs(void);
unsigned long dss_feat_get_param_min(enum dss_range_param param);
unsigned long dss_feat_get_param_max(enum dss_range_param param);
enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 10/18] OMAPDSS: DISPC: Configure input and output sizes for writeback
From: Archit Taneja @ 2012-09-25 6:31 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1348553993-8083-1-git-send-email-archit@ti.com>
Writeback uses the WB_PICTURE_SIZE register to define the size of the content
written to memory, this is the output of the scaler. It uses the WB_SIZE
register to define the size of the content coming from the overlay/manager to
which it is connected, this is the input to the scaler. This naming is different
as compared to overlays.
Add checks for writeback in dispc_ovl_set_input_size() and
dispc_ovl_set_output_size() to write to the correct registers.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dispc.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index e42e902..04fdd33 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -719,7 +719,7 @@ static void dispc_ovl_set_input_size(enum omap_plane plane, int width,
{
u32 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
- if (plane = OMAP_DSS_GFX)
+ if (plane = OMAP_DSS_GFX || plane = OMAP_DSS_WB)
dispc_write_reg(DISPC_OVL_SIZE(plane), val);
else
dispc_write_reg(DISPC_OVL_PICTURE_SIZE(plane), val);
@@ -734,7 +734,10 @@ static void dispc_ovl_set_output_size(enum omap_plane plane, int width,
val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
- dispc_write_reg(DISPC_OVL_SIZE(plane), val);
+ if (plane = OMAP_DSS_WB)
+ dispc_write_reg(DISPC_OVL_PICTURE_SIZE(plane), val);
+ else
+ dispc_write_reg(DISPC_OVL_SIZE(plane), val);
}
static void dispc_ovl_set_zorder(enum omap_plane plane,
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 11/18] OMAPDSS: DISPC: Downscale chroma if plane is writeback
From: Archit Taneja @ 2012-09-25 6:31 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1348553993-8083-1-git-send-email-archit@ti.com>
When converting YUYV444 content to YUV422 or NV12 formats through writeback
pipeline, the scaler needs to downscale the chroma plane. Ensure that chroma
is downscaled when the pipeline is writeback.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dispc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 04fdd33..4f36e83 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1460,7 +1460,7 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane,
{
int scale_x = out_width != orig_width;
int scale_y = out_height != orig_height;
- bool chroma_upscale = true;
+ bool chroma_upscale = plane != OMAP_DSS_WB ? true : false;
if (!dss_has_feature(FEAT_HANDLE_UV_SEPARATE))
return;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 12/18] OMAPDSS: DISPC: Don't set chroma resampling bit for writeback
From: Archit Taneja @ 2012-09-25 6:31 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1348553993-8083-1-git-send-email-archit@ti.com>
The bit YUVCHROMARESAMPLING isn't there for writeback in DISPC_WB_ATTRIBUTES2.
It isn't there because we don't upsample chroma like for video pipelines, we
downsample chroma in writeback to get YUV422 or NV12 formats from the YUV444
input.
Ignore this bit in dispc_ovl_set_scaling_uv() if the plane is OMAP_DSS_WB.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dispc.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 4f36e83..d9ca7bf 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1468,7 +1468,8 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane,
color_mode != OMAP_DSS_COLOR_UYVY &&
color_mode != OMAP_DSS_COLOR_NV12)) {
/* reset chroma resampling for RGB formats */
- REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), 0, 8, 8);
+ if (plane != OMAP_DSS_WB)
+ REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), 0, 8, 8);
return;
}
@@ -1520,8 +1521,10 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane,
out_width, out_height, five_taps,
rotation, DISPC_COLOR_COMPONENT_UV);
- REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane),
- (scale_x || scale_y) ? 1 : 0, 8, 8);
+ if (plane != OMAP_DSS_WB)
+ REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane),
+ (scale_x || scale_y) ? 1 : 0, 8, 8);
+
/* set H scaling */
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_x ? 1 : 0, 5, 5);
/* set V scaling */
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 13/18] OMAPDSS: DISPC: Add function to set channel in for writeback
From: Archit Taneja @ 2012-09-25 6:31 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1348553993-8083-1-git-send-email-archit@ti.com>
Writeback can take input from either one of the overlays, or one of the overlay
managers. Add an enum which represents the channel_in for writeback, and maps
to the register field programming.
Add a function to configure channel in for writeback. This will be used later in
APPLY.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dispc.c | 7 +++++++
drivers/video/omap2/dss/dss.h | 13 +++++++++++++
2 files changed, 20 insertions(+)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index d9ca7bf..6d482f5 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -983,6 +983,13 @@ static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane)
return channel;
}
+void dispc_wb_set_channel_in(enum dss_writeback_channel channel)
+{
+ enum omap_plane plane = OMAP_DSS_WB;
+
+ REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), channel, 18, 16);
+}
+
static void dispc_ovl_set_burst_size(enum omap_plane plane,
enum omap_burst_size burst_size)
{
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 04a1eda..872e420 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -113,6 +113,17 @@ enum dss_dsi_content_type {
DSS_DSI_CONTENT_GENERIC,
};
+enum dss_writeback_channel {
+ DSS_WB_LCD1_MGR = 0,
+ DSS_WB_LCD2_MGR = 1,
+ DSS_WB_TV_MGR = 2,
+ DSS_WB_OVL0 = 3,
+ DSS_WB_OVL1 = 4,
+ DSS_WB_OVL2 = 5,
+ DSS_WB_OVL3 = 6,
+ DSS_WB_LCD3_MGR = 7,
+};
+
struct dss_clock_info {
/* rates that we get with dividers below */
unsigned long fck;
@@ -471,6 +482,8 @@ int dispc_mgr_get_clock_div(enum omap_channel channel,
void dispc_mgr_setup(enum omap_channel channel,
struct omap_overlay_manager_info *info);
+void dispc_wb_set_channel_in(enum dss_writeback_channel channel);
+
/* VENC */
#ifdef CONFIG_OMAP2_DSS_VENC
int venc_init_platform_driver(void) __init;
--
1.7.9.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox