summaryrefslogtreecommitdiffstats
path: root/firmware/target/mips/ingenic_jz47xx/xduoo_x3/lcd-xduoo_x3.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/mips/ingenic_jz47xx/xduoo_x3/lcd-xduoo_x3.c')
-rw-r--r--firmware/target/mips/ingenic_jz47xx/xduoo_x3/lcd-xduoo_x3.c158
1 files changed, 110 insertions, 48 deletions
diff --git a/firmware/target/mips/ingenic_jz47xx/xduoo_x3/lcd-xduoo_x3.c b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/lcd-xduoo_x3.c
index 0446fb2cce..47b646be34 100644
--- a/firmware/target/mips/ingenic_jz47xx/xduoo_x3/lcd-xduoo_x3.c
+++ b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/lcd-xduoo_x3.c
@@ -8,6 +8,7 @@
* $Id$
*
* Copyright (C) 2016 by Roman Stolyarov
+ * Copyright (C) 2020 by William Wilgus
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -44,6 +45,13 @@
#define PIN_LCD_RES (32*2+18)
#define PIN_LCD_WR (32*2+19)
+ /* LCD_PINS_MASK D0-D7 RD DC CS RES WR */
+#define LCD_PINS_MASK 0x000C73FC
+ /* LCD_DATA_MASK D0-D7 */
+#define LCD_DATA_MASK 0x000030FC
+/* FRAMEBUF_TO_LCD_DATA -- translate data to match LCD data pins */
+#define FRAMEBUF_TO_LCD_DATA(b) (((b & 0xC0) << 6) | ((b & 0x3F) << 2))
+
/* LCD setup codes */
#define LCD_SET_LOWER_COLUMN_ADDRESS ((char)0x00)
#define LCD_SET_HIGHER_COLUMN_ADDRESS ((char)0x10)
@@ -82,35 +90,37 @@
#define LCD_COL_OFFSET 2 /* column offset */
-static inline void bitdelay(void)
-{
- unsigned int i = 15;
- __asm__ __volatile__ (
- ".set noreorder \n"
- "1: \n"
- "bne %0, $0, 1b \n"
- "addi %0, %0, -1 \n"
- ".set reorder \n"
- : "=r" (i)
- : "0" (i)
- );
-}
+#define BITDELAY() \
+ do { \
+ volatile unsigned int i = 12; \
+ __asm__ __volatile__ ( \
+ ".set noreorder \n" \
+ "1: \n" \
+ "bne %0, $0, 1b \n" \
+ "addi %0, %0, -1 \n" \
+ ".set reorder \n" \
+ : "=r" (i) \
+ : "0" (i) \
+ ); \
+ } while (0)
void lcd_hw_init(void)
{
- REG_GPIO_PXFUNC(2) = 0x000C73FC; /* D0-D7 RD DC CS RES WR -- GPIO/INTERRUPT */
- REG_GPIO_PXSELC(2) = 0x000C73FC; /* GPIO */
+ REG_GPIO_PXFUNC(2) = LCD_PINS_MASK; /* GPIO/INTERRUPT */
+ REG_GPIO_PXSELC(2) = LCD_PINS_MASK; /* GPIO */
- REG_GPIO_PXPEC(2) = 0x000C73FC; /* ENABLE PULLUP*/
+ REG_GPIO_PXPEC(2) = LCD_PINS_MASK; /* ENABLE PULLUP*/
+ REG_GPIO_PXDIRS(2) = LCD_PINS_MASK; /* OUTPUT */
- REG_GPIO_PXDIRS(2) = 0x000C73FC; /* OUTPUT */
- REG_GPIO_PXDATS(2) = 0x000C73FC; /* D0-D7 RD DC CS RES WR -- SET BIT */
+ REG_GPIO_PXDATS(2) = LCD_PINS_MASK; /* SET BIT */
+ REG_GPIO_PXSLS(2) = LCD_PINS_MASK; /* slew -- fast rate */
- REG_GPIO_PXSLC(2) = 0x000C73FC; /* slew -- slow rate */
+ REG_GPIO_PXDS0C(2) = LCD_PINS_MASK; /* Low pin drive strength */
+ REG_GPIO_PXDS1C(2) = LCD_PINS_MASK;
+ REG_GPIO_PXDS2C(2) = LCD_PINS_MASK;
- REG_GPIO_PXDS0C(2) = 0x000C73FC; /* Low pin drive strength */
- REG_GPIO_PXDS1C(2) = 0x000C73FC;
- REG_GPIO_PXDS2C(2) = 0x000C73FC;
+ __gpio_clear_pin(PIN_LCD_RD); /* UNUSED */
+ __gpio_as_input(PIN_LCD_RD); /* UNUSED */
__gpio_clear_pin(PIN_BL_EN);
__gpio_as_output(PIN_BL_EN);
@@ -125,26 +135,64 @@ void lcd_hw_init(void)
void lcd_write_command(int byte)
{
__gpio_clear_pin(PIN_LCD_DC);
- REG_GPIO_PXDATC(2) = 0x000030FC;
- REG_GPIO_PXDATS(2) = ((byte & 0xC0) << 6) | ((byte & 0x3F) << 2);
+ REG_GPIO_PXDATC(2) = LCD_DATA_MASK;
+ REG_GPIO_PXDATS(2) = FRAMEBUF_TO_LCD_DATA(byte);
+ __gpio_clear_pin(PIN_LCD_WR);
+ BITDELAY();
+ __gpio_set_pin(PIN_LCD_WR);
+ BITDELAY();
+}
+
+static void lcd_write_cmd_triplet(int cmd1, int cmd2, int cmd3)
+{
+#if 0
+ lcd_write_command(cmd1);
+ lcd_write_command(cmd2);
+ lcd_write_command(cmd3);
+#else
+ int command = LCD_DATA_MASK;
+ __gpio_clear_pin(PIN_LCD_DC);
+
+ REG_GPIO_PXDATC(2) = command;
+ command = FRAMEBUF_TO_LCD_DATA(cmd1);
+ REG_GPIO_PXDATS(2) = command;
__gpio_clear_pin(PIN_LCD_WR);
- bitdelay();
+ BITDELAY();
__gpio_set_pin(PIN_LCD_WR);
- bitdelay();
+ BITDELAY();
+
+ REG_GPIO_PXDATC(2) = command;
+ command = FRAMEBUF_TO_LCD_DATA(cmd2);
+ REG_GPIO_PXDATS(2) = command;
+ __gpio_clear_pin(PIN_LCD_WR);
+ BITDELAY();
+ __gpio_set_pin(PIN_LCD_WR);
+ BITDELAY();
+
+ REG_GPIO_PXDATC(2) = command;
+ command = FRAMEBUF_TO_LCD_DATA(cmd3);
+ REG_GPIO_PXDATS(2) = command;
+ __gpio_clear_pin(PIN_LCD_WR);
+ BITDELAY();
+ __gpio_set_pin(PIN_LCD_WR);
+ BITDELAY();
+#endif
}
void lcd_write_data(const fb_data* p_bytes, int count)
{
+ int data = LCD_DATA_MASK;
__gpio_set_pin(PIN_LCD_DC);
while (count--)
{
- REG_GPIO_PXDATC(2) = 0x000030FC;
- REG_GPIO_PXDATS(2) = ((*p_bytes & 0xC0) << 6) | ((*p_bytes & 0x3F) << 2);
+ REG_GPIO_PXDATC(2) = data;
+ data = FRAMEBUF_TO_LCD_DATA(*p_bytes);
p_bytes++;
+ REG_GPIO_PXDATS(2) = data;
__gpio_clear_pin(PIN_LCD_WR);
- bitdelay();
+ BITDELAY();
__gpio_set_pin(PIN_LCD_WR);
- bitdelay();
+ BITDELAY();
}
}
@@ -275,6 +323,7 @@ void lcd_enable(bool enable)
{
lcd_write_command(LCD_SET_DISPLAY_OFF);
lcd_enable_power(enable);
+ REG_GPIO_PXDATC(2) = LCD_DATA_MASK;
}
}
@@ -296,7 +345,7 @@ void lcd_init_device(void)
/* Set display clock and oscillator frequency */
lcd_write_command(LCD_SET_DISPLAY_CLOCK_AND_OSC_FREQ);
- lcd_write_command(0x80);
+ lcd_write_command(0x00); /* External clock Bits [0-3] for divider */
/* Set multiplex ratio*/
lcd_write_command(LCD_SET_MULTIPLEX_RATIO);
@@ -386,9 +435,12 @@ void lcd_blit_mono(const unsigned char *data, int x, int by, int width,
/* Copy display bitmap to hardware */
while (bheight--)
{
- lcd_write_command (LCD_CNTL_PAGE | (by++ & 0xf));
- lcd_write_command (column_high);
- lcd_write_command (column_low);
+ lcd_write_cmd_triplet
+ (
+ (LCD_CNTL_PAGE | (by++ & 0xf)),
+ (column_high),
+ (column_low)
+ );
lcd_write_data(data, width);
data += stride;
@@ -405,6 +457,7 @@ void lcd_grey_data(unsigned char *values, unsigned char *phases, int count)
unsigned long *lval = (unsigned long *)values;
unsigned long *lpha = (unsigned long *)phases;
const unsigned long mask = 0x80808080;
+ int data = LCD_DATA_MASK;
__gpio_set_pin(PIN_LCD_DC);
while(count--)
@@ -421,13 +474,13 @@ void lcd_grey_data(unsigned char *values, unsigned char *phases, int count)
lpha[0] = lval[0] + (lpha[0] & ~mask);
lpha[1] = lval[1] + (lpha[1] & ~mask);
- REG_GPIO_PXDATC(2) = 0x000030FC;
- REG_GPIO_PXDATS(2) = ((ltmp & 0xC0) << 6) | ((ltmp & 0x3F) << 2);
+ REG_GPIO_PXDATC(2) = data;
+ data = FRAMEBUF_TO_LCD_DATA(ltmp);
+ REG_GPIO_PXDATS(2) = data;
__gpio_clear_pin(PIN_LCD_WR);
- bitdelay();
+ BITDELAY();
__gpio_set_pin(PIN_LCD_WR);
- bitdelay();
-
+ /*BITDELAY(); //enough instructions above to satisfy data hold time */
lpha+=2;
lval+=2;
}
@@ -450,9 +503,12 @@ void lcd_blit_grey_phase(unsigned char *values, unsigned char *phases,
/* Copy display bitmap to hardware */
while (bheight--)
{
- lcd_write_command (LCD_CNTL_PAGE | (by++ & 0xf));
- lcd_write_command (column_high);
- lcd_write_command (column_low);
+ lcd_write_cmd_triplet
+ (
+ (LCD_CNTL_PAGE | (by++ & 0xf)),
+ (column_high),
+ (column_low)
+ );
lcd_grey_data(values, phases, width);
@@ -479,9 +535,12 @@ void lcd_update(void)
/* Copy display bitmap to hardware */
for (y = 0; y < LCD_FBHEIGHT; y++)
{
- lcd_write_command (LCD_CNTL_PAGE | (y & 0xf));
- lcd_write_command (column_high);
- lcd_write_command (column_low);
+ lcd_write_cmd_triplet
+ (
+ (LCD_CNTL_PAGE | (y & 0xf)),
+ (column_high),
+ (column_low)
+ );
lcd_write_data (FBADDR(0, y), LCD_WIDTH);
}
@@ -530,9 +589,12 @@ void lcd_update_rect(int x, int y, int width, int height)
/* Copy specified rectange bitmap to hardware */
for (; y <= ymax; y++)
{
- lcd_write_command (LCD_CNTL_PAGE | (y & 0xf));
- lcd_write_command (column_high);
- lcd_write_command (column_low);
+ lcd_write_cmd_triplet
+ (
+ (LCD_CNTL_PAGE | (y & 0xf)),
+ (column_high),
+ (column_low)
+ );
lcd_write_data (FBADDR(x,y), width);
}