Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

plat-imx: psci: implement clock-gated cluster idle state #2

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions core/arch/arm/include/sm/psci.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@
#define PSCI_POWER_STATE_TYPE_STANDBY 0
#define PSCI_POWER_STATE_TYPE_POWER_DOWN 1

/* extended StateID format */
#define PSCI_EXT_POWER_STATE_TYPE_POWER_DOWN BIT(30)
#define PSCI_EXT_POWER_STATE_ID_MASK 0x0fffffff

#define PSCI_OS_INITIATED BIT(0)
#define PSCI_EXTENDED_STATE_ID BIT(1)

#define PSCI_RET_SUCCESS (0)
#define PSCI_RET_NOT_SUPPORTED (-1)
#define PSCI_RET_INVALID_PARAMETERS (-2)
Expand Down
131 changes: 131 additions & 0 deletions core/arch/arm/plat-imx/imx-regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,52 @@
#error "CFG_MX6/7 not defined"
#endif

/* SNVS */
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these definitions can be removed

#define SNVS_HPLR 0x00000000
#define SNVS_HPCOMR 0x00000004
#define SNVS_HPCR 0x00000008
#define SNVS_HPSICR 0x0000000C
#define SNVS_HPSVCR 0x00000010
#define SNVS_HPSR 0x00000014
#define SNVS_HPSVSR 0x00000018
#define SNVS_HPHACIVR 0x0000001C
#define SNVS_HPHACR 0x00000020
#define SNVS_HPRTCMR 0x00000024
#define SNVS_HPRTCLR 0x00000028
#define SNVS_HPTAMR 0x0000002C
#define SNVS_HPTALR 0x00000030
#define SNVS_LPLR 0x00000034
#define SNVS_LPCR 0x00000038
#define SNVS_LPMKCR 0x0000003C
#define SNVS_LPSVCR 0x00000040
#define SNVS_LPTGFCR 0x00000044
#define SNVS_LPTDCR 0x00000048
#define SNVS_LPSR 0x0000004C
#define SNVS_LPSRTCMR 0x00000050
#define SNVS_LPSRTCLR 0x00000054
#define SNVS_LPTAR 0x00000058
#define SNVS_LPSMCMR 0x0000005C
#define SNVS_LPSMCLR 0x00000060
#define SNVS_LPPGDR 0x00000064
#define SNVS_LPGPR 0x00000068
#define SNVS_LPZMK 0x0000006C
#define SNVS_HPVIDR1 0x00000BF8
#define SNVS_HPVIDR2 0x00000BFC

#define SNVS_LPPGDR_INIT 0x41736166

#define SNVS_LPCR_DP_EN (1u << 5)
#define SNVS_LPCR_TOP (1u << 6)

#define SNVS_LPSR_PGD (1u << 3)

#define IOMUXC_GPR1_OFFSET 0x04
#define IOMUXC_GPR4_OFFSET 0x10
#define IOMUXC_GPR5_OFFSET 0x14

#define IOMUXC_GPR1_IRQ BIT(12)
#define GPR_IRQ 32

#define ARM_WFI_STAT_MASK(n) BIT(n)

#define ARM_WFI_STAT_MASK_7D(n) BIT(25 + ((n) & 1))
Expand All @@ -215,6 +259,7 @@
#define SRC_SCR_CPU_ENABLE_ALL SHIFT_U32(0x7, 22)

#define SRC_GPR1_MX7 0x074
#define SRC_GPR2_MX7 0x078
#define SRC_A7RCR0 0x004
#define SRC_A7RCR1 0x008
#define SRC_A7RCR0_A7_CORE_RESET0_OFFSET 0
Expand All @@ -232,14 +277,100 @@
#define OFFSET_DIGPROG_IMX7D 0x800

/* GPC V2 */
#define GPC_PGC_C0 0x800
#define GPC_PGC_C0_PUPSCR 0x804
#define GPC_PGC_C1 0x840
#define GPC_PGC_C1_PUPSCR 0x844
#define GPC_PGC_SCU 0x880

#define GPC_PGC_PCG_MASK BIT(0)
#define GPC_PGC_CORE_PUPSCR 0x7fff80

#define GPC_CPU_PGC_SW_PUP_REQ 0xf0
#define GPC_PU_PGC_SW_PUP_REQ 0xf8
#define GPC_CPU_PGC_SW_PDN_REQ 0xfc
#define GPC_PU_PGC_SW_PDN_REQ 0x104
#define GPC_PGC_SW_PDN_PUP_REQ_CORE1_MASK BIT(1)

