目录
[detailed mode](#detailed mode)
[HDMI 2.0 特性](#HDMI 2.0 特性)
[status and Control Data Channel (SCDC)](#status and Control Data Channel (SCDC))
[TMDS Configuration](#TMDS Configuration)
[Scrambler Status](#Scrambler Status)
[Status Flags](#Status Flags)
[DTS 及代码](#DTS 及代码)
[HDMI 视频属性](#HDMI 视频属性)
[HDMI sink 属性](#HDMI sink 属性)
现象
3403 HDMI接口连接 4K30FPS 可以正常显示,但是4K 60FPS在BIOS中显示,进入系统后则不显示。
VOP的时序参数
30HZ
dispmode :2d |pix_clk :297000 |debug_bit_width :max |
debug_pixel_format :null |vmin :820 |temperature :33 |
checking_status :ON |
----------------------------------------custom_timing_para_list-----------------------------------------
hact :3840 |vact :2160 |vfreq :30000 | |
hbb :296 |hfb :176 |hpw :88 | |
vbb :72 |vfb :8 |vpw :10 | |
idv :0 |ihs :0 |ivs :0 | |
---------------------------------display channel setting -------------------------------------------
60HZ
:customertiming |
dispmode :2d |pix_clk :533250 |debug_bit_width :max |
debug_pixel_format :null |vmin :783 |temperature :47 |
checking_status :ON |
----------------------------------------custom_timing_para_list-----------------------------------------
hact :3840 |vact :2160 |vfreq :59996 | |
hbb :80 |hfb :48 |hpw :32 | |
vbb :54 |vfb :3 |vpw :5 | |
idv :0 |ihs :0 |ivs :1 | |
---------------------------------display channel setting -------------------------------------------
|--------------------------------|
| 垂直同步脉冲信号是否翻转 60HZ 翻转;而30HZ没有翻转 |
调试用的位宽和像素格式都没有明确说明,而这和实际的数据量相关。
调试用的位宽设置/像素格式设置。
位宽设置: 8bit,10bit,12bit;
像素格式: rgb,422,444,420。
像素参数
30HZ
------------------------------------------display_interface_status--------------------------------------
enable :yes |matched :no |bitwidth :8bit |pixelfmt :rgb |
attach_intf :hdmi1 | | | |
-----------------------------------------------cast_info------------------------------------------------
60HZ
enable :yes |matched :no |bitwidth :8bit |pixelfmt :rgb |
attach_intf :hdmi1 | | | |
-----------------------------------------------cast_info------------------------------------------------
硬件中断信息
30HZ
---------------------------------------display_ssmu_isr_info--------------------------------------------
lowbandcount :0 |smmucount :0 |
smmu_err_status :0x0 |reg_addr :0x0 |
decomperr :0 |buserr :0 |
60HZ
lowbandcount :14079 |smmucount :0 |
smmu_err_status :0x0 |reg_addr :0x0 |
decomperr :0 |buserr :0 |
------------------------------------------display_interface_status--------------------------------------
对比

除了pix_clk及时序不同外,60HZ 有lowland count ,DISPLAY_BUS_UNDERFLOW_INT字面意思像是低带宽,而且已经为控制器的中断。 bus理解为HDMI控制器到显示器的接口。
具体对应代码:
/drv/drm/vo/vdp_v6_0/disp/drv_disp.c:223
linux\drv\drm\vo\vdp_v6_0\disp\drv_disp_isr.c
EDID
detailed mode

左边仅仅支持30HZ,最大dotclock为300MHz
右边支持到60HZ,最大到600MHz
CTA-861

硬件支持
支持两个 HDMI 2.0b 输出接口


VDP

Surface:总线输入的数据通路。 其功能包括单个图层的总线数据读取、数据处理。 Surface 包括:视频层 V0/V1/V2、图形层 G0/G1/G3。
● Display Channel:显示通道。 包括高清显示通道 DHD0、 高清显示通道 DHD1。
● CBM(CrossBar and Mixer,选通叠加器):
视频层 V0/视频层 V2/图形层 G0/图形层 G3 叠加 CBM0;
视频层 V1/视频层 V2/图形层 G1/图形层 G3 叠加 CBM1。
HDMI 2.0 特性
支持 8bit 输出。● 时钟频率最高 594MHz。● 最大支持 2160P@60fps YCbCr444/RGB 输出。
● 支持逐、 隔行显示。● 支持数据选择来自 DHD0。
显示通道特性
● DHD0 可作为高清 0 的输出通道。
● DHD1 可作为高清 1 的输出通道。
● DHD0 支持以下典型输出时序:2160P@60fps、 2160P@30fps、1080P@60fps、 720P@60fps。
● DHD1 支持以下典型输出时序: 1080P@60fps、 720P@60fps、 PAL/NTSC。
图形层与视频层
图形层用于桌面输出显示。
2160P@60fps 时序输出时, 存在性能限制:G0 层 ARGB8888 格式所支持的最大分辨率为 1080P。建议此时 G0 层采用 1080P 分辨率(格式不限)、同时开启图形层放大功能 , 将 G0 层在线放大到 2160P 进行显示; 或者采用 2160P 分辨率、 ARGB1555或 ARGB4444 格式
dts关系配置
显示通道与接口关系的配置如下所示,
1)采用DHD0 连接HDMI的接口。
2) 像素格式和像素位宽的调整
pdm_disp0:pdm_disp@0 {
compatible="soc-pdm-disp0";
default_channel=<SOCT_DISP_DEFAULT_DHD0>;
format=<SOCT_DISP_FMT_VESA_1920X1080_60>;
pixel_format=<SOCT_PIXEL_FORMAT_ARG8888>;
pixel_bitwidth=<SOCT_PIXEL_BITWIDTH_8BIT>;
color_space=<SOCT_COLOR_SPACE_BT709>;
vic=<0>;
hdr_type=<SOCT_HDR_TYPE_NORMAL>;
hdr_match_content=<0>;
scene_mode=<SOCT_DISP_SCENE_MODE_NORMAL>;
offset_info =<0 0 0 0>; //<left top right bottom>
bg_color=<0 0 0>; //<r g b>
aspect_ratio=<0 0 SOCT_DISP_ASPECT_RATIO_16TO9>; //<w h mode>
intf_number=<1>;
intf_0=<SOCT_DISP_INTF_TYPE_HDMI 0 0 0 0 0 0 0>;
disp_timing=<0 0 0 0 0 0 0 0 0 0 0 0 0 0>;
//<vfb vbb vact hfb hbb hact vpw hpw idv ihs ivs clkreversal pix_freq refresh_rate>
};
status and Control Data Channel (SCDC)
参考《hdmi2.0 spec.pdf》
TMDS Configuration

Scrambler Status

Status Flags

HDMI时序参数
cat /proc/msp/hdmitx1

上述tmds _scr_en 表示HDMI 控制器侧已经使能了scrambler。而输出

提示则表示 scrambler虽然配置了,但实际并没有配置成功。此时检测上述scrambler status状态寄存器为0,即sink端没有生效scrambler。
设置的代码流程
\linux\drv\hdmitx\drv_hdmitx_controller.c
drv_hdmitx_controller_tmds_set_scramble
time_out = 20;
do {
if (soft_status->cur_hw_config.tmds_scr_en &&
soft_status->cur_hw_config.work_mode == HDMITX_WORK_MODE_TMDS) {
hal_phy_hw_oe_enable(controller->hdmi->phy, TD_FALSE);
drv_hdmitx_ddc_scdc_set_high_tmds_clock_ratio(sub_module->ddc, TD_TRUE);
drv_hdmitx_ddc_scdc_set_scrambling(sub_module->ddc, TD_TRUE);
hal_ctrl_enable_scramble(&controller->reg_info, TD_TRUE);
osal_mdelay(time_out);
hal_phy_hw_oe_enable(controller->hdmi->phy, TD_TRUE);
osal_mdelay(time_out);
clock_ratio = drv_hdmitx_ddc_scdc_get_high_tmds_clock_ratio(sub_module->ddc);
} else {
drv_hdmitx_ddc_scdc_set_high_tmds_clock_ratio(sub_module->ddc, TD_FALSE);
drv_hdmitx_ddc_scdc_set_scrambling(sub_module->ddc, TD_FALSE);
break;
}
soc_log_info("sink scramble status: %d clock ratio: %d\n",
drv_hdmitx_ddc_scdc_get_scrambling_status(sub_module->ddc), clock_ratio);
time_out += 20;
} while (clock_ratio != TD_TRUE && (time_out <= 200));
链路参数调节
官方原厂SDK\ReleaseDoc\zh\02.only for reference\hardware\SS928V100╱SS927V100 HDMI2.0涉硬参数调试指南
Vswing:差分眼图幅度。和 VL 强相关,swing 不可过大或过小,否则单端 VL 可能不过。
● VL:单端幅度。
● 上升下降时间:差分指标测试项。
● Imain:主驱电流。
● Post1 emphasis:主驱辅助电流。
● ISI:(码间串扰)
主驱电流辅助调节(即加重调节),主要作用是预补偿通道衰减带来的 ISI(码间串扰)影响。客户单板的走线长度会因为场景不一样而变化。因此,通道的衰减大小不一样,补偿的值就需要相应的调整,以达到最佳效果。通道速率越高,调节该寄存器效果也越明显。
调节该寄存器,影响最大的指标是眼图和上升下降时间;Post1 emphasis 越大,上升下降时间越陡峭,但眼图不一定最佳(存在过加重风险)。
实例如表 3-2 所示,加重增加,上升沿变快
表3-2 CTS 部分认证指标
|------------------|--------------|----------|----------|
| Spec | Test Name | 加重 0 | 加重 15 |
| 75.00ps < TRISE | D0 Rise Time | 117.88ps | 100.02ps |
| 75.00ps < TRISE | D1 Rise Time | 110.56ps | 92.259ps |
| 75.00ps < TRISE | D2 Rise Time | 129.82ps | 105.07ps |
Post1 (mA)的调整,会降低"Vswing",虽然上升下降时间会变陡峭但预留了裕量,所以,不需要考虑对 EMI 指标的影响。
Post1 预加重档位不宜太大,以眼图为主要调节目标,防止过加重;同时预留上升下降时间裕量。
对于 Vswing 需要考虑指标下界裕量。
主驱电流辅助
调节寄存器 0:
-
对应寄存器地址:BASE+0510
-
寄存器调节位置:bit [21:16]:d0 channel post1 emphasis current
● 调节寄存器 3:(不建议调节该寄存器)
-
对应寄存器地址:BASE+051C
-
寄存器调节位置:bit [21:16]:clock channel post1 emphasis current
计算公式
Post1 emphasis = B5*32+B4*16+B3*8+B2*4+B1*2+B0*1
每个通道提供 6 个 bit 位调节,对应为[B5:B0],实际预加重档位计算示例如下:如果寄存器 BASE+0510 的值是 0x40071e00,那么[5:0]就是 0b000111,每个 bit 位从高到低分别对应 B5~B0,即 B5=0,B4=0,B3=0,B2=1,B1=1,B0=1,根据计算公式可以算得,d0 通道的预加重档位,Post1 (档位)= 0*32+0*16+0*8+1*4+1*2+1*1 = 7 。
预加重档位越大,表示预加重越强
Post1 emphasis = 0

Post1 emphasis = 15

主驱电流
主驱电流调节(即 Vswing 调节),主要作用是调整输出 Vswing 的大小;Imain 越大,差分 swing 幅度越大。信号速率越高,通道损耗越大,因此对于4k30 以上的速率需要根据单板走线长度,适当调整主驱电流。
调节指导原则
● Imain(mA)粗调,以眼图为主,默认配置即可;
● Imain(mA)细调:
-
1080P60 以下的速率,调节目标主要考虑 VL 指标裕量;
-
4k30,同时需要考虑单端 VL 指标裕量和 EMI 指标裕量;
调节寄存器 0:
-
对应寄存器地址:BASE+0510
-
寄存器调节位置:bit [13:8]:d0 channel main-drv current
Imain (档位) = B5*32+B4*16+B3*8+B2*4+B1*2+B0*1
每个通道提供 6 个 bit 位调节,对应为[B5:B0],实际 Imain 档位计算示例如下:如果寄存器 BASE+0510 的值是 0x40071e00,那么[13:8]就是 0b011110,每个 bit 位从高到低分别对应 B5~B0,即 B5=0,B4=1,B3=1,B2=1,B1=1,B0=0,根据计算公式可以算得,d0 通道的 Imain 档位值,Imain (档位)= 0*32+1*16+1*8+1*4+1*2+0*1 = 30。
Imain 档位越大,表示输出摆幅越高。



DTS 及代码
&hdmitx {
/* min_tmds_clk max_tmds_clk data_post1 data_main data_pre clock_post1 clock_main clock_pre */
phy_tmds_custom_params = <25000 100000 0x00 0x12 0x00 0x00 0x13 0x00>,
<100000 165000 0x02 0x15 0x05 0x00 0x13 0x00>,
<165000 340000 0x04 0x1d 0x02 0x00 0x14 0x00>,
<340000 600000 0x08 0x28 0x05 0x00 0x11 0x00>;
phy_tmds_custom_params_enable = <1>;
};
\linux\drv\hdmitx\hal\phy\v300\hal_hdmitx_phy.c
hal_phy_tmds_set
static td_void phy_hw_tmds_dphy_spec_set(const struct hdmitx_phy *hdmi_phy, const struct tmds_spec_params *tmds)
{
const struct dphy_spec_params *data = &tmds->data.dphy;
const struct dphy_spec_params *clk = &tmds->clock.dphy;
const struct dphy_spec_en *data_en = &tmds->data.en;
const struct dphy_spec_en *clk_en = &tmds->clock.en;
/* select dphy drv set mode */
hdmi_write_bits(hdmi_phy->regs, REG_TMDS_DRV_CFG_CH0, REG_CFG_HDMI_FFE_SEL_M, 0x1);
/* dphy data drv set */
hdmi_write_bits(hdmi_phy->regs, REG_TMDS_DRV_CFG_CH0, REG_CFG_DRV_POST2_CH0_M, data->drv_post2);
hdmi_write_bits(hdmi_phy->regs, REG_TMDS_DRV_CFG_CH0, REG_CFG_DRV_POST1_CH0_M, data->drv_post1);
hdmi_write_bits(hdmi_phy->regs, REG_TMDS_DRV_CFG_CH0, REG_CFG_DRV_M_CH0_M, data->drv_main);
hdmi_write_bits(hdmi_phy->regs, REG_TMDS_DRV_CFG_CH0, REG_CFG_DRV_PRE_CH0_M, data->drv_pre);
hdmi_write_bits(hdmi_phy->regs, REG_TMDS_DRV_CFG_CH1, REG_CFG_DRV_POST2_CH1_M, data->drv_post2);
hdmi_write_bits(hdmi_phy->regs, REG_TMDS_DRV_CFG_CH1, REG_CFG_DRV_POST1_CH1_M, data->drv_post1);
hdmi_write_bits(hdmi_phy->regs, REG_TMDS_DRV_CFG_CH1, REG_CFG_DRV_M_CH1_M, data->drv_main);
hdmi_write_bits(hdmi_phy->regs, REG_TMDS_DRV_CFG_CH1, REG_CFG_DRV_PRE_CH1_M, data->drv_pre);
hdmi_write_bits(hdmi_phy->regs, REG_TMDS_DRV_CFG_CH2, REG_CFG_DRV_POST2_CH2_M, data->drv_post2);
hdmi_write_bits(hdmi_phy->regs, REG_TMDS_DRV_CFG_CH2, REG_CFG_DRV_POST1_CH2_M, data->drv_post1);
hdmi_write_bits(hdmi_phy->regs, REG_TMDS_DRV_CFG_CH2, REG_CFG_DRV_M_CH2_M, data->drv_main);
hdmi_write_bits(hdmi_phy->regs, REG_TMDS_DRV_CFG_CH2, REG_CFG_DRV_PRE_CH2_M, data->drv_pre);
/* dphy clk drv set */
hdmi_write_bits(hdmi_phy->regs, REG_TMDS_DRV_CFG_CH3, REG_CFG_DRV_POST2_CH3_M, clk->drv_post2);
hdmi_write_bits(hdmi_phy->regs, REG_TMDS_DRV_CFG_CH3, REG_CFG_DRV_POST1_CH3_M, clk->drv_post1);
hdmi_write_bits(hdmi_phy->regs, REG_TMDS_DRV_CFG_CH3, REG_CFG_DRV_M_CH3_M, clk->drv_main);
hdmi_write_bits(hdmi_phy->regs, REG_TMDS_DRV_CFG_CH3, REG_CFG_DRV_PRE_CH3_M, clk->drv_pre);
/* dphy data drv enable */
hdmi_write_bits(hdmi_phy->regs, REG_FFE_EN_CFG, REG_CFG_C2_PRE_EN_M, data_en->drv_pre_en);
hdmi_write_bits(hdmi_phy->regs, REG_FFE_EN_CFG, REG_CFG_C2_POST1_EN_M, data_en->drv_post1_en);
hdmi_write_bits(hdmi_phy->regs, REG_FFE_EN_CFG, REG_CFG_C2_POST2_EN_M, data_en->drv_post2_en);
hdmi_write_bits(hdmi_phy->regs, REG_FFE_EN_CFG, REG_CFG_C1_PRE_EN_M, data_en->drv_pre_en);
hdmi_write_bits(hdmi_phy->regs, REG_FFE_EN_CFG, REG_CFG_C1_POST1_EN_M, data_en->drv_post1_en);
hdmi_write_bits(hdmi_phy->regs, REG_FFE_EN_CFG, REG_CFG_C1_POST2_EN_M, data_en->drv_post2_en);
hdmi_write_bits(hdmi_phy->regs, REG_FFE_EN_CFG, REG_CFG_C0_PRE_EN_M, data_en->drv_pre_en);
hdmi_write_bits(hdmi_phy->regs, REG_FFE_EN_CFG, REG_CFG_C0_POST1_EN_M, data_en->drv_post1_en);
hdmi_write_bits(hdmi_phy->regs, REG_FFE_EN_CFG, REG_CFG_C0_POST2_EN_M, data_en->drv_post2_en);
/* dphy clock drv enable */
hdmi_write_bits(hdmi_phy->regs, REG_FFE_EN_CFG, REG_CFG_C3_PRE_EN_M, clk_en->drv_pre_en);
hdmi_write_bits(hdmi_phy->regs, REG_FFE_EN_CFG, REG_CFG_C3_POST1_EN_M, clk_en->drv_post1_en);
hdmi_write_bits(hdmi_phy->regs, REG_FFE_EN_CFG, REG_CFG_C3_POST2_EN_M, clk_en->drv_post2_en);
}
HDMI 视频属性
cat /proc/msp/hdmitx1_aovo
包括视频的原始色彩空间、位数,输出的色彩空间、位数等。 还包括phy的像素时钟等。
HDMI sink 属性
也就是HDMI侧读到的屏的信息
cat /proc/msp/hdmitx1_sink
总结
通过4K60FPS的问题,我们了解到:
1) 海思surface 支持视频层和图形层。在摄像头采集,比如SDI摄像头采集后,经过处理通过显示输出的流程中,可以直接用摄像头的原始格式,例如YUV422等,经视频层送出。
2) 对于4K60FPS的显示,显示整个通道有限制。只能从DHD0输出,而且图形层只有G0支持,而G0支持又有像素格式限制。
3) 上述格式类的问题解决后。链路层的状态通过状态寄存器查看,例如我们板卡起初时钟通道锁定,而数据通道没有锁定。需要调整链路参数调整对应眼图,达到比较理想的效果。
总之,通过时序参数、硬件特性配置、链路参数调整,可以使海思芯片输出4K60FPS的桌面图形。