linux-omap.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 0/3] OMAP: DSS2: Fix for DISPC core functional clock divider
@ 2011-03-03  9:55 Raghuveer Murthy
  2011-03-03  9:55 ` [PATCH v1 1/3] OMAP: DSS2: Adding dss_features for independent core clk divider Raghuveer Murthy
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Raghuveer Murthy @ 2011-03-03  9:55 UTC (permalink / raw)
  To: tomba; +Cc: linux-omap

OMAP4 has 2 LCD channels and corresponding DISPC_DIVISOR1 and DISPC_DIVISOR2
registers to configure the pixel clock frequency, for the respective LCD 
displays.

There is also DISPC_DIVISOR register, which by default has the ENABLE bit 
set to zero, for backward compatibility mode. Hence the logical clock divider of
DISPC_DIVISOR1.LCD, gets used for core func clk configuration. The default value
of DISPC_DIVISOR1.LCD is 4.

If only the secondary LCD is enabled, at high pixel resolutions the core clk 
lags behind the pixel clock, causing stair-step effect (diagonal lines with
tearing) on the display.

Hence DISPC_DIVISOR.ENABLE is set to 1, and the core functional clock is set 
independently and exclusively in DISPC_DIVISOR.LCD.

- Added the above as dss_features

-----------------------------------------------------
History
-------
Changes from previous version (v1)
- Fixed comments from Tomi Valkeinen <tomi.valkeinen@ti.com>

Base
----
url = git://gitorious.org/linux-omap-dss2/linux.git
branch "master"
commit 1e0f79f1066aba3cfcaa45a0298bb24ba7bf864d 

-----------------------------------------------------
Raghuveer Murthy (3):
  OMAP: DSS2: Adding dss_features for independent core clk divider
  OMAP: DSS2: Renaming register macro DISPC_DIVISOR(ch)
  OMAP4: DSS2: Using dss_features to set independent core clock divider

 drivers/video/omap2/dss/dispc.c        |   51 +++++++++++++++++++++++--------
 drivers/video/omap2/dss/dss_features.c |    2 +-
 drivers/video/omap2/dss/dss_features.h |    2 +
 3 files changed, 41 insertions(+), 14 deletions(-)


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v1 1/3] OMAP: DSS2: Adding dss_features for independent core clk divider
  2011-03-03  9:55 [PATCH v1 0/3] OMAP: DSS2: Fix for DISPC core functional clock divider Raghuveer Murthy
@ 2011-03-03  9:55 ` Raghuveer Murthy
  2011-03-03  9:55 ` [PATCH v1 2/3] OMAP: DSS2: Renaming register macro DISPC_DIVISOR(ch) Raghuveer Murthy
  2011-03-03  9:55 ` [PATCH v1 3/3] OMAP4: DSS2: Using dss_features to set independent core clock divider Raghuveer Murthy
  2 siblings, 0 replies; 4+ messages in thread
From: Raghuveer Murthy @ 2011-03-03  9:55 UTC (permalink / raw)
  To: tomba; +Cc: linux-omap

In OMAP3xxx DISPC_DIVISOR register has a logical clock divisor (lcd_div)
field. The lcd_div is common, for deciding the DISPC core functional clock
frequency, and the final pixel clock frequency for LCD display.

In OMAP4, there are 2 LCD channels, hence two divisor registers, DISPC_DIVISOR1
and DISPC_DIVISOR2. Also, there is a third register DISPC_DIVISOR.

The DISPC_DIVISOR in OMAP4 is used to configure lcd_div exclusively for core
functional clock configuration. For pixel clock configuration of primary and
secondary LCDs, lcd_div of DISPC_DIVISOR1 and DISPC_DIVISOR2 are used
respectively

