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 += flash.c
|
||||
bootblock-y += load_validate.c
|
||||
bootblock-y += mcu.c
|
||||
bootblock-y += media.c
|
||||
bootblock-y += nvm.c
|
||||
bootblock-y += pinmux.c
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <soc/bdb.h>
|
||||
#include <soc/gic.h>
|
||||
#include <soc/load_validate.h>
|
||||
#include <soc/mcu.h>
|
||||
#include <soc/pmic.h>
|
||||
#include <soc/uart.h>
|
||||
|
||||
|
@ -64,6 +65,13 @@ void bootblock_soc_init(void)
|
|||
boot_path = get_boot_path();
|
||||
} else {
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
#define MVMAP2315_GPIOH_BASE 0xE0142200
|
||||
#define MVMAP2315_WDT0_BASE 0XE1010000
|
||||
#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_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 <soc/apmu.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/mcu.h>
|
||||
#include <soc/pmic.h>
|
||||
|
||||
static void syspwr_init(void)
|
||||
|
@ -121,5 +122,11 @@ void mcu_start(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