Rockchip RK3588 MIPI-DSI2 详解_rk3588 mipi dsi 详解

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

如果你需要这些资料,可以戳这里获取

&dsi1_in_vp2 {
status = “okay”;
};

&dsi1_in_vp3 {
status = “disabled”;
};


### 开机LOGO


#### route\_dsi0


例如 vp3->dsi0 或 vp3->dsc0->dsi0:



&route_dsi0 {
status = “okay”;
connect = <&vp3_out_dsi0>;
};


#### route\_dsi1


例如 vp2->dsi1 或 vp2->dsc1->dsi1:



&route_dsi1 {
status = “okay”;
connect = <&vp2_out_dsi1>;
};


#### route\_dsi0 && route\_dsi1


例如 (vp3->dsi0 或 vp3->dsc0->dsi0) && (vp2->dsi1 或 vp2->dsc1->dsi1):



&route_dsi0 {
status = “okay”;
connect = <&vp3_out_dsi0>;
};

&route_dsi1 {
status = “okay”;
connect = <&vp2_out_dsi1>;
};


### DSI HOST


**ports**  
 以下实例中 ports 是用来 Dispaly Interface 和 panel 之间进行关联。  
 详细配置说明参阅如下文档:



Documentation/devicetree/bindings/graph.txt


#### 单 DSI


