4 * Xilinx TFT LCD frame buffer driver
6 * Author: MontaVista Software, Inc.
9 * 2002-2007 (c) MontaVista Software, Inc. This file is licensed under the
10 * terms of the GNU General Public License version 2. This program is licensed
11 * "as is" without any warranty of any kind, whether express or implied.
15 * This driver was based on au1100fb.c by MontaVista rewritten for 2.6
16 * by Embedded Alley Solutions <source@embeddedalley.com>, which in turn
17 * was based on skeletonfb.c, Skeleton for a frame buffer device by
21 #include <linux/device.h>
22 #include <linux/module.h>
23 #include <linux/kernel.h>
24 #include <linux/version.h>
25 #include <linux/errno.h>
26 #include <linux/string.h>
29 #include <linux/init.h>
30 #include <linux/dma-mapping.h>
31 #include <linux/platform_device.h>
34 #include <linux/xilinxfb.h>
36 #define DRIVER_NAME "xilinxfb"
37 #define DRIVER_DESCRIPTION "Xilinx TFT LCD frame buffer driver"
40 * Xilinx calls it "PLB TFT LCD Controller" though it can also be used for
41 * the VGA port on the Xilinx ML40x board. This is a hardware display controller
42 * for a 640x480 resolution TFT or VGA screen.
44 * The interface to the framebuffer is nice and simple. There are two
45 * control registers. The first tells the LCD interface where in memory
46 * the frame buffer is (only the 11 most significant bits are used, so
47 * don't start thinking about scrolling). The second allows the LCD to
48 * be turned on or off as well as rotated 180 degrees.
53 #define REG_CTRL_ENABLE 0x0001
54 #define REG_CTRL_ROTATE 0x0002
57 * The hardware only handles a single mode: 640x480 24 bit true
58 * color. Each pixel gets a word (32 bits) of memory. Within each word,
59 * the 8 most significant bits are ignored, the next 8 bits are the red
60 * level, the next 8 bits are the green level and the 8 least
61 * significant bits are the blue level. Each row of the LCD uses 1024
62 * words, but only the first 640 pixels are displayed with the other 384
63 * words being ignored. There are 480 rows.
65 #define BYTES_PER_PIXEL 4
66 #define BITS_PER_PIXEL (BYTES_PER_PIXEL * 8)
69 #define XRES_VIRTUAL 1024
70 #define YRES_VIRTUAL YRES
71 #define LINE_LENGTH (XRES_VIRTUAL * BYTES_PER_PIXEL)
72 #define FB_SIZE (YRES_VIRTUAL * LINE_LENGTH)
78 #define PALETTE_ENTRIES_NO 16 /* passed to fb_alloc_cmap() */
81 * Here are the default fb_fix_screeninfo and fb_var_screeninfo structures
83 static struct fb_fix_screeninfo xilinx_fb_fix
= {
85 .type
= FB_TYPE_PACKED_PIXELS
,
86 .visual
= FB_VISUAL_TRUECOLOR
,
88 .line_length
= LINE_LENGTH
,
89 .accel
= FB_ACCEL_NONE
92 static struct fb_var_screeninfo xilinx_fb_var
= {
95 .xres_virtual
= XRES_VIRTUAL
,
96 .yres_virtual
= YRES_VIRTUAL
,
98 .bits_per_pixel
= BITS_PER_PIXEL
,
100 .red
= { RED_SHIFT
, 8, 0 },
101 .green
= { GREEN_SHIFT
, 8, 0 },
102 .blue
= { BLUE_SHIFT
, 8, 0 },
103 .transp
= { 0, 0, 0 },
105 .activate
= FB_ACTIVATE_NOW
108 struct xilinxfb_drvdata
{
110 struct fb_info info
; /* FB driver info record */
112 u32 regs_phys
; /* phys. address of the control registers */
113 u32 __iomem
*regs
; /* virt. address of the control registers */
115 unsigned char __iomem
*fb_virt
; /* virt. address of the frame buffer */
116 dma_addr_t fb_phys
; /* phys. address of the frame buffer */
118 u32 reg_ctrl_default
;
120 u32 pseudo_palette
[PALETTE_ENTRIES_NO
];
121 /* Fake palette of 16 colors */
124 #define to_xilinxfb_drvdata(_info) \
125 container_of(_info, struct xilinxfb_drvdata, info)
128 * The LCD controller has DCR interface to its registers, but all
129 * the boards and configurations the driver has been tested with
130 * use opb2dcr bridge. So the registers are seen as memory mapped.
131 * This macro is to make it simple to add the direct DCR access
134 #define xilinx_fb_out_be32(driverdata, offset, val) \
135 out_be32(driverdata->regs + offset, val)
138 xilinx_fb_setcolreg(unsigned regno
, unsigned red
, unsigned green
, unsigned blue
,
139 unsigned transp
, struct fb_info
*fbi
)
141 u32
*palette
= fbi
->pseudo_palette
;
143 if (regno
>= PALETTE_ENTRIES_NO
)
146 if (fbi
->var
.grayscale
) {
147 /* Convert color to grayscale.
148 * grayscale = 0.30*R + 0.59*G + 0.11*B */
150 (red
* 77 + green
* 151 + blue
* 28 + 127) >> 8;
153 /* fbi->fix.visual is always FB_VISUAL_TRUECOLOR */
155 /* We only handle 8 bits of each color. */
159 palette
[regno
] = (red
<< RED_SHIFT
) | (green
<< GREEN_SHIFT
) |
160 (blue
<< BLUE_SHIFT
);
166 xilinx_fb_blank(int blank_mode
, struct fb_info
*fbi
)
168 struct xilinxfb_drvdata
*drvdata
= to_xilinxfb_drvdata(fbi
);
170 switch (blank_mode
) {
171 case FB_BLANK_UNBLANK
:
173 xilinx_fb_out_be32(drvdata
, REG_CTRL
, drvdata
->reg_ctrl_default
);
176 case FB_BLANK_NORMAL
:
177 case FB_BLANK_VSYNC_SUSPEND
:
178 case FB_BLANK_HSYNC_SUSPEND
:
179 case FB_BLANK_POWERDOWN
:
181 xilinx_fb_out_be32(drvdata
, REG_CTRL
, 0);
186 return 0; /* success */
189 static struct fb_ops xilinxfb_ops
=
191 .owner
= THIS_MODULE
,
192 .fb_setcolreg
= xilinx_fb_setcolreg
,
193 .fb_blank
= xilinx_fb_blank
,
194 .fb_fillrect
= cfb_fillrect
,
195 .fb_copyarea
= cfb_copyarea
,
196 .fb_imageblit
= cfb_imageblit
,
199 /* ---------------------------------------------------------------------
200 * Bus independent setup/teardown
203 static int xilinxfb_assign(struct device
*dev
, unsigned long physaddr
,
204 int width_mm
, int height_mm
, int rotate
)
206 struct xilinxfb_drvdata
*drvdata
;
209 /* Allocate the driver data region */
210 drvdata
= kzalloc(sizeof(*drvdata
), GFP_KERNEL
);
212 dev_err(dev
, "Couldn't allocate device private record\n");
215 dev_set_drvdata(dev
, drvdata
);
217 /* Map the control registers in */
218 if (!request_mem_region(physaddr
, 8, DRIVER_NAME
)) {
219 dev_err(dev
, "Couldn't lock memory region at 0x%08lX\n",
224 drvdata
->regs_phys
= physaddr
;
225 drvdata
->regs
= ioremap(physaddr
, 8);
226 if (!drvdata
->regs
) {
227 dev_err(dev
, "Couldn't lock memory region at 0x%08lX\n",
233 /* Allocate the framebuffer memory */
234 drvdata
->fb_virt
= dma_alloc_coherent(dev
, PAGE_ALIGN(FB_SIZE
),
235 &drvdata
->fb_phys
, GFP_KERNEL
);
236 if (!drvdata
->fb_virt
) {
237 dev_err(dev
, "Could not allocate frame buffer memory\n");
242 /* Clear (turn to black) the framebuffer */
243 memset_io(drvdata
->fb_virt
, 0, FB_SIZE
);
245 /* Tell the hardware where the frame buffer is */
246 xilinx_fb_out_be32(drvdata
, REG_FB_ADDR
, drvdata
->fb_phys
);
248 /* Turn on the display */
249 drvdata
->reg_ctrl_default
= REG_CTRL_ENABLE
;
251 drvdata
->reg_ctrl_default
|= REG_CTRL_ROTATE
;
252 xilinx_fb_out_be32(drvdata
, REG_CTRL
, drvdata
->reg_ctrl_default
);
254 /* Fill struct fb_info */
255 drvdata
->info
.device
= dev
;
256 drvdata
->info
.screen_base
= drvdata
->fb_virt
;
257 drvdata
->info
.fbops
= &xilinxfb_ops
;
258 drvdata
->info
.fix
= xilinx_fb_fix
;
259 drvdata
->info
.fix
.smem_start
= drvdata
->fb_phys
;
260 drvdata
->info
.pseudo_palette
= drvdata
->pseudo_palette
;
261 drvdata
->info
.flags
= FBINFO_DEFAULT
;
262 drvdata
->info
.var
= xilinx_fb_var
;
264 xilinx_fb_var
.height
= height_mm
;
265 xilinx_fb_var
.width
= width_mm
;
267 /* Allocate a colour map */
268 rc
= fb_alloc_cmap(&drvdata
->info
.cmap
, PALETTE_ENTRIES_NO
, 0);
270 dev_err(dev
, "Fail to allocate colormap (%d entries)\n",
275 /* Register new frame buffer */
276 rc
= register_framebuffer(&drvdata
->info
);
278 dev_err(dev
, "Could not register frame buffer\n");
282 /* Put a banner in the log (for DEBUG) */
283 dev_dbg(dev
, "regs: phys=%lx, virt=%p\n", physaddr
, drvdata
->regs
);
284 dev_dbg(dev
, "fb: phys=%p, virt=%p, size=%x\n",
285 (void*)drvdata
->fb_phys
, drvdata
->fb_virt
, FB_SIZE
);
286 return 0; /* success */
289 fb_dealloc_cmap(&drvdata
->info
.cmap
);
292 dma_free_coherent(dev
, PAGE_ALIGN(FB_SIZE
), drvdata
->fb_virt
,
294 /* Turn off the display */
295 xilinx_fb_out_be32(drvdata
, REG_CTRL
, 0);
298 iounmap(drvdata
->regs
);
301 release_mem_region(physaddr
, 8);
305 dev_set_drvdata(dev
, NULL
);
310 static int xilinxfb_release(struct device
*dev
)
312 struct xilinxfb_drvdata
*drvdata
= dev_get_drvdata(dev
);
314 #if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
315 xilinx_fb_blank(VESA_POWERDOWN
, &drvdata
->info
);
318 unregister_framebuffer(&drvdata
->info
);
320 fb_dealloc_cmap(&drvdata
->info
.cmap
);
322 dma_free_coherent(dev
, PAGE_ALIGN(FB_SIZE
), drvdata
->fb_virt
,
325 /* Turn off the display */
326 xilinx_fb_out_be32(drvdata
, REG_CTRL
, 0);
327 iounmap(drvdata
->regs
);
329 release_mem_region(drvdata
->regs_phys
, 8);
332 dev_set_drvdata(dev
, NULL
);
337 /* ---------------------------------------------------------------------
338 * Platform bus binding
342 xilinxfb_drv_probe(struct device
*dev
)
344 struct platform_device
*pdev
;
345 struct xilinxfb_platform_data
*pdata
;
346 struct resource
*res
;
351 pdev
= to_platform_device(dev
);
352 pdata
= pdev
->dev
.platform_data
;
354 dev_err(dev
, "Missing pdata structure\n");
358 /* Find the registers address */
359 res
= platform_get_resource(pdev
, IORESOURCE_IO
, 0);
361 dev_err(dev
, "Couldn't get registers resource\n");
365 height_mm
= pdata
->screen_height_mm
;
366 width_mm
= pdata
->screen_width_mm
;
367 rotate
= pdata
->rotate_screen
? 1 : 0;
369 return xilinxfb_assign(dev
, res
->start
, width_mm
, height_mm
, rotate
);
373 xilinxfb_drv_remove(struct device
*dev
)
375 return xilinxfb_release(dev
);
379 static struct device_driver xilinxfb_driver
= {
381 .bus
= &platform_bus_type
,
383 .probe
= xilinxfb_drv_probe
,
384 .remove
= xilinxfb_drv_remove
391 * No kernel boot options used,
392 * so we just need to register the driver
394 return driver_register(&xilinxfb_driver
);
398 xilinxfb_cleanup(void)
400 driver_unregister(&xilinxfb_driver
);
403 module_init(xilinxfb_init
);
404 module_exit(xilinxfb_cleanup
);
406 MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
407 MODULE_DESCRIPTION(DRIVER_DESCRIPTION
);
408 MODULE_LICENSE("GPL");