msm8953 - configure I2C speed

foreword

This article records the records made when debugging an I2C device communication exception on the Qualcomm platform and trying to modify the I2C clock rate.

Platform: MSM8953.

System: Android 9.0

Category: I2C CLK

in conclusion

Let me talk about the conclusion first. After analysis and verification, the I2C features supported by the platform are as follows.

Default speed: 100K.

Support speed: 100K, 400K, 1M

Support range: 50K ~ 1M

Register description

The period and rate of CLK can be determined by configuring the register of the high and low level duration of I2C CLK.

The register description is as follows

It can be seen from here that since the high and low level configuration registers are all 8bit, the maximum value is 255.

According to the current clock source 19.2M, fs_div = 2hs_div, the minimum clock rate is:

clk-Min = 19.2 M / (255 + 255/2 + 6 ) = 49.42K, rounded to 50K

Calculation formula

I2C_FS_CLK = I2C_CLK/(fs_div+hs_div+6)

Here, I2C_CLK is 19200000,19.2M

100K CLK configuration example:

19.2M (CXO) /100K(transfer rate) = fs_div+hs_div+6

In general fs_div = 2hs_div

That's why the default 100K configuration is: 124/62, fs_div+hs_div+6 = 192.

code modification

dts node configuration

kernel\msm-4.9\arch\arm64\boot\dts\nwy\XXX_msm8953.dtsi

The I2C node is modified to 50K configuration as follows:

	i2c_3: i2c@78b7000 { /* BLSP1 QUP3 */
		compatible = "qcom,i2c-msm-v2";
		#address-cells = <1>;
		#size-cells = <0>;
		reg-names = "qup_phys_addr";
		reg = <0x78b7000 0x600>;
		interrupt-names = "qup_irq";
		interrupts = <0 97 0>;
-       qcom,clk-freq-out = <400000>; // 默认400K
+		qcom,clk-freq-out = <50000>;  // 修改为 50K 输出
		qcom,clk-freq-in  = <19200000>;
		clock-names = "iface_clk", "core_clk";
		clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>,
			<&clock_gcc clk_gcc_blsp1_qup3_i2c_apps_clk>;

		pinctrl-names = "i2c_active", "i2c_sleep";
		pinctrl-0 = <&i2c_3_active>;
		pinctrl-1 = <&i2c_3_sleep>;
		qcom,noise-rjct-scl = <0>;
		qcom,noise-rjct-sda = <0>;
		qcom,fs-clk-div = <252>;         // clk High 电平持续时间,非必须项
		qcom,high-time-clk-div = <126>;  // clk Low  电平持续时间,非必须项
		qcom,master-id = <86>;
		dmas = <&dma_blsp1 8 64 0x20000020 0x20>,
			<&dma_blsp1 9 32 0x20000020 0x20>;
		dma-names = "tx", "rx";
		status = "disabled";
	};

I2C driver files add clk table

8953_APP_P\kernel\msm-4.9\drivers\i2c\busses\i2c-msm-v2.c

This table is the currently supported I2C rate, and the corresponding high and low level duration parameters. [Refer to the previous chapter for parameter configuration]

If there is no required rate, add a new group, such as adding 50M rate.

/*
 * divider values as per HW Designers
 */
static struct i2c_msm_clk_div_fld i2c_msm_clk_div_map[] = {
+	{KHz(50), 252, 126},
	{KHz(100), 124, 62},
	{KHz(400),  28, 14},
	{KHz(1000),  8,  5},
};

references

80-NU767-1_LINUX BAM LOW-SPEED PERIPHERALS CONFIGURATION AND DEBUG GUIDE.pdf

I saw my hometown in the catkins flying

Guess you like

Origin blog.csdn.net/FANG_YISHAO/article/details/125080378
I2C