Amlogic android7.1 s905x hdmi相关内容浅析

amlogic android7.1 s905x hdmi相关内容浅析

文件节点目录:./drivers/amlogic/hdmi/hdmi_tx_20/hdmi_tx_main.c
1、读取edid原始数据:
stvs9:/ # cat ./sys/devices/virtual/amhdmitx/amhdmitx0/rawedid
00ffffffffffff0025e4032301010101011d0103805022782a96a1a355539f250a5054210800818081c0a9c0d1c001010101010101014eab70b8d1a042509060640820
4f3100001a000000fd00174c1f703c000a202020202020000000ff0053657269616c4e756d6265720a000000fc004c43442d474357513334315844015802033d704b10
0102030405202256585a23090707830100006a030c002000383c20000067d85dc401788001e30f0004e200cae60607018b6011e3056000e77c70a0d0a0295030203a00
204f3100001a565e00a0a0a0295030203500204f3100001a295900a0a038274030203a00204f3100001a000000000000000000000000ea

2、通过以下节点得到RX所支持的HDMI显示模式(分辨率)支持的情况
130|:/ # cat /sys/class/amhdmitx/amhdmitx0/disp_cap
480p60hz
720p60hz
1080i60hz
1080p60hz
1080p30hz
1080p24hz
2560x1080p60hz
2560x1080p60hz

3、设置分辨率
stvs9:/ # echo 1080p60hz > sys/class/display/mode //设置分辨率为1080p 3440x1440p60hz
stvs9:/ # cat sys/class/display/mode //查看当前设备分辨率
1080p60hz

4、HDMI在Spec 1.4中已经定义了的颜色空间有:
YCbCr 4:4:4、YCbCr 4:2:2、RGB 4:4:4
定义了的色深模式有:
8bit X 3,即24 bits
10bit X 3,即30 bits
12bit X 3,即36 bits
16bit X 3,即48 bits
到了HDMI2.0时,颜色空间增加了YCbCr 4:2:0

通过如下方式得到RX所支持的色彩空间/色深模式支持的情况
/ # cat /sys/class/amhdmitx/amhdmitx0/dc_cap
420,10bit
420,8bit
444,10bit
444,8bit
422,10bit
422,8bit
rgb,10bit
rgb,8bit

5、查看或者设置当前rx的color format参数
😕 # cat sys/class/amhdmitx/amhdmitx0/attr
rgb,8bit
😕 #
😕 # echo rgb,8bit > sys/class/amhdmitx/amhdmitx0/attr

6、例如设定720p50hz Y444 10bit模式,那么通过
echo 444,10bit > /sys/class/amhdmitx/amhdmitx0/attr
echo 720p50hz > /sys/class/display/mode
便可以实现这种模式输出。
测试脚本,test.sh(见附件,具体参考脚本内容),使用举例如下:
#Examples:
system/bin/test.sh 2160p60hz420 420,8bit 0 1
#Limits:
#1) For YCbCr420 modes, only 2160p50hz420/2160p60hz420 support
#2) 444,12bit 444,10bit rgb,12bit rgb,10bit is not valid for 2160p60hz, 2160p50hz

echo rgb,8bit > sys/class/amhdmitx/amhdmitx0/attr
echo 3440x1440p60hz > sys/class/display/mode

脚本操作:
system/bin/test.sh 3440x1440p60hz rgb,8bit 0 0
system/bin/test.sh 3440x1440p75hz rgb,8bit 0 0

130|stvs9:/ # cat sys/class/display/axis
0 0 1920 1080 0 0 18 18

输出BIST COLORBAR模式:
echo bist1920 > /sys/class/amhdmitx/amhdmitx0/debug
输出BIST LINE模式:
echo bistline > /sys/class/amhdmitx/amhdmitx0/debug
输出BIST DOT模式:
echo bistdot > /sys/class/amhdmitx/amhdmitx0/debug
调整BIST起始位置:
echo biststart100 > /sys/class/amhdmitx/amhdmitx0/debug
关闭BIST:
echo bistoff > /sys/class/amhdmitx/amhdmitx0/debug

uboot状态下的hdmi输出:

hdmi output输出3440x1440p60hz
gxl_stvs9_v1#hdmitx output 3440x1440p60hz
set hdmitx VIC = 793
Not find VIC = 793 for hpll setting
hdmitx: not find VIC: 793
rx version is 2.0 div=10
hdmtix: set audio
hdmitx phy setting done

gxl_stvs9_v1#hdmitx output 3440x1440p60hz
set hdmitx VIC = 793
Not find VIC = 793 for hpll setting
hdmitx: not find VIC: 793
rx version is 2.0 div=10
hdmtix: set audio
hdmitx phy setting done
gxl_stvs9_v1#
gxl_stvs9_v1#
gxl_stvs9_v1#
gxl_stvs9_v1#
gxl_stvs9_v1#hdmitx output bist 1
gxl_stvs9_v1#
gxl_stvs9_v1#hdmitx info
3440x1440p60hz 793
cd4 cs1 cr1
frac_rate: 0
gxl_stvs9_v1#

