mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-17 01:54:22 +00:00
feat(imx8ulp): add i.MX8ULP basic support
Add the basic support for i.MX8ULP. The i.MX 8ULP family of processors features NXP’s advanced implementation of the dual Arm Cortex-A35 cores alongside an Arm Cortex-M33. This combined architecture enables the device to run a rich operating system (such as Linux) on the Cortex-A35 core and an RTOS (such as FreeRTOS) on the Cortex-M33 core. It also includes a Cadence Tensilica Fusion DSP for low-power audio and a HiFi4 DSP for advanced audio and machine learning applications. Signed-off-by: Peng Fan <peng.fan@nxp.com> Signed-off-by: Ye Li <ye.li@nxp.com> Signed-off-by: Jacky Bai <ping.bai@nxp.com> Change-Id: I12df622b95960bcdf7da52e4c66470a700690e36
This commit is contained in:
parent
0d6b4cdb23
commit
fcd41e8692
20 changed files with 8281 additions and 3 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -86,6 +86,31 @@ func plat_calc_core_pos
|
|||
ret
|
||||
endfunc plat_calc_core_pos
|
||||
|
||||
/* ----------------------------------------------
|
||||
* function to handle platform specific reset.
|
||||
* ----------------------------------------------
|
||||
*/
|
||||
func plat_reset_handler
|
||||
#if defined(PLAT_imx8ulp)
|
||||
mrs x0, CORTEX_A35_CPUECTLR_EL1
|
||||
orr x0, x0, #(0x1 << 0)
|
||||
orr x0, x0, #(0x1 << 3)
|
||||
msr CORTEX_A35_CPUECTLR_EL1, x0
|
||||
|
||||
mrs x0, CORTEX_A35_L2ECTLR_EL1
|
||||
orr x0, x0, #(0x1 << 0)
|
||||
msr CORTEX_A35_L2ECTLR_EL1, x0
|
||||
isb
|
||||
#endif
|
||||
/* enable EL2 cpuectlr RW access */
|
||||
mov x0, #0x73
|
||||
msr actlr_el3, x0
|
||||
msr actlr_el2, x0
|
||||
isb
|
||||
|
||||
ret
|
||||
endfunc plat_reset_handler
|
||||
|
||||
/* ---------------------------------------------
|
||||
* function to get the entrypoint.
|
||||
* ---------------------------------------------
|
||||
|
|
23
plat/imx/common/imx_bl31_common.c
Normal file
23
plat/imx/common/imx_bl31_common.c
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright 2023-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <imx_plat_common.h>
|
||||
|
||||
uint32_t plat_get_spsr_for_bl33_entry(void)
|
||||
{
|
||||
unsigned long el_status;
|
||||
unsigned long mode;
|
||||
uint32_t spsr;
|
||||
|
||||
/* figure out what mode we enter the non-secure world */
|
||||
el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
|
||||
el_status &= ID_AA64PFR0_ELX_MASK;
|
||||
|
||||
mode = (el_status) ? MODE_EL2 : MODE_EL1;
|
||||
|
||||
spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
|
||||
return spsr;
|
||||
}
|
|
@ -1,14 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <common/runtime_svc.h>
|
||||
#include <drivers/scmi-msg.h>
|
||||
#include <lib/pmf/pmf.h>
|
||||
#include <tools_share/uuid.h>
|
||||
|
||||
#include <imx_sip_svc.h>
|
||||
|
||||
static int32_t imx_sip_setup(void)
|
||||
|
@ -29,6 +32,12 @@ static uintptr_t imx_sip_handler(unsigned int smc_fid,
|
|||
case IMX_SIP_AARCH32:
|
||||
SMC_RET1(handle, imx_kernel_entry_handler(smc_fid, x1, x2, x3, x4));
|
||||
break;
|
||||
#if defined(PLAT_imx8ulp)
|
||||
case IMX_SIP_SCMI:
|
||||
scmi_smt_fastcall_smc_entry(0);
|
||||
SMC_RET1(handle, 0);
|
||||
break;
|
||||
#endif
|
||||
#if defined(PLAT_imx8mq)
|
||||
case IMX_SIP_GET_SOC_INFO:
|
||||
SMC_RET1(handle, imx_soc_info_handler(smc_fid, x1, x2, x3));
|
||||
|
|
16
plat/imx/common/include/imx_plat_common.h
Normal file
16
plat/imx/common/include/imx_plat_common.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright 2023-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef IMX_PLAT_COMMON_H
|
||||
#define IMX_PLAT_COMMON_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <arch_helpers.h>
|
||||
|
||||
uint32_t plat_get_spsr_for_bl33_entry(void);
|
||||
|
||||
#endif /*IMX_PLAT_COMMON_H */
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -52,6 +52,9 @@
|
|||
int imx_kernel_entry_handler(uint32_t smc_fid, u_register_t x1,
|
||||
u_register_t x2, u_register_t x3,
|
||||
u_register_t x4);
|
||||
|
||||
#define IMX_SIP_SCMI 0xC20000FE
|
||||
|
||||
#if defined(PLAT_imx8mq)
|
||||
int imx_soc_info_handler(uint32_t smc_fid, u_register_t x1,
|
||||
u_register_t x2, u_register_t x3);
|
||||
|
@ -96,5 +99,6 @@ int imx_misc_set_temp_handler(uint32_t smc_fid, u_register_t x1,
|
|||
uint64_t imx_buildinfo_handler(uint32_t smc_fid, u_register_t x1,
|
||||
u_register_t x2, u_register_t x3,
|
||||
u_register_t x4);
|
||||
int scmi_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2, u_register_t x3);
|
||||
|
||||
#endif /* __IMX_SIP_SVC_H__ */
|
||||
|
|
133
plat/imx/imx8ulp/imx8ulp_bl31_setup.c
Normal file
133
plat/imx/imx8ulp/imx8ulp_bl31_setup.c
Normal file
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Copyright 2021-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <common/bl_common.h>
|
||||
#include <common/debug.h>
|
||||
#include <context.h>
|
||||
#include <drivers/console.h>
|
||||
#include <drivers/generic_delay_timer.h>
|
||||
#include <lib/el3_runtime/context_mgmt.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <lib/xlat_tables/xlat_tables_v2.h>
|
||||
#include <plat/common/platform.h>
|
||||
#include <platform_def.h>
|
||||
|
||||
#include <imx8_lpuart.h>
|
||||
#include <imx_plat_common.h>
|
||||
#include <plat_imx8.h>
|
||||
#include <upower_api.h>
|
||||
|
||||
#define MAP_BL31_TOTAL \
|
||||
MAP_REGION_FLAT(BL31_BASE, BL31_LIMIT - BL31_BASE, MT_MEMORY | MT_RW | MT_SECURE)
|
||||
#define MAP_BL31_RO \
|
||||
MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE, MT_MEMORY | MT_RO | MT_SECURE)
|
||||
|
||||
#define MAP_COHERENT_MEM \
|
||||
MAP_REGION_FLAT(BL_COHERENT_RAM_BASE, (BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE), \
|
||||
MT_DEVICE | MT_RW | MT_SECURE)
|
||||
|
||||
static const mmap_region_t imx_mmap[] = {
|
||||
DEVICE0_MAP, DEVICE1_MAP, ELE_MAP,
|
||||
SEC_SIM_MAP, SRAM0_MAP,
|
||||
{0}
|
||||
};
|
||||
|
||||
extern uint32_t upower_init(void);
|
||||
extern void imx8ulp_init_scmi_server(void);
|
||||
|
||||
static entry_point_info_t bl32_image_ep_info;
|
||||
static entry_point_info_t bl33_image_ep_info;
|
||||
|
||||
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
|
||||
u_register_t arg2, u_register_t arg3)
|
||||
{
|
||||
static console_t console;
|
||||
|
||||
|
||||
/* enable the GPIO D,E,F non-secure access by default */
|
||||
mmio_write_32(IMX_PCC4_BASE + 0x78, 0xc0000000);
|
||||
mmio_write_32(IMX_PCC4_BASE + 0x7c, 0xc0000000);
|
||||
mmio_write_32(IMX_PCC5_BASE + 0x114, 0xc0000000);
|
||||
|
||||
mmio_write_32(IMX_GPIOE_BASE + 0x10, 0xffffffff);
|
||||
mmio_write_32(IMX_GPIOE_BASE + 0x14, 0x3);
|
||||
mmio_write_32(IMX_GPIOE_BASE + 0x18, 0xffffffff);
|
||||
mmio_write_32(IMX_GPIOE_BASE + 0x1c, 0x3);
|
||||
|
||||
mmio_write_32(IMX_GPIOF_BASE + 0x10, 0xffffffff);
|
||||
mmio_write_32(IMX_GPIOF_BASE + 0x14, 0x3);
|
||||
mmio_write_32(IMX_GPIOF_BASE + 0x18, 0xffffffff);
|
||||
mmio_write_32(IMX_GPIOF_BASE + 0x1c, 0x3);
|
||||
|
||||
mmio_write_32(IMX_GPIOD_BASE + 0x10, 0xffffffff);
|
||||
mmio_write_32(IMX_GPIOD_BASE + 0x14, 0x3);
|
||||
mmio_write_32(IMX_GPIOD_BASE + 0x18, 0xffffffff);
|
||||
mmio_write_32(IMX_GPIOD_BASE + 0x1c, 0x3);
|
||||
|
||||
console_lpuart_register(IMX_LPUART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
|
||||
IMX_CONSOLE_BAUDRATE, &console);
|
||||
|
||||
/* This console is only used for boot stage */
|
||||
console_set_scope(&console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME);
|
||||
|
||||
bl33_image_ep_info.pc = PLAT_NS_IMAGE_OFFSET;
|
||||
bl33_image_ep_info.spsr = plat_get_spsr_for_bl33_entry();
|
||||
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
|
||||
}
|
||||
|
||||
void bl31_plat_arch_setup(void)
|
||||
{
|
||||
const mmap_region_t bl_regions[] = {
|
||||
MAP_BL31_TOTAL,
|
||||
MAP_BL31_RO,
|
||||
#if USE_COHERENT_MEM
|
||||
MAP_COHERENT_MEM,
|
||||
#endif
|
||||
{0},
|
||||
};
|
||||
|
||||
setup_page_tables(bl_regions, imx_mmap);
|
||||
enable_mmu_el3(0);
|
||||
|
||||
/* TODO: Hack, refine this piece, scmi channel free */
|
||||
mmio_write_32(SRAM0_BASE + 0x4, 1);
|
||||
}
|
||||
|
||||
void bl31_platform_setup(void)
|
||||
{
|
||||
/* select the arch timer source */
|
||||
mmio_setbits_32(IMX_SIM1_BASE + 0x30, 0x8000000);
|
||||
|
||||
generic_delay_timer_init();
|
||||
|
||||
plat_gic_driver_init();
|
||||
plat_gic_init();
|
||||
|
||||
imx8ulp_init_scmi_server();
|
||||
upower_init();
|
||||
}
|
||||
|
||||
entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type)
|
||||
{
|
||||
if (type == NON_SECURE) {
|
||||
return &bl33_image_ep_info;
|
||||
} else {
|
||||
return &bl32_image_ep_info;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int plat_get_syscnt_freq2(void)
|
||||
{
|
||||
return COUNTER_FREQUENCY;
|
||||
}
|
||||
|
||||
void bl31_plat_runtime_setup(void)
|
||||
{
|
||||
}
|
124
plat/imx/imx8ulp/imx8ulp_psci.c
Normal file
124
plat/imx/imx8ulp/imx8ulp_psci.c
Normal file
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* Copyright 2021-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <arch.h>
|
||||
#include <arch_helpers.h>
|
||||
#include <common/debug.h>
|
||||
#include <drivers/arm/gicv3.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <lib/psci/psci.h>
|
||||
|
||||
#include <plat_imx8.h>
|
||||
|
||||
static uintptr_t secure_entrypoint;
|
||||
|
||||
#define CORE_PWR_STATE(state) ((state)->pwr_domain_state[MPIDR_AFFLVL0])
|
||||
#define CLUSTER_PWR_STATE(state) ((state)->pwr_domain_state[MPIDR_AFFLVL1])
|
||||
#define SYSTEM_PWR_STATE(state) ((state)->pwr_domain_state[PLAT_MAX_PWR_LVL])
|
||||
|
||||
#define RVBARADDRx(c) (IMX_SIM1_BASE + 0x5c + 0x4 * (c))
|
||||
#define WKPUx(c) (IMX_SIM1_BASE + 0x3c + 0x4 * (c))
|
||||
#define AD_COREx_LPMODE(c) (IMX_CMC1_BASE + 0x50 + 0x4 * (c))
|
||||
|
||||
static int imx_pwr_set_cpu_entry(unsigned int cpu, unsigned int entry)
|
||||
{
|
||||
mmio_write_32(RVBARADDRx(cpu), entry);
|
||||
|
||||
/* set update bit */
|
||||
mmio_write_32(IMX_SIM1_BASE + 0x8, mmio_read_32(IMX_SIM1_BASE + 0x8) | BIT_32(24 + cpu));
|
||||
/* wait for ack */
|
||||
while (!(mmio_read_32(IMX_SIM1_BASE + 0x8) & BIT_32(26 + cpu))) {
|
||||
}
|
||||
|
||||
/* clear update bit */
|
||||
mmio_write_32(IMX_SIM1_BASE + 0x8, mmio_read_32(IMX_SIM1_BASE + 0x8) & ~BIT_32(24 + cpu));
|
||||
/* clear ack bit */
|
||||
mmio_write_32(IMX_SIM1_BASE + 0x8, mmio_read_32(IMX_SIM1_BASE + 0x8) | BIT_32(26 + cpu));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int imx_pwr_domain_on(u_register_t mpidr)
|
||||
{
|
||||
unsigned int cpu = MPIDR_AFFLVL0_VAL(mpidr);
|
||||
|
||||
imx_pwr_set_cpu_entry(cpu, secure_entrypoint);
|
||||
|
||||
mmio_write_32(IMX_CMC1_BASE + 0x18, 0x3f);
|
||||
mmio_write_32(IMX_CMC1_BASE + 0x50 + 0x4 * cpu, 0);
|
||||
|
||||
/* enable wku wakeup for idle */
|
||||
mmio_write_32(IMX_SIM1_BASE + 0x3c + 0x4 * cpu, 0xffffffff);
|
||||
|
||||
return PSCI_E_SUCCESS;
|
||||
}
|
||||
|
||||
void imx_pwr_domain_on_finish(const psci_power_state_t *target_state)
|
||||
{
|
||||
imx_pwr_set_cpu_entry(0, IMX_ROM_ENTRY);
|
||||
plat_gic_pcpu_init();
|
||||
plat_gic_cpuif_enable();
|
||||
}
|
||||
|
||||
int imx_validate_ns_entrypoint(uintptr_t ns_entrypoint)
|
||||
{
|
||||
return PSCI_E_SUCCESS;
|
||||
}
|
||||
|
||||
void imx_pwr_domain_off(const psci_power_state_t *target_state)
|
||||
{
|
||||
unsigned int cpu = MPIDR_AFFLVL0_VAL(read_mpidr_el1());
|
||||
|
||||
plat_gic_cpuif_disable();
|
||||
|
||||
/* disable wakeup */
|
||||
mmio_write_32(WKPUx(cpu), 0);
|
||||
|
||||
mmio_write_32(AD_COREx_LPMODE(cpu), 0x3);
|
||||
}
|
||||
|
||||
void __dead2 imx8ulp_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state)
|
||||
{
|
||||
while (1) {
|
||||
wfi();
|
||||
}
|
||||
}
|
||||
|
||||
void __dead2 imx8ulp_system_reset(void)
|
||||
{
|
||||
imx_pwr_set_cpu_entry(0, IMX_ROM_ENTRY);
|
||||
|
||||
/* Write invalid command to WDOG CNT to trigger reset */
|
||||
mmio_write_32(IMX_WDOG3_BASE + 0x4, 0x12345678);
|
||||
|
||||
while (true) {
|
||||
wfi();
|
||||
}
|
||||
}
|
||||
|
||||
static const plat_psci_ops_t imx_plat_psci_ops = {
|
||||
.pwr_domain_on = imx_pwr_domain_on,
|
||||
.pwr_domain_on_finish = imx_pwr_domain_on_finish,
|
||||
.validate_ns_entrypoint = imx_validate_ns_entrypoint,
|
||||
.system_reset = imx8ulp_system_reset,
|
||||
.pwr_domain_off = imx_pwr_domain_off,
|
||||
.pwr_domain_pwr_down_wfi = imx8ulp_pwr_domain_pwr_down_wfi,
|
||||
};
|
||||
|
||||
int plat_setup_psci_ops(uintptr_t sec_entrypoint,
|
||||
const plat_psci_ops_t **psci_ops)
|
||||
{
|
||||
secure_entrypoint = sec_entrypoint;
|
||||
imx_pwr_set_cpu_entry(0, sec_entrypoint);
|
||||
*psci_ops = &imx_plat_psci_ops;
|
||||
|
||||
mmio_write_32(IMX_CMC1_BASE + 0x18, 0x3f);
|
||||
mmio_write_32(IMX_SIM1_BASE + 0x3c, 0xffffffff);
|
||||
|
||||
return 0;
|
||||
}
|
93
plat/imx/imx8ulp/include/platform_def.h
Normal file
93
plat/imx/imx8ulp/include/platform_def.h
Normal file
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright 2021-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef PLATFORM_DEF_H
|
||||
#define PLATFORM_DEF_H
|
||||
|
||||
#include <lib/utils_def.h>
|
||||
|
||||
#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
|
||||
#define PLATFORM_LINKER_ARCH aarch64
|
||||
|
||||
#define PLATFORM_STACK_SIZE 0x400
|
||||
#define CACHE_WRITEBACK_GRANULE 64
|
||||
|
||||
#define PLAT_PRIMARY_CPU 0x0
|
||||
#define PLATFORM_MAX_CPU_PER_CLUSTER 2
|
||||
#define PLATFORM_CLUSTER_COUNT 1
|
||||
#define PLATFORM_CORE_COUNT 2
|
||||
#define PLATFORM_CLUSTER0_CORE_COUNT 2
|
||||
#define PLATFORM_CLUSTER1_CORE_COUNT 0
|
||||
|
||||
#define IMX_PWR_LVL0 MPIDR_AFFLVL0
|
||||
#define IMX_PWR_LVL1 MPIDR_AFFLVL1
|
||||
#define IMX_PWR_LVL2 MPIDR_AFFLVL2
|
||||
|
||||
#define PWR_DOMAIN_AT_MAX_LVL U(1)
|
||||
#define PLAT_MAX_PWR_LVL U(2)
|
||||
#define PLAT_MAX_OFF_STATE U(4)
|
||||
#define PLAT_MAX_RET_STATE U(2)
|
||||
|
||||
#define PLAT_WAIT_RET_STATE U(1)
|
||||
#define PLAT_STOP_OFF_STATE U(3)
|
||||
|
||||
#define BL31_BASE 0x20040000
|
||||
#define BL31_LIMIT 0x20070000
|
||||
|
||||
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 32)
|
||||
#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 32)
|
||||
|
||||
#define MAX_XLAT_TABLES 8
|
||||
#define MAX_MMAP_REGIONS 9
|
||||
|
||||
#define PLAT_GICD_BASE U(0x2d400000)
|
||||
#define PLAT_GICR_BASE U(0x2d440000)
|
||||
#define DEVICE0_BASE U(0x20000000)
|
||||
#define DEVICE0_SIZE U(0x10000000)
|
||||
#define DEVICE1_BASE U(0x30000000)
|
||||
#define DEVICE1_SIZE U(0x10000000)
|
||||
#define IMX_LPUART4_BASE U(0x29390000)
|
||||
#define IMX_LPUART5_BASE U(0x293a0000)
|
||||
#define IMX_LPUART_BASE IMX_LPUART5_BASE
|
||||
#define IMX_BOOT_UART_CLK_IN_HZ 24000000
|
||||
#define IMX_CONSOLE_BAUDRATE 115200
|
||||
|
||||
#define IMX_CGC1_BASE U(0x292c0000)
|
||||
#define IMX_PCC3_BASE U(0x292d0000)
|
||||
#define IMX_PCC4_BASE U(0x29800000)
|
||||
#define IMX_SIM2_BASE U(0x2da50000)
|
||||
#define IMX_CGC2_BASE U(0x2da60000)
|
||||
#define IMX_PCC5_BASE U(0x2da70000)
|
||||
#define IMX_CMC1_BASE U(0x29240000)
|
||||
#define IMX_SIM1_BASE U(0x29290000)
|
||||
#define IMX_WDOG3_BASE U(0x292a0000)
|
||||
#define IMX_GPIOE_BASE U(0x2D000000)
|
||||
#define IMX_GPIOD_BASE U(0x2E200000)
|
||||
#define IMX_GPIOF_BASE U(0x2D010000)
|
||||
|
||||
#define SRAM0_BASE U(0x2201F000)
|
||||
|
||||
#define IMX_ROM_ENTRY U(0x1000)
|
||||
#define COUNTER_FREQUENCY 1000000
|
||||
|
||||
#define PLAT_NS_IMAGE_OFFSET 0x80200000
|
||||
|
||||
#define BL31_NOBITS_BASE 0x20058000
|
||||
#define BL31_NOBITS_LIMIT 0x2006d000
|
||||
|
||||
#define BL31_RWDATA_BASE 0x2006d000
|
||||
#define BL31_RWDATA_LIMIT 0x20070000
|
||||
|
||||
/* system memory map define */
|
||||
#define DEVICE0_MAP MAP_REGION_FLAT(DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW)
|
||||
#define DEVICE1_MAP MAP_REGION_FLAT(DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW)
|
||||
/* MU and FSB */
|
||||
#define ELE_MAP MAP_REGION_FLAT(0x27010000, 0x20000, MT_DEVICE | MT_RW | MT_NS)
|
||||
#define SEC_SIM_MAP MAP_REGION_FLAT(0x2802B000, 0x1000, MT_DEVICE | MT_RW | MT_NS) /* SEC SIM */
|
||||
/* For SCMI shared memory region */
|
||||
#define SRAM0_MAP MAP_REGION_FLAT(SRAM0_BASE, 0x1000, MT_RW | MT_DEVICE)
|
||||
|
||||
#endif /* PLATFORM_DEF_H */
|
100
plat/imx/imx8ulp/include/scmi.h
Normal file
100
plat/imx/imx8ulp/include/scmi.h
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright 2021-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef IMX8_SCMI_H
|
||||
#define IMX8_SCMI_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define SCMI_SHMEM_CHANNEL_ERROR BIT_32(1)
|
||||
#define SCMI_SHMEM_CHANNEL_FREE BIT_32(0)
|
||||
|
||||
#define SCMI_SHMEM_FLAG_INTR_ENABLED BIT_32(0)
|
||||
|
||||
enum scmi_std_protocol {
|
||||
SCMI_PROTOCOL_BASE = 0x10,
|
||||
SCMI_PROTOCOL_POWER_DOMAIN = 0x11,
|
||||
SCMI_PROTOCOL_SYS_POWER = 0x12,
|
||||
SCMI_PROTOCOL_PERF_DOMAIN = 0x13,
|
||||
SCMI_PROTOCOL_CLK = 0x14,
|
||||
SCMI_PROTOCOL_SENSOR = 0x15,
|
||||
SCMI_PROTOCOL_RESET_DOMAIN = 0x16,
|
||||
};
|
||||
|
||||
#define MSG_ID(m) ((m) & 0xff)
|
||||
#define MSG_TYPE(m) (((m) >> 8) & 0x3)
|
||||
#define MSG_PRO_ID(m) (((m) >> 10) & 0xff)
|
||||
#define MSG_TOKEN(m) (((m) >> 18) & 0x3ff)
|
||||
|
||||
enum {
|
||||
SCMI_POWER_DOMAIN_PROTOCOL = 0x11,
|
||||
SCMI_SYS_PWR_DOMAIN_PROTOCOL = 0x12,
|
||||
SCMI_PER_DOMAIN_PROTOCOL = 0x13,
|
||||
SCMI_CLK_DOMAIN_PROTOCOL = 0x14,
|
||||
SCMI_SENSOR_PROTOCOL = 0x15,
|
||||
};
|
||||
|
||||
#define PROTOCOL_VERSION 0
|
||||
#define PROTOCOL_ATTRIBUTES 1
|
||||
#define PROTOCOL_MESSAGE_ATTRIBUTES 2
|
||||
#define BASE_DISCOVER_VENDOR 3
|
||||
#define BASE_DISCOVER_SUB_VENDOR 4
|
||||
#define BASE_DISCOVER_IMPLEMENTATION_VERSION 5
|
||||
#define BASE_DISCOVER_LIST_PROTOCOLS 6
|
||||
#define BASE_DISCOVER_AGENT 7
|
||||
#define BASE_NOTIFY_ERRORS 8
|
||||
#define BASE_SET_DEVICE_PERMISSIONS 9
|
||||
#define BASE_SET_PROTOCOL_PERMISSIONS 0xA
|
||||
#define BASE_RESET_AGENT_CONFIGURATION 0xB
|
||||
|
||||
enum {
|
||||
SCMI_RET_SUCCESS = 0,
|
||||
SCMI_RET_NOT_SUPPORTED = -1,
|
||||
SCMI_RET_INVALID_PARAMETERS = -2,
|
||||
SCMI_RET_DENIED = -3,
|
||||
SCMI_RET_NOT_FOUND = -4,
|
||||
SCMI_RET_OUT_OF_RANGE = -5,
|
||||
SCMI_RET_BUSY = -6,
|
||||
SCMI_RET_COMMS_ERROR = -7,
|
||||
SCMI_RET_GENERIC_ERROR = -8,
|
||||
SCMI_RET_HARDWARE_ERROR = -9,
|
||||
SCMI_RET_PROTOCOL_ERROR = -10,
|
||||
};
|
||||
|
||||
#define POWER_DOMAIN_ATTRIBUTES 3
|
||||
#define POWER_DOMAIN_SUPPORT_NOTIFICATION BIT(31)
|
||||
#define POWER_DOMAIN_SUPPORT_ASYNCHRONOUS BIT(30)
|
||||
#define POWER_DOMAIN_SUPPORT_SYNCHRONOUS BIT(29)
|
||||
|
||||
#define POWER_STATE_SET 4
|
||||
#define POWER_STATE_GET 5
|
||||
#define POWER_STATE_NOTIFY 6
|
||||
#define POWER_STATE_CHANGE_REQUESTED_NOTIFY 7
|
||||
|
||||
int scmi_power_domain_handler(uint32_t msg_id, void *shmem);
|
||||
|
||||
#define PERFORMANCE_DOMAIN_ATTRIBUTES 3
|
||||
#define PERFORMANCE_DESCRIBE_LEVELS 4
|
||||
#define PERFORMANCE_LIMITS_SET 5
|
||||
#define PERFORMANCE_LIMITS_GET 6
|
||||
#define PERFORMANCE_LEVEL_SET 7
|
||||
#define PERFORMANCE_LEVEL_GET 8
|
||||
#define PERFORMANCE_NOTIFY_LIMITS 9
|
||||
#define PERFORMANCE_NOTIFY_LEVEL 0xA
|
||||
#define PERFORMANCE_DESCRIBE_FAST_CHANNEL 0xB
|
||||
|
||||
int scmi_perf_domain_handler(uint32_t msg_id, void *shmem);
|
||||
|
||||
#define SENSOR_DESCRIPTION_GET 0x003
|
||||
#define SENSOR_CONFIG_SET 0x004
|
||||
#define SENSOR_TRIP_POINT_SET 0x005
|
||||
#define SENSOR_READING_GET 0x006
|
||||
|
||||
int scmi_sensor_handler(uint32_t msg_id, void *shmem);
|
||||
|
||||
#define SMC_SHMEM_BASE 0x2201f000
|
||||
|
||||
#endif /* IMX8_SCMI_H */
|
139
plat/imx/imx8ulp/include/scmi_sensor.h
Normal file
139
plat/imx/imx8ulp/include/scmi_sensor.h
Normal file
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Description:
|
||||
* System Control and Management Interface (SCMI) support.
|
||||
*/
|
||||
|
||||
#ifndef INTERNAL_SCMI_SENSOR_H
|
||||
#define INTERNAL_SCMI_SENSOR_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define SCMI_PROTOCOL_VERSION_SENSOR UINT32_C(0x10000)
|
||||
|
||||
/*
|
||||
* PROTOCOL_ATTRIBUTES
|
||||
*/
|
||||
struct scmi_sensor_protocol_attributes_p2a {
|
||||
int32_t status;
|
||||
uint32_t attributes;
|
||||
uint32_t sensor_reg_address_low;
|
||||
uint32_t sensor_reg_address_high;
|
||||
uint32_t sensor_reg_len;
|
||||
};
|
||||
|
||||
/*
|
||||
* SENSOR_READING_GET
|
||||
*/
|
||||
#define SCMI_SENSOR_PROTOCOL_READING_GET_ASYNC_FLAG_MASK (1 << 0)
|
||||
|
||||
struct scmi_sensor_protocol_reading_get_a2p {
|
||||
uint32_t sensor_id;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
struct scmi_sensor_protocol_reading_get_p2a {
|
||||
int32_t status;
|
||||
uint32_t sensor_value_low;
|
||||
uint32_t sensor_value_high;
|
||||
};
|
||||
|
||||
/*
|
||||
* SENSOR_DESCRIPTION_GET
|
||||
*/
|
||||
#define SCMI_SENSOR_DESCS_MAX(MAILBOX_SIZE) \
|
||||
((sizeof(struct scmi_sensor_protocol_description_get_p2a) < MAILBOX_SIZE) \
|
||||
? ((MAILBOX_SIZE - \
|
||||
sizeof(struct scmi_sensor_protocol_description_get_p2a)) \
|
||||
/ sizeof(struct scmi_sensor_desc)) \
|
||||
: 0)
|
||||
|
||||
#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_TYPE_POS 0
|
||||
#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_POS 11
|
||||
#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_POS 22
|
||||
#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_INTERVAL_POS 27
|
||||
|
||||
#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_TYPE_MASK \
|
||||
(UINT32_C(0xFF) << SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_TYPE_POS)
|
||||
#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_MASK \
|
||||
(UINT32_C(0x1F) << SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_POS)
|
||||
#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_MASK \
|
||||
(UINT32_C(0x1F) << \
|
||||
SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_POS)
|
||||
#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_INTERVAL_MASK \
|
||||
(UINT32_C(0x1F) << SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_INTERVAL_POS)
|
||||
|
||||
#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_MAX \
|
||||
(int32_t)(SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_MASK >> 1)
|
||||
#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_MIN \
|
||||
(-(SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_MAX + 1))
|
||||
|
||||
#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_MAX \
|
||||
(int32_t)(SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_INTERVAL_MASK >> 1)
|
||||
#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_MIN \
|
||||
(-(SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_MAX + 1))
|
||||
|
||||
#define SCMI_SENSOR_DESC_ATTRIBUTES_HIGH(SENSOR_TYPE, UNIT_MULTIPLIER, \
|
||||
UPDATE_MULTIPLIER, UPDATE_INTERVAL) \
|
||||
( \
|
||||
(((SENSOR_TYPE) << \
|
||||
SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_TYPE_POS) & \
|
||||
SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_TYPE_MASK) | \
|
||||
(((UNIT_MULTIPLIER) << \
|
||||
SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_POS) & \
|
||||
SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_MASK) | \
|
||||
(((UPDATE_MULTIPLIER) << \
|
||||
SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_POS) & \
|
||||
SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_MASK) | \
|
||||
(((UPDATE_INTERVAL) << \
|
||||
SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_INTERVAL_POS) & \
|
||||
SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_INTERVAL_MASK) \
|
||||
)
|
||||
|
||||
#define SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_DESCS_POS 0
|
||||
#define SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_REMAINING_DESCS_POS 16
|
||||
|
||||
#define SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_DESCS_MASK \
|
||||
(UINT32_C(0xFFF) << SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_DESCS_POS)
|
||||
#define SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_REMAINING_DESCS_MASK \
|
||||
(UINT32_C(0xFFFF) << SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_REMAINING_DESCS_POS)
|
||||
|
||||
#define SCMI_SENSOR_NUM_SENSOR_FLAGS(NUM_DESCS, NUM_REMAINING_DESCS) \
|
||||
( \
|
||||
(((NUM_DESCS) << \
|
||||
SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_DESCS_POS) & \
|
||||
SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_DESCS_MASK) | \
|
||||
(((NUM_REMAINING_DESCS) << \
|
||||
SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_REMAINING_DESCS_POS) & \
|
||||
SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_REMAINING_DESCS_MASK) \
|
||||
)
|
||||
|
||||
#define SCMI_SENSOR_NAME_LEN 16
|
||||
|
||||
struct scmi_sensor_desc {
|
||||
uint32_t sensor_id;
|
||||
uint32_t sensor_attributes_low;
|
||||
uint32_t sensor_attributes_high;
|
||||
char sensor_name[SCMI_SENSOR_NAME_LEN];
|
||||
};
|
||||
|
||||
struct scmi_sensor_protocol_description_get_a2p {
|
||||
uint32_t desc_index;
|
||||
};
|
||||
|
||||
struct scmi_sensor_protocol_description_get_p2a {
|
||||
int32_t status;
|
||||
uint32_t num_sensor_flags;
|
||||
struct scmi_sensor_desc sensor_desc[];
|
||||
};
|
||||
|
||||
/* Event indices */
|
||||
enum scmi_sensor_api_idx {
|
||||
SCMI_SENSOR_EVENT_IDX_REQUEST,
|
||||
SCMI_SENSOR_EVENT_IDX_COUNT,
|
||||
};
|
||||
|
||||
#endif /* INTERNAL_SCMI_SENSOR_H */
|
60
plat/imx/imx8ulp/platform.mk
Normal file
60
plat/imx/imx8ulp/platform.mk
Normal file
|
@ -0,0 +1,60 @@
|
|||
#
|
||||
# Copyright 2021-2024 NXP
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
||||
# Translation tables library
|
||||
include lib/xlat_tables_v2/xlat_tables.mk
|
||||
|
||||
# Include GICv3 driver files
|
||||
include drivers/arm/gic/v3/gicv3.mk
|
||||
|
||||
PLAT_INCLUDES := -Iplat/imx/imx8ulp/include \
|
||||
-Iplat/imx/common/include \
|
||||
-Iplat/imx/imx8ulp/upower
|
||||
|
||||
IMX_GIC_SOURCES := ${GICV3_SOURCES} \
|
||||
plat/common/plat_gicv3.c \
|
||||
plat/common/plat_psci_common.c \
|
||||
plat/imx/common/plat_imx8_gic.c
|
||||
|
||||
BL31_SOURCES += plat/imx/common/lpuart_console.S \
|
||||
plat/imx/common/imx8_helpers.S \
|
||||
plat/imx/imx8ulp/imx8ulp_bl31_setup.c \
|
||||
plat/imx/imx8ulp/imx8ulp_psci.c \
|
||||
plat/imx/common/imx8_topology.c \
|
||||
plat/imx/common/imx_sip_svc.c \
|
||||
plat/imx/common/imx_sip_handler.c \
|
||||
plat/imx/common/imx_bl31_common.c \
|
||||
plat/common/plat_psci_common.c \
|
||||
lib/cpus/aarch64/cortex_a35.S \
|
||||
drivers/delay_timer/delay_timer.c \
|
||||
drivers/delay_timer/generic_delay_timer.c \
|
||||
drivers/scmi-msg/base.c \
|
||||
drivers/scmi-msg/entry.c \
|
||||
drivers/scmi-msg/smt.c \
|
||||
drivers/scmi-msg/power_domain.c \
|
||||
drivers/scmi-msg/sensor.c \
|
||||
plat/imx/imx8ulp/scmi/scmi.c \
|
||||
plat/imx/imx8ulp/scmi/scmi_pd.c \
|
||||
plat/imx/imx8ulp/scmi/scmi_sensor.c \
|
||||
plat/imx/imx8ulp/upower/upower_api.c \
|
||||
plat/imx/imx8ulp/upower/upower_hal.c \
|
||||
${XLAT_TABLES_LIB_SRCS} \
|
||||
${IMX_GIC_SOURCES}
|
||||
|
||||
ifeq ($(findstring clang,$(notdir $(CC))),)
|
||||
TF_CFLAGS_aarch64 += -fno-strict-aliasing
|
||||
endif
|
||||
|
||||
USE_COHERENT_MEM := 1
|
||||
RESET_TO_BL31 := 1
|
||||
SEPARATE_NOBITS_REGION := 1
|
||||
SEPARATE_RWDATA_REGION := 1
|
||||
PROGRAMMABLE_RESET_ADDRESS := 1
|
||||
COLD_BOOT_SINGLE_CPU := 1
|
||||
BL32_BASE ?= 0xa6000000
|
||||
BL32_SIZE ?= 0x2000000
|
||||
$(eval $(call add_define,BL32_BASE))
|
||||
$(eval $(call add_define,BL32_SIZE))
|
69
plat/imx/imx8ulp/scmi/scmi.c
Normal file
69
plat/imx/imx8ulp/scmi/scmi.c
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright 2021-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <drivers/scmi-msg.h>
|
||||
#include <drivers/scmi.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
#define SMT_BUFFER_BASE 0x2201f000
|
||||
#define SMT_BUFFER0_BASE SMT_BUFFER_BASE
|
||||
#define SMT_BUFFER1_BASE (SMT_BUFFER_BASE + 0x200)
|
||||
|
||||
static struct scmi_msg_channel scmi_channel[] = {
|
||||
[0] = {
|
||||
.shm_addr = SMT_BUFFER0_BASE,
|
||||
.shm_size = SMT_BUF_SLOT_SIZE,
|
||||
},
|
||||
};
|
||||
|
||||
struct scmi_msg_channel *plat_scmi_get_channel(unsigned int agent_id)
|
||||
{
|
||||
assert(agent_id < ARRAY_SIZE(scmi_channel));
|
||||
|
||||
return &scmi_channel[agent_id];
|
||||
}
|
||||
|
||||
static const char vendor[] = "NXP";
|
||||
static const char sub_vendor[] = "";
|
||||
|
||||
const char *plat_scmi_vendor_name(void)
|
||||
{
|
||||
return vendor;
|
||||
}
|
||||
|
||||
const char *plat_scmi_sub_vendor_name(void)
|
||||
{
|
||||
return sub_vendor;
|
||||
}
|
||||
|
||||
/* Currently supporting Clocks and Reset Domains */
|
||||
static const uint8_t plat_protocol_list[] = {
|
||||
SCMI_PROTOCOL_ID_POWER_DOMAIN,
|
||||
SCMI_PROTOCOL_ID_SENSOR,
|
||||
0U /* Null termination */
|
||||
};
|
||||
|
||||
size_t plat_scmi_protocol_count(void)
|
||||
{
|
||||
return ARRAY_SIZE(plat_protocol_list) - 1U;
|
||||
}
|
||||
|
||||
const uint8_t *plat_scmi_protocol_list(unsigned int agent_id __unused)
|
||||
{
|
||||
return plat_protocol_list;
|
||||
}
|
||||
|
||||
void imx8ulp_init_scmi_server(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0U; i < ARRAY_SIZE(scmi_channel); i++) {
|
||||
scmi_smt_init_agent_channel(&scmi_channel[i]);
|
||||
}
|
||||
}
|
352
plat/imx/imx8ulp/scmi/scmi_pd.c
Normal file
352
plat/imx/imx8ulp/scmi/scmi_pd.c
Normal file
|
@ -0,0 +1,352 @@
|
|||
/*
|
||||
* Copyright 2021-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
#include <lib/libc/errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <drivers/scmi.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <lib/utils_def.h>
|
||||
#include <platform_def.h>
|
||||
#include <scmi.h>
|
||||
|
||||
#include <upower_api.h>
|
||||
|
||||
#define POWER_STATE_ON (0 << 30)
|
||||
#define POWER_STATE_OFF (1 << 30)
|
||||
|
||||
enum {
|
||||
PS0 = 0,
|
||||
PS1 = 1,
|
||||
PS2 = 2,
|
||||
PS3 = 3,
|
||||
PS4 = 4,
|
||||
PS5 = 5,
|
||||
PS6 = 6,
|
||||
PS7 = 7,
|
||||
PS8 = 8,
|
||||
PS9 = 9,
|
||||
PS10 = 10,
|
||||
PS11 = 11,
|
||||
PS12 = 12,
|
||||
PS13 = 13,
|
||||
PS14 = 14,
|
||||
PS15 = 15,
|
||||
PS16 = 16,
|
||||
PS17 = 17,
|
||||
PS18 = 18,
|
||||
PS19 = 19,
|
||||
};
|
||||
|
||||
#define SRAM_DMA1 BIT(6)
|
||||
#define SRAM_FLEXSPI2 BIT(7)
|
||||
#define SRAM_USB0 BIT(10)
|
||||
#define SRAM_USDHC0 BIT(11)
|
||||
#define SRAM_USDHC1 BIT(12)
|
||||
#define SRAM_USDHC2_USB1 BIT(13)
|
||||
#define SRAM_DCNANO GENMASK_32(18, 17)
|
||||
#define SRAM_EPDC GENMASK_32(20, 19)
|
||||
#define SRAM_DMA2 BIT(21)
|
||||
#define SRAM_GPU2D GENMASK_32(23, 22)
|
||||
#define SRAM_GPU3D GENMASK_32(25, 24)
|
||||
#define SRAM_HIFI4 BIT(26)
|
||||
#define SRAM_ISI_BUFFER BIT(27)
|
||||
#define SRAM_MIPI_CSI_FIFO BIT(28)
|
||||
#define SRAM_MIPI_DSI_FIFO BIT(29)
|
||||
#define SRAM_PXP BIT(30)
|
||||
|
||||
#define SRAM_DMA0 BIT_64(33)
|
||||
#define SRAM_FLEXCAN BIT_64(34)
|
||||
#define SRAM_FLEXSPI0 BIT_64(35)
|
||||
#define SRAM_FLEXSPI1 BIT_64(36)
|
||||
|
||||
struct psw {
|
||||
char *name;
|
||||
uint32_t reg;
|
||||
int power_state;
|
||||
uint32_t count;
|
||||
int flags;
|
||||
};
|
||||
|
||||
#define ALWAYS_ON BIT(0)
|
||||
|
||||
static struct psw imx8ulp_psw[] = {
|
||||
[PS6] = { .name = "PS6", .reg = PS6, .flags = ALWAYS_ON, .power_state = POWER_STATE_ON },
|
||||
[PS7] = { .name = "PS7", .reg = PS7, .power_state = POWER_STATE_OFF },
|
||||
[PS8] = { .name = "PS8", .reg = PS8, .power_state = POWER_STATE_OFF },
|
||||
[PS13] = { .name = "PS13", .reg = PS13, .power_state = POWER_STATE_OFF },
|
||||
[PS14] = { .name = "PS14", .reg = PS14, .flags = ALWAYS_ON, .power_state = POWER_STATE_OFF },
|
||||
[PS15] = { .name = "PS15", .reg = PS15, .power_state = POWER_STATE_OFF },
|
||||
[PS16] = { .name = "PS16", .reg = PS16, .flags = ALWAYS_ON, .power_state = POWER_STATE_ON },
|
||||
};
|
||||
|
||||
struct power_domain {
|
||||
char *name;
|
||||
uint32_t reg;
|
||||
uint32_t psw_parent;
|
||||
uint32_t sram_parent;
|
||||
uint64_t bits;
|
||||
uint32_t power_state;
|
||||
uint32_t sw_rst_reg; /* pcc sw reset reg offset */
|
||||
};
|
||||
|
||||
/* The Rich OS need flow the macro */
|
||||
#define IMX8ULP_PD_DMA1 0
|
||||
#define IMX8ULP_PD_FLEXSPI2 1
|
||||
#define IMX8ULP_PD_USB0 2
|
||||
#define IMX8ULP_PD_USDHC0 3
|
||||
#define IMX8ULP_PD_USDHC1 4
|
||||
#define IMX8ULP_PD_USDHC2_USB1 5
|
||||
#define IMX8ULP_PD_DCNANO 6
|
||||
#define IMX8ULP_PD_EPDC 7
|
||||
#define IMX8ULP_PD_DMA2 8
|
||||
#define IMX8ULP_PD_GPU2D 9
|
||||
#define IMX8ULP_PD_GPU3D 10
|
||||
#define IMX8ULP_PD_HIFI4 11
|
||||
#define IMX8ULP_PD_ISI 12
|
||||
#define IMX8ULP_PD_MIPI_CSI 13
|
||||
#define IMX8ULP_PD_MIPI_DSI 14
|
||||
#define IMX8ULP_PD_PXP 15
|
||||
|
||||
#define IMX8ULP_PD_PS6 16
|
||||
#define IMX8ULP_PD_PS7 17
|
||||
#define IMX8ULP_PD_PS8 18
|
||||
#define IMX8ULP_PD_PS13 19
|
||||
#define IMX8ULP_PD_PS14 20
|
||||
#define IMX8ULP_PD_PS15 21
|
||||
#define IMX8ULP_PD_PS16 22
|
||||
#define IMX8ULP_PD_MAX 23
|
||||
|
||||
/* LPAV peripheral PCC */
|
||||
#define PCC_GPU2D (IMX_PCC5_BASE + 0xf0)
|
||||
#define PCC_GPU3D (IMX_PCC5_BASE + 0xf4)
|
||||
#define PCC_EPDC (IMX_PCC5_BASE + 0xcc)
|
||||
#define PCC_CSI (IMX_PCC5_BASE + 0xbc)
|
||||
#define PCC_PXP (IMX_PCC5_BASE + 0xd0)
|
||||
|
||||
#define PCC_SW_RST BIT(28)
|
||||
|
||||
#define PWR_DOMAIN(_name, _reg, _psw_parent, _sram_parent, \
|
||||
_bits, _state, _rst_reg) \
|
||||
{ \
|
||||
.name = _name, \
|
||||
.reg = _reg, \
|
||||
.psw_parent = _psw_parent, \
|
||||
.sram_parent = _sram_parent, \
|
||||
.bits = _bits, \
|
||||
.power_state = _state, \
|
||||
.sw_rst_reg = _rst_reg, \
|
||||
}
|
||||
|
||||
static struct power_domain scmi_power_domains[] = {
|
||||
PWR_DOMAIN("DMA1", IMX8ULP_PD_DMA1, PS6, PS6, SRAM_DMA1, POWER_STATE_OFF, 0U),
|
||||
PWR_DOMAIN("FLEXSPI2", IMX8ULP_PD_FLEXSPI2, PS6, PS6, SRAM_FLEXSPI2, POWER_STATE_OFF, 0U),
|
||||
PWR_DOMAIN("USB0", IMX8ULP_PD_USB0, PS6, PS6, SRAM_USB0, POWER_STATE_OFF, 0U),
|
||||
PWR_DOMAIN("USDHC0", IMX8ULP_PD_USDHC0, PS6, PS6, SRAM_USDHC0, POWER_STATE_OFF, 0U),
|
||||
PWR_DOMAIN("USDHC1", IMX8ULP_PD_USDHC1, PS6, PS6, SRAM_USDHC1, POWER_STATE_OFF, 0U),
|
||||
PWR_DOMAIN("USDHC2_USB1", IMX8ULP_PD_USDHC2_USB1, PS6, PS6, SRAM_USDHC2_USB1, POWER_STATE_OFF, 0U),
|
||||
PWR_DOMAIN("DCNano", IMX8ULP_PD_DCNANO, PS16, PS16, SRAM_DCNANO, POWER_STATE_OFF, 0U),
|
||||
PWR_DOMAIN("EPDC", IMX8ULP_PD_EPDC, PS13, PS13, SRAM_EPDC, POWER_STATE_OFF, PCC_EPDC),
|
||||
PWR_DOMAIN("DMA2", IMX8ULP_PD_DMA2, PS16, PS16, SRAM_DMA2, POWER_STATE_OFF, 0U),
|
||||
PWR_DOMAIN("GPU2D", IMX8ULP_PD_GPU2D, PS16, PS16, SRAM_GPU2D, POWER_STATE_OFF, PCC_GPU2D),
|
||||
PWR_DOMAIN("GPU3D", IMX8ULP_PD_GPU3D, PS7, PS7, SRAM_GPU3D, POWER_STATE_OFF, PCC_GPU3D),
|
||||
PWR_DOMAIN("HIFI4", IMX8ULP_PD_HIFI4, PS8, PS8, SRAM_HIFI4, POWER_STATE_OFF, 0U),
|
||||
PWR_DOMAIN("ISI", IMX8ULP_PD_ISI, PS16, PS16, SRAM_ISI_BUFFER, POWER_STATE_OFF, 0U),
|
||||
PWR_DOMAIN("MIPI_CSI", IMX8ULP_PD_MIPI_CSI, PS15, PS16, SRAM_MIPI_CSI_FIFO, POWER_STATE_OFF, PCC_CSI),
|
||||
PWR_DOMAIN("MIPI_DSI", IMX8ULP_PD_MIPI_DSI, PS14, PS16, SRAM_MIPI_DSI_FIFO, POWER_STATE_OFF, 0U),
|
||||
PWR_DOMAIN("PXP", IMX8ULP_PD_PXP, PS13, PS13, SRAM_PXP | SRAM_EPDC, POWER_STATE_OFF, PCC_PXP)
|
||||
};
|
||||
|
||||
size_t plat_scmi_pd_count(unsigned int agent_id __unused)
|
||||
{
|
||||
return ARRAY_SIZE(scmi_power_domains);
|
||||
}
|
||||
|
||||
const char *plat_scmi_pd_get_name(unsigned int agent_id __unused,
|
||||
unsigned int pd_id)
|
||||
{
|
||||
if (pd_id >= IMX8ULP_PD_PS6) {
|
||||
return imx8ulp_psw[pd_id - IMX8ULP_PD_PS6].name;
|
||||
}
|
||||
|
||||
return scmi_power_domains[pd_id].name;
|
||||
}
|
||||
|
||||
unsigned int plat_scmi_pd_get_state(unsigned int agent_id __unused,
|
||||
unsigned int pd_id __unused)
|
||||
{
|
||||
if (pd_id >= IMX8ULP_PD_PS6) {
|
||||
return imx8ulp_psw[pd_id - IMX8ULP_PD_PS6].power_state;
|
||||
}
|
||||
|
||||
return scmi_power_domains[pd_id].power_state;
|
||||
}
|
||||
|
||||
extern void upower_wait_resp(void);
|
||||
int upwr_pwm_power(const uint32_t swton[], const uint32_t memon[], bool on)
|
||||
{
|
||||
int ret_val;
|
||||
int ret;
|
||||
|
||||
if (on == true) {
|
||||
ret = upwr_pwm_power_on(swton, memon, NULL);
|
||||
} else {
|
||||
ret = upwr_pwm_power_off(swton, memon, NULL);
|
||||
}
|
||||
|
||||
if (ret != 0U) {
|
||||
WARN("%s failed: ret: %d, state: %x\n", __func__, ret, on);
|
||||
return ret;
|
||||
}
|
||||
|
||||
upower_wait_resp();
|
||||
|
||||
ret = upwr_poll_req_status(UPWR_SG_PWRMGMT, NULL, NULL, &ret_val, 1000);
|
||||
if (ret != UPWR_REQ_OK) {
|
||||
WARN("Failure %d, %s\n", ret, __func__);
|
||||
if (ret == UPWR_REQ_BUSY) {
|
||||
return -EBUSY;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t plat_scmi_pd_psw(unsigned int index, unsigned int state)
|
||||
{
|
||||
uint32_t psw_parent = scmi_power_domains[index].psw_parent;
|
||||
uint32_t sram_parent = scmi_power_domains[index].sram_parent;
|
||||
uint64_t swt;
|
||||
bool on;
|
||||
int ret = 0;
|
||||
|
||||
if ((imx8ulp_psw[psw_parent].flags & ALWAYS_ON) != 0U &&
|
||||
(imx8ulp_psw[sram_parent].flags & ALWAYS_ON) != 0U) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
on = (state == POWER_STATE_ON) ? true : false;
|
||||
|
||||
if ((imx8ulp_psw[psw_parent].flags & ALWAYS_ON) == 0U) {
|
||||
swt = 1 << imx8ulp_psw[psw_parent].reg;
|
||||
if (imx8ulp_psw[psw_parent].count == 0U) {
|
||||
if (on == false) {
|
||||
WARN("off PSW[%d] that already in off state\n", psw_parent);
|
||||
ret = -EACCES;
|
||||
} else {
|
||||
ret = upwr_pwm_power((const uint32_t *)&swt, NULL, on);
|
||||
imx8ulp_psw[psw_parent].count++;
|
||||
}
|
||||
} else {
|
||||
if (on == true) {
|
||||
imx8ulp_psw[psw_parent].count++;
|
||||
} else {
|
||||
imx8ulp_psw[psw_parent].count--;
|
||||
}
|
||||
|
||||
if (imx8ulp_psw[psw_parent].count == 0U) {
|
||||
ret = upwr_pwm_power((const uint32_t *)&swt, NULL, on);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(imx8ulp_psw[sram_parent].flags & ALWAYS_ON) && (psw_parent != sram_parent)) {
|
||||
swt = 1 << imx8ulp_psw[sram_parent].reg;
|
||||
if (imx8ulp_psw[sram_parent].count == 0U) {
|
||||
if (on == false) {
|
||||
WARN("off PSW[%d] that already in off state\n", sram_parent);
|
||||
ret = -EACCES;
|
||||
} else {
|
||||
ret = upwr_pwm_power((const uint32_t *)&swt, NULL, on);
|
||||
imx8ulp_psw[sram_parent].count++;
|
||||
}
|
||||
} else {
|
||||
if (on == true) {
|
||||
imx8ulp_psw[sram_parent].count++;
|
||||
} else {
|
||||
imx8ulp_psw[sram_parent].count--;
|
||||
}
|
||||
|
||||
if (imx8ulp_psw[sram_parent].count == 0U) {
|
||||
ret = upwr_pwm_power((const uint32_t *)&swt, NULL, on);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void assert_pcc_reset(unsigned int pcc)
|
||||
{
|
||||
/* if sw_rst_reg is valid, assert the pcc reset */
|
||||
if (pcc != 0U) {
|
||||
mmio_clrbits_32(pcc, PCC_SW_RST);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t plat_scmi_pd_set_state(unsigned int agent_id __unused,
|
||||
unsigned int flags,
|
||||
unsigned int pd_id,
|
||||
unsigned int state)
|
||||
{
|
||||
unsigned int ps_idx;
|
||||
uint64_t mem;
|
||||
bool on;
|
||||
int ret;
|
||||
|
||||
if (flags != 0U || pd_id >= IMX8ULP_PD_PS6) {
|
||||
return SCMI_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
ps_idx = 0;
|
||||
while (ps_idx < IMX8ULP_PD_PS6 && scmi_power_domains[ps_idx].reg != pd_id) {
|
||||
ps_idx++;
|
||||
}
|
||||
|
||||
if (ps_idx == IMX8ULP_PD_PS6) {
|
||||
return SCMI_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (state == scmi_power_domains[ps_idx].power_state) {
|
||||
return SCMI_SUCCESS;
|
||||
}
|
||||
|
||||
mem = scmi_power_domains[ps_idx].bits;
|
||||
on = (state == POWER_STATE_ON ? true : false);
|
||||
if (on == true) {
|
||||
/* Assert pcc sw reset if necessary */
|
||||
assert_pcc_reset(scmi_power_domains[ps_idx].sw_rst_reg);
|
||||
|
||||
ret = plat_scmi_pd_psw(ps_idx, state);
|
||||
if (ret != 0U) {
|
||||
return SCMI_DENIED;
|
||||
}
|
||||
|
||||
ret = upwr_pwm_power(NULL, (const uint32_t *)&mem, on);
|
||||
if (ret != 0U) {
|
||||
return SCMI_DENIED;
|
||||
}
|
||||
} else {
|
||||
ret = upwr_pwm_power(NULL, (const uint32_t *)&mem, on);
|
||||
if (ret != 0U) {
|
||||
return SCMI_DENIED;
|
||||
}
|
||||
|
||||
ret = plat_scmi_pd_psw(ps_idx, state);
|
||||
if (ret != 0U) {
|
||||
return SCMI_DENIED;
|
||||
}
|
||||
}
|
||||
|
||||
scmi_power_domains[pd_id].power_state = state;
|
||||
|
||||
return SCMI_SUCCESS;
|
||||
}
|
85
plat/imx/imx8ulp/scmi/scmi_sensor.c
Normal file
85
plat/imx/imx8ulp/scmi/scmi_sensor.c
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright 2021-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <lib/libc/errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../../../drivers/scmi-msg/sensor.h"
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <drivers/scmi.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <lib/utils_def.h>
|
||||
#include <scmi.h>
|
||||
|
||||
#include <upower_api.h>
|
||||
|
||||
/* Only Temperature now */
|
||||
static uint16_t imx_scmi_sensor_count(unsigned int agent_id __unused)
|
||||
{
|
||||
return 1U;
|
||||
}
|
||||
|
||||
uint8_t imx_scmi_sensor_max_requests(unsigned int agent_id __unused)
|
||||
{
|
||||
return 1U;
|
||||
}
|
||||
|
||||
extern int upower_read_temperature(uint32_t sensor_id, int32_t *temperature);
|
||||
int imx_scmi_sensor_reading_get(uint32_t agent_id __unused, uint16_t sensor_id __unused,
|
||||
uint32_t *val)
|
||||
{
|
||||
int32_t temperature;
|
||||
int ret;
|
||||
|
||||
ret = upower_read_temperature(1, &temperature);
|
||||
if (ret != 0U) {
|
||||
val[0] = 0xFFFFFFFF;
|
||||
} else {
|
||||
val[0] = temperature;
|
||||
}
|
||||
|
||||
val[1] = 0;
|
||||
val[2] = 0;
|
||||
val[3] = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define SCMI_SENSOR_NAME_LENGTH_MAX 16U
|
||||
|
||||
uint32_t imx_scmi_sensor_state(uint32_t agent_id __unused, uint16_t sensor_id __unused)
|
||||
{
|
||||
return 1U;
|
||||
}
|
||||
|
||||
uint32_t imx_scmi_sensor_description_get(uint32_t agent_id __unused, uint16_t desc_index __unused,
|
||||
struct scmi_sensor_desc *desc __unused)
|
||||
{
|
||||
desc->id = 0;
|
||||
desc->attr_low = 0;
|
||||
desc->attr_high = 2;
|
||||
strlcpy((char *)desc->name, "UPOWER-TEMP", 12);
|
||||
desc->power = 0;
|
||||
desc->resolution = 0;
|
||||
desc->min_range_low = 0;
|
||||
desc->min_range_high = 0x80000000;
|
||||
desc->max_range_low = 0xffffffff;
|
||||
desc->max_range_high = 0x7fffffff;
|
||||
|
||||
return 1U;
|
||||
}
|
||||
|
||||
REGISTER_SCMI_SENSOR_OPS(imx_scmi_sensor_count,
|
||||
imx_scmi_sensor_max_requests,
|
||||
NULL,
|
||||
imx_scmi_sensor_reading_get,
|
||||
imx_scmi_sensor_description_get,
|
||||
NULL,
|
||||
imx_scmi_sensor_state,
|
||||
NULL);
|
279
plat/imx/imx8ulp/upower/upmu.h
Normal file
279
plat/imx/imx8ulp/upower/upmu.h
Normal file
|
@ -0,0 +1,279 @@
|
|||
/*
|
||||
* Copyright 2021-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef MU_H
|
||||
#define MU_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef volatile unsigned int vuint32_t;
|
||||
|
||||
/****************************************************************************/
|
||||
/* MODULE: Message Unit */
|
||||
/****************************************************************************/
|
||||
/* VER Register */
|
||||
typedef union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t FEATURE : 16;
|
||||
vuint32_t MINOR : 8;
|
||||
vuint32_t MAJOR : 8;
|
||||
} B;
|
||||
} MU_VER_t;
|
||||
|
||||
/* PAR Register */
|
||||
typedef union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t TR_NUM : 8;
|
||||
vuint32_t RR_NUM : 8;
|
||||
vuint32_t GIR_NUM : 8;
|
||||
vuint32_t FLAG_WIDTH : 8;
|
||||
} B;
|
||||
} MU_PAR_t;
|
||||
|
||||
/* CR Register */
|
||||
typedef union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t MUR : 1;
|
||||
vuint32_t MURIE : 1;
|
||||
vuint32_t rsrv_1 : 30;
|
||||
} B;
|
||||
} MU_CR_t;
|
||||
|
||||
/* SR Register */
|
||||
typedef union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t MURS : 1;
|
||||
vuint32_t MURIP : 1;
|
||||
vuint32_t EP : 1;
|
||||
vuint32_t FUP : 1;
|
||||
vuint32_t GIRP : 1;
|
||||
vuint32_t TEP : 1;
|
||||
vuint32_t RFP : 1;
|
||||
vuint32_t CEP : 1;
|
||||
vuint32_t rsrv_1 : 24;
|
||||
|
||||
} B;
|
||||
} MU_SR_t;
|
||||
|
||||
/* CCR0 Register */
|
||||
typedef union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t NMI : 1;
|
||||
vuint32_t HR : 1;
|
||||
vuint32_t HRM : 1;
|
||||
vuint32_t CLKE : 1;
|
||||
vuint32_t RSTH : 1;
|
||||
vuint32_t BOOT : 2;
|
||||
vuint32_t rsrv_1 : 25;
|
||||
|
||||
} B;
|
||||
} MU_CCR0_t;
|
||||
|
||||
/* CIER0 Register */
|
||||
typedef union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t rsrv_1 : 1;
|
||||
vuint32_t HRIE : 1;
|
||||
vuint32_t RUNIE : 1;
|
||||
vuint32_t RAIE : 1;
|
||||
vuint32_t HALTIE : 1;
|
||||
vuint32_t WAITIE : 1;
|
||||
vuint32_t STOPIE : 1;
|
||||
vuint32_t PDIE : 1;
|
||||
vuint32_t rsrv_2 : 24;
|
||||
} B;
|
||||
} MU_CIER0_t;
|
||||
|
||||
/* CSSR0 Register */
|
||||
typedef union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t NMIC : 1;
|
||||
vuint32_t HRIP : 1;
|
||||
vuint32_t RUN : 1;
|
||||
vuint32_t RAIP : 1;
|
||||
vuint32_t HALT : 1;
|
||||
vuint32_t WAIT : 1;
|
||||
vuint32_t STOP : 1;
|
||||
vuint32_t PD : 1;
|
||||
vuint32_t rsrv_1 : 24;
|
||||
} B;
|
||||
} MU_CSSR0_t;
|
||||
|
||||
/* CSR0 Register */
|
||||
typedef union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t rsrv_1 : 1;
|
||||
vuint32_t HRIP : 1;
|
||||
vuint32_t RUN : 1;
|
||||
vuint32_t RAIP : 1;
|
||||
vuint32_t HALT : 1;
|
||||
vuint32_t WAIT : 1;
|
||||
vuint32_t STOP : 1;
|
||||
vuint32_t PD : 1;
|
||||
vuint32_t rsrv_2 : 24;
|
||||
} B;
|
||||
} MU_CSR0_t;
|
||||
|
||||
/* FCR Register */
|
||||
typedef union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t F0 : 1;
|
||||
vuint32_t F1 : 1;
|
||||
vuint32_t F2 : 1;
|
||||
vuint32_t rsrv_1 : 29;
|
||||
} B;
|
||||
} MU_FCR_t;
|
||||
|
||||
/* FSR Register */
|
||||
typedef union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t F0 : 1;
|
||||
vuint32_t F1 : 1;
|
||||
vuint32_t F2 : 1;
|
||||
vuint32_t rsrv_1 : 29;
|
||||
} B;
|
||||
} MU_FSR_t;
|
||||
|
||||
/* GIER Register */
|
||||
typedef union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t GIE0 : 1;
|
||||
vuint32_t GIE1 : 1;
|
||||
vuint32_t rsrv_1 : 30;
|
||||
} B;
|
||||
} MU_GIER_t;
|
||||
|
||||
/* GCR Register */
|
||||
typedef union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t GIR0 : 1;
|
||||
vuint32_t GIR1 : 1;
|
||||
vuint32_t rsrv_1 : 30;
|
||||
} B;
|
||||
} MU_GCR_t;
|
||||
|
||||
/* GSR Register */
|
||||
typedef union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t GIP0 : 1;
|
||||
vuint32_t GIP1 : 1;
|
||||
vuint32_t rsrv_1 : 30;
|
||||
} B;
|
||||
} MU_GSR_t;
|
||||
|
||||
/* TCR Register */
|
||||
typedef union{
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t TIE0 : 1;
|
||||
vuint32_t TIE1 : 1;
|
||||
vuint32_t rsrv_1 : 30;
|
||||
} B;
|
||||
} MU_TCR_t;
|
||||
|
||||
/* TSR Register */
|
||||
typedef union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t TE0 : 1;
|
||||
vuint32_t TE1 : 1;
|
||||
vuint32_t rsrv_1 : 30;
|
||||
} B;
|
||||
} MU_TSR_t;
|
||||
|
||||
/* RCR Register */
|
||||
typedef union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t RIE0 : 1;
|
||||
vuint32_t RIE1 : 1;
|
||||
vuint32_t rsrv_1 : 30;
|
||||
} B;
|
||||
} MU_RCR_t;
|
||||
|
||||
/* RSR Register */
|
||||
typedef union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t RF0 : 1;
|
||||
vuint32_t RF1 : 1;
|
||||
vuint32_t rsrv_1 : 30;
|
||||
} B;
|
||||
} MU_RSR_t;
|
||||
|
||||
/* TR0 Register */
|
||||
typedef union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t TR_DATA : 32;
|
||||
} B;
|
||||
} MU_TR0_t;
|
||||
|
||||
/* TR1 Register */
|
||||
typedef union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t TR_DATA : 32;
|
||||
} B;
|
||||
} MU_TR1_t;
|
||||
|
||||
/* RR0 Register */
|
||||
typedef union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t RR_DATA : 32;
|
||||
} B;
|
||||
} MU_RR0_t;
|
||||
|
||||
/* RR1 Register */
|
||||
typedef union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t RR_DATA : 32;
|
||||
} B;
|
||||
} MU_RR1_t;
|
||||
|
||||
struct MU_t {
|
||||
MU_VER_t VER;
|
||||
MU_PAR_t PAR;
|
||||
MU_CR_t CR;
|
||||
MU_SR_t SR;
|
||||
MU_CCR0_t CCR0;
|
||||
MU_CIER0_t CIER0;
|
||||
MU_CSSR0_t CSSR0;
|
||||
MU_CSR0_t CSR0;
|
||||
uint8_t MU_reserved0[224];
|
||||
MU_FCR_t FCR;
|
||||
MU_FSR_t FSR;
|
||||
uint8_t MU_reserved1[8];
|
||||
MU_GIER_t GIER;
|
||||
MU_GCR_t GCR;
|
||||
MU_GSR_t GSR;
|
||||
uint8_t MU_reserved2[4];
|
||||
MU_TCR_t TCR;
|
||||
MU_TSR_t TSR;
|
||||
MU_RCR_t RCR;
|
||||
MU_RSR_t RSR;
|
||||
uint8_t MU_reserved3[208];
|
||||
MU_TR0_t TR[2];
|
||||
uint8_t MU_reserved4[120];
|
||||
MU_RR0_t RR[2];
|
||||
};
|
||||
|
||||
#endif /* MU_H */
|
3095
plat/imx/imx8ulp/upower/upower_api.c
Normal file
3095
plat/imx/imx8ulp/upower/upower_api.c
Normal file
File diff suppressed because it is too large
Load diff
1629
plat/imx/imx8ulp/upower/upower_api.h
Normal file
1629
plat/imx/imx8ulp/upower/upower_api.h
Normal file
File diff suppressed because it is too large
Load diff
742
plat/imx/imx8ulp/upower/upower_defs.h
Normal file
742
plat/imx/imx8ulp/upower/upower_defs.h
Normal file
|
@ -0,0 +1,742 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
/**
|
||||
* Copyright 2019-2024 NXP
|
||||
*
|
||||
* KEYWORDS: micro-power uPower driver API
|
||||
* -----------------------------------------------------------------------------
|
||||
* PURPOSE: uPower driver API #defines and typedefs shared with the firmware
|
||||
* -----------------------------------------------------------------------------
|
||||
* PARAMETERS:
|
||||
* PARAM NAME RANGE:DESCRIPTION: DEFAULTS: UNITS
|
||||
* -----------------------------------------------------------------------------
|
||||
* REUSE ISSUES: no reuse issues
|
||||
*/
|
||||
|
||||
#ifndef UPWR_DEFS_H
|
||||
#define UPWR_DEFS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef UPWR_PMC_SWT_WORDS
|
||||
#define UPWR_PMC_SWT_WORDS (1U)
|
||||
#endif
|
||||
|
||||
#ifndef UPWR_PMC_MEM_WORDS
|
||||
#define UPWR_PMC_MEM_WORDS (2U)
|
||||
#endif
|
||||
|
||||
/* ****************************************************************************
|
||||
* DOWNSTREAM MESSAGES - COMMANDS/FUNCTIONS
|
||||
* ****************************************************************************
|
||||
*/
|
||||
#define UPWR_SRVGROUP_BITS (4U)
|
||||
#define UPWR_FUNCTION_BITS (4U)
|
||||
#define UPWR_PWDOMAIN_BITS (4U)
|
||||
#define UPWR_HEADER_BITS \
|
||||
(UPWR_SRVGROUP_BITS + UPWR_FUNCTION_BITS + UPWR_PWDOMAIN_BITS)
|
||||
#define UPWR_ARG_BITS (32U - UPWR_HEADER_BITS)
|
||||
#if ((UPWR_ARG_BITS & 1U) > 0U)
|
||||
#error "UPWR_ARG_BITS must be an even number"
|
||||
#endif
|
||||
#define UPWR_ARG64_BITS (64U - UPWR_HEADER_BITS)
|
||||
#define UPWR_HALF_ARG_BITS (UPWR_ARG_BITS >> 1U)
|
||||
#define UPWR_DUAL_OFFSET_BITS ((UPWR_ARG_BITS + 32U) >> 1U)
|
||||
|
||||
/*
|
||||
* message header: header fields common to all downstream messages.
|
||||
*/
|
||||
struct upwr_msg_hdr {
|
||||
uint32_t domain : UPWR_PWDOMAIN_BITS; /* power domain */
|
||||
uint32_t srvgrp : UPWR_SRVGROUP_BITS; /* service group */
|
||||
uint32_t function : UPWR_FUNCTION_BITS; /* function */
|
||||
uint32_t arg : UPWR_ARG_BITS; /* function-specific argument */
|
||||
};
|
||||
|
||||
/* generic 1-word downstream message format */
|
||||
typedef union {
|
||||
struct upwr_msg_hdr hdr;
|
||||
uint32_t word; /* message first word */
|
||||
} upwr_down_1w_msg;
|
||||
|
||||
/* generic 2-word downstream message format */
|
||||
typedef struct {
|
||||
struct upwr_msg_hdr hdr;
|
||||
uint32_t word2; /* message second word */
|
||||
} upwr_down_2w_msg;
|
||||
|
||||
/* message format for functions that receive a pointer/offset */
|
||||
typedef struct {
|
||||
struct upwr_msg_hdr hdr;
|
||||
uint32_t ptr; /* config struct offset */
|
||||
} upwr_pointer_msg;
|
||||
|
||||
/* message format for functions that receive 2 pointers/offsets */
|
||||
typedef union {
|
||||
struct upwr_msg_hdr hdr;
|
||||
struct {
|
||||
uint64_t rsv : UPWR_HEADER_BITS;
|
||||
uint64_t ptr0 : UPWR_DUAL_OFFSET_BITS;
|
||||
uint64_t ptr1 : UPWR_DUAL_OFFSET_BITS;
|
||||
} ptrs;
|
||||
} upwr_2pointer_msg;
|
||||
|
||||
#define UPWR_SG_EXCEPT (0U) /* 0 = exception */
|
||||
#define UPWR_SG_PWRMGMT (1U) /* 1 = power management */
|
||||
#define UPWR_SG_DELAYM (2U) /* 2 = delay measurement */
|
||||
#define UPWR_SG_VOLTM (3U) /* 3 = voltage measurement */
|
||||
#define UPWR_SG_CURRM (4U) /* 4 = current measurement */
|
||||
#define UPWR_SG_TEMPM (5U) /* 5 = temperature measurement */
|
||||
#define UPWR_SG_DIAG (6U) /* 6 = diagnostic */
|
||||
#define UPWR_SG_COUNT (7U)
|
||||
|
||||
typedef uint32_t upwr_sg_t;
|
||||
|
||||
/* *************************************************************************
|
||||
* Initialization - downstream
|
||||
***************************************************************************/
|
||||
typedef upwr_down_1w_msg upwr_start_msg; /* start command message */
|
||||
typedef upwr_down_1w_msg upwr_power_on_msg; /* power on command message */
|
||||
typedef upwr_down_1w_msg upwr_boot_start_msg; /* boot start command message */
|
||||
typedef union {
|
||||
struct upwr_msg_hdr hdr;
|
||||
upwr_power_on_msg power_on;
|
||||
upwr_boot_start_msg boot_start;
|
||||
upwr_start_msg start;
|
||||
} upwr_startup_down_msg;
|
||||
|
||||
/* *************************************************************************
|
||||
* Service Group EXCEPTION - downstream
|
||||
***************************************************************************/
|
||||
|
||||
#define UPWR_XCP_INIT (0U) /* 0 = init msg (not a service request itself) */
|
||||
#define UPWR_XCP_PING (0U) /* 0 = also ping request, since its response isan init msg */
|
||||
#define UPWR_XCP_START (1U) /* 1 = service start: upwr_start *(not a service request itself) */
|
||||
#define UPWR_XCP_SHUTDOWN (2U) /* 2 = service shutdown: upwr_xcp_shutdown */
|
||||
#define UPWR_XCP_CONFIG (3U) /* 3 = uPower configuration: upwr_xcp_config */
|
||||
#define UPWR_XCP_SW_ALARM (4U) /* 4 = uPower software alarm: upwr_xcp_sw_alarm */
|
||||
#define UPWR_XCP_I2C (5U) /* 5 = I2C access: upwr_xcp_i2c_access */
|
||||
#define UPWR_XCP_SPARE_6 (6U) /* 6 = spare */
|
||||
#define UPWR_XCP_SET_DDR_RETN (7U) /* 7 = set/clear ddr retention */
|
||||
#define UPWR_XCP_SET_RTD_APD_LLWU (8U) /* 8 = set/clear rtd/apd llwu */
|
||||
#define UPWR_XCP_SPARE_8 (8U) /* 8 = spare */
|
||||
#define UPWR_XCP_SET_RTD_USE_DDR (9U) /* 9 = M33 core set it is using DDR or not */
|
||||
#define UPWR_XCP_SPARE_9 (9U) /* 9 = spare */
|
||||
#define UPWR_XCP_SPARE_10 (10U) /* 10 = spare */
|
||||
#define UPWR_XCP_SET_MIPI_DSI_ENA (10U) /* 10 = set/clear mipi dsi ena */
|
||||
#define UPWR_XCP_SPARE_11 (11U) /* 11 = spare */
|
||||
#define UPWR_XCP_GET_MIPI_DSI_ENA (11U) /* 11 = get mipi dsi ena status */
|
||||
#define UPWR_XCP_SPARE_12 (12U) /* 12 = spare */
|
||||
#define UPWR_XCP_SET_OSC_MODE (12U) /* 12 = set uPower OSC mode, high or low */
|
||||
#define UPWR_XCP_SPARE_13 (13U) /* 13 = spare */
|
||||
#define UPWR_XCP_SPARE_14 (14U) /* 14 = spare */
|
||||
#define UPWR_XCP_SPARE_15 (15U) /* 15 = spare */
|
||||
#define UPWR_XCP_F_COUNT (16U)
|
||||
|
||||
typedef uint32_t upwr_xcp_f_t;
|
||||
typedef upwr_down_1w_msg upwr_xcp_ping_msg;
|
||||
typedef upwr_down_1w_msg upwr_xcp_shutdown_msg;
|
||||
typedef upwr_power_on_msg upwr_xcp_power_on_msg;
|
||||
typedef upwr_boot_start_msg upwr_xcp_boot_start_msg;
|
||||
typedef upwr_start_msg upwr_xcp_start_msg;
|
||||
typedef upwr_down_2w_msg upwr_xcp_config_msg;
|
||||
typedef upwr_down_1w_msg upwr_xcp_swalarm_msg;
|
||||
typedef upwr_down_1w_msg upwr_xcp_ddr_retn_msg;
|
||||
typedef upwr_down_1w_msg upwr_xcp_set_mipi_dsi_ena_msg;
|
||||
typedef upwr_down_1w_msg upwr_xcp_get_mipi_dsi_ena_msg;
|
||||
typedef upwr_down_1w_msg upwr_xcp_rtd_use_ddr_msg;
|
||||
typedef upwr_down_1w_msg upwr_xcp_rtd_apd_llwu_msg;
|
||||
typedef upwr_down_1w_msg upwr_xcp_set_osc_mode_msg;
|
||||
typedef upwr_pointer_msg upwr_xcp_i2c_msg;
|
||||
|
||||
/* structure pointed by message upwr_xcp_i2c_msg */
|
||||
typedef struct {
|
||||
uint16_t addr;
|
||||
int8_t data_size;
|
||||
uint8_t subaddr_size;
|
||||
uint32_t subaddr;
|
||||
uint32_t data;
|
||||
} upwr_i2c_access;
|
||||
|
||||
/* Exception all messages */
|
||||
typedef union {
|
||||
struct upwr_msg_hdr hdr; /* message header */
|
||||
upwr_xcp_ping_msg ping; /* ping */
|
||||
upwr_xcp_start_msg start; /* service start */
|
||||
upwr_xcp_shutdown_msg shutdown; /* shutdown */
|
||||
upwr_xcp_boot_start_msg bootstart; /* boot start */
|
||||
upwr_xcp_config_msg config; /* uPower configuration */
|
||||
upwr_xcp_swalarm_msg swalarm; /* software alarm */
|
||||
upwr_xcp_i2c_msg i2c; /* I2C access */
|
||||
upwr_xcp_ddr_retn_msg set_ddr_retn; /* set ddr retention msg */
|
||||
upwr_xcp_set_mipi_dsi_ena_msg set_mipi_dsi_ena; /* set mipi dsi ena msg */
|
||||
upwr_xcp_get_mipi_dsi_ena_msg get_mipi_dsi_ena; /* get mipi dsi ena msg */
|
||||
upwr_xcp_rtd_use_ddr_msg set_rtd_use_ddr; /* set rtd is using ddr msg */
|
||||
upwr_xcp_rtd_apd_llwu_msg set_llwu; /* set rtd/apd llwu msg */
|
||||
upwr_xcp_set_osc_mode_msg set_osc_mode; /* set osc_mode msg */
|
||||
} upwr_xcp_msg;
|
||||
|
||||
/* structure pointed by message upwr_volt_dva_req_id_msg */
|
||||
typedef struct {
|
||||
uint32_t id_word0;
|
||||
uint32_t id_word1;
|
||||
uint32_t mode;
|
||||
} upwr_dva_id_struct;
|
||||
|
||||
/**
|
||||
* PMIC voltage accuracy is 12.5 mV, 12500 uV
|
||||
*/
|
||||
#define PMIC_VOLTAGE_MIN_STEP 12500U
|
||||
|
||||
/* *************************************************************************
|
||||
* Service Group POWER MANAGEMENT - downstream
|
||||
***************************************************************************/
|
||||
|
||||
#define UPWR_PWM_REGCFG (0U) /* 0 = regulator config: upwr_pwm_reg_config */
|
||||
#define UPWR_PWM_DEVMODE (0U) /* deprecated, for old compile */
|
||||
#define UPWR_PWM_VOLT (1U) /* 1 = voltage change: upwr_pwm_chng_reg_voltage */
|
||||
#define UPWR_PWM_SWITCH (2U) /* 2 = switch control: upwr_pwm_chng_switch_mem */
|
||||
#define UPWR_PWM_PWR_ON (3U) /* 3 = switch/RAM/ROM power on: upwr_pwm_power_on */
|
||||
#define UPWR_PWM_PWR_OFF (4U) /* 4 = switch/RAM/ROM power off: upwr_pwm_power_off */
|
||||
#define UPWR_PWM_RETAIN (5U) /* 5 = retain memory array: upwr_pwm_mem_retain */
|
||||
#define UPWR_PWM_DOM_BIAS (6U) /* 6 = Domain bias control: upwr_pwm_chng_dom_bias */
|
||||
#define UPWR_PWM_MEM_BIAS (7U) /* 7 = Memory bias control: upwr_pwm_chng_mem_bias */
|
||||
#define UPWR_PWM_PMICCFG (8U) /* 8 = PMIC configuration: upwr_pwm_pmic_config */
|
||||
#define UPWR_PWM_PMICMOD (8U) /* deprecated, for old compile */
|
||||
#define UPWR_PWM_PES (9U) /* 9 so far, no use */
|
||||
#define UPWR_PWM_CONFIG (10U) /* 10= apply power mode defined configuration */
|
||||
#define UPWR_PWM_CFGPTR (11U) /* 11= configuration pointer */
|
||||
#define UPWR_PWM_DOM_PWRON (12U) /* 12 = domain power on: upwr_pwm_dom_power_on */
|
||||
#define UPWR_PWM_BOOT (13U) /* 13 = boot start: upwr_pwm_boot_start */
|
||||
#define UPWR_PWM_FREQ (14U) /* 14 = domain frequency setup */
|
||||
#define UPWR_PWM_PARAM (15U) /* 15 = power management parameters */
|
||||
#define UPWR_PWM_F_COUNT (16U)
|
||||
|
||||
typedef uint32_t upwr_pwm_f_t;
|
||||
|
||||
#define MAX_PMETER_SSEL 7U
|
||||
|
||||
#define UPWR_VTM_CHNG_PMIC_RAIL_VOLT (0U) /* 0 = change pmic rail voltage */
|
||||
#define UPWR_VTM_GET_PMIC_RAIL_VOLT (1U) /* 1 = get pmic rail voltage */
|
||||
#define UPWR_VTM_PMIC_CONFIG (2U) /* 2 = configure PMIC IC */
|
||||
#define UPWR_VTM_DVA_DUMP_INFO (3U) /* 3 = dump dva information */
|
||||
#define UPWR_VTM_DVA_REQ_ID (4U) /* 4 = dva request ID array */
|
||||
#define UPWR_VTM_DVA_REQ_DOMAIN (5U) /* 5 = dva request domain */
|
||||
#define UPWR_VTM_DVA_REQ_SOC (6U) /* 6 = dva request the whole SOC */
|
||||
#define UPWR_VTM_PMETER_MEAS (7U) /* 7 = pmeter measure */
|
||||
#define UPWR_VTM_VMETER_MEAS (8U) /* 8 = vmeter measure */
|
||||
#define UPWR_VTM_PMIC_COLD_RESET (9U) /* 9 = pmic cold reset */
|
||||
#define UPWR_VTM_SET_DVFS_PMIC_RAIL (10U) /* 10 = set which domain use which pmic rail, for DVFS use */
|
||||
#define UPWR_VTM_SET_PMIC_MODE (11U) /* 11 = set pmic mode */
|
||||
#define UPWR_VTM_F_COUNT (16U)
|
||||
|
||||
typedef uint32_t upwr_volt_f_t;
|
||||
|
||||
#define VMETER_SEL_RTD 0U
|
||||
#define VMETER_SEL_LDO 1U
|
||||
#define VMETER_SEL_APD 2U
|
||||
#define VMETER_SEL_AVD 3U
|
||||
#define VMETER_SEL_MAX 3U
|
||||
|
||||
/**
|
||||
* The total TSEL count is 256
|
||||
*/
|
||||
#define MAX_TEMP_TSEL 256U
|
||||
|
||||
/**
|
||||
* Support 3 temperature sensor, sensor 0, 1, 2
|
||||
*/
|
||||
#define MAX_TEMP_SENSOR 2U
|
||||
|
||||
#define UPWR_TEMP_GET_CUR_TEMP (0U) /* 0 = get current temperature */
|
||||
#define UPWR_TEMP_F_COUNT (1U)
|
||||
typedef uint32_t upwr_temp_f_t;
|
||||
|
||||
#define UPWR_DMETER_GET_DELAY_MARGIN (0U) /* 0 = get delay margin */
|
||||
#define UPWR_DMETER_SET_DELAY_MARGIN (1U) /* 1 = set delay margin */
|
||||
#define UPWR_PMON_REQ (2U) /* 2 = process monitor service */
|
||||
#define UPWR_DMETER_F_COUNT (3U)
|
||||
|
||||
typedef uint32_t upwr_dmeter_f_t;
|
||||
|
||||
typedef upwr_down_1w_msg upwr_volt_pmeter_meas_msg;
|
||||
typedef upwr_down_1w_msg upwr_volt_pmic_set_mode_msg;
|
||||
typedef upwr_down_1w_msg upwr_volt_vmeter_meas_msg;
|
||||
|
||||
struct upwr_reg_config_t {
|
||||
uint32_t reg;
|
||||
};
|
||||
|
||||
/* set of 32 switches */
|
||||
struct upwr_switch_board_t {
|
||||
uint32_t on; /* Switch on state,1 bit per instance */
|
||||
uint32_t mask; /* actuation mask, 1 bit per instance */
|
||||
};
|
||||
|
||||
/* set of 32 RAM/ROM switches */
|
||||
struct upwr_mem_switches_t {
|
||||
uint32_t array; /* RAM/ROM array state, 1 bit per instance */
|
||||
uint32_t perif; /* RAM/ROM peripheral state, 1 bit per instance */
|
||||
uint32_t mask; /* actuation mask, 1 bit per instance */
|
||||
};
|
||||
|
||||
typedef upwr_down_1w_msg upwr_pwm_dom_pwron_msg; /* domain power on message */
|
||||
typedef upwr_down_1w_msg upwr_pwm_boot_start_msg; /* boot start message */
|
||||
|
||||
/* functions with complex arguments use the pointer message formats: */
|
||||
typedef upwr_pointer_msg upwr_pwm_retain_msg;
|
||||
typedef upwr_pointer_msg upwr_pwm_pmode_cfg_msg;
|
||||
|
||||
#if (UPWR_ARG_BITS < UPWR_DOMBIAS_ARG_BITS)
|
||||
#if ((UPWR_ARG_BITS + 32) < UPWR_DOMBIAS_ARG_BITS)
|
||||
#error "too few message bits for domain bias argument"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* service upwr_pwm_chng_dom_bias message argument fields */
|
||||
#define UPWR_DOMBIAS_MODE_BITS (2U)
|
||||
#define UPWR_DOMBIAS_RBB_BITS (8U)
|
||||
#define UPWR_DOMBIAS_RSV_BITS (14U)
|
||||
#define UPWR_DOMBIAS_ARG_BITS (UPWR_DOMBIAS_RSV_BITS + \
|
||||
(2U * UPWR_DOMBIAS_MODE_BITS) + \
|
||||
(4U * UPWR_DOMBIAS_RBB_BITS) + 2U)
|
||||
/*
|
||||
* upwr_pwm_dom_bias_args is an SoC-dependent message,
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t: 12U; /* TODO: find a way to use UPWR_HEADER_BITS */
|
||||
uint32_t dommode : UPWR_DOMBIAS_MODE_BITS;
|
||||
uint32_t avdmode : UPWR_DOMBIAS_MODE_BITS;
|
||||
uint32_t domapply : 1U;
|
||||
uint32_t avdapply : 1U;
|
||||
uint32_t rsv : UPWR_DOMBIAS_RSV_BITS;
|
||||
uint32_t domrbbn : UPWR_DOMBIAS_RBB_BITS; /* RTD/APD back bias N-well */
|
||||
uint32_t domrbbp : UPWR_DOMBIAS_RBB_BITS; /* RTD/APD back bias P-well */
|
||||
uint32_t avdrbbn : UPWR_DOMBIAS_RBB_BITS; /* AVD back bias N-well */
|
||||
uint32_t avdrbbp : UPWR_DOMBIAS_RBB_BITS; /* AVD back bias P-well */
|
||||
} upwr_pwm_dom_bias_args;
|
||||
|
||||
|
||||
typedef union {
|
||||
struct upwr_msg_hdr hdr; /* message header */
|
||||
struct {
|
||||
upwr_pwm_dom_bias_args B;
|
||||
} args;
|
||||
} upwr_pwm_dom_bias_msg;
|
||||
|
||||
/* service upwr_pwm_chng_mem_bias message argument fields */
|
||||
/*
|
||||
* upwr_pwm_mem_bias_args is an SoC-dependent message,
|
||||
* defined in upower_soc_defs.h
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t: 12U; /* TODO: find a way to use UPWR_HEADER_BITS */
|
||||
uint32_t en : 1U;
|
||||
uint32_t rsv : 19U;
|
||||
} upwr_pwm_mem_bias_args;
|
||||
|
||||
typedef union {
|
||||
struct upwr_msg_hdr hdr; /* message header */
|
||||
struct {
|
||||
upwr_pwm_mem_bias_args B;
|
||||
} args;
|
||||
} upwr_pwm_mem_bias_msg;
|
||||
|
||||
typedef upwr_pointer_msg upwr_pwm_pes_seq_msg;
|
||||
|
||||
/* upwr_pwm_reg_config-specific message format */
|
||||
typedef upwr_pointer_msg upwr_pwm_regcfg_msg;
|
||||
|
||||
/* upwr_volt_pmic_volt-specific message format */
|
||||
typedef union {
|
||||
struct upwr_msg_hdr hdr; /* message header */
|
||||
struct {
|
||||
uint32_t rsv : UPWR_HEADER_BITS;
|
||||
uint32_t domain : 8U;
|
||||
uint32_t rail : 8U;
|
||||
} args;
|
||||
} upwr_volt_dom_pmic_rail_msg;
|
||||
|
||||
typedef union {
|
||||
struct upwr_msg_hdr hdr;
|
||||
struct {
|
||||
uint32_t rsv : UPWR_HEADER_BITS;
|
||||
uint32_t rail : 4U; /* pmic rail id */
|
||||
uint32_t volt : 12U; /* voltage value, accurate to mV, support 0~3.3V */
|
||||
} args;
|
||||
} upwr_volt_pmic_set_volt_msg;
|
||||
|
||||
typedef union {
|
||||
struct upwr_msg_hdr hdr;
|
||||
struct {
|
||||
uint32_t rsv : UPWR_HEADER_BITS;
|
||||
uint32_t rail : 16U; /* pmic rail id */
|
||||
} args;
|
||||
} upwr_volt_pmic_get_volt_msg;
|
||||
|
||||
typedef union {
|
||||
struct upwr_msg_hdr hdr;
|
||||
struct {
|
||||
uint32_t rsv :UPWR_HEADER_BITS;
|
||||
uint32_t domain : 8U;
|
||||
uint32_t mode : 8U; /* work mode */
|
||||
} args;
|
||||
} upwr_volt_dva_req_domain_msg;
|
||||
|
||||
typedef union {
|
||||
struct upwr_msg_hdr hdr;
|
||||
struct {
|
||||
uint32_t rsv : UPWR_HEADER_BITS;
|
||||
uint32_t mode : 16U; /* work mode */
|
||||
} args;
|
||||
} upwr_volt_dva_req_soc_msg;
|
||||
|
||||
typedef union {
|
||||
struct upwr_msg_hdr hdr;
|
||||
struct {
|
||||
uint32_t rsv : UPWR_HEADER_BITS;
|
||||
uint32_t addr_offset : 16U; /* addr_offset to 0x28330000 */
|
||||
} args;
|
||||
} upwr_volt_dva_dump_info_msg;
|
||||
|
||||
typedef upwr_pointer_msg upwr_volt_pmiccfg_msg;
|
||||
typedef upwr_pointer_msg upwr_volt_dva_req_id_msg;
|
||||
typedef upwr_down_1w_msg upwr_volt_pmic_cold_reset_msg;
|
||||
|
||||
/* upwr_pwm_volt-specific message format */
|
||||
typedef union {
|
||||
struct upwr_msg_hdr hdr;
|
||||
struct {
|
||||
uint32_t rsv : UPWR_HEADER_BITS;
|
||||
uint32_t reg : UPWR_HALF_ARG_BITS; /* regulator id */
|
||||
uint32_t volt : UPWR_HALF_ARG_BITS; /* voltage value */
|
||||
} args;
|
||||
} upwr_pwm_volt_msg;
|
||||
|
||||
/* upwr_pwm_freq_setup-specific message format */
|
||||
/**
|
||||
* DVA adjust stage
|
||||
*/
|
||||
#define DVA_ADJUST_STAGE_INVALID 0U
|
||||
/* first stage, gross adjust, for increase frequency use */
|
||||
#define DVA_ADJUST_STAGE_ONE 1U
|
||||
/* second stage, fine adjust for increase frequency use */
|
||||
#define DVA_ADJUST_STAGE_TWO 2U
|
||||
/* combine first + second stage, for descrese frequency use */
|
||||
#define DVA_ADJUST_STAGE_FULL 3U
|
||||
|
||||
/**
|
||||
* This message structure is used for DVFS feature
|
||||
* 1. Because user may use different PMIC or different board,
|
||||
* the pmic regulator of RTD/APD may change,
|
||||
* so, user need to tell uPower the regulator number.
|
||||
* The number must be matched with PMIC IC and board.
|
||||
* use 4 bits for pmic regulator, support to 16 regulator.
|
||||
*
|
||||
* use 2 bits for DVA stage
|
||||
*
|
||||
* use 10 bits for target frequency, accurate to MHz, support to 1024 MHz
|
||||
*/
|
||||
typedef union {
|
||||
struct upwr_msg_hdr hdr;
|
||||
struct {
|
||||
uint32_t rsv : UPWR_HEADER_BITS;
|
||||
uint32_t rail : 4; /* pmic regulator */
|
||||
uint32_t stage : 2; /* DVA stage */
|
||||
uint32_t target_freq : 10; /* target frequency */
|
||||
} args;
|
||||
} upwr_pwm_freq_msg;
|
||||
|
||||
typedef upwr_down_2w_msg upwr_pwm_param_msg;
|
||||
|
||||
/* upwr_pwm_pmiccfg-specific message format */
|
||||
typedef upwr_pointer_msg upwr_pwm_pmiccfg_msg;
|
||||
|
||||
/* functions that pass a pointer use message format upwr_pointer_msg */
|
||||
typedef upwr_pointer_msg upwr_pwm_cfgptr_msg;
|
||||
|
||||
/* functions that pass 2 pointers use message format upwr_2pointer_msg
|
||||
*/
|
||||
typedef upwr_2pointer_msg upwr_pwm_switch_msg;
|
||||
typedef upwr_2pointer_msg upwr_pwm_pwron_msg;
|
||||
typedef upwr_2pointer_msg upwr_pwm_pwroff_msg;
|
||||
|
||||
/* Power Management all messages */
|
||||
typedef union {
|
||||
struct upwr_msg_hdr hdr; /* message header */
|
||||
upwr_pwm_param_msg param; /* power management parameters */
|
||||
upwr_pwm_dom_bias_msg dom_bias; /* domain bias message */
|
||||
upwr_pwm_mem_bias_msg mem_bias; /* memory bias message */
|
||||
upwr_pwm_pes_seq_msg pes; /* PE seq. message */
|
||||
upwr_pwm_pmode_cfg_msg pmode; /* power mode config message */
|
||||
upwr_pwm_regcfg_msg regcfg; /* regulator config message */
|
||||
upwr_pwm_volt_msg volt; /* set voltage message */
|
||||
upwr_pwm_freq_msg freq; /* set frequency message */
|
||||
upwr_pwm_switch_msg switches; /* switch control message */
|
||||
upwr_pwm_pwron_msg pwron; /* switch/RAM/ROM power on message */
|
||||
upwr_pwm_pwroff_msg pwroff; /* switch/RAM/ROM power off message */
|
||||
upwr_pwm_retain_msg retain; /* memory retain message */
|
||||
upwr_pwm_cfgptr_msg cfgptr; /* configuration pointer message*/
|
||||
upwr_pwm_dom_pwron_msg dompwron; /* domain power on message */
|
||||
upwr_pwm_boot_start_msg boot; /* boot start message */
|
||||
} upwr_pwm_msg;
|
||||
|
||||
typedef union {
|
||||
struct upwr_msg_hdr hdr; /* message header */
|
||||
upwr_volt_pmic_set_volt_msg set_pmic_volt; /* set pmic voltage message */
|
||||
upwr_volt_pmic_get_volt_msg get_pmic_volt; /* set pmic voltage message */
|
||||
upwr_volt_pmic_set_mode_msg set_pmic_mode; /* set pmic mode message */
|
||||
upwr_volt_pmiccfg_msg pmiccfg; /* PMIC configuration message */
|
||||
upwr_volt_dom_pmic_rail_msg dom_pmic_rail; /* domain bias message */
|
||||
upwr_volt_dva_dump_info_msg dva_dump_info; /* dump dva info message */
|
||||
upwr_volt_dva_req_id_msg dva_req_id; /* dump dva request id array message */
|
||||
upwr_volt_dva_req_domain_msg dva_req_domain; /* dump dva request domain message */
|
||||
upwr_volt_dva_req_soc_msg dva_req_soc; /* dump dva request whole soc message */
|
||||
upwr_volt_pmeter_meas_msg pmeter_meas_msg; /* pmeter measure message */
|
||||
upwr_volt_vmeter_meas_msg vmeter_meas_msg; /* vmeter measure message */
|
||||
upwr_volt_pmic_cold_reset_msg cold_reset_msg; /* pmic cold reset message */
|
||||
} upwr_volt_msg;
|
||||
|
||||
|
||||
typedef union {
|
||||
struct upwr_msg_hdr hdr;
|
||||
struct {
|
||||
uint32_t rsv : UPWR_HEADER_BITS;
|
||||
uint32_t sensor_id : 16U; /* temperature sensor id */
|
||||
} args;
|
||||
} upwr_temp_get_cur_temp_msg;
|
||||
|
||||
typedef union {
|
||||
struct upwr_msg_hdr hdr;
|
||||
struct {
|
||||
uint32_t rsv : UPWR_HEADER_BITS;
|
||||
uint32_t index : 8U; /* the delay meter index */
|
||||
uint32_t path : 8U; /* the critical path number */
|
||||
} args;
|
||||
} upwr_dmeter_get_delay_margin_msg;
|
||||
|
||||
#define MAX_DELAY_MARGIN 63U
|
||||
#define MAX_DELAY_CRITICAL_PATH 7U
|
||||
#define MAX_DELAY_METER_NUM 1U
|
||||
|
||||
typedef union {
|
||||
struct upwr_msg_hdr hdr;
|
||||
struct {
|
||||
uint32_t rsv : UPWR_HEADER_BITS;
|
||||
uint32_t index: 4U; /* the delay meter index */
|
||||
uint32_t path: 4U; /* the critical path number */
|
||||
uint32_t dm: 8U; /* the delay margin value of delay meter */
|
||||
} args;
|
||||
} upwr_dmeter_set_delay_margin_msg;
|
||||
|
||||
#define MAX_PMON_CHAIN_SEL 1U
|
||||
|
||||
typedef union {
|
||||
struct upwr_msg_hdr hdr;
|
||||
struct {
|
||||
uint32_t rsv : UPWR_HEADER_BITS;
|
||||
uint32_t chain_sel : 16U; /* the process monitor delay chain sel */
|
||||
} args;
|
||||
} upwr_pmon_msg;
|
||||
|
||||
typedef union {
|
||||
struct upwr_msg_hdr hdr; /* message header */
|
||||
upwr_temp_get_cur_temp_msg get_temp_msg; /* get current temperature message */
|
||||
} upwr_temp_msg;
|
||||
|
||||
typedef union {
|
||||
struct upwr_msg_hdr hdr; /* message header */
|
||||
upwr_dmeter_get_delay_margin_msg get_margin_msg; /* get delay margin message */
|
||||
upwr_dmeter_set_delay_margin_msg set_margin_msg; /* set delay margin message */
|
||||
upwr_pmon_msg pmon_msg; /* process monitor message */
|
||||
} upwr_dmeter_msg;
|
||||
|
||||
typedef upwr_down_2w_msg upwr_down_max_msg; /* longest downstream msg */
|
||||
|
||||
/*
|
||||
* upwr_dom_bias_cfg_t and upwr_mem_bias_cfg_t are SoC-dependent structs,
|
||||
* defined in upower_soc_defs.h
|
||||
*/
|
||||
/* Power and mem switches */
|
||||
typedef struct {
|
||||
volatile struct upwr_switch_board_t swt_board[UPWR_PMC_SWT_WORDS];
|
||||
volatile struct upwr_mem_switches_t swt_mem[UPWR_PMC_MEM_WORDS];
|
||||
} swt_config_t;
|
||||
|
||||
/* *************************************************************************
|
||||
* Service Group DIAGNOSE - downstream
|
||||
***************************************************************************/
|
||||
/* Diagnose Functions */
|
||||
#define UPWR_DGN_MODE (0U) /* 0 = diagnose mode: upwr_dgn_mode */
|
||||
#define UPWR_DGN_F_COUNT (1U)
|
||||
#define UPWR_DGN_BUFFER_EN (2U)
|
||||
typedef uint32_t upwr_dgn_f_t;
|
||||
|
||||
#define UPWR_DGN_ALL2ERR (0U) /* record all until an error occurs, freeze recording on error */
|
||||
#define UPWR_DGN_ALL2HLT (1U) /* record all until an error occurs, halt core on error */
|
||||
#define UPWR_DGN_ALL (2U) /* trace, warnings, errors, task state recorded */
|
||||
#define UPWR_DGN_MAX UPWR_DGN_ALL
|
||||
#define UPWR_DGN_TRACE (3U) /* trace, warnings, errors recorded */
|
||||
#define UPWR_DGN_SRVREQ (4U) /* service request activity recorded */
|
||||
#define UPWR_DGN_WARN (5U) /* warnings and errors recorded */
|
||||
#define UPWR_DGN_ERROR (6U) /* only errors recorded */
|
||||
#define UPWR_DGN_NONE (7U) /* no diagnostic recorded */
|
||||
#define UPWR_DGN_COUNT (8U)
|
||||
typedef uint32_t upwr_dgn_mode_t;
|
||||
|
||||
typedef upwr_down_1w_msg upwr_dgn_mode_msg;
|
||||
|
||||
typedef union {
|
||||
struct upwr_msg_hdr hdr;
|
||||
upwr_dgn_mode_msg mode_msg;
|
||||
} upwr_dgn_msg;
|
||||
|
||||
typedef struct {
|
||||
struct upwr_msg_hdr hdr;
|
||||
uint32_t buf_addr;
|
||||
} upwr_dgn_v2_msg;
|
||||
|
||||
/* diagnostics log types in the shared RAM log buffer */
|
||||
|
||||
typedef enum {
|
||||
DGN_LOG_NONE = 0x00000000,
|
||||
DGN_LOG_INFO = 0x10000000,
|
||||
DGN_LOG_ERROR = 0x20000000,
|
||||
DGN_LOG_ASSERT = 0x30000000,
|
||||
DGN_LOG_EXCEPT = 0x40000000,
|
||||
DGN_LOG_EVENT = 0x50000000, // old event trace
|
||||
DGN_LOG_EVENTNEW = 0x60000000, // new event trace
|
||||
DGN_LOG_SERVICE = 0x70000000,
|
||||
DGN_LOG_TASKDEF = 0x80000000,
|
||||
DGN_LOG_TASKEXE = 0x90000000,
|
||||
DGN_LOG_MUTEX = 0xA0000000,
|
||||
DGN_LOG_SEMAPH = 0xB0000000,
|
||||
DGN_LOG_TIMER = 0xC0000000,
|
||||
DGN_LOG_CALLTRACE = 0xD0000000,
|
||||
DGN_LOG_DATA = 0xE0000000,
|
||||
DGN_LOG_PCTRACE = 0xF0000000
|
||||
} upwr_dgn_log_t;
|
||||
|
||||
/* ****************************************************************************
|
||||
* UPSTREAM MESSAGES - RESPONSES
|
||||
* ****************************************************************************
|
||||
*/
|
||||
/* generic ok/ko response message */
|
||||
#define UPWR_RESP_ERR_BITS (4U)
|
||||
#define UPWR_RESP_HDR_BITS (UPWR_RESP_ERR_BITS+\
|
||||
UPWR_SRVGROUP_BITS+UPWR_FUNCTION_BITS)
|
||||
#define UPWR_RESP_RET_BITS (32U - UPWR_RESP_HDR_BITS)
|
||||
|
||||
#define UPWR_RESP_OK (0U) /* no error */
|
||||
#define UPWR_RESP_SG_BUSY (1U) /* service group is busy */
|
||||
#define UPWR_RESP_SHUTDOWN (2U) /* services not up or shutting down */
|
||||
#define UPWR_RESP_BAD_REQ (3U) /* invalid request */
|
||||
#define UPWR_RESP_BAD_STATE (4U) /* system state doesn't allow perform the request */
|
||||
#define UPWR_RESP_UNINSTALLD (5U) /* service or function not installed */
|
||||
#define UPWR_RESP_UNINSTALLED (5U) /* service or function not installed (alias) */
|
||||
#define UPWR_RESP_RESOURCE (6U) /* resource not available */
|
||||
#define UPWR_RESP_TIMEOUT (7U) /* service timeout */
|
||||
#define UPWR_RESP_COUNT (8U)
|
||||
|
||||
typedef uint32_t upwr_resp_t;
|
||||
|
||||
struct upwr_resp_hdr {
|
||||
uint32_t errcode : UPWR_RESP_ERR_BITS;
|
||||
uint32_t srvgrp : UPWR_SRVGROUP_BITS; /* service group */
|
||||
uint32_t function: UPWR_FUNCTION_BITS;
|
||||
uint32_t ret : UPWR_RESP_RET_BITS; /* return value, if any */
|
||||
};
|
||||
|
||||
/* generic 1-word upstream message format */
|
||||
typedef union {
|
||||
struct upwr_resp_hdr hdr;
|
||||
uint32_t word;
|
||||
} upwr_resp_msg;
|
||||
|
||||
/* generic 2-word upstream message format */
|
||||
typedef struct {
|
||||
struct upwr_resp_hdr hdr;
|
||||
uint32_t word2; /* message second word */
|
||||
} upwr_up_2w_msg;
|
||||
|
||||
typedef upwr_up_2w_msg upwr_up_max_msg;
|
||||
|
||||
/* *************************************************************************
|
||||
* Exception/Initialization - upstream
|
||||
***************************************************************************/
|
||||
#define UPWR_SOC_BITS (7U)
|
||||
#define UPWR_VMINOR_BITS (4U)
|
||||
#define UPWR_VFIXES_BITS (4U)
|
||||
#define UPWR_VMAJOR_BITS \
|
||||
(32U - UPWR_HEADER_BITS - UPWR_SOC_BITS - UPWR_VMINOR_BITS - UPWR_VFIXES_BITS)
|
||||
|
||||
typedef struct {
|
||||
uint32_t soc_id;
|
||||
uint32_t vmajor;
|
||||
uint32_t vminor;
|
||||
uint32_t vfixes;
|
||||
} upwr_code_vers_t;
|
||||
|
||||
/* message sent by firmware initialization, received by upwr_init */
|
||||
typedef union {
|
||||
struct upwr_resp_hdr hdr;
|
||||
struct {
|
||||
uint32_t rsv : UPWR_RESP_HDR_BITS;
|
||||
uint32_t soc : UPWR_SOC_BITS; /* SoC identification */
|
||||
uint32_t vmajor : UPWR_VMAJOR_BITS; /* firmware major version */
|
||||
uint32_t vminor : UPWR_VMINOR_BITS; /* firmware minor version */
|
||||
uint32_t vfixes : UPWR_VFIXES_BITS; /* firmware fixes version */
|
||||
} args;
|
||||
} upwr_init_msg;
|
||||
|
||||
/* message sent by firmware when the core platform is powered up */
|
||||
typedef upwr_resp_msg upwr_power_up_msg;
|
||||
|
||||
/* message sent by firmware when the core reset is released for boot */
|
||||
typedef upwr_resp_msg upwr_boot_up_msg;
|
||||
|
||||
/* message sent by firmware when ready for service requests */
|
||||
#define UPWR_RAM_VMINOR_BITS (7)
|
||||
#define UPWR_RAM_VFIXES_BITS (6)
|
||||
#define UPWR_RAM_VMAJOR_BITS (32 - UPWR_HEADER_BITS \
|
||||
- UPWR_RAM_VFIXES_BITS - UPWR_RAM_VMINOR_BITS)
|
||||
typedef union {
|
||||
struct upwr_resp_hdr hdr;
|
||||
struct {
|
||||
uint32_t rsv : UPWR_RESP_HDR_BITS;
|
||||
uint32_t vmajor : UPWR_RAM_VMAJOR_BITS; /* RAM fw major version */
|
||||
uint32_t vminor : UPWR_RAM_VMINOR_BITS; /* RAM fw minor version */
|
||||
uint32_t vfixes : UPWR_RAM_VFIXES_BITS; /* RAM fw fixes version */
|
||||
} args;
|
||||
} upwr_ready_msg;
|
||||
|
||||
/* message sent by firmware when shutdown finishes */
|
||||
typedef upwr_resp_msg upwr_shutdown_msg;
|
||||
|
||||
typedef union {
|
||||
struct upwr_resp_hdr hdr;
|
||||
upwr_init_msg init;
|
||||
upwr_power_up_msg pwrup;
|
||||
upwr_boot_up_msg booted;
|
||||
upwr_ready_msg ready;
|
||||
} upwr_startup_up_msg;
|
||||
|
||||
/* message sent by firmware for uPower config setting */
|
||||
typedef upwr_resp_msg upwr_config_resp_msg;
|
||||
|
||||
/* message sent by firmware for uPower alarm */
|
||||
typedef upwr_resp_msg upwr_alarm_resp_msg;
|
||||
|
||||
/* *************************************************************************
|
||||
* Power Management - upstream
|
||||
***************************************************************************/
|
||||
typedef upwr_resp_msg upwr_param_resp_msg;
|
||||
|
||||
enum work_mode {
|
||||
OVER_DRIVE,
|
||||
NORMAL_DRIVE,
|
||||
LOW_DRIVE
|
||||
};
|
||||
|
||||
#define UTIMER3_MAX_COUNT 0xFFFFU
|
||||
|
||||
#endif /* UPWR_DEFS_H */
|
147
plat/imx/imx8ulp/upower/upower_hal.c
Normal file
147
plat/imx/imx8ulp/upower/upower_hal.c
Normal file
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* Copyright 2020-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <drivers/delay_timer.h>
|
||||
#include <lib/mmio.h>
|
||||
|
||||
#include "upower_api.h"
|
||||
#include "upower_defs.h"
|
||||
|
||||
#define UPOWER_AP_MU1_ADDR U(0x29280000)
|
||||
|
||||
struct MU_t *muptr = (struct MU_t *)UPOWER_AP_MU1_ADDR;
|
||||
|
||||
void upower_apd_inst_isr(upwr_isr_callb txrx_isr,
|
||||
upwr_isr_callb excp_isr)
|
||||
{
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
int upower_status(int status)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
switch (status) {
|
||||
case 0:
|
||||
VERBOSE("finished successfully!\n");
|
||||
ret = 0;
|
||||
break;
|
||||
case -1:
|
||||
VERBOSE("memory allocation or resource failed!\n");
|
||||
break;
|
||||
case -2:
|
||||
VERBOSE("invalid argument!\n");
|
||||
break;
|
||||
case -3:
|
||||
VERBOSE("called in an invalid API state!\n");
|
||||
break;
|
||||
default:
|
||||
VERBOSE("invalid return status\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void upower_wait_resp(void)
|
||||
{
|
||||
while (muptr->RSR.B.RF0 == 0) {
|
||||
udelay(100);
|
||||
}
|
||||
upwr_txrx_isr();
|
||||
}
|
||||
|
||||
static void user_upwr_rdy_callb(uint32_t soc, uint32_t vmajor, uint32_t vminor)
|
||||
{
|
||||
NOTICE("%s: soc=%x\n", __func__, soc);
|
||||
NOTICE("%s: RAM version:%d.%d\n", __func__, vmajor, vminor);
|
||||
}
|
||||
|
||||
int upower_init(void)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = upwr_init(APD_DOMAIN, muptr, NULL, NULL, upower_apd_inst_isr, NULL);
|
||||
if (upower_status(status)) {
|
||||
ERROR("%s: upower init failure\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
NOTICE("%s: start uPower RAM service\n", __func__);
|
||||
status = upwr_start(1, user_upwr_rdy_callb);
|
||||
upower_wait_resp();
|
||||
/* poll status */
|
||||
if (upower_status(status)) {
|
||||
NOTICE("%s: upower init failure\n", __func__);
|
||||
return status;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int upower_pwm(int domain_id, bool pwr_on)
|
||||
{
|
||||
int ret, ret_val;
|
||||
uint32_t swt;
|
||||
|
||||
if (domain_id == 9U || domain_id == 11U || domain_id == 12U) {
|
||||
swt = BIT_32(12) | BIT_32(11) | BIT_32(10) | BIT_32(9);
|
||||
} else {
|
||||
swt = BIT_32(domain_id);
|
||||
}
|
||||
|
||||
if (pwr_on) {
|
||||
ret = upwr_pwm_power_on(&swt, NULL, NULL);
|
||||
} else {
|
||||
ret = upwr_pwm_power_off(&swt, NULL, NULL);
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
NOTICE("%s failed: ret: %d, pwr_on: %d\n", __func__, ret, pwr_on);
|
||||
return ret;
|
||||
}
|
||||
upower_wait_resp();
|
||||
|
||||
ret = upwr_poll_req_status(UPWR_SG_PWRMGMT, NULL, NULL, &ret_val, 1000);
|
||||
if (ret != UPWR_REQ_OK) {
|
||||
NOTICE("Failure %d, %s\n", ret, __func__);
|
||||
if (ret == UPWR_REQ_BUSY) {
|
||||
return -EBUSY;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int upower_read_temperature(uint32_t sensor_id, int32_t *temperature)
|
||||
{
|
||||
int ret, ret_val;
|
||||
upwr_resp_t err_code;
|
||||
int64_t t;
|
||||
|
||||
ret = upwr_tpm_get_temperature(sensor_id, NULL);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
upower_wait_resp();
|
||||
ret = upwr_poll_req_status(UPWR_SG_TEMPM, NULL, &err_code, &ret_val, 1000);
|
||||
if (ret > UPWR_REQ_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
t = ret_val & 0xff;
|
||||
*temperature = (2673049 * t * t * t / 10000000 + 3734262 * t * t / 100000 +
|
||||
4487042 * t / 100 - 4698694) / 100000;
|
||||
|
||||
return 0;
|
||||
}
|
1154
plat/imx/imx8ulp/upower/upower_soc_defs.h
Normal file
1154
plat/imx/imx8ulp/upower/upower_soc_defs.h
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue