diff options
Diffstat (limited to 'firmware/target/mips/ingenic_x1000/shanlingq1/lcd-shanlingq1.c')
-rw-r--r-- | firmware/target/mips/ingenic_x1000/shanlingq1/lcd-shanlingq1.c | 399 |
1 files changed, 399 insertions, 0 deletions
diff --git a/firmware/target/mips/ingenic_x1000/shanlingq1/lcd-shanlingq1.c b/firmware/target/mips/ingenic_x1000/shanlingq1/lcd-shanlingq1.c new file mode 100644 index 0000000000..532a149185 --- /dev/null +++ b/firmware/target/mips/ingenic_x1000/shanlingq1/lcd-shanlingq1.c @@ -0,0 +1,399 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2021 Aidan MacDonald + * + * 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 "system.h" +#include "lcd-x1000.h" +#include "gpio-x1000.h" + +/* LCD controller is probably an RM68090. + */ + +static const uint32_t q1_lcd_cmd_enable[] = { + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0xbe, + LCD_INSTR_DAT, 0xc3, + LCD_INSTR_DAT, 0x29, + + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0x01, + LCD_INSTR_DAT, 0x01, + LCD_INSTR_DAT, 0x04, + + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0x02, + LCD_INSTR_DAT, 0x01, + LCD_INSTR_DAT, 0x00, + + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0x03, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x10, + + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0x05, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x00, + + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0x06, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x00, + + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0x07, + LCD_INSTR_DAT, 0x01, + LCD_INSTR_DAT, 0x03, + + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0x08, + LCD_INSTR_DAT, 0x03, + LCD_INSTR_DAT, 0x03, + + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0x0d, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x00, + + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0x10, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0xc1, + + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0x11, + LCD_INSTR_DAT, 0xb1, + LCD_INSTR_DAT, 0x08, + + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0x12, + LCD_INSTR_DAT, 0xb1, + LCD_INSTR_DAT, 0x08, + + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0x13, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x0f, + + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0x14, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x14, + + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0x15, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x04, + + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0x16, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x00, + + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0x22, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x00, + + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0x23, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x00, + + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0x30, + LCD_INSTR_DAT, 0x7c, + LCD_INSTR_DAT, 0x3f, + + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0x32, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x00, + + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0x70, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x01, + + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0x91, + LCD_INSTR_DAT, 0x01, + LCD_INSTR_DAT, 0x00, + + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0xe0, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x01, + + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0xe1, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x61, + + LCD_INSTR_CMD, 0x01, + LCD_INSTR_CMD, 0x00, + LCD_INSTR_DAT, 0x10, + LCD_INSTR_DAT, 0x30, + + LCD_INSTR_CMD, 0x01, + LCD_INSTR_CMD, 0x01, + LCD_INSTR_DAT, 0xf6, + LCD_INSTR_DAT, 0x3f, + + LCD_INSTR_CMD, 0x01, + LCD_INSTR_CMD, 0x02, + LCD_INSTR_DAT, 0x50, + LCD_INSTR_DAT, 0x1f, + + LCD_INSTR_CMD, 0x01, + LCD_INSTR_CMD, 0x03, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x30, + + LCD_INSTR_CMD, 0x01, + LCD_INSTR_CMD, 0x08, + LCD_INSTR_DAT, 0x03, + LCD_INSTR_DAT, 0x00, + + LCD_INSTR_CMD, 0x01, + LCD_INSTR_CMD, 0x11, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x01, + + LCD_INSTR_CMD, 0x01, + LCD_INSTR_CMD, 0x35, + LCD_INSTR_DAT, 0x76, + LCD_INSTR_DAT, 0x66, + + LCD_INSTR_CMD, 0x01, + LCD_INSTR_CMD, 0x39, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x26, + + LCD_INSTR_CMD, 0x04, + LCD_INSTR_CMD, 0x00, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0xc7, + + LCD_INSTR_CMD, 0x04, + LCD_INSTR_CMD, 0x01, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x00, + + LCD_INSTR_CMD, 0x06, + LCD_INSTR_CMD, 0x06, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x00, + + LCD_INSTR_CMD, 0x03, + LCD_INSTR_CMD, 0x00, + LCD_INSTR_DAT, 0x0d, + LCD_INSTR_DAT, 0x0e, + + LCD_INSTR_CMD, 0x03, + LCD_INSTR_CMD, 0x01, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x03, + + LCD_INSTR_CMD, 0x03, + LCD_INSTR_CMD, 0x02, + LCD_INSTR_DAT, 0x08, + LCD_INSTR_DAT, 0x08, + + LCD_INSTR_CMD, 0x03, + LCD_INSTR_CMD, 0x03, + LCD_INSTR_DAT, 0x02, + LCD_INSTR_DAT, 0x01, + + LCD_INSTR_CMD, 0x03, + LCD_INSTR_CMD, 0x04, + LCD_INSTR_DAT, 0x03, + LCD_INSTR_DAT, 0x01, + + LCD_INSTR_CMD, 0x03, + LCD_INSTR_CMD, 0x05, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x04, + + LCD_INSTR_CMD, 0x03, + LCD_INSTR_CMD, 0x06, + LCD_INSTR_DAT, 0x1b, + LCD_INSTR_DAT, 0x21, + + LCD_INSTR_CMD, 0x03, + LCD_INSTR_CMD, 0x07, + LCD_INSTR_DAT, 0x0f, + LCD_INSTR_DAT, 0x0e, + + LCD_INSTR_CMD, 0x03, + LCD_INSTR_CMD, 0x08, + LCD_INSTR_DAT, 0x01, + LCD_INSTR_DAT, 0x04, + + LCD_INSTR_CMD, 0x03, + LCD_INSTR_CMD, 0x09, + LCD_INSTR_DAT, 0x08, + LCD_INSTR_DAT, 0x08, + + LCD_INSTR_CMD, 0x03, + LCD_INSTR_CMD, 0x0a, + LCD_INSTR_DAT, 0x02, + LCD_INSTR_DAT, 0x01, + + LCD_INSTR_CMD, 0x03, + LCD_INSTR_CMD, 0x0b, + LCD_INSTR_DAT, 0x03, + LCD_INSTR_DAT, 0x01, + + LCD_INSTR_CMD, 0x03, + LCD_INSTR_CMD, 0x0c, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x03, + + LCD_INSTR_CMD, 0x03, + LCD_INSTR_CMD, 0x0d, + LCD_INSTR_DAT, 0x31, + LCD_INSTR_DAT, 0x34, + + /* X start */ + LCD_INSTR_CMD, 0x02, + LCD_INSTR_CMD, 0x10, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x1e, /* 30 */ + + /* X end */ + LCD_INSTR_CMD, 0x02, + LCD_INSTR_CMD, 0x11, + LCD_INSTR_DAT, 0x01, + LCD_INSTR_DAT, 0x85, /* 389 */ + + /* Y start */ + LCD_INSTR_CMD, 0x02, + LCD_INSTR_CMD, 0x12, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x00, /* 0 */ + + /* Y end */ + LCD_INSTR_CMD, 0x02, + LCD_INSTR_CMD, 0x13, + LCD_INSTR_DAT, 0x01, + LCD_INSTR_DAT, 0x8f, /* 399 */ + + /* RAM write start X? */ + LCD_INSTR_CMD, 0x02, + LCD_INSTR_CMD, 0x00, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x1e, + + /* RAM write start Y? */ + LCD_INSTR_CMD, 0x02, + LCD_INSTR_CMD, 0x01, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x00, + + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0x03, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x30, + + LCD_INSTR_CMD, 0x02, + LCD_INSTR_CMD, 0x02, + LCD_INSTR_END, +}; + +/* NOTE this sleep mode may not be saving power, but it gets rid of the + * ghost image that would otherwise remain on the display */ +static const uint32_t q1_lcd_cmd_sleep[] = { + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0x10, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0x03, + + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0x07, + LCD_INSTR_DAT, 0x01, + LCD_INSTR_DAT, 0x01, + + LCD_INSTR_END, +}; + +static const uint32_t q1_lcd_cmd_wake[] = { + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0x07, + LCD_INSTR_DAT, 0x01, + LCD_INSTR_DAT, 0x03, + + LCD_INSTR_CMD, 0x00, + LCD_INSTR_CMD, 0x10, + LCD_INSTR_DAT, 0x00, + LCD_INSTR_DAT, 0xc1, + + LCD_INSTR_END, +}; + +static const uint8_t __attribute__((aligned(64))) + q1_lcd_dma_wr_cmd[] = {0x02, 0x02, 0x02, 0x02}; + +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, + .big_endian = 1, + .dma_wr_cmd_buf = &q1_lcd_dma_wr_cmd, + .dma_wr_cmd_size = sizeof(q1_lcd_dma_wr_cmd), +}; + +void lcd_tgt_enable(bool enable) +{ + if(enable) { + /* power on the panel */ + gpio_set_level(GPIO_LCD_PWR, 1); + gpio_set_level(GPIO_LCD_RST, 1); + gpio_set_level(GPIO_LCD_CE, 1); + gpio_set_level(GPIO_LCD_RD, 1); + mdelay(50); + gpio_set_level(GPIO_LCD_RST, 0); + mdelay(100); + gpio_set_level(GPIO_LCD_RST, 1); + mdelay(50); + gpio_set_level(GPIO_LCD_CE, 0); + + /* Start the controller */ + lcd_set_clock(X1000_CLK_MPLL, 50000000); + lcd_exec_commands(q1_lcd_cmd_enable); + } else { + /* FIXME: Shanling Q1 LCD power down sequence + * not important because we don't use it but it'd be nice to know */ + } +} + +void lcd_tgt_sleep(bool sleep) +{ + if(sleep) + lcd_exec_commands(q1_lcd_cmd_sleep); + else + lcd_exec_commands(q1_lcd_cmd_wake); +} |