Commit cc4b3c09 authored by Mark Brown's avatar Mark Brown

Add the PowerQUICC audio support using the QMC

Merge series from Herve Codina <herve.codina@bootlin.com>:

This series adds support for audio using the QMC controller available in
some Freescale PowerQUICC SoCs.

This series contains three parts in order to show the different blocks
hierarchy and their usage in this support.

The first one is related to TSA (Time Slot Assigner).
The TSA handles the data present at the pin level (TDM with up to 64
time slots) and dispatchs them to one or more serial controller (SCC).

The second is related to QMC (QUICC Multichannel Controller).
The QMC handles the data at the serial controller (SCC) level and splits
again the data to creates some virtual channels.

The last one is related to the audio component (QMC audio).
It is the glue between the QMC controller and the ASoC component. It
handles one or more QMC virtual channels and creates one DAI per QMC
virtual channels handled.
parents 631b8a8b eb7ff1cb
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,cpm1-scc-qmc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: PowerQUICC CPM QUICC Multichannel Controller (QMC)
maintainers:
- Herve Codina <herve.codina@bootlin.com>
description:
The QMC (QUICC Multichannel Controller) emulates up to 64 channels within one
serial controller using the same TDM physical interface routed from TSA.
properties:
compatible:
items:
- enum:
- fsl,mpc885-scc-qmc
- fsl,mpc866-scc-qmc
- const: fsl,cpm1-scc-qmc
reg:
items:
- description: SCC (Serial communication controller) register base
- description: SCC parameter ram base
- description: Dual port ram base
reg-names:
items:
- const: scc_regs
- const: scc_pram
- const: dpram
interrupts:
maxItems: 1
description: SCC interrupt line in the CPM interrupt controller
fsl,tsa-serial:
$ref: /schemas/types.yaml#/definitions/phandle-array
items:
- items:
- description: phandle to TSA node
- enum: [1, 2, 3]
description: |
TSA serial interface (dt-bindings/soc/cpm1-fsl,tsa.h defines these
values)
- 1: SCC2
- 2: SCC3
- 3: SCC4
description:
Should be a phandle/number pair. The phandle to TSA node and the TSA
serial interface to use.
'#address-cells':
const: 1
'#size-cells':
const: 0
'#fsl,chan-cells':
$ref: /schemas/types.yaml#/definitions/uint32
const: 1
description:
QMC consumers that use a phandle to QMC need to pass the channel number
with this phandle.
For instance "fsl,qmc-chan = <&qmc 16>;".
patternProperties:
'^channel@([0-9]|[1-5][0-9]|6[0-3])$':
description:
A channel managed by this controller
type: object
properties:
reg:
minimum: 0
maximum: 63
description:
The channel number
fsl,operational-mode:
$ref: /schemas/types.yaml#/definitions/string
enum: [transparent, hdlc]
default: transparent
description: |
The channel operational mode
- hdlc: The channel handles HDLC frames
- transparent: The channel handles raw data without any processing
fsl,reverse-data:
$ref: /schemas/types.yaml#/definitions/flag
description:
The bit order as seen on the channels is reversed,
transmitting/receiving the MSB of each octet first.
This flag is used only in 'transparent' mode.
fsl,tx-ts-mask:
$ref: /schemas/types.yaml#/definitions/uint64
description:
Channel assigned Tx time-slots within the Tx time-slots routed by the
TSA to this cell.
fsl,rx-ts-mask:
$ref: /schemas/types.yaml#/definitions/uint64
description:
Channel assigned Rx time-slots within the Rx time-slots routed by the
TSA to this cell.
required:
- reg
- fsl,tx-ts-mask
- fsl,rx-ts-mask
required:
- compatible
- reg
- reg-names
- interrupts
- fsl,tsa-serial
- '#address-cells'
- '#size-cells'
- '#fsl,chan-cells'
additionalProperties: false
examples:
- |
#include <dt-bindings/soc/cpm1-fsl,tsa.h>
qmc@a60 {
compatible = "fsl,mpc885-scc-qmc", "fsl,cpm1-scc-qmc";
reg = <0xa60 0x20>,
<0x3f00 0xc0>,
<0x2000 0x1000>;
reg-names = "scc_regs", "scc_pram", "dpram";
interrupts = <27>;
interrupt-parent = <&CPM_PIC>;
#address-cells = <1>;
#size-cells = <0>;
#fsl,chan-cells = <1>;
fsl,tsa-serial = <&tsa FSL_CPM_TSA_SCC4>;
channel@16 {
/* Ch16 : First 4 even TS from all routed from TSA */
reg = <16>;
fsl,mode = "transparent";
fsl,reverse-data;
fsl,tx-ts-mask = <0x00000000 0x000000aa>;
fsl,rx-ts-mask = <0x00000000 0x000000aa>;
};
channel@17 {
/* Ch17 : First 4 odd TS from all routed from TSA */
reg = <17>;
fsl,mode = "transparent";
fsl,reverse-data;
fsl,tx-ts-mask = <0x00000000 0x00000055>;
fsl,rx-ts-mask = <0x00000000 0x00000055>;
};
channel@19 {
/* Ch19 : 8 TS (TS 8..15) from all routed from TSA */
reg = <19>;
fsl,mode = "hdlc";
fsl,tx-ts-mask = <0x00000000 0x0000ff00>;
fsl,rx-ts-mask = <0x00000000 0x0000ff00>;
};
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,cpm1-tsa.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: PowerQUICC CPM Time-slot assigner (TSA) controller
maintainers:
- Herve Codina <herve.codina@bootlin.com>
description:
The TSA is the time-slot assigner that can be found on some PowerQUICC SoC.
Its purpose is to route some TDM time-slots to other internal serial
controllers.
properties:
compatible:
items:
- enum:
- fsl,mpc885-tsa
- fsl,mpc866-tsa
- const: fsl,cpm1-tsa
reg:
items:
- description: SI (Serial Interface) register base
- description: SI RAM base
reg-names:
items:
- const: si_regs
- const: si_ram
'#address-cells':
const: 1
'#size-cells':
const: 0
'#fsl,serial-cells':
$ref: /schemas/types.yaml#/definitions/uint32
const: 1
description:
TSA consumers that use a phandle to TSA need to pass the serial identifier
with this phandle (defined in dt-bindings/soc/fsl,tsa.h).
For instance "fsl,tsa-serial = <&tsa FSL_CPM_TSA_SCC4>;".
patternProperties:
'^tdm@[0-1]$':
description:
The TDM managed by this controller
type: object
additionalProperties: false
properties:
reg:
minimum: 0
maximum: 1
description:
The TDM number for this TDM, 0 for TDMa and 1 for TDMb
fsl,common-rxtx-pins:
$ref: /schemas/types.yaml#/definitions/flag
description:
The hardware can use four dedicated pins for Tx clock, Tx sync, Rx
clock and Rx sync or use only two pins, Tx/Rx clock and Tx/Rx sync.
Without the 'fsl,common-rxtx-pins' property, the four pins are used.
With the 'fsl,common-rxtx-pins' property, two pins are used.
clocks:
minItems: 2
items:
- description: External clock connected to L1RSYNC pin
- description: External clock connected to L1RCLK pin
- description: External clock connected to L1TSYNC pin
- description: External clock connected to L1TCLK pin
clock-names:
minItems: 2
items:
- const: l1rsync
- const: l1rclk
- const: l1tsync
- const: l1tclk
fsl,rx-frame-sync-delay-bits:
enum: [0, 1, 2, 3]
default: 0
description: |
Receive frame sync delay in number of bits.
Indicates the delay between the Rx sync and the first bit of the Rx
frame. 0 for no bit delay. 1, 2 or 3 for 1, 2 or 3 bits delay.
fsl,tx-frame-sync-delay-bits:
enum: [0, 1, 2, 3]
default: 0
description: |
Transmit frame sync delay in number of bits.
Indicates the delay between the Tx sync and the first bit of the Tx
frame. 0 for no bit delay. 1, 2 or 3 for 1, 2 or 3 bits delay.
fsl,clock-falling-edge:
$ref: /schemas/types.yaml#/definitions/flag
description:
Data is sent on falling edge of the clock (and received on the rising
edge). If 'clock-falling-edge' is not present, data is sent on the
rising edge (and received on the falling edge).
fsl,fsync-rising-edge:
$ref: /schemas/types.yaml#/definitions/flag
description:
Frame sync pulses are sampled with the rising edge of the channel
clock. If 'fsync-rising-edge' is not present, pulses are sampled with
the falling edge.
fsl,double-speed-clock:
$ref: /schemas/types.yaml#/definitions/flag
description:
The channel clock is twice the data rate.
patternProperties:
'^fsl,[rt]x-ts-routes$':
$ref: /schemas/types.yaml#/definitions/uint32-matrix
description: |
A list of tuple that indicates the Tx or Rx time-slots routes.
items:
items:
- description:
The number of time-slots
minimum: 1
maximum: 64
- description: |
The source (Tx) or destination (Rx) serial interface
(dt-bindings/soc/cpm1-fsl,tsa.h defines these values)
- 0: No destination
- 1: SCC2
- 2: SCC3
- 3: SCC4
- 4: SMC1
- 5: SMC2
enum: [0, 1, 2, 3, 4, 5]
minItems: 1
maxItems: 64
allOf:
# If fsl,common-rxtx-pins is present, only 2 clocks are needed.
# Else, the 4 clocks must be present.
- if:
required:
- fsl,common-rxtx-pins
then:
properties:
clocks:
maxItems: 2
clock-names:
maxItems: 2
else:
properties:
clocks:
minItems: 4
clock-names:
minItems: 4
required:
- reg
- clocks
- clock-names
required:
- compatible
- reg
- reg-names
- '#address-cells'
- '#size-cells'
- '#fsl,serial-cells'
additionalProperties: false
examples:
- |
#include <dt-bindings/soc/cpm1-fsl,tsa.h>
tsa@ae0 {
compatible = "fsl,mpc885-tsa", "fsl,cpm1-tsa";
reg = <0xae0 0x10>,
<0xc00 0x200>;
reg-names = "si_regs", "si_ram";
#address-cells = <1>;
#size-cells = <0>;
#fsl,serial-cells = <1>;
tdm@0 {
/* TDMa */
reg = <0>;
clocks = <&clk_l1rsynca>, <&clk_l1rclka>;
clock-names = "l1rsync", "l1rclk";
fsl,common-rxtx-pins;
fsl,fsync-rising-edge;
fsl,tx-ts-routes = <2 0>, /* TS 0..1 */
<24 FSL_CPM_TSA_SCC4>, /* TS 2..25 */
<1 0>, /* TS 26 */
<5 FSL_CPM_TSA_SCC3>; /* TS 27..31 */
fsl,rx-ts-routes = <2 0>, /* TS 0..1 */
<24 FSL_CPM_TSA_SCC4>, /* 2..25 */
<1 0>, /* TS 26 */
<5 FSL_CPM_TSA_SCC3>; /* TS 27..31 */
};
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/fsl,qmc-audio.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: QMC audio
maintainers:
- Herve Codina <herve.codina@bootlin.com>
description: |
The QMC audio is an ASoC component which uses QMC (QUICC Multichannel
Controller) channels to transfer the audio data.
It provides as many DAI as the number of QMC channel used.
allOf:
- $ref: dai-common.yaml#
properties:
compatible:
const: fsl,qmc-audio
'#address-cells':
const: 1
'#size-cells':
const: 0
'#sound-dai-cells':
const: 1
patternProperties:
'^dai@([0-9]|[1-5][0-9]|6[0-3])$':
description:
A DAI managed by this controller
type: object
properties:
reg:
minimum: 0
maximum: 63
description:
The DAI number
fsl,qmc-chan:
$ref: /schemas/types.yaml#/definitions/phandle-array
items:
- items:
- description: phandle to QMC node
- description: Channel number
description:
Should be a phandle/number pair. The phandle to QMC node and the QMC
channel to use for this DAI.
required:
- reg
- fsl,qmc-chan
required:
- compatible
- '#address-cells'
- '#size-cells'
- '#sound-dai-cells'
additionalProperties: false
examples:
- |
audio_controller: audio-controller {
compatible = "fsl,qmc-audio";
#address-cells = <1>;
#size-cells = <0>;
#sound-dai-cells = <1>;
dai@16 {
reg = <16>;
fsl,qmc-chan = <&qmc 16>;
};
dai@17 {
reg = <17>;
fsl,qmc-chan = <&qmc 17>;
};
};
sound {
compatible = "simple-audio-card";
#address-cells = <1>;
#size-cells = <0>;
simple-audio-card,dai-link@0 {
reg = <0>;
format = "dsp_b";
cpu {
sound-dai = <&audio_controller 16>;
};
codec {
sound-dai = <&codec1>;
dai-tdm-slot-num = <4>;
dai-tdm-slot-width = <8>;
/* TS 3, 5, 7, 9 */
dai-tdm-slot-tx-mask = <0 0 0 1 0 1 0 1 0 1>;
dai-tdm-slot-rx-mask = <0 0 0 1 0 1 0 1 0 1>;
};
};
simple-audio-card,dai-link@1 {
reg = <1>;
format = "dsp_b";
cpu {
sound-dai = <&audio_controller 17>;
};
codec {
sound-dai = <&codec2>;
dai-tdm-slot-num = <4>;
dai-tdm-slot-width = <8>;
/* TS 2, 4, 6, 8 */
dai-tdm-slot-tx-mask = <0 0 1 0 1 0 1 0 1>;
dai-tdm-slot-rx-mask = <0 0 1 0 1 0 1 0 1>;
};
};
};
......@@ -8247,6 +8247,23 @@ S: Maintained
F: drivers/soc/fsl/qe/
F: include/soc/fsl/qe/
FREESCALE QUICC ENGINE QMC DRIVER
M: Herve Codina <herve.codina@bootlin.com>
L: linuxppc-dev@lists.ozlabs.org
S: Maintained
F: Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,cpm1-scc-qmc.yaml
F: drivers/soc/fsl/qe/qmc.c
F: include/soc/fsl/qe/qmc.h
FREESCALE QUICC ENGINE TSA DRIVER
M: Herve Codina <herve.codina@bootlin.com>
L: linuxppc-dev@lists.ozlabs.org
S: Maintained
F: Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,cpm1-tsa.yaml
F: drivers/soc/fsl/qe/tsa.c
F: drivers/soc/fsl/qe/tsa.h
F: include/dt-bindings/soc/cpm1-fsl,tsa.h
FREESCALE QUICC ENGINE UCC ETHERNET DRIVER
M: Li Yang <leoyang.li@nxp.com>
L: netdev@vger.kernel.org
......@@ -8298,6 +8315,14 @@ F: sound/soc/fsl/fsl*
F: sound/soc/fsl/imx*
F: sound/soc/fsl/mpc8610_hpcd.c
FREESCALE SOC SOUND QMC DRIVER
M: Herve Codina <herve.codina@bootlin.com>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
L: linuxppc-dev@lists.ozlabs.org
S: Maintained
F: Documentation/devicetree/bindings/sound/fsl,qmc-audio.yaml
F: sound/soc/fsl/fsl_qmc_audio.c
FREESCALE USB PERIPHERAL DRIVERS
M: Li Yang <leoyang.li@nxp.com>
L: linux-usb@vger.kernel.org
......
......@@ -94,7 +94,7 @@ int cpm_command(u32 command, u8 opcode)
int i, ret;
unsigned long flags;
if (command & 0xffffff0f)
if (command & 0xffffff03)
return -EINVAL;
spin_lock_irqsave(&cmd_lock, flags);
......
......@@ -33,6 +33,29 @@ config UCC
bool
default y if UCC_FAST || UCC_SLOW
config CPM_TSA
tristate "CPM TSA support"
depends on OF && HAS_IOMEM
depends on CPM1 || COMPILE_TEST
help
Freescale CPM Time Slot Assigner (TSA)
controller.
This option enables support for this
controller
config CPM_QMC
tristate "CPM QMC support"
depends on OF && HAS_IOMEM
depends on CPM1 || (SOC_FSL && COMPILE_TEST)
depends on CPM_TSA
help
Freescale CPM QUICC Multichannel Controller
(QMC)
This option enables support for this
controller
config QE_TDM
bool
default y if FSL_UCC_HDLC
......
......@@ -4,6 +4,8 @@
#
obj-$(CONFIG_QUICC_ENGINE)+= qe.o qe_common.o qe_ic.o qe_io.o
obj-$(CONFIG_CPM) += qe_common.o
obj-$(CONFIG_CPM_TSA) += tsa.o
obj-$(CONFIG_CPM_QMC) += qmc.o
obj-$(CONFIG_UCC) += ucc.o
obj-$(CONFIG_UCC_SLOW) += ucc_slow.o
obj-$(CONFIG_UCC_FAST) += ucc_fast.o
......
This diff is collapsed.
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 */
/*
* TSA management
*
* Copyright 2022 CS GROUP France
*
* Author: Herve Codina <herve.codina@bootlin.com>
*/
#ifndef __SOC_FSL_TSA_H__
#define __SOC_FSL_TSA_H__
#include <linux/types.h>
struct device_node;
struct device;
struct tsa_serial;
struct tsa_serial *tsa_serial_get_byphandle(struct device_node *np,
const char *phandle_name);
void tsa_serial_put(struct tsa_serial *tsa_serial);
struct tsa_serial *devm_tsa_serial_get_byphandle(struct device *dev,
struct device_node *np,
const char *phandle_name);
/* Connect and disconnect the TSA serial */
int tsa_serial_connect(struct tsa_serial *tsa_serial);
int tsa_serial_disconnect(struct tsa_serial *tsa_serial);
/* Cell information */
struct tsa_serial_info {
unsigned long rx_fs_rate;
unsigned long rx_bit_rate;
u8 nb_rx_ts;
unsigned long tx_fs_rate;
unsigned long tx_bit_rate;
u8 nb_tx_ts;
};
/* Get information */
int tsa_serial_get_info(struct tsa_serial *tsa_serial, struct tsa_serial_info *info);
#endif /* __SOC_FSL_TSA_H__ */
/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
#ifndef __DT_BINDINGS_SOC_FSL_TSA_H
#define __DT_BINDINGS_SOC_FSL_TSA_H
#define FSL_CPM_TSA_NU 0 /* Pseuso Cell Id for not used item */
#define FSL_CPM_TSA_SCC2 1
#define FSL_CPM_TSA_SCC3 2
#define FSL_CPM_TSA_SCC4 3
#define FSL_CPM_TSA_SMC1 4
#define FSL_CPM_TSA_SMC2 5
#endif
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* QMC management
*
* Copyright 2022 CS GROUP France
*
* Author: Herve Codina <herve.codina@bootlin.com>
*/
#ifndef __SOC_FSL_QMC_H__
#define __SOC_FSL_QMC_H__
#include <linux/types.h>
struct device_node;
struct device;
struct qmc_chan;
struct qmc_chan *qmc_chan_get_byphandle(struct device_node *np, const char *phandle_name);
void qmc_chan_put(struct qmc_chan *chan);
struct qmc_chan *devm_qmc_chan_get_byphandle(struct device *dev, struct device_node *np,
const char *phandle_name);
enum qmc_mode {
QMC_TRANSPARENT,
QMC_HDLC,
};
struct qmc_chan_info {
enum qmc_mode mode;
unsigned long rx_fs_rate;
unsigned long rx_bit_rate;
u8 nb_rx_ts;
unsigned long tx_fs_rate;
unsigned long tx_bit_rate;
u8 nb_tx_ts;
};
int qmc_chan_get_info(struct qmc_chan *chan, struct qmc_chan_info *info);
struct qmc_chan_param {
enum qmc_mode mode;
union {
struct {
u16 max_rx_buf_size;
u16 max_rx_frame_size;
bool is_crc32;
} hdlc;
struct {
u16 max_rx_buf_size;
} transp;
};
};
int qmc_chan_set_param(struct qmc_chan *chan, const struct qmc_chan_param *param);
int qmc_chan_write_submit(struct qmc_chan *chan, dma_addr_t addr, size_t length,
void (*complete)(void *context), void *context);
int qmc_chan_read_submit(struct qmc_chan *chan, dma_addr_t addr, size_t length,
void (*complete)(void *context, size_t length),
void *context);
#define QMC_CHAN_READ (1<<0)
#define QMC_CHAN_WRITE (1<<1)
#define QMC_CHAN_ALL (QMC_CHAN_READ | QMC_CHAN_WRITE)
int qmc_chan_start(struct qmc_chan *chan, int direction);
int qmc_chan_stop(struct qmc_chan *chan, int direction);
int qmc_chan_reset(struct qmc_chan *chan, int direction);
#endif /* __SOC_FSL_QMC_H__ */
......@@ -172,6 +172,15 @@ config SND_MPC52xx_DMA
config SND_SOC_POWERPC_DMA
tristate
config SND_SOC_POWERPC_QMC_AUDIO
tristate "QMC ALSA SoC support"
depends on CPM_QMC
help
ALSA SoC Audio support using the Freescale QUICC Multichannel
Controller (QMC).
Say Y or M if you want to add support for SoC audio using Freescale
QMC.
comment "SoC Audio support for Freescale PPC boards:"
config SND_SOC_MPC8610_HPCD
......
......@@ -28,6 +28,7 @@ snd-soc-fsl-easrc-objs := fsl_easrc.o
snd-soc-fsl-xcvr-objs := fsl_xcvr.o
snd-soc-fsl-aud2htx-objs := fsl_aud2htx.o
snd-soc-fsl-rpmsg-objs := fsl_rpmsg.o
snd-soc-fsl-qmc-audio-objs := fsl_qmc_audio.o
obj-$(CONFIG_SND_SOC_FSL_AUDMIX) += snd-soc-fsl-audmix.o
obj-$(CONFIG_SND_SOC_FSL_ASOC_CARD) += snd-soc-fsl-asoc-card.o
......@@ -44,6 +45,7 @@ obj-$(CONFIG_SND_SOC_POWERPC_DMA) += snd-soc-fsl-dma.o
obj-$(CONFIG_SND_SOC_FSL_XCVR) += snd-soc-fsl-xcvr.o
obj-$(CONFIG_SND_SOC_FSL_AUD2HTX) += snd-soc-fsl-aud2htx.o
obj-$(CONFIG_SND_SOC_FSL_RPMSG) += snd-soc-fsl-rpmsg.o
obj-$(CONFIG_SND_SOC_POWERPC_QMC_AUDIO) += snd-soc-fsl-qmc-audio.o
# MPC5200 Platform Support
obj-$(CONFIG_SND_MPC52xx_DMA) += mpc5200_dma.o
......
This diff is collapsed.
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