video: xilinxfb: Add support for little endian accesses
authorMichal Simek <michal.simek@xilinx.com>
Mon, 3 Jun 2013 10:13:21 +0000 (12:13 +0200)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Wed, 26 Jun 2013 10:33:41 +0000 (13:33 +0300)
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>
drivers/video/xilinxfb.c

index bd3b85d890d403f4e2a19654f24ea336e07af001..f3d4a69e1e4e9058c4c4cc605705f1d62d923a48 100644 (file)
@@ -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;