feat(mediatek): add APU bootup control smc call

Add APU bootup control smc call.
The steps of bootup flow:
  1. set up APU config.
  2. reset APU.
  3. set up APU boot config.
  4. boot APU.

Change-Id: I9e930070a64c7c4dcaa3a8b3d28b897823e9f53c
Signed-off-by: Chungying Lu <chungying.lu@mediatek.com>
Signed-off-by: Karl Li <karl.li@mediatek.com>
This commit is contained in:
Chungying Lu 2023-04-19 17:17:23 +08:00 committed by Karl Li
parent ad7673adef
commit 94a9e6243e
5 changed files with 263 additions and 12 deletions

View file

@ -35,6 +35,21 @@ static u_register_t apusys_kernel_handler(u_register_t x1,
case MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_OFF:
ret = apusys_kernel_apusys_pwr_top_off();
break;
case MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_REVISER:
ret = apusys_kernel_apusys_rv_setup_reviser();
break;
case MTK_APUSYS_KERNEL_OP_APUSYS_RV_RESET_MP:
ret = apusys_kernel_apusys_rv_reset_mp();
break;
case MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_BOOT:
ret = apusys_kernel_apusys_rv_setup_boot();
break;
case MTK_APUSYS_KERNEL_OP_APUSYS_RV_START_MP:
ret = apusys_kernel_apusys_rv_start_mp();
break;
case MTK_APUSYS_KERNEL_OP_APUSYS_RV_STOP_MP:
ret = apusys_kernel_apusys_rv_stop_mp();
break;
default:
ERROR(MODULE_TAG "%s unknown request_ops = %x\n", MODULE_TAG, request_ops);
break;

View file

@ -10,8 +10,13 @@
#define MODULE_TAG "[APUSYS]"
enum MTK_APUSYS_KERNEL_OP {
MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_ON, /* 0 */
MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_OFF,/* 1 */
MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_ON, /* 0 */
MTK_APUSYS_KERNEL_OP_APUSYS_PWR_TOP_OFF, /* 1 */
MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_REVISER, /* 2 */
MTK_APUSYS_KERNEL_OP_APUSYS_RV_RESET_MP, /* 3 */
MTK_APUSYS_KERNEL_OP_APUSYS_RV_SETUP_BOOT, /* 4 */
MTK_APUSYS_KERNEL_OP_APUSYS_RV_START_MP, /* 5 */
MTK_APUSYS_KERNEL_OP_APUSYS_RV_STOP_MP, /* 6 */
MTK_APUSYS_KERNEL_OP_NUM,
};

View file

@ -6,12 +6,17 @@
/* TF-A system header */
#include <common/debug.h>
#include <drivers/delay_timer.h>
#include <lib/mmio.h>
#include <lib/spinlock.h>
/* Vendor header */
#include "apusys.h"
#include "apusys_rv.h"
#include "apusys_rv_mbox_mpu.h"
static spinlock_t apusys_rv_lock;
void apusys_rv_mbox_mpu_init(void)
{
int i;
@ -28,3 +33,151 @@ void apusys_rv_mbox_mpu_init(void)
(mbox_mpu_setting_tab[i].tx_domain << MBOX_TX_DOMAIN_SHIFT)));
}
}
int apusys_kernel_apusys_rv_setup_reviser(void)
{
static bool apusys_rv_setup_reviser_called;
spin_lock(&apusys_rv_lock);
if (apusys_rv_setup_reviser_called) {
WARN(MODULE_TAG "%s: already initialized\n", __func__);
spin_unlock(&apusys_rv_lock);
return -1;
}
apusys_rv_setup_reviser_called = true;
mmio_write_32(USERFW_CTXT, CFG_4GB_SEL_EN | CFG_4GB_SEL);
mmio_write_32(SECUREFW_CTXT, CFG_4GB_SEL_EN | CFG_4GB_SEL);
mmio_write_32(UP_IOMMU_CTRL, MMU_CTRL_LOCK | MMU_CTRL | MMU_EN);
mmio_write_32(UP_NORMAL_DOMAIN_NS,
(UP_NORMAL_DOMAIN << UP_DOMAIN_SHIFT) | (UP_NORMAL_NS << UP_NS_SHIFT));
mmio_write_32(UP_PRI_DOMAIN_NS,
(UP_PRI_DOMAIN << UP_DOMAIN_SHIFT) | (UP_PRI_NS << UP_NS_SHIFT));
mmio_write_32(UP_CORE0_VABASE0,
VLD | PARTIAL_ENABLE | (THREAD_NUM_PRI << THREAD_NUM_SHIFT));
mmio_write_32(UP_CORE0_MVABASE0, VASIZE_1MB | (APU_SEC_FW_IOVA >> MVA_34BIT_SHIFT));
mmio_write_32(UP_CORE0_VABASE1,
VLD | PARTIAL_ENABLE | (THREAD_NUM_NORMAL << THREAD_NUM_SHIFT));
mmio_write_32(UP_CORE0_MVABASE1, VASIZE_1MB | (APU_SEC_FW_IOVA >> MVA_34BIT_SHIFT));
spin_unlock(&apusys_rv_lock);
return 0;
}
int apusys_kernel_apusys_rv_reset_mp(void)
{
static bool apusys_rv_reset_mp_called;
spin_lock(&apusys_rv_lock);
if (apusys_rv_reset_mp_called) {
WARN(MODULE_TAG "%s: already initialized\n", __func__);
spin_unlock(&apusys_rv_lock);
return -1;
}
apusys_rv_reset_mp_called = true;
mmio_write_32(MD32_SYS_CTRL, MD32_SYS_CTRL_RST);
udelay(RESET_DEALY_US);
mmio_write_32(MD32_SYS_CTRL, MD32_G2B_CG_EN | MD32_DBG_EN | MD32_DM_AWUSER_IOMMU_EN |
MD32_DM_ARUSER_IOMMU_EN | MD32_PM_AWUSER_IOMMU_EN | MD32_PM_ARUSER_IOMMU_EN |
MD32_SOFT_RSTN);
mmio_write_32(MD32_CLK_CTRL, MD32_CLK_EN);
mmio_write_32(UP_WAKE_HOST_MASK0, WDT_IRQ_EN);
mmio_write_32(UP_WAKE_HOST_MASK1, MBOX0_IRQ_EN | MBOX1_IRQ_EN | MBOX2_IRQ_EN);
spin_unlock(&apusys_rv_lock);
return 0;
}
int apusys_kernel_apusys_rv_setup_boot(void)
{
static bool apusys_rv_setup_boot_called;
spin_lock(&apusys_rv_lock);
if (apusys_rv_setup_boot_called) {
WARN(MODULE_TAG "%s: already initialized\n", __func__);
spin_unlock(&apusys_rv_lock);
return -1;
}
apusys_rv_setup_boot_called = true;
mmio_write_32(MD32_BOOT_CTRL, APU_SEC_FW_IOVA);
mmio_write_32(MD32_PRE_DEFINE, (PREDEFINE_CACHE_TCM << PREDEF_1G_OFS) |
(PREDEFINE_CACHE << PREDEF_2G_OFS) | (PREDEFINE_CACHE << PREDEF_3G_OFS) |
(PREDEFINE_CACHE << PREDEF_4G_OFS));
spin_unlock(&apusys_rv_lock);
return 0;
}
int apusys_kernel_apusys_rv_start_mp(void)
{
static bool apusys_rv_start_mp_called;
spin_lock(&apusys_rv_lock);
if (apusys_rv_start_mp_called) {
WARN(MODULE_TAG "%s: already initialized\n", __func__);
spin_unlock(&apusys_rv_lock);
return -1;
}
apusys_rv_start_mp_called = true;
mmio_write_32(MD32_RUNSTALL, MD32_RUN);
spin_unlock(&apusys_rv_lock);
return 0;
}
static bool watch_dog_is_timeout(void)
{
if (mmio_read_32(WDT_INT) != WDT_INT_W1C) {
ERROR(MODULE_TAG "%s: WDT does not timeout\n", __func__);
return false;
}
return true;
}
int apusys_kernel_apusys_rv_stop_mp(void)
{
static bool apusys_rv_stop_mp_called;
spin_lock(&apusys_rv_lock);
if (apusys_rv_stop_mp_called) {
WARN(MODULE_TAG "%s: already initialized\n", __func__);
spin_unlock(&apusys_rv_lock);
return -1;
}
if (watch_dog_is_timeout() == false) {
spin_unlock(&apusys_rv_lock);
return -1;
}
apusys_rv_stop_mp_called = true;
mmio_write_32(MD32_RUNSTALL, MD32_STALL);
spin_unlock(&apusys_rv_lock);
return 0;
}

