Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a33d5959 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

Merge branch 'for-linus' into for-next



For taking back the recent change of HDA HDMI fixes for i915 HSW/BDW.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parents 58a8738c bb03ed21
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@
#ifdef CONFIG_SND_HDA_I915
int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable);
int snd_hdac_display_power(struct hdac_bus *bus, bool enable);
int snd_hdac_get_display_clk(struct hdac_bus *bus);
void snd_hdac_i915_set_bclk(struct hdac_bus *bus);
int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate);
int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
			   bool *audio_enabled, char *buffer, int max_bytes);
@@ -25,9 +25,8 @@ static inline int snd_hdac_display_power(struct hdac_bus *bus, bool enable)
{
	return 0;
}
static inline int snd_hdac_get_display_clk(struct hdac_bus *bus)
static inline void snd_hdac_i915_set_bclk(struct hdac_bus *bus)
{
	return 0;
}
static inline int snd_hdac_sync_audio_rate(struct hdac_device *codec,
					   hda_nid_t nid, int rate)
+2 −0
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@ int snd_hdac_regmap_add_vendor_verb(struct hdac_device *codec,
				    unsigned int verb);
int snd_hdac_regmap_read_raw(struct hdac_device *codec, unsigned int reg,
			     unsigned int *val);
int snd_hdac_regmap_read_raw_uncached(struct hdac_device *codec,
				      unsigned int reg, unsigned int *val);
int snd_hdac_regmap_write_raw(struct hdac_device *codec, unsigned int reg,
			      unsigned int val);
int snd_hdac_regmap_update_raw(struct hdac_device *codec, unsigned int reg,
+4 −6
Original line number Diff line number Diff line
@@ -299,13 +299,11 @@ EXPORT_SYMBOL_GPL(_snd_hdac_read_parm);
int snd_hdac_read_parm_uncached(struct hdac_device *codec, hda_nid_t nid,
				int parm)
{
	int val;
	unsigned int cmd, val;

	if (codec->regmap)
		regcache_cache_bypass(codec->regmap, true);
	val = snd_hdac_read_parm(codec, nid, parm);
	if (codec->regmap)
		regcache_cache_bypass(codec->regmap, false);
	cmd = snd_hdac_regmap_encode_verb(nid, AC_VERB_PARAMETERS) | parm;
	if (snd_hdac_regmap_read_raw_uncached(codec, cmd, &val) < 0)
		return -1;
	return val;
}
EXPORT_SYMBOL_GPL(snd_hdac_read_parm_uncached);
+50 −10
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <sound/core.h>
#include <sound/hdaudio.h>
#include <sound/hda_i915.h>
#include <sound/hda_register.h>

static struct i915_audio_component *hdac_acomp;

@@ -97,26 +98,65 @@ int snd_hdac_display_power(struct hdac_bus *bus, bool enable)
}
EXPORT_SYMBOL_GPL(snd_hdac_display_power);

#define CONTROLLER_IN_GPU(pci) (((pci)->device == 0x0a0c) || \
				((pci)->device == 0x0c0c) || \
				((pci)->device == 0x0d0c) || \
				((pci)->device == 0x160c))

/**
 * snd_hdac_get_display_clk - Get CDCLK in kHz
 * snd_hdac_i915_set_bclk - Reprogram BCLK for HSW/BDW
 * @bus: HDA core bus
 *
 * This function is supposed to be used only by a HD-audio controller
 * driver that needs the interaction with i915 graphics.
 * Intel HSW/BDW display HDA controller is in GPU. Both its power and link BCLK
 * depends on GPU. Two Extended Mode registers EM4 (M value) and EM5 (N Value)
 * are used to convert CDClk (Core Display Clock) to 24MHz BCLK:
 * BCLK = CDCLK * M / N
 * The values will be lost when the display power well is disabled and need to
 * be restored to avoid abnormal playback speed.
 *
 * This function queries CDCLK value in kHz from the graphics driver and
 * returns the value.  A negative code is returned in error.
 * Call this function at initializing and changing power well, as well as
 * at ELD notifier for the hotplug.
 */
int snd_hdac_get_display_clk(struct hdac_bus *bus)
void snd_hdac_i915_set_bclk(struct hdac_bus *bus)
{
	struct i915_audio_component *acomp = bus->audio_component;
	struct pci_dev *pci = to_pci_dev(bus->dev);
	int cdclk_freq;
	unsigned int bclk_m, bclk_n;

	if (!acomp || !acomp->ops || !acomp->ops->get_cdclk_freq)
		return; /* only for i915 binding */
	if (!CONTROLLER_IN_GPU(pci))
		return; /* only HSW/BDW */

	cdclk_freq = acomp->ops->get_cdclk_freq(acomp->dev);
	switch (cdclk_freq) {
	case 337500:
		bclk_m = 16;
		bclk_n = 225;
		break;

	if (!acomp || !acomp->ops)
		return -ENODEV;
	case 450000:
	default: /* default CDCLK 450MHz */
		bclk_m = 4;
		bclk_n = 75;
		break;

	case 540000:
		bclk_m = 4;
		bclk_n = 90;
		break;

	case 675000:
		bclk_m = 8;
		bclk_n = 225;
		break;
	}

	return acomp->ops->get_cdclk_freq(acomp->dev);
	snd_hdac_chip_writew(bus, HSW_EM4, bclk_m);
	snd_hdac_chip_writew(bus, HSW_EM5, bclk_n);
}
EXPORT_SYMBOL_GPL(snd_hdac_get_display_clk);
EXPORT_SYMBOL_GPL(snd_hdac_i915_set_bclk);

/* There is a fixed mapping between audio pin node and display port.
 * on SNB, IVY, HSW, BSW, SKL, BXT, KBL:
+28 −12
Original line number Diff line number Diff line
@@ -453,14 +453,30 @@ int snd_hdac_regmap_write_raw(struct hdac_device *codec, unsigned int reg,
EXPORT_SYMBOL_GPL(snd_hdac_regmap_write_raw);

static int reg_raw_read(struct hdac_device *codec, unsigned int reg,
			unsigned int *val)
			unsigned int *val, bool uncached)
{
	if (!codec->regmap)
	if (uncached || !codec->regmap)
		return hda_reg_read(codec, reg, val);
	else
		return regmap_read(codec->regmap, reg, val);
}

static int __snd_hdac_regmap_read_raw(struct hdac_device *codec,
				      unsigned int reg, unsigned int *val,
				      bool uncached)
{
	int err;

	err = reg_raw_read(codec, reg, val, uncached);
	if (err == -EAGAIN) {
		err = snd_hdac_power_up_pm(codec);
		if (!err)
			err = reg_raw_read(codec, reg, val, uncached);
		snd_hdac_power_down_pm(codec);
	}
	return err;
}

/**
 * snd_hdac_regmap_read_raw - read a pseudo register with power mgmt
 * @codec: the codec object
@@ -472,19 +488,19 @@ static int reg_raw_read(struct hdac_device *codec, unsigned int reg,
int snd_hdac_regmap_read_raw(struct hdac_device *codec, unsigned int reg,
			     unsigned int *val)
{
	int err;

	err = reg_raw_read(codec, reg, val);
	if (err == -EAGAIN) {
		err = snd_hdac_power_up_pm(codec);
		if (!err)
			err = reg_raw_read(codec, reg, val);
		snd_hdac_power_down_pm(codec);
	}
	return err;
	return __snd_hdac_regmap_read_raw(codec, reg, val, false);
}
EXPORT_SYMBOL_GPL(snd_hdac_regmap_read_raw);

/* Works like snd_hdac_regmap_read_raw(), but this doesn't read from the
 * cache but always via hda verbs.
 */
int snd_hdac_regmap_read_raw_uncached(struct hdac_device *codec,
				      unsigned int reg, unsigned int *val)
{
	return __snd_hdac_regmap_read_raw(codec, reg, val, true);
}

/**
 * snd_hdac_regmap_update_raw - update a pseudo register with power mgmt
 * @codec: the codec object
Loading