xref: /netbsd/sys/dev/pci/agp_apple.c (revision 70747dc1)
1*70747dc1Schs /*	$NetBSD: agp_apple.c,v 1.8 2019/11/10 21:16:36 chs Exp $ */
27325f795Smacallan 
37325f795Smacallan /*-
47325f795Smacallan  * Copyright (c) 2007 Michael Lorenz
57325f795Smacallan  * All rights reserved.
67325f795Smacallan  *
77325f795Smacallan  * Redistribution and use in source and binary forms, with or without
87325f795Smacallan  * modification, are permitted provided that the following conditions
97325f795Smacallan  * are met:
107325f795Smacallan  * 1. Redistributions of source code must retain the above copyright
117325f795Smacallan  *    notice, this list of conditions and the following disclaimer.
127325f795Smacallan  * 2. Redistributions in binary form must reproduce the above copyright
137325f795Smacallan  *    notice, this list of conditions and the following disclaimer in the
147325f795Smacallan  *    documentation and/or other materials provided with the distribution.
157325f795Smacallan  *
167325f795Smacallan  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
177325f795Smacallan  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
187325f795Smacallan  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
197325f795Smacallan  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
207325f795Smacallan  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
217325f795Smacallan  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
227325f795Smacallan  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
237325f795Smacallan  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
247325f795Smacallan  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
257325f795Smacallan  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
267325f795Smacallan  * POSSIBILITY OF SUCH DAMAGE.
277325f795Smacallan  */
287325f795Smacallan 
297325f795Smacallan #include <sys/cdefs.h>
30*70747dc1Schs __KERNEL_RCSID(0, "$NetBSD: agp_apple.c,v 1.8 2019/11/10 21:16:36 chs Exp $");
317325f795Smacallan #include <sys/param.h>
327325f795Smacallan #include <sys/systm.h>
337325f795Smacallan #include <sys/malloc.h>
347325f795Smacallan #include <sys/kernel.h>
357325f795Smacallan #include <sys/proc.h>
367325f795Smacallan #include <sys/conf.h>
377325f795Smacallan #include <sys/device.h>
387325f795Smacallan #include <sys/agpio.h>
397325f795Smacallan 
407325f795Smacallan #include <dev/pci/pcivar.h>
417325f795Smacallan #include <dev/pci/pcireg.h>
427325f795Smacallan #include <dev/pci/agpvar.h>
437325f795Smacallan #include <dev/pci/agpreg.h>
447325f795Smacallan 
45a2a38285Sad #include <sys/bus.h>
467325f795Smacallan 
47982c6a6cSchristos #define	APPLE_UNINORTH_GART_BASE	0x8c
48982c6a6cSchristos #define	APPLE_UNINORTH_GART_BASE_ADDR	0x90
49982c6a6cSchristos #define APPLE_UNINORTH_GART_CTRL	0x94
50982c6a6cSchristos #define APPLE_UNINORTH_GART_INVAL	0x00000001
51982c6a6cSchristos #define APPLE_UNINORTH_GART_ENABLE	0x00000100
52982c6a6cSchristos #define APPLE_UNINORTH_GART_2XRESET	0x00010000
53982c6a6cSchristos #define APPLE_UNINORTH_GART_PERFRD	0x00080000
54982c6a6cSchristos 
557325f795Smacallan static u_int32_t agp_apple_get_aperture(struct agp_softc *);
567325f795Smacallan static int agp_apple_set_aperture(struct agp_softc *, u_int32_t);
577325f795Smacallan static int agp_apple_bind_page(struct agp_softc *, off_t, bus_addr_t);
587325f795Smacallan static int agp_apple_unbind_page(struct agp_softc *, off_t);
597325f795Smacallan static void agp_apple_flush_tlb(struct agp_softc *);
607325f795Smacallan 
617325f795Smacallan static struct agp_methods agp_apple_methods = {
627325f795Smacallan 	agp_apple_get_aperture,
637325f795Smacallan 	agp_apple_set_aperture,
647325f795Smacallan 	agp_apple_bind_page,
657325f795Smacallan 	agp_apple_unbind_page,
667325f795Smacallan 	agp_apple_flush_tlb,
677325f795Smacallan 	agp_generic_enable,
687325f795Smacallan 	agp_generic_alloc_memory,
697325f795Smacallan 	agp_generic_free_memory,
707325f795Smacallan 	agp_generic_bind_memory,
717325f795Smacallan 	agp_generic_unbind_memory,
727325f795Smacallan };
737325f795Smacallan 
747325f795Smacallan struct agp_apple_softc {
757325f795Smacallan 	u_int32_t	initial_aperture; /* aperture size at startup */
767325f795Smacallan 	struct agp_gatt *gatt;
777325f795Smacallan };
787325f795Smacallan 
797325f795Smacallan int
agp_apple_attach(device_t parent,device_t self,void * aux)806e9d3398Sfreza agp_apple_attach(device_t parent, device_t self, void *aux)
817325f795Smacallan {
827325f795Smacallan 	struct pci_attach_args *pa = aux;
836e9d3398Sfreza 	struct agp_softc *sc = device_private(self);
847325f795Smacallan 	struct agp_apple_softc *asc;
857325f795Smacallan 	struct agp_gatt *gatt;
867325f795Smacallan 
87*70747dc1Schs 	asc = malloc(sizeof *asc, M_AGP, M_WAITOK|M_ZERO);
887325f795Smacallan 	sc->as_chipc = asc;
897325f795Smacallan 	sc->as_methods = &agp_apple_methods;
907325f795Smacallan 	pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, &sc->as_capoff,
917325f795Smacallan 	    NULL);
927325f795Smacallan 
937325f795Smacallan 	sc->as_apaddr = 0;
947325f795Smacallan 	sc->as_apsize = 8 * 1024 * 1024;
957325f795Smacallan 	sc->as_apflags = 0;
967325f795Smacallan 	sc->as_pc = pa->pa_pc;
977325f795Smacallan 	sc->as_tag = pa->pa_tag;
987325f795Smacallan 	sc->as_apt = pa->pa_memt;
997325f795Smacallan 
1007325f795Smacallan 	asc->initial_aperture = sc->as_apsize;
1017325f795Smacallan 
1027325f795Smacallan 	for (;;) {
1037325f795Smacallan 		gatt = agp_alloc_gatt(sc);
1047325f795Smacallan 		if (gatt)
1057325f795Smacallan 			break;
1067325f795Smacallan 		sc->as_apsize = sc->as_apsize >> 1;
1077325f795Smacallan 		if (sc->as_apsize == 0) {
1087325f795Smacallan 			aprint_error(": can't set aperture size\n");
1097325f795Smacallan 			return ENOMEM;
1107325f795Smacallan 		}
1117325f795Smacallan 	}
1127325f795Smacallan 	asc->gatt = gatt;
1137325f795Smacallan 
1147325f795Smacallan 	/* Install the gatt. */
115982c6a6cSchristos 	aprint_error("gatt: %08jx %ju MB\n", (uintmax_t)gatt->ag_physical,
116982c6a6cSchristos 	    (uintmax_t)(sc->as_apsize >> 20));
1177325f795Smacallan 	pci_conf_write(pa->pa_pc, pa->pa_tag, APPLE_UNINORTH_GART_BASE,
1187325f795Smacallan 	    (gatt->ag_physical & 0xfffff000) |
1197325f795Smacallan 	    (sc->as_apsize >> 22));
1207325f795Smacallan 
1217325f795Smacallan 	/* Enable the aperture. */
1227325f795Smacallan 	pci_conf_write(pa->pa_pc, pa->pa_tag, APPLE_UNINORTH_GART_CTRL,
123982c6a6cSchristos 	    APPLE_UNINORTH_GART_ENABLE);
1247325f795Smacallan 	pci_conf_write(pa->pa_pc, pa->pa_tag, APPLE_UNINORTH_GART_CTRL,
125982c6a6cSchristos 	    APPLE_UNINORTH_GART_ENABLE | APPLE_UNINORTH_GART_INVAL);
1267325f795Smacallan 	pci_conf_write(pa->pa_pc, pa->pa_tag, APPLE_UNINORTH_GART_CTRL,
127982c6a6cSchristos 	    APPLE_UNINORTH_GART_ENABLE);
1287325f795Smacallan 	return 0;
1297325f795Smacallan }
1307325f795Smacallan 
1317325f795Smacallan static u_int32_t
agp_apple_get_aperture(struct agp_softc * sc)1327325f795Smacallan agp_apple_get_aperture(struct agp_softc *sc)
1337325f795Smacallan {
1347325f795Smacallan #if 0
1357325f795Smacallan 	u_int32_t apsize = 0;
1367325f795Smacallan 
1377325f795Smacallan 	aprint_error("%s: ", __func__);
1387325f795Smacallan 	apsize = pci_conf_read(sc->as_pc, sc->as_tag,
1397325f795Smacallan 	    APPLE_UNINORTH_GART_BASE) & 0x0000ffff;
1407325f795Smacallan 	aprint_error("%08x\n", apsize);
1417325f795Smacallan 	return (apsize << 22);
1427325f795Smacallan #else
1437325f795Smacallan 	return sc->as_apsize;
1447325f795Smacallan #endif
1457325f795Smacallan }
1467325f795Smacallan 
1477325f795Smacallan static int
agp_apple_set_aperture(struct agp_softc * sc,u_int32_t aperture)1487325f795Smacallan agp_apple_set_aperture(struct agp_softc *sc, u_int32_t aperture)
1497325f795Smacallan {
1507325f795Smacallan 	pcireg_t reg;
1517325f795Smacallan 
1527325f795Smacallan 	aprint_error("%s: %08x\n", __func__, aperture);
1537325f795Smacallan 	reg = pci_conf_read(sc->as_pc, sc->as_tag, APPLE_UNINORTH_GART_BASE)
1547325f795Smacallan 	    & 0xfffff000;
1557325f795Smacallan 	reg |= ((aperture >> 22) & 0xfff);
1567325f795Smacallan 	pci_conf_write(sc->as_pc, sc->as_tag, APPLE_UNINORTH_GART_BASE, reg);
1577325f795Smacallan 	sc->as_apsize = aperture;
1587325f795Smacallan 	return 0;
1597325f795Smacallan }
1607325f795Smacallan 
1617325f795Smacallan static int
agp_apple_bind_page(struct agp_softc * sc,off_t offset,bus_addr_t physical)1627325f795Smacallan agp_apple_bind_page(struct agp_softc *sc, off_t offset, bus_addr_t physical)
1637325f795Smacallan {
1647325f795Smacallan 	struct agp_apple_softc *asc = sc->as_chipc;
1657325f795Smacallan 
1667325f795Smacallan 	if (offset < 0 || offset >= (asc->gatt->ag_entries << AGP_PAGE_SHIFT))
1677325f795Smacallan 		return EINVAL;
1687325f795Smacallan 
1697325f795Smacallan 	asc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = htole32(physical);
1707325f795Smacallan 	return 0;
1717325f795Smacallan }
1727325f795Smacallan 
1737325f795Smacallan static int
agp_apple_unbind_page(struct agp_softc * sc,off_t offset)1747325f795Smacallan agp_apple_unbind_page(struct agp_softc *sc, off_t offset)
1757325f795Smacallan {
1767325f795Smacallan 	struct agp_apple_softc *asc = sc->as_chipc;
1777325f795Smacallan 
1787325f795Smacallan 	if (offset < 0 || offset >= (asc->gatt->ag_entries << AGP_PAGE_SHIFT))
1797325f795Smacallan 		return EINVAL;
1807325f795Smacallan 
1817325f795Smacallan 	asc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = 0;
1827325f795Smacallan 	return 0;
1837325f795Smacallan }
1847325f795Smacallan 
1857325f795Smacallan static void
agp_apple_flush_tlb(struct agp_softc * sc)1867325f795Smacallan agp_apple_flush_tlb(struct agp_softc *sc)
1877325f795Smacallan {
1887325f795Smacallan 
1897325f795Smacallan 	pci_conf_write(sc->as_pc, sc->as_tag, APPLE_UNINORTH_GART_CTRL,
190982c6a6cSchristos 	    APPLE_UNINORTH_GART_ENABLE);
1917325f795Smacallan 	pci_conf_write(sc->as_pc, sc->as_tag, APPLE_UNINORTH_GART_CTRL,
192982c6a6cSchristos 	    APPLE_UNINORTH_GART_ENABLE | APPLE_UNINORTH_GART_INVAL);
1937325f795Smacallan 	pci_conf_write(sc->as_pc, sc->as_tag, APPLE_UNINORTH_GART_CTRL,
194982c6a6cSchristos 	    APPLE_UNINORTH_GART_ENABLE);
1957325f795Smacallan }
196