此问题在我使用的SDK版本中存在,不知道后续更新有没有修复这个bug,暂且记录一下修复过程。
使用mipi接口的LCD上会出现这个问题,原因是mipi控制器驱动reset流程有问题,导致reset后LCD 初始化指令下发不到LCD上。
下面是我的修复方法:
1.思路就是在lcd prepare期间判断是dsi接口屏就给mipi控制器reset一下。由于lcd不能直接调用mipi控制器接口,我就自己定义了一条特殊的mipi指令,在mipi控制器驱动那边收到这条指令后进行reset操作。
2.修改到的代码如下:
//panel_simple.c
static int panel_simple_prepare(struct drm_panel *panel)
{
... ...
if (p->dsi)
mipi_dsi_dcs_hard_reset(p->dsi);
... ...
}
//drm_mipi_dsi.c 新增接口
static ssize_t mipi_dsi_device_transfer(struct mipi_dsi_device *dsi,
struct mipi_dsi_msg *msg)
{
const struct mipi_dsi_host_ops *ops = dsi->host->ops;
if (!ops || !ops->transfer)
return -ENOSYS;
if (dsi->mode_flags & MIPI_DSI_MODE_LPM)
msg->flags |= MIPI_DSI_MSG_USE_LPM;
msg->flags |= MIPI_DSI_MSG_LASTCOMMAND;
return ops->transfer(dsi->host, msg);
}
int mipi_dsi_dcs_hard_reset(struct mipi_dsi_device *dsi)
{
struct mipi_dsi_msg msg = {
.channel = dsi->channel,
.type = 0xff,
};
return mipi_dsi_device_transfer(dsi, &msg);
}
EXPORT_SYMBOL(mipi_dsi_dcs_hard_reset);
//dw-mipi-dsi2-rockchip.c
static ssize_t dw_mipi_dsi2_reset_device(struct dw_mipi_dsi2 *dsi2)
{
dw_mipi_dsi2_post_disable(dsi2);
dw_mipi_dsi2_pre_enable(dsi2);
return 0;
}
static ssize_t dw_mipi_dsi2_transfer(struct dw_mipi_dsi2 *dsi2,
const struct mipi_dsi_msg *msg)
{
struct mipi_dsi_packet packet;
int ret;
u32 val;
u32 mode;
//处理这个自定义的命令
if (msg->type == 0xFF) {
DRM_DEV_INFO(dsi2->dev, "reset dsi2 device\n");
return dw_mipi_dsi2_reset_device(dsi2);
}
... ...
}