Linux Framebuffer Layer development
 help / color / mirror / Atom feed
* [PATCH v2] da8xx-fb: enable sync lost interrupt
From: Manjunathappa, Prakash @ 2012-07-24  3:55 UTC (permalink / raw)
  To: linux-fbdev

Patch enables sync lost interrupt and interrupt handler already
takes care to handle it.

Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
---
Since v1:
Minor nit, replaced spaces with tabs.

 drivers/video/da8xx-fb.c |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 47118c7..8163832 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -54,6 +54,7 @@
 #define LCD_DMA_BURST_8			0x3
 #define LCD_DMA_BURST_16		0x4
 #define LCD_V1_END_OF_FRAME_INT_ENA	BIT(2)
+#define LCD_V1_SYNC_LOST_ENA		BIT(5)
 #define LCD_V2_END_OF_FRAME0_INT_ENA	BIT(8)
 #define LCD_V2_END_OF_FRAME1_INT_ENA	BIT(9)
 #define LCD_DUAL_FRAME_BUFFER_ENABLE	BIT(0)
@@ -441,10 +442,10 @@ static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
 
 	/* enable additional interrupts here */
 	if (lcd_revision = LCD_VERSION_1) {
-		reg |= LCD_V1_UNDERFLOW_INT_ENA;
+		reg |= LCD_V1_UNDERFLOW_INT_ENA | LCD_V1_SYNC_LOST_ENA;
 	} else {
 		reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
-			LCD_V2_UNDERFLOW_INT_ENA;
+			LCD_V2_UNDERFLOW_INT_ENA | LCD_SYNC_LOST;
 		lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
 	}
 
@@ -718,6 +719,7 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
 	u32 reg_int;
 
 	if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
+		pr_err("LCDC sync lost or underflow error occurred\n");
 		lcd_disable_raster();
 		lcdc_write(stat, LCD_MASKED_STAT_REG);
 		lcd_enable_raster();
@@ -773,6 +775,7 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
 	u32 reg_ras;
 
 	if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
+		pr_err("LCDC sync lost or underflow error occurred\n");
 		lcd_disable_raster();
 		lcdc_write(stat, LCD_STAT_REG);
 		lcd_enable_raster();
-- 
1.7.1


^ permalink raw reply related

* [PATCH v2] video: exynos: s6e8ax0: support early fb event of fb_blank()
From: Donghwa Lee @ 2012-07-24  2:19 UTC (permalink / raw)
  To: linux-arm-kernel

This patch supports early fb event of fb_blank().

- In case of lcd power off : call early_set_power() interface and lcd
power is off. And then framebuffer is blanked.

- In case of lcd power on : First, framebuffer is unblanked, and then
call set_power() interface to turn lcd on.

Signed-off-by: Donghwa Lee <dh09.lee@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
Changes of v1:
	- changes function name from s6e8aa0_early_set_power() to
	s6e8ax0_early_set_power()

 drivers/video/exynos/s6e8ax0.c |   32 ++++++++++++++++++++++++++++++++
 1 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/drivers/video/exynos/s6e8ax0.c b/drivers/video/exynos/s6e8ax0.c
index 05d080b..bfb1919 100644
--- a/drivers/video/exynos/s6e8ax0.c
+++ b/drivers/video/exynos/s6e8ax0.c
@@ -663,6 +663,37 @@ static int s6e8ax0_gamma_ctrl(struct s6e8ax0 *lcd, int gamma)
 	return 0;
 }
 
+static int s6e8ax0_early_set_power(struct lcd_device *ld, int power)
+{
+	struct s6e8ax0 *lcd = lcd_get_data(ld);
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	int ret = 0;
+
+	if (power != FB_BLANK_UNBLANK && power != FB_BLANK_POWERDOWN &&
+			power != FB_BLANK_NORMAL) {
+		dev_err(lcd->dev, "power value should be 0, 1 or 4.\n");
+		return -EINVAL;
+	}
+
+	if (lcd->power = power) {
+		dev_err(lcd->dev, "power mode is same as previous one.\n");
+		return -EINVAL;
+	}
+
+	if (ops->set_early_blank_mode) {
+		/* LCD power off */
+		if ((POWER_IS_OFF(power) && POWER_IS_ON(lcd->power))
+			|| (POWER_IS_ON(lcd->power) && POWER_IS_NRM(power))) {
+			ret = ops->set_early_blank_mode(lcd_to_master(lcd),
+							power);
+			if (!ret && lcd->power != power)
+				lcd->power = power;
+		}
+	}
+
+	return ret;
+}
+
 static int s6e8ax0_set_power(struct lcd_device *ld, int power)
 {
 	struct s6e8ax0 *lcd = lcd_get_data(ld);
@@ -731,6 +762,7 @@ static int s6e8ax0_set_brightness(struct backlight_device *bd)
 }
 
 static struct lcd_ops s6e8ax0_lcd_ops = {
+	.early_set_power = s6e8ax0_early_set_power,
 	.set_power = s6e8ax0_set_power,
 	.get_power = s6e8ax0_get_power,
 };
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH 4/4] fbcon: optimize parameters parsing loop.
From: Paul Cercueil @ 2012-07-24  1:00 UTC (permalink / raw)
  To: FlorianSchandinat; +Cc: linux-kernel, linux-fbdev, Paul Cercueil
In-Reply-To: <1343091626-11435-1-git-send-email-paul@crapouillou.net>


Signed-off-by: Paul Cercueil <paul@crapouillou.net>
---
 drivers/video/console/fbcon.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 9b83b75..1ecaf68 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -441,8 +441,10 @@ static int __init fb_console_setup(char *this_opt)
 		return 1;
 
 	while ((options = strsep(&this_opt, ",")) != NULL) {
-		if (!strncmp(options, "font:", 5))
+		if (!strncmp(options, "font:", 5)) {
 			strlcpy(fontname, options + 5, sizeof(fontname));
+			continue;
+		}
 		
 		if (!strncmp(options, "scrollback:", 11)) {
 			char *k;
@@ -468,6 +470,7 @@ static int __init fb_console_setup(char *this_opt)
 			/* (k && *k): Check for garbage after the suffix */
 			if (ret || (k && *k))
 				printk(KERN_WARNING "fbcon: scrollback: incorrect value.\n");
+			continue;
 		}
 		
 		if (!strncmp(options, "map:", 4)) {
@@ -484,6 +487,7 @@ static int __init fb_console_setup(char *this_opt)
 			} else {
 				printk(KERN_WARNING "fbcon: map: incorrect value.\n");
 			}
+			continue;
 		}
 
 		if (!strncmp(options, "vc:", 3)) {
@@ -513,6 +517,7 @@ static int __init fb_console_setup(char *this_opt)
 				fbcon_is_default = 0;
 			else
 				printk(KERN_WARNING "fbcon: vc: incorrect value.\n");
+			continue;
 		}
 
 		if (!strncmp(options, "rotate:", 7)) {
@@ -525,6 +530,7 @@ static int __init fb_console_setup(char *this_opt)
 			} else {
 				printk(KERN_WARNING "fbcon: rotate: incorrect value.\n");
 			}
+			continue;
 		}
 	}
 	return 1;
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 3/4] fbcon: continue parsing parameters after an error.
From: Paul Cercueil @ 2012-07-24  1:00 UTC (permalink / raw)
  To: FlorianSchandinat; +Cc: linux-kernel, linux-fbdev, Paul Cercueil
In-Reply-To: <1343091626-11435-1-git-send-email-paul@crapouillou.net>


Signed-off-by: Paul Cercueil <paul@crapouillou.net>
---
 drivers/video/console/fbcon.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 3ffab97..9b83b75 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -481,9 +481,9 @@ static int __init fb_console_setup(char *this_opt)
 				}
 
 				fbcon_map_override();
+			} else {
+				pr_warn("fbcon: map: incorrect value.\n");
 			}
-
-			return 1;
 		}
 
 		if (!strncmp(options, "vc:", 3)) {
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 2/4] fbcon: prevent possible buffer overflow.
From: Paul Cercueil @ 2012-07-24  1:00 UTC (permalink / raw)
  To: FlorianSchandinat; +Cc: linux-kernel, linux-fbdev, Paul Cercueil
In-Reply-To: <1343091626-11435-1-git-send-email-paul@crapouillou.net>


Signed-off-by: Paul Cercueil <paul@crapouillou.net>
---
 drivers/video/console/fbcon.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index a0b1818..3ffab97 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -442,7 +442,7 @@ static int __init fb_console_setup(char *this_opt)
 
 	while ((options = strsep(&this_opt, ",")) != NULL) {
 		if (!strncmp(options, "font:", 5))
-			strcpy(fontname, options + 5);
+			strlcpy(fontname, options + 5, sizeof(fontname));
 		
 		if (!strncmp(options, "scrollback:", 11)) {
 			char *k;
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 1/4] fbcon: use kstrtouint instead of deprecated function simple_strtoul.
From: Paul Cercueil @ 2012-07-24  1:00 UTC (permalink / raw)
  To: FlorianSchandinat; +Cc: linux-kernel, linux-fbdev, Paul Cercueil


Signed-off-by: Paul Cercueil <paul@crapouillou.net>
---
 drivers/video/console/fbcon.c |  102 ++++++++++++++++++++++++++++-------------
 1 file changed, 69 insertions(+), 33 deletions(-)

diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 2e471c2..a0b1818 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -435,7 +435,7 @@ static void fbcon_del_cursor_timer(struct fb_info *info)
 static int __init fb_console_setup(char *this_opt)
 {
 	char *options;
-	int i, j;
+	int i, j, ret;
 
 	if (!this_opt || !*this_opt)
 		return 1;
@@ -445,18 +445,29 @@ static int __init fb_console_setup(char *this_opt)
 			strcpy(fontname, options + 5);
 		
 		if (!strncmp(options, "scrollback:", 11)) {
+			char *k;
 			options += 11;
-			if (*options) {
-				fbcon_softback_size = simple_strtoul(options, &options, 0);
-				if (*options = 'k' || *options = 'K') {
-					fbcon_softback_size *= 1024;
-					options++;
-				}
-				if (*options != ',')
-					return 1;
-				options++;
-			} else
-				return 1;
+			k = options;
+
+			while (*k != '\0' && *k != 'k' && *k != 'K')
+				k++;
+
+			/* Clear the 'k' or 'K' suffix to
+			 * prevent errors with kstrtouint */
+			if (*k != '\0')
+				*k++ = '\0';
+			else
+				k = NULL;
+
+			ret = kstrtouint(options, 0, (unsigned int *)
+						&fbcon_softback_size);
+
+			if (!ret && k)
+				fbcon_softback_size *= 1024;
+
+			/* (k && *k): Check for garbage after the suffix */
+			if (ret || (k && *k))
+				pr_warn("fbcon: scrollback: incorrect value.\n");
 		}
 		
 		if (!strncmp(options, "map:", 4)) {
@@ -476,22 +487,44 @@ static int __init fb_console_setup(char *this_opt)
 		}
 
 		if (!strncmp(options, "vc:", 3)) {
+			char *dash;
 			options += 3;
-			if (*options)
-				first_fb_vc = simple_strtoul(options, &options, 10) - 1;
-			if (first_fb_vc < 0)
-				first_fb_vc = 0;
-			if (*options++ = '-')
-				last_fb_vc = simple_strtoul(options, &options, 10) - 1;
-			fbcon_is_default = 0; 
-		}	
+
+			dash = strchr(options, '-');
+			if (dash)
+				*dash++ = '\0';
+
+			ret = kstrtouint(options, 10,
+						(unsigned int *) &first_fb_vc);
+			if (!ret) {
+				if (--first_fb_vc < 0)
+					first_fb_vc = 0;
+
+				if (dash) {
+					ret = kstrtouint(dash, 10,
+								(unsigned int *)
+								&last_fb_vc);
+					if (!ret)
+						last_fb_vc--;
+				}
+			}
+
+			if (!ret)
+				fbcon_is_default = 0;
+			else
+				pr_warn("fbcon: vc: incorrect value.\n");
+		}
 
 		if (!strncmp(options, "rotate:", 7)) {
 			options += 7;
-			if (*options)
-				initial_rotation = simple_strtoul(options, &options, 0);
-			if (initial_rotation > 3)
-				initial_rotation = 0;
+			ret = kstrtouint(options, 0, (unsigned int *)
+						&initial_rotation);
+			if (!ret) {
+				if (initial_rotation > 3)
+					initial_rotation = 0;
+			} else {
+				pr_warn("fbcon: rotate: incorrect value.\n");
+			}
 		}
 	}
 	return 1;
