xref: /OK3568_Linux_fs/kernel/drivers/gpu/drm/vc4/vc4_hdmi.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun #ifndef _VC4_HDMI_H_
2*4882a593Smuzhiyun #define _VC4_HDMI_H_
3*4882a593Smuzhiyun 
4*4882a593Smuzhiyun #include <drm/drm_connector.h>
5*4882a593Smuzhiyun #include <media/cec.h>
6*4882a593Smuzhiyun #include <sound/dmaengine_pcm.h>
7*4882a593Smuzhiyun #include <sound/soc.h>
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include "vc4_drv.h"
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun /* VC4 HDMI encoder KMS struct */
12*4882a593Smuzhiyun struct vc4_hdmi_encoder {
13*4882a593Smuzhiyun 	struct vc4_encoder base;
14*4882a593Smuzhiyun 	bool hdmi_monitor;
15*4882a593Smuzhiyun 	bool limited_rgb_range;
16*4882a593Smuzhiyun };
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun static inline struct vc4_hdmi_encoder *
to_vc4_hdmi_encoder(struct drm_encoder * encoder)19*4882a593Smuzhiyun to_vc4_hdmi_encoder(struct drm_encoder *encoder)
20*4882a593Smuzhiyun {
21*4882a593Smuzhiyun 	return container_of(encoder, struct vc4_hdmi_encoder, base.base);
22*4882a593Smuzhiyun }
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun struct drm_display_mode;
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun struct vc4_hdmi;
27*4882a593Smuzhiyun struct vc4_hdmi_register;
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun enum vc4_hdmi_phy_channel {
30*4882a593Smuzhiyun 	PHY_LANE_0 = 0,
31*4882a593Smuzhiyun 	PHY_LANE_1,
32*4882a593Smuzhiyun 	PHY_LANE_2,
33*4882a593Smuzhiyun 	PHY_LANE_CK,
34*4882a593Smuzhiyun };
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun struct vc4_hdmi_variant {
37*4882a593Smuzhiyun 	/* Encoder Type for that controller */
38*4882a593Smuzhiyun 	enum vc4_encoder_type encoder_type;
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun 	/* ALSA card name */
41*4882a593Smuzhiyun 	const char *card_name;
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun 	/* Filename to expose the registers in debugfs */
44*4882a593Smuzhiyun 	const char *debugfs_name;
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun 	/* Set to true when the CEC support is available */
47*4882a593Smuzhiyun 	bool cec_available;
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun 	/* Maximum pixel clock supported by the controller (in Hz) */
50*4882a593Smuzhiyun 	unsigned long long max_pixel_clock;
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun 	/* List of the registers available on that variant */
53*4882a593Smuzhiyun 	const struct vc4_hdmi_register *registers;
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun 	/* Number of registers on that variant */
56*4882a593Smuzhiyun 	unsigned int num_registers;
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun 	/* BCM2711 Only.
59*4882a593Smuzhiyun 	 * The variants don't map the lane in the same order in the
60*4882a593Smuzhiyun 	 * PHY, so this is an array mapping the HDMI channel (index)
61*4882a593Smuzhiyun 	 * to the PHY lane (value).
62*4882a593Smuzhiyun 	 */
63*4882a593Smuzhiyun 	enum vc4_hdmi_phy_channel phy_lane_mapping[4];
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun 	/* The BCM2711 cannot deal with odd horizontal pixel timings */
66*4882a593Smuzhiyun 	bool unsupported_odd_h_timings;
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun 	/* Callback to get the resources (memory region, interrupts,
69*4882a593Smuzhiyun 	 * clocks, etc) for that variant.
70*4882a593Smuzhiyun 	 */
71*4882a593Smuzhiyun 	int (*init_resources)(struct vc4_hdmi *vc4_hdmi);
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun 	/* Callback to reset the HDMI block */
74*4882a593Smuzhiyun 	void (*reset)(struct vc4_hdmi *vc4_hdmi);
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun 	/* Callback to enable / disable the CSC */
77*4882a593Smuzhiyun 	void (*csc_setup)(struct vc4_hdmi *vc4_hdmi, bool enable);
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun 	/* Callback to configure the video timings in the HDMI block */
80*4882a593Smuzhiyun 	void (*set_timings)(struct vc4_hdmi *vc4_hdmi,
81*4882a593Smuzhiyun 			    struct drm_display_mode *mode);
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun 	/* Callback to initialize the PHY according to the mode */
84*4882a593Smuzhiyun 	void (*phy_init)(struct vc4_hdmi *vc4_hdmi,
85*4882a593Smuzhiyun 			 struct drm_display_mode *mode);
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun 	/* Callback to disable the PHY */
88*4882a593Smuzhiyun 	void (*phy_disable)(struct vc4_hdmi *vc4_hdmi);
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun 	/* Callback to enable the RNG in the PHY */
91*4882a593Smuzhiyun 	void (*phy_rng_enable)(struct vc4_hdmi *vc4_hdmi);
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	/* Callback to disable the RNG in the PHY */
94*4882a593Smuzhiyun 	void (*phy_rng_disable)(struct vc4_hdmi *vc4_hdmi);
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun 	/* Callback to get channel map */
97*4882a593Smuzhiyun 	u32 (*channel_map)(struct vc4_hdmi *vc4_hdmi, u32 channel_mask);
98*4882a593Smuzhiyun };
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun /* HDMI audio information */
101*4882a593Smuzhiyun struct vc4_hdmi_audio {
102*4882a593Smuzhiyun 	struct snd_soc_card card;
103*4882a593Smuzhiyun 	struct snd_soc_dai_link link;
104*4882a593Smuzhiyun 	struct snd_soc_dai_link_component cpu;
105*4882a593Smuzhiyun 	struct snd_soc_dai_link_component codec;
106*4882a593Smuzhiyun 	struct snd_soc_dai_link_component platform;
107*4882a593Smuzhiyun 	int samplerate;
108*4882a593Smuzhiyun 	int channels;
109*4882a593Smuzhiyun 	struct snd_dmaengine_dai_dma_data dma_data;
110*4882a593Smuzhiyun 	struct snd_pcm_substream *substream;
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun 	bool streaming;
113*4882a593Smuzhiyun };
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun /* General HDMI hardware state. */
116*4882a593Smuzhiyun struct vc4_hdmi {
117*4882a593Smuzhiyun 	struct vc4_hdmi_audio audio;
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun 	struct platform_device *pdev;
120*4882a593Smuzhiyun 	const struct vc4_hdmi_variant *variant;
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 	struct vc4_hdmi_encoder encoder;
123*4882a593Smuzhiyun 	struct drm_connector connector;
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun 	struct i2c_adapter *ddc;
126*4882a593Smuzhiyun 	void __iomem *hdmicore_regs;
127*4882a593Smuzhiyun 	void __iomem *hd_regs;
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun 	/* VC5 Only */
130*4882a593Smuzhiyun 	void __iomem *cec_regs;
131*4882a593Smuzhiyun 	/* VC5 Only */
132*4882a593Smuzhiyun 	void __iomem *csc_regs;
133*4882a593Smuzhiyun 	/* VC5 Only */
134*4882a593Smuzhiyun 	void __iomem *dvp_regs;
135*4882a593Smuzhiyun 	/* VC5 Only */
136*4882a593Smuzhiyun 	void __iomem *phy_regs;
137*4882a593Smuzhiyun 	/* VC5 Only */
138*4882a593Smuzhiyun 	void __iomem *ram_regs;
139*4882a593Smuzhiyun 	/* VC5 Only */
140*4882a593Smuzhiyun 	void __iomem *rm_regs;
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 	int hpd_gpio;
143*4882a593Smuzhiyun 	bool hpd_active_low;
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun 	/*
146*4882a593Smuzhiyun 	 * On some systems (like the RPi4), some modes are in the same
147*4882a593Smuzhiyun 	 * frequency range than the WiFi channels (1440p@60Hz for
148*4882a593Smuzhiyun 	 * example). Should we take evasive actions because that system
149*4882a593Smuzhiyun 	 * has a wifi adapter?
150*4882a593Smuzhiyun 	 */
151*4882a593Smuzhiyun 	bool disable_wifi_frequencies;
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 	struct cec_adapter *cec_adap;
154*4882a593Smuzhiyun 	struct cec_msg cec_rx_msg;
155*4882a593Smuzhiyun 	bool cec_tx_ok;
156*4882a593Smuzhiyun 	bool cec_irq_was_rx;
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 	struct clk *pixel_clock;
159*4882a593Smuzhiyun 	struct clk *hsm_clock;
160*4882a593Smuzhiyun 	struct clk *audio_clock;
161*4882a593Smuzhiyun 	struct clk *pixel_bvb_clock;
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun 	struct reset_control *reset;
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 	struct debugfs_regset32 hdmi_regset;
166*4882a593Smuzhiyun 	struct debugfs_regset32 hd_regset;
167*4882a593Smuzhiyun };
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun static inline struct vc4_hdmi *
connector_to_vc4_hdmi(struct drm_connector * connector)170*4882a593Smuzhiyun connector_to_vc4_hdmi(struct drm_connector *connector)
171*4882a593Smuzhiyun {
172*4882a593Smuzhiyun 	return container_of(connector, struct vc4_hdmi, connector);
173*4882a593Smuzhiyun }
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun static inline struct vc4_hdmi *
encoder_to_vc4_hdmi(struct drm_encoder * encoder)176*4882a593Smuzhiyun encoder_to_vc4_hdmi(struct drm_encoder *encoder)
177*4882a593Smuzhiyun {
178*4882a593Smuzhiyun 	struct vc4_hdmi_encoder *_encoder = to_vc4_hdmi_encoder(encoder);
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun 	return container_of(_encoder, struct vc4_hdmi, encoder);
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
184*4882a593Smuzhiyun 		       struct drm_display_mode *mode);
185*4882a593Smuzhiyun void vc4_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi);
186*4882a593Smuzhiyun void vc4_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi);
187*4882a593Smuzhiyun void vc4_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi);
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun void vc5_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
190*4882a593Smuzhiyun 		       struct drm_display_mode *mode);
191*4882a593Smuzhiyun void vc5_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi);
192*4882a593Smuzhiyun void vc5_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi);
193*4882a593Smuzhiyun void vc5_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi);
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun #endif /* _VC4_HDMI_H_ */
196