Hi,
I'm bringing up a i.MX6sl board that gets interfaced using the EIM bus to a FPGA. The FPGA application runs purely in userspace. This application works but we're finding that the EIM bus cycle timing is changing dynamically resulting in sporadic failures.
After debugging, I found the following:
root@freescale ~$ mount -t debugfs debugfs /sys/kernel/debug
root@freescale ~$ find /sys/kernel/debug/clock -name \*emi\*
/sys/kernel/debug/clock/osc_clk/pll2_528_bus_main_clk/pll2_pfd2_400M/periph_clk/axi_clk/emi_slow_clk
_pfd2_400M/periph_clk/axi_clk/emi_slow_clk/rate c_clk/pll2_528_bus_main_clk/pll2_
8000000
_pfd2_400M/periph_clk/axi_clk/emi_slow_clk/rate c_clk/pll2_528_bus_main_clk/pll2_
8000000
_pfd2_400M/periph_clk/axi_clk/emi_slow_clk/rate c_clk/pll2_528_bus_main_clk/pll2_
66000000
_pfd2_400M/periph_clk/axi_clk/emi_slow_clk/rate c_clk/pll2_528_bus_main_clk/pll2_
66000000
_pfd2_400M/periph_clk/axi_clk/emi_slow_clk/rate c_clk/pll2_528_bus_main_clk/pll2_
8000000
_pfd2_400M/periph_clk/axi_clk/rate c_clk/pll2_528_bus_main_clk/pll2_
198000000
_pfd2_400M/periph_clk/axi_clk/rate ebug/clock/osc_clk/pll2_528_bus_main_clk/pll2_
24000000
Above shows that the EIM clock (which is called EMI slow clock) is switching between 66MHz and 80MHz. This appears to be because the parent clock, AXI clock is itself switching between 198MHz and 24MHz.
Going up further shows the parent of AXI clock, periph clock is also changing:
24000000
_pfd2_400M/periph_clk/rate kernel/debug/clock/osc_clk/pll2_528_bus_main_clk/pll2_
24000000
root@freescale ~$
root@freescale ~$
_pfd2_400M/periph_clk/rate kernel/debug/clock/osc_clk/pll2_528_bus_main_clk/pll2_
396000000
_pfd2_400M/periph_clk/rate kernel/debug/clock/osc_clk/pll2_528_bus_main_clk/pll2_
396000000
_pfd2_400M/periph_clk/rate kernel/debug/clock/osc_clk/pll2_528_bus_main_clk/pll2_
24000000
I am doing the following in the board file:
clk = clk_get(NULL, "emi_slow_clk");
if (IS_ERR(clk))
printk(KERN_ERR "emi_slow_clk not found\n");
printk(KERN_ERR "checking EMI slow clock rate to be 66MHz\n");
rate = clk_get_rate(clk);
clk_enable(clk);
if (rate != (66*1000*1000)) {
printk(KERN_ERR "Warning: trying to set emi_slow_clk to 66MHz again\n");
ret = clk_set_rate(clk, clk_round_rate(clk, 66000000));
printk(KERN_ERR "ret=%d, newrate=%d\n", clk_get_rate(clk));
}
But it does not look like this is sufficient to prevent the system from changing AXI clock underneath this.
I have already disabled CPUFREQ. I do not appear to be able to disable DVFS from the kernel config.
I've disabled CPUFREQ in the kernel. I couldn't find a way to easily
disable DVFS.
lucid@ubuntu:~/6sl/ltib/rpm/BUILD/linux-3.0.35$ egrep FREQ .config
CONFIG_ARCH_HAS_CPUFREQ=y
# CONFIG_CPU_FREQ is not set
lucid@ubuntu:~/6sl/ltib/rpm/BUILD/linux-3.0.35$ egrep DVFS .config
CONFIG_IMX_HAVE_PLATFORM_IMX_DVFS=y
lucid@ubuntu:~/6sl/ltib/rpm/BUILD/linux-3.0.35$ egrep RUNTIME .config
# CONFIG_PM_RUNTIME is not set
I suspect arch/arm/mach-mx6/bus_freq.c
reduce_bus_freq or one of the other functions is what is manipulating this. But I don't see a way to disable this. I'd be grateful for any suggestions/advice.
Thanks
jayakumar
已解决! 转到解答。
Ah, found an ugly solution:
Just force bus_freq to fail.
bus_freq_scaling_is_active = 0;
Linux clock api needs improvement to handle this kind of stuff cleanly.