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

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [drivers/] [video/] [ocfb.c] - Blame information for rev 7

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 7 xianfeng
/*
2
 * OpenCores framebuffer
3
 *
4
 * by Matjaz Breskvar (phoenix@bsemi.com)
5
 */
6
 
7
#include <linux/module.h>
8
#include <linux/kernel.h>
9
#include <linux/sched.h>
10
#include <linux/errno.h>
11
#include <linux/string.h>
12
#include <linux/mm.h>
13
#include <linux/tty.h>
14
#include <linux/slab.h>
15
#include <linux/delay.h>
16
#include <linux/init.h>
17
#include <linux/fb.h>
18
#include <linux/dio.h>
19
#include <asm/io.h>
20
 
21
static struct fb_info info;
22
static struct fb_ops ocfb_ops;
23
 
24
#define REG32(add) (*(volatile unsigned long *)(add))
25
#define REG16(add) (*(volatile unsigned short *)(add))
26
#define REG8(add) (*(volatile unsigned char *)(add))
27
 
28
/* VGA defines */
29
#define VGA_BASE      0x97000000
30
#define VGA_CTRL      0x000
31
#define VGA_STAT      0x004
32
#define VGA_HTIM      0x008
33
#define VGA_VTIM      0x00c
34
#define VGA_HVLEN     0x010
35
#define VGA_VBARA     0x014
36
 
37
static u32 pseudo_palette[16];
38
 
39
static struct fb_fix_screeninfo ocfb_rgb8_fix __initdata = {
40
        .id             = "OC VGA/LCD",
41
        .smem_len       = (640*480),
42
        .type           = FB_TYPE_PACKED_PIXELS,
43
        .visual         = FB_VISUAL_PSEUDOCOLOR,
44
        .line_length    = 640,
45
//      .accel          = FB_ACCEL_NONE,
46
};
47
 
48
static struct fb_var_screeninfo ocfb_rgb8_var __initdata = {
49
        .xres           = 640,
50
        .yres           = 480,
51
        .xres_virtual   = 640,
52
        .yres_virtual   = 480,
53
        .bits_per_pixel = 8,
54
        .grayscale      = 1,
55
        .red            = { 0,8,1},      /* R */
56
        .green          = { 0,8,1},      /* G */
57
        .blue           = { 0,8,1},      /* B */
58
        .activate       = FB_ACTIVATE_NOW,
59
        .height         = 274,
60
        .width          = 195,  /* 14" monitor */
61
        .accel_flags    = FB_ACCEL_NONE,
62
        .vmode          = FB_VMODE_NONINTERLACED,
63
};
64
 
65
static struct fb_fix_screeninfo ocfb_rgb16_fix __initdata = {
66
        .id             = "OC VGA/LCD",
67
        .smem_len       = (640*480*2),
68
        .type           = FB_TYPE_PACKED_PIXELS,
69
        .visual         = FB_VISUAL_TRUECOLOR,
70
// FB_VISUAL_TRUECOLOR, FB_VISUAL_STATIC_PSEUDOCOLOR
71
        .line_length    = 640*2,
72
};
73
 
74
static struct fb_var_screeninfo ocfb_rgb16_var __initdata = {
75
        .xres           = 640,
76
        .yres           = 480,
77
        .xres_virtual   = 640,
78
        .yres_virtual   = 480,
79
        .bits_per_pixel = 16,
80
        .red            = { .offset = 11, .length = 5, },
81
        .green          = { .offset = 5,  .length = 6, },
82
        .blue           = { .offset = 0,  .length = 5, },
83
        .transp         = { .offset = 0,  .length = 0, },
84
};
85
 
86
extern unsigned long fb_mem_start;
87
 
88
 
89
static int ocfb_setcolreg(unsigned regno, unsigned red, unsigned green,
90
                          unsigned blue, unsigned transp,
91
                          struct fb_info *info)
92
{
93
        if (regno >= info->cmap.len) {
94
                printk("ocfb_setcolreg: regno >= cmap.len\n");
95
                return(1);
96
        }
97
 
98
        switch (info->var.bits_per_pixel) {
99
        case 8:
100
                /* write color into hw */
101
                /*
102
                fb_writew(regno << 8, HD64461_CPTWAR);
103
                fb_writew(red >> 10, HD64461_CPTWDR);
104
                fb_writew(green >> 10, HD64461_CPTWDR);
105
                fb_writew(blue >> 10, HD64461_CPTWDR);
106
                */
107
                break;
108
        case 16:
109
                ((u32 *) (info->pseudo_palette))[regno] =
110
                    ((red & 0xf800)) |
111
                    ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
112
                break;
113
        }
114
        return 0;
115
 
116
}
117
 
