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
Solved! Go to Solution.
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);
}
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
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);
}
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
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
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
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