예제 #1
0
static int
bcm_fb_setup_fbd(struct bcmsc_softc *sc)
{
	struct bcm2835_fb_config fb;
	device_t fbd;
	int err;

	err = bcm_fb_init(sc, &fb);
	if (err)
		return (err);

	memset(&sc->info, 0, sizeof(sc->info));
	sc->info.fb_name = device_get_nameunit(sc->dev);

	sc->info.fb_vbase = (intptr_t)pmap_mapdev(fb.base, fb.size);
	sc->info.fb_pbase = fb.base;
	sc->info.fb_size = fb.size;
	sc->info.fb_bpp = sc->info.fb_depth = fb.bpp;
	sc->info.fb_stride = fb.pitch;
	sc->info.fb_width = fb.xres;
	sc->info.fb_height = fb.yres;
	sc->info.fb_flags = FB_FLAG_MEMATTR;
	sc->info.fb_memattr = VM_MEMATTR_WRITE_COMBINING;

	if (sc->fbswap) {
		switch (sc->info.fb_bpp) {
		case 24:
			vt_generate_cons_palette(sc->info.fb_cmap,
			    COLOR_FORMAT_RGB, 0xff, 0, 0xff, 8, 0xff, 16);
			sc->info.fb_cmsize = 16;
			break;
		case 32:
			vt_generate_cons_palette(sc->info.fb_cmap,
			    COLOR_FORMAT_RGB, 0xff, 16, 0xff, 8, 0xff, 0);
			sc->info.fb_cmsize = 16;
			break;
		}
	}

	fbd = device_add_child(sc->dev, "fbd", device_get_unit(sc->dev));
	if (fbd == NULL) {
		device_printf(sc->dev, "Failed to add fbd child\n");
		pmap_unmapdev(sc->info.fb_vbase, sc->info.fb_size);
		return (ENXIO);
	} else if (device_probe_and_attach(fbd) != 0) {
		device_printf(sc->dev, "Failed to attach fbd device\n");
		device_delete_child(sc->dev, fbd);
		pmap_unmapdev(sc->info.fb_vbase, sc->info.fb_size);
		return (ENXIO);
	}

	device_printf(sc->dev, "%dx%d(%dx%d@%d,%d) %dbpp\n", fb.xres, fb.yres,
	    fb.vxres, fb.vyres, fb.xoffset, fb.yoffset, fb.bpp);
	device_printf(sc->dev,
	    "fbswap: %d, pitch %d, base 0x%08x, screen_size %d\n",
	    sc->fbswap, fb.pitch, fb.base, fb.size);

	return (0);
}
예제 #2
0
vt_efb_initialize(struct fb_info *info)
#endif
{
#ifdef	FDT
	char name[64];
	cell_t retval;
	ihandle_t ih;
	int i;

	/* Open display device, thereby initializing it */
	memset(name, 0, sizeof(name));
	OF_package_to_path(node, name, sizeof(name));
	ih = OF_open(name);
#endif

	/*
	 * Set up the color map
	 */
	switch (info->fb_depth) {
	case 8:
		vt_generate_cons_palette(info->fb_cmap, COLOR_FORMAT_RGB,
		    0x7, 5, 0x7, 2, 0x3, 0);
		break;
	case 15:
		vt_generate_cons_palette(info->fb_cmap, COLOR_FORMAT_RGB,
		    0x1f, 10, 0x1f, 5, 0x1f, 0);
		break;
	case 16:
		vt_generate_cons_palette(info->fb_cmap, COLOR_FORMAT_RGB,
		    0x1f, 11, 0x3f, 5, 0x1f, 0);
		break;
	case 24:
	case 32:
#if BYTE_ORDER == BIG_ENDIAN
		vt_generate_cons_palette(info->fb_cmap,
		    COLOR_FORMAT_RGB, 255, 0, 255, 8, 255, 16);
#else
		vt_generate_cons_palette(info->fb_cmap,
		    COLOR_FORMAT_RGB, 255, 16, 255, 8, 255, 0);
#endif
#ifdef	FDT
		for (i = 0; i < 16; i++) {
			OF_call_method("color!", ih, 4, 1,
			    (cell_t)((info->fb_cmap[i] >> 16) & 0xff),
			    (cell_t)((info->fb_cmap[i] >> 8) & 0xff),
			    (cell_t)((info->fb_cmap[i] >> 0) & 0xff),
			    (cell_t)i, &retval);
		}
#endif
		break;

	default:
		panic("Unknown color space fb_depth %d", info->fb_depth);
		break;
	}
}
예제 #3
0
static int
vt_fb_init_cmap(uint32_t *cmap, int depth)
{

	switch (depth) {
	case 8:
		return (vt_generate_cons_palette(cmap, COLOR_FORMAT_RGB,
		    0x7, 5, 0x7, 2, 0x3, 0));
	case 15:
		return (vt_generate_cons_palette(cmap, COLOR_FORMAT_RGB,
		    0x1f, 10, 0x1f, 5, 0x1f, 0));
	case 16:
		return (vt_generate_cons_palette(cmap, COLOR_FORMAT_RGB,
		    0x1f, 11, 0x3f, 5, 0x1f, 0));
	case 24:
	case 32: /* Ignore alpha. */
		return (vt_generate_cons_palette(cmap, COLOR_FORMAT_RGB,
		    0xff, 16, 0xff, 8, 0xff, 0));
	default:
		return (1);
	}
}
예제 #4
0
파일: efifb.c 프로젝트: coyizumi/cs111
static int
vt_efifb_init(struct vt_device *vd)
{
	int		depth, d;
	struct fb_info	*info;
	struct efi_fb	*efifb;
	caddr_t		kmdp;

	info = vd->vd_softc;
	if (info == NULL)
		info = vd->vd_softc = (void *)&local_info;

	kmdp = preload_search_by_type("elf kernel");
	if (kmdp == NULL)
		kmdp = preload_search_by_type("elf64 kernel");
	efifb = (struct efi_fb *)preload_search_info(kmdp,
	    MODINFO_METADATA | MODINFOMD_EFI_FB);
	if (efifb == NULL)
		return (CN_DEAD);

	info->fb_height = efifb->fb_height;
	info->fb_width = efifb->fb_width;

	depth = fls(efifb->fb_mask_red);
	d = fls(efifb->fb_mask_green);
	depth = d > depth ? d : depth;
	d = fls(efifb->fb_mask_blue);
	depth = d > depth ? d : depth;
	d = fls(efifb->fb_mask_reserved);
	depth = d > depth ? d : depth;
	info->fb_depth = depth;

	info->fb_stride = efifb->fb_stride * (depth / 8);

	vt_generate_cons_palette(info->fb_cmap, COLOR_FORMAT_RGB,
	    efifb->fb_mask_red, ffs(efifb->fb_mask_red) - 1,
	    efifb->fb_mask_green, ffs(efifb->fb_mask_green) - 1,
	    efifb->fb_mask_blue, ffs(efifb->fb_mask_blue) - 1);

	info->fb_size = info->fb_height * info->fb_stride;
	info->fb_pbase = efifb->fb_addr;
	/*
	 * Use the direct map as a crutch until pmap is available. Once pmap
	 * is online, the framebuffer will be remapped by vt_efifb_remap()
	 * using pmap_mapdev_attr().
	 */
	info->fb_vbase = PHYS_TO_DMAP(efifb->fb_addr);

	/* Get pixel storage size. */
	info->fb_bpp = info->fb_stride / info->fb_width * 8;

	/*
	 * Early FB driver work with static window buffer, so reduce to minimal
	 * size, buffer or screen.
	 */
	info->fb_width = MIN(info->fb_width, VT_FB_DEFAULT_WIDTH);
	info->fb_height = MIN(info->fb_height, VT_FB_DEFAULT_HEIGHT);

	vt_fb_init(vd);

	return (CN_INTERNAL);
}