118
 
119
void debug_write_pattern(void *fb_shmem_virt, int xsize, int ysize);
120
void init_and_enable(int xsize, int ysize, int bpp);
121
void debug_bw_tests(void);
122
 
123
/*
124
 *  Initialization
125
 */
126
int __init ocfb_init(void)
127
{
128
        void *fb_shmem_virt;
129
 
130
        printk("\n\n");
131
        printk("OpenCores VGA/LCD 2.0 core init\n");
132
        printk("\n\n");
133
 
134
        /* if we have framebuffer in main memory it always
135
         * starts after max_low_pfn (see arch/or32/kernel/setup.c)
136
         */
137
        printk("ioremap(fb_mem_start 0x%lx, size 0x%x)\n",
138
               fb_mem_start, CONFIG_FB_OC_SHMEM_SIZE);
139
        fb_shmem_virt = ioremap_nocache(fb_mem_start, CONFIG_FB_OC_SHMEM_SIZE);
140
        if (fb_shmem_virt == NULL) {
141
                printk("ocfb: ioremap of framebuffer failed\n");
142
                return -1;
143
        }
144
 
145
#if 1
146
        debug_write_pattern(fb_shmem_virt, 640, 480);
147
        init_and_enable(640, 480, 16);
148
#endif
149
 
150
#if 0
151
        debug_write_pattern(fb_shmem_virt, 800, 600);
152
        init_and_enable(800, 600, 8);
153
#endif
154
 
155
        info.par = fb_shmem_virt;
156
        info.flags = FBINFO_FLAG_DEFAULT,
157
 
158
 
159
        /*
160
         *      Let there be consoles..
161
         */
162
        info.fbops = &ocfb_ops;
163
        info.var   = ocfb_rgb16_var;
164
        info.fix   = ocfb_rgb16_fix;
165
 
166
        ocfb_rgb16_fix.smem_start = (unsigned long)fb_shmem_virt;
167
        info.screen_base    = fb_shmem_virt;
168
 
169
        info.pseudo_palette = pseudo_palette;
170
        info.flags = FBINFO_FLAG_DEFAULT;
171
 
172
        /* This has to been done !!! */
173
        fb_alloc_cmap(&info.cmap, 256, 0);
174
 
175
        if (register_framebuffer(&info) < 0)
176
                return -EINVAL;
177
        printk(KERN_INFO "fb%d: %s frame buffer device\n", info.node,
178
               info.fix.id);
179
 
180
#if 0
181
        debug_bw_tests();
182
#endif
183
 
184
        return 0;
185
}
186
 
187
static void __exit ocfb_cleanup(void)
188
{
189
        /*
190
         *  If your driver supports multiple boards, you should unregister and
191
         *  clean up all instances.
192
         */
193
 
194
//      unregister_framebuffer(info);
195
        /* ... */
196
}
197
 
198
/* --------------------------------------------[ frame buffer operations ]-- */
199
 
200
 
201
/*
202
 *  Frame buffer operations
203
 */
204
 
205
static struct fb_ops ocfb_ops = {
206
        .owner          = THIS_MODULE,
207
        .fb_setcolreg   = ocfb_setcolreg,
208
        .fb_fillrect    = cfb_fillrect,
209
        .fb_copyarea    = cfb_copyarea,
210
        .fb_imageblit   = cfb_imageblit,
211
        .fb_cursor      = soft_cursor,
212
};
213
 
214
/* ------------------------------------------------------------------------- */
215
 
216
#ifdef MODULE
217
module_init(ocfb_init);
218
module_exit(ocfb_cleanup);
219
#endif
220
 
221
MODULE_LICENSE("GPL");
222
 
223
/* ------------------------------------------------------------------------- */
224
 
225
void init_and_enable(int xsize, int ysize, int bpp)
226
{
227
        unsigned long bpp_config;
228
 
229
        printk("HL: enabling VGA pads\n");
230
        /* enable VGA pads by setting SYS MUXes */
231
        REG32(0xb8070010) = 0;
232
        REG32(0xb8070014) = 0;
233
        REG32(0xb8070018) = 0;
234
 
235
        if ((xsize == 800) && (ysize == 600)) {
236
                printk("HL: setting VGA timings: 800x600 @75Hz\n");
237
 
238
                /* VESA: 800x600@60Hz
239
                 */
240
 
241
                /* pixel clock 37.5 Mhz --> vertical frequency   56.55  Hz
242
                 *                      --> horizontal frequency 35.51 kHz
243
                 */
244
 
245
                /*
246
                 *  VERTICAL TIMINGS
247
                 *  sync pulse  :   4
248
                 *  front porch :   1
249
                 *  active frame: 600
250
                 */
251
                REG32(VGA_BASE+VGA_VTIM)  = ((  4 - 1) << 24) |
252
                                            ((  1 - 1) << 16) |
253
                                             (600 - 1);
254
 
255
                /*  HORIZONTAL TIMINGS
256
                 *  sync pulse  : 128
257
                 *  front porch :  40
258
                 *  active frame: 800
259
                 */
260
                REG32(VGA_BASE+VGA_HTIM)  = ((128 - 1) << 24) |
261
                                            (( 40 - 1) << 16) |
262
                                             (800 - 1);
263
 
264
                /* TOTAL
265
                 * horizontal total: 1056
266
                 * vertical total  : 628
267
                 */
268
                REG32(VGA_BASE+VGA_HVLEN) = ((1056 - 1) << 16) |
269
                                             ( 628 - 1);
270
                REG32(VGA_BASE+VGA_VBARA) = fb_mem_start;
271
 
272
        } else if ((xsize == 640) && (ysize == 480)) {
273
                printk("HL: setting VGA timings: 640x480 @60Hz\n");
274
 
275
                /* VESA: 640x480@60Hz
276
                 */
277
 
278
                /* pixel clock 25 Mhz --> vertical frequency   59.64 Hz
279
                 *                    --> horizontal frequency 31.25 kHz
280
                 */
281
 
282
                /*
283
                 *  VERTICAL TIMINGS
284
                 *  sync pulse  :   2
285
                 *  front porch :  11
286
                 *  active frame: 480
287
                 */
288
                REG32(VGA_BASE+VGA_VTIM)  = ((  2 - 1) << 24) |
289
                                            (( 11 - 1) << 16) |
290
                                             (480 - 1);
291
 
292
                /* HORIZONTAL TIMINGS
293
                 * sync pulse  :  96
294
                 * front porch :  16
295
                 * active frame: 640
296
                 */
297
                REG32(VGA_BASE+VGA_HTIM)  = (( 96 - 1) << 24) |
298
                                            (( 16 - 1) << 16) |
299
                                             (640 - 1);
300
 
301
                /* TOTAL
302
                 * horizontal total: 800
303
                 * vertical total  : 524
304
                 */
305
                REG32(VGA_BASE+VGA_HVLEN) = ((800 - 1) << 16) |
306
                                             (524 - 1);
307
 
308
                REG32(VGA_BASE+VGA_VBARA) = fb_mem_start;
309
 
310
        } else {
311
 
312
                printk("HL: error no VGA timings specified\n");
313
        }
314
 
315
 
316
        bpp_config = 0;
317
        if (bpp==8) {
318
                bpp_config |= 0x0;
319
        } else if (bpp==16) {
320
                bpp_config |= 0x200;
321
        } else if (bpp==24) {
322
                bpp_config |= 0x400;
323
        } else if (bpp==32) {
324
                bpp_config |= 0x600;
325
        } else {
326
                printk("HL: no bpp specified\n");
327
        }
328
 
329
 
330
        /* maximum (8) VBL (video memory burst length)*/
331
        bpp_config |= 0x180;
332
 
333
 
334
        printk("HL: enabling framebuffer (bpp==%d)\n", bpp);
335
        /* VGA enable */
336
        REG32(VGA_BASE+VGA_CTRL) = 0x00000101 | bpp_config;
337
}
338
 
339
 
340
void debug_write_pattern(void *fb_shmem_virt, int xsize, int ysize)
341
{
342
 
343
        char *fb_mem;
344
        int v,h;
345
 
346
        fb_mem = (char *)fb_shmem_virt;
347
 
348
        for (h=0;h<xsize;h++) {
349
                for (v=0;v<ysize;v++) {
350
                        if (h < 255)
351
                                fb_mem[v*xsize + h]=h;
352
                        else
353
                                fb_mem[v*xsize + h]=100;
354
                }
355
        }
356
 
357
        /* last 30 lines almost black */
358
        for (h=0;h<xsize;h++)
359
                for (v=400;v<ysize;v++)
360
                        fb_mem[v*xsize + h]=30;
361
 
362
        /* last 2 lines white */
363
        for (h=0;h<xsize;h++)
364
                for (v=478;v<ysize;v++)
365
                        fb_mem[v*xsize + h]=255;
366
 
367
 
368
}
369
 
