My board is the same revision like yours. I have modified the driver a little more since I sent you the files. I no longer use DBC as I figured that my flickering issues were not caused by that. As for the rest it is pretty much what the datasheet says it is supposed to be. The whole init sequence is taken from the MicroC library code. That is very strange that it didn't work for your board. Let me give you the latest driver I have so you can compare. I will attach it to this post in a bit. static inline void set_backlight(GDisplay *g, uint8_t percent) { // The SSD1963 has a built-in PWM (duty_cycle 00..FF). // Its output can be used by a Dynamic Background Control or by a host (user) // Check your LCD's hardware, the PWM connection is default left open and instead // connected to a LED connection on the breakout board write_index(g, SSD1963_SET_PWM_CONF); //set PWM for BackLight write_data(g, 0x06); // write_data(g, 0x0E); // PWMF[7] = 2, PWM base freq = PLL/(256*(1+5))/256 = 300Hz for a PLL freq = 120MHz (source: Displaytech) if (percent == 0xFF) // use percent==0xFF to turn off SSD1963 pwm in power SLEEP or DEEP SLEEP mode write_data(g, 0x00); else if (percent >= 100) // Fully on for any percentage >= 100 write_data(g, 0xFF); else write_data(g, (percent*255)/100 & 0x00FF);// Set brightness percentage. write_data(g, 0x01); // PWM enable control by host (not DBC) write_data(g, 0xFF); // DBC manual brightness write_data(g, 0x00); // DBC minimum brightness write_data(g, 0x01); // Brightness prescaler when Transition effect enabled } /*===========================================================================*/ /* Driver exported functions. */ /*===========================================================================*/ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { LCD_Parameters * lcdp; /* * Some displays (e.g. Displaytech) have an on-board setup process which just requires that we don't touch anything for a time after power up. * For this type of display define GDISP_SSD1963_NO_INIT as TRUE, and implement an appropriate delay in the board file. * With such displays we can skip most of the initialisation. We also skip pulsing the reset pin, since it * will introduce an extra second or so of display to the startup time. */ // The private area for this controller is the LCD timings lcdp = (void *)&DisplayTimings[g->controllerdisplay]; g->priv = lcdp; // Initialise the board interface init_board(g); #if !GDISP_SSD1963_NO_INIT // Hardware reset setpin_reset(g, TRUE); gfxSleepMilliseconds(200); setpin_reset(g, FALSE); gfxSleepMilliseconds(200); #endif // Get the bus for the following initialisation commands acquire_bus(g); #if !GDISP_SSD1963_NO_INIT write_index(g, SSD1963_SOFT_RESET); // Software reset - clears almost everything (apart from PLL) write_index(g, SSD1963_SOFT_RESET); // Software reset - clears almost everything (apart from PLL) write_index(g, SSD1963_SOFT_RESET); // Software reset - clears almost everything (apart from PLL) /* Driver PLL config */ write_index(g, SSD1963_SET_PLL_MN); write_data(g, 35); // PLLclk = REFclk (10Mhz) * 36 (360Mhz) write_data(g, 2); // SYSclk = PLLclk / 3 (120MHz) write_data(g, 0x54); // Apply calculation bit, else it is ignored write_reg(g, SSD1963_SET_PLL, 0x01); // Enable PLL gfxSleepMicroseconds(100); // Let PLL stabilize write_reg(g, SSD1963_SET_PLL, 0x03); // Use PLL /* LCD panel parameters */ write_index(g, SSD1963_SET_GDISP_MODE); write_data(g, lcdp->flags & 0xFF); write_data(g, (lcdp->flags >> 8) & 0xFF); //** write_data(g, 0x18); //Enabled dithering //** write_data(g, 0x00); write_data16(g, lcdp->width-1); write_data16(g, lcdp->height-1); write_data(g, 0x00); // RGB - line sequences for serial TFT #endif // From Displaytech example - for larger horizontal resolutions - not sure if display-specific if (lcdp->width >= 640) write_reg(g, SSD1963_SET_ADDRESS_MODE, 2); // Flip horizontal direction write_reg(g, SSD1963_SET_PIXEL_DATA_INTERFACE, SSD1963_PDI_16BIT565); write_reg(g, SSD1963_SET_PIXEL_FORMAT, 0x50); #if !GDISP_SSD1963_NO_INIT /* LCD Clock specs */ write_index(g, SSD1963_SET_LSHIFT_FREQ); write_data(g, (lcdp->fpr >> 16) & 0xFF); write_data(g, (lcdp->fpr >> 8) & 0xFF); write_data(g, lcdp->fpr & 0xFF); write_index(g, SSD1963_SET_HORI_PERIOD); write_data16(g, lcdp->hperiod); // According to datasheet this write_data16(g, lcdp->hpulse + lcdp->hbporch); write_data(g, lcdp->hpulse - 1); // and this should be (value - 1) but in MicroC this is how it is write_data(g, 0x00); write_data(g, 0x00); write_data(g, 0x00); write_index(g, SSD1963_SET_VERT_PERIOD); write_data16(g, lcdp->vperiod - 1); // According to datasheet this write_data16(g, lcdp->vpulse + lcdp->vbporch); write_data(g, lcdp->vpulse - 1); // and this should be (value - 1) but in MicroC this is how it is write_data(g, 0x00); write_data(g, 0x00); #endif /* Tear effect indicator ON. This is used to tell the host MCU when the driver is not refreshing the panel (during front/back porch) */ //write_reg(g, SSD1963_SET_TEAR_ON, 0x00); /* Turn on */ write_index(g, SSD1963_SET_DISPLAY_ON); /* Turn on the back-light */ set_backlight(g, GDISP_INITIAL_BACKLIGHT); // Finish Init post_init_board(g); // Release the bus release_bus(g); /* Initialise the GDISP structure */ g->g.Width = lcdp->width; g->g.Height = lcdp->height; g->g.Orientation = GDISP_ROTATE_0; g->g.Powermode = powerOn; g->g.Backlight = GDISP_INITIAL_BACKLIGHT; g->g.Contrast = GDISP_INITIAL_CONTRAST; return TRUE; } And the board code: /* * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://ugfx.org/license.html */ #ifndef _GDISP_LLD_BOARD_H #define _GDISP_LLD_BOARD_H static const LCD_Parameters DisplayTimings[] = { // You need one of these array elements per display { 480, 272, // Panel width and height 2, 2, 41, // Horizontal Timings (back porch, front porch, pulse) CALC_PERIOD(480,2,2,41), // Total Horizontal Period (calculated from above line) 2, 2, 10, // Vertical Timings (back porch, front porch, pulse) CALC_PERIOD(272,2,2,10), // Total Vertical Period (calculated from above line) CALC_FPR(480,272,2,2,41,2,2,10,60ULL), // FPR - the 60ULL is the frames per second. Note the ULL! 83271, LCD_PANEL_DATA_WIDTH_24BIT | LCD_PANEL_ENABLE_DITHERING }, }; /* GPIO Pin Config */ #define GDISP_CMD_PORT GPIOF #define GDISP_DATA_LO_PORT GPIOG #define GDISP_DATA_HI_PORT GPIOE #define GDISP_WR 11 #define GDISP_RD 12 #define GDISP_CS 13 #define GDISP_RST 14 #define GDISP_DC 15 #define SET_CS palSetPad(GDISP_CMD_PORT, GDISP_CS); #define CLR_CS palClearPad(GDISP_CMD_PORT, GDISP_CS); #define SET_RST palSetPad(GDISP_CMD_PORT, GDISP_RST); #define CLR_RST palClearPad(GDISP_CMD_PORT, GDISP_RST); #define SET_WR palSetPad(GDISP_CMD_PORT, GDISP_WR); #define CLR_WR palClearPad(GDISP_CMD_PORT, GDISP_WR); #define SET_RD palSetPad(GDISP_CMD_PORT, GDISP_RD); #define CLR_RD palClearPad(GDISP_CMD_PORT, GDISP_RD); #define SET_DC palSetPad(GDISP_CMD_PORT, GDISP_DC); #define CLR_DC palClearPad(GDISP_CMD_PORT, GDISP_DC); #define writeStrobe { CLR_WR; asm volatile ("nop;"); SET_WR; } IOBus busCMD = { GDISP_CMD_PORT, (1 << GDISP_CS) | (1 << GDISP_RST) | (1 << GDISP_WR) | (1 << GDISP_RD) | (1 << GDISP_DC), 11 }; IOBus busDataLo = { GDISP_DATA_LO_PORT, 0xFF, 0 }; IOBus busDataHi = { GDISP_DATA_HI_PORT, 0xFF, 8 }; static inline void init_board(GDisplay *g) { g->board = 0; switch(g->controllerdisplay) { case 0: { palSetBusMode(&busCMD, PAL_MODE_OUTPUT_PUSHPULL); palSetBusMode(&busDataLo, PAL_MODE_OUTPUT_PUSHPULL); palSetBusMode(&busDataHi, PAL_MODE_OUTPUT_PUSHPULL); SET_CS; SET_WR; SET_RD; SET_DC; SET_RST; break; } default: break; } } static inline void post_init_board(GDisplay *g) { (void) g; } static inline void setpin_reset(GDisplay *g, bool_t state) { (void) g; if (state) { CLR_RST; } else { SET_RST; } } static inline void acquire_bus(GDisplay *g) { (void) g; CLR_CS; } static inline void release_bus(GDisplay *g) { (void) g; SET_CS; } static inline void write_index(GDisplay *g, uint16_t index) { (void) g; CLR_DC; palWriteBus(&busDataLo, (index & 0xFF)); palWriteBus(&busDataHi, (index >> 8)); writeStrobe; SET_DC; } static inline void write_data(GDisplay *g, uint16_t data) { (void) g; palWriteBus(&busDataLo, (data & 0xFF)); palWriteBus(&busDataHi, (data >> 8)); writeStrobe; } static inline void setreadmode(GDisplay *g) { (void) g; palSetBusMode(&busDataLo, PAL_MODE_OUTPUT_PUSHPULL); palSetBusMode(&busDataHi, PAL_MODE_OUTPUT_PUSHPULL); } static inline void setwritemode(GDisplay *g) { (void) g; palSetBusMode(&busDataLo, PAL_MODE_INPUT_PULLUP); palSetBusMode(&busDataHi, PAL_MODE_INPUT_PULLUP); } static inline uint16_t read_data(GDisplay *g) { (void) g; uint16_t data; CLR_RD; data = (palReadBus(&busDataHi) << 8) | palReadBus(&busDataLo); SET_RD; return data; } #endif /* _GDISP_LLD_BOARD_H */ PS: If you set your PWM Frequency at 0x01 then PWM Freq = 120Mhz / (256 * 1) / 256 = 1831 Hz which is way beyond the TPS61041 EN pin input PWM signal. According to it's datasheet the PWM it can accept is 100Hz - 500Hz. So value of 0x06 makes more sense which would put your PWM freq at 120Mhz / (256 * 6) / 256 = 305 Hz. That is of course given that your PLL clock is actually set at 120Mhz.