Problem with xorg-server and s3c2410fb driver
Michel Dänzer
michel at daenzer.net
Mon Aug 2 09:24:53 PDT 2010
On Mon, 2010-08-02 at 11:51 -0400, Adam Jackson wrote:
> On Mon, 2010-08-02 at 15:59 +0200, Michel Dänzer wrote:
> > On Son, 2010-07-25 at 09:35 +0300, Vasily Khoruzhick wrote:
> > > Hi,
> > >
> > > I'm trying to get xorg-server + xf86-video-fbdev working on my device, and I'm
> > > hitting problem:
> > >
> > > pixclock value of fb mode on my device is 260000 picosecs, and due to picosecs
> > > <-> khz conversions in xorg-server I'm getting rounding error:
> > >
> > > 1000000000 / 260000 = 3846
> > > 1000000000 / 3846 = 260010
> > >
> > > (Look through xfree2fbdev_timing and fbdev2xfree_timing functions in fbdevhw.c
> > > for more details)
> > >
> > > xorg-server gets mode via FBOIGET_VSCREENINFO (pixclock = 260000), converts it
> > > to its own format, then converts it back to fbmode (due to rounding error
> > > pixclock - 260010) and then tries to set mode with pixvalue 260010 via
> > > FBIOPUT_VSCREENINFO ioctl, but driver sets it back to 260000, and xorg-server
> > > fails to startup with this message:
> > >
> > > (EE) FBDEV(0): FBIOPUT_VSCREENINFO succeeded but modified mode.
> >
> > What version of xserver are you using? It sounds like your problem
> > should be fixed by Git commit bf333c2f9833a178887e7bdd7fc338f1e09c387f
> > ('fbdevhw: Remove pixclock check.') which should be included since 1.6.x
> > at least.
>
> bf333c2 is kind of gross. Seems like the right thing is to revert it
> and then apply:
>
> ------
> From: Adam Jackson <ajax at redhat.com>
> Date: Mon, 2 Aug 2010 11:48:22 -0400
> Subject: [PATCH] fbdevhw: Avoid rounding error from psec/kHz conversion
>
> Stash the real fbdev clock in mode->PrivFlags and use that for actual
> mode set calls. ->Clock is then only used for display in the log.
>
> Signed-off-by: Adam Jackson <ajax at redhat.com>
> ---
> hw/xfree86/fbdevhw/fbdevhw.c | 3 ++-
> 1 files changed, 2 insertions(+), 1 deletions(-)
>
> diff --git a/hw/xfree86/fbdevhw/fbdevhw.c b/hw/xfree86/fbdevhw/fbdevhw.c
> index f160908..3a6df94 100644
> --- a/hw/xfree86/fbdevhw/fbdevhw.c
> +++ b/hw/xfree86/fbdevhw/fbdevhw.c
> @@ -201,7 +201,7 @@ xfree2fbdev_timing(DisplayModePtr mode, struct fb_var_screeninfo *var)
> if (var->yres_virtual < var->yres)
> var->yres_virtual = var->yres;
> var->xoffset = var->yoffset = 0;
> - var->pixclock = mode->Clock ? 1000000000/mode->Clock : 0;
> + var->pixclock = mode->PrivFlags;
> var->right_margin = mode->HSyncStart-mode->HDisplay;
> var->hsync_len = mode->HSyncEnd-mode->HSyncStart;
> var->left_margin = mode->HTotal-mode->HSyncEnd;
> @@ -267,6 +267,7 @@ fbdev2xfree_timing(struct fb_var_screeninfo *var, DisplayModePtr mode)
> else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
> mode->Flags |= V_DBLSCAN;
> mode->SynthClock = mode->Clock;
> + mode->PrivFlags = var->pixclock;
> mode->CrtcHDisplay = mode->HDisplay;
> mode->CrtcHSyncStart = mode->HSyncStart;
> mode->CrtcHSyncEnd = mode->HSyncEnd;
AFAICT this will only work when using the 'built-in' mode, otherwise
mode->PrivFlags will never be set? One possible solution for that could
be
- var->pixclock = mode->Clock ? 1000000000/mode->Clock : 0;
+ var->pixclock = mode->PrivFlags ? mode->PrivFlags :
(mode->Clock ? 1000000000/mode->Clock : 0);
in xfree2fbdev_timing().
--
Earthling Michel Dänzer | http://www.vmware.com
Libre software enthusiast | Debian, X and DRI developer
More information about the xorg
mailing list