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.

OMAP3530 DSI MIPI video mode

Other Parts Discussed in Thread: SYSCONFIG

Hello,

 

We are trying to make work a 3.5'' display with the following characteristics:

MIPI, video mode
2-lane + clock
320(H) x 480(V) (RGB Stripe)
24-bits (R8, G8, B8)
VP 500 Line
VS 8 Line
VFP 6 Line
VBP 6 Line
VDISP 480 Line
HP 380 clk
HS 16 clk
HFP 12 clk
HBP 12 clk
HDISP 320 clk
fPCLK 10.80 MHz
tPCLK 92.5925935 ns

We have tried to implement the section 15.6.7 of http://focus.ti.com/lit/ug/spruf98g/spruf98g.pdf with the following code:
 
/* DSI registers */
#define DSI_IRQSTATUS            0x4804FC18
#define DSI_SYSCONFIG            0x4804FC10
#define DSI_SYSSTATUS            0x4804FC14
#define DSI_CLK_CTRL            0x4804FC54
#define DSI_PLL_CONTROL            0x4804FF00
#define DSI_PLL_CONFIGURATION1        0x4804FF0C
#define DSI_PLL_CONFIGURATION2        0x4804FF10
#define DSI_PLL_GO            0x4804FF08
#define DSI_PLL_STATUS            0x4804FF04
#define DSI_IRQENABLE            0x4804FC1C
#define DSI_VC0_CTRL            0x4804FD00
#define DSI_VC0_IRQENABLE        0x4804FD1C
#define DSI_VC0_LONG_PACKET_HEADER    0x4804FD08
#define DSI_VC1_CTRL            0x4804FD20
#define DSI_VC1_IRQENABLE        0x4804FD3C
#define DSI_VC1_SHORT_PACKET_HEADER    0x4804FD30
#define DSI_CTRL            0x4804FC40
#define DSI_COMPLEXIO_CFG1        0x4804FC48
#define DSI_COMPLEXIO_IRQSTATUS        0x4804FC4C
#define DSI_COMPLEXIO_IRQENABLE        0x4804FC50
#define DSI_SYSSTATUS            0x4804FC14
#define DSI_TIMING1            0x4804FC58
#define DSI_TIMING2            0x4804FC5C
#define DSI_VM_TIMING1            0x4804FC60
#define DSI_VM_TIMING2            0x4804FC64
#define DSI_VM_TIMING3            0x4804FC68
#define DSI_VM_TIMING7            0x4804FC90
#define DSI_CLK_TIMING            0x4804FC6C
#define DSI_PHY_CFG0            0x4804FE00
#define DSI_PHY_CFG1            0x4804FE04
#define DSI_PHY_CFG2            0x4804FE08
#define DSI_PHY_CFG5            0x4804FE14
#define DISPC_IRQENABLE            0x4805041C
 
/* Reset DSI [15.6.7.2.1] */
void dsi_reset(void)
{
    dss_write_reg(DSI_IRQSTATUS, 0);    /* Reset IRQ status */
    dss_write_reg(DSI_SYSCONFIG, 0x2);    /* Reset the module */
 
    /* Wait until RESET_DONE != 0 */
    printf("[1] DSI module reset in progress...\n");
    while((dss_read_reg(DSI_SYSSTATUS) & 0x1) == 0)
        ;
 
    dss_write_reg(DSI_SYSCONFIG, 0x314);    /* Set initial DSI configuration */
}
 
/* From DSS2 dss/dss.h */
#define FLD_MASK(start, end)        (((1 << ((start) - (end) + 1)) - 1) << (end))
#define FLD_VAL(val, start, end)    (((val) << (end)) & FLD_MASK(start, end))
#define FLD_GET(val, start, end)    (((val) & FLD_MASK(start, end)) >> (end))
#define FLD_MOD(orig, val, start, end)    (((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end))
 
/* Set up DSI DPLL [15.6.7.2.2] */
void dsi_set_dpll(void)
{
    uint l;
 
    /* Touch Book parameters */
    unsigned char m4 = 2, m3 = 2, m = 108, n = 19;
    unsigned char fint = 4, use_pck = 1, use_hfc = 0;
    unsigned int  height = 480, width = 320;
    unsigned char lck_div = 1, pck_div = 18;
    unsigned char hbp = 12, hfp = 12, hsw = 16;
    unsigned char vbp = 6, vfp = 6, vsw = 8;
 
    /* Set timings */
    l = FLD_MOD(0, hbp - 1, 31, 20);        /* HBP */
    l = FLD_MOD(l, hfp - 1, 19, 8);            /* HFP */
    l = FLD_MOD(l, hsw - 1, 7, 0);            /* HSW */
    dss_write_reg(DISPC_TIMING_H, l);
    l = FLD_MOD(0, vbp - 1, 27, 20);        /* VBP */
    l = FLD_MOD(l, vfp - 1, 15, 8);            /* VFP */
    l = FLD_MOD(l, vsw - 1, 5, 0);            /* VSW */
    dss_write_reg(DISPC_TIMING_V, l);
    l = FLD_MOD(0, lck_div, 23, 16);        /* LCD */
    l = FLD_MOD(l, pck_div, 7, 0);            /* PCD */
    dss_write_reg(DISPC_DIVISOR, l);
    l = FLD_MOD(0, height - 1, 26, 16);        /* LPP */
    l = FLD_MOD(l, width - 1, 10, 0);        /* PPL */
    dss_write_reg(DISPC_SIZE_LCD, l);
 
    /* Enable PCLKFREE */
    l = dss_read_reg(DISPC_CONTROL);
    dss_write_reg(DISPC_CONTROL, l | (1 << 27));
 
    /* Turn on PLL and HSDIVIDER */
    l = dss_read_reg(DSI_CLK_CTRL) | 0xC0000000;
    dss_write_reg(DSI_CLK_CTRL, l);
 
    /* Wait until PLL_PWR_STATUS = 0x2 */
    printf("[2] Waiting for PLL power...\n");
    while((dss_read_reg(DSI_CLK_CTRL) & 0x20000000) != 0x20000000)
        ;
 
    /* Set up the PLL */
    /* (Part 1) */
    l = FLD_MOD(0, 1, 0, 0);            /* DSI_PLL_STOPMODE */
    l = FLD_MOD(l, n - 1, 7, 1);            /* DSI_PLL_REGN */
    l = FLD_MOD(l, m, 18, 8);            /* DSI_PLL_REGM */
    l = FLD_MOD(l, m3 > 0 ? m3 - 1 : 0, 22, 19);    /* DSI_CLOCK_DIV */
    l = FLD_MOD(l, m4 > 0 ? m4 - 1 : 0, 26, 23);    /* DSIPROTO_CLOCK_DIV */
    dss_write_reg(DSI_PLL_CONFIGURATION1, l);
 
    /* (Part 2) */
    l = FLD_MOD(0, fint, 4, 1);            /* DSI_PLL_FREQSEL */
    l = FLD_MOD(l, use_pck, 11, 11);        /* DSI_PLL_CLKSEL */
    l = FLD_MOD(l, use_hfc, 12, 12);        /* DSI_PLL_HIGHFREQ */
    l = FLD_MOD(l, 1, 13, 13);            /* DSI_PLL_REFEN */
    l = FLD_MOD(l, 0, 14, 14);            /* DSIPHY_CLKINEN */
    l = FLD_MOD(l, 1, 20, 20);            /* DSIPHY_CLKINEN */
    dss_write_reg(DSI_PLL_CONFIGURATION2, l);
 
    /* Request locking */
    dss_write_reg(DSI_PLL_CONTROL, 0x0);
    dss_write_reg(DSI_PLL_GO, 0x1);
 
    /* Wait for lock... */
    printf("[3] Waiting for PLL lock request...\n");
    while((dss_read_reg(DSI_PLL_GO) & 0x1) != 0)
        ;
    printf("[4] Waiting for PLL lock...\n");
    while((dss_read_reg(DSI_PLL_STATUS) & 0x2) != 0x2)
        ;
 
    /* Locked -- change the configuration */
    l = dss_read_reg(DSI_PLL_CONFIGURATION2);
    l = FLD_MOD(l, 0, 0, 0);    /* DSI_PLL_IDLE */
    l = FLD_MOD(l, 0, 5, 5);    /* DSI_PLL_PLLLPMODE */
    l = FLD_MOD(l, 0, 6, 6);    /* DSI_PLL_LOWCURRSTBY */
    l = FLD_MOD(l, 0, 7, 7);    /* DSI_PLL_TIGHTPHASELOCK */
    l = FLD_MOD(l, 0, 8, 8);    /* DSI_PLL_DRIFTGUARDEN */
    l = FLD_MOD(l, 0, 10, 9);    /* DSI_PLL_LOCKSEL */
    l = FLD_MOD(l, 1, 13, 13);    /* DSI_PLL_REFEN */
    l = FLD_MOD(l, 1, 14, 14);    /* DSIPHY_CLKINEN */
    l = FLD_MOD(l, 0, 15, 15);    /* DSI_BYPASSEN */
    l = FLD_MOD(l, 1, 16, 16);    /* DSS_CLOCK_EN */
    l = FLD_MOD(l, 0, 17, 17);    /* DSS_CLOCK_PWDN */
    l = FLD_MOD(l, 1, 18, 18);    /* DSI_PROTO_CLOCK_EN */
    l = FLD_MOD(l, 0, 19, 19);    /* DSI_PROTO_CLOCK_PWDN */
    l = FLD_MOD(l, 0, 20, 20);    /* DSI_HSDIVBYPASS */
    dss_write_reg(DSI_PLL_CONFIGURATION2, l);
 
    /* Clock control */
    dss_write_reg(DSI_CLK_CTRL, 0x80244008);
}
 
