diff options
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/ati_radeon_fb.c | 50 | ||||
-rw-r--r-- | drivers/video/ati_radeon_fb.h | 4 | ||||
-rw-r--r-- | drivers/video/cfb_console.c | 200 |
3 files changed, 227 insertions, 27 deletions
diff --git a/drivers/video/ati_radeon_fb.c b/drivers/video/ati_radeon_fb.c index 9ebb0b0..4a9bd07 100644 --- a/drivers/video/ati_radeon_fb.c +++ b/drivers/video/ati_radeon_fb.c @@ -210,7 +210,7 @@ static void radeon_identify_vram(struct radeonfb_info *rinfo) * ToDo: identify these cases */ - DPRINT("radeonfb: Found %ldk of %s %d bits wide videoram\n", + DPRINT("radeonfb: Found %dk of %s %d bits wide videoram\n", rinfo->video_ram / 1024, rinfo->vram_ddr ? "DDR" : "SDRAM", rinfo->vram_width); @@ -586,18 +586,21 @@ int radeon_probe(struct radeonfb_info *rinfo) rinfo->pdev.device = did; rinfo->family = get_radeon_id_family(rinfo->pdev.device); pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, - &rinfo->fb_base_phys); + &rinfo->fb_base_bus); pci_read_config_dword(pdev, PCI_BASE_ADDRESS_2, - &rinfo->mmio_base_phys); - rinfo->fb_base_phys &= 0xfffff000; - rinfo->mmio_base_phys &= ~0x04; - - rinfo->mmio_base = (void *)rinfo->mmio_base_phys; - DPRINT("rinfo->mmio_base = 0x%x\n",rinfo->mmio_base); + &rinfo->mmio_base_bus); + rinfo->fb_base_bus &= 0xfffff000; + rinfo->mmio_base_bus &= ~0x04; + + rinfo->mmio_base = pci_bus_to_virt(pdev, rinfo->mmio_base_bus, + PCI_REGION_MEM, 0, MAP_NOCACHE); + DPRINT("rinfo->mmio_base = 0x%p bus=0x%x\n", + rinfo->mmio_base, rinfo->mmio_base_bus); rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16; DPRINT("rinfo->fb_local_base = 0x%x\n",rinfo->fb_local_base); /* PostBIOS with x86 emulater */ - BootVideoCardBIOS(pdev, NULL, 0); + if (!BootVideoCardBIOS(pdev, NULL, 0)) + return -1; /* * Check for errata @@ -610,14 +613,15 @@ int radeon_probe(struct radeonfb_info *rinfo) rinfo->mapped_vram = min_t(unsigned long, MAX_MAPPED_VRAM, rinfo->video_ram); - rinfo->fb_base = (void *)rinfo->fb_base_phys; - - DPRINT("Radeon: framebuffer base phy address 0x%08x," \ - "MMIO base phy address 0x%08x," \ - "framebuffer local base 0x%08x.\n ", - rinfo->fb_base_phys, rinfo->mmio_base_phys, - rinfo->fb_local_base); - + rinfo->fb_base = pci_bus_to_virt(pdev, rinfo->fb_base_bus, + PCI_REGION_MEM, 0, MAP_NOCACHE); + DPRINT("Radeon: framebuffer base address 0x%08x, " + "bus address 0x%08x\n" + "MMIO base address 0x%08x, bus address 0x%08x, " + "framebuffer local base 0x%08x.\n ", + (u32)rinfo->fb_base, rinfo->fb_base_bus, + (u32)rinfo->mmio_base, rinfo->mmio_base_bus, + rinfo->fb_local_base); return 0; } return -1; @@ -733,13 +737,13 @@ void *video_hw_init(void) } pGD->isaBase = CONFIG_SYS_ISA_IO_BASE_ADDRESS; - pGD->pciBase = rinfo->fb_base_phys; - pGD->frameAdrs = rinfo->fb_base_phys; + pGD->pciBase = (unsigned int)rinfo->fb_base; + pGD->frameAdrs = (unsigned int)rinfo->fb_base; pGD->memSize = 64 * 1024 * 1024; /* Cursor Start Address */ - pGD->dprBase = - (pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP) + rinfo->fb_base_phys; + pGD->dprBase = (pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP) + + (unsigned int)rinfo->fb_base; if ((pGD->dprBase & 0x0fff) != 0) { /* allign it */ pGD->dprBase &= 0xfffff000; @@ -747,8 +751,8 @@ void *video_hw_init(void) } DPRINT ("Cursor Start %x Pattern Start %x\n", pGD->dprBase, PATTERN_ADR); - pGD->vprBase = rinfo->fb_base_phys; /* Dummy */ - pGD->cprBase = rinfo->fb_base_phys; /* Dummy */ + pGD->vprBase = (unsigned int)rinfo->fb_base; /* Dummy */ + pGD->cprBase = (unsigned int)rinfo->fb_base; /* Dummy */ /* set up Hardware */ /* Clear video memory (only visible screen area) */ diff --git a/drivers/video/ati_radeon_fb.h b/drivers/video/ati_radeon_fb.h index e981f95..0659045 100644 --- a/drivers/video/ati_radeon_fb.h +++ b/drivers/video/ati_radeon_fb.h @@ -49,8 +49,8 @@ struct radeonfb_info { struct pci_device_id pdev; u16 family; - u32 fb_base_phys; - u32 mmio_base_phys; + u32 fb_base_bus; + u32 mmio_base_bus; void *mmio_base; void *fb_base; diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c index 49f0a2e..d1f47c9 100644 --- a/drivers/video/cfb_console.c +++ b/drivers/video/cfb_console.c @@ -803,8 +803,193 @@ static void inline fill_555rgb_pswap(uchar *fb, int x, #endif /* + * RLE8 bitmap support + */ + +#ifdef CONFIG_VIDEO_BMP_RLE8 +/* Pre-calculated color table entry */ +struct palette { + union { + unsigned short w; /* word */ + unsigned int dw; /* double word */ + } ce; /* color entry */ +}; + +/* + * Helper to draw encoded/unencoded run. + */ +static void draw_bitmap (uchar **fb, uchar *bm, struct palette *p, + int cnt, int enc) +{ + ulong addr = (ulong)*fb; + int *off; + int enc_off = 1; + int i; + + /* + * Setup offset of the color index in the bitmap. + * Color index of encoded run is at offset 1. + */ + off = enc ? &enc_off : &i; + + switch (VIDEO_DATA_FORMAT) { + case GDF__8BIT_INDEX: + for (i = 0; i < cnt; i++) + *(unsigned char *)addr++ = bm[*off]; + break; + case GDF_15BIT_555RGB: + case GDF_16BIT_565RGB: + /* differences handled while pre-calculating palette */ + for (i = 0; i < cnt; i++) { + *(unsigned short *)addr = p[bm[*off]].ce.w; + addr += 2; + } + break; + case GDF_32BIT_X888RGB: + for (i = 0; i < cnt; i++) { + *(unsigned long *)addr = p[bm[*off]].ce.dw; + addr += 4; + } + break; + } + *fb = (uchar *)addr; /* return modified address */ +} + +static int display_rle8_bitmap (bmp_image_t *img, int xoff, int yoff, + int width, int height) +{ + unsigned char *bm; + unsigned char *fbp; + unsigned int cnt, runlen; + int decode = 1; + int x, y, bpp, i, ncolors; + struct palette p[256]; + bmp_color_table_entry_t cte; + int green_shift, red_off; + + x = 0; + y = __le32_to_cpu(img->header.height) - 1; + ncolors = __le32_to_cpu(img->header.colors_used); + bpp = VIDEO_PIXEL_SIZE; + fbp = (unsigned char *)((unsigned int)video_fb_address + + (((y + yoff) * VIDEO_COLS) + xoff) * bpp); + + bm = (uchar *)img + __le32_to_cpu(img->header.data_offset); + + /* pre-calculate and setup palette */ + switch (VIDEO_DATA_FORMAT) { + case GDF__8BIT_INDEX: + for (i = 0; i < ncolors; i++) { + cte = img->color_table[i]; + video_set_lut (i, cte.red, cte.green, cte.blue); + } + break; + case GDF_15BIT_555RGB: + case GDF_16BIT_565RGB: + if (VIDEO_DATA_FORMAT == GDF_15BIT_555RGB) { + green_shift = 3; + red_off = 10; + } else { + green_shift = 2; + red_off = 11; + } + for (i = 0; i < ncolors; i++) { + cte = img->color_table[i]; + p[i].ce.w = SWAP16((unsigned short) + (((cte.red >> 3) << red_off) | + ((cte.green >> green_shift) << 5) | + cte.blue >> 3)); + } + break; + case GDF_32BIT_X888RGB: + for (i = 0; i < ncolors; i++) { + cte = img->color_table[i]; + p[i].ce.dw = SWAP32((cte.red << 16) | (cte.green << 8) | + cte.blue); + } + break; + default: + printf("RLE Bitmap unsupported in video mode 0x%x\n", + VIDEO_DATA_FORMAT); + return -1; + } + + while (decode) { + switch (bm[0]) { + case 0: + switch (bm[1]) { + case 0: + /* scan line end marker */ + bm += 2; + x = 0; + y--; + fbp = (unsigned char *) + ((unsigned int)video_fb_address + + (((y + yoff) * VIDEO_COLS) + + xoff) * bpp); + continue; + case 1: + /* end of bitmap data marker */ + decode = 0; + break; + case 2: + /* run offset marker */ + x += bm[2]; + y -= bm[3]; + fbp = (unsigned char *) + ((unsigned int)video_fb_address + + (((y + yoff) * VIDEO_COLS) + + x + xoff) * bpp); + bm += 4; + break; + default: + /* unencoded run */ + cnt = bm[1]; + runlen = cnt; + bm += 2; + if (y < height) { + if (x >= width) { + x += runlen; + goto next_run; + } + if (x + runlen > width) + cnt = width - x; + + draw_bitmap (&fbp, bm, p, cnt, 0); + x += runlen; + } +next_run: + bm += runlen; + if (runlen & 1) + bm++; /* 0 padding if length is odd */ + } + break; + default: + /* encoded run */ + if (y < height) { /* only draw into visible area */ + cnt = bm[0]; + runlen = cnt; + if (x >= width) { + x += runlen; + bm += 2; + continue; + } + if (x + runlen > width) + cnt = width - x; + + draw_bitmap (&fbp, bm, p, cnt, 1); + x += runlen; + } + bm += 2; + break; + } + } + return 0; +} +#endif + +/* * Display the BMP file located at address bmp_image. - * Only uncompressed */ int video_display_bitmap (ulong bmp_image, int x, int y) { @@ -872,7 +1057,11 @@ int video_display_bitmap (ulong bmp_image, int x, int y) debug ("Display-bmp: %d x %d with %d colors\n", width, height, colors); - if (compression != BMP_BI_RGB) { + if (compression != BMP_BI_RGB +#ifdef CONFIG_VIDEO_BMP_RLE8 + && compression != BMP_BI_RLE8 +#endif + ) { printf ("Error: compression type %ld not supported\n", compression); #ifdef CONFIG_VIDEO_BMP_GZIP @@ -906,6 +1095,13 @@ int video_display_bitmap (ulong bmp_image, int x, int y) ((y + height - 1) * VIDEO_COLS * VIDEO_PIXEL_SIZE) + x * VIDEO_PIXEL_SIZE); +#ifdef CONFIG_VIDEO_BMP_RLE8 + if (compression == BMP_BI_RLE8) { + return display_rle8_bitmap(bmp, + x, y, width, height); + } +#endif + /* We handle only 8bpp or 24 bpp bitmap */ switch (le16_to_cpu (bmp->header.bit_count)) { case 8: |