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 vc4_hdmi;
  25struct vc4_hdmi_register;
  26struct vc4_hdmi_connector_state;
  27
  28enum vc4_hdmi_phy_channel {
  29        PHY_LANE_0 = 0,
  30        PHY_LANE_1,
  31        PHY_LANE_2,
  32        PHY_LANE_CK,
  33};
  34
  35struct vc4_hdmi_variant {
  36        /* Encoder Type for that controller */
  37        enum vc4_encoder_type encoder_type;
  38
  39        /* ALSA card name */
  40        const char *card_name;
  41
  42        /* Filename to expose the registers in debugfs */
  43        const char *debugfs_name;
  44
  45        /* Maximum pixel clock supported by the controller (in Hz) */
  46        unsigned long long max_pixel_clock;
  47
  48        /* List of the registers available on that variant */
  49        const struct vc4_hdmi_register *registers;
  50
  51        /* Number of registers on that variant */
  52        unsigned int num_registers;
  53
  54        /* BCM2711 Only.
  55         * The variants don't map the lane in the same order in the
  56         * PHY, so this is an array mapping the HDMI channel (index)
  57         * to the PHY lane (value).
  58         */
  59        enum vc4_hdmi_phy_channel phy_lane_mapping[4];
  60
  61        /* The BCM2711 cannot deal with odd horizontal pixel timings */
  62        bool unsupported_odd_h_timings;
  63
  64        /*
  65         * The BCM2711 CEC/hotplug IRQ controller is shared between the
  66         * two HDMI controllers, and we have a proper irqchip driver for
  67         * it.
  68         */
  69        bool external_irq_controller;
  70
  71        /* Callback to get the resources (memory region, interrupts,
  72         * clocks, etc) for that variant.
  73         */
  74        int (*init_resources)(struct vc4_hdmi *vc4_hdmi);
  75
  76        /* Callback to reset the HDMI block */
  77        void (*reset)(struct vc4_hdmi *vc4_hdmi);
  78
  79        /* Callback to enable / disable the CSC */
  80        void (*csc_setup)(struct vc4_hdmi *vc4_hdmi, bool enable);
  81
  82        /* Callback to configure the video timings in the HDMI block */
  83        void (*set_timings)(struct vc4_hdmi *vc4_hdmi,
  84                            struct drm_connector_state *state,
  85                            struct drm_display_mode *mode);
  86
  87        /* Callback to initialize the PHY according to the connector state */
  88        void (*phy_init)(struct vc4_hdmi *vc4_hdmi,
  89                         struct vc4_hdmi_connector_state *vc4_conn_state);
  90
  91        /* Callback to disable the PHY */
  92        void (*phy_disable)(struct vc4_hdmi *vc4_hdmi);
  93
  94        /* Callback to enable the RNG in the PHY */
  95        void (*phy_rng_enable)(struct vc4_hdmi *vc4_hdmi);
  96
  97        /* Callback to disable the RNG in the PHY */
  98        void (*phy_rng_disable)(struct vc4_hdmi *vc4_hdmi);
  99
 100        /* Callback to get channel map */
 101        u32 (*channel_map)(struct vc4_hdmi *vc4_hdmi, u32 channel_mask);
 102
 103        /* Enables HDR metadata */
 104        bool supports_hdr;
 105};
 106
 107/* HDMI audio information */
 108struct vc4_hdmi_audio {
 109        struct snd_soc_card card;
 110        struct snd_soc_dai_link link;
 111        struct snd_soc_dai_link_component cpu;
 112        struct snd_soc_dai_link_component codec;
 113        struct snd_soc_dai_link_component platform;
 114        int samplerate;
 115        int channels;
 116        struct snd_dmaengine_dai_dma_data dma_data;
 117        struct snd_pcm_substream *substream;
 118
 119        bool streaming;
 120};
 121
 122/* General HDMI hardware state. */
 123struct vc4_hdmi {
 124        struct vc4_hdmi_audio audio;
 125
 126        struct platform_device *pdev;
 127        const struct vc4_hdmi_variant *variant;
 128
 129        struct vc4_hdmi_encoder encoder;
 130        struct drm_connector connector;
 131
 132        struct delayed_work scrambling_work;
 133
 134        struct i2c_adapter *ddc;
 135        void __iomem *hdmicore_regs;
 136        void __iomem *hd_regs;
 137
 138        /* VC5 Only */
 139        void __iomem *cec_regs;
 140        /* VC5 Only */
 141        void __iomem *csc_regs;
 142        /* VC5 Only */
 143        void __iomem *dvp_regs;
 144        /* VC5 Only */
 145        void __iomem *phy_regs;
 146        /* VC5 Only */
 147        void __iomem *ram_regs;
 148        /* VC5 Only */
 149        void __iomem *rm_regs;
 150
 151        struct gpio_desc *hpd_gpio;
 152
 153        /*
 154         * On some systems (like the RPi4), some modes are in the same
 155         * frequency range than the WiFi channels (1440p@60Hz for
 156         * example). Should we take evasive actions because that system
 157         * has a wifi adapter?
 158         */
 159        bool disable_wifi_frequencies;
 160
 161        /*
 162         * Even if HDMI0 on the RPi4 can output modes requiring a pixel
 163         * rate higher than 297MHz, it needs some adjustments in the
 164         * config.txt file to be able to do so and thus won't always be
 165         * available.
 166         */
 167        bool disable_4kp60;
 168
 169        struct cec_adapter *cec_adap;
 170        struct cec_msg cec_rx_msg;
 171        bool cec_tx_ok;
 172        bool cec_irq_was_rx;
 173
 174        struct clk *cec_clock;
 175        struct clk *pixel_clock;
 176        struct clk *hsm_clock;
 177        struct clk *audio_clock;
 178        struct clk *pixel_bvb_clock;
 179
 180        struct reset_control *reset;
 181
 182        struct debugfs_regset32 hdmi_regset;
 183        struct debugfs_regset32 hd_regset;
 184};
 185
 186static inline struct vc4_hdmi *
 187connector_to_vc4_hdmi(struct drm_connector *connector)
 188{
 189        return container_of(connector, struct vc4_hdmi, connector);
 190}
 191
 192static inline struct vc4_hdmi *
 193encoder_to_vc4_hdmi(struct drm_encoder *encoder)
 194{
 195        struct vc4_hdmi_encoder *_encoder = to_vc4_hdmi_encoder(encoder);
 196
 197        return container_of(_encoder, struct vc4_hdmi, encoder);
 198}
 199
 200struct vc4_hdmi_connector_state {
 201        struct drm_connector_state      base;
 202        unsigned long long              pixel_rate;
 203};
 204
 205static inline struct vc4_hdmi_connector_state *
 206conn_state_to_vc4_hdmi_conn_state(struct drm_connector_state *conn_state)
 207{
 208        return container_of(conn_state, struct vc4_hdmi_connector_state, base);
 209}
 210
 211void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
 212                       struct vc4_hdmi_connector_state *vc4_conn_state);
 213void vc4_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi);
 214void vc4_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi);
 215void vc4_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi);
 216
 217void vc5_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
 218                       struct vc4_hdmi_connector_state *vc4_conn_state);
 219void vc5_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi);
 220void vc5_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi);
 221void vc5_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi);
 222
 223#endif /* _VC4_HDMI_H_ */
 224