diff --git a/Documentation/devicetree/bindings/arm/pmu.yaml b/Documentation/devicetree/bindings/arm/pmu.yaml index f47baaefcdacfd..97800a991f2084 100644 --- a/Documentation/devicetree/bindings/arm/pmu.yaml +++ b/Documentation/devicetree/bindings/arm/pmu.yaml @@ -22,8 +22,14 @@ properties: - apm,potenza-pmu - apple,avalanche-pmu - apple,blizzard-pmu + - apple,cyclone-pmu - apple,firestorm-pmu + - apple,fusion-pmu - apple,icestorm-pmu + - apple,monsoon-pmu + - apple,mistral-pmu + - apple,twister-pmu + - apple,typhoon-pmu - arm,armv8-pmuv3 # Only for s/w models - arm,arm1136-pmu - arm,arm1176-pmu diff --git a/Documentation/devicetree/bindings/bus/apple,usb-complex.yaml b/Documentation/devicetree/bindings/bus/apple,usb-complex.yaml new file mode 100644 index 00000000000000..38c02bfa2b2906 --- /dev/null +++ b/Documentation/devicetree/bindings/bus/apple,usb-complex.yaml @@ -0,0 +1,120 @@ +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/bus/apple,usb-complex.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Apple USB Complex + +maintainers: + - Nick Chan + +description: | + Apple USB Complex is a power-mangaged bus that includes remap registers + that allows using USB hardware blocks with 32-bit DMA, even without + a real IOMMU. For a device connected to the complex to be used, the + PM domain associated with the bus must first be turned on, and the + remap registers be configured. + + The bindings for Apple USB Complex extend the bindings for "simple-pm-bus". + +allOf: + - $ref: simple-pm-bus.yaml# + +# We need a select here so we don't match all nodes with 'simple-pm-bus'. +select: + properties: + compatible: + contains: + enum: + - apple,s5l8960x-usb-complex + - apple,t8011-usb-complex + - apple,t8015-usb-complex + required: + - compatible + +properties: + compatible: + oneOf: + - items: + - enum: + - apple,t7000-usb-complex + - apple,s8000-usb-complex + - apple,t8010-usb-complex + - const: apple,s5l8960x-usb-complex + - const: simple-pm-bus + - items: + - enum: + - apple,s5l8960x-usb-complex + - apple,t8011-usb-complex + - apple,t8015-usb-complex + - const: simple-pm-bus + + reg: + description: | + Register ranges for the USB Complex. Some hardware has a USB2 PHY + in the middle that are handled by another driver and thus need + two ranges to avoid conflicts. + minItems: 1 + maxItems: 2 + + dma-ranges: + description: | + A single range for the memory region to be remapped. It must be a + 4 GiB range with DMA addresses starting at 0 and are typically + mapped to the start of DRAM. + maxItems: 1 + + nonposted-mmio: true + +patternProperties: + "^.*@[0-9a-f]+$": + description: Hardware attached to the bus + type: object + + required: + - reg + +required: + - compatible + - reg + - dma-ranges + +unevaluatedProperties: false + +examples: + - | + soc { + #address-cells = <2>; + #size-cells = <2>; + + bus@20c000000 { + compatible = "apple,t8011-usb-complex", "simple-pm-bus"; + #address-cells = <2>; + #size-cells = <2>; + dma-ranges = <0x0 0x00000000 0x8 0x00000000 0x1 0x00000000>; + nonposted-mmio; + ranges; + + reg = <0x2 0x0c000000 0x0 0x40>, + <0x2 0x0c000060 0x0 0x40>; + power-domains = <&ps_usb>; + }; + }; + + - | + soc { + #address-cells = <2>; + #size-cells = <2>; + + bus@21c000000 { + compatible = "apple,t7000-usb-complex", "apple,s5l8960x-usb-complex", "simple-pm-bus"; + #address-cells = <2>; + #size-cells = <2>; + dma-ranges = <0x0 0x00000000 0x8 0x00000000 0x1 0x00000000>; + nonposted-mmio; + ranges; + + reg = <0x2 0x1c900000 0x0 0x100>; + power-domains = <&ps_usb>; + }; + }; diff --git a/Documentation/devicetree/bindings/hwmon/apple,smc-hwmon.yaml b/Documentation/devicetree/bindings/hwmon/apple,smc-hwmon.yaml new file mode 100644 index 00000000000000..2eec317bc4b3e6 --- /dev/null +++ b/Documentation/devicetree/bindings/hwmon/apple,smc-hwmon.yaml @@ -0,0 +1,86 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/hwmon/apple,smc-hwmon.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Apple SMC Hardware Monitoring + +description: + Apple's System Management Controller (SMC) exposes a vast array of + hardware monitoring sensors, including temperature probes, current and + voltage sense, power meters, and fan speeds. It also provides endpoints + to manually control the speed of each fan individually. Each Apple + Silicon device exposes a different set of endpoints via SMC keys. This + is true even when two machines share an SoC. The CPU core temperature + sensor keys on an M1 Mac mini are different to those on an M1 MacBook + Pro, for example. + +maintainers: + - James Calligeros + +$defs: + sensor: + type: object + + properties: + apple,key-id: + $ref: /schemas/types.yaml#/definitions/string + pattern: "^[A-Za-z0-9]{4}$" + description: The SMC FourCC key of the desired sensor. + Must match the node's suffix. + + label: + description: Human-readable name for the sensor + + required: + - apple,key-id + +properties: + compatible: + const: apple,smc-hwmon + +patternProperties: + "^current-[A-Za-z0-9]{4}$": + $ref: "#/$defs/sensor" + unevaluatedProperties: false + + "^fan-[A-Za-z0-9]{4}$": + $ref: "#/$defs/sensor" + unevaluatedProperties: false + + properties: + apple,fan-minimum: + $ref: /schemas/types.yaml#/definitions/string + pattern: "^[A-Za-z0-9]{4}$" + description: SMC key containing the fan's minimum speed + + apple,fan-maximum: + $ref: /schemas/types.yaml#/definitions/string + pattern: "^[A-Za-z0-9]{4}$" + description: SMC key containing the fan's maximum speed + + apple,fan-target: + $ref: /schemas/types.yaml#/definitions/string + pattern: "^[A-Za-z0-9]{4}$" + description: Writeable endpoint for setting desired fan speed + + apple,fan-mode: + $ref: /schemas/types.yaml#/definitions/string + pattern: "^[A-Za-z0-9]{4}$" + description: Writeable key to enable/disable manual fan control + + + "^power-[A-Za-z0-9]{4}$": + $ref: "#/$defs/sensor" + unevaluatedProperties: false + + "^temperature-[A-Za-z0-9]{4}$": + $ref: "#/$defs/sensor" + unevaluatedProperties: false + + "^voltage-[A-Za-z0-9]{4}$": + $ref: "#/$defs/sensor" + unevaluatedProperties: false + +additionalProperties: false diff --git a/Documentation/devicetree/bindings/leds/backlight/apple,pmic-bl.yaml b/Documentation/devicetree/bindings/leds/backlight/apple,pmic-bl.yaml new file mode 100644 index 00000000000000..34cc7d545124d0 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/backlight/apple,pmic-bl.yaml @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/leds/backlight/apple,pmic-bl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Apple PMIC backlight + +maintainers: + - Nick Chan + +description: + This module is part of Apple PMICs. For more details see + ../mfd/apple,pmic.yaml. + + A backlight WLED interface in Apple PMICs. There are two variants + differing in how the backlight value is encoded in the registers. + +allOf: + - $ref: common.yaml# + +properties: + compatible: + oneOf: + - items: + - const: apple,arabela-pmic-bl + - const: apple,anya-pmic-bl + - items: + - const: apple,august-pmic-bl + - const: apple,aria-pmic-bl + - const: apple,anya-pmic-bl + - const: apple,aria-pmic-bl + + reg: + maxItems: 1 + +required: + - compatible + - reg + +additionalProperties: false diff --git a/Documentation/devicetree/bindings/mfd/apple,pmic.yaml b/Documentation/devicetree/bindings/mfd/apple,pmic.yaml new file mode 100644 index 00000000000000..8bf64a835559e6 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/apple,pmic.yaml @@ -0,0 +1,152 @@ +--- +$id: http://devicetree.org/schemas/mfd/apple,pmic.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Apple PMICs + +maintainers: + - Nick Chan + +description: | + Apple SoCs came with PMICs designed by Dialog Semiconductor before + Apple switched to their own PMIC designs. However, the parts used + by Apple appears to be sigificantly different from public parts + offered by dialog. + + On A7 - A10X SoCs, they are attached over I2C. On A11 and T2 the + PMIC is attached via SPMI. + + This binding describes simple MFD - I2C/SPMI device with 16-bit + register address and 8-bit values that allows subdevices like RTC, + power-off control, backlight and nvmem to be described. + + See also bindings/nvmem/apple,spmi-nvmem.yaml for a simpler + binding with only nvmem functions exposed used for newer PMICs. + +properties: + compatible: + oneOf: + - items: + - enum: + - apple,adelyn-pmic + - apple,adi-pmic + - apple,amber-pmic + - apple,angel-pmic + - apple,antigua-pmic + - apple,anya-pmic + - apple,arabela-pmic + - apple,aria-pmic + - apple,august-pmic + - apple,autumn-pmic + - const: apple,i2c-pmic + - items: + - enum: + - apple,agnes-pmic + - apple,calpe-pmic + - const: apple,spmi-pmic + + reg: + maxItems: 1 + + "#address-cells": + const: 1 + + "#size-cells": + const: 1 + +patternProperties: + "^backlight(@[0-9a-f]+)?$": + $ref: /schemas/leds/backlight/apple,pmic-bl.yaml + + "^rtc(@[0-9a-f]+)?$": + $ref: /schemas/rtc/apple,pmic-rtc.yaml + + "^nvmem(@[0-9a-f]+)?$": + $ref: /schemas/nvmem/apple,pmic-nvmem.yaml + +required: + - compatible + - reg + - "#address-cells" + - "#size-cells" + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + pmic@3c { + compatible = "apple,arabela-pmic", "apple,i2c-pmic"; + reg = <0x3c>; + #address-cells = <1>; + #size-cells = <1>; + + rtc@500 { + compatible = "apple,arabela-pmic-rtc", "apple,amber-pmic-rtc"; + reg = <0x500 0x10>; + nvmem-cells = <&rtc_offset_0>; + nvmem-cell-names = "rtc_offset"; + }; + + backlight@600 { + compatible = "apple,arabela-pmic-bl", "apple,anya-pmic-bl"; + reg = <0x600 0x2>; + }; + + nvmem@4000 { + compatible = "apple,pmic-nvmem"; + reg = <0x4000 0x28>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + rtc_offset_0: rtc-offset@4 { + reg = <0x4 0x4>; + }; + }; + }; + }; + }; + + - | + + #include + + spmi { + #address-cells = <2>; + #size-cells = <0>; + + pmic@f { + compatible = "apple,agnes-pmic", "apple,spmi-pmic"; + reg = <0xf SPMI_USID>; + #address-cells = <1>; + #size-cells = <1>; + + rtc@1400 { + compatible = "apple,agnes-pmic-rtc", "apple,antigua-pmic-rtc"; + reg = <0x1400 0x10>; + nvmem-cells = <&rtc_offset_1>; + nvmem-cell-names = "rtc_offset"; + }; + + nvmem@6000 { + compatible = "apple,pmic-nvmem"; + reg = <0x6000 0x300>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + rtc_offset_1: rtc-offset@4 { + reg = <0x4 0x4>; + }; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/mfd/apple,smc.yaml b/Documentation/devicetree/bindings/mfd/apple,smc.yaml index 0410e712c900a7..16702250a5c4e0 100644 --- a/Documentation/devicetree/bindings/mfd/apple,smc.yaml +++ b/Documentation/devicetree/bindings/mfd/apple,smc.yaml @@ -17,7 +17,10 @@ properties: compatible: oneOf: - items: - - const: apple,t6020-smc + - enum: + - apple,t6020-smc + - apple,t8012-smc + - apple,t8015-smc - const: apple,t8103-smc - items: - enum: @@ -40,6 +43,10 @@ properties: mboxes: maxItems: 1 + power-domains: + maxItems: 1 + description: SMC CPU power domain + gpio: $ref: /schemas/gpio/apple,smc-gpio.yaml @@ -49,6 +56,9 @@ properties: rtc: $ref: /schemas/rtc/apple,smc-rtc.yaml + hwmon: + $ref: /schemas/hwmon/apple,smc-hwmon.yaml + additionalProperties: false required: @@ -89,5 +99,38 @@ examples: nvmem-cells = <&rtc_offset>; nvmem-cell-names = "rtc_offset"; }; + + hwmon { + compatible = "apple,smc-hwmon"; + + current-ID0R { + apple,key-id = "ID0R"; + label = "AC Input Current"; + }; + + fan-F0Ac { + apple,key-id = "F0Ac"; + apple,fan-minimum = "F0Mn"; + apple,fan-maximum = "F0Mx"; + apple,fan-target = "F0Tg"; + apple,fan-mode = "F0Md"; + label = "Fan 1"; + }; + + power-PSTR { + apple,key-id = "PSTR"; + label = "Total System Power"; + }; + + temperature-TW0P { + apple,key-id = "TW0P"; + label = "WiFi/BT Module Temperature"; + }; + + voltage-VD0R { + apple,key-id = "VD0R"; + label = "AC Input Voltage"; + }; + }; }; }; diff --git a/Documentation/devicetree/bindings/nvmem/apple,pmic-nvmem.yaml b/Documentation/devicetree/bindings/nvmem/apple,pmic-nvmem.yaml new file mode 100644 index 00000000000000..b184c10ed08779 --- /dev/null +++ b/Documentation/devicetree/bindings/nvmem/apple,pmic-nvmem.yaml @@ -0,0 +1,37 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/nvmem/apple,pmic-nvmem.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Apple PMIC NVMEM + +description: | + This module is part of Apple PMICs. For more details see + ../mfd/apple,pmic.yaml. + + NVMEM cells found in Apple PMICs are used to store information + including RTC offset and boot failure count. + + See also bindings/nvmem/apple,spmi-nvmem.yaml which describes + PMICs with only NVMEM functions exposed. + +maintainers: + - Nick Chan + +allOf: + - $ref: nvmem.yaml# + +properties: + compatible: + const: apple,pmic-nvmem + + reg: + maxItems: 1 + +required: + - compatible + - reg + +unevaluatedProperties: false +... diff --git a/Documentation/devicetree/bindings/phy/apple,ausb-phy.yaml b/Documentation/devicetree/bindings/phy/apple,ausb-phy.yaml new file mode 100644 index 00000000000000..9c51d1d0fb42bc --- /dev/null +++ b/Documentation/devicetree/bindings/phy/apple,ausb-phy.yaml @@ -0,0 +1,81 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/apple,ausb-phy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Apple AUSB PHY + +maintainers: + - Nick Chan + +description: + Apple AUSB PHY is the USB PHY used in Apple SoCs before the introduced + of the Apple Type-C PHY (ATCPHY). It supports USB 2.0, and, on T8011, + USB 3.0 operation. This binding describes USB 2.0 operation only as + supported by the driver. + +properties: + compatible: + items: + - enum: + - apple,s5l8960x-ausb-phy + - apple,t7000-ausb-phy + - apple,s8000-ausb-phy + - apple,t8010-ausb-phy + - apple,t8011-ausb-phy + - apple,t8015-ausb-phy + - const: apple,ausb-phy + + reg: + maxItems: 1 + + "#phy-cells": + const: 1 + + mode-switch: + type: boolean + description: + The PHY handles muxing between USB 2.0 Host and Device modes. + + power-domains: + minItems: 1 + maxItems: 1 + + apple,cfg0-device: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Tunable 0 for device mode. + + apple,cfg1-device: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Tunable 1 for device mode. + + apple,cfg0-host: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Tunable 0 for host mode. + + apple,cfg1-host: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Tunable 1 for host mode. + +required: + - compatible + - reg + - "#phy-cells" + # The binding also requires tunables and they are filled by loader + +additionalProperties: false + +examples: + - | + phy@20c000060 { + compatible = "apple,t8015-ausb-phy", "apple,ausb-phy"; + reg = <0x2 0x0c000060 0x0 0x20>; + #phy-cells = <1>; + power-domains = <&ps_usbctlreg>; + /* Tunables to be filled by loader */ + }; diff --git a/Documentation/devicetree/bindings/power/reset/apple,smc-reboot.yaml b/Documentation/devicetree/bindings/power/reset/apple,smc-reboot.yaml index ce5ed88493cdb6..dff15674948544 100644 --- a/Documentation/devicetree/bindings/power/reset/apple,smc-reboot.yaml +++ b/Documentation/devicetree/bindings/power/reset/apple,smc-reboot.yaml @@ -16,7 +16,10 @@ maintainers: properties: compatible: - const: apple,smc-reboot + items: + - enum: + - apple,smc-reboot + - apple,t8015-smc-reboot nvmem-cells: items: @@ -32,6 +35,12 @@ properties: - const: boot_error_count - const: panic_count + prc-poweroff: + type: boolean + description: Set to one by loader if the current device is a PRC SKU. With + this property, attempting to power off the device when it is connected + to power will show a battery indicator after rebooting. + required: - compatible - nvmem-cells diff --git a/Documentation/devicetree/bindings/rtc/apple,pmic-rtc.yaml b/Documentation/devicetree/bindings/rtc/apple,pmic-rtc.yaml new file mode 100644 index 00000000000000..de0635797c9834 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/apple,pmic-rtc.yaml @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/rtc/apple,pmic-rtc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Apple PMIC RTC device + +maintainers: + - Nick Chan + +description: + This module is part of Apple PMICs. For more details + see ../mfd/apple,pmic.yaml. + + An RTC device that is part of the PMIC. Additionally an + offset stored in an nvmem cell is required to compute the + current date and time. + +properties: + compatible: + oneOf: + - items: + - enum: + - apple,adi-pmic-rtc + - apple,anya-pmic-rtc + - apple,arabela-pmic-rtc + - const: apple,amber-pmic-rtc + - items: + - enum: + - apple,aria-pmic-rtc + - apple,adelyn-pmic-rtc + - apple,angel-pmic-rtc + - apple,august-pmic-rtc + - apple,agnes-pmic-rtc + - apple,calpe-pmic-rtc # Counter also exposed via SMC + - const: apple,antigua-pmic-rtc + - const: apple,amber-pmic-rtc + - const: apple,antigua-pmic-rtc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + nvmem-cells: + items: + - description: + Upper 32 Bit of RTC offset in seconds. + # TODO: another cell for ticks specified in 32768 (2^15) Hz + # clock ticks + + nvmem-cell-names: + items: + - const: rtc_offset + + wakeup-source: true + +required: + - compatible + - reg + +additionalProperties: false +... diff --git a/Documentation/devicetree/bindings/soc/apple/apple,t8015-pmp.yaml b/Documentation/devicetree/bindings/soc/apple/apple,t8015-pmp.yaml new file mode 100644 index 00000000000000..f0f07ad07fa62c --- /dev/null +++ b/Documentation/devicetree/bindings/soc/apple/apple,t8015-pmp.yaml @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/soc/apple/apple,t8015-pmp.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Apple T8015 Power Management Processor + +maintainers: + - Nick Chan + +description: + Apple Power Management Processor regulates power consumption on Apple + SoCs. This bindings describes the variant found on T8015. + +properties: + compatible: + enum: + - apple,t8015-pmp + + reg: + items: + - description: ARM Cortex-A7 area + - description: CPU control area + - description: SRAM area + + reg-names: + items: + - const: akf + - const: control + - const: sram + + firmware-name: + maxItems: 1 + + mboxes: + maxItems: 1 + + mbox-names: + const: mbox + + power-domains: + maxItems: 1 + description: PMP CPU power domain + +additionalProperties: false + +required: + - compatible + - reg + - reg-names + - firmware-name + - mboxes + +examples: + - | + soc { + #address-cells = <2>; + #size-cells = <2>; + + pmp: pmp@232300000 { + compatible = "apple,t8015-pmp"; + reg = <0x2 0x32300000 0x0 0x8000>, + <0x2 0x32400000 0x0 0x10000>, + <0x2 0x32500000 0x0 0x20000>; + reg-names = "akf", "control", "sram"; + mboxes = <&pmp_mbox>; + mbox-names = "mbox"; + power-domains = <&ps_pmp>; + firmware-name = "apple/pmp-t8015.bin"; + }; + }; diff --git a/Documentation/devicetree/bindings/usb/dwc2.yaml b/Documentation/devicetree/bindings/usb/dwc2.yaml index 6c3a10991b8b6a..166d37cd921257 100644 --- a/Documentation/devicetree/bindings/usb/dwc2.yaml +++ b/Documentation/devicetree/bindings/usb/dwc2.yaml @@ -69,6 +69,14 @@ properties: - const: snps,dwc2 - const: samsung,s3c6400-hsotg - const: intel,socfpga-agilex-hsotg + - items: + - enum: + - apple,s5l8960x-dwc2 + - apple,s8000-dwc2 + - apple,t7000-dwc2 + - apple,t8010-dwc2 + - apple,t8015-dwc2 + - const: apple,dwc2 reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/usb/generic-ehci.yaml b/Documentation/devicetree/bindings/usb/generic-ehci.yaml index 55a5aa7d7a54e1..3c6c1ba6f0e2ac 100644 --- a/Documentation/devicetree/bindings/usb/generic-ehci.yaml +++ b/Documentation/devicetree/bindings/usb/generic-ehci.yaml @@ -30,6 +30,11 @@ properties: - allwinner,sun8i-v3s-ehci - allwinner,sun9i-a80-ehci - allwinner,sun20i-d1-ehci + - apple,s5l8960x-ehci + - apple,s8000-ehci + - apple,t7000-ehci + - apple,t8010-ehci + - apple,t8015-ehci - aspeed,ast2400-ehci - aspeed,ast2500-ehci - aspeed,ast2600-ehci diff --git a/Documentation/devicetree/bindings/usb/generic-ohci.yaml b/Documentation/devicetree/bindings/usb/generic-ohci.yaml index d42f448fa20446..ffde451792cf80 100644 --- a/Documentation/devicetree/bindings/usb/generic-ohci.yaml +++ b/Documentation/devicetree/bindings/usb/generic-ohci.yaml @@ -30,6 +30,11 @@ properties: - allwinner,sun8i-v3s-ohci - allwinner,sun9i-a80-ohci - allwinner,sun20i-d1-ohci + - apple,s5l8960x-ohci + - apple,s8000-ohci + - apple,t7000-ohci + - apple,t8010-ohci + - apple,t8015-ohci - brcm,bcm3384-ohci - brcm,bcm63268-ohci - brcm,bcm6328-ohci diff --git a/Documentation/devicetree/bindings/usb/generic-xhci.yaml b/Documentation/devicetree/bindings/usb/generic-xhci.yaml index 62678abd74b578..698a0239d032ac 100644 --- a/Documentation/devicetree/bindings/usb/generic-xhci.yaml +++ b/Documentation/devicetree/bindings/usb/generic-xhci.yaml @@ -34,6 +34,10 @@ properties: enum: - brcm,xhci-brcm-v2 - brcm,bcm7445-xhci + - description: Apple A10X SoC xHCI Controller + items: + - const: apple,t8011-xhci + - const: generic-xhci - description: Generic xHCI device const: xhci-platform deprecated: true @@ -80,7 +84,9 @@ allOf: properties: compatible: contains: - const: brcm,bcm2711-xhci + enum: + - apple,t8011-xhci + - brcm,bcm2711-xhci then: required: - power-domains diff --git a/MAINTAINERS b/MAINTAINERS index 9ec290e38b44ac..aeb5a11bdc348d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2523,17 +2523,21 @@ F: Documentation/devicetree/bindings/cpufreq/apple,cluster-cpufreq.yaml F: Documentation/devicetree/bindings/dma/apple,admac.yaml F: Documentation/devicetree/bindings/gpio/apple,smc-gpio.yaml F: Documentation/devicetree/bindings/gpu/apple,agx.yaml +F: Documentation/devicetree/bindings/hwmon/apple,smc-hwmon.yaml F: Documentation/devicetree/bindings/i2c/apple,i2c.yaml F: Documentation/devicetree/bindings/input/touchscreen/apple,z2-multitouch.yaml F: Documentation/devicetree/bindings/interrupt-controller/apple,* F: Documentation/devicetree/bindings/iommu/apple,dart.yaml F: Documentation/devicetree/bindings/iommu/apple,sart.yaml F: Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml +F: Documentation/devicetree/bindings/leds/backlight/apple,pmic-bl.yaml F: Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml F: Documentation/devicetree/bindings/mfd/apple,smc.yaml +F: Documentation/devicetree/bindings/mfd/apple,pmic.yaml F: Documentation/devicetree/bindings/net/bluetooth/brcm,bcm4377-bluetooth.yaml F: Documentation/devicetree/bindings/nvme/apple,nvme-ans.yaml F: Documentation/devicetree/bindings/nvmem/apple,efuses.yaml +F: Documentation/devicetree/bindings/nvmem/apple,pmic-nvmem.yaml F: Documentation/devicetree/bindings/nvmem/apple,spmi-nvmem.yaml F: Documentation/devicetree/bindings/pci/apple,pcie.yaml F: Documentation/devicetree/bindings/phy/apple,atcphy.yaml @@ -2541,6 +2545,7 @@ F: Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml F: Documentation/devicetree/bindings/power/apple* F: Documentation/devicetree/bindings/power/reset/apple,smc-reboot.yaml F: Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml +F: Documentation/devicetree/bindings/rtc/apple,pmic-rtc.yaml F: Documentation/devicetree/bindings/rtc/apple,smc-rtc.yaml F: Documentation/devicetree/bindings/spi/apple,spi.yaml F: Documentation/devicetree/bindings/spmi/apple,spmi.yaml @@ -2557,25 +2562,30 @@ F: drivers/hwmon/macsmc-hwmon.c F: drivers/pmdomain/apple/ F: drivers/i2c/busses/i2c-pasemi-core.c F: drivers/i2c/busses/i2c-pasemi-platform.c +F: drivers/input/misc/macsmc-input.c F: drivers/input/touchscreen/apple_z2.c F: drivers/iommu/apple-dart.c F: drivers/iommu/io-pgtable-dart.c F: drivers/irqchip/irq-apple-aic.c F: drivers/mfd/macsmc.c +F: drivers/mfd/simple-mfd-spmi.c F: drivers/nvme/host/apple.c F: drivers/nvmem/apple-efuses.c F: drivers/nvmem/apple-spmi-nvmem.c +F: drivers/nvmem/simple-mfd-nvmem.c F: drivers/phy/apple/ F: drivers/pinctrl/pinctrl-apple-gpio.c F: drivers/power/reset/macsmc-reboot.c F: drivers/power/supply/macsmc-power.c F: drivers/pwm/pwm-apple.c F: drivers/rtc/rtc-macsmc.c +F: drivers/rtc/rtc-apple-pmic.c F: drivers/soc/apple/* F: drivers/spi/spi-apple.c F: drivers/spmi/spmi-apple-controller.c F: drivers/usb/dwc3/dwc3-apple.c F: drivers/video/backlight/apple_dwi_bl.c +F: drivers/video/backlight/apple_pmic_bl.c F: drivers/watchdog/apple_wdt.c F: include/dt-bindings/interrupt-controller/apple-aic.h F: include/dt-bindings/pinctrl/apple.h diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index fe60738e5943ba..d56a942750b2d6 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -454,6 +454,31 @@ config AMPERE_ERRATUM_AC04_CPU_23 If unsure, say Y. +config ARM64_WORKAROUND_APPLE_FUSION + bool "Apple Hurricane-Zephyr: Variations between physical P-core and E-core presented as a single logical core" + depends on ARCH_APPLE + default y + help + This option disables 32-bit EL0 on Apple A10(X) to workaround + the physical "Zephyr" E-cores not supporting 32-bit EL0. + + In Apple A10(X), there are physical "Hurricane" performance and + "Zephyr" efficiency cores. They are presented as single cores that + can switch between E-mode and P-mode depending on the current p-state. + Only one of the core types may be active at a given time. + + However, only the "Hurricane" performance cores supports 32-bit EL0, + so this results in a logical core that can only execute 32-bit EL0 + in some states. Apple A10(X) only supports 16KB page sizes so + disabling 32-bit EL0 altogether is acceptable. + + The P-cores and E-cores also have different MPIDR values, so far + nothing needs to be done, as we do not use code paths that read MPIDR + after boot on A10(X). However, this is cursed enough such that this + workaround will also taint the kernel for it. + + If unsure, say Y. + config ARM64_WORKAROUND_CLEAN_CACHE bool diff --git a/arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi b/arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi index 8868df1538d685..c4ad5144a058f8 100644 --- a/arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi +++ b/arch/arm64/boot/dts/apple/s5l8960x-5s.dtsi @@ -58,3 +58,36 @@ &framebuffer0 { power-domains = <&ps_disp0 &ps_mipi_dsi>; }; + +&i2c0 { + status = "okay"; + + pmic@74 { + compatible = "apple,amber-pmic", "apple,i2c-pmic"; + reg = <0x74>; + #address-cells = <1>; + #size-cells = <1>; + + rtc@5c0 { + compatible = "apple,amber-pmic-rtc"; + reg = <0x5c0 0x10>; + nvmem-cells = <&rtc_offset>; + nvmem-cell-names = "rtc_offset"; + }; + + nvmem@4000 { + compatible = "apple,pmic-nvmem"; + reg = <0x4000 0x28>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + rtc_offset: rtc-offset@4 { + reg = <0x4 0x4>; + }; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi b/arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi index dd57eb1d34c06e..26b646f9da4af6 100644 --- a/arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi +++ b/arch/arm64/boot/dts/apple/s5l8960x-air1.dtsi @@ -54,3 +54,41 @@ &framebuffer0 { power-domains = <&ps_disp0 &ps_dp>; }; + +&i2c0 { + status = "okay"; + + pmic@3c { + compatible = "apple,anya-pmic", "apple,i2c-pmic"; + reg = <0x3c>; + #address-cells = <1>; + #size-cells = <1>; + + rtc@5c0 { + compatible = "apple,anya-pmic-rtc", "apple,amber-pmic-rtc"; + reg = <0x5c0 0x10>; + nvmem-cells = <&rtc_offset>; + nvmem-cell-names = "rtc_offset"; + }; + + backlight@600 { + compatible = "apple,anya-pmic-bl"; + reg = <0x600 0x2>; + }; + + nvmem@4000 { + compatible = "apple,pmic-nvmem"; + reg = <0x4000 0x28>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + rtc_offset: rtc-offset@4 { + reg = <0x4 0x4>; + }; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/apple/s5l8960x-common.dtsi b/arch/arm64/boot/dts/apple/s5l8960x-common.dtsi index 243480ca235669..a819f93cd470ab 100644 --- a/arch/arm64/boot/dts/apple/s5l8960x-common.dtsi +++ b/arch/arm64/boot/dts/apple/s5l8960x-common.dtsi @@ -11,6 +11,7 @@ / { aliases { + ausbphy0 = &ausbphy0; /* Used by loader */ serial0 = &serial0; }; diff --git a/arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi b/arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi index f3696d22e71cd1..c7a95fc01c8ee3 100644 --- a/arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi +++ b/arch/arm64/boot/dts/apple/s5l8960x-mini2.dtsi @@ -54,3 +54,41 @@ &framebuffer0 { power-domains = <&ps_disp0 &ps_dp>; }; + +&i2c0 { + status = "okay"; + + pmic@3c { + compatible = "apple,anya-pmic", "apple,i2c-pmic"; + reg = <0x3c>; + #address-cells = <1>; + #size-cells = <1>; + + rtc@5c0 { + compatible = "apple,anya-pmic-rtc", "apple,amber-pmic-rtc"; + reg = <0x5c0 0x10>; + nvmem-cells = <&rtc_offset>; + nvmem-cell-names = "rtc_offset"; + }; + + backlight@600 { + compatible = "apple,anya-pmic-bl"; + reg = <0x600 0x2>; + }; + + nvmem@4000 { + compatible = "apple,pmic-nvmem"; + reg = <0x4000 0x28>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + rtc_offset: rtc-offset@4 { + reg = <0x4 0x4>; + }; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/apple/s5l8960x.dtsi b/arch/arm64/boot/dts/apple/s5l8960x.dtsi index 462ffdd348fc89..2a747bec097854 100644 --- a/arch/arm64/boot/dts/apple/s5l8960x.dtsi +++ b/arch/arm64/boot/dts/apple/s5l8960x.dtsi @@ -11,6 +11,7 @@ #include #include #include +#include #include / { @@ -145,6 +146,68 @@ status = "disabled"; }; + bus@20c000000 { + compatible = "apple,s5l8960x-usb-complex", "simple-pm-bus"; + #address-cells = <2>; + #size-cells = <2>; + dma-ranges = <0x0 0x00000000 0x8 0x00000000 0x1 0x00000000>; + nonposted-mmio; + ranges; + + reg = <0x2 0x0c900000 0x0 0x100>; + power-domains = <&ps_usb>; + + ausbphy0: phy@20c000020 { + compatible = "apple,s5l8960x-ausb-phy", "apple,ausb-phy"; + reg = <0x2 0x0c000020 0x0 0x20>; + power-domains = <&ps_usbctrl>; + #phy-cells = <1>; + /* Tunables to be filled by loader */ + }; + + usbdev: usbdev@20c100000 { + compatible = "apple,s5l8960x-dwc2", "apple,dwc2"; + reg = <0x2 0x0c100000 0x0 0x10000>; + interrupts = ; + clocks = <&clkref>; + clock-names = "otg"; + phys = <&ausbphy0 PHY_TYPE_USB2>; + phy-names = "usb2-phy"; + power-domains = <&ps_usbotg>; + resets = <&ps_usbotg>; + dr_mode = "peripheral"; + }; +#if 0 + ehci0: usb-ehci@20c200000 { + compatible = "apple,s5l8960x-ehci", "generic-ehci"; + reg = <0x2 0x0c200000 0x0 0x10000>; + interrupts = ; + power-domains = <&ps_usb2host0>; + }; + + ohci0: usb-ohci@20c300000 { + compatible = "apple,s5l8960x-ohci", "generic-ohci"; + reg = <0x2 0x0c300000 0x0 0x10000>; + interrupts = ; + power-domains = <&ps_usb2host0_ohci>; + }; + + ehci1: usb-ehci@20c400000 { + compatible = "apple,s5l8960x-ehci", "generic-ehci"; + reg = <0x2 0x0c400000 0x0 0x10000>; + interrupts = ; + power-domains = <&ps_usb2host1>; + }; + + ohci1: usb-ohci@20c500000 { + compatible = "apple,s5l8960x-ohci", "generic-ohci"; + reg = <0x2 0x0c500000 0x0 0x10000>; + interrupts = ; + power-domains = <&ps_usb2host1_ohci>; + }; +#endif + }; + pmgr: power-management@20e000000 { compatible = "apple,s5l8960x-pmgr", "apple,pmgr", "syscon", "simple-mfd"; #address-cells = <1>; @@ -227,6 +290,14 @@ interrupts = , ; }; + + pmu { + compatible = "apple,cyclone-pmu"; + interrupt-parent = <&aic>; + interrupts = , + ; + interrupt-affinity = <&cpu0 &cpu1>; + }; }; #include "s5l8960x-pmgr.dtsi" diff --git a/arch/arm64/boot/dts/apple/s800-0-3-common.dtsi b/arch/arm64/boot/dts/apple/s800-0-3-common.dtsi index cb42c5f2c1b6ca..ad31117983f4a1 100644 --- a/arch/arm64/boot/dts/apple/s800-0-3-common.dtsi +++ b/arch/arm64/boot/dts/apple/s800-0-3-common.dtsi @@ -11,6 +11,7 @@ / { aliases { + ausbphy0 = &ausbphy0; serial0 = &serial0; }; diff --git a/arch/arm64/boot/dts/apple/s800-0-3.dtsi b/arch/arm64/boot/dts/apple/s800-0-3.dtsi index bb38662b7d2e0b..fc7dc7c5ba3a4f 100644 --- a/arch/arm64/boot/dts/apple/s800-0-3.dtsi +++ b/arch/arm64/boot/dts/apple/s800-0-3.dtsi @@ -10,6 +10,7 @@ #include #include #include +#include #include / { @@ -130,6 +131,68 @@ status = "disabled"; }; + bus@20c000000 { + compatible = "apple,s8000-usb-complex", "apple,s5l8960x-usb-complex", "simple-pm-bus"; + #address-cells = <2>; + #size-cells = <2>; + dma-ranges = <0x0 0x00000000 0x8 0x00000000 0x1 0x00000000>; + nonposted-mmio; + ranges; + + reg = <0x2 0x0c900000 0x0 0x100>; + power-domains = <&ps_usb>; + + ausbphy0: phy@20c000030 { + compatible = "apple,s8000-ausb-phy", "apple,ausb-phy"; + reg = <0x2 0x0c000030 0x0 0x20>; + power-domains = <&ps_usbctrl>; + #phy-cells = <1>; + /* Tunables to be filled by loader */ + }; + + usbdev: usbdev@20c100000 { + compatible = "apple,s8000-dwc2", "apple,dwc2"; + reg = <0x2 0x0c100000 0x0 0x10000>; + interrupts = ; + clocks = <&clkref>; + clock-names = "otg"; + phys = <&ausbphy0 PHY_TYPE_USB2>; + phy-names = "usb2-phy"; + power-domains = <&ps_usbotg>; + resets = <&ps_usbotg>; + dr_mode = "peripheral"; + }; +#if 0 + ehci0: usb-ehci@20c200000 { + compatible = "apple,s8000-ehci", "generic-ehci"; + reg = <0x2 0x0c200000 0x0 0x10000>; + interrupts = ; + power-domains = <&ps_usb2host0>; + }; + + ohci0: usb-ohci@20c300000 { + compatible = "apple,s8000-ohci", "generic-ohci"; + reg = <0x2 0x0c300000 0x0 0x10000>; + interrupts = ; + power-domains = <&ps_usb2host0_ohci>; + }; + + ehci1: usb-ehci@20c400000 { + compatible = "apple,s8000-ehci", "generic-ehci"; + reg = <0x2 0x0c400000 0x0 0x10000>; + interrupts = ; + power-domains = <&ps_usb2host1>; + }; + + ehci2: usb-ehci@20c500000 { + compatible = "apple,s8000-ehci", "generic-ehci"; + reg = <0x2 0x0c500000 0x0 0x10000>; + interrupts = ; + power-domains = <&ps_usb2host2>; + }; +#endif + }; + pmgr: power-management@20e000000 { compatible = "apple,s8000-pmgr", "apple,pmgr", "syscon", "simple-mfd"; #address-cells = <1>; @@ -237,6 +300,14 @@ interrupts = , ; }; + + pmu { + compatible = "apple,twister-pmu"; + interrupt-parent = <&aic>; + interrupts = , + ; + interrupt-affinity = <&cpu0 &cpu1>; + }; }; #include "s800-0-3-pmgr.dtsi" diff --git a/arch/arm64/boot/dts/apple/s8001-common.dtsi b/arch/arm64/boot/dts/apple/s8001-common.dtsi index 91b06e1138943a..01618a47d24f1f 100644 --- a/arch/arm64/boot/dts/apple/s8001-common.dtsi +++ b/arch/arm64/boot/dts/apple/s8001-common.dtsi @@ -11,6 +11,7 @@ / { aliases { + ausbphy0 = &ausbphy0; /* Used by loader */ serial0 = &serial0; }; diff --git a/arch/arm64/boot/dts/apple/s8001-j127-j128.dtsi b/arch/arm64/boot/dts/apple/s8001-j127-j128.dtsi new file mode 100644 index 00000000000000..dd3e00ac6313ca --- /dev/null +++ b/arch/arm64/boot/dts/apple/s8001-j127-j128.dtsi @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Apple iPad Pro (9.7-inch) + * + * This file contains parts common to iPad Pro (12.9-inch). + * + * target-type: J127, J128 + * + * Copyright (c) 2026, Nick Chan + */ + +&pmic0 { + backlight@b00 { + compatible = "apple,aria-pmic-bl"; + reg = <0xb00 0x2>; + }; +}; diff --git a/arch/arm64/boot/dts/apple/s8001-j127.dts b/arch/arm64/boot/dts/apple/s8001-j127.dts index 8b522085cb3ece..38ab8940e5469b 100644 --- a/arch/arm64/boot/dts/apple/s8001-j127.dts +++ b/arch/arm64/boot/dts/apple/s8001-j127.dts @@ -7,6 +7,7 @@ /dts-v1/; #include "s8001-pro.dtsi" +#include "s8001-j127-j128.dtsi" / { compatible = "apple,j127", "apple,s8001", "apple,arm-platform"; diff --git a/arch/arm64/boot/dts/apple/s8001-j128.dts b/arch/arm64/boot/dts/apple/s8001-j128.dts index cdd3d06dcbf1e5..db86400faa0e1d 100644 --- a/arch/arm64/boot/dts/apple/s8001-j128.dts +++ b/arch/arm64/boot/dts/apple/s8001-j128.dts @@ -7,6 +7,7 @@ /dts-v1/; #include "s8001-pro.dtsi" +#include "s8001-j127-j128.dtsi" / { compatible = "apple,j128", "apple,s8001", "apple,arm-platform"; diff --git a/arch/arm64/boot/dts/apple/s8001-pro.dtsi b/arch/arm64/boot/dts/apple/s8001-pro.dtsi index 1fce5a7c4200a9..adc7e3d1a99d8c 100644 --- a/arch/arm64/boot/dts/apple/s8001-pro.dtsi +++ b/arch/arm64/boot/dts/apple/s8001-pro.dtsi @@ -42,3 +42,36 @@ }; }; }; + +&i2c0 { + status = "okay"; + + pmic0: pmic@3c { + compatible = "apple,aria-pmic", "apple,i2c-pmic"; + reg = <0x3c>; + #address-cells = <1>; + #size-cells = <1>; + + rtc@500 { + compatible = "apple,aria-pmic-rtc", "apple,antigua-pmic-rtc"; + reg = <0x500 0x10>; + nvmem-cells = <&rtc_offset>; + nvmem-cell-names = "rtc_offset"; + }; + + nvmem@5000 { + compatible = "apple,pmic-nvmem"; + reg = <0x5000 0x28>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + rtc_offset: rtc-offset@4 { + reg = <0x4 0x4>; + }; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/apple/s8001.dtsi b/arch/arm64/boot/dts/apple/s8001.dtsi index 209c7dd19b7c28..f9fcfe1e6157bf 100644 --- a/arch/arm64/boot/dts/apple/s8001.dtsi +++ b/arch/arm64/boot/dts/apple/s8001.dtsi @@ -10,6 +10,7 @@ #include #include #include +#include #include / { @@ -193,6 +194,68 @@ status = "disabled"; }; + bus@20c000000 { + compatible = "apple,s8000-usb-complex", "apple,s5l8960x-usb-complex", "simple-pm-bus"; + #address-cells = <2>; + #size-cells = <2>; + dma-ranges = <0x0 0x00000000 0x8 0x00000000 0x1 0x00000000>; + nonposted-mmio; + ranges; + + reg = <0x2 0x0c900000 0x0 0x100>; + power-domains = <&ps_usb>; + + ausbphy0: phy@20c000030 { + compatible = "apple,s8000-ausb-phy", "apple,ausb-phy"; + reg = <0x2 0x0c000030 0x0 0x20>; + power-domains = <&ps_usbctrl>; + #phy-cells = <1>; + /* Tunables to be filled by loader */ + }; + + usbdev: usbdev@20c100000 { + compatible = "apple,s8000-dwc2", "apple,dwc2"; + reg = <0x2 0x0c100000 0x0 0x10000>; + interrupts = ; + clocks = <&clkref>; + clock-names = "otg"; + phys = <&ausbphy0 PHY_TYPE_USB2>; + phy-names = "usb2-phy"; + power-domains = <&ps_usbotg>; + resets = <&ps_usbotg>; + dr_mode = "peripheral"; + }; +#if 0 + ehci0: usb-ehci@20c200000 { + compatible = "apple,s8000-ehci", "generic-ehci"; + reg = <0x2 0x0c200000 0x0 0x10000>; + interrupts = ; + power-domains = <&ps_usb2host0>; + }; + + ohci0: usb-ohci@20c300000 { + compatible = "apple,s8000-ohci", "generic-ohci"; + reg = <0x2 0x0c300000 0x0 0x10000>; + interrupts = ; + power-domains = <&ps_usb2host0_ohci>; + }; + + ehci1: usb-ehci@20c400000 { + compatible = "apple,s8000-ehci", "generic-ehci"; + reg = <0x2 0x0c400000 0x0 0x10000>; + interrupts = ; + power-domains = <&ps_usb2host1>; + }; + + ehci2: usb-ehci@20c500000 { + compatible = "apple,s8000-ehci", "generic-ehci"; + reg = <0x2 0x0c500000 0x0 0x10000>; + interrupts = ; + power-domains = <&ps_usb2host2>; + }; +#endif + }; + pmgr: power-management@20e000000 { compatible = "apple,s8000-pmgr", "apple,pmgr", "syscon", "simple-mfd"; #address-cells = <1>; @@ -305,6 +368,14 @@ interrupts = , ; }; + + pmu { + compatible = "apple,twister-pmu"; + interrupt-parent = <&aic>; + interrupts = , + ; + interrupt-affinity = <&cpu0 &cpu1>; + }; }; #include "s8001-pmgr.dtsi" diff --git a/arch/arm64/boot/dts/apple/s800x-6s.dtsi b/arch/arm64/boot/dts/apple/s800x-6s.dtsi index 1dcf80cc292066..1ac114eecd262d 100644 --- a/arch/arm64/boot/dts/apple/s800x-6s.dtsi +++ b/arch/arm64/boot/dts/apple/s800x-6s.dtsi @@ -51,3 +51,36 @@ &framebuffer0 { power-domains = <&ps_disp0 &ps_mipi_dsi>; }; + +&i2c0 { + status = "okay"; + + pmic@74 { + compatible = "apple,antigua-pmic", "apple,i2c-pmic"; + reg = <0x74>; + #address-cells = <1>; + #size-cells = <1>; + + rtc@500 { + compatible = "apple,antigua-pmic-rtc"; + reg = <0x500 0x10>; + nvmem-cells = <&rtc_offset>; + nvmem-cell-names = "rtc_offset"; + }; + + nvmem@5000 { + compatible = "apple,pmic-nvmem"; + reg = <0x5000 0x28>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + rtc_offset: rtc-offset@4 { + reg = <0x4 0x4>; + }; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/apple/s800x-ipad5.dtsi b/arch/arm64/boot/dts/apple/s800x-ipad5.dtsi index c1701e81f0c1a2..972d84d6c0109e 100644 --- a/arch/arm64/boot/dts/apple/s800x-ipad5.dtsi +++ b/arch/arm64/boot/dts/apple/s800x-ipad5.dtsi @@ -45,3 +45,36 @@ &framebuffer0 { power-domains = <&ps_disp0 &ps_dp>; }; + +&i2c0 { + status = "okay"; + + pmic@3c { + compatible = "apple,angel-pmic", "apple,i2c-pmic"; + reg = <0x3c>; + #address-cells = <1>; + #size-cells = <1>; + + rtc@500 { + compatible = "apple,angel-pmic-rtc", "apple,antigua-pmic-rtc"; + reg = <0x500 0x10>; + nvmem-cells = <&rtc_offset>; + nvmem-cell-names = "rtc_offset"; + }; + + nvmem@5000 { + compatible = "apple,pmic-nvmem"; + reg = <0x5000 0x28>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + rtc_offset: rtc-offset@4 { + reg = <0x4 0x4>; + }; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/apple/s800x-se.dtsi b/arch/arm64/boot/dts/apple/s800x-se.dtsi index deb7c7cc90f625..724d8bc427a0ea 100644 --- a/arch/arm64/boot/dts/apple/s800x-se.dtsi +++ b/arch/arm64/boot/dts/apple/s800x-se.dtsi @@ -51,3 +51,36 @@ &framebuffer0 { power-domains = <&ps_disp0 &ps_mipi_dsi>; }; + +&i2c0 { + status = "okay"; + + pmic@74 { + compatible = "apple,antigua-pmic", "apple,i2c-pmic"; + reg = <0x74>; + #address-cells = <1>; + #size-cells = <1>; + + rtc@500 { + compatible = "apple,antigua-pmic-rtc"; + reg = <0x500 0x10>; + nvmem-cells = <&rtc_offset>; + nvmem-cell-names = "rtc_offset"; + }; + + nvmem@5000 { + compatible = "apple,pmic-nvmem"; + reg = <0x5000 0x28>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + rtc_offset: rtc-offset@4 { + reg = <0x4 0x4>; + }; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/apple/t7000-6.dtsi b/arch/arm64/boot/dts/apple/t7000-6.dtsi index 7048d7383982cd..d806865ae50dc5 100644 --- a/arch/arm64/boot/dts/apple/t7000-6.dtsi +++ b/arch/arm64/boot/dts/apple/t7000-6.dtsi @@ -56,3 +56,36 @@ &typhoon_opp06 { status = "okay"; }; + +&i2c0 { + status = "okay"; + + pmic@74 { + compatible = "apple,adi-pmic", "apple,i2c-pmic"; + reg = <0x74>; + #address-cells = <1>; + #size-cells = <1>; + + rtc@5c0 { + compatible = "apple,adi-pmic-rtc", "apple,amber-pmic-rtc"; + reg = <0x5c0 0x10>; + nvmem-cells = <&rtc_offset>; + nvmem-cell-names = "rtc_offset"; + }; + + nvmem@4000 { + compatible = "apple,pmic-nvmem"; + reg = <0x4000 0x28>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + rtc_offset: rtc-offset@4 { + reg = <0x4 0x4>; + }; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/apple/t7000-common.dtsi b/arch/arm64/boot/dts/apple/t7000-common.dtsi index 87146e6daae799..0d40a5753157d5 100644 --- a/arch/arm64/boot/dts/apple/t7000-common.dtsi +++ b/arch/arm64/boot/dts/apple/t7000-common.dtsi @@ -11,6 +11,7 @@ / { aliases { + ausbphy0 = &ausbphy0; /* Used by loader */ serial0 = &serial0; serial6 = &serial6; }; diff --git a/arch/arm64/boot/dts/apple/t7000-j42d.dts b/arch/arm64/boot/dts/apple/t7000-j42d.dts index 2ec9e06cc63fae..b65d1d81587f35 100644 --- a/arch/arm64/boot/dts/apple/t7000-j42d.dts +++ b/arch/arm64/boot/dts/apple/t7000-j42d.dts @@ -34,3 +34,36 @@ &typhoon_opp06 { status = "okay"; }; + +&i2c0 { + status = "okay"; + + pmic@74 { + compatible = "apple,adi-pmic", "apple,i2c-pmic"; + reg = <0x74>; + #address-cells = <1>; + #size-cells = <1>; + + rtc@5c0 { + compatible = "apple,adi-pmic-rtc", "apple,amber-pmic-rtc"; + reg = <0x5c0 0x10>; + nvmem-cells = <&rtc_offset>; + nvmem-cell-names = "rtc_offset"; + }; + + nvmem@4000 { + compatible = "apple,pmic-nvmem"; + reg = <0x4000 0x28>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + rtc_offset: rtc-offset@4 { + reg = <0x4 0x4>; + }; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/apple/t7000-mini4.dtsi b/arch/arm64/boot/dts/apple/t7000-mini4.dtsi index cc235c5a0c438f..e46c03970cd0a2 100644 --- a/arch/arm64/boot/dts/apple/t7000-mini4.dtsi +++ b/arch/arm64/boot/dts/apple/t7000-mini4.dtsi @@ -61,3 +61,36 @@ &typhoon_opp07 { status = "okay"; }; + +&i2c0 { + status = "okay"; + + pmic@3c { + compatible = "apple,arabela-pmic", "apple,i2c-pmic"; + reg = <0x3c>; + #address-cells = <1>; + #size-cells = <1>; + + rtc@5c0 { + compatible = "apple,arabela-pmic-rtc", "apple,amber-pmic-rtc"; + reg = <0x5c0 0x10>; + nvmem-cells = <&rtc_offset>; + nvmem-cell-names = "rtc_offset"; + }; + + nvmem@4000 { + compatible = "apple,pmic-nvmem"; + reg = <0x4000 0x28>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + rtc_offset: rtc-offset@4 { + reg = <0x4 0x4>; + }; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/apple/t7000-n102.dts b/arch/arm64/boot/dts/apple/t7000-n102.dts index 99eb8a2b8c7340..71624430aa45b5 100644 --- a/arch/arm64/boot/dts/apple/t7000-n102.dts +++ b/arch/arm64/boot/dts/apple/t7000-n102.dts @@ -50,3 +50,36 @@ &framebuffer0 { power-domains = <&ps_disp0 &ps_mipi_dsi>; }; + +&i2c0 { + status = "okay"; + + pmic@74 { + compatible = "apple,adi-pmic", "apple,i2c-pmic"; + reg = <0x74>; + #address-cells = <1>; + #size-cells = <1>; + + rtc@5c0 { + compatible = "apple,adi-pmic-rtc", "apple,amber-pmic-rtc"; + reg = <0x5c0 0x10>; + nvmem-cells = <&rtc_offset>; + nvmem-cell-names = "rtc_offset"; + }; + + nvmem@4000 { + compatible = "apple,pmic-nvmem"; + reg = <0x4000 0x28>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + rtc_offset: rtc-offset@4 { + reg = <0x4 0x4>; + }; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/apple/t7000.dtsi b/arch/arm64/boot/dts/apple/t7000.dtsi index 0342455d344474..2ebdfaa2cf1dc7 100644 --- a/arch/arm64/boot/dts/apple/t7000.dtsi +++ b/arch/arm64/boot/dts/apple/t7000.dtsi @@ -11,6 +11,7 @@ #include #include #include +#include #include / { @@ -200,6 +201,68 @@ status = "disabled"; }; + bus@20c000000 { + compatible = "apple,t7000-usb-complex", "apple,s5l8960x-usb-complex", "simple-pm-bus"; + #address-cells = <2>; + #size-cells = <2>; + dma-ranges = <0x0 0x00000000 0x8 0x00000000 0x1 0x00000000>; + nonposted-mmio; + ranges; + + reg = <0x2 0x0c900000 0x0 0x100>; + power-domains = <&ps_usb>; + + ausbphy0: phy@20c000030 { + compatible = "apple,t7000-ausb-phy", "apple,ausb-phy"; + reg = <0x2 0x0c000030 0x0 0x20>; + power-domains = <&ps_usbctrl>; + #phy-cells = <1>; + /* Tunables to be filled by loader */ + }; + + usbdev: usbdev@20c100000 { + compatible = "apple,t7000-dwc2", "apple,dwc2"; + reg = <0x2 0x0c100000 0x0 0x10000>; + interrupts = ; + clocks = <&clkref>; + clock-names = "otg"; + phys = <&ausbphy0 PHY_TYPE_USB2>; + phy-names = "usb2-phy"; + resets = <&ps_usbotg>; + power-domains = <&ps_usbotg>; + dr_mode = "peripheral"; + }; +#if 0 + ehci0: usb-ehci@20c200000 { + compatible = "apple,t7000-ehci", "generic-ehci"; + reg = <0x2 0x0c200000 0x0 0x10000>; + interrupts = ; + power-domains = <&ps_usb2host0>; + }; + + ohci0: usb-ohci@20c300000 { + compatible = "apple,t7000-ohci", "generic-ohci"; + reg = <0x2 0x0c300000 0x0 0x10000>; + interrupts = ; + power-domains = <&ps_usb2host0_ohci>; + }; + + ehci1: usb-ehci@20c400000 { + compatible = "apple,t7000-ehci", "generic-ehci"; + reg = <0x2 0x0c400000 0x0 0x10000>; + interrupts = ; + power-domains = <&ps_usb2host1>; + }; + + ehci2: usb-ehci@20c500000 { + compatible = "apple,t7000-ehci", "generic-ehci"; + reg = <0x2 0x0c500000 0x0 0x10000>; + interrupts = ; + power-domains = <&ps_usb2host2>; + }; +#endif + }; + pmgr: power-management@20e000000 { compatible = "apple,t7000-pmgr", "apple,pmgr", "syscon", "simple-mfd"; #address-cells = <1>; @@ -282,6 +345,14 @@ interrupts = , ; }; + + pmu { + compatible = "apple,typhoon-pmu"; + interrupt-parent = <&aic>; + interrupts = , + ; + interrupt-affinity = <&cpu0 &cpu1>; + }; }; #include "t7000-pmgr.dtsi" diff --git a/arch/arm64/boot/dts/apple/t7001-air2.dtsi b/arch/arm64/boot/dts/apple/t7001-air2.dtsi index e4ec8c1977dea5..fb000852d6a2dc 100644 --- a/arch/arm64/boot/dts/apple/t7001-air2.dtsi +++ b/arch/arm64/boot/dts/apple/t7001-air2.dtsi @@ -73,3 +73,41 @@ &serial0 { status = "okay"; }; + +&i2c0 { + status = "okay"; + + pmic@3c { + compatible = "apple,arabela-pmic", "apple,i2c-pmic"; + reg = <0x3c>; + #address-cells = <1>; + #size-cells = <1>; + + rtc@5c0 { + compatible = "apple,arabela-pmic-rtc", "apple,amber-pmic-rtc"; + reg = <0x5c0 0x10>; + nvmem-cells = <&rtc_offset>; + nvmem-cell-names = "rtc_offset"; + }; + + backlight@600 { + compatible = "apple,arabela-pmic-bl", "apple,anya-pmic-bl"; + reg = <0x600 0x2>; + }; + + nvmem@4000 { + compatible = "apple,pmic-nvmem"; + reg = <0x4000 0x28>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + rtc_offset: rtc-offset@4 { + reg = <0x4 0x4>; + }; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/apple/t7001.dtsi b/arch/arm64/boot/dts/apple/t7001.dtsi index e1afb054236982..711cfaf1d66e1c 100644 --- a/arch/arm64/boot/dts/apple/t7001.dtsi +++ b/arch/arm64/boot/dts/apple/t7001.dtsi @@ -9,6 +9,7 @@ #include #include #include +#include #include / { @@ -17,6 +18,7 @@ #size-cells = <2>; aliases { + ausbphy0 = &ausbphy0; /* Used by loader */ serial0 = &serial0; }; @@ -200,6 +202,69 @@ status = "disabled"; }; + bus@20c000000 { + compatible = "apple,t7000-usb-complex", "apple,s5l8960x-usb-complex", "simple-pm-bus"; + #address-cells = <2>; + #size-cells = <2>; + dma-ranges = <0x0 0x00000000 0x8 0x00000000 0x1 0x00000000>; + nonposted-mmio; + ranges; + + reg = <0x2 0x0c900000 0x0 0x100>; + power-domains = <&ps_usb>; + + ausbphy0: phy@20c000030 { + compatible = "apple,t7000-ausb-phy", "apple,ausb-phy"; + reg = <0x2 0x0c000030 0x0 0x20>; + power-domains = <&ps_usbctrl>; + #phy-cells = <1>; + /* Tunables to be filled by loader */ + }; + + usbdev: usbdev@20c100000 { + compatible = "apple,t7000-dwc2", "apple,dwc2"; + reg = <0x2 0x0c100000 0x0 0x10000>; + interrupts = ; + clocks = <&clkref>; + clock-names = "otg"; + phys = <&ausbphy0 PHY_TYPE_USB2>; + phy-names = "usb2-phy"; + power-domains = <&ps_usbotg>; + resets = <&ps_usbotg>; + dr_mode = "peripheral"; + }; +#if 0 + ehci0: usb-ehci@20c200000 { + compatible = "apple,t7000-ehci", "generic-ehci"; + reg = <0x2 0x0c200000 0x0 0x10000>; + interrupts = ; + power-domains = <&ps_usb2host0>; + }; + + ohci0: usb-ohci@20c300000 { + compatible = "apple,t7000-ohci", "generic-ohci"; + reg = <0x2 0x0c300000 0x0 0x10000>; + interrupts = ; + power-domains = <&ps_usb2host0_ohci>; + }; + + ehci1: usb-ehci@20c400000 { + compatible = "apple,t7000-ehci", "generic-ehci"; + reg = <0x2 0x0c400000 0x0 0x10000>; + interrupts = ; + power-domains = <&ps_usb2host1>; + }; + + ehci2: usb-ehci@20c500000 { + compatible = "apple,t7000-ehci", "generic-ehci"; + reg = <0x2 0x0c500000 0x0 0x10000>; + interrupts = ; + power-domains = <&ps_usb2host2>; + }; +#endif + }; + + pmgr: power-management@20e000000 { compatible = "apple,t7000-pmgr", "apple,pmgr", "syscon", "simple-mfd"; #address-cells = <1>; @@ -275,6 +340,15 @@ interrupts = , ; }; + + pmu { + compatible = "apple,typhoon-pmu"; + interrupt-parent = <&aic>; + interrupts = , + , + ; + interrupt-affinity = <&cpu0 &cpu1 &cpu2>; + }; }; #include "t7001-pmgr.dtsi" diff --git a/arch/arm64/boot/dts/apple/t8010-7.dtsi b/arch/arm64/boot/dts/apple/t8010-7.dtsi index 1913b7b2c1febc..67526e65955ee2 100644 --- a/arch/arm64/boot/dts/apple/t8010-7.dtsi +++ b/arch/arm64/boot/dts/apple/t8010-7.dtsi @@ -53,3 +53,36 @@ &hurricane_opp10 { status = "okay"; }; + +&i2c1 { + status = "okay"; + + pmic@74 { + compatible = "apple,adelyn-pmic", "apple,i2c-pmic"; + reg = <0x74>; + #address-cells = <1>; + #size-cells = <1>; + + rtc@500 { + compatible = "apple,adelyn-pmic-rtc", "apple,antigua-pmic-rtc"; + reg = <0x500 0x10>; + nvmem-cells = <&rtc_offset>; + nvmem-cell-names = "rtc_offset"; + }; + + nvmem@5000 { + compatible = "apple,pmic-nvmem"; + reg = <0x5000 0x28>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + rtc_offset: rtc-offset@4 { + reg = <0x4 0x4>; + }; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/apple/t8010-common.dtsi b/arch/arm64/boot/dts/apple/t8010-common.dtsi index 44dc968638b138..7426147af3ea9d 100644 --- a/arch/arm64/boot/dts/apple/t8010-common.dtsi +++ b/arch/arm64/boot/dts/apple/t8010-common.dtsi @@ -11,6 +11,7 @@ / { aliases { + ausbphy0 = &ausbphy0; /* Used by loader */ serial0 = &serial0; }; diff --git a/arch/arm64/boot/dts/apple/t8010-ipad6.dtsi b/arch/arm64/boot/dts/apple/t8010-ipad6.dtsi index 1e46e4a3a7f4ad..4e17a8448f6d93 100644 --- a/arch/arm64/boot/dts/apple/t8010-ipad6.dtsi +++ b/arch/arm64/boot/dts/apple/t8010-ipad6.dtsi @@ -54,3 +54,36 @@ &hurricane_opp10 { status = "okay"; }; + +&i2c0 { + status = "okay"; + + pmic@3c { + compatible = "apple,angel-pmic", "apple,i2c-pmic"; + reg = <0x3c>; + #address-cells = <1>; + #size-cells = <1>; + + rtc@500 { + compatible = "apple,angel-pmic-rtc", "apple,antigua-pmic-rtc"; + reg = <0x500 0x10>; + nvmem-cells = <&rtc_offset>; + nvmem-cell-names = "rtc_offset"; + }; + + nvmem@5000 { + compatible = "apple,pmic-nvmem"; + reg = <0x5000 0x28>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + rtc_offset: rtc-offset@4 { + reg = <0x4 0x4>; + }; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/apple/t8010-n112.dts b/arch/arm64/boot/dts/apple/t8010-n112.dts index 48fdbedf74da5c..ed719c3e17e757 100644 --- a/arch/arm64/boot/dts/apple/t8010-n112.dts +++ b/arch/arm64/boot/dts/apple/t8010-n112.dts @@ -49,3 +49,36 @@ &framebuffer0 { power-domains = <&ps_disp0_fe &ps_disp0_be &ps_mipi_dsi>; }; + +&i2c1 { + status = "okay"; + + pmic@74 { + compatible = "apple,adelyn-pmic", "apple,i2c-pmic"; + reg = <0x74>; + #address-cells = <1>; + #size-cells = <1>; + + rtc@500 { + compatible = "apple,adelyn-pmic-rtc", "apple,antigua-pmic-rtc"; + reg = <0x500 0x10>; + nvmem-cells = <&rtc_offset>; + nvmem-cell-names = "rtc_offset"; + }; + + nvmem@5000 { + compatible = "apple,pmic-nvmem"; + reg = <0x5000 0x28>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + rtc_offset: rtc-offset@4 { + reg = <0x4 0x4>; + }; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/apple/t8010.dtsi b/arch/arm64/boot/dts/apple/t8010.dtsi index 522b3896aa87eb..72ec543d7c8b42 100644 --- a/arch/arm64/boot/dts/apple/t8010.dtsi +++ b/arch/arm64/boot/dts/apple/t8010.dtsi @@ -10,6 +10,7 @@ #include #include #include +#include #include / { @@ -220,6 +221,61 @@ status = "disabled"; }; + bus@20c000000 { + compatible = "apple,t8010-usb-complex", "apple,s5l8960x-usb-complex", "simple-pm-bus"; + #address-cells = <2>; + #size-cells = <2>; + dma-ranges = <0x0 0x00000000 0x8 0x00000000 0x1 0x00000000>; + nonposted-mmio; + ranges; + + reg = <0x2 0x0c900000 0x0 0x100>; + power-domains = <&ps_usb>; + + ausbphy0: phy@20c000030 { + compatible = "apple,t8010-ausb-phy", "apple,ausb-phy"; + reg = <0x2 0x0c000030 0x0 0x20>; + power-domains = <&ps_usbctrl>; + #phy-cells = <1>; + /* Tunables to be filled by loader */ + }; + + usbdev: usbdev@20c100000 { + compatible = "apple,t8010-dwc2", "apple,dwc2"; + reg = <0x2 0x0c100000 0x0 0x10000>; + interrupts = ; + clocks = <&clkref>; + clock-names = "otg"; + phys = <&ausbphy0 PHY_TYPE_USB2>; + phy-names = "usb2-phy"; + power-domains = <&ps_usbotg>; + resets = <&ps_usbotg>; + dr_mode = "peripheral"; + }; +#if 0 + ehci0: usb-ehci@20c200000 { + compatible = "apple,t8010-ehci", "generic-ehci"; + reg = <0x2 0x0c200000 0x0 0x10000>; + interrupts = ; + power-domains = <&ps_usb2host0>; + }; + + ohci0: usb-ohci@20c300000 { + compatible = "apple,t8010-ohci", "generic-ohci"; + reg = <0x2 0x0c300000 0x0 0x10000>; + interrupts = ; + power-domains = <&ps_usb2host0_ohci>; + }; + + ehci1: usb-ehci@20c400000 { + compatible = "apple,t8010-ehci", "generic-ehci"; + reg = <0x2 0x0c400000 0x0 0x10000>; + interrupts = ; + power-domains = <&ps_usb2host1>; + }; +#endif + }; + pmgr: power-management@20e000000 { compatible = "apple,t8010-pmgr", "apple,pmgr", "syscon", "simple-mfd"; #address-cells = <1>; @@ -332,6 +388,14 @@ interrupts = , ; }; + + pmu { + compatible = "apple,fusion-pmu"; + interrupt-parent = <&aic>; + interrupts = , + ; + interrupt-affinity = <&cpu0 &cpu1>; + }; }; #include "t8010-pmgr.dtsi" diff --git a/arch/arm64/boot/dts/apple/t8011-common.dtsi b/arch/arm64/boot/dts/apple/t8011-common.dtsi index 2010b56246f143..1ffe1a2c0e58b2 100644 --- a/arch/arm64/boot/dts/apple/t8011-common.dtsi +++ b/arch/arm64/boot/dts/apple/t8011-common.dtsi @@ -9,6 +9,7 @@ / { aliases { + ausbphy0 = &ausbphy0; /* Used by loader */ serial0 = &serial0; }; @@ -42,6 +43,46 @@ }; }; +&i2c0 { + status = "okay"; + + august_pmic: pmic@3c { + compatible = "apple,august-pmic", "apple,i2c-pmic"; + reg = <0x3c>; + #address-cells = <1>; + #size-cells = <1>; + + rtc@500 { + compatible = "apple,august-pmic-rtc", "apple,antigua-pmic-rtc"; + reg = <0x500 0x10>; + nvmem-cells = <&rtc_offset>; + nvmem-cell-names = "rtc_offset"; + }; + + nvmem@5000 { + compatible = "apple,pmic-nvmem"; + reg = <0x5000 0x28>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + rtc_offset: rtc-offset@4 { + reg = <0x4 0x4>; + }; + }; + }; + }; + + autumn_pmic: pmic@40 { + compatible = "apple,autumn-pmic", "apple,i2c-pmic"; + reg = <0x40>; + #address-cells = <1>; + #size-cells = <1>; + }; +}; + &serial0 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/apple/t8011-pro2.dtsi b/arch/arm64/boot/dts/apple/t8011-pro2.dtsi index 5eaa0a73350f59..1e7426fc100ae1 100644 --- a/arch/arm64/boot/dts/apple/t8011-pro2.dtsi +++ b/arch/arm64/boot/dts/apple/t8011-pro2.dtsi @@ -41,6 +41,13 @@ }; }; +&august_pmic { + backlight@b00 { + compatible = "apple,august-pmic-bl", "apple,aria-pmic-bl"; + reg = <0xb00 0x2>; + }; +}; + &ps_dcs6 { apple,always-on; /* LPDDR4 interface */ }; diff --git a/arch/arm64/boot/dts/apple/t8011.dtsi b/arch/arm64/boot/dts/apple/t8011.dtsi index 039aa4d1e88762..01c3a0d55caf7a 100644 --- a/arch/arm64/boot/dts/apple/t8011.dtsi +++ b/arch/arm64/boot/dts/apple/t8011.dtsi @@ -10,6 +10,7 @@ #include #include #include +#include #include / { @@ -224,6 +225,57 @@ status = "disabled"; }; + bus@20c000000 { + compatible = "apple,t8011-usb-complex", "simple-pm-bus"; + #address-cells = <2>; + #size-cells = <2>; + dma-ranges = <0x0 0x00000000 0x8 0x00000000 0x1 0x00000000>; + nonposted-mmio; + ranges; + + reg = <0x2 0x0c000000 0x0 0x40>, + <0x2 0x0c000060 0x0 0x40>; + power-domains = <&ps_usb>; + + ausbphy0: phy@20c000040 { + compatible = "apple,t8011-ausb-phy", "apple,ausb-phy"; + reg = <0x2 0x0c000040 0x0 0x20>; + power-domains = <&ps_usbctrl>; + #phy-cells = <1>; + /* Tunables to be filled by loader */ + }; + + usb2dev: usb2dev@20c100000 { + compatible = "apple,t8010-dwc2", "apple,dwc2"; + reg = <0x2 0x0c100000 0x0 0x10000>; + interrupts = ; + clocks = <&clkref>; + clock-names = "otg"; + phys = <&ausbphy0 PHY_TYPE_USB2>; + phy-names = "usb2-phy"; + power-domains = <&ps_usb2dev>; + resets = <&ps_usb2dev>; + dr_mode = "peripheral"; + }; +#if 0 + ehci0: usb-ehci@20c200000 { + compatible = "apple,t8010-ehci", "generic-ehci"; + reg = <0x2 0x0c200000 0x0 0x10000>; + interrupts = ; + power-domains = <&ps_usb2host>; + }; + + xhci0: usb-xhci@20c400000 { + compatible = "apple,t8011-xhci", "generic-xhci"; + reg = <0x2 0x0c400000 0x0 0x10000>; + interrupts = ; + power-domains = <&ps_usb3host>; + /* FIXME: Time out on setup (need firmware?) */ + status = "disabled"; + }; +#endif + }; + pmgr: power-management@20e000000 { compatible = "apple,t8010-pmgr", "apple,pmgr", "syscon", "simple-mfd"; #address-cells = <1>; @@ -329,6 +381,15 @@ interrupts = , ; }; + + pmu { + compatible = "apple,fusion-pmu"; + interrupt-parent = <&aic>; + interrupts = , + , + ; + interrupt-affinity = <&cpu0 &cpu1 &cpu2>; + }; }; #include "t8011-pmgr.dtsi" diff --git a/arch/arm64/boot/dts/apple/t8012-jxxx.dtsi b/arch/arm64/boot/dts/apple/t8012-jxxx.dtsi index 36e82633bc521a..59cb13ed7c97b8 100644 --- a/arch/arm64/boot/dts/apple/t8012-jxxx.dtsi +++ b/arch/arm64/boot/dts/apple/t8012-jxxx.dtsi @@ -14,6 +14,7 @@ chassis-type = "embedded"; aliases { + ausbphy0 = &ausbphy0; /* Used by loader */ serial0 = &serial0; }; diff --git a/arch/arm64/boot/dts/apple/t8012.dtsi b/arch/arm64/boot/dts/apple/t8012.dtsi index e7923814169bd4..997cdc3f44b8ec 100644 --- a/arch/arm64/boot/dts/apple/t8012.dtsi +++ b/arch/arm64/boot/dts/apple/t8012.dtsi @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -149,6 +150,77 @@ #performance-domain-cells = <0>; }; + /* THESE I2C NODES DOES NOT WORK PROPERLY */ + i2c0: i2c@20a200000 { + compatible = "apple,t8010-i2c", "apple,i2c"; + reg = <0x2 0x0a200000 0x0 0x4000>; + clocks = <&clkref>; + interrupt-parent = <&aic>; + interrupts = ; + pinctrl-0 = <&i2c0_pins>; + pinctrl-names = "default"; + #address-cells = <0x1>; + #size-cells = <0x0>; + power-domains = <&ps_i2c0>; + status = "disabled"; + }; + + i2c1: i2c@20a204000 { + compatible = "apple,t8010-i2c", "apple,i2c"; + reg = <0x2 0x0a204000 0x0 0x4000>; + clocks = <&clkref>; + interrupt-parent = <&aic>; + interrupts = ; + pinctrl-0 = <&i2c1_pins>; + pinctrl-names = "default"; + #address-cells = <0x1>; + #size-cells = <0x0>; + power-domains = <&ps_i2c1>; + status = "disabled"; + }; + + i2c2: i2c@20a208000 { + compatible = "apple,t8010-i2c", "apple,i2c"; + reg = <0x2 0x0a208000 0x0 0x4000>; + clocks = <&clkref>; + interrupt-parent = <&aic>; + interrupts = ; + pinctrl-0 = <&i2c2_pins>; + pinctrl-names = "default"; + #address-cells = <0x1>; + #size-cells = <0x0>; + power-domains = <&ps_i2c2>; + status = "disabled"; + }; + + i2c3: i2c@20a20c000 { + compatible = "apple,t8010-i2c", "apple,i2c"; + reg = <0x2 0x0a20c000 0x0 0x4000>; + clocks = <&clkref>; + interrupt-parent = <&aic>; + interrupts = ; + pinctrl-0 = <&i2c3_pins>; + pinctrl-names = "default"; + #address-cells = <0x1>; + #size-cells = <0x0>; + power-domains = <&ps_i2c3>; + status = "disabled"; + }; + + i2c4: i2c@20a210000 { + compatible = "apple,t8010-i2c", "apple,i2c"; + reg = <0x2 0x0a210000 0x0 0x4000>; + clocks = <&clkref>; + interrupt-parent = <&aic>; + interrupts = ; + pinctrl-0 = <&i2c4_pins>; + pinctrl-names = "default"; + #address-cells = <0x1>; + #size-cells = <0x0>; + power-domains = <&ps_i2c4>; + status = "disabled"; + }; + serial0: serial@20a600000 { compatible = "apple,s5l-uart"; reg = <0x2 0x0a600000 0x0 0x4000>; @@ -162,6 +234,39 @@ status = "disabled"; }; + bus@20c000000 { + compatible = "apple,t8010-usb-complex", "apple,s5l8960x-usb-complex", "simple-pm-bus"; + #address-cells = <2>; + #size-cells = <2>; + dma-ranges = <0x0 0x00000000 0x8 0x00000000 0x1 0x00000000>; + nonposted-mmio; + ranges; + + reg = <0x2 0x0c900000 0x0 0x100>; + power-domains = <&ps_usb>; + + ausbphy0: phy@20c000030 { + compatible = "apple,s8000-ausb-phy", "apple,ausb-phy"; + reg = <0x2 0x0c000030 0x0 0x20>; + power-domains = <&ps_usbctrl>; + #phy-cells = <1>; + /* Tunables to be filled by loader */ + }; + + usbdev: usbdev@20c100000 { + compatible = "apple,t8010-dwc2", "apple,dwc2"; + reg = <0x2 0x0c100000 0x0 0x10000>; + interrupts = ; + clocks = <&clkref>; + clock-names = "otg"; + phys = <&ausbphy0 PHY_TYPE_USB2>; + phy-names = "usb2-phy"; + power-domains = <&ps_usbotg>; + resets = <&ps_usbotg>; + dr_mode = "peripheral"; + }; + }; + pmgr: power-management@20e000000 { compatible = "apple,t8010-pmgr", "apple,pmgr", "syscon", "simple-mfd"; #address-cells = <1>; @@ -198,6 +303,31 @@ , , ; + + i2c0_pins: i2c0-pins { + pinmux = , + ; + }; + + i2c1_pins: i2c1-pins { + pinmux = , + ; + }; + + i2c2_pins: i2c2-pins { + pinmux = , + ; + }; + + i2c3_pins: i2c3-pins { + pinmux = , + ; + }; + + i2c4_pins: i2c4-pins { + pinmux = , + ; + }; }; pinctrl_aop: pinctrl@2100f0000 { @@ -226,6 +356,35 @@ reg = <0x2 0x11180700 0x0 0x100>; #address-cells = <2>; #size-cells = <0>; + + pmic@f { + compatible = "apple,calpe-pmic", "apple,spmi-pmic"; + reg = <0xf SPMI_USID>; + #address-cells = <1>; + #size-cells = <1>; + + rtc@2603 { + compatible = "apple,calpe-pmic-rtc", "apple,antigua-pmic-rtc"; + reg = <0x2603 0x10>; + nvmem-cells = <&rtc_offset>; + nvmem-cell-names = "rtc_offset"; + }; + + nvmem@5000 { + compatible = "apple,pmic-nvmem"; + reg = <0x5000 0x300>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + rtc_offset: rtc-offset@4 { + reg = <0x4 0x4>; + }; + }; + }; + }; }; pinctrl_nub: pinctrl@2111f0000 { @@ -261,6 +420,15 @@ interrupts = ; }; + smc: smc@212000100 { + compatible = "apple,t8012-smc", "apple,t8103-smc"; + reg = <0x2 0x12000100 0x0 0x100>, + <0x2 0x12e00000 0x0 0x80000>; + reg-names = "smc", "sram"; + mboxes = <&smc_mbox>; + power-domains = <&ps_smc_cpu>; + }; + pinctrl_smc: pinctrl@212024000 { compatible = "apple,t8010-pinctrl", "apple,pinctrl"; reg = <0x2 0x12024000 0x0 0x1000>; @@ -281,11 +449,19 @@ , , ; - /* - * SMC is not yet supported and accessing this pinctrl while SMC is - * suspended results in a hang. - */ - status = "disabled"; + }; + + smc_mbox: mbox@212808000 { + compatible = "apple,t8015-asc-mailbox"; + reg = <0x2 0x12808000 0x0 0x4000>; + interrupt-parent = <&aic>; + interrupts = , + , + , + ; + interrupt-names = "send-empty", "send-not-empty", + "recv-empty", "recv-not-empty"; + #mbox-cells = <0>; }; }; @@ -297,6 +473,14 @@ interrupts = , ; }; + + pmu { + compatible = "apple,fusion-pmu"; + interrupt-parent = <&aic>; + interrupts = , + ; + interrupt-affinity = <&cpu0 &cpu1>; + }; }; #include "t8012-pmgr.dtsi" diff --git a/arch/arm64/boot/dts/apple/t8015-common.dtsi b/arch/arm64/boot/dts/apple/t8015-common.dtsi index 498f58fb9715d1..f1d68046a63b75 100644 --- a/arch/arm64/boot/dts/apple/t8015-common.dtsi +++ b/arch/arm64/boot/dts/apple/t8015-common.dtsi @@ -11,7 +11,10 @@ / { aliases { + ausbphy0 = &ausbphy0; serial0 = &serial0; + /* Used by loader to fill properties*/ + smc = &smc; }; chosen { @@ -47,3 +50,40 @@ &serial0 { status = "okay"; }; + +&smc_hwmon { + temperature-TG0B { + apple,key-id = "TG0B"; + label = "Battery Temp"; + }; + + temperature-TG0V { + apple,key-id = "TG0V"; + label = "Battery Flex Temp"; + }; + + temperature-TP1d { + apple,key-id = "TP1d"; + label = "Forehead Temp"; + }; + + temperature-TP2d { + apple,key-id = "TP2d"; + label = "Rear Camera Temp"; + }; + + temperature-TP3d { + apple,key-id = "TP3d"; + label = "Cellular Radio Temp"; + }; + + temperature-TP4d { + apple,key-id = "TP4d"; + label = "AP SoC Temp"; + }; + + temperature-TP5d { + apple,key-id = "TP5d"; + label = "Charger Temp"; + }; +}; diff --git a/arch/arm64/boot/dts/apple/t8015-pmgr.dtsi b/arch/arm64/boot/dts/apple/t8015-pmgr.dtsi index 1d8da9c7863e5b..249014ca7a305a 100644 --- a/arch/arm64/boot/dts/apple/t8015-pmgr.dtsi +++ b/arch/arm64/boot/dts/apple/t8015-pmgr.dtsi @@ -642,6 +642,7 @@ #power-domain-cells = <0>; #reset-cells = <0>; label = "pmp"; + power-domains = <&ps_pms_sram>; }; ps_pms_sram: power-controller@80310 { diff --git a/arch/arm64/boot/dts/apple/t8015.dtsi b/arch/arm64/boot/dts/apple/t8015.dtsi index 586d3cf1f3751d..1e00d84e00365f 100644 --- a/arch/arm64/boot/dts/apple/t8015.dtsi +++ b/arch/arm64/boot/dts/apple/t8015.dtsi @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -335,12 +336,79 @@ status = "disabled"; }; + bus@230000000 { + compatible = "apple,t8015-usb-complex", "simple-pm-bus"; + #address-cells = <2>; + #size-cells = <2>; + dma-ranges = <0x0 0x00000000 0x8 0x00000000 0x1 0x00000000>; + ranges; + + reg = <0x2 0x30000000 0x0 0x60>; + power-domains = <&ps_usb>; + + ausbphy0: phy@230000060 { + compatible = "apple,t8015-ausb-phy", "apple,ausb-phy"; + reg = <0x2 0x30000060 0x0 0x20>; + power-domains = <&ps_usbctlreg>; + #phy-cells = <1>; + /* Tunables to be filled by loader */ + }; + + usbdev: usbdev@230100000 { + compatible = "apple,t8015-dwc2", "apple,dwc2"; + reg = <0x2 0x30100000 0x0 0x10000>; + interrupts = ; + clocks = <&clkref>; + clock-names = "otg"; + phys = <&ausbphy0 PHY_TYPE_USB2>; + phy-names = "usb2-phy"; + power-domains = <&ps_usb2dev>; + resets = <&ps_usb2dev>; + dr_mode = "peripheral"; + }; + +#if 0 + ehci0: usb-ehci@230200000 { + compatible = "apple,t8015-ehci", "generic-ehci"; + reg = <0x2 0x30200000 0x0 0x10000>; + interrupts = ; + power-domains = <&ps_usb2host0>; + }; + + ohci0: usb-ohci@230300000 { + compatible = "apple,t8015-ohci", "generic-ohci"; + reg = <0x2 0x30300000 0x0 0x10000>; + interrupts = ; + power-domains = <&ps_usb2host0_ohci>; + }; + + ehci1: usb-ehci@230400000 { + compatible = "apple,t8015-ehci", "generic-ehci"; + reg = <0x2 0x30400000 0x0 0x10000>; + interrupts = ; + power-domains = <&ps_usb2host1>; + }; +#endif + }; + aic: interrupt-controller@232100000 { compatible = "apple,t8015-aic", "apple,aic"; reg = <0x2 0x32100000 0x0 0x8000>; #interrupt-cells = <3>; interrupt-controller; power-domains = <&ps_aic>; + + affinities { + e-core-pmu-affinity { + apple,fiq-index = ; + cpus = <&cpu_e0 &cpu_e1 &cpu_e2 &cpu_e3>; + }; + + p-core-pmu-affinity { + apple,fiq-index = ; + cpus = <&cpu_p0 &cpu_p1>; + }; + }; }; pmgr: power-management@232000000 { @@ -358,6 +426,33 @@ status = "disabled"; }; + pmp: pmp@232300000 { + compatible = "apple,t8015-pmp"; + reg = <0x2 0x32300000 0x0 0x8000>, + <0x2 0x32400000 0x0 0x10000>, + <0x2 0x32500000 0x0 0x20000>; + reg-names = "akf", "control", "sram"; + mboxes = <&pmp_mbox>; + mbox-names = "mbox"; + power-domains = <&ps_pmp>; + firmware-name = "apple/pmp-t8015.bin"; + }; + + pmp_mbox: mbox@232308000 { + compatible = "apple,t8015-asc-mailbox"; + reg = <0x2 0x32308000 0x0 0x4000>; + interrupt-parent = <&aic>; + interrupts = , + , + , + ; + interrupt-names = "send-empty", "send-not-empty", + "recv-empty", "recv-not-empty"; + #mbox-cells = <0>; + power-domains = <&ps_pmp>; + }; + + pinctrl_ap: pinctrl@233100000 { compatible = "apple,t8015-pinctrl", "apple,pinctrl"; reg = <0x2 0x33100000 0x0 0x1000>; @@ -426,6 +521,57 @@ reg = <0x2 0x35180700 0x0 0x100>; #address-cells = <2>; #size-cells = <0>; + + pmic@f { + compatible = "apple,calpe-pmic", "apple,spmi-pmic"; + reg = <0xf SPMI_USID>; + #address-cells = <1>; + #size-cells = <1>; + + rtc@1400 { + compatible = "apple,agnes-pmic-rtc", "apple,antigua-pmic-rtc"; + reg = <0x1400 0x10>; + nvmem-cells = <&rtc_offset>; + nvmem-cell-names = "rtc_offset"; + }; + + nvmem@6000 { + compatible = "apple,pmic-nvmem"; + reg = <0x6000 0x300>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + boot_stage: boot-stage@1 { + reg = <0x1 0x1>; + }; + + boot_error_count: boot-error-count@2,0 { + reg = <0x2 0x1>; + bits = <0 4>; + }; + + panic_count: panic-count@2,4 { + reg = <0x2 0x1>; + bits = <4 4>; + }; + + boot_error_stage: boot-error-stage@3 { + reg = <0x3 0x1>; + }; + + shutdown_flag: shutdown-flag@f { + reg = <0xf 0x1>; + }; + + rtc_offset: rtc-offset@4 { + reg = <0x4 0x4>; + }; + }; + }; + }; }; pinctrl_nub: pinctrl@2351f0000 { @@ -461,6 +607,28 @@ interrupts = ; }; + smc: smc@236000100 { + compatible = "apple,t8015-smc", "apple,t8103-smc"; + reg = <0x2 0x36000100 0x0 0x100>, + <0x2 0x36e00000 0x0 0x40000>; + reg-names = "smc", "sram"; + mboxes = <&smc_mbox>; + power-domains = <&ps_smc_cpu>; + + smc_hwmon: hwmon { + compatible = "apple,smc-hwmon"; + }; + + smc_reboot: reboot { + compatible = "apple,t8015-smc-reboot"; + nvmem-cells = <&shutdown_flag>, <&boot_stage>, + <&boot_error_count>, <&panic_count>; + nvmem-cell-names = "shutdown_flag", "boot_stage", + "boot_error_count", "panic_count"; + /* To be filled by loader */ + }; + }; + pinctrl_smc: pinctrl@236024000 { compatible = "apple,t8015-pinctrl", "apple,pinctrl"; reg = <0x2 0x36024000 0x0 0x4000>; @@ -480,11 +648,19 @@ , , ; - /* - * SMC is not yet supported and accessing this pinctrl while SMC is - * suspended results in a hang. - */ - status = "disabled"; + }; + + smc_mbox: mbox@236808000 { + compatible = "apple,t8015-asc-mailbox"; + reg = <0x2 0x36808000 0x0 0x4000>; + interrupt-parent = <&aic>; + interrupts = , + , + , + ; + interrupt-names = "send-empty", "send-not-empty", + "recv-empty", "recv-not-empty"; + #mbox-cells = <0>; }; ans_mbox: mbox@257008000 { @@ -530,6 +706,18 @@ interrupts = , ; }; + + pmu-e { + compatible = "apple,mistral-pmu"; + interrupt-parent = <&aic>; + interrupts = ; + }; + + pmu-p { + compatible = "apple,monsoon-pmu"; + interrupt-parent = <&aic>; + interrupts = ; + }; }; #include "t8015-pmgr.dtsi" diff --git a/arch/arm64/include/asm/apple_m1_pmu.h b/arch/arm64/include/asm/apple_m1_pmu.h index 02e05d05851f73..8a667e7f07a517 100644 --- a/arch/arm64/include/asm/apple_m1_pmu.h +++ b/arch/arm64/include/asm/apple_m1_pmu.h @@ -38,8 +38,10 @@ #define SYS_IMP_APL_PMCR1_EL1 sys_reg(3, 1, 15, 1, 0) #define SYS_IMP_APL_PMCR1_EL12 sys_reg(3, 1, 15, 7, 2) +#define PMCR1_COUNT_A32_EL0_0_7 GENMASK(7, 0) #define PMCR1_COUNT_A64_EL0_0_7 GENMASK(15, 8) #define PMCR1_COUNT_A64_EL1_0_7 GENMASK(23, 16) +#define PMCR1_COUNT_A32_EL0_8_9 GENMASK(33, 32) #define PMCR1_COUNT_A64_EL0_8_9 GENMASK(41, 40) #define PMCR1_COUNT_A64_EL1_8_9 GENMASK(49, 48) diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h index 7b518e81dd15bf..a4455fa7bc674c 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h @@ -139,18 +139,27 @@ #define HISI_CPU_PART_HIP09 0xD02 #define HISI_CPU_PART_HIP12 0xD06 -#define APPLE_CPU_PART_M1_ICESTORM 0x022 -#define APPLE_CPU_PART_M1_FIRESTORM 0x023 -#define APPLE_CPU_PART_M1_ICESTORM_PRO 0x024 -#define APPLE_CPU_PART_M1_FIRESTORM_PRO 0x025 -#define APPLE_CPU_PART_M1_ICESTORM_MAX 0x028 -#define APPLE_CPU_PART_M1_FIRESTORM_MAX 0x029 -#define APPLE_CPU_PART_M2_BLIZZARD 0x032 -#define APPLE_CPU_PART_M2_AVALANCHE 0x033 -#define APPLE_CPU_PART_M2_BLIZZARD_PRO 0x034 -#define APPLE_CPU_PART_M2_AVALANCHE_PRO 0x035 -#define APPLE_CPU_PART_M2_BLIZZARD_MAX 0x038 -#define APPLE_CPU_PART_M2_AVALANCHE_MAX 0x039 +#define APPLE_CPU_PART_A7_CYCLONE 0x1 +#define APPLE_CPU_PART_A8_TYPHOON 0x2 +#define APPLE_CPU_PART_A8X_TYPHOON 0x3 +#define APPLE_CPU_PART_SAMSUNG_TWISTER 0x4 /* Used in Samsung A9 */ +#define APPLE_CPU_PART_TSMC_TWISTER 0x5 /* Used in TSMC A9 and A9X */ +#define APPLE_CPU_PART_A10_T2_HURRICANE_ZEPHYR 0x6 +#define APPLE_CPU_PART_A10X_HURRICANE_ZEPHYR 0x7 +#define APPLE_CPU_PART_A11_MONSOON 0x8 +#define APPLE_CPU_PART_A11_MISTRAL 0x9 +#define APPLE_CPU_PART_M1_ICESTORM 0x022 +#define APPLE_CPU_PART_M1_FIRESTORM 0x023 +#define APPLE_CPU_PART_M1_ICESTORM_PRO 0x024 +#define APPLE_CPU_PART_M1_FIRESTORM_PRO 0x025 +#define APPLE_CPU_PART_M1_ICESTORM_MAX 0x028 +#define APPLE_CPU_PART_M1_FIRESTORM_MAX 0x029 +#define APPLE_CPU_PART_M2_BLIZZARD 0x032 +#define APPLE_CPU_PART_M2_AVALANCHE 0x033 +#define APPLE_CPU_PART_M2_BLIZZARD_PRO 0x034 +#define APPLE_CPU_PART_M2_AVALANCHE_PRO 0x035 +#define APPLE_CPU_PART_M2_BLIZZARD_MAX 0x038 +#define APPLE_CPU_PART_M2_AVALANCHE_MAX 0x039 #define AMPERE_CPU_PART_AMPERE1 0xAC3 #define AMPERE_CPU_PART_AMPERE1A 0xAC4 @@ -230,6 +239,15 @@ #define MIDR_HISI_TSV110 MIDR_CPU_MODEL(ARM_CPU_IMP_HISI, HISI_CPU_PART_TSV110) #define MIDR_HISI_HIP09 MIDR_CPU_MODEL(ARM_CPU_IMP_HISI, HISI_CPU_PART_HIP09) #define MIDR_HISI_HIP12 MIDR_CPU_MODEL(ARM_CPU_IMP_HISI, HISI_CPU_PART_HIP12) +#define MIDR_APPLE_A7_CYCLONE MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_A7_CYCLONE) +#define MIDR_APPLE_A8_TYPHOON MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_A8_TYPHOON) +#define MIDR_APPLE_A8X_TYPHOON MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_A8X_TYPHOON) +#define MIDR_APPLE_SAMSUNG_TWISTER MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_SAMSUNG_TWISTER) +#define MIDR_APPLE_TSMC_TWISTER MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_TSMC_TWISTER) +#define MIDR_APPLE_A10_T2_HURRICANE_ZEPHYR MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_A10_T2_HURRICANE_ZEPHYR) +#define MIDR_APPLE_A10X_HURRICANE_ZEPHYR MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_A10X_HURRICANE_ZEPHYR) +#define MIDR_APPLE_A11_MONSOON MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_A11_MONSOON) +#define MIDR_APPLE_A11_MISTRAL MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_A11_MISTRAL) #define MIDR_APPLE_M1_ICESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM) #define MIDR_APPLE_M1_FIRESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM) #define MIDR_APPLE_M1_ICESTORM_PRO MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM_PRO) diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index 5377e4c2eba2be..ac5bbe2cf15454 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -200,6 +200,20 @@ cpu_enable_cache_maint_trap(const struct arm64_cpu_capabilities *__unused) sysreg_clear_set(sctlr_el1, SCTLR_EL1_UCI, 0); } +static void __maybe_unused +apple_fusion_taint(const struct arm64_cpu_capabilities *__unused) +{ + /* + * A variable MPIDR_EL1 would have been a receipe for disaster, + * but since A10(X) does not use any of KVM, GIC, ACPI, PSCI + * or cpuidle, and that all CPUs switch between P-mode and E-mode + * together, we do not need to do anything about this (yet). + * However, this is still too cursed to not taint the kernel. + */ + pr_info_once("Apple Fusion Architecture detected, tainting kernel.\n"); + add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK); +} + #define CAP_MIDR_RANGE(model, v_min, r_min, v_max, r_max) \ .matches = is_affected_midr_range, \ .midr_range = MIDR_RANGE(model, v_min, r_min, v_max, r_max) @@ -608,6 +622,14 @@ static const struct midr_range erratum_ac04_cpu_23_list[] = { }; #endif +#ifdef CONFIG_ARM64_WORKAROUND_APPLE_FUSION +static const struct midr_range apple_fusion_list[] = { + MIDR_ALL_VERSIONS(MIDR_APPLE_A10_T2_HURRICANE_ZEPHYR), + MIDR_ALL_VERSIONS(MIDR_APPLE_A10X_HURRICANE_ZEPHYR), + {} +}; +#endif + const struct arm64_cpu_capabilities arm64_errata[] = { #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE { @@ -952,6 +974,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = { .capability = ARM64_WORKAROUND_AMPERE_AC04_CPU_23, ERRATA_MIDR_RANGE_LIST(erratum_ac04_cpu_23_list), }, +#endif +#ifdef CONFIG_ARM64_WORKAROUND_APPLE_FUSION + { + .desc = "Apple Fusion Architecture", + .capability = ARM64_WORKAROUND_APPLE_FUSION, + ERRATA_MIDR_RANGE_LIST(apple_fusion_list), + .cpu_enable = apple_fusion_taint, + }, #endif { .desc = "Broken CNTVOFF_EL2", diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 6d53bb15cf7bb4..104581d3478cee 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -3983,8 +3983,29 @@ static void __init setup_system_capabilities(void) spectre_print_disabled_mitigations(); } +static void bad_aarch32_el0_fixup(void) +{ + if (cpus_have_cap(ARM64_WORKAROUND_APPLE_FUSION)) { + struct arm64_ftr_reg *regp; + + /* + * Disable 32-bit EL0 altogether since A10(X) cannot execute + * 32-bit EL0 in some p-states. + */ + regp = get_arm64_ftr_reg(SYS_ID_AA64PFR0_EL1); + if (!regp) + return; + u64 val = (regp->sys_val & ~ID_AA64PFR0_EL1_EL0_MASK) + | ID_AA64PFR0_EL1_EL0_IMP; + + update_cpu_ftr_reg(regp, val); + } +} + void __init setup_system_features(void) { + bad_aarch32_el0_fixup(); + setup_system_capabilities(); linear_map_maybe_split_to_ptes(); diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 91428201606989..fc9f4214c9bb76 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -939,6 +940,18 @@ void __noreturn arm64_serror_panic(struct pt_regs *regs, unsigned long esr) if (regs) __show_regs(regs); +#ifdef CONFIG_ARCH_APPLE + #define SYS_IMP_APL_L2C_ERR_STS sys_reg(3, 3, 15, 8, 0) + #define SYS_IMP_APL_L2C_ERR_ADR sys_reg(3, 3, 15, 9, 0) + #define SYS_IMP_APL_L2C_ERR_INF sys_reg(3, 3, 15, 10, 0) + + if (of_machine_is_compatible("apple,arm-platform")) { + pr_crit("L2C_ERR_STS: 0x%llx\n", read_sysreg_s(SYS_IMP_APL_L2C_ERR_STS)); + pr_crit("L2C_ERR_ADR: 0x%llx\n", read_sysreg_s(SYS_IMP_APL_L2C_ERR_ADR)); + pr_crit("L2C_ERR_INF: 0x%llx\n", read_sysreg_s(SYS_IMP_APL_L2C_ERR_INF)); + } +#endif + nmi_panic(regs, "Asynchronous SError Interrupt"); cpu_park_loop(); diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps index 811c2479e82d6e..a1a48802e0d9e6 100644 --- a/arch/arm64/tools/cpucaps +++ b/arch/arm64/tools/cpucaps @@ -110,6 +110,7 @@ WORKAROUND_4193714 WORKAROUND_4311569 WORKAROUND_AMPERE_AC03_CPU_38 WORKAROUND_AMPERE_AC04_CPU_23 +WORKAROUND_APPLE_FUSION WORKAROUND_TRBE_OVERWRITE_FILL_MODE WORKAROUND_TSB_FLUSH_FAILURE WORKAROUND_TRBE_WRITE_OUT_OF_RANGE diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig index 3181d8aa32a3e3..2ed6586f5460c7 100644 --- a/drivers/bus/Kconfig +++ b/drivers/bus/Kconfig @@ -5,6 +5,17 @@ menu "Bus devices" +config APPLE_USBCOMPLEX + bool "Apple USB Complex" + depends on HAS_DMA && HAS_IOMEM && OF + depends on ARCH_APPLE || COMPILE_TEST + help + Driver for Apple USB Complex which remaps 32-bit addresses so 32-bit + DMA devices can be used without a real IOMMU. This driver configures + the remap according to the "dma-ranges" property to remove the need for + bootloader state required for USB to work. Say y here if you want + USB support on pre-atcphy Apple deviecs. + config ARM_CCI bool diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile index a01f97fef3e80e..ebcc5637c23722 100644 --- a/drivers/bus/Makefile +++ b/drivers/bus/Makefile @@ -3,6 +3,8 @@ # Makefile for the bus drivers. # +obj-$(CONFIG_APPLE_USBCOMPLEX) += apple-usbcomplex.o + # Interconnect bus drivers for ARM platforms obj-$(CONFIG_ARM_CCI) += arm-cci.o obj-$(CONFIG_ARM_INTEGRATOR_LM) += arm-integrator-lm.o diff --git a/drivers/bus/apple-usbcomplex.c b/drivers/bus/apple-usbcomplex.c new file mode 100644 index 00000000000000..c70a5f7722c8ad --- /dev/null +++ b/drivers/bus/apple-usbcomplex.c @@ -0,0 +1,227 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* + * Apple USB Complex + * + * Copyright (C) 2025 Nick Chan + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* S5L8960X remap registers */ +#define USBX_REMAP_EN_S5L8960X BIT(8) +#define USBX_REMAP_VAL_MASK_S5L8960X GENMASK(3, 0) +#define USBX_USBDEV_REMAP_S5L8960X 0x1c +#define USBX_EHCI0_REMAP_S5L8960X 0x3c +#define USBX_OHCI0_REMAP_S5L8960X 0x5c +#define USBX_EHCI1_REMAP_S5L8960X 0x7c +/* T7000/S8000/S8003 only, ignored by other hardware */ +#define USBX_EHCI2_REMAP_T7000 0x9c + +/* T8011/T8015 remap register values */ +#define USBX_CTL_T8011 0x00 +#define USBX_CTL_EN_T8011 BIT(0) +#define USBX_REMAP_EN1_T8011 BIT(24) +#define USBX_REMAP_EN2_T8011 BIT(25) +#define USBX_REMAP_VAL_MASK1_T8011 GENMASK(3, 0) +#define USBX_REMAP_VAL_MASK2_T8011 GENMASK(7, 4) +#define USBX_REMAP_VAL_SHIFT1_T8011 0 +#define USBX_REMAP_VAL_SHIFT2_T8011 4 + +/* T8011 remap registers */ +#define USBX_USB3DEV_REMAP_CTL_T8011 0x18 +#define USBX_USB2DEV_REMAP_CTL_T8011 0x24 +#define USBX_EHCI_REMAP_CTL_T8011 0x14 /* 0x74 */ +#define USBX_XHCI_REMAP_CTL_T8011 0x24 /* 0x84 */ + +/* T8015 remap registers */ +#define USBX_EHCI0_REMAP_CTL_T8015 0x18 +#define USBX_OHCI0_REMAP_CTL_T8015 0x28 +#define USBX_EHCI1_REMAP_CTL_T8015 0x38 +#define USBX_USBDEV_REMAP_CTL_T8015 0x48 + +#define USBX_REMAP_ADDR_MASK GENMASK(35, 32) + +struct apple_usbcomplex_hw { + u32 remap_regs[5]; + u32 hi_remap_regs[2]; + u32 (*remap_reg_value)(u32 hi_bits); + void (*enable)(void __iomem *base); +}; + +struct apple_usbcomplex { + void __iomem *base; + void __iomem *hi_remap_regs; + struct clk_bulk_data *clks; + const struct apple_usbcomplex_hw *hw; + u32 hi_bits; + int num_clks; +}; + +static u32 apple_usbcomplex_remap_reg_value_s5l8960x(u32 hi_bits) +{ + return (hi_bits & USBX_REMAP_VAL_MASK_S5L8960X) | USBX_REMAP_EN_S5L8960X; +} + +static u32 apple_usbcomplex_remap_reg_value_t8011(u32 hi_bits) +{ + return ((hi_bits << USBX_REMAP_VAL_SHIFT1_T8011) & USBX_REMAP_VAL_MASK1_T8011) + | ((hi_bits << USBX_REMAP_VAL_SHIFT2_T8011) & USBX_REMAP_VAL_MASK2_T8011) + | USBX_REMAP_EN1_T8011 | USBX_REMAP_EN2_T8011; +} + +static void apple_usbcomplex_enable_t8011(void __iomem *base) { + writel(USBX_CTL_EN_T8011, base + USBX_CTL_T8011); +}; + +static void apple_usbcomplex_init(struct apple_usbcomplex *complex) { + if (complex->hw->enable) + complex->hw->enable(complex->base); + + u32 remap_val = complex->hw->remap_reg_value(complex->hi_bits); + + for (int i = 0; i < sizeof(complex->hw->remap_regs)/sizeof(u32); i++) { + if (complex->hw->remap_regs[i]) + writel(remap_val, complex->base + complex->hw->remap_regs[i]); + } + + for (int i = 0; i < sizeof(complex->hw->hi_remap_regs)/sizeof(u32); i++) { + if (complex->hw->hi_remap_regs[i]) + writel(remap_val, complex->hi_remap_regs + complex->hw->hi_remap_regs[i]); + } +}; + +static int apple_usbcomplex_probe(struct platform_device *pdev) +{ + const struct device *dev = &pdev->dev; + const struct of_dev_auxdata *lookup = dev_get_platdata(dev); + struct device_node *np = dev->of_node; + struct resource *res; + struct of_range_parser parser; + struct of_range range; + struct apple_usbcomplex *complex; + int num_reg, ret; + + ret = of_dma_range_parser_init(&parser, np); + + if (ret < 0) + return ret; + + for_each_of_range(&parser, &range) { + if (range.size != BIT(32) || range.cpu_addr & U32_MAX || range.bus_addr != 0) + return -EINVAL; + + break; + } + + num_reg = of_address_count(np); + + complex = devm_kzalloc(&pdev->dev, sizeof(*complex), GFP_KERNEL); + + if (!complex) + return -ENOMEM; + + complex->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); + if (IS_ERR(complex->base)) + return PTR_ERR(complex->base); + if (num_reg > 1) { + complex->hi_remap_regs = devm_platform_get_and_ioremap_resource(pdev, 1, &res); + if (IS_ERR(complex->hi_remap_regs)) + return PTR_ERR(complex->hi_remap_regs); + } + + complex->hw = of_device_get_match_data(&pdev->dev); + if (!complex->hw) + return -ENODEV; + + complex->num_clks = devm_clk_bulk_get_all(&pdev->dev, &complex->clks); + if (complex->num_clks < 0) + return dev_err_probe(&pdev->dev, complex->num_clks, "failed to get clocks\n"); + + complex->hi_bits = FIELD_GET(USBX_REMAP_ADDR_MASK, range.cpu_addr); + + dev_set_drvdata(&pdev->dev, complex); + + pm_runtime_enable(&pdev->dev); + + apple_usbcomplex_init(complex); + + if (np) + of_platform_populate(np, NULL, lookup, &pdev->dev); + + return 0; +} + +static void apple_usbcomplex_remove(struct platform_device *pdev) +{ + const void *data = of_device_get_match_data(&pdev->dev); + + if (device_has_driver_override(&pdev->dev) || data) + return; + + pm_runtime_disable(&pdev->dev); +} + +static const struct apple_usbcomplex_hw s5l8960x_usbcomplex = { + .remap_regs = { + USBX_USBDEV_REMAP_S5L8960X, + USBX_EHCI0_REMAP_S5L8960X, + USBX_OHCI0_REMAP_S5L8960X, + USBX_EHCI1_REMAP_S5L8960X, + USBX_EHCI2_REMAP_T7000 + }, + .remap_reg_value = &apple_usbcomplex_remap_reg_value_s5l8960x, +}; + +static const struct apple_usbcomplex_hw t8011_usbcomplex = { + .remap_regs = { + USBX_USB3DEV_REMAP_CTL_T8011, + USBX_USB2DEV_REMAP_CTL_T8011 + }, + .hi_remap_regs = { + USBX_EHCI_REMAP_CTL_T8011, + USBX_XHCI_REMAP_CTL_T8011 + }, + .remap_reg_value = &apple_usbcomplex_remap_reg_value_t8011, + .enable = apple_usbcomplex_enable_t8011, +}; + +static const struct apple_usbcomplex_hw t8015_usbcomplex = { + .remap_regs = { + USBX_EHCI0_REMAP_CTL_T8015, + USBX_OHCI0_REMAP_CTL_T8015, + USBX_EHCI1_REMAP_CTL_T8015, + USBX_USBDEV_REMAP_CTL_T8015 + }, + .remap_reg_value = &apple_usbcomplex_remap_reg_value_t8011, + .enable = apple_usbcomplex_enable_t8011, +}; + +static const struct of_device_id apple_usbcomplex_of_match[] = { + { .compatible = "apple,s5l8960x-usb-complex", .data = &s5l8960x_usbcomplex }, + { .compatible = "apple,t8011-usb-complex", .data = &t8011_usbcomplex }, + { .compatible = "apple,t8015-usb-complex", .data = &t8015_usbcomplex }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, apple_usbcomplex_of_match); + +static struct platform_driver apple_usbcomplex_driver = { + .probe = apple_usbcomplex_probe, + .remove = apple_usbcomplex_remove, + .driver = { + .name = "apple-usb-complex", + .of_match_table = apple_usbcomplex_of_match, + }, +}; + +module_platform_driver(apple_usbcomplex_driver); + +MODULE_DESCRIPTION("Apple USB Complex Remapper"); +MODULE_AUTHOR("Nick Chan "); diff --git a/drivers/gpio/gpio-macsmc.c b/drivers/gpio/gpio-macsmc.c index b0952d066a9dd0..30d799b5fc12b5 100644 --- a/drivers/gpio/gpio-macsmc.c +++ b/drivers/gpio/gpio-macsmc.c @@ -239,6 +239,9 @@ static int macsmc_gpio_probe(struct platform_device *pdev) smc_key key; int ret; + if (!pdev->dev.of_node) + return -ENODEV; + smcgp = devm_kzalloc(&pdev->dev, sizeof(*smcgp), GFP_KERNEL); if (!smcgp) return -ENOMEM; diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 94a753fcb64fa5..0e805c870e2995 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -1003,4 +1003,15 @@ config INPUT_STPMIC1_ONKEY To compile this driver as a module, choose M here: the module will be called stpmic1_onkey. +config INPUT_MACSMC + tristate "Apple Mac SMC lid/buttons" + depends on MFD_MACSMC + help + Say Y here if you want to use the input events delivered via the + SMC controller on Apple Mac machines using the macsmc driver. + This includes lid open/close and the power button. + + To compile this driver as a module, choose M here: the + module will be called macsmc-input. + endif diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 415fc4e2918be8..1520218b406059 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -52,6 +52,7 @@ obj-$(CONFIG_INPUT_IQS7222) += iqs7222.o obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o obj-$(CONFIG_INPUT_KXTJ9) += kxtj9.o obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o +obj-$(CONFIG_INPUT_MACSMC) += macsmc-input.o obj-$(CONFIG_INPUT_MAX7360_ROTARY) += max7360-rotary.o obj-$(CONFIG_INPUT_MAX77650_ONKEY) += max77650-onkey.o obj-$(CONFIG_INPUT_MAX77693_HAPTIC) += max77693-haptic.o diff --git a/drivers/input/misc/macsmc-input.c b/drivers/input/misc/macsmc-input.c new file mode 100644 index 00000000000000..b3157f1f929e70 --- /dev/null +++ b/drivers/input/misc/macsmc-input.c @@ -0,0 +1,275 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Apple SMC input event driver + * Copyright The Asahi Linux Contributors + * + * This driver exposes certain events from the SMC as an input device. + * This includes the lid open/close and power button notifications. + */ + +#include +#include +#include +#include +#include +#include + +/** + * struct macsmc_input + * @dev: Underlying struct device for the input sub-device + * @smc: Pointer to apple_smc struct of the mfd parent + * @input: Allocated input_dev; devres managed + * @nb: Notifier block used for incoming events from SMC (e.g. button pressed down) + * @wakeup_mode: Set to true when system is suspended and power button events should wake it + * @force_shutdown: True if force reset should shutdown, false if system should restart + */ +struct macsmc_input { + struct device *dev; + struct apple_smc *smc; + struct input_dev *input; + struct notifier_block nb; + bool wakeup_mode; + bool force_shutdown; +}; + +#define SMC_EV_BTN 0x7201 +#define SMC_EV_LID 0x7203 + +#define BTN_POWER 0x01 /* power button on e.g. Mac Mini chasis pressed */ +#define BTN_VOLUMEUP 0x02 /* Volume up */ +#define BTN_VOLUMEDOWN 0x03 /* Volume down */ +#define BTN_MUTE 0x04 /* Mute switch */ +#define BTN_TOUCHID 0x06 /* combined TouchID / power button on MacBooks pressed */ +#define BTN_POWER_HELD_SHORT 0xfe /* power button briefly held down */ +#define BTN_POWER_HELD_LONG 0x00 /* power button held down; sent just before forced poweroff */ + +static void macsmc_input_event_button(struct macsmc_input *smcin, unsigned long event) +{ + u8 button = (event >> 8) & 0xff; + u8 state = !!(event & 0xff); + + switch (button) { + case BTN_POWER: + case BTN_TOUCHID: + pm_wakeup_dev_event(smcin->dev, 0, (smcin->wakeup_mode && state)); + + /* Suppress KEY_POWER event to prevent immediate shutdown on wake */ + if (smcin->wakeup_mode) + return; + + input_report_key(smcin->input, KEY_POWER, state); + input_sync(smcin->input); + break; + case BTN_VOLUMEUP: + input_report_key(smcin->input, KEY_VOLUMEUP, state); + input_sync(smcin->input); + break; + case BTN_VOLUMEDOWN: + input_report_key(smcin->input, KEY_VOLUMEDOWN, state); + input_sync(smcin->input); + break; + case BTN_MUTE: + input_report_key(smcin->input, KEY_MUTE, state); + input_sync(smcin->input); + break; + case BTN_POWER_HELD_SHORT: /* power button held down; ignore */ + break; + case BTN_POWER_HELD_LONG: + /* + * If we get here the power button has been held down for a while and + * we have about 4 seconds before forced power-off is triggered by SMC. + * Try to do an emergency shutdown to make sure the NVMe cache is + * flushed. macOS actually does this by panicing (!)... + */ + if (state) { + dev_crit(smcin->dev, "Triggering forced %s!\n", + smcin->force_shutdown ? "shutdown" : "restart"); + if (smcin->force_shutdown && kernel_can_power_off()) + kernel_power_off(); + else /* Missing macsmc-reboot driver? */ + kernel_restart("SMC power button triggered restart"); + } + break; + default: + dev_warn(smcin->dev, "Unknown SMC button event: %04lx\n", event & 0xffff); + } +} + +static void macsmc_input_event_lid(struct macsmc_input *smcin, unsigned long event) +{ + u8 lid_state = !!((event >> 8) & 0xff); + + pm_wakeup_dev_event(smcin->dev, 0, (smcin->wakeup_mode && !lid_state)); + input_report_switch(smcin->input, SW_LID, lid_state); + input_sync(smcin->input); +} + +static int macsmc_input_event(struct notifier_block *nb, unsigned long event, void *data) +{ + struct macsmc_input *smcin = container_of(nb, struct macsmc_input, nb); + u16 type = event >> 16; + + switch (type) { + case SMC_EV_BTN: + macsmc_input_event_button(smcin, event); + return NOTIFY_OK; + case SMC_EV_LID: + macsmc_input_event_lid(smcin, event); + return NOTIFY_OK; + default: + /* SMC event meant for another driver */ + return NOTIFY_DONE; + } +} + +static int macsmc_input_probe(struct platform_device *pdev) +{ + struct apple_smc *smc = dev_get_drvdata(pdev->dev.parent); + struct macsmc_input *smcin; + bool have_lid, have_power, have_volup, have_voldown, have_mute; + int error; + bool is_t8012; + + is_t8012 = of_device_is_compatible(pdev->dev.parent->of_node, + "apple,t8012-smc"); + + /* Bail early if this SMC does not support lid nor any buttons */ + have_lid = apple_smc_key_exists(smc, SMC_KEY(MSLD)); + + /* T2's SMC reports the power button but no corresponding key */ + have_power = apple_smc_key_exists(smc, SMC_KEY(bHLD)) || is_t8012; + have_volup = apple_smc_key_exists(smc, SMC_KEY(bVUP)); + have_voldown = apple_smc_key_exists(smc, SMC_KEY(bVDN)); + have_mute = apple_smc_key_exists(smc, SMC_KEY(bRIN)); + if (!have_lid && !have_power && !have_volup && !have_voldown + && !have_mute) + return -ENODEV; + + smcin = devm_kzalloc(&pdev->dev, sizeof(*smcin), GFP_KERNEL); + if (!smcin) + return -ENOMEM; + + smcin->dev = &pdev->dev; + smcin->smc = smc; + platform_set_drvdata(pdev, smcin); + + smcin->input = devm_input_allocate_device(&pdev->dev); + if (!smcin->input) + return -ENOMEM; + + if (!of_device_is_compatible(pdev->dev.parent->of_node, "apple,t8015-smc")) + smcin->force_shutdown = true; + + smcin->input->phys = "macsmc-input (0)"; + smcin->input->name = "Apple SMC power/lid events"; + + if (have_lid) + input_set_capability(smcin->input, EV_SW, SW_LID); + if (have_power) + input_set_capability(smcin->input, EV_KEY, KEY_POWER); + if (have_volup) + input_set_capability(smcin->input, EV_KEY, KEY_VOLUMEUP); + if (have_voldown) + input_set_capability(smcin->input, EV_KEY, KEY_VOLUMEDOWN); + if (have_mute) + input_set_capability(smcin->input, EV_KEY, KEY_MUTE); + + if (have_lid) { + u8 val; + + error = apple_smc_read_u8(smc, SMC_KEY(MSLD), &val); + if (error < 0) + dev_warn(&pdev->dev, "Failed to read initial lid state\n"); + else + input_report_switch(smcin->input, SW_LID, val); + } + + if (have_power && !is_t8012) { + u32 val; + + error = apple_smc_read_u32(smc, SMC_KEY(bHLD), &val); + if (error < 0) + dev_warn(&pdev->dev, "Failed to read initial power button state\n"); + else + input_report_key(smcin->input, KEY_POWER, val & 1); + } + + if (have_volup) { + u32 val; + + error = apple_smc_read_u32(smc, SMC_KEY(bVUP), &val); + if (error < 0) + dev_warn(&pdev->dev, "Failed to read initial volume up button state\n"); + else + input_report_key(smcin->input, KEY_VOLUMEUP, val & 1); + } + + if (have_voldown) { + u32 val; + + error = apple_smc_read_u32(smc, SMC_KEY(bVDN), &val); + if (error < 0) + dev_warn(&pdev->dev, "Failed to read initial volume down button state\n"); + else + input_report_key(smcin->input, KEY_VOLUMEDOWN, val & 1); + } + + if (have_mute) { + u32 val; + + error = apple_smc_read_u32(smc, SMC_KEY(bRIN), &val); + if (error < 0) + dev_warn(&pdev->dev, "Failed to read initial mute switch state\n"); + else + input_report_key(smcin->input, KEY_MUTE, val & 1); + } + + error = input_register_device(smcin->input); + if (error) { + dev_err(&pdev->dev, "Failed to register input device: %d\n", error); + return error; + } + + input_sync(smcin->input); + + smcin->nb.notifier_call = macsmc_input_event; + blocking_notifier_chain_register(&smc->event_handlers, &smcin->nb); + + device_init_wakeup(&pdev->dev, true); + + return 0; +} + +static int macsmc_input_pm_prepare(struct device *dev) +{ + struct macsmc_input *smcin = dev_get_drvdata(dev); + + smcin->wakeup_mode = true; + return 0; +} + +static void macsmc_input_pm_complete(struct device *dev) +{ + struct macsmc_input *smcin = dev_get_drvdata(dev); + + smcin->wakeup_mode = false; +} + +static const struct dev_pm_ops macsmc_input_pm_ops = { + .prepare = macsmc_input_pm_prepare, + .complete = macsmc_input_pm_complete, +}; + +static struct platform_driver macsmc_input_driver = { + .driver = { + .name = "macsmc-input", + .pm = &macsmc_input_pm_ops, + }, + .probe = macsmc_input_probe, +}; +module_platform_driver(macsmc_input_driver); + +MODULE_AUTHOR("Hector Martin "); +MODULE_LICENSE("Dual MIT/GPL"); +MODULE_DESCRIPTION("Apple SMC input driver"); +MODULE_ALIAS("platform:macsmc-input"); diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 7192c9d1d268e9..b4bf85460e478e 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1492,6 +1492,19 @@ config MFD_SIMPLE_MFD_I2C sub-devices represented by child nodes in Device Tree will be subsequently registered. +config MFD_SIMPLE_MFD_SPMI + tristate + depends on SPMI + select MFD_CORE + select REGMAP_SPMI + help + This driver creates a single register map with the intention for it + to be shared by all sub-devices. + + Once the register map has been successfully initialised, any + sub-devices represented by child nodes in Device Tree will be + subsequently registered. + config MFD_SL28CPLD tristate "Kontron sl28cpld Board Management Controller" depends on I2C diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index e75e8045c28afa..25eccceaa3ed8d 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -285,6 +285,7 @@ obj-$(CONFIG_MFD_QCOM_PM8008) += qcom-pm8008.o obj-$(CONFIG_SGI_MFD_IOC3) += ioc3.o obj-$(CONFIG_MFD_SIMPLE_MFD_I2C) += simple-mfd-i2c.o +obj-$(CONFIG_MFD_SIMPLE_MFD_SPMI) += simple-mfd-spmi.o obj-$(CONFIG_MFD_SMPRO) += smpro-core.o obj-$(CONFIG_MFD_INTEL_M10_BMC_CORE) += intel-m10-bmc-core.o diff --git a/drivers/mfd/macsmc.c b/drivers/mfd/macsmc.c index 358feec2d088fc..c259d074b260b4 100644 --- a/drivers/mfd/macsmc.c +++ b/drivers/mfd/macsmc.c @@ -21,7 +21,7 @@ #include #include -#define SMC_ENDPOINT 0x20 +#define SMC_APP_ENDPOINT 0 /* We don't actually know the true size here but this seem reasonable */ #define SMC_SHMEM_SIZE 0x1000 @@ -44,7 +44,19 @@ #define SMC_TIMEOUT_MS 500 -static const struct mfd_cell apple_smc_devs[] = { +#define SMC_TYPE_T8012 0x8012 +#define SMC_TYPE_T8015 0x8015 +#define SMC_TYPE_T8103 0x8103 + +static const struct mfd_cell apple_smc_t8015_devs[] = { + MFD_CELL_NAME("macsmc-input"), + MFD_CELL_NAME("macsmc-power"), + MFD_CELL_OF("macsmc-gpio", NULL, NULL, 0, 0, "apple,smc-gpio"), + MFD_CELL_OF("macsmc-hwmon", NULL, NULL, 0, 0, "apple,smc-hwmon"), + MFD_CELL_OF("macsmc-reboot", NULL, NULL, 0, 0, "apple,t8015-smc-reboot"), +}; + +static const struct mfd_cell apple_smc_t8103_devs[] = { MFD_CELL_NAME("macsmc-input"), MFD_CELL_NAME("macsmc-power"), MFD_CELL_OF("macsmc-gpio", NULL, NULL, 0, 0, "apple,smc-gpio"), @@ -76,7 +88,7 @@ static int apple_smc_cmd_locked(struct apple_smc *smc, u64 cmd, u64 arg, FIELD_PREP(SMC_ID, smc->msg_id) | FIELD_PREP(SMC_DATA, arg)); - ret = apple_rtkit_send_message(smc->rtk, SMC_ENDPOINT, msg, NULL, false); + ret = apple_rtkit_send_message(smc->rtk, smc->ep, msg, NULL, false); if (ret) { dev_err(smc->dev, "Failed to send command\n"); return ret; @@ -266,7 +278,7 @@ int apple_smc_write_atomic(struct apple_smc *smc, smc_key key, const void *buf, FIELD_PREP(SMC_DATA, key)); smc->atomic_pending = true; - ret = apple_rtkit_send_message(smc->rtk, SMC_ENDPOINT, msg, NULL, true); + ret = apple_rtkit_send_message(smc->rtk, smc->ep, msg, NULL, true); if (ret < 0) { dev_err(smc->dev, "Failed to send command (%d)\n", ret); return ret; @@ -334,7 +346,7 @@ static bool apple_smc_rtkit_recv_early(void *cookie, u8 endpoint, u64 message) { struct apple_smc *smc = cookie; - if (endpoint != SMC_ENDPOINT) { + if (endpoint != smc->ep) { dev_warn(smc->dev, "Received message for unknown endpoint 0x%x\n", endpoint); return false; } @@ -370,7 +382,7 @@ static void apple_smc_rtkit_recv(void *cookie, u8 endpoint, u64 message) { struct apple_smc *smc = cookie; - if (endpoint != SMC_ENDPOINT) { + if (endpoint != smc->ep) { dev_warn(smc->dev, "Received message for unknown endpoint 0x%x\n", endpoint); return; } @@ -410,8 +422,30 @@ static int apple_smc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct apple_smc *smc; - u32 count; + u32 count, dev_cnt; + const struct mfd_cell *devs; int ret; + uintptr_t type; + + type = (uintptr_t)of_device_get_match_data(dev); + switch (type) { + /* + * T8012 has differences in button and RTC handling + * Currently it works with T8015. + */ + case SMC_TYPE_T8012: + case SMC_TYPE_T8015: + devs = apple_smc_t8015_devs; + dev_cnt = ARRAY_SIZE(apple_smc_t8015_devs); + break; + case SMC_TYPE_T8103: + devs = apple_smc_t8103_devs; + dev_cnt = ARRAY_SIZE(apple_smc_t8103_devs); + break; + default: + WARN_ON(1); + return -ENODEV; + } smc = devm_kzalloc(dev, sizeof(*smc), GFP_KERNEL); if (!smc) @@ -432,18 +466,22 @@ static int apple_smc_probe(struct platform_device *pdev) if (ret) return dev_err_probe(dev, ret, "Failed to wake up SMC"); + smc->ep = apple_rtkit_app_ep_to_ep(smc->rtk, SMC_APP_ENDPOINT); + if (!smc->ep) + return dev_err_probe(dev, ret, "Failed to get SMC endpoint"); + ret = devm_add_action_or_reset(dev, apple_smc_rtkit_shutdown, smc); if (ret) return ret; - ret = apple_rtkit_start_ep(smc->rtk, SMC_ENDPOINT); + ret = apple_rtkit_start_ep(smc->rtk, smc->ep); if (ret) return dev_err_probe(dev, ret, "Failed to start SMC endpoint"); init_completion(&smc->init_done); init_completion(&smc->cmd_done); - ret = apple_rtkit_send_message(smc->rtk, SMC_ENDPOINT, + ret = apple_rtkit_send_message(smc->rtk, smc->ep, FIELD_PREP(SMC_MSG, SMC_MSG_INITIALIZE), NULL, false); if (ret) return dev_err_probe(dev, ret, "Failed to send init message"); @@ -472,8 +510,7 @@ static int apple_smc_probe(struct platform_device *pdev) if (ret) return ret; - ret = devm_mfd_add_devices(smc->dev, PLATFORM_DEVID_NONE, - apple_smc_devs, ARRAY_SIZE(apple_smc_devs), + ret = devm_mfd_add_devices(smc->dev, PLATFORM_DEVID_NONE, devs, dev_cnt, NULL, 0, NULL); if (ret) return dev_err_probe(smc->dev, ret, "Failed to register sub-devices"); @@ -483,8 +520,10 @@ static int apple_smc_probe(struct platform_device *pdev) } static const struct of_device_id apple_smc_of_match[] = { - { .compatible = "apple,t8103-smc" }, - { .compatible = "apple,smc" }, + { .compatible = "apple,t8012-smc", .data = (void*)SMC_TYPE_T8012 }, + { .compatible = "apple,t8015-smc", .data = (void*)SMC_TYPE_T8015 }, + { .compatible = "apple,t8103-smc", .data = (void*)SMC_TYPE_T8103 }, + { .compatible = "apple,smc", .data = (void*)SMC_TYPE_T8103 }, {}, }; MODULE_DEVICE_TABLE(of, apple_smc_of_match); diff --git a/drivers/mfd/simple-mfd-i2c.c b/drivers/mfd/simple-mfd-i2c.c index 7315fad618e445..e000b08dbcd94c 100644 --- a/drivers/mfd/simple-mfd-i2c.c +++ b/drivers/mfd/simple-mfd-i2c.c @@ -35,6 +35,11 @@ static const struct regmap_config regmap_config_8r_8v = { .val_bits = 8, }; +static const struct regmap_config regmap_config_16r_8v = { + .reg_bits = 16, + .val_bits = 8, +}; + static int simple_mfd_i2c_probe(struct i2c_client *i2c) { const struct simple_mfd_data *simple_mfd_data; @@ -68,6 +73,10 @@ static int simple_mfd_i2c_probe(struct i2c_client *i2c) return ret; } +static const struct simple_mfd_data apple_i2c_pmic = { + .regmap_config = ®map_config_16r_8v +}; + static const struct mfd_cell sy7636a_cells[] = { { .name = "sy7636a-regulator", }, { .name = "sy7636a-temperature", }, @@ -116,6 +125,7 @@ static const struct simple_mfd_data spacemit_p1 = { }; static const struct of_device_id simple_mfd_i2c_of_match[] = { + { .compatible = "apple,i2c-pmic", .data = &apple_i2c_pmic }, { .compatible = "delta,tn48m-cpld" }, { .compatible = "fsl,ls1028aqds-fpga" }, { .compatible = "fsl,lx2160aqds-fpga" }, diff --git a/drivers/mfd/simple-mfd-spmi.c b/drivers/mfd/simple-mfd-spmi.c new file mode 100644 index 00000000000000..699ea5b7327420 --- /dev/null +++ b/drivers/mfd/simple-mfd-spmi.c @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Simple MFD - SPMI + * + * Copyright The Asahi Linux Contributors + */ + +#include +#include +#include +#include +#include + +static const struct regmap_config spmi_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .max_register = 0xffff, +}; + +static int simple_spmi_probe(struct spmi_device *sdev) +{ + struct regmap *regmap; + + regmap = devm_regmap_init_spmi_ext(sdev, &spmi_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + return devm_of_platform_populate(&sdev->dev); +} + +static const struct of_device_id simple_spmi_id_table[] = { + { .compatible = "apple,spmi-pmic" }, + {} +}; +MODULE_DEVICE_TABLE(of, simple_spmi_id_table); + +static struct spmi_driver pmic_spmi_driver = { + .probe = simple_spmi_probe, + .driver = { + .name = "simple-mfd-spmi", + .of_match_table = simple_spmi_id_table, + }, +}; +module_spmi_driver(pmic_spmi_driver); + +MODULE_LICENSE("Dual MIT/GPL"); +MODULE_DESCRIPTION("Simple MFD - SPMI driver"); +MODULE_AUTHOR("Hector Martin "); diff --git a/drivers/nvme/host/apple.c b/drivers/nvme/host/apple.c index c692fc73babfe5..e88f6a5c9dae05 100644 --- a/drivers/nvme/host/apple.c +++ b/drivers/nvme/host/apple.c @@ -203,6 +203,16 @@ struct apple_nvme { int irq; spinlock_t lock; + + /* + * t8015's ANS seems to treat the command tag as global across + * both the admin and I/O queues rather than per-queue. It's not + * clear why; our best guess is the firmware keys some internal + * state off the tag alone, so reusing one that's still live on + * the other queue upsets it. Track the in-flight tags here and + * hold off submitting until the tag is free. + */ + unsigned long t8015_active_tags; }; static_assert(sizeof(struct nvme_command) == 64); @@ -290,6 +300,28 @@ static void apple_nvmmu_inval(struct apple_nvme_queue *q, unsigned int tag) "NVMMU TCB invalidation failed\n"); } +static bool apple_nvme_reserve_tag_t8015(struct apple_nvme *anv, + struct nvme_command *cmd) +{ + u16 tag = nvme_tag_from_cid(cmd->common.command_id); + + if (WARN_ON_ONCE(tag >= BITS_PER_LONG)) + return false; + + return !test_and_set_bit(tag, &anv->t8015_active_tags); +} + +static void apple_nvme_release_cid_t8015(struct apple_nvme *anv, + __u16 command_id) +{ + u16 tag = nvme_tag_from_cid(command_id); + + if (WARN_ON_ONCE(tag >= BITS_PER_LONG)) + return; + + clear_bit(tag, &anv->t8015_active_tags); +} + static void apple_nvme_submit_cmd_t8015(struct apple_nvme_queue *q, struct nvme_command *cmd) { @@ -310,7 +342,6 @@ static void apple_nvme_submit_cmd_t8015(struct apple_nvme_queue *q, spin_unlock_irq(&anv->lock); } - static void apple_nvme_submit_cmd_t8103(struct apple_nvme_queue *q, struct nvme_command *cmd) { @@ -652,9 +683,14 @@ static inline void apple_nvme_update_cq_head(struct apple_nvme_queue *q) static bool apple_nvme_poll_cq(struct apple_nvme_queue *q, struct io_comp_batch *iob) { + struct apple_nvme *anv = queue_to_apple_nvme(q); + unsigned long completed_tags = 0; bool found = false; while (apple_nvme_cqe_pending(q)) { + struct nvme_completion *cqe = &q->cqes[q->cq_head]; + __u16 command_id; + found = true; /* @@ -662,13 +698,30 @@ static bool apple_nvme_poll_cq(struct apple_nvme_queue *q, * the cqe requires a full read memory barrier */ dma_rmb(); + + command_id = READ_ONCE(cqe->command_id); + apple_nvme_handle_cqe(q, iob, q->cq_head); apple_nvme_update_cq_head(q); + + if (!anv->hw->has_lsq_nvmmu) { + u16 tag = nvme_tag_from_cid(command_id); + + if (!WARN_ON_ONCE(tag >= BITS_PER_LONG)) + __set_bit(tag, &completed_tags); + } } if (found) writel(q->cq_head, q->cq_db); + if (!anv->hw->has_lsq_nvmmu && completed_tags) { + unsigned int tag; + + for_each_set_bit(tag, &completed_tags, BITS_PER_LONG) + clear_bit(tag, &anv->t8015_active_tags); + } + return found; } @@ -790,10 +843,20 @@ static blk_status_t apple_nvme_queue_rq(struct blk_mq_hw_ctx *hctx, if (ret) return ret; + if (!anv->hw->has_lsq_nvmmu && + !apple_nvme_reserve_tag_t8015(anv, cmnd)) { + ret = BLK_STS_RESOURCE; + goto out_free_cmd; + } + if (blk_rq_nr_phys_segments(req)) { ret = apple_nvme_map_data(anv, req, cmnd); - if (ret) + if (ret) { + if (!anv->hw->has_lsq_nvmmu) + apple_nvme_release_cid_t8015(anv, + cmnd->common.command_id); goto out_free_cmd; + } } nvme_start_request(req); @@ -1165,6 +1228,9 @@ static void apple_nvme_reset_work(struct work_struct *work) if (ret) goto out; + if (!anv->hw->has_lsq_nvmmu) + WRITE_ONCE(anv->t8015_active_tags, 0); + dev_dbg(anv->dev, "Starting admin queue"); apple_nvme_init_queue(&anv->adminq); nvme_unquiesce_admin_queue(&anv->ctrl); diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig index 74ddbd0f79b0ec..1bafd8f4cc3af4 100644 --- a/drivers/nvmem/Kconfig +++ b/drivers/nvmem/Kconfig @@ -365,6 +365,18 @@ config NVMEM_SNVS_LPGPR This driver can also be built as a module. If so, the module will be called nvmem-snvs-lpgpr. +config NVMEM_SIMPLE_MFD + tristate "Simple MFD - I2C/SPMI NVMEM" + depends on MFD_SIMPLE_MFD_I2C || MFD_SIMPLE_MFD_SPMI || COMPILE_TEST + help + Say y here to build a generic driver to expose an simple MFD device + as a NVMEM provider. Both I2C and SPMI MFDs are supported. This can + be used for PMIC devices which are used to store power and + RTC-related settings on certain platforms, such as Apple iPhones. + + This driver can also be built as a module. If so, the module + will be called nvmem-simple-mfd. + config NVMEM_SPMI_SDAM tristate "SPMI SDAM Support" depends on SPMI diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile index 7252b8ec88d469..6f8812210436db 100644 --- a/drivers/nvmem/Makefile +++ b/drivers/nvmem/Makefile @@ -72,6 +72,8 @@ obj-$(CONFIG_NVMEM_SC27XX_EFUSE) += nvmem-sc27xx-efuse.o nvmem-sc27xx-efuse-y := sc27xx-efuse.o obj-$(CONFIG_NVMEM_SNVS_LPGPR) += nvmem_snvs_lpgpr.o nvmem_snvs_lpgpr-y := snvs_lpgpr.o +obj-$(CONFIG_NVMEM_SIMPLE_MFD) += nvmem_simple_mfd.o +nvmem_simple_mfd-y := simple-mfd-nvmem.o obj-$(CONFIG_NVMEM_SPMI_SDAM) += nvmem_qcom-spmi-sdam.o nvmem_qcom-spmi-sdam-y += qcom-spmi-sdam.o obj-$(CONFIG_NVMEM_SPRD_EFUSE) += nvmem_sprd_efuse.o diff --git a/drivers/nvmem/simple-mfd-nvmem.c b/drivers/nvmem/simple-mfd-nvmem.c new file mode 100644 index 00000000000000..2ae862185b0108 --- /dev/null +++ b/drivers/nvmem/simple-mfd-nvmem.c @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Simple MFD - I2C/SPMI NVMEM driver + * + * Copyright The Asahi Linux Contributors + */ + +#include +#include +#include +#include +#include +#include + +struct simple_mfd_nvmem { + struct regmap *regmap; + unsigned int base; +}; + +static int simple_mfd_nvmem_read(void *priv, unsigned int offset, + void *val, size_t bytes) +{ + struct simple_mfd_nvmem *nvmem = priv; + + return regmap_bulk_read(nvmem->regmap, nvmem->base + offset, val, bytes); +} + +static int simple_mfd_nvmem_write(void *priv, unsigned int offset, + void *val, size_t bytes) +{ + struct simple_mfd_nvmem *nvmem = priv; + + return regmap_bulk_write(nvmem->regmap, nvmem->base + offset, val, bytes); +} + +static int simple_mfd_nvmem_probe(struct platform_device *pdev) +{ + struct simple_mfd_nvmem *nvmem; + const __be32 *addr; + int len; + struct nvmem_config nvmem_cfg = { + .dev = &pdev->dev, + .name = "simple_mfd_nvmem", + .id = NVMEM_DEVID_AUTO, + .word_size = 1, + .stride = 1, + .reg_read = simple_mfd_nvmem_read, + .reg_write = simple_mfd_nvmem_write, + .add_legacy_fixed_of_cells = true, + }; + + nvmem = devm_kzalloc(&pdev->dev, sizeof(*nvmem), GFP_KERNEL); + if (!nvmem) + return -ENOMEM; + + nvmem_cfg.priv = nvmem; + + nvmem->regmap = dev_get_regmap(pdev->dev.parent, NULL); + if (!nvmem->regmap) { + dev_err(&pdev->dev, "Parent regmap unavailable.\n"); + return -ENXIO; + } + + addr = of_get_property(pdev->dev.of_node, "reg", &len); + if (!addr) { + dev_err(&pdev->dev, "No reg property\n"); + return -EINVAL; + } + if (len != 2 * sizeof(u32)) { + dev_err(&pdev->dev, "Invalid reg property\n"); + return -EINVAL; + } + + nvmem->base = be32_to_cpup(&addr[0]); + nvmem_cfg.size = be32_to_cpup(&addr[1]); + + return PTR_ERR_OR_ZERO(devm_nvmem_register(&pdev->dev, &nvmem_cfg)); +} + +static const struct of_device_id simple_mfd_nvmem_id_table[] = { + { .compatible = "apple,pmic-nvmem" }, + {} +}; +MODULE_DEVICE_TABLE(of, simple_mfd_nvmem_id_table); + +static struct platform_driver simple_mfd_nvmem_driver = { + .probe = simple_mfd_nvmem_probe, + .driver = { + .name = "simple-mfd-nvmem", + .of_match_table = simple_mfd_nvmem_id_table, + }, +}; + +module_platform_driver(simple_mfd_nvmem_driver); + +MODULE_LICENSE("Dual MIT/GPL"); +MODULE_AUTHOR("Hector Martin "); +MODULE_DESCRIPTION("Simple MFD - I2C/SPMI NVMEM driver"); diff --git a/drivers/of/address.c b/drivers/of/address.c index cf4aab11e9b1f1..48aea863796a33 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -784,7 +784,6 @@ int of_pci_dma_range_parser_init(struct of_pci_range_parser *parser, return parser_init(parser, node, "dma-ranges"); } EXPORT_SYMBOL_GPL(of_pci_dma_range_parser_init); -#define of_dma_range_parser_init of_pci_dma_range_parser_init struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser, struct of_pci_range *range) diff --git a/drivers/perf/apple_m1_cpu_pmu.c b/drivers/perf/apple_m1_cpu_pmu.c index 81b6f1a6234995..23cff6e6c4e701 100644 --- a/drivers/perf/apple_m1_cpu_pmu.c +++ b/drivers/perf/apple_m1_cpu_pmu.c @@ -19,13 +19,16 @@ #include #include +#define A7_PMU_NR_COUNTERS 8 #define M1_PMU_NR_COUNTERS 10 +#define APPLE_PMU_MAX_NR_COUNTERS 10 #define M1_PMU_CFG_EVENT GENMASK(7, 0) #define ANY_BUT_0_1 GENMASK(9, 2) #define ONLY_2_TO_7 GENMASK(7, 2) #define ONLY_2_4_6 (BIT(2) | BIT(4) | BIT(6)) +#define ONLY_3_5_7 (BIT(3) | BIT(5) | BIT(7)) #define ONLY_5_6_7 (BIT(5) | BIT(6) | BIT(7)) /* @@ -43,10 +46,574 @@ * moment, we don't really need to distinguish between the two because we * know next to nothing about the events themselves, and we already have * per cpu-type PMU abstractions. - * - * If we eventually find out that the events are different across - * implementations, we'll have to introduce per cpu-type tables. */ + +enum a7_pmu_events { + A7_PMU_PERFCTR_INST_ALL = 0x0, + A7_PMU_PERFCTR_UNKNOWN_1 = 0x1, + A7_PMU_PERFCTR_CORE_ACTIVE_CYCLE = 0x2, + A7_PMU_PERFCTR_L2_TLB_MISS_INSTRUCTION = 0x10, + A7_PMU_PERFCTR_L2_TLB_MISS_DATA = 0x11, + A7_PMU_PERFCTR_BIU_UPSTREAM_CYCLE = 0x19, + A7_PMU_PERFCTR_BIU_DOWNSTREAM_CYCLE = 0x20, + A7_PMU_PERFCTR_L2C_AGENT_LD = 0x22, + A7_PMU_PERFCTR_L2C_AGENT_LD_MISS = 0x23, + A7_PMU_PERFCTR_L2C_AGENT_ST = 0x24, + A7_PMU_PERFCTR_L2C_AGENT_ST_MISS = 0x25, + A7_PMU_PERFCTR_SCHEDULE_UOP = 0x58, + A7_PMU_PERFCTR_MAP_REWIND = 0x61, + A7_PMU_PERFCTR_MAP_STALL = 0x62, + A7_PMU_PERFCTR_FLUSH_RESTART_OTHER_NONSPEC = 0x6e, + A7_PMU_PERFCTR_INST_A32 = 0x78, + A7_PMU_PERFCTR_INST_T32 = 0x79, + A7_PMU_PERFCTR_INST_A64 = 0x7a, + A7_PMU_PERFCTR_INST_BRANCH = 0x7b, + A7_PMU_PERFCTR_INST_BRANCH_CALL = 0x7c, + A7_PMU_PERFCTR_INST_BRANCH_RET = 0x7d, + A7_PMU_PERFCTR_INST_BRANCH_TAKEN = 0x7e, + A7_PMU_PERFCTR_INST_BRANCH_INDIR = 0x81, + A7_PMU_PERFCTR_INST_BRANCH_COND = 0x82, + A7_PMU_PERFCTR_INST_INT_LD = 0x83, + A7_PMU_PERFCTR_INST_INT_ST = 0x84, + A7_PMU_PERFCTR_INST_INT_ALU = 0x85, + A7_PMU_PERFCTR_INST_SIMD_LD = 0x86, + A7_PMU_PERFCTR_INST_SIMD_ST = 0x87, + A7_PMU_PERFCTR_INST_SIMD_ALU = 0x88, + A7_PMU_PERFCTR_INST_LDST = 0x89, + A7_PMU_PERFCTR_UNKNOWN_8d = 0x8d, + A7_PMU_PERFCTR_UNKNOWN_8e = 0x8e, + A7_PMU_PERFCTR_UNKNOWN_8f = 0x8f, + A7_PMU_PERFCTR_UNKNOWN_90 = 0x90, + A7_PMU_PERFCTR_UNKNOWN_93 = 0x93, + A7_PMU_PERFCTR_UNKNOWN_94 = 0x94, + A7_PMU_PERFCTR_UNKNOWN_95 = 0x95, + A7_PMU_PERFCTR_L1D_TLB_ACCESS = 0x96, + A7_PMU_PERFCTR_L1D_TLB_MISS = 0x97, + A7_PMU_PERFCTR_L1D_CACHE_MISS_ST = 0x98, + A7_PMU_PERFCTR_L1D_CACHE_MISS_LD = 0x99, + A7_PMU_PERFCTR_UNKNOWN_9b = 0x9b, + A7_PMU_PERFCTR_LD_UNIT_UOP = 0x9c, + A7_PMU_PERFCTR_ST_UNIT_UOP = 0x9d, + A7_PMU_PERFCTR_L1D_CACHE_WRITEBACK = 0x9e, + A7_PMU_PERFCTR_UNKNOWN_9f = 0x9f, + A7_PMU_PERFCTR_LDST_X64_UOP = 0xa7, + A7_PMU_PERFCTR_L1D_CACHE_MISS_LD_NONSPEC = 0xb4, + A7_PMU_PERFCTR_L1D_CACHE_MISS_ST_NONSPEC = 0xb5, + A7_PMU_PERFCTR_L1D_TLB_MISS_NONSPEC = 0xb6, + A7_PMU_PERFCTR_ST_MEMORY_ORDER_VIOLATION_NONSPEC = 0xb9, + A7_PMU_PERFCTR_BRANCH_COND_MISPRED_NONSPEC = 0xba, + A7_PMU_PERFCTR_BRANCH_INDIR_MISPRED_NONSPEC = 0xbb, + A7_PMU_PERFCTR_BRANCH_RET_INDIR_MISPRED_NONSPEC = 0xbd, + A7_PMU_PERFCTR_BRANCH_CALL_INDIR_MISPRED_NONSPEC = 0xbf, + A7_PMU_PERFCTR_BRANCH_MISPRED_NONSPEC = 0xc0, + A7_PMU_PERFCTR_UNKNOWN_c1 = 0xc1, + A7_PMU_PERFCTR_UNKNOWN_c4 = 0xc4, + A7_PMU_PERFCTR_UNKNOWN_c5 = 0xc5, + A7_PMU_PERFCTR_UNKNOWN_c6 = 0xc6, + A7_PMU_PERFCTR_UNKNOWN_c8 = 0xc8, + A7_PMU_PERFCTR_UNKNOWN_ca = 0xca, + A7_PMU_PERFCTR_UNKNOWN_cb = 0xcb, + A7_PMU_PERFCTR_FED_IC_MISS_DEMAND = 0xce, + A7_PMU_PERFCTR_L1I_TLB_MISS_DEMAND = 0xcf, + A7_PMU_PERFCTR_UNKNOWN_f5 = 0xf5, + A7_PMU_PERFCTR_UNKNOWN_f6 = 0xf6, + A7_PMU_PERFCTR_UNKNOWN_f7 = 0xf7, + A7_PMU_PERFCTR_UNKNOWN_f8 = 0xf8, + A7_PMU_PERFCTR_UNKNOWN_fd = 0xfd, + A7_PMU_PERFCTR_LAST = M1_PMU_CFG_EVENT, + /* + * From this point onwards, these are not actual HW events, + * but attributes that get stored in hw->config_base. + */ + A7_PMU_CFG_COUNT_USER = BIT(8), + A7_PMU_CFG_COUNT_KERNEL = BIT(9), +}; + +static const u16 a7_pmu_event_affinity[A7_PMU_PERFCTR_LAST + 1] = { + [0 ... A7_PMU_PERFCTR_LAST] = ANY_BUT_0_1, + [A7_PMU_PERFCTR_INST_ALL] = ANY_BUT_0_1 | BIT(1), + [A7_PMU_PERFCTR_UNKNOWN_1] = ONLY_5_6_7, + [A7_PMU_PERFCTR_CORE_ACTIVE_CYCLE] = ANY_BUT_0_1 | BIT(0), + [A7_PMU_PERFCTR_INST_A32] = ONLY_5_6_7, + [A7_PMU_PERFCTR_INST_T32] = ONLY_5_6_7, + [A7_PMU_PERFCTR_INST_A64] = ONLY_5_6_7, + [A7_PMU_PERFCTR_INST_BRANCH] = ONLY_5_6_7, + [A7_PMU_PERFCTR_INST_BRANCH_CALL] = ONLY_5_6_7, + [A7_PMU_PERFCTR_INST_BRANCH_RET] = ONLY_5_6_7, + [A7_PMU_PERFCTR_INST_BRANCH_TAKEN] = ONLY_5_6_7, + [A7_PMU_PERFCTR_INST_BRANCH_INDIR] = ONLY_5_6_7, + [A7_PMU_PERFCTR_INST_BRANCH_COND] = ONLY_5_6_7, + [A7_PMU_PERFCTR_INST_INT_LD] = ONLY_5_6_7, + [A7_PMU_PERFCTR_INST_INT_ST] = ONLY_5_6_7, + [A7_PMU_PERFCTR_INST_INT_ALU] = ONLY_5_6_7, + [A7_PMU_PERFCTR_INST_SIMD_LD] = ONLY_5_6_7, + [A7_PMU_PERFCTR_INST_SIMD_ST] = ONLY_5_6_7, + [A7_PMU_PERFCTR_INST_SIMD_ALU] = ONLY_5_6_7, + [A7_PMU_PERFCTR_INST_LDST] = ONLY_5_6_7, + [A7_PMU_PERFCTR_UNKNOWN_8d] = ONLY_5_6_7, + [A7_PMU_PERFCTR_UNKNOWN_8e] = ONLY_5_6_7, + [A7_PMU_PERFCTR_UNKNOWN_8f] = ONLY_5_6_7, + [A7_PMU_PERFCTR_UNKNOWN_90] = ONLY_5_6_7, + [A7_PMU_PERFCTR_UNKNOWN_93] = ONLY_5_6_7, + [A7_PMU_PERFCTR_UNKNOWN_94] = ONLY_5_6_7, + [A7_PMU_PERFCTR_UNKNOWN_95] = ONLY_5_6_7, + [A7_PMU_PERFCTR_L1D_CACHE_MISS_ST] = ONLY_5_6_7, + [A7_PMU_PERFCTR_L1D_CACHE_MISS_LD] = ONLY_5_6_7, + [A7_PMU_PERFCTR_UNKNOWN_9b] = ONLY_5_6_7, + [A7_PMU_PERFCTR_LD_UNIT_UOP] = ONLY_5_6_7, + [A7_PMU_PERFCTR_UNKNOWN_9f] = ONLY_5_6_7, + [A7_PMU_PERFCTR_L1D_CACHE_MISS_LD_NONSPEC] = ONLY_5_6_7, + [A7_PMU_PERFCTR_L1D_CACHE_MISS_ST_NONSPEC] = ONLY_5_6_7, + [A7_PMU_PERFCTR_L1D_TLB_MISS_NONSPEC] = ONLY_5_6_7, + [A7_PMU_PERFCTR_ST_MEMORY_ORDER_VIOLATION_NONSPEC] = ONLY_5_6_7, + [A7_PMU_PERFCTR_BRANCH_COND_MISPRED_NONSPEC] = ONLY_5_6_7, + [A7_PMU_PERFCTR_BRANCH_INDIR_MISPRED_NONSPEC] = ONLY_5_6_7, + [A7_PMU_PERFCTR_BRANCH_RET_INDIR_MISPRED_NONSPEC] = ONLY_5_6_7, + [A7_PMU_PERFCTR_BRANCH_CALL_INDIR_MISPRED_NONSPEC] = ONLY_5_6_7, + [A7_PMU_PERFCTR_BRANCH_MISPRED_NONSPEC] = ONLY_5_6_7, + [A7_PMU_PERFCTR_UNKNOWN_c1] = ONLY_5_6_7, + [A7_PMU_PERFCTR_UNKNOWN_c4] = ONLY_5_6_7, + [A7_PMU_PERFCTR_UNKNOWN_c5] = ONLY_5_6_7, + [A7_PMU_PERFCTR_UNKNOWN_c6] = ONLY_5_6_7, + [A7_PMU_PERFCTR_UNKNOWN_c8] = ONLY_5_6_7, + [A7_PMU_PERFCTR_UNKNOWN_ca] = ONLY_5_6_7, + [A7_PMU_PERFCTR_UNKNOWN_cb] = ONLY_5_6_7, + [A7_PMU_PERFCTR_UNKNOWN_f5] = ONLY_2_4_6, + [A7_PMU_PERFCTR_UNKNOWN_f6] = ONLY_2_4_6, + [A7_PMU_PERFCTR_UNKNOWN_f7] = ONLY_2_4_6, + [A7_PMU_PERFCTR_UNKNOWN_fd] = ONLY_2_4_6, +}; + +enum a8_pmu_events { + A8_PMU_PERFCTR_UNKNOWN_1 = 0x1, + A8_PMU_PERFCTR_CORE_ACTIVE_CYCLE = 0x2, + A8_PMU_PERFCTR_L2_TLB_MISS_INSTRUCTION = 0xa, + A8_PMU_PERFCTR_L2_TLB_MISS_DATA = 0xb, + A8_PMU_PERFCTR_BIU_UPSTREAM_CYCLE = 0x13, + A8_PMU_PERFCTR_BIU_DOWNSTREAM_CYCLE = 0x14, + A8_PMU_PERFCTR_L2C_AGENT_LD = 0x1a, + A8_PMU_PERFCTR_L2C_AGENT_LD_MISS = 0x1b, + A8_PMU_PERFCTR_L2C_AGENT_ST = 0x1c, + A8_PMU_PERFCTR_L2C_AGENT_ST_MISS = 0x1d, + A8_PMU_PERFCTR_SCHEDULE_UOP = 0x52, + A8_PMU_PERFCTR_MAP_REWIND = 0x75, + A8_PMU_PERFCTR_MAP_STALL = 0x76, + A8_PMU_PERFCTR_MAP_INT_UOP = 0x7b, + A8_PMU_PERFCTR_MAP_LDST_UOP = 0x7c, + A8_PMU_PERFCTR_MAP_SIMD_UOP = 0x7d, + A8_PMU_PERFCTR_FLUSH_RESTART_OTHER_NONSPEC = 0x84, + A8_PMU_PERFCTR_INST_A32 = 0x8a, + A8_PMU_PERFCTR_INST_T32 = 0x8b, + A8_PMU_PERFCTR_INST_ALL = 0x8c, + A8_PMU_PERFCTR_INST_BRANCH = 0x8d, + A8_PMU_PERFCTR_INST_BRANCH_CALL = 0x8e, + A8_PMU_PERFCTR_INST_BRANCH_RET = 0x8f, + A8_PMU_PERFCTR_INST_BRANCH_TAKEN = 0x90, + A8_PMU_PERFCTR_INST_BRANCH_INDIR = 0x93, + A8_PMU_PERFCTR_INST_BRANCH_COND = 0x94, + A8_PMU_PERFCTR_INST_INT_LD = 0x95, + A8_PMU_PERFCTR_INST_INT_ST = 0x96, + A8_PMU_PERFCTR_INST_INT_ALU = 0x97, + A8_PMU_PERFCTR_INST_SIMD_LD = 0x98, + A8_PMU_PERFCTR_INST_SIMD_ST = 0x99, + A8_PMU_PERFCTR_INST_SIMD_ALU = 0x9a, + A8_PMU_PERFCTR_INST_LDST = 0x9b, + A8_PMU_PERFCTR_UNKNOWN_9c = 0x9c, + A8_PMU_PERFCTR_UNKNOWN_9f = 0x9f, + A8_PMU_PERFCTR_L1D_TLB_ACCESS = 0xa0, + A8_PMU_PERFCTR_L1D_TLB_MISS = 0xa1, + A8_PMU_PERFCTR_L1D_CACHE_MISS_ST = 0xa2, + A8_PMU_PERFCTR_L1D_CACHE_MISS_LD = 0xa3, + A8_PMU_PERFCTR_LD_UNIT_UOP = 0xa6, + A8_PMU_PERFCTR_ST_UNIT_UOP = 0xa7, + A8_PMU_PERFCTR_L1D_CACHE_WRITEBACK = 0xa8, + A8_PMU_PERFCTR_LDST_X64_UOP = 0xb1, + A8_PMU_PERFCTR_L1D_CACHE_MISS_LD_NONSPEC = 0xbf, + A8_PMU_PERFCTR_L1D_CACHE_MISS_ST_NONSPEC = 0xc0, + A8_PMU_PERFCTR_L1D_TLB_MISS_NONSPEC = 0xc1, + A8_PMU_PERFCTR_ST_MEMORY_ORDER_VIOLATION_NONSPEC = 0xc4, + A8_PMU_PERFCTR_BRANCH_COND_MISPRED_NONSPEC = 0xc5, + A8_PMU_PERFCTR_BRANCH_INDIR_MISPRED_NONSPEC = 0xc6, + A8_PMU_PERFCTR_BRANCH_RET_INDIR_MISPRED_NONSPEC = 0xc8, + A8_PMU_PERFCTR_BRANCH_CALL_INDIR_MISPRED_NONSPEC = 0xca, + A8_PMU_PERFCTR_BRANCH_MISPRED_NONSPEC = 0xcb, + A8_PMU_PERFCTR_FED_IC_MISS_DEMAND = 0xd3, + A8_PMU_PERFCTR_L1I_TLB_MISS_DEMAND = 0xd4, + A8_PMU_PERFCTR_FETCH_RESTART = 0xde, + A8_PMU_PERFCTR_UNKNOWN_f5 = 0xf5, + A8_PMU_PERFCTR_UNKNOWN_f6 = 0xf6, + A8_PMU_PERFCTR_UNKNOWN_f7 = 0xf7, + A8_PMU_PERFCTR_LAST = M1_PMU_CFG_EVENT, + + /* + * From this point onwards, these are not actual HW events, + * but attributes that get stored in hw->config_base. + */ + A8_PMU_CFG_COUNT_USER = BIT(8), + A8_PMU_CFG_COUNT_KERNEL = BIT(9), +}; + +static const u16 a8_pmu_event_affinity[A8_PMU_PERFCTR_LAST + 1] = { + [0 ... A8_PMU_PERFCTR_LAST] = ANY_BUT_0_1, + [A8_PMU_PERFCTR_UNKNOWN_1] = ONLY_5_6_7, + [A8_PMU_PERFCTR_CORE_ACTIVE_CYCLE] = ANY_BUT_0_1 | BIT(0), + [A8_PMU_PERFCTR_INST_A32] = ONLY_5_6_7, + [A8_PMU_PERFCTR_INST_T32] = ONLY_5_6_7, + [A8_PMU_PERFCTR_INST_ALL] = BIT(7) | BIT(1), + [A8_PMU_PERFCTR_INST_BRANCH] = ONLY_5_6_7, + [A8_PMU_PERFCTR_INST_BRANCH_CALL] = ONLY_5_6_7, + [A8_PMU_PERFCTR_INST_BRANCH_RET] = ONLY_5_6_7, + [A8_PMU_PERFCTR_INST_BRANCH_TAKEN] = ONLY_5_6_7, + [A8_PMU_PERFCTR_INST_BRANCH_INDIR] = ONLY_5_6_7, + [A8_PMU_PERFCTR_INST_BRANCH_COND] = ONLY_5_6_7, + [A8_PMU_PERFCTR_INST_INT_LD] = ONLY_5_6_7, + [A8_PMU_PERFCTR_INST_INT_ST] = ONLY_5_6_7, + [A8_PMU_PERFCTR_INST_INT_ALU] = ONLY_5_6_7, + [A8_PMU_PERFCTR_INST_SIMD_LD] = ONLY_5_6_7, + [A8_PMU_PERFCTR_INST_SIMD_ST] = ONLY_5_6_7, + [A8_PMU_PERFCTR_INST_SIMD_ALU] = ONLY_5_6_7, + [A8_PMU_PERFCTR_INST_LDST] = ONLY_5_6_7, + [A8_PMU_PERFCTR_UNKNOWN_9c] = ONLY_5_6_7, + [A8_PMU_PERFCTR_UNKNOWN_9f] = ONLY_5_6_7, + [A8_PMU_PERFCTR_L1D_CACHE_MISS_LD_NONSPEC] = ONLY_5_6_7, + [A8_PMU_PERFCTR_L1D_CACHE_MISS_ST_NONSPEC] = ONLY_5_6_7, + [A8_PMU_PERFCTR_L1D_TLB_MISS_NONSPEC] = ONLY_5_6_7, + [A8_PMU_PERFCTR_ST_MEMORY_ORDER_VIOLATION_NONSPEC] = ONLY_5_6_7, + [A8_PMU_PERFCTR_BRANCH_COND_MISPRED_NONSPEC] = ONLY_5_6_7, + [A8_PMU_PERFCTR_BRANCH_INDIR_MISPRED_NONSPEC] = ONLY_5_6_7, + [A8_PMU_PERFCTR_BRANCH_RET_INDIR_MISPRED_NONSPEC] = ONLY_5_6_7, + [A8_PMU_PERFCTR_BRANCH_CALL_INDIR_MISPRED_NONSPEC] = ONLY_5_6_7, + [A8_PMU_PERFCTR_BRANCH_MISPRED_NONSPEC] = ONLY_5_6_7, + [A8_PMU_PERFCTR_UNKNOWN_f5] = ANY_BUT_0_1, + [A8_PMU_PERFCTR_UNKNOWN_f6] = ONLY_3_5_7, + [A8_PMU_PERFCTR_UNKNOWN_f7] = ONLY_3_5_7, +}; + + +enum a9_pmu_events { + A9_PMU_PERFCTR_UNKNOWN_1 = 0x1, + A9_PMU_PERFCTR_CORE_ACTIVE_CYCLE = 0x2, + A9_PMU_PERFCTR_L2_TLB_MISS_INSTRUCTION = 0xa, + A9_PMU_PERFCTR_L2_TLB_MISS_DATA = 0xb, + A9_PMU_PERFCTR_L2C_AGENT_LD = 0x1a, + A9_PMU_PERFCTR_L2C_AGENT_LD_MISS = 0x1b, + A9_PMU_PERFCTR_L2C_AGENT_ST = 0x1c, + A9_PMU_PERFCTR_L2C_AGENT_ST_MISS = 0x1d, + A9_PMU_PERFCTR_SCHEDULE_UOP = 0x52, + A9_PMU_PERFCTR_MAP_REWIND = 0x75, + A9_PMU_PERFCTR_MAP_STALL = 0x76, + A9_PMU_PERFCTR_MAP_INT_UOP = 0x7c, + A9_PMU_PERFCTR_MAP_LDST_UOP = 0x7d, + A9_PMU_PERFCTR_MAP_SIMD_UOP = 0x7e, + A9_PMU_PERFCTR_FLUSH_RESTART_OTHER_NONSPEC = 0x84, + A9_PMU_PERFCTR_INST_A32 = 0x8a, + A9_PMU_PERFCTR_INST_T32 = 0x8b, + A9_PMU_PERFCTR_INST_ALL = 0x8c, + A9_PMU_PERFCTR_INST_BRANCH = 0x8d, + A9_PMU_PERFCTR_INST_BRANCH_CALL = 0x8e, + A9_PMU_PERFCTR_INST_BRANCH_RET = 0x8f, + A9_PMU_PERFCTR_INST_BRANCH_TAKEN = 0x90, + A9_PMU_PERFCTR_INST_BRANCH_INDIR = 0x93, + A9_PMU_PERFCTR_INST_BRANCH_COND = 0x94, + A9_PMU_PERFCTR_INST_INT_LD = 0x95, + A9_PMU_PERFCTR_INST_INT_ST = 0x96, + A9_PMU_PERFCTR_INST_INT_ALU = 0x97, + A9_PMU_PERFCTR_INST_SIMD_LD = 0x98, + A9_PMU_PERFCTR_INST_SIMD_ST = 0x99, + A9_PMU_PERFCTR_INST_SIMD_ALU = 0x9a, + A9_PMU_PERFCTR_INST_LDST = 0x9b, + A9_PMU_PERFCTR_INST_BARRIER = 0x9c, + A9_PMU_PERFCTR_UNKNOWN_9f = 0x9f, + A9_PMU_PERFCTR_L1D_TLB_ACCESS = 0xa0, + A9_PMU_PERFCTR_L1D_TLB_MISS = 0xa1, + A9_PMU_PERFCTR_L1D_CACHE_MISS_ST = 0xa2, + A9_PMU_PERFCTR_L1D_CACHE_MISS_LD = 0xa3, + A9_PMU_PERFCTR_LD_UNIT_UOP = 0xa6, + A9_PMU_PERFCTR_ST_UNIT_UOP = 0xa7, + A9_PMU_PERFCTR_L1D_CACHE_WRITEBACK = 0xa8, + A9_PMU_PERFCTR_LDST_X64_UOP = 0xb1, + A9_PMU_PERFCTR_ATOMIC_OR_EXCLUSIVE_SUCC = 0xb3, + A9_PMU_PERFCTR_ATOMIC_OR_EXCLUSIVE_FAIL = 0xb4, + A9_PMU_PERFCTR_L1D_CACHE_MISS_LD_NONSPEC = 0xbf, + A9_PMU_PERFCTR_L1D_CACHE_MISS_ST_NONSPEC = 0xc0, + A9_PMU_PERFCTR_L1D_TLB_MISS_NONSPEC = 0xc1, + A9_PMU_PERFCTR_ST_MEMORY_ORDER_VIOLATION_NONSPEC = 0xc4, + A9_PMU_PERFCTR_BRANCH_COND_MISPRED_NONSPEC = 0xc5, + A9_PMU_PERFCTR_BRANCH_INDIR_MISPRED_NONSPEC = 0xc6, + A9_PMU_PERFCTR_BRANCH_RET_INDIR_MISPRED_NONSPEC = 0xc8, + A9_PMU_PERFCTR_BRANCH_CALL_INDIR_MISPRED_NONSPEC = 0xca, + A9_PMU_PERFCTR_BRANCH_MISPRED_NONSPEC = 0xcb, + A9_PMU_PERFCTR_FED_IC_MISS_DEMAND = 0xd3, + A9_PMU_PERFCTR_L1I_TLB_MISS_DEMAND = 0xd4, + A9_PMU_PERFCTR_MAP_DISPATCH_BUBBLE = 0xd6, + A9_PMU_PERFCTR_FETCH_RESTART = 0xde, + A9_PMU_PERFCTR_ST_NT_UOP = 0xe5, + A9_PMU_PERFCTR_LD_NT_UOP = 0xe6, + A9_PMU_PERFCTR_UNKNOWN_f6 = 0xf6, + A9_PMU_PERFCTR_UNKNOWN_f7 = 0xf7, + A9_PMU_PERFCTR_LAST = M1_PMU_CFG_EVENT, + + /* + * From this point onwards, these are not actual HW events, + * but attributes that get stored in hw->config_base. + */ + A9_PMU_CFG_COUNT_USER = BIT(8), + A9_PMU_CFG_COUNT_KERNEL = BIT(9), +}; + +static const u16 a9_pmu_event_affinity[A9_PMU_PERFCTR_LAST + 1] = { + [0 ... A9_PMU_PERFCTR_LAST] = ANY_BUT_0_1, + [A9_PMU_PERFCTR_UNKNOWN_1] = BIT(7), + [A9_PMU_PERFCTR_CORE_ACTIVE_CYCLE] = ANY_BUT_0_1 | BIT(0), + [A9_PMU_PERFCTR_INST_A32] = BIT(7), + [A9_PMU_PERFCTR_INST_T32] = BIT(7), + [A9_PMU_PERFCTR_INST_ALL] = BIT(7) | BIT(1), + [A9_PMU_PERFCTR_INST_BRANCH] = ONLY_5_6_7, + [A9_PMU_PERFCTR_INST_BRANCH_CALL] = ONLY_5_6_7, + [A9_PMU_PERFCTR_INST_BRANCH_RET] = ONLY_5_6_7, + [A9_PMU_PERFCTR_INST_BRANCH_TAKEN] = ONLY_5_6_7, + [A9_PMU_PERFCTR_INST_BRANCH_INDIR] = ONLY_5_6_7, + [A9_PMU_PERFCTR_INST_BRANCH_COND] = ONLY_5_6_7, + [A9_PMU_PERFCTR_INST_INT_LD] = ONLY_5_6_7, + [A9_PMU_PERFCTR_INST_INT_ST] = ONLY_5_6_7, + [A9_PMU_PERFCTR_INST_INT_ALU] = BIT(7), + [A9_PMU_PERFCTR_INST_SIMD_LD] = ONLY_5_6_7, + [A9_PMU_PERFCTR_INST_SIMD_ST] = ONLY_5_6_7, + [A9_PMU_PERFCTR_INST_SIMD_ALU] = BIT(7), + [A9_PMU_PERFCTR_INST_LDST] = ONLY_5_6_7, + [A9_PMU_PERFCTR_INST_BARRIER] = ONLY_5_6_7, + [A9_PMU_PERFCTR_UNKNOWN_9f] = BIT(7), + [A9_PMU_PERFCTR_L1D_CACHE_MISS_LD_NONSPEC] = ONLY_5_6_7, + [A9_PMU_PERFCTR_L1D_CACHE_MISS_ST_NONSPEC] = ONLY_5_6_7, + [A9_PMU_PERFCTR_L1D_TLB_MISS_NONSPEC] = ONLY_5_6_7, + [A9_PMU_PERFCTR_ST_MEMORY_ORDER_VIOLATION_NONSPEC] = ONLY_5_6_7, + [A9_PMU_PERFCTR_BRANCH_COND_MISPRED_NONSPEC] = ONLY_5_6_7, + [A9_PMU_PERFCTR_BRANCH_INDIR_MISPRED_NONSPEC] = ONLY_5_6_7, + [A9_PMU_PERFCTR_BRANCH_RET_INDIR_MISPRED_NONSPEC] = ONLY_5_6_7, + [A9_PMU_PERFCTR_BRANCH_CALL_INDIR_MISPRED_NONSPEC] = ONLY_5_6_7, + [A9_PMU_PERFCTR_BRANCH_MISPRED_NONSPEC] = ONLY_5_6_7, + [A9_PMU_PERFCTR_UNKNOWN_f6] = ONLY_3_5_7, + [A9_PMU_PERFCTR_UNKNOWN_f7] = ONLY_3_5_7, +}; + +enum a10_pmu_events { + A10_PMU_PERFCTR_RETIRE_UOP = 0x1, + A10_PMU_PERFCTR_CORE_ACTIVE_CYCLE = 0x2, + A10_PMU_PERFCTR_L2_TLB_MISS_INSTRUCTION = 0xa, + A10_PMU_PERFCTR_L2_TLB_MISS_DATA = 0xb, + A10_PMU_PERFCTR_L2C_AGENT_LD = 0x1a, + A10_PMU_PERFCTR_L2C_AGENT_LD_MISS = 0x1b, + A10_PMU_PERFCTR_L2C_AGENT_ST = 0x1c, + A10_PMU_PERFCTR_L2C_AGENT_ST_MISS = 0x1d, + A10_PMU_PERFCTR_SCHEDULE_UOP = 0x52, + A10_PMU_PERFCTR_MAP_REWIND = 0x75, + A10_PMU_PERFCTR_MAP_STALL = 0x76, + A10_PMU_PERFCTR_MAP_INT_UOP = 0x7c, + A10_PMU_PERFCTR_MAP_LDST_UOP = 0x7d, + A10_PMU_PERFCTR_MAP_SIMD_UOP = 0x7e, + A10_PMU_PERFCTR_FLUSH_RESTART_OTHER_NONSPEC = 0x84, + A10_PMU_PERFCTR_INST_A32 = 0x8a, + A10_PMU_PERFCTR_INST_T32 = 0x8b, + A10_PMU_PERFCTR_INST_ALL = 0x8c, + A10_PMU_PERFCTR_INST_BRANCH = 0x8d, + A10_PMU_PERFCTR_INST_BRANCH_CALL = 0x8e, + A10_PMU_PERFCTR_INST_BRANCH_RET = 0x8f, + A10_PMU_PERFCTR_INST_BRANCH_TAKEN = 0x90, + A10_PMU_PERFCTR_INST_BRANCH_INDIR = 0x93, + A10_PMU_PERFCTR_INST_BRANCH_COND = 0x94, + A10_PMU_PERFCTR_INST_INT_LD = 0x95, + A10_PMU_PERFCTR_INST_INT_ST = 0x96, + A10_PMU_PERFCTR_INST_INT_ALU = 0x97, + A10_PMU_PERFCTR_INST_SIMD_LD = 0x98, + A10_PMU_PERFCTR_INST_SIMD_ST = 0x99, + A10_PMU_PERFCTR_INST_SIMD_ALU = 0x9a, + A10_PMU_PERFCTR_INST_LDST = 0x9b, + A10_PMU_PERFCTR_INST_BARRIER = 0x9c, + A10_PMU_PERFCTR_UNKNOWN_9f = 0x9f, + A10_PMU_PERFCTR_L1D_TLB_ACCESS = 0xa0, + A10_PMU_PERFCTR_L1D_TLB_MISS = 0xa1, + A10_PMU_PERFCTR_L1D_CACHE_MISS_ST = 0xa2, + A10_PMU_PERFCTR_L1D_CACHE_MISS_LD = 0xa3, + A10_PMU_PERFCTR_LD_UNIT_UOP = 0xa6, + A10_PMU_PERFCTR_ST_UNIT_UOP = 0xa7, + A10_PMU_PERFCTR_L1D_CACHE_WRITEBACK = 0xa8, + A10_PMU_PERFCTR_LDST_X64_UOP = 0xb1, + A10_PMU_PERFCTR_ATOMIC_OR_EXCLUSIVE_SUCC = 0xb3, + A10_PMU_PERFCTR_ATOMIC_OR_EXCLUSIVE_FAIL = 0xb4, + A10_PMU_PERFCTR_L1D_CACHE_MISS_LD_NONSPEC = 0xbf, + A10_PMU_PERFCTR_L1D_CACHE_MISS_ST_NONSPEC = 0xc0, + A10_PMU_PERFCTR_L1D_TLB_MISS_NONSPEC = 0xc1, + A10_PMU_PERFCTR_ST_MEMORY_ORDER_VIOLATION_NONSPEC = 0xc4, + A10_PMU_PERFCTR_BRANCH_COND_MISPRED_NONSPEC = 0xc5, + A10_PMU_PERFCTR_BRANCH_INDIR_MISPRED_NONSPEC = 0xc6, + A10_PMU_PERFCTR_BRANCH_RET_INDIR_MISPRED_NONSPEC = 0xc8, + A10_PMU_PERFCTR_BRANCH_CALL_INDIR_MISPRED_NONSPEC = 0xca, + A10_PMU_PERFCTR_BRANCH_MISPRED_NONSPEC = 0xcb, + A10_PMU_PERFCTR_FED_IC_MISS_DEMAND = 0xd3, + A10_PMU_PERFCTR_L1I_TLB_MISS_DEMAND = 0xd4, + A10_PMU_PERFCTR_MAP_DISPATCH_BUBBLE = 0xd6, + A10_PMU_PERFCTR_L1I_CACHE_MISS_DEMAND = 0xdb, + A10_PMU_PERFCTR_FETCH_RESTART = 0xde, + A10_PMU_PERFCTR_ST_NT_UOP = 0xe5, + A10_PMU_PERFCTR_LD_NT_UOP = 0xe6, + A10_PMU_PERFCTR_UNKNOWN_f5 = 0xf5, + A10_PMU_PERFCTR_UNKNOWN_f6 = 0xf6, + A10_PMU_PERFCTR_UNKNOWN_f7 = 0xf7, + A10_PMU_PERFCTR_UNKNOWN_f8 = 0xf8, + A10_PMU_PERFCTR_UNKNOWN_fd = 0xfd, + A10_PMU_PERFCTR_LAST = M1_PMU_CFG_EVENT, + + /* + * From this point onwards, these are not actual HW events, + * but attributes that get stored in hw->config_base. + */ + A10_PMU_CFG_COUNT_USER = BIT(8), + A10_PMU_CFG_COUNT_KERNEL = BIT(9), +}; + +static const u16 a10_pmu_event_affinity[A10_PMU_PERFCTR_LAST + 1] = { + [0 ... A10_PMU_PERFCTR_LAST] = ANY_BUT_0_1, + [A10_PMU_PERFCTR_RETIRE_UOP] = BIT(7), + [A10_PMU_PERFCTR_CORE_ACTIVE_CYCLE] = ANY_BUT_0_1 | BIT(0), + [A10_PMU_PERFCTR_INST_A32] = BIT(7), + [A10_PMU_PERFCTR_INST_T32] = BIT(7), + [A10_PMU_PERFCTR_INST_ALL] = BIT(7) | BIT(1), + [A10_PMU_PERFCTR_INST_BRANCH] = ONLY_5_6_7, + [A10_PMU_PERFCTR_INST_BRANCH_CALL] = ONLY_5_6_7, + [A10_PMU_PERFCTR_INST_BRANCH_RET] = ONLY_5_6_7, + [A10_PMU_PERFCTR_INST_BRANCH_TAKEN] = ONLY_5_6_7, + [A10_PMU_PERFCTR_INST_BRANCH_INDIR] = ONLY_5_6_7, + [A10_PMU_PERFCTR_INST_BRANCH_COND] = ONLY_5_6_7, + [A10_PMU_PERFCTR_INST_INT_LD] = ONLY_5_6_7, + [A10_PMU_PERFCTR_INST_INT_ST] = ONLY_5_6_7, + [A10_PMU_PERFCTR_INST_INT_ALU] = BIT(7), + [A10_PMU_PERFCTR_INST_SIMD_LD] = ONLY_5_6_7, + [A10_PMU_PERFCTR_INST_SIMD_ST] = ONLY_5_6_7, + [A10_PMU_PERFCTR_INST_SIMD_ALU] = BIT(7), + [A10_PMU_PERFCTR_INST_LDST] = ONLY_5_6_7, + [A10_PMU_PERFCTR_INST_BARRIER] = ONLY_5_6_7, + [A10_PMU_PERFCTR_UNKNOWN_9f] = BIT(7), + [A10_PMU_PERFCTR_L1D_CACHE_MISS_LD_NONSPEC] = ONLY_5_6_7, + [A10_PMU_PERFCTR_L1D_CACHE_MISS_ST_NONSPEC] = ONLY_5_6_7, + [A10_PMU_PERFCTR_L1D_TLB_MISS_NONSPEC] = ONLY_5_6_7, + [A10_PMU_PERFCTR_ST_MEMORY_ORDER_VIOLATION_NONSPEC] = ONLY_5_6_7, + [A10_PMU_PERFCTR_BRANCH_COND_MISPRED_NONSPEC] = ONLY_5_6_7, + [A10_PMU_PERFCTR_BRANCH_INDIR_MISPRED_NONSPEC] = ONLY_5_6_7, + [A10_PMU_PERFCTR_BRANCH_RET_INDIR_MISPRED_NONSPEC] = ONLY_5_6_7, + [A10_PMU_PERFCTR_BRANCH_CALL_INDIR_MISPRED_NONSPEC] = ONLY_5_6_7, + [A10_PMU_PERFCTR_BRANCH_MISPRED_NONSPEC] = ONLY_5_6_7, + [A10_PMU_PERFCTR_UNKNOWN_f5] = ONLY_2_4_6, + [A10_PMU_PERFCTR_UNKNOWN_f6] = ONLY_2_4_6, + [A10_PMU_PERFCTR_UNKNOWN_f7] = ONLY_2_4_6, + [A10_PMU_PERFCTR_UNKNOWN_f8] = ONLY_2_TO_7, + [A10_PMU_PERFCTR_UNKNOWN_fd] = ONLY_2_4_6, +}; + +enum a11_pmu_events { + A11_PMU_PERFCTR_RETIRE_UOP = 0x1, + A11_PMU_PERFCTR_CORE_ACTIVE_CYCLE = 0x2, + A11_PMU_PERFCTR_L2_TLB_MISS_INSTRUCTION = 0xa, + A11_PMU_PERFCTR_L2_TLB_MISS_DATA = 0xb, + A11_PMU_PERFCTR_SCHEDULE_UOP = 0x52, + A11_PMU_PERFCTR_MAP_REWIND = 0x75, + A11_PMU_PERFCTR_MAP_STALL = 0x76, + A11_PMU_PERFCTR_MAP_INT_UOP = 0x7c, + A11_PMU_PERFCTR_MAP_LDST_UOP = 0x7d, + A11_PMU_PERFCTR_MAP_SIMD_UOP = 0x7e, + A11_PMU_PERFCTR_FLUSH_RESTART_OTHER_NONSPEC = 0x84, + A11_PMU_PERFCTR_INST_ALL = 0x8c, + A11_PMU_PERFCTR_INST_BRANCH = 0x8d, + A11_PMU_PERFCTR_INST_BRANCH_CALL = 0x8e, + A11_PMU_PERFCTR_INST_BRANCH_RET = 0x8f, + A11_PMU_PERFCTR_INST_BRANCH_TAKEN = 0x90, + A11_PMU_PERFCTR_INST_BRANCH_INDIR = 0x93, + A11_PMU_PERFCTR_INST_BRANCH_COND = 0x94, + A11_PMU_PERFCTR_INST_INT_LD = 0x95, + A11_PMU_PERFCTR_INST_INT_ST = 0x96, + A11_PMU_PERFCTR_INST_INT_ALU = 0x97, + A11_PMU_PERFCTR_INST_SIMD_LD = 0x98, + A11_PMU_PERFCTR_INST_SIMD_ST = 0x99, + A11_PMU_PERFCTR_INST_SIMD_ALU = 0x9a, + A11_PMU_PERFCTR_INST_LDST = 0x9b, + A11_PMU_PERFCTR_INST_BARRIER = 0x9c, + A11_PMU_PERFCTR_UNKNOWN_9f = 0x9f, + A11_PMU_PERFCTR_L1D_TLB_ACCESS = 0xa0, + A11_PMU_PERFCTR_L1D_TLB_MISS = 0xa1, + A11_PMU_PERFCTR_L1D_CACHE_MISS_ST = 0xa2, + A11_PMU_PERFCTR_L1D_CACHE_MISS_LD = 0xa3, + A11_PMU_PERFCTR_LD_UNIT_UOP = 0xa6, + A11_PMU_PERFCTR_ST_UNIT_UOP = 0xa7, + A11_PMU_PERFCTR_L1D_CACHE_WRITEBACK = 0xa8, + A11_PMU_PERFCTR_LDST_X64_UOP = 0xb1, + A11_PMU_PERFCTR_ATOMIC_OR_EXCLUSIVE_SUCC = 0xb3, + A11_PMU_PERFCTR_ATOMIC_OR_EXCLUSIVE_FAIL = 0xb4, + A11_PMU_PERFCTR_L1D_CACHE_MISS_LD_NONSPEC = 0xbf, + A11_PMU_PERFCTR_L1D_CACHE_MISS_ST_NONSPEC = 0xc0, + A11_PMU_PERFCTR_L1D_TLB_MISS_NONSPEC = 0xc1, + A11_PMU_PERFCTR_ST_MEMORY_ORDER_VIOLATION_NONSPEC = 0xc4, + A11_PMU_PERFCTR_BRANCH_COND_MISPRED_NONSPEC = 0xc5, + A11_PMU_PERFCTR_BRANCH_INDIR_MISPRED_NONSPEC = 0xc6, + A11_PMU_PERFCTR_BRANCH_RET_INDIR_MISPRED_NONSPEC = 0xc8, + A11_PMU_PERFCTR_BRANCH_CALL_INDIR_MISPRED_NONSPEC = 0xca, + A11_PMU_PERFCTR_BRANCH_MISPRED_NONSPEC = 0xcb, + A11_PMU_PERFCTR_FED_IC_MISS_DEMAND = 0xd3, + A11_PMU_PERFCTR_L1I_TLB_MISS_DEMAND = 0xd4, + A11_PMU_PERFCTR_MAP_DISPATCH_BUBBLE = 0xd6, + A11_PMU_PERFCTR_L1I_CACHE_MISS_DEMAND = 0xdb, + A11_PMU_PERFCTR_FETCH_RESTART = 0xde, + A11_PMU_PERFCTR_ST_NT_UOP = 0xe5, + A11_PMU_PERFCTR_LD_NT_UOP = 0xe6, + A11_PMU_PERFCTR_UNKNOWN_f5 = 0xf5, + A11_PMU_PERFCTR_UNKNOWN_f6 = 0xf6, + A11_PMU_PERFCTR_UNKNOWN_f7 = 0xf7, + A11_PMU_PERFCTR_UNKNOWN_f8 = 0xf8, + A11_PMU_PERFCTR_UNKNOWN_fd = 0xfd, + A11_PMU_PERFCTR_LAST = M1_PMU_CFG_EVENT, + + /* + * From this point onwards, these are not actual HW events, + * but attributes that get stored in hw->config_base. + */ + A11_PMU_CFG_COUNT_USER = BIT(8), + A11_PMU_CFG_COUNT_KERNEL = BIT(9), +}; + +static const u16 a11_pmu_event_affinity[A11_PMU_PERFCTR_LAST + 1] = { + [0 ... A11_PMU_PERFCTR_LAST] = ANY_BUT_0_1, + [A11_PMU_PERFCTR_RETIRE_UOP] = BIT(7), + [A11_PMU_PERFCTR_CORE_ACTIVE_CYCLE] = ANY_BUT_0_1 | BIT(0), + [A11_PMU_PERFCTR_INST_ALL] = BIT(7) | BIT(1), + [A11_PMU_PERFCTR_INST_BRANCH] = ONLY_5_6_7, + [A11_PMU_PERFCTR_INST_BRANCH_CALL] = ONLY_5_6_7, + [A11_PMU_PERFCTR_INST_BRANCH_RET] = ONLY_5_6_7, + [A11_PMU_PERFCTR_INST_BRANCH_TAKEN] = ONLY_5_6_7, + [A11_PMU_PERFCTR_INST_BRANCH_INDIR] = ONLY_5_6_7, + [A11_PMU_PERFCTR_INST_BRANCH_COND] = ONLY_5_6_7, + [A11_PMU_PERFCTR_INST_INT_LD] = ONLY_5_6_7, + [A11_PMU_PERFCTR_INST_INT_ST] = ONLY_5_6_7, + [A11_PMU_PERFCTR_INST_INT_ALU] = BIT(7), + [A11_PMU_PERFCTR_INST_SIMD_LD] = ONLY_5_6_7, + [A11_PMU_PERFCTR_INST_SIMD_ST] = ONLY_5_6_7, + [A11_PMU_PERFCTR_INST_SIMD_ALU] = BIT(7), + [A11_PMU_PERFCTR_INST_LDST] = ONLY_5_6_7, + [A11_PMU_PERFCTR_INST_BARRIER] = ONLY_5_6_7, + [A11_PMU_PERFCTR_UNKNOWN_9f] = BIT(7), + [A11_PMU_PERFCTR_L1D_CACHE_MISS_LD_NONSPEC] = ONLY_5_6_7, + [A11_PMU_PERFCTR_L1D_CACHE_MISS_ST_NONSPEC] = ONLY_5_6_7, + [A11_PMU_PERFCTR_L1D_TLB_MISS_NONSPEC] = ONLY_5_6_7, + [A11_PMU_PERFCTR_ST_MEMORY_ORDER_VIOLATION_NONSPEC] = ONLY_5_6_7, + [A11_PMU_PERFCTR_BRANCH_COND_MISPRED_NONSPEC] = ONLY_5_6_7, + [A11_PMU_PERFCTR_BRANCH_INDIR_MISPRED_NONSPEC] = ONLY_5_6_7, + [A11_PMU_PERFCTR_BRANCH_RET_INDIR_MISPRED_NONSPEC] = ONLY_5_6_7, + [A11_PMU_PERFCTR_BRANCH_CALL_INDIR_MISPRED_NONSPEC] = ONLY_5_6_7, + [A11_PMU_PERFCTR_BRANCH_MISPRED_NONSPEC] = ONLY_5_6_7, + [A11_PMU_PERFCTR_UNKNOWN_f5] = ONLY_2_4_6, + [A11_PMU_PERFCTR_UNKNOWN_f6] = ONLY_2_4_6, + [A11_PMU_PERFCTR_UNKNOWN_f7] = ONLY_2_4_6, + [A11_PMU_PERFCTR_UNKNOWN_f8] = ONLY_2_TO_7, + [A11_PMU_PERFCTR_UNKNOWN_fd] = ONLY_2_4_6, +}; + enum m1_pmu_events { M1_PMU_PERFCTR_RETIRE_UOP = 0x1, M1_PMU_PERFCTR_CORE_ACTIVE_CYCLE = 0x2, @@ -167,6 +734,14 @@ static const u16 m1_pmu_event_affinity[M1_PMU_PERFCTR_LAST + 1] = { [M1_PMU_PERFCTR_UNKNOWN_fd] = ONLY_2_4_6, }; +static const unsigned int a7_pmu_perf_map[PERF_COUNT_HW_MAX] = { + PERF_MAP_ALL_UNSUPPORTED, + [PERF_COUNT_HW_CPU_CYCLES] = A7_PMU_PERFCTR_CORE_ACTIVE_CYCLE, + [PERF_COUNT_HW_INSTRUCTIONS] = A7_PMU_PERFCTR_INST_ALL, + [PERF_COUNT_HW_BRANCH_MISSES] = A7_PMU_PERFCTR_BRANCH_MISPRED_NONSPEC, + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = A7_PMU_PERFCTR_INST_BRANCH +}; + static const unsigned m1_pmu_perf_map[PERF_COUNT_HW_MAX] = { PERF_MAP_ALL_UNSUPPORTED, [PERF_COUNT_HW_CPU_CYCLES] = M1_PMU_PERFCTR_CORE_ACTIVE_CYCLE, @@ -201,6 +776,17 @@ static ssize_t m1_pmu_events_sysfs_show(struct device *dev, #define M1_PMU_EVENT_ATTR(name, config) \ PMU_EVENT_ATTR_ID(name, m1_pmu_events_sysfs_show, config) +static struct attribute *a7_pmu_event_attrs[] = { + M1_PMU_EVENT_ATTR(cycles, A7_PMU_PERFCTR_CORE_ACTIVE_CYCLE), + M1_PMU_EVENT_ATTR(instructions, A7_PMU_PERFCTR_INST_ALL), + NULL, +}; + +static const struct attribute_group a7_pmu_events_attr_group = { + .name = "events", + .attrs = a7_pmu_event_attrs, +}; + static struct attribute *m1_pmu_event_attrs[] = { M1_PMU_EVENT_ATTR(cycles, M1_PMU_PERFCTR_CORE_ACTIVE_CYCLE), M1_PMU_EVENT_ATTR(instructions, M1_PMU_PERFCTR_INST_ALL), @@ -350,10 +936,16 @@ static void __m1_pmu_configure_event_filter(unsigned int index, bool user, case 0 ... 7: user_bit = BIT(get_bit_offset(index, PMCR1_COUNT_A64_EL0_0_7)); kernel_bit = BIT(get_bit_offset(index, PMCR1_COUNT_A64_EL1_0_7)); + + if (system_supports_32bit_el0()) + user_bit |= BIT(get_bit_offset(index, PMCR1_COUNT_A32_EL0_0_7)); break; case 8 ... 9: user_bit = BIT(get_bit_offset(index - 8, PMCR1_COUNT_A64_EL0_8_9)); kernel_bit = BIT(get_bit_offset(index - 8, PMCR1_COUNT_A64_EL1_8_9)); + + if (system_supports_32bit_el0()) + user_bit |= BIT(get_bit_offset(index - 8, PMCR1_COUNT_A32_EL0_8_9)); break; default: BUG(); @@ -462,7 +1054,7 @@ static irqreturn_t m1_pmu_handle_irq(struct arm_pmu *cpu_pmu) regs = get_irq_regs(); - for_each_set_bit(idx, cpu_pmu->cntr_mask, M1_PMU_NR_COUNTERS) { + for_each_set_bit(idx, cpu_pmu->cntr_mask, APPLE_PMU_MAX_NR_COUNTERS) { struct perf_event *event = cpuc->events[idx]; struct perf_sample_data data; @@ -493,11 +1085,13 @@ static void m1_pmu_write_counter(struct perf_event *event, u64 value) isb(); } -static int m1_pmu_get_event_idx(struct pmu_hw_events *cpuc, - struct perf_event *event) +static int apple_pmu_get_event_idx(struct pmu_hw_events *cpuc, + struct perf_event *event, + const u16 event_affinities[], + u8 nr_counters) { unsigned long evtype = event->hw.config_base & M1_PMU_CFG_EVENT; - unsigned long affinity = m1_pmu_event_affinity[evtype]; + unsigned long affinity = event_affinities[evtype]; int idx; /* @@ -508,7 +1102,7 @@ static int m1_pmu_get_event_idx(struct pmu_hw_events *cpuc, * counting on the PMU at any given time, and by placing the * most constraining events first. */ - for_each_set_bit(idx, &affinity, M1_PMU_NR_COUNTERS) { + for_each_set_bit(idx, &affinity, nr_counters) { if (!test_and_set_bit(idx, cpuc->used_mask)) return idx; } @@ -516,6 +1110,48 @@ static int m1_pmu_get_event_idx(struct pmu_hw_events *cpuc, return -EAGAIN; } +static int a7_pmu_get_event_idx(struct pmu_hw_events *cpuc, + struct perf_event *event) +{ + return apple_pmu_get_event_idx(cpuc, event, a7_pmu_event_affinity, + A7_PMU_NR_COUNTERS); +} + +static int a8_pmu_get_event_idx(struct pmu_hw_events *cpuc, + struct perf_event *event) +{ + return apple_pmu_get_event_idx(cpuc, event, a8_pmu_event_affinity, + A7_PMU_NR_COUNTERS); +} + +static int a9_pmu_get_event_idx(struct pmu_hw_events *cpuc, + struct perf_event *event) +{ + return apple_pmu_get_event_idx(cpuc, event, a9_pmu_event_affinity, + A7_PMU_NR_COUNTERS); +} + +static int a10_pmu_get_event_idx(struct pmu_hw_events *cpuc, + struct perf_event *event) +{ + return apple_pmu_get_event_idx(cpuc, event, a10_pmu_event_affinity, + M1_PMU_NR_COUNTERS); +} + +static int a11_pmu_get_event_idx(struct pmu_hw_events *cpuc, + struct perf_event *event) +{ + return apple_pmu_get_event_idx(cpuc, event, a11_pmu_event_affinity, + M1_PMU_NR_COUNTERS); +} + +static int m1_pmu_get_event_idx(struct pmu_hw_events *cpuc, + struct perf_event *event) +{ + return apple_pmu_get_event_idx(cpuc, event, m1_pmu_event_affinity, + M1_PMU_NR_COUNTERS); +} + static void m1_pmu_clear_event_idx(struct pmu_hw_events *cpuc, struct perf_event *event) { @@ -533,6 +1169,11 @@ static void __m1_pmu_set_mode(u8 mode) isb(); } +static void a7_pmu_start(struct arm_pmu *cpu_pmu) +{ + __m1_pmu_set_mode(PMCR0_IMODE_AIC); +} + static void m1_pmu_start(struct arm_pmu *cpu_pmu) { __m1_pmu_set_mode(PMCR0_IMODE_FIQ); @@ -543,7 +1184,8 @@ static void m1_pmu_stop(struct arm_pmu *cpu_pmu) __m1_pmu_set_mode(PMCR0_IMODE_OFF); } -static int m1_pmu_map_event(struct perf_event *event) +static int apple_pmu_map_event_47(struct perf_event *event, + const unsigned int (*perf_map)[]) { /* * Although the counters are 48bit wide, bit 47 is what @@ -551,18 +1193,34 @@ static int m1_pmu_map_event(struct perf_event *event) * being 47bit wide to mimick the behaviour of the ARM PMU. */ event->hw.flags |= ARMPMU_EVT_47BIT; - return armpmu_map_event(event, &m1_pmu_perf_map, NULL, M1_PMU_CFG_EVENT); + return armpmu_map_event(event, perf_map, NULL, M1_PMU_CFG_EVENT); } -static int m2_pmu_map_event(struct perf_event *event) +static int apple_pmu_map_event_63(struct perf_event *event, + const unsigned int (*perf_map)[]) { /* - * Same deal as the above, except that M2 has 64bit counters. + * Same deal as the above, except with 64bit counters. * Which, as far as we're concerned, actually means 63 bits. * Yes, this is getting awkward. */ event->hw.flags |= ARMPMU_EVT_63BIT; - return armpmu_map_event(event, &m1_pmu_perf_map, NULL, M1_PMU_CFG_EVENT); + return armpmu_map_event(event, perf_map, NULL, M1_PMU_CFG_EVENT); +} + +static int a7_pmu_map_event(struct perf_event *event) +{ + return apple_pmu_map_event_47(event, &a7_pmu_perf_map); +} + +static int m1_pmu_map_event(struct perf_event *event) +{ + return apple_pmu_map_event_47(event, &m1_pmu_perf_map); +} + +static int m2_pmu_map_event(struct perf_event *event) +{ + return apple_pmu_map_event_63(event, &m1_pmu_perf_map); } static int m1_pmu_map_pmuv3_event(unsigned int eventsel) @@ -585,13 +1243,13 @@ static void m1_pmu_init_pmceid(struct arm_pmu *pmu) } } -static void m1_pmu_reset(void *info) +static void apple_pmu_reset(void *info, u32 counters) { int i; __m1_pmu_set_mode(PMCR0_IMODE_OFF); - for (i = 0; i < M1_PMU_NR_COUNTERS; i++) { + for (i = 0; i < counters; i++) { m1_pmu_disable_counter(i); m1_pmu_disable_counter_interrupt(i); m1_pmu_write_hw_counter(0, i); @@ -600,6 +1258,16 @@ static void m1_pmu_reset(void *info) isb(); } +static void a7_pmu_reset(void *info) +{ + apple_pmu_reset(info, A7_PMU_NR_COUNTERS); +} + +static void m1_pmu_reset(void *info) +{ + apple_pmu_reset(info, M1_PMU_NR_COUNTERS); +} + static int m1_pmu_set_event_filter(struct hw_perf_event *event, struct perf_event_attr *attr) { @@ -623,60 +1291,136 @@ static int m1_pmu_set_event_filter(struct hw_perf_event *event, return 0; } -static int m1_pmu_init(struct arm_pmu *cpu_pmu, u32 flags) +static int apple_pmu_init(struct arm_pmu *cpu_pmu, u32 nr_counters) { cpu_pmu->handle_irq = m1_pmu_handle_irq; cpu_pmu->enable = m1_pmu_enable_event; cpu_pmu->disable = m1_pmu_disable_event; cpu_pmu->read_counter = m1_pmu_read_counter; cpu_pmu->write_counter = m1_pmu_write_counter; - cpu_pmu->get_event_idx = m1_pmu_get_event_idx; cpu_pmu->clear_event_idx = m1_pmu_clear_event_idx; - cpu_pmu->start = m1_pmu_start; cpu_pmu->stop = m1_pmu_stop; - - if (flags & ARMPMU_EVT_47BIT) - cpu_pmu->map_event = m1_pmu_map_event; - else if (flags & ARMPMU_EVT_63BIT) - cpu_pmu->map_event = m2_pmu_map_event; - else - return WARN_ON(-EINVAL); - - cpu_pmu->reset = m1_pmu_reset; cpu_pmu->set_event_filter = m1_pmu_set_event_filter; - cpu_pmu->map_pmuv3_event = m1_pmu_map_pmuv3_event; - m1_pmu_init_pmceid(cpu_pmu); + if (is_hyp_mode_available()) { + cpu_pmu->map_pmuv3_event = m1_pmu_map_pmuv3_event; + m1_pmu_init_pmceid(cpu_pmu); + } - bitmap_set(cpu_pmu->cntr_mask, 0, M1_PMU_NR_COUNTERS); - cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &m1_pmu_events_attr_group; + bitmap_set(cpu_pmu->cntr_mask, 0, nr_counters); cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] = &m1_pmu_format_attr_group; return 0; } /* Device driver gunk */ +static int a7_pmu_cyclone_init(struct arm_pmu *cpu_pmu) +{ + cpu_pmu->name = "apple_cyclone_pmu"; + cpu_pmu->get_event_idx = a7_pmu_get_event_idx; + cpu_pmu->map_event = a7_pmu_map_event; + cpu_pmu->reset = a7_pmu_reset; + cpu_pmu->start = a7_pmu_start; + cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &a7_pmu_events_attr_group; + return apple_pmu_init(cpu_pmu, A7_PMU_NR_COUNTERS); +} + +static int a8_pmu_typhoon_init(struct arm_pmu *cpu_pmu) +{ + cpu_pmu->name = "apple_typhoon_pmu"; + cpu_pmu->get_event_idx = a8_pmu_get_event_idx; + cpu_pmu->map_event = m1_pmu_map_event; + cpu_pmu->reset = a7_pmu_reset; + cpu_pmu->start = a7_pmu_start; + cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &m1_pmu_events_attr_group; + return apple_pmu_init(cpu_pmu, A7_PMU_NR_COUNTERS); +} + +static int a9_pmu_twister_init(struct arm_pmu *cpu_pmu) +{ + cpu_pmu->name = "apple_twister_pmu"; + cpu_pmu->get_event_idx = a9_pmu_get_event_idx; + cpu_pmu->map_event = m1_pmu_map_event; + cpu_pmu->reset = a7_pmu_reset; + cpu_pmu->start = a7_pmu_start; + cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &m1_pmu_events_attr_group; + return apple_pmu_init(cpu_pmu, A7_PMU_NR_COUNTERS); +} + +static int a10_pmu_fusion_init(struct arm_pmu *cpu_pmu) +{ + cpu_pmu->name = "apple_fusion_pmu"; + cpu_pmu->get_event_idx = a10_pmu_get_event_idx; + cpu_pmu->map_event = m1_pmu_map_event; + cpu_pmu->reset = m1_pmu_reset; + cpu_pmu->start = a7_pmu_start; + cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &m1_pmu_events_attr_group; + return apple_pmu_init(cpu_pmu, M1_PMU_NR_COUNTERS); +} + +static int a11_pmu_monsoon_init(struct arm_pmu *cpu_pmu) +{ + cpu_pmu->name = "apple_monsoon_pmu"; + cpu_pmu->get_event_idx = a11_pmu_get_event_idx; + cpu_pmu->map_event = m1_pmu_map_event; + cpu_pmu->reset = m1_pmu_reset; + cpu_pmu->start = m1_pmu_start; + cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &m1_pmu_events_attr_group; + return apple_pmu_init(cpu_pmu, M1_PMU_NR_COUNTERS); +} + +static int a11_pmu_mistral_init(struct arm_pmu *cpu_pmu) +{ + cpu_pmu->name = "apple_mistral_pmu"; + cpu_pmu->get_event_idx = a11_pmu_get_event_idx; + cpu_pmu->map_event = m1_pmu_map_event; + cpu_pmu->reset = m1_pmu_reset; + cpu_pmu->start = m1_pmu_start; + cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &m1_pmu_events_attr_group; + return apple_pmu_init(cpu_pmu, M1_PMU_NR_COUNTERS); +} + static int m1_pmu_ice_init(struct arm_pmu *cpu_pmu) { cpu_pmu->name = "apple_icestorm_pmu"; - return m1_pmu_init(cpu_pmu, ARMPMU_EVT_47BIT); + cpu_pmu->get_event_idx = m1_pmu_get_event_idx; + cpu_pmu->map_event = m1_pmu_map_event; + cpu_pmu->reset = m1_pmu_reset; + cpu_pmu->start = m1_pmu_start; + cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &m1_pmu_events_attr_group; + return apple_pmu_init(cpu_pmu, M1_PMU_NR_COUNTERS); } static int m1_pmu_fire_init(struct arm_pmu *cpu_pmu) { cpu_pmu->name = "apple_firestorm_pmu"; - return m1_pmu_init(cpu_pmu, ARMPMU_EVT_47BIT); + cpu_pmu->get_event_idx = m1_pmu_get_event_idx; + cpu_pmu->map_event = m1_pmu_map_event; + cpu_pmu->reset = m1_pmu_reset; + cpu_pmu->start = m1_pmu_start; + cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &m1_pmu_events_attr_group; + return apple_pmu_init(cpu_pmu, M1_PMU_NR_COUNTERS); } static int m2_pmu_avalanche_init(struct arm_pmu *cpu_pmu) { cpu_pmu->name = "apple_avalanche_pmu"; - return m1_pmu_init(cpu_pmu, ARMPMU_EVT_63BIT); + cpu_pmu->get_event_idx = m1_pmu_get_event_idx; + cpu_pmu->map_event = m2_pmu_map_event; + cpu_pmu->reset = m1_pmu_reset; + cpu_pmu->start = m1_pmu_start; + cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &m1_pmu_events_attr_group; + return apple_pmu_init(cpu_pmu, M1_PMU_NR_COUNTERS); } static int m2_pmu_blizzard_init(struct arm_pmu *cpu_pmu) { cpu_pmu->name = "apple_blizzard_pmu"; - return m1_pmu_init(cpu_pmu, ARMPMU_EVT_63BIT); + cpu_pmu->get_event_idx = m1_pmu_get_event_idx; + cpu_pmu->map_event = m2_pmu_map_event; + cpu_pmu->reset = m1_pmu_reset; + cpu_pmu->start = m1_pmu_start; + cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &m1_pmu_events_attr_group; + return apple_pmu_init(cpu_pmu, M1_PMU_NR_COUNTERS); } static const struct of_device_id m1_pmu_of_device_ids[] = { @@ -684,6 +1428,12 @@ static const struct of_device_id m1_pmu_of_device_ids[] = { { .compatible = "apple,blizzard-pmu", .data = m2_pmu_blizzard_init, }, { .compatible = "apple,icestorm-pmu", .data = m1_pmu_ice_init, }, { .compatible = "apple,firestorm-pmu", .data = m1_pmu_fire_init, }, + { .compatible = "apple,monsoon-pmu", .data = a11_pmu_monsoon_init, }, + { .compatible = "apple,mistral-pmu", .data = a11_pmu_mistral_init, }, + { .compatible = "apple,fusion-pmu", .data = a10_pmu_fusion_init, }, + { .compatible = "apple,twister-pmu", .data = a9_pmu_twister_init, }, + { .compatible = "apple,typhoon-pmu", .data = a8_pmu_typhoon_init, }, + { .compatible = "apple,cyclone-pmu", .data = a7_pmu_cyclone_init, }, { }, }; MODULE_DEVICE_TABLE(of, m1_pmu_of_device_ids); diff --git a/drivers/phy/apple/Kconfig b/drivers/phy/apple/Kconfig index d82d6f291a7537..0f52455021c9c3 100644 --- a/drivers/phy/apple/Kconfig +++ b/drivers/phy/apple/Kconfig @@ -11,3 +11,17 @@ config PHY_APPLE_ATC USB3, USB4, Thunderbolt, and DisplayPort. If M is selected the module will be called 'phy-apple-atc'. + +config PHY_APPLE_AUSB + tristate "Apple AUSB PHY" + depends on (ARM64 && ARCH_APPLE) || (COMPILE_TEST && !GENERIC_ATOMIC64) + select GENERIC_PHY + select APPLE_USBCOMPLEX + help + Enable this to add support for the Apple AUSB PHY found in + Apple Silicon A-series SoCs which is the type of PHY before + Apple Type-C PHY. + + This driver supports USB2. + + If M is selected the module will be called 'phy-apple-ausb'. diff --git a/drivers/phy/apple/Makefile b/drivers/phy/apple/Makefile index e02836a63df3b5..6a52d57193c0d3 100644 --- a/drivers/phy/apple/Makefile +++ b/drivers/phy/apple/Makefile @@ -2,3 +2,6 @@ obj-$(CONFIG_PHY_APPLE_ATC) += phy-apple-atc.o phy-apple-atc-y := atc.o + +obj-$(CONFIG_PHY_APPLE_AUSB) += phy-apple-ausb.o +phy-apple-ausb-y := ausb.o diff --git a/drivers/phy/apple/ausb.c b/drivers/phy/apple/ausb.c new file mode 100644 index 00000000000000..39ba39d833776a --- /dev/null +++ b/drivers/phy/apple/ausb.c @@ -0,0 +1,190 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* + * Apple AUSB PHY + * + * Copyright (C) 2025 Nick Chan + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* These look similar to ATC's USB2PHY_CTL and USB2PHY_SIG */ +#define AUSB_CTL 0x00 +#define AUSB_CTL_RESET BIT(0) +#define AUSB_CTL_PWRDOWN BIT(2) +#define AUSB_CTL_SIDDQ BIT(3) + +#define AUSB_SIG 0x04 +#define AUSB_SIG_VBUSDET_FORCE_EN BIT(1) +#define AUSB_SIG_CABLE_CONNECTED BIT(8) +#define AUSB_SIG_HOST (7 << 12) + +/* Tunable registers */ +#define AUSB_CFG0 0x08 +#define AUSB_CFG1 0x0c + +struct ausb_usbphy { + struct device *dev; + struct phy *phy; + void __iomem *base; + struct phy_provider *phy_provider; + u32 cfg0_device; + u32 cfg1_device; + u32 cfg0_host; + u32 cfg1_host; +}; + +static inline void mask32(void __iomem *reg, u32 mask, u32 set) +{ + u32 value = readl(reg); + value &= ~mask; + value |= set; + writel(value, reg); +} + +static inline void set32(void __iomem *reg, u32 set) +{ + mask32(reg, 0, set); +} + +static inline void clear32(void __iomem *reg, u32 clear) +{ + mask32(reg, clear, 0); +} + +#if 0 +static __maybe_unused int ausb_phy_usb2_set_mode(struct phy *phy, enum phy_mode mode, + int submode) +{ + struct ausb_usbphy *aphy = phy_get_drvdata(phy); + + switch (mode) { + case PHY_MODE_USB_HOST: + case PHY_MODE_USB_HOST_LS: + case PHY_MODE_USB_HOST_FS: + case PHY_MODE_USB_HOST_HS: + case PHY_MODE_USB_HOST_SS: + writel(aphy->cfg0_host, aphy->base + AUSB_CFG0); + writel(aphy->cfg1_host, aphy->base + AUSB_CFG1); + set32(aphy->base + AUSB_SIG, AUSB_SIG_HOST); + return 0; + + case PHY_MODE_USB_DEVICE: + case PHY_MODE_USB_DEVICE_LS: + case PHY_MODE_USB_DEVICE_FS: + case PHY_MODE_USB_DEVICE_HS: + case PHY_MODE_USB_DEVICE_SS: + writel(aphy->cfg0_device, aphy->base + AUSB_CFG0); + writel(aphy->cfg1_device, aphy->base + AUSB_CFG1); + clear32(aphy->base + AUSB_SIG, AUSB_SIG_HOST); + return 0; + + default: + dev_err(aphy->dev, "Unknown mode for usb2 phy: %d\n", mode); + return -EINVAL; + } +} +#endif + +static int ausb_phy_usb2_power_on(struct phy *phy) +{ + struct ausb_usbphy *aphy = phy_get_drvdata(phy); + + /* set a sane tunable */ + writel(aphy->cfg0_device, aphy->base + AUSB_CFG0); + writel(aphy->cfg1_device, aphy->base + AUSB_CFG1); + + set32(aphy->base + AUSB_CTL, AUSB_CTL_RESET); + udelay(20); + clear32(aphy->base, AUSB_CTL_PWRDOWN | AUSB_CTL_SIDDQ); + udelay(20); + clear32(aphy->base + AUSB_CTL, AUSB_CTL_RESET); + udelay(1500); + set32(aphy->base + AUSB_SIG, AUSB_SIG_VBUSDET_FORCE_EN); + + return 0; +} + +static int ausb_phy_usb2_power_off(struct phy *phy) +{ + struct ausb_usbphy *aphy = phy_get_drvdata(phy); + + set32(aphy->base + AUSB_CTL, AUSB_CTL_RESET); + udelay(20); + set32(aphy->base, AUSB_CTL_PWRDOWN | AUSB_CTL_SIDDQ); + udelay(20); + clear32(aphy->base + AUSB_CTL, AUSB_CTL_RESET); + udelay(1500); + clear32(aphy->base + AUSB_SIG, AUSB_SIG_VBUSDET_FORCE_EN); + + return 0; +} + + +static const struct phy_ops ausb_phy_usb2_ops = { + .owner = THIS_MODULE, + //.set_mode = ausb_phy_usb2_set_mode, + .init = ausb_phy_usb2_power_on, + .exit = ausb_phy_usb2_power_off, +}; + +static int ausb_usbphy_probe(struct platform_device *pdev) { + struct ausb_usbphy *aphy; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct resource *res; + + aphy = devm_kzalloc(&pdev->dev, sizeof(*aphy), GFP_KERNEL); + if (!aphy) + return -ENOMEM; + + if (of_property_read_u32(np, "apple,cfg0-device", &aphy->cfg0_device)) + return -ENODEV; + if (of_property_read_u32(np, "apple,cfg1-device", &aphy->cfg1_device)) + return -ENODEV; + if (of_property_read_u32(np, "apple,cfg0-host", &aphy->cfg0_host)) + return -ENODEV; + if (of_property_read_u32(np, "apple,cfg1-host", &aphy->cfg1_host)) + return -ENODEV; + + aphy->dev = dev; + + aphy->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); + if (IS_ERR(aphy->base)) + return PTR_ERR(aphy->base); + + aphy->phy = devm_phy_create(aphy->dev, NULL, &ausb_phy_usb2_ops); + if (IS_ERR(aphy->phy)) + return PTR_ERR(aphy->phy); + + phy_set_drvdata(aphy->phy, aphy); + + aphy->phy_provider = devm_of_phy_provider_register(&pdev->dev, + of_phy_simple_xlate); + + return PTR_ERR_OR_ZERO(aphy->phy_provider); +} + +static const struct of_device_id ausb_usbphy_of_match[] = { + { .compatible = "apple,ausb-phy" }, + {}, +}; + +static struct platform_driver ausb_usbphy_driver = { + .probe = ausb_usbphy_probe, + .driver = { + .of_match_table = ausb_usbphy_of_match, + .name = "phy-apple-ausb", + } + +}; + +module_platform_driver(ausb_usbphy_driver); diff --git a/drivers/power/reset/macsmc-reboot.c b/drivers/power/reset/macsmc-reboot.c index e9702acdd366b0..a40c40e8e0c860 100644 --- a/drivers/power/reset/macsmc-reboot.c +++ b/drivers/power/reset/macsmc-reboot.c @@ -14,6 +14,10 @@ #include #include +/* Power-off Simulation with battery indicator (PRC) */ +#define SHUTDOWN_FLAG_PWR_OFF_SIM_BATT_INDICATOR_ON 0x10 +#define SHUTDOWN_FLAG_PWR_OFF_SIM_BATT_INDICATOR_OFF 0x90 + struct macsmc_reboot_nvmem { struct nvmem_cell *shutdown_flag; struct nvmem_cell *boot_stage; @@ -38,6 +42,8 @@ struct macsmc_reboot { struct device *dev; struct apple_smc *smc; struct notifier_block reboot_notify; + bool has_phra; + u8 sim_shutdown_flag; union { struct macsmc_reboot_nvmem nvm; @@ -97,11 +103,18 @@ static int macsmc_prepare_atomic(struct sys_off_data *data) static int macsmc_power_off(struct sys_off_data *data) { struct macsmc_reboot *reboot = data->cb_data; + u32 poweroff_key; + + if (reboot->has_phra) + poweroff_key = SMC_KEY(off1); + else + poweroff_key = SMC_KEY(off0); + - dev_info(reboot->dev, "Issuing power off (off1)\n"); + dev_info(reboot->dev, "Issuing power off (%p4ch)\n", &poweroff_key); - if (apple_smc_write_u32_atomic(reboot->smc, SMC_KEY(MBSE), SMC_KEY(off1)) < 0) { - dev_err(reboot->dev, "Failed to issue MBSE = off1 (power_off)\n"); + if (apple_smc_write_u32_atomic(reboot->smc, SMC_KEY(MBSE), poweroff_key) < 0) { + dev_err(reboot->dev, "Failed to issue MBSE = %p4ch (power_off)\n", &poweroff_key); } else { mdelay(100); WARN_ONCE(1, "Unable to power off system\n"); @@ -130,7 +143,8 @@ static int macsmc_reboot_notify(struct notifier_block *this, unsigned long actio { struct macsmc_reboot *reboot = container_of(this, struct macsmc_reboot, reboot_notify); u8 shutdown_flag; - u32 val; + u32 val, vbus; + int ret; switch (action) { case SYS_RESTART: @@ -139,7 +153,20 @@ static int macsmc_reboot_notify(struct notifier_block *this, unsigned long actio break; case SYS_POWER_OFF: val = SMC_KEY(offw); - shutdown_flag = 1; + if (reboot->has_phra) { + shutdown_flag = 1; + } else { + ret = apple_smc_read_u32(reboot->smc, SMC_KEY(VBUS), &vbus); + if (ret) { + dev_err(reboot->dev, "Failed to read VBUS state: %d\n", ret); + vbus = 0; + } + /* Continue because we are shutting down */ + if (vbus) + shutdown_flag = reboot->sim_shutdown_flag; + else + shutdown_flag = 0; + } break; default: return NOTIFY_DONE; @@ -205,6 +232,9 @@ static int macsmc_reboot_probe(struct platform_device *pdev) struct macsmc_reboot *reboot; int ret, i; + if (!pdev->dev.of_node) + return -ENODEV; + reboot = devm_kzalloc(&pdev->dev, sizeof(*reboot), GFP_KERNEL); if (!reboot) return -ENOMEM; @@ -212,6 +242,13 @@ static int macsmc_reboot_probe(struct platform_device *pdev) reboot->dev = &pdev->dev; reboot->smc = smc; + reboot->has_phra = (bool)of_device_get_match_data(&pdev->dev); + + if (of_property_read_bool(pdev->dev.of_node, "prc-poweroff")) + reboot->sim_shutdown_flag = SHUTDOWN_FLAG_PWR_OFF_SIM_BATT_INDICATOR_ON; + else + reboot->sim_shutdown_flag = SHUTDOWN_FLAG_PWR_OFF_SIM_BATT_INDICATOR_OFF; + platform_set_drvdata(pdev, reboot); for (i = 0; i < ARRAY_SIZE(nvmem_names); i++) { @@ -256,10 +293,13 @@ static int macsmc_reboot_probe(struct platform_device *pdev) if (ret) return dev_err_probe(&pdev->dev, ret, "Failed to register restart prepare handler\n"); - ret = devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART, SYS_OFF_PRIO_HIGH, - macsmc_restart, reboot); - if (ret) - return dev_err_probe(&pdev->dev, ret, "Failed to register restart handler\n"); + + if (reboot->has_phra) { + ret = devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART, + SYS_OFF_PRIO_HIGH, macsmc_restart, reboot); + if (ret) + return dev_err_probe(&pdev->dev, ret, "Failed to register restart handler\n"); + } ret = devm_register_reboot_notifier(&pdev->dev, &reboot->reboot_notify); if (ret) @@ -271,7 +311,8 @@ static int macsmc_reboot_probe(struct platform_device *pdev) } static const struct of_device_id macsmc_reboot_of_table[] = { - { .compatible = "apple,smc-reboot", }, + { .compatible = "apple,smc-reboot", .data = (void*)true }, + { .compatible = "apple,t8015-smc-reboot", .data = (void*)false }, {} }; MODULE_DEVICE_TABLE(of, macsmc_reboot_of_table); diff --git a/drivers/power/supply/macsmc-power.c b/drivers/power/supply/macsmc-power.c index 33ca07460f3a31..8c7363fb1a852a 100644 --- a/drivers/power/supply/macsmc-power.c +++ b/drivers/power/supply/macsmc-power.c @@ -57,6 +57,8 @@ #define ACSt_CAN_BOOT_AP BIT(2) #define ACSt_CAN_BOOT_IBOOT BIT(1) +#define BMDT_SUPPORTED_LEN 6 + #define CHWA_CHLS_FIXED_START_OFFSET 5 #define CHLS_MIN_END_THRESHOLD 10 #define CHLS_FORCE_DISCHARGE 0x100 @@ -81,12 +83,15 @@ struct macsmc_power { char mfg_date[MAX_STRING_LENGTH]; /* Supported feature flags based on SMC key presence */ + bool has_bmdn; /* Battery Model Name */ bool has_chwa; /* Charge limit (Modern firmware) */ bool has_chls; /* Charge limit (Older firmware) */ bool has_ch0i; /* Force discharge (Older firmware) */ bool has_ch0c; /* Inhibit charge (Older firmware) */ bool has_chte; /* Inhibit charge (Modern firmware) */ + u32 b0ap_type; /* SMC key type for power now (si16 or si32) */ + u8 num_cells; int nominal_voltage_mv; @@ -353,8 +358,18 @@ static int macsmc_battery_get_property(struct power_supply *psy, val->intval = vs16 * 1000; break; case POWER_SUPPLY_PROP_POWER_NOW: - ret = apple_smc_read_s32(power->smc, SMC_KEY(B0AP), &vs32); - val->intval = vs32 * 1000; + switch (power->b0ap_type) { + case __SMC_KEY('s', 'i', '1', '6'): + ret = apple_smc_read_s16(power->smc, SMC_KEY(B0AP), &vs16); + val->intval = vs16 * 1000; + break; + case __SMC_KEY('s', 'i', '3', '2'): + ret = apple_smc_read_s32(power->smc, SMC_KEY(B0AP), &vs32); + val->intval = vs32 * 1000; + break; + default: + return -EINVAL; + } break; case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: ret = apple_smc_read_u16(power->smc, SMC_KEY(BITV), &vu16); @@ -594,7 +609,9 @@ static int macsmc_power_event(struct notifier_block *nb, unsigned long event, vo * 0x71... indicates power/battery events. */ if ((event & 0xffffff00) == 0x71010100 || /* Charger status change */ + (event & 0xffffff00) == 0x71010200 || /* Wireless charger status change */ (event & 0xffff0000) == 0x71060000 || /* Port charge state change */ + (event & 0xffff0000) == 0x71070000 || /* Charging coil state change */ (event & 0xffff0000) == 0x71130000) { /* Connector insert/remove event */ if (power->batt) power_supply_changed(power->batt); @@ -617,6 +634,7 @@ static int macsmc_power_probe(struct platform_device *pdev) struct apple_smc *smc = dev_get_drvdata(pdev->dev.parent); struct power_supply_config psy_cfg = {}; struct macsmc_power *power; + struct apple_smc_key_info info; bool has_battery = false; bool has_ac_adapter = false; int ret = -ENODEV; @@ -680,24 +698,12 @@ static int macsmc_power_probe(struct platform_device *pdev) props[nprops++] = POWER_SUPPLY_PROP_CAPACITY_LEVEL; props[nprops++] = POWER_SUPPLY_PROP_TEMP; props[nprops++] = POWER_SUPPLY_PROP_CYCLE_COUNT; - props[nprops++] = POWER_SUPPLY_PROP_HEALTH; props[nprops++] = POWER_SUPPLY_PROP_SCOPE; - props[nprops++] = POWER_SUPPLY_PROP_MODEL_NAME; props[nprops++] = POWER_SUPPLY_PROP_SERIAL_NUMBER; - props[nprops++] = POWER_SUPPLY_PROP_MANUFACTURE_YEAR; - props[nprops++] = POWER_SUPPLY_PROP_MANUFACTURE_MONTH; - props[nprops++] = POWER_SUPPLY_PROP_MANUFACTURE_DAY; /* Extended properties usually present */ - props[nprops++] = POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW; - props[nprops++] = POWER_SUPPLY_PROP_TIME_TO_FULL_NOW; - props[nprops++] = POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN; - props[nprops++] = POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN; props[nprops++] = POWER_SUPPLY_PROP_VOLTAGE_MIN; props[nprops++] = POWER_SUPPLY_PROP_VOLTAGE_MAX; - props[nprops++] = POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT; - props[nprops++] = POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX; - props[nprops++] = POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE; props[nprops++] = POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN; props[nprops++] = POWER_SUPPLY_PROP_CHARGE_FULL; props[nprops++] = POWER_SUPPLY_PROP_CHARGE_NOW; @@ -707,6 +713,24 @@ static int macsmc_power_probe(struct platform_device *pdev) props[nprops++] = POWER_SUPPLY_PROP_CHARGE_COUNTER; /* Detect features based on key availability */ + if (apple_smc_key_exists(smc, SMC_KEY(B0TE))) /* A11 iOS 15.0+ */ + props[nprops++] = POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW; + if (apple_smc_key_exists(smc, SMC_KEY(B0TF))) /* Unavailable on A11 */ + props[nprops++] = POWER_SUPPLY_PROP_TIME_TO_FULL_NOW; + if (apple_smc_key_exists(smc, SMC_KEY(B0RC))) /* Unavailable on A11 */ + props[nprops++] = POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT; + if (apple_smc_key_exists(smc, SMC_KEY(B0RI))) /* Unavailable on A11 */ + props[nprops++] = POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX; + if (apple_smc_key_exists(smc, SMC_KEY(B0RV))) /* Unavailable on A11 */ + props[nprops++] = POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE; + if (apple_smc_key_exists(smc, SMC_KEY(BBAD))) /* A11 iOS 14.0+ */ + props[nprops++] = POWER_SUPPLY_PROP_HEALTH; + if (apple_smc_key_exists(smc, SMC_KEY(BITV))) /* Unavailable on A11 */ + props[nprops++] = POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN; + if (apple_smc_key_exists(smc, SMC_KEY(BVVN))) /* A11 iOS 14.0+ */ + props[nprops++] = POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN; + if (apple_smc_key_exists(smc, SMC_KEY(BMDN))) /* Unavailable on A11 */ + power->has_bmdn = true; if (apple_smc_key_exists(smc, SMC_KEY(CHTE))) power->has_chte = true; if (apple_smc_key_exists(smc, SMC_KEY(CH0C))) @@ -714,6 +738,11 @@ static int macsmc_power_probe(struct platform_device *pdev) if (apple_smc_key_exists(smc, SMC_KEY(CH0I))) power->has_ch0i = true; + /* B0AP changed from si16 to si32 in iOS 15.0 so detect it here */ + ret = apple_smc_get_key_info(smc, SMC_KEY(B0AP), &info); + if (!ret) + power->b0ap_type = info.type_code; + /* Reset "Optimised Battery Charging" flags to default state */ if (power->has_chte) apple_smc_write_u32(smc, SMC_KEY(CHTE), 0); @@ -755,12 +784,32 @@ static int macsmc_power_probe(struct platform_device *pdev) power->batt_desc.num_properties = nprops; /* Fetch identity strings */ - apple_smc_read(smc, SMC_KEY(BMDN), power->model_name, - sizeof(power->model_name) - 1); - apple_smc_read(smc, SMC_KEY(BMSN), power->serial_number, - sizeof(power->serial_number) - 1); - apple_smc_read(smc, SMC_KEY(BMDT), power->mfg_date, - sizeof(power->mfg_date) - 1); + if (power->has_bmdn) { + apple_smc_read(smc, SMC_KEY(BMDN), power->model_name, + sizeof(power->model_name) - 1); + + props[nprops++] = POWER_SUPPLY_PROP_MODEL_NAME; + } + /* BMDT is 4 byte in Apple A11 and is of an unknown format */ + ret = apple_smc_get_key_info(smc, SMC_KEY(BMDT), &info); + if (!ret && info.size == BMDT_SUPPORTED_LEN) { + apple_smc_read(smc, SMC_KEY(BMDT), power->mfg_date, + sizeof(power->mfg_date) - 1); + + props[nprops++] = POWER_SUPPLY_PROP_MANUFACTURE_YEAR; + props[nprops++] = POWER_SUPPLY_PROP_MANUFACTURE_MONTH; + props[nprops++] = POWER_SUPPLY_PROP_MANUFACTURE_DAY; + } + + /* + * On Apple A11, iOS 16 reading more than 0x80 bytes from SMC + * SRAM causes SError so check the key size first. + */ + ret = apple_smc_get_key_info(smc, SMC_KEY(BMSN), &info); + if (!ret) { + apple_smc_read(smc, SMC_KEY(BMSN), power->serial_number, + min(info.size, sizeof(power->serial_number) - 1)); + } apple_smc_read_u8(power->smc, SMC_KEY(BNCB), &power->num_cells); power->nominal_voltage_mv = MACSMC_NOMINAL_CELL_VOLTAGE_MV * power->num_cells; @@ -801,6 +850,17 @@ static int macsmc_power_probe(struct platform_device *pdev) props[nprops++] = POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT; } + /* + * On T8015, AC requires manual configuration. There is a D2* + * version of keys with the seemingly same effect. + */ + if (apple_smc_key_exists(power->smc, SMC_KEY(D1NO))) { + apple_smc_write_u32(power->smc, SMC_KEY(D1AR), 1000); /* Current in mA */ + apple_smc_write_u32(power->smc, SMC_KEY(D1VR), 5000); /* Voltage in mV */ + apple_smc_write_u32(power->smc, SMC_KEY(D1IR), 1000); /* Current in mA */ + apple_smc_write_u8(power->smc, SMC_KEY(D1NO), 1); /* Apply settings */ + } + if (nprops > MACSMC_MAX_AC_PROPS) return -ENOMEM; diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 364afc73f8abd2..4fed5af39361f3 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1208,6 +1208,18 @@ config RTC_DRV_DS2404 This driver can also be built as a module. If so, the module will be called rtc-ds2404. +config RTC_DRV_APPLE_PMIC + tristate "Apple PMIC RTC" + depends on ARCH_APPLE || COMPILE_TEST + select MFD_SIMPLE_MFD_SPMI + select MFD_SIMPLE_MFD_I2C + help + If you say yes here you get support for the RTC in PMIC chips + found on Apple iPhones and iPads. + + This driver can also be built as a module, if so, the module + will be called "rtc-apple-pmic". + config RTC_DRV_DA9052 tristate "Dialog DA9052/DA9053 RTC" depends on PMIC_DA9052 diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 6cf7e066314e13..f0a37a5ab82152 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o obj-$(CONFIG_RTC_DRV_CPCAP) += rtc-cpcap.o obj-$(CONFIG_RTC_DRV_CROS_EC) += rtc-cros-ec.o obj-$(CONFIG_RTC_DRV_CV1800) += rtc-cv1800.o +obj-$(CONFIG_RTC_DRV_APPLE_PMIC) += rtc-apple-pmic.o obj-$(CONFIG_RTC_DRV_DA9052) += rtc-da9052.o obj-$(CONFIG_RTC_DRV_DA9055) += rtc-da9055.o obj-$(CONFIG_RTC_DRV_DA9063) += rtc-da9063.o diff --git a/drivers/rtc/rtc-apple-pmic.c b/drivers/rtc/rtc-apple-pmic.c new file mode 100644 index 00000000000000..ac1e086f70524e --- /dev/null +++ b/drivers/rtc/rtc-apple-pmic.c @@ -0,0 +1,290 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Apple PMIC RTC driver + * + * Based on rtc-pm8xxx.c + * + * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved. + * Copyright (c) 2023, Linaro Limited + * Copyright (c) 2025, Nick Chan + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define RTC_COUNTER_SIZE 6 + +/** + * struct apple_pmic_rtc_regs - RTC Hardware registers + * @control: RTC Control + * @counter: Time Counter + */ + +struct apple_pmic_rtc_regs { + u32 control; + u32 counter; +}; + +/** + * struct apple_pmic_rtc - RTC driver internal structure + * @rtc: RTC device + * @regmap: regmap used to access registers + * @nvmem_cell: nvmem cell for offset + * @regs: hardware registers + * @base: RTC base address + * @offset: offset from epoch in seconds + * @offset_dirty: offset needs to be stored on shutdown + */ +struct apple_pmic_rtc { + struct rtc_device *rtc; + struct regmap *regmap; + struct device *dev; + struct nvmem_cell *nvmem_cell; + const struct apple_pmic_rtc_regs *regs; + u32 base; + int offset; + bool offset_dirty; +}; + +static int apple_pmic_rtc_read_nvmem_offset(struct apple_pmic_rtc *ap_rtc) +{ + size_t len; + void *buf; + int rc; + + buf = nvmem_cell_read(ap_rtc->nvmem_cell, &len); + if (IS_ERR(buf)) { + rc = PTR_ERR(buf); + dev_dbg(ap_rtc->dev, "failed to read nvmem offset: %d\n", rc); + return rc; + } + + if (len != sizeof(int)) { + dev_dbg(ap_rtc->dev, "unexpected nvmem cell size %zu\n", len); + kfree(buf); + return -EINVAL; + } + + ap_rtc->offset = get_unaligned_le32(buf); + + kfree(buf); + + return 0; +} + +static int apple_pmic_rtc_write_nvmem_offset(struct apple_pmic_rtc *ap_rtc, int offset) +{ + u8 buf[sizeof(u32)]; + int rc; + + put_unaligned_le32(offset, buf); + + rc = nvmem_cell_write(ap_rtc->nvmem_cell, buf, sizeof(buf)); + if (rc < 0) { + dev_dbg(ap_rtc->dev, "failed to write nvmem offset: %d\n", rc); + return rc; + } + + return 0; +} + +static int apple_pmic_rtc_read_raw(struct apple_pmic_rtc *ap_rtc, u32 *secs) +{ + u64 value; + int rc; + + rc = regmap_bulk_read(ap_rtc->regmap, + ap_rtc->base + ap_rtc->regs->counter, &value, RTC_COUNTER_SIZE); + if (rc) + return rc; + + *secs = (u32)(value >> 16); + return 0; +} + +static int apple_pmic_rtc_update_offset(struct apple_pmic_rtc *ap_rtc, int secs) +{ + u32 raw_secs; + int offset; + int rc; + + rc = apple_pmic_rtc_read_raw(ap_rtc, &raw_secs); + if (rc) + return rc; + + offset = secs - raw_secs; + + if (offset == ap_rtc->offset) + return 0; + + /* + * Reduce wear by deferring updates due to clock drift until shutdown. + */ + if (abs_diff(offset, ap_rtc->offset) < 30) { + ap_rtc->offset_dirty = true; + goto out; + } + + rc = apple_pmic_rtc_write_nvmem_offset(ap_rtc, offset); + + if (rc) + return rc; + + ap_rtc->offset_dirty = false; +out: + ap_rtc->offset = offset; + + return 0; +} + +static int apple_pmic_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct apple_pmic_rtc *ap_rtc = dev_get_drvdata(dev); + int secs; + int rc; + + secs = rtc_tm_to_time64(tm); + + rc = apple_pmic_rtc_update_offset(ap_rtc, secs); + if (rc) + return rc; + + dev_dbg(dev, "set time: %ptRd %ptRt (%u + %u)\n", tm, tm, + secs - ap_rtc->offset, ap_rtc->offset); + return 0; +} + +static int apple_pmic_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct apple_pmic_rtc *ap_rtc = dev_get_drvdata(dev); + int secs; + int rc; + + rc = apple_pmic_rtc_read_raw(ap_rtc, &secs); + if (rc) + return rc; + + secs += ap_rtc->offset; + rtc_time64_to_tm(secs, tm); + + dev_dbg(dev, "read time: %ptRd %ptRt (%u + %u)\n", tm, tm, + secs - ap_rtc->offset, ap_rtc->offset); + return 0; +} + +static const struct rtc_class_ops apple_pmic_rtc_ops = { + .read_time = apple_pmic_rtc_read_time, + .set_time = apple_pmic_rtc_set_time, +}; + +static const struct apple_pmic_rtc_regs amber_regs = { + .control = 0x4, + .counter = 0x6 +}; + +static const struct apple_pmic_rtc_regs antigua_regs = { + .control = 0x0, + .counter = 0x2 +}; + +static const struct of_device_id apple_pmic_id_table[] = { + { .compatible = "apple,amber-pmic-rtc", .data = &amber_regs }, + { .compatible = "apple,antigua-pmic-rtc", .data = &antigua_regs }, + { }, +}; +MODULE_DEVICE_TABLE(of, apple_pmic_id_table); + +static int apple_pmic_rtc_probe_offset(struct apple_pmic_rtc *ap_rtc) +{ + int rc; + + ap_rtc->nvmem_cell = devm_nvmem_cell_get(ap_rtc->dev, "rtc_offset"); + if (IS_ERR(ap_rtc->nvmem_cell)) { + rc = PTR_ERR(ap_rtc->nvmem_cell); + if (rc != -ENOENT) + return rc; + ap_rtc->nvmem_cell = NULL; + } else { + return apple_pmic_rtc_read_nvmem_offset(ap_rtc); + } + + return 0; +} + +static int apple_pmic_rtc_probe(struct platform_device *pdev) +{ + struct device_node *node = pdev->dev.of_node; + const struct of_device_id *match; + struct apple_pmic_rtc *ap_rtc; + int rc; + + match = of_match_node(apple_pmic_id_table, node); + if (!match) + return -ENXIO; + + ap_rtc = devm_kzalloc(&pdev->dev, sizeof(*ap_rtc), GFP_KERNEL); + if (ap_rtc == NULL) + return -ENOMEM; + + rc = of_property_read_u32_index(node, "reg", 0, &ap_rtc->base); + if (rc) + return -ENXIO; + + ap_rtc->dev = &pdev->dev; + ap_rtc->regs = match->data; + + ap_rtc->regmap = dev_get_regmap(pdev->dev.parent, NULL); + if (!ap_rtc->regmap) + return -ENXIO; + + rc = apple_pmic_rtc_probe_offset(ap_rtc); + if (rc) + return rc; + + platform_set_drvdata(pdev, ap_rtc); + + ap_rtc->rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(ap_rtc->rtc)) + return PTR_ERR(ap_rtc->rtc); + + ap_rtc->rtc->ops = &apple_pmic_rtc_ops; + ap_rtc->rtc->range_min = INT_MIN; + ap_rtc->rtc->range_max = INT_MAX; + + return devm_rtc_register_device(ap_rtc->rtc); +} + +static void apple_pmic_shutdown(struct platform_device *pdev) +{ + struct apple_pmic_rtc *ap_rtc = platform_get_drvdata(pdev); + + if (ap_rtc->offset_dirty) + apple_pmic_rtc_write_nvmem_offset(ap_rtc, ap_rtc->offset); +} + +static struct platform_driver apple_pmic_rtc_driver = { + .probe = apple_pmic_rtc_probe, + .shutdown = apple_pmic_shutdown, + .driver = { + .name = "rtc-apple-pmic", + .of_match_table = apple_pmic_id_table, + }, +}; + +module_platform_driver(apple_pmic_rtc_driver); + +MODULE_ALIAS("platform:rtc-apple-pmic"); +MODULE_DESCRIPTION("Apple PMIC RTC driver"); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Nick Chan "); diff --git a/drivers/soc/apple/Kconfig b/drivers/soc/apple/Kconfig index d0ff32182a2b4a..e9c78a500488b7 100644 --- a/drivers/soc/apple/Kconfig +++ b/drivers/soc/apple/Kconfig @@ -28,6 +28,16 @@ config APPLE_RTKIT Say 'y' here if you have an Apple SoC. +config APPLE_PMP_T8015 + tristate "Apple T8015 PMP" + depends on ARCH_APPLE || COMPILE_TEST + help + Apple PMP is a coprocessor with power-management functions. This + option enable support for booting its firmware, which is enough + to reduce power consumption. + + Say 'y' here if you have an Apple A11 SoC. + config APPLE_SART tristate "Apple SART DMA address filter" depends on ARCH_APPLE || COMPILE_TEST diff --git a/drivers/soc/apple/Makefile b/drivers/soc/apple/Makefile index 0b85ab61aefe13..078318d286bab4 100644 --- a/drivers/soc/apple/Makefile +++ b/drivers/soc/apple/Makefile @@ -11,3 +11,5 @@ apple-sart-y = sart.o obj-$(CONFIG_APPLE_TUNABLE) += apple-tunable.o apple-tunable-y = tunable.o + +obj-$(CONFIG_APPLE_PMP_T8015) += pmp_t8015.o diff --git a/drivers/soc/apple/pmp_t8015.c b/drivers/soc/apple/pmp_t8015.c new file mode 100644 index 00000000000000..dadc0c9319b219 --- /dev/null +++ b/drivers/soc/apple/pmp_t8015.c @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Apple T8015 PMP (Power Management Processor) Driver + * + * Copyright 2026 Nick Chan + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define AKF_REMAP_AP_LO 0x8 +#define AKF_REMAP_AP_HI 0x10 +#define AKF_REMAP_IOP_LO 0x18 +#define AKF_REMAP_IOP_HI 0x20 +#define AKF_REMAP_SZ_LO 0x28 +#define AKF_REMAP_SZ_HI 0x30 +#define AKF_REMAP_ENABLE 0x38 +#define AKF_REG_80C 0x80c + +struct apple_pmp { + void __iomem *akf_base; + void __iomem *ctl_base; + void __iomem *sram_base; + struct resource *sram; + struct device *dev; + const char *fw_name; + struct apple_rtkit *rtk; +}; + +static const struct apple_rtkit_ops apple_pmp_rtkit_ops = {}; + +static int apple_pmp_upload_firmware(struct apple_pmp *pmp) +{ + const struct firmware *fw __free(firmware) = NULL; + int ret; + + ret = request_firmware(&fw, pmp->fw_name, pmp->dev); + if (ret) { + dev_err(pmp->dev, "unable to load firmware\n"); + return ret; + } + + if (fw->size > resource_size(pmp->sram)) { + dev_err(pmp->dev, "firmware larger than SRAM: %zu > %llu", + fw->size, resource_size(pmp->sram)); + return -ENOSPC; + } + + memcpy_toio(pmp->sram_base, fw->data, fw->size); + + /* Map PMP SRAM to its reset vector (0x0) */ + writel(0, pmp->akf_base + AKF_REMAP_IOP_LO); + writel(0, pmp->akf_base + AKF_REMAP_IOP_HI); + writel(resource_size(pmp->sram) & 0xffffffff, pmp->akf_base + AKF_REMAP_SZ_LO); + writel(resource_size(pmp->sram) & 0xffffffff, + pmp->akf_base + AKF_REMAP_SZ_HI); + writel((uintptr_t)pmp->sram->start & 0xffffffff, + pmp->akf_base + AKF_REMAP_AP_LO); + writel(((uintptr_t)pmp->sram->start >> 32) & 0xffffffff, + pmp->akf_base + AKF_REMAP_AP_HI); + writel(1, pmp->akf_base + AKF_REMAP_ENABLE); + + /* Unknown */ + writel(0, pmp->akf_base + AKF_REG_80C); + writel(2, pmp->akf_base + AKF_REG_80C); + + /* Start PMP */ + writel(1, pmp->ctl_base); + + return 0; +} + +static int apple_pmp_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct apple_pmp *pmp; + struct resource *res; + int ret; + + pmp = devm_kzalloc(&pdev->dev, sizeof(*pmp), GFP_KERNEL); + if (!pmp) + return -ENOMEM; + + pmp->dev = dev; + + pmp->akf_base = devm_platform_ioremap_resource_byname(pdev, "akf"); + if (IS_ERR(pmp->akf_base)) + return PTR_ERR(pmp->akf_base); + + pmp->ctl_base = devm_platform_ioremap_resource_byname(pdev, "control"); + if (IS_ERR(pmp->ctl_base)) + return PTR_ERR(pmp->ctl_base); + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram"); + if (IS_ERR(res)) + return PTR_ERR(res); + + pmp->sram = res; + pmp->sram_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(pmp->sram_base)) + return PTR_ERR(pmp->sram_base); + + ret = device_property_read_string(dev, "firmware-name", &pmp->fw_name); + if (ret) + return dev_err_probe(dev, ret, "unable to get firmware name\n"); + + ret = apple_pmp_upload_firmware(pmp); + if (ret) + return ret; + + pmp->rtk = devm_apple_rtkit_init(dev, pmp, NULL, 0, &apple_pmp_rtkit_ops); + if (IS_ERR(pmp->rtk)) + return dev_err_probe(dev, PTR_ERR(pmp->rtk), "Failed to initialize RTKit"); + + if (dma_set_mask_and_coherent(pmp->dev, DMA_BIT_MASK(64))) { + ret = -ENXIO; + return ret; + } + + ret = apple_rtkit_wake(pmp->rtk); + if (ret) + return dev_err_probe(dev, ret, "Failed to wake PMP"); + + return 0; +} + +static const struct of_device_id apple_pmp_of_match[] = { + { .compatible = "apple,t8015-pmp" }, + {} +}; +MODULE_DEVICE_TABLE(of, apple_pmp_of_match); + + +static struct platform_driver apple_pmp_driver = { + .driver = { + .name = "pmp-t8015", + .of_match_table = apple_pmp_of_match, + }, + .probe = apple_pmp_probe, +}; +module_platform_driver(apple_pmp_driver); + +MODULE_AUTHOR("Nick Chan "); +MODULE_LICENSE("Dual MIT/GPL"); +MODULE_DESCRIPTION("Apple T8015 PMP driver"); diff --git a/drivers/soc/apple/rtkit-internal.h b/drivers/soc/apple/rtkit-internal.h index b8d5244678f010..5f91dea8b7a178 100644 --- a/drivers/soc/apple/rtkit-internal.h +++ b/drivers/soc/apple/rtkit-internal.h @@ -19,7 +19,8 @@ #include #include "mailbox.h" -#define APPLE_RTKIT_APP_ENDPOINT_START 0x20 +#define APPLE_RTKIT_APP_ENDPOINT_START_V10 0x6 +#define APPLE_RTKIT_APP_ENDPOINT_START_V11 0x20 #define APPLE_RTKIT_MAX_ENDPOINTS 0x100 struct apple_rtkit { @@ -35,6 +36,7 @@ struct apple_rtkit { int boot_result; int version; + u8 app_ep_start; unsigned int iop_power_state; unsigned int ap_power_state; diff --git a/drivers/soc/apple/rtkit.c b/drivers/soc/apple/rtkit.c index a3fdac8f6f069e..a6bce181d9886f 100644 --- a/drivers/soc/apple/rtkit.c +++ b/drivers/soc/apple/rtkit.c @@ -71,7 +71,7 @@ enum { #define APPLE_RTKIT_OSLOG_SIZE GENMASK_ULL(55, 36) #define APPLE_RTKIT_OSLOG_IOVA GENMASK_ULL(35, 0) -#define APPLE_RTKIT_MIN_SUPPORTED_VERSION 11 +#define APPLE_RTKIT_MIN_SUPPORTED_VERSION 10 #define APPLE_RTKIT_MAX_SUPPORTED_VERSION 12 struct apple_rtkit_rx_work { @@ -140,6 +140,11 @@ static void apple_rtkit_management_rx_hello(struct apple_rtkit *rtk, u64 msg) want_ver); rtk->version = want_ver; + if (rtk->version < 11) + rtk->app_ep_start = APPLE_RTKIT_APP_ENDPOINT_START_V10; + else + rtk->app_ep_start = APPLE_RTKIT_APP_ENDPOINT_START_V11; + reply = FIELD_PREP(APPLE_RTKIT_MGMT_HELLO_MINVER, want_ver); reply |= FIELD_PREP(APPLE_RTKIT_MGMT_HELLO_MAXVER, want_ver); apple_rtkit_management_send(rtk, APPLE_RTKIT_MGMT_HELLO_REPLY, reply); @@ -169,17 +174,19 @@ static void apple_rtkit_management_rx_epmap(struct apple_rtkit *rtk, u64 msg) } reply = FIELD_PREP(APPLE_RTKIT_MGMT_EPMAP_BASE, base); - if (msg & APPLE_RTKIT_MGMT_EPMAP_LAST) - reply |= APPLE_RTKIT_MGMT_EPMAP_LAST; - else - reply |= APPLE_RTKIT_MGMT_EPMAP_REPLY_MORE; + if (rtk->version > 10) { + if (msg & APPLE_RTKIT_MGMT_EPMAP_LAST) + reply |= APPLE_RTKIT_MGMT_EPMAP_LAST; + else + reply |= APPLE_RTKIT_MGMT_EPMAP_REPLY_MORE; + } apple_rtkit_management_send(rtk, APPLE_RTKIT_MGMT_EPMAP_REPLY, reply); - if (!(msg & APPLE_RTKIT_MGMT_EPMAP_LAST)) + if (rtk->version > 10 && !(msg & APPLE_RTKIT_MGMT_EPMAP_LAST)) return; - for_each_set_bit(ep, rtk->endpoints, APPLE_RTKIT_APP_ENDPOINT_START) { + for_each_set_bit(ep, rtk->endpoints, rtk->app_ep_start) { switch (ep) { /* the management endpoint is started by default */ case APPLE_RTKIT_EP_MGMT: @@ -547,20 +554,21 @@ static void apple_rtkit_rx_work(struct work_struct *work) case APPLE_RTKIT_EP_OSLOG: apple_rtkit_oslog_rx(rtk, rtk_work->msg); break; - case APPLE_RTKIT_APP_ENDPOINT_START ... 0xff: - if (rtk->ops->recv_message) + default: + if (rtk_work->ep >= rtk->app_ep_start && rtk->ops->recv_message) rtk->ops->recv_message(rtk->cookie, rtk_work->ep, rtk_work->msg); - else + else if (rtk_work->ep >= rtk->app_ep_start) dev_warn( rtk->dev, "Received unexpected message to EP%02d: %llx\n", rtk_work->ep, rtk_work->msg); + else + dev_warn( + rtk->dev, + "RTKit: message to unknown endpoint %02x: %llx\n", + rtk_work->ep, rtk_work->msg); break; - default: - dev_warn(rtk->dev, - "RTKit: message to unknown endpoint %02x: %llx\n", - rtk_work->ep, rtk_work->msg); } kfree(rtk_work); @@ -585,7 +593,7 @@ static void apple_rtkit_rx(struct apple_mbox *mbox, struct apple_mbox_msg msg, "RTKit: Message to undiscovered endpoint 0x%02x\n", ep); - if (ep >= APPLE_RTKIT_APP_ENDPOINT_START && + if (ep >= rtk->app_ep_start && rtk->ops->recv_message_early && rtk->ops->recv_message_early(rtk->cookie, ep, msg.msg0)) return; @@ -615,8 +623,7 @@ int apple_rtkit_send_message(struct apple_rtkit *rtk, u8 ep, u64 message, return -EINVAL; } - if (ep >= APPLE_RTKIT_APP_ENDPOINT_START && - !apple_rtkit_is_running(rtk)) { + if (ep >= rtk->app_ep_start && !apple_rtkit_is_running(rtk)) { dev_warn(rtk->dev, "RTKit: Endpoint 0x%02x is not running, cannot send message\n", ep); return -EINVAL; @@ -645,7 +652,7 @@ int apple_rtkit_start_ep(struct apple_rtkit *rtk, u8 endpoint) if (!test_bit(endpoint, rtk->endpoints)) return -EINVAL; - if (endpoint >= APPLE_RTKIT_APP_ENDPOINT_START && + if (endpoint >= rtk->app_ep_start && !apple_rtkit_is_running(rtk)) return -EINVAL; @@ -675,6 +682,13 @@ struct apple_rtkit *apple_rtkit_init(struct device *dev, void *cookie, rtk->cookie = cookie; rtk->ops = ops; + /* + * The management endpoint is required to receive the HELLO message + * and infer the start of app endpoints so assume it is a system + * endpoint here and update this value when HELLO is received. + */ + rtk->app_ep_start = APPLE_RTKIT_EP_CRASHLOG; + init_completion(&rtk->epmap_completion); init_completion(&rtk->iop_pwr_ack_completion); init_completion(&rtk->ap_pwr_ack_completion); @@ -867,6 +881,15 @@ int apple_rtkit_poweroff(struct apple_rtkit *rtk) } EXPORT_SYMBOL_GPL(apple_rtkit_poweroff); +u8 apple_rtkit_app_ep_to_ep(struct apple_rtkit *rtk, u8 app_ep) +{ + if (!apple_rtkit_is_running(rtk)) + return 0; + + return rtk->app_ep_start + app_ep; +} +EXPORT_SYMBOL_GPL(apple_rtkit_app_ep_to_ep); + int apple_rtkit_idle(struct apple_rtkit *rtk) { int ret; diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c index 091bfcfef75301..c6be27724cfe53 100644 --- a/drivers/usb/dwc2/params.c +++ b/drivers/usb/dwc2/params.c @@ -303,6 +303,25 @@ static void dwc2_set_stm32mp15_hsotg_params(struct dwc2_hsotg *hsotg) p->hird_threshold_en = false; } +static void dwc2_set_apple_silicon_params(struct dwc2_hsotg *hsotg) +{ + struct dwc2_core_params *p = &hsotg->params; + unsigned fifo, fifo_count; + + p->speed = DWC2_SPEED_PARAM_HIGH; + p->power_down = DWC2_POWER_DOWN_PARAM_NONE; + p->g_rx_fifo_size = 539; + p->host_nperio_tx_fifo_size = 16; + p->g_np_tx_fifo_size = 16; + p->lpm = false; + + + fifo_count = dwc2_hsotg_tx_fifo_count(hsotg); + p->g_tx_fifo_size[0] = 64; + for(fifo = 1; fifo <= fifo_count; fifo++) + p->g_tx_fifo_size[fifo] = 244; +} + const struct of_device_id dwc2_of_match_table[] = { { .compatible = "brcm,bcm2835-usb", .data = dwc2_set_bcm_params }, { .compatible = "hisilicon,hi6220-usb", .data = dwc2_set_his_params }, @@ -347,6 +366,8 @@ const struct of_device_id dwc2_of_match_table[] = { .data = dwc2_set_stm32mp15_hsotg_params }, { .compatible = "intel,socfpga-agilex-hsotg", .data = dwc2_set_socfpga_agilex_params }, + { .compatible = "apple,dwc2", + .data = dwc2_set_apple_silicon_params }, {}, }; MODULE_DEVICE_TABLE(of, dwc2_of_match_table); diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index a7a3fbaf7c29e3..717e5329eba8c5 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -321,6 +321,19 @@ config BACKLIGHT_APPLE_DWI To compile this driver as a module, choose M here: the module will be called apple_dwi_bl. +config BACKLIGHT_APPLE_PMIC + tristate "Backlight Driver for Apple PMICs using WLED" + depends on I2C && (ARCH_APPLE || COMPILE_TEST) + select REGMAP + select MFD_SIMPLE_MFD_I2C + help + Say Y here to enable driver for backlights connected to WLED output + of Apple Anya/Arabela/Aria/August PMICs, as used on some Apple + iPads. + + To compile this driver as a module, choose M here: the module will + be called apple_pmic_bl. + config BACKLIGHT_QCOM_WLED tristate "Qualcomm PMIC WLED Driver" select REGMAP diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 794820a98ed492..daad32891393c5 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_BACKLIGHT_ADP8860) += adp8860_bl.o obj-$(CONFIG_BACKLIGHT_ADP8870) += adp8870_bl.o obj-$(CONFIG_BACKLIGHT_APPLE) += apple_bl.o obj-$(CONFIG_BACKLIGHT_APPLE_DWI) += apple_dwi_bl.o +obj-$(CONFIG_BACKLIGHT_APPLE_PMIC) += apple_pmic_bl.o obj-$(CONFIG_BACKLIGHT_AS3711) += as3711_bl.o obj-$(CONFIG_BACKLIGHT_AW99706) += aw99706.o obj-$(CONFIG_BACKLIGHT_BD6107) += bd6107.o diff --git a/drivers/video/backlight/apple_pmic_bl.c b/drivers/video/backlight/apple_pmic_bl.c new file mode 100644 index 00000000000000..64d47251282dc2 --- /dev/null +++ b/drivers/video/backlight/apple_pmic_bl.c @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* + * Apple PMIC Backlight Driver + * + * Copyright (c) 2025 Nick Chan + */ + +#include +#include +#include +#include +#include +#include +#include + +#define APPLE_PMIC_BL_MAX_BRIGHTNESS 2047 + +enum apple_pmic_type { + PMIC_TYPE_ANYA, + PMIC_TYPE_ARIA +}; + +struct apple_pmic_bl { + struct regmap *regmap; + u32 base; + enum apple_pmic_type type; +}; + +static int apple_pmic_bl_update_status(struct backlight_device *bl) +{ + struct apple_pmic_bl *data = bl_get_data(bl); + + int brightness = backlight_get_brightness(bl); + + u8 cmd[2]; + + switch (data->type) { + case PMIC_TYPE_ANYA: + cmd[0] = (brightness >> 3) & 0xff; + cmd[1] = brightness & 0x7; + break; + case PMIC_TYPE_ARIA: + cmd[0] = brightness & 0xff; + cmd[1] = (brightness >> 8) & 0x7; + break; + } + + return regmap_bulk_write(data->regmap, data->base, cmd, 2); +} + +static int apple_pmic_bl_get_brightness(struct backlight_device *bl) +{ + struct apple_pmic_bl *data = bl_get_data(bl); + + u8 cmd[2]; + + int ret = regmap_bulk_read(data->regmap, data->base, &cmd, 2); + + if (ret) + return ret; + + switch (data->type) { + case PMIC_TYPE_ANYA: + return (cmd[0] << 3) | (cmd[1] & 7); + case PMIC_TYPE_ARIA: + return ((cmd[1] & 7) << 8) | (cmd[0] & 0xff); + } +} + +static const struct backlight_ops apple_pmic_bl_ops = { + .options = BL_CORE_SUSPENDRESUME, + .get_brightness = apple_pmic_bl_get_brightness, + .update_status = apple_pmic_bl_update_status +}; + +static int apple_pmic_bl_probe(struct platform_device *dev) +{ + struct backlight_device *bl; + struct backlight_properties props; + struct apple_pmic_bl *data; + + data = devm_kzalloc(&dev->dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->regmap = dev_get_regmap(dev->dev.parent, NULL); + if (!data->regmap) + return -ENODEV; + + if (of_property_read_u32(dev->dev.of_node, "reg", &data->base)) + return -ENODEV; + + data->type = (enum apple_pmic_type)of_device_get_match_data(&dev->dev); + + memset(&props, 0, sizeof(struct backlight_properties)); + props.type = BACKLIGHT_RAW; + props.max_brightness = APPLE_PMIC_BL_MAX_BRIGHTNESS; + props.scale = BACKLIGHT_SCALE_LINEAR; + + bl = devm_backlight_device_register(&dev->dev, dev->name, &dev->dev, + data, &apple_pmic_bl_ops, &props); + if (IS_ERR(bl)) + return PTR_ERR(bl); + + platform_set_drvdata(dev, data); + + bl->props.brightness = apple_pmic_bl_get_brightness(bl); + + return 0; +} + +static const struct of_device_id apple_pmic_bl_of_match[] = { + { .compatible = "apple,anya-pmic-bl", .data = (void*)PMIC_TYPE_ANYA }, + { .compatible = "apple,aria-pmic-bl", .data = (void*)PMIC_TYPE_ARIA }, + {}, +}; + +MODULE_DEVICE_TABLE(of, apple_pmic_bl_of_match); + +static struct platform_driver apple_pmic_bl_driver = { + .driver = { + .name = "apple-pmic-bl", + .of_match_table = apple_pmic_bl_of_match + }, + .probe = apple_pmic_bl_probe, +}; + +module_platform_driver(apple_pmic_bl_driver); + +MODULE_DESCRIPTION("Apple PMIC Backlight Driver"); +MODULE_AUTHOR("Nick Chan "); +MODULE_LICENSE("Dual MIT/GPL"); diff --git a/include/linux/mfd/macsmc.h b/include/linux/mfd/macsmc.h index cc09ecce0df742..1a462baae0e38a 100644 --- a/include/linux/mfd/macsmc.h +++ b/include/linux/mfd/macsmc.h @@ -93,6 +93,7 @@ enum apple_smc_boot_stage { * @sram: Pointer to SRAM resource * @sram_base: SRAM base address * @shmem: RTKit shared memory structure for SRAM + * @ep: SMC endpoint number * @msg_id: Current message id for commands, will be incremented for each command * @atomic_mode: Flag set when atomic mode is entered * @atomic_pending: Flag indicating pending atomic command @@ -118,6 +119,7 @@ struct apple_smc { struct resource *sram; void __iomem *sram_base; struct apple_rtkit_shmem shmem; + u8 ep; unsigned int msg_id; diff --git a/include/linux/of_address.h b/include/linux/of_address.h index 0cff9036539168..37f59a521ab2e9 100644 --- a/include/linux/of_address.h +++ b/include/linux/of_address.h @@ -174,6 +174,7 @@ static inline void __iomem *of_iomap(struct device_node *device, int index) return NULL; } #endif +#define of_dma_range_parser_init of_pci_dma_range_parser_init #define of_range_parser_init of_pci_range_parser_init static inline const __be32 *of_get_address(struct device_node *dev, int index, diff --git a/include/linux/soc/apple/rtkit.h b/include/linux/soc/apple/rtkit.h index bda3c528b51553..dde8abe99d00a1 100644 --- a/include/linux/soc/apple/rtkit.h +++ b/include/linux/soc/apple/rtkit.h @@ -179,4 +179,14 @@ int apple_rtkit_send_message(struct apple_rtkit *rtk, u8 ep, u64 message, */ int apple_rtkit_poll(struct apple_rtkit *rtk); +/* + * Convert an endpoint number relative to start of app endpoint to an absolute + * endpoint number. + * + * Returns the endpoint number on success, 0 on failure. + * + * @rtk: RTKit reference + */ +u8 apple_rtkit_app_ep_to_ep(struct apple_rtkit *rtk, u8 app_ep); + #endif /* _LINUX_APPLE_RTKIT_H_ */ diff --git a/tools/perf/pmu-events/arch/arm64/apple/a10/core-imp-def.json b/tools/perf/pmu-events/arch/arm64/apple/a10/core-imp-def.json new file mode 100644 index 00000000000000..b3b783d394abea --- /dev/null +++ b/tools/perf/pmu-events/arch/arm64/apple/a10/core-imp-def.json @@ -0,0 +1,320 @@ +[ + { + "PublicDescription": "Retired indirect branch instructions including indirect calls", + "EventCode": "0x93", + "EventName": "INST_BRANCH_INDIR", + "BriefDescription": "Retired indirect branch instructions including indirect calls" + }, + { + "PublicDescription": "Retired indirect branch instructions including calls and returns that mispredicted", + "EventCode": "0xc6", + "EventName": "BRANCH_INDIR_MISPRED_NONSPEC", + "BriefDescription": "Retired indirect branch instructions including calls and returns that mispredicted" + }, + { + "PublicDescription": "Mapped Advanced SIMD and FP Unit \u03bcops", + "EventCode": "0x7e", + "EventName": "MAP_SIMD_UOP", + "BriefDescription": "Mapped Advanced SIMD and FP Unit \u03bcops" + }, + { + "PublicDescription": "Retired branch instructions including calls and returns", + "EventCode": "0x8d", + "EventName": "INST_BRANCH", + "BriefDescription": "Retired branch instructions including calls and returns" + }, + { + "PublicDescription": "Retired subroutine return instructions", + "EventCode": "0x8f", + "EventName": "INST_BRANCH_RET", + "BriefDescription": "Retired subroutine return instructions" + }, + { + "PublicDescription": "Retired core store \u03bcops that triggered memory order violations with core load \u03bcops", + "EventCode": "0xc4", + "EventName": "ST_MEMORY_ORDER_VIOLATION_NONSPEC", + "BriefDescription": "Retired core store \u03bcops that triggered memory order violations with core load \u03bcops" + }, + { + "PublicDescription": "Mapped Load and Store Unit \u03bcops, including GPR to vector register converts; includes all instructions sent to the SME engine because they are processed through the Store Unit", + "EventCode": "0x7d", + "EventName": "MAP_LDST_UOP", + "BriefDescription": "Mapped Load and Store Unit \u03bcops" + }, + { + "PublicDescription": "\u03bcops that flowed through the Load Unit", + "EventCode": "0xa6", + "EventName": "LD_UNIT_UOP", + "BriefDescription": "\u03bcops that flowed through the Load Unit" + }, + { + "PublicDescription": "Retired branch instructions including calls and returns that mispredicted", + "EventCode": "0xcb", + "EventName": "BRANCH_MISPRED_NONSPEC", + "BriefDescription": "Retired branch instructions including calls and returns that mispredicted" + }, + { + "PublicDescription": "Retired barrier instructions", + "EventCode": "0x9c", + "EventName": "INST_BARRIER", + "BriefDescription": "Retired barrier instructions" + }, + { + "PublicDescription": "Retired return instructions that mispredicted", + "EventCode": "0xc8", + "EventName": "BRANCH_RET_INDIR_MISPRED_NONSPEC", + "BriefDescription": "Retired return instructions that mispredicted" + }, + { + "PublicDescription": "Cycles while rewinding the Map Unit due to flush and restart", + "EventCode": "0x75", + "EventName": "MAP_REWIND", + "BriefDescription": "Cycles while rewinding the Map Unit due to flush and restart" + }, + { + "PublicDescription": "Cycles while the Map Unit was stalled for any reason", + "EventCode": "0x76", + "EventName": "MAP_STALL", + "BriefDescription": "Cycles while the Map Unit was stalled for any reason" + }, + { + "PublicDescription": "Retired load Advanced SIMD and FP Unit instructions", + "EventCode": "0x98", + "EventName": "INST_SIMD_LD", + "BriefDescription": "Retired load Advanced SIMD and FP Unit instructions" + }, + { + "PublicDescription": "Retired indirect call instructions mispredicted", + "EventCode": "0xca", + "EventName": "BRANCH_CALL_INDIR_MISPRED_NONSPEC", + "BriefDescription": "Retired indirect call instructions mispredicted" + }, + { + "PublicDescription": "Stores that missed the L1 Data Cache", + "EventCode": "0xa2", + "EventName": "L1D_CACHE_MISS_ST", + "BriefDescription": "Stores that missed the L1 Data Cache" + }, + { + "PublicDescription": "Retired A32 instructions", + "EventCode": "0x8a", + "EventName": "INST_A32", + "BriefDescription": "Retired A32 instructions" + }, + { + "PublicDescription": "Retired T32 instructions", + "EventCode": "0x8b", + "EventName": "INST_T32", + "BriefDescription": "Retired T32 instructions" + }, + { + "PublicDescription": "All retired instructions", + "EventCode": "0x8c", + "EventName": "INST_ALL", + "BriefDescription": "All retired instructions" + }, + { + "PublicDescription": "Store \u03bcops that executed with non-temporal hint; includes SSVE/SME loads because they utilize the Store Unit", + "EventCode": "0xe5", + "EventName": "ST_NT_UOP", + "BriefDescription": "Store \u03bcops that executed with non-temporal hint; includes SSVE/SME loads because they utilize the Store Unit" + }, + { + "PublicDescription": "Pipeline flush and restarts that were not due to branch mispredictions or memory order violations", + "EventCode": "0x84", + "EventName": "FLUSH_RESTART_OTHER_NONSPEC", + "BriefDescription": "Pipeline flush and restarts that were not due to branch mispredictions or memory order violations" + }, + { + "PublicDescription": "Cycles while the core was active", + "EventCode": "0x2", + "EventName": "CORE_ACTIVE_CYCLE", + "BriefDescription": "Cycles while the core was active" + }, + { + "PublicDescription": "Retired non-branch and non-load/store Integer Unit instructions", + "EventCode": "0x97", + "EventName": "INST_INT_ALU", + "BriefDescription": "Retired non-branch and non-load/store Integer Unit instructions" + }, + { + "PublicDescription": "Atomic or exclusive instruction successfully completed *For exclusives, incorrectly undercounts for exclusives when the cache line is initially found in shared state, however counts correctly for atomics", + "EventCode": "0xb3", + "EventName": "ATOMIC_OR_EXCLUSIVE_SUCC", + "BriefDescription": "Atomic or exclusive instruction successfully completed *For exclusives" + }, + { + "PublicDescription": "Retired load and store instructions; does not count DC ZVA (Data Cache Zero by VA).", + "EventCode": "0x9b", + "EventName": "INST_LDST", + "BriefDescription": "Retired load and store instructions; does not count DC ZVA" + }, + { + "PublicDescription": "Load and store \u03bcops that crossed a 64B boundary", + "EventCode": "0xb1", + "EventName": "LDST_X64_UOP", + "BriefDescription": "Load and store \u03bcops that crossed a 64B boundary" + }, + { + "PublicDescription": "Cycles while the Map Unit was not stalled and Decode Unit did not send any \u03bcops", + "EventCode": "0xd6", + "EventName": "MAP_DISPATCH_BUBBLE", + "BriefDescription": "Cycles while the Map Unit was not stalled and Decode Unit did not send any \u03bcops" + }, + { + "PublicDescription": "Retired non-load/store Advanced SIMD and FP Unit instructions", + "EventCode": "0x9a", + "EventName": "INST_SIMD_ALU", + "BriefDescription": "Retired non-load/store Advanced SIMD and FP Unit instructions" + }, + { + "PublicDescription": "Retired taken branch instructions", + "EventCode": "0x90", + "EventName": "INST_BRANCH_TAKEN", + "BriefDescription": "Retired taken branch instructions" + }, + { + "PublicDescription": "Retired store Integer Unit instructions; does not count DC ZVA (Data Cache Zero by VA).", + "EventCode": "0x96", + "EventName": "INST_INT_ST", + "BriefDescription": "Retired store Integer Unit instructions; does not count DC ZVA" + }, + { + "PublicDescription": "Demand instruction fetches that missed in the L1 Instruction TLB", + "EventCode": "0xd4", + "EventName": "L1I_TLB_MISS_DEMAND", + "BriefDescription": "Demand instruction fetches that missed in the L1 Instruction TLB" + }, + { + "PublicDescription": "Retired loads and stores that missed in the L1 Data TLB", + "EventCode": "0xc1", + "EventName": "L1D_TLB_MISS_NONSPEC", + "BriefDescription": "Retired loads and stores that missed in the L1 Data TLB" + }, + { + "PublicDescription": "Mapped Integer Unit \u03bcops", + "EventCode": "0x7c", + "EventName": "MAP_INT_UOP", + "BriefDescription": "Mapped Integer Unit \u03bcops" + }, + { + "PublicDescription": "Retired conditional branch instructions B.cond *On M3 and prior, only counts only instructions. On M4 CBZCBNZTBZTBNZ and following, adds / / / instructions to form the complete set of conditional branch instructions", + "EventCode": "0x94", + "EventName": "INST_BRANCH_COND", + "BriefDescription": "Retired conditional branch instructions B" + }, + { + "PublicDescription": "Retired load Integer Unit instructions", + "EventCode": "0x95", + "EventName": "INST_INT_LD", + "BriefDescription": "Retired load Integer Unit instructions" + }, + { + "PublicDescription": "Load and store accesses that missed the L1 Data TLB", + "EventCode": "0xa1", + "EventName": "L1D_TLB_MISS", + "BriefDescription": "Load and store accesses that missed the L1 Data TLB" + }, + { + "PublicDescription": "\u03bcops that flowed through the Store Unit", + "EventCode": "0xa7", + "EventName": "ST_UNIT_UOP", + "BriefDescription": "\u03bcops that flowed through the Store Unit" + }, + { + "PublicDescription": "All retired \u03bcops", + "EventCode": "0x1", + "EventName": "RETIRE_UOP", + "BriefDescription": "All retired \u03bcops" + }, + { + "PublicDescription": "Retired loads that missed in the L1 Data Cache", + "EventCode": "0xbf", + "EventName": "L1D_CACHE_MISS_LD_NONSPEC", + "BriefDescription": "Retired loads that missed in the L1 Data Cache" + }, + { + "PublicDescription": "Demand instruction fetches that missed in the L1 Instruction Cache", + "EventCode": "0xdb", + "EventName": "L1I_CACHE_MISS_DEMAND", + "BriefDescription": "Demand instruction fetches that missed in the L1 Instruction Cache" + }, + { + "PublicDescription": "\u03bcops issued by the scheduler to any execution unit", + "EventCode": "0x52", + "EventName": "SCHEDULE_UOP", + "BriefDescription": "\u03bcops issued by the scheduler to any execution unit" + }, + { + "PublicDescription": "Dirty cache lines written back from the L1D Cache toward the Shared L2 Cache", + "EventCode": "0xa8", + "EventName": "L1D_CACHE_WRITEBACK", + "BriefDescription": "Dirty cache lines written back from the L1D Cache toward the Shared L2 Cache" + }, + { + "PublicDescription": "Fetch Unit internal restarts for any reason. Does not include branch mispredicts", + "EventCode": "0xde", + "EventName": "FETCH_RESTART", + "BriefDescription": "Fetch Unit internal restarts for any reason" + }, + { + "PublicDescription": "Retired subroutine call instructions", + "EventCode": "0x8e", + "EventName": "INST_BRANCH_CALL", + "BriefDescription": "Retired subroutine call instructions" + }, + { + "PublicDescription": "Atomic or exclusive instruction failed due to contention *For exclusives, incorrectly undercounts for exclusives when the cache line is initially found in shared state, however counts correctly for atomics", + "EventCode": "0xb4", + "EventName": "ATOMIC_OR_EXCLUSIVE_FAIL", + "BriefDescription": "Atomic or exclusive instruction failed due to contention *For exclusives" + }, + { + "PublicDescription": "Retired conditional branch instructions that mispredicted", + "EventCode": "0xc5", + "EventName": "BRANCH_COND_MISPRED_NONSPEC", + "BriefDescription": "Retired conditional branch instructions that mispredicted" + }, + { + "PublicDescription": "Loads and stores that missed in the L2 TLB", + "EventCode": "0xb", + "EventName": "L2_TLB_MISS_DATA", + "BriefDescription": "Loads and stores that missed in the L2 TLB" + }, + { + "PublicDescription": "Loads that missed the L1 Data Cache", + "EventCode": "0xa3", + "EventName": "L1D_CACHE_MISS_LD", + "BriefDescription": "Loads that missed the L1 Data Cache" + }, + { + "PublicDescription": "Instruction fetches that missed in the L2 TLB", + "EventCode": "0xa", + "EventName": "L2_TLB_MISS_INSTRUCTION", + "BriefDescription": "Instruction fetches that missed in the L2 TLB" + }, + { + "PublicDescription": "Load and store accesses to the L1 Data TLB", + "EventCode": "0xa0", + "EventName": "L1D_TLB_ACCESS", + "BriefDescription": "Load and store accesses to the L1 Data TLB" + }, + { + "PublicDescription": "Load \u03bcops that executed with non-temporal hint; excludes SSVE/SME loads because they utilize the Store Unit", + "EventCode": "0xe6", + "EventName": "LD_NT_UOP", + "BriefDescription": "Load \u03bcops that executed with non-temporal hint; excludes SSVE/SME loads because they utilize the Store Unit" + }, + { + "PublicDescription": "Retired stores that missed in the L1 Data Cache", + "EventCode": "0xc0", + "EventName": "L1D_CACHE_MISS_ST_NONSPEC", + "BriefDescription": "Retired stores that missed in the L1 Data Cache" + }, + { + "PublicDescription": "Retired store Advanced SIMD and FP Unit instructions", + "EventCode": "0x99", + "EventName": "INST_SIMD_ST", + "BriefDescription": "Retired store Advanced SIMD and FP Unit instructions" + } +] diff --git a/tools/perf/pmu-events/arch/arm64/apple/a11/core-imp-def.json b/tools/perf/pmu-events/arch/arm64/apple/a11/core-imp-def.json new file mode 100644 index 00000000000000..7b480d19b89ec9 --- /dev/null +++ b/tools/perf/pmu-events/arch/arm64/apple/a11/core-imp-def.json @@ -0,0 +1,308 @@ +[ + { + "PublicDescription": "Retired indirect branch instructions including indirect calls", + "EventCode": "0x93", + "EventName": "INST_BRANCH_INDIR", + "BriefDescription": "Retired indirect branch instructions including indirect calls" + }, + { + "PublicDescription": "Retired indirect branch instructions including calls and returns that mispredicted", + "EventCode": "0xc6", + "EventName": "BRANCH_INDIR_MISPRED_NONSPEC", + "BriefDescription": "Retired indirect branch instructions including calls and returns that mispredicted" + }, + { + "PublicDescription": "Mapped Advanced SIMD and FP Unit \u03bcops", + "EventCode": "0x7e", + "EventName": "MAP_SIMD_UOP", + "BriefDescription": "Mapped Advanced SIMD and FP Unit \u03bcops" + }, + { + "PublicDescription": "Retired branch instructions including calls and returns", + "EventCode": "0x8d", + "EventName": "INST_BRANCH", + "BriefDescription": "Retired branch instructions including calls and returns" + }, + { + "PublicDescription": "Retired subroutine return instructions", + "EventCode": "0x8f", + "EventName": "INST_BRANCH_RET", + "BriefDescription": "Retired subroutine return instructions" + }, + { + "PublicDescription": "Retired core store \u03bcops that triggered memory order violations with core load \u03bcops", + "EventCode": "0xc4", + "EventName": "ST_MEMORY_ORDER_VIOLATION_NONSPEC", + "BriefDescription": "Retired core store \u03bcops that triggered memory order violations with core load \u03bcops" + }, + { + "PublicDescription": "Mapped Load and Store Unit \u03bcops, including GPR to vector register converts; includes all instructions sent to the SME engine because they are processed through the Store Unit", + "EventCode": "0x7d", + "EventName": "MAP_LDST_UOP", + "BriefDescription": "Mapped Load and Store Unit \u03bcops" + }, + { + "PublicDescription": "\u03bcops that flowed through the Load Unit", + "EventCode": "0xa6", + "EventName": "LD_UNIT_UOP", + "BriefDescription": "\u03bcops that flowed through the Load Unit" + }, + { + "PublicDescription": "Retired branch instructions including calls and returns that mispredicted", + "EventCode": "0xcb", + "EventName": "BRANCH_MISPRED_NONSPEC", + "BriefDescription": "Retired branch instructions including calls and returns that mispredicted" + }, + { + "PublicDescription": "Retired barrier instructions", + "EventCode": "0x9c", + "EventName": "INST_BARRIER", + "BriefDescription": "Retired barrier instructions" + }, + { + "PublicDescription": "Retired return instructions that mispredicted", + "EventCode": "0xc8", + "EventName": "BRANCH_RET_INDIR_MISPRED_NONSPEC", + "BriefDescription": "Retired return instructions that mispredicted" + }, + { + "PublicDescription": "Cycles while rewinding the Map Unit due to flush and restart", + "EventCode": "0x75", + "EventName": "MAP_REWIND", + "BriefDescription": "Cycles while rewinding the Map Unit due to flush and restart" + }, + { + "PublicDescription": "Cycles while the Map Unit was stalled for any reason", + "EventCode": "0x76", + "EventName": "MAP_STALL", + "BriefDescription": "Cycles while the Map Unit was stalled for any reason" + }, + { + "PublicDescription": "Retired load Advanced SIMD and FP Unit instructions", + "EventCode": "0x98", + "EventName": "INST_SIMD_LD", + "BriefDescription": "Retired load Advanced SIMD and FP Unit instructions" + }, + { + "PublicDescription": "Retired indirect call instructions mispredicted", + "EventCode": "0xca", + "EventName": "BRANCH_CALL_INDIR_MISPRED_NONSPEC", + "BriefDescription": "Retired indirect call instructions mispredicted" + }, + { + "PublicDescription": "Stores that missed the L1 Data Cache", + "EventCode": "0xa2", + "EventName": "L1D_CACHE_MISS_ST", + "BriefDescription": "Stores that missed the L1 Data Cache" + }, + { + "PublicDescription": "All retired instructions", + "EventCode": "0x8c", + "EventName": "INST_ALL", + "BriefDescription": "All retired instructions" + }, + { + "PublicDescription": "Store \u03bcops that executed with non-temporal hint; includes SSVE/SME loads because they utilize the Store Unit", + "EventCode": "0xe5", + "EventName": "ST_NT_UOP", + "BriefDescription": "Store \u03bcops that executed with non-temporal hint; includes SSVE/SME loads because they utilize the Store Unit" + }, + { + "PublicDescription": "Pipeline flush and restarts that were not due to branch mispredictions or memory order violations", + "EventCode": "0x84", + "EventName": "FLUSH_RESTART_OTHER_NONSPEC", + "BriefDescription": "Pipeline flush and restarts that were not due to branch mispredictions or memory order violations" + }, + { + "PublicDescription": "Cycles while the core was active", + "EventCode": "0x2", + "EventName": "CORE_ACTIVE_CYCLE", + "BriefDescription": "Cycles while the core was active" + }, + { + "PublicDescription": "Retired non-branch and non-load/store Integer Unit instructions", + "EventCode": "0x97", + "EventName": "INST_INT_ALU", + "BriefDescription": "Retired non-branch and non-load/store Integer Unit instructions" + }, + { + "PublicDescription": "Atomic or exclusive instruction successfully completed *For exclusives, incorrectly undercounts for exclusives when the cache line is initially found in shared state, however counts correctly for atomics", + "EventCode": "0xb3", + "EventName": "ATOMIC_OR_EXCLUSIVE_SUCC", + "BriefDescription": "Atomic or exclusive instruction successfully completed *For exclusives" + }, + { + "PublicDescription": "Retired load and store instructions; does not count DC ZVA (Data Cache Zero by VA).", + "EventCode": "0x9b", + "EventName": "INST_LDST", + "BriefDescription": "Retired load and store instructions; does not count DC ZVA" + }, + { + "PublicDescription": "Load and store \u03bcops that crossed a 64B boundary", + "EventCode": "0xb1", + "EventName": "LDST_X64_UOP", + "BriefDescription": "Load and store \u03bcops that crossed a 64B boundary" + }, + { + "PublicDescription": "Cycles while the Map Unit was not stalled and Decode Unit did not send any \u03bcops", + "EventCode": "0xd6", + "EventName": "MAP_DISPATCH_BUBBLE", + "BriefDescription": "Cycles while the Map Unit was not stalled and Decode Unit did not send any \u03bcops" + }, + { + "PublicDescription": "Retired non-load/store Advanced SIMD and FP Unit instructions", + "EventCode": "0x9a", + "EventName": "INST_SIMD_ALU", + "BriefDescription": "Retired non-load/store Advanced SIMD and FP Unit instructions" + }, + { + "PublicDescription": "Retired taken branch instructions", + "EventCode": "0x90", + "EventName": "INST_BRANCH_TAKEN", + "BriefDescription": "Retired taken branch instructions" + }, + { + "PublicDescription": "Retired store Integer Unit instructions; does not count DC ZVA (Data Cache Zero by VA).", + "EventCode": "0x96", + "EventName": "INST_INT_ST", + "BriefDescription": "Retired store Integer Unit instructions; does not count DC ZVA" + }, + { + "PublicDescription": "Demand instruction fetches that missed in the L1 Instruction TLB", + "EventCode": "0xd4", + "EventName": "L1I_TLB_MISS_DEMAND", + "BriefDescription": "Demand instruction fetches that missed in the L1 Instruction TLB" + }, + { + "PublicDescription": "Retired loads and stores that missed in the L1 Data TLB", + "EventCode": "0xc1", + "EventName": "L1D_TLB_MISS_NONSPEC", + "BriefDescription": "Retired loads and stores that missed in the L1 Data TLB" + }, + { + "PublicDescription": "Mapped Integer Unit \u03bcops", + "EventCode": "0x7c", + "EventName": "MAP_INT_UOP", + "BriefDescription": "Mapped Integer Unit \u03bcops" + }, + { + "PublicDescription": "Retired conditional branch instructions (counts onyly B.cond)", + "EventCode": "0x94", + "EventName": "INST_BRANCH_COND", + "BriefDescription": "Retired conditional branch instructions (counts only B.cond)" + }, + { + "PublicDescription": "Retired load Integer Unit instructions", + "EventCode": "0x95", + "EventName": "INST_INT_LD", + "BriefDescription": "Retired load Integer Unit instructions" + }, + { + "PublicDescription": "Load and store accesses that missed the L1 Data TLB", + "EventCode": "0xa1", + "EventName": "L1D_TLB_MISS", + "BriefDescription": "Load and store accesses that missed the L1 Data TLB" + }, + { + "PublicDescription": "\u03bcops that flowed through the Store Unit", + "EventCode": "0xa7", + "EventName": "ST_UNIT_UOP", + "BriefDescription": "\u03bcops that flowed through the Store Unit" + }, + { + "PublicDescription": "All retired \u03bcops", + "EventCode": "0x1", + "EventName": "RETIRE_UOP", + "BriefDescription": "All retired \u03bcops" + }, + { + "PublicDescription": "Retired loads that missed in the L1 Data Cache", + "EventCode": "0xbf", + "EventName": "L1D_CACHE_MISS_LD_NONSPEC", + "BriefDescription": "Retired loads that missed in the L1 Data Cache" + }, + { + "PublicDescription": "Demand instruction fetches that missed in the L1 Instruction Cache", + "EventCode": "0xdb", + "EventName": "L1I_CACHE_MISS_DEMAND", + "BriefDescription": "Demand instruction fetches that missed in the L1 Instruction Cache" + }, + { + "PublicDescription": "\u03bcops issued by the scheduler to any execution unit", + "EventCode": "0x52", + "EventName": "SCHEDULE_UOP", + "BriefDescription": "\u03bcops issued by the scheduler to any execution unit" + }, + { + "PublicDescription": "Dirty cache lines written back from the L1D Cache toward the Shared L2 Cache", + "EventCode": "0xa8", + "EventName": "L1D_CACHE_WRITEBACK", + "BriefDescription": "Dirty cache lines written back from the L1D Cache toward the Shared L2 Cache" + }, + { + "PublicDescription": "Fetch Unit internal restarts for any reason. Does not include branch mispredicts", + "EventCode": "0xde", + "EventName": "FETCH_RESTART", + "BriefDescription": "Fetch Unit internal restarts for any reason" + }, + { + "PublicDescription": "Retired subroutine call instructions", + "EventCode": "0x8e", + "EventName": "INST_BRANCH_CALL", + "BriefDescription": "Retired subroutine call instructions" + }, + { + "PublicDescription": "Atomic or exclusive instruction failed due to contention *For exclusives, incorrectly undercounts for exclusives when the cache line is initially found in shared state, however counts correctly for atomics", + "EventCode": "0xb4", + "EventName": "ATOMIC_OR_EXCLUSIVE_FAIL", + "BriefDescription": "Atomic or exclusive instruction failed due to contention *For exclusives" + }, + { + "PublicDescription": "Retired conditional branch instructions that mispredicted", + "EventCode": "0xc5", + "EventName": "BRANCH_COND_MISPRED_NONSPEC", + "BriefDescription": "Retired conditional branch instructions that mispredicted" + }, + { + "PublicDescription": "Loads and stores that missed in the L2 TLB", + "EventCode": "0xb", + "EventName": "L2_TLB_MISS_DATA", + "BriefDescription": "Loads and stores that missed in the L2 TLB" + }, + { + "PublicDescription": "Loads that missed the L1 Data Cache", + "EventCode": "0xa3", + "EventName": "L1D_CACHE_MISS_LD", + "BriefDescription": "Loads that missed the L1 Data Cache" + }, + { + "PublicDescription": "Instruction fetches that missed in the L2 TLB", + "EventCode": "0xa", + "EventName": "L2_TLB_MISS_INSTRUCTION", + "BriefDescription": "Instruction fetches that missed in the L2 TLB" + }, + { + "PublicDescription": "Load and store accesses to the L1 Data TLB", + "EventCode": "0xa0", + "EventName": "L1D_TLB_ACCESS", + "BriefDescription": "Load and store accesses to the L1 Data TLB" + }, + { + "PublicDescription": "Load \u03bcops that executed with non-temporal hint; excludes SSVE/SME loads because they utilize the Store Unit", + "EventCode": "0xe6", + "EventName": "LD_NT_UOP", + "BriefDescription": "Load \u03bcops that executed with non-temporal hint; excludes SSVE/SME loads because they utilize the Store Unit" + }, + { + "PublicDescription": "Retired stores that missed in the L1 Data Cache", + "EventCode": "0xc0", + "EventName": "L1D_CACHE_MISS_ST_NONSPEC", + "BriefDescription": "Retired stores that missed in the L1 Data Cache" + }, + { + "PublicDescription": "Retired store Advanced SIMD and FP Unit instructions", + "EventCode": "0x99", + "EventName": "INST_SIMD_ST", + "BriefDescription": "Retired store Advanced SIMD and FP Unit instructions" + } +] diff --git a/tools/perf/pmu-events/arch/arm64/apple/a7/core-imp-def.json b/tools/perf/pmu-events/arch/arm64/apple/a7/core-imp-def.json new file mode 100644 index 00000000000000..d55771f434a1b4 --- /dev/null +++ b/tools/perf/pmu-events/arch/arm64/apple/a7/core-imp-def.json @@ -0,0 +1,254 @@ +[ + { + "PublicDescription": "All retired instructions", + "EventCode": "0x00", + "EventName": "INST_ALL", + "BriefDescription": "All retired instructions" + }, + { + "PublicDescription": "Cycles while the core was active", + "EventCode": "0x2", + "EventName": "CORE_ACTIVE_CYCLE", + "BriefDescription": "Cycles while the core was active" + }, + { + "PublicDescription": "Retired store Integer Unit instructions; does not count DC ZVA (Data Cache Zero by VA).", + "EventCode": "0x84", + "EventName": "INST_INT_ST", + "BriefDescription": "Retired store Integer Unit instructions; does not count DC ZVA" + }, + { + "PublicDescription": "Retired conditional branch instructions that mispredicted", + "EventCode": "0xba", + "EventName": "BRANCH_COND_MISPRED_NONSPEC", + "BriefDescription": "Retired conditional branch instructions that mispredicted" + }, + { + "PublicDescription": "Loads and stores that missed in the L2 TLB", + "EventCode": "0x11", + "EventName": "L2_TLB_MISS_DATA", + "BriefDescription": "Loads and stores that missed in the L2 TLB" + }, + { + "PublicDescription": "Retired subroutine return instructions", + "EventCode": "0x7d", + "EventName": "INST_BRANCH_RET", + "BriefDescription": "Retired subroutine return instructions" + }, + { + "PublicDescription": "\u03bcops that flowed through the Load Unit", + "EventCode": "0x9c", + "EventName": "LD_UNIT_UOP", + "BriefDescription": "\u03bcops that flowed through the Load Unit" + }, + { + "PublicDescription": "Retired branch instructions including calls and returns that mispredicted", + "EventCode": "0xc0", + "EventName": "BRANCH_MISPRED_NONSPEC", + "BriefDescription": "Retired branch instructions including calls and returns that mispredicted" + }, + { + "PublicDescription": "Demand instruction fetches that missed in the L1 Instruction TLB", + "EventCode": "0xcf", + "EventName": "L1I_TLB_MISS_DEMAND", + "BriefDescription": "Demand instruction fetches that missed in the L1 Instruction TLB" + }, + { + "PublicDescription": "Load and store \u03bcops that crossed a 64B boundary", + "EventCode": "0xa7", + "EventName": "LDST_X64_UOP", + "BriefDescription": "Load and store \u03bcops that crossed a 64B boundary" + }, + { + "PublicDescription": "Retired conditional branch instructions (counts only B.cond)", + "EventCode": "0x82", + "EventName": "INST_BRANCH_COND", + "BriefDescription": "Retired conditional branch instructions (counts only B.cond)" + }, + { + "PublicDescription": "Load and store accesses that missed the L1 Data TLB", + "EventCode": "0x97", + "EventName": "L1D_TLB_MISS", + "BriefDescription": "Load and store accesses that missed the L1 Data TLB" + }, + { + "PublicDescription": "Retired loads that missed in the L1 Data Cache", + "EventCode": "0xb4", + "EventName": "L1D_CACHE_MISS_LD_NONSPEC", + "BriefDescription": "Retired loads that missed in the L1 Data Cache" + }, + { + "PublicDescription": "\u03bcops that flowed through the Store Unit", + "EventCode": "0x9d", + "EventName": "ST_UNIT_UOP", + "BriefDescription": "\u03bcops that flowed through the Store Unit" + }, + { + "PublicDescription": "Retired stores that missed in the L1 Data Cache", + "EventCode": "0xb5", + "EventName": "L1D_CACHE_MISS_ST_NONSPEC", + "BriefDescription": "Retired stores that missed in the L1 Data Cache" + }, + { + "PublicDescription": "Cycles while rewinding the Map Unit due to flush and restart", + "EventCode": "0x61", + "EventName": "MAP_REWIND", + "BriefDescription": "Cycles while rewinding the Map Unit due to flush and restart" + }, + { + "PublicDescription": "Retired indirect branch instructions including indirect calls", + "EventCode": "0x81", + "EventName": "INST_BRANCH_INDIR", + "BriefDescription": "Retired indirect branch instructions including indirect calls" + }, + { + "PublicDescription": "Retired branch instructions including calls and returns", + "EventCode": "0x7b", + "EventName": "INST_BRANCH", + "BriefDescription": "Retired branch instructions including calls and returns" + }, + { + "PublicDescription": "Retired return instructions that mispredicted", + "EventCode": "0xbd", + "EventName": "BRANCH_RET_INDIR_MISPRED_NONSPEC", + "BriefDescription": "Retired return instructions that mispredicted" + }, + { + "PublicDescription": "Cycles while the Map Unit was stalled for any reason", + "EventCode": "0x62", + "EventName": "MAP_STALL", + "BriefDescription": "Cycles while the Map Unit was stalled for any reason" + }, + { + "PublicDescription": "\u03bcops issued by the scheduler to any execution unit", + "EventCode": "0x58", + "EventName": "SCHEDULE_UOP", + "BriefDescription": "\u03bcops issued by the scheduler to any execution unit" + }, + { + "PublicDescription": "Retired load and store instructions; does not count DC ZVA (Data Cache Zero by VA).", + "EventCode": "0x89", + "EventName": "INST_LDST", + "BriefDescription": "Retired load and store instructions; does not count DC ZVA" + }, + { + "PublicDescription": "Retired indirect call instructions mispredicted", + "EventCode": "0xbf", + "EventName": "BRANCH_CALL_INDIR_MISPRED_NONSPEC", + "BriefDescription": "Retired indirect call instructions mispredicted" + }, + { + "PublicDescription": "Retired load Integer Unit instructions", + "EventCode": "0x83", + "EventName": "INST_INT_LD", + "BriefDescription": "Retired load Integer Unit instructions" + }, + { + "PublicDescription": "Instruction fetches that missed in the L2 TLB", + "EventCode": "0x10", + "EventName": "L2_TLB_MISS_INSTRUCTION", + "BriefDescription": "Instruction fetches that missed in the L2 TLB" + }, + { + "PublicDescription": "Retired load Advanced SIMD and FP Unit instructions", + "EventCode": "0x86", + "EventName": "INST_SIMD_LD", + "BriefDescription": "Retired load Advanced SIMD and FP Unit instructions" + }, + { + "PublicDescription": "Retired A32 instructions", + "EventCode": "0x78", + "EventName": "INST_A32", + "BriefDescription": "Retired A32 instructions" + }, + { + "PublicDescription": "Retired T32 instructions", + "EventCode": "0x79", + "EventName": "INST_T32", + "BriefDescription": "Retired T32 instructions" + }, + { + "PublicDescription": "Retired A64 instructions", + "EventCode": "0x7a", + "EventName": "INST_A64", + "BriefDescription": "Retired A64 instructions" + }, + { + "PublicDescription": "Retired subroutine call instructions", + "EventCode": "0x7c", + "EventName": "INST_BRANCH_CALL", + "BriefDescription": "Retired subroutine call instructions" + }, + { + "PublicDescription": "Retired core store \u03bcops that triggered memory order violations with core load \u03bcops", + "EventCode": "0xb9", + "EventName": "ST_MEMORY_ORDER_VIOLATION_NONSPEC", + "BriefDescription": "Retired core store \u03bcops that triggered memory order violations with core load \u03bcops" + }, + { + "PublicDescription": "Retired non-load/store Advanced SIMD and FP Unit instructions", + "EventCode": "0x88", + "EventName": "INST_SIMD_ALU", + "BriefDescription": "Retired non-load/store Advanced SIMD and FP Unit instructions" + }, + { + "PublicDescription": "Retired indirect branch instructions including calls and returns that mispredicted", + "EventCode": "0xbb", + "EventName": "BRANCH_INDIR_MISPRED_NONSPEC", + "BriefDescription": "Retired indirect branch instructions including calls and returns that mispredicted" + }, + { + "PublicDescription": "Retired taken branch instructions", + "EventCode": "0x7e", + "EventName": "INST_BRANCH_TAKEN", + "BriefDescription": "Retired taken branch instructions" + }, + { + "PublicDescription": "Stores that missed the L1 Data Cache", + "EventCode": "0x98", + "EventName": "L1D_CACHE_MISS_ST", + "BriefDescription": "Stores that missed the L1 Data Cache" + }, + { + "PublicDescription": "Loads that missed the L1 Data Cache", + "EventCode": "0x99", + "EventName": "L1D_CACHE_MISS_LD", + "BriefDescription": "Loads that missed the L1 Data Cache" + }, + { + "PublicDescription": "Dirty cache lines written back from the L1D Cache toward the Shared L2 Cache", + "EventCode": "0x9e", + "EventName": "L1D_CACHE_WRITEBACK", + "BriefDescription": "Dirty cache lines written back from the L1D Cache toward the Shared L2 Cache" + }, + { + "PublicDescription": "Pipeline flush and restarts that were not due to branch mispredictions or memory order violations", + "EventCode": "0x6e", + "EventName": "FLUSH_RESTART_OTHER_NONSPEC", + "BriefDescription": "Pipeline flush and restarts that were not due to branch mispredictions or memory order violations" + }, + { + "PublicDescription": "Retired store Advanced SIMD and FP Unit instructions", + "EventCode": "0x87", + "EventName": "INST_SIMD_ST", + "BriefDescription": "Retired store Advanced SIMD and FP Unit instructions" + }, + { + "PublicDescription": "Retired non-branch and non-load/store Integer Unit instructions", + "EventCode": "0x85", + "EventName": "INST_INT_ALU", + "BriefDescription": "Retired non-branch and non-load/store Integer Unit instructions" + }, + { + "PublicDescription": "Load and store accesses to the L1 Data TLB", + "EventCode": "0x96", + "EventName": "L1D_TLB_ACCESS", + "BriefDescription": "Load and store accesses to the L1 Data TLB" + }, + { + "PublicDescription": "Retired loads and stores that missed in the L1 Data TLB", + "EventCode": "0xb6", + "EventName": "L1D_TLB_MISS_NONSPEC", + "BriefDescription": "Retired loads and stores that missed in the L1 Data TLB" + } +] diff --git a/tools/perf/pmu-events/arch/arm64/apple/a8/core-imp-def.json b/tools/perf/pmu-events/arch/arm64/apple/a8/core-imp-def.json new file mode 100644 index 00000000000000..349593ec6e714e --- /dev/null +++ b/tools/perf/pmu-events/arch/arm64/apple/a8/core-imp-def.json @@ -0,0 +1,272 @@ +[ + { + "PublicDescription": "Cycles while the core was active", + "EventCode": "0x2", + "EventName": "CORE_ACTIVE_CYCLE", + "BriefDescription": "Cycles while the core was active" + }, + { + "PublicDescription": "Retired store Integer Unit instructions; does not count DC ZVA (Data Cache Zero by VA).", + "EventCode": "0x96", + "EventName": "INST_INT_ST", + "BriefDescription": "Retired store Integer Unit instructions; does not count DC ZVA" + }, + { + "PublicDescription": "Retired conditional branch instructions that mispredicted", + "EventCode": "0xc5", + "EventName": "BRANCH_COND_MISPRED_NONSPEC", + "BriefDescription": "Retired conditional branch instructions that mispredicted" + }, + { + "PublicDescription": "Retired subroutine return instructions", + "EventCode": "0x8f", + "EventName": "INST_BRANCH_RET", + "BriefDescription": "Retired subroutine return instructions" + }, + { + "PublicDescription": "Loads and stores that missed in the L2 TLB", + "EventCode": "0xb", + "EventName": "L2_TLB_MISS_DATA", + "BriefDescription": "Loads and stores that missed in the L2 TLB" + }, + { + "PublicDescription": "\u03bcops that flowed through the Load Unit", + "EventCode": "0xa6", + "EventName": "LD_UNIT_UOP", + "BriefDescription": "\u03bcops that flowed through the Load Unit" + }, + { + "PublicDescription": "Retired branch instructions including calls and returns that mispredicted", + "EventCode": "0xcb", + "EventName": "BRANCH_MISPRED_NONSPEC", + "BriefDescription": "Retired branch instructions including calls and returns that mispredicted" + }, + { + "PublicDescription": "Demand instruction fetches that missed in the L1 Instruction TLB", + "EventCode": "0xd4", + "EventName": "L1I_TLB_MISS_DEMAND", + "BriefDescription": "Demand instruction fetches that missed in the L1 Instruction TLB" + }, + { + "PublicDescription": "Load and store \u03bcops that crossed a 64B boundary", + "EventCode": "0xb1", + "EventName": "LDST_X64_UOP", + "BriefDescription": "Load and store \u03bcops that crossed a 64B boundary" + }, + { + "PublicDescription": "Mapped Integer Unit \u03bcops", + "EventCode": "0x7b", + "EventName": "MAP_INT_UOP", + "BriefDescription": "Mapped Integer Unit \u03bcops" + }, + { + "PublicDescription": "Retired conditional branch instructions B.cond *On M3 and prior, only counts only instructions. On M4 CBZCBNZTBZTBNZ and following, adds / / / instructions to form the complete set of conditional branch instructions", + "EventCode": "0x94", + "EventName": "INST_BRANCH_COND", + "BriefDescription": "Retired conditional branch instructions B" + }, + { + "PublicDescription": "Load and store accesses that missed the L1 Data TLB", + "EventCode": "0xa1", + "EventName": "L1D_TLB_MISS", + "BriefDescription": "Load and store accesses that missed the L1 Data TLB" + }, + { + "PublicDescription": "Retired loads that missed in the L1 Data Cache", + "EventCode": "0xbf", + "EventName": "L1D_CACHE_MISS_LD_NONSPEC", + "BriefDescription": "Retired loads that missed in the L1 Data Cache" + }, + { + "PublicDescription": "Fetch Unit internal restarts for any reason. Does not include branch mispredicts", + "EventCode": "0xde", + "EventName": "FETCH_RESTART", + "BriefDescription": "Fetch Unit internal restarts for any reason" + }, + { + "PublicDescription": "\u03bcops that flowed through the Store Unit", + "EventCode": "0xa7", + "EventName": "ST_UNIT_UOP", + "BriefDescription": "\u03bcops that flowed through the Store Unit" + }, + { + "PublicDescription": "Retired stores that missed in the L1 Data Cache", + "EventCode": "0xc0", + "EventName": "L1D_CACHE_MISS_ST_NONSPEC", + "BriefDescription": "Retired stores that missed in the L1 Data Cache" + }, + { + "PublicDescription": "Cycles while rewinding the Map Unit due to flush and restart", + "EventCode": "0x75", + "EventName": "MAP_REWIND", + "BriefDescription": "Cycles while rewinding the Map Unit due to flush and restart" + }, + { + "PublicDescription": "Retired indirect branch instructions including indirect calls", + "EventCode": "0x93", + "EventName": "INST_BRANCH_INDIR", + "BriefDescription": "Retired indirect branch instructions including indirect calls" + }, + { + "PublicDescription": "Retired branch instructions including calls and returns", + "EventCode": "0x8d", + "EventName": "INST_BRANCH", + "BriefDescription": "Retired branch instructions including calls and returns" + }, + { + "PublicDescription": "Retired return instructions that mispredicted", + "EventCode": "0xc8", + "EventName": "BRANCH_RET_INDIR_MISPRED_NONSPEC", + "BriefDescription": "Retired return instructions that mispredicted" + }, + { + "PublicDescription": "Cycles while the Map Unit was stalled for any reason", + "EventCode": "0x76", + "EventName": "MAP_STALL", + "BriefDescription": "Cycles while the Map Unit was stalled for any reason" + }, + { + "PublicDescription": "\u03bcops issued by the scheduler to any execution unit", + "EventCode": "0x52", + "EventName": "SCHEDULE_UOP", + "BriefDescription": "\u03bcops issued by the scheduler to any execution unit" + }, + { + "PublicDescription": "Retired load and store instructions; does not count DC ZVA (Data Cache Zero by VA).", + "EventCode": "0x9b", + "EventName": "INST_LDST", + "BriefDescription": "Retired load and store instructions; does not count DC ZVA" + }, + { + "PublicDescription": "Retired indirect call instructions mispredicted", + "EventCode": "0xca", + "EventName": "BRANCH_CALL_INDIR_MISPRED_NONSPEC", + "BriefDescription": "Retired indirect call instructions mispredicted" + }, + { + "PublicDescription": "Retired load Integer Unit instructions", + "EventCode": "0x95", + "EventName": "INST_INT_LD", + "BriefDescription": "Retired load Integer Unit instructions" + }, + { + "PublicDescription": "Instruction fetches that missed in the L2 TLB", + "EventCode": "0xa", + "EventName": "L2_TLB_MISS_INSTRUCTION", + "BriefDescription": "Instruction fetches that missed in the L2 TLB" + }, + { + "PublicDescription": "Retired load Advanced SIMD and FP Unit instructions", + "EventCode": "0x98", + "EventName": "INST_SIMD_LD", + "BriefDescription": "Retired load Advanced SIMD and FP Unit instructions" + }, + { + "PublicDescription": "Retired A32 instructions", + "EventCode": "0x8a", + "EventName": "INST_A32", + "BriefDescription": "Retired A32 instructions" + }, + { + "PublicDescription": "Retired T32 instructions", + "EventCode": "0x8b", + "EventName": "INST_T32", + "BriefDescription": "Retired T32 instructions" + }, + { + "PublicDescription": "All retired instructions", + "EventCode": "0x8c", + "EventName": "INST_ALL", + "BriefDescription": "All retired instructions" + }, + { + "PublicDescription": "Retired subroutine call instructions", + "EventCode": "0x8e", + "EventName": "INST_BRANCH_CALL", + "BriefDescription": "Retired subroutine call instructions" + }, + { + "PublicDescription": "Retired core store \u03bcops that triggered memory order violations with core load \u03bcops", + "EventCode": "0xc4", + "EventName": "ST_MEMORY_ORDER_VIOLATION_NONSPEC", + "BriefDescription": "Retired core store \u03bcops that triggered memory order violations with core load \u03bcops" + }, + { + "PublicDescription": "Retired non-load/store Advanced SIMD and FP Unit instructions", + "EventCode": "0x9a", + "EventName": "INST_SIMD_ALU", + "BriefDescription": "Retired non-load/store Advanced SIMD and FP Unit instructions" + }, + { + "PublicDescription": "Retired indirect branch instructions including calls and returns that mispredicted", + "EventCode": "0xc6", + "EventName": "BRANCH_INDIR_MISPRED_NONSPEC", + "BriefDescription": "Retired indirect branch instructions including calls and returns that mispredicted" + }, + { + "PublicDescription": "Retired taken branch instructions", + "EventCode": "0x90", + "EventName": "INST_BRANCH_TAKEN", + "BriefDescription": "Retired taken branch instructions" + }, + { + "PublicDescription": "Stores that missed the L1 Data Cache", + "EventCode": "0xa2", + "EventName": "L1D_CACHE_MISS_ST", + "BriefDescription": "Stores that missed the L1 Data Cache" + }, + { + "PublicDescription": "Loads that missed the L1 Data Cache", + "EventCode": "0xa3", + "EventName": "L1D_CACHE_MISS_LD", + "BriefDescription": "Loads that missed the L1 Data Cache" + }, + { + "PublicDescription": "Dirty cache lines written back from the L1D Cache toward the Shared L2 Cache", + "EventCode": "0xa8", + "EventName": "L1D_CACHE_WRITEBACK", + "BriefDescription": "Dirty cache lines written back from the L1D Cache toward the Shared L2 Cache" + }, + { + "PublicDescription": "Pipeline flush and restarts that were not due to branch mispredictions or memory order violations", + "EventCode": "0x84", + "EventName": "FLUSH_RESTART_OTHER_NONSPEC", + "BriefDescription": "Pipeline flush and restarts that were not due to branch mispredictions or memory order violations" + }, + { + "PublicDescription": "Retired store Advanced SIMD and FP Unit instructions", + "EventCode": "0x99", + "EventName": "INST_SIMD_ST", + "BriefDescription": "Retired store Advanced SIMD and FP Unit instructions" + }, + { + "PublicDescription": "Retired non-branch and non-load/store Integer Unit instructions", + "EventCode": "0x97", + "EventName": "INST_INT_ALU", + "BriefDescription": "Retired non-branch and non-load/store Integer Unit instructions" + }, + { + "PublicDescription": "Load and store accesses to the L1 Data TLB", + "EventCode": "0xa0", + "EventName": "L1D_TLB_ACCESS", + "BriefDescription": "Load and store accesses to the L1 Data TLB" + }, + { + "PublicDescription": "Retired loads and stores that missed in the L1 Data TLB", + "EventCode": "0xc1", + "EventName": "L1D_TLB_MISS_NONSPEC", + "BriefDescription": "Retired loads and stores that missed in the L1 Data TLB" + }, + { + "PublicDescription": "Mapped Load and Store Unit \u03bcops, including GPR to vector register converts; includes all instructions sent to the SME engine because they are processed through the Store Unit", + "EventCode": "0x7c", + "EventName": "MAP_LDST_UOP", + "BriefDescription": "Mapped Load and Store Unit \u03bcops" + }, + { + "PublicDescription": "Mapped Advanced SIMD and FP Unit \u03bcops", + "EventCode": "0x7d", + "EventName": "MAP_SIMD_UOP", + "BriefDescription": "Mapped Advanced SIMD and FP Unit \u03bcops" + } +] diff --git a/tools/perf/pmu-events/arch/arm64/apple/a9/core-imp-def.json b/tools/perf/pmu-events/arch/arm64/apple/a9/core-imp-def.json new file mode 100644 index 00000000000000..4413d4f21e6b9d --- /dev/null +++ b/tools/perf/pmu-events/arch/arm64/apple/a9/core-imp-def.json @@ -0,0 +1,308 @@ +[ + { + "PublicDescription": "Cycles while the core was active", + "EventCode": "0x2", + "EventName": "CORE_ACTIVE_CYCLE", + "BriefDescription": "Cycles while the core was active" + }, + { + "PublicDescription": "Retired store Integer Unit instructions; does not count DC ZVA (Data Cache Zero by VA).", + "EventCode": "0x96", + "EventName": "INST_INT_ST", + "BriefDescription": "Retired store Integer Unit instructions; does not count DC ZVA" + }, + { + "PublicDescription": "Retired conditional branch instructions that mispredicted", + "EventCode": "0xc5", + "EventName": "BRANCH_COND_MISPRED_NONSPEC", + "BriefDescription": "Retired conditional branch instructions that mispredicted" + }, + { + "PublicDescription": "Retired barrier instructions", + "EventCode": "0x9c", + "EventName": "INST_BARRIER", + "BriefDescription": "Retired barrier instructions" + }, + { + "PublicDescription": "Retired subroutine return instructions", + "EventCode": "0x8f", + "EventName": "INST_BRANCH_RET", + "BriefDescription": "Retired subroutine return instructions" + }, + { + "PublicDescription": "Loads and stores that missed in the L2 TLB", + "EventCode": "0xb", + "EventName": "L2_TLB_MISS_DATA", + "BriefDescription": "Loads and stores that missed in the L2 TLB" + }, + { + "PublicDescription": "Load \u03bcops that executed with non-temporal hint; excludes SSVE/SME loads because they utilize the Store Unit", + "EventCode": "0xe6", + "EventName": "LD_NT_UOP", + "BriefDescription": "Load \u03bcops that executed with non-temporal hint; excludes SSVE/SME loads because they utilize the Store Unit" + }, + { + "PublicDescription": "\u03bcops that flowed through the Load Unit", + "EventCode": "0xa6", + "EventName": "LD_UNIT_UOP", + "BriefDescription": "\u03bcops that flowed through the Load Unit" + }, + { + "PublicDescription": "Retired branch instructions including calls and returns that mispredicted", + "EventCode": "0xcb", + "EventName": "BRANCH_MISPRED_NONSPEC", + "BriefDescription": "Retired branch instructions including calls and returns that mispredicted" + }, + { + "PublicDescription": "Demand instruction fetches that missed in the L1 Instruction TLB", + "EventCode": "0xd4", + "EventName": "L1I_TLB_MISS_DEMAND", + "BriefDescription": "Demand instruction fetches that missed in the L1 Instruction TLB" + }, + { + "PublicDescription": "Load and store \u03bcops that crossed a 64B boundary", + "EventCode": "0xb1", + "EventName": "LDST_X64_UOP", + "BriefDescription": "Load and store \u03bcops that crossed a 64B boundary" + }, + { + "PublicDescription": "Mapped Integer Unit \u03bcops", + "EventCode": "0x7c", + "EventName": "MAP_INT_UOP", + "BriefDescription": "Mapped Integer Unit \u03bcops" + }, + { + "PublicDescription": "Retired conditional branch instructions (counts only B.cond)", + "EventCode": "0x94", + "EventName": "INST_BRANCH_COND", + "BriefDescription": "Retired conditional branch instructions (counts only B.cond)" + }, + { + "PublicDescription": "Load and store accesses that missed the L1 Data TLB", + "EventCode": "0xa1", + "EventName": "L1D_TLB_MISS", + "BriefDescription": "Load and store accesses that missed the L1 Data TLB" + }, + { + "PublicDescription": "Retired loads that missed in the L1 Data Cache", + "EventCode": "0xbf", + "EventName": "L1D_CACHE_MISS_LD_NONSPEC", + "BriefDescription": "Retired loads that missed in the L1 Data Cache" + }, + { + "PublicDescription": "Fetch Unit internal restarts for any reason. Does not include branch mispredicts", + "EventCode": "0xde", + "EventName": "FETCH_RESTART", + "BriefDescription": "Fetch Unit internal restarts for any reason" + }, + { + "PublicDescription": "Atomic or exclusive instruction failed due to contention *For exclusives, incorrectly undercounts for exclusives when the cache line is initially found in shared state, however counts correctly for atomics", + "EventCode": "0xb4", + "EventName": "ATOMIC_OR_EXCLUSIVE_FAIL", + "BriefDescription": "Atomic or exclusive instruction failed due to contention *For exclusives" + }, + { + "PublicDescription": "\u03bcops that flowed through the Store Unit", + "EventCode": "0xa7", + "EventName": "ST_UNIT_UOP", + "BriefDescription": "\u03bcops that flowed through the Store Unit" + }, + { + "PublicDescription": "Cycles while the Map Unit was not stalled and Decode Unit did not send any \u03bcops", + "EventCode": "0xd6", + "EventName": "MAP_DISPATCH_BUBBLE", + "BriefDescription": "Cycles while the Map Unit was not stalled and Decode Unit did not send any \u03bcops" + }, + { + "PublicDescription": "Atomic or exclusive instruction successfully completed *For exclusives, incorrectly undercounts for exclusives when the cache line is initially found in shared state, however counts correctly for atomics", + "EventCode": "0xb3", + "EventName": "ATOMIC_OR_EXCLUSIVE_SUCC", + "BriefDescription": "Atomic or exclusive instruction successfully completed *For exclusives" + }, + { + "PublicDescription": "Retired stores that missed in the L1 Data Cache", + "EventCode": "0xc0", + "EventName": "L1D_CACHE_MISS_ST_NONSPEC", + "BriefDescription": "Retired stores that missed in the L1 Data Cache" + }, + { + "PublicDescription": "Cycles while rewinding the Map Unit due to flush and restart", + "EventCode": "0x75", + "EventName": "MAP_REWIND", + "BriefDescription": "Cycles while rewinding the Map Unit due to flush and restart" + }, + { + "PublicDescription": "Retired indirect branch instructions including indirect calls", + "EventCode": "0x93", + "EventName": "INST_BRANCH_INDIR", + "BriefDescription": "Retired indirect branch instructions including indirect calls" + }, + { + "PublicDescription": "Retired branch instructions including calls and returns", + "EventCode": "0x8d", + "EventName": "INST_BRANCH", + "BriefDescription": "Retired branch instructions including calls and returns" + }, + { + "PublicDescription": "Retired return instructions that mispredicted", + "EventCode": "0xc8", + "EventName": "BRANCH_RET_INDIR_MISPRED_NONSPEC", + "BriefDescription": "Retired return instructions that mispredicted" + }, + { + "PublicDescription": "Cycles while the Map Unit was stalled for any reason", + "EventCode": "0x76", + "EventName": "MAP_STALL", + "BriefDescription": "Cycles while the Map Unit was stalled for any reason" + }, + { + "PublicDescription": "\u03bcops issued by the scheduler to any execution unit", + "EventCode": "0x52", + "EventName": "SCHEDULE_UOP", + "BriefDescription": "\u03bcops issued by the scheduler to any execution unit" + }, + { + "PublicDescription": "Store \u03bcops that executed with non-temporal hint; includes SSVE/SME loads because they utilize the Store Unit", + "EventCode": "0xe5", + "EventName": "ST_NT_UOP", + "BriefDescription": "Store \u03bcops that executed with non-temporal hint; includes SSVE/SME loads because they utilize the Store Unit" + }, + { + "PublicDescription": "Retired load and store instructions; does not count DC ZVA (Data Cache Zero by VA).", + "EventCode": "0x9b", + "EventName": "INST_LDST", + "BriefDescription": "Retired load and store instructions; does not count DC ZVA" + }, + { + "PublicDescription": "Retired indirect call instructions mispredicted", + "EventCode": "0xca", + "EventName": "BRANCH_CALL_INDIR_MISPRED_NONSPEC", + "BriefDescription": "Retired indirect call instructions mispredicted" + }, + { + "PublicDescription": "Retired load Integer Unit instructions", + "EventCode": "0x95", + "EventName": "INST_INT_LD", + "BriefDescription": "Retired load Integer Unit instructions" + }, + { + "PublicDescription": "Instruction fetches that missed in the L2 TLB", + "EventCode": "0xa", + "EventName": "L2_TLB_MISS_INSTRUCTION", + "BriefDescription": "Instruction fetches that missed in the L2 TLB" + }, + { + "PublicDescription": "Retired load Advanced SIMD and FP Unit instructions", + "EventCode": "0x98", + "EventName": "INST_SIMD_LD", + "BriefDescription": "Retired load Advanced SIMD and FP Unit instructions" + }, + { + "PublicDescription": "Retired A32 instructions", + "EventCode": "0x8a", + "EventName": "INST_A32", + "BriefDescription": "Retired A32 instructions" + }, + { + "PublicDescription": "Retired T32 instructions", + "EventCode": "0x8b", + "EventName": "INST_T32", + "BriefDescription": "Retired T32 instructions" + }, + { + "PublicDescription": "All retired instructions", + "EventCode": "0x8c", + "EventName": "INST_ALL", + "BriefDescription": "All retired instructions" + }, + { + "PublicDescription": "Retired subroutine call instructions", + "EventCode": "0x8e", + "EventName": "INST_BRANCH_CALL", + "BriefDescription": "Retired subroutine call instructions" + }, + { + "PublicDescription": "Retired core store \u03bcops that triggered memory order violations with core load \u03bcops", + "EventCode": "0xc4", + "EventName": "ST_MEMORY_ORDER_VIOLATION_NONSPEC", + "BriefDescription": "Retired core store \u03bcops that triggered memory order violations with core load \u03bcops" + }, + { + "PublicDescription": "Retired non-load/store Advanced SIMD and FP Unit instructions", + "EventCode": "0x9a", + "EventName": "INST_SIMD_ALU", + "BriefDescription": "Retired non-load/store Advanced SIMD and FP Unit instructions" + }, + { + "PublicDescription": "Retired indirect branch instructions including calls and returns that mispredicted", + "EventCode": "0xc6", + "EventName": "BRANCH_INDIR_MISPRED_NONSPEC", + "BriefDescription": "Retired indirect branch instructions including calls and returns that mispredicted" + }, + { + "PublicDescription": "Retired taken branch instructions", + "EventCode": "0x90", + "EventName": "INST_BRANCH_TAKEN", + "BriefDescription": "Retired taken branch instructions" + }, + { + "PublicDescription": "Stores that missed the L1 Data Cache", + "EventCode": "0xa2", + "EventName": "L1D_CACHE_MISS_ST", + "BriefDescription": "Stores that missed the L1 Data Cache" + }, + { + "PublicDescription": "Loads that missed the L1 Data Cache", + "EventCode": "0xa3", + "EventName": "L1D_CACHE_MISS_LD", + "BriefDescription": "Loads that missed the L1 Data Cache" + }, + { + "PublicDescription": "Dirty cache lines written back from the L1D Cache toward the Shared L2 Cache", + "EventCode": "0xa8", + "EventName": "L1D_CACHE_WRITEBACK", + "BriefDescription": "Dirty cache lines written back from the L1D Cache toward the Shared L2 Cache" + }, + { + "PublicDescription": "Pipeline flush and restarts that were not due to branch mispredictions or memory order violations", + "EventCode": "0x84", + "EventName": "FLUSH_RESTART_OTHER_NONSPEC", + "BriefDescription": "Pipeline flush and restarts that were not due to branch mispredictions or memory order violations" + }, + { + "PublicDescription": "Retired store Advanced SIMD and FP Unit instructions", + "EventCode": "0x99", + "EventName": "INST_SIMD_ST", + "BriefDescription": "Retired store Advanced SIMD and FP Unit instructions" + }, + { + "PublicDescription": "Retired non-branch and non-load/store Integer Unit instructions", + "EventCode": "0x97", + "EventName": "INST_INT_ALU", + "BriefDescription": "Retired non-branch and non-load/store Integer Unit instructions" + }, + { + "PublicDescription": "Load and store accesses to the L1 Data TLB", + "EventCode": "0xa0", + "EventName": "L1D_TLB_ACCESS", + "BriefDescription": "Load and store accesses to the L1 Data TLB" + }, + { + "PublicDescription": "Retired loads and stores that missed in the L1 Data TLB", + "EventCode": "0xc1", + "EventName": "L1D_TLB_MISS_NONSPEC", + "BriefDescription": "Retired loads and stores that missed in the L1 Data TLB" + }, + { + "PublicDescription": "Mapped Load and Store Unit \u03bcops, including GPR to vector register converts; includes all instructions sent to the SME engine because they are processed through the Store Unit", + "EventCode": "0x7d", + "EventName": "MAP_LDST_UOP", + "BriefDescription": "Mapped Load and Store Unit \u03bcops" + }, + { + "PublicDescription": "Mapped Advanced SIMD and FP Unit \u03bcops", + "EventCode": "0x7e", + "EventName": "MAP_SIMD_UOP", + "BriefDescription": "Mapped Advanced SIMD and FP Unit \u03bcops" + } +] diff --git a/tools/perf/pmu-events/arch/arm64/mapfile.csv b/tools/perf/pmu-events/arch/arm64/mapfile.csv index 7f0eaa70204853..4f174f144937d0 100644 --- a/tools/perf/pmu-events/arch/arm64/mapfile.csv +++ b/tools/perf/pmu-events/arch/arm64/mapfile.csv @@ -47,3 +47,12 @@ 0x00000000c00fac30,v1,ampere/ampereone,core 0x00000000c00fac40,v1,ampere/ampereonex,core 0x000000004e0f0100,v1,nvidia/t410,core +0x00000000610f0010,v1,apple/a7,core +0x00000000610f0020,v1,apple/a8,core +0x00000000610f0030,v1,apple/a8,core +0x00000000610f0040,v1,apple/a9,core +0x00000000610f0050,v1,apple/a9,core +0x00000000610f0060,v1,apple/a10,core +0x00000000610f0070,v1,apple/a10,core +0x00000000610f0080,v1,apple/a11,core +0x00000000610f0090,v1,apple/a11,core