Edit online

屏驱动说明

屏源码位置:Kernel: source/linux-5.10/drivers/video/artinchip/disp/panel/

新屏驱动支持

LCD 屏驱动,即 panel,本质上是一个回调函数的集合。新屏驱动实际上是重新实现 aic_panel_funcs 结构体中一个或多个回调接口。
注:

不需要初始化动作的 LCD 屏幕,如 RGB/ LVDS 屏幕,可通过 menuconfig 选择 panel_lvds_general.c/panel_rgb_general.c,在 board.dts 中修改相关参数即可。

在 panel 目录下,根据屏接口类型(RGB/LVDS/MIPI-DSI/MIPI-DBI)选择一个合适的模板,拷贝一个屏驱动。

  • MIPI-DSI 接口可参考 panel_dsi_xm91080.c

  • SRGB 接口可参考 panel_srgb_ili8961.c

  • MIPI-DBI 接口可参考 panel_dbi_ili9488.c

  1. 修改新屏驱动名字,将屏驱动添加进 panel 目录下的 Kconfig 和 Makefile 文件。
  2. 重新实现 aic_panel_funcs 结构体中的 prepare 或者 enable 接口,添加屏幕所需的初始化操作。
  1. 通用 RGB 屏幕驱动

    panel_rgb_general.c ,可通过 menuconfig 配置 选择。

  2. RGB 接口可配置参数
    • mode : PRGB/SRGB ,串行/并行模式
    • format : 24/18/16 bit 输出
    • clock phase : pixelclk 时钟输出相位
    • data order : R/G/B 三个分量输出顺序,支持任意组合
    • data mirror : R/G/B 组内高低位互换,0 - 7 输出 7 - 0
  3. 时序参数board.dts 文件 panel_rgb 节点 display-timings 子节点。
提示:

参数含义详见 配置章节

6.3.6.3.2.1.

6.3.6.3.2.2. LVDS 屏幕

  1. 通用 LVDS 屏幕驱动
    • panel_lvds_general.c ,可通过 menuconfig 选择
  2. LVDS 接口可配置参数

    • data-mapping : vesa-24/jeida-24/jeida-18 协议

    • data-channel : single/dual link 输出

    • link-swap : link 1 和 link 0 输出互换

    • lines : link 内部 5 个通道的差分信号输出顺序,允许 5 对差分信号任意互换

    • pols : link 内部 5 个通道差分信号的极性

  3. 时序参数

    • board.dts 文件 panel_lvds 节点 display-timings 子节点

小技巧

参数含义详见 panel_lvds 配置章节和 LVDS Display Interface 配置章节

mipi 屏幕

  1. 在发送 init_sequence 之前需要调用 panel_mipi_send_perpare 确保屏幕能正确无误地接受到命令。

  2. 在发送完 init_sequence 后需要调用 panel_mipi_setup_realmode 设置正确的 mipi 模式。

  3. panel_dsi.c 中为 mipi-dsi 的 init_sequence 封装了两个接口:

    1. panel_dsi_dcs_send_seq :发送屏厂根据 mipi 协议扩展的 command

    2. panel_dsi_generic_send_seq :发送 mipi 协议标准的 command

额外 gpio

  1. 结构体默认支持两个 gpio
    1. 一个 enable gpio , 可用于控制背光,使能屏幕

    2. 一个 sleep gpio, 可用于控制屏幕供电,休眠唤醒

如果需要添加更多 gpio 引脚,可参考 panel_dsi_wuxga_7in.c/panel_srgb_ili8961.c

时序参数

  1. LCD 的 timing 参数,既可以在驱动中使用 hardcode 的方式设置 struct videomode,也可以在 board.dts 中通过 display-timings 节点设置。

  2. 如果 timing 参数采用 hardcode 方式设置,board.dts 必须删除 display-timings 节点。不然屏驱动源码中的 timing 参数会被 dts 中的 timing 参数覆盖。其他屏参数不受此影响。

