~ubuntu-branches/ubuntu/maverick/u-boot-omap3/maverick

« back to all changes in this revision

Viewing changes to drivers/video/mb862xx.c

  • Committer: Bazaar Package Importer
  • Author(s): Oliver Grawert
  • Date: 2010-03-22 15:06:23 UTC
  • Revision ID: james.westby@ubuntu.com-20100322150623-i21g8rgiyl5dohag
Tags: upstream-2010.3git20100315
ImportĀ upstreamĀ versionĀ 2010.3git20100315

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * (C) Copyright 2007
 
3
 * DENX Software Engineering, Anatolij Gustschin, agust@denx.de
 
4
 *
 
5
 * See file CREDITS for list of people who contributed to this
 
6
 * project.
 
7
 *
 
8
 * This program is free software; you can redistribute it and/or
 
9
 * modify it under the terms of the GNU General Public License as
 
10
 * published by the Free Software Foundation; either version 2 of
 
11
 * the License, or (at your option) any later version.
 
12
 *
 
13
 * This program is distributed in the hope that it will be useful,
 
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
 * GNU General Public License for more details.
 
17
 *
 
18
 * You should have received a copy of the GNU General Public License
 
19
 * along with this program; if not, write to the Free Software
 
20
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 
21
 * MA 02111-1307 USA
 
22
 */
 
23
 
 
24
/*
 
25
 * mb862xx.c - Graphic interface for Fujitsu CoralP/Lime
 
26
 * PCI and video mode code was derived from smiLynxEM driver.
 
27
 */
 
28
 
 
29
#include <common.h>
 
30
 
 
31
#include <asm/io.h>
 
32
#include <pci.h>
 
33
#include <video_fb.h>
 
34
#include "videomodes.h"
 
35
#include <mb862xx.h>
 
36
 
 
37
#if defined(CONFIG_POST)
 
38
#include <post.h>
 
39
#endif
 
40
 
 
41
/*
 
42
 * Graphic Device
 
43
 */
 
44
GraphicDevice mb862xx;
 
45
 
 
46
/*
 
47
 * 32MB external RAM - 256K Chip MMIO = 0x1FC0000 ;
 
48
 */
 
49
#define VIDEO_MEM_SIZE  0x01FC0000
 
50
 
 
51
#if defined(CONFIG_PCI)
 
52
#if defined(CONFIG_VIDEO_CORALP)
 
53
 
 
54
static struct pci_device_id supported[] = {
 
55
        { PCI_VENDOR_ID_FUJITSU, PCI_DEVICE_ID_CORAL_P },
 
56
        { PCI_VENDOR_ID_FUJITSU, PCI_DEVICE_ID_CORAL_PA },
 
57
        { }
 
58
};
 
59
 
 
60
/* Internal clock frequency divider table, index is mode number */
 
61
unsigned int fr_div[] = { 0x00000f00, 0x00000900, 0x00000500 };
 
62
#endif
 
63
#endif
 
64
 
 
65
#if defined(CONFIG_VIDEO_CORALP)
 
66
#define rd_io           in32r
 
67
#define wr_io           out32r
 
68
#else
 
69
#define rd_io(addr)     in_be32((volatile unsigned *)(addr))
 
70
#define wr_io(addr, val)        out_be32((volatile unsigned *)(addr), (val))
 
71
#endif
 
72
 
 
73
#define HOST_RD_REG(off)        rd_io((dev->frameAdrs + GC_HOST_BASE + (off)))
 
74
#define HOST_WR_REG(off, val)   wr_io((dev->frameAdrs + GC_HOST_BASE + (off)), \
 
75
                                      (val))
 
76
#define DISP_RD_REG(off)        rd_io((dev->frameAdrs + GC_DISP_BASE + (off)))
 
77
#define DISP_WR_REG(off, val)   wr_io((dev->frameAdrs + GC_DISP_BASE + (off)), \
 
78
                                      (val))
 
79
#define DE_RD_REG(off)          rd_io((dev->dprBase + (off)))
 
80
#define DE_WR_REG(off, val)     wr_io((dev->dprBase + (off)), (val))
 
81
 
 
82
#if defined(CONFIG_VIDEO_CORALP)
 
83
#define DE_WR_FIFO(val)         wr_io((dev->dprBase + (GC_GEO_FIFO)), (val))
 
84
#else
 
85
#define DE_WR_FIFO(val)         wr_io((dev->dprBase + (GC_FIFO)), (val))
 
86
#endif
 
