Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ed914f69 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'of_videomode_helper' of git://git.pengutronix.de/git/str/linux into drm-next

videomode helpers for of + devicetree stuff, required for new kms drivers

(not the fbdev maintainer).

* tag 'of_videomode_helper' of git://git.pengutronix.de/git/str/linux:
  drm_modes: add of_videomode helpers
  drm_modes: add videomode helpers
  fbmon: add of_videomode helpers
  fbmon: add videomode helpers
  video: add of helper for display timings/videomode
  video: add display_timing and videomode
  viafb: rename display_timing to via_display_timing
parents bb0f78dd edb37a95
Loading
Loading
Loading
Loading
+109 −0
Original line number Diff line number Diff line
display-timing bindings
=======================

display-timings node
--------------------

required properties:
 - none

optional properties:
 - native-mode: The native mode for the display, in case multiple modes are
		provided. When omitted, assume the first node is the native.

timing subnode
--------------

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-frequency: display clock in Hz

optional properties:
 - hsync-active: hsync pulse is active low/high/ignored
 - vsync-active: vsync pulse is active low/high/ignored
 - de-active: data-enable pulse is active low/high/ignored
 - pixelclk-active: with
			- active high = drive pixel data on rising edge/
					sample data on falling edge
			- active low  = drive pixel data on falling edge/
					sample data on rising edge
			- ignored     = ignored
 - interlaced (bool): boolean to enable interlaced mode
 - doublescan (bool): boolean to enable doublescan mode

All the optional properties that are not bool follow the following logic:
    <1>: high active
    <0>: low active
    omitted: not used on hardware

There are different ways of describing the capabilities of a display. The
devicetree representation corresponds to the one commonly found in datasheets
for displays. If a display supports multiple signal timings, the native-mode
can be specified.

The parameters are defined as:

  +----------+-------------------------------------+----------+-------+
  |          |        ↑                            |          |       |
  |          |        |vback_porch                 |          |       |
  |          |        ↓                            |          |       |
  +----------#######################################----------+-------+
  |          #        ↑                            #          |       |
  |          #        |                            #          |       |
  |  hback   #        |                            #  hfront  | hsync |
  |   porch  #        |       hactive              #  porch   |  len  |
  |<-------->#<-------+--------------------------->#<-------->|<----->|
  |          #        |                            #          |       |
  |          #        |vactive                     #          |       |
  |          #        |                            #          |       |
  |          #        ↓                            #          |       |
  +----------#######################################----------+-------+
  |          |        ↑                            |          |       |
  |          |        |vfront_porch                |          |       |
  |          |        ↓                            |          |       |
  +----------+-------------------------------------+----------+-------+
  |          |        ↑                            |          |       |
  |          |        |vsync_len                   |          |       |
  |          |        ↓                            |          |       |
  +----------+-------------------------------------+----------+-------+

Example:

	display-timings {
		native-mode = <&timing0>;
		timing0: 1080p24 {
			/* 1920x1080p24 */
			clock-frequency = <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 = <1>;
		};
	};

Every required property also supports the use of ranges, so the commonly used
datasheet description with minimum, typical and maximum values can be used.

Example:

	timing1: timing {
		/* 1920x1080p24 */
		clock-frequency = <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>;
	};
+70 −0
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@
#include <linux/export.h>
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
#include <video/of_videomode.h>
#include <video/videomode.h>

