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.

lcd 800x680x24 (32) RGB888 help with dm365

we got a 7 inch lcd with 800x680x24 RGB888, support max dclk =  30 M.

we are trying with our custom board witht the lcd directly connected.

and i get a little modification based on dvsdk4 on both Davinci_platform.c (media\video\davinci) and Vpbe_encoder.c (media\video\davinci) .

remove anything connect to the cpld in dm365.c and configure the kernel to make it run.

in Vpbe_encoder.c:

the red one is added:

/* All Supported encoder modes */
static struct vid_enc_mode_info vpbe_encoder_modes[VPBE_ENCODER_MAX_NUM_STD+1] = {
 {
 .name = VID_ENC_STD_800x480,
  .std = 1,
 .if_type = VID_ENC_IF_PRGB,
  .interlaced = 1,
  .xres = 800,
  .yres = 480,
  .fps = {30000, 1001},
  .left_margin = 18,
  .right_margin = 12,
  .upper_margin = 20,
  .lower_margin = 8,
  .hsync_len = 1,
  .vsync_len = 1,
  .flags = 0},
 {
  .name = VID_ENC_STD_NTSC,
  .std = 1,
  .if_type = VID_ENC_IF_INT,
  .interlaced = 1,
  .xres = 720,
  .yres = 480,
  .fps = {30000, 1001},
  .left_margin = 0x79,
  .right_margin = 0,
  .upper_margin = 0x10,
  .lower_margin = 0,
  .hsync_len = 0,
  .vsync_len = 0,
  .flags = 0},
/ /...

and

 .no_of_outputs = VPBE_DM644X_ENCODER_MAX_NO_OUTPUTS,
 .output[0] = {
        .output_name = VID_ENC_OUTPUT_COMPOSITE,
        .no_of_standard = VPBE_DM644X_ENCODER_COMPOSITE_NUM_STD,
//mike changed:
//        .standards = {VID_ENC_STD_NTSC, VID_ENC_STD_PAL},
        .standards = {VID_ENC_STD_800x480, VID_ENC_STD_NTSC},
        },

 

for Davinci_platform.c :

struct enc_config davinci_enc_default[DAVINCI_ENC_MAX_CHANNELS] = {
//mike changed:
//{VID_ENC_OUTPUT_COMPOSITE,
//VID_ENC_STD_NTSC}
 {VID_ENC_OUTPUT_LCD,
  VID_ENC_STD_800x480}
};

and in davinci_enc_set_prgb:

else if (cpu_is_davinci_dm365()) {
  /* DM365 pinmux */
  dispc_reg_out(VENC_CLKCTL, 0x11);
  davinci_cfg_reg(DM365_VOUT_FIELD_G81);
  davinci_cfg_reg(DM365_VOUT_COUTL_EN);
  davinci_cfg_reg(DM365_VOUT_COUTH_EN);
//mike added for RGB888
printk("davinci_enc_set_prgb : pinmux1  calling\n\n\n");

 reg = __raw_readl(IO_ADDRESS(0x01c40000 + 0x04));//pin mux 1
 reg &= ~(3 << 18); /* FIELD = 2 => R2*/
 reg |= 2<<18;

 reg &= ~(3 << 20); /* EXTCLK = 2 => B2*/
 reg |= 2<<20;  
 __raw_writel(reg, IO_ADDRESS(0x01c40000 + 0x04));

 reg = __raw_readl(IO_ADDRESS(0x01c40000 + 0x10));/* pinmux 4*/
 reg |= 0xf<<10; /* R1, R0 */
 reg |= 0xff;    /* B0, B1, G0, G1 */
 __raw_writel(reg, IO_ADDRESS(0x01c40000 + 0x10));

 }

if this line :

//dispc_reg_out(VENC_VDPRO, 0x903);

is add in the end of this function, like this
dispc_reg_out(VENC_VDPRO, 0x903);

 if (cpu_is_davinci_dm368()) {
  /* Turn on LCD display */
  mdelay(200);
  gpio_set_value(82, 1);
 }

after the system start, we can see the color bar in the lcd :

 

but if we remove this line,

dispc_reg_out(VENC_VDPRO, 0x903);

 we get :

 

 

i dont kown what's the problem.. and stil  i cannot see the linux log and .. the app of qt example cannot be display in the lcd.

we even tried with decode etc, but no luck.

Any help will be appreciated. thinks in advance.

regards, Mike.

 

  • we are tring to use this test code to set the lcd to an color bar, but first we need to set mono color.

    #include <stdio.h>

    #include <fcntl.h>

    #include <string.h>

    #include <stdlib.h>

    #include <linux/fb.h>

    #include <sys/mman.h>

    #include <sys/ioctl.h>

    #include <fcntl.h>

    #include <malloc.h>

    #include <unistd.h>

    struct fb_var_screeninfo vinfo;

    int main(int argc, char *argv[])

    {

    int fbfd, fbsize, i;

    int red, green, blue;

    unsigned char *fbbuf;

    if (argc != 5) {

    printf("usage: ./%s /dev/fbx r g b\n", argv[0]);

    printf("e.g: ./%s /dev/fb0 128 255 255\n", argv[0]);

    exit(0);

    }

    red = atoi(argv[2]);

    green = atoi(argv[3]);

    blue = atoi(argv[4]);

    /* Open video memory */

    if ((fbfd = open(argv[1], O_RDWR)) < 0) {

    exit(1);

    }

    /* Get variable display parameters */

    if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {

    printf("Bad vscreeninfo ioctl\n");

    exit(2);

    }

    printf("xres, yres, pixel/bit : %d, %d, %d\n", vinfo.xres, vinfo.yres, vinfo.

    bits_per_pixel);

    /* Size of frame buffer */

    fbsize = vinfo.xres*vinfo.yres*(vinfo.bits_per_pixel/8);

    /* Map video memory */

    if ((fbbuf = mmap(0, fbsize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0)) == (void *) -1

    ) {

    exit(3);

    }

    /* Clear the screen */

    for (i = 0; i < fbsize; i++) {

    *(fbbuf + i++) = red;

    *(fbbuf + i++) = green;

    *(fbbuf + i++) = blue;

    }

    printf("clear screen with rgb:%s %s %s %d\n", argv[2], argv[3], argv[4], fbsize);

    munmap(fbbuf, fbsize);

    close(fbfd);

    return 0;

    }

    if we try with

    ./fb /dev/fb0 255 0 0

    the lcd turn to blue and  it is the same below:

    ./fb /dev/fb0  0 0 255

    this one turns lcd to be cyan...

    ./fb /dev/fb0  0 0 255

     

  •  

    Kernel command line:

    console=ttyS0,115200n8 rw mem=54M video=davincifb:vid0=800x480x24,4050K:vid1=800x480x24,4050K:osd0=800x480x24,4050K dm365_imp.oper_mode=0 davinci_enc_mngr.ch0_output=LCD1 davinci_enc_mngr.ch0_mode=800x480

    the info when the system start:(some is added by ourselves)

    ch0 default output "LCD1", mode "800x480"
    ch1 default output "", mode ""
    Mode 800x480
    mgr->current_mode.name 800x480

    davinci_enc_set_prgb : pinmux1  calling


    davincifb davincifb.0: dm_osd0_fb: 800x480x16@0,0 with framebuffer size 4050KB
    davincifb davincifb.0: dm_vid0_fb: 800x480x16@0,0 with framebuffer size 4050KB
    davincifb davincifb.0: dm_osd1_fb: 800x480x4@0,0 with framebuffer size 750KB
    davincifb davincifb.0: dm_vid1_fb: 800x480x16@0,0 with framebuffer size 4050KB

     

    when i use fbset -s found here :

    mode "800x480-60"
        # D: 12.658 MHz, H: 15.233 kHz, V: 59.853 Hz
        geometry 800 480 800 480 16
        timings 79000 18 12 20 8 1 1
        bcast true
        laced true
        rgba 5/11,6/5,5/0,0/0
    endmode

    so we found the problem : the fb setting is not correct:

    rgba 5/11,6/5,5/0,0/0

    it is 5/6/5,but we are need 8/8/8.

    so change Davincifb.c (video) 

    in convert_osd_to_fb_var:

