1/*	$NetBSD: omapfb.c,v 1.2 2011/04/12 18:10:15 ahoka Exp $	*/
2
3/*
4 * Copyright (c) 2010 Michael Lorenz
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28/*
29 * A console driver for OMAP 3530's built-in video controller
30 * tested on beagleboard only so far
31 */
32
33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: omapfb.c,v 1.2 2011/04/12 18:10:15 ahoka Exp $");
35
36#include <sys/param.h>
37#include <sys/systm.h>
38#include <sys/kernel.h>
39#include <sys/device.h>
40#include <sys/malloc.h>
41#include <sys/lwp.h>
42#include <sys/kauth.h>
43
44#include <uvm/uvm_extern.h>
45
46#include <dev/videomode/videomode.h>
47
48#include <sys/bus.h>
49#include <arm/omap/omapfbreg.h>
50#include <arm/omap/omap2_obiovar.h>
51#include <arm/omap/omap2_obioreg.h>
52
53#include <dev/wscons/wsdisplayvar.h>
54#include <dev/wscons/wsconsio.h>
55#include <dev/wsfont/wsfont.h>
56#include <dev/rasops/rasops.h>
57#include <dev/wscons/wsdisplay_vconsvar.h>
58
59struct omapfb_softc {
60	device_t sc_dev;
61
62	bus_space_tag_t sc_iot;
63	bus_dma_tag_t sc_dmat;
64	bus_space_handle_t sc_regh;
65	bus_dmamap_t sc_dmamap;
66	bus_dma_segment_t sc_dmamem[1];
67	size_t sc_vramsize;
68
69	int sc_width, sc_height, sc_depth, sc_stride;
70	int sc_locked;
71	void *sc_fbaddr, *sc_vramaddr;
72	uint32_t *sc_clut;
73	struct vcons_screen sc_console_screen;
74	struct wsscreen_descr sc_defaultscreen_descr;
75	const struct wsscreen_descr *sc_screens[1];
76	struct wsscreen_list sc_screenlist;
77	struct vcons_data vd;
78	int sc_mode;
79	uint8_t sc_cmap_red[256], sc_cmap_green[256], sc_cmap_blue[256];
80};
81
82static int	omapfb_match(device_t, cfdata_t, void *);
83static void	omapfb_attach(device_t, device_t, void *);
84
85CFATTACH_DECL_NEW(omapfb, sizeof(struct omapfb_softc),
86    omapfb_match, omapfb_attach, NULL, NULL);
87
88static int	omapfb_ioctl(void *, void *, u_long, void *, int,
89			     struct lwp *);
90static paddr_t	omapfb_mmap(void *, void *, off_t, int);
91static void	omapfb_init_screen(void *, struct vcons_screen *, int, long *);
92
93static void	omapfb_init(struct omapfb_softc *);
94
95static int	omapfb_putcmap(struct omapfb_softc *, struct wsdisplay_cmap *);
96static int 	omapfb_getcmap(struct omapfb_softc *, struct wsdisplay_cmap *);
97static void	omapfb_restore_palette(struct omapfb_softc *);
98static void 	omapfb_putpalreg(struct omapfb_softc *, int, uint8_t,
99			    uint8_t, uint8_t);
100
101#if 0
102static void	omapfb_flush_engine(struct omapfb_softc *);
103static void	omapfb_rectfill(struct omapfb_softc *, int, int, int, int,
104			    uint32_t);
105static void	omapfb_bitblt(struct omapfb_softc *, int, int, int, int, int,
106			    int, int);
107
108static void	omapfb_cursor(void *, int, int, int);
109static void	omapfb_putchar(void *, int, int, u_int, long);
110static void	omapfb_copycols(void *, int, int, int, int);
111static void	omapfb_erasecols(void *, int, int, int, long);
112static void	omapfb_copyrows(void *, int, int, int);
113static void	omapfb_eraserows(void *, int, int, long);
114#endif
115
116struct wsdisplay_accessops omapfb_accessops = {
117	omapfb_ioctl,
118	omapfb_mmap,
119	NULL,	/* alloc_screen */
120	NULL,	/* free_screen */
121	NULL,	/* show_screen */
122	NULL, 	/* load_font */
123	NULL,	/* pollc */
124	NULL	/* scroll */
125};
126
127uint32_t venc_mode_ntsc[] = {
128	0x00000000, 0x00000001, 0x00008040, 0x00000359,
129	0x0000020c, 0x00000000, 0x043f2631, 0x00000000,
130	0x00000102, 0x0000016c, 0x0000012f, 0x00000043,
131	0x00000038, 0x00000007, 0x00000001, 0x00000038,
132	0x21f07c1f, 0x00000000, 0x01310011, 0x0000f003,
133	0x00000000, 0x069300f4, 0x0016020c, 0x00060107,
134	0x008e0350, 0x000f0359, 0x01a00000, 0x020701a0,
135	0x01ac0024, 0x020d01ac, 0x00000006, 0x03480078,
136	0x02060024, 0x0001008a, 0x01ac0106, 0x01060006,
137	0x00140001, 0x00010001, 0x00f90000, 0x0000000d,
138	0x00000000};
139
140extern const u_char rasops_cmap[768];
141
142static int
143omapfb_match(device_t parent, cfdata_t match, void *aux)
144{
145	struct obio_attach_args *obio = aux;
146
147	if ((obio->obio_addr == -1) || (obio->obio_size == 0))
148		return 0;
149	return 1;
150}
151
152static void
153omapfb_attach(device_t parent, device_t self, void *aux)
154{
155	struct omapfb_softc	*sc = device_private(self);
156	struct obio_attach_args *obio = aux;
157	struct rasops_info	*ri;
158	struct wsemuldisplaydev_attach_args aa;
159	prop_dictionary_t	dict;
160	unsigned long		defattr;
161	bool			is_console;
162	uint32_t		sz, reg;
163	int			segs, i, j, adr;
164
165	sc->sc_iot = obio->obio_iot;
166	sc->sc_dev = self;
167	sc->sc_dmat = obio->obio_dmat;
168
169	printf(": OMAP onboard video\n");
170	if (bus_space_map(obio->obio_iot, obio->obio_addr, obio->obio_size, 0,
171	    &sc->sc_regh)) {
172		aprint_error(": couldn't map register space\n");
173		return;
174	}
175
176	sz = bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_SIZE);
177	sc->sc_width = (sz & 0xfff) + 1;
178	sc->sc_height = ((sz & 0x0fff0000 ) >> 16) + 1;
179	sc->sc_depth = 16;
180	sc->sc_stride = sc->sc_width << 1;
181
182	if (sc->sc_width == 1 || sc->sc_height == 1) {
183		aprint_error_dev(self, "bogus display size, not attaching\n");
184		return;
185	}
186
187	printf("%s: firmware set up %d x %d\n", device_xname(self),
188	    sc->sc_width, sc->sc_height);
189#if 0
190	printf("DSS revision: %08x\n",
191	    bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DSS_REVISION));
192#endif
193	dict = device_properties(self);
194	prop_dictionary_get_bool(dict, "is_console", &is_console);
195	is_console = 1;
196
197	/* setup video DMA */
198	sc->sc_vramsize = (12 << 20) + 0x1000; /* 12MB + CLUT */
199
200	if (bus_dmamem_alloc(sc->sc_dmat, sc->sc_vramsize, 0, 0,
201	    sc->sc_dmamem, 1, &segs, BUS_DMA_NOWAIT) != 0) {
202		panic("boo!\n");
203		aprint_error_dev(sc->sc_dev,
204		"failed to allocate video memory\n");
205		return;
206	}
207
208	if (bus_dmamem_map(sc->sc_dmat, sc->sc_dmamem, 1, sc->sc_vramsize,
209	    &sc->sc_vramaddr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT) != 0) {
210		aprint_error_dev(sc->sc_dev, "failed to map video RAM\n");
211		return;
212	}
213	sc->sc_fbaddr = (uint8_t *)sc->sc_vramaddr + 0x1000;
214	sc->sc_clut = sc->sc_vramaddr;
215
216	if (bus_dmamap_create(sc->sc_dmat, sc->sc_vramsize, 1, sc->sc_vramsize,
217	    0, BUS_DMA_NOWAIT, &sc->sc_dmamap) != 0) {
218		aprint_error_dev(sc->sc_dev, "failed to create DMA map\n");
219		return;
220	}
221
222	if (bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, sc->sc_vramaddr,
223	    sc->sc_vramsize, NULL, BUS_DMA_NOWAIT) != 0) {
224		aprint_error_dev(sc->sc_dev, "failed to load DMA map\n");
225		return;
226	}
227
228	if (sc->sc_depth == 8) {
229		j = 0;
230		for (i = 0; i < 256; i++) {
231			sc->sc_cmap_red[i] = rasops_cmap[j];
232			sc->sc_cmap_green[i] = rasops_cmap[j + 1];
233			sc->sc_cmap_blue[i] = rasops_cmap[j + 2];
234			j += 3;
235		}
236	} else {
237		for (i = 0; i < 256; i++) {
238			sc->sc_cmap_red[i] = i;
239			sc->sc_cmap_green[i] = i;
240			sc->sc_cmap_blue[i] = i;
241		}
242	}
243	omapfb_restore_palette(sc);
244
245	/* now that we have video memory, stick it to the video controller */
246
247	reg = bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_SYSCONFIG);
248	reg &= ~(OMAP_DISPC_SYSC_STANDBY_MASK | OMAP_DISPC_SYSC_IDLE_MASK);
249	reg |= OMAP_DISPC_SYSC_SMART_STANDBY | OMAP_DISPC_SYSC_SMART_IDLE |
250	       OMAP_DISPC_SYSC_WAKEUP_ENABLE | OMAP_SYSCONF_AUTOIDLE;
251	bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_SYSCONFIG, reg);
252
253	bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DSS_SYSCONFIG,
254	    OMAP_SYSCONF_AUTOIDLE);
255	reg = bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONFIG);
256	reg = 0x8;
257	bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONFIG, reg);
258
259	bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_BASE_0,
260	    sc->sc_dmamem->ds_addr + 0x1000);
261	bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_TABLE_BASE,
262	    sc->sc_dmamem->ds_addr);
263	bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_POSITION,
264	    0);
265	bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_PRELOAD, 0x60);
266	bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_ATTRIBUTES,
267	    OMAP_DISPC_ATTR_ENABLE |
268	    OMAP_DISPC_ATTR_BURST_16x32 |
269	    /*OMAP_DISPC_ATTR_8BIT*/OMAP_DISPC_ATTR_RGB16
270	    | OMAP_DISPC_ATTR_REPLICATION);
271#if 0
272	printf("dss_control: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DSS_CONTROL));
273	bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DSS_CONTROL,
274	    /*OMAP_DSSCTRL_DISPC_CLK_SWITCH |*/
275	    OMAP_DSSCTRL_CLOCK_MODE |
276	    OMAP_DSSCTRL_VENC_CLOCK_4X |
277	    OMAP_DSSCTRL_DAC_DEMEN);
278#endif
279
280	/* VENC to NTSC mode */
281	adr = OMAPFB_VENC_F_CONTROL;
282#if 0
283	for (i = 0; i < __arraycount(venc_mode_ntsc); i++) {
284		bus_space_write_4(sc->sc_iot, sc->sc_regh, adr,
285		    venc_mode_ntsc[i]);
286		adr += 4;
287	}
288	bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_VENC_F_CONTROL,
289		    venc_mode_ntsc[0]);
290	bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_VENC_SYNC_CTRL,
291		    venc_mode_ntsc[2]);
292
293	bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_DEFAULT_COLOR_1,
294	    0x00ff0000);
295#endif
296	reg = bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONTROL);
297	bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONTROL,
298	    reg | OMAP_DISPC_CTRL_GO_LCD);
299
300#ifdef OMAPFB_DEBUG
301	printf("attr: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_ATTRIBUTES));
302	printf("preload: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_PRELOAD));
303	printf("config: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONFIG));
304	printf("control: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONTROL));
305	printf("dss_control: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DSS_CONTROL));
306	printf("threshold: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_FIFO_THRESH));
307	printf("GFX size: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_SIZE));
308	printf("row inc: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_ROW_INC));
309	printf("pixel inc: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_PIXEL_INC));
310#endif
311
312	sc->sc_defaultscreen_descr = (struct wsscreen_descr){
313		"default",
314		0, 0,
315		NULL,
316		8, 16,
317		WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
318		NULL
319	};
320	sc->sc_screens[0] = &sc->sc_defaultscreen_descr;
321	sc->sc_screenlist = (struct wsscreen_list){1, sc->sc_screens};
322	sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
323	sc->sc_locked = 0;
324
325	vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr,
326	    &omapfb_accessops);
327	sc->vd.init_screen = omapfb_init_screen;
328
329	/* init engine here */
330	omapfb_init(sc);
331
332	ri = &sc->sc_console_screen.scr_ri;
333
334	if (is_console) {
335		vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1,
336		    &defattr);
337		sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
338
339#if 0
340		omapfb_rectfill(sc, 0, 0, sc->sc_width, sc->sc_height,
341		    ri->ri_devcmap[(defattr >> 16) & 0xff]);
342#endif
343		sc->sc_defaultscreen_descr.textops = &ri->ri_ops;
344		sc->sc_defaultscreen_descr.capabilities = ri->ri_caps;
345		sc->sc_defaultscreen_descr.nrows = ri->ri_rows;
346		sc->sc_defaultscreen_descr.ncols = ri->ri_cols;
347		wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0,
348		    defattr);
349		vcons_replay_msgbuf(&sc->sc_console_screen);
350	} else {
351		/*
352		 * since we're not the console we can postpone the rest
353		 * until someone actually allocates a screen for us
354		 */
355		(*ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr);
356	}
357
358	aa.console = is_console;
359	aa.scrdata = &sc->sc_screenlist;
360	aa.accessops = &omapfb_accessops;
361	aa.accesscookie = &sc->vd;
362
363	config_found(sc->sc_dev, &aa, wsemuldisplaydevprint);
364
365}
366
367static int
368omapfb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
369	struct lwp *l)
370{
371	struct vcons_data *vd = v;
372	struct omapfb_softc *sc = vd->cookie;
373	struct wsdisplay_fbinfo *wdf;
374	struct vcons_screen *ms = vd->active;
375
376	switch (cmd) {
377
378		case WSDISPLAYIO_GTYPE:
379			*(u_int *)data = WSDISPLAY_TYPE_PCIMISC;
380			return 0;
381
382		case WSDISPLAYIO_GINFO:
383			if (ms == NULL)
384				return ENODEV;
385			wdf = (void *)data;
386			wdf->height = ms->scr_ri.ri_height;
387			wdf->width = ms->scr_ri.ri_width;
388			wdf->depth = ms->scr_ri.ri_depth;
389			wdf->cmsize = 256;
390			return 0;
391
392		case WSDISPLAYIO_GETCMAP:
393			return omapfb_getcmap(sc,
394			    (struct wsdisplay_cmap *)data);
395
396		case WSDISPLAYIO_PUTCMAP:
397			return omapfb_putcmap(sc,
398			    (struct wsdisplay_cmap *)data);
399
400		case WSDISPLAYIO_LINEBYTES:
401			*(u_int *)data = sc->sc_stride;
402			return 0;
403
404		case WSDISPLAYIO_SMODE:
405			{
406				int new_mode = *(int*)data;
407
408				/* notify the bus backend */
409				if (new_mode != sc->sc_mode) {
410					sc->sc_mode = new_mode;
411					if(new_mode == WSDISPLAYIO_MODE_EMUL) {
412						vcons_redraw_screen(ms);
413					}
414				}
415			}
416			return 0;
417	}
418	return EPASSTHROUGH;
419}
420
421static paddr_t
422omapfb_mmap(void *v, void *vs, off_t offset, int prot)
423{
424	paddr_t pa = -1;
425#if 0
426	struct vcons_data *vd = v;
427	struct omapfb_softc *sc = vd->cookie;
428
429	/* 'regular' framebuffer mmap()ing */
430	if (offset < sc->sc_fbsize) {
431		pa = bus_space_mmap(sc->sc_memt, sc->sc_fb + offset, 0, prot,
432		    BUS_SPACE_MAP_LINEAR);
433		return pa;
434	}
435#endif
436	return pa;
437}
438
439static void
440omapfb_init_screen(void *cookie, struct vcons_screen *scr,
441    int existing, long *defattr)
442{
443	struct omapfb_softc *sc = cookie;
444	struct rasops_info *ri = &scr->scr_ri;
445
446	ri->ri_depth = sc->sc_depth;
447	ri->ri_width = sc->sc_width;
448	ri->ri_height = sc->sc_height;
449	ri->ri_stride = sc->sc_stride;
450	ri->ri_flg = RI_CENTER | RI_FULLCLEAR;
451
452	ri->ri_bits = (char *)sc->sc_fbaddr;
453
454	scr->scr_flags |= VCONS_DONT_READ;
455
456	if (existing) {
457		ri->ri_flg |= RI_CLEAR;
458	}
459
460	rasops_init(ri, sc->sc_height / 8, sc->sc_width / 8);
461	ri->ri_caps = WSSCREEN_WSCOLORS;
462
463	rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight,
464		    sc->sc_width / ri->ri_font->fontwidth);
465
466	ri->ri_hw = scr;
467#if 0
468	ri->ri_ops.copyrows = omapfb_copyrows;
469	ri->ri_ops.copycols = omapfb_copycols;
470	ri->ri_ops.eraserows = omapfb_eraserows;
471	ri->ri_ops.erasecols = omapfb_erasecols;
472	ri->ri_ops.cursor = omapfb_cursor;
473	ri->ri_ops.putchar = omapfb_putchar;
474#endif
475}
476
477static int
478omapfb_putcmap(struct omapfb_softc *sc, struct wsdisplay_cmap *cm)
479{
480	u_char *r, *g, *b;
481	u_int index = cm->index;
482	u_int count = cm->count;
483	int i, error;
484	u_char rbuf[256], gbuf[256], bbuf[256];
485
486	if (cm->index >= 256 || cm->count > 256 ||
487	    (cm->index + cm->count) > 256)
488		return EINVAL;
489	error = copyin(cm->red, &rbuf[index], count);
490	if (error)
491		return error;
492	error = copyin(cm->green, &gbuf[index], count);
493	if (error)
494		return error;
495	error = copyin(cm->blue, &bbuf[index], count);
496	if (error)
497		return error;
498
499	memcpy(&sc->sc_cmap_red[index], &rbuf[index], count);
500	memcpy(&sc->sc_cmap_green[index], &gbuf[index], count);
501	memcpy(&sc->sc_cmap_blue[index], &bbuf[index], count);
502
503	r = &sc->sc_cmap_red[index];
504	g = &sc->sc_cmap_green[index];
505	b = &sc->sc_cmap_blue[index];
506
507	for (i = 0; i < count; i++) {
508		omapfb_putpalreg(sc, index, *r, *g, *b);
509		index++;
510		r++, g++, b++;
511	}
512	return 0;
513}
514
515static int
516omapfb_getcmap(struct omapfb_softc *sc, struct wsdisplay_cmap *cm)
517{
518	u_int index = cm->index;
519	u_int count = cm->count;
520	int error;
521
522	if (index >= 255 || count > 256 || index + count > 256)
523		return EINVAL;
524
525	error = copyout(&sc->sc_cmap_red[index],   cm->red,   count);
526	if (error)
527		return error;
528	error = copyout(&sc->sc_cmap_green[index], cm->green, count);
529	if (error)
530		return error;
531	error = copyout(&sc->sc_cmap_blue[index],  cm->blue,  count);
532	if (error)
533		return error;
534
535	return 0;
536}
537
538static void
539omapfb_restore_palette(struct omapfb_softc *sc)
540{
541	int i;
542
543	for (i = 0; i < (1 << sc->sc_depth); i++) {
544		omapfb_putpalreg(sc, i, sc->sc_cmap_red[i],
545		    sc->sc_cmap_green[i], sc->sc_cmap_blue[i]);
546	}
547}
548
549static void
550omapfb_putpalreg(struct omapfb_softc *sc, int idx, uint8_t r, uint8_t g,
551    uint8_t b)
552{
553	uint32_t reg;
554
555	if ((idx < 0) || (idx > 255))
556		return;
557	/* whack the DAC */
558	reg = (r << 16) | (g << 8) | b;
559	sc->sc_clut[idx] = reg;
560
561}
562
563static void
564omapfb_init(struct omapfb_softc *sc)
565{
566}
567
568#if 0
569static void
570omapfb_rectfill(struct omapfb_softc *sc, int x, int y, int wi, int he,
571     uint32_t colour)
572{
573}
574
575static void
576omapfb_bitblt(struct omapfb_softc *sc, int xs, int ys, int xd, int yd,
577    int wi, int he, int rop)
578{
579}
580
581static void
582omapfb_cursor(void *cookie, int on, int row, int col)
583{
584	struct rasops_info *ri = cookie;
585	struct vcons_screen *scr = ri->ri_hw;
586	struct omapfb_softc *sc = scr->scr_cookie;
587	int x, y, wi, he;
588
589	wi = ri->ri_font->fontwidth;
590	he = ri->ri_font->fontheight;
591
592	if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
593		x = ri->ri_ccol * wi + ri->ri_xorigin;
594		y = ri->ri_crow * he + ri->ri_yorigin;
595		if (ri->ri_flg & RI_CURSOR) {
596			omapfb_bitblt(sc, x, y, x, y, wi, he, 3);
597			ri->ri_flg &= ~RI_CURSOR;
598		}
599		ri->ri_crow = row;
600		ri->ri_ccol = col;
601		if (on) {
602			x = ri->ri_ccol * wi + ri->ri_xorigin;
603			y = ri->ri_crow * he + ri->ri_yorigin;
604			omapfb_bitblt(sc, x, y, x, y, wi, he, 3);
605			ri->ri_flg |= RI_CURSOR;
606		}
607	} else {
608		scr->scr_ri.ri_crow = row;
609		scr->scr_ri.ri_ccol = col;
610		scr->scr_ri.ri_flg &= ~RI_CURSOR;
611	}
612
613}
614
615#if 0
616static void
617omapfb_putchar(void *cookie, int row, int col, u_int c, long attr)
618{
619}
620#endif
621
622static void
623omapfb_copycols(void *cookie, int row, int srccol, int dstcol, int ncols)
624{
625	struct rasops_info *ri = cookie;
626	struct vcons_screen *scr = ri->ri_hw;
627	struct omapfb_softc *sc = scr->scr_cookie;
628	int32_t xs, xd, y, width, height;
629
630	if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) {
631		xs = ri->ri_xorigin + ri->ri_font->fontwidth * srccol;
632		xd = ri->ri_xorigin + ri->ri_font->fontwidth * dstcol;
633		y = ri->ri_yorigin + ri->ri_font->fontheight * row;
634		width = ri->ri_font->fontwidth * ncols;
635		height = ri->ri_font->fontheight;
636		omapfb_bitblt(sc, xs, y, xd, y, width, height, 12);
637	}
638}
639
640static void
641omapfb_erasecols(void *cookie, int row, int startcol, int ncols, long fillattr)
642{
643	struct rasops_info *ri = cookie;
644	struct vcons_screen *scr = ri->ri_hw;
645	struct omapfb_softc *sc = scr->scr_cookie;
646	int32_t x, y, width, height, fg, bg, ul;
647
648	if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) {
649		x = ri->ri_xorigin + ri->ri_font->fontwidth * startcol;
650		y = ri->ri_yorigin + ri->ri_font->fontheight * row;
651		width = ri->ri_font->fontwidth * ncols;
652		height = ri->ri_font->fontheight;
653		rasops_unpack_attr(fillattr, &fg, &bg, &ul);
654
655		omapfb_rectfill(sc, x, y, width, height, ri->ri_devcmap[bg]);
656	}
657}
658
659static void
660omapfb_copyrows(void *cookie, int srcrow, int dstrow, int nrows)
661{
662	struct rasops_info *ri = cookie;
663	struct vcons_screen *scr = ri->ri_hw;
664	struct omapfb_softc *sc = scr->scr_cookie;
665	int32_t x, ys, yd, width, height;
666
667	if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) {
668		x = ri->ri_xorigin;
669		ys = ri->ri_yorigin + ri->ri_font->fontheight * srcrow;
670		yd = ri->ri_yorigin + ri->ri_font->fontheight * dstrow;
671		width = ri->ri_emuwidth;
672		height = ri->ri_font->fontheight*nrows;
673		omapfb_bitblt(sc, x, ys, x, yd, width, height, 12);
674	}
675}
676
677static void
678omapfb_eraserows(void *cookie, int row, int nrows, long fillattr)
679{
680	struct rasops_info *ri = cookie;
681	struct vcons_screen *scr = ri->ri_hw;
682	struct omapfb_softc *sc = scr->scr_cookie;
683	int32_t x, y, width, height, fg, bg, ul;
684
685	if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) {
686		x = ri->ri_xorigin;
687		y = ri->ri_yorigin + ri->ri_font->fontheight * row;
688		width = ri->ri_emuwidth;
689		height = ri->ri_font->fontheight * nrows;
690		rasops_unpack_attr(fillattr, &fg, &bg, &ul);
691
692		omapfb_rectfill(sc, x, y, width, height, ri->ri_devcmap[bg]);
693	}
694}
695#endif
696