Commit 1b6a349a authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'soundwire-6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire

Pull soundwire updates from Vinod Koul:
 "This include bunch of Intel driver code reorganization and support for
  qcom v1.7.0 controller:

   - intel: reorganization of hw_ops callbacks, splitting files etc

   - qcom: support for v1.7.0 qcom controllers"

* tag 'soundwire-6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire:
  soundwire: intel: split auxdevice to different file
  soundwire: intel: add in-band wake callbacks in hw_ops
  soundwire: intel: add link power management callbacks in hw_ops
  soundwire: intel: add bus management callbacks in hw_ops
  soundwire: intel: add register_dai callback in hw_ops
  soundwire: intel: add debugfs callbacks in hw_ops
  soundwire: intel: start using hw_ops
  dt-bindings: soundwire: Convert text bindings to DT Schema
  soundwire: cadence: use dai_runtime_array instead of dma_data
  soundwire: cadence: rename sdw_cdns_dai_dma_data as sdw_cdns_dai_runtime
  soundwire: qcom: add support for v1.7 Soundwire Controller
  dt-bindings: soundwire: qcom: add v1.7.0 support
  soundwire: qcom: make reset optional for v1.6 controller
  soundwire: qcom: remove unused SWRM_SPECIAL_CMD_ID
  soundwire: dmi-quirks: add quirk variant for LAPBC710 NUC15
