diff options
| -rw-r--r-- | README | 6 | ||||
| -rw-r--r-- | common/cmd_usb.c | 13 | ||||
| -rw-r--r-- | common/usb_storage.c | 6 | ||||
| -rw-r--r-- | drivers/bios_emulator/atibios.c | 13 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-hcd.c | 38 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-pci.c | 1 | ||||
| -rw-r--r-- | drivers/video/ati_radeon_fb.c | 48 | ||||
| -rw-r--r-- | drivers/video/ati_radeon_fb.h | 4 | ||||
| -rw-r--r-- | drivers/video/cfb_console.c | 200 | 
9 files changed, 272 insertions, 57 deletions
@@ -1133,6 +1133,12 @@ The following options need to be configured:  		images, gzipped BMP images can be displayed via the  		splashscreen support or the bmp command. +- Run length encoded BMP image (RLE8) support: CONFIG_VIDEO_BMP_RLE8 + +		If this option is set, 8-bit RLE compressed BMP images +		can be displayed via the splashscreen support or the +		bmp command. +  - Compression support:  		CONFIG_BZIP2 diff --git a/common/cmd_usb.c b/common/cmd_usb.c index 6b5c58255..ee3755c12 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -387,7 +387,7 @@ int do_usbboot(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  	dev = simple_strtoul(boot_device, &ep, 16);  	stor_dev = usb_stor_get_dev(dev); -	if (stor_dev->type == DEV_TYPE_UNKNOWN) { +	if (stor_dev == NULL || stor_dev->type == DEV_TYPE_UNKNOWN) {  		printf("\n** Device %d not available\n", dev);  		return 1;  	} @@ -595,8 +595,10 @@ int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  	if (strncmp(argv[1], "part", 4) == 0) {  		int devno, ok = 0;  		if (argc == 2) { -			for (devno = 0; devno < USB_MAX_STOR_DEV; ++devno) { +			for (devno = 0; ; ++devno) {  				stor_dev = usb_stor_get_dev(devno); +				if (stor_dev == NULL) +					break;  				if (stor_dev->type != DEV_TYPE_UNKNOWN) {  					ok++;  					if (devno) @@ -608,7 +610,8 @@ int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  		} else {  			devno = simple_strtoul(argv[2], NULL, 16);  			stor_dev = usb_stor_get_dev(devno); -			if (stor_dev->type != DEV_TYPE_UNKNOWN) { +			if (stor_dev != NULL && +			    stor_dev->type != DEV_TYPE_UNKNOWN) {  				ok++;  				debug("print_part of %x\n", devno);  				print_part(stor_dev); @@ -668,12 +671,12 @@ int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  		if (argc == 3) {  			int dev = (int)simple_strtoul(argv[2], NULL, 10);  			printf("\nUSB device %d: ", dev); -			if (dev >= USB_MAX_STOR_DEV) { +			stor_dev = usb_stor_get_dev(dev); +			if (stor_dev == NULL) {  				printf("unknown device\n");  				return 1;  			}  			printf("\n    Device %d: ", dev); -			stor_dev = usb_stor_get_dev(dev);  			dev_print(stor_dev);  			if (stor_dev->type == DEV_TYPE_UNKNOWN)  				return 1; diff --git a/common/usb_storage.c b/common/usb_storage.c index a8642c9cc..4fc01a22b 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -175,7 +175,7 @@ void uhci_show_temp_int_td(void);  block_dev_desc_t *usb_stor_get_dev(int index)  { -	return (index < USB_MAX_STOR_DEV) ? &usb_dev_desc[index] : NULL; +	return (index < usb_max_devs) ? &usb_dev_desc[index] : NULL;  } @@ -244,7 +244,7 @@ int usb_stor_scan(int mode)  			 * get info and fill it in  			 */  			if (usb_stor_get_info(dev, &usb_stor[usb_max_devs], -						&usb_dev_desc[usb_max_devs])) +						&usb_dev_desc[usb_max_devs]) == 1)  				usb_max_devs++;  		}  		/* if storage device */ @@ -888,7 +888,7 @@ static int usb_inquiry(ccb *srb, struct us_data *ss)  		USB_STOR_PRINTF("inquiry returns %d\n", i);  		if (i == 0)  			break; -	} while (retry--); +	} while (--retry);  	if (!retry) {  		printf("error in inquiry\n"); diff --git a/drivers/bios_emulator/atibios.c b/drivers/bios_emulator/atibios.c index 5f9bd101d..dbb5e8cce 100644 --- a/drivers/bios_emulator/atibios.c +++ b/drivers/bios_emulator/atibios.c @@ -173,7 +173,7 @@ Maps a pointer to the BIOS image on the graphics card on the PCI bus.  ****************************************************************************/  void *PCI_mapBIOSImage(pci_dev_t pcidev)  { -	u32 BIOSImagePhys; +	u32 BIOSImageBus;  	int BIOSImageBAR;  	u8 *BIOSImage; @@ -195,16 +195,18 @@ void *PCI_mapBIOSImage(pci_dev_t pcidev)  	 specific programming for different cards to solve this problem.  	*/ -	if ((BIOSImagePhys = PCI_findBIOSAddr(pcidev, &BIOSImageBAR)) == 0) { +	BIOSImageBus = PCI_findBIOSAddr(pcidev, &BIOSImageBAR); +	if (BIOSImageBus == 0) {  		printf("Find bios addr error\n");  		return NULL;  	} -	BIOSImage = (u8 *) BIOSImagePhys; +	BIOSImage = pci_bus_to_virt(pcidev, BIOSImageBus, +				    PCI_REGION_MEM, 0, MAP_NOCACHE);  	/*Change the PCI BAR registers to map it onto the bus.*/  	pci_write_config_dword(pcidev, BIOSImageBAR, 0); -	pci_write_config_dword(pcidev, PCI_ROM_ADDRESS, BIOSImagePhys | 0x1); +	pci_write_config_dword(pcidev, PCI_ROM_ADDRESS, BIOSImageBus | 0x1);  	udelay(1); @@ -315,7 +317,8 @@ int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo ** pVGAInfo, int cleanUp)  	BE_init(0, 65536, VGAInfo, 0);  	/*Post all the display controller BIOS'es*/ -	PCI_postController(pcidev, VGAInfo); +	if (!PCI_postController(pcidev, VGAInfo)) +		return false;  	/*Cleanup and exit the emulator if requested. If the BIOS emulator  	is needed after booting the card, we will not call BE_exit and diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 9ebeb4f23..7784d92b6 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -55,14 +55,14 @@ static struct descriptor {  	{  		0x12,		/* bLength */  		1,		/* bDescriptorType: UDESC_DEVICE */ -		0x0002,		/* bcdUSB: v2.0 */ +		cpu_to_le16(0x0200), /* bcdUSB: v2.0 */  		9,		/* bDeviceClass: UDCLASS_HUB */  		0,		/* bDeviceSubClass: UDSUBCLASS_HUB */  		1,		/* bDeviceProtocol: UDPROTO_HSHUBSTT */  		64,		/* bMaxPacketSize: 64 bytes */  		0x0000,		/* idVendor */  		0x0000,		/* idProduct */ -		0x0001,		/* bcdDevice */ +		cpu_to_le16(0x0100), /* bcdDevice */  		1,		/* iManufacturer */  		2,		/* iProduct */  		0,		/* iSerialNumber */ @@ -536,7 +536,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,  	uint32_t reg;  	uint32_t *status_reg; -	if (le16_to_cpu(req->index) >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) { +	if (le16_to_cpu(req->index) > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {  		printf("The request port(%d) is not configured\n",  			le16_to_cpu(req->index) - 1);  		return -1; @@ -630,19 +630,8 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,  			tmpbuf[0] |= USB_PORT_STAT_SUSPEND;  		if (reg & EHCI_PS_OCA)  			tmpbuf[0] |= USB_PORT_STAT_OVERCURRENT; -		if (reg & EHCI_PS_PR && -		    (portreset & (1 << le16_to_cpu(req->index)))) { -			int ret; -			/* force reset to complete */ -			reg = reg & ~(EHCI_PS_PR | EHCI_PS_CLEAR); -			ehci_writel(status_reg, reg); -			ret = handshake(status_reg, EHCI_PS_PR, 0, 2 * 1000); -			if (!ret) -				tmpbuf[0] |= USB_PORT_STAT_RESET; -			else -				printf("port(%d) reset error\n", -					le16_to_cpu(req->index) - 1); -		} +		if (reg & EHCI_PS_PR) +			tmpbuf[0] |= USB_PORT_STAT_RESET;  		if (reg & EHCI_PS_PP)  			tmpbuf[1] |= USB_PORT_STAT_POWER >> 8; @@ -699,6 +688,8 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,  				ehci_writel(status_reg, reg);  				break;  			} else { +				int ret; +  				reg |= EHCI_PS_PR;  				reg &= ~EHCI_PS_PE;  				ehci_writel(status_reg, reg); @@ -710,8 +701,19 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,  				wait_ms(50);  				/* terminate the reset */  				ehci_writel(status_reg, reg & ~EHCI_PS_PR); -				wait_ms(2); -				portreset |= 1 << le16_to_cpu(req->index); +				/* +				 * A host controller must terminate the reset +				 * and stabilize the state of the port within +				 * 2 milliseconds +				 */ +				ret = handshake(status_reg, EHCI_PS_PR, 0, +						2 * 1000); +				if (!ret) +					portreset |= +						1 << le16_to_cpu(req->index); +				else +					printf("port(%d) reset error\n", +					le16_to_cpu(req->index) - 1);  			}  			break;  		default: diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 441b1a271..047902a0c 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -28,6 +28,7 @@  #ifdef CONFIG_PCI_EHCI_DEVICE  static struct pci_device_id ehci_pci_ids[] = {  	/* Please add supported PCI EHCI controller ids here */ +	{0x1033, 0x00E0},  	{0, 0}  };  #endif diff --git a/drivers/video/ati_radeon_fb.c b/drivers/video/ati_radeon_fb.c index 9ebb0b0c9..4a9bd07e0 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_bus); +		rinfo->fb_base_bus &= 0xfffff000; +		rinfo->mmio_base_bus &= ~0x04; -		rinfo->mmio_base = (void *)rinfo->mmio_base_phys; -		DPRINT("rinfo->mmio_base = 0x%x\n",rinfo->mmio_base); +		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 e981f9524..065904555 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 49f0a2e04..d1f47c915 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:  |