370
void debug_bw_tests()
371
{
372
 
373
        unsigned long i;
374
        unsigned long flags, tmp;
375
        unsigned long addr=0xc0000000;
376
 
377
 
378
        printk("going into loop 2 x 10^7 cycles: IRQs on\n");
379
        for (i=0;i<20000000;i++)
380
                __asm__ __volatile__("l.nop");
381
 
382
 
383
        local_irq_save(flags);
384
        printk("going into loop 2 x 10^7 cycles: IRQs off\n");
385
        for (i=0;i<20000000;i++)
386
                __asm__ __volatile__("l.nop");
387
        local_irq_restore(flags);
388
 
389
        local_irq_save(flags);
390
        /* now to really screw him */
391
        printk("going into loop 2 x 10^7 cycles: IRQs off, loads of loads\n");
392
        for (i=0;i<5000000;i++) {
393
                __asm__ __volatile__("l.lbz %0,0x0000001(%1)" : "=r"(tmp) : "r"(addr));
394
                __asm__ __volatile__("l.lhz %0,0x1000002(%1)" : "=r"(tmp) : "r"(addr));
395
                __asm__ __volatile__("l.lwz %0,0x1800004(%1)" : "=r"(tmp) : "r"(addr));
396
 
397
                __asm__ __volatile__("l.lbz %0,0x0000201(%1)" : "=r"(tmp) : "r"(addr));
398
                __asm__ __volatile__("l.lhz %0,0x1000602(%1)" : "=r"(tmp) : "r"(addr));
399
                __asm__ __volatile__("l.lwz %0,0x1800104(%1)" : "=r"(tmp) : "r"(addr));
400
 
401
                __asm__ __volatile__("l.lbz %0,0x0000301(%1)" : "=r"(tmp) : "r"(addr));
402
                __asm__ __volatile__("l.lhz %0,0x1000702(%1)" : "=r"(tmp) : "r"(addr));
403
                __asm__ __volatile__("l.lwz %0,0x1800204(%1)" : "=r"(tmp) : "r"(addr));
404
        }
405
        local_irq_restore(flags);
406
 
407
#if 0
408
        {
409
                unsigned long *tick=0xc0000500;
410
 
411
                /* triggers a bug */
412
                local_irq_save(flags);
413
                printk("going into loop 2 x 10^7 cycles: IRQs off, tick interrupt\n");
414
                /* l.rfe at tick timer */
415
                *tick = 0x24000000;
416
                /* tick timer enable */
417
                mtspr(SPR_SR, mfspr(SPR_SR) & !SPR_SR_TEE);
418
                for (i=0;i<20000000;i++) {
419
                        __asm__ __volatile__("l.lbz %0,0x0000001(%1)" : "=r"(tmp) : "r"(addr));
420
                        __asm__ __volatile__("l.lhz %0,0x1002002(%1)" : "=r"(tmp) : "r"(addr));
421
                        __asm__ __volatile__("l.lwz %0,0x1804004(%1)" : "=r"(tmp) : "r"(addr));
422
 
423
                        __asm__ __volatile__("l.lbz %0,0x0000201(%1)" : "=r"(tmp) : "r"(addr));
424
                        __asm__ __volatile__("l.lhz %0,0x1002602(%1)" : "=r"(tmp) : "r"(addr));
425
                        __asm__ __volatile__("l.lwz %0,0x1804104(%1)" : "=r"(tmp) : "r"(addr));
426
 
427
                        __asm__ __volatile__("l.lbz %0,0x0000301(%1)" : "=r"(tmp) : "r"(addr));
428
                        __asm__ __volatile__("l.lhz %0,0x1002702(%1)" : "=r"(tmp) : "r"(addr));
429
                        __asm__ __volatile__("l.lwz %0,0x1804204(%1)" : "=r"(tmp) : "r"(addr));
430
                }
431
                local_irq_restore(flags);
432
        }
433
#endif
434
}

powered by: WebSVN 2.1.0

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