diff mbox

[58/72] imx-drm: parallel-display: Add interface-pix-map DT property

Message ID 1414796095-10107-59-git-send-email-steve_longerbeam@mentor.com (mailing list archive)
State New, archived
Headers show

Commit Message

Steve Longerbeam Oct. 31, 2014, 10:54 p.m. UTC
Define a new devicetree property "interface-pix-map" for use by
i.MX DRM display drivers. This property defines a DI interface
pixel bus mapping. Implement the parsing of this property in the
parallel display driver, and pass on the mapping to
imx_drm_panel_format().

See Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt
for a complete description of this property.

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
---
 .../bindings/staging/imx-drm/fsl-imx-drm.txt       |   43 ++++++++++++++++++--
 drivers/staging/imx-drm/parallel-display.c         |   25 +++++++++++-
 2 files changed, 63 insertions(+), 5 deletions(-)
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt b/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt
index e75f0e5..a9146f8 100644
--- a/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt
+++ b/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt
@@ -59,9 +59,26 @@  Parallel display support
 Required properties:
 - compatible: Should be "fsl,imx-parallel-display"
 Optional properties:
-- interface_pix_fmt: How this display is connected to the
-  display interface. Currently supported types: "rgb24", "rgb565", "bgr666"
-  and "lvds666".
+- interface-pix-map: Defines a pixel mapping onto the 24-bit IPU
+  Display Interface bus to the display. Internally the IPU represents
+  pixels in either RGB24 or YUV444 format. This property tells the IPU how
+  to map those RGB24 or YUV444 pixels onto the display interface bus.
+  The data format is as follows:
+
+  interface-pix-map = <c0-dest-msb c0-src-mask c1-dest-msb c1-src-mask
+  		       c2-dest-msb c2-src-mask>;
+
+  where:
+	c0, c1, c2: are the color components (c0 = B/V, c1 = G/U, c2 = R/Y)
+	src-mask: is the mask of component source bits to be forwarded
+	          to the DI bus
+	dest-msb: defines where to place those component bits on the
+	          24-bit DI bus, represented as the MSBit on the bus.
+
+- interface-pix-fmt: A name given to the pixel format sent to the display.
+  The following are names with pre-defined pixel mappings that do not
+  require an explicit interface-pix-map property: "rgb24", "rgb565", "rgb666"
+
 - edid: verbatim EDID data block describing attached display.
 - ddc: phandle describing the i2c bus handling the display data
   channel
@@ -81,3 +98,23 @@  display@di0 {
 		};
 	};
 };
+
+Pixel map examples:
+
+This example defines a new format named "bgr565" using a pixel map:
+
+display@di0 {
+	compatible = "fsl,imx-parallel-display";
+	edid = [edid-data];
+	interface-pix-fmt = "bgr565";
+	interface-pix-map = <15 0xf8 10 0xfc 4 0xf8>;
+};
+
+This example defines an unnamed format where an rgb666 format is shifted
+up by 6 bits on the DI bus:
+
+display@di0 {
+	compatible = "fsl,imx-parallel-display";
+	edid = [edid-data];
+	interface-pix-map = <11 0xfc 17 0xfc 23 0xfc>;
+};
diff --git a/drivers/staging/imx-drm/parallel-display.c b/drivers/staging/imx-drm/parallel-display.c
index 667a9b3..e0b0b56 100644
--- a/drivers/staging/imx-drm/parallel-display.c
+++ b/drivers/staging/imx-drm/parallel-display.c
@@ -26,6 +26,7 @@ 
 #include <drm/drm_panel.h>
 #include <linux/videodev2.h>
 #include <video/of_display_timing.h>
+#include <video/imx-ipu-v3.h>
 
 #include "imx-drm.h"
 
@@ -39,6 +40,7 @@  struct imx_parallel_display {
 	void *edid;
 	int edid_len;
 	u32 interface_pix_fmt;
+	struct ipu_dc_if_map *interface_map;
 	int mode_valid;
 	struct drm_display_mode mode;
 	struct drm_panel *panel;
@@ -123,7 +125,8 @@  static void imx_pd_encoder_prepare(struct drm_encoder *encoder)
 {
 	struct imx_parallel_display *imxpd = enc_to_imxpd(encoder);
 
-	imx_drm_panel_format(encoder, imxpd->interface_pix_fmt, NULL);
+	imx_drm_panel_format(encoder, imxpd->interface_pix_fmt,
+			     imxpd->interface_map);
 }
 
 static void imx_pd_encoder_commit(struct drm_encoder *encoder)
@@ -208,8 +211,9 @@  static int imx_pd_bind(struct device *dev, struct device *master, void *data)
 	struct device_node *panel_node;
 	const u8 *edidp;
 	struct imx_parallel_display *imxpd;
-	int ret;
+	struct ipu_dc_if_map interface_map;
 	const char *fmt;
+	int ret;
 
 	imxpd = devm_kzalloc(dev, sizeof(*imxpd), GFP_KERNEL);
 	if (!imxpd)
@@ -239,6 +243,23 @@  static int imx_pd_bind(struct device *dev, struct device *master, void *data)
 		}
 	}
 
+	ret = of_property_read_u32_array(np, "interface-pix-map",
+					 (u32 *)&interface_map,
+					 sizeof(interface_map) / sizeof(u32));
+	if (!ret) {
+		imxpd->interface_map =
+			devm_kmalloc(dev, sizeof(imxpd->interface_map),
+				     GFP_KERNEL);
+		if (!imxpd->interface_map)
+			return -ENOMEM;
+		*imxpd->interface_map = interface_map;
+	}
+
+	if (!imxpd->interface_pix_fmt && !imxpd->interface_map) {
+		dev_err(imxpd->dev, "No interface pix fmt defined!\n");
+		return -EINVAL;
+	}
+
 	panel_node = of_parse_phandle(np, "fsl,panel", 0);
 	if (panel_node)
 		imxpd->panel = of_drm_find_panel(panel_node);