1
0

Merge branch 'for-linus' into for-next

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

Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Iwai
2016-04-26 10:04:19 +02:00
14 changed files with 146 additions and 92 deletions

View File

@@ -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);

View File

@@ -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)
return -ENODEV;
if (!acomp || !acomp->ops || !acomp->ops->get_cdclk_freq)
return; /* only for i915 binding */
if (!CONTROLLER_IN_GPU(pci))
return; /* only HSW/BDW */
return acomp->ops->get_cdclk_freq(acomp->dev);
cdclk_freq = acomp->ops->get_cdclk_freq(acomp->dev);
switch (cdclk_freq) {
case 337500:
bclk_m = 16;
bclk_n = 225;
break;
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;
}
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:

View File

@@ -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