| From 34682d82bb5fdacc605bebe92375d30d6fe5d96b Mon Sep 17 00:00:00 2001 |
| From: Michal Simek <michal.simek@xilinx.com> |
| Date: Mon, 3 Jun 2013 12:13:21 +0200 |
| Subject: video: xilinxfb: Add support for little endian accesses |
| |
| Dynamically detect endianess on IP and use |
| ioread/iowrite functions instead of powerpc and microblaze |
| specific out_be32. |
| |
| Signed-off-by: Michal Simek <michal.simek@xilinx.com> |
| Acked-by: Arnd Bergmann <arnd@arndb.de> |
| Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> |
| (cherry picked from commit 2121c339eb6fd234df16172d6a748d7007eceba8) |
| Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> |
| Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> |
| --- |
| drivers/video/xilinxfb.c | 30 ++++++++++++++++++++++++++++-- |
| 1 file changed, 28 insertions(+), 2 deletions(-) |
| |
| diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c |
| index bd3b85d890d4..f3d4a69e1e4e 100644 |
| --- a/drivers/video/xilinxfb.c |
| +++ b/drivers/video/xilinxfb.c |
| @@ -117,6 +117,7 @@ static struct fb_var_screeninfo xilinx_fb_var = { |
| |
| |
| #define BUS_ACCESS_FLAG 0x1 /* 1 = BUS, 0 = DCR */ |
| +#define LITTLE_ENDIAN_ACCESS 0x2 /* LITTLE ENDIAN IO functions */ |
| |
| struct xilinxfb_drvdata { |
| |
| @@ -153,14 +154,33 @@ struct xilinxfb_drvdata { |
| static void xilinx_fb_out32(struct xilinxfb_drvdata *drvdata, u32 offset, |
| u32 val) |
| { |
| - if (drvdata->flags & BUS_ACCESS_FLAG) |
| - out_be32(drvdata->regs + (offset << 2), val); |
| + if (drvdata->flags & BUS_ACCESS_FLAG) { |
| + if (drvdata->flags & LITTLE_ENDIAN_ACCESS) |
| + iowrite32(val, drvdata->regs + (offset << 2)); |
| + else |
| + iowrite32be(val, drvdata->regs + (offset << 2)); |
| + } |
| #ifdef CONFIG_PPC_DCR |
| else |
| dcr_write(drvdata->dcr_host, offset, val); |
| #endif |
| } |
| |
| +static u32 xilinx_fb_in32(struct xilinxfb_drvdata *drvdata, u32 offset) |
| +{ |
| + if (drvdata->flags & BUS_ACCESS_FLAG) { |
| + if (drvdata->flags & LITTLE_ENDIAN_ACCESS) |
| + return ioread32(drvdata->regs + (offset << 2)); |
| + else |
| + return ioread32be(drvdata->regs + (offset << 2)); |
| + } |
| +#ifdef CONFIG_PPC_DCR |
| + else |
| + return dcr_read(drvdata->dcr_host, offset); |
| +#endif |
| + return 0; |
| +} |
| + |
| static int |
| xilinx_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, |
| unsigned transp, struct fb_info *fbi) |
| @@ -271,6 +291,12 @@ static int xilinxfb_assign(struct platform_device *pdev, |
| |
| /* Tell the hardware where the frame buffer is */ |
| xilinx_fb_out32(drvdata, REG_FB_ADDR, drvdata->fb_phys); |
| + rc = xilinx_fb_in32(drvdata, REG_FB_ADDR); |
| + /* Endianess detection */ |
| + if (rc != drvdata->fb_phys) { |
| + drvdata->flags |= LITTLE_ENDIAN_ACCESS; |
| + xilinx_fb_out32(drvdata, REG_FB_ADDR, drvdata->fb_phys); |
| + } |
| |
| /* Turn on the display */ |
| drvdata->reg_ctrl_default = REG_CTRL_ENABLE; |
| -- |
| 1.8.5.rc3 |
| |