AnsweredAssumed Answered

[i.MX28] Trouble with a 1024x768 lcd

Question asked by Marco Catellani on May 8, 2018
Latest reply on May 9, 2018 by igorpadykov

Hi all. I'trying to use this LCD:

https://www.mouser.it/datasheet/2/365/LQ150X1LX95_30Jul14_Spec_LD-26206B-1131491.pdf with the i.MX28
I'm using the LTIB 2.6.35_10_12_01.

 

I've made some modification to the lcd_43wvf1g.c file. In particular I've changed these lines:

#define DOTCLK_H_ACTIVE  1024
#define DOTCLK_V_ACTIVE  768
ret = clk_set_rate(lcd_clk, 1000000000 / pentry->cycle_time_ns);    /* kHz */
static struct mxs_platform_fb_entry fb_entry = {
    .name = "43wvf1g",
    .x_res = DOTCLK_H_ACTIVE,
    .y_res = DOTCLK_V_ACTIVE,
    .bpp = 32,
    .cycle_time_ns = 20,
    .lcd_type = MXS_LCD_PANEL_DOTCLK,
    .init_panel = init_panel,
    .release_panel = release_panel,
    .blank_panel = blank_panel,
    .run_panel = mxs_lcdif_run,
    .stop_panel = mxs_lcdif_stop,
    .pan_display = mxs_lcdif_pan_display,
    .bl_data = &bl_data,
};

Initially I thinked about a problem in lcd clock frequency.
The static function int lcdif_set_rate(struct clk *clk, unsigned long rate) in clock.c, fix lcd clock to xtal frequency that is about 24MHz and the datasheet specify that this frequency need to be between 50 and 80MHz..

 

I've changed this function in that way, and now I can set the frequency that I want.

static int lcdif_set_rate(struct clk *clk, unsigned long rate)
{
    int reg_val;
    printk("LCD: \"lcdif_set_rate\" %lu\n", rate);
    {
        unsigned long int regAddr;
        #define RAW_READ_L(X, D)    do { \
                            regAddr = X; \
                            reg_val = __raw_readl(regAddr); \
                            printk("LCD: \"lcdif_set_rate\" GET_L reg: 0x%lX (%s) : 0x%X\n", regAddr, D, reg_val); \
                        } while(0)
        #define RAW_WRITE_L(X, Y, D)    do { \
                            regAddr = X; \
                            reg_val = Y; \
                            __raw_writel(reg_val, regAddr); \
                            printk("LCD: \"lcdif_set_rate\" SET_L reg: 0x%lX (%s) to: 0x%X\n", regAddr, D, reg_val); \
                        } while(0)
        #define RAW_WRITE_W(X, Y, D)    do { \
                            regAddr = X; \
                            reg_val = Y; \
                            __raw_writew(reg_val, regAddr); \
                            printk("LCD: \"lcdif_set_rate\" SET_W reg: 0x%lX (%s) to: 0x%X\n", regAddr, D, reg_val); \
                        } while(0)
        #define RAW_WRITE_B(X, Y, D)    do { \
                            regAddr = X; \
                            reg_val = Y; \
                            __raw_writeb(reg_val, regAddr); \
                            printk("LCD: \"lcdif_set_rate\" SET_B reg: 0x%lX (%s) to: 0x%X\n", regAddr, D, reg_val); \
                        } while(0)
        RAW_READ_L(CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLL0CTRL0, "HW_CLKCTRL_PLL0CTRL0");
        RAW_READ_L(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC1, "HW_CLKCTRL_FRAC1");

        reg_val &= ~BM_CLKCTRL_FRAC1_PIXFRAC;
        reg_val |= BF_CLKCTRL_FRAC1_PIXFRAC(18) & BM_CLKCTRL_FRAC1_PIXFRAC;
        //RAW_WRITE_L(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC1_SET, reg_val, "HW_CLKCTRL_FRAC1_SET");
        RAW_WRITE_B(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC1_SET, reg_val & 0xFF, "HW_CLKCTRL_FRAC1_SET");
        reg_val = BM_CLKCTRL_FRAC1_CLKGATEPIX;
        RAW_WRITE_B(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC1_CLR, reg_val & 0xFF, "HW_CLKCTRL_FRAC1_CLR");

 

        RAW_READ_L(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC1, "HW_CLKCTRL_FRAC1");

 

        //Set lcdif clock to ref_pix to generate rate frequency
        RAW_READ_L(clk->scale_reg, "HW_CLKCTRL_DIS_LCDIF");
        reg_val &= ~(BM_CLKCTRL_DIS_LCDIF_DIV | BM_CLKCTRL_DIS_LCDIF_CLKGATE | BM_CLKCTRL_DIS_LCDIF_DIV_FRAC_EN);
        //reg_val |= (1 << BP_CLKCTRL_DIS_LCDIF_DIV) & BM_CLKCTRL_DIS_LCDIF_DIV;
        reg_val |= BF_CLKCTRL_DIS_LCDIF_DIV(480000000/rate) & BM_CLKCTRL_DIS_LCDIF_DIV;
        RAW_WRITE_L(clk->scale_reg, reg_val, "HW_CLKCTRL_DIS_LCDIF");
        RAW_READ_L(clk->scale_reg, "HW_CLKCTRL_DIS_LCDIF");

 

        if (clk->busy_reg) {
            int i;
            for (i = 1000000; i; i--)
                if (!clk_is_busy(clk))
                    break;
            if (!i) {
                return -ETIMEDOUT;
            }
        }
        RAW_READ_L(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ, "HW_CLKCTRL_CLKSEQ");
        reg_val &= ~BM_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF;
        RAW_WRITE_L(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ, reg_val, "HW_CLKCTRL_CLKSEQ");
        #undef RAW_READ_L
        #undef RAW_WRITE_L
        #undef RAW_WRITE_W
        #undef RAW_WRITE_B
    }
    return 0;
}

I've tryed frequency from 50Mhz to 60Mhz,

I've checked the frequency with an oscilloscope and it's ok, but the output image still have some problem, it seems horizontally shifted.

 

Someone can help me or give some hint?
Thanks in advance.

 

PS. The LVDS hardware is ok. With this hardware I'm able to use other LCD: 10"@800x600 and 7"@800x480.

Attachments

Outcomes