diff --git a/arch/sh/boards/board-ap325rxa.c b/arch/sh/boards/board-ap325rxa.c index bcf1f40bcc6c5624681b0ef02ba1bd4545d27eaf..327d47c25a57646dc1e01d2613a85e9351f733b9 100644 --- a/arch/sh/boards/board-ap325rxa.c +++ b/arch/sh/boards/board-ap325rxa.c @@ -211,7 +211,7 @@ static struct resource lcdc_resources[] = { [0] = { .name = "LCDC", .start = 0xfe940000, /* P4-only space */ - .end = 0xfe941fff, + .end = 0xfe942fff, .flags = IORESOURCE_MEM, }, [1] = { diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 7da274ae7440758e7c2a49c1455bce0a272afa78..bbe601d4209f47016c90d1551751bd4a08f6ec42 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c @@ -239,7 +239,7 @@ static struct resource lcdc_resources[] = { [0] = { .name = "LCDC", .start = 0xfe940000, - .end = 0xfe941fff, + .end = 0xfe942fff, .flags = IORESOURCE_MEM, }, [1] = { diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c index 7155be0d115425ff9c621623c3230fb7e4b834ad..c08d33fe2104352eeb8db79d6d88c403189f05cc 100644 --- a/arch/sh/boards/mach-kfr2r09/setup.c +++ b/arch/sh/boards/mach-kfr2r09/setup.c @@ -162,7 +162,7 @@ static struct resource kfr2r09_sh_lcdc_resources[] = { [0] = { .name = "LCDC", .start = 0xfe940000, /* P4-only space */ - .end = 0xfe941fff, + .end = 0xfe942fff, .flags = IORESOURCE_MEM, }, [1] = { diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c index be8f0d94f6f1690cdfcceb637d9892ad1aede530..6ed1fd32369e456fb4437a1d133f9f949f822029 100644 --- a/arch/sh/boards/mach-migor/setup.c +++ b/arch/sh/boards/mach-migor/setup.c @@ -279,7 +279,7 @@ static struct resource migor_lcdc_resources[] = { [0] = { .name = "LCDC", .start = 0xfe940000, /* P4-only space */ - .end = 0xfe941fff, + .end = 0xfe942fff, .flags = IORESOURCE_MEM, }, [1] = { diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index 1876c8306c85e3d5cb5a73a8279e4371ce391839..00973e0f8c631b7181e3ef4ca3b554fcb03fa5b4 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c @@ -166,7 +166,7 @@ static struct resource lcdc_resources[] = { [0] = { .name = "LCDC", .start = 0xfe940000, - .end = 0xfe941fff, + .end = 0xfe942fff, .flags = IORESOURCE_MEM, }, [1] = { diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index 7f30cb33a2037a1cc69251be35a07de496a7307a..3ad5157f9899f766e2a272668c148d73006cb000 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -23,6 +23,8 @@ #include #define PALETTE_NR 16 +#define SIDE_B_OFFSET 0x1000 +#define MIRROR_OFFSET 0x2000 /* shared registers */ #define _LDDCKR 0x410 @@ -100,6 +102,10 @@ static unsigned long lcdc_offs_sublcd[NR_CH_REGS] = { #define LDINTR_FS 0x00000004 #define LDINTR_VSS 0x00000002 #define LDINTR_VES 0x00000001 +#define LDRCNTR_SRS 0x00020000 +#define LDRCNTR_SRC 0x00010000 +#define LDRCNTR_MRS 0x00000002 +#define LDRCNTR_MRC 0x00000001 struct sh_mobile_lcdc_priv; struct sh_mobile_lcdc_chan { @@ -132,10 +138,39 @@ struct sh_mobile_lcdc_priv { int started; }; +static bool banked(int reg_nr) +{ + switch (reg_nr) { + case LDMT1R: + case LDMT2R: + case LDMT3R: + case LDDFR: + case LDSM1R: + case LDSA1R: + case LDMLSR: + case LDHCNR: + case LDHSYNR: + case LDVLNR: + case LDVSYNR: + return true; + } + return false; +} + static void lcdc_write_chan(struct sh_mobile_lcdc_chan *chan, int reg_nr, unsigned long data) { iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr]); + if (banked(reg_nr)) + iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr] + + SIDE_B_OFFSET); +} + +static void lcdc_write_chan_mirror(struct sh_mobile_lcdc_chan *chan, + int reg_nr, unsigned long data) +{ + iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr] + + MIRROR_OFFSET); } static 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) /* VSYNC End */ if (ldintr & LDINTR_VES) { + unsigned long ldrcntr = lcdc_read(priv, _LDRCNTR); /* Set the source address for the next refresh */ - lcdc_write_chan(ch, LDSA1R, ch->dma_handle + - ch->new_pan_offset); - lcdc_write(ch->lcdc, _LDRCNTR, 0); + lcdc_write_chan_mirror(ch, LDSA1R, ch->dma_handle + + ch->new_pan_offset); + if (lcdc_chan_is_sublcd(ch)) + lcdc_write(ch->lcdc, _LDRCNTR, + ldrcntr ^ LDRCNTR_SRS); + else + lcdc_write(ch->lcdc, _LDRCNTR, + ldrcntr ^ LDRCNTR_MRS); ch->pan_offset = ch->new_pan_offset; } }