-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ASoC: SOF: Add DSP HW abstraction operations
Add operation pointers that can be called by core to control a wide variety of DSP targets. The DSP HW drivers will fill in these operations. Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Reviewed-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Mark Brown <broonie@kernel.org>
- Loading branch information
Liam Girdwood
authored and
Mark Brown
committed
Apr 27, 2019
1 parent
fd51c47
commit d1d95fc
Showing
2 changed files
with
562 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) | ||
// | ||
// This file is provided under a dual BSD/GPLv2 license. When using or | ||
// redistributing this file, you may do so under either license. | ||
// | ||
// Copyright(c) 2018 Intel Corporation. All rights reserved. | ||
// | ||
// Author: Liam Girdwood <liam.r.girdwood@linux.intel.com> | ||
// | ||
|
||
#include <linux/pci.h> | ||
#include "ops.h" | ||
|
||
static | ||
bool snd_sof_pci_update_bits_unlocked(struct snd_sof_dev *sdev, u32 offset, | ||
u32 mask, u32 value) | ||
{ | ||
struct pci_dev *pci = to_pci_dev(sdev->dev); | ||
unsigned int old, new; | ||
u32 ret; | ||
|
||
pci_read_config_dword(pci, offset, &ret); | ||
old = ret; | ||
dev_dbg(sdev->dev, "Debug PCIR: %8.8x at %8.8x\n", old & mask, offset); | ||
|
||
new = (old & ~mask) | (value & mask); | ||
|
||
if (old == new) | ||
return false; | ||
|
||
pci_write_config_dword(pci, offset, new); | ||
dev_dbg(sdev->dev, "Debug PCIW: %8.8x at %8.8x\n", value, | ||
offset); | ||
|
||
return true; | ||
} | ||
|
||
bool snd_sof_pci_update_bits(struct snd_sof_dev *sdev, u32 offset, | ||
u32 mask, u32 value) | ||
{ | ||
unsigned long flags; | ||
bool change; | ||
|
||
spin_lock_irqsave(&sdev->hw_lock, flags); | ||
change = snd_sof_pci_update_bits_unlocked(sdev, offset, mask, value); | ||
spin_unlock_irqrestore(&sdev->hw_lock, flags); | ||
return change; | ||
} | ||
EXPORT_SYMBOL(snd_sof_pci_update_bits); | ||
|
||
bool snd_sof_dsp_update_bits_unlocked(struct snd_sof_dev *sdev, u32 bar, | ||
u32 offset, u32 mask, u32 value) | ||
{ | ||
unsigned int old, new; | ||
u32 ret; | ||
|
||
ret = snd_sof_dsp_read(sdev, bar, offset); | ||
|
||
old = ret; | ||
new = (old & ~mask) | (value & mask); | ||
|
||
if (old == new) | ||
return false; | ||
|
||
snd_sof_dsp_write(sdev, bar, offset, new); | ||
|
||
return true; | ||
} | ||
EXPORT_SYMBOL(snd_sof_dsp_update_bits_unlocked); | ||
|
||
bool snd_sof_dsp_update_bits64_unlocked(struct snd_sof_dev *sdev, u32 bar, | ||
u32 offset, u64 mask, u64 value) | ||
{ | ||
u64 old, new; | ||
|
||
old = snd_sof_dsp_read64(sdev, bar, offset); | ||
|
||
new = (old & ~mask) | (value & mask); | ||
|
||
if (old == new) | ||
return false; | ||
|
||
snd_sof_dsp_write64(sdev, bar, offset, new); | ||
|
||
return true; | ||
} | ||
EXPORT_SYMBOL(snd_sof_dsp_update_bits64_unlocked); | ||
|
||
/* This is for registers bits with attribute RWC */ | ||
bool snd_sof_dsp_update_bits(struct snd_sof_dev *sdev, u32 bar, u32 offset, | ||
u32 mask, u32 value) | ||
{ | ||
unsigned long flags; | ||
bool change; | ||
|
||
spin_lock_irqsave(&sdev->hw_lock, flags); | ||
change = snd_sof_dsp_update_bits_unlocked(sdev, bar, offset, mask, | ||
value); | ||
spin_unlock_irqrestore(&sdev->hw_lock, flags); | ||
return change; | ||
} | ||
EXPORT_SYMBOL(snd_sof_dsp_update_bits); | ||
|
||
bool snd_sof_dsp_update_bits64(struct snd_sof_dev *sdev, u32 bar, u32 offset, | ||
u64 mask, u64 value) | ||
{ | ||
unsigned long flags; | ||
bool change; | ||
|
||
spin_lock_irqsave(&sdev->hw_lock, flags); | ||
change = snd_sof_dsp_update_bits64_unlocked(sdev, bar, offset, mask, | ||
value); | ||
spin_unlock_irqrestore(&sdev->hw_lock, flags); | ||
return change; | ||
} | ||
EXPORT_SYMBOL(snd_sof_dsp_update_bits64); | ||
|
||
static | ||
void snd_sof_dsp_update_bits_forced_unlocked(struct snd_sof_dev *sdev, u32 bar, | ||
u32 offset, u32 mask, u32 value) | ||
{ | ||
unsigned int old, new; | ||
u32 ret; | ||
|
||
ret = snd_sof_dsp_read(sdev, bar, offset); | ||
|
||
old = ret; | ||
new = (old & ~mask) | (value & mask); | ||
|
||
snd_sof_dsp_write(sdev, bar, offset, new); | ||
} | ||
|
||
/* This is for registers bits with attribute RWC */ | ||
void snd_sof_dsp_update_bits_forced(struct snd_sof_dev *sdev, u32 bar, | ||
u32 offset, u32 mask, u32 value) | ||
{ | ||
unsigned long flags; | ||
|
||
spin_lock_irqsave(&sdev->hw_lock, flags); | ||
snd_sof_dsp_update_bits_forced_unlocked(sdev, bar, offset, mask, value); | ||
spin_unlock_irqrestore(&sdev->hw_lock, flags); | ||
} | ||
EXPORT_SYMBOL(snd_sof_dsp_update_bits_forced); | ||
|
||
void snd_sof_dsp_panic(struct snd_sof_dev *sdev, u32 offset) | ||
{ | ||
dev_err(sdev->dev, "error : DSP panic!\n"); | ||
|
||
/* | ||
* check if DSP is not ready and did not set the dsp_oops_offset. | ||
* if the dsp_oops_offset is not set, set it from the panic message. | ||
* Also add a check to memory window setting with panic message. | ||
*/ | ||
if (!sdev->dsp_oops_offset) | ||
sdev->dsp_oops_offset = offset; | ||
else | ||
dev_dbg(sdev->dev, "panic: dsp_oops_offset %zu offset %d\n", | ||
sdev->dsp_oops_offset, offset); | ||
|
||
snd_sof_dsp_dbg_dump(sdev, SOF_DBG_REGS | SOF_DBG_MBOX); | ||
snd_sof_trace_notify_for_error(sdev); | ||
} | ||
EXPORT_SYMBOL(snd_sof_dsp_panic); |
Oops, something went wrong.