[Intel-gfx] [RFC 04/15] drm/i915: Add headers for non-HDAudio HDMI interface

Ville Syrjälä ville.syrjala at linux.intel.com
Thu Mar 10 17:54:02 UTC 2016


On Fri, Mar 04, 2016 at 08:50:41PM -0600, Pierre-Louis Bossart wrote:
> Add header files for interface available on Baytrail and CherryTrail
> 
> Initial code was downloaded from https://github.com/01org/baytrailaudio/
> ...and had the changes to .config stripped and the revert on sound/init.c
> done by David Henningson
> 
> Clean-up, port to 4.4 and intel-drm by Pierre Bossart
> 
> Signed-off-by: David Henningsson <david.henningsson at canonical.com>
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
> ---
>  drivers/gpu/drm/i915/hdmi_audio_if.h | 122 +++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/i915_drv.h      |  31 +++++++++
>  drivers/gpu/drm/i915/i915_reg.h      |   7 ++
>  drivers/gpu/drm/i915/intel_drv.h     |  11 ++++
>  4 files changed, 171 insertions(+)
>  create mode 100644 drivers/gpu/drm/i915/hdmi_audio_if.h
> 
> diff --git a/drivers/gpu/drm/i915/hdmi_audio_if.h b/drivers/gpu/drm/i915/hdmi_audio_if.h
> new file mode 100644
> index 0000000..f968028
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/hdmi_audio_if.h
> @@ -0,0 +1,122 @@
> +/*
> + * Copyright (c) 2010, Intel Corporation.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * Authors:
> + *	jim liu <jim.liu at intel.com>
> + *	Uma Shankar <uma.shankar at intel.com>
> + */
> +
> +
> +#ifndef __HDMI_AUDIO_IF_H
> +#define __HDMI_AUDIO_IF_H
> +
> +#include <linux/types.h>
> +#include <drm/drmP.h>
> +
> +/* HDMI AUDIO INTERRUPT TYPE */
> +#define HDMI_AUDIO_UNDERRUN     (1UL<<0)
> +#define HDMI_AUDIO_BUFFER_DONE  (1UL<<1)
> +
> +/* the monitor type HDMI or DVI */
> +#define MONITOR_TYPE_HDMI 1
> +#define MONITOR_TYPE_DVI  2
> +
> +extern int i915_hdmi_state;
> +extern int i915_notify_had;
> +
> +enum had_caps_list {
> +	HAD_GET_ELD = 1,
> +	HAD_GET_SAMPLING_FREQ,
> +	HAD_GET_DISPLAY_RATE,
> +	HAD_GET_HDCP_STATUS,
> +	HAD_GET_AUDIO_STATUS,
> +	HAD_SET_ENABLE_AUDIO,
> +	HAD_SET_DISABLE_AUDIO,
> +	HAD_SET_ENABLE_AUDIO_INT,
> +	HAD_SET_DISABLE_AUDIO_INT,
> +	OTHERS_TBD,
> +};
> +
> +enum had_event_type {
> +	HAD_EVENT_HOT_PLUG = 1,
> +	HAD_EVENT_HOT_UNPLUG,
> +	HAD_EVENT_MODE_CHANGING,
> +	HAD_EVENT_PM_CHANGING,
> +	HAD_EVENT_AUDIO_BUFFER_DONE,
> +	HAD_EVENT_AUDIO_BUFFER_UNDERRUN,
> +	HAD_EVENT_QUERY_IS_AUDIO_BUSY,
> +	HAD_EVENT_QUERY_IS_AUDIO_SUSPENDED,
> +};
> +
> +/*
> + * HDMI Display Controller Audio Interface
> + *
> + */
> +typedef int (*had_event_call_back) (enum had_event_type event_type,
> +		void *ctxt_info);
> +
> +struct hdmi_audio_registers_ops {
> +	int (*hdmi_audio_read_register)(uint32_t reg_addr, uint32_t *data);
> +	int (*hdmi_audio_write_register)(uint32_t reg_addr, uint32_t data);
> +	int (*hdmi_audio_read_modify)(uint32_t reg_addr, uint32_t data,
> +			uint32_t mask);
> +};

Do all the register actually live within the device 2 mmio bar? If so
I think what we might want to do here is go for a proper subdevice
approach like we tried to do for the VED on BYT. VED sort of dried up
and no one cared (not sure the userspae part was even published), but
I think the approach was sane. See here:
https://lists.freedesktop.org/archives/intel-gfx/2015-January/058137.html

> +
> +struct hdmi_audio_query_set_ops {
> +	int (*hdmi_audio_get_caps)(enum had_caps_list query_element,
> +			void *capabilties);
> +	int (*hdmi_audio_set_caps)(enum had_caps_list set_element,
> +			void *capabilties);
> +};
> +
> +typedef struct hdmi_audio_event {
> +	int type;
> +} hdmi_audio_event_t;
> +
> +struct snd_intel_had_interface {
> +	const char *name;
> +	int (*query)(void *had_data, hdmi_audio_event_t event);
> +	int (*suspend)(void *had_data, hdmi_audio_event_t event);
> +	int (*resume)(void *had_data);
> +};
> +
> +struct hdmi_audio_priv {
> +	struct drm_device *dev;
> +	u32 hdmib_reg;
> +
> +	bool is_hdcp_supported;
> +	bool hdmi_hpd_connected;
> +	int monitor_type;
> +	void *context;
> +};
> +
> +extern void i915_hdmi_audio_init(struct hdmi_audio_priv *p_hdmi_priv);
> +
> +extern bool mid_hdmi_audio_is_busy(struct drm_device *dev);
> +extern bool mid_hdmi_audio_suspend(struct drm_device *dev);
> +extern void mid_hdmi_audio_resume(struct drm_device *dev);
> +extern void mid_hdmi_audio_signal_event(struct drm_device *dev,
> +		enum had_event_type event);
> +
> +/* Added for HDMI Audio */
> +extern void hdmi_get_eld(uint8_t *eld);
> +extern int i915_enable_hdmi_audio_int(struct drm_device *dev);
> +extern int i915_disable_hdmi_audio_int(struct drm_device *dev);
> +extern int mid_hdmi_audio_setup(
> +	had_event_call_back audio_callbacks,
> +	struct hdmi_audio_registers_ops *reg_ops,
> +	struct hdmi_audio_query_set_ops *query_ops);
> +extern int mid_hdmi_audio_register(
> +	struct snd_intel_had_interface *driver,
> +	void *had_data);
> +
> +#endif /* __HDMI_AUDIO_IF_H */
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 2cb0a41..5dceb5b 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -53,6 +53,7 @@
>  #include <linux/kref.h>
>  #include <linux/pm_qos.h>
>  #include "intel_guc.h"
> +#include "hdmi_audio_if.h"
>  
>  /* General customization:
>   */
> @@ -1196,6 +1197,18 @@ struct intel_gen6_power_mgmt {
>  	struct mutex hw_lock;
>  };
>  
> +/* Runtime power management related */
> +struct intel_gen7_rpm {
> +	/* To track (num of get calls - num of put calls)
> +	 * made by procfs
> +	 */
> +	atomic_t procfs_count;
> +	/* To make sure ring get/put are in pair */
> +	bool ring_active;
> +	struct proc_dir_entry *i915_proc_dir;
> +	struct proc_dir_entry *i915_proc_file;
> +};
> +
>  /* defined intel_pm.c */
>  extern spinlock_t mchdev_lock;
>  
> @@ -2018,6 +2031,19 @@ struct drm_i915_private {
>  
>  	struct intel_encoder *dig_port_map[I915_MAX_PORTS];
>  
> +	/* Added for HDMI Audio */
> +	had_event_call_back had_event_callbacks;
> +	struct snd_intel_had_interface *had_interface;
> +	void *had_pvt_data;
> +	int tmds_clock_speed;
> +	int hdmi_audio_interrupt_mask;
> +	struct work_struct hdmi_audio_wq;
> +
> +	u32 hotplug_status;
> +
> +	/* Runtime power management related */
> +	struct intel_gen7_rpm rpm;
> +
>  	/*
>  	 * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
>  	 * will be rejected. Instead look for a better place.
> @@ -3537,6 +3563,11 @@ int intel_freq_opcode(struct drm_i915_private *dev_priv, int val);
>  	} while (upper != old_upper && loop++ < 2);			\
>  	(u64)upper << 32 | lower; })
>  
> +int i915_rpm_get_disp(struct drm_device *dev);
> +int i915_rpm_put_disp(struct drm_device *dev);
> +
> +bool i915_is_device_active(struct drm_device *dev);
> +
>  #define POSTING_READ(reg)	(void)I915_READ_NOTRACE(reg)
>  #define POSTING_READ16(reg)	(void)I915_READ16_NOTRACE(reg)
>  
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 228b22f..370371c 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -2062,7 +2062,12 @@ enum skl_disp_power_wells {
>  #define I915_WINVALID_INTERRUPT				(1<<1)
>  #define I915_USER_INTERRUPT				(1<<1)
>  #define I915_ASLE_INTERRUPT				(1<<0)
> +#define I915_LPE_AUDIO_HDMI_STATUS_A	_MMIO(dev_priv->info.display_mmio_offset + 0x65064)
> +#define I915_LPE_AUDIO_HDMI_STATUS_B	_MMIO(dev_priv->info.display_mmio_offset + 0x65864)
> +#define I915_HDMI_AUDIO_UNDERRUN			(1UL<<31)
> +#define I915_HDMI_AUDIO_BUFFER_DONE			(1UL<<29)
>  #define I915_BSD_USER_INTERRUPT				(1<<25)
> +#define I915_HDMI_AUDIO_UNDERRUN_ENABLE			(1UL<<15)
>  
>  #define GEN6_BSD_RNCID			_MMIO(0x12198)
>  
> @@ -3364,6 +3369,7 @@ enum skl_disp_power_wells {
>  #define _GEN3_SDVOC	0x61160
>  #define GEN3_SDVOB	_MMIO(_GEN3_SDVOB)
>  #define GEN3_SDVOC	_MMIO(_GEN3_SDVOC)
> +#define HDMIB	(dev_priv->info.display_mmio_offset + 0x61140)
>  #define GEN4_HDMIB	GEN3_SDVOB
>  #define GEN4_HDMIC	GEN3_SDVOC
>  #define VLV_HDMIB	_MMIO(VLV_DISPLAY_BASE + 0x61140)
> @@ -3373,6 +3379,7 @@ enum skl_disp_power_wells {
>  #define PCH_HDMIB	PCH_SDVOB
>  #define PCH_HDMIC	_MMIO(0xe1150)
>  #define PCH_HDMID	_MMIO(0xe1160)
> +#define PORT_ENABLE	(1 << 31)
>  
>  #define PORT_DFT_I9XX				_MMIO(0x61150)
>  #define   DC_BALANCE_RESET			(1 << 25)
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index cb413e2..adfd27c 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -724,6 +724,14 @@ struct cxsr_latency {
>  #define to_intel_plane_state(x) container_of(x, struct intel_plane_state, base)
>  #define intel_fb_obj(x) (x ? to_intel_framebuffer(x)->obj : NULL)
>  
> +/* HDMI bits are shared with the DP bits */
> +#define   HDMIB_HOTPLUG_LIVE_STATUS             (1 << 29)
> +#define   HDMIC_HOTPLUG_LIVE_STATUS             (1 << 28)
> +#define   HDMID_HOTPLUG_LIVE_STATUS             (1 << 27)
> +#define   HDMI_LIVE_STATUS_BASE			30
> +#define   HDMI_LIVE_STATUS_DELAY_STEP		10
> +#define   HDMI_EDID_RETRY_COUNT			3
> +
>  struct intel_hdmi {
>  	i915_reg_t hdmi_reg;
>  	int ddc_bus;
> @@ -735,6 +743,9 @@ struct intel_hdmi {
>  	bool rgb_quant_range_selectable;
>  	enum hdmi_picture_aspect aspect_ratio;
>  	struct intel_connector *attached_connector;
> +	struct edid *edid;
> +	uint32_t edid_mode_count;
> +
>  	void (*write_infoframe)(struct drm_encoder *encoder,
>  				enum hdmi_infoframe_type type,
>  				const void *frame, ssize_t len);
> -- 
> 1.9.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC


More information about the Intel-gfx mailing list