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