xref: /freebsd/sys/arm/ti/am335x/am335x_lcd_syscons.c (revision fdafd315ad0d0f28a11b9fb4476a9ab059c62b92)
124ca3d19SOleksandr Tymoshenko /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3af3dc4a7SPedro F. Giffuni  *
424ca3d19SOleksandr Tymoshenko  * Copyright (c) 2013 Oleksandr Tymoshenko <gonzo@freebsd.org>
524ca3d19SOleksandr Tymoshenko  * All rights reserved.
624ca3d19SOleksandr Tymoshenko  *
724ca3d19SOleksandr Tymoshenko  * Redistribution and use in source and binary forms, with or without
824ca3d19SOleksandr Tymoshenko  * modification, are permitted provided that the following conditions
924ca3d19SOleksandr Tymoshenko  * are met:
1024ca3d19SOleksandr Tymoshenko  * 1. Redistributions of source code must retain the above copyright
1124ca3d19SOleksandr Tymoshenko  *    notice, this list of conditions and the following disclaimer.
1224ca3d19SOleksandr Tymoshenko  * 2. Redistributions in binary form must reproduce the above copyright
1324ca3d19SOleksandr Tymoshenko  *    notice, this list of conditions and the following disclaimer in the
1424ca3d19SOleksandr Tymoshenko  *    documentation and/or other materials provided with the distribution.
1524ca3d19SOleksandr Tymoshenko  *
1624ca3d19SOleksandr Tymoshenko  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1724ca3d19SOleksandr Tymoshenko  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1824ca3d19SOleksandr Tymoshenko  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1924ca3d19SOleksandr Tymoshenko  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2024ca3d19SOleksandr Tymoshenko  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2124ca3d19SOleksandr Tymoshenko  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2224ca3d19SOleksandr Tymoshenko  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2324ca3d19SOleksandr Tymoshenko  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2424ca3d19SOleksandr Tymoshenko  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2524ca3d19SOleksandr Tymoshenko  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2624ca3d19SOleksandr Tymoshenko  * SUCH DAMAGE.
2724ca3d19SOleksandr Tymoshenko  */
28*fdafd315SWarner Losh 
2924ca3d19SOleksandr Tymoshenko #include <sys/param.h>
3024ca3d19SOleksandr Tymoshenko #include <sys/systm.h>
3124ca3d19SOleksandr Tymoshenko #include <sys/bus.h>
3224ca3d19SOleksandr Tymoshenko #include <sys/conf.h>
3324ca3d19SOleksandr Tymoshenko #include <sys/endian.h>
3424ca3d19SOleksandr Tymoshenko #include <sys/kernel.h>
3524ca3d19SOleksandr Tymoshenko #include <sys/lock.h>
3624ca3d19SOleksandr Tymoshenko #include <sys/malloc.h>
3724ca3d19SOleksandr Tymoshenko #include <sys/module.h>
3824ca3d19SOleksandr Tymoshenko #include <sys/mutex.h>
3924ca3d19SOleksandr Tymoshenko #include <sys/resource.h>
4024ca3d19SOleksandr Tymoshenko #include <sys/rman.h>
4124ca3d19SOleksandr Tymoshenko #include <sys/fbio.h>
4224ca3d19SOleksandr Tymoshenko #include <sys/consio.h>
4324ca3d19SOleksandr Tymoshenko 
4424ca3d19SOleksandr Tymoshenko #include <sys/kdb.h>
4524ca3d19SOleksandr Tymoshenko 
4624ca3d19SOleksandr Tymoshenko #include <machine/bus.h>
4724ca3d19SOleksandr Tymoshenko #include <machine/resource.h>
4824ca3d19SOleksandr Tymoshenko #include <machine/intr.h>
4924ca3d19SOleksandr Tymoshenko 
5024ca3d19SOleksandr Tymoshenko #include <dev/ofw/ofw_bus.h>
5124ca3d19SOleksandr Tymoshenko #include <dev/ofw/ofw_bus_subr.h>
5224ca3d19SOleksandr Tymoshenko 
5324ca3d19SOleksandr Tymoshenko #include <dev/fb/fbreg.h>
5424ca3d19SOleksandr Tymoshenko #include <dev/syscons/syscons.h>
5524ca3d19SOleksandr Tymoshenko 
5624ca3d19SOleksandr Tymoshenko #include "am335x_lcd.h"
5724ca3d19SOleksandr Tymoshenko 
5824ca3d19SOleksandr Tymoshenko struct video_adapter_softc {
5924ca3d19SOleksandr Tymoshenko 	/* Videoadpater part */
6024ca3d19SOleksandr Tymoshenko 	video_adapter_t	va;
6124ca3d19SOleksandr Tymoshenko 	int		console;
6224ca3d19SOleksandr Tymoshenko 
6324ca3d19SOleksandr Tymoshenko 	intptr_t	fb_addr;
6424ca3d19SOleksandr Tymoshenko 	intptr_t	fb_paddr;
6524ca3d19SOleksandr Tymoshenko 	unsigned int	fb_size;
6624ca3d19SOleksandr Tymoshenko 
6724ca3d19SOleksandr Tymoshenko 	unsigned int	height;
6824ca3d19SOleksandr Tymoshenko 	unsigned int	width;
6924ca3d19SOleksandr Tymoshenko 	unsigned int	depth;
7024ca3d19SOleksandr Tymoshenko 	unsigned int	stride;
7124ca3d19SOleksandr Tymoshenko 
7224ca3d19SOleksandr Tymoshenko 	unsigned int	xmargin;
7324ca3d19SOleksandr Tymoshenko 	unsigned int	ymargin;
7424ca3d19SOleksandr Tymoshenko 
7524ca3d19SOleksandr Tymoshenko 	unsigned char	*font;
7624ca3d19SOleksandr Tymoshenko 	int		initialized;
7724ca3d19SOleksandr Tymoshenko };
7824ca3d19SOleksandr Tymoshenko 
7924ca3d19SOleksandr Tymoshenko struct argb {
8024ca3d19SOleksandr Tymoshenko 	uint8_t		a;
8124ca3d19SOleksandr Tymoshenko 	uint8_t		r;
8224ca3d19SOleksandr Tymoshenko 	uint8_t		g;
8324ca3d19SOleksandr Tymoshenko 	uint8_t		b;
8424ca3d19SOleksandr Tymoshenko };
8524ca3d19SOleksandr Tymoshenko 
8624ca3d19SOleksandr Tymoshenko static struct argb am335x_syscons_palette[16] = {
8724ca3d19SOleksandr Tymoshenko 	{0x00, 0x00, 0x00, 0x00},
8824ca3d19SOleksandr Tymoshenko 	{0x00, 0x00, 0x00, 0xaa},
8924ca3d19SOleksandr Tymoshenko 	{0x00, 0x00, 0xaa, 0x00},
9024ca3d19SOleksandr Tymoshenko 	{0x00, 0x00, 0xaa, 0xaa},
9124ca3d19SOleksandr Tymoshenko 	{0x00, 0xaa, 0x00, 0x00},
9224ca3d19SOleksandr Tymoshenko 	{0x00, 0xaa, 0x00, 0xaa},
9324ca3d19SOleksandr Tymoshenko 	{0x00, 0xaa, 0x55, 0x00},
9424ca3d19SOleksandr Tymoshenko 	{0x00, 0xaa, 0xaa, 0xaa},
9524ca3d19SOleksandr Tymoshenko 	{0x00, 0x55, 0x55, 0x55},
9624ca3d19SOleksandr Tymoshenko 	{0x00, 0x55, 0x55, 0xff},
9724ca3d19SOleksandr Tymoshenko 	{0x00, 0x55, 0xff, 0x55},
9824ca3d19SOleksandr Tymoshenko 	{0x00, 0x55, 0xff, 0xff},
9924ca3d19SOleksandr Tymoshenko 	{0x00, 0xff, 0x55, 0x55},
10024ca3d19SOleksandr Tymoshenko 	{0x00, 0xff, 0x55, 0xff},
10124ca3d19SOleksandr Tymoshenko 	{0x00, 0xff, 0xff, 0x55},
10224ca3d19SOleksandr Tymoshenko 	{0x00, 0xff, 0xff, 0xff}
10324ca3d19SOleksandr Tymoshenko };
10424ca3d19SOleksandr Tymoshenko 
10524ca3d19SOleksandr Tymoshenko /* mouse pointer from dev/syscons/scgfbrndr.c */
10624ca3d19SOleksandr Tymoshenko static u_char mouse_pointer[16] = {
10724ca3d19SOleksandr Tymoshenko         0x00, 0x40, 0x60, 0x70, 0x78, 0x7c, 0x7e, 0x68,
10824ca3d19SOleksandr Tymoshenko         0x0c, 0x0c, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00
10924ca3d19SOleksandr Tymoshenko };
11024ca3d19SOleksandr Tymoshenko 
11124ca3d19SOleksandr Tymoshenko #define	AM335X_FONT_HEIGHT	16
11224ca3d19SOleksandr Tymoshenko 
11324ca3d19SOleksandr Tymoshenko #define FB_WIDTH		640
11424ca3d19SOleksandr Tymoshenko #define FB_HEIGHT		480
11524ca3d19SOleksandr Tymoshenko #define FB_DEPTH		24
11624ca3d19SOleksandr Tymoshenko 
11724ca3d19SOleksandr Tymoshenko static struct video_adapter_softc va_softc;
11824ca3d19SOleksandr Tymoshenko 
11924ca3d19SOleksandr Tymoshenko static int am335x_syscons_configure(int flags);
12024ca3d19SOleksandr Tymoshenko 
12124ca3d19SOleksandr Tymoshenko /*
12224ca3d19SOleksandr Tymoshenko  * Video driver routines and glue.
12324ca3d19SOleksandr Tymoshenko  */
12424ca3d19SOleksandr Tymoshenko static vi_probe_t		am335x_syscons_probe;
12524ca3d19SOleksandr Tymoshenko static vi_init_t		am335x_syscons_init;
12624ca3d19SOleksandr Tymoshenko static vi_get_info_t		am335x_syscons_get_info;
12724ca3d19SOleksandr Tymoshenko static vi_query_mode_t		am335x_syscons_query_mode;
12824ca3d19SOleksandr Tymoshenko static vi_set_mode_t		am335x_syscons_set_mode;
12924ca3d19SOleksandr Tymoshenko static vi_save_font_t		am335x_syscons_save_font;
13024ca3d19SOleksandr Tymoshenko static vi_load_font_t		am335x_syscons_load_font;
13124ca3d19SOleksandr Tymoshenko static vi_show_font_t		am335x_syscons_show_font;
13224ca3d19SOleksandr Tymoshenko static vi_save_palette_t	am335x_syscons_save_palette;
13324ca3d19SOleksandr Tymoshenko static vi_load_palette_t	am335x_syscons_load_palette;
13424ca3d19SOleksandr Tymoshenko static vi_set_border_t		am335x_syscons_set_border;
13524ca3d19SOleksandr Tymoshenko static vi_save_state_t		am335x_syscons_save_state;
13624ca3d19SOleksandr Tymoshenko static vi_load_state_t		am335x_syscons_load_state;
13724ca3d19SOleksandr Tymoshenko static vi_set_win_org_t		am335x_syscons_set_win_org;
13824ca3d19SOleksandr Tymoshenko static vi_read_hw_cursor_t	am335x_syscons_read_hw_cursor;
13924ca3d19SOleksandr Tymoshenko static vi_set_hw_cursor_t	am335x_syscons_set_hw_cursor;
14024ca3d19SOleksandr Tymoshenko static vi_set_hw_cursor_shape_t	am335x_syscons_set_hw_cursor_shape;
14124ca3d19SOleksandr Tymoshenko static vi_blank_display_t	am335x_syscons_blank_display;
14224ca3d19SOleksandr Tymoshenko static vi_mmap_t		am335x_syscons_mmap;
14324ca3d19SOleksandr Tymoshenko static vi_ioctl_t		am335x_syscons_ioctl;
14424ca3d19SOleksandr Tymoshenko static vi_clear_t		am335x_syscons_clear;
14524ca3d19SOleksandr Tymoshenko static vi_fill_rect_t		am335x_syscons_fill_rect;
14624ca3d19SOleksandr Tymoshenko static vi_bitblt_t		am335x_syscons_bitblt;
14724ca3d19SOleksandr Tymoshenko static vi_diag_t		am335x_syscons_diag;
14824ca3d19SOleksandr Tymoshenko static vi_save_cursor_palette_t	am335x_syscons_save_cursor_palette;
14924ca3d19SOleksandr Tymoshenko static vi_load_cursor_palette_t	am335x_syscons_load_cursor_palette;
15024ca3d19SOleksandr Tymoshenko static vi_copy_t		am335x_syscons_copy;
15124ca3d19SOleksandr Tymoshenko static vi_putp_t		am335x_syscons_putp;
15224ca3d19SOleksandr Tymoshenko static vi_putc_t		am335x_syscons_putc;
15324ca3d19SOleksandr Tymoshenko static vi_puts_t		am335x_syscons_puts;
15424ca3d19SOleksandr Tymoshenko static vi_putm_t		am335x_syscons_putm;
15524ca3d19SOleksandr Tymoshenko 
15624ca3d19SOleksandr Tymoshenko static video_switch_t am335x_sysconsvidsw = {
15724ca3d19SOleksandr Tymoshenko 	.probe			= am335x_syscons_probe,
15824ca3d19SOleksandr Tymoshenko 	.init			= am335x_syscons_init,
15924ca3d19SOleksandr Tymoshenko 	.get_info		= am335x_syscons_get_info,
16024ca3d19SOleksandr Tymoshenko 	.query_mode		= am335x_syscons_query_mode,
16124ca3d19SOleksandr Tymoshenko 	.set_mode		= am335x_syscons_set_mode,
16224ca3d19SOleksandr Tymoshenko 	.save_font		= am335x_syscons_save_font,
16324ca3d19SOleksandr Tymoshenko 	.load_font		= am335x_syscons_load_font,
16424ca3d19SOleksandr Tymoshenko 	.show_font		= am335x_syscons_show_font,
16524ca3d19SOleksandr Tymoshenko 	.save_palette		= am335x_syscons_save_palette,
16624ca3d19SOleksandr Tymoshenko 	.load_palette		= am335x_syscons_load_palette,
16724ca3d19SOleksandr Tymoshenko 	.set_border		= am335x_syscons_set_border,
16824ca3d19SOleksandr Tymoshenko 	.save_state		= am335x_syscons_save_state,
16924ca3d19SOleksandr Tymoshenko 	.load_state		= am335x_syscons_load_state,
17024ca3d19SOleksandr Tymoshenko 	.set_win_org		= am335x_syscons_set_win_org,
17124ca3d19SOleksandr Tymoshenko 	.read_hw_cursor		= am335x_syscons_read_hw_cursor,
17224ca3d19SOleksandr Tymoshenko 	.set_hw_cursor		= am335x_syscons_set_hw_cursor,
17324ca3d19SOleksandr Tymoshenko 	.set_hw_cursor_shape	= am335x_syscons_set_hw_cursor_shape,
17424ca3d19SOleksandr Tymoshenko 	.blank_display		= am335x_syscons_blank_display,
17524ca3d19SOleksandr Tymoshenko 	.mmap			= am335x_syscons_mmap,
17624ca3d19SOleksandr Tymoshenko 	.ioctl			= am335x_syscons_ioctl,
17724ca3d19SOleksandr Tymoshenko 	.clear			= am335x_syscons_clear,
17824ca3d19SOleksandr Tymoshenko 	.fill_rect		= am335x_syscons_fill_rect,
17924ca3d19SOleksandr Tymoshenko 	.bitblt			= am335x_syscons_bitblt,
18024ca3d19SOleksandr Tymoshenko 	.diag			= am335x_syscons_diag,
18124ca3d19SOleksandr Tymoshenko 	.save_cursor_palette	= am335x_syscons_save_cursor_palette,
18224ca3d19SOleksandr Tymoshenko 	.load_cursor_palette	= am335x_syscons_load_cursor_palette,
18324ca3d19SOleksandr Tymoshenko 	.copy			= am335x_syscons_copy,
18424ca3d19SOleksandr Tymoshenko 	.putp			= am335x_syscons_putp,
18524ca3d19SOleksandr Tymoshenko 	.putc			= am335x_syscons_putc,
18624ca3d19SOleksandr Tymoshenko 	.puts			= am335x_syscons_puts,
18724ca3d19SOleksandr Tymoshenko 	.putm			= am335x_syscons_putm,
18824ca3d19SOleksandr Tymoshenko };
18924ca3d19SOleksandr Tymoshenko 
19024ca3d19SOleksandr Tymoshenko VIDEO_DRIVER(am335x_syscons, am335x_sysconsvidsw, am335x_syscons_configure);
19124ca3d19SOleksandr Tymoshenko 
19224ca3d19SOleksandr Tymoshenko static vr_init_t am335x_rend_init;
19324ca3d19SOleksandr Tymoshenko static vr_clear_t am335x_rend_clear;
19424ca3d19SOleksandr Tymoshenko static vr_draw_border_t am335x_rend_draw_border;
19524ca3d19SOleksandr Tymoshenko static vr_draw_t am335x_rend_draw;
19624ca3d19SOleksandr Tymoshenko static vr_set_cursor_t am335x_rend_set_cursor;
19724ca3d19SOleksandr Tymoshenko static vr_draw_cursor_t am335x_rend_draw_cursor;
19824ca3d19SOleksandr Tymoshenko static vr_blink_cursor_t am335x_rend_blink_cursor;
19924ca3d19SOleksandr Tymoshenko static vr_set_mouse_t am335x_rend_set_mouse;
20024ca3d19SOleksandr Tymoshenko static vr_draw_mouse_t am335x_rend_draw_mouse;
20124ca3d19SOleksandr Tymoshenko 
20224ca3d19SOleksandr Tymoshenko /*
20324ca3d19SOleksandr Tymoshenko  * We use our own renderer; this is because we must emulate a hardware
20424ca3d19SOleksandr Tymoshenko  * cursor.
20524ca3d19SOleksandr Tymoshenko  */
20624ca3d19SOleksandr Tymoshenko static sc_rndr_sw_t am335x_rend = {
20724ca3d19SOleksandr Tymoshenko 	am335x_rend_init,
20824ca3d19SOleksandr Tymoshenko 	am335x_rend_clear,
20924ca3d19SOleksandr Tymoshenko 	am335x_rend_draw_border,
21024ca3d19SOleksandr Tymoshenko 	am335x_rend_draw,
21124ca3d19SOleksandr Tymoshenko 	am335x_rend_set_cursor,
21224ca3d19SOleksandr Tymoshenko 	am335x_rend_draw_cursor,
21324ca3d19SOleksandr Tymoshenko 	am335x_rend_blink_cursor,
21424ca3d19SOleksandr Tymoshenko 	am335x_rend_set_mouse,
21524ca3d19SOleksandr Tymoshenko 	am335x_rend_draw_mouse
21624ca3d19SOleksandr Tymoshenko };
21724ca3d19SOleksandr Tymoshenko 
21824ca3d19SOleksandr Tymoshenko RENDERER(am335x_syscons, 0, am335x_rend, gfb_set);
21924ca3d19SOleksandr Tymoshenko RENDERER_MODULE(am335x_syscons, gfb_set);
22024ca3d19SOleksandr Tymoshenko 
22124ca3d19SOleksandr Tymoshenko static void
am335x_rend_init(scr_stat * scp)22224ca3d19SOleksandr Tymoshenko am335x_rend_init(scr_stat* scp)
22324ca3d19SOleksandr Tymoshenko {
22424ca3d19SOleksandr Tymoshenko }
22524ca3d19SOleksandr Tymoshenko 
22624ca3d19SOleksandr Tymoshenko static void
am335x_rend_clear(scr_stat * scp,int c,int attr)22724ca3d19SOleksandr Tymoshenko am335x_rend_clear(scr_stat* scp, int c, int attr)
22824ca3d19SOleksandr Tymoshenko {
22924ca3d19SOleksandr Tymoshenko }
23024ca3d19SOleksandr Tymoshenko 
23124ca3d19SOleksandr Tymoshenko static void
am335x_rend_draw_border(scr_stat * scp,int color)23224ca3d19SOleksandr Tymoshenko am335x_rend_draw_border(scr_stat* scp, int color)
23324ca3d19SOleksandr Tymoshenko {
23424ca3d19SOleksandr Tymoshenko }
23524ca3d19SOleksandr Tymoshenko 
23624ca3d19SOleksandr Tymoshenko static void
am335x_rend_draw(scr_stat * scp,int from,int count,int flip)23724ca3d19SOleksandr Tymoshenko am335x_rend_draw(scr_stat* scp, int from, int count, int flip)
23824ca3d19SOleksandr Tymoshenko {
23924ca3d19SOleksandr Tymoshenko 	video_adapter_t* adp = scp->sc->adp;
24024ca3d19SOleksandr Tymoshenko 	int i, c, a;
24124ca3d19SOleksandr Tymoshenko 
24224ca3d19SOleksandr Tymoshenko 	if (!flip) {
24324ca3d19SOleksandr Tymoshenko 		/* Normal printing */
24424ca3d19SOleksandr Tymoshenko 		vidd_puts(adp, from, (uint16_t*)sc_vtb_pointer(&scp->vtb, from), count);
24524ca3d19SOleksandr Tymoshenko 	} else {
24624ca3d19SOleksandr Tymoshenko 		/* This is for selections and such: invert the color attribute */
24724ca3d19SOleksandr Tymoshenko 		for (i = count; i-- > 0; ++from) {
24824ca3d19SOleksandr Tymoshenko 			c = sc_vtb_getc(&scp->vtb, from);
24924ca3d19SOleksandr Tymoshenko 			a = sc_vtb_geta(&scp->vtb, from) >> 8;
25024ca3d19SOleksandr Tymoshenko 			vidd_putc(adp, from, c, (a >> 4) | ((a & 0xf) << 4));
25124ca3d19SOleksandr Tymoshenko 		}
25224ca3d19SOleksandr Tymoshenko 	}
25324ca3d19SOleksandr Tymoshenko }
25424ca3d19SOleksandr Tymoshenko 
25524ca3d19SOleksandr Tymoshenko static void
am335x_rend_set_cursor(scr_stat * scp,int base,int height,int blink)25624ca3d19SOleksandr Tymoshenko am335x_rend_set_cursor(scr_stat* scp, int base, int height, int blink)
25724ca3d19SOleksandr Tymoshenko {
25824ca3d19SOleksandr Tymoshenko }
25924ca3d19SOleksandr Tymoshenko 
26024ca3d19SOleksandr Tymoshenko static void
am335x_rend_draw_cursor(scr_stat * scp,int off,int blink,int on,int flip)26124ca3d19SOleksandr Tymoshenko am335x_rend_draw_cursor(scr_stat* scp, int off, int blink, int on, int flip)
26224ca3d19SOleksandr Tymoshenko {
26324ca3d19SOleksandr Tymoshenko 	video_adapter_t* adp = scp->sc->adp;
26424ca3d19SOleksandr Tymoshenko 	struct video_adapter_softc *sc;
26524ca3d19SOleksandr Tymoshenko 	int row, col;
26624ca3d19SOleksandr Tymoshenko 	uint8_t *addr;
26724ca3d19SOleksandr Tymoshenko 	int i, j, bytes;
26824ca3d19SOleksandr Tymoshenko 
26924ca3d19SOleksandr Tymoshenko 	sc = (struct video_adapter_softc *)adp;
27024ca3d19SOleksandr Tymoshenko 
27124ca3d19SOleksandr Tymoshenko 	if (scp->curs_attr.height <= 0)
27224ca3d19SOleksandr Tymoshenko 		return;
27324ca3d19SOleksandr Tymoshenko 
27424ca3d19SOleksandr Tymoshenko 	if (sc->fb_addr == 0)
27524ca3d19SOleksandr Tymoshenko 		return;
27624ca3d19SOleksandr Tymoshenko 
27724ca3d19SOleksandr Tymoshenko 	if (off >= adp->va_info.vi_width * adp->va_info.vi_height)
27824ca3d19SOleksandr Tymoshenko 		return;
27924ca3d19SOleksandr Tymoshenko 
28024ca3d19SOleksandr Tymoshenko 	/* calculate the coordinates in the video buffer */
28124ca3d19SOleksandr Tymoshenko 	row = (off / adp->va_info.vi_width) * adp->va_info.vi_cheight;
28224ca3d19SOleksandr Tymoshenko 	col = (off % adp->va_info.vi_width) * adp->va_info.vi_cwidth;
28324ca3d19SOleksandr Tymoshenko 
28424ca3d19SOleksandr Tymoshenko 	addr = (uint8_t *)sc->fb_addr
28524ca3d19SOleksandr Tymoshenko 	    + (row + sc->ymargin)*(sc->stride)
28624ca3d19SOleksandr Tymoshenko 	    + (sc->depth/8) * (col + sc->xmargin);
28724ca3d19SOleksandr Tymoshenko 
28824ca3d19SOleksandr Tymoshenko 	bytes = sc->depth/8;
28924ca3d19SOleksandr Tymoshenko 
29024ca3d19SOleksandr Tymoshenko 	/* our cursor consists of simply inverting the char under it */
29124ca3d19SOleksandr Tymoshenko 	for (i = 0; i < adp->va_info.vi_cheight; i++) {
29224ca3d19SOleksandr Tymoshenko 		for (j = 0; j < adp->va_info.vi_cwidth; j++) {
29324ca3d19SOleksandr Tymoshenko 			switch (sc->depth) {
29424ca3d19SOleksandr Tymoshenko 			case 32:
29524ca3d19SOleksandr Tymoshenko 			case 24:
29624ca3d19SOleksandr Tymoshenko 				addr[bytes*j + 2] ^= 0xff;
29724ca3d19SOleksandr Tymoshenko 				/* FALLTHROUGH */
29824ca3d19SOleksandr Tymoshenko 			case 16:
29924ca3d19SOleksandr Tymoshenko 				addr[bytes*j + 1] ^= 0xff;
30024ca3d19SOleksandr Tymoshenko 				addr[bytes*j] ^= 0xff;
30124ca3d19SOleksandr Tymoshenko 				break;
30224ca3d19SOleksandr Tymoshenko 			default:
30324ca3d19SOleksandr Tymoshenko 				break;
30424ca3d19SOleksandr Tymoshenko 			}
30524ca3d19SOleksandr Tymoshenko 		}
30624ca3d19SOleksandr Tymoshenko 
30724ca3d19SOleksandr Tymoshenko 		addr += sc->stride;
30824ca3d19SOleksandr Tymoshenko 	}
30924ca3d19SOleksandr Tymoshenko }
31024ca3d19SOleksandr Tymoshenko 
31124ca3d19SOleksandr Tymoshenko static void
am335x_rend_blink_cursor(scr_stat * scp,int at,int flip)31224ca3d19SOleksandr Tymoshenko am335x_rend_blink_cursor(scr_stat* scp, int at, int flip)
31324ca3d19SOleksandr Tymoshenko {
31424ca3d19SOleksandr Tymoshenko }
31524ca3d19SOleksandr Tymoshenko 
31624ca3d19SOleksandr Tymoshenko static void
am335x_rend_set_mouse(scr_stat * scp)31724ca3d19SOleksandr Tymoshenko am335x_rend_set_mouse(scr_stat* scp)
31824ca3d19SOleksandr Tymoshenko {
31924ca3d19SOleksandr Tymoshenko }
32024ca3d19SOleksandr Tymoshenko 
32124ca3d19SOleksandr Tymoshenko static void
am335x_rend_draw_mouse(scr_stat * scp,int x,int y,int on)32224ca3d19SOleksandr Tymoshenko am335x_rend_draw_mouse(scr_stat* scp, int x, int y, int on)
32324ca3d19SOleksandr Tymoshenko {
32424ca3d19SOleksandr Tymoshenko 	vidd_putm(scp->sc->adp, x, y, mouse_pointer, 0xffffffff, 16, 8);
32524ca3d19SOleksandr Tymoshenko }
32624ca3d19SOleksandr Tymoshenko 
32724ca3d19SOleksandr Tymoshenko static uint16_t am335x_syscons_static_window[ROW*COL];
32824ca3d19SOleksandr Tymoshenko extern u_char dflt_font_16[];
32924ca3d19SOleksandr Tymoshenko 
33024ca3d19SOleksandr Tymoshenko /*
33124ca3d19SOleksandr Tymoshenko  * Update videoadapter settings after changing resolution
33224ca3d19SOleksandr Tymoshenko  */
33324ca3d19SOleksandr Tymoshenko static void
am335x_syscons_update_margins(video_adapter_t * adp)33424ca3d19SOleksandr Tymoshenko am335x_syscons_update_margins(video_adapter_t *adp)
33524ca3d19SOleksandr Tymoshenko {
33624ca3d19SOleksandr Tymoshenko 	struct video_adapter_softc *sc;
33724ca3d19SOleksandr Tymoshenko 	video_info_t *vi;
33824ca3d19SOleksandr Tymoshenko 
33924ca3d19SOleksandr Tymoshenko 	sc = (struct video_adapter_softc *)adp;
34024ca3d19SOleksandr Tymoshenko 	vi = &adp->va_info;
34124ca3d19SOleksandr Tymoshenko 
34224ca3d19SOleksandr Tymoshenko 	sc->xmargin = (sc->width - (vi->vi_width * vi->vi_cwidth)) / 2;
34324ca3d19SOleksandr Tymoshenko 	sc->ymargin = (sc->height - (vi->vi_height * vi->vi_cheight))/2;
34424ca3d19SOleksandr Tymoshenko }
34524ca3d19SOleksandr Tymoshenko 
34624ca3d19SOleksandr Tymoshenko static phandle_t
am335x_syscons_find_panel_node(phandle_t start)34724ca3d19SOleksandr Tymoshenko am335x_syscons_find_panel_node(phandle_t start)
34824ca3d19SOleksandr Tymoshenko {
34924ca3d19SOleksandr Tymoshenko 	phandle_t child;
35024ca3d19SOleksandr Tymoshenko 	phandle_t result;
35124ca3d19SOleksandr Tymoshenko 
35224ca3d19SOleksandr Tymoshenko 	for (child = OF_child(start); child != 0; child = OF_peer(child)) {
35387acb7f8SAndrew Turner 		if (ofw_bus_node_is_compatible(child, "ti,am335x-lcd"))
35424ca3d19SOleksandr Tymoshenko 			return (child);
35524ca3d19SOleksandr Tymoshenko 		if ((result = am335x_syscons_find_panel_node(child)))
35624ca3d19SOleksandr Tymoshenko 			return (result);
35724ca3d19SOleksandr Tymoshenko 	}
35824ca3d19SOleksandr Tymoshenko 
35924ca3d19SOleksandr Tymoshenko 	return (0);
36024ca3d19SOleksandr Tymoshenko }
36124ca3d19SOleksandr Tymoshenko 
36224ca3d19SOleksandr Tymoshenko static int
am335x_syscons_configure(int flags)36324ca3d19SOleksandr Tymoshenko am335x_syscons_configure(int flags)
36424ca3d19SOleksandr Tymoshenko {
36524ca3d19SOleksandr Tymoshenko 	struct video_adapter_softc *va_sc;
36624ca3d19SOleksandr Tymoshenko 
36724ca3d19SOleksandr Tymoshenko 	va_sc = &va_softc;
36824ca3d19SOleksandr Tymoshenko 	phandle_t display, root;
36924ca3d19SOleksandr Tymoshenko 	pcell_t cell;
37024ca3d19SOleksandr Tymoshenko 
37124ca3d19SOleksandr Tymoshenko 	if (va_sc->initialized)
37224ca3d19SOleksandr Tymoshenko 		return (0);
37324ca3d19SOleksandr Tymoshenko 
37424ca3d19SOleksandr Tymoshenko 	va_sc->width = 0;
37524ca3d19SOleksandr Tymoshenko 	va_sc->height = 0;
37624ca3d19SOleksandr Tymoshenko 
37724ca3d19SOleksandr Tymoshenko 	/*
37824ca3d19SOleksandr Tymoshenko 	 * It seems there is no way to let syscons framework know
37924ca3d19SOleksandr Tymoshenko 	 * that framebuffer resolution has changed. So just try
38024ca3d19SOleksandr Tymoshenko 	 * to fetch data from FDT and go with defaults if failed
38124ca3d19SOleksandr Tymoshenko 	 */
38224ca3d19SOleksandr Tymoshenko 	root = OF_finddevice("/");
383108117ccSOleksandr Tymoshenko 	if ((root != -1) &&
38424ca3d19SOleksandr Tymoshenko 	    (display = am335x_syscons_find_panel_node(root))) {
3859783ea5cSAndrew Turner 		if ((OF_getencprop(display, "panel_width", &cell,
3869783ea5cSAndrew Turner 		    sizeof(cell))) > 0)
3879783ea5cSAndrew Turner 			va_sc->width = cell;
38824ca3d19SOleksandr Tymoshenko 
3899783ea5cSAndrew Turner 		if ((OF_getencprop(display, "panel_height", &cell,
3909783ea5cSAndrew Turner 		    sizeof(cell))) > 0)
3919783ea5cSAndrew Turner 			va_sc->height = cell;
39224ca3d19SOleksandr Tymoshenko 	}
39324ca3d19SOleksandr Tymoshenko 
39424ca3d19SOleksandr Tymoshenko 	if (va_sc->width == 0)
39524ca3d19SOleksandr Tymoshenko 		va_sc->width = FB_WIDTH;
39624ca3d19SOleksandr Tymoshenko 	if (va_sc->height == 0)
39724ca3d19SOleksandr Tymoshenko 		va_sc->height = FB_HEIGHT;
39824ca3d19SOleksandr Tymoshenko 
39924ca3d19SOleksandr Tymoshenko 	am335x_syscons_init(0, &va_sc->va, 0);
40024ca3d19SOleksandr Tymoshenko 
40124ca3d19SOleksandr Tymoshenko 	va_sc->initialized = 1;
40224ca3d19SOleksandr Tymoshenko 
40324ca3d19SOleksandr Tymoshenko 	return (0);
40424ca3d19SOleksandr Tymoshenko }
40524ca3d19SOleksandr Tymoshenko 
40624ca3d19SOleksandr Tymoshenko static int
am335x_syscons_probe(int unit,video_adapter_t ** adp,void * arg,int flags)40724ca3d19SOleksandr Tymoshenko am335x_syscons_probe(int unit, video_adapter_t **adp, void *arg, int flags)
40824ca3d19SOleksandr Tymoshenko {
40924ca3d19SOleksandr Tymoshenko 
41024ca3d19SOleksandr Tymoshenko 	return (0);
41124ca3d19SOleksandr Tymoshenko }
41224ca3d19SOleksandr Tymoshenko 
41324ca3d19SOleksandr Tymoshenko static int
am335x_syscons_init(int unit,video_adapter_t * adp,int flags)41424ca3d19SOleksandr Tymoshenko am335x_syscons_init(int unit, video_adapter_t *adp, int flags)
41524ca3d19SOleksandr Tymoshenko {
41624ca3d19SOleksandr Tymoshenko 	struct video_adapter_softc *sc;
41724ca3d19SOleksandr Tymoshenko 	video_info_t *vi;
41824ca3d19SOleksandr Tymoshenko 
41924ca3d19SOleksandr Tymoshenko 	sc = (struct video_adapter_softc *)adp;
42024ca3d19SOleksandr Tymoshenko 	vi = &adp->va_info;
42124ca3d19SOleksandr Tymoshenko 
42224ca3d19SOleksandr Tymoshenko 	vid_init_struct(adp, "am335x_syscons", -1, unit);
42324ca3d19SOleksandr Tymoshenko 
42424ca3d19SOleksandr Tymoshenko 	sc->font = dflt_font_16;
42524ca3d19SOleksandr Tymoshenko 	vi->vi_cheight = AM335X_FONT_HEIGHT;
42624ca3d19SOleksandr Tymoshenko 	vi->vi_cwidth = 8;
42724ca3d19SOleksandr Tymoshenko 
42824ca3d19SOleksandr Tymoshenko 	vi->vi_width = sc->width/8;
42924ca3d19SOleksandr Tymoshenko 	vi->vi_height = sc->height/vi->vi_cheight;
43024ca3d19SOleksandr Tymoshenko 
43124ca3d19SOleksandr Tymoshenko 	/*
43224ca3d19SOleksandr Tymoshenko 	 * Clamp width/height to syscons maximums
43324ca3d19SOleksandr Tymoshenko 	 */
43424ca3d19SOleksandr Tymoshenko 	if (vi->vi_width > COL)
43524ca3d19SOleksandr Tymoshenko 		vi->vi_width = COL;
43624ca3d19SOleksandr Tymoshenko 	if (vi->vi_height > ROW)
43724ca3d19SOleksandr Tymoshenko 		vi->vi_height = ROW;
43824ca3d19SOleksandr Tymoshenko 
43924ca3d19SOleksandr Tymoshenko 	sc->xmargin = (sc->width - (vi->vi_width * vi->vi_cwidth)) / 2;
44024ca3d19SOleksandr Tymoshenko 	sc->ymargin = (sc->height - (vi->vi_height * vi->vi_cheight))/2;
44124ca3d19SOleksandr Tymoshenko 
44224ca3d19SOleksandr Tymoshenko 	adp->va_window = (vm_offset_t) am335x_syscons_static_window;
44324ca3d19SOleksandr Tymoshenko 	adp->va_flags |= V_ADP_FONT /* | V_ADP_COLOR | V_ADP_MODECHANGE */;
44424ca3d19SOleksandr Tymoshenko 
44524ca3d19SOleksandr Tymoshenko 	vid_register(&sc->va);
44624ca3d19SOleksandr Tymoshenko 
44724ca3d19SOleksandr Tymoshenko 	return (0);
44824ca3d19SOleksandr Tymoshenko }
44924ca3d19SOleksandr Tymoshenko 
45024ca3d19SOleksandr Tymoshenko static int
am335x_syscons_get_info(video_adapter_t * adp,int mode,video_info_t * info)45124ca3d19SOleksandr Tymoshenko am335x_syscons_get_info(video_adapter_t *adp, int mode, video_info_t *info)
45224ca3d19SOleksandr Tymoshenko {
45324ca3d19SOleksandr Tymoshenko 	bcopy(&adp->va_info, info, sizeof(*info));
45424ca3d19SOleksandr Tymoshenko 	return (0);
45524ca3d19SOleksandr Tymoshenko }
45624ca3d19SOleksandr Tymoshenko 
45724ca3d19SOleksandr Tymoshenko static int
am335x_syscons_query_mode(video_adapter_t * adp,video_info_t * info)45824ca3d19SOleksandr Tymoshenko am335x_syscons_query_mode(video_adapter_t *adp, video_info_t *info)
45924ca3d19SOleksandr Tymoshenko {
46024ca3d19SOleksandr Tymoshenko 	return (0);
46124ca3d19SOleksandr Tymoshenko }
46224ca3d19SOleksandr Tymoshenko 
46324ca3d19SOleksandr Tymoshenko static int
am335x_syscons_set_mode(video_adapter_t * adp,int mode)46424ca3d19SOleksandr Tymoshenko am335x_syscons_set_mode(video_adapter_t *adp, int mode)
46524ca3d19SOleksandr Tymoshenko {
46624ca3d19SOleksandr Tymoshenko 	return (0);
46724ca3d19SOleksandr Tymoshenko }
46824ca3d19SOleksandr Tymoshenko 
46924ca3d19SOleksandr Tymoshenko static int
am335x_syscons_save_font(video_adapter_t * adp,int page,int size,int width,u_char * data,int c,int count)47024ca3d19SOleksandr Tymoshenko am335x_syscons_save_font(video_adapter_t *adp, int page, int size, int width,
47124ca3d19SOleksandr Tymoshenko     u_char *data, int c, int count)
47224ca3d19SOleksandr Tymoshenko {
47324ca3d19SOleksandr Tymoshenko 	return (0);
47424ca3d19SOleksandr Tymoshenko }
47524ca3d19SOleksandr Tymoshenko 
47624ca3d19SOleksandr Tymoshenko static int
am335x_syscons_load_font(video_adapter_t * adp,int page,int size,int width,u_char * data,int c,int count)47724ca3d19SOleksandr Tymoshenko am335x_syscons_load_font(video_adapter_t *adp, int page, int size, int width,
47824ca3d19SOleksandr Tymoshenko     u_char *data, int c, int count)
47924ca3d19SOleksandr Tymoshenko {
48024ca3d19SOleksandr Tymoshenko 	struct video_adapter_softc *sc = (struct video_adapter_softc *)adp;
48124ca3d19SOleksandr Tymoshenko 
48224ca3d19SOleksandr Tymoshenko 	sc->font = data;
48324ca3d19SOleksandr Tymoshenko 
48424ca3d19SOleksandr Tymoshenko 	return (0);
48524ca3d19SOleksandr Tymoshenko }
48624ca3d19SOleksandr Tymoshenko 
48724ca3d19SOleksandr Tymoshenko static int
am335x_syscons_show_font(video_adapter_t * adp,int page)48824ca3d19SOleksandr Tymoshenko am335x_syscons_show_font(video_adapter_t *adp, int page)
48924ca3d19SOleksandr Tymoshenko {
49024ca3d19SOleksandr Tymoshenko 	return (0);
49124ca3d19SOleksandr Tymoshenko }
49224ca3d19SOleksandr Tymoshenko 
49324ca3d19SOleksandr Tymoshenko static int
am335x_syscons_save_palette(video_adapter_t * adp,u_char * palette)49424ca3d19SOleksandr Tymoshenko am335x_syscons_save_palette(video_adapter_t *adp, u_char *palette)
49524ca3d19SOleksandr Tymoshenko {
49624ca3d19SOleksandr Tymoshenko 	return (0);
49724ca3d19SOleksandr Tymoshenko }
49824ca3d19SOleksandr Tymoshenko 
49924ca3d19SOleksandr Tymoshenko static int
am335x_syscons_load_palette(video_adapter_t * adp,u_char * palette)50024ca3d19SOleksandr Tymoshenko am335x_syscons_load_palette(video_adapter_t *adp, u_char *palette)
50124ca3d19SOleksandr Tymoshenko {
50224ca3d19SOleksandr Tymoshenko 	return (0);
50324ca3d19SOleksandr Tymoshenko }
50424ca3d19SOleksandr Tymoshenko 
50524ca3d19SOleksandr Tymoshenko static int
am335x_syscons_set_border(video_adapter_t * adp,int border)50624ca3d19SOleksandr Tymoshenko am335x_syscons_set_border(video_adapter_t *adp, int border)
50724ca3d19SOleksandr Tymoshenko {
50824ca3d19SOleksandr Tymoshenko 	return (am335x_syscons_blank_display(adp, border));
50924ca3d19SOleksandr Tymoshenko }
51024ca3d19SOleksandr Tymoshenko 
51124ca3d19SOleksandr Tymoshenko static int
am335x_syscons_save_state(video_adapter_t * adp,void * p,size_t size)51224ca3d19SOleksandr Tymoshenko am335x_syscons_save_state(video_adapter_t *adp, void *p, size_t size)
51324ca3d19SOleksandr Tymoshenko {
51424ca3d19SOleksandr Tymoshenko 	return (0);
51524ca3d19SOleksandr Tymoshenko }
51624ca3d19SOleksandr Tymoshenko 
51724ca3d19SOleksandr Tymoshenko static int
am335x_syscons_load_state(video_adapter_t * adp,void * p)51824ca3d19SOleksandr Tymoshenko am335x_syscons_load_state(video_adapter_t *adp, void *p)
51924ca3d19SOleksandr Tymoshenko {
52024ca3d19SOleksandr Tymoshenko 	return (0);
52124ca3d19SOleksandr Tymoshenko }
52224ca3d19SOleksandr Tymoshenko 
52324ca3d19SOleksandr Tymoshenko static int
am335x_syscons_set_win_org(video_adapter_t * adp,off_t offset)52424ca3d19SOleksandr Tymoshenko am335x_syscons_set_win_org(video_adapter_t *adp, off_t offset)
52524ca3d19SOleksandr Tymoshenko {
52624ca3d19SOleksandr Tymoshenko 	return (0);
52724ca3d19SOleksandr Tymoshenko }
52824ca3d19SOleksandr Tymoshenko 
52924ca3d19SOleksandr Tymoshenko static int
am335x_syscons_read_hw_cursor(video_adapter_t * adp,int * col,int * row)53024ca3d19SOleksandr Tymoshenko am335x_syscons_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
53124ca3d19SOleksandr Tymoshenko {
53224ca3d19SOleksandr Tymoshenko 	*col = *row = 0;
53324ca3d19SOleksandr Tymoshenko 
53424ca3d19SOleksandr Tymoshenko 	return (0);
53524ca3d19SOleksandr Tymoshenko }
53624ca3d19SOleksandr Tymoshenko 
53724ca3d19SOleksandr Tymoshenko static int
am335x_syscons_set_hw_cursor(video_adapter_t * adp,int col,int row)53824ca3d19SOleksandr Tymoshenko am335x_syscons_set_hw_cursor(video_adapter_t *adp, int col, int row)
53924ca3d19SOleksandr Tymoshenko {
54024ca3d19SOleksandr Tymoshenko 	return (0);
54124ca3d19SOleksandr Tymoshenko }
54224ca3d19SOleksandr Tymoshenko 
54324ca3d19SOleksandr Tymoshenko static int
am335x_syscons_set_hw_cursor_shape(video_adapter_t * adp,int base,int height,int celsize,int blink)54424ca3d19SOleksandr Tymoshenko am335x_syscons_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
54524ca3d19SOleksandr Tymoshenko     int celsize, int blink)
54624ca3d19SOleksandr Tymoshenko {
54724ca3d19SOleksandr Tymoshenko 	return (0);
54824ca3d19SOleksandr Tymoshenko }
54924ca3d19SOleksandr Tymoshenko 
55024ca3d19SOleksandr Tymoshenko static int
am335x_syscons_blank_display(video_adapter_t * adp,int mode)55124ca3d19SOleksandr Tymoshenko am335x_syscons_blank_display(video_adapter_t *adp, int mode)
55224ca3d19SOleksandr Tymoshenko {
55324ca3d19SOleksandr Tymoshenko 
55424ca3d19SOleksandr Tymoshenko 	struct video_adapter_softc *sc;
55524ca3d19SOleksandr Tymoshenko 
55624ca3d19SOleksandr Tymoshenko 	sc = (struct video_adapter_softc *)adp;
55724ca3d19SOleksandr Tymoshenko 	if (sc && sc->fb_addr)
55824ca3d19SOleksandr Tymoshenko 		memset((void*)sc->fb_addr, 0, sc->fb_size);
55924ca3d19SOleksandr Tymoshenko 
56024ca3d19SOleksandr Tymoshenko 	return (0);
56124ca3d19SOleksandr Tymoshenko }
56224ca3d19SOleksandr Tymoshenko 
56324ca3d19SOleksandr Tymoshenko static int
am335x_syscons_mmap(video_adapter_t * adp,vm_ooffset_t offset,vm_paddr_t * paddr,int prot,vm_memattr_t * memattr)56424ca3d19SOleksandr Tymoshenko am335x_syscons_mmap(video_adapter_t *adp, vm_ooffset_t offset, vm_paddr_t *paddr,
56524ca3d19SOleksandr Tymoshenko     int prot, vm_memattr_t *memattr)
56624ca3d19SOleksandr Tymoshenko {
56724ca3d19SOleksandr Tymoshenko 	struct video_adapter_softc *sc;
56824ca3d19SOleksandr Tymoshenko 
56924ca3d19SOleksandr Tymoshenko 	sc = (struct video_adapter_softc *)adp;
57024ca3d19SOleksandr Tymoshenko 
57124ca3d19SOleksandr Tymoshenko 	/*
57224ca3d19SOleksandr Tymoshenko 	 * This might be a legacy VGA mem request: if so, just point it at the
57324ca3d19SOleksandr Tymoshenko 	 * framebuffer, since it shouldn't be touched
57424ca3d19SOleksandr Tymoshenko 	 */
57524ca3d19SOleksandr Tymoshenko 	if (offset < sc->stride*sc->height) {
57624ca3d19SOleksandr Tymoshenko 		*paddr = sc->fb_paddr + offset;
57724ca3d19SOleksandr Tymoshenko 		return (0);
57824ca3d19SOleksandr Tymoshenko 	}
57924ca3d19SOleksandr Tymoshenko 
58024ca3d19SOleksandr Tymoshenko 	return (EINVAL);
58124ca3d19SOleksandr Tymoshenko }
58224ca3d19SOleksandr Tymoshenko 
58324ca3d19SOleksandr Tymoshenko static int
am335x_syscons_ioctl(video_adapter_t * adp,u_long cmd,caddr_t data)58424ca3d19SOleksandr Tymoshenko am335x_syscons_ioctl(video_adapter_t *adp, u_long cmd, caddr_t data)
58524ca3d19SOleksandr Tymoshenko {
58624ca3d19SOleksandr Tymoshenko 	struct video_adapter_softc *sc;
58724ca3d19SOleksandr Tymoshenko 	struct fbtype *fb;
58824ca3d19SOleksandr Tymoshenko 
58924ca3d19SOleksandr Tymoshenko 	sc = (struct video_adapter_softc *)adp;
59024ca3d19SOleksandr Tymoshenko 
59124ca3d19SOleksandr Tymoshenko 	switch (cmd) {
59224ca3d19SOleksandr Tymoshenko 	case FBIOGTYPE:
59324ca3d19SOleksandr Tymoshenko 		fb = (struct fbtype *)data;
59424ca3d19SOleksandr Tymoshenko 		fb->fb_type = FBTYPE_PCIMISC;
59524ca3d19SOleksandr Tymoshenko 		fb->fb_height = sc->height;
59624ca3d19SOleksandr Tymoshenko 		fb->fb_width = sc->width;
59724ca3d19SOleksandr Tymoshenko 		fb->fb_depth = sc->depth;
59824ca3d19SOleksandr Tymoshenko 		if (sc->depth <= 1 || sc->depth > 8)
59924ca3d19SOleksandr Tymoshenko 			fb->fb_cmsize = 0;
60024ca3d19SOleksandr Tymoshenko 		else
60124ca3d19SOleksandr Tymoshenko 			fb->fb_cmsize = 1 << sc->depth;
60224ca3d19SOleksandr Tymoshenko 		fb->fb_size = sc->fb_size;
60324ca3d19SOleksandr Tymoshenko 		break;
60424ca3d19SOleksandr Tymoshenko 	default:
60524ca3d19SOleksandr Tymoshenko 		return (fb_commonioctl(adp, cmd, data));
60624ca3d19SOleksandr Tymoshenko 	}
60724ca3d19SOleksandr Tymoshenko 
60824ca3d19SOleksandr Tymoshenko 	return (0);
60924ca3d19SOleksandr Tymoshenko }
61024ca3d19SOleksandr Tymoshenko 
61124ca3d19SOleksandr Tymoshenko static int
am335x_syscons_clear(video_adapter_t * adp)61224ca3d19SOleksandr Tymoshenko am335x_syscons_clear(video_adapter_t *adp)
61324ca3d19SOleksandr Tymoshenko {
61424ca3d19SOleksandr Tymoshenko 
61524ca3d19SOleksandr Tymoshenko 	return (am335x_syscons_blank_display(adp, 0));
61624ca3d19SOleksandr Tymoshenko }
61724ca3d19SOleksandr Tymoshenko 
61824ca3d19SOleksandr Tymoshenko static int
am335x_syscons_fill_rect(video_adapter_t * adp,int val,int x,int y,int cx,int cy)61924ca3d19SOleksandr Tymoshenko am335x_syscons_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy)
62024ca3d19SOleksandr Tymoshenko {
62124ca3d19SOleksandr Tymoshenko 
62224ca3d19SOleksandr Tymoshenko 	return (0);
62324ca3d19SOleksandr Tymoshenko }
62424ca3d19SOleksandr Tymoshenko 
62524ca3d19SOleksandr Tymoshenko static int
am335x_syscons_bitblt(video_adapter_t * adp,...)62624ca3d19SOleksandr Tymoshenko am335x_syscons_bitblt(video_adapter_t *adp, ...)
62724ca3d19SOleksandr Tymoshenko {
62824ca3d19SOleksandr Tymoshenko 
62924ca3d19SOleksandr Tymoshenko 	return (0);
63024ca3d19SOleksandr Tymoshenko }
63124ca3d19SOleksandr Tymoshenko 
63224ca3d19SOleksandr Tymoshenko static int
am335x_syscons_diag(video_adapter_t * adp,int level)63324ca3d19SOleksandr Tymoshenko am335x_syscons_diag(video_adapter_t *adp, int level)
63424ca3d19SOleksandr Tymoshenko {
63524ca3d19SOleksandr Tymoshenko 
63624ca3d19SOleksandr Tymoshenko 	return (0);
63724ca3d19SOleksandr Tymoshenko }
63824ca3d19SOleksandr Tymoshenko 
63924ca3d19SOleksandr Tymoshenko static int
am335x_syscons_save_cursor_palette(video_adapter_t * adp,u_char * palette)64024ca3d19SOleksandr Tymoshenko am335x_syscons_save_cursor_palette(video_adapter_t *adp, u_char *palette)
64124ca3d19SOleksandr Tymoshenko {
64224ca3d19SOleksandr Tymoshenko 
64324ca3d19SOleksandr Tymoshenko 	return (0);
64424ca3d19SOleksandr Tymoshenko }
64524ca3d19SOleksandr Tymoshenko 
64624ca3d19SOleksandr Tymoshenko static int
am335x_syscons_load_cursor_palette(video_adapter_t * adp,u_char * palette)64724ca3d19SOleksandr Tymoshenko am335x_syscons_load_cursor_palette(video_adapter_t *adp, u_char *palette)
64824ca3d19SOleksandr Tymoshenko {
64924ca3d19SOleksandr Tymoshenko 
65024ca3d19SOleksandr Tymoshenko 	return (0);
65124ca3d19SOleksandr Tymoshenko }
65224ca3d19SOleksandr Tymoshenko 
65324ca3d19SOleksandr Tymoshenko static int
am335x_syscons_copy(video_adapter_t * adp,vm_offset_t src,vm_offset_t dst,int n)65424ca3d19SOleksandr Tymoshenko am335x_syscons_copy(video_adapter_t *adp, vm_offset_t src, vm_offset_t dst, int n)
65524ca3d19SOleksandr Tymoshenko {
65624ca3d19SOleksandr Tymoshenko 
65724ca3d19SOleksandr Tymoshenko 	return (0);
65824ca3d19SOleksandr Tymoshenko }
65924ca3d19SOleksandr Tymoshenko 
66024ca3d19SOleksandr Tymoshenko static int
am335x_syscons_putp(video_adapter_t * adp,vm_offset_t off,uint32_t p,uint32_t a,int size,int bpp,int bit_ltor,int byte_ltor)66124ca3d19SOleksandr Tymoshenko am335x_syscons_putp(video_adapter_t *adp, vm_offset_t off, uint32_t p, uint32_t a,
66224ca3d19SOleksandr Tymoshenko     int size, int bpp, int bit_ltor, int byte_ltor)
66324ca3d19SOleksandr Tymoshenko {
66424ca3d19SOleksandr Tymoshenko 
66524ca3d19SOleksandr Tymoshenko 	return (0);
66624ca3d19SOleksandr Tymoshenko }
66724ca3d19SOleksandr Tymoshenko 
66824ca3d19SOleksandr Tymoshenko static int
am335x_syscons_putc(video_adapter_t * adp,vm_offset_t off,uint8_t c,uint8_t a)66924ca3d19SOleksandr Tymoshenko am335x_syscons_putc(video_adapter_t *adp, vm_offset_t off, uint8_t c, uint8_t a)
67024ca3d19SOleksandr Tymoshenko {
67124ca3d19SOleksandr Tymoshenko 	struct video_adapter_softc *sc;
67224ca3d19SOleksandr Tymoshenko 	int row;
67324ca3d19SOleksandr Tymoshenko 	int col;
67424ca3d19SOleksandr Tymoshenko 	int i, j, k;
67524ca3d19SOleksandr Tymoshenko 	uint8_t *addr;
67624ca3d19SOleksandr Tymoshenko 	u_char *p;
67724ca3d19SOleksandr Tymoshenko 	uint8_t fg, bg, color;
67824ca3d19SOleksandr Tymoshenko 	uint16_t rgb;
67924ca3d19SOleksandr Tymoshenko 
68024ca3d19SOleksandr Tymoshenko 	sc = (struct video_adapter_softc *)adp;
68124ca3d19SOleksandr Tymoshenko 
68224ca3d19SOleksandr Tymoshenko 	if (sc->fb_addr == 0)
68324ca3d19SOleksandr Tymoshenko 		return (0);
68424ca3d19SOleksandr Tymoshenko 
68524ca3d19SOleksandr Tymoshenko 	row = (off / adp->va_info.vi_width) * adp->va_info.vi_cheight;
68624ca3d19SOleksandr Tymoshenko 	col = (off % adp->va_info.vi_width) * adp->va_info.vi_cwidth;
68724ca3d19SOleksandr Tymoshenko 	p = sc->font + c*AM335X_FONT_HEIGHT;
68824ca3d19SOleksandr Tymoshenko 	addr = (uint8_t *)sc->fb_addr
68924ca3d19SOleksandr Tymoshenko 	    + (row + sc->ymargin)*(sc->stride)
69024ca3d19SOleksandr Tymoshenko 	    + (sc->depth/8) * (col + sc->xmargin);
69124ca3d19SOleksandr Tymoshenko 
69224ca3d19SOleksandr Tymoshenko 	fg = a & 0xf ;
69324ca3d19SOleksandr Tymoshenko 	bg = (a >> 4) & 0xf;
69424ca3d19SOleksandr Tymoshenko 
69524ca3d19SOleksandr Tymoshenko 	for (i = 0; i < AM335X_FONT_HEIGHT; i++) {
69624ca3d19SOleksandr Tymoshenko 		for (j = 0, k = 7; j < 8; j++, k--) {
69724ca3d19SOleksandr Tymoshenko 			if ((p[i] & (1 << k)) == 0)
69824ca3d19SOleksandr Tymoshenko 				color = bg;
69924ca3d19SOleksandr Tymoshenko 			else
70024ca3d19SOleksandr Tymoshenko 				color = fg;
70124ca3d19SOleksandr Tymoshenko 
70224ca3d19SOleksandr Tymoshenko 			switch (sc->depth) {
70324ca3d19SOleksandr Tymoshenko 			case 32:
70424ca3d19SOleksandr Tymoshenko 				addr[4*j+0] = am335x_syscons_palette[color].r;
70524ca3d19SOleksandr Tymoshenko 				addr[4*j+1] = am335x_syscons_palette[color].g;
70624ca3d19SOleksandr Tymoshenko 				addr[4*j+2] = am335x_syscons_palette[color].b;
70724ca3d19SOleksandr Tymoshenko 				addr[4*j+3] = am335x_syscons_palette[color].a;
70824ca3d19SOleksandr Tymoshenko 				break;
70924ca3d19SOleksandr Tymoshenko 			case 24:
71024ca3d19SOleksandr Tymoshenko 				addr[3*j] = am335x_syscons_palette[color].r;
71124ca3d19SOleksandr Tymoshenko 				addr[3*j+1] = am335x_syscons_palette[color].g;
71224ca3d19SOleksandr Tymoshenko 				addr[3*j+2] = am335x_syscons_palette[color].b;
71324ca3d19SOleksandr Tymoshenko 				break;
71424ca3d19SOleksandr Tymoshenko 			case 16:
71524ca3d19SOleksandr Tymoshenko 				rgb = (am335x_syscons_palette[color].r >> 3) << 11;
71624ca3d19SOleksandr Tymoshenko 				rgb |= (am335x_syscons_palette[color].g >> 2) << 5;
71724ca3d19SOleksandr Tymoshenko 				rgb |= (am335x_syscons_palette[color].b >> 3);
71824ca3d19SOleksandr Tymoshenko 				addr[2*j] = rgb & 0xff;
71924ca3d19SOleksandr Tymoshenko 				addr[2*j + 1] = (rgb >> 8) & 0xff;
72024ca3d19SOleksandr Tymoshenko 			default:
72124ca3d19SOleksandr Tymoshenko 				/* Not supported yet */
72224ca3d19SOleksandr Tymoshenko 				break;
72324ca3d19SOleksandr Tymoshenko 			}
72424ca3d19SOleksandr Tymoshenko 		}
72524ca3d19SOleksandr Tymoshenko 
72624ca3d19SOleksandr Tymoshenko 		addr += (sc->stride);
72724ca3d19SOleksandr Tymoshenko 	}
72824ca3d19SOleksandr Tymoshenko 
72924ca3d19SOleksandr Tymoshenko         return (0);
73024ca3d19SOleksandr Tymoshenko }
73124ca3d19SOleksandr Tymoshenko 
73224ca3d19SOleksandr Tymoshenko static int
am335x_syscons_puts(video_adapter_t * adp,vm_offset_t off,u_int16_t * s,int len)73324ca3d19SOleksandr Tymoshenko am335x_syscons_puts(video_adapter_t *adp, vm_offset_t off, u_int16_t *s, int len)
73424ca3d19SOleksandr Tymoshenko {
73524ca3d19SOleksandr Tymoshenko 	int i;
73624ca3d19SOleksandr Tymoshenko 
73724ca3d19SOleksandr Tymoshenko 	for (i = 0; i < len; i++)
73824ca3d19SOleksandr Tymoshenko 		am335x_syscons_putc(adp, off + i, s[i] & 0xff, (s[i] & 0xff00) >> 8);
73924ca3d19SOleksandr Tymoshenko 
74024ca3d19SOleksandr Tymoshenko 	return (0);
74124ca3d19SOleksandr Tymoshenko }
74224ca3d19SOleksandr Tymoshenko 
74324ca3d19SOleksandr Tymoshenko static int
am335x_syscons_putm(video_adapter_t * adp,int x,int y,uint8_t * pixel_image,uint32_t pixel_mask,int size,int width)74424ca3d19SOleksandr Tymoshenko am335x_syscons_putm(video_adapter_t *adp, int x, int y, uint8_t *pixel_image,
74524ca3d19SOleksandr Tymoshenko     uint32_t pixel_mask, int size, int width)
74624ca3d19SOleksandr Tymoshenko {
74724ca3d19SOleksandr Tymoshenko 
74824ca3d19SOleksandr Tymoshenko 	return (0);
74924ca3d19SOleksandr Tymoshenko }
75024ca3d19SOleksandr Tymoshenko 
75124ca3d19SOleksandr Tymoshenko /* Initialization function */
am335x_lcd_syscons_setup(vm_offset_t vaddr,vm_paddr_t paddr,struct panel_info * panel)75224ca3d19SOleksandr Tymoshenko int am335x_lcd_syscons_setup(vm_offset_t vaddr, vm_paddr_t paddr,
75324ca3d19SOleksandr Tymoshenko     struct panel_info *panel)
75424ca3d19SOleksandr Tymoshenko {
75524ca3d19SOleksandr Tymoshenko 	struct video_adapter_softc *va_sc = &va_softc;
75624ca3d19SOleksandr Tymoshenko 
75724ca3d19SOleksandr Tymoshenko 	va_sc->fb_addr = vaddr;
75824ca3d19SOleksandr Tymoshenko 	va_sc->fb_paddr = paddr;
75924ca3d19SOleksandr Tymoshenko 	va_sc->depth = panel->bpp;
76024ca3d19SOleksandr Tymoshenko 	va_sc->stride = panel->bpp*panel->panel_width/8;
76124ca3d19SOleksandr Tymoshenko 
76224ca3d19SOleksandr Tymoshenko 	va_sc->width = panel->panel_width;
76324ca3d19SOleksandr Tymoshenko 	va_sc->height = panel->panel_height;
76424ca3d19SOleksandr Tymoshenko 	va_sc->fb_size = va_sc->width * va_sc->height
76524ca3d19SOleksandr Tymoshenko 	    * va_sc->depth/8;
76624ca3d19SOleksandr Tymoshenko 	am335x_syscons_update_margins(&va_sc->va);
76724ca3d19SOleksandr Tymoshenko 
76824ca3d19SOleksandr Tymoshenko 	return (0);
76924ca3d19SOleksandr Tymoshenko }
770