aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/wmt_ge_rops.c
diff options
context:
space:
mode:
authorAlexey Charkov <alchark@gmail.com>2010-11-08 18:42:39 -0500
committerPaul Mundt <lethal@linux-sh.org>2010-11-09 04:52:07 -0500
commitd6ff7d0fe22cdf3ea41c48b50da9a9181500d1bf (patch)
treef14609b2e10c9b381c1905a3a895729293119929 /drivers/video/wmt_ge_rops.c
parenta7bcf21e60c73cb7f7c13fad928967d7e47c3cac (diff)
ARM: Add support for the display controllers in VT8500 and WM8505
This adds drivers for the LCD controller found in VIA VT8500 SoC, GOVR display controller found in WonderMedia WM8505 SoC and for the Graphics Engine present in both of them that provides hardware accelerated raster operations (used for copyarea and fillrect). Signed-off-by: Alexey Charkov <alchark@gmail.com> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/video/wmt_ge_rops.c')
-rw-r--r--drivers/video/wmt_ge_rops.c192
1 files changed, 192 insertions, 0 deletions
diff --git a/drivers/video/wmt_ge_rops.c b/drivers/video/wmt_ge_rops.c
new file mode 100644
index 000000000000..f31883f8eaf7
--- /dev/null
+++ b/drivers/video/wmt_ge_rops.c
@@ -0,0 +1,192 @@
1/*
2 * linux/drivers/video/wmt_ge_rops.c
3 *
4 * Accelerators for raster operations using WonderMedia Graphics Engine
5 *
6 * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <linux/module.h>
19#include <linux/fb.h>
20#include <linux/platform_device.h>
21#include "fb_draw.h"
22
23#define GE_COMMAND_OFF 0x00
24#define GE_DEPTH_OFF 0x04
25#define GE_HIGHCOLOR_OFF 0x08
26#define GE_ROPCODE_OFF 0x14
27#define GE_FIRE_OFF 0x18
28#define GE_SRCBASE_OFF 0x20
29#define GE_SRCDISPW_OFF 0x24
30#define GE_SRCDISPH_OFF 0x28
31#define GE_SRCAREAX_OFF 0x2c
32#define GE_SRCAREAY_OFF 0x30
33#define GE_SRCAREAW_OFF 0x34
34#define GE_SRCAREAH_OFF 0x38
35#define GE_DESTBASE_OFF 0x3c
36#define GE_DESTDISPW_OFF 0x40
37#define GE_DESTDISPH_OFF 0x44
38#define GE_DESTAREAX_OFF 0x48
39#define GE_DESTAREAY_OFF 0x4c
40#define GE_DESTAREAW_OFF 0x50
41#define GE_DESTAREAH_OFF 0x54
42#define GE_PAT0C_OFF 0x88 /* Pattern 0 color */
43#define GE_ENABLE_OFF 0xec
44#define GE_INTEN_OFF 0xf0
45#define GE_STATUS_OFF 0xf8
46
47static void __iomem *regbase;
48
49void wmt_ge_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
50{
51 unsigned long fg, pat;
52
53 if (p->state != FBINFO_STATE_RUNNING)
54 return;
55
56 if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
57 p->fix.visual == FB_VISUAL_DIRECTCOLOR)
58 fg = ((u32 *) (p->pseudo_palette))[rect->color];
59 else
60 fg = rect->color;
61
62 pat = pixel_to_pat(p->var.bits_per_pixel, fg);
63
64 if (p->fbops->fb_sync)
65 p->fbops->fb_sync(p);
66
67 writel(p->var.bits_per_pixel == 32 ? 3 :
68 (p->var.bits_per_pixel == 8 ? 0 : 1), regbase + GE_DEPTH_OFF);
69 writel(p->var.bits_per_pixel == 15 ? 1 : 0, regbase + GE_HIGHCOLOR_OFF);
70 writel(p->fix.smem_start, regbase + GE_DESTBASE_OFF);
71 writel(p->var.xres_virtual - 1, regbase + GE_DESTDISPW_OFF);
72 writel(p->var.yres_virtual - 1, regbase + GE_DESTDISPH_OFF);
73 writel(rect->dx, regbase + GE_DESTAREAX_OFF);
74 writel(rect->dy, regbase + GE_DESTAREAY_OFF);
75 writel(rect->width - 1, regbase + GE_DESTAREAW_OFF);
76 writel(rect->height - 1, regbase + GE_DESTAREAH_OFF);
77
78 writel(pat, regbase + GE_PAT0C_OFF);
79 writel(1, regbase + GE_COMMAND_OFF);
80 writel(rect->rop == ROP_XOR ? 0x5a : 0xf0, regbase + GE_ROPCODE_OFF);
81 writel(1, regbase + GE_FIRE_OFF);
82}
83EXPORT_SYMBOL_GPL(wmt_ge_fillrect);
84
85void wmt_ge_copyarea(struct fb_info *p, const struct fb_copyarea *area)
86{
87 if (p->state != FBINFO_STATE_RUNNING)
88 return;
89
90 if (p->fbops->fb_sync)
91 p->fbops->fb_sync(p);
92
93 writel(p->var.bits_per_pixel > 16 ? 3 :
94 (p->var.bits_per_pixel > 8 ? 1 : 0), regbase + GE_DEPTH_OFF);
95
96 writel(p->fix.smem_start, regbase + GE_SRCBASE_OFF);
97 writel(p->var.xres_virtual - 1, regbase + GE_SRCDISPW_OFF);
98 writel(p->var.yres_virtual - 1, regbase + GE_SRCDISPH_OFF);
99 writel(area->sx, regbase + GE_SRCAREAX_OFF);
100 writel(area->sy, regbase + GE_SRCAREAY_OFF);
101 writel(area->width - 1, regbase + GE_SRCAREAW_OFF);
102 writel(area->height - 1, regbase + GE_SRCAREAH_OFF);
103
104 writel(p->fix.smem_start, regbase + GE_DESTBASE_OFF);
105 writel(p->var.xres_virtual - 1, regbase + GE_DESTDISPW_OFF);
106 writel(p->var.yres_virtual - 1, regbase + GE_DESTDISPH_OFF);
107 writel(area->dx, regbase + GE_DESTAREAX_OFF);
108 writel(area->dy, regbase + GE_DESTAREAY_OFF);
109 writel(area->width - 1, regbase + GE_DESTAREAW_OFF);
110 writel(area->height - 1, regbase + GE_DESTAREAH_OFF);
111
112 writel(0xcc, regbase + GE_ROPCODE_OFF);
113 writel(1, regbase + GE_COMMAND_OFF);
114 writel(1, regbase + GE_FIRE_OFF);
115}
116EXPORT_SYMBOL_GPL(wmt_ge_copyarea);
117
118int wmt_ge_sync(struct fb_info *p)
119{
120 int loops = 5000000;
121 while ((readl(regbase + GE_STATUS_OFF) & 4) && --loops)
122 cpu_relax();
123 return loops > 0 ? 0 : -EBUSY;
124}
125EXPORT_SYMBOL_GPL(wmt_ge_sync);
126
127static int __devinit wmt_ge_rops_probe(struct platform_device *pdev)
128{
129 struct resource *res;
130 int ret;
131
132 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
133 if (res == NULL) {
134 dev_err(&pdev->dev, "no I/O memory resource defined\n");
135 ret = -ENODEV;
136 goto error;
137 }
138
139 /* Only one ROP engine is presently supported. */
140 if (unlikely(regbase)) {
141 WARN_ON(1);
142 return -EBUSY;
143 }
144
145 regbase = ioremap(res->start, resource_size(res));
146 if (regbase == NULL) {
147 dev_err(&pdev->dev, "failed to map I/O memory\n");
148 ret = -EBUSY;
149 goto error;
150 }
151
152 writel(1, regbase + GE_ENABLE_OFF);
153 printk(KERN_INFO "Enabled support for WMT GE raster acceleration\n");
154
155 return 0;
156
157error:
158 return ret;
159}
160
161static int __devexit wmt_ge_rops_remove(struct platform_device *pdev)
162{
163 iounmap(regbase);
164 return 0;
165}
166
167static struct platform_driver wmt_ge_rops_driver = {
168 .probe = wmt_ge_rops_probe,
169 .remove = __devexit_p(wmt_ge_rops_remove),
170 .driver = {
171 .owner = THIS_MODULE,
172 .name = "wmt_ge_rops",
173 },
174};
175
176static int __init wmt_ge_rops_init(void)
177{
178 return platform_driver_register(&wmt_ge_rops_driver);
179}
180
181static void __exit wmt_ge_rops_exit(void)
182{
183 platform_driver_unregister(&wmt_ge_rops_driver);
184}
185
186module_init(wmt_ge_rops_init);
187module_exit(wmt_ge_rops_exit);
188
189MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com");
190MODULE_DESCRIPTION("Accelerators for raster operations using "
191 "WonderMedia Graphics Engine");
192MODULE_LICENSE("GPL");