CAM2_MCLK weird behaviour

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);