/* Set up DSI Protocol Engine [15.6.7.2.4] */
void dsi_set_protocol_engine(void)
{
    uint l, dsi_ctrl = 0x2EE9C;
 
    /* Touch Book parameters */
    unsigned char pos_clock = 2, pos_data1 = 1, pos_data2 = 3;
    unsigned char pol_clock = 1, pol_data1 = 1, pol_data2 = 1;
 
    dss_write_reg(DSI_IRQENABLE, 0x40000);
    dss_write_reg(DSI_VC0_IRQENABLE, 0x4);
    dss_write_reg(DSI_CTRL, dsi_ctrl);
 
    /* Set up CIO */
    l = dss_read_reg(DSI_COMPLEXIO_CFG1);
    l = FLD_MOD(l, pol_clock, 3, 3);        /* CLOCK_POL */
    l = FLD_MOD(l, pol_data1, 7, 7);        /* DATA1_POL */
    l = FLD_MOD(l, pol_data2, 11, 11);        /* DATA2_POL */
 
    l = FLD_MOD(l, pos_clock, 2, 0);        /* CLOCK_POSITION */
    l = FLD_MOD(l, pos_data1, 6, 4);        /* DATA1_POSITION */
    l = FLD_MOD(l, pos_data2, 10, 8);        /* DATA2_POSITION */
 
    dss_write_reg(DSI_COMPLEXIO_CFG1, l);
    dss_write_reg(DSI_COMPLEXIO_IRQSTATUS, 0xC3F39CE7);
    dss_write_reg(DSI_COMPLEXIO_IRQENABLE, 0x0);
 
    /* A dummy read using the SCP interface to any DSIPHY register is
     * required after DSIPHY reset to complete the reset of the DSI complex
     * I/O. */
    dss_read_reg(DSI_PHY_CFG5);
 
    printf("[5] Waiting for DSIPHY reset...\n");
    while((dss_read_reg(DSI_PHY_CFG5) & 0x40000000) != 0x40000000)
        ;
 
    /* Enable ComplexIO Power */
    l = dss_read_reg(DSI_COMPLEXIO_CFG1);
    l = FLD_MOD(l, 1, 28, 27);
    dss_write_reg(DSI_COMPLEXIO_CFG1, l);
 
    /* Check power status */
    printf("[6] Actioning ComplexIO power-up...\n");
    while((dss_read_reg(DSI_COMPLEXIO_CFG1) & 0x08000000) == 0)
        ;
    /* Wait until reset done */
    printf("[7] Waiting for ComplexIO reset...\n");
    while((dss_read_reg(DSI_COMPLEXIO_CFG1) & 0x20000000) == 0)
        ;
    printf("[8] Waiting for ComplexIO power status...\n");
    while((dss_read_reg(DSI_COMPLEXIO_CFG1) & 0x06000000) == 0)
        ;
 
    /* Now, reset I/F */
    l = dsi_ctrl;
    dss_write_reg(DSI_CTRL, l |  0x1);
    dss_write_reg(DSI_CTRL, l & ~0x1);
    printf("[9] Waiting for DSI I/F reset...\n");
    while((dss_read_reg(DSI_CTRL) & 0x1) != 0x0)
        ;
 
    /* Enable Low Power clock */
    dss_write_reg(DSI_CLK_CTRL, 0x80344008);
 
    printf("[10] Waiting for DSI I/F reset...\n");
    while((dss_read_reg(DSI_SYSSTATUS) & 0x1) == 0)
        ;
 
    /* Set timing registers (FIXME -- these are just the magic values
       in the TRM -- do they need to be changed?) */
    dss_write_reg(DSI_TIMING1, 0x00000999);
    dss_write_reg(DSI_TIMING2, 0x2FD240CD);
    dss_write_reg(DSI_VM_TIMING1, 0x0000700A);
    dss_write_reg(DSI_VM_TIMING2, 0x04010101);
    dss_write_reg(DSI_VM_TIMING3, 0x05BB0280);
    dss_write_reg(DSI_VM_TIMING7, 0x0000C00A);
    dss_write_reg(DSI_CLK_TIMING, 0x00000F0B);
    dss_write_reg(DSI_VC0_CTRL, 0x20800390);    /* DSS */
    dss_write_reg(DSI_VC1_CTRL, 0x00000380);    /* L4 */
}
 
/* Set up DSI PHY [15.6.7.2.5] */
void dsi_set_phy(void)
{
    /* Touch Book parameters */
    uint ths_prepare = 22, ths_prepare_ths_zero = 49, ths_trail = 22, ths_exit = 39;
    uint tlpx_half = 8, tclk_trail = 19, tclk_zero = 69;
    uint tclk_prepare = 18, r;
 
    r = dss_read_reg(DSI_PHY_CFG0);
    r = FLD_MOD(r, ths_prepare, 31, 24);
    r = FLD_MOD(r, ths_prepare_ths_zero, 23, 16);
    r = FLD_MOD(r, ths_trail, 15, 8);
    r = FLD_MOD(r, ths_exit, 7, 0);
    dss_write_reg(DSI_PHY_CFG0, r);
 
    r = dss_read_reg(DSI_PHY_CFG1);
    r = FLD_MOD(r, tlpx_half, 22, 16);
    r = FLD_MOD(r, tclk_trail, 15, 8);
    r = FLD_MOD(r, tclk_zero, 7, 0);
    dss_write_reg(DSI_PHY_CFG1, r);
 
    r = dss_read_reg(DSI_PHY_CFG2);
    r = FLD_MOD(r, tclk_prepare, 7, 0);
    dss_write_reg(DSI_PHY_CFG2, r);
 
    /* Drive Stop State */
    printf("[11] Forcing TX Stop Mode...\n");
    dss_write_reg(DSI_TIMING1, dss_read_reg(DSI_TIMING1) | (1 << 15));
    while((dss_read_reg(DSI_SYSSTATUS) & (1 << 15)) != 0)
        ;
 
    /* FIXME: Toggle external controller reset at this point */
}
 
