xref: /freebsd/sys/powerpc/ps3/ps3_syscons.c (revision f1d2752f)
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