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

/*
 * Copyright © 2006 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]>
 *
 */

#include <linux/firmware.h>

#include <drm/display/drm_dp_helper.h>
#include <drm/display/drm_dsc_helper.h>
#include <drm/drm_edid.h>
#include <drm/drm_fixed.h>

#include "i915_drv.h"
#include "i915_reg.h"
#include "intel_display.h"
#include "intel_display_types.h"
#include "intel_gmbus.h"
#include "intel_uncore.h"

#define _INTEL_BIOS_PRIVATE
#include "intel_vbt_defs.h"

/**
 * DOC: Video BIOS Table (VBT)
 *
 * The Video BIOS Table, or VBT, provides platform and board specific
 * configuration information to the driver that is not discoverable or available
 * through other means. The configuration is mostly related to display
 * hardware. The VBT is available via the ACPI OpRegion or, on older systems, in
 * the PCI ROM.
 *
 * The VBT consists of a VBT Header (defined as &struct vbt_header), a BDB
 * Header (&struct bdb_header), and a number of BIOS Data Blocks (BDB) that
 * contain the actual configuration information. The VBT Header, and thus the
 * VBT, begins with "$VBT" signature. The VBT Header contains the offset of the
 * BDB Header. The data blocks are concatenated after the BDB Header. The data
 * blocks have a 1-byte Block ID, 2-byte Block Size, and Block Size bytes of
 * data. (Block 53, the MIPI Sequence Block is an exception.)
 *
 * The driver parses the VBT during load. The relevant information is stored in
 * driver private data for ease of use, and the actual VBT is not read after
 * that.
 */

/* Wrapper for VBT child device config */
struct intel_bios_encoder_data {};

#define TARGET_ADDR1
#define TARGET_ADDR2

/* Get BDB block size given a pointer to Block ID. */
static u32 _get_blocksize(const u8 *block_base)
{}

/* Get BDB block size give a pointer to data after Block ID and Block Size. */
static u32 get_blocksize(const void *block_data)
{}

static const void *
find_raw_section(const void *_bdb, enum bdb_block_id section_id)
{}

/*
 * Offset from the start of BDB to the start of the
 * block data (just past the block header).
 */
static u32 raw_block_offset(const void *bdb, enum bdb_block_id section_id)
{}

struct bdb_block_entry {};

static const void *
bdb_find_section(struct intel_display *display,
		 enum bdb_block_id section_id)
{}

static const struct {} bdb_blocks[] =;

static size_t lfp_data_min_size(struct intel_display *display)
{}

static bool validate_lfp_data_ptrs(const void *bdb,
				   const struct bdb_lfp_data_ptrs *ptrs)
{}

/* make the data table offsets relative to the data block */
static bool fixup_lfp_data_ptrs(const void *bdb, void *ptrs_block)
{}

static int make_lfp_data_ptr(struct lfp_data_ptr_table *table,
			     int table_size, int total_size)
{}

static void next_lfp_data_ptr(struct lfp_data_ptr_table *next,
			      const struct lfp_data_ptr_table *prev,
			      int size)
{}

static void *generate_lfp_data_ptrs(struct intel_display *display,
				    const void *bdb)
{}

static void
init_bdb_block(struct intel_display *display,
	       const void *bdb, enum bdb_block_id section_id,
	       size_t min_size)
{}

static void init_bdb_blocks(struct intel_display *display,
			    const void *bdb)
{}

static void
fill_detail_timing_data(struct intel_display *display,
			struct drm_display_mode *panel_fixed_mode,
			const struct bdb_edid_dtd *dvo_timing)
{}

static const struct bdb_edid_dtd *
get_lfp_dvo_timing(const struct bdb_lfp_data *data,
		   const struct bdb_lfp_data_ptrs *ptrs,
		   int index)
{}

static const struct fp_timing *
get_lfp_fp_timing(const struct bdb_lfp_data *data,
		  const struct bdb_lfp_data_ptrs *ptrs,
		  int index)
{}

static const struct drm_edid_product_id *
get_lfp_pnp_id(const struct bdb_lfp_data *data,
	       const struct bdb_lfp_data_ptrs *ptrs,
	       int index)
{}

static const struct bdb_lfp_data_tail *
get_lfp_data_tail(const struct bdb_lfp_data *data,
		  const struct bdb_lfp_data_ptrs *ptrs)
{}

static int opregion_get_panel_type(struct intel_display *display,
				   const struct intel_bios_encoder_data *devdata,
				   const struct drm_edid *drm_edid, bool use_fallback)
{}

static int vbt_get_panel_type(struct intel_display *display,
			      const struct intel_bios_encoder_data *devdata,
			      const struct drm_edid *drm_edid, bool use_fallback)
{}

