xref: /freebsd/sys/powerpc/ps3/ps3_syscons.c (revision fdafd315)
103479763SNathan Whitehorn /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
371e3c308SPedro F. Giffuni  *
449588d0fSNathan Whitehorn  * Copyright (c) 2011-2014 Nathan Whitehorn
503479763SNathan Whitehorn  * All rights reserved.
603479763SNathan Whitehorn  *
703479763SNathan Whitehorn  * Redistribution and use in source and binary forms, with or without
803479763SNathan Whitehorn  * modification, are permitted provided that the following conditions
903479763SNathan Whitehorn  * are met:
1003479763SNathan Whitehorn  * 1. Redistributions of source code must retain the above copyright
1103479763SNathan Whitehorn  *    notice, this list of conditions and the following disclaimer.
1203479763SNathan Whitehorn  * 2. Redistributions in binary form must reproduce the above copyright
1303479763SNathan Whitehorn  *    notice, this list of conditions and the following disclaimer in the
1403479763SNathan Whitehorn  *    documentation and/or other materials provided with the distribution.
1503479763SNathan Whitehorn  *
1603479763SNathan Whitehorn  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1703479763SNathan Whitehorn  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1803479763SNathan Whitehorn  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1903479763SNathan Whitehorn  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2003479763SNathan Whitehorn  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2103479763SNathan Whitehorn  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2203479763SNathan Whitehorn  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2303479763SNathan Whitehorn  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2403479763SNathan Whitehorn  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2503479763SNathan Whitehorn  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2603479763SNathan Whitehorn  * SUCH DAMAGE.
2703479763SNathan Whitehorn  */
2803479763SNathan Whitehorn 
2903479763SNathan Whitehorn #include <sys/param.h>
3003479763SNathan Whitehorn #include <sys/systm.h>
3103479763SNathan Whitehorn #include <sys/kernel.h>
3203479763SNathan Whitehorn #include <sys/sysctl.h>
3303479763SNathan Whitehorn #include <sys/limits.h>
3403479763SNathan Whitehorn #include <sys/conf.h>
3503479763SNathan Whitehorn #include <sys/cons.h>
3603479763SNathan Whitehorn #include <sys/fbio.h>
3703479763SNathan Whitehorn 
3803479763SNathan Whitehorn #include <vm/vm.h>
3903479763SNathan Whitehorn #include <vm/pmap.h>
4003479763SNathan Whitehorn 
4103479763SNathan Whitehorn #include <machine/platform.h>
4203479763SNathan Whitehorn 
43fd520b6eSNathan Whitehorn #include <dev/ofw/openfirm.h>
4449588d0fSNathan Whitehorn #include <dev/vt/vt.h>
4549588d0fSNathan Whitehorn #include <dev/vt/hw/fb/vt_fb.h>
4649588d0fSNathan Whitehorn #include <dev/vt/colors/vt_termcolors.h>
4703479763SNathan Whitehorn 
4803479763SNathan Whitehorn #include "ps3-hvcall.h"
4903479763SNathan Whitehorn 
5003479763SNathan Whitehorn #define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_MODE_SET	0x0100
5103479763SNathan Whitehorn #define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC		0x0101
5203479763SNathan Whitehorn #define  L1GPU_DISPLAY_SYNC_HSYNC			1
5303479763SNathan Whitehorn #define  L1GPU_DISPLAY_SYNC_VSYNC			2
5403479763SNathan Whitehorn #define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP		0x0102
5503479763SNathan Whitehorn 
5649588d0fSNathan Whitehorn static vd_init_t ps3fb_init;
5749588d0fSNathan Whitehorn static vd_probe_t ps3fb_probe;
5803479763SNathan Whitehorn void ps3fb_remap(void);
5903479763SNathan Whitehorn 
6003479763SNathan Whitehorn struct ps3fb_softc {
6149588d0fSNathan Whitehorn 	struct fb_info	fb_info;
62263b7901SNathan Whitehorn 
63263b7901SNathan Whitehorn 	uint64_t	sc_fbhandle;
64263b7901SNathan Whitehorn 	uint64_t	sc_fbcontext;
65263b7901SNathan Whitehorn 	uint64_t	sc_dma_control;
66263b7901SNathan Whitehorn 	uint64_t	sc_driver_info;
67263b7901SNathan Whitehorn 	uint64_t	sc_reports;
68263b7901SNathan Whitehorn 	uint64_t	sc_reports_size;
6903479763SNathan Whitehorn };
7003479763SNathan Whitehorn 
7149588d0fSNathan Whitehorn static struct vt_driver vt_ps3fb_driver = {
7249588d0fSNathan Whitehorn 	.vd_name = "ps3fb",
7349588d0fSNathan Whitehorn 	.vd_probe = ps3fb_probe,
7449588d0fSNathan Whitehorn 	.vd_init = ps3fb_init,
7549588d0fSNathan Whitehorn 	.vd_blank = vt_fb_blank,
76c285e4a5SJean-Sébastien Pédron 	.vd_bitblt_text = vt_fb_bitblt_text,
77631bb572SJean-Sébastien Pédron 	.vd_bitblt_bmp = vt_fb_bitblt_bitmap,
781365d077SJean-Sébastien Pédron 	.vd_drawrect = vt_fb_drawrect,
791365d077SJean-Sébastien Pédron 	.vd_setpixel = vt_fb_setpixel,
803ddad7daSNathan Whitehorn 	.vd_fb_ioctl = vt_fb_ioctl,
813ddad7daSNathan Whitehorn 	.vd_fb_mmap = vt_fb_mmap,
8249588d0fSNathan Whitehorn 	/* Better than VGA, but still generic driver. */
8349588d0fSNathan Whitehorn 	.vd_priority = VD_PRIORITY_GENERIC + 1,
8403479763SNathan Whitehorn };
8503479763SNathan Whitehorn 
8649588d0fSNathan Whitehorn VT_DRIVER_DECLARE(vt_ps3fb, vt_ps3fb_driver);
8703479763SNathan Whitehorn static struct ps3fb_softc ps3fb_softc;
8803479763SNathan Whitehorn 
8903479763SNathan Whitehorn static int
ps3fb_probe(struct vt_device * vd)9049588d0fSNathan Whitehorn ps3fb_probe(struct vt_device *vd)
9103479763SNathan Whitehorn {
9203479763SNathan Whitehorn 	int disable;
9303479763SNathan Whitehorn 	char compatible[64];
9403479763SNathan Whitehorn 	phandle_t root;
9503479763SNathan Whitehorn 
9603479763SNathan Whitehorn 	disable = 0;
9703479763SNathan Whitehorn 	TUNABLE_INT_FETCH("hw.syscons.disable", &disable);
9803479763SNathan Whitehorn 	if (disable != 0)
9903479763SNathan Whitehorn 		return (0);
10003479763SNathan Whitehorn 
101fd520b6eSNathan Whitehorn 	TUNABLE_STR_FETCH("hw.platform", compatible, sizeof(compatible));
102fd520b6eSNathan Whitehorn 	if (strcmp(compatible, "ps3") == 0)
103fd520b6eSNathan Whitehorn 		return (CN_INTERNAL);
104fd520b6eSNathan Whitehorn 
10503479763SNathan Whitehorn 	root = OF_finddevice("/");
10603479763SNathan Whitehorn 	if (OF_getprop(root, "compatible", compatible, sizeof(compatible)) <= 0)
107fd520b6eSNathan Whitehorn                 return (CN_DEAD);
10803479763SNathan Whitehorn 
10903479763SNathan Whitehorn 	if (strncmp(compatible, "sony,ps3", sizeof(compatible)) != 0)
11049588d0fSNathan Whitehorn 		return (CN_DEAD);
11103479763SNathan Whitehorn 
11249588d0fSNathan Whitehorn 	return (CN_INTERNAL);
11303479763SNathan Whitehorn }
11403479763SNathan Whitehorn 
11503479763SNathan Whitehorn void
ps3fb_remap(void)11603479763SNathan Whitehorn ps3fb_remap(void)
11703479763SNathan Whitehorn {
118263b7901SNathan Whitehorn 	struct ps3fb_softc *sc;
11903479763SNathan Whitehorn 	vm_offset_t va, fb_paddr;
120263b7901SNathan Whitehorn 
121263b7901SNathan Whitehorn 	sc = &ps3fb_softc;
12203479763SNathan Whitehorn 
12303479763SNathan Whitehorn 	lv1_gpu_close();
12403479763SNathan Whitehorn 	lv1_gpu_open(0);
12503479763SNathan Whitehorn 
12603479763SNathan Whitehorn 	lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_MODE_SET,
12703479763SNathan Whitehorn 	    0,0,0,0);
12803479763SNathan Whitehorn 	lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_MODE_SET,
12903479763SNathan Whitehorn 	    0,0,1,0);
13003479763SNathan Whitehorn 	lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
13103479763SNathan Whitehorn 	    0,L1GPU_DISPLAY_SYNC_VSYNC,0,0);
13203479763SNathan Whitehorn 	lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
13303479763SNathan Whitehorn 	    1,L1GPU_DISPLAY_SYNC_VSYNC,0,0);
1340a9ce08bSNathan Whitehorn 	lv1_gpu_memory_allocate(roundup2(sc->fb_info.fb_size, 1024*1024),
1350a9ce08bSNathan Whitehorn 	    0, 0, 0, 0, &sc->sc_fbhandle, &fb_paddr);
13649588d0fSNathan Whitehorn 	lv1_gpu_context_allocate(sc->sc_fbhandle, 0, &sc->sc_fbcontext,
13749588d0fSNathan Whitehorn 	    &sc->sc_dma_control, &sc->sc_driver_info, &sc->sc_reports,
13849588d0fSNathan Whitehorn 	    &sc->sc_reports_size);
13903479763SNathan Whitehorn 
140263b7901SNathan Whitehorn 	lv1_gpu_context_attribute(sc->sc_fbcontext,
14103479763SNathan Whitehorn 	    L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 0, 0, 0, 0);
142263b7901SNathan Whitehorn 	lv1_gpu_context_attribute(sc->sc_fbcontext,
14303479763SNathan Whitehorn 	    L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 1, 0, 0, 0);
14403479763SNathan Whitehorn 
14549588d0fSNathan Whitehorn 	sc->fb_info.fb_pbase = fb_paddr;
1460a9ce08bSNathan Whitehorn 	for (va = 0; va < sc->fb_info.fb_size; va += PAGE_SIZE)
14703479763SNathan Whitehorn 		pmap_kenter_attr(0x10000000 + va, fb_paddr + va,
14803479763SNathan Whitehorn 		    VM_MEMATTR_WRITE_COMBINING);
149f1d2752fSNathan Whitehorn 	sc->fb_info.fb_flags &= ~FB_FLAG_NOWRITE;
15003479763SNathan Whitehorn }
15103479763SNathan Whitehorn 
15203479763SNathan Whitehorn static int
ps3fb_init(struct vt_device * vd)15349588d0fSNathan Whitehorn ps3fb_init(struct vt_device *vd)
15403479763SNathan Whitehorn {
15503479763SNathan Whitehorn 	struct ps3fb_softc *sc;
1565261ac0eSNathan Whitehorn 	char linux_video_mode[24];
1575261ac0eSNathan Whitehorn 	int linux_video_mode_num = 0;
15803479763SNathan Whitehorn 
15949588d0fSNathan Whitehorn 	/* Init softc */
16049588d0fSNathan Whitehorn 	vd->vd_softc = sc = &ps3fb_softc;
16103479763SNathan Whitehorn 
16249588d0fSNathan Whitehorn 	sc->fb_info.fb_depth = 32;
1635261ac0eSNathan Whitehorn 	sc->fb_info.fb_height = 1080;
1645261ac0eSNathan Whitehorn 	sc->fb_info.fb_width = 1920;
1655261ac0eSNathan Whitehorn 
1665261ac0eSNathan Whitehorn 	/* See if the bootloader has passed a graphics mode to use */
1675261ac0eSNathan Whitehorn 	bzero(linux_video_mode, sizeof(linux_video_mode));
1685261ac0eSNathan Whitehorn 	TUNABLE_STR_FETCH("video", linux_video_mode, sizeof(linux_video_mode));
1695261ac0eSNathan Whitehorn 	sscanf(linux_video_mode, "ps3fb:mode:%d", &linux_video_mode_num);
1705261ac0eSNathan Whitehorn 
1715261ac0eSNathan Whitehorn 	switch (linux_video_mode_num) {
1725261ac0eSNathan Whitehorn 	case 1:
1735261ac0eSNathan Whitehorn 	case 2:
17449588d0fSNathan Whitehorn 		sc->fb_info.fb_height = 480;
17549588d0fSNathan Whitehorn 		sc->fb_info.fb_width = 720;
1765261ac0eSNathan Whitehorn 		break;
1775261ac0eSNathan Whitehorn 	case 3:
1785261ac0eSNathan Whitehorn 	case 8:
1795261ac0eSNathan Whitehorn 		sc->fb_info.fb_height = 720;
1805261ac0eSNathan Whitehorn 		sc->fb_info.fb_width = 1280;
1815261ac0eSNathan Whitehorn 		break;
1825261ac0eSNathan Whitehorn 	case 4:
1835261ac0eSNathan Whitehorn 	case 5:
1845261ac0eSNathan Whitehorn 	case 9:
1855261ac0eSNathan Whitehorn 	case 10:
1865261ac0eSNathan Whitehorn 		sc->fb_info.fb_height = 1080;
1875261ac0eSNathan Whitehorn 		sc->fb_info.fb_width = 1920;
1885261ac0eSNathan Whitehorn 		break;
1895261ac0eSNathan Whitehorn 	case 6:
1905261ac0eSNathan Whitehorn 	case 7:
1915261ac0eSNathan Whitehorn 		sc->fb_info.fb_height = 576;
1925261ac0eSNathan Whitehorn 		sc->fb_info.fb_width = 720;
1935261ac0eSNathan Whitehorn 		break;
1945261ac0eSNathan Whitehorn 	case 11:
1955261ac0eSNathan Whitehorn 		sc->fb_info.fb_height = 768;
1965261ac0eSNathan Whitehorn 		sc->fb_info.fb_width = 1024;
1975261ac0eSNathan Whitehorn 		break;
1985261ac0eSNathan Whitehorn 	case 12:
1995261ac0eSNathan Whitehorn 		sc->fb_info.fb_height = 1024;
2005261ac0eSNathan Whitehorn 		sc->fb_info.fb_width = 1280;
2015261ac0eSNathan Whitehorn 		break;
2025261ac0eSNathan Whitehorn 	case 13:
2035261ac0eSNathan Whitehorn 		sc->fb_info.fb_height = 1200;
2045261ac0eSNathan Whitehorn 		sc->fb_info.fb_width = 1920;
2055261ac0eSNathan Whitehorn 		break;
2065261ac0eSNathan Whitehorn 	}
2075261ac0eSNathan Whitehorn 
2085261ac0eSNathan Whitehorn 	/* Allow explicitly-specified values for us to override everything */
2090a9ce08bSNathan Whitehorn 	TUNABLE_INT_FETCH("hw.ps3fb.height", &sc->fb_info.fb_height);
2100a9ce08bSNathan Whitehorn 	TUNABLE_INT_FETCH("hw.ps3fb.width", &sc->fb_info.fb_width);
2115261ac0eSNathan Whitehorn 
21249588d0fSNathan Whitehorn 	sc->fb_info.fb_stride = sc->fb_info.fb_width*4;
21349588d0fSNathan Whitehorn 	sc->fb_info.fb_size = sc->fb_info.fb_height * sc->fb_info.fb_stride;
21449588d0fSNathan Whitehorn 	sc->fb_info.fb_bpp = sc->fb_info.fb_stride / sc->fb_info.fb_width * 8;
21503479763SNathan Whitehorn 
21649588d0fSNathan Whitehorn 	/*
217f1d2752fSNathan Whitehorn 	 * Arbitrarily choose address for the framebuffer
21849588d0fSNathan Whitehorn 	 */
21903479763SNathan Whitehorn 
22049588d0fSNathan Whitehorn 	sc->fb_info.fb_vbase = 0x10000000;
221f1d2752fSNathan Whitehorn 	sc->fb_info.fb_flags |= FB_FLAG_NOWRITE; /* Not available yet */
222f1d2752fSNathan Whitehorn 	sc->fb_info.fb_cmsize = 16;
22349588d0fSNathan Whitehorn 
22449588d0fSNathan Whitehorn 	/* 32-bit VGA palette */
225b9f3b63aSLeandro Lupori 	vt_config_cons_colors(&sc->fb_info, COLOR_FORMAT_RGB,
22667530f82SNathan Whitehorn 	    255, 16, 255, 8, 255, 0);
22749588d0fSNathan Whitehorn 
22849588d0fSNathan Whitehorn 	/* Set correct graphics context */
229263b7901SNathan Whitehorn 	lv1_gpu_context_attribute(sc->sc_fbcontext,
230263b7901SNathan Whitehorn 	    L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 0, 0, 0, 0);
231263b7901SNathan Whitehorn 	lv1_gpu_context_attribute(sc->sc_fbcontext,
232263b7901SNathan Whitehorn 	    L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 1, 0, 0, 0);
233263b7901SNathan Whitehorn 
23449588d0fSNathan Whitehorn 	vt_fb_init(vd);
23549588d0fSNathan Whitehorn 
23649588d0fSNathan Whitehorn 	return (CN_INTERNAL);
23703479763SNathan Whitehorn }
238