Module Name:    src
Committed By:   macallan
Date:           Mon Sep 28 05:43:59 UTC 2020

Modified Files:
        src/sys/dev/pci: radeonfb.c radeonfbvar.h

Log Message:
first step towards r5xx support:
- no CRTC programming yet, we just use whatever mode the (open)firmware hands
  us
- palette control, fb location etc. all work
- hardware acceleration for character drawing, scrolling etc. works
- hardware cursor works
... tested & still works on various radeons in various macppc machines


To generate a diff of this commit:
cvs rdiff -u -r1.109 -r1.110 src/sys/dev/pci/radeonfb.c
cvs rdiff -u -r1.21 -r1.22 src/sys/dev/pci/radeonfbvar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/radeonfb.c
diff -u src/sys/dev/pci/radeonfb.c:1.109 src/sys/dev/pci/radeonfb.c:1.110
--- src/sys/dev/pci/radeonfb.c:1.109	Sun Jul  5 09:53:54 2020
+++ src/sys/dev/pci/radeonfb.c	Mon Sep 28 05:43:58 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: radeonfb.c,v 1.109 2020/07/05 09:53:54 martin Exp $ */
+/*	$NetBSD: radeonfb.c,v 1.110 2020/09/28 05:43:58 macallan Exp $ */
 
 /*-
  * Copyright (c) 2006 Itronix Inc.
@@ -70,7 +70,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: radeonfb.c,v 1.109 2020/07/05 09:53:54 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: radeonfb.c,v 1.110 2020/09/28 05:43:58 macallan Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -383,10 +383,10 @@ static struct {
 	{ PCI_PRODUCT_ATI_RADEON_R423_UT,	RADEON_R420, 0 },
 	{ PCI_PRODUCT_ATI_RADEON_R423_5D57,	RADEON_R420, 0 },
 	{ PCI_PRODUCT_ATI_RADEON_R430_554F,	RADEON_R420, 0 },
+#endif
 
 	/* R5xx family */
-	{ 0x7240,	RADEON_R420, 0 },	
-#endif
+	{ 0x7240,	RADEON_R580, RFB_IS_AVIVO },	
 	{ 0, 0, 0 }
 };
 
@@ -426,6 +426,7 @@ static const struct {
 	{ RADEON_RV350,	{{15000, 0xb0155}, {-1, 0xb01cb}}},
 	{ RADEON_RV380,	{{15000, 0xb0155}, {-1, 0xb01cb}}},
 	{ RADEON_R420,	{{-1, 0xb01cb}}},
+	{ RADEON_R580,	{{-1, 0xb01cb}}}, /* XXX likely bogus */
 };
 
 #define RADEONFB_BACKLIGHT_MAX    255  /* Maximum backlight level. */
