arch/arm/plat-s5p4418/drone2/include/Cfg_main.h

有关显示的定义:

/*------------------------------------------------------------------------------* Display (DPC and MLC)*//* Primary */#define CFG_DISP_PRI_SCREEN_LAYER 0#define CFG_DISP_PRI_SCREEN_RGB_FORMAT MLC_RGBFMT_A8R8G8B8#define CFG_DISP_PRI_SCREEN_PIXEL_BYTE 4#define CFG_DISP_PRI_SCREEN_COLOR_KEY 0x090909#define CFG_DISP_PRI_VIDEO_PRIORITY 2 // 0, 1, 2, 3#define CFG_DISP_PRI_BACK_GROUND_COLOR 0x000000#define CFG_DISP_PRI_MLC_INTERLACE CFALSE#define CFG_DISP_PRI_LCD_WIDTH_MM 154#define CFG_DISP_PRI_LCD_HEIGHT_MM 85#define CFG_DISP_PRI_RESOL_WIDTH 480 // X Resolution#define CFG_DISP_PRI_RESOL_HEIGHT 800 // Y Resolution红色的部分即对应驱动代码中的struct disp_vsync_info结构。这此数据在dev-display.c中设置。#define CFG_DISP_PRI_HSYNC_SYNC_WIDTH 1#define CFG_DISP_PRI_HSYNC_BACK_PORCH 7#define CFG_DISP_PRI_HSYNC_FRONT_PORCH 8#define CFG_DISP_PRI_HSYNC_ACTIVE_HIGH CTRUE#define CFG_DISP_PRI_VSYNC_SYNC_WIDTH 1#define CFG_DISP_PRI_VSYNC_BACK_PORCH 7#define CFG_DISP_PRI_VSYNC_FRONT_PORCH 8#define CFG_DISP_PRI_VSYNC_ACTIVE_HIGH CTRUE#define CFG_DISP_PRI_CLKGEN0_SOURCE DPC_VCLK_SRC_PLL2#define CFG_DISP_PRI_CLKGEN0_DIV 40// even divide#define CFG_DISP_PRI_CLKGEN0_DELAY 0#define CFG_DISP_PRI_CLKGEN0_INVERT 0#define CFG_DISP_PRI_CLKGEN1_SOURCE DPC_VCLK_SRC_VCLK2#define CFG_DISP_PRI_CLKGEN1_DIV 2#define CFG_DISP_PRI_CLKGEN1_DELAY 0#define CFG_DISP_PRI_CLKGEN1_INVERT 0#define CFG_DISP_PRI_CLKSEL1_SELECT 0#define CFG_DISP_PRI_PADCLKSEL DPC_PADCLKSEL_VCLK /* VCLK=CLKGEN1, VCLK12=CLKGEN0 */#define CFG_DISP_PRI_PIXEL_CLOCK 800000000/CFG_DISP_PRI_CLKGEN0_DIV#define CFG_DISP_PRI_OUT_SWAPRB CFALSE#define CFG_DISP_PRI_OUT_FORMAT DPC_FORMAT_RGB888#define CFG_DISP_PRI_OUT_YCORDER DPC_YCORDER_CbYCrY#define CFG_DISP_PRI_OUT_INTERLACE CFALSE#define CFG_DISP_PRI_OUT_INVERT_FIELD CFALSE#define CFG_DISP_LCD_MPY_TYPE 0

这个表和LCD时序图有关:

VCLK表示LCD时钟频率。

HSYNC表示行同步,每个时钟周期表示扫描1行。

VSYNC表示帧同步,每个时钟周期表示扫描完1帧。

LINEVAL表示LCD垂直宽度。

HOZVAL表示LCD水平宽度。

LCD帧扫描流程:当VSYNC(脉冲宽度为VSPW+1)上升沿到来后经历VBPD+1个时钟周期后开始行扫描,VDEN表示行有效,经历LINEVAL+1个行信号后行扫描结束,再经历VFPD+1时钟后进行下一个帧信号。

行扫描流程:当HSYNC(脉冲宽度为HSPW+1)上升沿后HBPD+1周期后开始扫描每个点,经历HOZVAL+1个点后行扫描结束,再经历HFPD+1个周期后开始下一行。

