This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Setting the AM3358 display resolution with fbset

Other Parts Discussed in Thread: AM3358, DA8XX

I'm having some trouble changing the display resolution on the AM3358. We're running the Linux kernel/filesystem that's provided with the Sitara SDK 07.00.00.00 (although with slight modifications for our custom board).

We need to be able to adjust the display resolution without rebooting. I know I've had this working before, but now I'm having difficulties getting this to work. Let me describe a couple scenarios that exhibit problems.

Scenario 1

My device tree is configured for 640x480 resolution, and the system boots properly to this. Here are the settings in the device tree file:

hactive         = <640>;
vactive         = <480>;
hback-porch     = <48>;
hfront-porch    = <16>;
hsync-len       = <96>;
vback-porch     = <33>;
vfront-porch    = <10>;
vsync-len       = <2>;
clock-frequency = <25175000>;
hsync-active    = <0>;
vsync-active    = <0>;

After booting up, here is the output of the fbset command (displaying the current settings):

mode "640x480-60"
    # D: 25.176 MHz, H: 31.469 kHz, V: 59.942 Hz
    geometry 640 480 640 480 32
    timings 39721 48 16 33 10 96 2
    rgba 8/16,8/8,8/0,8/24
endmode

This looks to be correct. Also, when I observe the CTRL register in the LCD controller, the clkdiv field is 2. Now, I change to an 800x600 mode with fbset -xres 800 -yres 600 -vxres 800 -vyres 600 -t 25000 88 40 23 1 128 4. I again dump the video mode info from fbset:

mode "800x600-60"
    # D: 40.000 MHz, H: 37.879 kHz, V: 60.317 Hz
    geometry 800 600 800 600 32
    timings 25000 88 40 23 1 128 4
    rgba 8/16,8/8,8/0,8/24
endmode

This also looks appropriate. Now, I want to switch back to 640x480, so I issue fbset -xres 640 -yres 480 -vxres 640 -vyres 480 -t 39722 48 16 33 10 96 2, which results in the following:

mode "640x480-63"
    # D: 26.667 MHz, H: 33.333 kHz, V: 63.492 Hz
    geometry 640 480 640 480 32
    timings 37500 48 16 33 10 96 2
    rgba 8/16,8/8,8/0,8/24
endmode

Notice that the pixel clock is no longer 39721 but 37500, which changes the vertical refresh from about 60 Hz to about 63.5 Hz. The clkdiv field of the CTRL register is now set to 3, not 2 as when first booted. What happened here?

Scenario 2

I'm booting up with a resolution of 480x272, which is the resolution used by default in the TI SDK. After booting, I dump the video info:

mode "480x272-75"
    # D: 12.000 MHz, H: 22.430 kHz, V: 75.268 Hz
    geometry 480 272 480 272 32
    timings 83333 43 8 12 4 4 10
    rgba 8/16,8/8,8/0,8/24
endmode

This looks right. I then try to set 640x480 using the same command and timing information from scenario 1 above: fbset -xres 640 -yres 480 -vxres 640 -vyres 480 -t 39722 48 16 33 10 96 2, and then again dump the fbset info:

mode "640x432-66"
    # D: 25.173 MHz, H: 31.466 kHz, V: 65.967 Hz
    geometry 640 432 640 432 32
    timings 39725 48 16 33 10 96 2
    rgba 8/16,8/8,8/0,8/24
endmode

Notice here that we're actually in a 640x432 mode! When I first boot into 480x272 mode, the clkdiv field of the CTRL register is 2 and the vertical refresh rate is 75 Hz. After switching to 640x480, it's still at 2. However, when I switch back from 640x480 to 480x272, clkdiv is now 4, and the vertical refresh rate is 79 Hz instead of 75 Hz (while the other registers are identical).

I've also tried booting into 800x600 and then setting 640x480 (using the exact same command above), but I actually get 640x345 for some weird reason.

When I thought I had this working, I asked another question in this forum about unloading/reloading the PVR drivers while switching modes, but haven't received a response yet (and now I seem to have taken a step backwards). The information there might be useful to this discussion though.

SUMMARY

    It appears that the clkdiv field of the CTRL register in the LCD controller isn't being set properly.Sometimes, the number of vertical lines is not set properly.Depending on what video mode I boot into and subsequently switch to, I can get different results, even for the same modes.
  • Hi Steve,

    Sorry for delaying the reply to your other question. I will check what happened and also forward this question first thing on Monday.

  • Thanks for responsing Biser. I've updated my post above with a few bits of additional information, as well as a little summary bit at the bottom to help make it clear the issues I see.
  • If there is a better way to change video modes instead of using fbset, please let me know.
  • I believe I've figured out one of the two issues, which is why the 640x480 resolution is incorrectly set to 640x432.

    The da8xx framebuffer driver allocates a block of memory to use for the framebuffer only once, when it's first loaded. When switching resolutions, fb_check_var() in the driver modifies the number of lines to fit within this block of memory. So, when booting first into 480x272, I can't set 640x480 because it's too large for the block of memory. 640x432 just fits, and the driver tells fbset to use this value instead. This we can deal with... Either by booting up to the largest resolution from the start, or by modifying the driver to allocate a larger block of memory.

    I'm still stuck on the vertical refresh rate problem, though. I don't quite understand how the clocking works, and would like assistance.
  • Steve,

    I was wondering if you've tried to reverse the test in Scenario 1 as well by booting to the larger and switching to the smaller? Since this had an impact on Scenario 2 and seemed to solve that, I was curious if it would impact Scenario 1 as well?

    Also, were you able to try this on a TI board just to see if it happened there?

    Thanks,

    Ron

  • When I boot into a larger resolution and reduce it, the lower resolution is correct (at least, number of pixels and lines) but the timing is incorrect (pixel clock is not what was asked for).

    I haven't tried it with a TI board, I don't think it would make much difference - this stuff is all internal to the AM3358 if I'm not mistaken.