241 lines · c
1#ifndef _VC4_HDMI_H_2#define _VC4_HDMI_H_3 4#include <drm/drm_connector.h>5#include <media/cec.h>6#include <sound/dmaengine_pcm.h>7#include <sound/soc.h>8 9#include "vc4_drv.h"10 11struct vc4_hdmi;12struct vc4_hdmi_register;13 14enum vc4_hdmi_phy_channel {15 PHY_LANE_0 = 0,16 PHY_LANE_1,17 PHY_LANE_2,18 PHY_LANE_CK,19};20 21struct vc4_hdmi_variant {22 /* Encoder Type for that controller */23 enum vc4_encoder_type encoder_type;24 25 /* ALSA card name */26 const char *card_name;27 28 /* Filename to expose the registers in debugfs */29 const char *debugfs_name;30 31 /* Maximum pixel clock supported by the controller (in Hz) */32 unsigned long long max_pixel_clock;33 34 /* List of the registers available on that variant */35 const struct vc4_hdmi_register *registers;36 37 /* Number of registers on that variant */38 unsigned int num_registers;39 40 /* BCM2711 Only.41 * The variants don't map the lane in the same order in the42 * PHY, so this is an array mapping the HDMI channel (index)43 * to the PHY lane (value).44 */45 enum vc4_hdmi_phy_channel phy_lane_mapping[4];46 47 /* The BCM2711 cannot deal with odd horizontal pixel timings */48 bool unsupported_odd_h_timings;49 50 /*51 * The BCM2711 CEC/hotplug IRQ controller is shared between the52 * two HDMI controllers, and we have a proper irqchip driver for53 * it.54 */55 bool external_irq_controller;56 57 /* Callback to get the resources (memory region, interrupts,58 * clocks, etc) for that variant.59 */60 int (*init_resources)(struct drm_device *drm,61 struct vc4_hdmi *vc4_hdmi);62 63 /* Callback to reset the HDMI block */64 void (*reset)(struct vc4_hdmi *vc4_hdmi);65 66 /* Callback to enable / disable the CSC */67 void (*csc_setup)(struct vc4_hdmi *vc4_hdmi,68 struct drm_connector_state *state,69 const struct drm_display_mode *mode);70 71 /* Callback to configure the video timings in the HDMI block */72 void (*set_timings)(struct vc4_hdmi *vc4_hdmi,73 struct drm_connector_state *state,74 const struct drm_display_mode *mode);75 76 /* Callback to initialize the PHY according to the connector state */77 void (*phy_init)(struct vc4_hdmi *vc4_hdmi,78 struct drm_connector_state *conn_state);79 80 /* Callback to disable the PHY */81 void (*phy_disable)(struct vc4_hdmi *vc4_hdmi);82 83 /* Callback to enable the RNG in the PHY */84 void (*phy_rng_enable)(struct vc4_hdmi *vc4_hdmi);85 86 /* Callback to disable the RNG in the PHY */87 void (*phy_rng_disable)(struct vc4_hdmi *vc4_hdmi);88 89 /* Callback to get channel map */90 u32 (*channel_map)(struct vc4_hdmi *vc4_hdmi, u32 channel_mask);91 92 /* Enables HDR metadata */93 bool supports_hdr;94 95 /* Callback for hardware specific hotplug detect */96 bool (*hp_detect)(struct vc4_hdmi *vc4_hdmi);97};98 99/* HDMI audio information */100struct vc4_hdmi_audio {101 struct snd_soc_card card;102 struct snd_soc_dai_link link;103 struct snd_soc_dai_link_component cpu;104 struct snd_soc_dai_link_component codec;105 struct snd_soc_dai_link_component platform;106 struct snd_dmaengine_dai_dma_data dma_data;107 struct hdmi_audio_infoframe infoframe;108 struct platform_device *codec_pdev;109 bool streaming;110};111 112/* General HDMI hardware state. */113struct vc4_hdmi {114 struct vc4_hdmi_audio audio;115 116 struct platform_device *pdev;117 const struct vc4_hdmi_variant *variant;118 119 struct vc4_encoder encoder;120 struct drm_connector connector;121 122 struct delayed_work scrambling_work;123 124 struct i2c_adapter *ddc;125 void __iomem *hdmicore_regs;126 void __iomem *hd_regs;127 128 /* VC5 Only */129 void __iomem *cec_regs;130 /* VC5 Only */131 void __iomem *csc_regs;132 /* VC5 Only */133 void __iomem *dvp_regs;134 /* VC5 Only */135 void __iomem *phy_regs;136 /* VC5 Only */137 void __iomem *ram_regs;138 /* VC5 Only */139 void __iomem *rm_regs;140 141 struct gpio_desc *hpd_gpio;142 143 /*144 * On some systems (like the RPi4), some modes are in the same145 * frequency range than the WiFi channels (1440p@60Hz for146 * example). Should we take evasive actions because that system147 * has a wifi adapter?148 */149 bool disable_wifi_frequencies;150 151 struct cec_adapter *cec_adap;152 struct cec_msg cec_rx_msg;153 bool cec_tx_ok;154 bool cec_irq_was_rx;155 156 struct clk *cec_clock;157 struct clk *pixel_clock;158 struct clk *hsm_clock;159 struct clk *audio_clock;160 struct clk *pixel_bvb_clock;161 162 struct reset_control *reset;163 164 struct debugfs_regset32 hdmi_regset;165 struct debugfs_regset32 hd_regset;166 167 /* VC5 only */168 struct debugfs_regset32 cec_regset;169 struct debugfs_regset32 csc_regset;170 struct debugfs_regset32 dvp_regset;171 struct debugfs_regset32 phy_regset;172 struct debugfs_regset32 ram_regset;173 struct debugfs_regset32 rm_regset;174 175 /**176 * @hw_lock: Spinlock protecting device register access.177 */178 spinlock_t hw_lock;179 180 /**181 * @mutex: Mutex protecting the driver access across multiple182 * frameworks (KMS, ALSA, CEC).183 */184 struct mutex mutex;185 186 /**187 * @saved_adjusted_mode: Copy of @drm_crtc_state.adjusted_mode188 * for use by ALSA hooks and interrupt handlers. Protected by @mutex.189 */190 struct drm_display_mode saved_adjusted_mode;191 192 /**193 * @packet_ram_enabled: Is the HDMI controller packet RAM currently194 * on? Protected by @mutex.195 */196 bool packet_ram_enabled;197 198 /**199 * @scdc_enabled: Is the HDMI controller currently running with200 * the scrambler on? Protected by @mutex.201 */202 bool scdc_enabled;203 204 /**205 * @output_bpc: Copy of @drm_connector_state.hdmi.output_bpc for206 * use outside of KMS hooks. Protected by @mutex.207 */208 unsigned int output_bpc;209 210 /**211 * @output_format: Copy of212 * @drm_connector_state.hdmi.output_format for use outside of213 * KMS hooks. Protected by @mutex.214 */215 enum hdmi_colorspace output_format;216};217 218#define connector_to_vc4_hdmi(_connector) \219 container_of_const(_connector, struct vc4_hdmi, connector)220 221static inline struct vc4_hdmi *222encoder_to_vc4_hdmi(struct drm_encoder *encoder)223{224 struct vc4_encoder *_encoder = to_vc4_encoder(encoder);225 return container_of_const(_encoder, struct vc4_hdmi, encoder);226}227 228void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,229 struct drm_connector_state *conn_state);230void vc4_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi);231void vc4_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi);232void vc4_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi);233 234void vc5_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,235 struct drm_connector_state *conn_state);236void vc5_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi);237void vc5_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi);238void vc5_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi);239 240#endif /* _VC4_HDMI_H_ */241