hakim giydan (hgiydan@marvell.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/15508
-gerrit
commit 1a9aa6e1c95ecec8071d93fd25c9e8cf0e59697c Author: Hakim Giydan hgiydan@marvell.com Date: Wed Jun 29 18:52:21 2016 -0700
marvell/mvmap2315: add uart & pinconfig drivers
the pinconfig driver is for emulation only, the real driver comes later.
Change-Id: I89dee1bbf8b68460897f64bf673b328533e70cd4 Signed-off-by: Hakim Giydan hgiydan@marvell.com --- src/mainboard/marvell/rotor/Makefile.inc | 1 + src/mainboard/marvell/rotor/romstage.c | 63 ++++++++++++++ src/soc/marvell/mvmap2315/Kconfig | 5 ++ src/soc/marvell/mvmap2315/Makefile.inc | 2 + src/soc/marvell/mvmap2315/include/soc/addressmap.h | 1 + src/soc/marvell/mvmap2315/include/soc/pinconfig.h | 68 +++++++++++++++ src/soc/marvell/mvmap2315/include/soc/romstage.h | 23 +++++ src/soc/marvell/mvmap2315/include/soc/uart.h | 49 +++++++++++ src/soc/marvell/mvmap2315/pinconfig.c | 64 ++++++++++++++ src/soc/marvell/mvmap2315/romstage.c | 15 +++- src/soc/marvell/mvmap2315/uart.c | 97 ++++++++++++++++++++-- 11 files changed, 380 insertions(+), 8 deletions(-)
diff --git a/src/mainboard/marvell/rotor/Makefile.inc b/src/mainboard/marvell/rotor/Makefile.inc index cb318e5..9c8b8b9 100644 --- a/src/mainboard/marvell/rotor/Makefile.inc +++ b/src/mainboard/marvell/rotor/Makefile.inc @@ -20,4 +20,5 @@ ramstage-$(CONFIG_CHROMEOS) += chromeos.c
romstage-y += memlayout.ld romstage-y += reset.c +romstage-y += romstage.c romstage-$(CONFIG_CHROMEOS) += chromeos.c diff --git a/src/mainboard/marvell/rotor/romstage.c b/src/mainboard/marvell/rotor/romstage.c new file mode 100644 index 0000000..3d9f12a --- /dev/null +++ b/src/mainboard/marvell/rotor/romstage.c @@ -0,0 +1,63 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2016 Marvell, Inc. + * + * 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; version 2 of the License. + * + * 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. + */ + +#include "arch/io.h" +#include "soc/clock.h" +#include "soc/pinconfig.h" +#include "soc/romstage.h" + +static const struct mvmap2315_pinconfig serial_1_pin_cfg[] = { + { 165, 1 }, /* APB:UART2_TXD */ + { 166, 1 } /* APB:UART2_RXD */ +}; + +static const struct mvmap2315_pinconfig serial_2_pin_cfg[] = { + { 176, 1 }, /* APB:UART2_TXD */ + { 177, 1 } /* APB:UART2_RXD */ +}; + +static void initpinconfig(void) +{ + /* Minimal IOs needed for initial startup */ + setpinconfigiogroup(serial_1_pin_cfg, + (sizeof(serial_1_pin_cfg) / + sizeof(struct mvmap2315_pinconfig))); + setpinconfigiogroup(serial_2_pin_cfg, + (sizeof(serial_2_pin_cfg) / + sizeof(struct mvmap2315_pinconfig))); +} + +void romstage_mainboard_early_init(void) +{ + u32 reg; + + /* + * enable APB/UART0 & APB/UART1 clock, but note that in emulation, + * even though this configuration implies that we are selecting + * the reference clock for uart clock source, the top level emulation + * scripts re-route that clock source to a 160690Hz clock in order to + * get a rate that works for 9600 baud uart output + */ + + reg = read32(&mvmap2315_apmu_clk->uartclk0_clkgenconfig); + reg |= MVMAP2315_UART_CLK_EN; + write32(&mvmap2315_apmu_clk->uartclk0_clkgenconfig, reg); + + reg = read32(&mvmap2315_apmu_clk->uartclk1_clkgenconfig); + reg |= MVMAP2315_UART_CLK_EN; + write32(&mvmap2315_apmu_clk->uartclk1_clkgenconfig, reg); + + initpinconfig(); +} diff --git a/src/soc/marvell/mvmap2315/Kconfig b/src/soc/marvell/mvmap2315/Kconfig index cfa622e..b110392 100644 --- a/src/soc/marvell/mvmap2315/Kconfig +++ b/src/soc/marvell/mvmap2315/Kconfig @@ -34,4 +34,9 @@ if SOC_MARVELL_MVMAP2315 config EMULATION bool default n + +config CONSOLE_SERIAL_MVMAP2315_UART_ADDRESS + hex + depends on CONSOLE_SERIAL + default 0xE1060000 endif diff --git a/src/soc/marvell/mvmap2315/Makefile.inc b/src/soc/marvell/mvmap2315/Makefile.inc index d80453a..994c745 100644 --- a/src/soc/marvell/mvmap2315/Makefile.inc +++ b/src/soc/marvell/mvmap2315/Makefile.inc @@ -20,6 +20,7 @@ ramstage-y += gic.c ramstage-y += media.c ramstage-y += mmu_operations.c ramstage-y += monotonic_timer.c +ramstage-y += pinconfig.c ramstage-y += ramstage.c ramstage-y += soc.c ramstage-y += stage_entry.S @@ -30,6 +31,7 @@ romstage-y += cbmem.c romstage-y += clock.c romstage-y += media.c romstage-y += monotonic_timer.c +romstage-y += pinconfig.c romstage-y += power.c romstage-y += romstage_asm.S romstage-y += romstage.c diff --git a/src/soc/marvell/mvmap2315/include/soc/addressmap.h b/src/soc/marvell/mvmap2315/include/soc/addressmap.h index 6cf5db2..242c5c2 100644 --- a/src/soc/marvell/mvmap2315/include/soc/addressmap.h +++ b/src/soc/marvell/mvmap2315/include/soc/addressmap.h @@ -25,6 +25,7 @@ enum { MVMAP2315_MAIN_PLL_BASE = 0xE0125000, MVMAP2315_APMU_CLK_BASE = 0xE0125400, MVMAP2315_GENTIMER_BASE = 0xE0137000, + MVMAP2315_PADWRAP_BASE = 0xE0140000, MVMAP2315_TIMER0_BASE = 0xE1020000, MVMAP2315_MPMU_CLK_BASE = 0xEF000800, MVMAP2315_GICD_BASE = 0xF0401000, diff --git a/src/soc/marvell/mvmap2315/include/soc/pinconfig.h b/src/soc/marvell/mvmap2315/include/soc/pinconfig.h new file mode 100644 index 0000000..047145de --- /dev/null +++ b/src/soc/marvell/mvmap2315/include/soc/pinconfig.h @@ -0,0 +1,68 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2016 Marvell, Inc. + * + * This program is free software; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __PINCONFIG_H__ +#define __PINCONFIG_H__ + +#include <stdint.h> +#include <stdlib.h> +#include <types.h> + +#include <soc/addressmap.h> + +#define MVMAP2315_PADWRAP_FUNC_SEL (BIT(0) | BIT(1) | BIT(2)) +#define MVMAP2315_PADWRAP_PU_EN BIT(14) +#define MVMAP2315_PADWRAP_PD_EN BIT(13) +struct mvmap2315_padwrap_regs { + u32 io_pad_piocfg[72]; + u8 _reserved0[0xee0]; + u32 pc_pwrdwn_g29_pwrdn; + u32 pc_v18en_lvl_g29; + u32 vdd3p3_1p8_g29_reg_pwrdn; + u32 pc_pwrdwn_g30_pwrdn; + u32 pc_v18en_lvl_g30; + u32 vdd3p3_1p8_g30_reg_pwrdn; + u32 pc_pwrdwn_g31_pwrdn; + u32 pc_v18en_lvl_g31; + u32 vdd3p3_1p8_g31_reg_pwrdn; + u32 pc_pwrdwn_g32_pwrdn; + u32 pc_v18en_lvl_g32; + u32 vdd3p3_1p8_g32_reg_pwrdn; + u32 pc_pwrdwn_g33_pwrdn; + u32 pc_v18en_lvl_g33; + u32 vdd3p3_1p8_g33_reg_pwrdn; +}; + +check_member(mvmap2315_padwrap_regs, vdd3p3_1p8_g33_reg_pwrdn, 0x1038); +static struct mvmap2315_padwrap_regs * const mvmap2315_padwrap + = (void *)MVMAP2315_PADWRAP_BASE; + +struct mvmap2315_pinconfig { + u32 pad; + u32 function; + u32 pull_down_enable; + u32 pull_up_enable; + u32 pull_select; + + /* Add other pin config here if necessary + * (e.g., pullup, slew, etc) + */ +}; + +check_member(mvmap2315_pinconfig, pull_select, 0x10); +void setpinconfigiogroup(const struct mvmap2315_pinconfig *io_grp_pin_cfg, + int num_pins); + +#endif /* __PINCONFIG_H__ */ diff --git a/src/soc/marvell/mvmap2315/include/soc/romstage.h b/src/soc/marvell/mvmap2315/include/soc/romstage.h new file mode 100644 index 0000000..af9f891 --- /dev/null +++ b/src/soc/marvell/mvmap2315/include/soc/romstage.h @@ -0,0 +1,23 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2016 Marvell, Inc. + * + * 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; version 2 of the License. + * + * 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. + */ +#ifndef __SOC_MARVELL_MVMAP2315_ROMSTAGE_H__ +#define __SOC_MARVELL_MVMAP2315_ROMSTAGE_H__ + +#include <stdint.h> +#include <stdlib.h> + +void romstage_mainboard_early_init(void); + +#endif /* __SOC_MARVELL_MVMAP2315_ROMSTAGE_H__ */ diff --git a/src/soc/marvell/mvmap2315/include/soc/uart.h b/src/soc/marvell/mvmap2315/include/soc/uart.h new file mode 100644 index 0000000..569a5aa --- /dev/null +++ b/src/soc/marvell/mvmap2315/include/soc/uart.h @@ -0,0 +1,49 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2016 Marvell, Inc. + * + * 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; version 2 of the License. + * + * 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. + */ + +#ifndef __SOC_MARVELL_MVMAP2315_UART_H__ +#define __SOC_MARVELL_MVMAP2315_UART_H__ + +#include <stdint.h> +#include <stdlib.h> + +#define BAUDRATE 9600 +#define BUSSPD 1 + +extern u32 uart_num; + +struct mvmap2315_uart_regs { + union { + u32 thr; + u32 rbr; + u32 dll; + }; + union { + u32 ier; + u32 dlm; + }; + union { + u32 iir; + u32 fcr; + }; + u32 lcr; + u32 mcr; + u32 lsr; + u32 msr; +}; + +check_member(mvmap2315_uart_regs, msr, 0x18); + +#endif /* __SOC_MARVELL_MVMAP2315_UART_H__ */ diff --git a/src/soc/marvell/mvmap2315/pinconfig.c b/src/soc/marvell/mvmap2315/pinconfig.c new file mode 100644 index 0000000..19e7ca1 --- /dev/null +++ b/src/soc/marvell/mvmap2315/pinconfig.c @@ -0,0 +1,64 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2016 Marvell, Inc. + * + * 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; version 2 of the License. + * + * 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. + */ + +#include "arch/io.h" +#include <soc/pinconfig.h> + +static void setpinconfig(const struct mvmap2315_pinconfig *pinconfig) +{ + u32 reg; + u32 pad_num; + + if (!pinconfig) + return; + + /* pads < 160 are part of the MCU domain and not handled here */ + if (pinconfig->pad < 160) + return; + + pad_num = pinconfig->pad - 160; + + reg = read32(&mvmap2315_padwrap->io_pad_piocfg[pad_num]); + reg |= (pinconfig->function & MVMAP2315_PADWRAP_FUNC_SEL); + write32(&mvmap2315_padwrap->io_pad_piocfg[pad_num], reg); + + if (pinconfig->pull_select) { + reg = read32(&mvmap2315_padwrap->io_pad_piocfg[pad_num]); + + if (pinconfig->pull_up_enable) + reg |= MVMAP2315_PADWRAP_PU_EN; + else + reg &= ~MVMAP2315_PADWRAP_PU_EN; + + if (pinconfig->pull_down_enable) + reg |= MVMAP2315_PADWRAP_PD_EN; + else + reg &= ~MVMAP2315_PADWRAP_PD_EN; + + write32(&mvmap2315_padwrap->io_pad_piocfg[pad_num], reg); + } +} + +void setpinconfigiogroup(const struct mvmap2315_pinconfig *io_grp_pin_cfg, + int num_pins) +{ + int i; + + if (!io_grp_pin_cfg || !num_pins) + return; + + for (i = 0; i < num_pins; i++, io_grp_pin_cfg++) + setpinconfig(io_grp_pin_cfg); +} diff --git a/src/soc/marvell/mvmap2315/romstage.c b/src/soc/marvell/mvmap2315/romstage.c index 8924d01..6752461 100644 --- a/src/soc/marvell/mvmap2315/romstage.c +++ b/src/soc/marvell/mvmap2315/romstage.c @@ -13,11 +13,15 @@ * GNU General Public License for more details. */
+#include <console/console.h> +#include <console/uart.h> #include <program_loading.h> #include <soc/assert.h> #include <soc/clock.h> #include <soc/monotonic_timer.h> #include <soc/power.h> +#include <soc/romstage.h> +#include <soc/uart.h> #include <timestamp.h>
/* @@ -34,8 +38,14 @@ void main(void)
asm volatile ("bl cpu_enable_icache" : : : "r0", "r1");
+ romstage_mainboard_early_init(); + + uart_num = CONFIG_UART_FOR_CONSOLE; + console_init(); + asm volatile ("bl cpu_init" : : : "r0");
+ printk(BIOS_INFO, "Starting monotonic timer.\n"); start_monotonic_timer();
timestamp_add_now(TS_START_ROMSTAGE); @@ -63,7 +73,9 @@ void main(void)
static void romstage_continue(void) { - /* TODO: R4 Functionality to be added */ + uart_num = 1; + uart_init(uart_num); + printk(BIOS_INFO, "TODO: R4 Functionality to be added\n"); while (1) ; } @@ -73,6 +85,7 @@ void platform_prog_run(struct prog *prog) if (!prog_entry(prog)) __assert("ramstage entrypoint not found", __FILE__, __LINE__);
+ printk(BIOS_INFO, "powering AP core 0.\n"); start_ap_cores(prog_entry(prog)); romstage_continue(); } diff --git a/src/soc/marvell/mvmap2315/uart.c b/src/soc/marvell/mvmap2315/uart.c index a486ee4..fc986d8 100644 --- a/src/soc/marvell/mvmap2315/uart.c +++ b/src/soc/marvell/mvmap2315/uart.c @@ -14,33 +14,116 @@ * GNU General Public License for more details. */
-#include <console/uart.h> +#include <arch/io.h> +#include <assert.h> #include <boot/coreboot_tables.h> +#include <console/console.h> +#include <console/uart.h> +#include <drivers/uart/uart8250reg.h> +#include <soc/uart.h> + +u32 uart_num; + +static void mvmap2315_uart_tx_flush(struct mvmap2315_uart_regs *uart_ptr) +{ + while (!(read8(&uart_ptr->lsr) & UART8250_LSR_TEMT)) + ; +} + +static void mvmap2315_uart_init(struct mvmap2315_uart_regs *uart_ptr) +{ + const u8 line_config = UART8250_LCR_WLS_8; + u16 divisor = divisor = ((BUSSPD * 6250) + + (BAUDRATE / 2)) / BAUDRATE; + + mvmap2315_uart_tx_flush(uart_ptr); + /* Disable interrupts. */ + write8(&uart_ptr->ier, 0); + /* Enable access to divisor latches. */ + write8(&uart_ptr->lcr, UART8250_LCR_DLAB); + /* Set the divisor. */ + write8(&uart_ptr->dll, divisor & 0xff); + write8(&uart_ptr->dlm, (divisor >> 8) & 0xff); + /* Hide divisor latches and program line config. */ + write8(&uart_ptr->lcr, line_config); + /* Enable FIFOs, and clear receive and transmit. */ + write8(&uart_ptr->fcr, + UART8250_FCR_FIFO_EN | + UART8250_FCR_CLEAR_RCVR | + UART8250_FCR_CLEAR_XMIT); +} + +static void mvmap2315_uart_tx_byte(struct mvmap2315_uart_regs *uart_ptr, + unsigned char data) +{ + while (!(read8(&uart_ptr->lsr) & UART8250_LSR_THRE)) + ; + write8(&uart_ptr->thr, data); +} + +static int mvmap2315_uart_tst_byte(struct mvmap2315_uart_regs *uart_ptr) +{ + return (read8(&uart_ptr->lsr) & UART8250_LSR_DR) + == UART8250_LSR_DR; +} + +static unsigned char mvmap2315_uart_rx_byte( + struct mvmap2315_uart_regs *uart_ptr) +{ + if (!mvmap2315_uart_tst_byte(uart_ptr)) + return 0; + return read8(&uart_ptr->rbr); +} + +uintptr_t uart_platform_base(int idx) +{ + /* Default to UART 0 */ + unsigned int base = CONFIG_CONSOLE_SERIAL_MVMAP2315_UART_ADDRESS; + + assert((uart_num >= 0) && (uart_num < 2)); + base += uart_num * 0x1000; + return base; +}
void uart_init(int idx) { - /*TODO: implement uart_init */ + struct mvmap2315_uart_regs *uart_ptr = uart_platform_baseptr(idx); + + mvmap2315_uart_init(uart_ptr); }
void uart_tx_byte(int idx, unsigned char data) { - /*TODO: implement uart_tx_byte */ + struct mvmap2315_uart_regs *uart_ptr = uart_platform_baseptr(idx); + + mvmap2315_uart_tx_byte(uart_ptr, data); }
void uart_tx_flush(int idx) { - /*TODO: implement uart_tx_flush */ + struct mvmap2315_uart_regs *uart_ptr = uart_platform_baseptr(idx); + + mvmap2315_uart_tx_flush(uart_ptr); }
unsigned char uart_rx_byte(int idx) { - /*TODO: implement uart_rx_byte */ - return 0; + struct mvmap2315_uart_regs *uart_ptr = uart_platform_baseptr(idx); + + return mvmap2315_uart_rx_byte(uart_ptr); }
#if ENV_RAMSTAGE void uart_fill_lb(void *data) { - /*TODO: implement uart_fill_lb */ + struct lb_serial serial; + + serial.type = LB_SERIAL_TYPE_MEMORY_MAPPED; + serial.baseaddr = uart_platform_base(CONFIG_UART_FOR_CONSOLE); + serial.baud = default_baudrate(); + serial.regwidth = 4; + lb_add_serial(&serial, data); + + lb_add_console(LB_TAG_CONSOLE_SERIAL8250MEM, data); } #endif