View file

@ -9,17 +9,87 @@
#include <platform_def.h>
#define APU_SEC_FW_IOVA (0x200000UL)
/* APU_SCTRL_REVISER */
#define UP_NORMAL_DOMAIN_NS (APU_REVISER + 0x0000)
#define UP_PRI_DOMAIN_NS (APU_REVISER + 0x0004)
#define UP_IOMMU_CTRL (APU_REVISER + 0x0008)
#define UP_CORE0_VABASE0 (APU_REVISER + 0x000c)
#define UP_CORE0_MVABASE0 (APU_REVISER + 0x0010)
#define UP_CORE0_VABASE1 (APU_REVISER + 0x0014)
#define UP_CORE0_MVABASE1 (APU_REVISER + 0x0018)
#define USERFW_CTXT (APU_REVISER + 0x1000)
#define SECUREFW_CTXT (APU_REVISER + 0x1004)
#define UP_NORMAL_DOMAIN (7)
#define UP_NORMAL_NS (1)
#define UP_PRI_DOMAIN (5)
#define UP_PRI_NS (1)
#define UP_DOMAIN_SHIFT (0)
#define UP_NS_SHIFT (4)
#define MMU_EN BIT(0)
#define MMU_CTRL BIT(1)
#define MMU_CTRL_LOCK BIT(2)
#define VLD BIT(0)
#define PARTIAL_ENABLE BIT(1)
#define THREAD_NUM_PRI (1)
#define THREAD_NUM_NORMAL (0)
#define THREAD_NUM_SHIFT (2)
#define VASIZE_1MB BIT(0)
#define CFG_4GB_SEL_EN BIT(2)
#define CFG_4GB_SEL (0)
#define MVA_34BIT_SHIFT (2)
/* APU_MD32_SYSCTRL */
#define MD32_SYS_CTRL (APU_MD32_SYSCTRL + 0x0000)
#define MD32_CLK_CTRL (APU_MD32_SYSCTRL + 0x00b8)
#define UP_WAKE_HOST_MASK0 (APU_MD32_SYSCTRL + 0x00bc)
#define UP_WAKE_HOST_MASK1 (APU_MD32_SYSCTRL + 0x00c0)
#define MD32_SYS_CTRL_RST (0)
#define MD32_G2B_CG_EN BIT(11)
#define MD32_DBG_EN BIT(10)
#define MD32_DM_AWUSER_IOMMU_EN BIT(9)
#define MD32_DM_ARUSER_IOMMU_EN BIT(7)
#define MD32_PM_AWUSER_IOMMU_EN BIT(5)
#define MD32_PM_ARUSER_IOMMU_EN BIT(3)
#define MD32_SOFT_RSTN BIT(0)
#define MD32_CLK_EN (1)
#define WDT_IRQ_EN BIT(0)
#define MBOX0_IRQ_EN BIT(21)
#define MBOX1_IRQ_EN BIT(22)
#define MBOX2_IRQ_EN BIT(23)
#define RESET_DEALY_US (10)
/* APU_AO_CTRL */
#define MD32_PRE_DEFINE (APU_AO_CTRL + 0x0000)
#define MD32_BOOT_CTRL (APU_AO_CTRL + 0x0004)
#define MD32_RUNSTALL (APU_AO_CTRL + 0x0008)
#define PREDEFINE_NON_CACHE (0)
#define PREDEFINE_TCM (1)
#define PREDEFINE_CACHE (2)
#define PREDEFINE_CACHE_TCM (3)
#define PREDEF_1G_OFS (0)
#define PREDEF_2G_OFS (2)
#define PREDEF_3G_OFS (4)
#define PREDEF_4G_OFS (6)
#define MD32_RUN (0)
#define MD32_STALL (1)
/* APU_MD32_WDT */
#define WDT_INT (APU_MD32_WDT + 0x0)
#define WDT_INT_W1C (1)
/* APU MBOX */
#define MBOX_FUNC_CFG (0xb0)
#define MBOX_DOMAIN_CFG (0xe0)
#define MBOX_CTRL_LOCK BIT(0)
#define MBOX_NO_MPU_SHIFT (16)
#define MBOX_RX_NS_SHIFT (16)
#define MBOX_RX_DOMAIN_SHIFT (17)
#define MBOX_TX_NS_SHIFT (24)
#define MBOX_TX_DOMAIN_SHIFT (25)
#define MBOX_SIZE (0x100)
#define MBOX_NUM (8)
#define MBOX_FUNC_CFG (0xb0)
#define MBOX_DOMAIN_CFG (0xe0)
#define MBOX_CTRL_LOCK BIT(0)
#define MBOX_NO_MPU_SHIFT (16)
#define MBOX_RX_NS_SHIFT (16)
#define MBOX_RX_DOMAIN_SHIFT (17)
#define MBOX_TX_NS_SHIFT (24)
#define MBOX_TX_DOMAIN_SHIFT (25)
#define MBOX_SIZE (0x100)
#define MBOX_NUM (8)
#define APU_MBOX(i) (((i) < MBOX_NUM) ? (APU_MBOX0 + MBOX_SIZE * (i)) : \
(APU_MBOX1 + MBOX_SIZE * ((i) - MBOX_NUM)))
@ -27,5 +97,10 @@
#define APU_MBOX_DOMAIN_CFG(i) (APU_MBOX(i) + MBOX_DOMAIN_CFG)
void apusys_rv_mbox_mpu_init(void);
int apusys_kernel_apusys_rv_setup_reviser(void);
int apusys_kernel_apusys_rv_reset_mp(void);
int apusys_kernel_apusys_rv_setup_boot(void);
int apusys_kernel_apusys_rv_start_mp(void);
int apusys_kernel_apusys_rv_stop_mp(void);
#endif /* APUSYS_RV_H */

View file

@ -28,7 +28,10 @@
* APUSYS related constants
******************************************************************************/
#define BCRM_FMEM_PDN_BASE (IO_PHYS + 0x00276000)
#define APU_MD32_SYSCTRL (IO_PHYS + 0x09001000)
#define APU_MD32_WDT (IO_PHYS + 0x09002000)
#define APU_RCX_CONFIG (IO_PHYS + 0x09020000)
#define APU_REVISER (IO_PHYS + 0x0903c000)
#define APU_RCX_VCORE_CONFIG (IO_PHYS + 0x090e0000)
#define APU_MBOX0 (IO_PHYS + 0x090e1000)
#define APU_MBOX1 (IO_PHYS + 0x090e2000)