Is there a way to allow setting of a 24MHz frequency to the extperiph3 (CAM2_MCLK, TX2 pin #E7) output ?
We currently face two issues:
- it seems that programming is capped to 19.2MHz by max_rate
- it is not properly set from within the camera framework - always starts at 19.2 MHz, no matter what mclk_khz we specify in the DT
Changing the frequency by hand using /sys/kernel/debug/bpmp/debug/clk after the boot works (within the limits)
The other two clock output pins do work correctly.
Did you check the /sys/kernel/debug/bpmp/debug/clk/extperiph1/rate?
Yes, the 1 and 2 are okay, the 3 is the only one wrong:
# cat /sys/kernel/debug/bpmp/debug/clk/extperiph{1,2,3,4}/rate
24000000
24000000
19200000
19200000
Furthermore the limits are:
# for i in 1 2 3 4 ; do echo `cat /sys/kernel/debug/bpmp/debug/clk/extperiph$i/{min,max}_rate`; done
3175097 37090909
3175097 37090909
149416 19200000
149416 19200000
We are running R28.1 on TX2
Another issue is: When I request 12MHz clock from DT, the rates are 12M, 12M, 19.2M, 19.2M. Third clock just does not behave same as the first two do.
How do you request 12MHz clock from DT for extperiph3/extperiph4
There is a binding of clock per each sensor:
$ cat tegra186-camera-generated.dtsi | grep -iC 2 periph
compatible = "nvidia,imx377";
reg = <0x1a>;
clocks = <&tegra_car TEGRA186_CLK_EXTPERIPH2>, <&tegra_car TEGRA186_CLK_PLLP_OUT0>;
clock-names = "extperiph2", "pllp_grtba";
mclk = "extperiph2";
reset-gpios = <&tegra_main_gpio CAM1_PWDN GPIO_ACTIVE_HIGH>;
devnode = "video0";
--
compatible = "nvidia,imx377";
reg = <0x1a>;
clocks = <&tegra_car TEGRA186_CLK_EXTPERIPH1>, <&tegra_car TEGRA186_CLK_PLLP_OUT0>;
clock-names = "extperiph1", "pllp_grtba";
mclk = "extperiph1";
reset-gpios = <&tegra_main_gpio CAM0_PWDN GPIO_ACTIVE_HIGH>;
devnode = "video1";
--
compatible = "nvidia,imx377";
reg = <0x1a>;
clocks = <&tegra_car TEGRA186_CLK_EXTPERIPH3>, <&tegra_car TEGRA186_CLK_PLLP_OUT0>;
clock-names = "extperiph3", "pllp_grtba";
mclk = "extperiph3";
reset-gpios = <&tegra_main_gpio CAM1_RST_L GPIO_ACTIVE_HIGH>;
devnode = "video2";
And then per each sensor, in each mode we have the frequency defined (totally 3 sensors x 14 mode occurrences, showing just first):
use_sensor_mode_id = "true";
mode0 { /* IMX377_MODE_4104X3046_12BPP_FULL_MODE0_F_12 */
mclk_khz = "12000";
num_lanes = "4";
Of course the 24MHz is the target, I am using 12MHz to figure out whether the clocks are set as I would like.
Could you enable the clk trace to check the extpheriphx
echo 1 > /sys/kernel/debug/tracing/events/clk/clk_set_rate/enable
echo 1 > /sys/kernel/debug/tracing/events/clk/enable
echo 1 > /sys/kernel/debug/tracing/tracing_on
cat /sys/kernel/debug/tracing/trace
hello ShaneCCC
I have same problem,too. now I am using JetPack3.2.1 tegra-l4t-r28.2.1 kernel4.4.38 for jetson TX2. when porting Toshiba TC358743 Linux driver for Tegra X2 using Auvidea’s J120 and B102 (HDMI2CSI), I got the error “Unsupported refclk rate: 19200000 Hz”. J120 uses TX2’s CAM2_CLK(extperiph3) signal for its CSI interface.
my device tree of CAM2_CLK is:
clocks = <&tegra_car TEGRA186_CLK_EXTPERIPH3>,
&tegra_car TEGRA186_CLK_PLLP_OUT0>;
clock-names = "extperiph3", "pllp_grtba";
mclk = "extperiph3";
refclk_hz = <27000000>;
I set the extperiph3 clock to 27MHz, but finally I get 19.2MHz.
I check the extperiph3 on clk trace using ShaneCCC’s method, but find no infomation about extperiph3.
Then I check the clock status and clk tree:
# cat /sys/kernel/debug/clk/clk_summary
clock enable_cnt prepare_cnt rate req_rate accuracy phase
extperiph3 0 0 19200000 27000000 0 0
# cat /sys/kernel/debug/bpmp/debug/clk/clk_tree
extperiph3 enabled: 0 refcounts: 0,0, rate: 19200000
I am a beginner of jetson. where is the problem of mine? the device tree or the driver code?
@54336869
Please enable the dev_dbg() in kernel/kernel-4.4/drivers/media/platform/tegra/camera/camera_common.c
Also check the dmesg | grep -i camera
[ 2.834743] ov5693 2-0036: mclk in DT extperiph1
[ 2.835304] ov5693 2-0036: camera_common_mclk_enable: enable MCLK with 24000000 Hz
[ 3.635509] ov5693 2-0036: camera_common_mclk_disable: disable MCLK
[ 3.635596] ov5693 2-0036: camera_common_mclk_enable: enable MCLK with 24000000 Hz
[ 3.706032] ov5693 2-0036: camera_common_mclk_disable: disable MCLK
[ 7.612936] ov5693 2-0036: camera_common_mclk_enable: enable MCLK with 24000000 Hz
[ 7.679510] ov5693 2-0036: camera_common_mclk_disable: disable MCLK
diff --git a/drivers/media/platform/tegra/camera/camera_common.c b/drivers/media/platform/tegra/camera/camera_common.c
index 625fa06..e8e9b78 100644
--- a/drivers/media/platform/tegra/camera/camera_common.c
+++ b/drivers/media/platform/tegra/camera/camera_common.c
@@ -15,6 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#define DEBUG
#include <linux/types.h>
#include <media/tegra-v4l2-camera.h>
#include <media/camera_common.h>
@ShaneCCC
I am using driver: kernel/kernel-4.4/drivers/media/i2c/tc358743.c. It does not call functions in /drivers/media/platform/tegra/camera/camera_common.c
# dmesg | grep -i camera
[0.418585] tegra_camera_platform tegra_camera_platform: tegra_camera_probe:camera_platform_driver probe
[0.418670] misc tegra_camera_ctrl: tegra_camera-isomgr_register isp_iso_bw=1020000, vi_iso_bw=2812500, max_bw=2812500
@54336869
If your driver didn’t call the camera_common.c set mclk function. You need to set it from your driver if your device need this clock.
I set the mclk by calling the function: clk_set_rate(refclk,27000000); but the result of extperiph3 clk rate is 19200000
#dmesg | grep tc358743
[2.967114] tc358743 7-000f:unsupported refclk rate:19200000 Hz
[2.967206] tc358743: probe of 7-000f failed with error -22
@54336869
What’s the value of max rate? “cat /sys/kernel/debug/bpmp/debug/clk/extperiph3/max_rate”
@ShaneCCC
Thanks for your help!
I have found the problem. It’s all because of the clk source. I didn’t set the clk source of extperiph3 at first, so it uses the default clk source(CLK_M). I guess the clk rate of CLK_M is 19.2MHz. so the max rate of extperiph3 I can get is also 19.2MHz. Now I change the clk source to PLLP_OUT0, and it works! I set the clk rate of extperiph3 to 27000000Hz,then I get the result clk rate of 27200000Hz.
Old driver source:
refclk = devm_clk_get(dev, "extperiph3");
if (IS_ERR(refclk)) {
dev_err(dev, "unable to get clock %s\n", "extperiph3");
return PTR_ERR(refclk);
}
error = clk_set_rate(refclk,27000000);
if(!error)
error = clk_prepare_enable(refclk);
New driver source:
refclk = devm_clk_get(dev, "extperiph3");
if (IS_ERR(refclk)) {
dev_err(dev, "unable to get clock %s\n", "extperiph3");
return PTR_ERR(refclk);
}
parent = devm_clk_get(dev, "pllp_grtba");
if (IS_ERR(parent)) {
dev_err(dev, "unable to get parent clcok %s", "pllp_grtba");
} else
clk_set_parent(refclk, parent);
error = clk_set_rate(refclk,27000000);
if(!error)
error = clk_prepare_enable(refclk);