arch/arm/plat-s5p4418/dron2/device.c

/*------------------------------------------------------------------------------* DISPLAY (LVDS) / FB*/#if defined (CONFIG_FB_NXP)#if defined (CONFIG_FB0_NXP)static struct nxp_fb_plat_data fb0_plat_data = {.module = CONFIG_FB0_NXP_DISPOUT,.layer = CFG_DISP_PRI_SCREEN_LAYER,.format = CFG_DISP_PRI_SCREEN_RGB_FORMAT,.bgcolor = CFG_DISP_PRI_BACK_GROUND_COLOR,.bitperpixel = CFG_DISP_PRI_SCREEN_PIXEL_BYTE * 8,.x_resol = CFG_DISP_PRI_RESOL_WIDTH,.y_resol = CFG_DISP_PRI_RESOL_HEIGHT,#ifdef CONFIG_ANDROID.buffers = 3,.skip_pan_vsync = 1,#else.buffers = 2,#endif.lcd_with_mm = CFG_DISP_PRI_LCD_WIDTH_MM, /* 152.4 */.lcd_height_mm = CFG_DISP_PRI_LCD_HEIGHT_MM, /* 91.44 */};static struct platform_device fb0_device = {.name = DEV_NAME_FB, //“nxp-fb”.id = 0, /* FB device node num */.dev = {.coherent_dma_mask = 0xffffffffUL, /* for DMA allocate */.platform_data = &fb0_plat_data},};#endifstatic struct platform_device *fb_devices[] = {#if defined (CONFIG_FB0_NXP)&fb0_device,#endif};#endif /* CONFIG_FB_NXP */

arch/arm/plat-s5p4418/dron2/dev-display.c

这个文件是为display_lcd.c(见下面,这是platform_driver)服务的,这里定义platform_data。

/*------------------------------------------------------------------------------* LCD platform device*/#if defined (CONFIG_NXP_DISPLAY_LCD)static struct disp_vsync_info __lcd_vsync = {/* default parameters refer to cfg_main.h */#if defined(CFG_DISP_PRI_RESOL_WIDTH) && defined(CFG_DISP_PRI_RESOL_HEIGHT).h_active_len = CFG_DISP_PRI_RESOL_WIDTH,.h_sync_width = CFG_DISP_PRI_HSYNC_SYNC_WIDTH,.h_back_porch = CFG_DISP_PRI_HSYNC_BACK_PORCH,.h_front_porch = CFG_DISP_PRI_HSYNC_FRONT_PORCH,.h_sync_invert = CFG_DISP_PRI_HSYNC_ACTIVE_HIGH,.v_active_len = CFG_DISP_PRI_RESOL_HEIGHT,.v_sync_width = CFG_DISP_PRI_VSYNC_SYNC_WIDTH,.v_back_porch = CFG_DISP_PRI_VSYNC_BACK_PORCH,.v_front_porch = CFG_DISP_PRI_VSYNC_FRONT_PORCH,.v_sync_invert = CFG_DISP_PRI_VSYNC_ACTIVE_HIGH,.pixel_clock_hz = CFG_DISP_PRI_PIXEL_CLOCK,.clk_src_lv0 = CFG_DISP_PRI_CLKGEN0_SOURCE,.clk_div_lv0 = CFG_DISP_PRI_CLKGEN0_DIV,.clk_src_lv1 = CFG_DISP_PRI_CLKGEN1_SOURCE,.clk_div_lv1 = CFG_DISP_PRI_CLKGEN1_DIV,#endif};static struct disp_lcd_param __lcd_devpar; //注意,没有做初始化,但在下面的函数__disp_lcd_dev_data赋了值。static struct nxp_lcd_plat_data lcd_data = {.display_in = DISPLAY_INPUT(CONFIG_NXP_DISPLAY_LCD_IN),.display_dev = DISP_DEVICE_LCD,.vsync = &__lcd_vsync,.dev_param = (union disp_dev_param*)&__lcd_devpar,};//此结构没有被使用。static struct platform_device lcd_device = {.name = DEV_NAME_LCD, // "nxp-lcd" //arch/arm/plat-s5p4418/soc/display_lcd.c是此名称的platform_driver驱动.id = -1,.dev = {.platform_data = &lcd_data},};//此函数的作用是将dev_par, sgpar的参数都复制到本地lcd_data实体,并将lcd_data.vsync复制到输出参数*vsync。lcd_data实体是arch/arm/mach-s5p4418/display_lcd.c中的platform_driver中的platform_datastatic void __disp_lcd_dev_data(struct disp_vsync_info *vsync,void *dev_par, struct disp_syncgen_par *sgpar){struct nxp_lcd_plat_data *plcd = &lcd_data; //lcd_data是本地数据。struct disp_lcd_param *dst = (struct disp_lcd_param *)plcd->dev_param;struct disp_lcd_param *src = dev_par;if (src) {SET_PARAM(src, dst, lcd_format);SET_PARAM(src, dst, lcd_mpu_type);SET_PARAM(src, dst, invert_field);SET_PARAM(src, dst, swap_RB);SET_PARAM(src, dst, yc_order);SET_PARAM(src, dst, lcd_init);SET_PARAM(src, dst, lcd_exit);}if (sgpar)plcd->sync_gen = sgpar;SET_VSYNC_INFO(vsync, plcd->vsync);}#else#define __disp_lcd_dev_data(s, p, g)#endif /* LCD */