@@ -514,6 +515,7 @@ radeonfb_attach(device_t parent, device_
 	case RADEON_R350:
 	case RADEON_RV380:
 	case RADEON_R420:
+	case RADEON_R580:
 		/* newer chips */
 		sc->sc_flags |= RFB_R300;
 		break;
@@ -587,12 +589,13 @@ radeonfb_attach(device_t parent, device_
 	PRINTREG(RADEON_TMDS_PLL_CNTL);
 	PRINTREG(RADEON_LVDS_GEN_CNTL);
 	PRINTREG(RADEON_DISP_HW_DEBUG);
-	PRINTREG(RADEON_PIXCLKS_CNTL);
-	PRINTREG(RADEON_CRTC_H_SYNC_STRT_WID);
-	PRINTREG(RADEON_FP_H_SYNC_STRT_WID);
-	PRINTREG(RADEON_CRTC2_H_SYNC_STRT_WID);
-	PRINTREG(RADEON_FP_H2_SYNC_STRT_WID);
-
+	if (!IS_AVIVO(sc)) {
+		PRINTREG(RADEON_PIXCLKS_CNTL);
+		PRINTREG(RADEON_CRTC_H_SYNC_STRT_WID);
+		PRINTREG(RADEON_FP_H_SYNC_STRT_WID);
+		PRINTREG(RADEON_CRTC2_H_SYNC_STRT_WID);
+		PRINTREG(RADEON_FP_H2_SYNC_STRT_WID);
+	}
 /*
  * XXX
  * This was if (IS_RV100()), which is set for all pre-R3xx chips.
@@ -883,12 +886,11 @@ radeonfb_attach(device_t parent, device_
 		/* N.B.: radeon wants 64-byte aligned stride */
 		dp->rd_stride = dp->rd_virtx * dp->rd_bpp / 8;
 		dp->rd_stride = ROUNDUP(dp->rd_stride, RADEON_STRIDEALIGN);
-		DPRINTF(("stride: %d %d\n", dp->rd_stride, dp->rd_virtx));
 
 		dp->rd_offset = sc->sc_fboffset * i;
 		dp->rd_fbptr = (vaddr_t)bus_space_vaddr(sc->sc_memt,
 		    sc->sc_memh) + dp->rd_offset;
-		dp->rd_curoff = sc->sc_fboffset - 4096;	/* 4KB cursor space */
+		dp->rd_curoff = sc->sc_fboffset - 16384; /* 16KB cursor space */
 		dp->rd_curptr = dp->rd_fbptr + dp->rd_curoff;
 
 		DPRINTF(("fpbtr = %p\n", (void *)dp->rd_fbptr));
@@ -905,10 +907,11 @@ radeonfb_attach(device_t parent, device_
 			    dp->rd_bpp);
 			goto error;
 		}
-
 		DPRINTF(("init engine\n"));
 		/* XXX: this seems suspicious - per display engine
 		   initialization? */
+
+		radeonfb_modeswitch(dp);
 		radeonfb_engine_init(dp);
 
 		/* copy the template into place */
@@ -980,7 +983,6 @@ radeonfb_attach(device_t parent, device_
 
 		if (dp->rd_console) {
 
-			radeonfb_modeswitch(dp);
 			wsdisplay_cnattach(dp->rd_wsscreens, ri, 0, 0,
 			    defattr);
 #ifdef SPLASHSCREEN
@@ -1000,7 +1002,6 @@ radeonfb_attach(device_t parent, device_
 			 */
 			memset(ri->ri_bits, 0, 1024);
 
-			radeonfb_modeswitch(dp);
 #ifdef SPLASHSCREEN
 			if (splash_render(&dp->rd_splash,
 			    SPLASH_F_CENTER|SPLASH_F_FILL) == 0)
@@ -1021,23 +1022,27 @@ radeonfb_attach(device_t parent, device_
 		callout_init(&dp->rd_bl_lvds_co, 0);
 		callout_setfunc(&dp->rd_bl_lvds_co,
 				radeonfb_lvds_callout, dp);
+
 		dp->rd_bl_on = 1;
 		if (sc->sc_flags & RFB_MOB) {
 			dp->rd_bl_level = radeonfb_get_backlight(dp);
 		} else
 			dp->rd_bl_level = 128;
+
 		radeonfb_set_backlight(dp, dp->rd_bl_level);
 	}
-
 	for (i = 0; i < RADEON_NDISPLAYS; i++)
 		radeonfb_init_palette(&sc->sc_displays[i]);
- 
-	if (HAS_CRTC2(sc)) {
+
+	if (HAS_CRTC2(sc) && !IS_AVIVO(sc)) {
 		CLR32(sc, RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_DISP_DIS);
 	}
 
-	CLR32(sc, RADEON_CRTC_EXT_CNTL, RADEON_CRTC_DISPLAY_DIS);
-	SET32(sc, RADEON_FP_GEN_CNTL, RADEON_FP_FPON);
+	if (!IS_AVIVO(sc)) {
+		CLR32(sc, RADEON_CRTC_EXT_CNTL, RADEON_CRTC_DISPLAY_DIS);
+		SET32(sc, RADEON_FP_GEN_CNTL, RADEON_FP_FPON);
+	}
+
 	pmf_event_register(dev, PMFE_DISPLAY_BRIGHTNESS_UP,
 	    radeonfb_brightness_up, TRUE);
 	pmf_event_register(dev, PMFE_DISPLAY_BRIGHTNESS_DOWN,
@@ -1052,18 +1057,19 @@ radeonfb_attach(device_t parent, device_
 	    (config_found_ia(dev, "drm", aux, radeonfb_drm_print) != 0);
 	DPRINTF(("needs_unmap: %d\n", sc->sc_needs_unmap));
 
-	PRINTREG(RADEON_CRTC_EXT_CNTL);
-	PRINTREG(RADEON_CRTC_GEN_CNTL);
-	PRINTREG(RADEON_CRTC2_GEN_CNTL);
-	PRINTREG(RADEON_DISP_OUTPUT_CNTL);
-	PRINTREG(RADEON_DAC_CNTL2);
-	PRINTREG(RADEON_FP_GEN_CNTL);
-	PRINTREG(RADEON_FP2_GEN_CNTL);
-	PRINTREG(RADEON_TMDS_CNTL);
-	PRINTREG(RADEON_TMDS_TRANSMITTER_CNTL);
-	PRINTREG(RADEON_TMDS_PLL_CNTL);
-	PRINTREG(RADEON_PIXCLKS_CNTL);
-
+	if (!IS_AVIVO(sc)) {
+		PRINTREG(RADEON_CRTC_EXT_CNTL);
+		PRINTREG(RADEON_CRTC_GEN_CNTL);
+		PRINTREG(RADEON_CRTC2_GEN_CNTL);
+		PRINTREG(RADEON_DISP_OUTPUT_CNTL);
+		PRINTREG(RADEON_DAC_CNTL2);
+		PRINTREG(RADEON_FP_GEN_CNTL);
+		PRINTREG(RADEON_FP2_GEN_CNTL);
+		PRINTREG(RADEON_TMDS_CNTL);
+		PRINTREG(RADEON_TMDS_TRANSMITTER_CNTL);
+		PRINTREG(RADEON_TMDS_PLL_CNTL);
+		PRINTREG(RADEON_PIXCLKS_CNTL);
+	}
 	return;
 
 error:
@@ -1173,10 +1179,12 @@ radeonfb_ioctl(void *v, void *vs,
 		return 0;
 
 	case WSDISPLAYIO_SVIDEO:
-		radeonfb_blank(dp,
-		    (*(unsigned int *)d == WSDISPLAYIO_VIDEO_OFF));
-		radeonfb_switch_backlight(dp,
-		    (*(unsigned int *)d == WSDISPLAYIO_VIDEO_ON));
+		if (dp->rd_wsmode != WSDISPLAYIO_MODE_MAPPED) {
+			radeonfb_blank(dp,
+			    (*(unsigned int *)d == WSDISPLAYIO_VIDEO_OFF));
+			radeonfb_switch_backlight(dp,
+			    (*(unsigned int *)d == WSDISPLAYIO_VIDEO_ON));
+		}
 		pmf_event_inject(NULL, 
 		    (*(unsigned int *)d == WSDISPLAYIO_VIDEO_ON) ?
 		     PMFE_DISPLAY_ON : PMFE_DISPLAY_OFF);
@@ -2268,8 +2276,27 @@ radeonfb_modeswitch(struct radeonfb_disp
 	struct radeonfb_softc	*sc = dp->rd_softc;
 	int			i;
 
+	if (IS_AVIVO(sc)) {
+		/*
+		 * no actual mode setting yet, we just make sure the CRTCs
+		 * point at the right memory ranges and use the same pitch
+		 * for the drawing engine
+		 */
+		if (GET32(sc, AVIVO_D1CRTC_CONTROL) & AVIVO_CRTC_EN) {
+			CLR32(sc, AVIVO_D1GRPH_CONTROL, AVIVO_D1GRPH_MACRO_ADDRESS_MODE);
+			dp->rd_stride = GET32(sc, AVIVO_D1GRPH_PITCH);
+			PUT32(sc, AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS, 0);
+		}
+		if (GET32(sc, AVIVO_D2CRTC_CONTROL) & AVIVO_CRTC_EN) {
+			CLR32(sc, AVIVO_D2GRPH_CONTROL, AVIVO_D1GRPH_MACRO_ADDRESS_MODE);
+			dp->rd_stride = GET32(sc, AVIVO_D2GRPH_PITCH);
+			PUT32(sc, AVIVO_D2GRPH_PRIMARY_SURFACE_ADDRESS, 0);
+		}
+		return;
+	}
+
 	/* blank the display while we switch modes */
-	radeonfb_blank(dp, 1);
+	//radeonfb_blank(dp, 1);
 
 #if 0
 	SET32(sc, RADEON_CRTC_EXT_CNTL,
@@ -2288,11 +2315,6 @@ radeonfb_modeswitch(struct radeonfb_disp
 	PUT32(sc, RADEON_GEN_INT_CNTL, 0);
 	PUT32(sc, RADEON_CAP0_TRIG_CNTL, 0);
 	PUT32(sc, RADEON_CAP1_TRIG_CNTL, 0);
-	/*
-	 * Apple OF hands us R3xx radeons with tiling enabled - explicitly
-	 * disable it here
-	 */
-	PUT32(sc, RADEON_SURFACE_CNTL, RADEON_SURF_TRANSLATION_DIS);
 
 	for (i = 0; i < dp->rd_ncrtcs; i++)
 		radeonfb_setcrtc(dp, i);
@@ -2323,7 +2345,7 @@ radeonfb_setcrtc(struct radeonfb_display
 	struct videomode	*mode;
 	struct radeonfb_softc	*sc;
 	struct radeonfb_crtc	*cp;
-	uint32_t		v;
+	uint32_t		v, hd, vd;
 	uint32_t		gencntl;
 	uint32_t		htotaldisp;
 	uint32_t		hsyncstrt;
@@ -2425,57 +2447,65 @@ radeonfb_setcrtc(struct radeonfb_display
 	PUT32(sc, RADEON_CRTC_EXT_CNTL, v);
 	PRINTREG(RADEON_CRTC_EXT_CNTL);
 
-	/*
-	 * H_TOTAL_DISP
-	 */
-	v = ((mode->hdisplay / 8) - 1) << 16;
-	v |= (mode->htotal / 8) - 1;
-	PUT32(sc, htotaldisp, v);
-	DPRINTF(("CRTC%s_H_TOTAL_DISP = %08x\n", crtc ? "2" : "", v));
-	if (fphtotaldisp) {
-		PUT32(sc, fphtotaldisp, v);
-		DPRINTF(("FP_H%s_TOTAL_DISP = %08x\n", crtc ? "2" : "", v));
-	}
-	/*
-	 * H_SYNC_STRT_WID
-	 */
-	v = (((mode->hsync_end - mode->hsync_start) / 8) << 16);
-	v |= (mode->hsync_start - 8);	/* match xf86-video-radeon */
-	if (mode->flags & VID_NHSYNC)
-		v |= RADEON_CRTC_H_SYNC_POL;
-	PUT32(sc, hsyncstrt, v);
-	DPRINTF(("CRTC%s_H_SYNC_STRT_WID = %08x\n", crtc ? "2" : "", v));
-	if (fphsyncstrt) {
-		PUT32(sc, fphsyncstrt, v);
-		DPRINTF(("FP_H%s_SYNC_STRT_WID = %08x\n", crtc ? "2" : "", v));
-	}
+	hd = ((GET32(sc, htotaldisp) >> 16) + 1) * 8;
+	vd = (GET32(sc, vtotaldisp) >> 16) + 1;
+	DPRINTF(("res %d x %d\n", hd, vd));
 
-	/*
-	 * V_TOTAL_DISP
-	 */
-	v = ((mode->vdisplay - 1) << 16);
-	v |= (mode->vtotal - 1);
-	PUT32(sc, vtotaldisp, v);
-	DPRINTF(("CRTC%s_V_TOTAL_DISP = %08x\n", crtc ? "2" : "", v));
-	if (fpvtotaldisp) {
-		PUT32(sc, fpvtotaldisp, v);
-		DPRINTF(("FP_V%s_TOTAL_DISP = %08x\n", crtc ? "2" : "", v));
-	}
+	if ((hd != mode->hdisplay) || (vd != mode->vdisplay)) {
 
-	/*
-	 * V_SYNC_STRT_WID
-	 */
-	v = ((mode->vsync_end - mode->vsync_start) << 16);
-	v |= (mode->vsync_start - 1);
-	if (mode->flags & VID_NVSYNC)
-		v |= RADEON_CRTC_V_SYNC_POL;
-	PUT32(sc, vsyncstrt, v);
-	DPRINTF(("CRTC%s_V_SYNC_STRT_WID = %08x\n", crtc ? "2" : "", v));
-	if (fpvsyncstrt) {
-		PUT32(sc, fpvsyncstrt, v);
-		DPRINTF(("FP_V%s_SYNC_STRT_WID = %08x\n", crtc ? "2" : "", v));
-	}
+		/*
+		 * H_TOTAL_DISP
+		 */
+		v = ((mode->hdisplay / 8) - 1) << 16;
+		v |= (mode->htotal / 8) - 1;
+		PRINTREG(RADEON_CRTC_H_TOTAL_DISP);
+		PUT32(sc, htotaldisp, v);
+		DPRINTF(("CRTC%s_H_TOTAL_DISP = %08x\n", crtc ? "2" : "", v));
+		if (fphtotaldisp) {
+			PRINTREG(RADEON_FP_CRTC_H_TOTAL_DISP);
+			PUT32(sc, fphtotaldisp, v);
+			DPRINTF(("FP_H%s_TOTAL_DISP = %08x\n", crtc ? "2" : "", v));
+		}
+		/*
+		 * H_SYNC_STRT_WID
+		 */
+		v = (((mode->hsync_end - mode->hsync_start) / 8) << 16);
+		v |= (mode->hsync_start - 8);	/* match xf86-video-radeon */
+		if (mode->flags & VID_NHSYNC)
+			v |= RADEON_CRTC_H_SYNC_POL;
+		PUT32(sc, hsyncstrt, v);
+		DPRINTF(("CRTC%s_H_SYNC_STRT_WID = %08x\n", crtc ? "2" : "", v));
+		if (fphsyncstrt) {
+			PUT32(sc, fphsyncstrt, v);
+			DPRINTF(("FP_H%s_SYNC_STRT_WID = %08x\n", crtc ? "2" : "", v));
+		}
 
+		/*
+		 * V_TOTAL_DISP
+		 */
+		v = ((mode->vdisplay - 1) << 16);
+		v |= (mode->vtotal - 1);
+		PUT32(sc, vtotaldisp, v);
+		DPRINTF(("CRTC%s_V_TOTAL_DISP = %08x\n", crtc ? "2" : "", v));
+		if (fpvtotaldisp) {
+			PUT32(sc, fpvtotaldisp, v);
+			DPRINTF(("FP_V%s_TOTAL_DISP = %08x\n", crtc ? "2" : "", v));
+		}
+
+		/*
+		 * V_SYNC_STRT_WID
+		 */
+		v = ((mode->vsync_end - mode->vsync_start) << 16);
+		v |= (mode->vsync_start - 1);
+		if (mode->flags & VID_NVSYNC)
+			v |= RADEON_CRTC_V_SYNC_POL;
+		PUT32(sc, vsyncstrt, v);
+		DPRINTF(("CRTC%s_V_SYNC_STRT_WID = %08x\n", crtc ? "2" : "", v));
+		if (fpvsyncstrt) {
+			PUT32(sc, fpvsyncstrt, v);
+			DPRINTF(("FP_V%s_SYNC_STRT_WID = %08x\n", crtc ? "2" : "", v));
+		}
+	}
 	radeonfb_program_vclk(sc, mode->dot_clock, crtc, flags);
 
 	switch (crtc) {
@@ -2511,8 +2541,11 @@ radeonfb_setcrtc(struct radeonfb_display
 int
 radeonfb_isblank(struct radeonfb_display *dp)
 {
+	struct radeonfb_softc	*sc = dp->rd_softc;
 	uint32_t	reg, mask;
 
+	if (IS_AVIVO(sc)) return 0;
+
 	if(!dp->rd_softc->sc_mapped)
 		return 1;
 
@@ -2534,6 +2567,8 @@ radeonfb_blank(struct radeonfb_display *
 	uint32_t		fpreg, fpval;
 	int			i;
 
+	if(IS_AVIVO(sc)) return;
+
 	if (!sc->sc_mapped)
 		return;
 
@@ -2608,7 +2643,7 @@ radeonfb_init_screen(void *cookie, struc
 		ri->ri_flg |= RI_CLEAR;
 
 		/* start a modeswitch now */
-		radeonfb_modeswitch(dp);
+		//radeonfb_modeswitch(dp);
 	}
 
 	/*
@@ -2633,8 +2668,8 @@ radeonfb_init_screen(void *cookie, struc
 	/* pick a putchar method based on font and Radeon model */
 	if (ri->ri_font->stride < ri->ri_font->fontwidth) {
 		/* got a bitmap font */
-#ifndef RADEONFB_ALWAYS_ACCEL_PUTCHAR
-		if (IS_R300(dp->rd_softc)) {
+#if !defined(RADEONFB_ALWAYS_ACCEL_PUTCHAR)
+		if (IS_R300(dp->rd_softc) && 0) {
 			/*
 			 * radeonfb_putchar() doesn't work right on some R3xx
 			 * so we use software drawing here, the wrapper just
@@ -2663,39 +2698,70 @@ radeonfb_init_screen(void *cookie, struc
 	ri->ri_ops.cursor = radeonfb_cursor;
 }
 
+static uint32_t
+radeonfb_avivo_INMC(struct radeonfb_softc *sc, uint32_t addr)
+{
+	uint32_t data;
+
+	PUT32(sc, AVIVO_MC_INDEX, (addr & 0xff) | 0x7f0000);
+	(void)GET32(sc, AVIVO_MC_INDEX);
+	data = GET32(sc, AVIVO_MC_DATA);
+	PUT32(sc, AVIVO_MC_INDEX, 0);
+	(void)GET32(sc, AVIVO_MC_INDEX);
+	return data;
+}
+
+static void
+radeonfb_avivo_OUTMC(struct radeonfb_softc *sc, uint32_t addr, uint32_t data)
+{
+
+	PUT32(sc, AVIVO_MC_INDEX, (addr & 0xff) | 0x7f0000);
+	(void)GET32(sc, AVIVO_MC_INDEX);
+	PUT32(sc, AVIVO_MC_DATA, data);
+	PUT32(sc, AVIVO_MC_INDEX, 0);
+	(void)GET32(sc, AVIVO_MC_INDEX);
+}
+
 void
 radeonfb_set_fbloc(struct radeonfb_softc *sc)
 {
-	uint32_t	gen, ext, gen2 = 0;
+	uint32_t	gen = 0, ext = 0, gen2 = 0;
 	uint32_t	agploc, aperbase, apersize, mcfbloc;
 
-	gen = GET32(sc, RADEON_CRTC_GEN_CNTL);
-	/* XXX */
-	ext = GET32(sc, RADEON_CRTC_EXT_CNTL) & ~RADEON_CRTC_DISPLAY_DIS;
-	agploc = GET32(sc, RADEON_MC_AGP_LOCATION);
-	aperbase = GET32(sc, RADEON_CONFIG_APER_0_BASE);
-	apersize = GET32(sc, RADEON_CONFIG_APER_SIZE);
 
-	PUT32(sc, RADEON_CRTC_GEN_CNTL, gen | RADEON_CRTC_DISP_REQ_EN_B);
-	PUT32(sc, RADEON_CRTC_EXT_CNTL, ext | RADEON_CRTC_DISPLAY_DIS);
+	if (IS_AVIVO(sc)) {
+		agploc = radeonfb_avivo_INMC(sc, R520_MC_AGP_LOCATION);
+	} else {
+		gen = GET32(sc, RADEON_CRTC_GEN_CNTL);
+		/* XXX */
+		ext = GET32(sc, RADEON_CRTC_EXT_CNTL) & ~RADEON_CRTC_DISPLAY_DIS;
+		agploc = GET32(sc, RADEON_MC_AGP_LOCATION);
+		PUT32(sc, RADEON_CRTC_GEN_CNTL, gen | RADEON_CRTC_DISP_REQ_EN_B);
+		PUT32(sc, RADEON_CRTC_EXT_CNTL, ext | RADEON_CRTC_DISPLAY_DIS);
 #if 0
-	PUT32(sc, RADEON_CRTC_GEN_CNTL, gen | RADEON_CRTC_DISPLAY_DIS);
-	PUT32(sc, RADEON_CRTC_EXT_CNTL, ext | RADEON_CRTC_DISP_REQ_EN_B);
+		PUT32(sc, RADEON_CRTC_GEN_CNTL, gen | RADEON_CRTC_DISPLAY_DIS);
+		PUT32(sc, RADEON_CRTC_EXT_CNTL, ext | RADEON_CRTC_DISP_REQ_EN_B);
 #endif
 
-	if (HAS_CRTC2(sc)) {
-		gen2 = GET32(sc, RADEON_CRTC2_GEN_CNTL);
-		PUT32(sc, RADEON_CRTC2_GEN_CNTL, 
-		    gen2 | RADEON_CRTC2_DISP_REQ_EN_B);
+		if (HAS_CRTC2(sc)) {
+			gen2 = GET32(sc, RADEON_CRTC2_GEN_CNTL);
+			PUT32(sc, RADEON_CRTC2_GEN_CNTL, 
+			    gen2 | RADEON_CRTC2_DISP_REQ_EN_B);
+		}
+
+		delay(100000);
 	}
 
-	delay(100000);
+	aperbase = GET32(sc, RADEON_CONFIG_APER_0_BASE);
+	apersize = GET32(sc, RADEON_CONFIG_APER_SIZE);
+
 
 	mcfbloc = (aperbase >> 16) |
 	    ((aperbase + (apersize - 1)) & 0xffff0000);
 
 	sc->sc_aperbase = (mcfbloc & 0xffff) << 16;
 	sc->sc_memsz = apersize;
+	DPRINTF(("aperbase = %08x\n", aperbase));
 
 	if (((agploc & 0xffff) << 16) !=
 	    ((mcfbloc & 0xffff0000U) + 0x10000)) {
@@ -2705,32 +2771,36 @@ radeonfb_set_fbloc(struct radeonfb_softc
 
 	PUT32(sc, RADEON_HOST_PATH_CNTL, 0);
 
-	PUT32(sc, RADEON_MC_FB_LOCATION, mcfbloc);
-	PUT32(sc, RADEON_MC_AGP_LOCATION, agploc);
+	if (IS_AVIVO(sc)) {
+		radeonfb_avivo_OUTMC(sc, R520_MC_FB_LOCATION, mcfbloc);
+		radeonfb_avivo_OUTMC(sc, R520_MC_AGP_LOCATION, agploc);
+		PRINTREG(AVIVO_HDP_FB_LOCATION);
+		DPRINTF((" FB loc %08x\n", radeonfb_avivo_INMC(sc, R520_MC_FB_LOCATION)));
+		DPRINTF(("AGP loc %08x\n", radeonfb_avivo_INMC(sc, R520_MC_AGP_LOCATION)));
+	} else {
+		PUT32(sc, RADEON_MC_FB_LOCATION, mcfbloc);
+		PUT32(sc, RADEON_MC_AGP_LOCATION, agploc);
+		PRINTREG(RADEON_MC_FB_LOCATION);
+		PRINTREG(RADEON_MC_AGP_LOCATION);
 
-	DPRINTF(("aperbase = %u\n", aperbase));
-	PRINTREG(RADEON_MC_FB_LOCATION);
-	PRINTREG(RADEON_MC_AGP_LOCATION);
+		PUT32(sc, RADEON_DISPLAY_BASE_ADDR, sc->sc_aperbase);
 
-	PUT32(sc, RADEON_DISPLAY_BASE_ADDR, sc->sc_aperbase);
+		if (HAS_CRTC2(sc))
+			PUT32(sc, RADEON_DISPLAY2_BASE_ADDR, sc->sc_aperbase);
 
-	if (HAS_CRTC2(sc))
-		PUT32(sc, RADEON_DISPLAY2_BASE_ADDR, sc->sc_aperbase);
+		PUT32(sc, RADEON_OV0_BASE_ADDR, sc->sc_aperbase);
+		delay(100000);
 
-	PUT32(sc, RADEON_OV0_BASE_ADDR, sc->sc_aperbase);
+		PUT32(sc, RADEON_CRTC_GEN_CNTL, gen);
+		PUT32(sc, RADEON_CRTC_EXT_CNTL, ext);
 
+		if (HAS_CRTC2(sc))
+			PUT32(sc, RADEON_CRTC2_GEN_CNTL, gen2);
+	}
 #if 0
 	/* XXX: what is this AGP garbage? :-) */
 	PUT32(sc, RADEON_AGP_CNTL, 0x00100000);
 #endif
-
-	delay(100000);
-
-	PUT32(sc, RADEON_CRTC_GEN_CNTL, gen);
-	PUT32(sc, RADEON_CRTC_EXT_CNTL, ext);
-
-	if (HAS_CRTC2(sc))
-		PUT32(sc, RADEON_CRTC2_GEN_CNTL, gen2);
 }
 
 void
@@ -2775,24 +2845,43 @@ radeonfb_putpal(struct radeonfb_display 
 	int		crtc, cc;
 	uint32_t	vclk;
 
-	vclk = GETPLL(sc, RADEON_VCLK_ECP_CNTL);
-	PUTPLL(sc, RADEON_VCLK_ECP_CNTL, vclk & ~RADEON_PIXCLK_DAC_ALWAYS_ONb);
+	if (IS_AVIVO(sc)) {
+		for (cc = 0; cc < dp->rd_ncrtcs; cc++) {
+			crtc = dp->rd_crtcs[cc].rc_number;
 
-	/* initialize the palette for every CRTC used by this display */
-	for (cc = 0; cc < dp->rd_ncrtcs; cc++) {
-		crtc = dp->rd_crtcs[cc].rc_number;
+			if (crtc)
+				PUT32(sc, AVIVO_DC_LUT_RW_SELECT, 1);
+			else
+				PUT32(sc, AVIVO_DC_LUT_RW_SELECT, 0);
 
-		if (crtc)
-			SET32(sc, RADEON_DAC_CNTL2, RADEON_DAC2_PALETTE_ACC_CTL);
-		else
-			CLR32(sc, RADEON_DAC_CNTL2, RADEON_DAC2_PALETTE_ACC_CTL);
+			PUT32(sc, AVIVO_DC_LUT_RW_INDEX, idx);
+	            	PUT32(sc, AVIVO_DC_LUT_30_COLOR,
+	            	    (r << 22) | (g << 12) | (b << 2));
+		}
+		
+	} else {
+		vclk = GETPLL(sc, RADEON_VCLK_ECP_CNTL);
+		PUTPLL(sc, RADEON_VCLK_ECP_CNTL,
+		    vclk & ~RADEON_PIXCLK_DAC_ALWAYS_ONb);
+
+		/* init the palette for every CRTC used by this display */
+		for (cc = 0; cc < dp->rd_ncrtcs; cc++) {
+			crtc = dp->rd_crtcs[cc].rc_number;
+
+			if (crtc)
+				SET32(sc, RADEON_DAC_CNTL2,
+				    RADEON_DAC2_PALETTE_ACC_CTL);
+			else
+				CLR32(sc, RADEON_DAC_CNTL2,
+				    RADEON_DAC2_PALETTE_ACC_CTL);
 
-		PUT32(sc, RADEON_PALETTE_INDEX, idx);
-            	PUT32(sc, RADEON_PALETTE_30_DATA,
-            	    (r << 22) | (g << 12) | (b << 2));
-	}
+			PUT32(sc, RADEON_PALETTE_INDEX, idx);
+	            	PUT32(sc, RADEON_PALETTE_30_DATA,
+	            	    (r << 22) | (g << 12) | (b << 2));
+		}
 
-	PUTPLL(sc, RADEON_VCLK_ECP_CNTL, vclk);
+		PUTPLL(sc, RADEON_VCLK_ECP_CNTL, vclk);
+	}
 }
 
 /*
@@ -3466,7 +3555,7 @@ radeonfb_bitblt(void *cookie, int srcx, 
 	radeonfb_wait_fifo(sc, 6);
 
 	PUT32(sc, RADEON_DP_GUI_MASTER_CNTL,
-	    RADEON_GMC_BRUSH_SOLID_COLOR |
+	    RADEON_GMC_BRUSH_NONE |
 	    RADEON_GMC_SRC_DATATYPE_COLOR |
 	    RADEON_GMC_CLR_CMP_CNTL_DIS |
 	    RADEON_DP_SRC_SOURCE_MEMORY |
@@ -3499,7 +3588,7 @@ radeonfb_wait_fifo(struct radeonfb_softc
 			RADEON_RBBM_FIFOCNT_MASK) >= n)
 			return;
 	}
-#ifdef	DIAGNOSTIC
+#ifdef	RADEONFB_DEBUG
 	if (!i)
 		printf("%s: timed out waiting for fifo (%x)\n",
 		    XNAME(sc), GET32(sc, RADEON_RBBM_STATUS));
@@ -3511,7 +3600,7 @@ radeonfb_engine_flush(struct radeonfb_so
 {
 	int	i = 0;
 
-	if (IS_R300(sc)) {
+	if (IS_R300(sc) || IS_AVIVO(sc)) {
 		SET32(sc, R300_DSTCACHE_CTLSTAT, R300_RB2D_DC_FLUSH_ALL);
 		while (GET32(sc, R300_DSTCACHE_CTLSTAT) & R300_RB2D_DC_BUSY) {
 			i++;
@@ -3548,22 +3637,60 @@ radeonfb_engine_init(struct radeonfb_dis
 	/* no 3D */
 	PUT32(sc, RADEON_RB3D_CNTL, 0);
 
+	if (IS_AVIVO(sc)) {
+
+#if 0
+		/* XXX the xf86-video-radeon does this, causes lockups here */
+		psel = GET32(sc, R400_GB_PIPE_SELECT);
+		PRINTREG(R400_GB_PIPE_SELECT);
+		DPRINTF(("PLL %08x %08x\n", GETPLL(sc, R500_DYN_SCLK_PWMEM_PIPE),
+		    (1 | ((psel >> 8) & 0xf) << 4)));
+		PUTPLL(sc, R500_DYN_SCLK_PWMEM_PIPE, (1 | ((psel >> 8) & 0xf) << 4));
+#endif
+		SET32(sc, RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
+		SET32(sc, R300_DST_PIPE_CONFIG, R300_PIPE_AUTO_CONFIG);
+		SET32(sc, R300_RB2D_DSTCACHE_MODE, R300_DC_AUTOFLUSH_ENABLE |
+					     R300_DC_DC_DISABLE_IGNORE_PE);
+	}
+
+	PRINTREG(RADEON_RB3D_CNTL);
+	PRINTREG(RADEON_DP_GUI_MASTER_CNTL);
+	PRINTREG(RADEON_RBBM_STATUS);
+
 	radeonfb_engine_reset(sc);
-	pitch = ((dp->rd_virtx * (dp->rd_bpp / 8) + 0x3f)) >> 6;
+	PRINTREG(RADEON_RBBM_STATUS);
+
+	/*
+	 * Apple OF hands us some radeons with tiling enabled - explicitly
+	 * disable it here
+	 */
+	PUT32(sc, RADEON_SURFACE_CNTL, RADEON_SURF_TRANSLATION_DIS);
 
 	radeonfb_wait_fifo(sc, 1);
-	if (!IS_R300(sc))
+	if (!IS_R300(sc) && !IS_AVIVO(sc))
 		PUT32(sc, RADEON_RB2D_DSTCACHE_MODE, 0);
 
 	radeonfb_wait_fifo(sc, 3);
-	PUT32(sc, RADEON_DEFAULT_PITCH_OFFSET,
-	    (pitch << 22) | (sc->sc_aperbase >> 10));
 
+	/*
+	 * XXX
+	 * I strongly suspect this works mostly by accident on !AVIVO
+	 * AVIVO uses all 22 bits for the framebuffer offset, so it can
+	 * address up to 4GB. Older chips probably use bits 20-22 for other
+	 * things and we just so happen to set the right ones by having our
+	 * PCI/AGP space above 0x80000000.
+	 * Either way, r5xx does not work if we set these bits, while older
+	 * chips don't work without.
+	 */
+	pitch = (dp->rd_stride + 0x3f) >> 6;
+	if (IS_AVIVO(sc)) {
+		pitch = pitch << 22;
+	} else
+		pitch = (pitch << 22) | (sc->sc_aperbase >> 10);
 
-	PUT32(sc, RADEON_DST_PITCH_OFFSET,
-	    (pitch << 22) | (sc->sc_aperbase >> 10));
-	PUT32(sc, RADEON_SRC_PITCH_OFFSET,
-	    (pitch << 22) | (sc->sc_aperbase >> 10));
+	PUT32(sc, RADEON_DEFAULT_PITCH_OFFSET, pitch);
+	PUT32(sc, RADEON_DST_PITCH_OFFSET, pitch);
+	PUT32(sc, RADEON_SRC_PITCH_OFFSET, pitch);
 
 	(void)GET32(sc, RADEON_DP_DATATYPE);
 
@@ -3613,7 +3740,7 @@ radeonfb_engine_reset(struct radeonfb_so
 
 	hpc = GET32(sc, RADEON_HOST_PATH_CNTL);
 	rbbm = GET32(sc, RADEON_RBBM_SOFT_RESET);
-	if (IS_R300(sc)) {
+	if (IS_R300(sc) || IS_AVIVO(sc)) {
 		PUT32(sc, RADEON_RBBM_SOFT_RESET, rbbm |
 		    RADEON_SOFT_RESET_CP |
 		    RADEON_SOFT_RESET_HI |
@@ -3624,7 +3751,7 @@ radeonfb_engine_reset(struct radeonfb_so
 		 * XXX: this bit is not defined in any ATI docs I have,
 		 * nor in the XFree code, but XFree does it.  Why?
 		 */
-		SET32(sc, RADEON_RB2D_DSTCACHE_MODE, (1<<17));
+		SET32(sc, RADEON_RB2D_DSTCACHE_MODE, R300_DC_DC_DISABLE_IGNORE_PE);
 	} else {
 		PUT32(sc, RADEON_RBBM_SOFT_RESET, rbbm |
 		    RADEON_SOFT_RESET_CP |
@@ -3648,7 +3775,7 @@ radeonfb_engine_reset(struct radeonfb_so
 	GET32(sc, RADEON_HOST_PATH_CNTL);
 	PUT32(sc, RADEON_HOST_PATH_CNTL, hpc);
 
-	if (IS_R300(sc))
+	if (!IS_R300(sc) && !IS_AVIVO(sc))
 		PUT32(sc, RADEON_RBBM_SOFT_RESET, rbbm);
 
 	PUT32(sc, RADEON_CLOCK_CNTL_INDEX, clkindex);
@@ -3878,13 +4005,52 @@ radeonfb_cursor_shape(struct radeonfb_di
 	}
 }
 
+/*
+ * We use the cursor in 24bit mode on avivo, much simpler than the above.
+ * Should probably do the same on older radeons
+ */
+static void
+radeonfb_avivo_cursor_shape(struct radeonfb_display *dp)
+{
+	const uint8_t	*msk = dp->rd_cursor.rc_mask;
+	const uint8_t	*img = dp->rd_cursor.rc_image;
+	uint32_t 	*out = (uint32_t *)dp->rd_curptr;
+	uint8_t		bit;
+	int 		i, j, px;
+
+	for (i = 0; i < 64 * 8; i++) {
+		bit = 0x01;
+		for (j = 0; j < 8; j++) {
+			px = ((*msk & bit) ? 2 : 0) | ((*img & bit) ? 1 : 0);
+			switch (px) {
+				case 0:
+				case 1:
+					*out = htole32(0x00000000);
+					break;
+				case 2:
+					*out = htole32(0xff000000 |
+						  dp->rd_cursor.rc_cmap[0]);
+					break;
+				case 3:
+					*out = htole32(0xff000000 |
+						  dp->rd_cursor.rc_cmap[1]);
+					break;
+			}		
+			out++;
+			bit = bit << 1;
+		}
+		msk++;
+		img++;
+	}
+}
+
 static void
 radeonfb_cursor_position(struct radeonfb_display *dp)
 {
 	struct radeonfb_softc	*sc = dp->rd_softc;
 	uint32_t		offset, hvoff, hvpos;	/* registers */
 	uint32_t		coff;			/* cursor offset */
-	int			i, x, y, xoff, yoff, crtcoff;
+	int			i, x, y, xoff, yoff, crtcoff, lock;
 
 	/*
 	 * XXX: this also needs to handle pan/scan
@@ -3893,16 +4059,34 @@ radeonfb_cursor_position(struct radeonfb
 
 		struct radeonfb_crtc	*rcp = &dp->rd_crtcs[i];
 
-		if (rcp->rc_number) {
-			offset = RADEON_CUR2_OFFSET;
-			hvoff = RADEON_CUR2_HORZ_VERT_OFF;
-			hvpos = RADEON_CUR2_HORZ_VERT_POSN;
-			crtcoff = RADEON_CRTC2_OFFSET;
+		SET32(sc, AVIVO_D1CUR_UPDATE, AVIVO_D1CURSOR_UPDATE_LOCK);
+		PUT32(sc, AVIVO_D1CUR_SIZE, 0x003f003f);
+		if (IS_AVIVO(sc)) {
+			if (rcp->rc_number) {
+				offset = AVIVO_D2CUR_SURFACE_ADDRESS;
+				hvoff = AVIVO_D2CUR_HOT_SPOT;
+				hvpos = AVIVO_D2CUR_POSITION;
+				crtcoff = 0/*RADEON_CRTC_OFFSET*/;
+			} else {
+				offset = AVIVO_D1CUR_SURFACE_ADDRESS;
+				hvoff = AVIVO_D1CUR_HOT_SPOT;
+				hvpos = AVIVO_D1CUR_POSITION;
+				crtcoff = 0/*RADEON_CRTC_OFFSET*/;
+			}
+			lock = 0;
 		} else {
-			offset = RADEON_CUR_OFFSET;
-			hvoff = RADEON_CUR_HORZ_VERT_OFF;
-			hvpos = RADEON_CUR_HORZ_VERT_POSN;
-			crtcoff = RADEON_CRTC_OFFSET;
+			if (rcp->rc_number) {
+				offset = RADEON_CUR2_OFFSET;
+				hvoff = RADEON_CUR2_HORZ_VERT_OFF;
+				hvpos = RADEON_CUR2_HORZ_VERT_POSN;
+				crtcoff = RADEON_CRTC2_OFFSET;
+			} else {
+				offset = RADEON_CUR_OFFSET;
+				hvoff = RADEON_CUR_HORZ_VERT_OFF;
+				hvpos = RADEON_CUR_HORZ_VERT_POSN;
+				crtcoff = RADEON_CRTC_OFFSET;
+			}
+			lock = RADEON_CUR_LOCK;
 		}
 
 		x = dp->rd_cursor.rc_pos.x;
@@ -3951,35 +4135,52 @@ radeonfb_cursor_position(struct radeonfb
 		}
 
 		/* pan the display */
-		PUT32(sc, crtcoff, (rcp->rc_yoffset * dp->rd_stride) +
-		    rcp->rc_xoffset);
+		if (crtcoff != 0)
+			PUT32(sc, crtcoff, (rcp->rc_yoffset * dp->rd_stride) +
+			    rcp->rc_xoffset);
 
-		PUT32(sc, offset, (dp->rd_curoff + coff) | RADEON_CUR_LOCK);
-		PUT32(sc, hvoff, (xoff << 16) | (yoff) | RADEON_CUR_LOCK);
+		PUT32(sc, offset, (dp->rd_curoff + coff) | lock);
+		PUT32(sc, hvoff, (xoff << 16) | (yoff) | lock);
 		/* NB: this unlocks the cursor */
 		PUT32(sc, hvpos, (x << 16) | y);
+		if (IS_AVIVO(sc))
+			CLR32(sc, AVIVO_D1CUR_UPDATE, AVIVO_D1CURSOR_UPDATE_LOCK);
 	}
 }
 
 static void
 radeonfb_cursor_visible(struct radeonfb_display *dp)
 {
+	struct radeonfb_softc	*sc = dp->rd_softc;
 	int		i;
 	uint32_t	gencntl, bit;
 
 	for (i = 0; i < dp->rd_ncrtcs; i++) {
-		if (dp->rd_crtcs[i].rc_number) {
-			gencntl = RADEON_CRTC2_GEN_CNTL;
-			bit = RADEON_CRTC2_CUR_EN;
+		if (IS_AVIVO(sc)) {
+			SET32(sc, AVIVO_D1CUR_UPDATE, AVIVO_D1CURSOR_UPDATE_LOCK);
+			if (dp->rd_crtcs[i].rc_number) {
+				gencntl = AVIVO_D2CUR_CONTROL;
+				bit = AVIVO_D1CURSOR_EN | (2 << 8);
+			} else {
+				gencntl = AVIVO_D1CUR_CONTROL;
+				bit = AVIVO_D1CURSOR_EN | (2 << 8);
+			}
 		} else {
-			gencntl = RADEON_CRTC_GEN_CNTL;
-			bit = RADEON_CRTC_CUR_EN;
+			if (dp->rd_crtcs[i].rc_number) {
+				gencntl = RADEON_CRTC2_GEN_CNTL;
+				bit = RADEON_CRTC2_CUR_EN;
+			} else {
+				gencntl = RADEON_CRTC_GEN_CNTL;
+				bit = RADEON_CRTC_CUR_EN;
+			}
 		}
-		
 		if (dp->rd_cursor.rc_visible)
 			SET32(dp->rd_softc, gencntl, bit);
 		else
 			CLR32(dp->rd_softc, gencntl, bit);
+		if (IS_AVIVO(sc))
+			CLR32(sc, AVIVO_D1CUR_UPDATE, AVIVO_D1CURSOR_UPDATE_LOCK);
+		
 	}
 }
 
@@ -4011,20 +4212,39 @@ radeonfb_cursor_update(struct radeonfb_d
 	int		i;
 
 	sc = dp->rd_softc;
+	
 	for (i = 0; i < dp->rd_ncrtcs; i++) {
 		if (dp->rd_crtcs[i].rc_number) {
-			SET32(sc, RADEON_CUR2_OFFSET, RADEON_CUR_LOCK);
+			if (IS_AVIVO(sc)) {
+				SET32(sc, AVIVO_D2CUR_UPDATE, AVIVO_D1CURSOR_UPDATE_LOCK);
+			} else
+				SET32(sc, RADEON_CUR2_OFFSET, RADEON_CUR_LOCK);
 		} else {
-			SET32(sc, RADEON_CUR_OFFSET,RADEON_CUR_LOCK);
+			if (IS_AVIVO(sc)) {
+				SET32(sc, AVIVO_D1CUR_UPDATE, AVIVO_D1CURSOR_UPDATE_LOCK);
+			} else
+				SET32(sc, RADEON_CUR_OFFSET,RADEON_CUR_LOCK);
 		}
 	}
 
-	if (which & WSDISPLAY_CURSOR_DOCMAP)
-		radeonfb_cursor_cmap(dp);
-
-	if (which & WSDISPLAY_CURSOR_DOSHAPE)
-		radeonfb_cursor_shape(dp);
+	if (which & WSDISPLAY_CURSOR_DOCMAP) {
+		if (IS_AVIVO(sc)) {
+			/*
+			 * we use an ARGB cursor here, so we need to rebuild
+			 * the cursor image every time the palette changes
+			 */
+			radeonfb_avivo_cursor_shape(dp);
+		} else
+			radeonfb_cursor_cmap(dp);
+	}
 
+	if (which & WSDISPLAY_CURSOR_DOSHAPE) {
+		if (IS_AVIVO(sc)) {
+			radeonfb_avivo_cursor_shape(dp);
+		} else
+			radeonfb_cursor_shape(dp);
+	}
+	
 	if (which & WSDISPLAY_CURSOR_DOCUR)
 		radeonfb_cursor_visible(dp);
 
@@ -4336,7 +4556,7 @@ radeonfb_set_backlight(struct radeonfb_d
 	rlevel = level;
 
 	callout_stop(&dp->rd_bl_lvds_co);
-	radeonfb_engine_idle(sc);
+	//radeonfb_engine_idle(sc);
 
 	/* 
 	 * Turn off the display if the backlight is set to 0, since the

Index: src/sys/dev/pci/radeonfbvar.h
diff -u src/sys/dev/pci/radeonfbvar.h:1.21 src/sys/dev/pci/radeonfbvar.h:1.22
--- src/sys/dev/pci/radeonfbvar.h:1.21	Thu Jun 11 14:22:10 2020
+++ src/sys/dev/pci/radeonfbvar.h	Mon Sep 28 05:43:58 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: radeonfbvar.h,v 1.21 2020/06/11 14:22:10 macallan Exp $ */
+/* $NetBSD: radeonfbvar.h,v 1.22 2020/09/28 05:43:58 macallan Exp $ */
 
 /*-
  * Copyright (c) 2006 Itronix Inc.
@@ -293,7 +293,8 @@ struct radeonfb_softc {
 #define	RADEON_RV350	12
 #define	RADEON_RV380	13
 #define	RADEON_R420	14
-#define	RADEON_FAMILIES	15
+#define RADEON_R580	15
+#define	RADEON_FAMILIES	16
 
 /* feature flags */
 #define	RFB_MOB		(1 << 0)	/* Mobility */
@@ -305,6 +306,7 @@ struct radeonfb_softc {
 #define	RFB_RV100	(1 << 6)	/* RV100 variants -- previous gen */
 #define	RFB_ATOM	(1 << 7)	/* ATOM bios */
 #define RFB_INV_BLIGHT	(1 << 8)	/* backlight level inverted */
+#define RFB_IS_AVIVO	(1 << 9)	/* MC and CRTCs are different here */
 
 #define	IS_MOBILITY(sc)	((sc)->sc_flags & RFB_MOB)
 #define	HAS_CRTC2(sc)	(((sc)->sc_flags & RFB_NCRTC2) == 0)
@@ -315,6 +317,7 @@ struct radeonfb_softc {
 #define	IS_RV100(sc)	((sc)->sc_flags & RFB_RV100)
 #define	IS_IGP(sc)	((sc)->sc_flags & RFB_IGP)
 #define	IS_ATOM(sc)	((sc)->sc_flags & RFB_ATOM)
+#define	IS_AVIVO(sc)	((sc)->sc_flags & RFB_IS_AVIVO)
 
 #define	RADEON_TIMEOUT	2000000
 

Reply via email to