xref: /freebsd/sys/powerpc/ps3/ps3_syscons.c (revision 0a9ce08b)
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 
45fd520b6eSNathan Whitehorn #include <dev/ofw/openfirm.h>
4649588d0fSNathan Whitehorn #include <dev/vt/vt.h>
4749588d0fSNathan Whitehorn #include <dev/vt/hw/fb/vt_fb.h>
4849588d0fSNathan Whitehorn #include <dev/vt/colors/vt_termcolors.h>
4903479763SNathan Whitehorn 
5003479763SNathan Whitehorn #include "ps3-hvcall.h"
5103479763SNathan Whitehorn 
5203479763SNathan Whitehorn #define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_MODE_SET	0x0100
5303479763SNathan Whitehorn #define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC		0x0101
5403479763SNathan Whitehorn #define  L1GPU_DISPLAY_SYNC_HSYNC			1
5503479763SNathan Whitehorn #define  L1GPU_DISPLAY_SYNC_VSYNC			2
5603479763SNathan Whitehorn #define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP		0x0102
5703479763SNathan Whitehorn 
5849588d0fSNathan Whitehorn static vd_init_t ps3fb_init;
5949588d0fSNathan Whitehorn static vd_probe_t ps3fb_probe;
6003479763SNathan Whitehorn void ps3fb_remap(void);
6103479763SNathan Whitehorn 
6203479763SNathan Whitehorn struct ps3fb_softc {
6349588d0fSNathan Whitehorn 	struct fb_info	fb_info;
64263b7901SNathan Whitehorn 
65263b7901SNathan Whitehorn 	uint64_t	sc_fbhandle;
66263b7901SNathan Whitehorn 	uint64_t	sc_fbcontext;
67263b7901SNathan Whitehorn 	uint64_t	sc_dma_control;
68263b7901SNathan Whitehorn 	uint64_t	sc_driver_info;
69263b7901SNathan Whitehorn 	uint64_t	sc_reports;
70263b7901SNathan Whitehorn 	uint64_t	sc_reports_size;
7103479763SNathan Whitehorn };
7203479763SNathan Whitehorn 
7349588d0fSNathan Whitehorn static struct vt_driver vt_ps3fb_driver = {
7449588d0fSNathan Whitehorn 	.vd_name = "ps3fb",
7549588d0fSNathan Whitehorn 	.vd_probe = ps3fb_probe,
7649588d0fSNathan Whitehorn 	.vd_init = ps3fb_init,
7749588d0fSNathan Whitehorn 	.vd_blank = vt_fb_blank,
78c285e4a5SJean-Sébastien Pédron 	.vd_bitblt_text = vt_fb_bitblt_text,
79631bb572SJean-Sébastien Pédron 	.vd_bitblt_bmp = vt_fb_bitblt_bitmap,
801365d077SJean-Sébastien Pédron 	.vd_drawrect = vt_fb_drawrect,
811365d077SJean-Sébastien Pédron 	.vd_setpixel = vt_fb_setpixel,
823ddad7daSNathan Whitehorn 	.vd_fb_ioctl = vt_fb_ioctl,
833ddad7daSNathan Whitehorn 	.vd_fb_mmap = vt_fb_mmap,
8449588d0fSNathan Whitehorn 	/* Better than VGA, but still generic driver. */
8549588d0fSNathan Whitehorn 	.vd_priority = VD_PRIORITY_GENERIC + 1,
8603479763SNathan Whitehorn };
8703479763SNathan Whitehorn 
8849588d0fSNathan Whitehorn VT_DRIVER_DECLARE(vt_ps3fb, vt_ps3fb_driver);
8903479763SNathan Whitehorn static struct ps3fb_softc ps3fb_softc;
9003479763SNathan Whitehorn 
9103479763SNathan Whitehorn static int
9249588d0fSNathan Whitehorn ps3fb_probe(struct vt_device *vd)
9303479763SNathan Whitehorn {
9403479763SNathan Whitehorn 	struct ps3fb_softc *sc;
9503479763SNathan Whitehorn 	int disable;
9603479763SNathan Whitehorn 	char compatible[64];
9703479763SNathan Whitehorn 	phandle_t root;
9803479763SNathan Whitehorn 
9903479763SNathan Whitehorn 	disable = 0;
10003479763SNathan Whitehorn 	TUNABLE_INT_FETCH("hw.syscons.disable", &disable);
10103479763SNathan Whitehorn 	if (disable != 0)
10203479763SNathan Whitehorn 		return (0);
10303479763SNathan Whitehorn 
10403479763SNathan Whitehorn 	sc = &ps3fb_softc;
10503479763SNathan Whitehorn 
106fd520b6eSNathan Whitehorn 	TUNABLE_STR_FETCH("hw.platform", compatible, sizeof(compatible));
107fd520b6eSNathan Whitehorn 	if (strcmp(compatible, "ps3") == 0)
108fd520b6eSNathan Whitehorn 		return (CN_INTERNAL);
109fd520b6eSNathan Whitehorn 
11003479763SNathan Whitehorn 	root = OF_finddevice("/");
11103479763SNathan Whitehorn 	if (OF_getprop(root, "compatible", compatible, sizeof(compatible)) <= 0)
112fd520b6eSNathan Whitehorn                 return (CN_DEAD);
11303479763SNathan Whitehorn 
11403479763SNathan Whitehorn 	if (strncmp(compatible, "sony,ps3", sizeof(compatible)) != 0)
11549588d0fSNathan Whitehorn 		return (CN_DEAD);
11603479763SNathan Whitehorn 
11749588d0fSNathan Whitehorn 	return (CN_INTERNAL);
11803479763SNathan Whitehorn }
11903479763SNathan Whitehorn 
12003479763SNathan Whitehorn void
12103479763SNathan Whitehorn ps3fb_remap(void)
12203479763SNathan Whitehorn {
123263b7901SNathan Whitehorn 	struct ps3fb_softc *sc;
12403479763SNathan Whitehorn 	vm_offset_t va, fb_paddr;
125263b7901SNathan Whitehorn 
126263b7901SNathan Whitehorn 	sc = &ps3fb_softc;
12703479763SNathan Whitehorn 
12803479763SNathan Whitehorn 	lv1_gpu_close();
12903479763SNathan Whitehorn 	lv1_gpu_open(0);
13003479763SNathan Whitehorn 
13103479763SNathan Whitehorn 	lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_MODE_SET,
13203479763SNathan Whitehorn 	    0,0,0,0);
13303479763SNathan Whitehorn 	lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_MODE_SET,
13403479763SNathan Whitehorn 	    0,0,1,0);
13503479763SNathan Whitehorn 	lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
13603479763SNathan Whitehorn 	    0,L1GPU_DISPLAY_SYNC_VSYNC,0,0);
13703479763SNathan Whitehorn 	lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
13803479763SNathan Whitehorn 	    1,L1GPU_DISPLAY_SYNC_VSYNC,0,0);
1390a9ce08bSNathan Whitehorn 	lv1_gpu_memory_allocate(roundup2(sc->fb_info.fb_size, 1024*1024),
1400a9ce08bSNathan Whitehorn 	    0, 0, 0, 0, &sc->sc_fbhandle, &fb_paddr);
14149588d0fSNathan Whitehorn 	lv1_gpu_context_allocate(sc->sc_fbhandle, 0, &sc->sc_fbcontext,
14249588d0fSNathan Whitehorn 	    &sc->sc_dma_control, &sc->sc_driver_info, &sc->sc_reports,
14349588d0fSNathan Whitehorn 	    &sc->sc_reports_size);
14403479763SNathan Whitehorn 
145263b7901SNathan Whitehorn 	lv1_gpu_context_attribute(sc->sc_fbcontext,
14603479763SNathan Whitehorn 	    L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 0, 0, 0, 0);
147263b7901SNathan Whitehorn 	lv1_gpu_context_attribute(sc->sc_fbcontext,
14803479763SNathan Whitehorn 	    L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 1, 0, 0, 0);
14903479763SNathan Whitehorn 
15049588d0fSNathan Whitehorn 	sc->fb_info.fb_pbase = fb_paddr;
1510a9ce08bSNathan Whitehorn 	for (va = 0; va < sc->fb_info.fb_size; va += PAGE_SIZE)
15203479763SNathan Whitehorn 		pmap_kenter_attr(0x10000000 + va, fb_paddr + va,
15303479763SNathan Whitehorn 		    VM_MEMATTR_WRITE_COMBINING);
154f1d2752fSNathan Whitehorn 	sc->fb_info.fb_flags &= ~FB_FLAG_NOWRITE;
15503479763SNathan Whitehorn }
15603479763SNathan Whitehorn 
15703479763SNathan Whitehorn static int
15849588d0fSNathan Whitehorn ps3fb_init(struct vt_device *vd)
15903479763SNathan Whitehorn {
16003479763SNathan Whitehorn 	struct ps3fb_softc *sc;
16103479763SNathan Whitehorn 
16249588d0fSNathan Whitehorn 	/* Init softc */
16349588d0fSNathan Whitehorn 	vd->vd_softc = sc = &ps3fb_softc;
16403479763SNathan Whitehorn 
16549588d0fSNathan Whitehorn 	/* XXX: get from HV repository */
16649588d0fSNathan Whitehorn 	sc->fb_info.fb_depth = 32;
16749588d0fSNathan Whitehorn 	sc->fb_info.fb_height = 480;
16849588d0fSNathan Whitehorn 	sc->fb_info.fb_width = 720;
1690a9ce08bSNathan Whitehorn 	TUNABLE_INT_FETCH("hw.ps3fb.height", &sc->fb_info.fb_height);
1700a9ce08bSNathan Whitehorn 	TUNABLE_INT_FETCH("hw.ps3fb.width", &sc->fb_info.fb_width);
17149588d0fSNathan Whitehorn 	sc->fb_info.fb_stride = sc->fb_info.fb_width*4;
17249588d0fSNathan Whitehorn 	sc->fb_info.fb_size = sc->fb_info.fb_height * sc->fb_info.fb_stride;
17349588d0fSNathan Whitehorn 	sc->fb_info.fb_bpp = sc->fb_info.fb_stride / sc->fb_info.fb_width * 8;
17403479763SNathan Whitehorn 
17549588d0fSNathan Whitehorn 	/*
176f1d2752fSNathan Whitehorn 	 * Arbitrarily choose address for the framebuffer
17749588d0fSNathan Whitehorn 	 */
17803479763SNathan Whitehorn 
17949588d0fSNathan Whitehorn 	sc->fb_info.fb_vbase = 0x10000000;
180f1d2752fSNathan Whitehorn 	sc->fb_info.fb_flags |= FB_FLAG_NOWRITE; /* Not available yet */
181f1d2752fSNathan Whitehorn 	sc->fb_info.fb_cmsize = 16;
18249588d0fSNathan Whitehorn 
18349588d0fSNathan Whitehorn 	/* 32-bit VGA palette */
184ca885fdfSJean-Sébastien Pédron 	vt_generate_cons_palette(sc->fb_info.fb_cmap, COLOR_FORMAT_RGB,
185ca885fdfSJean-Sébastien Pédron 	    255, 0, 255, 8, 255, 16);
18649588d0fSNathan Whitehorn 
18749588d0fSNathan Whitehorn 	/* Set correct graphics context */
188263b7901SNathan Whitehorn 	lv1_gpu_context_attribute(sc->sc_fbcontext,
189263b7901SNathan Whitehorn 	    L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 0, 0, 0, 0);
190263b7901SNathan Whitehorn 	lv1_gpu_context_attribute(sc->sc_fbcontext,
191263b7901SNathan Whitehorn 	    L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 1, 0, 0, 0);
192263b7901SNathan Whitehorn 
19349588d0fSNathan Whitehorn 	vt_fb_init(vd);
1949ed297c8SNathan Whitehorn 	sc->fb_info.fb_flags &= ~FB_FLAG_NOMMAP; /* Set wrongly by vt_fb_init */
19549588d0fSNathan Whitehorn 
19649588d0fSNathan Whitehorn 	return (CN_INTERNAL);
19703479763SNathan Whitehorn }
19803479763SNathan Whitehorn 
199