hakim giydan (hgiydan@marvell.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/16149
-gerrit
commit 31b6d9ef0830e5b6d57e402a19c600c2f61c0579 Author: Hakim Giydan hgiydan@marvell.com Date: Wed Aug 17 13:53:32 2016 -0700
soc/marvell/mvmap2315: Add PMIC driver
Testing: booted successfully.
Change-Id: I168206585f403d2259efe424e563982be661df0b Signed-off-by: Hakim Giydan hgiydan@marvell.com --- src/soc/marvell/mvmap2315/Makefile.inc | 1 + src/soc/marvell/mvmap2315/bootblock.c | 29 ++- src/soc/marvell/mvmap2315/include/soc/addressmap.h | 2 + src/soc/marvell/mvmap2315/include/soc/pmic.h | 194 +++++++++++++++++++++ src/soc/marvell/mvmap2315/pmic.c | 125 +++++++++++++ 5 files changed, 349 insertions(+), 2 deletions(-)
diff --git a/src/soc/marvell/mvmap2315/Makefile.inc b/src/soc/marvell/mvmap2315/Makefile.inc index 69733bf..1e0cdac 100644 --- a/src/soc/marvell/mvmap2315/Makefile.inc +++ b/src/soc/marvell/mvmap2315/Makefile.inc @@ -27,6 +27,7 @@ bootblock-y += flash.c bootblock-y += load_validate.c bootblock-y += media.c bootblock-y += pinmux.c +bootblock-y += pmic.c bootblock-y += reset.c bootblock-y += timer.c bootblock-y += sdram.c diff --git a/src/soc/marvell/mvmap2315/bootblock.c b/src/soc/marvell/mvmap2315/bootblock.c index 8ad2eed..4b2fd2100 100644 --- a/src/soc/marvell/mvmap2315/bootblock.c +++ b/src/soc/marvell/mvmap2315/bootblock.c @@ -17,6 +17,7 @@ #include <stdint.h> #include <stdlib.h>
+#include <arch/io.h> #include <bootblock_common.h> #include <console/console.h> #include <timestamp.h> @@ -25,6 +26,7 @@ #include <soc/bdb.h> #include <soc/gic.h> #include <soc/load_validate.h> +#include <soc/pmic.h> #include <soc/uart.h>
void bootblock_soc_early_init(void) @@ -41,6 +43,7 @@ void bootblock_soc_early_init(void) void bootblock_soc_init(void) { struct bdb_pointer bdb_info; + u32 boot_path;
set_bdb_pointers((u8 *)MVMAP2315_BDB_LCM_BASE, &bdb_info);
@@ -49,8 +52,30 @@ void bootblock_soc_init(void)
apmu_start();
- printk(BIOS_DEBUG, "loading and validating MCU firmware.\n"); - load_and_validate(&bdb_info, MCU_FIRMWARE); + if (!(read32((void *)MVMAP2315_LOWPWR_REG) & MVMAP2315_LOWPWR_FLAG)) { + printk(BIOS_DEBUG, "loading and validating MCU firmware.\n"); + load_and_validate(&bdb_info, MCU_FIRMWARE); + mcu_start(); + boot_path = get_boot_path(); + } else { + printk(BIOS_DEBUG, "Low power restart. Skip MCU code load.\n"); + boot_path = get_boot_path(); + } + + switch (boot_path) { + case NO_BOOT: + no_boot(); + break; + case CHARGING_SCREEN: + charging_screen(); + break; + case FULL_BOOT: + full_boot(); + break; + } + + printk(BIOS_DEBUG, "Powering up the AP core0.\n"); + ap_start((void *)0xE0010000);
/* initializing UART1 to free UART0 to be used by romstage */ uart_num = 1; diff --git a/src/soc/marvell/mvmap2315/include/soc/addressmap.h b/src/soc/marvell/mvmap2315/include/soc/addressmap.h index 31f895f..e3ee304 100644 --- a/src/soc/marvell/mvmap2315/include/soc/addressmap.h +++ b/src/soc/marvell/mvmap2315/include/soc/addressmap.h @@ -36,10 +36,12 @@ #define MVMAP2315_MCU_SECCONFIG_BASE 0xED600000 #define MVMAP2315_APMU_PWRCTL_BASE 0xE012C000 #define MVMAP2315_LCM_REGS_BASE 0xE0130000 +#define MVMAP2315_CPU_BASE 0xF0410000
#define MVMAP2315_RAM_BASE 0x00000000 #define MVMAP2315_DEVICE_BASE 0x80000000 #define MVMAP2315_FLASH_BASE 0xFE000000 #define MVMAP2315_LCM_BASE 0xE0000000 +#define MVMAP2315_LOWPWR_REG 0xE0002000
#endif /* __SOC_MARVELL_MVMAP2315_ADDRESS_MAP_H__ */ diff --git a/src/soc/marvell/mvmap2315/include/soc/pmic.h b/src/soc/marvell/mvmap2315/include/soc/pmic.h new file mode 100644 index 0000000..01a6040 --- /dev/null +++ b/src/soc/marvell/mvmap2315/include/soc/pmic.h @@ -0,0 +1,194 @@ +/* + * 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_PMIC_H__ +#define __SOC_MARVELL_MVMAP2315_PMIC_H__ + +#include <soc/addressmap.h> +#include <types.h> + +#define MVMAP2315_LOWPWR_FLAG BIT(4) + +#define MVMAP2315_APGENCFG_SYSBARDISABLE BIT(1) +#define MVMAP2315_APGENCFG_BROADCASTINNER BIT(2) +#define MVMAP2315_APGENCFG_BROADCASTOUTER BIT(3) +#define MVMAP2315_APGENCFG_BROADCASTCACHEMAINT BIT(4) +#define MVMAP2315_APGENCFG_BROADCASTCACHEMAINTPOU BIT(5) +#define MVMAP2315_APCORECFG0_AA64NAA32 BIT(4) +struct mvmap2315_cpu_regs { + u32 fuse00; + u32 fuse01; + u32 fuse02; + u32 fuse03; + u32 fuse04; + u32 fuse05; + u32 fuse06; + u32 fuse07; + u32 fuse10; + u32 fuse11; + u32 fuse12; + u32 fuse13; + u32 fuse14; + u32 fuse15; + u32 fuse16; + u32 fuse17; + u8 _reserved0[0x20]; + u32 fuse20; + u32 fuse21; + u32 fuse22; + u32 fuse23; + u32 fuse24; + u32 fuse25; + u32 fuse26; + u32 fuse27; + u32 fuse30; + u32 fuse31; + u32 fuse32; + u32 fuse33; + u32 fuse34; + u32 fuse35; + u32 fuse36; + u32 fuse37; + u32 fuse40; + u32 fuse41; + u32 fuse42; + u32 fuse43; + u32 fuse44; + u32 fuse45; + u32 fuse46; + u32 fuse47; + u32 fuse50; + u32 fuse51; + u32 fuse52; + u32 fuse53; + u32 fuse54; + u32 fuse55; + u32 fuse56; + u32 fuse57; + u32 fuse60; + u32 fuse61; + u32 fuse62; + u32 fuse63; + u32 fuse64; + u32 fuse65; + u32 fuse66; + u32 fuse67; + u32 fuse70; + u32 fuse71; + u32 fuse72; + u32 fuse73; + u32 fuse74; + u32 fuse75; + u32 fuse76; + u32 fuse77; + u32 fuse80; + u32 fuse81; + u32 fuse82; + u32 fuse83; + u32 fuse84; + u32 fuse85; + u32 fuse86; + u32 fuse87; + u32 fuse90; + u32 fuse91; + u32 fuse92; + u32 fuse93; + u32 fuse94; + u32 fuse95; + u32 fuse96; + u32 fuse97; + u32 fuse100; + u32 fuse101; + u32 fuse102; + u32 fuse103; + u32 fuse104; + u32 fuse105; + u32 fuse106; + u32 fuse107; + u32 fuse110; + u32 fuse111; + u32 fuse112; + u32 fuse113; + u32 fuse114; + u32 fuse115; + u32 fuse116; + u32 fuse117; + u32 fuse120; + u32 fuse121; + u32 fuse122; + u32 fuse123; + u32 fuse124; + u32 fuse125; + u32 fuse126; + u32 fuse127; + u32 fuse130; + u32 fuse131; + u32 fuse132; + u32 fuse133; + u32 fuse134; + u32 fuse135; + u32 fuse136; + u32 fuse137; + u32 fuse140; + u32 fuse141; + u32 fuse142; + u32 fuse143; + u32 fuse144; + u32 fuse145; + u32 fuse146; + u32 fuse147; + u32 fuse150; + u32 fuse151; + u32 fuse152; + u32 fuse153; + u32 fuse154; + u32 fuse155; + u32 fuse156; + u32 fuse157; + u32 apgencfg; + u32 apcorecfg0; + u32 apcorecfg1; + u32 apcorecfg2; + u32 apcorecfg3; + u32 rvbaraddr_low0; + u32 rvbaraddr_low1; + u32 rvbaraddr_low2; + u32 rvbaraddr_low3; + u8 _reserved1[0x10]; + u32 rvbaraddr_high0; + u32 rvbaraddr_high1; + u32 rvbaraddr_high2; + u32 rvbaraddr_high3; + u32 highvecremap; +}; + +check_member(mvmap2315_cpu_regs, highvecremap, 0x264); +static struct mvmap2315_cpu_regs * const mvmap2315_cpu + = (void *)MVMAP2315_CPU_BASE; + +enum boot_options { + NO_BOOT = 0, + CHARGING_SCREEN = 1, + FULL_BOOT = 2 +}; + +void no_boot(void); +void full_boot(void); +void charging_screen(void); +void mcu_start(void); +void ap_start(void *entry); +u32 get_boot_path(void); + +#endif /* __SOC_MARVELL_MVMAP2315_PMIC_H__ */ diff --git a/src/soc/marvell/mvmap2315/pmic.c b/src/soc/marvell/mvmap2315/pmic.c new file mode 100644 index 0000000..f263804 --- /dev/null +++ b/src/soc/marvell/mvmap2315/pmic.c @@ -0,0 +1,125 @@ +/* + * 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 <stddef.h> +#include <stdint.h> +#include <stdlib.h> + +#include <arch/io.h> +#include <assert.h> +#include <console/console.h> +#include <soc/apmu.h> +#include <soc/clock.h> +#include <soc/pmic.h> + +static void syspwr_init(void) +{ + int result = 0; + + /* Start the PLLs */ + result |= apmu_set_pll(MAIN_PLL, D0, 2000); + result |= apmu_set_pll(CPU_PLL, D0, 2400); + result |= apmu_set_pll(MC_PLL, D0, 3200); + result |= apmu_set_pll(MCFLC_PLL, D0, 2133); + result |= apmu_set_pll(A2_PLL, D0, 1800); + result |= apmu_set_pll(GPU_PLL0, D0, 2000); + result |= apmu_set_pll(GPU_PLL1, D0, 2400); + result |= apmu_set_pll(MIPI_PLL, D0, 2000); + result |= apmu_set_pll(DISPLAY_PLL, D0, 1800); + + /* Start the peripheral devices */ + result |= apmu_set_dev(SDMMC, D0); + result |= apmu_set_dev(AES256, D0); + result |= apmu_set_dev(AP_AXI_HS, D0); + result |= apmu_set_dev(AP_UART0, D0); + result |= apmu_set_dev(AP_UART1, D0); + result |= apmu_set_dev(AP_M2M, D0); + result |= apmu_set_dev(AP_APB, D0); + result |= apmu_set_dev(AP_GIC, D0); + result |= apmu_set_dev(A2, D0); + result |= apmu_set_dev(MC, D0); + result |= apmu_set_dev(DDRPHY_0, D0); + result |= apmu_set_dev(DDRPHY_1, D0); + result |= apmu_set_dev(DDRPHY_2, D0); + result |= apmu_set_dev(DDRPHY_3, D0); + + if (result) + assert("ERRORS DURING system POWER-on"); +} + +void ap_start(void *entry) +{ + int result = 0; + + setbits_le32(&mvmap2315_cpu->apgencfg, + MVMAP2315_APGENCFG_BROADCASTINNER); + setbits_le32(&mvmap2315_cpu->apgencfg, + MVMAP2315_APGENCFG_BROADCASTOUTER); + clrbits_le32(&mvmap2315_cpu->apgencfg, + MVMAP2315_APGENCFG_BROADCASTCACHEMAINT); + setbits_le32(&mvmap2315_cpu->apgencfg, + MVMAP2315_APGENCFG_BROADCASTCACHEMAINTPOU); + setbits_le32(&mvmap2315_cpu->apgencfg, + MVMAP2315_APGENCFG_SYSBARDISABLE); + + result |= apmu_set_dev(APCPU_L2, D0); + + setbits_le32(&mvmap2315_cpu->apcorecfg0, + MVMAP2315_APCORECFG0_AA64NAA32); + + write32(&mvmap2315_cpu->rvbaraddr_low0, ((uintptr_t)entry) >> 2); + + write32(&mvmap2315_cpu->rvbaraddr_high0, 0); + + result |= apmu_set_dev(APCPU_0, D0); + + if (result) + assert("ERRORS DURING AP POWER-on"); +} + +void no_boot(void) +{ + /*TODO: impelement no_boot */ +} + +void charging_screen(void) +{ + /*TODO: impelement charging_screen */ +} + +void full_boot(void) +{ + printk(BIOS_DEBUG, "Powering up the system.\n"); + syspwr_init(); +} + +void mcu_start(void) +{ + int result = 0; + + result |= apmu_set_pll(APLL0, D0, APLL_589P824); + result |= apmu_set_clk(M4CLK, NOCHANGE, 4, SRCSEL_APLL0); + + if (result) + assert("ERRORS DURING MCU POWER-on"); + + clrbits_le32(&mvmap2315_mpmu_clk->resetmcu, MVMAP2315_MCU_RST_EN); + setbits_le32(&mvmap2315_mpmu_clk->resetmcu, MVMAP2315_MCU_RST_EN); +} + +u32 get_boot_path(void) +{ + return FULL_BOOT; +}