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