parents e7904111 7cbf00bd
Qualcomm SoundWire Controller Bindings
This binding describes the Qualcomm SoundWire Controller along with its
board specific bus parameters.
- compatible:
Usage: required
Value type: <stringlist>
Definition: must be "qcom,soundwire-v<MAJOR>.<MINOR>.<STEP>",
Example:
"qcom,soundwire-v1.3.0"
"qcom,soundwire-v1.5.0"
"qcom,soundwire-v1.5.1"
"qcom,soundwire-v1.6.0"
- reg:
Usage: required
Value type: <prop-encoded-array>
Definition: the base address and size of SoundWire controller
address space.
- interrupts:
Usage: required
Value type: <prop-encoded-array>
Definition: should specify the SoundWire Controller core and optional
wake IRQ
- interrupt-names:
Usage: Optional
Value type: boolean
Value type: <stringlist>
Definition: should be "core" for core and "wakeup" for wake interrupt.
- wakeup-source:
Usage: Optional
Value type: boolean
Definition: should specify if SoundWire Controller is wake up capable.
- clock-names:
Usage: required
Value type: <stringlist>
Definition: should be "iface" for SoundWire Controller interface clock
- clocks:
Usage: required
Value type: <prop-encoded-array>
Definition: should specify the SoundWire Controller interface clock
- #sound-dai-cells:
Usage: required
Value type: <u32>
Definition: must be 1 for digital audio interfaces on the controller.
- qcom,dout-ports:
Usage: required
Value type: <u32>
Definition: must be count of data out ports
- qcom,din-ports:
Usage: required
Value type: <u32>
Definition: must be count of data in ports
- qcom,ports-offset1:
Usage: required
Value type: <prop-encoded-array>
Definition: should specify payload transport window offset1 of each
data port. Out ports followed by In ports.
Value of 0xFF indicates that this option is not implemented
or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
- qcom,ports-offset2:
Usage: required
Value type: <prop-encoded-array>
Definition: should specify payload transport window offset2 of each
data port. Out ports followed by In ports.
Value of 0xFF indicates that this option is not implemented
or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
- qcom,ports-sinterval-low:
Usage: required
Value type: <prop-encoded-array>
Definition: should be sample interval low of each data port.
Out ports followed by In ports. Used for Sample Interval
calculation.
Value of 0xFF indicates that this option is not implemented
or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
- qcom,ports-word-length:
Usage: optional
Value type: <prop-encoded-array>
Definition: should be size of payload channel sample.
Value of 0xFF indicates that this option is not implemented
or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
- qcom,ports-block-pack-mode:
Usage: optional
Value type: <prop-encoded-array>
Definition: should be 0 or 1 to indicate the block packing mode.
0 to indicate Blocks are per Channel
1 to indicate Blocks are per Port.
Out ports followed by In ports.
Value of 0xFF indicates that this option is not implemented
or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
- qcom,ports-block-group-count:
Usage: optional
Value type: <prop-encoded-array>
Definition: should be in range 1 to 4 to indicate how many sample
intervals are combined into a payload.
Out ports followed by In ports.
Value of 0xFF indicates that this option is not implemented
or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
- qcom,ports-lane-control:
Usage: optional
Value type: <prop-encoded-array>
Definition: should be in range 0 to 7 to identify which data lane
the data port uses.
Out ports followed by In ports.
Value of 0xFF indicates that this option is not implemented
or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
- qcom,ports-hstart:
Usage: optional
Value type: <prop-encoded-array>
Definition: should be number identifying lowerst numbered coloum in
SoundWire Frame, i.e. left edge of the Transport sub-frame
for each port. Values between 0 and 15 are valid.
Out ports followed by In ports.
Value of 0xFF indicates that this option is not implemented
or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
- qcom,ports-hstop:
Usage: optional
Value type: <prop-encoded-array>
Definition: should be number identifying highest numbered coloum in
SoundWire Frame, i.e. the right edge of the Transport
sub-frame for each port. Values between 0 and 15 are valid.
Out ports followed by In ports.
Value of 0xFF indicates that this option is not implemented
or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
- qcom,dports-type:
Usage: optional
Value type: <prop-encoded-array>
Definition: should be one of the following types
0 for reduced port
1 for simple ports
2 for full port
Out ports followed by In ports.
Value of 0xFF indicates that this option is not implemented
or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
- reset:
Usage: optional
Value type: <prop-encoded-array>
Definition: Should specify the SoundWire audio CSR reset controller interface,
which is required for SoundWire version 1.6.0 and above.
- reset-names:
Usage: optional
Value type: <stringlist>
Definition: should be "swr_audio_cgcr" for SoundWire audio CSR reset
controller interface.
Note:
More Information on detail of encoding of these fields can be
found in MIPI Alliance SoundWire 1.0 Specifications.
= SoundWire devices
Each subnode of the bus represents SoundWire device attached to it.
The properties of these nodes are defined by the individual bindings.
= EXAMPLE
The following example represents a SoundWire controller on DB845c board
which has controller integrated inside WCD934x codec on SDM845 SoC.
soundwire: soundwire@c85 {
compatible = "qcom,soundwire-v1.3.0";
reg = <0xc85 0x20>;
interrupts = <20 IRQ_TYPE_EDGE_RISING>;
clocks = <&wcc>;
clock-names = "iface";
resets = <&lpass_audiocc LPASS_AUDIO_SWR_TX_CGCR>;
reset-names = "swr_audio_cgcr";
#sound-dai-cells = <1>;
qcom,dports-type = <0>;
qcom,dout-ports = <6>;
qcom,din-ports = <2>;
qcom,ports-sinterval-low = /bits/ 8 <0x07 0x1F 0x3F 0x7 0x1F 0x3F 0x0F 0x0F>;
qcom,ports-offset1 = /bits/ 8 <0x01 0x02 0x0C 0x6 0x12 0x0D 0x07 0x0A >;
qcom,ports-offset2 = /bits/ 8 <0x00 0x00 0x1F 0x00 0x00 0x1F 0x00 0x00>;
/* Left Speaker */
left{
....
};
/* Right Speaker */
right{
....
};
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/soundwire/qcom,soundwire.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm SoundWire Controller
maintainers:
- Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
- Srinivasa Rao Mandadapu <quic_srivasam@quicinc.com>
description:
The Qualcomm SoundWire controller along with its board specific bus parameters.
properties:
compatible:
enum:
- qcom,soundwire-v1.3.0
- qcom,soundwire-v1.5.0
- qcom,soundwire-v1.5.1
- qcom,soundwire-v1.6.0
- qcom,soundwire-v1.7.0
reg:
maxItems: 1
interrupts:
minItems: 1
items:
- description: specify the SoundWire controller core.
- description: specify the Soundwire controller wake IRQ.
interrupt-names:
minItems: 1
items:
- const: core
- const: wakeup
clocks:
items:
- description: iface clock
clock-names:
items:
- const: iface
resets:
items:
- description: SWR_AUDIO_CGCR RESET
reset-names:
items:
- const: swr_audio_cgcr
'#sound-dai-cells':
const: 1
'#address-cells':
const: 2
'#size-cells':
const: 0
wakeup-source: true
qcom,din-ports:
$ref: /schemas/types.yaml#/definitions/uint32
description: count of data in ports
qcom,dout-ports:
$ref: /schemas/types.yaml#/definitions/uint32
description: count of data out ports
qcom,ports-word-length:
$ref: /schemas/types.yaml#/definitions/uint8-array
description:
Size of payload channel sample.
Value of 0xff indicates that this option is not implemented
or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
minItems: 3
maxItems: 5
qcom,ports-sinterval-low:
$ref: /schemas/types.yaml#/definitions/uint8-array
description:
Sample interval low of each data port.
Out ports followed by In ports. Used for Sample Interval calculation.
Value of 0xff indicates that this option is not implemented
or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
minItems: 3
maxItems: 8
qcom,ports-offset1:
$ref: /schemas/types.yaml#/definitions/uint8-array
description:
Payload transport window offset1 of each data port.
Out ports followed by In ports.
Value of 0xff indicates that this option is not implemented
or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
minItems: 3
maxItems: 8
qcom,ports-offset2:
$ref: /schemas/types.yaml#/definitions/uint8-array
description:
Payload transport window offset2 of each data port.
Out ports followed by In ports.
Value of 0xff indicates that this option is not implemented
or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
minItems: 3
maxItems: 8
qcom,ports-lane-control:
$ref: /schemas/types.yaml#/definitions/uint8-array
description:
Identify which data lane the data port uses.
Out ports followed by In ports.
Value of 0xff indicates that this option is not implemented
or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
minItems: 3
maxItems: 5
qcom,ports-block-pack-mode:
$ref: /schemas/types.yaml#/definitions/uint8-array
description:
Indicate the block packing mode.
0 to indicate Blocks are per Channel
1 to indicate Blocks are per Port.
Out ports followed by In ports.
Value of 0xff indicates that this option is not implemented
or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
minItems: 3
maxItems: 8
items:
oneOf:
- minimum: 0
maximum: 1
- const: 0xff
qcom,ports-hstart:
$ref: /schemas/types.yaml#/definitions/uint8-array
description:
Identifying lowerst numbered coloum in SoundWire Frame,
i.e. left edge of the Transport sub-frame for each port.
Out ports followed by In ports.
Value of 0xff indicates that this option is not implemented
or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
minItems: 3
maxItems: 5
items:
oneOf:
- minimum: 0
maximum: 15
- const: 0xff
qcom,ports-hstop:
$ref: /schemas/types.yaml#/definitions/uint8-array
description:
Identifying highest numbered coloum in SoundWire Frame,
i.e. the right edge of the Transport
sub-frame for each port. Out ports followed by In ports.
Value of 0xff indicates that this option is not implemented
or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
minItems: 3
maxItems: 5
items:
oneOf:
- minimum: 0
maximum: 15
- const: 0xff
qcom,ports-block-group-count:
$ref: /schemas/types.yaml#/definitions/uint8-array
description:
In range 1 to 4 to indicate how many sample intervals are combined
into a payload. Out ports followed by In ports.
Value of 0xff indicates that this option is not implemented
or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
minItems: 3
maxItems: 5
items:
oneOf:
- minimum: 0
maximum: 4
- const: 0xff
label:
maxItems: 1
patternProperties:
"^.*@[0-9a-f],[0-9a-f]$":
type: object
description:
Child nodes for a standalone audio codec or speaker amplifier IC.
It has RX and TX Soundwire secondary devices.
properties:
compatible:
pattern: "^sdw[0-9a-f]{1}[0-9a-f]{4}[0-9a-f]{4}[0-9a-f]{2}$"
required:
- compatible
- reg
- interrupts
- clocks
- clock-names
- '#sound-dai-cells'
- '#address-cells'
- '#size-cells'
- qcom,dout-ports
- qcom,din-ports
- qcom,ports-sinterval-low
- qcom,ports-offset1
- qcom,ports-offset2
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/clock/qcom,lpassaudiocc-sc7280.h>
soundwire@3210000 {
compatible = "qcom,soundwire-v1.6.0";
reg = <0x03210000 0x2000>;
interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>,
<&pdc 130 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "core", "wakeup";
clocks = <&lpass_rx_macro>;
clock-names = "iface";
qcom,din-ports = <0>;
qcom,dout-ports = <5>;
resets = <&lpass_audiocc LPASS_AUDIO_SWR_RX_CGCR>;
reset-names = "swr_audio_cgcr";
qcom,ports-word-length = /bits/ 8 <0x01 0x07 0x04 0xff 0xff>;
qcom,ports-sinterval-low = /bits/ 8 <0x03 0x3f 0x1f 0x03 0x03>;
qcom,ports-offset1 = /bits/ 8 <0x00 0x00 0x0b 0x01 0x01>;
qcom,ports-offset2 = /bits/ 8 <0x00 0x00 0x0b 0x00 0x00>;
qcom,ports-lane-control = /bits/ 8 <0x01 0x00 0x00 0x00 0x00>;
qcom,ports-block-pack-mode = /bits/ 8 <0xff 0x00 0x01 0xff 0xff>;
qcom,ports-hstart = /bits/ 8 <0xff 0x03 0xff 0xff 0xff>;
qcom,ports-hstop = /bits/ 8 <0xff 0x06 0xff 0xff 0xff>;
qcom,ports-block-group-count = /bits/ 8 <0xff 0xff 0xff 0xff 0x00>;
#sound-dai-cells = <1>;
#address-cells = <2>;
#size-cells = <0>;
codec@0,4 {
compatible = "sdw20217010d00";
reg = <0 4>;
qcom,rx-port-mapping = <1 2 3 4 5>;
};
};
......@@ -20,7 +20,7 @@ soundwire-cadence-y := cadence_master.o
obj-$(CONFIG_SOUNDWIRE_CADENCE) += soundwire-cadence.o
#Intel driver
soundwire-intel-y := intel.o intel_init.o dmi-quirks.o
soundwire-intel-y := intel.o intel_auxdevice.o intel_init.o dmi-quirks.o
obj-$(CONFIG_SOUNDWIRE_INTEL) += soundwire-intel.o
#Qualcomm driver
......
......@@ -1707,47 +1707,45 @@ int cdns_set_sdw_stream(struct snd_soc_dai *dai,
void *stream, int direction)
{
struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
struct sdw_cdns_dma_data *dma;
struct sdw_cdns_dai_runtime *dai_runtime;
dai_runtime = cdns->dai_runtime_array[dai->id];
if (stream) {
/* first paranoia check */
if (direction == SNDRV_PCM_STREAM_PLAYBACK)
dma = dai->playback_dma_data;
else
dma = dai->capture_dma_data;
if (dma) {
if (dai_runtime) {
dev_err(dai->dev,
"dma_data already allocated for dai %s\n",
"dai_runtime already allocated for dai %s\n",
dai->name);
return -EINVAL;
}
/* allocate and set dma info */
dma = kzalloc(sizeof(*dma), GFP_KERNEL);
if (!dma)
/* allocate and set dai_runtime info */
dai_runtime = kzalloc(sizeof(*dai_runtime), GFP_KERNEL);
if (!dai_runtime)
return -ENOMEM;
dma->stream_type = SDW_STREAM_PCM;
dai_runtime->stream_type = SDW_STREAM_PCM;
dma->bus = &cdns->bus;
dma->link_id = cdns->instance;
dai_runtime->bus = &cdns->bus;
dai_runtime->link_id = cdns->instance;
dma->stream = stream;
dai_runtime->stream = stream;
dai_runtime->direction = direction;
if (direction == SNDRV_PCM_STREAM_PLAYBACK)
dai->playback_dma_data = dma;
else
dai->capture_dma_data = dma;
cdns->dai_runtime_array[dai->id] = dai_runtime;
} else {
/* for NULL stream we release allocated dma_data */
if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
kfree(dai->playback_dma_data);
dai->playback_dma_data = NULL;
} else {
kfree(dai->capture_dma_data);
dai->capture_dma_data = NULL;
/* second paranoia check */
if (!dai_runtime) {
dev_err(dai->dev,
"dai_runtime not allocated for dai %s\n",
dai->name);
return -EINVAL;
}
/* for NULL stream we release allocated dai_runtime */
kfree(dai_runtime);
cdns->dai_runtime_array[dai->id] = NULL;
}
return 0;
}
......
......@@ -70,7 +70,7 @@ struct sdw_cdns_stream_config {
};
/**
* struct sdw_cdns_dma_data: Cadence DMA data
* struct sdw_cdns_dai_runtime: Cadence DAI runtime data
*
* @name: SoundWire stream name
* @stream: stream runtime
......@@ -81,8 +81,9 @@ struct sdw_cdns_stream_config {
* @hw_params: hw_params to be applied in .prepare step
* @suspended: status set when suspended, to be used in .prepare
* @paused: status set in .trigger, to be used in suspend
* @direction: stream direction
*/
struct sdw_cdns_dma_data {
struct sdw_cdns_dai_runtime {
char *name;
struct sdw_stream_runtime *stream;
struct sdw_cdns_pdi *pdi;
......@@ -92,6 +93,7 @@ struct sdw_cdns_dma_data {
struct snd_pcm_hw_params *hw_params;
bool suspended;
bool paused;
int direction;
};
/**
......@@ -108,6 +110,7 @@ struct sdw_cdns_dma_data {
* @registers: Cadence registers
* @link_up: Link status
* @msg_count: Messages sent on bus
* @dai_runtime_array: runtime context for each allocated DAI.
*/
struct sdw_cdns {
struct device *dev;
......@@ -135,6 +138,8 @@ struct sdw_cdns {
struct work_struct work;
struct list_head list;
struct sdw_cdns_dai_runtime **dai_runtime_array;
};
#define bus_to_cdns(_bus) container_of(_bus, struct sdw_cdns, bus)
......
......@@ -90,6 +90,14 @@ static const struct dmi_system_id adr_remap_quirk_table[] = {
},
.driver_data = (void *)intel_tgl_bios,
},
{
/* quirk used for NUC15 LAPBC710 skew */
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
DMI_MATCH(DMI_BOARD_NAME, "LAPBC710"),
},
.driver_data = (void *)intel_tgl_bios,
},
{
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
......
This diff is collapsed.
......@@ -7,6 +7,7 @@
/**
* struct sdw_intel_link_res - Soundwire Intel link resource structure,
* typically populated by the controller driver.
* @hw_ops: platform-specific ops
* @mmio_base: mmio base of SoundWire registers
* @registers: Link IO registers base
* @shim: Audio shim pointer
......@@ -22,6 +23,8 @@
* @list: used to walk-through all masters exposed by the same controller
*/
struct sdw_intel_link_res {
const struct sdw_intel_hw_ops *hw_ops;
void __iomem *mmio_base; /* not strictly needed, useful for debug */
void __iomem *registers;
void __iomem *shim;
......@@ -47,15 +50,92 @@ struct sdw_intel {
#endif
};
int intel_link_startup(struct auxiliary_device *auxdev);
int intel_link_process_wakeen_event(struct auxiliary_device *auxdev);
#define cdns_to_intel(_cdns) container_of(_cdns, struct sdw_intel, cdns)
struct sdw_intel_link_dev {
struct auxiliary_device auxdev;
struct sdw_intel_link_res link_res;
};
#define INTEL_MASTER_RESET_ITERATIONS 10
#define SDW_INTEL_CHECK_OPS(sdw, cb) ((sdw) && (sdw)->link_res && (sdw)->link_res->hw_ops && \
(sdw)->link_res->hw_ops->cb)
#define SDW_INTEL_OPS(sdw, cb) ((sdw)->link_res->hw_ops->cb)
static inline void sdw_intel_debugfs_init(struct sdw_intel *sdw)
{
if (SDW_INTEL_CHECK_OPS(sdw, debugfs_init))
SDW_INTEL_OPS(sdw, debugfs_init)(sdw);
}
static inline void sdw_intel_debugfs_exit(struct sdw_intel *sdw)
{
if (SDW_INTEL_CHECK_OPS(sdw, debugfs_exit))
SDW_INTEL_OPS(sdw, debugfs_exit)(sdw);
}
static inline int sdw_intel_register_dai(struct sdw_intel *sdw)
{
if (SDW_INTEL_CHECK_OPS(sdw, register_dai))
return SDW_INTEL_OPS(sdw, register_dai)(sdw);
return -ENOTSUPP;
}
static inline void sdw_intel_check_clock_stop(struct sdw_intel *sdw)
{
if (SDW_INTEL_CHECK_OPS(sdw, check_clock_stop))
SDW_INTEL_OPS(sdw, check_clock_stop)(sdw);
}
static inline int sdw_intel_start_bus(struct sdw_intel *sdw)
{
if (SDW_INTEL_CHECK_OPS(sdw, start_bus))
return SDW_INTEL_OPS(sdw, start_bus)(sdw);
return -ENOTSUPP;
}
static inline int sdw_intel_start_bus_after_reset(struct sdw_intel *sdw)
{
if (SDW_INTEL_CHECK_OPS(sdw, start_bus_after_reset))
return SDW_INTEL_OPS(sdw, start_bus_after_reset)(sdw);
return -ENOTSUPP;
}
static inline int sdw_intel_start_bus_after_clock_stop(struct sdw_intel *sdw)
{
if (SDW_INTEL_CHECK_OPS(sdw, start_bus_after_clock_stop))
return SDW_INTEL_OPS(sdw, start_bus_after_clock_stop)(sdw);
return -ENOTSUPP;
}
static inline int sdw_intel_stop_bus(struct sdw_intel *sdw, bool clock_stop)
{
if (SDW_INTEL_CHECK_OPS(sdw, stop_bus))
return SDW_INTEL_OPS(sdw, stop_bus)(sdw, clock_stop);
return -ENOTSUPP;
}
static inline int sdw_intel_link_power_up(struct sdw_intel *sdw)
{
if (SDW_INTEL_CHECK_OPS(sdw, link_power_up))
return SDW_INTEL_OPS(sdw, link_power_up)(sdw);
return -ENOTSUPP;
}
static inline int sdw_intel_link_power_down(struct sdw_intel *sdw)
{
if (SDW_INTEL_CHECK_OPS(sdw, link_power_down))
return SDW_INTEL_OPS(sdw, link_power_down)(sdw);
return -ENOTSUPP;
}
static inline int sdw_intel_shim_check_wake(struct sdw_intel *sdw)
{
if (SDW_INTEL_CHECK_OPS(sdw, shim_check_wake))
return SDW_INTEL_OPS(sdw, shim_check_wake)(sdw);
return -ENOTSUPP;
}
#define auxiliary_dev_to_sdw_intel_link_dev(auxiliary_dev) \
container_of(auxiliary_dev, struct sdw_intel_link_dev, auxdev)
static inline void sdw_intel_shim_wake(struct sdw_intel *sdw, bool wake_enable)
{
if (SDW_INTEL_CHECK_OPS(sdw, shim_wake))
SDW_INTEL_OPS(sdw, shim_wake)(sdw, wake_enable);
}
#endif /* __SDW_INTEL_LOCAL_H */
This diff is collapsed.
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/* Copyright(c) 2015-2022 Intel Corporation. */
#ifndef __SDW_INTEL_AUXDEVICE_H
#define __SDW_INTEL_AUXDEVICE_H
int intel_link_startup(struct auxiliary_device *auxdev);
int intel_link_process_wakeen_event(struct auxiliary_device *auxdev);
struct sdw_intel_link_dev {
struct auxiliary_device auxdev;
struct sdw_intel_link_res link_res;
};
#define auxiliary_dev_to_sdw_intel_link_dev(auxiliary_dev) \
container_of(auxiliary_dev, struct sdw_intel_link_dev, auxdev)
#endif /* __SDW_INTEL_AUXDEVICE_H */
......@@ -17,6 +17,7 @@
#include <linux/soundwire/sdw_intel.h>
#include "cadence_master.h"
#include "intel.h"
#include "intel_auxdevice.h"
static void intel_link_dev_release(struct device *dev)
{
......@@ -60,6 +61,7 @@ static struct sdw_intel_link_dev *intel_link_dev_register(struct sdw_intel_res *
/* Add link information used in the driver probe */
link = &ldev->link_res;
link->hw_ops = res->hw_ops;
link->mmio_base = res->mmio_base;
link->registers = res->mmio_base + SDW_LINK_BASE
+ (SDW_LINK_SIZE * link_id);
......
......@@ -25,6 +25,8 @@
#define SWRM_COMP_SW_RESET 0x008
#define SWRM_COMP_STATUS 0x014
#define SWRM_LINK_MANAGER_EE 0x018
#define SWRM_EE_CPU 1
#define SWRM_FRM_GEN_ENABLED BIT(0)
#define SWRM_COMP_HW_VERSION 0x00
#define SWRM_COMP_CFG_ADDR 0x04
......@@ -104,7 +106,6 @@
#define SWRM_REG_VAL_PACK(data, dev, id, reg) \
((reg) | ((id) << 16) | ((dev) << 20) | ((data) << 24))
#define SWRM_SPECIAL_CMD_ID 0xF
#define MAX_FREQ_NUM 1
#define TIMEOUT_MS 100
#define QCOM_SWRM_MAX_RD_LEN 0x1
......@@ -694,7 +695,14 @@ static int qcom_swrm_init(struct qcom_swrm_ctrl *ctrl)
u32p_replace_bits(&val, SWRM_DEF_CMD_NO_PINGS, SWRM_MCP_CFG_MAX_NUM_OF_CMD_NO_PINGS_BMSK);
ctrl->reg_write(ctrl, SWRM_MCP_CFG_ADDR, val);
ctrl->reg_write(ctrl, SWRM_MCP_BUS_CTRL, SWRM_MCP_BUS_CLK_START);
if (ctrl->version >= 0x01070000) {
ctrl->reg_write(ctrl, SWRM_LINK_MANAGER_EE, SWRM_EE_CPU);
ctrl->reg_write(ctrl, SWRM_MCP_BUS_CTRL,
SWRM_MCP_BUS_CLK_START << SWRM_EE_CPU);
} else {
ctrl->reg_write(ctrl, SWRM_MCP_BUS_CTRL, SWRM_MCP_BUS_CLK_START);
}
/* Configure number of retries of a read/write cmd */
if (ctrl->version > 0x01050001) {
/* Only for versions >= 1.5.1 */
......@@ -1331,8 +1339,8 @@ static int qcom_swrm_probe(struct platform_device *pdev)
}
if (data->sw_clk_gate_required) {
ctrl->audio_cgcr = devm_reset_control_get_exclusive(dev, "swr_audio_cgcr");
if (IS_ERR_OR_NULL(ctrl->audio_cgcr)) {
ctrl->audio_cgcr = devm_reset_control_get_optional_exclusive(dev, "swr_audio_cgcr");
if (IS_ERR(ctrl->audio_cgcr)) {
dev_err(dev, "Failed to get cgcr reset ctrl required for SW gating\n");
ret = PTR_ERR(ctrl->audio_cgcr);
goto err_init;
......@@ -1519,7 +1527,13 @@ static int __maybe_unused swrm_runtime_resume(struct device *dev)
} else {
reset_control_reset(ctrl->audio_cgcr);
ctrl->reg_write(ctrl, SWRM_MCP_BUS_CTRL, SWRM_MCP_BUS_CLK_START);
if (ctrl->version >= 0x01070000) {
ctrl->reg_write(ctrl, SWRM_LINK_MANAGER_EE, SWRM_EE_CPU);
ctrl->reg_write(ctrl, SWRM_MCP_BUS_CTRL,
SWRM_MCP_BUS_CLK_START << SWRM_EE_CPU);
} else {
ctrl->reg_write(ctrl, SWRM_MCP_BUS_CTRL, SWRM_MCP_BUS_CLK_START);
}
ctrl->reg_write(ctrl, SWRM_INTERRUPT_CLEAR,
SWRM_INTERRUPT_STATUS_MASTER_CLASH_DET);
......@@ -1583,6 +1597,7 @@ static const struct of_device_id qcom_swrm_of_match[] = {
{ .compatible = "qcom,soundwire-v1.3.0", .data = &swrm_v1_3_data },
{ .compatible = "qcom,soundwire-v1.5.1", .data = &swrm_v1_5_data },
{ .compatible = "qcom,soundwire-v1.6.0", .data = &swrm_v1_6_data },
{ .compatible = "qcom,soundwire-v1.7.0", .data = &swrm_v1_5_data },
{/* sentinel */},
};
......
......@@ -233,6 +233,7 @@ struct sdw_intel_ctx {
* struct sdw_intel_res - Soundwire Intel global resource structure,
* typically populated by the DSP driver
*
* @hw_ops: abstraction for platform ops
* @count: link count
* @mmio_base: mmio base of SoundWire registers
* @irq: interrupt number
......@@ -249,6 +250,7 @@ struct sdw_intel_ctx {
* @alh_base: sdw alh base.
*/
struct sdw_intel_res {
const struct sdw_intel_hw_ops *hw_ops;
int count;
void __iomem *mmio_base;
int irq;
......@@ -290,4 +292,46 @@ irqreturn_t sdw_intel_thread(int irq, void *dev_id);
#define SDW_INTEL_QUIRK_MASK_BUS_DISABLE BIT(1)
struct sdw_intel;
/* struct intel_sdw_hw_ops - SoundWire ops for Intel platforms.
* @debugfs_init: initialize all debugfs capabilities
* @debugfs_exit: close and cleanup debugfs capabilities
* @register_dai: read all PDI information and register DAIs
* @check_clock_stop: throw error message if clock is not stopped.
* @start_bus: normal start
* @start_bus_after_reset: start after reset
* @start_bus_after_clock_stop: start after mode0 clock stop
* @stop_bus: stop all bus
* @link_power_up: power-up using chip-specific helpers
* @link_power_down: power-down with chip-specific helpers
* @shim_check_wake: check if a wake was received
* @shim_wake: enable/disable in-band wake management
* @pre_bank_switch: helper for bus management
* @post_bank_switch: helper for bus management
*/
struct sdw_intel_hw_ops {
void (*debugfs_init)(struct sdw_intel *sdw);
void (*debugfs_exit)(struct sdw_intel *sdw);
int (*register_dai)(struct sdw_intel *sdw);
void (*check_clock_stop)(struct sdw_intel *sdw);
int (*start_bus)(struct sdw_intel *sdw);
int (*start_bus_after_reset)(struct sdw_intel *sdw);
int (*start_bus_after_clock_stop)(struct sdw_intel *sdw);
int (*stop_bus)(struct sdw_intel *sdw, bool clock_stop);
int (*link_power_up)(struct sdw_intel *sdw);
int (*link_power_down)(struct sdw_intel *sdw);
int (*shim_check_wake)(struct sdw_intel *sdw);
void (*shim_wake)(struct sdw_intel *sdw, bool wake_enable);
int (*pre_bank_switch)(struct sdw_intel *sdw);
int (*post_bank_switch)(struct sdw_intel *sdw);
};
extern const struct sdw_intel_hw_ops sdw_intel_cnl_hw_ops;
#endif
......@@ -206,6 +206,7 @@ static int hda_sdw_probe(struct snd_sof_dev *sdev)
memset(&res, 0, sizeof(res));
res.hw_ops = &sdw_intel_cnl_hw_ops;
res.mmio_base = sdev->bar[HDA_DSP_BAR];
res.shim_base = hdev->desc->sdw_shim_base;
res.alh_base = hdev->desc->sdw_alh_base;
......@@ -1727,3 +1728,4 @@ MODULE_IMPORT_NS(SND_SOC_SOF_HDA_AUDIO_CODEC_I915);
MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA);
MODULE_IMPORT_NS(SND_INTEL_SOUNDWIRE_ACPI);
MODULE_IMPORT_NS(SOUNDWIRE_INTEL_INIT);
MODULE_IMPORT_NS(SOUNDWIRE_INTEL);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment