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

Stm32mp1 cpu opp #7219

Open
wants to merge 16 commits 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
32 changes: 32 additions & 0 deletions core/arch/arm/dts/stm32mp131.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,38 @@
compatible = "arm,cortex-a7";
device_type = "cpu";
reg = <0>;
clocks = <&rcc CK_MPU>;
clock-names = "cpu";
operating-points-v2 = <&cpu0_opp_table>;
nvmem-cells = <&part_number_otp>;
nvmem-cell-names = "part_number";
};
};

cpu0_opp_table: cpu0-opp-table {
compatible = "operating-points-v2";

/* Non‑overdrive OPP mission profile */
opp-650000000 {
opp-hz = /bits/ 64 <650000000>;
opp-microvolt = <1250000>;
opp-supported-hw = <0x3>;
st,opp-default;
};

/* Overdrive OPP: 10‑year life activity @100% activity rate */
opp-900000000 {
opp-hz = /bits/ 64 <900000000>;
opp-microvolt = <1350000>;
opp-supported-hw = <0x2>;
st,opp-default;
};

/* Overdrive OPP: 10‑year life activity @25% activity rate */
opp-1000000000 {
opp-hz = /bits/ 64 <1000000000>;
opp-microvolt = <1350000>;
opp-supported-hw = <0x2>;
};
};

Expand Down
22 changes: 21 additions & 1 deletion core/arch/arm/dts/stm32mp135f-dk.dts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@
};
};

&cpu0 {
cpu-supply = <&vddcpu>;
};

&etzpc {
st,decprot =
<DECPROT(STM32MP1_ETZPC_ADC1_ID, DECPROT_NS_RW, DECPROT_UNLOCK)>,
Expand Down Expand Up @@ -379,6 +383,12 @@
frac = <0xAAA>;
};

pll1_vco_1800Mhz: pll1-vco-1800Mhz {
src = <CLK_PLL12_HSE>;
divmn = <1 74>;
frac = <0>;
};

pll1_vco_1300Mhz: pll1-vco-1300Mhz {
src = <CLK_PLL12_HSE>;
divmn = <2 80>;
Expand Down Expand Up @@ -419,6 +429,11 @@
st,pll_vco = <&pll1_vco_2000Mhz>;
st,pll_div_pqr = <0 1 1>;
};

pll1_cfg3: pll1_cfg3 {
st,pll_vco = <&pll1_vco_1800Mhz>;
st,pll_div_pqr = <0 1 1>;
};
};

/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 266, R = 533 (DDR) */
Expand Down Expand Up @@ -462,7 +477,6 @@
st,clk_opp {
/* CK_MPU clock config for MP13 */
st,ck_mpu {

cfg_1 {
hz = <650000000>;
st,clksrc = <CLK_MPU_PLL1P>;
Expand All @@ -474,6 +488,12 @@
st,clksrc = <CLK_MPU_PLL1P>;
st,pll = <&pll1_cfg2>;
};

cfg_3 {
hz = <900000000>;
st,clksrc = <CLK_MPU_PLL1P>;
st,pll = <&pll1_cfg3>;
};
};
};
};
Expand Down
9 changes: 8 additions & 1 deletion core/arch/arm/plat-stm32mp1/conf.mk
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ $(call force,CFG_CORE_ASYNC_NOTIF,y)
$(call force,CFG_CORE_ASYNC_NOTIF_GIC_INTID,31)
$(call force,CFG_CORE_RESERVED_SHM,n)
$(call force,CFG_DRIVERS_CLK_FIXED,y)
$(call force,CFG_SCMI_MSG_PERF_DOMAIN,y)
$(call force,CFG_SECONDARY_INIT_CNTFRQ,n)
$(call force,CFG_STM32_GPIO,y)
$(call force,CFG_STM32_VREFBUF,y)
Expand All @@ -143,14 +144,17 @@ $(call force,CFG_STM32MP13_REGULATOR_IOD,y)
$(call force,CFG_TEE_CORE_NB_CORE,1)
$(call force,CFG_WITH_NSEC_GPIOS,n)
CFG_EXTERNAL_DT ?= n
CFG_STM32MP_OPP_COUNT ?= 2
CFG_STM32_CPU_OPP ?= y
CFG_STM32MP_OPP_COUNT ?= 3
CFG_STM32MP_OPP_LATENCY_US ?= 1000
CFG_WITH_PAGER ?= n
endif # CFG_STM32MP13

