OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [video/] [pmag-ba-fb.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 *      linux/drivers/video/pmag-ba-fb.c
3
 *
4
 *      PMAG-BA TURBOchannel Color Frame Buffer (CFB) card support,
5
 *      derived from:
6
 *      "HP300 Topcat framebuffer support (derived from macfb of all things)
7
 *      Phil Blundell <philb@gnu.org> 1998", the original code can be
8
 *      found in the file hpfb.c in the same directory.
9
 *
10
 *      Based on digital document:
11
 *      "PMAG-BA TURBOchannel Color Frame Buffer
12
 *       Functional Specification", Revision 1.2, August 27, 1990
13
 *
14
 *      DECstation related code Copyright (C) 1999, 2000, 2001 by
15
 *      Michael Engel <engel@unix-ag.org>,
16
 *      Karsten Merker <merker@linuxtag.org> and
17
 *      Harald Koerfgen.
18
 *      Copyright (c) 2005, 2006  Maciej W. Rozycki
19
 *      Copyright (c) 2005  James Simmons
20
 *
21
 *      This file is subject to the terms and conditions of the GNU General
22
 *      Public License.  See the file COPYING in the main directory of this
23
 *      archive for more details.
24
 */
25
 
26
#include <linux/compiler.h>
27
#include <linux/errno.h>
28
#include <linux/fb.h>
29
#include <linux/init.h>
30
#include <linux/kernel.h>
31
#include <linux/module.h>
32
#include <linux/tc.h>
33
#include <linux/types.h>
34
 
35
#include <asm/io.h>
36
#include <asm/system.h>
37
 
38
#include <video/pmag-ba-fb.h>
39
 
40
 
41
struct pmagbafb_par {
42
        volatile void __iomem *mmio;
43
        volatile u32 __iomem *dac;
44
};
45
 
46
 
47
static struct fb_var_screeninfo pmagbafb_defined __initdata = {
48
        .xres           = 1024,
49
        .yres           = 864,
50
        .xres_virtual   = 1024,
51
        .yres_virtual   = 864,
52
        .bits_per_pixel = 8,
53
        .red.length     = 8,
54
        .green.length   = 8,
55
        .blue.length    = 8,
56
        .activate       = FB_ACTIVATE_NOW,
57
        .height         = -1,
58
        .width          = -1,
59
        .accel_flags    = FB_ACCEL_NONE,
60
        .pixclock       = 14452,
61
        .left_margin    = 116,
62
        .right_margin   = 12,
63
        .upper_margin   = 34,
64
        .lower_margin   = 12,
65
        .hsync_len      = 128,
66
        .vsync_len      = 3,
67
        .sync           = FB_SYNC_ON_GREEN,
68
        .vmode          = FB_VMODE_NONINTERLACED,
69
};
70
 
71
static struct fb_fix_screeninfo pmagbafb_fix __initdata = {
72
        .id             = "PMAG-BA",
73
        .smem_len       = (1024 * 1024),
74
        .type           = FB_TYPE_PACKED_PIXELS,
75
        .visual         = FB_VISUAL_PSEUDOCOLOR,
76
        .line_length    = 1024,
77
        .mmio_len       = PMAG_BA_SIZE - PMAG_BA_BT459,
78
};
79
 
80
 
81
static inline void dac_write(struct pmagbafb_par *par, unsigned int reg, u8 v)
82
{
83
        writeb(v, par->dac + reg / 4);
84
}
85
 
86
static inline u8 dac_read(struct pmagbafb_par *par, unsigned int reg)
87
{
88
        return readb(par->dac + reg / 4);
89
}
90
 
91
 
92
/*
93
 * Set the palette.
94
 */
95
static int pmagbafb_setcolreg(unsigned int regno, unsigned int red,
96
                              unsigned int green, unsigned int blue,
97
                              unsigned int transp, struct fb_info *info)
98
{
99
        struct pmagbafb_par *par = info->par;
100
 
101
        BUG_ON(regno >= info->cmap.len);
102
 
103
        red   >>= 8;    /* The cmap fields are 16 bits    */
104
        green >>= 8;    /* wide, but the hardware colormap */
105
        blue  >>= 8;    /* registers are only 8 bits wide */
106
 
107
        mb();
108
        dac_write(par, BT459_ADDR_LO, regno);
109
        dac_write(par, BT459_ADDR_HI, 0x00);
110
        wmb();
111
        dac_write(par, BT459_CMAP, red);
112
        wmb();
113
        dac_write(par, BT459_CMAP, green);
114
        wmb();
115
        dac_write(par, BT459_CMAP, blue);
116
 
117
        return 0;
118
}
119
 
120
static struct fb_ops pmagbafb_ops = {
121
        .owner          = THIS_MODULE,
122
        .fb_setcolreg   = pmagbafb_setcolreg,
123
        .fb_fillrect    = cfb_fillrect,
124
        .fb_copyarea    = cfb_copyarea,
125
        .fb_imageblit   = cfb_imageblit,
126
};
127
 
128
 
129
/*
130
 * Turn the hardware cursor off.
131
 */
132
static void __init pmagbafb_erase_cursor(struct fb_info *info)
133
{
134
        struct pmagbafb_par *par = info->par;
135
 
136
        mb();
137
        dac_write(par, BT459_ADDR_LO, 0x00);
138
        dac_write(par, BT459_ADDR_HI, 0x03);
139
        wmb();
140
        dac_write(par, BT459_DATA, 0x00);
141
}
142
 
143
 
144
static int __init pmagbafb_probe(struct device *dev)
145
{
146
        struct tc_dev *tdev = to_tc_dev(dev);
147
        resource_size_t start, len;
148
        struct fb_info *info;
149
        struct pmagbafb_par *par;
150
        int err;
151
 
152
        info = framebuffer_alloc(sizeof(struct pmagbafb_par), dev);
153
        if (!info) {
154
                printk(KERN_ERR "%s: Cannot allocate memory\n", dev->bus_id);
155
                return -ENOMEM;
156
        }
157
 
158
        par = info->par;
159
        dev_set_drvdata(dev, info);
160
 
161
        if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
162
                printk(KERN_ERR "%s: Cannot allocate color map\n",
163
                       dev->bus_id);
164
                err = -ENOMEM;
165
                goto err_alloc;
166
        }
167
 
168
        info->fbops = &pmagbafb_ops;
169
        info->fix = pmagbafb_fix;
170
        info->var = pmagbafb_defined;
171
        info->flags = FBINFO_DEFAULT;
172
 
173
        /* Request the I/O MEM resource.  */
174
        start = tdev->resource.start;
175
        len = tdev->resource.end - start + 1;
176
        if (!request_mem_region(start, len, dev->bus_id)) {
177
                printk(KERN_ERR "%s: Cannot reserve FB region\n", dev->bus_id);
178
                err = -EBUSY;
179
                goto err_cmap;
180
        }
181
 
182
        /* MMIO mapping setup.  */
183
        info->fix.mmio_start = start;
184
        par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
185
        if (!par->mmio) {
186
                printk(KERN_ERR "%s: Cannot map MMIO\n", dev->bus_id);
187
                err = -ENOMEM;
188
                goto err_resource;
189
        }
190
        par->dac = par->mmio + PMAG_BA_BT459;
191
 
192
        /* Frame buffer mapping setup.  */
193
        info->fix.smem_start = start + PMAG_BA_FBMEM;
194
        info->screen_base = ioremap_nocache(info->fix.smem_start,
195
                                            info->fix.smem_len);
196
        if (!info->screen_base) {
197
                printk(KERN_ERR "%s: Cannot map FB\n", dev->bus_id);
198
                err = -ENOMEM;
199
                goto err_mmio_map;
200
        }
201
        info->screen_size = info->fix.smem_len;
202
 
203
        pmagbafb_erase_cursor(info);
204
 
205
        err = register_framebuffer(info);
206
        if (err < 0) {
207
                printk(KERN_ERR "%s: Cannot register framebuffer\n",
208
                       dev->bus_id);
209
                goto err_smem_map;
210
        }
211
 
212
        get_device(dev);
213
 
214
        pr_info("fb%d: %s frame buffer device at %s\n",
215
                info->node, info->fix.id, dev->bus_id);
216
 
217
        return 0;
218
 
219
 
220
err_smem_map:
221
        iounmap(info->screen_base);
222
 
223
err_mmio_map:
224
        iounmap(par->mmio);
225
 
226
err_resource:
227
        release_mem_region(start, len);
228
 
229
err_cmap:
230
        fb_dealloc_cmap(&info->cmap);
231
 
232
err_alloc:
233
        framebuffer_release(info);
234
        return err;
235
}
236
 