![在这里插入图片描述](https://img-blog.csdnimg.cn/0a96b1d210c24171889ae3fe6414c0be.png#pic_center)


##### DSI0



&dsi0 {
status = “okay”;
//rockchip,lane-rate = <1000>;
dsi0_panel: panel@0 {
status = “okay”;
compatible = “simple-panel-dsi”;

	ports {
		#address-cells = <1>;
		#size-cells = <0>;

		port@0 {
			reg = <0>;
			panel_in_dsi: endpoint {
				remote-endpoint = <&dsi_out_panel>;
			};
		};
	};
};

ports {
	#address-cells = <1>;
	#size-cells = <0>;

	port@1 {
		reg = <1>;
		dsi_out_panel: endpoint {
			remote-endpoint = <&panel_in_dsi>;
		};
	};
};

};

&mipi_dcphy0 {
status = “okay”;
};


##### DSI1



&dsi1 {
status = “okay”;
//rockchip,lane-rate = <1000>;
dsi1_panel: panel@0 {
status = “okay”;
compatible = “simple-panel-dsi”;

	ports {
		#address-cells = <1>;
		#size-cells = <0>;

		port@0 {
			reg = <0>;
			panel_in_dsi1: endpoint {
				remote-endpoint = <&dsi1_out_panel>;
			};
		};
	};
};

ports {
	#address-cells = <1>;
	#size-cells = <0>;

	port@1 {
		reg = <1>;
		dsi1_out_panel: endpoint {
			remote-endpoint = <&panel_in_dsi1>;
		};
	};
};

};

&mipi_dcphy1 {
status = “okay”;
};


#### 双通道 DSI


MODE1:


![在这里插入图片描述](https://img-blog.csdnimg.cn/d64363329d934b4a8e5e068908d564cb.png#pic_center)


MODE2:


![在这里插入图片描述](https://img-blog.csdnimg.cn/73038ad71055457892e6860fa9fe8b44.png#pic_center)


双通道的配置注意如下标红属性:  
 rockchip,dual-channel = <&dsi1>  
 dsi,lanes = <8>;//DPHY 屏, CPHY 屏值改成 6 



&dsi0 {
status = “okay”;
rockchip,dual-channel = <&dsi1>;

dsi0_panel {
	status = "okay";
	compatible = "simple-panel-dsi";
	dsi,lanes  = <8>;
	...

	display-timings {
		native-mode = <&timing0>;

		timing0: timing0 {
			clock-frequency = <260000000>;
			hactive = <1440>;
			vactive = <2560>;
			hfront-porch = <150>;
			hsync-len = <30>;
			hback-porch = <60>;
			vfront-porch = <8>;
			vsync-len = <4>;
			vback-porch = <4>;
			hsync-active = <0>;
			vsync-active = <0>;
			de-active = <0>;
			pixelclk-active = <0>;
		};
	};

	ports {
		#address-cells = <1>;
		#size-cells = <0>;

		port@0 {
			reg = <0>;
			panel_in_dsi0: endpoint {
				remote-endpoint = <&dsi0_out_panel>;
			};
		};
	};
};

ports {
	#address-cells = <1>;
	#size-cells = <0>;

	port@1 {
		reg = <1>;
		dsi0_out_panel: endpoint {
			remote-endpoint = <&panel_in_dsi0>;
		};
	};
};

};

&dsi1 {
status = “okay”;
};

&mipi_dcphy0 {
status = “okay”;
};

&mipi_dcphy1 {
status = “okay”;
};


#### Dual-link DSI


![在这里插入图片描述](https://img-blog.csdnimg.cn/72a971179853423486249698f850b353.png#pic_center)



&dsi0 {
status = “okay”;
//rockchip,lane-rate = <1000>;
dsi0_panel: panel@0 {
status = “okay”;
compatible = “simple-panel-dsi”;

	ports {
		#address-cells = <1>;
		#size-cells = <0>;

		port@0 {
			reg = <0>;
			panel_in_dsi: endpoint {
				remote-endpoint = <&dsi_out_panel>;
			};
		};
	};
};

ports {
	#address-cells = <1>;
	#size-cells = <0>;

	port@1 {
		reg = <1>;
		dsi_out_panel: endpoint {
			remote-endpoint = <&panel_in_dsi>;
		};
	};
};

};

&dsi1 { status = “okay”;
//rockchip,lane-rate = <1000>;
dsi1_panel: panel@0 {
status = “okay”;
compatible = “simple-panel-dsi”;

	ports {
		#address-cells = <1>;
		#size-cells = <0>;

		port@0 {
			reg = <0>;
			panel_in_dsi1: endpoint {
				remote-endpoint = <&dsi1_out_panel>;
			};
		};
	};
};

ports {
	#address-cells = <1>;
	#size-cells = <0>;

	port@1 {
		reg = <1>;
		dsi1_out_panel: endpoint {
			remote-endpoint = <&panel_in_dsi1>;
		};
	};
};

};

&mipi_dcphy0 {
status = “okay”;
};

&mipi_dcphy1 {
status = “okay”;
};


### DCPHY


实际应用配置中默认是配置成D-PHY,通过屏端配置介绍可知,通过下面可以配置成 C-PHY:



dsi0_panel: panel@0 {

phy-c-option;

};


#### D-PHY


![在这里插入图片描述](https://img-blog.csdnimg.cn/30f139c4071c4fc5b297a7a79a3b969f.png#pic_center)


1. Up to 4.5 Gbps per lane in D-PHY  
 2. 一个D-PHY port 最多4lanes,每个lane由两条差分线组成


#### C-PHY


![在这里插入图片描述](https://img-blog.csdnimg.cn/3aef49b6ad7a4af6814bf6a19211f4c8.png#pic_center)


1. Up to 2.0 Gsps per trio in C-PHY  
 2. 一个C-PHY port 最多3lanes,每个lane由 tree-wire-trios 组成


### 协议分析


#### DSI Layer Definitions


![在这里插入图片描述](https://img-blog.csdnimg.cn/1bdf13d2820244538d0469c20f405aee.png#pic_center)


#### D Option


##### Lane states and line levels


![在这里插入图片描述](https://img-blog.csdnimg.cn/fd4081c8822741308ceca362f30b2a77.png#pic_center)


下表罗列在 DPHY Lane 正常操作中可能出现的所有通道状态。


![在这里插入图片描述](https://img-blog.csdnimg.cn/f20239fd81f34a9d8a90d541b0fc3269.png#pic_center)


##### Global Operation Flow Diagram


![在这里插入图片描述](https://img-blog.csdnimg.cn/36463df186534f509bae49f7417fd4e0.png#pic_center)


DSI 数据通道可以驱动到如下三种模式:


1. Escape Mode (只有 Dp0/Dn0 会操作在该模式);
2. Bus Turnaround Request (只有 Dp0/Dn0 会操作在该模式);
3. High-Speed Data Transmission。


这三种模式和它们进入对应模式的序列定义如下:


![在这里插入图片描述](https://img-blog.csdnimg.cn/e886ea0bebe74f2fa7578864358d9de9.png#pic_center)


###### Escape Modes


当数据通道处于 LP 模式,数据通道0用于 Escape Mode, 数据通道应通过 LP-11->LP-10->LP-00->LP-01->LP-00 进入 Escape Mode,通过 LP-00->LP-10->LP-11 退出 Escape Mode.


![在这里插入图片描述](https://img-blog.csdnimg.cn/619eebe7c8db4942a554d962374f8b00.png#pic_center)


###### Escape Commands


一旦数据通道进入 Escape 模式, 发送器应该发送 8-bit Escape Comands 指示请求行为,Escape Comands 如下:


![在这里插入图片描述](https://img-blog.csdnimg.cn/e7a9d8d9bacd4aec9a838297fe5ef742.png#pic_center)


###### LPDT


当数据通道进入 Escape 模式且向显示模块发送 Low-Power Data Transmission(LPDT) 序列,Soc 的 MIPI DSI TX 可以通过 LPDT 模式向显示模块发送数据, 一般就是通过这种方式向 MIPI 显示模块下载初始化序列。


![在这里插入图片描述](https://img-blog.csdnimg.cn/52c5a62e8d794f1ea862677b54b63c0f.png#pic_center)


通过示波器捕获 LPDT 波形如下:


![在这里插入图片描述](https://img-blog.csdnimg.cn/eb541a070a964228a4103e069f10ca1e.png#pic_center)


###### ULPS


![在这里插入图片描述](https://img-blog.csdnimg.cn/a6fde79ecfad4f79a116ca1bc70d2a00.png#pic_center)


###### HSDT


当 DPHY 的时钟通道在高速时钟模式时,显示模块可以进入高速数据传输模式,所有的数据通道同时进入高速数据传输模式,但可以不同时退出高速模式。数据通道通过如下序列进入高速模式:  
 LP-11 -> LP-01 -> LP-00 -> HS-0 -> SoT(0001\_1101).



  1. Start: LP-11
  2. HS-Request: LP-01
  3. HS-Settle: LP-00 -> HS-0 (RX: Lane Termination Enable)
  4. Rx Synchronization: SoT(0001_1101)
  5. End: High-Speed Data Transmission (HSDT) - Ready to receive High-Speed Data Load

数据通道退出高速数据传输模式流程:在最后一个有效负载数据之后立即切换差分状态位并保持该状态一段时间 Ths-trail。


![在这里插入图片描述](https://img-blog.csdnimg.cn/bdab0de99eaf47b68da6c5758575a24e.png#pic_center)


通过示波器捕获 HSDT 波形如下:


![在这里插入图片描述](https://img-blog.csdnimg.cn/e79bf59cbf484230bb11aff02a131f51.png#pic_center)


###### BTA


当需要从显示模块获取信息时,Soc DPHY 的第一数据通道可以通过执行总线翻转步骤。操作步骤如下:


![在这里插入图片描述](https://img-blog.csdnimg.cn/c3dbcb869891445ab4e4606102e3688a.png#pic_center)


通过示波器在 HSDT 时向显示模块回读并捕获 BTA 波形如下:


![在这里插入图片描述](https://img-blog.csdnimg.cn/3b826e67cd6b45b185f449d653d6dce1.png#pic_center)


##### Endian Policy


无论是在 LP 和 HS 数据传输模式,数据都是以长包和短包形式打包并传输给显示模块。


###### SPa


![在这里插入图片描述](https://img-blog.csdnimg.cn/5d6cafdf1ea6405e8b1ac82dfb875549.png#pic_center)


Example:


![在这里插入图片描述](https://img-blog.csdnimg.cn/76091d5b15304014843c4cedcae35340.png#pic_center)


###### LPDT-SPa


通过示波器在 LPDT 时向显示模块发送如上 SPa 并捕获波形如下:


![在这里插入图片描述](https://img-blog.csdnimg.cn/7beb6c43add24d4991cf9da688602fb7.png#pic_center)


###### HSDT-SPa


通过示波器在 HSDT 时向显示模块发送如上 SPa 并捕获波形如下:


![在这里插入图片描述](https://img-blog.csdnimg.cn/5c3a5b6b75d947b9b9da910837007530.png#pic_center)


###### LPa


![在这里插入图片描述](https://img-blog.csdnimg.cn/f2ec6c3a82f74ef2aa62667552c53060.png#pic_center)


Example:  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/c49f85b041864736ad3b983cfeb19d23.png#pic_center)


###### LPDT-LPa


通过示波器在 LPDT 时向显示模块发送如上 LPa 并捕获波形如下:


![在这里插入图片描述](https://img-blog.csdnimg.cn/359363c6ccd143d2b3106fd389d97948.png#pic_center)


###### HSDT-LPa


通过示波器在 HSDT 时向显示模块发送如上 LPa 并捕获波形如下:


![在这里插入图片描述](https://img-blog.csdnimg.cn/4f99c9896e944ad1ad0783d4fad39ee2.png#pic_center)


###### DI


如上 SPa 和 LPa 中都有一个 Data Identification (DI), 一个包是长短包就是由 DI 决定,DI 是包头的一部分,由两个部分组成:


![在这里插入图片描述](https://img-blog.csdnimg.cn/b8d1ba898fb14e17b1ef4cffef1aae5a.png#pic_center)


MIPI 协议中目前定义的绝大部分数据类型如下:  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/6a375a942c9d4b95bc0f296da936d78c.png#pic_center)


##### Video Mode Interface Timing


###### Horizontal Display Timing (Video mode)


![在这里插入图片描述](https://img-blog.csdnimg.cn/549122a8fb2444e4ba0c3ddb11975f1d.png#pic_center)


###### Non-Burst Mode with Sync Pulses


![在这里插入图片描述](https://img-blog.csdnimg.cn/ceaee687f8824afe8d70018cab07b4f0.png#pic_center)


通过示波器捕获 Non Burst Sync Pulse 波形如下:


![在这里插入图片描述](https://img-blog.csdnimg.cn/5a8297ba2a9f4e5fb99c1d146c4ff711.png#pic_center)


###### Burst Mode


![在这里插入图片描述](https://img-blog.csdnimg.cn/df04599b0d5e4e6383cadcb329c8f3b9.png#pic_center)


通过示波器捕获 Video Burst 波形如下:


![在这里插入图片描述](https://img-blog.csdnimg.cn/5ff053265b0242918b2b73b5c243ca72.png#pic_center)


### 常见问题


#### 查看VOP timing 和 Connector 信息



console:/ # cat /d/dri/0/summary
Video Port0: DISABLED
Video Port1: DISABLED
Video Port2: DISABLED
Video Port3: ACTIVE
Connector: DSI-2
bus_format[100a]: RGB888_1X24
overlay_mode[0] output_mode[0] color_space[0]
Display mode: 1080x1920p60
clk[132000] real_clk[132000] type[48] flag[a]
H: 1080 1095 1099 1129
V: 1920 1935 1937 1952
Cluster3-win0: ACTIVE
win_id: 6
format: AB24 little-endian (0x34324241) SDR[0] color_space[0] glb_alpha[0xff]
rotate: xmirror: 0 ymirror: 0 rotate_90: 0 rotate_270: 0
csc: y2r[0] r2y[0] csc mode[0]
zpos: 0
src: pos[0, 0] rect[1080 x 1920]
dst: pos[0, 0] rect[1080 x 1920]
buf[0]: addr: 0x000000000376e000 pitch: 4352 offset: 0


#### 查看 DSI2 相关 clk tree



console:/ # cat /d/clk/clk_summary | grep vop
clk_vop_pmu 0 0 0 24000000 0 0 50000
dclk_vop3 1 2 0 33000000 0 0 50000
dclk_vop1_src 0 1 0 594000000 0 0 50000
dclk_vop1 0 1 0 594000000 0 0 50000
dclk_vop0_src 0 1 0 594000000 0 0 50000
dclk_vop0 0 1 0 594000000 0 0 50000
aclk_vop_low_root 1 1 0 396000000 0 0 50000
hclk_vop_root 2 4 0 198000000 0 0 50000
hclk_vop 1 3 0 198000000 0 0 50000
aclk_vop_root 1 1 0 500000000 0 0 50000
aclk_vop_doby 0 0 0 500000000 0 0 50000
aclk_vop_sub_src 1 1 0 500000000 0 0 50000
aclk_vop 1 4 0 500000000 0 0 50000
pclk_vop_root 3 5 0 100000000 0 0 50000
dclk_vop2_src 1 1 0 148500000 0 0 50000
dclk_vop2 1 2 0 148500000 0 0 50000
console:/ # cat /d/clk/clk_summary | grep dsi
pclk_dsihost1 1 2 0 100000000 0 0 50000
pclk_dsihost0 1 2 0 100000000 0 0 50000
clk_dsihost1 1 2 0 351000000 0 0 50000
clk_dsihost0 1 2 0 351000000 0 0 50000
console:/ # cat /d/clk/clk_summary | grep mipi
mipi1_clk_src 0 0 0 33000000 0 0 50000
mipi1_pixclk 0 0 0 33000000 0 0 50000
mipi0_clk_src 0 0 0 148500000 0 0 50000
mipi0_pixclk 0 0 0 148500000 0 0 50000
clk_usbdpphy_mipidcpphy_ref 5 5 0 24000000 0 0 50000
clk_mipi_camaraout_m4 0 0 0 24000000 0 0 50000
clk_mipi_camaraout_m3 0 0 0 24000000 0 0 50000
clk_mipi_camaraout_m2 0 0 0 24000000 0 0 50000
clk_mipi_camaraout_m0 0 0 0 24000000 0 0 50000
clk_mipi_camaraout_m1 0 0 0 37125000 0 0 50000
pclk_mipi_dcphy1 1 1 0 100000000 0 0 50000
pclk_mipi_dcphy0 1 1 0 100000000 0 0 50000
console:/ #


#### 如何查看指定 DSI lane 速率


DSI lane 速率的指定有两种,一种是驱动自动计算:



dmesg | grep dsi

[ 77.369812] dw-mipi-dsi2 fde20000.dsi: [drm:dw_mipi_dsi2_encoder_enable] final DSI-Link bandwidth: 879 x 4 Mbps


一种是通过如下属性手动指定:



&dsi0 {

rockchip,lane-rate = <1000>;

}


#### MIPI DSI2 HOST 没有自己color bar 功能,通过如下命令可以让 VOP2 投显 color bar


根据显示路由选择对应的命令:



vp0:
io -4 0xfdd90c08 0x1 && io -4 0xfdd90000 0xffffffff

vp1:
io -4 0xfdd90d08 0x1 && io -4 0xfdd90000 0xffffffff

vp2:
io -4 0xfdd90e08 0x1 && io -4 0xfdd90000 0xffffffff

vp3:
io -4 0xfdd90f08 0x1 && io -4 0xfdd90000 0xffffffff


#### 如何判断显示异常的时候,MIPI DSI2 和 panel 是否通信正常


uboot:



— a/drivers/video/drm/rockchip_panel.c
+++ b/drivers/video/drm/rockchip_panel.c
@@ -260,6 +260,7 @@ static void panel_simple_prepare(struct rockchip_panel *panel)
struct rockchip_panel_priv *priv = dev_get_priv(panel->dev);
struct mipi_dsi_device *dsi = dev_get_parent_platdata(panel->dev);
int ret;

  • u8 mode;

    if (priv->prepared)
    return;
    @@ -285,6 +286,8 @@ static void panel_simple_prepare(struct rockchip_panel *panel)
    if (plat->delay.init)
    mdelay(plat->delay.init);

  • mipi_dsi_dcs_get_power_mode(dsi, &mode);

  • printf(“===>mode: 0x%x\n”, mode);
    if (plat->on_cmds) {
    if (priv->cmd_type == CMD_TYPE_SPI)
    ret = rockchip_panel_send_spi_cmds(panel->state,
    @@ -298,6 +301,8 @@ static void panel_simple_prepare(struct rockchip_panel *panel)
    printf(“failed to send on cmds: %d\n”, ret);
    }

  • mipi_dsi_dcs_get_power_mode(dsi, &mode);

  • printf(“===>mode: 0x%x\n”, mode);
    priv->prepared = true;
    }


kernel



— a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -506,6 +506,7 @@ static int panel_simple_prepare(struct drm_panel *panel)
unsigned int delay;
int err;
int hpd_asserted;

  • u8 mode;

    if (p->prepared)
    return 0;
    @@ -554,6 +555,8 @@ static int panel_simple_prepare(struct drm_panel *panel)
    }
    }

  • mipi_dsi_dcs_get_power_mode(p->dsi, &mode);

  • printk(“===>mode: 0x%x\n, mode”);
    if (p->desc->init_seq)
    if (p->dsi)
    panel_simple_xfer_dsi_cmd_seq(p, p->desc->init_seq);
    @@ -561,6 +564,9 @@ static int panel_simple_prepare(struct drm_panel *panel)
    if (p->desc->delay.init)
    msleep(p->desc->delay.init);

  • mipi_dsi_dcs_get_power_mode(p->dsi, &mode);

  • printk(“===>mode: 0x%x\n, mode”);

  • p->prepared = true;

    return 0;


通信正常会有如下打印,否者排查屏端时序确保屏是否就绪:



===> mode: 0x8
===> mode: 0x9c


#### backlight驱动probe失败



console:/ # dmesg | grep backlight
[ 3.164274] pwm-backlight: probe of backlight failed with error -16


#### Command Mode 显示模组如何配置 TE


为防止图像显示撕裂,显示控制器刷帧的频率应该和显示模组从GRAM中刷图的频率保持一致。RK3588只支持显示模组将TE信号外部反馈的方式。



&dsi0 {

/* 显示模组TE信号连接到MIPI_TE0 */
pinctrl-names = “default”;
pinctrl-0 = <&mipi_te0>;

};

&dsi1 {

/* 显示模组TE信号连接到MIPI_TE1 */
pinctrl-names = “default”;
pinctrl-0 = <&mipi_te1>;

};


下图捕获MIPI DSI发送数据信号场频和显示模组TE信号频率一致波形:


![在这里插入图片描述](https://img-blog.csdnimg.cn/e69919e256d14eaf845b4735850e3fd4.png#pic_center)


#### 双通道MIPI切换主从顺序


如果硬件设计将双通道的两个MIPI Ports接反了,可以通过如下配置进行软件纠正:



&dsi0 {

rockchip,data-swap;
rockchip,dual-channel = <&dsi1>;

};

&dsi1 {
status = “okay”;
};


#### 调试节点


在MIPI DSI信号测试过程中需要对信号进行调整,如下是相关调试节点路径:



dcphy0:
cd /sys/devices/platform/feda0000.phy/
dcphy1:
cd /sys/devices/platform/fedb0000.phy/


##### Patch



diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c b/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c
index 1d5db69ee…c5d11f30c 100644
— a/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c
@@ -142,6 +142,25 @@
#define T_TA_GET(x) UPDATE(x, 7, 4)
#define T_TA_GO(x) UPDATE(x, 3, 0)

+#define REG_400M_MASK GENMASK(6, 4)
+#define REG_400M(x) UPDATE(x, 6, 4)
+#define BIAS_CON4 0x0010
+#define I_MUX_SEL_MASK GENMASK(6, 5)
+#define I_MUX_SEL(x) UPDATE(x, 6, 5)
+#define CAP_PEAKING_MASK GENMASK(14, 12)
+#define CAP_PEAKING(x) UPDATE(x, 14, 12)
+#define RES_UP_MASK GENMASK(7, 4)
+#define RES_UP(x) UPDATE(x, 7, 4)
+#define RES_DN_MASK GENMASK(3, 0)
+#define RES_DN(x) UPDATE(x, 3, 0)
+#define T_HS_ZERO_MASK GENMASK(15, 8)
+#define T_HS_PREPARE_MASK GENMASK(7, 0)
+#define T_HS_EXIT_MASK GENMASK(15, 8)
+#define T_HS_TRAIL_MASK GENMASK(7, 0)
+#define T_TA_GET_MASK GENMASK(7, 4)
+#define T_TA_GO_MASK GENMASK(3, 0)
+
/* MIPI_CDPHY_GRF registers */
#define MIPI_DCPHY_GRF_CON0 0x0000
#define S_CPHY_MODE HIWORD_UPDATE(1, 3, 3)
@@ -1194,6 +1213,421 @@ struct samsung_mipi_cphy_timing samsung_mipi_cphy_timing_table[] = {
{ 80, 1, 50, 25, 2, 0, 2 },
};

+static ssize_t
+reg_400m_show(struct device *device, struct device_attribute *attr, char *buf)
+{

  • struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
  • unsigned int val;
  • unsigned int level;
  • regmap_read(samsung->regmap, BIAS_CON2, &val);
  • level = (val & REG_400M_MASK) >> 4;
  • return sprintf(buf, “%d\n”, level);

+}
+
+static ssize_t
+reg_400m_store(struct device *device, struct device_attribute *attr,

  •        const char *buf, size_t count)
    

+{

  • struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
  • unsigned long val;
  • if (kstrtoul(buf, 10, &val))
  •   return -EINVAL;
    
  • if (val > 7)
  •   val = 7;
    
  • regmap_update_bits(samsung->regmap, BIAS_CON2, REG_400M_MASK, REG_400M(val));
  • return count;
    +}
    +static DEVICE_ATTR_RW(reg_400m);

+static ssize_t
+cap_peaking_show(struct device *device, struct device_attribute *attr, char *buf)
+{

  • struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
  • unsigned int val;
  • unsigned int level;
  • regmap_read(samsung->regmap, COMBO_MD0_ANA_CON0, &val);
  • level = (val & CAP_PEAKING_MASK) >> 12;
  • return sprintf(buf, “%d\n”, level);

+}
+
+static ssize_t
+cap_peaking_store(struct device *device, struct device_attribute *attr,

  •        const char *buf, size_t count)
    

+{

  • struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
  • unsigned long val;
  • if (kstrtoul(buf, 10, &val))
  •   return -EINVAL;
    
  • if (val > 7)
  •   val = 7;
    
  • regmap_update_bits(samsung->regmap, DPHY_MC_ANA_CON0, CAP_PEAKING_MASK, CAP_PEAKING(val));
  • regmap_update_bits(samsung->regmap, COMBO_MD0_ANA_CON0, CAP_PEAKING_MASK, CAP_PEAKING(val));
  • regmap_update_bits(samsung->regmap, COMBO_MD1_ANA_CON0, CAP_PEAKING_MASK, CAP_PEAKING(val));
  • regmap_update_bits(samsung->regmap, COMBO_MD2_ANA_CON0, CAP_PEAKING_MASK, CAP_PEAKING(val));
  • regmap_update_bits(samsung->regmap, DPHY_MD3_ANA_CON0, CAP_PEAKING_MASK, CAP_PEAKING(val));
  • return count;
    +}
    +static DEVICE_ATTR_RW(cap_peaking);

+static ssize_t
+res_up_show(struct device *device, struct device_attribute *attr, char *buf)
+{

  • struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
  • unsigned int val;
  • unsigned int level;
  • regmap_read(samsung->regmap, COMBO_MD0_ANA_CON0, &val);
  • level = (val & RES_UP_MASK) >> 4;
  • return sprintf(buf, “%d\n”, level);

+}
+
+static ssize_t
+res_up_store(struct device *device, struct device_attribute *attr,

  •        const char *buf, size_t count)
    

+{

  • struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
  • unsigned long val;
  • if (kstrtoul(buf, 10, &val))
  •   return -EINVAL;
    
  • if (val > 15)
  •   val = 15;
    
  • regmap_update_bits(samsung->regmap, DPHY_MC_ANA_CON0, RES_UP_MASK, RES_UP(val));
  • regmap_update_bits(samsung->regmap, COMBO_MD0_ANA_CON0, RES_UP_MASK, RES_UP(val));
  • regmap_update_bits(samsung->regmap, COMBO_MD1_ANA_CON0, RES_UP_MASK, RES_UP(val));
  • regmap_update_bits(samsung->regmap, COMBO_MD2_ANA_CON0, RES_UP_MASK, RES_UP(val));
  • regmap_update_bits(samsung->regmap, DPHY_MD3_ANA_CON0, RES_UP_MASK, RES_UP(val));
  • return count;
    +}
    +static DEVICE_ATTR_RW(res_up);

+static ssize_t
+res_dn_show(struct device *device, struct device_attribute *attr, char *buf)
+{

  • struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
  • unsigned int val;
  • unsigned int level;
  • regmap_read(samsung->regmap, COMBO_MD0_ANA_CON0, &val);
  • level = (val & RES_DN_MASK);
  • return sprintf(buf, “%d\n”, level);

+}
+
+static ssize_t
+res_dn_store(struct device *device, struct device_attribute *attr,

  •        const char *buf, size_t count)
    

+{

  • struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
  • unsigned long val;
  • if (kstrtoul(buf, 10, &val))
  •   return -EINVAL;
    
  • if (val > 15)
  •   val = 15;
    
  • regmap_update_bits(samsung->regmap, DPHY_MC_ANA_CON0, RES_DN_MASK, RES_DN(val));
  • regmap_update_bits(samsung->regmap, COMBO_MD0_ANA_CON0, RES_DN_MASK, RES_DN(val));
  • regmap_update_bits(samsung->regmap, COMBO_MD1_ANA_CON0, RES_DN_MASK, RES_DN(val));
  • regmap_update_bits(samsung->regmap, COMBO_MD2_ANA_CON0, RES_DN_MASK, RES_DN(val));
  • regmap_update_bits(samsung->regmap, DPHY_MD3_ANA_CON0, RES_DN_MASK, RES_DN(val));
  • return count;
    +}
    +static DEVICE_ATTR_RW(res_dn);

+static ssize_t
+output_voltage_show(struct device *device, struct device_attribute *attr, char *buf)
+{

  • struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
  • unsigned int val;
  • unsigned int level;
  • regmap_read(samsung->regmap, BIAS_CON4, &val);
  • level = (val & I_MUX_SEL_MASK) >> 5;
  • return sprintf(buf, “%d\n”, level);

+}
+
+static ssize_t
+output_voltage_store(struct device *device, struct device_attribute *attr,

  •        const char *buf, size_t count)
    

+{

  • struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
  • unsigned long val;
  • if (kstrtoul(buf, 10, &val))
  •   return -EINVAL;
    
  • if (val > 3)
  •   val = 3;
    
  • regmap_update_bits(samsung->regmap, BIAS_CON4,
  •   	   I_MUX_SEL_MASK, I_MUX_SEL(val));
    
  • return count;
    +}
    +static DEVICE_ATTR_RW(output_voltage);

+static ssize_t
+hs_exit_show(struct device *device, struct device_attribute *attr, char *buf)
+{

  • struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
  • unsigned int val;
  • unsigned int hs_exit;
  • regmap_read(samsung->regmap, COMBO_MD0_TIME_CON2, &val);
  • hs_exit = (val & GENMASK(15, 8)) >> 8;
  • return sprintf(buf, “%d\n”, hs_exit);

+}
+
+static ssize_t hs_exit_store(struct device *device, struct device_attribute *attr,

  •   	 const char *buf, size_t count)
    

+{

  • struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
  • unsigned long val;
  • unsigned long hs_exit;
  • if (kstrtoul(buf, 10, &val))
  •   return -EINVAL;
    
  • hs_exit = T_HS_EXIT(val);
  • regmap_update_bits(samsung->regmap, COMBO_MD0_TIME_CON2, T_HS_EXIT_MASK, hs_exit);
  • regmap_update_bits(samsung->regmap, COMBO_MD1_TIME_CON2, T_HS_EXIT_MASK, hs_exit);
  • regmap_update_bits(samsung->regmap, COMBO_MD2_TIME_CON2, T_HS_EXIT_MASK, hs_exit);
  • if (!samsung->c_option) {
  •   regmap_update_bits(samsung->regmap, DPHY_MC_TIME_CON2, T_HS_EXIT_MASK, hs_exit);
    
  •   regmap_update_bits(samsung->regmap, DPHY_MD3_TIME_CON2, T_HS_EXIT_MASK, hs_exit);
    
  • }
  • return count;
    +}
    +static DEVICE_ATTR_RW(hs_exit);

+static ssize_t
+hs_trail_or_post_3_show(struct device *device, struct device_attribute *attr, char *buf)
+{

  • struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
  • unsigned int val;
  • unsigned int hs_trail;
  • regmap_read(samsung->regmap, COMBO_MD0_TIME_CON2, &val);
  • hs_trail = val & GENMASK(7, 0);
  • return sprintf(buf, “%d\n”, hs_trail);

+}
+
+static ssize_t hs_trail_or_post_3_store(struct device *device, struct device_attribute *attr,

  •   	 const char *buf, size_t count)
    

+{

  • struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
  • unsigned long val;
  • unsigned long hs_trail;
  • if (kstrtoul(buf, 10, &val))
  •   return -EINVAL;
    
  • hs_trail = T_HS_TRAIL(val);
  • regmap_update_bits(samsung->regmap, COMBO_MD0_TIME_CON2, T_HS_TRAIL_MASK, hs_trail);
  • regmap_update_bits(samsung->regmap, COMBO_MD1_TIME_CON2, T_HS_TRAIL_MASK, hs_trail);
  • regmap_update_bits(samsung->regmap, COMBO_MD2_TIME_CON2, T_HS_TRAIL_MASK, hs_trail);
  • if (!samsung->c_option) {
  •   regmap_update_bits(samsung->regmap, DPHY_MC_TIME_CON2, T_HS_TRAIL_MASK, hs_trail);
    
  •   regmap_update_bits(samsung->regmap, DPHY_MD3_TIME_CON2, T_HS_TRAIL_MASK, hs_trail);
    
  • }
  • return count;
    +}
    +static DEVICE_ATTR_RW(hs_trail_or_post_3);

+static ssize_t
+hs_zero_or_prebegin_3_show(struct device *device, struct device_attribute *attr, char *buf)
+{

  • struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
  • unsigned int val;
  • unsigned int hs_zero;
  • regmap_read(samsung->regmap, COMBO_MD0_TIME_CON1, &val);
  • hs_zero = (val & GENMASK(15, 8)) >> 8;
  • return sprintf(buf, “%d\n”, hs_zero);

+}
+
+static ssize_t hs_zero_or_prebegin_3_store(struct device *device, struct device_attribute *attr,

  •   	 const char *buf, size_t count)
    

+{

  • struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
  • unsigned long val;
  • unsigned long hs_zero;
  • if (kstrtoul(buf, 10, &val))

收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。
img
img

如果你需要这些资料,可以戳这里获取

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

p, DPHY_MC_TIME_CON2, T_HS_TRAIL_MASK, hs_trail);

  •   regmap_update_bits(samsung->regmap, DPHY_MD3_TIME_CON2, T_HS_TRAIL_MASK, hs_trail);
    
  • }
  • return count;
    +}
    +static DEVICE_ATTR_RW(hs_trail_or_post_3);

+static ssize_t
+hs_zero_or_prebegin_3_show(struct device *device, struct device_attribute *attr, char *buf)
+{

  • struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
  • unsigned int val;
  • unsigned int hs_zero;
  • regmap_read(samsung->regmap, COMBO_MD0_TIME_CON1, &val);
  • hs_zero = (val & GENMASK(15, 8)) >> 8;
  • return sprintf(buf, “%d\n”, hs_zero);

+}
+
+static ssize_t hs_zero_or_prebegin_3_store(struct device *device, struct device_attribute *attr,

  •   	 const char *buf, size_t count)
    

+{

  • struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
  • unsigned long val;
  • unsigned long hs_zero;
  • if (kstrtoul(buf, 10, &val))

收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。
[外链图片转存中…(img-1VQICzMP-1715902059441)]
[外链图片转存中…(img-VChYf9hr-1715902059441)]

如果你需要这些资料,可以戳这里获取

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 13
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值