static int pnpid_get_panel_type(struct intel_display *display,
				const struct intel_bios_encoder_data *devdata,
				const struct drm_edid *drm_edid, bool use_fallback)
{}

static int fallback_get_panel_type(struct intel_display *display,
				   const struct intel_bios_encoder_data *devdata,
				   const struct drm_edid *drm_edid, bool use_fallback)
{}

enum panel_type {};

static int get_panel_type(struct intel_display *display,
			  const struct intel_bios_encoder_data *devdata,
			  const struct drm_edid *drm_edid, bool use_fallback)
{}

static unsigned int panel_bits(unsigned int value, int panel_type, int num_bits)
{}

static bool panel_bool(unsigned int value, int panel_type)
{}

/* Parse general panel options */
static void
parse_panel_options(struct intel_display *display,
		    struct intel_panel *panel)
{}

static void
parse_lfp_panel_dtd(struct intel_display *display,
		    struct intel_panel *panel,
		    const struct bdb_lfp_data *lfp_data,
		    const struct bdb_lfp_data_ptrs *lfp_data_ptrs)
{}

static void
parse_lfp_data(struct intel_display *display,
	       struct intel_panel *panel)
{}

static void
parse_generic_dtd(struct intel_display *display,
		  struct intel_panel *panel)
{}

static void
parse_lfp_backlight(struct intel_display *display,
		    struct intel_panel *panel)
{}

static void
parse_sdvo_lvds_data(struct intel_display *display,
		     struct intel_panel *panel)
{}

static int intel_bios_ssc_frequency(struct intel_display *display,
				    bool alternate)
{}

static void
parse_general_features(struct intel_display *display)
{}

static const struct child_device_config *
child_device_ptr(const struct bdb_general_definitions *defs, int i)
{}

static void
parse_sdvo_device_mapping(struct intel_display *display)
{}

static void
parse_driver_features(struct intel_display *display)
{}

static void
parse_panel_driver_features(struct intel_display *display,
			    struct intel_panel *panel)
{}

static void
parse_power_conservation_features(struct intel_display *display,
				  struct intel_panel *panel)
{}

static void
parse_edp(struct intel_display *display,
	  struct intel_panel *panel)
{}

static void
parse_psr(struct intel_display *display,
	  struct intel_panel *panel)
{}

static void parse_dsi_backlight_ports(struct intel_display *display,
				      struct intel_panel *panel,
				      enum port port)
{}

static void
parse_mipi_config(struct intel_display *display,
		  struct intel_panel *panel)
{}

/* Find the sequence block and size for the given panel. */
static const u8 *
find_panel_sequence_block(struct intel_display *display,
			  const struct bdb_mipi_sequence *sequence,
			  u16 panel_id, u32 *seq_size)
{}

static int goto_next_sequence(struct intel_display *display,
			      const u8 *data, int index, int total)
{}

static int goto_next_sequence_v3(struct intel_display *display,
				 const u8 *data, int index, int total)
{}

/*
 * Get len of pre-fixed deassert fragment from a v1 init OTP sequence,
 * skip all delay + gpio operands and stop at the first DSI packet op.
 */
static int get_init_otp_deassert_fragment_len(struct intel_display *display,
					      struct intel_panel *panel)
{}

/*
 * Some v1 VBT MIPI sequences do the deassert in the init OTP sequence.
 * The deassert must be done before calling intel_dsi_device_ready, so for
 * these devices we split the init OTP sequence into a deassert sequence and
 * the actual init OTP part.
 */
static void vlv_fixup_mipi_sequences(struct intel_display *display,
				     struct intel_panel *panel)
{}

/*
 * Some machines (eg. Lenovo 82TQ) appear to have broken
 * VBT sequences:
 * - INIT_OTP is not present at all
 * - what should be in INIT_OTP is in DISPLAY_ON
 * - what should be in DISPLAY_ON is in BACKLIGHT_ON
 *   (along with the actual backlight stuff)
 *
 * To make those work we simply swap DISPLAY_ON and INIT_OTP.
 *
 * TODO: Do we need to limit this to specific machines,
 *       or examine the contents of the sequences to
 *       avoid false positives?
 */
static void icl_fixup_mipi_sequences(struct intel_display *display,
				     struct intel_panel *panel)
{}

static void fixup_mipi_sequences(struct intel_display *display,
				 struct intel_panel *panel)
{}

static void
parse_mipi_sequence(struct intel_display *display,
		    struct intel_panel *panel)
{}

static void
parse_compression_parameters(struct intel_display *display)
{}

static u8 translate_iboost(struct intel_display *display, u8 val)
{}

static const u8 cnp_ddc_pin_map[] =;

static const u8 icp_ddc_pin_map[] =;

