1217044Snwhitehorn/*- 2265871Snwhitehorn * Copyright (c) 2011-2014 Nathan Whitehorn 3217044Snwhitehorn * All rights reserved. 4217044Snwhitehorn * 5217044Snwhitehorn * Redistribution and use in source and binary forms, with or without 6217044Snwhitehorn * modification, are permitted provided that the following conditions 7217044Snwhitehorn * are met: 8217044Snwhitehorn * 1. Redistributions of source code must retain the above copyright 9217044Snwhitehorn * notice, this list of conditions and the following disclaimer. 10217044Snwhitehorn * 2. Redistributions in binary form must reproduce the above copyright 11217044Snwhitehorn * notice, this list of conditions and the following disclaimer in the 12217044Snwhitehorn * documentation and/or other materials provided with the distribution. 13217044Snwhitehorn * 14217044Snwhitehorn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15217044Snwhitehorn * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16217044Snwhitehorn * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17217044Snwhitehorn * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18217044Snwhitehorn * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19217044Snwhitehorn * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20217044Snwhitehorn * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21217044Snwhitehorn * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22217044Snwhitehorn * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23217044Snwhitehorn * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24217044Snwhitehorn * SUCH DAMAGE. 25217044Snwhitehorn */ 26217044Snwhitehorn 27217044Snwhitehorn#include <sys/cdefs.h> 28217044Snwhitehorn__FBSDID("$FreeBSD: releng/11.0/sys/powerpc/ps3/ps3_syscons.c 295880 2016-02-22 09:02:20Z skra $"); 29217044Snwhitehorn 30217044Snwhitehorn#include <sys/param.h> 31217044Snwhitehorn#include <sys/systm.h> 32217044Snwhitehorn#include <sys/kernel.h> 33217044Snwhitehorn#include <sys/sysctl.h> 34217044Snwhitehorn#include <sys/limits.h> 35217044Snwhitehorn#include <sys/conf.h> 36217044Snwhitehorn#include <sys/cons.h> 37217044Snwhitehorn#include <sys/fbio.h> 38217044Snwhitehorn 39217044Snwhitehorn#include <vm/vm.h> 40217044Snwhitehorn#include <vm/pmap.h> 41217044Snwhitehorn 42217044Snwhitehorn#include <machine/platform.h> 43217044Snwhitehorn 44276680Snwhitehorn#include <dev/ofw/openfirm.h> 45265871Snwhitehorn#include <dev/vt/vt.h> 46265871Snwhitehorn#include <dev/vt/hw/fb/vt_fb.h> 47265871Snwhitehorn#include <dev/vt/colors/vt_termcolors.h> 48217044Snwhitehorn 49217044Snwhitehorn#include "ps3-hvcall.h" 50217044Snwhitehorn 51217044Snwhitehorn#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_MODE_SET 0x0100 52217044Snwhitehorn#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC 0x0101 53217044Snwhitehorn#define L1GPU_DISPLAY_SYNC_HSYNC 1 54217044Snwhitehorn#define L1GPU_DISPLAY_SYNC_VSYNC 2 55217044Snwhitehorn#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP 0x0102 56217044Snwhitehorn 57265871Snwhitehornstatic vd_init_t ps3fb_init; 58265871Snwhitehornstatic vd_probe_t ps3fb_probe; 59217044Snwhitehornvoid ps3fb_remap(void); 60217044Snwhitehorn 61217044Snwhitehornstruct ps3fb_softc { 62265871Snwhitehorn struct fb_info fb_info; 63217044Snwhitehorn 64228689Snwhitehorn uint64_t sc_fbhandle; 65228689Snwhitehorn uint64_t sc_fbcontext; 66228689Snwhitehorn uint64_t sc_dma_control; 67228689Snwhitehorn uint64_t sc_driver_info; 68228689Snwhitehorn uint64_t sc_reports; 69228689Snwhitehorn uint64_t sc_reports_size; 70217044Snwhitehorn}; 71217044Snwhitehorn 72265871Snwhitehornstatic struct vt_driver vt_ps3fb_driver = { 73265871Snwhitehorn .vd_name = "ps3fb", 74265871Snwhitehorn .vd_probe = ps3fb_probe, 75265871Snwhitehorn .vd_init = ps3fb_init, 76265871Snwhitehorn .vd_blank = vt_fb_blank, 77270411Sdumbbell .vd_bitblt_text = vt_fb_bitblt_text, 78270431Sdumbbell .vd_bitblt_bmp = vt_fb_bitblt_bitmap, 79271684Sdumbbell .vd_drawrect = vt_fb_drawrect, 80271684Sdumbbell .vd_setpixel = vt_fb_setpixel, 81268895Snwhitehorn .vd_fb_ioctl = vt_fb_ioctl, 82268895Snwhitehorn .vd_fb_mmap = vt_fb_mmap, 83265871Snwhitehorn /* Better than VGA, but still generic driver. */ 84265871Snwhitehorn .vd_priority = VD_PRIORITY_GENERIC + 1, 85217044Snwhitehorn}; 86217044Snwhitehorn 87265871SnwhitehornVT_DRIVER_DECLARE(vt_ps3fb, vt_ps3fb_driver); 88217044Snwhitehornstatic struct ps3fb_softc ps3fb_softc; 89217044Snwhitehorn 90217044Snwhitehornstatic int 91265871Snwhitehornps3fb_probe(struct vt_device *vd) 92217044Snwhitehorn{ 93217044Snwhitehorn struct ps3fb_softc *sc; 94217044Snwhitehorn int disable; 95217044Snwhitehorn char compatible[64]; 96217044Snwhitehorn phandle_t root; 97217044Snwhitehorn 98217044Snwhitehorn disable = 0; 99217044Snwhitehorn TUNABLE_INT_FETCH("hw.syscons.disable", &disable); 100217044Snwhitehorn if (disable != 0) 101217044Snwhitehorn return (0); 102217044Snwhitehorn 103217044Snwhitehorn sc = &ps3fb_softc; 104217044Snwhitehorn 105276680Snwhitehorn TUNABLE_STR_FETCH("hw.platform", compatible, sizeof(compatible)); 106276680Snwhitehorn if (strcmp(compatible, "ps3") == 0) 107276680Snwhitehorn return (CN_INTERNAL); 108276680Snwhitehorn 109217044Snwhitehorn root = OF_finddevice("/"); 110217044Snwhitehorn if (OF_getprop(root, "compatible", compatible, sizeof(compatible)) <= 0) 111276680Snwhitehorn return (CN_DEAD); 112217044Snwhitehorn 113217044Snwhitehorn if (strncmp(compatible, "sony,ps3", sizeof(compatible)) != 0) 114265871Snwhitehorn return (CN_DEAD); 115217044Snwhitehorn 116265871Snwhitehorn return (CN_INTERNAL); 117217044Snwhitehorn} 118217044Snwhitehorn 119217044Snwhitehornvoid 120217044Snwhitehornps3fb_remap(void) 121217044Snwhitehorn{ 122228689Snwhitehorn struct ps3fb_softc *sc; 123217044Snwhitehorn vm_offset_t va, fb_paddr; 124217044Snwhitehorn 125228689Snwhitehorn sc = &ps3fb_softc; 126228689Snwhitehorn 127217044Snwhitehorn lv1_gpu_close(); 128217044Snwhitehorn lv1_gpu_open(0); 129217044Snwhitehorn 130217044Snwhitehorn lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_MODE_SET, 131217044Snwhitehorn 0,0,0,0); 132217044Snwhitehorn lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_MODE_SET, 133217044Snwhitehorn 0,0,1,0); 134217044Snwhitehorn lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC, 135217044Snwhitehorn 0,L1GPU_DISPLAY_SYNC_VSYNC,0,0); 136217044Snwhitehorn lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC, 137217044Snwhitehorn 1,L1GPU_DISPLAY_SYNC_VSYNC,0,0); 138279136Snwhitehorn lv1_gpu_memory_allocate(roundup2(sc->fb_info.fb_size, 1024*1024), 139279136Snwhitehorn 0, 0, 0, 0, &sc->sc_fbhandle, &fb_paddr); 140265871Snwhitehorn lv1_gpu_context_allocate(sc->sc_fbhandle, 0, &sc->sc_fbcontext, 141265871Snwhitehorn &sc->sc_dma_control, &sc->sc_driver_info, &sc->sc_reports, 142265871Snwhitehorn &sc->sc_reports_size); 143217044Snwhitehorn 144228689Snwhitehorn lv1_gpu_context_attribute(sc->sc_fbcontext, 145217044Snwhitehorn L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 0, 0, 0, 0); 146228689Snwhitehorn lv1_gpu_context_attribute(sc->sc_fbcontext, 147217044Snwhitehorn L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 1, 0, 0, 0); 148217044Snwhitehorn 149265871Snwhitehorn sc->fb_info.fb_pbase = fb_paddr; 150279136Snwhitehorn for (va = 0; va < sc->fb_info.fb_size; va += PAGE_SIZE) 151217044Snwhitehorn pmap_kenter_attr(0x10000000 + va, fb_paddr + va, 152276679Snwhitehorn VM_MEMATTR_WRITE_COMBINING); 153276679Snwhitehorn sc->fb_info.fb_flags &= ~FB_FLAG_NOWRITE; 154217044Snwhitehorn} 155217044Snwhitehorn 156217044Snwhitehornstatic int 157265871Snwhitehornps3fb_init(struct vt_device *vd) 158217044Snwhitehorn{ 159217044Snwhitehorn struct ps3fb_softc *sc; 160217044Snwhitehorn 161265871Snwhitehorn /* Init softc */ 162265871Snwhitehorn vd->vd_softc = sc = &ps3fb_softc; 163217044Snwhitehorn 164265871Snwhitehorn /* XXX: get from HV repository */ 165265871Snwhitehorn sc->fb_info.fb_depth = 32; 166265871Snwhitehorn sc->fb_info.fb_height = 480; 167265871Snwhitehorn sc->fb_info.fb_width = 720; 168279136Snwhitehorn TUNABLE_INT_FETCH("hw.ps3fb.height", &sc->fb_info.fb_height); 169279136Snwhitehorn TUNABLE_INT_FETCH("hw.ps3fb.width", &sc->fb_info.fb_width); 170265871Snwhitehorn sc->fb_info.fb_stride = sc->fb_info.fb_width*4; 171265871Snwhitehorn sc->fb_info.fb_size = sc->fb_info.fb_height * sc->fb_info.fb_stride; 172265871Snwhitehorn sc->fb_info.fb_bpp = sc->fb_info.fb_stride / sc->fb_info.fb_width * 8; 173217044Snwhitehorn 174217044Snwhitehorn /* 175276679Snwhitehorn * Arbitrarily choose address for the framebuffer 176217044Snwhitehorn */ 177217044Snwhitehorn 178265871Snwhitehorn sc->fb_info.fb_vbase = 0x10000000; 179276679Snwhitehorn sc->fb_info.fb_flags |= FB_FLAG_NOWRITE; /* Not available yet */ 180276679Snwhitehorn sc->fb_info.fb_cmsize = 16; 181217044Snwhitehorn 182265871Snwhitehorn /* 32-bit VGA palette */ 183269791Sdumbbell vt_generate_cons_palette(sc->fb_info.fb_cmap, COLOR_FORMAT_RGB, 184269791Sdumbbell 255, 0, 255, 8, 255, 16); 185217044Snwhitehorn 186265871Snwhitehorn /* Set correct graphics context */ 187228689Snwhitehorn lv1_gpu_context_attribute(sc->sc_fbcontext, 188228689Snwhitehorn L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 0, 0, 0, 0); 189228689Snwhitehorn lv1_gpu_context_attribute(sc->sc_fbcontext, 190228689Snwhitehorn L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 1, 0, 0, 0); 191228689Snwhitehorn 192265871Snwhitehorn vt_fb_init(vd); 193217044Snwhitehorn 194265871Snwhitehorn return (CN_INTERNAL); 195217044Snwhitehorn} 196217044Snwhitehorn 197