From: Takashi Iwai Date: Tue, 26 Apr 2016 08:04:19 +0000 (+0200) Subject: Merge branch 'for-linus' into for-next X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=a33d59599653edc6469c582f0ffd99c5fc58af04;p=linux-beck.git 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 --- a33d59599653edc6469c582f0ffd99c5fc58af04 diff --cc include/sound/hda_i915.h index eed87a7559b7,f5842bcd9c94..796cabf6be5e --- a/include/sound/hda_i915.h +++ b/include/sound/hda_i915.h @@@ -9,9 -9,9 +9,9 @@@ #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_bus *bus, hda_nid_t nid, int rate); -int snd_hdac_acomp_get_eld(struct hdac_bus *bus, hda_nid_t nid, +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); int snd_hdac_i915_init(struct hdac_bus *bus); int snd_hdac_i915_exit(struct hdac_bus *bus); @@@ -25,12 -25,11 +25,11 @@@ static inline int snd_hdac_display_powe { 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_bus *bus, hda_nid_t nid, - int rate) +static inline int snd_hdac_sync_audio_rate(struct hdac_device *codec, + hda_nid_t nid, int rate) { return 0; } diff --cc sound/hda/hdac_i915.c index 6800e0c5a38f,607bbeaebddf..c9af022676c2 --- a/sound/hda/hdac_i915.c +++ b/sound/hda/hdac_i915.c @@@ -97,29 -98,68 +98,68 @@@ int snd_hdac_display_power(struct hdac_ } 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; + + 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; + } - if (!acomp || !acomp->ops) - return -ENODEV; - - 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 current Intel platforms: +/* There is a fixed mapping between audio pin node and display port. + * on SNB, IVY, HSW, BSW, SKL, BXT, KBL: * Pin Widget 5 - PORT B (port = 1 in i915 driver) * Pin Widget 6 - PORT C (port = 2 in i915 driver) * Pin Widget 7 - PORT D (port = 3 in i915 driver)