diff --git a/boot/m1n1/patches/orchard/0021-kboot-Pass-the-A9-AOP-s-boot-arguments-and-sensor-ca.patch b/boot/m1n1/patches/orchard/0021-kboot-Pass-the-A9-AOP-s-boot-arguments-and-sensor-ca.patch new file mode 100644 index 00000000..6a30fc37 --- /dev/null +++ b/boot/m1n1/patches/orchard/0021-kboot-Pass-the-A9-AOP-s-boot-arguments-and-sensor-ca.patch @@ -0,0 +1,116 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Berkay=20K=C3=B6sebay?= +Date: Mon, 2 Nov 2026 15:07:08 +0100 +Subject: [PATCH] kboot: Pass the A9 AOP's boot arguments and sensor + calibration + +The A9's AOP firmware takes more than the ECID from its loader: the AOP +target number (iop-aop-nub aop-target), the chip's ID (/chosen chip-id) +and revision (/arm-io chip-revision). Its accelerometer, gyroscope and +pressure sensor also send no reports until the driver has given them the +unit's factory calibration, which iBoot resolves from syscfg into the +sensors' nodes below iop-aop-nub. + +Copy the three numbers into the AOP's node (alias aop) as +apple,aop-target, apple,chip-id and apple,chip-revision, and each +sensor's calibration properties into the AOP's child node of the same +name, prefixed with "apple,". Unprovisioned "syscfg/" references and +nodes the device tree doesn't have are skipped. The orientation +properties are not copied: the A9 firmware rejects them and the board's +mount-matrix describes the mounting. + +The values are the unit's own and never leave the device: the kernel +sends them to the AOP and nothing else. + +Assisted-by: LLM +--- + src/kboot.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 68 insertions(+), 1 deletion(-) + +diff --git a/src/kboot.c b/src/kboot.c +index ebd6282..7ce9d72 100644 +--- a/src/kboot.c ++++ b/src/kboot.c +@@ -1005,6 +1005,73 @@ static int dt_set_als(void) + return 0; + } + ++/* ++ * The A9's AOP firmware also takes the AOP target number and the chip's ID and ++ * revision in its boot arguments, and each motion sensor's factory ++ * calibration, which iBoot resolves from syscfg into the sensor's node below ++ * iop-aop-nub. Copy them into the AOP's node and its sensor child nodes of the ++ * same name; the calibration keeps its name with an "apple," prefix. ++ */ ++static const char *const aop_sensor_calibrations[] = { ++ "low-temp-accel-offset", ++ "accel-sensitivity-calibration", ++ "accel-range-sensitivity-cal", ++ "accel-interrupt-calibration", ++ "gyro-sensitivity-calibration", ++ "gyro-range-sensitivity-cal", ++ "gyro-interrupt-calibration", ++ "gyro-trim-calibration", ++ "pressure-offset-calibration", ++ "pressure-accel-sensitivity", ++ "pressure-heater-resistance", ++}; ++ ++static int dt_set_aop_sensors(int node) ++{ ++ int nub = adt_path_offset(adt, "/arm-io/aop/iop-aop-nub"); ++ if (nub < 0) ++ return 0; ++ ++ u32 val; ++ if (ADT_GETPROP(adt, nub, "aop-target", &val) >= 0 && ++ fdt_setprop_u32(dt, node, "apple,aop-target", val)) ++ bail("FDT: failed to set apple,aop-target\n"); ++ ++ int chosen = adt_path_offset(adt, "/chosen"); ++ if (chosen >= 0 && ADT_GETPROP(adt, chosen, "chip-id", &val) >= 0 && ++ fdt_setprop_u32(dt, node, "apple,chip-id", val)) ++ bail("FDT: failed to set apple,chip-id\n"); ++ ++ int arm_io = adt_path_offset(adt, "/arm-io"); ++ if (arm_io >= 0 && ADT_GETPROP(adt, arm_io, "chip-revision", &val) >= 0 && ++ fdt_setprop_u32(dt, node, "apple,chip-revision", val)) ++ bail("FDT: failed to set apple,chip-revision\n"); ++ ++ int sensor = nub; ++ ADT_FOREACH_CHILD(adt, sensor) ++ { ++ const char *name = adt_get_name(adt, sensor); ++ ++ for (size_t i = 0; i < ARRAY_SIZE(aop_sensor_calibrations); i++) { ++ u32 len; ++ const u8 *blob = adt_getprop(adt, sensor, aop_sensor_calibrations[i], &len); ++ if (!blob || !len || (len >= 7 && !memcmp(blob, "syscfg/", 7))) ++ continue; ++ ++ /* Earlier properties may have moved the sensor's node. */ ++ int child = fdt_subnode_offset(dt, node, name); ++ if (child < 0) ++ break; ++ ++ char prop[64]; ++ snprintf(prop, sizeof(prop), "apple,%s", aop_sensor_calibrations[i]); ++ if (fdt_setprop(dt, child, prop, blob, len)) ++ bail("FDT: failed to set %s/%s\n", name, prop); ++ } ++ } ++ return 0; ++} ++ + /* + * The AOP's firmware carries the chip's ECID in its boot arguments. Pass it + * only to the AOP's node; the driver removes it from the tree once read. +@@ -1028,7 +1095,7 @@ static int dt_set_aop(void) + + if (fdt_setprop_u64(dt, node, "apple,ecid", ecid)) + bail("FDT: failed to set apple,ecid\n"); +- return 0; ++ return dt_set_aop_sensors(node); + } + + static int dt_set_multitouch(void)