日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

TI Am335LCD驱动

發布時間:2024/1/18 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 TI Am335LCD驱动 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

drivers/video/da8xx-fb.c

platformdriver的名稱是

#define DRIVER_NAME "da8xx_lcdc"

?

arch/arm/mach-omap2/devices.c中:

int __init am33xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata) {int id = 0;struct platform_device *pdev;struct omap_hwmod *oh;char *oh_name = "lcdc"; //驅動代碼在arch/arm/mach-omap2/omap_hwmod_33xx_data.cchar *dev_name = "da8xx_lcdc";oh = omap_hwmod_lookup(oh_name);if (!oh) {pr_err("Could not look up LCD%d hwmod\n", id);return -ENODEV;}pdev = omap_device_build(dev_name, id, oh, pdata,sizeof(struct da8xx_lcdc_platform_data), NULL, 0, 0);if (IS_ERR(pdev)) {WARN(1, "Can't build omap_device for %s:%s.\n",dev_name, oh->name);return PTR_ERR(pdev);}return 0; }

這個函數是設置struct da8xx_lcdc_platform_data

board-am335xevm.c:

static const struct display_panel consys_disp_panel = {WVGA,32,32,COLOR_ACTIVE, }; static struct lcd_ctrl_config consys_lcd_cfg = {&consys_disp_panel,.ac_bias = 255,.ac_bias_intrpt = 0,.dma_burst_sz = 16,.bpp = 32, 1個像素用多少位表示,這里其實是24位。在probe的代碼使用了。.fdd = 0x80,.tft_alt_mode = 1,.stn_565_mode = 0,.mono_8bit_mode = 0,.invert_line_clock = 0,.invert_frm_clock = 0,.sync_edge = 1,.sync_ctrl = 1,.raster_order = 0, }; struct da8xx_lcdc_platform_data samsung_AMS369FG06_pdata = {.manu_name = "SamSung",.controller_data = &consys_lcd_cfg,.type = "samsung_AMS369FG06", }; static void lcdc_init(int evm_id, int profile) {struct da8xx_lcdc_platform_data *lcdc_pdata;setup_pin_mux(lcdc_pin_mux);if (conf_disp_pll(300000000)) {pr_info("Failed configure display PLL, not attempting to""register LCDC\n");return;}switch (evm_id) {case GEN_PURP_EVM:case GEN_PURP_DDR3_EVM:/*lcdc_pdata = &TFC_S9700RTWV35TR_01B_pdata;*/lcdc_pdata = &samsung_AMS369FG06_pdata;break;case EVM_SK:lcdc_pdata = &NHD_480272MF_ATXI_pdata;break;default:pr_err("LCDC not supported on this evm (%d)\n",evm_id);return;}lcdc_pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;if (am33xx_register_lcdc(lcdc_pdata)) //設置pr_info("Failed to register LCDC device\n");return; }

回到開頭來看Da8xx-fb.c:

static int __devinit fb_probe(struct platform_device *device) {struct da8xx_lcdc_platform_data *fb_pdata =device->dev.platform_data;struct lcd_ctrl_config *lcd_cfg;struct da8xx_panel *lcdc_info;struct fb_info *da8xx_fb_info;struct clk *fb_clk = NULL;struct da8xx_fb_par *par;resource_size_t len;int ret, i;unsigned long ulcm; 代碼略下面的代碼申請LCD寄存器的虛擬地址,(這個resource是在哪定義的,還沒找到)lcdc_regs = platform_get_resource(device, IORESOURCE_MEM, 0);if (!lcdc_regs) {dev_err(&device->dev,"Can not get memory resource for LCD controller\n");return -ENOENT;}len = resource_size(lcdc_regs);lcdc_regs = request_mem_region(lcdc_regs->start, len, lcdc_regs->name);if (!lcdc_regs)return -EBUSY;da8xx_fb_reg_base = (resource_size_t)ioremap(lcdc_regs->start, len); 代碼略//上面定義了一些預定義的配置,見known_lcd_panelsfor (i = 0, lcdc_info = known_lcd_panels;i < ARRAY_SIZE(known_lcd_panels);i++, lcdc_info++) {if (strcmp(fb_pdata->type, lcdc_info->name) == 0)break;}if (i == ARRAY_SIZE(known_lcd_panels)) {dev_err(&device->dev, "GLCD: No valid panel found\n");ret = -ENODEV;goto err_pm_runtime_disable;} elsedev_info(&device->dev, "GLCD: Found %s panel\n",fb_pdata->type);lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data; //得到board-am335xevm.c中定義的lcd_ctrl_configda8xx_fb_info = framebuffer_alloc(sizeof(struct da8xx_fb_par),&device->dev);if (!da8xx_fb_info) {dev_dbg(&device->dev, "Memory allocation failed for fb_info\n");ret = -ENOMEM;goto err_pm_runtime_disable;}下面初始化par變量。par = da8xx_fb_info->par;par->dev = &device->dev;par->lcdc_clk = fb_clk; #ifdef CONFIG_CPU_FREQpar->lcd_fck_rate = clk_get_rate(fb_clk); #endifpar->pxl_clk = lcdc_info->pxl_clk;if (fb_pdata->panel_power_ctrl) {par->panel_power_ctrl = fb_pdata->panel_power_ctrl;par->panel_power_ctrl(1);}調用lcd_init(),芯片級的初始化操作。if (lcd_init(par, lcd_cfg, lcdc_info) < 0) {dev_err(&device->dev, "lcd_init failed\n");ret = -EFAULT;goto err_release_fb;}/* allocate frame buffer */par->vram_size = lcdc_info->width * lcdc_info->height * lcd_cfg->bpp; //得到總共所需位數ulcm = lcm((lcdc_info->width * lcd_cfg->bpp)/8, PAGE_SIZE); //內存對齊par->vram_size = roundup(par->vram_size/8, ulcm); //1個字節8位,除8得到字節數。par->vram_size = par->vram_size * LCD_NUM_BUFFERS; //需求申請的內存的個數為LCD_NUM_BUFFERS申請DMA內存區域par->vram_virt = dma_alloc_coherent(NULL,par->vram_size,(resource_size_t *) &par->vram_phys,GFP_KERNEL | GFP_DMA);if (!par->vram_virt) {dev_err(&device->dev,"GLCD: kmalloc for frame buffer failed\n");ret = -EINVAL;goto err_release_fb;}da8xx_fb_info->screen_base = (char __iomem *) par->vram_virt;da8xx_fb_fix.smem_start = par->vram_phys;da8xx_fb_fix.smem_len = par->vram_size;da8xx_fb_fix.line_length = (lcdc_info->width * lcd_cfg->bpp) / 8;memcpy(par->vram_virt,kernel_logo,par->vram_size);//add by jiachenghui for kernel logo showpar->dma_start = par->vram_phys;par->dma_end = par->dma_start + lcdc_info->height *da8xx_fb_fix.line_length - 1;/* allocate palette buffer */par->v_palette_base = dma_alloc_coherent(NULL,PALETTE_SIZE,(resource_size_t *)&par->p_palette_base,GFP_KERNEL | GFP_DMA);if (!par->v_palette_base) {dev_err(&device->dev,"GLCD: kmalloc for palette buffer failed\n");ret = -EINVAL;goto err_release_fb_mem;}memset(par->v_palette_base, 0, PALETTE_SIZE);par->irq = platform_get_irq(device, 0);if (par->irq < 0) {ret = -ENOENT;goto err_release_pl_mem;} 代碼略(設置結構da8xx_fb_info)dev_set_drvdata(&device->dev, da8xx_fb_info); //platform_driver其它函數可以得到它,見resume和suspend函數。/* initialize the vsync wait queue */init_waitqueue_head(&par->vsync_wait);par->vsync_timeout = HZ / 5;par->which_dma_channel_done = -1;spin_lock_init(&par->lock_for_chan_update);/* Register the Frame Buffer */if (register_framebuffer(da8xx_fb_info) < 0) { //見(2)dev_err(&device->dev,"GLCD: Frame Buffer Registration Failed!\n");ret = -EINVAL;goto err_dealloc_cmap;}
  • known_lcd_panels的定義說明:

  • static struct da8xx_panel known_lcd_panels[] = {/* Sharp LCD035Q3DG01 */[0] = {.name = "Sharp_LCD035Q3DG01",.width = 320,.height = 240,.hfp = 8,.hbp = 6,.hsw = 0,.vfp = 2,.vbp = 2,.vsw = 0,.pxl_clk = 4608000,.invert_pxl_clk = 1,}, 代碼略[10] = {/* samsung AMS369FG06-0 */.name = "samsung_AMS369FG06",.width = 480,.height = 800,.hfp = 8,.hbp = 7,.hsw = 1,.vfp = 8,.vbp = 7,.vsw = 1,.pxl_clk = 19200000,.invert_pxl_clk = 0,}, };

    struct da8xx_panel定義如下:

    struct da8xx_panel {const char name[25]; /* Full name <vendor>_<model> */unsigned short width;unsigned short height;int hfp; /* Horizontal front porch */int hbp; /* Horizontal back porch */int hsw; /* Horizontal Sync Pulse Width */int vfp; /* Vertical front porch */int vbp; /* Vertical back porch */int vsw; /* Vertical Sync Pulse Width */unsigned int pxl_clk; /* Pixel clock */unsigned char invert_pxl_clk; /* Invert Pixel clock */ };

    2. register_framebuffer()

    int register_framebuffer(struct fb_info *fb_info)

    它注冊結構fb_info到framebuff系統,fb_info中有一個重要的成員是fb_ops結構。例如:

    static struct fb_ops da8xx_fb_ops = {.owner = THIS_MODULE,.fb_check_var = fb_check_var,.fb_setcolreg = fb_setcolreg,.fb_pan_display = da8xx_pan_display,.fb_ioctl = fb_ioctl,.fb_fillrect = cfb_fillrect,.fb_copyarea = cfb_copyarea,.fb_imageblit = cfb_imageblit,.fb_blank = cfb_blank, };

    fb_ops的函數中都有一個參數fb_info。

    ?

    總結

    以上是生活随笔為你收集整理的TI Am335LCD驱动的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。