     case PIXFMT_RGB888:
    //mike  
    #if 0  
      if (cpu_is_davinci_dm644x()) {
    #endif
       var->bits_per_pixel = 24;
       var->red.offset = 0;
       var->red.length = 8;
       var->green.offset = 8;
       var->green.length = 8;
       var->blue.offset = 16;
       var->blue.length = 8;
    //mike   
    #if 0   
      } else {
       var->bits_per_pixel = 32;
       var->red.offset = 16;
       var->red.length = 8;
       var->green.offset = 8;
       var->green.length = 8;
       var->blue.offset = 0;
       var->blue.length = 8;
       var->transp.offset = 24;
       var->transp.length = 3;
      }
    #endif

    in davincifb_check_var:

     case 24:
    //mike  
    #if 0  
      if (cpu_is_davinci_dm355())
       return -EINVAL;
    #endif  
      break;

    in parse_win_params:

       case 24:
    //mike
    printk("setting to 24 bit \n\n\n");
    //    if (cpu_is_davinci_dm644x()
    //        && (win->layer == WIN_VID0
    //     || win->layer == WIN_VID1))
         lconfig->pixfmt = PIXFMT_RGB888;
        break;

    and still the command line change to

    video=davincifb:vid0=off:vid1=off:osd0=800x480x24,4050K:osd1=off  dm365_imp.oper_mode=0  davinci_enc_mngr.ch0_output=LCD1  davinci_enc_mngr.ch0_mode=800x480

    now the monochrome - color is showing ok in the lcd,but ..

    fbset :

    mode "800x480-60"
        # D: 12.658 MHz, H: 15.233 kHz, V: 59.853 Hz
        geometry 800 480 800 480 24
        timings 79000 18 12 20 8 1 1
        bcast true
        laced true
        rgba 8/0,8/8,8/16,0/0
    endmode

    we still find that

    *(fbbuf + i++) = red;

    *(fbbuf + i++) = green;

    *(fbbuf + i++) = blue;

    i++;

    we cannot display the color bar by this software - tool above.

  • The 24-bit RGB888 data is stored in DDR2/mDDR in 32-bit words. Within each 24-bit element, the red value in the least significant byte, followed by the green, then the blue byte, as shown in Figure 68. The three lower bits of the MSByte are interpreted as pixel-level blending bits.

     

    Address

    31 27

    26 24

    23 16

    15 8

    7 0

    N

    n/a

    Blend0

    R0

    G0

    B0

    N+1

    n/a

    Blend1

    R1

    G1

    B1

    See it in :

    4.4.4.6 Bitmap Window Data — RGB Formats

    after a litte search, we found this.

    So i think we need to change to 32 mode in the kernel command line.

    also.. we need to patch  Davincifb.c (video) to support 32 bit of dm365.

    but this time .. it is almost the same with the last one.

  • after write the data to the memory been mmap on the fb0, i found that the data address is not correct:

    unsigned char * bar(unsigned char * base,int length, unsigned char r, unsigned char g, unsigned char b)
    {
     int i = 0;
     while(i <= length-4) {
      *(base + i++) = b;
      *(base + i++) = g;
      *(base + i++) = r; 
      ++i;
      }
     return base + i ;
    }

     ptr = bar(fbbuf,800, 255, 0, 0);
     
     ptr = bar(ptr,800,  0, 255, 0);
     
     ptr = bar(ptr,800,  0, 0, 255);
     
     ptr = bar(ptr,800, 255,  255, 0);

    then the lcd is full of 4 kinds of colors, the problem is .. it is only small part of the memory after mmap.

    dd if=/dev/fb0 of=/fb_data

    fb_data:

    form 0x0000 - 0x0c70h : the data is fill with the above data, but the other is null.

    i just doubl why the other data is not getting showing in the lcd.

  • Assuming your display is 800x480xRGB8888, I think your code will draw 4 lines of colour and 476 lines are undefined. Possible code to try 4 bars that fills the entire display.

    unsigned char *bar(unsigned char *base,
                       int            width,
                       int            height,
                       unsigned char  r,
                       unsigned char  g,
                       unsigned char  b)
    {
     register int            i;
     register int            n = width*height;
     register unsigned long  pixel; /* RGB8888 */
     register unsigned long *p = (unsigned long *)base;

     pixel   = r;
     pixel <<= 8;
     pixel  |= g;
     pixel <<= 8;
     pixel  |= b;

     for(i=0; i < n; i++)
       *p++ = pixel;

     return((unsigned char *)p);
    }


