ps3_syscons.c revision 268895
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: head/sys/powerpc/ps3/ps3_syscons.c 268895 2014-07-19 23:39:17Z nwhitehorn $");
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#include <machine/pmap.h>
44217044Snwhitehorn
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 PS3FB_SIZE (4*1024*1024)
52217044Snwhitehorn
53217044Snwhitehorn#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_MODE_SET	0x0100
54217044Snwhitehorn#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC		0x0101
55217044Snwhitehorn#define  L1GPU_DISPLAY_SYNC_HSYNC			1
56217044Snwhitehorn#define  L1GPU_DISPLAY_SYNC_VSYNC			2
57217044Snwhitehorn#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP		0x0102
58217044Snwhitehorn
59265871Snwhitehornstatic vd_init_t ps3fb_init;
60265871Snwhitehornstatic vd_probe_t ps3fb_probe;
61217044Snwhitehornvoid ps3fb_remap(void);
62217044Snwhitehorn
63217044Snwhitehornstruct ps3fb_softc {
64265871Snwhitehorn	struct fb_info	fb_info;
65217044Snwhitehorn
66228689Snwhitehorn	uint64_t	sc_fbhandle;
67228689Snwhitehorn	uint64_t	sc_fbcontext;
68228689Snwhitehorn	uint64_t	sc_dma_control;
69228689Snwhitehorn	uint64_t	sc_driver_info;
70228689Snwhitehorn	uint64_t	sc_reports;
71228689Snwhitehorn	uint64_t	sc_reports_size;
72217044Snwhitehorn};
73217044Snwhitehorn
74265871Snwhitehornstatic struct vt_driver vt_ps3fb_driver = {
75265871Snwhitehorn	.vd_name = "ps3fb",
76265871Snwhitehorn	.vd_probe = ps3fb_probe,
77265871Snwhitehorn	.vd_init = ps3fb_init,
78265871Snwhitehorn	.vd_blank = vt_fb_blank,
79265871Snwhitehorn	.vd_bitbltchr = vt_fb_bitbltchr,
80265871Snwhitehorn	.vd_maskbitbltchr = vt_fb_maskbitbltchr,
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#if 0
97217044Snwhitehorn	phandle_t root;
98217044Snwhitehorn#endif
99217044Snwhitehorn
100217044Snwhitehorn	disable = 0;
101217044Snwhitehorn	TUNABLE_INT_FETCH("hw.syscons.disable", &disable);
102217044Snwhitehorn	if (disable != 0)
103217044Snwhitehorn		return (0);
104217044Snwhitehorn
105217044Snwhitehorn	sc = &ps3fb_softc;
106217044Snwhitehorn
107217044Snwhitehorn#if 0
108217044Snwhitehorn	root = OF_finddevice("/");
109217044Snwhitehorn	if (OF_getprop(root, "compatible", compatible, sizeof(compatible)) <= 0)
110217044Snwhitehorn                return (0);
111217044Snwhitehorn
112217044Snwhitehorn	if (strncmp(compatible, "sony,ps3", sizeof(compatible)) != 0)
113217044Snwhitehorn		return (0);
114217044Snwhitehorn#else
115217044Snwhitehorn	TUNABLE_STR_FETCH("hw.platform", compatible, sizeof(compatible));
116217044Snwhitehorn	if (strcmp(compatible, "ps3") != 0)
117265871Snwhitehorn		return (CN_DEAD);
118217044Snwhitehorn#endif
119217044Snwhitehorn
120265871Snwhitehorn	return (CN_INTERNAL);
121217044Snwhitehorn}
122217044Snwhitehorn
123217044Snwhitehornvoid
124217044Snwhitehornps3fb_remap(void)
125217044Snwhitehorn{
126228689Snwhitehorn	struct ps3fb_softc *sc;
127217044Snwhitehorn	vm_offset_t va, fb_paddr;
128217044Snwhitehorn
129228689Snwhitehorn	sc = &ps3fb_softc;
130228689Snwhitehorn
131217044Snwhitehorn	lv1_gpu_close();
132217044Snwhitehorn	lv1_gpu_open(0);
133217044Snwhitehorn
134217044Snwhitehorn	lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_MODE_SET,
135217044Snwhitehorn	    0,0,0,0);
136217044Snwhitehorn	lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_MODE_SET,
137217044Snwhitehorn	    0,0,1,0);
138217044Snwhitehorn	lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
139217044Snwhitehorn	    0,L1GPU_DISPLAY_SYNC_VSYNC,0,0);
140217044Snwhitehorn	lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
141217044Snwhitehorn	    1,L1GPU_DISPLAY_SYNC_VSYNC,0,0);
142265871Snwhitehorn	lv1_gpu_memory_allocate(PS3FB_SIZE, 0, 0, 0, 0, &sc->sc_fbhandle,
143265871Snwhitehorn	    &fb_paddr);
144265871Snwhitehorn	lv1_gpu_context_allocate(sc->sc_fbhandle, 0, &sc->sc_fbcontext,
145265871Snwhitehorn	    &sc->sc_dma_control, &sc->sc_driver_info, &sc->sc_reports,
146265871Snwhitehorn	    &sc->sc_reports_size);
147217044Snwhitehorn
148228689Snwhitehorn	lv1_gpu_context_attribute(sc->sc_fbcontext,
149217044Snwhitehorn	    L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 0, 0, 0, 0);
150228689Snwhitehorn	lv1_gpu_context_attribute(sc->sc_fbcontext,
151217044Snwhitehorn	    L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 1, 0, 0, 0);
152217044Snwhitehorn
153265871Snwhitehorn	sc->fb_info.fb_pbase = fb_paddr;
154217044Snwhitehorn	for (va = 0; va < PS3FB_SIZE; va += PAGE_SIZE)
155217044Snwhitehorn		pmap_kenter_attr(0x10000000 + va, fb_paddr + va,
156217044Snwhitehorn		    VM_MEMATTR_WRITE_COMBINING);
157217044Snwhitehorn}
158217044Snwhitehorn
159217044Snwhitehornstatic int
160265871Snwhitehornps3fb_init(struct vt_device *vd)
161217044Snwhitehorn{
162217044Snwhitehorn	struct ps3fb_softc *sc;
163217044Snwhitehorn
164265871Snwhitehorn	/* Init softc */
165265871Snwhitehorn	vd->vd_softc = sc = &ps3fb_softc;
166217044Snwhitehorn
167265871Snwhitehorn	/* XXX: get from HV repository */
168265871Snwhitehorn	sc->fb_info.fb_depth = 32;
169265871Snwhitehorn	sc->fb_info.fb_height = 480;
170265871Snwhitehorn	sc->fb_info.fb_width = 720;
171265871Snwhitehorn	sc->fb_info.fb_stride = sc->fb_info.fb_width*4;
172265871Snwhitehorn	sc->fb_info.fb_size = sc->fb_info.fb_height * sc->fb_info.fb_stride;
173265871Snwhitehorn	sc->fb_info.fb_bpp = sc->fb_info.fb_stride / sc->fb_info.fb_width * 8;
174217044Snwhitehorn
175217044Snwhitehorn	/*
176265871Snwhitehorn	 * The loader puts the FB at 0x10000000, so use that for now.
177217044Snwhitehorn	 */
178217044Snwhitehorn
179265871Snwhitehorn	sc->fb_info.fb_vbase = 0x10000000;
180217044Snwhitehorn
181265871Snwhitehorn	/* 32-bit VGA palette */
182265871Snwhitehorn	vt_generate_vga_palette(sc->fb_info.fb_cmap, COLOR_FORMAT_RGB,
183265871Snwhitehorn	    255, 16, 255, 8, 255, 0);
184217044Snwhitehorn
185265871Snwhitehorn	/* Set correct graphics context */
186228689Snwhitehorn	lv1_gpu_context_attribute(sc->sc_fbcontext,
187228689Snwhitehorn	    L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 0, 0, 0, 0);
188228689Snwhitehorn	lv1_gpu_context_attribute(sc->sc_fbcontext,
189228689Snwhitehorn	    L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 1, 0, 0, 0);
190228689Snwhitehorn
191265871Snwhitehorn	fb_probe(&sc->fb_info);
192268895Snwhitehorn	sc->fb_info.fb_flags &= ~FB_FLAG_NOMMAP; /* Set wrongly by fb_probe */
193265871Snwhitehorn	vt_fb_init(vd);
194217044Snwhitehorn
195265871Snwhitehorn	/* Clear the screen. */
196265871Snwhitehorn	vt_fb_blank(vd, TC_BLACK);
197217044Snwhitehorn
198265871Snwhitehorn	return (CN_INTERNAL);
199217044Snwhitehorn}
200217044Snwhitehorn
201