xref: /openbsd/sys/arch/armv7/exynos/exdisplay.c (revision 5af055cd)
1 /* $OpenBSD: exdisplay.c,v 1.2 2015/05/27 00:06:14 jsg Exp $ */
2 /*
3  * Copyright (c) 2013 Patrick Wildt <patrick@blueri.se>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include "fdt.h"
19 
20 #include <sys/param.h>
21 #include <sys/systm.h>
22 #include <sys/queue.h>
23 #include <sys/malloc.h>
24 #include <sys/device.h>
25 #include <sys/evcount.h>
26 #include <sys/socket.h>
27 #include <sys/timeout.h>
28 
29 #include <dev/cons.h>
30 #include <dev/wscons/wsconsio.h>
31 #include <dev/wscons/wsdisplayvar.h>
32 #include <dev/wscons/wscons_callbacks.h>
33 #include <dev/wsfont/wsfont.h>
34 #include <dev/rasops/rasops.h>
35 
36 #include <machine/intr.h>
37 #include <machine/bus.h>
38 #if NFDT > 0
39 #include <machine/fdt.h>
40 #endif
41 #include <armv7/armv7/armv7var.h>
42 
43 /* registers */
44 
45 struct exdisplay_softc {
46 	struct device		 sc_dev;
47 	bus_space_tag_t		 sc_iot;
48 	bus_space_handle_t	 sc_ioh;
49 	struct rasops_info	*ro;
50 };
51 
52 int exdisplay_match(struct device *parent, void *v, void *aux);
53 void exdisplay_attach(struct device *parent, struct device *self, void *args);
54 int exdisplay_cnattach(bus_space_tag_t iot, bus_addr_t iobase, size_t size);
55 void exdisplay_setup_rasops(struct rasops_info *rinfo, struct wsscreen_descr *descr);
56 
57 struct cfattach	exdisplay_ca = {
58 	sizeof (struct exdisplay_softc), NULL, exdisplay_attach
59 };
60 struct cfattach	exdisplay_fdt_ca = {
61 	sizeof (struct exdisplay_softc), exdisplay_match, exdisplay_attach
62 };
63 
64 struct cfdriver exdisplay_cd = {
65 	NULL, "exdisplay", DV_DULL
66 };
67 
68 int exdisplay_wsioctl(void *, u_long, caddr_t, int, struct proc *);
69 paddr_t exdisplay_wsmmap(void *, off_t, int);
70 int exdisplay_alloc_screen(void *, const struct wsscreen_descr *,
71     void **, int *, int *, long *);
72 void exdisplay_free_screen(void *, void *);
73 int exdisplay_show_screen(void *, void *, int,
74     void (*)(void *, int, int), void *);
75 void exdisplay_doswitch(void *, void *);
76 int exdisplay_load_font(void *, void *, struct wsdisplay_font *);
77 int exdisplay_list_font(void *, struct wsdisplay_font *);
78 int exdisplay_getchar(void *, int, int, struct wsdisplay_charcell *);
79 void exdisplay_burner(void *, u_int, u_int);
80 
81 struct rasops_info exdisplay_ri;
82 struct wsscreen_descr exdisplay_stdscreen = {
83 	"std"
84 };
85 
86 const struct wsscreen_descr *exdisplay_scrlist[] = {
87 	&exdisplay_stdscreen,
88 };
89 
90 struct wsscreen_list exdisplay_screenlist = {
91 	nitems(exdisplay_scrlist), exdisplay_scrlist
92 };
93 
94 struct wsdisplay_accessops exdisplay_accessops = {
95 	.ioctl = exdisplay_wsioctl,
96 	.mmap = exdisplay_wsmmap,
97 	.alloc_screen = exdisplay_alloc_screen,
98 	.free_screen = exdisplay_free_screen,
99 	.show_screen = exdisplay_show_screen,
100 	.getchar = exdisplay_getchar,
101 	.load_font = exdisplay_load_font,
102 	.list_font = exdisplay_list_font,
103 	.burn_screen = exdisplay_burner
104 };
105 
106 int
107 exdisplay_match(struct device *parent, void *v, void *aux)
108 {
109 #if NFDT > 0
110 	struct armv7_attach_args *aa = aux;
111 
112 	if (fdt_node_compatible("samsung,exynos5250-fimd", aa->aa_node))
113 		return 1;
114 #endif
115 
116 	return 0;
117 }
118 
119 void
120 exdisplay_attach(struct device *parent, struct device *self, void *args)
121 {
122 	struct armv7_attach_args *aa = args;
123 	struct exdisplay_softc *sc = (struct exdisplay_softc *) self;
124 	struct wsemuldisplaydev_attach_args waa;
125 	struct rasops_info *ri = &exdisplay_ri;
126 	struct armv7mem mem;
127 
128 	sc->sc_iot = aa->aa_iot;
129 #if NFDT > 0
130 	if (aa->aa_node) {
131 		struct fdt_memory fdtmem;
132 		if (fdt_get_memory_address(aa->aa_node, 0, &fdtmem))
133 			panic("%s: could not extract memory data from FDT",
134 			    __func__);
135 		mem.addr = fdtmem.addr;
136 		mem.size = fdtmem.size;
137 	} else
138 #endif
139 	{
140 		mem.addr = aa->aa_dev->mem[0].addr;
141 		mem.size = aa->aa_dev->mem[0].size;
142 	}
143 
144 	if (bus_space_map(sc->sc_iot, mem.addr, mem.size, 0, &sc->sc_ioh))
145 		panic("%s: bus_space_map failed!", __func__);
146 
147 	printf("\n");
148 
149 #if notyet
150 	/* FIXME: Set up framebuffer instead of re-using. */
151 	if (!fdt_find_compatible("simple-framebuffer")) {
152 		long defattr;
153 
154 		ri->ri_bits = (u_char *)sc->sc_fbioh;
155 		exdisplay_setup_rasops(ri, &exdisplay_stdscreen);
156 
157 		ri->ri_ops.alloc_attr(ri->ri_active, 0, 0, 0, &defattr);
158 		wsdisplay_cnattach(&exdisplay_stdscreen, ri->ri_active,
159 		    0, 0, defattr);
160 	}
161 #endif
162 
163 	sc->ro = ri;
164 
165 	waa.console = 1;
166 	waa.scrdata = &exdisplay_screenlist;
167 	waa.accessops = &exdisplay_accessops;
168 	waa.accesscookie = sc;
169 	waa.defaultscreens = 0;
170 
171 	printf("%s: %dx%d\n", sc->sc_dev.dv_xname, ri->ri_width, ri->ri_height);
172 
173 	config_found(self, &waa, wsemuldisplaydevprint);
174 }
175 
176 int
177 exdisplay_cnattach(bus_space_tag_t iot, bus_addr_t iobase, size_t size)
178 {
179 	struct wsscreen_descr *descr = &exdisplay_stdscreen;
180 	struct rasops_info *ri = &exdisplay_ri;
181 	long defattr;
182 
183 	if (bus_space_map(iot, iobase, size, 0, (bus_space_handle_t *)&ri->ri_bits))
184 		return ENOMEM;
185 
186 	exdisplay_setup_rasops(ri, descr);
187 
188 	/* assumes 16 bpp */
189 	ri->ri_ops.alloc_attr(ri, 0, 0, 0, &defattr);
190 
191 	wsdisplay_cnattach(descr, ri, ri->ri_ccol, ri->ri_crow, defattr);
192 
193 	return 0;
194 }
195 
196 void
197 exdisplay_setup_rasops(struct rasops_info *rinfo, struct wsscreen_descr *descr)
198 {
199 	rinfo->ri_flg = RI_CLEAR;
200 	rinfo->ri_depth = 16;
201 	rinfo->ri_width = 1366;
202 	rinfo->ri_height = 768;
203 	rinfo->ri_stride = rinfo->ri_width * rinfo->ri_depth / 8;
204 
205 	/* swap B and R */
206 	if (rinfo->ri_depth == 16) {
207 		rinfo->ri_rnum = 5;
208 		rinfo->ri_rpos = 11;
209 		rinfo->ri_gnum = 6;
210 		rinfo->ri_gpos = 5;
211 		rinfo->ri_bnum = 5;
212 		rinfo->ri_bpos = 0;
213 	}
214 
215 	wsfont_init();
216 	rinfo->ri_wsfcookie = wsfont_find(NULL, 8, 0, 0);
217 	wsfont_lock(rinfo->ri_wsfcookie, &rinfo->ri_font,
218 	    WSDISPLAY_FONTORDER_L2R, WSDISPLAY_FONTORDER_L2R);
219 
220 	/* get rasops to compute screen size the first time */
221 	rasops_init(rinfo, 200, 200);
222 
223 	descr->nrows = rinfo->ri_rows;
224 	descr->ncols = rinfo->ri_cols;
225 	descr->capabilities = rinfo->ri_caps;
226 	descr->textops = &rinfo->ri_ops;
227 }
228 
229 int
230 exdisplay_wsioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
231 {
232 	return (-1);
233 }
234 
235 paddr_t
236 exdisplay_wsmmap(void *v, off_t off, int prot)
237 {
238 	return (-1);
239 }
240 
241 int
242 exdisplay_alloc_screen(void *v, const struct wsscreen_descr *type,
243     void **cookiep, int *curxp, int *curyp, long *attrp)
244 {
245 	struct exdisplay_softc *sc = v;
246 	struct rasops_info *ri = sc->ro;
247 
248 	return rasops_alloc_screen(ri, cookiep, curxp, curyp, attrp);
249 }
250 
251 void
252 exdisplay_free_screen(void *v, void *cookie)
253 {
254 	struct exdisplay_softc *sc = v;
255 	struct rasops_info *ri = sc->ro;
256 
257 	return rasops_free_screen(ri, cookie);
258 }
259 
260 int
261 exdisplay_show_screen(void *v, void *cookie, int waitok,
262     void (*cb)(void *, int, int), void *cbarg)
263 {
264 	return (0);
265 }
266 
267 void
268 exdisplay_doswitch(void *v, void *dummy)
269 {
270 }
271 
272 int
273 exdisplay_getchar(void *v, int row, int col, struct wsdisplay_charcell *cell)
274 {
275 	struct exdisplay_softc *sc = v;
276 	struct rasops_info *ri = sc->ro;
277 
278 	return rasops_getchar(ri, row, col, cell);
279 }
280 
281 int
282 exdisplay_load_font(void *v, void *cookie, struct wsdisplay_font *font)
283 {
284 	struct exdisplay_softc *sc = v;
285 	struct rasops_info *ri = sc->ro;
286 
287 	return rasops_load_font(ri, cookie, font);
288 }
289 
290 int
291 exdisplay_list_font(void *v, struct wsdisplay_font *font)
292 {
293 	struct exdisplay_softc *sc = v;
294 	struct rasops_info *ri = sc->ro;
295 
296 	return rasops_list_font(ri, font);
297 }
298 
299 void
300 exdisplay_burner(void *v, u_int on, u_int flags)
301 {
302 }
303