Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+1237 -950
-214
Documentation/devicetree/bindings/soundwire/qcom,sdw.txt
··· 1 - Qualcomm SoundWire Controller Bindings 2 - 3 - 4 - This binding describes the Qualcomm SoundWire Controller along with its 5 - board specific bus parameters. 6 - 7 - - compatible: 8 - Usage: required 9 - Value type: <stringlist> 10 - Definition: must be "qcom,soundwire-v<MAJOR>.<MINOR>.<STEP>", 11 - Example: 12 - "qcom,soundwire-v1.3.0" 13 - "qcom,soundwire-v1.5.0" 14 - "qcom,soundwire-v1.5.1" 15 - "qcom,soundwire-v1.6.0" 16 - - reg: 17 - Usage: required 18 - Value type: <prop-encoded-array> 19 - Definition: the base address and size of SoundWire controller 20 - address space. 21 - 22 - - interrupts: 23 - Usage: required 24 - Value type: <prop-encoded-array> 25 - Definition: should specify the SoundWire Controller core and optional 26 - wake IRQ 27 - 28 - - interrupt-names: 29 - Usage: Optional 30 - Value type: boolean 31 - Value type: <stringlist> 32 - Definition: should be "core" for core and "wakeup" for wake interrupt. 33 - 34 - - wakeup-source: 35 - Usage: Optional 36 - Value type: boolean 37 - Definition: should specify if SoundWire Controller is wake up capable. 38 - 39 - - clock-names: 40 - Usage: required 41 - Value type: <stringlist> 42 - Definition: should be "iface" for SoundWire Controller interface clock 43 - 44 - - clocks: 45 - Usage: required 46 - Value type: <prop-encoded-array> 47 - Definition: should specify the SoundWire Controller interface clock 48 - 49 - - #sound-dai-cells: 50 - Usage: required 51 - Value type: <u32> 52 - Definition: must be 1 for digital audio interfaces on the controller. 53 - 54 - - qcom,dout-ports: 55 - Usage: required 56 - Value type: <u32> 57 - Definition: must be count of data out ports 58 - 59 - - qcom,din-ports: 60 - Usage: required 61 - Value type: <u32> 62 - Definition: must be count of data in ports 63 - 64 - - qcom,ports-offset1: 65 - Usage: required 66 - Value type: <prop-encoded-array> 67 - Definition: should specify payload transport window offset1 of each 68 - data port. Out ports followed by In ports. 69 - Value of 0xFF indicates that this option is not implemented 70 - or applicable for the respective data port. 71 - More info in MIPI Alliance SoundWire 1.0 Specifications. 72 - 73 - - qcom,ports-offset2: 74 - Usage: required 75 - Value type: <prop-encoded-array> 76 - Definition: should specify payload transport window offset2 of each 77 - data port. Out ports followed by In ports. 78 - Value of 0xFF indicates that this option is not implemented 79 - or applicable for the respective data port. 80 - More info in MIPI Alliance SoundWire 1.0 Specifications. 81 - 82 - - qcom,ports-sinterval-low: 83 - Usage: required 84 - Value type: <prop-encoded-array> 85 - Definition: should be sample interval low of each data port. 86 - Out ports followed by In ports. Used for Sample Interval 87 - calculation. 88 - Value of 0xFF indicates that this option is not implemented 89 - or applicable for the respective data port. 90 - More info in MIPI Alliance SoundWire 1.0 Specifications. 91 - 92 - - qcom,ports-word-length: 93 - Usage: optional 94 - Value type: <prop-encoded-array> 95 - Definition: should be size of payload channel sample. 96 - Value of 0xFF indicates that this option is not implemented 97 - or applicable for the respective data port. 98 - More info in MIPI Alliance SoundWire 1.0 Specifications. 99 - 100 - - qcom,ports-block-pack-mode: 101 - Usage: optional 102 - Value type: <prop-encoded-array> 103 - Definition: should be 0 or 1 to indicate the block packing mode. 104 - 0 to indicate Blocks are per Channel 105 - 1 to indicate Blocks are per Port. 106 - Out ports followed by In ports. 107 - Value of 0xFF indicates that this option is not implemented 108 - or applicable for the respective data port. 109 - More info in MIPI Alliance SoundWire 1.0 Specifications. 110 - 111 - - qcom,ports-block-group-count: 112 - Usage: optional 113 - Value type: <prop-encoded-array> 114 - Definition: should be in range 1 to 4 to indicate how many sample 115 - intervals are combined into a payload. 116 - Out ports followed by In ports. 117 - Value of 0xFF indicates that this option is not implemented 118 - or applicable for the respective data port. 119 - More info in MIPI Alliance SoundWire 1.0 Specifications. 120 - 121 - - qcom,ports-lane-control: 122 - Usage: optional 123 - Value type: <prop-encoded-array> 124 - Definition: should be in range 0 to 7 to identify which data lane 125 - the data port uses. 126 - Out ports followed by In ports. 127 - Value of 0xFF indicates that this option is not implemented 128 - or applicable for the respective data port. 129 - More info in MIPI Alliance SoundWire 1.0 Specifications. 130 - 131 - - qcom,ports-hstart: 132 - Usage: optional 133 - Value type: <prop-encoded-array> 134 - Definition: should be number identifying lowerst numbered coloum in 135 - SoundWire Frame, i.e. left edge of the Transport sub-frame 136 - for each port. Values between 0 and 15 are valid. 137 - Out ports followed by In ports. 138 - Value of 0xFF indicates that this option is not implemented 139 - or applicable for the respective data port. 140 - More info in MIPI Alliance SoundWire 1.0 Specifications. 141 - 142 - - qcom,ports-hstop: 143 - Usage: optional 144 - Value type: <prop-encoded-array> 145 - Definition: should be number identifying highest numbered coloum in 146 - SoundWire Frame, i.e. the right edge of the Transport 147 - sub-frame for each port. Values between 0 and 15 are valid. 148 - Out ports followed by In ports. 149 - Value of 0xFF indicates that this option is not implemented 150 - or applicable for the respective data port. 151 - More info in MIPI Alliance SoundWire 1.0 Specifications. 152 - 153 - - qcom,dports-type: 154 - Usage: optional 155 - Value type: <prop-encoded-array> 156 - Definition: should be one of the following types 157 - 0 for reduced port 158 - 1 for simple ports 159 - 2 for full port 160 - Out ports followed by In ports. 161 - Value of 0xFF indicates that this option is not implemented 162 - or applicable for the respective data port. 163 - More info in MIPI Alliance SoundWire 1.0 Specifications. 164 - 165 - - reset: 166 - Usage: optional 167 - Value type: <prop-encoded-array> 168 - Definition: Should specify the SoundWire audio CSR reset controller interface, 169 - which is required for SoundWire version 1.6.0 and above. 170 - 171 - - reset-names: 172 - Usage: optional 173 - Value type: <stringlist> 174 - Definition: should be "swr_audio_cgcr" for SoundWire audio CSR reset 175 - controller interface. 176 - 177 - Note: 178 - More Information on detail of encoding of these fields can be 179 - found in MIPI Alliance SoundWire 1.0 Specifications. 180 - 181 - = SoundWire devices 182 - Each subnode of the bus represents SoundWire device attached to it. 183 - The properties of these nodes are defined by the individual bindings. 184 - 185 - = EXAMPLE 186 - The following example represents a SoundWire controller on DB845c board 187 - which has controller integrated inside WCD934x codec on SDM845 SoC. 188 - 189 - soundwire: soundwire@c85 { 190 - compatible = "qcom,soundwire-v1.3.0"; 191 - reg = <0xc85 0x20>; 192 - interrupts = <20 IRQ_TYPE_EDGE_RISING>; 193 - clocks = <&wcc>; 194 - clock-names = "iface"; 195 - resets = <&lpass_audiocc LPASS_AUDIO_SWR_TX_CGCR>; 196 - reset-names = "swr_audio_cgcr"; 197 - #sound-dai-cells = <1>; 198 - qcom,dports-type = <0>; 199 - qcom,dout-ports = <6>; 200 - qcom,din-ports = <2>; 201 - qcom,ports-sinterval-low = /bits/ 8 <0x07 0x1F 0x3F 0x7 0x1F 0x3F 0x0F 0x0F>; 202 - qcom,ports-offset1 = /bits/ 8 <0x01 0x02 0x0C 0x6 0x12 0x0D 0x07 0x0A >; 203 - qcom,ports-offset2 = /bits/ 8 <0x00 0x00 0x1F 0x00 0x00 0x1F 0x00 0x00>; 204 - 205 - /* Left Speaker */ 206 - left{ 207 - .... 208 - }; 209 - 210 - /* Right Speaker */ 211 - right{ 212 - .... 213 - }; 214 - };
+270
Documentation/devicetree/bindings/soundwire/qcom,soundwire.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/soundwire/qcom,soundwire.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Qualcomm SoundWire Controller 8 + 9 + maintainers: 10 + - Srinivas Kandagatla <srinivas.kandagatla@linaro.org> 11 + - Srinivasa Rao Mandadapu <quic_srivasam@quicinc.com> 12 + 13 + description: 14 + The Qualcomm SoundWire controller along with its board specific bus parameters. 15 + 16 + properties: 17 + compatible: 18 + enum: 19 + - qcom,soundwire-v1.3.0 20 + - qcom,soundwire-v1.5.0 21 + - qcom,soundwire-v1.5.1 22 + - qcom,soundwire-v1.6.0 23 + - qcom,soundwire-v1.7.0 24 + 25 + reg: 26 + maxItems: 1 27 + 28 + interrupts: 29 + minItems: 1 30 + items: 31 + - description: specify the SoundWire controller core. 32 + - description: specify the Soundwire controller wake IRQ. 33 + 34 + interrupt-names: 35 + minItems: 1 36 + items: 37 + - const: core 38 + - const: wakeup 39 + 40 + clocks: 41 + items: 42 + - description: iface clock 43 + 44 + clock-names: 45 + items: 46 + - const: iface 47 + 48 + resets: 49 + items: 50 + - description: SWR_AUDIO_CGCR RESET 51 + 52 + reset-names: 53 + items: 54 + - const: swr_audio_cgcr 55 + 56 + '#sound-dai-cells': 57 + const: 1 58 + 59 + '#address-cells': 60 + const: 2 61 + 62 + '#size-cells': 63 + const: 0 64 + 65 + wakeup-source: true 66 + 67 + qcom,din-ports: 68 + $ref: /schemas/types.yaml#/definitions/uint32 69 + description: count of data in ports 70 + 71 + qcom,dout-ports: 72 + $ref: /schemas/types.yaml#/definitions/uint32 73 + description: count of data out ports 74 + 75 + qcom,ports-word-length: 76 + $ref: /schemas/types.yaml#/definitions/uint8-array 77 + description: 78 + Size of payload channel sample. 79 + Value of 0xff indicates that this option is not implemented 80 + or applicable for the respective data port. 81 + More info in MIPI Alliance SoundWire 1.0 Specifications. 82 + minItems: 3 83 + maxItems: 5 84 + 85 + qcom,ports-sinterval-low: 86 + $ref: /schemas/types.yaml#/definitions/uint8-array 87 + description: 88 + Sample interval low of each data port. 89 + Out ports followed by In ports. Used for Sample Interval calculation. 90 + Value of 0xff indicates that this option is not implemented 91 + or applicable for the respective data port. 92 + More info in MIPI Alliance SoundWire 1.0 Specifications. 93 + minItems: 3 94 + maxItems: 8 95 + 96 + qcom,ports-offset1: 97 + $ref: /schemas/types.yaml#/definitions/uint8-array 98 + description: 99 + Payload transport window offset1 of each data port. 100 + Out ports followed by In ports. 101 + Value of 0xff indicates that this option is not implemented 102 + or applicable for the respective data port. 103 + More info in MIPI Alliance SoundWire 1.0 Specifications. 104 + minItems: 3 105 + maxItems: 8 106 + 107 + qcom,ports-offset2: 108 + $ref: /schemas/types.yaml#/definitions/uint8-array 109 + description: 110 + Payload transport window offset2 of each data port. 111 + Out ports followed by In ports. 112 + Value of 0xff indicates that this option is not implemented 113 + or applicable for the respective data port. 114 + More info in MIPI Alliance SoundWire 1.0 Specifications. 115 + minItems: 3 116 + maxItems: 8 117 + 118 + qcom,ports-lane-control: 119 + $ref: /schemas/types.yaml#/definitions/uint8-array 120 + description: 121 + Identify which data lane the data port uses. 122 + Out ports followed by In ports. 123 + Value of 0xff indicates that this option is not implemented 124 + or applicable for the respective data port. 125 + More info in MIPI Alliance SoundWire 1.0 Specifications. 126 + minItems: 3 127 + maxItems: 5 128 + 129 + qcom,ports-block-pack-mode: 130 + $ref: /schemas/types.yaml#/definitions/uint8-array 131 + description: 132 + Indicate the block packing mode. 133 + 0 to indicate Blocks are per Channel 134 + 1 to indicate Blocks are per Port. 135 + Out ports followed by In ports. 136 + Value of 0xff indicates that this option is not implemented 137 + or applicable for the respective data port. 138 + More info in MIPI Alliance SoundWire 1.0 Specifications. 139 + minItems: 3 140 + maxItems: 8 141 + items: 142 + oneOf: 143 + - minimum: 0 144 + maximum: 1 145 + - const: 0xff 146 + 147 + qcom,ports-hstart: 148 + $ref: /schemas/types.yaml#/definitions/uint8-array 149 + description: 150 + Identifying lowerst numbered coloum in SoundWire Frame, 151 + i.e. left edge of the Transport sub-frame for each port. 152 + Out ports followed by In ports. 153 + Value of 0xff indicates that this option is not implemented 154 + or applicable for the respective data port. 155 + More info in MIPI Alliance SoundWire 1.0 Specifications. 156 + minItems: 3 157 + maxItems: 5 158 + items: 159 + oneOf: 160 + - minimum: 0 161 + maximum: 15 162 + - const: 0xff 163 + 164 + qcom,ports-hstop: 165 + $ref: /schemas/types.yaml#/definitions/uint8-array 166 + description: 167 + Identifying highest numbered coloum in SoundWire Frame, 168 + i.e. the right edge of the Transport 169 + sub-frame for each port. Out ports followed by In ports. 170 + Value of 0xff indicates that this option is not implemented 171 + or applicable for the respective data port. 172 + More info in MIPI Alliance SoundWire 1.0 Specifications. 173 + minItems: 3 174 + maxItems: 5 175 + items: 176 + oneOf: 177 + - minimum: 0 178 + maximum: 15 179 + - const: 0xff 180 + 181 + qcom,ports-block-group-count: 182 + $ref: /schemas/types.yaml#/definitions/uint8-array 183 + description: 184 + In range 1 to 4 to indicate how many sample intervals are combined 185 + into a payload. Out ports followed by In ports. 186 + Value of 0xff indicates that this option is not implemented 187 + or applicable for the respective data port. 188 + More info in MIPI Alliance SoundWire 1.0 Specifications. 189 + minItems: 3 190 + maxItems: 5 191 + items: 192 + oneOf: 193 + - minimum: 0 194 + maximum: 4 195 + - const: 0xff 196 + 197 + label: 198 + maxItems: 1 199 + 200 + patternProperties: 201 + "^.*@[0-9a-f],[0-9a-f]$": 202 + type: object 203 + description: 204 + Child nodes for a standalone audio codec or speaker amplifier IC. 205 + It has RX and TX Soundwire secondary devices. 206 + properties: 207 + compatible: 208 + pattern: "^sdw[0-9a-f]{1}[0-9a-f]{4}[0-9a-f]{4}[0-9a-f]{2}$" 209 + 210 + required: 211 + - compatible 212 + - reg 213 + - interrupts 214 + - clocks 215 + - clock-names 216 + - '#sound-dai-cells' 217 + - '#address-cells' 218 + - '#size-cells' 219 + - qcom,dout-ports 220 + - qcom,din-ports 221 + - qcom,ports-sinterval-low 222 + - qcom,ports-offset1 223 + - qcom,ports-offset2 224 + 225 + additionalProperties: false 226 + 227 + examples: 228 + - | 229 + #include <dt-bindings/interrupt-controller/arm-gic.h> 230 + #include <dt-bindings/interrupt-controller/irq.h> 231 + #include <dt-bindings/clock/qcom,lpassaudiocc-sc7280.h> 232 + 233 + soundwire@3210000 { 234 + compatible = "qcom,soundwire-v1.6.0"; 235 + reg = <0x03210000 0x2000>; 236 + 237 + interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>, 238 + <&pdc 130 IRQ_TYPE_LEVEL_HIGH>; 239 + 240 + interrupt-names = "core", "wakeup"; 241 + 242 + clocks = <&lpass_rx_macro>; 243 + clock-names = "iface"; 244 + 245 + qcom,din-ports = <0>; 246 + qcom,dout-ports = <5>; 247 + 248 + resets = <&lpass_audiocc LPASS_AUDIO_SWR_RX_CGCR>; 249 + reset-names = "swr_audio_cgcr"; 250 + 251 + qcom,ports-word-length = /bits/ 8 <0x01 0x07 0x04 0xff 0xff>; 252 + qcom,ports-sinterval-low = /bits/ 8 <0x03 0x3f 0x1f 0x03 0x03>; 253 + qcom,ports-offset1 = /bits/ 8 <0x00 0x00 0x0b 0x01 0x01>; 254 + qcom,ports-offset2 = /bits/ 8 <0x00 0x00 0x0b 0x00 0x00>; 255 + qcom,ports-lane-control = /bits/ 8 <0x01 0x00 0x00 0x00 0x00>; 256 + qcom,ports-block-pack-mode = /bits/ 8 <0xff 0x00 0x01 0xff 0xff>; 257 + qcom,ports-hstart = /bits/ 8 <0xff 0x03 0xff 0xff 0xff>; 258 + qcom,ports-hstop = /bits/ 8 <0xff 0x06 0xff 0xff 0xff>; 259 + qcom,ports-block-group-count = /bits/ 8 <0xff 0xff 0xff 0xff 0x00>; 260 + 261 + #sound-dai-cells = <1>; 262 + #address-cells = <2>; 263 + #size-cells = <0>; 264 + 265 + codec@0,4 { 266 + compatible = "sdw20217010d00"; 267 + reg = <0 4>; 268 + qcom,rx-port-mapping = <1 2 3 4 5>; 269 + }; 270 + };
+1 -1
drivers/soundwire/Makefile
··· 20 20 obj-$(CONFIG_SOUNDWIRE_CADENCE) += soundwire-cadence.o 21 21 22 22 #Intel driver 23 - soundwire-intel-y := intel.o intel_init.o dmi-quirks.o 23 + soundwire-intel-y := intel.o intel_auxdevice.o intel_init.o dmi-quirks.o 24 24 obj-$(CONFIG_SOUNDWIRE_INTEL) += soundwire-intel.o 25 25 26 26 #Qualcomm driver
+24 -26
drivers/soundwire/cadence_master.c
··· 1707 1707 void *stream, int direction) 1708 1708 { 1709 1709 struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai); 1710 - struct sdw_cdns_dma_data *dma; 1710 + struct sdw_cdns_dai_runtime *dai_runtime; 1711 + 1712 + dai_runtime = cdns->dai_runtime_array[dai->id]; 1711 1713 1712 1714 if (stream) { 1713 1715 /* first paranoia check */ 1714 - if (direction == SNDRV_PCM_STREAM_PLAYBACK) 1715 - dma = dai->playback_dma_data; 1716 - else 1717 - dma = dai->capture_dma_data; 1718 - 1719 - if (dma) { 1716 + if (dai_runtime) { 1720 1717 dev_err(dai->dev, 1721 - "dma_data already allocated for dai %s\n", 1718 + "dai_runtime already allocated for dai %s\n", 1722 1719 dai->name); 1723 1720 return -EINVAL; 1724 1721 } 1725 1722 1726 - /* allocate and set dma info */ 1727 - dma = kzalloc(sizeof(*dma), GFP_KERNEL); 1728 - if (!dma) 1723 + /* allocate and set dai_runtime info */ 1724 + dai_runtime = kzalloc(sizeof(*dai_runtime), GFP_KERNEL); 1725 + if (!dai_runtime) 1729 1726 return -ENOMEM; 1730 1727 1731 - dma->stream_type = SDW_STREAM_PCM; 1728 + dai_runtime->stream_type = SDW_STREAM_PCM; 1732 1729 1733 - dma->bus = &cdns->bus; 1734 - dma->link_id = cdns->instance; 1730 + dai_runtime->bus = &cdns->bus; 1731 + dai_runtime->link_id = cdns->instance; 1735 1732 1736 - dma->stream = stream; 1733 + dai_runtime->stream = stream; 1734 + dai_runtime->direction = direction; 1737 1735 1738 - if (direction == SNDRV_PCM_STREAM_PLAYBACK) 1739 - dai->playback_dma_data = dma; 1740 - else 1741 - dai->capture_dma_data = dma; 1736 + cdns->dai_runtime_array[dai->id] = dai_runtime; 1742 1737 } else { 1743 - /* for NULL stream we release allocated dma_data */ 1744 - if (direction == SNDRV_PCM_STREAM_PLAYBACK) { 1745 - kfree(dai->playback_dma_data); 1746 - dai->playback_dma_data = NULL; 1747 - } else { 1748 - kfree(dai->capture_dma_data); 1749 - dai->capture_dma_data = NULL; 1738 + /* second paranoia check */ 1739 + if (!dai_runtime) { 1740 + dev_err(dai->dev, 1741 + "dai_runtime not allocated for dai %s\n", 1742 + dai->name); 1743 + return -EINVAL; 1750 1744 } 1745 + 1746 + /* for NULL stream we release allocated dai_runtime */ 1747 + kfree(dai_runtime); 1748 + cdns->dai_runtime_array[dai->id] = NULL; 1751 1749 } 1752 1750 return 0; 1753 1751 }
+7 -2
drivers/soundwire/cadence_master.h
··· 70 70 }; 71 71 72 72 /** 73 - * struct sdw_cdns_dma_data: Cadence DMA data 73 + * struct sdw_cdns_dai_runtime: Cadence DAI runtime data 74 74 * 75 75 * @name: SoundWire stream name 76 76 * @stream: stream runtime ··· 81 81 * @hw_params: hw_params to be applied in .prepare step 82 82 * @suspended: status set when suspended, to be used in .prepare 83 83 * @paused: status set in .trigger, to be used in suspend 84 + * @direction: stream direction 84 85 */ 85 - struct sdw_cdns_dma_data { 86 + struct sdw_cdns_dai_runtime { 86 87 char *name; 87 88 struct sdw_stream_runtime *stream; 88 89 struct sdw_cdns_pdi *pdi; ··· 93 92 struct snd_pcm_hw_params *hw_params; 94 93 bool suspended; 95 94 bool paused; 95 + int direction; 96 96 }; 97 97 98 98 /** ··· 110 108 * @registers: Cadence registers 111 109 * @link_up: Link status 112 110 * @msg_count: Messages sent on bus 111 + * @dai_runtime_array: runtime context for each allocated DAI. 113 112 */ 114 113 struct sdw_cdns { 115 114 struct device *dev; ··· 138 135 struct work_struct work; 139 136 140 137 struct list_head list; 138 + 139 + struct sdw_cdns_dai_runtime **dai_runtime_array; 141 140 }; 142 141 143 142 #define bus_to_cdns(_bus) container_of(_bus, struct sdw_cdns, bus)
+8
drivers/soundwire/dmi-quirks.c
··· 91 91 .driver_data = (void *)intel_tgl_bios, 92 92 }, 93 93 { 94 + /* quirk used for NUC15 LAPBC710 skew */ 95 + .matches = { 96 + DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), 97 + DMI_MATCH(DMI_BOARD_NAME, "LAPBC710"), 98 + }, 99 + .driver_data = (void *)intel_tgl_bios, 100 + }, 101 + { 94 102 .matches = { 95 103 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 96 104 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A3E")
+75 -694
drivers/soundwire/intel.c
··· 8 8 #include <linux/acpi.h> 9 9 #include <linux/debugfs.h> 10 10 #include <linux/delay.h> 11 - #include <linux/module.h> 12 - #include <linux/interrupt.h> 13 11 #include <linux/io.h> 14 - #include <linux/auxiliary_bus.h> 15 12 #include <sound/pcm_params.h> 16 13 #include <linux/pm_runtime.h> 17 14 #include <sound/soc.h> ··· 19 22 #include "bus.h" 20 23 #include "intel.h" 21 24 22 - /* IDA min selected to avoid conflicts with HDaudio/iDISP SDI values */ 23 - #define INTEL_DEV_NUM_IDA_MIN 4 24 - 25 - #define INTEL_MASTER_SUSPEND_DELAY_MS 3000 26 - #define INTEL_MASTER_RESET_ITERATIONS 10 27 - 28 - /* 29 - * debug/config flags for the Intel SoundWire Master. 30 - * 31 - * Since we may have multiple masters active, we can have up to 8 32 - * flags reused in each byte, with master0 using the ls-byte, etc. 33 - */ 34 - 35 - #define SDW_INTEL_MASTER_DISABLE_PM_RUNTIME BIT(0) 36 - #define SDW_INTEL_MASTER_DISABLE_CLOCK_STOP BIT(1) 37 - #define SDW_INTEL_MASTER_DISABLE_PM_RUNTIME_IDLE BIT(2) 38 - #define SDW_INTEL_MASTER_DISABLE_MULTI_LINK BIT(3) 39 - 40 - static int md_flags; 41 - module_param_named(sdw_md_flags, md_flags, int, 0444); 42 - MODULE_PARM_DESC(sdw_md_flags, "SoundWire Intel Master device flags (0x0 all off)"); 43 25 44 26 enum intel_pdi_type { 45 27 INTEL_PDI_IN = 0, ··· 721 745 * bank switch routines 722 746 */ 723 747 724 - static int intel_pre_bank_switch(struct sdw_bus *bus) 748 + static int intel_pre_bank_switch(struct sdw_intel *sdw) 725 749 { 726 - struct sdw_cdns *cdns = bus_to_cdns(bus); 727 - struct sdw_intel *sdw = cdns_to_intel(cdns); 750 + struct sdw_cdns *cdns = &sdw->cdns; 751 + struct sdw_bus *bus = &cdns->bus; 728 752 729 753 /* Write to register only for multi-link */ 730 754 if (!bus->multi_link) ··· 735 759 return 0; 736 760 } 737 761 738 - static int intel_post_bank_switch(struct sdw_bus *bus) 762 + static int intel_post_bank_switch(struct sdw_intel *sdw) 739 763 { 740 - struct sdw_cdns *cdns = bus_to_cdns(bus); 741 - struct sdw_intel *sdw = cdns_to_intel(cdns); 764 + struct sdw_cdns *cdns = &sdw->cdns; 765 + struct sdw_bus *bus = &cdns->bus; 742 766 void __iomem *shim = sdw->link_res->shim; 743 767 int sync_reg, ret; 744 768 ··· 800 824 { 801 825 struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai); 802 826 struct sdw_intel *sdw = cdns_to_intel(cdns); 803 - struct sdw_cdns_dma_data *dma; 827 + struct sdw_cdns_dai_runtime *dai_runtime; 804 828 struct sdw_cdns_pdi *pdi; 805 829 struct sdw_stream_config sconfig; 806 830 struct sdw_port_config *pconfig; 807 831 int ch, dir; 808 832 int ret; 809 833 810 - dma = snd_soc_dai_get_dma_data(dai, substream); 811 - if (!dma) 834 + dai_runtime = cdns->dai_runtime_array[dai->id]; 835 + if (!dai_runtime) 812 836 return -EIO; 813 837 814 838 ch = params_channels(params); ··· 830 854 sdw_cdns_config_stream(cdns, ch, dir, pdi); 831 855 832 856 /* store pdi and hw_params, may be needed in prepare step */ 833 - dma->paused = false; 834 - dma->suspended = false; 835 - dma->pdi = pdi; 836 - dma->hw_params = params; 857 + dai_runtime->paused = false; 858 + dai_runtime->suspended = false; 859 + dai_runtime->pdi = pdi; 860 + dai_runtime->hw_params = params; 837 861 838 862 /* Inform DSP about PDI stream number */ 839 863 ret = intel_params_stream(sdw, substream->stream, dai, params, ··· 845 869 sconfig.direction = dir; 846 870 sconfig.ch_count = ch; 847 871 sconfig.frame_rate = params_rate(params); 848 - sconfig.type = dma->stream_type; 872 + sconfig.type = dai_runtime->stream_type; 849 873 850 874 sconfig.bps = snd_pcm_format_width(params_format(params)); 851 875 ··· 860 884 pconfig->ch_mask = (1 << ch) - 1; 861 885 862 886 ret = sdw_stream_add_master(&cdns->bus, &sconfig, 863 - pconfig, 1, dma->stream); 887 + pconfig, 1, dai_runtime->stream); 864 888 if (ret) 865 889 dev_err(cdns->dev, "add master to stream failed:%d\n", ret); 866 890 ··· 874 898 { 875 899 struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai); 876 900 struct sdw_intel *sdw = cdns_to_intel(cdns); 877 - struct sdw_cdns_dma_data *dma; 901 + struct sdw_cdns_dai_runtime *dai_runtime; 878 902 int ch, dir; 879 903 int ret = 0; 880 904 881 - dma = snd_soc_dai_get_dma_data(dai, substream); 882 - if (!dma) { 883 - dev_err(dai->dev, "failed to get dma data in %s\n", 905 + dai_runtime = cdns->dai_runtime_array[dai->id]; 906 + if (!dai_runtime) { 907 + dev_err(dai->dev, "failed to get dai runtime in %s\n", 884 908 __func__); 885 909 return -EIO; 886 910 } 887 911 888 - if (dma->suspended) { 889 - dma->suspended = false; 912 + if (dai_runtime->suspended) { 913 + dai_runtime->suspended = false; 890 914 891 915 /* 892 916 * .prepare() is called after system resume, where we ··· 897 921 */ 898 922 899 923 /* configure stream */ 900 - ch = params_channels(dma->hw_params); 924 + ch = params_channels(dai_runtime->hw_params); 901 925 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 902 926 dir = SDW_DATA_DIR_RX; 903 927 else 904 928 dir = SDW_DATA_DIR_TX; 905 929 906 - intel_pdi_shim_configure(sdw, dma->pdi); 907 - intel_pdi_alh_configure(sdw, dma->pdi); 908 - sdw_cdns_config_stream(cdns, ch, dir, dma->pdi); 930 + intel_pdi_shim_configure(sdw, dai_runtime->pdi); 931 + intel_pdi_alh_configure(sdw, dai_runtime->pdi); 932 + sdw_cdns_config_stream(cdns, ch, dir, dai_runtime->pdi); 909 933 910 934 /* Inform DSP about PDI stream number */ 911 935 ret = intel_params_stream(sdw, substream->stream, dai, 912 - dma->hw_params, 936 + dai_runtime->hw_params, 913 937 sdw->instance, 914 - dma->pdi->intel_alh_id); 938 + dai_runtime->pdi->intel_alh_id); 915 939 } 916 940 917 941 return ret; ··· 922 946 { 923 947 struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai); 924 948 struct sdw_intel *sdw = cdns_to_intel(cdns); 925 - struct sdw_cdns_dma_data *dma; 949 + struct sdw_cdns_dai_runtime *dai_runtime; 926 950 int ret; 927 951 928 - dma = snd_soc_dai_get_dma_data(dai, substream); 929 - if (!dma) 952 + dai_runtime = cdns->dai_runtime_array[dai->id]; 953 + if (!dai_runtime) 930 954 return -EIO; 931 955 932 956 /* ··· 935 959 * DEPREPARED for the first cpu-dai and to RELEASED for the last 936 960 * cpu-dai. 937 961 */ 938 - ret = sdw_stream_remove_master(&cdns->bus, dma->stream); 962 + ret = sdw_stream_remove_master(&cdns->bus, dai_runtime->stream); 939 963 if (ret < 0) { 940 964 dev_err(dai->dev, "remove master from stream %s failed: %d\n", 941 - dma->stream->name, ret); 965 + dai_runtime->stream->name, ret); 942 966 return ret; 943 967 } 944 968 ··· 948 972 return ret; 949 973 } 950 974 951 - dma->hw_params = NULL; 952 - dma->pdi = NULL; 975 + dai_runtime->hw_params = NULL; 976 + dai_runtime->pdi = NULL; 953 977 954 978 return 0; 955 979 } ··· 972 996 static void *intel_get_sdw_stream(struct snd_soc_dai *dai, 973 997 int direction) 974 998 { 975 - struct sdw_cdns_dma_data *dma; 999 + struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai); 1000 + struct sdw_cdns_dai_runtime *dai_runtime; 976 1001 977 - if (direction == SNDRV_PCM_STREAM_PLAYBACK) 978 - dma = dai->playback_dma_data; 979 - else 980 - dma = dai->capture_dma_data; 981 - 982 - if (!dma) 1002 + dai_runtime = cdns->dai_runtime_array[dai->id]; 1003 + if (!dai_runtime) 983 1004 return ERR_PTR(-EINVAL); 984 1005 985 - return dma->stream; 1006 + return dai_runtime->stream; 986 1007 } 987 1008 988 1009 static int intel_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) ··· 987 1014 struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai); 988 1015 struct sdw_intel *sdw = cdns_to_intel(cdns); 989 1016 struct sdw_intel_link_res *res = sdw->link_res; 990 - struct sdw_cdns_dma_data *dma; 1017 + struct sdw_cdns_dai_runtime *dai_runtime; 991 1018 int ret = 0; 992 1019 993 1020 /* ··· 998 1025 if (res->ops && res->ops->trigger) 999 1026 res->ops->trigger(dai, cmd, substream->stream); 1000 1027 1001 - dma = snd_soc_dai_get_dma_data(dai, substream); 1002 - if (!dma) { 1003 - dev_err(dai->dev, "failed to get dma data in %s\n", 1028 + dai_runtime = cdns->dai_runtime_array[dai->id]; 1029 + if (!dai_runtime) { 1030 + dev_err(dai->dev, "failed to get dai runtime in %s\n", 1004 1031 __func__); 1005 1032 return -EIO; 1006 1033 } ··· 1015 1042 * the .trigger callback is used to track the suspend case only. 1016 1043 */ 1017 1044 1018 - dma->suspended = true; 1045 + dai_runtime->suspended = true; 1019 1046 1020 1047 ret = intel_free_stream(sdw, substream->stream, dai, sdw->instance); 1021 1048 break; 1022 1049 1023 1050 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 1024 - dma->paused = true; 1051 + dai_runtime->paused = true; 1025 1052 break; 1026 1053 case SNDRV_PCM_TRIGGER_STOP: 1027 1054 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 1028 - dma->paused = false; 1055 + dai_runtime->paused = false; 1029 1056 break; 1030 1057 default: 1031 1058 break; ··· 1064 1091 for_each_component_dais(component, dai) { 1065 1092 struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai); 1066 1093 struct sdw_intel *sdw = cdns_to_intel(cdns); 1067 - struct sdw_cdns_dma_data *dma; 1068 - int stream; 1094 + struct sdw_cdns_dai_runtime *dai_runtime; 1069 1095 int ret; 1070 1096 1071 - dma = dai->playback_dma_data; 1072 - stream = SNDRV_PCM_STREAM_PLAYBACK; 1073 - if (!dma) { 1074 - dma = dai->capture_dma_data; 1075 - stream = SNDRV_PCM_STREAM_CAPTURE; 1076 - } 1097 + dai_runtime = cdns->dai_runtime_array[dai->id]; 1077 1098 1078 - if (!dma) 1099 + if (!dai_runtime) 1079 1100 continue; 1080 1101 1081 - if (dma->suspended) 1102 + if (dai_runtime->suspended) 1082 1103 continue; 1083 1104 1084 - if (dma->paused) { 1085 - dma->suspended = true; 1105 + if (dai_runtime->paused) { 1106 + dai_runtime->suspended = true; 1086 1107 1087 - ret = intel_free_stream(sdw, stream, dai, sdw->instance); 1108 + ret = intel_free_stream(sdw, dai_runtime->direction, dai, sdw->instance); 1088 1109 if (ret < 0) 1089 1110 return ret; 1090 1111 } ··· 1145 1178 1146 1179 static int intel_register_dai(struct sdw_intel *sdw) 1147 1180 { 1181 + struct sdw_cdns_dai_runtime **dai_runtime_array; 1148 1182 struct sdw_cdns_stream_config config; 1149 1183 struct sdw_cdns *cdns = &sdw->cdns; 1150 1184 struct sdw_cdns_streams *stream; ··· 1162 1194 1163 1195 /* DAIs are created based on total number of PDIs supported */ 1164 1196 num_dai = cdns->pcm.num_pdi; 1197 + 1198 + dai_runtime_array = devm_kcalloc(cdns->dev, num_dai, 1199 + sizeof(struct sdw_cdns_dai_runtime *), 1200 + GFP_KERNEL); 1201 + if (!dai_runtime_array) 1202 + return -ENOMEM; 1203 + cdns->dai_runtime_array = dai_runtime_array; 1165 1204 1166 1205 dais = devm_kcalloc(cdns->dev, num_dai, sizeof(*dais), GFP_KERNEL); 1167 1206 if (!dais) ··· 1398 1423 return 0; 1399 1424 } 1400 1425 1401 - static int sdw_master_read_intel_prop(struct sdw_bus *bus) 1402 - { 1403 - struct sdw_master_prop *prop = &bus->prop; 1404 - struct fwnode_handle *link; 1405 - char name[32]; 1406 - u32 quirk_mask; 1426 + const struct sdw_intel_hw_ops sdw_intel_cnl_hw_ops = { 1427 + .debugfs_init = intel_debugfs_init, 1428 + .debugfs_exit = intel_debugfs_exit, 1407 1429 1408 - /* Find master handle */ 1409 - snprintf(name, sizeof(name), 1410 - "mipi-sdw-link-%d-subproperties", bus->link_id); 1430 + .register_dai = intel_register_dai, 1411 1431 1412 - link = device_get_named_child_node(bus->dev, name); 1413 - if (!link) { 1414 - dev_err(bus->dev, "Master node %s not found\n", name); 1415 - return -EIO; 1416 - } 1432 + .check_clock_stop = intel_check_clock_stop, 1433 + .start_bus = intel_start_bus, 1434 + .start_bus_after_reset = intel_start_bus_after_reset, 1435 + .start_bus_after_clock_stop = intel_start_bus_after_clock_stop, 1436 + .stop_bus = intel_stop_bus, 1417 1437 1418 - fwnode_property_read_u32(link, 1419 - "intel-sdw-ip-clock", 1420 - &prop->mclk_freq); 1438 + .link_power_up = intel_link_power_up, 1439 + .link_power_down = intel_link_power_down, 1421 1440 1422 - /* the values reported by BIOS are the 2x clock, not the bus clock */ 1423 - prop->mclk_freq /= 2; 1441 + .shim_check_wake = intel_shim_check_wake, 1442 + .shim_wake = intel_shim_wake, 1424 1443 1425 - fwnode_property_read_u32(link, 1426 - "intel-quirk-mask", 1427 - &quirk_mask); 1428 - 1429 - if (quirk_mask & SDW_INTEL_QUIRK_MASK_BUS_DISABLE) 1430 - prop->hw_disabled = true; 1431 - 1432 - prop->quirks = SDW_MASTER_QUIRKS_CLEAR_INITIAL_CLASH | 1433 - SDW_MASTER_QUIRKS_CLEAR_INITIAL_PARITY; 1434 - 1435 - return 0; 1436 - } 1437 - 1438 - static int intel_prop_read(struct sdw_bus *bus) 1439 - { 1440 - /* Initialize with default handler to read all DisCo properties */ 1441 - sdw_master_read_prop(bus); 1442 - 1443 - /* read Intel-specific properties */ 1444 - sdw_master_read_intel_prop(bus); 1445 - 1446 - return 0; 1447 - } 1448 - 1449 - static struct sdw_master_ops sdw_intel_ops = { 1450 - .read_prop = intel_prop_read, 1451 - .override_adr = sdw_dmi_override_adr, 1452 - .xfer_msg = cdns_xfer_msg, 1453 - .xfer_msg_defer = cdns_xfer_msg_defer, 1454 - .reset_page_addr = cdns_reset_page_addr, 1455 - .set_bus_conf = cdns_bus_conf, 1456 1444 .pre_bank_switch = intel_pre_bank_switch, 1457 1445 .post_bank_switch = intel_post_bank_switch, 1458 - .read_ping_status = cdns_read_ping_status, 1459 1446 }; 1447 + EXPORT_SYMBOL_NS(sdw_intel_cnl_hw_ops, SOUNDWIRE_INTEL); 1460 1448 1461 - /* 1462 - * probe and init (aux_dev_id argument is required by function prototype but not used) 1463 - */ 1464 - static int intel_link_probe(struct auxiliary_device *auxdev, 1465 - const struct auxiliary_device_id *aux_dev_id) 1466 - 1467 - { 1468 - struct device *dev = &auxdev->dev; 1469 - struct sdw_intel_link_dev *ldev = auxiliary_dev_to_sdw_intel_link_dev(auxdev); 1470 - struct sdw_intel *sdw; 1471 - struct sdw_cdns *cdns; 1472 - struct sdw_bus *bus; 1473 - int ret; 1474 - 1475 - sdw = devm_kzalloc(dev, sizeof(*sdw), GFP_KERNEL); 1476 - if (!sdw) 1477 - return -ENOMEM; 1478 - 1479 - cdns = &sdw->cdns; 1480 - bus = &cdns->bus; 1481 - 1482 - sdw->instance = auxdev->id; 1483 - sdw->link_res = &ldev->link_res; 1484 - cdns->dev = dev; 1485 - cdns->registers = sdw->link_res->registers; 1486 - cdns->instance = sdw->instance; 1487 - cdns->msg_count = 0; 1488 - 1489 - bus->link_id = auxdev->id; 1490 - bus->dev_num_ida_min = INTEL_DEV_NUM_IDA_MIN; 1491 - bus->clk_stop_timeout = 1; 1492 - 1493 - sdw_cdns_probe(cdns); 1494 - 1495 - /* Set ops */ 1496 - bus->ops = &sdw_intel_ops; 1497 - 1498 - /* set driver data, accessed by snd_soc_dai_get_drvdata() */ 1499 - auxiliary_set_drvdata(auxdev, cdns); 1500 - 1501 - /* use generic bandwidth allocation algorithm */ 1502 - sdw->cdns.bus.compute_params = sdw_compute_params; 1503 - 1504 - /* avoid resuming from pm_runtime suspend if it's not required */ 1505 - dev_pm_set_driver_flags(dev, DPM_FLAG_SMART_SUSPEND); 1506 - 1507 - ret = sdw_bus_master_add(bus, dev, dev->fwnode); 1508 - if (ret) { 1509 - dev_err(dev, "sdw_bus_master_add fail: %d\n", ret); 1510 - return ret; 1511 - } 1512 - 1513 - if (bus->prop.hw_disabled) 1514 - dev_info(dev, 1515 - "SoundWire master %d is disabled, will be ignored\n", 1516 - bus->link_id); 1517 - /* 1518 - * Ignore BIOS err_threshold, it's a really bad idea when dealing 1519 - * with multiple hardware synchronized links 1520 - */ 1521 - bus->prop.err_threshold = 0; 1522 - 1523 - return 0; 1524 - } 1525 - 1526 - int intel_link_startup(struct auxiliary_device *auxdev) 1527 - { 1528 - struct device *dev = &auxdev->dev; 1529 - struct sdw_cdns *cdns = auxiliary_get_drvdata(auxdev); 1530 - struct sdw_intel *sdw = cdns_to_intel(cdns); 1531 - struct sdw_bus *bus = &cdns->bus; 1532 - int link_flags; 1533 - bool multi_link; 1534 - u32 clock_stop_quirks; 1535 - int ret; 1536 - 1537 - if (bus->prop.hw_disabled) { 1538 - dev_info(dev, 1539 - "SoundWire master %d is disabled, ignoring\n", 1540 - sdw->instance); 1541 - return 0; 1542 - } 1543 - 1544 - link_flags = md_flags >> (bus->link_id * 8); 1545 - multi_link = !(link_flags & SDW_INTEL_MASTER_DISABLE_MULTI_LINK); 1546 - if (!multi_link) { 1547 - dev_dbg(dev, "Multi-link is disabled\n"); 1548 - } else { 1549 - /* 1550 - * hardware-based synchronization is required regardless 1551 - * of the number of segments used by a stream: SSP-based 1552 - * synchronization is gated by gsync when the multi-master 1553 - * mode is set. 1554 - */ 1555 - bus->hw_sync_min_links = 1; 1556 - } 1557 - bus->multi_link = multi_link; 1558 - 1559 - /* Initialize shim, controller */ 1560 - ret = intel_link_power_up(sdw); 1561 - if (ret) 1562 - goto err_init; 1563 - 1564 - /* Register DAIs */ 1565 - ret = intel_register_dai(sdw); 1566 - if (ret) { 1567 - dev_err(dev, "DAI registration failed: %d\n", ret); 1568 - goto err_power_up; 1569 - } 1570 - 1571 - intel_debugfs_init(sdw); 1572 - 1573 - /* start bus */ 1574 - ret = intel_start_bus(sdw); 1575 - if (ret) { 1576 - dev_err(dev, "bus start failed: %d\n", ret); 1577 - goto err_power_up; 1578 - } 1579 - 1580 - /* Enable runtime PM */ 1581 - if (!(link_flags & SDW_INTEL_MASTER_DISABLE_PM_RUNTIME)) { 1582 - pm_runtime_set_autosuspend_delay(dev, 1583 - INTEL_MASTER_SUSPEND_DELAY_MS); 1584 - pm_runtime_use_autosuspend(dev); 1585 - pm_runtime_mark_last_busy(dev); 1586 - 1587 - pm_runtime_set_active(dev); 1588 - pm_runtime_enable(dev); 1589 - } 1590 - 1591 - clock_stop_quirks = sdw->link_res->clock_stop_quirks; 1592 - if (clock_stop_quirks & SDW_INTEL_CLK_STOP_NOT_ALLOWED) { 1593 - /* 1594 - * To keep the clock running we need to prevent 1595 - * pm_runtime suspend from happening by increasing the 1596 - * reference count. 1597 - * This quirk is specified by the parent PCI device in 1598 - * case of specific latency requirements. It will have 1599 - * no effect if pm_runtime is disabled by the user via 1600 - * a module parameter for testing purposes. 1601 - */ 1602 - pm_runtime_get_noresume(dev); 1603 - } 1604 - 1605 - /* 1606 - * The runtime PM status of Slave devices is "Unsupported" 1607 - * until they report as ATTACHED. If they don't, e.g. because 1608 - * there are no Slave devices populated or if the power-on is 1609 - * delayed or dependent on a power switch, the Master will 1610 - * remain active and prevent its parent from suspending. 1611 - * 1612 - * Conditionally force the pm_runtime core to re-evaluate the 1613 - * Master status in the absence of any Slave activity. A quirk 1614 - * is provided to e.g. deal with Slaves that may be powered on 1615 - * with a delay. A more complete solution would require the 1616 - * definition of Master properties. 1617 - */ 1618 - if (!(link_flags & SDW_INTEL_MASTER_DISABLE_PM_RUNTIME_IDLE)) 1619 - pm_runtime_idle(dev); 1620 - 1621 - sdw->startup_done = true; 1622 - return 0; 1623 - 1624 - err_power_up: 1625 - intel_link_power_down(sdw); 1626 - err_init: 1627 - return ret; 1628 - } 1629 - 1630 - static void intel_link_remove(struct auxiliary_device *auxdev) 1631 - { 1632 - struct sdw_cdns *cdns = auxiliary_get_drvdata(auxdev); 1633 - struct sdw_intel *sdw = cdns_to_intel(cdns); 1634 - struct sdw_bus *bus = &cdns->bus; 1635 - 1636 - /* 1637 - * Since pm_runtime is already disabled, we don't decrease 1638 - * the refcount when the clock_stop_quirk is 1639 - * SDW_INTEL_CLK_STOP_NOT_ALLOWED 1640 - */ 1641 - if (!bus->prop.hw_disabled) { 1642 - intel_debugfs_exit(sdw); 1643 - sdw_cdns_enable_interrupt(cdns, false); 1644 - } 1645 - sdw_bus_master_delete(bus); 1646 - } 1647 - 1648 - int intel_link_process_wakeen_event(struct auxiliary_device *auxdev) 1649 - { 1650 - struct device *dev = &auxdev->dev; 1651 - struct sdw_intel *sdw; 1652 - struct sdw_bus *bus; 1653 - 1654 - sdw = auxiliary_get_drvdata(auxdev); 1655 - bus = &sdw->cdns.bus; 1656 - 1657 - if (bus->prop.hw_disabled || !sdw->startup_done) { 1658 - dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n", 1659 - bus->link_id); 1660 - return 0; 1661 - } 1662 - 1663 - if (!intel_shim_check_wake(sdw)) 1664 - return 0; 1665 - 1666 - /* disable WAKEEN interrupt ASAP to prevent interrupt flood */ 1667 - intel_shim_wake(sdw, false); 1668 - 1669 - /* 1670 - * resume the Master, which will generate a bus reset and result in 1671 - * Slaves re-attaching and be re-enumerated. The SoundWire physical 1672 - * device which generated the wake will trigger an interrupt, which 1673 - * will in turn cause the corresponding Linux Slave device to be 1674 - * resumed and the Slave codec driver to check the status. 1675 - */ 1676 - pm_request_resume(dev); 1677 - 1678 - return 0; 1679 - } 1680 - 1681 - /* 1682 - * PM calls 1683 - */ 1684 - 1685 - static int intel_resume_child_device(struct device *dev, void *data) 1686 - { 1687 - int ret; 1688 - struct sdw_slave *slave = dev_to_sdw_dev(dev); 1689 - 1690 - if (!slave->probed) { 1691 - dev_dbg(dev, "skipping device, no probed driver\n"); 1692 - return 0; 1693 - } 1694 - if (!slave->dev_num_sticky) { 1695 - dev_dbg(dev, "skipping device, never detected on bus\n"); 1696 - return 0; 1697 - } 1698 - 1699 - ret = pm_request_resume(dev); 1700 - if (ret < 0) 1701 - dev_err(dev, "%s: pm_request_resume failed: %d\n", __func__, ret); 1702 - 1703 - return ret; 1704 - } 1705 - 1706 - static int __maybe_unused intel_pm_prepare(struct device *dev) 1707 - { 1708 - struct sdw_cdns *cdns = dev_get_drvdata(dev); 1709 - struct sdw_intel *sdw = cdns_to_intel(cdns); 1710 - struct sdw_bus *bus = &cdns->bus; 1711 - u32 clock_stop_quirks; 1712 - int ret; 1713 - 1714 - if (bus->prop.hw_disabled || !sdw->startup_done) { 1715 - dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n", 1716 - bus->link_id); 1717 - return 0; 1718 - } 1719 - 1720 - clock_stop_quirks = sdw->link_res->clock_stop_quirks; 1721 - 1722 - if (pm_runtime_suspended(dev) && 1723 - pm_runtime_suspended(dev->parent) && 1724 - ((clock_stop_quirks & SDW_INTEL_CLK_STOP_BUS_RESET) || 1725 - !clock_stop_quirks)) { 1726 - /* 1727 - * if we've enabled clock stop, and the parent is suspended, the SHIM registers 1728 - * are not accessible and the shim wake cannot be disabled. 1729 - * The only solution is to resume the entire bus to full power 1730 - */ 1731 - 1732 - /* 1733 - * If any operation in this block fails, we keep going since we don't want 1734 - * to prevent system suspend from happening and errors should be recoverable 1735 - * on resume. 1736 - */ 1737 - 1738 - /* 1739 - * first resume the device for this link. This will also by construction 1740 - * resume the PCI parent device. 1741 - */ 1742 - ret = pm_request_resume(dev); 1743 - if (ret < 0) { 1744 - dev_err(dev, "%s: pm_request_resume failed: %d\n", __func__, ret); 1745 - return 0; 1746 - } 1747 - 1748 - /* 1749 - * Continue resuming the entire bus (parent + child devices) to exit 1750 - * the clock stop mode. If there are no devices connected on this link 1751 - * this is a no-op. 1752 - * The resume to full power could have been implemented with a .prepare 1753 - * step in SoundWire codec drivers. This would however require a lot 1754 - * of code to handle an Intel-specific corner case. It is simpler in 1755 - * practice to add a loop at the link level. 1756 - */ 1757 - ret = device_for_each_child(bus->dev, NULL, intel_resume_child_device); 1758 - 1759 - if (ret < 0) 1760 - dev_err(dev, "%s: intel_resume_child_device failed: %d\n", __func__, ret); 1761 - } 1762 - 1763 - return 0; 1764 - } 1765 - 1766 - static int __maybe_unused intel_suspend(struct device *dev) 1767 - { 1768 - struct sdw_cdns *cdns = dev_get_drvdata(dev); 1769 - struct sdw_intel *sdw = cdns_to_intel(cdns); 1770 - struct sdw_bus *bus = &cdns->bus; 1771 - u32 clock_stop_quirks; 1772 - int ret; 1773 - 1774 - if (bus->prop.hw_disabled || !sdw->startup_done) { 1775 - dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n", 1776 - bus->link_id); 1777 - return 0; 1778 - } 1779 - 1780 - if (pm_runtime_suspended(dev)) { 1781 - dev_dbg(dev, "pm_runtime status: suspended\n"); 1782 - 1783 - clock_stop_quirks = sdw->link_res->clock_stop_quirks; 1784 - 1785 - if ((clock_stop_quirks & SDW_INTEL_CLK_STOP_BUS_RESET) || 1786 - !clock_stop_quirks) { 1787 - 1788 - if (pm_runtime_suspended(dev->parent)) { 1789 - /* 1790 - * paranoia check: this should not happen with the .prepare 1791 - * resume to full power 1792 - */ 1793 - dev_err(dev, "%s: invalid config: parent is suspended\n", __func__); 1794 - } else { 1795 - intel_shim_wake(sdw, false); 1796 - } 1797 - } 1798 - 1799 - return 0; 1800 - } 1801 - 1802 - ret = intel_stop_bus(sdw, false); 1803 - if (ret < 0) { 1804 - dev_err(dev, "%s: cannot stop bus: %d\n", __func__, ret); 1805 - return ret; 1806 - } 1807 - 1808 - return 0; 1809 - } 1810 - 1811 - static int __maybe_unused intel_suspend_runtime(struct device *dev) 1812 - { 1813 - struct sdw_cdns *cdns = dev_get_drvdata(dev); 1814 - struct sdw_intel *sdw = cdns_to_intel(cdns); 1815 - struct sdw_bus *bus = &cdns->bus; 1816 - u32 clock_stop_quirks; 1817 - int ret; 1818 - 1819 - if (bus->prop.hw_disabled || !sdw->startup_done) { 1820 - dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n", 1821 - bus->link_id); 1822 - return 0; 1823 - } 1824 - 1825 - clock_stop_quirks = sdw->link_res->clock_stop_quirks; 1826 - 1827 - if (clock_stop_quirks & SDW_INTEL_CLK_STOP_TEARDOWN) { 1828 - ret = intel_stop_bus(sdw, false); 1829 - if (ret < 0) { 1830 - dev_err(dev, "%s: cannot stop bus during teardown: %d\n", 1831 - __func__, ret); 1832 - return ret; 1833 - } 1834 - } else if (clock_stop_quirks & SDW_INTEL_CLK_STOP_BUS_RESET || !clock_stop_quirks) { 1835 - ret = intel_stop_bus(sdw, true); 1836 - if (ret < 0) { 1837 - dev_err(dev, "%s: cannot stop bus during clock_stop: %d\n", 1838 - __func__, ret); 1839 - return ret; 1840 - } 1841 - } else { 1842 - dev_err(dev, "%s clock_stop_quirks %x unsupported\n", 1843 - __func__, clock_stop_quirks); 1844 - ret = -EINVAL; 1845 - } 1846 - 1847 - return ret; 1848 - } 1849 - 1850 - static int __maybe_unused intel_resume(struct device *dev) 1851 - { 1852 - struct sdw_cdns *cdns = dev_get_drvdata(dev); 1853 - struct sdw_intel *sdw = cdns_to_intel(cdns); 1854 - struct sdw_bus *bus = &cdns->bus; 1855 - int link_flags; 1856 - int ret; 1857 - 1858 - if (bus->prop.hw_disabled || !sdw->startup_done) { 1859 - dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n", 1860 - bus->link_id); 1861 - return 0; 1862 - } 1863 - 1864 - link_flags = md_flags >> (bus->link_id * 8); 1865 - 1866 - if (pm_runtime_suspended(dev)) { 1867 - dev_dbg(dev, "pm_runtime status was suspended, forcing active\n"); 1868 - 1869 - /* follow required sequence from runtime_pm.rst */ 1870 - pm_runtime_disable(dev); 1871 - pm_runtime_set_active(dev); 1872 - pm_runtime_mark_last_busy(dev); 1873 - pm_runtime_enable(dev); 1874 - 1875 - link_flags = md_flags >> (bus->link_id * 8); 1876 - 1877 - if (!(link_flags & SDW_INTEL_MASTER_DISABLE_PM_RUNTIME_IDLE)) 1878 - pm_runtime_idle(dev); 1879 - } 1880 - 1881 - ret = intel_link_power_up(sdw); 1882 - if (ret) { 1883 - dev_err(dev, "%s failed: %d\n", __func__, ret); 1884 - return ret; 1885 - } 1886 - 1887 - /* 1888 - * make sure all Slaves are tagged as UNATTACHED and provide 1889 - * reason for reinitialization 1890 - */ 1891 - sdw_clear_slave_status(bus, SDW_UNATTACH_REQUEST_MASTER_RESET); 1892 - 1893 - ret = intel_start_bus(sdw); 1894 - if (ret < 0) { 1895 - dev_err(dev, "cannot start bus during resume\n"); 1896 - intel_link_power_down(sdw); 1897 - return ret; 1898 - } 1899 - 1900 - /* 1901 - * after system resume, the pm_runtime suspend() may kick in 1902 - * during the enumeration, before any children device force the 1903 - * master device to remain active. Using pm_runtime_get() 1904 - * routines is not really possible, since it'd prevent the 1905 - * master from suspending. 1906 - * A reasonable compromise is to update the pm_runtime 1907 - * counters and delay the pm_runtime suspend by several 1908 - * seconds, by when all enumeration should be complete. 1909 - */ 1910 - pm_runtime_mark_last_busy(dev); 1911 - 1912 - return 0; 1913 - } 1914 - 1915 - static int __maybe_unused intel_resume_runtime(struct device *dev) 1916 - { 1917 - struct sdw_cdns *cdns = dev_get_drvdata(dev); 1918 - struct sdw_intel *sdw = cdns_to_intel(cdns); 1919 - struct sdw_bus *bus = &cdns->bus; 1920 - u32 clock_stop_quirks; 1921 - int ret; 1922 - 1923 - if (bus->prop.hw_disabled || !sdw->startup_done) { 1924 - dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n", 1925 - bus->link_id); 1926 - return 0; 1927 - } 1928 - 1929 - /* unconditionally disable WAKEEN interrupt */ 1930 - intel_shim_wake(sdw, false); 1931 - 1932 - clock_stop_quirks = sdw->link_res->clock_stop_quirks; 1933 - 1934 - if (clock_stop_quirks & SDW_INTEL_CLK_STOP_TEARDOWN) { 1935 - ret = intel_link_power_up(sdw); 1936 - if (ret) { 1937 - dev_err(dev, "%s: power_up failed after teardown: %d\n", __func__, ret); 1938 - return ret; 1939 - } 1940 - 1941 - /* 1942 - * make sure all Slaves are tagged as UNATTACHED and provide 1943 - * reason for reinitialization 1944 - */ 1945 - sdw_clear_slave_status(bus, SDW_UNATTACH_REQUEST_MASTER_RESET); 1946 - 1947 - ret = intel_start_bus(sdw); 1948 - if (ret < 0) { 1949 - dev_err(dev, "%s: cannot start bus after teardown: %d\n", __func__, ret); 1950 - intel_link_power_down(sdw); 1951 - return ret; 1952 - } 1953 - 1954 - 1955 - } else if (clock_stop_quirks & SDW_INTEL_CLK_STOP_BUS_RESET) { 1956 - ret = intel_link_power_up(sdw); 1957 - if (ret) { 1958 - dev_err(dev, "%s: power_up failed after bus reset: %d\n", __func__, ret); 1959 - return ret; 1960 - } 1961 - 1962 - ret = intel_start_bus_after_reset(sdw); 1963 - if (ret < 0) { 1964 - dev_err(dev, "%s: cannot start bus after reset: %d\n", __func__, ret); 1965 - intel_link_power_down(sdw); 1966 - return ret; 1967 - } 1968 - } else if (!clock_stop_quirks) { 1969 - 1970 - intel_check_clock_stop(sdw); 1971 - 1972 - ret = intel_link_power_up(sdw); 1973 - if (ret) { 1974 - dev_err(dev, "%s: power_up failed: %d\n", __func__, ret); 1975 - return ret; 1976 - } 1977 - 1978 - ret = intel_start_bus_after_clock_stop(sdw); 1979 - if (ret < 0) { 1980 - dev_err(dev, "%s: cannot start bus after clock stop: %d\n", __func__, ret); 1981 - intel_link_power_down(sdw); 1982 - return ret; 1983 - } 1984 - } else { 1985 - dev_err(dev, "%s: clock_stop_quirks %x unsupported\n", 1986 - __func__, clock_stop_quirks); 1987 - ret = -EINVAL; 1988 - } 1989 - 1990 - return ret; 1991 - } 1992 - 1993 - static const struct dev_pm_ops intel_pm = { 1994 - .prepare = intel_pm_prepare, 1995 - SET_SYSTEM_SLEEP_PM_OPS(intel_suspend, intel_resume) 1996 - SET_RUNTIME_PM_OPS(intel_suspend_runtime, intel_resume_runtime, NULL) 1997 - }; 1998 - 1999 - static const struct auxiliary_device_id intel_link_id_table[] = { 2000 - { .name = "soundwire_intel.link" }, 2001 - {}, 2002 - }; 2003 - MODULE_DEVICE_TABLE(auxiliary, intel_link_id_table); 2004 - 2005 - static struct auxiliary_driver sdw_intel_drv = { 2006 - .probe = intel_link_probe, 2007 - .remove = intel_link_remove, 2008 - .driver = { 2009 - /* auxiliary_driver_register() sets .name to be the modname */ 2010 - .pm = &intel_pm, 2011 - }, 2012 - .id_table = intel_link_id_table 2013 - }; 2014 - module_auxiliary_driver(sdw_intel_drv); 2015 - 2016 - MODULE_LICENSE("Dual BSD/GPL"); 2017 - MODULE_DESCRIPTION("Intel Soundwire Link Driver");
+88 -8
drivers/soundwire/intel.h
··· 7 7 /** 8 8 * struct sdw_intel_link_res - Soundwire Intel link resource structure, 9 9 * typically populated by the controller driver. 10 + * @hw_ops: platform-specific ops 10 11 * @mmio_base: mmio base of SoundWire registers 11 12 * @registers: Link IO registers base 12 13 * @shim: Audio shim pointer ··· 23 22 * @list: used to walk-through all masters exposed by the same controller 24 23 */ 25 24 struct sdw_intel_link_res { 25 + const struct sdw_intel_hw_ops *hw_ops; 26 + 26 27 void __iomem *mmio_base; /* not strictly needed, useful for debug */ 27 28 void __iomem *registers; 28 29 void __iomem *shim; ··· 50 47 #endif 51 48 }; 52 49 53 - int intel_link_startup(struct auxiliary_device *auxdev); 54 - int intel_link_process_wakeen_event(struct auxiliary_device *auxdev); 50 + #define cdns_to_intel(_cdns) container_of(_cdns, struct sdw_intel, cdns) 55 51 56 - struct sdw_intel_link_dev { 57 - struct auxiliary_device auxdev; 58 - struct sdw_intel_link_res link_res; 59 - }; 52 + #define INTEL_MASTER_RESET_ITERATIONS 10 60 53 61 - #define auxiliary_dev_to_sdw_intel_link_dev(auxiliary_dev) \ 62 - container_of(auxiliary_dev, struct sdw_intel_link_dev, auxdev) 54 + #define SDW_INTEL_CHECK_OPS(sdw, cb) ((sdw) && (sdw)->link_res && (sdw)->link_res->hw_ops && \ 55 + (sdw)->link_res->hw_ops->cb) 56 + #define SDW_INTEL_OPS(sdw, cb) ((sdw)->link_res->hw_ops->cb) 57 + 58 + static inline void sdw_intel_debugfs_init(struct sdw_intel *sdw) 59 + { 60 + if (SDW_INTEL_CHECK_OPS(sdw, debugfs_init)) 61 + SDW_INTEL_OPS(sdw, debugfs_init)(sdw); 62 + } 63 + 64 + static inline void sdw_intel_debugfs_exit(struct sdw_intel *sdw) 65 + { 66 + if (SDW_INTEL_CHECK_OPS(sdw, debugfs_exit)) 67 + SDW_INTEL_OPS(sdw, debugfs_exit)(sdw); 68 + } 69 + 70 + static inline int sdw_intel_register_dai(struct sdw_intel *sdw) 71 + { 72 + if (SDW_INTEL_CHECK_OPS(sdw, register_dai)) 73 + return SDW_INTEL_OPS(sdw, register_dai)(sdw); 74 + return -ENOTSUPP; 75 + } 76 + 77 + static inline void sdw_intel_check_clock_stop(struct sdw_intel *sdw) 78 + { 79 + if (SDW_INTEL_CHECK_OPS(sdw, check_clock_stop)) 80 + SDW_INTEL_OPS(sdw, check_clock_stop)(sdw); 81 + } 82 + 83 + static inline int sdw_intel_start_bus(struct sdw_intel *sdw) 84 + { 85 + if (SDW_INTEL_CHECK_OPS(sdw, start_bus)) 86 + return SDW_INTEL_OPS(sdw, start_bus)(sdw); 87 + return -ENOTSUPP; 88 + } 89 + 90 + static inline int sdw_intel_start_bus_after_reset(struct sdw_intel *sdw) 91 + { 92 + if (SDW_INTEL_CHECK_OPS(sdw, start_bus_after_reset)) 93 + return SDW_INTEL_OPS(sdw, start_bus_after_reset)(sdw); 94 + return -ENOTSUPP; 95 + } 96 + 97 + static inline int sdw_intel_start_bus_after_clock_stop(struct sdw_intel *sdw) 98 + { 99 + if (SDW_INTEL_CHECK_OPS(sdw, start_bus_after_clock_stop)) 100 + return SDW_INTEL_OPS(sdw, start_bus_after_clock_stop)(sdw); 101 + return -ENOTSUPP; 102 + } 103 + 104 + static inline int sdw_intel_stop_bus(struct sdw_intel *sdw, bool clock_stop) 105 + { 106 + if (SDW_INTEL_CHECK_OPS(sdw, stop_bus)) 107 + return SDW_INTEL_OPS(sdw, stop_bus)(sdw, clock_stop); 108 + return -ENOTSUPP; 109 + } 110 + 111 + static inline int sdw_intel_link_power_up(struct sdw_intel *sdw) 112 + { 113 + if (SDW_INTEL_CHECK_OPS(sdw, link_power_up)) 114 + return SDW_INTEL_OPS(sdw, link_power_up)(sdw); 115 + return -ENOTSUPP; 116 + } 117 + 118 + static inline int sdw_intel_link_power_down(struct sdw_intel *sdw) 119 + { 120 + if (SDW_INTEL_CHECK_OPS(sdw, link_power_down)) 121 + return SDW_INTEL_OPS(sdw, link_power_down)(sdw); 122 + return -ENOTSUPP; 123 + } 124 + 125 + static inline int sdw_intel_shim_check_wake(struct sdw_intel *sdw) 126 + { 127 + if (SDW_INTEL_CHECK_OPS(sdw, shim_check_wake)) 128 + return SDW_INTEL_OPS(sdw, shim_check_wake)(sdw); 129 + return -ENOTSUPP; 130 + } 131 + 132 + static inline void sdw_intel_shim_wake(struct sdw_intel *sdw, bool wake_enable) 133 + { 134 + if (SDW_INTEL_CHECK_OPS(sdw, shim_wake)) 135 + SDW_INTEL_OPS(sdw, shim_wake)(sdw, wake_enable); 136 + } 63 137 64 138 #endif /* __SDW_INTEL_LOCAL_H */
+678
drivers/soundwire/intel_auxdevice.c
··· 1 + // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 2 + // Copyright(c) 2015-22 Intel Corporation. 3 + 4 + /* 5 + * Soundwire Intel Manager Driver 6 + */ 7 + 8 + #include <linux/acpi.h> 9 + #include <linux/debugfs.h> 10 + #include <linux/delay.h> 11 + #include <linux/module.h> 12 + #include <linux/interrupt.h> 13 + #include <linux/io.h> 14 + #include <linux/auxiliary_bus.h> 15 + #include <sound/pcm_params.h> 16 + #include <linux/pm_runtime.h> 17 + #include <sound/soc.h> 18 + #include <linux/soundwire/sdw_registers.h> 19 + #include <linux/soundwire/sdw.h> 20 + #include <linux/soundwire/sdw_intel.h> 21 + #include "cadence_master.h" 22 + #include "bus.h" 23 + #include "intel.h" 24 + #include "intel_auxdevice.h" 25 + 26 + /* IDA min selected to avoid conflicts with HDaudio/iDISP SDI values */ 27 + #define INTEL_DEV_NUM_IDA_MIN 4 28 + 29 + #define INTEL_MASTER_SUSPEND_DELAY_MS 3000 30 + 31 + /* 32 + * debug/config flags for the Intel SoundWire Master. 33 + * 34 + * Since we may have multiple masters active, we can have up to 8 35 + * flags reused in each byte, with master0 using the ls-byte, etc. 36 + */ 37 + 38 + #define SDW_INTEL_MASTER_DISABLE_PM_RUNTIME BIT(0) 39 + #define SDW_INTEL_MASTER_DISABLE_CLOCK_STOP BIT(1) 40 + #define SDW_INTEL_MASTER_DISABLE_PM_RUNTIME_IDLE BIT(2) 41 + #define SDW_INTEL_MASTER_DISABLE_MULTI_LINK BIT(3) 42 + 43 + static int md_flags; 44 + module_param_named(sdw_md_flags, md_flags, int, 0444); 45 + MODULE_PARM_DESC(sdw_md_flags, "SoundWire Intel Master device flags (0x0 all off)"); 46 + 47 + static int generic_pre_bank_switch(struct sdw_bus *bus) 48 + { 49 + struct sdw_cdns *cdns = bus_to_cdns(bus); 50 + struct sdw_intel *sdw = cdns_to_intel(cdns); 51 + 52 + return sdw->link_res->hw_ops->pre_bank_switch(sdw); 53 + } 54 + 55 + static int generic_post_bank_switch(struct sdw_bus *bus) 56 + { 57 + struct sdw_cdns *cdns = bus_to_cdns(bus); 58 + struct sdw_intel *sdw = cdns_to_intel(cdns); 59 + 60 + return sdw->link_res->hw_ops->post_bank_switch(sdw); 61 + } 62 + 63 + static int sdw_master_read_intel_prop(struct sdw_bus *bus) 64 + { 65 + struct sdw_master_prop *prop = &bus->prop; 66 + struct fwnode_handle *link; 67 + char name[32]; 68 + u32 quirk_mask; 69 + 70 + /* Find master handle */ 71 + snprintf(name, sizeof(name), 72 + "mipi-sdw-link-%d-subproperties", bus->link_id); 73 + 74 + link = device_get_named_child_node(bus->dev, name); 75 + if (!link) { 76 + dev_err(bus->dev, "Master node %s not found\n", name); 77 + return -EIO; 78 + } 79 + 80 + fwnode_property_read_u32(link, 81 + "intel-sdw-ip-clock", 82 + &prop->mclk_freq); 83 + 84 + /* the values reported by BIOS are the 2x clock, not the bus clock */ 85 + prop->mclk_freq /= 2; 86 + 87 + fwnode_property_read_u32(link, 88 + "intel-quirk-mask", 89 + &quirk_mask); 90 + 91 + if (quirk_mask & SDW_INTEL_QUIRK_MASK_BUS_DISABLE) 92 + prop->hw_disabled = true; 93 + 94 + prop->quirks = SDW_MASTER_QUIRKS_CLEAR_INITIAL_CLASH | 95 + SDW_MASTER_QUIRKS_CLEAR_INITIAL_PARITY; 96 + 97 + return 0; 98 + } 99 + 100 + static int intel_prop_read(struct sdw_bus *bus) 101 + { 102 + /* Initialize with default handler to read all DisCo properties */ 103 + sdw_master_read_prop(bus); 104 + 105 + /* read Intel-specific properties */ 106 + sdw_master_read_intel_prop(bus); 107 + 108 + return 0; 109 + } 110 + 111 + static struct sdw_master_ops sdw_intel_ops = { 112 + .read_prop = intel_prop_read, 113 + .override_adr = sdw_dmi_override_adr, 114 + .xfer_msg = cdns_xfer_msg, 115 + .xfer_msg_defer = cdns_xfer_msg_defer, 116 + .reset_page_addr = cdns_reset_page_addr, 117 + .set_bus_conf = cdns_bus_conf, 118 + .pre_bank_switch = generic_pre_bank_switch, 119 + .post_bank_switch = generic_post_bank_switch, 120 + .read_ping_status = cdns_read_ping_status, 121 + }; 122 + 123 + /* 124 + * probe and init (aux_dev_id argument is required by function prototype but not used) 125 + */ 126 + static int intel_link_probe(struct auxiliary_device *auxdev, 127 + const struct auxiliary_device_id *aux_dev_id) 128 + 129 + { 130 + struct device *dev = &auxdev->dev; 131 + struct sdw_intel_link_dev *ldev = auxiliary_dev_to_sdw_intel_link_dev(auxdev); 132 + struct sdw_intel *sdw; 133 + struct sdw_cdns *cdns; 134 + struct sdw_bus *bus; 135 + int ret; 136 + 137 + sdw = devm_kzalloc(dev, sizeof(*sdw), GFP_KERNEL); 138 + if (!sdw) 139 + return -ENOMEM; 140 + 141 + cdns = &sdw->cdns; 142 + bus = &cdns->bus; 143 + 144 + sdw->instance = auxdev->id; 145 + sdw->link_res = &ldev->link_res; 146 + cdns->dev = dev; 147 + cdns->registers = sdw->link_res->registers; 148 + cdns->instance = sdw->instance; 149 + cdns->msg_count = 0; 150 + 151 + bus->link_id = auxdev->id; 152 + bus->dev_num_ida_min = INTEL_DEV_NUM_IDA_MIN; 153 + bus->clk_stop_timeout = 1; 154 + 155 + sdw_cdns_probe(cdns); 156 + 157 + /* Set ops */ 158 + bus->ops = &sdw_intel_ops; 159 + 160 + /* set driver data, accessed by snd_soc_dai_get_drvdata() */ 161 + auxiliary_set_drvdata(auxdev, cdns); 162 + 163 + /* use generic bandwidth allocation algorithm */ 164 + sdw->cdns.bus.compute_params = sdw_compute_params; 165 + 166 + /* avoid resuming from pm_runtime suspend if it's not required */ 167 + dev_pm_set_driver_flags(dev, DPM_FLAG_SMART_SUSPEND); 168 + 169 + ret = sdw_bus_master_add(bus, dev, dev->fwnode); 170 + if (ret) { 171 + dev_err(dev, "sdw_bus_master_add fail: %d\n", ret); 172 + return ret; 173 + } 174 + 175 + if (bus->prop.hw_disabled) 176 + dev_info(dev, 177 + "SoundWire master %d is disabled, will be ignored\n", 178 + bus->link_id); 179 + /* 180 + * Ignore BIOS err_threshold, it's a really bad idea when dealing 181 + * with multiple hardware synchronized links 182 + */ 183 + bus->prop.err_threshold = 0; 184 + 185 + return 0; 186 + } 187 + 188 + int intel_link_startup(struct auxiliary_device *auxdev) 189 + { 190 + struct device *dev = &auxdev->dev; 191 + struct sdw_cdns *cdns = auxiliary_get_drvdata(auxdev); 192 + struct sdw_intel *sdw = cdns_to_intel(cdns); 193 + struct sdw_bus *bus = &cdns->bus; 194 + int link_flags; 195 + bool multi_link; 196 + u32 clock_stop_quirks; 197 + int ret; 198 + 199 + if (bus->prop.hw_disabled) { 200 + dev_info(dev, 201 + "SoundWire master %d is disabled, ignoring\n", 202 + sdw->instance); 203 + return 0; 204 + } 205 + 206 + link_flags = md_flags >> (bus->link_id * 8); 207 + multi_link = !(link_flags & SDW_INTEL_MASTER_DISABLE_MULTI_LINK); 208 + if (!multi_link) { 209 + dev_dbg(dev, "Multi-link is disabled\n"); 210 + } else { 211 + /* 212 + * hardware-based synchronization is required regardless 213 + * of the number of segments used by a stream: SSP-based 214 + * synchronization is gated by gsync when the multi-master 215 + * mode is set. 216 + */ 217 + bus->hw_sync_min_links = 1; 218 + } 219 + bus->multi_link = multi_link; 220 + 221 + /* Initialize shim, controller */ 222 + ret = sdw_intel_link_power_up(sdw); 223 + if (ret) 224 + goto err_init; 225 + 226 + /* Register DAIs */ 227 + ret = sdw_intel_register_dai(sdw); 228 + if (ret) { 229 + dev_err(dev, "DAI registration failed: %d\n", ret); 230 + goto err_power_up; 231 + } 232 + 233 + sdw_intel_debugfs_init(sdw); 234 + 235 + /* start bus */ 236 + ret = sdw_intel_start_bus(sdw); 237 + if (ret) { 238 + dev_err(dev, "bus start failed: %d\n", ret); 239 + goto err_power_up; 240 + } 241 + 242 + /* Enable runtime PM */ 243 + if (!(link_flags & SDW_INTEL_MASTER_DISABLE_PM_RUNTIME)) { 244 + pm_runtime_set_autosuspend_delay(dev, 245 + INTEL_MASTER_SUSPEND_DELAY_MS); 246 + pm_runtime_use_autosuspend(dev); 247 + pm_runtime_mark_last_busy(dev); 248 + 249 + pm_runtime_set_active(dev); 250 + pm_runtime_enable(dev); 251 + } 252 + 253 + clock_stop_quirks = sdw->link_res->clock_stop_quirks; 254 + if (clock_stop_quirks & SDW_INTEL_CLK_STOP_NOT_ALLOWED) { 255 + /* 256 + * To keep the clock running we need to prevent 257 + * pm_runtime suspend from happening by increasing the 258 + * reference count. 259 + * This quirk is specified by the parent PCI device in 260 + * case of specific latency requirements. It will have 261 + * no effect if pm_runtime is disabled by the user via 262 + * a module parameter for testing purposes. 263 + */ 264 + pm_runtime_get_noresume(dev); 265 + } 266 + 267 + /* 268 + * The runtime PM status of Slave devices is "Unsupported" 269 + * until they report as ATTACHED. If they don't, e.g. because 270 + * there are no Slave devices populated or if the power-on is 271 + * delayed or dependent on a power switch, the Master will 272 + * remain active and prevent its parent from suspending. 273 + * 274 + * Conditionally force the pm_runtime core to re-evaluate the 275 + * Master status in the absence of any Slave activity. A quirk 276 + * is provided to e.g. deal with Slaves that may be powered on 277 + * with a delay. A more complete solution would require the 278 + * definition of Master properties. 279 + */ 280 + if (!(link_flags & SDW_INTEL_MASTER_DISABLE_PM_RUNTIME_IDLE)) 281 + pm_runtime_idle(dev); 282 + 283 + sdw->startup_done = true; 284 + return 0; 285 + 286 + err_power_up: 287 + sdw_intel_link_power_down(sdw); 288 + err_init: 289 + return ret; 290 + } 291 + 292 + static void intel_link_remove(struct auxiliary_device *auxdev) 293 + { 294 + struct sdw_cdns *cdns = auxiliary_get_drvdata(auxdev); 295 + struct sdw_intel *sdw = cdns_to_intel(cdns); 296 + struct sdw_bus *bus = &cdns->bus; 297 + 298 + /* 299 + * Since pm_runtime is already disabled, we don't decrease 300 + * the refcount when the clock_stop_quirk is 301 + * SDW_INTEL_CLK_STOP_NOT_ALLOWED 302 + */ 303 + if (!bus->prop.hw_disabled) { 304 + sdw_intel_debugfs_exit(sdw); 305 + sdw_cdns_enable_interrupt(cdns, false); 306 + } 307 + sdw_bus_master_delete(bus); 308 + } 309 + 310 + int intel_link_process_wakeen_event(struct auxiliary_device *auxdev) 311 + { 312 + struct device *dev = &auxdev->dev; 313 + struct sdw_intel *sdw; 314 + struct sdw_bus *bus; 315 + 316 + sdw = auxiliary_get_drvdata(auxdev); 317 + bus = &sdw->cdns.bus; 318 + 319 + if (bus->prop.hw_disabled || !sdw->startup_done) { 320 + dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n", 321 + bus->link_id); 322 + return 0; 323 + } 324 + 325 + if (!sdw_intel_shim_check_wake(sdw)) 326 + return 0; 327 + 328 + /* disable WAKEEN interrupt ASAP to prevent interrupt flood */ 329 + sdw_intel_shim_wake(sdw, false); 330 + 331 + /* 332 + * resume the Master, which will generate a bus reset and result in 333 + * Slaves re-attaching and be re-enumerated. The SoundWire physical 334 + * device which generated the wake will trigger an interrupt, which 335 + * will in turn cause the corresponding Linux Slave device to be 336 + * resumed and the Slave codec driver to check the status. 337 + */ 338 + pm_request_resume(dev); 339 + 340 + return 0; 341 + } 342 + 343 + /* 344 + * PM calls 345 + */ 346 + 347 + static int intel_resume_child_device(struct device *dev, void *data) 348 + { 349 + int ret; 350 + struct sdw_slave *slave = dev_to_sdw_dev(dev); 351 + 352 + if (!slave->probed) { 353 + dev_dbg(dev, "skipping device, no probed driver\n"); 354 + return 0; 355 + } 356 + if (!slave->dev_num_sticky) { 357 + dev_dbg(dev, "skipping device, never detected on bus\n"); 358 + return 0; 359 + } 360 + 361 + ret = pm_request_resume(dev); 362 + if (ret < 0) 363 + dev_err(dev, "%s: pm_request_resume failed: %d\n", __func__, ret); 364 + 365 + return ret; 366 + } 367 + 368 + static int __maybe_unused intel_pm_prepare(struct device *dev) 369 + { 370 + struct sdw_cdns *cdns = dev_get_drvdata(dev); 371 + struct sdw_intel *sdw = cdns_to_intel(cdns); 372 + struct sdw_bus *bus = &cdns->bus; 373 + u32 clock_stop_quirks; 374 + int ret; 375 + 376 + if (bus->prop.hw_disabled || !sdw->startup_done) { 377 + dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n", 378 + bus->link_id); 379 + return 0; 380 + } 381 + 382 + clock_stop_quirks = sdw->link_res->clock_stop_quirks; 383 + 384 + if (pm_runtime_suspended(dev) && 385 + pm_runtime_suspended(dev->parent) && 386 + ((clock_stop_quirks & SDW_INTEL_CLK_STOP_BUS_RESET) || 387 + !clock_stop_quirks)) { 388 + /* 389 + * if we've enabled clock stop, and the parent is suspended, the SHIM registers 390 + * are not accessible and the shim wake cannot be disabled. 391 + * The only solution is to resume the entire bus to full power 392 + */ 393 + 394 + /* 395 + * If any operation in this block fails, we keep going since we don't want 396 + * to prevent system suspend from happening and errors should be recoverable 397 + * on resume. 398 + */ 399 + 400 + /* 401 + * first resume the device for this link. This will also by construction 402 + * resume the PCI parent device. 403 + */ 404 + ret = pm_request_resume(dev); 405 + if (ret < 0) { 406 + dev_err(dev, "%s: pm_request_resume failed: %d\n", __func__, ret); 407 + return 0; 408 + } 409 + 410 + /* 411 + * Continue resuming the entire bus (parent + child devices) to exit 412 + * the clock stop mode. If there are no devices connected on this link 413 + * this is a no-op. 414 + * The resume to full power could have been implemented with a .prepare 415 + * step in SoundWire codec drivers. This would however require a lot 416 + * of code to handle an Intel-specific corner case. It is simpler in 417 + * practice to add a loop at the link level. 418 + */ 419 + ret = device_for_each_child(bus->dev, NULL, intel_resume_child_device); 420 + 421 + if (ret < 0) 422 + dev_err(dev, "%s: intel_resume_child_device failed: %d\n", __func__, ret); 423 + } 424 + 425 + return 0; 426 + } 427 + 428 + static int __maybe_unused intel_suspend(struct device *dev) 429 + { 430 + struct sdw_cdns *cdns = dev_get_drvdata(dev); 431 + struct sdw_intel *sdw = cdns_to_intel(cdns); 432 + struct sdw_bus *bus = &cdns->bus; 433 + u32 clock_stop_quirks; 434 + int ret; 435 + 436 + if (bus->prop.hw_disabled || !sdw->startup_done) { 437 + dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n", 438 + bus->link_id); 439 + return 0; 440 + } 441 + 442 + if (pm_runtime_suspended(dev)) { 443 + dev_dbg(dev, "pm_runtime status: suspended\n"); 444 + 445 + clock_stop_quirks = sdw->link_res->clock_stop_quirks; 446 + 447 + if ((clock_stop_quirks & SDW_INTEL_CLK_STOP_BUS_RESET) || 448 + !clock_stop_quirks) { 449 + 450 + if (pm_runtime_suspended(dev->parent)) { 451 + /* 452 + * paranoia check: this should not happen with the .prepare 453 + * resume to full power 454 + */ 455 + dev_err(dev, "%s: invalid config: parent is suspended\n", __func__); 456 + } else { 457 + sdw_intel_shim_wake(sdw, false); 458 + } 459 + } 460 + 461 + return 0; 462 + } 463 + 464 + ret = sdw_intel_stop_bus(sdw, false); 465 + if (ret < 0) { 466 + dev_err(dev, "%s: cannot stop bus: %d\n", __func__, ret); 467 + return ret; 468 + } 469 + 470 + return 0; 471 + } 472 + 473 + static int __maybe_unused intel_suspend_runtime(struct device *dev) 474 + { 475 + struct sdw_cdns *cdns = dev_get_drvdata(dev); 476 + struct sdw_intel *sdw = cdns_to_intel(cdns); 477 + struct sdw_bus *bus = &cdns->bus; 478 + u32 clock_stop_quirks; 479 + int ret; 480 + 481 + if (bus->prop.hw_disabled || !sdw->startup_done) { 482 + dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n", 483 + bus->link_id); 484 + return 0; 485 + } 486 + 487 + clock_stop_quirks = sdw->link_res->clock_stop_quirks; 488 + 489 + if (clock_stop_quirks & SDW_INTEL_CLK_STOP_TEARDOWN) { 490 + ret = sdw_intel_stop_bus(sdw, false); 491 + if (ret < 0) { 492 + dev_err(dev, "%s: cannot stop bus during teardown: %d\n", 493 + __func__, ret); 494 + return ret; 495 + } 496 + } else if (clock_stop_quirks & SDW_INTEL_CLK_STOP_BUS_RESET || !clock_stop_quirks) { 497 + ret = sdw_intel_stop_bus(sdw, true); 498 + if (ret < 0) { 499 + dev_err(dev, "%s: cannot stop bus during clock_stop: %d\n", 500 + __func__, ret); 501 + return ret; 502 + } 503 + } else { 504 + dev_err(dev, "%s clock_stop_quirks %x unsupported\n", 505 + __func__, clock_stop_quirks); 506 + ret = -EINVAL; 507 + } 508 + 509 + return ret; 510 + } 511 + 512 + static int __maybe_unused intel_resume(struct device *dev) 513 + { 514 + struct sdw_cdns *cdns = dev_get_drvdata(dev); 515 + struct sdw_intel *sdw = cdns_to_intel(cdns); 516 + struct sdw_bus *bus = &cdns->bus; 517 + int link_flags; 518 + int ret; 519 + 520 + if (bus->prop.hw_disabled || !sdw->startup_done) { 521 + dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n", 522 + bus->link_id); 523 + return 0; 524 + } 525 + 526 + link_flags = md_flags >> (bus->link_id * 8); 527 + 528 + if (pm_runtime_suspended(dev)) { 529 + dev_dbg(dev, "pm_runtime status was suspended, forcing active\n"); 530 + 531 + /* follow required sequence from runtime_pm.rst */ 532 + pm_runtime_disable(dev); 533 + pm_runtime_set_active(dev); 534 + pm_runtime_mark_last_busy(dev); 535 + pm_runtime_enable(dev); 536 + 537 + link_flags = md_flags >> (bus->link_id * 8); 538 + 539 + if (!(link_flags & SDW_INTEL_MASTER_DISABLE_PM_RUNTIME_IDLE)) 540 + pm_runtime_idle(dev); 541 + } 542 + 543 + ret = sdw_intel_link_power_up(sdw); 544 + if (ret) { 545 + dev_err(dev, "%s failed: %d\n", __func__, ret); 546 + return ret; 547 + } 548 + 549 + /* 550 + * make sure all Slaves are tagged as UNATTACHED and provide 551 + * reason for reinitialization 552 + */ 553 + sdw_clear_slave_status(bus, SDW_UNATTACH_REQUEST_MASTER_RESET); 554 + 555 + ret = sdw_intel_start_bus(sdw); 556 + if (ret < 0) { 557 + dev_err(dev, "cannot start bus during resume\n"); 558 + sdw_intel_link_power_down(sdw); 559 + return ret; 560 + } 561 + 562 + /* 563 + * after system resume, the pm_runtime suspend() may kick in 564 + * during the enumeration, before any children device force the 565 + * master device to remain active. Using pm_runtime_get() 566 + * routines is not really possible, since it'd prevent the 567 + * master from suspending. 568 + * A reasonable compromise is to update the pm_runtime 569 + * counters and delay the pm_runtime suspend by several 570 + * seconds, by when all enumeration should be complete. 571 + */ 572 + pm_runtime_mark_last_busy(dev); 573 + 574 + return 0; 575 + } 576 + 577 + static int __maybe_unused intel_resume_runtime(struct device *dev) 578 + { 579 + struct sdw_cdns *cdns = dev_get_drvdata(dev); 580 + struct sdw_intel *sdw = cdns_to_intel(cdns); 581 + struct sdw_bus *bus = &cdns->bus; 582 + u32 clock_stop_quirks; 583 + int ret; 584 + 585 + if (bus->prop.hw_disabled || !sdw->startup_done) { 586 + dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n", 587 + bus->link_id); 588 + return 0; 589 + } 590 + 591 + /* unconditionally disable WAKEEN interrupt */ 592 + sdw_intel_shim_wake(sdw, false); 593 + 594 + clock_stop_quirks = sdw->link_res->clock_stop_quirks; 595 + 596 + if (clock_stop_quirks & SDW_INTEL_CLK_STOP_TEARDOWN) { 597 + ret = sdw_intel_link_power_up(sdw); 598 + if (ret) { 599 + dev_err(dev, "%s: power_up failed after teardown: %d\n", __func__, ret); 600 + return ret; 601 + } 602 + 603 + /* 604 + * make sure all Slaves are tagged as UNATTACHED and provide 605 + * reason for reinitialization 606 + */ 607 + sdw_clear_slave_status(bus, SDW_UNATTACH_REQUEST_MASTER_RESET); 608 + 609 + ret = sdw_intel_start_bus(sdw); 610 + if (ret < 0) { 611 + dev_err(dev, "%s: cannot start bus after teardown: %d\n", __func__, ret); 612 + sdw_intel_link_power_down(sdw); 613 + return ret; 614 + } 615 + 616 + } else if (clock_stop_quirks & SDW_INTEL_CLK_STOP_BUS_RESET) { 617 + ret = sdw_intel_link_power_up(sdw); 618 + if (ret) { 619 + dev_err(dev, "%s: power_up failed after bus reset: %d\n", __func__, ret); 620 + return ret; 621 + } 622 + 623 + ret = sdw_intel_start_bus_after_reset(sdw); 624 + if (ret < 0) { 625 + dev_err(dev, "%s: cannot start bus after reset: %d\n", __func__, ret); 626 + sdw_intel_link_power_down(sdw); 627 + return ret; 628 + } 629 + } else if (!clock_stop_quirks) { 630 + 631 + sdw_intel_check_clock_stop(sdw); 632 + 633 + ret = sdw_intel_link_power_up(sdw); 634 + if (ret) { 635 + dev_err(dev, "%s: power_up failed: %d\n", __func__, ret); 636 + return ret; 637 + } 638 + 639 + ret = sdw_intel_start_bus_after_clock_stop(sdw); 640 + if (ret < 0) { 641 + dev_err(dev, "%s: cannot start bus after clock stop: %d\n", __func__, ret); 642 + sdw_intel_link_power_down(sdw); 643 + return ret; 644 + } 645 + } else { 646 + dev_err(dev, "%s: clock_stop_quirks %x unsupported\n", 647 + __func__, clock_stop_quirks); 648 + ret = -EINVAL; 649 + } 650 + 651 + return ret; 652 + } 653 + 654 + static const struct dev_pm_ops intel_pm = { 655 + .prepare = intel_pm_prepare, 656 + SET_SYSTEM_SLEEP_PM_OPS(intel_suspend, intel_resume) 657 + SET_RUNTIME_PM_OPS(intel_suspend_runtime, intel_resume_runtime, NULL) 658 + }; 659 + 660 + static const struct auxiliary_device_id intel_link_id_table[] = { 661 + { .name = "soundwire_intel.link" }, 662 + {}, 663 + }; 664 + MODULE_DEVICE_TABLE(auxiliary, intel_link_id_table); 665 + 666 + static struct auxiliary_driver sdw_intel_drv = { 667 + .probe = intel_link_probe, 668 + .remove = intel_link_remove, 669 + .driver = { 670 + /* auxiliary_driver_register() sets .name to be the modname */ 671 + .pm = &intel_pm, 672 + }, 673 + .id_table = intel_link_id_table 674 + }; 675 + module_auxiliary_driver(sdw_intel_drv); 676 + 677 + MODULE_LICENSE("Dual BSD/GPL"); 678 + MODULE_DESCRIPTION("Intel Soundwire Link Driver");
+18
drivers/soundwire/intel_auxdevice.h
··· 1 + /* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ 2 + /* Copyright(c) 2015-2022 Intel Corporation. */ 3 + 4 + #ifndef __SDW_INTEL_AUXDEVICE_H 5 + #define __SDW_INTEL_AUXDEVICE_H 6 + 7 + int intel_link_startup(struct auxiliary_device *auxdev); 8 + int intel_link_process_wakeen_event(struct auxiliary_device *auxdev); 9 + 10 + struct sdw_intel_link_dev { 11 + struct auxiliary_device auxdev; 12 + struct sdw_intel_link_res link_res; 13 + }; 14 + 15 + #define auxiliary_dev_to_sdw_intel_link_dev(auxiliary_dev) \ 16 + container_of(auxiliary_dev, struct sdw_intel_link_dev, auxdev) 17 + 18 + #endif /* __SDW_INTEL_AUXDEVICE_H */
+2
drivers/soundwire/intel_init.c
··· 17 17 #include <linux/soundwire/sdw_intel.h> 18 18 #include "cadence_master.h" 19 19 #include "intel.h" 20 + #include "intel_auxdevice.h" 20 21 21 22 static void intel_link_dev_release(struct device *dev) 22 23 { ··· 61 60 62 61 /* Add link information used in the driver probe */ 63 62 link = &ldev->link_res; 63 + link->hw_ops = res->hw_ops; 64 64 link->mmio_base = res->mmio_base; 65 65 link->registers = res->mmio_base + SDW_LINK_BASE 66 66 + (SDW_LINK_SIZE * link_id);
+20 -5
drivers/soundwire/qcom.c
··· 25 25 26 26 #define SWRM_COMP_SW_RESET 0x008 27 27 #define SWRM_COMP_STATUS 0x014 28 + #define SWRM_LINK_MANAGER_EE 0x018 29 + #define SWRM_EE_CPU 1 28 30 #define SWRM_FRM_GEN_ENABLED BIT(0) 29 31 #define SWRM_COMP_HW_VERSION 0x00 30 32 #define SWRM_COMP_CFG_ADDR 0x04 ··· 106 104 #define SWRM_REG_VAL_PACK(data, dev, id, reg) \ 107 105 ((reg) | ((id) << 16) | ((dev) << 20) | ((data) << 24)) 108 106 109 - #define SWRM_SPECIAL_CMD_ID 0xF 110 107 #define MAX_FREQ_NUM 1 111 108 #define TIMEOUT_MS 100 112 109 #define QCOM_SWRM_MAX_RD_LEN 0x1 ··· 695 694 u32p_replace_bits(&val, SWRM_DEF_CMD_NO_PINGS, SWRM_MCP_CFG_MAX_NUM_OF_CMD_NO_PINGS_BMSK); 696 695 ctrl->reg_write(ctrl, SWRM_MCP_CFG_ADDR, val); 697 696 698 - ctrl->reg_write(ctrl, SWRM_MCP_BUS_CTRL, SWRM_MCP_BUS_CLK_START); 697 + if (ctrl->version >= 0x01070000) { 698 + ctrl->reg_write(ctrl, SWRM_LINK_MANAGER_EE, SWRM_EE_CPU); 699 + ctrl->reg_write(ctrl, SWRM_MCP_BUS_CTRL, 700 + SWRM_MCP_BUS_CLK_START << SWRM_EE_CPU); 701 + } else { 702 + ctrl->reg_write(ctrl, SWRM_MCP_BUS_CTRL, SWRM_MCP_BUS_CLK_START); 703 + } 704 + 699 705 /* Configure number of retries of a read/write cmd */ 700 706 if (ctrl->version > 0x01050001) { 701 707 /* Only for versions >= 1.5.1 */ ··· 1339 1331 } 1340 1332 1341 1333 if (data->sw_clk_gate_required) { 1342 - ctrl->audio_cgcr = devm_reset_control_get_exclusive(dev, "swr_audio_cgcr"); 1343 - if (IS_ERR_OR_NULL(ctrl->audio_cgcr)) { 1334 + ctrl->audio_cgcr = devm_reset_control_get_optional_exclusive(dev, "swr_audio_cgcr"); 1335 + if (IS_ERR(ctrl->audio_cgcr)) { 1344 1336 dev_err(dev, "Failed to get cgcr reset ctrl required for SW gating\n"); 1345 1337 ret = PTR_ERR(ctrl->audio_cgcr); 1346 1338 goto err_init; ··· 1527 1519 } else { 1528 1520 reset_control_reset(ctrl->audio_cgcr); 1529 1521 1530 - ctrl->reg_write(ctrl, SWRM_MCP_BUS_CTRL, SWRM_MCP_BUS_CLK_START); 1522 + if (ctrl->version >= 0x01070000) { 1523 + ctrl->reg_write(ctrl, SWRM_LINK_MANAGER_EE, SWRM_EE_CPU); 1524 + ctrl->reg_write(ctrl, SWRM_MCP_BUS_CTRL, 1525 + SWRM_MCP_BUS_CLK_START << SWRM_EE_CPU); 1526 + } else { 1527 + ctrl->reg_write(ctrl, SWRM_MCP_BUS_CTRL, SWRM_MCP_BUS_CLK_START); 1528 + } 1531 1529 ctrl->reg_write(ctrl, SWRM_INTERRUPT_CLEAR, 1532 1530 SWRM_INTERRUPT_STATUS_MASTER_CLASH_DET); 1533 1531 ··· 1597 1583 { .compatible = "qcom,soundwire-v1.3.0", .data = &swrm_v1_3_data }, 1598 1584 { .compatible = "qcom,soundwire-v1.5.1", .data = &swrm_v1_5_data }, 1599 1585 { .compatible = "qcom,soundwire-v1.6.0", .data = &swrm_v1_6_data }, 1586 + { .compatible = "qcom,soundwire-v1.7.0", .data = &swrm_v1_5_data }, 1600 1587 {/* sentinel */}, 1601 1588 }; 1602 1589
+44
include/linux/soundwire/sdw_intel.h
··· 233 233 * struct sdw_intel_res - Soundwire Intel global resource structure, 234 234 * typically populated by the DSP driver 235 235 * 236 + * @hw_ops: abstraction for platform ops 236 237 * @count: link count 237 238 * @mmio_base: mmio base of SoundWire registers 238 239 * @irq: interrupt number ··· 250 249 * @alh_base: sdw alh base. 251 250 */ 252 251 struct sdw_intel_res { 252 + const struct sdw_intel_hw_ops *hw_ops; 253 253 int count; 254 254 void __iomem *mmio_base; 255 255 int irq; ··· 291 289 irqreturn_t sdw_intel_thread(int irq, void *dev_id); 292 290 293 291 #define SDW_INTEL_QUIRK_MASK_BUS_DISABLE BIT(1) 292 + 293 + struct sdw_intel; 294 + 295 + /* struct intel_sdw_hw_ops - SoundWire ops for Intel platforms. 296 + * @debugfs_init: initialize all debugfs capabilities 297 + * @debugfs_exit: close and cleanup debugfs capabilities 298 + * @register_dai: read all PDI information and register DAIs 299 + * @check_clock_stop: throw error message if clock is not stopped. 300 + * @start_bus: normal start 301 + * @start_bus_after_reset: start after reset 302 + * @start_bus_after_clock_stop: start after mode0 clock stop 303 + * @stop_bus: stop all bus 304 + * @link_power_up: power-up using chip-specific helpers 305 + * @link_power_down: power-down with chip-specific helpers 306 + * @shim_check_wake: check if a wake was received 307 + * @shim_wake: enable/disable in-band wake management 308 + * @pre_bank_switch: helper for bus management 309 + * @post_bank_switch: helper for bus management 310 + */ 311 + struct sdw_intel_hw_ops { 312 + void (*debugfs_init)(struct sdw_intel *sdw); 313 + void (*debugfs_exit)(struct sdw_intel *sdw); 314 + 315 + int (*register_dai)(struct sdw_intel *sdw); 316 + 317 + void (*check_clock_stop)(struct sdw_intel *sdw); 318 + int (*start_bus)(struct sdw_intel *sdw); 319 + int (*start_bus_after_reset)(struct sdw_intel *sdw); 320 + int (*start_bus_after_clock_stop)(struct sdw_intel *sdw); 321 + int (*stop_bus)(struct sdw_intel *sdw, bool clock_stop); 322 + 323 + int (*link_power_up)(struct sdw_intel *sdw); 324 + int (*link_power_down)(struct sdw_intel *sdw); 325 + 326 + int (*shim_check_wake)(struct sdw_intel *sdw); 327 + void (*shim_wake)(struct sdw_intel *sdw, bool wake_enable); 328 + 329 + int (*pre_bank_switch)(struct sdw_intel *sdw); 330 + int (*post_bank_switch)(struct sdw_intel *sdw); 331 + }; 332 + 333 + extern const struct sdw_intel_hw_ops sdw_intel_cnl_hw_ops; 294 334 295 335 #endif
+2
sound/soc/sof/intel/hda.c
··· 206 206 207 207 memset(&res, 0, sizeof(res)); 208 208 209 + res.hw_ops = &sdw_intel_cnl_hw_ops; 209 210 res.mmio_base = sdev->bar[HDA_DSP_BAR]; 210 211 res.shim_base = hdev->desc->sdw_shim_base; 211 212 res.alh_base = hdev->desc->sdw_alh_base; ··· 1728 1727 MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA); 1729 1728 MODULE_IMPORT_NS(SND_INTEL_SOUNDWIRE_ACPI); 1730 1729 MODULE_IMPORT_NS(SOUNDWIRE_INTEL_INIT); 1730 + MODULE_IMPORT_NS(SOUNDWIRE_INTEL);