linux/drivers/gpu/drm/i915/display/intel_hdmi.c

/*
 * Copyright 2006 Dave Airlie <[email protected]>
 * Copyright © 2006-2009 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Authors:
 *	Eric Anholt <[email protected]>
 *	Jesse Barnes <[email protected]>
 */

#include <linux/delay.h>
#include <linux/hdmi.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/string_helpers.h>

#include <drm/display/drm_hdcp_helper.h>
#include <drm/display/drm_hdmi_helper.h>
#include <drm/display/drm_scdc_helper.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
#include <drm/intel/intel_lpe_audio.h>

#include "g4x_hdmi.h"
#include "i915_drv.h"
#include "i915_reg.h"
#include "intel_atomic.h"
#include "intel_audio.h"
#include "intel_connector.h"
#include "intel_cx0_phy.h"
#include "intel_ddi.h"
#include "intel_de.h"
#include "intel_display_driver.h"
#include "intel_display_types.h"
#include "intel_dp.h"
#include "intel_gmbus.h"
#include "intel_hdcp.h"
#include "intel_hdcp_regs.h"
#include "intel_hdmi.h"
#include "intel_lspcon.h"
#include "intel_panel.h"
#include "intel_snps_phy.h"

static void
assert_hdmi_port_disabled(struct intel_hdmi *intel_hdmi)
{}

static void
assert_hdmi_transcoder_func_disabled(struct intel_display *display,
				     enum transcoder cpu_transcoder)
{}

static u32 g4x_infoframe_index(unsigned int type)
{}

static u32 g4x_infoframe_enable(unsigned int type)
{}

static u32 hsw_infoframe_enable(unsigned int type)
{}

static i915_reg_t
hsw_dip_data_reg(struct intel_display *display,
		 enum transcoder cpu_transcoder,
		 unsigned int type,
		 int i)
{}

static int hsw_dip_data_size(struct intel_display *display,
			     unsigned int type)
{}

static void g4x_write_infoframe(struct intel_encoder *encoder,
				const struct intel_crtc_state *crtc_state,
				unsigned int type,
				const void *frame, ssize_t len)
{}

static void g4x_read_infoframe(struct intel_encoder *encoder,
			       const struct intel_crtc_state *crtc_state,
			       unsigned int type,
			       void *frame, ssize_t len)
{}

static u32 g4x_infoframes_enabled(struct intel_encoder *encoder,
				  const struct intel_crtc_state *pipe_config)
{}

static void ibx_write_infoframe(struct intel_encoder *encoder,
				const struct intel_crtc_state *crtc_state,
				unsigned int type,
				const void *frame, ssize_t len)
{}

static void ibx_read_infoframe(struct intel_encoder *encoder,
			       const struct intel_crtc_state *crtc_state,
			       unsigned int type,
			       void *frame, ssize_t len)
{}

static u32 ibx_infoframes_enabled(struct intel_encoder *encoder,
				  const struct intel_crtc_state *pipe_config)
{}

static void cpt_write_infoframe(struct intel_encoder *encoder,
				const struct intel_crtc_state *crtc_state,
				unsigned int type,
				const void *frame, ssize_t len)
{}

static void cpt_read_infoframe(struct intel_encoder *encoder,
			       const struct intel_crtc_state *crtc_state,
			       unsigned int type,
			       void *frame, ssize_t len)
{}

static u32 cpt_infoframes_enabled(struct intel_encoder *encoder,
				  const struct intel_crtc_state *pipe_config)
{}

static void vlv_write_infoframe(struct intel_encoder *encoder,
				const struct intel_crtc_state *crtc_state,
				unsigned int type,
				const void *frame, ssize_t len)
{}

static void vlv_read_infoframe(struct intel_encoder *encoder,
			       const struct intel_crtc_state *crtc_state,
			       unsigned int type,
			       void *frame, ssize_t len)
{}

static u32 vlv_infoframes_enabled(struct intel_encoder *encoder,
				  const struct intel_crtc_state *pipe_config)
{}

void hsw_write_infoframe(struct intel_encoder *encoder,
			 const struct intel_crtc_state *crtc_state,
			 unsigned int type,
			 const void *frame, ssize_t len)
{}

void hsw_read_infoframe(struct intel_encoder *encoder,
			const struct intel_crtc_state *crtc_state,
			unsigned int type, void *frame, ssize_t len)
{}

static u32 hsw_infoframes_enabled(struct intel_encoder *encoder,
				  const struct intel_crtc_state *pipe_config)
{}

static const u8 infoframe_type_to_idx[] =;

u32 intel_hdmi_infoframe_enable(unsigned int type)
{}

u32 intel_hdmi_infoframes_enabled(struct intel_encoder *encoder,
				  const struct intel_crtc_state *crtc_state)
{}

/*
 * The data we write to the DIP data buffer registers is 1 byte bigger than the
 * HDMI infoframe size because of an ECC/reserved byte at position 3 (starting
 * at 0). It's also a byte used by DisplayPort so the same DIP registers can be
 * used for both technologies.
 *
 * DW0: Reserved/ECC/DP | HB2 | HB1 | HB0
 * DW1:       DB3       | DB2 | DB1 | DB0
 * DW2:       DB7       | DB6 | DB5 | DB4
 * DW3: ...
 *
 * (HB is Header Byte, DB is Data Byte)
 *
 * The hdmi pack() functions don't know about that hardware specific hole so we
 * trick them by giving an offset into the buffer and moving back the header
 * bytes by one.
 */
static void intel_write_infoframe(struct intel_encoder *encoder,
				  const struct intel_crtc_state *crtc_state,
				  enum hdmi_infoframe_type type,
				  const union hdmi_infoframe *frame)
{}

void intel_read_infoframe(struct intel_encoder *encoder,
			  const struct intel_crtc_state *crtc_state,
			  enum hdmi_infoframe_type type,
			  union hdmi_infoframe *frame)
{}

static bool
intel_hdmi_compute_avi_infoframe(struct intel_encoder *encoder,
				 struct intel_crtc_state *crtc_state,
				 struct drm_connector_state *conn_state)
{}

static bool
intel_hdmi_compute_spd_infoframe(struct intel_encoder *encoder,
				 struct intel_crtc_state *crtc_state,
				 struct drm_connector_state *conn_state)
{}

static bool
intel_hdmi_compute_hdmi_infoframe(struct intel_encoder *encoder,
				  struct intel_crtc_state *crtc_state,
				  struct drm_connector_state *conn_state)
{}

static bool
intel_hdmi_compute_drm_infoframe(struct intel_encoder *encoder,
				 struct intel_crtc_state *crtc_state,
				 struct drm_connector_state *conn_state)
{}

static void g4x_set_infoframes(struct intel_encoder *encoder,
			       bool enable,
			       const struct intel_crtc_state *crtc_state,
			       const struct drm_connector_state *conn_state)
{}

/*
 * Determine if default_phase=1 can be indicated in the GCP infoframe.
 *
 * From HDMI specification 1.4a:
 * - The first pixel of each Video Data Period shall always have a pixel packing phase of 0
 * - The first pixel following each Video Data Period shall have a pixel packing phase of 0
 * - The PP bits shall be constant for all GCPs and will be equal to the last packing phase
 * - The first pixel following every transition of HSYNC or VSYNC shall have a pixel packing
 *   phase of 0
 */
static bool gcp_default_phase_possible(int pipe_bpp,
				       const struct drm_display_mode *mode)
{}

static bool intel_hdmi_set_gcp_infoframe(struct intel_encoder *encoder,
					 const struct intel_crtc_state *crtc_state,
					 const struct drm_connector_state *conn_state)
{}

void intel_hdmi_read_gcp_infoframe(struct intel_encoder *encoder,
				   struct intel_crtc_state *crtc_state)
{}

static void intel_hdmi_compute_gcp_infoframe(struct intel_encoder *encoder,
					     struct intel_crtc_state *crtc_state,
					     struct drm_connector_state *conn_state)
{}

static void ibx_set_infoframes(struct intel_encoder *encoder,
			       bool enable,
			       const struct intel_crtc_state *crtc_state,
			       const struct drm_connector_state *conn_state)
{}

static void cpt_set_infoframes(struct intel_encoder *encoder,
			       bool enable,
			       const struct intel_crtc_state *crtc_state,
			       const struct drm_connector_state *conn_state)
{}

static void vlv_set_infoframes(struct intel_encoder *encoder,
			       bool enable,
			       const struct intel_crtc_state *crtc_state,
			       const struct drm_connector_state *conn_state)
{}

static void hsw_set_infoframes(struct intel_encoder *encoder,
			       bool enable,
			       const struct intel_crtc_state *crtc_state,
			       const struct drm_connector_state *conn_state)
{}

void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable)
{}

static int intel_hdmi_hdcp_read(struct intel_digital_port *dig_port,
				unsigned int offset, void *buffer, size_t size)
{}

static int intel_hdmi_hdcp_write(struct intel_digital_port *dig_port,
				 unsigned int offset, void *buffer, size_t size)
{}

static
int intel_hdmi_hdcp_write_an_aksv(struct intel_digital_port *dig_port,
				  u8 *an)
{}

static int intel_hdmi_hdcp_read_bksv(struct intel_digital_port *dig_port,
				     u8 *bksv)
{}

static
int intel_hdmi_hdcp_read_bstatus(struct intel_digital_port *dig_port,
				 u8 *bstatus)
{}

static
int intel_hdmi_hdcp_repeater_present(struct intel_digital_port *dig_port,
				     bool *repeater_present)
{}

static
int intel_hdmi_hdcp_read_ri_prime(struct intel_digital_port *dig_port,
				  u8 *ri_prime)
{}

static
int intel_hdmi_hdcp_read_ksv_ready(struct intel_digital_port *dig_port,
				   bool *ksv_ready)
{}

static
int intel_hdmi_hdcp_read_ksv_fifo(struct intel_digital_port *dig_port,
				  int num_downstream, u8 *ksv_fifo)
{}

static
int intel_hdmi_hdcp_read_v_prime_part(struct intel_digital_port *dig_port,
				      int i, u32 *part)
{}

static int kbl_repositioning_enc_en_signal(struct intel_connector *connector,
					   enum transcoder cpu_transcoder)
{}

static
int intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port *dig_port,
				      enum transcoder cpu_transcoder,
				      bool enable)
{}

static
bool intel_hdmi_hdcp_check_link_once(struct intel_digital_port *dig_port,
				     struct intel_connector *connector)
{}

static
bool intel_hdmi_hdcp_check_link(struct intel_digital_port *dig_port,
				struct intel_connector *connector)
{}

struct hdcp2_hdmi_msg_timeout {};

static const struct hdcp2_hdmi_msg_timeout hdcp2_msg_timeout[] =;

static
int intel_hdmi_hdcp2_read_rx_status(struct intel_digital_port *dig_port,
				    u8 *rx_status)
{}

static int get_hdcp2_msg_timeout(u8 msg_id, bool is_paired)
{}

static int
hdcp2_detect_msg_availability(struct intel_digital_port *dig_port,
			      u8 msg_id, bool *msg_ready,
			      ssize_t *msg_sz)
{}

static ssize_t
intel_hdmi_hdcp2_wait_for_msg(struct intel_digital_port *dig_port,
			      u8 msg_id, bool paired)
{}

static
int intel_hdmi_hdcp2_write_msg(struct intel_connector *connector,
			       void *buf, size_t size)
{}

static
int intel_hdmi_hdcp2_read_msg(struct intel_connector *connector,
			      u8 msg_id, void *buf, size_t size)
{}

static
int intel_hdmi_hdcp2_check_link(struct intel_digital_port *dig_port,
				struct intel_connector *connector)
{}

static
int intel_hdmi_hdcp2_get_capability(struct intel_connector *connector,
				    bool *capable)
{}

static const struct intel_hdcp_shim intel_hdmi_hdcp_shim =;

static int intel_hdmi_source_max_tmds_clock(struct intel_encoder *encoder)
{}

static bool intel_has_hdmi_sink(struct intel_hdmi *hdmi,
				const struct drm_connector_state *conn_state)
{}

static bool intel_hdmi_is_ycbcr420(const struct intel_crtc_state *crtc_state)
{}

