Home | History | Annotate | Line # | Download | only in windermere
wmlcd.c revision 1.1.4.2
      1  1.1.4.2  tls /*      $NetBSD: wmlcd.c,v 1.1.4.2 2013/06/23 06:20:03 tls Exp $      */
      2  1.1.4.2  tls /*
      3  1.1.4.2  tls  * Copyright (c) 2013 KIYOHARA Takashi
      4  1.1.4.2  tls  * All rights reserved.
      5  1.1.4.2  tls  *
      6  1.1.4.2  tls  * Redistribution and use in source and binary forms, with or without
      7  1.1.4.2  tls  * modification, are permitted provided that the following conditions
      8  1.1.4.2  tls  * are met:
      9  1.1.4.2  tls  * 1. Redistributions of source code must retain the above copyright
     10  1.1.4.2  tls  *    notice, this list of conditions and the following disclaimer.
     11  1.1.4.2  tls  * 2. Redistributions in binary form must reproduce the above copyright
     12  1.1.4.2  tls  *    notice, this list of conditions and the following disclaimer in the
     13  1.1.4.2  tls  *    documentation and/or other materials provided with the distribution.
     14  1.1.4.2  tls  *
     15  1.1.4.2  tls  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     16  1.1.4.2  tls  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     17  1.1.4.2  tls  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     18  1.1.4.2  tls  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
     19  1.1.4.2  tls  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     20  1.1.4.2  tls  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     21  1.1.4.2  tls  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     22  1.1.4.2  tls  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     23  1.1.4.2  tls  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     24  1.1.4.2  tls  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     25  1.1.4.2  tls  * POSSIBILITY OF SUCH DAMAGE.
     26  1.1.4.2  tls  */
     27  1.1.4.2  tls #include <sys/cdefs.h>
     28  1.1.4.2  tls __KERNEL_RCSID(0, "$NetBSD: wmlcd.c,v 1.1.4.2 2013/06/23 06:20:03 tls Exp $");
     29  1.1.4.2  tls 
     30  1.1.4.2  tls #include "rnd.h"
     31  1.1.4.2  tls 
     32  1.1.4.2  tls #include <sys/param.h>
     33  1.1.4.2  tls #include <sys/bus.h>
     34  1.1.4.2  tls #include <sys/device.h>
     35  1.1.4.2  tls #include <sys/errno.h>
     36  1.1.4.2  tls 
     37  1.1.4.2  tls #include <uvm/uvm_extern.h>
     38  1.1.4.2  tls 
     39  1.1.4.2  tls #include <epoc32/windermere/windermerereg.h>
     40  1.1.4.2  tls #include <epoc32/windermere/windermerevar.h>
     41  1.1.4.2  tls 
     42  1.1.4.2  tls #include <dev/cons.h>
     43  1.1.4.2  tls #include <dev/wscons/wsconsio.h>
     44  1.1.4.2  tls #include <dev/wscons/wsdisplayvar.h>
     45  1.1.4.2  tls #include <dev/rasops/rasops.h>
     46  1.1.4.2  tls 
     47  1.1.4.2  tls #include "locators.h"
     48  1.1.4.2  tls 
     49  1.1.4.2  tls #define LCD_SIZE	0x100
     50  1.1.4.2  tls 
     51  1.1.4.2  tls static int is_console;
     52  1.1.4.2  tls struct wmlcd_softc {
     53  1.1.4.2  tls 	device_t sc_dev;
     54  1.1.4.2  tls 
     55  1.1.4.2  tls 	bus_space_tag_t sc_iot;
     56  1.1.4.2  tls 	bus_space_handle_t sc_ioh;
     57  1.1.4.2  tls 
     58  1.1.4.2  tls 	vaddr_t sc_buffer;
     59  1.1.4.2  tls 
     60  1.1.4.2  tls 	struct rasops_info sc_ri;
     61  1.1.4.2  tls };
     62  1.1.4.2  tls 
     63  1.1.4.2  tls static int wmlcd_match(device_t, cfdata_t, void *);
     64  1.1.4.2  tls static void wmlcd_attach(device_t, device_t, void *);
     65  1.1.4.2  tls 
     66  1.1.4.2  tls /* wsdisplay functions */
     67  1.1.4.2  tls static int wmlcd_ioctl(void *, void *, u_long, void *, int, struct lwp *);
     68  1.1.4.2  tls static paddr_t wmlcd_mmap(void *, void *, off_t, int);
     69  1.1.4.2  tls static int wmlcd_alloc_screen(void *, const struct wsscreen_descr *, void **,
     70  1.1.4.2  tls 			      int *, int *, long *);
     71  1.1.4.2  tls static void wmlcd_free_screen(void *, void *);
     72  1.1.4.2  tls static int wmlcd_show_screen(void *, void *, int,
     73  1.1.4.2  tls 			     void (*)(void *, int, int), void *);
     74  1.1.4.2  tls 
     75  1.1.4.2  tls CFATTACH_DECL_NEW(wmlcd, sizeof(struct wmlcd_softc),
     76  1.1.4.2  tls     wmlcd_match, wmlcd_attach, NULL, NULL);
     77  1.1.4.2  tls 
     78  1.1.4.2  tls 
     79  1.1.4.2  tls #define WMLCD_DEFAULT_DEPTH	4
     80  1.1.4.2  tls /* Linux like palette data */
     81  1.1.4.2  tls const static char palette_2bpp[] = {
     82  1.1.4.2  tls 	0x00, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x0f, 0x00,
     83  1.1.4.2  tls 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     84  1.1.4.2  tls 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     85  1.1.4.2  tls 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     86  1.1.4.2  tls };
     87  1.1.4.2  tls const static char palette_4bpp[] = {
     88  1.1.4.2  tls 	0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x07, 0x00,
     89  1.1.4.2  tls 	0x03, 0x00, 0x04, 0x00, 0x06, 0x00, 0x0a, 0x00,
     90  1.1.4.2  tls 	0x05, 0x00, 0x06, 0x00, 0x0b, 0x00, 0x0c, 0x00,
     91  1.1.4.2  tls 	0x08, 0x00, 0x09, 0x00, 0x0e, 0x00, 0x0f, 0x00,
     92  1.1.4.2  tls };
     93  1.1.4.2  tls 
     94  1.1.4.2  tls static struct wsscreen_descr wmlcd_descr = {
     95  1.1.4.2  tls 	.name = "wmlcd",
     96  1.1.4.2  tls 	.fontwidth = 8,
     97  1.1.4.2  tls 	.fontheight = 16,
     98  1.1.4.2  tls 	.capabilities = WSSCREEN_WSCOLORS,
     99  1.1.4.2  tls };
    100  1.1.4.2  tls static const struct wsscreen_descr *wmlcd_descrs[] = {
    101  1.1.4.2  tls 	&wmlcd_descr
    102  1.1.4.2  tls };
    103  1.1.4.2  tls 
    104  1.1.4.2  tls static const struct wsscreen_list wmlcd_screen_list = {
    105  1.1.4.2  tls 	.nscreens = __arraycount(wmlcd_descrs),
    106  1.1.4.2  tls 	.screens = wmlcd_descrs,
    107  1.1.4.2  tls };
    108  1.1.4.2  tls 
    109  1.1.4.2  tls struct wsdisplay_accessops wmlcd_accessops = {
    110  1.1.4.2  tls 	wmlcd_ioctl,
    111  1.1.4.2  tls 	wmlcd_mmap,
    112  1.1.4.2  tls 	wmlcd_alloc_screen,
    113  1.1.4.2  tls 	wmlcd_free_screen,
    114  1.1.4.2  tls 	wmlcd_show_screen,
    115  1.1.4.2  tls 	NULL,
    116  1.1.4.2  tls 	NULL,
    117  1.1.4.2  tls 	NULL,
    118  1.1.4.2  tls };
    119  1.1.4.2  tls 
    120  1.1.4.2  tls /* ARGSUSED */
    121  1.1.4.2  tls static int
    122  1.1.4.2  tls wmlcd_match(device_t parent, cfdata_t match, void *aux)
    123  1.1.4.2  tls {
    124  1.1.4.2  tls 	struct windermere_attach_args *aa = aux;
    125  1.1.4.2  tls 
    126  1.1.4.2  tls 	/* Wildcard not accept */
    127  1.1.4.2  tls 	if (aa->aa_offset == WINDERMERECF_OFFSET_DEFAULT)
    128  1.1.4.2  tls 		return 0;
    129  1.1.4.2  tls 
    130  1.1.4.2  tls 	aa->aa_size = LCD_SIZE;
    131  1.1.4.2  tls 	return 1;
    132  1.1.4.2  tls }
    133  1.1.4.2  tls 
    134  1.1.4.2  tls /* ARGSUSED */
    135  1.1.4.2  tls static void
    136  1.1.4.2  tls wmlcd_attach(device_t parent, device_t self, void *aux)
    137  1.1.4.2  tls {
    138  1.1.4.2  tls 	struct wmlcd_softc *sc = device_private(self);
    139  1.1.4.2  tls 	struct windermere_attach_args *aa = aux;
    140  1.1.4.2  tls 	struct wsemuldisplaydev_attach_args waa;
    141  1.1.4.2  tls 	prop_dictionary_t dict = device_properties(self);
    142  1.1.4.2  tls 	paddr_t paddr;
    143  1.1.4.2  tls 	struct rasops_info *ri;
    144  1.1.4.2  tls 	uint32_t lcdctl, width, height, addr, depth;
    145  1.1.4.2  tls 	int c, i;
    146  1.1.4.2  tls 	const char *palette;
    147  1.1.4.2  tls 
    148  1.1.4.2  tls 	aprint_naive("\n");
    149  1.1.4.2  tls 	aprint_normal("\n");
    150  1.1.4.2  tls 
    151  1.1.4.2  tls 	sc->sc_dev = self;
    152  1.1.4.2  tls 	if (windermere_bus_space_subregion(aa->aa_iot, *aa->aa_ioh,
    153  1.1.4.2  tls 				aa->aa_offset, aa->aa_size, &sc->sc_ioh) != 0) {
    154  1.1.4.2  tls 		aprint_error_dev(self, "can't map registers\n");
    155  1.1.4.2  tls 		return;
    156  1.1.4.2  tls 	}
    157  1.1.4.2  tls 	sc->sc_iot = aa->aa_iot;
    158  1.1.4.2  tls 
    159  1.1.4.2  tls 	if (!prop_dictionary_get_uint32(dict, "width", &width) ||
    160  1.1.4.2  tls 	    !prop_dictionary_get_uint32(dict, "height", &height) ||
    161  1.1.4.2  tls 	    !prop_dictionary_get_uint32(dict, "addr", &addr)) {
    162  1.1.4.2  tls 		aprint_error_dev(self, "can't get properties\n");
    163  1.1.4.2  tls 		return;
    164  1.1.4.2  tls 	}
    165  1.1.4.2  tls 	sc->sc_buffer = addr;
    166  1.1.4.2  tls 	pmap_extract(pmap_kernel(), addr, &paddr);
    167  1.1.4.2  tls 
    168  1.1.4.2  tls 	/* Setup palette data */
    169  1.1.4.2  tls 	depth = WMLCD_DEFAULT_DEPTH;
    170  1.1.4.2  tls 	if (depth == 2)
    171  1.1.4.2  tls 		palette = palette_2bpp;
    172  1.1.4.2  tls 	else
    173  1.1.4.2  tls 		palette = palette_4bpp;
    174  1.1.4.2  tls 	for (i = 0; i < LCD_PALETTE_SIZE; i++)
    175  1.1.4.2  tls 		*((uint8_t *)addr + i) = palette[i];
    176  1.1.4.2  tls 	*(uint16_t *)addr |= (depth >> 1) << 12;
    177  1.1.4.2  tls 
    178  1.1.4.2  tls 	lcdctl = bus_space_read_4(sc->sc_iot, sc->sc_ioh, LCDCTL);
    179  1.1.4.2  tls 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, LCDCTL, lcdctl & ~LCDCTL_EN);
    180  1.1.4.2  tls 
    181  1.1.4.2  tls 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, LCDDBAR1, paddr);
    182  1.1.4.2  tls 
    183  1.1.4.2  tls 	lcdctl = bus_space_read_4(sc->sc_iot, sc->sc_ioh, LCDCTL);
    184  1.1.4.2  tls 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, LCDCTL,
    185  1.1.4.2  tls 	    lcdctl | LCDCTL_EN | LCDCTL_BW);
    186  1.1.4.2  tls 
    187  1.1.4.2  tls 	aprint_normal_dev(self,
    188  1.1.4.2  tls 	    ": %dx%d pixels, %d bpp mono\n", width, height, 1 << depth);
    189  1.1.4.2  tls 
    190  1.1.4.2  tls 	ri = &sc->sc_ri;
    191  1.1.4.2  tls 	ri->ri_depth = depth;
    192  1.1.4.2  tls 	ri->ri_bits = (void *)(addr + LCD_PALETTE_SIZE);
    193  1.1.4.2  tls 	ri->ri_width = width;
    194  1.1.4.2  tls 	ri->ri_height = height;
    195  1.1.4.2  tls 	ri->ri_stride = width * ri->ri_depth / 8/*bits*/;
    196  1.1.4.2  tls 	ri->ri_flg = RI_FORCEMONO | RI_CLEAR | RI_CENTER;
    197  1.1.4.2  tls 
    198  1.1.4.2  tls 	if (is_console) {
    199  1.1.4.2  tls 		long defattr;
    200  1.1.4.2  tls 
    201  1.1.4.2  tls 		if (rasops_init(ri, 0, 0) < 0)
    202  1.1.4.2  tls 			panic("rasops_init failed");
    203  1.1.4.2  tls 
    204  1.1.4.2  tls 		if (ri->ri_depth == 4) {
    205  1.1.4.2  tls 			/* XXXXX: Create color map. */
    206  1.1.4.2  tls 			ri->ri_devcmap[0] = 0;
    207  1.1.4.2  tls 			for (i = 1; i < 15; i++) {
    208  1.1.4.2  tls 				c = (i + 0xc) & 0xf;
    209  1.1.4.2  tls 				ri->ri_devcmap[i] =
    210  1.1.4.2  tls 				    c | (c << 8) | (c << 16) | (c << 24);
    211  1.1.4.2  tls 			}
    212  1.1.4.2  tls 		}
    213  1.1.4.2  tls 		ri->ri_devcmap[15] = -1;
    214  1.1.4.2  tls 
    215  1.1.4.2  tls 		wmlcd_descr.ncols = ri->ri_cols;
    216  1.1.4.2  tls 		wmlcd_descr.nrows = ri->ri_rows;
    217  1.1.4.2  tls 		wmlcd_descr.textops = &ri->ri_ops;
    218  1.1.4.2  tls 		wmlcd_descr.capabilities = ri->ri_caps;
    219  1.1.4.2  tls 
    220  1.1.4.2  tls 		if ((ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr) != 0)
    221  1.1.4.2  tls 			panic("allocattr failed");
    222  1.1.4.2  tls 		wsdisplay_cnattach(&wmlcd_descr, ri, ri->ri_ccol, ri->ri_crow,
    223  1.1.4.2  tls 		    defattr);
    224  1.1.4.2  tls 	}
    225  1.1.4.2  tls 
    226  1.1.4.2  tls 	waa.console = is_console;
    227  1.1.4.2  tls 	waa.scrdata = &wmlcd_screen_list;
    228  1.1.4.2  tls 	waa.accessops = &wmlcd_accessops;
    229  1.1.4.2  tls 	waa.accesscookie = sc;
    230  1.1.4.2  tls 
    231  1.1.4.2  tls 	config_found(self, &waa, wsemuldisplaydevprint);
    232  1.1.4.2  tls }
    233  1.1.4.2  tls 
    234  1.1.4.2  tls static int
    235  1.1.4.2  tls wmlcd_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l)
    236  1.1.4.2  tls {
    237  1.1.4.2  tls 	struct wmlcd_softc *sc = v;
    238  1.1.4.2  tls 	struct wsdisplay_fbinfo *wsdisp_info;
    239  1.1.4.2  tls 
    240  1.1.4.2  tls 	switch (cmd) {
    241  1.1.4.2  tls 	case WSDISPLAYIO_GTYPE:
    242  1.1.4.2  tls 		*(int *)data = WSDISPLAY_TYPE_WINDERMERE;
    243  1.1.4.2  tls 		return 0;
    244  1.1.4.2  tls 
    245  1.1.4.2  tls 	case WSDISPLAYIO_GINFO:
    246  1.1.4.2  tls 		wsdisp_info = (struct wsdisplay_fbinfo *)data;
    247  1.1.4.2  tls 		wsdisp_info->height = sc->sc_ri.ri_height;
    248  1.1.4.2  tls 		wsdisp_info->width = sc->sc_ri.ri_width;
    249  1.1.4.2  tls 		wsdisp_info->depth = sc->sc_ri.ri_depth;
    250  1.1.4.2  tls 		wsdisp_info->cmsize = 0;
    251  1.1.4.2  tls 		return 0;
    252  1.1.4.2  tls 
    253  1.1.4.2  tls 	case WSDISPLAYIO_GVIDEO:
    254  1.1.4.2  tls 		if (1)	/* XXXX */
    255  1.1.4.2  tls 			*(int *)data = WSDISPLAYIO_VIDEO_ON;
    256  1.1.4.2  tls 		else
    257  1.1.4.2  tls 			*(int *)data = WSDISPLAYIO_VIDEO_OFF;
    258  1.1.4.2  tls 		return 0;
    259  1.1.4.2  tls 
    260  1.1.4.2  tls 	case WSDISPLAYIO_SVIDEO:
    261  1.1.4.2  tls 		if (*(int *)data == WSDISPLAYIO_VIDEO_ON) {
    262  1.1.4.2  tls 			/* XXXX: turn on */
    263  1.1.4.2  tls 		} else {
    264  1.1.4.2  tls 			/* XXXX: turn off */
    265  1.1.4.2  tls 		}
    266  1.1.4.2  tls 		return 0;
    267  1.1.4.2  tls 
    268  1.1.4.2  tls 	case WSDISPLAYIO_LINEBYTES:
    269  1.1.4.2  tls 		*(int *)data = sc->sc_ri.ri_stride;
    270  1.1.4.2  tls 		return 0;
    271  1.1.4.2  tls 	}
    272  1.1.4.2  tls 
    273  1.1.4.2  tls 	return EPASSTHROUGH;
    274  1.1.4.2  tls }
    275  1.1.4.2  tls 
    276  1.1.4.2  tls static paddr_t
    277  1.1.4.2  tls wmlcd_mmap(void *v, void *vs, off_t off, int prot)
    278  1.1.4.2  tls {
    279  1.1.4.2  tls 	struct wmlcd_softc *sc = v;
    280  1.1.4.2  tls 
    281  1.1.4.2  tls 	if (off < 0 || sc->sc_ri.ri_stride * sc->sc_ri.ri_height <= off)
    282  1.1.4.2  tls 		return -1;
    283  1.1.4.2  tls 
    284  1.1.4.2  tls 	return (paddr_t)sc->sc_ri.ri_bits + off;
    285  1.1.4.2  tls }
    286  1.1.4.2  tls 
    287  1.1.4.2  tls static int
    288  1.1.4.2  tls wmlcd_alloc_screen(void *v, const struct wsscreen_descr *scr, void **cookiep,
    289  1.1.4.2  tls 		   int *curxp, int *curyp, long *attrp)
    290  1.1.4.2  tls {
    291  1.1.4.2  tls printf("%s\n", __func__);
    292  1.1.4.2  tls return -1;
    293  1.1.4.2  tls }
    294  1.1.4.2  tls 
    295  1.1.4.2  tls static void
    296  1.1.4.2  tls wmlcd_free_screen(void *v, void *cookie)
    297  1.1.4.2  tls {
    298  1.1.4.2  tls printf("%s\n", __func__);
    299  1.1.4.2  tls }
    300  1.1.4.2  tls 
    301  1.1.4.2  tls static int
    302  1.1.4.2  tls wmlcd_show_screen(void *v, void *cookie, int waitok,
    303  1.1.4.2  tls 		  void (*func)(void *, int, int), void *arg)
    304  1.1.4.2  tls {
    305  1.1.4.2  tls printf("%s\n", __func__);
    306  1.1.4.2  tls return -1;
    307  1.1.4.2  tls }
    308  1.1.4.2  tls 
    309  1.1.4.2  tls int
    310  1.1.4.2  tls wmlcd_cnattach(void)
    311  1.1.4.2  tls {
    312  1.1.4.2  tls 
    313  1.1.4.2  tls 	is_console = 1;
    314  1.1.4.2  tls 	return 0;
    315  1.1.4.2  tls }
    316