1*355a2878Srin /* $NetBSD: grf_obio.c,v 1.59 2019/07/26 10:48:44 rin Exp $ */
259b4da2bSbriggs
359b4da2bSbriggs /*
463526c1fSscottr * Copyright (C) 1998 Scott Reynolds
563526c1fSscottr * All rights reserved.
663526c1fSscottr *
763526c1fSscottr * Redistribution and use in source and binary forms, with or without
863526c1fSscottr * modification, are permitted provided that the following conditions
963526c1fSscottr * are met:
1063526c1fSscottr * 1. Redistributions of source code must retain the above copyright
1163526c1fSscottr * notice, this list of conditions and the following disclaimer.
1263526c1fSscottr * 2. Redistributions in binary form must reproduce the above copyright
1363526c1fSscottr * notice, this list of conditions and the following disclaimer in the
1463526c1fSscottr * documentation and/or other materials provided with the distribution.
1563526c1fSscottr * 3. The name of the author may not be used to endorse or promote products
1663526c1fSscottr * derived from this software without specific prior written permission.
1763526c1fSscottr *
1863526c1fSscottr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1963526c1fSscottr * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2063526c1fSscottr * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2163526c1fSscottr * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2263526c1fSscottr * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2363526c1fSscottr * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2463526c1fSscottr * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2563526c1fSscottr * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2663526c1fSscottr * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2763526c1fSscottr * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2863526c1fSscottr */
2963526c1fSscottr /*
3059b4da2bSbriggs * Copyright (c) 1995 Allen Briggs. All rights reserved.
3159b4da2bSbriggs *
3259b4da2bSbriggs * Redistribution and use in source and binary forms, with or without
3359b4da2bSbriggs * modification, are permitted provided that the following conditions
3459b4da2bSbriggs * are met:
3559b4da2bSbriggs * 1. Redistributions of source code must retain the above copyright
3659b4da2bSbriggs * notice, this list of conditions and the following disclaimer.
3759b4da2bSbriggs * 2. Redistributions in binary form must reproduce the above copyright
3859b4da2bSbriggs * notice, this list of conditions and the following disclaimer in the
3959b4da2bSbriggs * documentation and/or other materials provided with the distribution.
4059b4da2bSbriggs * 3. All advertising materials mentioning features or use of this software
4159b4da2bSbriggs * must display the following acknowledgement:
4259b4da2bSbriggs * This product includes software developed by Allen Briggs.
4359b4da2bSbriggs * 4. The name of the author may not be used to endorse or promote products
4459b4da2bSbriggs * derived from this software without specific prior written permission.
4559b4da2bSbriggs *
4659b4da2bSbriggs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
4759b4da2bSbriggs * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
4859b4da2bSbriggs * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
4959b4da2bSbriggs * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
5059b4da2bSbriggs * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
5159b4da2bSbriggs * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
5259b4da2bSbriggs * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
5359b4da2bSbriggs * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
5459b4da2bSbriggs * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
5559b4da2bSbriggs * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5659b4da2bSbriggs */
5759b4da2bSbriggs /*
5859b4da2bSbriggs * Graphics display driver for the Macintosh internal video for machines
5959b4da2bSbriggs * that don't map it into a fake nubus card.
6059b4da2bSbriggs */
6159b4da2bSbriggs
624b2744bfSlukem #include <sys/cdefs.h>
63*355a2878Srin __KERNEL_RCSID(0, "$NetBSD: grf_obio.c,v 1.59 2019/07/26 10:48:44 rin Exp $");
644b2744bfSlukem
6559b4da2bSbriggs #include <sys/param.h>
6659b4da2bSbriggs #include <sys/device.h>
6759b4da2bSbriggs #include <sys/ioctl.h>
68*355a2878Srin #include <sys/kmem.h>
6959b4da2bSbriggs #include <sys/file.h>
7059b4da2bSbriggs #include <sys/mman.h>
7159b4da2bSbriggs #include <sys/proc.h>
7237163421Sbriggs #include <sys/systm.h>
7359b4da2bSbriggs
74a3d5b326Sbriggs #include <machine/autoconf.h>
75b1e59123Sscottr #include <machine/bus.h>
7659b4da2bSbriggs #include <machine/cpu.h>
77b1e59123Sscottr #include <machine/grfioctl.h>
78a3d5b326Sbriggs #include <machine/viareg.h>
7992203533Sjmmv #include <machine/video.h>
8059b4da2bSbriggs
819dfbdab6Sscottr #include <mac68k/nubus/nubus.h>
82*355a2878Srin #include <mac68k/obio/grf_obioreg.h>
839dfbdab6Sscottr #include <mac68k/obio/obiovar.h>
84e083a60aSscottr #include <mac68k/dev/grfvar.h>
8559b4da2bSbriggs
867acd68b1Schs static int grfiv_mode(struct grf_softc *, int, void *);
87cbab9cadSchs static int grfiv_match(device_t, cfdata_t, void *);
88cbab9cadSchs static void grfiv_attach(device_t, device_t, void *);
8937163421Sbriggs
90*355a2878Srin static void dafb_set_mapreg(void *, int, int, int, int);
91*355a2878Srin static void civic_set_mapreg(void *, int, int, int, int);
92*355a2878Srin static void valkyrie_set_mapreg(void *, int, int, int, int);
93*355a2878Srin static void rbv_set_mapreg(void *, int, int, int, int);
94*355a2878Srin
95cbab9cadSchs CFATTACH_DECL_NEW(intvid, sizeof(struct grfbus_softc),
96c5e91d44Sthorpej grfiv_match, grfiv_attach, NULL, NULL);
9737163421Sbriggs
9837163421Sbriggs static int
grfiv_match(device_t parent,cfdata_t cf,void * aux)99cbab9cadSchs grfiv_match(device_t parent, cfdata_t cf, void *aux)
10059b4da2bSbriggs {
101a3d5b326Sbriggs struct obio_attach_args *oa = (struct obio_attach_args *)aux;
102a3d5b326Sbriggs bus_space_handle_t bsh;
10352da0e26Sscottr int found;
104527e5cbcSbriggs u_int base;
10559b4da2bSbriggs
106a3d5b326Sbriggs found = 1;
107a3d5b326Sbriggs
108a3d5b326Sbriggs switch (current_mac_model->class) {
10963526c1fSscottr case MACH_CLASSQ2:
11063526c1fSscottr if (current_mac_model->machineid != MACH_MACLC575) {
11163526c1fSscottr base = VALKYRIE_CONTROL_BASE;
11263526c1fSscottr
11363526c1fSscottr if (bus_space_map(oa->oa_tag, base, 0x40, 0, &bsh))
11463526c1fSscottr return 0;
11563526c1fSscottr
11663526c1fSscottr /* Disable interrupts */
11763526c1fSscottr bus_space_write_1(oa->oa_tag, bsh, 0x18, 0x1);
118fc6d3c5fSscottr
119fc6d3c5fSscottr bus_space_unmap(oa->oa_tag, bsh, 0x40);
120b27d1061Sscottr break;
12163526c1fSscottr }
12263526c1fSscottr /*
12363526c1fSscottr * Note: the only system in this class that does not have
12463526c1fSscottr * the Valkyrie chip -- at least, that we know of -- is
12563526c1fSscottr * the Performa/LC 57x series. This system has a version
12663526c1fSscottr * of the DAFB controller, instead.
12763526c1fSscottr *
12863526c1fSscottr * If this assumption proves false, we'll have to be more
12963526c1fSscottr * intelligent here.
13063526c1fSscottr */
13163526c1fSscottr /*FALLTHROUGH*/
132a3d5b326Sbriggs case MACH_CLASSQ:
133fc43576eSbriggs /*
134fc43576eSbriggs * Assume DAFB for all of these, unless we can't
135fc43576eSbriggs * access the memory.
136fc43576eSbriggs */
13763526c1fSscottr base = DAFB_CONTROL_BASE;
138a3d5b326Sbriggs
139b21b6272Sscottr if (bus_space_map(oa->oa_tag, base, 0x20, 0, &bsh))
14063526c1fSscottr return 0;
141ff5fa674Sbriggs
14263526c1fSscottr if (mac68k_bus_space_probe(oa->oa_tag, bsh, 0x1c, 4) == 0) {
143b21b6272Sscottr bus_space_unmap(oa->oa_tag, bsh, 0x20);
14463526c1fSscottr return 0;
145fc43576eSbriggs }
146fc43576eSbriggs
147b21b6272Sscottr bus_space_unmap(oa->oa_tag, bsh, 0x20);
148b21b6272Sscottr
149b21b6272Sscottr if (bus_space_map(oa->oa_tag, base + 0x100, 0x20, 0, &bsh))
150b21b6272Sscottr return 0;
151b21b6272Sscottr
152b21b6272Sscottr if (mac68k_bus_space_probe(oa->oa_tag, bsh, 0x04, 4) == 0) {
153b21b6272Sscottr bus_space_unmap(oa->oa_tag, bsh, 0x20);
154b21b6272Sscottr return 0;
155b21b6272Sscottr }
156a3d5b326Sbriggs
157a3d5b326Sbriggs /* Disable interrupts */
158b21b6272Sscottr bus_space_write_4(oa->oa_tag, bsh, 0x04, 0);
159a3d5b326Sbriggs
160a3d5b326Sbriggs /* Clear any interrupts */
161b21b6272Sscottr bus_space_write_4(oa->oa_tag, bsh, 0x0C, 0);
162b21b6272Sscottr bus_space_write_4(oa->oa_tag, bsh, 0x10, 0);
163b21b6272Sscottr bus_space_write_4(oa->oa_tag, bsh, 0x14, 0);
164a3d5b326Sbriggs
165b21b6272Sscottr bus_space_unmap(oa->oa_tag, bsh, 0x20);
166a3d5b326Sbriggs break;
1679c8e4f24Sbriggs case MACH_CLASSAV:
168527e5cbcSbriggs base = CIVIC_CONTROL_BASE;
169527e5cbcSbriggs
17063526c1fSscottr if (bus_space_map(oa->oa_tag, base, 0x1000, 0, &bsh))
17163526c1fSscottr return 0;
17260dd653bSscottr
1739c8e4f24Sbriggs /* Disable interrupts */
1749c8e4f24Sbriggs bus_space_write_1(oa->oa_tag, bsh, 0x120, 0);
175527e5cbcSbriggs
1769c8e4f24Sbriggs bus_space_unmap(oa->oa_tag, bsh, 0x1000);
1779c8e4f24Sbriggs break;
17846b2a0ebSscottr case MACH_CLASSIIci:
17946b2a0ebSscottr case MACH_CLASSIIsi:
1808583ef18Sjmmv if (mac68k_video.mv_len == 0 ||
18146b2a0ebSscottr (via2_reg(rMonitor) & RBVMonitorMask) == RBVMonIDNone)
18246b2a0ebSscottr found = 0;
18346b2a0ebSscottr break;
184a3d5b326Sbriggs default:
1858583ef18Sjmmv if (mac68k_video.mv_len == 0)
186a3d5b326Sbriggs found = 0;
187a3d5b326Sbriggs break;
188a3d5b326Sbriggs }
189a3d5b326Sbriggs
190a3d5b326Sbriggs return found;
191a3d5b326Sbriggs }
192a3d5b326Sbriggs
19337163421Sbriggs static void
grfiv_attach(device_t parent,device_t self,void * aux)194cbab9cadSchs grfiv_attach(device_t parent, device_t self, void *aux)
19559b4da2bSbriggs {
196a3d5b326Sbriggs struct obio_attach_args *oa = (struct obio_attach_args *)aux;
197d048582cSscottr struct grfbus_softc *sc;
19859b4da2bSbriggs struct grfmode *gm;
19963526c1fSscottr u_long base, length;
20063526c1fSscottr u_int32_t vbase1, vbase2;
20137163421Sbriggs
202cbab9cadSchs sc = device_private(self);
203cbab9cadSchs sc->sc_dev = self;
20459b4da2bSbriggs
20559b4da2bSbriggs sc->card_id = 0;
20659b4da2bSbriggs
207a3d5b326Sbriggs switch (current_mac_model->class) {
20863526c1fSscottr case MACH_CLASSQ2:
209b27d1061Sscottr if (current_mac_model->machineid != MACH_MACLC575) {
210*355a2878Srin sc->sc_basepa = VALKYRIE_FB_BASE;
21163526c1fSscottr length = 0x00100000; /* 1MB */
21263526c1fSscottr
2138583ef18Sjmmv if (sc->sc_basepa <= mac68k_video.mv_phys &&
2148583ef18Sjmmv mac68k_video.mv_phys < (sc->sc_basepa + length)) {
2158583ef18Sjmmv sc->sc_fbofs =
2168583ef18Sjmmv mac68k_video.mv_phys - sc->sc_basepa;
2178a007407Sscottr } else {
2188583ef18Sjmmv sc->sc_basepa =
2198583ef18Sjmmv m68k_trunc_page(mac68k_video.mv_phys);
2208583ef18Sjmmv sc->sc_fbofs =
2218583ef18Sjmmv m68k_page_offset(mac68k_video.mv_phys);
2228583ef18Sjmmv length = mac68k_video.mv_len + sc->sc_fbofs;
2238a007407Sscottr }
22463526c1fSscottr
225*355a2878Srin if (bus_space_map(sc->sc_tag, VALKYRIE_CMAP_BASE,
226*355a2878Srin VALKYRIE_CMAP_LEN, 0, &sc->sc_cmh) == 0)
227*355a2878Srin sc->sc_set_mapreg = valkyrie_set_mapreg;
228*355a2878Srin
22963526c1fSscottr printf(" @ %lx: Valkyrie video subsystem\n",
23063526c1fSscottr sc->sc_basepa + sc->sc_fbofs);
23163526c1fSscottr break;
23263526c1fSscottr }
23363526c1fSscottr /* See note in grfiv_match() */
23463526c1fSscottr /*FALLTHROUGH*/
235a3d5b326Sbriggs case MACH_CLASSQ:
23663526c1fSscottr base = DAFB_CONTROL_BASE;
237a3d5b326Sbriggs sc->sc_tag = oa->oa_tag;
238b21b6272Sscottr if (bus_space_map(sc->sc_tag, base, 0x20, 0, &sc->sc_regh)) {
23963526c1fSscottr printf(": failed to map DAFB register space\n");
24063526c1fSscottr return;
241a3d5b326Sbriggs }
24263526c1fSscottr
243*355a2878Srin sc->sc_basepa = DAFB_FB_BASE;
24463526c1fSscottr length = 0x00100000; /* 1MB */
24563526c1fSscottr
24663526c1fSscottr /* Compute the current frame buffer offset */
24763526c1fSscottr vbase1 = bus_space_read_4(sc->sc_tag, sc->sc_regh, 0x0) & 0xfff;
24818b4602fSscottr #if 1
24918b4602fSscottr /*
250eb910c35Sscottr * XXX The following exists because the DAFB v7 in these
251eb910c35Sscottr * systems doesn't return reasonable values to use for fbofs.
252eb910c35Sscottr * Ken'ichi Ishizaka gets credit for this hack. (sar 19990426)
253eb910c35Sscottr * (Does this get us the correct result for _all_ DAFB-
254eb910c35Sscottr * equipped systems and monitor combinations? It seems
255eb910c35Sscottr * possible, if not likely...)
25618b4602fSscottr */
25718b4602fSscottr switch (current_mac_model->machineid) {
25818b4602fSscottr case MACH_MACLC475:
25918b4602fSscottr case MACH_MACLC475_33:
26018b4602fSscottr case MACH_MACLC575:
261ba0669d0Sscottr case MACH_MACQ605:
262ba0669d0Sscottr case MACH_MACQ605_33:
263eb910c35Sscottr vbase1 &= 0x3f;
26418b4602fSscottr break;
26518b4602fSscottr }
26618b4602fSscottr #endif
267eb910c35Sscottr vbase2 = bus_space_read_4(sc->sc_tag, sc->sc_regh, 0x4) & 0xf;
268eb910c35Sscottr sc->sc_fbofs = (vbase1 << 9) | (vbase2 << 5);
26963526c1fSscottr
270*355a2878Srin if (bus_space_map(sc->sc_tag, DAFB_CMAP_BASE, DAFB_CMAP_LEN,
271*355a2878Srin 0, &sc->sc_cmh) == 0) {
272*355a2878Srin uint8_t *buf = kmem_zalloc(256 * 3, KM_SLEEP);
273*355a2878Srin sc->sc_cmap.red = buf;
274*355a2878Srin sc->sc_cmap.green = buf + 256;
275*355a2878Srin sc->sc_cmap.blue = buf + 256 * 2;
276*355a2878Srin sc->sc_set_mapreg = dafb_set_mapreg;
277*355a2878Srin }
278*355a2878Srin
27963526c1fSscottr printf(" @ %lx: DAFB video subsystem, monitor sense %x\n",
28063526c1fSscottr sc->sc_basepa + sc->sc_fbofs,
28163526c1fSscottr (bus_space_read_4(sc->sc_tag, sc->sc_regh, 0x1c) & 0x7));
28263526c1fSscottr
283b21b6272Sscottr bus_space_unmap(sc->sc_tag, sc->sc_regh, 0x20);
284a3d5b326Sbriggs break;
285527e5cbcSbriggs case MACH_CLASSAV:
286*355a2878Srin sc->sc_basepa = CIVIC_FB_BASE;
28763526c1fSscottr length = 0x00200000; /* 2MB */
2888583ef18Sjmmv if (mac68k_video.mv_phys >= sc->sc_basepa &&
2898583ef18Sjmmv mac68k_video.mv_phys < (sc->sc_basepa + length)) {
2908583ef18Sjmmv sc->sc_fbofs = mac68k_video.mv_phys - sc->sc_basepa;
2918a007407Sscottr } else {
2928583ef18Sjmmv sc->sc_basepa = m68k_trunc_page(mac68k_video.mv_phys);
2938583ef18Sjmmv sc->sc_fbofs = m68k_page_offset(mac68k_video.mv_phys);
2948583ef18Sjmmv length = mac68k_video.mv_len + sc->sc_fbofs;
2958a007407Sscottr }
29663526c1fSscottr
297*355a2878Srin if (bus_space_map(sc->sc_tag, CIVIC_CMAP_BASE, CIVIC_CMAP_LEN,
298*355a2878Srin 0, &sc->sc_cmh) == 0)
299*355a2878Srin sc->sc_set_mapreg = civic_set_mapreg;
300*355a2878Srin
3018a007407Sscottr printf(" @ %lx: CIVIC video subsystem\n",
30263526c1fSscottr sc->sc_basepa + sc->sc_fbofs);
30363526c1fSscottr break;
30446b2a0ebSscottr case MACH_CLASSIIci:
30546b2a0ebSscottr case MACH_CLASSIIsi:
3068583ef18Sjmmv sc->sc_basepa = m68k_trunc_page(mac68k_video.mv_phys);
3078583ef18Sjmmv sc->sc_fbofs = m68k_page_offset(mac68k_video.mv_phys);
3088583ef18Sjmmv length = mac68k_video.mv_len + sc->sc_fbofs;
30946b2a0ebSscottr
310*355a2878Srin if (bus_space_map(sc->sc_tag, RBV_CMAP_BASE, RBV_CMAP_LEN,
311*355a2878Srin 0, &sc->sc_cmh) == 0)
312*355a2878Srin sc->sc_set_mapreg = rbv_set_mapreg;
313*355a2878Srin
31446b2a0ebSscottr printf(" @ %lx: RBV video subsystem, ",
31546b2a0ebSscottr sc->sc_basepa + sc->sc_fbofs);
31646b2a0ebSscottr switch (via2_reg(rMonitor) & RBVMonitorMask) {
31746b2a0ebSscottr case RBVMonIDBWP:
31846b2a0ebSscottr printf("15\" monochrome portrait");
31946b2a0ebSscottr break;
32046b2a0ebSscottr case RBVMonIDRGB12:
32146b2a0ebSscottr printf("12\" color");
32246b2a0ebSscottr break;
32346b2a0ebSscottr case RBVMonIDRGB15:
32446b2a0ebSscottr printf("15\" color");
32546b2a0ebSscottr break;
32646b2a0ebSscottr case RBVMonIDStd:
32746b2a0ebSscottr printf("Macintosh II");
32846b2a0ebSscottr break;
32946b2a0ebSscottr default:
33046b2a0ebSscottr printf("unrecognized");
33146b2a0ebSscottr break;
33246b2a0ebSscottr }
33346b2a0ebSscottr printf(" display\n");
33446b2a0ebSscottr
33546b2a0ebSscottr break;
336a3d5b326Sbriggs default:
3378583ef18Sjmmv sc->sc_basepa = m68k_trunc_page(mac68k_video.mv_phys);
3388583ef18Sjmmv sc->sc_fbofs = m68k_page_offset(mac68k_video.mv_phys);
3398583ef18Sjmmv length = mac68k_video.mv_len + sc->sc_fbofs;
34063526c1fSscottr
341*355a2878Srin /* XXX setpalette? */
342*355a2878Srin
34363526c1fSscottr printf(" @ %lx: On-board video\n",
34463526c1fSscottr sc->sc_basepa + sc->sc_fbofs);
345a3d5b326Sbriggs break;
346a3d5b326Sbriggs }
34759b4da2bSbriggs
34863526c1fSscottr if (bus_space_map(sc->sc_tag, sc->sc_basepa, length, 0,
34963526c1fSscottr &sc->sc_handle)) {
350cbab9cadSchs printf("%s: failed to map video RAM\n", device_xname(sc->sc_dev));
35163526c1fSscottr return;
35263526c1fSscottr }
35363526c1fSscottr
3548583ef18Sjmmv if (sc->sc_basepa <= mac68k_video.mv_phys &&
3558583ef18Sjmmv mac68k_video.mv_phys < (sc->sc_basepa + length)) {
3568583ef18Sjmmv /* XXX Hack */
3578583ef18Sjmmv mac68k_video.mv_kvaddr = sc->sc_handle.base + sc->sc_fbofs;
3588583ef18Sjmmv }
35963526c1fSscottr
36059b4da2bSbriggs gm = &(sc->curr_mode);
36159b4da2bSbriggs gm->mode_id = 0;
3628583ef18Sjmmv gm->psize = mac68k_video.mv_depth;
36359b4da2bSbriggs gm->ptype = 0;
3648583ef18Sjmmv gm->width = mac68k_video.mv_width;
3658583ef18Sjmmv gm->height = mac68k_video.mv_height;
3668583ef18Sjmmv gm->rowbytes = mac68k_video.mv_stride;
36763526c1fSscottr gm->hres = 80; /* XXX hack */
36863526c1fSscottr gm->vres = 80; /* XXX hack */
36963526c1fSscottr gm->fbsize = gm->height * gm->rowbytes;
37053524e44Schristos gm->fbbase = (void *)sc->sc_handle.base; /* XXX yet another hack */
37163526c1fSscottr gm->fboff = sc->sc_fbofs;
37259b4da2bSbriggs
373d048582cSscottr /* Perform common video attachment. */
374da2f2cb7Sscottr grf_establish(sc, NULL, grfiv_mode);
37559b4da2bSbriggs }
37659b4da2bSbriggs
37737163421Sbriggs static int
grfiv_mode(struct grf_softc * sc,int cmd,void * arg)3787acd68b1Schs grfiv_mode(struct grf_softc *sc, int cmd, void *arg)
37959b4da2bSbriggs {
38038031d91Sbriggs switch (cmd) {
38138031d91Sbriggs case GM_GRFON:
38238031d91Sbriggs case GM_GRFOFF:
38359b4da2bSbriggs return 0;
38438031d91Sbriggs case GM_CURRMODE:
38538031d91Sbriggs break;
38638031d91Sbriggs case GM_NEWMODE:
38738031d91Sbriggs break;
38838031d91Sbriggs case GM_LISTMODES:
38938031d91Sbriggs break;
39038031d91Sbriggs }
39138031d91Sbriggs return EINVAL;
39259b4da2bSbriggs }
393*355a2878Srin
394*355a2878Srin #define CHECK_INDEX(index) \
395*355a2878Srin do { \
396*355a2878Srin size_t depth = mac68k_video.mv_depth; \
397*355a2878Srin if (depth == 1 || depth > 8 || (index) >= (1 << depth)) \
398*355a2878Srin return; \
399*355a2878Srin } while (0 /* CONSTCOND */)
400*355a2878Srin
401*355a2878Srin static void
dafb_set_mapreg(void * cookie,int index,int r,int g,int b)402*355a2878Srin dafb_set_mapreg(void *cookie, int index, int r, int g, int b)
403*355a2878Srin {
404*355a2878Srin struct grfbus_softc *sc = (struct grfbus_softc *)cookie;
405*355a2878Srin static int last = -2;
406*355a2878Srin
407*355a2878Srin CHECK_INDEX(index);
408*355a2878Srin
409*355a2878Srin #define dafb_write_lut(val) \
410*355a2878Srin bus_space_write_1(sc->sc_tag, sc->sc_cmh, DAFB_CMAP_LUT, val)
411*355a2878Srin
412*355a2878Srin if (index != last + 1) {
413*355a2878Srin bus_space_write_4(sc->sc_tag, sc->sc_cmh, DAFB_CMAP_RESET, 0);
414*355a2878Srin for (int i = 0; i < index; i++) {
415*355a2878Srin dafb_write_lut(sc->sc_cmap.red[i]);
416*355a2878Srin dafb_write_lut(sc->sc_cmap.green[i]);
417*355a2878Srin dafb_write_lut(sc->sc_cmap.blue[i]);
418*355a2878Srin }
419*355a2878Srin }
420*355a2878Srin
421*355a2878Srin dafb_write_lut(r);
422*355a2878Srin dafb_write_lut(g);
423*355a2878Srin dafb_write_lut(b);
424*355a2878Srin
425*355a2878Srin last = index;
426*355a2878Srin sc->sc_cmap.red[index] = r;
427*355a2878Srin sc->sc_cmap.green[index] = g;
428*355a2878Srin sc->sc_cmap.blue[index] = b;
429*355a2878Srin
430*355a2878Srin #undef dafb_write_lut
431*355a2878Srin
432*355a2878Srin }
433*355a2878Srin
434*355a2878Srin static void
civic_set_mapreg(void * cookie,int index,int r,int g,int b)435*355a2878Srin civic_set_mapreg(void *cookie, int index, int r, int g, int b)
436*355a2878Srin {
437*355a2878Srin struct grfbus_softc *sc = (struct grfbus_softc *)cookie;
438*355a2878Srin uint8_t status, junk = 0;
439*355a2878Srin
440*355a2878Srin CHECK_INDEX(index);
441*355a2878Srin
442*355a2878Srin #define civic_read_lut \
443*355a2878Srin bus_space_read_1(sc->sc_tag, sc->sc_cmh, CIVIC_CMAP_LUT)
444*355a2878Srin #define civic_write_lut(val) \
445*355a2878Srin bus_space_write_1(sc->sc_tag, sc->sc_cmh, CIVIC_CMAP_LUT, val)
446*355a2878Srin
447*355a2878Srin bus_space_write_1(sc->sc_tag, sc->sc_cmh, CIVIC_CMAP_ADDR, index);
448*355a2878Srin status = bus_space_read_1(sc->sc_tag, sc->sc_cmh, CIVIC_CMAP_STATUS2);
449*355a2878Srin if (status & 0x08) {
450*355a2878Srin junk = civic_read_lut;
451*355a2878Srin junk = civic_read_lut;
452*355a2878Srin junk = civic_read_lut;
453*355a2878Srin junk = civic_read_lut;
454*355a2878Srin if (status & 0x0d) {
455*355a2878Srin civic_write_lut(0);
456*355a2878Srin civic_write_lut(0);
457*355a2878Srin }
458*355a2878Srin }
459*355a2878Srin civic_write_lut(r);
460*355a2878Srin civic_write_lut(g);
461*355a2878Srin civic_write_lut(b);
462*355a2878Srin civic_write_lut(junk);
463*355a2878Srin
464*355a2878Srin #undef civic_read_lut
465*355a2878Srin #undef civic_write_lut
466*355a2878Srin
467*355a2878Srin }
468*355a2878Srin
469*355a2878Srin static void
valkyrie_set_mapreg(void * cookie,int index,int r,int g,int b)470*355a2878Srin valkyrie_set_mapreg(void *cookie, int index, int r, int g, int b)
471*355a2878Srin {
472*355a2878Srin struct grfbus_softc *sc = (struct grfbus_softc *)cookie;
473*355a2878Srin
474*355a2878Srin CHECK_INDEX(index);
475*355a2878Srin
476*355a2878Srin #define valkyrie_write_lut(val) \
477*355a2878Srin bus_space_write_1(sc->sc_tag, sc->sc_cmh, VALKYRIE_CMAP_LUT, val)
478*355a2878Srin
479*355a2878Srin bus_space_write_1(sc->sc_tag, sc->sc_cmh, VALKYRIE_CMAP_ADDR, index);
480*355a2878Srin delay(1);
481*355a2878Srin valkyrie_write_lut(r);
482*355a2878Srin valkyrie_write_lut(g);
483*355a2878Srin valkyrie_write_lut(b);
484*355a2878Srin
485*355a2878Srin #undef valkyrie_write_lut
486*355a2878Srin
487*355a2878Srin }
488*355a2878Srin
489*355a2878Srin static void
rbv_set_mapreg(void * cookie,int index,int r,int g,int b)490*355a2878Srin rbv_set_mapreg(void *cookie, int index, int r, int g, int b)
491*355a2878Srin {
492*355a2878Srin struct grfbus_softc *sc = (struct grfbus_softc *)cookie;
493*355a2878Srin
494*355a2878Srin CHECK_INDEX(index);
495*355a2878Srin
496*355a2878Srin #define rbv_write_lut(val) \
497*355a2878Srin bus_space_write_1(sc->sc_tag, sc->sc_cmh, RBV_CMAP_LUT, val)
498*355a2878Srin
499*355a2878Srin index += 256 - (1 << mac68k_video.mv_depth);
500*355a2878Srin bus_space_write_1(sc->sc_tag, sc->sc_cmh, RBV_CMAP_CNTL, 0xff);
501*355a2878Srin bus_space_write_1(sc->sc_tag, sc->sc_cmh, RBV_CMAP_ADDR, index);
502*355a2878Srin rbv_write_lut(r);
503*355a2878Srin rbv_write_lut(g);
504*355a2878Srin rbv_write_lut(b);
505*355a2878Srin
506*355a2878Srin #undef rbv_write_lut
507*355a2878Srin
508*355a2878Srin }
509*355a2878Srin
510*355a2878Srin #undef CHECK_INDEX
511