设置分辨率的代码流程跟踪:
从节点开始:

/* ./drivers/amlogic/display/vout/vout_serve.c */
mode_store-->
-->set_vout_mode
	-->if (strcmp(name, local_name)) //判断分辨率是否跟当前分辨率一致

			/* 文件目录:./drivers/amlogic/display/vout/tv_vout.c */
		-->mode = validate_vmode(name) --> tv_validate_vmode;
			-->*info = get_valid_vinfo(mode);// 判断mode是否是有效、能使用的mode
				-->ret = set_current_vmode(mode); //设置当前video mode

common目录即(kernel部分):
驱动目录:
drivers/amlogic/hdmi/hdmi_tx_20/

文件:drivers/amlogic/hdmi/hdmi_tx_20/hdmi_tx_main.c

		->amhdmitx_probe //从跑probe开始分析
			->INIT_DELAYED_WORK(&hdmi_delay_event_work, hdmi_delay_event_post); //初始化延时工作队列,
			->hdmitx_init_parameters(&hdmitx_device.hdmi_info); //hdmitx协议级接口; 在文件:./drivers/amlogic/hdmi/hdmi_tx_20/hdmi_tx_video.c
				->
			
			->HDMITX_Meson_Init(&hdmitx_device); //HDMI TX初始化
				->hdmi_hwp_init(hdev);
					->hdmitx_uboot_already_display() // 文件:./drivers/amlogic/hdmi/hdmi_tx_20/hw/hdmi_tx_hw.c
						->get_hdmitx_format(); //获取记录HDMI TX当前hdmitx format参数,与uboot匹配(通过下面的读取寄存器值的方式)
							->return hd_read_reg(P_ISA_DEBUG_REG0); //读取寄存器 P_ISA_DEBUG_REG0 的值,这个寄存器值在uboot中设置
							  /* ISA_DEBUG_REG0 0x2600				//VIC值在./include/linux/amlogic/hdmi_tx/hdmi_common.h有枚举定义
							   * bit[11]: Y420
							   * bit[10:8]: HDMI VIC  //这里 #######获取VIC值#########,
							   * bit[7:0]: CEA VIC
							   */							   
			->hdmitx_init_fmt_attr(&hdmitx_device, fmt_attr);// ############ 设置当前color format ###########
				->memcpy(fmt_attr, "422,", 4); //例如
				->strcat(fmt_attr, "10bit"); //例如

				
			->hdmitx_device.task = kthread_run(hdmi_task_handle, &hdmitx_device, "kthread_hdmi"); //kthread_run创建和运行内核线程,入口函数是 hdmi_task_handle
				->hdmi_task_handle
					->switch_set_state(&hdmi_power, hdmitx_device->hpd_state);//设置hdmi拔插状态
					->INIT_WORK(&hdmitx_device->work_hdr, hdr_work_func); //初始化hdmi状态检测工作队列hdr_work_func
						->hdr_work_func
							->hdmitx_sdr_hdr_uevent(hdev); //hdmi拔插检测的uevent事件
								->switch_set_state(&hdmi_hdr, 1); //插入hdmi?
								->switch_set_state(&hdmi_hdr, 0); //拔出hdmi?
					 
				->hdmitx_edid_ram_buffer_clear(hdmitx_device); //初始化hdmi时,清除hdmitx模块edid ram和edid缓冲区
				->INIT_DELAYED_WORK(&hdmitx_device->work_hpd_plugin, hdmitx_hpd_plugin_handler); //初始化延时工作队列hdmitx_hpd_plugin_handler,检测hdmi插入
				->INIT_DELAYED_WORK(&hdmitx_device->work_hpd_plugout, hdmitx_hpd_plugout_handler); //初始化延时工作队列hdmitx_hpd_plugout_handler,检测hdmi拔出
					->void hdmitx_hpd_plugin_handler(struct work_struct *work); //延时工作队列函数
						->if (hdev->repeater_tx) //判断hdmi是否插入,设置hpd状态
							rx_repeat_hpd_state(1); //设置hpd状态为插入hdmi
						->hdmitx_get_edid(hdev); //获取EDID:通过i2c通讯的方式读取edid,读取128个字节,这里读取两次,
							||	->gpio_read_edid(hdev->EDID_buf);
									->edid_rx_data(regaddr & 0xff, rx_data, 128); //读取128个字节的edid
										->err = i2c_transfer(i2c_edid_client->adapter, msgs, ARRAY_SIZE(msgs));
							||调用
							\/
							------------------------------------------------------------
							文件./drivers/amlogic/hdmi/hdmi_tx_20/hdmi_tx_edid.c
							->hdmitx_edid_clear(hdev); //清除HDMI Sink的EDID的解析结果,原函数在文件./drivers/amlogic/hdmi/hdmi_tx_20/hdmi_tx_edid.c中
							->hdmitx_edid_parse(hdev); //解析读到的edid的内容--【128个字节】,
								->ret_val = Edid_DecodeHeader(&hdmitx_device->hdmi_info, &EDID_buf[0]); //判断edid的引导码是否正确,一般是:00ffffffffffff00开头的引导码
								->如果识别到的edid块数量为0,则  #################识别读取不到显示器edid####################
									->if (BlockCount == 0) {
										->hdmitx_edid_set_default_vic(hdmitx_device); //设置默认的vic值
										->
									}
								->hdmitx_edid_block_parse(hdmitx_device, &(EDID_buf[i*128])); //
									->Edid_DTD_parsing(struct rx_cap *pRXCap, unsigned char *data); //EDID DTD 详细时序解析
										->para = hdmi_match_dtd_paras(t); //调用 hdmi_match_dtd_paras()检查t时序参数是否与VIC对应时序参数匹配
											||
											\/
											文件:./drivers/amlogic/hdmi/hdmi_common/hdmi_parameters.c
											->*hdmi_match_dtd_paras(struct dtd *t) //这里hdmi_match_dtd_paras函数的t参数会和all_fmt_paras对应的参数比对,如果一致就返回对应参数对应结构体
												->return all_fmt_paras[i];																		\/
													->struct hdmi_format_para *all_fmt_paras[] = { //hdmi的显示参数结构体,分辨率、clk和前后阶参数等都在这里
														...
														&fmt_para_3840x2160p60_16x9,
														...
														}
											                     ||
																 \/
																	static struct hdmi_format_para fmt_para_3840x2160p60_16x9 = {
																				.vic = HDMI_3840x2160p60_16x9,
																				.name = "3840x2160p60hz",
																				.sname = "2160p60hz",
																				.pixel_repetition_factor = 0,
																				.progress_mode = 1,
																				.scrambler_en = 1,
																				.tmds_clk_div40 = 1,
																				.tmds_clk = 594000,
																				.timing = {
																						.pixel_freq = 594000,
																						.frac_freq = 593407,
																						.h_freq = 135000,
																						.v_freq = 60000,
																						.vsync_polarity = 1,
																						.hsync_polarity = 1,
																						.h_active = 3840,
																						.h_total = 4400,
																						.h_blank = 560,
																						.h_front = 176,
																						.h_sync = 88,
																						.h_back = 296,
																						.v_active = 2160,
																						.v_total = 2250,
																						.v_blank = 90,
																						.v_front = 8,
																						.v_sync = 10,
																						.v_back = 72,
																						.v_sync_ln = 1,
																						},
																	};
																
									   ->dump_dtd_info(t); //dump出hdmi的显示参数
							------------------------------------------------------------
						->set_disp_mode_auto(); //###########设置显示分辨率##############
							->hdmi_get_current_vinfo
								->info = get_current_vinfo();
									->vinfo_s *get_current_vinfo(void)
										->return &vinfo_1080p60hz; //这里分辨率设置为1080p60hz
											-> ||
											   \/
											   -----------------------------
											    104 const struct vinfo_s vinfo_1080p60hz = {
												105         .name = "1080p60hz",
												106         .mode = VMODE_1080P,
												107         .width = 1920,
												108         .height = 1080,
												109         .field_height = 1080,
												110         .aspect_ratio_num = 16,
												111         .aspect_ratio_den  = 9,
												112         .sync_duration_num = 60,
												113         .sync_duration_den = 1,
												114         .video_clk = 148500000,
												115 };
											   -----------------------------
										
						->hdmitx_edid_buf_compare_print(hdev); //打印edid buf内容到log输出
								||
								\/
								---------------------------------------
								文件:./drivers/amlogic/hdmi/hdmi_tx_20/hdmi_tx_edid.c
								->hdmitx_edid_buf_compare_print(struct hdmitx_dev *hdmitx_device) //假设DDC成功读取EDID两次,然后比较EDID_buf和EDID_buf1。如果相同,
																								  //只打印出EDID buf原始数据,否则打印出2个缓冲区数据
									->for (blk_idx = 0; blk_idx < valid_blk_no; blk_idx++)
										hdmitx_edid_blk_print(&buf0[blk_idx*128], blk_idx);									
									->valid_blk_no = hdmitx_edid_check_valid_blocks(buf1);
										for (blk_idx = 0; blk_idx < valid_blk_no; blk_idx++)
											hdmitx_edid_blk_print(&buf1[blk_idx*128], blk_idx);
								---------------------------------------

							||
							\/
						->set_disp_mode_auto(); //
							->hdmi_get_current_vinfo();//获取当前显示信息
								->para = hdmi_get_fmt_name(mode, fmt_attr); //
									->vic = hdmitx_edid_get_VIC(hdev, mode, 1); //
									->ret = hdmitx_set_display(hdev, vic); //
									->recalc_vinfo_sync_duration(info, hdev->frac_rate_policy);
									->hdmitx_set_audio(hdev, &(hdev->cur_audio_param), hdmi_ch); //打开hdmi音频

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

零意@

您的打赏将是我继续创作的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值