[imx8mp-evk] About micfil(PDM mic) clock algorithm & settings

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

[imx8mp-evk] About micfil(PDM mic) clock algorithm & settings

2,475 Views
ESK
Contributor I

 

Dear NXP team,

Please check below,

 

    imx8mp-evk + PDM mic(SPG08P4HM4H-1 * 2ea)

 

    1. When I check other case of PDM mic on NXP community & NXP's mic board, PDM_CLK 1MHz is ok. But 'SPG08P4HM4H' needs minimum 1.2MHz.

  ESK_0-1646311245806.png

    So, I want to change PDM_CLK, But I can't understand the algorithm of assigned-clock-rates = <196608000>

   ESK_1-1646311599616.png

    Could you explain the calculate algorithm using example real-use-case?
        196608000 means?
        MICFIL_CLK_ROOT = ? (code location)
        PDM_CLK = ? (code location)

 

    2. When I use memtool for reading PDM register, I does not work. (bus error? sorry, I have no captures now)
        command : memtool -32 0x30ca0000 1 
        How I read the PDM register in this case?

 

Environment)

HW :

ESK_2-1646312584282.png

SW : using imx8mp-evk.dts (imx_5.10.72-2.2.0)

 

BR,

Thanks.

0 Kudos
9 Replies

2,412 Views
jimmychan
NXP TechSupport
NXP TechSupport

Regarding the access with memtool the bus error it is caused because the MICFIL module is not clocked until you exercise it. You can first check which is the card assigned to the imxaudiomicfil

root@imx8mp-lpddr4-evk:/unit_tests# arecord -l
**** List of CAPTURE Hardware Devices ****
...
card 1: imxaudiomicfil [imx-audio-micfil], device 0: micfil hifi snd-soc-dummy-dai-0 [micfil hifi snd-soc-dummy-dai-0]
Subdevices: 1/1
Subdevice #0: subdevice #0
...

Do a record on the background and now the MICFIL registers should be accesible

root@imx8mp-lpddr4-evk:/unit_tests# arecord -Dhw:1,0 -fS32_LE -r48000 -c4 test.wav &
Recording WAVE 'test.wav' : Signed 32 bit Little Endian, Rate 48000 Hz, Channels 4
root@imx8mp-lpddr4-evk:/unit_tests# ./memtool -32 0x30ca0000 1
Reading 0x1 count starting at address 0x30CA0000
0x30CA0000: 2100000F

root@imx8mp-lpddr4-evk:/unit_tests# pkill arecord

Dont forget to kill the arecord application.

0 Kudos

2,413 Views
jimmychan
NXP TechSupport
NXP TechSupport

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

 
jimmychan_0-1648538031886.png

 

 

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; /* kfactor = 0.5 */
               break;
       case MICFIL_MEDIUM_QUALITY:
       case MICFIL_VLOW0_QUALITY:
               bclk = rate * 4 * osr * 1; /* kfactor = 1 */
               break;
       case MICFIL_LOW_QUALITY:
       case MICFIL_VLOW1_QUALITY:
               bclk = rate * 2 * osr * 2; /* kfactor = 2 */
               break;
       case MICFIL_VLOW2_QUALITY:
               bclk = rate * osr * 4; /* kfactor = 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)
{
.. .
       /* set CICOSR */
       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

 

0 Kudos

2,410 Views
ESK
Contributor I

First of all, thank you for the detail information.

I have one more question.

=============================================================

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

=============================================================

When I check "amixer -c 1 cget name='MICFIL Quality Select'"

ESK_0-1648539219709.png

I already know, the Mic-fil set 'High Quality' using register set.

But amixer set values=6 'VLow0' as a default. Is it need to modify?

 

0 Kudos

2,408 Views
jimmychan
NXP TechSupport
NXP TechSupport

Yes, need.

0 Kudos

2,406 Views
ESK
Contributor I

When I change that using "amixer -c 1 cset name='MICFIL Quality Select' 1" for test,

PDM mic does not work......

How do I fix it?

0 Kudos

2,385 Views
jimmychan
NXP TechSupport
NXP TechSupport

Does it work well for the other values? Or it only fail with value=1?

What is the failure? Does it throw you an error?

 

We did a test and it is working on all the levels on our side.

How are you recording, which command are you using to record?

0 Kudos

2,379 Views
ESK
Contributor I

Dear NXP team,

Sorry, I can't attach files because of our security program.

 

working invironment : imx8mp-evk + PDM mic(SPG08P4HM4H-1 * 2ea)

test command : arecord -f S16_LE -D plughw:1,0 -t wav -r 48000 -c 2 -d 10 -vvv ./sample.wav

 

case1) "MICFIL Quality Select" "VLow0"(default) : working good (no noise)
            

ESK_0-1648723861221.png

ESK_1-1648724026107.png

ESK_2-1648724075144.png

 

case2) set "MICFIL Quality Select" to "HIGH" : NG (high noise)

ESK_3-1648724275776.png

ESK_4-1648724953579.png

ESK_5-1648724998401.png

0 Kudos

2,318 Views
jimmychan
NXP TechSupport
NXP TechSupport

I got the expert AE reply:

===============

I tried on 8Mplus but not able to reproduce the noise issue. Noticed you are using format S16_LE, micfil on 8Mplus outputs S32_LE, so maybe try to do the arecord bypassing the plug element on your pipeline. The plug element will perform format convertion from S16_LE to S32_LE and this extra process might be adding some artifacts, maybe not as severe as the noise you are observing but I will advise to try without the plug.

Try something like:

 arecord -f S32_LE -D hw:1,0 -t wav -r 48000 -c 2 -d 10 -vvv

===============

Best regards,

Jimmy

 

0 Kudos

2,340 Views
augustl
Contributor III

Hello,

We see this same issue on i.MX8MN SoC. Setting quality "High" introduces tons of more noise.

Br
August

0 Kudos