clpslcd.c revision 1.1.4.2 1 1.1.4.2 tls /* $NetBSD: clpslcd.c,v 1.1.4.2 2013/06/23 06:20:00 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: clpslcd.c,v 1.1.4.2 2013/06/23 06:20:00 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 <arm/clps711x/clps711xreg.h>
40 1.1.4.2 tls #include <arm/clps711x/clpssocvar.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 CLPSLCD_DEFAULT_DEPTH 4
50 1.1.4.2 tls
51 1.1.4.2 tls static int is_console;
52 1.1.4.2 tls struct clpslcd_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 clpslcd_match(device_t, cfdata_t, void *);
64 1.1.4.2 tls static void clpslcd_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 clpslcd_ioctl(void *, void *, u_long, void *, int, struct lwp *);
68 1.1.4.2 tls static paddr_t clpslcd_mmap(void *, void *, off_t, int);
69 1.1.4.2 tls static int clpslcd_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 clpslcd_free_screen(void *, void *);
72 1.1.4.2 tls static int clpslcd_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(clpslcd, sizeof(struct clpslcd_softc),
76 1.1.4.2 tls clpslcd_match, clpslcd_attach, NULL, NULL);
77 1.1.4.2 tls
78 1.1.4.2 tls
79 1.1.4.2 tls static struct wsscreen_descr clpslcd_descr = {
80 1.1.4.2 tls .name = "clpslcd",
81 1.1.4.2 tls .fontwidth = 8,
82 1.1.4.2 tls .fontheight = 16,
83 1.1.4.2 tls .capabilities = WSSCREEN_WSCOLORS,
84 1.1.4.2 tls };
85 1.1.4.2 tls static const struct wsscreen_descr *clpslcd_descrs[] = {
86 1.1.4.2 tls &clpslcd_descr
87 1.1.4.2 tls };
88 1.1.4.2 tls
89 1.1.4.2 tls static const struct wsscreen_list clpslcd_screen_list = {
90 1.1.4.2 tls .nscreens = __arraycount(clpslcd_descrs),
91 1.1.4.2 tls .screens = clpslcd_descrs,
92 1.1.4.2 tls };
93 1.1.4.2 tls
94 1.1.4.2 tls struct wsdisplay_accessops clpslcd_accessops = {
95 1.1.4.2 tls clpslcd_ioctl,
96 1.1.4.2 tls clpslcd_mmap,
97 1.1.4.2 tls clpslcd_alloc_screen,
98 1.1.4.2 tls clpslcd_free_screen,
99 1.1.4.2 tls clpslcd_show_screen,
100 1.1.4.2 tls NULL,
101 1.1.4.2 tls NULL,
102 1.1.4.2 tls NULL,
103 1.1.4.2 tls };
104 1.1.4.2 tls
105 1.1.4.2 tls /* ARGSUSED */
106 1.1.4.2 tls static int
107 1.1.4.2 tls clpslcd_match(device_t parent, cfdata_t match, void *aux)
108 1.1.4.2 tls {
109 1.1.4.2 tls
110 1.1.4.2 tls return 1;
111 1.1.4.2 tls }
112 1.1.4.2 tls
113 1.1.4.2 tls /* ARGSUSED */
114 1.1.4.2 tls static void
115 1.1.4.2 tls clpslcd_attach(device_t parent, device_t self, void *aux)
116 1.1.4.2 tls {
117 1.1.4.2 tls struct clpslcd_softc *sc = device_private(self);
118 1.1.4.2 tls struct clpssoc_attach_args *aa = aux;
119 1.1.4.2 tls struct wsemuldisplaydev_attach_args waa;
120 1.1.4.2 tls prop_dictionary_t dict = device_properties(self);
121 1.1.4.2 tls struct rasops_info *ri;
122 1.1.4.2 tls uint32_t syscon, lcdcon, depth, width, height, addr;
123 1.1.4.2 tls int i;
124 1.1.4.2 tls
125 1.1.4.2 tls aprint_naive("\n");
126 1.1.4.2 tls aprint_normal("\n");
127 1.1.4.2 tls
128 1.1.4.2 tls sc->sc_dev = self;
129 1.1.4.2 tls sc->sc_iot = aa->aa_iot;
130 1.1.4.2 tls sc->sc_ioh = *aa->aa_ioh;
131 1.1.4.2 tls
132 1.1.4.2 tls if (!prop_dictionary_get_uint32(dict, "width", &width) ||
133 1.1.4.2 tls !prop_dictionary_get_uint32(dict, "height", &height) ||
134 1.1.4.2 tls !prop_dictionary_get_uint32(dict, "addr", &addr)) {
135 1.1.4.2 tls aprint_error_dev(self, "can't get properties\n");
136 1.1.4.2 tls return;
137 1.1.4.2 tls }
138 1.1.4.2 tls KASSERT(addr == 0xc0000000);
139 1.1.4.2 tls
140 1.1.4.2 tls sc->sc_buffer = addr;
141 1.1.4.2 tls
142 1.1.4.2 tls depth = CLPSLCD_DEFAULT_DEPTH;
143 1.1.4.2 tls lcdcon =
144 1.1.4.2 tls LCDCON_GSEN |
145 1.1.4.2 tls LCDCON_ACP(13) |
146 1.1.4.2 tls LCDCON_PP(width * height) |
147 1.1.4.2 tls LCDCON_LL(width) |
148 1.1.4.2 tls LCDCON_VBS(width * height * depth);
149 1.1.4.2 tls if (depth == 4)
150 1.1.4.2 tls lcdcon |= LCDCON_GSMD;
151 1.1.4.2 tls
152 1.1.4.2 tls syscon = bus_space_read_4(sc->sc_iot, sc->sc_ioh, PS711X_SYSCON);
153 1.1.4.2 tls bus_space_write_4(sc->sc_iot, sc->sc_ioh, PS711X_SYSCON,
154 1.1.4.2 tls syscon | SYSCON_LCDEN);
155 1.1.4.2 tls bus_space_write_4(sc->sc_iot, sc->sc_ioh, PS711X_LCDCON, lcdcon);
156 1.1.4.2 tls bus_space_write_4(sc->sc_iot, sc->sc_ioh, PS711X_PALLSW, 0x54321fc0);
157 1.1.4.2 tls bus_space_write_4(sc->sc_iot, sc->sc_ioh, PS711X_PALMSW, 0xedba9876);
158 1.1.4.2 tls
159 1.1.4.2 tls aprint_normal_dev(self,
160 1.1.4.2 tls ": %dx%d pixels, %d bpp mono\n", width, height, depth);
161 1.1.4.2 tls
162 1.1.4.2 tls ri = &sc->sc_ri;
163 1.1.4.2 tls ri->ri_depth = depth;
164 1.1.4.2 tls ri->ri_bits = (void *)addr;
165 1.1.4.2 tls ri->ri_width = width;
166 1.1.4.2 tls ri->ri_height = height;
167 1.1.4.2 tls ri->ri_stride = width * ri->ri_depth / 8/*bits*/;
168 1.1.4.2 tls ri->ri_flg = RI_FORCEMONO | RI_CLEAR | RI_CENTER;
169 1.1.4.2 tls
170 1.1.4.2 tls if (is_console) {
171 1.1.4.2 tls long defattr;
172 1.1.4.2 tls
173 1.1.4.2 tls if (rasops_init(ri, 0, 0) < 0)
174 1.1.4.2 tls panic("rasops_init failed");
175 1.1.4.2 tls
176 1.1.4.2 tls if (ri->ri_depth == 4) {
177 1.1.4.2 tls /* XXXXX: Create color map. */
178 1.1.4.2 tls ri->ri_devcmap[0] = 0;
179 1.1.4.2 tls for (i = 1; i < 15; i++) {
180 1.1.4.2 tls ri->ri_devcmap[i] =
181 1.1.4.2 tls i | (i << 8) | (i << 16) | (i << 24);
182 1.1.4.2 tls }
183 1.1.4.2 tls }
184 1.1.4.2 tls ri->ri_devcmap[15] = -1;
185 1.1.4.2 tls
186 1.1.4.2 tls clpslcd_descr.ncols = ri->ri_cols;
187 1.1.4.2 tls clpslcd_descr.nrows = ri->ri_rows;
188 1.1.4.2 tls clpslcd_descr.textops = &ri->ri_ops;
189 1.1.4.2 tls clpslcd_descr.capabilities = ri->ri_caps;
190 1.1.4.2 tls
191 1.1.4.2 tls if ((ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr) != 0)
192 1.1.4.2 tls panic("allocattr failed");
193 1.1.4.2 tls wsdisplay_cnattach(&clpslcd_descr, ri, ri->ri_ccol, ri->ri_crow,
194 1.1.4.2 tls defattr);
195 1.1.4.2 tls }
196 1.1.4.2 tls
197 1.1.4.2 tls waa.console = is_console;
198 1.1.4.2 tls waa.scrdata = &clpslcd_screen_list;
199 1.1.4.2 tls waa.accessops = &clpslcd_accessops;
200 1.1.4.2 tls waa.accesscookie = sc;
201 1.1.4.2 tls
202 1.1.4.2 tls config_found(self, &waa, wsemuldisplaydevprint);
203 1.1.4.2 tls }
204 1.1.4.2 tls
205 1.1.4.2 tls static int
206 1.1.4.2 tls clpslcd_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
207 1.1.4.2 tls struct lwp *l)
208 1.1.4.2 tls {
209 1.1.4.2 tls struct clpslcd_softc *sc = v;
210 1.1.4.2 tls struct wsdisplay_fbinfo *wsdisp_info;
211 1.1.4.2 tls
212 1.1.4.2 tls switch (cmd) {
213 1.1.4.2 tls case WSDISPLAYIO_GTYPE:
214 1.1.4.2 tls *(int *)data = WSDISPLAY_TYPE_CLPS711X;
215 1.1.4.2 tls return 0;
216 1.1.4.2 tls
217 1.1.4.2 tls case WSDISPLAYIO_GINFO:
218 1.1.4.2 tls wsdisp_info = (struct wsdisplay_fbinfo *)data;
219 1.1.4.2 tls wsdisp_info->height = sc->sc_ri.ri_height;
220 1.1.4.2 tls wsdisp_info->width = sc->sc_ri.ri_width;
221 1.1.4.2 tls wsdisp_info->depth = sc->sc_ri.ri_depth;
222 1.1.4.2 tls wsdisp_info->cmsize = 0;
223 1.1.4.2 tls return 0;
224 1.1.4.2 tls
225 1.1.4.2 tls case WSDISPLAYIO_GVIDEO:
226 1.1.4.2 tls if (1) /* XXXX */
227 1.1.4.2 tls *(int *)data = WSDISPLAYIO_VIDEO_ON;
228 1.1.4.2 tls else
229 1.1.4.2 tls *(int *)data = WSDISPLAYIO_VIDEO_OFF;
230 1.1.4.2 tls return 0;
231 1.1.4.2 tls
232 1.1.4.2 tls case WSDISPLAYIO_SVIDEO:
233 1.1.4.2 tls if (*(int *)data == WSDISPLAYIO_VIDEO_ON) {
234 1.1.4.2 tls /* XXXX: turn on */
235 1.1.4.2 tls } else {
236 1.1.4.2 tls /* XXXX: turn off */
237 1.1.4.2 tls }
238 1.1.4.2 tls return 0;
239 1.1.4.2 tls
240 1.1.4.2 tls case WSDISPLAYIO_LINEBYTES:
241 1.1.4.2 tls *(int *)data = sc->sc_ri.ri_stride;
242 1.1.4.2 tls return 0;
243 1.1.4.2 tls }
244 1.1.4.2 tls
245 1.1.4.2 tls return EPASSTHROUGH;
246 1.1.4.2 tls }
247 1.1.4.2 tls
248 1.1.4.2 tls static paddr_t
249 1.1.4.2 tls clpslcd_mmap(void *v, void *vs, off_t off, int prot)
250 1.1.4.2 tls {
251 1.1.4.2 tls struct clpslcd_softc *sc = v;
252 1.1.4.2 tls
253 1.1.4.2 tls if (off < 0 || sc->sc_ri.ri_stride * sc->sc_ri.ri_height <= off)
254 1.1.4.2 tls return -1;
255 1.1.4.2 tls
256 1.1.4.2 tls return (paddr_t)sc->sc_ri.ri_bits + off;
257 1.1.4.2 tls }
258 1.1.4.2 tls
259 1.1.4.2 tls static int
260 1.1.4.2 tls clpslcd_alloc_screen(void *v, const struct wsscreen_descr *scr, void **cookiep,
261 1.1.4.2 tls int *curxp, int *curyp, long *attrp)
262 1.1.4.2 tls {
263 1.1.4.2 tls printf("%s\n", __func__);
264 1.1.4.2 tls return -1;
265 1.1.4.2 tls }
266 1.1.4.2 tls
267 1.1.4.2 tls static void
268 1.1.4.2 tls clpslcd_free_screen(void *v, void *cookie)
269 1.1.4.2 tls {
270 1.1.4.2 tls printf("%s\n", __func__);
271 1.1.4.2 tls }
272 1.1.4.2 tls
273 1.1.4.2 tls static int
274 1.1.4.2 tls clpslcd_show_screen(void *v, void *cookie, int waitok,
275 1.1.4.2 tls void (*func)(void *, int, int), void *arg)
276 1.1.4.2 tls {
277 1.1.4.2 tls printf("%s\n", __func__);
278 1.1.4.2 tls return -1;
279 1.1.4.2 tls }
280 1.1.4.2 tls
281 1.1.4.2 tls int
282 1.1.4.2 tls clpslcd_cnattach(void)
283 1.1.4.2 tls {
284 1.1.4.2 tls
285 1.1.4.2 tls is_console = 1;
286 1.1.4.2 tls return 0;
287 1.1.4.2 tls }
288