@@ -3312,8 +3345,8 @@ static ssize_t store_rotate(struct device *device,
 			    size_t count)
 {
 	struct fb_info *info;
-	int rotate, idx;
-	char **last = NULL;
+	int idx;
+	unsigned int rotate;
 
 	if (fbcon_has_exited)
 		return count;
@@ -3325,7 +3358,8 @@ static ssize_t store_rotate(struct device *device,
 		goto err;
 
 	info = registered_fb[idx];
-	rotate = simple_strtoul(buf, last, 0);
+	if (kstrtouint(buf, 0, &rotate))
+		goto err;
 	fbcon_rotate(info, rotate);
 err:
 	console_unlock();
@@ -3337,8 +3371,8 @@ static ssize_t store_rotate_all(struct device *device,
 				size_t count)
 {
 	struct fb_info *info;
-	int rotate, idx;
-	char **last = NULL;
+	int idx;
+	unsigned int rotate;
 
 	if (fbcon_has_exited)
 		return count;
@@ -3350,7 +3384,8 @@ static ssize_t store_rotate_all(struct device *device,
 		goto err;
 
 	info = registered_fb[idx];
-	rotate = simple_strtoul(buf, last, 0);
+	if (kstrtouint(buf, 0, &rotate))
+		goto err;
 	fbcon_rotate_all(info, rotate);
 err:
 	console_unlock();
@@ -3412,8 +3447,8 @@ static ssize_t store_cursor_blink(struct device *device,
 				  const char *buf, size_t count)
 {
 	struct fb_info *info;
-	int blink, idx;
-	char **last = NULL;
+	int idx;
+	unsigned int blink;
 
 	if (fbcon_has_exited)
 		return count;
@@ -3429,7 +3464,8 @@ static ssize_t store_cursor_blink(struct device *device,
 	if (!info->fbcon_par)
 		goto err;
 
-	blink = simple_strtoul(buf, last, 0);
+	if (kstrtouint(buf, 0, &blink))
+		goto err;
 
 	if (blink) {
 		fbcon_cursor_noblink = 0;
-- 
1.7.10.4


^ permalink raw reply related

* Re: [RFC][PATCH V2 3/3] tegra: add pwm backlight device tree nodes
From: Stephen Warren @ 2012-07-23 20:38 UTC (permalink / raw)
  To: Alex Courbot
  Cc: Simon Glass, Thierry Reding, linux-tegra@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-fbdev@vger.kernel.org,
	devicetree-discuss@lists.ozlabs.org
In-Reply-To: <4FFFB2DC.3040605@nvidia.com>

On 07/12/2012 11:32 PM, Alex Courbot wrote:
> On 07/12/2012 11:27 PM, Simon Glass wrote
...
>>  From my understanding mixing strings and numbers in a property is
>> frowned on though.
> 
> But doesn't it make sense in the current case? The power sequence is
> basically a program that is run by an interpreter. From this
> perspective, it makes more sense to me to have it as a binary field
> rather than a hierarchy of nodes and properties that will be harder to
> parse and will make error detection more complicated. I don't really see
> any practical benefit from turning the steps into sub-nodes, but then
> again I am not so familiar with the DT.

Mixing strings and integers in a property isn't "allowed" (by convention
of DT bindings reviewers - as you noticed, dtc will happily compile it);
there are practical issues with attempting to do so, such as causing the
integer values to be unaligned, and thus causing the current integer
parsing code to fail, etc.

^ permalink raw reply

* RE: [PATCH v3] video: da8xx-fb: add 24bpp LCD configuration support
From: Manjunathappa, Prakash @ 2012-07-23  8:26 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1342712266-4381-1-git-send-email-prakash.pm@ti.com>

Hi,

On Thu, Jul 19, 2012 at 21:07:46, Manjunathappa, Prakash wrote:
> LCD controller on am335x supports 24bpp raster configuration in addition
> to ones on da850. LCDC also supports 24bpp in unpacked format having
> ARGB:8888 32bpp format data in DDR, but it doesn't interpret alpha
> component of the data.
> 
> Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
> Cc: Anatolij Gustschin <agust@denx.de>
> ---
> Since v2:
> Fixed additional configurations for 24bpp support.
> Since v1:
> Simplified calculation of pseudopalette for FB_VISUAL_TRUECOLOR type.
> 
>  drivers/video/da8xx-fb.c |  127 ++++++++++++++++++++++++++++++++++------------
>  1 files changed, 94 insertions(+), 33 deletions(-)
> 
> diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
> index 47118c7..3d2d0d1 100644
> --- a/drivers/video/da8xx-fb.c
> +++ b/drivers/video/da8xx-fb.c
> @@ -83,6 +83,8 @@
>  #define LCD_V2_LIDD_CLK_EN		BIT(1)
>  #define LCD_V2_CORE_CLK_EN		BIT(0)
>  #define LCD_V2_LPP_B10			26
> +#define LCD_V2_TFT_24BPP_MODE		BIT(25)
> +#define LCD_V2_TFT_24BPP_UNPACK		BIT(26)
>  
>  /* LCD Raster Timing 2 Register */
>  #define LCD_AC_BIAS_TRANSITIONS_PER_INT(x)	((x) << 16)
> @@ -153,7 +155,7 @@ struct da8xx_fb_par {
>  	unsigned int		dma_end;
>  	struct clk *lcdc_clk;
>  	int irq;
> -	unsigned short pseudo_palette[16];
> +	unsigned long pseudo_palette[16];

I am still not convinced as sizes of "unsigned long" and "unsigned int" are not
guaranteed to be 32bit across platforms and compilers, so planning to retain u32.

Florian Tobias Schandinat,
Can you please comment?

Here is the history:
http://marc.info/?l=linux-fbdev&m\x134259216714719&w=2

>  	unsigned int palette_sz;
>  	unsigned int pxl_clk;
>  	int blank;
> @@ -482,6 +484,9 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
>  {
>  	u32 reg;
>  
> +	if ((bpp > 16) && (lcd_revision = LCD_VERSION_1))
> +		return -EINVAL;
> +
>  	/* Set the Panel Width */
>  	/* Pixels per line = (PPL + 1)*16 */
>  	if (lcd_revision = LCD_VERSION_1) {
> @@ -525,6 +530,12 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
>  	reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(1 << 8);
>  	if (raster_order)
>  		reg |= LCD_RASTER_ORDER;
> +
> +	if (bpp = 24)
> +		reg |= LCD_V2_TFT_24BPP_MODE;
> +	else if (bpp = 32)
> +		reg |= (LCD_V2_TFT_24BPP_MODE | LCD_V2_TFT_24BPP_UNPACK);
> +
>  	lcdc_write(reg, LCD_RASTER_CTRL_REG);
>  
>  	switch (bpp) {
> @@ -532,6 +543,8 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
>  	case 2:
>  	case 4:
>  	case 16:
> +	case 24:
> +	case 32:
>  		par->palette_sz = 16 * 2;
>  		break;
>  
> @@ -546,6 +559,8 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
>  	return 0;
>  }
>  
> +
> +#define CNVT_TOHW(val, width) ((((val)<<(width))+0x7FFF-(val))>>16)

since multiple FB drivers have re-defined this macro, I will move this to common place(linux/fb.h) and
convert it as inline function.

Thanks,
Prakash

>  static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
[...]

^ permalink raw reply

* RE: [PATCH] video: da8xx-fb: allow frame to complete before disabling LCDC
From: Manjunathappa, Prakash @ 2012-07-23  7:52 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1342799516-10842-1-git-send-email-prakash.pm@ti.com>

Hi Florian Tobias Schandinat,

On Sun, Jul 22, 2012 at 17:20:28, Florian Tobias Schandinat wrote:
> Hi,
> 
> On 07/20/2012 03:51 PM, Manjunathappa, Prakash wrote:
> > Wait for active frame transfer to complete before disabling LCDC.
> > At the same this wait is not be required when there are sync and
> > underflow errors.
> > 
> > Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
> > ---
> >  drivers/video/da8xx-fb.c |   58 ++++++++++++++++++++++++++++++++++++---------
> >  1 files changed, 46 insertions(+), 12 deletions(-)
> > 
> > diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
> > index 4440292..c178592 100644
> > --- a/drivers/video/da8xx-fb.c
> > +++ b/drivers/video/da8xx-fb.c
> > @@ -31,6 +31,7 @@
> >  #include <linux/cpufreq.h>
> >  #include <linux/console.h>
> >  #include <linux/slab.h>
> > +#include <linux/delay.h>
> >  #include <video/da8xx-fb.h>
> >  #include <asm/div64.h>
> >  
> > @@ -45,6 +46,7 @@
> >  #define LCD_PL_LOAD_DONE		BIT(6)
> >  #define LCD_FIFO_UNDERFLOW		BIT(5)
> >  #define LCD_SYNC_LOST			BIT(2)
> > +#define LCD_FRAME_DONE			BIT(0)
> >  
> >  /* LCD DMA Control Register */
> >  #define LCD_DMA_BURST_SIZE(x)		((x) << 4)
> > @@ -129,6 +131,8 @@
> >  #define RIGHT_MARGIN	64
> >  #define UPPER_MARGIN	32
> >  #define LOWER_MARGIN	32
> > +#define WAIT_FOR_FRAME_DONE	true
> > +#define NO_WAIT_FOR_FRAME_DONE	false
> 
> These defines look a bit strange. While I consider it acceptable, one
> really should know the arguments of a function and hence it doesn't make
> sense to add an extra abstraction to bool (in contrast to flags where
> such defines are really helpful).
> 

I agree to remove them.

> >  
> >  static resource_size_t da8xx_fb_reg_base;
> >  static struct resource *lcdc_regs;
> > @@ -280,13 +284,39 @@ static inline void lcd_enable_raster(void)
> >  }
> >  
> >  /* Disable the Raster Engine of the LCD Controller */
> > -static inline void lcd_disable_raster(void)
> > +static inline void lcd_disable_raster(bool wait_for_frame_done)
> >  {
> >  	u32 reg;
> > +	u32 loop_cnt = 0;
> > +	u32 stat;
> > +	u32 i = 0;
> > +
> > +	/* 50 milli seconds should be sufficient for a frame to complete */
> > +	if (wait_for_frame_done)
> > +		loop_cnt = 50;
> >  
> >  	reg = lcdc_read(LCD_RASTER_CTRL_REG);
> >  	if (reg & LCD_RASTER_ENABLE)
> >  		lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
> > +
> > +	/* Wait for the current frame to complete */
> > +	do {
> > +		if (lcd_revision = LCD_VERSION_1)
> > +			stat = lcdc_read(LCD_STAT_REG);
> > +		else
> > +			stat = lcdc_read(LCD_RAW_STAT_REG);
> > +		mdelay(1);
> > +	} while (!(stat & LCD_FRAME_DONE) && (i++ < loop_cnt));
> 
> I don't know the documentation of your hardware but this really looks
> like you are waiting after you disabled it.
> 

Correct, it is expected to wait for frame_done before applying the software reset.
I will re-write the commit message to convey the same.

> > +
> > +	if (lcd_revision = LCD_VERSION_1)
> > +		lcdc_write(stat, LCD_STAT_REG);
> > +	else
> > +		lcdc_write(stat, LCD_MASKED_STAT_REG);
> > +
> > +	if ((loop_cnt != 0) && (i >= loop_cnt)) {
> > +		pr_err("LCD Controller timed out\n");
> > +		return;
> > +	}
> >  }
> >  
> >  static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
> > @@ -663,7 +693,7 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
> >  static void lcd_reset(struct da8xx_fb_par *par)
> >  {
> >  	/* Disable the Raster if previously Enabled */
> > -	lcd_disable_raster();
> > +	lcd_disable_raster(NO_WAIT_FOR_FRAME_DONE);
> >  
> >  	/* DMA has to be disabled */
> >  	lcdc_write(0, LCD_DMA_CTRL_REG);
> > @@ -760,7 +790,8 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
> >  	u32 reg_int;
> >  
> >  	if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
> > -		lcd_disable_raster();
> > +		pr_err("LCDC sync lost or underflow error occured\n");
> > +		lcd_disable_raster(NO_WAIT_FOR_FRAME_DONE);
> >  		lcdc_write(stat, LCD_MASKED_STAT_REG);
> >  		lcd_enable_raster();
> >  	} else if (stat & LCD_PL_LOAD_DONE) {
> > @@ -770,7 +801,7 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
> >  		 * interrupt via the following write to the status register. If
> >  		 * this is done after then one gets multiple PL done interrupts.
> >  		 */
> > -		lcd_disable_raster();
> > +		lcd_disable_raster(NO_WAIT_FOR_FRAME_DONE);
> >  
> >  		lcdc_write(stat, LCD_MASKED_STAT_REG);
> >  
> > @@ -815,7 +846,8 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
> >  	u32 reg_ras;
> >  
> >  	if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
> > -		lcd_disable_raster();
> > +		pr_err("LCDC sync lost or underflow error occured\n");
> > +		lcd_disable_raster(NO_WAIT_FOR_FRAME_DONE);
> >  		lcdc_write(stat, LCD_STAT_REG);
> >  		lcd_enable_raster();
> >  	} else if (stat & LCD_PL_LOAD_DONE) {
> > @@ -825,7 +857,7 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
> >  		 * interrupt via the following write to the status register. If
> >  		 * this is done after then one gets multiple PL done interrupts.
> >  		 */
> > -		lcd_disable_raster();
> > +		lcd_disable_raster(NO_WAIT_FOR_FRAME_DONE);
> >  
> >  		lcdc_write(stat, LCD_STAT_REG);
> >  
> > @@ -945,7 +977,7 @@ static int lcd_da8xx_cpufreq_transition(struct notifier_block *nb,
> >  	if (val = CPUFREQ_POSTCHANGE) {
> >  		if (par->lcd_fck_rate != clk_get_rate(par->lcdc_clk)) {
> >  			par->lcd_fck_rate = clk_get_rate(par->lcdc_clk);
> > -			lcd_disable_raster();
> > +			lcd_disable_raster(WAIT_FOR_FRAME_DONE);
> >  			lcd_calc_clk_divider(par);
> >  			lcd_enable_raster();
> >  		}
> > @@ -982,7 +1014,7 @@ static int __devexit fb_remove(struct platform_device *dev)
> >  		if (par->panel_power_ctrl)
> >  			par->panel_power_ctrl(0);
> >  
> > -		lcd_disable_raster();
> > +		lcd_disable_raster(WAIT_FOR_FRAME_DONE);
> >  		lcdc_write(0, LCD_RASTER_CTRL_REG);
> >  
> >  		/* disable DMA  */
> > @@ -1095,7 +1127,7 @@ static int cfb_blank(int blank, struct fb_info *info)
> >  		if (par->panel_power_ctrl)
> >  			par->panel_power_ctrl(0);
> >  
> > -		lcd_disable_raster();
> > +		lcd_disable_raster(WAIT_FOR_FRAME_DONE);
> >  		break;
> >  	default:
> >  		ret = -EINVAL;
> > @@ -1435,7 +1467,7 @@ static int fb_suspend(struct platform_device *dev, pm_message_t state)
> >  		par->panel_power_ctrl(0);
> >  
> >  	fb_set_suspend(info, 1);
> > -	lcd_disable_raster();
> > +	lcd_disable_raster(WAIT_FOR_FRAME_DONE);
> >  	clk_disable(par->lcdc_clk);
> >  	console_unlock();
> >  
> > @@ -1447,11 +1479,13 @@ static int fb_resume(struct platform_device *dev)
> >  	struct da8xx_fb_par *par = info->par;
> >  
> >  	console_lock();
> > -	if (par->panel_power_ctrl)
> > -		par->panel_power_ctrl(1);
> >  
> >  	clk_enable(par->lcdc_clk);
> > +	usleep_range(1000, 2000);
> >  	lcd_enable_raster();
> > +	if (par->panel_power_ctrl)
> > +		par->panel_power_ctrl(1);
> > +
> 
> This change looks unrelated and should go in a separate patch?
> 

Agree, I will send out in separate patch.

Thanks,
Prakash

> >  	fb_set_suspend(info, 0);
> >  	console_unlock();
> >  
> 
> 
> Best regards,
> 
> Florian Tobias Schandinat
> 


^ permalink raw reply

* [PATCH] video: exynos: s6e8ax0: support early fb event of fb_blank()
From: Donghwa Lee @ 2012-07-23  4:27 UTC (permalink / raw)
  To: linux-arm-kernel

This patch supports early fb event of fb_blank().

- In case of lcd power off : call early_set_power() interface and lcd
power is off. And then framebuffer is blanked.

- In case of lcd power on : First, framebuffer is unblanked, and then
call set_power() interface to turn lcd on.

Signed-off-by: Donghwa Lee <dh09.lee@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 drivers/video/exynos/s6e8ax0.c |   32 ++++++++++++++++++++++++++++++++
 1 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/drivers/video/exynos/s6e8ax0.c b/drivers/video/exynos/s6e8ax0.c
index 05d080b..e51d024 100644
--- a/drivers/video/exynos/s6e8ax0.c
+++ b/drivers/video/exynos/s6e8ax0.c
@@ -663,6 +663,37 @@ static int s6e8ax0_gamma_ctrl(struct s6e8ax0 *lcd, int gamma)
 	return 0;
 }
 
+static int s6e8aa0_early_set_power(struct lcd_device *ld, int power)
+{
+	struct s6e8ax0 *lcd = lcd_get_data(ld);
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	int ret = 0;
+
+	if (power != FB_BLANK_UNBLANK && power != FB_BLANK_POWERDOWN &&
+			power != FB_BLANK_NORMAL) {
+		dev_err(lcd->dev, "power value should be 0, 1 or 4.\n");
+		return -EINVAL;
+	}
+
+	if (lcd->power = power) {
+		dev_err(lcd->dev, "power mode is same as previous one.\n");
+		return -EINVAL;
+	}
+
+	if (ops->set_early_blank_mode) {
+		/* LCD power off */
+		if ((POWER_IS_OFF(power) && POWER_IS_ON(lcd->power))
+			|| (POWER_IS_ON(lcd->power) && POWER_IS_NRM(power))) {
+			ret = ops->set_early_blank_mode(lcd_to_master(lcd),
+							power);
+			if (!ret && lcd->power != power)
+				lcd->power = power;
+		}
+	}
+
+	return ret;
+}
+
 static int s6e8ax0_set_power(struct lcd_device *ld, int power)
 {
 	struct s6e8ax0 *lcd = lcd_get_data(ld);
@@ -731,6 +762,7 @@ static int s6e8ax0_set_brightness(struct backlight_device *bd)
 }
 
 static struct lcd_ops s6e8ax0_lcd_ops = {
+	.early_set_power = s6e8aa0_early_set_power,
 	.set_power = s6e8ax0_set_power,
 	.get_power = s6e8ax0_get_power,
 };
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH] video: exynos mipi dsi: Fix mipi dsi regulators handling issue
From: Donghwa Lee @ 2012-07-23  2:25 UTC (permalink / raw)
  To: linux-arm-kernel

When FB_BLANK_UNLANK event occured, exynos mipi dsi regulators have to turn on.

Signed-off-by: Donghwa Lee <dh09.lee@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 drivers/video/exynos/exynos_mipi_dsi.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/video/exynos/exynos_mipi_dsi.c b/drivers/video/exynos/exynos_mipi_dsi.c
index 6c1f5c3..9390640 100644
--- a/drivers/video/exynos/exynos_mipi_dsi.c
+++ b/drivers/video/exynos/exynos_mipi_dsi.c
@@ -154,7 +154,7 @@ static int exynos_mipi_dsi_blank_mode(struct mipi_dsim_device *dsim, int power)
 		if (client_drv && client_drv->power_on)
 			client_drv->power_on(client_dev, 1);
 
-		exynos_mipi_regulator_disable(dsim);
+		exynos_mipi_regulator_enable(dsim);
 
 		/* enable MIPI-DSI PHY. */
 		if (dsim->pd->phy_enable)
-- 
1.7.4.1

^ permalink raw reply related

* [GIT PULL] OMAP DSS for v3.6
From: Tomi Valkeinen @ 2012-07-22 18:13 UTC (permalink / raw)
  To: Florian Tobias Schandinat
  Cc: linux-omap, linux-fbdev, Tony Lindgren, Archit Taneja

[-- Attachment #1: Type: text/plain, Size: 6956 bytes --]

Hi Florian,

Here are OMAP DSS changes for 3.6. The main changes are:

- Patches from Archit, which reorganize the output side of omapdss. This
is much cleaner in itself, but will also help us in the future to
implement the missing omap4 features and omap5+ features.

- LCD3 patches from Chandrabhanu, which implement the support for LCD3
overlay manager (for omap5). His patches also generalize the code which
accesses the overlay manager related registers.

There hasn't been new patches applied to the DSS tree for 3 weeks, as
I'm on vacation. The tree has been in linux-next for that period, and I
haven't received any complaints so I hope the stuff works quite well.
Archit also reported that he has tested the linux-next, and it seems to
work fine.

There is a small conflict, though. This was caused by the two fixes
"OMAPDSS: fix warnings if CONFIG_PM_RUNTIME=n" and "OMAPDSS: Use PM
notifiers for system suspend", as I had already applied them into my
master branch before Archit sent them for you. And as you fixed the code
formatting issue (sorry about that), we have a small conflict there.

The conflict is trivial to resolve, and I also pushed for-florian-merged
branch to the same git tree below, which has the conflict resolved.

I'm still on vacation for the next week, but I'll check my email every
now and then to see if there are any issues.

 Tomi


The following changes since commit cfaf025112d3856637ff34a767ef785ef5cf2ca9:

  Linux 3.5-rc2 (2012-06-08 18:40:09 -0700)

are available in the git repository at:

  git://gitorious.org/linux-omap-dss2/linux.git for-florian

for you to fetch changes up to 974a65825e0b5fbda49605f0416a2c975d66e9e6:

  Merge "Apply LCD manager related parameters" from Archit (2012-06-29 14:13:07 +0300)

----------------------------------------------------------------

Archit Taneja (27):
      OMAPDSS: Remove passive matrix LCD support (part 1)
      OMAPDSS: Remove passive matrix LCD support (part 2)
      OMAPDSS: Remove passive matrix LCD support (part 3)
      OMAPDSS: Remove passive matrix LCD support (part 4)
      OMAPDSS: Add some new fields to omap_video_timings
      OMAPDSS: DISPLAY: Ignore newly added omap_video_timings fields for display timings sysfs file
      OMAPDSS: DISPC: Configure newly added omap_video_timing fields
      OMAPDSS: DISPC: Remove dispc_mgr_set_pol_freq()
      OMAPFB: Map the newly added omap_video_timings fields with fb sync flags
      OMAPDSS: Remove omap_panel_config enum from omap_dss_device
      OMAPDSS: Add interlace parameter to omap_video_timings
      OMAPDSS: DISPC/APPLY: Use interlace info in manager timings for dispc_ovl_setup()
      OMAPFB: Map interlace field in omap_video_timings with fb vmode flags
      OMAPDSS: HDMI: Remove custom hdmi_video_timings struct
      OMAPDSS: DSI: Fix HSYNC, VSYNC and DE polarities between DISPC and DSI
      OMAPDSS: DISPC: Change return type of dispc_mgr_set_clock_div()
      OMAPDSS: Add struct to hold LCD overlay manager configuration
      OMAPDSS: DPI: Configure dss_lcd_mgr_config struct with lcd manager parameters
      OMAPDSS: RFBI: Configure dss_lcd_mgr_config struct with lcd manager parameters
      OMAPDSS: DSI: Configure dss_lcd_mgr_config struct with lcd manager parameters
      OMAPDSS: SDI: Configure dss_lcd_mgr_config struct with lcd manager parameters
      OMAPDSS: APPLY: Remove DISPC writes to manager's lcd parameters in interface drivers
      OMAPDSS: MANAGER: Check LCD related overlay manager parameters
      OMAPDSS: APPLY: Remove usage of omap_dss_device from manual/auto update checks
      OMAPDSS: DISPC: Remove a redundant function
      OMAPDSS: RFBI: Use dss_mgr_enable to enable the overlay manager
      OMAPDSS: OVERLAY: Clean up replication checking

Chandrabhanu Mahapatra (5):
      OMAPDSS: Cleanup implementation of LCD channels
      OMAPDSS: Add support for LCD3 channel
      OMAPDSS: Add LCD3 overlay manager and Clock and IRQ support
      OMAPDSS: Add dump and debug support for LCD3
      ARM: OMAP2PLUS: DSS: Disable LCD3 output when resetting DSS

Jassi Brar (2):
      OMAPDSS: HDMI: Discard phy_tx_enabled member
      OMAPDSS: HDMI: Replace spinlock with mutex in hdmi_check_hpd_state

Peter Meerwald (1):
      OMAPDSS: fix specification spelling in Kconfig

Rajendra Nayak (1):
      OMAPDSS: add clk_prepare_enable and clk_disable_unprepare

Tomi Valkeinen (6):
      Merge tag 'v3.5-rc2'
      OMAPDSS: remove enum omap_dss_overlay_managers
      OMAPDSS: Use PM notifiers for system suspend
      OMAPDSS: fix warnings if CONFIG_PM_RUNTIME=n
      Merge Misc DSS clean ups from Archit
      Merge "Apply LCD manager related parameters" from Archit

 arch/arm/mach-omap2/display.c                      |   29 +-
 drivers/video/omap2/displays/panel-acx565akm.c     |   10 +-
 drivers/video/omap2/displays/panel-generic-dpi.c   |  179 ++++---
 .../omap2/displays/panel-lgphilips-lb035q02.c      |    8 +-
 drivers/video/omap2/displays/panel-n8x0.c          |    1 -
 .../omap2/displays/panel-nec-nl8048hl11-01b.c      |    9 +-
 drivers/video/omap2/displays/panel-picodlp.c       |    9 +-
 .../video/omap2/displays/panel-sharp-ls037v7dw01.c |    9 +-
 drivers/video/omap2/displays/panel-taal.c          |    3 +-
 drivers/video/omap2/displays/panel-tfp410.c        |    7 +-
 .../video/omap2/displays/panel-tpo-td043mtea1.c    |    8 +-
 drivers/video/omap2/dss/Kconfig                    |    4 +-
 drivers/video/omap2/dss/apply.c                    |   91 +++-
 drivers/video/omap2/dss/core.c                     |   48 +-
 drivers/video/omap2/dss/dispc.c                    |  496 ++++++++++----------
 drivers/video/omap2/dss/dispc.h                    |   28 ++
 drivers/video/omap2/dss/display.c                  |   40 +-
 drivers/video/omap2/dss/dpi.c                      |   64 +--
 drivers/video/omap2/dss/dsi.c                      |  156 +++---
 drivers/video/omap2/dss/dss.c                      |   21 +-
 drivers/video/omap2/dss/dss.h                      |   54 ++-
 drivers/video/omap2/dss/dss_features.h             |    5 +-
 drivers/video/omap2/dss/hdmi.c                     |  248 ++++++++--
 drivers/video/omap2/dss/hdmi_panel.c               |    9 +-
 drivers/video/omap2/dss/manager.c                  |   51 +-
 drivers/video/omap2/dss/overlay.c                  |   33 +-
 drivers/video/omap2/dss/rfbi.c                     |   42 +-
 drivers/video/omap2/dss/sdi.c                      |   42 +-
 drivers/video/omap2/dss/ti_hdmi.h                  |   21 +-
 drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c          |   26 +-
 drivers/video/omap2/dss/venc.c                     |   10 +-
 drivers/video/omap2/omapfb/omapfb-main.c           |   51 +-
 include/video/omapdss.h                            |   51 +-
 33 files changed, 1172 insertions(+), 691 deletions(-)


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: [PATCH] video: da8xx-fb: allow frame to complete before disabling LCDC
From: Florian Tobias Schandinat @ 2012-07-22 11:50 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1342799516-10842-1-git-send-email-prakash.pm@ti.com>

Hi,

On 07/20/2012 03:51 PM, Manjunathappa, Prakash wrote:
> Wait for active frame transfer to complete before disabling LCDC.
> At the same this wait is not be required when there are sync and
> underflow errors.
> 
> Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
> ---
>  drivers/video/da8xx-fb.c |   58 ++++++++++++++++++++++++++++++++++++---------
>  1 files changed, 46 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
> index 4440292..c178592 100644
> --- a/drivers/video/da8xx-fb.c
> +++ b/drivers/video/da8xx-fb.c
> @@ -31,6 +31,7 @@
>  #include <linux/cpufreq.h>
>  #include <linux/console.h>
>  #include <linux/slab.h>
> +#include <linux/delay.h>
>  #include <video/da8xx-fb.h>
>  #include <asm/div64.h>
>  
> @@ -45,6 +46,7 @@
>  #define LCD_PL_LOAD_DONE		BIT(6)
>  #define LCD_FIFO_UNDERFLOW		BIT(5)
>  #define LCD_SYNC_LOST			BIT(2)
> +#define LCD_FRAME_DONE			BIT(0)
>  
>  /* LCD DMA Control Register */
>  #define LCD_DMA_BURST_SIZE(x)		((x) << 4)
> @@ -129,6 +131,8 @@
>  #define RIGHT_MARGIN	64
>  #define UPPER_MARGIN	32
>  #define LOWER_MARGIN	32
> +#define WAIT_FOR_FRAME_DONE	true
> +#define NO_WAIT_FOR_FRAME_DONE	false

These defines look a bit strange. While I consider it acceptable, one
really should know the arguments of a function and hence it doesn't make
sense to add an extra abstraction to bool (in contrast to flags where
such defines are really helpful).

>  
>  static resource_size_t da8xx_fb_reg_base;
>  static struct resource *lcdc_regs;
> @@ -280,13 +284,39 @@ static inline void lcd_enable_raster(void)
>  }
>  
>  /* Disable the Raster Engine of the LCD Controller */
> -static inline void lcd_disable_raster(void)
> +static inline void lcd_disable_raster(bool wait_for_frame_done)
>  {
>  	u32 reg;
> +	u32 loop_cnt = 0;
> +	u32 stat;
> +	u32 i = 0;
> +
> +	/* 50 milli seconds should be sufficient for a frame to complete */
> +	if (wait_for_frame_done)
> +		loop_cnt = 50;
>  
>  	reg = lcdc_read(LCD_RASTER_CTRL_REG);
>  	if (reg & LCD_RASTER_ENABLE)
>  		lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
> +
> +	/* Wait for the current frame to complete */
> +	do {
> +		if (lcd_revision = LCD_VERSION_1)
> +			stat = lcdc_read(LCD_STAT_REG);
> +		else
> +			stat = lcdc_read(LCD_RAW_STAT_REG);
> +		mdelay(1);
> +	} while (!(stat & LCD_FRAME_DONE) && (i++ < loop_cnt));

I don't know the documentation of your hardware but this really looks
like you are waiting after you disabled it.

> +
> +	if (lcd_revision = LCD_VERSION_1)
> +		lcdc_write(stat, LCD_STAT_REG);
> +	else
> +		lcdc_write(stat, LCD_MASKED_STAT_REG);
> +
> +	if ((loop_cnt != 0) && (i >= loop_cnt)) {
> +		pr_err("LCD Controller timed out\n");
> +		return;
> +	}
>  }
>  
>  static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
> @@ -663,7 +693,7 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
>  static void lcd_reset(struct da8xx_fb_par *par)
>  {
>  	/* Disable the Raster if previously Enabled */
> -	lcd_disable_raster();
> +	lcd_disable_raster(NO_WAIT_FOR_FRAME_DONE);
>  
>  	/* DMA has to be disabled */
>  	lcdc_write(0, LCD_DMA_CTRL_REG);
> @@ -760,7 +790,8 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
>  	u32 reg_int;
>  
>  	if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
> -		lcd_disable_raster();
> +		pr_err("LCDC sync lost or underflow error occured\n");
> +		lcd_disable_raster(NO_WAIT_FOR_FRAME_DONE);
>  		lcdc_write(stat, LCD_MASKED_STAT_REG);
>  		lcd_enable_raster();
>  	} else if (stat & LCD_PL_LOAD_DONE) {
> @@ -770,7 +801,7 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
>  		 * interrupt via the following write to the status register. If
>  		 * this is done after then one gets multiple PL done interrupts.
>  		 */
> -		lcd_disable_raster();
> +		lcd_disable_raster(NO_WAIT_FOR_FRAME_DONE);
>  
>  		lcdc_write(stat, LCD_MASKED_STAT_REG);
>  
> @@ -815,7 +846,8 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
>  	u32 reg_ras;
>  
>  	if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
> -		lcd_disable_raster();
> +		pr_err("LCDC sync lost or underflow error occured\n");
> +		lcd_disable_raster(NO_WAIT_FOR_FRAME_DONE);
>  		lcdc_write(stat, LCD_STAT_REG);
>  		lcd_enable_raster();
>  	} else if (stat & LCD_PL_LOAD_DONE) {
> @@ -825,7 +857,7 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
>  		 * interrupt via the following write to the status register. If
>  		 * this is done after then one gets multiple PL done interrupts.
>  		 */
> -		lcd_disable_raster();
> +		lcd_disable_raster(NO_WAIT_FOR_FRAME_DONE);
>  
>  		lcdc_write(stat, LCD_STAT_REG);
>  
> @@ -945,7 +977,7 @@ static int lcd_da8xx_cpufreq_transition(struct notifier_block *nb,
>  	if (val = CPUFREQ_POSTCHANGE) {
>  		if (par->lcd_fck_rate != clk_get_rate(par->lcdc_clk)) {
>  			par->lcd_fck_rate = clk_get_rate(par->lcdc_clk);
> -			lcd_disable_raster();
> +			lcd_disable_raster(WAIT_FOR_FRAME_DONE);
>  			lcd_calc_clk_divider(par);
>  			lcd_enable_raster();
>  		}
> @@ -982,7 +1014,7 @@ static int __devexit fb_remove(struct platform_device *dev)
>  		if (par->panel_power_ctrl)
>  			par->panel_power_ctrl(0);
>  
> -		lcd_disable_raster();
> +		lcd_disable_raster(WAIT_FOR_FRAME_DONE);
>  		lcdc_write(0, LCD_RASTER_CTRL_REG);
>  
>  		/* disable DMA  */
> @@ -1095,7 +1127,7 @@ static int cfb_blank(int blank, struct fb_info *info)
>  		if (par->panel_power_ctrl)
>  			par->panel_power_ctrl(0);
>  
> -		lcd_disable_raster();
> +		lcd_disable_raster(WAIT_FOR_FRAME_DONE);
>  		break;
>  	default:
>  		ret = -EINVAL;
> @@ -1435,7 +1467,7 @@ static int fb_suspend(struct platform_device *dev, pm_message_t state)
>  		par->panel_power_ctrl(0);
>  
>  	fb_set_suspend(info, 1);
> -	lcd_disable_raster();
> +	lcd_disable_raster(WAIT_FOR_FRAME_DONE);
>  	clk_disable(par->lcdc_clk);
>  	console_unlock();
>  
> @@ -1447,11 +1479,13 @@ static int fb_resume(struct platform_device *dev)
>  	struct da8xx_fb_par *par = info->par;
>  
>  	console_lock();
> -	if (par->panel_power_ctrl)
> -		par->panel_power_ctrl(1);
>  
>  	clk_enable(par->lcdc_clk);
> +	usleep_range(1000, 2000);
>  	lcd_enable_raster();
> +	if (par->panel_power_ctrl)
> +		par->panel_power_ctrl(1);
> +

This change looks unrelated and should go in a separate patch?

>  	fb_set_suspend(info, 0);
>  	console_unlock();
>  


Best regards,

Florian Tobias Schandinat

^ permalink raw reply

* [PATCH] video: da8xx-fb: allow frame to complete before disabling LCDC
From: Manjunathappa, Prakash @ 2012-07-20 16:03 UTC (permalink / raw)
  To: linux-fbdev

Wait for active frame transfer to complete before disabling LCDC.
At the same this wait is not be required when there are sync and
underflow errors.

Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
---
 drivers/video/da8xx-fb.c |   58 ++++++++++++++++++++++++++++++++++++---------
 1 files changed, 46 insertions(+), 12 deletions(-)

diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 4440292..c178592 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -31,6 +31,7 @@
 #include <linux/cpufreq.h>
 #include <linux/console.h>
 #include <linux/slab.h>
+#include <linux/delay.h>
 #include <video/da8xx-fb.h>
 #include <asm/div64.h>
 
@@ -45,6 +46,7 @@
 #define LCD_PL_LOAD_DONE		BIT(6)
 #define LCD_FIFO_UNDERFLOW		BIT(5)
 #define LCD_SYNC_LOST			BIT(2)
+#define LCD_FRAME_DONE			BIT(0)
 
 /* LCD DMA Control Register */
 #define LCD_DMA_BURST_SIZE(x)		((x) << 4)
@@ -129,6 +131,8 @@
 #define RIGHT_MARGIN	64
 #define UPPER_MARGIN	32
 #define LOWER_MARGIN	32
+#define WAIT_FOR_FRAME_DONE	true
+#define NO_WAIT_FOR_FRAME_DONE	false
 
 static resource_size_t da8xx_fb_reg_base;
 static struct resource *lcdc_regs;
@@ -280,13 +284,39 @@ static inline void lcd_enable_raster(void)
 }
 
 /* Disable the Raster Engine of the LCD Controller */
-static inline void lcd_disable_raster(void)
+static inline void lcd_disable_raster(bool wait_for_frame_done)
 {
 	u32 reg;
+	u32 loop_cnt = 0;
+	u32 stat;
+	u32 i = 0;
+
+	/* 50 milli seconds should be sufficient for a frame to complete */
+	if (wait_for_frame_done)
+		loop_cnt = 50;
 
 	reg = lcdc_read(LCD_RASTER_CTRL_REG);
 	if (reg & LCD_RASTER_ENABLE)
 		lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
+
+	/* Wait for the current frame to complete */
+	do {
+		if (lcd_revision = LCD_VERSION_1)
+			stat = lcdc_read(LCD_STAT_REG);
+		else
+			stat = lcdc_read(LCD_RAW_STAT_REG);
+		mdelay(1);
+	} while (!(stat & LCD_FRAME_DONE) && (i++ < loop_cnt));
+
+	if (lcd_revision = LCD_VERSION_1)
+		lcdc_write(stat, LCD_STAT_REG);
+	else
+		lcdc_write(stat, LCD_MASKED_STAT_REG);
+
+	if ((loop_cnt != 0) && (i >= loop_cnt)) {
+		pr_err("LCD Controller timed out\n");
+		return;
+	}
 }
 
 static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
@@ -663,7 +693,7 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
 static void lcd_reset(struct da8xx_fb_par *par)
 {
 	/* Disable the Raster if previously Enabled */
-	lcd_disable_raster();
+	lcd_disable_raster(NO_WAIT_FOR_FRAME_DONE);
 
 	/* DMA has to be disabled */
 	lcdc_write(0, LCD_DMA_CTRL_REG);
@@ -760,7 +790,8 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
 	u32 reg_int;
 
 	if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
-		lcd_disable_raster();
+		pr_err("LCDC sync lost or underflow error occured\n");
+		lcd_disable_raster(NO_WAIT_FOR_FRAME_DONE);
 		lcdc_write(stat, LCD_MASKED_STAT_REG);
 		lcd_enable_raster();
 	} else if (stat & LCD_PL_LOAD_DONE) {
@@ -770,7 +801,7 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
 		 * interrupt via the following write to the status register. If
 		 * this is done after then one gets multiple PL done interrupts.
 		 */
-		lcd_disable_raster();
+		lcd_disable_raster(NO_WAIT_FOR_FRAME_DONE);
 
 		lcdc_write(stat, LCD_MASKED_STAT_REG);
 
@@ -815,7 +846,8 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
 	u32 reg_ras;
 
 	if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
-		lcd_disable_raster();
+		pr_err("LCDC sync lost or underflow error occured\n");
+		lcd_disable_raster(NO_WAIT_FOR_FRAME_DONE);
 		lcdc_write(stat, LCD_STAT_REG);
 		lcd_enable_raster();
 	} else if (stat & LCD_PL_LOAD_DONE) {
@@ -825,7 +857,7 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
 		 * interrupt via the following write to the status register. If
 		 * this is done after then one gets multiple PL done interrupts.
 		 */
-		lcd_disable_raster();
+		lcd_disable_raster(NO_WAIT_FOR_FRAME_DONE);
 
 		lcdc_write(stat, LCD_STAT_REG);
 
@@ -945,7 +977,7 @@ static int lcd_da8xx_cpufreq_transition(struct notifier_block *nb,
 	if (val = CPUFREQ_POSTCHANGE) {
 		if (par->lcd_fck_rate != clk_get_rate(par->lcdc_clk)) {
 			par->lcd_fck_rate = clk_get_rate(par->lcdc_clk);
-			lcd_disable_raster();
+			lcd_disable_raster(WAIT_FOR_FRAME_DONE);
 			lcd_calc_clk_divider(par);
 			lcd_enable_raster();
 		}
@@ -982,7 +1014,7 @@ static int __devexit fb_remove(struct platform_device *dev)
 		if (par->panel_power_ctrl)
 			par->panel_power_ctrl(0);
 
-		lcd_disable_raster();
+		lcd_disable_raster(WAIT_FOR_FRAME_DONE);
 		lcdc_write(0, LCD_RASTER_CTRL_REG);
 
 		/* disable DMA  */
@@ -1095,7 +1127,7 @@ static int cfb_blank(int blank, struct fb_info *info)
 		if (par->panel_power_ctrl)
 			par->panel_power_ctrl(0);
 
-		lcd_disable_raster();
+		lcd_disable_raster(WAIT_FOR_FRAME_DONE);
 		break;
 	default:
 		ret = -EINVAL;
@@ -1435,7 +1467,7 @@ static int fb_suspend(struct platform_device *dev, pm_message_t state)
 		par->panel_power_ctrl(0);
 
 	fb_set_suspend(info, 1);
-	lcd_disable_raster();
+	lcd_disable_raster(WAIT_FOR_FRAME_DONE);
 	clk_disable(par->lcdc_clk);
 	console_unlock();
 
@@ -1447,11 +1479,13 @@ static int fb_resume(struct platform_device *dev)
 	struct da8xx_fb_par *par = info->par;
 
 	console_lock();
-	if (par->panel_power_ctrl)
-		par->panel_power_ctrl(1);
 
 	clk_enable(par->lcdc_clk);
+	usleep_range(1000, 2000);
 	lcd_enable_raster();
+	if (par->panel_power_ctrl)
+		par->panel_power_ctrl(1);
+
 	fb_set_suspend(info, 0);
 	console_unlock();
 
-- 
1.7.1


^ permalink raw reply related

* [PATCH] video: da8xx-fb: do clock reset of revision 2 LCDC before enabling
From: Manjunathappa, Prakash @ 2012-07-20 16:03 UTC (permalink / raw)
  To: linux-fbdev

As in specification software reset should be applied for several
cycles before bringing it out of reset. Without this patch
particularly during suspend and resume clock reset is not guaranteed
to happen.

Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
---
 drivers/video/da8xx-fb.c |   12 ++++++++----
 1 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 3d2d0d1..4440292 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -262,10 +262,18 @@ static inline void lcd_enable_raster(void)
 {
 	u32 reg;
 
+	/* Put LCDC in reset for several cycles */
+	if (lcd_revision = LCD_VERSION_2)
+		/* Write 1 to reset LCDC */
+		lcdc_write(LCD_CLK_MAIN_RESET, LCD_CLK_RESET_REG);
+	mdelay(1);
+
 	/* Bring LCDC out of reset */
 	if (lcd_revision = LCD_VERSION_2)
 		lcdc_write(0, LCD_CLK_RESET_REG);
+	mdelay(1);
 
+	/* Above reset sequence doesnot reset register context */
 	reg = lcdc_read(LCD_RASTER_CTRL_REG);
 	if (!(reg & LCD_RASTER_ENABLE))
 		lcdc_write(reg | LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
@@ -279,10 +287,6 @@ static inline void lcd_disable_raster(void)
 	reg = lcdc_read(LCD_RASTER_CTRL_REG);
 	if (reg & LCD_RASTER_ENABLE)
 		lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
-
-	if (lcd_revision = LCD_VERSION_2)
-		/* Write 1 to reset LCDC */
-		lcdc_write(LCD_CLK_MAIN_RESET, LCD_CLK_RESET_REG);
 }
 
 static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
-- 
1.7.1


^ permalink raw reply related

* [PATCH] OMAPDSS: DPI: Get panel configuration from platform data
From: Jassi Brar @ 2012-07-20 15:42 UTC (permalink / raw)
  To: tomi.valkeinen, a0393947; +Cc: linux-omap, linux-fbdev, Jassi Brar

Instead of harcoding in the driver some of potentially countless sets
of parameters that could define a panel, have the board provide the
parameters to the panel driver.

Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
---
 arch/arm/mach-omap2/board-2430sdp.c              |    4 +-
 arch/arm/mach-omap2/board-am3517evm.c            |    5 +-
 arch/arm/mach-omap2/board-apollon.c              |    4 +-
 arch/arm/mach-omap2/board-cm-t35.c               |    5 +-
 arch/arm/mach-omap2/board-devkit8000.c           |    4 +-
 arch/arm/mach-omap2/board-h4.c                   |    3 +-
 arch/arm/mach-omap2/board-ldp.c                  |    4 +-
 arch/arm/mach-omap2/board-overo.c                |    4 +-
 drivers/video/omap2/displays/panel-generic-dpi.c |  467 +---------------------
 include/video/omap-panel-generic-dpi.h           |   15 +-
 10 files changed, 44 insertions(+), 471 deletions(-)

diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index 99ca6ba..0cc58c3 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -125,7 +125,9 @@ static void sdp2430_panel_disable_lcd(struct omap_dss_device *dssdev)
 }
 
 static struct panel_generic_dpi_data sdp2430_panel_data = {
-	.name			= "nec_nl2432dr22-11b",
+	.pcfg = {{240, 320, 5400, 3, 3, 39, 1, 2, 7,}, 0, 0,
+		(OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS),
+		0, 0,},
 	.platform_enable	= sdp2430_panel_enable_lcd,
 	.platform_disable	= sdp2430_panel_disable_lcd,
 };
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
index 18f6010..afd87b5 100644
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -176,7 +176,10 @@ static void am3517_evm_panel_disable_lcd(struct omap_dss_device *dssdev)
 }
 
 static struct panel_generic_dpi_data lcd_panel = {
-	.name			= "sharp_lq",
+	.pcfg = {{480, 272, 9000, 42, 3, 2, 11, 3, 2,}, 0, 0,
+		(OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
+			OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IEO),
+		50, 100,},
 	.platform_enable	= am3517_evm_panel_enable_lcd,
 	.platform_disable	= am3517_evm_panel_disable_lcd,
 };
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index 502c31e..e9c6f5a 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -261,7 +261,9 @@ static struct omap_usb_config apollon_usb_config __initdata = {
 };
 
 static struct panel_generic_dpi_data apollon_panel_data = {
-	.name			= "apollon",
+	.pcfg = {{480, 272, 6250, 41, 2, 2, 10, 2, 2,}, 0, 0,
+		(OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS),
+		0, 0,},
 };
 
 static struct omap_dss_device apollon_lcd_device = {
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index ded100c..f5a8ce4 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -228,7 +228,10 @@ static void cm_t35_panel_disable_tv(struct omap_dss_device *dssdev)
 }
 
 static struct panel_generic_dpi_data lcd_panel = {
-	.name			= "toppoly_tdo35s",
+	.pcfg = {{480, 640, 26000, 8, 104, 8, 2, 4, 2,}, 0, 0,
+		(OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS |
+			OMAP_DSS_LCD_IPC | OMAP_DSS_LCD_ONOFF),
+		0, 0,},
 	.platform_enable	= cm_t35_panel_enable_lcd,
 	.platform_disable	= cm_t35_panel_disable_lcd,
 };
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index 6567c1c..397f52d 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -128,7 +128,9 @@ static struct regulator_consumer_supply devkit8000_vio_supply[] = {
 };
 
 static struct panel_generic_dpi_data lcd_panel = {
-	.name			= "innolux_at070tn83",
+	.pcfg = {{800, 480, 40000, 48, 1, 1, 3, 12, 25,}, 0, 0x28,
+		(OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS),
+		0, 0,},
 	.platform_enable        = devkit8000_panel_enable_lcd,
 	.platform_disable       = devkit8000_panel_disable_lcd,
 };
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index 876becf..4f62bad 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -205,7 +205,8 @@ static struct platform_device *h4_devices[] __initdata = {
 };
 
 static struct panel_generic_dpi_data h4_panel_data = {
-	.name			= "h4",
+	.pcfg = {{240, 320, 6250, 15, 15, 60, 1, 1, 1,}, 0, 0,
+		OMAP_DSS_LCD_TFT, 0, 0,},
 };
 
 static struct omap_dss_device h4_lcd_device = {
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index ef9e829..de797920 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -210,7 +210,9 @@ static void ldp_panel_disable_lcd(struct omap_dss_device *dssdev)
 }
 
 static struct panel_generic_dpi_data ldp_panel_data = {
-	.name			= "nec_nl2432dr22-11b",
+	.pcfg = {{240, 320, 5400, 3, 3, 39, 1, 2, 7,}, 0, 0,
+		(OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS),
+		0, 0,},
 	.platform_enable	= ldp_panel_enable_lcd,
 	.platform_disable	= ldp_panel_disable_lcd,
 };
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 779734d..4f7a9fb5 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -208,7 +208,9 @@ static void overo_panel_disable_lcd(struct omap_dss_device *dssdev)
 }
 
 static struct panel_generic_dpi_data lcd43_panel = {
-	.name			= "samsung_lte430wq_f0c",
+	.pcfg = {{480, 272, 9200, 41, 8, 4, 10, 4, 2,}, 0, 0,
+		(OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS),
+		0, 0,},
 	.platform_enable	= overo_panel_enable_lcd,
 	.platform_disable	= overo_panel_disable_lcd,
 };
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index e42f9dc..6fa5e22 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -37,457 +37,6 @@
 
 #include <video/omap-panel-generic-dpi.h>
 
-struct panel_config {
-	struct omap_video_timings timings;
-
-	int acbi;	/* ac-bias pin transitions per interrupt */
-	/* Unit: line clocks */
-	int acb;	/* ac-bias pin frequency */
-
-	enum omap_panel_config config;
-
-	int power_on_delay;
-	int power_off_delay;
-
-	/*
-	 * Used to match device to panel configuration
-	 * when use generic panel driver
-	 */
-	const char *name;
-};
-
-/* Panel configurations */
-static struct panel_config generic_dpi_panels[] = {
-	/* Sharp LQ043T1DG01 */
-	{
-		{
-			.x_res		= 480,
-			.y_res		= 272,
-
-			.pixel_clock	= 9000,
-
-			.hsw		= 42,
-			.hfp		= 3,
-			.hbp		= 2,
-
-			.vsw		= 11,
-			.vfp		= 3,
-			.vbp		= 2,
-		},
-		.acbi			= 0x0,
-		.acb			= 0x0,
-		.config			= OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
-					OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IEO,
-		.power_on_delay		= 50,
-		.power_off_delay	= 100,
-		.name			= "sharp_lq",
-	},
-
-	/* Sharp LS037V7DW01 */
-	{
-		{
-			.x_res		= 480,
-			.y_res		= 640,
-
-			.pixel_clock	= 19200,
-
-			.hsw		= 2,
-			.hfp		= 1,
-			.hbp		= 28,
-
-			.vsw		= 1,
-			.vfp		= 1,
-			.vbp		= 1,
-		},
-		.acbi			= 0x0,
-		.acb			= 0x28,
-		.config			= OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
-						OMAP_DSS_LCD_IHS,
-		.power_on_delay		= 50,
-		.power_off_delay	= 100,
-		.name			= "sharp_ls",
-	},
-
-	/* Toppoly TDO35S */
-	{
-		{
-			.x_res		= 480,
-			.y_res		= 640,
-
-			.pixel_clock	= 26000,
-
-			.hfp		= 104,
-			.hsw		= 8,
-			.hbp		= 8,
-
-			.vfp		= 4,
-			.vsw		= 2,
-			.vbp		= 2,
-		},
-		.acbi			= 0x0,
-		.acb			= 0x0,
-		.config			= OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
-					OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC |
-					OMAP_DSS_LCD_ONOFF,
-		.power_on_delay		= 0,
-		.power_off_delay	= 0,
-		.name			= "toppoly_tdo35s",
-	},
-
-	/* Samsung LTE430WQ-F0C */
-	{
-		{
-			.x_res		= 480,
-			.y_res		= 272,
-
-			.pixel_clock	= 9200,
-
-			.hfp		= 8,
-			.hsw		= 41,
-			.hbp		= 45 - 41,
-
-			.vfp		= 4,
-			.vsw		= 10,
-			.vbp		= 12 - 10,
-		},
-		.acbi			= 0x0,
-		.acb			= 0x0,
-		.config			= OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
-						OMAP_DSS_LCD_IHS,
-		.power_on_delay		= 0,
-		.power_off_delay	= 0,
-		.name			= "samsung_lte430wq_f0c",
-	},
-
-	/* Seiko 70WVW1TZ3Z3 */
-	{
-		{
-			.x_res		= 800,
-			.y_res		= 480,
-
-			.pixel_clock	= 33000,
-
-			.hsw		= 128,
-			.hfp		= 10,
-			.hbp		= 10,
-
-			.vsw		= 2,
-			.vfp		= 4,
-			.vbp		= 11,
-		},
-		.acbi			= 0x0,
-		.acb			= 0x0,
-		.config			= OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
-						OMAP_DSS_LCD_IHS,
-		.power_on_delay		= 0,
-		.power_off_delay	= 0,
-		.name			= "seiko_70wvw1tz3",
-	},
-
-	/* Powertip PH480272T */
-	{
-		{
-			.x_res		= 480,
-			.y_res		= 272,
-
-			.pixel_clock	= 9000,
-
-			.hsw		= 40,
-			.hfp		= 2,
-			.hbp		= 2,
-
-			.vsw		= 10,
-			.vfp		= 2,
-			.vbp		= 2,
-		},
-		.acbi			= 0x0,
-		.acb			= 0x0,
-		.config			= OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
-					  OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IEO,
-		.power_on_delay		= 0,
-		.power_off_delay	= 0,
-		.name			= "powertip_ph480272t",
-	},
-
-	/* Innolux AT070TN83 */
-	{
-		{
-			.x_res		= 800,
-			.y_res		= 480,
-
-			.pixel_clock	= 40000,
-
-			.hsw		= 48,
-			.hfp		= 1,
-			.hbp		= 1,
-
-			.vsw		= 3,
-			.vfp		= 12,
-			.vbp		= 25,
-		},
-		.acbi			= 0x0,
-		.acb			= 0x28,
-		.config			= OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
-					  OMAP_DSS_LCD_IHS,
-		.power_on_delay		= 0,
-		.power_off_delay	= 0,
-		.name			= "innolux_at070tn83",
-	},
-
-	/* NEC NL2432DR22-11B */
-	{
-		{
-			.x_res		= 240,
-			.y_res		= 320,
-
-			.pixel_clock	= 5400,
-
-			.hsw		= 3,
-			.hfp		= 3,
-			.hbp		= 39,
-
-			.vsw		= 1,
-			.vfp		= 2,
-			.vbp		= 7,
-		},
-		.config			= OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
-						OMAP_DSS_LCD_IHS,
-		.name			= "nec_nl2432dr22-11b",
-	},
-
-	/* Unknown panel used in OMAP H4 */
-	{
-		{
-			.x_res		= 240,
-			.y_res		= 320,
-
-			.pixel_clock	= 6250,
-
-			.hsw		= 15,
-			.hfp		= 15,
-			.hbp		= 60,
-
-			.vsw		= 1,
-			.vfp		= 1,
-			.vbp		= 1,
-		},
-		.config			= OMAP_DSS_LCD_TFT,
-
-		.name			= "h4",
-	},
-
-	/* Unknown panel used in Samsung OMAP2 Apollon */
-	{
-		{
-			.x_res		= 480,
-			.y_res		= 272,
-
-			.pixel_clock	= 6250,
-
-			.hsw		= 41,
-			.hfp		= 2,
-			.hbp		= 2,
-
-			.vsw		= 10,
-			.vfp		= 2,
-			.vbp		= 2,
-		},
-		.config			= OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
-						OMAP_DSS_LCD_IHS,
-
-		.name			= "apollon",
-	},
-	/* FocalTech ETM070003DH6 */
-	{
-		{
-			.x_res		= 800,
-			.y_res		= 480,
-
-			.pixel_clock	= 28000,
-
-			.hsw		= 48,
-			.hfp		= 40,
-			.hbp		= 40,
-
-			.vsw		= 3,
-			.vfp		= 13,
-			.vbp		= 29,
-		},
-		.config			= OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
-					  OMAP_DSS_LCD_IHS,
-		.name			= "focaltech_etm070003dh6",
-	},
-
-	/* Microtips Technologies - UMSH-8173MD */
-	{
-		{
-			.x_res		= 800,
-			.y_res		= 480,
-
-			.pixel_clock	= 34560,
-
-			.hsw		= 13,
-			.hfp		= 101,
-			.hbp		= 101,
-
-			.vsw		= 23,
-			.vfp		= 1,
-			.vbp		= 1,
-		},
-		.acbi			= 0x0,
-		.acb			= 0x0,
-		.config			= OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
-					  OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC,
-		.power_on_delay		= 0,
-		.power_off_delay	= 0,
-		.name			= "microtips_umsh_8173md",
-	},
-
-	/* OrtusTech COM43H4M10XTC */
-	{
-		{
-			.x_res		= 480,
-			.y_res		= 272,
-
-			.pixel_clock	= 8000,
-
-			.hsw		= 41,
-			.hfp		= 8,
-			.hbp		= 4,
-
-			.vsw		= 10,
-			.vfp		= 4,
-			.vbp		= 2,
-		},
-		.config			= OMAP_DSS_LCD_TFT,
-
-		.name			= "ortustech_com43h4m10xtc",
-	},
-
-	/* Innolux AT080TN52 */
-	{
-		{
-			.x_res = 800,
-			.y_res = 600,
-
-			.pixel_clock	= 41142,
-
-			.hsw		= 20,
-			.hfp		= 210,
-			.hbp		= 46,
-
-			.vsw		= 10,
-			.vfp		= 12,
-			.vbp		= 23,
-		},
-		.acb			= 0x0,
-		.config			= OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
-					  OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IEO,
-
-		.name			= "innolux_at080tn52",
-	},
-
-	/* Mitsubishi AA084SB01 */
-	{
-		{
-			.x_res		= 800,
-			.y_res		= 600,
-			.pixel_clock	= 40000,
-
-			.hsw		= 1,
-			.hfp		= 254,
-			.hbp		= 1,
-
-			.vsw		= 1,
-			.vfp		= 26,
-			.vbp		= 1,
-		},
-		.config			= OMAP_DSS_LCD_TFT,
-		.name			= "mitsubishi_aa084sb01",
-	},
-	/* EDT ET0500G0DH6 */
-	{
-		{
-			.x_res		= 800,
-			.y_res		= 480,
-			.pixel_clock	= 33260,
-
-			.hsw		= 128,
-			.hfp		= 216,
-			.hbp		= 40,
-
-			.vsw		= 2,
-			.vfp		= 35,
-			.vbp		= 10,
-		},
-		.config			= OMAP_DSS_LCD_TFT,
-		.name			= "edt_et0500g0dh6",
-	},
-
-	/* Prime-View PD050VL1 */
-	{
-		{
-			.x_res		= 640,
-			.y_res		= 480,
-
-			.pixel_clock	= 25000,
-
-			.hsw		= 96,
-			.hfp		= 18,
-			.hbp		= 46,
-
-			.vsw		= 2,
-			.vfp		= 10,
-			.vbp		= 33,
-		},
-		.config			= OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
-					  OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC,
-		.name			= "primeview_pd050vl1",
-	},
-
-	/* Prime-View PM070WL4 */
-	{
-		{
-			.x_res		= 800,
-			.y_res		= 480,
-
-			.pixel_clock	= 32000,
-
-			.hsw		= 128,
-			.hfp		= 42,
-			.hbp		= 86,
-
-			.vsw		= 2,
-			.vfp		= 10,
-			.vbp		= 33,
-		},
-		.config			= OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
-					  OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC,
-		.name			= "primeview_pm070wl4",
-	},
-
-	/* Prime-View PD104SLF */
-	{
-		{
-			.x_res		= 800,
-			.y_res		= 600,
-
-			.pixel_clock	= 40000,
-
-			.hsw		= 128,
-			.hfp		= 42,
-			.hbp		= 86,
-
-			.vsw		= 4,
-			.vfp		= 1,
-			.vbp		= 23,
-		},
-		.config			= OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
-					  OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC,
-		.name			= "primeview_pd104slf",
-	},
-};
-
 struct panel_drv_data {
 
 	struct omap_dss_device *dssdev;
@@ -554,23 +103,17 @@ static void generic_dpi_panel_power_off(struct omap_dss_device *dssdev)
 static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
 {
 	struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev);
-	struct panel_config *panel_config = NULL;
 	struct panel_drv_data *drv_data = NULL;
-	int i;
+	struct panel_config *panel_config;
 
 	dev_dbg(&dssdev->dev, "probe\n");
 
-	if (!panel_data || !panel_data->name)
+	if (!panel_data)
 		return -EINVAL;
 
-	for (i = 0; i < ARRAY_SIZE(generic_dpi_panels); i++) {
-		if (strcmp(panel_data->name, generic_dpi_panels[i].name) = 0) {
-			panel_config = &generic_dpi_panels[i];
-			break;
-		}
-	}
-
-	if (!panel_config)
+	panel_config = &panel_data->pcfg;
+	/* Basic check for config availability */
+	if (!panel_config->timings.x_res)
 		return -EINVAL;
 
 	dssdev->panel.config = panel_config->config;
diff --git a/include/video/omap-panel-generic-dpi.h b/include/video/omap-panel-generic-dpi.h
index 127e3f2..ca5206f 100644
--- a/include/video/omap-panel-generic-dpi.h
+++ b/include/video/omap-panel-generic-dpi.h
@@ -22,6 +22,19 @@
 
 struct omap_dss_device;
 
+struct panel_config {
+	struct omap_video_timings timings;
+
+	int acbi;	/* ac-bias pin transitions per interrupt */
+	/* Unit: line clocks */
+	int acb;	/* ac-bias pin frequency */
+
+	enum omap_panel_config config;
+
+	int power_on_delay;
+	int power_off_delay;
+};
+
 /**
  * struct panel_generic_dpi_data - panel driver configuration data
  * @name: panel name
@@ -29,7 +42,7 @@ struct omap_dss_device;
  * @platform_disable: platform specific panel disable function
  */
 struct panel_generic_dpi_data {
-	const char *name;
+	struct panel_config pcfg;
 	int (*platform_enable)(struct omap_dss_device *dssdev);
 	void (*platform_disable)(struct omap_dss_device *dssdev);
 };
-- 
1.7.4.1


^ permalink raw reply related

* Re: [PATCH v2] da8xx-fb: add missing FB_BLANK operations
From: Yegor Yefremov @ 2012-07-20 12:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1341583288-30281-1-git-send-email-yegorslists@googlemail.com>

On Fri, Jul 6, 2012 at 4:01 PM,  <yegorslists@googlemail.com> wrote:
> From: Yegor Yefremov <yegorslists@googlemail.com>
>
> add FB_BLANK_NORMAL, FB_BLANK_VSYNC_SUSPEND and FB_BLANK_HSYNC_SUSPEND
> modes (copy drivers/video/omap2/omapfb/omapfb-main.c implementation).
> Otherwise X-server will complain about invalid parameter.
>
> Signed-off-by: Yegor Yefremov <yegorslists@googlemail.com>
> ---
> v2: add linux-fbdev as recipient
>
>  drivers/video/da8xx-fb.c |    3 +++
>  1 files changed, 3 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
> index 47118c7..8d745bf 100644
> --- a/drivers/video/da8xx-fb.c
> +++ b/drivers/video/da8xx-fb.c
> @@ -1026,6 +1026,9 @@ static int cfb_blank(int blank, struct fb_info *info)
>
>                 lcd_enable_raster();
>                 break;
> +       case FB_BLANK_NORMAL:
> +       case FB_BLANK_VSYNC_SUSPEND:
> +       case FB_BLANK_HSYNC_SUSPEND:
>         case FB_BLANK_POWERDOWN:
>                 if (par->panel_power_ctrl)
>                         par->panel_power_ctrl(0);
> --
> 1.7.7
>

Were is possible to get this patch into 3.6?

Thanks.

Yegor

^ permalink raw reply

* [PATCH] OMAPDSS: Do not require a VDDS_DSI regulator on am35xx
From: Raphael Assenat @ 2012-07-19 20:04 UTC (permalink / raw)
  To: linux-omap; +Cc: tomi.valkeinen, linux-fbdev

On our AM3505 based board, dpi.c complains that there is no VDSS_DSI regulator
and the framebuffer cannot be enabled. However, this check does not seem to
apply to AM3505/17 chips.

I am not the first facing this issue, see this thread from Nov. 2011:
http://marc.info/?l=linux-omap&m\x132147745930213&w=2

The string 'vdds_dsi' does appear once in the technical reference manual[1]
but there is no corresponding power pin on the package[2]. I failed to 
locate any signal that could be an equivalent. I am trying to obtain some
clarifications on TI's forum[3]...

In any case, I am currently running with the patch below. In order to keep
cpu_is_xx uses to a minimum, I check for am35xx once at init time and allow
dpi.vdds_dsi_reg to be NULL from then on, getting rid of all the other
cpu_is_omap34xx uses in the process.

Your comments would be appreciated. Please also consider for merging.

[1] http://www.ti.com/litv/pdf/sprugr0b
[2] http://www.ti.com/lit/gpn/am3505
[3] http://e2e.ti.com/support/dsp/sitara_arm174_microprocessors/f/416/t/202586.aspx

Signed-off-by: Raphael Assenat <raph@8d.com>

diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 8c2056c..d3b428d 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -180,11 +180,6 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 {
 	int r;
 
-	if (cpu_is_omap34xx() && !dpi.vdds_dsi_reg) {
-		DSSERR("no VDSS_DSI regulator\n");
-		return -ENODEV;
-	}
-
 	if (dssdev->manager = NULL) {
 		DSSERR("failed to enable display: no manager\n");
 		return -ENODEV;
@@ -196,7 +191,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 		goto err_start_dev;
 	}
 
-	if (cpu_is_omap34xx()) {
+	if (dpi.vdds_dsi_reg) {
 		r = regulator_enable(dpi.vdds_dsi_reg);
 		if (r)
 			goto err_reg_enable;
@@ -240,7 +235,7 @@ err_dsi_pll_init:
 err_get_dsi:
 	dispc_runtime_put();
 err_get_dispc:
-	if (cpu_is_omap34xx())
+	if (dpi.vdds_dsi_reg)
 		regulator_disable(dpi.vdds_dsi_reg);
 err_reg_enable:
 	omap_dss_stop_device(dssdev);
@@ -261,7 +256,7 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
 
 	dispc_runtime_put();
 
-	if (cpu_is_omap34xx())
+	if (dpi.vdds_dsi_reg)
 		regulator_disable(dpi.vdds_dsi_reg);
 
 	omap_dss_stop_device(dssdev);
@@ -343,7 +338,7 @@ static int __init dpi_init_display(struct omap_dss_device *dssdev)
 {
 	DSSDBG("init_display\n");
 
-	if (cpu_is_omap34xx() && dpi.vdds_dsi_reg = NULL) {
+	if (cpu_is_omap34xx() && dpi.vdds_dsi_reg = NULL && !soc_is_am35xx()) {
 		struct regulator *vdds_dsi;
 
 		vdds_dsi = dss_get_vdds_dsi();

^ permalink raw reply related

* [PATCH v3] video: da8xx-fb: add 24bpp LCD configuration support
From: Manjunathappa, Prakash @ 2012-07-19 15:49 UTC (permalink / raw)
  To: linux-fbdev

LCD controller on am335x supports 24bpp raster configuration in addition
to ones on da850. LCDC also supports 24bpp in unpacked format having
ARGB:8888 32bpp format data in DDR, but it doesn't interpret alpha
component of the data.

Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
Cc: Anatolij Gustschin <agust@denx.de>
---
Since v2:
Fixed additional configurations for 24bpp support.
Since v1:
Simplified calculation of pseudopalette for FB_VISUAL_TRUECOLOR type.

 drivers/video/da8xx-fb.c |  127 ++++++++++++++++++++++++++++++++++------------
 1 files changed, 94 insertions(+), 33 deletions(-)

diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 47118c7..3d2d0d1 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -83,6 +83,8 @@
 #define LCD_V2_LIDD_CLK_EN		BIT(1)
 #define LCD_V2_CORE_CLK_EN		BIT(0)
 #define LCD_V2_LPP_B10			26
+#define LCD_V2_TFT_24BPP_MODE		BIT(25)
+#define LCD_V2_TFT_24BPP_UNPACK		BIT(26)
 
 /* LCD Raster Timing 2 Register */
 #define LCD_AC_BIAS_TRANSITIONS_PER_INT(x)	((x) << 16)
@@ -153,7 +155,7 @@ struct da8xx_fb_par {
 	unsigned int		dma_end;
 	struct clk *lcdc_clk;
 	int irq;
-	unsigned short pseudo_palette[16];
+	unsigned long pseudo_palette[16];
 	unsigned int palette_sz;
 	unsigned int pxl_clk;
 	int blank;
@@ -482,6 +484,9 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
 {
 	u32 reg;
 
+	if ((bpp > 16) && (lcd_revision = LCD_VERSION_1))
+		return -EINVAL;
+
 	/* Set the Panel Width */
 	/* Pixels per line = (PPL + 1)*16 */
 	if (lcd_revision = LCD_VERSION_1) {
@@ -525,6 +530,12 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
 	reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(1 << 8);
 	if (raster_order)
 		reg |= LCD_RASTER_ORDER;
+
+	if (bpp = 24)
+		reg |= LCD_V2_TFT_24BPP_MODE;
+	else if (bpp = 32)
+		reg |= (LCD_V2_TFT_24BPP_MODE | LCD_V2_TFT_24BPP_UNPACK);
+
 	lcdc_write(reg, LCD_RASTER_CTRL_REG);
 
 	switch (bpp) {
@@ -532,6 +543,8 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
 	case 2:
 	case 4:
 	case 16:
+	case 24:
+	case 32:
 		par->palette_sz = 16 * 2;
 		break;
 
@@ -546,6 +559,8 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
 	return 0;
 }
 
+
+#define CNVT_TOHW(val, width) ((((val)<<(width))+0x7FFF-(val))>>16)
 static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
 			      unsigned blue, unsigned transp,
 			      struct fb_info *info)
@@ -561,13 +576,36 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
 	if (info->fix.visual = FB_VISUAL_DIRECTCOLOR)
 		return 1;
 
-	if (info->var.bits_per_pixel = 4) {
-		if (regno > 15)
-			return 1;
+	if ((info->var.bits_per_pixel > 16) && (lcd_revision = LCD_VERSION_1))
+		return 1;
 
-		if (info->var.grayscale) {
-			pal = regno;
-		} else {
+	switch (info->fix.visual) {
+	case FB_VISUAL_TRUECOLOR:
+		red = CNVT_TOHW(red, info->var.red.length);
+		green = CNVT_TOHW(green, info->var.green.length);
+		blue = CNVT_TOHW(blue, info->var.blue.length);
+		break;
+	case FB_VISUAL_PSEUDOCOLOR:
+		if (info->var.bits_per_pixel = 4) {
+			if (regno > 15)
+				return 1;
+
+			if (info->var.grayscale) {
+				pal = regno;
+			} else {
+				red >>= 4;
+				green >>= 8;
+				blue >>= 12;
+
+				pal = (red & 0x0f00);
+				pal |= (green & 0x00f0);
+				pal |= (blue & 0x000f);
+			}
+			if (regno = 0)
+				pal |= 0x2000;
+			palette[regno] = pal;
+
+		} else if (info->var.bits_per_pixel = 8) {
 			red >>= 4;
 			green >>= 8;
 			blue >>= 12;
@@ -575,36 +613,35 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
 			pal = (red & 0x0f00);
 			pal |= (green & 0x00f0);
 			pal |= (blue & 0x000f);
-		}
-		if (regno = 0)
-			pal |= 0x2000;
-		palette[regno] = pal;
-
-	} else if (info->var.bits_per_pixel = 8) {
-		red >>= 4;
-		green >>= 8;
-		blue >>= 12;
-
-		pal = (red & 0x0f00);
-		pal |= (green & 0x00f0);
-		pal |= (blue & 0x000f);
 
-		if (palette[regno] != pal) {
-			update_hw = 1;
-			palette[regno] = pal;
+			if (palette[regno] != pal) {
+				update_hw = 1;
+				palette[regno] = pal;
+			}
 		}
-	} else if ((info->var.bits_per_pixel = 16) && regno < 16) {
-		red >>= (16 - info->var.red.length);
-		red <<= info->var.red.offset;
+		break;
+	}
 
-		green >>= (16 - info->var.green.length);
-		green <<= info->var.green.offset;
+	/* Truecolor has hardware independent palette */
+	if (info->fix.visual = FB_VISUAL_TRUECOLOR) {
+		u32 v;
 
-		blue >>= (16 - info->var.blue.length);
-		blue <<= info->var.blue.offset;
+		if (regno > 15)
+			return -EINVAL;
 
-		par->pseudo_palette[regno] = red | green | blue;
+		v = (red << info->var.red.offset) |
+			(green << info->var.green.offset) |
+			(blue << info->var.blue.offset);
 
+		switch (info->var.bits_per_pixel) {
+		case 16:
+			((u16 *) (info->pseudo_palette))[regno] = v;
+			break;
+		case 24:
+		case 32:
+			((u32 *) (info->pseudo_palette))[regno] = v;
+			break;
+		}
 		if (palette[0] != 0x4000) {
 			update_hw = 1;
 			palette[0] = 0x4000;
@@ -617,6 +654,7 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
 
 	return 0;
 }
+#undef CNVT_TOHW
 
 static void lcd_reset(struct da8xx_fb_par *par)
 {
@@ -824,6 +862,9 @@ static int fb_check_var(struct fb_var_screeninfo *var,
 {
 	int err = 0;
 
+	if ((var->bits_per_pixel > 16) && (lcd_revision = LCD_VERSION_1))
+		return -EINVAL;
+
 	switch (var->bits_per_pixel) {
 	case 1:
 	case 8:
@@ -859,6 +900,26 @@ static int fb_check_var(struct fb_var_screeninfo *var,
 		var->transp.length = 0;
 		var->nonstd = 0;
 		break;
+	case 24:
+		var->red.offset = 16;
+		var->red.length = 8;
+		var->green.offset = 8;
+		var->green.length = 8;
+		var->blue.offset = 0;
+		var->blue.length = 8;
+		var->nonstd = 0;
+		break;
+	case 32:
+		var->transp.offset = 24;
+		var->transp.length = 8;
+		var->red.offset = 16;
+		var->red.length = 8;
+		var->green.offset = 8;
+		var->green.length = 8;
+		var->blue.offset = 0;
+		var->blue.length = 8;
+		var->nonstd = 0;
+		break;
 	default:
 		err = -EINVAL;
 	}
-- 
1.7.1


^ permalink raw reply related

* Re: [PATCH 7/9] fbdev: sh_mobile_lcdc: Support horizontal panning
From: Laurent Pinchart @ 2012-07-19 10:20 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1342658362-19491-8-git-send-email-laurent.pinchart@ideasonboard.com>

Hi Damian,

Thank you for the review.

On Thursday 19 July 2012 10:40:03 Damian Hobson-Garcia wrote:
> On 2012/07/19 9:39, Laurent Pinchart wrote:
> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > ---
> > 
> >  drivers/video/sh_mobile_lcdcfb.c |   22 ++++++++++++++++------
> >  1 files changed, 16 insertions(+), 6 deletions(-)
> > 
> > -	if (ovl->format->fourcc = V4L2_PIX_FMT_NV12 ||
> > -	    ovl->format->fourcc = V4L2_PIX_FMT_NV21)
> > +	switch (ovl->format->fourcc) {
> > +	case V4L2_PIX_FMT_NV16:
> > +	case V4L2_PIX_FMT_NV61:
> > +		info->fix.xpanstep = 2;
> > +	case V4L2_PIX_FMT_NV12:
> > +	case V4L2_PIX_FMT_NV21:
> >  		info->fix.ypanstep = 2;
> > +	}
> > 
> > 
> > -	if (ch->format->fourcc = V4L2_PIX_FMT_NV12 ||
> > -	    ch->format->fourcc = V4L2_PIX_FMT_NV21)
> > +	switch (ch->format->fourcc) {
> > +	case V4L2_PIX_FMT_NV16:
> > +	case V4L2_PIX_FMT_NV61:
> > +		info->fix.xpanstep = 2;
> > +	case V4L2_PIX_FMT_NV12:
> > +	case V4L2_PIX_FMT_NV21:
> >  		info->fix.ypanstep = 2;
> > +	}
> 
> I think that the panstep settings are backwards.  The pansteps should be
> NV16: x = 2, y = 1; NV12: x = 2, y = 2.

Good catch, thanks. I've fixed that.

-- 
Regards,

Laurent Pinchart


^ permalink raw reply

* Re: [PATCH] radeonfb: Add quirk for the graphics adapter in some JSxx
From: Tony Breeds @ 2012-07-19  5:48 UTC (permalink / raw)
  To: olaf; +Cc: linux-fbdev, linuxppc-dev
In-Reply-To: <1342630144-16350-1-git-send-email-olaf@aepfle.de>

[-- Attachment #1: Type: text/plain, Size: 534 bytes --]

On Wed, Jul 18, 2012 at 06:49:04PM +0200, olaf@aepfle.de wrote:

Thanks for following this up.

> From: Tony Breeds <tony@bakeyournoodle.com>
> 
> These devices are set to 640x480 by firmware, switch them to 800x600@60
> so that the graphical installer can run on remote console.
> 
> Reported by IBM during SLES10 SP2 beta testing:
> 
> https://bugzilla.novell.com/show_bug.cgi?id=461002
> LTC50817
> 
> Signed-off-by: Olaf Hering <olaf@aepfle.de>

Signed-off-by: Tony Breeds <tony@bakeyournoodle.com>

Yours Tony

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: [PATCH] radeonfb: Add quirk for the graphics adapter in some JSxx
From: Olaf Hering @ 2012-07-19  5:20 UTC (permalink / raw)
  To: Jingoo Han, 'Tony Breeds'; +Cc: linux-fbdev, linuxppc-dev
In-Reply-To: <001201cd656b$b2794350$176bc9f0$%han@samsung.com>

On Thu, Jul 19, Jingoo Han wrote:

> On Thursday, July 19, 2012 1:49 AM, olaf@aepfle.de wrote:
> > From: Tony Breeds <tony@bakeyournoodle.com>
> > 
> > These devices are set to 640x480 by firmware, switch them to 800x600@60
> > so that the graphical installer can run on remote console.
> > 
> > Reported by IBM during SLES10 SP2 beta testing:
> > 
> > https://bugzilla.novell.com/show_bug.cgi?idF1002
> > LTC50817
> > 
> > Signed-off-by: Olaf Hering <olaf@aepfle.de>
> 
> If the author is Tony Breeds, please add 'Signed-off-by: Tony Breeds <tony@bakeyournoodle.com>'.

He provided the initial version of the change, but did not add his tag
back in 2009. Tony, perhaps you can do that now?

Olaf

^ permalink raw reply

* RE: [PATCH RESEND] video: da8xx-fb: enable sync lost interrupt
From: Manjunathappa, Prakash @ 2012-07-19  5:19 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1342625417-6974-1-git-send-email-prakash.pm@ti.com>

Hi Sergei,

On Wed, Jul 18, 2012 at 21:26:32, Sergei Shtylyov wrote:
> Hello.
> 
> On 07/18/2012 07:30 PM, Manjunathappa, Prakash wrote:
> 
> > Patch enables sync lost interrupt and interrupt handler already
> > takes care to handle it.
> 
> > Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
> > ---
> > Resending as my earlier patch seems like not reached fbdev mailing list.
> 
> >  drivers/video/da8xx-fb.c |    5 +++--
> >  1 files changed, 3 insertions(+), 2 deletions(-)
> 
> > diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
> > index 88e98ea..e9d2f6e 100644
> > --- a/drivers/video/da8xx-fb.c
> > +++ b/drivers/video/da8xx-fb.c
> > @@ -54,6 +54,7 @@
> >  #define LCD_DMA_BURST_8			0x3
> >  #define LCD_DMA_BURST_16		0x4
> >  #define LCD_V1_END_OF_FRAME_INT_ENA	BIT(2)
> > +#define LCD_V1_SYNC_LOST_ENA            BIT(5)
> 
>    Please indent the value with tabs, as the others.
> 

Agree, I will replace with tabs.

Thanks,
Prakash

> >  #define LCD_V2_END_OF_FRAME0_INT_ENA	BIT(8)
> >  #define LCD_V2_END_OF_FRAME1_INT_ENA	BIT(9)
> >  #define LCD_DUAL_FRAME_BUFFER_ENABLE	BIT(0)
> 
> WBR, Sergei
> 


^ permalink raw reply

* RE: [PATCH] radeonfb: Add quirk for the graphics adapter in some JSxx
From: Jingoo Han @ 2012-07-19  5:02 UTC (permalink / raw)
  To: olaf, 'Benjamin Herrenschmidt'; +Cc: linuxppc-dev, linux-fbdev
In-Reply-To: <1342630144-16350-1-git-send-email-olaf@aepfle.de>

On Thursday, July 19, 2012 1:49 AM, olaf@aepfle.de wrote:
> From: Tony Breeds <tony@bakeyournoodle.com>
> 
> These devices are set to 640x480 by firmware, switch them to 800x600@60
> so that the graphical installer can run on remote console.
> 
> Reported by IBM during SLES10 SP2 beta testing:
> 
> https://bugzilla.novell.com/show_bug.cgi?idF1002
> LTC50817
> 
> Signed-off-by: Olaf Hering <olaf@aepfle.de>

If the author is Tony Breeds, please add 'Signed-off-by: Tony Breeds <tony@bakeyournoodle.com>'.

Best regards,
Jingoo Han

> 
> diff --git a/drivers/video/aty/radeon_monitor.c b/drivers/video/aty/radeon_monitor.c
> index 9261c91..5c23eac 100644
> --- a/drivers/video/aty/radeon_monitor.c
> +++ b/drivers/video/aty/radeon_monitor.c
> @@ -730,6 +730,25 @@ static void radeon_videomode_to_var(struct fb_var_screeninfo *var,
>  	var->vmode = mode->vmode;
>  }
> 
> +#ifdef CONFIG_PPC_PSERIES
> +static int is_powerblade(const char *model)
> +{
> +	struct device_node *root;
> +	const char* cp;
> +	int len, l, rc = 0;
> +
> +	root = of_find_node_by_path("/");
> +	if (root && model) {
> +		l = strlen(model);
> +		cp = of_get_property(root, "model", &len);
> +		if (cp)
> +			rc = memcmp(model, cp, min(len, l)) = 0;
> +		of_node_put(root);
> +	}
> +	return rc;
> +}
> +#endif
> +
>  /*
>   * Build the modedb for head 1 (head 2 will come later), check panel infos
>   * from either BIOS or EDID, and pick up the default mode
> @@ -865,6 +884,22 @@ void __devinit radeon_check_modes(struct radeonfb_info *rinfo, const char *mode_
>  			has_default_mode = 1;
>   	}
> 
> +#ifdef CONFIG_PPC_PSERIES
> +	if (!has_default_mode && (
> +		is_powerblade("IBM,8842") || /* JS20 */
> +		is_powerblade("IBM,8844") || /* JS21 */
> +		is_powerblade("IBM,7998") || /* JS12/JS21/JS22 */
> +		is_powerblade("IBM,0792") || /* QS21 */
> +		is_powerblade("IBM,0793")    /* QS22 */
> +	    )) {
> +		printk("Falling back to 800x600 on JSxx hardware\n");
> +		if (fb_find_mode(&info->var, info, "800x600@60",
> +				 info->monspecs.modedb,
> +				 info->monspecs.modedb_len, NULL, 8) != 0)
> +			has_default_mode = 1;
> +	}
> +#endif
> +
>  	/*
>  	 * Still no mode, let's pick up a default from the db
>  	 */
> --
> 1.7.10.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


^ permalink raw reply

* [PATCH] video: exynos_dp: adjust voltage swing and pre-emphasis during Link Training
From: Jingoo Han @ 2012-07-19  4:52 UTC (permalink / raw)
  To: linux-fbdev

This patch adds adjustement for voltage swing and pre-emphasis during
Link Training procedure. According to the DP specification, unless all
the LANEx_CR_DONE bits are set, the transmitter must read
the ADJUST_REQUEST_LANEx_x, increase the voltage swing according to
the request, and update the TRAINING_LANEx_SET bytes to match the new
voltage swing setting.

Refer to the DP specification v1.1a, Section 3.5.1.3 Link Training.

Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
 drivers/video/exynos/exynos_dp_core.c |  282 +++++++++++++++++----------------
 drivers/video/exynos/exynos_dp_core.h |    2 +-
 2 files changed, 144 insertions(+), 140 deletions(-)

diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index c6c016a..9c0140f 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -260,7 +260,7 @@ static void exynos_dp_set_lane_lane_pre_emphasis(struct exynos_dp_device *dp,
 
 static void exynos_dp_link_start(struct exynos_dp_device *dp)
 {
-	u8 buf[5];
+	u8 buf[4];
 	int lane;
 	int lane_count;
 
@@ -295,10 +295,10 @@ static void exynos_dp_link_start(struct exynos_dp_device *dp)
 	exynos_dp_set_training_pattern(dp, TRAINING_PTN1);
 
 	/* Set RX training pattern */
-	buf[0] = DPCD_SCRAMBLING_DISABLED |
-		 DPCD_TRAINING_PATTERN_1;
 	exynos_dp_write_byte_to_dpcd(dp,
-		DPCD_ADDR_TRAINING_PATTERN_SET, buf[0]);
+		DPCD_ADDR_TRAINING_PATTERN_SET,
+		DPCD_SCRAMBLING_DISABLED |
+		DPCD_TRAINING_PATTERN_1);
 
 	for (lane = 0; lane < lane_count; lane++)
 		buf[lane] = DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 |
@@ -308,7 +308,7 @@ static void exynos_dp_link_start(struct exynos_dp_device *dp)
 		lane_count, buf);
 }
 
-static unsigned char exynos_dp_get_lane_status(u8 link_status[6], int lane)
+static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int lane)
 {
 	int shift = (lane & 1) * 4;
 	u8 link_value = link_status[lane>>1];
@@ -316,7 +316,7 @@ static unsigned char exynos_dp_get_lane_status(u8 link_status[6], int lane)
 	return (link_value >> shift) & 0xf;
 }
 
-static int exynos_dp_clock_recovery_ok(u8 link_status[6], int lane_count)
+static int exynos_dp_clock_recovery_ok(u8 link_status[2], int lane_count)
 {
 	int lane;
 	u8 lane_status;
@@ -329,22 +329,23 @@ static int exynos_dp_clock_recovery_ok(u8 link_status[6], int lane_count)
 	return 0;
 }
 
-static int exynos_dp_channel_eq_ok(u8 link_status[6], int lane_count)
+static int exynos_dp_channel_eq_ok(u8 link_align[3], int lane_count)
 {
 	int lane;
 	u8 lane_align;
 	u8 lane_status;
 
-	lane_align = link_status[2];
+	lane_align = link_align[2];
 	if ((lane_align & DPCD_INTERLANE_ALIGN_DONE) = 0)
 		return -EINVAL;
 
 	for (lane = 0; lane < lane_count; lane++) {
-		lane_status = exynos_dp_get_lane_status(link_status, lane);
+		lane_status = exynos_dp_get_lane_status(link_align, lane);
 		lane_status &= DPCD_CHANNEL_EQ_BITS;
 		if (lane_status != DPCD_CHANNEL_EQ_BITS)
 			return -EINVAL;
 	}
+
 	return 0;
 }
 
@@ -417,69 +418,17 @@ static unsigned int exynos_dp_get_lane_link_training(
 
 static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp)
 {
-	if (dp->link_train.link_rate = LINK_RATE_2_70GBPS) {
-		/* set to reduced bit rate */
-		dp->link_train.link_rate = LINK_RATE_1_62GBPS;
-		dev_err(dp->dev, "set to bandwidth %.2x\n",
-			dp->link_train.link_rate);
-		dp->link_train.lt_state = START;
-	} else {
-		exynos_dp_training_pattern_dis(dp);
-		/* set enhanced mode if available */
-		exynos_dp_set_enhanced_mode(dp);
-		dp->link_train.lt_state = FAILED;
-	}
-}
-
-static void exynos_dp_get_adjust_train(struct exynos_dp_device *dp,
-				u8 adjust_request[2])
-{
-	int lane;
-	int lane_count;
-	u8 voltage_swing;
-	u8 pre_emphasis;
-	u8 training_lane;
+	exynos_dp_training_pattern_dis(dp);
+	exynos_dp_set_enhanced_mode(dp);
 
-	lane_count = dp->link_train.lane_count;
-	for (lane = 0; lane < lane_count; lane++) {
-		voltage_swing = exynos_dp_get_adjust_request_voltage(
-						adjust_request, lane);
-		pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
-						adjust_request, lane);
-		training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
-				DPCD_PRE_EMPHASIS_SET(pre_emphasis);
-
-		if (voltage_swing = VOLTAGE_LEVEL_3 ||
-		   pre_emphasis = PRE_EMPHASIS_LEVEL_3) {
-			training_lane |= DPCD_MAX_SWING_REACHED;
-			training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
-		}
-		dp->link_train.training_lane[lane] = training_lane;
-	}
-}
-
-static int exynos_dp_check_max_cr_loop(struct exynos_dp_device *dp,
-					u8 voltage_swing)
-{
-	int lane;
-	int lane_count;
-
-	lane_count = dp->link_train.lane_count;
-	for (lane = 0; lane < lane_count; lane++) {
-		if (voltage_swing = VOLTAGE_LEVEL_3 ||
-			dp->link_train.cr_loop[lane] = MAX_CR_LOOP)
-			return -EINVAL;
-	}
-	return 0;
+	dp->link_train.lt_state = FAILED;
 }
 
 static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
 {
-	u8 data;
-	u8 link_status[6];
+	u8 link_status[2];
 	int lane;
 	int lane_count;
-	u8 buf[5];
 
 	u8 adjust_request[2];
 	u8 voltage_swing;
@@ -488,98 +437,152 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
 
 	usleep_range(100, 101);
 
-	exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
-				6, link_status);
 	lane_count = dp->link_train.lane_count;
 
+	exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
+				2, link_status);
+
 	if (exynos_dp_clock_recovery_ok(link_status, lane_count) = 0) {
 		/* set training pattern 2 for EQ */
 		exynos_dp_set_training_pattern(dp, TRAINING_PTN2);
 
-		adjust_request[0] = link_status[4];
-		adjust_request[1] = link_status[5];
+		for (lane = 0; lane < lane_count; lane++) {
+			exynos_dp_read_bytes_from_dpcd(dp,
+					DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
+					2, adjust_request);
+			voltage_swing = exynos_dp_get_adjust_request_voltage(
+							adjust_request, lane);
+			pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
+							adjust_request, lane);
+			training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
+					DPCD_PRE_EMPHASIS_SET(pre_emphasis);
 
-		exynos_dp_get_adjust_train(dp, adjust_request);
+			if (voltage_swing = VOLTAGE_LEVEL_3)
+				training_lane |= DPCD_MAX_SWING_REACHED;
+			if (pre_emphasis = PRE_EMPHASIS_LEVEL_3)
+				training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
 
-		buf[0] = DPCD_SCRAMBLING_DISABLED |
-			 DPCD_TRAINING_PATTERN_2;
-		exynos_dp_write_byte_to_dpcd(dp,
-			DPCD_ADDR_TRAINING_PATTERN_SET,
-			buf[0]);
+			dp->link_train.training_lane[lane] = training_lane;
 
-		for (lane = 0; lane < lane_count; lane++) {
 			exynos_dp_set_lane_link_training(dp,
 				dp->link_train.training_lane[lane],
 				lane);
-			buf[lane] = dp->link_train.training_lane[lane];
-			exynos_dp_write_byte_to_dpcd(dp,
-				DPCD_ADDR_TRAINING_LANE0_SET + lane,
-				buf[lane]);
 		}
-		dp->link_train.lt_state = EQUALIZER_TRAINING;
-	} else {
-		exynos_dp_read_byte_from_dpcd(dp,
-			DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
-			&data);
-		adjust_request[0] = data;
 
-		exynos_dp_read_byte_from_dpcd(dp,
-			DPCD_ADDR_ADJUST_REQUEST_LANE2_3,
-			&data);
-		adjust_request[1] = data;
+		exynos_dp_write_byte_to_dpcd(dp,
+			DPCD_ADDR_TRAINING_PATTERN_SET,
+			DPCD_SCRAMBLING_DISABLED |
+			DPCD_TRAINING_PATTERN_2);
+
+		exynos_dp_write_bytes_to_dpcd(dp,
+			DPCD_ADDR_TRAINING_LANE0_SET,
+			lane_count,
+			dp->link_train.training_lane);
 
+		dev_info(dp->dev, "Link Training Clock Recovery success\n");
+		dp->link_train.lt_state = EQUALIZER_TRAINING;
+	} else {
 		for (lane = 0; lane < lane_count; lane++) {
 			training_lane = exynos_dp_get_lane_link_training(
 							dp, lane);
+			exynos_dp_read_bytes_from_dpcd(dp,
+					DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
+					2, adjust_request);
 			voltage_swing = exynos_dp_get_adjust_request_voltage(
 							adjust_request, lane);
 			pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
 							adjust_request, lane);
-			if ((DPCD_VOLTAGE_SWING_GET(training_lane) = voltage_swing) &&
-			    (DPCD_PRE_EMPHASIS_GET(training_lane) = pre_emphasis))
-				dp->link_train.cr_loop[lane]++;
-			dp->link_train.training_lane[lane] = training_lane;
-		}
 
-		if (exynos_dp_check_max_cr_loop(dp, voltage_swing) != 0) {
-			exynos_dp_reduce_link_rate(dp);
-		} else {
-			exynos_dp_get_adjust_train(dp, adjust_request);
+			if (voltage_swing = VOLTAGE_LEVEL_3 ||
+			    pre_emphasis = PRE_EMPHASIS_LEVEL_3) {
+				dev_err(dp->dev, "voltage or pre emphasis reached max level\n");
+				goto reduce_link_rate;
+			}
 
-			for (lane = 0; lane < lane_count; lane++) {
-				exynos_dp_set_lane_link_training(dp,
-					dp->link_train.training_lane[lane],
-					lane);
-				buf[lane] = dp->link_train.training_lane[lane];
-				exynos_dp_write_byte_to_dpcd(dp,
-					DPCD_ADDR_TRAINING_LANE0_SET + lane,
-					buf[lane]);
+			if ((DPCD_VOLTAGE_SWING_GET(training_lane) =
+					voltage_swing) &&
+			   (DPCD_PRE_EMPHASIS_GET(training_lane) =
+					pre_emphasis)) {
+				dp->link_train.cr_loop[lane]++;
+				if (dp->link_train.cr_loop[lane] = MAX_CR_LOOP) {
+					dev_err(dp->dev, "CR Max loop\n");
+					goto reduce_link_rate;
+				}
 			}
+
+			training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
+					DPCD_PRE_EMPHASIS_SET(pre_emphasis);
+
+			if (voltage_swing = VOLTAGE_LEVEL_3)
+				training_lane |= DPCD_MAX_SWING_REACHED;
+			if (pre_emphasis = PRE_EMPHASIS_LEVEL_3)
+				training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
+
+			dp->link_train.training_lane[lane] = training_lane;
+
+			exynos_dp_set_lane_link_training(dp,
+				dp->link_train.training_lane[lane], lane);
 		}
+
+		exynos_dp_write_bytes_to_dpcd(dp,
+			DPCD_ADDR_TRAINING_LANE0_SET,
+			lane_count,
+			dp->link_train.training_lane);
 	}
 
 	return 0;
+
+reduce_link_rate:
+	exynos_dp_reduce_link_rate(dp);
+	return -EIO;
 }
 
 static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
 {
-	u8 link_status[6];
+	u8 link_status[2];
+	u8 link_align[3];
 	int lane;
 	int lane_count;
-	u8 buf[5];
 	u32 reg;
 
 	u8 adjust_request[2];
+	u8 voltage_swing;
+	u8 pre_emphasis;
+	u8 training_lane;
 
 	usleep_range(400, 401);
 
-	exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
-				6, link_status);
 	lane_count = dp->link_train.lane_count;
 
+	exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
+				2, link_status);
+
 	if (exynos_dp_clock_recovery_ok(link_status, lane_count) = 0) {
-		adjust_request[0] = link_status[4];
-		adjust_request[1] = link_status[5];
+		link_align[0] = link_status[0];
+		link_align[1] = link_status[1];
+
+		exynos_dp_read_byte_from_dpcd(dp,
+			DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED,
+			&link_align[2]);
+
+		for (lane = 0; lane < lane_count; lane++) {
+			exynos_dp_read_bytes_from_dpcd(dp,
+					DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
+					2, adjust_request);
+			voltage_swing = exynos_dp_get_adjust_request_voltage(
+							adjust_request, lane);
+			pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
+							adjust_request, lane);
+			training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
+					DPCD_PRE_EMPHASIS_SET(pre_emphasis);
+
+			if (voltage_swing = VOLTAGE_LEVEL_3)
+				training_lane |= DPCD_MAX_SWING_REACHED;
+			if (pre_emphasis = PRE_EMPHASIS_LEVEL_3)
+				training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
+
+			dp->link_train.training_lane[lane] = training_lane;
+		}
 
 		if (exynos_dp_channel_eq_ok(link_status, lane_count) = 0) {
 			/* traing pattern Set to Normal */
@@ -596,39 +599,42 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
 			dp->link_train.lane_count = reg;
 			dev_dbg(dp->dev, "final lane count = %.2x\n",
 				dp->link_train.lane_count);
+
 			/* set enhanced mode if available */
 			exynos_dp_set_enhanced_mode(dp);
-
 			dp->link_train.lt_state = FINISHED;
 		} else {
 			/* not all locked */
 			dp->link_train.eq_loop++;
 
 			if (dp->link_train.eq_loop > MAX_EQ_LOOP) {
-				exynos_dp_reduce_link_rate(dp);
-			} else {
-				exynos_dp_get_adjust_train(dp, adjust_request);
-
-				for (lane = 0; lane < lane_count; lane++) {
-					exynos_dp_set_lane_link_training(dp,
-						dp->link_train.training_lane[lane],
-						lane);
-					buf[lane] = dp->link_train.training_lane[lane];
-					exynos_dp_write_byte_to_dpcd(dp,
-						DPCD_ADDR_TRAINING_LANE0_SET + lane,
-						buf[lane]);
-				}
+				dev_err(dp->dev, "EQ Max loop\n");
+				goto reduce_link_rate;
 			}
+
+			for (lane = 0; lane < lane_count; lane++)
+				exynos_dp_set_lane_link_training(dp,
+					dp->link_train.training_lane[lane],
+					lane);
+
+			exynos_dp_write_bytes_to_dpcd(dp,
+				DPCD_ADDR_TRAINING_LANE0_SET,
+				lane_count,
+				dp->link_train.training_lane);
 		}
 	} else {
-		exynos_dp_reduce_link_rate(dp);
+		goto reduce_link_rate;
 	}
 
 	return 0;
+
+reduce_link_rate:
+	exynos_dp_reduce_link_rate(dp);
+	return -EIO;
 }
 
 static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
-			u8 *bandwidth)
+					u8 *bandwidth)
 {
 	u8 data;
 
@@ -641,7 +647,7 @@ static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
 }
 
 static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp,
-			u8 *lane_count)
+					u8 *lane_count)
 {
 	u8 data;
 
@@ -693,13 +699,7 @@ static void exynos_dp_init_training(struct exynos_dp_device *dp,
 static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
 {
 	int retval = 0;
-	int training_finished;
-
-	/* Turn off unnecessary lane */
-	if (dp->link_train.lane_count = 1)
-		exynos_dp_set_analog_power_down(dp, CH1_BLOCK, 1);
-
-	training_finished = 0;
+	int training_finished = 0;
 
 	dp->link_train.lt_state = START;
 
@@ -710,10 +710,14 @@ static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
 			exynos_dp_link_start(dp);
 			break;
 		case CLOCK_RECOVERY:
-			exynos_dp_process_clock_recovery(dp);
+			retval = exynos_dp_process_clock_recovery(dp);
+			if (retval)
+				dev_err(dp->dev, "LT CR failed!\n");
 			break;
 		case EQUALIZER_TRAINING:
-			exynos_dp_process_equalizer_training(dp);
+			retval = exynos_dp_process_equalizer_training(dp);
+			if (retval)
+				dev_err(dp->dev, "LT EQ failed!\n");
 			break;
 		case FINISHED:
 			training_finished = 1;
diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h
index 8526e54..44c11e1 100644
--- a/drivers/video/exynos/exynos_dp_core.h
+++ b/drivers/video/exynos/exynos_dp_core.h
@@ -144,7 +144,7 @@ void exynos_dp_disable_scrambling(struct exynos_dp_device *dp);
 #define DPCD_ADDR_TRAINING_PATTERN_SET		0x0102
 #define DPCD_ADDR_TRAINING_LANE0_SET		0x0103
 #define DPCD_ADDR_LANE0_1_STATUS		0x0202
-#define DPCD_ADDR_LANE_ALIGN__STATUS_UPDATED	0x0204
+#define DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED	0x0204
 #define DPCD_ADDR_ADJUST_REQUEST_LANE0_1	0x0206
 #define DPCD_ADDR_ADJUST_REQUEST_LANE2_3	0x0207
 #define DPCD_ADDR_TEST_REQUEST			0x0218
-- 
1.7.1



^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox