1*54fd6939SJiyong Park /* 2*54fd6939SJiyong Park * Copyright (c) 2021, Arm Limited. All rights reserved. 3*54fd6939SJiyong Park * 4*54fd6939SJiyong Park * SPDX-License-Identifier: BSD-3-Clause 5*54fd6939SJiyong Park */ 6*54fd6939SJiyong Park 7*54fd6939SJiyong Park #include <stdbool.h> 8*54fd6939SJiyong Park 9*54fd6939SJiyong Park #include <common/debug.h> 10*54fd6939SJiyong Park #include <lib/mpmm/mpmm.h> 11*54fd6939SJiyong Park 12*54fd6939SJiyong Park #include <plat/common/platform.h> 13*54fd6939SJiyong Park 14*54fd6939SJiyong Park #if ENABLE_MPMM_FCONF 15*54fd6939SJiyong Park # include <lib/fconf/fconf.h> 16*54fd6939SJiyong Park # include <lib/fconf/fconf_mpmm_getter.h> 17*54fd6939SJiyong Park #endif 18*54fd6939SJiyong Park read_cpuppmcr_el3_mpmmpinctl(void)19*54fd6939SJiyong Parkstatic uint64_t read_cpuppmcr_el3_mpmmpinctl(void) 20*54fd6939SJiyong Park { 21*54fd6939SJiyong Park return (read_cpuppmcr_el3() >> CPUPPMCR_EL3_MPMMPINCTL_SHIFT) & 22*54fd6939SJiyong Park CPUPPMCR_EL3_MPMMPINCTL_MASK; 23*54fd6939SJiyong Park } 24*54fd6939SJiyong Park write_cpumpmmcr_el3_mpmm_en(uint64_t mpmm_en)25*54fd6939SJiyong Parkstatic void write_cpumpmmcr_el3_mpmm_en(uint64_t mpmm_en) 26*54fd6939SJiyong Park { 27*54fd6939SJiyong Park uint64_t value = read_cpumpmmcr_el3(); 28*54fd6939SJiyong Park 29*54fd6939SJiyong Park value &= ~(CPUMPMMCR_EL3_MPMM_EN_MASK << CPUMPMMCR_EL3_MPMM_EN_SHIFT); 30*54fd6939SJiyong Park value |= (mpmm_en & CPUMPMMCR_EL3_MPMM_EN_MASK) << 31*54fd6939SJiyong Park CPUMPMMCR_EL3_MPMM_EN_SHIFT; 32*54fd6939SJiyong Park 33*54fd6939SJiyong Park write_cpumpmmcr_el3(value); 34*54fd6939SJiyong Park } 35*54fd6939SJiyong Park mpmm_supported(void)36*54fd6939SJiyong Parkstatic bool mpmm_supported(void) 37*54fd6939SJiyong Park { 38*54fd6939SJiyong Park bool supported = false; 39*54fd6939SJiyong Park const struct mpmm_topology *topology; 40*54fd6939SJiyong Park 41*54fd6939SJiyong Park #if ENABLE_MPMM_FCONF 42*54fd6939SJiyong Park topology = FCONF_GET_PROPERTY(mpmm, config, topology); 43*54fd6939SJiyong Park #else 44*54fd6939SJiyong Park topology = plat_mpmm_topology(); 45*54fd6939SJiyong Park #endif /* ENABLE_MPMM_FCONF */ 46*54fd6939SJiyong Park 47*54fd6939SJiyong Park /* 48*54fd6939SJiyong Park * For the current core firstly try to find out if the platform 49*54fd6939SJiyong Park * configuration has claimed support for MPMM, then make sure that MPMM 50*54fd6939SJiyong Park * is controllable through the system registers. 51*54fd6939SJiyong Park */ 52*54fd6939SJiyong Park 53*54fd6939SJiyong Park if (topology != NULL) { 54*54fd6939SJiyong Park unsigned int core_pos = plat_my_core_pos(); 55*54fd6939SJiyong Park 56*54fd6939SJiyong Park supported = topology->cores[core_pos].supported && 57*54fd6939SJiyong Park (read_cpuppmcr_el3_mpmmpinctl() == 0U); 58*54fd6939SJiyong Park } else { 59*54fd6939SJiyong Park ERROR("MPMM: failed to generate MPMM topology\n"); 60*54fd6939SJiyong Park } 61*54fd6939SJiyong Park 62*54fd6939SJiyong Park return supported; 63*54fd6939SJiyong Park } 64*54fd6939SJiyong Park mpmm_enable(void)65*54fd6939SJiyong Parkvoid mpmm_enable(void) 66*54fd6939SJiyong Park { 67*54fd6939SJiyong Park bool supported = mpmm_supported(); 68*54fd6939SJiyong Park 69*54fd6939SJiyong Park if (supported) { 70*54fd6939SJiyong Park write_cpumpmmcr_el3_mpmm_en(1U); 71*54fd6939SJiyong Park } 72*54fd6939SJiyong Park } 73