Esempio n. 1
0
static void offb_init_palette_hacks(struct fb_info *info, struct device_node *dp,
				    const char *name, unsigned long address)
{
	struct offb_par *par = (struct offb_par *) info->par;

	if (dp && !strncmp(name, "ATY,Rage128", 11)) {
		par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
		if (par->cmap_adr)
			par->cmap_type = cmap_r128;
	} else if (dp && (!strncmp(name, "ATY,RageM3pA", 12)
			  || !strncmp(name, "ATY,RageM3p12A", 14))) {
		par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
		if (par->cmap_adr)
			par->cmap_type = cmap_M3A;
	} else if (dp && !strncmp(name, "ATY,RageM3pB", 12)) {
		par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
		if (par->cmap_adr)
			par->cmap_type = cmap_M3B;
	} else if (dp && !strncmp(name, "ATY,Rage6", 9)) {
		par->cmap_adr = offb_map_reg(dp, 1, 0, 0x1fff);
		if (par->cmap_adr)
			par->cmap_type = cmap_radeon;
	} else if (!strncmp(name, "ATY,", 4)) {
		unsigned long base = address & 0xff000000UL;
		par->cmap_adr =
			ioremap(base + 0x7ff000, 0x1000) + 0xcc0;
		par->cmap_data = par->cmap_adr + 1;
		par->cmap_type = cmap_m64;
	} else if (dp && (of_device_is_compatible(dp, "pci1014,b7") ||
			  of_device_is_compatible(dp, "pci1014,21c"))) {
		par->cmap_adr = offb_map_reg(dp, 0, 0x6000, 0x1000);
		if (par->cmap_adr)
			par->cmap_type = cmap_gxt2000;
	} else if (dp && !strncmp(name, "vga,Display-", 12)) {
		/* Look for AVIVO initialized by SLOF */
		struct device_node *pciparent = of_get_parent(dp);
		const u32 *vid, *did;
		vid = of_get_property(pciparent, "vendor-id", NULL);
		did = of_get_property(pciparent, "device-id", NULL);
		/* This will match most R5xx */
		if (vid && did && *vid == 0x1002 &&
		    ((*did >= 0x7100 && *did < 0x7800) ||
		     (*did >= 0x9400))) {
			par->cmap_adr = offb_map_reg(pciparent, 2, 0, 0x10000);
			if (par->cmap_adr)
				par->cmap_type = cmap_avivo;
		}
		of_node_put(pciparent);
	}
	info->fix.visual = (par->cmap_type != cmap_unknown) ?
		FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_STATIC_PSEUDOCOLOR;
}
Esempio n. 2
0
static void __init offb_init_fb(const char *name, const char *full_name,
				int width, int height, int depth,
				int pitch, unsigned long address,
				struct device_node *dp)
{
	unsigned long res_size = pitch * height * (depth + 7) / 8;
	struct offb_par *par = &default_par;
	unsigned long res_start = address;
	struct fb_fix_screeninfo *fix;
	struct fb_var_screeninfo *var;
	struct fb_info *info;
	int size;

	if (!request_mem_region(res_start, res_size, "offb"))
		return;

	printk(KERN_INFO
	       "Using unsupported %dx%d %s at %lx, depth=%d, pitch=%d\n",
	       width, height, name, address, depth, pitch);
	if (depth != 8 && depth != 15 && depth != 16 && depth != 32) {
		printk(KERN_ERR "%s: can't use depth = %d\n", full_name,
		       depth);
		release_mem_region(res_start, res_size);
		return;
	}

	size = sizeof(struct fb_info) + sizeof(u32) * 16;

	info = kmalloc(size, GFP_ATOMIC);
	
	if (info == 0) {
		release_mem_region(res_start, res_size);
		return;
	}
	memset(info, 0, size);

	fix = &info->fix;
	var = &info->var;

	strcpy(fix->id, "OFfb ");
	strncat(fix->id, name, sizeof(fix->id) - sizeof("OFfb "));
	fix->id[sizeof(fix->id) - 1] = '\0';

	var->xres = var->xres_virtual = width;
	var->yres = var->yres_virtual = height;
	fix->line_length = pitch;

	fix->smem_start = address;
	fix->smem_len = pitch * height;
	fix->type = FB_TYPE_PACKED_PIXELS;
	fix->type_aux = 0;

	par->cmap_type = cmap_unknown;
	if (depth == 8) {
		if (dp && !strncmp(name, "ATY,Rage128", 11)) {
			par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
			if (par->cmap_adr)
				par->cmap_type = cmap_r128;
		} else if (dp && (!strncmp(name, "ATY,RageM3pA", 12)
				  || !strncmp(name, "ATY,RageM3p12A", 14))) {
			par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
			if (par->cmap_adr)
				par->cmap_type = cmap_M3A;
		} else if (dp && !strncmp(name, "ATY,RageM3pB", 12)) {
			par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
			if (par->cmap_adr)
				par->cmap_type = cmap_M3B;
		} else if (dp && !strncmp(name, "ATY,Rage6", 9)) {
			par->cmap_adr = offb_map_reg(dp, 1, 0, 0x1fff);
			if (par->cmap_adr)
				par->cmap_type = cmap_radeon;
		} else if (!strncmp(name, "ATY,", 4)) {
			unsigned long base = address & 0xff000000UL;
			par->cmap_adr =
			    ioremap(base + 0x7ff000, 0x1000) + 0xcc0;
			par->cmap_data = par->cmap_adr + 1;
			par->cmap_type = cmap_m64;
		} else if (dp && (of_device_is_compatible(dp, "pci1014,b7") ||
				  of_device_is_compatible(dp, "pci1014,21c"))) {
			par->cmap_adr = offb_map_reg(dp, 0, 0x6000, 0x1000);
			if (par->cmap_adr)
				par->cmap_type = cmap_gxt2000;
		}
		fix->visual = (par->cmap_type != cmap_unknown) ?
			FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_STATIC_PSEUDOCOLOR;
	} else
		fix->visual = FB_VISUAL_TRUECOLOR;

	var->xoffset = var->yoffset = 0;
	switch (depth) {
	case 8:
		var->bits_per_pixel = 8;
		var->red.offset = 0;
		var->red.length = 8;
		var->green.offset = 0;
		var->green.length = 8;
		var->blue.offset = 0;
		var->blue.length = 8;
		var->transp.offset = 0;
		var->transp.length = 0;
		break;
	case 15:		/* RGB 555 */
		var->bits_per_pixel = 16;
		var->red.offset = 10;
		var->red.length = 5;
		var->green.offset = 5;
		var->green.length = 5;
		var->blue.offset = 0;
		var->blue.length = 5;
		var->transp.offset = 0;
		var->transp.length = 0;
		break;
	case 16:		/* RGB 565 */
		var->bits_per_pixel = 16;
		var->red.offset = 11;
		var->red.length = 5;
		var->green.offset = 5;
		var->green.length = 6;
		var->blue.offset = 0;
		var->blue.length = 5;
		var->transp.offset = 0;
		var->transp.length = 0;
		break;
	case 32:		/* RGB 888 */
		var->bits_per_pixel = 32;
		var->red.offset = 16;
		var->red.length = 8;
		var->green.offset = 8;
		var->green.length = 8;
		var->blue.offset = 0;
		var->blue.length = 8;
		var->transp.offset = 24;
		var->transp.length = 8;
		break;
	}
	var->red.msb_right = var->green.msb_right = var->blue.msb_right =
	    var->transp.msb_right = 0;
	var->grayscale = 0;
	var->nonstd = 0;
	var->activate = 0;
	var->height = var->width = -1;
	var->pixclock = 10000;
	var->left_margin = var->right_margin = 16;
	var->upper_margin = var->lower_margin = 16;
	var->hsync_len = var->vsync_len = 8;
	var->sync = 0;
	var->vmode = FB_VMODE_NONINTERLACED;

	info->fbops = &offb_ops;
	info->screen_base = ioremap(address, fix->smem_len);
	info->par = par;
	info->pseudo_palette = (void *) (info + 1);
	info->flags = FBINFO_DEFAULT;

	fb_alloc_cmap(&info->cmap, 256, 0);

	if (register_framebuffer(info) < 0) {
		iounmap(par->cmap_adr);
		par->cmap_adr = NULL;
		iounmap(info->screen_base);
		kfree(info);
		release_mem_region(res_start, res_size);
		return;
	}

	printk(KERN_INFO "fb%d: Open Firmware frame buffer device on %s\n",
	       info->node, full_name);
}