50 lines
3.4 KiB
Markdown
50 lines
3.4 KiB
Markdown
## DT binding
|
|
|
|
The "gpio,t8101" nodes in the ADT represent a GPIO controller with pinmux facilities.
|
|
Judging from the Corellium code base the pins can be switched between "gpio" functionality and "periph" functionality.
|
|
There may be more options though sine there are unknown bits right next to the bit that controls switching between those two modes.
|
|
Given that the controller implements pinmux functionality we need to model this hardware as a pinctrl node in the FDT. This can be done entirely using generic pinctrl/pinmux/gpio binding properties:
|
|
|
|
```
|
|
#define APPLE_PINMUX(pin, func) ((pin) | ((func) << 16))
|
|
|
|
pinctrl: pinctrl@23c100000 {
|
|
compatible = "apple,t8103-pinctrl";
|
|
reg = <0x2 0x3c100000 0x0 0x100000>;
|
|
clocks = <&gpio_clk>;
|
|
|
|
gpio-controller;
|
|
#gpio-cells = <2>;
|
|
gpio-ranges = <&pinctrl 0 0 212>;
|
|
|
|
pcie_pins: pcie-pins {
|
|
pinmux = <APPLE_PINMUX(150, 1)>,
|
|
<APPLE_PINMUX(151, 1)>,
|
|
<APPLE_PINMUX(32, 1)>;
|
|
};
|
|
};
|
|
```
|
|
Using `pinmux` has the benefit that we don't have to invent names for pins and functions and hardcode those in the driver.
|
|
The purpose of pins is likely to vary between SoCs and between controllers on a single SoC. There are four controllers on the M1 SoC!
|
|
The example here uses a simple split of the 32-bit pinmux cell.
|
|
The lower 16 bits encode the pin number whereas the upper 16 bits encode the pin function.
|
|
It is unlikely we need the full 16 bits to encode the pin function so we repurpose some of those bits if we need to in the future.
|
|
|
|
Some open questions:
|
|
* Should the compatible string be "apple,t8101-gpio" given the name of the node in the ADT? Or should we mention both?
|
|
* The controllers seem to provide interrupt functionality as well. The standard bindings allow for an `interrupt-controller` property so this this can be handled as well. There are (up to) 7 AIC interrupts per controllers each handling a group of GPIO pins. It seems GPIO pins can be freely assigned to a group although the ADT contains properties that suggest that not all groups are functional on some of the controllers.
|
|
|
|
The gpio controller provides interrupt functionality to devices which uses it as `interrupt-parent`. Those devices have 2 `#interrupt-cells`. The first cell specifies the GPIO pin. The meaning of the second pin is unknown. `audio-tas5770L-speaker`, `audio-codec-output`, `hpmBusManager` use 0x1, `wlan` 0x2 and `bluetooth` 0x2000002. The second cells' value does not seem to correspond to the pin's configuration register.
|
|
|
|
device | pin | 2nd cell | config by iboot (mac mini)
|
|
---------------------- | --- | --------- | --------------------------
|
|
hpmBusManager | 106 | 0x1 | 0x76b80
|
|
bluetooth | 136 | 0x2000002 | 0x76a80
|
|
audio-tas5770L-speaker | 182 | 0x1 | 0x76b81
|
|
audio-codec-output | 183 | 0x1 | 0x76b81
|
|
wlan | 196 | 0x2 | 0x76ac0
|
|
|
|
Observed Mac OS behavior for device `/arm-io/gpio` at address `0x23c100000`:
|
|
1. read pin config (4 bytes) from offset `0x0000` to `0x34c` (212 pins)
|
|
2. clear interrupts for all 7 groups? writing ones 7 x 4 bytes in seven groups to the offsets `0x800`, `0x840`, `0x880`, `0x8C0`, `0x900`, `0x940`, `0x980`
|