diff --git a/.gitignore b/.gitignore index 0b912a3..7478ff5 100644 --- a/.gitignore +++ b/.gitignore @@ -3,9 +3,13 @@ iris.raw iris.raw.gz uimage *.o +*.elf *.cc *.hh gpio lcd init +udc boot-programs/charset.data +mips/nanonote/sdram-setup.raw +nanonote-boot diff --git a/Makefile b/Makefile index 4bf4970..6686784 100644 --- a/Makefile +++ b/Makefile @@ -43,7 +43,7 @@ PYPP = /usr/bin/pypp $(CC) $(CPPFLAGS) $(TARGET_FLAGS) $(CXXFLAGS) -c $< -o $@ %: boot-programs/crt0.o boot-programs/%.o - $(LD) $(filter %.o,$^) -o $@ + $(LD) $(LDFLAGS) $(filter %.o,$^) -o $@ #$(OBJCOPY) -S $(OBJCOPYFLAGS) $@ clean: diff --git a/boot-programs/init.ccp b/boot-programs/init.ccp index 812634e..b79601f 100644 --- a/boot-programs/init.ccp +++ b/boot-programs/init.ccp @@ -84,6 +84,8 @@ Kernel::Num start (): if code & Keyboard::RELEASE: break kdebug_char (decode_kbd[code]) + if code == 0: + Kernel::Caps ().print (~0) break case TP: unsigned leds = 0 diff --git a/boot-programs/init.hhp b/boot-programs/init.hhp index 6108ca7..b3b11fb 100644 --- a/boot-programs/init.hhp +++ b/boot-programs/init.hhp @@ -32,7 +32,7 @@ struct Init : public Kernel::Cap: GPIO_LOCKLEDS GPIO_PWM LCD_SET_EOF_CB - LCD_LOG + LOG void register_gpio (): Kernel::Caps c = Kernel::my_memory.create_caps (4) unsigned slot = c.use () diff --git a/boot-programs/lcd.ccp b/boot-programs/lcd.ccp index 72e1177..7a354b9 100644 --- a/boot-programs/lcd.ccp +++ b/boot-programs/lcd.ccp @@ -40,6 +40,7 @@ struct Descriptor: unsigned id unsigned cmd +#if defined (TRENDTAC) static void reset (): LCD_CTRL = LCD_CTRL_BPP_16 | LCD_CTRL_BST_16 LCD_VSYNC = vs @@ -68,6 +69,12 @@ static void reset (): LCD_DA0 = physical_descriptor lcd_set_ena () lcd_enable_eof_intr () +#elif defined (NANONOTE) +static void reset (): + // TODO +#else +#error unknown board +#endif static void putchar (unsigned x, unsigned y, unsigned ch, unsigned fg = 0xffff, unsigned bg = 0x0000): if ch < 32 || ch > 126: @@ -163,7 +170,6 @@ Kernel::Num start (): ((Init)Kernel::my_parent).register_lcd () - unsigned slot = Kernel::alloc_slot () Kernel::Cap eof_cb = Kernel::alloc_cap () while true: Kernel::wait () diff --git a/boot-programs/udc.ccp b/boot-programs/udc.ccp new file mode 100644 index 0000000..b517f5b --- /dev/null +++ b/boot-programs/udc.ccp @@ -0,0 +1,317 @@ +#pypp 0 +// Iris: micro-kernel for a capability-based operating system. +// boot-programs/udc.ccp: USB device controller driver. +// Copyright 2009 Bas Wijnen +// +// 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 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "devices.hh" +#include "init.hh" +#define ARCH +#include "arch.hh" + +class Udc: + typedef unsigned char u8 + typedef unsigned short u16 + typedef unsigned int u32 + typedef u8 string + // The ugly stuff is because pypp doesn't support __attribute__. + /**/struct Setup { + u8 request_type; + u8 request; + u16 value; + u16 index; + u16 length; + } __attribute__ ((packed)) + /**/struct Device { + static u8 const Type = 1; + u8 length; + u8 type; + u16 usb_version; + u8 dev_class; + u8 subclass; + u8 protocol; + u8 max_packet_size0; + u16 vendor; + u16 product; + u16 dev_version; + string s_manufacturer; + string s_product; + string s_serial; + u8 num_configurations; + } __attribute__ ((packed)) + /**/struct Configuration { + static u8 const Type = 2; + u8 length; + u8 type; + u16 total_length; + u8 num_interfaces; + u8 configuration_value; + u8 configuration; + u8 attributes; + u8 max_power; + } __attribute__ ((packed)) + /**/struct Interface { + static u8 const Type = 4; + u8 length; + u8 type; + u8 interface; + u8 alternate; + u8 num_endpoints; + u8 iface_class; + u8 subclass; + u8 protocol; + string name; + } __attribute__ ((packed)) + /**/struct Endpoint { + static u8 const Type = 5; + u8 length; + u8 type; + u8 address; + u8 attributes; + u16 max_packet_size; + u8 interval; + } __attribute__ ((packed)) + template struct String { + static u8 const Type = 3; + u8 length; + u8 type; + u16 data[size]; + } __attribute__ ((packed)) + static unsigned const max_packet_size0 = 64 + static unsigned const max_packet_size_bulk = 512 + enum Requests: + GET_STATUS = 0 + CLEAR_FEATURE = 1 + SET_FEATURE = 3 + SET_ADDRESS = 5 + GET_DESCRIPTOR = 6 + SET_DESCRIPTOR = 7 + GET_CONFIGURATION = 8 + SET_CONFIGURATION = 9 + GET_INTERFACE = 10 + SET_INTERFACE = 11 + SYNCH_FRAME = 12 + enum Request_types: + STANDARD_TO_DEVICE = 0 + VENDOR_TO_DEVICE = 0x40 + STANDARD_FROM_DEVICE = 0x80 + VENDOR_FROM_DEVICE = 0xc0 + enum Endpoint_types: + CONTROL = 0 + ISOCHRONOUS = 1 + BULK = 2 + INTERRUPT = 3 + /**/struct my_config { + Configuration config; + Interface interface; + Endpoint endpoint[2]; + } __attribute__ ((packed)) + static Device const device_descriptor + static my_config const config_descriptor + static String <7> const s_manufacturer + static String <22> const s_product + enum State: + IDLE + TX + RX + State state + char configuration + unsigned size + char const *ptr + unsigned send_next (unsigned old_csr) + unsigned vendor (unsigned old_csr, Setup *s) + unsigned get_descriptor (unsigned old_csr, unsigned type, unsigned idx, unsigned len) + public: + void init () + void log (unsigned c) + void interrupt () + unsigned handle_setup (unsigned old_csr, Setup *s) + +Udc::Device const Udc::device_descriptor = { sizeof (Device), Device::Type, 0x200, 0, 0, 0, max_packet_size0, 0x601a, 0x4740, 0x100, 1, 2, 0, 1 } +Udc::my_config const Udc::config_descriptor = { + (Configuration){ sizeof (Configuration), Configuration::Type, sizeof (my_config), 1, 1, 0, 0xc0, 1 }, + (Interface){ sizeof (Interface), Interface::Type, 0, 0, 2, 0xff, 0, 0x80, 0 }, { + (Endpoint){ sizeof (Endpoint), Endpoint::Type, 1, BULK, max_packet_size_bulk, 0 }, + (Endpoint){ sizeof (Endpoint), Endpoint::Type, 0x81, BULK, max_packet_size_bulk, 0 } + } + } +Udc::String <7> const Udc::s_manufacturer = { sizeof (String <7>), String <7>::Type, { 'I', 'n', 'g', 'e', 'n', 'i', 'c' } } +Udc::String <22> const Udc::s_product = { sizeof (String <22>), String <22>::Type, { 'J', 'Z', '4', '7', '4', '0', ' ', 'U', 'S', 'B', ' ', 'B', 'o', 'o', 't', ' ', 'D', 'e', 'v', 'i', 'c', 'e'} } +void Udc::init (): + state = IDLE + configuration = 0 + size = 0 + // exit suspend mode by reading the interrupt register. + unsigned i = UDC_INTRUSB + // reset all pending endpoint interrupts. + i = UDC_INTRIN + i = UDC_INTROUT + // enable interrupt on bus reset. + UDC_INTRUSB = UDC_INTR_RESET + // enable interrupts on endpoint 0. + UDC_INTRINE |= 1 << 0 + +unsigned Udc::send_next (unsigned old_csr): + for unsigned i = 0; size > 0 && i < max_packet_size0; ++i, --size: + // Use 8-bit transfers to avoid problems with alignment. + REG8 (UDC_FIFO_EP0) = *ptr++ + if size: + state = TX + return (old_csr | UDC_CSR0_INPKTRDY) & ~UDC_CSR0_DATAEND + else: + state = IDLE + return old_csr | UDC_CSR0_INPKTRDY + +unsigned Udc::vendor (unsigned old_csr, Setup *s): + if s->request_type & 0x80: + ptr = "abcdefgh" + size = 8 + return send_next (old_csr) + return old_csr + +unsigned Udc::get_descriptor (unsigned old_csr, unsigned type, unsigned idx, unsigned len): + switch type: + case Configuration::Type: + if idx != 1: + return old_csr | UDC_CSR0_SENDSTALL + ptr = reinterpret_cast (&config_descriptor) + size = (len < sizeof (config_descriptor) ? len : sizeof (config_descriptor)) + break + case Device::Type: + if idx != 0: + return old_csr | UDC_CSR0_SENDSTALL + ptr = reinterpret_cast (&device_descriptor) + size = (len < sizeof (device_descriptor) ? len : sizeof (device_descriptor)) + break + // The 7 is an arbitrary number. + case String <7>::Type: + switch idx: + case 1: + ptr = reinterpret_cast (&s_manufacturer) + size = (len < sizeof (s_manufacturer) ? len : sizeof (s_manufacturer)) + break + case 2: + ptr = reinterpret_cast (&s_product) + size = (len < sizeof (s_product) ? len : sizeof (s_product)) + break + default: + return old_csr | UDC_CSR0_SENDSTALL + break + default: + return old_csr | UDC_CSR0_SENDSTALL + return send_next (old_csr) + +unsigned Udc::handle_setup (unsigned old_csr, Setup *s): + switch s->request_type: + case STANDARD_TO_DEVICE: + switch s->request: + case SET_ADDRESS: + UDC_FADDR = s->value + break + case SET_CONFIGURATION: + if s->value >= 2: + return old_csr | UDC_CSR0_SENDSTALL + configuration = s->value + break + case SET_INTERFACE: + if s->value != 0: + return old_csr | UDC_CSR0_SENDSTALL + break + default: + return old_csr | UDC_CSR0_SENDSTALL + break + case STANDARD_FROM_DEVICE: + switch s->request: + case GET_STATUS: + ptr = "\0\0" + size = (s->length < 2 ? s->length : 2) + return send_next (old_csr) + case GET_DESCRIPTOR: + return get_descriptor (old_csr, (s->value >> 8) & 0xff, s->value & 0xff, s->length) + case GET_CONFIGURATION: + ptr = &configuration + size = (s->length < 1 ? s->length : 1) + return send_next (old_csr) + case GET_INTERFACE: + ptr = "\0" + size = (s->length < 1 ? s->length : 1) + return send_next (old_csr) + default: + return old_csr | UDC_CSR0_SENDSTALL + break + case VENDOR_TO_DEVICE: + case VENDOR_FROM_DEVICE: + return vendor (old_csr, s) + default: + return old_csr | UDC_CSR0_SENDSTALL + return old_csr + +void Udc::interrupt (): + unsigned i = UDC_INTRUSB + if i & UDC_INTR_RESET: + state = IDLE + return + i = UDC_INTRIN + if i & (1 << 0): + // Interrupt on endpoint 0. + unsigned csr = UDC_CSR0 + if csr & UDC_CSR0_SENTSTALL: + csr &= ~UDC_CSR0_SENTSTALL + state = IDLE + if csr & UDC_CSR0_SETUPEND: + csr |= UDC_CSR0_SVDSETUPEND + state = IDLE + switch state: + case IDLE: + if !(csr & UDC_CSR0_OUTPKTRDY): + break + csr |= UDC_CSR0_SVDOUTPKTRDY | UDC_CSR0_DATAEND + union { unsigned d[2]; Setup s; } packet + packet.d[0] = UDC_FIFO_EP0 + packet.d[1] = UDC_FIFO_EP0 + csr = handle_setup (csr, &packet.s) + UDC_CSR0 = csr + break + case TX: + UDC_CSR0 = send_next (UDC_CSR0 | UDC_CSR0_DATAEND) + break + case RX: + // Not supported. + UDC_CSR0 |= UDC_CSR0_SENDSTALL + state = IDLE + break + +void Udc::log (unsigned c): + +Kernel::Num start (): + map_udc () + Udc udc + + udc.init () + Kernel::Cap logcap = Kernel::my_receiver.create_capability (Init::LOG) + __asm__ volatile ("li $a0, 1\nlw $a1, %0\nbreak" :: "m"(logcap.code): "a0", "a1", "memory") + Kernel::register_interrupt (IRQ_UDC) + while true: + Kernel::wait () + switch Kernel::recv.protected_data.l: + case IRQ_UDC: + udc.interrupt () + break + case Init::LOG: + udc.log (Kernel::recv.data[0].l) + break + default: + udc.log ('~') + break diff --git a/invoke.ccp b/invoke.ccp index f7d8520..e9a2a82 100644 --- a/invoke.ccp +++ b/invoke.ccp @@ -730,6 +730,10 @@ static void caps_invoke (unsigned cmd, unsigned target, Kernel::Num protected_da return case Kernel::Caps::PRINT & REQUEST_MASK: if c->data[1].l >= caps->size: + if c->data[1].l == ~0: + // debug: power down. + *((volatile unsigned *)0xa0003020) = 1 + return dpanic (0, "invalid caps for print") return kCapRef cap (caps, c->data[1].l) diff --git a/mips/Makefile.arch b/mips/Makefile.arch deleted file mode 100644 index 78b7bbf..0000000 --- a/mips/Makefile.arch +++ /dev/null @@ -1,60 +0,0 @@ -# Iris: micro-kernel for a capability-based operating system. -# mips/Makefile.arch: mips-specific parts of the build rules -# Copyright 2009 Bas Wijnen -# -# 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 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -load = 0x80000000 - -ARCH_CXXFLAGS = -DNUM_THREADS=3 -ARCH_CPPFLAGS = -Imips -Wa,-mips32 -CROSS = mipsel-linux-gnu- -OBJDUMP = $(CROSS)objdump -junk = mdebug.abi32 reginfo comment pdr -OBJCOPYFLAGS = $(addprefix --remove-section=.,$(junk)) - -arch_iris_sources = mips/interrupts.cc mips/arch.cc -boot_sources = mips/init.cc -arch_headers = mips/arch.hh mips/jz4730.hh -boot_threads = init gpio lcd - -uimage: - -mips/entry.o: $(boot_threads) -mips/init.o: TARGET_FLAGS = -I/usr/include -$(boot_threads): TARGET_FLAGS = -I. -$(addprefix boot-programs/,$(addsuffix .cc,$(boot_threads))): boot-programs/devices.hh boot-programs/init.hh -lcd: boot-programs/charset.data - -boot-programs/charset.data: boot-programs/charset - $< > $@ - -# Transform ':' into ';' so vim doesn't think there are errors. -uimage: iris.raw.gz Makefile mips/Makefile.arch - mkimage -A MIPS -O Linux -C gzip -a $(load) -e 0xa$(shell /bin/sh -c '$(OBJDUMP) -t iris | grep __start$$ | cut -b2-8') -n "Iris" -d $< $@ | sed -e 's/:/;/g' - -%.o:%.S Makefile mips/Makefile.arch mips/arch.hh - $(CC) $(CPPFLAGS) $(TARGET_FLAGS) -DKERNEL_STACK_SIZE=0x2000 -c $< -o $@ - -# entry.o must be the first file. boot.o must be the first of the init objects (which can be freed after loading). -iris: mips/entry.o $(subst .cc,.o,$(iris_sources)) mips/boot.o $(subst .cc,.o,$(boot_sources)) - $(LD) --omagic -Ttext $(load) $^ -o $@ - -%.raw: % - $(OBJCOPY) -S $(OBJCOPYFLAGS) -Obinary $< $@ - -%.gz: % - gzip < $< > $@ - -ARCH_CLEAN_FILES = uimage $(boot_threads) mips/*.o boot-programs/charset.data iris iris.raw iris.raw.gz diff --git a/mips/Makefile.arch b/mips/Makefile.arch new file mode 120000 index 0000000..5fa69c3 --- /dev/null +++ b/mips/Makefile.arch @@ -0,0 +1 @@ +board/Makefile.arch \ No newline at end of file diff --git a/mips/arch.ccp b/mips/arch.ccp index c520501..22b4f13 100644 --- a/mips/arch.ccp +++ b/mips/arch.ccp @@ -17,7 +17,7 @@ // along with this program. If not, see . #define ARCH -#include "../kernel.hh" +#include "kernel.hh" void kThread_arch_init (kThread *thread): thread->arch.at = 0 diff --git a/mips/arch.hhp b/mips/arch.hhp index cc0a48b..27cb55e 100644 --- a/mips/arch.hhp +++ b/mips/arch.hhp @@ -22,7 +22,7 @@ #ifdef ARCH #ifndef ASM -#include "jz4730.hh" +#include "board.hh" #endif #define reg_hack(x...) #x @@ -131,6 +131,7 @@ extern "C": #ifdef INIT // Initialize most things (the rest is done in boot.S) void init (unsigned mem) + void board_init () // Start running the idle task for the first time. void run_idle (kThread *self) #endif diff --git a/mips/board b/mips/board new file mode 120000 index 0000000..a4401b3 --- /dev/null +++ b/mips/board @@ -0,0 +1 @@ +nanonote \ No newline at end of file diff --git a/mips/boot.S b/mips/boot.S index 4422431..46c6f28 100644 --- a/mips/boot.S +++ b/mips/boot.S @@ -1,5 +1,5 @@ // Iris: micro-kernel for a capability-based operating system. -// mips/boot.S: Kernel entry point, called by the boot loader. +// mips/trendtac/boot.S: Kernel entry point, called by the boot loader. // Copyright 2009 Bas Wijnen // // This program is free software: you can redistribute it and/or modify @@ -15,16 +15,16 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . + #define ASM + #define ARCH + #include "arch.hh" + // The kernel stack. .lcomm kernel_stack, KERNEL_STACK_SIZE .globl __start - .globl thread_start .set noreorder -#define Status 12 -#define Config 16 - // Note that this code starts at 0xa0000000, even though it is linked for // 0x80000000. This means that until the jump below, it must be PIC. __start: @@ -49,13 +49,14 @@ start_hack_for_disassembler: // Set kseg0 cachable. li $k0, 0x3 - mtc0 $k0, $Config, 0 + mtc0 $k0, $CP0_CONFIG, 0 // Jump into cached code. la $t9, 1f jr $t9 nop 1: + // From here, the code no longer needs to be PIC. // Clear .bss la $a0, _edata @@ -64,14 +65,7 @@ start_hack_for_disassembler: bne $a1, $a0, 1b addu $a0, 4 - // First argument is the memory size: 128 megabytes. - li $a0, 128 << 20 + // First argument is the memory size. la $t9, init jr $t9 - nop - -thread_start: - .word thread0 - .word thread1 - .word thread2 - .word thread3 + li $a0, MEMORY_SIZE diff --git a/mips/entry.S b/mips/entry.S index a18d03b..c9f6fcd 100644 --- a/mips/entry.S +++ b/mips/entry.S @@ -226,18 +226,3 @@ save_regs: la $ra, kernel_exit jr $t9 nop - - .globl thread0 - .globl thread1 - .globl thread2 - .globl thread3 - .balign 0x1000 -thread0: - .incbin "init" - .balign 0x1000 -thread1: - .incbin "lcd" - .balign 0x1000 -thread2: - .incbin "gpio" -thread3: diff --git a/mips/init.ccp b/mips/init.ccp index 122b337..4823fa3 100644 --- a/mips/init.ccp +++ b/mips/init.ccp @@ -260,49 +260,13 @@ void init (unsigned mem): // Set up initial threads. init_threads () - // Disable all gpio interrupts and alternate functions initially. - for unsigned i = 0; i < 4; ++i: - GPIO_GPIER (i) = 0 - GPIO_GPALR (i) = 0 - GPIO_GPAUR (i) = 0 - // Set up the rest of the hardware (copied from Linux). - cpm_idle_mode () - cpm_enable_cko1 () - cpm_start_all () - harb_set_priority (0x08) - dmac_enable_all_channels () - harb_usb0_uhc () - gpio_as_emc () - gpio_as_uart0 () - gpio_as_dma () - gpio_as_eth () - gpio_as_usb () - gpio_as_lcd_master () - gpio_as_ssi() - gpio_as_msc () - - gpio_as_gpio (GPIO_CAPS_PORT, GPIO_CAPS) - gpio_as_gpio (GPIO_SCROLL_PORT, GPIO_SCROLL) - gpio_as_gpio (GPIO_NUM_PORT, GPIO_NUM) - gpio_as_gpio (GPIO_TP_LEFT_PORT, GPIO_TP_LEFT) - gpio_as_gpio (GPIO_TP_RIGHT_PORT, GPIO_TP_RIGHT) - - // Start the operating system timer, and set it to give an interrupt immediately. - // This is better, because the kernel starts with jumping into the idle task and - // waiting for the first interrupt. - unsigned latch = (JZ_EXTAL + (HZ >> 1)) / HZ - ost_disable_all () - ost_set_mode (0, OST_TCSR_UIE | OST_TCSR_CKS_EXTAL) - ost_set_reload (0, latch) - ost_set_count (0, 1) - ost_set_mode (0, OST_TCSR_UIE | OST_TCSR_CKS_EXTAL) - ost_enable_channel (0) - intc_unmask_irq (IRQ_OST0) - // Unset all interrupt handlers. for unsigned i = 0; i < 32; ++i: arch_interrupt_receiver[i] = NULL + // Initialize board-specific things. + board_init () + // Say we're handling an exception. Since we're going to enter the idle task, allow access to cp0. // All interrupts enter the CPU through the interrupt controller at IP2, so enable that. cp0_set (CP0_STATUS, 0x1000ff13) diff --git a/mips/interrupts.ccp b/mips/interrupts.ccp index 1e2980d..5028291 100644 --- a/mips/interrupts.ccp +++ b/mips/interrupts.ccp @@ -94,7 +94,7 @@ kThread *interrupt (): for unsigned i = 0; i < 32; ++i: if ipr & (1 << i): // Handle timer interrupts specially: don't disable them. - if i == IRQ_OST0: + if i == TIMER_INTERRUPT: continue // Disable the interrupt while handling it. intc_mask_irq (i) @@ -106,9 +106,15 @@ kThread *interrupt (): c.data[j] = 0 arch_interrupt_receiver[i]->send_message (i, &c) arch_interrupt_receiver[i] = NULL - if ipr & (1 << IRQ_OST0): + if ipr & (1 << TIMER_INTERRUPT): + #if defined (TRENDTAC) ost_clear_uf (0) - intc_ack_irq (IRQ_OST0) + #elif defined (NANONOTE) + tcu_clear_full_match_flag (0) + #else + #error unknown board + #endif + intc_ack_irq (TIMER_INTERRUPT) timer_interrupt () handle_exit () return current diff --git a/mips/nanonote/Makefile.arch b/mips/nanonote/Makefile.arch new file mode 100644 index 0000000..711142d --- /dev/null +++ b/mips/nanonote/Makefile.arch @@ -0,0 +1,66 @@ +# Iris: micro-kernel for a capability-based operating system. +# mips/nanonote/Makefile.arch: nanonote-specific parts of the build rules +# Copyright 2009 Bas Wijnen +# +# 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 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +load = 0x80000000 + +ARCH_CXXFLAGS = -DNUM_THREADS=2 +ARCH_CPPFLAGS = -I. -Imips -Imips/nanonote -Wa,-mips32 -DNANONOTE +CROSS = mipsel-linux-gnu- +OBJDUMP = $(CROSS)objdump +junk = mdebug.abi32 reginfo comment pdr +OBJCOPYFLAGS = $(addprefix --remove-section=.,$(junk)) +LDFLAGS = --omagic -Ttext $(load) + +arch_iris_sources = mips/interrupts.cc mips/arch.cc +boot_sources = mips/init.cc mips/nanonote/board.cc +arch_headers = mips/arch.hh mips/nanonote/jz4740.hh mips/nanonote/board.hh +boot_threads = init udc + +test: iris.raw nanonote-boot + ./nanonote-boot iris.raw 0xa$(shell /bin/sh -c '$(OBJDUMP) -t iris | grep __start$$ | cut -b2-8') +.PHONY: test + +%.elf: %.o + $(LD) $(LDFLAGS) -o $@ $< + +%.raw: %.elf + $(OBJCOPY) -S $(OBJCOPYFLAGS) -Obinary $< $@ + +nanonote-boot: mips/nanonote/nanonote-boot.cc mips/nanonote/sdram-setup.raw + g++ `pkg-config --cflags --libs shevek` $< -o $@ -D'STAGE1="$<"' -lusb + +mips/nanonote/sdram-setup.elf: mips/nanonote/sdram-setup.ld +mips/nanonote/sdram-setup.elf: LDFLAGS = --omagic -T mips/nanonote/sdram-setup.ld +mips/boot.o: TARGET_FLAGS = -DMEMORY_SIZE="32 << 20" +mips/entry.o: $(boot_threads) +mips/init.o: TARGET_FLAGS = -I/usr/include +$(boot_threads): TARGET_FLAGS = -I. +$(boot_threads): LDFLAGS = -EL +$(addprefix boot-programs/,$(addsuffix .cc,$(boot_threads))): boot-programs/devices.hh boot-programs/init.hh +lcd: boot-programs/charset.data + +boot-programs/charset.data: boot-programs/charset + $< > $@ + +%.o:%.S Makefile Makefile.arch mips/arch.hh + $(CC) $(CPPFLAGS) $(TARGET_FLAGS) -DKERNEL_STACK_SIZE=0x2000 -c $< -o $@ + +# entry.o must be the first file. threadlist.o must be the first of the init objects (which can be freed after loading). +iris.elf: mips/entry.o $(subst .cc,.o,$(iris_sources)) mips/nanonote/threadlist.o mips/boot.o $(subst .cc,.o,$(boot_sources)) + $(LD) $(LDFLAGS) $^ -o $@ + +ARCH_CLEAN_FILES = $(boot_sources) $(boot_threads) $(arch_headers) boot_programs/init.hh boot_programs/devices.hh mips/*.o mips/nanonote/*.o boot-programs/charset.data iris.elf iris.raw mips/nanonote/sdram-setup.elf mips/nanonote/sdram-setup.raw diff --git a/mips/nanonote/board.ccp b/mips/nanonote/board.ccp new file mode 100644 index 0000000..bb161ee --- /dev/null +++ b/mips/nanonote/board.ccp @@ -0,0 +1,51 @@ +#pypp 0 +// Iris: micro-kernel for a capability-based operating system. +// mips/nanonote/board.ccp: nanonote-specific definitions. +// Copyright 2009 Bas Wijnen +// +// 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 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#define ARCH +#define INIT +#include "kernel.hh" + +void board_init (): + cpm_start_all () + gpio_as_uart0 () + gpio_as_sdram_16bit () + gpio_as_nand () + gpio_as_aic () + gpio_as_lcd_16bit () + gpio_as_msc () + // Set up keyboard: this breaks uart receive. + gpio_as_gpio (3, 0x05fc0000) + tcu_stop_counter (0) + tcu_select_extalclk (0) + tcu_select_clk_div1 (0) + tcu_disable_pwm_output (0) + tcu_set_full_data (0, JZ_EXTAL / HZ) + tcu_mask_half_match_irq (0) + tcu_clear_full_match_flag (0) + tcu_unmask_full_match_irq (0) + tcu_start_counter (0) + // Set up uart. + uart_disable (0) + uart_set_baud (0, JZ_EXTAL, 9600) + uart_set_8n1 (0) + UART0_IER = 0 + UART0_MCR = 0 + UART0_SIRCR = 0 + UART0_UMR = 0 + UART0_UACR = 0 + UART0_FCR |= UARTFCR_UUE | UARTFCR_RFLS | UARTFCR_TFLS diff --git a/mips/nanonote/board.hhp b/mips/nanonote/board.hhp new file mode 100644 index 0000000..64c9598 --- /dev/null +++ b/mips/nanonote/board.hhp @@ -0,0 +1,19 @@ +#pypp 0 +// Iris: micro-kernel for a capability-based operating system. +// mips/nanonote/board.hhp: nanonote-specific declarations and type definitions. +// Copyright 2009 Bas Wijnen +// +// 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 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "jz4740.hh" diff --git a/mips/nanonote/jz4740.hhp b/mips/nanonote/jz4740.hhp new file mode 100644 index 0000000..30e646c --- /dev/null +++ b/mips/nanonote/jz4740.hhp @@ -0,0 +1,3568 @@ +#pypp 0 +// Iris: micro-kernel for a capability-based operating system. +// nanonote/jz4740.ccp: Chip features. Most of this file is +// copied from the Linux source files include/asm-mips/jz4740/{ops,regs}.h, +// which don't have a copyright statement or license in the header. +// Copyright 2009 Bas Wijnen +// +// 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 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef __JZ4740_HH__ +#define __JZ4740_HH__ + +// Main clock, for cpu, serial port, and with divisors for most other hardware +#define JZ_EXTAL 3686400 /* 3.6864 MHz */ +// RTC clock +#define RTC_CLOCK 32768 /* 32.768 KHz */ +// Interrupt source used for system timer +#define TIMER_INTERRUPT IRQ_TCU0 + +// Physical addresses are where they really are. +#define CPM_PHYSICAL 0x10000000 +#define INTC_PHYSICAL 0x10001000 +#define TCU_PHYSICAL 0x10002000 +#define WDT_PHYSICAL 0x10002000 +#define RTC_PHYSICAL 0x10003000 +#define GPIO_PHYSICAL 0x10010000 +#define AIC_PHYSICAL 0x10020000 +#define MSC_PHYSICAL 0x10021000 +#define UART0_PHYSICAL 0x10030000 +#define I2C_PHYSICAL 0x10042000 +#define SSI_PHYSICAL 0x10043000 +#define SADC_PHYSICAL 0x10070000 +#define EMC_PHYSICAL 0x13010000 +#define DMAC_PHYSICAL 0x13020000 +#define UHC_PHYSICAL 0x13030000 +#define UDC_PHYSICAL 0x13040000 +#define LCD_PHYSICAL 0x13050000 +#define SLCD_PHYSICAL 0x13050000 +#define CIM_PHYSICAL 0x13060000 +#define ETH_PHYSICAL 0x13100000 + +#ifdef __KERNEL +// In kernel space you need to add 0xa0000000 to see them unmapped uncached in kseg2. +#define CPM_BASE (0xa0000000 + CPM_PHYSICAL) +#define INTC_BASE (0xa0000000 + INTC_PHYSICAL) +#define TCU_BASE (0xa0000000 + TCU_PHYSICAL) +#define WDT_BASE (0xa0000000 + WDT_PHYSICAL) +#define RTC_BASE (0xa0000000 + RTC_PHYSICAL) +#define GPIO_BASE (0xa0000000 + GPIO_PHYSICAL) +#define AIC_BASE (0xa0000000 + AIC_PHYSICAL) +#define MSC_BASE (0xa0000000 + MSC_PHYSICAL) +#define UART0_BASE (0xa0000000 + UART0_PHYSICAL) +#define I2C_BASE (0xa0000000 + I2C_PHYSICAL) +#define SSI_BASE (0xa0000000 + SSI_PHYSICAL) +#define SADC_BASE (0xa0000000 + SADC_PHYSICAL) +#define EMC_BASE (0xa0000000 + EMC_PHYSICAL) +#define DMAC_BASE (0xa0000000 + DMAC_PHYSICAL) +#define UHC_BASE (0xa0000000 + UHC_PHYSICAL) +#define UDC_BASE (0xa0000000 + UDC_PHYSICAL) +#define LCD_BASE (0xa0000000 + LCD_PHYSICAL) +#define SLCD_BASE (0xa0000000 + SLCD_PHYSICAL) +#define CIM_BASE (0xa0000000 + CIM_PHYSICAL) +#define ETH_BASE (0xa0000000 + ETH_PHYSICAL) + +// udelay should not be called from the kernel. +#define udelay(x) dpanic (x, "udelay called") + +#else +// In user space, they just need a mapping. +#define UNMAPPED_BASE 0x00000000 + +#define CPM_BASE 0x00001000 +#define INTC_BASE 0x00002000 +#define TCU_BASE 0x00003000 +#define WDT_BASE 0x00004000 +#define RTC_BASE 0x00005000 +#define GPIO_BASE 0x00006000 +#define AIC_BASE 0x00007000 +#define MSC_BASE 0x00008000 +#define UART0_BASE 0x00009000 +#define I2C_BASE 0x0000a000 +#define SSI_BASE 0x0000b000 +#define SADC_BASE 0x0000c000 +#define EMC_BASE 0x0000d000 +#define DMAC_BASE 0x0000e000 +#define UHC_BASE 0x0000f000 +#define UDC_BASE 0x00010000 +#define LCD_BASE 0x00011000 +#define SLCD_BASE 0x00012000 +#define CIM_BASE 0x00013000 +#define ETH_BASE 0x00014000 + +// Default lcd framebuffer mapping space. +#define LCD_FRAMEBUFFER_BASE ((unsigned short *)0x00015000) + +// Map IO memory (requires a priviledged Kernel::my_thread capability). +#include +static void __map_io (unsigned physical, unsigned mapping): + Kernel::Page p = Kernel::my_memory.create_page () + // false means not cachable; false means don't free when done. + p.alloc_physical (physical, false, false) + Kernel::my_memory.map (p, mapping) + Kernel::free_cap (p) + +#define map_cpm() do { __map_io (CPM_PHYSICAL, CPM_BASE); } while (0) +#define map_intc() do { __map_io (INTC_PHYSICAL, INTC_BASE); } while (0) +#define map_tcu() do { __map_io (TCU_PHYSICAL, TCU_BASE); } while (0) +#define map_wdt() do { __map_io (WDT_PHYSICAL, WDT_BASE); } while (0) +#define map_rtc() do { __map_io (RTC_PHYSICAL, RTC_BASE); } while (0) +#define map_gpio() do { __map_io (GPIO_PHYSICAL, GPIO_BASE); } while (0) +#define map_aic() do { __map_io (AIC_PHYSICAL, AIC_BASE); } while (0) +#define map_uart0() do { __map_io (UART0_PHYSICAL, UART0_BASE); } while (0) +#define map_i2c() do { __map_io (I2C_PHYSICAL, I2C_BASE); } while (0) +#define map_ssi() do { __map_io (SSI_PHYSICAL, SSI_BASE); } while (0) +#define map_sadc() do { __map_io (SADC_PHYSICAL, SADC_BASE); } while (0) +#define map_emc() do { __map_io (EMC_PHYSICAL, EMC_BASE); } while (0) +#define map_dmac() do { __map_io (DMAC_PHYSICAL, DMAC_BASE); } while (0) +#define map_uhc() do { __map_io (UHC_PHYSICAL, UHC_BASE); } while (0) +#define map_udc() do { __map_io (UDC_PHYSICAL, UDC_BASE); } while (0) +#define map_lcd() do { __map_io (LCD_PHYSICAL, LCD_BASE); } while (0) +#define map_slcd() do { __map_io (SLCD_PHYSICAL, SLCD_BASE); } while (0) +#define map_cim() do { __map_io (CIM_PHYSICAL, CIM_BASE); } while (0) +#define map_eth() do { __map_io (ETH_PHYSICAL, ETH_BASE); } while (0) + +// udelay implementation +void cdelay (unsigned cs): + Kernel::my_receiver.set_alarm (cs + 1) + Kernel::Cap ().call () + +#endif + +#define REG8(x) (*(volatile unsigned char *)(x)) +#define REG16(x) (*(volatile unsigned short *)(x)) +#define REG32(x) (*(volatile unsigned *)(x)) + +//************************************************************************ +// INTC (Interrupt Controller) +//************************************************************************ +#define INTC_ISR REG32 (INTC_BASE + 0x00) +#define INTC_IMR REG32 (INTC_BASE + 0x04) +#define INTC_IMSR REG32 (INTC_BASE + 0x08) +#define INTC_IMCR REG32 (INTC_BASE + 0x0c) +#define INTC_IPR REG32 (INTC_BASE + 0x10) + +#define IRQ_I2C 1 +#define IRQ_UHC 3 +#define IRQ_UART0 9 +#define IRQ_SADC 12 +#define IRQ_MSC 14 +#define IRQ_RTC 15 +#define IRQ_SSI 16 +#define IRQ_CIM 17 +#define IRQ_AIC 18 +#define IRQ_ETH 19 +#define IRQ_DMAC 20 +#define IRQ_TCU2 21 +#define IRQ_TCU1 22 +#define IRQ_TCU0 23 +#define IRQ_UDC 24 +#define IRQ_GPIO3 25 +#define IRQ_GPIO2 26 +#define IRQ_GPIO1 27 +#define IRQ_GPIO0 28 +#define IRQ_IPU 29 +#define IRQ_LCD 30 + + +//************************************************************************ +// RTC +//************************************************************************ +#define RTC_RCR REG32 (RTC_BASE + 0x00) // RTC Control Register +#define RTC_RSR REG32 (RTC_BASE + 0x04) // RTC Second Register +#define RTC_RSAR REG32 (RTC_BASE + 0x08) // RTC Second Alarm Register +#define RTC_RGR REG32 (RTC_BASE + 0x0c) // RTC Regulator Register + +#define RTC_HCR REG32 (RTC_BASE + 0x20) // Hibernate Control Register +#define RTC_HWFCR REG32 (RTC_BASE + 0x24) // Hibernate Wakeup Filter Counter Reg +#define RTC_HRCR REG32 (RTC_BASE + 0x28) // Hibernate Reset Counter Register +#define RTC_HWCR REG32 (RTC_BASE + 0x2c) // Hibernate Wakeup Control Register +#define RTC_HWRSR REG32 (RTC_BASE + 0x30) // Hibernate Wakeup Status Register +#define RTC_HSPR REG32 (RTC_BASE + 0x34) // Hibernate Scratch Pattern Register + +// RTC Control Register +#define RTC_RCR_WRDY_BIT 7 +#define RTC_RCR_WRDY (1 << 7) // Write Ready Flag +#define RTC_RCR_1HZ_BIT 6 +#define RTC_RCR_1HZ (1 << RTC_RCR_1HZ_BIT) // 1Hz Flag +#define RTC_RCR_1HZIE (1 << 5) // 1Hz Interrupt Enable +#define RTC_RCR_AF_BIT 4 +#define RTC_RCR_AF (1 << RTC_RCR_AF_BIT) // Alarm Flag +#define RTC_RCR_AIE (1 << 3) // Alarm Interrupt Enable +#define RTC_RCR_AE (1 << 2) // Alarm Enable +#define RTC_RCR_RTCE (1 << 0) // RTC Enable + +// RTC Regulator Register +#define RTC_RGR_LOCK (1 << 31) // Lock Bit +#define RTC_RGR_ADJC_BIT 16 +#define RTC_RGR_ADJC_MASK (0x3ff << RTC_RGR_ADJC_BIT) +#define RTC_RGR_NC1HZ_BIT 0 +#define RTC_RGR_NC1HZ_MASK (0xffff << RTC_RGR_NC1HZ_BIT) + +// Hibernate Control Register +#define RTC_HCR_PD (1 << 0) // Power Down + +// Hibernate Wakeup Filter Counter Register +#define RTC_HWFCR_BIT 5 +#define RTC_HWFCR_MASK (0x7ff << RTC_HWFCR_BIT) + +// Hibernate Reset Counter Register +#define RTC_HRCR_BIT 5 +#define RTC_HRCR_MASK (0x7f << RTC_HRCR_BIT) + +// Hibernate Wakeup Control Register +#define RTC_HWCR_EALM (1 << 0) // RTC alarm wakeup enable + +// Hibernate Wakeup Status Register +#define RTC_HWRSR_HR (1 << 5) // Hibernate reset +#define RTC_HWRSR_PPR (1 << 4) // PPR reset +#define RTC_HWRSR_PIN (1 << 1) // Wakeup pin status bit +#define RTC_HWRSR_ALM (1 << 0) // RTC alarm status bit + + +//************************************************************************ +// CPM (Clock reset and Power control Management) +//************************************************************************ +#define CPM_CPCCR REG32 (CPM_BASE+0x00) +#define CPM_CPPCR REG32 (CPM_BASE+0x10) +#define CPM_I2SCDR REG32 (CPM_BASE+0x60) +#define CPM_LPCDR REG32 (CPM_BASE+0x64) +#define CPM_MSCCDR REG32 (CPM_BASE+0x68) +#define CPM_UHCCDR REG32 (CPM_BASE+0x6C) +#define CPM_SSICDR REG32 (CPM_BASE+0x74) + +#define CPM_LCR REG32 (CPM_BASE+0x04) +#define CPM_CLKGR REG32 (CPM_BASE+0x20) +#define CPM_SCR REG32 (CPM_BASE+0x24) + +#define CPM_HCR REG32 (CPM_BASE+0x30) +#define CPM_HWFCR REG32 (CPM_BASE+0x34) +#define CPM_HRCR REG32 (CPM_BASE+0x38) +#define CPM_HWCR REG32 (CPM_BASE+0x3c) +#define CPM_HWSR REG32 (CPM_BASE+0x40) +#define CPM_HSPR REG32 (CPM_BASE+0x44) + +#define CPM_RSR REG32 (CPM_BASE+0x08) + + +// Clock Control Register +#define CPM_CPCCR_I2CS (1 << 31) +#define CPM_CPCCR_CLKOEN (1 << 30) +#define CPM_CPCCR_UCS (1 << 29) +#define CPM_CPCCR_UDIV_BIT 23 +#define CPM_CPCCR_UDIV_MASK (0x3f << CPM_CPCCR_UDIV_BIT) +#define CPM_CPCCR_CE (1 << 22) +#define CPM_CPCCR_PCS (1 << 21) +#define CPM_CPCCR_LDIV_BIT 16 +#define CPM_CPCCR_LDIV_MASK (0x1f << CPM_CPCCR_LDIV_BIT) +#define CPM_CPCCR_MDIV_BIT 12 +#define CPM_CPCCR_MDIV_MASK (0x0f << CPM_CPCCR_MDIV_BIT) +#define CPM_CPCCR_PDIV_BIT 8 +#define CPM_CPCCR_PDIV_MASK (0x0f << CPM_CPCCR_PDIV_BIT) +#define CPM_CPCCR_HDIV_BIT 4 +#define CPM_CPCCR_HDIV_MASK (0x0f << CPM_CPCCR_HDIV_BIT) +#define CPM_CPCCR_CDIV_BIT 0 +#define CPM_CPCCR_CDIV_MASK (0x0f << CPM_CPCCR_CDIV_BIT) + +// I2S Clock Divider Register +#define CPM_I2SCDR_I2SDIV_BIT 0 +#define CPM_I2SCDR_I2SDIV_MASK (0x1ff << CPM_I2SCDR_I2SDIV_BIT) + +// LCD Pixel Clock Divider Register +#define CPM_LPCDR_PIXDIV_BIT 0 +#define CPM_LPCDR_PIXDIV_MASK (0x1ff << CPM_LPCDR_PIXDIV_BIT) + +// MSC Clock Divider Register +#define CPM_MSCCDR_MSCDIV_BIT 0 +#define CPM_MSCCDR_MSCDIV_MASK (0x1f << CPM_MSCCDR_MSCDIV_BIT) + +// UHC Clock Divider Register +#define CPM_UHCCDR_UHCDIV_BIT 0 +#define CPM_UHCCDR_UHCDIV_MASK (0xf << CPM_UHCCDR_UHCDIV_BIT) + +// SSI Clock Divider Register +#define CPM_SSICDR_SCS (1<<31) // SSI clock source selection, 0:EXCLK, 1: PLL +#define CPM_SSICDR_SSIDIV_BIT 0 +#define CPM_SSICDR_SSIDIV_MASK (0xf << CPM_SSICDR_SSIDIV_BIT) + +// PLL Control Register +#define CPM_CPPCR_PLLM_BIT 23 +#define CPM_CPPCR_PLLM_MASK (0x1ff << CPM_CPPCR_PLLM_BIT) +#define CPM_CPPCR_PLLN_BIT 18 +#define CPM_CPPCR_PLLN_MASK (0x1f << CPM_CPPCR_PLLN_BIT) +#define CPM_CPPCR_PLLOD_BIT 16 +#define CPM_CPPCR_PLLOD_MASK (0x03 << CPM_CPPCR_PLLOD_BIT) +#define CPM_CPPCR_PLLS (1 << 10) +#define CPM_CPPCR_PLLBP (1 << 9) +#define CPM_CPPCR_PLLEN (1 << 8) +#define CPM_CPPCR_PLLST_BIT 0 +#define CPM_CPPCR_PLLST_MASK (0xff << CPM_CPPCR_PLLST_BIT) + +// Low Power Control Register +#define CPM_LCR_DOZE_DUTY_BIT 3 +#define CPM_LCR_DOZE_DUTY_MASK (0x1f << CPM_LCR_DOZE_DUTY_BIT) +#define CPM_LCR_DOZE_ON (1 << 2) +#define CPM_LCR_LPM_BIT 0 +#define CPM_LCR_LPM_MASK (0x3 << CPM_LCR_LPM_BIT) + #define CPM_LCR_LPM_IDLE (0x0 << CPM_LCR_LPM_BIT) + #define CPM_LCR_LPM_SLEEP (0x1 << CPM_LCR_LPM_BIT) + +// Clock Gate Register +#define CPM_CLKGR_UART1 (1 << 15) +#define CPM_CLKGR_UHC (1 << 14) +#define CPM_CLKGR_IPU (1 << 13) +#define CPM_CLKGR_DMAC (1 << 12) +#define CPM_CLKGR_UDC (1 << 11) +#define CPM_CLKGR_LCD (1 << 10) +#define CPM_CLKGR_CIM (1 << 9) +#define CPM_CLKGR_SADC (1 << 8) +#define CPM_CLKGR_MSC (1 << 7) +#define CPM_CLKGR_AIC1 (1 << 6) +#define CPM_CLKGR_AIC2 (1 << 5) +#define CPM_CLKGR_SSI (1 << 4) +#define CPM_CLKGR_I2C (1 << 3) +#define CPM_CLKGR_RTC (1 << 2) +#define CPM_CLKGR_TCU (1 << 1) +#define CPM_CLKGR_UART0 (1 << 0) + +// Sleep Control Register +#define CPM_SCR_O1ST_BIT 8 +#define CPM_SCR_O1ST_MASK (0xff << CPM_SCR_O1ST_BIT) +#define CPM_SCR_USBPHY_ENABLE (1 << 6) +#define CPM_SCR_OSC_ENABLE (1 << 4) + +// Hibernate Control Register +#define CPM_HCR_PD (1 << 0) + +// Wakeup Filter Counter Register in Hibernate Mode +#define CPM_HWFCR_TIME_BIT 0 +#define CPM_HWFCR_TIME_MASK (0x3ff << CPM_HWFCR_TIME_BIT) + +// Reset Counter Register in Hibernate Mode +#define CPM_HRCR_TIME_BIT 0 +#define CPM_HRCR_TIME_MASK (0x7f << CPM_HRCR_TIME_BIT) + +// Wakeup Control Register in Hibernate Mode +#define CPM_HWCR_WLE_LOW (0 << 2) +#define CPM_HWCR_WLE_HIGH (1 << 2) +#define CPM_HWCR_PIN_WAKEUP (1 << 1) +#define CPM_HWCR_RTC_WAKEUP (1 << 0) + +// Wakeup Status Register in Hibernate Mode +#define CPM_HWSR_WSR_PIN (1 << 1) +#define CPM_HWSR_WSR_RTC (1 << 0) + +// Reset Status Register +#define CPM_RSR_HR (1 << 2) +#define CPM_RSR_WR (1 << 1) +#define CPM_RSR_PR (1 << 0) + + +//************************************************************************ +// TCU (Timer Counter Unit) +//************************************************************************ +#define TCU_TSR REG32 (TCU_BASE + 0x1C) // Timer Stop Register +#define TCU_TSSR REG32 (TCU_BASE + 0x2C) // Timer Stop Set Register +#define TCU_TSCR REG32 (TCU_BASE + 0x3C) // Timer Stop Clear Register +#define TCU_TER REG8 (TCU_BASE + 0x10) // Timer Counter Enable Register +#define TCU_TESR REG8 (TCU_BASE + 0x14) // Timer Counter Enable Set Register +#define TCU_TECR REG8 (TCU_BASE + 0x18) // Timer Counter Enable Clear Register +#define TCU_TFR REG32 (TCU_BASE + 0x20) // Timer Flag Register +#define TCU_TFSR REG32 (TCU_BASE + 0x24) // Timer Flag Set Register +#define TCU_TFCR REG32 (TCU_BASE + 0x28) // Timer Flag Clear Register +#define TCU_TMR REG32 (TCU_BASE + 0x30) // Timer Mask Register +#define TCU_TMSR REG32 (TCU_BASE + 0x34) // Timer Mask Set Register +#define TCU_TMCR REG32 (TCU_BASE + 0x38) // Timer Mask Clear Register + +// n = 0,1,2,3,4,5 +#define TCU_TDFR(n) REG16 (TCU_BASE + (0x40 + (n)*0x10)) // Timer Data Full Reg +#define TCU_TDHR(n) REG16 (TCU_BASE + (0x44 + (n)*0x10)) // Timer Data Half Reg +#define TCU_TCNT(n) REG16 (TCU_BASE + (0x48 + (n)*0x10)) // Timer Counter Reg +#define TCU_TCSR(n) REG16 (TCU_BASE + (0x4C + (n)*0x10)) // Timer Control Reg + +// Register definitions +#define TCU_TCSR_PWM_SD (1 << 9) +#define TCU_TCSR_PWM_INITL_HIGH (1 << 8) +#define TCU_TCSR_PWM_EN (1 << 7) +#define TCU_TCSR_PRESCALE_BIT 3 +#define TCU_TCSR_PRESCALE_MASK (0x7 << TCU_TCSR_PRESCALE_BIT) + #define TCU_TCSR_PRESCALE1 (0x0 << TCU_TCSR_PRESCALE_BIT) + #define TCU_TCSR_PRESCALE4 (0x1 << TCU_TCSR_PRESCALE_BIT) + #define TCU_TCSR_PRESCALE16 (0x2 << TCU_TCSR_PRESCALE_BIT) + #define TCU_TCSR_PRESCALE64 (0x3 << TCU_TCSR_PRESCALE_BIT) + #define TCU_TCSR_PRESCALE256 (0x4 << TCU_TCSR_PRESCALE_BIT) + #define TCU_TCSR_PRESCALE1024 (0x5 << TCU_TCSR_PRESCALE_BIT) +#define TCU_TCSR_EXT_EN (1 << 2) +#define TCU_TCSR_RTC_EN (1 << 1) +#define TCU_TCSR_PCK_EN (1 << 0) + +#define TCU_TER_TCEN(n) (1 << (n)) +#define TCU_TESR_TCST(n) (1 << (n)) +#define TCU_TECR_TCCL(n) (1 << (n)) +#define TCU_TFR_HFLAG(n) (1 << ((n) + 16)) +#define TCU_TFR_FFLAG(n) (1 << (n)) +#define TCU_TFSR_HFLAG(n) (1 << ((n) + 16)) +#define TCU_TFSR_FFLAG(n) (1 << (n)) +#define TCU_TFCR_HFLAG(n) (1 << ((n) + 16)) +#define TCU_TFCR_FFLAG(n) (1 << (n)) +#define TCU_TMR_HMASK(n) (1 << ((n) + 16)) +#define TCU_TMR_FMASK(n) (1 << (n)) +#define TCU_TMSR_HMST(n) (1 << ((n) + 16)) +#define TCU_TMSR_FMST(n) (1 << (n)) +#define TCU_TMCR_HMCL(n) (1 << ((n) + 16)) +#define TCU_TMCR_FMCL(n) (1 << (n)) +#define TCU_TSR_WDTS (1 << 16) +#define TCU_TSR_STOP(n) (1 << (n)) +#define TCU_TSSR_WDTSS (1 << 16) +#define TCU_TSSR_STPS(n) (1 << (n)) +#define TCU_TSSR_WDTSC (1 << 16) +#define TCU_TSSR_STPC(n) (1 << (n)) + + +//************************************************************************ +// WDT (WatchDog Timer) +//************************************************************************ +#define WDT_TDR REG16 (WDT_BASE + 0x00) +#define WDT_TCER REG8 (WDT_BASE + 0x04) +#define WDT_TCNT REG16 (WDT_BASE + 0x08) +#define WDT_TCSR REG16 (WDT_BASE + 0x0C) + +// Register definition +#define WDT_TCSR_PRESCALE_BIT 3 +#define WDT_TCSR_PRESCALE_MASK (0x7 << WDT_TCSR_PRESCALE_BIT) + #define WDT_TCSR_PRESCALE1 (0x0 << WDT_TCSR_PRESCALE_BIT) + #define WDT_TCSR_PRESCALE4 (0x1 << WDT_TCSR_PRESCALE_BIT) + #define WDT_TCSR_PRESCALE16 (0x2 << WDT_TCSR_PRESCALE_BIT) + #define WDT_TCSR_PRESCALE64 (0x3 << WDT_TCSR_PRESCALE_BIT) + #define WDT_TCSR_PRESCALE256 (0x4 << WDT_TCSR_PRESCALE_BIT) + #define WDT_TCSR_PRESCALE1024 (0x5 << WDT_TCSR_PRESCALE_BIT) +#define WDT_TCSR_EXT_EN (1 << 2) +#define WDT_TCSR_RTC_EN (1 << 1) +#define WDT_TCSR_PCK_EN (1 << 0) + +#define WDT_TCER_TCEN (1 << 0) + + +//************************************************************************ +// DMAC (DMA Controller) +//************************************************************************ + +#define MAX_DMA_NUM 6 // max 6 channels + +#define DMAC_DSAR(n) REG32 (DMAC_BASE + (0x00 + (n) * 0x20)) // DMA source address +#define DMAC_DTAR(n) REG32 (DMAC_BASE + (0x04 + (n) * 0x20)) // DMA target address +#define DMAC_DTCR(n) REG32 (DMAC_BASE + (0x08 + (n) * 0x20)) // DMA transfer count +#define DMAC_DRSR(n) REG32 (DMAC_BASE + (0x0c + (n) * 0x20)) // DMA request source +#define DMAC_DCCSR(n) REG32 (DMAC_BASE + (0x10 + (n) * 0x20)) // DMA control/status +#define DMAC_DCMD(n) REG32 (DMAC_BASE + (0x14 + (n) * 0x20)) // DMA command +#define DMAC_DDA(n) REG32 (DMAC_BASE + (0x18 + (n) * 0x20)) // DMA descriptor address +#define DMAC_DMACR REG32 (DMAC_BASE + 0x0300) // DMA control register +#define DMAC_DMAIPR REG32 (DMAC_BASE + 0x0304) // DMA interrupt pending +#define DMAC_DMADBR REG32 (DMAC_BASE + 0x0308) // DMA doorbell +#define DMAC_DMADBSR REG32 (DMAC_BASE + 0x030C) // DMA doorbell set + +// DMA request source register +#define DMAC_DRSR_RS_BIT 0 +#define DMAC_DRSR_RS_MASK (0x1f << DMAC_DRSR_RS_BIT) + #define DMAC_DRSR_RS_AUTO (8 << DMAC_DRSR_RS_BIT) + #define DMAC_DRSR_RS_UART0OUT (20 << DMAC_DRSR_RS_BIT) + #define DMAC_DRSR_RS_UART0IN (21 << DMAC_DRSR_RS_BIT) + #define DMAC_DRSR_RS_SSIOUT (22 << DMAC_DRSR_RS_BIT) + #define DMAC_DRSR_RS_SSIIN (23 << DMAC_DRSR_RS_BIT) + #define DMAC_DRSR_RS_AICOUT (24 << DMAC_DRSR_RS_BIT) + #define DMAC_DRSR_RS_AICIN (25 << DMAC_DRSR_RS_BIT) + #define DMAC_DRSR_RS_MSCOUT (26 << DMAC_DRSR_RS_BIT) + #define DMAC_DRSR_RS_MSCIN (27 << DMAC_DRSR_RS_BIT) + #define DMAC_DRSR_RS_TCU (28 << DMAC_DRSR_RS_BIT) + #define DMAC_DRSR_RS_SADC (29 << DMAC_DRSR_RS_BIT) + #define DMAC_DRSR_RS_SLCD (30 << DMAC_DRSR_RS_BIT) + +// DMA channel control/status register +#define DMAC_DCCSR_NDES (1 << 31) // descriptor (0) or not (1) ? +#define DMAC_DCCSR_CDOA_BIT 16 // copy of DMA offset address +#define DMAC_DCCSR_CDOA_MASK (0xff << DMAC_DCCSR_CDOA_BIT) +#define DMAC_DCCSR_INV (1 << 6) // descriptor invalid +#define DMAC_DCCSR_AR (1 << 4) // address error +#define DMAC_DCCSR_TT (1 << 3) // transfer terminated +#define DMAC_DCCSR_HLT (1 << 2) // DMA halted +#define DMAC_DCCSR_CT (1 << 1) // count terminated +#define DMAC_DCCSR_EN (1 << 0) // channel enable bit + +// DMA channel command register +#define DMAC_DCMD_SAI (1 << 23) // source address increment +#define DMAC_DCMD_DAI (1 << 22) // dest address increment +#define DMAC_DCMD_RDIL_BIT 16 // request detection interval length +#define DMAC_DCMD_RDIL_MASK (0x0f << DMAC_DCMD_RDIL_BIT) + #define DMAC_DCMD_RDIL_IGN (0 << DMAC_DCMD_RDIL_BIT) + #define DMAC_DCMD_RDIL_2 (1 << DMAC_DCMD_RDIL_BIT) + #define DMAC_DCMD_RDIL_4 (2 << DMAC_DCMD_RDIL_BIT) + #define DMAC_DCMD_RDIL_8 (3 << DMAC_DCMD_RDIL_BIT) + #define DMAC_DCMD_RDIL_12 (4 << DMAC_DCMD_RDIL_BIT) + #define DMAC_DCMD_RDIL_16 (5 << DMAC_DCMD_RDIL_BIT) + #define DMAC_DCMD_RDIL_20 (6 << DMAC_DCMD_RDIL_BIT) + #define DMAC_DCMD_RDIL_24 (7 << DMAC_DCMD_RDIL_BIT) + #define DMAC_DCMD_RDIL_28 (8 << DMAC_DCMD_RDIL_BIT) + #define DMAC_DCMD_RDIL_32 (9 << DMAC_DCMD_RDIL_BIT) + #define DMAC_DCMD_RDIL_48 (10 << DMAC_DCMD_RDIL_BIT) + #define DMAC_DCMD_RDIL_60 (11 << DMAC_DCMD_RDIL_BIT) + #define DMAC_DCMD_RDIL_64 (12 << DMAC_DCMD_RDIL_BIT) + #define DMAC_DCMD_RDIL_124 (13 << DMAC_DCMD_RDIL_BIT) + #define DMAC_DCMD_RDIL_128 (14 << DMAC_DCMD_RDIL_BIT) + #define DMAC_DCMD_RDIL_200 (15 << DMAC_DCMD_RDIL_BIT) +#define DMAC_DCMD_SWDH_BIT 14 // source port width +#define DMAC_DCMD_SWDH_MASK (0x03 << DMAC_DCMD_SWDH_BIT) + #define DMAC_DCMD_SWDH_32 (0 << DMAC_DCMD_SWDH_BIT) + #define DMAC_DCMD_SWDH_8 (1 << DMAC_DCMD_SWDH_BIT) + #define DMAC_DCMD_SWDH_16 (2 << DMAC_DCMD_SWDH_BIT) +#define DMAC_DCMD_DWDH_BIT 12 // dest port width +#define DMAC_DCMD_DWDH_MASK (0x03 << DMAC_DCMD_DWDH_BIT) + #define DMAC_DCMD_DWDH_32 (0 << DMAC_DCMD_DWDH_BIT) + #define DMAC_DCMD_DWDH_8 (1 << DMAC_DCMD_DWDH_BIT) + #define DMAC_DCMD_DWDH_16 (2 << DMAC_DCMD_DWDH_BIT) +#define DMAC_DCMD_DS_BIT 8 // transfer data size of a data unit +#define DMAC_DCMD_DS_MASK (0x07 << DMAC_DCMD_DS_BIT) + #define DMAC_DCMD_DS_32BIT (0 << DMAC_DCMD_DS_BIT) + #define DMAC_DCMD_DS_8BIT (1 << DMAC_DCMD_DS_BIT) + #define DMAC_DCMD_DS_16BIT (2 << DMAC_DCMD_DS_BIT) + #define DMAC_DCMD_DS_16BYTE (3 << DMAC_DCMD_DS_BIT) + #define DMAC_DCMD_DS_32BYTE (4 << DMAC_DCMD_DS_BIT) +#define DMAC_DCMD_TM (1 << 7) // transfer mode: 0-single 1-block +#define DMAC_DCMD_DES_V (1 << 4) // descriptor valid flag +#define DMAC_DCMD_DES_VM (1 << 3) // descriptor valid mask: 1:support V-bit +#define DMAC_DCMD_DES_VIE (1 << 2) // DMA valid error interrupt enable +#define DMAC_DCMD_TIE (1 << 1) // DMA transfer interrupt enable +#define DMAC_DCMD_LINK (1 << 0) // descriptor link enable + +// DMA descriptor address register +#define DMAC_DDA_BASE_BIT 12 // descriptor base address +#define DMAC_DDA_BASE_MASK (0x0fffff << DMAC_DDA_BASE_BIT) +#define DMAC_DDA_OFFSET_BIT 4 // descriptor offset address +#define DMAC_DDA_OFFSET_MASK (0x0ff << DMAC_DDA_OFFSET_BIT) + +// DMA control register +#define DMAC_DMACR_PR_BIT 8 // channel priority mode +#define DMAC_DMACR_PR_MASK (0x03 << DMAC_DMACR_PR_BIT) + #define DMAC_DMACR_PR_012345 (0 << DMAC_DMACR_PR_BIT) + #define DMAC_DMACR_PR_023145 (1 << DMAC_DMACR_PR_BIT) + #define DMAC_DMACR_PR_201345 (2 << DMAC_DMACR_PR_BIT) + #define DMAC_DMACR_PR_RR (3 << DMAC_DMACR_PR_BIT) // round robin +#define DMAC_DMACR_HLT (1 << 3) // DMA halt flag +#define DMAC_DMACR_AR (1 << 2) // address error flag +#define DMAC_DMACR_DMAE (1 << 0) // DMA enable bit +#define DMAC_DMADBR_DB (1 << 5) // doorbell +#define DMAC_DMADBSR_DBS (1 << 5) // enable doorbell +#define DMAC_DMAIPR_CIRQ(n) (1 << n) // irq pending status for channel n + + +//************************************************************************ +// GPIO (General-Purpose I/O Ports) +//************************************************************************ +#define MAX_GPIO_NUM 128 + +//n = 0,1,2,3 +#define GPIO_PXPIN(n) REG32 (GPIO_BASE + (0x00 + (n)*0x100)) // PIN Level Register +#define GPIO_PXDAT(n) REG32 (GPIO_BASE + (0x10 + (n)*0x100)) // Port Data Register 1: interrupt pending +#define GPIO_PXDATS(n) REG32 (GPIO_BASE + (0x14 + (n)*0x100)) // Port Data Set Register +#define GPIO_PXDATC(n) REG32 (GPIO_BASE + (0x18 + (n)*0x100)) // Port Data Clear Register +#define GPIO_PXIM(n) REG32 (GPIO_BASE + (0x20 + (n)*0x100)) // Interrupt Mask Register 1: mask pin interrupt +#define GPIO_PXIMS(n) REG32 (GPIO_BASE + (0x24 + (n)*0x100)) // Interrupt Mask Set Reg +#define GPIO_PXIMC(n) REG32 (GPIO_BASE + (0x28 + (n)*0x100)) // Interrupt Mask Clear Reg +#define GPIO_PXPE(n) REG32 (GPIO_BASE + (0x30 + (n)*0x100)) // Pull Enable Register 1: disable pull up/down +#define GPIO_PXPES(n) REG32 (GPIO_BASE + (0x34 + (n)*0x100)) // Pull Enable Set Reg. +#define GPIO_PXPEC(n) REG32 (GPIO_BASE + (0x38 + (n)*0x100)) // Pull Enable Clear Reg. +#define GPIO_PXFUN(n) REG32 (GPIO_BASE + (0x40 + (n)*0x100)) // Function Register 0: gpio; 1: function +#define GPIO_PXFUNS(n) REG32 (GPIO_BASE + (0x44 + (n)*0x100)) // Function Set Register +#define GPIO_PXFUNC(n) REG32 (GPIO_BASE + (0x48 + (n)*0x100)) // Function Clear Register +#define GPIO_PXSEL(n) REG32 (GPIO_BASE + (0x50 + (n)*0x100)) // Select Register 0: gpio/fun0; 1: intr/fun1 +#define GPIO_PXSELS(n) REG32 (GPIO_BASE + (0x54 + (n)*0x100)) // Select Set Register +#define GPIO_PXSELC(n) REG32 (GPIO_BASE + (0x58 + (n)*0x100)) // Select Clear Register +#define GPIO_PXDIR(n) REG32 (GPIO_BASE + (0x60 + (n)*0x100)) // Direction Register 0:input/low-level-trig/falling-edge-trig, 1:output/high-level-trig/rising-edge-trig +#define GPIO_PXDIRS(n) REG32 (GPIO_BASE + (0x64 + (n)*0x100)) // Direction Set Register +#define GPIO_PXDIRC(n) REG32 (GPIO_BASE + (0x68 + (n)*0x100)) // Direction Clear Register +#define GPIO_PXTRG(n) REG32 (GPIO_BASE + (0x70 + (n)*0x100)) // Trigger Register 0:level-trigger, 1:edge-trigger +#define GPIO_PXTRGS(n) REG32 (GPIO_BASE + (0x74 + (n)*0x100)) // Trigger Set Register +#define GPIO_PXTRGC(n) REG32 (GPIO_BASE + (0x78 + (n)*0x100)) // Trigger Set Register +#define GPIO_PXFLG(n) REG32 (GPIO_BASE + (0x80 + (n)*0x100)) // Port Flag Register interrupt flag +#define GPIO_PXFLGC(n) REG32 (GPIO_BASE + (0x14 + (n)*0x100)) // Port Flag Clear Register + + +//************************************************************************ +// UART +//************************************************************************ + +#define IRDA_BASE UART0_BASE +#define UART_BASE UART0_BASE +#define UART_OFF 0x1000 + +// Register Offset +#define OFF_RDR (0x00) // R 8b H'xx +#define OFF_TDR (0x00) // W 8b H'xx +#define OFF_DLLR (0x00) // RW 8b H'00 +#define OFF_DLHR (0x04) // RW 8b H'00 +#define OFF_IER (0x04) // RW 8b H'00 +#define OFF_ISR (0x08) // R 8b H'01 +#define OFF_FCR (0x08) // W 8b H'00 +#define OFF_LCR (0x0C) // RW 8b H'00 +#define OFF_MCR (0x10) // RW 8b H'00 +#define OFF_LSR (0x14) // R 8b H'00 +#define OFF_MSR (0x18) // R 8b H'00 +#define OFF_SPR (0x1C) // RW 8b H'00 +#define OFF_SIRCR (0x20) // RW 8b H'00, UART0 +#define OFF_UMR (0x24) // RW 8b H'00, UART M Register +#define OFF_UACR (0x28) // RW 8b H'00, UART Add Cycle Register + +// Register Address +#define UART0_RDR REG8 (UART0_BASE + OFF_RDR) +#define UART0_TDR REG8 (UART0_BASE + OFF_TDR) +#define UART0_DLLR REG8 (UART0_BASE + OFF_DLLR) +#define UART0_DLHR REG8 (UART0_BASE + OFF_DLHR) +#define UART0_IER REG8 (UART0_BASE + OFF_IER) +#define UART0_ISR REG8 (UART0_BASE + OFF_ISR) +#define UART0_FCR REG8 (UART0_BASE + OFF_FCR) +#define UART0_LCR REG8 (UART0_BASE + OFF_LCR) +#define UART0_MCR REG8 (UART0_BASE + OFF_MCR) +#define UART0_LSR REG8 (UART0_BASE + OFF_LSR) +#define UART0_MSR REG8 (UART0_BASE + OFF_MSR) +#define UART0_SPR REG8 (UART0_BASE + OFF_SPR) +#define UART0_SIRCR REG8 (UART0_BASE + OFF_SIRCR) +#define UART0_UMR REG8 (UART0_BASE + OFF_UMR) +#define UART0_UACR REG8 (UART0_BASE + OFF_UACR) + +// UART Interrupt Enable Register +#define UARTIER_RIE (1 << 0) // 0: receive fifo full interrupt disable +#define UARTIER_TIE (1 << 1) // 0: transmit fifo empty interrupt disable +#define UARTIER_RLIE (1 << 2) // 0: receive line status interrupt disable +#define UARTIER_MIE (1 << 3) // 0: modem status interrupt disable +#define UARTIER_RTIE (1 << 4) // 0: receive timeout interrupt disable + +// UART Interrupt Status Register +#define UARTISR_IP (1 << 0) // 0: interrupt is pending 1: no interrupt +#define UARTISR_IID (7 << 1) // Source of Interrupt +#define UARTISR_IID_MSI (0 << 1) // Modem status interrupt +#define UARTISR_IID_THRI (1 << 1) // Transmitter holding register empty +#define UARTISR_IID_RDI (2 << 1) // Receiver data interrupt +#define UARTISR_IID_RLSI (3 << 1) // Receiver line status interrupt +#define UARTISR_IID_RTO (6 << 1) // Receive timeout +#define UARTISR_FFMS (3 << 6) // FIFO mode select, set when UARTFCR.FE is set to 1 +#define UARTISR_FFMS_NO_FIFO (0 << 6) +#define UARTISR_FFMS_FIFO_MODE (3 << 6) + +// UART FIFO Control Register +#define UARTFCR_FE (1 << 0) // 0: non-FIFO mode 1: FIFO mode +#define UARTFCR_RFLS (1 << 1) // write 1 to flush receive FIFO +#define UARTFCR_TFLS (1 << 2) // write 1 to flush transmit FIFO +#define UARTFCR_DMS (1 << 3) // 0: disable DMA mode +#define UARTFCR_UUE (1 << 4) // 0: disable UART +#define UARTFCR_RTRG (3 << 6) // Receive FIFO Data Trigger +#define UARTFCR_RTRG_1 (0 << 6) +#define UARTFCR_RTRG_4 (1 << 6) +#define UARTFCR_RTRG_8 (2 << 6) +#define UARTFCR_RTRG_15 (3 << 6) + +// UART Line Control Register +#define UARTLCR_WLEN (3 << 0) // word length +#define UARTLCR_WLEN_5 (0 << 0) +#define UARTLCR_WLEN_6 (1 << 0) +#define UARTLCR_WLEN_7 (2 << 0) +#define UARTLCR_WLEN_8 (3 << 0) +#define UARTLCR_STOP (1 << 2) // 0: 1 stop bit when word length is 5,6,7,8 1: 1.5 stop bits when 5; 2 stop bits when 6,7,8 +#define UARTLCR_STOP1 (0 << 2) +#define UARTLCR_STOP2 (1 << 2) +#define UARTLCR_PE (1 << 3) // 0: parity disable +#define UARTLCR_PROE (1 << 4) // 0: even parity 1: odd parity +#define UARTLCR_SPAR (1 << 5) // 0: sticky parity disable +#define UARTLCR_SBRK (1 << 6) // write 0 normal, write 1 send break +#define UARTLCR_DLAB (1 << 7) // 0: access UARTRDR/TDR/IER 1: access UARTDLLR/DLHR + +// UART Line Status Register +#define UARTLSR_DR (1 << 0) // 0: receive FIFO is empty 1: receive data is ready +#define UARTLSR_ORER (1 << 1) // 0: no overrun error +#define UARTLSR_PER (1 << 2) // 0: no parity error +#define UARTLSR_FER (1 << 3) // 0; no framing error +#define UARTLSR_BRK (1 << 4) // 0: no break detected 1: receive a break signal +#define UARTLSR_TDRQ (1 << 5) // 1: transmit FIFO half "empty" +#define UARTLSR_TEMT (1 << 6) // 1: transmit FIFO and shift registers empty +#define UARTLSR_RFER (1 << 7) // 0: no receive error 1: receive error in FIFO mode + +// UART Modem Control Register +#define UARTMCR_RTS (1 << 1) // 0: RTS_ output high, 1: RTS_ output low +#define UARTMCR_LOOP (1 << 4) // 0: normal 1: loopback mode +#define UARTMCR_MCE (1 << 7) // 0: modem function is disable + +// UART Modem Status Register +#define UARTMSR_CCTS (1 << 0) // 1: a change on CTS_ pin +#define UARTMSR_CTS (1 << 4) // 0: CTS_ pin is high + +// Slow IrDA Control Register +#define SIRCR_TSIRE (1 << 0) // 0: transmitter is in UART mode 1: SIR mode +#define SIRCR_RSIRE (1 << 1) // 0: receiver is in UART mode 1: SIR mode +#define SIRCR_TPWS (1 << 2) // 0: transmit 0 pulse width is 3/16 of bit length 1: 0 pulse width is 1.6us for 115.2Kbps +#define SIRCR_TDPL (1 << 3) // 0: encoder generates a positive pulse for 0 +#define SIRCR_RDPL (1 << 4) // 0: decoder interprets positive pulse as 0 + + +//************************************************************************ +// AIC (AC97/I2S Controller) +//************************************************************************ +#define AIC_FR REG32 (AIC_BASE + 0x000) +#define AIC_CR REG32 (AIC_BASE + 0x004) +#define AIC_ACCR1 REG32 (AIC_BASE + 0x008) +#define AIC_ACCR2 REG32 (AIC_BASE + 0x00C) +#define AIC_I2SCR REG32 (AIC_BASE + 0x010) +#define AIC_SR REG32 (AIC_BASE + 0x014) +#define AIC_ACSR REG32 (AIC_BASE + 0x018) +#define AIC_I2SSR REG32 (AIC_BASE + 0x01C) +#define AIC_ACCAR REG32 (AIC_BASE + 0x020) +#define AIC_ACCDR REG32 (AIC_BASE + 0x024) +#define AIC_ACSAR REG32 (AIC_BASE + 0x028) +#define AIC_ACSDR REG32 (AIC_BASE + 0x02C) +#define AIC_I2SDIV REG32 (AIC_BASE + 0x030) +#define AIC_DR REG32 (AIC_BASE + 0x034) + +// AIC Controller Configuration Register (AIC_FR) + +#define AIC_FR_RFTH_BIT 12 // Receive FIFO Threshold +#define AIC_FR_RFTH_MASK (0xf << AIC_FR_RFTH_BIT) +#define AIC_FR_TFTH_BIT 8 // Transmit FIFO Threshold +#define AIC_FR_TFTH_MASK (0xf << AIC_FR_TFTH_BIT) +#define AIC_FR_LSMP (1 << 6) // Play Zero sample or last sample +#define AIC_FR_ICDC (1 << 5) // External(0) or Internal CODEC(1) +#define AIC_FR_AUSEL (1 << 4) // AC97(0) or I2S/MSB-justified(1) +#define AIC_FR_RST (1 << 3) // AIC registers reset +#define AIC_FR_BCKD (1 << 2) // I2S BIT_CLK direction, 0:input,1:output +#define AIC_FR_SYNCD (1 << 1) // I2S SYNC direction, 0:input,1:output +#define AIC_FR_ENB (1 << 0) // AIC enable bit + +// AIC Controller Common Control Register (AIC_CR) + +#define AIC_CR_OSS_BIT 19 // Output Sample Size from memory (AIC V2 only) +#define AIC_CR_OSS_MASK (0x7 << AIC_CR_OSS_BIT) + #define AIC_CR_OSS_8BIT (0x0 << AIC_CR_OSS_BIT) + #define AIC_CR_OSS_16BIT (0x1 << AIC_CR_OSS_BIT) + #define AIC_CR_OSS_18BIT (0x2 << AIC_CR_OSS_BIT) + #define AIC_CR_OSS_20BIT (0x3 << AIC_CR_OSS_BIT) + #define AIC_CR_OSS_24BIT (0x4 << AIC_CR_OSS_BIT) +#define AIC_CR_ISS_BIT 16 // Input Sample Size from memory (AIC V2 only) +#define AIC_CR_ISS_MASK (0x7 << AIC_CR_ISS_BIT) + #define AIC_CR_ISS_8BIT (0x0 << AIC_CR_ISS_BIT) + #define AIC_CR_ISS_16BIT (0x1 << AIC_CR_ISS_BIT) + #define AIC_CR_ISS_18BIT (0x2 << AIC_CR_ISS_BIT) + #define AIC_CR_ISS_20BIT (0x3 << AIC_CR_ISS_BIT) + #define AIC_CR_ISS_24BIT (0x4 << AIC_CR_ISS_BIT) +#define AIC_CR_RDMS (1 << 15) // Receive DMA enable +#define AIC_CR_TDMS (1 << 14) // Transmit DMA enable +#define AIC_CR_M2S (1 << 11) // Mono to Stereo enable +#define AIC_CR_ENDSW (1 << 10) // Endian switch enable +#define AIC_CR_AVSTSU (1 << 9) // Signed <-> Unsigned toggle enable +#define AIC_CR_FLUSH (1 << 8) // Flush FIFO +#define AIC_CR_EROR (1 << 6) // Enable ROR interrupt +#define AIC_CR_ETUR (1 << 5) // Enable TUR interrupt +#define AIC_CR_ERFS (1 << 4) // Enable RFS interrupt +#define AIC_CR_ETFS (1 << 3) // Enable TFS interrupt +#define AIC_CR_ENLBF (1 << 2) // Enable Loopback Function +#define AIC_CR_ERPL (1 << 1) // Enable Playback Function +#define AIC_CR_EREC (1 << 0) // Enable Record Function + +// AIC Controller AC-link Control Register 1 (AIC_ACCR1) + +#define AIC_ACCR1_RS_BIT 16 // Receive Valid Slots +#define AIC_ACCR1_RS_MASK (0x3ff << AIC_ACCR1_RS_BIT) + #define AIC_ACCR1_RS_SLOT12 (1 << 25) // Slot 12 valid bit + #define AIC_ACCR1_RS_SLOT11 (1 << 24) // Slot 11 valid bit + #define AIC_ACCR1_RS_SLOT10 (1 << 23) // Slot 10 valid bit + #define AIC_ACCR1_RS_SLOT9 (1 << 22) // Slot 9 valid bit, LFE + #define AIC_ACCR1_RS_SLOT8 (1 << 21) // Slot 8 valid bit, Surround Right + #define AIC_ACCR1_RS_SLOT7 (1 << 20) // Slot 7 valid bit, Surround Left + #define AIC_ACCR1_RS_SLOT6 (1 << 19) // Slot 6 valid bit, PCM Center + #define AIC_ACCR1_RS_SLOT5 (1 << 18) // Slot 5 valid bit + #define AIC_ACCR1_RS_SLOT4 (1 << 17) // Slot 4 valid bit, PCM Right + #define AIC_ACCR1_RS_SLOT3 (1 << 16) // Slot 3 valid bit, PCM Left +#define AIC_ACCR1_XS_BIT 0 // Transmit Valid Slots +#define AIC_ACCR1_XS_MASK (0x3ff << AIC_ACCR1_XS_BIT) + #define AIC_ACCR1_XS_SLOT12 (1 << 9) // Slot 12 valid bit + #define AIC_ACCR1_XS_SLOT11 (1 << 8) // Slot 11 valid bit + #define AIC_ACCR1_XS_SLOT10 (1 << 7) // Slot 10 valid bit + #define AIC_ACCR1_XS_SLOT9 (1 << 6) // Slot 9 valid bit, LFE + #define AIC_ACCR1_XS_SLOT8 (1 << 5) // Slot 8 valid bit, Surround Right + #define AIC_ACCR1_XS_SLOT7 (1 << 4) // Slot 7 valid bit, Surround Left + #define AIC_ACCR1_XS_SLOT6 (1 << 3) // Slot 6 valid bit, PCM Center + #define AIC_ACCR1_XS_SLOT5 (1 << 2) // Slot 5 valid bit + #define AIC_ACCR1_XS_SLOT4 (1 << 1) // Slot 4 valid bit, PCM Right + #define AIC_ACCR1_XS_SLOT3 (1 << 0) // Slot 3 valid bit, PCM Left + +// AIC Controller AC-link Control Register 2 (AIC_ACCR2) + +#define AIC_ACCR2_ERSTO (1 << 18) // Enable RSTO interrupt +#define AIC_ACCR2_ESADR (1 << 17) // Enable SADR interrupt +#define AIC_ACCR2_ECADT (1 << 16) // Enable CADT interrupt +#define AIC_ACCR2_OASS_BIT 8 // Output Sample Size for AC-link +#define AIC_ACCR2_OASS_MASK (0x3 << AIC_ACCR2_OASS_BIT) + #define AIC_ACCR2_OASS_20BIT (0 << AIC_ACCR2_OASS_BIT) // Output Audio Sample Size is 20-bit + #define AIC_ACCR2_OASS_18BIT (1 << AIC_ACCR2_OASS_BIT) // Output Audio Sample Size is 18-bit + #define AIC_ACCR2_OASS_16BIT (2 << AIC_ACCR2_OASS_BIT) // Output Audio Sample Size is 16-bit + #define AIC_ACCR2_OASS_8BIT (3 << AIC_ACCR2_OASS_BIT) // Output Audio Sample Size is 8-bit +#define AIC_ACCR2_IASS_BIT 6 // Output Sample Size for AC-link +#define AIC_ACCR2_IASS_MASK (0x3 << AIC_ACCR2_IASS_BIT) + #define AIC_ACCR2_IASS_20BIT (0 << AIC_ACCR2_IASS_BIT) // Input Audio Sample Size is 20-bit + #define AIC_ACCR2_IASS_18BIT (1 << AIC_ACCR2_IASS_BIT) // Input Audio Sample Size is 18-bit + #define AIC_ACCR2_IASS_16BIT (2 << AIC_ACCR2_IASS_BIT) // Input Audio Sample Size is 16-bit + #define AIC_ACCR2_IASS_8BIT (3 << AIC_ACCR2_IASS_BIT) // Input Audio Sample Size is 8-bit +#define AIC_ACCR2_SO (1 << 3) // SDATA_OUT output value +#define AIC_ACCR2_SR (1 << 2) // RESET# pin level +#define AIC_ACCR2_SS (1 << 1) // SYNC pin level +#define AIC_ACCR2_SA (1 << 0) // SYNC and SDATA_OUT alternation + +// AIC Controller I2S/MSB-justified Control Register (AIC_I2SCR) + +#define AIC_I2SCR_STPBK (1 << 12) // Stop BIT_CLK for I2S/MSB-justified +#define AIC_I2SCR_WL_BIT 1 // Input/Output Sample Size for I2S/MSB-justified +#define AIC_I2SCR_WL_MASK (0x7 << AIC_I2SCR_WL_BIT) + #define AIC_I2SCR_WL_24BIT (0 << AIC_I2SCR_WL_BIT) // Word Length is 24 bit + #define AIC_I2SCR_WL_20BIT (1 << AIC_I2SCR_WL_BIT) // Word Length is 20 bit + #define AIC_I2SCR_WL_18BIT (2 << AIC_I2SCR_WL_BIT) // Word Length is 18 bit + #define AIC_I2SCR_WL_16BIT (3 << AIC_I2SCR_WL_BIT) // Word Length is 16 bit + #define AIC_I2SCR_WL_8BIT (4 << AIC_I2SCR_WL_BIT) // Word Length is 8 bit +#define AIC_I2SCR_AMSL (1 << 0) // 0:I2S, 1:MSB-justified + +// AIC Controller FIFO Status Register (AIC_SR) + +#define AIC_SR_RFL_BIT 24 // Receive FIFO Level +#define AIC_SR_RFL_MASK (0x3f << AIC_SR_RFL_BIT) +#define AIC_SR_TFL_BIT 8 // Transmit FIFO level +#define AIC_SR_TFL_MASK (0x3f << AIC_SR_TFL_BIT) +#define AIC_SR_ROR (1 << 6) // Receive FIFO Overrun +#define AIC_SR_TUR (1 << 5) // Transmit FIFO Underrun +#define AIC_SR_RFS (1 << 4) // Receive FIFO Service Request +#define AIC_SR_TFS (1 << 3) // Transmit FIFO Service Request + +// AIC Controller AC-link Status Register (AIC_ACSR) + +#define AIC_ACSR_SLTERR (1 << 21) // Slot Error Flag +#define AIC_ACSR_CRDY (1 << 20) // External CODEC Ready Flag +#define AIC_ACSR_CLPM (1 << 19) // External CODEC low power mode flag +#define AIC_ACSR_RSTO (1 << 18) // External CODEC regs read status timeout +#define AIC_ACSR_SADR (1 << 17) // External CODEC regs status addr and data received +#define AIC_ACSR_CADT (1 << 16) // Command Address and Data Transmitted + +// AIC Controller I2S/MSB-justified Status Register (AIC_I2SSR) + +#define AIC_I2SSR_BSY (1 << 2) // AIC Busy in I2S/MSB-justified format + +// AIC Controller AC97 codec Command Address Register (AIC_ACCAR) + +#define AIC_ACCAR_CAR_BIT 0 +#define AIC_ACCAR_CAR_MASK (0xfffff << AIC_ACCAR_CAR_BIT) + +// AIC Controller AC97 codec Command Data Register (AIC_ACCDR) + +#define AIC_ACCDR_CDR_BIT 0 +#define AIC_ACCDR_CDR_MASK (0xfffff << AIC_ACCDR_CDR_BIT) + +// AIC Controller AC97 codec Status Address Register (AIC_ACSAR) + +#define AIC_ACSAR_SAR_BIT 0 +#define AIC_ACSAR_SAR_MASK (0xfffff << AIC_ACSAR_SAR_BIT) + +// AIC Controller AC97 codec Status Data Register (AIC_ACSDR) + +#define AIC_ACSDR_SDR_BIT 0 +#define AIC_ACSDR_SDR_MASK (0xfffff << AIC_ACSDR_SDR_BIT) + +// AIC Controller I2S/MSB-justified Clock Divider Register (AIC_I2SDIV) + +#define AIC_I2SDIV_DIV_BIT 0 +#define AIC_I2SDIV_DIV_MASK (0x7f << AIC_I2SDIV_DIV_BIT) + #define AIC_I2SDIV_BITCLK_3072KHZ (0x0C << AIC_I2SDIV_DIV_BIT) // BIT_CLK of 3.072MHz + #define AIC_I2SDIV_BITCLK_2836KHZ (0x0D << AIC_I2SDIV_DIV_BIT) // BIT_CLK of 2.836MHz + #define AIC_I2SDIV_BITCLK_1418KHZ (0x1A << AIC_I2SDIV_DIV_BIT) // BIT_CLK of 1.418MHz + #define AIC_I2SDIV_BITCLK_1024KHZ (0x24 << AIC_I2SDIV_DIV_BIT) // BIT_CLK of 1.024MHz + #define AIC_I2SDIV_BITCLK_7089KHZ (0x34 << AIC_I2SDIV_DIV_BIT) // BIT_CLK of 708.92KHz + #define AIC_I2SDIV_BITCLK_512KHZ (0x48 << AIC_I2SDIV_DIV_BIT) // BIT_CLK of 512.00KHz + + +//************************************************************************ +// ICDC (Internal CODEC) +//************************************************************************ +#define ICDC_CR REG32 (ICDC_BASE + 0x0400) // ICDC Control Register +#define ICDC_APWAIT REG32 (ICDC_BASE + 0x0404) // Anti-Pop WAIT Stage Timing Control Register +#define ICDC_APPRE REG32 (ICDC_BASE + 0x0408) // Anti-Pop HPEN-PRE Stage Timing Control Register +#define ICDC_APHPEN REG32 (ICDC_BASE + 0x040C) // Anti-Pop HPEN Stage Timing Control Register +#define ICDC_APSR REG32 (ICDC_BASE + 0x0410) // Anti-Pop Status Register +#define ICDC_CDCCR1 REG32 (ICDC_BASE + 0x0080) +#define ICDC_CDCCR2 REG32 (ICDC_BASE + 0x0084) + +// ICDC Control Register +#define ICDC_CR_LINVOL_BIT 24 // LINE Input Volume Gain: GAIN=LINVOL*1.5-34.5 +#define ICDC_CR_LINVOL_MASK (0x1f << ICDC_CR_LINVOL_BIT) +#define ICDC_CR_ASRATE_BIT 20 // Audio Sample Rate +#define ICDC_CR_ASRATE_MASK (0x0f << ICDC_CR_ASRATE_BIT) + #define ICDC_CR_ASRATE_8000 (0x0 << ICDC_CR_ASRATE_BIT) + #define ICDC_CR_ASRATE_11025 (0x1 << ICDC_CR_ASRATE_BIT) + #define ICDC_CR_ASRATE_12000 (0x2 << ICDC_CR_ASRATE_BIT) + #define ICDC_CR_ASRATE_16000 (0x3 << ICDC_CR_ASRATE_BIT) + #define ICDC_CR_ASRATE_22050 (0x4 << ICDC_CR_ASRATE_BIT) + #define ICDC_CR_ASRATE_24000 (0x5 << ICDC_CR_ASRATE_BIT) + #define ICDC_CR_ASRATE_32000 (0x6 << ICDC_CR_ASRATE_BIT) + #define ICDC_CR_ASRATE_44100 (0x7 << ICDC_CR_ASRATE_BIT) + #define ICDC_CR_ASRATE_48000 (0x8 << ICDC_CR_ASRATE_BIT) +#define ICDC_CR_MICBG_BIT 18 // MIC Boost Gain +#define ICDC_CR_MICBG_MASK (0x3 << ICDC_CR_MICBG_BIT) + #define ICDC_CR_MICBG_0DB (0x0 << ICDC_CR_MICBG_BIT) + #define ICDC_CR_MICBG_6DB (0x1 << ICDC_CR_MICBG_BIT) + #define ICDC_CR_MICBG_12DB (0x2 << ICDC_CR_MICBG_BIT) + #define ICDC_CR_MICBG_20DB (0x3 << ICDC_CR_MICBG_BIT) +#define ICDC_CR_HPVOL_BIT 16 // Headphone Volume Gain +#define ICDC_CR_HPVOL_MASK (0x3 << ICDC_CR_HPVOL_BIT) + #define ICDC_CR_HPVOL_0DB (0x0 << ICDC_CR_HPVOL_BIT) + #define ICDC_CR_HPVOL_2DB (0x1 << ICDC_CR_HPVOL_BIT) + #define ICDC_CR_HPVOL_4DB (0x2 << ICDC_CR_HPVOL_BIT) + #define ICDC_CR_HPVOL_6DB (0x3 << ICDC_CR_HPVOL_BIT) +#define ICDC_CR_ELINEIN (1 << 13) // Enable LINE Input +#define ICDC_CR_EMIC (1 << 12) // Enable MIC Input +#define ICDC_CR_SW1ON (1 << 11) // Switch 1 in CODEC is on +#define ICDC_CR_EADC (1 << 10) // Enable ADC +#define ICDC_CR_SW2ON (1 << 9) // Switch 2 in CODEC is on +#define ICDC_CR_EDAC (1 << 8) // Enable DAC +#define ICDC_CR_HPMUTE (1 << 5) // Headphone Mute +#define ICDC_CR_HPTON (1 << 4) // Headphone Amplifier Trun On +#define ICDC_CR_HPTOFF (1 << 3) // Headphone Amplifier Trun Off +#define ICDC_CR_TAAP (1 << 2) // Turn Around of the Anti-Pop Procedure +#define ICDC_CR_EAP (1 << 1) // Enable Anti-Pop Procedure +#define ICDC_CR_SUSPD (1 << 0) // CODEC Suspend + +// Anti-Pop WAIT Stage Timing Control Register +#define ICDC_APWAIT_WAITSN_BIT 0 +#define ICDC_APWAIT_WAITSN_MASK (0x7ff << ICDC_APWAIT_WAITSN_BIT) + +// Anti-Pop HPEN-PRE Stage Timing Control Register +#define ICDC_APPRE_PRESN_BIT 0 +#define ICDC_APPRE_PRESN_MASK (0x1ff << ICDC_APPRE_PRESN_BIT) + +// Anti-Pop HPEN Stage Timing Control Register +#define ICDC_APHPEN_HPENSN_BIT 0 +#define ICDC_APHPEN_HPENSN_MASK (0x3fff << ICDC_APHPEN_HPENSN_BIT) + +// Anti-Pop Status Register +#define ICDC_SR_HPST_BIT 14 // Headphone Amplifier State +#define ICDC_SR_HPST_MASK (0x7 << ICDC_SR_HPST_BIT) +#define ICDC_SR_HPST_HP_OFF (0x0 << ICDC_SR_HPST_BIT) // HP amplifier is off +#define ICDC_SR_HPST_TON_WAIT (0x1 << ICDC_SR_HPST_BIT) // wait state in turn-on + #define ICDC_SR_HPST_TON_PRE (0x2 << ICDC_SR_HPST_BIT) // pre-enable state in turn-on +#define ICDC_SR_HPST_TON_HPEN (0x3 << ICDC_SR_HPST_BIT) // HP enable state in turn-on + #define ICDC_SR_HPST_TOFF_HPEN (0x4 << ICDC_SR_HPST_BIT) // HP enable state in turn-off + #define ICDC_SR_HPST_TOFF_PRE (0x5 << ICDC_SR_HPST_BIT) // pre-enable state in turn-off + #define ICDC_SR_HPST_TOFF_WAIT (0x6 << ICDC_SR_HPST_BIT) // wait state in turn-off + #define ICDC_SR_HPST_HP_ON (0x7 << ICDC_SR_HPST_BIT) // HP amplifier is on +#define ICDC_SR_SNCNT_BIT 0 // Sample Number Counter +#define ICDC_SR_SNCNT_MASK (0x3fff << ICDC_SR_SNCNT_BIT) + + +//************************************************************************ +// I2C +//************************************************************************ +#define I2C_DR REG8 (I2C_BASE + 0x000) +#define I2C_CR REG8 (I2C_BASE + 0x004) +#define I2C_SR REG8 (I2C_BASE + 0x008) +#define I2C_GR REG16 (I2C_BASE + 0x00C) + +// I2C Control Register (I2C_CR) + +#define I2C_CR_IEN (1 << 4) +#define I2C_CR_STA (1 << 3) +#define I2C_CR_STO (1 << 2) +#define I2C_CR_AC (1 << 1) +#define I2C_CR_I2CE (1 << 0) + +// I2C Status Register (I2C_SR) + +#define I2C_SR_STX (1 << 4) +#define I2C_SR_BUSY (1 << 3) +#define I2C_SR_TEND (1 << 2) +#define I2C_SR_DRF (1 << 1) +#define I2C_SR_ACKF (1 << 0) + + +//************************************************************************ +// SSI +//************************************************************************ +#define SSI_DR REG32 (SSI_BASE + 0x000) +#define SSI_CR0 REG16 (SSI_BASE + 0x004) +#define SSI_CR1 REG32 (SSI_BASE + 0x008) +#define SSI_SR REG32 (SSI_BASE + 0x00C) +#define SSI_ITR REG16 (SSI_BASE + 0x010) +#define SSI_ICR REG8 (SSI_BASE + 0x014) +#define SSI_GR REG16 (SSI_BASE + 0x018) + +// SSI Data Register (SSI_DR) + +#define SSI_DR_GPC_BIT 0 +#define SSI_DR_GPC_MASK (0x1ff << SSI_DR_GPC_BIT) + +// SSI Control Register 0 (SSI_CR0) + +#define SSI_CR0_SSIE (1 << 15) +#define SSI_CR0_TIE (1 << 14) +#define SSI_CR0_RIE (1 << 13) +#define SSI_CR0_TEIE (1 << 12) +#define SSI_CR0_REIE (1 << 11) +#define SSI_CR0_LOOP (1 << 10) +#define SSI_CR0_RFINE (1 << 9) +#define SSI_CR0_RFINC (1 << 8) +#define SSI_CR0_FSEL (1 << 6) +#define SSI_CR0_TFLUSH (1 << 2) +#define SSI_CR0_RFLUSH (1 << 1) +#define SSI_CR0_DISREV (1 << 0) + +// SSI Control Register 1 (SSI_CR1) + +#define SSI_CR1_FRMHL_BIT 30 +#define SSI_CR1_FRMHL_MASK (0x3 << SSI_CR1_FRMHL_BIT) + #define SSI_CR1_FRMHL_CELOW_CE2LOW (0 << SSI_CR1_FRMHL_BIT) // SSI_CE_ is low valid and SSI_CE2_ is low valid + #define SSI_CR1_FRMHL_CEHIGH_CE2LOW (1 << SSI_CR1_FRMHL_BIT) // SSI_CE_ is high valid and SSI_CE2_ is low valid + #define SSI_CR1_FRMHL_CELOW_CE2HIGH (2 << SSI_CR1_FRMHL_BIT) // SSI_CE_ is low valid and SSI_CE2_ is high valid + #define SSI_CR1_FRMHL_CEHIGH_CE2HIGH (3 << SSI_CR1_FRMHL_BIT) // SSI_CE_ is high valid and SSI_CE2_ is high valid +#define SSI_CR1_TFVCK_BIT 28 +#define SSI_CR1_TFVCK_MASK (0x3 << SSI_CR1_TFVCK_BIT) + #define SSI_CR1_TFVCK_0 (0 << SSI_CR1_TFVCK_BIT) + #define SSI_CR1_TFVCK_1 (1 << SSI_CR1_TFVCK_BIT) + #define SSI_CR1_TFVCK_2 (2 << SSI_CR1_TFVCK_BIT) + #define SSI_CR1_TFVCK_3 (3 << SSI_CR1_TFVCK_BIT) +#define SSI_CR1_TCKFI_BIT 26 +#define SSI_CR1_TCKFI_MASK (0x3 << SSI_CR1_TCKFI_BIT) + #define SSI_CR1_TCKFI_0 (0 << SSI_CR1_TCKFI_BIT) + #define SSI_CR1_TCKFI_1 (1 << SSI_CR1_TCKFI_BIT) + #define SSI_CR1_TCKFI_2 (2 << SSI_CR1_TCKFI_BIT) + #define SSI_CR1_TCKFI_3 (3 << SSI_CR1_TCKFI_BIT) +#define SSI_CR1_LFST (1 << 25) +#define SSI_CR1_ITFRM (1 << 24) +#define SSI_CR1_UNFIN (1 << 23) +#define SSI_CR1_MULTS (1 << 22) +#define SSI_CR1_FMAT_BIT 20 +#define SSI_CR1_FMAT_MASK (0x3 << SSI_CR1_FMAT_BIT) + #define SSI_CR1_FMAT_SPI (0 << SSI_CR1_FMAT_BIT) // Motorola's SPI format + #define SSI_CR1_FMAT_SSP (1 << SSI_CR1_FMAT_BIT) // TI's SSP format + #define SSI_CR1_FMAT_MW1 (2 << SSI_CR1_FMAT_BIT) // National Microwire 1 format + #define SSI_CR1_FMAT_MW2 (3 << SSI_CR1_FMAT_BIT) // National Microwire 2 format +#define SSI_CR1_TTRG_BIT 16 +#define SSI_CR1_TTRG_MASK (0xf << SSI_CR1_TTRG_BIT) + #define SSI_CR1_TTRG_1 (0 << SSI_CR1_TTRG_BIT) + #define SSI_CR1_TTRG_8 (1 << SSI_CR1_TTRG_BIT) + #define SSI_CR1_TTRG_16 (2 << SSI_CR1_TTRG_BIT) + #define SSI_CR1_TTRG_24 (3 << SSI_CR1_TTRG_BIT) + #define SSI_CR1_TTRG_32 (4 << SSI_CR1_TTRG_BIT) + #define SSI_CR1_TTRG_40 (5 << SSI_CR1_TTRG_BIT) + #define SSI_CR1_TTRG_48 (6 << SSI_CR1_TTRG_BIT) + #define SSI_CR1_TTRG_56 (7 << SSI_CR1_TTRG_BIT) + #define SSI_CR1_TTRG_64 (8 << SSI_CR1_TTRG_BIT) + #define SSI_CR1_TTRG_72 (9 << SSI_CR1_TTRG_BIT) + #define SSI_CR1_TTRG_80 (10<< SSI_CR1_TTRG_BIT) + #define SSI_CR1_TTRG_88 (11<< SSI_CR1_TTRG_BIT) + #define SSI_CR1_TTRG_96 (12<< SSI_CR1_TTRG_BIT) + #define SSI_CR1_TTRG_104 (13<< SSI_CR1_TTRG_BIT) + #define SSI_CR1_TTRG_112 (14<< SSI_CR1_TTRG_BIT) + #define SSI_CR1_TTRG_120 (15<< SSI_CR1_TTRG_BIT) +#define SSI_CR1_MCOM_BIT 12 +#define SSI_CR1_MCOM_MASK (0xf << SSI_CR1_MCOM_BIT) + #define SSI_CR1_MCOM_1BIT (0x0 << SSI_CR1_MCOM_BIT) // 1-bit command selected + #define SSI_CR1_MCOM_2BIT (0x1 << SSI_CR1_MCOM_BIT) // 2-bit command selected + #define SSI_CR1_MCOM_3BIT (0x2 << SSI_CR1_MCOM_BIT) // 3-bit command selected + #define SSI_CR1_MCOM_4BIT (0x3 << SSI_CR1_MCOM_BIT) // 4-bit command selected + #define SSI_CR1_MCOM_5BIT (0x4 << SSI_CR1_MCOM_BIT) // 5-bit command selected + #define SSI_CR1_MCOM_6BIT (0x5 << SSI_CR1_MCOM_BIT) // 6-bit command selected + #define SSI_CR1_MCOM_7BIT (0x6 << SSI_CR1_MCOM_BIT) // 7-bit command selected + #define SSI_CR1_MCOM_8BIT (0x7 << SSI_CR1_MCOM_BIT) // 8-bit command selected + #define SSI_CR1_MCOM_9BIT (0x8 << SSI_CR1_MCOM_BIT) // 9-bit command selected + #define SSI_CR1_MCOM_10BIT (0x9 << SSI_CR1_MCOM_BIT) // 10-bit command selected + #define SSI_CR1_MCOM_11BIT (0xA << SSI_CR1_MCOM_BIT) // 11-bit command selected + #define SSI_CR1_MCOM_12BIT (0xB << SSI_CR1_MCOM_BIT) // 12-bit command selected + #define SSI_CR1_MCOM_13BIT (0xC << SSI_CR1_MCOM_BIT) // 13-bit command selected + #define SSI_CR1_MCOM_14BIT (0xD << SSI_CR1_MCOM_BIT) // 14-bit command selected + #define SSI_CR1_MCOM_15BIT (0xE << SSI_CR1_MCOM_BIT) // 15-bit command selected + #define SSI_CR1_MCOM_16BIT (0xF << SSI_CR1_MCOM_BIT) // 16-bit command selected +#define SSI_CR1_RTRG_BIT 8 +#define SSI_CR1_RTRG_MASK (0xf << SSI_CR1_RTRG_BIT) + #define SSI_CR1_RTRG_1 (0 << SSI_CR1_RTRG_BIT) + #define SSI_CR1_RTRG_8 (1 << SSI_CR1_RTRG_BIT) + #define SSI_CR1_RTRG_16 (2 << SSI_CR1_RTRG_BIT) + #define SSI_CR1_RTRG_24 (3 << SSI_CR1_RTRG_BIT) + #define SSI_CR1_RTRG_32 (4 << SSI_CR1_RTRG_BIT) + #define SSI_CR1_RTRG_40 (5 << SSI_CR1_RTRG_BIT) + #define SSI_CR1_RTRG_48 (6 << SSI_CR1_RTRG_BIT) + #define SSI_CR1_RTRG_56 (7 << SSI_CR1_RTRG_BIT) + #define SSI_CR1_RTRG_64 (8 << SSI_CR1_RTRG_BIT) + #define SSI_CR1_RTRG_72 (9 << SSI_CR1_RTRG_BIT) + #define SSI_CR1_RTRG_80 (10<< SSI_CR1_RTRG_BIT) + #define SSI_CR1_RTRG_88 (11<< SSI_CR1_RTRG_BIT) + #define SSI_CR1_RTRG_96 (12<< SSI_CR1_RTRG_BIT) + #define SSI_CR1_RTRG_104 (13<< SSI_CR1_RTRG_BIT) + #define SSI_CR1_RTRG_112 (14<< SSI_CR1_RTRG_BIT) + #define SSI_CR1_RTRG_120 (15<< SSI_CR1_RTRG_BIT) +#define SSI_CR1_FLEN_BIT 4 +#define SSI_CR1_FLEN_MASK (0xf << SSI_CR1_FLEN_BIT) + #define SSI_CR1_FLEN_2BIT (0x0 << SSI_CR1_FLEN_BIT) + #define SSI_CR1_FLEN_3BIT (0x1 << SSI_CR1_FLEN_BIT) + #define SSI_CR1_FLEN_4BIT (0x2 << SSI_CR1_FLEN_BIT) + #define SSI_CR1_FLEN_5BIT (0x3 << SSI_CR1_FLEN_BIT) + #define SSI_CR1_FLEN_6BIT (0x4 << SSI_CR1_FLEN_BIT) + #define SSI_CR1_FLEN_7BIT (0x5 << SSI_CR1_FLEN_BIT) + #define SSI_CR1_FLEN_8BIT (0x6 << SSI_CR1_FLEN_BIT) + #define SSI_CR1_FLEN_9BIT (0x7 << SSI_CR1_FLEN_BIT) + #define SSI_CR1_FLEN_10BIT (0x8 << SSI_CR1_FLEN_BIT) + #define SSI_CR1_FLEN_11BIT (0x9 << SSI_CR1_FLEN_BIT) + #define SSI_CR1_FLEN_12BIT (0xA << SSI_CR1_FLEN_BIT) + #define SSI_CR1_FLEN_13BIT (0xB << SSI_CR1_FLEN_BIT) + #define SSI_CR1_FLEN_14BIT (0xC << SSI_CR1_FLEN_BIT) + #define SSI_CR1_FLEN_15BIT (0xD << SSI_CR1_FLEN_BIT) + #define SSI_CR1_FLEN_16BIT (0xE << SSI_CR1_FLEN_BIT) + #define SSI_CR1_FLEN_17BIT (0xF << SSI_CR1_FLEN_BIT) +#define SSI_CR1_PHA (1 << 1) +#define SSI_CR1_POL (1 << 0) + +// SSI Status Register (SSI_SR) + +#define SSI_SR_TFIFONUM_BIT 16 +#define SSI_SR_TFIFONUM_MASK (0xff << SSI_SR_TFIFONUM_BIT) +#define SSI_SR_RFIFONUM_BIT 8 +#define SSI_SR_RFIFONUM_MASK (0xff << SSI_SR_RFIFONUM_BIT) +#define SSI_SR_END (1 << 7) +#define SSI_SR_BUSY (1 << 6) +#define SSI_SR_TFF (1 << 5) +#define SSI_SR_RFE (1 << 4) +#define SSI_SR_TFHE (1 << 3) +#define SSI_SR_RFHF (1 << 2) +#define SSI_SR_UNDR (1 << 1) +#define SSI_SR_OVER (1 << 0) + +// SSI Interval Time Control Register (SSI_ITR) + +#define SSI_ITR_CNTCLK (1 << 15) +#define SSI_ITR_IVLTM_BIT 0 +#define SSI_ITR_IVLTM_MASK (0x7fff << SSI_ITR_IVLTM_BIT) + + +//************************************************************************ +// MSC +//************************************************************************ +#define MSC_STRPCL REG16 (MSC_BASE + 0x000) +#define MSC_STAT REG32 (MSC_BASE + 0x004) +#define MSC_CLKRT REG16 (MSC_BASE + 0x008) +#define MSC_CMDAT REG32 (MSC_BASE + 0x00C) +#define MSC_RESTO REG16 (MSC_BASE + 0x010) +#define MSC_RDTO REG16 (MSC_BASE + 0x014) +#define MSC_BLKLEN REG16 (MSC_BASE + 0x018) +#define MSC_NOB REG16 (MSC_BASE + 0x01C) +#define MSC_SNOB REG16 (MSC_BASE + 0x020) +#define MSC_IMASK REG16 (MSC_BASE + 0x024) +#define MSC_IREG REG16 (MSC_BASE + 0x028) +#define MSC_CMD REG8 (MSC_BASE + 0x02C) +#define MSC_ARG REG32 (MSC_BASE + 0x030) +#define MSC_RES REG16 (MSC_BASE + 0x034) +#define MSC_RXFIFO REG32 (MSC_BASE + 0x038) +#define MSC_TXFIFO REG32 (MSC_BASE + 0x03C) + +// MSC Clock and Control Register (MSC_STRPCL) + +#define MSC_STRPCL_EXIT_MULTIPLE (1 << 7) +#define MSC_STRPCL_EXIT_TRANSFER (1 << 6) +#define MSC_STRPCL_START_READWAIT (1 << 5) +#define MSC_STRPCL_STOP_READWAIT (1 << 4) +#define MSC_STRPCL_RESET (1 << 3) +#define MSC_STRPCL_START_OP (1 << 2) +#define MSC_STRPCL_CLOCK_CONTROL_BIT 0 +#define MSC_STRPCL_CLOCK_CONTROL_MASK (0x3 << MSC_STRPCL_CLOCK_CONTROL_BIT) + #define MSC_STRPCL_CLOCK_CONTROL_STOP (0x1 << MSC_STRPCL_CLOCK_CONTROL_BIT) // Stop MMC/SD clock + #define MSC_STRPCL_CLOCK_CONTROL_START (0x2 << MSC_STRPCL_CLOCK_CONTROL_BIT) // Start MMC/SD clock + +// MSC Status Register (MSC_STAT) + +#define MSC_STAT_IS_RESETTING (1 << 15) +#define MSC_STAT_SDIO_INT_ACTIVE (1 << 14) +#define MSC_STAT_PRG_DONE (1 << 13) +#define MSC_STAT_DATA_TRAN_DONE (1 << 12) +#define MSC_STAT_END_CMD_RES (1 << 11) +#define MSC_STAT_DATA_FIFO_AFULL (1 << 10) +#define MSC_STAT_IS_READWAIT (1 << 9) +#define MSC_STAT_CLK_EN (1 << 8) +#define MSC_STAT_DATA_FIFO_FULL (1 << 7) +#define MSC_STAT_DATA_FIFO_EMPTY (1 << 6) +#define MSC_STAT_CRC_RES_ERR (1 << 5) +#define MSC_STAT_CRC_READ_ERROR (1 << 4) +#define MSC_STAT_CRC_WRITE_ERROR_BIT 2 +#define MSC_STAT_CRC_WRITE_ERROR_MASK (0x3 << MSC_STAT_CRC_WRITE_ERROR_BIT) + #define MSC_STAT_CRC_WRITE_ERROR_NO (0 << MSC_STAT_CRC_WRITE_ERROR_BIT) // No error on transmission of data + #define MSC_STAT_CRC_WRITE_ERROR (1 << MSC_STAT_CRC_WRITE_ERROR_BIT) // Card observed erroneous transmission of data + #define MSC_STAT_CRC_WRITE_ERROR_NOSTS (2 << MSC_STAT_CRC_WRITE_ERROR_BIT) // No CRC status is sent back +#define MSC_STAT_TIME_OUT_RES (1 << 1) +#define MSC_STAT_TIME_OUT_READ (1 << 0) + +// MSC Bus Clock Control Register (MSC_CLKRT) + +#define MSC_CLKRT_CLK_RATE_BIT 0 +#define MSC_CLKRT_CLK_RATE_MASK (0x7 << MSC_CLKRT_CLK_RATE_BIT) + #define MSC_CLKRT_CLK_RATE_DIV_1 (0x0 << MSC_CLKRT_CLK_RATE_BIT) // CLK_SRC + #define MSC_CLKRT_CLK_RATE_DIV_2 (0x1 << MSC_CLKRT_CLK_RATE_BIT) // 1/2 of CLK_SRC + #define MSC_CLKRT_CLK_RATE_DIV_4 (0x2 << MSC_CLKRT_CLK_RATE_BIT) // 1/4 of CLK_SRC + #define MSC_CLKRT_CLK_RATE_DIV_8 (0x3 << MSC_CLKRT_CLK_RATE_BIT) // 1/8 of CLK_SRC + #define MSC_CLKRT_CLK_RATE_DIV_16 (0x4 << MSC_CLKRT_CLK_RATE_BIT) // 1/16 of CLK_SRC + #define MSC_CLKRT_CLK_RATE_DIV_32 (0x5 << MSC_CLKRT_CLK_RATE_BIT) // 1/32 of CLK_SRC + #define MSC_CLKRT_CLK_RATE_DIV_64 (0x6 << MSC_CLKRT_CLK_RATE_BIT) // 1/64 of CLK_SRC + #define MSC_CLKRT_CLK_RATE_DIV_128 (0x7 << MSC_CLKRT_CLK_RATE_BIT) // 1/128 of CLK_SRC + +// MSC Command Sequence Control Register (MSC_CMDAT) + +#define MSC_CMDAT_IO_ABORT (1 << 11) +#define MSC_CMDAT_BUS_WIDTH_BIT 9 +#define MSC_CMDAT_BUS_WIDTH_MASK (0x3 << MSC_CMDAT_BUS_WIDTH_BIT) + #define MSC_CMDAT_BUS_WIDTH_1BIT (0x0 << MSC_CMDAT_BUS_WIDTH_BIT) // 1-bit data bus + #define MSC_CMDAT_BUS_WIDTH_4BIT (0x2 << MSC_CMDAT_BUS_WIDTH_BIT) // 4-bit data bus + #define CMDAT_BUS_WIDTH1 (0x0 << MSC_CMDAT_BUS_WIDTH_BIT) + #define CMDAT_BUS_WIDTH4 (0x2 << MSC_CMDAT_BUS_WIDTH_BIT) +#define MSC_CMDAT_DMA_EN (1 << 8) +#define MSC_CMDAT_INIT (1 << 7) +#define MSC_CMDAT_BUSY (1 << 6) +#define MSC_CMDAT_STREAM_BLOCK (1 << 5) +#define MSC_CMDAT_WRITE (1 << 4) +#define MSC_CMDAT_READ (0 << 4) +#define MSC_CMDAT_DATA_EN (1 << 3) +#define MSC_CMDAT_RESPONSE_BIT 0 +#define MSC_CMDAT_RESPONSE_MASK (0x7 << MSC_CMDAT_RESPONSE_BIT) + #define MSC_CMDAT_RESPONSE_NONE (0x0 << MSC_CMDAT_RESPONSE_BIT) // No response + #define MSC_CMDAT_RESPONSE_R1 (0x1 << MSC_CMDAT_RESPONSE_BIT) // Format R1 and R1b + #define MSC_CMDAT_RESPONSE_R2 (0x2 << MSC_CMDAT_RESPONSE_BIT) // Format R2 + #define MSC_CMDAT_RESPONSE_R3 (0x3 << MSC_CMDAT_RESPONSE_BIT) // Format R3 + #define MSC_CMDAT_RESPONSE_R4 (0x4 << MSC_CMDAT_RESPONSE_BIT) // Format R4 + #define MSC_CMDAT_RESPONSE_R5 (0x5 << MSC_CMDAT_RESPONSE_BIT) // Format R5 + #define MSC_CMDAT_RESPONSE_R6 (0x6 << MSC_CMDAT_RESPONSE_BIT) // Format R6 + +#define CMDAT_DMA_EN (1 << 8) +#define CMDAT_INIT (1 << 7) +#define CMDAT_BUSY (1 << 6) +#define CMDAT_STREAM (1 << 5) +#define CMDAT_WRITE (1 << 4) +#define CMDAT_DATA_EN (1 << 3) + +// MSC Interrupts Mask Register (MSC_IMASK) + +#define MSC_IMASK_SDIO (1 << 7) +#define MSC_IMASK_TXFIFO_WR_REQ (1 << 6) +#define MSC_IMASK_RXFIFO_RD_REQ (1 << 5) +#define MSC_IMASK_END_CMD_RES (1 << 2) +#define MSC_IMASK_PRG_DONE (1 << 1) +#define MSC_IMASK_DATA_TRAN_DONE (1 << 0) + + +// MSC Interrupts Status Register (MSC_IREG) + +#define MSC_IREG_SDIO (1 << 7) +#define MSC_IREG_TXFIFO_WR_REQ (1 << 6) +#define MSC_IREG_RXFIFO_RD_REQ (1 << 5) +#define MSC_IREG_END_CMD_RES (1 << 2) +#define MSC_IREG_PRG_DONE (1 << 1) +#define MSC_IREG_DATA_TRAN_DONE (1 << 0) + + +//************************************************************************ +// EMC (External Memory Controller) +//************************************************************************ +#define EMC_SMCR(n) REG32 (EMC_BASE + 0x10 + 4 * (n)) // Static Memory Control Register n (n = 0,1,2,3,4) +#define EMC_SACR(n) REG32 (EMC_BASE + 0x30 + 4 * (n)) // Static Memory Bank n Addr Config Reg (n = 0,1,2,3,4) + +#define EMC_NFCSR REG32 (EMC_BASE + 0x050) // NAND Flash Control/Status Register +#define EMC_NFECR REG32 (EMC_BASE + 0x100) // NAND Flash ECC Control Register +#define EMC_NFECC REG32 (EMC_BASE + 0x104) // NAND Flash ECC Data Register +#define EMC_NFPAR(n) REG32 (EMC_BASE + 0x108 + 4 * (n)) // NAND Flash RS Parity n Register (n = 0,1,2) +#define EMC_NFINTS REG32 (EMC_BASE + 0x114) // NAND Flash Interrupt Status Register +#define EMC_NFINTE REG32 (EMC_BASE + 0x118) // NAND Flash Interrupt Enable Register +#define EMC_NFERR(n) REG32 (EMC_BASE + 0x11c + 4 * (n)) // NAND Flash RS Error Report n Register (n = 0,1,2,3) + +#define EMC_DMCR REG32 (EMC_BASE + 0x80) // DRAM Control Register +#define EMC_RTCSR REG16 (EMC_BASE + 0x84) // Refresh Time Control/Status Register +#define EMC_RTCNT REG16 (EMC_BASE + 0x88) // Refresh Timer Counter +#define EMC_RTCOR REG16 (EMC_BASE + 0x8c) // Refresh Time Constant Register +#define EMC_DMAR0 REG32 (EMC_BASE + 0x90) // SDRAM Bank 0 Addr Config Register +#define EMC_SDMR0 (EMC_BASE + 0xa000) // Mode Register of SDRAM bank 0. Very weird: uses address bus for data. Data bus is ignored, thus no REG +#define EMC_BCR REG32 (EMC_BASE + 0x00) // Bus Control Register + +// Static Memory Control Register +#define EMC_SMCR_STRV_BIT 24 +#define EMC_SMCR_STRV_MASK (0x0f << EMC_SMCR_STRV_BIT) +#define EMC_SMCR_TAW_BIT 20 +#define EMC_SMCR_TAW_MASK (0x0f << EMC_SMCR_TAW_BIT) +#define EMC_SMCR_TBP_BIT 16 +#define EMC_SMCR_TBP_MASK (0x0f << EMC_SMCR_TBP_BIT) +#define EMC_SMCR_TAH_BIT 12 +#define EMC_SMCR_TAH_MASK (0x07 << EMC_SMCR_TAH_BIT) +#define EMC_SMCR_TAS_BIT 8 +#define EMC_SMCR_TAS_MASK (0x07 << EMC_SMCR_TAS_BIT) +#define EMC_SMCR_BW_BIT 6 +#define EMC_SMCR_BW_MASK (0x03 << EMC_SMCR_BW_BIT) + #define EMC_SMCR_BW_8BIT (0 << EMC_SMCR_BW_BIT) + #define EMC_SMCR_BW_16BIT (1 << EMC_SMCR_BW_BIT) + #define EMC_SMCR_BW_32BIT (2 << EMC_SMCR_BW_BIT) +#define EMC_SMCR_BCM (1 << 3) +#define EMC_SMCR_BL_BIT 1 +#define EMC_SMCR_BL_MASK (0x03 << EMC_SMCR_BL_BIT) + #define EMC_SMCR_BL_4 (0 << EMC_SMCR_BL_BIT) + #define EMC_SMCR_BL_8 (1 << EMC_SMCR_BL_BIT) + #define EMC_SMCR_BL_16 (2 << EMC_SMCR_BL_BIT) + #define EMC_SMCR_BL_32 (3 << EMC_SMCR_BL_BIT) +#define EMC_SMCR_SMT (1 << 0) + +// Static Memory Bank Addr Config Reg +#define EMC_SACR_BASE_BIT 8 +#define EMC_SACR_BASE_MASK (0xff << EMC_SACR_BASE_BIT) +#define EMC_SACR_MASK_BIT 0 +#define EMC_SACR_MASK_MASK (0xff << EMC_SACR_MASK_BIT) + +// NAND Flash Control/Status Register +#define EMC_NFCSR_NFCE4 (1 << 7) // NAND Flash Enable +#define EMC_NFCSR_NFE4 (1 << 6) // NAND Flash FCE# Assertion Enable +#define EMC_NFCSR_NFCE3 (1 << 5) +#define EMC_NFCSR_NFE3 (1 << 4) +#define EMC_NFCSR_NFCE2 (1 << 3) +#define EMC_NFCSR_NFE2 (1 << 2) +#define EMC_NFCSR_NFCE1 (1 << 1) +#define EMC_NFCSR_NFE1 (1 << 0) + +// NAND Flash ECC Control Register +#define EMC_NFECR_PRDY (1 << 4) // Parity Ready +#define EMC_NFECR_RS_DECODING (0 << 3) // RS is in decoding phase +#define EMC_NFECR_RS_ENCODING (1 << 3) // RS is in encoding phase +#define EMC_NFECR_HAMMING (0 << 2) // Select HAMMING Correction Algorithm +#define EMC_NFECR_RS (1 << 2) // Select RS Correction Algorithm +#define EMC_NFECR_ERST (1 << 1) // ECC Reset +#define EMC_NFECR_ECCE (1 << 0) // ECC Enable + +// NAND Flash ECC Data Register +#define EMC_NFECC_ECC2_BIT 16 +#define EMC_NFECC_ECC2_MASK (0xff << EMC_NFECC_ECC2_BIT) +#define EMC_NFECC_ECC1_BIT 8 +#define EMC_NFECC_ECC1_MASK (0xff << EMC_NFECC_ECC1_BIT) +#define EMC_NFECC_ECC0_BIT 0 +#define EMC_NFECC_ECC0_MASK (0xff << EMC_NFECC_ECC0_BIT) + +// NAND Flash Interrupt Status Register +#define EMC_NFINTS_ERRCNT_BIT 29 // Error Count +#define EMC_NFINTS_ERRCNT_MASK (0x7 << EMC_NFINTS_ERRCNT_BIT) +#define EMC_NFINTS_PADF (1 << 4) // Padding Finished +#define EMC_NFINTS_DECF (1 << 3) // Decoding Finished +#define EMC_NFINTS_ENCF (1 << 2) // Encoding Finished +#define EMC_NFINTS_UNCOR (1 << 1) // Uncorrectable Error Occurred +#define EMC_NFINTS_ERR (1 << 0) // Error Occurred + +// NAND Flash Interrupt Enable Register +#define EMC_NFINTE_PADFE (1 << 4) // Padding Finished Interrupt Enable +#define EMC_NFINTE_DECFE (1 << 3) // Decoding Finished Interrupt Enable +#define EMC_NFINTE_ENCFE (1 << 2) // Encoding Finished Interrupt Enable +#define EMC_NFINTE_UNCORE (1 << 1) // Uncorrectable Error Occurred Intr Enable +#define EMC_NFINTE_ERRE (1 << 0) // Error Occurred Interrupt + +// NAND Flash RS Error Report Register +#define EMC_NFERR_INDEX_BIT 16 // Error Symbol Index +#define EMC_NFERR_INDEX_MASK (0x1ff << EMC_NFERR_INDEX_BIT) +#define EMC_NFERR_MASK_BIT 0 // Error Symbol Value +#define EMC_NFERR_MASK_MASK (0x1ff << EMC_NFERR_MASK_BIT) + + +// DRAM Control Register +#define EMC_DMCR_BW_BIT 31 +#define EMC_DMCR_BW (1 << EMC_DMCR_BW_BIT) +#define EMC_DMCR_CA_BIT 26 +#define EMC_DMCR_CA_MASK (0x07 << EMC_DMCR_CA_BIT) + #define EMC_DMCR_CA_8 (0 << EMC_DMCR_CA_BIT) + #define EMC_DMCR_CA_9 (1 << EMC_DMCR_CA_BIT) + #define EMC_DMCR_CA_10 (2 << EMC_DMCR_CA_BIT) + #define EMC_DMCR_CA_11 (3 << EMC_DMCR_CA_BIT) + #define EMC_DMCR_CA_12 (4 << EMC_DMCR_CA_BIT) +#define EMC_DMCR_RMODE (1 << 25) +#define EMC_DMCR_RFSH (1 << 24) +#define EMC_DMCR_MRSET (1 << 23) +#define EMC_DMCR_RA_BIT 20 +#define EMC_DMCR_RA_MASK (0x03 << EMC_DMCR_RA_BIT) + #define EMC_DMCR_RA_11 (0 << EMC_DMCR_RA_BIT) + #define EMC_DMCR_RA_12 (1 << EMC_DMCR_RA_BIT) + #define EMC_DMCR_RA_13 (2 << EMC_DMCR_RA_BIT) +#define EMC_DMCR_BA_BIT 19 +#define EMC_DMCR_BA (1 << EMC_DMCR_BA_BIT) +#define EMC_DMCR_PDM (1 << 18) +#define EMC_DMCR_EPIN (1 << 17) +#define EMC_DMCR_TRAS_BIT 13 +#define EMC_DMCR_TRAS_MASK (0x07 << EMC_DMCR_TRAS_BIT) +#define EMC_DMCR_RCD_BIT 11 +#define EMC_DMCR_RCD_MASK (0x03 << EMC_DMCR_RCD_BIT) +#define EMC_DMCR_TPC_BIT 8 +#define EMC_DMCR_TPC_MASK (0x07 << EMC_DMCR_TPC_BIT) +#define EMC_DMCR_TRWL_BIT 5 +#define EMC_DMCR_TRWL_MASK (0x03 << EMC_DMCR_TRWL_BIT) +#define EMC_DMCR_TRC_BIT 2 +#define EMC_DMCR_TRC_MASK (0x07 << EMC_DMCR_TRC_BIT) +#define EMC_DMCR_TCL_BIT 0 +#define EMC_DMCR_TCL_MASK (0x03 << EMC_DMCR_TCL_BIT) + +// Refresh Time Control/Status Register +#define EMC_RTCSR_CMF (1 << 7) +#define EMC_RTCSR_CKS_BIT 0 +#define EMC_RTCSR_CKS_MASK (0x07 << EMC_RTCSR_CKS_BIT) + #define EMC_RTCSR_CKS_DISABLE (0 << EMC_RTCSR_CKS_BIT) + #define EMC_RTCSR_CKS_4 (1 << EMC_RTCSR_CKS_BIT) + #define EMC_RTCSR_CKS_16 (2 << EMC_RTCSR_CKS_BIT) + #define EMC_RTCSR_CKS_64 (3 << EMC_RTCSR_CKS_BIT) + #define EMC_RTCSR_CKS_256 (4 << EMC_RTCSR_CKS_BIT) + #define EMC_RTCSR_CKS_1024 (5 << EMC_RTCSR_CKS_BIT) + #define EMC_RTCSR_CKS_2048 (6 << EMC_RTCSR_CKS_BIT) + #define EMC_RTCSR_CKS_4096 (7 << EMC_RTCSR_CKS_BIT) + +// SDRAM Bank Address Configuration Register +#define EMC_DMAR_BASE_BIT 8 +#define EMC_DMAR_BASE_MASK (0xff << EMC_DMAR_BASE_BIT) +#define EMC_DMAR_MASK_BIT 0 +#define EMC_DMAR_MASK_MASK (0xff << EMC_DMAR_MASK_BIT) + +// Mode Register of SDRAM bank 0 +#define EMC_SDMR_BM (1 << 9) // Write Burst Mode +#define EMC_SDMR_OM_BIT 7 // Operating Mode +#define EMC_SDMR_OM_MASK (3 << EMC_SDMR_OM_BIT) + #define EMC_SDMR_OM_NORMAL (0 << EMC_SDMR_OM_BIT) +#define EMC_SDMR_CAS_BIT 4 // CAS Latency +#define EMC_SDMR_CAS_MASK (7 << EMC_SDMR_CAS_BIT) + #define EMC_SDMR_CAS_1 (1 << EMC_SDMR_CAS_BIT) + #define EMC_SDMR_CAS_2 (2 << EMC_SDMR_CAS_BIT) + #define EMC_SDMR_CAS_3 (3 << EMC_SDMR_CAS_BIT) +#define EMC_SDMR_BT_BIT 3 // Burst Type +#define EMC_SDMR_BT_MASK (1 << EMC_SDMR_BT_BIT) + #define EMC_SDMR_BT_SEQ (0 << EMC_SDMR_BT_BIT) // Sequential + #define EMC_SDMR_BT_INT (1 << EMC_SDMR_BT_BIT) // Interleave +#define EMC_SDMR_BL_BIT 0 // Burst Length +#define EMC_SDMR_BL_MASK (7 << EMC_SDMR_BL_BIT) + #define EMC_SDMR_BL_1 (0 << EMC_SDMR_BL_BIT) + #define EMC_SDMR_BL_2 (1 << EMC_SDMR_BL_BIT) + #define EMC_SDMR_BL_4 (2 << EMC_SDMR_BL_BIT) + #define EMC_SDMR_BL_8 (3 << EMC_SDMR_BL_BIT) + +#define EMC_SDMR_CAS2_16BIT (EMC_SDMR_CAS_2 | EMC_SDMR_BT_SEQ | EMC_SDMR_BL_2) +#define EMC_SDMR_CAS2_32BIT (EMC_SDMR_CAS_2 | EMC_SDMR_BT_SEQ | EMC_SDMR_BL_4) +#define EMC_SDMR_CAS3_16BIT (EMC_SDMR_CAS_3 | EMC_SDMR_BT_SEQ | EMC_SDMR_BL_2) +#define EMC_SDMR_CAS3_32BIT (EMC_SDMR_CAS_3 | EMC_SDMR_BT_SEQ | EMC_SDMR_BL_4) + + +//************************************************************************ +// CIM +//************************************************************************ +#define CIM_CFG REG32 (CIM_BASE + 0x0000) +#define CIM_CTRL REG32 (CIM_BASE + 0x0004) +#define CIM_STATE REG32 (CIM_BASE + 0x0008) +#define CIM_IID REG32 (CIM_BASE + 0x000C) +#define CIM_RXFIFO REG32 (CIM_BASE + 0x0010) +#define CIM_DA REG32 (CIM_BASE + 0x0020) +#define CIM_FA REG32 (CIM_BASE + 0x0024) +#define CIM_FID REG32 (CIM_BASE + 0x0028) +#define CIM_CMD REG32 (CIM_BASE + 0x002C) + +// CIM Configuration Register (CIM_CFG) + +#define CIM_CFG_INV_DAT (1 << 15) +#define CIM_CFG_VSP (1 << 14) +#define CIM_CFG_HSP (1 << 13) +#define CIM_CFG_PCP (1 << 12) +#define CIM_CFG_DUMMY_ZERO (1 << 9) +#define CIM_CFG_EXT_VSYNC (1 << 8) +#define CIM_CFG_PACK_BIT 4 +#define CIM_CFG_PACK_MASK (0x7 << CIM_CFG_PACK_BIT) + #define CIM_CFG_PACK_0 (0 << CIM_CFG_PACK_BIT) + #define CIM_CFG_PACK_1 (1 << CIM_CFG_PACK_BIT) + #define CIM_CFG_PACK_2 (2 << CIM_CFG_PACK_BIT) + #define CIM_CFG_PACK_3 (3 << CIM_CFG_PACK_BIT) + #define CIM_CFG_PACK_4 (4 << CIM_CFG_PACK_BIT) + #define CIM_CFG_PACK_5 (5 << CIM_CFG_PACK_BIT) + #define CIM_CFG_PACK_6 (6 << CIM_CFG_PACK_BIT) + #define CIM_CFG_PACK_7 (7 << CIM_CFG_PACK_BIT) +#define CIM_CFG_DSM_BIT 0 +#define CIM_CFG_DSM_MASK (0x3 << CIM_CFG_DSM_BIT) + #define CIM_CFG_DSM_CPM (0 << CIM_CFG_DSM_BIT) // CCIR656 Progressive Mode + #define CIM_CFG_DSM_CIM (1 << CIM_CFG_DSM_BIT) // CCIR656 Interlace Mode + #define CIM_CFG_DSM_GCM (2 << CIM_CFG_DSM_BIT) // Gated Clock Mode + #define CIM_CFG_DSM_NGCM (3 << CIM_CFG_DSM_BIT) // Non-Gated Clock Mode + +// CIM Control Register (CIM_CTRL) + +#define CIM_CTRL_MCLKDIV_BIT 24 +#define CIM_CTRL_MCLKDIV_MASK (0xff << CIM_CTRL_MCLKDIV_BIT) +#define CIM_CTRL_FRC_BIT 16 +#define CIM_CTRL_FRC_MASK (0xf << CIM_CTRL_FRC_BIT) + #define CIM_CTRL_FRC_1 (0x0 << CIM_CTRL_FRC_BIT) // Sample every frame + #define CIM_CTRL_FRC_2 (0x1 << CIM_CTRL_FRC_BIT) // Sample 1/2 frame + #define CIM_CTRL_FRC_3 (0x2 << CIM_CTRL_FRC_BIT) // Sample 1/3 frame + #define CIM_CTRL_FRC_4 (0x3 << CIM_CTRL_FRC_BIT) // Sample 1/4 frame + #define CIM_CTRL_FRC_5 (0x4 << CIM_CTRL_FRC_BIT) // Sample 1/5 frame + #define CIM_CTRL_FRC_6 (0x5 << CIM_CTRL_FRC_BIT) // Sample 1/6 frame + #define CIM_CTRL_FRC_7 (0x6 << CIM_CTRL_FRC_BIT) // Sample 1/7 frame + #define CIM_CTRL_FRC_8 (0x7 << CIM_CTRL_FRC_BIT) // Sample 1/8 frame + #define CIM_CTRL_FRC_9 (0x8 << CIM_CTRL_FRC_BIT) // Sample 1/9 frame + #define CIM_CTRL_FRC_10 (0x9 << CIM_CTRL_FRC_BIT) // Sample 1/10 frame + #define CIM_CTRL_FRC_11 (0xA << CIM_CTRL_FRC_BIT) // Sample 1/11 frame + #define CIM_CTRL_FRC_12 (0xB << CIM_CTRL_FRC_BIT) // Sample 1/12 frame + #define CIM_CTRL_FRC_13 (0xC << CIM_CTRL_FRC_BIT) // Sample 1/13 frame + #define CIM_CTRL_FRC_14 (0xD << CIM_CTRL_FRC_BIT) // Sample 1/14 frame + #define CIM_CTRL_FRC_15 (0xE << CIM_CTRL_FRC_BIT) // Sample 1/15 frame + #define CIM_CTRL_FRC_16 (0xF << CIM_CTRL_FRC_BIT) // Sample 1/16 frame +#define CIM_CTRL_VDDM (1 << 13) +#define CIM_CTRL_DMA_SOFM (1 << 12) +#define CIM_CTRL_DMA_EOFM (1 << 11) +#define CIM_CTRL_DMA_STOPM (1 << 10) +#define CIM_CTRL_RXF_TRIGM (1 << 9) +#define CIM_CTRL_RXF_OFM (1 << 8) +#define CIM_CTRL_RXF_TRIG_BIT 4 +#define CIM_CTRL_RXF_TRIG_MASK (0x7 << CIM_CTRL_RXF_TRIG_BIT) + #define CIM_CTRL_RXF_TRIG_4 (0 << CIM_CTRL_RXF_TRIG_BIT) // RXFIFO Trigger Value is 4 + #define CIM_CTRL_RXF_TRIG_8 (1 << CIM_CTRL_RXF_TRIG_BIT) // RXFIFO Trigger Value is 8 + #define CIM_CTRL_RXF_TRIG_12 (2 << CIM_CTRL_RXF_TRIG_BIT) // RXFIFO Trigger Value is 12 + #define CIM_CTRL_RXF_TRIG_16 (3 << CIM_CTRL_RXF_TRIG_BIT) // RXFIFO Trigger Value is 16 + #define CIM_CTRL_RXF_TRIG_20 (4 << CIM_CTRL_RXF_TRIG_BIT) // RXFIFO Trigger Value is 20 + #define CIM_CTRL_RXF_TRIG_24 (5 << CIM_CTRL_RXF_TRIG_BIT) // RXFIFO Trigger Value is 24 + #define CIM_CTRL_RXF_TRIG_28 (6 << CIM_CTRL_RXF_TRIG_BIT) // RXFIFO Trigger Value is 28 + #define CIM_CTRL_RXF_TRIG_32 (7 << CIM_CTRL_RXF_TRIG_BIT) // RXFIFO Trigger Value is 32 +#define CIM_CTRL_DMA_EN (1 << 2) +#define CIM_CTRL_RXF_RST (1 << 1) +#define CIM_CTRL_ENA (1 << 0) + +// CIM State Register (CIM_STATE) + +#define CIM_STATE_DMA_SOF (1 << 6) +#define CIM_STATE_DMA_EOF (1 << 5) +#define CIM_STATE_DMA_STOP (1 << 4) +#define CIM_STATE_RXF_OF (1 << 3) +#define CIM_STATE_RXF_TRIG (1 << 2) +#define CIM_STATE_RXF_EMPTY (1 << 1) +#define CIM_STATE_VDD (1 << 0) + +// CIM DMA Command Register (CIM_CMD) + +#define CIM_CMD_SOFINT (1 << 31) +#define CIM_CMD_EOFINT (1 << 30) +#define CIM_CMD_STOP (1 << 28) +#define CIM_CMD_LEN_BIT 0 +#define CIM_CMD_LEN_MASK (0xffffff << CIM_CMD_LEN_BIT) + + +//************************************************************************ +// SADC (Smart A/D Controller) +//************************************************************************ + +#define SADC_ENA REG8 (SADC_BASE + 0x00) // ADC Enable Register +#define SADC_CFG REG32 (SADC_BASE + 0x04) // ADC Configure Register +#define SADC_CTRL REG8 (SADC_BASE + 0x08) // ADC Control Register +#define SADC_STATE REG8 (SADC_BASE + 0x0C) // ADC Status Register*/ +#define SADC_SAMETIME REG16 (SADC_BASE + 0x10) // ADC Same Point Time Register +#define SADC_WAITTIME REG16 (SADC_BASE + 0x14) // ADC Wait Time Register +#define SADC_TSDAT REG32 (SADC_BASE + 0x18) // ADC Touch Screen Data Register +#define SADC_BATDAT REG16 (SADC_BASE + 0x1C) // ADC PBAT Data Register +#define SADC_SADDAT REG16 (SADC_BASE + 0x20) // ADC SADCIN Data Register + +// ADC Enable Register +#define SADC_ENA_ADEN (1 << 7) // Touch Screen Enable +#define SADC_ENA_TSEN (1 << 2) // Touch Screen Enable +#define SADC_ENA_PBATEN (1 << 1) // PBAT Enable +#define SADC_ENA_SADCINEN (1 << 0) // SADCIN Enable + +// ADC Configure Register +#define SADC_CFG_EXIN (1 << 30) +#define SADC_CFG_CLKOUT_NUM_BIT 16 +#define SADC_CFG_CLKOUT_NUM_MASK (0x7 << SADC_CFG_CLKOUT_NUM_BIT) +#define SADC_CFG_TS_DMA (1 << 15) // Touch Screen DMA Enable +#define SADC_CFG_XYZ_BIT 13 // XYZ selection +#define SADC_CFG_XYZ_MASK (0x3 << SADC_CFG_XYZ_BIT) + #define SADC_CFG_XY (0 << SADC_CFG_XYZ_BIT) + #define SADC_CFG_XYZ (1 << SADC_CFG_XYZ_BIT) + #define SADC_CFG_XYZ1Z2 (2 << SADC_CFG_XYZ_BIT) +#define SADC_CFG_SNUM_BIT 10 // Sample Number +#define SADC_CFG_SNUM_MASK (0x7 << SADC_CFG_SNUM_BIT) + #define SADC_CFG_SNUM_1 (0x0 << SADC_CFG_SNUM_BIT) + #define SADC_CFG_SNUM_2 (0x1 << SADC_CFG_SNUM_BIT) + #define SADC_CFG_SNUM_3 (0x2 << SADC_CFG_SNUM_BIT) + #define SADC_CFG_SNUM_4 (0x3 << SADC_CFG_SNUM_BIT) + #define SADC_CFG_SNUM_5 (0x4 << SADC_CFG_SNUM_BIT) + #define SADC_CFG_SNUM_6 (0x5 << SADC_CFG_SNUM_BIT) + #define SADC_CFG_SNUM_8 (0x6 << SADC_CFG_SNUM_BIT) + #define SADC_CFG_SNUM_9 (0x7 << SADC_CFG_SNUM_BIT) +#define SADC_CFG_CLKDIV_BIT 5 // AD Converter frequency clock divider +#define SADC_CFG_CLKDIV_MASK (0x1f << SADC_CFG_CLKDIV_BIT) +#define SADC_CFG_PBAT_HIGH (0 << 4) // PBAT >= 2.5V +#define SADC_CFG_PBAT_LOW (1 << 4) // PBAT < 2.5V +#define SADC_CFG_CMD_BIT 0 // ADC Command +#define SADC_CFG_CMD_MASK (0xf << SADC_CFG_CMD_BIT) + #define SADC_CFG_CMD_X_SE (0x0 << SADC_CFG_CMD_BIT) // X Single-End + #define SADC_CFG_CMD_Y_SE (0x1 << SADC_CFG_CMD_BIT) // Y Single-End + #define SADC_CFG_CMD_X_DIFF (0x2 << SADC_CFG_CMD_BIT) // X Differential + #define SADC_CFG_CMD_Y_DIFF (0x3 << SADC_CFG_CMD_BIT) // Y Differential + #define SADC_CFG_CMD_Z1_DIFF (0x4 << SADC_CFG_CMD_BIT) // Z1 Differential + #define SADC_CFG_CMD_Z2_DIFF (0x5 << SADC_CFG_CMD_BIT) // Z2 Differential + #define SADC_CFG_CMD_Z3_DIFF (0x6 << SADC_CFG_CMD_BIT) // Z3 Differential + #define SADC_CFG_CMD_Z4_DIFF (0x7 << SADC_CFG_CMD_BIT) // Z4 Differential + #define SADC_CFG_CMD_TP_SE (0x8 << SADC_CFG_CMD_BIT) // Touch Pressure + #define SADC_CFG_CMD_PBATH_SE (0x9 << SADC_CFG_CMD_BIT) // PBAT >= 2.5V + #define SADC_CFG_CMD_PBATL_SE (0xa << SADC_CFG_CMD_BIT) // PBAT < 2.5V + #define SADC_CFG_CMD_SADCIN_SE (0xb << SADC_CFG_CMD_BIT) // Measure SADCIN + #define SADC_CFG_CMD_INT_PEN (0xc << SADC_CFG_CMD_BIT) // INT_PEN Enable + +// ADC Control Register +#define SADC_CTRL_PENDM (1 << 4) // Pen Down Interrupt Mask +#define SADC_CTRL_PENUM (1 << 3) // Pen Up Interrupt Mask +#define SADC_CTRL_TSRDYM (1 << 2) // Touch Screen Data Ready Interrupt Mask +#define SADC_CTRL_PBATRDYM (1 << 1) // PBAT Data Ready Interrupt Mask +#define SADC_CTRL_SRDYM (1 << 0) // SADCIN Data Ready Interrupt Mask + +// ADC Status Register +#define SADC_STATE_TSBUSY (1 << 7) // TS A/D is working +#define SADC_STATE_PBATBUSY (1 << 6) // PBAT A/D is working +#define SADC_STATE_SBUSY (1 << 5) // SADCIN A/D is working +#define SADC_STATE_PEND (1 << 4) // Pen Down Interrupt Flag +#define SADC_STATE_PENU (1 << 3) // Pen Up Interrupt Flag +#define SADC_STATE_TSRDY (1 << 2) // Touch Screen Data Ready Interrupt Flag +#define SADC_STATE_PBATRDY (1 << 1) // PBAT Data Ready Interrupt Flag +#define SADC_STATE_SRDY (1 << 0) // SADCIN Data Ready Interrupt Flag + +// ADC Touch Screen Data Register +#define SADC_TSDAT_DATA0_BIT 0 +#define SADC_TSDAT_DATA0_MASK (0xfff << SADC_TSDAT_DATA0_BIT) +#define SADC_TSDAT_TYPE0 (1 << 15) +#define SADC_TSDAT_DATA1_BIT 16 +#define SADC_TSDAT_DATA1_MASK (0xfff << SADC_TSDAT_DATA1_BIT) +#define SADC_TSDAT_TYPE1 (1 << 31) + + +//************************************************************************ +// SLCD (Smart LCD Controller) +//************************************************************************ + +#define SLCD_CFG REG32 (SLCD_BASE + 0xA0) // SLCD Configure Register +#define SLCD_CTRL REG8 (SLCD_BASE + 0xA4) // SLCD Control Register +#define SLCD_STATE REG8 (SLCD_BASE + 0xA8) // SLCD Status Register +#define SLCD_DATA REG32 (SLCD_BASE + 0xAC) // SLCD Data Register +#define SLCD_FIFO REG32 (SLCD_BASE + 0xB0) // SLCD FIFO Register + +// SLCD Configure Register +#define SLCD_CFG_BURST_BIT 14 +#define SLCD_CFG_BURST_MASK (0x3 << SLCD_CFG_BURST_BIT) + #define SLCD_CFG_BURST_4_WORD (0 << SLCD_CFG_BURST_BIT) + #define SLCD_CFG_BURST_8_WORD (1 << SLCD_CFG_BURST_BIT) +#define SLCD_CFG_DWIDTH_BIT 10 +#define SLCD_CFG_DWIDTH_MASK (0x7 << SLCD_CFG_DWIDTH_BIT) + #define SLCD_CFG_DWIDTH_18 (0 << SLCD_CFG_DWIDTH_BIT) + #define SLCD_CFG_DWIDTH_16 (1 << SLCD_CFG_DWIDTH_BIT) + #define SLCD_CFG_DWIDTH_8_x3 (2 << SLCD_CFG_DWIDTH_BIT) + #define SLCD_CFG_DWIDTH_8_x2 (3 << SLCD_CFG_DWIDTH_BIT) + #define SLCD_CFG_DWIDTH_9_x2 (4 << SLCD_CFG_DWIDTH_BIT) +#define SLCD_CFG_CWIDTH_16BIT (0 << 8) +#define SLCD_CFG_CWIDTH_8BIT (1 << 8) +#define SLCD_CFG_CS_ACTIVE_LOW (0 << 4) +#define SLCD_CFG_CS_ACTIVE_HIGH (1 << 4) +#define SLCD_CFG_RS_CMD_LOW (0 << 3) +#define SLCD_CFG_RS_CMD_HIGH (1 << 3) +#define SLCD_CFG_CLK_ACTIVE_FALLING (0 << 1) +#define SLCD_CFG_CLK_ACTIVE_RISING (1 << 1) +#define SLCD_CFG_TYPE_PARALLEL (0 << 0) +#define SLCD_CFG_TYPE_SERIAL (1 << 0) + +// SLCD Control Register +#define SLCD_CTRL_DMA_EN (1 << 0) + +// SLCD Status Register +#define SLCD_STATE_BUSY (1 << 0) + +// SLCD Data Register +#define SLCD_DATA_RS_DATA (0 << 31) +#define SLCD_DATA_RS_COMMAND (1 << 31) + +// SLCD FIFO Register +#define SLCD_FIFO_RS_DATA (0 << 31) +#define SLCD_FIFO_RS_COMMAND (1 << 31) + + +//************************************************************************ +// LCD (LCD Controller) +//************************************************************************ +#define LCD_CFG REG32 (LCD_BASE + 0x00) // LCD Configure Register +#define LCD_VSYNC REG32 (LCD_BASE + 0x04) // Vertical Synchronize Register +#define LCD_HSYNC REG32 (LCD_BASE + 0x08) // Horizontal Synchronize Register +#define LCD_VAT REG32 (LCD_BASE + 0x0c) // Virtual Area Setting Register +#define LCD_DAH REG32 (LCD_BASE + 0x10) // Display Area Horizontal Start/End Point +#define LCD_DAV REG32 (LCD_BASE + 0x14) // Display Area Vertical Start/End Point +#define LCD_PS REG32 (LCD_BASE + 0x18) // PS Signal Setting +#define LCD_CLS REG32 (LCD_BASE + 0x1c) // CLS Signal Setting +#define LCD_SPL REG32 (LCD_BASE + 0x20) // SPL Signal Setting +#define LCD_REV REG32 (LCD_BASE + 0x24) // REV Signal Setting +#define LCD_CTRL REG32 (LCD_BASE + 0x30) // LCD Control Register +#define LCD_STATE REG32 (LCD_BASE + 0x34) // LCD Status Register +#define LCD_IID REG32 (LCD_BASE + 0x38) // Interrupt ID Register +#define LCD_DA0 REG32 (LCD_BASE + 0x40) // Descriptor Address Register 0 +#define LCD_SA0 REG32 (LCD_BASE + 0x44) // Source Address Register 0 +#define LCD_FID0 REG32 (LCD_BASE + 0x48) // Frame ID Register 0 +#define LCD_CMD0 REG32 (LCD_BASE + 0x4c) // DMA Command Register 0 +#define LCD_DA1 REG32 (LCD_BASE + 0x50) // Descriptor Address Register 1 +#define LCD_SA1 REG32 (LCD_BASE + 0x54) // Source Address Register 1 +#define LCD_FID1 REG32 (LCD_BASE + 0x58) // Frame ID Register 1 +#define LCD_CMD1 REG32 (LCD_BASE + 0x5c) // DMA Command Register 1 + +// LCD Configure Register +#define LCD_CFG_LCDPIN_BIT 31 // LCD pins selection +#define LCD_CFG_LCDPIN_MASK (0x1 << LCD_CFG_LCDPIN_BIT) + #define LCD_CFG_LCDPIN_LCD (0x0 << LCD_CFG_LCDPIN_BIT) + #define LCD_CFG_LCDPIN_SLCD (0x1 << LCD_CFG_LCDPIN_BIT) +#define LCD_CFG_PSM (1 << 23) // PS signal mode +#define LCD_CFG_CLSM (1 << 22) // CLS signal mode +#define LCD_CFG_SPLM (1 << 21) // SPL signal mode +#define LCD_CFG_REVM (1 << 20) // REV signal mode +#define LCD_CFG_HSYNM (1 << 19) // HSYNC signal mode +#define LCD_CFG_PCLKM (1 << 18) // PCLK signal mode +#define LCD_CFG_INVDAT (1 << 17) // Inverse output data +#define LCD_CFG_SYNDIR_IN (1 << 16) // VSYNC&HSYNC direction +#define LCD_CFG_PSP (1 << 15) // PS pin reset state +#define LCD_CFG_CLSP (1 << 14) // CLS pin reset state +#define LCD_CFG_SPLP (1 << 13) // SPL pin reset state +#define LCD_CFG_REVP (1 << 12) // REV pin reset state +#define LCD_CFG_HSP (1 << 11) // HSYNC pority:0-active high,1-active low +#define LCD_CFG_PCP (1 << 10) // PCLK pority:0-rising,1-falling +#define LCD_CFG_DEP (1 << 9) // DE pority:0-active high,1-active low +#define LCD_CFG_VSP (1 << 8) // VSYNC pority:0-rising,1-falling +#define LCD_CFG_PDW_BIT 4 // STN pins utilization +#define LCD_CFG_PDW_MASK (0x3 << LCD_DEV_PDW_BIT) +#define LCD_CFG_PDW_1 (0 << LCD_CFG_PDW_BIT) // LCD_D[0] + #define LCD_CFG_PDW_2 (1 << LCD_CFG_PDW_BIT) // LCD_D[0:1] + #define LCD_CFG_PDW_4 (2 << LCD_CFG_PDW_BIT) // LCD_D[0:3]/LCD_D[8:11] + #define LCD_CFG_PDW_8 (3 << LCD_CFG_PDW_BIT) // LCD_D[0:7]/LCD_D[8:15] +#define LCD_CFG_MODE_BIT 0 // Display Device Mode Select +#define LCD_CFG_MODE_MASK (0x0f << LCD_CFG_MODE_BIT) + #define LCD_CFG_MODE_GENERIC_TFT (0 << LCD_CFG_MODE_BIT) // 16,18 bit TFT + #define LCD_CFG_MODE_SPECIAL_TFT_1 (1 << LCD_CFG_MODE_BIT) + #define LCD_CFG_MODE_SPECIAL_TFT_2 (2 << LCD_CFG_MODE_BIT) + #define LCD_CFG_MODE_SPECIAL_TFT_3 (3 << LCD_CFG_MODE_BIT) + #define LCD_CFG_MODE_NONINTER_CCIR656 (4 << LCD_CFG_MODE_BIT) + #define LCD_CFG_MODE_INTER_CCIR656 (5 << LCD_CFG_MODE_BIT) + #define LCD_CFG_MODE_SINGLE_CSTN (8 << LCD_CFG_MODE_BIT) + #define LCD_CFG_MODE_SINGLE_MSTN (9 << LCD_CFG_MODE_BIT) + #define LCD_CFG_MODE_DUAL_CSTN (10 << LCD_CFG_MODE_BIT) + #define LCD_CFG_MODE_DUAL_MSTN (11 << LCD_CFG_MODE_BIT) + #define LCD_CFG_MODE_SERIAL_TFT (12 << LCD_CFG_MODE_BIT) + #define LCD_CFG_MODE_GENERIC_18BIT_TFT (13 << LCD_CFG_MODE_BIT) + // JZ47XX defines + #define LCD_CFG_MODE_SHARP_HR (1 << LCD_CFG_MODE_BIT) + #define LCD_CFG_MODE_CASIO_TFT (2 << LCD_CFG_MODE_BIT) + #define LCD_CFG_MODE_SAMSUNG_ALPHA (3 << LCD_CFG_MODE_BIT) + + + +// Vertical Synchronize Register +#define LCD_VSYNC_VPS_BIT 16 // VSYNC pulse start in line clock, fixed to 0 +#define LCD_VSYNC_VPS_MASK (0xffff << LCD_VSYNC_VPS_BIT) +#define LCD_VSYNC_VPE_BIT 0 // VSYNC pulse end in line clock +#define LCD_VSYNC_VPE_MASK (0xffff << LCD_VSYNC_VPS_BIT) + +// Horizontal Synchronize Register +#define LCD_HSYNC_HPS_BIT 16 // HSYNC pulse start position in dot clock +#define LCD_HSYNC_HPS_MASK (0xffff << LCD_HSYNC_HPS_BIT) +#define LCD_HSYNC_HPE_BIT 0 // HSYNC pulse end position in dot clock +#define LCD_HSYNC_HPE_MASK (0xffff << LCD_HSYNC_HPE_BIT) + +// Virtual Area Setting Register +#define LCD_VAT_HT_BIT 16 // Horizontal Total size in dot clock +#define LCD_VAT_HT_MASK (0xffff << LCD_VAT_HT_BIT) +#define LCD_VAT_VT_BIT 0 // Vertical Total size in dot clock +#define LCD_VAT_VT_MASK (0xffff << LCD_VAT_VT_BIT) + +// Display Area Horizontal Start/End Point Register +#define LCD_DAH_HDS_BIT 16 // Horizontal display area start in dot clock +#define LCD_DAH_HDS_MASK (0xffff << LCD_DAH_HDS_BIT) +#define LCD_DAH_HDE_BIT 0 // Horizontal display area end in dot clock +#define LCD_DAH_HDE_MASK (0xffff << LCD_DAH_HDE_BIT) + +// Display Area Vertical Start/End Point Register +#define LCD_DAV_VDS_BIT 16 // Vertical display area start in line clock +#define LCD_DAV_VDS_MASK (0xffff << LCD_DAV_VDS_BIT) +#define LCD_DAV_VDE_BIT 0 // Vertical display area end in line clock +#define LCD_DAV_VDE_MASK (0xffff << LCD_DAV_VDE_BIT) + +// PS Signal Setting +#define LCD_PS_PSS_BIT 16 // PS signal start position in dot clock +#define LCD_PS_PSS_MASK (0xffff << LCD_PS_PSS_BIT) +#define LCD_PS_PSE_BIT 0 // PS signal end position in dot clock +#define LCD_PS_PSE_MASK (0xffff << LCD_PS_PSE_BIT) + +// CLS Signal Setting +#define LCD_CLS_CLSS_BIT 16 // CLS signal start position in dot clock +#define LCD_CLS_CLSS_MASK (0xffff << LCD_CLS_CLSS_BIT) +#define LCD_CLS_CLSE_BIT 0 // CLS signal end position in dot clock +#define LCD_CLS_CLSE_MASK (0xffff << LCD_CLS_CLSE_BIT) + +// SPL Signal Setting +#define LCD_SPL_SPLS_BIT 16 // SPL signal start position in dot clock +#define LCD_SPL_SPLS_MASK (0xffff << LCD_SPL_SPLS_BIT) +#define LCD_SPL_SPLE_BIT 0 // SPL signal end position in dot clock +#define LCD_SPL_SPLE_MASK (0xffff << LCD_SPL_SPLE_BIT) + +// REV Signal Setting +#define LCD_REV_REVS_BIT 16 // REV signal start position in dot clock +#define LCD_REV_REVS_MASK (0xffff << LCD_REV_REVS_BIT) + +// LCD Control Register +#define LCD_CTRL_BST_BIT 28 // Burst Length Selection +#define LCD_CTRL_BST_MASK (0x03 << LCD_CTRL_BST_BIT) + #define LCD_CTRL_BST_4 (0 << LCD_CTRL_BST_BIT) // 4-word + #define LCD_CTRL_BST_8 (1 << LCD_CTRL_BST_BIT) // 8-word + #define LCD_CTRL_BST_16 (2 << LCD_CTRL_BST_BIT) // 16-word +#define LCD_CTRL_RGB565 (0 << 27) // RGB565 mode +#define LCD_CTRL_RGB555 (1 << 27) // RGB555 mode +#define LCD_CTRL_OFUP (1 << 26) // Output FIFO underrun protection enable +#define LCD_CTRL_FRC_BIT 24 // STN FRC Algorithm Selection +#define LCD_CTRL_FRC_MASK (0x03 << LCD_CTRL_FRC_BIT) + #define LCD_CTRL_FRC_16 (0 << LCD_CTRL_FRC_BIT) // 16 grayscale + #define LCD_CTRL_FRC_4 (1 << LCD_CTRL_FRC_BIT) // 4 grayscale + #define LCD_CTRL_FRC_2 (2 << LCD_CTRL_FRC_BIT) // 2 grayscale +#define LCD_CTRL_PDD_BIT 16 // Load Palette Delay Counter +#define LCD_CTRL_PDD_MASK (0xff << LCD_CTRL_PDD_BIT) +#define LCD_CTRL_EOFM (1 << 13) // EOF interrupt mask +#define LCD_CTRL_SOFM (1 << 12) // SOF interrupt mask +#define LCD_CTRL_OFUM (1 << 11) // Output FIFO underrun interrupt mask +#define LCD_CTRL_IFUM0 (1 << 10) // Input FIFO 0 underrun interrupt mask +#define LCD_CTRL_IFUM1 (1 << 9) // Input FIFO 1 underrun interrupt mask +#define LCD_CTRL_LDDM (1 << 8) // LCD disable done interrupt mask +#define LCD_CTRL_QDM (1 << 7) // LCD quick disable done interrupt mask +#define LCD_CTRL_BEDN (1 << 6) // Endian selection +#define LCD_CTRL_PEDN (1 << 5) // Endian in byte:0-msb first, 1-lsb first +#define LCD_CTRL_DIS (1 << 4) // Disable indicate bit +#define LCD_CTRL_ENA (1 << 3) // LCD enable bit +#define LCD_CTRL_BPP_BIT 0 // Bits Per Pixel +#define LCD_CTRL_BPP_MASK (0x07 << LCD_CTRL_BPP_BIT) + #define LCD_CTRL_BPP_1 (0 << LCD_CTRL_BPP_BIT) // 1 bpp + #define LCD_CTRL_BPP_2 (1 << LCD_CTRL_BPP_BIT) // 2 bpp + #define LCD_CTRL_BPP_4 (2 << LCD_CTRL_BPP_BIT) // 4 bpp + #define LCD_CTRL_BPP_8 (3 << LCD_CTRL_BPP_BIT) // 8 bpp + #define LCD_CTRL_BPP_16 (4 << LCD_CTRL_BPP_BIT) // 15/16 bpp + #define LCD_CTRL_BPP_18_24 (5 << LCD_CTRL_BPP_BIT) // 18/24/32 bpp + +// LCD Status Register +#define LCD_STATE_QD (1 << 7) // Quick Disable Done +#define LCD_STATE_EOF (1 << 5) // EOF Flag +#define LCD_STATE_SOF (1 << 4) // SOF Flag +#define LCD_STATE_OFU (1 << 3) // Output FIFO Underrun +#define LCD_STATE_IFU0 (1 << 2) // Input FIFO 0 Underrun +#define LCD_STATE_IFU1 (1 << 1) // Input FIFO 1 Underrun +#define LCD_STATE_LDD (1 << 0) // LCD Disabled + +// DMA Command Register +#define LCD_CMD_SOFINT (1 << 31) +#define LCD_CMD_EOFINT (1 << 30) +#define LCD_CMD_PAL (1 << 28) +#define LCD_CMD_LEN_BIT 0 +#define LCD_CMD_LEN_MASK (0xffffff << LCD_CMD_LEN_BIT) + + +//************************************************************************ +// USB Device +//************************************************************************ +#define UDC_FADDR REG8 (UDC_BASE + 0x00) // Function Address 8-bit +#define UDC_POWER REG8 (UDC_BASE + 0x01) // Power Managemetn 8-bit +#define UDC_INTRIN REG16 (UDC_BASE + 0x02) // Interrupt IN 16-bit +#define UDC_INTROUT REG16 (UDC_BASE + 0x04) // Interrupt OUT 16-bit +#define UDC_INTRINE REG16 (UDC_BASE + 0x06) // Intr IN enable 16-bit +#define UDC_INTROUTE REG16 (UDC_BASE + 0x08) // Intr OUT enable 16-bit +#define UDC_INTRUSB REG8 (UDC_BASE + 0x0a) // Interrupt USB 8-bit +#define UDC_INTRUSBE REG8 (UDC_BASE + 0x0b) // Interrupt USB Enable 8-bit +#define UDC_FRAME REG16 (UDC_BASE + 0x0c) // Frame number 16-bit +#define UDC_INDEX REG8 (UDC_BASE + 0x0e) // Index register 8-bit +#define UDC_TESTMODE REG8 (UDC_BASE + 0x0f) // USB test mode 8-bit + +#define UDC_CSR0 REG8 (UDC_BASE + 0x12) // EP0 CSR 8-bit +#define UDC_INMAXP REG16 (UDC_BASE + 0x10) // EP1-2 IN Max Pkt Size 16-bit +#define UDC_INCSR REG16 (UDC_BASE + 0x12) // EP1-2 IN CSR LSB 8/16bit +#define UDC_INCSRH REG8 (UDC_BASE + 0x13) // EP1-2 IN CSR MSB 8-bit +#define UDC_OUTMAXP REG16 (UDC_BASE + 0x14) // EP1 OUT Max Pkt Size 16-bit +#define UDC_OUTCSR REG16 (UDC_BASE + 0x16) // EP1 OUT CSR LSB 8/16bit +#define UDC_OUTCSRH REG8 (UDC_BASE + 0x17) // EP1 OUT CSR MSB 8-bit +#define UDC_OUTCOUNT REG16 (UDC_BASE + 0x18) // bytes in EP0/1 OUT FIFO 16-bit + +#define UDC_FIFO_EP0 REG32 (UDC_BASE + 0x20) +#define UDC_FIFO_EP1 REG32 (UDC_BASE + 0x24) +#define UDC_FIFO_EP2 REG32 (UDC_BASE + 0x28) + +#define UDC_EPINFO REG32 (UDC_BASE + 0x78) // Endpoint information +#define UDC_RAMINFO REG32 (UDC_BASE + 0x79) // RAM information + +#define UDC_INTR REG32 (UDC_BASE + 0x200) // DMA pending interrupts +#define UDC_CNTL1 REG32 (UDC_BASE + 0x204) // DMA channel 1 control +#define UDC_ADDR1 REG32 (UDC_BASE + 0x208) // DMA channel 1 AHB memory addr +#define UDC_COUNT1 REG32 (UDC_BASE + 0x20c) // DMA channel 1 byte count +#define UDC_CNTL2 REG32 (UDC_BASE + 0x214) // DMA channel 2 control +#define UDC_ADDR2 REG32 (UDC_BASE + 0x218) // DMA channel 2 AHB memory addr +#define UDC_COUNT2 REG32 (UDC_BASE + 0x21c) // DMA channel 2 byte count + + +// Power register bit masks +#define UDC_POWER_SUSPENDM 0x01 +#define UDC_POWER_RESUME 0x04 +#define UDC_POWER_HSMODE 0x10 +#define UDC_POWER_HSENAB 0x20 +#define UDC_POWER_SOFTCONN 0x40 + +// Interrupt register bit masks +#define UDC_INTR_SUSPEND 0x01 +#define UDC_INTR_RESUME 0x02 +#define UDC_INTR_RESET 0x04 + +#define UDC_INTR_EP0 0x0001 +#define UDC_INTR_INEP1 0x0002 +#define UDC_INTR_INEP2 0x0004 +#define UDC_INTR_OUTEP1 0x0002 + +// CSR0 bit masks +#define UDC_CSR0_OUTPKTRDY 0x01 +#define UDC_CSR0_INPKTRDY 0x02 +#define UDC_CSR0_SENTSTALL 0x04 +#define UDC_CSR0_DATAEND 0x08 +#define UDC_CSR0_SETUPEND 0x10 +#define UDC_CSR0_SENDSTALL 0x20 +#define UDC_CSR0_SVDOUTPKTRDY 0x40 +#define UDC_CSR0_SVDSETUPEND 0x80 + +// Endpoint CSR register bits +#define UDC_INCSRH_AUTOSET 0x80 +#define UDC_INCSRH_ISO 0x40 +#define UDC_INCSRH_MODE 0x20 +#define UDC_INCSRH_DMAREQENAB 0x10 +#define UDC_INCSRH_DMAREQMODE 0x04 +#define UDC_INCSR_CDT 0x40 +#define UDC_INCSR_SENTSTALL 0x20 +#define UDC_INCSR_SENDSTALL 0x10 +#define UDC_INCSR_FF 0x08 +#define UDC_INCSR_UNDERRUN 0x04 +#define UDC_INCSR_FFNOTEMPT 0x02 +#define UDC_INCSR_INPKTRDY 0x01 +#define UDC_OUTCSRH_AUTOCLR 0x80 +#define UDC_OUTCSRH_ISO 0x40 +#define UDC_OUTCSRH_DMAREQENAB 0x20 +#define UDC_OUTCSRH_DNYT 0x10 +#define UDC_OUTCSRH_DMAREQMODE 0x08 +#define UDC_OUTCSR_CDT 0x80 +#define UDC_OUTCSR_SENTSTALL 0x40 +#define UDC_OUTCSR_SENDSTALL 0x20 +#define UDC_OUTCSR_FF 0x10 +#define UDC_OUTCSR_DATAERR 0x08 +#define UDC_OUTCSR_OVERRUN 0x04 +#define UDC_OUTCSR_FFFULL 0x02 +#define UDC_OUTCSR_OUTPKTRDY 0x01 + +// Testmode register bits +#define UDC_TEST_SE0NAK 0x01 +#define UDC_TEST_J 0x02 +#define UDC_TEST_K 0x04 +#define UDC_TEST_PACKET 0x08 + +// DMA control bits +#define UDC_CNTL_ENA 0x01 +#define UDC_CNTL_DIR_IN 0x02 +#define UDC_CNTL_MODE_1 0x04 +#define UDC_CNTL_INTR_EN 0x08 +#define UDC_CNTL_EP(n) ((n) << 4) +#define UDC_CNTL_BURST_0 (0 << 9) +#define UDC_CNTL_BURST_4 (1 << 9) +#define UDC_CNTL_BURST_8 (2 << 9) +#define UDC_CNTL_BURST_16 (3 << 9) + +//########################################################################## +//************************************************************************** +// GPIO +//************************************************************************** + +//------------------------------------------------------ +// GPIO Pins Description +// +// PORT 0 +// +// PIN/BIT N FUNC0 FUNC1 +// 0 D0 - +// 1 D1 - +// 2 D2 - +// 3 D3 - +// 4 D4 - +// 5 D5 - +// 6 D6 - +// 7 D7 - +// 8 D8 - +// 9 D9 - +// 10 D10 - +// 11 D11 - +// 12 D12 - +// 13 D13 - +// 14 D14 - +// 15 D15 - +// 16 D16 - +// 17 D17 - +// 18 D18 - +// 19 D19 - +// 20 D20 - +// 21 D21 - +// 22 D22 - +// 23 D23 - +// 24 D24 - +// 25 D25 - +// 26 D26 - +// 27 D27 - +// 28 D28 - +// 29 D29 - +// 30 D30 - +// 31 D31 - +// +//------------------------------------------------------ +// PORT 1 +// +// PIN/BIT N FUNC0 FUNC1 +// 0 A0 - +// 1 A1 - +// 2 A2 - +// 3 A3 - +// 4 A4 - +// 5 A5 - +// 6 A6 - +// 7 A7 - +// 8 A8 - +// 9 A9 - +// 10 A10 - +// 11 A11 - +// 12 A12 - +// 13 A13 - +// 14 A14 - +// 15 A15/CL - +// 16 A16/AL - +// 17 LCD_CLS A21 +// 18 LCD_SPL A22 +// 19 DCS# - +// 20 RAS# - +// 21 CAS# - +// 22 RDWE#/BUFD# - +// 23 CKE - +// 24 CKO - +// 25 CS1# - +// 26 CS2# - +// 27 CS3# - +// 28 CS4# - +// 29 RD# - +// 30 WR# - +// 31 WE0# - +// +// Note: PIN15&16 are CL&AL when connecting to NAND flash. +//------------------------------------------------------ +// PORT 2 +// +// PIN/BIT N FUNC0 FUNC1 +// 0 LCD_D0 - +// 1 LCD_D1 - +// 2 LCD_D2 - +// 3 LCD_D3 - +// 4 LCD_D4 - +// 5 LCD_D5 - +// 6 LCD_D6 - +// 7 LCD_D7 - +// 8 LCD_D8 - +// 9 LCD_D9 - +// 10 LCD_D10 - +// 11 LCD_D11 - +// 12 LCD_D12 - +// 13 LCD_D13 - +// 14 LCD_D14 - +// 15 LCD_D15 - +// 16 LCD_D16 - +// 17 LCD_D17 - +// 18 LCD_PCLK - +// 19 LCD_HSYNC - +// 20 LCD_VSYNC - +// 21 LCD_DE - +// 22 LCD_PS A19 +// 23 LCD_REV A20 +// 24 WE1# - +// 25 WE2# - +// 26 WE3# - +// 27 WAIT# - +// 28 FRE# - +// 29 FWE# - +// 30(NOTE:FRB#) - - +// 31 - - +// +// NOTE(1): PIN30 is used for FRB# when connecting to NAND flash. +//------------------------------------------------------ +// PORT 3 +// +// PIN/BIT N FUNC0 FUNC1 +// 0 CIM_D0 - +// 1 CIM_D1 - +// 2 CIM_D2 - +// 3 CIM_D3 - +// 4 CIM_D4 - +// 5 CIM_D5 - +// 6 CIM_D6 - +// 7 CIM_D7 - +// 8 MSC_CMD - +// 9 MSC_CLK - +// 10 MSC_D0 - +// 11 MSC_D1 - +// 12 MSC_D2 - +// 13 MSC_D3 - +// 14 CIM_MCLK - +// 15 CIM_PCLK - +// 16 CIM_VSYNC - +// 17 CIM_HSYNC - +// 18 SSI_CLK SCLK_RSTN +// 19 SSI_CE0# BIT_CLK(AIC) +// 20 SSI_DT SDATA_OUT(AIC) +// 21 SSI_DR SDATA_IN(AIC) +// 22 SSI_CE1#&GPC SYNC(AIC) +// 23 PWM0 I2C_SDA +// 24 PWM1 I2C_SCK +// 25 PWM2 UART0_TxD +// 26 PWM3 UART0_RxD +// 27 PWM4 A17 +// 28 PWM5 A18 +// 29 - - +// 30 PWM6 UART0_CTS/UART1_RxD +// 31 PWM7 UART0_RTS/UART1_TxD +// +////////////////////////////////////////////////////////// + +// p is the port number (0,1,2,3) +// o is the pin offset (0-31) inside the port + +//------------------------------------------- +// Function Pins Mode + +static void gpio_as_func0 (unsigned p, unsigned o): + GPIO_PXFUNS (p) = (1 << o) + GPIO_PXSELC (p) = (1 << o) + +static void gpio_as_func1 (unsigned p, unsigned o): + GPIO_PXFUNS (p) = (1 << o) + GPIO_PXSELS (p) = (1 << o) + +// D0 ~ D31, A0 ~ A16, DCS#, RAS#, CAS#, CKE#, RDWE#, CKO#, WE0#, WE1#, WE2#, WE3# +static void gpio_as_sdram_32bit (): + GPIO_PXFUNS (0) = 0xffffffff + GPIO_PXSELC (0) = 0xffffffff + GPIO_PXPES (0) = 0xffffffff + GPIO_PXFUNS (1) = 0x81f9ffff + GPIO_PXSELC (1) = 0x81f9ffff + GPIO_PXPES (1) = 0x81f9ffff + GPIO_PXFUNS (2) = 0x07000000 + GPIO_PXSELC (2) = 0x07000000 + GPIO_PXPES (2) = 0x07000000 + +// D0 ~ D15, A0 ~ A16, DCS#, RAS#, CAS#, CKE#, RDWE#, CKO#, WE0#, WE1# +static void gpio_as_sdram_16bit(): + GPIO_PXFUNS (0) = 0x5442bfaa + GPIO_PXSELC (0) = 0x5442bfaa + GPIO_PXPES (0) = 0x5442bfaa + GPIO_PXFUNS (1) = 0x81f9ffff + GPIO_PXSELC (1) = 0x81f9ffff + GPIO_PXPES (1) = 0x81f9ffff + GPIO_PXFUNS (2) = 0x01000000 + GPIO_PXSELC (2) = 0x01000000 + GPIO_PXPES (2) = 0x01000000 + +// CS1#, CLE, ALE, FRE#, FWE#, FRB#, RDWE#/BUFD# +static void gpio_as_nand (): + GPIO_PXFUNS (1) = 0x02018000 + GPIO_PXSELC (1) = 0x02018000 + GPIO_PXPES (1) = 0x02018000 + GPIO_PXFUNS (2) = 0x30000000 + GPIO_PXSELC (2) = 0x30000000 + GPIO_PXPES (2) = 0x30000000 + GPIO_PXFUNC (2) = 0x40000000 + GPIO_PXSELC (2) = 0x40000000 + GPIO_PXDIRC (2) = 0x40000000 + GPIO_PXPES (2) = 0x40000000 + GPIO_PXFUNS (1) = 0x00400000 + GPIO_PXSELC (1) = 0x00400000 + +// UART0_TxD, UART_RxD0 +static void gpio_as_uart0 (): + GPIO_PXFUNS (3) = 0x06000000 + GPIO_PXSELS (3) = 0x06000000 + GPIO_PXPES (3) = 0x06000000 + +// UART0_CTS, UART0_RTS +static void gpio_as_ctsrts (): + GPIO_PXFUNS (3) = 0xc0000000 + GPIO_PXSELS (3) = 0xc0000000 + GPIO_PXTRGC (3) = 0xc0000000 + GPIO_PXPES (3) = 0xc0000000 + +// UART1_TxD, UART1_RxD1 +static void gpio_as_uart1(): + GPIO_PXFUNS (3) = 0xc0000000 + GPIO_PXSELC (3) = 0xc0000000 + GPIO_PXTRGS (3) = 0xc0000000 + GPIO_PXPES (3) = 0xc0000000 + +// LCD_D0~LCD_D15, LCD_PCLK, LCD_HSYNC, LCD_VSYNC, LCD_DE +static void gpio_as_lcd_16bit (): + GPIO_PXFUNS (2) = 0x003cffff + GPIO_PXSELC (2) = 0x003cffff + GPIO_PXPES (2) = 0x003cffff + +// LCD_D0~LCD_D17, LCD_PCLK, LCD_HSYNC, LCD_VSYNC, LCD_DE +static void gpio_as_lcd_18bit (): + GPIO_PXFUNS (2) = 0x003fffff + GPIO_PXSELC (2) = 0x003fffff + GPIO_PXPES (2) = 0x003fffff + +// LCD_PS, LCD_REV, LCD_CLS, LCD_SPL +static void gpio_as_lcd_spl (): + GPIO_PXFUNS (1) = 0x00060000 + GPIO_PXSELC (1) = 0x00060000 + GPIO_PXPES (1) = 0x00060000 + GPIO_PXFUNS (2) = 0x00c00000 + GPIO_PXSELC (2) = 0x00c00000 + GPIO_PXPES (2) = 0x00c00000 + +// CIM_D0~CIM_D7, CIM_MCLK, CIM_PCLK, CIM_VSYNC, CIM_HSYNC +static void gpio_as_cim (): + GPIO_PXFUNS (3) = 0x0003c0ff + GPIO_PXSELC (3) = 0x0003c0ff + GPIO_PXPES (3) = 0x0003c0ff + +// SDATA_OUT, SDATA_IN, BIT_CLK, SYNC, SCLK_RESET +static void gpio_as_aic (): + GPIO_PXFUNS(3) = 0x007c0000 + GPIO_PXSELS(3) = 0x007c0000 + GPIO_PXPES(3) = 0x007c0000 + +// MSC_CMD, MSC_CLK, MSC_D0 ~ MSC_D3 +static void gpio_as_msc (): + GPIO_PXFUNS (3) = 0x00003f00 + GPIO_PXSELC (3) = 0x00003f00 + GPIO_PXPES (3) = 0x00003f00 + +// SSI_CS0, SSI_CLK, SSI_DT, SSI_DR +static void gpio_as_ssi (): + GPIO_PXFUNS (3) = 0x003c0000 + GPIO_PXSELC (3) = 0x003c0000 + GPIO_PXPES (3) = 0x003c0000 + +// I2C_SCK, I2C_SDA +static void gpio_as_i2c (): + GPIO_PXFUNS (3) = 0x01800000 + GPIO_PXSELS (3) = 0x01800000 + GPIO_PXPES (3) = 0x01800000 + +// PWM* +static void gpio_as_pwm0 (): + GPIO_PXFUNS (3) = 0x00800000 + GPIO_PXSELC (3) = 0x00800000 + GPIO_PXPES (3) = 0x00800000 +static void gpio_as_pwm1 (): + GPIO_PXFUNS (3) = 0x01000000 + GPIO_PXSELC (3) = 0x01000000 + GPIO_PXPES (3) = 0x01000000 +static void gpio_as_pwm2 (): + GPIO_PXFUNS (3) = 0x02000000 + GPIO_PXSELC (3) = 0x02000000 + GPIO_PXPES (3) = 0x02000000 +static void gpio_as_pwm3 (): + GPIO_PXFUNS (3) = 0x04000000 + GPIO_PXSELC (3) = 0x04000000 + GPIO_PXPES (3) = 0x04000000 +static void gpio_as_pwm4 (): + GPIO_PXFUNS (3) = 0x08000000 + GPIO_PXSELC (3) = 0x08000000 + GPIO_PXPES (3) = 0x08000000 +static void gpio_as_pwm5 (): + GPIO_PXFUNS (3) = 0x10000000 + GPIO_PXSELC (3) = 0x10000000 + GPIO_PXPES (3) = 0x10000000 +static void gpio_as_pwm6 (): + GPIO_PXFUNS (3) = 0x40000000 + GPIO_PXSELC (3) = 0x40000000 + GPIO_PXPES (3) = 0x40000000 +static void gpio_as_pwm7 (): + GPIO_PXFUNS (3) = 0x80000000 + GPIO_PXSELC (3) = 0x80000000 + GPIO_PXPES (3) = 0x80000000 + +// n = 0 ~ 7 +#define gpio_as_pwm(n) (gpio_as_pwm##n ()) + +//------------------------------------------- +// GPIO or Interrupt Mode + +static unsigned gpio_get_port (unsigned p): + return GPIO_PXPIN (p) +static unsigned gpio_get_irqs (unsigned p): + return GPIO_PXFLG (p) + +static void gpio_as_gpio (unsigned p, unsigned pins): + GPIO_PXFUNC (p) = pins +static void gpio_as_output (unsigned p, unsigned pins): + GPIO_PXDIRS (p) = pins +static void gpio_as_input (unsigned p, unsigned pins): + GPIO_PXDIRC (p) = pins +// Set gpio as interrupt. It must already be set as gpio. It must be unmasked before it will trigger. +static void gpio_as_interrupt (unsigned p, unsigned pins, bool high, bool level): + GPIO_PXIMS (p) = pins + if level: + GPIO_PXTRGC (p) = pins + else: + GPIO_PXTRGS (p) = pins + GPIO_PXSELS (p) = pins + if high: + GPIO_PXDIRS (p) = pins + else: + GPIO_PXDIRS (p) = pins + GPIO_PXFLGC (p) = pins + +static void gpio_set (unsigned p, unsigned pins): + GPIO_PXDATS (p) = pins +static void gpio_clear (unsigned p, unsigned pins): + GPIO_PXDATC (p) = pins +static void gpio_mask_irq (unsigned p, unsigned pins): + GPIO_PXIMS (p) = pins +static void gpio_unmask_irq (unsigned p, unsigned pins): + GPIO_PXIMC (p) = pins +static void gpio_ack_irq (unsigned p, unsigned pins): + GPIO_PXFLGC (p) = pins + +static void gpio_enable_pull (unsigned p, unsigned pins): + GPIO_PXPEC (p) = pins +static void gpio_disable_pull (unsigned p, unsigned pins): + GPIO_PXPES (p) = pins + + +//************************************************************************** +// CPM +//************************************************************************** +static unsigned cpm_get_pllm (): + return (CPM_CPPCR & CPM_CPPCR_PLLM_MASK) >> CPM_CPPCR_PLLM_BIT +static unsigned cpm_get_plln (): + return (CPM_CPPCR & CPM_CPPCR_PLLN_MASK) >> CPM_CPPCR_PLLN_BIT +static unsigned cpm_get_pllod (): + return (CPM_CPPCR & CPM_CPPCR_PLLOD_MASK) >> CPM_CPPCR_PLLOD_BIT + +static unsigned cpm_get_cdiv (): + return (CPM_CPCCR & CPM_CPCCR_CDIV_MASK) >> CPM_CPCCR_CDIV_BIT +static unsigned cpm_get_hdiv (): + return (CPM_CPCCR & CPM_CPCCR_HDIV_MASK) >> CPM_CPCCR_HDIV_BIT +static unsigned cpm_get_pdiv (): + return (CPM_CPCCR & CPM_CPCCR_PDIV_MASK) >> CPM_CPCCR_PDIV_BIT +static unsigned cpm_get_mdiv (): + return (CPM_CPCCR & CPM_CPCCR_MDIV_MASK) >> CPM_CPCCR_MDIV_BIT +static unsigned cpm_get_ldiv (): + return (CPM_CPCCR & CPM_CPCCR_LDIV_MASK) >> CPM_CPCCR_LDIV_BIT +static unsigned cpm_get_udiv (): + return (CPM_CPCCR & CPM_CPCCR_UDIV_MASK) >> CPM_CPCCR_UDIV_BIT +static unsigned cpm_get_i2sdiv (): + return (CPM_I2SCDR & CPM_I2SCDR_I2SDIV_MASK) >> CPM_I2SCDR_I2SDIV_BIT +static unsigned cpm_get_pixdiv (): + return (CPM_LPCDR & CPM_LPCDR_PIXDIV_MASK) >> CPM_LPCDR_PIXDIV_BIT +static unsigned cpm_get_mscdiv (): + return (CPM_MSCCDR & CPM_MSCCDR_MSCDIV_MASK) >> CPM_MSCCDR_MSCDIV_BIT +static unsigned cpm_get_uhcdiv (): + return (CPM_UHCCDR & CPM_UHCCDR_UHCDIV_MASK) >> CPM_UHCCDR_UHCDIV_BIT +static unsigned cpm_get_ssidiv (): + return (CPM_SSICDR & CPM_SSICDR_SSIDIV_MASK) >> CPM_SSICDR_SSIDIV_BIT + +static unsigned cpm_set_cdiv (unsigned v): + return CPM_CPCCR = (CPM_CPCCR & ~CPM_CPCCR_CDIV_MASK) | (v << (CPM_CPCCR_CDIV_BIT)) +static unsigned cpm_set_hdiv (unsigned v): + return CPM_CPCCR = (CPM_CPCCR & ~CPM_CPCCR_HDIV_MASK) | (v << (CPM_CPCCR_HDIV_BIT)) +static unsigned cpm_set_pdiv (unsigned v): + return CPM_CPCCR = (CPM_CPCCR & ~CPM_CPCCR_PDIV_MASK) | (v << (CPM_CPCCR_PDIV_BIT)) +static unsigned cpm_set_mdiv (unsigned v): + return CPM_CPCCR = (CPM_CPCCR & ~CPM_CPCCR_MDIV_MASK) | (v << (CPM_CPCCR_MDIV_BIT)) +static unsigned cpm_set_ldiv (unsigned v): + return CPM_CPCCR = (CPM_CPCCR & ~CPM_CPCCR_LDIV_MASK) | (v << (CPM_CPCCR_LDIV_BIT)) +static unsigned cpm_set_udiv (unsigned v): + return CPM_CPCCR = (CPM_CPCCR & ~CPM_CPCCR_UDIV_MASK) | (v << (CPM_CPCCR_UDIV_BIT)) +static unsigned cpm_set_i2sdiv (unsigned v): + return CPM_I2SCDR = (CPM_I2SCDR & ~CPM_I2SCDR_I2SDIV_MASK) | (v << (CPM_I2SCDR_I2SDIV_BIT)) +static unsigned cpm_set_pixdiv (unsigned v): + return CPM_LPCDR = (CPM_LPCDR & ~CPM_LPCDR_PIXDIV_MASK) | (v << (CPM_LPCDR_PIXDIV_BIT)) +static unsigned cpm_set_mscdiv (unsigned v): + return CPM_MSCCDR = (CPM_MSCCDR & ~CPM_MSCCDR_MSCDIV_MASK) | (v << (CPM_MSCCDR_MSCDIV_BIT)) +static unsigned cpm_set_uhcdiv (unsigned v): + return CPM_UHCCDR = (CPM_UHCCDR & ~CPM_UHCCDR_UHCDIV_MASK) | (v << (CPM_UHCCDR_UHCDIV_BIT)) +static unsigned cpm_ssiclk_select_exclk (): + return CPM_SSICDR &= ~CPM_SSICDR_SCS +static unsigned cpm_ssiclk_select_pllout (): + return CPM_SSICDR |= CPM_SSICDR_SCS +static unsigned cpm_set_ssidiv (unsigned v): + return CPM_SSICDR = (CPM_SSICDR & ~CPM_SSICDR_SSIDIV_MASK) | ((v) << (CPM_SSICDR_SSIDIV_BIT)) + +#define cpm_select_i2sclk_exclk() (CPM_CPCCR &= ~CPM_CPCCR_I2CS) +#define cpm_select_i2sclk_pll() (CPM_CPCCR |= CPM_CPCCR_I2CS) +#define cpm_enable_cko() (CPM_CPCCR |= CPM_CPCCR_CLKOEN) +#define cpm_select_usbclk_exclk() (CPM_CPCCR &= ~CPM_CPCCR_UCS) +#define cpm_select_usbclk_pll() (CPM_CPCCR |= CPM_CPCCR_UCS) +#define cpm_enable_pll_change() (CPM_CPCCR |= CPM_CPCCR_CE) +#define cpm_pllout_direct() (CPM_CPCCR |= CPM_CPCCR_PCS) +#define cpm_pllout_div2() (CPM_CPCCR &= ~CPM_CPCCR_PCS) + +#define cpm_pll_is_on() (CPM_CPPCR & CPM_CPPCR_PLLS) +#define cpm_pll_bypass() (CPM_CPPCR |= CPM_CPPCR_PLLBP) +#define cpm_pll_enable() (CPM_CPPCR |= CPM_CPPCR_PLLEN) + +#define cpm_get_cclk_doze_duty() ((CPM_LCR & CPM_LCR_DOZE_DUTY_MASK) >> CPM_LCR_DOZE_DUTY_BIT) +#define cpm_set_cclk_doze_duty(v) (CPM_LCR = (CPM_LCR & ~CPM_LCR_DOZE_DUTY_MASK) | ((v) << (CPM_LCR_DOZE_DUTY_BIT))) + +#define cpm_doze_mode() (CPM_LCR |= CPM_LCR_DOZE_ON) +#define cpm_idle_mode() (CPM_LCR = (CPM_LCR & ~CPM_LCR_LPM_MASK) | CPM_LCR_LPM_IDLE) +#define cpm_sleep_mode() (CPM_LCR = (CPM_LCR & ~CPM_LCR_LPM_MASK) | CPM_LCR_LPM_SLEEP) + +#define cpm_stop_all() (CPM_CLKGR = 0x7fff) +#define cpm_stop_uart1() (CPM_CLKGR |= CPM_CLKGR_UART1) +#define cpm_stop_uhc() (CPM_CLKGR |= CPM_CLKGR_UHC) +#define cpm_stop_ipu() (CPM_CLKGR |= CPM_CLKGR_IPU) +#define cpm_stop_dmac() (CPM_CLKGR |= CPM_CLKGR_DMAC) +#define cpm_stop_udc() (CPM_CLKGR |= CPM_CLKGR_UDC) +#define cpm_stop_lcd() (CPM_CLKGR |= CPM_CLKGR_LCD) +#define cpm_stop_cim() (CPM_CLKGR |= CPM_CLKGR_CIM) +#define cpm_stop_sadc() (CPM_CLKGR |= CPM_CLKGR_SADC) +#define cpm_stop_msc() (CPM_CLKGR |= CPM_CLKGR_MSC) +#define cpm_stop_aic1() (CPM_CLKGR |= CPM_CLKGR_AIC1) +#define cpm_stop_aic2() (CPM_CLKGR |= CPM_CLKGR_AIC2) +#define cpm_stop_ssi() (CPM_CLKGR |= CPM_CLKGR_SSI) +#define cpm_stop_i2c() (CPM_CLKGR |= CPM_CLKGR_I2C) +#define cpm_stop_rtc() (CPM_CLKGR |= CPM_CLKGR_RTC) +#define cpm_stop_tcu() (CPM_CLKGR |= CPM_CLKGR_TCU) +#define cpm_stop_uart0() (CPM_CLKGR |= CPM_CLKGR_UART0) + +#define cpm_start_all() (CPM_CLKGR = 0x0) +#define cpm_start_uart1() (CPM_CLKGR &= ~CPM_CLKGR_UART1) +#define cpm_start_uhc() (CPM_CLKGR &= ~CPM_CLKGR_UHC) +#define cpm_start_ipu() (CPM_CLKGR &= ~CPM_CLKGR_IPU) +#define cpm_start_dmac() (CPM_CLKGR &= ~CPM_CLKGR_DMAC) +#define cpm_start_udc() (CPM_CLKGR &= ~CPM_CLKGR_UDC) +#define cpm_start_lcd() (CPM_CLKGR &= ~CPM_CLKGR_LCD) +#define cpm_start_cim() (CPM_CLKGR &= ~CPM_CLKGR_CIM) +#define cpm_start_sadc() (CPM_CLKGR &= ~CPM_CLKGR_SADC) +#define cpm_start_msc() (CPM_CLKGR &= ~CPM_CLKGR_MSC) +#define cpm_start_aic1() (CPM_CLKGR &= ~CPM_CLKGR_AIC1) +#define cpm_start_aic2() (CPM_CLKGR &= ~CPM_CLKGR_AIC2) +#define cpm_start_ssi() (CPM_CLKGR &= ~CPM_CLKGR_SSI) +#define cpm_start_i2c() (CPM_CLKGR &= ~CPM_CLKGR_I2C) +#define cpm_start_rtc() (CPM_CLKGR &= ~CPM_CLKGR_RTC) +#define cpm_start_tcu() (CPM_CLKGR &= ~CPM_CLKGR_TCU) +#define cpm_start_uart0() (CPM_CLKGR &= ~CPM_CLKGR_UART0) + +#define cpm_get_o1st() ((CPM_SCR & CPM_SCR_O1ST_MASK) >> CPM_SCR_O1ST_BIT) +#define cpm_set_o1st(v) (CPM_SCR = (CPM_SCR & ~CPM_SCR_O1ST_MASK) | ((v) << (CPM_SCR_O1ST_BIT))) +#define cpm_suspend_usbphy() (CPM_SCR |= CPM_SCR_USBPHY_SUSPEND) +#define cpm_enable_osc_in_sleep() (CPM_SCR |= CPM_SCR_OSC_ENABLE) + +// PLL output frequency +static unsigned cpm_get_pllout (): + unsigned m, n, no, pllout + unsigned cppcr = CPM_CPPCR + unsigned od[4] = {1, 2, 2, 4} + if (cppcr & CPM_CPPCR_PLLEN) && !(cppcr & CPM_CPPCR_PLLBP): + m = cpm_get_pllm () + 2 + n = cpm_get_plln () + 2 + no = od[cpm_get_pllod ()] + pllout = ((JZ_EXTAL) / (n * no)) * m + else: + pllout = JZ_EXTAL + return pllout + +// PLL output frequency for MSC/I2S/LCD/USB +static unsigned cpm_get_pllout2 (): + if CPM_CPCCR & CPM_CPCCR_PCS: + return cpm_get_pllout () + else: + return cpm_get_pllout () / 2 + +// CPU core clock +static unsigned cpm_get_cclk (): + int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32} + return cpm_get_pllout () / div[cpm_get_cdiv ()] + +// AHB system bus clock +static unsigned cpm_get_hclk (): + int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32} + return cpm_get_pllout () / div[cpm_get_hdiv ()] + +// Memory bus clock +static unsigned cpm_get_mclk (): + int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32} + return cpm_get_pllout () / div[cpm_get_mdiv ()] + +// APB peripheral bus clock +static unsigned cpm_get_pclk (): + int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32} + return cpm_get_pllout () / div[cpm_get_pdiv ()] + +// LCDC module clock +static unsigned cpm_get_lcdclk (): + return cpm_get_pllout2 () / (cpm_get_ldiv () + 1) + +// LCD pixel clock +static unsigned cpm_get_pixclk (): + return cpm_get_pllout2 () / (cpm_get_pixdiv () + 1) + +// I2S clock +static unsigned cpm_get_i2sclk (): + if CPM_CPCCR & CPM_CPCCR_I2CS: + return cpm_get_pllout2 () / (cpm_get_i2sdiv () + 1) + else: + return JZ_EXTAL + +// USB clock +static unsigned cpm_get_usbclk (): + if CPM_CPCCR & CPM_CPCCR_UCS: + return cpm_get_pllout2 () / (cpm_get_udiv () + 1) + else: + return JZ_EXTAL + +// MSC clock +static unsigned cpm_get_mscclk (): + return cpm_get_pllout2 () / (cpm_get_mscdiv () + 1) + +// EXTAL clock for UART,I2C,SSI,TCU,USB-PHY +static unsigned cpm_get_extalclk (): + return JZ_EXTAL + +// RTC clock for CPM,INTC,RTC,TCU,WDT +static unsigned cpm_get_rtcclk (): + return RTC_CLOCK + +// Output 24MHz for SD and 16MHz for MMC. +static inline void cpm_select_msc_clk (int sd): + unsigned int pllout2 = cpm_get_pllout2 () + unsigned int div = 0 + if sd: + div = pllout2 / 24000000 + else: + div = pllout2 / 16000000 + CPM_MSCCDR = div - 1 + + +//************************************************************************** +// TCU +//************************************************************************** +// where 'n' is the TCU channel +#define tcu_select_extalclk(n) (TCU_TCSR((n)) = (TCU_TCSR((n)) & ~(TCU_TCSR_EXT_EN | TCU_TCSR_RTC_EN | TCU_TCSR_PCK_EN)) | TCU_TCSR_EXT_EN) +#define tcu_select_rtcclk(n) (TCU_TCSR((n)) = (TCU_TCSR((n)) & ~(TCU_TCSR_EXT_EN | TCU_TCSR_RTC_EN | TCU_TCSR_PCK_EN)) | TCU_TCSR_RTC_EN) +#define tcu_select_pclk(n) (TCU_TCSR((n)) = (TCU_TCSR((n)) & ~(TCU_TCSR_EXT_EN | TCU_TCSR_RTC_EN | TCU_TCSR_PCK_EN)) | TCU_TCSR_PCK_EN) + +#define tcu_select_clk_div1(n) (TCU_TCSR((n)) = (TCU_TCSR((n)) & ~TCU_TCSR_PRESCALE_MASK) | TCU_TCSR_PRESCALE1) +#define tcu_select_clk_div4(n) (TCU_TCSR((n)) = (TCU_TCSR((n)) & ~TCU_TCSR_PRESCALE_MASK) | TCU_TCSR_PRESCALE4) +#define tcu_select_clk_div16(n) (TCU_TCSR((n)) = (TCU_TCSR((n)) & ~TCU_TCSR_PRESCALE_MASK) | TCU_TCSR_PRESCALE16) +#define tcu_select_clk_div64(n) (TCU_TCSR((n)) = (TCU_TCSR((n)) & ~TCU_TCSR_PRESCALE_MASK) | TCU_TCSR_PRESCALE64) +#define tcu_select_clk_div256(n) (TCU_TCSR((n)) = (TCU_TCSR((n)) & ~TCU_TCSR_PRESCALE_MASK) | TCU_TCSR_PRESCALE256) +#define tcu_select_clk_div1024(n) (TCU_TCSR((n)) = (TCU_TCSR((n)) & ~TCU_TCSR_PRESCALE_MASK) | TCU_TCSR_PRESCALE1024) + +#define tcu_enable_pwm_output(n) ( TCU_TCSR((n)) |= TCU_TCSR_PWM_EN ) +#define tcu_disable_pwm_output(n) ( TCU_TCSR((n)) &= ~TCU_TCSR_PWM_EN ) + +#define tcu_init_pwm_output_high(n) ( TCU_TCSR((n)) |= TCU_TCSR_PWM_INITL_HIGH ) +#define tcu_init_pwm_output_low(n) ( TCU_TCSR((n)) &= ~TCU_TCSR_PWM_INITL_HIGH ) + +#define tcu_set_pwm_output_shutdown_graceful(n) ( TCU_TCSR((n)) &= ~TCU_TCSR_PWM_SD ) +#define tcu_set_pwm_output_shutdown_abrupt(n) ( TCU_TCSR((n)) |= TCU_TCSR_PWM_SD ) + +#define tcu_start_counter(n) ( TCU_TESR |= (1 << (n)) ) +#define tcu_stop_counter(n) ( TCU_TECR |= (1 << (n)) ) + +#define tcu_half_match_flag(n) ( TCU_TFR & (1 << ((n) + 16)) ) +#define tcu_full_match_flag(n) ( TCU_TFR & (1 << (n)) ) +#define tcu_set_half_match_flag(n) ( TCU_TFSR = (1 << ((n) + 16)) ) +#define tcu_set_full_match_flag(n) ( TCU_TFSR = (1 << (n)) ) +#define tcu_clear_half_match_flag(n) ( TCU_TFCR = (1 << ((n) + 16)) ) +#define tcu_clear_full_match_flag(n) ( TCU_TFCR = (1 << (n)) ) +#define tcu_mask_half_match_irq(n) ( TCU_TMSR = (1 << ((n) + 16)) ) +#define tcu_mask_full_match_irq(n) ( TCU_TMSR = (1 << (n)) ) +#define tcu_unmask_half_match_irq(n) ( TCU_TMCR = (1 << ((n) + 16)) ) +#define tcu_unmask_full_match_irq(n) ( TCU_TMCR = (1 << (n)) ) + +#define tcu_wdt_clock_stopped() ( TCU_TSR & TCU_TSSR_WDTSC ) +#define tcu_timer_clock_stopped(n) ( TCU_TSR & (1 << (n)) ) + +#define tcu_start_wdt_clock() ( TCU_TSCR = TCU_TSSR_WDTSC ) +#define tcu_start_timer_clock(n) ( TCU_TSCR = (1 << (n)) ) + +#define tcu_stop_wdt_clock() ( TCU_TSSR = TCU_TSSR_WDTSC ) +#define tcu_stop_timer_clock(n) ( TCU_TSSR = (1 << (n)) ) + +#define tcu_get_count(n) ( TCU_TCNT((n)) ) +#define tcu_set_count(n,v) ( TCU_TCNT((n)) = (v) ) +#define tcu_set_full_data(n,v) ( TCU_TDFR((n)) = (v) ) +#define tcu_set_half_data(n,v) ( TCU_TDHR((n)) = (v) ) + + +//************************************************************************** +// WDT +//************************************************************************** +#define wdt_start() ( WDT_TCER |= WDT_TCER_TCEN ) +#define wdt_stop() ( WDT_TCER &= ~WDT_TCER_TCEN ) +#define wdt_set_count(v) ( WDT_TCNT = (v) ) +#define wdt_set_data(v) ( WDT_TDR = (v) ) + +#define wdt_select_extalclk() (WDT_TCSR = (WDT_TCSR & ~(WDT_TCSR_EXT_EN | WDT_TCSR_RTC_EN | WDT_TCSR_PCK_EN)) | WDT_TCSR_EXT_EN) +#define wdt_select_rtcclk() (WDT_TCSR = (WDT_TCSR & ~(WDT_TCSR_EXT_EN | WDT_TCSR_RTC_EN | WDT_TCSR_PCK_EN)) | WDT_TCSR_RTC_EN) +#define wdt_select_pclk() (WDT_TCSR = (WDT_TCSR & ~(WDT_TCSR_EXT_EN | WDT_TCSR_RTC_EN | WDT_TCSR_PCK_EN)) | WDT_TCSR_PCK_EN) + +#define wdt_select_clk_div1() (WDT_TCSR = (WDT_TCSR & ~WDT_TCSR_PRESCALE_MASK) | WDT_TCSR_PRESCALE1) +#define wdt_select_clk_div4() (WDT_TCSR = (WDT_TCSR & ~WDT_TCSR_PRESCALE_MASK) | WDT_TCSR_PRESCALE4) +#define wdt_select_clk_div16() (WDT_TCSR = (WDT_TCSR & ~WDT_TCSR_PRESCALE_MASK) | WDT_TCSR_PRESCALE16) +#define wdt_select_clk_div64() (WDT_TCSR = (WDT_TCSR & ~WDT_TCSR_PRESCALE_MASK) | WDT_TCSR_PRESCALE64) +#define wdt_select_clk_div256() (WDT_TCSR = (WDT_TCSR & ~WDT_TCSR_PRESCALE_MASK) | WDT_TCSR_PRESCALE256) +#define wdt_select_clk_div1024() (WDT_TCSR = (WDT_TCSR & ~WDT_TCSR_PRESCALE_MASK) | WDT_TCSR_PRESCALE1024) + + +//************************************************************************** +// UART +//************************************************************************** + +#define uart_enable(n) ( REG8(UART_BASE + UART_OFF*(n) + OFF_FCR) |= UARTFCR_UUE | UARTFCR_FE ) +#define uart_disable(n) ( REG8(UART_BASE + UART_OFF*(n) + OFF_FCR) = ~UARTFCR_UUE ) + +#define uart_enable_transmit_irq(n) ( REG8(UART_BASE + UART_OFF*(n) + OFF_IER) |= UARTIER_TIE ) +#define uart_disable_transmit_irq(n) ( REG8(UART_BASE + UART_OFF*(n) + OFF_IER) &= ~UARTIER_TIE ) + +#define uart_enable_receive_irq(n) ( REG8(UART_BASE + UART_OFF*(n) + OFF_IER) |= UARTIER_RIE | UARTIER_RLIE | UARTIER_RTIE ) +#define uart_disable_receive_irq(n) ( REG8(UART_BASE + UART_OFF*(n) + OFF_IER) &= ~(UARTIER_RIE | UARTIER_RLIE | UARTIER_RTIE) ) + +#define uart_enable_loopback(n) ( REG8(UART_BASE + UART_OFF*(n) + OFF_MCR) |= UARTMCR_LOOP ) +#define uart_disable_loopback(n) ( REG8(UART_BASE + UART_OFF*(n) + OFF_MCR) &= ~UARTMCR_LOOP ) + +#define uart_set_8n1(n) ( REG8(UART_BASE + UART_OFF*(n) + OFF_LCR) = UARTLCR_WLEN_8 ) + +static void uart_set_baud (unsigned n, unsigned devclk, unsigned baud): + REG8 (UART_BASE + UART_OFF*(n) + OFF_LCR) |= UARTLCR_DLAB + REG8 (UART_BASE + UART_OFF*(n) + OFF_DLLR) = (devclk / 16 / baud) & 0xff + REG8 (UART_BASE + UART_OFF*(n) + OFF_DLHR) = ((devclk / 16 / baud) >> 8) & 0xff + REG8 (UART_BASE + UART_OFF*(n) + OFF_LCR) &= ~UARTLCR_DLAB + +#define uart_parity_error(n) ( (REG8(UART_BASE + UART_OFF*(n) + OFF_LSR) & UARTLSR_PER) != 0 ) + +#define uart_clear_errors(n) ( REG8(UART_BASE + UART_OFF*(n) + OFF_LSR) &= ~(UARTLSR_ORER | UARTLSR_BRK | UARTLSR_FER | UARTLSR_PER | UARTLSR_RFER) ) + +#define uart_transmit_fifo_empty(n) ( (REG8(UART_BASE + UART_OFF*(n) + OFF_LSR) & UARTLSR_TDRQ) != 0 ) + +#define uart_transmit_end(n) ( (REG8(UART_BASE + UART_OFF*(n) + OFF_LSR) & UARTLSR_TEMT) != 0 ) + +#define uart_transmit_char(n, ch) REG8(UART_BASE + UART_OFF*(n) + OFF_TDR) = (ch) + +#define uart_receive_fifo_full(n) ( (REG8(UART_BASE + UART_OFF*(n) + OFF_LSR) & UARTLSR_DR) != 0 ) + +#define uart_receive_ready(n) ( (REG8(UART_BASE + UART_OFF*(n) + OFF_LSR) & UARTLSR_DR) != 0 ) + +#define uart_receive_char(n) REG8(UART_BASE + UART_OFF*(n) + OFF_RDR) + +#define uart_disable_irda() ( REG8(IRDA_BASE + OFF_SIRCR) &= ~(SIRCR_TSIRE | SIRCR_RSIRE) ) +#define uart_enable_irda() /* Tx high pulse as 0, Rx low pulse as 0 */ ( REG8(IRDA_BASE + OFF_SIRCR) = SIRCR_TSIRE | SIRCR_RSIRE | SIRCR_RXPL | SIRCR_TPWS ) + + +//************************************************************************** +// DMAC +//************************************************************************** + +// n is the DMA channel (0 - 5) + +#define dmac_enable_module() ( DMAC_DMACR |= DMAC_DMACR_DMAE | DMAC_DMACR_PR_RR ) +#define dmac_disable_module() ( DMAC_DMACR &= ~DMAC_DMACR_DMAE ) + +// p=0,1,2,3 +static void dmac_set_priority (unsigned p): + DMAC_DMACR &= ~DMAC_DMACR_PR_MASK + DMAC_DMACR |= ((p) << DMAC_DMACR_PR_BIT) + +#define dmac_test_halt_error() ( DMAC_DMACR & DMAC_DMACR_HLT ) +#define dmac_test_addr_error() ( DMAC_DMACR & DMAC_DMACR_AR ) + +#define dmac_enable_descriptor(n) ( DMAC_DCCSR((n)) &= ~DMAC_DCCSR_NDES ) +#define dmac_disable_descriptor(n) ( DMAC_DCCSR((n)) |= DMAC_DCCSR_NDES ) + +#define dmac_enable_channel(n) ( DMAC_DCCSR((n)) |= DMAC_DCCSR_EN ) +#define dmac_disable_channel(n) ( DMAC_DCCSR((n)) &= ~DMAC_DCCSR_EN ) +#define dmac_channel_enabled(n) ( DMAC_DCCSR((n)) & DMAC_DCCSR_EN ) + +#define dmac_channel_enable_irq(n) ( DMAC_DCMD((n)) |= DMAC_DCMD_TIE ) +#define dmac_channel_disable_irq(n) ( DMAC_DCMD((n)) &= ~DMAC_DCMD_TIE ) + +#define dmac_channel_transmit_halt_detected(n) ( DMAC_DCCSR((n)) & DMAC_DCCSR_HLT ) +#define dmac_channel_transmit_end_detected(n) ( DMAC_DCCSR((n)) & DMAC_DCCSR_TT ) +#define dmac_channel_address_error_detected(n) ( DMAC_DCCSR((n)) & DMAC_DCCSR_AR ) +#define dmac_channel_count_terminated_detected(n) ( DMAC_DCCSR((n)) & DMAC_DCCSR_CT ) +#define dmac_channel_descriptor_invalid_detected(n) ( DMAC_DCCSR((n)) & DMAC_DCCSR_INV ) + +#define dmac_channel_clear_transmit_halt(n) ( DMAC_DCCSR(n) &= ~DMAC_DCCSR_HLT ) +#define dmac_channel_clear_transmit_end(n) ( DMAC_DCCSR(n) &= ~DMAC_DCCSR_TT ) +#define dmac_channel_clear_address_error(n) ( DMAC_DCCSR(n) &= ~DMAC_DCCSR_AR ) +#define dmac_channel_clear_count_terminated(n) ( DMAC_DCCSR((n)) &= ~DMAC_DCCSR_CT ) +#define dmac_channel_clear_descriptor_invalid(n) ( DMAC_DCCSR((n)) &= ~DMAC_DCCSR_INV ) + +#define dmac_channel_set_single_mode(n) ( DMAC_DCMD((n)) &= ~DMAC_DCMD_TM ) +#define dmac_channel_set_block_mode(n) ( DMAC_DCMD((n)) |= DMAC_DCMD_TM ) + +static void dmac_channel_set_transfer_unit_32bit (unsigned n): + DMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK + DMAC_DCMD((n)) |= DMAC_DCMD_DS_32BIT + +static void dmac_channel_set_transfer_unit_16bit (unsigned n): + DMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK + DMAC_DCMD((n)) |= DMAC_DCMD_DS_16BIT + +static void dmac_channel_set_transfer_unit_8bit (unsigned n): + DMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK + DMAC_DCMD((n)) |= DMAC_DCMD_DS_8BIT + +static void dmac_channel_set_transfer_unit_16byte (unsigned n): + DMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK + DMAC_DCMD((n)) |= DMAC_DCMD_DS_16BYTE + +static void dmac_channel_set_transfer_unit_32byte (unsigned n): + DMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK + DMAC_DCMD((n)) |= DMAC_DCMD_DS_32BYTE + +// w=8,16,32 +#define dmac_channel_set_dest_port_width(n,w) do { DMAC_DCMD((n)) &= ~DMAC_DCMD_DWDH_MASK; DMAC_DCMD((n)) |= DMAC_DCMD_DWDH_##w; } while (0) + +// w=8,16,32 +#define dmac_channel_set_src_port_width(n,v) do { DMAC_DCMD((n)) &= ~DMAC_DCMD_SWDH_MASK; DMAC_DCMD((n)) |= DMAC_DCMD_SWDH_##w; } while (0) + +// v=0-15 +static void dmac_channel_set_rdil(unsigned n, unsigned v): + DMAC_DCMD((n)) &= ~DMAC_DCMD_RDIL_MASK + DMAC_DCMD((n)) |= ((v) << DMAC_DCMD_RDIL_BIT) + +#define dmac_channel_dest_addr_fixed(n) ( DMAC_DCMD((n)) &= ~DMAC_DCMD_DAI ) +#define dmac_channel_dest_addr_increment(n) ( DMAC_DCMD((n)) |= DMAC_DCMD_DAI ) + +#define dmac_channel_src_addr_fixed(n) ( DMAC_DCMD((n)) &= ~DMAC_DCMD_SAI ) +#define dmac_channel_src_addr_increment(n) ( DMAC_DCMD((n)) |= DMAC_DCMD_SAI ) + +#define dmac_channel_set_doorbell(n) ( DMAC_DMADBSR = (1 << (n)) ) + +#define dmac_channel_irq_detected(n) ( DMAC_DMAIPR & (1 << (n)) ) +#define dmac_channel_ack_irq(n) ( DMAC_DMAIPR &= ~(1 << (n)) ) + + +//************************************************************************** +// AIC (AC'97 & I2S Controller) +//************************************************************************** + +#define aic_enable() ( AIC_FR |= AIC_FR_ENB ) +#define aic_disable() ( AIC_FR &= ~AIC_FR_ENB ) + +#define aic_select_ac97() ( AIC_FR &= ~AIC_FR_AUSEL ) +#define aic_select_i2s() ( AIC_FR |= AIC_FR_AUSEL ) + +#define aic_play_zero() ( AIC_FR &= ~AIC_FR_LSMP ) +#define aic_play_lastsample() ( AIC_FR |= AIC_FR_LSMP ) + +#define i2s_as_master() ( AIC_FR |= AIC_FR_BCKD | AIC_FR_SYNCD ) +#define i2s_as_slave() ( AIC_FR &= ~(AIC_FR_BCKD | AIC_FR_SYNCD) ) +#define aic_reset_status() ( AIC_FR & AIC_FR_RST ) + +static void aic_reset(): + AIC_FR |= AIC_FR_RST + +static void aic_set_transmit_trigger (unsigned n): + AIC_FR &= ~AIC_FR_TFTH_MASK + AIC_FR |= ((n) << AIC_FR_TFTH_BIT) + +static void aic_set_receive_trigger (unsigned n): + AIC_FR &= ~AIC_FR_RFTH_MASK + AIC_FR |= ((n) << AIC_FR_RFTH_BIT) + +#define aic_enable_record() ( AIC_CR |= AIC_CR_EREC ) +#define aic_disable_record() ( AIC_CR &= ~AIC_CR_EREC ) +#define aic_enable_replay() ( AIC_CR |= AIC_CR_ERPL ) +#define aic_disable_replay() ( AIC_CR &= ~AIC_CR_ERPL ) +#define aic_enable_loopback() ( AIC_CR |= AIC_CR_ENLBF ) +#define aic_disable_loopback() ( AIC_CR &= ~AIC_CR_ENLBF ) + +#define aic_flush_fifo() ( AIC_CR |= AIC_CR_FLUSH ) +#define aic_unflush_fifo() ( AIC_CR &= ~AIC_CR_FLUSH ) + +#define aic_enable_transmit_intr() ( AIC_CR |= (AIC_CR_ETFS | AIC_CR_ETUR) ) +#define aic_disable_transmit_intr() ( AIC_CR &= ~(AIC_CR_ETFS | AIC_CR_ETUR) ) +#define aic_enable_receive_intr() ( AIC_CR |= (AIC_CR_ERFS | AIC_CR_EROR) ) +#define aic_disable_receive_intr() ( AIC_CR &= ~(AIC_CR_ERFS | AIC_CR_EROR) ) + +#define aic_enable_transmit_dma() ( AIC_CR |= AIC_CR_TDMS ) +#define aic_disable_transmit_dma() ( AIC_CR &= ~AIC_CR_TDMS ) +#define aic_enable_receive_dma() ( AIC_CR |= AIC_CR_RDMS ) +#define aic_disable_receive_dma() ( AIC_CR &= ~AIC_CR_RDMS ) + +#define aic_enable_mono2stereo() ( AIC_CR |= AIC_CR_M2S ) +#define aic_disable_mono2stereo() ( AIC_CR &= ~AIC_CR_M2S ) +#define aic_enable_byteswap() ( AIC_CR |= AIC_CR_ENDSW ) +#define aic_disable_byteswap() ( AIC_CR &= ~AIC_CR_ENDSW ) +#define aic_enable_unsignadj() ( AIC_CR |= AIC_CR_AVSTSU ) +#define aic_disable_unsignadj() ( AIC_CR &= ~AIC_CR_AVSTSU ) + +#define AC97_PCM_XS_L_FRONT AIC_ACCR1_XS_SLOT3 +#define AC97_PCM_XS_R_FRONT AIC_ACCR1_XS_SLOT4 +#define AC97_PCM_XS_CENTER AIC_ACCR1_XS_SLOT6 +#define AC97_PCM_XS_L_SURR AIC_ACCR1_XS_SLOT7 +#define AC97_PCM_XS_R_SURR AIC_ACCR1_XS_SLOT8 +#define AC97_PCM_XS_LFE AIC_ACCR1_XS_SLOT9 + +#define AC97_PCM_RS_L_FRONT AIC_ACCR1_RS_SLOT3 +#define AC97_PCM_RS_R_FRONT AIC_ACCR1_RS_SLOT4 +#define AC97_PCM_RS_CENTER AIC_ACCR1_RS_SLOT6 +#define AC97_PCM_RS_L_SURR AIC_ACCR1_RS_SLOT7 +#define AC97_PCM_RS_R_SURR AIC_ACCR1_RS_SLOT8 +#define AC97_PCM_RS_LFE AIC_ACCR1_RS_SLOT9 + +#define ac97_set_xs_none() ( AIC_ACCR1 &= ~AIC_ACCR1_XS_MASK ) +static void ac97_set_xs_mono(): + AIC_ACCR1 &= ~AIC_ACCR1_XS_MASK + AIC_ACCR1 |= AC97_PCM_XS_R_FRONT +static void ac97_set_xs_stereo(): + AIC_ACCR1 &= ~AIC_ACCR1_XS_MASK + AIC_ACCR1 |= AC97_PCM_XS_L_FRONT | AC97_PCM_XS_R_FRONT + +// In fact, only stereo is support now. +#define ac97_set_rs_none() ( AIC_ACCR1 &= ~AIC_ACCR1_RS_MASK ) +static void ac97_set_rs_mono(): + AIC_ACCR1 &= ~AIC_ACCR1_RS_MASK + AIC_ACCR1 |= AC97_PCM_RS_R_FRONT +static void ac97_set_rs_stereo(): + AIC_ACCR1 &= ~AIC_ACCR1_RS_MASK + AIC_ACCR1 |= AC97_PCM_RS_L_FRONT | AC97_PCM_RS_R_FRONT + +static void ac97_warm_reset_codec(): + AIC_ACCR2 |= AIC_ACCR2_SA + AIC_ACCR2 |= AIC_ACCR2_SS + //udelay(2) // TODO + AIC_ACCR2 &= ~AIC_ACCR2_SS + AIC_ACCR2 &= ~AIC_ACCR2_SA + +static void ac97_cold_reset_codec(): + AIC_ACCR2 |= AIC_ACCR2_SR + //udelay(2) // TODO + AIC_ACCR2 &= ~AIC_ACCR2_SR + +// n=8,16,18,20 +#define ac97_set_iass(n) ( AIC_ACCR2 = (AIC_ACCR2 & ~AIC_ACCR2_IASS_MASK) | AIC_ACCR2_IASS_##n##BIT ) +#define ac97_set_oass(n) ( AIC_ACCR2 = (AIC_ACCR2 & ~AIC_ACCR2_OASS_MASK) | AIC_ACCR2_OASS_##n##BIT ) + +#define i2s_select_i2s() ( AIC_I2SCR &= ~AIC_I2SCR_AMSL ) +#define i2s_select_msbjustified() ( AIC_I2SCR |= AIC_I2SCR_AMSL ) + +// n=8,16,18,20,24 +//#define i2s_set_sample_size(n) ( AIC_I2SCR |= (AIC_I2SCR & ~AIC_I2SCR_WL_MASK) | AIC_I2SCR_WL_##n##BIT ) + +#define i2s_set_oss_sample_size(n) ( AIC_CR = (AIC_CR & ~AIC_CR_OSS_MASK) | AIC_CR_OSS_##n##BIT ) +#define i2s_set_iss_sample_size(n) ( AIC_CR = (AIC_CR & ~AIC_CR_ISS_MASK) | AIC_CR_ISS_##n##BIT ) + +#define i2s_stop_bitclk() ( AIC_I2SCR |= AIC_I2SCR_STPBK ) +#define i2s_start_bitclk() ( AIC_I2SCR &= ~AIC_I2SCR_STPBK ) + +#define aic_transmit_request() ( AIC_SR & AIC_SR_TFS ) +#define aic_receive_request() ( AIC_SR & AIC_SR_RFS ) +#define aic_transmit_underrun() ( AIC_SR & AIC_SR_TUR ) +#define aic_receive_overrun() ( AIC_SR & AIC_SR_ROR ) + +#define aic_clear_errors() ( AIC_SR &= ~(AIC_SR_TUR | AIC_SR_ROR) ) + +#define aic_get_transmit_resident() ( (AIC_SR & AIC_SR_TFL_MASK) >> AIC_SR_TFL_BIT ) +#define aic_get_receive_count() ( (AIC_SR & AIC_SR_RFL_MASK) >> AIC_SR_RFL_BIT ) + +#define ac97_command_transmitted() ( AIC_ACSR & AIC_ACSR_CADT ) +#define ac97_status_received() ( AIC_ACSR & AIC_ACSR_SADR ) +#define ac97_status_receive_timeout() ( AIC_ACSR & AIC_ACSR_RSTO ) +#define ac97_codec_is_low_power_mode() ( AIC_ACSR & AIC_ACSR_CLPM ) +#define ac97_codec_is_ready() ( AIC_ACSR & AIC_ACSR_CRDY ) +#define ac97_slot_error_detected() ( AIC_ACSR & AIC_ACSR_SLTERR ) +#define ac97_clear_slot_error() ( AIC_ACSR &= ~AIC_ACSR_SLTERR ) + +#define i2s_is_busy() ( AIC_I2SSR & AIC_I2SSR_BSY ) + +#define CODEC_READ_CMD (1 << 19) +#define CODEC_WRITE_CMD (0 << 19) +#define CODEC_REG_INDEX_BIT 12 +#define CODEC_REG_INDEX_MASK (0x7f << CODEC_REG_INDEX_BIT) // 18:12 +#define CODEC_REG_DATA_BIT 4 +#define CODEC_REG_DATA_MASK (0x0ffff << 4) // 19:4 + +#define ac97_out_rcmd_addr(reg) (AIC_ACCAR = CODEC_READ_CMD | ((reg) << CODEC_REG_INDEX_BIT)) + +#define ac97_out_wcmd_addr(reg) (AIC_ACCAR = CODEC_WRITE_CMD | ((reg) << CODEC_REG_INDEX_BIT)) + +#define ac97_out_data(value) (AIC_ACCDR = ((value) << CODEC_REG_DATA_BIT)) + +#define ac97_in_data() ( (AIC_ACSDR & CODEC_REG_DATA_MASK) >> CODEC_REG_DATA_BIT ) + +#define ac97_in_status_addr() ( (AIC_ACSAR & CODEC_REG_INDEX_MASK) >> CODEC_REG_INDEX_BIT ) + +#define i2s_set_sample_rate(i2sclk, sync) ( AIC_I2SDIV = ((i2sclk) / (4*64)) / (sync) ) + +#define aic_write_tfifo(v) ( AIC_DR = (v) ) +#define aic_read_rfifo() ( AIC_DR ) + +#define aic_internal_codec() ( AIC_FR |= AIC_FR_ICDC ) +#define aic_external_codec() ( AIC_FR &= ~AIC_FR_ICDC ) + +// +// Define next ops for AC97 compatible +// + +#define AC97_ACSR AIC_ACSR + +#define ac97_enable() aic_enable(); aic_select_ac97() +#define ac97_disable() aic_disable() +#define ac97_reset() aic_reset() + +#define ac97_set_transmit_trigger(n) aic_set_transmit_trigger(n) +#define ac97_set_receive_trigger(n) aic_set_receive_trigger(n) + +#define ac97_enable_record() aic_enable_record() +#define ac97_disable_record() aic_disable_record() +#define ac97_enable_replay() aic_enable_replay() +#define ac97_disable_replay() aic_disable_replay() +#define ac97_enable_loopback() aic_enable_loopback() +#define ac97_disable_loopback() aic_disable_loopback() + +#define ac97_enable_transmit_dma() aic_enable_transmit_dma() +#define ac97_disable_transmit_dma() aic_disable_transmit_dma() +#define ac97_enable_receive_dma() aic_enable_receive_dma() +#define ac97_disable_receive_dma() aic_disable_receive_dma() + +#define ac97_transmit_request() aic_transmit_request() +#define ac97_receive_request() aic_receive_request() +#define ac97_transmit_underrun() aic_transmit_underrun() +#define ac97_receive_overrun() aic_receive_overrun() + +#define ac97_clear_errors() aic_clear_errors() + +#define ac97_get_transmit_resident() aic_get_transmit_resident() +#define ac97_get_receive_count() aic_get_receive_count() + +#define ac97_enable_transmit_intr() aic_enable_transmit_intr() +#define ac97_disable_transmit_intr() aic_disable_transmit_intr() +#define ac97_enable_receive_intr() aic_enable_receive_intr() +#define ac97_disable_receive_intr() aic_disable_receive_intr() + +#define ac97_write_tfifo(v) aic_write_tfifo(v) +#define ac97_read_rfifo() aic_read_rfifo() + +// +// Define next ops for I2S compatible +// + +#define I2S_ACSR AIC_I2SSR + +#define i2s_enable() aic_enable(); aic_select_i2s() +#define i2s_disable() aic_disable() +#define i2s_reset() aic_reset() + +#define i2s_set_transmit_trigger(n) aic_set_transmit_trigger(n) +#define i2s_set_receive_trigger(n) aic_set_receive_trigger(n) + +#define i2s_enable_record() aic_enable_record() +#define i2s_disable_record() aic_disable_record() +#define i2s_enable_replay() aic_enable_replay() +#define i2s_disable_replay() aic_disable_replay() +#define i2s_enable_loopback() aic_enable_loopback() +#define i2s_disable_loopback() aic_disable_loopback() + +#define i2s_enable_transmit_dma() aic_enable_transmit_dma() +#define i2s_disable_transmit_dma() aic_disable_transmit_dma() +#define i2s_enable_receive_dma() aic_enable_receive_dma() +#define i2s_disable_receive_dma() aic_disable_receive_dma() + +#define i2s_transmit_request() aic_transmit_request() +#define i2s_receive_request() aic_receive_request() +#define i2s_transmit_underrun() aic_transmit_underrun() +#define i2s_receive_overrun() aic_receive_overrun() + +#define i2s_clear_errors() aic_clear_errors() + +#define i2s_get_transmit_resident() aic_get_transmit_resident() +#define i2s_get_receive_count() aic_get_receive_count() + +#define i2s_enable_transmit_intr() aic_enable_transmit_intr() +#define i2s_disable_transmit_intr() aic_disable_transmit_intr() +#define i2s_enable_receive_intr() aic_enable_receive_intr() +#define i2s_disable_receive_intr() aic_disable_receive_intr() + +#define i2s_write_tfifo(v) aic_write_tfifo(v) +#define i2s_read_rfifo() aic_read_rfifo() + +#define i2s_reset_codec() do { } while (0) + + +//************************************************************************** +// ICDC +//************************************************************************** +#define i2s_internal_codec() aic_internal_codec() +#define i2s_external_codec() aic_external_codec() + +//************************************************************************** +// INTC +//************************************************************************** +#define intc_unmask_irq(n) ( INTC_IMCR = (1 << (n)) ) +#define intc_mask_irq(n) ( INTC_IMSR = (1 << (n)) ) +#define intc_ack_irq(n) ( INTC_IPR = (1 << (n)) ) + + +//************************************************************************** +// I2C +//************************************************************************** + +#define i2c_enable() ( I2C_CR |= I2C_CR_I2CE ) +#define i2c_disable() ( I2C_CR &= ~I2C_CR_I2CE ) + +#define i2c_send_start() ( I2C_CR |= I2C_CR_STA ) +#define i2c_send_stop() ( I2C_CR |= I2C_CR_STO ) +#define i2c_send_ack() ( I2C_CR &= ~I2C_CR_AC ) +#define i2c_send_nack() ( I2C_CR |= I2C_CR_AC ) + +#define i2c_set_drf() ( I2C_SR |= I2C_SR_DRF ) +#define i2c_clear_drf() ( I2C_SR &= ~I2C_SR_DRF ) +#define i2c_check_drf() ( I2C_SR & I2C_SR_DRF ) + +#define i2c_received_ack() ( !(I2C_SR & I2C_SR_ACKF) ) +#define i2c_is_busy() ( I2C_SR & I2C_SR_BUSY ) +#define i2c_transmit_ended() ( I2C_SR & I2C_SR_TEND ) + +#define i2c_set_clk(dev_clk, i2c_clk) ( I2C_GR = (dev_clk) / (16*(i2c_clk)) - 1 ) + +#define i2c_read() ( I2C_DR ) +#define i2c_write(val) ( I2C_DR = (val) ) + + +//************************************************************************** +// MSC +//************************************************************************** + +#define msc_start_op() ( MSC_STRPCL = MSC_STRPCL_START_OP | MSC_STRPCL_CLOCK_CONTROL_START ) + +#define msc_set_resto(to) ( MSC_RESTO = to ) +#define msc_set_rdto(to) ( MSC_RDTO = to ) +#define msc_set_cmd(cmd) ( MSC_CMD = cmd ) +#define msc_set_arg(arg) ( MSC_ARG = arg ) +#define msc_set_nob(nob) ( MSC_NOB = nob ) +#define msc_get_nob() ( MSC_NOB ) +#define msc_set_blklen(len) ( MSC_BLKLEN = len ) +#define msc_set_cmdat(cmdat) ( MSC_CMDAT = cmdat ) +#define msc_set_cmdat_ioabort() ( MSC_CMDAT |= MSC_CMDAT_IO_ABORT ) +#define msc_clear_cmdat_ioabort() ( MSC_CMDAT &= ~MSC_CMDAT_IO_ABORT ) + +static void msc_set_cmdat_bus_width1(): + MSC_CMDAT &= ~MSC_CMDAT_BUS_WIDTH_MASK + MSC_CMDAT |= MSC_CMDAT_BUS_WIDTH_1BIT + +static void msc_set_cmdat_bus_width4(): + MSC_CMDAT &= ~MSC_CMDAT_BUS_WIDTH_MASK + MSC_CMDAT |= MSC_CMDAT_BUS_WIDTH_4BIT + +#define msc_set_cmdat_dma_en() ( MSC_CMDAT |= MSC_CMDAT_DMA_EN ) +#define msc_set_cmdat_init() ( MSC_CMDAT |= MSC_CMDAT_INIT ) +#define msc_set_cmdat_busy() ( MSC_CMDAT |= MSC_CMDAT_BUSY ) +#define msc_set_cmdat_stream() ( MSC_CMDAT |= MSC_CMDAT_STREAM_BLOCK ) +#define msc_set_cmdat_block() ( MSC_CMDAT &= ~MSC_CMDAT_STREAM_BLOCK ) +#define msc_set_cmdat_read() ( MSC_CMDAT &= ~MSC_CMDAT_WRITE_READ ) +#define msc_set_cmdat_write() ( MSC_CMDAT |= MSC_CMDAT_WRITE_READ ) +#define msc_set_cmdat_data_en() ( MSC_CMDAT |= MSC_CMDAT_DATA_EN ) + +// r is MSC_CMDAT_RESPONSE_FORMAT_Rx or MSC_CMDAT_RESPONSE_FORMAT_NONE +static void msc_set_cmdat_res_format(unsigned r): + MSC_CMDAT &= ~MSC_CMDAT_RESPONSE_MASK + MSC_CMDAT |= (r) + +#define msc_clear_cmdat() MSC_CMDAT &= ~( MSC_CMDAT_IO_ABORT | MSC_CMDAT_DMA_EN | MSC_CMDAT_INIT| MSC_CMDAT_BUSY | MSC_CMDAT_STREAM_BLOCK | MSC_CMDAT_WRITE_READ | MSC_CMDAT_DATA_EN | MSC_CMDAT_RESPONSE_MASK ) + +#define msc_get_imask() ( MSC_IMASK ) +#define msc_mask_all_intrs() ( MSC_IMASK = 0xff ) +#define msc_unmask_all_intrs() ( MSC_IMASK = 0x00 ) +#define msc_mask_rd() ( MSC_IMASK |= MSC_IMASK_RXFIFO_RD_REQ ) +#define msc_unmask_rd() ( MSC_IMASK &= ~MSC_IMASK_RXFIFO_RD_REQ ) +#define msc_mask_wr() ( MSC_IMASK |= MSC_IMASK_TXFIFO_WR_REQ ) +#define msc_unmask_wr() ( MSC_IMASK &= ~MSC_IMASK_TXFIFO_WR_REQ ) +#define msc_mask_endcmdres() ( MSC_IMASK |= MSC_IMASK_END_CMD_RES ) +#define msc_unmask_endcmdres() ( MSC_IMASK &= ~MSC_IMASK_END_CMD_RES ) +#define msc_mask_datatrandone() ( MSC_IMASK |= MSC_IMASK_DATA_TRAN_DONE ) +#define msc_unmask_datatrandone() ( MSC_IMASK &= ~MSC_IMASK_DATA_TRAN_DONE ) +#define msc_mask_prgdone() ( MSC_IMASK |= MSC_IMASK_PRG_DONE ) +#define msc_unmask_prgdone() ( MSC_IMASK &= ~MSC_IMASK_PRG_DONE ) + +// n=0,1,2,3,4,5,6,7 +#define msc_set_clkrt(n) (MSC_CLKRT = n) + +#define msc_get_ireg() ( MSC_IREG ) +#define msc_ireg_rd() ( MSC_IREG & MSC_IREG_RXFIFO_RD_REQ ) +#define msc_ireg_wr() ( MSC_IREG & MSC_IREG_TXFIFO_WR_REQ ) +#define msc_ireg_end_cmd_res() ( MSC_IREG & MSC_IREG_END_CMD_RES ) +#define msc_ireg_data_tran_done() ( MSC_IREG & MSC_IREG_DATA_TRAN_DONE ) +#define msc_ireg_prg_done() ( MSC_IREG & MSC_IREG_PRG_DONE ) +#define msc_ireg_clear_end_cmd_res() ( MSC_IREG = MSC_IREG_END_CMD_RES ) +#define msc_ireg_clear_data_tran_done() ( MSC_IREG = MSC_IREG_DATA_TRAN_DONE ) +#define msc_ireg_clear_prg_done() ( MSC_IREG = MSC_IREG_PRG_DONE ) + +#define msc_get_stat() ( MSC_STAT ) +#define msc_stat_not_end_cmd_res() ( (MSC_STAT & MSC_STAT_END_CMD_RES) == 0) +#define msc_stat_crc_err() ( MSC_STAT & (MSC_STAT_CRC_RES_ERR | MSC_STAT_CRC_READ_ERROR | MSC_STAT_CRC_WRITE_ERROR_YES) ) +#define msc_stat_res_crc_err() ( MSC_STAT & MSC_STAT_CRC_RES_ERR ) +#define msc_stat_rd_crc_err() ( MSC_STAT & MSC_STAT_CRC_READ_ERROR ) +#define msc_stat_wr_crc_err() ( MSC_STAT & MSC_STAT_CRC_WRITE_ERROR_YES ) +#define msc_stat_resto_err() ( MSC_STAT & MSC_STAT_TIME_OUT_RES ) +#define msc_stat_rdto_err() ( MSC_STAT & MSC_STAT_TIME_OUT_READ ) + +#define msc_rd_resfifo() ( MSC_RES ) +#define msc_rd_rxfifo() ( MSC_RXFIFO ) +#define msc_wr_txfifo(v) ( MSC_TXFIFO = v ) + +static void msc_reset(): + MSC_STRPCL = MSC_STRPCL_RESET + while MSC_STAT & MSC_STAT_IS_RESETTING: + +#define msc_start_clk() (MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_START) + +#define msc_stop_clk() (MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_STOP) + +#define MMC_CLK 19169200 +#define SD_CLK 24576000 + +// msc_clk should little than pclk and little than clk retrieve from card +static unsigned msc_calc_clk_divisor (bool sd, unsigned dev_clk, unsigned msc_clk): + unsigned int rate, pclk, i + pclk = dev_clk + rate = sd ? SD_CLK : MMC_CLK + if msc_clk && msc_clk < pclk: + pclk = msc_clk + i = 0 + while pclk < rate: + i ++ + rate >>= 1 + return i + +// divide rate to little than or equal to 400kHz +static unsigned msc_calc_slow_clk_divisor (bool sd): + unsigned rate, i + rate = (sd ? SD_CLK : MMC_CLK) / 1000 / 400 + i = 0 + while rate > 0: + rate >>= 1 + ++i + return i + + +//************************************************************************** +// SSI +//************************************************************************** + +#define ssi_enable() ( SSI_CR0 |= SSI_CR0_SSIE ) +#define ssi_disable() ( SSI_CR0 &= ~SSI_CR0_SSIE ) +#define ssi_select_ce() ( SSI_CR0 &= ~SSI_CR0_FSEL ) + +#define ssi_normal_mode() ( SSI_ITR &= ~SSI_ITR_IVLTM_MASK ) + +static void ssi_select_ce2 (): + SSI_CR0 |= SSI_CR0_FSEL + SSI_CR1 &= ~SSI_CR1_MULTS + +static void ssi_select_gpc (): + SSI_CR0 &= ~SSI_CR0_FSEL + SSI_CR1 |= SSI_CR1_MULTS + +#define ssi_enable_tx_intr() ( SSI_CR0 |= SSI_CR0_TIE | SSI_CR0_TEIE ) + +#define ssi_disable_tx_intr() ( SSI_CR0 &= ~(SSI_CR0_TIE | SSI_CR0_TEIE) ) + +#define ssi_enable_rx_intr() ( SSI_CR0 |= SSI_CR0_RIE | SSI_CR0_REIE ) + +#define ssi_disable_rx_intr() ( SSI_CR0 &= ~(SSI_CR0_RIE | SSI_CR0_REIE) ) + +#define ssi_enable_txfifo_half_empty_intr() ( SSI_CR0 |= SSI_CR0_TIE ) +#define ssi_disable_txfifo_half_empty_intr() ( SSI_CR0 &= ~SSI_CR0_TIE ) +#define ssi_enable_tx_error_intr() ( SSI_CR0 |= SSI_CR0_TEIE ) +#define ssi_disable_tx_error_intr() ( SSI_CR0 &= ~SSI_CR0_TEIE ) + +#define ssi_enable_rxfifo_half_full_intr() ( SSI_CR0 |= SSI_CR0_RIE ) +#define ssi_disable_rxfifo_half_full_intr() ( SSI_CR0 &= ~SSI_CR0_RIE ) +#define ssi_enable_rx_error_intr() ( SSI_CR0 |= SSI_CR0_REIE ) +#define ssi_disable_rx_error_intr() ( SSI_CR0 &= ~SSI_CR0_REIE ) + +#define ssi_enable_loopback() ( SSI_CR0 |= SSI_CR0_LOOP ) +#define ssi_disable_loopback() ( SSI_CR0 &= ~SSI_CR0_LOOP ) + +#define ssi_enable_receive() ( SSI_CR0 &= ~SSI_CR0_DISREV ) +#define ssi_disable_receive() ( SSI_CR0 |= SSI_CR0_DISREV ) + +#define ssi_finish_receive() ( SSI_CR0 |= (SSI_CR0_RFINE | SSI_CR0_RFINC) ) + +#define ssi_disable_recvfinish() ( SSI_CR0 &= ~(SSI_CR0_RFINE | SSI_CR0_RFINC) ) + +#define ssi_flush_txfifo() ( SSI_CR0 |= SSI_CR0_TFLUSH ) +#define ssi_flush_rxfifo() ( SSI_CR0 |= SSI_CR0_RFLUSH ) + +#define ssi_flush_fifo() ( SSI_CR0 |= SSI_CR0_TFLUSH | SSI_CR0_RFLUSH ) + +#define ssi_finish_transmit() ( SSI_CR1 &= ~SSI_CR1_UNFIN ) + +static void ssi_spi_format(): + SSI_CR1 &= ~SSI_CR1_FMAT_MASK + SSI_CR1 |= SSI_CR1_FMAT_SPI + SSI_CR1 &= ~(SSI_CR1_TFVCK_MASK|SSI_CR1_TCKFI_MASK) + SSI_CR1 |= (SSI_CR1_TFVCK_1 | SSI_CR1_TCKFI_1) + +// TI's SSP format, must clear SSI_CR1.UNFIN +static void ssi_ssp_format (): + SSI_CR1 &= ~(SSI_CR1_FMAT_MASK | SSI_CR1_UNFIN) + SSI_CR1 |= SSI_CR1_FMAT_SSP + +// National's Microwire format, must clear SSI_CR0.RFINE, and set max delay +static void ssi_microwire_format (): + SSI_CR1 &= ~SSI_CR1_FMAT_MASK + SSI_CR1 |= SSI_CR1_FMAT_MW1 + SSI_CR1 &= ~(SSI_CR1_TFVCK_MASK|SSI_CR1_TCKFI_MASK) + SSI_CR1 |= (SSI_CR1_TFVCK_3 | SSI_CR1_TCKFI_3) + SSI_CR0 &= ~SSI_CR0_RFINE + +// CE# level (FRMHL), CE# in interval time (ITFRM), clock phase and polarity (PHA POL), interval time (SSIITR), interval characters/frame (SSIICR) +// frmhl,endian,mcom,flen,pha,pol MASK +#define SSICR1_MISC_MASK ( SSI_CR1_FRMHL_MASK | SSI_CR1_LFST | SSI_CR1_MCOM_MASK | SSI_CR1_FLEN_MASK | SSI_CR1_PHA | SSI_CR1_POL ) +static void ssi_spi_set_misc (unsigned frmhl, unsigned endian, unsigned flen, unsigned mcom, unsigned pha, unsigned pol): + SSI_CR1 &= ~SSICR1_MISC_MASK + SSI_CR1 |= ((frmhl) << 30) | ((endian) << 25) | (((mcom) - 1) << 12) | (((flen) - 2) << 4) | ((pha) << 1) | (pol) + +// Transfer with MSB or LSB first +#define ssi_set_msb() ( SSI_CR1 &= ~SSI_CR1_LFST ) +#define ssi_set_lsb() ( SSI_CR1 |= SSI_CR1_LFST ) + +#define ssi_set_frame_length(n) SSI_CR1 = (SSI_CR1 & ~SSI_CR1_FLEN_MASK) | (((n) - 2) << 4) + +// n = 1 - 16 +#define ssi_set_microwire_command_length(n) ( SSI_CR1 = ((SSI_CR1 & ~SSI_CR1_MCOM_MASK) | SSI_CR1_MCOM_##n##BIT) ) + +// Set the clock phase for SPI +#define ssi_set_spi_clock_phase(n) ( SSI_CR1 = ((SSI_CR1 & ~SSI_CR1_PHA) | ((n&0x1)<< 1))) + +// Set the clock polarity for SPI +#define ssi_set_spi_clock_polarity(n) ( SSI_CR1 = ((SSI_CR1 & ~SSI_CR1_POL) | (n&0x1)) ) + +// n = ix8 +#define ssi_set_tx_trigger(n) do { SSI_CR1 &= ~SSI_CR1_TTRG_MASK; SSI_CR1 |= SSI_CR1_TTRG_##n; } while (0) + +// n = ix8 +#define ssi_set_rx_trigger(n) do { SSI_CR1 &= ~SSI_CR1_RTRG_MASK; SSI_CR1 |= SSI_CR1_RTRG_##n; } while (0) + +#define ssi_get_txfifo_count() ( (SSI_SR & SSI_SR_TFIFONUM_MASK) >> SSI_SR_TFIFONUM_BIT ) + +#define ssi_get_rxfifo_count() ( (SSI_SR & SSI_SR_RFIFONUM_MASK) >> SSI_SR_RFIFONUM_BIT ) + +#define ssi_clear_errors() ( SSI_SR &= ~(SSI_SR_UNDR | SSI_SR_OVER) ) + +#define ssi_transfer_end() ( SSI_SR & SSI_SR_END ) +#define ssi_is_busy() ( SSI_SR & SSI_SR_BUSY ) + +#define ssi_txfifo_full() ( SSI_SR & SSI_SR_TFF ) +#define ssi_rxfifo_empty() ( SSI_SR & SSI_SR_RFE ) +#define ssi_rxfifo_noempty() ( SSI_SR & SSI_SR_RFHF ) + +#define ssi_set_clk(dev_clk, ssi_clk) ( SSI_GR = (dev_clk) / (2*(ssi_clk)) - 1 ) + +#define ssi_receive_data() SSI_DR +#define ssi_transmit_data(v) ( SSI_DR = (v) ) + + +//************************************************************************** +// CIM +//************************************************************************** + +#define cim_enable() ( CIM_CTRL |= CIM_CTRL_ENA ) +#define cim_disable() ( CIM_CTRL &= ~CIM_CTRL_ENA ) + +#define cim_input_data_inverse() ( CIM_CFG |= CIM_CFG_INV_DAT ) +#define cim_input_data_normal() ( CIM_CFG &= ~CIM_CFG_INV_DAT ) + +#define cim_vsync_active_low() ( CIM_CFG |= CIM_CFG_VSP ) +#define cim_vsync_active_high() ( CIM_CFG &= ~CIM_CFG_VSP ) + +#define cim_hsync_active_low() ( CIM_CFG |= CIM_CFG_HSP ) +#define cim_hsync_active_high() ( CIM_CFG &= ~CIM_CFG_HSP ) + +#define cim_sample_data_at_pclk_falling_edge() ( CIM_CFG |= CIM_CFG_PCP ) +#define cim_sample_data_at_pclk_rising_edge() ( CIM_CFG &= ~CIM_CFG_PCP ) + +#define cim_enable_dummy_zero() ( CIM_CFG |= CIM_CFG_DUMMY_ZERO ) +#define cim_disable_dummy_zero() ( CIM_CFG &= ~CIM_CFG_DUMMY_ZERO ) + +#define cim_select_external_vsync() ( CIM_CFG |= CIM_CFG_EXT_VSYNC ) +#define cim_select_internal_vsync() ( CIM_CFG &= ~CIM_CFG_EXT_VSYNC ) + +// n=0-7 +#define cim_set_data_packing_mode(n) do { CIM_CFG &= ~CIM_CFG_PACK_MASK; CIM_CFG |= (CIM_CFG_PACK_##n); } while (0) + +static void cim_enable_ccir656_progressive_mode (): + CIM_CFG &= ~CIM_CFG_DSM_MASK + CIM_CFG |= CIM_CFG_DSM_CPM + +static void cim_enable_ccir656_interlace_mode (): + CIM_CFG &= ~CIM_CFG_DSM_MASK + CIM_CFG |= CIM_CFG_DSM_CIM + +static void cim_enable_gated_clock_mode (): + CIM_CFG &= ~CIM_CFG_DSM_MASK + CIM_CFG |= CIM_CFG_DSM_GCM + +static void cim_enable_nongated_clock_mode (): + CIM_CFG &= ~CIM_CFG_DSM_MASK + CIM_CFG |= CIM_CFG_DSM_NGCM + +// sclk:system bus clock +// mclk: CIM master clock +#define cim_set_master_clk(sclk, mclk) do { CIM_CTRL &= ~CIM_CTRL_MCLKDIV_MASK; CIM_CTRL |= (((sclk)/(mclk) - 1) << CIM_CTRL_MCLKDIV_BIT); } while (0) + +#define cim_enable_sof_intr() ( CIM_CTRL |= CIM_CTRL_DMA_SOFM ) +#define cim_disable_sof_intr() ( CIM_CTRL &= ~CIM_CTRL_DMA_SOFM ) + +#define cim_enable_eof_intr() ( CIM_CTRL |= CIM_CTRL_DMA_EOFM ) +#define cim_disable_eof_intr() ( CIM_CTRL &= ~CIM_CTRL_DMA_EOFM ) + +#define cim_enable_stop_intr() ( CIM_CTRL |= CIM_CTRL_DMA_STOPM ) +#define cim_disable_stop_intr() ( CIM_CTRL &= ~CIM_CTRL_DMA_STOPM ) + +#define cim_enable_trig_intr() ( CIM_CTRL |= CIM_CTRL_RXF_TRIGM ) +#define cim_disable_trig_intr() ( CIM_CTRL &= ~CIM_CTRL_RXF_TRIGM ) + +#define cim_enable_rxfifo_overflow_intr() ( CIM_CTRL |= CIM_CTRL_RXF_OFM ) +#define cim_disable_rxfifo_overflow_intr() ( CIM_CTRL &= ~CIM_CTRL_RXF_OFM ) + +// n=1-16 +#define cim_set_frame_rate(n) do { CIM_CTRL &= ~CIM_CTRL_FRC_MASK; CIM_CTRL |= CIM_CTRL_FRC_##n; } while (0) + +#define cim_enable_dma() ( CIM_CTRL |= CIM_CTRL_DMA_EN ) +#define cim_disable_dma() ( CIM_CTRL &= ~CIM_CTRL_DMA_EN ) + +#define cim_reset_rxfifo() ( CIM_CTRL |= CIM_CTRL_RXF_RST ) +#define cim_unreset_rxfifo() ( CIM_CTRL &= ~CIM_CTRL_RXF_RST ) + +// n=4,8,12,16,20,24,28,32 +#define cim_set_rxfifo_trigger(n) do { CIM_CTRL &= ~CIM_CTRL_RXF_TRIG_MASK; CIM_CTRL |= CIM_CTRL_RXF_TRIG_##n; } while (0) + +#define cim_clear_state() ( CIM_STATE = 0 ) + +#define cim_disable_done() ( CIM_STATE & CIM_STATE_VDD ) +#define cim_rxfifo_empty() ( CIM_STATE & CIM_STATE_RXF_EMPTY ) +#define cim_rxfifo_reach_trigger() ( CIM_STATE & CIM_STATE_RXF_TRIG ) +#define cim_rxfifo_overflow() ( CIM_STATE & CIM_STATE_RXF_OF ) +#define cim_clear_rxfifo_overflow() ( CIM_STATE &= ~CIM_STATE_RXF_OF ) +#define cim_dma_stop() ( CIM_STATE & CIM_STATE_DMA_STOP ) +#define cim_dma_eof() ( CIM_STATE & CIM_STATE_DMA_EOF ) +#define cim_dma_sof() ( CIM_STATE & CIM_STATE_DMA_SOF ) + +#define cim_get_iid() ( CIM_IID ) +#define cim_get_image_data() ( CIM_RXFIFO ) +#define cim_get_dam_cmd() ( CIM_CMD ) + +#define cim_set_da(a) ( CIM_DA = (a) ) + +//************************************************************************** +// LCD +//************************************************************************** +#define lcd_as_smart_lcd() ( LCD_CFG |= (1<> LCD_VSYNC_VPS_BIT ) + +#define lcd_vsync_get_vpe() ( (LCD_VSYNC & LCD_VSYNC_VPE_MASK) >> LCD_VSYNC_VPE_BIT ) +#define lcd_vsync_set_vpe(n) do { LCD_VSYNC &= ~LCD_VSYNC_VPE_MASK; LCD_VSYNC |= (n) << LCD_VSYNC_VPE_BIT; } while (0) + +#define lcd_hsync_get_hps() ( (LCD_HSYNC & LCD_HSYNC_HPS_MASK) >> LCD_HSYNC_HPS_BIT ) +#define lcd_hsync_set_hps(n) do { LCD_HSYNC &= ~LCD_HSYNC_HPS_MASK; LCD_HSYNC |= (n) << LCD_HSYNC_HPS_BIT; } while (0) + +#define lcd_hsync_get_hpe() ( (LCD_HSYNC & LCD_HSYNC_HPE_MASK) >> LCD_VSYNC_HPE_BIT ) +#define lcd_hsync_set_hpe(n) do { LCD_HSYNC &= ~LCD_HSYNC_HPE_MASK; LCD_HSYNC |= (n) << LCD_HSYNC_HPE_BIT; } while (0) + +#define lcd_vat_get_ht() ( (LCD_VAT & LCD_VAT_HT_MASK) >> LCD_VAT_HT_BIT ) +#define lcd_vat_set_ht(n) do { LCD_VAT &= ~LCD_VAT_HT_MASK; LCD_VAT |= (n) << LCD_VAT_HT_BIT; } while (0) + +#define lcd_vat_get_vt() ( (LCD_VAT & LCD_VAT_VT_MASK) >> LCD_VAT_VT_BIT ) +#define lcd_vat_set_vt(n) do { LCD_VAT &= ~LCD_VAT_VT_MASK; LCD_VAT |= (n) << LCD_VAT_VT_BIT; } while (0) + +#define lcd_dah_get_hds() ( (LCD_DAH & LCD_DAH_HDS_MASK) >> LCD_DAH_HDS_BIT ) +#define lcd_dah_set_hds(n) do { LCD_DAH &= ~LCD_DAH_HDS_MASK; LCD_DAH |= (n) << LCD_DAH_HDS_BIT; } while (0) + +#define lcd_dah_get_hde() ( (LCD_DAH & LCD_DAH_HDE_MASK) >> LCD_DAH_HDE_BIT ) +#define lcd_dah_set_hde(n) do { LCD_DAH &= ~LCD_DAH_HDE_MASK; LCD_DAH |= (n) << LCD_DAH_HDE_BIT; } while (0) + +#define lcd_dav_get_vds() ( (LCD_DAV & LCD_DAV_VDS_MASK) >> LCD_DAV_VDS_BIT ) +#define lcd_dav_set_vds(n) do { LCD_DAV &= ~LCD_DAV_VDS_MASK; LCD_DAV |= (n) << LCD_DAV_VDS_BIT; } while (0) + +#define lcd_dav_get_vde() ( (LCD_DAV & LCD_DAV_VDE_MASK) >> LCD_DAV_VDE_BIT ) +#define lcd_dav_set_vde(n) do { LCD_DAV &= ~LCD_DAV_VDE_MASK; LCD_DAV |= (n) << LCD_DAV_VDE_BIT; } while (0) + +#define lcd_cmd0_set_sofint() ( LCD_CMD0 |= LCD_CMD_SOFINT ) +#define lcd_cmd0_clr_sofint() ( LCD_CMD0 &= ~LCD_CMD_SOFINT ) +#define lcd_cmd1_set_sofint() ( LCD_CMD1 |= LCD_CMD_SOFINT ) +#define lcd_cmd1_clr_sofint() ( LCD_CMD1 &= ~LCD_CMD_SOFINT ) + +#define lcd_cmd0_set_eofint() ( LCD_CMD0 |= LCD_CMD_EOFINT ) +#define lcd_cmd0_clr_eofint() ( LCD_CMD0 &= ~LCD_CMD_EOFINT ) +#define lcd_cmd1_set_eofint() ( LCD_CMD1 |= LCD_CMD_EOFINT ) +#define lcd_cmd1_clr_eofint() ( LCD_CMD1 &= ~LCD_CMD_EOFINT ) + +#define lcd_cmd0_set_pal() ( LCD_CMD0 |= LCD_CMD_PAL ) +#define lcd_cmd0_clr_pal() ( LCD_CMD0 &= ~LCD_CMD_PAL ) + +#define lcd_cmd0_get_len() ( (LCD_CMD0 & LCD_CMD_LEN_MASK) >> LCD_CMD_LEN_BIT ) +#define lcd_cmd1_get_len() ( (LCD_CMD1 & LCD_CMD_LEN_MASK) >> LCD_CMD_LEN_BIT ) + +//************************************************************************** +// RTC ops +//************************************************************************** + +#define rtc_write_ready() ( (RTC_RCR & RTC_RCR_WRDY) >> RTC_RCR_WRDY_BIT ) +#define rtc_enabled() ( RTC_RCR |= RTC_RCR_RTCE ) +#define rtc_disabled() ( RTC_RCR &= ~RTC_RCR_RTCE ) +#define rtc_enable_alarm() ( RTC_RCR |= RTC_RCR_AE ) +#define rtc_disable_alarm() ( RTC_RCR &= ~RTC_RCR_AE ) +#define rtc_enable_alarm_irq() ( RTC_RCR |= RTC_RCR_AIE ) +#define rtc_disable_alarm_irq() ( RTC_RCR &= ~RTC_RCR_AIE ) +#define rtc_enable_1Hz_irq() ( RTC_RCR |= RTC_RCR_1HZIE ) +#define rtc_disable_1Hz_irq() ( RTC_RCR &= ~RTC_RCR_1HZIE ) + +#define rtc_get_1Hz_flag() ( (RTC_RCR >> RTC_RCR_1HZ_BIT) & 0x1 ) +#define rtc_clear_1Hz_flag() ( RTC_RCR &= ~RTC_RCR_1HZ ) +#define rtc_get_alarm_flag() ( (RTC_RCR >> RTC_RCR_AF_BIT) & 0x1 ) +#define rtc_clear_alarm_flag() ( RTC_RCR &= ~RTC_RCR_AF ) + +#define rtc_get_second() ( RTC_RSR ) +#define rtc_set_second(v) ( RTC_RSR = v ) + +#define rtc_get_alarm_second() ( RTC_RSAR ) +#define rtc_set_alarm_second(v) ( RTC_RSAR = v ) + +#define rtc_RGR_is_locked() ( (RTC_RGR >> RTC_RGR_LOCK) ) +#define rtc_lock_RGR() ( RTC_RGR |= RTC_RGR_LOCK ) +#define rtc_unlock_RGR() ( RTC_RGR &= ~RTC_RGR_LOCK ) +#define rtc_get_adjc_val() ( (RTC_RGR & RTC_RGR_ADJC_MASK) >> RTC_RGR_ADJC_BIT ) +#define rtc_set_adjc_val(v) ( RTC_RGR = ( (RTC_RGR & ~RTC_RGR_ADJC_MASK) | (v << RTC_RGR_ADJC_BIT) )) +#define rtc_get_nc1Hz_val() ( (RTC_RGR & RTC_RGR_NC1HZ_MASK) >> RTC_RGR_NC1HZ_BIT ) +#define rtc_set_nc1Hz_val(v) ( RTC_RGR = ( (RTC_RGR & ~RTC_RGR_NC1HZ_MASK) | (v << RTC_RGR_NC1HZ_BIT) )) + +#define rtc_power_down() ( RTC_HCR |= RTC_HCR_PD ) + +#define rtc_get_hwfcr_val() ( RTC_HWFCR & RTC_HWFCR_MASK ) +#define rtc_set_hwfcr_val(v) ( RTC_HWFCR = (v) & RTC_HWFCR_MASK ) +#define rtc_get_hrcr_val() ( RTC_HRCR & RTC_HRCR_MASK ) +#define rtc_set_hrcr_val(v) ( RTC_HRCR = (v) & RTC_HRCR_MASK ) + +#define rtc_enable_alarm_wakeup() ( RTC_HWCR |= RTC_HWCR_EALM ) +#define rtc_disable_alarm_wakeup() ( RTC_HWCR &= ~RTC_HWCR_EALM ) + +#define rtc_status_hib_reset_occur() ( (RTC_HWRSR >> RTC_HWRSR_HR) & 0x1 ) +#define rtc_status_ppr_reset_occur() ( (RTC_HWRSR >> RTC_HWRSR_PPR) & 0x1 ) +#define rtc_status_wakeup_pin_waken_up() ( (RTC_HWRSR >> RTC_HWRSR_PIN) & 0x1 ) +#define rtc_status_alarm_waken_up() ( (RTC_HWRSR >> RTC_HWRSR_ALM) & 0x1 ) +#define rtc_clear_hib_stat_all() ( RTC_HWRSR = 0 ) + +#define rtc_get_scratch_pattern() (RTC_HSPR) +#define rtc_set_scratch_pattern(n) (RTC_HSPR = n ) + + + +#endif diff --git a/mips/nanonote/nanonote-boot.ccp b/mips/nanonote/nanonote-boot.ccp new file mode 100644 index 0000000..2960825 --- /dev/null +++ b/mips/nanonote/nanonote-boot.ccp @@ -0,0 +1,188 @@ +#pypp 0 +// Iris: micro-kernel for a capability-based operating system. +// mips/nanonote/nanonote-boot.ccp: Host-side helper for booting over USB. +// Copyright 2009 Bas Wijnen +// +// 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 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include + +asm volatile (".section .rodata\n" + ".globl stage1\n" + ".globl stage1_end\n" + "stage1:\n" + ".incbin \"mips/nanonote/sdram-setup.raw\"\n" + "stage1_end:\n" + ".section .text") +extern char stage1[1] +extern char stage1_end[1] + +unsigned const stage1_load = 0x80002000 +unsigned const stage1_start = 0x80002000 +unsigned const stage1_size = stage1_end - stage1 + +class nanonote: + public: + + nanonote (unsigned skip = 0) + void boot (std::string const &data, unsigned load, unsigned start) + + private: + + enum requests: + VR_GET_CPU_INFO = 0 + VR_SET_DATA_ADDRESS = 1 + VR_SET_DATA_LENGTH = 2 + VR_FLUSH_CACHES = 3 + VR_PROGRAM_START1 = 4 + VR_PROGRAM_START2 = 5 + static int const vendor = 0x601a + static int const product = 0x4740 + static unsigned const timeout = 1000 + usb_dev_handle *handle + int interface + int in_ep, out_ep + std::string cpu_info + bool try_open (struct usb_device *dev) + bool find_device (unsigned skip) + void request (requests num, unsigned data = 0) + void send_file (unsigned address, unsigned size, char const *data) + void get_cpu_info () + +bool nanonote::try_open (struct usb_device *dev): + handle = usb_open (dev) + + if dev->descriptor.bNumConfigurations != 1: + usb_close (handle) + std::cerr << dev->descriptor.bNumConfigurations << " configurations\n" + return false + if usb_set_configuration (handle, 1) < 0: + usb_close (handle) + std::cerr << "Can't set configuration 1: " << usb_strerror () << '\n' + return false + + interface = dev->config->interface->altsetting->bInterfaceNumber + int have_in = 0, have_out = 0 + for unsigned i = 0; i < dev->config->interface->altsetting->bNumEndpoints; ++i: + if (dev->config->interface->altsetting->endpoint[i].bmAttributes & USB_ENDPOINT_TYPE_MASK) != USB_ENDPOINT_TYPE_BULK: + usb_close (handle) + std::cerr << "Device has non-bulk endpoint.\n" + return false + if (dev->config->interface->altsetting->endpoint[i].bEndpointAddress & USB_ENDPOINT_DIR_MASK): + /* input */ + if have_in: + usb_close (handle) + std::cerr << "Device has multiple IN endpoints.\n" + return false + have_in = 1 + in_ep = dev->config->interface->altsetting->endpoint[i].bEndpointAddress & USB_ENDPOINT_ADDRESS_MASK + if in_ep != 1: + usb_close (handle) + std::cerr << "IN endpoint is not numbered as 1.\n" + return false + else: + /* output */ + if have_out: + usb_close (handle) + std::cerr << "Device has multiple OUT endpoints.\n" + return false + have_out = 1 + out_ep = dev->config->interface->altsetting->endpoint[i].bEndpointAddress & USB_ENDPOINT_ADDRESS_MASK + if out_ep != 1: + usb_close (handle) + std::cerr << "OUT endpoint is not numbered as 1.\n" + return false + if usb_claim_interface (handle, interface) < 0: + std::cerr << "unable to claim interface\n" + return false + return true + +bool nanonote::find_device (unsigned skip): + unsigned skipped = 0 + usb_init () + usb_find_busses () + usb_find_devices () + for struct usb_bus *bus = usb_busses; bus; bus = bus->next: + for struct usb_device *dev = bus->devices; dev; dev = dev->next: + if dev->descriptor.idProduct != product || dev->descriptor.idVendor != vendor: + continue + if skip > skipped++: + continue + if try_open (dev): + return true + return false + +nanonote::nanonote (unsigned skip): + if !find_device (skip): + std::cerr << "unable to find NanoNote device.\n"; + throw "unable to find NanoNote device"; + +void nanonote::get_cpu_info (): + char buffer[8] + if usb_control_msg (handle, USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, VR_GET_CPU_INFO, 0, 0, buffer, 8, timeout) < 0: + std::cerr << "unable to request cpu info from NanoNote: " << usb_strerror () << ".\n" + throw "unable to request cpu info from NanoNote" + cpu_info = std::string (buffer, 8) + +void nanonote::request (requests r, unsigned data): + std::cerr << "requesting " << r << " (data = " << std::hex << data << ")" << std::endl + if usb_control_msg (handle, USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, r, (data >> 16) & 0xffff, data & 0xffff, NULL, 0, timeout) < 0: + std::cerr << "unable to send control message to NanoNote: " << usb_strerror () << ".\n" + throw "unable to send control message to NanoNote" + +void nanonote::send_file (unsigned address, unsigned size, char const *data): + request (VR_SET_DATA_ADDRESS, address) + //request (VR_SET_DATA_LENGTH, size) + char const *ptr = data + while ptr - data < size: + int ret = usb_bulk_write (handle, out_ep, ptr, size - (ptr - data), timeout) + if ret <= 0: + std::cerr << "failed to write to NanoNote.\n" + throw "failed to write to NanoNote" + ptr += ret + +void nanonote::boot (std::string const &data, unsigned load, unsigned start): + get_cpu_info () + std::cerr << "info: " << cpu_info << std::endl + send_file (stage1_load, stage1_size, stage1) + request (VR_PROGRAM_START1, stage1_start) + usleep (100) + send_file (load, data.size (), data.data ()) + request (VR_FLUSH_CACHES) + request (VR_PROGRAM_START2, start) + get_cpu_info () + std::cerr << "info: " << cpu_info << std::endl + +int main (int argc, char **argv): + if argc != 3: + std::cerr << "Usage: " << argv[0] << " [kernel] [entry address]\n" + std::cerr << "The kernel is loaded from 0x80000000 and run from entry address\n" + return 1 + unsigned entry = strtoul (argv[2], NULL, 0) + nanonote nn + std::ifstream file (argv[1]) + if !file: + std::cerr << "can't open file '" << argv[1] << "' for reading.\n" + return 1 + std::ostringstream data + data << file.rdbuf () + if data.str ().empty (): + std::cerr << "no data read from '" << argv[1] << "'.\n" + return 1 + nn.boot (data.str (), 0x80000000, entry) + return 0 diff --git a/mips/nanonote/sdram-setup.ccp b/mips/nanonote/sdram-setup.ccp new file mode 100644 index 0000000..94fd1b5 --- /dev/null +++ b/mips/nanonote/sdram-setup.ccp @@ -0,0 +1,136 @@ +#pypp 0 +// Iris: micro-kernel for a capability-based operating system. +// mips/nanonote/sdram-setup.ccp: bootstrapping over usb. +// Copyright 2009 Bas Wijnen +// +// 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 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// This runs like the kernel. In particular, it doesn't want userspace declarations. +#define __KERNEL +#include "jz4740.hh" + +#define CONFIG_NR_DRAM_BANKS 1 // SDRAM BANK Number: 1, 2 +#define SDRAM_CASL 3 // CAS latency: 2 or 3 +// SDRAM Timings, unit: ns +#define SDRAM_TRAS 45 // RAS# Active Time +#define SDRAM_RCD 20 // RAS# to CAS# Delay +#define SDRAM_TPC 20 // RAS# Precharge Time +#define SDRAM_TRWL 7 // Write Latency Time +#define SDRAM_TREF 15625 // Refresh period: 4096 refresh cycles/64ms + +asm volatile (".set noreorder\n" + "\t.globl __start\n" + "\t.text\n" + "__start:\n" + "\tla $sp, 0x80004000\n" + "__hack_label:\n" + "\tmove $a0, $ra\n" + "\tbal 1f\n" + "\tnop\n" + "\t.word _gp\n" + "1:\n" + "\tlw $gp, 0($ra)\n" + "\tla $t9, start_cpp\n" + "\tmove $ra, $a0\n" + "\tjr $t9\n" + "\tnop\n" + ".set reorder") + +extern "C": + void start_cpp () + +void start_cpp (): + unsigned dmcr0, dmcr, sdmode, tmp, cpu_clk, mem_clk, ns + unsigned cas_latency_sdmr[2] = { EMC_SDMR_CAS_2, EMC_SDMR_CAS_3 } + unsigned cas_latency_dmcr[2] = { 1 << EMC_DMCR_TCL_BIT, 2 << EMC_DMCR_TCL_BIT } + int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32} + + cpu_clk = 225000000 + gpio_as_sdram_32bit () + unsigned SDRAM_BW16 = 0 + unsigned SDRAM_BANK4 = 1 + unsigned SDRAM_ROW = 13 + unsigned SDRAM_COL = 9 + + mem_clk = cpu_clk * div[cpm_get_cdiv()] / div[cpm_get_mdiv()] + EMC_BCR = 0 + EMC_RTCSR = 0 + #define SDRAM_ROW0 11 + #define SDRAM_COL0 8 + #define SDRAM_BANK40 0 + dmcr0 = ((SDRAM_ROW0-11)< 11: + tmp = 11 + dmcr |= ((tmp-4) << EMC_DMCR_TRAS_BIT) + tmp = SDRAM_RCD/ns + if tmp > 3: + tmp = 3 + dmcr |= (tmp << EMC_DMCR_RCD_BIT) + tmp = SDRAM_TPC/ns + if tmp > 7: + tmp = 7 + dmcr |= (tmp << EMC_DMCR_TPC_BIT) + tmp = SDRAM_TRWL/ns + if tmp > 3: + tmp = 3 + dmcr |= (tmp << EMC_DMCR_TRWL_BIT) + tmp = (SDRAM_TRAS + SDRAM_TPC)/ns + if tmp > 14: + tmp = 14 + dmcr |= (((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT) + + // SDRAM mode value + sdmode = EMC_SDMR_BT_SEQ | EMC_SDMR_OM_NORMAL | EMC_SDMR_BL_4 | cas_latency_sdmr[((SDRAM_CASL == 3) ? 1 : 0)]; + + // Stage 1. Precharge all banks by writing SDMR with DMCR.MRSET=0 + EMC_DMCR = dmcr + REG8(EMC_SDMR0|sdmode) = 0 + + // Wait for precharge, > 200us + tmp = (cpu_clk / 1000000) * 1000 + volatile unsigned t = tmp + while t--: + + // Stage 2. Enable auto-refresh + EMC_DMCR = dmcr | EMC_DMCR_RFSH + + tmp = SDRAM_TREF/ns + tmp = tmp/64 + 1 + if tmp > 0xff: + tmp = 0xff + EMC_RTCOR = tmp + EMC_RTCNT = 0 + // Divisor is 64, CKO/64 + EMC_RTCSR = EMC_RTCSR_CKS_64 + + // Wait for number of auto-refresh cycles + tmp = (cpu_clk / 1000000) * 1000 + t = tmp + while t--: + + // Stage 3. Mode Register Set + EMC_DMCR = dmcr0 | EMC_DMCR_RFSH | EMC_DMCR_MRSET + REG8(EMC_SDMR0|sdmode) = 0 + + // Set back to basic DMCR value + EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET + + // everything is ok now: return to boot loader to load stage 2. diff --git a/mips/nanonote/sdram-setup.ld b/mips/nanonote/sdram-setup.ld new file mode 100644 index 0000000..2cfa90f --- /dev/null +++ b/mips/nanonote/sdram-setup.ld @@ -0,0 +1,31 @@ +OUTPUT_ARCH(mips) +ENTRY(__start) +MEMORY +{ + ram : ORIGIN = 0x80002000 , LENGTH = 0x100000 +} + +SECTIONS +{ + . = ALIGN(4); + .text : { *(.text*) } > ram + + . = ALIGN(4); + .rodata : { *(.rodata*) } > ram + + . = ALIGN(4); + .sdata : { *(.sdata*) } > ram + + . = ALIGN(4); + .data : { *(.data*) *(.scommon*) *(.reginfo*) } > ram + + _gp = ABSOLUTE(.); /* Base of small data */ + + .got : { *(.got*) } > ram + + . = ALIGN(4); + .sbss : { *(.sbss*) } > ram + .bss : { *(.bss*) } > ram + . = ALIGN (4); +} + diff --git a/mips/nanonote/threadlist.S b/mips/nanonote/threadlist.S new file mode 100644 index 0000000..66deb6e --- /dev/null +++ b/mips/nanonote/threadlist.S @@ -0,0 +1,38 @@ +// Iris: micro-kernel for a capability-based operating system. +// mips/nanonote/threadlist.S: List of initial threads. +// Copyright 2009 Bas Wijnen +// +// 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 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + + .globl init_start + .globl thread_start + .set noreorder + + .balign 0x1000 +thread0: + .incbin "init" + + .balign 0x1000 +thread1: + .incbin "udc" + +thread2: + +// Everything from here may be freed after kernel initialization. +init_start: + +thread_start: + .word thread0 + .word thread1 + .word thread2 diff --git a/mips/trendtac/Makefile.arch b/mips/trendtac/Makefile.arch new file mode 100644 index 0000000..92d5538 --- /dev/null +++ b/mips/trendtac/Makefile.arch @@ -0,0 +1,61 @@ +# Iris: micro-kernel for a capability-based operating system. +# mips/trendtac/Makefile.arch: board-specific parts of the build rules +# Copyright 2009 Bas Wijnen +# +# 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 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +load = 0x80000000 + +ARCH_CXXFLAGS = -DNUM_THREADS=3 +ARCH_CPPFLAGS = -Imips -Wa,-mips32 +CROSS = mipsel-linux-gnu- +OBJDUMP = $(CROSS)objdump +junk = mdebug.abi32 reginfo comment pdr +OBJCOPYFLAGS = $(addprefix --remove-section=.,$(junk)) + +arch_iris_sources = mips/interrupts.cc mips/arch.cc +boot_sources = mips/init.cc +arch_headers = mips/arch.hh mips/jz4730.hh +boot_threads = init gpio lcd + +uimage: + +mips/boot.o: TARGET_FLAGS = -DMEMORY_SIZE = "128 << 20" +mips/threadlist.o: $(boot_threads) +mips/init.o: TARGET_FLAGS = -I/usr/include +$(boot_threads): TARGET_FLAGS = -I. +$(addprefix boot-programs/,$(addsuffix .cc,$(boot_threads))): boot-programs/devices.hh boot-programs/init.hh +lcd: boot-programs/charset.data + +boot-programs/charset.data: boot-programs/charset + $< > $@ + +# Transform ':' into ';' so vim doesn't think there are errors. +uimage: iris.raw.gz Makefile mips/Makefile.arch + mkimage -A MIPS -O Linux -C gzip -a $(load) -e 0xa$(shell /bin/sh -c '$(OBJDUMP) -t iris | grep __start$$ | cut -b2-8') -n "Iris" -d $< $@ | sed -e 's/:/;/g' + +%.o:%.S Makefile Makefile.arch mips/arch.hh + $(CC) $(CPPFLAGS) $(TARGET_FLAGS) -DKERNEL_STACK_SIZE=0x2000 -c $< -o $@ + +# entry.o must be the first file. threadlist.o must be the first of the init objects (which can be freed after loading). +iris: mips/entry.o $(subst .cc,.o,$(iris_sources)) mips/trendtac/threadlist.o mips/boot.o $(subst .cc,.o,$(boot_sources)) + $(LD) --omagic -Ttext $(load) $^ -o $@ + +%.raw: % + $(OBJCOPY) -S $(OBJCOPYFLAGS) -Obinary $< $@ + +%.gz: % + gzip < $< > $@ + +ARCH_CLEAN_FILES = uimage $(boot_threads) mips/*.o boot-programs/charset.data iris iris.raw iris.raw.gz diff --git a/mips/trendtac/board.ccp b/mips/trendtac/board.ccp new file mode 100644 index 0000000..515c0dc --- /dev/null +++ b/mips/trendtac/board.ccp @@ -0,0 +1,57 @@ +#pypp 0 +// Iris: micro-kernel for a capability-based operating system. +// mips/trendtac/board.ccp: trendtac-specific functions. +// Copyright 2009 Bas Wijnen +// +// 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 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +void board_init (): + // Disable all gpio interrupts and alternate functions initially. + for unsigned i = 0; i < 4; ++i: + GPIO_GPIER (i) = 0 + GPIO_GPALR (i) = 0 + GPIO_GPAUR (i) = 0 + // Set up the rest of the hardware (copied from Linux). + cpm_idle_mode () + cpm_enable_cko1 () + cpm_start_all () + harb_set_priority (0x08) + dmac_enable_all_channels () + harb_usb0_uhc () + gpio_as_emc () + gpio_as_uart0 () + gpio_as_dma () + gpio_as_eth () + gpio_as_usb () + gpio_as_lcd_master () + gpio_as_ssi() + gpio_as_msc () + + gpio_as_gpio (GPIO_CAPS_PORT, GPIO_CAPS) + gpio_as_gpio (GPIO_SCROLL_PORT, GPIO_SCROLL) + gpio_as_gpio (GPIO_NUM_PORT, GPIO_NUM) + gpio_as_gpio (GPIO_TP_LEFT_PORT, GPIO_TP_LEFT) + gpio_as_gpio (GPIO_TP_RIGHT_PORT, GPIO_TP_RIGHT) + + // Start the operating system timer, and set it to give an interrupt immediately. + // This is better, because the kernel starts with jumping into the idle task and + // waiting for the first interrupt. + unsigned latch = (JZ_EXTAL + (HZ >> 1)) / HZ + ost_disable_all () + ost_set_mode (0, OST_TCSR_UIE | OST_TCSR_CKS_EXTAL) + ost_set_reload (0, latch) + ost_set_count (0, 1) + ost_set_mode (0, OST_TCSR_UIE | OST_TCSR_CKS_EXTAL) + ost_enable_channel (0) + intc_unmask_irq (IRQ_OST0) diff --git a/mips/jz4730.hhp b/mips/trendtac/jz4730.hhp similarity index 99% rename from mips/jz4730.hhp rename to mips/trendtac/jz4730.hhp index dd69953..844ad41 100644 --- a/mips/jz4730.hhp +++ b/mips/trendtac/jz4730.hhp @@ -25,6 +25,8 @@ #define JZ_EXTAL 3686400 // RTC clock #define RTC_CLOCK 32768 +// The interrupt source that is used for the system timer +#define TIMER_INTERRUPT IRQ_OST0 // Physical addresses are where they really are. #define HARB_PHYSICAL 0x13000000 diff --git a/mips/trendtac/threadlist.S b/mips/trendtac/threadlist.S new file mode 100644 index 0000000..4a83691 --- /dev/null +++ b/mips/trendtac/threadlist.S @@ -0,0 +1,43 @@ +// Iris: micro-kernel for a capability-based operating system. +// mips/trendtac/threadlist.S: Kernel entry point, called by the boot loader. +// Copyright 2009 Bas Wijnen +// +// 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 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + + .globl init_start + .globl thread_start + .set noreorder + + .balign 0x1000 +thread0: + .incbin "init" + + .balign 0x1000 +thread1: + .incbin "lcd" + + .balign 0x1000 +thread2: + .incbin "gpio" + +thread3: + +// Everything from here may be freed after kernel initialization. +init_start: + +thread_start: + .word thread0 + .word thread1 + .word thread2 + .word thread3 diff --git a/panic.ccp b/panic.ccp index 6e3bcce..3a35686 100644 --- a/panic.ccp +++ b/panic.ccp @@ -19,6 +19,11 @@ #define ARCH #include "kernel.hh" +#ifdef USE_SERIAL +void dbg_log_char (unsigned ch): + while !(UART0_LSR & UARTLSR_TDRQ): + UART0_TDR = ch +#else void dbg_log_char (unsigned ch): if !dbg_cap.valid (): return @@ -27,6 +32,7 @@ void dbg_log_char (unsigned ch): ++dbg_code.l dbg_cap->invoke (&c) --dbg_code.l +#endif void dbg_log (char const *str): while *str: