aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJayachandran B <jayachandran.b@intel.com>2015-12-18 04:42:03 -0500
committerMark Brown <broonie@kernel.org>2016-01-10 07:19:01 -0500
commit0c8ba9d28518822d612de23fc9020b2a66a0228c (patch)
tree89295d33fcb50b73dba25302a9979fb013cf9cd0
parent648e3a5bdddf8e7ad9c27450ac368b8bccd807a5 (diff)
ASoC: Intel: Skylake: fix reset controller sequencing
MISCBDCGE is a new register for Misc Backbone clock gate control which is useful to control while resetting the link and ensuring controller is in required state so add API to control it HW recommends that we reset with CGCTL.MISCBDCGE disabled, so add that while doing init chip and reset sequence. Signed-off-by: Jayachandran B <jayachandran.b@intel.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-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;