]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/terasic/mtl/terasic_mtl_syscons.c
[PowerPC] hwpmc: add support for POWER8/9 PMCs
[FreeBSD/FreeBSD.git] / sys / dev / terasic / mtl / terasic_mtl_syscons.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2012 Robert N. M. Watson
5  * All rights reserved.
6  *
7  * This software was developed by SRI International and the University of
8  * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
9  * ("CTSRD"), as part of the DARPA CRASH research programme.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
35
36 #include <sys/param.h>
37 #include <sys/bus.h>
38 #include <sys/conf.h>
39 #include <sys/consio.h>
40 #include <sys/fbio.h>
41 #include <sys/kbio.h>
42 #include <sys/kernel.h>
43 #include <sys/lock.h>
44 #include <sys/malloc.h>
45 #include <sys/mutex.h>
46 #include <sys/module.h>
47 #include <sys/rman.h>
48 #include <sys/systm.h>
49 #include <sys/uio.h>
50
51 #include <machine/bus.h>
52 #include <machine/resource.h>
53 #include <machine/vm.h>
54
55 #include <dev/fb/fbreg.h>
56
57 #include <dev/kbd/kbdreg.h>
58
59 #include <dev/syscons/syscons.h>
60
61 #include <dev/terasic/mtl/terasic_mtl.h>
62
63 /*
64  * Terasic Multitouch LCD (MTL) syscons driver.  Implement syscons(4)'s
65  * video_switch_t KPI using MTL's text frame buffer.  In principle, we could
66  * actually implement sc_rndr_sw_t, since the MTL text frame buffer implements
67  * a VGA-like memory mapping.  However, this requires a lot more book-keeping
68  * with only minor performance improvements (avoiding indirection), as well as
69  * introducing potential endianness issues.  Instead we accept one additional
70  * memory copy between a software frame buffer and the hardware frame buffer
71  * and the generic frame buffer (gfb) framework.
72  */
73
74 MALLOC_DEFINE(M_TERASIC_MTL, "mtl_syscons", "MTL syscons frame buffer");
75
76 /*
77  * Run early so that boot-time console support can be initialised before
78  * newbus gets around to configuring syscons.
79  *
80  * XXXRW: We may need to do more here in order to see earlier boot messages.
81  */
82 static int
83 terasic_mtl_syscons_configure(int flags)
84 {
85
86         printf("%s: not yet\n", __func__);
87         return (0);
88 }
89
90 static int
91 terasic_mtl_vidsw_probe(int unit, video_adapter_t **adp, void *args,
92     int flags)
93 {
94
95         printf("%s: not yet\n", __func__);
96         return (0);
97 }
98
99 static int
100 terasic_mtl_vidsw_init(int unit, video_adapter_t *adp, int flags)
101 {
102         struct terasic_mtl_softc *sc;
103         video_info_t *vi;
104
105         sc = (struct terasic_mtl_softc *)adp;
106
107         vi = &adp->va_info;
108         vid_init_struct(adp, "terasic_mtl_syscons", -1, unit);
109
110         vi->vi_width = TERASIC_MTL_COLS;
111         if (vi->vi_width > COL)
112                 vi->vi_width = COL;
113         vi->vi_height = TERASIC_MTL_ROWS;
114         if (vi->vi_height > ROW)
115                 vi->vi_height = ROW;
116
117         /*
118          * XXXRW: It's not quite clear how these should be initialised.
119          */
120         vi->vi_cwidth = 0;
121         vi->vi_cheight = 0;
122         vi->vi_flags = V_INFO_COLOR;
123         vi->vi_mem_model = V_INFO_MM_OTHER;
124
125         /*
126          * Software text frame buffer from which we update the actual MTL
127          * frame buffer when asked to.
128          */
129         adp->va_window = (vm_offset_t)sc->mtl_text_soft;
130
131         /*
132          * Declare video adapter capabilities -- at this point, simply color
133          * support, as MTL doesn't support screen borders, font loading, or
134          * mode changes.
135          *
136          * XXXRW: It's unclear if V_ADP_INITIALIZED is needed here; other
137          * syscons(4) drivers are inconsistent about this and
138          * V_ADP_REGISTERED.
139          */
140         adp->va_flags |= V_ADP_COLOR | V_ADP_INITIALIZED;
141         if (vid_register(adp) < 0) {
142                 device_printf(sc->mtl_dev, "%s: vid_register failed\n",
143                     __func__);
144                 return (ENXIO);
145         }
146         adp->va_flags |= V_ADP_REGISTERED;
147         return (0);
148 }
149
150 static int
151 terasic_mtl_vidsw_get_info(video_adapter_t *adp, int mode, video_info_t *info)
152 {
153
154         bcopy(&adp->va_info, info, sizeof(*info));
155         return (0);
156 }
157
158 static int
159 terasic_mtl_vidsw_query_mode(video_adapter_t *adp, video_info_t *info)
160 {
161
162         printf("%s: not yet\n", __func__);
163         return (ENODEV);
164 }
165
166 static int
167 terasic_mtl_vidsw_set_mode(video_adapter_t *adp, int mode)
168 {
169
170         printf("%s: not yet\n", __func__);
171         return (ENODEV);
172 }
173
174 static int
175 terasic_mtl_vidsw_save_font(video_adapter_t *adp, int page, int size,
176     int width, u_char *data, int c, int count)
177 {
178
179         printf("%s: not yet\n", __func__);
180         return (ENODEV);
181 }
182
183 static int
184 terasic_mtl_vidsw_load_font(video_adapter_t *adp, int page, int size,
185     int width, u_char *data, int c, int count)
186 {
187
188         printf("%s: not yet\n", __func__);
189         return (ENODEV);
190 }
191
192 static int
193 terasic_mtl_vidsw_show_font(video_adapter_t *adp, int page)
194 {
195
196         printf("%s: not yet\n", __func__);
197         return (ENODEV);
198 }
199
200 static int
201 terasic_mtl_vidsw_save_palette(video_adapter_t *adp, u_char *palette)
202 {
203
204         printf("%s: not yet\n", __func__);
205         return (ENODEV);
206 }
207
208 static int
209 terasic_mtl_vidsw_load_palette(video_adapter_t *adp, u_char *palette)
210 {
211
212         printf("%s: not yet\n", __func__);
213         return (ENODEV);
214 }
215
216 static int
217 terasic_mtl_vidsw_set_border(video_adapter_t *adp, int border)
218 {
219
220         printf("%s: not yet\n", __func__);
221         return (ENODEV);
222 }
223
224 static int
225 terasic_mtl_vidsw_save_state(video_adapter_t *adp, void *p, size_t size)
226 {
227
228         printf("%s: not yet\n", __func__);
229         return (ENODEV);
230 }
231
232 static int
233 terasic_mtl_vidsw_load_state(video_adapter_t *adp, void *p)
234 {
235
236         printf("%s: not yet\n", __func__);
237         return (ENODEV);
238 }
239
240 static int
241 terasic_mtl_vidsw_set_win_org(video_adapter_t *adp, off_t offset)
242 {
243
244         printf("%s: not yet\n", __func__);
245         return (ENODEV);
246 }
247
248 static int
249 terasic_mtl_vidsw_read_hw_cursor(video_adapter_t *adp, int *colp, int *rowp)
250 {
251         struct terasic_mtl_softc *sc;
252         uint8_t col, row;
253
254         sc = (struct terasic_mtl_softc *)adp;
255         terasic_mtl_reg_textcursor_get(sc, &col, &row);
256         *colp = col;
257         *rowp = row;
258         return (0);
259 }
260
261 static int
262 terasic_mtl_vidsw_set_hw_cursor(video_adapter_t *adp, int col, int row)
263 {
264         struct terasic_mtl_softc *sc;
265
266         sc = (struct terasic_mtl_softc *)adp;
267         terasic_mtl_reg_textcursor_set(sc, col, row);
268         return (0);
269 }
270
271 static int
272 terasic_mtl_vidsw_set_hw_cursor_shape(video_adapter_t *adp, int base,
273     int height, int celsize, int blink)
274 {
275
276         printf("%s: not yet\n", __func__);
277         return (ENODEV);
278 }
279
280 static int
281 terasic_mtl_vidsw_blank_display(video_adapter_t *adp, int mode)
282 {
283         struct terasic_mtl_softc *sc;
284
285         sc = (struct terasic_mtl_softc *)adp;
286         terasic_mtl_reg_blank(sc);
287         return (0);
288 }
289
290 static int
291 terasic_mtl_vidsw_mmap(video_adapter_t *adp, vm_ooffset_t offset,
292     vm_paddr_t *paddr, int prot, vm_memattr_t *memattr)
293 {
294
295         printf("%s: not yet\n", __func__);
296         return (ENODEV);
297 }
298
299 static int
300 terasic_mtl_vidsw_ioctl(video_adapter_t *adp, u_long cmd, caddr_t data)
301 {
302
303         return (fb_commonioctl(adp, cmd, data));
304 }
305
306 static int
307 terasic_mtl_vidsw_clear(video_adapter_t *adp)
308 {
309         struct terasic_mtl_softc *sc;
310
311         sc = (struct terasic_mtl_softc *)adp;
312         printf("%s: not yet terasic_mtl_io_clear(sc);\n", __func__);
313         return (0);
314 }
315
316 static int
317 terasic_mtl_vidsw_fill_rect(video_adapter_t *adp, int val, int x, int y,
318     int cx, int cy)
319 {
320
321         printf("%s: not yet\n", __func__);
322         return (ENODEV);
323 }
324
325 static int
326 terasic_mtl_vidsw_bitblt(video_adapter_t *adp, ...)
327 {
328
329         printf("%s: not yet\n", __func__);
330         return (ENODEV);
331 }
332
333 static int
334 terasic_mtl_vidsw_diag(video_adapter_t *adp, int level)
335 {
336
337         printf("%s: not yet\n", __func__);
338         return (ENODEV);
339 }
340
341 static int
342 terasic_mtl_vidsw_save_cursor_palette(video_adapter_t *adp, u_char *palette)
343 {
344
345         printf("%s: not yet\n", __func__);
346         return (ENODEV);
347 }
348
349 static int
350 terasic_mtl_vidsw_load_cursor_palette(video_adapter_t *adp, u_char *palette)
351 {
352
353         printf("%s: not yet\n", __func__);
354         return (ENODEV);
355 }
356
357 static int
358 terasic_mtl_vidsw_copy(video_adapter_t *adp, vm_offset_t src, vm_offset_t dst,
359     int n)
360 {
361
362         printf("%s: not yet\n", __func__);
363         return (ENODEV);
364 }
365
366 static int
367 terasic_mtl_vidsw_putp(video_adapter_t *adp, vm_offset_t off, uint32_t p,
368     uint32_t a, int size, int bpp, int bit_ltor, int byte_ltor)
369 {
370
371         printf("%s: not yet\n", __func__);
372         return (ENODEV);
373 }
374
375 static int
376 terasic_mtl_vidsw_putc(video_adapter_t *adp, vm_offset_t off, uint8_t c,
377     uint8_t a)
378 {
379         struct terasic_mtl_softc *sc;
380         u_int col, row;
381
382         sc = (struct terasic_mtl_softc *)adp;
383         col = (off % adp->va_info.vi_width);
384         row = (off / adp->va_info.vi_width);
385         terasic_mtl_text_putc(sc, col, row, c, a);
386         return (0);
387 }
388
389 static int
390 terasic_mtl_vidsw_puts(video_adapter_t *adp, vm_offset_t off, u_int16_t *s,
391     int len)
392 {
393         int i;
394
395         for (i = 0; i < len; i++)
396                 vidd_putc(adp, off + i, s[i] & 0xff, (s[i] & 0xff00) >> 8);
397         return (0);
398 }
399
400 static int
401 terasic_mtl_vidsw_putm(video_adapter_t *adp, int x, int y,
402     uint8_t *pixel_image, uint32_t pixel_mask, int size, int width)
403 {
404
405         printf("%s: not yet\n", __func__);
406         return (ENODEV);
407 }
408
409 int
410 terasic_mtl_syscons_attach(struct terasic_mtl_softc *sc)
411 {
412         int error;
413
414         sc->mtl_text_soft  =
415             malloc(sizeof(uint16_t) * TERASIC_MTL_ROWS * TERASIC_MTL_COLS,
416             M_TERASIC_MTL, M_WAITOK | M_ZERO);
417         error = terasic_mtl_vidsw_init(0, &sc->mtl_va, 0);
418         if (error)
419                 goto out;
420         error = sc_attach_unit(sc->mtl_unit, device_get_flags(sc->mtl_dev) |
421             SC_AUTODETECT_KBD);
422         if (error)
423                 device_printf(sc->mtl_dev, "%s: sc_attach_unit failed (%d)\n",
424                     __func__, error);
425 out:
426         if (error)
427                 free(sc->mtl_text_soft, M_TERASIC_MTL);
428         return (error);
429 }
430
431 void
432 terasic_mtl_syscons_detach(struct terasic_mtl_softc *sc)
433 {
434
435         free(sc->mtl_text_soft, M_TERASIC_MTL);
436         panic("%s: not supported by syscons", __func__);
437 }
438
439 static video_switch_t terasic_mtl_vidsw = {
440         .probe =                        terasic_mtl_vidsw_probe,
441         .init =                         terasic_mtl_vidsw_init,
442         .get_info =                     terasic_mtl_vidsw_get_info,
443         .query_mode =                   terasic_mtl_vidsw_query_mode,
444         .set_mode =                     terasic_mtl_vidsw_set_mode,
445         .save_font =                    terasic_mtl_vidsw_save_font,
446         .load_font =                    terasic_mtl_vidsw_load_font,
447         .show_font =                    terasic_mtl_vidsw_show_font,
448         .save_palette =                 terasic_mtl_vidsw_save_palette,
449         .load_palette =                 terasic_mtl_vidsw_load_palette,
450         .set_border =                   terasic_mtl_vidsw_set_border,
451         .save_state =                   terasic_mtl_vidsw_save_state,
452         .load_state =                   terasic_mtl_vidsw_load_state,
453         .set_win_org =                  terasic_mtl_vidsw_set_win_org,
454         .read_hw_cursor =               terasic_mtl_vidsw_read_hw_cursor,
455         .set_hw_cursor =                terasic_mtl_vidsw_set_hw_cursor,
456         .set_hw_cursor_shape =          terasic_mtl_vidsw_set_hw_cursor_shape,
457         .blank_display =                terasic_mtl_vidsw_blank_display,
458         .mmap =                         terasic_mtl_vidsw_mmap,
459         .ioctl =                        terasic_mtl_vidsw_ioctl,
460         .clear =                        terasic_mtl_vidsw_clear,
461         .fill_rect =                    terasic_mtl_vidsw_fill_rect,
462         .bitblt =                       terasic_mtl_vidsw_bitblt,
463         .diag =                         terasic_mtl_vidsw_diag,
464         .save_cursor_palette =          terasic_mtl_vidsw_save_cursor_palette,
465         .load_cursor_palette =          terasic_mtl_vidsw_load_cursor_palette,
466         .copy =                         terasic_mtl_vidsw_copy,
467         .putp =                         terasic_mtl_vidsw_putp,
468         .putc =                         terasic_mtl_vidsw_putc,
469         .puts =                         terasic_mtl_vidsw_puts,
470         .putm =                         terasic_mtl_vidsw_putm,
471 };
472 VIDEO_DRIVER(terasic_mtl_syscons, terasic_mtl_vidsw,
473     terasic_mtl_syscons_configure);
474 extern sc_rndr_sw_t txtrndrsw;
475 RENDERER(terasic_mtl_syscons, 0, txtrndrsw, gfb_set);
476 RENDERER_MODULE(terasic_mtl_syscons, gfb_set);