    ptr = bar(fbbuf,800, 120, 255,   0,   0); /* 800x120 bar of red */
    ptr = bar(ptr,  800, 120,   0, 255,   0); /* 800x120 bar of blue */
    ptr = bar(ptr,  800, 120,   0,   0, 255); /* 800x120 bar of green */
    ptr = bar(ptr,  800, 120, 255, 255,   0); /* 800x120 bar of red/blue */

    The code combines the RGB values into one 32 bit value for speed.

     

  • Norman Wong said:

    Assuming your display is 800x480xRGB8888, I think your code will draw 4 lines of colour and 476 lines are undefined. Possible code to try 4 bars that fills the entire display.

    unsigned char *bar(unsigned char *base,
                       int            width,
                       int            height,
                       unsigned char  r,
                       unsigned char  g,
                       unsigned char  b)
    {
     register int            i;
     register int            n = width*height;
     register unsigned long  pixel; /* RGB8888 */
     register unsigned long *p = (unsigned long *)base;

     pixel   = r;
     pixel <<= 8;
     pixel  |= g;
     pixel <<= 8;
     pixel  |= b;

     for(i=0; i < n; i++)
       *p++ = pixel;

     return((unsigned char *)p);
    }


    ptr = bar(fbbuf,800, 120, 255,   0,   0); /* 800x120 bar of red */
    ptr = bar(ptr,  800, 120,   0, 255,   0); /* 800x120 bar of blue */
    ptr = bar(ptr,  800, 120,   0,   0, 255); /* 800x120 bar of green */
    ptr = bar(ptr,  800, 120, 255, 255,   0); /* 800x120 bar of red/blue */

    The code combines the RGB values into one 32 bit value for speed.

     

    Hi, Norman Wong ,  You are right but only on the LCD+borad which can display correct things.

    but on my situation your code can just display only one color : red

    the other colors cannot get displayed.

    it also puzzles me.

    the lcd dispaly the color bar in the lcd after running my code: 

    red

    blue

    green

    red/blue

     

     but .. it should display the color bars like this :

     

    red

    blue

    green

    red/blue

     

     

     

     

     

     

     

  • I assume that the images are full screen and no black regions omitted, I would guess that your LCD scans vertically rather than horizontally. The origin could be top left or bottom left. Your code looks like it writing out 4 lines but you get 4 large blocks. Implies that the LCD itself uses a lot less than 4 bytes per pixel. Also, are you sure that your LCD is interlaced?

    I am not familiar with the DM365 LCD controller. Does it do format conversion? Does it allow origin and scan direction to be set? Or is the frame buffer passed through to the LCD without change? The frame buffer format might be diffferent than the LCD format.

     

  • Thinks, Norman Wong.

    i think we resolve the problem by configure the pin of the lcd to the mode of SYNC rather then DE mode.

    then it works.

    it is  may be the problem of interlaced..

  • Hi zanget,

    Could you post the detail step of adding the LCD as output component? I've tried to set the ch0_output=LCD, but failed when kernel startup, with the code you have mentioned.

    Thanks,

    John

  • hello!

    I have done all of your operate as you say. but the LCD is black! and I have some questions an below:

    1.The bootargs I fixed like this:

    bootargs=mem=48M console=ttyS1,115200n8 root=/dev/ram0 rw initrd=0x82000000,14M                                 ip=192.168.1.101:192.168.1.100:192.168.1.1:255.255.255.0:::off eth=00:11:22:43:46:6adavinci_enc_mngr.ch0_mode=LCD video=davincifb:osd0=800x480x16@0

     2. vpbe_encoder_setmode() in vpbe_encoder.c print error during the kernel start,and below is what the kernel print:
                         ch0 default output "LCD", mode "800x480"
                         Mode not supported..
                         Erron in setting default mode
                         Error occured in setoutput
                         VPBE Encoder Initialized
                         Invalid id...
    2. there is no VCLK signal output on the oscilloscope.

    can you gave some suggest?
    thank you!