ifeq ($(CFG_STM32MP15),y)
$(call force,CFG_BOOT_SECONDARY_REQUEST,y)
$(call force,CFG_DRIVERS_CLK_FIXED,n)
$(call force,CFG_HALT_CORES_ON_PANIC_SGI,15)
$(call force,CFG_SCMI_MSG_PERF_DOMAIN,n)
$(call force,CFG_SECONDARY_INIT_CNTFRQ,y)
$(call force,CFG_STM32_SAES,n)
$(call force,CFG_STM32MP1_RSTCTRL,y)
Expand Down Expand Up @@ -293,6 +297,9 @@ ifeq ($(CFG_STM32_BSEC_PTA),y)
$(call force,CFG_STM32_BSEC,y,Mandated by CFG_BSEC_PTA)
endif

# Default disable CPU OPP support
CFG_STM32_CPU_OPP ?= n

# Default enable SCMI PTA support
CFG_SCMI_PTA ?= y
ifeq ($(CFG_SCMI_PTA),y)
Expand Down
6 changes: 6 additions & 0 deletions core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pwr.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@
#define PWR_WKUPCR_OFF 0x20
#define PWR_MPUWKUPENR_OFF 0x28

#ifdef CFG_STM32MP13
/* CR1 register bitfield for STM32MP13 variants */
#define PWR_CR1_MPU_RAM_LOW_SPEED BIT(9)
#define PWR_MPU_RAM_LOW_SPEED_THRESHOLD 1320000
#endif

/* CR3 register bitfield for STM32MP13 variants */
#define PWR_CR3_VDDSD1EN BIT(13)
#define PWR_CR3_VDDSD1RDY BIT(14)
Expand Down
17 changes: 17 additions & 0 deletions core/arch/arm/plat-stm32mp1/drivers/stm32mp1_syscfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#define SYSCFG_CMPSD1CR U(0x30)
#define SYSCFG_CMPSD2CR U(0x40)
#define SYSCFG_HSLVEN0R U(0x50)
#define SYSCFG_IDC U(0x380)
#define SYSCFG_IOSIZE U(0x400)

/*
Expand Down Expand Up @@ -61,13 +62,29 @@
#define SYSCFG_HSLV_MASK GENMASK_32(15, 0)
#define SYSCFG_HSLV_KEY U(0x1018)

/*
* SYSCFG_IDC Register
*/
#define SYSCFG_IDC_DEV_ID_MASK GENMASK_32(11, 0)
#define SYSCFG_IDC_REV_ID_MASK GENMASK_32(31, 16)
#define SYSCFG_IDC_REV_ID_SHIFT U(16)

static vaddr_t get_syscfg_base(void)
{
static struct io_pa_va base = { .pa = SYSCFG_BASE };

return io_pa_or_va(&base, SYSCFG_IOSIZE);
}

uint32_t stm32mp_syscfg_get_chip_dev_id(void)
{
if (IS_ENABLED(CFG_STM32MP13))
return io_read32(get_syscfg_base() + SYSCFG_IDC) &
SYSCFG_IDC_DEV_ID_MASK;

return 0;
}

static void enable_io_compensation(int cmpcr_offset)
{
vaddr_t cmpcr_va = get_syscfg_base() + cmpcr_offset;
Expand Down
164 changes: 164 additions & 0 deletions core/arch/arm/plat-stm32mp1/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,35 @@ static TEE_Result init_console_from_dt(void)
/* Probe console from DT once clock inits (service init level) are completed */
service_init_late(init_console_from_dt);

static uintptr_t stm32_dbgmcu_base(void)
{
static void *va;

if (!cpu_mmu_enabled())
return DBGMCU_BASE;

if (!va)
va = phys_to_virt(DBGMCU_BASE, MEM_AREA_IO_SEC, 1);

return (uintptr_t)va;
}

/* SoC device ID util, returns default ID if can't access DBGMCU */
TEE_Result stm32mp1_dbgmcu_get_chip_dev_id(uint32_t *chip_dev_id)
{
uint32_t id = STM32MP1_CHIP_ID;

assert(chip_dev_id);

if (stm32_bsec_read_debug_conf() & BSEC_DBGSWGEN)
id = io_read32(stm32_dbgmcu_base() + DBGMCU_IDC) &
DBGMCU_IDC_DEV_ID_MASK;

*chip_dev_id = id;

return TEE_SUCCESS;
}

/*
* GIC init, used also for primary/secondary boot core wake completion
*/
Expand Down Expand Up @@ -620,3 +649,138 @@ bool stm32mp1_ram_intersect_pager_ram(paddr_t base, size_t size)
CFG_TZSRAM_SIZE);
}
#endif

static TEE_Result get_chip_dev_id(uint32_t *dev_id)
{
#ifdef CFG_STM32MP13
*dev_id = stm32mp_syscfg_get_chip_dev_id();
return TEE_SUCCESS;
#else /* assume CFG_STM32MP15 */
return stm32mp1_dbgmcu_get_chip_dev_id(dev_id);
#endif
}

static TEE_Result get_part_number(uint32_t *part_nb)
{
static uint32_t part_number;
uint32_t dev_id = 0;
uint32_t otp = 0;
size_t bit_len = 0;
TEE_Result res = TEE_ERROR_GENERIC;

assert(part_nb);

if (part_number) {
*part_nb = part_number;
return TEE_SUCCESS;
}

res = get_chip_dev_id(&dev_id);
if (res)
return res;

res = stm32_bsec_find_otp_in_nvmem_layout("part_number_otp",
&otp, NULL, &bit_len);
if (res)
return res;

res = stm32_bsec_read_otp(&part_number, otp);
if (res)
return res;

assert(bit_len < 16);
part_number = (part_number & GENMASK_32(bit_len, 0)) |
SHIFT_U32(dev_id, 16);

*part_nb = part_number;

return TEE_SUCCESS;
}

bool stm32mp_supports_cpu_opp(uint32_t opp_id)
{
uint32_t part_number = 0;
uint32_t id = 0;

if (get_part_number(&part_number)) {
DMSG("Cannot get part number");
panic();
}

switch (part_number) {
case STM32MP135F_PART_NB:
case STM32MP135D_PART_NB:
case STM32MP133F_PART_NB:
case STM32MP133D_PART_NB:
case STM32MP131F_PART_NB:
case STM32MP131D_PART_NB:
case STM32MP157F_PART_NB:
case STM32MP157D_PART_NB:
case STM32MP153F_PART_NB:
case STM32MP153D_PART_NB:
case STM32MP151F_PART_NB:
case STM32MP151D_PART_NB:
id = BIT(1);
break;
default:
id = BIT(0);
break;
}

return opp_id & id;
}

bool stm32mp_supports_hw_cryp(void)
{
uint32_t part_number = 0;

if (!IS_ENABLED(CFG_STM32_CRYP))
return false;

if (get_part_number(&part_number)) {
DMSG("Cannot get part number");
panic();
}

switch (part_number) {
case STM32MP135F_PART_NB:
case STM32MP135C_PART_NB:
case STM32MP133F_PART_NB:
case STM32MP133C_PART_NB:
case STM32MP131F_PART_NB:
case STM32MP131C_PART_NB:
return true;
case STM32MP157F_PART_NB:
case STM32MP157C_PART_NB:
case STM32MP153F_PART_NB:
case STM32MP153C_PART_NB:
case STM32MP151F_PART_NB:
case STM32MP151C_PART_NB:
return true;
default:
return false;
}
}

bool stm32mp_supports_second_core(void)
{
uint32_t part_number = 0;

if (CFG_TEE_CORE_NB_CORE == 1)
return false;

if (get_part_number(&part_number)) {
DMSG("Cannot get part number");
panic();
}

switch (part_number) {
case STM32MP151F_PART_NB:
case STM32MP151D_PART_NB:
case STM32MP151C_PART_NB:
case STM32MP151A_PART_NB:
return false;
default:
return true;
}
}
Loading
Loading