summaryrefslogtreecommitdiff
path: root/firmware/target/mips/ingenic_x1000/shanlingq1/lcd-shanlingq1.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/mips/ingenic_x1000/shanlingq1/lcd-shanlingq1.c')
-rw-r--r--firmware/target/mips/ingenic_x1000/shanlingq1/lcd-shanlingq1.c399
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);
+}