237
static int __exit pmagbafb_remove(struct device *dev)
238
{
239
        struct tc_dev *tdev = to_tc_dev(dev);
240
        struct fb_info *info = dev_get_drvdata(dev);
241
        struct pmagbafb_par *par = info->par;
242
        resource_size_t start, len;
243
 
244
        put_device(dev);
245
        unregister_framebuffer(info);
246
        iounmap(info->screen_base);
247
        iounmap(par->mmio);
248
        start = tdev->resource.start;
249
        len = tdev->resource.end - start + 1;
250
        release_mem_region(start, len);
251
        fb_dealloc_cmap(&info->cmap);
252
        framebuffer_release(info);
253
        return 0;
254
}
255
 
256
 
257
/*
258
 * Initialize the framebuffer.
259
 */
260
static const struct tc_device_id pmagbafb_tc_table[] = {
261
        { "DEC     ", "PMAG-BA " },
262
        { }
263
};
264
MODULE_DEVICE_TABLE(tc, pmagbafb_tc_table);
265
 
266
static struct tc_driver pmagbafb_driver = {
267
        .id_table       = pmagbafb_tc_table,
268
        .driver         = {
269
                .name   = "pmagbafb",
270
                .bus    = &tc_bus_type,
271
                .probe  = pmagbafb_probe,
272
                .remove = __exit_p(pmagbafb_remove),
273
        },
274
};
275
 
276
static int __init pmagbafb_init(void)
277
{
278
#ifndef MODULE
279
        if (fb_get_options("pmagbafb", NULL))
280
                return -ENXIO;
281
#endif
282
        return tc_register_driver(&pmagbafb_driver);
283
}
284
 
285
static void __exit pmagbafb_exit(void)
286
{
287
        tc_unregister_driver(&pmagbafb_driver);
288
}
289
 
290
 
291
module_init(pmagbafb_init);
292
module_exit(pmagbafb_exit);
293
 
294
MODULE_LICENSE("GPL");

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.