diff options
Diffstat (limited to 'firmware/target/mips/ingenic_x1000/erosqnative/lcd-erosqnative.c')
-rw-r--r-- | firmware/target/mips/ingenic_x1000/erosqnative/lcd-erosqnative.c | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/lcd-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/lcd-erosqnative.c new file mode 100644 index 0000000000..073bddb8b4 --- /dev/null +++ b/firmware/target/mips/ingenic_x1000/erosqnative/lcd-erosqnative.c @@ -0,0 +1,188 @@ + +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2021 Aidan MacDonald, Dana Conrad + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "lcd.h" +#include "kernel.h" +#include "lcd-x1000.h" +#include "gpio-x1000.h" +#include "system.h" + +/* for reference on these command/data hex values, see the mipi dcs lcd spec. * + * Not everything here is there, but all the standard stuff is. */ + +static const uint32_t erosqnative_lcd_cmd_enable[] = { + /* Set EXTC? */ + LCD_INSTR_CMD, 0xc8, + LCD_INSTR_DAT, 0xff, + LCD_INSTR_DAT, 0x93, + LCD_INSTR_DAT, 0x42, + /* Set Address Mode */ + LCD_INSTR_CMD, 0x36, + LCD_INSTR_DAT, 0xd8, + /* Pixel Format Set */ + LCD_INSTR_CMD, 0x3a, + //LCD_INSTR_DAT, 0x66, /* OF specified 18 bpp */ + LCD_INSTR_DAT, 0x05, /* RB seems to be happier dealing with 16 bits/pixel */ + /* Power Control 1? */ + LCD_INSTR_CMD, 0xc0, + LCD_INSTR_DAT, 0x15, + LCD_INSTR_DAT, 0x15, + /* Power Control 2? */ + LCD_INSTR_CMD, 0xc1, + LCD_INSTR_DAT, 0x01, + /* VCOM? */ + LCD_INSTR_CMD, 0xc5, + LCD_INSTR_DAT, 0xda, + /* ?? */ + LCD_INSTR_CMD, 0xb1, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x1b, + /* ?? */ + LCD_INSTR_CMD, 0xb4, + LCD_INSTR_DAT, 0x02, + /* Positive gamma correction? */ + LCD_INSTR_CMD, 0xe0, + LCD_INSTR_DAT, 0x0f, + LCD_INSTR_DAT, 0x13, + LCD_INSTR_DAT, 0x17, + LCD_INSTR_DAT, 0x04, + LCD_INSTR_DAT, 0x13, + LCD_INSTR_DAT, 0x07, + LCD_INSTR_DAT, 0x40, + LCD_INSTR_DAT, 0x39, + LCD_INSTR_DAT, 0x4f, + LCD_INSTR_DAT, 0x06, + LCD_INSTR_DAT, 0x0d, + LCD_INSTR_DAT, 0x0a, + LCD_INSTR_DAT, 0x1f, + LCD_INSTR_DAT, 0x22, + LCD_INSTR_DAT, 0x00, + /* Negative gamma correction? */ + LCD_INSTR_CMD, 0xe1, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x21, + LCD_INSTR_DAT, 0x24, + LCD_INSTR_DAT, 0x03, + LCD_INSTR_DAT, 0x0f, + LCD_INSTR_DAT, 0x05, + LCD_INSTR_DAT, 0x38, + LCD_INSTR_DAT, 0x32, + LCD_INSTR_DAT, 0x49, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x09, + LCD_INSTR_DAT, 0x08, + LCD_INSTR_DAT, 0x32, + LCD_INSTR_DAT, 0x35, + LCD_INSTR_DAT, 0x0f, + /* Exit Sleep */ + LCD_INSTR_CMD, 0x11, + LCD_INSTR_UDELAY, 120000, + /* Display On */ + LCD_INSTR_CMD, 0x29, + LCD_INSTR_UDELAY, 20000, +}; + +/* sleep and wake copied directly from m3k */ +static const uint32_t erosqnative_lcd_cmd_sleep[] = { + /* Display OFF */ + LCD_INSTR_CMD, 0x28, + /* Sleep IN */ + LCD_INSTR_CMD, 0x10, + LCD_INSTR_UDELAY, 5000, + LCD_INSTR_END, +}; + +static const uint32_t erosqnative_lcd_cmd_wake[] = { + /* Sleep OUT */ + LCD_INSTR_CMD, 0x11, + LCD_INSTR_UDELAY, 5000, + /* Display ON */ + LCD_INSTR_CMD, 0x29, + LCD_INSTR_END, +}; + +/* As far as I can tell, this is a sequence of commands sent before each + * DMA set. Original in OF was: + * {0x2c, 0x2c, 0x2c, 0x2c} + * But this set from the m3k seems to work the same, and makes more sense + * to me: + * {0x00, 0x00, 0x00, 0x2c} + * This command is more than likely going to be the same + * for any old mipi lcd on the market, maybe. I really don't think we need + * to send "write_memory_start four times in a row. */ +static const uint8_t __attribute__((aligned(64))) + erosqnative_lcd_dma_wr_cmd[] = {0x2c, 0x2c, 0x2c, 0x2c}; + +const struct lcd_tgt_config lcd_tgt_config = { + .bus_width = 8, + .cmd_width = 8, + .use_6800_mode = 0, + .use_serial = 0, + .clk_polarity = 0, + .dc_polarity = 0, + .wr_polarity = 1, + .te_enable = 0, /* OF had TE enabled (1) */ + .te_polarity = 1, + .te_narrow = 0, + .dma_wr_cmd_buf = &erosqnative_lcd_dma_wr_cmd, + .dma_wr_cmd_size = sizeof(erosqnative_lcd_dma_wr_cmd), +}; + +void lcd_tgt_enable(bool enable) +{ + if(enable) { + /* power up the panel */ + gpio_set_level(GPIO_LCD_PWR, 1); + mdelay(20); + gpio_set_level(GPIO_LCD_RESET, 1); + mdelay(12); + + /* set the clock */ + lcd_set_clock(X1000_CLK_SCLK_A, 20000000); + + /* toggle chip select low (active) */ + gpio_set_level(GPIO_LCD_RD, 1); + gpio_set_level(GPIO_LCD_CE, 1); + mdelay(5); + gpio_set_level(GPIO_LCD_CE, 0); + + lcd_exec_commands(&erosqnative_lcd_cmd_enable[0]); + } else { + /* doesn't flash white if we don't do anything... */ +#if 0 + lcd_exec_commands(&erosqnative_lcd_cmd_sleep[0]); + + mdelay(115); // copied from m3k + + gpio_set_level(GPIO_LCD_PWR, 0); + gpio_set_level(GPIO_LCD_RESET, 0); +#endif + } +} + +void lcd_tgt_sleep(bool sleep) +{ + if(sleep) + lcd_exec_commands(&erosqnative_lcd_cmd_sleep[0]); + else + lcd_exec_commands(&erosqnative_lcd_cmd_wake[0]); +} |