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

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

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

跳至解决方案
2,113 次查看
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 解答
2,079 次查看
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 回复数
2,097 次查看
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 项奖励
回复
2,080 次查看
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 项奖励
回复
2,070 次查看
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 项奖励
回复
2,093 次查看
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 项奖励
回复
2,084 次查看
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 项奖励
回复
2,099 次查看
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 项奖励
回复
2,106 次查看
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 项奖励
回复