static int hdmi_port_clock_limit(struct intel_hdmi *hdmi,
				 bool respect_downstream_limits,
				 bool has_hdmi_sink)
{}

static enum drm_mode_status
hdmi_port_clock_valid(struct intel_hdmi *hdmi,
		      int clock, bool respect_downstream_limits,
		      bool has_hdmi_sink)
{}

int intel_hdmi_tmds_clock(int clock, int bpc,
			  enum intel_output_format sink_format)
{}

static bool intel_hdmi_source_bpc_possible(struct intel_display *display, int bpc)
{}

static bool intel_hdmi_sink_bpc_possible(struct drm_connector *connector,
					 int bpc, bool has_hdmi_sink,
					 enum intel_output_format sink_format)
{}

static enum drm_mode_status
intel_hdmi_mode_clock_valid(struct drm_connector *connector, int clock,
			    bool has_hdmi_sink,
			    enum intel_output_format sink_format)
{}

static enum drm_mode_status
intel_hdmi_mode_valid(struct drm_connector *connector,
		      struct drm_display_mode *mode)
{}

bool intel_hdmi_bpc_possible(const struct intel_crtc_state *crtc_state,
			     int bpc, bool has_hdmi_sink)
{}

static bool hdmi_bpc_possible(const struct intel_crtc_state *crtc_state, int bpc)
{}

static int intel_hdmi_compute_bpc(struct intel_encoder *encoder,
				  struct intel_crtc_state *crtc_state,
				  int clock, bool respect_downstream_limits)
{}

static int intel_hdmi_compute_clock(struct intel_encoder *encoder,
				    struct intel_crtc_state *crtc_state,
				    bool respect_downstream_limits)
{}

bool intel_hdmi_limited_color_range(const struct intel_crtc_state *crtc_state,
				    const struct drm_connector_state *conn_state)
{}

static bool intel_hdmi_has_audio(struct intel_encoder *encoder,
				 const struct intel_crtc_state *crtc_state,
				 const struct drm_connector_state *conn_state)
{}

static enum intel_output_format
intel_hdmi_sink_format(const struct intel_crtc_state *crtc_state,
		       struct intel_connector *connector,
		       bool ycbcr_420_output)
{}

static enum intel_output_format
intel_hdmi_output_format(const struct intel_crtc_state *crtc_state)
{}

static int intel_hdmi_compute_output_format(struct intel_encoder *encoder,
					    struct intel_crtc_state *crtc_state,
					    const struct drm_connector_state *conn_state,
					    bool respect_downstream_limits)
{}

static bool intel_hdmi_is_cloned(const struct intel_crtc_state *crtc_state)
{}

static bool source_supports_scrambling(struct intel_encoder *encoder)
{}

bool intel_hdmi_compute_has_hdmi_sink(struct intel_encoder *encoder,
				      const struct intel_crtc_state *crtc_state,
				      const struct drm_connector_state *conn_state)
{}

int intel_hdmi_compute_config(struct intel_encoder *encoder,
			      struct intel_crtc_state *pipe_config,
			      struct drm_connector_state *conn_state)
{}

void intel_hdmi_encoder_shutdown(struct intel_encoder *encoder)
{}

static void
intel_hdmi_unset_edid(struct drm_connector *connector)
{}

static void
intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector)
{}

static bool
intel_hdmi_set_edid(struct drm_connector *connector)
{}

static enum drm_connector_status
intel_hdmi_detect(struct drm_connector *connector, bool force)
{}

static void
intel_hdmi_force(struct drm_connector *connector)
{}

static int intel_hdmi_get_modes(struct drm_connector *connector)
{}

static int
intel_hdmi_connector_register(struct drm_connector *connector)
{}

static void intel_hdmi_connector_unregister(struct drm_connector *connector)
{}

static const struct drm_connector_funcs intel_hdmi_connector_funcs =;

static int intel_hdmi_connector_atomic_check(struct drm_connector *connector,
					     struct drm_atomic_state *state)
{}

static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs =;

static void
intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *connector)
{}

