* [PATCH v3 0/3] OMAP: DSS2: Fix for DISPC core functional clock divider
@ 2011-03-03 15:27 Raghuveer Murthy
2011-03-03 15:27 ` [PATCH v3 1/3] OMAP: DSS2: Adding dss_features for independent core clk divider Raghuveer Murthy
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Raghuveer Murthy @ 2011-03-03 15:27 UTC (permalink / raw)
To: linux-arm-kernel
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>
Changes from previous version (v2)
- Rebased against the DSS2 master to avoid conflicts
Base
----
url = git://gitorious.org/linux-omap-dss2/linux.git
branch "master"
commit a2792bb44d45ef97963e67565ad1e1dd5bf0cbd7
-----------------------------------------------------
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 | 3 +-
drivers/video/omap2/dss/dss_features.h | 2 +
3 files changed, 42 insertions(+), 14 deletions(-)
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 1/3] OMAP: DSS2: Adding dss_features for independent core clk divider
2011-03-03 15:27 [PATCH v3 0/3] OMAP: DSS2: Fix for DISPC core functional clock divider Raghuveer Murthy
@ 2011-03-03 15:27 ` Raghuveer Murthy
2011-03-03 15:27 ` [PATCH v3 2/3] OMAP: DSS2: Renaming register macro DISPC_DIVISOR(ch) Raghuveer Murthy
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Raghuveer Murthy @ 2011-03-03 15:27 UTC (permalink / raw)
To: linux-arm-kernel
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 | 3 ++-
drivers/video/omap2/dss/dss_features.h | 2 ++
2 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index ccae57b..dc170ad 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -234,7 +234,8 @@ static struct omap_dss_features omap4_dss_features = {
.has_feature =
FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA |
- FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1,
+ FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 |
+ 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 65d6de7..569d1b2 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -36,6 +36,8 @@ enum dss_feat_id {
FEAT_LINEBUFFERSPLIT = 1 << 8,
FEAT_ROWREPEATENABLE = 1 << 9,
FEAT_RESIZECONF = 1 << 10,
+ /* Independent core clk divider */
+ FEAT_CORE_CLK_DIV = 1 << 11,
};
/* DSS register field id */
--
1.7.0.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v3 2/3] OMAP: DSS2: Renaming register macro DISPC_DIVISOR(ch)
2011-03-03 15:27 [PATCH v3 0/3] OMAP: DSS2: Fix for DISPC core functional clock divider Raghuveer Murthy
2011-03-03 15:27 ` [PATCH v3 1/3] OMAP: DSS2: Adding dss_features for independent core clk divider Raghuveer Murthy
@ 2011-03-03 15:27 ` Raghuveer Murthy
2011-03-03 15:28 ` [PATCH v3 3/3] OMAP4: DSS2: Using dss_features to set independent core clock divider Raghuveer Murthy
2011-03-03 16:12 ` [PATCH v3 0/3] OMAP: DSS2: Fix for DISPC core functional " Tomi Valkeinen
3 siblings, 0 replies; 5+ messages in thread
From: Raghuveer Murthy @ 2011-03-03 15:27 UTC (permalink / raw)
To: linux-arm-kernel
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 9fb11c1..a3dff5f 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);
}
@@ -2316,7 +2317,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);
}
@@ -2325,7 +2326,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);
}
@@ -2351,7 +2352,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);
@@ -2366,7 +2367,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);
@@ -2483,7 +2484,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));
@@ -2495,7 +2496,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));
}
@@ -2737,8 +2738,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] 5+ messages in thread
* [PATCH v3 3/3] OMAP4: DSS2: Using dss_features to set independent core clock divider
2011-03-03 15:27 [PATCH v3 0/3] OMAP: DSS2: Fix for DISPC core functional clock divider Raghuveer Murthy
2011-03-03 15:27 ` [PATCH v3 1/3] OMAP: DSS2: Adding dss_features for independent core clk divider Raghuveer Murthy
2011-03-03 15:27 ` [PATCH v3 2/3] OMAP: DSS2: Renaming register macro DISPC_DIVISOR(ch) Raghuveer Murthy
@ 2011-03-03 15:28 ` Raghuveer Murthy
2011-03-03 16:12 ` [PATCH v3 0/3] OMAP: DSS2: Fix for DISPC core functional " Tomi Valkeinen
3 siblings, 0 replies; 5+ messages in thread
From: Raghuveer Murthy @ 2011-03-03 15:28 UTC (permalink / raw)
To: linux-arm-kernel
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 a3dff5f..dae9686 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))
@@ -2380,6 +2386,7 @@ unsigned long dispc_pclk_rate(enum omap_channel channel)
void dispc_dump_clocks(struct seq_file *s)
{
int lcd, pcd;
+ u32 l;
enum dss_clk_source dispc_clk_src = dss_get_dispc_clk_source();
enable_clocks(1);
@@ -2392,6 +2399,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);
@@ -3287,6 +3302,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] 5+ messages in thread
* [PATCH v3 0/3] OMAP: DSS2: Fix for DISPC core functional clock divider
2011-03-03 15:27 [PATCH v3 0/3] OMAP: DSS2: Fix for DISPC core functional clock divider Raghuveer Murthy
` (2 preceding siblings ...)
2011-03-03 15:28 ` [PATCH v3 3/3] OMAP4: DSS2: Using dss_features to set independent core clock divider Raghuveer Murthy
@ 2011-03-03 16:12 ` Tomi Valkeinen
3 siblings, 0 replies; 5+ messages in thread
From: Tomi Valkeinen @ 2011-03-03 16:12 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, 2011-03-03 at 09:27 -0600, Murthy, Raghuveer wrote:
> 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
Thanks, applied.
Tomi
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2011-03-03 16:12 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-03 15:27 [PATCH v3 0/3] OMAP: DSS2: Fix for DISPC core functional clock divider Raghuveer Murthy
2011-03-03 15:27 ` [PATCH v3 1/3] OMAP: DSS2: Adding dss_features for independent core clk divider Raghuveer Murthy
2011-03-03 15:27 ` [PATCH v3 2/3] OMAP: DSS2: Renaming register macro DISPC_DIVISOR(ch) Raghuveer Murthy
2011-03-03 15:28 ` [PATCH v3 3/3] OMAP4: DSS2: Using dss_features to set independent core clock divider Raghuveer Murthy
2011-03-03 16:12 ` [PATCH v3 0/3] OMAP: DSS2: Fix for DISPC core functional " Tomi Valkeinen
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).