#define GPC_LPCR_A7_BSC 0
#define GPC_LPCR_A7_AD 0x4
#define GPC_LPCR_M4 0x8
#define GPC_SLPCR 0x14
#define GPC_MLPCR 0x20
#define GPC_PGC_ACK_SEL_A7 0x24
#define GPC_PGC_ACK_SEL_M4 0x28
#define GPC_MISC 0x2C
#define GPC_IMR1_CORE0_A7 0x30
#define GPC_IMR2_CORE0_A7 0x34
#define GPC_IMR3_CORE0_A7 0x38
#define GPC_IMR4_CORE0_A7 0x3C
#define GPC_IMR1_CORE1_A7 0x40
#define GPC_IMR2_CORE1_A7 0x44
#define GPC_IMR3_CORE1_A7 0x48
#define GPC_IMR4_CORE1_A7 0x4C
#define GPC_ISR1_A7 0x70
#define GPC_ISR2_A7 0x74
#define GPC_ISR3_A7 0x78
#define GPC_ISR4_A7 0x7C
#define GPC_SLT0_CFG 0xB0
#define GPC_SLT1_CFG 0xB4
#define GPC_SLT2_CFG 0xB8
#define GPC_SLT3_CFG 0xBC
#define GPC_SLT4_CFG 0xC0
#define GPC_SLT5_CFG 0xC4
#define GPC_SLT6_CFG 0xC8
#define GPC_SLT7_CFG 0xCC
#define GPC_SLT8_CFG 0xD0
#define GPC_SLT9_CFG 0xD4
#define GPC_PGC_CPU_MAPPING 0xEC
#define GPC_PGC_SCU_AUXSW 0x890

#define GPC_LPCR_A7_BSC_LPM0 SHIFT_U32(0x3, 0)
#define GPC_LPCR_A7_BSC_LPM1 SHIFT_U32(0x3, 2)
#define GPC_LPCR_A7_BSC_CPU_CLK_ON_LPM BIT(14)
#define GPC_LPCR_A7_BSC_MASK_CORE0_WFI BIT(16)
#define GPC_LPCR_A7_BSC_MASK_CORE1_WFI BIT(17)
#define GPC_LPCR_A7_BSC_MASK_L2CC_WFI BIT(26)
#define GPC_LPCR_A7_BSC_IRQ_SRC_C0 BIT(28)
#define GPC_LPCR_A7_BSC_IRQ_SRC_C1 BIT(29)
#define GPC_LPCR_A7_BSC_IRQ_SRC_A7_WUP BIT(30)
#define GPC_LPCR_A7_BSC_MASK_DSM_TRIGGER BIT(31)

#define GPC_LPCR_A7_AD_L2_PGE 0x10000
#define GPC_LPCR_A7_AD_EN_C1_PUP 0x800
#define GPC_LPCR_A7_AD_EN_C1_IRQ_PUP 0x400
#define GPC_LPCR_A7_AD_EN_C0_PUP 0x200
#define GPC_LPCR_A7_AD_EN_C0_IRQ_PUP 0x100
#define GPC_LPCR_A7_AD_EN_PLAT_PDN 0x10
#define GPC_LPCR_A7_AD_EN_C1_PDN 0x8
#define GPC_LPCR_A7_AD_EN_C1_WFI_PDN 0x4
#define GPC_LPCR_A7_AD_EN_C0_PDN 0x2
#define GPC_LPCR_A7_AD_EN_C0_WFI_PDN 0x1

#define GPC_LPCR_M4_MASK_DSM_TRIGGER BIT(31)

#define GPC_SLPCR_EN_DSM BIT(31)
#define GPC_SLPCR_RBC_EN BIT(30)
#define GPC_SLPCR_EN_A7_FASTWUP_WAIT_MODE BIT(16)
#define GPC_SLPCR_SBYOS BIT(1)
#define GPC_SLPCR_BYPASS_PMIC_READY BIT(0)

#define GPC_MLPCR_MEMLP_CTL_DIS BIT(0)

#define GPC_PGC_ACK_SEL_A7_DUMMY_PUP_ACK 0x80000000
#define GPC_PGC_ACK_SEL_A7_DUMMY_PDN_ACK 0x00008000
#define GPC_PGC_ACK_SEL_A7_PLAT_PGC_PUP_ACK BIT(18)
#define GPC_PGC_ACK_SEL_A7_PLAT_PGC_PDN_ACK BIT(2)
#define GPC_PGC_ACK_SEL_A7_C0_PGC_PUP_ACK BIT(16)
#define GPC_PGC_ACK_SEL_A7_C0_PGC_PDN_ACK BIT(0)

#define CORE0_A7_PDN_SLOT_CONTROL BIT(0)
#define CORE0_A7_PUP_SLOT_CONTROL BIT(1)
#define CORE1_A7_PDN_SLOT_CONTROL BIT(2)
#define CORE1_A7_PUP_SLOT_CONTROL BIT(3)
#define SCU_PDN_SLOT_CONTROL BIT(4)
#define SCU_PUP_SLOT_CONTROL BIT(5)
#define FASTMEGA_PDN_SLOT_CONTROL BIT(6)
#define FASTMEGA_PUP_SLOT_CONTROL BIT(7)

#endif
4 changes: 4 additions & 0 deletions core/arch/arm/plat-imx/imx.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,8 @@ uint32_t imx_soc_type(void);
void imx_gpcv2_set_core1_pdn_by_software(void);
void imx_gpcv2_set_core1_pup_by_software(void);
void imx_gpcv2_set_core_pgc(bool enable, uint32_t offset);
void imx_gpcv2_mask_all_irqs(void);
void imx_gpcv2_mask_irq(uint32_t irq);
void imx_gpcv2_unmask_irq(uint32_t irq);
bool imx_gpcv2_irq_pending(uint32_t irq);
#endif
9 changes: 9 additions & 0 deletions core/arch/arm/plat-imx/imx_pm.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
#define SUSPEND_OCRAM_OFFSET 0x0
#define LOWPOWER_IDLE_OCRAM_OFFSET 0x1000

#define MX7_STATEID_CORE_CLOCK_GATE 0x00000004
#define MX7_STATEID_CLUSTER_CLOCK_GATE 0x00000040
#define MX7_LEVELID_CLUSTER 0x01000000

#ifndef ASM
#include <sm/sm.h>

Expand Down Expand Up @@ -92,6 +96,11 @@ int imx7d_lowpower_idle(uint32_t power_state, uintptr_t entry,
void imx7d_low_power_idle(struct imx7_pm_info *info);
int imx7d_cpuidle_init(void);
void v7_cpu_resume(void);

extern struct imx7_pm_info *pm_info;
extern struct gic_data gic_data;
extern uint32_t active_cores;
extern uint32_t resume;
#endif

#endif
2 changes: 1 addition & 1 deletion core/arch/arm/plat-imx/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@


static void main_fiq(void);
static struct gic_data gic_data;
struct gic_data gic_data;

static const struct thread_handlers handlers = {
.std_smc = tee_entry_std,
Expand Down
50 changes: 50 additions & 0 deletions core/arch/arm/plat-imx/pm/gpcv2.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,53 @@ void imx_gpcv2_set_core1_pup_by_software(void)

imx_gpcv2_set_core_pgc(false, GPC_PGC_C1);
}

void imx_gpcv2_mask_all_irqs(void)
{
vaddr_t base = gpc_base();

write32(~0x0, base + GPC_IMR1_CORE0_A7);
write32(~0x0, base + GPC_IMR2_CORE0_A7);
write32(~0x0, base + GPC_IMR3_CORE0_A7);
write32(~0x0, base + GPC_IMR4_CORE0_A7);

write32(~0x0, base + GPC_IMR1_CORE1_A7);
write32(~0x0, base + GPC_IMR2_CORE1_A7);
write32(~0x0, base + GPC_IMR3_CORE1_A7);
write32(~0x0, base + GPC_IMR4_CORE1_A7);
}

static void imx_gpcv2_mask_irq_helper(uint32_t irq, bool mask)
{
uint32_t val;
vaddr_t base = gpc_base();
uint32_t idx = (irq - 32) / 32;
uint32_t irqmask = 1 << (irq % 32);

val = read32(base + GPC_IMR1_CORE0_A7 + idx * 4);
if (mask)
val |= irqmask;
else
val &= ~irqmask;

write32(val, base + GPC_IMR1_CORE0_A7 + idx * 4);
}

void imx_gpcv2_mask_irq(uint32_t irq)
{
imx_gpcv2_mask_irq_helper(irq, true);
}

void imx_gpcv2_unmask_irq(uint32_t irq)
{
imx_gpcv2_mask_irq_helper(irq, false);
}

bool imx_gpcv2_irq_pending(uint32_t irq)
{
vaddr_t base = gpc_base();
uint32_t idx = (irq - 32) / 32;
uint32_t mask = 1 << (irq % 32);

return (read32(base + GPC_ISR1_A7 + idx * 4) & mask) != 0;
}
Loading