Hi, I've hit a snag and I'm not really sure how to debug it.
Both xf86-video-glint/src/pm3_dac.c:Permedia3Init and kernel/drivers/video/pm3fb.c:pm3fb_write_mode set the mode in virtually identical ways. I'm trying to do the same, but I think some of what I'm passing in from drm_display_mode is wrong, specifically
WREG32(PM3HTotal, glint_shift_bpp(bpp, mode->htotal - 1)); WREG32(PM3HsEnd, glint_shift_bpp(bpp, mode->hsync_end - mode->hdisplay)); WREG32(PM3HsStart, glint_shift_bpp(bpp, mode->hsync_start - mode->hdisplay)); WREG32(PM3HbEnd, glint_shift_bpp(bpp, mode->htotal - mode->hdisplay)); WREG32(PM3HgEnd, glint_shift_bpp(bpp, mode->htotal - mode->hdisplay)); WREG32(PM3ScreenStride, glint_shift_bpp(bpp, crtc->fb->width)); WREG32(PM3VTotal, glint_shift_bpp(bpp, mode->vtotal - 1)); WREG32(PM3VsEnd, glint_shift_bpp(bpp, mode->vsync_end - 1)); WREG32(PM3VsStart, glint_shift_bpp(bpp, mode->vsync_start - 1)); WREG32(PM3VbEnd, glint_shift_bpp(bpp, mode->vtotal - mode->vdisplay));
I printed the values that xf86-video-glint passes through here, and of course they don't match with anything my driver has. I imagine guess it's because they're all resolution-dependent?
Can anyone give me some advice?
Thanks, Matt
On Thu, 2010-08-05 at 12:16 -0400, Matt Turner wrote:
Hi, I've hit a snag and I'm not really sure how to debug it.
Both xf86-video-glint/src/pm3_dac.c:Permedia3Init and kernel/drivers/video/pm3fb.c:pm3fb_write_mode set the mode in virtually identical ways. I'm trying to do the same, but I think some of what I'm passing in from drm_display_mode is wrong, specifically
WREG32(PM3HTotal, glint_shift_bpp(bpp, mode->htotal - 1)); WREG32(PM3HsEnd, glint_shift_bpp(bpp, mode->hsync_end - mode->hdisplay)); WREG32(PM3HsStart, glint_shift_bpp(bpp, mode->hsync_start - mode->hdisplay)); WREG32(PM3HbEnd, glint_shift_bpp(bpp, mode->htotal - mode->hdisplay)); WREG32(PM3HgEnd, glint_shift_bpp(bpp, mode->htotal - mode->hdisplay)); WREG32(PM3ScreenStride, glint_shift_bpp(bpp, crtc->fb->width)); WREG32(PM3VTotal, glint_shift_bpp(bpp, mode->vtotal - 1)); WREG32(PM3VsEnd, glint_shift_bpp(bpp, mode->vsync_end - 1)); WREG32(PM3VsStart, glint_shift_bpp(bpp, mode->vsync_start - 1)); WREG32(PM3VbEnd, glint_shift_bpp(bpp, mode->vtotal - mode->vdisplay));
I printed the values that xf86-video-glint passes through here, and of course they don't match with anything my driver has. I imagine guess it's because they're all resolution-dependent?
They are. What does the X driver print, and what mode are you trying to set?
This though:
WREG32(PM3VsStart, glint_shift_bpp(bpp, mode->vsync_start - 1));
Versus in the X driver:
temp2 = mode->CrtcVSyncStart - mode->CrtcVDisplay; ... STOREREG(PMVsStart, temp2 - 1);
For a mode like 1920x1200R, the former is going to be 1202, but the latter is going to be (1203 - 1200) - 1 == 2. So assuming the X driver is right, the hardware is looking for the distance in clocks between the various sync steps, and not their absolute offset from the beginning of the line/frame.
- ajax
I'll preface this response by saying that the driver is working now, in very large part due to help I've received from Adam Jackson, Dave Airlie, Alex Deucher, and Jerome Glisse.
On Thu, Aug 5, 2010 at 5:47 PM, Adam Jackson ajax@redhat.com wrote:
On Thu, 2010-08-05 at 12:16 -0400, Matt Turner wrote:
Hi, I've hit a snag and I'm not really sure how to debug it.
Both xf86-video-glint/src/pm3_dac.c:Permedia3Init and kernel/drivers/video/pm3fb.c:pm3fb_write_mode set the mode in virtually identical ways. I'm trying to do the same, but I think some of what I'm passing in from drm_display_mode is wrong, specifically
WREG32(PM3HTotal, glint_shift_bpp(bpp, mode->htotal - 1)); WREG32(PM3HsEnd, glint_shift_bpp(bpp, mode->hsync_end - mode->hdisplay)); WREG32(PM3HsStart, glint_shift_bpp(bpp, mode->hsync_start - mode->hdisplay)); WREG32(PM3HbEnd, glint_shift_bpp(bpp, mode->htotal - mode->hdisplay)); WREG32(PM3HgEnd, glint_shift_bpp(bpp, mode->htotal - mode->hdisplay)); WREG32(PM3ScreenStride, glint_shift_bpp(bpp, crtc->fb->width)); WREG32(PM3VTotal, glint_shift_bpp(bpp, mode->vtotal - 1)); WREG32(PM3VsEnd, glint_shift_bpp(bpp, mode->vsync_end - 1)); WREG32(PM3VsStart, glint_shift_bpp(bpp, mode->vsync_start - 1)); WREG32(PM3VbEnd, glint_shift_bpp(bpp, mode->vtotal - mode->vdisplay));
I printed the values that xf86-video-glint passes through here, and of course they don't match with anything my driver has. I imagine guess it's because they're all resolution-dependent?
They are. What does the X driver print, and what mode are you trying to set?
I'm setting 1024x768x24 (32 bpp).
Timings set by my driver are PM3HTotal: 335 PM3HsEnd: 40 PM3HsStart: 6 PM3HbEnd: 80 PM3HgEnd: 80 PM3ScreenStride: 256 PM3VTotal: 805 PM3VsEnd: 8 PM3VsStart: 2 PM3VbEnd: 38
Timings set by xf86-video-glint are (for the same mode) PM3HTotal: 327 PM3HsEnd: 28 PM3HsStart: 4 PM3HbEnd: 72 PM3HgEnd: 72 PM3ScreenStride: 256 PM3VTotal: 799 PM3VsEnd: 3 PM3VsStart: 0 PM3VbEnd: 32
So, clearly very close.
The final thing I did to make it work was to set the PM3VideoControl register to turn on hsync and vsync. So, of course without this I'm not getting any signals to the monitor. :)
This though:
WREG32(PM3VsStart, glint_shift_bpp(bpp, mode->vsync_start - 1));
Versus in the X driver:
temp2 = mode->CrtcVSyncStart - mode->CrtcVDisplay; ... STOREREG(PMVsStart, temp2 - 1);
Yes, you were right about this. I've changed them to - PM3VsEnd = mode->vsync_end - mode->vdisplay - 1 - PM3VsStart = mode->vsync_start - mode->vdisplay - 1
I also noticed that I was using glint_shift_bpp on the vsync timings, which isn't correct.
For a mode like 1920x1200R, the former is going to be 1202, but the latter is going to be (1203 - 1200) - 1 == 2. So assuming the X driver is right, the hardware is looking for the distance in clocks between the various sync steps, and not their absolute offset from the beginning of the line/frame.
Yep, this appears to be the case. It also appears, and I could be wrong, not to be what the documentation states. :)
- ajax
Thanks again to everyone who helped me. Now I'll write up some documentation to finish off the GSoC requirements and hopefully will fix up the driver to a state where it can live in the kernel.
Matt
dri-devel@lists.freedesktop.org