/**
 * drm_mode_debug_printmodeline - debug print a mode
@@ -504,6 +506,74 @@ drm_gtf_mode(struct drm_device *dev, int hdisplay, int vdisplay, int vrefresh,
}
EXPORT_SYMBOL(drm_gtf_mode);

#if IS_ENABLED(CONFIG_VIDEOMODE)
int drm_display_mode_from_videomode(const struct videomode *vm,
				    struct drm_display_mode *dmode)
{
	dmode->hdisplay = vm->hactive;
	dmode->hsync_start = dmode->hdisplay + vm->hfront_porch;
	dmode->hsync_end = dmode->hsync_start + vm->hsync_len;
	dmode->htotal = dmode->hsync_end + vm->hback_porch;

	dmode->vdisplay = vm->vactive;
	dmode->vsync_start = dmode->vdisplay + vm->vfront_porch;
	dmode->vsync_end = dmode->vsync_start + vm->vsync_len;
	dmode->vtotal = dmode->vsync_end + vm->vback_porch;

	dmode->clock = vm->pixelclock / 1000;

	dmode->flags = 0;
	if (vm->dmt_flags & VESA_DMT_HSYNC_HIGH)
		dmode->flags |= DRM_MODE_FLAG_PHSYNC;
	else if (vm->dmt_flags & VESA_DMT_HSYNC_LOW)
		dmode->flags |= DRM_MODE_FLAG_NHSYNC;
	if (vm->dmt_flags & VESA_DMT_VSYNC_HIGH)
		dmode->flags |= DRM_MODE_FLAG_PVSYNC;
	else if (vm->dmt_flags & VESA_DMT_VSYNC_LOW)
		dmode->flags |= DRM_MODE_FLAG_NVSYNC;
	if (vm->data_flags & DISPLAY_FLAGS_INTERLACED)
		dmode->flags |= DRM_MODE_FLAG_INTERLACE;
	if (vm->data_flags & DISPLAY_FLAGS_DOUBLESCAN)
		dmode->flags |= DRM_MODE_FLAG_DBLSCAN;
	drm_mode_set_name(dmode);

	return 0;
}
EXPORT_SYMBOL_GPL(drm_display_mode_from_videomode);
#endif

#if IS_ENABLED(CONFIG_OF_VIDEOMODE)
/**
 * of_get_drm_display_mode - get a drm_display_mode from devicetree
 * @np: device_node with the timing specification
 * @dmode: will be set to the return value
 * @index: index into the list of display timings in devicetree
 *
 * This function is expensive and should only be used, if only one mode is to be
 * read from DT. To get multiple modes start with of_get_display_timings and
 * work with that instead.
 */
int of_get_drm_display_mode(struct device_node *np,
			    struct drm_display_mode *dmode, int index)
{
	struct videomode vm;
	int ret;

	ret = of_get_videomode(np, &vm, index);
	if (ret)
		return ret;

	drm_display_mode_from_videomode(&vm, dmode);

	pr_debug("%s: got %dx%d display mode from %s\n",
		of_node_full_name(np), vm.hactive, vm.vactive, np->name);
	drm_mode_debug_printmodeline(dmode);

	return 0;
}
EXPORT_SYMBOL_GPL(of_get_drm_display_mode);
#endif

/**
 * drm_mode_set_name - set the name on a mode
 * @mode: name will be set in this mode
+21 −0
Original line number Diff line number Diff line
@@ -33,6 +33,27 @@ config VIDEO_OUTPUT_CONTROL
	  This framework adds support for low-level control of the video 
	  output switch.

config DISPLAY_TIMING
       bool

config VIDEOMODE
       bool

config OF_DISPLAY_TIMING
	bool "Enable device tree display timing support"
	depends on OF
	select DISPLAY_TIMING
	help
	  helper to parse display timings from the devicetree

config OF_VIDEOMODE
	bool "Enable device tree videomode support"
	depends on OF
	select VIDEOMODE
	select OF_DISPLAY_TIMING
	help
	  helper to get videomodes from the devicetree

menuconfig FB
	tristate "Support for frame buffer devices"
	---help---
+4 −0
Original line number Diff line number Diff line
@@ -168,3 +168,7 @@ obj-$(CONFIG_FB_VIRTUAL) += vfb.o

#video output switch sysfs driver
obj-$(CONFIG_VIDEO_OUTPUT_CONTROL) += output.o
obj-$(CONFIG_DISPLAY_TIMING) += display_timing.o
obj-$(CONFIG_OF_DISPLAY_TIMING) += of_display_timing.o
obj-$(CONFIG_VIDEOMODE) += videomode.o
obj-$(CONFIG_OF_VIDEOMODE) += of_videomode.o
+24 −0
Original line number Diff line number Diff line
/*
 * generic display timing functions
 *
 * Copyright (c) 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>, Pengutronix
 *
 * This file is released under the GPLv2
 */

#include <linux/export.h>
#include <linux/slab.h>
#include <video/display_timing.h>

void display_timings_release(struct display_timings *disp)
{
	if (disp->timings) {
		unsigned int i;

		for (i = 0; i < disp->num_timings; i++)
			kfree(disp->timings[i]);
		kfree(disp->timings);
	}
	kfree(disp);
}
EXPORT_SYMBOL_GPL(display_timings_release);
Loading