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
exdisplay_match(struct device * parent,void * v,void * aux)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
exdisplay_attach(struct device * parent,struct device * self,void * args)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, ®))
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
exdisplay_cnattach(bus_space_tag_t iot,bus_addr_t iobase,size_t size)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
exdisplay_setup_rasops(struct rasops_info * rinfo,struct wsscreen_descr * descr)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
exdisplay_wsioctl(void * v,u_long cmd,caddr_t data,int flag,struct proc * p)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
exdisplay_wsmmap(void * v,off_t off,int prot)234 exdisplay_wsmmap(void *v, off_t off, int prot)
235 {
236 return (-1);
237 }
238
239 int
exdisplay_alloc_screen(void * v,const struct wsscreen_descr * type,void ** cookiep,int * curxp,int * curyp,uint32_t * attrp)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
exdisplay_free_screen(void * v,void * cookie)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
exdisplay_show_screen(void * v,void * cookie,int waitok,void (* cb)(void *,int,int),void * cbarg)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
exdisplay_doswitch(void * v,void * dummy)266 exdisplay_doswitch(void *v, void *dummy)
267 {
268 }
269
270 int
exdisplay_getchar(void * v,int row,int col,struct wsdisplay_charcell * cell)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
exdisplay_load_font(void * v,void * cookie,struct wsdisplay_font * font)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
exdisplay_list_font(void * v,struct wsdisplay_font * font)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
exdisplay_burner(void * v,u_int on,u_int flags)298 exdisplay_burner(void *v, u_int on, u_int flags)
299 {
300 }
301