87
 
 
88
#define L0PAL_WR_REG(idx, val)  wr_io((dev->frameAdrs + \
 
89
                                       (GC_DISP_BASE | GC_L0PAL0) + \
 
90
                                       ((idx) << 2)), (val))
 
91
 
 
92
#if defined(CONFIG_VIDEO_MB862xx_ACCEL)
 
93
static void gdc_sw_reset (void)
 
94
{
 
95
        GraphicDevice *dev = &mb862xx;
 
96
 
 
97
        HOST_WR_REG (GC_SRST, 0x1);
 
98
        udelay (500);
 
99
        video_hw_init ();
 
100
}
 
101
 
 
102
 
 
103
static void de_wait (void)
 
104
{
 
105
        GraphicDevice *dev = &mb862xx;
 
106
        int lc = 0x10000;
 
107
 
 
108
        /*
 
109
         * Sync with software writes to framebuffer,
 
110
         * try to reset if engine locked
 
111
         */
 
112
        while (DE_RD_REG (GC_CTR) & 0x00000131)
 
113
                if (lc-- < 0) {
 
114
                        gdc_sw_reset ();
 
115
                        puts ("gdc reset done after drawing engine lock.\n");
 
116
                        break;
 
117
                }
 
118
}
 
119
 
 
120
static void de_wait_slots (int slots)
 
121
{
 
122
        GraphicDevice *dev = &mb862xx;
 
123
        int lc = 0x10000;
 
124
 
 
125
        /* Wait for free fifo slots */
 
126
        while (DE_RD_REG (GC_IFCNT) < slots)
 
127
                if (lc-- < 0) {
 
128
                        gdc_sw_reset ();
 
129
                        puts ("gdc reset done after drawing engine lock.\n");
 
130
                        break;
 
131
                }
 
132
}
 
133
#endif
 
134
 
 
135
#if !defined(CONFIG_VIDEO_CORALP)
 
136
static void board_disp_init (void)
 
137
{
 
138
        GraphicDevice *dev = &mb862xx;
 
139
        const gdc_regs *regs = board_get_regs ();
 
140
 
 
141
        while (regs->index) {
 
142
                DISP_WR_REG (regs->index, regs->value);
 
143
                regs++;
 
144
        }
 
145
}
 
146
#endif
 
147
 
 
148
/*
 
149
 * Init drawing engine if accel enabled.
 
150
 * Also clears visible framebuffer.
 
151
 */
 
152
static void de_init (void)
 
153
{
 
154
        GraphicDevice *dev = &mb862xx;
 
155
#if defined(CONFIG_VIDEO_MB862xx_ACCEL)
 
156
        int cf = (dev->gdfBytesPP == 1) ? 0x0000 : 0x8000;
 
157
 
 
158
        dev->dprBase = dev->frameAdrs + GC_DRAW_BASE;
 
159
 
 
160
        /* Setup mode and fbbase, xres, fg, bg */
 
161
        de_wait_slots (2);
 
162
        DE_WR_FIFO (0xf1010108);
 
163
        DE_WR_FIFO (cf | 0x0300);
 
164
        DE_WR_REG (GC_FBR, 0x0);
 
165
        DE_WR_REG (GC_XRES, dev->winSizeX);
 
166
        DE_WR_REG (GC_FC, 0x0);
 
167
        DE_WR_REG (GC_BC, 0x0);
 
168
        /* Reset clipping */
 
169
        DE_WR_REG (GC_CXMIN, 0x0);
 
170
        DE_WR_REG (GC_CXMAX, dev->winSizeX);
 
171
        DE_WR_REG (GC_CYMIN, 0x0);
 
172
        DE_WR_REG (GC_CYMAX, dev->winSizeY);
 
173
 
 
174
        /* Clear framebuffer using drawing engine */
 
175
        de_wait_slots (3);
 
176
        DE_WR_FIFO (0x09410000);
 
177
        DE_WR_FIFO (0x00000000);
 
178
        DE_WR_FIFO (dev->winSizeY << 16 | dev->winSizeX);
 
179
        /* sync with SW access to framebuffer */
 
180
        de_wait ();
 
181
#else
 
182
        unsigned int i, *p;
 
183
 
 
184
        i = dev->winSizeX * dev->winSizeY;
 
185
        p = (unsigned int *)dev->frameAdrs;
 
186
        while (i--)
 
187
                *p++ = 0;
 
188
#endif
 
189
}
 
190
 
 
191
#if defined(CONFIG_VIDEO_CORALP)
 
192
unsigned int pci_video_init (void)
 
193
{
 
194
        GraphicDevice *dev = &mb862xx;
 
195
        pci_dev_t devbusfn;
 
196
 
 
197
        if ((devbusfn = pci_find_devices (supported, 0)) < 0) {
 
198
                puts ("PCI video controller not found!\n");
 
199
                return 0;
 
200
        }
 
201
 
 
202
        /* PCI setup */
 
203
        pci_write_config_dword (devbusfn, PCI_COMMAND,
 
204
                                (PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
 
205
        pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, &dev->frameAdrs);
 
206
        dev->frameAdrs = pci_mem_to_phys (devbusfn, dev->frameAdrs);
 
207
 
 
208
        if (dev->frameAdrs == 0) {
 
209
                puts ("PCI config: failed to get base address\n");
 
210
                return 0;
 
211
        }
 
212
 
 
213
        dev->pciBase = dev->frameAdrs;
 
214
 
 
215
        /* Setup clocks and memory mode for Coral-P Eval. Board */
 
216
        HOST_WR_REG (GC_CCF, 0x00090000);
 
217
        udelay (200);
 
218
        HOST_WR_REG (GC_MMR, 0x11d7fa13);
 
219
        udelay (100);
 
220
        return dev->frameAdrs;
 
221
}
 
222
 
 
223
unsigned int card_init (void)
 
224
{
 
225
        GraphicDevice *dev = &mb862xx;
 
226
        unsigned int cf, videomode, div = 0;
 
227
        unsigned long t1, hsync, vsync;
 
228
        char *penv;
 
229
        int tmp, i, bpp;
 
230
        struct ctfb_res_modes *res_mode;
 
231
        struct ctfb_res_modes var_mode;
 
232
 
 
233
        memset (dev, 0, sizeof (GraphicDevice));
 
234
 
 
235
        if (!pci_video_init ())
 
236
                return 0;
 
237
 
 
238
        puts ("CoralP\n");
 
239
 
 
240
        tmp = 0;
 
241
        videomode = 0x310;
 
242
        /* get video mode via environment */
 
243
        if ((penv = getenv ("videomode")) != NULL) {
 
244
                /* decide if it is a string */
 
245
                if (penv[0] <= '9') {
 
246
                        videomode = (int) simple_strtoul (penv, NULL, 16);
 
247
                        tmp = 1;
 
248
                }
 
249
        } else {
 
250
                tmp = 1;
 
251
        }
 
252
 
 
253
        if (tmp) {
 
254
                /* parameter are vesa modes, search params */
 
255
                for (i = 0; i < VESA_MODES_COUNT; i++) {
 
256
                        if (vesa_modes[i].vesanr == videomode)
 
257
                                break;
 
258
                }
 
259
                if (i == VESA_MODES_COUNT) {
 
260
                        printf ("\tno VESA Mode found, fallback to mode 0x%x\n",
 
261
                                videomode);
 
262
                        i = 0;
 
263
                }
 
264
                res_mode = (struct ctfb_res_modes *)
 
265
                           &res_mode_init[vesa_modes[i].resindex];
 
266
                if (vesa_modes[i].resindex > 2) {
 
267
                        puts ("\tUnsupported resolution, using default\n");
 
268
                        bpp = vesa_modes[1].bits_per_pixel;
 
269
                        div = fr_div[1];
 
270
                }
 
271
                bpp = vesa_modes[i].bits_per_pixel;
 
272
                div = fr_div[vesa_modes[i].resindex];
 
273
        } else {
 
274
                res_mode = (struct ctfb_res_modes *) &var_mode;
 
275
                bpp = video_get_params (res_mode, penv);
 
276
        }
 
277
 
 
278
        /* calculate hsync and vsync freq (info only) */
 
279
        t1 = (res_mode->left_margin + res_mode->xres +
 
280
              res_mode->right_margin + res_mode->hsync_len) / 8;
 
281
        t1 *= 8;
 
282
        t1 *= res_mode->pixclock;
 
283
        t1 /= 1000;
 
284
        hsync = 1000000000L / t1;
 
285
        t1 *= (res_mode->upper_margin + res_mode->yres +
 
286
               res_mode->lower_margin + res_mode->vsync_len);
 
287
        t1 /= 1000;
 
288
        vsync = 1000000000L / t1;
 
289
 
 
290
        /* fill in Graphic device struct */
 
291
        sprintf (dev->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres,
 
292
                 res_mode->yres, bpp, (hsync / 1000), (vsync / 1000));
 
293
        printf ("\t%s\n", dev->modeIdent);
 
294
        dev->winSizeX = res_mode->xres;
 
295
        dev->winSizeY = res_mode->yres;
 
296
        dev->memSize = VIDEO_MEM_SIZE;
 
297
 
 
298
        switch (bpp) {
 
299
        case 8:
 
300
                dev->gdfIndex = GDF__8BIT_INDEX;
 
301
                dev->gdfBytesPP = 1;
 
302
                break;
 
303
        case 15:
 
304
        case 16:
 
305
                dev->gdfIndex = GDF_15BIT_555RGB;
 
306
                dev->gdfBytesPP = 2;
 
307
                break;
 
308
        default:
 
309
                printf ("\t%d bpp configured, but only 8,15 and 16 supported\n",
 
310
                        bpp);
 
311
                puts ("\tfallback to 15bpp\n");
 
312
                dev->gdfIndex = GDF_15BIT_555RGB;
 
313
                dev->gdfBytesPP = 2;
 
314
        }
 
315
 
 
316
        /* Setup dot clock (internal pll, division rate) */
 
317
        DISP_WR_REG (GC_DCM1, div);
 
318
        /* L0 init */
 
319
        cf = (dev->gdfBytesPP == 1) ? 0x00000000 : 0x80000000;
 
320
        DISP_WR_REG (GC_L0M, ((dev->winSizeX * dev->gdfBytesPP) / 64) << 16 |
 
321
                             (dev->winSizeY - 1) | cf);
 
322
        DISP_WR_REG (GC_L0OA0, 0x0);
 
323
        DISP_WR_REG (GC_L0DA0, 0x0);
 
324
        DISP_WR_REG (GC_L0DY_L0DX, 0x0);
 
325
        DISP_WR_REG (GC_L0EM, 0x0);
 
326
        DISP_WR_REG (GC_L0WY_L0WX, 0x0);
 
327
        DISP_WR_REG (GC_L0WH_L0WW, (dev->winSizeY - 1) << 16 | dev->winSizeX);
 
328
 
 
329
        /* Display timing init */
 
330
        DISP_WR_REG (GC_HTP_A, (dev->winSizeX +
 
331
                                res_mode->left_margin +
 
332
                                res_mode->right_margin +
 
333
                                res_mode->hsync_len - 1) << 16);
 
334
        DISP_WR_REG (GC_HDB_HDP_A, (dev->winSizeX - 1) << 16 |
 
335
                                   (dev->winSizeX - 1));
 
336
        DISP_WR_REG (GC_VSW_HSW_HSP_A,  (res_mode->vsync_len - 1) << 24 |
 
337
                                        (res_mode->hsync_len - 1) << 16 |
 
338
                                        (dev->winSizeX +
 
339
                                         res_mode->right_margin - 1));
 
340
        DISP_WR_REG (GC_VTR_A, (dev->winSizeY + res_mode->lower_margin +
 
341
                                res_mode->upper_margin +
 
342
                                res_mode->vsync_len - 1) << 16);
 
343
        DISP_WR_REG (GC_VDP_VSP_A, (dev->winSizeY-1) << 16 |
 
344
                                   (dev->winSizeY +
 
345
                                    res_mode->lower_margin - 1));
 
346
        DISP_WR_REG (GC_WY_WX, 0x0);
 
347
        DISP_WR_REG (GC_WH_WW, dev->winSizeY << 16 | dev->winSizeX);
 
348
        /* Display enable, L0 layer */
 
349
        DISP_WR_REG (GC_DCM1, 0x80010000 | div);
 
350
 
 
351
        return dev->frameAdrs;
 
352
}
 
353
#endif
 
354
 
 
355
 
 
356
#if !defined(CONFIG_VIDEO_CORALP)
 
357
int mb862xx_probe(unsigned int addr)
 
358
{
 
359
        GraphicDevice *dev = &mb862xx;
 
360
        unsigned int reg;
 
361
 
 
362
        dev->frameAdrs = addr;
 
363
        dev->dprBase = dev->frameAdrs + GC_DRAW_BASE;
 
364
 
 
365
        /* Try to access GDC ID/Revision registers */
 
366
        reg = HOST_RD_REG (GC_CID);
 
367
        reg = HOST_RD_REG (GC_CID);
 
368
        if (reg == 0x303) {
 
369
                reg = DE_RD_REG(GC_REV);
 
370
                reg = DE_RD_REG(GC_REV);
 
371
                if ((reg & ~0xff) == 0x20050100)
 
372
                        return MB862XX_TYPE_LIME;
 
373
        }
 
374
 
 
375
        return 0;
 
376
}
 
377
#endif
 
378
 
 
379
void *video_hw_init (void)
 
380
{
 
381
        GraphicDevice *dev = &mb862xx;
 
382
 
 
383
        puts ("Video: Fujitsu ");
 
384
 
 
385
        memset (dev, 0, sizeof (GraphicDevice));
 
386
 
 
387
#if defined(CONFIG_VIDEO_CORALP)
 
388
        if (card_init () == 0)
 
389
                return NULL;
 
390
#else
 
391
        /*
 
392
         * Preliminary init of the onboard graphic controller,
 
393
         * retrieve base address
 
394
         */
 
395
        if ((dev->frameAdrs = board_video_init ()) == 0) {
 
396
                puts ("Controller not found!\n");
 
397
                return NULL;
 
398
        } else {
 
399
                puts ("Lime\n");
 
400
 
 
401
                /* Set Change of Clock Frequency Register */
 
402
                HOST_WR_REG (GC_CCF, CONFIG_SYS_MB862xx_CCF);
 
403
                /* Delay required */
 
404
                udelay(300);
 
405
                /* Set Memory I/F Mode Register) */
 
406
                HOST_WR_REG (GC_MMR, CONFIG_SYS_MB862xx_MMR);
 
407
        }
 
408
#endif
 
409
 
 
410
        de_init ();
 
411
 
 
412
#if !defined(CONFIG_VIDEO_CORALP)
 
413
        board_disp_init ();
 
414
#endif
 
415
 
 
416
#if (defined(CONFIG_LWMON5) || \
 
417
     defined(CONFIG_SOCRATES)) && !(CONFIG_POST & CONFIG_SYS_POST_SYSMON)
 
418
        /* Lamp on */
 
419
        board_backlight_switch (1);
 
420
#endif
 
421
 
 
422
        return dev;
 
423
}
 
