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

/*
 * Copyright © 2014 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.
 */

#include <linux/component.h>
#include <linux/kernel.h>

#include <drm/drm_edid.h>
#include <drm/drm_eld.h>
#include <drm/drm_fixed.h>
#include <drm/intel/i915_component.h>

#include "i915_drv.h"
#include "intel_atomic.h"
#include "intel_audio.h"
#include "intel_audio_regs.h"
#include "intel_cdclk.h"
#include "intel_crtc.h"
#include "intel_de.h"
#include "intel_display_types.h"
#include "intel_lpe_audio.h"

/**
 * DOC: High Definition Audio over HDMI and Display Port
 *
 * The graphics and audio drivers together support High Definition Audio over
 * HDMI and Display Port. The audio programming sequences are divided into audio
 * codec and controller enable and disable sequences. The graphics driver
 * handles the audio codec sequences, while the audio driver handles the audio
 * controller sequences.
 *
 * The disable sequences must be performed before disabling the transcoder or
 * port. The enable sequences may only be performed after enabling the
 * transcoder and port, and after completed link training. Therefore the audio
 * enable/disable sequences are part of the modeset sequence.
 *
 * The codec and controller sequences could be done either parallel or serial,
 * but generally the ELDV/PD change in the codec sequence indicates to the audio
 * driver that the controller sequence should start. Indeed, most of the
 * co-operation between the graphics and audio drivers is handled via audio
 * related registers. (The notable exception is the power management, not
 * covered here.)
 *
 * The struct &i915_audio_component is used to interact between the graphics
 * and audio drivers. The struct &i915_audio_component_ops @ops in it is
 * defined in graphics driver and called in audio driver. The
 * struct &i915_audio_component_audio_ops @audio_ops is called from i915 driver.
 */

struct intel_audio_funcs {};

struct hdmi_aud_ncts {};

static const struct {} hdmi_audio_clock[] =;

/* HDMI N/CTS table */
#define TMDS_297M
#define TMDS_296M
#define TMDS_594M
#define TMDS_593M

static const struct hdmi_aud_ncts hdmi_aud_ncts_24bpp[] =;

/* Appendix C - N & CTS values for deep color from HDMI 2.0 spec*/
/* HDMI N/CTS table for 10 bit deep color(30 bpp)*/
#define TMDS_371M
#define TMDS_370M

static const struct hdmi_aud_ncts hdmi_aud_ncts_30bpp[] =;

/* HDMI N/CTS table for 12 bit deep color(36 bpp)*/
#define TMDS_445_5M
#define TMDS_445M

static const struct hdmi_aud_ncts hdmi_aud_ncts_36bpp[] =;

/*
 * WA_14020863754: Implement Audio Workaround
 * Corner case with Min Hblank Fix can cause audio hang
 */
static bool needs_wa_14020863754(struct drm_i915_private *i915)
{}

/* get AUD_CONFIG_PIXEL_CLOCK_HDMI_* value for mode */
static u32 audio_config_hdmi_pixel_clock(const struct intel_crtc_state *crtc_state)
{}

static int audio_config_hdmi_get_n(const struct intel_crtc_state *crtc_state,
				   int rate)
{}

/* ELD buffer size in dwords */
static int g4x_eld_buffer_size(struct drm_i915_private *i915)
{}

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

static void g4x_audio_codec_disable(struct intel_encoder *encoder,
				    const struct intel_crtc_state *old_crtc_state,
				    const struct drm_connector_state *old_conn_state)
{}

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

static void
hsw_dp_audio_config_update(struct intel_encoder *encoder,
			   const struct intel_crtc_state *crtc_state)
{}

static void
hsw_hdmi_audio_config_update(struct intel_encoder *encoder,
			     const struct intel_crtc_state *crtc_state)
{}

static void
hsw_audio_config_update(struct intel_encoder *encoder,
			const struct intel_crtc_state *crtc_state)
{}

static void hsw_audio_codec_disable(struct intel_encoder *encoder,
				    const struct intel_crtc_state *old_crtc_state,
				    const struct drm_connector_state *old_conn_state)
{}

static unsigned int calc_hblank_early_prog(struct intel_encoder *encoder,
					   const struct intel_crtc_state *crtc_state)
{}

static unsigned int calc_samples_room(const struct intel_crtc_state *crtc_state)
{}

static void enable_audio_dsc_wa(struct intel_encoder *encoder,
				const struct intel_crtc_state *crtc_state)
{}

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

struct ibx_audio_regs {};

static void ibx_audio_regs_init(struct drm_i915_private *i915,
				enum pipe pipe,
				struct ibx_audio_regs *regs)
{}

static void ibx_audio_codec_disable(struct intel_encoder *encoder,
				    const struct intel_crtc_state *old_crtc_state,
				    const struct drm_connector_state *old_conn_state)
{}

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

void intel_audio_sdp_split_update(const struct intel_crtc_state *crtc_state)
{}

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

/**
 * intel_audio_codec_enable - Enable the audio codec for HD audio
 * @encoder: encoder on which to enable audio
 * @crtc_state: pointer to the current crtc state.
 * @conn_state: pointer to the current connector state.
 *
 * The enable sequences may only be performed after enabling the transcoder and
 * port, and after completed link training.
 */
void intel_audio_codec_enable(struct intel_encoder *encoder,
			      const struct intel_crtc_state *crtc_state,
			      const struct drm_connector_state *conn_state)
{}

/**
 * intel_audio_codec_disable - Disable the audio codec for HD audio
 * @encoder: encoder on which to disable audio
 * @old_crtc_state: pointer to the old crtc state.
 * @old_conn_state: pointer to the old connector state.
 *
 * The disable sequences must be performed before disabling the transcoder or
 * port.
 */
void intel_audio_codec_disable(struct intel_encoder *encoder,
			       const struct intel_crtc_state *old_crtc_state,
			       const struct drm_connector_state *old_conn_state)
{}

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

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

static const struct intel_audio_funcs g4x_audio_funcs =;

static const struct intel_audio_funcs ibx_audio_funcs =;

static const struct intel_audio_funcs hsw_audio_funcs =;

/**
 * intel_audio_hooks_init - Set up chip specific audio hooks
 * @i915: device private
 */
void intel_audio_hooks_init(struct drm_i915_private *i915)
{}

struct aud_ts_cdclk_m_n {};

void intel_audio_cdclk_change_pre(struct drm_i915_private *i915)
{}

static void get_aud_ts_cdclk_m_n(int refclk, int cdclk, struct aud_ts_cdclk_m_n *aud_ts)
{}

void intel_audio_cdclk_change_post(struct drm_i915_private *i915)
{}

static int glk_force_audio_cdclk_commit(struct intel_atomic_state *state,
					struct intel_crtc *crtc,
					bool enable)
{}

static void glk_force_audio_cdclk(struct drm_i915_private *i915,
				  bool enable)
{}

static unsigned long i915_audio_component_get_power(struct device *kdev)
{}

static void i915_audio_component_put_power(struct device *kdev,
					   unsigned long cookie)
{}

static void i915_audio_component_codec_wake_override(struct device *kdev,
						     bool enable)
{}

/* Get CDCLK in kHz  */
static int i915_audio_component_get_cdclk_freq(struct device *kdev)
{}

/*
 * get the intel audio state according to the parameter port and cpu_transcoder
 * MST & (cpu_transcoder >= 0): return the audio.state[cpu_transcoder].encoder],
 *   when port is matched
 * MST & (cpu_transcoder < 0): this is invalid
 * Non-MST & (cpu_transcoder >= 0): only cpu_transcoder = 0 (the first device entry)
 *   will get the right intel_encoder with port matched
 * Non-MST & (cpu_transcoder < 0): get the right intel_encoder with port matched
 */
static struct intel_audio_state *find_audio_state(struct drm_i915_private *i915,
						  int port, int cpu_transcoder)
{}

static int i915_audio_component_sync_audio_rate(struct device *kdev, int port,
						int cpu_transcoder, int rate)
{}

static int i915_audio_component_get_eld(struct device *kdev, int port,
					int cpu_transcoder, bool *enabled,
					unsigned char *buf, int max_bytes)
{}

static const struct drm_audio_component_ops i915_audio_component_ops =;

static int i915_audio_component_bind(struct device *drv_kdev,
				     struct device *hda_kdev, void *data)
{}

static void i915_audio_component_unbind(struct device *drv_kdev,
					struct device *hda_kdev, void *data)
{}

static const struct component_ops i915_audio_component_bind_ops =;

#define AUD_FREQ_TMODE_SHIFT
#define AUD_FREQ_4T
#define AUD_FREQ_8T
#define AUD_FREQ_PULLCLKS(x)
#define AUD_FREQ_BCLK_96M

#define AUD_FREQ_GEN12
#define AUD_FREQ_TGL_BROKEN

/**
 * i915_audio_component_init - initialize and register the audio component
 * @i915: i915 device instance
 *
 * This will register with the component framework a child component which
 * will bind dynamically to the snd_hda_intel driver's corresponding master
 * component when the latter is registered. During binding the child
 * initializes an instance of struct i915_audio_component which it receives
 * from the master. The master can then start to use the interface defined by
 * this struct. Each side can break the binding at any point by deregistering
 * its own component after which each side's component unbind callback is
 * called.
 *
 * We ignore any error during registration and continue with reduced
 * functionality (i.e. without HDMI audio).
 */
static void i915_audio_component_init(struct drm_i915_private *i915)
{}

static void i915_audio_component_register(struct drm_i915_private *i915)
{}

/**
 * i915_audio_component_cleanup - deregister the audio component
 * @i915: i915 device instance
 *
 * Deregisters the audio component, breaking any existing binding to the
 * corresponding snd_hda_intel driver's master component.
 */
static void i915_audio_component_cleanup(struct drm_i915_private *i915)
{}

/**
 * intel_audio_init() - Initialize the audio driver either using
 * component framework or using lpe audio bridge
 * @i915: the i915 drm device private data
 *
 */
void intel_audio_init(struct drm_i915_private *i915)
{}

void intel_audio_register(struct drm_i915_private *i915)
{}

/**
 * intel_audio_deinit() - deinitialize the audio driver
 * @i915: the i915 drm device private data
 *
 */
void intel_audio_deinit(struct drm_i915_private *i915)
{}