Signed-off-by: Archit Taneja <archit@ti.com>
Signed-off-by: Raghuveer Murthy <raghuveer.murthy@ti.com>
---
 drivers/video/omap2/dss/dss_features.c |    2 +-
 drivers/video/omap2/dss/dss_features.h |    2 ++
 2 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index fe22d11..82a4ac3 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -195,7 +195,7 @@ static struct omap_dss_features omap4_dss_features = {
 
 	.has_feature	=
 		FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA |
-		FEAT_MGR_LCD2,
+		FEAT_MGR_LCD2 | FEAT_CORE_CLK_DIV,
 
 	.num_mgrs = 3,
 	.num_ovls = 3,
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index b9c70be..24fcef5 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -33,6 +33,8 @@ enum dss_feat_id {
 	FEAT_PCKFREEENABLE	= 1 << 5,
 	FEAT_FUNCGATED		= 1 << 6,
 	FEAT_MGR_LCD2		= 1 << 7,
+	/* Independent core clk divider */
+	FEAT_CORE_CLK_DIV	= 1 << 8,
 };
 
 /* DSS register field id */
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v1 2/3] OMAP: DSS2: Renaming register macro DISPC_DIVISOR(ch)
  2011-03-03  9:55 [PATCH v1 0/3] OMAP: DSS2: Fix for DISPC core functional clock divider Raghuveer Murthy
  2011-03-03  9:55 ` [PATCH v1 1/3] OMAP: DSS2: Adding dss_features for independent core clk divider Raghuveer Murthy
@ 2011-03-03  9:55 ` Raghuveer Murthy
  2011-03-03  9:55 ` [PATCH v1 3/3] OMAP4: DSS2: Using dss_features to set independent core clock divider Raghuveer Murthy
  2 siblings, 0 replies; 4+ messages in thread
From: Raghuveer Murthy @ 2011-03-03  9:55 UTC (permalink / raw)
  To: tomba; +Cc: linux-omap

The OMAP4 DISPC_DIVISOR1 is backward compatible to OMAP3xxx DISPC_DIVISOR.
However DISPC_DIVISOR is also provided in OMAP4, to control DISPC_CORE_CLK
independent of Primary and Secondary display clocks.

Renamed DISPC_DIVISOR(ch) to DISPC_DIVISORo(ch), to facilitate introduction
of DISPC_DIVISOR register, which is specific for OMAP4. OMAP4 has 3 registers
DISPC_DIVISOR, DISPC_DIVISOR1 and DISPC_DIVISOR2.

Also updated, all the usages of DISPC_DIVISOR(ch) to DISPC_DIVISORo(ch).
Use DISPC_DIVISORo(ch) when DISPC_DIVISOR1 or DISPC_DIVISOR2 has to be
configured

OMAP4 TRM uses DISPC_DIVISORo generically to refer to DISPC_DIVISOR1 and
DISPC_DIVISOR2

Signed-off-by: Raghuveer Murthy <raghuveer.murthy@ti.com>
---
 drivers/video/omap2/dss/dispc.c |   27 ++++++++++++++-------------
 1 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 43f7091..11b2b04 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -73,7 +73,7 @@ struct dispc_reg { u16 idx; };
 #define DISPC_TIMING_H(ch)		DISPC_REG(ch != 2 ? 0x0064 : 0x0400)
 #define DISPC_TIMING_V(ch)		DISPC_REG(ch != 2 ? 0x0068 : 0x0404)
 #define DISPC_POL_FREQ(ch)		DISPC_REG(ch != 2 ? 0x006C : 0x0408)
-#define DISPC_DIVISOR(ch)		DISPC_REG(ch != 2 ? 0x0070 : 0x040C)
+#define DISPC_DIVISORo(ch)		DISPC_REG(ch != 2 ? 0x0070 : 0x040C)
 #define DISPC_GLOBAL_ALPHA		DISPC_REG(0x0074)
 #define DISPC_SIZE_DIG			DISPC_REG(0x0078)
 #define DISPC_SIZE_LCD(ch)		DISPC_REG(ch != 2 ? 0x007C : 0x03CC)
@@ -128,6 +128,7 @@ struct dispc_reg { u16 idx; };
 
 #define DISPC_VID_PRELOAD(n)		DISPC_REG(0x230 + (n)*0x04)
 
+#define DISPC_DIVISOR			DISPC_REG(0x0804)
 
 #define DISPC_IRQ_MASK_ERROR            (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \
 					 DISPC_IRQ_OCP_ERR | \
@@ -231,7 +232,7 @@ void dispc_save_context(void)
 	SR(TIMING_H(0));
 	SR(TIMING_V(0));
 	SR(POL_FREQ(0));
-	SR(DIVISOR(0));
+	SR(DIVISORo(0));
 	SR(GLOBAL_ALPHA);
 	SR(SIZE_DIG);
 	SR(SIZE_LCD(0));
@@ -243,7 +244,7 @@ void dispc_save_context(void)
 		SR(TIMING_H(2));
 		SR(TIMING_V(2));
 		SR(POL_FREQ(2));
-		SR(DIVISOR(2));
+		SR(DIVISORo(2));
 		SR(CONFIG2);
 	}
 
@@ -390,7 +391,7 @@ void dispc_restore_context(void)
 	RR(TIMING_H(0));
 	RR(TIMING_V(0));
 	RR(POL_FREQ(0));
-	RR(DIVISOR(0));
+	RR(DIVISORo(0));
 	RR(GLOBAL_ALPHA);
 	RR(SIZE_DIG);
 	RR(SIZE_LCD(0));
@@ -401,7 +402,7 @@ void dispc_restore_context(void)
 		RR(TIMING_H(2));
 		RR(TIMING_V(2));
 		RR(POL_FREQ(2));
-		RR(DIVISOR(2));
+		RR(DIVISORo(2));
 		RR(CONFIG2);
 	}
 
@@ -2294,7 +2295,7 @@ static void dispc_set_lcd_divisor(enum omap_channel channel, u16 lck_div,
 	BUG_ON(pck_div < 2);
 
 	enable_clocks(1);
-	dispc_write_reg(DISPC_DIVISOR(channel),
+	dispc_write_reg(DISPC_DIVISORo(channel),
 			FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0));
 	enable_clocks(0);
 }
@@ -2303,7 +2304,7 @@ static void dispc_get_lcd_divisor(enum omap_channel channel, int *lck_div,
 		int *pck_div)
 {
 	u32 l;
-	l = dispc_read_reg(DISPC_DIVISOR(channel));
+	l = dispc_read_reg(DISPC_DIVISORo(channel));
 	*lck_div = FLD_GET(l, 23, 16);
 	*pck_div = FLD_GET(l, 7, 0);
 }
@@ -2329,7 +2330,7 @@ unsigned long dispc_lclk_rate(enum omap_channel channel)
 	unsigned long r;
 	u32 l;
 
-	l = dispc_read_reg(DISPC_DIVISOR(channel));
+	l = dispc_read_reg(DISPC_DIVISORo(channel));
 
 	lcd = FLD_GET(l, 23, 16);
 
@@ -2344,7 +2345,7 @@ unsigned long dispc_pclk_rate(enum omap_channel channel)
 	unsigned long r;
 	u32 l;
 
-	l = dispc_read_reg(DISPC_DIVISOR(channel));
+	l = dispc_read_reg(DISPC_DIVISORo(channel));
 
 	lcd = FLD_GET(l, 23, 16);
 	pcd = FLD_GET(l, 7, 0);
@@ -2460,7 +2461,7 @@ void dispc_dump_regs(struct seq_file *s)
 	DUMPREG(DISPC_TIMING_H(0));
 	DUMPREG(DISPC_TIMING_V(0));
 	DUMPREG(DISPC_POL_FREQ(0));
-	DUMPREG(DISPC_DIVISOR(0));
+	DUMPREG(DISPC_DIVISORo(0));
 	DUMPREG(DISPC_GLOBAL_ALPHA);
 	DUMPREG(DISPC_SIZE_DIG);
 	DUMPREG(DISPC_SIZE_LCD(0));
@@ -2472,7 +2473,7 @@ void dispc_dump_regs(struct seq_file *s)
 		DUMPREG(DISPC_TIMING_H(2));
 		DUMPREG(DISPC_TIMING_V(2));
 		DUMPREG(DISPC_POL_FREQ(2));
-		DUMPREG(DISPC_DIVISOR(2));
+		DUMPREG(DISPC_DIVISORo(2));
 		DUMPREG(DISPC_SIZE_LCD(2));
 	}
 
@@ -2714,8 +2715,8 @@ int dispc_get_clock_div(enum omap_channel channel,
 
 	fck = dispc_fclk_rate();
 
-	cinfo->lck_div = REG_GET(DISPC_DIVISOR(channel), 23, 16);
-	cinfo->pck_div = REG_GET(DISPC_DIVISOR(channel), 7, 0);
+	cinfo->lck_div = REG_GET(DISPC_DIVISORo(channel), 23, 16);
+	cinfo->pck_div = REG_GET(DISPC_DIVISORo(channel), 7, 0);
 
 	cinfo->lck = fck / cinfo->lck_div;
 	cinfo->pck = cinfo->lck / cinfo->pck_div;
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v1 3/3] OMAP4: DSS2: Using dss_features to set independent core clock divider
  2011-03-03  9:55 [PATCH v1 0/3] OMAP: DSS2: Fix for DISPC core functional clock divider Raghuveer Murthy
  2011-03-03  9:55 ` [PATCH v1 1/3] OMAP: DSS2: Adding dss_features for independent core clk divider Raghuveer Murthy
  2011-03-03  9:55 ` [PATCH v1 2/3] OMAP: DSS2: Renaming register macro DISPC_DIVISOR(ch) Raghuveer Murthy
@ 2011-03-03  9:55 ` Raghuveer Murthy
  2 siblings, 0 replies; 4+ messages in thread
From: Raghuveer Murthy @ 2011-03-03  9:55 UTC (permalink / raw)
  To: tomba; +Cc: linux-omap

Using dss_features to select independent core clock divider and setting
it. Added the register used, to DISPC context save and restore group

-----------------------------------------------------------------------
In OMAP4, the minimum DISPC_CORE_CLK required can be expressed as:

	DISPC_CORE_CLK >= max(PCLK1*HSCALE1, PCLK2*HSCALE2, ...)

Where PCLKi is the pixel clock generated by MANAGERi and HSCALEi is the
maximum horizontal downscaling done through MANAGERi

Based on the usecase, core clk can be increased or decreased at runtime
to save power. Such mechanism are not yet implemented. Hence, we set the
core clock divisor to 1, to support maximum range of resolutions
------------------------------------------------------------------------

Signed-off-by: Raghuveer Murthy <raghuveer.murthy@ti.com>
---
 drivers/video/omap2/dss/dispc.c |   24 ++++++++++++++++++++++++
 1 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 11b2b04..bb88dfb 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -375,6 +375,9 @@ void dispc_save_context(void)
 	SR(VID_FIR_COEF_V(1, 7));
 
 	SR(VID_PRELOAD(1));
+
+	if (dss_has_feature(FEAT_CORE_CLK_DIV))
+		SR(DIVISOR);
 }
 
 void dispc_restore_context(void)
@@ -534,6 +537,9 @@ void dispc_restore_context(void)
 
 	RR(VID_PRELOAD(1));
 
+	if (dss_has_feature(FEAT_CORE_CLK_DIV))
+		RR(DIVISOR);
+
 	/* enable last, because LCD & DIGIT enable are here */
 	RR(CONTROL);
 	if (dss_has_feature(FEAT_MGR_LCD2))
@@ -2358,6 +2364,7 @@ unsigned long dispc_pclk_rate(enum omap_channel channel)
 void dispc_dump_clocks(struct seq_file *s)
 {
 	int lcd, pcd;
+	u32 l;
 
 	enable_clocks(1);
 
@@ -2369,6 +2376,14 @@ void dispc_dump_clocks(struct seq_file *s)
 
 	seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate());
 
+	if (dss_has_feature(FEAT_CORE_CLK_DIV)) {
+		seq_printf(s, "- DISPC-CORE-CLK -\n");
+		l = dispc_read_reg(DISPC_DIVISOR);
+		lcd = FLD_GET(l, 23, 16);
+
+		seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
+				(dispc_fclk_rate()/lcd), lcd);
+	}
 	seq_printf(s, "- LCD1 -\n");
 
 	dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD, &lcd, &pcd);
@@ -3264,6 +3279,15 @@ static void _omap_dispc_initial_config(void)
 	l = FLD_MOD(l, 1, 0, 0);	/* AUTOIDLE */
 	dispc_write_reg(DISPC_SYSCONFIG, l);
 
+	/* Exclusively enable DISPC_CORE_CLK and set divider to 1 */
+	if (dss_has_feature(FEAT_CORE_CLK_DIV)) {
+		l = dispc_read_reg(DISPC_DIVISOR);
+		/* Use DISPC_DIVISOR.LCD, instead of DISPC_DIVISOR1.LCD */
+		l = FLD_MOD(l, 1, 0, 0);
+		l = FLD_MOD(l, 1, 23, 16);
+		dispc_write_reg(DISPC_DIVISOR, l);
+	}
+
 	/* FUNCGATED */
 	if (dss_has_feature(FEAT_FUNCGATED))
 		REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9);
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2011-03-03  9:55 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-03  9:55 [PATCH v1 0/3] OMAP: DSS2: Fix for DISPC core functional clock divider Raghuveer Murthy
2011-03-03  9:55 ` [PATCH v1 1/3] OMAP: DSS2: Adding dss_features for independent core clk divider Raghuveer Murthy
2011-03-03  9:55 ` [PATCH v1 2/3] OMAP: DSS2: Renaming register macro DISPC_DIVISOR(ch) Raghuveer Murthy
2011-03-03  9:55 ` [PATCH v1 3/3] OMAP4: DSS2: Using dss_features to set independent core clock divider Raghuveer Murthy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).