i.MX8QXP: how to change ADMA SPI1 clock frequency over 12 MHz?

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

i.MX8QXP: how to change ADMA SPI1 clock frequency over 12 MHz?

Jump to solution
2,617 Views
EAlepins
Contributor V

Hi,

I'm trying to increase the SPI1 peripheral clock to 25MHz (SPI in Audio DMA subsystem). The LPSPI CCR register configures a divider of 2, so peripheral clock needs to be 50 MHz in my understanding.

Calling

err = sc_pm_set_clock_rate(l_i_mu_vaddr, SC_R_SPI_1, SC_PM_CLK_PER, &sc_rate);

works up to 24 000 000 (err=SC_ERR_NONE=0), above which we get SC_ERR_PARM=3. I guess this is because as shown in i.MX 8X reference manual ADMA subsystem "Figure 8-3. Clock Tree", the clock mux driving ADMA_SSSLICE5_CLK_ROOT (SPI1) is probably the 24 MHz XTAL. So I tried to change that mux to rather select the 1280MHz System PLL (DIG_PLL0). Is this done through SCFW API sc_pm_set_clock_parent()? When I try to read the current parent:

sc_pm_clk_parent_t parent;
err = sc_pm_clock_enable(l_i_mu_vaddr, SC_R_SPI_1, SC_PM_CLK_PER, FALSE, FALSE);
err = sc_pm_get_clock_parent(l_i_mu_vaddr, SC_R_SPI_1, SC_PM_CLK_PER, &parent);

I get a parent of 255 ... which does not exist in the documentation!

Then, I try to set the parent:

parent = SC_PM_PARENT_PLL0;
err = sc_pm_set_clock_parent(l_i_mu_vaddr, SC_R_SPI_1, SC_PM_CLK_PER, &parent);

but I get the SC_ERR_PARM=3 error...

Please help! Thanks,

Étienne

Tags (4)
0 Kudos
Reply
1 Solution
2,583 Views
joanxie
NXP TechSupport
NXP TechSupport

for the function sc_pm_set_clock_parent(l_i_mu_vaddr, SC_R_SPI_1, SC_PM_CLK_PER, &parent); the parent isn't pointer, pls try the blow code I got from internal team, should fix your issue

#define REQUESTED_SPI1_RATE 50*1000*1000

int main(void)

{

    sc_pm_clock_rate_t lpspi1_clock_rate = REQUESTED_SPI1_RATE;

    sc_err_t err;

 

    /* Board pin, clock, debug console init */

    sc_ipc_t ipc;

    ipc = BOARD_InitRpc();

    BOARD_InitPins(ipc);

    BOARD_BootClockRUN();

    BOARD_InitMemory();

    BOARD_InitDebugConsole();

 

    if (sc_pm_set_resource_power_mode(ipc, SC_R_SPI_1, SC_PM_PW_MODE_ON) != SC_ERR_NONE)

    {

        PRINTF("Error: Failed to power on LPSPI1.\r\n");

        return -1;

    }

 

    err = sc_pm_clock_enable(ipc, SC_R_SPI_1, SC_PM_CLK_PER, 0, 0);

    PRINTF("SPI1 clock disabled (%d)\r\n", err);

    err = sc_pm_set_clock_parent(ipc, SC_R_SPI_1, SC_PM_CLK_PER, SC_PM_PARENT_PLL0); /* Last parameter is not a pointer */

    PRINTF("SPI1 clock parent set to PLL (%d)\r\n", err);

    err = sc_pm_set_clock_rate(ipc, SC_R_SPI_1, SC_PM_CLK_PER, &lpspi1_clock_rate);

    PRINTF("SPI1 clock rate set to %d (%d requested) (%d) \r\n", lpspi1_clock_rate, REQUESTED_SPI1_RATE, err);

    err = sc_pm_clock_enable(ipc, SC_R_SPI_1, SC_PM_CLK_PER, 1, 0);

    PRINTF("SPI1 clock enabled (%d)\r\n", err);

 

   while(1);

}

View solution in original post

0 Kudos
Reply
7 Replies
2,601 Views
EAlepins
Contributor V

Hi,

For information, the following code works (we see ~49 MHz SPI clock on oscilloscope):

err = sc_pm_clock_enable(l_i_mu_vaddr, SC_R_SPI_1, SC_PM_CLK_PER, FALSE, FALSE);
sc_pm_clk_parent_t parent;
parent = SC_PM_PARENT_PLL1;
err = sc_pm_set_clock_parent(l_i_mu_vaddr, SC_R_SPI_1, SC_PM_CLK_PER, &parent);
sc_rate = SC_50MHZ;
err = sc_pm_set_clock_rate(l_i_mu_vaddr, SC_R_SPI_1, SC_PM_CLK_PER, &sc_rate);
sc_pm_clock_enable(l_i_mu_vaddr, SC_R_SPI_1, SC_PM_CLK_PER, TRUE, TRUE);