/* Set up DISPC [15.6.7.4.1] */
void dsi_set_dispc(void)
{
    /* Reset DISPC */
    uint t = dss_read_reg(DISPC_SYSCONFIG);
    dss_write_reg(DISPC_SYSCONFIG, t | (1 << 1));
    printf("[12] Waiting for DISPC reset...\n");
    while((dss_read_reg(DSI_SYSSTATUS) & 0x1) == 0)
        ;
 
    /* Turn off standby */
    dss_write_reg(DISPC_SYSCONFIG, t | (1 << 12) | (1 << 3));
    dss_write_reg(DISPC_IRQENABLE, 0);
 
    /* Configure DISPC_CONTROL */
    t = dss_read_reg(DISPC_CONTROL);
    t &= ~(1 << 0);
    t &= ~(1 << 5);
    t &= ~(1 << 11);
    t |=  (1 << 27) | (1 << 16) | (1 << 15) | (1 <<  9) |
        (1 <<  8) | (1 <<  3);
    dss_write_reg(DISPC_CONTROL, t);
 
    /* Enable VC0 */
    dss_write_reg(DSI_VC0_LONG_PACKET_HEADER, 0x0005A03E);
    t = dss_read_reg(DSI_VC0_CTRL);
    dss_write_reg(DSI_VC0_CTRL, t | 0x1);
 
    /* Enable VC1, set BTA_SHORT_EN */
    t = dss_read_reg(DSI_VC1_CTRL);
    dss_write_reg(DSI_VC1_CTRL, t | (1 << 0) | (1 << 2));
 
    t = dss_read_reg(DSI_CTRL);
    dss_write_reg(DSI_CTRL, t | 1);
    printf("[13] Waiting for DSI to be ready...\n");
    while((dss_read_reg(DSI_CTRL) & 0x1) == 0)
        ;
 
    /* Set up GFX plane */
    ai_logo();
 
    t = dss_read_reg(DISPC_CONTROL);
    t |= (1 << 5) | (1 << 0);
    dss_write_reg(DISPC_CONTROL, t);
 
    printf("[14] Waiting for DISPC to be ready...\n");
    while((dss_read_reg(DISPC_CONTROL) & (1 << 5)) != 0)
        ;

    /* Send NOP */
    t  = 0x05;         /* Data type: DCS Short WRITE, 0 parameters */
    t |= (0x00) << 8;  /* Data byte 1 */
    printf("[14] Sending DCS NOP\n");
    dss_write_reg(DSI_VC1_SHORT_PACKET_HEADER, t);
    while((dss_read_reg(DSI_VC1_CTRL) & (1 << 16)) == 1)
        ;

    /* Try "Read Panel ID" */
    t  = 0x15;         /* Data type: DCS Short WRITE, 1 parameter */
    t |= (0xB1) << 8;  /* Data byte 1 */
    t |= (0x14) << 16; /* Data byte 2 */
    printf("[14] Sending DCS Read Panel ID\n");
    dss_write_reg(DSI_VC1_SHORT_PACKET_HEADER, t);
    while((dss_read_reg(DSI_VC1_CTRL) & (1 << 16)) == 1)
        ;

    /* Block on RX FIFO */
    printf("[14] Testing GET ID [waiting to get back data]\n");
    while((dss_read_reg(DSI_VC1_CTRL) & (1 << 20)) == 0)
        ;

    /* Send wake-up commands on VC1 */
    printf("[14] RX FIFO has data!\n");
    printf("[15] Testing Sleep Out\n");
    t  = 0x05;         /* Data type: DCS Short WRITE, 0 parameters */
    t |= (0x11) << 8;  /* Data byte 1 */
    dss_write_reg(DSI_VC1_SHORT_PACKET_HEADER, t);
    while((dss_read_reg(DSI_VC1_CTRL) & (1 << 16)) == 1)
        ;

    printf("[16] Testing Display On\n");
    t  = 0x05;         /* Data type: DCS Short WRITE, 0 parameters */
    t |= (0x29) << 8;  /* Data byte 1 */
    dss_write_reg(DSI_VC1_SHORT_PACKET_HEADER, t);
    while((dss_read_reg(DSI_VC1_CTRL) & (1 << 16)) == 1)
        ;
}


and then:

    MUX_VAL(CP(DSS_DATA0), (IDIS | PTD | DIS | M1));
    MUX_VAL(CP(DSS_DATA1), (IDIS | PTD | DIS | M1));
    MUX_VAL(CP(DSS_DATA2), (IDIS | PTD | DIS | M1));
    MUX_VAL(CP(DSS_DATA3), (IDIS | PTD | DIS | M1));
    MUX_VAL(CP(DSS_DATA4), (IDIS | PTD | DIS | M1));
    MUX_VAL(CP(DSS_DATA5), (IDIS | PTD | DIS | M1));

    dsi_reset();
    dsi_set_dpll();
    dsi_set_protocol_engine();
    dsi_set_phy();
    dsi_set_dispc();


The result is:


[1] DSI module reset in progress...                                 
[2] Waiting for PLL power...                                        
[3] Waiting for PLL lock request...                                 
[4] Waiting for PLL lock...                                         
[5] Waiting for DSIPHY reset...                                     
[6] Actioning ComplexIO power-up...                                 
[7] Waiting for ComplexIO reset...                                  
[8] Waiting for ComplexIO power status...                           
[9] Waiting for DSI I/F reset...                                    
[10] Waiting for DSI I/F reset...                                   
[11] Forcing TX Stop Mode...                                        
[12] Waiting for DISPC reset...                                     
[13] Waiting for DSI to be ready...                                 
[14] Waiting for DISPC to be ready...                               
[14] Sending DCS NOP                                                
[14] Sending DCS Read Panel ID                                      
[14] Testing GET ID [waiting to get back data]

The screen doesn't answer the get id request. Hardware wise, everything seems correctly wired.

Any idea? Has anyone (at TI???) done an implementation of section 15.6.7 of spruf98g?

