From 5251a08d6807ecd76acb78eddbc3bbca4785bfbe Mon Sep 17 00:00:00 2001 From: Hakim Giydan Date: Thu, 8 Sep 2016 10:51:13 -0700 Subject: soc/marvell/mvmap2315: Add PMIC driver Testing: booted successfully. Change-Id: I168206585f403d2259efe424e563982be661df0b Signed-off-by: Hakim Giydan Reviewed-on: https://review.coreboot.org/16149 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth --- src/soc/marvell/mvmap2315/Makefile.inc | 1 + src/soc/marvell/mvmap2315/bootblock.c | 28 ++- src/soc/marvell/mvmap2315/include/soc/addressmap.h | 3 + src/soc/marvell/mvmap2315/include/soc/pmic.h | 196 +++++++++++++++++++++ src/soc/marvell/mvmap2315/pmic.c | 125 +++++++++++++ 5 files changed, 351 insertions(+), 2 deletions(-) create mode 100644 src/soc/marvell/mvmap2315/include/soc/pmic.h create mode 100644 src/soc/marvell/mvmap2315/pmic.c (limited to 'src/soc/marvell') diff --git a/src/soc/marvell/mvmap2315/Makefile.inc b/src/soc/marvell/mvmap2315/Makefile.inc index b42d3b3c51..1510815225 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 8d7b0cbfd9..22a8387f7f 100644 --- a/src/soc/marvell/mvmap2315/bootblock.c +++ b/src/soc/marvell/mvmap2315/bootblock.c @@ -27,6 +27,7 @@ #include #include #include +#include #include void bootblock_soc_early_init(void) @@ -43,6 +44,7 @@ void bootblock_soc_early_init(void) void bootblock_soc_init(void) { struct bdb_pointer bdb_info; + u32 boot_path; write32((void *)MVMAP2315_BOOTBLOCK_CB1, 0); write32((void *)MVMAP2315_BOOTBLOCK_CB2, 0); @@ -54,8 +56,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 *)MVMAP2315_ROMSTAGE_BASE); /* 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 99bf901d21..b82b538965 100644 --- a/src/soc/marvell/mvmap2315/include/soc/addressmap.h +++ b/src/soc/marvell/mvmap2315/include/soc/addressmap.h @@ -21,6 +21,7 @@ #define MAX_DRAM_ADDRESS 0x73000000 #define MVMAP2315_CBFS_BASE 0x00400000 +#define MVMAP2315_ROMSTAGE_BASE 0xE0010000 #define MVMAP2315_BOOTBLOCK_CB1 0xE0009510 #define MVMAP2315_BOOTBLOCK_CB2 0xE0009514 @@ -41,10 +42,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 0000000000..10e22b2de9 --- /dev/null +++ b/src/soc/marvell/mvmap2315/include/soc/pmic.h @@ -0,0 +1,196 @@ +/* + * 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 + +#include +#include + +#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 0000000000..f263804795 --- /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 +#include +#include + +#include +#include +#include +#include +#include +#include + +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; +} -- cgit v1.2.3