cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

vc4_hdmi.h (7369B)


      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;
     13struct vc4_hdmi_connector_state;
     14
     15enum vc4_hdmi_phy_channel {
     16	PHY_LANE_0 = 0,
     17	PHY_LANE_1,
     18	PHY_LANE_2,
     19	PHY_LANE_CK,
     20};
     21
     22struct vc4_hdmi_variant {
     23	/* Encoder Type for that controller */
     24	enum vc4_encoder_type encoder_type;
     25
     26	/* ALSA card name */
     27	const char *card_name;
     28
     29	/* Filename to expose the registers in debugfs */
     30	const char *debugfs_name;
     31
     32	/* Maximum pixel clock supported by the controller (in Hz) */
     33	unsigned long long max_pixel_clock;
     34
     35	/* List of the registers available on that variant */
     36	const struct vc4_hdmi_register *registers;
     37
     38	/* Number of registers on that variant */
     39	unsigned int num_registers;
     40
     41	/* BCM2711 Only.
     42	 * The variants don't map the lane in the same order in the
     43	 * PHY, so this is an array mapping the HDMI channel (index)
     44	 * to the PHY lane (value).
     45	 */
     46	enum vc4_hdmi_phy_channel phy_lane_mapping[4];
     47
     48	/* The BCM2711 cannot deal with odd horizontal pixel timings */
     49	bool unsupported_odd_h_timings;
     50
     51	/*
     52	 * The BCM2711 CEC/hotplug IRQ controller is shared between the
     53	 * two HDMI controllers, and we have a proper irqchip driver for
     54	 * it.
     55	 */
     56	bool external_irq_controller;
     57
     58	/* Callback to get the resources (memory region, interrupts,
     59	 * clocks, etc) for that variant.
     60	 */
     61	int (*init_resources)(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			    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 vc4_hdmi_connector_state *vc4_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
    112enum vc4_hdmi_output_format {
    113	VC4_HDMI_OUTPUT_RGB,
    114	VC4_HDMI_OUTPUT_YUV422,
    115	VC4_HDMI_OUTPUT_YUV444,
    116	VC4_HDMI_OUTPUT_YUV420,
    117};
    118
    119/* General HDMI hardware state. */
    120struct vc4_hdmi {
    121	struct vc4_hdmi_audio audio;
    122
    123	struct platform_device *pdev;
    124	const struct vc4_hdmi_variant *variant;
    125
    126	struct vc4_encoder encoder;
    127	struct drm_connector connector;
    128
    129	struct delayed_work scrambling_work;
    130
    131	struct i2c_adapter *ddc;
    132	void __iomem *hdmicore_regs;
    133	void __iomem *hd_regs;
    134
    135	/* VC5 Only */
    136	void __iomem *cec_regs;
    137	/* VC5 Only */
    138	void __iomem *csc_regs;
    139	/* VC5 Only */
    140	void __iomem *dvp_regs;
    141	/* VC5 Only */
    142	void __iomem *phy_regs;
    143	/* VC5 Only */
    144	void __iomem *ram_regs;
    145	/* VC5 Only */
    146	void __iomem *rm_regs;
    147
    148	struct gpio_desc *hpd_gpio;
    149
    150	/*
    151	 * On some systems (like the RPi4), some modes are in the same
    152	 * frequency range than the WiFi channels (1440p@60Hz for
    153	 * example). Should we take evasive actions because that system
    154	 * has a wifi adapter?
    155	 */
    156	bool disable_wifi_frequencies;
    157
    158	/*
    159	 * Even if HDMI0 on the RPi4 can output modes requiring a pixel
    160	 * rate higher than 297MHz, it needs some adjustments in the
    161	 * config.txt file to be able to do so and thus won't always be
    162	 * available.
    163	 */
    164	bool disable_4kp60;
    165
    166	struct cec_adapter *cec_adap;
    167	struct cec_msg cec_rx_msg;
    168	bool cec_tx_ok;
    169	bool cec_irq_was_rx;
    170
    171	struct clk *cec_clock;
    172	struct clk *pixel_clock;
    173	struct clk *hsm_clock;
    174	struct clk *audio_clock;
    175	struct clk *pixel_bvb_clock;
    176
    177	struct reset_control *reset;
    178
    179	struct debugfs_regset32 hdmi_regset;
    180	struct debugfs_regset32 hd_regset;
    181
    182	/**
    183	 * @hw_lock: Spinlock protecting device register access.
    184	 */
    185	spinlock_t hw_lock;
    186
    187	/**
    188	 * @mutex: Mutex protecting the driver access across multiple
    189	 * frameworks (KMS, ALSA).
    190	 *
    191	 * NOTE: While supported, CEC has been left out since
    192	 * cec_s_phys_addr_from_edid() might call .adap_enable and lead to a
    193	 * reentrancy issue between .get_modes (or .detect) and .adap_enable.
    194	 * Since we don't share any state between the CEC hooks and KMS', it's
    195	 * not a big deal. The only trouble might come from updating the CEC
    196	 * clock divider which might be affected by a modeset, but CEC should
    197	 * be resilient to that.
    198	 */
    199	struct mutex mutex;
    200
    201	/**
    202	 * @saved_adjusted_mode: Copy of @drm_crtc_state.adjusted_mode
    203	 * for use by ALSA hooks and interrupt handlers. Protected by @mutex.
    204	 */
    205	struct drm_display_mode saved_adjusted_mode;
    206
    207	/**
    208	 * @output_enabled: Is the HDMI controller currently active?
    209	 * Protected by @mutex.
    210	 */
    211	bool output_enabled;
    212
    213	/**
    214	 * @scdc_enabled: Is the HDMI controller currently running with
    215	 * the scrambler on? Protected by @mutex.
    216	 */
    217	bool scdc_enabled;
    218
    219	/**
    220	 * @output_bpc: Copy of @vc4_connector_state.output_bpc for use
    221	 * outside of KMS hooks. Protected by @mutex.
    222	 */
    223	unsigned int output_bpc;
    224
    225	/**
    226	 * @output_format: Copy of @vc4_connector_state.output_format
    227	 * for use outside of KMS hooks. Protected by @mutex.
    228	 */
    229	enum vc4_hdmi_output_format output_format;
    230};
    231
    232static inline struct vc4_hdmi *
    233connector_to_vc4_hdmi(struct drm_connector *connector)
    234{
    235	return container_of(connector, struct vc4_hdmi, connector);
    236}
    237
    238static inline struct vc4_hdmi *
    239encoder_to_vc4_hdmi(struct drm_encoder *encoder)
    240{
    241	struct vc4_encoder *_encoder = to_vc4_encoder(encoder);
    242	return container_of(_encoder, struct vc4_hdmi, encoder);
    243}
    244
    245struct vc4_hdmi_connector_state {
    246	struct drm_connector_state	base;
    247	unsigned long long		tmds_char_rate;
    248	unsigned int 			output_bpc;
    249	enum vc4_hdmi_output_format	output_format;
    250};
    251
    252static inline struct vc4_hdmi_connector_state *
    253conn_state_to_vc4_hdmi_conn_state(struct drm_connector_state *conn_state)
    254{
    255	return container_of(conn_state, struct vc4_hdmi_connector_state, base);
    256}
    257
    258void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
    259		       struct vc4_hdmi_connector_state *vc4_conn_state);
    260void vc4_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi);
    261void vc4_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi);
    262void vc4_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi);
    263
    264void vc5_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
    265		       struct vc4_hdmi_connector_state *vc4_conn_state);
    266void vc5_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi);
    267void vc5_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi);
    268void vc5_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi);
    269
    270#endif /* _VC4_HDMI_H_ */