数据结构

  • struct panel_comp
    struct panel_comp {
        struct aic_panel panel;
        struct display_timings *timings;
        bool   use_dt_timing;
        struct backlight_device *backlight;
        struct regulator *supply;
        struct gpio_desc *enable_gpio;
        struct gpio_desc *sleep_gpio;
    };
  • struct aic_panel
    struct aic_panel {
        struct aic_panel_funcs *funcs;
        struct aic_panel_callbacks callbacks;
        struct videomode *vm;
        struct device *dev;
        union {
            struct panel_rgb *rgb;
            struct panel_lvds *lvds;
            struct panel_dsi *dsi;
        };
    };
  • struct aic_panel_funcs
    panel 提供,供 fb 调用的回调。新屏驱动必须实现。
    /* Each panel driver should define the follow functions. */
    struct aic_panel_funcs {
        int (*prepare)(struct aic_panel *panel);
        int (*enable)(struct aic_panel *panel);
        int (*disable)(struct aic_panel *panel);
        int (*unprepare)(struct aic_panel *panel);
        int (*get_video_mode)(struct aic_panel *panel, struct videomode *vm);
        int (*register_callback)(struct aic_panel *panel,
                    struct aic_panel_callbacks *pcallback);
    };
  • struct aic_panel_callbacks
    panel 无需实现,由 DE、DI 提供,供 panel 调用的回调。
    struct aic_panel_callbacks {
        int (*di_enable)(void);
        int (*di_disable)(void);
        int (*di_send_cmd)(u32 dt, u32 vc, s8 *data, u32 len);
        int (*di_set_videomode)(struct videomode *vm, int enable);
        int (*timing_enable)(void);
        int (*timing_disable)(void);
    };
  • struct panel_rgb
    rgb 接口屏幕参数
    struct panel_rgb {
        unsigned int mode;
        unsigned int format;
        unsigned int clock_phase;
        unsigned int data_order;
        bool data_mirror;
    };
    struct panel_rgb {
        unsigned int mode;
        unsigned int format;
        unsigned int clock_phase;
        unsigned int data_order;
        unsigned int data_mirror;
    };
  • struct panel_lvds
    lvds 接口屏幕参数
    struct panel_lvds {
        enum lvds_mode mode;
        enum lvds_link_mode link_mode;
    };
  • struct panel_dsi
    dsi 接口屏幕参数
    struct panel_dsi {
        enum dsi_mode mode;
        enum dsi_format format;
        unsigned int lane_num;
    };
  • struct panel_dbi
    mipi-dbi 接口屏幕参数
    struct panel_dbi_commands {
        const u8 *buf;
        size_t len;
    };
    
    struct spi_cfg {
        unsigned int qspi_mode;
        unsigned int vbp_num;
        unsigned int code1_cfg;
        unsigned int code[3];
    };
    
    struct panel_dbi {
        unsigned int type;
        unsigned int format;
        unsigned int first_line;
        unsigned int other_line;
        struct panel_dbi_commands commands;
        struct spi_cfg *spi;
    };

函数接口

1. panel_default_prepare
接口定义 int panel_default_prepare(struct aic_panel *panel)
功能说明 默认的 prepare 接口函数,使能 regulator
参数定义 结构体 aic_panel
返回值 0: 成功 负数:失败
注意事项 -
2. panel_default_enable
接口定义 int panel_default_enable(struct aic_panel *panel)
功能说明 默认的 enable 接口函数,设置 de 模块的 timing 参数,使能相应的 DI 接口,开启背光
参数定义 结构体 aic_panel
返回值 0:成功
注意事项 -
3. panel_default_unprepare
接口定义 int panel_default_unprepare(struct aic_panel *panel)
功能说明 默认的 unprepare 接口函数,禁用 regulator
参数定义 结构体 aic_panel
返回值 0:成功
注意事项 -
4. panel_default_disable
接口定义 int panel_default_disable(struct aic_panel *panel)
功能说明 默认的 disable 接口函数,禁用背光,禁用 DI 接口,禁用 DE
参数定义 结构体 aic_panel
返回值 0:成功
注意事项 -
5. panel_register_callback
接口定义 int panel_register_callback(struct aic_panel *panel, struct aic_panel_callbacks *pcallback)
功能说明 DE,DI 提供的回调函数,供 panel 调用
参数定义 结构体 aic_panel

结构体 aic_panel_callbacks

返回值 0:成功
注意事项 -
6. panel_default_get_video_mode
接口定义 int panel_default_get_video_mode(struct aic_panel *panel, struct videomode *vm)
功能说明 panel 提供的回调,供 fb 调用,传递从 dts 中解析的 timing 参数
参数定义 videomode:包含屏幕的 timing 参数
返回值 0:成功
注意事项 -
7. panel_parse_dts
接口定义 int panel_parse_dts(struct panel_comp *p, struct device *dev);
功能说明 解析 dts 中的 panel 结点
参数定义 panel_comp ,结构体 device
返回值 0:成功
注意事项 -
8. panel_di_enable
接口定义 void panel_di_enable(struct aic_panel *panel, u32 ms)
功能说明 使能相应的 DI 接口
参数定义 结构体 aic_panel, ms 延时毫秒
返回值 void
注意事项 -
9. panel_di_disable
接口定义 void panel_di_disable(struct aic_panel *panel, u32 ms)
功能说明 禁用相应的 DI 接口
参数定义 结构体 aic_panel, ms 延时毫秒
返回值 void
注意事项 -
10. panel_de_timing_enable
接口定义 void panel_de_timing_enable(struct aic_panel *panel, u32 ms)
功能说明 启用 DE, 设置 de 模块的 timing 参数
参数定义 结构体 aic_panel, ms 延时毫秒
返回值 void
注意事项 -
11. panel_de_timing_disable
接口定义 void panel_de_timing_disable(struct aic_panel *panel, u32 ms)
功能说明 禁用 DE, 设置 de 模块的 timing 参数
参数定义 结构体 aic_panel, ms 延时毫秒
返回值 void
注意事项 -
12. panel_mipi_send_perpare
接口定义 void panel_mipi_send_perpare(struct aic_panel *panel)
功能说明 将 dsi 通道切换到 command mode, 准备好给 mipi 屏幕发送初始化命令
参数定义 结构体 aic_panel
返回值 void
注意事项 在 mipi 屏幕发送初始化命令前要先调用这个函数,以确保 mipi 屏幕收到正确的初始化命令
13. panel_send_command
接口定义 void panel_send_command(u8 *para_cmd, u32 size, struct aic_panel *panel)
功能说明 给 mipi 屏幕发送初始化命令
参数定义 结构体 aic_panel , 初始化序列大小 size, 初始化序列 para_cmd
返回值 void
注意事项 -
14. panel_mipi_setup_realmode
接口定义 void panel_send_command(u8 *para_cmd, u32 size, struct aic_panel *panel)
功能说明 将 dsi 通道切换回正确的模式
参数定义 结构体 aic_panel
返回值 void
注意事项 在 mipi 屏幕发送完初始化命令后调用这个函数,以确保 mipi 通道正常工作
15. panel_dsi_generic_send_seq
接口定义 #define panel_dsi_generic_send_seq(panel, seq…)
功能说明 发送屏厂根据 mipi 协议扩展的 command
参数定义 结构体 aic_panel,seq: init command
返回值 0: 成功, 负数:失败
注意事项 -
16. panel_dsi_dcs_send_seq
接口定义 #define panel_dsi_dcs_send_seq(panel, seq…)
功能说明 发送 mipi 协议标准的 command
参数定义 结构体 aic_panel,seq: init command
返回值 0: 成功, 负数:失败
注意事项 -
17. panel_init
接口定义

static inline void panel_init(struct panel_comp *p, struct device *dev,

struct videomode *vm, struct aic_panel_funcs *funcs)

功能说明 初始化一个 panel
参数定义 结构体 panel_comp , 结构体 device,屏时序参数 videomode, aic_panel_funcs
返回值 void
注意事项 -