[coreboot-gerrit] New patch to review for coreboot: marvell/mvmap2315: add apmu driver

hakim giydan (hgiydan@marvell.com) gerrit at coreboot.org
Thu Jun 30 16:16:01 CEST 2016


hakim giydan (hgiydan at marvell.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/15518

-gerrit

commit a06929dd247c59286074ce3c454813a5bd3442f2
Author: Hakim Giydan <hgiydan at marvell.com>
Date:   Wed Jun 29 18:55:45 2016 -0700

    marvell/mvmap2315: add apmu driver
    
    this driver send and receive command from/to APMU to
    enable/disable individual power rails.
    
    Change-Id: I5ae07849f8432bece8a0ae9066a3f786e6e8d2fe
    Signed-off-by: Hakim Giydan <hgiydan at marvell.com>
---
 src/soc/marvell/mvmap2315/Makefile.inc             |   1 +
 src/soc/marvell/mvmap2315/apmu.c                   | 149 +++++++
 src/soc/marvell/mvmap2315/include/soc/addressmap.h |   4 +
 src/soc/marvell/mvmap2315/include/soc/apmu.h       | 288 ++++++++++++
 src/soc/marvell/mvmap2315/include/soc/clock.h      |   2 +
 src/soc/marvell/mvmap2315/include/soc/power.h      | 171 +++++++-
 src/soc/marvell/mvmap2315/include/soc/pwr_types.h  | 487 +++++++++++++++++++++
 src/soc/marvell/mvmap2315/power.c                  |  89 +++-
 src/soc/marvell/mvmap2315/romstage.c               |  20 +
 9 files changed, 1205 insertions(+), 6 deletions(-)

diff --git a/src/soc/marvell/mvmap2315/Makefile.inc b/src/soc/marvell/mvmap2315/Makefile.inc
index ebb0515..a408049 100644
--- a/src/soc/marvell/mvmap2315/Makefile.inc
+++ b/src/soc/marvell/mvmap2315/Makefile.inc
@@ -26,6 +26,7 @@ ramstage-y += soc.c
 ramstage-y += stage_entry.S
 ramstage-y += uart.c
 
+romstage-y += apmu.c
 romstage-y += assert.c
 romstage-y += bootrom.c
 romstage-y += cbmem.c
diff --git a/src/soc/marvell/mvmap2315/apmu.c b/src/soc/marvell/mvmap2315/apmu.c
new file mode 100644
index 0000000..ce9c85c
--- /dev/null
+++ b/src/soc/marvell/mvmap2315/apmu.c
@@ -0,0 +1,149 @@
+/*
+ * 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 <console/console.h>
+#include <soc/apmu.h>
+#include <soc/clock.h>
+
+static int apmu_blocking_cmd(u32 cmd)
+{
+	u32 reg;
+	u32 completed_cmd;
+	u32 success = 0;
+	u32 timeout_count = 0;
+
+	printk(BIOS_INFO, "Sending cmd: %x.\n", cmd);
+
+	/* Send a sync command with interrupt when complete */
+	reg = read32(&mvmap2315_apmu_pwrctl->pwrcmdfifo);
+	reg = (cmd | MVMAP2315_APMU_PWRCMDFIFO_DONEIRQ);
+	write32(&mvmap2315_apmu_pwrctl->pwrcmdfifo, cmd);
+
+	while (!(read32(&mvmap2315_apmu_pwrctl->intstatus) &
+		(MVMAP2315_APMU_ISTCLR_DONE |
+		MVMAP2315_APMU_ISTCLR_ERROR)) &&
+		(timeout_count < 0x5000))
+		timeout_count++;
+
+	if (timeout_count >= 0x5000) {
+		printk(BIOS_INFO, "Timeout: %d.\n", timeout_count);
+		return -2;
+	}
+
+	if (read32(&mvmap2315_apmu_pwrctl->intstatus) &
+					MVMAP2315_APMU_ISTCLR_DONE) {
+		completed_cmd = read32(&mvmap2315_apmu_pwrctl->doneirq);
+
+		reg = read32(&mvmap2315_apmu_pwrctl->intstatusclear);
+		reg = MVMAP2315_APMU_ISTCLR_DONE;
+		write32(&mvmap2315_apmu_pwrctl->intstatusclear, reg);
+
+		printk(BIOS_INFO, "Completed cmd: %x.\n", completed_cmd);
+		success = 1;
+	} else if (read32(&mvmap2315_apmu_pwrctl->intstatus) &
+					MVMAP2315_APMU_ISTCLR_ERROR) {
+		completed_cmd = read32(&mvmap2315_apmu_pwrctl->errorirq);
+
+		reg = read32(&mvmap2315_apmu_pwrctl->intstatusclear);
+		reg = MVMAP2315_APMU_ISTCLR_ERROR;
+		write32(&mvmap2315_apmu_pwrctl->intstatusclear, reg);
+		printk(BIOS_INFO, "Error cmd: %x.\n", completed_cmd);
+	}
+
+	if (success)
+		return 0;
+
+	return -1;
+}
+
+int apmu_start(u32 first_lcm_bank, u32 last_lcm_bank)
+{
+	u32 reg;
+
+	printk(BIOS_INFO, "APMU LCM start bank: %d.\n", first_lcm_bank);
+	printk(BIOS_INFO, "end bank: %d.\n", last_lcm_bank);
+
+	/* Dedicate the specified LCM area to the APMU */
+	reg = (last_lcm_bank << MVMAP2315_LCM_END_BANK)
+		| (first_lcm_bank << MVMAP2315_LCM_START_BANK)
+		| MVMAP2315_LCM_DIRACCESS_EN;
+	write32(&mvmap2315_lcm_regs->lcm_access, reg);
+
+	printk(BIOS_INFO, "Release APMU...\r\n");
+
+	/* Take the APMU out of reset and let it start running */
+	reg = read32(&mvmap2315_apmu_clk->apaonclk_apmucpu_clkgenconfig);
+	reg |= MVMAP2315_APMU_CLK_EN;
+	write32(&mvmap2315_apmu_clk->apaonclk_apmucpu_clkgenconfig, reg);
+
+	reg = read32(&mvmap2315_apmu_clk->apaonclk_apmucpu_clkgenconfig);
+	reg |= MVMAP2315_APMU_CLK_RSTN;
+	write32(&mvmap2315_apmu_clk->apaonclk_apmucpu_clkgenconfig, reg);
+
+	return 0;
+}
+
+int apmu_set_device_state(u32 device, u32 new_state)
+{
+	u32 pwr_cmd;
+
+	pwr_cmd = MVMAP2315_APMU_PWRCMDFIFO_DONEIRQ;
+	pwr_cmd |= (2 << MVMAP2315_APMU_PWRCMDFIFO_OPCODE_SHIFT);
+	pwr_cmd |= (new_state << MVMAP2315_APMU_PWRCMDFIFO_STATE_SHIFT);
+	pwr_cmd |= (device << MVMAP2315_APMU_PWRCMDFIFO_OBJECT_SHIFT);
+
+	return apmu_blocking_cmd(pwr_cmd);
+}
+
+int apmu_set_pll_state(u32 device, u32 new_state, u32 frequency)
+{
+	u32 pwr_cmd = 0;
+
+	pwr_cmd = MVMAP2315_APMU_PWRCMDFIFO_DONEIRQ;
+	pwr_cmd |= (2 << MVMAP2315_APMU_PWRCMDFIFO_OPCODE_SHIFT);
+	pwr_cmd |= (frequency << MVMAP2315_APMU_PWRCMDFIFO_TARGFREQ_SHIFT);
+	pwr_cmd |= (new_state << MVMAP2315_APMU_PWRCMDFIFO_STATE_SHIFT);
+	pwr_cmd |= (device << MVMAP2315_APMU_PWRCMDFIFO_OBJECT_SHIFT);
+
+	return apmu_blocking_cmd(pwr_cmd);
+}
+
+int apmu_set_clock_state(u32 clock, u32 new_state, u32 divider, u32 source)
+{
+	u32 pwr_cmd = 0;
+	u32 arg     = 0;
+
+	pwr_cmd = MVMAP2315_APMU_PWRCMDFIFO_DONEIRQ;
+	pwr_cmd |= (1 << MVMAP2315_APMU_PWRCMDFIFO_OPCODE_SHIFT);
+
+	arg = (new_state << 25) | (divider << 12) |
+		(source << 8) | (clock);
+
+	pwr_cmd |= (arg << MVMAP2315_APMU_PWRCMDFIFO_ARGUMENT_SHIFT);
+
+	return apmu_blocking_cmd(pwr_cmd);
+}
+
+int apmu_declare_s0(void)
+{
+	u32 pwr_cmd = 0;
+
+	pwr_cmd = MVMAP2315_APMU_PWRCMDFIFO_DONEIRQ;
+	pwr_cmd |= (0XF << MVMAP2315_APMU_PWRCMDFIFO_OPCODE_SHIFT);
+	pwr_cmd |= (0X14 << MVMAP2315_APMU_PWRCMDFIFO_ARGUMENT_SHIFT);
+
+	return apmu_blocking_cmd(pwr_cmd);
+}
diff --git a/src/soc/marvell/mvmap2315/include/soc/addressmap.h b/src/soc/marvell/mvmap2315/include/soc/addressmap.h
index 9d20a75..1303cc8 100644
--- a/src/soc/marvell/mvmap2315/include/soc/addressmap.h
+++ b/src/soc/marvell/mvmap2315/include/soc/addressmap.h
@@ -23,12 +23,16 @@ enum {
 	MVMAP2315_RAM_BASE = 0x00000000,
 	MVMAP2315_CBFS_BASE = 0x00400000,
 	MVMAP2315_BDB_LCM_BASE = 0xE0000000,
+	MVMAP2315_LOWPWR_REG = 0xE0002000,
 	MVMAP2315_BRM_CBS_MEDIA_TYPE = 0xE0002004,
 	MVMAP2315_BCM_GICD_BASE = 0xE0111000,
 	MVMAP2315_BCM_GICC_BASE = 0xE0112000,
 	MVMAP2315_MAIN_PLL_BASE = 0xE0125000,
 	MVMAP2315_APMU_CLK_BASE = 0xE0125400,
+	MVMAP2315_APMU_PWRCTL_BASE = 0xE012C000,
+	MVMAP2315_LCM_REGS_BASE = 0xE0130000,
 	MVMAP2315_GENTIMER_BASE = 0xE0137000,
+	MVMAP2315_CPU_BASE = 0xE013F200,
 	MVMAP2315_PADWRAP_BASE = 0xE0140000,
 	MVMAP2315_TIMER0_BASE = 0xE1020000,
 	MVMAP2315_MPMU_CLK_BASE = 0xEF000800,
diff --git a/src/soc/marvell/mvmap2315/include/soc/apmu.h b/src/soc/marvell/mvmap2315/include/soc/apmu.h
new file mode 100644
index 0000000..e8ede68
--- /dev/null
+++ b/src/soc/marvell/mvmap2315/include/soc/apmu.h
@@ -0,0 +1,288 @@
+/*
+ * 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 __SOC_MARVELL_MVMAP2315_APMU_H__
+#define __SOC_MARVELL_MVMAP2315_APMU_H__
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <types.h>
+
+#include <soc/addressmap.h>
+
+#define MVMAP2315_APMU_PWRCMDFIFO_DONEIRQ		BIT(27)
+#define MVMAP2315_APMU_ISTCLR_DONE			BIT(30)
+#define MVMAP2315_APMU_ISTCLR_ERROR			BIT(31)
+#define MVMAP2315_APMU_PWRCMDFIFO_OPCODE_SHIFT		28
+#define MVMAP2315_APMU_PWRCMDFIFO_STATE_SHIFT		8
+#define MVMAP2315_APMU_PWRCMDFIFO_OBJECT_SHIFT		0
+#define MVMAP2315_APMU_PWRCMDFIFO_TARGFREQ_SHIFT	12
+#define MVMAP2315_APMU_PWRCMDFIFO_ARGUMENT_SHIFT	0
+struct mvmap2315_apmu_pwrctl_regs {
+	 u32 pwrcmdfifo;
+	 u32 pwrcmdfifostatus;
+	 u8 _reserved0[0x08];
+	 u32 intstatusset;
+	 u32 intstatusclear;
+	 u32 intstatus;
+	 u8 _reserved1[0x04];
+	 u32 doneirq;
+	 u32 errorirq;
+	 u32 scratch0;
+	 u32 scratch1;
+	 u8 _reserved2[0x10];
+	 u32 pmp_spci_rx_int_status;
+	 u32 pmp_spci_rx_int_set;
+	 u32 pmp_spci_rx_int_clear;
+	 u8 _reserved3[0x04];
+	 u32 pmp_spci_tx_int_status;
+	 u32 pmp_spci_tx_int_set;
+	 u32 pmp_spci_tx_int_clear;
+	 u8 _reserved4[0xa4];
+	 u32 global_pwrstate;
+	 u8 _reserved5[0x0c];
+	 u32 a72core0_pwrstate;
+	 u8 _reserved6[0x0c];
+	 u32 a72core1_pwrstate;
+	 u8 _reserved7[0x0c];
+	 u32 a72core2_pwrstate;
+	 u8 _reserved8[0x0c];
+	 u32 a72core3_pwrstate;
+	 u8 _reserved9[0x0c];
+	 u32 a72l2_pwrstate;
+	 u8 _reserved10[0x0c];
+	 u32 a2fab_pwrstate;
+	 u8 _reserved11[0x0c];
+	 u32 mc_pwrstate;
+	 u8 _reserved12[0x0c];
+	 u32 mc_phy0_pwrstate;
+	 u8 _reserved13[0x0c];
+	 u32 mc_phy1_pwrstate;
+	 u8 _reserved14[0x0c];
+	 u32 mc_phy2_pwrstate;
+	 u8 _reserved15[0x0c];
+	 u32 mc_phy3_pwrstate;
+	 u8 _reserved16[0x0c];
+	 u32 mcflc_pwrstate;
+	 u8 _reserved17[0x0c];
+	 u32 mcflc_phy0_pwrstate;
+	 u8 _reserved18[0x0c];
+	 u32 mcflc_phy1_pwrstate;
+	 u8 _reserved19[0x0c];
+	 u32 mcflc_phy2_pwrstate;
+	 u8 _reserved20[0x0c];
+	 u32 mcflc_phy3_pwrstate;
+	 u8 _reserved21[0x0c];
+	 u32 gpu3dcore0_pwrstate;
+	 u8 _reserved22[0x0c];
+	 u32 gpu3dcore1_pwrstate;
+	 u8 _reserved23[0x0c];
+	 u32 gpu3dcore2_pwrstate;
+	 u8 _reserved24[0x0c];
+	 u32 gpu3dcore3_pwrstate;
+	 u8 _reserved25[0x0c];
+	 u32 gpu3dl2_pwrstate;
+	 u8 _reserved26[0x0c];
+	 u32 smmu_pwrstate;
+	 u8 _reserved27[0x0c];
+	 u32 vpudec_pwrstate;
+	 u8 _reserved28[0x0c];
+	 u32 jpeg_pwrstate;
+	 u8 _reserved29[0x0c];
+	 u32 decoder_pwrstate;
+	 u8 _reserved30[0x0c];
+	 u32 vpuenc_pwrstate;
+	 u8 _reserved31[0x0c];
+	 u32 vp8_pwrstate;
+	 u8 _reserved32[0x0c];
+	 u32 vp9_pwrstate;
+	 u8 _reserved33[0x0c];
+	 u32 zram_pwrstate;
+	 u8 _reserved34[0x0c];
+	 u32 gpu2d_pwrstate;
+	 u8 _reserved35[0x0c];
+	 u32 edisplay_pwrstate;
+	 u8 _reserved36[0x0c];
+	 u32 edp_phy_pwrstate;
+	 u8 _reserved37[0x0c];
+	 u32 dsi_phy0_pwrstate;
+	 u8 _reserved38[0x0c];
+	 u32 dsi_phy1_pwrstate;
+	 u8 _reserved39[0x0c];
+	 u32 display_pwrstate;
+	 u8 _reserved40[0x0c];
+	 u32 mci_x40_pwrstate;
+	 u8 _reserved41[0x0c];
+	 u32 mci_x4_phy0_pwrstate;
+	 u8 _reserved42[0x0c];
+	 u32 mci_x41_pwrstate;
+	 u8 _reserved43[0x0c];
+	 u32 mci_x4_phy1_pwrstate;
+	 u8 _reserved44[0x0c];
+	 u32 mci_x42_pwrstate;
+	 u8 _reserved45[0x0c];
+	 u32 mci_x4_phy2_pwrstate;
+	 u8 _reserved46[0x0c];
+	 u32 mci_x2_pwrstate;
+	 u8 _reserved47[0x0c];
+	 u32 mci_x2_phy_pwrstate;
+	 u8 _reserved48[0x0c];
+	 u32 mci_x10_pwrstate;
+	 u8 _reserved49[0x0c];
+	 u32 mci_x1_phy0_pwrstate;
+	 u8 _reserved50[0x0c];
+	 u32 mci_x11_pwrstate;
+	 u8 _reserved51[0x0c];
+	 u32 mci_x1_phy1_pwrstate;
+	 u8 _reserved52[0x0c];
+	 u32 mci_x12_pwrstate;
+	 u8 _reserved53[0x0c];
+	 u32 mci_x1_phy2_pwrstate;
+	 u8 _reserved54[0x0c];
+	 u32 mci_x13_pwrstate;
+	 u8 _reserved55[0x0c];
+	 u32 mci_x1_phy3_pwrstate;
+	 u8 _reserved56[0x2c];
+	 u32 sdmmc_pwrstate;
+	 u8 _reserved57[0x0c];
+	 u32 emmc_phy_pwrstate;
+	 u8 _reserved58[0x0c];
+	 u32 sdio_phy0_pwrstate;
+	 u8 _reserved59[0x0c];
+	 u32 sdio_phy1_pwrstate;
+	 u8 _reserved60[0x0c];
+	 u32 aes256_pwrstate;
+	 u8 _reserved61[0x0c];
+	 u32 ap_axi_pwrstate;
+	 u8 _reserved62[0x1c];
+	 u32 ap_uart0_pwrstate;
+	 u8 _reserved63[0x0c];
+	 u32 ap_uart1_pwrstate;
+	 u8 _reserved64[0x0c];
+	 u32 ap_ssp0_pwrstate;
+	 u8 _reserved65[0x0c];
+	 u32 ap_ssp1_pwrstate;
+	 u8 _reserved66[0x0c];
+	 u32 ap_i2c0_pwrstate;
+	 u8 _reserved67[0x0c];
+	 u32 ap_i2c1_pwrstate;
+	 u8 _reserved68[0x0c];
+	 u32 ap_i2c2_pwrstate;
+	 u8 _reserved69[0x0c];
+	 u32 ap_i2c3_pwrstate;
+	 u8 _reserved70[0x0c];
+	 u32 ap_i2c4_pwrstate;
+	 u8 _reserved71[0x0c];
+	 u32 ap_lcm_pwrstate;
+	 u8 _reserved72[0x0c];
+	 u32 ap_m2m_pwrstate;
+	 u8 _reserved73[0x0c];
+	 u32 ap_apb_pwrstate;
+	 u8 _reserved74[0x0c];
+	 u32 bcm_r4_pwrstate;
+	 u8 _reserved75[0x0c];
+	 u32 apmu_m4_pwrstate;
+	 u8 _reserved76[0x0c];
+	 u32 ap_gic_pwrstate;
+	 u8 _reserved77[0x4c];
+	 u32 cpu_pll_pwrstate;
+	 u8 _reserved78[0x0c];
+	 u32 mc_pll_pwrstate;
+	 u8 _reserved79[0x0c];
+	 u32 mcflc_pll_pwrstate;
+	 u8 _reserved80[0x0c];
+	 u32 a2_pll_pwrstate;
+	 u8 _reserved81[0x0c];
+	 u32 main_pll_pwrstate;
+	 u8 _reserved82[0x0c];
+	 u32 gpu_pll0_pwrstate;
+	 u8 _reserved83[0x0c];
+	 u32 gpu_pll1_pwrstate;
+	 u8 _reserved84[0x0c];
+	 u32 mipi_pll_pwrstate;
+	 u8 _reserved85[0x0c];
+	 u32 display_pll_pwrstate;
+	 u8 _reserved86[0x0c];
+	 u32 avs_vmain_pwrstate;
+	 u8 _reserved87[0x0c];
+	 u32 avs_vcpu_pwrstate;
+	 u8 _reserved88[0x0c];
+	 u32 avs_vgpu_pwrstate;
+	 u8 _reserved89[0x0c];
+	 u32 ap_tsene_pwrstate;
+	 u8 _reserved90[0x0c];
+	 u32 rng_pwrstate;
+	 u8 _reserved91[0x3c];
+	 u32 padgroup29_pwrstate;
+	 u8 _reserved92[0x0c];
+	 u32 padgroup30_pwrstate;
+	 u8 _reserved93[0x0c];
+	 u32 padgroup31_pwrstate;
+	 u8 _reserved94[0x0c];
+	 u32 padgroup32_pwrstate;
+	 u8 _reserved95[0x0c];
+	 u32 padgroup33_pwrstate;
+};
+
+check_member(mvmap2315_apmu_pwrctl_regs, padgroup33_pwrstate, 0x750);
+static struct mvmap2315_apmu_pwrctl_regs * const mvmap2315_apmu_pwrctl
+					= (void *)MVMAP2315_APMU_PWRCTL_BASE;
+
+#define MVMAP2315_LCM_DIRACCESS_EN		BIT(0)
+#define MVMAP2315_LCM_START_BANK		BIT(2)
+#define MVMAP2315_LCM_END_BANK			BIT(3)
+struct mvmap2315_lcm_regs {
+	 u32 lcm_scfg;
+	 u32 lcm_access;
+	 u8 _reserved0[0x08];
+	 u32 lcm_ctrl_bank_mstr_id_wr0;
+	 u32 lcm_ctrl_bank_mstr_id_wr1;
+	 u32 lcm_ctrl_bank_mstr_id_wr2;
+	 u32 lcm_ctrl_bank_mstr_id_wr3;
+	 u32 lcm_ctrl_bank_mstr_id_wr4;
+	 u32 lcm_ctrl_bank_mstr_id_wr5;
+	 u8 _reserved1[0x28];
+	 u32 lcm_ctrl_bank_mask_id_wr0;
+	 u32 lcm_ctrl_bank_mask_id_wr1;
+	 u32 lcm_ctrl_bank_mask_id_wr2;
+	 u32 lcm_ctrl_bank_mask_id_wr3;
+	 u32 lcm_ctrl_bank_mask_id_wr4;
+	 u32 lcm_ctrl_bank_mask_id_wr5;
+	 u8 _reserved2[0x28];
+	 u32 lcm_ctrl_bank_mstr_id_rd0;
+	 u32 lcm_ctrl_bank_mstr_id_rd1;
+	 u32 lcm_ctrl_bank_mstr_id_rd2;
+	 u32 lcm_ctrl_bank_mstr_id_rd3;
+	 u32 lcm_ctrl_bank_mstr_id_rd4;
+	 u32 lcm_ctrl_bank_mstr_id_rd5;
+	 u8 _reserved3[0x28];
+	 u32 lcm_ctrl_bank_mask_id_rd0;
+	 u32 lcm_ctrl_bank_mask_id_rd1;
+	 u32 lcm_ctrl_bank_mask_id_rd2;
+	 u32 lcm_ctrl_bank_mask_id_rd3;
+	 u32 lcm_ctrl_bank_mask_id_rd4;
+	 u32 lcm_ctrl_bank_mask_id_rd5;
+};
+
+check_member(mvmap2315_lcm_regs, lcm_ctrl_bank_mask_id_rd5, 0xe4);
+static struct mvmap2315_lcm_regs * const mvmap2315_lcm_regs
+					= (void *)MVMAP2315_LCM_REGS_BASE;
+
+int apmu_start(u32 first_lcm_bank, u32 last_lcm_bank);
+int apmu_set_device_state(u32 device, u32 new_state);
+int apmu_set_pll_state(u32 device, u32 new_state, u32 frequency);
+int apmu_set_clock_state(u32 clock, u32 new_state, u32 divider, u32 source);
+int apmu_declare_s0(void);
+
+#endif /* __SOC_MARVELL_MVMAP2315_APMU_H__ */
diff --git a/src/soc/marvell/mvmap2315/include/soc/clock.h b/src/soc/marvell/mvmap2315/include/soc/clock.h
index a982198..7fd15b1 100644
--- a/src/soc/marvell/mvmap2315/include/soc/clock.h
+++ b/src/soc/marvell/mvmap2315/include/soc/clock.h
@@ -72,6 +72,8 @@ static struct mvmap2315_main_pll_regs * const mvmap2315_pll
 
 #define MVMAP2315_UART_CLK_EN		BIT(1)
 #define MVMAP2315_SDMMC_CLK_RSTN	BIT(0)
+#define MVMAP2315_APMU_CLK_EN		BIT(1)
+#define MVMAP2315_APMU_CLK_RSTN		BIT(0)
 struct mvmap2315_apmu_clk_regs {
 	u32 uartfracdivcfg0;
 	u8 _reserved0[0x0c];
diff --git a/src/soc/marvell/mvmap2315/include/soc/power.h b/src/soc/marvell/mvmap2315/include/soc/power.h
index 308f657..154a3c0 100644
--- a/src/soc/marvell/mvmap2315/include/soc/power.h
+++ b/src/soc/marvell/mvmap2315/include/soc/power.h
@@ -3,12 +3,12 @@
  *
  * Copyright (C) 2016 Marvell, Inc.
  *
- * This program is free software; you can redistribute it and/or modify
+ * This program is free software;
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * the Free Software Foundation;
  *
  * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * but WITHOUT ANY WARRANTY;
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
@@ -17,8 +17,170 @@
 
 #include <stdint.h>
 #include <stdlib.h>
+#include <types.h>
 
-enum boot_paths {
+#include <soc/addressmap.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
@@ -28,6 +190,7 @@ void no_boot(void);
 void full_boot(void);
 void charging_screen(void);
 void start_ap_cores(void *entry);
+void mcu_start(void);
 u32 get_boot_path(void);
 
 #endif /* __SOC_MARVELL_MVMAP2315_POWER_H__ */
diff --git a/src/soc/marvell/mvmap2315/include/soc/pwr_types.h b/src/soc/marvell/mvmap2315/include/soc/pwr_types.h
new file mode 100644
index 0000000..04493e6
--- /dev/null
+++ b/src/soc/marvell/mvmap2315/include/soc/pwr_types.h
@@ -0,0 +1,487 @@
+/*
+ * 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_ADDRESS_PWR_TYPES_H__
+#define __SOC_MARVELL_MVMAP2315_ADDRESS_PWR_TYPES_H__
+
+#include <stdint.h>
+#include <stdlib.h>
+
+enum sleepstatet {
+	S0 = 0,
+	S3 = 3,
+	S5 = 5
+};
+
+enum devicestatet {
+	D0 = 0,
+	D1 = 1,
+	D2 = 2,
+	D3 = 3,
+	D3WAKEINT = 11
+};
+
+enum clockstatet {
+	NOCHANGE = 0,
+	GATED = 1,
+	RUNNING = 2
+};
+
+enum clocksscstatet {
+	SSCOFF = 0,
+	SSCONDOWN1 = 1,
+	SSCONDOWN2 = 2,
+	SSCONDOWN3 = 3
+};
+
+enum apllfreqt {
+	APLL_NOCHANGE = 0,
+	APLL_589P824  = 1,
+	APLL_541P9008 = 2,
+	APLL_451P584  = 3
+};
+
+enum clocktypest {
+	CLKMUX_C = 0,
+	CLKGEN_C = 1,
+	CLKGEN_W_CLKGATE_C = 2,
+	CLKGATE_C = 4,
+	CLKGATEDIV2_C = 5,
+	CLKGATEDIV4_C = 6,
+	CLKGATEDIV8_C = 7,
+	CLKFRAC_W_CLKGATE_C = 8,
+	DIV2_C = 9,
+	DIV4_C = 10,
+	SSPLL_C = 11,
+	APLL_C = 12,
+	REFCLK25M_C = 13,
+	REFCLK32K_C = 14,
+	DROCLK_C = 15
+};
+
+enum devicetypest {
+	DIGLOGIC_D = 0,
+	DIGLOGIC_WSRAM_D = 2,
+	DIGLOGIC_PI_D = 3,
+	DIGLOGIC_WSRAM_PI_D = 4,
+	PHY_D = 5,
+	SSPLL_D = 6,
+	APLL_D = 7,
+	TSENSOR_D = 8,
+	EFUSE_D = 9,
+	AVS_D = 10,
+	ANA_GRP_D = 11,
+	PADGROUP_D = 12,
+	MCIREFDRV_D = 13,
+	TESTTYPE_D = 14
+};
+
+enum gaclockst {
+	CPUCLK = 0,
+	CPUBUSCLK = 1,
+	CPUTSCLK = 2,
+	TRACECLK0 = 3,
+	MCCLK2X = 4,
+	MCCLK = 5,
+	MCFLCCLK2X = 6,
+	MCFLCCLK = 7,
+	BUSRINGCLK = 8,
+	SNOOPCLK = 9,
+	MCBUSCLK = 10,
+	MCBUSCLK_A2 = 11,
+	MCCFGCLK = 12,
+	MCCFGCLK_A2 = 13,
+	CPUCFGCLK = 14,
+	CPUCFGCLK_A2 = 15,
+	VPUENC_VP8CLK = 16,
+	VPUENC_VP9CLK = 17,
+	BUSCLK2X_A2 = 18,
+	BUSCLK = 19,
+	BUSCLK_MCIX2_0 = 20,
+	BUSCLK_MCIX1_0 = 21,
+	BUSCLK_MCIX1_1 = 22,
+	BUSCLK_MCIX1_2 = 23,
+	BUSCLK_MCIX1_3 = 24,
+	BUSCLK_A2 = 25,
+	BUSCLK_AES = 26,
+	BUSCLK_APAONBUS_HS = 27,
+	ACLK2X_A2 = 28,
+	ACLK_A2 = 29,
+	ACLK_VPU = 30,
+	ACLK_MCIX4_0 = 31,
+	ACLK_MCIX4_1 = 32,
+	ACLK_MCIX4_2 = 33,
+	ACLK_EDISPLAY = 34,
+	ACLK_DISPLAY = 35,
+	CFGCLK = 36,
+	CFGCLK_A2 = 37,
+	HCLK_A2 = 38,
+	HCLK_EDISPLAY = 39,
+	HCLK_DISPLAY = 40,
+	HCLK_VPU = 41,
+	APAONCLK = 42,
+	APAONCLK_APMUCPU = 43,
+	APAONCLK_SDMMC = 44,
+	APAONCLK_LCM = 45,
+	APAONCLK_M2M = 46,
+	APAONCLK_APB = 47,
+	BISTCLK = 48,
+	BCMCPUCLK = 49,
+	ZRAMCLK = 50,
+	ZRAMCLK_A2 = 51,
+	SDMMCBASECLK = 52,
+	JPEGCLK = 53,
+	UARTCLKGEN = 54,
+	UARTCLK_0 = 55,
+	UARTCLK_1 = 56,
+	SSPCLK_0 = 57,
+	SSPCLK_1 = 58,
+	I2CCLK_0 = 59,
+	I2CCLK_1 = 60,
+	I2CCLK_2 = 61,
+	I2CCLK_3 = 62,
+	I2CCLK_4 = 63,
+	GPU2DBUSCLK = 64,
+	GPU2DBUSCLK_A2 = 65,
+	GPU2DCFGCLK = 66,
+	GPU2DCFGCLK_A2 = 67,
+	GPU2DCORECLK = 68,
+	GPU3DBUSCORECLK = 69,
+	GPU3DBUSCORECLK_A2 = 70,
+	GPU3DCFGCLK = 71,
+	GPU3DCFGCLK_A2 = 72,
+	GPU3DSHADERCLK = 73,
+	VPUDECCLK = 74,
+	VPUDECM3CLK = 75,
+	DISPLAYPIPECLK = 76,
+	EDISPLAYPIPECLK = 77,
+	EDISPLAYMIPIBITCLK = 78,
+	EDISPLAYAUXREFCLK = 79,
+	EDISPLAYAUXCLK = 80,
+	EDISPLAYPIXELCLK = 81,
+	DMICCLK = 82,
+	SSPACLK_0 = 83,
+	SSPACLK_1 = 84,
+	SSPACLK_2 = 85,
+	TSENCLK = 86,
+	AP_TSENCLK = 87,
+	CLK32K = 88,
+	REFCLK = 89,
+	REFCLK_UARTGEN = 90,
+	REFCLK_UART0 = 91,
+	REFCLK_UART1 = 92,
+	REFCLK_I2C0 = 93,
+	REFCLK_I2C1 = 94,
+	REFCLK_I2C2 = 95,
+	REFCLK_I2C3 = 96,
+	REFCLK_I2C4 = 97,
+	REFCLK_I2C5 = 98,
+	REFCLK_SSP0 = 99,
+	REFCLK_SSP1 = 100,
+	REFCLK_SSPA0 = 101,
+	REFCLK_SSPA1 = 102,
+	REFCLK_SSPA2 = 103,
+	MCUCLK = 104,
+	MCUCLK_CDMA = 105,
+	MCUCLK_BSPI = 106,
+	MCUCLK_OWI = 107,
+	MCUCLK_UART0 = 108,
+	MCUCLK_UART1 = 109,
+	MCUCLK_SSP0 = 110,
+	MCUCLK_SSP1 = 111,
+	MCUCLK_SSPA0 = 112,
+	MCUCLK_SSPA1 = 113,
+	MCUCLK_SSPA2 = 114,
+	MCUCLK_DMIC0 = 115,
+	MCUCLK_DMIC1 = 116,
+	MCUCLK_DMIC2 = 117,
+	MCUCLK_DMIC3 = 118,
+	DMIC_DCLK0 = 119,
+	DMIC_DCLK1 = 120,
+	DMIC_DCLK2 = 121,
+	DMIC_DCLK3 = 122,
+	DMIC_ENGDETCLK = 123,
+	M4CLK = 124,
+	M4CLK_LCM0 = 125,
+	M4CLK_LCM1 = 126,
+	M4CLK_LCM2 = 127,
+	CPUDBGCLK = 128,
+	M4CLK_BIST = 129,
+	BSPICLK = 130,
+	CPU_MUXCLK = 131,
+	DISPLAY_MUXCLK = 132,
+	CPU_PLL_CLK = 133,
+	MC_PLL_CLK = 134,
+	MCFLC_PLL_CLK = 135,
+	A2_PLL_CLK = 136,
+	MAIN_PLL_CLK = 137,
+	GPU_PLL0_CLK = 138,
+	GPU_PLL1_CLK = 139,
+	MIPI_PLL_CLK = 140,
+	DISPLAY_PLL_CLK = 141,
+	APLL0_CLK = 142,
+	APLL1_CLK = 143,
+	REFCLK25M = 144,
+	REFCLK32K = 145,
+	DROCLK = 146,
+	GACLOCKS_END = 147
+};
+
+enum gasrcselclockst {
+	SRCSEL_NO_CHANGE =  0,
+	SRCSEL_CPU_PLL =  1,
+	SRCSEL_MC_PLL =  2,
+	SRCSEL_MCFLC_PLL =  3,
+	SRCSEL_A2_PLL =  4,
+	SRCSEL_MAIN_PLL =  5,
+	SRCSEL_GPU_PLL0 =  6,
+	SRCSEL_GPU_PLL1 =  7,
+	SRCSEL_MIPI_PLL =  8,
+	SRCSEL_DISPLAY_PLL =  9,
+	SRCSEL_APLL0 = 10,
+	SRCSEL_APLL1 = 11,
+	SRCSEL_REFCLK25M = 12,
+	SRCSEL_REFCLK32K = 13,
+	SRCSEL_DROCLK = 14,
+	SRCSEL_SELECT_INVALID = 15
+};
+
+enum gadevicest {
+	APCPU_0 = 0,
+	APCPU_1 = 1,
+	APCPU_2 = 2,
+	APCPU_3 = 3,
+	APCPU_L2 = 4,
+	A2 = 5,
+	MC = 6,
+	DDRPHY_0 = 7,
+	DDRPHY_1 = 8,
+	DDRPHY_2 = 9,
+	DDRPHY_3 = 10,
+	MCFLC = 11,
+	MCFLCPHY_0 = 12,
+	MCFLCPHY_1 = 13,
+	MCFLCPHY_2 = 14,
+	MCFLCPHY_3 = 15,
+	GPU3D_0 = 16,
+	GPU3D_1 = 17,
+	GPU3D_2 = 18,
+	GPU3D_3 = 19,
+	GPU3D_L2 = 20,
+	VPUDEC = 21,
+	JPEG = 22,
+	DECODER = 23,
+	VPUENC = 24,
+	VP8 = 25,
+	VP9 = 26,
+	ZRAM = 27,
+	GPU2D = 28,
+	EDISPLAY = 29,
+	EDP_PHY = 30,
+	DSI0_PHY = 31,
+	DSI1_PHY = 32,
+	DISPLAY = 33,
+	MCI0 = 34,
+	MCI0_PHY = 35,
+	MCI1 = 36,
+	MCI1_PHY = 37,
+	MCI2 = 38,
+	MCI2_PHY = 39,
+	MCI3 = 40,
+	MCI3_PHY = 41,
+	MCI4 = 42,
+	MCI4_PHY = 43,
+	MCI5 = 44,
+	MCI5_PHY = 45,
+	MCI6 = 46,
+	MCI6_PHY = 47,
+	MCI7 = 48,
+	MCI7_PHY = 49,
+	SDMMC = 50,
+	EMMC_PHY = 51,
+	SDIO1_PHY = 52,
+	SDIO2_PHY = 53,
+	AES256 = 54,
+	AP_AXI_HS = 55,
+	AP_UART0 = 56,
+	AP_UART1 = 57,
+	AP_SSP0 = 58,
+	AP_SSP1 = 59,
+	AP_I2C0 = 60,
+	AP_I2C1 = 61,
+	AP_I2C2 = 62,
+	AP_I2C3 = 63,
+	AP_I2C4 = 64,
+	AP_M2M = 65,
+	AP_APB = 66,
+	AP_GIC = 67,
+	MCU_BOOTSPI = 68,
+	MCU_UART0 = 69,
+	MCU_UART1 = 70,
+	MCU_SSP0 = 71,
+	MCU_SSP1 = 72,
+	MCU_I2C0 = 73,
+	MCU_I2C1 = 74,
+	MCU_I2C2 = 75,
+	MCU_I2C3 = 76,
+	MCU_I2C4 = 77,
+	MCU_I2C5 = 78,
+	MCU_OWI = 79,
+	MCU_DMIC = 80,
+	MCU_DMIC0 = 81,
+	MCU_DMIC1 = 82,
+	MCU_DMIC2 = 83,
+	MCU_DMIC3 = 84,
+	MCU_CDMA = 85,
+	MCU_SSPA0 = 86,
+	MCU_SSPA1 = 87,
+	MCU_SSPA2 = 88,
+	MCU_LCM0 = 89,
+	MCU_LCM1 = 90,
+	MCU_LCM2 = 91,
+	TRACE_DEBUG = 92,
+	CPU_PLL = 93,
+	MC_PLL = 94,
+	MCFLC_PLL = 95,
+	A2_PLL = 96,
+	MAIN_PLL = 97,
+	GPU_PLL0 = 98,
+	GPU_PLL1 = 99,
+	MIPI_PLL = 100,
+	DISPLAY_PLL = 101,
+	APLL0 = 102,
+	APLL1 = 103,
+	ANA_GRP = 104,
+	AVS_VMCU = 105,
+	AVS_VMAIN = 106,
+	AVS_VCPU = 107,
+	AVS_VGPU = 108,
+	AP_TSENE = 109,
+	MCU_TSENE = 110,
+	RBIST_EFUSE = 111,
+	MCICLK0 = 112,
+	MCICLK1 = 113,
+	MCICLK2 = 114,
+	MCICLK3 = 115,
+	MCICLK4 = 116,
+	MCICLK5 = 117,
+	PG4 = 118,
+	PG18 = 119,
+	PG19 = 120,
+	PG20 = 121,
+	PG21 = 122,
+	PG22 = 123,
+	PG23 = 124,
+	PG24 = 125,
+	PG25 = 126,
+	PG26 = 127,
+	PG27 = 128,
+	PG29 = 129,
+	PG30 = 130,
+	PG31 = 131,
+	PG32 = 132,
+	PG33 = 133,
+	GADEVICES_END = 134
+};
+
+enum pmuerrort {
+	PMUERRORNONE = 0,
+	PMUERRORGENERAL = 1,
+	PMUERROROPCODE = 2,
+	PMUERROROBJECT = 3,
+	PMUERRORMAX_FREQ = 4,
+	PMUERRORLIMIT = 5,
+	PMUERRORUNGATABLE = 6,
+	PMUERRORFREQ = 7,
+	PMUERRORCLKSRC = 9,
+	PMUERRORMAX_DIV = 10,
+	PMUERRORSHELFMAX = 11,
+	PMUERRORSTATE = 12
+};
+
+enum opcodet {
+	SYNC = 0,
+	CHANGECLOCKSTATE = 1,
+	CHANGEDEVICEPOWERSTATE = 2,
+	CHANGESOCPOWERSTATE = 3,
+	SETWAKEUPSOURCE = 4,
+	EXECUTELIST = 5,
+	READCLOCKSTATE = 6,
+	READDEVICEPOWERSTATE = 7
+};
+
+enum executelistcmdt {
+	BUILDLISTSHELF = 0,
+	ENDOFLIST = 1,
+	BLOCKLISTUNTILWAKE = 2,
+	PROCESSLISTSHELF = 3,
+	PROCESSLISTAPLCM = 4,
+	PROCESSLISTMCULCM = 5
+};
+
+enum wakeupsourcet {
+	RTCINT1 = 0,
+	RTCINT2 = 1,
+	RTC1SINT = 2,
+	MCUTIMERINT0 = 3,
+	MCUTIMERINT1 = 4,
+	MCUTIMERINT2 = 5,
+	MCUTIMERINT3 = 6,
+	MCUTIMERINT4 = 7,
+	MCUTIMERINT5 = 8,
+	MCUTIMERINT6 = 9,
+	MCUTIMERINT7 = 10,
+	APTIMERINT0 = 11,
+	APTIMERINT1 = 12,
+	APTIMERINT2 = 13,
+	APTIMERINT3 = 14,
+	APTIMERINT4 = 15,
+	APTIMERINT5 = 16,
+	APTIMERINT6 = 17,
+	APTIMERINT7 = 18,
+	MCUGPIOINT0 = 19,
+	MCUGPIOINT1 = 20,
+	MCUGPIOINT2 = 21,
+	MCUGPIOINT3 = 22,
+	MCUGPIOINT4 = 23,
+	MCUGPIOINT5 = 24,
+	MCUGPIOINT6 = 25,
+	MCUGPIOINT7 = 26,
+	APGPIOINT0 = 27,
+	APGPIOINT1 = 28,
+	APGPIOINT2 = 29,
+	APGPIOINT3 = 30,
+	APGPIOINT4 = 31,
+	APGPIOINT5 = 32,
+	APGPIOINT6 = 33,
+	APGPIOINT7 = 34,
+	KEYBINT = 35,
+	ENGDETINT = 36,
+	MCIREMOTE0 = 37,
+	MCIREMOTE1 = 38,
+	MCIREMOTE2 = 39,
+	MCIREMOTE3 = 40,
+	MCIREMOTE4 = 41,
+	MCIREMOTE5 = 42,
+	MCIREMOTE6 = 43,
+	MCIREMOTE7 = 44,
+	EMMCPHY = 45,
+	SDIOPHY1 = 46,
+	SDIOPHY2 = 47,
+	SDMMCWAKEINT = 48,
+	WAKEINTINVALID = 49
+};
+
+#endif /* __SOC_MARVELL_MVMAP2315_ADDRESS_PWR_TYPES_H__ */
diff --git a/src/soc/marvell/mvmap2315/power.c b/src/soc/marvell/mvmap2315/power.c
index 578fb51..bf7ffda 100644
--- a/src/soc/marvell/mvmap2315/power.c
+++ b/src/soc/marvell/mvmap2315/power.c
@@ -13,11 +13,95 @@
  * GNU General Public License for more details.
  */
 
+#include <arch/io.h>
+#include <console/console.h>
+#include <soc/apmu.h>
+#include <soc/assert.h>
+#include <soc/clock.h>
 #include <soc/power.h>
+#include <soc/pwr_types.h>
+
+static void enable_sys_power(void)
+{
+	int result = 0;
+
+	/* Start the PLLs */
+	result |= apmu_set_pll_state(MAIN_PLL, D0, 2000);
+	result |= apmu_set_pll_state(CPU_PLL, D0, 2400);
+	result |= apmu_set_pll_state(MC_PLL, D0, 3200);
+	result |= apmu_set_pll_state(MCFLC_PLL, D0, 2133);
+	result |= apmu_set_pll_state(A2_PLL, D0, 1800);
+	result |= apmu_set_pll_state(GPU_PLL0, D0, 2000);
+	result |= apmu_set_pll_state(GPU_PLL1, D0, 2400);
+	result |= apmu_set_pll_state(MIPI_PLL, D0, 2000);
+	result |= apmu_set_pll_state(DISPLAY_PLL, D0, 1800);
+
+	/* Start the peripheral devices */
+	result |= apmu_set_device_state(A2, D0);
+	result |= apmu_set_device_state(MC, D0);
+	result |= apmu_set_device_state(SDMMC, D0);
+	result |= apmu_set_device_state(AES256, D0);
+	result |= apmu_set_device_state(AP_AXI_HS, D0);
+	result |= apmu_set_device_state(AP_UART0, D0);
+	result |= apmu_set_device_state(AP_UART1, D0);
+	result |= apmu_set_device_state(AP_M2M, D0);
+	result |= apmu_set_device_state(AP_APB, D0);
+	result |= apmu_set_device_state(AP_GIC, D0);
+
+	if (result != 0)
+		__assert("ERRORS DURING POWER-on", __FILE__, __LINE__);
+}
 
 void start_ap_cores(void *entry)
 {
-	/*TODO: start_ap_cores */
+	int result = 0;
+	u32 reg;
+
+	printk(BIOS_INFO, "Writing APGenCfg, initial value is %x.\n",
+	       read32(&mvmap2315_cpu->apgencfg));
+
+	reg = read32(&mvmap2315_cpu->apgencfg);
+
+	reg |= MVMAP2315_APGENCFG_SYSBARDISABLE;
+	reg |= MVMAP2315_APGENCFG_BROADCASTINNER;
+	reg &= ~MVMAP2315_APGENCFG_BROADCASTOUTER;
+	reg |= MVMAP2315_APGENCFG_BROADCASTCACHEMAINT;
+	reg |= MVMAP2315_APGENCFG_BROADCASTCACHEMAINTPOU;
+
+	write32(&mvmap2315_cpu->apgencfg, reg);
+
+	printk(BIOS_INFO, "Writes complete, APGenCfg is now %x.\n",
+	       read32(&mvmap2315_cpu->apgencfg));
+
+	result |= apmu_set_device_state(APCPU_L2, D0);
+
+	reg = read32(&mvmap2315_cpu->apcorecfg0);
+	reg |= MVMAP2315_APCORECFG0_AA64NAA32;
+	write32(&mvmap2315_cpu->apcorecfg0, reg);
+
+	write32(&mvmap2315_cpu->rvbaraddr_low0, ((uintptr_t)entry) >> 2);
+	write32(&mvmap2315_cpu->rvbaraddr_high0, 0);
+
+	result |= apmu_set_device_state(APCPU_0, D0);
+
+	if (result != 0)
+		__assert("ERRORS DURING POWER-on", __FILE__, __LINE__);
+}
+
+void mcu_start(void)
+{
+	u32 reg;
+
+	apmu_set_pll_state(APLL0, D0, APLL_589P824);
+	apmu_set_clock_state(M4CLK, NOCHANGE, 4, SRCSEL_APLL0);
+
+	reg = read32(&mvmap2315_mpmu_clk->resetmcu);
+	reg &= ~MVMAP2315_MCU_RST_EN;
+	write32(&mvmap2315_mpmu_clk->resetmcu, reg);
+
+	reg = read32(&mvmap2315_mpmu_clk->resetmcu);
+	reg |= MVMAP2315_MCU_RST_EN;
+	write32(&mvmap2315_mpmu_clk->resetmcu, reg);
 }
 
 void no_boot(void)
@@ -32,7 +116,8 @@ void charging_screen(void)
 
 void full_boot(void)
 {
-	/*TODO: impelement full_boot */
+	printk(BIOS_INFO, "Powering up the system.\n");
+	enable_sys_power();
 }
 
 u32 get_boot_path(void)
diff --git a/src/soc/marvell/mvmap2315/romstage.c b/src/soc/marvell/mvmap2315/romstage.c
index bc9172e..f4c64d2 100644
--- a/src/soc/marvell/mvmap2315/romstage.c
+++ b/src/soc/marvell/mvmap2315/romstage.c
@@ -13,10 +13,12 @@
  * GNU General Public License for more details.
  */
 
+#include <arch/io.h>
 #include <console/console.h>
 #include <console/uart.h>
 #include <program_loading.h>
 #include <soc/addressmap.h>
+#include <soc/apmu.h>
 #include <soc/assert.h>
 #include <soc/bdb.h>
 #include <soc/bootrom.h>
@@ -63,6 +65,22 @@ void main(void)
 	printk(BIOS_INFO, "loading and validating APMU FIRMWARE\n");
 	load_and_validate_image(&bdb_info, APMU_FIRMWARE);
 
+	/* Temporary fix for emulation testing only
+	 * TODO: remove in real silicon
+	 */
+	write32(&mvmap2315_apmu_pwrctl->scratch0, 0x900dc0de);
+
+	apmu_start(4, 5);
+
+	if (!(read32((void *)MVMAP2315_LOWPWR_REG) & MVMAP2315_LOWPWR_FLAG)) {
+		printk(BIOS_INFO, "loading and validating MCU FIRMWARE\n");
+		load_and_validate_image(&bdb_info, MCU_FIRMWARE);
+		mcu_start();
+	} else {
+		printk(BIOS_INFO, "low power restart. skip MCU code load\n");
+		printk(BIOS_INFO, "TODO: check MCU Firmware hash\n");
+	}
+
 	boot_path = get_boot_path();
 
 	switch (boot_path) {
@@ -79,6 +97,8 @@ void main(void)
 		break;
 	}
 
+	apmu_declare_s0();
+
 	timestamp_add_now(TS_END_ROMSTAGE);
 
 	run_ramstage();



More information about the coreboot-gerrit mailing list