Grégoire

 

  • Actually, the latest is http://focus.ti.com/lit/ug/spruf98g/spruf98h.pdf, section 15.6.7, named "DSI Video Mode Using the DISPC Video Port",

     

    Grégoire

     

  • Gregoire,

    Unfortunately I am not a DSI expert, but here are some thoughts...

    Have you tried omitting the "Read Panel ID" stage, possibly replacing it with a simple delay? Are you sure your display supports the ID read command?

    Additionally, I could not see where you configured the actual graphics/video plane? e.g. DISPC_VIDn_SIZE or DISPC_GFX_SIZE. This should not stop the read command working though.

    Are you using a video pipe or the graphics pipe? How are you setting the layer resolution?

    BR,

    Steve

  • Even bypassing the read, nothing is shown up on the screen.

    The video planes are setup in a separate function. I will post again the complete code.

     

    Grégoire

  • To be very precise, the referenced TI doc is: http://focus.ti.com/lit/ug/spruf98h/spruf98h.pdf

     

    Grégoire

     

  • Here is an updated code (with more comments to get more feed-back),

    Grégoire

     

    #define DISPC_GFX_MEM        0x85000000
    #define DISPC_GFX_BA0        0x48050480
    #define DISPC_GFX_BA1        0x48050484
    #define DISPC_GFX_SIZE        0x4805048c
    #define DISPC_GFX_ATTRIBUTES    0x480504a0

    void logo(void)
    {
        unsigned int i, k=0;
        unsigned char pixel[3];
        int offset = 0;

        /* Fill up to the logo */
        for (i = 0; i < 2 * (LOGO_SCREEN_WIDTH * ((LOGO_SCREEN_HEIGHT/2) - (height/2))); i += 2) {
            *((unsigned short *)(DISPC_GFX_MEM + i)) = LOGO_FILL_COLOUR;
        }
        offset += i;

        /* Paint the image data */
        for (i = 0; i < height; i++) {
            for (k = 0; k < LOGO_SCREEN_WIDTH; k++) {
                if(k < (LOGO_SCREEN_WIDTH / 2 - width / 2) || k >= (LOGO_SCREEN_WIDTH / 2 + width / 2))
                    *((unsigned short *)(DISPC_GFX_MEM + offset + 2*k)) = LOGO_FILL_COLOUR;
                else {
                    HEADER_PIXEL(header_data, pixel);
                    *((unsigned short *)(DISPC_GFX_MEM + offset + 2*k)) =
                        ((((pixel[0])&0xf8) << 8) |
                         (((pixel[1])&0xfc) << 3) |
                         (((pixel[2])&0xf8) >> 3));
                }
            }

            offset += 2 * LOGO_SCREEN_WIDTH;
        }

        /* Fill the rest */
        for (i = 0; i < 2 * (LOGO_SCREEN_WIDTH * ((LOGO_SCREEN_HEIGHT/2) - (height/2))); i += 2) {
            *((unsigned short *)(DISPC_GFX_MEM + offset + i)) = LOGO_FILL_COLOUR;
        }

        *((uint *) DISPC_GFX_BA0) = DISPC_GFX_MEM;
        *((uint *) DISPC_GFX_BA1) = DISPC_GFX_MEM;
        *((uint *) DISPC_GFX_SIZE) = 0x02ff03ff;    /* 1024 x 768 */
        *((uint *) DISPC_GFX_ATTRIBUTES) = 0x0000008d;    /* RGB16, burst = 16x32bits, plane enabled */
    }

    /* DSI registers */
    #define DSI_IRQSTATUS            0x4804FC18
    #define DSI_SYSCONFIG            0x4804FC10
    #define DSI_SYSSTATUS            0x4804FC14
    #define DSI_CLK_CTRL            0x4804FC54
    #define DSI_PLL_CONTROL            0x4804FF00
    #define DSI_PLL_CONFIGURATION1        0x4804FF0C
    #define DSI_PLL_CONFIGURATION2        0x4804FF10
    #define DSI_PLL_GO            0x4804FF08
    #define DSI_PLL_STATUS            0x4804FF04
    #define DSI_IRQENABLE            0x4804FC1C
    #define DSI_VC0_CTRL            0x4804FD00
    #define DSI_VC0_IRQENABLE        0x4804FD1C
    #define DSI_VC0_LONG_PACKET_HEADER    0x4804FD08
    #define DSI_VC1_CTRL            0x4804FD20
    #define DSI_VC1_IRQENABLE        0x4804FD3C
    #define DSI_VC1_SHORT_PACKET_HEADER    0x4804FD30
    #define DSI_CTRL            0x4804FC40
    #define DSI_COMPLEXIO_CFG1        0x4804FC48
    #define DSI_COMPLEXIO_IRQSTATUS        0x4804FC4C
    #define DSI_COMPLEXIO_IRQENABLE        0x4804FC50
    #define DSI_SYSSTATUS            0x4804FC14
    #define DSI_TIMING1            0x4804FC58
    #define DSI_TIMING2            0x4804FC5C
    #define DSI_VM_TIMING1            0x4804FC60
    #define DSI_VM_TIMING2            0x4804FC64
    #define DSI_VM_TIMING3            0x4804FC68
    #define DSI_VM_TIMING7            0x4804FC90
    #define DSI_CLK_TIMING            0x4804FC6C
    #define DSI_PHY_CFG0            0x4804FE00
    #define DSI_PHY_CFG1            0x4804FE04
    #define DSI_PHY_CFG2            0x4804FE08
    #define DSI_PHY_CFG5            0x4804FE14
    #define DISPC_IRQENABLE            0x4805041C
    #define DSS_CONTROL            0x48050040
    #define DISPC_DEFAULT_COLOR0        0x4805044C

    /* Reset DSI [SPRUF98H 15.6.7.2.1] */
    void dsi_reset(void)
    {
        dss_write_reg(DSI_IRQSTATUS, 0);    /* Reset IRQ status */
        dss_write_reg(DSI_SYSCONFIG, 0x312);    /* Reset the module */

        /* Wait until RESET_DONE != 0 */
        printf("[1] DSI module reset in progress...\n");
        while((dss_read_reg(DSI_SYSSTATUS) & 0x1) == 0)
            ;
    }

    /* From DSS2 dss/dss.h */
    #define FLD_MASK(start, end)        (((1 << ((start) - (end) + 1)) - 1) << (end))
    #define FLD_VAL(val, start, end)    (((val) << (end)) & FLD_MASK(start, end))
    #define FLD_GET(val, start, end)    (((val) & FLD_MASK(start, end)) >> (end))
    #define FLD_MOD(orig, val, start, end)    (((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end))

    /* Set up DSI DPLL [SPRUF98H 15.6.7.2.2] */
    void dsi_set_dpll(void)
    {
        uint l;

        /* Touch Book parameters */
        unsigned char m4 = 2, m3 = 2, m = 108, n = 19;
        unsigned char fint = 4, use_pck = 1, use_hfc = 0;
        unsigned int  height = 480, width = 320;
        unsigned char lck_div = 1, pck_div = 18;
        unsigned char hbp = 12, hfp = 12, hsw = 16;
        unsigned char vbp = 6, vfp = 6, vsw = 8;

        /* FCLK = 432MHz, with pck_div = 18, lck_div = 1, PCK => 24MHz
           DSI-PHY => ((2 * RegM) / (RegN + 1)) * ((ClkIn) / (HighFreq + 1))
                   => ((2 * 108)  / (19   + 1)) * ((24)    / (0        + 1))
               => 259.2MHz

           Display Pixel Clock is 10.80MHz, at 24BPP
           => Data rate on each lane: (10.80 * 24) / 2 = 129.6Mbps
           => Data lane frequency:    259.2MHz
           => Clock lane frequency:   64.80MHz
        */

        /* Set timings */
        l = FLD_MOD(0, hbp - 1, 31, 20);        /* HBP */
        l = FLD_MOD(l, hfp - 1, 19, 8);            /* HFP */
        l = FLD_MOD(l, hsw - 1, 7, 0);            /* HSW */
        dss_write_reg(DISPC_TIMING_H, l);
        l = FLD_MOD(0, vbp - 1, 31, 20);        /* VBP */
        l = FLD_MOD(l, vfp - 1, 19, 8);            /* VFP */
        l = FLD_MOD(l, vsw - 1, 7, 0);            /* VSW */
        dss_write_reg(DISPC_TIMING_V, l);
        l = FLD_MOD(0, lck_div, 23, 16);        /* LCD */
        l = FLD_MOD(l, pck_div, 7, 0);            /* PCD */
        dss_write_reg(DISPC_DIVISOR, l);
        l = FLD_MOD(0, height - 1, 26, 16);        /* LPP */
        l = FLD_MOD(l, width - 1, 10, 0);        /* PPL */
        dss_write_reg(DISPC_SIZE_LCD, l);
        dss_write_reg(DISPC_DEFAULT_COLOR0, 0x00FFFFFF);

        /* Enable PCLKFREE */
        l = dss_read_reg(DISPC_CONTROL);
        dss_write_reg(DISPC_CONTROL, l | (1 << 27));

        /* Turn on PLL and HSDIVIDER */
        l = dss_read_reg(DSI_CLK_CTRL);
        dss_write_reg(DSI_CLK_CTRL, l | (1 << 31) | (1 << 30));

        /* Wait until PLL_PWR_STATUS = 0x2 */
        printf("[2] Waiting for PLL power...\n");
        while((dss_read_reg(DSI_CLK_CTRL) & 0x20000000) != 0x20000000)
            ;

        /* Set up the PLL */
        /* (Part 1) */
        l = FLD_MOD(0, 1, 0, 0);            /* DSI_PLL_STOPMODE */
        l = FLD_MOD(l, n - 1, 7, 1);            /* DSI_PLL_REGN */
        l = FLD_MOD(l, m, 18, 8);            /* DSI_PLL_REGM */
        l = FLD_MOD(l, m3 > 0 ? m3 - 1 : 0, 22, 19);    /* DSI_CLOCK_DIV */
        l = FLD_MOD(l, m4 > 0 ? m4 - 1 : 0, 26, 23);    /* DSIPROTO_CLOCK_DIV */
        dss_write_reg(DSI_PLL_CONFIGURATION1, l);

        /* (Part 2) */
        l = FLD_MOD(0, fint, 4, 1);            /* DSI_PLL_FREQSEL */
        l = FLD_MOD(l, use_pck, 11, 11);        /* DSI_PLL_CLKSEL */
        l = FLD_MOD(l, use_hfc, 12, 12);        /* DSI_PLL_HIGHFREQ */
        l = FLD_MOD(l, 1, 13, 13);            /* DSI_PLL_REFEN */
        l = FLD_MOD(l, 0, 14, 14);            /* DSIPHY_CLKINEN */
        l = FLD_MOD(l, 1, 20, 20);            /* DSI_HSDIVBYPASS */
        dss_write_reg(DSI_PLL_CONFIGURATION2, l);

        /* Request locking */
        dss_write_reg(DSI_PLL_CONTROL, 0x0);
        dss_write_reg(DSI_PLL_GO, 0x1);

        /* Wait for lock... */
        printf("[3] Waiting for PLL lock request...\n");
        while((dss_read_reg(DSI_PLL_GO) & 0x1) != 0)
            ;
        printf("[4] Waiting for PLL lock...\n");
        while((dss_read_reg(DSI_PLL_STATUS) & 0x2) != 0x2)
            ;

        /* Locked -- change the configuration */
        l = dss_read_reg(DSI_PLL_CONFIGURATION2);
        l = FLD_MOD(l, 0, 0, 0);    /* DSI_PLL_IDLE */
        l = FLD_MOD(l, 0, 5, 5);    /* DSI_PLL_PLLLPMODE */
        l = FLD_MOD(l, 0, 6, 6);    /* DSI_PLL_LOWCURRSTBY */
        l = FLD_MOD(l, 0, 7, 7);    /* DSI_PLL_TIGHTPHASELOCK */
        l = FLD_MOD(l, 0, 8, 8);    /* DSI_PLL_DRIFTGUARDEN */
        l = FLD_MOD(l, 0, 10, 9);    /* DSI_PLL_LOCKSEL */
        l = FLD_MOD(l, 1, 13, 13);    /* DSI_PLL_REFEN */
        l = FLD_MOD(l, 1, 14, 14);    /* DSIPHY_CLKINEN */
        l = FLD_MOD(l, 0, 15, 15);    /* DSI_BYPASSEN */
        l = FLD_MOD(l, 1, 16, 16);    /* DSS_CLOCK_EN */
        l = FLD_MOD(l, 0, 17, 17);    /* DSS_CLOCK_PWDN */
        l = FLD_MOD(l, 1, 18, 18);    /* DSI_PROTO_CLOCK_EN */
        l = FLD_MOD(l, 0, 19, 19);    /* DSI_PROTO_CLOCK_PWDN */
        l = FLD_MOD(l, 0, 20, 20);    /* DSI_HSDIVBYPASS */
        dss_write_reg(DSI_PLL_CONFIGURATION2, l);

        /* Clock control (FIXME?) */
        dss_write_reg(DSI_CLK_CTRL, 0x80244008);

        /* [15.6.7.2.3] Switch to DSI PLL Clock Source */
        dss_write_reg(DSS_CONTROL, 0x3);
    }

    /* Set up DSI Protocol Engine [SPRUF98H 15.6.7.2.4.1] */
    void dsi_set_protocol_engine(void)
    {
        uint l;

        /* Touch Book parameters */
        unsigned char pos_clock = 2, pos_data1 = 1, pos_data2 = 3;
        unsigned char pol_clock = 1, pol_data1 = 1, pol_data2 = 1;

        dss_write_reg(DSI_IRQENABLE, 0x40000);
        dss_write_reg(DSI_VC0_IRQENABLE, 0x4);

        /* Set up DSI_CTRL */
        l = FLD_MOD(0, 1, 17, 17);            /* VP_HSYNC_START */
        l = FLD_MOD(l, 1, 15, 15);            /* VP_VSYNC_START */
        l = FLD_MOD(l, 1, 14, 14);            /* TRIGGER_RESET_MODE */
        l = FLD_MOD(l, 2, 13, 12);            /* LINE_BUFFER */
        l = FLD_MOD(l, 1, 9, 9);            /* VP_DE_POL */
        l = FLD_MOD(l, 2, 7, 6);            /* VP_DATA_BUS_WIDTH */
        l = FLD_MOD(l, 1, 3, 3);            /* TX_FIFO_ARBITRATION */
        l = FLD_MOD(l, 1, 2, 2);            /* ECC_RX_EN */
        dss_write_reg(DSI_CTRL, l);

        /* Set up CIO */
        l = dss_read_reg(DSI_COMPLEXIO_CFG1);
        l = FLD_MOD(l, 1, 30, 30);            /* GOBIT */
        l = FLD_MOD(l, pol_clock, 3, 3);        /* CLOCK_POL */
        l = FLD_MOD(l, pol_data1, 7, 7);        /* DATA1_POL */
        l = FLD_MOD(l, pol_data2, 11, 11);        /* DATA2_POL */

        l = FLD_MOD(l, pos_clock, 2, 0);        /* CLOCK_POSITION */
        l = FLD_MOD(l, pos_data1, 6, 4);        /* DATA1_POSITION */
        l = FLD_MOD(l, pos_data2, 10, 8);        /* DATA2_POSITION */

        dss_write_reg(DSI_COMPLEXIO_CFG1, l);
        dss_write_reg(DSI_COMPLEXIO_IRQSTATUS, 0xC3F39CE7);
        dss_write_reg(DSI_COMPLEXIO_IRQENABLE, 0x0);

        /* A dummy read using the SCP interface to any DSIPHY register is
         * required after DSIPHY reset to complete the reset of the DSI complex
         * I/O. */
        dss_read_reg(DSI_PHY_CFG5);

        printf("[5] Waiting for DSIPHY reset...\n");
        while((dss_read_reg(DSI_PHY_CFG5) & 0x40000000) != 0x40000000)
            ;

        /* Enable ComplexIO Power */
        l = dss_read_reg(DSI_COMPLEXIO_CFG1);
        l = FLD_MOD(l, 1, 28, 27);
        dss_write_reg(DSI_COMPLEXIO_CFG1, l);

        /* Check power status */
        printf("[6] Actioning ComplexIO power-up...\n");
        while((dss_read_reg(DSI_COMPLEXIO_CFG1) & 0x08000000) == 0)
            ;
        /* Wait until reset done */
        printf("[7] Waiting for ComplexIO reset...\n");
        while((dss_read_reg(DSI_COMPLEXIO_CFG1) & 0x20000000) == 0)
            ;
        printf("[8] Waiting for ComplexIO power status...\n");
        while((dss_read_reg(DSI_COMPLEXIO_CFG1) & 0x06000000) == 0)
            ;

        /* Now, reset I/F */
        l = dss_read_reg(DSI_CTRL);
        dss_write_reg(DSI_CTRL, l |  0x1);
        dss_write_reg(DSI_CTRL, l & ~0x1);
        printf("[9] Waiting for DSI I/F reset...\n");
        while((dss_read_reg(DSI_CTRL) & 0x1) != 0x0)
            ;

        /* Enable Low Power clock */
        l = dss_read_reg(DSI_CLK_CTRL);
        dss_write_reg(DSI_CLK_CTRL, l | (1 << 20));

        printf("[10] Waiting for DSI I/F reset...\n");
        while((dss_read_reg(DSI_SYSSTATUS) & 0x1) == 0)
            ;

        /* Set timing registers (FIXME -- these are just the magic values
           in the TRM -- may need changing) */
        dss_write_reg(DSI_TIMING1, 0x00000999);
        dss_write_reg(DSI_TIMING2, 0x2FD240CD);
        dss_write_reg(DSI_CLK_TIMING, 0x00000F0B);
        dss_write_reg(DSI_VC0_CTRL, 0x20800390);    /* DSS */
        dss_write_reg(DSI_VC1_CTRL, 0x00000380);    /* L4 */

        /* VM timing */
        dss_write_reg(DSI_VM_TIMING1, 0x0000700A);
        dss_write_reg(DSI_VM_TIMING2, 0x04010101);
        dss_write_reg(DSI_VM_TIMING3, 0x05BB0280);
        dss_write_reg(DSI_VM_TIMING7, 0x0000C00A);
    }

    /* Set up DSI PHY [SPRUF98H 15.6.7.2.5] */
    void dsi_set_phy(void)
    {
        /* Touch Book parameters */
        uint ths_prepare = 22, ths_prepare_ths_zero = 49, ths_trail = 22, ths_exit = 39;
        uint tlpx_half = 8, tclk_trail = 19, tclk_zero = 69;
        uint tclk_prepare = 18, r;

        r = dss_read_reg(DSI_PHY_CFG0);
        r = FLD_MOD(r, ths_prepare, 31, 24);
        r = FLD_MOD(r, ths_prepare_ths_zero, 23, 16);
        r = FLD_MOD(r, ths_trail, 15, 8);
        r = FLD_MOD(r, ths_exit, 7, 0);
        dss_write_reg(DSI_PHY_CFG0, r);

        r = dss_read_reg(DSI_PHY_CFG1);
        r = FLD_MOD(r, tlpx_half, 22, 16);
        r = FLD_MOD(r, tclk_trail, 15, 8);
        r = FLD_MOD(r, tclk_zero, 7, 0);
        dss_write_reg(DSI_PHY_CFG1, r);

        r = dss_read_reg(DSI_PHY_CFG2);
        r = FLD_MOD(r, tclk_prepare, 7, 0);
        dss_write_reg(DSI_PHY_CFG2, r);

        /* Drive Stop State */
        printf("[11] Forcing TX Stop Mode...\n");
        dss_write_reg(DSI_TIMING1, dss_read_reg(DSI_TIMING1) | (1 << 15));
        while((dss_read_reg(DSI_SYSSTATUS) & (1 << 15)) != 0)
            ;

        /* FIXME: Toggle external controller reset at this point */
    }

    /* Set up DISPC [SPRUF98H 15.6.7.4] */
    void dsi_set_dispc(void)
    {
        /* Reset DISPC */
        uint t = dss_read_reg(DISPC_SYSCONFIG);
        dss_write_reg(DISPC_SYSCONFIG, t | (1 << 1));
        printf("[12] Waiting for DISPC reset...\n");
        while((dss_read_reg(DSI_SYSSTATUS) & 0x1) == 0)
            ;

        /* Turn off standby */
        dss_write_reg(DISPC_SYSCONFIG, t | (1 << 12) | (1 << 3));
        dss_write_reg(DISPC_IRQENABLE, 0);

        /* Configure DISPC_CONTROL */
        t = dss_read_reg(DISPC_CONTROL);
        t &= ~(1 << 0);
        t &= ~(1 << 5);
        t &= ~(1 << 11);
        t |=  (1 << 27) | (1 << 16) | (1 << 15) | (1 <<  9) |
            (1 <<  8) | (1 <<  3);
        dss_write_reg(DISPC_CONTROL, t);

        /* Enable VC0 */
        dss_write_reg(DSI_VC0_LONG_PACKET_HEADER, 0x0005A03E);
        t = dss_read_reg(DSI_VC0_CTRL);
        dss_write_reg(DSI_VC0_CTRL, t | 0x1);

        /* Enable VC1, set BTA_SHORT_EN */
        t = dss_read_reg(DSI_VC1_CTRL);
        dss_write_reg(DSI_VC1_CTRL, t | (1 << 0) | (1 << 2));

        t = dss_read_reg(DSI_CTRL);
        dss_write_reg(DSI_CTRL, t | 1);
        printf("[13] Waiting for DSI to be ready...\n");
        while((dss_read_reg(DSI_CTRL) & 0x1) == 0)
            ;

        /* Set up GFX plane */
        ai_logo();

        /* Enable LCD interface, enable GOLCD */
        t = dss_read_reg(DISPC_CONTROL);
        t |= (1 << 5) | (1 << 0);
        dss_write_reg(DISPC_CONTROL, t);

        printf("[14] Waiting for DISPC to be ready...\n");
        while((dss_read_reg(DISPC_CONTROL) & (1 << 5)) != 0)
            ;

        /* Send NOP */
        t  = 0x05;         /* Data type: DCS Short WRITE, 0 parameters */
        t |= (0x00) << 8;  /* Data byte 1 */
        printf("[14] Sending DCS NOP\n");
        dss_write_reg(DSI_VC1_SHORT_PACKET_HEADER, t);
        while((dss_read_reg(DSI_VC1_CTRL) & (1 << 16)) == 1)
            ;

        /* Try "Read Panel ID" */
        t  = 0x15;         /* Data type: DCS Short WRITE, 1 parameter */
        t |= (0xB1) << 8;  /* Data byte 1 */
        t |= (0x14) << 16; /* Data byte 2 */
        printf("[14] Sending DCS Read Panel ID\n");
        dss_write_reg(DSI_VC1_SHORT_PACKET_HEADER, t);
        while((dss_read_reg(DSI_VC1_CTRL) & (1 << 16)) == 1)
            ;

        /* Block on RX FIFO */
        printf("[14] Testing GET ID [waiting to get back data]\n");
        //while((dss_read_reg(DSI_VC1_CTRL) & (1 << 20)) == 0)
        //    ;

        /* Send wake-up commands on VC1 */
        printf("[14] RX FIFO has data!\n");
        printf("[15] Testing Sleep Out\n");
        t  = 0x05;         /* Data type: DCS Short WRITE, 0 parameters */
        t |= (0x11) << 8;  /* Data byte 1 */
        dss_write_reg(DSI_VC1_SHORT_PACKET_HEADER, t);
        while((dss_read_reg(DSI_VC1_CTRL) & (1 << 16)) == 1)
            ;

        printf("[16] Testing Display On\n");
        t  = 0x05;         /* Data type: DCS Short WRITE, 0 parameters */
        t |= (0x29) << 8;  /* Data byte 1 */
        dss_write_reg(DSI_VC1_SHORT_PACKET_HEADER, t);
        while((dss_read_reg(DSI_VC1_CTRL) & (1 << 16)) == 1)
            ;
    }

    /*
     * Configure DSS to display background color on DVID
     * Configure VENC to display color bar on S-Video
     */
    void display_init(void)
    {
        omap3_dss_panel_config(&dvid_cfg);
        omap3_dss_set_background_col(DVI_TOUCHBOOK_BACKGROUND_COL);
        *((uint *) 0x49040024) = 0x80; /* Turn on GPT9 PWM */
        logo();
    }


    int main(void)
    {
        display_init();

        MUX_VAL(CP(DSS_DATA0), (IDIS | PTD | DIS | M1));
        MUX_VAL(CP(DSS_DATA1), (IDIS | PTD | DIS | M1));
        MUX_VAL(CP(DSS_DATA2), (IDIS | PTD | DIS | M1));
        MUX_VAL(CP(DSS_DATA3), (IDIS | PTD | DIS | M1));
        MUX_VAL(CP(DSS_DATA4), (IDIS | PTD | DIS | M1));
        MUX_VAL(CP(DSS_DATA5), (IDIS | PTD | DIS | M1));
        dsi_reset();
        dsi_set_dpll();
        dsi_set_protocol_engine();
        dsi_set_phy();
        dsi_set_dispc();
    }

     

     

  • And to make it very clear, the previous code is not working.