2020-09-03 10:01:11 +02:00
# ifndef _VC4_HDMI_H_
# define _VC4_HDMI_H_
# include <drm/drm_connector.h>
# include <media/cec.h>
# include <sound/dmaengine_pcm.h>
# include <sound/soc.h>
# include "vc4_drv.h"
2020-09-03 10:01:12 +02:00
/* VC4 HDMI encoder KMS struct */
struct vc4_hdmi_encoder {
struct vc4_encoder base ;
bool hdmi_monitor ;
bool limited_rgb_range ;
} ;
static inline struct vc4_hdmi_encoder *
to_vc4_hdmi_encoder ( struct drm_encoder * encoder )
{
return container_of ( encoder , struct vc4_hdmi_encoder , base . base ) ;
}
2020-09-03 10:01:25 +02:00
struct drm_display_mode ;
2020-09-03 10:01:22 +02:00
struct vc4_hdmi ;
2020-09-03 10:01:23 +02:00
struct vc4_hdmi_register ;
2020-09-03 10:01:22 +02:00
2020-09-03 10:01:48 +02:00
enum vc4_hdmi_phy_channel {
PHY_LANE_0 = 0 ,
PHY_LANE_1 ,
PHY_LANE_2 ,
PHY_LANE_CK ,
} ;
2020-09-03 10:01:22 +02:00
struct vc4_hdmi_variant {
2020-09-03 10:01:29 +02:00
/* Encoder Type for that controller */
enum vc4_encoder_type encoder_type ;
2020-09-03 10:01:41 +02:00
/* ALSA card name */
const char * card_name ;
2020-09-03 10:01:30 +02:00
/* Filename to expose the registers in debugfs */
const char * debugfs_name ;
2020-09-03 10:01:32 +02:00
/* Set to true when the CEC support is available */
bool cec_available ;
2020-09-03 10:01:35 +02:00
/* Maximum pixel clock supported by the controller (in Hz) */
unsigned long long max_pixel_clock ;
2020-09-03 10:01:23 +02:00
/* List of the registers available on that variant */
const struct vc4_hdmi_register * registers ;
/* Number of registers on that variant */
unsigned int num_registers ;
2020-09-03 10:01:48 +02:00
/* BCM2711 Only.
* The variants don ' t map the lane in the same order in the
* PHY , so this is an array mapping the HDMI channel ( index )
* to the PHY lane ( value ) .
*/
enum vc4_hdmi_phy_channel phy_lane_mapping [ 4 ] ;
2020-10-29 13:25:22 +01:00
/* The BCM2711 cannot deal with odd horizontal pixel timings */
bool unsupported_odd_h_timings ;
2020-09-03 10:01:22 +02:00
/* Callback to get the resources (memory region, interrupts,
* clocks , etc ) for that variant .
*/
int ( * init_resources ) ( struct vc4_hdmi * vc4_hdmi ) ;
2020-09-03 10:01:24 +02:00
/* Callback to reset the HDMI block */
void ( * reset ) ( struct vc4_hdmi * vc4_hdmi ) ;
2020-09-03 10:01:25 +02:00
2020-09-03 10:01:27 +02:00
/* Callback to enable / disable the CSC */
void ( * csc_setup ) ( struct vc4_hdmi * vc4_hdmi , bool enable ) ;
2020-09-03 10:01:28 +02:00
/* Callback to configure the video timings in the HDMI block */
void ( * set_timings ) ( struct vc4_hdmi * vc4_hdmi ,
struct drm_display_mode * mode ) ;
2020-09-03 10:01:25 +02:00
/* Callback to initialize the PHY according to the mode */
void ( * phy_init ) ( struct vc4_hdmi * vc4_hdmi ,
struct drm_display_mode * mode ) ;
/* Callback to disable the PHY */
void ( * phy_disable ) ( struct vc4_hdmi * vc4_hdmi ) ;
2020-09-03 10:01:26 +02:00
/* Callback to enable the RNG in the PHY */
void ( * phy_rng_enable ) ( struct vc4_hdmi * vc4_hdmi ) ;
/* Callback to disable the RNG in the PHY */
void ( * phy_rng_disable ) ( struct vc4_hdmi * vc4_hdmi ) ;
2020-09-03 10:01:40 +02:00
/* Callback to get channel map */
u32 ( * channel_map ) ( struct vc4_hdmi * vc4_hdmi , u32 channel_mask ) ;
2020-09-03 10:01:22 +02:00
} ;
2020-09-03 10:01:11 +02:00
/* HDMI audio information */
struct vc4_hdmi_audio {
struct snd_soc_card card ;
struct snd_soc_dai_link link ;
struct snd_soc_dai_link_component cpu ;
struct snd_soc_dai_link_component codec ;
struct snd_soc_dai_link_component platform ;
int samplerate ;
int channels ;
struct snd_dmaengine_dai_dma_data dma_data ;
struct snd_pcm_substream * substream ;
2020-09-03 10:01:38 +02:00
bool streaming ;
2020-09-03 10:01:11 +02:00
} ;
/* General HDMI hardware state. */
struct vc4_hdmi {
2020-09-03 10:01:19 +02:00
struct vc4_hdmi_audio audio ;
2020-09-03 10:01:11 +02:00
struct platform_device * pdev ;
2020-09-03 10:01:22 +02:00
const struct vc4_hdmi_variant * variant ;
2020-09-03 10:01:11 +02:00
2020-09-03 10:01:12 +02:00
struct vc4_hdmi_encoder encoder ;
2020-09-03 10:01:21 +02:00
struct drm_connector connector ;
2020-09-03 10:01:11 +02:00
struct i2c_adapter * ddc ;
void __iomem * hdmicore_regs ;
void __iomem * hd_regs ;
2020-09-03 10:01:48 +02:00
/* VC5 Only */
void __iomem * cec_regs ;
/* VC5 Only */
void __iomem * csc_regs ;
/* VC5 Only */
void __iomem * dvp_regs ;
/* VC5 Only */
void __iomem * phy_regs ;
/* VC5 Only */
void __iomem * ram_regs ;
/* VC5 Only */
void __iomem * rm_regs ;
2020-09-03 10:01:11 +02:00
int hpd_gpio ;
bool hpd_active_low ;
2020-10-29 14:40:17 +01:00
/*
* On some systems ( like the RPi4 ) , some modes are in the same
* frequency range than the WiFi channels ( 1440 p @ 60 Hz for
* example ) . Should we take evasive actions because that system
* has a wifi adapter ?
*/
bool disable_wifi_frequencies ;
2020-09-03 10:01:11 +02:00
struct cec_adapter * cec_adap ;
struct cec_msg cec_rx_msg ;
bool cec_tx_ok ;
bool cec_irq_was_rx ;
struct clk * pixel_clock ;
struct clk * hsm_clock ;
2020-09-03 10:01:40 +02:00
struct clk * audio_clock ;
2020-09-03 10:01:47 +02:00
struct clk * pixel_bvb_clock ;
2020-09-03 10:01:11 +02:00
2020-09-03 10:01:48 +02:00
struct reset_control * reset ;
2020-09-03 10:01:11 +02:00
struct debugfs_regset32 hdmi_regset ;
struct debugfs_regset32 hd_regset ;
} ;
2020-09-03 10:01:17 +02:00
static inline struct vc4_hdmi *
connector_to_vc4_hdmi ( struct drm_connector * connector )
{
2020-09-03 10:01:21 +02:00
return container_of ( connector , struct vc4_hdmi , connector ) ;
2020-09-03 10:01:17 +02:00
}
static inline struct vc4_hdmi *
encoder_to_vc4_hdmi ( struct drm_encoder * encoder )
{
struct vc4_hdmi_encoder * _encoder = to_vc4_hdmi_encoder ( encoder ) ;
return container_of ( _encoder , struct vc4_hdmi , encoder ) ;
}
2020-09-03 10:01:25 +02:00
void vc4_hdmi_phy_init ( struct vc4_hdmi * vc4_hdmi ,
struct drm_display_mode * mode ) ;
void vc4_hdmi_phy_disable ( struct vc4_hdmi * vc4_hdmi ) ;
2020-09-03 10:01:26 +02:00
void vc4_hdmi_phy_rng_enable ( struct vc4_hdmi * vc4_hdmi ) ;
void vc4_hdmi_phy_rng_disable ( struct vc4_hdmi * vc4_hdmi ) ;
2020-09-03 10:01:25 +02:00
2020-09-03 10:01:48 +02:00
void vc5_hdmi_phy_init ( struct vc4_hdmi * vc4_hdmi ,
struct drm_display_mode * mode ) ;
void vc5_hdmi_phy_disable ( struct vc4_hdmi * vc4_hdmi ) ;
void vc5_hdmi_phy_rng_enable ( struct vc4_hdmi * vc4_hdmi ) ;
void vc5_hdmi_phy_rng_disable ( struct vc4_hdmi * vc4_hdmi ) ;
2020-09-03 10:01:11 +02:00
# endif /* _VC4_HDMI_H_ */