imx-drm changes to use media bus formats and LDB drm_panel support

- Add media bus formats needed by imx-drm
 - Switch to use media bus formats to describe the pixel format
   on the internal parallel bus between display interface and
   encoders
 - Some preparations for TV Output via TVEv2 on i.MX5
 - Add drm_panel support to the i.MX LVDS driver, allow to
   determine the bus pixel format from the panel descriptor.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJVGnvrAAoJEFDCiBxwnmDrnXwP/RrkQjc9lluHJXJFN0gSE2vv
 +xKhZ4fPAkQECcHUFcSaL3mZiwQr2wym6kMR8j2ivj/EpJjfMsy91M+6yiwrMfyb
 Ccp6750LLljvQnUBayjHKMA55p9p+59wihFU26jCLzMB/30fJjqRtvQXwI3I4l2+
 ZKOaoeq+EubWfGKe3yVGqZB8p+DS4BvMwnXLrv2IF9ONRE7E24p6beKM1D5PFBPQ
 C5ZJ+BusMIyessgd7iNuIKJPkhZWjcgzSqfB3NiHxOB1FMCLpaGC8LcP/XKzqeQn
 cKBlAzxGhZucOshS217G6cK5C7ELTSEWP+CbFbIBOHyaiY0pVgW5AfKVUgPQK7+l
 50o8xQWQAZvzUIjGMPkhoELEW1mXmGDUksdae9rhr7/e6m/t8xBPvyxgMB70QEsL
 q0YL7XJzmLugTeSSABZBG/4GFfiOmaVP8ANUM9Kg6lOAVTS5NiVzlUrEukv4tppo
 VMQWBc8ot0woqZUlwlP1OJ2Z8lU2aT3px7BnZVu/VWIrNfJX5H9+Q4w57HqaYeqF
 lmuW9R/R/RulQiEVG36g91VYOsfE2bB7QlAums0jxTZu84fhy7BIOhdBzUdC+xO1
 yihgSkuNQPXvtIboIuUvQ/qc3G9fDlnlP78OfVdOn6uY+XSWAKiLs914xcQHphT/
 ZlVJkXAKk1WzKyVeghL2
 =nTVr
 -----END PGP SIGNATURE-----

Merge tag 'imx-drm-next-2015-03-31' of git://git.pengutronix.de/git/pza/linux into drm-next

imx-drm changes to use media bus formats and LDB drm_panel support

- Add media bus formats needed by imx-drm
- Switch to use media bus formats to describe the pixel format
  on the internal parallel bus between display interface and
  encoders
- Some preparations for TV Output via TVEv2 on i.MX5
- Add drm_panel support to the i.MX LVDS driver, allow to
  determine the bus pixel format from the panel descriptor.

* tag 'imx-drm-next-2015-03-31' of git://git.pengutronix.de/git/pza/linux:
  drm/imx: imx-ldb: allow to determine bus format from the connected panel
  drm/imx: imx-ldb: reset display clock input when disabling LVDS
  drm/imx: imx-ldb: add drm_panel support
  drm/imx: consolidate bus format variable names
  drm/imx: switch to use media bus formats
  Add RGB666_1X24_CPADHI media bus format
  Add YUV8_1X24 media bus format
  Add BGR888_1X24 and GBR888_1X24 media bus formats
  Add LVDS RGB media bus formats
  Add RGB444_1X12 and RGB565_1X16 media bus formats
  drm/imx: ipuv3-crtc: Allow to divide DI clock from TVEv2
  drm/imx: Add support for interlaced scanout
This commit is contained in:
Dave Airlie 2015-04-13 17:28:57 +10:00
commit 1d2add28ed
15 changed files with 669 additions and 129 deletions

View File

@ -91,7 +91,9 @@ see <xref linkend="colorspaces" />.</entry>
<listitem><para>For formats where the total number of bits per pixel is smaller
than the number of bus samples per pixel times the bus width, a padding
value stating if the bytes are padded in their most high order bits
(PADHI) or low order bits (PADLO).</para></listitem>
(PADHI) or low order bits (PADLO). A "C" prefix is used for component-wise
padding in the most high order bits (CPADHI) or low order bits (CPADLO)
of each separate component.</para></listitem>
<listitem><para>For formats where the number of bus samples per pixel is larger
than 1, an endianness value stating if the pixel is transferred MSB first
(BE) or LSB first (LE).</para></listitem>
@ -192,6 +194,24 @@ see <xref linkend="colorspaces" />.</entry>
</row>
</thead>
<tbody valign="top">
<row id="MEDIA-BUS-FMT-RGB444-1X12">
<entry>MEDIA_BUS_FMT_RGB444_1X12</entry>
<entry>0x100e</entry>
<entry></entry>
&dash-ent-20;
<entry>r<subscript>3</subscript></entry>
<entry>r<subscript>2</subscript></entry>
<entry>r<subscript>1</subscript></entry>
<entry>r<subscript>0</subscript></entry>
<entry>g<subscript>3</subscript></entry>
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
<entry>b<subscript>3</subscript></entry>
<entry>b<subscript>2</subscript></entry>
<entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry>
</row>
<row id="MEDIA-BUS-FMT-RGB444-2X8-PADHI-BE">
<entry>MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE</entry>
<entry>0x1001</entry>
@ -304,6 +324,28 @@ see <xref linkend="colorspaces" />.</entry>
<entry>g<subscript>4</subscript></entry>
<entry>g<subscript>3</subscript></entry>
</row>
<row id="MEDIA-BUS-FMT-RGB565-1X16">
<entry>MEDIA_BUS_FMT_RGB565_1X16</entry>
<entry>0x100f</entry>
<entry></entry>
&dash-ent-16;
<entry>r<subscript>4</subscript></entry>
<entry>r<subscript>3</subscript></entry>
<entry>r<subscript>2</subscript></entry>
<entry>r<subscript>1</subscript></entry>
<entry>r<subscript>0</subscript></entry>
<entry>g<subscript>5</subscript></entry>
<entry>g<subscript>4</subscript></entry>
<entry>g<subscript>3</subscript></entry>
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
<entry>b<subscript>4</subscript></entry>
<entry>b<subscript>3</subscript></entry>
<entry>b<subscript>2</subscript></entry>
<entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry>
</row>
<row id="MEDIA-BUS-FMT-BGR565-2X8-BE">
<entry>MEDIA_BUS_FMT_BGR565_2X8_BE</entry>
<entry>0x1005</entry>
@ -440,6 +482,96 @@ see <xref linkend="colorspaces" />.</entry>
<entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry>
</row>
<row id="MEDIA-BUS-FMT-RGB666-1X24_CPADHI">
<entry>MEDIA_BUS_FMT_RGB666_1X24_CPADHI</entry>
<entry>0x1015</entry>
<entry></entry>
&dash-ent-8;
<entry>0</entry>
<entry>0</entry>
<entry>r<subscript>5</subscript></entry>
<entry>r<subscript>4</subscript></entry>
<entry>r<subscript>3</subscript></entry>
<entry>r<subscript>2</subscript></entry>
<entry>r<subscript>1</subscript></entry>
<entry>r<subscript>0</subscript></entry>
<entry>0</entry>
<entry>0</entry>
<entry>g<subscript>5</subscript></entry>
<entry>g<subscript>4</subscript></entry>
<entry>g<subscript>3</subscript></entry>
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
<entry>0</entry>
<entry>0</entry>
<entry>b<subscript>5</subscript></entry>
<entry>b<subscript>4</subscript></entry>
<entry>b<subscript>3</subscript></entry>
<entry>b<subscript>2</subscript></entry>
<entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry>
</row>
<row id="MEDIA-BUS-FMT-BGR888-1X24">
<entry>MEDIA_BUS_FMT_BGR888_1X24</entry>
<entry>0x1013</entry>
<entry></entry>
&dash-ent-8;
<entry>b<subscript>7</subscript></entry>
<entry>b<subscript>6</subscript></entry>
<entry>b<subscript>5</subscript></entry>
<entry>b<subscript>4</subscript></entry>
<entry>b<subscript>3</subscript></entry>
<entry>b<subscript>2</subscript></entry>
<entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry>
<entry>g<subscript>7</subscript></entry>
<entry>g<subscript>6</subscript></entry>
<entry>g<subscript>5</subscript></entry>
<entry>g<subscript>4</subscript></entry>
<entry>g<subscript>3</subscript></entry>
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
<entry>r<subscript>7</subscript></entry>
<entry>r<subscript>6</subscript></entry>
<entry>r<subscript>5</subscript></entry>
<entry>r<subscript>4</subscript></entry>
<entry>r<subscript>3</subscript></entry>
<entry>r<subscript>2</subscript></entry>
<entry>r<subscript>1</subscript></entry>
<entry>r<subscript>0</subscript></entry>
</row>
<row id="MEDIA-BUS-FMT-GBR888-1X24">
<entry>MEDIA_BUS_FMT_GBR888_1X24</entry>
<entry>0x1014</entry>
<entry></entry>
&dash-ent-8;
<entry>g<subscript>7</subscript></entry>
<entry>g<subscript>6</subscript></entry>
<entry>g<subscript>5</subscript></entry>
<entry>g<subscript>4</subscript></entry>
<entry>g<subscript>3</subscript></entry>
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
<entry>b<subscript>7</subscript></entry>
<entry>b<subscript>6</subscript></entry>
<entry>b<subscript>5</subscript></entry>
<entry>b<subscript>4</subscript></entry>
<entry>b<subscript>3</subscript></entry>
<entry>b<subscript>2</subscript></entry>
<entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry>
<entry>r<subscript>7</subscript></entry>
<entry>r<subscript>6</subscript></entry>
<entry>r<subscript>5</subscript></entry>
<entry>r<subscript>4</subscript></entry>
<entry>r<subscript>3</subscript></entry>
<entry>r<subscript>2</subscript></entry>
<entry>r<subscript>1</subscript></entry>
<entry>r<subscript>0</subscript></entry>
</row>
<row id="MEDIA-BUS-FMT-RGB888-1X24">
<entry>MEDIA_BUS_FMT_RGB888_1X24</entry>
<entry>0x100a</entry>
@ -582,6 +714,261 @@ see <xref linkend="colorspaces" />.</entry>
</tbody>
</tgroup>
</table>
<para>On LVDS buses, usually each sample is transferred serialized in
seven time slots per pixel clock, on three (18-bit) or four (24-bit)
differential data pairs at the same time. The remaining bits are used for
control signals as defined by SPWG/PSWG/VESA or JEIDA standards.
The 24-bit RGB format serialized in seven time slots on four lanes using
JEIDA defined bit mapping will be named
<constant>MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA</constant>, for example.
</para>
<table pgwide="0" frame="none" id="v4l2-mbus-pixelcode-rgb-lvds">
<title>LVDS RGB formats</title>
<tgroup cols="8">
<colspec colname="id" align="left" />
<colspec colname="code" align="center" />
<colspec colname="slot" align="center" />
<colspec colname="lane" />
<colspec colnum="5" colname="l03" align="center" />
<colspec colnum="6" colname="l02" align="center" />
<colspec colnum="7" colname="l01" align="center" />
<colspec colnum="8" colname="l00" align="center" />
<spanspec namest="l03" nameend="l00" spanname="l0" />
<thead>
<row>
<entry>Identifier</entry>
<entry>Code</entry>
<entry></entry>
<entry></entry>
<entry spanname="l0">Data organization</entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry>Timeslot</entry>
<entry>Lane</entry>
<entry>3</entry>
<entry>2</entry>
<entry>1</entry>
<entry>0</entry>
</row>
</thead>
<tbody valign="top">
<row id="MEDIA-BUS-FMT-RGB666-1X7X3-SPWG">
<entry>MEDIA_BUS_FMT_RGB666_1X7X3_SPWG</entry>
<entry>0x1010</entry>
<entry>0</entry>
<entry></entry>
<entry>-</entry>
<entry>d</entry>
<entry>b<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry>1</entry>
<entry></entry>
<entry>-</entry>
<entry>d</entry>
<entry>b<subscript>0</subscript></entry>
<entry>r<subscript>5</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry>2</entry>
<entry></entry>
<entry>-</entry>
<entry>d</entry>
<entry>g<subscript>5</subscript></entry>
<entry>r<subscript>4</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry>3</entry>
<entry></entry>
<entry>-</entry>
<entry>b<subscript>5</subscript></entry>
<entry>g<subscript>4</subscript></entry>
<entry>r<subscript>3</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry>4</entry>
<entry></entry>
<entry>-</entry>
<entry>b<subscript>4</subscript></entry>
<entry>g<subscript>3</subscript></entry>
<entry>r<subscript>2</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry>5</entry>
<entry></entry>
<entry>-</entry>
<entry>b<subscript>3</subscript></entry>
<entry>g<subscript>2</subscript></entry>
<entry>r<subscript>1</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry>6</entry>
<entry></entry>
<entry>-</entry>
<entry>b<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>r<subscript>0</subscript></entry>
</row>
<row id="MEDIA-BUS-FMT-RGB888-1X7X4-SPWG">
<entry>MEDIA_BUS_FMT_RGB888_1X7X4_SPWG</entry>
<entry>0x1011</entry>
<entry>0</entry>
<entry></entry>
<entry>d</entry>
<entry>d</entry>
<entry>b<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry>1</entry>
<entry></entry>
<entry>b<subscript>7</subscript></entry>
<entry>d</entry>
<entry>b<subscript>0</subscript></entry>
<entry>r<subscript>5</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry>2</entry>
<entry></entry>
<entry>b<subscript>6</subscript></entry>
<entry>d</entry>
<entry>g<subscript>5</subscript></entry>
<entry>r<subscript>4</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry>3</entry>
<entry></entry>
<entry>g<subscript>7</subscript></entry>
<entry>b<subscript>5</subscript></entry>
<entry>g<subscript>4</subscript></entry>
<entry>r<subscript>3</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry>4</entry>
<entry></entry>
<entry>g<subscript>6</subscript></entry>
<entry>b<subscript>4</subscript></entry>
<entry>g<subscript>3</subscript></entry>
<entry>r<subscript>2</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry>5</entry>
<entry></entry>
<entry>r<subscript>7</subscript></entry>
<entry>b<subscript>3</subscript></entry>
<entry>g<subscript>2</subscript></entry>
<entry>r<subscript>1</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry>6</entry>
<entry></entry>
<entry>r<subscript>6</subscript></entry>
<entry>b<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
<entry>r<subscript>0</subscript></entry>
</row>
<row id="MEDIA-BUS-FMT-RGB888-1X7X4-JEIDA">
<entry>MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA</entry>
<entry>0x1012</entry>
<entry>0</entry>
<entry></entry>
<entry>d</entry>
<entry>d</entry>
<entry>b<subscript>3</subscript></entry>
<entry>g<subscript>2</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry>1</entry>
<entry></entry>
<entry>b<subscript>1</subscript></entry>
<entry>d</entry>
<entry>b<subscript>2</subscript></entry>
<entry>r<subscript>7</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry>2</entry>
<entry></entry>
<entry>b<subscript>0</subscript></entry>
<entry>d</entry>
<entry>g<subscript>7</subscript></entry>
<entry>r<subscript>6</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry>3</entry>
<entry></entry>
<entry>g<subscript>1</subscript></entry>
<entry>b<subscript>7</subscript></entry>
<entry>g<subscript>6</subscript></entry>
<entry>r<subscript>5</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry>4</entry>
<entry></entry>
<entry>g<subscript>0</subscript></entry>
<entry>b<subscript>6</subscript></entry>
<entry>g<subscript>5</subscript></entry>
<entry>r<subscript>4</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry>5</entry>
<entry></entry>
<entry>r<subscript>1</subscript></entry>
<entry>b<subscript>5</subscript></entry>
<entry>g<subscript>4</subscript></entry>
<entry>r<subscript>3</subscript></entry>
</row>
<row>
<entry></entry>
<entry></entry>
<entry>6</entry>
<entry></entry>
<entry>r<subscript>0</subscript></entry>
<entry>b<subscript>4</subscript></entry>
<entry>g<subscript>3</subscript></entry>
<entry>r<subscript>2</subscript></entry>
</row>
</tbody>
</tgroup>
</table>
</section>
<section>
@ -2660,6 +3047,43 @@ see <xref linkend="colorspaces" />.</entry>
<entry>u<subscript>1</subscript></entry>
<entry>u<subscript>0</subscript></entry>
</row>
<row id="MEDIA-BUS-FMT-YUV8-1X24">
<entry>MEDIA_BUS_FMT_YUV8_1X24</entry>
<entry>0x2024</entry>
<entry></entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>y<subscript>7</subscript></entry>
<entry>y<subscript>6</subscript></entry>
<entry>y<subscript>5</subscript></entry>
<entry>y<subscript>4</subscript></entry>
<entry>y<subscript>3</subscript></entry>
<entry>y<subscript>2</subscript></entry>
<entry>y<subscript>1</subscript></entry>
<entry>y<subscript>0</subscript></entry>
<entry>u<subscript>7</subscript></entry>
<entry>u<subscript>6</subscript></entry>
<entry>u<subscript>5</subscript></entry>
<entry>u<subscript>4</subscript></entry>
<entry>u<subscript>3</subscript></entry>
<entry>u<subscript>2</subscript></entry>
<entry>u<subscript>1</subscript></entry>
<entry>u<subscript>0</subscript></entry>
<entry>v<subscript>7</subscript></entry>
<entry>v<subscript>6</subscript></entry>
<entry>v<subscript>5</subscript></entry>
<entry>v<subscript>4</subscript></entry>
<entry>v<subscript>3</subscript></entry>
<entry>v<subscript>2</subscript></entry>
<entry>v<subscript>1</subscript></entry>
<entry>v<subscript>0</subscript></entry>
</row>
<row id="MEDIA-BUS-FMT-YUV10-1X30">
<entry>MEDIA_BUS_FMT_YUV10_1X30</entry>
<entry>0x2016</entry>

View File

@ -44,23 +44,30 @@ Optional properties:
LVDS Channel
============
Each LVDS Channel has to contain a display-timings node that describes the
video timings for the connected LVDS display. For detailed information, also
have a look at Documentation/devicetree/bindings/video/display-timing.txt.
Each LVDS Channel has to contain either an of graph link to a panel device node
or a display-timings node that describes the video timings for the connected
LVDS display as well as the fsl,data-mapping and fsl,data-width properties.
Required properties:
- reg : should be <0> or <1>
- port: Input and output port nodes with endpoint definitions as defined in
Documentation/devicetree/bindings/graph.txt.
On i.MX5, the internal two-input-multiplexer is used. Due to hardware
limitations, only one input port (port@[0,1]) can be used for each channel
(lvds-channel@[0,1], respectively).
On i.MX6, there should be four input ports (port@[0-3]) that correspond
to the four LVDS multiplexer inputs.
A single output port (port@2 on i.MX5, port@4 on i.MX6) must be connected
to a panel input port. Optionally, the output port can be left out if
display-timings are used instead.
Optional properties (required if display-timings are used):
- display-timings : A node that describes the display timings as defined in
Documentation/devicetree/bindings/video/display-timing.txt.
- fsl,data-mapping : should be "spwg" or "jeida"
This describes how the color bits are laid out in the
serialized LVDS signal.
- fsl,data-width : should be <18> or <24>
- port: A port node with endpoint definitions as defined in
Documentation/devicetree/bindings/media/video-interfaces.txt.
On i.MX5, the internal two-input-multiplexer is used.
Due to hardware limitations, only one port (port@[0,1])
can be used for each channel (lvds-channel@[0,1], respectively)
On i.MX6, there should be four ports (port@[0-3]) that correspond
to the four LVDS multiplexer inputs.
example:
@ -73,23 +80,21 @@ ldb: ldb@53fa8008 {
#size-cells = <0>;
compatible = "fsl,imx53-ldb";
gpr = <&gpr>;
clocks = <&clks 122>, <&clks 120>,
<&clks 115>, <&clks 116>,
<&clks 123>, <&clks 85>;
clocks = <&clks IMX5_CLK_LDB_DI0_SEL>,
<&clks IMX5_CLK_LDB_DI1_SEL>,
<&clks IMX5_CLK_IPU_DI0_SEL>,
<&clks IMX5_CLK_IPU_DI1_SEL>,
<&clks IMX5_CLK_LDB_DI0_GATE>,
<&clks IMX5_CLK_LDB_DI1_GATE>;
clock-names = "di0_pll", "di1_pll",
"di0_sel", "di1_sel",
"di0", "di1";
/* Using an of-graph endpoint link to connect the panel */
lvds-channel@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
fsl,data-mapping = "spwg";
fsl,data-width = <24>;
display-timings {
/* ... */
};
port@0 {
reg = <0>;
@ -98,8 +103,17 @@ ldb: ldb@53fa8008 {
remote-endpoint = <&ipu_di0_lvds0>;
};
};
port@2 {
reg = <2>;
lvds0_out: endpoint {
remote-endpoint = <&panel_in>;
};
};
};
/* Using display-timings and fsl,data-mapping/width instead */
lvds-channel@1 {
#address-cells = <1>;
#size-cells = <0>;
@ -120,3 +134,13 @@ ldb: ldb@53fa8008 {
};
};
};
panel: lvds-panel {
/* ... */
port {
panel_in: endpoint {
remote-endpoint = <&lvds0_out>;
};
};
};

View File

@ -36,6 +36,7 @@ config DRM_IMX_TVE
config DRM_IMX_LDB
tristate "Support for LVDS displays"
depends on DRM_IMX && MFD_SYSCON
select DRM_PANEL
help
Choose this to enable the internal LVDS Display Bridge (LDB)
found on i.MX53 and i.MX6 processors.

View File

@ -123,7 +123,7 @@ static void dw_hdmi_imx_encoder_commit(struct drm_encoder *encoder)
static void dw_hdmi_imx_encoder_prepare(struct drm_encoder *encoder)
{
imx_drm_panel_format(encoder, V4L2_PIX_FMT_RGB24);
imx_drm_set_bus_format(encoder, MEDIA_BUS_FMT_RGB888_1X24);
}
static struct drm_encoder_helper_funcs dw_hdmi_imx_encoder_helper_funcs = {

View File

@ -103,8 +103,8 @@ static struct imx_drm_crtc *imx_drm_find_crtc(struct drm_crtc *crtc)
return NULL;
}
int imx_drm_panel_format_pins(struct drm_encoder *encoder,
u32 interface_pix_fmt, int hsync_pin, int vsync_pin)
int imx_drm_set_bus_format_pins(struct drm_encoder *encoder, u32 bus_format,
int hsync_pin, int vsync_pin)
{
struct imx_drm_crtc_helper_funcs *helper;
struct imx_drm_crtc *imx_crtc;
@ -116,16 +116,16 @@ int imx_drm_panel_format_pins(struct drm_encoder *encoder,
helper = &imx_crtc->imx_drm_helper_funcs;
if (helper->set_interface_pix_fmt)
return helper->set_interface_pix_fmt(encoder->crtc,
interface_pix_fmt, hsync_pin, vsync_pin);
bus_format, hsync_pin, vsync_pin);
return 0;
}
EXPORT_SYMBOL_GPL(imx_drm_panel_format_pins);
EXPORT_SYMBOL_GPL(imx_drm_set_bus_format_pins);
int imx_drm_panel_format(struct drm_encoder *encoder, u32 interface_pix_fmt)
int imx_drm_set_bus_format(struct drm_encoder *encoder, u32 bus_format)
{
return imx_drm_panel_format_pins(encoder, interface_pix_fmt, 2, 3);
return imx_drm_set_bus_format_pins(encoder, bus_format, 2, 3);
}
EXPORT_SYMBOL_GPL(imx_drm_panel_format);
EXPORT_SYMBOL_GPL(imx_drm_set_bus_format);
int imx_drm_crtc_vblank_get(struct imx_drm_crtc *imx_drm_crtc)
{

View File

@ -18,7 +18,7 @@ struct imx_drm_crtc_helper_funcs {
int (*enable_vblank)(struct drm_crtc *crtc);
void (*disable_vblank)(struct drm_crtc *crtc);
int (*set_interface_pix_fmt)(struct drm_crtc *crtc,
u32 pix_fmt, int hsync_pin, int vsync_pin);
u32 bus_format, int hsync_pin, int vsync_pin);
const struct drm_crtc_helper_funcs *crtc_helper_funcs;
const struct drm_crtc_funcs *crtc_funcs;
};
@ -40,10 +40,10 @@ void imx_drm_mode_config_init(struct drm_device *drm);
struct drm_gem_cma_object *imx_drm_fb_get_obj(struct drm_framebuffer *fb);
int imx_drm_panel_format_pins(struct drm_encoder *encoder,
u32 interface_pix_fmt, int hsync_pin, int vsync_pin);
int imx_drm_panel_format(struct drm_encoder *encoder,
u32 interface_pix_fmt);
int imx_drm_set_bus_format_pins(struct drm_encoder *encoder,
u32 bus_format, int hsync_pin, int vsync_pin);
int imx_drm_set_bus_format(struct drm_encoder *encoder,
u32 bus_format);
int imx_drm_encoder_get_mux_id(struct device_node *node,
struct drm_encoder *encoder);

View File

@ -19,10 +19,11 @@
#include <drm/drmP.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_panel.h>
#include <linux/mfd/syscon.h>
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_graph.h>
#include <video/of_videomode.h>
#include <linux/regmap.h>
#include <linux/videodev2.h>
@ -55,12 +56,14 @@ struct imx_ldb_channel {
struct imx_ldb *ldb;
struct drm_connector connector;
struct drm_encoder encoder;
struct drm_panel *panel;
struct device_node *child;
int chno;
void *edid;
int edid_len;
struct drm_display_mode mode;
int mode_valid;
int bus_format;
};
struct bus_mux {
@ -75,6 +78,7 @@ struct imx_ldb {
struct imx_ldb_channel channel[2];
struct clk *clk[2]; /* our own clock */
struct clk *clk_sel[4]; /* parent of display clock */
struct clk *clk_parent[4]; /* original parent of clk_sel */
struct clk *clk_pll[2]; /* upstream clock we can adjust */
u32 ldb_ctrl;
const struct bus_mux *lvds_mux;
@ -91,6 +95,17 @@ static int imx_ldb_connector_get_modes(struct drm_connector *connector)
struct imx_ldb_channel *imx_ldb_ch = con_to_imx_ldb_ch(connector);
int num_modes = 0;
if (imx_ldb_ch->panel && imx_ldb_ch->panel->funcs &&
imx_ldb_ch->panel->funcs->get_modes) {
struct drm_display_info *di = &connector->display_info;
num_modes = imx_ldb_ch->panel->funcs->get_modes(imx_ldb_ch->panel);
if (!imx_ldb_ch->bus_format && di->num_bus_formats)
imx_ldb_ch->bus_format = di->bus_formats[0];
if (num_modes > 0)
return num_modes;
}
if (imx_ldb_ch->edid) {
drm_mode_connector_update_edid_property(connector,
imx_ldb_ch->edid);
@ -163,24 +178,36 @@ static void imx_ldb_encoder_prepare(struct drm_encoder *encoder)
{
struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
struct imx_ldb *ldb = imx_ldb_ch->ldb;
u32 pixel_fmt;
int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN;
u32 bus_format;
switch (imx_ldb_ch->chno) {
case 0:
pixel_fmt = (ldb->ldb_ctrl & LDB_DATA_WIDTH_CH0_24) ?
V4L2_PIX_FMT_RGB24 : V4L2_PIX_FMT_BGR666;
break;
case 1:
pixel_fmt = (ldb->ldb_ctrl & LDB_DATA_WIDTH_CH1_24) ?
V4L2_PIX_FMT_RGB24 : V4L2_PIX_FMT_BGR666;
break;
switch (imx_ldb_ch->bus_format) {
default:
dev_err(ldb->dev, "unable to config di%d panel format\n",
imx_ldb_ch->chno);
pixel_fmt = V4L2_PIX_FMT_RGB24;
dev_warn(ldb->dev,
"could not determine data mapping, default to 18-bit \"spwg\"\n");
/* fallthrough */
case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
bus_format = MEDIA_BUS_FMT_RGB666_1X18;
break;
case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
bus_format = MEDIA_BUS_FMT_RGB888_1X24;
if (imx_ldb_ch->chno == 0 || dual)
ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24;
if (imx_ldb_ch->chno == 1 || dual)
ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24;
break;
case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
bus_format = MEDIA_BUS_FMT_RGB888_1X24;
if (imx_ldb_ch->chno == 0 || dual)
ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24 |
LDB_BIT_MAP_CH0_JEIDA;
if (imx_ldb_ch->chno == 1 || dual)
ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24 |
LDB_BIT_MAP_CH1_JEIDA;
break;
}
imx_drm_panel_format(encoder, pixel_fmt);
imx_drm_set_bus_format(encoder, bus_format);
}
static void imx_ldb_encoder_commit(struct drm_encoder *encoder)
@ -190,6 +217,8 @@ static void imx_ldb_encoder_commit(struct drm_encoder *encoder)
int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN;
int mux = imx_drm_encoder_get_mux_id(imx_ldb_ch->child, encoder);
drm_panel_prepare(imx_ldb_ch->panel);
if (dual) {
clk_prepare_enable(ldb->clk[0]);
clk_prepare_enable(ldb->clk[1]);
@ -223,6 +252,8 @@ static void imx_ldb_encoder_commit(struct drm_encoder *encoder)
}
regmap_write(ldb->regmap, IOMUXC_GPR2, ldb->ldb_ctrl);
drm_panel_enable(imx_ldb_ch->panel);
}
static void imx_ldb_encoder_mode_set(struct drm_encoder *encoder,
@ -274,6 +305,7 @@ static void imx_ldb_encoder_disable(struct drm_encoder *encoder)
{
struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
struct imx_ldb *ldb = imx_ldb_ch->ldb;
int mux, ret;
/*
* imx_ldb_encoder_disable is called by
@ -287,6 +319,8 @@ static void imx_ldb_encoder_disable(struct drm_encoder *encoder)
(ldb->ldb_ctrl & LDB_CH1_MODE_EN_MASK) == 0)
return;
drm_panel_disable(imx_ldb_ch->panel);
if (imx_ldb_ch == &ldb->channel[0])
ldb->ldb_ctrl &= ~LDB_CH0_MODE_EN_MASK;
else if (imx_ldb_ch == &ldb->channel[1])
@ -298,6 +332,30 @@ static void imx_ldb_encoder_disable(struct drm_encoder *encoder)
clk_disable_unprepare(ldb->clk[0]);
clk_disable_unprepare(ldb->clk[1]);
}
if (ldb->lvds_mux) {
const struct bus_mux *lvds_mux = NULL;
if (imx_ldb_ch == &ldb->channel[0])
lvds_mux = &ldb->lvds_mux[0];
else if (imx_ldb_ch == &ldb->channel[1])
lvds_mux = &ldb->lvds_mux[1];
regmap_read(ldb->regmap, lvds_mux->reg, &mux);
mux &= lvds_mux->mask;
mux >>= lvds_mux->shift;
} else {
mux = (imx_ldb_ch == &ldb->channel[0]) ? 0 : 1;
}
/* set display clock mux back to original input clock */
ret = clk_set_parent(ldb->clk_sel[mux], ldb->clk_parent[mux]);
if (ret)
dev_err(ldb->dev,
"unable to set di%d parent clock to original parent\n",
mux);
drm_panel_unprepare(imx_ldb_ch->panel);
}
static struct drm_connector_funcs imx_ldb_connector_funcs = {
@ -371,6 +429,9 @@ static int imx_ldb_register(struct drm_device *drm,
drm_connector_init(drm, &imx_ldb_ch->connector,
&imx_ldb_connector_funcs, DRM_MODE_CONNECTOR_LVDS);
if (imx_ldb_ch->panel)
drm_panel_attach(imx_ldb_ch->panel, &imx_ldb_ch->connector);
drm_mode_connector_attach_encoder(&imx_ldb_ch->connector,
&imx_ldb_ch->encoder);
@ -382,25 +443,39 @@ enum {
LVDS_BIT_MAP_JEIDA
};
static const char * const imx_ldb_bit_mappings[] = {
[LVDS_BIT_MAP_SPWG] = "spwg",
[LVDS_BIT_MAP_JEIDA] = "jeida",
struct imx_ldb_bit_mapping {
u32 bus_format;
u32 datawidth;
const char * const mapping;
};
static const int of_get_data_mapping(struct device_node *np)
static const struct imx_ldb_bit_mapping imx_ldb_bit_mappings[] = {
{ MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, 18, "spwg" },
{ MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, 24, "spwg" },
{ MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, 24, "jeida" },
};
static u32 of_get_bus_format(struct device *dev, struct device_node *np)
{
const char *bm;
u32 datawidth = 0;
int ret, i;
ret = of_property_read_string(np, "fsl,data-mapping", &bm);
if (ret < 0)
return ret;
for (i = 0; i < ARRAY_SIZE(imx_ldb_bit_mappings); i++)
if (!strcasecmp(bm, imx_ldb_bit_mappings[i]))
return i;
of_property_read_u32(np, "fsl,data-width", &datawidth);
return -EINVAL;
for (i = 0; i < ARRAY_SIZE(imx_ldb_bit_mappings); i++) {
if (!strcasecmp(bm, imx_ldb_bit_mappings[i].mapping) &&
datawidth == imx_ldb_bit_mappings[i].datawidth)
return imx_ldb_bit_mappings[i].bus_format;
}
dev_err(dev, "invalid data mapping: %d-bit \"%s\"\n", datawidth, bm);
return -ENOENT;
}
static struct bus_mux imx6q_lvds_mux[2] = {
@ -437,8 +512,6 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
struct device_node *child;
const u8 *edidp;
struct imx_ldb *imx_ldb;
int datawidth;
int mapping;
int dual;
int ret;
int i;
@ -479,12 +552,15 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
imx_ldb->clk_sel[i] = NULL;
break;
}
imx_ldb->clk_parent[i] = clk_get_parent(imx_ldb->clk_sel[i]);
}
if (i == 0)
return ret;
for_each_child_of_node(np, child) {
struct imx_ldb_channel *channel;
struct device_node *port;
ret = of_property_read_u32(child, "reg", &i);
if (ret || i < 0 || i > 1)
@ -503,49 +579,53 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
channel->chno = i;
channel->child = child;
/*
* The output port is port@4 with an external 4-port mux or
* port@2 with the internal 2-port mux.
*/
port = of_graph_get_port_by_id(child, imx_ldb->lvds_mux ? 4 : 2);
if (port) {
struct device_node *endpoint, *remote;
endpoint = of_get_child_by_name(port, "endpoint");
if (endpoint) {
remote = of_graph_get_remote_port_parent(endpoint);
if (remote)
channel->panel = of_drm_find_panel(remote);
else
return -EPROBE_DEFER;
if (!channel->panel) {
dev_err(dev, "panel not found: %s\n",
remote->full_name);
return -EPROBE_DEFER;
}
}
}
edidp = of_get_property(child, "edid", &channel->edid_len);
if (edidp) {
channel->edid = kmemdup(edidp, channel->edid_len,
GFP_KERNEL);
} else {
} else if (!channel->panel) {
ret = of_get_drm_display_mode(child, &channel->mode, 0);
if (!ret)
channel->mode_valid = 1;
}
ret = of_property_read_u32(child, "fsl,data-width", &datawidth);
if (ret)
datawidth = 0;
else if (datawidth != 18 && datawidth != 24)
return -EINVAL;
mapping = of_get_data_mapping(child);
switch (mapping) {
case LVDS_BIT_MAP_SPWG:
if (datawidth == 24) {
if (i == 0 || dual)
imx_ldb->ldb_ctrl |=
LDB_DATA_WIDTH_CH0_24;
if (i == 1 || dual)
imx_ldb->ldb_ctrl |=
LDB_DATA_WIDTH_CH1_24;
channel->bus_format = of_get_bus_format(dev, child);
if (channel->bus_format == -EINVAL) {
/*
* If no bus format was specified in the device tree,
* we can still get it from the connected panel later.
*/
if (channel->panel && channel->panel->funcs &&
channel->panel->funcs->get_modes)
channel->bus_format = 0;
}
break;
case LVDS_BIT_MAP_JEIDA:
if (datawidth == 18) {
dev_err(dev, "JEIDA standard only supported in 24 bit\n");
return -EINVAL;
}
if (i == 0 || dual)
imx_ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24 |
LDB_BIT_MAP_CH0_JEIDA;
if (i == 1 || dual)
imx_ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24 |
LDB_BIT_MAP_CH1_JEIDA;
break;
default:
dev_err(dev, "data mapping not specified or invalid\n");
return -EINVAL;
if (channel->bus_format < 0) {
dev_err(dev, "could not determine data mapping: %d\n",
channel->bus_format);
return channel->bus_format;
}
ret = imx_ldb_register(drm, channel);

View File

@ -301,11 +301,11 @@ static void imx_tve_encoder_prepare(struct drm_encoder *encoder)
switch (tve->mode) {
case TVE_MODE_VGA:
imx_drm_panel_format_pins(encoder, IPU_PIX_FMT_GBR24,
imx_drm_set_bus_format_pins(encoder, MEDIA_BUS_FMT_YUV8_1X24,
tve->hsync_pin, tve->vsync_pin);
break;
case TVE_MODE_TVOUT:
imx_drm_panel_format(encoder, V4L2_PIX_FMT_YUV444);
imx_drm_set_bus_format(encoder, MEDIA_BUS_FMT_YUV8_1X24);
break;
}
}

View File

@ -45,7 +45,7 @@ struct ipu_crtc {
struct drm_pending_vblank_event *page_flip_event;
struct drm_framebuffer *newfb;
int irq;
u32 interface_pix_fmt;
u32 bus_format;
int di_hsync_pin;
int di_vsync_pin;
};
@ -145,7 +145,6 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc,
struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
struct ipu_di_signal_cfg sig_cfg = {};
unsigned long encoder_types = 0;
u32 out_pixel_fmt;
int ret;
dev_dbg(ipu_crtc->dev, "%s: mode->hdisplay: %d\n", __func__,
@ -161,21 +160,21 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc,
__func__, encoder_types);
/*
* If we have DAC, TVDAC or LDB, then we need the IPU DI clock
* to be the same as the LDB DI clock.
* If we have DAC or LDB, then we need the IPU DI clock to be
* the same as the LDB DI clock. For TVDAC, derive the IPU DI
* clock from 27 MHz TVE_DI clock, but allow to divide it.
*/
if (encoder_types & (BIT(DRM_MODE_ENCODER_DAC) |
BIT(DRM_MODE_ENCODER_TVDAC) |
BIT(DRM_MODE_ENCODER_LVDS)))
sig_cfg.clkflags = IPU_DI_CLKMODE_SYNC | IPU_DI_CLKMODE_EXT;
else if (encoder_types & BIT(DRM_MODE_ENCODER_TVDAC))
sig_cfg.clkflags = IPU_DI_CLKMODE_EXT;
else
sig_cfg.clkflags = 0;
out_pixel_fmt = ipu_crtc->interface_pix_fmt;
sig_cfg.enable_pol = 1;
sig_cfg.clk_pol = 0;
sig_cfg.pixel_fmt = out_pixel_fmt;
sig_cfg.bus_format = ipu_crtc->bus_format;
sig_cfg.v_to_h_sync = 0;
sig_cfg.hsync_pin = ipu_crtc->di_hsync_pin;
sig_cfg.vsync_pin = ipu_crtc->di_vsync_pin;
@ -184,7 +183,7 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc,
ret = ipu_dc_init_sync(ipu_crtc->dc, ipu_crtc->di,
mode->flags & DRM_MODE_FLAG_INTERLACE,
out_pixel_fmt, mode->hdisplay);
ipu_crtc->bus_format, mode->hdisplay);
if (ret) {
dev_err(ipu_crtc->dev,
"initializing display controller failed with %d\n",
@ -202,7 +201,8 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc,
return ipu_plane_mode_set(ipu_crtc->plane[0], crtc, mode,
crtc->primary->fb,
0, 0, mode->hdisplay, mode->vdisplay,
x, y, mode->hdisplay, mode->vdisplay);
x, y, mode->hdisplay, mode->vdisplay,
mode->flags & DRM_MODE_FLAG_INTERLACE);
}
static void ipu_crtc_handle_pageflip(struct ipu_crtc *ipu_crtc)
@ -291,11 +291,11 @@ static void ipu_disable_vblank(struct drm_crtc *crtc)
}
static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc,
u32 pixfmt, int hsync_pin, int vsync_pin)
u32 bus_format, int hsync_pin, int vsync_pin)
{
struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
ipu_crtc->interface_pix_fmt = pixfmt;
ipu_crtc->bus_format = bus_format;
ipu_crtc->di_hsync_pin = hsync_pin;
ipu_crtc->di_vsync_pin = vsync_pin;

View File

@ -99,7 +99,7 @@ int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc,
struct drm_framebuffer *fb, int crtc_x, int crtc_y,
unsigned int crtc_w, unsigned int crtc_h,
uint32_t src_x, uint32_t src_y,
uint32_t src_w, uint32_t src_h)
uint32_t src_w, uint32_t src_h, bool interlaced)
{
struct device *dev = ipu_plane->base.dev->dev;
int ret;
@ -213,6 +213,8 @@ int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc,
ret = ipu_plane_set_base(ipu_plane, fb, src_x, src_y);
if (ret < 0)
return ret;
if (interlaced)
ipu_cpmem_interlaced_scan(ipu_plane->ipu_ch, fb->pitches[0]);
ipu_plane->w = src_w;
ipu_plane->h = src_h;
@ -312,7 +314,8 @@ static int ipu_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
ret = ipu_plane_mode_set(ipu_plane, crtc, &crtc->hwmode, fb,
crtc_x, crtc_y, crtc_w, crtc_h,
src_x >> 16, src_y >> 16, src_w >> 16, src_h >> 16);
src_x >> 16, src_y >> 16, src_w >> 16, src_h >> 16,
false);
if (ret < 0) {
ipu_plane_put_resources(ipu_plane);
return ret;

View File

@ -42,7 +42,7 @@ int ipu_plane_mode_set(struct ipu_plane *plane, struct drm_crtc *crtc,
struct drm_framebuffer *fb, int crtc_x, int crtc_y,
unsigned int crtc_w, unsigned int crtc_h,
uint32_t src_x, uint32_t src_y, uint32_t src_w,
uint32_t src_h);
uint32_t src_h, bool interlaced);
void ipu_plane_enable(struct ipu_plane *plane);
void ipu_plane_disable(struct ipu_plane *plane);

View File

@ -33,7 +33,7 @@ struct imx_parallel_display {
struct device *dev;
void *edid;
int edid_len;
u32 interface_pix_fmt;
u32 bus_format;
int mode_valid;
struct drm_display_mode mode;
struct drm_panel *panel;
@ -118,7 +118,7 @@ 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);
imx_drm_set_bus_format(encoder, imxpd->bus_format);
}
static void imx_pd_encoder_commit(struct drm_encoder *encoder)
@ -225,14 +225,13 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data)
ret = of_property_read_string(np, "interface-pix-fmt", &fmt);
if (!ret) {
if (!strcmp(fmt, "rgb24"))
imxpd->interface_pix_fmt = V4L2_PIX_FMT_RGB24;
imxpd->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
else if (!strcmp(fmt, "rgb565"))
imxpd->interface_pix_fmt = V4L2_PIX_FMT_RGB565;
imxpd->bus_format = MEDIA_BUS_FMT_RGB565_1X16;
else if (!strcmp(fmt, "bgr666"))
imxpd->interface_pix_fmt = V4L2_PIX_FMT_BGR666;
imxpd->bus_format = MEDIA_BUS_FMT_RGB666_1X18;
else if (!strcmp(fmt, "lvds666"))
imxpd->interface_pix_fmt =
v4l2_fourcc('L', 'V', 'D', '6');
imxpd->bus_format = MEDIA_BUS_FMT_RGB666_1X24_CPADHI;
}
panel_node = of_parse_phandle(np, "fsl,panel", 0);

View File

@ -147,20 +147,20 @@ static void dc_write_tmpl(struct ipu_dc *dc, int word, u32 opcode, u32 operand,
writel(reg2, priv->dc_tmpl_reg + word * 8 + 4);
}
static int ipu_pixfmt_to_map(u32 fmt)
static int ipu_bus_format_to_map(u32 fmt)
{
switch (fmt) {
case V4L2_PIX_FMT_RGB24:
case MEDIA_BUS_FMT_RGB888_1X24:
return IPU_DC_MAP_RGB24;
case V4L2_PIX_FMT_RGB565:
case MEDIA_BUS_FMT_RGB565_1X16:
return IPU_DC_MAP_RGB565;
case IPU_PIX_FMT_GBR24:
case MEDIA_BUS_FMT_GBR888_1X24:
return IPU_DC_MAP_GBR24;
case V4L2_PIX_FMT_BGR666:
case MEDIA_BUS_FMT_RGB666_1X18:
return IPU_DC_MAP_BGR666;
case v4l2_fourcc('L', 'V', 'D', '6'):
case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
return IPU_DC_MAP_LVDS666;
case V4L2_PIX_FMT_BGR24:
case MEDIA_BUS_FMT_BGR888_1X24:
return IPU_DC_MAP_BGR24;
default:
return -EINVAL;
@ -168,7 +168,7 @@ static int ipu_pixfmt_to_map(u32 fmt)
}
int ipu_dc_init_sync(struct ipu_dc *dc, struct ipu_di *di, bool interlaced,
u32 pixel_fmt, u32 width)
u32 bus_format, u32 width)
{
struct ipu_dc_priv *priv = dc->priv;
u32 reg = 0;
@ -176,7 +176,7 @@ int ipu_dc_init_sync(struct ipu_dc *dc, struct ipu_di *di, bool interlaced,
dc->di = ipu_di_get_num(di);
map = ipu_pixfmt_to_map(pixel_fmt);
map = ipu_bus_format_to_map(bus_format);
if (map < 0) {
dev_dbg(priv->dev, "IPU_DISP: No MAP\n");
return map;

View File

@ -33,22 +33,30 @@
#define MEDIA_BUS_FMT_FIXED 0x0001
/* RGB - next is 0x100e */
/* RGB - next is 0x1016 */
#define MEDIA_BUS_FMT_RGB444_1X12 0x100e
#define MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE 0x1001
#define MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE 0x1002
#define MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE 0x1003
#define MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE 0x1004
#define MEDIA_BUS_FMT_RGB565_1X16 0x100f
#define MEDIA_BUS_FMT_BGR565_2X8_BE 0x1005
#define MEDIA_BUS_FMT_BGR565_2X8_LE 0x1006
#define MEDIA_BUS_FMT_RGB565_2X8_BE 0x1007
#define MEDIA_BUS_FMT_RGB565_2X8_LE 0x1008
#define MEDIA_BUS_FMT_RGB666_1X18 0x1009
#define MEDIA_BUS_FMT_RGB666_1X24_CPADHI 0x1015
#define MEDIA_BUS_FMT_RGB666_1X7X3_SPWG 0x1010
#define MEDIA_BUS_FMT_BGR888_1X24 0x1013
#define MEDIA_BUS_FMT_GBR888_1X24 0x1014
#define MEDIA_BUS_FMT_RGB888_1X24 0x100a
#define MEDIA_BUS_FMT_RGB888_2X12_BE 0x100b
#define MEDIA_BUS_FMT_RGB888_2X12_LE 0x100c
#define MEDIA_BUS_FMT_RGB888_1X7X4_SPWG 0x1011
#define MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA 0x1012
#define MEDIA_BUS_FMT_ARGB8888_1X32 0x100d
/* YUV (including grey) - next is 0x2024 */
/* YUV (including grey) - next is 0x2025 */
#define MEDIA_BUS_FMT_Y8_1X8 0x2001
#define MEDIA_BUS_FMT_UV8_1X8 0x2015
#define MEDIA_BUS_FMT_UYVY8_1_5X8 0x2002
@ -74,6 +82,7 @@
#define MEDIA_BUS_FMT_VYUY10_1X20 0x201b
#define MEDIA_BUS_FMT_YUYV10_1X20 0x200d
#define MEDIA_BUS_FMT_YVYU10_1X20 0x200e
#define MEDIA_BUS_FMT_YUV8_1X24 0x2024
#define MEDIA_BUS_FMT_YUV10_1X30 0x2016
#define MEDIA_BUS_FMT_AYUV8_1X32 0x2017
#define MEDIA_BUS_FMT_UYVY12_2X12 0x201c

View File

@ -39,7 +39,7 @@ struct ipu_di_signal_cfg {
struct videomode mode;
u32 pixel_fmt;
u32 bus_format;
u32 v_to_h_sync;
#define IPU_DI_CLKMODE_SYNC (1 << 0)