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); }
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; } }
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); } }
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); }