mirror of
https://github.com/AsahiLinux/m1n1
synced 2024-11-21 22:23:05 +00:00
pmgr: Fix struct for older SoCs
At some point Apple ran out of bits and have to widen the device field to 16-bit. This adds support for the old 8-bit layout. Signed-off-by: Nick Chan <towinchenmi@gmail.com>
This commit is contained in:
parent
9ca6d1c16f
commit
fb59dc03ca
1 changed files with 50 additions and 13 deletions
63
src/pmgr.c
63
src/pmgr.c
|
@ -21,14 +21,24 @@
|
||||||
#define PMGR_FLAG_VIRTUAL 0x10
|
#define PMGR_FLAG_VIRTUAL 0x10
|
||||||
|
|
||||||
struct pmgr_device {
|
struct pmgr_device {
|
||||||
u32 flags;
|
u8 flags;
|
||||||
u16 parent[2];
|
u16 unk1;
|
||||||
u8 unk1[2];
|
u8 id1;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
u8 parent[2];
|
||||||
|
u8 unk2[2];
|
||||||
|
} u8id;
|
||||||
|
struct {
|
||||||
|
u16 parent[2];
|
||||||
|
} u16id;
|
||||||
|
};
|
||||||
|
u8 unk3[2];
|
||||||
u8 addr_offset;
|
u8 addr_offset;
|
||||||
u8 psreg_idx;
|
u8 psreg_idx;
|
||||||
u8 unk2[14];
|
u8 unk4[14];
|
||||||
u16 id;
|
u16 id2;
|
||||||
u8 unk3[4];
|
u8 unk5[4];
|
||||||
const char name[0x10];
|
const char name[0x10];
|
||||||
} PACKED;
|
} PACKED;
|
||||||
|
|
||||||
|
@ -44,6 +54,8 @@ static u32 pmgr_ps_regs_len = 0;
|
||||||
static const struct pmgr_device *pmgr_devices = NULL;
|
static const struct pmgr_device *pmgr_devices = NULL;
|
||||||
static u32 pmgr_devices_len = 0;
|
static u32 pmgr_devices_len = 0;
|
||||||
|
|
||||||
|
static bool pmgr_u8id = false;
|
||||||
|
|
||||||
static uintptr_t pmgr_get_psreg(u8 idx)
|
static uintptr_t pmgr_get_psreg(u8 idx)
|
||||||
{
|
{
|
||||||
if (idx * 12 >= pmgr_ps_regs_len) {
|
if (idx * 12 >= pmgr_ps_regs_len) {
|
||||||
|
@ -76,11 +88,19 @@ int pmgr_set_mode(uintptr_t addr, u8 target_mode)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u16 pmgr_adt_get_id(const struct pmgr_device *device)
|
||||||
|
{
|
||||||
|
if (pmgr_u8id)
|
||||||
|
return device->id1;
|
||||||
|
else
|
||||||
|
return device->id2;
|
||||||
|
}
|
||||||
|
|
||||||
static int pmgr_find_device(u16 id, const struct pmgr_device **device)
|
static int pmgr_find_device(u16 id, const struct pmgr_device **device)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < pmgr_devices_len; ++i) {
|
for (size_t i = 0; i < pmgr_devices_len; ++i) {
|
||||||
const struct pmgr_device *i_device = &pmgr_devices[i];
|
const struct pmgr_device *i_device = &pmgr_devices[i];
|
||||||
if (i_device->id != id)
|
if (pmgr_adt_get_id(i_device) != id)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
*device = i_device;
|
*device = i_device;
|
||||||
|
@ -102,6 +122,17 @@ static uintptr_t pmgr_device_get_addr(u8 die, const struct pmgr_device *device)
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pmgr_adt_get_parents(const struct pmgr_device *device, u16 parent[2])
|
||||||
|
{
|
||||||
|
if (pmgr_u8id) {
|
||||||
|
parent[0] = device->u8id.parent[0];
|
||||||
|
parent[1] = device->u8id.parent[1];
|
||||||
|
} else {
|
||||||
|
parent[0] = device->u16id.parent[0];
|
||||||
|
parent[1] = device->u16id.parent[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int pmgr_set_mode_recursive(u8 die, u16 id, u8 target_mode, bool recurse)
|
static int pmgr_set_mode_recursive(u8 die, u16 id, u8 target_mode, bool recurse)
|
||||||
{
|
{
|
||||||
if (!pmgr_initialized) {
|
if (!pmgr_initialized) {
|
||||||
|
@ -127,9 +158,10 @@ static int pmgr_set_mode_recursive(u8 die, u16 id, u8 target_mode, bool recurse)
|
||||||
|
|
||||||
if (recurse)
|
if (recurse)
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
if (device->parent[i]) {
|
u16 parents[2];
|
||||||
u16 parent = FIELD_GET(PMGR_DEVICE_ID, device->parent[i]);
|
pmgr_adt_get_parents(device, parents);
|
||||||
int ret = pmgr_set_mode_recursive(die, parent, target_mode, true);
|
if (parents[i]) {
|
||||||
|
int ret = pmgr_set_mode_recursive(die, parents[i], target_mode, true);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -346,6 +378,9 @@ int pmgr_init(void)
|
||||||
for (size_t i = 0; i < pmgr_devices_len; ++i) {
|
for (size_t i = 0; i < pmgr_devices_len; ++i) {
|
||||||
const struct pmgr_device *device = &pmgr_devices[i];
|
const struct pmgr_device *device = &pmgr_devices[i];
|
||||||
|
|
||||||
|
if (device->id1)
|
||||||
|
pmgr_u8id = true;
|
||||||
|
|
||||||
if ((device->flags & PMGR_FLAG_VIRTUAL))
|
if ((device->flags & PMGR_FLAG_VIRTUAL))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -357,10 +392,12 @@ int pmgr_init(void)
|
||||||
|
|
||||||
if (reg & PMGR_AUTO_ENABLE || FIELD_GET(PMGR_PS_TARGET, reg) == PMGR_PS_ACTIVE) {
|
if (reg & PMGR_AUTO_ENABLE || FIELD_GET(PMGR_PS_TARGET, reg) == PMGR_PS_ACTIVE) {
|
||||||
for (int j = 0; j < 2; j++) {
|
for (int j = 0; j < 2; j++) {
|
||||||
if (device->parent[j]) {
|
u16 parent[2];
|
||||||
|
pmgr_adt_get_parents(device, parent);
|
||||||
|
if (parent[j]) {
|
||||||
const struct pmgr_device *pdevice;
|
const struct pmgr_device *pdevice;
|
||||||
if (pmgr_find_device(device->parent[j], &pdevice)) {
|
if (pmgr_find_device(parent[j], &pdevice)) {
|
||||||
printf("pmgr: Failed to find parent #%d for %s\n", device->parent[j],
|
printf("pmgr: Failed to find parent #%d for %s\n", parent[j],
|
||||||
device->name);
|
device->name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue