aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/sh_mobile_lcdcfb.c
diff options
context:
space:
mode:
authorPhil Edworthy <phil.edworthy@renesas.com>2009-09-15 08:00:30 -0400
committerPaul Mundt <lethal@linux-sh.org>2009-09-15 08:08:22 -0400
commita6f15ade97989d414e9bf33874c9d5d1f39808ec (patch)
tree6738402bca402004d55b913f56c2671913756e83 /drivers/video/sh_mobile_lcdcfb.c
parent9dd38819c2257375ea05bcb92b1f607a1d523c84 (diff)
video: sh_mobile_lcdcfb: use both register sets for display panning
Switch to using both register sets - side A and side B for display panning. Signed-off-by: Phil Edworthy <phil.edworthy@renesas.com> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/video/sh_mobile_lcdcfb.c')
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c47
1 files changed, 44 insertions, 3 deletions
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 7f30cb33a20..3ad5157f989 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -23,6 +23,8 @@
23#include <asm/atomic.h> 23#include <asm/atomic.h>
24 24
25#define PALETTE_NR 16 25#define PALETTE_NR 16
26#define SIDE_B_OFFSET 0x1000
27#define MIRROR_OFFSET 0x2000
26 28
27/* shared registers */ 29/* shared registers */
28#define _LDDCKR 0x410 30#define _LDDCKR 0x410
@@ -100,6 +102,10 @@ static unsigned long lcdc_offs_sublcd[NR_CH_REGS] = {
100#define LDINTR_FS 0x00000004 102#define LDINTR_FS 0x00000004
101#define LDINTR_VSS 0x00000002 103#define LDINTR_VSS 0x00000002
102#define LDINTR_VES 0x00000001 104#define LDINTR_VES 0x00000001
105#define LDRCNTR_SRS 0x00020000
106#define LDRCNTR_SRC 0x00010000
107#define LDRCNTR_MRS 0x00000002
108#define LDRCNTR_MRC 0x00000001
103 109
104struct sh_mobile_lcdc_priv; 110struct sh_mobile_lcdc_priv;
105struct sh_mobile_lcdc_chan { 111struct sh_mobile_lcdc_chan {
@@ -132,10 +138,39 @@ struct sh_mobile_lcdc_priv {
132 int started; 138 int started;
133}; 139};
134 140
141static bool banked(int reg_nr)
142{
143 switch (reg_nr) {
144 case LDMT1R:
145 case LDMT2R:
146 case LDMT3R:
147 case LDDFR:
148 case LDSM1R:
149 case LDSA1R:
150 case LDMLSR:
151 case LDHCNR:
152 case LDHSYNR:
153 case LDVLNR:
154 case LDVSYNR:
155 return true;
156 }
157 return false;
158}
159
135static void lcdc_write_chan(struct sh_mobile_lcdc_chan *chan, 160static void lcdc_write_chan(struct sh_mobile_lcdc_chan *chan,
136 int reg_nr, unsigned long data) 161 int reg_nr, unsigned long data)
137{ 162{
138 iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr]); 163 iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr]);
164 if (banked(reg_nr))
165 iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr] +
166 SIDE_B_OFFSET);
167}
168
169static void lcdc_write_chan_mirror(struct sh_mobile_lcdc_chan *chan,
170 int reg_nr, unsigned long data)
171{
172 iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr] +
173 MIRROR_OFFSET);
139} 174}
140 175
141static unsigned long lcdc_read_chan(struct sh_mobile_lcdc_chan *chan, 176static unsigned long lcdc_read_chan(struct sh_mobile_lcdc_chan *chan,
@@ -308,10 +343,16 @@ static irqreturn_t sh_mobile_lcdc_irq(int irq, void *data)
308 343
309 /* VSYNC End */ 344 /* VSYNC End */
310 if (ldintr & LDINTR_VES) { 345 if (ldintr & LDINTR_VES) {
346 unsigned long ldrcntr = lcdc_read(priv, _LDRCNTR);
311 /* Set the source address for the next refresh */ 347 /* Set the source address for the next refresh */
312 lcdc_write_chan(ch, LDSA1R, ch->dma_handle + 348 lcdc_write_chan_mirror(ch, LDSA1R, ch->dma_handle +
313 ch->new_pan_offset); 349 ch->new_pan_offset);
314 lcdc_write(ch->lcdc, _LDRCNTR, 0); 350 if (lcdc_chan_is_sublcd(ch))
351 lcdc_write(ch->lcdc, _LDRCNTR,
352 ldrcntr ^ LDRCNTR_SRS);
353 else
354 lcdc_write(ch->lcdc, _LDRCNTR,
355 ldrcntr ^ LDRCNTR_MRS);
315 ch->pan_offset = ch->new_pan_offset; 356 ch->pan_offset = ch->new_pan_offset;
316 } 357 }
317 } 358 }