Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
Arm Trusted Firmware
Commits
44b935c0
Unverified
Commit
44b935c0
authored
Jan 30, 2019
by
Antonio Niño Díaz
Committed by
GitHub
Jan 30, 2019
Browse files
Merge pull request #1789 from Anson-Huang/lpm
Add power optimization for i.MX8QM/i.MX8QX
parents
7d388400
e6cf7a46
Changes
13
Hide whitespace changes
Inline
Side-by-side
plat/imx/common/imx8_psci.c
View file @
44b935c0
...
@@ -32,8 +32,22 @@ void __dead2 imx_system_reset(void)
...
@@ -32,8 +32,22 @@ void __dead2 imx_system_reset(void)
int
imx_validate_power_state
(
unsigned
int
power_state
,
int
imx_validate_power_state
(
unsigned
int
power_state
,
psci_power_state_t
*
req_state
)
psci_power_state_t
*
req_state
)
{
{
/* TODO */
int
pwr_lvl
=
psci_get_pstate_pwrlvl
(
power_state
);
return
PSCI_E_INVALID_PARAMS
;
int
pwr_type
=
psci_get_pstate_type
(
power_state
);
int
state_id
=
psci_get_pstate_id
(
power_state
);
if
(
pwr_lvl
>
PLAT_MAX_PWR_LVL
)
return
PSCI_E_INVALID_PARAMS
;
if
(
pwr_type
==
PSTATE_TYPE_POWERDOWN
)
{
req_state
->
pwr_domain_state
[
MPIDR_AFFLVL0
]
=
PLAT_MAX_OFF_STATE
;
if
(
!
state_id
)
req_state
->
pwr_domain_state
[
MPIDR_AFFLVL1
]
=
PLAT_MAX_RET_STATE
;
else
req_state
->
pwr_domain_state
[
MPIDR_AFFLVL1
]
=
PLAT_MAX_OFF_STATE
;
}
return
PSCI_E_SUCCESS
;
}
}
void
imx_get_sys_suspend_power_state
(
psci_power_state_t
*
req_state
)
void
imx_get_sys_suspend_power_state
(
psci_power_state_t
*
req_state
)
...
...
plat/imx/common/include/plat_imx8.h
View file @
44b935c0
...
@@ -10,6 +10,11 @@
...
@@ -10,6 +10,11 @@
#include <drivers/arm/gicv3.h>
#include <drivers/arm/gicv3.h>
#include <lib/psci/psci.h>
#include <lib/psci/psci.h>
struct
plat_gic_ctx
{
gicv3_redist_ctx_t
rdist_ctx
[
PLATFORM_CORE_COUNT
];
gicv3_dist_ctx_t
dist_ctx
;
};
unsigned
int
plat_calc_core_pos
(
uint64_t
mpidr
);
unsigned
int
plat_calc_core_pos
(
uint64_t
mpidr
);
void
imx_mailbox_init
(
uintptr_t
base_addr
);
void
imx_mailbox_init
(
uintptr_t
base_addr
);
void
plat_gic_driver_init
(
void
);
void
plat_gic_driver_init
(
void
);
...
@@ -24,5 +29,7 @@ int imx_validate_power_state(unsigned int power_state,
...
@@ -24,5 +29,7 @@ int imx_validate_power_state(unsigned int power_state,
psci_power_state_t
*
req_state
);
psci_power_state_t
*
req_state
);
void
imx_get_sys_suspend_power_state
(
psci_power_state_t
*
req_state
);
void
imx_get_sys_suspend_power_state
(
psci_power_state_t
*
req_state
);
bool
imx_is_wakeup_src_irqsteer
(
void
);
bool
imx_is_wakeup_src_irqsteer
(
void
);
void
plat_gic_save
(
unsigned
int
proc_num
,
struct
plat_gic_ctx
*
ctx
);
void
plat_gic_restore
(
unsigned
int
proc_num
,
struct
plat_gic_ctx
*
ctx
);
#endif
/* PLAT_IMX8_H */
#endif
/* PLAT_IMX8_H */
plat/imx/common/plat_imx8_gic.c
View file @
44b935c0
...
@@ -73,3 +73,19 @@ void plat_gic_pcpu_init(void)
...
@@ -73,3 +73,19 @@ void plat_gic_pcpu_init(void)
{
{
gicv3_rdistif_init
(
plat_my_core_pos
());
gicv3_rdistif_init
(
plat_my_core_pos
());
}
}
void
plat_gic_save
(
unsigned
int
proc_num
,
struct
plat_gic_ctx
*
ctx
)
{
/* save the gic rdist/dist context */
for
(
int
i
=
0
;
i
<
PLATFORM_CORE_COUNT
;
i
++
)
gicv3_rdistif_save
(
i
,
&
ctx
->
rdist_ctx
[
i
]);
gicv3_distif_save
(
&
ctx
->
dist_ctx
);
}
void
plat_gic_restore
(
unsigned
int
proc_num
,
struct
plat_gic_ctx
*
ctx
)
{
/* restore the gic rdist/dist context */
gicv3_distif_init_restore
(
&
ctx
->
dist_ctx
);
for
(
int
i
=
0
;
i
<
PLATFORM_CORE_COUNT
;
i
++
)
gicv3_rdistif_init_restore
(
i
,
&
ctx
->
rdist_ctx
[
i
]);
}
plat/imx/common/sci/imx8_mu.c
View file @
44b935c0
...
@@ -8,6 +8,21 @@
...
@@ -8,6 +8,21 @@
#include "imx8_mu.h"
#include "imx8_mu.h"
void
MU_Resume
(
uint32_t
base
)
{
uint32_t
reg
,
i
;
reg
=
mmio_read_32
(
base
+
MU_ACR_OFFSET1
);
/* Clear GIEn, RIEn, TIEn, GIRn and ABFn. */
reg
&=
~
(
MU_CR_GIEn_MASK1
|
MU_CR_RIEn_MASK1
|
MU_CR_TIEn_MASK1
|
MU_CR_GIRn_MASK1
|
MU_CR_Fn_MASK1
);
mmio_write_32
(
base
+
MU_ACR_OFFSET1
,
reg
);
/* Enable all RX interrupts */
for
(
i
=
0
;
i
<
MU_RR_COUNT
;
i
++
)
MU_EnableRxFullInt
(
base
,
i
);
}
void
MU_EnableRxFullInt
(
uint32_t
base
,
uint32_t
index
)
void
MU_EnableRxFullInt
(
uint32_t
base
,
uint32_t
index
)
{
{
uint32_t
reg
=
mmio_read_32
(
base
+
MU_ACR_OFFSET1
);
uint32_t
reg
=
mmio_read_32
(
base
+
MU_ACR_OFFSET1
);
...
...
plat/imx/common/sci/imx8_mu.h
View file @
44b935c0
...
@@ -33,3 +33,4 @@ void MU_SendMessage(uint32_t base, uint32_t regIndex, uint32_t msg);
...
@@ -33,3 +33,4 @@ void MU_SendMessage(uint32_t base, uint32_t regIndex, uint32_t msg);
void
MU_ReceiveMsg
(
uint32_t
base
,
uint32_t
regIndex
,
uint32_t
*
msg
);
void
MU_ReceiveMsg
(
uint32_t
base
,
uint32_t
regIndex
,
uint32_t
*
msg
);
void
MU_EnableGeneralInt
(
uint32_t
base
,
uint32_t
index
);
void
MU_EnableGeneralInt
(
uint32_t
base
,
uint32_t
index
);
void
MU_EnableRxFullInt
(
uint32_t
base
,
uint32_t
index
);
void
MU_EnableRxFullInt
(
uint32_t
base
,
uint32_t
index
);
void
MU_Resume
(
uint32_t
base
);
plat/imx/imx8qm/imx8qm_bl31_setup.c
View file @
44b935c0
...
@@ -49,11 +49,7 @@ const static int imx8qm_cci_map[] = {
...
@@ -49,11 +49,7 @@ const static int imx8qm_cci_map[] = {
};
};
static
const
mmap_region_t
imx_mmap
[]
=
{
static
const
mmap_region_t
imx_mmap
[]
=
{
MAP_REGION_FLAT
(
IMX_BOOT_UART_BASE
,
IMX_BOOT_UART_SIZE
,
MT_DEVICE
|
MT_RW
),
MAP_REGION_FLAT
(
IMX_REG_BASE
,
IMX_REG_SIZE
,
MT_DEVICE
|
MT_RW
),
MAP_REGION_FLAT
(
SC_IPC_BASE
,
SC_IPC_SIZE
,
MT_DEVICE
|
MT_RW
),
MAP_REGION_FLAT
(
PLAT_GICD_BASE
,
PLAT_GICD_SIZE
,
MT_DEVICE
|
MT_RW
),
MAP_REGION_FLAT
(
PLAT_GICR_BASE
,
PLAT_GICR_SIZE
,
MT_DEVICE
|
MT_RW
),
MAP_REGION_FLAT
(
PLAT_CCI_BASE
,
PLAT_CCI_SIZE
,
MT_DEVICE
|
MT_RW
),
{
0
}
{
0
}
};
};
...
@@ -324,6 +320,10 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
...
@@ -324,6 +320,10 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
/* turn on MU1 for non-secure OS/Hypervisor */
/* turn on MU1 for non-secure OS/Hypervisor */
sc_pm_set_resource_power_mode
(
ipc_handle
,
SC_R_MU_1A
,
SC_PM_PW_MODE_ON
);
sc_pm_set_resource_power_mode
(
ipc_handle
,
SC_R_MU_1A
,
SC_PM_PW_MODE_ON
);
/* Turn on GPT_0's power & clock for non-secure OS/Hypervisor */
sc_pm_set_resource_power_mode
(
ipc_handle
,
SC_R_GPT_0
,
SC_PM_PW_MODE_ON
);
sc_pm_clock_enable
(
ipc_handle
,
SC_R_GPT_0
,
SC_PM_CLK_PER
,
true
,
0
);
mmio_write_32
(
IMX_GPT_LPCG_BASE
,
mmio_read_32
(
IMX_GPT_LPCG_BASE
)
|
(
1
<<
25
));
/*
/*
* create new partition for non-secure OS/Hypervisor
* create new partition for non-secure OS/Hypervisor
...
...
plat/imx/imx8qm/imx8qm_psci.c
View file @
44b935c0
...
@@ -17,6 +17,8 @@
...
@@ -17,6 +17,8 @@
#include <plat_imx8.h>
#include <plat_imx8.h>
#include <sci/sci.h>
#include <sci/sci.h>
#include "../../common/sci/imx8_mu.h"
#define CORE_PWR_STATE(state) \
#define CORE_PWR_STATE(state) \
((state)->pwr_domain_state[MPIDR_AFFLVL0])
((state)->pwr_domain_state[MPIDR_AFFLVL0])
#define CLUSTER_PWR_STATE(state) \
#define CLUSTER_PWR_STATE(state) \
...
@@ -29,44 +31,70 @@ const static int ap_core_index[PLATFORM_CORE_COUNT] = {
...
@@ -29,44 +31,70 @@ const static int ap_core_index[PLATFORM_CORE_COUNT] = {
SC_R_A53_3
,
SC_R_A72_0
,
SC_R_A72_1
,
SC_R_A53_3
,
SC_R_A72_0
,
SC_R_A72_1
,
};
};
/* save gic dist/redist context when GIC is poewr down */
static
struct
plat_gic_ctx
imx_gicv3_ctx
;
static
unsigned
int
gpt_lpcg
,
gpt_reg
[
2
];
static
void
imx_enable_irqstr_wakeup
(
void
)
{
uint32_t
irq_mask
;
gicv3_dist_ctx_t
*
dist_ctx
=
&
imx_gicv3_ctx
.
dist_ctx
;
/* put IRQSTR into ON mode */
sc_pm_set_resource_power_mode
(
ipc_handle
,
SC_R_IRQSTR_SCU2
,
SC_PM_PW_MODE_ON
);
/* enable the irqsteer to handle wakeup irq */
mmio_write_32
(
IMX_WUP_IRQSTR_BASE
,
0x1
);
for
(
int
i
=
0
;
i
<
15
;
i
++
)
{
irq_mask
=
dist_ctx
->
gicd_isenabler
[
i
];
mmio_write_32
(
IMX_WUP_IRQSTR_BASE
+
0x3c
-
0x4
*
i
,
irq_mask
);
}
/* set IRQSTR low power mode */
if
(
imx_is_wakeup_src_irqsteer
())
sc_pm_set_resource_power_mode
(
ipc_handle
,
SC_R_IRQSTR_SCU2
,
SC_PM_PW_MODE_STBY
);
else
sc_pm_set_resource_power_mode
(
ipc_handle
,
SC_R_IRQSTR_SCU2
,
SC_PM_PW_MODE_OFF
);
}
static
void
imx_disable_irqstr_wakeup
(
void
)
{
/* put IRQSTR into ON from STBY mode */
sc_pm_set_resource_power_mode
(
ipc_handle
,
SC_R_IRQSTR_SCU2
,
SC_PM_PW_MODE_ON
);
/* disable the irqsteer */
mmio_write_32
(
IMX_WUP_IRQSTR_BASE
,
0x0
);
for
(
int
i
=
0
;
i
<
16
;
i
++
)
mmio_write_32
(
IMX_WUP_IRQSTR_BASE
+
0x4
+
0x4
*
i
,
0x0
);
/* put IRQSTR into OFF mode */
sc_pm_set_resource_power_mode
(
ipc_handle
,
SC_R_IRQSTR_SCU2
,
SC_PM_PW_MODE_OFF
);
}
int
imx_pwr_domain_on
(
u_register_t
mpidr
)
int
imx_pwr_domain_on
(
u_register_t
mpidr
)
{
{
int
ret
=
PSCI_E_SUCCESS
;
int
ret
=
PSCI_E_SUCCESS
;
unsigned
int
cluster_id
,
cpu_id
;
unsigned
int
cluster_id
=
MPIDR_AFFLVL1_VAL
(
mpidr
);
unsigned
int
cpu_id
=
MPIDR_AFFLVL0_VAL
(
mpidr
);
cluster_id
=
MPIDR_AFFLVL1_VAL
(
mpidr
);
cpu_id
=
MPIDR_AFFLVL0_VAL
(
mpidr
);
sc_pm_set_resource_power_mode
(
ipc_handle
,
cluster_id
==
0
?
SC_R_A53
:
SC_R_A72
,
SC_PM_PW_MODE_ON
);
printf
(
"imx_pwr_domain_on cluster_id %d, cpu_id %d
\n
"
,
cluster_id
,
cpu_id
);
if
(
cluster_id
==
1
)
if
(
cluster_id
==
0
)
{
sc_pm_req_low_power_mode
(
ipc_handle
,
SC_R_A72
,
SC_PM_PW_MODE_ON
);
sc_pm_set_resource_power_mode
(
ipc_handle
,
SC_R_A53
,
SC_PM_PW_MODE_ON
);
if
(
sc_pm_set_resource_power_mode
(
ipc_handle
,
if
(
sc_pm_set_resource_power_mode
(
ipc_handle
,
ap_core_index
[
cpu_id
],
ap_core_index
[
cpu_id
+
PLATFORM_CLUSTER0_CORE_COUNT
*
cluster_id
],
SC_PM_PW_MODE_ON
)
!=
SC_ERR_NONE
)
{
SC_PM_PW_MODE_ON
)
!=
SC_ERR_NONE
)
{
ERROR
(
"cluster0 core %d power on failed!
\n
"
,
cpu_id
);
ERROR
(
"core %d power on failed!
\n
"
,
cpu_id
+
PLATFORM_CLUSTER0_CORE_COUNT
*
cluster_id
);
ret
=
PSCI_E_INTERN_FAIL
;
ret
=
PSCI_E_INTERN_FAIL
;
}
}
if
(
sc_pm_cpu_start
(
ipc_handle
,
ap_core_index
[
cpu_id
],
if
(
sc_pm_cpu_start
(
ipc_handle
,
true
,
BL31_BASE
)
!=
SC_ERR_NONE
)
{
ap_core_index
[
cpu_id
+
PLATFORM_CLUSTER0_CORE_COUNT
*
cluster_id
],
ERROR
(
"boot cluster0 core %d failed!
\n
"
,
cpu_id
);
true
,
BL31_BASE
)
!=
SC_ERR_NONE
)
{
ret
=
PSCI_E_INTERN_FAIL
;
ERROR
(
"boot core %d failed!
\n
"
,
cpu_id
+
PLATFORM_CLUSTER0_CORE_COUNT
*
cluster_id
);
}
ret
=
PSCI_E_INTERN_FAIL
;
}
else
{
sc_pm_set_resource_power_mode
(
ipc_handle
,
SC_R_A72
,
SC_PM_PW_MODE_ON
);
if
(
sc_pm_set_resource_power_mode
(
ipc_handle
,
ap_core_index
[
cpu_id
+
4
],
SC_PM_PW_MODE_ON
)
!=
SC_ERR_NONE
)
{
ERROR
(
" cluster1 core %d power on failed!
\n
"
,
cpu_id
);
ret
=
PSCI_E_INTERN_FAIL
;
}
if
(
sc_pm_cpu_start
(
ipc_handle
,
ap_core_index
[
cpu_id
+
4
],
true
,
BL31_BASE
)
!=
SC_ERR_NONE
)
{
ERROR
(
"boot cluster1 core %d failed!
\n
"
,
cpu_id
);
ret
=
PSCI_E_INTERN_FAIL
;
}
}
}
return
ret
;
return
ret
;
...
@@ -91,11 +119,14 @@ void imx_pwr_domain_off(const psci_power_state_t *target_state)
...
@@ -91,11 +119,14 @@ void imx_pwr_domain_off(const psci_power_state_t *target_state)
plat_gic_cpuif_disable
();
plat_gic_cpuif_disable
();
sc_pm_req_cpu_low_power_mode
(
ipc_handle
,
sc_pm_req_cpu_low_power_mode
(
ipc_handle
,
ap_core_index
[
cpu_id
+
cluster_id
*
4
],
ap_core_index
[
cpu_id
+
PLATFORM_CLUSTER0_CORE_COUNT
*
cluster_id
],
SC_PM_PW_MODE_OFF
,
SC_PM_PW_MODE_OFF
,
SC_PM_WAKE_SRC_NONE
);
SC_PM_WAKE_SRC_NONE
);
if
(
CLUSTER_PWR_STATE
(
target_state
)
==
PLAT_MAX_OFF_STATE
)
if
(
is_local_state_off
(
CLUSTER_PWR_STATE
(
target_state
)))
{
cci_disable_snoop_dvm_reqs
(
MPIDR_AFFLVL1_VAL
(
mpidr
));
cci_disable_snoop_dvm_reqs
(
cluster_id
);
if
(
cluster_id
==
1
)
sc_pm_req_low_power_mode
(
ipc_handle
,
SC_R_A72
,
SC_PM_PW_MODE_OFF
);
}
printf
(
"turn off cluster:%d core:%d
\n
"
,
cluster_id
,
cpu_id
);
printf
(
"turn off cluster:%d core:%d
\n
"
,
cluster_id
,
cpu_id
);
}
}
...
@@ -105,24 +136,148 @@ void imx_domain_suspend(const psci_power_state_t *target_state)
...
@@ -105,24 +136,148 @@ void imx_domain_suspend(const psci_power_state_t *target_state)
unsigned
int
cluster_id
=
MPIDR_AFFLVL1_VAL
(
mpidr
);
unsigned
int
cluster_id
=
MPIDR_AFFLVL1_VAL
(
mpidr
);
unsigned
int
cpu_id
=
MPIDR_AFFLVL0_VAL
(
mpidr
);
unsigned
int
cpu_id
=
MPIDR_AFFLVL0_VAL
(
mpidr
);
plat_gic_cpuif_disable
();
if
(
is_local_state_off
(
CORE_PWR_STATE
(
target_state
)))
{
plat_gic_cpuif_disable
();
sc_pm_set_cpu_resume
(
ipc_handle
,
ap_core_index
[
cpu_id
+
PLATFORM_CLUSTER0_CORE_COUNT
*
cluster_id
],
true
,
BL31_BASE
);
sc_pm_req_cpu_low_power_mode
(
ipc_handle
,
ap_core_index
[
cpu_id
+
PLATFORM_CLUSTER0_CORE_COUNT
*
cluster_id
],
SC_PM_PW_MODE_OFF
,
SC_PM_WAKE_SRC_GIC
);
}
else
{
dsb
();
write_scr_el3
(
read_scr_el3
()
|
SCR_FIQ_BIT
);
isb
();
}
cci_disable_snoop_dvm_reqs
(
MPIDR_AFFLVL1_VAL
(
mpidr
));
if
(
is_local_state_off
(
CLUSTER_PWR_STATE
(
target_state
)))
{
cci_disable_snoop_dvm_reqs
(
MPIDR_AFFLVL1_VAL
(
mpidr
));
if
(
cluster_id
==
1
)
sc_pm_req_low_power_mode
(
ipc_handle
,
SC_R_A72
,
SC_PM_PW_MODE_OFF
);
}
sc_pm_set_cpu_resume_addr
(
ipc_handle
,
if
(
is_local_state_retn
(
SYSTEM_PWR_STATE
(
target_state
)))
{
ap_core_index
[
cpu_id
+
cluster_id
*
4
],
BL31_BASE
);
plat_gic_cpuif_disable
();
sc_pm_req_cpu_low_power_mode
(
ipc_handle
,
ap_core_index
[
cpu_id
+
cluster_id
*
4
],
/* save gic context */
SC_PM_PW_MODE_OFF
,
SC_PM_WAKE_SRC_GIC
);
plat_gic_save
(
cpu_id
,
&
imx_gicv3_ctx
);
/* enable the irqsteer for wakeup */
imx_enable_irqstr_wakeup
();
cci_disable_snoop_dvm_reqs
(
MPIDR_AFFLVL1_VAL
(
mpidr
));
/* Put GIC in LP mode. */
sc_pm_set_resource_power_mode
(
ipc_handle
,
SC_R_GIC
,
SC_PM_PW_MODE_OFF
);
/* Save GPT clock and registers, then turn off its power */
gpt_lpcg
=
mmio_read_32
(
IMX_GPT_LPCG_BASE
);
gpt_reg
[
0
]
=
mmio_read_32
(
IMX_GPT_BASE
);
gpt_reg
[
1
]
=
mmio_read_32
(
IMX_GPT_BASE
+
0x4
);
sc_pm_set_resource_power_mode
(
ipc_handle
,
SC_R_GPT_0
,
SC_PM_PW_MODE_OFF
);
sc_pm_req_low_power_mode
(
ipc_handle
,
SC_R_A53
,
SC_PM_PW_MODE_OFF
);
sc_pm_req_low_power_mode
(
ipc_handle
,
SC_R_A72
,
SC_PM_PW_MODE_OFF
);
sc_pm_req_low_power_mode
(
ipc_handle
,
SC_R_CCI
,
SC_PM_PW_MODE_OFF
);
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A53
,
SC_PM_SYS_IF_DDR
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_OFF
);
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A72
,
SC_PM_SYS_IF_DDR
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_OFF
);
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A53
,
SC_PM_SYS_IF_MU
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_OFF
);
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A72
,
SC_PM_SYS_IF_MU
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_OFF
);
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A53
,
SC_PM_SYS_IF_INTERCONNECT
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_OFF
);
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A72
,
SC_PM_SYS_IF_INTERCONNECT
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_OFF
);
sc_pm_req_low_power_mode
(
ipc_handle
,
SC_R_CCI
,
SC_PM_PW_MODE_OFF
);
sc_pm_set_cpu_resume
(
ipc_handle
,
ap_core_index
[
cpu_id
+
PLATFORM_CLUSTER0_CORE_COUNT
*
cluster_id
],
true
,
BL31_BASE
);
if
(
imx_is_wakeup_src_irqsteer
())
sc_pm_req_cpu_low_power_mode
(
ipc_handle
,
ap_core_index
[
cpu_id
+
PLATFORM_CLUSTER0_CORE_COUNT
*
cluster_id
],
SC_PM_PW_MODE_OFF
,
SC_PM_WAKE_SRC_IRQSTEER
);
else
sc_pm_req_cpu_low_power_mode
(
ipc_handle
,
ap_core_index
[
cpu_id
+
PLATFORM_CLUSTER0_CORE_COUNT
*
cluster_id
],
SC_PM_PW_MODE_OFF
,
SC_PM_WAKE_SRC_SCU
);
}
}
}
void
imx_domain_suspend_finish
(
const
psci_power_state_t
*
target_state
)
void
imx_domain_suspend_finish
(
const
psci_power_state_t
*
target_state
)
{
{
u_register_t
mpidr
=
read_mpidr_el1
();
u_register_t
mpidr
=
read_mpidr_el1
();
unsigned
int
cluster_id
=
MPIDR_AFFLVL1_VAL
(
mpidr
);
unsigned
int
cpu_id
=
MPIDR_AFFLVL0_VAL
(
mpidr
);
cci_enable_snoop_dvm_reqs
(
MPIDR_AFFLVL1_VAL
(
mpidr
));
/* check the system level status */
if
(
is_local_state_retn
(
SYSTEM_PWR_STATE
(
target_state
)))
{
MU_Resume
(
SC_IPC_BASE
);
plat_gic_cpuif_enable
();
sc_pm_req_cpu_low_power_mode
(
ipc_handle
,
ap_core_index
[
cpu_id
+
PLATFORM_CLUSTER0_CORE_COUNT
*
cluster_id
],
SC_PM_PW_MODE_ON
,
SC_PM_WAKE_SRC_GIC
);
/* Put GIC/IRQSTR back to high power mode. */
sc_pm_set_resource_power_mode
(
ipc_handle
,
SC_R_GIC
,
SC_PM_PW_MODE_ON
);
/* Turn GPT power and restore its clock and registers */
sc_pm_set_resource_power_mode
(
ipc_handle
,
SC_R_GPT_0
,
SC_PM_PW_MODE_ON
);
sc_pm_clock_enable
(
ipc_handle
,
SC_R_GPT_0
,
SC_PM_CLK_PER
,
true
,
0
);
mmio_write_32
(
IMX_GPT_BASE
,
gpt_reg
[
0
]);
mmio_write_32
(
IMX_GPT_BASE
+
0x4
,
gpt_reg
[
1
]);
mmio_write_32
(
IMX_GPT_LPCG_BASE
,
gpt_lpcg
);
sc_pm_req_low_power_mode
(
ipc_handle
,
SC_R_A53
,
SC_PM_PW_MODE_ON
);
sc_pm_req_low_power_mode
(
ipc_handle
,
SC_R_A72
,
SC_PM_PW_MODE_ON
);
sc_pm_req_low_power_mode
(
ipc_handle
,
SC_R_CCI
,
SC_PM_PW_MODE_ON
);
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A53
,
SC_PM_SYS_IF_DDR
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_ON
);
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A72
,
SC_PM_SYS_IF_DDR
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_ON
);
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A53
,
SC_PM_SYS_IF_MU
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_ON
);
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A72
,
SC_PM_SYS_IF_MU
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_ON
);
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A53
,
SC_PM_SYS_IF_INTERCONNECT
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_ON
);
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A72
,
SC_PM_SYS_IF_INTERCONNECT
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_ON
);
sc_pm_req_low_power_mode
(
ipc_handle
,
SC_R_CCI
,
SC_PM_PW_MODE_ON
);
cci_enable_snoop_dvm_reqs
(
MPIDR_AFFLVL1_VAL
(
mpidr
));
/* restore gic context */
plat_gic_restore
(
cpu_id
,
&
imx_gicv3_ctx
);
/* disable the irqsteer wakeup */
imx_disable_irqstr_wakeup
();
plat_gic_cpuif_enable
();
}
/* check the cluster level power status */
if
(
is_local_state_off
(
CLUSTER_PWR_STATE
(
target_state
)))
{
cci_enable_snoop_dvm_reqs
(
MPIDR_AFFLVL1_VAL
(
mpidr
));
if
(
cluster_id
==
1
)
sc_pm_req_low_power_mode
(
ipc_handle
,
SC_R_A72
,
SC_PM_PW_MODE_ON
);
}
/* check the core level power status */
if
(
is_local_state_off
(
CORE_PWR_STATE
(
target_state
)))
{
sc_pm_set_cpu_resume
(
ipc_handle
,
ap_core_index
[
cpu_id
+
PLATFORM_CLUSTER0_CORE_COUNT
*
cluster_id
],
false
,
BL31_BASE
);
sc_pm_req_cpu_low_power_mode
(
ipc_handle
,
ap_core_index
[
cpu_id
+
PLATFORM_CLUSTER0_CORE_COUNT
*
cluster_id
],
SC_PM_PW_MODE_ON
,
SC_PM_WAKE_SRC_GIC
);
plat_gic_cpuif_enable
();
}
else
{
write_scr_el3
(
read_scr_el3
()
&
(
~
SCR_FIQ_BIT
));
isb
();
}
}
}
int
imx_validate_ns_entrypoint
(
uintptr_t
ns_entrypoint
)
int
imx_validate_ns_entrypoint
(
uintptr_t
ns_entrypoint
)
...
@@ -149,26 +304,23 @@ int plat_setup_psci_ops(uintptr_t sec_entrypoint,
...
@@ -149,26 +304,23 @@ int plat_setup_psci_ops(uintptr_t sec_entrypoint,
imx_mailbox_init
(
sec_entrypoint
);
imx_mailbox_init
(
sec_entrypoint
);
*
psci_ops
=
&
imx_plat_psci_ops
;
*
psci_ops
=
&
imx_plat_psci_ops
;
/* Request low power mode for cluster/cci, only need to do once */
/* make sure system sources power ON in low power mode by default */
sc_pm_req_low_power_mode
(
ipc_handle
,
SC_R_A72
,
SC_PM_PW_MODE_OFF
);
sc_pm_req_low_power_mode
(
ipc_handle
,
SC_R_A53
,
SC_PM_PW_MODE_ON
);
sc_pm_req_low_power_mode
(
ipc_handle
,
SC_R_A53
,
SC_PM_PW_MODE_OFF
);
sc_pm_req_low_power_mode
(
ipc_handle
,
SC_R_A72
,
SC_PM_PW_MODE_ON
);
sc_pm_req_low_power_mode
(
ipc_handle
,
SC_R_CCI
,
SC_PM_PW_MODE_OFF
);
sc_pm_req_low_power_mode
(
ipc_handle
,
SC_R_CCI
,
SC_PM_PW_MODE_ON
);
/* Request RUN and LP modes for DDR, system interconnect etc. */
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A53
,
SC_PM_SYS_IF_DDR
,
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A53
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_ON
);
SC_PM_SYS_IF_DDR
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_STBY
);
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A72
,
SC_PM_SYS_IF_DDR
,
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A72
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_ON
);
SC_PM_SYS_IF_DDR
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_STBY
);
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A53
,
SC_PM_SYS_IF_MU
,
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A53
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_ON
);
SC_PM_SYS_IF_MU
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_STBY
);
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A72
,
SC_PM_SYS_IF_MU
,
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A72
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_ON
);
SC_PM_SYS_IF_MU
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_STBY
);
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A53
,
SC_PM_SYS_IF_INTERCONNECT
,
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A53
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_ON
);
SC_PM_SYS_IF_INTERCONNECT
,
SC_PM_PW_MODE_ON
,
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A72
,
SC_PM_SYS_IF_INTERCONNECT
,
SC_PM_PW_MODE_STBY
);
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_ON
);
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A72
,
SC_PM_SYS_IF_INTERCONNECT
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_STBY
);
return
0
;
return
0
;
}
}
plat/imx/imx8qm/include/platform_def.h
View file @
44b935c0
...
@@ -36,22 +36,22 @@
...
@@ -36,22 +36,22 @@
#define BL31_LIMIT 0x80020000
#define BL31_LIMIT 0x80020000
#define PLAT_GICD_BASE 0x51a00000
#define PLAT_GICD_BASE 0x51a00000
#define PLAT_GICD_SIZE 0x10000
#define PLAT_GICR_BASE 0x51b00000
#define PLAT_GICR_BASE 0x51b00000
#define PLAT_GICR_SIZE 0xc0000
#define PLAT_CCI_BASE 0x52090000
#define PLAT_CCI_BASE 0x52090000
#define PLAT_CCI_SIZE 0x10000
#define CLUSTER0_CCI_SLVAE_IFACE 3
#define CLUSTER0_CCI_SLVAE_IFACE 3
#define CLUSTER1_CCI_SLVAE_IFACE 4
#define CLUSTER1_CCI_SLVAE_IFACE 4
#define IMX_BOOT_UART_BASE 0x5a060000
#define IMX_BOOT_UART_BASE 0x5a060000
#define IMX_BOOT_UART_SIZE 0x1000
#define IMX_BOOT_UART_BAUDRATE 115200
#define IMX_BOOT_UART_BAUDRATE 115200
#define IMX_BOOT_UART_CLK_IN_HZ 24000000
#define IMX_BOOT_UART_CLK_IN_HZ 24000000
#define PLAT_CRASH_UART_BASE IMX_BOOT_UART_BASE
#define PLAT_CRASH_UART_BASE IMX_BOOT_UART_BASE
#define PLAT__CRASH_UART_CLK_IN_HZ 24000000
#define PLAT__CRASH_UART_CLK_IN_HZ 24000000
#define IMX_CONSOLE_BAUDRATE 115200
#define IMX_CONSOLE_BAUDRATE 115200
#define SC_IPC_BASE 0x5d1b0000
#define SC_IPC_BASE 0x5d1b0000
#define SC_IPC_SIZE 0x10000
#define IMX_GPT_LPCG_BASE 0x5d540000
#define IMX_GPT_BASE 0x5d140000
#define IMX_WUP_IRQSTR_BASE 0x51090000
#define IMX_REG_BASE 0x50000000
#define IMX_REG_SIZE 0x10000000
#define COUNTER_FREQUENCY 8000000
/* 8MHz */
#define COUNTER_FREQUENCY 8000000
/* 8MHz */
...
...
plat/imx/imx8qm/include/sec_rsrc.h
View file @
44b935c0
...
@@ -19,12 +19,14 @@ sc_rsrc_t secure_rsrcs[] = {
...
@@ -19,12 +19,14 @@ sc_rsrc_t secure_rsrcs[] = {
SC_R_GIC_SMMU
,
SC_R_GIC_SMMU
,
SC_R_CCI
,
SC_R_CCI
,
SC_R_SYSTEM
,
SC_R_SYSTEM
,
SC_R_IRQSTR_SCU2
SC_R_IRQSTR_SCU2
,
SC_R_GPT_0
};
};
/* resources that have register access for non-secure domain */
/* resources that have register access for non-secure domain */
sc_rsrc_t
ns_access_allowed
[]
=
{
sc_rsrc_t
ns_access_allowed
[]
=
{
SC_R_GIC
,
SC_R_GIC
,
SC_R_GIC_SMMU
,
SC_R_GIC_SMMU
,
SC_R_CCI
SC_R_CCI
,
SC_R_GPT_0
};
};
plat/imx/imx8qx/imx8qx_bl31_setup.c
View file @
44b935c0
...
@@ -44,10 +44,7 @@ static entry_point_info_t bl33_image_ep_info;
...
@@ -44,10 +44,7 @@ static entry_point_info_t bl33_image_ep_info;
(SC_PAD_28FDSOI_PS_PD << PADRING_PULL_SHIFT))
(SC_PAD_28FDSOI_PS_PD << PADRING_PULL_SHIFT))
static
const
mmap_region_t
imx_mmap
[]
=
{
static
const
mmap_region_t
imx_mmap
[]
=
{
MAP_REGION_FLAT
(
IMX_BOOT_UART_BASE
,
IMX_BOOT_UART_SIZE
,
MT_DEVICE
|
MT_RW
),
MAP_REGION_FLAT
(
IMX_REG_BASE
,
IMX_REG_SIZE
,
MT_DEVICE
|
MT_RW
),
MAP_REGION_FLAT
(
SC_IPC_BASE
,
SC_IPC_SIZE
,
MT_DEVICE
|
MT_RW
),
MAP_REGION_FLAT
(
PLAT_GICD_BASE
,
PLAT_GICD_SIZE
,
MT_DEVICE
|
MT_RW
),
MAP_REGION_FLAT
(
PLAT_GICR_BASE
,
PLAT_GICR_SIZE
,
MT_DEVICE
|
MT_RW
),
{
0
}
{
0
}
};
};
...
@@ -281,6 +278,11 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
...
@@ -281,6 +278,11 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
/* Turn on MU1 for non-secure OS/Hypervisor */
/* Turn on MU1 for non-secure OS/Hypervisor */
sc_pm_set_resource_power_mode
(
ipc_handle
,
SC_R_MU_1A
,
SC_PM_PW_MODE_ON
);
sc_pm_set_resource_power_mode
(
ipc_handle
,
SC_R_MU_1A
,
SC_PM_PW_MODE_ON
);
/* Turn on GPT_0's power & clock for non-secure OS/Hypervisor */
sc_pm_set_resource_power_mode
(
ipc_handle
,
SC_R_GPT_0
,
SC_PM_PW_MODE_ON
);
sc_pm_clock_enable
(
ipc_handle
,
SC_R_GPT_0
,
SC_PM_CLK_PER
,
true
,
0
);
mmio_write_32
(
IMX_GPT0_LPCG_BASE
,
mmio_read_32
(
IMX_GPT0_LPCG_BASE
)
|
(
1
<<
25
));
/*
/*
* create new partition for non-secure OS/Hypervisor
* create new partition for non-secure OS/Hypervisor
* uses global structs defined in sec_rsrc.h
* uses global structs defined in sec_rsrc.h
...
...
plat/imx/imx8qx/imx8qx_psci.c
View file @
44b935c0
...
@@ -16,10 +16,52 @@
...
@@ -16,10 +16,52 @@
#include <plat_imx8.h>
#include <plat_imx8.h>
#include <sci/sci.h>
#include <sci/sci.h>
#include "../../common/sci/imx8_mu.h"
const
static
int
ap_core_index
[
PLATFORM_CORE_COUNT
]
=
{
const
static
int
ap_core_index
[
PLATFORM_CORE_COUNT
]
=
{
SC_R_A35_0
,
SC_R_A35_1
,
SC_R_A35_2
,
SC_R_A35_3
SC_R_A35_0
,
SC_R_A35_1
,
SC_R_A35_2
,
SC_R_A35_3
};
};
/* save gic dist/redist context when GIC is power down */
static
struct
plat_gic_ctx
imx_gicv3_ctx
;
static
unsigned
int
gpt_lpcg
,
gpt_reg
[
2
];
static
void
imx_enable_irqstr_wakeup
(
void
)
{
uint32_t
irq_mask
;
gicv3_dist_ctx_t
*
dist_ctx
=
&
imx_gicv3_ctx
.
dist_ctx
;
/* put IRQSTR into ON mode */
sc_pm_set_resource_power_mode
(
ipc_handle
,
SC_R_IRQSTR_SCU2
,
SC_PM_PW_MODE_ON
);
/* enable the irqsteer to handle wakeup irq */
mmio_write_32
(
IMX_WUP_IRQSTR_BASE
,
0x1
);
for
(
int
i
=
0
;
i
<
15
;
i
++
)
{
irq_mask
=
dist_ctx
->
gicd_isenabler
[
i
];
mmio_write_32
(
IMX_WUP_IRQSTR_BASE
+
0x3c
-
0x4
*
i
,
irq_mask
);
}
/* set IRQSTR low power mode */
if
(
imx_is_wakeup_src_irqsteer
())
sc_pm_set_resource_power_mode
(
ipc_handle
,
SC_R_IRQSTR_SCU2
,
SC_PM_PW_MODE_STBY
);
else
sc_pm_set_resource_power_mode
(
ipc_handle
,
SC_R_IRQSTR_SCU2
,
SC_PM_PW_MODE_OFF
);
}
static
void
imx_disable_irqstr_wakeup
(
void
)
{
/* Put IRQSTEER back to ON mode */
sc_pm_set_resource_power_mode
(
ipc_handle
,
SC_R_IRQSTR_SCU2
,
SC_PM_PW_MODE_ON
);
/* disable the irqsteer */
mmio_write_32
(
IMX_WUP_IRQSTR_BASE
,
0x0
);
for
(
int
i
=
0
;
i
<
16
;
i
++
)
mmio_write_32
(
IMX_WUP_IRQSTR_BASE
+
0x4
+
0x4
*
i
,
0x0
);
/* Put IRQSTEER into OFF mode */
sc_pm_set_resource_power_mode
(
ipc_handle
,
SC_R_IRQSTR_SCU2
,
SC_PM_PW_MODE_OFF
);
}
int
imx_pwr_domain_on
(
u_register_t
mpidr
)
int
imx_pwr_domain_on
(
u_register_t
mpidr
)
{
{
int
ret
=
PSCI_E_SUCCESS
;
int
ret
=
PSCI_E_SUCCESS
;
...
@@ -71,11 +113,52 @@ void imx_domain_suspend(const psci_power_state_t *target_state)
...
@@ -71,11 +113,52 @@ void imx_domain_suspend(const psci_power_state_t *target_state)
u_register_t
mpidr
=
read_mpidr_el1
();
u_register_t
mpidr
=
read_mpidr_el1
();
unsigned
int
cpu_id
=
MPIDR_AFFLVL0_VAL
(
mpidr
);
unsigned
int
cpu_id
=
MPIDR_AFFLVL0_VAL
(
mpidr
);
plat_gic_cpuif_disable
();
if
(
is_local_state_off
(
target_state
->
pwr_domain_state
[
MPIDR_AFFLVL0
]))
{
plat_gic_cpuif_disable
();
sc_pm_set_cpu_resume
(
ipc_handle
,
ap_core_index
[
cpu_id
],
true
,
BL31_BASE
);
sc_pm_req_cpu_low_power_mode
(
ipc_handle
,
ap_core_index
[
cpu_id
],
SC_PM_PW_MODE_OFF
,
SC_PM_WAKE_SRC_GIC
);
}
else
{
dsb
();
write_scr_el3
(
read_scr_el3
()
|
SCR_FIQ_BIT
);
isb
();
}
sc_pm_set_cpu_resume_addr
(
ipc_handle
,
ap_core_index
[
cpu_id
],
BL31_BASE
);
if
(
is_local_state_off
(
target_state
->
pwr_domain_state
[
MPIDR_AFFLVL1
]))
sc_pm_req_cpu_low_power_mode
(
ipc_handle
,
ap_core_index
[
cpu_id
],
sc_pm_req_low_power_mode
(
ipc_handle
,
SC_R_A35
,
SC_PM_PW_MODE_OFF
);
SC_PM_PW_MODE_OFF
,
SC_PM_WAKE_SRC_GIC
);
if
(
is_local_state_retn
(
target_state
->
pwr_domain_state
[
PLAT_MAX_PWR_LVL
]))
{
plat_gic_cpuif_disable
();
/* save gic context */
plat_gic_save
(
cpu_id
,
&
imx_gicv3_ctx
);
/* enable the irqsteer for wakeup */
imx_enable_irqstr_wakeup
();
/* Save GPT clock and registers, then turn off its power */
gpt_lpcg
=
mmio_read_32
(
IMX_GPT0_LPCG_BASE
);
gpt_reg
[
0
]
=
mmio_read_32
(
IMX_GPT0_BASE
);
gpt_reg
[
1
]
=
mmio_read_32
(
IMX_GPT0_BASE
+
0x4
);
sc_pm_set_resource_power_mode
(
ipc_handle
,
SC_R_GPT_0
,
SC_PM_PW_MODE_OFF
);
sc_pm_req_low_power_mode
(
ipc_handle
,
SC_R_A35
,
SC_PM_PW_MODE_OFF
);
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A35
,
SC_PM_SYS_IF_DDR
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_OFF
);
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A35
,
SC_PM_SYS_IF_MU
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_OFF
);
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A35
,
SC_PM_SYS_IF_INTERCONNECT
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_OFF
);
/* Put GIC in OFF mode. */
sc_pm_set_resource_power_mode
(
ipc_handle
,
SC_R_GIC
,
SC_PM_PW_MODE_OFF
);
sc_pm_set_cpu_resume
(
ipc_handle
,
ap_core_index
[
cpu_id
],
true
,
BL31_BASE
);
if
(
imx_is_wakeup_src_irqsteer
())
sc_pm_req_cpu_low_power_mode
(
ipc_handle
,
ap_core_index
[
cpu_id
],
SC_PM_PW_MODE_OFF
,
SC_PM_WAKE_SRC_IRQSTEER
);
else
sc_pm_req_cpu_low_power_mode
(
ipc_handle
,
ap_core_index
[
cpu_id
],
SC_PM_PW_MODE_OFF
,
SC_PM_WAKE_SRC_SCU
);
}
}
}
void
imx_domain_suspend_finish
(
const
psci_power_state_t
*
target_state
)
void
imx_domain_suspend_finish
(
const
psci_power_state_t
*
target_state
)
...
@@ -83,10 +166,51 @@ void imx_domain_suspend_finish(const psci_power_state_t *target_state)
...
@@ -83,10 +166,51 @@ void imx_domain_suspend_finish(const psci_power_state_t *target_state)
u_register_t
mpidr
=
read_mpidr_el1
();
u_register_t
mpidr
=
read_mpidr_el1
();
unsigned
int
cpu_id
=
MPIDR_AFFLVL0_VAL
(
mpidr
);
unsigned
int
cpu_id
=
MPIDR_AFFLVL0_VAL
(
mpidr
);
sc_pm_req_low_power_mode
(
ipc_handle
,
ap_core_index
[
cpu_id
],
if
(
is_local_state_retn
(
target_state
->
pwr_domain_state
[
PLAT_MAX_PWR_LVL
]))
{
SC_PM_PW_MODE_ON
);
MU_Resume
(
SC_IPC_BASE
);
plat_gic_cpuif_enable
();
sc_pm_req_low_power_mode
(
ipc_handle
,
ap_core_index
[
cpu_id
],
SC_PM_PW_MODE_ON
);
sc_pm_req_cpu_low_power_mode
(
ipc_handle
,
ap_core_index
[
cpu_id
],
SC_PM_PW_MODE_ON
,
SC_PM_WAKE_SRC_GIC
);
/* Put GIC back to high power mode. */
sc_pm_set_resource_power_mode
(
ipc_handle
,
SC_R_GIC
,
SC_PM_PW_MODE_ON
);
/* restore gic context */
plat_gic_restore
(
cpu_id
,
&
imx_gicv3_ctx
);
/* Turn on GPT power and restore its clock and registers */
sc_pm_set_resource_power_mode
(
ipc_handle
,
SC_R_GPT_0
,
SC_PM_PW_MODE_ON
);
sc_pm_clock_enable
(
ipc_handle
,
SC_R_GPT_0
,
SC_PM_CLK_PER
,
true
,
0
);
mmio_write_32
(
IMX_GPT0_BASE
,
gpt_reg
[
0
]);
mmio_write_32
(
IMX_GPT0_BASE
+
0x4
,
gpt_reg
[
1
]);
mmio_write_32
(
IMX_GPT0_LPCG_BASE
,
gpt_lpcg
);
sc_pm_req_low_power_mode
(
ipc_handle
,
SC_R_A35
,
SC_PM_PW_MODE_ON
);
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A35
,
SC_PM_SYS_IF_DDR
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_ON
);
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A35
,
SC_PM_SYS_IF_MU
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_ON
);
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A35
,
SC_PM_SYS_IF_INTERCONNECT
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_ON
);
/* disable the irqsteer wakeup */
imx_disable_irqstr_wakeup
();
plat_gic_cpuif_enable
();
}
if
(
is_local_state_off
(
target_state
->
pwr_domain_state
[
MPIDR_AFFLVL1
]))
sc_pm_req_low_power_mode
(
ipc_handle
,
SC_R_A35
,
SC_PM_PW_MODE_ON
);
if
(
is_local_state_off
(
target_state
->
pwr_domain_state
[
MPIDR_AFFLVL0
]))
{
sc_pm_req_cpu_low_power_mode
(
ipc_handle
,
ap_core_index
[
cpu_id
],
SC_PM_PW_MODE_ON
,
SC_PM_WAKE_SRC_GIC
);
plat_gic_cpuif_enable
();
}
else
{
write_scr_el3
(
read_scr_el3
()
&
(
~
SCR_FIQ_BIT
));
isb
();
}
}
}
static
const
plat_psci_ops_t
imx_plat_psci_ops
=
{
static
const
plat_psci_ops_t
imx_plat_psci_ops
=
{
...
@@ -108,17 +232,15 @@ int plat_setup_psci_ops(uintptr_t sec_entrypoint,
...
@@ -108,17 +232,15 @@ int plat_setup_psci_ops(uintptr_t sec_entrypoint,
imx_mailbox_init
(
sec_entrypoint
);
imx_mailbox_init
(
sec_entrypoint
);
*
psci_ops
=
&
imx_plat_psci_ops
;
*
psci_ops
=
&
imx_plat_psci_ops
;
/* Request low power mode for A35 cluster, only need to do once */
/* make sure system sources power ON in low power mode by default */
sc_pm_req_low_power_mode
(
ipc_handle
,
SC_R_A35
,
SC_PM_PW_MODE_OFF
);
sc_pm_req_low_power_mode
(
ipc_handle
,
SC_R_A35
,
SC_PM_PW_MODE_ON
);
/* Request RUN and LP modes for DDR, system interconnect etc. */
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A35
,
SC_PM_SYS_IF_DDR
,
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A35
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_ON
);
SC_PM_SYS_IF_DDR
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_STBY
);
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A35
,
SC_PM_SYS_IF_MU
,
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A35
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_ON
);
SC_PM_SYS_IF_MU
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_STBY
);
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A35
,
SC_PM_SYS_IF_INTERCONNECT
,
sc_pm_req_sys_if_power_mode
(
ipc_handle
,
SC_R_A35
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_ON
);
SC_PM_SYS_IF_INTERCONNECT
,
SC_PM_PW_MODE_ON
,
SC_PM_PW_MODE_STBY
);
return
0
;
return
0
;
}
}
plat/imx/imx8qx/include/platform_def.h
View file @
44b935c0
...
@@ -37,18 +37,19 @@
...
@@ -37,18 +37,19 @@
#define MAX_MMAP_REGIONS 8
#define MAX_MMAP_REGIONS 8
#define PLAT_GICD_BASE 0x51a00000
#define PLAT_GICD_BASE 0x51a00000
#define PLAT_GICD_SIZE 0x10000
#define PLAT_GICR_BASE 0x51b00000
#define PLAT_GICR_BASE 0x51b00000
#define PLAT_GICR_SIZE 0xc0000
#define IMX_BOOT_UART_BASE 0x5a060000
#define IMX_BOOT_UART_BASE 0x5a060000
#define IMX_BOOT_UART_SIZE 0x1000
#define IMX_BOOT_UART_BAUDRATE 115200
#define IMX_BOOT_UART_BAUDRATE 115200
#define IMX_BOOT_UART_CLK_IN_HZ 24000000
#define IMX_BOOT_UART_CLK_IN_HZ 24000000
#define PLAT_CRASH_UART_BASE IMX_BOOT_UART_BASE
#define PLAT_CRASH_UART_BASE IMX_BOOT_UART_BASE
#define PLAT__CRASH_UART_CLK_IN_HZ 24000000
#define PLAT__CRASH_UART_CLK_IN_HZ 24000000
#define IMX_CONSOLE_BAUDRATE 115200
#define IMX_CONSOLE_BAUDRATE 115200
#define SC_IPC_BASE 0x5d1b0000
#define SC_IPC_BASE 0x5d1b0000
#define SC_IPC_SIZE 0x10000
#define IMX_GPT0_LPCG_BASE 0x5d540000
#define IMX_GPT0_BASE 0x5d140000
#define IMX_WUP_IRQSTR_BASE 0x51090000
#define IMX_REG_BASE 0x50000000
#define IMX_REG_SIZE 0x10000000
#define COUNTER_FREQUENCY 8000000
#define COUNTER_FREQUENCY 8000000
...
...
plat/imx/imx8qx/include/sec_rsrc.h
View file @
44b935c0
...
@@ -14,10 +14,12 @@ sc_rsrc_t secure_rsrcs[] = {
...
@@ -14,10 +14,12 @@ sc_rsrc_t secure_rsrcs[] = {
SC_R_A35_3
,
SC_R_A35_3
,
SC_R_GIC
,
SC_R_GIC
,
SC_R_SYSTEM
,
SC_R_SYSTEM
,
SC_R_IRQSTR_SCU2
SC_R_IRQSTR_SCU2
,
SC_R_GPT_0
};
};
/* resources that have register access for non-secure domain */
/* resources that have register access for non-secure domain */
sc_rsrc_t
ns_access_allowed
[]
=
{
sc_rsrc_t
ns_access_allowed
[]
=
{
SC_R_GIC
,
SC_R_GIC
,
SC_R_GPT_0
};
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment