103479763SNathan Whitehorn /*- 249588d0fSNathan Whitehorn * Copyright (c) 2011-2014 Nathan Whitehorn 303479763SNathan Whitehorn * All rights reserved. 403479763SNathan Whitehorn * 503479763SNathan Whitehorn * Redistribution and use in source and binary forms, with or without 603479763SNathan Whitehorn * modification, are permitted provided that the following conditions 703479763SNathan Whitehorn * are met: 803479763SNathan Whitehorn * 1. Redistributions of source code must retain the above copyright 903479763SNathan Whitehorn * notice, this list of conditions and the following disclaimer. 1003479763SNathan Whitehorn * 2. Redistributions in binary form must reproduce the above copyright 1103479763SNathan Whitehorn * notice, this list of conditions and the following disclaimer in the 1203479763SNathan Whitehorn * documentation and/or other materials provided with the distribution. 1303479763SNathan Whitehorn * 1403479763SNathan Whitehorn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1503479763SNathan Whitehorn * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1603479763SNathan Whitehorn * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1703479763SNathan Whitehorn * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1803479763SNathan Whitehorn * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1903479763SNathan Whitehorn * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2003479763SNathan Whitehorn * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2103479763SNathan Whitehorn * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2203479763SNathan Whitehorn * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2303479763SNathan Whitehorn * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2403479763SNathan Whitehorn * SUCH DAMAGE. 2503479763SNathan Whitehorn */ 2603479763SNathan Whitehorn 2703479763SNathan Whitehorn #include <sys/cdefs.h> 2803479763SNathan Whitehorn __FBSDID("$FreeBSD$"); 2903479763SNathan Whitehorn 3003479763SNathan Whitehorn #include <sys/param.h> 3103479763SNathan Whitehorn #include <sys/systm.h> 3203479763SNathan Whitehorn #include <sys/kernel.h> 3303479763SNathan Whitehorn #include <sys/sysctl.h> 3403479763SNathan Whitehorn #include <sys/limits.h> 3503479763SNathan Whitehorn #include <sys/conf.h> 3603479763SNathan Whitehorn #include <sys/cons.h> 3703479763SNathan Whitehorn #include <sys/fbio.h> 3803479763SNathan Whitehorn 3903479763SNathan Whitehorn #include <vm/vm.h> 4003479763SNathan Whitehorn #include <vm/pmap.h> 4103479763SNathan Whitehorn 4203479763SNathan Whitehorn #include <machine/platform.h> 4303479763SNathan Whitehorn #include <machine/pmap.h> 4403479763SNathan Whitehorn 4549588d0fSNathan Whitehorn #include <dev/vt/vt.h> 4649588d0fSNathan Whitehorn #include <dev/vt/hw/fb/vt_fb.h> 4749588d0fSNathan Whitehorn #include <dev/vt/colors/vt_termcolors.h> 4803479763SNathan Whitehorn 4903479763SNathan Whitehorn #include "ps3-hvcall.h" 5003479763SNathan Whitehorn 5103479763SNathan Whitehorn #define PS3FB_SIZE (4*1024*1024) 5203479763SNathan Whitehorn 5303479763SNathan Whitehorn #define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_MODE_SET 0x0100 5403479763SNathan Whitehorn #define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC 0x0101 5503479763SNathan Whitehorn #define L1GPU_DISPLAY_SYNC_HSYNC 1 5603479763SNathan Whitehorn #define L1GPU_DISPLAY_SYNC_VSYNC 2 5703479763SNathan Whitehorn #define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP 0x0102 5803479763SNathan Whitehorn 5949588d0fSNathan Whitehorn static vd_init_t ps3fb_init; 6049588d0fSNathan Whitehorn static vd_probe_t ps3fb_probe; 6103479763SNathan Whitehorn void ps3fb_remap(void); 6203479763SNathan Whitehorn 6303479763SNathan Whitehorn struct ps3fb_softc { 6449588d0fSNathan Whitehorn struct fb_info fb_info; 65263b7901SNathan Whitehorn 66263b7901SNathan Whitehorn uint64_t sc_fbhandle; 67263b7901SNathan Whitehorn uint64_t sc_fbcontext; 68263b7901SNathan Whitehorn uint64_t sc_dma_control; 69263b7901SNathan Whitehorn uint64_t sc_driver_info; 70263b7901SNathan Whitehorn uint64_t sc_reports; 71263b7901SNathan Whitehorn uint64_t sc_reports_size; 7203479763SNathan Whitehorn }; 7303479763SNathan Whitehorn 7449588d0fSNathan Whitehorn static struct vt_driver vt_ps3fb_driver = { 7549588d0fSNathan Whitehorn .vd_name = "ps3fb", 7649588d0fSNathan Whitehorn .vd_probe = ps3fb_probe, 7749588d0fSNathan Whitehorn .vd_init = ps3fb_init, 7849588d0fSNathan Whitehorn .vd_blank = vt_fb_blank, 79c285e4a5SJean-Sébastien Pédron .vd_bitblt_text = vt_fb_bitblt_text, 80631bb572SJean-Sébastien Pédron .vd_bitblt_bmp = vt_fb_bitblt_bitmap, 811365d077SJean-Sébastien Pédron .vd_drawrect = vt_fb_drawrect, 821365d077SJean-Sébastien Pédron .vd_setpixel = vt_fb_setpixel, 833ddad7daSNathan Whitehorn .vd_fb_ioctl = vt_fb_ioctl, 843ddad7daSNathan Whitehorn .vd_fb_mmap = vt_fb_mmap, 8549588d0fSNathan Whitehorn /* Better than VGA, but still generic driver. */ 8649588d0fSNathan Whitehorn .vd_priority = VD_PRIORITY_GENERIC + 1, 8703479763SNathan Whitehorn }; 8803479763SNathan Whitehorn 8949588d0fSNathan Whitehorn VT_DRIVER_DECLARE(vt_ps3fb, vt_ps3fb_driver); 9003479763SNathan Whitehorn static struct ps3fb_softc ps3fb_softc; 9103479763SNathan Whitehorn 9203479763SNathan Whitehorn static int 9349588d0fSNathan Whitehorn ps3fb_probe(struct vt_device *vd) 9403479763SNathan Whitehorn { 9503479763SNathan Whitehorn struct ps3fb_softc *sc; 9603479763SNathan Whitehorn int disable; 9703479763SNathan Whitehorn char compatible[64]; 9803479763SNathan Whitehorn #if 0 9903479763SNathan Whitehorn phandle_t root; 10003479763SNathan Whitehorn #endif 10103479763SNathan Whitehorn 10203479763SNathan Whitehorn disable = 0; 10303479763SNathan Whitehorn TUNABLE_INT_FETCH("hw.syscons.disable", &disable); 10403479763SNathan Whitehorn if (disable != 0) 10503479763SNathan Whitehorn return (0); 10603479763SNathan Whitehorn 10703479763SNathan Whitehorn sc = &ps3fb_softc; 10803479763SNathan Whitehorn 10903479763SNathan Whitehorn #if 0 11003479763SNathan Whitehorn root = OF_finddevice("/"); 11103479763SNathan Whitehorn if (OF_getprop(root, "compatible", compatible, sizeof(compatible)) <= 0) 11203479763SNathan Whitehorn return (0); 11303479763SNathan Whitehorn 11403479763SNathan Whitehorn if (strncmp(compatible, "sony,ps3", sizeof(compatible)) != 0) 11503479763SNathan Whitehorn return (0); 11603479763SNathan Whitehorn #else 11703479763SNathan Whitehorn TUNABLE_STR_FETCH("hw.platform", compatible, sizeof(compatible)); 11803479763SNathan Whitehorn if (strcmp(compatible, "ps3") != 0) 11949588d0fSNathan Whitehorn return (CN_DEAD); 12003479763SNathan Whitehorn #endif 12103479763SNathan Whitehorn 12249588d0fSNathan Whitehorn return (CN_INTERNAL); 12303479763SNathan Whitehorn } 12403479763SNathan Whitehorn 12503479763SNathan Whitehorn void 12603479763SNathan Whitehorn ps3fb_remap(void) 12703479763SNathan Whitehorn { 128263b7901SNathan Whitehorn struct ps3fb_softc *sc; 12903479763SNathan Whitehorn vm_offset_t va, fb_paddr; 130263b7901SNathan Whitehorn 131263b7901SNathan Whitehorn sc = &ps3fb_softc; 13203479763SNathan Whitehorn 13303479763SNathan Whitehorn lv1_gpu_close(); 13403479763SNathan Whitehorn lv1_gpu_open(0); 13503479763SNathan Whitehorn 13603479763SNathan Whitehorn lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_MODE_SET, 13703479763SNathan Whitehorn 0,0,0,0); 13803479763SNathan Whitehorn lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_MODE_SET, 13903479763SNathan Whitehorn 0,0,1,0); 14003479763SNathan Whitehorn lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC, 14103479763SNathan Whitehorn 0,L1GPU_DISPLAY_SYNC_VSYNC,0,0); 14203479763SNathan Whitehorn lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC, 14303479763SNathan Whitehorn 1,L1GPU_DISPLAY_SYNC_VSYNC,0,0); 14449588d0fSNathan Whitehorn lv1_gpu_memory_allocate(PS3FB_SIZE, 0, 0, 0, 0, &sc->sc_fbhandle, 14549588d0fSNathan Whitehorn &fb_paddr); 14649588d0fSNathan Whitehorn lv1_gpu_context_allocate(sc->sc_fbhandle, 0, &sc->sc_fbcontext, 14749588d0fSNathan Whitehorn &sc->sc_dma_control, &sc->sc_driver_info, &sc->sc_reports, 14849588d0fSNathan Whitehorn &sc->sc_reports_size); 14903479763SNathan Whitehorn 150263b7901SNathan Whitehorn lv1_gpu_context_attribute(sc->sc_fbcontext, 15103479763SNathan Whitehorn L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 0, 0, 0, 0); 152263b7901SNathan Whitehorn lv1_gpu_context_attribute(sc->sc_fbcontext, 15303479763SNathan Whitehorn L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 1, 0, 0, 0); 15403479763SNathan Whitehorn 15549588d0fSNathan Whitehorn sc->fb_info.fb_pbase = fb_paddr; 15603479763SNathan Whitehorn for (va = 0; va < PS3FB_SIZE; va += PAGE_SIZE) 15703479763SNathan Whitehorn pmap_kenter_attr(0x10000000 + va, fb_paddr + va, 15803479763SNathan Whitehorn VM_MEMATTR_WRITE_COMBINING); 159f1d2752fSNathan Whitehorn sc->fb_info.fb_flags &= ~FB_FLAG_NOWRITE; 16003479763SNathan Whitehorn } 16103479763SNathan Whitehorn 16203479763SNathan Whitehorn static int 16349588d0fSNathan Whitehorn ps3fb_init(struct vt_device *vd) 16403479763SNathan Whitehorn { 16503479763SNathan Whitehorn struct ps3fb_softc *sc; 16603479763SNathan Whitehorn 16749588d0fSNathan Whitehorn /* Init softc */ 16849588d0fSNathan Whitehorn vd->vd_softc = sc = &ps3fb_softc; 16903479763SNathan Whitehorn 17049588d0fSNathan Whitehorn /* XXX: get from HV repository */ 17149588d0fSNathan Whitehorn sc->fb_info.fb_depth = 32; 17249588d0fSNathan Whitehorn sc->fb_info.fb_height = 480; 17349588d0fSNathan Whitehorn sc->fb_info.fb_width = 720; 17449588d0fSNathan Whitehorn sc->fb_info.fb_stride = sc->fb_info.fb_width*4; 17549588d0fSNathan Whitehorn sc->fb_info.fb_size = sc->fb_info.fb_height * sc->fb_info.fb_stride; 17649588d0fSNathan Whitehorn sc->fb_info.fb_bpp = sc->fb_info.fb_stride / sc->fb_info.fb_width * 8; 17703479763SNathan Whitehorn 17849588d0fSNathan Whitehorn /* 179f1d2752fSNathan Whitehorn * Arbitrarily choose address for the framebuffer 18049588d0fSNathan Whitehorn */ 18103479763SNathan Whitehorn 18249588d0fSNathan Whitehorn sc->fb_info.fb_vbase = 0x10000000; 183f1d2752fSNathan Whitehorn sc->fb_info.fb_flags |= FB_FLAG_NOWRITE; /* Not available yet */ 184f1d2752fSNathan Whitehorn sc->fb_info.fb_cmsize = 16; 18549588d0fSNathan Whitehorn 18649588d0fSNathan Whitehorn /* 32-bit VGA palette */ 187ca885fdfSJean-Sébastien Pédron vt_generate_cons_palette(sc->fb_info.fb_cmap, COLOR_FORMAT_RGB, 188ca885fdfSJean-Sébastien Pédron 255, 0, 255, 8, 255, 16); 18949588d0fSNathan Whitehorn 19049588d0fSNathan Whitehorn /* Set correct graphics context */ 191263b7901SNathan Whitehorn lv1_gpu_context_attribute(sc->sc_fbcontext, 192263b7901SNathan Whitehorn L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 0, 0, 0, 0); 193263b7901SNathan Whitehorn lv1_gpu_context_attribute(sc->sc_fbcontext, 194263b7901SNathan Whitehorn L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 1, 0, 0, 0); 195263b7901SNathan Whitehorn 19649588d0fSNathan Whitehorn vt_fb_init(vd); 1979ed297c8SNathan Whitehorn sc->fb_info.fb_flags &= ~FB_FLAG_NOMMAP; /* Set wrongly by vt_fb_init */ 19849588d0fSNathan Whitehorn 19949588d0fSNathan Whitehorn return (CN_INTERNAL); 20003479763SNathan Whitehorn } 20103479763SNathan Whitehorn 202