首页 > 代码库 > [Freescale] LCD 噪点修正
[Freescale] LCD 噪点修正
Board:DSA2LV
Platform:Android 4.2.2 / Linux 3.0.35
LCD:Sansumg PI_LTM230HL06 & ChiMei V500HK1-LS
问题
在Suspend/Resume 和 开机后,屏幕上几率性出现条状噪点,几率约1/20。
在论坛上寻找一通发现类似问题,并找到Patch,在最后贴上。
看一下作者的注释:
In order to avoid any random pixelation issue, we should follow a correct
display controller/LDB initialization sequence, that is, LDB channel should
be enabled after its relevant display controller is enabled. Since the
enable() callback of the mxc display driver is called after a display
controller is enabled, this patch uses the enable()/disable() callbacks
to replace the fb notifier callback implemented in the LDB driver. Also,
we disable a LDB channel in the setup() callback of the mxc display driver
to make sure of the correct sequence in any fb set_par() function. As the
enable()/disable() callbacks are always invoked with fb_blank(), this
patch drops the suspend()/resume() functions of the LDB driver which
do nothing but enable/disable LDB channels. We also remove the code to
enable ldb di clocks because they can be enabled when their relevant
child pixel clocks are enabled.
简单来说,也就是只有当相关显示控制器设定完毕后,LDB(LVDS Display Bridge)channel 才应当被打开。
这边还提到setup()、enable()、disable()等方法,所以先简单理一下LDB、IPU(Image Process Unit)的调用关系。
LDB 和 IPU
首先要知道FrameBuffer是经过IPU的一些列处理,然后才丢给LDB的(当然除了LVDS控制器,可能还有VGA、HDMI等其它的控制器),LDB再通过LVDS接口将数据丢到LCD上面,所以IPU在LDB前面。
然后看LDB里面的一些Callback Function:
ldb.c
static struct mxc_dispdrv_driver ldb_drv = { .name = DISPDRV_LDB, .init = ldb_disp_init, .deinit = ldb_disp_deinit, .setup = ldb_disp_setup, .enable = ldb_disp_enable, .disable = ldb_disp_disable,};static int ldb_probe(struct platform_device *pdev){ ldb->disp_ldb = mxc_dispdrv_register(&ldb_drv);}
LDB提供了像init、setup、enable等一些方法,目的就是当IPU该初始化、该设定的寄存器都设定完成后,可以调用LDB的init、setup、enable方法。如何让IPU顺利地调用LDB的Callback function呢,通过mxc_dispdrv_register方法注册进去。
mxc_dispdrv.c
struct mxc_dispdrv_handle *mxc_dispdrv_register(struct mxc_dispdrv_driver *drv){ struct mxc_dispdrv_entry *new; mutex_lock(&dispdrv_lock); new = kzalloc(sizeof(struct mxc_dispdrv_entry), GFP_KERNEL); if (!new) { mutex_unlock(&dispdrv_lock); return ERR_PTR(-ENOMEM); } new->drv = drv; list_add_tail(&new->list, &dispdrv_list); mutex_unlock(&dispdrv_lock); return (struct mxc_dispdrv_handle *)new;}
直接看最关键的一句,将我们注册进来的结构体丢到了dispdrv_list里面,前面说到,framebuffer除了给LVDS控制器之外,可能还有VGA、HDMI等控制器,所以这边需要一个list来保存Callback Function。
既然有存,那必定有取:
struct mxc_dispdrv_handle *mxc_dispdrv_gethandle(char *name, struct mxc_dispdrv_setting *setting){ int ret, found = 0; struct mxc_dispdrv_entry *entry; mutex_lock(&dispdrv_lock); list_for_each_entry(entry, &dispdrv_list, list) { if (!strcmp(entry->drv->name, name) && (entry->drv->init)) {
// 注意这边会调用 init 函数 ret = entry->drv->init((struct mxc_dispdrv_handle *) entry, setting); if (ret >= 0) { entry->active = true; found = 1; break; } } } mutex_unlock(&dispdrv_lock); return found ? (struct mxc_dispdrv_handle *)entry:ERR_PTR(-ENODEV);}
同样从dispdrv_list中,根据name来进行匹配查找。那这个方法会被谁调用?必定是IPU相关的模块:
mxc_ipuv3_fb.c
static int mxcfb_dispdrv_init(struct platform_device *pdev, struct fb_info *fbi){ mxcfbi->dispdrv = mxc_dispdrv_gethandle(disp_dev, &setting);}
驱动部分都看到了,那一定还有设备的添加,不论是LDB还是IPU:
board-mx6q_dsa2lv.c
static struct ipuv3_fb_platform_data sabresd_fb_data[] = { { /*fb0*/ .disp_dev = "ldb", .interface_pix_fmt = IPU_PIX_FMT_RGB24, .mode_str = "LDB-1080P60", .default_bpp = 32, .int_clk = false, .late_init = false, }, { .disp_dev = "hdmi", .interface_pix_fmt = IPU_PIX_FMT_RGB24, .mode_str = "1920x1080M@60", .default_bpp = 32, .int_clk = false, .late_init = false, },}; imx6q_add_ipuv3(0, &ipu_data[0]); if (cpu_is_mx6q()) { imx6q_add_ipuv3(1, &ipu_data[1]); for (i = 0; i < 4 && i < ARRAY_SIZE(sabresd_fb_data); i++) imx6q_add_ipuv3fb(i, &sabresd_fb_data[i]); } else for (i = 0; i < 2 && i < ARRAY_SIZE(sabresd_fb_data); i++) imx6q_add_ipuv3fb(i, &sabresd_fb_data[i]); if( gpio_get_value(DSA2LV_LVDS_HDMI_SEL) ){ //0:HDMI, 1:LVDS imx6q_add_ldb(&ldb_data); }
可以看到,除了添加 LDB 的 IPU fb,还添加了 HDMI 的 IPU fb。
接下来看一下 IPU 中如何调用 LDB 的 Callback Function:
mxc_ipuv3_fb.c:
/* * Set framebuffer parameters and change the operating mode. * * @param info framebuffer information pointer */static int mxcfb_set_par(struct fb_info *fbi){ // setp1,清除IPU中断,disable IPU channel,uninit channel ...... // step2,设置framebuffer参数 ...... // step3,调用dispdrv的setup函数 if (mxc_fbi->dispdrv && mxc_fbi->dispdrv->drv->setup) { retval = mxc_fbi->dispdrv->drv->setup(mxc_fbi->dispdrv, fbi); } // step4,初始化IPU channel,sync panel ...... // step5,enable IPU channel ...... // step6,调用dispdrv的enable函数 if (mxc_fbi->dispdrv && mxc_fbi->dispdrv->drv->enable) { retval = mxc_fbi->dispdrv->drv->enable(mxc_fbi->dispdrv, fbi); }}
LDB的init、setup、enable函数不作代码分析了,基本上也就是初始化LDB控制器的寄存器,最后enable LDB channel。
再简单介绍一下LDB:
LDB和IPU的连接示意图见http://www.cnblogs.com/all-for-fiona/p/3988977.html
从IPU连接到LDB时,有两个通道的数据会传递给LDB控制器,然后LDB控制器根据寄存器的值对数据进行一系列处理后,将两个通道的数据分别给到LDB channel 0 和 LDB channel 1,最后,LDB channel 再通过LVDS接口将图形传递给LCD。
LDB控制器可以设定以下参数:
- channel 0 和 channel 1 分别使用SPWG 还是 JEIDA 标准,这两种标准的区别在于RGB数据的mapping 方式不同:
- 使用18bit或者24bit的数据
- 控制channel 0 和 channel 1 enable/disable
- 设置vsync高电平有效或者低电平有效
Patch后的问题
打完patch后可以解决几率性噪点的问题,但是会出现sansumg lcd开机进入android logo前闪一下白屏的问题。
分析代码后,应该是在setup函数中关闭channel导致:
/* clear channel mode */ reg &= ~ldb->setting[setting_idx].ch_mask;
目前解法是在关闭channel之前,先关闭LCD背光,在寄存器等设置完后在调用enable再打开:
ldb.c -> ldb_disp_setup
if(fb_ioinit_low){ if(power_off_ms < 0) power_off_ms = 200; fb_ioinit_low(power_off_ms); } reg = readl(ldb->control_reg); reg &= ~ldb->setting[setting_idx].ch_mask;
board-mx6q_dsa2lv.c
static int fb_ioinit_high(int power_on_ms){ gpio_set_value( DSA2LV_LVDS_POWER_EN , 1 ); mdelay(power_on_ms); gpio_set_value( DSA2LV_BACKLIGHT_EN , 1 ); return 0;}static int fb_ioinit_low(int power_off_ms){ gpio_set_value( DSA2LV_BACKLIGHT_EN , 0 ); mdelay(power_off_ms); gpio_set_value( DSA2LV_LVDS_POWER_EN , 0 ); return 0;}
Patch Code
From f53fd88eea3667e19b10b254e6d9f80b2a918da5 Mon Sep 17 00:00:00 2001From: Liu Ying <Ying.Liu@freescale.com>Date: Mon, 24 Mar 2014 10:39:01 +0800Subject: [PATCH 1/1] ENGR00304402 video: mxc LDB: Enable LDB channel after display controllerIn order to avoid any random pixelation issue, we should follow a correctdisplay controller/LDB initialization sequence, that is, LDB channel shouldbe enabled after its relevant display controller is enabled. Since theenable() callback of the mxc display driver is called after a displaycontroller is enabled, this patch uses the enable()/disable() callbacksto replace the fb notifier callback implemented in the LDB driver. Also,we disable a LDB channel in the setup() callback of the mxc display driverto make sure of the correct sequence in any fb set_par() function. As theenable()/disable() callbacks are always invoked with fb_blank(), thispatch drops the suspend()/resume() functions of the LDB driver whichdo nothing but enable/disable LDB channels. We also remove the code toenable ldb di clocks because they can be enabled when their relevantchild pixel clocks are enabled.Conflicts: drivers/video/mxc/ldb.c drivers/video/mxc/mxc_dispdrv.hSigned-off-by: Liu Ying <Ying.Liu@freescale.com>(cherry picked from commit 8d189a9cc067f74cc3d49757af25118b459b9726)--- drivers/video/mxc/ldb.c | 140 +++++++++----------------------------- drivers/video/mxc/mipi_dsi.c | 15 +++- drivers/video/mxc/mxc_dispdrv.h | 6 +- drivers/video/mxc/mxc_ipuv3_fb.c | 6 +- drivers/video/mxc_hdmi.c | 8 ++- 5 files changed, 54 insertions(+), 121 deletions(-)diff --git a/drivers/video/mxc/ldb.c b/drivers/video/mxc/ldb.cindex 278475c..3b83019 100644--- a/drivers/video/mxc/ldb.c+++ b/drivers/video/mxc/ldb.c@@ -1,5 +1,5 @@ /*- * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.+ * Copyright (C) 2012-2014 Freescale Semiconductor, Inc. All Rights Reserved. */ /*@@ -84,7 +84,6 @@ struct ldb_data { uint32_t *reg; uint32_t *control_reg; uint32_t *gpr3_reg;- uint32_t control_reg_data; struct regulator *lvds_bg_reg; int mode; bool inited;@@ -92,13 +91,11 @@ struct ldb_data { struct clk *di_clk; struct clk *ldb_di_clk; bool active;- bool clk_en; int ipu; int di; uint32_t ch_mask; uint32_t ch_val; } setting[2];- struct notifier_block nb; }; static int g_ldb_mode;@@ -226,7 +223,7 @@ static int find_ldb_setting(struct ldb_data *ldb, struct fb_info *fbi) static int ldb_disp_setup(struct mxc_dispdrv_handle *disp, struct fb_info *fbi) {- uint32_t reg, val;+ uint32_t reg; uint32_t pixel_clk, rounded_pixel_clk; struct clk *ldb_clk_parent; struct ldb_data *ldb = mxc_dispdrv_getdata(disp);@@ -238,15 +235,10 @@ static int ldb_disp_setup(struct mxc_dispdrv_handle *disp, struct fb_info *fbi) di = ldb->setting[setting_idx].di; - /* restore channel mode setting */- val = readl(ldb->control_reg);- val |= ldb->setting[setting_idx].ch_val;- writel(val, ldb->control_reg);- dev_dbg(&ldb->pdev->dev, "LDB setup, control reg:0x%x\n",- readl(ldb->control_reg));-- /* vsync setup */ reg = readl(ldb->control_reg);+ /* clear channel mode */+ reg &= ~ldb->setting[setting_idx].ch_mask;+ /* vsync setup */ if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT) { if (di == 0) reg = (reg & ~LDB_DI0_VS_POL_MASK)@@ -265,8 +257,6 @@ static int ldb_disp_setup(struct mxc_dispdrv_handle *disp, struct fb_info *fbi) writel(reg, ldb->control_reg); /* clk setup */- if (ldb->setting[setting_idx].clk_en)- clk_disable(ldb->setting[setting_idx].ldb_di_clk); pixel_clk = (PICOS2KHZ(fbi->var.pixclock)) * 1000UL; ldb_clk_parent = clk_get_parent(ldb->setting[setting_idx].ldb_di_clk); if ((ldb->mode == LDB_SPL_DI0) || (ldb->mode == LDB_SPL_DI1))@@ -276,76 +266,44 @@ static int ldb_disp_setup(struct mxc_dispdrv_handle *disp, struct fb_info *fbi) rounded_pixel_clk = clk_round_rate(ldb->setting[setting_idx].ldb_di_clk, pixel_clk); clk_set_rate(ldb->setting[setting_idx].ldb_di_clk, rounded_pixel_clk);- clk_enable(ldb->setting[setting_idx].ldb_di_clk);- if (!ldb->setting[setting_idx].clk_en)- ldb->setting[setting_idx].clk_en = true; return 0; } -int ldb_fb_event(struct notifier_block *nb, unsigned long val, void *v)+static int ldb_disp_enable(struct mxc_dispdrv_handle *disp,+ struct fb_info *fbi) {- struct ldb_data *ldb = container_of(nb, struct ldb_data, nb);- struct fb_event *event = v;- struct fb_info *fbi = event->info;+ struct ldb_data *ldb = mxc_dispdrv_getdata(disp); int index;- uint32_t data;+ uint32_t reg; index = find_ldb_setting(ldb, fbi); if (index < 0)- return 0;+ return index; - fbi->mode = (struct fb_videomode *)fb_match_mode(&fbi->var,- &fbi->modelist);-- if (!fbi->mode) {- dev_warn(&ldb->pdev->dev,- "LDB: can not find mode for xres=%d, yres=%d\n",- fbi->var.xres, fbi->var.yres);- if (ldb->setting[index].clk_en) {- clk_disable(ldb->setting[index].ldb_di_clk);- ldb->setting[index].clk_en = false;- data = http://www.mamicode.com/readl(ldb->control_reg);- data &= ~ldb->setting[index].ch_mask;- writel(data, ldb->control_reg);- }- return 0;- }+ reg = readl(ldb->control_reg);+ reg |= ldb->setting[index].ch_val;+ writel(reg, ldb->control_reg); - switch (val) {- case FB_EVENT_BLANK:- {- if (*((int *)event->data) == FB_BLANK_UNBLANK) {- if (!ldb->setting[index].clk_en) {- clk_enable(ldb->setting[index].ldb_di_clk);- ldb->setting[index].clk_en = true;- }- } else {- if (ldb->setting[index].clk_en) {- clk_disable(ldb->setting[index].ldb_di_clk);- ldb->setting[index].clk_en = false;- data = http://www.mamicode.com/readl(ldb->control_reg);- data &= ~ldb->setting[index].ch_mask;- writel(data, ldb->control_reg);- dev_dbg(&ldb->pdev->dev,- "LDB blank, control reg:0x%x\n",- readl(ldb->control_reg));- }- }- break;- }- case FB_EVENT_SUSPEND:- if (ldb->setting[index].clk_en) {- clk_disable(ldb->setting[index].ldb_di_clk);- ldb->setting[index].clk_en = false;- }- break;- default:- break;- } return 0; } +static void ldb_disp_disable(struct mxc_dispdrv_handle *disp,+ struct fb_info *fbi)+{+ struct ldb_data *ldb = mxc_dispdrv_getdata(disp);+ int index;+ uint32_t reg;++ index = find_ldb_setting(ldb, fbi);+ if (index < 0)+ return;++ reg = readl(ldb->control_reg);+ reg &= ~ldb->setting[index].ch_mask;+ writel(reg, ldb->control_reg);+}+ #define LVDS_MUX_CTL_WIDTH 2 #define LVDS_MUX_CTL_MASK 3 #define LVDS0_MUX_CTL_OFFS 6@@ -615,14 +573,6 @@ static int ldb_disp_init(struct mxc_dispdrv_handle *disp, dev_dbg(&ldb->pdev->dev, "ldb_clk to di clk: %s -> %s\n", ldb_clk, di_clk); - /* fb notifier for clk setting */- ldb->nb.notifier_call = ldb_fb_event,- ret = fb_register_client(&ldb->nb);- if (ret < 0) {- iounmap(ldb->reg);- return ret;- }- ldb->inited = true; i2c_dev = ldb_i2c_client[lvds_channel];@@ -785,8 +735,6 @@ static void ldb_disp_deinit(struct mxc_dispdrv_handle *disp) clk_put(ldb->setting[i].ldb_di_clk); } - fb_unregister_client(&ldb->nb);- iounmap(ldb->reg); } @@ -795,34 +743,10 @@ static struct mxc_dispdrv_driver ldb_drv = { .init = ldb_disp_init, .deinit = ldb_disp_deinit, .setup = ldb_disp_setup,+ .enable = ldb_disp_enable,+ .disable = ldb_disp_disable, }; -static int ldb_suspend(struct platform_device *pdev, pm_message_t state)-{- struct ldb_data *ldb = dev_get_drvdata(&pdev->dev);- uint32_t data;-- if (!ldb->inited)- return 0;- data = http://www.mamicode.com/readl(ldb->control_reg);- ldb->control_reg_data =http://www.mamicode.com/ data;- data &= ~(LDB_CH0_MODE_MASK | LDB_CH1_MODE_MASK);- writel(data, ldb->control_reg);-- return 0;-}--static int ldb_resume(struct platform_device *pdev)-{- struct ldb_data *ldb = dev_get_drvdata(&pdev->dev);-- if (!ldb->inited)- return 0;- writel(ldb->control_reg_data, ldb->control_reg);-- return 0;-}- static int mxc_ldb_edidread(struct i2c_client *client) { int ret = 0;@@ -972,8 +896,6 @@ static struct platform_driver mxcldb_driver = { }, .probe = ldb_probe, .remove = ldb_remove,- .suspend = ldb_suspend,- .resume = ldb_resume, }; static int __init ldb_init(void)diff --git a/drivers/video/mxc/mipi_dsi.c b/drivers/video/mxc/mipi_dsi.cindex 73c2dda..bdfb93a 100644--- a/drivers/video/mxc/mipi_dsi.c+++ b/drivers/video/mxc/mipi_dsi.c@@ -1,5 +1,5 @@ /*- * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.+ * Copyright (C) 2011-2014 Freescale Semiconductor, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by@@ -621,7 +621,8 @@ static int mipi_dsi_lcd_init(struct mipi_dsi_info *mipi_dsi, return 0; } -int mipi_dsi_enable(struct mxc_dispdrv_handle *disp)+static int mipi_dsi_enable(struct mxc_dispdrv_handle *disp,+ struct fb_info *fbi) { int err; struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);@@ -649,6 +650,14 @@ int mipi_dsi_enable(struct mxc_dispdrv_handle *disp) return 0; } +static void mipi_dsi_disable(struct mxc_dispdrv_handle *disp,+ struct fb_info *fbi)+{+ struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);++ mipi_dsi_power_off(mipi_dsi->disp_mipi);+}+ static int mipi_dsi_disp_init(struct mxc_dispdrv_handle *disp, struct mxc_dispdrv_setting *setting) {@@ -906,7 +915,7 @@ static struct mxc_dispdrv_driver mipi_dsi_drv = { .init = mipi_dsi_disp_init, .deinit = mipi_dsi_disp_deinit, .enable = mipi_dsi_enable,- .disable = mipi_dsi_power_off,+ .disable = mipi_dsi_disable, }; /**diff --git a/drivers/video/mxc/mxc_dispdrv.h b/drivers/video/mxc/mxc_dispdrv.hindex 9a72217..cdf908d 100644--- a/drivers/video/mxc/mxc_dispdrv.h+++ b/drivers/video/mxc/mxc_dispdrv.h@@ -1,5 +1,5 @@ /*- * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.+ * Copyright (C) 2011-2014 Freescale Semiconductor, Inc. All Rights Reserved. */ /*@@ -35,9 +35,9 @@ struct mxc_dispdrv_driver { int (*init) (struct mxc_dispdrv_handle *, struct mxc_dispdrv_setting *); void (*deinit) (struct mxc_dispdrv_handle *); /* display driver enable function for extension */- int (*enable) (struct mxc_dispdrv_handle *);+ int (*enable) (struct mxc_dispdrv_handle *, struct fb_info *); /* display driver disable function, called at early part of fb_blank */- void (*disable) (struct mxc_dispdrv_handle *);+ void (*disable) (struct mxc_dispdrv_handle *, struct fb_info *); /* display driver setup function, called at early part of fb_set_par */ int (*setup) (struct mxc_dispdrv_handle *, struct fb_info *fbi); };diff --git a/drivers/video/mxc/mxc_ipuv3_fb.c b/drivers/video/mxc/mxc_ipuv3_fb.cindex 9deffbbb..28d9e3d 100644--- a/drivers/video/mxc/mxc_ipuv3_fb.c+++ b/drivers/video/mxc/mxc_ipuv3_fb.c@@ -1,5 +1,5 @@ /*- * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.+ * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved. */ /*@@ -677,7 +677,7 @@ static int mxcfb_set_par(struct fb_info *fbi) ipu_enable_channel(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch); if (mxc_fbi->dispdrv && mxc_fbi->dispdrv->drv->enable) {- retval = mxc_fbi->dispdrv->drv->enable(mxc_fbi->dispdrv);+ retval = mxc_fbi->dispdrv->drv->enable(mxc_fbi->dispdrv, fbi); if (retval < 0) { dev_err(fbi->device, "enable error, dispdrv:%s.\n", mxc_fbi->dispdrv->drv->name);@@ -1471,7 +1471,7 @@ static int mxcfb_blank(int blank, struct fb_info *info) case FB_BLANK_HSYNC_SUSPEND: case FB_BLANK_NORMAL: if (mxc_fbi->dispdrv && mxc_fbi->dispdrv->drv->disable)- mxc_fbi->dispdrv->drv->disable(mxc_fbi->dispdrv);+ mxc_fbi->dispdrv->drv->disable(mxc_fbi->dispdrv, info); ipu_disable_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch, true); if (mxc_fbi->ipu_di >= 0) ipu_uninit_sync_panel(mxc_fbi->ipu, mxc_fbi->ipu_di);diff --git a/drivers/video/mxc_hdmi.c b/drivers/video/mxc_hdmi.cindex 2a1b3a1..ee5b0a2 100644--- a/drivers/video/mxc_hdmi.c+++ b/drivers/video/mxc_hdmi.c@@ -1,5 +1,5 @@ /*- * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.+ * Copyright (C) 2011-2014 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by@@ -1968,14 +1968,16 @@ static void mxc_hdmi_cable_connected(struct mxc_hdmi *hdmi) dev_dbg(&hdmi->pdev->dev, "%s exit\n", __func__); } -static int mxc_hdmi_power_on(struct mxc_dispdrv_handle *disp)+static int mxc_hdmi_power_on(struct mxc_dispdrv_handle *disp,+ struct fb_info *fbi) { struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp); mxc_hdmi_phy_init(hdmi); return 0; } -static void mxc_hdmi_power_off(struct mxc_dispdrv_handle *disp)+static void mxc_hdmi_power_off(struct mxc_dispdrv_handle *disp,+ struct fb_info *fbi) { struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp); mxc_hdmi_phy_disable(hdmi);-- 1.7.9.5
[Freescale] LCD 噪点修正