---
typora-root-url: 常见显示问题
---

# rockchip平台常见显示问题

发布版本：1.0

作者邮箱：hjc@rock-chips.com

日期：2019.11

文件密级：公开资料

---
**前言**

**概述**

**读者对象**

本文档（本指南）主要适用于以下工程师：
显示驱动开发工程师

**修订记录**

| **日期**   | **版本** | **作者** | **修改说明** |
| ---------- | -------- | -------- | ------------ |
| 2019-09-11 | V1.0     | 黄家钗   | 初始发布     |
|            |          |          |              |

---
[TOC]
---

## 1 关闭VOP iommu的方法

有时候为了解决一些问题或者做实验需要关闭VOP iommu，Linux 3.10和Linux4.4及以上版本的内核修改方法分别是：

Linux 3.10内核

1. dts中加大CMA的size，至少到512M

   ```c
   &ion_cma {
   reg = <0x00000000 0x20000000>; /* 512MB */
   };
   ```

2. dts vop节点中关闭iommu

   ```c
   &vop {
   
   rockchip,iommu-enabled = <0>;
   
   };
   ```

Linux 4.4及以上版本的内核

1. defconfig配置CMA SIZE = 512M

   ```c
   --- a/arch/arm64/configs/rockchip_defconfig
   +++ b/arch/arm64/configs/rockchip_defconfig
   @@ -232,6 +232,7 @@ CONFIG_RFKILL=y
    CONFIG_DEVTMPFS=y
    CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
    CONFIG_DMA_CMA=y
   +CONFIG_CMA_SIZE_MBYTES=512
   ```

2. drm驱动中关闭iommu

   ```c
   --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
   +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
   @@ -59,7 +59,7 @@
   
   -static bool is_support_iommu = true;
   +static bool is_support_iommu = false;
   ```

## 2 linux4.4 开机后支持系统分辨率修改

问题原因

客户特殊需求，希望系统起来后输出分辨率可以做动态切换

处理方案

1. 相关功能实现参考display_patches工程补丁：0001-drm-panel-panel-simple-add-support-multi-panel-timin.patch

2. 在所使用的dts文件中，加入新的timing定义

3. 通过modetest可以看到dsi里面有2组timing

   ```c
   --- a/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-linux-for-rk1808-cascade.dts
   ++ b/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-linux-for-rk1808-cascade.dts
   `@ -331,6 +331,22 `@
   de-active = <0>;
   pixelclk-active = <0>;
   };
   
   + timing_720p: timing-720p {
   + clock-frequency = <76000000>;
   + hactive = <1280>;
   + vactive = <720>;
   + hback-porch = <100>;
   + hfront-porch = <200>;
   + vback-porch = <10>;
   + vfront-porch = <10>;
   + hsync-len = <20>;
   + vsync-len = <20>;
   + hsync-active = <0>;
   + vsync-active = <0>;
   + de-active = <0>;
   + pixelclk-active = <0>;
   + };
   };
   };
   ```

   3. 通过modetest可以看到dsi里面有2组timing

   ```c
   93 0 connected DSI-1 0x0 2 92
   modes:
   name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot)
   1920x1080 60 1920 2040 2060 2260 1080 1082 1092 1112 220000 flags: nhsync, nvsync; type: preferred, driver
   1280x720 60 1280 2120 2140 2240 720 1090 1110 1120 76000 flags: nhsync, nvsync; type: preferred, driver
   ```

   4. 通过串口配置新的分辨率：

     ```c
     setprop persist.sys.resolution.main 1280x720p60
     setprop sys.display.timeline N
     ```

Redmine记录

Defect #185506 android7.1 linux4.4 开机后支持系统分辨修改 https://redmine.rockchip.com.cn/issues/185506

## 3 kernel logo显示失败

问题原因

由于代码不同步，一些早期的uboot没有解析mode->flag导致在内核drm_drv_bind显示logo的时候对比分辨率出现分辨率变化，从而放弃显示kernel logo，直到安卓logo起来的时候才显示；

处理方案

1. 确认mode->flag中pixelclk-active等极性的修改是否必要，如果不是必要的，可以先删掉；

2. 如果极性的修改是必要的那可以在drm驱动中做如下修改：

   ```c
   diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
   index 42e88f0..efcc6d5 100644
   --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
   +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
   @@ -632,7 +632,7 @@ static int setup_initial_state(struct drm_device *drm_dev,
                       mode->crtc_hsync_end == set->crtc_hsync_end &&
                       mode->crtc_vsync_end == set->crtc_vsync_end &&
                       drm_mode_vrefresh(mode) == set->vrefresh &&
   
   -mode->flags == set->flags &&
   
   +//mode->flags == set->flags &&
   mode->picture_aspect_ratio == set->picture_aspect_ratio) {
       found = 1;
       match = 1;
   ```

3. 或者同步到最新的内核；

Redmine记录

Defect #180968 晶凌达 RK3288_ANDROID7.1-TABLET-SDK_V1 .00_20170629 EDP屏问题 https://redmine.rockchip.com.cn/issues/180968#change-1699594

## 4 播放视频时，屏幕出现残影

问题原因

VOP驱动bug导致一些alpha 模式本来应该全透的per-pixel alpha变成src被乘以1，隐约可以看见上一个图层的显示效果，也就是客户说的残影效果；

 处理方案

最新代码已经提交，如果是客户早期的代码可以参考display_patches工程的补丁：rk3368_alpha.patch

 Redmine记录

Defect #190412 Yealink RK3368_ANDROID5.1-SDK_V1.00_20150415 后台播放视频时，屏幕出现残影

## 5 一级休眠唤醒时间太长

 问题原因

VOP standby en配置的位置不对，导致帧中断没来，出现wait win close timeout

 处理方案

将stanby en的配置挪到resume函数的最前面，和suspend函数的最后面即可。最新代码已经有相关修改。

 Redmine记录

Defect #191554 [display]rockchip-vop报错确认 https://redmine.rockchip.com.cn/issues/191554

## 6 RGB输出3个通道交换

问题原因

客户硬件layout出问题，需要VOP做R-B swap的操作

处理方案

```c
uboot：
--- a/drivers/video/drm/rockchip_vop.c
+++ b/drivers/video/drm/rockchip_vop.c
`@ -372,7 +372,7 `@ static int rockchip_vop_init(struct display_state *state)
VOP_CTRL_SET(vop, dsp_data_swap, 0);

​```
VOP_CTRL_SET(vop, out_mode, conn_state->output_mode);
+VOP_CTRL_SET(vop, dsp_data_swap, DSP_RB_SWAP);
if (VOP_CTRL_SUPPORT(vop, overlay_mode)) {
yuv_overlay = is_yuv_output(conn_state->bus_format);
VOP_CTRL_SET(vop, overlay_mode, yuv_overlay);
​```

kernel：
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index f349494..2f1b20e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
`@ -2536,7 +2536,7 `@ static void vop_update_csc(struct drm_crtc *crtc)
VOP_CTRL_SET(vop, dsp_data_swap, DSP_RB_SWAP);
else
VOP_CTRL_SET(vop, dsp_data_swap, 0);
+VOP_CTRL_SET(vop, dsp_data_swap, DSP_RB_SWAP);
VOP_CTRL_SET(vop, out_mode, s->output_mode);
```

Redmine记录

Defect #192157 RK3399 industry android7.1 DSI显示RGB颜色位不能交换。 https://redmine.rockchip.com.cn/issues/192157

## 7 下拉窗口界面概率性闪竖条纹

问题原因

DDR频率调到太低导致

处理方案

1、显示的节点下漏了引用dmc节点；
2、vop的带宽统计数据不对，需要更新；

https://10.10.10.29/#/c/rk/kernel/+/64573/
https://10.10.10.29/#/c/rk/kernel/+/64602/

Redmine记录

Defect #193086 下拉窗口界面概率性闪竖条纹 https://redmine.rockchip.com.cn/issues/193086

## 8 RK FB框架读写显示的数据

问题原因

客户希望从应用层读到显示的buf或者将一帧数据通过cmd送显示

处理方案

可以参考drivers/video/rockchip/rkfb_sysfs.c中set_dsp_buffer的实现，这边其实也提供通过串口将一张bmp的图片或者bin文件送显示；
可以cat /sys/class/graphics/fb0/dsp_buf
看操作说明

Redmine记录

Defect #192004 hwc问题咨询 https://redmine.rockchip.com.cn/issues/192004#change-1731935

## 9 RGB666的屏显示有条纹

问题原因

1. 客户板子个别应缴虚焊导致部分数据丢失；
2. RK3308只能支持RGB666输出，对接RGB888的屏本身也会出现数据丢失

处理方案

1. 硬件解决虚焊问题；
2. 如果非要接RGB888的屏，建议可以使用RK3308B。

Redmine记录

Defect #194917 Mcuzone野芯科技_RK3308_RGB666LCD_显示不正常 https://redmine.rockchip.com.cn/issues/194917 

## 10 RGB屏显示有斑点

问题原因

VCCIO 1.8V和3.3V配置错误，导致一些lcdc data引脚拉不高或者拉不低，出现显示斑点；

处理方案

只在RK3308上出现，最新的evb板参考dts配置文件已经修正。

Redmine记录

Defect #194420 RK3308_LINUX_SDK_V1.00_20180510( uboot下的logo显示有斑点) https://redmine.rockchip.com.cn/issues/194420

## 11 RK3288 VOP做镜像处理

问题原因

有些客户磨具搞错，屏幕需要做180°旋转，可以打开VOP的x、y mirror功能

处理方案

可以打开vop x，ymirror功能

linux 3.10内核：

​	可以参考display_patches工程的补丁：panelMirror/rk_fb/rk3288_android_6.0_mirror.patch

linux 4.4内核：

​	可以参考display_patches工程的说明：panelMirror/drm/README.md

Redmine记录

Defect #229079 rk3288 android5.1 lvds屏镜像

## 12 调节亮度、对比度、饱和度、色度

处理方案

linux 4.4内核

默认值为50，可以按下面的命令做调整：
setprop persist.sys.brightness.main 50;setprop persist.sys.contrast.main 50;setprop persist.sys.hue.main 50;setprop persist.sys.saturation.main 50;
setprop sys.display.timeline 设定值+1

linux 3.10内核

参考文档：《《基于RK FB显示框架的常见问题.pdf》第三节是BCSH使用说明

Redmine记录

Defect #193922 android8.0中调节色彩和对比度

Defect #199483 rk3128 4.4 LCD图像显示效果问题

## 13 VOP时钟配置问题

问题原因

rk3399 连接HDMI的那个vop dclk要从vpll分，另一个vop的dclk要从cpll分。

处理方案

按如下修改：

```c
&vopb {
assigned-clocks = <&cru DCLK_VOP0_DIV>;
assigned-clock-parents = <&cru PLL_VPLL>;
};

&vopl {
assigned-clocks = <&cru DCLK_VOP1_DIV>;
assigned-clock-parents = <&cru PLL_VPLL>;
};
```

Redmine记录

Defect #196844 深圳鸿创达-rk33399 android７.1 hdmi切换分辨率时报错

## 14 LPDDR3/LPDDR4带宽问题

问题描述

使用LPDDR3/LPDDR4在一些场景出现带宽不够闪屏现象，和底层平台负责DDR的同事确认，DDR性能上LPDDR4<LPDDR3<DDR3，可以通过io命令在特定场景调节leatendy:

针对RK3399平台，bit[31: 24],默认是0x80,这个值配置越小，VOP取数的实时性就越高，但是其他模块插进来的机会就越少，所以如果调小这个值会提高VOP访问的实时性但会对GPU/CPU等模块的性能产生影响；

```c
io -4 0xffa84010 0x200d080d;io -4 0xffa8c010 0x200d080d
```

回读确认：

```c
io -4 0xffa84010;io -4 0xffa8c010
```

确认到合适的值后可以写道板级的dts文件中：

```c
&dmc {

vop-pn-msch-readlatency = <

	/* plane_number readlatency */

	+0	0x20

	+4 	0x20

> ;

};
```

## 15 VOP挂掉问题

现象

这个问题一般会导致显示花屏，绿屏；

可能出现的log信息

```c
[    2.927676] rk_iommu ff940300.iommu: FORCE_RESET command timed out
[    2.927693] rockchip-vop ff940000.vop: Failed to attach iommu device
[    2.927715] rockchip-vop ff940000.vop: failed to attach dma mapping, -110
[    3.271055] rk_iommu ff940300.iommu: Enable stall request timed out, status: 0x000011
```

或者

```c
[ 1121.915803] rockchip-vop ff900000.vop: [drm:vop_isr] *ERROR* POST_BUF_EMPTY irq err
[ 1121.916109] rockchip-vop ff900000.vop: [drm:vop_isr] *ERROR* POST_BUF_EMPTY irq err
[ 1121.916162] rockchip-vop ff900000.vop: [drm:vop_isr] *ERROR* POST_BUF_EMPTY irq err
[ 1121.916197] rockchip-vop ff900000.vop: [drm:vop_isr] *ERROR* POST_BUF_EMPTY irq err
```

原因

客户的项目可能存在PMIC配置不对或者硬件设计问题导致logic那路的电压太低，低于VOP的工作电压会直接导致VOP IP异常；

处理方案

可以按如下步骤让客户确认：

1. 用示波器抓取从正常到异常过程中logic的电压；
2. dts或者硬件修改，将logic电压提高100mv；
3. 再次用示波器抓取相同场景的logic电压，确认客户修改有成功；

## 16 播放4096视频显示异常

问题原因

VOP linebuffer模式配置错误导致播放3840的视频正常，播放4096的视频异常；

处理方案

最新代码已经修改，旧代码可以参考如下修改：

```c
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -640,9 +640,9 @@ static inline int scl_vop_cal_lb_mode(int width, bool is_yuv)
 {
 	int lb_mode;

- if (width > 2560)

+ if (!is_yuv && (width > 2560))
  lb_mode = LB_RGB_3840X2;

- else if (width > 1920)

+ else if (!is_yuv && (width > 1920))
  lb_mode = LB_RGB_2560X4;
   	else if (!is_yuv)
   		lb_mode = LB_RGB_1920X5;
```

Redmine记录

Defect #199553 rk3399 edp 是否支持4096x2304屏 https://redmine.rockchip.com.cn/issues/199553#change-1787391

## 17 各个版本LVDS差分电压、共模电压调整问题

问题原因

由于不同硬件板子的差异性，有些板子需要调整这些参数；

处理方案

可以参考display_patches工程的说明：lvds各个版本spec确认.xlsx

## 18 各个版本RGB接口驱动强度调整问题

问题原因

由于不同硬件板子的差异性，有些板子需要调整这些参数；

处理方案

可以参考文档《基于RK FB显示框架的常见问题.pdf》第十三章节；

## 19 VOP mmu pagefault问题

问题原因

目前的驱动代码软件逻辑上已经可以保证不会出现iommu pagefault问题，偶尔还会看到VOP iommu pagefault的log，可能是以下几个原因：

1. logic电压太低，导致VOP IP异常；
2. RK3288/px30 VOP在带宽紧张的情况下可能出现iommu pagefault问题；

处理方案

1. 针对原因1可以通过提高logic电压解决；

 	2. 针对原因2可以通过提高DDR频率来解决；

Redmine记录

Defect #197247 商汤科技 RK3399 ANDRIOD 7.1 正常关机跑飞报错 https://redmine.rockchip.com.cn/issues/197247

## 20 HDMI分辨率切换导致绿屏死机问题

问题原因

早期的drm驱动在切分辨率的时候没有关闭afbdc导致；

处理方案

更新到最新代码或者加上下面的修改：

```c
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -1374,6 +1374,7 @@ static void vop_crtc_disable(struct drm_crtc *crtc)

  vop_lock(vop);
  drm_crtc_vblank_off(crtc);

+ VOP_CTRL_SET(vop, afbdc_en, 0);
  vop_disable_all_planes(vop);
```

Redmine记录

Defect #205074 新板子切换制式高概率出现绿屏 https://redmine.rockchip.com.cn/issues/205074

## 21 HDMI EDID读取失败的情况下如何加入4k分辨率的支持

问题原因

一些板子硬件问题会出现edid分辨率读取失败导致设置选项中不支持4k分辨率输出，但有时候为了测试方便又需要4k分辨率支持，这种情况下可以在驱动中强制加入4k分辨率支持；

处理方案

```c
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2572,7 +2572,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
                                             connector);
        struct edid *edid;
        struct drm_display_mode *mode;

- const u8 def_modes[6] = {4, 16, 31, 19, 17, 2};

+ const u8 def_modes[6] = {4, 16, 31, 19, 17, 2, 96, 97};
  struct drm_display_info *info = &connector->display_info;
  struct hdr_static_metadata *metedata =
```

## 22 HDMI显示屏桌面壁纸的背光忽明忽暗

问题原因

VOP CSC转换系数配置不对，导致VOP和GPU CSC转换效果不一样，出现忽明忽暗的效果；

处理方案

加入vop win lite 的csc转换系数，最新代码已经提交，如果是客户早期的代码可以参考display_patches工程的补丁：0001-drm-rockchip-vop-add-extern-csc-for-rk3399-win-lite.patch

Redmine记录

Defect #192784 HDMI显示屏桌面壁纸的背光忽明忽暗 https://redmine.rockchip.com.cn/issues/192784#change-1751222

## 23 去掉VOP Dither功能

问题原因

VOP full内部按10bit处理，所以所有数据默认会dither up到10bit再参与VOP内部的处理，根据输出接口决定是否dither down到8bit或者6bit。

一些客户的特殊项目希望保持原始数据不变，即输入什么数据就输出什么数据，可以参考下面的方法关闭vop内部所有的dither功能。

处理方案

```c
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 5ea33c4..b965f53 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
`@ -234,11 +234,11 `@ static const struct vop_ctrl rk3288_ctrl_data = {
.mipi_dclk_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0x1, 31, 3, 2, -1),
.mipi_pin_pol = VOP_REG_VER(RK3368_DSP_CTRL1, 0x7, 28, 3, 2, -1),

- .dither_down_sel = VOP_REG(RK3288_DSP_CTRL1, 0x1, 4),
- .dither_down_mode = VOP_REG(RK3288_DSP_CTRL1, 0x1, 3),
- .dither_down_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 2),
- .pre_dither_down_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 1),
- .dither_up_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 6),
+ //.dither_down_sel = VOP_REG(RK3288_DSP_CTRL1, 0x1, 4),
+ //.dither_down_mode = VOP_REG(RK3288_DSP_CTRL1, 0x1, 3),
+ //.dither_down_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 2),
+ //.pre_dither_down_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 1),
+ //.dither_up_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 6),
```

## 24 切换分辨率死机重启问题

出现的log：

```c
[   21.432332] Internal error: Accessing user space memory outside uaccess.h routines: 96000005 [#1] PREEMPT SMP
[   21.433228] Modules linked in:
[   21.433530] CPU: 3 PID: 716 Comm: ndroid.settings Not tainted 4.4.83 #121
[   21.434130] Hardware name: Rockchip RK3399 Excavator Board edp (Android) (DT)
[   21.434768] task: ffffffc0cd63e800 task.stack: ffffffc0cd630000
[   21.435304] PC is at kmem_cache_alloc_trace+0xa8/0x204
[   21.435776] LR is at binder_transaction+0x58c/0x1c44
......
[   21.572340] [<ffffff80081ad584>] kmem_cache_alloc_trace+0xa8/0x204
[   21.572890] [<ffffff800893964c>] binder_transaction+0x58c/0x1c44
[   21.573424] [<ffffff800893cd08>] binder_thread_write+0xa44/0x136c
[   21.573968] [<ffffff800893d710>] binder_ioctl_write_read+0xe0/0x314
[   21.574523] [<ffffff800893db14>] binder_ioctl+0x1d0/0x668
[   21.575010] [<ffffff80081c77b8>] do_vfs_ioctl+0x5e4/0x720
[   21.575494] [<ffffff80081c7954>] SyS_ioctl+0x60/0x88
[   21.575936] [<ffffff8008083170>] el0_svc_naked+0x24/0x28
```
或者

```c
[  549.171031] Internal error: Accessing user space memory outside uaccess.h routines: 96000005 [#1] PREEMPT SMP
[  549.171920] Modules linked in:
[  549.172213] CPU: 2 PID: 2575 Comm: surfaceflinger Not tainted 4.4.83 #121
[  549.172810] Hardware name: Rockchip RK3399 Excavator Board edp (Android) (DT)
[  549.173444] task: ffffffc0b851a700 task.stack: ffffffc0b2a40000
[  549.173973] PC is at kmem_cache_alloc_trace+0xa8/0x204
[  549.174437] LR is at drm_flip_work_allocate_task+0x2c/0x4c
[  549.174920] pc : [<ffffff80081ad584>] lr : [<ffffff800848ce04>] pstate: 60400145
......
[  549.285299] [<ffffff80081ad584>] kmem_cache_alloc_trace+0xa8/0x204
[  549.285845] [<ffffff800848ce04>] drm_flip_work_allocate_task+0x2c/0x4c
[  549.286422] [<ffffff800848d020>] drm_flip_work_queue+0x38/0xa4
[  549.286942] [<ffffff80084a7a30>] vop_crtc_atomic_flush+0x1f48/0x2274
[  549.287509] [<ffffff800846add4>] drm_atomic_helper_commit_planes+0x194/0x1bc
[  549.288136] [<ffffff80084a0584>] rockchip_atomic_commit_complete+0x58/0xa0
[  549.288750] [<ffffff80084a0750>] rockchip_drm_atomic_commit+0x184/0x1a4
[  549.289340] [<ffffff800848e678>] drm_atomic_commit+0x64/0x70
[  549.289848] [<ffffff800848f960>] drm_mode_atomic_ioctl+0x4fc/0x604
[  549.290393] [<ffffff8008473368>] drm_ioctl+0x278/0x3f8
[  549.290856] [<ffffff80081c77b8>] do_vfs_ioctl+0x5e4/0x720
[  549.291339] [<ffffff80081c7954>] SyS_ioctl+0x60/0x88
[  549.291778] [<ffffff8008083170>] el0_svc_naked+0x24/0x28
```

DRM驱动bug，最新的内核代码已经解决，旧的代码可以参考下面的修改：

```c
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
`@ -2345,7 +2345,8 `@ static size_t vop_plane_line_bandwidth(struct drm_plane_state *pstate)
int vskiplines = scl_get_vskiplines(src_height, dest_height);
size_t bandwidth;

- if (!src_width || !src_height || !dest_width || !dest_height)
+ if (src_width <= 0 || src_height <= 0 || dest_width <= 0 ||
+ dest_height <= 0)
```

```c
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -2232,19 +2232,22 @@ static size_t vop_crtc_bandwidth(struct drm_crtc *crtc,
        u16 htotal = adjusted_mode->crtc_htotal;
        u16 vdisplay = adjusted_mode->crtc_vdisplay;
        int clock = adjusted_mode->crtc_clock;
-       struct vop *vop = to_vop(crtc);
-       const struct vop_data *vop_data = vop->data;
        struct vop_plane_state *vop_plane_state;
        struct drm_plane_state *pstate;
        struct vop_bandwidth *pbandwidth;
        struct drm_plane *plane;
        u64 bandwidth;
-       int i, cnt = 0;
+       int i, cnt = 0, plane_num = 0;
 
        if (!htotal || !vdisplay)
                return 0;
 
-       pbandwidth = kmalloc_array(vop_data->win_size, sizeof(*pbandwidth),
+       for_each_plane_in_state(state, plane, pstate, i) {
+               if (pstate->crtc != crtc || !pstate->fb)
+                       continue;
+               plane_num++;
+       }
+       pbandwidth = kmalloc_array(plane_num, sizeof(*pbandwidth),
                                   GFP_KERNEL);
```

## 25 DRM驱动内存泄漏

问题原因

DRM驱动bug，最新的内核代码已经解决，旧的代码可以参考下面的修改：

```c
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -1834,6 +1834,7 @@ static size_t vop_crtc_bandwidth(struct drm_crtc *crtc,
        sort(pbandwidth, cnt, sizeof(pbandwidth[0]), vop_bandwidth_cmp, NULL);
 
        bandwidth = vop_calc_max_bandwidth(pbandwidth, 0, cnt, vdisplay);
+       kfree(pbandwidth);
        /*
         * bandwidth(MB/s)
```

## 26 需要关闭AFBDC的场景

场景1：非16x4像素对齐的屏

由于afbdc按块处理，每块的大小是16x4像素，所以afbdc处理的数据需要按16x4 pixel对齐，否则需要关闭afbdc；

场景2：HDMI interlace输出模式

关闭方法：

```c
目录：hardware/rockchip/libgralloc
修改方法：
diff --git a/Android.mk b/Android.mk  
index dd3d518..f99dd33 100644  
--- a/Android.mk  
+++ b/Android.mk  
@@ -128,7 +128,7 @@ MALI_USE_YUV_AFBC_WIDEBLK?=0  
 GRALLOC_INIT_AFBC?=1  
   
 # for bifrost GPU, use afbc layer by default.  
-USE_AFBC_LAYER = 1  
+USE_AFBC_LAYER = 0  
   
 ifeq ($(strip $(TARGET_BOARD_PLATFORM)),rk3399)  
 USE_AFBC_LAYER = 1 
对应的库
 Android 7.1： 
32位
	system/lib/libgralloc_drm.so 
	system/lib/hw/gralloc.rk30board.so 
64位
	system/lib64/libgralloc_drm.so 
	system/lib64/hw/gralloc.rk30board.so 
Android 8.1及以上：  
32位
	vendor/lib/libgralloc_drm.so 
	vendor/lib/hw/gralloc.rk30board.so 
64位
	vendor/lib64/libgralloc_drm.so 
	vendor/lib64/hw/gralloc.rk30board.so 
```

## 27 HDMI/CVBS interlace输出模式下出现错场问题

现象

分辨率进行多次切换后显示糊掉，从现象看是奇数场和偶数场错位了导致

处理方案

将VOP输出的场生效改成帧生效，每提交一帧送出2场，这样可以保证不会奇偶场错位：

```c
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index ead313b..6fb3c0f 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@ -186,7 +186,7 @ static const struct vop_ctrl rk3288_ctrl_data = {
.dma_stop = VOP_REG(RK3288_SYS_CTRL, 0x1, 21),
.axi_outstanding_max_num = VOP_REG(RK3288_SYS_CTRL1, 0x1f, 13),
.axi_max_outstanding_en = VOP_REG(RK3288_SYS_CTRL1, 0x1, 12),
- .reg_done_frm = VOP_REG_VER(RK3288_SYS_CTRL1, 0x1, 24, 3, 7, -1),
+ .reg_done_frm = VOP_REG_VER(RK3288_SYS_CTRL1, 0x1, 24, 3, 5, -1),
.htotal_pw = VOP_REG(RK3288_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
.hact_st_end = VOP_REG(RK3288_DSP_HACT_ST_END, 0x1fff1fff, 0),
.vtotal_pw = VOP_REG(RK3288_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
```

## 28 RK3368 CVBS模式下插拔HDMI导致屏闪

问题原因

RK3368 CVBS和HDMI功能一个VOP，所以有2个connector,连接通路如下：

VOP ->RGB->CVBS->TV

​        |->HDMI->TV

用于管理BCSH的tv_state需要同时在RGB驱动和HDMI驱动中初始化，否则会出现软件逻辑错误，针对RK3368出现该问题的修改已经提交，具体修改方法如下：

```c
--- a/drivers/gpu/drm/rockchip/rockchip_rgb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_rgb.c
@@ -26,6 +26,7 @@
 #include <linux/regmap.h>
 #include <linux/mfd/syscon.h>
 #include <linux/phy/phy.h>
+#include <uapi/linux/videodev2.h>
 
 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_vop.h"
@@ -194,6 +195,9 @@ rockchip_rgb_encoder_atomic_check(struct drm_encoder *encoder,
        }
 
        s->output_type = DRM_MODE_CONNECTOR_DPI;
+       s->tv_state = &conn_state->tv;
+       s->eotf = TRADITIONAL_GAMMA_SDR;
+       s->color_space = V4L2_COLORSPACE_DEFAULT;
```

## 29 Android7.1 微信与pc视屏通话会死机

问题原因

RK3288/PX30多区域不支持不同格式配置，这个场景下会使用win2的2个区域，格式分别是ARGB888和RGB565，导致IOMMU访问越界。

修改方法：

````c
diff --git a/hardware/rockchip/hwcomposer/hwc_rockchip.cpp b/hardware/rockchip/hwcomposer/hwc_rockchip.cpp
index ca9b525..49864e7 100755
--- a/hardware/rockchip/hwcomposer/hwc_rockchip.cpp
+++ b/hardware/rockchip/hwcomposer/hwc_rockchip.cpp
@ -948,6 +948,7 @ static bool is_layer_combine(DrmHwcLayer * layer_one,DrmHwcLayer * layer_two)
#ifdef TARGET_BOARD_PLATFORM_RK3288 || is_x_intersect(&layer_one->display_frame,&layer_two->display_frame)
#endif
+ || (layer_one->format != layer_two->format)
) {
ALOGD_IF(log_level(DBG_SILENT),"is_layer_combine layer one alpha=%d,is_scale=%d",layer_one->alpha,layer_one->is_scale);
@ -2012,7 +2013,7 @ AllMatch: {
float scale_factor = vop_band_width(hd, layers);
float head_factor = 0.0, tail_factor = 0.0;
- if(scale_factor > 4)
+ if(scale_factor > 6) {
ALOGD_IF(log_level(DBG_DEBUG), "scale_factor=%f is so big",scale_factor);
if(layers.size() >= 4)
````

Redmine记录：

Defect #223454 RK3288 Android7.1 微信与pc视屏通话会死机 https://redmine.rockchip.com.cn/issues/223454

## 30 DDR变频导致显示异常问题

问题原因

DDR变频需要在消隐期内完成，一些屏的消隐期一般在几十微秒到一百多微秒，而DDR变频需要一百多微秒，为了保证DDR变频能在消隐期内完成，在DDR开始变频前将DCLK降低，变频完成后再提高原来的DCLK。这个修改会导致一些对时钟敏感的屏显示异常。

处理方案

参考如下方法关闭DDR变频过程中修改DCLK 的处理流程：

```c
&dmc {
vop-dclk-mode = <1>;
}；
```

Redmine 记录：

Defect #224836 RK3288_ANDROID7.1_TABLET-SDK_V1.01视频播放导致显示花屏 https://redmine.rockchip.com.cn/issues/224836

## 31 RK3128双屏显示插拔HDMI显示花屏问题

问题原因

RK3128只有一个vop，所以在做双屏切换的时候需要改变时序，这会导致闪屏现象，目前的做法是在切换的时候关闭背光来解决这个问题

处理方案

具体可以参考display_patches工程的补丁：

fix_rk3128_one_dual_ouput_display_splash_screen_when_hdmi_plug.patch

Redmine 记录：

Defect #219426 RK3128 静态画面下，插拔HDMI out，会导致LVDS端输出花屏 https://redmine.rockchip.com.cn/issues/219426

## 32 双LVDS屏左右通道交换

问题原因

一些客户的板子可能会把双LVDS左右通道接反，需要软件做交换

处理方案

```c
--- a/drivers/video/rockchip/transmitter/rk32_lvds.c
+++ b/drivers/video/rockchip/transmitter/rk32_lvds.c
@@ -89,6 +89,7 @@ static int rk32_lvds_en(void)
 	val |= (screen->pin_dclk << 8) | (screen->pin_hsync << 9) |
 		(screen->pin_den << 10);
 	val |= (0xffff << 16);
+	val |= LVDS_FMT_1;
 	grf_writel(val, RK3288_GRF_SOC_CON7);
 
 	if (screen->type == SCREEN_RGB) {
```

Redmine 记录：

Defect #222894 RK3288 lvds屏奇偶场交换需要怎样修改 https://redmine.rockchip.com.cn/issues/222894#change-2050009

## 33 HDMI显示亮度不够

问题原因

如果将HDMI设置为YUV输出，那在UI场景需要做RGB2YUV的操作，这会带来一定的数据丢失，那些对原始RGB数据准确性要求较高产品，可以在设置里面将HDMI设置为RGB输出。

Redmine 记录：

Defect #224399 rk3328 android 7.1 一进入android系统主界面，整体界面颜色变暗 open,hdmi输入改成RGB后亮度提高了70nit

## 34 DRM驱动bind失败

异常log

```c
 3.882822] [drm:rockchip_dp_bind] ERROR failed to find panel
[ 3.882828] rockchip-drm display-subsystem: failed to bind ff970000.dp (ops 0xc0c5b454): -517
[ 3.883519] rockchip-drm display-subsystem: master bind failed: -517

……

[ 3.886287] [drm:rockchip_dp_bind] ERROR failed to find panel
[ 3.886293] rockchip-drm display-subsystem: failed to bind ff970000.dp (ops 0xc0c5b454): -517
[ 3.887021] rockchip-drm display-subsystem: master bind failed: -517
```

分析

这种情况一般是2个原因：

1. dts文件panel节点的GPIO或者regulator有冲突，导致panel注册失败；
2. encoer、connector或者bridge驱动注册失败；

处理方法

根据log提示排查panel或者其他drm sub_driver加载失败的原因。

## 35 DRM驱动如何获取内核空间的虚拟地址

修改方法

```c
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@ -676,7 +676,7 @ rockchip_gem_create_with_handle(struct drm_file *file_priv,
struct drm_gem_object *obj;
int ret;

- rk_obj = rockchip_gem_create_object(drm, size, false, flags);
+ rk_obj = rockchip_gem_create_object(drm, size, true, flags);
if (IS_ERR(rk_obj))
return ERR_CAST(rk_obj);

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index f85fd57..6c6da91 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@ -1774,6 +1774,8 @ static void vop_plane_atomic_update(struct drm_plane *plane, * spi interface(vop_plane_state->yrgb_kvaddr, fb->pixel_format, * actual_w, actual_h)
*/

//vop_plane_state->yrgb_kvaddr
```

vop_plane_state->yrgb_kvaddr即为内核空间的虚拟地址，如果客户是要获取整屏的显示数据，需要将hwc关闭。

Redmine 记录：

Defect #228322 [3328] 【内核】 做内核DRM驱动，如何得到当前显示的图像像素地址

## 35 RGB屏不支持BCSH调整

问题原因

中间有一个版本把RGB显示接口的BCSH调整功能删了，可以同步到最新代码或者加入下面的修改：

````c
commit ce05fde82358377d92102332afc69be25f649280
Author: Sandy Huang <hjc@rock-chips.com>
Date:   Tue Aug 13 09:58:54 2019 +0800

    drm/rockchip: rgb: init eotf and color space for tv output

    Change-Id: Ieb5891dbee664c4fe283db6f075a811be1b4bd25
    Signed-off-by: Sandy Huang <hjc@rock-chips.com>

diff --git a/drivers/gpu/drm/rockchip/rockchip_rgb.c b/drivers/gpu/drm/rockchip/rockchip_rgb.c
index 04b04d7..0d28493 100644
--- a/drivers/gpu/drm/rockchip/rockchip_rgb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_rgb.c
@@ -26,6 +26,7 @@
 #include <linux/regmap.h>
 #include <linux/mfd/syscon.h>
 #include <linux/phy/phy.h>
+#include <uapi/linux/videodev2.h>

 #include "rockchip_drm_drv.h" 
 #include "rockchip_drm_vop.h" 
@@ -194,6 +195,9 @@ rockchip_rgb_encoder_atomic_check(struct drm_encoder *encoder,
        }

        s->output_type = DRM_MODE_CONNECTOR_DPI;
+       s->tv_state = &conn_state->tv;
+       s->eotf = TRADITIONAL_GAMMA_SDR;
+       s->color_space = V4L2_COLORSPACE_DEFAULT;

        return 0;
 }
````

Redmine 记录：

Defect #228473 RK3308B 和 RK3308H 的VOP是否支持RGB656图片的缩放

## 36 Per-pixel alhap 无法做到全透

问题原因

VOP驱动的bug，在Per-pixel alpha为255的之后src alpha value会变成1，导致src图层会成上系数1。

修改方法：

```c
commit 3af05ecdc10c99d0a457caf703376d7a0b65388e
Author: chris.zheng <chris.zheng@rock-chips.com>
Date:   Tue Oct 29 14:50:07 2019 +0800

    drm/rockchip: vop: fix per-pixel alpha[255] calc error
    
    Signed-off-by: chris.zheng <chris.zheng@rock-chips.com>

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 2fd34f0..50579a2 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -1766,7 +1766,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
                val = SRC_ALPHA_EN(1) | SRC_COLOR_M0(ALPHA_SRC_PRE_MUL) |
                        SRC_ALPHA_M0(ALPHA_STRAIGHT) |
                        SRC_BLEND_M0(src_bland_m0) |
-                       SRC_ALPHA_CAL_M0(ALPHA_NO_SATURATION) |
+                       SRC_ALPHA_CAL_M0(ALPHA_SATURATION) |
                        SRC_FACTOR_M0(global_alpha_en ?
                                      ALPHA_SRC_GLOBAL : ALPHA_ONE);
                VOP_WIN_SET(vop, win, src_alpha_ctl, val);
```

## 37 MCU屏帧率计算问题

MCU屏帧率计算：

如果是并行的RGB888/RGB666接口，fps = dclk/(htotal * vtotal * （mcu-pix-total + 1）)

如果是串行的SRGB888/SRGB666接口，fps = dclk/(htotal * vtotal * （mcu-pix-total +1）* 3)

普通屏帧率计算：

如果是并行的RGB888/RGB666接口，fps = dclk/(htotal * vtotal)

如果是串行的SRGB888/SRGB666接口，fps = dclk/(htotal * vtotal * 3)

htotal = hactive + hback-porch + hfront-porch + hsync-len

vtotal = vactive + vback-porch + vfront-porch+ vsync-len

Redmine 记录：

Defect #228040 Rk3308 MCU屏显示异常 https://redmine.rockchip.com.cn/issues/228040

## 38 BCSH打开后有色阶问题

问题原因

在一些渐变色的场景由于BCSH会数据做了修改导致这种现象；

修改方法

建议将渐变色的场景改成纯色场景，或者关闭BCSH功能；

## 39 VOP 缩放限制

vop full

rk3399/rk3328/rk3368/rk322x/rk3288这几个芯片是基于vop full框架修改，对缩放有以下限制：

水平方向没缩放，若源数据大于2560 pixel，则垂直方向不支持缩放；

水平方向有缩放，若目标大小大于2560 pixel，则垂直方向不支持缩放；

vop lite

除了以上几个平台之外，其他都是基于vop lite框架设计：

不支持pixel alpha + scale同时存在

## 40 显示有雪花点、水波纹

比较可能有以下3个原因：

1. 修改dclk极性，在dts配置中：pixelclk-active = <1>;

2. 关闭ddr变频中对dclk的修改

   ```c
   &dmc {
   vop-dclk-mode = <1>;
   };
   ```

3. dclk或者hs-clk配置不对，参考屏的spec配置；

## 41 VOP time out问题

可能存在的log1：

```c
VOP vblank IRQ stuck for 10 ms
```

一般出现这个log是系统哪里有卡住，导致vop硬件终端来了，但是中端处理函数没有被调用；

可能存在的log2：

```
VOP wait vblank time out
```

出现这个log一般是dclk或者其他vop的配置不对，导致中断没来。

## 42 MCU屏引脚的复用关系

RD: 1：表示发数据到屏，0：表示从屏读数据；和DEN复用

CS: 片选信号，低有效；和VSYNC复用

RS: 1表示发送的是数据，0表示发送的是命令，和dclk复用

WR:写使能信号，上升沿有效  和SPI的SCL差不多， 和hsync复用

## 43 如何打开debug信息

rk fb

```c
	echo 1 >  /sys/module/rk_fb/parameters/rk_fb_debug_lvl
```

drm

```c
	echo 0x1f > /sys/module/drm/parameters/debug
```

## 44 logo图片白色背景需求

问题原因

一些vop用于uboot logo显示的图层不支持缩放，但是客户又有全屏显示的需求，所以有时候需要修改vop背景层的颜色，以白色为例，按如下修改：

```c
--- a/drivers/video/drm/rockchip_vop.c
+++ b/drivers/video/drm/rockchip_vop.c
@@ -411,7 +411,7 @@ static int rockchip_vop_init(struct display_state *state)
                val = 0x20010200;
        else
                val = 0x801080;
-       VOP_CTRL_SET(vop, dsp_background, val);
+       VOP_CTRL_SET(vop, dsp_background, 0xffffff);
```

Redmine 记录：

Defect #224100 开机logo只能选择居中显示，不能选择全屏显示，背景色不支持白色

## 45 alpha预乘与非预乘配置

问题原因

传统安卓的alpha的效果都是应用预乘好的，但在Linux或者一些新的系统上出现非预乘的需求，需要加入以下修改,通过blend mode属性来决定vop是做src*alpha动作：

```c
commit ce0ec8d27b704c51409ac331e929951a519bdb01
Author: Sandy Huang <hjc@rock-chips.com>
Date:   Sun Feb 11 16:54:27 2018 +0800

    drm/rockchip: vop: alpha_pre_mul mode depend on user space
    
    Change-Id: Iaada438902ddddbbd00890c53a58cc49af3c3d3e
    Signed-off-by: Sandy Huang <hjc@rock-chips.com>

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index b61acb0..82a4443 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -1138,6 +1138,12 @@ static int rockchip_drm_create_properties(struct drm_device *dev)
                return -ENOMEM;
        private->global_alpha_prop = prop;
 
+       prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
+                                        "BLEND_MODE", 0, 1);
+       if (!prop)
+               return -ENOMEM;
+       private->blend_mode_prop = prop;
```

## 46 uboot logo到kernel logo切换阶段插拔hdmi导致异常

问题原因

内核logo这段时间显示驱动刚注册完，这个时候做hdmi插拔很容引入边界问题，目前的做法是在内核阶段如果发现HDMI拔出，那就将显示关闭，发现HDMI插入不做处理，等到系统起来后再由应用使能显示；

修改记录：

```c
commit 77dbbdc036791c8cf48eaa80201a8cbb92d58bf2
Author: Sandy Huang <hjc@rock-chips.com>
Date:   Thu Mar 8 14:44:26 2018 +0800

    drm/rockchp: rk3328 vop: fix post empty when plug out hdmi
    
    case 1:
    plug in hdmi and power on, after kernel complete and before android
    start(maybe can update simplification boot.img) we plug out hdmi will
    appear error log.
    
    case 2:
    plug in hdmi and power on, at the beginning of drm driver bind, plug out
    hdmi, the hdmi irq maybe at disable state, so the vop is in running
    state which is set at uboot. in this case vop will not to enable clk
    refrerence, after driver probe complete, the unused clk maybe close by
    clk driver framework. this will lead to vop appear error log:
    
    [    4.898107] rockchip-vop ff370000.vop: [drm:vop_crtc_enable] Update mode to 720*288
    [    4.900174] rockchip-vop ff370000.vop: [drm:vop_isr] *ERROR*BUS_ERROR irq err
    
    solution:
    1. disable vop all planes before disable crtc and enable crtc;
    2. disable vop all planes when can't detect connect at power on.
    3. enable dma stop before detach iommu and disable dma stop after attach
    iommu.
    
    Change-Id: Ia981d52c96a274fa177493d10362fd4e395a6707
    Signed-off-by: Sandy Huang <hjc@rock-chips.com>
```

## 47 如何关闭logo显示

问题原因

有时候为了调试需要关闭logo显示，包括uboot logo和kernel logo，以edp屏为例，在对应的板极dts文件中做如下修改：

```
&route_edp {
	status = "disabled";
};
```

关闭后uboot logo和kernel logo都不显示，直到系统起来后由系统打开显示；

## 48 系统起来后如何强制开关显示

以lvds接口为例：

```
  打开显示：echo on  > /sys/class/drm/card0-LVDS-1/status
  关闭显示：echo off > /sys/class/drm/card0-LVDS-1/status
```

## 49 如何获取TV的edid信息

```
cat /sys/class/drm/card0-HDMI-A-1/edid > /data/edid.bin
```

拿到edid.bin后可以通过软件：980 Manager查看

## 50 drm显示暂停和启动

有时候为了方便debug，需要停在某些场景，可以使用下面的命令：

暂停：

```c
kill -STOP `pgrep surfaceflinger`
```

启动：

```c
kill -CONT `pgrep surfaceflinger
```

## 51 todo

……

