aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.h5
-rw-r--r--sound/soc/intel/skylake/skl.c55
-rw-r--r--sound/soc/intel/skylake/skl.h3
3 files changed, 60 insertions, 3 deletions
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.h b/sound/soc/intel/skylake/skl-sst-ipc.h
index 1bbcdb471cf2..d59d1ba62a43 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.h
+++ b/sound/soc/intel/skylake/skl-sst-ipc.h
@@ -55,6 +55,11 @@ struct skl_sst {
55 55
56 /* IPC messaging */ 56 /* IPC messaging */
57 struct sst_generic_ipc ipc; 57 struct sst_generic_ipc ipc;
58
59 /* callback for miscbdge */
60 void (*enable_miscbdcge)(struct device *dev, bool enable);
61 /*Is CGCTL.MISCBDCGE disabled*/
62 bool miscbdcg_disabled;
58}; 63};
59 64
60struct skl_ipc_init_instance_msg { 65struct skl_ipc_init_instance_msg {
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c
index b69649aa7809..dd38f5feb7c0 100644
--- a/sound/soc/intel/skylake/skl.c
+++ b/sound/soc/intel/skylake/skl.c
@@ -29,6 +29,8 @@
29#include <sound/pcm.h> 29#include <sound/pcm.h>
30#include "../common/sst-acpi.h" 30#include "../common/sst-acpi.h"
31#include "skl.h" 31#include "skl.h"
32#include "skl-sst-dsp.h"
33#include "skl-sst-ipc.h"
32 34
33/* 35/*
34 * initialize the PCI registers 36 * initialize the PCI registers
@@ -59,6 +61,49 @@ static void skl_init_pci(struct skl *skl)
59 skl_update_pci_byte(skl->pci, AZX_PCIREG_TCSEL, 0x07, 0); 61 skl_update_pci_byte(skl->pci, AZX_PCIREG_TCSEL, 0x07, 0);
60} 62}
61 63
64static void update_pci_dword(struct pci_dev *pci,
65 unsigned int reg, u32 mask, u32 val)
66{
67 u32 data = 0;
68
69 pci_read_config_dword(pci, reg, &data);
70 data &= ~mask;
71 data |= (val & mask);
72 pci_write_config_dword(pci, reg, data);
73}
74
75/*
76 * skl_enable_miscbdcge - enable/dsiable CGCTL.MISCBDCGE bits
77 *
78 * @dev: device pointer
79 * @enable: enable/disable flag
80 */
81static void skl_enable_miscbdcge(struct device *dev, bool enable)
82{
83 struct pci_dev *pci = to_pci_dev(dev);
84 u32 val;
85
86 val = enable ? AZX_CGCTL_MISCBDCGE_MASK : 0;
87
88 update_pci_dword(pci, AZX_PCIREG_CGCTL, AZX_CGCTL_MISCBDCGE_MASK, val);
89}
90
91/*
92 * While performing reset, controller may not come back properly causing
93 * issues, so recommendation is to set CGCTL.MISCBDCGE to 0 then do reset
94 * (init chip) and then again set CGCTL.MISCBDCGE to 1
95 */
96static int skl_init_chip(struct hdac_bus *bus, bool full_reset)
97{
98 int ret;
99
100 skl_enable_miscbdcge(bus->dev, false);
101 ret = snd_hdac_bus_init_chip(bus, full_reset);
102 skl_enable_miscbdcge(bus->dev, true);
103
104 return ret;
105}
106
62/* called from IRQ */ 107/* called from IRQ */
63static void skl_stream_update(struct hdac_bus *bus, struct hdac_stream *hstr) 108static void skl_stream_update(struct hdac_bus *bus, struct hdac_stream *hstr)
64{ 109{
@@ -145,7 +190,9 @@ static int _skl_suspend(struct hdac_ext_bus *ebus)
145 return ret; 190 return ret;
146 191
147 snd_hdac_bus_stop_chip(bus); 192 snd_hdac_bus_stop_chip(bus);
193 skl_enable_miscbdcge(bus->dev, false);
148 snd_hdac_bus_enter_link_reset(bus); 194 snd_hdac_bus_enter_link_reset(bus);
195 skl_enable_miscbdcge(bus->dev, true);
149 196
150 return 0; 197 return 0;
151} 198}
@@ -156,7 +203,7 @@ static int _skl_resume(struct hdac_ext_bus *ebus)
156 struct hdac_bus *bus = ebus_to_hbus(ebus); 203 struct hdac_bus *bus = ebus_to_hbus(ebus);
157 204
158 skl_init_pci(skl); 205 skl_init_pci(skl);
159 snd_hdac_bus_init_chip(bus, true); 206 skl_init_chip(bus, true);
160 207
161 return skl_resume_dsp(skl); 208 return skl_resume_dsp(skl);
162} 209}
@@ -380,7 +427,7 @@ static int skl_codec_create(struct hdac_ext_bus *ebus)
380 * back to the sanity state. 427 * back to the sanity state.
381 */ 428 */
382 snd_hdac_bus_stop_chip(bus); 429 snd_hdac_bus_stop_chip(bus);
383 snd_hdac_bus_init_chip(bus, true); 430 skl_init_chip(bus, true);
384 } 431 }
385 } 432 }
386 } 433 }
@@ -490,7 +537,7 @@ static int skl_first_init(struct hdac_ext_bus *ebus)
490 /* initialize chip */ 537 /* initialize chip */
491 skl_init_pci(skl); 538 skl_init_pci(skl);
492 539
493 snd_hdac_bus_init_chip(bus, true); 540 skl_init_chip(bus, true);
494 541
495 /* codec detection */ 542 /* codec detection */
496 if (!bus->codec_mask) { 543 if (!bus->codec_mask) {
@@ -539,6 +586,8 @@ static int skl_probe(struct pci_dev *pci,
539 dev_dbg(bus->dev, "error failed to register dsp\n"); 586 dev_dbg(bus->dev, "error failed to register dsp\n");
540 goto out_mach_free; 587 goto out_mach_free;
541 } 588 }
589 skl->skl_sst->enable_miscbdcge = skl_enable_miscbdcge;
590
542 } 591 }
543 if (ebus->mlcap) 592 if (ebus->mlcap)
544 snd_hdac_ext_bus_get_ml_capabilities(ebus); 593 snd_hdac_ext_bus_get_ml_capabilities(ebus);
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h
index 36a1b8c5f6d0..8a08bb727991 100644
--- a/sound/soc/intel/skylake/skl.h
+++ b/sound/soc/intel/skylake/skl.h
@@ -48,6 +48,9 @@
48#define AZX_REG_VS_SDXEFIFOS_XBASE 0x1094 48#define AZX_REG_VS_SDXEFIFOS_XBASE 0x1094
49#define AZX_REG_VS_SDXEFIFOS_XINTERVAL 0x20 49#define AZX_REG_VS_SDXEFIFOS_XINTERVAL 0x20
50 50
51#define AZX_PCIREG_CGCTL 0x48
52#define AZX_CGCTL_MISCBDCGE_MASK (1 << 6)
53
51struct skl_dsp_resource { 54struct skl_dsp_resource {
52 u32 max_mcps; 55 u32 max_mcps;
53 u32 max_mem; 56 u32 max_mem;