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.

TI Sitara LCD Controller Output Signal Modification - Linux

Other Parts Discussed in Thread: DA8XX

For one of our application we need to convert the LCD Control output to NTSC. We are using Video DAC to accomplish this task. In a nutshell we would like to modify the LCD Controller registers so that signal such as VSYNC, HSYNC etc meet the requirements. (This is my thought)

My thought is to develop a loadable module that will be loaded after the system is up and running.

I have identified the following files as the likely candidates to aid the task.

  1.  /arch/arm/mach-omap2/board-am335xevm.c
  2. /arch/arm/mach-omap2/devics.c
  3. /kernel/drivers/video/da8xx-fb.c
I would appreciated your assistance to 
  1. Confirm above list of files is all we need
  2. Guidance on functions calls to initialize the LCD Controller
  3. Identify the required function calls to manipulate the LCD Controller registers

I am open for other suggestions

Thank you in advance

  • Hi,

    All the important stuff is happening inside the da8xx-fb.c driver. The lcdc_info structure contains all the important parameters like HSYNC width and VSYNC width. Take a look at the da8xxfb_set_par() function to see how these parameters are initialized.

    The fb_info structure used for passing parameters to the function is defined in include/linux/fb.h. In the same file take a look at the fb_var_screeninfo structure. It contains the following elements, related to signal timing:

    /* Timing: All values in pixclocks, except pixclock (of course) */
        __u32 pixclock;            /* pixel clock in ps (pico seconds) */
        __u32 left_margin;        /* time from sync to picture    */
        __u32 right_margin;        /* time from picture to sync    */
        __u32 upper_margin;        /* time from sync to picture    */
        __u32 lower_margin;
        __u32 hsync_len;        /* length of horizontal sync    */
        __u32 vsync_len;        /* length of vertical sync    */
        __u32 sync;            /* see FB_SYNC_*        */
        __u32 vmode;            /* see FB_VMODE_*        */
        __u32 rotate;            /* angle we rotate counter clockwise */
        __u32 reserved[5];        /* Reserved for future compatibility */

    Best regards,
    Miroslav

  • @Miroslav

    Was this part of the ICS or JB release. I am currently working on ICS. 

    Thanks

  • Hi,

    This is from the linux kernel from the Linux SDK 06.00.00.00. I don't currently have the Android SDK, but this should be same in both kernels as the device drivers are the same.

    Best regards,
    Miroslav

  • @Miroslav,

    I check the kernel/drivers/video/da8xx-fb.c on both the git download ICS and JB for Android and I don't see set_par() function. I googled da8xxfb_set_par() and looks like the patch has been added but the android distribution has not picked it up yet.

  • Hi,

    It seems like the kernel driver inside the Android package is missing this function. I'm guessing by looking at the definition of the struct fb_ops da8xx_fb_ops in this Linux cross reference (I assume it is similar with the driver that comes with the Android package): http://lxr.free-electrons.com/source/drivers/video/da8xx-fb.c?v=3.2#L1039

    The fb_ops structure contains frame buffer operations and has a member called fb_set_par which is set to point to the da8xxfb_set_par() function in the kernel driver I have from the Linux SDK. This is how the fb_ops structure looks like: http://lxr.free-electrons.com/source/include/linux/fb.h#L222 (the fb_set_par function pointer is on line 255).

    This is how the da8xx_fb_ops structure is defined in the Linux SDK da8xx driver that I have:

    static struct fb_ops da8xx_fb_ops = {
        .owner = THIS_MODULE,
        .fb_check_var = fb_check_var,
        .fb_set_par = da8xxfb_set_par,
        .fb_setcolreg = fb_setcolreg,
        .fb_pan_display = da8xx_pan_display,
        .fb_ioctl = fb_ioctl,
        .fb_fillrect = cfb_fillrect,
        .fb_copyarea = cfb_copyarea,
        .fb_imageblit = cfb_imageblit,
        .fb_blank = cfb_blank,
    };

    and here is how the da8xxfb_set_par function looks like in the same driver:

    static int da8xxfb_set_par(struct fb_info *info)
    {
        struct da8xx_fb_par *par = info->par;
        struct lcd_ctrl_config *lcd_cfg = par->lcd_cfg;
        struct da8xx_panel *lcdc_info = par->lcdc_info;
        unsigned long long pxl_clk = 1000000000000ULL;
        bool raster;
        int ret;

        raster = is_raster_enabled();

        lcdc_info->hfp = info->var.right_margin;
        lcdc_info->hbp = info->var.left_margin;
        lcdc_info->vfp = info->var.lower_margin;
        lcdc_info->vbp = info->var.upper_margin;
        lcdc_info->hsw = info->var.hsync_len;
        lcdc_info->vsw = info->var.vsync_len;
        lcdc_info->width = info->var.xres;
        lcdc_info->height = info->var.yres;

        do_div(pxl_clk, info->var.pixclock);
        par->pxl_clk = pxl_clk;

        lcd_cfg->bpp = info->var.bits_per_pixel;

        if (raster)
            lcd_disable_raster(WAIT_FOR_FRAME_DONE);
        else
            lcd_disable_raster(NO_WAIT_FOR_FRAME_DONE);

        info->fix.visual = (lcd_cfg->bpp <= 8) ?
                    FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
        info->fix.line_length = (lcdc_info->width * lcd_cfg->bpp) / 8;

        par->dma_start = par->vram_phys;
        par->dma_end   = par->dma_start + lcdc_info->height *
                    info->fix.line_length - 1;

        ret = lcd_init(par, lcd_cfg, lcdc_info);
        if (ret < 0) {
            dev_err(par->dev, "lcd init failed\n");
            return ret;
        }

        if (raster)
            lcd_enable_raster();

        return 0;
    }

    Note how the function assigns new values for the HSYNC and VSYNC signal widths. These values are taken from a structure of type fb_var_screeninfo (which I mentioned in my first answer). The definition of this structure is inside include/linux/fb.h in the kernel sources I have, but in the cross reference I mentioned the definition is here: http://lxr.free-electrons.com/source/include/uapi/linux/fb.h#L240

    All these differences make me think that this frame buffer functionality is either not used inside the driver that is included in the Android package, or they are used in some different way.

    I guess you will have to implement this functionality if it is missing in the Android kernel driver and if it is indeed what you are looking for (modifying the video mode timings).

    Best regards,
    Miroslav