xref: /openbsd-src/sys/arch/armv7/exynos/exdisplay.c (revision 9fdf0c627b1fec102f212f847a6f7676c1829e65)
1*9fdf0c62Smpi /* $OpenBSD: exdisplay.c,v 1.7 2021/10/24 17:52:27 mpi Exp $ */
207829fe8Sbmercer /*
307829fe8Sbmercer  * Copyright (c) 2013 Patrick Wildt <patrick@blueri.se>
407829fe8Sbmercer  *
507829fe8Sbmercer  * Permission to use, copy, modify, and distribute this software for any
607829fe8Sbmercer  * purpose with or without fee is hereby granted, provided that the above
707829fe8Sbmercer  * copyright notice and this permission notice appear in all copies.
807829fe8Sbmercer  *
907829fe8Sbmercer  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1007829fe8Sbmercer  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1107829fe8Sbmercer  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1207829fe8Sbmercer  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1307829fe8Sbmercer  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1407829fe8Sbmercer  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1507829fe8Sbmercer  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1607829fe8Sbmercer  */
1707829fe8Sbmercer 
1807829fe8Sbmercer #include <sys/param.h>
1907829fe8Sbmercer #include <sys/systm.h>
2007829fe8Sbmercer #include <sys/queue.h>
2107829fe8Sbmercer #include <sys/malloc.h>
2207829fe8Sbmercer #include <sys/device.h>
2307829fe8Sbmercer #include <sys/evcount.h>
2407829fe8Sbmercer #include <sys/socket.h>
2507829fe8Sbmercer #include <sys/timeout.h>
2607829fe8Sbmercer 
2707829fe8Sbmercer #include <dev/cons.h>
2807829fe8Sbmercer #include <dev/wscons/wsconsio.h>
2907829fe8Sbmercer #include <dev/wscons/wsdisplayvar.h>
3007829fe8Sbmercer #include <dev/wscons/wscons_callbacks.h>
3107829fe8Sbmercer #include <dev/wsfont/wsfont.h>
3207829fe8Sbmercer #include <dev/rasops/rasops.h>
3307829fe8Sbmercer 
3407829fe8Sbmercer #include <machine/intr.h>
3507829fe8Sbmercer #include <machine/bus.h>
36ae88ccfdSjsg #if NFDT > 0
3707829fe8Sbmercer #include <machine/fdt.h>
38ae88ccfdSjsg #endif
3907829fe8Sbmercer #include <armv7/armv7/armv7var.h>
4007829fe8Sbmercer 
4107829fe8Sbmercer /* registers */
4207829fe8Sbmercer 
4307829fe8Sbmercer struct exdisplay_softc {
4407829fe8Sbmercer 	struct device		 sc_dev;
4507829fe8Sbmercer 	bus_space_tag_t		 sc_iot;
4607829fe8Sbmercer 	bus_space_handle_t	 sc_ioh;
4707829fe8Sbmercer 	struct rasops_info	*ro;
4807829fe8Sbmercer };
4907829fe8Sbmercer 
5007829fe8Sbmercer int exdisplay_match(struct device *parent, void *v, void *aux);
5107829fe8Sbmercer void exdisplay_attach(struct device *parent, struct device *self, void *args);
5207829fe8Sbmercer int exdisplay_cnattach(bus_space_tag_t iot, bus_addr_t iobase, size_t size);
5307829fe8Sbmercer void exdisplay_setup_rasops(struct rasops_info *rinfo, struct wsscreen_descr *descr);
5407829fe8Sbmercer 
55*9fdf0c62Smpi const struct cfattach	exdisplay_ca = {
5607829fe8Sbmercer 	sizeof (struct exdisplay_softc), NULL, exdisplay_attach
5707829fe8Sbmercer };
58*9fdf0c62Smpi const struct cfattach	exdisplay_fdt_ca = {
5907829fe8Sbmercer 	sizeof (struct exdisplay_softc), exdisplay_match, exdisplay_attach
6007829fe8Sbmercer };
6107829fe8Sbmercer 
6207829fe8Sbmercer struct cfdriver exdisplay_cd = {
6307829fe8Sbmercer 	NULL, "exdisplay", DV_DULL
6407829fe8Sbmercer };
6507829fe8Sbmercer 
6607829fe8Sbmercer int exdisplay_wsioctl(void *, u_long, caddr_t, int, struct proc *);
6707829fe8Sbmercer paddr_t exdisplay_wsmmap(void *, off_t, int);
6807829fe8Sbmercer int exdisplay_alloc_screen(void *, const struct wsscreen_descr *,
69e0c3e559Sjsg     void **, int *, int *, uint32_t *);
7007829fe8Sbmercer void exdisplay_free_screen(void *, void *);
7107829fe8Sbmercer int exdisplay_show_screen(void *, void *, int,
7207829fe8Sbmercer     void (*)(void *, int, int), void *);
7307829fe8Sbmercer void exdisplay_doswitch(void *, void *);
7407829fe8Sbmercer int exdisplay_load_font(void *, void *, struct wsdisplay_font *);
7507829fe8Sbmercer int exdisplay_list_font(void *, struct wsdisplay_font *);
7607829fe8Sbmercer int exdisplay_getchar(void *, int, int, struct wsdisplay_charcell *);
7707829fe8Sbmercer void exdisplay_burner(void *, u_int, u_int);
7807829fe8Sbmercer 
7907829fe8Sbmercer struct rasops_info exdisplay_ri;
8007829fe8Sbmercer struct wsscreen_descr exdisplay_stdscreen = {
8107829fe8Sbmercer 	"std"
8207829fe8Sbmercer };
8307829fe8Sbmercer 
8407829fe8Sbmercer const struct wsscreen_descr *exdisplay_scrlist[] = {
8507829fe8Sbmercer 	&exdisplay_stdscreen,
8607829fe8Sbmercer };
8707829fe8Sbmercer 
8807829fe8Sbmercer struct wsscreen_list exdisplay_screenlist = {
8907829fe8Sbmercer 	nitems(exdisplay_scrlist), exdisplay_scrlist
9007829fe8Sbmercer };
9107829fe8Sbmercer 
9207829fe8Sbmercer struct wsdisplay_accessops exdisplay_accessops = {
9307829fe8Sbmercer 	.ioctl = exdisplay_wsioctl,
9407829fe8Sbmercer 	.mmap = exdisplay_wsmmap,
9507829fe8Sbmercer 	.alloc_screen = exdisplay_alloc_screen,
9607829fe8Sbmercer 	.free_screen = exdisplay_free_screen,
9707829fe8Sbmercer 	.show_screen = exdisplay_show_screen,
9807829fe8Sbmercer 	.getchar = exdisplay_getchar,
9907829fe8Sbmercer 	.load_font = exdisplay_load_font,
10007829fe8Sbmercer 	.list_font = exdisplay_list_font,
10107829fe8Sbmercer 	.burn_screen = exdisplay_burner
10207829fe8Sbmercer };
10307829fe8Sbmercer 
10407829fe8Sbmercer int
exdisplay_match(struct device * parent,void * v,void * aux)10507829fe8Sbmercer exdisplay_match(struct device *parent, void *v, void *aux)
10607829fe8Sbmercer {
107ae88ccfdSjsg #if NFDT > 0
10807829fe8Sbmercer 	struct armv7_attach_args *aa = aux;
10907829fe8Sbmercer 
11007829fe8Sbmercer 	if (fdt_node_compatible("samsung,exynos5250-fimd", aa->aa_node))
11107829fe8Sbmercer 		return 1;
112ae88ccfdSjsg #endif
11307829fe8Sbmercer 
11407829fe8Sbmercer 	return 0;
11507829fe8Sbmercer }
11607829fe8Sbmercer 
11707829fe8Sbmercer void
exdisplay_attach(struct device * parent,struct device * self,void * args)11807829fe8Sbmercer exdisplay_attach(struct device *parent, struct device *self, void *args)
11907829fe8Sbmercer {
12007829fe8Sbmercer 	struct armv7_attach_args *aa = args;
12107829fe8Sbmercer 	struct exdisplay_softc *sc = (struct exdisplay_softc *) self;
12207829fe8Sbmercer 	struct wsemuldisplaydev_attach_args waa;
12307829fe8Sbmercer 	struct rasops_info *ri = &exdisplay_ri;
124ae88ccfdSjsg 	struct armv7mem mem;
12507829fe8Sbmercer 
12607829fe8Sbmercer 	sc->sc_iot = aa->aa_iot;
127ae88ccfdSjsg #if NFDT > 0
128ae88ccfdSjsg 	if (aa->aa_node) {
129b7952965Spatrick 		struct fdt_reg reg;
130b7952965Spatrick 		if (fdt_get_reg(aa->aa_node, 0, &reg))
13107829fe8Sbmercer 			panic("%s: could not extract memory data from FDT",
13207829fe8Sbmercer 			    __func__);
133b7952965Spatrick 		mem.addr = reg.addr;
134b7952965Spatrick 		mem.size = reg.size;
135ae88ccfdSjsg 	} else
136ae88ccfdSjsg #endif
137ae88ccfdSjsg 	{
138ae88ccfdSjsg 		mem.addr = aa->aa_dev->mem[0].addr;
139ae88ccfdSjsg 		mem.size = aa->aa_dev->mem[0].size;
140ae88ccfdSjsg 	}
14107829fe8Sbmercer 
14207829fe8Sbmercer 	if (bus_space_map(sc->sc_iot, mem.addr, mem.size, 0, &sc->sc_ioh))
14307829fe8Sbmercer 		panic("%s: bus_space_map failed!", __func__);
14407829fe8Sbmercer 
14507829fe8Sbmercer 	printf("\n");
14607829fe8Sbmercer 
14707829fe8Sbmercer #if notyet
14807829fe8Sbmercer 	/* FIXME: Set up framebuffer instead of re-using. */
14907829fe8Sbmercer 	if (!fdt_find_compatible("simple-framebuffer")) {
150e0c3e559Sjsg 		uint32_t defattr;
15107829fe8Sbmercer 
15207829fe8Sbmercer 		ri->ri_bits = (u_char *)sc->sc_fbioh;
15307829fe8Sbmercer 		exdisplay_setup_rasops(ri, &exdisplay_stdscreen);
15407829fe8Sbmercer 
155fc223b23Sjsg 		ri->ri_ops.pack_attr(ri->ri_active, 0, 0, 0, &defattr);
15607829fe8Sbmercer 		wsdisplay_cnattach(&exdisplay_stdscreen, ri->ri_active,
15707829fe8Sbmercer 		    0, 0, defattr);
15807829fe8Sbmercer 	}
15907829fe8Sbmercer #endif
16007829fe8Sbmercer 
16107829fe8Sbmercer 	sc->ro = ri;
16207829fe8Sbmercer 
16307829fe8Sbmercer 	waa.console = 1;
16407829fe8Sbmercer 	waa.scrdata = &exdisplay_screenlist;
16507829fe8Sbmercer 	waa.accessops = &exdisplay_accessops;
16607829fe8Sbmercer 	waa.accesscookie = sc;
16707829fe8Sbmercer 	waa.defaultscreens = 0;
16807829fe8Sbmercer 
16907829fe8Sbmercer 	printf("%s: %dx%d\n", sc->sc_dev.dv_xname, ri->ri_width, ri->ri_height);
17007829fe8Sbmercer 
17107829fe8Sbmercer 	config_found(self, &waa, wsemuldisplaydevprint);
17207829fe8Sbmercer }
17307829fe8Sbmercer 
17407829fe8Sbmercer int
exdisplay_cnattach(bus_space_tag_t iot,bus_addr_t iobase,size_t size)17507829fe8Sbmercer exdisplay_cnattach(bus_space_tag_t iot, bus_addr_t iobase, size_t size)
17607829fe8Sbmercer {
17707829fe8Sbmercer 	struct wsscreen_descr *descr = &exdisplay_stdscreen;
17807829fe8Sbmercer 	struct rasops_info *ri = &exdisplay_ri;
179e0c3e559Sjsg 	uint32_t defattr;
18007829fe8Sbmercer 
18107829fe8Sbmercer 	if (bus_space_map(iot, iobase, size, 0, (bus_space_handle_t *)&ri->ri_bits))
18207829fe8Sbmercer 		return ENOMEM;
18307829fe8Sbmercer 
18407829fe8Sbmercer 	exdisplay_setup_rasops(ri, descr);
18507829fe8Sbmercer 
18607829fe8Sbmercer 	/* assumes 16 bpp */
187fc223b23Sjsg 	ri->ri_ops.pack_attr(ri, 0, 0, 0, &defattr);
18807829fe8Sbmercer 
18907829fe8Sbmercer 	wsdisplay_cnattach(descr, ri, ri->ri_ccol, ri->ri_crow, defattr);
19007829fe8Sbmercer 
19107829fe8Sbmercer 	return 0;
19207829fe8Sbmercer }
19307829fe8Sbmercer 
19407829fe8Sbmercer void
exdisplay_setup_rasops(struct rasops_info * rinfo,struct wsscreen_descr * descr)19507829fe8Sbmercer exdisplay_setup_rasops(struct rasops_info *rinfo, struct wsscreen_descr *descr)
19607829fe8Sbmercer {
19707829fe8Sbmercer 	rinfo->ri_flg = RI_CLEAR;
19807829fe8Sbmercer 	rinfo->ri_depth = 16;
19907829fe8Sbmercer 	rinfo->ri_width = 1366;
20007829fe8Sbmercer 	rinfo->ri_height = 768;
20107829fe8Sbmercer 	rinfo->ri_stride = rinfo->ri_width * rinfo->ri_depth / 8;
20207829fe8Sbmercer 
20307829fe8Sbmercer 	/* swap B and R */
20407829fe8Sbmercer 	if (rinfo->ri_depth == 16) {
20507829fe8Sbmercer 		rinfo->ri_rnum = 5;
20607829fe8Sbmercer 		rinfo->ri_rpos = 11;
20707829fe8Sbmercer 		rinfo->ri_gnum = 6;
20807829fe8Sbmercer 		rinfo->ri_gpos = 5;
20907829fe8Sbmercer 		rinfo->ri_bnum = 5;
21007829fe8Sbmercer 		rinfo->ri_bpos = 0;
21107829fe8Sbmercer 	}
21207829fe8Sbmercer 
21307829fe8Sbmercer 	wsfont_init();
21407829fe8Sbmercer 	rinfo->ri_wsfcookie = wsfont_find(NULL, 8, 0, 0);
21507829fe8Sbmercer 	wsfont_lock(rinfo->ri_wsfcookie, &rinfo->ri_font,
21607829fe8Sbmercer 	    WSDISPLAY_FONTORDER_L2R, WSDISPLAY_FONTORDER_L2R);
21707829fe8Sbmercer 
21807829fe8Sbmercer 	/* get rasops to compute screen size the first time */
21907829fe8Sbmercer 	rasops_init(rinfo, 200, 200);
22007829fe8Sbmercer 
22107829fe8Sbmercer 	descr->nrows = rinfo->ri_rows;
22207829fe8Sbmercer 	descr->ncols = rinfo->ri_cols;
22307829fe8Sbmercer 	descr->capabilities = rinfo->ri_caps;
22407829fe8Sbmercer 	descr->textops = &rinfo->ri_ops;
22507829fe8Sbmercer }
22607829fe8Sbmercer 
22707829fe8Sbmercer int
exdisplay_wsioctl(void * v,u_long cmd,caddr_t data,int flag,struct proc * p)22807829fe8Sbmercer exdisplay_wsioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
22907829fe8Sbmercer {
23007829fe8Sbmercer 	return (-1);
23107829fe8Sbmercer }
23207829fe8Sbmercer 
23307829fe8Sbmercer paddr_t
exdisplay_wsmmap(void * v,off_t off,int prot)23407829fe8Sbmercer exdisplay_wsmmap(void *v, off_t off, int prot)
23507829fe8Sbmercer {
23607829fe8Sbmercer 	return (-1);
23707829fe8Sbmercer }
23807829fe8Sbmercer 
23907829fe8Sbmercer int
exdisplay_alloc_screen(void * v,const struct wsscreen_descr * type,void ** cookiep,int * curxp,int * curyp,uint32_t * attrp)24007829fe8Sbmercer exdisplay_alloc_screen(void *v, const struct wsscreen_descr *type,
241e0c3e559Sjsg     void **cookiep, int *curxp, int *curyp, uint32_t *attrp)
24207829fe8Sbmercer {
24307829fe8Sbmercer 	struct exdisplay_softc *sc = v;
24407829fe8Sbmercer 	struct rasops_info *ri = sc->ro;
24507829fe8Sbmercer 
24607829fe8Sbmercer 	return rasops_alloc_screen(ri, cookiep, curxp, curyp, attrp);
24707829fe8Sbmercer }
24807829fe8Sbmercer 
24907829fe8Sbmercer void
exdisplay_free_screen(void * v,void * cookie)25007829fe8Sbmercer exdisplay_free_screen(void *v, void *cookie)
25107829fe8Sbmercer {
25207829fe8Sbmercer 	struct exdisplay_softc *sc = v;
25307829fe8Sbmercer 	struct rasops_info *ri = sc->ro;
25407829fe8Sbmercer 
25507829fe8Sbmercer 	return rasops_free_screen(ri, cookie);
25607829fe8Sbmercer }
25707829fe8Sbmercer 
25807829fe8Sbmercer int
exdisplay_show_screen(void * v,void * cookie,int waitok,void (* cb)(void *,int,int),void * cbarg)25907829fe8Sbmercer exdisplay_show_screen(void *v, void *cookie, int waitok,
26007829fe8Sbmercer     void (*cb)(void *, int, int), void *cbarg)
26107829fe8Sbmercer {
26207829fe8Sbmercer 	return (0);
26307829fe8Sbmercer }
26407829fe8Sbmercer 
26507829fe8Sbmercer void
exdisplay_doswitch(void * v,void * dummy)26607829fe8Sbmercer exdisplay_doswitch(void *v, void *dummy)
26707829fe8Sbmercer {
26807829fe8Sbmercer }
26907829fe8Sbmercer 
27007829fe8Sbmercer int
exdisplay_getchar(void * v,int row,int col,struct wsdisplay_charcell * cell)27107829fe8Sbmercer exdisplay_getchar(void *v, int row, int col, struct wsdisplay_charcell *cell)
27207829fe8Sbmercer {
27307829fe8Sbmercer 	struct exdisplay_softc *sc = v;
27407829fe8Sbmercer 	struct rasops_info *ri = sc->ro;
27507829fe8Sbmercer 
27607829fe8Sbmercer 	return rasops_getchar(ri, row, col, cell);
27707829fe8Sbmercer }
27807829fe8Sbmercer 
27907829fe8Sbmercer int
exdisplay_load_font(void * v,void * cookie,struct wsdisplay_font * font)28007829fe8Sbmercer exdisplay_load_font(void *v, void *cookie, struct wsdisplay_font *font)
28107829fe8Sbmercer {
28207829fe8Sbmercer 	struct exdisplay_softc *sc = v;
28307829fe8Sbmercer 	struct rasops_info *ri = sc->ro;
28407829fe8Sbmercer 
28507829fe8Sbmercer 	return rasops_load_font(ri, cookie, font);
28607829fe8Sbmercer }
28707829fe8Sbmercer 
28807829fe8Sbmercer int
exdisplay_list_font(void * v,struct wsdisplay_font * font)28907829fe8Sbmercer exdisplay_list_font(void *v, struct wsdisplay_font *font)
29007829fe8Sbmercer {
29107829fe8Sbmercer 	struct exdisplay_softc *sc = v;
29207829fe8Sbmercer 	struct rasops_info *ri = sc->ro;
29307829fe8Sbmercer 
29407829fe8Sbmercer 	return rasops_list_font(ri, font);
29507829fe8Sbmercer }
29607829fe8Sbmercer 
29707829fe8Sbmercer void
exdisplay_burner(void * v,u_int on,u_int flags)29807829fe8Sbmercer exdisplay_burner(void *v, u_int on, u_int flags)
29907829fe8Sbmercer {
30007829fe8Sbmercer }
301