From f03f74aa7bd75260194088d8c9855001c231e6ab Mon Sep 17 00:00:00 2001 From: Steve Markgraf Date: Mon, 11 Oct 2010 00:54:17 +0200 Subject: mtk_hack: This is very experimental code for running "loader" on MT622x-based devices Since this is just a hack and no proper separation, you have to upload compal_e88/loader.compalram.bin with osmocom -m mtk to the phone. Signed-off-by: Steve Markgraf --- src/target/firmware/Makefile | 7 +- src/target/firmware/apps/loader/main.c | 133 ++++++++++++++++++++++++------ src/target/firmware/board/compal/macros.S | 2 +- src/target/firmware/board/compal/ram.lds | 13 ++- src/target/firmware/calypso/uart.c | 116 ++++++++++++-------------- 5 files changed, 173 insertions(+), 98 deletions(-) diff --git a/src/target/firmware/Makefile b/src/target/firmware/Makefile index 56e0068e..347ce2c8 100644 --- a/src/target/firmware/Makefile +++ b/src/target/firmware/Makefile @@ -1,10 +1,10 @@ # List of all supported boards (meant to be overridden on command line) -BOARDS?=compal_e88 compal_e99 gta0x +BOARDS?=compal_e88 # List of all applications (meant to be overridden on command line) -APPLICATIONS?=hello_world compal_dsp_dump layer1 loader simtest chainload +APPLICATIONS?=loader # TI Calypso @@ -49,6 +49,7 @@ e99loader_LDS=board/compal_e99/loader.lds e99loader_OBJS=board/compal/header.o e99flash_LDS=board/compal_e99/flash.lds + # Global include path INCLUDES=-Iinclude/ -I../../../include -I../../shared/libosmocore/include @@ -59,7 +60,7 @@ ABB_OBJS=abb/twl3025.o RF_OBJS=rf/trf6151.o # Objects that go in all applications -ANY_APP_OBJS+=$(ABB_OBJS) $(RF_OBJS) $(DISPLAY_OBJS) $(FLASH_OBJS) +ANY_APP_OBJS+=$(FLASH_OBJS) ANY_APP_LIBS+=calypso/libcalypso.a layer1/liblayer1.a lib/libmini.a comm/libcomm.a ../../shared/libosmocore/build-target/src/.libs/libosmocore.a diff --git a/src/target/firmware/apps/loader/main.c b/src/target/firmware/apps/loader/main.c index fd10b192..81c36d78 100644 --- a/src/target/firmware/apps/loader/main.c +++ b/src/target/firmware/apps/loader/main.c @@ -52,6 +52,90 @@ #include "protocol.h" +/* MT6223 */ +//TODO split to separate drivers and put the register definitions there +#define GPIO_BASE 0x80120000 +#define GPIO_REG(n) (GPIO_BASE + n) +enum gpio_reg { + /* data direction registers */ + DIR1 = 0x00, + DIR2 = 0x10, + DIR3 = 0x20, + DIR4 = 0x30, + /* pull-up registers */ + PULLEN1 = 0x40, + PULLEN2 = 0x50, + PULLEN3 = 0x60, + PULLEN4 = 0x70, + /* data inversion registers */ + DINV1 = 0x80, + DINV2 = 0x90, + DINV3 = 0xa0, + DINV4 = 0xb0, + /* data output registers */ + DOUT1 = 0xc0,\ + DOUT2 = 0xd0, + DOUT3 = 0xe0, + DOUT4 = 0xf0, + /* data input registers */ + DIN1 = 0x0100, + DIN2 = 0x0110, + DIN3 = 0x0120, + DIN4 = 0x0130, + /*[...]*/ + BANK = 0x01c0, + + /* GPIO mode registers */ + MODE1 = 0x0150, + MODE2 = 0x0160, + MODE3 = 0x0170, + MODE4 = 0x0180, + MODE5 = 0x0190, + MODE6 = 0x01a0, + MODE7 = 0x01b0, + +}; + +#define CONFIG_BASE 0x80000000 +#define CONFIG_REG(n) (CONFIG_BASE + n) + +enum config_reg { + HW_VERSION = 0x00, + SW_VERSION = 0x04, + HW_CODE = 0x08, + + PDN_CON0 = 0x300, + PDN_CON1 = 0x304, + PDN_CON2 = 0x308, + PDN_CON3 = 0x30c, + PDN_CON4 = 0x330, + PDN_SET0 = 0x310, + PDN_SET1 = 0x314, + PDN_SET2 = 0x318, + PDN_SET3 = 0x31c, + PDN_CLR0 = 0x320, + PDN_CLR1 = 0x324, + PDN_CLR2 = 0x328, + PDN_CLR3 = 0x32c, + PDN_CLR4 = 0x338, + + APB_CON = 0x404, + AHB_CON = 0x500, +}; + +#define MAGIC_POWERKEY1 0xa357 +#define MAGIC_POWERKEY2 0x67d2 +#define RTC_BASE 0x80210000 +#define RGU_BASE 0x80040000 + +#define RTC_REG(n) (RTC_BASE + n) + +enum rtc_reg { + BBPU = 0x00, + POWERKEY1 = 0x50, + POWERKEY2 = 0x54, +}; + /* Main Program */ const char *hr = "======================================================================\n"; @@ -73,21 +157,21 @@ static void flush_uart(void) static void device_poweroff(void) { flush_uart(); - twl3025_power_off(); + writew(0x430a, RTC_REG(BBPU)); } static void device_reset(void) { flush_uart(); - wdog_reset(); +// wdog_reset(); } static void device_enter_loader(unsigned char bootrom) { flush_uart(); - - calypso_bootrom(bootrom); - void (*entry) (void) = (void (*)(void))0; + delay_ms(2000); +// calypso_bootrom(bootrom); + void (*entry)( void ) = (void (*)(void))0; entry(); } @@ -124,21 +208,20 @@ static const uint8_t phone_ack[] = { 0x1b, 0xf6, 0x02, 0x00, 0x41, 0x03, 0x42 }; int main(void) { - /* Simulate a compal loader saying "ACK" */ - int i = 0; - for (i = 0; i < sizeof(phone_ack); i++) { - putchar_asm(phone_ack[i]); - } + /* powerup the baseband */ + writew(MAGIC_POWERKEY1, RTC_REG(POWERKEY1)); + writew(MAGIC_POWERKEY2, RTC_REG(POWERKEY2)); + writew(0x430e, RTC_REG(BBPU)); - /* Always disable wdt (some platforms enable it on boot) */ - wdog_enable(0); + /* disable watchdog timer */ + writew(0x2200, RGU_BASE); - /* Initialize TWL3025 for power control */ - twl3025_init(); - - /* Backlight */ - bl_mode_pwl(1); - bl_level(50); + /* power _everything_ on for now */ + writew(0xffff, CONFIG_REG(PDN_CLR0)); + writew(0xffff, CONFIG_REG(PDN_CLR1)); + writew(0xffff, CONFIG_REG(PDN_CLR2)); + writew(0xffff, CONFIG_REG(PDN_CLR3)); + writew(0xffff, CONFIG_REG(PDN_CLR4)); /* Initialize UART without interrupts */ uart_init(SERCOMM_UART_NR, 0); @@ -155,8 +238,12 @@ int main(void) printf("Running on %s in environment %s\n", manifest_board, manifest_environment); + printf("HW_VERSION = 0x%04x\n", readw(CONFIG_REG(HW_VERSION))); + printf("SW_VERSION = 0x%04x\n", readw(CONFIG_REG(SW_VERSION))); + printf("HW_CODE = 0x%04x\n", readw(CONFIG_REG(HW_CODE))); + /* Initialize flash driver */ - if (flash_init(&the_flash, 0)) { +/* if (flash_init(&the_flash, 0)) { puts("Failed to initialize flash!\n"); } else { printf("Found flash of %d bytes at 0x%x with %d regions\n", @@ -172,25 +259,25 @@ int main(void) } } +*/ /* Set up a key handler for powering off */ - keypad_set_handler(&key_handler); +// keypad_set_handler(&key_handler); /* Set up loader communications */ sercomm_register_rx_cb(SC_DLCI_LOADER, &cmd_handler); /* Notify any running osmoload about our startup */ - loader_send_init(SC_DLCI_LOADER); +// loader_send_init(SC_DLCI_LOADER); /* Wait for events */ while (1) { - keypad_poll(); uart_poll(SERCOMM_UART_NR); } /* NOT REACHED */ - twl3025_power_off(); +// twl3025_power_off(); } static void cmd_handler(uint8_t dlci, struct msgb *msg) diff --git a/src/target/firmware/board/compal/macros.S b/src/target/firmware/board/compal/macros.S index 613e6bda..14ee6e6a 100644 --- a/src/target/firmware/board/compal/macros.S +++ b/src/target/firmware/board/compal/macros.S @@ -44,7 +44,7 @@ done_ramtext: .EQU I_BIT, 0x80 .EQU F_BIT, 0x40 -#define TOP_OF_RAM 0x083fff0 +#define TOP_OF_RAM 0x4000a000 #define FIQ_STACK_SIZE 1024 #define IRQ_STACK_SIZE 1024 diff --git a/src/target/firmware/board/compal/ram.lds b/src/target/firmware/board/compal/ram.lds index 342870dc..1bff82bd 100644 --- a/src/target/firmware/board/compal/ram.lds +++ b/src/target/firmware/board/compal/ram.lds @@ -11,19 +11,16 @@ ENTRY(_start) MEMORY { /* compal-loaded binary: our text, initialized data */ - LRAM (rw) : ORIGIN = 0x00800000, LENGTH = 0x00010000 + LRAM (rw) : ORIGIN = 0x40000000, LENGTH = 0x00005000 /* compal-loaded binary: our unitialized data, stacks, heap */ - IRAM (rw) : ORIGIN = 0x00810000, LENGTH = 0x00010000 + IRAM (rw) : ORIGIN = 0x40005000, LENGTH = 0x00005000 } SECTIONS { - . = 0x800000; + . = 0x40000000; /* romloader data section, contains passthru interrupt vectors */ - .compal.loader (NOLOAD) : { . = 0x100; } > LRAM - - /* image signature (prepended by osmocon according to phone type) */ - .compal.header (NOLOAD) : { . = 4; } > LRAM + .compal.loader (NOLOAD) : { . = 0x1400; } > LRAM /* initialization code */ . = ALIGN(4); @@ -34,7 +31,7 @@ SECTIONS } > LRAM /* exception vectors from 0x80001c to 0x800034 */ - .text.exceptions 0x80001c : AT (LOADADDR(.text.start) + SIZEOF(.text.start)) { + .text.exceptions 0x4000001c : AT (LOADADDR(.text.start) + SIZEOF(.text.start)) { KEEP(*(.text.exceptions)) * (.text.exceptions) . = ALIGN(4); diff --git a/src/target/firmware/calypso/uart.c b/src/target/firmware/calypso/uart.c index a46fff91..99be60b1 100644 --- a/src/target/firmware/calypso/uart.c +++ b/src/target/firmware/calypso/uart.c @@ -1,7 +1,8 @@ -/* Calypso DBB internal UART Driver */ +/* MediaTek MT622x internal UART Driver */ /* (C) 2010 by Harald Welte * (C) 2010 by Ingo Albrecht + * (C) 2010 by Steve Markgraf * * All Rights Reserved * @@ -35,10 +36,12 @@ #include #include -#define BASE_ADDR_UART_MODEM 0xffff5000 -#define OFFSET_IRDA 0x800 +#define BASE_ADDR_UART1 0x80130000 +#define BASE_ADDR_UART2 0x80180000 +#define BASE_ADDR_UART3 0x801b0000 -#define UART_REG(n,m) (BASE_ADDR_UART_MODEM + ((n)*OFFSET_IRDA)+(m)) +//TODO make UART2 and 3 work +#define UART_REG(n,m) (BASE_ADDR_UART1 + (m)) #define LCR7BIT 0x80 #define LCRBFBIT 0x40 @@ -46,46 +49,39 @@ #define REG_OFFS(m) ((m) &= ~(LCR7BIT|LCRBFBIT|MCR6BIT)) /* read access LCR[7] = 0 */ enum uart_reg { - RHR = 0, - IER = 1, - IIR = 2, - LCR = 3, - MCR = 4, - LSR = 5, - MSR = 6, - SPR = 7, - MDR1 = 8, - DMR2 = 9, - SFLSR = 0x0a, - RESUME = 0x0b, - SFREGL = 0x0c, - SFREGH = 0x0d, - BLR = 0x0e, - ACREG = 0x0f, - SCR = 0x10, - SSR = 0x11, - EBLR = 0x12, + RBR = 0x00, + IER = 0x04, + IIR = 0x08, + LCR = 0x0c, + MCR = 0x10, + LSR = 0x14, + MSR = 0x18, + SCR = 0x1c, + AUTOBAUD_EN = 0x20, + HIGHSPEED = 0x24, + SAMPLE_COUNT = 0x28, + SAMPLE_POINT = 0x2c, + AUTOBAUD_REG = 0x30, + RATE_FIX_REG = 0x34, /* undocumented */ + AUTOBAUDSAMPLE = 0x38, + GUARD = 0x3c, + ESCAPE_DAT = 0x40, + ESCAPE_EN = 0x44, + SLEEP_EN = 0x48, + VFIFO_EN = 0x4c, /* read access LCR[7] = 1 */ - DLL = RHR | LCR7BIT, - DLH = IER | LCR7BIT, - DIV1_6 = ACREG | LCR7BIT, + DLL = RBR, + DLH = IER, /* read/write access LCR[7:0] = 0xbf */ EFR = IIR | LCRBFBIT, XON1 = MCR | LCRBFBIT, XON2 = LSR | LCRBFBIT, XOFF1 = MSR | LCRBFBIT, - XOFF2 = SPR | LCRBFBIT, -/* read/write access if EFR[4] = 1 and MCR[6] = 1 */ - TCR = MSR | MCR6BIT, - TLR = SPR | MCR6BIT, + XOFF2 = SCR | LCRBFBIT, }; -/* write access LCR[7] = 0 */ -#define THR RHR -#define FCR IIR /* only if EFR[4] = 1 */ -#define TXFLL SFLSR -#define TXFLH RESUME -#define RXFLL SFREGL -#define RXFLH SFREGH +/* write access */ +#define THR RBR +#define FCR IIR enum fcr_bits { FIFO_EN = (1 << 0), @@ -101,7 +97,7 @@ enum iir_bits { IIR_INT_TYPE = 0x3E, IIR_INT_TYPE_RX_STATUS_ERROR = 0x06, IIR_INT_TYPE_RX_TIMEOUT = 0x0C, - IIR_INT_TYPE_RHR = 0x04, + IIR_INT_TYPE_RBR = 0x04, IIR_INT_TYPE_THR = 0x02, IIR_INT_TYPE_MSR = 0x00, IIR_INT_TYPE_XOFF = 0x10, @@ -109,7 +105,6 @@ enum iir_bits { IIR_FCR0_MIRROR = 0xC0, }; -#define UART_REG_UIR 0xffff6000 /* enable or disable the divisor latch for access to DLL, DLH */ static void uart_set_lcr7bit(int uart, int on) @@ -203,7 +198,7 @@ static void uart_irq_handler_cons(__unused enum irq_nr irqnr) return; switch (iir & IIR_INT_TYPE) { - case IIR_INT_TYPE_RHR: + case IIR_INT_TYPE_RBR: break; case IIR_INT_TYPE_THR: if (cons_rb_flush() == 1) { @@ -237,7 +232,7 @@ static void uart_irq_handler_sercomm(__unused enum irq_nr irqnr) switch (iir & IIR_INT_TYPE) { case IIR_INT_TYPE_RX_TIMEOUT: - case IIR_INT_TYPE_RHR: + case IIR_INT_TYPE_RBR: /* as long as we have rx data available */ while (uart_getchar_nb(uart, &ch)) { if (sercomm_drv_rx_char(ch) < 0) { @@ -304,22 +299,15 @@ void uart_init(uint8_t uart, uint8_t interrupts) } #endif - /* if we don't initialize these, we get strange corruptions in the - received data... :-( */ - uart_reg_write(uart, MDR1, 0x07); /* turn off UART */ - uart_reg_write(uart, XON1, 0x00); /* Xon1/Addr Register */ - uart_reg_write(uart, XON2, 0x00); /* Xon2/Addr Register */ - uart_reg_write(uart, XOFF1, 0x00); /* Xoff1 Register */ - uart_reg_write(uart, XOFF2, 0x00); /* Xoff2 Register */ - uart_reg_write(uart, EFR, 0x00); /* Enhanced Features Register */ - - /* select UART mode */ - uart_reg_write(uart, MDR1, 0); + uart_reg_write(uart, AUTOBAUD_EN, 0x00); /* disable AUTOBAUD */ + uart_reg_write(uart, EFR, 0x10); /* Enhanced Features Register */ + /* no XON/XOFF flow control, ENHANCED_EN, no auto-RTS/CTS */ uart_reg_write(uart, EFR, (1 << 4)); /* enable Tx/Rx FIFO, Tx trigger at 56 spaces, Rx trigger at 60 chars */ + //FIXME check those FIFO settings uart_reg_write(uart, FCR, FIFO_EN | RX_FIFO_CLEAR | TX_FIFO_CLEAR | - (3 << TX_FIFO_TRIG_SHIFT) | (3 << RX_FIFO_TRIG_SHIFT)); + (3 << TX_FIFO_TRIG_SHIFT) | (1 << RX_FIFO_TRIG_SHIFT)); /* THR interrupt only when TX FIFO and TX shift register are empty */ uart_reg_write(uart, SCR, (1 << 0));// | (1 << 3)); @@ -364,7 +352,7 @@ void uart_irq_enable(uint8_t uart, enum uart_irq irq, int on) void uart_putchar_wait(uint8_t uart, int c) { /* wait while TX FIFO indicates full */ - while (readb(UART_REG(uart, SSR)) & 0x01) { } + while (~readb(UART_REG(uart, LSR)) & 0x20) { } /* put character in TX FIFO */ writeb(c, UART_REG(uart, THR)); @@ -373,7 +361,7 @@ void uart_putchar_wait(uint8_t uart, int c) int uart_putchar_nb(uint8_t uart, int c) { /* if TX FIFO indicates full, abort */ - if (readb(UART_REG(uart, SSR)) & 0x01) + if (~readb(UART_REG(uart, LSR)) & 0x20) return 0; writeb(c, UART_REG(uart, THR)); @@ -402,25 +390,27 @@ int uart_getchar_nb(uint8_t uart, uint8_t *ch) if (!(lsr & 0x01)) return 0; - *ch = readb(UART_REG(uart, RHR)); + *ch = readb(UART_REG(uart, RBR)); //printf("getchar_nb(%u) = %02x\n", uart, *ch); return 1; } int uart_tx_busy(uint8_t uart) { - if (readb(UART_REG(uart, SSR)) & 0x01) + /* Check THRE bit (LSR[5]) to see if FIFO is full */ + if (~readb(UART_REG(uart, LSR)) & 0x20) return 1; return 0; } +/* currently only valid for 26MHz clock input */ static const uint16_t divider[] = { - [UART_38400] = 21, /* 38,690 */ - [UART_57600] = 14, /* 58,035 */ - [UART_115200] = 7, /* 116,071 */ - [UART_230400] = 4, /* 203,125! (-3% would be 223,488) */ - [UART_460800] = 2, /* 406,250! (-3% would be 446,976) */ - [UART_921600] = 1, /* 812,500! (-3% would be 893,952) */ + [UART_38400] = 42, + [UART_57600] = 28, + [UART_115200] = 14, + [UART_230400] = 7, + [UART_460800] = 14, /* would need UART_REG(HIGHSPEED) = 1 or 2 */ + [UART_921600] = 7, /* would need UART_REG(HIGHSPEED) = 2 */ }; int uart_baudrate(uint8_t uart, enum uart_baudrate bdrt) -- cgit v1.2.3