1
0
Fork 0

MLK-14399: 4.9 rebase: LVDS panel does not work on iMX6SX Auto

The LCDIF driver fails at boot time because it cannot read display timings
from device tree. This is a fake error because the LCDIF DT node contains a
display device property which leads to the display driver that also provides
the timings.

This fake error case has been introduced by
commit 5443a75ed038 ("MLK-14283: dts: fix DE polarity for lcdif") and
commit 56412d6a83d8 ("MLK-13996: lcdif: Use DE polarity specified in DTS")
which fixed DE polarity panel differences for different boards.

This patch adds support for choosing a particular video mode from the ones
provided by the display driver, thus also fixing the DE polarity issue
initially fixed by the above mentioned 2 patches.

Signed-off-by: Cristina Ciocan <cristina-mihaela.ciocan@nxp.com>
pull/10/head
Cristina Ciocan 2017-03-09 20:13:17 +02:00 committed by Jason Liu
parent 7e3c173128
commit 929d75b54b
4 changed files with 94 additions and 9 deletions

View File

@ -44,6 +44,12 @@ Required properties:
- interrupts: Should contain LCDIF interrupts
- display: phandle to display node (see below for details)
Optional properties:
- disp-dev: Display device driver name
- disp-videomode: Display device video mode name; this is used if the panel
supports multiple video modes, in order to chose the right one (see below for
examples)
* display node
Required properties:
@ -84,3 +90,46 @@ lcdif@80030000 {
};
};
};
Examples - optional properties:
Snippet from imx7d-sdb-mipi-dsi.dts:
&lcdif {
disp-dev = "mipi_dsi_samsung";
disp-videomode = "TRUULY-WVGA-SYNC-LOW";
};
&mipi_dsi {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_mipi_dsi_reset>;
lcd_panel = "TRULY-WVGA-TFT3P5581E";
resets = <&mipi_dsi_reset>;
status = "okay";
};
In the above example, the panel supports 2 video modes (snippet from
drivers/video/fbdev/mxc/mxcfb_hx8363_wvga.c):
#define ACTIVE_HIGH_NAME "TRUULY-WVGA-SYNC-HIGH"
#define ACTIVE_LOW_NAME "TRUULY-WVGA-SYNC-LOW"
static struct fb_videomode truly_lcd_modedb[] = {
{
ACTIVE_HIGH_NAME, 50, 480, 854, 41042,
40, 60,
3, 3,
8, 4,
0x0,
FB_VMODE_NONINTERLACED,
0,
}, {
ACTIVE_LOW_NAME, 50, 480, 854, 41042,
40, 60,
3, 3,
8, 4,
FB_SYNC_OE_LOW_ACT,
FB_VMODE_NONINTERLACED,
0,
},
};

View File

@ -19,6 +19,7 @@
&lcdif {
disp-dev = "mipi_dsi_samsung";
disp-videomode = "TRUULY-WVGA-SYNC-LOW";
};
&mipi_dsi {

View File

@ -128,15 +128,26 @@ static void parse_variadic(int n, u8 *buf, ...)
static int hx8363bl_brightness;
#define ACTIVE_HIGH_NAME "TRUULY-WVGA-SYNC-HIGH"
#define ACTIVE_LOW_NAME "TRUULY-WVGA-SYNC-LOW"
static struct fb_videomode truly_lcd_modedb[] = {
{
"TRUULY-WVGA", 50, 480, 854, 41042,
40, 60,
3, 3,
8, 4,
0x0,
FB_VMODE_NONINTERLACED,
0,
ACTIVE_HIGH_NAME, 50, 480, 854, 41042,
40, 60,
3, 3,
8, 4,
0x0,
FB_VMODE_NONINTERLACED,
0,
}, {
ACTIVE_LOW_NAME, 50, 480, 854, 41042,
40, 60,
3, 3,
8, 4,
FB_SYNC_OE_LOW_ACT,
FB_VMODE_NONINTERLACED,
0,
},
};

View File

@ -233,6 +233,8 @@ struct mxsfb_layer {
struct mxsfb_info *fbi;
};
#define NAME_LEN 32
struct mxsfb_info {
struct fb_info *fb_info;
struct platform_device *pdev;
@ -255,12 +257,14 @@ struct mxsfb_info {
struct completion flip_complete;
int cur_blank;
int restore_blank;
char disp_dev[32];
char disp_dev[NAME_LEN];
struct mxc_dispdrv_handle *dispdrv;
int id;
struct fb_var_screeninfo var;
struct pm_qos_request pm_qos_req;
char disp_videomode[NAME_LEN];
#ifdef CONFIG_FB_MXC_OVERLAY
struct mxsfb_layer overlay;
#endif
@ -1277,7 +1281,7 @@ static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host)
struct device_node *display_np;
struct device_node *timings_np;
struct display_timings *timings = NULL;
const char *disp_dev;
const char *disp_dev, *disp_videomode;
u32 width;
int i;
int ret = 0;
@ -1325,6 +1329,13 @@ static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host)
ret = of_property_read_string(np, "disp-dev", &disp_dev);
if (!ret) {
memcpy(host->disp_dev, disp_dev, strlen(disp_dev));
if (!of_property_read_string(np, "disp-videomode",
&disp_videomode)) {
memcpy(host->disp_videomode, disp_videomode,
strlen(disp_videomode));
}
/* Timing is from encoder driver */
goto put_display_node;
}
@ -1439,7 +1450,20 @@ static int mxsfb_dispdrv_init(struct platform_device *pdev,
memcpy(disp_dev, host->disp_dev, strlen(host->disp_dev));
disp_dev[strlen(host->disp_dev)] = '\0';
/* Use videomode name from dtb, if any given */
if (host->disp_videomode) {
setting.dft_mode_str = kmalloc(NAME_LEN, GFP_KERNEL);
if (setting.dft_mode_str) {
memset(setting.dft_mode_str, 0x0, NAME_LEN);
memcpy(setting.dft_mode_str, host->disp_videomode,
strlen(host->disp_videomode));
}
}
host->dispdrv = mxc_dispdrv_gethandle(disp_dev, &setting);
kfree(setting.dft_mode_str);
if (IS_ERR(host->dispdrv)) {
if (PTR_ERR(host->dispdrv) == -EPROBE_DEFER)
return PTR_ERR(host->dispdrv);