mirror of https://gitee.com/openkylin/linux.git
drm-misc-next for v5.6:
UAPI Changes: Cross-subsystem Changes: - Convert simple panel bindings to a template. Core Changes: - Revert drm-bridge-state changes, it causes a dependency error between drm and drm_kms_helper. - Fix when disabling crc's. - Assorted Kconfig fixes. Driver Changes: - Add ddc symlinks to more drivers. - Fix chained bridge handling in exynos and vc4. - More clock rate fixes in sun4i. - Add support for AUO B116XAK01, GiantPlus GPM940B0, Sony ACX424AKP, BOE NV140FHM-N49, Satoz SAT050AT40H12R2 and Sharp LS020B1DD01D panels. - Assorted small bugfixes. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEuXvWqAysSYEJGuVH/lWMcqZwE8MFAl4YZQEACgkQ/lWMcqZw E8OLZA/+NOx1QWnXNV/PgMc8aleGGOuqnezWRZr7yb1Ai+oaDk7cmc5sARu1/K0P tiMohehLOyYTu254I5xn+8jbaw1AhZcS3IGT27ayXz6MJPM3feE5uv/0pEyhd3Jc 8AZ82Y12wGgWxEMiOH8YONoseEObTcVxiubmLz7GdNu4m+T7qa6D8Gh1B1rbZqVj 5H00yHvuJuHMQu81fSJVNEt5VhxEqQGnAzRQ28cvVxb6VD5y6xCvY3vMz/63/+UO 8f2irsSydqAAeKQ33obcS6nBy394YxKDwCPsMR8zo6DMIw7xp4iuR1k39J3JYV8+ 3RIxAq1aOBRrIYVxzqNTztM5A2bo5gxUV8gYw34Jkv6sHAgtOiAU8zyZUbt8A/Mx 69FVFQ26uww+1ccgEWnrJi+8lafkublgJRsZ+u5/u+dY4aHPeEhxWCpx1O3X1dwU bASsRp26KLK+e4TJpg3Xk6lOZrepkJsuHdewIuwgs4kWKz5xMWi2tlXO2yGTLfor B8H38VvmFSkRLqthVWOKWe/Geoe3G36X3O4YiSAcT9wVZmGy77maJfppvfAP/hlO SItIn4Z4B4zSyrQ5T0n26LcWKenRKVMbtPcF14gxdgGx4QpMrYnIO25gL10upyXN eFLDZm3spUf5YPVAYmtSHqVQeA9HJ9YEfbwAdJ8LTTOVKs7OhXM= =P/VK -----END PGP SIGNATURE----- Merge tag 'drm-misc-next-2020-01-10' of git://anongit.freedesktop.org/drm/drm-misc into drm-next drm-misc-next for v5.6: UAPI Changes: Cross-subsystem Changes: - Convert simple panel bindings to a template. Core Changes: - Revert drm-bridge-state changes, it causes a dependency error between drm and drm_kms_helper. - Fix when disabling crc's. - Assorted Kconfig fixes. Driver Changes: - Add ddc symlinks to more drivers. - Fix chained bridge handling in exynos and vc4. - More clock rate fixes in sun4i. - Add support for AUO B116XAK01, GiantPlus GPM940B0, Sony ACX424AKP, BOE NV140FHM-N49, Satoz SAT050AT40H12R2 and Sharp LS020B1DD01D panels. - Assorted small bugfixes. Signed-off-by: Dave Airlie <airlied@redhat.com> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/1e8d4944-68d7-0df3-f39b-31f6fba22a2a@linux.intel.com
This commit is contained in:
commit
79f88da22b
|
@ -0,0 +1,291 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/allwinner,sun4i-a10-display-backend.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Allwinner A10 Display Engine Backend Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- Chen-Yu Tsai <wens@csie.org>
|
||||
- Maxime Ripard <mripard@kernel.org>
|
||||
|
||||
description: |
|
||||
The display engine backend exposes layers and sprites to the system.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- allwinner,sun4i-a10-display-backend
|
||||
- allwinner,sun5i-a13-display-backend
|
||||
- allwinner,sun6i-a31-display-backend
|
||||
- allwinner,sun7i-a20-display-backend
|
||||
- allwinner,sun8i-a23-display-backend
|
||||
- allwinner,sun8i-a33-display-backend
|
||||
- allwinner,sun9i-a80-display-backend
|
||||
|
||||
reg:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
items:
|
||||
- description: Display Backend registers
|
||||
- description: SAT registers
|
||||
|
||||
reg-names:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
items:
|
||||
- const: be
|
||||
- const: sat
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
minItems: 3
|
||||
maxItems: 4
|
||||
items:
|
||||
- description: The backend interface clock
|
||||
- description: The backend module clock
|
||||
- description: The backend DRAM clock
|
||||
- description: The SAT clock
|
||||
|
||||
clock-names:
|
||||
minItems: 3
|
||||
maxItems: 4
|
||||
items:
|
||||
- const: ahb
|
||||
- const: mod
|
||||
- const: ram
|
||||
- const: sat
|
||||
|
||||
resets:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
items:
|
||||
- description: The Backend reset line
|
||||
- description: The SAT reset line
|
||||
|
||||
reset-names:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
items:
|
||||
- const: be
|
||||
- const: sat
|
||||
|
||||
# FIXME: This should be made required eventually once every SoC will
|
||||
# have the MBUS declared.
|
||||
interconnects:
|
||||
maxItems: 1
|
||||
|
||||
# FIXME: This should be made required eventually once every SoC will
|
||||
# have the MBUS declared.
|
||||
interconnect-names:
|
||||
const: dma-mem
|
||||
|
||||
ports:
|
||||
type: object
|
||||
description: |
|
||||
A ports node with endpoint definitions as defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt.
|
||||
|
||||
properties:
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
port@0:
|
||||
type: object
|
||||
description: |
|
||||
Input endpoints of the controller.
|
||||
|
||||
port@1:
|
||||
type: object
|
||||
description: |
|
||||
Output endpoints of the controller.
|
||||
|
||||
required:
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
- port@0
|
||||
- port@1
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- ports
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: allwinner,sun8i-a33-display-backend
|
||||
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
minItems: 2
|
||||
|
||||
reg-names:
|
||||
minItems: 2
|
||||
|
||||
clocks:
|
||||
minItems: 4
|
||||
|
||||
clock-names:
|
||||
minItems: 4
|
||||
|
||||
resets:
|
||||
minItems: 2
|
||||
|
||||
reset-names:
|
||||
minItems: 2
|
||||
|
||||
required:
|
||||
- reg-names
|
||||
- reset-names
|
||||
|
||||
else:
|
||||
properties:
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
reg-names:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 3
|
||||
|
||||
clock-names:
|
||||
maxItems: 3
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
reset-names:
|
||||
maxItems: 1
|
||||
|
||||
examples:
|
||||
- |
|
||||
/*
|
||||
* This comes from the clock/sun4i-a10-ccu.h and
|
||||
* reset/sun4i-a10-ccu.h headers, but we can't include them since
|
||||
* it would trigger a bunch of warnings for redefinitions of
|
||||
* symbols with the other example.
|
||||
*/
|
||||
|
||||
#define CLK_AHB_DE_BE0 42
|
||||
#define CLK_DRAM_DE_BE0 140
|
||||
#define CLK_DE_BE0 144
|
||||
#define RST_DE_BE0 5
|
||||
|
||||
display-backend@1e60000 {
|
||||
compatible = "allwinner,sun4i-a10-display-backend";
|
||||
reg = <0x01e60000 0x10000>;
|
||||
interrupts = <47>;
|
||||
clocks = <&ccu CLK_AHB_DE_BE0>, <&ccu CLK_DE_BE0>,
|
||||
<&ccu CLK_DRAM_DE_BE0>;
|
||||
clock-names = "ahb", "mod",
|
||||
"ram";
|
||||
resets = <&ccu RST_DE_BE0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0>;
|
||||
|
||||
endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&fe0_out_be0>;
|
||||
};
|
||||
|
||||
endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&fe1_out_be0>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <1>;
|
||||
|
||||
endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&tcon0_in_be0>;
|
||||
};
|
||||
|
||||
endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&tcon1_in_be0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
/*
|
||||
* This comes from the clock/sun8i-a23-a33-ccu.h and
|
||||
* reset/sun8i-a23-a33-ccu.h headers, but we can't include them
|
||||
* since it would trigger a bunch of warnings for redefinitions of
|
||||
* symbols with the other example.
|
||||
*/
|
||||
|
||||
#define CLK_BUS_DE_BE 40
|
||||
#define CLK_BUS_SAT 46
|
||||
#define CLK_DRAM_DE_BE 84
|
||||
#define CLK_DE_BE 85
|
||||
#define RST_BUS_DE_BE 21
|
||||
#define RST_BUS_SAT 27
|
||||
|
||||
display-backend@1e60000 {
|
||||
compatible = "allwinner,sun8i-a33-display-backend";
|
||||
reg = <0x01e60000 0x10000>, <0x01e80000 0x1000>;
|
||||
reg-names = "be", "sat";
|
||||
interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&ccu CLK_BUS_DE_BE>, <&ccu CLK_DE_BE>,
|
||||
<&ccu CLK_DRAM_DE_BE>, <&ccu CLK_BUS_SAT>;
|
||||
clock-names = "ahb", "mod",
|
||||
"ram", "sat";
|
||||
resets = <&ccu RST_BUS_DE_BE>, <&ccu RST_BUS_SAT>;
|
||||
reset-names = "be", "sat";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
endpoint {
|
||||
remote-endpoint = <&fe0_out_be0>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
|
||||
endpoint {
|
||||
remote-endpoint = <&drc0_in_be0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
|
@ -0,0 +1,114 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/allwinner,sun4i-a10-display-engine.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Allwinner A10 Display Engine Pipeline Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- Chen-Yu Tsai <wens@csie.org>
|
||||
- Maxime Ripard <mripard@kernel.org>
|
||||
|
||||
description: |
|
||||
The display engine pipeline (and its entry point, since it can be
|
||||
either directly the backend or the frontend) is represented as an
|
||||
extra node.
|
||||
|
||||
The Allwinner A10 Display pipeline is composed of several components
|
||||
that are going to be documented below:
|
||||
|
||||
For all connections between components up to the TCONs in the
|
||||
display pipeline, when there are multiple components of the same
|
||||
type at the same depth, the local endpoint ID must be the same as
|
||||
the remote component's index. For example, if the remote endpoint is
|
||||
Frontend 1, then the local endpoint ID must be 1.
|
||||
|
||||
Frontend 0 [0] ------- [0] Backend 0 [0] ------- [0] TCON 0
|
||||
[1] -- -- [1] [1] -- -- [1]
|
||||
\ / \ /
|
||||
X X
|
||||
/ \ / \
|
||||
[0] -- -- [0] [0] -- -- [0]
|
||||
Frontend 1 [1] ------- [1] Backend 1 [1] ------- [1] TCON 1
|
||||
|
||||
For a two pipeline system such as the one depicted above, the lines
|
||||
represent the connections between the components, while the numbers
|
||||
within the square brackets corresponds to the ID of the local endpoint.
|
||||
|
||||
The same rule also applies to DE 2.0 mixer-TCON connections:
|
||||
|
||||
Mixer 0 [0] ----------- [0] TCON 0
|
||||
[1] ---- ---- [1]
|
||||
\ /
|
||||
X
|
||||
/ \
|
||||
[0] ---- ---- [0]
|
||||
Mixer 1 [1] ----------- [1] TCON 1
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- allwinner,sun4i-a10-display-engine
|
||||
- allwinner,sun5i-a10s-display-engine
|
||||
- allwinner,sun5i-a13-display-engine
|
||||
- allwinner,sun6i-a31-display-engine
|
||||
- allwinner,sun6i-a31s-display-engine
|
||||
- allwinner,sun7i-a20-display-engine
|
||||
- allwinner,sun8i-a23-display-engine
|
||||
- allwinner,sun8i-a33-display-engine
|
||||
- allwinner,sun8i-a83t-display-engine
|
||||
- allwinner,sun8i-h3-display-engine
|
||||
- allwinner,sun8i-r40-display-engine
|
||||
- allwinner,sun8i-v3s-display-engine
|
||||
- allwinner,sun9i-a80-display-engine
|
||||
- allwinner,sun50i-a64-display-engine
|
||||
- allwinner,sun50i-h6-display-engine
|
||||
|
||||
allwinner,pipelines:
|
||||
allOf:
|
||||
- $ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
- minItems: 1
|
||||
maxItems: 2
|
||||
description: |
|
||||
Available display engine frontends (DE 1.0) or mixers (DE
|
||||
2.0/3.0) available.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- allwinner,pipelines
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- allwinner,sun4i-a10-display-engine
|
||||
- allwinner,sun6i-a31-display-engine
|
||||
- allwinner,sun6i-a31s-display-engine
|
||||
- allwinner,sun7i-a20-display-engine
|
||||
- allwinner,sun8i-a83t-display-engine
|
||||
- allwinner,sun8i-r40-display-engine
|
||||
- allwinner,sun9i-a80-display-engine
|
||||
- allwinner,sun50i-a64-display-engine
|
||||
|
||||
then:
|
||||
properties:
|
||||
allwinner,pipelines:
|
||||
minItems: 2
|
||||
|
||||
else:
|
||||
properties:
|
||||
allwinner,pipelines:
|
||||
maxItems: 1
|
||||
|
||||
examples:
|
||||
- |
|
||||
de: display-engine {
|
||||
compatible = "allwinner,sun4i-a10-display-engine";
|
||||
allwinner,pipelines = <&fe0>, <&fe1>;
|
||||
};
|
||||
|
||||
...
|
|
@ -0,0 +1,138 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/allwinner,sun4i-a10-display-frontend.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Allwinner A10 Display Engine Frontend Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- Chen-Yu Tsai <wens@csie.org>
|
||||
- Maxime Ripard <mripard@kernel.org>
|
||||
|
||||
description: |
|
||||
The display engine frontend does formats conversion, scaling,
|
||||
deinterlacing and color space conversion.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- allwinner,sun4i-a10-display-frontend
|
||||
- allwinner,sun5i-a13-display-frontend
|
||||
- allwinner,sun6i-a31-display-frontend
|
||||
- allwinner,sun7i-a20-display-frontend
|
||||
- allwinner,sun8i-a23-display-frontend
|
||||
- allwinner,sun8i-a33-display-frontend
|
||||
- allwinner,sun9i-a80-display-frontend
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: The frontend interface clock
|
||||
- description: The frontend module clock
|
||||
- description: The frontend DRAM clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: ahb
|
||||
- const: mod
|
||||
- const: ram
|
||||
|
||||
# FIXME: This should be made required eventually once every SoC will
|
||||
# have the MBUS declared.
|
||||
interconnects:
|
||||
maxItems: 1
|
||||
|
||||
# FIXME: This should be made required eventually once every SoC will
|
||||
# have the MBUS declared.
|
||||
interconnect-names:
|
||||
const: dma-mem
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
ports:
|
||||
type: object
|
||||
description: |
|
||||
A ports node with endpoint definitions as defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt.
|
||||
|
||||
properties:
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
port@0:
|
||||
type: object
|
||||
description: |
|
||||
Input endpoints of the controller.
|
||||
|
||||
port@1:
|
||||
type: object
|
||||
description: |
|
||||
Output endpoints of the controller.
|
||||
|
||||
required:
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
- port@1
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- ports
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/sun4i-a10-ccu.h>
|
||||
#include <dt-bindings/reset/sun4i-a10-ccu.h>
|
||||
|
||||
fe0: display-frontend@1e00000 {
|
||||
compatible = "allwinner,sun4i-a10-display-frontend";
|
||||
reg = <0x01e00000 0x20000>;
|
||||
interrupts = <47>;
|
||||
clocks = <&ccu CLK_AHB_DE_FE0>, <&ccu CLK_DE_FE0>,
|
||||
<&ccu CLK_DRAM_DE_FE0>;
|
||||
clock-names = "ahb", "mod",
|
||||
"ram";
|
||||
resets = <&ccu RST_DE_FE0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
fe0_out: port@1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <1>;
|
||||
|
||||
fe0_out_be0: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&be0_in_fe0>;
|
||||
};
|
||||
|
||||
fe0_out_be1: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&be1_in_fe0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
...
|
|
@ -0,0 +1,183 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/allwinner,sun4i-a10-hdmi.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Allwinner A10 HDMI Controller Device Tree Bindings
|
||||
|
||||
description: |
|
||||
The HDMI Encoder supports the HDMI video and audio outputs, and does
|
||||
CEC. It is one end of the pipeline.
|
||||
|
||||
maintainers:
|
||||
- Chen-Yu Tsai <wens@csie.org>
|
||||
- Maxime Ripard <mripard@kernel.org>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: allwinner,sun4i-a10-hdmi
|
||||
- const: allwinner,sun5i-a10s-hdmi
|
||||
- const: allwinner,sun6i-a31-hdmi
|
||||
- items:
|
||||
- const: allwinner,sun7i-a20-hdmi
|
||||
- const: allwinner,sun5i-a10s-hdmi
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
oneOf:
|
||||
- items:
|
||||
- description: The HDMI interface clock
|
||||
- description: The HDMI module clock
|
||||
- description: The first video PLL
|
||||
- description: The second video PLL
|
||||
|
||||
- items:
|
||||
- description: The HDMI interface clock
|
||||
- description: The HDMI module clock
|
||||
- description: The HDMI DDC clock
|
||||
- description: The first video PLL
|
||||
- description: The second video PLL
|
||||
|
||||
clock-names:
|
||||
oneOf:
|
||||
- items:
|
||||
- const: ahb
|
||||
- const: mod
|
||||
- const: pll-0
|
||||
- const: pll-1
|
||||
|
||||
- items:
|
||||
- const: ahb
|
||||
- const: mod
|
||||
- const: ddc
|
||||
- const: pll-0
|
||||
- const: pll-1
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
dmas:
|
||||
items:
|
||||
- description: DDC Transmission DMA Channel
|
||||
- description: DDC Reception DMA Channel
|
||||
- description: Audio Transmission DMA Channel
|
||||
|
||||
dma-names:
|
||||
items:
|
||||
- const: ddc-tx
|
||||
- const: ddc-rx
|
||||
- const: audio-tx
|
||||
|
||||
ports:
|
||||
type: object
|
||||
description: |
|
||||
A ports node with endpoint definitions as defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt.
|
||||
|
||||
properties:
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
port@0:
|
||||
type: object
|
||||
description: |
|
||||
Input endpoints of the controller.
|
||||
|
||||
port@1:
|
||||
type: object
|
||||
description: |
|
||||
Output endpoints of the controller. Usually an HDMI
|
||||
connector.
|
||||
|
||||
required:
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
- port@0
|
||||
- port@1
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- dmas
|
||||
- dma-names
|
||||
|
||||
if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: allwinner,sun6i-a31-hdmi
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 5
|
||||
|
||||
clock-names:
|
||||
minItems: 5
|
||||
|
||||
required:
|
||||
- resets
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/sun4i-a10-ccu.h>
|
||||
#include <dt-bindings/dma/sun4i-a10.h>
|
||||
#include <dt-bindings/reset/sun4i-a10-ccu.h>
|
||||
|
||||
hdmi: hdmi@1c16000 {
|
||||
compatible = "allwinner,sun4i-a10-hdmi";
|
||||
reg = <0x01c16000 0x1000>;
|
||||
interrupts = <58>;
|
||||
clocks = <&ccu CLK_AHB_HDMI0>, <&ccu CLK_HDMI>,
|
||||
<&ccu CLK_PLL_VIDEO0_2X>,
|
||||
<&ccu CLK_PLL_VIDEO1_2X>;
|
||||
clock-names = "ahb", "mod", "pll-0", "pll-1";
|
||||
dmas = <&dma SUN4I_DMA_NORMAL 16>,
|
||||
<&dma SUN4I_DMA_NORMAL 16>,
|
||||
<&dma SUN4I_DMA_DEDICATED 24>;
|
||||
dma-names = "ddc-tx", "ddc-rx", "audio-tx";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
hdmi_in: port@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0>;
|
||||
|
||||
hdmi_in_tcon0: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&tcon0_out_hdmi>;
|
||||
};
|
||||
|
||||
hdmi_in_tcon1: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&tcon1_out_hdmi>;
|
||||
};
|
||||
};
|
||||
|
||||
hdmi_out: port@1 {
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
|
@ -0,0 +1,676 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/allwinner,sun4i-a10-tcon.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Allwinner A10 Timings Controller (TCON) Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- Chen-Yu Tsai <wens@csie.org>
|
||||
- Maxime Ripard <mripard@kernel.org>
|
||||
|
||||
description: |
|
||||
The TCON acts as a timing controller for RGB, LVDS and TV
|
||||
interfaces.
|
||||
|
||||
properties:
|
||||
"#clock-cells":
|
||||
const: 0
|
||||
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: allwinner,sun4i-a10-tcon
|
||||
- const: allwinner,sun5i-a13-tcon
|
||||
- const: allwinner,sun6i-a31-tcon
|
||||
- const: allwinner,sun6i-a31s-tcon
|
||||
- const: allwinner,sun7i-a20-tcon
|
||||
- const: allwinner,sun8i-a23-tcon
|
||||
- const: allwinner,sun8i-a33-tcon
|
||||
- const: allwinner,sun8i-a83t-tcon-lcd
|
||||
- const: allwinner,sun8i-a83t-tcon-tv
|
||||
- const: allwinner,sun8i-r40-tcon-tv
|
||||
- const: allwinner,sun8i-v3s-tcon
|
||||
- const: allwinner,sun9i-a80-tcon-lcd
|
||||
- const: allwinner,sun9i-a80-tcon-tv
|
||||
|
||||
- items:
|
||||
- enum:
|
||||
- allwinner,sun50i-a64-tcon-lcd
|
||||
- const: allwinner,sun8i-a83t-tcon-lcd
|
||||
|
||||
- items:
|
||||
- enum:
|
||||
- allwinner,sun8i-h3-tcon-tv
|
||||
- allwinner,sun50i-a64-tcon-tv
|
||||
- allwinner,sun50i-h6-tcon-tv
|
||||
- const: allwinner,sun8i-a83t-tcon-tv
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
clock-output-names:
|
||||
allOf:
|
||||
- $ref: /schemas/types.yaml#/definitions/string-array
|
||||
- maxItems: 1
|
||||
description:
|
||||
Name of the LCD pixel clock created.
|
||||
|
||||
dmas:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
anyOf:
|
||||
- items:
|
||||
- description: TCON Reset Line
|
||||
|
||||
- items:
|
||||
- description: TCON Reset Line
|
||||
- description: TCON LVDS Reset Line
|
||||
|
||||
- items:
|
||||
- description: TCON Reset Line
|
||||
- description: TCON eDP Reset Line
|
||||
|
||||
- items:
|
||||
- description: TCON Reset Line
|
||||
- description: TCON eDP Reset Line
|
||||
- description: TCON LVDS Reset Line
|
||||
|
||||
reset-names:
|
||||
oneOf:
|
||||
- const: lcd
|
||||
|
||||
- items:
|
||||
- const: lcd
|
||||
- const: lvds
|
||||
|
||||
- items:
|
||||
- const: lcd
|
||||
- const: edp
|
||||
|
||||
- items:
|
||||
- const: lcd
|
||||
- const: edp
|
||||
- const: lvds
|
||||
|
||||
ports:
|
||||
type: object
|
||||
description: |
|
||||
A ports node with endpoint definitions as defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt.
|
||||
|
||||
properties:
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
port@0:
|
||||
type: object
|
||||
description: |
|
||||
Input endpoints of the controller.
|
||||
|
||||
port@1:
|
||||
type: object
|
||||
description: |
|
||||
Output endpoints of the controller.
|
||||
|
||||
patternProperties:
|
||||
"^endpoint(@[0-9])$":
|
||||
type: object
|
||||
|
||||
properties:
|
||||
allwinner,tcon-channel:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: |
|
||||
TCON can have 1 or 2 channels, usually with the
|
||||
first channel being used for the panels interfaces
|
||||
(RGB, LVDS, etc.), and the second being used for the
|
||||
outputs that require another controller (TV Encoder,
|
||||
HDMI, etc.).
|
||||
|
||||
If that property is present, specifies the TCON
|
||||
channel the endpoint is associated to. If that
|
||||
property is not present, the endpoint number will be
|
||||
used as the channel number.
|
||||
|
||||
unevaluatedProperties: true
|
||||
|
||||
required:
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
- port@0
|
||||
- port@1
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- ports
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- allwinner,sun4i-a10-tcon
|
||||
- allwinner,sun5i-a13-tcon
|
||||
- allwinner,sun7i-a20-tcon
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 3
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: ahb
|
||||
- const: tcon-ch0
|
||||
- const: tcon-ch1
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- allwinner,sun6i-a31-tcon
|
||||
- allwinner,sun6i-a31s-tcon
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 4
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: ahb
|
||||
- const: tcon-ch0
|
||||
- const: tcon-ch1
|
||||
- const: lvds-alt
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- allwinner,sun8i-a23-tcon
|
||||
- allwinner,sun8i-a33-tcon
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 3
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: ahb
|
||||
- const: tcon-ch0
|
||||
- const: lvds-alt
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- allwinner,sun8i-a83t-tcon-lcd
|
||||
- allwinner,sun8i-v3s-tcon
|
||||
- allwinner,sun9i-a80-tcon-lcd
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 2
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: ahb
|
||||
- const: tcon-ch0
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- allwinner,sun8i-a83t-tcon-tv
|
||||
- allwinner,sun8i-r40-tcon-tv
|
||||
- allwinner,sun9i-a80-tcon-tv
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 2
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: ahb
|
||||
- const: tcon-ch1
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- allwinner,sun5i-a13-tcon
|
||||
- allwinner,sun6i-a31-tcon
|
||||
- allwinner,sun6i-a31s-tcon
|
||||
- allwinner,sun7i-a20-tcon
|
||||
- allwinner,sun8i-a23-tcon
|
||||
- allwinner,sun8i-a33-tcon
|
||||
- allwinner,sun8i-v3s-tcon
|
||||
- allwinner,sun9i-a80-tcon-lcd
|
||||
- allwinner,sun4i-a10-tcon
|
||||
- allwinner,sun8i-a83t-tcon-lcd
|
||||
|
||||
then:
|
||||
required:
|
||||
- "#clock-cells"
|
||||
- clock-output-names
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- allwinner,sun6i-a31-tcon
|
||||
- allwinner,sun6i-a31s-tcon
|
||||
- allwinner,sun8i-a23-tcon
|
||||
- allwinner,sun8i-a33-tcon
|
||||
- allwinner,sun8i-a83t-tcon-lcd
|
||||
|
||||
then:
|
||||
properties:
|
||||
resets:
|
||||
minItems: 2
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: lcd
|
||||
- const: lvds
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- allwinner,sun9i-a80-tcon-lcd
|
||||
|
||||
then:
|
||||
properties:
|
||||
resets:
|
||||
minItems: 3
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: lcd
|
||||
- const: edp
|
||||
- const: lvds
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- allwinner,sun9i-a80-tcon-tv
|
||||
|
||||
then:
|
||||
properties:
|
||||
resets:
|
||||
minItems: 2
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: lcd
|
||||
- const: edp
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- allwinner,sun4i-a10-tcon
|
||||
- allwinner,sun5i-a13-tcon
|
||||
- allwinner,sun6i-a31-tcon
|
||||
- allwinner,sun6i-a31s-tcon
|
||||
- allwinner,sun7i-a20-tcon
|
||||
- allwinner,sun8i-a23-tcon
|
||||
- allwinner,sun8i-a33-tcon
|
||||
|
||||
then:
|
||||
required:
|
||||
- dmas
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/dma/sun4i-a10.h>
|
||||
|
||||
/*
|
||||
* This comes from the clock/sun4i-a10-ccu.h and
|
||||
* reset/sun4i-a10-ccu.h headers, but we can't include them since
|
||||
* it would trigger a bunch of warnings for redefinitions of
|
||||
* symbols with the other example.
|
||||
*/
|
||||
|
||||
#define CLK_AHB_LCD0 56
|
||||
#define CLK_TCON0_CH0 149
|
||||
#define CLK_TCON0_CH1 155
|
||||
#define RST_TCON0 11
|
||||
|
||||
lcd-controller@1c0c000 {
|
||||
compatible = "allwinner,sun4i-a10-tcon";
|
||||
reg = <0x01c0c000 0x1000>;
|
||||
interrupts = <44>;
|
||||
resets = <&ccu RST_TCON0>;
|
||||
reset-names = "lcd";
|
||||
clocks = <&ccu CLK_AHB_LCD0>,
|
||||
<&ccu CLK_TCON0_CH0>,
|
||||
<&ccu CLK_TCON0_CH1>;
|
||||
clock-names = "ahb",
|
||||
"tcon-ch0",
|
||||
"tcon-ch1";
|
||||
clock-output-names = "tcon0-pixel-clock";
|
||||
#clock-cells = <0>;
|
||||
dmas = <&dma SUN4I_DMA_DEDICATED 14>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0>;
|
||||
|
||||
endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&be0_out_tcon0>;
|
||||
};
|
||||
|
||||
endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&be1_out_tcon0>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <1>;
|
||||
|
||||
endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&hdmi_in_tcon0>;
|
||||
allwinner,tcon-channel = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#undef CLK_AHB_LCD0
|
||||
#undef CLK_TCON0_CH0
|
||||
#undef CLK_TCON0_CH1
|
||||
#undef RST_TCON0
|
||||
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
/*
|
||||
* This comes from the clock/sun6i-a31-ccu.h and
|
||||
* reset/sun6i-a31-ccu.h headers, but we can't include them since
|
||||
* it would trigger a bunch of warnings for redefinitions of
|
||||
* symbols with the other example.
|
||||
*/
|
||||
|
||||
#define CLK_PLL_MIPI 15
|
||||
#define CLK_AHB1_LCD0 47
|
||||
#define CLK_LCD0_CH0 127
|
||||
#define CLK_LCD0_CH1 129
|
||||
#define RST_AHB1_LCD0 27
|
||||
#define RST_AHB1_LVDS 41
|
||||
|
||||
lcd-controller@1c0c000 {
|
||||
compatible = "allwinner,sun6i-a31-tcon";
|
||||
reg = <0x01c0c000 0x1000>;
|
||||
interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
|
||||
dmas = <&dma 11>;
|
||||
resets = <&ccu RST_AHB1_LCD0>, <&ccu RST_AHB1_LVDS>;
|
||||
reset-names = "lcd", "lvds";
|
||||
clocks = <&ccu CLK_AHB1_LCD0>,
|
||||
<&ccu CLK_LCD0_CH0>,
|
||||
<&ccu CLK_LCD0_CH1>,
|
||||
<&ccu CLK_PLL_MIPI>;
|
||||
clock-names = "ahb",
|
||||
"tcon-ch0",
|
||||
"tcon-ch1",
|
||||
"lvds-alt";
|
||||
clock-output-names = "tcon0-pixel-clock";
|
||||
#clock-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0>;
|
||||
|
||||
endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&drc0_out_tcon0>;
|
||||
};
|
||||
|
||||
endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&drc1_out_tcon0>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <1>;
|
||||
|
||||
endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&hdmi_in_tcon0>;
|
||||
allwinner,tcon-channel = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#undef CLK_PLL_MIPI
|
||||
#undef CLK_AHB1_LCD0
|
||||
#undef CLK_LCD0_CH0
|
||||
#undef CLK_LCD0_CH1
|
||||
#undef RST_AHB1_LCD0
|
||||
#undef RST_AHB1_LVDS
|
||||
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
/*
|
||||
* This comes from the clock/sun9i-a80-ccu.h and
|
||||
* reset/sun9i-a80-ccu.h headers, but we can't include them since
|
||||
* it would trigger a bunch of warnings for redefinitions of
|
||||
* symbols with the other example.
|
||||
*/
|
||||
|
||||
#define CLK_BUS_LCD0 102
|
||||
#define CLK_LCD0 58
|
||||
#define RST_BUS_LCD0 22
|
||||
#define RST_BUS_EDP 24
|
||||
#define RST_BUS_LVDS 25
|
||||
|
||||
lcd-controller@3c00000 {
|
||||
compatible = "allwinner,sun9i-a80-tcon-lcd";
|
||||
reg = <0x03c00000 0x10000>;
|
||||
interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&ccu CLK_BUS_LCD0>, <&ccu CLK_LCD0>;
|
||||
clock-names = "ahb", "tcon-ch0";
|
||||
resets = <&ccu RST_BUS_LCD0>, <&ccu RST_BUS_EDP>, <&ccu RST_BUS_LVDS>;
|
||||
reset-names = "lcd", "edp", "lvds";
|
||||
clock-output-names = "tcon0-pixel-clock";
|
||||
#clock-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
endpoint {
|
||||
remote-endpoint = <&drc0_out_tcon0>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#undef CLK_BUS_TCON0
|
||||
#undef CLK_TCON0
|
||||
#undef RST_BUS_TCON0
|
||||
#undef RST_BUS_EDP
|
||||
#undef RST_BUS_LVDS
|
||||
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
/*
|
||||
* This comes from the clock/sun8i-a83t-ccu.h and
|
||||
* reset/sun8i-a83t-ccu.h headers, but we can't include them since
|
||||
* it would trigger a bunch of warnings for redefinitions of
|
||||
* symbols with the other example.
|
||||
*/
|
||||
|
||||
#define CLK_BUS_TCON0 36
|
||||
#define CLK_TCON0 85
|
||||
#define RST_BUS_TCON0 22
|
||||
#define RST_BUS_LVDS 31
|
||||
|
||||
lcd-controller@1c0c000 {
|
||||
compatible = "allwinner,sun8i-a83t-tcon-lcd";
|
||||
reg = <0x01c0c000 0x1000>;
|
||||
interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&ccu CLK_BUS_TCON0>, <&ccu CLK_TCON0>;
|
||||
clock-names = "ahb", "tcon-ch0";
|
||||
clock-output-names = "tcon-pixel-clock";
|
||||
#clock-cells = <0>;
|
||||
resets = <&ccu RST_BUS_TCON0>, <&ccu RST_BUS_LVDS>;
|
||||
reset-names = "lcd", "lvds";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0>;
|
||||
|
||||
endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&mixer0_out_tcon0>;
|
||||
};
|
||||
|
||||
endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&mixer1_out_tcon0>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#undef CLK_BUS_TCON0
|
||||
#undef CLK_TCON0
|
||||
#undef RST_BUS_TCON0
|
||||
#undef RST_BUS_LVDS
|
||||
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
/*
|
||||
* This comes from the clock/sun8i-r40-ccu.h and
|
||||
* reset/sun8i-r40-ccu.h headers, but we can't include them since
|
||||
* it would trigger a bunch of warnings for redefinitions of
|
||||
* symbols with the other example.
|
||||
*/
|
||||
|
||||
#define CLK_BUS_TCON_TV0 73
|
||||
#define RST_BUS_TCON_TV0 49
|
||||
|
||||
tcon_tv0: lcd-controller@1c73000 {
|
||||
compatible = "allwinner,sun8i-r40-tcon-tv";
|
||||
reg = <0x01c73000 0x1000>;
|
||||
interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&ccu CLK_BUS_TCON_TV0>, <&tcon_top 0>;
|
||||
clock-names = "ahb", "tcon-ch1";
|
||||
resets = <&ccu RST_BUS_TCON_TV0>;
|
||||
reset-names = "lcd";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0>;
|
||||
|
||||
endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&tcon_top_mixer0_out_tcon_tv0>;
|
||||
};
|
||||
|
||||
endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&tcon_top_mixer1_out_tcon_tv0>;
|
||||
};
|
||||
};
|
||||
|
||||
tcon_tv0_out: port@1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <1>;
|
||||
|
||||
endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&tcon_top_hdmi_in_tcon_tv0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#undef CLK_BUS_TCON_TV0
|
||||
#undef RST_BUS_TCON_TV0
|
||||
|
||||
...
|
|
@ -0,0 +1,62 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/allwinner,sun4i-a10-tv-encoder.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Allwinner A10 TV Encoder Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- Chen-Yu Tsai <wens@csie.org>
|
||||
- Maxime Ripard <mripard@kernel.org>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: allwinner,sun4i-a10-tv-encoder
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
port:
|
||||
type: object
|
||||
description:
|
||||
A port node with endpoint definitions as defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt. The
|
||||
first port should be the input endpoint, usually coming from the
|
||||
associated TCON.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- resets
|
||||
- port
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
tve0: tv-encoder@1c0a000 {
|
||||
compatible = "allwinner,sun4i-a10-tv-encoder";
|
||||
reg = <0x01c0a000 0x1000>;
|
||||
clocks = <&ahb_gates 34>;
|
||||
resets = <&tcon_ch0_clk 0>;
|
||||
|
||||
port {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
tve0_in_tcon0: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&tcon0_out_tve0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
|
@ -0,0 +1,138 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/allwinner,sun6i-a31-drc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Allwinner A31 Dynamic Range Controller Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- Chen-Yu Tsai <wens@csie.org>
|
||||
- Maxime Ripard <mripard@kernel.org>
|
||||
|
||||
description: |
|
||||
The DRC (Dynamic Range Controller) allows to dynamically adjust
|
||||
pixel brightness/contrast based on histogram measurements for LCD
|
||||
content adaptive backlight control.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- allwinner,sun6i-a31-drc
|
||||
- allwinner,sun6i-a31s-drc
|
||||
- allwinner,sun8i-a23-drc
|
||||
- allwinner,sun8i-a33-drc
|
||||
- allwinner,sun9i-a80-drc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: The DRC interface clock
|
||||
- description: The DRC module clock
|
||||
- description: The DRC DRAM clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: ahb
|
||||
- const: mod
|
||||
- const: ram
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
ports:
|
||||
type: object
|
||||
description: |
|
||||
A ports node with endpoint definitions as defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt.
|
||||
|
||||
properties:
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
port@0:
|
||||
type: object
|
||||
description: |
|
||||
Input endpoints of the controller.
|
||||
|
||||
port@1:
|
||||
type: object
|
||||
description: |
|
||||
Output endpoints of the controller.
|
||||
|
||||
required:
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
- port@0
|
||||
- port@1
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- ports
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
#include <dt-bindings/clock/sun6i-a31-ccu.h>
|
||||
#include <dt-bindings/reset/sun6i-a31-ccu.h>
|
||||
|
||||
drc0: drc@1e70000 {
|
||||
compatible = "allwinner,sun6i-a31-drc";
|
||||
reg = <0x01e70000 0x10000>;
|
||||
interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&ccu CLK_AHB1_DRC0>, <&ccu CLK_IEP_DRC0>,
|
||||
<&ccu CLK_DRAM_DRC0>;
|
||||
clock-names = "ahb", "mod",
|
||||
"ram";
|
||||
resets = <&ccu RST_AHB1_DRC0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
drc0_in: port@0 {
|
||||
reg = <0>;
|
||||
|
||||
drc0_in_be0: endpoint {
|
||||
remote-endpoint = <&be0_out_drc0>;
|
||||
};
|
||||
};
|
||||
|
||||
drc0_out: port@1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <1>;
|
||||
|
||||
drc0_out_tcon0: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&tcon0_in_drc0>;
|
||||
};
|
||||
|
||||
drc0_out_tcon1: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&tcon1_in_drc0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
...
|
|
@ -0,0 +1,118 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/allwinner,sun8i-a83t-de2-mixer.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Allwinner Display Engine 2.0 Mixer Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- Chen-Yu Tsai <wens@csie.org>
|
||||
- Maxime Ripard <mripard@kernel.org>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- allwinner,sun8i-a83t-de2-mixer-0
|
||||
- allwinner,sun8i-a83t-de2-mixer-1
|
||||
- allwinner,sun8i-h3-de2-mixer-0
|
||||
- allwinner,sun8i-r40-de2-mixer-0
|
||||
- allwinner,sun8i-r40-de2-mixer-1
|
||||
- allwinner,sun8i-v3s-de2-mixer
|
||||
- allwinner,sun50i-a64-de2-mixer-0
|
||||
- allwinner,sun50i-a64-de2-mixer-1
|
||||
- allwinner,sun50i-h6-de3-mixer-0
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: The mixer interface clock
|
||||
- description: The mixer module clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: bus
|
||||
- const: mod
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
ports:
|
||||
type: object
|
||||
description: |
|
||||
A ports node with endpoint definitions as defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt.
|
||||
|
||||
properties:
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
port@0:
|
||||
type: object
|
||||
description: |
|
||||
Input endpoints of the controller.
|
||||
|
||||
port@1:
|
||||
type: object
|
||||
description: |
|
||||
Output endpoints of the controller.
|
||||
|
||||
required:
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
- port@1
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- ports
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/sun8i-de2.h>
|
||||
#include <dt-bindings/reset/sun8i-de2.h>
|
||||
|
||||
mixer0: mixer@1100000 {
|
||||
compatible = "allwinner,sun8i-a83t-de2-mixer-0";
|
||||
reg = <0x01100000 0x100000>;
|
||||
clocks = <&display_clocks CLK_BUS_MIXER0>,
|
||||
<&display_clocks CLK_MIXER0>;
|
||||
clock-names = "bus",
|
||||
"mod";
|
||||
resets = <&display_clocks RST_MIXER0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mixer0_out: port@1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <1>;
|
||||
|
||||
mixer0_out_tcon0: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&tcon0_in_mixer0>;
|
||||
};
|
||||
|
||||
mixer0_out_tcon1: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&tcon1_in_mixer0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
|
@ -0,0 +1,273 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/allwinner,sun8i-a83t-dw-hdmi.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Allwinner A83t DWC HDMI TX Encoder Device Tree Bindings
|
||||
|
||||
description: |
|
||||
The HDMI transmitter is a Synopsys DesignWare HDMI 1.4 TX controller
|
||||
IP with Allwinner\'s own PHY IP. It supports audio and video outputs
|
||||
and CEC.
|
||||
|
||||
These DT bindings follow the Synopsys DWC HDMI TX bindings defined
|
||||
in Documentation/devicetree/bindings/display/bridge/dw_hdmi.txt with
|
||||
the following device-specific properties.
|
||||
|
||||
maintainers:
|
||||
- Chen-Yu Tsai <wens@csie.org>
|
||||
- Maxime Ripard <mripard@kernel.org>
|
||||
|
||||
properties:
|
||||
"#phy-cells":
|
||||
const: 0
|
||||
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: allwinner,sun8i-a83t-dw-hdmi
|
||||
- const: allwinner,sun50i-h6-dw-hdmi
|
||||
|
||||
- items:
|
||||
- enum:
|
||||
- allwinner,sun8i-h3-dw-hdmi
|
||||
- allwinner,sun8i-r40-dw-hdmi
|
||||
- allwinner,sun50i-a64-dw-hdmi
|
||||
- const: allwinner,sun8i-a83t-dw-hdmi
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
reg-io-width:
|
||||
const: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
minItems: 3
|
||||
maxItems: 6
|
||||
items:
|
||||
- description: Bus Clock
|
||||
- description: Register Clock
|
||||
- description: TMDS Clock
|
||||
- description: HDMI CEC Clock
|
||||
- description: HDCP Clock
|
||||
- description: HDCP Bus Clock
|
||||
|
||||
clock-names:
|
||||
minItems: 3
|
||||
maxItems: 6
|
||||
items:
|
||||
- const: iahb
|
||||
- const: isfr
|
||||
- const: tmds
|
||||
- const: cec
|
||||
- const: hdcp
|
||||
- const: hdcp-bus
|
||||
|
||||
resets:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
items:
|
||||
- description: HDMI Controller Reset
|
||||
- description: HDCP Reset
|
||||
|
||||
reset-names:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
items:
|
||||
- const: ctrl
|
||||
- const: hdcp
|
||||
|
||||
phys:
|
||||
maxItems: 1
|
||||
description:
|
||||
Phandle to the DWC HDMI PHY.
|
||||
|
||||
phy-names:
|
||||
const: phy
|
||||
|
||||
hvcc-supply:
|
||||
description:
|
||||
The VCC power supply of the controller
|
||||
|
||||
ports:
|
||||
type: object
|
||||
description: |
|
||||
A ports node with endpoint definitions as defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt.
|
||||
|
||||
properties:
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
port@0:
|
||||
type: object
|
||||
description: |
|
||||
Input endpoints of the controller. Usually the associated
|
||||
TCON.
|
||||
|
||||
port@1:
|
||||
type: object
|
||||
description: |
|
||||
Output endpoints of the controller. Usually an HDMI
|
||||
connector.
|
||||
|
||||
required:
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
- port@0
|
||||
- port@1
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-io-width
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- reset-names
|
||||
- phys
|
||||
- phy-names
|
||||
- ports
|
||||
|
||||
if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- allwinner,sun50i-h6-dw-hdmi
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 6
|
||||
|
||||
clock-names:
|
||||
minItems: 6
|
||||
|
||||
resets:
|
||||
minItems: 2
|
||||
|
||||
reset-names:
|
||||
minItems: 2
|
||||
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
/*
|
||||
* This comes from the clock/sun8i-a83t-ccu.h and
|
||||
* reset/sun8i-a83t-ccu.h headers, but we can't include them since
|
||||
* it would trigger a bunch of warnings for redefinitions of
|
||||
* symbols with the other example.
|
||||
*/
|
||||
#define CLK_BUS_HDMI 39
|
||||
#define CLK_HDMI 93
|
||||
#define CLK_HDMI_SLOW 94
|
||||
#define RST_BUS_HDMI1 26
|
||||
|
||||
hdmi@1ee0000 {
|
||||
compatible = "allwinner,sun8i-a83t-dw-hdmi";
|
||||
reg = <0x01ee0000 0x10000>;
|
||||
reg-io-width = <1>;
|
||||
interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&ccu CLK_BUS_HDMI>, <&ccu CLK_HDMI_SLOW>,
|
||||
<&ccu CLK_HDMI>;
|
||||
clock-names = "iahb", "isfr", "tmds";
|
||||
resets = <&ccu RST_BUS_HDMI1>;
|
||||
reset-names = "ctrl";
|
||||
phys = <&hdmi_phy>;
|
||||
phy-names = "phy";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&hdmi_pins>;
|
||||
status = "disabled";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
endpoint {
|
||||
remote-endpoint = <&tcon1_out_hdmi>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/* Cleanup after ourselves */
|
||||
#undef CLK_BUS_HDMI
|
||||
#undef CLK_HDMI
|
||||
#undef CLK_HDMI_SLOW
|
||||
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
/*
|
||||
* This comes from the clock/sun50i-h6-ccu.h and
|
||||
* reset/sun50i-h6-ccu.h headers, but we can't include them since
|
||||
* it would trigger a bunch of warnings for redefinitions of
|
||||
* symbols with the other example.
|
||||
*/
|
||||
#define CLK_BUS_HDMI 126
|
||||
#define CLK_BUS_HDCP 137
|
||||
#define CLK_HDMI 123
|
||||
#define CLK_HDMI_SLOW 124
|
||||
#define CLK_HDMI_CEC 125
|
||||
#define CLK_HDCP 136
|
||||
#define RST_BUS_HDMI_SUB 57
|
||||
#define RST_BUS_HDCP 62
|
||||
|
||||
hdmi@6000000 {
|
||||
compatible = "allwinner,sun50i-h6-dw-hdmi";
|
||||
reg = <0x06000000 0x10000>;
|
||||
reg-io-width = <1>;
|
||||
interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&ccu CLK_BUS_HDMI>, <&ccu CLK_HDMI_SLOW>,
|
||||
<&ccu CLK_HDMI>, <&ccu CLK_HDMI_CEC>,
|
||||
<&ccu CLK_HDCP>, <&ccu CLK_BUS_HDCP>;
|
||||
clock-names = "iahb", "isfr", "tmds", "cec", "hdcp",
|
||||
"hdcp-bus";
|
||||
resets = <&ccu RST_BUS_HDMI_SUB>, <&ccu RST_BUS_HDCP>;
|
||||
reset-names = "ctrl", "hdcp";
|
||||
phys = <&hdmi_phy>;
|
||||
phy-names = "phy";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&hdmi_pins>;
|
||||
status = "disabled";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
endpoint {
|
||||
remote-endpoint = <&tcon_top_hdmi_out_hdmi>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
|
@ -0,0 +1,117 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/allwinner,sun8i-a83t-hdmi-phy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Allwinner A83t HDMI PHY Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- Chen-Yu Tsai <wens@csie.org>
|
||||
- Maxime Ripard <mripard@kernel.org>
|
||||
|
||||
properties:
|
||||
"#phy-cells":
|
||||
const: 0
|
||||
|
||||
compatible:
|
||||
enum:
|
||||
- allwinner,sun8i-a83t-hdmi-phy
|
||||
- allwinner,sun8i-h3-hdmi-phy
|
||||
- allwinner,sun8i-r40-hdmi-phy
|
||||
- allwinner,sun50i-a64-hdmi-phy
|
||||
- allwinner,sun50i-h6-hdmi-phy
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
minItems: 2
|
||||
maxItems: 4
|
||||
items:
|
||||
- description: Bus Clock
|
||||
- description: Module Clock
|
||||
- description: Parent of the PHY clock
|
||||
- description: Second possible parent of the PHY clock
|
||||
|
||||
clock-names:
|
||||
minItems: 2
|
||||
maxItems: 4
|
||||
items:
|
||||
- const: bus
|
||||
- const: mod
|
||||
- const: pll-0
|
||||
- const: pll-1
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
reset-names:
|
||||
const: phy
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- reset-names
|
||||
|
||||
if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- allwinner,sun8i-r40-hdmi-phy
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 4
|
||||
|
||||
clock-names:
|
||||
minItems: 4
|
||||
|
||||
else:
|
||||
if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- allwinner,sun8i-h3-hdmi-phy
|
||||
- allwinner,sun50i-a64-hdmi-phy
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 3
|
||||
|
||||
clock-names:
|
||||
minItems: 3
|
||||
|
||||
else:
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 2
|
||||
|
||||
clock-names:
|
||||
maxItems: 2
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/sun8i-a83t-ccu.h>
|
||||
#include <dt-bindings/reset/sun8i-a83t-ccu.h>
|
||||
|
||||
hdmi_phy: hdmi-phy@1ef0000 {
|
||||
compatible = "allwinner,sun8i-a83t-hdmi-phy";
|
||||
reg = <0x01ef0000 0x10000>;
|
||||
clocks = <&ccu CLK_BUS_HDMI>, <&ccu CLK_HDMI_SLOW>;
|
||||
clock-names = "bus", "mod";
|
||||
resets = <&ccu RST_BUS_HDMI0>;
|
||||
reset-names = "phy";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
...
|
|
@ -0,0 +1,382 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/allwinner,sun8i-r40-tcon-top.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Allwinner R40 TCON TOP Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- Chen-Yu Tsai <wens@csie.org>
|
||||
- Maxime Ripard <mripard@kernel.org>
|
||||
|
||||
description: |
|
||||
TCON TOPs main purpose is to configure whole display pipeline. It
|
||||
determines relationships between mixers and TCONs, selects source
|
||||
TCON for HDMI, muxes LCD and TV encoder GPIO output, selects TV
|
||||
encoder clock source and contains additional TV TCON and DSI gates.
|
||||
|
||||
It allows display pipeline to be configured in very different ways:
|
||||
|
||||
/ LCD0/LVDS0
|
||||
/ [0] TCON-LCD0
|
||||
| \ MIPI DSI
|
||||
mixer0 |
|
||||
\ / [1] TCON-LCD1 - LCD1/LVDS1
|
||||
TCON-TOP
|
||||
/ \ [2] TCON-TV0 [0] - TVE0/RGB
|
||||
mixer1 | \
|
||||
| TCON-TOP - HDMI
|
||||
| /
|
||||
\ [3] TCON-TV1 [1] - TVE1/RGB
|
||||
|
||||
Note that both TCON TOP references same physical unit. Both mixers
|
||||
can be connected to any TCON. Not all TCON TOP variants support all
|
||||
features.
|
||||
|
||||
properties:
|
||||
"#clock-cells":
|
||||
const: 1
|
||||
|
||||
compatible:
|
||||
enum:
|
||||
- allwinner,sun8i-r40-tcon-top
|
||||
- allwinner,sun50i-h6-tcon-top
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
minItems: 2
|
||||
maxItems: 6
|
||||
items:
|
||||
- description: The TCON TOP interface clock
|
||||
- description: The TCON TOP TV0 clock
|
||||
- description: The TCON TOP TVE0 clock
|
||||
- description: The TCON TOP TV1 clock
|
||||
- description: The TCON TOP TVE1 clock
|
||||
- description: The TCON TOP MIPI DSI clock
|
||||
|
||||
clock-names:
|
||||
minItems: 2
|
||||
maxItems: 6
|
||||
items:
|
||||
- const: bus
|
||||
- const: tcon-tv0
|
||||
- const: tve0
|
||||
- const: tcon-tv1
|
||||
- const: tve1
|
||||
- const: dsi
|
||||
|
||||
clock-output-names:
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
description: >
|
||||
The first item is the name of the clock created for the TV0
|
||||
channel, the second item is the name of the TCON TV1 channel
|
||||
clock and the third one is the name of the DSI channel clock.
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
ports:
|
||||
type: object
|
||||
description: |
|
||||
A ports node with endpoint definitions as defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt.
|
||||
All ports should have only one endpoint connected to
|
||||
remote endpoint.
|
||||
|
||||
properties:
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
port@0:
|
||||
type: object
|
||||
description: |
|
||||
Input endpoint for Mixer 0 mux.
|
||||
|
||||
port@1:
|
||||
type: object
|
||||
description: |
|
||||
Output endpoint for Mixer 0 mux
|
||||
|
||||
properties:
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
reg: true
|
||||
|
||||
patternProperties:
|
||||
"^endpoint@[0-9]$":
|
||||
type: object
|
||||
|
||||
properties:
|
||||
reg:
|
||||
description: |
|
||||
ID of the target TCON
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
required:
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
port@2:
|
||||
type: object
|
||||
description: |
|
||||
Input endpoint for Mixer 1 mux.
|
||||
|
||||
port@3:
|
||||
type: object
|
||||
description: |
|
||||
Output endpoint for Mixer 1 mux
|
||||
|
||||
properties:
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
reg: true
|
||||
|
||||
patternProperties:
|
||||
"^endpoint@[0-9]$":
|
||||
type: object
|
||||
|
||||
properties:
|
||||
reg:
|
||||
description: |
|
||||
ID of the target TCON
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
required:
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
port@4:
|
||||
type: object
|
||||
description: |
|
||||
Input endpoint for HDMI mux.
|
||||
|
||||
properties:
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
reg: true
|
||||
|
||||
patternProperties:
|
||||
"^endpoint@[0-9]$":
|
||||
type: object
|
||||
|
||||
properties:
|
||||
reg:
|
||||
description: |
|
||||
ID of the target TCON
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
required:
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
port@5:
|
||||
type: object
|
||||
description: |
|
||||
Output endpoint for HDMI mux
|
||||
|
||||
required:
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
- port@0
|
||||
- port@1
|
||||
- port@4
|
||||
- port@5
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- "#clock-cells"
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- clock-output-names
|
||||
- resets
|
||||
- ports
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: allwinner,sun50i-h6-tcon-top
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 2
|
||||
|
||||
clock-output-names:
|
||||
maxItems: 1
|
||||
|
||||
else:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 6
|
||||
|
||||
clock-output-names:
|
||||
minItems: 3
|
||||
|
||||
ports:
|
||||
required:
|
||||
- port@2
|
||||
- port@3
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
#include <dt-bindings/clock/sun8i-r40-ccu.h>
|
||||
#include <dt-bindings/reset/sun8i-r40-ccu.h>
|
||||
|
||||
tcon_top: tcon-top@1c70000 {
|
||||
compatible = "allwinner,sun8i-r40-tcon-top";
|
||||
reg = <0x01c70000 0x1000>;
|
||||
clocks = <&ccu CLK_BUS_TCON_TOP>,
|
||||
<&ccu CLK_TCON_TV0>,
|
||||
<&ccu CLK_TVE0>,
|
||||
<&ccu CLK_TCON_TV1>,
|
||||
<&ccu CLK_TVE1>,
|
||||
<&ccu CLK_DSI_DPHY>;
|
||||
clock-names = "bus",
|
||||
"tcon-tv0",
|
||||
"tve0",
|
||||
"tcon-tv1",
|
||||
"tve1",
|
||||
"dsi";
|
||||
clock-output-names = "tcon-top-tv0",
|
||||
"tcon-top-tv1",
|
||||
"tcon-top-dsi";
|
||||
resets = <&ccu RST_BUS_TCON_TOP>;
|
||||
#clock-cells = <1>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
tcon_top_mixer0_in: port@0 {
|
||||
reg = <0>;
|
||||
|
||||
tcon_top_mixer0_in_mixer0: endpoint {
|
||||
remote-endpoint = <&mixer0_out_tcon_top>;
|
||||
};
|
||||
};
|
||||
|
||||
tcon_top_mixer0_out: port@1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <1>;
|
||||
|
||||
tcon_top_mixer0_out_tcon_lcd0: endpoint@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
|
||||
tcon_top_mixer0_out_tcon_lcd1: endpoint@1 {
|
||||
reg = <1>;
|
||||
};
|
||||
|
||||
tcon_top_mixer0_out_tcon_tv0: endpoint@2 {
|
||||
reg = <2>;
|
||||
remote-endpoint = <&tcon_tv0_in_tcon_top_mixer0>;
|
||||
};
|
||||
|
||||
tcon_top_mixer0_out_tcon_tv1: endpoint@3 {
|
||||
reg = <3>;
|
||||
remote-endpoint = <&tcon_tv1_in_tcon_top_mixer0>;
|
||||
};
|
||||
};
|
||||
|
||||
tcon_top_mixer1_in: port@2 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <2>;
|
||||
|
||||
tcon_top_mixer1_in_mixer1: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&mixer1_out_tcon_top>;
|
||||
};
|
||||
};
|
||||
|
||||
tcon_top_mixer1_out: port@3 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <3>;
|
||||
|
||||
tcon_top_mixer1_out_tcon_lcd0: endpoint@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
|
||||
tcon_top_mixer1_out_tcon_lcd1: endpoint@1 {
|
||||
reg = <1>;
|
||||
};
|
||||
|
||||
tcon_top_mixer1_out_tcon_tv0: endpoint@2 {
|
||||
reg = <2>;
|
||||
remote-endpoint = <&tcon_tv0_in_tcon_top_mixer1>;
|
||||
};
|
||||
|
||||
tcon_top_mixer1_out_tcon_tv1: endpoint@3 {
|
||||
reg = <3>;
|
||||
remote-endpoint = <&tcon_tv1_in_tcon_top_mixer1>;
|
||||
};
|
||||
};
|
||||
|
||||
tcon_top_hdmi_in: port@4 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <4>;
|
||||
|
||||
tcon_top_hdmi_in_tcon_tv0: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&tcon_tv0_out_tcon_top>;
|
||||
};
|
||||
|
||||
tcon_top_hdmi_in_tcon_tv1: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&tcon_tv1_out_tcon_top>;
|
||||
};
|
||||
};
|
||||
|
||||
tcon_top_hdmi_out: port@5 {
|
||||
reg = <5>;
|
||||
|
||||
tcon_top_hdmi_out_hdmi: endpoint {
|
||||
remote-endpoint = <&hdmi_in_tcon_top>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
|
@ -0,0 +1,133 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/allwinner,sun9i-a80-deu.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Allwinner A80 Detail Enhancement Unit Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- Chen-Yu Tsai <wens@csie.org>
|
||||
- Maxime Ripard <mripard@kernel.org>
|
||||
|
||||
description: |
|
||||
The DEU (Detail Enhancement Unit), found in the Allwinner A80 SoC,
|
||||
can sharpen the display content in both luma and chroma channels.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: allwinner,sun9i-a80-deu
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: The DEU interface clock
|
||||
- description: The DEU module clock
|
||||
- description: The DEU DRAM clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: ahb
|
||||
- const: mod
|
||||
- const: ram
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
ports:
|
||||
type: object
|
||||
description: |
|
||||
A ports node with endpoint definitions as defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt.
|
||||
|
||||
properties:
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
port@0:
|
||||
type: object
|
||||
description: |
|
||||
Input endpoints of the controller.
|
||||
|
||||
port@1:
|
||||
type: object
|
||||
description: |
|
||||
Output endpoints of the controller.
|
||||
|
||||
required:
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
- port@0
|
||||
- port@1
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- ports
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
#include <dt-bindings/clock/sun9i-a80-de.h>
|
||||
#include <dt-bindings/reset/sun9i-a80-de.h>
|
||||
|
||||
deu0: deu@3300000 {
|
||||
compatible = "allwinner,sun9i-a80-deu";
|
||||
reg = <0x03300000 0x40000>;
|
||||
interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&de_clocks CLK_BUS_DEU0>,
|
||||
<&de_clocks CLK_IEP_DEU0>,
|
||||
<&de_clocks CLK_DRAM_DEU0>;
|
||||
clock-names = "ahb",
|
||||
"mod",
|
||||
"ram";
|
||||
resets = <&de_clocks RST_DEU0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
deu0_in: port@0 {
|
||||
reg = <0>;
|
||||
|
||||
deu0_in_fe0: endpoint {
|
||||
remote-endpoint = <&fe0_out_deu0>;
|
||||
};
|
||||
};
|
||||
|
||||
deu0_out: port@1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <1>;
|
||||
|
||||
deu0_out_be0: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&be0_in_deu0>;
|
||||
};
|
||||
|
||||
deu0_out_be1: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&be1_in_deu0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
|
@ -1,42 +0,0 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/panel/ampire,am-480272h3tmqw-t01h.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Ampire AM-480272H3TMQW-T01H 4.3" WQVGA TFT LCD panel
|
||||
|
||||
maintainers:
|
||||
- Yannick Fertre <yannick.fertre@st.com>
|
||||
- Thierry Reding <treding@nvidia.com>
|
||||
|
||||
allOf:
|
||||
- $ref: panel-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ampire,am-480272h3tmqw-t01h
|
||||
|
||||
power-supply: true
|
||||
enable-gpios: true
|
||||
backlight: true
|
||||
port: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
panel_rgb: panel {
|
||||
compatible = "ampire,am-480272h3tmqw-t01h";
|
||||
enable-gpios = <&gpioa 8 1>;
|
||||
port {
|
||||
panel_in_rgb: endpoint {
|
||||
remote-endpoint = <&controller_out_rgb>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
|
@ -1,7 +0,0 @@
|
|||
Ampire AM-800480R3TMQW-A1H 7.0" WVGA TFT LCD panel
|
||||
|
||||
Required properties:
|
||||
- compatible: should be "ampire,am800480r3tmqwa1h"
|
||||
|
||||
This binding is compatible with the simple-panel binding, which is specified
|
||||
in simple-panel.txt in this directory.
|
|
@ -1,12 +0,0 @@
|
|||
GiantPlus 3.0" (320x240 pixels) 24-bit TFT LCD panel
|
||||
|
||||
Required properties:
|
||||
- compatible: should be "giantplus,gpm940b0"
|
||||
- power-supply: as specified in the base binding
|
||||
|
||||
Optional properties:
|
||||
- backlight: as specified in the base binding
|
||||
- enable-gpios: as specified in the base binding
|
||||
|
||||
This binding is compatible with the simple-panel binding, which is specified
|
||||
in simple-panel.txt in this directory.
|
|
@ -0,0 +1,69 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/panel/panel-simple.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Simple panels with one power supply
|
||||
|
||||
maintainers:
|
||||
- Thierry Reding <thierry.reding@gmail.com>
|
||||
- Sam Ravnborg <sam@ravnborg.org>
|
||||
|
||||
description: |
|
||||
This binding file is a collection of the simple (dumb) panels that
|
||||
requires only a single power-supply.
|
||||
There are optionally a backlight and an enable GPIO.
|
||||
The panel may use an OF graph binding for the association to the display,
|
||||
or it may be a direct child node of the display.
|
||||
|
||||
If the panel is more advanced a dedicated binding file is required.
|
||||
|
||||
allOf:
|
||||
- $ref: panel-common.yaml#
|
||||
|
||||
properties:
|
||||
|
||||
compatible:
|
||||
enum:
|
||||
# compatible must be listed in alphabetical order, ordered by compatible.
|
||||
# The description in the comment is mandatory for each compatible.
|
||||
|
||||
# Ampire AM-480272H3TMQW-T01H 4.3" WQVGA TFT LCD panel
|
||||
- ampire,am-480272h3tmqw-t01h
|
||||
# Ampire AM-800480R3TMQW-A1H 7.0" WVGA TFT LCD panel
|
||||
- ampire,am800480r3tmqwa1h
|
||||
# AUO B116XAK01 eDP TFT LCD panel
|
||||
- auo,b116xa01
|
||||
# BOE NV140FHM-N49 14.0" FHD a-Si FT panel
|
||||
- boe,nv140fhmn49
|
||||
# GiantPlus GPM940B0 3.0" QVGA TFT LCD panel
|
||||
- giantplus,gpm940b0
|
||||
# Satoz SAT050AT40H12R2 5.0" WVGA TFT LCD panel
|
||||
- satoz,sat050at40h12r2
|
||||
# Sharp LS020B1DD01D 2.0" HQVGA TFT LCD panel
|
||||
- sharp,ls020b1dd01d
|
||||
|
||||
backlight: true
|
||||
enable-gpios: true
|
||||
port: true
|
||||
power-supply: true
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- power-supply
|
||||
|
||||
examples:
|
||||
- |
|
||||
panel_rgb: panel-rgb {
|
||||
compatible = "ampire,am-480272h3tmqw-t01h";
|
||||
power-supply = <&vcc_lcd_reg>;
|
||||
|
||||
port {
|
||||
panel_in_rgb: endpoint {
|
||||
remote-endpoint = <<dc_out_rgb>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -1,12 +0,0 @@
|
|||
Sharp 2.0" (240x160 pixels) 16-bit TFT LCD panel
|
||||
|
||||
Required properties:
|
||||
- compatible: should be "sharp,ls020b1dd01d"
|
||||
- power-supply: as specified in the base binding
|
||||
|
||||
Optional properties:
|
||||
- backlight: as specified in the base binding
|
||||
- enable-gpios: as specified in the base binding
|
||||
|
||||
This binding is compatible with the simple-panel binding, which is specified
|
||||
in simple-panel.txt in this directory.
|
|
@ -1,637 +0,0 @@
|
|||
Allwinner A10 Display Pipeline
|
||||
==============================
|
||||
|
||||
The Allwinner A10 Display pipeline is composed of several components
|
||||
that are going to be documented below:
|
||||
|
||||
For all connections between components up to the TCONs in the display
|
||||
pipeline, when there are multiple components of the same type at the
|
||||
same depth, the local endpoint ID must be the same as the remote
|
||||
component's index. For example, if the remote endpoint is Frontend 1,
|
||||
then the local endpoint ID must be 1.
|
||||
|
||||
Frontend 0 [0] ------- [0] Backend 0 [0] ------- [0] TCON 0
|
||||
[1] -- -- [1] [1] -- -- [1]
|
||||
\ / \ /
|
||||
X X
|
||||
/ \ / \
|
||||
[0] -- -- [0] [0] -- -- [0]
|
||||
Frontend 1 [1] ------- [1] Backend 1 [1] ------- [1] TCON 1
|
||||
|
||||
For a two pipeline system such as the one depicted above, the lines
|
||||
represent the connections between the components, while the numbers
|
||||
within the square brackets corresponds to the ID of the local endpoint.
|
||||
|
||||
The same rule also applies to DE 2.0 mixer-TCON connections:
|
||||
|
||||
Mixer 0 [0] ----------- [0] TCON 0
|
||||
[1] ---- ---- [1]
|
||||
\ /
|
||||
X
|
||||
/ \
|
||||
[0] ---- ---- [0]
|
||||
Mixer 1 [1] ----------- [1] TCON 1
|
||||
|
||||
HDMI Encoder
|
||||
------------
|
||||
|
||||
The HDMI Encoder supports the HDMI video and audio outputs, and does
|
||||
CEC. It is one end of the pipeline.
|
||||
|
||||
Required properties:
|
||||
- compatible: value must be one of:
|
||||
* allwinner,sun4i-a10-hdmi
|
||||
* allwinner,sun5i-a10s-hdmi
|
||||
* allwinner,sun6i-a31-hdmi
|
||||
- reg: base address and size of memory-mapped region
|
||||
- interrupts: interrupt associated to this IP
|
||||
- clocks: phandles to the clocks feeding the HDMI encoder
|
||||
* ahb: the HDMI interface clock
|
||||
* mod: the HDMI module clock
|
||||
* ddc: the HDMI ddc clock (A31 only)
|
||||
* pll-0: the first video PLL
|
||||
* pll-1: the second video PLL
|
||||
- clock-names: the clock names mentioned above
|
||||
- resets: phandle to the reset control for the HDMI encoder (A31 only)
|
||||
- dmas: phandles to the DMA channels used by the HDMI encoder
|
||||
* ddc-tx: The channel for DDC transmission
|
||||
* ddc-rx: The channel for DDC reception
|
||||
* audio-tx: The channel used for audio transmission
|
||||
- dma-names: the channel names mentioned above
|
||||
|
||||
- ports: A ports node with endpoint definitions as defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt. The
|
||||
first port should be the input endpoint. The second should be the
|
||||
output, usually to an HDMI connector.
|
||||
|
||||
DWC HDMI TX Encoder
|
||||
-------------------
|
||||
|
||||
The HDMI transmitter is a Synopsys DesignWare HDMI 1.4 TX controller IP
|
||||
with Allwinner's own PHY IP. It supports audio and video outputs and CEC.
|
||||
|
||||
These DT bindings follow the Synopsys DWC HDMI TX bindings defined in
|
||||
Documentation/devicetree/bindings/display/bridge/dw_hdmi.txt with the
|
||||
following device-specific properties.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible: value must be one of:
|
||||
* "allwinner,sun8i-a83t-dw-hdmi"
|
||||
* "allwinner,sun50i-a64-dw-hdmi", "allwinner,sun8i-a83t-dw-hdmi"
|
||||
* "allwinner,sun50i-h6-dw-hdmi"
|
||||
- reg: base address and size of memory-mapped region
|
||||
- reg-io-width: See dw_hdmi.txt. Shall be 1.
|
||||
- interrupts: HDMI interrupt number
|
||||
- clocks: phandles to the clocks feeding the HDMI encoder
|
||||
* iahb: the HDMI bus clock
|
||||
* isfr: the HDMI register clock
|
||||
* tmds: TMDS clock
|
||||
* cec: HDMI CEC clock (H6 only)
|
||||
* hdcp: HDCP clock (H6 only)
|
||||
* hdcp-bus: HDCP bus clock (H6 only)
|
||||
- clock-names: the clock names mentioned above
|
||||
- resets:
|
||||
* ctrl: HDMI controller reset
|
||||
* hdcp: HDCP reset (H6 only)
|
||||
- reset-names: reset names mentioned above
|
||||
- phys: phandle to the DWC HDMI PHY
|
||||
- phy-names: must be "phy"
|
||||
|
||||
- ports: A ports node with endpoint definitions as defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt. The
|
||||
first port should be the input endpoint. The second should be the
|
||||
output, usually to an HDMI connector.
|
||||
|
||||
Optional properties:
|
||||
- hvcc-supply: the VCC power supply of the controller
|
||||
|
||||
DWC HDMI PHY
|
||||
------------
|
||||
|
||||
Required properties:
|
||||
- compatible: value must be one of:
|
||||
* allwinner,sun8i-a83t-hdmi-phy
|
||||
* allwinner,sun8i-h3-hdmi-phy
|
||||
* allwinner,sun8i-r40-hdmi-phy
|
||||
* allwinner,sun50i-a64-hdmi-phy
|
||||
* allwinner,sun50i-h6-hdmi-phy
|
||||
- reg: base address and size of memory-mapped region
|
||||
- clocks: phandles to the clocks feeding the HDMI PHY
|
||||
* bus: the HDMI PHY interface clock
|
||||
* mod: the HDMI PHY module clock
|
||||
- clock-names: the clock names mentioned above
|
||||
- resets: phandle to the reset controller driving the PHY
|
||||
- reset-names: must be "phy"
|
||||
|
||||
H3, A64 and R40 HDMI PHY require additional clocks:
|
||||
- pll-0: parent of phy clock
|
||||
- pll-1: second possible phy clock parent (A64/R40 only)
|
||||
|
||||
TV Encoder
|
||||
----------
|
||||
|
||||
The TV Encoder supports the composite and VGA output. It is one end of
|
||||
the pipeline.
|
||||
|
||||
Required properties:
|
||||
- compatible: value should be "allwinner,sun4i-a10-tv-encoder".
|
||||
- reg: base address and size of memory-mapped region
|
||||
- clocks: the clocks driving the TV encoder
|
||||
- resets: phandle to the reset controller driving the encoder
|
||||
|
||||
- ports: A ports node with endpoint definitions as defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt. The
|
||||
first port should be the input endpoint.
|
||||
|
||||
TCON
|
||||
----
|
||||
|
||||
The TCON acts as a timing controller for RGB, LVDS and TV interfaces.
|
||||
|
||||
Required properties:
|
||||
- compatible: value must be either:
|
||||
* allwinner,sun4i-a10-tcon
|
||||
* allwinner,sun5i-a13-tcon
|
||||
* allwinner,sun6i-a31-tcon
|
||||
* allwinner,sun6i-a31s-tcon
|
||||
* allwinner,sun7i-a20-tcon
|
||||
* allwinner,sun8i-a23-tcon
|
||||
* allwinner,sun8i-a33-tcon
|
||||
* allwinner,sun8i-a83t-tcon-lcd
|
||||
* allwinner,sun8i-a83t-tcon-tv
|
||||
* allwinner,sun8i-r40-tcon-tv
|
||||
* allwinner,sun8i-v3s-tcon
|
||||
* allwinner,sun9i-a80-tcon-lcd
|
||||
* allwinner,sun9i-a80-tcon-tv
|
||||
* "allwinner,sun50i-a64-tcon-lcd", "allwinner,sun8i-a83t-tcon-lcd"
|
||||
* "allwinner,sun50i-a64-tcon-tv", "allwinner,sun8i-a83t-tcon-tv"
|
||||
* allwinner,sun50i-h6-tcon-tv, allwinner,sun8i-r40-tcon-tv
|
||||
- reg: base address and size of memory-mapped region
|
||||
- interrupts: interrupt associated to this IP
|
||||
- clocks: phandles to the clocks feeding the TCON.
|
||||
- 'ahb': the interface clocks
|
||||
- 'tcon-ch0': The clock driving the TCON channel 0, if supported
|
||||
- resets: phandles to the reset controllers driving the encoder
|
||||
- "lcd": the reset line for the TCON
|
||||
- "edp": the reset line for the eDP block (A80 only)
|
||||
|
||||
- clock-names: the clock names mentioned above
|
||||
- reset-names: the reset names mentioned above
|
||||
- clock-output-names: Name of the pixel clock created, if TCON supports
|
||||
channel 0.
|
||||
|
||||
- ports: A ports node with endpoint definitions as defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt. The
|
||||
first port should be the input endpoint, the second one the output
|
||||
|
||||
The output may have multiple endpoints. TCON can have 1 or 2 channels,
|
||||
usually with the first channel being used for the panels interfaces
|
||||
(RGB, LVDS, etc.), and the second being used for the outputs that
|
||||
require another controller (TV Encoder, HDMI, etc.). The endpoints
|
||||
will take an extra property, allwinner,tcon-channel, to specify the
|
||||
channel the endpoint is associated to. If that property is not
|
||||
present, the endpoint number will be used as the channel number.
|
||||
|
||||
For TCONs with channel 0, there is one more clock required:
|
||||
- 'tcon-ch0': The clock driving the TCON channel 0
|
||||
For TCONs with channel 1, there is one more clock required:
|
||||
- 'tcon-ch1': The clock driving the TCON channel 1
|
||||
|
||||
When TCON support LVDS (all TCONs except TV TCONs on A83T, R40 and those found
|
||||
in A13, H3, H5 and V3s SoCs), you need one more reset line:
|
||||
- 'lvds': The reset line driving the LVDS logic
|
||||
|
||||
And on the A23, A31, A31s and A33, you need one more clock line:
|
||||
- 'lvds-alt': An alternative clock source, separate from the TCON channel 0
|
||||
clock, that can be used to drive the LVDS clock
|
||||
|
||||
TCON TOP
|
||||
--------
|
||||
|
||||
TCON TOPs main purpose is to configure whole display pipeline. It determines
|
||||
relationships between mixers and TCONs, selects source TCON for HDMI, muxes
|
||||
LCD and TV encoder GPIO output, selects TV encoder clock source and contains
|
||||
additional TV TCON and DSI gates.
|
||||
|
||||
It allows display pipeline to be configured in very different ways:
|
||||
|
||||
/ LCD0/LVDS0
|
||||
/ [0] TCON-LCD0
|
||||
| \ MIPI DSI
|
||||
mixer0 |
|
||||
\ / [1] TCON-LCD1 - LCD1/LVDS1
|
||||
TCON-TOP
|
||||
/ \ [2] TCON-TV0 [0] - TVE0/RGB
|
||||
mixer1 | \
|
||||
| TCON-TOP - HDMI
|
||||
| /
|
||||
\ [3] TCON-TV1 [1] - TVE1/RGB
|
||||
|
||||
Note that both TCON TOP references same physical unit. Both mixers can be
|
||||
connected to any TCON. Not all TCON TOP variants support all features.
|
||||
|
||||
Required properties:
|
||||
- compatible: value must be one of:
|
||||
* allwinner,sun8i-r40-tcon-top
|
||||
* allwinner,sun50i-h6-tcon-top
|
||||
- reg: base address and size of the memory-mapped region.
|
||||
- clocks: phandle to the clocks feeding the TCON TOP
|
||||
* bus: TCON TOP interface clock
|
||||
* tcon-tv0: TCON TV0 clock
|
||||
* tve0: TVE0 clock (R40 only)
|
||||
* tcon-tv1: TCON TV1 clock (R40 only)
|
||||
* tve1: TVE0 clock (R40 only)
|
||||
* dsi: MIPI DSI clock (R40 only)
|
||||
- clock-names: clock name mentioned above
|
||||
- resets: phandle to the reset line driving the TCON TOP
|
||||
- #clock-cells : must contain 1
|
||||
- clock-output-names: Names of clocks created for TCON TV0 channel clock,
|
||||
TCON TV1 channel clock (R40 only) and DSI channel clock (R40 only), in
|
||||
that order.
|
||||
|
||||
- ports: A ports node with endpoint definitions as defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt. 6 ports should
|
||||
be defined:
|
||||
* port 0 is input for mixer0 mux
|
||||
* port 1 is output for mixer0 mux
|
||||
* port 2 is input for mixer1 mux
|
||||
* port 3 is output for mixer1 mux
|
||||
* port 4 is input for HDMI mux
|
||||
* port 5 is output for HDMI mux
|
||||
All output endpoints for mixer muxes and input endpoints for HDMI mux should
|
||||
have reg property with the id of the target TCON, as shown in above graph
|
||||
(0-3 for mixer muxes and 0-1 for HDMI mux). All ports should have only one
|
||||
endpoint connected to remote endpoint.
|
||||
|
||||
DRC
|
||||
---
|
||||
|
||||
The DRC (Dynamic Range Controller), found in the latest Allwinner SoCs
|
||||
(A31, A23, A33, A80), allows to dynamically adjust pixel
|
||||
brightness/contrast based on histogram measurements for LCD content
|
||||
adaptive backlight control.
|
||||
|
||||
|
||||
Required properties:
|
||||
- compatible: value must be one of:
|
||||
* allwinner,sun6i-a31-drc
|
||||
* allwinner,sun6i-a31s-drc
|
||||
* allwinner,sun8i-a23-drc
|
||||
* allwinner,sun8i-a33-drc
|
||||
* allwinner,sun9i-a80-drc
|
||||
- reg: base address and size of the memory-mapped region.
|
||||
- interrupts: interrupt associated to this IP
|
||||
- clocks: phandles to the clocks feeding the DRC
|
||||
* ahb: the DRC interface clock
|
||||
* mod: the DRC module clock
|
||||
* ram: the DRC DRAM clock
|
||||
- clock-names: the clock names mentioned above
|
||||
- resets: phandles to the reset line driving the DRC
|
||||
|
||||
- ports: A ports node with endpoint definitions as defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt. The
|
||||
first port should be the input endpoints, the second one the outputs
|
||||
|
||||
Display Engine Backend
|
||||
----------------------
|
||||
|
||||
The display engine backend exposes layers and sprites to the
|
||||
system.
|
||||
|
||||
Required properties:
|
||||
- compatible: value must be one of:
|
||||
* allwinner,sun4i-a10-display-backend
|
||||
* allwinner,sun5i-a13-display-backend
|
||||
* allwinner,sun6i-a31-display-backend
|
||||
* allwinner,sun7i-a20-display-backend
|
||||
* allwinner,sun8i-a23-display-backend
|
||||
* allwinner,sun8i-a33-display-backend
|
||||
* allwinner,sun9i-a80-display-backend
|
||||
- reg: base address and size of the memory-mapped region.
|
||||
- interrupts: interrupt associated to this IP
|
||||
- clocks: phandles to the clocks feeding the frontend and backend
|
||||
* ahb: the backend interface clock
|
||||
* mod: the backend module clock
|
||||
* ram: the backend DRAM clock
|
||||
- clock-names: the clock names mentioned above
|
||||
- resets: phandles to the reset controllers driving the backend
|
||||
|
||||
- ports: A ports node with endpoint definitions as defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt. The
|
||||
first port should be the input endpoints, the second one the output
|
||||
|
||||
On the A33, some additional properties are required:
|
||||
- reg needs to have an additional region corresponding to the SAT
|
||||
- reg-names need to be set, with "be" and "sat"
|
||||
- clocks and clock-names need to have a phandle to the SAT bus
|
||||
clocks, whose name will be "sat"
|
||||
- resets and reset-names need to have a phandle to the SAT bus
|
||||
resets, whose name will be "sat"
|
||||
|
||||
DEU
|
||||
---
|
||||
|
||||
The DEU (Detail Enhancement Unit), found in the Allwinner A80 SoC,
|
||||
can sharpen the display content in both luma and chroma channels.
|
||||
|
||||
Required properties:
|
||||
- compatible: value must be one of:
|
||||
* allwinner,sun9i-a80-deu
|
||||
- reg: base address and size of the memory-mapped region.
|
||||
- interrupts: interrupt associated to this IP
|
||||
- clocks: phandles to the clocks feeding the DEU
|
||||
* ahb: the DEU interface clock
|
||||
* mod: the DEU module clock
|
||||
* ram: the DEU DRAM clock
|
||||
- clock-names: the clock names mentioned above
|
||||
- resets: phandles to the reset line driving the DEU
|
||||
|
||||
- ports: A ports node with endpoint definitions as defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt. The
|
||||
first port should be the input endpoints, the second one the outputs
|
||||
|
||||
Display Engine Frontend
|
||||
-----------------------
|
||||
|
||||
The display engine frontend does formats conversion, scaling,
|
||||
deinterlacing and color space conversion.
|
||||
|
||||
Required properties:
|
||||
- compatible: value must be one of:
|
||||
* allwinner,sun4i-a10-display-frontend
|
||||
* allwinner,sun5i-a13-display-frontend
|
||||
* allwinner,sun6i-a31-display-frontend
|
||||
* allwinner,sun7i-a20-display-frontend
|
||||
* allwinner,sun8i-a23-display-frontend
|
||||
* allwinner,sun8i-a33-display-frontend
|
||||
* allwinner,sun9i-a80-display-frontend
|
||||
- reg: base address and size of the memory-mapped region.
|
||||
- interrupts: interrupt associated to this IP
|
||||
- clocks: phandles to the clocks feeding the frontend and backend
|
||||
* ahb: the backend interface clock
|
||||
* mod: the backend module clock
|
||||
* ram: the backend DRAM clock
|
||||
- clock-names: the clock names mentioned above
|
||||
- resets: phandles to the reset controllers driving the backend
|
||||
|
||||
- ports: A ports node with endpoint definitions as defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt. The
|
||||
first port should be the input endpoints, the second one the outputs
|
||||
|
||||
Display Engine 2.0 Mixer
|
||||
------------------------
|
||||
|
||||
The DE2 mixer have many functionalities, currently only layer blending is
|
||||
supported.
|
||||
|
||||
Required properties:
|
||||
- compatible: value must be one of:
|
||||
* allwinner,sun8i-a83t-de2-mixer-0
|
||||
* allwinner,sun8i-a83t-de2-mixer-1
|
||||
* allwinner,sun8i-h3-de2-mixer-0
|
||||
* allwinner,sun8i-r40-de2-mixer-0
|
||||
* allwinner,sun8i-r40-de2-mixer-1
|
||||
* allwinner,sun8i-v3s-de2-mixer
|
||||
* allwinner,sun50i-a64-de2-mixer-0
|
||||
* allwinner,sun50i-a64-de2-mixer-1
|
||||
* allwinner,sun50i-h6-de3-mixer-0
|
||||
- reg: base address and size of the memory-mapped region.
|
||||
- clocks: phandles to the clocks feeding the mixer
|
||||
* bus: the mixer interface clock
|
||||
* mod: the mixer module clock
|
||||
- clock-names: the clock names mentioned above
|
||||
- resets: phandles to the reset controllers driving the mixer
|
||||
|
||||
- ports: A ports node with endpoint definitions as defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt. The
|
||||
first port should be the input endpoints, the second one the output
|
||||
|
||||
|
||||
Display Engine Pipeline
|
||||
-----------------------
|
||||
|
||||
The display engine pipeline (and its entry point, since it can be
|
||||
either directly the backend or the frontend) is represented as an
|
||||
extra node.
|
||||
|
||||
Required properties:
|
||||
- compatible: value must be one of:
|
||||
* allwinner,sun4i-a10-display-engine
|
||||
* allwinner,sun5i-a10s-display-engine
|
||||
* allwinner,sun5i-a13-display-engine
|
||||
* allwinner,sun6i-a31-display-engine
|
||||
* allwinner,sun6i-a31s-display-engine
|
||||
* allwinner,sun7i-a20-display-engine
|
||||
* allwinner,sun8i-a23-display-engine
|
||||
* allwinner,sun8i-a33-display-engine
|
||||
* allwinner,sun8i-a83t-display-engine
|
||||
* allwinner,sun8i-h3-display-engine
|
||||
* allwinner,sun8i-r40-display-engine
|
||||
* allwinner,sun8i-v3s-display-engine
|
||||
* allwinner,sun9i-a80-display-engine
|
||||
* allwinner,sun50i-a64-display-engine
|
||||
* allwinner,sun50i-h6-display-engine
|
||||
|
||||
- allwinner,pipelines: list of phandle to the display engine
|
||||
frontends (DE 1.0) or mixers (DE 2.0/3.0) available.
|
||||
|
||||
Example:
|
||||
|
||||
panel: panel {
|
||||
compatible = "olimex,lcd-olinuxino-43-ts";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
panel_input: endpoint {
|
||||
remote-endpoint = <&tcon0_out_panel>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
connector {
|
||||
compatible = "hdmi-connector";
|
||||
type = "a";
|
||||
|
||||
port {
|
||||
hdmi_con_in: endpoint {
|
||||
remote-endpoint = <&hdmi_out_con>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
hdmi: hdmi@1c16000 {
|
||||
compatible = "allwinner,sun5i-a10s-hdmi";
|
||||
reg = <0x01c16000 0x1000>;
|
||||
interrupts = <58>;
|
||||
clocks = <&ccu CLK_AHB_HDMI>, <&ccu CLK_HDMI>,
|
||||
<&ccu CLK_PLL_VIDEO0_2X>,
|
||||
<&ccu CLK_PLL_VIDEO1_2X>;
|
||||
clock-names = "ahb", "mod", "pll-0", "pll-1";
|
||||
dmas = <&dma SUN4I_DMA_NORMAL 16>,
|
||||
<&dma SUN4I_DMA_NORMAL 16>,
|
||||
<&dma SUN4I_DMA_DEDICATED 24>;
|
||||
dma-names = "ddc-tx", "ddc-rx", "audio-tx";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0>;
|
||||
|
||||
hdmi_in_tcon0: endpoint {
|
||||
remote-endpoint = <&tcon0_out_hdmi>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <1>;
|
||||
|
||||
hdmi_out_con: endpoint {
|
||||
remote-endpoint = <&hdmi_con_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
tve0: tv-encoder@1c0a000 {
|
||||
compatible = "allwinner,sun4i-a10-tv-encoder";
|
||||
reg = <0x01c0a000 0x1000>;
|
||||
clocks = <&ahb_gates 34>;
|
||||
resets = <&tcon_ch0_clk 0>;
|
||||
|
||||
port {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
tve0_in_tcon0: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&tcon0_out_tve0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
tcon0: lcd-controller@1c0c000 {
|
||||
compatible = "allwinner,sun5i-a13-tcon";
|
||||
reg = <0x01c0c000 0x1000>;
|
||||
interrupts = <44>;
|
||||
resets = <&tcon_ch0_clk 1>;
|
||||
reset-names = "lcd";
|
||||
clocks = <&ahb_gates 36>,
|
||||
<&tcon_ch0_clk>,
|
||||
<&tcon_ch1_clk>;
|
||||
clock-names = "ahb",
|
||||
"tcon-ch0",
|
||||
"tcon-ch1";
|
||||
clock-output-names = "tcon-pixel-clock";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
tcon0_in: port@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0>;
|
||||
|
||||
tcon0_in_be0: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&be0_out_tcon0>;
|
||||
};
|
||||
};
|
||||
|
||||
tcon0_out: port@1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <1>;
|
||||
|
||||
tcon0_out_panel: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&panel_input>;
|
||||
};
|
||||
|
||||
tcon0_out_tve0: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&tve0_in_tcon0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
fe0: display-frontend@1e00000 {
|
||||
compatible = "allwinner,sun5i-a13-display-frontend";
|
||||
reg = <0x01e00000 0x20000>;
|
||||
interrupts = <47>;
|
||||
clocks = <&ahb_gates 46>, <&de_fe_clk>,
|
||||
<&dram_gates 25>;
|
||||
clock-names = "ahb", "mod",
|
||||
"ram";
|
||||
resets = <&de_fe_clk>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
fe0_out: port@1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <1>;
|
||||
|
||||
fe0_out_be0: endpoint {
|
||||
remote-endpoint = <&be0_in_fe0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
be0: display-backend@1e60000 {
|
||||
compatible = "allwinner,sun5i-a13-display-backend";
|
||||
reg = <0x01e60000 0x10000>;
|
||||
interrupts = <47>;
|
||||
clocks = <&ahb_gates 44>, <&de_be_clk>,
|
||||
<&dram_gates 26>;
|
||||
clock-names = "ahb", "mod",
|
||||
"ram";
|
||||
resets = <&de_be_clk>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
be0_in: port@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0>;
|
||||
|
||||
be0_in_fe0: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&fe0_out_be0>;
|
||||
};
|
||||
};
|
||||
|
||||
be0_out: port@1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <1>;
|
||||
|
||||
be0_out_tcon0: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&tcon0_in_be0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
display-engine {
|
||||
compatible = "allwinner,sun5i-a13-display-engine";
|
||||
allwinner,pipelines = <&fe0>;
|
||||
};
|
|
@ -825,6 +825,8 @@ patternProperties:
|
|||
description: Sancloud Ltd
|
||||
"^sandisk,.*":
|
||||
description: Sandisk Corporation
|
||||
"^satoz,.*":
|
||||
description: Satoz International Co., Ltd
|
||||
"^sbs,.*":
|
||||
description: Smart Battery System
|
||||
"^schindler,.*":
|
||||
|
|
|
@ -5357,6 +5357,12 @@ S: Maintained
|
|||
F: drivers/gpu/drm/tiny/st7735r.c
|
||||
F: Documentation/devicetree/bindings/display/sitronix,st7735r.txt
|
||||
|
||||
DRM DRIVER FOR SONY ACX424AKP PANELS
|
||||
M: Linus Walleij <linus.walleij@linaro.org>
|
||||
T: git git://anongit.freedesktop.org/drm/drm-misc
|
||||
S: Maintained
|
||||
F: drivers/gpu/drm/panel/panel-sony-acx424akp.c
|
||||
|
||||
DRM DRIVER FOR ST-ERICSSON MCDE
|
||||
M: Linus Walleij <linus.walleij@linaro.org>
|
||||
T: git git://anongit.freedesktop.org/drm/drm-misc
|
||||
|
|
|
@ -168,6 +168,7 @@ config DRM_LOAD_EDID_FIRMWARE
|
|||
|
||||
config DRM_DP_CEC
|
||||
bool "Enable DisplayPort CEC-Tunneling-over-AUX HDMI support"
|
||||
depends on DRM
|
||||
select CEC_CORE
|
||||
help
|
||||
Choose this option if you want to enable HDMI CEC support for
|
||||
|
|
|
@ -1289,21 +1289,19 @@ struct drm_crtc *analogix_dp_get_new_crtc(struct analogix_dp_device *dp,
|
|||
return conn_state->crtc;
|
||||
}
|
||||
|
||||
static void
|
||||
analogix_dp_bridge_atomic_pre_enable(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *old_bridge_state)
|
||||
static void analogix_dp_bridge_atomic_pre_enable(struct drm_bridge *bridge,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
struct drm_atomic_state *old_state = old_bridge_state->base.state;
|
||||
struct analogix_dp_device *dp = bridge->driver_private;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_crtc_state *old_crtc_state;
|
||||
int ret;
|
||||
|
||||
crtc = analogix_dp_get_new_crtc(dp, old_state);
|
||||
crtc = analogix_dp_get_new_crtc(dp, state);
|
||||
if (!crtc)
|
||||
return;
|
||||
|
||||
old_crtc_state = drm_atomic_get_old_crtc_state(old_state, crtc);
|
||||
old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
|
||||
/* Don't touch the panel if we're coming back from PSR */
|
||||
if (old_crtc_state && old_crtc_state->self_refresh_active)
|
||||
return;
|
||||
|
@ -1368,22 +1366,20 @@ static int analogix_dp_set_bridge(struct analogix_dp_device *dp)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
analogix_dp_bridge_atomic_enable(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *old_bridge_state)
|
||||
static void analogix_dp_bridge_atomic_enable(struct drm_bridge *bridge,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
struct drm_atomic_state *old_state = old_bridge_state->base.state;
|
||||
struct analogix_dp_device *dp = bridge->driver_private;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_crtc_state *old_crtc_state;
|
||||
int timeout_loop = 0;
|
||||
int ret;
|
||||
|
||||
crtc = analogix_dp_get_new_crtc(dp, old_state);
|
||||
crtc = analogix_dp_get_new_crtc(dp, state);
|
||||
if (!crtc)
|
||||
return;
|
||||
|
||||
old_crtc_state = drm_atomic_get_old_crtc_state(old_state, crtc);
|
||||
old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
|
||||
/* Not a full enable, just disable PSR and continue */
|
||||
if (old_crtc_state && old_crtc_state->self_refresh_active) {
|
||||
ret = analogix_dp_disable_psr(dp);
|
||||
|
@ -1444,20 +1440,18 @@ static void analogix_dp_bridge_disable(struct drm_bridge *bridge)
|
|||
dp->dpms_mode = DRM_MODE_DPMS_OFF;
|
||||
}
|
||||
|
||||
static void
|
||||
analogix_dp_bridge_atomic_disable(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *old_bridge_state)
|
||||
static void analogix_dp_bridge_atomic_disable(struct drm_bridge *bridge,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
struct drm_atomic_state *old_state = old_bridge_state->base.state;
|
||||
struct analogix_dp_device *dp = bridge->driver_private;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_crtc_state *new_crtc_state = NULL;
|
||||
|
||||
crtc = analogix_dp_get_new_crtc(dp, old_state);
|
||||
crtc = analogix_dp_get_new_crtc(dp, state);
|
||||
if (!crtc)
|
||||
goto out;
|
||||
|
||||
new_crtc_state = drm_atomic_get_new_crtc_state(old_state, crtc);
|
||||
new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
|
||||
if (!new_crtc_state)
|
||||
goto out;
|
||||
|
||||
|
@ -1469,21 +1463,20 @@ analogix_dp_bridge_atomic_disable(struct drm_bridge *bridge,
|
|||
analogix_dp_bridge_disable(bridge);
|
||||
}
|
||||
|
||||
static void
|
||||
analogix_dp_bridge_atomic_post_disable(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *old_bridge_state)
|
||||
static
|
||||
void analogix_dp_bridge_atomic_post_disable(struct drm_bridge *bridge,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
struct drm_atomic_state *old_state = old_bridge_state->base.state;
|
||||
struct analogix_dp_device *dp = bridge->driver_private;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_crtc_state *new_crtc_state;
|
||||
int ret;
|
||||
|
||||
crtc = analogix_dp_get_new_crtc(dp, old_state);
|
||||
crtc = analogix_dp_get_new_crtc(dp, state);
|
||||
if (!crtc)
|
||||
return;
|
||||
|
||||
new_crtc_state = drm_atomic_get_new_crtc_state(old_state, crtc);
|
||||
new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
|
||||
if (!new_crtc_state || !new_crtc_state->self_refresh_active)
|
||||
return;
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
|
||||
#include <drm/drm_atomic.h>
|
||||
#include <drm/drm_atomic_uapi.h>
|
||||
#include <drm/drm_bridge.h>
|
||||
#include <drm/drm_debugfs.h>
|
||||
#include <drm/drm_device.h>
|
||||
#include <drm/drm_drv.h>
|
||||
|
@ -1018,44 +1017,6 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
|
|||
connector->funcs->atomic_print_state(p, state);
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_atomic_add_encoder_bridges - add bridges attached to an encoder
|
||||
* @state: atomic state
|
||||
* @encoder: DRM encoder
|
||||
*
|
||||
* This function adds all bridges attached to @encoder. This is needed to add
|
||||
* bridge states to @state and make them available when
|
||||
* &bridge_funcs.atomic_{check,pre_enable,enable,disable_post_disable}() are
|
||||
* called
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK
|
||||
* then the w/w mutex code has detected a deadlock and the entire atomic
|
||||
* sequence must be restarted. All other errors are fatal.
|
||||
*/
|
||||
int
|
||||
drm_atomic_add_encoder_bridges(struct drm_atomic_state *state,
|
||||
struct drm_encoder *encoder)
|
||||
{
|
||||
struct drm_bridge_state *bridge_state;
|
||||
struct drm_bridge *bridge;
|
||||
|
||||
if (!encoder)
|
||||
return 0;
|
||||
|
||||
DRM_DEBUG_ATOMIC("Adding all bridges for [encoder:%d:%s] to %p\n",
|
||||
encoder->base.id, encoder->name, state);
|
||||
|
||||
drm_for_each_bridge_in_chain(encoder, bridge) {
|
||||
bridge_state = drm_atomic_get_bridge_state(state, bridge);
|
||||
if (IS_ERR(bridge_state))
|
||||
return PTR_ERR(bridge_state);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_atomic_add_encoder_bridges);
|
||||
|
||||
/**
|
||||
* drm_atomic_add_affected_connectors - add connectors for CRTC
|
||||
* @state: atomic state
|
||||
|
|
|
@ -437,12 +437,12 @@ mode_fixup(struct drm_atomic_state *state)
|
|||
funcs = encoder->helper_private;
|
||||
|
||||
bridge = drm_bridge_chain_get_first_bridge(encoder);
|
||||
ret = drm_atomic_bridge_chain_check(bridge,
|
||||
new_crtc_state,
|
||||
new_conn_state);
|
||||
if (ret) {
|
||||
DRM_DEBUG_ATOMIC("Bridge atomic check failed\n");
|
||||
return ret;
|
||||
ret = drm_bridge_chain_mode_fixup(bridge,
|
||||
&new_crtc_state->mode,
|
||||
&new_crtc_state->adjusted_mode);
|
||||
if (!ret) {
|
||||
DRM_DEBUG_ATOMIC("Bridge fixup failed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (funcs && funcs->atomic_check) {
|
||||
|
@ -730,26 +730,6 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate over all connectors again, and add all affected bridges to
|
||||
* the state.
|
||||
*/
|
||||
for_each_oldnew_connector_in_state(state, connector,
|
||||
old_connector_state,
|
||||
new_connector_state, i) {
|
||||
struct drm_encoder *encoder;
|
||||
|
||||
encoder = old_connector_state->best_encoder;
|
||||
ret = drm_atomic_add_encoder_bridges(state, encoder);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
encoder = new_connector_state->best_encoder;
|
||||
ret = drm_atomic_add_encoder_bridges(state, encoder);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mode_valid(state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#include <drm/drm_atomic_state_helper.h>
|
||||
#include <drm/drm_bridge.h>
|
||||
#include <drm/drm_encoder.h>
|
||||
|
||||
|
@ -90,74 +89,6 @@ void drm_bridge_remove(struct drm_bridge *bridge)
|
|||
}
|
||||
EXPORT_SYMBOL(drm_bridge_remove);
|
||||
|
||||
static struct drm_bridge_state *
|
||||
drm_atomic_default_bridge_duplicate_state(struct drm_bridge *bridge)
|
||||
{
|
||||
struct drm_bridge_state *new;
|
||||
|
||||
if (WARN_ON(!bridge->base.state))
|
||||
return NULL;
|
||||
|
||||
new = kzalloc(sizeof(*new), GFP_KERNEL);
|
||||
if (new)
|
||||
__drm_atomic_helper_bridge_duplicate_state(bridge, new);
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
static struct drm_private_state *
|
||||
drm_bridge_atomic_duplicate_priv_state(struct drm_private_obj *obj)
|
||||
{
|
||||
struct drm_bridge *bridge = drm_priv_to_bridge(obj);
|
||||
struct drm_bridge_state *state;
|
||||
|
||||
if (bridge->funcs->atomic_duplicate_state)
|
||||
state = bridge->funcs->atomic_duplicate_state(bridge);
|
||||
else
|
||||
state = drm_atomic_default_bridge_duplicate_state(bridge);
|
||||
|
||||
return state ? &state->base : NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
drm_atomic_default_bridge_destroy_state(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *state)
|
||||
{
|
||||
/* Just a simple kfree() for now */
|
||||
kfree(state);
|
||||
}
|
||||
|
||||
static void
|
||||
drm_bridge_atomic_destroy_priv_state(struct drm_private_obj *obj,
|
||||
struct drm_private_state *s)
|
||||
{
|
||||
struct drm_bridge_state *state = drm_priv_to_bridge_state(s);
|
||||
struct drm_bridge *bridge = drm_priv_to_bridge(obj);
|
||||
|
||||
if (bridge->funcs->atomic_destroy_state)
|
||||
bridge->funcs->atomic_destroy_state(bridge, state);
|
||||
else
|
||||
drm_atomic_default_bridge_destroy_state(bridge, state);
|
||||
}
|
||||
|
||||
static const struct drm_private_state_funcs drm_bridge_priv_state_funcs = {
|
||||
.atomic_duplicate_state = drm_bridge_atomic_duplicate_priv_state,
|
||||
.atomic_destroy_state = drm_bridge_atomic_destroy_priv_state,
|
||||
};
|
||||
|
||||
static struct drm_bridge_state *
|
||||
drm_atomic_default_bridge_reset(struct drm_bridge *bridge)
|
||||
{
|
||||
struct drm_bridge_state *bridge_state;
|
||||
|
||||
bridge_state = kzalloc(sizeof(*bridge_state), GFP_KERNEL);
|
||||
if (!bridge_state)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
__drm_atomic_helper_bridge_reset(bridge, bridge_state);
|
||||
return bridge_state;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_bridge_attach - attach the bridge to an encoder's chain
|
||||
*
|
||||
|
@ -183,7 +114,6 @@ drm_atomic_default_bridge_reset(struct drm_bridge *bridge)
|
|||
int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
|
||||
struct drm_bridge *previous)
|
||||
{
|
||||
struct drm_bridge_state *state;
|
||||
int ret;
|
||||
|
||||
if (!encoder || !bridge)
|
||||
|
@ -205,35 +135,15 @@ int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
|
|||
|
||||
if (bridge->funcs->attach) {
|
||||
ret = bridge->funcs->attach(bridge);
|
||||
if (ret < 0)
|
||||
goto err_reset_bridge;
|
||||
if (ret < 0) {
|
||||
list_del(&bridge->chain_node);
|
||||
bridge->dev = NULL;
|
||||
bridge->encoder = NULL;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (bridge->funcs->atomic_reset)
|
||||
state = bridge->funcs->atomic_reset(bridge);
|
||||
else
|
||||
state = drm_atomic_default_bridge_reset(bridge);
|
||||
|
||||
if (IS_ERR(state)) {
|
||||
ret = PTR_ERR(state);
|
||||
goto err_detach_bridge;
|
||||
}
|
||||
|
||||
drm_atomic_private_obj_init(bridge->dev, &bridge->base,
|
||||
&state->base,
|
||||
&drm_bridge_priv_state_funcs);
|
||||
|
||||
return 0;
|
||||
|
||||
err_detach_bridge:
|
||||
if (bridge->funcs->detach)
|
||||
bridge->funcs->detach(bridge);
|
||||
|
||||
err_reset_bridge:
|
||||
bridge->dev = NULL;
|
||||
bridge->encoder = NULL;
|
||||
list_del(&bridge->chain_node);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_bridge_attach);
|
||||
|
||||
|
@ -245,8 +155,6 @@ void drm_bridge_detach(struct drm_bridge *bridge)
|
|||
if (WARN_ON(!bridge->dev))
|
||||
return;
|
||||
|
||||
drm_atomic_private_obj_fini(&bridge->base);
|
||||
|
||||
if (bridge->funcs->detach)
|
||||
bridge->funcs->detach(bridge);
|
||||
|
||||
|
@ -501,19 +409,10 @@ void drm_atomic_bridge_chain_disable(struct drm_bridge *bridge,
|
|||
|
||||
encoder = bridge->encoder;
|
||||
list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) {
|
||||
if (iter->funcs->atomic_disable) {
|
||||
struct drm_bridge_state *old_bridge_state;
|
||||
|
||||
old_bridge_state =
|
||||
drm_atomic_get_old_bridge_state(old_state,
|
||||
iter);
|
||||
if (WARN_ON(!old_bridge_state))
|
||||
return;
|
||||
|
||||
iter->funcs->atomic_disable(iter, old_bridge_state);
|
||||
} else if (iter->funcs->disable) {
|
||||
if (iter->funcs->atomic_disable)
|
||||
iter->funcs->atomic_disable(iter, old_state);
|
||||
else if (iter->funcs->disable)
|
||||
iter->funcs->disable(iter);
|
||||
}
|
||||
|
||||
if (iter == bridge)
|
||||
break;
|
||||
|
@ -544,20 +443,10 @@ void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge,
|
|||
|
||||
encoder = bridge->encoder;
|
||||
list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
|
||||
if (bridge->funcs->atomic_post_disable) {
|
||||
struct drm_bridge_state *old_bridge_state;
|
||||
|
||||
old_bridge_state =
|
||||
drm_atomic_get_old_bridge_state(old_state,
|
||||
bridge);
|
||||
if (WARN_ON(!old_bridge_state))
|
||||
return;
|
||||
|
||||
bridge->funcs->atomic_post_disable(bridge,
|
||||
old_bridge_state);
|
||||
} else if (bridge->funcs->post_disable) {
|
||||
if (bridge->funcs->atomic_post_disable)
|
||||
bridge->funcs->atomic_post_disable(bridge, old_state);
|
||||
else if (bridge->funcs->post_disable)
|
||||
bridge->funcs->post_disable(bridge);
|
||||
}
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(drm_atomic_bridge_chain_post_disable);
|
||||
|
@ -586,19 +475,10 @@ void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge,
|
|||
|
||||
encoder = bridge->encoder;
|
||||
list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) {
|
||||
if (iter->funcs->atomic_pre_enable) {
|
||||
struct drm_bridge_state *old_bridge_state;
|
||||
|
||||
old_bridge_state =
|
||||
drm_atomic_get_old_bridge_state(old_state,
|
||||
iter);
|
||||
if (WARN_ON(!old_bridge_state))
|
||||
return;
|
||||
|
||||
iter->funcs->atomic_pre_enable(iter, old_bridge_state);
|
||||
} else if (iter->funcs->pre_enable) {
|
||||
if (iter->funcs->atomic_pre_enable)
|
||||
iter->funcs->atomic_pre_enable(iter, old_state);
|
||||
else if (iter->funcs->pre_enable)
|
||||
iter->funcs->pre_enable(iter);
|
||||
}
|
||||
|
||||
if (iter == bridge)
|
||||
break;
|
||||
|
@ -628,385 +508,14 @@ void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge,
|
|||
|
||||
encoder = bridge->encoder;
|
||||
list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
|
||||
if (bridge->funcs->atomic_enable) {
|
||||
struct drm_bridge_state *old_bridge_state;
|
||||
|
||||
old_bridge_state =
|
||||
drm_atomic_get_old_bridge_state(old_state,
|
||||
bridge);
|
||||
if (WARN_ON(!old_bridge_state))
|
||||
return;
|
||||
|
||||
bridge->funcs->atomic_enable(bridge, old_bridge_state);
|
||||
} else if (bridge->funcs->enable) {
|
||||
if (bridge->funcs->atomic_enable)
|
||||
bridge->funcs->atomic_enable(bridge, old_state);
|
||||
else if (bridge->funcs->enable)
|
||||
bridge->funcs->enable(bridge);
|
||||
}
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(drm_atomic_bridge_chain_enable);
|
||||
|
||||
static int drm_atomic_bridge_check(struct drm_bridge *bridge,
|
||||
struct drm_crtc_state *crtc_state,
|
||||
struct drm_connector_state *conn_state)
|
||||
{
|
||||
if (bridge->funcs->atomic_check) {
|
||||
struct drm_bridge_state *bridge_state;
|
||||
int ret;
|
||||
|
||||
bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state,
|
||||
bridge);
|
||||
if (WARN_ON(!bridge_state))
|
||||
return -EINVAL;
|
||||
|
||||
ret = bridge->funcs->atomic_check(bridge, bridge_state,
|
||||
crtc_state, conn_state);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else if (bridge->funcs->mode_fixup) {
|
||||
if (!bridge->funcs->mode_fixup(bridge, &crtc_state->mode,
|
||||
&crtc_state->adjusted_mode))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_atomic_helper_bridge_propagate_bus_fmt() - Propagate output format to
|
||||
* the input end of a bridge
|
||||
* @bridge: bridge control structure
|
||||
* @bridge_state: new bridge state
|
||||
* @crtc_state: new CRTC state
|
||||
* @conn_state: new connector state
|
||||
* @output_fmt: tested output bus format
|
||||
* @num_input_fmts: will contain the size of the returned array
|
||||
*
|
||||
* This helper is a pluggable implementation of the
|
||||
* &drm_bridge_funcs.atomic_get_input_bus_fmts operation for bridges that don't
|
||||
* modify the bus configuration between their input and their output. It
|
||||
* returns an array of input formats with a single element set to @output_fmt.
|
||||
*
|
||||
* RETURNS:
|
||||
* a valid format array of size @num_input_fmts, or NULL if the allocation
|
||||
* failed
|
||||
*/
|
||||
u32 *
|
||||
drm_atomic_helper_bridge_propagate_bus_fmt(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *bridge_state,
|
||||
struct drm_crtc_state *crtc_state,
|
||||
struct drm_connector_state *conn_state,
|
||||
u32 output_fmt,
|
||||
unsigned int *num_input_fmts)
|
||||
{
|
||||
u32 *input_fmts;
|
||||
|
||||
input_fmts = kzalloc(sizeof(*input_fmts), GFP_KERNEL);
|
||||
if (!input_fmts) {
|
||||
*num_input_fmts = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*num_input_fmts = 1;
|
||||
input_fmts[0] = output_fmt;
|
||||
return input_fmts;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_atomic_helper_bridge_propagate_bus_fmt);
|
||||
|
||||
static int select_bus_fmt_recursive(struct drm_bridge *first_bridge,
|
||||
struct drm_bridge *cur_bridge,
|
||||
struct drm_crtc_state *crtc_state,
|
||||
struct drm_connector_state *conn_state,
|
||||
u32 out_bus_fmt)
|
||||
{
|
||||
struct drm_bridge_state *cur_state;
|
||||
unsigned int num_in_bus_fmts, i;
|
||||
struct drm_bridge *prev_bridge;
|
||||
u32 *in_bus_fmts;
|
||||
int ret;
|
||||
|
||||
prev_bridge = drm_bridge_get_prev_bridge(cur_bridge);
|
||||
cur_state = drm_atomic_get_new_bridge_state(crtc_state->state,
|
||||
cur_bridge);
|
||||
if (WARN_ON(!cur_state))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* If bus format negotiation is not supported by this bridge, let's
|
||||
* pass MEDIA_BUS_FMT_FIXED to the previous bridge in the chain and
|
||||
* hope that it can handle this situation gracefully (by providing
|
||||
* appropriate default values).
|
||||
*/
|
||||
if (!cur_bridge->funcs->atomic_get_input_bus_fmts) {
|
||||
if (cur_bridge != first_bridge) {
|
||||
ret = select_bus_fmt_recursive(first_bridge,
|
||||
prev_bridge, crtc_state,
|
||||
conn_state,
|
||||
MEDIA_BUS_FMT_FIXED);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
cur_state->input_bus_cfg.format = MEDIA_BUS_FMT_FIXED;
|
||||
cur_state->output_bus_cfg.format = out_bus_fmt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
in_bus_fmts = cur_bridge->funcs->atomic_get_input_bus_fmts(cur_bridge,
|
||||
cur_state,
|
||||
crtc_state,
|
||||
conn_state,
|
||||
out_bus_fmt,
|
||||
&num_in_bus_fmts);
|
||||
if (!num_in_bus_fmts)
|
||||
return -ENOTSUPP;
|
||||
else if (!in_bus_fmts)
|
||||
return -ENOMEM;
|
||||
|
||||
if (first_bridge == cur_bridge) {
|
||||
cur_state->input_bus_cfg.format = in_bus_fmts[0];
|
||||
cur_state->output_bus_cfg.format = out_bus_fmt;
|
||||
kfree(in_bus_fmts);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_in_bus_fmts; i++) {
|
||||
ret = select_bus_fmt_recursive(first_bridge, prev_bridge,
|
||||
crtc_state, conn_state,
|
||||
in_bus_fmts[i]);
|
||||
if (ret != -ENOTSUPP)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
cur_state->input_bus_cfg.format = in_bus_fmts[i];
|
||||
cur_state->output_bus_cfg.format = out_bus_fmt;
|
||||
}
|
||||
|
||||
kfree(in_bus_fmts);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called by &drm_atomic_bridge_chain_check() just before
|
||||
* calling &drm_bridge_funcs.atomic_check() on all elements of the chain.
|
||||
* It performs bus format negotiation between bridge elements. The negotiation
|
||||
* happens in reverse order, starting from the last element in the chain up to
|
||||
* @bridge.
|
||||
*
|
||||
* Negotiation starts by retrieving supported output bus formats on the last
|
||||
* bridge element and testing them one by one. The test is recursive, meaning
|
||||
* that for each tested output format, the whole chain will be walked backward,
|
||||
* and each element will have to choose an input bus format that can be
|
||||
* transcoded to the requested output format. When a bridge element does not
|
||||
* support transcoding into a specific output format -ENOTSUPP is returned and
|
||||
* the next bridge element will have to try a different format. If none of the
|
||||
* combinations worked, -ENOTSUPP is returned and the atomic modeset will fail.
|
||||
*
|
||||
* This implementation is relying on
|
||||
* &drm_bridge_funcs.atomic_get_output_bus_fmts() and
|
||||
* &drm_bridge_funcs.atomic_get_input_bus_fmts() to gather supported
|
||||
* input/output formats.
|
||||
*
|
||||
* When &drm_bridge_funcs.atomic_get_output_bus_fmts() is not implemented by
|
||||
* the last element of the chain, &drm_atomic_bridge_chain_select_bus_fmts()
|
||||
* tries a single format: &drm_connector.display_info.bus_formats[0] if
|
||||
* available, MEDIA_BUS_FMT_FIXED otherwise.
|
||||
*
|
||||
* When &drm_bridge_funcs.atomic_get_input_bus_fmts() is not implemented,
|
||||
* &drm_atomic_bridge_chain_select_bus_fmts() skips the negotiation on the
|
||||
* bridge element that lacks this hook and asks the previous element in the
|
||||
* chain to try MEDIA_BUS_FMT_FIXED. It's up to bridge drivers to decide what
|
||||
* to do in that case (fail if they want to enforce bus format negotiation, or
|
||||
* provide a reasonable default if they need to support pipelines where not
|
||||
* all elements support bus format negotiation).
|
||||
*/
|
||||
static int
|
||||
drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge,
|
||||
struct drm_crtc_state *crtc_state,
|
||||
struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct drm_connector *conn = conn_state->connector;
|
||||
struct drm_encoder *encoder = bridge->encoder;
|
||||
struct drm_bridge_state *last_bridge_state;
|
||||
unsigned int i, num_out_bus_fmts;
|
||||
struct drm_bridge *last_bridge;
|
||||
u32 *out_bus_fmts;
|
||||
int ret = 0;
|
||||
|
||||
last_bridge = list_last_entry(&encoder->bridge_chain,
|
||||
struct drm_bridge, chain_node);
|
||||
last_bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state,
|
||||
last_bridge);
|
||||
if (WARN_ON(!last_bridge_state))
|
||||
return -EINVAL;
|
||||
|
||||
if (last_bridge->funcs->atomic_get_output_bus_fmts) {
|
||||
const struct drm_bridge_funcs *funcs = last_bridge->funcs;
|
||||
|
||||
out_bus_fmts = funcs->atomic_get_output_bus_fmts(last_bridge,
|
||||
last_bridge_state,
|
||||
crtc_state,
|
||||
conn_state,
|
||||
&num_out_bus_fmts);
|
||||
if (!num_out_bus_fmts)
|
||||
return -ENOTSUPP;
|
||||
else if (!out_bus_fmts)
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
num_out_bus_fmts = 1;
|
||||
out_bus_fmts = kmalloc(sizeof(*out_bus_fmts), GFP_KERNEL);
|
||||
if (!out_bus_fmts)
|
||||
return -ENOMEM;
|
||||
|
||||
if (conn->display_info.num_bus_formats &&
|
||||
conn->display_info.bus_formats)
|
||||
out_bus_fmts[0] = conn->display_info.bus_formats[0];
|
||||
else
|
||||
out_bus_fmts[0] = MEDIA_BUS_FMT_FIXED;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_out_bus_fmts; i++) {
|
||||
ret = select_bus_fmt_recursive(bridge, last_bridge, crtc_state,
|
||||
conn_state, out_bus_fmts[i]);
|
||||
if (ret != -ENOTSUPP)
|
||||
break;
|
||||
}
|
||||
|
||||
kfree(out_bus_fmts);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
drm_atomic_bridge_propagate_bus_flags(struct drm_bridge *bridge,
|
||||
struct drm_connector *conn,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
struct drm_bridge_state *bridge_state, *next_bridge_state;
|
||||
struct drm_bridge *next_bridge;
|
||||
u32 output_flags;
|
||||
|
||||
bridge_state = drm_atomic_get_new_bridge_state(state, bridge);
|
||||
next_bridge = drm_bridge_get_next_bridge(bridge);
|
||||
|
||||
/*
|
||||
* Let's try to apply the most common case here, that is, propagate
|
||||
* display_info flags for the last bridge, and propagate the input
|
||||
* flags of the next bridge element to the output end of the current
|
||||
* bridge when the bridge is not the last one.
|
||||
* There are exceptions to this rule, like when signal inversion is
|
||||
* happening at the board level, but that's something drivers can deal
|
||||
* with from their &drm_bridge_funcs.atomic_check() implementation by
|
||||
* simply overriding the flags value we've set here.
|
||||
*/
|
||||
if (!next_bridge) {
|
||||
output_flags = conn->display_info.bus_flags;
|
||||
} else {
|
||||
next_bridge_state = drm_atomic_get_new_bridge_state(state,
|
||||
next_bridge);
|
||||
output_flags = next_bridge_state->input_bus_cfg.flags;
|
||||
}
|
||||
|
||||
bridge_state->output_bus_cfg.flags = output_flags;
|
||||
|
||||
/*
|
||||
* Propage the output flags to the input end of the bridge. Again, it's
|
||||
* not necessarily what all bridges want, but that's what most of them
|
||||
* do, and by doing that by default we avoid forcing drivers to
|
||||
* duplicate the "dummy propagation" logic.
|
||||
*/
|
||||
bridge_state->input_bus_cfg.flags = output_flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_atomic_bridge_chain_check() - Do an atomic check on the bridge chain
|
||||
* @bridge: bridge control structure
|
||||
* @crtc_state: new CRTC state
|
||||
* @conn_state: new connector state
|
||||
*
|
||||
* First trigger a bus format negotiation before calling
|
||||
* &drm_bridge_funcs.atomic_check() (falls back on
|
||||
* &drm_bridge_funcs.mode_fixup()) op for all the bridges in the encoder chain,
|
||||
* starting from the last bridge to the first. These are called before calling
|
||||
* &drm_encoder_helper_funcs.atomic_check()
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 on success, a negative error code on failure
|
||||
*/
|
||||
int drm_atomic_bridge_chain_check(struct drm_bridge *bridge,
|
||||
struct drm_crtc_state *crtc_state,
|
||||
struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct drm_connector *conn = conn_state->connector;
|
||||
struct drm_encoder *encoder = bridge->encoder;
|
||||
struct drm_bridge *iter;
|
||||
int ret;
|
||||
|
||||
ret = drm_atomic_bridge_chain_select_bus_fmts(bridge, crtc_state,
|
||||
conn_state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) {
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Bus flags are propagated by default. If a bridge needs to
|
||||
* tweak the input bus flags for any reason, it should happen
|
||||
* in its &drm_bridge_funcs.atomic_check() implementation such
|
||||
* that preceding bridges in the chain can propagate the new
|
||||
* bus flags.
|
||||
*/
|
||||
drm_atomic_bridge_propagate_bus_flags(iter, conn,
|
||||
crtc_state->state);
|
||||
|
||||
ret = drm_atomic_bridge_check(iter, crtc_state, conn_state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (iter == bridge)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_atomic_bridge_chain_check);
|
||||
|
||||
/**
|
||||
* __drm_atomic_helper_bridge_reset() - Initialize a bridge state to its
|
||||
* default
|
||||
* @bridge: the bridge this state is refers to
|
||||
* @state: bridge state to initialize
|
||||
*
|
||||
* Initialize the bridge state to default values. This is meant to be* called
|
||||
* by the bridge &drm_plane_funcs.reset hook for bridges that subclass the
|
||||
* bridge state.
|
||||
*/
|
||||
void __drm_atomic_helper_bridge_reset(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *state)
|
||||
{
|
||||
memset(state, 0, sizeof(*state));
|
||||
state->bridge = bridge;
|
||||
}
|
||||
EXPORT_SYMBOL(__drm_atomic_helper_bridge_reset);
|
||||
|
||||
/**
|
||||
* __drm_atomic_helper_bridge_duplicate_state() - Copy atomic bridge state
|
||||
* @bridge: bridge object
|
||||
* @state: atomic bridge state
|
||||
*
|
||||
* Copies atomic state from a bridge's current state and resets inferred values.
|
||||
* This is useful for drivers that subclass the bridge state.
|
||||
*/
|
||||
void __drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *state)
|
||||
{
|
||||
__drm_atomic_helper_private_obj_duplicate_state(&bridge->base,
|
||||
&state->base);
|
||||
state->bridge = bridge;
|
||||
}
|
||||
EXPORT_SYMBOL(__drm_atomic_helper_bridge_duplicate_state);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
/**
|
||||
* of_drm_find_bridge - find the bridge corresponding to the device node in
|
||||
|
|
|
@ -140,8 +140,8 @@ static ssize_t crc_control_write(struct file *file, const char __user *ubuf,
|
|||
if (IS_ERR(source))
|
||||
return PTR_ERR(source);
|
||||
|
||||
if (source[len] == '\n')
|
||||
source[len] = '\0';
|
||||
if (source[len - 1] == '\n')
|
||||
source[len - 1] = '\0';
|
||||
|
||||
ret = crtc->funcs->verify_crc_source(crtc, source, &values_cnt);
|
||||
if (ret)
|
||||
|
@ -258,6 +258,11 @@ static int crtc_crc_release(struct inode *inode, struct file *filep)
|
|||
struct drm_crtc *crtc = filep->f_inode->i_private;
|
||||
struct drm_crtc_crc *crc = &crtc->crc;
|
||||
|
||||
/* terminate the infinite while loop if 'drm_dp_aux_crc_work' running */
|
||||
spin_lock_irq(&crc->lock);
|
||||
crc->opened = false;
|
||||
spin_unlock_irq(&crc->lock);
|
||||
|
||||
crtc->funcs->set_crc_source(crtc, NULL);
|
||||
|
||||
spin_lock_irq(&crc->lock);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
* Copyright (C) 2012 Red Hat
|
||||
*/
|
||||
|
||||
#include <drm/drm_fb_cma_helper.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
#include <drm/drm_framebuffer.h>
|
||||
#include <drm/drm_gem_cma_helper.h>
|
||||
|
|
|
@ -360,7 +360,8 @@ void drm_legacy_lock_master_cleanup(struct drm_device *dev, struct drm_master *m
|
|||
/*
|
||||
* Since the master is disappearing, so is the
|
||||
* possibility to lock.
|
||||
*/ mutex_lock(&dev->struct_mutex);
|
||||
*/
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
if (master->lock.hw_lock) {
|
||||
if (dev->sigdata.lock == master->lock.hw_lock)
|
||||
dev->sigdata.lock = NULL;
|
||||
|
|
|
@ -233,7 +233,7 @@ struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay,
|
|||
/* 3) Nominal HSync width (% of line period) - default 8 */
|
||||
#define CVT_HSYNC_PERCENTAGE 8
|
||||
unsigned int hblank_percentage;
|
||||
int vsyncandback_porch, vback_porch, hblank;
|
||||
int vsyncandback_porch, __maybe_unused vback_porch, hblank;
|
||||
|
||||
/* estimated the horizontal period */
|
||||
tmp1 = HV_FACTOR * 1000000 -
|
||||
|
@ -386,9 +386,10 @@ drm_gtf_mode_complex(struct drm_device *dev, int hdisplay, int vdisplay,
|
|||
int top_margin, bottom_margin;
|
||||
int interlace;
|
||||
unsigned int hfreq_est;
|
||||
int vsync_plus_bp, vback_porch;
|
||||
unsigned int vtotal_lines, vfieldrate_est, hperiod;
|
||||
unsigned int vfield_rate, vframe_rate;
|
||||
int vsync_plus_bp, __maybe_unused vback_porch;
|
||||
unsigned int vtotal_lines, __maybe_unused vfieldrate_est;
|
||||
unsigned int __maybe_unused hperiod;
|
||||
unsigned int vfield_rate, __maybe_unused vframe_rate;
|
||||
int left_margin, right_margin;
|
||||
unsigned int total_active_pixels, ideal_duty_cycle;
|
||||
unsigned int hblank, total_pixels, pixel_freq;
|
||||
|
|
|
@ -1378,6 +1378,7 @@ static void exynos_dsi_unregister_te_irq(struct exynos_dsi *dsi)
|
|||
static void exynos_dsi_enable(struct drm_encoder *encoder)
|
||||
{
|
||||
struct exynos_dsi *dsi = encoder_to_dsi(encoder);
|
||||
struct drm_bridge *iter;
|
||||
int ret;
|
||||
|
||||
if (dsi->state & DSIM_STATE_ENABLED)
|
||||
|
@ -1391,7 +1392,11 @@ static void exynos_dsi_enable(struct drm_encoder *encoder)
|
|||
if (ret < 0)
|
||||
goto err_put_sync;
|
||||
} else {
|
||||
drm_bridge_chain_pre_enable(dsi->out_bridge);
|
||||
list_for_each_entry_reverse(iter, &dsi->bridge_chain,
|
||||
chain_node) {
|
||||
if (iter->funcs->pre_enable)
|
||||
iter->funcs->pre_enable(iter);
|
||||
}
|
||||
}
|
||||
|
||||
exynos_dsi_set_display_mode(dsi);
|
||||
|
@ -1402,7 +1407,10 @@ static void exynos_dsi_enable(struct drm_encoder *encoder)
|
|||
if (ret < 0)
|
||||
goto err_display_disable;
|
||||
} else {
|
||||
drm_bridge_chain_enable(dsi->out_bridge);
|
||||
list_for_each_entry(iter, &dsi->bridge_chain, chain_node) {
|
||||
if (iter->funcs->enable)
|
||||
iter->funcs->enable(iter);
|
||||
}
|
||||
}
|
||||
|
||||
dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;
|
||||
|
@ -1420,6 +1428,7 @@ static void exynos_dsi_enable(struct drm_encoder *encoder)
|
|||
static void exynos_dsi_disable(struct drm_encoder *encoder)
|
||||
{
|
||||
struct exynos_dsi *dsi = encoder_to_dsi(encoder);
|
||||
struct drm_bridge *iter;
|
||||
|
||||
if (!(dsi->state & DSIM_STATE_ENABLED))
|
||||
return;
|
||||
|
@ -1427,10 +1436,20 @@ static void exynos_dsi_disable(struct drm_encoder *encoder)
|
|||
dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE;
|
||||
|
||||
drm_panel_disable(dsi->panel);
|
||||
drm_bridge_chain_disable(dsi->out_bridge);
|
||||
|
||||
list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) {
|
||||
if (iter->funcs->disable)
|
||||
iter->funcs->disable(iter);
|
||||
}
|
||||
|
||||
exynos_dsi_set_display_enable(dsi, false);
|
||||
drm_panel_unprepare(dsi->panel);
|
||||
drm_bridge_chain_post_disable(dsi->out_bridge);
|
||||
|
||||
list_for_each_entry(iter, &dsi->bridge_chain, chain_node) {
|
||||
if (iter->funcs->post_disable)
|
||||
iter->funcs->post_disable(iter);
|
||||
}
|
||||
|
||||
dsi->state &= ~DSIM_STATE_ENABLED;
|
||||
pm_runtime_put_sync(dsi->dev);
|
||||
}
|
||||
|
@ -1523,7 +1542,7 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
|
|||
if (out_bridge) {
|
||||
drm_bridge_attach(encoder, out_bridge, NULL);
|
||||
dsi->out_bridge = out_bridge;
|
||||
list_splice(&encoder->bridge_chain, &dsi->bridge_chain);
|
||||
list_splice_init(&encoder->bridge_chain, &dsi->bridge_chain);
|
||||
} else {
|
||||
int ret = exynos_dsi_create_connector(encoder);
|
||||
|
||||
|
|
|
@ -470,12 +470,11 @@ void psb_irq_turn_off_dpst(struct drm_device *dev)
|
|||
{
|
||||
struct drm_psb_private *dev_priv =
|
||||
(struct drm_psb_private *) dev->dev_private;
|
||||
u32 hist_reg;
|
||||
u32 pwm_reg;
|
||||
|
||||
if (gma_power_begin(dev, false)) {
|
||||
PSB_WVDC32(0x00000000, HISTOGRAM_INT_CONTROL);
|
||||
hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
|
||||
PSB_RVDC32(HISTOGRAM_INT_CONTROL);
|
||||
|
||||
psb_disable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE);
|
||||
|
||||
|
|
|
@ -255,13 +255,17 @@ static struct dma_fence *lima_sched_run_job(struct drm_sched_job *job)
|
|||
return task->fence;
|
||||
}
|
||||
|
||||
static void lima_sched_handle_error_task(struct lima_sched_pipe *pipe,
|
||||
struct lima_sched_task *task)
|
||||
static void lima_sched_timedout_job(struct drm_sched_job *job)
|
||||
{
|
||||
struct lima_sched_pipe *pipe = to_lima_pipe(job->sched);
|
||||
struct lima_sched_task *task = to_lima_task(job);
|
||||
|
||||
if (!pipe->error)
|
||||
DRM_ERROR("lima job timeout\n");
|
||||
|
||||
drm_sched_stop(&pipe->base, &task->base);
|
||||
|
||||
if (task)
|
||||
drm_sched_increase_karma(&task->base);
|
||||
drm_sched_increase_karma(&task->base);
|
||||
|
||||
pipe->task_error(pipe);
|
||||
|
||||
|
@ -284,16 +288,6 @@ static void lima_sched_handle_error_task(struct lima_sched_pipe *pipe,
|
|||
drm_sched_start(&pipe->base, true);
|
||||
}
|
||||
|
||||
static void lima_sched_timedout_job(struct drm_sched_job *job)
|
||||
{
|
||||
struct lima_sched_pipe *pipe = to_lima_pipe(job->sched);
|
||||
struct lima_sched_task *task = to_lima_task(job);
|
||||
|
||||
DRM_ERROR("lima job timeout\n");
|
||||
|
||||
lima_sched_handle_error_task(pipe, task);
|
||||
}
|
||||
|
||||
static void lima_sched_free_job(struct drm_sched_job *job)
|
||||
{
|
||||
struct lima_sched_task *task = to_lima_task(job);
|
||||
|
@ -318,15 +312,6 @@ static const struct drm_sched_backend_ops lima_sched_ops = {
|
|||
.free_job = lima_sched_free_job,
|
||||
};
|
||||
|
||||
static void lima_sched_error_work(struct work_struct *work)
|
||||
{
|
||||
struct lima_sched_pipe *pipe =
|
||||
container_of(work, struct lima_sched_pipe, error_work);
|
||||
struct lima_sched_task *task = pipe->current_task;
|
||||
|
||||
lima_sched_handle_error_task(pipe, task);
|
||||
}
|
||||
|
||||
int lima_sched_pipe_init(struct lima_sched_pipe *pipe, const char *name)
|
||||
{
|
||||
unsigned int timeout = lima_sched_timeout_ms > 0 ?
|
||||
|
@ -335,8 +320,6 @@ int lima_sched_pipe_init(struct lima_sched_pipe *pipe, const char *name)
|
|||
pipe->fence_context = dma_fence_context_alloc(1);
|
||||
spin_lock_init(&pipe->fence_lock);
|
||||
|
||||
INIT_WORK(&pipe->error_work, lima_sched_error_work);
|
||||
|
||||
return drm_sched_init(&pipe->base, &lima_sched_ops, 1, 0,
|
||||
msecs_to_jiffies(timeout), name);
|
||||
}
|
||||
|
@ -349,7 +332,7 @@ void lima_sched_pipe_fini(struct lima_sched_pipe *pipe)
|
|||
void lima_sched_pipe_task_done(struct lima_sched_pipe *pipe)
|
||||
{
|
||||
if (pipe->error)
|
||||
schedule_work(&pipe->error_work);
|
||||
drm_sched_fault(&pipe->base);
|
||||
else {
|
||||
struct lima_sched_task *task = pipe->current_task;
|
||||
|
||||
|
|
|
@ -68,8 +68,6 @@ struct lima_sched_pipe {
|
|||
void (*task_fini)(struct lima_sched_pipe *pipe);
|
||||
void (*task_error)(struct lima_sched_pipe *pipe);
|
||||
void (*task_mmu_error)(struct lima_sched_pipe *pipe);
|
||||
|
||||
struct work_struct error_work;
|
||||
};
|
||||
|
||||
int lima_sched_task_init(struct lima_sched_task *task,
|
||||
|
|
|
@ -135,7 +135,7 @@ struct meson_drm {
|
|||
} venc;
|
||||
|
||||
struct {
|
||||
dma_addr_t addr_phys;
|
||||
dma_addr_t addr_dma;
|
||||
uint32_t *addr;
|
||||
unsigned int offset;
|
||||
} rdma;
|
||||
|
|
|
@ -27,7 +27,7 @@ int meson_rdma_init(struct meson_drm *priv)
|
|||
/* Allocate a PAGE buffer */
|
||||
priv->rdma.addr =
|
||||
dma_alloc_coherent(priv->dev, SZ_4K,
|
||||
&priv->rdma.addr_phys,
|
||||
&priv->rdma.addr_dma,
|
||||
GFP_KERNEL);
|
||||
if (!priv->rdma.addr)
|
||||
return -ENOMEM;
|
||||
|
@ -47,16 +47,16 @@ int meson_rdma_init(struct meson_drm *priv)
|
|||
|
||||
void meson_rdma_free(struct meson_drm *priv)
|
||||
{
|
||||
if (!priv->rdma.addr && !priv->rdma.addr_phys)
|
||||
if (!priv->rdma.addr && !priv->rdma.addr_dma)
|
||||
return;
|
||||
|
||||
meson_rdma_stop(priv);
|
||||
|
||||
dma_free_coherent(priv->dev, SZ_4K,
|
||||
priv->rdma.addr, priv->rdma.addr_phys);
|
||||
priv->rdma.addr, priv->rdma.addr_dma);
|
||||
|
||||
priv->rdma.addr = NULL;
|
||||
priv->rdma.addr_phys = (dma_addr_t)NULL;
|
||||
priv->rdma.addr_dma = (dma_addr_t)0;
|
||||
}
|
||||
|
||||
void meson_rdma_setup(struct meson_drm *priv)
|
||||
|
@ -118,11 +118,11 @@ void meson_rdma_flush(struct meson_drm *priv)
|
|||
meson_rdma_stop(priv);
|
||||
|
||||
/* Start of Channel 1 register writes buffer */
|
||||
writel(priv->rdma.addr_phys,
|
||||
writel(priv->rdma.addr_dma,
|
||||
priv->io_base + _REG(RDMA_AHB_START_ADDR_1));
|
||||
|
||||
/* Last byte on Channel 1 register writes buffer */
|
||||
writel(priv->rdma.addr_phys + (priv->rdma.offset * RDMA_DESC_SIZE) - 1,
|
||||
writel(priv->rdma.addr_dma + (priv->rdma.offset * RDMA_DESC_SIZE) - 1,
|
||||
priv->io_base + _REG(RDMA_AHB_END_ADDR_1));
|
||||
|
||||
/* Trigger Channel 1 on VSYNC event */
|
||||
|
|
|
@ -393,8 +393,7 @@ static void dispc_get_reg_field(struct dispc_device *dispc,
|
|||
enum dispc_feat_reg_field id,
|
||||
u8 *start, u8 *end)
|
||||
{
|
||||
if (id >= dispc->feat->num_reg_fields)
|
||||
BUG();
|
||||
BUG_ON(id >= dispc->feat->num_reg_fields);
|
||||
|
||||
*start = dispc->feat->reg_fields[id].start;
|
||||
*end = dispc->feat->reg_fields[id].end;
|
||||
|
|
|
@ -338,6 +338,17 @@ config DRM_PANEL_SITRONIX_ST7789V
|
|||
Say Y here if you want to enable support for the Sitronix
|
||||
ST7789V controller for 240x320 LCD panels
|
||||
|
||||
config DRM_PANEL_SONY_ACX424AKP
|
||||
tristate "Sony ACX424AKP DSI command mode panel"
|
||||
depends on OF
|
||||
depends on DRM_MIPI_DSI
|
||||
depends on BACKLIGHT_CLASS_DEVICE
|
||||
select VIDEOMODE_HELPERS
|
||||
help
|
||||
Say Y here if you want to enable the Sony ACX424 display
|
||||
panel. This panel supports DSI in both command and video
|
||||
mode.
|
||||
|
||||
config DRM_PANEL_SONY_ACX565AKM
|
||||
tristate "Sony ACX565AKM panel"
|
||||
depends on GPIOLIB && OF && SPI
|
||||
|
|
|
@ -35,6 +35,7 @@ obj-$(CONFIG_DRM_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
|
|||
obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o
|
||||
obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7701) += panel-sitronix-st7701.o
|
||||
obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7789V) += panel-sitronix-st7789v.o
|
||||
obj-$(CONFIG_DRM_PANEL_SONY_ACX424AKP) += panel-sony-acx424akp.o
|
||||
obj-$(CONFIG_DRM_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o
|
||||
obj-$(CONFIG_DRM_PANEL_TPO_TD028TTEC1) += panel-tpo-td028ttec1.o
|
||||
obj-$(CONFIG_DRM_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o
|
||||
|
|
|
@ -629,6 +629,35 @@ static const struct panel_desc auo_b101xtn01 = {
|
|||
},
|
||||
};
|
||||
|
||||
static const struct drm_display_mode auo_b116xak01_mode = {
|
||||
.clock = 69300,
|
||||
.hdisplay = 1366,
|
||||
.hsync_start = 1366 + 48,
|
||||
.hsync_end = 1366 + 48 + 32,
|
||||
.htotal = 1366 + 48 + 32 + 10,
|
||||
.vdisplay = 768,
|
||||
.vsync_start = 768 + 4,
|
||||
.vsync_end = 768 + 4 + 6,
|
||||
.vtotal = 768 + 4 + 6 + 15,
|
||||
.vrefresh = 60,
|
||||
.flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
|
||||
};
|
||||
|
||||
static const struct panel_desc auo_b116xak01 = {
|
||||
.modes = &auo_b116xak01_mode,
|
||||
.num_modes = 1,
|
||||
.bpc = 6,
|
||||
.size = {
|
||||
.width = 256,
|
||||
.height = 144,
|
||||
},
|
||||
.delay = {
|
||||
.hpd_absent_delay = 200,
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB666_1X18,
|
||||
.connector_type = DRM_MODE_CONNECTOR_eDP,
|
||||
};
|
||||
|
||||
static const struct drm_display_mode auo_b116xw03_mode = {
|
||||
.clock = 70589,
|
||||
.hdisplay = 1366,
|
||||
|
@ -1008,6 +1037,38 @@ static const struct panel_desc boe_nv101wxmn51 = {
|
|||
},
|
||||
};
|
||||
|
||||
static const struct drm_display_mode boe_nv140fhmn49_modes[] = {
|
||||
{
|
||||
.clock = 148500,
|
||||
.hdisplay = 1920,
|
||||
.hsync_start = 1920 + 48,
|
||||
.hsync_end = 1920 + 48 + 32,
|
||||
.htotal = 2200,
|
||||
.vdisplay = 1080,
|
||||
.vsync_start = 1080 + 3,
|
||||
.vsync_end = 1080 + 3 + 5,
|
||||
.vtotal = 1125,
|
||||
.vrefresh = 60,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct panel_desc boe_nv140fhmn49 = {
|
||||
.modes = boe_nv140fhmn49_modes,
|
||||
.num_modes = ARRAY_SIZE(boe_nv140fhmn49_modes),
|
||||
.bpc = 6,
|
||||
.size = {
|
||||
.width = 309,
|
||||
.height = 174,
|
||||
},
|
||||
.delay = {
|
||||
.prepare = 210,
|
||||
.enable = 50,
|
||||
.unprepare = 160,
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB666_1X18,
|
||||
.connector_type = DRM_MODE_CONNECTOR_eDP,
|
||||
};
|
||||
|
||||
static const struct drm_display_mode cdtech_s043wq26h_ct7_mode = {
|
||||
.clock = 9000,
|
||||
.hdisplay = 480,
|
||||
|
@ -2553,6 +2614,30 @@ static const struct panel_desc samsung_ltn140at29_301 = {
|
|||
},
|
||||
};
|
||||
|
||||
static const struct display_timing satoz_sat050at40h12r2_timing = {
|
||||
.pixelclock = {33300000, 33300000, 50000000},
|
||||
.hactive = {800, 800, 800},
|
||||
.hfront_porch = {16, 210, 354},
|
||||
.hback_porch = {46, 46, 46},
|
||||
.hsync_len = {1, 1, 40},
|
||||
.vactive = {480, 480, 480},
|
||||
.vfront_porch = {7, 22, 147},
|
||||
.vback_porch = {23, 23, 23},
|
||||
.vsync_len = {1, 1, 20},
|
||||
};
|
||||
|
||||
static const struct panel_desc satoz_sat050at40h12r2 = {
|
||||
.timings = &satoz_sat050at40h12r2_timing,
|
||||
.num_timings = 1,
|
||||
.bpc = 8,
|
||||
.size = {
|
||||
.width = 108,
|
||||
.height = 65,
|
||||
},
|
||||
.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
|
||||
.connector_type = DRM_MODE_CONNECTOR_LVDS,
|
||||
};
|
||||
|
||||
static const struct drm_display_mode sharp_ld_d5116z01b_mode = {
|
||||
.clock = 168480,
|
||||
.hdisplay = 1920,
|
||||
|
@ -3125,6 +3210,9 @@ static const struct of_device_id platform_of_match[] = {
|
|||
}, {
|
||||
.compatible = "auo,b101xtn01",
|
||||
.data = &auo_b101xtn01,
|
||||
}, {
|
||||
.compatible = "auo,b116xa01",
|
||||
.data = &auo_b116xak01,
|
||||
}, {
|
||||
.compatible = "auo,b116xw03",
|
||||
.data = &auo_b116xw03,
|
||||
|
@ -3167,6 +3255,9 @@ static const struct of_device_id platform_of_match[] = {
|
|||
}, {
|
||||
.compatible = "boe,nv101wxmn51",
|
||||
.data = &boe_nv101wxmn51,
|
||||
}, {
|
||||
.compatible = "boe,nv140fhmn49",
|
||||
.data = &boe_nv140fhmn49,
|
||||
}, {
|
||||
.compatible = "cdtech,s043wq26h-ct7",
|
||||
.data = &cdtech_s043wq26h_ct7,
|
||||
|
@ -3356,6 +3447,9 @@ static const struct of_device_id platform_of_match[] = {
|
|||
}, {
|
||||
.compatible = "samsung,ltn140at29-301",
|
||||
.data = &samsung_ltn140at29_301,
|
||||
}, {
|
||||
.compatible = "satoz,sat050at40h12r2",
|
||||
.data = &satoz_sat050at40h12r2,
|
||||
}, {
|
||||
.compatible = "sharp,ld-d5116z01b",
|
||||
.data = &sharp_ld_d5116z01b,
|
||||
|
|
|
@ -0,0 +1,550 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* MIPI-DSI Sony ACX424AKP panel driver. This is a 480x864
|
||||
* AMOLED panel with a command-only DSI interface.
|
||||
*
|
||||
* Copyright (C) Linaro Ltd. 2019
|
||||
* Author: Linus Walleij
|
||||
* Based on code and know-how from Marcus Lorentzon
|
||||
* Copyright (C) ST-Ericsson SA 2010
|
||||
*/
|
||||
#include <linux/backlight.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#include <video/mipi_display.h>
|
||||
|
||||
#include <drm/drm_mipi_dsi.h>
|
||||
#include <drm/drm_modes.h>
|
||||
#include <drm/drm_panel.h>
|
||||
#include <drm/drm_print.h>
|
||||
|
||||
#define ACX424_DCS_READ_ID1 0xDA
|
||||
#define ACX424_DCS_READ_ID2 0xDB
|
||||
#define ACX424_DCS_READ_ID3 0xDC
|
||||
#define ACX424_DCS_SET_MDDI 0xAE
|
||||
|
||||
/*
|
||||
* Sony seems to use vendor ID 0x81
|
||||
*/
|
||||
#define DISPLAY_SONY_ACX424AKP_ID1 0x811b
|
||||
#define DISPLAY_SONY_ACX424AKP_ID2 0x811a
|
||||
/*
|
||||
* The third ID looks like a bug, vendor IDs begin at 0x80
|
||||
* and panel 00 ... seems like default values.
|
||||
*/
|
||||
#define DISPLAY_SONY_ACX424AKP_ID3 0x8000
|
||||
|
||||
struct acx424akp {
|
||||
struct drm_panel panel;
|
||||
struct device *dev;
|
||||
struct backlight_device *bl;
|
||||
struct regulator *supply;
|
||||
struct gpio_desc *reset_gpio;
|
||||
bool video_mode;
|
||||
};
|
||||
|
||||
static const struct drm_display_mode sony_acx424akp_vid_mode = {
|
||||
.clock = 330000,
|
||||
.hdisplay = 480,
|
||||
.hsync_start = 480 + 15,
|
||||
.hsync_end = 480 + 15 + 0,
|
||||
.htotal = 480 + 15 + 0 + 15,
|
||||
.vdisplay = 864,
|
||||
.vsync_start = 864 + 14,
|
||||
.vsync_end = 864 + 14 + 1,
|
||||
.vtotal = 864 + 14 + 1 + 11,
|
||||
.vrefresh = 60,
|
||||
.width_mm = 48,
|
||||
.height_mm = 84,
|
||||
.flags = DRM_MODE_FLAG_PVSYNC,
|
||||
};
|
||||
|
||||
/*
|
||||
* The timings are not very helpful as the display is used in
|
||||
* command mode using the maximum HS frequency.
|
||||
*/
|
||||
static const struct drm_display_mode sony_acx424akp_cmd_mode = {
|
||||
.clock = 420160,
|
||||
.hdisplay = 480,
|
||||
.hsync_start = 480 + 154,
|
||||
.hsync_end = 480 + 154 + 16,
|
||||
.htotal = 480 + 154 + 16 + 32,
|
||||
.vdisplay = 864,
|
||||
.vsync_start = 864 + 1,
|
||||
.vsync_end = 864 + 1 + 1,
|
||||
.vtotal = 864 + 1 + 1 + 1,
|
||||
/*
|
||||
* Some desired refresh rate, experiments at the maximum "pixel"
|
||||
* clock speed (HS clock 420 MHz) yields around 117Hz.
|
||||
*/
|
||||
.vrefresh = 60,
|
||||
.width_mm = 48,
|
||||
.height_mm = 84,
|
||||
};
|
||||
|
||||
static inline struct acx424akp *panel_to_acx424akp(struct drm_panel *panel)
|
||||
{
|
||||
return container_of(panel, struct acx424akp, panel);
|
||||
}
|
||||
|
||||
#define FOSC 20 /* 20Mhz */
|
||||
#define SCALE_FACTOR_NS_DIV_MHZ 1000
|
||||
|
||||
static int acx424akp_set_brightness(struct backlight_device *bl)
|
||||
{
|
||||
struct acx424akp *acx = bl_get_data(bl);
|
||||
struct mipi_dsi_device *dsi = to_mipi_dsi_device(acx->dev);
|
||||
int period_ns = 1023;
|
||||
int duty_ns = bl->props.brightness;
|
||||
u8 pwm_ratio;
|
||||
u8 pwm_div;
|
||||
u8 par;
|
||||
int ret;
|
||||
|
||||
/* Calculate the PWM duty cycle in n/256's */
|
||||
pwm_ratio = max(((duty_ns * 256) / period_ns) - 1, 1);
|
||||
pwm_div = max(1,
|
||||
((FOSC * period_ns) / 256) /
|
||||
SCALE_FACTOR_NS_DIV_MHZ);
|
||||
|
||||
/* Set up PWM dutycycle ONE byte (differs from the standard) */
|
||||
DRM_DEV_DEBUG(acx->dev, "calculated duty cycle %02x\n", pwm_ratio);
|
||||
ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
|
||||
&pwm_ratio, 1);
|
||||
if (ret < 0) {
|
||||
DRM_DEV_ERROR(acx->dev,
|
||||
"failed to set display PWM ratio (%d)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sequence to write PWMDIV:
|
||||
* address data
|
||||
* 0xF3 0xAA CMD2 Unlock
|
||||
* 0x00 0x01 Enter CMD2 page 0
|
||||
* 0X7D 0x01 No reload MTP of CMD2 P1
|
||||
* 0x22 PWMDIV
|
||||
* 0x7F 0xAA CMD2 page 1 lock
|
||||
*/
|
||||
par = 0xaa;
|
||||
ret = mipi_dsi_dcs_write(dsi, 0xf3, &par, 1);
|
||||
if (ret < 0) {
|
||||
DRM_DEV_ERROR(acx->dev,
|
||||
"failed to unlock CMD 2 (%d)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
par = 0x01;
|
||||
ret = mipi_dsi_dcs_write(dsi, 0x00, &par, 1);
|
||||
if (ret < 0) {
|
||||
DRM_DEV_ERROR(acx->dev,
|
||||
"failed to enter page 1 (%d)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
par = 0x01;
|
||||
ret = mipi_dsi_dcs_write(dsi, 0x7d, &par, 1);
|
||||
if (ret < 0) {
|
||||
DRM_DEV_ERROR(acx->dev,
|
||||
"failed to disable MTP reload (%d)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
ret = mipi_dsi_dcs_write(dsi, 0x22, &pwm_div, 1);
|
||||
if (ret < 0) {
|
||||
DRM_DEV_ERROR(acx->dev,
|
||||
"failed to set PWM divisor (%d)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
par = 0xaa;
|
||||
ret = mipi_dsi_dcs_write(dsi, 0x7f, &par, 1);
|
||||
if (ret < 0) {
|
||||
DRM_DEV_ERROR(acx->dev,
|
||||
"failed to lock CMD 2 (%d)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Enable backlight */
|
||||
par = 0x24;
|
||||
ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY,
|
||||
&par, 1);
|
||||
if (ret < 0) {
|
||||
DRM_DEV_ERROR(acx->dev,
|
||||
"failed to enable display backlight (%d)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct backlight_ops acx424akp_bl_ops = {
|
||||
.update_status = acx424akp_set_brightness,
|
||||
};
|
||||
|
||||
static int acx424akp_read_id(struct acx424akp *acx)
|
||||
{
|
||||
struct mipi_dsi_device *dsi = to_mipi_dsi_device(acx->dev);
|
||||
u8 vendor, version, panel;
|
||||
u16 val;
|
||||
int ret;
|
||||
|
||||
ret = mipi_dsi_dcs_read(dsi, ACX424_DCS_READ_ID1, &vendor, 1);
|
||||
if (ret < 0) {
|
||||
DRM_DEV_ERROR(acx->dev, "could not vendor ID byte\n");
|
||||
return ret;
|
||||
}
|
||||
ret = mipi_dsi_dcs_read(dsi, ACX424_DCS_READ_ID2, &version, 1);
|
||||
if (ret < 0) {
|
||||
DRM_DEV_ERROR(acx->dev, "could not read device version byte\n");
|
||||
return ret;
|
||||
}
|
||||
ret = mipi_dsi_dcs_read(dsi, ACX424_DCS_READ_ID3, &panel, 1);
|
||||
if (ret < 0) {
|
||||
DRM_DEV_ERROR(acx->dev, "could not read panel ID byte\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (vendor == 0x00) {
|
||||
DRM_DEV_ERROR(acx->dev, "device vendor ID is zero\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
val = (vendor << 8) | panel;
|
||||
switch (val) {
|
||||
case DISPLAY_SONY_ACX424AKP_ID1:
|
||||
case DISPLAY_SONY_ACX424AKP_ID2:
|
||||
case DISPLAY_SONY_ACX424AKP_ID3:
|
||||
DRM_DEV_INFO(acx->dev,
|
||||
"MTP vendor: %02x, version: %02x, panel: %02x\n",
|
||||
vendor, version, panel);
|
||||
break;
|
||||
default:
|
||||
DRM_DEV_INFO(acx->dev,
|
||||
"unknown vendor: %02x, version: %02x, panel: %02x\n",
|
||||
vendor, version, panel);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acx424akp_power_on(struct acx424akp *acx)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = regulator_enable(acx->supply);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(acx->dev, "failed to enable supply (%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Assert RESET */
|
||||
gpiod_set_value_cansleep(acx->reset_gpio, 1);
|
||||
udelay(20);
|
||||
/* De-assert RESET */
|
||||
gpiod_set_value_cansleep(acx->reset_gpio, 0);
|
||||
usleep_range(11000, 20000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void acx424akp_power_off(struct acx424akp *acx)
|
||||
{
|
||||
/* Assert RESET */
|
||||
gpiod_set_value_cansleep(acx->reset_gpio, 1);
|
||||
usleep_range(11000, 20000);
|
||||
|
||||
regulator_disable(acx->supply);
|
||||
}
|
||||
|
||||
static int acx424akp_prepare(struct drm_panel *panel)
|
||||
{
|
||||
struct acx424akp *acx = panel_to_acx424akp(panel);
|
||||
struct mipi_dsi_device *dsi = to_mipi_dsi_device(acx->dev);
|
||||
const u8 mddi = 3;
|
||||
int ret;
|
||||
|
||||
ret = acx424akp_power_on(acx);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = acx424akp_read_id(acx);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(acx->dev, "failed to read panel ID (%d)\n", ret);
|
||||
goto err_power_off;
|
||||
}
|
||||
|
||||
/* Enabe tearing mode: send TE (tearing effect) at VBLANK */
|
||||
ret = mipi_dsi_dcs_set_tear_on(dsi,
|
||||
MIPI_DSI_DCS_TEAR_MODE_VBLANK);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(acx->dev, "failed to enable vblank TE (%d)\n",
|
||||
ret);
|
||||
goto err_power_off;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set MDDI
|
||||
*
|
||||
* This presumably deactivates the Qualcomm MDDI interface and
|
||||
* selects DSI, similar code is found in other drivers such as the
|
||||
* Sharp LS043T1LE01 which makes us suspect that this panel may be
|
||||
* using a Novatek NT35565 or similar display driver chip that shares
|
||||
* this command. Due to the lack of documentation we cannot know for
|
||||
* sure.
|
||||
*/
|
||||
ret = mipi_dsi_dcs_write(dsi, ACX424_DCS_SET_MDDI,
|
||||
&mddi, sizeof(mddi));
|
||||
if (ret < 0) {
|
||||
DRM_DEV_ERROR(acx->dev, "failed to set MDDI (%d)\n", ret);
|
||||
goto err_power_off;
|
||||
}
|
||||
|
||||
/* Exit sleep mode */
|
||||
ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(acx->dev, "failed to exit sleep mode (%d)\n",
|
||||
ret);
|
||||
goto err_power_off;
|
||||
}
|
||||
msleep(140);
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_on(dsi);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(acx->dev, "failed to turn display on (%d)\n",
|
||||
ret);
|
||||
goto err_power_off;
|
||||
}
|
||||
if (acx->video_mode) {
|
||||
/* In video mode turn peripheral on */
|
||||
ret = mipi_dsi_turn_on_peripheral(dsi);
|
||||
if (ret) {
|
||||
dev_err(acx->dev, "failed to turn on peripheral\n");
|
||||
goto err_power_off;
|
||||
}
|
||||
}
|
||||
|
||||
acx->bl->props.power = FB_BLANK_NORMAL;
|
||||
|
||||
return 0;
|
||||
|
||||
err_power_off:
|
||||
acx424akp_power_off(acx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int acx424akp_unprepare(struct drm_panel *panel)
|
||||
{
|
||||
struct acx424akp *acx = panel_to_acx424akp(panel);
|
||||
struct mipi_dsi_device *dsi = to_mipi_dsi_device(acx->dev);
|
||||
u8 par;
|
||||
int ret;
|
||||
|
||||
/* Disable backlight */
|
||||
par = 0x00;
|
||||
ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY,
|
||||
&par, 1);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(acx->dev,
|
||||
"failed to disable display backlight (%d)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_off(dsi);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(acx->dev, "failed to turn display off (%d)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Enter sleep mode */
|
||||
ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(acx->dev, "failed to enter sleep mode (%d)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
msleep(85);
|
||||
|
||||
acx424akp_power_off(acx);
|
||||
acx->bl->props.power = FB_BLANK_POWERDOWN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acx424akp_enable(struct drm_panel *panel)
|
||||
{
|
||||
struct acx424akp *acx = panel_to_acx424akp(panel);
|
||||
|
||||
/*
|
||||
* The backlight is on as long as the display is on
|
||||
* so no use to call backlight_enable() here.
|
||||
*/
|
||||
acx->bl->props.power = FB_BLANK_UNBLANK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acx424akp_disable(struct drm_panel *panel)
|
||||
{
|
||||
struct acx424akp *acx = panel_to_acx424akp(panel);
|
||||
|
||||
/*
|
||||
* The backlight is on as long as the display is on
|
||||
* so no use to call backlight_disable() here.
|
||||
*/
|
||||
acx->bl->props.power = FB_BLANK_NORMAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acx424akp_get_modes(struct drm_panel *panel,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct acx424akp *acx = panel_to_acx424akp(panel);
|
||||
struct drm_display_mode *mode;
|
||||
|
||||
if (acx->video_mode)
|
||||
mode = drm_mode_duplicate(connector->dev,
|
||||
&sony_acx424akp_vid_mode);
|
||||
else
|
||||
mode = drm_mode_duplicate(connector->dev,
|
||||
&sony_acx424akp_cmd_mode);
|
||||
if (!mode) {
|
||||
DRM_ERROR("bad mode or failed to add mode\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
drm_mode_set_name(mode);
|
||||
mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
|
||||
|
||||
connector->display_info.width_mm = mode->width_mm;
|
||||
connector->display_info.height_mm = mode->height_mm;
|
||||
|
||||
drm_mode_probed_add(connector, mode);
|
||||
|
||||
return 1; /* Number of modes */
|
||||
}
|
||||
|
||||
static const struct drm_panel_funcs acx424akp_drm_funcs = {
|
||||
.disable = acx424akp_disable,
|
||||
.unprepare = acx424akp_unprepare,
|
||||
.prepare = acx424akp_prepare,
|
||||
.enable = acx424akp_enable,
|
||||
.get_modes = acx424akp_get_modes,
|
||||
};
|
||||
|
||||
static int acx424akp_probe(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct device *dev = &dsi->dev;
|
||||
struct acx424akp *acx;
|
||||
int ret;
|
||||
|
||||
acx = devm_kzalloc(dev, sizeof(struct acx424akp), GFP_KERNEL);
|
||||
if (!acx)
|
||||
return -ENOMEM;
|
||||
acx->video_mode = of_property_read_bool(dev->of_node,
|
||||
"enforce-video-mode");
|
||||
|
||||
mipi_dsi_set_drvdata(dsi, acx);
|
||||
acx->dev = dev;
|
||||
|
||||
dsi->lanes = 2;
|
||||
dsi->format = MIPI_DSI_FMT_RGB888;
|
||||
/*
|
||||
* FIXME: these come from the ST-Ericsson vendor driver for the
|
||||
* HREF520 and seems to reflect limitations in the PLLs on that
|
||||
* platform, if you have the datasheet, please cross-check the
|
||||
* actual max rates.
|
||||
*/
|
||||
dsi->lp_rate = 19200000;
|
||||
dsi->hs_rate = 420160000;
|
||||
|
||||
if (acx->video_mode)
|
||||
/* Burst mode using event for sync */
|
||||
dsi->mode_flags =
|
||||
MIPI_DSI_MODE_VIDEO |
|
||||
MIPI_DSI_MODE_VIDEO_BURST;
|
||||
else
|
||||
dsi->mode_flags =
|
||||
MIPI_DSI_CLOCK_NON_CONTINUOUS |
|
||||
MIPI_DSI_MODE_EOT_PACKET;
|
||||
|
||||
acx->supply = devm_regulator_get(dev, "vddi");
|
||||
if (IS_ERR(acx->supply))
|
||||
return PTR_ERR(acx->supply);
|
||||
|
||||
/* This asserts RESET by default */
|
||||
acx->reset_gpio = devm_gpiod_get_optional(dev, "reset",
|
||||
GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(acx->reset_gpio)) {
|
||||
ret = PTR_ERR(acx->reset_gpio);
|
||||
if (ret != -EPROBE_DEFER)
|
||||
DRM_DEV_ERROR(dev, "failed to request GPIO (%d)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
drm_panel_init(&acx->panel, dev, &acx424akp_drm_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
acx->bl = devm_backlight_device_register(dev, "acx424akp", dev, acx,
|
||||
&acx424akp_bl_ops, NULL);
|
||||
if (IS_ERR(acx->bl)) {
|
||||
DRM_DEV_ERROR(dev, "failed to register backlight device\n");
|
||||
return PTR_ERR(acx->bl);
|
||||
}
|
||||
acx->bl->props.max_brightness = 1023;
|
||||
acx->bl->props.brightness = 512;
|
||||
acx->bl->props.power = FB_BLANK_POWERDOWN;
|
||||
|
||||
ret = drm_panel_add(&acx->panel);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = mipi_dsi_attach(dsi);
|
||||
if (ret < 0) {
|
||||
drm_panel_remove(&acx->panel);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acx424akp_remove(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct acx424akp *acx = mipi_dsi_get_drvdata(dsi);
|
||||
|
||||
mipi_dsi_detach(dsi);
|
||||
drm_panel_remove(&acx->panel);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id acx424akp_of_match[] = {
|
||||
{ .compatible = "sony,acx424akp" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, acx424akp_of_match);
|
||||
|
||||
static struct mipi_dsi_driver acx424akp_driver = {
|
||||
.probe = acx424akp_probe,
|
||||
.remove = acx424akp_remove,
|
||||
.driver = {
|
||||
.name = "panel-sony-acx424akp",
|
||||
.of_match_table = acx424akp_of_match,
|
||||
},
|
||||
};
|
||||
module_mipi_dsi_driver(acx424akp_driver);
|
||||
|
||||
MODULE_AUTHOR("Linus Wallei <linus.walleij@linaro.org>");
|
||||
MODULE_DESCRIPTION("MIPI-DSI Sony acx424akp Panel Driver");
|
||||
MODULE_LICENSE("GPL v2");
|
|
@ -590,9 +590,8 @@ static void __rcar_lvds_atomic_enable(struct drm_bridge *bridge,
|
|||
}
|
||||
|
||||
static void rcar_lvds_atomic_enable(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *old_bridge_state)
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
struct drm_atomic_state *state = old_bridge_state->base.state;
|
||||
struct drm_connector *connector;
|
||||
struct drm_crtc *crtc;
|
||||
|
||||
|
@ -604,7 +603,7 @@ static void rcar_lvds_atomic_enable(struct drm_bridge *bridge,
|
|||
}
|
||||
|
||||
static void rcar_lvds_atomic_disable(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *old_bridge_state)
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
|
||||
|
||||
|
@ -619,8 +618,7 @@ static void rcar_lvds_atomic_disable(struct drm_bridge *bridge,
|
|||
|
||||
/* Disable the companion LVDS encoder in dual-link mode. */
|
||||
if (lvds->link_type != RCAR_LVDS_SINGLE_LINK && lvds->companion)
|
||||
lvds->companion->funcs->atomic_disable(lvds->companion,
|
||||
old_bridge_state);
|
||||
lvds->companion->funcs->atomic_disable(lvds->companion, state);
|
||||
|
||||
clk_disable_unprepare(lvds->clocks.mod);
|
||||
}
|
||||
|
|
|
@ -856,6 +856,13 @@ static int sun4i_backend_bind(struct device *dev, struct device *master,
|
|||
ret = PTR_ERR(backend->mod_clk);
|
||||
goto err_disable_bus_clk;
|
||||
}
|
||||
|
||||
ret = clk_set_rate_exclusive(backend->mod_clk, 300000000);
|
||||
if (ret) {
|
||||
dev_err(dev, "Couldn't set the module clock frequency\n");
|
||||
goto err_disable_bus_clk;
|
||||
}
|
||||
|
||||
clk_prepare_enable(backend->mod_clk);
|
||||
|
||||
backend->ram_clk = devm_clk_get(dev, "ram");
|
||||
|
@ -932,6 +939,7 @@ static int sun4i_backend_bind(struct device *dev, struct device *master,
|
|||
err_disable_ram_clk:
|
||||
clk_disable_unprepare(backend->ram_clk);
|
||||
err_disable_mod_clk:
|
||||
clk_rate_exclusive_put(backend->mod_clk);
|
||||
clk_disable_unprepare(backend->mod_clk);
|
||||
err_disable_bus_clk:
|
||||
clk_disable_unprepare(backend->bus_clk);
|
||||
|
@ -952,6 +960,7 @@ static void sun4i_backend_unbind(struct device *dev, struct device *master,
|
|||
sun4i_backend_free_sat(dev);
|
||||
|
||||
clk_disable_unprepare(backend->ram_clk);
|
||||
clk_rate_exclusive_put(backend->mod_clk);
|
||||
clk_disable_unprepare(backend->mod_clk);
|
||||
clk_disable_unprepare(backend->bus_clk);
|
||||
reset_control_assert(backend->reset);
|
||||
|
|
|
@ -56,6 +56,13 @@ static int sun6i_drc_bind(struct device *dev, struct device *master,
|
|||
ret = PTR_ERR(drc->mod_clk);
|
||||
goto err_disable_bus_clk;
|
||||
}
|
||||
|
||||
ret = clk_set_rate_exclusive(drc->mod_clk, 300000000);
|
||||
if (ret) {
|
||||
dev_err(dev, "Couldn't set the module clock frequency\n");
|
||||
goto err_disable_bus_clk;
|
||||
}
|
||||
|
||||
clk_prepare_enable(drc->mod_clk);
|
||||
|
||||
return 0;
|
||||
|
@ -72,6 +79,7 @@ static void sun6i_drc_unbind(struct device *dev, struct device *master,
|
|||
{
|
||||
struct sun6i_drc *drc = dev_get_drvdata(dev);
|
||||
|
||||
clk_rate_exclusive_put(drc->mod_clk);
|
||||
clk_disable_unprepare(drc->mod_clk);
|
||||
clk_disable_unprepare(drc->bus_clk);
|
||||
reset_control_assert(drc->reset);
|
||||
|
|
|
@ -1430,9 +1430,10 @@ static int tegra_hdmi_init(struct host1x_client *client)
|
|||
|
||||
hdmi->output.dev = client->dev;
|
||||
|
||||
drm_connector_init(drm, &hdmi->output.connector,
|
||||
&tegra_hdmi_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_HDMIA);
|
||||
drm_connector_init_with_ddc(drm, &hdmi->output.connector,
|
||||
&tegra_hdmi_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_HDMIA,
|
||||
hdmi->output.ddc);
|
||||
drm_connector_helper_add(&hdmi->output.connector,
|
||||
&tegra_hdmi_connector_helper_funcs);
|
||||
hdmi->output.connector.dpms = DRM_MODE_DPMS_OFF;
|
||||
|
|
|
@ -3086,9 +3086,10 @@ static int tegra_sor_init(struct host1x_client *client)
|
|||
|
||||
sor->output.dev = sor->dev;
|
||||
|
||||
drm_connector_init(drm, &sor->output.connector,
|
||||
&tegra_sor_connector_funcs,
|
||||
connector);
|
||||
drm_connector_init_with_ddc(drm, &sor->output.connector,
|
||||
&tegra_sor_connector_funcs,
|
||||
connector,
|
||||
sor->output.ddc);
|
||||
drm_connector_helper_add(&sor->output.connector,
|
||||
&tegra_sor_connector_helper_funcs);
|
||||
sor->output.connector.dpms = DRM_MODE_DPMS_OFF;
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
config DRM_UDL
|
||||
tristate "DisplayLink"
|
||||
depends on DRM
|
||||
depends on USB_SUPPORT
|
||||
depends on USB
|
||||
depends on USB_ARCH_HAS_HCD
|
||||
select USB
|
||||
select DRM_GEM_SHMEM_HELPER
|
||||
select DRM_KMS_HELPER
|
||||
help
|
||||
|
|
|
@ -753,10 +753,19 @@ static void vc4_dsi_encoder_disable(struct drm_encoder *encoder)
|
|||
struct vc4_dsi_encoder *vc4_encoder = to_vc4_dsi_encoder(encoder);
|
||||
struct vc4_dsi *dsi = vc4_encoder->dsi;
|
||||
struct device *dev = &dsi->pdev->dev;
|
||||
struct drm_bridge *iter;
|
||||
|
||||
list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) {
|
||||
if (iter->funcs->disable)
|
||||
iter->funcs->disable(iter);
|
||||
}
|
||||
|
||||
drm_bridge_chain_disable(dsi->bridge);
|
||||
vc4_dsi_ulps(dsi, true);
|
||||
drm_bridge_chain_post_disable(dsi->bridge);
|
||||
|
||||
list_for_each_entry_from(iter, &dsi->bridge_chain, chain_node) {
|
||||
if (iter->funcs->post_disable)
|
||||
iter->funcs->post_disable(iter);
|
||||
}
|
||||
|
||||
clk_disable_unprepare(dsi->pll_phy_clock);
|
||||
clk_disable_unprepare(dsi->escape_clock);
|
||||
|
@ -824,6 +833,7 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder)
|
|||
struct vc4_dsi *dsi = vc4_encoder->dsi;
|
||||
struct device *dev = &dsi->pdev->dev;
|
||||
bool debug_dump_regs = false;
|
||||
struct drm_bridge *iter;
|
||||
unsigned long hs_clock;
|
||||
u32 ui_ns;
|
||||
/* Minimum LP state duration in escape clock cycles. */
|
||||
|
@ -1056,7 +1066,10 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder)
|
|||
|
||||
vc4_dsi_ulps(dsi, false);
|
||||
|
||||
drm_bridge_chain_pre_enable(dsi->bridge);
|
||||
list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) {
|
||||
if (iter->funcs->pre_enable)
|
||||
iter->funcs->pre_enable(iter);
|
||||
}
|
||||
|
||||
if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
|
||||
DSI_PORT_WRITE(DISP0_CTRL,
|
||||
|
@ -1073,7 +1086,10 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder)
|
|||
DSI_DISP0_ENABLE);
|
||||
}
|
||||
|
||||
drm_bridge_chain_enable(dsi->bridge);
|
||||
list_for_each_entry(iter, &dsi->bridge_chain, chain_node) {
|
||||
if (iter->funcs->enable)
|
||||
iter->funcs->enable(iter);
|
||||
}
|
||||
|
||||
if (debug_dump_regs) {
|
||||
struct drm_printer p = drm_info_printer(&dsi->pdev->dev);
|
||||
|
@ -1613,7 +1629,7 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
|
|||
* from our driver, since we need to sequence them within the
|
||||
* encoder's enable/disable paths.
|
||||
*/
|
||||
list_splice(&dsi->encoder->bridge_chain, &dsi->bridge_chain);
|
||||
list_splice_init(&dsi->encoder->bridge_chain, &dsi->bridge_chain);
|
||||
|
||||
if (dsi->port == 0)
|
||||
vc4_debugfs_add_regset32(drm, "dsi0_regs", &dsi->regset);
|
||||
|
@ -1639,7 +1655,7 @@ static void vc4_dsi_unbind(struct device *dev, struct device *master,
|
|||
* Restore the bridge_chain so the bridge detach procedure can happen
|
||||
* normally.
|
||||
*/
|
||||
list_splice(&dsi->bridge_chain, &dsi->encoder->bridge_chain);
|
||||
list_splice_init(&dsi->bridge_chain, &dsi->encoder->bridge_chain);
|
||||
vc4_dsi_encoder_destroy(dsi->encoder);
|
||||
|
||||
if (dsi->port == 1)
|
||||
|
|
|
@ -267,7 +267,8 @@ static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs =
|
|||
};
|
||||
|
||||
static struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev,
|
||||
struct drm_encoder *encoder)
|
||||
struct drm_encoder *encoder,
|
||||
struct i2c_adapter *ddc)
|
||||
{
|
||||
struct drm_connector *connector;
|
||||
struct vc4_hdmi_connector *hdmi_connector;
|
||||
|
@ -281,8 +282,10 @@ static struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev,
|
|||
|
||||
hdmi_connector->encoder = encoder;
|
||||
|
||||
drm_connector_init(dev, connector, &vc4_hdmi_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_HDMIA);
|
||||
drm_connector_init_with_ddc(dev, connector,
|
||||
&vc4_hdmi_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_HDMIA,
|
||||
ddc);
|
||||
drm_connector_helper_add(connector, &vc4_hdmi_connector_helper_funcs);
|
||||
|
||||
/* Create and attach TV margin props to this connector. */
|
||||
|
@ -1395,7 +1398,8 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
|
|||
DRM_MODE_ENCODER_TMDS, NULL);
|
||||
drm_encoder_helper_add(hdmi->encoder, &vc4_hdmi_encoder_helper_funcs);
|
||||
|
||||
hdmi->connector = vc4_hdmi_connector_init(drm, hdmi->encoder);
|
||||
hdmi->connector =
|
||||
vc4_hdmi_connector_init(drm, hdmi->encoder, hdmi->ddc);
|
||||
if (IS_ERR(hdmi->connector)) {
|
||||
ret = PTR_ERR(hdmi->connector);
|
||||
goto err_destroy_encoder;
|
||||
|
|
|
@ -319,8 +319,10 @@ static int zx_hdmi_register(struct drm_device *drm, struct zx_hdmi *hdmi)
|
|||
|
||||
hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
|
||||
|
||||
drm_connector_init(drm, &hdmi->connector, &zx_hdmi_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_HDMIA);
|
||||
drm_connector_init_with_ddc(drm, &hdmi->connector,
|
||||
&zx_hdmi_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_HDMIA,
|
||||
&hdmi->ddc->adap);
|
||||
drm_connector_helper_add(&hdmi->connector,
|
||||
&zx_hdmi_connector_helper_funcs);
|
||||
|
||||
|
|
|
@ -165,8 +165,10 @@ static int zx_vga_register(struct drm_device *drm, struct zx_vga *vga)
|
|||
|
||||
vga->connector.polled = DRM_CONNECTOR_POLL_HPD;
|
||||
|
||||
ret = drm_connector_init(drm, connector, &zx_vga_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_VGA);
|
||||
ret = drm_connector_init_with_ddc(drm, connector,
|
||||
&zx_vga_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_VGA,
|
||||
&vga->ddc->adap);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(dev, "failed to init connector: %d\n", ret);
|
||||
goto clean_encoder;
|
||||
|
|
|
@ -456,7 +456,6 @@ static int mmphw_probe(struct platform_device *pdev)
|
|||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
dev_err(&pdev->dev, "%s: no IRQ defined\n", __func__);
|
||||
ret = -ENOENT;
|
||||
goto failed;
|
||||
}
|
||||
|
|
|
@ -669,9 +669,6 @@ __drm_atomic_get_current_plane_state(struct drm_atomic_state *state,
|
|||
return plane->state;
|
||||
}
|
||||
|
||||
int __must_check
|
||||
drm_atomic_add_encoder_bridges(struct drm_atomic_state *state,
|
||||
struct drm_encoder *encoder);
|
||||
int __must_check
|
||||
drm_atomic_add_affected_connectors(struct drm_atomic_state *state,
|
||||
struct drm_crtc *crtc);
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
|
||||
#include <linux/list.h>
|
||||
#include <linux/ctype.h>
|
||||
|
||||
#include <drm/drm_atomic.h>
|
||||
#include <drm/drm_encoder.h>
|
||||
#include <drm/drm_mode_object.h>
|
||||
#include <drm/drm_modes.h>
|
||||
|
@ -35,65 +33,6 @@ struct drm_bridge;
|
|||
struct drm_bridge_timings;
|
||||
struct drm_panel;
|
||||
|
||||
/**
|
||||
* struct drm_bus_cfg - bus configuration
|
||||
*
|
||||
* This structure stores the configuration of a physical bus between two
|
||||
* components in an output pipeline, usually between two bridges, an encoder
|
||||
* and a bridge, or a bridge and a connector.
|
||||
*
|
||||
* The bus configuration is stored in &drm_bridge_state separately for the
|
||||
* input and output buses, as seen from the point of view of each bridge. The
|
||||
* bus configuration of a bridge output is usually identical to the
|
||||
* configuration of the next bridge's input, but may differ if the signals are
|
||||
* modified between the two bridges, for instance by an inverter on the board.
|
||||
* The input and output configurations of a bridge may differ if the bridge
|
||||
* modifies the signals internally, for instance by performing format
|
||||
* conversion, or modifying signals polarities.
|
||||
*/
|
||||
struct drm_bus_cfg {
|
||||
/**
|
||||
* @format: format used on this bus (one of the MEDIA_BUS_FMT_* format)
|
||||
*
|
||||
* This field should not be directly modified by drivers
|
||||
* (&drm_atomic_bridge_chain_select_bus_fmts() takes care of the bus
|
||||
* format negotiation).
|
||||
*/
|
||||
u32 format;
|
||||
|
||||
/**
|
||||
* @flags: DRM_BUS_* flags used on this bus
|
||||
*/
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct drm_bridge_state - Atomic bridge state object
|
||||
* @base: inherit from &drm_private_state
|
||||
* @bridge: the bridge this state refers to
|
||||
*/
|
||||
struct drm_bridge_state {
|
||||
struct drm_private_state base;
|
||||
|
||||
struct drm_bridge *bridge;
|
||||
|
||||
/**
|
||||
* @input_bus_cfg: input bus configuration
|
||||
*/
|
||||
struct drm_bus_cfg input_bus_cfg;
|
||||
|
||||
/**
|
||||
* @output_bus_cfg: input bus configuration
|
||||
*/
|
||||
struct drm_bus_cfg output_bus_cfg;
|
||||
};
|
||||
|
||||
static inline struct drm_bridge_state *
|
||||
drm_priv_to_bridge_state(struct drm_private_state *priv)
|
||||
{
|
||||
return container_of(priv, struct drm_bridge_state, base);
|
||||
}
|
||||
|
||||
/**
|
||||
* struct drm_bridge_funcs - drm_bridge control functions
|
||||
*/
|
||||
|
@ -170,9 +109,7 @@ struct drm_bridge_funcs {
|
|||
* this function passes all other callbacks must succeed for this
|
||||
* configuration.
|
||||
*
|
||||
* The mode_fixup callback is optional. &drm_bridge_funcs.mode_fixup()
|
||||
* is not called when &drm_bridge_funcs.atomic_check() is implemented,
|
||||
* so only one of them should be provided.
|
||||
* The @mode_fixup callback is optional.
|
||||
*
|
||||
* NOTE:
|
||||
*
|
||||
|
@ -326,7 +263,7 @@ struct drm_bridge_funcs {
|
|||
* The @atomic_pre_enable callback is optional.
|
||||
*/
|
||||
void (*atomic_pre_enable)(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *old_bridge_state);
|
||||
struct drm_atomic_state *old_state);
|
||||
|
||||
/**
|
||||
* @atomic_enable:
|
||||
|
@ -351,7 +288,7 @@ struct drm_bridge_funcs {
|
|||
* The @atomic_enable callback is optional.
|
||||
*/
|
||||
void (*atomic_enable)(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *old_bridge_state);
|
||||
struct drm_atomic_state *old_state);
|
||||
/**
|
||||
* @atomic_disable:
|
||||
*
|
||||
|
@ -374,7 +311,7 @@ struct drm_bridge_funcs {
|
|||
* The @atomic_disable callback is optional.
|
||||
*/
|
||||
void (*atomic_disable)(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *old_bridge_state);
|
||||
struct drm_atomic_state *old_state);
|
||||
|
||||
/**
|
||||
* @atomic_post_disable:
|
||||
|
@ -400,146 +337,7 @@ struct drm_bridge_funcs {
|
|||
* The @atomic_post_disable callback is optional.
|
||||
*/
|
||||
void (*atomic_post_disable)(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *old_bridge_state);
|
||||
|
||||
/**
|
||||
* @atomic_duplicate_state:
|
||||
*
|
||||
* Duplicate the current bridge state object (which is guaranteed to be
|
||||
* non-NULL).
|
||||
*
|
||||
* The atomic_duplicate_state() is optional. When not implemented the
|
||||
* core allocates a drm_bridge_state object and calls
|
||||
* &__drm_atomic_helper_bridge_duplicate_state() to initialize it.
|
||||
*
|
||||
* RETURNS:
|
||||
* A valid drm_bridge_state object or NULL if the allocation fails.
|
||||
*/
|
||||
struct drm_bridge_state *(*atomic_duplicate_state)(struct drm_bridge *bridge);
|
||||
|
||||
/**
|
||||
* @atomic_destroy_state:
|
||||
*
|
||||
* Destroy a bridge state object previously allocated by
|
||||
* &drm_bridge_funcs.atomic_duplicate_state().
|
||||
*
|
||||
* The atomic_destroy_state hook is optional. When not implemented the
|
||||
* core calls kfree() on the state.
|
||||
*/
|
||||
void (*atomic_destroy_state)(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *state);
|
||||
|
||||
/**
|
||||
* @atomic_get_output_bus_fmts:
|
||||
*
|
||||
* Return the supported bus formats on the output end of a bridge.
|
||||
* The returned array must be allocated with kmalloc() and will be
|
||||
* freed by the caller. If the allocation fails, NULL should be
|
||||
* returned. num_output_fmts must be set to the returned array size.
|
||||
* Formats listed in the returned array should be listed in decreasing
|
||||
* preference order (the core will try all formats until it finds one
|
||||
* that works).
|
||||
*
|
||||
* This method is only called on the last element of the bridge chain
|
||||
* as part of the bus format negotiation process that happens in
|
||||
* &drm_atomic_bridge_chain_select_bus_fmts().
|
||||
* This method is optional. When not implemented, the core will
|
||||
* fall back to &drm_connector.display_info.bus_formats[0] if
|
||||
* &drm_connector.display_info.num_bus_formats > 0,
|
||||
* or to MEDIA_BUS_FMT_FIXED otherwise.
|
||||
*/
|
||||
u32 *(*atomic_get_output_bus_fmts)(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *bridge_state,
|
||||
struct drm_crtc_state *crtc_state,
|
||||
struct drm_connector_state *conn_state,
|
||||
unsigned int *num_output_fmts);
|
||||
|
||||
/**
|
||||
* @atomic_get_input_bus_fmts:
|
||||
*
|
||||
* Return the supported bus formats on the input end of a bridge for
|
||||
* a specific output bus format.
|
||||
*
|
||||
* The returned array must be allocated with kmalloc() and will be
|
||||
* freed by the caller. If the allocation fails, NULL should be
|
||||
* returned. num_output_fmts must be set to the returned array size.
|
||||
* Formats listed in the returned array should be listed in decreasing
|
||||
* preference order (the core will try all formats until it finds one
|
||||
* that works). When the format is not supported NULL should be
|
||||
* returned and *num_output_fmts should be set to 0.
|
||||
*
|
||||
* This method is called on all elements of the bridge chain as part of
|
||||
* the bus format negotiation process that happens in
|
||||
* &drm_atomic_bridge_chain_select_bus_fmts().
|
||||
* This method is optional. When not implemented, the core will bypass
|
||||
* bus format negotiation on this element of the bridge without
|
||||
* failing, and the previous element in the chain will be passed
|
||||
* MEDIA_BUS_FMT_FIXED as its output bus format.
|
||||
*
|
||||
* Bridge drivers that need to support being linked to bridges that are
|
||||
* not supporting bus format negotiation should handle the
|
||||
* output_fmt == MEDIA_BUS_FMT_FIXED case appropriately, by selecting a
|
||||
* sensible default value or extracting this information from somewhere
|
||||
* else (FW property, &drm_display_mode, &drm_display_info, ...)
|
||||
*
|
||||
* Note: Even if input format selection on the first bridge has no
|
||||
* impact on the negotiation process (bus format negotiation stops once
|
||||
* we reach the first element of the chain), drivers are expected to
|
||||
* return accurate input formats as the input format may be used to
|
||||
* configure the CRTC output appropriately.
|
||||
*/
|
||||
u32 *(*atomic_get_input_bus_fmts)(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *bridge_state,
|
||||
struct drm_crtc_state *crtc_state,
|
||||
struct drm_connector_state *conn_state,
|
||||
u32 output_fmt,
|
||||
unsigned int *num_input_fmts);
|
||||
|
||||
/**
|
||||
* @atomic_check:
|
||||
*
|
||||
* This method is responsible for checking bridge state correctness.
|
||||
* It can also check the state of the surrounding components in chain
|
||||
* to make sure the whole pipeline can work properly.
|
||||
*
|
||||
* &drm_bridge_funcs.atomic_check() hooks are called in reverse
|
||||
* order (from the last to the first bridge).
|
||||
*
|
||||
* This method is optional. &drm_bridge_funcs.mode_fixup() is not
|
||||
* called when &drm_bridge_funcs.atomic_check() is implemented, so only
|
||||
* one of them should be provided.
|
||||
*
|
||||
* If drivers need to tweak &drm_bridge_state.input_bus_cfg.flags or
|
||||
* &drm_bridge_state.output_bus_cfg.flags it should should happen in
|
||||
* this function. By default the &drm_bridge_state.output_bus_cfg.flags
|
||||
* field is set to the next bridge
|
||||
* &drm_bridge_state.input_bus_cfg.flags value or
|
||||
* &drm_connector.display_info.bus_flags if the bridge is the last
|
||||
* element in the chain.
|
||||
*
|
||||
* RETURNS:
|
||||
* zero if the check passed, a negative error code otherwise.
|
||||
*/
|
||||
int (*atomic_check)(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *bridge_state,
|
||||
struct drm_crtc_state *crtc_state,
|
||||
struct drm_connector_state *conn_state);
|
||||
|
||||
/**
|
||||
* @atomic_reset:
|
||||
*
|
||||
* Reset the bridge to a predefined state (or retrieve its current
|
||||
* state) and return a &drm_bridge_state object matching this state.
|
||||
* This function is called at attach time.
|
||||
*
|
||||
* The atomic_reset hook is optional. When not implemented the core
|
||||
* allocates a new state and calls &__drm_atomic_helper_bridge_reset().
|
||||
*
|
||||
* RETURNS:
|
||||
* A valid drm_bridge_state object in case of success, an ERR_PTR()
|
||||
* giving the reason of the failure otherwise.
|
||||
*/
|
||||
struct drm_bridge_state *(*atomic_reset)(struct drm_bridge *bridge);
|
||||
struct drm_atomic_state *old_state);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -582,8 +380,6 @@ struct drm_bridge_timings {
|
|||
* struct drm_bridge - central DRM bridge control structure
|
||||
*/
|
||||
struct drm_bridge {
|
||||
/** @base: inherit from &drm_private_object */
|
||||
struct drm_private_obj base;
|
||||
/** @dev: DRM device this bridge belongs to */
|
||||
struct drm_device *dev;
|
||||
/** @encoder: encoder to which this bridge is connected */
|
||||
|
@ -608,12 +404,6 @@ struct drm_bridge {
|
|||
void *driver_private;
|
||||
};
|
||||
|
||||
static inline struct drm_bridge *
|
||||
drm_priv_to_bridge(struct drm_private_obj *priv)
|
||||
{
|
||||
return container_of(priv, struct drm_bridge, base);
|
||||
}
|
||||
|
||||
void drm_bridge_add(struct drm_bridge *bridge);
|
||||
void drm_bridge_remove(struct drm_bridge *bridge);
|
||||
struct drm_bridge *of_drm_find_bridge(struct device_node *np);
|
||||
|
@ -692,9 +482,6 @@ void drm_bridge_chain_mode_set(struct drm_bridge *bridge,
|
|||
void drm_bridge_chain_pre_enable(struct drm_bridge *bridge);
|
||||
void drm_bridge_chain_enable(struct drm_bridge *bridge);
|
||||
|
||||
int drm_atomic_bridge_chain_check(struct drm_bridge *bridge,
|
||||
struct drm_crtc_state *crtc_state,
|
||||
struct drm_connector_state *conn_state);
|
||||
void drm_atomic_bridge_chain_disable(struct drm_bridge *bridge,
|
||||
struct drm_atomic_state *state);
|
||||
void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge,
|
||||
|
@ -704,58 +491,6 @@ void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge,
|
|||
void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge,
|
||||
struct drm_atomic_state *state);
|
||||
|
||||
u32 *
|
||||
drm_atomic_helper_bridge_propagate_bus_fmt(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *bridge_state,
|
||||
struct drm_crtc_state *crtc_state,
|
||||
struct drm_connector_state *conn_state,
|
||||
u32 output_fmt,
|
||||
unsigned int *num_input_fmts);
|
||||
|
||||
void __drm_atomic_helper_bridge_reset(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *state);
|
||||
void __drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge,
|
||||
struct drm_bridge_state *new);
|
||||
|
||||
static inline struct drm_bridge_state *
|
||||
drm_atomic_get_bridge_state(struct drm_atomic_state *state,
|
||||
struct drm_bridge *bridge)
|
||||
{
|
||||
struct drm_private_state *obj_state;
|
||||
|
||||
obj_state = drm_atomic_get_private_obj_state(state, &bridge->base);
|
||||
if (IS_ERR(obj_state))
|
||||
return ERR_CAST(obj_state);
|
||||
|
||||
return drm_priv_to_bridge_state(obj_state);
|
||||
}
|
||||
|
||||
static inline struct drm_bridge_state *
|
||||
drm_atomic_get_old_bridge_state(struct drm_atomic_state *state,
|
||||
struct drm_bridge *bridge)
|
||||
{
|
||||
struct drm_private_state *obj_state;
|
||||
|
||||
obj_state = drm_atomic_get_old_private_obj_state(state, &bridge->base);
|
||||
if (!obj_state)
|
||||
return NULL;
|
||||
|
||||
return drm_priv_to_bridge_state(obj_state);
|
||||
}
|
||||
|
||||
static inline struct drm_bridge_state *
|
||||
drm_atomic_get_new_bridge_state(struct drm_atomic_state *state,
|
||||
struct drm_bridge *bridge)
|
||||
{
|
||||
struct drm_private_state *obj_state;
|
||||
|
||||
obj_state = drm_atomic_get_new_private_obj_state(state, &bridge->base);
|
||||
if (!obj_state)
|
||||
return NULL;
|
||||
|
||||
return drm_priv_to_bridge_state(obj_state);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DRM_PANEL_BRIDGE
|
||||
struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel);
|
||||
struct drm_bridge *drm_panel_bridge_add_typed(struct drm_panel *panel,
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#ifndef __DRM_FB_CMA_HELPER_H__
|
||||
#define __DRM_FB_CMA_HELPER_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct drm_framebuffer;
|
||||
struct drm_plane_state;
|
||||
|
||||
|
|
Loading…
Reference in New Issue