diff options
author | Vic (Chun-Ju) Yang <victoryang@chromium.org> | 2013-11-05 18:50:10 +0800 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2013-11-21 04:30:55 +0000 |
commit | 14c7191b53607e46187cea6e95ebf869f3b85e2a (patch) | |
tree | 7eccaa37279665a6c67b46c9b43cd814bb34837c | |
parent | 5524ba7bf71b8ee520f3c8410b65b5bba07544c4 (diff) | |
download | chrome-ec-14c7191b53607e46187cea6e95ebf869f3b85e2a.tar.gz |
mec1322: initial commit
This is the initial commit of mec1322 support. This includes:
- Basic GPIO driver. Interrupt not supported yet.
- Microsecond timer
- UART driver
The script to pack the firmware binary will be checked in in
following-up CL.
BUG=chrome-os-partner:24107
TEST=Build and boot on eval board
BRANCH=None
Change-Id: I9013c908049d1f740f84bb56abca51b779f39eef
Signed-off-by: Vic (Chun-Ju) Yang <victoryang@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/175716
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r-- | board/mec1322_evb/board.c | 27 | ||||
-rw-r--r-- | board/mec1322_evb/board.h | 45 | ||||
-rw-r--r-- | board/mec1322_evb/build.mk | 12 | ||||
-rw-r--r-- | board/mec1322_evb/ec.tasklist | 21 | ||||
-rw-r--r-- | chip/lm4/registers.h | 2 | ||||
-rw-r--r-- | chip/mec1322/build.mk | 15 | ||||
-rw-r--r-- | chip/mec1322/clock.c | 38 | ||||
-rw-r--r-- | chip/mec1322/config_chip.h | 94 | ||||
-rw-r--r-- | chip/mec1322/gpio.c | 116 | ||||
-rw-r--r-- | chip/mec1322/hwtimer.c | 109 | ||||
-rw-r--r-- | chip/mec1322/jtag.c | 13 | ||||
-rw-r--r-- | chip/mec1322/registers.h | 152 | ||||
-rw-r--r-- | chip/mec1322/system.c | 71 | ||||
-rw-r--r-- | chip/mec1322/uart.c | 154 | ||||
-rw-r--r-- | chip/stm32/registers.h | 2 | ||||
-rw-r--r-- | include/common.h | 1 | ||||
-rw-r--r-- | include/gpio.h | 6 |
17 files changed, 873 insertions, 5 deletions
diff --git a/board/mec1322_evb/board.c b/board/mec1322_evb/board.c new file mode 100644 index 0000000000..d2638056a3 --- /dev/null +++ b/board/mec1322_evb/board.c @@ -0,0 +1,27 @@ +/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +/* MEC1322 eval board-specific configuration */ + +#include "gpio.h" +#include "registers.h" +#include "util.h" + +/* GPIO signal list. Must match order from enum gpio_signal. */ +const struct gpio_info gpio_list[] = { + {"LED1", GPIO_PORT(15), (1 << 4), GPIO_ODR_LOW, NULL}, + {"LED2", GPIO_PORT(15), (1 << 5), GPIO_ODR_HIGH, NULL}, + {"LED3", GPIO_PORT(15), (1 << 6), GPIO_ODR_LOW, NULL}, + /* Unimplemented signals which we need to emulate for now */ + GPIO_SIGNAL_NOT_IMPLEMENTED("RECOVERYn"), + GPIO_SIGNAL_NOT_IMPLEMENTED("WP"), + GPIO_SIGNAL_NOT_IMPLEMENTED("ENTERING_RW"), +}; +BUILD_ASSERT(ARRAY_SIZE(gpio_list) == GPIO_COUNT); + +/* Pins with alternate functions */ +const struct gpio_alt_func gpio_alt_funcs[] = { + {GPIO_PORT(16), 0x24, 1, MODULE_UART}, /* UART0 */ +}; +const int gpio_alt_funcs_count = ARRAY_SIZE(gpio_alt_funcs); diff --git a/board/mec1322_evb/board.h b/board/mec1322_evb/board.h new file mode 100644 index 0000000000..269cb4fb9d --- /dev/null +++ b/board/mec1322_evb/board.h @@ -0,0 +1,45 @@ +/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* MEC1322 eval board configuration */ + +#ifndef __BOARD_H +#define __BOARD_H + +/* Optional features */ +#define CONFIG_SYSTEM_UNLOCKED /* Allow dangerous commands */ + +/* Modules we want to exclude */ +#undef CONFIG_EEPROM +#undef CONFIG_EOPTION +#undef CONFIG_PSTORE +#undef CONFIG_LID_SWITCH +#undef CONFIG_LPC +#undef CONFIG_PECI +#undef CONFIG_SWITCH +#undef CONFIG_WATCHDOG + +#ifndef __ASSEMBLER__ + +/* GPIO signal list */ +enum gpio_signal { + GPIO_LED1 = 0, + GPIO_LED2, + GPIO_LED3, + /* + * Signals which aren't implemented on MEC1322 eval board but we'll + * emulate anyway, to make it more convenient to debug other code. + */ + GPIO_RECOVERYn, /* Recovery signal from DOWN button */ + GPIO_WP, /* Write protect input */ + GPIO_ENTERING_RW, /* EC entering RW code */ + + /* Number of GPIOs; not an actual GPIO */ + GPIO_COUNT +}; + +#endif /* !__ASSEMBLER__ */ + +#endif /* __BOARD_H */ diff --git a/board/mec1322_evb/build.mk b/board/mec1322_evb/build.mk new file mode 100644 index 0000000000..5f03511802 --- /dev/null +++ b/board/mec1322_evb/build.mk @@ -0,0 +1,12 @@ +# -*- makefile -*- +# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +# +# Board specific files build +# + +# the IC is SMSC MEC1322 +CHIP:=mec1322 + +board-y=board.o diff --git a/board/mec1322_evb/ec.tasklist b/board/mec1322_evb/ec.tasklist new file mode 100644 index 0000000000..d3ac489b42 --- /dev/null +++ b/board/mec1322_evb/ec.tasklist @@ -0,0 +1,21 @@ +/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/** + * List of enabled tasks in the priority order + * + * The first one has the lowest priority. + * + * For each task, use the macro TASK_ALWAYS(n, r, d, s) for base tasks and + * TASK_NOTEST(n, r, d, s) for tasks that can be excluded in test binaries, + * where : + * 'n' in the name of the task + * 'r' in the main routine of the task + * 'd' in an opaque parameter passed to the routine at startup + * 's' is the stack size in bytes; must be a multiple of 8 + */ +#define CONFIG_TASK_LIST \ + TASK_ALWAYS(HOOKS, hook_task, NULL, TASK_STACK_SIZE) \ + TASK_ALWAYS(CONSOLE, console_task, NULL, TASK_STACK_SIZE) diff --git a/chip/lm4/registers.h b/chip/lm4/registers.h index b87a7b55ec..8db3b2c71f 100644 --- a/chip/lm4/registers.h +++ b/chip/lm4/registers.h @@ -487,6 +487,8 @@ enum clock_gate_offsets { #define GPIO_P LM4_GPIO_P #define GPIO_Q LM4_GPIO_Q +#define DUMMY_GPIO_BANK GPIO_A + /* Value to write to LM4_GPIO_LOCK to unlock writes */ #define LM4_GPIO_LOCK_UNLOCK 0x4c4f434b diff --git a/chip/mec1322/build.mk b/chip/mec1322/build.mk new file mode 100644 index 0000000000..ae435bf8c6 --- /dev/null +++ b/chip/mec1322/build.mk @@ -0,0 +1,15 @@ +# -*- makefile -*- +# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +# +# MEC1322 chip specific files build +# + +# MEC1322 SoC has a Cortex-M4 ARM core +CORE:=cortex-m +# Allow the full Cortex-M4 instruction set +CFLAGS_CPU+=-march=armv7e-m -mcpu=cortex-m4 + +# Required chip modules +chip-y=clock.o gpio.o hwtimer.o system.o uart.o jtag.o diff --git a/chip/mec1322/clock.c b/chip/mec1322/clock.c new file mode 100644 index 0000000000..6111b7de86 --- /dev/null +++ b/chip/mec1322/clock.c @@ -0,0 +1,38 @@ +/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Clocks and power management settings */ + +#include "clock.h" +#include "common.h" +#include "console.h" +#include "registers.h" +#include "util.h" + +/* Console output macros */ +#define CPUTS(outstr) cputs(CC_CLOCK, outstr) +#define CPRINTF(format, args...) cprintf(CC_CLOCK, format, ## args) + +static int freq = 48000000; + +void clock_wait_cycles(uint32_t cycles) +{ + asm("1: subs %0, #1\n" + " bne 1b\n" :: "r"(cycles)); +} + +int clock_get_freq(void) +{ + return freq; +} + +void clock_init(void) +{ + /* XOSEL = Single ended clock source */ + MEC1322_VBAT_CE |= 0x1; + + /* 32K clock enable */ + MEC1322_VBAT_CE |= 0x2; +} diff --git a/chip/mec1322/config_chip.h b/chip/mec1322/config_chip.h new file mode 100644 index 0000000000..93cb2b4dda --- /dev/null +++ b/chip/mec1322/config_chip.h @@ -0,0 +1,94 @@ +/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef __CROS_EC_CONFIG_CHIP_H +#define __CROS_EC_CONFIG_CHIP_H + +/* CPU core BFD configuration */ +#include "core/cortex-m/config_core.h" + +/* Number of IRQ vectors on the NVIC */ +#define CONFIG_IRQ_COUNT 93 + +/* Use a bigger console output buffer */ +#undef CONFIG_UART_TX_BUF_SIZE +#define CONFIG_UART_TX_BUF_SIZE 2048 + +/* Interval between HOOK_TICK notifications */ +#define HOOK_TICK_INTERVAL (250 * MSEC) + +/* Maximum number of deferrable functions */ +#define DEFERRABLE_MAX_COUNT 8 + +/* Number of I2C ports */ +#define I2C_PORT_COUNT 4 + +/****************************************************************************/ +/* Memory mapping */ + +/* + * The memory region for RAM is actually 0x00100000-0x00120000. The lower 96K + * stores code and the higher 32K stores data. To reflect this, let's say + * the lower 96K is flash, and the higher 32K is RAM. + */ +#define CONFIG_RAM_BASE 0x00118000 +#define CONFIG_RAM_SIZE 0x00008000 + +/* System stack size */ +#define CONFIG_STACK_SIZE 4096 + +/* non-standard task stack sizes */ +#define IDLE_TASK_STACK_SIZE 512 +#define LARGER_TASK_STACK_SIZE 640 + +/* Default task stack size */ +#define TASK_STACK_SIZE 512 + +#define CONFIG_FLASH_BASE 0x00100000 + +#define CONFIG_FLASH_PHYSICAL_SIZE 0x00018000 + +/* Size of one firmware image in RAM */ + +/****************************************************************************/ +/* Define our flash layout. */ + +/* Size of one firmware image in flash */ +#ifndef CONFIG_FW_IMAGE_SIZE +#define CONFIG_FW_IMAGE_SIZE (CONFIG_FLASH_PHYSICAL_SIZE / 2) +#endif + +/* RO firmware must start at beginning of flash */ +#define CONFIG_FW_RO_OFF 0 + +#define CONFIG_FW_RO_SIZE CONFIG_FW_IMAGE_SIZE +#define CONFIG_FLASH_SIZE CONFIG_FLASH_PHYSICAL_SIZE + +/* Either way, RW firmware is one firmware image offset from the start */ +#define CONFIG_FW_RW_OFF CONFIG_FW_IMAGE_SIZE +#define CONFIG_FW_RW_SIZE CONFIG_FW_IMAGE_SIZE + +/* TODO(crosbug.com/p/23796): why 2 sets of configs with the same numbers? */ +#define CONFIG_FW_WP_RO_OFF CONFIG_FW_RO_OFF +#define CONFIG_FW_WP_RO_SIZE CONFIG_FW_RO_SIZE + +#define CONFIG_FLASH_BANK_SIZE 4 + +/****************************************************************************/ +/* Customize the build */ +/* Optional features present on this chip */ +#if 0 +#define CONFIG_ADC +#define CONFIG_I2C +#define CONFIG_LPC +#define CONFIG_PECI +#define CONFIG_SWITCH +#define CONFIG_MPU +#endif +#define CONFIG_FPU + +#undef CONFIG_FLASH + +#endif /* __CROS_EC_CONFIG_CHIP_H */ diff --git a/chip/mec1322/gpio.c b/chip/mec1322/gpio.c new file mode 100644 index 0000000000..065b4383ec --- /dev/null +++ b/chip/mec1322/gpio.c @@ -0,0 +1,116 @@ +/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* GPIO module for MEC1322 */ + +#include "common.h" +#include "gpio.h" +#include "registers.h" +#include "timer.h" +#include "util.h" + +void gpio_set_alternate_function(uint32_t port, uint32_t mask, int func) +{ + int i; + uint32_t val; + + while (mask) { + i = __builtin_ffs(mask) - 1; + val = MEC1322_GPIO_CTL(port, i); + val &= ~((1 << 12) | (1 << 13)); + val |= (func & 0x3) << 12; + MEC1322_GPIO_CTL(port, i) = val; + mask &= ~(1 << i); + } +} + +test_mockable int gpio_get_level(enum gpio_signal signal) +{ + uint32_t mask = gpio_list[signal].mask; + int i = 31 - __builtin_clz(mask); + uint32_t val = MEC1322_GPIO_CTL(gpio_list[signal].port, i); + + if (val & (1 << 9)) /* Output */ + return (val & (1 << 16)) ? 1 : 0; + else + return (val & (1 << 24)) ? 1 : 0; +} + +void gpio_set_level(enum gpio_signal signal, int value) +{ + uint32_t mask = gpio_list[signal].mask; + int i = 31 - __builtin_clz(mask); + if (value) + MEC1322_GPIO_CTL(gpio_list[signal].port, i) |= (1 << 16); + else + MEC1322_GPIO_CTL(gpio_list[signal].port, i) &= ~(1 << 16); +} + +void gpio_set_flags_by_mask(uint32_t port, uint32_t mask, uint32_t flags) +{ + int i; + uint32_t val; + while (mask) { + i = 31 - __builtin_clz(mask); + mask &= ~(1 << i); + val = MEC1322_GPIO_CTL(port, i); + + /* + * Select open drain first, so that we don't glitch the signal + * when changing the line to an output. + */ + if (flags & GPIO_OPEN_DRAIN) + val |= (1 << 8); + else + val &= ~(1 << 8); + + if (flags & GPIO_OUTPUT) { + val |= (1 << 9); + val &= ~(1 << 10); + } else { + val &= ~(1 << 9); + val |= (1 << 10); + } + + /* Handle pullup / pulldown */ + if (flags & GPIO_PULL_UP) + val = (val & ~0x3) | 0x1; + else if (flags & GPIO_PULL_DOWN) + val = (val & ~0x3) | 0x2; + else + val &= ~0x3; + + /* TODO(crosbug.com/p/24107): Set up interrupt */ + + /* Use as GPIO */ + val &= ~((1 << 12) | (1 << 13)); + + MEC1322_GPIO_CTL(port, i) = val; + + if (flags & GPIO_HIGH) + MEC1322_GPIO_CTL(port, i) |= (1 << 16); + else + MEC1322_GPIO_CTL(port, i) &= ~(1 << 16); + } +} + +int gpio_enable_interrupt(enum gpio_signal signal) +{ + return EC_ERROR_UNIMPLEMENTED; +} + +int gpio_disable_interrupt(enum gpio_signal signal) +{ + return EC_ERROR_UNIMPLEMENTED; +} + +void gpio_pre_init(void) +{ + int i; + const struct gpio_info *g = gpio_list; + + for (i = 0; i < GPIO_COUNT; i++, g++) + gpio_set_flags_by_mask(g->port, g->mask, g->flags); +} diff --git a/chip/mec1322/hwtimer.c b/chip/mec1322/hwtimer.c new file mode 100644 index 0000000000..51fa28647b --- /dev/null +++ b/chip/mec1322/hwtimer.c @@ -0,0 +1,109 @@ +/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Hardware timers driver */ + +#include "clock.h" +#include "common.h" +#include "hooks.h" +#include "hwtimer.h" +#include "registers.h" +#include "task.h" +#include "timer.h" + +void __hw_clock_event_set(uint32_t deadline) +{ + MEC1322_TMR32_CNT(1) = MEC1322_TMR32_CNT(0) - + (0xffffffff - deadline); + MEC1322_TMR32_CTL(1) |= (1 << 5); +} + +uint32_t __hw_clock_event_get(void) +{ + return MEC1322_TMR32_CNT(1) - MEC1322_TMR32_CNT(0) + 0xffffffff; +} + +void __hw_clock_event_clear(void) +{ + MEC1322_TMR32_CTL(1) &= ~(1 << 5); +} + +uint32_t __hw_clock_source_read(void) +{ + return 0xffffffff - MEC1322_TMR32_CNT(0); +} + +void __hw_clock_source_set(uint32_t ts) +{ + MEC1322_TMR32_CTL(0) &= ~(1 << 5); + MEC1322_TMR32_CNT(0) = 0xffffffff - ts; + MEC1322_TMR32_CTL(0) |= (1 << 5); +} + +static void __hw_clock_source_irq(int timer_id) +{ + if (timer_id == 1) + MEC1322_TMR32_STS(1) |= 1; + /* If IRQ is from timer 0, 32-bit timer overflowed */ + process_timers(timer_id == 0); +} + +static void __hw_clock_source_irq_0(void) { __hw_clock_source_irq(0); } +DECLARE_IRQ(MEC1322_IRQ_TIMER32_0, __hw_clock_source_irq_0, 1); +static void __hw_clock_source_irq_1(void) { __hw_clock_source_irq(1); } +DECLARE_IRQ(MEC1322_IRQ_TIMER32_1, __hw_clock_source_irq_1, 1); + +static void configure_timer(int timer_id) +{ + uint32_t val; + + /* Ensure timer is not running */ + MEC1322_TMR32_CTL(timer_id) &= ~(1 << 5); + + /* Enable timer */ + MEC1322_TMR32_CTL(timer_id) |= (1 << 0); + + val = MEC1322_TMR32_CTL(timer_id); + + /* Pre-scale = 48 -> 1MHz -> Period = 1us */ + val = (val & 0xffff) | (47 << 16); + + MEC1322_TMR32_CTL(timer_id) = val; + + /* Set preload to use the full 32 bits of the timer */ + MEC1322_TMR32_PRE(timer_id) = 0xffffffff; + + /* Enable interrupt */ + MEC1322_TMR32_IEN(timer_id) |= 1; +} + +int __hw_clock_source_init(uint32_t start_t) +{ + /* + * The timer can only fire interrupt when its value reaches zero. + * Therefore we need two timers: + * - Timer 0 as free running timer + * - Timer 1 as event timer + */ + configure_timer(0); + configure_timer(1); + + /* Override the count */ + MEC1322_TMR32_CNT(0) = 0xffffffff - start_t; + + /* Auto restart */ + MEC1322_TMR32_CTL(0) |= (1 << 3); + + /* Start counting in timer 0 */ + MEC1322_TMR32_CTL(0) |= (1 << 5); + + /* Enable interrupt */ + task_enable_irq(MEC1322_IRQ_TIMER32_0); + task_enable_irq(MEC1322_IRQ_TIMER32_1); + MEC1322_INT_ENABLE(23) |= (1 << 4) | (1 << 5); + MEC1322_INT_BLK_EN |= (1 << 23); + + return MEC1322_IRQ_TIMER32_1; +} diff --git a/chip/mec1322/jtag.c b/chip/mec1322/jtag.c new file mode 100644 index 0000000000..fdc2ed63cd --- /dev/null +++ b/chip/mec1322/jtag.c @@ -0,0 +1,13 @@ +/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +/* Settings to enable JTAG debugging */ + +#include "jtag.h" +#include "registers.h" + +void jtag_pre_init(void) +{ + /* Not implemented yet */ +} diff --git a/chip/mec1322/registers.h b/chip/mec1322/registers.h new file mode 100644 index 0000000000..1e7634267f --- /dev/null +++ b/chip/mec1322/registers.h @@ -0,0 +1,152 @@ +/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Register map for MEC1322 processor + */ + +#ifndef __CROS_EC_REGISTERS_H +#define __CROS_EC_REGISTERS_H + +#include "common.h" + +/* EC Chip Configuration */ +#define MEC1322_CHIP_BASE 0x400fff00 +#define MEC1322_CHIP_DEV_ID REG8(MEC1322_CHIP_BASE + 0x20) +#define MEC1322_CHIP_DEV_REV REG8(MEC1322_CHIP_BASE + 0x21) + + +/* EC Subsystem */ +#define MEC1322_EC_BASE 0x4000fc00 +#define MEC1322_EC_INT_CTRL REG32(MEC1322_EC_BASE + 0x18) + + +/* Interrupt aggregator */ +#define MEC1322_INT_BASE 0x4000c000 +#define MEC1322_INTx_BASE(x) (MEC1322_INT_BASE + ((x) - 8) * 0x14) +#define MEC1322_INT_SOURCE(x) REG32(MEC1322_INTx_BASE(x) + 0x0) +#define MEC1322_INT_ENABLE(x) REG32(MEC1322_INTx_BASE(x) + 0x4) +#define MEC1322_INT_RESULT(x) REG32(MEC1322_INTx_BASE(x) + 0x8) +#define MEC1322_INT_DISABLE(x) REG32(MEC1322_INTx_BASE(x) + 0xc) +#define MEC1322_INT_BLK_EN REG32(MEC1322_INT_BASE + 0x200) +#define MEC1322_INT_BLK_DIS REG32(MEC1322_INT_BASE + 0x204) +#define MEC1322_INT_BLK_IRQ REG32(MEC1322_INT_BASE + 0x208) + + +/* UART */ +#define MEC1322_UART_CONFIG_BASE 0x400f1f00 +#define MEC1322_UART_RUNTIME_BASE 0x400f1c00 + +#define MEC1322_UART_ACT REG8(MEC1322_UART_CONFIG_BASE + 0x30) +#define MEC1322_UART_CFG REG8(MEC1322_UART_CONFIG_BASE + 0xf0) + +/* DLAB=0 */ +#define MEC1322_UART_RB /*R*/ REG8(MEC1322_UART_RUNTIME_BASE + 0x0) +#define MEC1322_UART_TB /*W*/ REG8(MEC1322_UART_RUNTIME_BASE + 0x0) +#define MEC1322_UART_IER REG8(MEC1322_UART_RUNTIME_BASE + 0x1) +/* DLAB=1 */ +#define MEC1322_UART_PBRG0 REG8(MEC1322_UART_RUNTIME_BASE + 0x0) +#define MEC1322_UART_PBRG1 REG8(MEC1322_UART_RUNTIME_BASE + 0x1) + +#define MEC1322_UART_FCR /*W*/ REG8(MEC1322_UART_RUNTIME_BASE + 0x2) +#define MEC1322_UART_IIR /*R*/ REG8(MEC1322_UART_RUNTIME_BASE + 0x2) +#define MEC1322_UART_LCR REG8(MEC1322_UART_RUNTIME_BASE + 0x3) +#define MEC1322_UART_MCR REG8(MEC1322_UART_RUNTIME_BASE + 0x4) +#define MEC1322_UART_LSR REG8(MEC1322_UART_RUNTIME_BASE + 0x5) +#define MEC1322_UART_MSR REG8(MEC1322_UART_RUNTIME_BASE + 0x6) +#define MEC1322_UART_SCR REG8(MEC1322_UART_RUNTIME_BASE + 0x7) + + +/* GPIO */ +#define MEC1322_GPIO_BASE 0x40081000 +#define MEC1322_GPIO_PORT(x) (x) +#define GPIO_PORT(x) MEC1322_GPIO_PORT(x) +static inline uintptr_t gpio_port_base(int port_id) +{ + int oct = (port_id / 10) * 8 + port_id % 10; + return MEC1322_GPIO_BASE + oct * 0x20; +} +#define MEC1322_GPIO_CTL(port, id) REG32(gpio_port_base(port) + (id << 2)) + +#define DUMMY_GPIO_BANK GPIO_PORT(0) + + +/* Timer */ +#define MEC1322_TMR16_BASE(x) (0x40000c00 + (x) * 0x20) +#define MEC1322_TMR32_BASE(x) (0x40000c80 + (x) * 0x20) + +#define MEC1322_TMR16_CNT(x) REG32(MEC1322_TMR16_BASE(x) + 0x0) +#define MEC1322_TMR16_PRE(x) REG32(MEC1322_TMR16_BASE(x) + 0x4) +#define MEC1322_TMR16_STS(x) REG32(MEC1322_TMR16_BASE(x) + 0x8) +#define MEC1322_TMR16_IEN(x) REG32(MEC1322_TMR16_BASE(x) + 0xc) +#define MEC1322_TMR16_CTL(x) REG32(MEC1322_TMR16_BASE(x) + 0x10) +#define MEC1322_TMR32_CNT(x) REG32(MEC1322_TMR32_BASE(x) + 0x0) +#define MEC1322_TMR32_PRE(x) REG32(MEC1322_TMR32_BASE(x) + 0x4) +#define MEC1322_TMR32_STS(x) REG32(MEC1322_TMR32_BASE(x) + 0x8) +#define MEC1322_TMR32_IEN(x) REG32(MEC1322_TMR32_BASE(x) + 0xc) +#define MEC1322_TMR32_CTL(x) REG32(MEC1322_TMR32_BASE(x) + 0x10) + + +/* Watchdog */ +#define MEC1322_WDG_BASE 0x40000400 +#define MEC1322_WDG_LOAD REG16(MEC1322_WDG_BASE + 0x0) +#define MEC1322_WDG_CTL REG8(MEC1322_WDG_BASE + 0x4) +#define MEC1322_WDG_KICK REG8(MEC1322_WDG_BASE + 0x8) +#define MEC1322_WDG_CNT REG16(MEC1322_WDG_BASE + 0xc) + + +/* VBAT */ +#define MEC1322_VBAT_BASE 0x4000a400 +#define MEC1322_VBAT_STS REG32(MEC1322_VBAT_BASE + 0x0) +#define MEC1322_VBAT_CE REG32(MEC1322_VBAT_BASE + 0x8) + + +/* IRQ Numbers */ +#define MEC1322_IRQ_I2C_0 0 +#define MEC1322_IRQ_I2C_1 1 +#define MEC1322_IRQ_I2C_2 2 +#define MEC1322_IRQ_I2C_3 3 +#define MEC1322_IRQ_DMA_0 4 +#define MEC1322_IRQ_DMA_1 5 +#define MEC1322_IRQ_DMA_2 6 +#define MEC1322_IRQ_DMA_3 7 +#define MEC1322_IRQ_DMA_4 8 +#define MEC1322_IRQ_DMA_5 9 +#define MEC1322_IRQ_DMA_6 10 +#define MEC1322_IRQ_DMA_7 11 +#define MEC1322_IRQ_LPC 12 +#define MEC1322_IRQ_UART 13 +#define MEC1322_IRQ_EMI 14 +#define MEC1322_IRQ_ACPIEC0_IBF 15 +#define MEC1322_IRQ_ACPIEC0_OBF 16 +#define MEC1322_IRQ_TIMER16_0 49 +#define MEC1322_IRQ_TIMER16_1 50 +#define MEC1322_IRQ_TIMER16_2 51 +#define MEC1322_IRQ_TIMER16_3 52 +#define MEC1322_IRQ_TIMER32_0 53 +#define MEC1322_IRQ_TIMER32_1 54 +#define MEC1322_IRQ_GIRQ8 57 +#define MEC1322_IRQ_GIRQ9 58 +#define MEC1322_IRQ_GIRQ10 59 +#define MEC1322_IRQ_GIRQ11 60 +#define MEC1322_IRQ_GIRQ12 61 +#define MEC1322_IRQ_GIRQ13 62 +#define MEC1322_IRQ_GIRQ14 63 +#define MEC1322_IRQ_GIRQ15 64 +#define MEC1322_IRQ_GIRQ16 65 +#define MEC1322_IRQ_GIRQ17 66 +#define MEC1322_IRQ_GIRQ18 67 +#define MEC1322_IRQ_GIRQ19 68 +#define MEC1322_IRQ_GIRQ20 69 +#define MEC1322_IRQ_GIRQ21 70 +#define MEC1322_IRQ_GIRQ22 71 +#define MEC1322_IRQ_GIRQ23 72 +#define MEC1322_IRQ_DMA_8 81 +#define MEC1322_IRQ_DMA_9 82 +#define MEC1322_IRQ_DMA_10 83 +#define MEC1322_IRQ_DMA_11 84 +#define MEC1322_IRQ_PWM_WDT3 85 +#define MEC1322_IRQ_RTC 91 +#define MEC1322_IRQ_RTC_ALARM 92 + +#endif /* __CROS_EC_REGISTERS_H */ diff --git a/chip/mec1322/system.c b/chip/mec1322/system.c new file mode 100644 index 0000000000..f86f8e144f --- /dev/null +++ b/chip/mec1322/system.c @@ -0,0 +1,71 @@ +/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* System module for Chrome EC : MEC1322 hardware specific implementation */ + +#include "clock.h" +#include "common.h" +#include "console.h" +#include "cpu.h" +#include "host_command.h" +#include "registers.h" +#include "system.h" +#include "task.h" +#include "timer.h" +#include "util.h" + + +#define DUMMY(x) x {} +#define DUMMY_int(x) x { return 0; } + +DUMMY(void system_hibernate(uint32_t seconds, uint32_t microseconds)); +DUMMY_int(int system_get_vbnvcontext(uint8_t *block)); +DUMMY_int(int system_set_vbnvcontext(const uint8_t *block)); + +void system_pre_init(void) +{ + /* Enable direct NVIC */ + MEC1322_EC_INT_CTRL |= 1; +} + +void system_reset(int flags) +{ + /* Trigger watchdog in 1ms */ + MEC1322_WDG_LOAD = 1; + MEC1322_WDG_CTL |= 1; +} + +const char *system_get_chip_vendor(void) +{ + return "smsc"; +} + +const char *system_get_chip_name(void) +{ + switch (MEC1322_CHIP_DEV_ID) { + case 0x15: + return "mec1322"; + default: + return "unknown"; + } +} + +static char to_hex(int x) +{ + if (x >= 0 && x <= 9) + return '0' + x; + return 'a' + x - 10; +} + +const char *system_get_chip_revision(void) +{ + static char buf[3]; + uint8_t rev = MEC1322_CHIP_DEV_REV; + + buf[0] = to_hex(rev / 16); + buf[1] = to_hex(rev & 0xf); + buf[2] = '\0'; + return buf; +} diff --git a/chip/mec1322/uart.c b/chip/mec1322/uart.c new file mode 100644 index 0000000000..351541de9d --- /dev/null +++ b/chip/mec1322/uart.c @@ -0,0 +1,154 @@ +/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* UART module for MEC1322 */ + +#include "clock.h" +#include "common.h" +#include "console.h" +#include "gpio.h" +#include "lpc.h" +#include "registers.h" +#include "system.h" +#include "task.h" +#include "uart.h" +#include "util.h" + +static int init_done; + +int uart_init_done(void) +{ + return init_done; +} + +void uart_tx_start(void) +{ + /* If interrupt is already enabled, nothing to do */ + if (MEC1322_UART_IER & (1 << 1)) + return; + + /* + * Re-enable the transmit interrupt, then forcibly trigger the + * interrupt. This works around a hardware problem with the + * UART where the FIFO only triggers the interrupt when its + * threshold is _crossed_, not just met. + */ + MEC1322_UART_IER |= (1 << 1); + task_trigger_irq(MEC1322_IRQ_UART); +} + +void uart_tx_stop(void) +{ + MEC1322_UART_IER &= ~(1 << 1); +} + +void uart_tx_flush(void) +{ + /* Wait for transmit FIFO empty */ + while (!(MEC1322_UART_LSR & (1 << 5))) + ; +} + +int uart_tx_ready(void) +{ + /* + * TODO(crosbug.com/p/24107): This is FIFO empty bit instead of + * FIFO full bit? + */ + return MEC1322_UART_LSR & (1 << 5); +} + +int uart_rx_available(void) +{ + return MEC1322_UART_LSR & (1 << 0); +} + +void uart_write_char(char c) +{ + /* Wait for space in transmit FIFO. */ + while (!uart_tx_ready()) + ; + + MEC1322_UART_TB = c; +} + +int uart_read_char(void) +{ + return MEC1322_UART_RB; +} + +static void uart_clear_rx_fifo(int channel) +{ + MEC1322_UART_FCR = (1 << 0) | (1 << 1); +} + +void uart_disable_interrupt(void) +{ + task_disable_irq(MEC1322_IRQ_UART); +} + +void uart_enable_interrupt(void) +{ + task_enable_irq(MEC1322_IRQ_UART); +} + +/** + * Interrupt handler for UART + */ +static void uart_ec_interrupt(void) +{ + /* Read input FIFO until empty, then fill output FIFO */ + uart_process_input(); + uart_process_output(); +} +DECLARE_IRQ(MEC1322_IRQ_UART, uart_ec_interrupt, 1); + +void uart_init(void) +{ + /* Set UART to reset on VCC1_RESET instaed of nSIO_RESET */ + MEC1322_UART_CFG &= ~(1 << 1); + + /* Baud rate = 115200. 1.8432MHz clock. Divisor = 1 */ + + /* Set CLK_SRC = 0 */ + MEC1322_UART_CFG &= ~(1 << 0); + + /* Set DLAB = 1 */ + MEC1322_UART_LCR |= (1 << 7); + + /* PBRG0/PBRG1 */ + MEC1322_UART_PBRG0 = 1; + MEC1322_UART_PBRG1 = 0; + + /* Set DLAB = 0 */ + MEC1322_UART_LCR &= ~(1 << 7); + + /* Set word length to 8-bit */ + MEC1322_UART_LCR |= (1 << 0) | (1 << 1); + + /* Enable FIFO */ + MEC1322_UART_FCR = (1 << 0); + + /* Activate UART */ + MEC1322_UART_ACT |= (1 << 0); + + /* + clock_enable_peripheral(CGC_OFFSET_UART, mask, + CGC_MODE_RUN | CGC_MODE_SLEEP);*/ + + gpio_config_module(MODULE_UART, 1); + + /* + * Enable interrupts for UART0. + */ + uart_clear_rx_fifo(0); + MEC1322_UART_IER |= (1 << 0); + MEC1322_UART_MCR |= (1 << 3); + MEC1322_INT_ENABLE(15) |= (1 << 0); + MEC1322_INT_BLK_EN |= (1 << 15); + task_enable_irq(MEC1322_IRQ_UART); + + init_done = 1; +} diff --git a/chip/stm32/registers.h b/chip/stm32/registers.h index 71c254c992..ead13c58d1 100644 --- a/chip/stm32/registers.h +++ b/chip/stm32/registers.h @@ -214,6 +214,8 @@ typedef volatile struct timer_ctlr timer_ctlr_t; #define GPIO_G STM32_GPIOG_BASE #define GPIO_H STM32_GPIOH_BASE +#define DUMMY_GPIO_BANK GPIO_A + #if defined(CHIP_FAMILY_stm32l) #define STM32_GPIOA_BASE 0x40020000 #define STM32_GPIOB_BASE 0x40020400 diff --git a/include/common.h b/include/common.h index 06888191fe..b15b72e629 100644 --- a/include/common.h +++ b/include/common.h @@ -30,6 +30,7 @@ /* Macros to access registers */ #define REG32(addr) (*(volatile uint32_t *)(addr)) #define REG16(addr) (*(volatile uint16_t *)(addr)) +#define REG8(addr) (*(volatile uint8_t *)(addr)) /* * Define __aligned(n) and __packed if someone hasn't beat us to it. Linux diff --git a/include/gpio.h b/include/gpio.h index fc46e995ce..6b1f80fe99 100644 --- a/include/gpio.h +++ b/include/gpio.h @@ -71,11 +71,7 @@ struct gpio_info { extern const struct gpio_info gpio_list[]; /* Macro for signals which don't exist */ -#ifdef CHIP_lm4 -#define GPIO_SIGNAL_NOT_IMPLEMENTED(name) {name, LM4_GPIO_A, 0, 0, NULL} -#else -#define GPIO_SIGNAL_NOT_IMPLEMENTED(name) {name, GPIO_A, 0, 0, NULL} -#endif +#define GPIO_SIGNAL_NOT_IMPLEMENTED(name) {name, DUMMY_GPIO_BANK, 0, 0, NULL} /* GPIO alternate function structure, for use by board.c */ struct gpio_alt_func { |