Commit 7f7a942c authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-next-20221025' of git://linuxtv.org/pinchartl/media into drm-next

Xilinx ZynqMP DisplayPort bridge support
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Link: https://patchwork.freedesktop.org/patch/msgid/Y1cdU4HJoy0Pr2sQ@pendragon.ideasonboard.com
parents 0a20a3ea ddcb8fa6
...@@ -117,6 +117,45 @@ properties: ...@@ -117,6 +117,45 @@ properties:
- const: dp-phy0 - const: dp-phy0
- const: dp-phy1 - const: dp-phy1
ports:
$ref: /schemas/graph.yaml#/properties/ports
description: |
Connections to the programmable logic and the DisplayPort PHYs. Each port
shall have a single endpoint.
properties:
port@0:
$ref: /schemas/graph.yaml#/properties/port
description: The live video input from the programmable logic
port@1:
$ref: /schemas/graph.yaml#/properties/port
description: The live graphics input from the programmable logic
port@2:
$ref: /schemas/graph.yaml#/properties/port
description: The live audio input from the programmable logic
port@3:
$ref: /schemas/graph.yaml#/properties/port
description: The blended video output to the programmable logic
port@4:
$ref: /schemas/graph.yaml#/properties/port
description: The mixed audio output to the programmable logic
port@5:
$ref: /schemas/graph.yaml#/properties/port
description: The DisplayPort output
required:
- port@0
- port@1
- port@2
- port@3
- port@4
- port@5
required: required:
- compatible - compatible
- reg - reg
...@@ -130,6 +169,7 @@ required: ...@@ -130,6 +169,7 @@ required:
- dma-names - dma-names
- phys - phys
- phy-names - phy-names
- ports
additionalProperties: false additionalProperties: false
...@@ -164,6 +204,33 @@ examples: ...@@ -164,6 +204,33 @@ examples:
<&psgtr 0 PHY_TYPE_DP 1 3>; <&psgtr 0 PHY_TYPE_DP 1 3>;
phy-names = "dp-phy0", "dp-phy1"; phy-names = "dp-phy0", "dp-phy1";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
};
port@1 {
reg = <1>;
};
port@2 {
reg = <2>;
};
port@3 {
reg = <3>;
};
port@4 {
reg = <4>;
};
port@5 {
reg = <5>;
dpsub_dp_out: endpoint {
remote-endpoint = <&dp_connector>;
};
};
};
}; };
... ...
...@@ -150,6 +150,18 @@ refhdmi: refhdmi { ...@@ -150,6 +150,18 @@ refhdmi: refhdmi {
#clock-cells = <0>; #clock-cells = <0>;
clock-frequency = <114285000>; clock-frequency = <114285000>;
}; };
dpcon {
compatible = "dp-connector";
label = "P11";
type = "full-size";
port {
dpcon_in: endpoint {
remote-endpoint = <&dpsub_dp_out>;
};
};
};
}; };
&can1 { &can1 {
...@@ -1015,4 +1027,12 @@ &zynqmp_dpsub { ...@@ -1015,4 +1027,12 @@ &zynqmp_dpsub {
phy-names = "dp-phy0", "dp-phy1"; phy-names = "dp-phy0", "dp-phy1";
phys = <&psgtr 1 PHY_TYPE_DP 0 3>, phys = <&psgtr 1 PHY_TYPE_DP 0 3>,
<&psgtr 0 PHY_TYPE_DP 1 3>; <&psgtr 0 PHY_TYPE_DP 1 3>;
ports {
port@5 {
dpsub_dp_out: endpoint {
remote-endpoint = <&dpcon_in>;
};
};
};
}; };
...@@ -930,6 +930,30 @@ zynqmp_dpsub: display@fd4a0000 { ...@@ -930,6 +930,30 @@ zynqmp_dpsub: display@fd4a0000 {
<&zynqmp_dpdma ZYNQMP_DPDMA_VIDEO1>, <&zynqmp_dpdma ZYNQMP_DPDMA_VIDEO1>,
<&zynqmp_dpdma ZYNQMP_DPDMA_VIDEO2>, <&zynqmp_dpdma ZYNQMP_DPDMA_VIDEO2>,
<&zynqmp_dpdma ZYNQMP_DPDMA_GRAPHICS>; <&zynqmp_dpdma ZYNQMP_DPDMA_GRAPHICS>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
};
port@1 {
reg = <1>;
};
port@2 {
reg = <2>;
};
port@3 {
reg = <3>;
};
port@4 {
reg = <4>;
};
port@5 {
reg = <5>;
};
};
}; };
}; };
}; };
zynqmp-dpsub-y := zynqmp_disp.o zynqmp_dpsub.o zynqmp_dp.o zynqmp-dpsub-y := zynqmp_disp.o zynqmp_dpsub.o zynqmp_dp.o zynqmp_kms.o
obj-$(CONFIG_DRM_ZYNQMP_DPSUB) += zynqmp-dpsub.o obj-$(CONFIG_DRM_ZYNQMP_DPSUB) += zynqmp-dpsub.o
This diff is collapsed.
...@@ -25,18 +25,52 @@ ...@@ -25,18 +25,52 @@
#define ZYNQMP_DISP_MAX_DMA_BIT 44 #define ZYNQMP_DISP_MAX_DMA_BIT 44
struct device; struct device;
struct drm_device; struct drm_format_info;
struct drm_plane_state;
struct platform_device; struct platform_device;
struct zynqmp_disp; struct zynqmp_disp;
struct zynqmp_disp_layer;
struct zynqmp_dpsub; struct zynqmp_dpsub;
void zynqmp_disp_handle_vblank(struct zynqmp_disp *disp); /**
bool zynqmp_disp_audio_enabled(struct zynqmp_disp *disp); * enum zynqmp_dpsub_layer_id - Layer identifier
unsigned int zynqmp_disp_get_audio_clk_rate(struct zynqmp_disp *disp); * @ZYNQMP_DPSUB_LAYER_VID: Video layer
uint32_t zynqmp_disp_get_crtc_mask(struct zynqmp_disp *disp); * @ZYNQMP_DPSUB_LAYER_GFX: Graphics layer
*/
enum zynqmp_dpsub_layer_id {
ZYNQMP_DPSUB_LAYER_VID,
ZYNQMP_DPSUB_LAYER_GFX,
};
/**
* enum zynqmp_dpsub_layer_mode - Layer mode
* @ZYNQMP_DPSUB_LAYER_NONLIVE: non-live (memory) mode
* @ZYNQMP_DPSUB_LAYER_LIVE: live (stream) mode
*/
enum zynqmp_dpsub_layer_mode {
ZYNQMP_DPSUB_LAYER_NONLIVE,
ZYNQMP_DPSUB_LAYER_LIVE,
};
void zynqmp_disp_enable(struct zynqmp_disp *disp);
void zynqmp_disp_disable(struct zynqmp_disp *disp);
int zynqmp_disp_setup_clock(struct zynqmp_disp *disp,
unsigned long mode_clock);
void zynqmp_disp_blend_set_global_alpha(struct zynqmp_disp *disp,
bool enable, u32 alpha);
u32 *zynqmp_disp_layer_drm_formats(struct zynqmp_disp_layer *layer,
unsigned int *num_formats);
void zynqmp_disp_layer_enable(struct zynqmp_disp_layer *layer,
enum zynqmp_dpsub_layer_mode mode);
void zynqmp_disp_layer_disable(struct zynqmp_disp_layer *layer);
void zynqmp_disp_layer_set_format(struct zynqmp_disp_layer *layer,
const struct drm_format_info *info);
int zynqmp_disp_layer_update(struct zynqmp_disp_layer *layer,
struct drm_plane_state *state);
int zynqmp_disp_drm_init(struct zynqmp_dpsub *dpsub); int zynqmp_disp_probe(struct zynqmp_dpsub *dpsub);
int zynqmp_disp_probe(struct zynqmp_dpsub *dpsub, struct drm_device *drm);
void zynqmp_disp_remove(struct zynqmp_dpsub *dpsub); void zynqmp_disp_remove(struct zynqmp_dpsub *dpsub);
#endif /* _ZYNQMP_DISP_H_ */ #endif /* _ZYNQMP_DISP_H_ */
This diff is collapsed.
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#ifndef _ZYNQMP_DP_H_ #ifndef _ZYNQMP_DP_H_
#define _ZYNQMP_DP_H_ #define _ZYNQMP_DP_H_
struct drm_device;
struct platform_device; struct platform_device;
struct zynqmp_dp; struct zynqmp_dp;
struct zynqmp_dpsub; struct zynqmp_dpsub;
...@@ -20,8 +19,7 @@ struct zynqmp_dpsub; ...@@ -20,8 +19,7 @@ struct zynqmp_dpsub;
void zynqmp_dp_enable_vblank(struct zynqmp_dp *dp); void zynqmp_dp_enable_vblank(struct zynqmp_dp *dp);
void zynqmp_dp_disable_vblank(struct zynqmp_dp *dp); void zynqmp_dp_disable_vblank(struct zynqmp_dp *dp);
int zynqmp_dp_drm_init(struct zynqmp_dpsub *dpsub); int zynqmp_dp_probe(struct zynqmp_dpsub *dpsub);
int zynqmp_dp_probe(struct zynqmp_dpsub *dpsub, struct drm_device *drm);
void zynqmp_dp_remove(struct zynqmp_dpsub *dpsub); void zynqmp_dp_remove(struct zynqmp_dpsub *dpsub);
#endif /* _ZYNQMP_DP_H_ */ #endif /* _ZYNQMP_DP_H_ */
This diff is collapsed.
...@@ -14,9 +14,23 @@ ...@@ -14,9 +14,23 @@
struct clk; struct clk;
struct device; struct device;
struct drm_device; struct drm_bridge;
struct zynqmp_disp; struct zynqmp_disp;
struct zynqmp_disp_layer;
struct zynqmp_dp; struct zynqmp_dp;
struct zynqmp_dpsub_drm;
#define ZYNQMP_DPSUB_NUM_LAYERS 2
enum zynqmp_dpsub_port {
ZYNQMP_DPSUB_PORT_LIVE_VIDEO,
ZYNQMP_DPSUB_PORT_LIVE_GFX,
ZYNQMP_DPSUB_PORT_LIVE_AUDIO,
ZYNQMP_DPSUB_PORT_OUT_VIDEO,
ZYNQMP_DPSUB_PORT_OUT_AUDIO,
ZYNQMP_DPSUB_PORT_OUT_DP,
ZYNQMP_DPSUB_NUM_PORTS,
};
enum zynqmp_dpsub_format { enum zynqmp_dpsub_format {
ZYNQMP_DPSUB_FORMAT_RGB, ZYNQMP_DPSUB_FORMAT_RGB,
...@@ -27,28 +41,46 @@ enum zynqmp_dpsub_format { ...@@ -27,28 +41,46 @@ enum zynqmp_dpsub_format {
/** /**
* struct zynqmp_dpsub - ZynqMP DisplayPort Subsystem * struct zynqmp_dpsub - ZynqMP DisplayPort Subsystem
* @drm: The DRM/KMS device
* @dev: The physical device * @dev: The physical device
* @apb_clk: The APB clock * @apb_clk: The APB clock
* @vid_clk: Video clock
* @vid_clk_from_ps: True of the video clock comes from PS, false from PL
* @aud_clk: Audio clock
* @aud_clk_from_ps: True of the audio clock comes from PS, false from PL
* @connected_ports: Bitmask of connected ports in the device tree
* @dma_enabled: True if the DMA interface is enabled, false if the DPSUB is
* driven by the live input
* @drm: The DRM/KMS device data
* @bridge: The DP encoder bridge
* @disp: The display controller * @disp: The display controller
* @dp: The DisplayPort controller * @dp: The DisplayPort controller
* @dma_align: DMA alignment constraint (must be a power of 2) * @dma_align: DMA alignment constraint (must be a power of 2)
*/ */
struct zynqmp_dpsub { struct zynqmp_dpsub {
struct drm_device drm;
struct device *dev; struct device *dev;
struct clk *apb_clk; struct clk *apb_clk;
struct clk *vid_clk;
bool vid_clk_from_ps;
struct clk *aud_clk;
bool aud_clk_from_ps;
unsigned int connected_ports;
bool dma_enabled;
struct zynqmp_dpsub_drm *drm;
struct drm_bridge *bridge;
struct zynqmp_disp *disp; struct zynqmp_disp *disp;
struct zynqmp_disp_layer *layers[ZYNQMP_DPSUB_NUM_LAYERS];
struct zynqmp_dp *dp; struct zynqmp_dp *dp;
unsigned int dma_align; unsigned int dma_align;
}; };
static inline struct zynqmp_dpsub *to_zynqmp_dpsub(struct drm_device *drm) bool zynqmp_dpsub_audio_enabled(struct zynqmp_dpsub *dpsub);
{ unsigned int zynqmp_dpsub_get_audio_clk_rate(struct zynqmp_dpsub *dpsub);
return container_of(drm, struct zynqmp_dpsub, drm);
} void zynqmp_dpsub_release(struct zynqmp_dpsub *dpsub);
#endif /* _ZYNQMP_DPSUB_H_ */ #endif /* _ZYNQMP_DPSUB_H_ */
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 */
/*
* ZynqMP DisplayPort Subsystem - KMS API
*
* Copyright (C) 2017 - 2021 Xilinx, Inc.
*
* Authors:
* - Hyun Woo Kwon <hyun.kwon@xilinx.com>
* - Laurent Pinchart <laurent.pinchart@ideasonboard.com>
*/
#ifndef _ZYNQMP_KMS_H_
#define _ZYNQMP_KMS_H_
#include <drm/drm_crtc.h>
#include <drm/drm_device.h>
#include <drm/drm_encoder.h>
#include <drm/drm_plane.h>
#include "zynqmp_dpsub.h"
struct zynqmp_dpsub;
/**
* struct zynqmp_dpsub - ZynqMP DisplayPort Subsystem DRM/KMS data
* @dpsub: Backpointer to the DisplayPort subsystem
* @drm: The DRM/KMS device
* @planes: The DRM planes
* @crtc: The DRM CRTC
* @encoder: The dummy DRM encoder
*/
struct zynqmp_dpsub_drm {
struct zynqmp_dpsub *dpsub;
struct drm_device dev;
struct drm_plane planes[ZYNQMP_DPSUB_NUM_LAYERS];
struct drm_crtc crtc;
struct drm_encoder encoder;
};
void zynqmp_dpsub_drm_handle_vblank(struct zynqmp_dpsub *dpsub);
int zynqmp_dpsub_drm_init(struct zynqmp_dpsub *dpsub);
void zynqmp_dpsub_drm_cleanup(struct zynqmp_dpsub *dpsub);
#endif /* _ZYNQMP_KMS_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment