1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
3 // This file is provided under a dual BSD/GPLv2 license. When using or
4 // redistributing this file, you may do so under either license.
6 // Copyright(c) 2018 Intel Corporation. All rights reserved.
8 // Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
11 #include <linux/pci.h>
15 bool snd_sof_pci_update_bits_unlocked(struct snd_sof_dev
*sdev
, u32 offset
,
18 struct pci_dev
*pci
= to_pci_dev(sdev
->dev
);
19 unsigned int old
, new;
22 pci_read_config_dword(pci
, offset
, &ret
);
24 dev_dbg(sdev
->dev
, "Debug PCIR: %8.8x at %8.8x\n", old
& mask
, offset
);
26 new = (old
& ~mask
) | (value
& mask
);
31 pci_write_config_dword(pci
, offset
, new);
32 dev_dbg(sdev
->dev
, "Debug PCIW: %8.8x at %8.8x\n", value
,
38 bool snd_sof_pci_update_bits(struct snd_sof_dev
*sdev
, u32 offset
,
44 spin_lock_irqsave(&sdev
->hw_lock
, flags
);
45 change
= snd_sof_pci_update_bits_unlocked(sdev
, offset
, mask
, value
);
46 spin_unlock_irqrestore(&sdev
->hw_lock
, flags
);
49 EXPORT_SYMBOL(snd_sof_pci_update_bits
);
51 bool snd_sof_dsp_update_bits_unlocked(struct snd_sof_dev
*sdev
, u32 bar
,
52 u32 offset
, u32 mask
, u32 value
)
54 unsigned int old
, new;
57 ret
= snd_sof_dsp_read(sdev
, bar
, offset
);
60 new = (old
& ~mask
) | (value
& mask
);
65 snd_sof_dsp_write(sdev
, bar
, offset
, new);
69 EXPORT_SYMBOL(snd_sof_dsp_update_bits_unlocked
);
71 bool snd_sof_dsp_update_bits64_unlocked(struct snd_sof_dev
*sdev
, u32 bar
,
72 u32 offset
, u64 mask
, u64 value
)
76 old
= snd_sof_dsp_read64(sdev
, bar
, offset
);
78 new = (old
& ~mask
) | (value
& mask
);
83 snd_sof_dsp_write64(sdev
, bar
, offset
, new);
87 EXPORT_SYMBOL(snd_sof_dsp_update_bits64_unlocked
);
89 /* This is for registers bits with attribute RWC */
90 bool snd_sof_dsp_update_bits(struct snd_sof_dev
*sdev
, u32 bar
, u32 offset
,
96 spin_lock_irqsave(&sdev
->hw_lock
, flags
);
97 change
= snd_sof_dsp_update_bits_unlocked(sdev
, bar
, offset
, mask
,
99 spin_unlock_irqrestore(&sdev
->hw_lock
, flags
);
102 EXPORT_SYMBOL(snd_sof_dsp_update_bits
);
104 bool snd_sof_dsp_update_bits64(struct snd_sof_dev
*sdev
, u32 bar
, u32 offset
,
110 spin_lock_irqsave(&sdev
->hw_lock
, flags
);
111 change
= snd_sof_dsp_update_bits64_unlocked(sdev
, bar
, offset
, mask
,
113 spin_unlock_irqrestore(&sdev
->hw_lock
, flags
);
116 EXPORT_SYMBOL(snd_sof_dsp_update_bits64
);
119 void snd_sof_dsp_update_bits_forced_unlocked(struct snd_sof_dev
*sdev
, u32 bar
,
120 u32 offset
, u32 mask
, u32 value
)
122 unsigned int old
, new;
125 ret
= snd_sof_dsp_read(sdev
, bar
, offset
);
128 new = (old
& ~mask
) | (value
& mask
);
130 snd_sof_dsp_write(sdev
, bar
, offset
, new);
133 /* This is for registers bits with attribute RWC */
134 void snd_sof_dsp_update_bits_forced(struct snd_sof_dev
*sdev
, u32 bar
,
135 u32 offset
, u32 mask
, u32 value
)
139 spin_lock_irqsave(&sdev
->hw_lock
, flags
);
140 snd_sof_dsp_update_bits_forced_unlocked(sdev
, bar
, offset
, mask
, value
);
141 spin_unlock_irqrestore(&sdev
->hw_lock
, flags
);
143 EXPORT_SYMBOL(snd_sof_dsp_update_bits_forced
);
145 void snd_sof_dsp_panic(struct snd_sof_dev
*sdev
, u32 offset
)
147 dev_err(sdev
->dev
, "error : DSP panic!\n");
150 * check if DSP is not ready and did not set the dsp_oops_offset.
151 * if the dsp_oops_offset is not set, set it from the panic message.
152 * Also add a check to memory window setting with panic message.
154 if (!sdev
->dsp_oops_offset
)
155 sdev
->dsp_oops_offset
= offset
;
157 dev_dbg(sdev
->dev
, "panic: dsp_oops_offset %zu offset %d\n",
158 sdev
->dsp_oops_offset
, offset
);
160 snd_sof_dsp_dbg_dump(sdev
, SOF_DBG_REGS
| SOF_DBG_MBOX
);
161 snd_sof_trace_notify_for_error(sdev
);
163 EXPORT_SYMBOL(snd_sof_dsp_panic
);