The assigned-clocks -rate property on the mifcil node set the initial rate of the corresponding clk under the assigned-clocks. This is the IMX8MM_CLK_PDM is set to 196608000Hz at boot up.
&micfil {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pdm>;
assigned-clocks = <&clk IMX8MM_CLK_PDM>;
assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
assigned-clock-rates = <196608000>;
status = "okay";
};
If you dump the clk_summary just after booting linux
cat /sys/kernel/debug/clk/clk_summary
enable prepare protect duty clock count count count rate accuracy phase cycle
----------------------------------------------------------------------------------------
audio_pll1_ref_sel 0 0 0 24000000 0 0 50000
audio_pll1 0 0 0 393216000 0 0 50000
audio_pll1_bypass 0 0 0 393216000 0 0 50000
audio_pll1_out 0 0 0 393216000 0 0 50000
pdm 0 0 0 196608000 0 0 50000
pdm_root 0 0 0 196608000 0 0 50000
pdm_sel 0 0 0 196608000 0 0 50000
pdm_root_clk 0 0 0 196608000 0 0 50000
As you can see the pdm_root_clk (IMX8MM_CLK_PDM) is set at 196608000Hz
However, once you record something using arecord (The micfil driver is exercised)
arecord -Dhw:1,0 -fS32_LE -r48000 -c4 test.wav
You will notice the pdm_root_clk changes its value to 24576000 Hz
cat /sys/kernel/debug/clk/clk_summary
audio_pll1_ref_sel 1 1 0 24000000 0 0 50000
audio_pll1 1 1 0 393216000 0 0 50000
audio_pll1_bypass 1 1 0 393216000 0 0 50000
audio_pll1_out 1 1 0 393216000 0 0 50000
pdm 1 1 0 24576000 0 0 50000
pdm_root 1 1 0 24576000 0 0 50000
pdm_sel 1 1 0 24576000 0 0 50000
pdm_root_clk 1 1 0 24576000 0 0 50000
This is because the output rate 48KHz is requested by the application. The fsl_micfil_set_mclk_rate function at the kernel driver will be called with parameter freq = 48000 and the mclk (pdm_root_clk) will be set the accordingly
If freq is interger multiple of 8K then pdm_root_clk = 24576000 (CLK_8K_FREQ)
if freq NOT integer multiple of 8K then use 22579200 (CLK_11K_FREQ)
For the freq = 48Khz mclk = 24576000
This can be seen at the sound/soc/fsl/fsl_micfil.c file on kernel driver
#define CLK_8K_FREQ 24576000
#define CLK_11K_FREQ 22579200
static int fsl_micfil_set_mclk_rate(struct fsl_micfil *micfil, int clk_id,
unsigned int freq)
{
. . .
clk_disable_unprepare(micfil->mclk);
. . .
clk_rate = freq % 8000 == 0 ? CLK_8K_FREQ : CLK_11K_FREQ;
ret = clk_set_rate(micfil->mclk, clk_rate);
. . .
clk_prepare_enable(micfil->mclk);
. . .
}
The mclk is not the actual bitclk. This is computed based from the following table on the RM
which correspond to the calculations on the get_pdm_clk function (plus the k factor)
where rate = output rate 48KHz and cicosr = osr =16
For High quality -> bclk = 48KHz * 8 * 16 /2 = 3072000 Hz
static inline int get_pdm_clk(struct fsl_micfil *micfil,
unsigned int rate)
{
. . .
switch (qsel) {
case MICFIL_HIGH_QUALITY:
bclk = rate * 8 * osr / 2;
break;
case MICFIL_MEDIUM_QUALITY:
case MICFIL_VLOW0_QUALITY:
bclk = rate * 4 * osr * 1;
break;
case MICFIL_LOW_QUALITY:
case MICFIL_VLOW1_QUALITY:
bclk = rate * 2 * osr * 2;
break;
case MICFIL_VLOW2_QUALITY:
bclk = rate * osr * 4;
break;
. . .
}
The OSR is always set to the default value of MICFIL_CTRL2_OSR_DEFAULT (0) hence cicosr = 16
static int fsl_set_clock_params(struct device *dev, unsigned int rate)
{
.. .
ret |= regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL2,
MICFIL_CTRL2_CICOSR_MASK,
MICFIL_CTRL2_OSR_DEFAULT);
. . .
}
Finally the clk_div is computed as follows
clk_div = mclk / (pdm_clk *2)
clkdiv = 24576000/(3072000 * 2) = 4
clk__div = 4
static inline int get_clk_div(struct fsl_micfil *micfil,
unsigned int rate)
{
. . .
mclk_rate = clk_get_rate(micfil->mclk);
clk_div = mclk_rate / (get_pdm_clk(micfil, rate) * 2);
. . .
}
So, translated to the nomenclature on RM for the output rate = 48KHz example:
MICFIL_CLK_ROOT = mclk_rate = = 24576000
PDM_CLK = mclk_rate/ clk_div = 6144000
So actual clk on the pdm microphone will be 6.1 MHz for High Quality