424
 
 
425
/*
 
426
 * Set a RGB color in the LUT
 
427
 */
 
428
void video_set_lut (unsigned int index, unsigned char r,
 
429
                    unsigned char g, unsigned char b)
 
430
{
 
431
        GraphicDevice *dev = &mb862xx;
 
432
 
 
433
        L0PAL_WR_REG (index, (r << 16) | (g << 8) | (b));
 
434
}
 
435
 
 
436
#if defined(CONFIG_VIDEO_MB862xx_ACCEL)
 
437
/*
 
438
 * Drawing engine Fill and BitBlt screen region
 
439
 */
 
440
void video_hw_rectfill (unsigned int bpp, unsigned int dst_x,
 
441
                        unsigned int dst_y, unsigned int dim_x,
 
442
                        unsigned int dim_y, unsigned int color)
 
443
{
 
444
        GraphicDevice *dev = &mb862xx;
 
445
 
 
446
        de_wait_slots (3);
 
447
        DE_WR_REG (GC_FC, color);
 
448
        DE_WR_FIFO (0x09410000);
 
449
        DE_WR_FIFO ((dst_y << 16) | dst_x);
 
450
        DE_WR_FIFO ((dim_y << 16) | dim_x);
 
451
        de_wait ();
 
452
}
 
453
 
 
454
void video_hw_bitblt (unsigned int bpp, unsigned int src_x,
 
455
                      unsigned int src_y, unsigned int dst_x,
 
456
                      unsigned int dst_y, unsigned int width,
 
457
                      unsigned int height)
 
458
{
 
459
        GraphicDevice *dev = &mb862xx;
 
460
        unsigned int ctrl = 0x0d000000L;
 
461
 
 
462
        if (src_x >= dst_x && src_y >= dst_y)
 
463
                ctrl |= 0x00440000L;
 
464
        else if (src_x >= dst_x && src_y <= dst_y)
 
465
                ctrl |= 0x00460000L;
 
466
        else if (src_x <= dst_x && src_y >= dst_y)
 
467
                ctrl |= 0x00450000L;
 
468
        else
 
469
                ctrl |= 0x00470000L;
 
470
 
 
471
        de_wait_slots (4);
 
472
        DE_WR_FIFO (ctrl);
 
473
        DE_WR_FIFO ((src_y << 16) | src_x);
 
474
        DE_WR_FIFO ((dst_y << 16) | dst_x);
 
475
        DE_WR_FIFO ((height << 16) | width);
 
476
        de_wait (); /* sync */
 
477
}
 
478
#endif