From d21c18d1f0746bfa575dc19d51d3b8fd9915074c Mon Sep 17 00:00:00 2001 From: bunnie Date: Mon, 15 Sep 2014 10:15:25 +0000 Subject: [PATCH] initial take at LCD API Nothing is correct at the moment, but basic commands are integrated into the shell, which will simplifying merging later on for files that are shared-edit. --- Makefile | 1 + cmd-lcd.c | 61 ++++++++++++++++++++++++++++++++++ include/fernvale-lcd.h | 74 ++++++++++++++++++++++++++++++++++++++++++ main.c | 6 ++++ 4 files changed, 142 insertions(+) create mode 100644 cmd-lcd.c create mode 100644 include/fernvale-lcd.h diff --git a/Makefile b/Makefile index d5ac070..428d084 100644 --- a/Makefile +++ b/Makefile @@ -18,6 +18,7 @@ SRC_C = \ cmd-spi.c \ cmd-led.c \ cmd-bl.c \ + cmd-lcd.c \ emi.c \ irq.c \ main.c \ diff --git a/cmd-lcd.c b/cmd-lcd.c new file mode 100644 index 0000000..71da37a --- /dev/null +++ b/cmd-lcd.c @@ -0,0 +1,61 @@ +#include +#include "bionic.h" +#include "memio.h" +#include "printf.h" +#include "serial.h" +#include "fernvale-lcd.h" + +// local implementation of strncmp() because we don't have it as a lib in fernly +static int my_strncmp(const char* s1, const char* s2, size_t n) +{ + while(n--) { + if( *s2 == '\0' ) // abort checking if we reach the end of s2 + return 0; + if(*s1++!=*s2++) + return *(unsigned char*)(s1 - 1) - *(unsigned char*)(s2 - 1); + } + return 0; +} + +int cmd_lcd(int argc, char **argv) +{ + uint32_t genarg = 0; + char *subcmd; + + if (argc < 1) { + printf("Usage: lcd [subcmd] [arg0]\n"); + return -1; + } + + subcmd = argv[0]; + + if (argc == 2 ) { + genarg = _strtoul(argv[1], NULL, 0); + } + + printf( "command got: %s\n", subcmd ); + if( my_strncmp( subcmd, "su", 8 ) == 0 ) { + // execute setup command + printf( "nothing for now.\n" ); + } else if( my_strncmp( subcmd, "dump", 8 ) == 0 ) { + // dump registers + printf( "LCD_PAR0_CMD_PORT_REG: %08x\n", *((volatile uint32_t *) LCD_PAR0_CMD_PORT_REG) ); + printf( "LCD_PAR0_DAT_PORT_REG: %08x\n", *((volatile uint32_t *) LCD_PAR0_DAT_PORT_REG) ); + printf( "LCD_PAR1_CMD_PORT_REG: %08x\n", *((volatile uint32_t *) LCD_PAR1_CMD_PORT_REG) ); + printf( "LCD_PAR1_DAT_PORT_REG: %08x\n", *((volatile uint32_t *) LCD_PAR1_DAT_PORT_REG) ); + printf( "LCD_PAR0_CFG_REG: %08x\n", *((volatile uint32_t *) LCD_PAR0_CFG_REG) ); + printf( "LCD_PAR1_CFG_REG: %08x\n", *((volatile uint32_t *) LCD_PAR1_CFG_REG) ); + printf( "LCD_STATUS_REG: %08x\n", *((volatile uint32_t *) LCD_STATUS_REG) ); + printf( "LCD_INT_ENA_REG: %08x\n", *((volatile uint32_t *) LCD_INT_ENA_REG) ); + printf( "LCD_INT_STAT_REG: %08x\n", *((volatile uint32_t *) LCD_INT_STAT_REG) ); + printf( "LCD_RUN_REG: %08x\n", *((volatile uint32_t *) LCD_RUN_REG) ); + printf( "LCD_RESET_REG: %08x\n", *((volatile uint32_t *) LCD_RESET_REG) ); + printf( "LCD_PAR_DATA_WIDTH_REG: %08x\n", *((volatile uint32_t *) LCD_PAR_DATA_WIDTH_REG) ); + printf( "LCD_TEARING_CON_REG: %08x\n", *((volatile uint32_t *) LCD_TEARING_CON_REG) ); + } else { + printf( "lcd commands: su (setup timing), dump (dump registers)\n" ); + } + + return 0; +} + diff --git a/include/fernvale-lcd.h b/include/fernvale-lcd.h new file mode 100644 index 0000000..2965f55 --- /dev/null +++ b/include/fernvale-lcd.h @@ -0,0 +1,74 @@ +#ifndef __FV_LCD_H__ +#define __FV_LCD_H__ + +// don't take values in here as gospel. some may be incorrect due to +// misinterpertation of reverse engineered values + +#define LCD_CTRL_ADDR 0xa0450000 + +#define LCD_PAR0_CMD_PORT_REG (LCD_CTRL_ADDR + 0x0F00) +#define LCD_PAR0_DAT_PORT_REG (LCD_CTRL_ADDR + 0x0F10) +#define LCD_PAR1_CMD_PORT_REG (LCD_CTRL_ADDR + 0x0F20) +#define LCD_PAR1_DAT_PORT_REG (LCD_CTRL_ADDR + 0x0F30) + +#define LCD_PAR0_CFG_REG (LCD_CTRL_ADDR + 0x0030) +#define LCD_PAR1_CFG_REG (LCD_CTRL_ADDR + 0x0034) +#define LCD_PAR_CFG_WR_WAIT_CYC_MASK (0x3F) +#define LCD_PAR_CFG_WR_WAIT_CYC_BIT (0) +#define LCD_PAR_CFG_WR_TSU_MASK (0xF00) +#define LCD_PAR_CFG_WR_TSU_BIT (8) +#define LCD_PAR_CFG_WR_TH_MASK (0xF000) +#define LCD_PAR_CFG_WR_TH_BIT (12) +#define LCD_PAR_CFG_RD_LATENCY_CYC_MASK (0x3F0000) +#define LCD_PAR_CFG_RD_LATENCY_CYC_BIT (16) +#define LCD_PAR_CFG_RD_TSU_MASK (0xF000000) +#define LCD_PAR_CFG_RD_TSU_BIT (24) +#define LCD_PAR_CFG_RD_TH_MASK (0xF0000000) +#define LCD_PAR_CFG_RD_TH_BIT (28) + +#define LCD_STATUS_REG (LCD_CTRL_ADDR + 0x0000) +#define LCD_STATUS_RUN_BIT (0x1) +#define LCD_STATUS_WAIT_CMDQ_BIT (0x2) +#define LCD_STATUS_WAIT_HTT_BIT (0x8) +#define LCD_STATUS_TE_PENDING_BIT (0x10) +#define LCD_STATUS_BUSY_BIT (0x20) +#define LCD_STATUS_GMC_REQ_BIT (0x40) + +#define LCD_INT_ENA_REG (LCD_CTRL_ADDR + 0x0004) +#define LCD_INT_ENA_TRIG_BIT (0x1) +#define LCD_INT_ENA_REG_TRIG_BIT (0x2) +#define LCD_INT_ENA_CMD_TRIG_BIT (0x4) +#define LCD_INT_ENA_HTT_TRIG_BIT (0x10) +#define LCD_INT_ENA_HSYNC_TRIG_BIT (0x20) +#define LCD_INT_ENA_VSYNC_TRIG_BIT (0x20) + +#define LCD_INT_STAT_REG (LCD_CTRL_ADDR + 0x0008) +#define LCD_INT_STAT_DONE_BIT (0x1) + +#define LCD_RUN_REG (LCD_CTRL_ADDR + 0x000C) +#define LCD_RUN_BIT (0x8000) + +#define LCD_RESET_REG (LCD_CTRL_ADDR + 0x0010) +#define LCD_RESET_BIT (0x1) // check polarity + +#define LCD_PAR_DATA_WIDTH_REG (LCD_CTRL_ADDR + 0x003C) +#define LCD_PAR_BUS_WIDTH0_MASK (0x7) +#define LCD_PAR_BUS_WIDTH0_BIT (0) +#define LCD_PAR_BUS_WIDTH1_MASK (0x70) +#define LCD_PAR_BUS_WIDTH1_BIT (4) +#define LCD_PAR_WAIT0_MASK (0xF0000) +#define LCD_PAR_WAIT0_BIT (16) +#define LCD_PAR_WAIT1_MASK (0xF00000) +#define LCD_PAR_WAIT1_BIT (20) +#define LCD_PAR_BUS_WIDTH_8BIT (0) // valid values for LCD_PAR_BUS_WIDTHn +#define LCD_PAR_BUS_WIDTH_9BIT (1) +#define LCD_PAR_BUS_WIDTH_16BIT (2) +#define LCD_PAR_BUS_WIDTH_18BIT (3) + + +#define LCD_TEARING_CON_REG (LCD_CTRL_ADDR + 0x0050) +#define LCD_TEARING_EN_BIT (0x1) +#define LCD_TEARING_SYNCEDGE_BIT (0x2) +#define LCD_TEARING_SW_FORCE_BIT (0x8000) + +#endif /* __FV_LCD_H__ */ diff --git a/main.c b/main.c index 8656a31..8ef2d74 100644 --- a/main.c +++ b/main.c @@ -341,6 +341,7 @@ extern int cmd_swi(int argc, char **argv); extern int cmd_reboot(int argc, char **argv); extern int cmd_led(int argc, char **argv); extern int cmd_bl(int argc, char **argv); +extern int cmd_lcd(int argc, char **argv); static const struct { int (*func)(int argc, char **argv); @@ -402,6 +403,11 @@ static const struct { .name = "bl", .help = "Set the LCD backlight brightness", }, + { + .func = cmd_lcd, + .name = "lcd", + .help = "Manipulate the LCD", + }, }; int cmd_help(int argc, char **argv)