xref: /netbsd-src/sys/arch/mac68k/obio/grf_obio.c (revision 355a2878fad22b80314bcbfd857f2fb9f9076bd0)
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