static const u8 rkl_pch_tgp_ddc_pin_map[] =;

static const u8 adls_ddc_pin_map[] =;

static const u8 gen9bc_tgp_ddc_pin_map[] =;

static const u8 adlp_ddc_pin_map[] =;

static u8 map_ddc_pin(struct intel_display *display, u8 vbt_pin)
{}

static u8 dvo_port_type(u8 dvo_port)
{}

static enum port __dvo_port_to_port(int n_ports, int n_dvo,
				    const int port_mapping[][3], u8 dvo_port)
{}

static enum port dvo_port_to_port(struct intel_display *display,
				  u8 dvo_port)
{}

static enum port
dsi_dvo_port_to_port(struct intel_display *display, u8 dvo_port)
{}

enum port intel_bios_encoder_port(const struct intel_bios_encoder_data *devdata)
{}

static int parse_bdb_230_dp_max_link_rate(const int vbt_max_link_rate)
{}

static int parse_bdb_216_dp_max_link_rate(const int vbt_max_link_rate)
{}

int intel_bios_dp_max_link_rate(const struct intel_bios_encoder_data *devdata)
{}

int intel_bios_dp_max_lane_count(const struct intel_bios_encoder_data *devdata)
{}

static void sanitize_device_type(struct intel_bios_encoder_data *devdata,
				 enum port port)
{}

static void sanitize_hdmi_level_shift(struct intel_bios_encoder_data *devdata,
				      enum port port)
{}

static bool
intel_bios_encoder_supports_crt(const struct intel_bios_encoder_data *devdata)
{}

bool
intel_bios_encoder_supports_dvi(const struct intel_bios_encoder_data *devdata)
{}

bool
intel_bios_encoder_supports_hdmi(const struct intel_bios_encoder_data *devdata)
{}

bool
intel_bios_encoder_supports_dp(const struct intel_bios_encoder_data *devdata)
{}

bool
intel_bios_encoder_supports_edp(const struct intel_bios_encoder_data *devdata)
{}

bool
intel_bios_encoder_supports_dsi(const struct intel_bios_encoder_data *devdata)
{}

bool
intel_bios_encoder_is_lspcon(const struct intel_bios_encoder_data *devdata)
{}

/* This is an index in the HDMI/DVI DDI buffer translation table, or -1 */
int intel_bios_hdmi_level_shift(const struct intel_bios_encoder_data *devdata)
{}

int intel_bios_hdmi_max_tmds_clock(const struct intel_bios_encoder_data *devdata)
{}

static bool is_port_valid(struct intel_display *display, enum port port)
{}

static void print_ddi_port(const struct intel_bios_encoder_data *devdata)
{}

static void parse_ddi_port(struct intel_bios_encoder_data *devdata)
{}

static bool has_ddi_port_info(struct intel_display *display)
{}

static void parse_ddi_ports(struct intel_display *display)
{}

static int child_device_expected_size(u16 version)
{}

static bool child_device_size_valid(struct intel_display *display, int size)
{}

static void
parse_general_definitions(struct intel_display *display)
{}

/* Common defaults which may be overridden by VBT. */
static void
init_vbt_defaults(struct intel_display *display)
{}

/* Common defaults which may be overridden by VBT. */
static void
init_vbt_panel_defaults(struct intel_panel *panel)
{}

/* Defaults to initialize only if there is no VBT. */
static void
init_vbt_missing_defaults(struct intel_display *display)
{}

static const struct bdb_header *get_bdb_header(const struct vbt_header *vbt)
{}

/**
 * intel_bios_is_valid_vbt - does the given buffer contain a valid VBT
 * @display:	display device
 * @buf:	pointer to a buffer to validate
 * @size:	size of the buffer
 *
 * Returns true on valid VBT.
 */
bool intel_bios_is_valid_vbt(struct intel_display *display,
			     const void *buf, size_t size)
{}

static struct vbt_header *firmware_get_vbt(struct intel_display *display,
					   size_t *size)
{}

static u32 intel_spi_read(struct intel_uncore *uncore, u32 offset)
{}

static struct vbt_header *spi_oprom_get_vbt(struct intel_display *display,
					    size_t *size)
{}

static struct vbt_header *oprom_get_vbt(struct intel_display *display,
					size_t *sizep)
{}

static const struct vbt_header *intel_bios_get_vbt(struct intel_display *display,
						   size_t *sizep)
{}

/**
 * intel_bios_init - find VBT and initialize settings from the BIOS
 * @display: display device instance
 *
 * Parse and initialize settings from the Video BIOS Tables (VBT). If the VBT
 * was not found in ACPI OpRegion, try to find it in PCI ROM first. Also
 * initialize some defaults if the VBT is not present at all.
 */
void intel_bios_init(struct intel_display *display)
{}

static void intel_bios_init_panel(struct intel_display *display,
				  struct intel_panel *panel,
				  const struct intel_bios_encoder_data *devdata,
				  const struct drm_edid *drm_edid,
				  bool use_fallback)
{}

void intel_bios_init_panel_early(struct intel_display *display,
				 struct intel_panel *panel,
				 const struct intel_bios_encoder_data *devdata)
{}

void intel_bios_init_panel_late(struct intel_display *display,
				struct intel_panel *panel,
				const struct intel_bios_encoder_data *devdata,
				const struct drm_edid *drm_edid)
{}

/**
 * intel_bios_driver_remove - Free any resources allocated by intel_bios_init()
 * @display: display device instance
 */
void intel_bios_driver_remove(struct intel_display *display)
{}

void intel_bios_fini_panel(struct intel_panel *panel)
{}

/**
 * intel_bios_is_tv_present - is integrated TV present in VBT
 * @display: display device instance
 *
 * Return true if TV is present. If no child devices were parsed from VBT,
 * assume TV is present.
 */
bool intel_bios_is_tv_present(struct intel_display *display)
{}

/**
 * intel_bios_is_lvds_present - is LVDS present in VBT
 * @display: display device instance
 * @i2c_pin:	i2c pin for LVDS if present
 *
 * Return true if LVDS is present. If no child devices were parsed from VBT,
 * assume LVDS is present.
 */
bool intel_bios_is_lvds_present(struct intel_display *display, u8 *i2c_pin)
{}

/**
 * intel_bios_is_port_present - is the specified digital port present
 * @display: display device instance
 * @port:	port to check
 *
 * Return true if the device in %port is present.
 */
bool intel_bios_is_port_present(struct intel_display *display, enum port port)
{}

bool intel_bios_encoder_supports_dp_dual_mode(const struct intel_bios_encoder_data *devdata)
{}

/**
 * intel_bios_is_dsi_present - is DSI present in VBT
 * @display: display device instance
 * @port:	port for DSI if present
 *
 * Return true if DSI is present, and return the port in %port.
 */
bool intel_bios_is_dsi_present(struct intel_display *display,
			       enum port *port)
{}

static void fill_dsc(struct intel_crtc_state *crtc_state,
		     struct dsc_compression_parameters_entry *dsc,
		     int dsc_max_bpc)
{}

/* FIXME: initially DSI specific */
bool intel_bios_get_dsc_params(struct intel_encoder *encoder,
			       struct intel_crtc_state *crtc_state,
			       int dsc_max_bpc)
{}

static const u8 adlp_aux_ch_map[] =;

/*
 * ADL-S VBT uses PHY based mapping. Combo PHYs A,B,C,D,E
 * map to DDI A,TC1,TC2,TC3,TC4 respectively.
 */
static const u8 adls_aux_ch_map[] =;

/*
 * RKL/DG1 VBT uses PHY based mapping. Combo PHYs A,B,C,D
 * map to DDI A,B,TC1,TC2 respectively.
 */
static const u8 rkl_aux_ch_map[] =;

static const u8 direct_aux_ch_map[] =;

static enum aux_ch map_aux_ch(struct intel_display *display, u8 aux_channel)
{}

enum aux_ch intel_bios_dp_aux_ch(const struct intel_bios_encoder_data *devdata)
{}

bool intel_bios_dp_has_shared_aux_ch(const struct intel_bios_encoder_data *devdata)
{}

int intel_bios_dp_boost_level(const struct intel_bios_encoder_data *devdata)
{}

int intel_bios_hdmi_boost_level(const struct intel_bios_encoder_data *devdata)
{}

int intel_bios_hdmi_ddc_pin(const struct intel_bios_encoder_data *devdata)
{}

bool intel_bios_encoder_supports_typec_usb(const struct intel_bios_encoder_data *devdata)
{}

bool intel_bios_encoder_supports_tbt(const struct intel_bios_encoder_data *devdata)
{}

bool intel_bios_encoder_lane_reversal(const struct intel_bios_encoder_data *devdata)
{}

bool intel_bios_encoder_hpd_invert(const struct intel_bios_encoder_data *devdata)
{}

const struct intel_bios_encoder_data *
intel_bios_encoder_data_lookup(struct intel_display *display, enum port port)
{}

void intel_bios_for_each_encoder(struct intel_display *display,
				 void (*func)(struct intel_display *display,
					      const struct intel_bios_encoder_data *devdata))
{}

static int intel_bios_vbt_show(struct seq_file *m, void *unused)
{}

DEFINE_SHOW_ATTRIBUTE();

void intel_bios_debugfs_register(struct intel_display *display)
{}