diff options
author | Michal Simek <michal.simek@xilinx.com> | 2013-06-03 06:13:21 -0400 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2013-06-26 06:33:41 -0400 |
commit | 2121c339eb6fd234df16172d6a748d7007eceba8 (patch) | |
tree | 947eafb1d4fa54af8a44518f988fa595358dadbd | |
parent | a8f045aa07b3d40f46e35536eeb54e3c5423c5c2 (diff) |
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>
-rw-r--r-- | drivers/video/xilinxfb.c | 30 |
1 files 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 = { | |||
117 | 117 | ||
118 | 118 | ||
119 | #define BUS_ACCESS_FLAG 0x1 /* 1 = BUS, 0 = DCR */ | 119 | #define BUS_ACCESS_FLAG 0x1 /* 1 = BUS, 0 = DCR */ |
120 | #define LITTLE_ENDIAN_ACCESS 0x2 /* LITTLE ENDIAN IO functions */ | ||
120 | 121 | ||
121 | struct xilinxfb_drvdata { | 122 | struct xilinxfb_drvdata { |
122 | 123 | ||
@@ -153,14 +154,33 @@ struct xilinxfb_drvdata { | |||
153 | static void xilinx_fb_out32(struct xilinxfb_drvdata *drvdata, u32 offset, | 154 | static void xilinx_fb_out32(struct xilinxfb_drvdata *drvdata, u32 offset, |
154 | u32 val) | 155 | u32 val) |
155 | { | 156 | { |
156 | if (drvdata->flags & BUS_ACCESS_FLAG) | 157 | if (drvdata->flags & BUS_ACCESS_FLAG) { |
157 | out_be32(drvdata->regs + (offset << 2), val); | 158 | if (drvdata->flags & LITTLE_ENDIAN_ACCESS) |
159 | iowrite32(val, drvdata->regs + (offset << 2)); | ||
160 | else | ||
161 | iowrite32be(val, drvdata->regs + (offset << 2)); | ||
162 | } | ||
158 | #ifdef CONFIG_PPC_DCR | 163 | #ifdef CONFIG_PPC_DCR |
159 | else | 164 | else |
160 | dcr_write(drvdata->dcr_host, offset, val); | 165 | dcr_write(drvdata->dcr_host, offset, val); |
161 | #endif | 166 | #endif |
162 | } | 167 | } |
163 | 168 | ||
169 | static u32 xilinx_fb_in32(struct xilinxfb_drvdata *drvdata, u32 offset) | ||
170 | { | ||
171 | if (drvdata->flags & BUS_ACCESS_FLAG) { | ||
172 | if (drvdata->flags & LITTLE_ENDIAN_ACCESS) | ||
173 | return ioread32(drvdata->regs + (offset << 2)); | ||
174 | else | ||
175 | return ioread32be(drvdata->regs + (offset << 2)); | ||
176 | } | ||
177 | #ifdef CONFIG_PPC_DCR | ||
178 | else | ||
179 | return dcr_read(drvdata->dcr_host, offset); | ||
180 | #endif | ||
181 | return 0; | ||
182 | } | ||
183 | |||
164 | static int | 184 | static int |
165 | xilinx_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, | 185 | xilinx_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, |
166 | unsigned transp, struct fb_info *fbi) | 186 | unsigned transp, struct fb_info *fbi) |
@@ -271,6 +291,12 @@ static int xilinxfb_assign(struct platform_device *pdev, | |||
271 | 291 | ||
272 | /* Tell the hardware where the frame buffer is */ | 292 | /* Tell the hardware where the frame buffer is */ |
273 | xilinx_fb_out32(drvdata, REG_FB_ADDR, drvdata->fb_phys); | 293 | xilinx_fb_out32(drvdata, REG_FB_ADDR, drvdata->fb_phys); |
294 | rc = xilinx_fb_in32(drvdata, REG_FB_ADDR); | ||
295 | /* Endianess detection */ | ||
296 | if (rc != drvdata->fb_phys) { | ||
297 | drvdata->flags |= LITTLE_ENDIAN_ACCESS; | ||
298 | xilinx_fb_out32(drvdata, REG_FB_ADDR, drvdata->fb_phys); | ||
299 | } | ||
274 | 300 | ||
275 | /* Turn on the display */ | 301 | /* Turn on the display */ |
276 | drvdata->reg_ctrl_default = REG_CTRL_ENABLE; | 302 | drvdata->reg_ctrl_default = REG_CTRL_ENABLE; |