soc/marvell/mvmap2315: Add MCU driver
Testing: booted successfully. Change-Id: I003f6929b00476d46be931773cd35418fe6622a6 Signed-off-by: Hakim Giydan <hgiydan@marvell.com> Reviewed-on: https://review.coreboot.org/15529 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth <martinroth@google.com>
This commit is contained in:
parent
34c835db30
commit
f727c7ce38
|
@ -26,6 +26,7 @@ bootblock-y += gic.c
|
||||||
bootblock-y += gpio.c
|
bootblock-y += gpio.c
|
||||||
bootblock-y += flash.c
|
bootblock-y += flash.c
|
||||||
bootblock-y += load_validate.c
|
bootblock-y += load_validate.c
|
||||||
|
bootblock-y += mcu.c
|
||||||
bootblock-y += media.c
|
bootblock-y += media.c
|
||||||
bootblock-y += nvm.c
|
bootblock-y += nvm.c
|
||||||
bootblock-y += pinmux.c
|
bootblock-y += pinmux.c
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <soc/bdb.h>
|
#include <soc/bdb.h>
|
||||||
#include <soc/gic.h>
|
#include <soc/gic.h>
|
||||||
#include <soc/load_validate.h>
|
#include <soc/load_validate.h>
|
||||||
|
#include <soc/mcu.h>
|
||||||
#include <soc/pmic.h>
|
#include <soc/pmic.h>
|
||||||
#include <soc/uart.h>
|
#include <soc/uart.h>
|
||||||
|
|
||||||
|
@ -64,6 +65,13 @@ void bootblock_soc_init(void)
|
||||||
boot_path = get_boot_path();
|
boot_path = get_boot_path();
|
||||||
} else {
|
} else {
|
||||||
printk(BIOS_DEBUG, "Low power restart. Skip MCU code load.\n");
|
printk(BIOS_DEBUG, "Low power restart. Skip MCU code load.\n");
|
||||||
|
|
||||||
|
sned_hash_msg(GET_HASH);
|
||||||
|
receive_hash_msg_respond();
|
||||||
|
|
||||||
|
printk(BIOS_DEBUG,
|
||||||
|
"MCU hash validation not currently implemented\n");
|
||||||
|
|
||||||
boot_path = get_boot_path();
|
boot_path = get_boot_path();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
#define MVMAP2315_GPIOH_BASE 0xE0142200
|
#define MVMAP2315_GPIOH_BASE 0xE0142200
|
||||||
#define MVMAP2315_WDT0_BASE 0XE1010000
|
#define MVMAP2315_WDT0_BASE 0XE1010000
|
||||||
#define MVMAP2315_WDT1_BASE 0XE1020000
|
#define MVMAP2315_WDT1_BASE 0XE1020000
|
||||||
|
#define MVMAP2315_SP_IPC_BASE 0xED0C2000
|
||||||
|
#define MVMAP2315_MCU_MSG_BUFF_BASE 0xEE03FF8C
|
||||||
|
|
||||||
#define MVMAP2315_A2BUS_BANKED_BASE 0xF0000000
|
#define MVMAP2315_A2BUS_BANKED_BASE 0xF0000000
|
||||||
#define MVMAP2315_A2BUS_ALIAS6_BASE 0xF0002000
|
#define MVMAP2315_A2BUS_ALIAS6_BASE 0xF0002000
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
/*
|
||||||
|
* 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_MCU_H__
|
||||||
|
#define __SOC_MARVELL_MVMAP2315_MCU_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <soc/addressmap.h>
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
|
#define MVMAP2315_MCU_MSG_OFFSET 0xCE000000
|
||||||
|
|
||||||
|
enum {
|
||||||
|
GET_HASH = 0x0,
|
||||||
|
ABORT_HASH = 0x1,
|
||||||
|
START_HASH = 0x2,
|
||||||
|
SYNC_HASH = 0x3,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ABORT = 0x0,
|
||||||
|
FINISHED = 0x1,
|
||||||
|
BUSY = 0x2
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
MSG_READY = 1,
|
||||||
|
MSG_RECEIVED = 8,
|
||||||
|
MSG_READY_RECEIVED = 9,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sp_hash_request_msg {
|
||||||
|
u8 protocol_version;
|
||||||
|
u8 csum;
|
||||||
|
u16 cmd_id;
|
||||||
|
u8 cmd_version;
|
||||||
|
u8 reserved0;
|
||||||
|
u16 length;
|
||||||
|
u8 hash_subcmd;
|
||||||
|
u8 hash_type;
|
||||||
|
u8 nonce_size;
|
||||||
|
u8 reserved1;
|
||||||
|
u32 offset;
|
||||||
|
u32 size;
|
||||||
|
u8 nonce_data[64];
|
||||||
|
};
|
||||||
|
|
||||||
|
check_member(sp_hash_request_msg, nonce_data, 0x14);
|
||||||
|
static struct sp_hash_request_msg * const mvmap2315_mcu_msg_buff
|
||||||
|
= (void *)MVMAP2315_MCU_MSG_BUFF_BASE;
|
||||||
|
|
||||||
|
struct mcu_hash_msg {
|
||||||
|
u8 protocol_version;
|
||||||
|
u8 csum;
|
||||||
|
u16 result;
|
||||||
|
u16 length;
|
||||||
|
u8 status;
|
||||||
|
u8 type;
|
||||||
|
u8 digest_size;
|
||||||
|
u8 reserved0;
|
||||||
|
u32 offset;
|
||||||
|
u32 size;
|
||||||
|
u8 digest_data[64];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mcu_pwr_status_msg {
|
||||||
|
u8 protocol_version;
|
||||||
|
u8 csum;
|
||||||
|
u16 cmd_id;
|
||||||
|
u8 cmd_version;
|
||||||
|
u8 reserved;
|
||||||
|
u16 length;
|
||||||
|
u8 status;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MVMAP2315_IPC_IRQSET_MSGSENT BIT(0)
|
||||||
|
#define MVMAP2315_IPC_IRQCLR_MSGREADY BIT(0)
|
||||||
|
#define MVMAP2315_IPC_IRQCLR_MSGRECEIVED BIT(3)
|
||||||
|
#define MVMAP2315_IPC_IRQACK BIT(3)
|
||||||
|
#define MVMAP2315_MCU_IPC_IRQ BIT(6)
|
||||||
|
struct mvmap2315_ipc_regs {
|
||||||
|
u32 isrr;
|
||||||
|
u32 wdr0;
|
||||||
|
u32 wdr1;
|
||||||
|
u32 isrw;
|
||||||
|
u32 icr;
|
||||||
|
u32 iir;
|
||||||
|
u32 rdr0;
|
||||||
|
u32 rdr1;
|
||||||
|
u32 maj_mid_rev;
|
||||||
|
u32 cfg_rev;
|
||||||
|
u32 dummy;
|
||||||
|
};
|
||||||
|
|
||||||
|
check_member(mvmap2315_ipc_regs, dummy, 0x28);
|
||||||
|
static struct mvmap2315_ipc_regs * const mvmap2315_sp_ipc
|
||||||
|
= (void *)MVMAP2315_SP_IPC_BASE;
|
||||||
|
|
||||||
|
void mcu_irq(void);
|
||||||
|
void send_mcu_msg(void *msg, u32 size);
|
||||||
|
void *receive_mcu_msg(void);
|
||||||
|
void sned_hash_msg(u8 subcmd);
|
||||||
|
void *receive_hash_msg_respond(void);
|
||||||
|
|
||||||
|
#endif /* __SOC_MARVELL_MVMAP2315_MCU_H__ */
|
|
@ -0,0 +1,130 @@
|
||||||
|
/*
|
||||||
|
* 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 <console/console.h>
|
||||||
|
#include <soc/gic.h>
|
||||||
|
#include <soc/mcu.h>
|
||||||
|
|
||||||
|
static u8 mvmap2315_calc_checksum(const void *data, u32 size)
|
||||||
|
{
|
||||||
|
u8 csum;
|
||||||
|
const u8 *bytes = data;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = csum = 0; i < size; i++)
|
||||||
|
csum += bytes[i];
|
||||||
|
|
||||||
|
return (~csum) && 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mcu_irq(void)
|
||||||
|
{
|
||||||
|
printk(BIOS_DEBUG, "waiting for MCU msg...\n");
|
||||||
|
while (!(read32(&mvmap2315_bcm_gicd->ispendr2) &
|
||||||
|
MVMAP2315_MCU_IPC_IRQ))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void send_mcu_msg(void *msg, u32 size)
|
||||||
|
{
|
||||||
|
printk(BIOS_DEBUG, "sending msg to MCU...\n");
|
||||||
|
write32(&mvmap2315_sp_ipc->wdr0, (u32)msg);
|
||||||
|
setbits_le32(&mvmap2315_sp_ipc->isrw, MVMAP2315_IPC_IRQSET_MSGSENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *receive_mcu_msg(void)
|
||||||
|
{
|
||||||
|
void *msg;
|
||||||
|
|
||||||
|
printk(BIOS_DEBUG, "receiving msg to MCU...\n");
|
||||||
|
|
||||||
|
write32(&mvmap2315_sp_ipc->dummy, 0xA5A5A5A5);
|
||||||
|
|
||||||
|
switch (read32(&mvmap2315_sp_ipc->iir)) {
|
||||||
|
case MSG_READY:
|
||||||
|
msg = (void *)(read32(&mvmap2315_sp_ipc->rdr0)
|
||||||
|
+ MVMAP2315_MCU_MSG_OFFSET);
|
||||||
|
setbits_le32(&mvmap2315_sp_ipc->icr,
|
||||||
|
MVMAP2315_IPC_IRQCLR_MSGREADY);
|
||||||
|
setbits_le32(&mvmap2315_sp_ipc->isrw, MVMAP2315_IPC_IRQACK);
|
||||||
|
break;
|
||||||
|
case MSG_RECEIVED:
|
||||||
|
msg = NULL;
|
||||||
|
setbits_le32(&mvmap2315_sp_ipc->icr,
|
||||||
|
MVMAP2315_IPC_IRQCLR_MSGRECEIVED);
|
||||||
|
break;
|
||||||
|
case MSG_READY_RECEIVED:
|
||||||
|
msg = (void *)(read32(&mvmap2315_sp_ipc->rdr0)
|
||||||
|
+ MVMAP2315_MCU_MSG_OFFSET);
|
||||||
|
setbits_le32(&mvmap2315_sp_ipc->icr,
|
||||||
|
MVMAP2315_IPC_IRQCLR_MSGREADY);
|
||||||
|
setbits_le32(&mvmap2315_sp_ipc->icr,
|
||||||
|
MVMAP2315_IPC_IRQCLR_MSGRECEIVED);
|
||||||
|
setbits_le32(&mvmap2315_sp_ipc->isrw, MVMAP2315_IPC_IRQACK);
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
msg = NULL;
|
||||||
|
write32(&mvmap2315_sp_ipc->icr, read32(&mvmap2315_sp_ipc->iir));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sned_hash_msg(u8 subcmd)
|
||||||
|
{
|
||||||
|
printk(BIOS_DEBUG, "requesting MCU hash...\n");
|
||||||
|
|
||||||
|
mvmap2315_mcu_msg_buff->protocol_version = 0x3;
|
||||||
|
mvmap2315_mcu_msg_buff->cmd_id = 0x2A;
|
||||||
|
mvmap2315_mcu_msg_buff->reserved0 = 0x0;
|
||||||
|
mvmap2315_mcu_msg_buff->length = 76;
|
||||||
|
mvmap2315_mcu_msg_buff->csum = 0;
|
||||||
|
mvmap2315_mcu_msg_buff->hash_subcmd = subcmd;
|
||||||
|
mvmap2315_mcu_msg_buff->hash_type = 0;
|
||||||
|
mvmap2315_mcu_msg_buff->nonce_size = 0;
|
||||||
|
mvmap2315_mcu_msg_buff->reserved1 = 0;
|
||||||
|
mvmap2315_mcu_msg_buff->offset = 0;
|
||||||
|
mvmap2315_mcu_msg_buff->size = 32;
|
||||||
|
mvmap2315_mcu_msg_buff->csum = mvmap2315_calc_checksum(
|
||||||
|
(void *)mvmap2315_mcu_msg_buff,
|
||||||
|
sizeof(struct sp_hash_request_msg));
|
||||||
|
|
||||||
|
send_mcu_msg((void *)mvmap2315_mcu_msg_buff,
|
||||||
|
sizeof(struct sp_hash_request_msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
void *receive_hash_msg_respond(void)
|
||||||
|
{
|
||||||
|
struct mcu_hash_msg *mvmap2315_hash_msg_response;
|
||||||
|
|
||||||
|
printk(BIOS_DEBUG, "waiting for MCU hash response msg...\n");
|
||||||
|
|
||||||
|
mcu_irq();
|
||||||
|
|
||||||
|
mvmap2315_hash_msg_response = receive_mcu_msg();
|
||||||
|
|
||||||
|
mcu_irq();
|
||||||
|
|
||||||
|
receive_mcu_msg();
|
||||||
|
|
||||||
|
return mvmap2315_hash_msg_response;
|
||||||
|
}
|
|
@ -22,6 +22,7 @@
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
#include <soc/apmu.h>
|
#include <soc/apmu.h>
|
||||||
#include <soc/clock.h>
|
#include <soc/clock.h>
|
||||||
|
#include <soc/mcu.h>
|
||||||
#include <soc/pmic.h>
|
#include <soc/pmic.h>
|
||||||
|
|
||||||
static void syspwr_init(void)
|
static void syspwr_init(void)
|
||||||
|
@ -121,5 +122,11 @@ void mcu_start(void)
|
||||||
|
|
||||||
u32 get_boot_path(void)
|
u32 get_boot_path(void)
|
||||||
{
|
{
|
||||||
return FULL_BOOT;
|
struct mcu_pwr_status_msg *msg;
|
||||||
|
|
||||||
|
mcu_irq();
|
||||||
|
|
||||||
|
msg = receive_mcu_msg();
|
||||||
|
|
||||||
|
return msg->status;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue