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

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

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

跳至解决方案
1,611 次查看
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

标记 (4)
0 项奖励
1 解答
1,577 次查看
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 项奖励
7 回复数
1,595 次查看
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 项奖励
1,578 次查看
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 项奖励
1,568 次查看
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 项奖励
1,591 次查看
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 项奖励
1,582 次查看
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 项奖励
1,597 次查看
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 项奖励
1,604 次查看
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 项奖励