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
|
description: Sancloud Ltd
|
||||||
"^sandisk,.*":
|
"^sandisk,.*":
|
||||||
description: Sandisk Corporation
|
description: Sandisk Corporation
|
||||||
|
"^satoz,.*":
|
||||||
|
description: Satoz International Co., Ltd
|
||||||
"^sbs,.*":
|
"^sbs,.*":
|
||||||
description: Smart Battery System
|
description: Smart Battery System
|
||||||
"^schindler,.*":
|
"^schindler,.*":
|
||||||
|
@ -5357,6 +5357,12 @@ S: Maintained
|
|||||||
F: drivers/gpu/drm/tiny/st7735r.c
|
F: drivers/gpu/drm/tiny/st7735r.c
|
||||||
F: Documentation/devicetree/bindings/display/sitronix,st7735r.txt
|
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
|
DRM DRIVER FOR ST-ERICSSON MCDE
|
||||||
M: Linus Walleij <linus.walleij@linaro.org>
|
M: Linus Walleij <linus.walleij@linaro.org>
|
||||||
T: git git://anongit.freedesktop.org/drm/drm-misc
|
T: git git://anongit.freedesktop.org/drm/drm-misc
|
||||||
|
@ -168,6 +168,7 @@ config DRM_LOAD_EDID_FIRMWARE
|
|||||||
|
|
||||||
config DRM_DP_CEC
|
config DRM_DP_CEC
|
||||||
bool "Enable DisplayPort CEC-Tunneling-over-AUX HDMI support"
|
bool "Enable DisplayPort CEC-Tunneling-over-AUX HDMI support"
|
||||||
|
depends on DRM
|
||||||
select CEC_CORE
|
select CEC_CORE
|
||||||
help
|
help
|
||||||
Choose this option if you want to enable HDMI CEC support for
|
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;
|
return conn_state->crtc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void analogix_dp_bridge_atomic_pre_enable(struct drm_bridge *bridge,
|
||||||
analogix_dp_bridge_atomic_pre_enable(struct drm_bridge *bridge,
|
struct drm_atomic_state *state)
|
||||||
struct drm_bridge_state *old_bridge_state)
|
|
||||||
{
|
{
|
||||||
struct drm_atomic_state *old_state = old_bridge_state->base.state;
|
|
||||||
struct analogix_dp_device *dp = bridge->driver_private;
|
struct analogix_dp_device *dp = bridge->driver_private;
|
||||||
struct drm_crtc *crtc;
|
struct drm_crtc *crtc;
|
||||||
struct drm_crtc_state *old_crtc_state;
|
struct drm_crtc_state *old_crtc_state;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
crtc = analogix_dp_get_new_crtc(dp, old_state);
|
crtc = analogix_dp_get_new_crtc(dp, state);
|
||||||
if (!crtc)
|
if (!crtc)
|
||||||
return;
|
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 */
|
/* Don't touch the panel if we're coming back from PSR */
|
||||||
if (old_crtc_state && old_crtc_state->self_refresh_active)
|
if (old_crtc_state && old_crtc_state->self_refresh_active)
|
||||||
return;
|
return;
|
||||||
@ -1368,22 +1366,20 @@ out_dp_clk_pre:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void analogix_dp_bridge_atomic_enable(struct drm_bridge *bridge,
|
||||||
analogix_dp_bridge_atomic_enable(struct drm_bridge *bridge,
|
struct drm_atomic_state *state)
|
||||||
struct drm_bridge_state *old_bridge_state)
|
|
||||||
{
|
{
|
||||||
struct drm_atomic_state *old_state = old_bridge_state->base.state;
|
|
||||||
struct analogix_dp_device *dp = bridge->driver_private;
|
struct analogix_dp_device *dp = bridge->driver_private;
|
||||||
struct drm_crtc *crtc;
|
struct drm_crtc *crtc;
|
||||||
struct drm_crtc_state *old_crtc_state;
|
struct drm_crtc_state *old_crtc_state;
|
||||||
int timeout_loop = 0;
|
int timeout_loop = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
crtc = analogix_dp_get_new_crtc(dp, old_state);
|
crtc = analogix_dp_get_new_crtc(dp, state);
|
||||||
if (!crtc)
|
if (!crtc)
|
||||||
return;
|
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 */
|
/* Not a full enable, just disable PSR and continue */
|
||||||
if (old_crtc_state && old_crtc_state->self_refresh_active) {
|
if (old_crtc_state && old_crtc_state->self_refresh_active) {
|
||||||
ret = analogix_dp_disable_psr(dp);
|
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;
|
dp->dpms_mode = DRM_MODE_DPMS_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void analogix_dp_bridge_atomic_disable(struct drm_bridge *bridge,
|
||||||
analogix_dp_bridge_atomic_disable(struct drm_bridge *bridge,
|
struct drm_atomic_state *state)
|
||||||
struct drm_bridge_state *old_bridge_state)
|
|
||||||
{
|
{
|
||||||
struct drm_atomic_state *old_state = old_bridge_state->base.state;
|
|
||||||
struct analogix_dp_device *dp = bridge->driver_private;
|
struct analogix_dp_device *dp = bridge->driver_private;
|
||||||
struct drm_crtc *crtc;
|
struct drm_crtc *crtc;
|
||||||
struct drm_crtc_state *new_crtc_state = NULL;
|
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)
|
if (!crtc)
|
||||||
goto out;
|
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)
|
if (!new_crtc_state)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -1469,21 +1463,20 @@ out:
|
|||||||
analogix_dp_bridge_disable(bridge);
|
analogix_dp_bridge_disable(bridge);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static
|
||||||
analogix_dp_bridge_atomic_post_disable(struct drm_bridge *bridge,
|
void analogix_dp_bridge_atomic_post_disable(struct drm_bridge *bridge,
|
||||||
struct drm_bridge_state *old_bridge_state)
|
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 analogix_dp_device *dp = bridge->driver_private;
|
||||||
struct drm_crtc *crtc;
|
struct drm_crtc *crtc;
|
||||||
struct drm_crtc_state *new_crtc_state;
|
struct drm_crtc_state *new_crtc_state;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
crtc = analogix_dp_get_new_crtc(dp, old_state);
|
crtc = analogix_dp_get_new_crtc(dp, state);
|
||||||
if (!crtc)
|
if (!crtc)
|
||||||
return;
|
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)
|
if (!new_crtc_state || !new_crtc_state->self_refresh_active)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -30,7 +30,6 @@
|
|||||||
|
|
||||||
#include <drm/drm_atomic.h>
|
#include <drm/drm_atomic.h>
|
||||||
#include <drm/drm_atomic_uapi.h>
|
#include <drm/drm_atomic_uapi.h>
|
||||||
#include <drm/drm_bridge.h>
|
|
||||||
#include <drm/drm_debugfs.h>
|
#include <drm/drm_debugfs.h>
|
||||||
#include <drm/drm_device.h>
|
#include <drm/drm_device.h>
|
||||||
#include <drm/drm_drv.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);
|
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
|
* drm_atomic_add_affected_connectors - add connectors for CRTC
|
||||||
* @state: atomic state
|
* @state: atomic state
|
||||||
|
@ -437,12 +437,12 @@ mode_fixup(struct drm_atomic_state *state)
|
|||||||
funcs = encoder->helper_private;
|
funcs = encoder->helper_private;
|
||||||
|
|
||||||
bridge = drm_bridge_chain_get_first_bridge(encoder);
|
bridge = drm_bridge_chain_get_first_bridge(encoder);
|
||||||
ret = drm_atomic_bridge_chain_check(bridge,
|
ret = drm_bridge_chain_mode_fixup(bridge,
|
||||||
new_crtc_state,
|
&new_crtc_state->mode,
|
||||||
new_conn_state);
|
&new_crtc_state->adjusted_mode);
|
||||||
if (ret) {
|
if (!ret) {
|
||||||
DRM_DEBUG_ATOMIC("Bridge atomic check failed\n");
|
DRM_DEBUG_ATOMIC("Bridge fixup failed\n");
|
||||||
return ret;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (funcs && funcs->atomic_check) {
|
if (funcs && funcs->atomic_check) {
|
||||||
@ -730,26 +730,6 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
|
|||||||
return ret;
|
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);
|
ret = mode_valid(state);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
|
|
||||||
#include <drm/drm_atomic_state_helper.h>
|
|
||||||
#include <drm/drm_bridge.h>
|
#include <drm/drm_bridge.h>
|
||||||
#include <drm/drm_encoder.h>
|
#include <drm/drm_encoder.h>
|
||||||
|
|
||||||
@ -90,74 +89,6 @@ void drm_bridge_remove(struct drm_bridge *bridge)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_bridge_remove);
|
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
|
* 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,
|
int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
|
||||||
struct drm_bridge *previous)
|
struct drm_bridge *previous)
|
||||||
{
|
{
|
||||||
struct drm_bridge_state *state;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!encoder || !bridge)
|
if (!encoder || !bridge)
|
||||||
@ -205,35 +135,15 @@ int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
|
|||||||
|
|
||||||
if (bridge->funcs->attach) {
|
if (bridge->funcs->attach) {
|
||||||
ret = bridge->funcs->attach(bridge);
|
ret = bridge->funcs->attach(bridge);
|
||||||
if (ret < 0)
|
if (ret < 0) {
|
||||||
goto err_reset_bridge;
|
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;
|
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);
|
EXPORT_SYMBOL(drm_bridge_attach);
|
||||||
|
|
||||||
@ -245,8 +155,6 @@ void drm_bridge_detach(struct drm_bridge *bridge)
|
|||||||
if (WARN_ON(!bridge->dev))
|
if (WARN_ON(!bridge->dev))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
drm_atomic_private_obj_fini(&bridge->base);
|
|
||||||
|
|
||||||
if (bridge->funcs->detach)
|
if (bridge->funcs->detach)
|
||||||
bridge->funcs->detach(bridge);
|
bridge->funcs->detach(bridge);
|
||||||
|
|
||||||
@ -501,19 +409,10 @@ void drm_atomic_bridge_chain_disable(struct drm_bridge *bridge,
|
|||||||
|
|
||||||
encoder = bridge->encoder;
|
encoder = bridge->encoder;
|
||||||
list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) {
|
list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) {
|
||||||
if (iter->funcs->atomic_disable) {
|
if (iter->funcs->atomic_disable)
|
||||||
struct drm_bridge_state *old_bridge_state;
|
iter->funcs->atomic_disable(iter, old_state);
|
||||||
|
else if (iter->funcs->disable)
|
||||||
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) {
|
|
||||||
iter->funcs->disable(iter);
|
iter->funcs->disable(iter);
|
||||||
}
|
|
||||||
|
|
||||||
if (iter == bridge)
|
if (iter == bridge)
|
||||||
break;
|
break;
|
||||||
@ -544,20 +443,10 @@ void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge,
|
|||||||
|
|
||||||
encoder = bridge->encoder;
|
encoder = bridge->encoder;
|
||||||
list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
|
list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
|
||||||
if (bridge->funcs->atomic_post_disable) {
|
if (bridge->funcs->atomic_post_disable)
|
||||||
struct drm_bridge_state *old_bridge_state;
|
bridge->funcs->atomic_post_disable(bridge, old_state);
|
||||||
|
else if (bridge->funcs->post_disable)
|
||||||
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) {
|
|
||||||
bridge->funcs->post_disable(bridge);
|
bridge->funcs->post_disable(bridge);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_atomic_bridge_chain_post_disable);
|
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;
|
encoder = bridge->encoder;
|
||||||
list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) {
|
list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) {
|
||||||
if (iter->funcs->atomic_pre_enable) {
|
if (iter->funcs->atomic_pre_enable)
|
||||||
struct drm_bridge_state *old_bridge_state;
|
iter->funcs->atomic_pre_enable(iter, old_state);
|
||||||
|
else if (iter->funcs->pre_enable)
|
||||||
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) {
|
|
||||||
iter->funcs->pre_enable(iter);
|
iter->funcs->pre_enable(iter);
|
||||||
}
|
|
||||||
|
|
||||||
if (iter == bridge)
|
if (iter == bridge)
|
||||||
break;
|
break;
|
||||||
@ -628,385 +508,14 @@ void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge,
|
|||||||
|
|
||||||
encoder = bridge->encoder;
|
encoder = bridge->encoder;
|
||||||
list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
|
list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
|
||||||
if (bridge->funcs->atomic_enable) {
|
if (bridge->funcs->atomic_enable)
|
||||||
struct drm_bridge_state *old_bridge_state;
|
bridge->funcs->atomic_enable(bridge, old_state);
|
||||||
|
else if (bridge->funcs->enable)
|
||||||
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) {
|
|
||||||
bridge->funcs->enable(bridge);
|
bridge->funcs->enable(bridge);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_atomic_bridge_chain_enable);
|
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
|
#ifdef CONFIG_OF
|
||||||
/**
|
/**
|
||||||
* of_drm_find_bridge - find the bridge corresponding to the device node in
|
* 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))
|
if (IS_ERR(source))
|
||||||
return PTR_ERR(source);
|
return PTR_ERR(source);
|
||||||
|
|
||||||
if (source[len] == '\n')
|
if (source[len - 1] == '\n')
|
||||||
source[len] = '\0';
|
source[len - 1] = '\0';
|
||||||
|
|
||||||
ret = crtc->funcs->verify_crc_source(crtc, source, &values_cnt);
|
ret = crtc->funcs->verify_crc_source(crtc, source, &values_cnt);
|
||||||
if (ret)
|
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 *crtc = filep->f_inode->i_private;
|
||||||
struct drm_crtc_crc *crc = &crtc->crc;
|
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);
|
crtc->funcs->set_crc_source(crtc, NULL);
|
||||||
|
|
||||||
spin_lock_irq(&crc->lock);
|
spin_lock_irq(&crc->lock);
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
* Copyright (C) 2012 Red Hat
|
* Copyright (C) 2012 Red Hat
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <drm/drm_fb_cma_helper.h>
|
||||||
#include <drm/drm_fourcc.h>
|
#include <drm/drm_fourcc.h>
|
||||||
#include <drm/drm_framebuffer.h>
|
#include <drm/drm_framebuffer.h>
|
||||||
#include <drm/drm_gem_cma_helper.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
|
* Since the master is disappearing, so is the
|
||||||
* possibility to lock.
|
* possibility to lock.
|
||||||
*/ mutex_lock(&dev->struct_mutex);
|
*/
|
||||||
|
mutex_lock(&dev->struct_mutex);
|
||||||
if (master->lock.hw_lock) {
|
if (master->lock.hw_lock) {
|
||||||
if (dev->sigdata.lock == master->lock.hw_lock)
|
if (dev->sigdata.lock == master->lock.hw_lock)
|
||||||
dev->sigdata.lock = NULL;
|
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 */
|
/* 3) Nominal HSync width (% of line period) - default 8 */
|
||||||
#define CVT_HSYNC_PERCENTAGE 8
|
#define CVT_HSYNC_PERCENTAGE 8
|
||||||
unsigned int hblank_percentage;
|
unsigned int hblank_percentage;
|
||||||
int vsyncandback_porch, vback_porch, hblank;
|
int vsyncandback_porch, __maybe_unused vback_porch, hblank;
|
||||||
|
|
||||||
/* estimated the horizontal period */
|
/* estimated the horizontal period */
|
||||||
tmp1 = HV_FACTOR * 1000000 -
|
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 top_margin, bottom_margin;
|
||||||
int interlace;
|
int interlace;
|
||||||
unsigned int hfreq_est;
|
unsigned int hfreq_est;
|
||||||
int vsync_plus_bp, vback_porch;
|
int vsync_plus_bp, __maybe_unused vback_porch;
|
||||||
unsigned int vtotal_lines, vfieldrate_est, hperiod;
|
unsigned int vtotal_lines, __maybe_unused vfieldrate_est;
|
||||||
unsigned int vfield_rate, vframe_rate;
|
unsigned int __maybe_unused hperiod;
|
||||||
|
unsigned int vfield_rate, __maybe_unused vframe_rate;
|
||||||
int left_margin, right_margin;
|
int left_margin, right_margin;
|
||||||
unsigned int total_active_pixels, ideal_duty_cycle;
|
unsigned int total_active_pixels, ideal_duty_cycle;
|
||||||
unsigned int hblank, total_pixels, pixel_freq;
|
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)
|
static void exynos_dsi_enable(struct drm_encoder *encoder)
|
||||||
{
|
{
|
||||||
struct exynos_dsi *dsi = encoder_to_dsi(encoder);
|
struct exynos_dsi *dsi = encoder_to_dsi(encoder);
|
||||||
|
struct drm_bridge *iter;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (dsi->state & DSIM_STATE_ENABLED)
|
if (dsi->state & DSIM_STATE_ENABLED)
|
||||||
@ -1391,7 +1392,11 @@ static void exynos_dsi_enable(struct drm_encoder *encoder)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err_put_sync;
|
goto err_put_sync;
|
||||||
} else {
|
} 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);
|
exynos_dsi_set_display_mode(dsi);
|
||||||
@ -1402,7 +1407,10 @@ static void exynos_dsi_enable(struct drm_encoder *encoder)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err_display_disable;
|
goto err_display_disable;
|
||||||
} else {
|
} 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;
|
dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;
|
||||||
@ -1420,6 +1428,7 @@ err_put_sync:
|
|||||||
static void exynos_dsi_disable(struct drm_encoder *encoder)
|
static void exynos_dsi_disable(struct drm_encoder *encoder)
|
||||||
{
|
{
|
||||||
struct exynos_dsi *dsi = encoder_to_dsi(encoder);
|
struct exynos_dsi *dsi = encoder_to_dsi(encoder);
|
||||||
|
struct drm_bridge *iter;
|
||||||
|
|
||||||
if (!(dsi->state & DSIM_STATE_ENABLED))
|
if (!(dsi->state & DSIM_STATE_ENABLED))
|
||||||
return;
|
return;
|
||||||
@ -1427,10 +1436,20 @@ static void exynos_dsi_disable(struct drm_encoder *encoder)
|
|||||||
dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE;
|
dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE;
|
||||||
|
|
||||||
drm_panel_disable(dsi->panel);
|
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);
|
exynos_dsi_set_display_enable(dsi, false);
|
||||||
drm_panel_unprepare(dsi->panel);
|
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;
|
dsi->state &= ~DSIM_STATE_ENABLED;
|
||||||
pm_runtime_put_sync(dsi->dev);
|
pm_runtime_put_sync(dsi->dev);
|
||||||
}
|
}
|
||||||
@ -1523,7 +1542,7 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
|
|||||||
if (out_bridge) {
|
if (out_bridge) {
|
||||||
drm_bridge_attach(encoder, out_bridge, NULL);
|
drm_bridge_attach(encoder, out_bridge, NULL);
|
||||||
dsi->out_bridge = out_bridge;
|
dsi->out_bridge = out_bridge;
|
||||||
list_splice(&encoder->bridge_chain, &dsi->bridge_chain);
|
list_splice_init(&encoder->bridge_chain, &dsi->bridge_chain);
|
||||||
} else {
|
} else {
|
||||||
int ret = exynos_dsi_create_connector(encoder);
|
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_priv =
|
||||||
(struct drm_psb_private *) dev->dev_private;
|
(struct drm_psb_private *) dev->dev_private;
|
||||||
u32 hist_reg;
|
|
||||||
u32 pwm_reg;
|
u32 pwm_reg;
|
||||||
|
|
||||||
if (gma_power_begin(dev, false)) {
|
if (gma_power_begin(dev, false)) {
|
||||||
PSB_WVDC32(0x00000000, HISTOGRAM_INT_CONTROL);
|
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);
|
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;
|
return task->fence;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lima_sched_handle_error_task(struct lima_sched_pipe *pipe,
|
static void lima_sched_timedout_job(struct drm_sched_job *job)
|
||||||
struct lima_sched_task *task)
|
|
||||||
{
|
{
|
||||||
|
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);
|
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);
|
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);
|
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)
|
static void lima_sched_free_job(struct drm_sched_job *job)
|
||||||
{
|
{
|
||||||
struct lima_sched_task *task = to_lima_task(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,
|
.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)
|
int lima_sched_pipe_init(struct lima_sched_pipe *pipe, const char *name)
|
||||||
{
|
{
|
||||||
unsigned int timeout = lima_sched_timeout_ms > 0 ?
|
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);
|
pipe->fence_context = dma_fence_context_alloc(1);
|
||||||
spin_lock_init(&pipe->fence_lock);
|
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,
|
return drm_sched_init(&pipe->base, &lima_sched_ops, 1, 0,
|
||||||
msecs_to_jiffies(timeout), name);
|
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)
|
void lima_sched_pipe_task_done(struct lima_sched_pipe *pipe)
|
||||||
{
|
{
|
||||||
if (pipe->error)
|
if (pipe->error)
|
||||||
schedule_work(&pipe->error_work);
|
drm_sched_fault(&pipe->base);
|
||||||
else {
|
else {
|
||||||
struct lima_sched_task *task = pipe->current_task;
|
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_fini)(struct lima_sched_pipe *pipe);
|
||||||
void (*task_error)(struct lima_sched_pipe *pipe);
|
void (*task_error)(struct lima_sched_pipe *pipe);
|
||||||
void (*task_mmu_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,
|
int lima_sched_task_init(struct lima_sched_task *task,
|
||||||
|
@ -135,7 +135,7 @@ struct meson_drm {
|
|||||||
} venc;
|
} venc;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
dma_addr_t addr_phys;
|
dma_addr_t addr_dma;
|
||||||
uint32_t *addr;
|
uint32_t *addr;
|
||||||
unsigned int offset;
|
unsigned int offset;
|
||||||
} rdma;
|
} rdma;
|
||||||
|
@ -27,7 +27,7 @@ int meson_rdma_init(struct meson_drm *priv)
|
|||||||
/* Allocate a PAGE buffer */
|
/* Allocate a PAGE buffer */
|
||||||
priv->rdma.addr =
|
priv->rdma.addr =
|
||||||
dma_alloc_coherent(priv->dev, SZ_4K,
|
dma_alloc_coherent(priv->dev, SZ_4K,
|
||||||
&priv->rdma.addr_phys,
|
&priv->rdma.addr_dma,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!priv->rdma.addr)
|
if (!priv->rdma.addr)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -47,16 +47,16 @@ int meson_rdma_init(struct meson_drm *priv)
|
|||||||
|
|
||||||
void meson_rdma_free(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;
|
return;
|
||||||
|
|
||||||
meson_rdma_stop(priv);
|
meson_rdma_stop(priv);
|
||||||
|
|
||||||
dma_free_coherent(priv->dev, SZ_4K,
|
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 = 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)
|
void meson_rdma_setup(struct meson_drm *priv)
|
||||||
@ -118,11 +118,11 @@ void meson_rdma_flush(struct meson_drm *priv)
|
|||||||
meson_rdma_stop(priv);
|
meson_rdma_stop(priv);
|
||||||
|
|
||||||
/* Start of Channel 1 register writes buffer */
|
/* 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));
|
priv->io_base + _REG(RDMA_AHB_START_ADDR_1));
|
||||||
|
|
||||||
/* Last byte on Channel 1 register writes buffer */
|
/* 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));
|
priv->io_base + _REG(RDMA_AHB_END_ADDR_1));
|
||||||
|
|
||||||
/* Trigger Channel 1 on VSYNC event */
|
/* 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,
|
enum dispc_feat_reg_field id,
|
||||||
u8 *start, u8 *end)
|
u8 *start, u8 *end)
|
||||||
{
|
{
|
||||||
if (id >= dispc->feat->num_reg_fields)
|
BUG_ON(id >= dispc->feat->num_reg_fields);
|
||||||
BUG();
|
|
||||||
|
|
||||||
*start = dispc->feat->reg_fields[id].start;
|
*start = dispc->feat->reg_fields[id].start;
|
||||||
*end = dispc->feat->reg_fields[id].end;
|
*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
|
Say Y here if you want to enable support for the Sitronix
|
||||||
ST7789V controller for 240x320 LCD panels
|
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
|
config DRM_PANEL_SONY_ACX565AKM
|
||||||
tristate "Sony ACX565AKM panel"
|
tristate "Sony ACX565AKM panel"
|
||||||
depends on GPIOLIB && OF && SPI
|
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_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o
|
||||||
obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7701) += panel-sitronix-st7701.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_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_SONY_ACX565AKM) += panel-sony-acx565akm.o
|
||||||
obj-$(CONFIG_DRM_PANEL_TPO_TD028TTEC1) += panel-tpo-td028ttec1.o
|
obj-$(CONFIG_DRM_PANEL_TPO_TD028TTEC1) += panel-tpo-td028ttec1.o
|
||||||
obj-$(CONFIG_DRM_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.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 = {
|
static const struct drm_display_mode auo_b116xw03_mode = {
|
||||||
.clock = 70589,
|
.clock = 70589,
|
||||||
.hdisplay = 1366,
|
.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 = {
|
static const struct drm_display_mode cdtech_s043wq26h_ct7_mode = {
|
||||||
.clock = 9000,
|
.clock = 9000,
|
||||||
.hdisplay = 480,
|
.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 = {
|
static const struct drm_display_mode sharp_ld_d5116z01b_mode = {
|
||||||
.clock = 168480,
|
.clock = 168480,
|
||||||
.hdisplay = 1920,
|
.hdisplay = 1920,
|
||||||
@ -3125,6 +3210,9 @@ static const struct of_device_id platform_of_match[] = {
|
|||||||
}, {
|
}, {
|
||||||
.compatible = "auo,b101xtn01",
|
.compatible = "auo,b101xtn01",
|
||||||
.data = &auo_b101xtn01,
|
.data = &auo_b101xtn01,
|
||||||
|
}, {
|
||||||
|
.compatible = "auo,b116xa01",
|
||||||
|
.data = &auo_b116xak01,
|
||||||
}, {
|
}, {
|
||||||
.compatible = "auo,b116xw03",
|
.compatible = "auo,b116xw03",
|
||||||
.data = &auo_b116xw03,
|
.data = &auo_b116xw03,
|
||||||
@ -3167,6 +3255,9 @@ static const struct of_device_id platform_of_match[] = {
|
|||||||
}, {
|
}, {
|
||||||
.compatible = "boe,nv101wxmn51",
|
.compatible = "boe,nv101wxmn51",
|
||||||
.data = &boe_nv101wxmn51,
|
.data = &boe_nv101wxmn51,
|
||||||
|
}, {
|
||||||
|
.compatible = "boe,nv140fhmn49",
|
||||||
|
.data = &boe_nv140fhmn49,
|
||||||
}, {
|
}, {
|
||||||
.compatible = "cdtech,s043wq26h-ct7",
|
.compatible = "cdtech,s043wq26h-ct7",
|
||||||
.data = &cdtech_s043wq26h_ct7,
|
.data = &cdtech_s043wq26h_ct7,
|
||||||
@ -3356,6 +3447,9 @@ static const struct of_device_id platform_of_match[] = {
|
|||||||
}, {
|
}, {
|
||||||
.compatible = "samsung,ltn140at29-301",
|
.compatible = "samsung,ltn140at29-301",
|
||||||
.data = &samsung_ltn140at29_301,
|
.data = &samsung_ltn140at29_301,
|
||||||
|
}, {
|
||||||
|
.compatible = "satoz,sat050at40h12r2",
|
||||||
|
.data = &satoz_sat050at40h12r2,
|
||||||
}, {
|
}, {
|
||||||
.compatible = "sharp,ld-d5116z01b",
|
.compatible = "sharp,ld-d5116z01b",
|
||||||
.data = &sharp_ld_d5116z01b,
|
.data = &sharp_ld_d5116z01b,
|
||||||
|
550
drivers/gpu/drm/panel/panel-sony-acx424akp.c
Normal file
550
drivers/gpu/drm/panel/panel-sony-acx424akp.c
Normal file
@ -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,
|
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_connector *connector;
|
||||||
struct drm_crtc *crtc;
|
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,
|
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);
|
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. */
|
/* Disable the companion LVDS encoder in dual-link mode. */
|
||||||
if (lvds->link_type != RCAR_LVDS_SINGLE_LINK && lvds->companion)
|
if (lvds->link_type != RCAR_LVDS_SINGLE_LINK && lvds->companion)
|
||||||
lvds->companion->funcs->atomic_disable(lvds->companion,
|
lvds->companion->funcs->atomic_disable(lvds->companion, state);
|
||||||
old_bridge_state);
|
|
||||||
|
|
||||||
clk_disable_unprepare(lvds->clocks.mod);
|
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);
|
ret = PTR_ERR(backend->mod_clk);
|
||||||
goto err_disable_bus_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);
|
clk_prepare_enable(backend->mod_clk);
|
||||||
|
|
||||||
backend->ram_clk = devm_clk_get(dev, "ram");
|
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:
|
err_disable_ram_clk:
|
||||||
clk_disable_unprepare(backend->ram_clk);
|
clk_disable_unprepare(backend->ram_clk);
|
||||||
err_disable_mod_clk:
|
err_disable_mod_clk:
|
||||||
|
clk_rate_exclusive_put(backend->mod_clk);
|
||||||
clk_disable_unprepare(backend->mod_clk);
|
clk_disable_unprepare(backend->mod_clk);
|
||||||
err_disable_bus_clk:
|
err_disable_bus_clk:
|
||||||
clk_disable_unprepare(backend->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);
|
sun4i_backend_free_sat(dev);
|
||||||
|
|
||||||
clk_disable_unprepare(backend->ram_clk);
|
clk_disable_unprepare(backend->ram_clk);
|
||||||
|
clk_rate_exclusive_put(backend->mod_clk);
|
||||||
clk_disable_unprepare(backend->mod_clk);
|
clk_disable_unprepare(backend->mod_clk);
|
||||||
clk_disable_unprepare(backend->bus_clk);
|
clk_disable_unprepare(backend->bus_clk);
|
||||||
reset_control_assert(backend->reset);
|
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);
|
ret = PTR_ERR(drc->mod_clk);
|
||||||
goto err_disable_bus_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);
|
clk_prepare_enable(drc->mod_clk);
|
||||||
|
|
||||||
return 0;
|
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);
|
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->mod_clk);
|
||||||
clk_disable_unprepare(drc->bus_clk);
|
clk_disable_unprepare(drc->bus_clk);
|
||||||
reset_control_assert(drc->reset);
|
reset_control_assert(drc->reset);
|
||||||
|
@ -1430,9 +1430,10 @@ static int tegra_hdmi_init(struct host1x_client *client)
|
|||||||
|
|
||||||
hdmi->output.dev = client->dev;
|
hdmi->output.dev = client->dev;
|
||||||
|
|
||||||
drm_connector_init(drm, &hdmi->output.connector,
|
drm_connector_init_with_ddc(drm, &hdmi->output.connector,
|
||||||
&tegra_hdmi_connector_funcs,
|
&tegra_hdmi_connector_funcs,
|
||||||
DRM_MODE_CONNECTOR_HDMIA);
|
DRM_MODE_CONNECTOR_HDMIA,
|
||||||
|
hdmi->output.ddc);
|
||||||
drm_connector_helper_add(&hdmi->output.connector,
|
drm_connector_helper_add(&hdmi->output.connector,
|
||||||
&tegra_hdmi_connector_helper_funcs);
|
&tegra_hdmi_connector_helper_funcs);
|
||||||
hdmi->output.connector.dpms = DRM_MODE_DPMS_OFF;
|
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;
|
sor->output.dev = sor->dev;
|
||||||
|
|
||||||
drm_connector_init(drm, &sor->output.connector,
|
drm_connector_init_with_ddc(drm, &sor->output.connector,
|
||||||
&tegra_sor_connector_funcs,
|
&tegra_sor_connector_funcs,
|
||||||
connector);
|
connector,
|
||||||
|
sor->output.ddc);
|
||||||
drm_connector_helper_add(&sor->output.connector,
|
drm_connector_helper_add(&sor->output.connector,
|
||||||
&tegra_sor_connector_helper_funcs);
|
&tegra_sor_connector_helper_funcs);
|
||||||
sor->output.connector.dpms = DRM_MODE_DPMS_OFF;
|
sor->output.connector.dpms = DRM_MODE_DPMS_OFF;
|
||||||
|
@ -2,9 +2,8 @@
|
|||||||
config DRM_UDL
|
config DRM_UDL
|
||||||
tristate "DisplayLink"
|
tristate "DisplayLink"
|
||||||
depends on DRM
|
depends on DRM
|
||||||
depends on USB_SUPPORT
|
depends on USB
|
||||||
depends on USB_ARCH_HAS_HCD
|
depends on USB_ARCH_HAS_HCD
|
||||||
select USB
|
|
||||||
select DRM_GEM_SHMEM_HELPER
|
select DRM_GEM_SHMEM_HELPER
|
||||||
select DRM_KMS_HELPER
|
select DRM_KMS_HELPER
|
||||||
help
|
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_encoder *vc4_encoder = to_vc4_dsi_encoder(encoder);
|
||||||
struct vc4_dsi *dsi = vc4_encoder->dsi;
|
struct vc4_dsi *dsi = vc4_encoder->dsi;
|
||||||
struct device *dev = &dsi->pdev->dev;
|
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);
|
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->pll_phy_clock);
|
||||||
clk_disable_unprepare(dsi->escape_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 vc4_dsi *dsi = vc4_encoder->dsi;
|
||||||
struct device *dev = &dsi->pdev->dev;
|
struct device *dev = &dsi->pdev->dev;
|
||||||
bool debug_dump_regs = false;
|
bool debug_dump_regs = false;
|
||||||
|
struct drm_bridge *iter;
|
||||||
unsigned long hs_clock;
|
unsigned long hs_clock;
|
||||||
u32 ui_ns;
|
u32 ui_ns;
|
||||||
/* Minimum LP state duration in escape clock cycles. */
|
/* 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);
|
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) {
|
if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
|
||||||
DSI_PORT_WRITE(DISP0_CTRL,
|
DSI_PORT_WRITE(DISP0_CTRL,
|
||||||
@ -1073,7 +1086,10 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder)
|
|||||||
DSI_DISP0_ENABLE);
|
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) {
|
if (debug_dump_regs) {
|
||||||
struct drm_printer p = drm_info_printer(&dsi->pdev->dev);
|
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
|
* from our driver, since we need to sequence them within the
|
||||||
* encoder's enable/disable paths.
|
* 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)
|
if (dsi->port == 0)
|
||||||
vc4_debugfs_add_regset32(drm, "dsi0_regs", &dsi->regset);
|
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
|
* Restore the bridge_chain so the bridge detach procedure can happen
|
||||||
* normally.
|
* 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);
|
vc4_dsi_encoder_destroy(dsi->encoder);
|
||||||
|
|
||||||
if (dsi->port == 1)
|
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,
|
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 drm_connector *connector;
|
||||||
struct vc4_hdmi_connector *hdmi_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;
|
hdmi_connector->encoder = encoder;
|
||||||
|
|
||||||
drm_connector_init(dev, connector, &vc4_hdmi_connector_funcs,
|
drm_connector_init_with_ddc(dev, connector,
|
||||||
DRM_MODE_CONNECTOR_HDMIA);
|
&vc4_hdmi_connector_funcs,
|
||||||
|
DRM_MODE_CONNECTOR_HDMIA,
|
||||||
|
ddc);
|
||||||
drm_connector_helper_add(connector, &vc4_hdmi_connector_helper_funcs);
|
drm_connector_helper_add(connector, &vc4_hdmi_connector_helper_funcs);
|
||||||
|
|
||||||
/* Create and attach TV margin props to this connector. */
|
/* 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_MODE_ENCODER_TMDS, NULL);
|
||||||
drm_encoder_helper_add(hdmi->encoder, &vc4_hdmi_encoder_helper_funcs);
|
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)) {
|
if (IS_ERR(hdmi->connector)) {
|
||||||
ret = PTR_ERR(hdmi->connector);
|
ret = PTR_ERR(hdmi->connector);
|
||||||
goto err_destroy_encoder;
|
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;
|
hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
|
||||||
|
|
||||||
drm_connector_init(drm, &hdmi->connector, &zx_hdmi_connector_funcs,
|
drm_connector_init_with_ddc(drm, &hdmi->connector,
|
||||||
DRM_MODE_CONNECTOR_HDMIA);
|
&zx_hdmi_connector_funcs,
|
||||||
|
DRM_MODE_CONNECTOR_HDMIA,
|
||||||
|
&hdmi->ddc->adap);
|
||||||
drm_connector_helper_add(&hdmi->connector,
|
drm_connector_helper_add(&hdmi->connector,
|
||||||
&zx_hdmi_connector_helper_funcs);
|
&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;
|
vga->connector.polled = DRM_CONNECTOR_POLL_HPD;
|
||||||
|
|
||||||
ret = drm_connector_init(drm, connector, &zx_vga_connector_funcs,
|
ret = drm_connector_init_with_ddc(drm, connector,
|
||||||
DRM_MODE_CONNECTOR_VGA);
|
&zx_vga_connector_funcs,
|
||||||
|
DRM_MODE_CONNECTOR_VGA,
|
||||||
|
&vga->ddc->adap);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
DRM_DEV_ERROR(dev, "failed to init connector: %d\n", ret);
|
DRM_DEV_ERROR(dev, "failed to init connector: %d\n", ret);
|
||||||
goto clean_encoder;
|
goto clean_encoder;
|
||||||
|
@ -456,7 +456,6 @@ static int mmphw_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
irq = platform_get_irq(pdev, 0);
|
irq = platform_get_irq(pdev, 0);
|
||||||
if (irq < 0) {
|
if (irq < 0) {
|
||||||
dev_err(&pdev->dev, "%s: no IRQ defined\n", __func__);
|
|
||||||
ret = -ENOENT;
|
ret = -ENOENT;
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
@ -669,9 +669,6 @@ __drm_atomic_get_current_plane_state(struct drm_atomic_state *state,
|
|||||||
return plane->state;
|
return plane->state;
|
||||||
}
|
}
|
||||||
|
|
||||||
int __must_check
|
|
||||||
drm_atomic_add_encoder_bridges(struct drm_atomic_state *state,
|
|
||||||
struct drm_encoder *encoder);
|
|
||||||
int __must_check
|
int __must_check
|
||||||
drm_atomic_add_affected_connectors(struct drm_atomic_state *state,
|
drm_atomic_add_affected_connectors(struct drm_atomic_state *state,
|
||||||
struct drm_crtc *crtc);
|
struct drm_crtc *crtc);
|
||||||
|
@ -25,8 +25,6 @@
|
|||||||
|
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/ctype.h>
|
#include <linux/ctype.h>
|
||||||
|
|
||||||
#include <drm/drm_atomic.h>
|
|
||||||
#include <drm/drm_encoder.h>
|
#include <drm/drm_encoder.h>
|
||||||
#include <drm/drm_mode_object.h>
|
#include <drm/drm_mode_object.h>
|
||||||
#include <drm/drm_modes.h>
|
#include <drm/drm_modes.h>
|
||||||
@ -35,65 +33,6 @@ struct drm_bridge;
|
|||||||
struct drm_bridge_timings;
|
struct drm_bridge_timings;
|
||||||
struct drm_panel;
|
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
|
* 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
|
* this function passes all other callbacks must succeed for this
|
||||||
* configuration.
|
* configuration.
|
||||||
*
|
*
|
||||||
* The mode_fixup callback is optional. &drm_bridge_funcs.mode_fixup()
|
* The @mode_fixup callback is optional.
|
||||||
* is not called when &drm_bridge_funcs.atomic_check() is implemented,
|
|
||||||
* so only one of them should be provided.
|
|
||||||
*
|
*
|
||||||
* NOTE:
|
* NOTE:
|
||||||
*
|
*
|
||||||
@ -326,7 +263,7 @@ struct drm_bridge_funcs {
|
|||||||
* The @atomic_pre_enable callback is optional.
|
* The @atomic_pre_enable callback is optional.
|
||||||
*/
|
*/
|
||||||
void (*atomic_pre_enable)(struct drm_bridge *bridge,
|
void (*atomic_pre_enable)(struct drm_bridge *bridge,
|
||||||
struct drm_bridge_state *old_bridge_state);
|
struct drm_atomic_state *old_state);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @atomic_enable:
|
* @atomic_enable:
|
||||||
@ -351,7 +288,7 @@ struct drm_bridge_funcs {
|
|||||||
* The @atomic_enable callback is optional.
|
* The @atomic_enable callback is optional.
|
||||||
*/
|
*/
|
||||||
void (*atomic_enable)(struct drm_bridge *bridge,
|
void (*atomic_enable)(struct drm_bridge *bridge,
|
||||||
struct drm_bridge_state *old_bridge_state);
|
struct drm_atomic_state *old_state);
|
||||||
/**
|
/**
|
||||||
* @atomic_disable:
|
* @atomic_disable:
|
||||||
*
|
*
|
||||||
@ -374,7 +311,7 @@ struct drm_bridge_funcs {
|
|||||||
* The @atomic_disable callback is optional.
|
* The @atomic_disable callback is optional.
|
||||||
*/
|
*/
|
||||||
void (*atomic_disable)(struct drm_bridge *bridge,
|
void (*atomic_disable)(struct drm_bridge *bridge,
|
||||||
struct drm_bridge_state *old_bridge_state);
|
struct drm_atomic_state *old_state);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @atomic_post_disable:
|
* @atomic_post_disable:
|
||||||
@ -400,146 +337,7 @@ struct drm_bridge_funcs {
|
|||||||
* The @atomic_post_disable callback is optional.
|
* The @atomic_post_disable callback is optional.
|
||||||
*/
|
*/
|
||||||
void (*atomic_post_disable)(struct drm_bridge *bridge,
|
void (*atomic_post_disable)(struct drm_bridge *bridge,
|
||||||
struct drm_bridge_state *old_bridge_state);
|
struct drm_atomic_state *old_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);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -582,8 +380,6 @@ struct drm_bridge_timings {
|
|||||||
* struct drm_bridge - central DRM bridge control structure
|
* struct drm_bridge - central DRM bridge control structure
|
||||||
*/
|
*/
|
||||||
struct drm_bridge {
|
struct drm_bridge {
|
||||||
/** @base: inherit from &drm_private_object */
|
|
||||||
struct drm_private_obj base;
|
|
||||||
/** @dev: DRM device this bridge belongs to */
|
/** @dev: DRM device this bridge belongs to */
|
||||||
struct drm_device *dev;
|
struct drm_device *dev;
|
||||||
/** @encoder: encoder to which this bridge is connected */
|
/** @encoder: encoder to which this bridge is connected */
|
||||||
@ -608,12 +404,6 @@ struct drm_bridge {
|
|||||||
void *driver_private;
|
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_add(struct drm_bridge *bridge);
|
||||||
void drm_bridge_remove(struct drm_bridge *bridge);
|
void drm_bridge_remove(struct drm_bridge *bridge);
|
||||||
struct drm_bridge *of_drm_find_bridge(struct device_node *np);
|
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_pre_enable(struct drm_bridge *bridge);
|
||||||
void drm_bridge_chain_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,
|
void drm_atomic_bridge_chain_disable(struct drm_bridge *bridge,
|
||||||
struct drm_atomic_state *state);
|
struct drm_atomic_state *state);
|
||||||
void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge,
|
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,
|
void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge,
|
||||||
struct drm_atomic_state *state);
|
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
|
#ifdef CONFIG_DRM_PANEL_BRIDGE
|
||||||
struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel);
|
struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel);
|
||||||
struct drm_bridge *drm_panel_bridge_add_typed(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__
|
#ifndef __DRM_FB_CMA_HELPER_H__
|
||||||
#define __DRM_FB_CMA_HELPER_H__
|
#define __DRM_FB_CMA_HELPER_H__
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
struct drm_framebuffer;
|
struct drm_framebuffer;
|
||||||
struct drm_plane_state;
|
struct drm_plane_state;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user