ALT Linux Bugzilla – #1837
radeonfb broken in kernel24-2.4.20-alt0.8-up
Last modified: 2003-11-14 15:59:21
You need to
before you can comment on or make changes to this bug.
The radeonfb driver in kernel24-2.4.20-alt0.8-up is broken. It gives
garbage on the screen when doing many operations (browsing text files
with \'less\', editing the command line, ...). Even clearing the screen
does not work - it leaves some garbage (and sometimes does not clear
anything at all).
Looking at the source, I have found several problems (and tried to fix
them - the patch is attached):
1. A very common bug (it is also present in the aty128fb driver - see
#992; also likely to be present in clgenfb, pm2fb, tdfxfb, tridentfb,
sisfb): putting fbcon_cfb* functions directly into the display_switch
structure when some other functions use the accelerator. This does not
work correctly - radeon_engine_idle() must always be called before
directly accessing the framebuffer memory (which fbcon_cfb* functions
I have added wrappers for all fbcon_cfb* functions which call
2. A similar bug: missing fb_rasterimg handler (which should wait for
the accelerator operations to complete). I have added such handler to
3. radeon_engine_init() was not called after changing the video mode,
therefore the accelerated functions did not work after fbset. I have
added call to radeon_engine_init() in radeonfb_set_var(), after
4. The accelerator initialization sequence in radeon_engine_init() has a
nasty bug: OUTREG(DSTCACHE_MODE, 0) does not do what is expected because
the value of DSTCACHE_MODE is wrong - so a write into some unrelated
register is performed, and this screws up even X (started when the
framebuffer driver is active).
I have added the correct define RB2D_DSTCACHE_MODE (taken from the
XFree86 radeon driver).
5. The accelerator reset sequence in _radeon_engine_reset() also did not
work: after X was started, the correct framebuffer display could not be
restored (the result was either a blank screen or some garbage). I have
noticed that the XFree86 radeon driver does the reset differently (it
contains a comment stating that resetting HDP thru RBBM_SOFT_RESET does
not work). I have implemented the same reset sequence as in the XFree86
driver - this fixed the problem.
This bug did not show up until the problem 3 above was corrected,
because the accelerator reset was not performed except during the module
6. The initialization of DEFAULT_PITCH_OFFSET in radeon_engine_init()
was causing problems. After fixing the previously mentioned bugs, the
driver mostly worked without X, but after starting X and switching back
to the console the machine crashed and rebooted after starting \'less\'
and displaying about two pages of text. (This problem also did not show
up until fixing the problem 3 above, for the same reason.)
I have replaced the initialization of DEFAULT_PITCH_OFFSET with the code
taken from the XFree86 radeon driver (which, BTW, also contains the same
old code, but commented out with #if 0); this fixed the problem.
7. After changing the video mode with fbset (setting some other
resolution) the screen sometimes was not updated properly (showing the
previous contents of the screen, but as garbage due to changed line
length). The problem was that radeonfb_set_var() called info->changevar
too early - before actually setting the video mode and updating the
accelerator state. Because of this, the update_screen() call inside the
changevar handler could not redraw the console contents.
I have moved the call to info->changevar to the proper place - after the
video mode setup.
8. After modifying the video mode with fbset without changing the
resolution (e.g., \'fbset -move left\' or something similar - so that the
screen size will not change) the screen offset was not updated properly.
Example: press Enter enough times so that the screen will be scrolled,
then run \'fbset -move left\' - the top of the scrollback buffer will be
shown instead of the expected screen contents.
There were several things involved here:
- radeonfb_set_var() did not handle var->xoffset and var->yoffset
fields properly - in fact, they were ignored completely, and
CRTC_OFFSET was set to 0. I have added the call to
radeonfb_pan_display() after radeon_load_video_mode() to set the
screen offset properly.
- radeonfb_set_var() did not check var->yoffset when determining if
info->changevar should be called (according to the code in fbgen.c,
this field should be compared with the old value). I have added the
needed check to the calculation of chgvar.
- radeonfb_pan_display() did not save the specified var->xoffset and
var->yoffset values anywhere, except writing them to the chip (in
fact, xoffset was not implemented at all). Because of this, the
above comparison in radeonfb_set_var() did not work, and
radeonfb_get_var() did not return the correct offset values. I have
added the code to save the offsets, and also added support for
xoffset (it is needed for XFree86 when using the UseFBDev option).
9. I also have performed several minor fixes:
- Added call to radeon_engine_init() in _radeon_fifo_wait() and
_radeon_engine_idle(), if the operation is timed out (the XFree86
driver does this to try to recover from accelerator lockup).
- Removed an unused dp_cntl = DST_LAST_PEL from fbcon_radeon_bmove().
- Added apparently missing rinfo->ram.tr2w = 1 to the SDR SGRAM memory
The changes were tested with the Gigabyte GV-AP64D card (Radeon 8500LE
[QL], 64M DDR SDRAM), both in the console-only mode and together with X
(with the accelerated \"radeon_gatos\" driver, with and without UseFBDev,
but without DRI).
Working together with DRI support in X was _not_ tested.
fixed long ago (radeonfb is broken again in 2.4.22, but that is a separate