/*
 * intel_hdmi_handle_sink_scrambling: handle sink scrambling/clock ratio setup
 * @encoder: intel_encoder
 * @connector: drm_connector
 * @high_tmds_clock_ratio = bool to indicate if the function needs to set
 *  or reset the high tmds clock ratio for scrambling
 * @scrambling: bool to Indicate if the function needs to set or reset
 *  sink scrambling
 *
 * This function handles scrambling on HDMI 2.0 capable sinks.
 * If required clock rate is > 340 Mhz && scrambling is supported by sink
 * it enables scrambling. This should be called before enabling the HDMI
 * 2.0 port, as the sink can choose to disable the scrambling if it doesn't
 * detect a scrambled clock within 100 ms.
 *
 * Returns:
 * True on success, false on failure.
 */
bool intel_hdmi_handle_sink_scrambling(struct intel_encoder *encoder,
				       struct drm_connector *connector,
				       bool high_tmds_clock_ratio,
				       bool scrambling)
{}

static u8 chv_encoder_to_ddc_pin(struct intel_encoder *encoder)
{}

static u8 bxt_encoder_to_ddc_pin(struct intel_encoder *encoder)
{}

static u8 cnp_encoder_to_ddc_pin(struct intel_encoder *encoder)
{}

static u8 icl_encoder_to_ddc_pin(struct intel_encoder *encoder)
{}

static u8 mcc_encoder_to_ddc_pin(struct intel_encoder *encoder)
{}

static u8 rkl_encoder_to_ddc_pin(struct intel_encoder *encoder)
{}

static u8 gen9bc_tgp_encoder_to_ddc_pin(struct intel_encoder *encoder)
{}

static u8 dg1_encoder_to_ddc_pin(struct intel_encoder *encoder)
{}

static u8 adls_encoder_to_ddc_pin(struct intel_encoder *encoder)
{}

static u8 g4x_encoder_to_ddc_pin(struct intel_encoder *encoder)
{}

static u8 intel_hdmi_default_ddc_pin(struct intel_encoder *encoder)
{}

static struct intel_encoder *
get_encoder_by_ddc_pin(struct intel_encoder *encoder, u8 ddc_pin)
{}

static u8 intel_hdmi_ddc_pin(struct intel_encoder *encoder)
{}

void intel_infoframe_init(struct intel_digital_port *dig_port)
{}

void intel_hdmi_init_connector(struct intel_digital_port *dig_port,
			       struct intel_connector *intel_connector)
{}

/*
 * intel_hdmi_dsc_get_slice_height - get the dsc slice_height
 * @vactive: Vactive of a display mode
 *
 * @return: appropriate dsc slice height for a given mode.
 */
int intel_hdmi_dsc_get_slice_height(int vactive)
{}

/*
 * intel_hdmi_dsc_get_num_slices - get no. of dsc slices based on dsc encoder
 * and dsc decoder capabilities
 *
 * @crtc_state: intel crtc_state
 * @src_max_slices: maximum slices supported by the DSC encoder
 * @src_max_slice_width: maximum slice width supported by DSC encoder
 * @hdmi_max_slices: maximum slices supported by sink DSC decoder
 * @hdmi_throughput: maximum clock per slice (MHz) supported by HDMI sink
 *
 * @return: num of dsc slices that can be supported by the dsc encoder
 * and decoder.
 */
int
intel_hdmi_dsc_get_num_slices(const struct intel_crtc_state *crtc_state,
			      int src_max_slices, int src_max_slice_width,
			      int hdmi_max_slices, int hdmi_throughput)
{}

/*
 * intel_hdmi_dsc_get_bpp - get the appropriate compressed bits_per_pixel based on
 * source and sink capabilities.
 *
 * @src_fraction_bpp: fractional bpp supported by the source
 * @slice_width: dsc slice width supported by the source and sink
 * @num_slices: num of slices supported by the source and sink
 * @output_format: video output format
 * @hdmi_all_bpp: sink supports decoding of 1/16th bpp setting
 * @hdmi_max_chunk_bytes: max bytes in a line of chunks supported by sink
 *
 * @return: compressed bits_per_pixel in step of 1/16 of bits_per_pixel
 */
int
intel_hdmi_dsc_get_bpp(int src_fractional_bpp, int slice_width, int num_slices,
		       int output_format, bool hdmi_all_bpp,
		       int hdmi_max_chunk_bytes)
{}