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