mirror of
https://github.com/cyring/CoreFreq.git
synced 2025-07-23 12:13:07 +02:00
[aarch64] Query CMN either from DeviceTree either from ACPI
This commit is contained in:
@@ -318,6 +318,7 @@ typedef struct
|
||||
struct {
|
||||
CLUSTERCFR ClusterCfg;
|
||||
CLUSTERIDR ClusterRev;
|
||||
enum CMN_TYPE CMN_Type;
|
||||
|
||||
unsigned int Boost[UNCORE_BOOST(SIZE)];
|
||||
BUS_REGISTERS Bus;
|
||||
|
@@ -687,6 +687,9 @@ void Technology_Update( RO(SHM_STRUCT) *RO(Shm),
|
||||
&& RO(Proc)->Uncore.ClusterRev.value != 0) {
|
||||
RO(Shm)->Proc.Technology.DSU = 1;
|
||||
}
|
||||
if (RO(Proc)->Uncore.CMN_Type != CMN_NONE) {
|
||||
RO(Shm)->Proc.Technology.CMN = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void Mitigation_Stage( RO(SHM_STRUCT) *RO(Shm),
|
||||
|
@@ -38,6 +38,9 @@
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
|
||||
#include <asm/sysreg.h>
|
||||
#endif
|
||||
#ifdef CONFIG_OF
|
||||
#include <linux/of.h>
|
||||
#endif
|
||||
#ifdef CONFIG_ACPI
|
||||
#include <linux/acpi.h>
|
||||
#include <acpi/processor.h>
|
||||
@@ -2757,6 +2760,187 @@ static int CoreFreqK_ProbePCI( struct pci_device_id PCI_ids[],
|
||||
return rc;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_OF)
|
||||
static const struct of_device_id CMN_of_match[] = {
|
||||
{ .compatible = "arm,cmn-600", .data = (void *) CMN_600 },
|
||||
{ .compatible = "arm,cmn-650", .data = (void *) CMN_650 },
|
||||
{ .compatible = "arm,cmn-700", .data = (void *) CMN_700 },
|
||||
{ .compatible = "arm,cmn-s3", .data = (void *) CMN_S3 },
|
||||
{ .compatible = "arm,ci-700", .data = (void *) CMN_CI700 },
|
||||
{ /* EOL */ }
|
||||
};
|
||||
|
||||
static enum CMN_TYPE Detect_CMN_From_DeviceTree(void)
|
||||
{
|
||||
struct device_node *node = of_find_all_nodes(NULL);
|
||||
while (node != NULL) {
|
||||
const struct of_device_id *match;
|
||||
match = of_match_node(CMN_of_match, node);
|
||||
if (match) {
|
||||
of_node_put(node);
|
||||
return (enum CMN_TYPE) (uintptr_t) match->data;
|
||||
}
|
||||
node = of_find_all_nodes(node);
|
||||
}
|
||||
return CMN_NONE;
|
||||
}
|
||||
#endif /* CONFIG_OF */
|
||||
|
||||
#if defined(CONFIG_ACPI)
|
||||
/* Source: drivers/acpi/bus.c */
|
||||
#define ACPI_DT_NAMESPACE_HID "PRP0001"
|
||||
|
||||
static bool Zacpi_of_match_device(struct acpi_device *adev,
|
||||
const struct of_device_id *of_match_table,
|
||||
const struct of_device_id **of_id)
|
||||
{
|
||||
const union acpi_object *of_compatible, *obj;
|
||||
int i, nval;
|
||||
|
||||
if (!adev)
|
||||
return false;
|
||||
|
||||
of_compatible = adev->data.of_compatible;
|
||||
if (!of_match_table || !of_compatible)
|
||||
return false;
|
||||
|
||||
if (of_compatible->type == ACPI_TYPE_PACKAGE) {
|
||||
nval = of_compatible->package.count;
|
||||
obj = of_compatible->package.elements;
|
||||
} else {
|
||||
nval = 1;
|
||||
obj = of_compatible;
|
||||
}
|
||||
for (i = 0; i < nval; i++, obj++) {
|
||||
const struct of_device_id *id;
|
||||
|
||||
for (id = of_match_table; id->compatible[0]; id++)
|
||||
if (!strcasecmp(obj->string.pointer, id->compatible)) {
|
||||
if (of_id)
|
||||
*of_id = id;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool Z__acpi_match_device_cls(const struct acpi_device_id *id,
|
||||
struct acpi_hardware_id *hwid)
|
||||
{
|
||||
int i, msk, byte_shift;
|
||||
char buf[3];
|
||||
|
||||
if (!id->cls)
|
||||
return false;
|
||||
|
||||
for (i = 1; i <= 3; i++) {
|
||||
byte_shift = 8 * (3 - i);
|
||||
msk = (id->cls_msk >> byte_shift) & 0xFF;
|
||||
if (!msk)
|
||||
continue;
|
||||
|
||||
sprintf(buf, "%02x", (id->cls >> byte_shift) & msk);
|
||||
if (strncmp(buf, &hwid->id[(i - 1) * 2], 2))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool Z__acpi_match_device(struct acpi_device *device,
|
||||
const struct acpi_device_id *acpi_ids,
|
||||
const struct of_device_id *of_ids,
|
||||
const struct acpi_device_id **acpi_id,
|
||||
const struct of_device_id **of_id)
|
||||
{
|
||||
const struct acpi_device_id *id;
|
||||
struct acpi_hardware_id *hwid;
|
||||
|
||||
if (!device || !device->status.present)
|
||||
return false;
|
||||
|
||||
list_for_each_entry(hwid, &device->pnp.ids, list) {
|
||||
if (acpi_ids) {
|
||||
for (id = acpi_ids; id->id[0] || id->cls; id++) {
|
||||
if (id->id[0] && !strcmp((char *)id->id, hwid->id))
|
||||
goto out_acpi_match;
|
||||
if (id->cls && Z__acpi_match_device_cls(id, hwid))
|
||||
goto out_acpi_match;
|
||||
}
|
||||
}
|
||||
if (!strcmp(ACPI_DT_NAMESPACE_HID, hwid->id))
|
||||
return Zacpi_of_match_device(device, of_ids, of_id);
|
||||
}
|
||||
return false;
|
||||
|
||||
out_acpi_match:
|
||||
if (acpi_id)
|
||||
*acpi_id = id;
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct acpi_device_id CMN_ACPI_ID[] = {
|
||||
{ "ARMHC600", CMN_600 },
|
||||
{ "ARMHC650", CMN_650 },
|
||||
{ "ARMHC700", CMN_700 },
|
||||
{ "ARMHC003", CMN_S3 },
|
||||
{ "ARMHC701", CMN_CI700 },
|
||||
{ "", 0 }
|
||||
};
|
||||
|
||||
static int CMN_Match( struct acpi_device *adev,
|
||||
const struct acpi_device_id *ids,
|
||||
const struct acpi_device_id **id )
|
||||
{
|
||||
int rc = Z__acpi_match_device(adev, ids, NULL, id, NULL) ? 0 : -ENOENT;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static acpi_status CMN_Compare( acpi_handle handle,
|
||||
u32 level,
|
||||
void *data,
|
||||
void **return_value )
|
||||
{
|
||||
struct acpi_device_id *ids;
|
||||
struct acpi_device *adev, **rdev;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0)
|
||||
if ((adev = acpi_fetch_acpi_dev(handle)) == NULL) {
|
||||
return AE_OK;
|
||||
}
|
||||
#else
|
||||
if (acpi_bus_get_device(handle, &adev)) {
|
||||
return AE_OK;
|
||||
}
|
||||
#endif
|
||||
rdev = data;
|
||||
|
||||
for (ids = CMN_ACPI_ID; ids->id[0] || ids->cls; ids++) {
|
||||
const struct acpi_device_id *id = NULL;
|
||||
if (CMN_Match(adev, ids, &id) == 0) {
|
||||
*rdev = adev;
|
||||
(*rdev)->driver_data = (void*) id->driver_data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
static enum CMN_TYPE Detect_CMN_From_ACPI(void)
|
||||
{
|
||||
struct acpi_device *rdev = NULL;
|
||||
acpi_status status;
|
||||
status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
|
||||
ACPI_UINT32_MAX, CMN_Compare, NULL, &rdev, NULL);
|
||||
|
||||
if (!ACPI_FAILURE(status) && (rdev != NULL)) {
|
||||
return (enum CMN_TYPE) rdev->driver_data;
|
||||
} else {
|
||||
return CMN_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
#undef ACPI_DT_NAMESPACE_HID
|
||||
#endif /* CONFIG_ACPI */
|
||||
|
||||
static void Query_Same_Genuine_Features(void)
|
||||
{
|
||||
if ((PRIVATE(OF(Specific)) = LookupProcessor()) != NULL)
|
||||
@@ -2805,6 +2989,27 @@ static void Query_DynamIQ(unsigned int cpu)
|
||||
}
|
||||
}
|
||||
|
||||
static void Query_CMN(unsigned int cpu)
|
||||
{
|
||||
enum CMN_TYPE CMN_Type[2] = {CMN_NONE, CMN_NONE};
|
||||
|
||||
Query_GenericMachine(cpu);
|
||||
#if defined(CONFIG_OF)
|
||||
CMN_Type[0] = Detect_CMN_From_DeviceTree();
|
||||
#endif
|
||||
#if defined(CONFIG_ACPI)
|
||||
CMN_Type[1] = Detect_CMN_From_ACPI();
|
||||
#endif
|
||||
PUBLIC(RO(Proc))->Uncore.CMN_Type = \
|
||||
CMN_Type[0] == CMN_NONE ? CMN_Type[1] : CMN_Type[0];
|
||||
}
|
||||
|
||||
static void Query_DynamIQ_CMN(unsigned int cpu)
|
||||
{
|
||||
Query_DynamIQ(cpu);
|
||||
Query_CMN(cpu);
|
||||
}
|
||||
|
||||
static void SystemRegisters(CORE_RO *Core)
|
||||
{
|
||||
volatile AA64ISAR2 isar2;
|
||||
|
@@ -397,12 +397,14 @@ typedef struct
|
||||
} ARCH;
|
||||
|
||||
static CLOCK BaseClock_GenericMachine(unsigned int ratio) ;
|
||||
static void Query_CMN(unsigned int cpu) ;
|
||||
static void Query_GenericMachine(unsigned int cpu) ;
|
||||
static void PerCore_GenericMachine(void *arg) ;
|
||||
static void Start_GenericMachine(void *arg) ;
|
||||
static void Stop_GenericMachine(void *arg) ;
|
||||
static void InitTimer_GenericMachine(unsigned int cpu) ;
|
||||
static void Query_DynamIQ(unsigned int cpu) ;
|
||||
static void Query_DynamIQ_CMN(unsigned int cpu) ;
|
||||
/* [Void] */
|
||||
#define _Void_Signature {.ExtFamily=0x00, .Family=0x0, .ExtModel=0x0, .Model=0x0}
|
||||
#define _Cortex_A34 {.ExtFamily=0xd0, .Family=0x2, .ExtModel=0x0, .Model=0x8}
|
||||
@@ -1346,7 +1348,7 @@ static ARCH Arch[ARCHITECTURES] = {
|
||||
},
|
||||
[Neoverse_E1] = {
|
||||
.Signature = _Neoverse_E1,
|
||||
.Query = Query_GenericMachine,
|
||||
.Query = Query_CMN,
|
||||
.Update = PerCore_GenericMachine,
|
||||
.Start = Start_GenericMachine,
|
||||
.Stop = Stop_GenericMachine,
|
||||
@@ -1374,7 +1376,7 @@ static ARCH Arch[ARCHITECTURES] = {
|
||||
},
|
||||
[Neoverse_N1] = {
|
||||
.Signature = _Neoverse_N1,
|
||||
.Query = Query_GenericMachine,
|
||||
.Query = Query_CMN,
|
||||
.Update = PerCore_GenericMachine,
|
||||
.Start = Start_GenericMachine,
|
||||
.Stop = Stop_GenericMachine,
|
||||
@@ -1402,7 +1404,7 @@ static ARCH Arch[ARCHITECTURES] = {
|
||||
},
|
||||
[Neoverse_N2] = {
|
||||
.Signature = _Neoverse_N2,
|
||||
.Query = Query_GenericMachine,
|
||||
.Query = Query_CMN,
|
||||
.Update = PerCore_GenericMachine,
|
||||
.Start = Start_GenericMachine,
|
||||
.Stop = Stop_GenericMachine,
|
||||
@@ -1430,7 +1432,7 @@ static ARCH Arch[ARCHITECTURES] = {
|
||||
},
|
||||
[Neoverse_V1] = {
|
||||
.Signature = _Neoverse_V1,
|
||||
.Query = Query_DynamIQ,
|
||||
.Query = Query_DynamIQ_CMN,
|
||||
.Update = PerCore_GenericMachine,
|
||||
.Start = Start_GenericMachine,
|
||||
.Stop = Stop_GenericMachine,
|
||||
@@ -1458,7 +1460,7 @@ static ARCH Arch[ARCHITECTURES] = {
|
||||
},
|
||||
[Neoverse_V2] = {
|
||||
.Signature = _Neoverse_V2,
|
||||
.Query = Query_GenericMachine,
|
||||
.Query = Query_CMN,
|
||||
.Update = PerCore_GenericMachine,
|
||||
.Start = Start_GenericMachine,
|
||||
.Stop = Stop_GenericMachine,
|
||||
|
@@ -103,6 +103,15 @@ enum MECH_CSV2 {
|
||||
CSV2_3p0
|
||||
};
|
||||
|
||||
enum CMN_TYPE {
|
||||
CMN_NONE,
|
||||
CMN_600,
|
||||
CMN_650,
|
||||
CMN_700,
|
||||
CMN_S3,
|
||||
CMN_CI700
|
||||
};
|
||||
|
||||
enum HYPERVISOR {
|
||||
HYPERV_NONE,
|
||||
BARE_METAL,
|
||||
|
Reference in New Issue
Block a user