/* SPDX-License-Identifier: MIT */ #include "tunables.h" #include "adt.h" #include "pmgr.h" #include "soc.h" #include "types.h" #include "utils.h" /* * These magic tunable sequences are hardcoded in various places in XNU, and are required for * proper operation of various fabric features and other miscellanea. Without them, things tend * to subtly break... */ struct entry { u32 offset; u32 clear; u32 set; }; struct sequence { struct entry *entry; u64 base; }; struct entry t8103_agx_entry[] = { {0x30, 0xffffffff, 0x50014}, {0x34, 0xffffffff, 0xa003c}, {0x400, 0x400103ff, 0x40010001}, {0x600, 0x1ffffff, 0x1ffffff}, {0x738, 0x1ff01ff, 0x140034}, {0x798, 0x1ff01ff, 0x14003c}, {0x800, 0x100, 0x100}, {-1, 0, 0}, }; struct sequence t8103_agx_tunables[] = { {t8103_agx_entry, 0x205000000}, {NULL, -1}, }; // TODO: check masks struct entry t600x_agx_entry[] = { {0x0, 0x1, 0x1}, {0x10, 0xfff0000, 0xd0000}, {0x14, 0x3, 0x1}, {0x18, 0x3, 0x1}, {0x1c, 0x3, 0x3}, {0x20, 0x3, 0x3}, {0x24, 0x3, 0x3}, {0x28, 0x3, 0x3}, {0x2c, 0x3, 0x3}, {0x400, 0x400103ff, 0x40010001}, {0x600, 0x1ffffff, 0x1ffffff}, {0x800, 0x100, 0x100}, {-1, 0, 0}, }; struct sequence t600x_agx_tunables[] = { {t600x_agx_entry, 0x405000000}, {NULL, -1}, }; // TODO: check masks struct entry t8112_agx_entry[] = { {0x0, 0x200, 0x200}, {0x34, 0xffffffff, 0x50014}, {0x38, 0xffffffff, 0xa003c}, {0x400, 0xc00103ff, 0xc0010001}, {0x600, 0x1ffffff, 0x1ffffff}, {0x738, 0x1ff01ff, 0x14003c}, {0x798, 0x1ff01ff, 0x14003c}, {0x800, 0x100, 0x100}, {-1, 0, 0}, }; struct sequence t8112_agx_tunables[] = { {t8112_agx_entry, 0x205000000}, {NULL, -1}, }; struct entry t8103_ane_pmgr_entry[] = { {0x0, 0x10, 0x10}, {0x38, 0xffff, 0x50020}, {0x3c, 0xffff, 0xa0030}, {0x400, 0x4, 0x40010001}, {0x600, 0x0, 0x1ffffff}, {0x738, 0x1ff01ff, 0x200020}, {0x798, 0x1ff01ff, 0x100030}, {0x7f8, 0x1ff01ff, 0x100000a}, {0x900, 0x1, 0x101}, {-1, 0, 0}, }; struct entry t8103_ane_dart_entry[] = { {0xfc, 0x0, 0x1}, {0x2d0, 0x0, 0x0}, {0x2f0, 0x0, 0x0}, {0x34, 0x0, 0xffffffff}, {0x20, 0x0, 0x100000}, {0x60, 0x0, 0x80016100}, {0x68, 0x20202, 0xf0f0f}, {0x6c, 0x0, 0x80808}, {0x100, 0x0, 0x80}, {-1, 0, 0}, }; struct entry t8103_ane_dapf_entry[] = { {0x4, 0x0, 0x1}, {0x8, 0x0, 0x824000}, {0xc, 0x0, 0x8}, {0x10, 0x0, 0x8c7fff}, {0x14, 0x0, 0x8}, {0x0, 0x0, 0x11}, {0x44, 0x0, 0x1}, {0x48, 0x0, 0x0}, {0x4c, 0x0, 0xf}, {0x50, 0x0, 0xffffffff}, {0x54, 0x0, 0xf}, {0x40, 0x0, 0x33}, {0x84, 0x0, 0x1}, {0x88, 0x0, 0x2b45c000}, {0x8c, 0x0, 0x2}, {0x90, 0x0, 0x2b45c003}, {0x94, 0x0, 0x2}, {0x80, 0x0, 0x31}, {0xc4, 0x0, 0x1}, {0xc8, 0x0, 0x3b70c000}, {0xcc, 0x0, 0x2}, {0xd0, 0x0, 0x3b70c033}, {0xd4, 0x0, 0x2}, {0xc0, 0x0, 0x31}, {-1, 0, 0}, }; struct entry t8103_ane_dpe_sys_entry[] = { {0x3c, 0x0, 0x262}, {0x40, 0x0, 0x262}, {0x44, 0x0, 0x2c8}, {0x48, 0x0, 0x351}, {0x4c, 0x0, 0x391}, {0x50, 0x0, 0x404}, {0x54, 0x0, 0x441}, {0x58, 0x0, 0x4b5}, {0x5c, 0x0, 0x4ec}, {0x60, 0x0, 0x599}, {0x64, 0x0, 0x647}, {0x68, 0x0, 0x6f2}, {0x6c, 0x0, 0x82b}, {0x70, 0x0, 0x82b}, {0x74, 0x0, 0x82b}, {0x78, 0x0, 0x82b}, {-1, 0, 0}, }; struct entry t8103_ane_perf_entry[] = { {0x8, 0xff, 0xf8a96}, {0xc, 0xff, 0x11ca11}, {0x10, 0xff, 0x15c4ad}, {0x14, 0xff, 0x1cafc0}, {0x18, 0xff, 0x1c858e}, {0x1c, 0xff, 0x20cf3d}, {0x20, 0xff, 0x2087b1}, {0x24, 0xff, 0x294c83}, {0x28, 0xff, 0x2b6ffb}, {0x2c, 0xff, 0x2cfb4c}, {0x30, 0xff, 0x305c9b}, {0x34, 0xff, 0x2e277f}, {0x38, 0xff, 0x0}, {0x3c, 0xff, 0x0}, {0x40, 0xff, 0x0}, {0x48, 0xff, 0xd47e2}, {0x4c, 0xff, 0x11ca11}, {0x50, 0xff, 0x15c4ad}, {0x54, 0xff, 0x1a1c07}, {0x58, 0xff, 0x1c858e}, {0x5c, 0xff, 0x20cf3d}, {0x60, 0xff, 0x2087b1}, {0x64, 0xff, 0x270050}, {0x68, 0xff, 0x28cacd}, {0x6c, 0xff, 0x2b19cc}, {0x70, 0xff, 0x2b09f6}, {0x74, 0xff, 0x2cd4e0}, {0x78, 0xff, 0x0}, {0x7c, 0xff, 0x0}, {0x80, 0xff, 0x0}, {0x88, 0xff, 0xb8130}, {0x8c, 0xff, 0xf5f41}, {0x90, 0xff, 0x12b938}, {0x94, 0xff, 0x167287}, {0x98, 0xff, 0x14710e}, {0x9c, 0xff, 0x18b58d}, {0xa0, 0xff, 0x147c37}, {0xa4, 0xff, 0x1635ee}, {0xa8, 0xff, 0x18560a}, {0xac, 0xff, 0x18737e}, {0xb0, 0xff, 0x19e10d}, {0xb4, 0xff, 0x0}, {0xb8, 0xff, 0x0}, {0xbc, 0xff, 0x0}, {0xc0, 0xff, 0x0}, {-1, 0, 0}, }; struct entry t8103_ane_dpe_soc_entry[] = { {0x24, 0x0, 0x226}, {0x28, 0x0, 0x6b7}, {0x2c, 0x0, 0xd8}, {0x30, 0x0, 0x1af}, {0x34, 0x0, 0x35e}, {0x38, 0x0, 0x6bb}, {0x3c, 0x0, 0x226}, {0x40, 0x0, 0x6b7}, {0x44, 0x0, 0xd8}, {0x48, 0x0, 0x1af}, {0x4c, 0x0, 0x35e}, {0x50, 0x0, 0x6bb}, {0x54, 0x0, 0x21c}, {0x58, 0x0, 0x69a}, {0x5c, 0x0, 0xd4}, {0x60, 0x0, 0x1a8}, {0x64, 0x0, 0x34f}, {0x68, 0x0, 0x69e}, {0x6c, 0x0, 0x213}, {0x70, 0x0, 0x67c}, {0x74, 0x0, 0xd0}, {0x78, 0x0, 0x1a0}, {0x7c, 0x0, 0x340}, {0x80, 0x0, 0x680}, {0x84, 0x0, 0x210}, {0x88, 0x0, 0x671}, {0x8c, 0x0, 0xcf}, {0x90, 0x0, 0x19e}, {0x94, 0x0, 0x33b}, {0x98, 0x0, 0x675}, {0x9c, 0x0, 0x20b}, {0xa0, 0x0, 0x664}, {0xa4, 0x0, 0xcd}, {0xa8, 0x0, 0x19a}, {0xac, 0x0, 0x334}, {0xb0, 0x0, 0x668}, {0xb4, 0x0, 0x20b}, {0xb8, 0x0, 0x662}, {0xbc, 0x0, 0xcd}, {0xc0, 0x0, 0x19a}, {0xc4, 0x0, 0x333}, {0xc8, 0x0, 0x666}, {0xcc, 0x0, 0x20e}, {0xd0, 0x0, 0x66d}, {0xd4, 0x0, 0xcf}, {0xd8, 0x0, 0x19d}, {0xdc, 0x0, 0x339}, {0xe0, 0x0, 0x671}, {0xe4, 0x0, 0x212}, {0xe8, 0x0, 0x67a}, {0xec, 0x0, 0xd0}, {0xf0, 0x0, 0x1a0}, {0xf4, 0x0, 0x33f}, {0xf8, 0x0, 0x67e}, {0xfc, 0x0, 0x22d}, {0x100, 0x0, 0x6cc}, {0x104, 0x0, 0xda}, {0x108, 0x0, 0x1b4}, {0x10c, 0x0, 0x368}, {0x110, 0x0, 0x6d0}, {0x114, 0x0, 0x25f}, {0x118, 0x0, 0x768}, {0x11c, 0x0, 0xee}, {0x120, 0x0, 0x1dc}, {0x124, 0x0, 0x3b7}, {0x128, 0x0, 0x76d}, {0x12c, 0x0, 0x2ab}, {0x130, 0x0, 0x857}, {0x134, 0x0, 0x10c}, {0x138, 0x0, 0x217}, {0x13c, 0x0, 0x42e}, {0x140, 0x0, 0x85c}, {0x144, 0x0, 0x384}, {0x148, 0x0, 0xafd}, {0x14c, 0x0, 0x161}, {0x150, 0x0, 0x2c2}, {0x154, 0x0, 0x583}, {0x158, 0x0, 0xb05}, {0x15c, 0x0, 0x384}, {0x160, 0x0, 0xafd}, {0x164, 0x0, 0x161}, {0x168, 0x0, 0x2c2}, {0x16c, 0x0, 0x583}, {0x170, 0x0, 0xb05}, {0x174, 0x0, 0x384}, {0x178, 0x0, 0xafd}, {0x17c, 0x0, 0x161}, {0x180, 0x0, 0x2c2}, {0x184, 0x0, 0x583}, {0x188, 0x0, 0xb05}, {0x18c, 0x0, 0x384}, {0x190, 0x0, 0xafd}, {0x194, 0x0, 0x161}, {0x198, 0x0, 0x2c2}, {0x19c, 0x0, 0x583}, {0x1a0, 0x0, 0xb05}, {-1, 0, 0}, }; struct sequence t8103_ane_tunables[] = { {t8103_ane_pmgr_entry, 0x26a000000}, {t8103_ane_dart_entry, 0x26b800000}, {t8103_ane_dart_entry, 0x26b810000}, {t8103_ane_dart_entry, 0x26b820000}, {t8103_ane_dapf_entry, 0x26b804000}, {t8103_ane_dpe_sys_entry, 0x26b8f0000}, {t8103_ane_perf_entry, 0x26b908000}, {t8103_ane_dpe_soc_entry, 0x26b8f4000}, {NULL, -1}, }; static void tunables_apply(struct sequence *seq) { struct entry *entry = seq->entry; while (entry->offset != UINT32_MAX) { mask32(seq->base + entry->offset, entry->clear, entry->set); entry++; } } int power_and_apply(const char *path, struct sequence *seq) { if (pmgr_adt_power_enable(path) < 0) { printf("tunables: Failed to enable power: %s\n", path); return -1; } while (seq->base != UINT32_MAX) { tunables_apply(seq); seq++; } if (pmgr_adt_power_disable(path) < 0) { printf("tunables: Failed to disable power: %s\n", path); return -1; } return 0; } int tunables_apply_static(void) { int ret = 0; switch (chip_id) { case T8103: ret |= power_and_apply("/arm-io/sgx", t8103_agx_tunables); ret |= power_and_apply("/arm-io/ane", t8103_ane_tunables); break; case T8112: ret |= power_and_apply("/arm-io/sgx", t8112_agx_tunables); break; case T6000: case T6001: case T6002: ret |= power_and_apply("/arm-io/sgx", t600x_agx_tunables); break; default: break; } return ret ? -1 : 0; }