Loading drivers/gpu/drm/i915/intel_pm.c +21 −0 Original line number Diff line number Diff line Loading @@ -6053,6 +6053,27 @@ int i915_release_power_well(void) } EXPORT_SYMBOL_GPL(i915_release_power_well); /* * Private interface for the audio driver to get CDCLK in kHz. * * Caller must request power well using i915_request_power_well() prior to * making the call. */ int i915_get_cdclk_freq(void) { struct drm_i915_private *dev_priv; if (!hsw_pwr) return -ENODEV; dev_priv = container_of(hsw_pwr, struct drm_i915_private, power_domains); return intel_ddi_get_cdclk_freq(dev_priv); } EXPORT_SYMBOL_GPL(i915_get_cdclk_freq); #define POWER_DOMAIN_MASK (BIT(POWER_DOMAIN_NUM) - 1) #define HSW_ALWAYS_ON_POWER_DOMAINS ( \ Loading include/drm/i915_powerwell.h +1 −0 Original line number Diff line number Diff line Loading @@ -32,5 +32,6 @@ /* For use by hda_i915 driver */ extern int i915_request_power_well(void); extern int i915_release_power_well(void); extern int i915_get_cdclk_freq(void); #endif /* _I915_POWERWELL_H_ */ sound/pci/hda/hda_i915.c +55 −0 Original line number Diff line number Diff line Loading @@ -20,10 +20,20 @@ #include <linux/module.h> #include <sound/core.h> #include <drm/i915_powerwell.h> #include "hda_priv.h" #include "hda_i915.h" /* Intel HSW/BDW display HDA controller 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. */ #define AZX_REG_EM4 0x100c #define AZX_REG_EM5 0x1010 static int (*get_power)(void); static int (*put_power)(void); static int (*get_cdclk)(void); int hda_display_power(bool enable) { Loading @@ -38,6 +48,43 @@ int hda_display_power(bool enable) return put_power(); } void haswell_set_bclk(struct azx *chip) { int cdclk_freq; unsigned int bclk_m, bclk_n; if (!get_cdclk) return; cdclk_freq = get_cdclk(); 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; } azx_writew(chip, EM4, bclk_m); azx_writew(chip, EM5, bclk_n); } int hda_i915_init(void) { int err = 0; Loading @@ -55,6 +102,10 @@ int hda_i915_init(void) return -ENODEV; } get_cdclk = symbol_request(i915_get_cdclk_freq); if (!get_cdclk) /* may have abnormal BCLK and audio playback rate */ pr_warn("hda-i915: get_cdclk symbol get fail\n"); pr_debug("HDA driver get symbol successfully from i915 module\n"); return err; Loading @@ -70,6 +121,10 @@ int hda_i915_exit(void) symbol_put(i915_release_power_well); put_power = NULL; } if (get_cdclk) { symbol_put(i915_get_cdclk_freq); get_cdclk = NULL; } return 0; } sound/pci/hda/hda_i915.h +2 −0 Original line number Diff line number Diff line Loading @@ -18,10 +18,12 @@ #ifdef CONFIG_SND_HDA_I915 int hda_display_power(bool enable); void haswell_set_bclk(struct azx *chip); int hda_i915_init(void); int hda_i915_exit(void); #else static inline int hda_display_power(bool enable) { return 0; } static inline void haswell_set_bclk(struct azx *chip) { return; } static inline int hda_i915_init(void) { return -ENODEV; Loading sound/pci/hda/hda_intel.c +9 −41 Original line number Diff line number Diff line Loading @@ -61,9 +61,9 @@ #include <linux/vga_switcheroo.h> #include <linux/firmware.h> #include "hda_codec.h" #include "hda_i915.h" #include "hda_controller.h" #include "hda_priv.h" #include "hda_i915.h" /* position fix mode */ enum { Loading Loading @@ -333,22 +333,9 @@ static char *driver_short_names[] = { [AZX_DRIVER_GENERIC] = "HD-Audio Generic", }; /* Intel HSW/BDW display HDA controller 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. */ #define AZX_REG_EM4 0x100c #define AZX_REG_EM5 0x1010 struct hda_intel { struct azx chip; /* HSW/BDW display HDA controller to restore BCLK from CDCLK */ unsigned int bclk_m; unsigned int bclk_n; /* for pending irqs */ struct work_struct irq_pending_work; Loading Loading @@ -777,22 +764,6 @@ static int param_set_xint(const char *val, const struct kernel_param *kp) #define azx_del_card_list(chip) /* NOP */ #endif /* CONFIG_PM */ static void haswell_save_bclk(struct azx *chip) { struct hda_intel *hda = container_of(chip, struct hda_intel, chip); hda->bclk_m = azx_readw(chip, EM4); hda->bclk_n = azx_readw(chip, EM5); } static void haswell_restore_bclk(struct azx *chip) { struct hda_intel *hda = container_of(chip, struct hda_intel, chip); azx_writew(chip, EM4, hda->bclk_m); azx_writew(chip, EM5, hda->bclk_n); } #if defined(CONFIG_PM_SLEEP) || defined(SUPPORT_VGA_SWITCHEROO) /* * power management Loading Loading @@ -820,12 +791,6 @@ static int azx_suspend(struct device *dev) chip->irq = -1; } /* Save BCLK M/N values before they become invalid in D3. * Will test if display power well can be released now. */ if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) haswell_save_bclk(chip); if (chip->msi) pci_disable_msi(chip->pci); pci_disable_device(pci); Loading @@ -847,7 +812,7 @@ static int azx_resume(struct device *dev) if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { hda_display_power(true); haswell_restore_bclk(chip); haswell_set_bclk(chip); } pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); Loading Loading @@ -892,10 +857,9 @@ static int azx_runtime_suspend(struct device *dev) azx_stop_chip(chip); azx_enter_link_reset(chip); azx_clear_irq_pending(chip); if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { haswell_save_bclk(chip); if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) hda_display_power(false); } return 0; } Loading @@ -915,7 +879,7 @@ static int azx_runtime_resume(struct device *dev) if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { hda_display_power(true); haswell_restore_bclk(chip); haswell_set_bclk(chip); } /* Read STATESTS before controller reset */ Loading Loading @@ -1604,6 +1568,10 @@ static int azx_first_init(struct azx *chip) /* initialize chip */ azx_init_pci(chip); if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) haswell_set_bclk(chip); azx_init_chip(chip, (probe_only[dev] & 2) == 0); /* codec detection */ Loading Loading
drivers/gpu/drm/i915/intel_pm.c +21 −0 Original line number Diff line number Diff line Loading @@ -6053,6 +6053,27 @@ int i915_release_power_well(void) } EXPORT_SYMBOL_GPL(i915_release_power_well); /* * Private interface for the audio driver to get CDCLK in kHz. * * Caller must request power well using i915_request_power_well() prior to * making the call. */ int i915_get_cdclk_freq(void) { struct drm_i915_private *dev_priv; if (!hsw_pwr) return -ENODEV; dev_priv = container_of(hsw_pwr, struct drm_i915_private, power_domains); return intel_ddi_get_cdclk_freq(dev_priv); } EXPORT_SYMBOL_GPL(i915_get_cdclk_freq); #define POWER_DOMAIN_MASK (BIT(POWER_DOMAIN_NUM) - 1) #define HSW_ALWAYS_ON_POWER_DOMAINS ( \ Loading
include/drm/i915_powerwell.h +1 −0 Original line number Diff line number Diff line Loading @@ -32,5 +32,6 @@ /* For use by hda_i915 driver */ extern int i915_request_power_well(void); extern int i915_release_power_well(void); extern int i915_get_cdclk_freq(void); #endif /* _I915_POWERWELL_H_ */
sound/pci/hda/hda_i915.c +55 −0 Original line number Diff line number Diff line Loading @@ -20,10 +20,20 @@ #include <linux/module.h> #include <sound/core.h> #include <drm/i915_powerwell.h> #include "hda_priv.h" #include "hda_i915.h" /* Intel HSW/BDW display HDA controller 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. */ #define AZX_REG_EM4 0x100c #define AZX_REG_EM5 0x1010 static int (*get_power)(void); static int (*put_power)(void); static int (*get_cdclk)(void); int hda_display_power(bool enable) { Loading @@ -38,6 +48,43 @@ int hda_display_power(bool enable) return put_power(); } void haswell_set_bclk(struct azx *chip) { int cdclk_freq; unsigned int bclk_m, bclk_n; if (!get_cdclk) return; cdclk_freq = get_cdclk(); 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; } azx_writew(chip, EM4, bclk_m); azx_writew(chip, EM5, bclk_n); } int hda_i915_init(void) { int err = 0; Loading @@ -55,6 +102,10 @@ int hda_i915_init(void) return -ENODEV; } get_cdclk = symbol_request(i915_get_cdclk_freq); if (!get_cdclk) /* may have abnormal BCLK and audio playback rate */ pr_warn("hda-i915: get_cdclk symbol get fail\n"); pr_debug("HDA driver get symbol successfully from i915 module\n"); return err; Loading @@ -70,6 +121,10 @@ int hda_i915_exit(void) symbol_put(i915_release_power_well); put_power = NULL; } if (get_cdclk) { symbol_put(i915_get_cdclk_freq); get_cdclk = NULL; } return 0; }
sound/pci/hda/hda_i915.h +2 −0 Original line number Diff line number Diff line Loading @@ -18,10 +18,12 @@ #ifdef CONFIG_SND_HDA_I915 int hda_display_power(bool enable); void haswell_set_bclk(struct azx *chip); int hda_i915_init(void); int hda_i915_exit(void); #else static inline int hda_display_power(bool enable) { return 0; } static inline void haswell_set_bclk(struct azx *chip) { return; } static inline int hda_i915_init(void) { return -ENODEV; Loading
sound/pci/hda/hda_intel.c +9 −41 Original line number Diff line number Diff line Loading @@ -61,9 +61,9 @@ #include <linux/vga_switcheroo.h> #include <linux/firmware.h> #include "hda_codec.h" #include "hda_i915.h" #include "hda_controller.h" #include "hda_priv.h" #include "hda_i915.h" /* position fix mode */ enum { Loading Loading @@ -333,22 +333,9 @@ static char *driver_short_names[] = { [AZX_DRIVER_GENERIC] = "HD-Audio Generic", }; /* Intel HSW/BDW display HDA controller 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. */ #define AZX_REG_EM4 0x100c #define AZX_REG_EM5 0x1010 struct hda_intel { struct azx chip; /* HSW/BDW display HDA controller to restore BCLK from CDCLK */ unsigned int bclk_m; unsigned int bclk_n; /* for pending irqs */ struct work_struct irq_pending_work; Loading Loading @@ -777,22 +764,6 @@ static int param_set_xint(const char *val, const struct kernel_param *kp) #define azx_del_card_list(chip) /* NOP */ #endif /* CONFIG_PM */ static void haswell_save_bclk(struct azx *chip) { struct hda_intel *hda = container_of(chip, struct hda_intel, chip); hda->bclk_m = azx_readw(chip, EM4); hda->bclk_n = azx_readw(chip, EM5); } static void haswell_restore_bclk(struct azx *chip) { struct hda_intel *hda = container_of(chip, struct hda_intel, chip); azx_writew(chip, EM4, hda->bclk_m); azx_writew(chip, EM5, hda->bclk_n); } #if defined(CONFIG_PM_SLEEP) || defined(SUPPORT_VGA_SWITCHEROO) /* * power management Loading Loading @@ -820,12 +791,6 @@ static int azx_suspend(struct device *dev) chip->irq = -1; } /* Save BCLK M/N values before they become invalid in D3. * Will test if display power well can be released now. */ if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) haswell_save_bclk(chip); if (chip->msi) pci_disable_msi(chip->pci); pci_disable_device(pci); Loading @@ -847,7 +812,7 @@ static int azx_resume(struct device *dev) if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { hda_display_power(true); haswell_restore_bclk(chip); haswell_set_bclk(chip); } pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); Loading Loading @@ -892,10 +857,9 @@ static int azx_runtime_suspend(struct device *dev) azx_stop_chip(chip); azx_enter_link_reset(chip); azx_clear_irq_pending(chip); if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { haswell_save_bclk(chip); if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) hda_display_power(false); } return 0; } Loading @@ -915,7 +879,7 @@ static int azx_runtime_resume(struct device *dev) if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { hda_display_power(true); haswell_restore_bclk(chip); haswell_set_bclk(chip); } /* Read STATESTS before controller reset */ Loading Loading @@ -1604,6 +1568,10 @@ static int azx_first_init(struct azx *chip) /* initialize chip */ azx_init_pci(chip); if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) haswell_set_bclk(chip); azx_init_chip(chip, (probe_only[dev] & 2) == 0); /* codec detection */ Loading