However, the call to sc_pm_set_clock_parent() and sc_pm_set_clock_rate() return SC_ERR_PARAM=3, which seems to indicate the calls had no effect, but that is false: without that sc_pm_set_clock_parent() call, sc_pm_set_clock_rate() keeps the clock at 24 MHz; with it, it returns a clock rate of 49230769 Hz (almost the asked 50 MHz).

Is there a bug in the SCFW? It should not return errors.

Thanks,

Étienne

0 Kudos
Reply
2,584 Views
joanxie
NXP TechSupport
NXP TechSupport

for the function sc_pm_set_clock_parent(l_i_mu_vaddr, SC_R_SPI_1, SC_PM_CLK_PER, &parent); the parent isn't pointer, pls try the blow code I got from internal team, should fix your issue

#define REQUESTED_SPI1_RATE 50*1000*1000

int main(void)

{

    sc_pm_clock_rate_t lpspi1_clock_rate = REQUESTED_SPI1_RATE;

    sc_err_t err;

 

    /* Board pin, clock, debug console init */

    sc_ipc_t ipc;

    ipc = BOARD_InitRpc();

    BOARD_InitPins(ipc);

    BOARD_BootClockRUN();

    BOARD_InitMemory();

    BOARD_InitDebugConsole();

 

    if (sc_pm_set_resource_power_mode(ipc, SC_R_SPI_1, SC_PM_PW_MODE_ON) != SC_ERR_NONE)

    {

        PRINTF("Error: Failed to power on LPSPI1.\r\n");

        return -1;

    }

 

    err = sc_pm_clock_enable(ipc, SC_R_SPI_1, SC_PM_CLK_PER, 0, 0);

    PRINTF("SPI1 clock disabled (%d)\r\n", err);

    err = sc_pm_set_clock_parent(ipc, SC_R_SPI_1, SC_PM_CLK_PER, SC_PM_PARENT_PLL0); /* Last parameter is not a pointer */

    PRINTF("SPI1 clock parent set to PLL (%d)\r\n", err);

    err = sc_pm_set_clock_rate(ipc, SC_R_SPI_1, SC_PM_CLK_PER, &lpspi1_clock_rate);

    PRINTF("SPI1 clock rate set to %d (%d requested) (%d) \r\n", lpspi1_clock_rate, REQUESTED_SPI1_RATE, err);

    err = sc_pm_clock_enable(ipc, SC_R_SPI_1, SC_PM_CLK_PER, 1, 0);

    PRINTF("SPI1 clock enabled (%d)\r\n", err);

 

   while(1);

}

0 Kudos
Reply
2,574 Views
EAlepins
Contributor V

Thanks! You were right: the problem was that had passed the parent by address... When changed by value, all error codes are back to 0.

Étienne

0 Kudos
Reply
2,597 Views
joanxie
NXP TechSupport
NXP TechSupport

let me confirm again, did you enable lpspi1 in your dts file? the default dtsi file disable this according to the link I sent to you, did you set it, pls set the clock in the dts file and test again

0 Kudos
Reply
2,588 Views
EAlepins
Contributor V

Hi,

We are not using DTS file because we are not using Linux. However, I think DTS parsing calls SCFW, so we end up to the same point. Note the last function call in our sequence (sc_pm_clock_enable) which enables the clock, so I think we are enabled. Anyway, we DO see SPI clock to ~25 MHz on i.MX output pin.

My main question now is regarding the return code returned by SCFW calls. Is this normal? Is this an SCFW bug?

Thanks,

Étienne

0 Kudos
Reply
2,603 Views
EAlepins
Contributor V

Hi,

Ok, but isn't getting SC_ERR_PARAM=3 a bad thing or it is normal?

We tested and changing the rate above 24 MHz has no effect: SPI1 freq stays at ~12 MHz (as seen on oscilloscope).

Étienne

0 Kudos
Reply
2,610 Views
joanxie
NXP TechSupport
NXP TechSupport
you can refer to the dtsi file "https://source.codeaurora.org/external/imx/linux-imx/tree/arch/arm64/boot/dts/freescale/imx8-ss-dma...." lpspi1: spi@5a010000 { compatible = "fsl,imx7ulp-spi"; reg = <0x5a010000 0x10000>; #address-cells = <1>; #size-cells = <0>; interrupts = ; interrupt-parent = <&gic>; clocks = <&spi1_lpcg 0>, <&spi1_lpcg 1>; clock-names = "per", "ipg"; assigned-clocks = <&clk IMX_SC_R_SPI_1 IMX_SC_PM_CLK_PER>; assigned-clock-rates = <60000000>; power-domains = <&pd IMX_SC_R_SPI_1>; dma-names = "tx","rx"; dmas = <&edma2 3 0 0>, <&edma2 2 0 1>; status = "disabled"; }; current lpspi1 clock is set to 60M, the minimal frequency for LPSPI could be ~41MHz. if you set under 41Mhz, you should get SC_ERR_PARM=3 error
0 Kudos
Reply