Date:2011-04-29 02:30:45 (12 years 10 months ago)
Author:Werner Almesberger
Commit:71c9c7dd786aac13db8a390593317cd82b03a99b
Message:ubb-vga2: new option -m to select the display mode (resolution, timing)

- ubb-vga2.c (XREs, YRES, res, res_db, setup, line, hdelay, frame,
session): replaced hard-coded display characteristics with a mode
database
- ubb-vga2.c (usage, main): new option -m to select the display mode
- ubb-vga2.c (session): allocate frame buffer dynamically
- ubb-vga2.c (session): since we no longer prefetch, we don't need to
allocate space beyond the end of the frame buffer
- ubb-vga2.c (line): resurrected "quick load" and extended it to fill the
FIFO completely
Files: ubb-vga/ubb-vga2.c (12 diffs)

Change Details

ubb-vga/ubb-vga2.c
3838#include "ubb-vga.h"
3939
4040
41#define XRES 640
42#define YRES 480
43
44
4541#define REG_BASE_PTR base
4642
4743static volatile void *base;
...... 
190186/* ----- Frame buffer output ----------------------------------------------- */
191187
192188
193static int line_words = XRES/8;
194//static int line_cycles = US(36); /* nominally 31.77 us, but we're too slow */
195//static int line_cycles = US(32); /* nominally 31.77 us, but we're too slow */
196static int line_cycles = US(29.7); /* nominally 31.77 us, but we're too fast */
197/*
198 * Note: 29.6 is already too short. Tricky timing.
199 */
189static const struct mode {
190    const char *name;
191    int xres, yres;
192    int line_words; /* xres/8 */
193    int clkdiv; /* pixel clock = 336 MHz/(clkdiv+1) */
194    int line_cycles; /* 31.77 us for official VGA */
195    int hsync_end; /* 0.79+3.77 us for official VGA */
196} mode_db[] = {
197    { "640x480", 640, 480, 640/8, 11, US(29.7), US(0.79+3.77-0.3) },
198    { "800x600", 800, 600, 800/8, 8, US(28.7), US(2.0+3.3+0.3) },
199    /* the next one may work after adjusting the timing in "frame" */
200    { "800x600", 800, 600, 800/8, 8, US(28.2), US(2.0+3.3+0.3-0.3) },
201    /* the 1024x768 below is not great but has good parameter tolerance */
202    { "1024x768", 1024, 768, 1024/8, 8, US(36.0), US(2.0+3.3) },
203    /* illustrate underruns */
204    { "1024x768ur", 1024, 768, 1024/8, 7, US(33.5), US(0.4+2.1+0.5) },
205    { NULL }
206}, *mode = mode_db;
207
200208
201209void setup(void)
202210{
...... 
209217    PDDATS = VSYNC | HSYNC;
210218    PDDATC = R | G | B | Y;
211219
212// *msccdr = 20; /* set the MSC clock to 336 MHz / 21 = 16 MHz */
213    MSCCDR = 11; /* set the MSC clock to 336 MHz / 12 = 28 MHz */
220    MSCCDR = mode->clkdiv; /* set the MSC clock to 336 MHz / 12 = 28 MHz */
214221    CLKGR &= ~(1 << 7); /* enable MSC clock */
215222    MSC_CLKRT = 0; /* bus clock = MSC clock / 1 */
216223}
...... 
236243
237244    PDDATC = HSYNC;
238245    MSC_STRPCL = 2; /* start MMC clock output */
246    MSC_RESTO = 0xffff;
239247
240248    MSC_CMDAT =
241249        (1 << 10) | /* 4 bit bus */
...... 
245253
246254    MSC_STRPCL = 4; /* START_OP */
247255
248    until(US(0.79+3.77-0.3));
256    until(mode->hsync_end);
249257    /*
250258     * Adjustment value tests with the XEN-1510:
251259     *
...... 
283291     * of the delay to shovel bits into the MSC's FIFO.
284292     */
285293
286#if 0 /* quick load */
287    MSC_TXFIFO = *p++;
288    MSC_TXFIFO = *p++;
294#if 1 /* quick load */
295    MSC_TXFIFO = *p++; MSC_TXFIFO = *p++; MSC_TXFIFO = *p++;
296    MSC_TXFIFO = *p++; MSC_TXFIFO = *p++; MSC_TXFIFO = *p++;
297    MSC_TXFIFO = *p++; MSC_TXFIFO = *p++; MSC_TXFIFO = *p++;
298    MSC_TXFIFO = *p++; MSC_TXFIFO = *p++; MSC_TXFIFO = *p++;
299    MSC_TXFIFO = *p++; MSC_TXFIFO = *p++; MSC_TXFIFO = *p++;
289300#endif
290    while (p != line+line_words) {
301    while (p != line+mode->line_words) {
291302        uint8_t st;
292303        do {
293304            st = MSC_STAT;
...... 
301312    }
302313
303314fail:
304    until(line_cycles);
315    until(mode->line_cycles);
305316}
306317
307318
...... 
312323        PDDATC = HSYNC;
313324        until(US(3.77));
314325        PDDATS = HSYNC;
315        until(line_cycles);
326        until(mode->line_cycles);
316327    }
317328}
318329
...... 
338349    PDDATC = HSYNC;
339350    until(US(3.77));
340351    PDDATS = HSYNC;
341    until(line_cycles-US(0.79));
352    until(mode->line_cycles-US(0.79));
342353
343    for (p = f; p != f+YRES*line_words; p += line_words)
354    for (p = f; p != f+mode->yres*mode->line_words; p += mode->line_words)
344355        line(p);
345356
346357    /* Back porch */
...... 
353364
354365static void session(void (*gen)(void *fb, int xres, int yres), int frames)
355366{
356    uint32_t f[YRES*(line_words+1)];
367    uint32_t *f;
357368    int i;
358369
370    f = malloc((mode->yres*mode->line_words)*4);
371    if (!f) {
372        perror("malloc");
373        exit(1);
374    }
359375    memset(f, 0, sizeof(f));
360376    ccube_init();
361    gen(f, XRES, YRES);
377    gen(f, mode->xres, mode->yres);
362378
363379    disable_interrupts();
364380
...... 
372388static void usage(const char *name)
373389{
374390    fprintf(stderr,
375"usage: %s [-t] frames [file]\n\n"
391"usage: %s [-t] [-r resolution] frames [file]\n\n"
376392" frames number of frames to display\n"
377393" file PPM file\n\n"
378" -t generate a test image\n"
379    , name);
394" -m mode select the display mode, default \"%s\"\n"
395" -t generate a test image\n"
396    , name, mode_db[0].name);
380397    exit(1);
381398}
382399
...... 
387404    int frames;
388405    int c;
389406
390    while ((c = getopt(argc, argv, "t")) != EOF)
407    while ((c = getopt(argc, argv, "m:t")) != EOF)
391408        switch (c) {
409        case 'm':
410            for (mode = mode_db; mode->name; mode++)
411                if (!strcmp(mode->name, optarg))
412                    break;
413            if (!mode) {
414                fprintf(stderr, "no resolution \"%s\"\n",
415                    optarg);
416                exit(1);
417            }
418            break;
392419        case 't':
393420            gen = tstimg;
394421            break;

Archive Download the corresponding diff file

Branches:
master



interactive