ps3_syscons.c revision 270411
1191783Srmacklem/*- 2191783Srmacklem * Copyright (c) 2011-2014 Nathan Whitehorn 3191783Srmacklem * All rights reserved. 4191783Srmacklem * 5191783Srmacklem * Redistribution and use in source and binary forms, with or without 6191783Srmacklem * modification, are permitted provided that the following conditions 7191783Srmacklem * are met: 8191783Srmacklem * 1. Redistributions of source code must retain the above copyright 9191783Srmacklem * notice, this list of conditions and the following disclaimer. 10191783Srmacklem * 2. Redistributions in binary form must reproduce the above copyright 11191783Srmacklem * notice, this list of conditions and the following disclaimer in the 12191783Srmacklem * documentation and/or other materials provided with the distribution. 13191783Srmacklem * 14191783Srmacklem * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15191783Srmacklem * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16191783Srmacklem * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17191783Srmacklem * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18191783Srmacklem * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19191783Srmacklem * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20191783Srmacklem * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21191783Srmacklem * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22191783Srmacklem * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23191783Srmacklem * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24191783Srmacklem * SUCH DAMAGE. 25191783Srmacklem */ 26191783Srmacklem 27191783Srmacklem#include <sys/cdefs.h> 28191783Srmacklem__FBSDID("$FreeBSD: head/sys/powerpc/ps3/ps3_syscons.c 270411 2014-08-23 15:00:47Z dumbbell $"); 29191783Srmacklem 30191783Srmacklem#include <sys/param.h> 31191783Srmacklem#include <sys/systm.h> 32191783Srmacklem#include <sys/kernel.h> 33191783Srmacklem#include <sys/sysctl.h> 34191783Srmacklem#include <sys/limits.h> 35191783Srmacklem#include <sys/conf.h> 36191783Srmacklem#include <sys/cons.h> 37191783Srmacklem#include <sys/fbio.h> 38191783Srmacklem 39191783Srmacklem#include <vm/vm.h> 40191783Srmacklem#include <vm/pmap.h> 41191783Srmacklem 42221523Smav#include <machine/platform.h> 43191783Srmacklem#include <machine/pmap.h> 44191783Srmacklem 45191783Srmacklem#include <dev/vt/vt.h> 46191783Srmacklem#include <dev/vt/hw/fb/vt_fb.h> 47191783Srmacklem#include <dev/vt/colors/vt_termcolors.h> 48191783Srmacklem 49191783Srmacklem#include "ps3-hvcall.h" 50191783Srmacklem 51191783Srmacklem#define PS3FB_SIZE (4*1024*1024) 52191783Srmacklem 53191783Srmacklem#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_MODE_SET 0x0100 54191783Srmacklem#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC 0x0101 55191783Srmacklem#define L1GPU_DISPLAY_SYNC_HSYNC 1 56191783Srmacklem#define L1GPU_DISPLAY_SYNC_VSYNC 2 57191783Srmacklem#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP 0x0102 58191783Srmacklem 59220739Srmacklemstatic vd_init_t ps3fb_init; 60191783Srmacklemstatic vd_probe_t ps3fb_probe; 61191783Srmacklemvoid ps3fb_remap(void); 62191783Srmacklem 63191783Srmacklemstruct ps3fb_softc { 64191783Srmacklem struct fb_info fb_info; 65191783Srmacklem 66191783Srmacklem uint64_t sc_fbhandle; 67191783Srmacklem uint64_t sc_fbcontext; 68191783Srmacklem uint64_t sc_dma_control; 69191783Srmacklem uint64_t sc_driver_info; 70191783Srmacklem uint64_t sc_reports; 71191783Srmacklem uint64_t sc_reports_size; 72191783Srmacklem}; 73191783Srmacklem 74220683Srmacklemstatic struct vt_driver vt_ps3fb_driver = { 75220683Srmacklem .vd_name = "ps3fb", 76220683Srmacklem .vd_probe = ps3fb_probe, 77191783Srmacklem .vd_init = ps3fb_init, 78191783Srmacklem .vd_blank = vt_fb_blank, 79191783Srmacklem .vd_bitblt_text = vt_fb_bitblt_text, 80191783Srmacklem .vd_fb_ioctl = vt_fb_ioctl, 81191783Srmacklem .vd_fb_mmap = vt_fb_mmap, 82191783Srmacklem /* Better than VGA, but still generic driver. */ 83191783Srmacklem .vd_priority = VD_PRIORITY_GENERIC + 1, 84191783Srmacklem}; 85191783Srmacklem 86191783SrmacklemVT_DRIVER_DECLARE(vt_ps3fb, vt_ps3fb_driver); 87191783Srmacklemstatic struct ps3fb_softc ps3fb_softc; 88191783Srmacklem 89191783Srmacklemstatic int 90191783Srmacklemps3fb_probe(struct vt_device *vd) 91191783Srmacklem{ 92191783Srmacklem struct ps3fb_softc *sc; 93191783Srmacklem int disable; 94191783Srmacklem char compatible[64]; 95191783Srmacklem#if 0 96191783Srmacklem phandle_t root; 97191783Srmacklem#endif 98191783Srmacklem 99191783Srmacklem disable = 0; 100191783Srmacklem TUNABLE_INT_FETCH("hw.syscons.disable", &disable); 101191783Srmacklem if (disable != 0) 102191783Srmacklem return (0); 103191783Srmacklem 104191783Srmacklem sc = &ps3fb_softc; 105191783Srmacklem 106191783Srmacklem#if 0 107191783Srmacklem root = OF_finddevice("/"); 108191783Srmacklem if (OF_getprop(root, "compatible", compatible, sizeof(compatible)) <= 0) 109191783Srmacklem return (0); 110191783Srmacklem 111191783Srmacklem if (strncmp(compatible, "sony,ps3", sizeof(compatible)) != 0) 112191783Srmacklem return (0); 113191783Srmacklem#else 114191783Srmacklem TUNABLE_STR_FETCH("hw.platform", compatible, sizeof(compatible)); 115191783Srmacklem if (strcmp(compatible, "ps3") != 0) 116191783Srmacklem return (CN_DEAD); 117191783Srmacklem#endif 118191783Srmacklem 119191783Srmacklem return (CN_INTERNAL); 120191783Srmacklem} 121191783Srmacklem 122191783Srmacklemvoid 123191783Srmacklemps3fb_remap(void) 124191783Srmacklem{ 125191783Srmacklem struct ps3fb_softc *sc; 126191783Srmacklem vm_offset_t va, fb_paddr; 127191783Srmacklem 128191783Srmacklem sc = &ps3fb_softc; 129191783Srmacklem 130191783Srmacklem lv1_gpu_close(); 131191783Srmacklem lv1_gpu_open(0); 132191783Srmacklem 133191783Srmacklem lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_MODE_SET, 134191783Srmacklem 0,0,0,0); 135191783Srmacklem lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_MODE_SET, 136191783Srmacklem 0,0,1,0); 137191783Srmacklem lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC, 138191783Srmacklem 0,L1GPU_DISPLAY_SYNC_VSYNC,0,0); 139191783Srmacklem lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC, 140191783Srmacklem 1,L1GPU_DISPLAY_SYNC_VSYNC,0,0); 141191783Srmacklem lv1_gpu_memory_allocate(PS3FB_SIZE, 0, 0, 0, 0, &sc->sc_fbhandle, 142191783Srmacklem &fb_paddr); 143191783Srmacklem lv1_gpu_context_allocate(sc->sc_fbhandle, 0, &sc->sc_fbcontext, 144191783Srmacklem &sc->sc_dma_control, &sc->sc_driver_info, &sc->sc_reports, 145191783Srmacklem &sc->sc_reports_size); 146191783Srmacklem 147191783Srmacklem lv1_gpu_context_attribute(sc->sc_fbcontext, 148191783Srmacklem L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 0, 0, 0, 0); 149191783Srmacklem lv1_gpu_context_attribute(sc->sc_fbcontext, 150191783Srmacklem L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 1, 0, 0, 0); 151191783Srmacklem 152191783Srmacklem sc->fb_info.fb_pbase = fb_paddr; 153191783Srmacklem for (va = 0; va < PS3FB_SIZE; va += PAGE_SIZE) 154191783Srmacklem pmap_kenter_attr(0x10000000 + va, fb_paddr + va, 155191783Srmacklem VM_MEMATTR_WRITE_COMBINING); 156191783Srmacklem} 157191783Srmacklem 158191783Srmacklemstatic int 159191783Srmacklemps3fb_init(struct vt_device *vd) 160191783Srmacklem{ 161191783Srmacklem struct ps3fb_softc *sc; 162192000Srmacklem 163191783Srmacklem /* Init softc */ 164191783Srmacklem vd->vd_softc = sc = &ps3fb_softc; 165191783Srmacklem 166191783Srmacklem /* XXX: get from HV repository */ 167191783Srmacklem sc->fb_info.fb_depth = 32; 168191783Srmacklem sc->fb_info.fb_height = 480; 169191783Srmacklem sc->fb_info.fb_width = 720; 170191783Srmacklem sc->fb_info.fb_stride = sc->fb_info.fb_width*4; 171191783Srmacklem sc->fb_info.fb_size = sc->fb_info.fb_height * sc->fb_info.fb_stride; 172191783Srmacklem sc->fb_info.fb_bpp = sc->fb_info.fb_stride / sc->fb_info.fb_width * 8; 173191783Srmacklem 174191783Srmacklem /* 175191783Srmacklem * The loader puts the FB at 0x10000000, so use that for now. 176191783Srmacklem */ 177191783Srmacklem 178191783Srmacklem sc->fb_info.fb_vbase = 0x10000000; 179191783Srmacklem 180191783Srmacklem /* 32-bit VGA palette */ 181191783Srmacklem vt_generate_cons_palette(sc->fb_info.fb_cmap, COLOR_FORMAT_RGB, 182191783Srmacklem 255, 0, 255, 8, 255, 16); 183191783Srmacklem 184191783Srmacklem /* Set correct graphics context */ 185191783Srmacklem lv1_gpu_context_attribute(sc->sc_fbcontext, 186191783Srmacklem L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 0, 0, 0, 0); 187191783Srmacklem lv1_gpu_context_attribute(sc->sc_fbcontext, 188191783Srmacklem L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 1, 0, 0, 0); 189191783Srmacklem 190191783Srmacklem vt_fb_init(vd); 191191783Srmacklem sc->fb_info.fb_flags &= ~FB_FLAG_NOMMAP; /* Set wrongly by vt_fb_init */ 192191783Srmacklem 193191783Srmacklem return (CN_INTERNAL); 194191783Srmacklem} 195191783Srmacklem 196191783Srmacklem