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:
Коммит
1d2add28ed
|
@ -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>
|
||||
|
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Загрузка…
Ссылка в новой задаче