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