The recent series of changes to the caching in the SSI driver have
caused a number of problems to appear in some test systems. These are
still not fully understood but we're coming up to the merge window so
for now let's revert commit 7de2763d9b (ASoC: fsl_ssi: Remove
.num_reg_defaults_raw from regmap_config) as backing that out seems to
resolve the problem on affected systems.
Reported-by: Maciej S. Szmigiero" <mail@maciej.szmigiero.name>
Signed-off-by: Mark Brown <broonie@kernel.org>
Reviewed-by: Marek Vasut <marex@denx.de>
This driver provides no .reg_defaults_raw in regmap_config, so
the .num_reg_defaults_raw is useless, and, in fact harmful. It
triggers kernel crash in regmap_init which tries to access the
register defaults.
Signed-off-by: Marek Vasut <marex@denx.de>
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Same as commit ce492b3b8f
Subject: drm/fsl-dcu: use flat regmap cache
Using flat regmap cache instead of RB-tree to avoid the following
lockdep warning on driver load:
WARNING: CPU: 0 PID: 1 at kernel/locking/lockdep.c:2871 lockdep_trace_alloc+0x104/0x128
DEBUG_LOCKS_WARN_ON(irqs_disabled_flags(flags))
The RB-tree regmap cache needs to allocate new space on first
writes. However, allocations in an atomic context (e.g. when a
spinlock is held) are not allowed. The function regmap_write
calls map->lock, which acquires a spinlock in the fast_io case.
Since the driver uses MMIO, the regmap bus of type regmap_mmio
is being used which has fast_io set to true.
Signed-off-by: Marek Vasut <marex@denx.de>
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
The i.MX51 datasheet says:
Chapter 56.1.2.4 I2S Mode
...
When I2S modes are entered (I2S master (01) or I2S slave (10)),
the following settings are recommended:
...
- TX Frame Rate should be 2 i.e. (STCCR[12:8] = 1)
- RX Frame Rate should be 2 i.e. (SRCCR[12:8] = 1)
Chapter 56.3.3.12 SSI Transmit and Receive Clock Control Registers (STCCR & SRCCR)
...
Bits 12-8 DC4-DC0
Frame Rate Divider Control. These bits are used to control the divide ratio
for the programmable frame rate dividers. The divide ratio works on the word
clock. In Normal mode, this ratio determines the word transfer rate.
In Network mode, this ratio sets the number of words per frame. The divide
ratio ranges from 1 to 32 in Normal mode and from 2 to 32 in Network mode.
In Normal mode, a divide ratio of 1 (DC=00000) provides continuous periodic
data word transfer. A bit-length frame sync must be used in this case.
Function fsl_ssi_hw_params() setup Normal mode for MONO output,
so with DC=0, SSI enters to continuous periodic data word transfer.
To fix this, setup DC for any I2S mode.
Patch has tested on custom board based on Digi CCMX-51 module (i.MX51).
Signed-off-by: Alexander Shiyan <shc_work@mail.ru>
Signed-off-by: Mark Brown <broonie@kernel.org>
Happened when the Playback (or Capture) is running continuously
and Capture (or Playback) is restarted (xrun, manual stop/start...)
Since the RX (or TX) FIFO are only reset when the whole SSI is disabled,
pending samples from previous capture (or playback) session may still
be present. They must be erased to not introduce channel slipping.
FIFO Clear register fields are documented in IMX51, IMX35 reference manual.
They are not documented in IMX50 or IMX6 RM, despite they are
working as expected on IMX6SL and IMX6solo.
Signed-off-by: Arnaud Mouiche <arnaud.mouiche@invoxia.com>
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
Tested-by: Caleb Crome <caleb@crome.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
Previously, SCR.SSIEN and SCR.TE were enabled at once if no capture
stream was also running.
This may not give a chance for the DMA to write the first sample in
TX FIFO before the streaming starts on the PCM bus, inserting void
samples first.
Those void samples are then responsible for slipping the channels.
Signed-off-by: Arnaud Mouiche <arnaud.mouiche@invoxia.com>
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
Tested-by: Caleb Crome <caleb@crome.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
If the capture is already running while playback is started, it is highly
probable (>80% in a 8 channels scenario) that samples are lost between
the DMA and TX fifo.
The reason is that SIER.TDMAE is set before STCR.TFEN0, leaving a time
window where the FIFO doesn't receive the samples written by the DMA.
This particular case happened only if capture is already enabled as
SCR.SSIEN is already set at the playback startup instant.
Signed-off-by: Arnaud Mouiche <arnaud.mouiche@invoxia.com>
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
Tested-by: Caleb Crome <caleb@crome.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
Most of functions only receive the ssi_private reference and don't have
a knowledge of 'dev' pointer, even for debug purpose.
Signed-off-by: Arnaud Mouiche <arnaud.mouiche@invoxia.com>
Tested-by: Caleb Crome <caleb@crome.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
im6sl reference manual 47.7.4:
"
Bit clock - Used to serially clock the data bits in and out of the SSI port.
This clock is either generated internally (from SSI's sys clock) or taken
from external clock source (through the Tx/Rx clock ports).
[...]
Care should be taken to ensure that the bit clock frequency (either
internally generated by dividing the SSI's sys clock or sourced from
external device through Tx/Rx clock ports) is never greater than 1/5
of the ipg_clk (from CCM) frequency.
"
Since, in master mode, the sysclk is a multiple of bitclk, we can
easily reach a high sysclk value, whereas keeping a reasonable bitclk.
ex: 8ch x 16bit x 48kHz = 6144000, requires a 24576000 sysclk (PM=1)
yet ipg_clk/5 = 66Mhz/5 = 13.2
Signed-off-by: Arnaud Mouiche <arnaud.mouiche@invoxia.com>
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
Tested-by: Caleb Crome <caleb@crome.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
The max number of slots in TDM mode is 32:
- Frame Rate Divider Control is a 5bit value
- Time slot mask registers control 32 slots.
Signed-off-by: Arnaud Mouiche <arnaud.mouiche@invoxia.com>
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
Tested-by: Caleb Crome <caleb@crome.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
The CCSR_SSI_SOR is a register that clears the TX and/or the RX fifo
on the i.MX SSI port. The fsl_ssi_trigger writes this register in
order to clear the fifo at trigger time.
However, since the CCSR_SSI_SOR register is not in the volatile list,
the caching mechanism prevented the register write in the trigger
function. This caused the fifo to not be cleared (because the value
was unchanged from the last time the register was written), and thus
causes the channels in both TDM or simple I2S mode to slip and be in
the wrong time slots on SSI restart.
This has gone unnoticed for so long because with simple stereo mode,
the consequence is that left and right are swapped, which isn't that
noticeable. However, it's catestrophic in some systems that
require the channels to be in the right slots.
Signed-off-by: Caleb Crome <caleb@crome.org>
Suggested-by: Arnaud Mouiche <arnaud.mouiche@invoxia.com>
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
There is no guarantee that on fsl_ssi module load
SSI registers will have their power-on-reset values.
In fact, if the driver is reloaded the values in
registers will be whatever they were set to previously.
However, the cache needs to be fully populated at probe
time to avoid non-atomic allocations during register
access.
Special case here is imx21-class SSI, since
according to datasheet it don't have SACC{ST,EN,DIS}
regs.
This fixes hard lockup on fsl_ssi module reload,
at least in AC'97 mode.
Fixes: 05cf237972 ("ASoC: fsl_ssi: Add driver suspend and resume to support MEGA Fast")
Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
Tested-by: Fabio Estevam <fabio.estevam@nxp.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Commit 5c408fee25 ("ASoC: fsl_ssi: remove explicit register defaults")
causes the driver to fail to probe:
fsl-ssi-dai 2028000.ssi: No cache defaults, reading back from HW
fsl-ssi-dai 2028000.ssi: Failed to init register map
fsl-ssi-dai: probe of 2028000.ssi failed with error -22
, so revert this commit.
Reported-by: Mika Penttilä <mika.penttila@nextfour.com>
Signed-off-by: Fabio Estevam <fabio.estevam@nxp.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
There is no guarantee that on fsl_ssi module load
SSI registers will have their power-on-reset values.
In fact, if the driver is reloaded the values in
registers will be whatever they were set to previously.
However, the cache needs to be fully populated at probe
time to avoid non-atomic allocations during register
access.
Special case here is imx21-class SSI, since
according to datasheet it don't have SACC{ST,EN,DIS}
regs.
This fixes hard lockup on fsl_ssi module reload,
at least in AC'97 mode.
Fixes: 05cf237972 ("ASoC: fsl_ssi: Add driver suspend and resume to support MEGA Fast")
Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
Tested-by: Fabio Estevam <fabio.estevam@nxp.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Mark some registers precious since their
reads have side effects (like clearing flags).
Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
SACNT register should be marked volatile since
its WR and RD bits are cleared by SSI after
completing the relevant operation.
This unbreaks AC'97 register access.
Fixes: 05cf237972 ("ASoC: fsl_ssi: Add driver suspend and resume to support MEGA Fast")
Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
using params_width function to simplify code.
Signed-off-by: Zidan Wang <zidan.wang@freescale.com>
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
using macro for default register map
Signed-off-by: Zidan Wang <zidan.wang@freescale.com>
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
For i.MX6 SoloX, there is a mode of the SoC to shutdown all power
source of modules during system suspend and resume procedure. Thus,
SSI needs to save all the values of registers before the system
suspend and restore them after the system resume.
The register SFCSR is volatile, but some bits in it need to be
recovered after suspend/resume.
Signed-off-by: Zidan Wang <zidan.wang@freescale.com>
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Current code incorrectly treats dai format for AC97 as bit mask
whereas it's actually an integer value. This causes DAI formats
other than AC97 (e.g. DSP_B) to trigger AC97 related code,
which is incorrect and breaks functionality. This patch fixes
the code to correctly compare values to determine AC97 or not.
Signed-off-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
Acked-by: Timur Tabi <timur@tabi.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
Adjust set DAI format function in fsl_ssi driver
so it doesn't fail and clears RXDIR in AC'97 mode.
Signed-off-by: Maciej Szmigiero <mail@maciej.szmigiero.name>
Signed-off-by: Mark Brown <broonie@kernel.org>
Instantiate AC'97 CODEC in fsl_ssi driver AC'97 mode.
Signed-off-by: Maciej Szmigiero <mail@maciej.szmigiero.name>
Signed-off-by: Mark Brown <broonie@kernel.org>
Check whether setting AC'97 ops succeeded and clean them
on removal so the fsl_ssi driver can be reloaded.
Signed-off-by: Maciej Szmigiero <mail@maciej.szmigiero.name>
Signed-off-by: Mark Brown <broonie@kernel.org>
AC'97 bus can support asymmetric playback/capture rates
so enable them in this case in fsl_ssi driver.
Signed-off-by: Maciej Szmigiero <mail@maciej.szmigiero.name>
Signed-off-by: Mark Brown <broonie@kernel.org>
AC'97 DAI driver struct need the same probe method as
I2S one to setup DMA params in fsl_ssi driver.
Signed-off-by: Maciej Szmigiero <mail@maciej.szmigiero.name>
Signed-off-by: Mark Brown <broonie@kernel.org>
IPG clock have to be enabled during AC'97 CODEC register
access in fsl_ssi driver.
Signed-off-by: Maciej Szmigiero <mail@maciej.szmigiero.name>
Signed-off-by: Mark Brown <broonie@kernel.org>
There are too much noise about the typos for fsl's drivers. So I fix
all the typos here in this patch in almost every file I touched.
Signed-off-by: Xiubo Li <lixiubo@cmss.chinamobile.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
According to the datasheet 'pm', 'psr' and 'div2' should never be all 0.
Since commit 541b03ad6c ("ASoC: fsl_ssi: Fix the incorrect limitation of
the bit clock rate") this can happen, because for some bitclock rates
'pm' = 0 seems to be a valid choice but does not work due to hardware
restrictions. This results into a bad hardware behaviour (slow audio for
example). Feature tested on a i.MX25.
Signed-off-by: Juergen Borleis <jbe@pengutronix.de>
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
As the ssi is not the only cpu dai, there are esai, spdif, sai.
and imx_pcm_dma can be used by all of them. Especially ESAI need
a larger DMA buffer size. So Add dedicated DMA buffer for each cpu
dai.
Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
Acked-by: Timur Tabi <timur@tabi.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
The comment and the call to of_device_is_available() are not really
needed.
It is the expected behaviour to probe only the ssi nodes that are
enabled in the device tree.
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Acked-by: Timur Tabi <timur@tabi.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
We should check whether platform_get_irq() returns a negative number and
propagate the error in this case.
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Using platform_get_resource() and devm_ioremap_resource() can make the
code a bit simpler.
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Using devm_snd_soc_register_component() can make the code shorter and
cleaner.
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
According to i.MX6 Series Reference Manual, the formula to calculate
the sys clock is
sysclk rate = bclk rate * (div2 + 1) * (7 * psr + 1) * (pm + 1) * 2
Commit aafa85e71a ("ASoC: fsl_ssi: Add DAI master mode support for
SSI on i.MX series") added the divisor calculation which relies on
the clk_round_rate(). However, at that time, clk_round_rate() didn't
provide closest clock rates for some cases because it might not use
a correct rounding policy. So using the original formula (pm + 1) for
PM divisor was not able to give us a desired clock rate. And then we
used (pm + 2) to do the trick.
However, the clk-divider driver has been refined a lot since commit
b11d282dbe ("clk: divider: fix rate calculation for fractional rates")
Now using (pm + 2) trick would result an incorrect clock rate.
So this patch fixes the problem by removing the useless trick.
Reported-by: Stephane Cerveau <scerveau@voxtok.com>
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
of_property_read_u32_array returns 0 on success,
so the return value shouldn't be inverted twice,
first on assignment then in condition expression.
Signed-off-by: Maciej Szmigiero <mail@maciej.szmigiero.name>
Signed-off-by: Mark Brown <broonie@kernel.org>
According to i.MX Reference Manual, the bit-clock frequency generated
by SSI must be never greater than 1/5 of the peripheral clock frequency.
This peripheral clock, however, is not baudclk but the IPG clock (i.e.
ssi_private->clk in the fsl_ssi driver).
So this patch just simply fixes the incorrect limitation applied to
the bit clock (baudclk) rate.
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
The fsl-ssi and imx-ssi drivers use inverted semantics for the tx_mask and
rx_mask parameter of the set_tdm_slot() callback compared to rest of ASoC.
This patch updates the driver's semantics to be consistent with the rest of
ASoC, i.e. a set bit means a active slot and a cleared bit means a inactive
slot. This will allow us to use the set_tdm_slot() API in a more generic
way.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Since commit 2ffa531078 ("ASoC: fsl_ssi: Fix module unbound") the irq
number is retrieved via platform_get_irq(), which may fail and return a negative
number, so adapt its type to 'int'.
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Currently the error message uses 'np->full_name' which leads to a very verbose
log as:
fsl-ssi-dai 202c000.ssi: no irq for node /soc/aips-bus@02000000/spba-bus@02000000/ssi@0202c000
We can have a concise log by using pdev->name instead:
fsl-ssi-dai 202c000.ssi: no irq for node 202c000.ssi
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>