arch/arm/mach-s5p4418/soc/display_lcd.c

它是一个platform_driver,注册的platform_driver是

#define DEV_NAME_LCD "nxp-lcd"

它为display.c(见下面)服务,注册disp_process_ops结构。

static struct disp_process_ops lcd_ops = {.set_vsync = lcd_set_vsync,.get_vsync = lcd_get_vsync,.enable = lcd_enable,.stat_enable= lcd_stat_enable,.suspend = lcd_suspend,.resume = lcd_resume,};static int lcd_probe(struct platform_device *pdev){struct nxp_lcd_plat_data *plat = pdev->dev.platform_data;struct disp_lcd_param *plcd;struct disp_vsync_info *psync;struct disp_syncgen_par *sgpar;int device = DISP_DEVICE_LCD;int input;RET_ASSERT_VAL(plat, -EINVAL);RET_ASSERT_VAL(plat->display_in == DISP_DEVICE_SYNCGEN0 ||plat->display_in == DISP_DEVICE_SYNCGEN1 ||plat->display_dev == DISP_DEVICE_LCD ||plat->display_in == DISP_DEVICE_RESCONV, -EINVAL);RET_ASSERT_VAL(plat->vsync, -EINVAL);plcd = kzalloc(sizeof(*plcd), GFP_KERNEL);RET_ASSERT_VAL(plcd, -EINVAL);if (plat->dev_param)memcpy(plcd, plat->dev_param, sizeof(*plcd));sgpar = plat->sync_gen;psync = plat->vsync;input = plat->display_in;//在dev-display.c中设置lcd_data->display_in= DISP_DEVICE_SYNCGEN0nxp_soc_disp_register_proc_ops(device, &lcd_ops); //此注册函数在同目录下的display.c中nxp_soc_disp_device_connect_to(device, input, psync);nxp_soc_disp_device_set_dev_param(device, plcd);if (sgpar &&(input == DISP_DEVICE_SYNCGEN0 ||input == DISP_DEVICE_SYNCGEN1))nxp_soc_disp_device_set_sync_param(input, sgpar);printk("LCD : [%d]=%s connect to [%d]=%s\n",device, dev_to_str(device), input, dev_to_str(input));return 0;}

第一句:struct nxp_lcd_plat_data *plat = pdev->dev.platform_data;

对应dev-display.c中:

static struct platform_device lcd_device = { 但代码中没有找到驱动注册此结构的代码,为何??.name = DEV_NAME_LCD,.id = -1,.dev = {.platform_data = &lcd_data},};

arch/arm/mach-s5p4418/soc/display.c

此文件内部有一组显示结构,它将所有显示有关的设备(包括LCD)定义了一个内部数据结构数组:

static struct disp_process_dev device_dev[] = {[0] = { .dev_id = DISP_DEVICE_RESCONV , .name = "RESCONV" , .list = LIST_INIT(0), .lock = LOCK_INIT(0)},[1] = { .dev_id = DISP_DEVICE_LCD , .name = "LCD" , .list = LIST_INIT(1), .lock = LOCK_INIT(1)},[2] = { .dev_id = DISP_DEVICE_HDMI , .name = "HDMI" , .list = LIST_INIT(2), .lock = LOCK_INIT(2)},[3] = { .dev_id = DISP_DEVICE_MIPI , .name = "MiPi" , .list = LIST_INIT(3), .lock = LOCK_INIT(3)},[4] = { .dev_id = DISP_DEVICE_LVDS , .name = "LVDS" , .list = LIST_INIT(4), .lock = LOCK_INIT(4)},[5] = { .dev_id = DISP_DEVICE_SYNCGEN0, .name = "SYNCGEN0", .list = LIST_INIT(5), .lock = LOCK_INIT(5)},[6] = { .dev_id = DISP_DEVICE_SYNCGEN1, .name = "SYNCGEN1", .list = LIST_INIT(6), .lock = LOCK_INIT(6)},};#define DEVICE_SIZE ARRAY_SIZE(device_dev)static struct kobject *kobj_syncgen = NULL;static inline void *get_display_ptr(enum disp_dev_type device) //根据参数得到指定的结构指针{return (&device_dev[device]);}const char * dev_to_str(enum disp_dev_type device) //打印出名称{struct disp_process_dev *pdev = get_display_ptr(device);return pdev->name;}

每一个显示设备都是disp_process_dev结构:

/* display device instance (syncgen, lvds, lcd,..) */struct disp_process_dev {const char *name;int dev_id;int dev_in;int dev_out;unsigned int save_addr;unsigned int base_addr;struct list_head list;unsigned int status;spinlock_t lock;struct disp_vsync_info vsync;struct disp_syncgen_par sync_gen;struct disp_process_ops *disp_ops; //即是上面display_lcd.c中定义的disp_process_opsvoid * dev_param;void * dev_info;void * priv;};

分析display_lcd.c中使用的第一个函数nxp_soc_disp_register_proc_ops:

此函数将ops赋给内部数据device_dev[1]->disp_ops。void nxp_soc_disp_register_proc_ops(enum disp_dev_type device, struct disp_process_ops *ops){struct disp_process_dev *pdev = get_display_ptr(device);RET_ASSERT(DEVICE_SIZE > device);RET_ASSERT(device == pdev->dev_id);if (get_display_ops(device))printk(KERN_ERR "Warn , %s operation will be replaced \n", dev_to_str(device));spin_lock(&pdev->lock);/* set device info */set_display_ops (device, ops);spin_unlock(&pdev->lock);printk(KERN_INFO "Display %s register operation \n", dev_to_str(device));}

nxp-fb.c

这个文件就是与frambuffer驱动fbmem.c对接的代码。在probe时调用了register_framebuffer(info);info的数据结构定义如下:

struct fb_info {atomic_t count;int node;int flags;struct mutex lock; /* open/release/ioctl函数使用的锁 */struct mutex mm_lock; /* Lock for fb_mmap and smem_* fields */struct fb_var_screeninfo var; /* 可变参数*/struct fb_fix_screeninfo fix; /* 固定参数 */struct fb_monspecs monspecs; /* 显示器标准 */struct work_struct queue; /* Framebuffer event queue 事件队列*/struct fb_pixmap pixmap; /* Image hardware mapper图像硬件mapper */struct fb_pixmap sprite; /* Cursor hardware mapper光标硬件mapper */struct fb_cmap cmap; /* Current cmap目前颜色表 */struct list_head modelist; /* mode list */struct fb_videomode *mode; /* current mode */#ifdef CONFIG_FB_BACKLIGHT/* assigned backlight device *//* set before framebuffer registration,remove after unregister */struct backlight_device *bl_dev;/* Backlight level curve */struct mutex bl_curve_mutex;u8 bl_curve[FB_BACKLIGHT_LEVELS];#endif#ifdef CONFIG_FB_DEFERRED_IOstruct delayed_work deferred_work;struct fb_deferred_io *fbdefio;#endifstruct fb_ops *fbops;//帧缓冲操作函数fb_opsstruct device *device; /* This is the parent */struct device *dev; /* This is this fb device */int class_flag; /* private sysfs flags */#ifdef CONFIG_FB_TILEBLITTINGstruct fb_tile_ops *tileops; /* Tile Blitting */#endifchar __iomem *screen_base; /* Virtual address 虚拟基地址,大小即长*宽*每像素占字句字节数*buff个数。*/unsigned long screen_size; /* Amount of ioremapped VRAM or 0 */ io remapped虚拟内存大小。void *pseudo_palette; /* Fake palette of 16 colors */#define FBINFO_STATE_RUNNING 0#define FBINFO_STATE_SUSPENDED 1u32 state; /* Hardware state i.e suspend 硬件状态,如挂起*/void *fbcon_par; /* fbcon use-only private area *//* From here on everything is device dependent */void *par;/* we need the PCI or similar aperture base/size notsmem_start/size as smem_start may just be an objectallocated inside the aperture so may not actually overlap */struct apertures_struct {unsigned int count;struct aperture {resource_size_t base;resource_size_t size;} ranges[0];} *apertures;};

nxp_fb_probe的函数做的工作主要是初始化struct fb_info,并调用register_framebuffer(info);

static int nxp_fb_probe(struct platform_device *pdev){struct nxp_fb_plat_data *plat = pdev->dev.platform_data; // arch/arm/plat-s5p4418/dron2/device.c中定义了”nxp-fb”设备的platform_data,见上面的代码分析。struct fb_info *info = NULL;#ifdef CONFIG_FB_NXP_ION_MEMstruct nxp_fb_device *fbdev;struct nxp_fb_param *fbpar;#endifint i = 0, ret = 0;pr_debug("\n%s (name=%s, id=%d)\n", __func__, dev_name(&pdev->dev), pdev->id);/* allocate fb_info and init */info = nxp_fb_init_fb(pdev->id, &pdev->dev);if(! info) {ret = -ENOMEM;goto err_fb;}ret = nxp_fb_setup_param(pdev->id, info, plat);if (0 > ret)goto err_map;nxp_fb_setup_info(info);#ifdef CONFIG_FB_NXP_ION_MEMfbpar = info->par;fbdev = &fbpar->fb_dev;fbdev->dev = &pdev->dev;ret = nxp_fb_setup_ion(&fbpar->fb_dev.dma_buf_data);if (ret) {printk(KERN_ERR "Fail to setup ion\n");goto err_map;}#endif/* allocate frame buffer memory from here */ret = nxp_fb_alloc_mem(info);if(ret) {printk(KERN_ERR "Fail, unable to allcate frame buffer (%d)\n", pdev->id);goto err_map;}nxp_fb_init_display(info);/** device_create '/proc/fb0' & fb class* register machine file operation to frame buffer file operation* registered_fb[]* (drivers/video/fbmem.c)*/if (pdev->id != 0) {for (i = 0; pdev->id > i; i++) {if (!registered_fb[i]) {printk("FB: Reserve dev/node [%d]\n", i);registered_fb[i] = info;}}}ret = register_framebuffer(info);if(ret < 0) {printk(KERN_ERR "Fail, unable to register frame buffer(%d)\n", pdev->id);goto err_reg;}/* register to driver data, use platform_get_drvdata */platform_set_drvdata(pdev, info);return ret;err_reg:unregister_framebuffer(info);err_map:nxp_fb_free_mem(info);err_fb:nxp_fb_exit_fb(info);return ret;}

s5p4418显示驱动相关推荐

  1. android系统平台显示驱动开发简要:Samsung LCD接口篇『三』

    平台信息: 内核:linux3.4.39 系统:android4.4  平台:S5P4418(cortex a9) 作者:瘋耔(欢迎转载,请注明作者) 欢迎指正错误,共同学习.共同进步!! 关注博主新 ...

  2. WINCE6.0显示驱动模型介绍

    ********************************LoongEmbedded*****************作者:LoongEmbedded(kandi)时间:2011.06.4 类别 ...

  3. LED计数电路,5输入按键编码器,7段数码管显示驱动集成为LED计数测试电路

    LED计数电路: 5输入按键编码器: 7段数码管显示驱动真值表: 集成:

  4. nano-pc-t1 4412 显示驱动分析

    1. 和其它内核代码类似. 显示驱动的分析都是由 drivers/video/fbmem.c开始,fbmem.c是显示驱动的抽象,实际只是一个框架性的东西. fbmem_init 中实现了一个字符设备 ...

  5. 2440 6.0BSP 移植过程之显示驱动篇

    2440 6.0BSP 移植过程之显示驱动篇 //--------------------------------------------------------------------------- ...

  6. 键盘扫描并控制数码管C语言,CH454 数码管显示驱动和键盘扫描控制芯片

    1.概述 CH454 是数码管显示驱动和键盘扫描控制芯片.CH454内置时钟振荡电路,可以动态驱动8 只16段的数码管或者128 只LED,支持11 段.14 段.16 段×8 以及17 段×7 等; ...

  7. LED显示驱动(六):LED显示设备显示单层图片调试(DE驱动测试)

    一.显示驱动基础 1.深入学习display2模块的函数和数据结构. 2.制作图层挂在盒子做多个图层的显示,以及图层做alpha blending.colorkey等效果. 问题:1.bin文件生成. ...

  8. LED显示驱动(五):视频设备显示驱动调试步骤总结

    一.显示驱动修改基本步骤 1)查看当前display设备显示状态命令:cat sys/class/disp/disp/attr/sys (显示驱动路径) 2)编译打包内核:./build.sh  ./ ...

  9. LDE显示驱动(四):显示驱动内核底层代码分析

    作者:DayInAI 日期:20190124 一.RTMX 1)int de_rtmx_set_route(unsigned int sel, unsigned char pno, unsigned ...

  10. LED显示驱动(三):显示驱动底层学习小结

    一.DE硬件架构 显示系统可划分为三个层面,驱动层,框架层及底层. 底层与图形硬件相接,将上层配置的功能参数转换成硬件需要的参数,配置相应寄存器. 显示框架层对底层进行抽象封装成功能模块. 驱动层对外 ...

最新文章

  1. JAVA中console方法怎么用_Java中Console对象实例代码
  2. 二阶差分预测后数据还原公式_携程如何基于ARIMA时序分析做业务量的预测
  3. java知识百科全书--强烈推荐
  4. Http上传Xml文件
  5. php对表格的处理,JavaScript_js处理表格对table进行修饰,js处理表格 1、行颜色间隔显示 - phpStudy...
  6. TypeScript中怎么用接口(interface)描述类(静态部分与实例部分)
  7. [react] childContextTypes是什么?它有什么用?
  8. eclipse maven项目 class类部署不到tomcat下_Springboot介绍以及用Eclipse搭建一个简单的Springboot项目教程
  9. CentOS+Apache+Mysql+Php安装及优化配置小记
  10. POJ1144 Network 连通性
  11. MATLAB获取字符串中两个特定字符之间的内容
  12. python基础语法-缩进规则:
  13. 机械制造技术基础【3】
  14. JavaScript练习题
  15. ASO优化方法有哪些_五大ASO优化方法
  16. 矩阵求导术(二)——矩阵对矩阵的求导
  17. Jetson nano使用anaconda 2021-5-15
  18. 教培企业女神节线上营销方案怎么做好?
  19. CPU GPU 扫盲帖
  20. 梦幻新开服务器维护,梦幻西游12月新开服务器

热门文章

  1. 深度篇——实例分割(三) 细说 mask rcnn 实例分割代码 训练自己数据 之 相关网络,数据处理,工具等
  2. 2022苹果ios个人开发中注册遇到的问题
  3. 基于IMDb数据集的情感分析(TF-IDF与机器学习实现)
  4. 17-内部类的基本概念
  5. 【练习】新浪邮箱注册测试用例
  6. torch.Longtensor是什么?和torch.Tensor有什么区别?
  7. 乱谈SOA——IT世界观及方法论
  8. Vue项目中实现改变屏幕尺寸重新刷新页面-计算页面尺寸
  9. NOI2016 滚粗记
  10. info.plist 隐私权限 国际化