备注:本文涉及内容主要为摘录总结,均标注了出处,
mipi的 video mode和command mode
MIPI扫盲——DSI Command Mode vs Video Mode
MIPI video mode 和 command mode 的区别
总结 video mode和command mode区别
video mode: 主机需要定期刷新显示器,显示器不用帧缓冲器。
command mode: 显示器有全帧长的帧缓冲器来存储所有的像素数据。一旦数据被放在显示器的帧缓冲器中,定时控制器就从帧缓冲器中取出数据,并自动把他们显示在屏幕上。
所以区别在于缓冲器的位置,以及MIPI总线控制器是不是需要定期刷新数据。
TE 控制信号
mipi command mode 是通过TE PIN来同步的。
原理如下:
CPU先送一帧显示数据给panel,panel收到数据后开始从上往下刷新,等刷新到最后一行的时候,driver IC会从TE发送一个信号告诉CPU当前帧已经刷新完毕,可以送另一帧新数据过来了。如果panel的自我刷新率是60HZ,那么理论上从TE pin量到的信号也是60Hz。
后果:如果te不同步,那么就会出现图像撕裂,切屏或分屏现象
笔记分享 Display MIPI中的TE pin
LCD MIPI DSI简析系列之二
id pin
LCD_ID0 Output pin of LCD_ID0, conncet 1.8V
id pin在有设备接入的时候,为高电平,无设备时为低电平
在驱动中通过gpio捕获状态
设计驱动函数gpiod_direction_input 和 gpiod_get_value
如果引脚为 gpio1_B1
unsigned gpio = gpio 1 x 32 + 1 x 8 + 1 = 41
在kernel-5.10/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c
里添加id pin
struct gpio_desc *te_gpio;
+ struct gpio_desc *id_gpio;
在函数 dw_mipi_dsi2_connector_detect
中 添加判断,看返回 return connector_status_connected
或者return connector_status_disconnected
gpiod_direction_input(p->id_gpio); //GPIO设置为input
if( gpiod_get_value(p->id_gpio)) //获取gpio值
return connector_status_connected;
else
return connector_status_disconnected;
gpiod_direction_input 和 gpiod_get_value 函数原型
/**
* gpiod_direction_input - set the GPIO direction to input
* @desc: GPIO to set to input
*
* Set the direction of the passed GPIO to input, such as gpiod_get_value() can
* be called safely on it.
*
* Return 0 in case of success, else an error code.
*/
int gpiod_direction_input(struct gpio_desc *desc)
{
struct gpio_chip *gc;
int ret = 0;
VALIDATE_DESC(desc);
gc = desc->gdev->chip;
/*
* It is legal to have no .get() and .direction_input() specified if
* the chip is output-only, but you can't specify .direction_input()
* and not support the .get() operation, that doesn't make sense.
*/
if (!gc->get && gc->direction_input) {
gpiod_warn(desc,
"%s: missing get() but have direction_input()\n",
__func__);
return -EIO;
}
/*
* If we have a .direction_input() callback, things are simple,
* just call it. Else we are some input-only chip so try to check the
* direction (if .get_direction() is supported) else we silently
* assume we are in input mode after this.
*/
if (gc->direction_input) {
ret = gc->direction_input(gc, gpio_chip_hwgpio(desc));
} else if (gc->get_direction &&
(gc->get_direction(gc, gpio_chip_hwgpio(desc)) != 1)) {
gpiod_warn(desc,
"%s: missing direction_input() operation and line is output\n",
__func__);
return -EIO;
}
if (ret == 0) {
clear_bit(FLAG_IS_OUT, &desc->flags);
ret = gpio_set_bias(desc);
}
trace_gpio_direction(desc_to_gpio(desc), 1, ret);
return ret;
}
EXPORT_SYMBOL_GPL(gpiod_direction_input);
/**
* gpiod_get_value() - return a gpio's value
* @desc: gpio whose value will be returned
*
* Return the GPIO's logical value, i.e. taking the ACTIVE_LOW status into
* account, or negative errno on failure.
*
* This function can be called from contexts where we cannot sleep, and will
* complain if the GPIO chip functions potentially sleep.
*/
int gpiod_get_value(const struct gpio_desc *desc)
{
int value;
VALIDATE_DESC(desc);
/* Should be using gpiod_get_value_cansleep() */
WARN_ON(desc->gdev->chip->can_sleep);
value = gpiod_get_raw_value_commit(desc);
if (value < 0)
return value;
if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))
value = !value;
return value;
}
EXPORT_SYMBOL_GPL(gpiod_get_value);