* "ACCEL_MMIO" ifdef branches in XFree86
* --dte
*/
+
+static void radeon_fixup_offset(struct radeonfb_info *rinfo)
+{
+ u32 local_base;
+
+ /* *** Ugly workaround *** */
+ /*
+ * On some platforms, the video memory is mapped at 0 in radeon chip space
+ * (like PPCs) by the firmware. X will always move it up so that it's seen
+ * by the chip to be at the same address as the PCI BAR.
+ * That means that when switching back from X, there is a mismatch between
+ * the offsets programmed into the engine. This means that potentially,
+ * accel operations done before radeonfb has a chance to re-init the engine
+ * will have incorrect offsets, and potentially trash system memory !
+ *
+ * The correct fix is for fbcon to never call any accel op before the engine
+ * has properly been re-initialized (by a call to set_var), but this is a
+ * complex fix. This workaround in the meantime, called before every accel
+ * operation, makes sure the offsets are in sync.
+ */
+
+ radeon_fifo_wait (1);
+ local_base = INREG(MC_FB_LOCATION) << 16;
+ if (local_base == rinfo->fb_local_base)
+ return;
+
+ rinfo->fb_local_base = local_base;
+
+ radeon_fifo_wait (3);
+ OUTREG(DEFAULT_PITCH_OFFSET, (rinfo->pitch << 0x16) |
+ (rinfo->fb_local_base >> 10));
+ OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
+ OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
+}
+
static void radeonfb_prim_fillrect(struct radeonfb_info *rinfo,
const struct fb_fillrect *region)
{
return;
}
+ radeon_fixup_offset(rinfo);
+
vxres = info->var.xres_virtual;
vyres = info->var.yres_virtual;
return;
}
+ radeon_fixup_offset(rinfo);
+
vxres = info->var.xres_virtual;
vyres = info->var.yres_virtual;
radeon_engine_flush (rinfo);
- /* Some ASICs have bugs with dynamic-on feature, which are
- * ASIC-version dependent, so we force all blocks on for now
- * -- from XFree86
- * We don't do that on macs, things just work here with dynamic
- * clocking... --BenH
- */
-#ifdef CONFIG_ALL_PPC
- if (_machine != _MACH_Pmac && rinfo->hasCRTC2)
-#else
- if (rinfo->has_CRTC2)
-#endif
- {
- u32 tmp;
-
- tmp = INPLL(SCLK_CNTL);
- OUTPLL(SCLK_CNTL, ((tmp & ~DYN_STOP_LAT_MASK) |
- CP_MAX_DYN_STOP_LAT |
- SCLK_FORCEON_MASK));
-
- if (rinfo->family == CHIP_FAMILY_RV200)
- {
- tmp = INPLL(SCLK_MORE_CNTL);
- OUTPLL(SCLK_MORE_CNTL, tmp | SCLK_MORE_FORCEON);
- }
- }
-
clock_cntl_index = INREG(CLOCK_CNTL_INDEX);
mclk_cntl = INPLL(MCLK_CNTL);
OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index);
OUTPLL(MCLK_CNTL, mclk_cntl);
- if (rinfo->R300_cg_workaround)
- R300_cg_workardound(rinfo);
}
void radeonfb_engine_init (struct radeonfb_info *rinfo)